ZGlmZiAtLWdpdCBhLy5oZ2lnbm9yZSBiLy5oZ2lnbm9yZQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOTcwZmM4Mi4uMDAwMDAwMAotLS0gYS8uaGdpZ25vcmUKKysrIC9kZXYvbnVsbApAQCAtMSw3ICswLDAgQEAKLV5idWlsZC8KLV5kaXN0LwotXmRyb3AvCi1eZHJvcF9pbmNsdWRlZC8KLV53ZWJyZXYvCi0vbmJwcm9qZWN0L3ByaXZhdGUvCi1eLmhndGlwCmRpZmYgLS1naXQgYS8uaGd0YWdzIGIvLmhndGFncwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDU3NWVlOC4uMDAwMDAwMAotLS0gYS8uaGd0YWdzCisrKyAvZGV2L251bGwKQEAgLTEsNjk5ICswLDAgQEAKLTZjZTVmNDc1N2JkZTA4Zjc0NzBjYmI5ZjBiNDZkYThmMmYzZDRmNTYgamRrNy1iMjQKLWEzYjNiYTdkNjAzNGRjNzU0YjUxZGRjM2QyODEzOTlhYzFjYWU1ZjEgamRrNy1iMjUKLWRhNDNjYjg1ZmFjMTY0NmQ2Zjk3ZTRhMzVlNTEwYmJmZGZmOTdiZGIgamRrNy1iMjYKLWJhZmVkNDc4ZDY3YzNhY2Y3NzQ0YWFhZDg4Yjk0MDQyNjFlYTY3MzkgamRrNy1iMjcKLWI5OTYzMTg5NTVjMGFkOGU5ZmEwZmZiNTZjNzRmNjI2Nzg2ZTg2M2YgamRrNy1iMjgKLTYxN2VlODYwN2NmZDVmZDgxZjIzM2YzYzBiNjkwZjg1MDg0Njg3YTAgamRrNy1iMjkKLTJkOTRhMjM4YTE2NDFkMDc0ZTYwMzJkY2RjZWVkNDYxZDZmODVkNmEgamRrNy1iMzAKLTI1NWQ2NGVlMjg3ZTkyNmU4NjI5ZGQ4MGJjNjc2OTBlNjVlZWJhMzAgamRrNy1iMzEKLTQwMGE1ZWU0MzJjYzJkYjkwMzFlMDY4NTJkZGRlOTI2NGExOTJiNDggamRrNy1iMzIKLTk1Mzc1ODM1NTI3ZjBiZjA2MTI0Y2U5ODQyNjZlMmFkNWRlOGE2ZGMgamRrNy1iMzMKLTAxZmFjZGY4Y2FiZGVhYWY2OGNjYTAzN2FlZjU2Y2M1ZjA3NDg5N2YgamRrNy1iMzQKLWVhYzQ2ZDFlYjdmMDkzNWJhMDRmMWM3OTI5ZWMxNTQyM2ZkMDMwOWUgamRrNy1iMzUKLWM4NGNhNjM4ZGI0MmE4YjZiMjI3YjRlM2I2M2JjYTE5MmM1Y2E2MzQgamRrNy1iMzYKLWFmNDk1OTFiYzQ4NmQ4MmFhMDRiODMyMjU3ZGUwZDE4YWRjOWFmNTIgamRrNy1iMzcKLWU5Zjc1MGYwYTNhMDA0MTNhN2I3NzAyOGIyZWNkYWJiNzEyOWFlMzIgamRrNy1iMzgKLTgzMWI4MGJlNmNlYThlN2Q3ZGExOTdjY2RhYzVmZDRjNzAxYTUwMzMgamRrNy1iMzkKLTU0OTQ2ZjQ2NmUyYzA0N2M0NGM5MDNmMWJlYzQwMGI2ODVjMjUwOGUgamRrNy1iNDAKLTA3NThiZDNlMjg1MmU0ZjkzMWJhMjExY2M0ZDQ4ZjU4OTQ1MGVlYjQgamRrNy1iNDEKLTAzNmUwZGNhODQxYTVhMTdmNzg0ZDE1Yzg2YTlkYTg4ZDJhNmYxZTYgamRrNy1iNDIKLTk2ZmUyOGQ0YTkxMzFlMWE5N2JmZTAwZjc3OWU1NjI2Y2QwOWM0ZDAgamRrNy1iNDMKLWIyMDNkZjA3NDFhZjNlYjA4Njg3YmM1ZWI3OThiYWM4NzM2Mzc1OGQgamRrNy1iNDQKLTBmMTEzNjY3ODgwZDMzNWNmYTJjMzU3MjFiMWI0NTE0NGZiNzU3ZjUgamRrNy1iNDUKLWIyMjcxODc3ODk0YWY4MDliNzcwMzc2N2ZlOGQ0ZTM4NTkxYTAyYTIgamRrNy1iNDYKLWQ3MTFhZDE5NTRiMjk0OTU3NzM3ZWEzODZjZmQ0ZDNjMDUwMjhhMzYgamRrNy1iNDcKLTM5ZGU5MGViNDgyMmNhZmFhY2M2OWVkZDY3YWI1NTQ3ZTU1YWU5MjAgamRrNy1iNDgKLTVjMWYyNDUzMTkwMzU3M2MxODMwNzc1NDMyMjc2ZGE1NjcyNDNmOWMgamRrNy1iNDkKLWU4NTE0ZTJiZTc2ZDkwODg5ZWJkYjkwZDYyN2FjYTJkYjVjMTUwYzYgamRrNy1iNTAKLWFlODkwZDgwZDVkZmZjZDRkYzc3YTFmMTdkNzY4ZTE5MmQxODUyYzcgamRrNy1iNTEKLTY5YWQ4N2RjMjVjYmNhYWFkZWQ0NzI3MTk5Mzk1YWQwYzc4YmM0MjcgamRrNy1iNTIKLWU4ODM3MzY2ZDNmZDcyZjdjN2E0N2ViZmRiZDUxMDZjMTYxNTZmMTIgamRrNy1iNTMKLTk0NmE5ZjBjNDkzMjYxZmE2YTAxMGRjMzNlNjFiOWI1MzViYTgwYzEgamRrNy1iNTQKLTAzOTk0NWZiYTY4M2VlNjc3M2E3MjFlMmJkNGU0NDlmNjEzMzc2OWEgamRrNy1iNTUKLWMxOTdjNjgwMTI3MWM2MGY5YzlmNWQxOGZjYzk1YjU5ZTc2ZGNkNTQgamRrNy1iNTYKLWU0ODUxZTlmN2JlMjZmYzUyYTYyOGJlMDZmZmE4YWFlYTA5MTliZDcgamRrNy1iNTcKLTEzYmY2N2Q4YzYzNDFiODQxZDI2ODk4NWNhYmFmNzQ3ZjI2NTJiYzggamRrNy1iNTgKLTc1MTEzZDdjZTA4MzA0OGU3NTc2YjlkMGQ2MGE0ZTgwZGI2YjE4MWYgamRrNy1iNTkKLTI1OWFlZjUwNDVhMTU1ZWI2YTJmOGRkMGUyNDI5YzZkYmUwZjY1MmYgamRrNy1iNjAKLWYxYWM3NTY2MTZlYWFhZDc5NWY3N2Y3ZjVlN2Y3YzdiZmRjOWMxZGUgamRrNy1iNjEKLWE5N2RkNTdhNjI2MDRjMzVjNzliYzJmYTc3YTYxMmVkNTQ3ZjYxMzUgamRrNy1iNjIKLWFlNDQ5ZTljMDRjMWZlNjUxYmQzMGYwZjRkNGNjMjRiYTc5NGUwYzQgamRrNy1iNjMKLWExMGVlYzdhMWVkZjUzNmYzOWI1ODI4ZDg2MjMwNTRkYmM2MmMyYjcgamRrNy1iNjQKLTAwOGM2NjJlMGVlOWE5MWFlYmI3NWU0NmI5N2RlOTc5MDgzZDVjMWMgamRrNy1iNjUKLTIyZjlkNWQ1YjVmZTBmNDcwNDhmNDFlNmM2ZTU0ZmVlNWVkYWQwZWMgamRrNy1iNjYKLWEwMzNhZjhkODI0YTQwOGQzYWM2MDIyMDVlY2RlZmMxMjg3NDllMWUgamRrNy1iNjcKLTgzYjJhOTMzMTM4M2Y5ZGI3YTQ5MzUwZDRjYjEzYjc2MzVmNmI4NjEgamRrNy1iNjgKLWE0YWIwZDZkZWQ2M2JlZDBmZDFlNWJlNTVkMzgwOTBlMGVlNWVmYjcgamRrNy1iNjkKLWM4M2YwMTA2Yjc4YTg1YzdlNjE0ZDI3YTMyODY3NTQ2MGIyMDgxY2YgamRrNy1iNzAKLWZmOTRkOGNlMGRhZGVkNjQ3YmIzMjY2MzBlNjQzZDAxMDM1N2FmY2UgamRrNy1iNzEKLTM3YzgwNWI2MTU2ZmQ0OTJjMTIzMDE2ODhiNTRhNmJjY2EzOWU3MjkgamRrNy1iNzIKLWZlYjA1OTgwZjlmMjk2NGU2YmMyYjNhODUzMmY5YjMwNTRjMjI4OWIgamRrNy1iNzMKLWVhN2I4OGM2NzZkZDhiMjY5YmM4NThhNGExN2MxNGRjOTZjOGFlZDEgamRrNy1iNzQKLTU1NWZiNzhlZTRjZWJlZDA4MmNhN2RkYWJmZjQ2ZDJlNWI0YzkwMjYgamRrNy1iNzUKLTIzM2E0ODcxZDMzNjRlYzMwNWVmZDRhNThjZmQ2NzY2MjBhMDNhOTAgamRrNy1iNzYKLWJmYWRhYjhjN2IxYmY4MDZhNDlkM2UxYmMxOWVjOTE5NzE3ZjA1N2EgamRrNy1iNzcKLTdhMTJkMzc4OWUxYjA3YTU2MGZjNzk1NjhiOTkxODE4ZDYxN2VkZTIgamRrNy1iNzgKLWIxMDA1YzUwNDM1OGMxODY5NGM4NGU5NWZlYzE2YjI4Y2RjZTdhZTEgamRrNy1iNzkKLTkyMTk1NzRkYjU5MzYzNjcxMTRiMGYzMTQ2OTgzN2YyN2Q1YTM3NWEgamRrNy1iODAKLTIwNGU1OWQ0ODhjZGFhOWVhZmE4Y2I3MTY0ZWE5NTViNWE5ZDRhNTEgamRrNy1iODEKLWM4NzZhZDIyZTRiZjlkM2M2NDYwMDgwZGI3YWNlNDc4ZTI5YTNmZjkgamRrNy1iODIKLTMwOWEwYTdmYzZjZWIxYzlmYzNhODViMzYwOGU5N2VmOGY3YjBkZmQgamRrNy1iODMKLTMyYzBjZjAxZDU1NTc0NzkxODUyOWE2ZmY5ZTA2YjAwOTBjN2E0NzQgamRrNy1iODQKLTZjMGNjYWJiNDMwZGFjZGNkNDQ3OWY4YjE5Nzk4MGQ1ZGE0ZWViNjYgamRrNy1iODUKLTgxYzBmMTE1YmJlNWQzYmNmNTk4NjQ0NjViNWVjYTU1Mzg1NjdjNzkgamRrNy1iODYKLThiNDkzZjFhYTEzNmQ4NmRlMDg4NWZjYmExNTI2MmM0ZmEyYjE0MTIgamRrNy1iODcKLWQ4ZWJkMTU5MTAwMzRmMmJhNTBiMmYxMjlmOTU5Zjg2Y2NhMDE0MTkgamRrNy1iODgKLWQyODE4ZmQyYjAzNmYzYjMxNTRhOWE3ZGU0MWFmY2Y0YWM2NzljMWIgamRrNy1iODkKLWM1ZDkzMmVlMzI2ZDZmN2ZkNDYzNGIxMWM3MTg1ZWE4MmQxODRkZjIgamRrNy1iOTAKLWI4OWIyYzMwNDRhMjk4ZDU0MmY4NGEyZTlkOTU3MjAyYjdkOGNkYjkgamRrNy1iOTEKLWU2YTQwZTRiYjEwNDk5ZmI2ZWU5ZGI3MWFiNTY1NGU1YTE3YWI3NWIgamRrNy1iOTIKLWM3MjVjYTgyOWM1YWE0YjUwYThlZDU3Mjg1NzllYzg4MDlmYmZiMWQgamRrNy1iOTMKLTJkZTMwN2NkM2I0ZTcxMTI3ZTc1ZGZmNzA4MDljMWIxZmJjMWE0OTQgamRrNy1iOTQKLTA3MDUwODQwZjk4Y2RhMzU3YWE2YThkNDE2ZmRjY2JkMDMwMzhkMzUgamRrNy1iOTUKLTk1MTBlZDBlMWM3YWI0NmE4YjY2NTkyMzRlMWRjNzc4NjQwN2E3MmIgamRrNy1iOTYKLWNhMDFlYzMyNTYxZmVlMTg1NTYzMGI2OGEyZmNkMDA0MjI1N2E4ZWYgamRrNy1iOTcKLWQ0YWRmNGYyZDE0YzdiNzlkZjBhODFkZTg4NGI2YjU3YzY4NTA4MDIgamRrNy1iOTgKLTdlZjg0NjkwMjFmYmM4MjRhYzQ5ZDU3YzgzYTE0YjFiYjA4ZjE3NjYgamRrNy1iOTkKLWQ1MjRiZTVlZjYyZThiOGNiODkwYzU5YTVkMmMxOWVmMGFiNTBkNDUgamRrNy1iMTAwCi0xN2Y2MmE1NjZhMjAyMGZkOTA4ZTc3MTA2ZWQ4ODVlMGM0ZTdjMTRkIGpkazctYjEwMQotMTU1NzM2MjVhZjk3ZDAxYzRlMjQ1NDkwNDFjYmE3NTg0ZGE3ZmU4OCBqZGs3LWIxMDIKLWI3NzIyZTg3ODg2NDQ1MDdjMTBiYjY5YTEzN2RlNDIyZDAzMDBiMjQgamRrNy1iMTAzCi1kNDJjNGFjYjY0MjRhMDk0YmRhZmUyYWQ5YzhjMWM3Y2E3ZmI3YjdlIGpkazctYjEwNAotMzIzM2I5YTRjMTJlZjI2NjNhMzU2ZDA4YmIxNDFjMDI3MzZjN2Y0OSBqZGs3LWIxMDUKLTViYTg0NjkyMTJhNmNhYjk1Y2E2NTJlZWE0MTRiNzUzYmU3ZDI0NWEgamRrNy1iMTA2Ci0yMGVlMzdjMTM3MmEzZWFlZmE0OWI0MjZjNmViNjhhMmU4ZjVkNmUyIGpkazctYjEwNwotN2QzNzlmODkzNGNhZjI1NWY1M2RlZjEzMTBjMGVmMGYxYjUxMjYwMSBqZGs3LWIxMDgKLTBmMzgyZDYxMjBmYzA3YWVkMjIwOTQ4NGE0MjQ1OGNhYmY0MDU5MTYgamRrNy1iMTA5Ci1kNDIyZGJkZDA5NzY2MjY5MzQ0Yjc5NmIzYTQ2YTViM2Y3NDU1N2UxIGpkazctYjExMAotODEwNmM3NDcwNjdjOTA1ZDgxNGE3MzdhNTdmZWEwZTI5MDU3YjMzZiBqZGs3LWIxMTEKLTFiMDUyNTQyNDI4ODE1MjdiNGQ1ZDcxMTI5NWMwZmU3MDhjODgyM2EgamRrNy1iMTEyCi1iYzBjODRjZTU0YzM0ZDNlOGIwNjA0Yjk0ZGEwZDdjNzVjMjY3NTVlIGpkazctYjExMwotZDU3MTk3ZDIyYzJiZmMzOWQxYTg2MDA0MGY2NTViNDY2YWI0NmY1MiBqZGs3LWIxMTQKLWRjMTYxMmUxZDNhYzA4ZWI4ZmNhZDc2NGRhZmYyMWM5MjQ3ZDMzYzkgamRrNy1iMTE1Ci1mOGQ0ZTZjNmNmY2UxY2RhMjNmY2JkMTQ0NjI4YTk3OTFhOWUxYTYzIGpkazctYjExNgotOWVlNGQ5NmU4OTM0MzZhNDg2MDc5MjQyMjdkYWRkMmQ5M2I5YjAwZCBqZGs3LWIxMTcKLWIyZjZkOWM0ZjEyZmZkMzA3YTVkZTQwNDU1YjJiNjFiMzFhNWNiNzkgamRrNy1iMTE4Ci05ZWU5MDBmMDFjNTg3MjU1MWMwNmYzM2FlOTA5NjYyZmZkODQ2M2FjIGpkazctYjExOQotNDgyMWRlMDkwOGRlZmU2NDdmY2RhYWI0NDg1Zjk4ODczZTI0ZGVhMCBqZGs3LWIxMjAKLTYzZGFlNDBmYTE5ZmQzYmY0Njg5ZWEyZjNjMWQ5ZDY5MGUxYWJjZWUgamRrNy1iMTIxCi0wM2ZmMTNkMTljOGZhOTgzY2JhYjY1NDI5MzBhN2YzNTJlOWI1YjMzIGpkazctYjEyMgotZTJhZWRlYTY0OTVkNjE1NTczMjY5MjhkZTIwZGJiMmQ3OGZkZDlhYSBqZGs3LWIxMjMKLTU3ZWQxZjNiZWM3MjkyNGNkYWQxMDJmOWJmOTBmNzQ0OWVhN2JiODMgamRrNy1iMTI0Ci02YzliZGVlMGNjM2E4OTEyYWNjNTE4OWNjMDkyYjhjYmE2ODUxZjlkIGpkazctYjEyNQotMmZkZTYzOTQzOWMxZmIzZmJjNDRmNTMzZDQ4YmIyOTE2ZTgxMzMxMiBqZGs3LWIxMjYKLWM1MzJkNmRiYzhkMThkNTViNWQ2OTM1OTllZTVjZDgyNTBlMTZlYjQgamRrNy1iMTI3Ci1hNDJjNjEzMmM3NDZjODZlOWZjMjdlYzgwY2JkNjk5ZjZlZTVlZGNhIGpkazctYjEyOAotZjViNjBjNWEzMTBmOTkyYzZjYTYyN2QxN2NhM2UwNDJmMGUwYjJjMyBqZGs3LWIxMjkKLWFiMTA3YzFiYzRiOTE4NDA0YjE5MTgzOGM0NTVlOWIyODkyMzg5ZjMgamRrNy1iMTMwCi1lYWI2ZjI3MTMxZTRlMmYwYWYwMDE2YjM1YjE4YWU2NWNkZDI0OWQ5IGpkazctYjEzMQotYWJlMDRjNTlhNTU2YTM4MjFjMzBiZDg4MzllM2M3NGY1ZDQyODFkMSBqZGs3LWIxMzIKLThlMTE0OGM3OTExYjAyZTAwYTcyNzQ2MTUyNWYyMzlkYTAyNWNhYjcgamRrNy1iMTMzCi1kNTZiMzI2YWUwNTQ0ZmMxNmMzZTBkMDI4NTg3NmYzYzgyMDU0ZGIyIGpkazctYjEzNAotNGFhOTkxNjY5M2RjMTA3ODU4MGMxODY1ZTZmMjU4NDA0Njg1MWU1YSBqZGs3LWIxMzUKLTE3NTlkYWE4NWQzMzgwMGJkNTc4ODUzZjk1MzFmOWRlNzNmNzBmYzcgamRrNy1iMTM2Ci0xZDg3Zjc0NjBjZGU3ZjhmMzBhZjY2ODQ5MGY4MmI1MmI4NzliZmQ4IGpkazctYjEzNwotYmUzNzU4OTQzNzcwYTBhM2RkNGJlNmExY2I0MDYzNTA3YzRkNzA2MiBqZGs3LWIxMzgKLTI4YzdjMGVkMjQ0NDYwNzgyOWJhMTFhZDgyN2Y4ZDUyMTk3YTI4MzAgamRrNy1iMTM5Ci1jODEzNmZkMTYxYzgzOTE3Zjg3ZTkzYjE0ZmEyYmEzNDgzZjliZTgzIGpkazctYjE0MAotZTFiNWVmMjQzNDQ1YmY4MzZkMDk1ZmQ0NDg2NmUxNzcxZWY5OTM3NCBqZGs3LWIxNDEKLTdkMDY3YWY0YjI1ZTRiN2U2YjI4YmVmNDg1MjdkNjdmODY1MGU2YzUgamRrNy1iMTQyCi0xNmI4NDdlOWJiZDc0N2Y5ZDI3Nzg1YjJmYzIwZDRkNzIwY2NhODkzIGpkazctYjE0MwotMzliZjZkY2FhYjIzMzYzMjZiMjE3NDNjZWY3MDQyZDBhMmRlOWJhMCBqZGs3LWIxNDQKLTEwY2E3NTcwZjQ3ZjJhZTQxMzI2NDhmN2U4ZGExYTA1ZjFhOThhMTUgamRrNy1iMTQ1Ci1iY2QzMWZhMWUzYzZmNTFiNGZkZDQyN2VmOTA1MTg4Y2RhYzU3MTY0IGpkazctYjE0NgotZmMyNjhjZDFkZDVkMmU5MDNjY2Q0YjAyNzVlMWY5YzI0NjFlZDMwYyBqZGs3LWIxNDcKLTRmMGZjYjgxMjc2NzU5NGZlOWRlNTA5Zjk0NmI1Njk0MmRiNWEyZjAgamRrOC1iMDEKLWNhNGQ2YWQ1NWE2NjBmMDQ2OTg4MmU4NWI0ZGFjZjc4MjJkNTBhYmYgamRrOC1iMDIKLTdhNzQzNzFjZTBjNjQxMDhiODU3YzQ5N2FlMTMwZGZlOTUxNDUzMmMgamRrOC1iMDMKLWFjYmNhZGVmMGIyMTU4MmFiZjQwNmYwN2YxYjc0ZDJiOGY4MGRjMDEgamRrOC1iMDQKLWZmMGEzZDc4ZTdhMjI3NDNlYWJiYWE3MWU5ZDE3YjJmMDk0ZGRmNjIgamRrOC1iMDUKLWQ3YjgxOTJlNzI3N2M0OWI5YzcwMmY0YzRmZDk5YmQ4M2JhOTQ3ZWEgamRrOC1iMDYKLWMxMTQzMDY1NzZkY2MxY2I4NzFhNDgwNThiNDFiZjdkODdjZTg4MmEgamRrOC1iMDcKLWRlNDc5NGRkNjljNDhiMDgwMjlkMTU4YTk3Mjk5M2ZmOWQ1NjI3ZGYgamRrOC1iMDgKLTkzNTU0MzI0YzAxNDI4MjU3MWFlZWI0ODU1MmFkMDBkM2ZlZGIwODkgamRrOC1iMDkKLWQyMWE0ZDUxNDFjMDRiYzllODhmMmMwMjUzMTIxZDQ0OWI2NmQ2NjcgamRrOC1iMTAKLWQxYjdhNGY2ZGQyMDY1ZmRlYWZiY2RmZDlkY2MwMDcyZGE4YzY4ODEgamRrOC1iMTEKLWNhOTc3ZDE2NzY5N2E1NjFjMDQ4OTQxODdmYzFjNGQ5Mjc1ODJmZmEgamRrOC1iMTIKLWJjYzczOTIyOWY2Mzg0Nzg2YzdhYzBiNTJjMTgyMmM4NTY3NGRjZjEgamRrOC1iMTMKLTlkMGM5ZDYzODc1N2NiMDlkZTE4OTMzYjk0NmZhMDRiNGYzZmI5NGYgamRrOC1iMTQKLTgwNGY2NjZkNmQ0NGUzM2NhYWMxMmFkOGRhM2QyNzgwYWM0NGVmNzIgamRrOC1iMTUKLTA5ZWI1MTc0MDRiMDU5NjA3YWNhMzBjZGQxYWY4M2ZmYzU3ZWFmZWIgamRrOC1iMTcKLTA5ZWI1MTc0MDRiMDU5NjA3YWNhMzBjZGQxYWY4M2ZmYzU3ZWFmZWIgamRrOC1iMTYKLWViZWM2YTdlOGQ0ZTQ4MWQyMDVhMjEwOWRkZWVhODEyMWQ3NmRiN2YgamRrOC1iMTgKLWRmZmViNjJiMWE3ZmM4YjMxNmJmNThmZTU0NzkzMjNmMzY2MTg5NGUgamRrOC1iMTkKLWYwNTJhYmI4ZjM3NDQ0YmE3Nzg1ODkxMzg4N2QwZDkyNzk1ZGQ2YjggamRrOC1iMjAKLWQ0MWVlYWRmNWMxMzQ0Yjg4YzUwNTFhOTk3YWVjOWUxYWQ3Y2UxZGIgamRrOC1iMjEKLWNmOWQ2ZWM0NGY4OTEyMzZhZDE4NDUxMDIxZDZkY2Q1N2RjODJmN2IgamRrOC1iMjIKLTk1MTAyZmQzMzQxODNkMTVkYzk4YTk1ZGQwZDc0OTUyN2I2YzczMDAgamRrOC1iMjMKLTc4MzY2NTVlMjQ5NTY0NmM0NjJmMTNkZTczZGNjM2FkYTE5N2I2NGYgamRrOC1iMjQKLWJiNjk0YzE1MWZjN2I1YzhmOWVkYzhhZjZhODA3Mzg1MzBmZWFjYWYgamRrOC1iMjUKLWRiYjcyODNjMTk3YjI3ZGExZmMxMmFlOGE4Mzc4NWM4NTFiNjhjMTIgamRrOC1iMjYKLTgwYzQ3ZWI4M2QyNGZkZDY0YmJiNDhmMjg4YmQ2ZDRmMDNlMGVjODggamRrOC1iMjcKLWYzMjQ0YzFmMDQ4NjRkMzVjNDFmYThkMTM2NjlmYWY0ZjY1YjgxZTIgamRrOC1iMjgKLTI1MDk5YTc0NWUxYTQzNTc5YjZhZjg2YjNlMDUyYjJlNTA5NTg3NTMgamRrOC1iMjkKLTNiZTMwYzI1YTgyNTU4MDM2NTJiNWM0NjYzMzYwNTVkMzZlMmJhMjEgamRrOC1iMzAKLTk0YWFiZTA5ODkxNjQ0MGFlNzkxMTg2NjMxMWM5NjE3ZDg0ODFhMzYgamRrOC1iMzEKLTYwOTYwZmJjNzVkZjhiZTRjMWEyNTA0YWE2OWZjMTQyOGNjOTRmOTMgamRrOC1iMzIKLTliY2FiMmI4YjhlYTU3OGU1OTQ5MTZhM2QzZGY2ZGJlYzc5ODRiY2IgamRrOC1iMzMKLThiOTFhODk3YTA0NDg2Y2Y5MDFhZjBkZTdmNjg0YTNlYjMxZjEyMWYgamRrOC1iMzQKLWUxODdmM2VkZTY0OTY1ZGMyOTc5ZGY5YTIxMTEwN2NkM2QzOGVhY2IgamRrOC1iMzUKLWNmZDI4OGZlMWQzZTJiNzAwODM4MzQyZTcwZDcxZDQ0YWM5OTFhZjUgamRrOC1iMzYKLTkwMjA0YmZhYjRlMmJlZDQwMmJhZGNjOTk3Y2JmODQ0NmFiNTY2OWYgamRrOC1iMzcKLTViYmUwY2I2ZjJmMmQ3Y2UyOTJkYTc3YmY0ZmE5ZDYxOGQ3NzBhNzggamRrOC1iMzgKLWY5NWZkYmU1MjVjODhlZjBkNTdkYzEzOTBiZTY1ODJhOGFmNWUwN2MgamRrOC1iMzkKLTllY2ZkYmQ2YWVkNDcwMjY3NGVhZWRlMjAyM2I0YTE5NTEzZDZiMzYgamRrOC1iNDAKLTZmNWMwZTE3NDE1ZGU3YTljNzQ5MDBlZjRiYTEyZjQ3YWNjZGY4OGIgamRrOC1iNDEKLTM5ZWUwM2MxNjAyMTU1ZmYwMmU1ZmViNmNkNDQ4Njk0NTJmMjRjZjcgamRrOC1iNDIKLWVmZjRlY2U5YzhiYzQzYjNjZTJiMzc1ODU3NGM0YzIwMTQ3ZjA2ODkgamRrOC1iNDMKLTBiM2YzYTRjZTEzOTMwNDMwYjMyYjYxNmE3MTdkZmM3ZmUzODViMjggamRrOC1iNDQKLTU3NDc2ZjY2ZTEzYzU1ZWVhMmYyZmUyYjg1ODM2OWE0YzY0Yjk5MzYgamRrOC1iNDUKLTMwMGY0NWU5OTA2NDNhZjIzMGQ2Y2NhMzk0NzdmZjYyYzQ0YTlhNTQgamRrOC1iNDYKLTQwNDUyMTk0NGFjOTM4M2FmZGE3ZDU1ZDYwNzEzYjIxMmM3MzA2NDYgamRrOC1iNDcKLTFjODhkYTlhMTM2NTc5N2U0OWJlNzdhZTQyYzM0YmJjMGEzYzNmMGMgamRrOC1iNDgKLWY4MWU5ODFlY2E3YjYzMzE2Y2Y5ZDc3OGY5MzkwM2E0ZmM2MjE2MWQgamRrOC1iNDkKLTI3OTFlYzU1ZjY2YjU3YTcwMjM0OWM2NDk1NjdhMzkxZTYzMDFmNGUgamRrOC1iNTAKLWRjMWVhNzdlZDlkOTc0NmUwZjk4YmIxMjY4OTg3YzM1OTZjOGI0YjUgamRrOC1iNTEKLWJkM2MwMGQ1NzYxNDA4OTU0Y2MyOWZmYjgyMDE2YTc2Y2JjOTBiNDMgamRrOC1iNTIKLTJjNTY2ZjI1YzM5ZjAwODc0NjRiNzNlM2JjZjFjMTQyMWQwZjJhN2UgamRrOC1iNTMKLTdkZDgxY2NiN2MxMTM0ZGY3MDk2OWIzMDY4YjFlOThkZWY3MDE3NDYgamRrOC1iNTQKLTdjMjM2MzY2Njg5MGM2Njc1MTk0OTQ4ZmJjZDc0ZDgxZGRiODQyOTggamRrOC1iNTUKLWYxOWQ2M2IyMTE5YTAwOTJmMDE2MjAzOTgxZmZlZjVjYzMxYmMzYzUgamRrOC1iNTYKLTdjOTQ3NWM3NjE4Y2IxMzFiY2Q3NDcwZjg1OWJmNDNjNWU1Zjk5MDUgamRrOC1iNTcKLTFjYjE5YWJiM2Y3YjQwYmYyMzNiMzQ5Y2QyZjUxZjAyZDM3YTlmNWIgamRrOC1iNTgKLWFmOWU4YjBmMTkwMGI2MzFhOGEwZmNjY2ZmOWYxNTE0ZmU1OGM4MDggamRrOC1iNTkKLTJkMWRmZjUzMTBkYWFmMjI2NDIxYThjOTI4MjNjYjhhZmNmMzVmMzEgamRrOC1iNjAKLTZiMWRiMGI0MWQyZjZlMmE3YjNiZGJjOGE4ZGI4MjNiNDc3NTI5MDYgamRrOC1iNjEKLTVkMGZhMDEwOGQwMjhjMDU3NTNhNDdiY2YyYTU5ODM1N2RhYmYwYzAgamRrOC1iNjIKLTE5MmQ4YTI0NGJjMzY0Mjc3NTc4NjZlOWZiM2EwODkzOGMwZTY3NGMgamRrOC1iNjMKLTI3YWI3OTU2OGMzNGFiZjgwOTU4ZDVmYThjMDRmZDE3NDBkMjQzZGEgamRrOC1iNjQKLTVjZjNjNjlhOTNkNmQwODhhMWNkZmEyODAzMWQ0ZjBmOTQzOGMwZGUgamRrOC1iNjUKLWU2YWYxYWQ0NjRlM2Q5YjExNTRiOWY5ZWQ5YTUzNzNiOTdkMTI5ZmMgamRrOC1iNjYKLTgzZGYzNDkzY2EzY2YwYmUwNzdmMWQwZGQ5MDExOTQ1NmYyNjZmNTQgamRrOC1iNjcKLWI4NTRlNzAwODQyMTRlOWRjZjFiMzczNzNmNmU0YjFhNjg3NjBlMDMgamRrOC1iNjgKLTc4OWE4NTVkZTk1OWY3ZTk2MDBlNTc3NTljNmMzZGJiMGIyNGQ3OGIgamRrOC1iNjkKLTZlYzllZGZmYzI4NmM5YzlhYzk2YzljZDIwNTBiMDFjYjVkNTE0YTggamRrOC1iNzAKLTQ5OWJlOTUyYTI5MWNlYzFkYzc3NGE4NGEyMzg5NDFkNmZhZjc3MmQgamRrOC1iNzEKLWJkZjJhZjcyMmE2YjU0ZmNhNDdkOGM1MWQxN2ExYjhmNDFkZDdhM2UgamRrOC1iNzIKLTg0OTQ2NDA0ZDFlMWRlMDAzZWQyYmYyMThlZjhkNDg5MDZhOTBlMzcgamRrOC1iNzMKLTIwODdlMjRhNDM1N2VjZWI2NDMyZTk0OTE4ZTc1ZmRjNzA2YTI3ZDYgamRrOC1iNzQKLWZmMGI3M2E2YjNmNmNlYTY0NGQzN2Q1NmQ3NDZhMzc3NDM0MTlmYTcgamRrOC1iNzUKLTBjMDg1OTM5NDRkMGNkMzA2NDVmNmUxZTQ5NDZjNTFmZjJiMTBjOGMgamRrOC1iNzYKLTU3M2U3ODljMTg3YTY5YTNhZTAwYmZmZDI2ZWIzNWMwZjRhNjA2MzYgamRrOC1iNzcKLTAwOTU4YzVhNzA3MGJkNTc4YWE4YjcwNzczY2IzZjIwNGE5YzFiZTEgamRrOC1iNzgKLTU4ZmEwNjVkZDVkNjYzZDYyZjg1NDAyNDYxMzg4ZmI3YTkyNjU2ZmEgamRrOC1iNzkKLTQ4NzNhMDQ5OWJjM2JkMjYzYjdkZDNiNTUxYTJiNGUyNzVhYjVhMGIgamRrOC1iODAKLWVmMzQ5NTU1NWE0YzZlNzA2YTMwNThjMThhYTIyOWIxNDIyMGRlMGIgamRrOC1iODEKLWQ1YTU4MjkxZjA5YTUwODFlYWYyMmMyYTZhYjJmOWNlZDRiNzg4ODIgamRrOC1iODIKLWE0NmQ2OWExYThlYzk2NTJhNDgxMTQ4MjM1MzUzNzJlMWM5ODA3OTkgamRrOC1iODMKLWY1ZjQwMDk0ZmZjYzEyMzBlMmE1Zjc2ZWE0Yzk2ODY0NTM2OWJlNmMgamRrOC1iODQKLTQxYjUwZTJjNWVhM2Y0YWExYWY3MjllMWRlYjE2NzhjYjNlMWVmOWMgamRrOC1iODUKLWNhNzFlYzM3YjJlZmM5YzNmMDk3MWViYWJiM2E2ZWIxMjEzZDc2ZGUgamRrOC1iODYKLWVkZGJjOGFkMjQzNWE4OWY2NDcyOTUxMjMzN2M5ZjI2NjllNGRkODUgamRrOC1iODcKLTcxMjJmN2JiMGZjYzhhMzllNTI1NDQwMjExOWIyZWUzZmEwYWQzMTMgamRrOC1iODgKLTg5M2QyYmE4YmJlYTNhOGQwOTBlNTFkOGVhZWEyODViMzkwNzg5ZWEgamRrOC1iODkKLTY2OGFjYzBlMTAzNGJjMWJlYzZkMDJiZTkyZTBkZDRhNjNkMDY2N2UgamRrOC1iOTAKLWUzMDY1ZmIwNzg3N2M3ZTk2ZThiOTM0MTZmZTJhYjlhNGM5ZWIyYTUgamRrOC1iOTEKLTFhYjVkOGQ2ZWFiODFlNjVjNmMzY2YyMTczOTQ3NGNkNjdhMGU3Y2YgamRrOC1iOTIKLWQ1ODNhNDkxZDYzYzQ5ZWVkYTQ4Njk1MjUwNDgwNzVkYTFjYjU5NmUgamRrOC1iOTMKLWM4NDY1OGUxNzQwZGY2NDkzMTAwNWE5YmM0YzhlY2VmMzhlYjQ3YzMgamRrOC1iOTQKLWI4YzVmNGI2ZjBmZmZiNDQ2MThmYzYwOWE1ODQ5NTNjNGVkNjdjMGIgamRrOC1iOTUKLTYxMjFlZmQyOTkyMzViMDU3ZjNkZTk0YjBhNDE1OGMzODhjMjkwN2MgamRrOC1iOTYKLTZjODMwZGIyOGQyMTEwOGYzMmFmOTkwZWNmNGQ4MGE3NTg4Nzk4MGQgamRrOC1iOTcKLTE1ZTViYjUxYmMwY2Q4OTMwNGRjMmY3ZjI5YjRjODAwMmU2MzIzNTMgamRrOC1iOTgKLWFkZjQ5YzNlZjgzYzE2MGQ1M2VjZTYyMzA0OWIyY2RjY2FmNzhmYzcgamRrOC1iOTkKLTVkMTk3NGMxZDdiOWE4NjQzMWJjMjUzZGM1YTZhNTJkNDU4NjYyMmUgamRrOC1iMTAwCi0wYTc0MzJmODk4ZTU3OWVhMzVlOGM1MWUzZWRhYjM3Zjk0OTE2OGU0IGpkazgtYjEwMQotN2NmZmFmYTYwNmU5ZmI4NjVlN2I1ZTZhNTZlMGE2ODFjZTVjZjYxNyBqZGs4LWIxMDIKLWIxY2VhYjU4MmZjNmQ3OTViMjBhYWE4YTNmZGUyZWJhMzRhZjkzOTkgamRrOC1iMTAzCi1hMjJmZTliZDAxZTZjN2U3ZGRjNzk5NWRmYzk0NzE3MTE2OTJiOGQxIGpkazgtYjEwNAotMDlhNDZlYzExZjg4MDE1NDg4NmM3MGJlMDNhZmY1YWIyZGRmMGFiNyBqZGs4LWIxMDUKLWQzYmU4ZTNiNDI5ZGY5MTdlNzJjMWMyM2U3OTIwYzY1MTIxOWI1ODcgamRrOC1iMTA2Ci1kNmEzMmUzODMxYWFiMjBhOWEzYmM3OGNkYzBhNjBhYWFkNzI1YzZjIGpkazgtYjEwNwotOGFkZTNlZWQ2M2RhODcwNjdhNzEzN2MxMTFmNjg0YTgyMWU5ZTUzMSBqZGs4LWIxMDgKLTAyYmZhYjJhYTkzODk5ZTBmMDI1ODRmMWU4NTUzNzQ4NWExOTY1NTMgamRrOC1iMTA5Ci00Yzg0YzViNDQ3YjA5YWZmMjdmM2I3MjY2N2FiM2E1NDAxZTg1OTY4IGpkazgtYjExMAotMTdlZTBkM2U5N2ZkYjQxMmU0OGYxNGQ4N2Y1MDQ5NDZhNzA4Zjg0NiBqZGs4LWIxMTEKLWMxZjkxNThmYmI5YzJkYTUwZjY5NDZmZmZkOTc0ZTgyMzZlMDg0NDcgamRrOC1iMTEyCi0wMDQ2ZDIyNzgyMDRiN2VmZjc2ODAzZmM0NjIzY2I0OGM3ZTYzODRkIGpkazgtYjExMwotMWIxZTEyMTE3ZmUyODQwZTVkMjFhZTlhNGIzMDllNGY5ODFmM2VhOCBqZGs4LWIxMTQKLWY2MTBmZDQ2NDYzZTZiMDUzM2RkOTJiY2UxMWExZTdkODQ5ODRlNjQgamRrOC1iMTE1Ci1lNzU3ZWI5YWVlM2Q2YmVjN2RhMDc0YzQ3ZTA3NjE2MTA0YThkZjMzIGpkazgtYjExNgotYzFkMjM0ZDRmMTY0NzJhNTE2MzQ2NDQyMGZhMDBiMjVmZmE1Mjk4YSBqZGs4LWIxMTcKLWU0ZTUwNjkyNTBlNzE3ZGVmY2I1NTZlMmY2YmUyOTE0NjA5ODhjNTEgamRrOC1iMTE4Ci02OWE5MzAzNzZjNzBiZWI5ODc3OTcwMTI4YmFkMGYwNGNiMGM2ZWIxIGpkazgtYjExOQotNjRkOGIyMjhhNzJjZjkwODJiMWE5YTg4MWM4MTE4OGNjZmZkZTIzNCBqZGs4LWIxMjAKLTQwNDVlZGQzNWU4YmE3M2JmZGMyM2NlODk2MWI5NjQwZDQxNDVmZTUgamRrOC1iMTIxCi05M2JmMjU5MDNhZjBhOGVhZWM3OGQ3YjFhYjg1YTViODEyYzlhZWYyIGpkazgtYjEyMgotNGUzNWI1YjZkMmU1ZTI3NzcyZDU5YTcwYTU0ZTVkMDRmYzgwMWE2NCBqZGs4LWIxMjMKLTFhMjhmNzczYzg5NDMxMTMxODdlMzkzYmZkODA4ODVkZWRhYzNjY2QgamRrOHUyMC1iMDAKLTgzYmI5MjQyMzhmODAwZGI2OGZiNmY2MDE0MmNjNTE0OWQ3YTliZjYgamRrOC1iMTI0Ci1kOTg3NzkyOTE5ZTEyZWFmYzhiOTA0MmIxMWY5YzM1M2Q3YzQyOGI4IGpkazh1MjAtYjAxCi04M2JiOTI0MjM4ZjgwMGRiNjhmYjZmNjAxNDJjYzUxNDlkN2E5YmY2IGpkazgtYjEyNQotMzkwY2MyNzVjMDRjNGQ3YzhhMTRhODk1ZTliY2RjNTc2MjFhZjk2NiBqZGs4LWIxMjYKLWI2OGNkYjYzYTcwYmNhN2FhZDI4NDk0NjEwN2Q1ZDhkZDFkYmM2NjMgamRrOC1iMTI3Ci1iMTgzOTkyMmYxMGMwYzg4ZGVhNjgzNTkwZmEwOTNkMWQzODIwNDZjIGpkazgtYjEyOAotYjc3NTJjZWE3YzgxM2ZiOGIxZDNiZjJlMDVlOGY5MzMzMWNjN2YxZCBqZGs4LWIxMjkKLTBjYjBjZDAxNTIxODQ1YzJkNmY1MTcyYTllZjE3ODNkNGM4YmQ2NjggamRrOC1iMTMwCi03OWQ4YjdmYWMyMWQyNjNkYjVlNWViZDNiODMwYTNjZjk4NTA5NTQxIGpkazgtYjEzMQotNTk5MzM0NjAyMGQxNGExYzJjNzAwMzU4OGM1ODQzNjZkYjc5MjFmNSBqZGs4LWIxMzIKLTIyYjYzNjAxYmU2ZjA0ZmNiMmMzYjU2MzI2MWYxNDg2OTk1NGI0NGEgamRrOHU1LWIwMQotYmQ5N2ZmNWY4MjU4OGM2Mjc4NjkyMThkZjAyYTljMmRiYjk0MDJkMCBqZGs4dTUtYjAyCi0xOTViNzRiM2U1NzkwNWI2ZDZjOWVkOWIzMjEzOWM2NzgxYmE3ZDI4IGpkazh1NS1iMDMKLTEwNmZkY2RlNGI4YTY5ODFiZTEzZGFjMzRhM2RlOTlkNmZlY2U5N2MgamRrOHU1LWIwNAotOGY4NTliMWIwZjBiMThlZTdlMjMxZDY4ODdiMThiNTcyMWMyNDA0ZSBqZGs4dTExLWIwMAotNTdjNjk1YWYzZmU4MzhjMzZlYWVmNjQ3ZjJhZjU0M2NkNjA1MzNlNCBqZGs4dTUtYjA1Ci0wMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwIGpkazh1NS1iMDUKLThmODU5YjFiMGYwYjE4ZWU3ZTIzMWQ2ODg3YjE4YjU3MjFjMjQwNGUgamRrOHU1LWIwNQotZTIyYmM1NDhiNThhNjk1ZWVkZTAzMDQzOTk3NzczMTRhZTQ3MzU2MiBqZGs4dTUtYjA2Ci0wZjk2NTg0YjAyYjM5OWRmNzA2YmVjMjA1MmE3ZmU0OGJkYzYwNThiIGpkazh1NS1iMDcKLWJiZTYwNTM0NTI4ZDJlODExODk1N2FhYTc0YTc1YmVkYzFjMzgxOWEgamRrOHU1LWIwOAotZDliM2VmNDUxMTQzNGNmNTU4NzBkNDJiNmNhYTZhNTYxOGJjNDdjZSBqZGs4dTUtYjA5Ci00YjMyZWU4ZDcxMTI1MWU5MGFkZTFkOTU4YTUxZTEzNGMzZDM4N2M5IGpkazh1NS1iMTAKLWMxN2E4MjdiZWMyODdmNGM3NTY1YzcyYzE5NTY2N2U1MjE1NDc3MmIgamRrOHU1LWIxMQotMGU1MzE3Y2JlNDUxZDU3ZjlmZmNiYjgzNWRlMDdmZTU1M2E4YWEzNCBqZGs4dTUtYjEyCi1hMzAzZWJiMzM4NTE4YTcxNmMyNjdiMTc5ODY2MzRlMzU3NGU3Y2ZlIGpkazh1NS1iMTMKLWFjZDA2NmM4NTRiMTFmZmVkNjJkOGYxMzIyMDVmMjIyOTYzZjRmMWUgamRrOHU1LWIzMQotM2UxNjMxZjU0NTM5Y2MyMTc3MDY1OWRjZjYxNDQwNjkzYWM1ZmE3OSBqZGs4dTExLWIwMQotNmVhZjU2NTY5MWExMzMyOGU4MjQ3M2Q3MGRmZDBmZWI4ZmIyZjVlOCBqZGs4dTExLWIwMgotMzZkNzEzYzMzMzlhZDk0NTUyMWQyOThlZWIyMWM2N2VlODU2MzQ0ZSBqZGs4dTExLWIwMwotYTI1MDIwYmRjYTExYWNhZDg1NDU0YTM1YTk5MTJmZDFiNDE2OGQ4MyBqZGs4dTExLWIwNAotNjVlNWVlMjQ5ZWJjODFjMGNjZmZmMjM5NDZhMGEyYTZkNGJlY2RjYyBqZGs4dTExLWIwNQotYmVhZmViMGI3YTE3OGEzOTA2YmNiN2RjZjQ2ZjNjOWE5Yzk3MTdjNSBqZGs4dTExLWIwNgotMTkyM2M3NTllNWVkN2U5YTkyNTEyNzk3MjY5ZDk5N2NhZTExMzViOCBqZGs4dTExLWIwNwotNjFmYWFmYTQ1NTAyZTRlNmRiNmNlOTAyNmQyYTdmMjEyMWRjYWUzZiBqZGs4dTExLWIwOAotYTAxZmQ5NzFlZjY2Nzk3N2ExMzFmNWZiYWFlZTMwMGU1MDA0MjRjMyBqZGs4dTExLWIwOQotMWQ4OTRhOWQzMDhjNGIzYTY0ZTg3NjA5N2MyZTBlMWU1NzdjZmQ3MyBqZGs4dTExLWIxMAotNDFlZGQ3MWFmNDFmMTEwMGI5NjVlMGZhYjg4Zjk3ZDNjMTMwZTNkZSBqZGs4dTExLWIxMQotODM4MTgzYWY2ZDcwMGM5MWI5MTQ4NDM5OTJmZmEwMjEyYmNiN2RkYyBqZGs4dTExLWIxMgotNDA1OTBiYmU2ZmMyNDRkYmRlYzRiNjYwOTYzYmNmYzI1YmQyZmVjMSBqZGs4dTExLWIzMQotZGU5ZWMxMjQ2YTBjNWMwYjMyY2UzODE4Mzg2MDE5ZmQ0YTZmY2VhYSBqZGs4dTIwLWIwMgotNDdjZGZlMjcxYjFlOTdlNTkwNmViMWI5NmNkN2QxNWYwNzE3YTExOCBqZGs4dTIwLWIwMwotZjY3NDJkMGNmNzEyMDFmMWZmZDA1ODRjMWYyOTkwZGYzNDNiYzVlYiBqZGs4dTIwLWIwNAotZmM2Y2E5MjY4OGVmMDYyNWQyMDg4MWE5YzkwNTIzZDQ5YjE3NzNkNCBqZGs4dTIwLWIwNQotMGNiMGNkMDE1MjE4NDVjMmQ2ZjUxNzJhOWVmMTc4M2Q0YzhiZDY2OCBqZGs4LWIxMzAKLTc5ZDhiN2ZhYzIxZDI2M2RiNWU1ZWJkM2I4MzBhM2NmOTg1MDk1NDEgamRrOC1iMTMxCi01OTkzMzQ2MDIwZDE0YTFjMmM3MDAzNTg4YzU4NDM2NmRiNzkyMWY1IGpkazgtYjEzMgotN2IxYTZkYThhZDgyYjhmNTc2ZjIxYWUwNjkyZTgyNTM5NWY4YjMxYiBqZGs4dTIwLWIwNgotMzBiOGJhY2ViNzJiY2VjMTExYzZhYWQzN2VlZjk2ZDE4YzA5ZTRlZiBqZGs4dTIwLWIwNwotNjhlMmVhMzJmOTI3MzFiOGFkODE1NzI1MjExNmRiODk5MDNiNTFhMyBqZGs4dTIwLWIwOAotYjcwNmU5Nzc1YmY3NTEyODQ1MTIwNzQwODcwZjcxNzM0MWUyYjQ5NyBqZGs4dTIwLWIwOQotYzM1NmRlNzA1MWVhNmQyNWRlMDdlZjg2ZjYwZWI2NjQ3ZWFhZjJkMCBqZGs4dTIwLWIxMAotNDBiNjQ0MGU1NjllNWY3YTAwZjU3NjNlZGRjNmRjOGFlMjQ0MjFmMSBqZGs4dTIwLWIxMQotOGY0OWY5NjkwMzA1NzRlNDZhNTJmM2JjYmQ3Nzc5MDA0NWEyZWMwNyBqZGs4dTIwLWIxMgotNzc3N2RkNDE0MzU5OTMxMDg1M2UxZTllYTUyZjhiNzliMjk0OGMxNSBqZGs4dTIwLWIxMwotNjQxMzMzZGQ3Y2UyYjQ2ZDRiODM2NmQ3MTk0Nzk4YzNmYjI4YmI1NSBqZGs4dTIwLWIxNAotZDAzOTYwYjk3ZWM4YWRjNTM3ZjkyYmFlOTc1NGU5Y2E2MzAzODgwYyBqZGs4dTIwLWIxNQotY2JkZTY4OWNhNzRhZGQ2ZjllNDdiYTdlNzUzZDRkYzlhMjhkZmQxNiBqZGs4dTIwLWIxNgotMzIxOGEyZDdlZGRiYjA1OGFmNDQ2OGM1NzIxYjNhODdmNGViMjNiZiBqZGs4dTIwLWIxNwotMjYyMzYzMTc1ZWM4Y2Q5ZjZmNzhiMzNkNTY3ZjExNjFlMmU3ZDQ5NCBqZGs4dTIwLWIxOAotYmViNjRmNmIxOTg5YmM0OTk1NGE0YWEyNmFkYTU0YTkxZWVmNjllYiBqZGs4dTIwLWIxOQotMjU1ZDk2MTk1NWU0ZmRiODNjZTEwNWFlOTkwYzI2Yjg3MDIyMzYzZiBqZGs4dTIwLWIyMAotM2ExYmJhODA3NmRhNGU1NDg4MjEyM2U5OGUyMTllYWIxYzMxY2NlZiBqZGs4dTIwLWIyMQotYmYxMTU2ODlkODliYjgyZGMxZWZiZTAzNDg2NTdlOTkzNzE1ZTg1MCBqZGs4dTIwLWIyMgotZDZkZWQ2MGNmZGM1Mzg2MWFlN2QxYTAxMGY5NWI1MDM2ZDYxMGU4MCBqZGs4dTIwLWIyMwotZGQwOWQ4YjllZGVmYjU2ODQ5NDE5NDFlNWQ5YjM1Yzg0ZWUwNjZmMyBqZGs4dTIwLWIyNAotZGQwOWQ4YjllZGVmYjU2ODQ5NDE5NDFlNWQ5YjM1Yzg0ZWUwNjZmMyBqZGs4dTIwLWIyNQotOTM4YjlkNTAyYzJiMGY5Njg0MTUxZTFiMWY0N2NmNzA1MmRiMTUwMiBqZGs4dTIwLWIyNgotZjczNDY0OWEzZjg5MzE2ZDg0ZmM2NjlmZGJmN2JiZmY5MmU3MjkxYSBqZGs4dTIwLWIzMQotZDc5MWExNzc0NGQ1MGE0NTZkNjBlZTUxMThkOGNiOTYzM2JiMzZkMiBqZGs4dTIwLWIzMgotNjVlNWVlMjQ5ZWJjODFjMGNjZmZmMjM5NDZhMGEyYTZkNGJlY2RjYyBqZGs4dTI1LWIwMAotYjI5Mjc3NTY1ZWRmZGVjZTRlMzkyOGIxMzVkNGZkODZhZTE0MWU0ZiBqZGs4dTI1LWIwMQotMDlkZjViZGE0NjcwOTAwNDEwOTA4NzNmNzFkNDE4ZWViY2FkZjUxNiBqZGs4dTI1LWIwMgotZjM1NjdlNmJlZDIyZWFmODljM2M3ZDY0ZTBiMWZhMzA4NzA3MjYwZiBqZGs4dTI1LWIwMwotYTRkMGYxMWNmMDhkNWRhZTkxYzVlOWFkMzg3YjFmZjg4Mzg4NTAzZCBqZGs4dTI1LWIwNAotMGM0OTE3Y2VhNjc4ZGMyYTM3NDViYWNhNzQwMTZmMGQ2ZjE2OTAxMiBqZGs4dTI1LWIwNQotZTg0ZDc4ZGQ5ZTA1MzNlYjExYzI2YjY5NzI3YzA0NDg5OGQxOWY2MCBqZGs4dTI1LWIwNgotN2FhYWVjMzFhMDMzMWFkMDkxYWJlZGY4MWM5MjhiNDdhOTgyMjIyZCBqZGs4dTI1LWIwNwotZTQ4YTQ1OTRmMTlhZDExOWJjMjdkODljNTNkZDM1ZDExZWQ2ZGE3ZCBqZGs4dTI1LWIwOAotYTA5ODkzYjhmNjE3OTEyNTY5MTk2ZDdiZDY0YTk2YzM0OTc5NmJlMCBqZGs4dTI1LWIwOQotODVkZTkxYjZlOTUzYzhjMjFhYzVlNmQ5YTVlMjg0Zjg2ZDc1OTY4MCBqZGs4dTI1LWIxMAotNWMxYWM0NjFmZWY3ZmUwZjgxMGJkOWQ2MDUxZGI1YTI0MjQ3ZGUxZCBqZGs4dTI1LWIxMQotYzA3OGU5MDRkYjBhN2JlNjUwZTRiYTJkNjY1Mjc3Nzg1ZTIyMTZiMCBqZGs4dTI1LWIxMgotMjQxODRjZmUwZjhiMGRhMGYzNDk5MzNhZTdiNWNjMTY0NTVhNTJiOCBqZGs4dTI1LWIxMwotOTBmM2I4Yjk3MGE4YmIzMTczMDgzMTExMjQ4MzcyYWZkYzYxNjUyZCBqZGs4dTI1LWIxNAotZjVhYzJlMjQyYmI5NWJlMGEzZGVkZGYzNzM2MjE3ODIwMjA4NjEzNyBqZGs4dTI1LWIxNQotZGY2OGIxMzJhNDcxZWQxZTgyNWE3OWJkMWQ4YWNiNDdkMmJjYzA0ZiBqZGs4dTI1LWIxNgotN2E3MjFlNTdiMzhmZjZjMWQzNGFmMGI4NmY2NDgyNTQwYTgxNWQ5MCBqZGs4dTI1LWIxNwotZmRkYmMwMGJkZTI4MWQ3ZDQzN2IwNTIyNjJlOTIxZWQ1MWRlOGI5YSBqZGs4dTI1LWIxOAotMzA0MjBhMzFhODFmMjFlMzYzZjQxMmFlOTgwMWI3NDY3YzhjYzkwOCBqZGs4dTI1LWIzMQotYjQyMzFlNjgyZjk4YzhmNzAzN2UwMGZlNmVmNDQ2ZDA1YTAxODExYiBqZGs4dTI1LWIzMgotMWMxN2ZmZGRiNzY2MjVlODM1ZDIyNWM4NGE4YzZmZjIzYzFlNTcyOSBqZGs4dTI1LWIzMwotMTliNmUxNjM0MzkyNWE0YmYyNzg3OTc5NWI1MzBkNGY2NGU1ZDI2MiBqZGs4dTMxLWIwMAotNDY5NzkyZDE3OTMwNGM5YjMyMTg5MzAxMTI1NDc1NzdlMWFlY2I3NyBqZGs4dTMxLWIwMQotYWRiZDNlMzFlZjFhOTViM2Y4MGE3N2RmYmI4NDNkNTJjMDUzYzZkMyBqZGs4dTMxLWIwMgotZDc5NjFjYTlhZmJjNzQ0Njc0ZWIzZmZkYThlZjIwMDMxNThmM2VhNiBqZGs4dTMxLWIwMwotM2JjZDM4YzkyZjIxNmU2ZTBmZDc0NzQyNzIwYjZmNzg2MzAxOTUzZSBqZGs4dTMxLWIwNAotMTdiY2EzZmUzMjViMzUzOTI5ZTBlZGEzZjFhYWE3Y2MyODA2YjkzZCBqZGs4dTMxLWIwNQotYTFhYjgxYjhjYzM2YjE1NmYyNzJiMjBkYTYyOTIyZDdmOGFhNmZlOSBqZGs4dTMxLWIwNgotNTczYjc2MTc4NWY3OThhOGI1MzY2YTg3YWNlYjczMjRiMzEyZjc0NyBqZGs4dTMxLWIwNwotNDNmMDgyMTkwMmE3MWMxZmNjYzk5YmUzNmEwYjIwNWIxYWU3OTE4MyBqZGs4dTMxLWIwOAotNjMwYjA1ZmIyZGRjZGFlZGE2MjY5ZGRiNzQzNTdmNjUxYjczZDZkNyBqZGs4dTMxLWIwOQotYjUxNjVhYzM1NTZlOTVjNDJhMjk1ZDNjYmVlZjhjZDZlNTYwN2IyNSBqZGs4dTMxLWIxMAotZjQ3NWRiYzcwMzQ1OTA0YmRhNmI1MjBhZjQzOTU1ZTI0NDI5Mjg4NiBqZGs4dTMxLWIxMQotNjU2M2U0MzgzNzdmMjA4NjI1MzU3N2UwODU5M2IxZGRmYjkwMWVmZiBqZGs4dTMxLWIxMgotMWRkODI4ZmQ5OGYxYjg0ZGU1ZGNhZGI5MDQzMjJiNzExZTc0ODlmZiBqZGs4dTMxLWIxMwotZGNjNTYzYzlkYjllZjI5MGEwNzgzMzc4ZDQzYTAzOWNkOTJhMDhlMyBqZGs4dTMxLWIzMQotMTE5ZjRhZTMxNTFmNDEzNGE1ZTYyMDM0ZTY2YTRjMTdmNTI0ODM4YiBqZGs4dTMxLWIzMgotZDhhNTk0ZmQ4NTA3MzQzZGMyM2ZhMThjMDFiMTdjOTZmY2VkNDdmZCBqZGs4dTMxLWIzMwotNjhmMGNkN2Q2MGQ0NWRmOGU0YjczYTg1ZTMxYTE2YWEwMjVkOTI3OCBqZGs4dTMxLWIzNAotM2ExYmJhODA3NmRhNGU1NDg4MjEyM2U5OGUyMTllYWIxYzMxY2NlZiBqZGs4dTQwLWIwMAotZjIxOWRhMzc4ZDA3NjhmZjA0MmQ3NzIyMWU1ZDIwNjc2ZWNjMTZmMCBqZGs4dTQwLWIwMQotMTZlZjIxMzRjMzJhNGU2MGI1YTYwMTA1YjM3MTE2M2FhNTkzNjI3OCBqZGs4dTQwLWIwMgotZDczMTQ0ZWU0NzFkNGQ0YzQ5ZGI5NGIzY2M4OTkwNDc5OTYxNDk5YSBqZGs4dTQwLWIwMwotMjNjMWE0MWQ3NWFkYzZmYzU3ZjY5NTI4YzJjODA0MDc5ZjQ0OWQ5NCBqZGs4dTQwLWIwNAotOGQ2MGNlYmY2YTBjMWNmMWE1NjY5ZTQ5ZGViNzk1YTE0NDVlODI2YiBqZGs4dTQwLWIwNQotNTBhMmFkZmE1N2ZjYmJlMTU4Nzk5MWQ1M2Y1OGQyMjcwNzBhMjRkYiBqZGs4dTQwLWIwNgotYjIyMTBkZTE1ODdiMTZjYTFkMWQ3ODFiNTVlMTliYzcwNzI0YzYyYiBqZGs4dTQwLWIwNwotNjQxZWI2NTQzYzcxODZkMWMyYzI2ZWFmOTY4MDNiMWU2YjQxMWQ5YSBqZGs4dTQwLWIwOAotYzQ1YzBlZTQxNjAwMjYyMDdjZWYxODUwYzIxNWMyNjkxZDQzYTk3ZCBqZGs4dTQwLWIwOQotMWY1MjQ4YmMwNzE0YTQ1MTYwNTI1ZDQ4YmZjZjQ1NWI5Y2RmODZhMyBqZGs4dTQwLWIxMAotMGJmNmRiYjZhYzRlMjI1OGQ0ZDgzMmJiOTQ5Y2IxYmUyNDAyYTg5OSBqZGs4dTQwLWIxMQotYjBjZGU0NGJkYmZkNjMzOTEyOGNhNWE3ZGJiYmZmYWFlY2FjNzkzYSBqZGs4dTQwLWIxMgotOWRmMDI3YzQwZjBmZTE1MGY2MDlmMWE1ZTczMWI3ZTY0OTkyM2YyYiBqZGs4dTQwLWIxMwotZDg4ODZkZWRlOTRkZWRjYWQ2NmU2ZDc3MGRhYzZiOGJjYTFlYjUxZCBqZGs4dTQwLWIxNAotZWQ0NmMwNWFmMjU3MGZlZWQ1ZWEyNjRlY2EwMmYyMjMwNTUxMDllOSBqZGs4dTQwLWIxNQotY2RhODFmYmVlYzk0YjMxZGJhMjdhMDQzZmJmNThmNDQyNTI0Y2RmNSBqZGs4dTQwLWIxNgotY2I2MzAyOTE2OGE1MmQ2MmQ4MmMzMzI1ZjEwOTI0MDVjMzE4ZTc4YyBqZGs4dTQwLWIxNwotNjEwM2Y1YTgxMTlhODU5MzdhZTAwNmYxOGI4ZGZjMDRmNzMzMTVkMCBqZGs4dTQwLWIxOAotM2I3MzczMmQ2ODg2ZGM4MTU1ZjBjMWZiYjEyNWNhNjBkOWUyZmQyYiBqZGs4dTQwLWIxOQotN2JmYzg4OTMzMGUwZWMxZmQ0OTU5OTBlYWEwZDdmMGMzOTBiNzMwNCBqZGs4dTQwLWIyMAotNzhkOTBkYjlkZTI4MDFlZWMwMTBjY2I5ZjBkYjNjYWY5NjlkZmMzYiBqZGs4dTQwLWIyMQotNTRhMTM0NTFjZTI0M2YyMTU5ZWQzOTk2ZTZlZmNmMzc0YTU3NTBjYSBqZGs4dTQwLWIyMgotZTA3ZmJhZTFlZmVhYzRlNTA1MTQzODRjYWE3ZDIyNmFmNzQxNDExNCBqZGs4dTQwLWIyMwotMDQ4Y2ViZDE3ZjczZjIzY2UyMjk1ZTM2MGYzMWMxYjY3ODgxOTVhYSBqZGs4dTQwLWIyNAotNGMwZDRjMzgyNzljNTc5MGFhNWI2MWIwM2M0Y2ZhOWIyYTU4YmM3MiBqZGs4dTQwLWIyNQotZjY5M2VmNjJjMjA3ZGQwMjkwOTU3Yzk1YmQ2MmFiNjUzYWZlNDYyNiBqZGs4dTQwLWIyNgotNTZmNmNhNzk0NjdkMDRlYjk1MzgzMTAyMDQ2ODM2YjZhYzdkMjgxMSBqZGs4dTQwLWIyNwotN2U0M2Q0ZTIwYTMzYjhiNmJkMDYxMTJlMzlkMzY3YjUxZGU5MjFhNyBqZGs4dTQwLWIzMQotOGZhY2JlNjYyZWMxMDZmMWFhZTI3MWY1YzU5OTA5ZTEyNDkzOGM0MCBqZGs4dTQwLWIzMgotYjAyMzAxYWVhYjc5YjFlZTc4NTlhZWViOTk0ZmE1YmEzMTEwNTczNCBqZGs4dTQwLWIzMwotOTI4NmFjYzYwMGE3NzlhY2I4YmNmYWIzOGU4MmQ0ZjUwNzA0YWZlMyBqZGs4dTQ1LWIwMAotOWZkZWQ2NWUxZDM2ZTMzODgxMTE5NTVkNTBlYmY4NTExZGQwMzQ1ZSBqZGs4dTQ1LWIwMQotNjI1NjZhM2RiZTU5ODI1NjVjZTNlNDY4ZWUzOTgwYjc5MzdhODZjYyBqZGs4dTQ1LWIwMgotNjI5MDk2NzgzYzI3NTEwYzY1NjIyOWIxYWRjN2ZiMTgwY2FkYTljNiBqZGs4dTQ1LWIwMwotODU1ODUwMTJiOTc2YjcyNjY1ZjhmNzc0MDUyNmJkZTI1Y2NjNjJlNCBqZGs4dTQ1LWIwNAotZGEwMjViYWRlNjQ1ZjBkMWUwZWYyZjgyNTMyMGJkNWFmMGMyM2ViYSBqZGs4dTQ1LWIwNQotNDliYzU0NzJkZWQ0MWM3N2RhYmIwODQwZDM4NWNiZWUxZDYwZDhlOSBqZGs4dTQ1LWIwNgotMDYxOTMwYmQ3ZDhmYzJmMDUwNDJlN2VlYjMyYWRmZjE3NTljNmQ2MiBqZGs4dTQ1LWIwNwotNTBmYmEzOGYzYTI5ZjU1YmFhYWUyZGE5YjM5MmJmOWFiYzgzODljMSBqZGs4dTQ1LWIwOAotZjg5M2Q4YjlhMGQxNDg5NTEwMTQ2MTBiMWFhYjJiYTBhNTEwNWRmZSBqZGs4dTQ1LWIwOQotNGRlMThhNjI5MDQ4YjkwZTBkODc1YjljMGJkMzE4MDBmMWNjMDJhZSBqZGs4dTQ1LWIxMAotZDQwNDIzNDBmZTBhYTlkMzNhMTYxODkwZTE3OWJjMjFiNmM3YjhlNiBqZGs4dTQ1LWIxMQotOTFkMTEwMjI2NGU5YjU4YjJhZGE0YjVmMTEyZDQ3MmYwZDg2MDkyYiBqZGs4dTQ1LWIxMgotYTE1MDI1NzQyZjIwMWYwNWVhZDNkNzMxNzgwYTRhZDQzNzUyNDQ5MSBqZGs4dTQ1LWIxMwotZTAxNjdlYzlkNzU5NmFiOWFjNTJhOGMzYjg1YzFhZWY1ZDNmYmQ5MiBqZGs4dTQ1LWIxNAotYmY4MTNlMTBkMGJhYzE3ODY2ZWYyMzg5YmFhOGExZTY0OTRlNzgwMCBqZGs4dTQ1LWIxNQotNzQ0NTJiODI3YjYyYzMxMjIwNzA5ZDE0YTY1ZTcxZjM3Nzk1MTk5YSBqZGs4dTQ1LWIzMQotOTBmZTEzZWIzNTM4OGUwOTUzODNiY2I4MWVlYjZkMjQ4NzVlMzA1NCBqZGs4dTQ1LWIzMgotMzIwNmMzNWY4YTBlZDcyNGY1YjIwODVkYWMzYWExODViNGM4MmNkNSBqZGs4dTQ1LWIzMwotNjczOWYzYmNhMGQxYTc1ZjY3OWRkYmFjNjZhMWZiYTc3ZDZiM2E3YSBqZGs4dTQ1LWIzNAotNDZiNTRkMzgzMGYyMGE2YTI1NzNjMWRlMTY4NTczZWVjMjIxZGMzNiBqZGs4dTQ1LWIzNQotMzBlNDVjYWYwNmMyNWQ2NzQwZjQ5ODA3N2VjZGNiYTU0ZGEyMjY1ZCBqZGs4dTQ1LWIzNgotZDU4MzliNjdiZTRlYjY4MWQ1OWJjNmQyNDNiODQzOGJhZWMyZjA3ZSBqZGs4dTQ1LWIzNwotZWY0MzdlNTc2ZTM2NTRmNmY5YzBjYzExNmEwYTgyNGYzODJiOTAwNyBqZGs4dTUxLWIwMAotZDZkZGM5OTUwZmY1NWRjOWJlNDQ3MDRlZDU5NTU1ZTIyMWE4ZmNjOSBqZGs4dTUxLWIwMQotZGEwYWQwZjc1ZjA4ZDhmYmI0ZWU0ZDM5NWU0Mzg2YTQ2NjBiODU0ZSBqZGs4dTUxLWIwMgotMzQ3MzdkZmFkZDYzMGFmYmE2MGI2YWQ2M2E2OTZhZTMzNWQ3ZTk2MCBqZGs4dTUxLWIwMwotNzVmMDU1YWVlZTlmOWNhYjI4YTU4ZTFkZWVhOWVjYjg4ODViNjNkMCBqZGs4dTUxLWIwNAotNWU1N2NhNzg0ZGU5Y2U5MjU0N2MxMmQwYmMzNzk1YzQyNzk0Yjk2MiBqZGs4dTUxLWIwNQotMzZjOTdiNDE1NjNiN2JlZDcyMDE0ZGE2ZTQ5NzM5OGM3ODYxNmQ1YiBqZGs4dTUxLWIwNgotMDQ2YmNmOGY4ZTAwNTlmYTUzMTM2YjA2NTQ3MTEyOTMzZDUyODRkNiBqZGs4dTUxLWIwNwotNzEwYjU2ODAxZGUwMTQ3NzE2ZDkxYmU3MjI2YjEyNWI1YTY0YzJlZiBqZGs4dTUxLWIwOAotM2I0YzgzN2FiZGY2NzhlYTJlNjBlZmNkMmQyMGNjOWZmMTEyM2MwNiBqZGs4dTUxLWIwOQotN2FhY2Q4YzY3MTYwYWY2N2Y3YzlkODE5NzRkMDIxZWViMjI5OTI5ZSBqZGs4dTUxLWIxMAotMDQwMDU0MzJmYmE0OTgyZTVjMDczYmU1NWI5MTdmOGExMWM4MzhmMCBqZGs4dTUxLWIxMQotOTY2YzA0ZDU3MDI4ODI2MDNhMDJmNWJhNGE0ZTVkMTlkNDc5NjBmNiBqZGs4dTUxLWIxMgotM2Y1MzUzMjA4YTIyNmEzMWQ5YWQ4NjAxOGExN2ZlNWYzYjEwMmQ0YiBqZGs4dTUxLWIxMwotMzYxYWQ5MTIxNDY4Nzc2ZWVlMWQ2NDcwNDQ0ODFkODBlODMzNGZmYSBqZGs4dTUxLWIxNAotMTQ5NzVkOTA1ZDc2NGM1YTE4YjYwYjk5MWI5NzM3NWQ0MmRjZWNkNyBqZGs4dTUxLWIxNQotMDUwZjU2NTRmYTE5ZGI1MThiMzU0ZjA2YTY3ZTBlMWYwMzI4NGE0MSBqZGs4dTUxLWIxNgotNDUxOTc5OTc0OTY3MWNlZjY5MDkxZTM1NGI3Y2Q1MjQ5NmY2ZDk3MCBqZGs4dTUxLWIzMQotOTc1YjAxZTZiZTkzMjY3MmVkZDUyN2Y2ZWZlNGI0MzBkN2JjZjA3YSBqZGs4dTUxLWIzMgotNTlhZWE0NjIzMjc5N2YyNDdhYWI4NjlkNzUxZTRiODA5MGViNDc4OSBqZGs4dTUxLWIzMwotNTU2NTdlZTg1ZThlNDE1NzgzNmJiNGI3NDhkNzYyMzRiMTM2MGU5NSBqZGs4dTUxLWIzNAotM2I3MzczMmQ2ODg2ZGM4MTU1ZjBjMWZiYjEyNWNhNjBkOWUyZmQyYiBqZGs4dTYwLWIwMAotYjBlMTVjZDE2OWE5MzA4MGM0ZTMwZTllYjMwNjFkMGIzMjliZjM4YyBqZGs4dTYwLWIwMQotMGI2NGU3MjdiZGIwNmM4MmNhYTAyZWYyNWFjMjU1MmNlMzMxNDUzNyBqZGs4dTYwLWIwMgotMGMzZjRlNTA5MmQyMGVkNzY3NTRmZGIzMDAyYmViYjQ2OTUyMzc1ZSBqZGs4dTYwLWIwMwotYmQwNWExNDVlNTg5YjViYzIwMDg5OGEzNGQyZDBmNzgzNzJlOWVkMCBqZGs4dTYwLWIwNAotMTNhNTc5OWU5MGU5NThlZWE3YzcyYmM5MzgyOWQ3MDlhMTA1Mzk5NSBqZGs4dTYwLWIwNQotYjI2NWIzOTQ0NDM3OWNjZDlkNDAzOGE4ZjEwYzA1MjdmMTJiYTA2ZiBqZGs4dTYwLWIwNgotNTFlYWI2ODk5ODA2YjM5OWJjY2E0NTMzYWIwMTM2MmEzMDZlNGQwYiBqZGs4dTYwLWIwNwotMGVmM2UyMGYxZDQ4ZGRmOGIxODQ1MDM5Zjk3ZGMxMTc0ZDA3MDFhZCBqZGs4dTYwLWIwOAotNTY2ZmY0ZWU1MGJiZmJiOWY0MTQyODliODIwNmJlMDc3ZjA3Mjk0ZSBqZGs4dTYwLWIwOQotNDk3ZDEwNmQ0NzZkYjJlYWEwZTBjYTI3NTZlMjExZmRmOWYwZDM0ZSBqZGs4dTYwLWIxMAotYzhjNmU1NDlkMWE2ZTQ1NGFhOWZkNTk2NWE5NjZmNWUzYTg3MGU2MCBqZGs4dTYwLWIxMQotNDEyNTk3YjE3ZGY4YTQxMDliNGZjZjMyNjg3Nzg1YzJjOTNhYzUzNiBqZGs4dTYwLWIxMgotYzYxZmJlNTcyOWQ0ZDZjZTU1MjJmMzU3Yjk1ZjI4NWJhZGE4YjQ0MCBqZGs4dTYwLWIxMwotZGRiNGJmOGEzMDZhOGIwZDk0Y2E2Mzk5OTRiMmI0MjA2MzJkNDBiMyBqZGs4dTYwLWIxNAotMDQwY2U0YmY1YTQxMDQ3MTE2YTBiZTY0M2Q3OTFiOWM3NmM0MTJiMyBqZGs4dTYwLWIxNQotM2NiODQxZGVmYmEwNjljODkxZjgwZmIwM2UyYzcxZGFkOTk1YWU2YSBqZGs4dTYwLWIxNgotZTg4MmYzOGRmNzEzY2FjNWNlYzk4ZTE4YTAxM2E4MWNlOWZhZDBkMyBqZGs4dTYwLWIxNwotZWUzODlkMmNiNzg1MzE3YWUwYjhiYjJjNzNlNzJkYWY5NDM1ODI0ZCBqZGs4dTYwLWIxOAotYTg2ODkzMzgxZmJiMWMwM2VlNzQzYjY5MWE3YjdkNmE5MDkwM2VjYSBqZGs4dTYwLWIxOQotN2QwMzA1MDYyMGQ3NGU2ZTZiNjBjOWU2NGI1YjhjYmU1NTdjODIwMSBqZGs4dTYwLWIyMAotZGVmODAxNGU0OTcwOTlkNmYxYjFmYzY0NTU0YjE1MzQ1YTU3NGE5NiBqZGs4dTYwLWIyMQotYmMxYWQ1ZDgzYTY1MzM5YzQwYTE3NDA2ZWEzOGQyZWE4Y2JiOTgwNyBqZGs4dTYwLWIyMgotOWQ2YjYwN2RjYmY4MjBjZmVjMTdkNmY4Nzc1ZDg2NDk2MzBjZmIzNSBqZGs4dTYwLWIyMwotYzhlYTVhZmQzZDUzYTMxYjJhYWU3NmJjODE0ZTczODRjYWU4N2I4NyBqZGs4dTYwLWIyNAotN2E3NGZkNDc5MWU4NjZjMDMxZGYzYzIyY2ZjMTljZTcxZDNkOTUyZSBqZGs4dTYwLWIyNQotOWRiMTcyMWI1MjdlZWUzYjQxZmY3M2ZjZDM2YWUwNTIyMjdiYmY1OSBqZGs4dTYwLWIyNgotOGYyNjA4NTFlMDUxMTFjMzkzNTNhNmE0ZDA2ZTc1MmU3Yzg2ZWMzMSBqZGs4dTYwLWIyNwotMzdlN2YzNGMyMjMxZDk5YTRlZjNlYjJjMGIxYTY4OTk4MjhmMTFmNyBqZGs4dTYwLWIzMQotMzkzYWU1OTRhZTdjM2Y0YTc3NmM5NzZlMzhmYjQ1OThhZTFjNjlmZCBqZGs4dTYwLWIzMgotZDZlZjk2ODcxOTIwZTZmNmEwYzQzNzg1MGM1YWZiNmQ3ZmM1YjRmOCBqZGs4dTUyLWIwNgotYWE4YmZiMWIzZTgzYmRkYTY4N2Q2YzA2NWJiNTExNzRkOGNjNWE4MSBqZGs4dTUyLWIwNwotZDZlZjk2ODcxOTIwZTZmNmEwYzQzNzg1MGM1YWZiNmQ3ZmM1YjRmOCBqZGs4dTY1LWIwMAotMDRhZDczMjQwMzQxY2IwMmQyMGJiNTUxMGYxYTY2ZDllNjdjNDQzNyBqZGs4dTY1LWIwMQotYmQwYjQxYzNjN2Q0ZGU0MGMzMmVlNjNlYzI2Y2QzMTU3OTlhNWZiZSBqZGs4dTY1LWIwMgotYzY4Yzk0YjNmN2Y5NWIxNDA2ZWNiY2YxM2ZkMzU1ODE5MjQ4NWUxOSBqZGs4dTY1LWIwMwotOWY5ZTg1Y2RlZDlmMTg5MTExNWRiN2Q2N2QxOGFmMjIzYzU0ZjVhNyBqZGs4dTY1LWIwNAotOTc3ZDRhYzU1NjFlZTk0MDA5ZjcwODQ4YjFlZjdiMjYyMzA1NDVlMCBqZGs4dTY1LWIwNQotZjk4YjhmMDZhNDZhZDdkN2FiMTkxNzljODQ2NWMyODYxYmYxYTdmNiBqZGs4dTY1LWIwNgotOTc3ZmRjN2NlMjNlMTllNDNlYjczNTNjZGVjZjA5YjViN2RmZWFiMyBqZGs4dTY1LWIwNwotZTQ2YzYwOWQ0ZGZkYTU0MTE0YWQ3OTk1NWE0NjUzNTVjYmMxZTIzMCBqZGs4dTY1LWIwOAotMzkyYWJjZTVmMDI2Y2ZlNDQ2MzVmNWQ2MjMxNjY4ZDc3OTkzYzYzNyBqZGs4dTY1LWIwOQotMTdiYmNmZmU3NDhkMjAwMDMzMzJiOGM0ZTZlOTRjYjE1YTk2ZDcyNSBqZGs4dTY1LWIxMAotMTdiYmNmZmU3NDhkMjAwMDMzMzJiOGM0ZTZlOTRjYjE1YTk2ZDcyNSBqZGs4dTY1LWIxMAotMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMCBqZGs4dTY1LWIxMAotMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMCBqZGs4dTY1LWIxMAotMmRhMTkxNzFiZGZmZjdkOTk3MDA5ZmQxNzc2ZTg2YTE4ZjRmNzUzMSBqZGs4dTY1LWIxMAotOTkyMDY0ZjM0YWVmNmVlYzA1MzcwMTA5N2U1ZmY2MzQxZTRlNDE3MiBqZGs4dTY1LWIxMQotOWVlNzk1MjkyZjZhMjNkMWRkYzIyNGVmYjVjNGFlMGYwNzRlNWFlZiBqZGs4dTY1LWIxMgotOTA1ZjMxMjhhMWJmMWUyNmZjMjNkNTM3NDg1NmE3ODY2OWFhNTgzMSBqZGs4dTY1LWIxMwotMjk0YmEwNDFlMDQ1NDRiN2FiYjE4YzA4MTQxY2ViNGU4OTFkMWU2NiBqZGs4dTY1LWIxNAotOTczMTE5YjgyYjEzZjUxMzhmZTdkZjZiZTgzMWU4NjMxMDU0MjcxNyBqZGs4dTY1LWIxNQotNzgyYTAyOGIyMmFmMDNiMmU5MDE4Zjk2MGJkOTc3ZmRiMmI0NDBmOCBqZGs4dTY1LWIxNgotYjZiNjc1NmIwNDFkNDdiZWZkYjQ4YjJhNzFlMjU0ZjYxNTM5Yjk1YSBqZGs4dTY1LWIxNwotYmMxYWQ1ZDgzYTY1MzM5YzQwYTE3NDA2ZWEzOGQyZWE4Y2JiOTgwNyBqZGs4dTY2LWIwMAotMGYyZWQyN2M3ZDc5M2NlZTRkOTE1OTFjNmEwYjFhNzMwZTk4NTkwNiBqZGs4dTY2LWIwMQotMDk2MDM4YTc3MDE0MmIwZTY1MDFkMDRkMDMyODMxNjVkYTk2NjFjNiBqZGs4dTY2LWIwMgotYjZhYzNhMWI3YTJjNmJhMzk2ZTg5NGFjNWI5NjVlYTJhYjEwY2YzZCBqZGs4dTY2LWIwNwotODdjYjhmOTM5ZWM2NzkyM2EyMWRjOTc0MzZkMDlmNDhkYWQyMmVjYiBqZGs4dTY2LWIwOAotNTBjNWMyMmY4NTIwOTkzYTRmZmNjYWY2NmI0OGZhODgzNGYwMWMzNSBqZGs4dTY2LWIwOQotMDY5ZTY0YWJkMTllYzQ2YmY4NWQ3YjZiZjI3YjFiMzEwZDBhZTliNyBqZGs4dTY2LWIxMAotN2ZkYmIwNTI4MGY0NDQwZmNmM2JkMTE1MDk3YjY3ZjE3ZTJiMDMwYyBqZGs4dTY2LWIxMQotZDg1N2Q2MDMzYmYxNDk5YzAxNWVmMmEyMzEzZjUzYTNlNjQ5MWRmMyBqZGs4dTY2LWIxMgotNmU5ZDU0NDNkZWZkYzllZDU5NTUyODc5NGI4MmM2NGEwNDlkNWUyOCBqZGs4dTY2LWIxMwotOTRiNmUzZGRjMTkzMzQ1NzhhYmVmYmM0NGE3ZWM2ZjllMjBhNmUyNCBqZGs4dTY2LWIxNAotMjVjZjhkZGZjOGJmMTYzMjExZDFkZmQ3OWYzMTc2NWNhYzU4ZWVmNSBqZGs4dTY2LWIxNQotNDBjZTVhNmQ3MzNkNDRkOTNjYmQ1YzAxMDVhODIwYWQ3YTdmNDc1NCBqZGs4dTY2LWIxNgotZmMzNDg5MDFlOTU4ODQyYTc1N2Q1OWM2YjM1ODQ2ZDEzYWI4Njc5MyBqZGs4dTY2LWIxNwotNGFlMGMyZDZkZDI0OTMxZjNmMjcxZTY0NTIyMWU1MzMxZTM1MWMwMCBqZGs4dTY2LWIxOAotOGFmN2RhNmMxM2FmM2M5NWJjOTkzM2U2ZDFlMGQ4MzY0OGY2YzBhZSBqZGs4dTY2LWIzMQotMWRiNjAyNmUzOGQ0MWYyMTdiY2JlMmI2MTk3MTFiODUwYzE3ODhmNCBqZGs4dTY2LWIzMgotYTg1MDMwZGIwMjYxMDgxMzVhOTViODZjMzQzMjgwZWQ3YmRhMzIyYSBqZGs4dTY2LWIzMwotNTlkYzI1OWRiOWFkN2Q3ZWFhOThiOTU0MDczNGJkNWMyMmQ5YmM4NiBqZGs4dTY2LWIzNAotYTlmODI4MWQ4MzkxZTkwZjI1NWJiNzU0ZDFkNmIzMWRiYTE4ZTc3ZCBqZGs4dTY2LWIzNQotZDExYzNiYzA4ODFhODNiYWNmZDhmZDI1ZjdjOGQyOWNiNDA1YWZlNSBqZGs4dTY2LWIzNgotNzAwZGM2YzYyMzQzOWM1ZGY5ODI1M2ZiYTQ5Mzg3OTE5ZGQ4NzMyZCBqZGs4dTcxLWIwMAotZjEzZTM2YTRhYzgxOTI4MTk5MDMxMmYxM2YxNTZkYmI2ZjkxMzM3MSBqZGs4dTcxLWIwMQotOTBiY2E1MWZjZGFhMDY1YjgyM2VjZTYxZTRiMGFmMWFkODE5NTVlNSBqZGs4dTcxLWIwMgotMzMxMzRmMzVlZWEzZmJmZmQ2OTVkMjQyMjlkNzg5NGM3YzJjZjE0ZiBqZGs4dTcxLWIwMwotMjg5MjJmODYzOTczYjJkYzBjODdiNzY3Njg1OTU4ZWM3ZmMxM2I5NyBqZGs4dTcxLWIwNAotNmM3ODNjZGQ2ODVmNmZjOGJiYzI1ZTRkZWJiMDdjMjA5NmY3YjY0YSBqZGs4dTcxLWIwNQotYWUzOTFlM2I3MjU2OTdmMTdlNzM5ZWFmNmI2NjlhZjEwYzU0ZWQyOCBqZGs4dTcxLWIwNgotNWNhZGZlMTAyZTVjN2ZhMWQ1ZWEzNzk5MWEzZTdmYzAzMzdlN2ZhYiBqZGs4dTcxLWIwNwotNmVmYWVjODJlOGRhNDUyNjQ3MThjZTkzOTFiYzAyZjE5NmRhNjNhMCBqZGs4dTcxLWIwOAotMTkxODVkNGUwMDY2MWRlNjVmMzcwNzMyOGIwMTRlM2EwMTFmNTQ1NiBqZGs4dTcxLWIwOQotZDJkMWRlMzc5ZjkwYmFlYTQ5NGE3NDdiYWNmZGRmNmIwNTkxMDg5YiBqZGs4dTcxLWIxMAotZTcxOTcyZTkyMjMyYWQ1YmIxN2M3OTYwOWQ3NWFkM2I4MDYyYmYxMCBqZGs4dTcxLWIxMQotMTdmNTRhZmNiMTdmMTlkZmExODY4MDgxNDM3NmJiZTA2Y2E4MWUxMiBqZGs4dTcxLWIxMgotMjYwZWYxYzk4N2EyZDU2NmQ3Y2FmN2RlNGYzMWViMzBjMTQ0ZjczYiBqZGs4dTcxLWIxMwotMDc5ZmU2ZTViODUyNmEyYjhiOTJkZTVmZmNhYjUyZDJlMWFiZjNmMCBqZGs4dTcxLWIxNAotMTZhN2FkZWM1ZmFlOGJiODRlNDE1YmJlZGE2ZGE3MDRmMzhhNjE1NiBqZGs4dTcxLWIxNQotNjBlNjIzZDA2ZWJkY2RjNjgxOTQzYjE2ZjAwYTg3YWVlZGY0Njg3MyBqZGs4dTcyLWIwMAotMTc2YTJjZTJlMmQ2ZmQwNzk2NGVjYTYwYzI4YzZiMDA0OWQ3YmM0ZCBqZGs4dTcyLWIwMQotM2M1OTE1NjY1Mzk2MzAxYjczMGY4MDhmOGY1YWE2ZTk1YjdjNjExMyBqZGs4dTcyLWIwMgotZmIzOTVjYzNkZTc3OWFkNDI3NDA2M2MyYTFkODc2MTk0YmNmYWFiZiBqZGs4dTcyLWIwMwotNWI1NjI2NzE2Yzg4NjQ2ODk1YzRhZGE5ZWQxYTM1YjI0ZTcxNDhjOCBqZGs4dTcyLWIwNAotMTYzNmU0N2MyZDQ4ZDkyODI3ZGFjMTQ5M2QyOTJlYmUxOWEyZTEwOCBqZGs4dTcyLWIwNQotM2EzODYzYjEyODg0ZjYxNjcyNjFmOTk1YjVlYjBiOGM2OTQ5NWYzMCBqZGs4dTcyLWIwNgotODA0NWVmOTRmZDExZGJkYTg5NzQwNGRlMzQ1ZDFlYTFlZWY1MmEwMSBqZGs4dTcyLWIwNwotYmUwNTkyMGFmYTE3ZDM3NGJjODUzZDg5MGExNTc1ZGIwOTdhYzkxYyBqZGs4dTcyLWIwOAotODQwNGQzMTFjMTMzMzNkNGIyNDU1YmI3NWJmMWFhMTBhN2U1NWJjMiBqZGs4dTcyLWIwOQotNjE5YWI1NDk0MGZjMDJlMzI5NjZjZWVkY2JkNzcyNmQ3YjUwZWU5NyBqZGs4dTcyLWIxMAotOGNmZjMxNjlmYTdiOTVjNDc1OTljMTMxMmU0ZGFlOTdlYTUyMjhmMyBqZGs4dTcyLWIxMQotNjhiODgwZTBmNWRlMWQ0OTkxNDc5MGYxYTZlNWM2ZTRjMzg0NzQzNCBqZGs4dTcyLWIxMgotNTg2MzBmZGU2N2Y0YmE3YjBmYmU4NTA5YmIwYjEwNWYwNjUzODNhOCBqZGs4dTcyLWIxMwotMDVjMzVlYzA0ZDI5OGFkMTFhOTdhMGM4MmU1NGU0NDY4NTQyYzZlNyBqZGs4dTcyLWIxNAotMWJjYzQxODk0MzQwNWM1ZWY2NzdlYjNmNjM3ODM2ODMyNjFiZDJkMyBqZGs4dTcyLWIxNQotYWVlY2JhYTI3ZjgwN2NlMDY1NmExMDhjZDBlODE2Njk3MjRiOGQxYiBqZGs4dTczLWIwMAotOTAwOWE4YjJiNTUyNTY3NjRkZDMwNDkwMmIwNGEzZGVhMjU5NzY4NCBqZGs4dTczLWIwMQotN2EwMjE5ODVlZjAwOWMzYTg4YTIwNmQ2ZjI5NWYxN2UzODJmOThiOSBqZGs4dTczLWIwMgotMmU3Yjg5YzdmNzk3OTRiODcyZTczNzA4ZmRhYTNlZDkzMzFlYzQ1ZCBqZGs4dTc0LWIwMAotYWE5NDg1YTg4N2I3ZTk4M2Y5NzQzYzljMTE0ZGUyMDU1MDU1MzAwZCBqZGs4dTc0LWIwMQotYjMzMjVjMDUyNjYyMWY5ZGRmODI3MzgzNzNjYzhmODk0N2RhYjE5NSBqZGs4dTc0LWIwMgotMmIzZDBlNmYzY2QxNzllMjM0NjY3OWFmMmE4ODgxYmI2YjIwZjk2OCBqZGs4dTcyLWIzMQotYWVlY2JhYTI3ZjgwN2NlMDY1NmExMDhjZDBlODE2Njk3MjRiOGQxYiBqZGs4dTczLWIwMAotOTAwOWE4YjJiNTUyNTY3NjRkZDMwNDkwMmIwNGEzZGVhMjU5NzY4NCBqZGs4dTczLWIwMQotN2EwMjE5ODVlZjAwOWMzYTg4YTIwNmQ2ZjI5NWYxN2UzODJmOThiOSBqZGs4dTczLWIwMgotMmU3Yjg5YzdmNzk3OTRiODcyZTczNzA4ZmRhYTNlZDkzMzFlYzQ1ZCBqZGs4dTc0LWIwMAotYWE5NDg1YTg4N2I3ZTk4M2Y5NzQzYzljMTE0ZGUyMDU1MDU1MzAwZCBqZGs4dTc0LWIwMQotYjMzMjVjMDUyNjYyMWY5ZGRmODI3MzgzNzNjYzhmODk0N2RhYjE5NSBqZGs4dTc0LWIwMgotYzU4M2FjNTFlMmM3OGQ2YzU5Nzg2YjQ0Nzk4NmJhZjdiOTYxNTE4ZCBqZGs4dTc0LWIzMQotNGM4ZmQwODE0YmYwYmNiYzk2NjZhMjllMWRhYTM1YzY0YzdiYjU3YSBqZGs4dTc0LWIzMgotOGNjNTJlZGJiNzQxYzQyZTA5ZjRiMTMyY2EwYTc1OWQzZGU2Zjg0OCBqZGs4dTc3LWIwMAotOGYwZWQ4OTY5OGEyODEzODA2NWI2Yjk0MTc2OTY1MDYyNzYzNjc0NSBqZGs4dTc3LWIwMQotMjdmMTEzMDMyMGE1NWI2Yjg5MDI0Y2I4YmFhOTNjODc2N2M1MTZkMiBqZGs4dTc3LWIwMgotMWM3MTg5OWU4NTY2MjIzOTA4NWZhYjk0YWQ1YzI2NDQxZTdhODBjZCBqZGs4dTc3LWIwMwotYTQ5ZDhjN2RiMWU1YjNhYjg0NTYxMDY5YmQ0YWU2MzU3OTEzOTg3OCBqZGs4dTc3LWIzMQotZWNhMTY1YzA2NTRhYzJlMTkyNmI1MDY1NWU1ZWQ1ZTliNzNjYTY3NCBqZGs4dTc1LWIwMAotMDZjZGY1ZGM2NzllMGZlZjdjOGUzN2M1YzcxMmIyYzU4OTFjMTQ0NCBqZGs4dTc1LWIwMQotMjZjMjk3ZTlmMTFiNzhiNTVjZGVmZDIyODQ5YWU0ZmU1NTA0MmE1YiBqZGs4dTc1LWIwMgotMmEyOTI1MDNjNTU3MDRjYjdmODk4ZmExOTVkNzY2ODJjMGVhNmE3MiBqZGs4dTc1LWIwMwotY2IwNzJiMTJmNWRiZTNhMjQ5ZDU5NjA3OGQ5OGEzNGVjOTM2NDE4NyBqZGs4dTEwMS1iMDAKLWNiMDcyYjEyZjVkYmUzYTI0OWQ1OTYwNzhkOThhMzRlYzkzNjQxODcgamRrOHU3NS1iMDQKLTQwY2NjNDBkNTg0NTBlYjQ1MTgzNDhmNmIzNDg4NWM1YTcxMTY3NWEgamRrOHU3NS1iMDUKLWU3N2FjZWJlYmZkYzJmODRiMTIxN2JlM2E2YTJlYjRjMjA1YWZkYTUgamRrOHU3NS1iMDYKLWU1NDIzZGVkZWQxOTUzMWI3Mjg4NDgwYjA1OTIwOWM4MjUwNDZjZTQgamRrOHU3NS1iMDcKLTgyNDRjMmQ4ODVkNDEyYzA3YWU2M2I1MDJkMGIxZjhjZjRmOWYzOGQgamRrOHU3NS1iMDgKLTFiM2VmN2VkY2NiY2VlMTA2OTljNjQ3ZGEyM2I5OGNmZTdlYzFlZDcgamRrOHU3NS1iMDkKLWU5MjZjYmM5MzBmZjcyNzIyOTE5MTI0MmExNDVhYzYyNWRkZDdmYTAgamRrOHU3NS1iMTAKLWNlOWI4NDU0NTMwMjdhN2E2MzA5Mzk4YjFjYTJmMzJjZjE1MzRhZTUgamRrOHU3NS1iMTIKLThjYzUyZWRiYjc0MWM0MmUwOWY0YjEzMmNhMGE3NTlkM2RlNmY4NDggamRrOHU3Ny1iMDAKLThmMGVkODk2OThhMjgxMzgwNjViNmI5NDE3Njk2NTA2Mjc2MzY3NDUgamRrOHU3Ny1iMDEKLTI3ZjExMzAzMjBhNTViNmI4OTAyNGNiOGJhYTkzYzg3NjdjNTE2ZDIgamRrOHU3Ny1iMDIKLTFjNzE4OTllODU2NjIyMzkwODVmYWI5NGFkNWMyNjQ0MWU3YTgwY2QgamRrOHU3Ny1iMDMKLTZiMGQxZjA0YzQ4MDhhYWFiMzI3NzFlMDg5MmFjODNlNjY3MTRlY2IgamRrOHU5MS1iMDAKLTgxNzg5OGQ1MzgxNGRhNDJmNTY3OTk1YzkyMWYzZWE5MDAxNmRjY2MgamRrOHU5MS1iMTMKLWY2YmRhNTcyOWZmODZlOTY5MWNkNTFmMDQyNjFjMzk0Mjk3NGNlY2MgamRrOHU5MS1iMTQKLThiMGJmNTVhMDQxYWU1NjU3YjFhZTllNzRlNjgyNThlOGQzNmRkYTQgamRrOHU5MS1iMTUKLWFjYmNiNjY4MmM5YjNlNjZmOWNjNjFhNmE2MmU4Y2I1ZjI0Yzc1ZDMgamRrOHU3Ni1iMDAKLWIzYzkxNGFkODQyZDYxODE4ZTBjNTg1MDQwOWY3NzQ3OGIxM2FjYzYgamRrOHU3Ni1iMDEKLTc3MTE5MzNlYzE4NDYyZWNlOGExYjlhOTUyN2VjODczYzUyMGIxYWIgamRrOHU3Ni1iMDIKLTExZGQxYzEzZjFiZDc1ZjU4ZmMwYjAyMGM3NjdmMmMzMzFhYmIyYTcgamRrOHU3Ni1iMDMKLTFjYzFjMzUxMGZkOGI5ZmEyYTE4YmZhZDM5ODRjYTE2MDY5ZjAxM2UgamRrOHU3Ni1iMDQKLWVjOTcwMWIzODQ2YmU2ZGE2MWIxNWMzYjFmNDUzMDc3NDA0ZjdiNmEgamRrOHU3Ni1iMDUKLWNlODAxOWYyMTk0Mzk5NmI5NzcwZThmOWQzNWE2YzA3NmM3M2JiODIgamRrOHU3Ni1iMDYKLTNmMWEwMjhjMTUyZWFhMWNmOWNhOTdlZDZjN2ViYzIzOWIwOTY3YmUgamRrOHU3Ni1iMDcKLTc0YzBiMjc1ZDJkZGM2ZTE5NzY3N2FkYzI4NTMyZWU2MDI1NTU5YTYgamRrOHU3Ni1iMDgKLTJlNTg0MWY1N2RmNDRiMGY0OWU0OWVmM2I4MjdhN2JhYmY1MWJjYTcgamRrOHU3Ni1iMDkKLThjNGIyNTg4OTIwMjVlZTRkNWRmNDEwOWY5NzRiYTQ2NjVlZTEyMDggamRrOHU3Ni1iMTAKLTZhZmM4N2JkYWE3YjkzODU1ZTE1MmFhZDQzNzMwNWNlMGE0MjI1MWEgamRrOHU3Ni1iMTEKLTIzMzc2ODM3NmEzNjQ5YjNmMWY0NjUzZmUxYzQzMzI3MWZjNzc2ZWUgamRrOHU3Ni1iMTIKLTdlNDNlMTE1ZGZhZmVlNzAxNTJhMDFiOTlhYTlkZTI1YjQ0MTA1NzAgamRrOHU5Mi1iMDAKLTFiY2U4NDQxMWQzN2VjZjlhNDMzNWQxMzQ4ZjRiMmYwYjdhYjZlMDggamRrOHU5Mi1iMTMKLWZiOWY5OGVkNmVmMjUwNWE0MjQ4NjRmMGE5NDY4ZTU5Mjk4ZmVkZTYgamRrOHU5Mi1iMTQKLWFjODg3MTkzMTc5YmFlODJmZDFjZGY0ZDhjNDYzNDU3MTYzYTY1MzUgamRrOHU5Mi1iMzEKLWVkY2U1NWRkMTY0MjNiNzBlYmRiMzZhMTRiM2U2YzYyZDIyMzYzN2IgamRrOHU5Mi1iMzIKLTY5NTUwZGZlZTRiMWFkYjVjNzMxNzVmMDU1NWRkNjllNzQzNmNhOGIgamRrOHU5Mi1iMzMKLTc1NzU3MzA4ZDI3ODVhYjlkYzM2ZmRkZjAyMmU2ZDNmNmU5MjQ2YTYgamRrOHU5Mi1iMzQKLWNiMDcyYjEyZjVkYmUzYTI0OWQ1OTYwNzhkOThhMzRlYzkzNjQxODcgamRrOHU4MS1iMDAKLWZiNWUwYTE4YWQ3ZDQ5MTM0NjE2ODc5ZDFhNTAwYjEzNTZlMTJmZDQgamRrOHUxMDEtYjAxCi1jN2FlYjRlNTViMGY3ZGU4YzViZDJhNmU0MWRjNWM1NGM0MjM5MjcxIGpkazh1MTAxLWIwMgotYzY3OGMxYTMxYTU1M2ViZTdhOGZkMzg4OGFjYzI4MmRiZDk3NWUzYiBqZGs4dTEwMS1iMDMKLWE2YTAzMmE1NDkwZjQwMDBiZGZiMjVhMmY2MDRiMjJiY2RmOTVlY2YgamRrOHUxMDEtYjA0Ci04MGYzODk1OTZiZmFhMjJkNGQyMjgyYjg0MTdiOThhNTMyNDFmMmFhIGpkazh1MTAxLWIwNQotMDNmMmJmOTQxMGVmMmFhZDhkOGE1YWIwNDMyYWUwZGJkZjhiZmQ2MiBqZGs4dTEwMS1iMDYKLTM5ZTYyMGRkZjBiYjhjNmE2ZDZmMDU4OGM3MWQ1ZjQzZDhiY2M5ODcgamRrOHUxMDEtYjA3Ci0yMGI0NzE1OTc2MzM4ZDQzMDdjMmQ3MGUyMDVjZTg4ZjMxZmJkN2U3IGpkazh1MTAxLWIwOAotOTc5MzlkMDYxYTBlNDkyYzZjMmI0NjRkZjQ0MzczMTY1ZWNjMTVkMiBqZGs4dTEwMS1iMDkKLTAwNjZmZTcxYjEyMDNlMTAzZjdlMWEyMzU0YmQ5NGY2NWZkZjM4ZmQgamRrOHUxMDEtYjEwCi0wODc4YTBhNWZkYWJlZWM4NzJlODc4ZjQ3MzdkOTZlZGVlOGIxMzkzIGpkazh1MTAxLWIxMQotZGRjYzEwZWViOWQzMzY3ZWI0YjNmYTBjZDRkMTE4ZTZkYmM4ODUwZSBqZGs4dTEwMS1iMTIKLThlZTM2ZWNhMjEyNGY0ZWExNGQwYjdlZjg0NGQ1ZDcwNzBlYjBkZDEgamRrOHUxMDEtYjEzCi1hY2JjYjY2ODJjOWIzZTY2ZjljYzYxYTZhNjJlOGNiNWYyNGM3NWQzIGpkazh1NzYtYjAwCi1iM2M5MTRhZDg0MmQ2MTgxOGUwYzU4NTA0MDlmNzc0NzhiMTNhY2M2IGpkazh1NzYtYjAxCi03NzExOTMzZWMxODQ2MmVjZThhMWI5YTk1MjdlYzg3M2M1MjBiMWFiIGpkazh1NzYtYjAyCi0xMWRkMWMxM2YxYmQ3NWY1OGZjMGIwMjBjNzY3ZjJjMzMxYWJiMmE3IGpkazh1NzYtYjAzCi0xY2MxYzM1MTBmZDhiOWZhMmExOGJmYWQzOTg0Y2ExNjA2OWYwMTNlIGpkazh1NzYtYjA0Ci1iOTYyMDQ0MzAzNDQ1MzhiMTllZWE0OTFhOGNiNGFkMWJhNzExYzM5IGpkazh1MTAyLWIwMAotYjk2MjA0NDMwMzQ0NTM4YjE5ZWVhNDkxYThjYjRhZDFiYTcxMWMzOSBqZGs4dTgyLWIwMAotN2FlMjNmYWRkODUxZDM5YjNjNGYxYTg4Y2RiNWUwODdlMTc0YWZkNSBqZGs4dTEwMi1iMDEKLTc2MGQyNmRiYWEyNzYwM2VlOTRhNzQ2ZTQ3ZjE2NmU2NDcwMjkwYzIgamRrOHUxMDItYjAyCi05YmUzZTc1YzhmNDY2ZTY5ZjIxYTA4OTQ3MzFhMzg2M2Q0OGJjZjQzIGpkazh1MTAyLWIwMwotNTg0NjljNTA2NzdkZmNmODhiN2IyZjc0MGFjNzFjN2UxZDFkZDFkMiBqZGs4dTEwMi1iMDQKLWY1Y2IyMWUzYTM2MTk2ZjFjOGMyMjRkNmIxN2Q4OGRlYzM3ZjdlNDkgamRrOHUxMDItYjA1Ci01NDVhZTg4Y2QwOTFkMWUzNjI1Mzc5NzFiMGM2ZjFiOGQ0MzI3YjllIGpkazh1MTAyLWIwNgotZjU2M2U0NmYzMDgzZTFjNTQyYTZiZjNlMTE1NDdkMjk3YzlkYThmYSBqZGs4dTEwMi1iMDcKLWM5ZjgzMThlYjYzMTU3MTlkNzlhM2ZhNDc5MWQ3M2RhNDJlNzNmZTIgamRrOHUxMDItYjA4Ci04ZjVlYmI5MWFiM2EzNDFhNmY3ZGI3ZWRlODExM2E0ZjUyYTZhYjI2IGpkazh1MTAyLWIwOQotMDE4YzdlYmI4NThjNWNkM2FmOGU5YjExYjAzZTRlMDU2NjMyNTBiNCBqZGs4dTEwMi1iMTAKLTQyOTYyMWQyNTc3OGFiYjFhYjdhMGVkZThkYzQ4ZDU2MDZmNzYxMDggamRrOHUxMDItYjExCi1mZWY2MmY3ZWI1OTk4MmYyYzkyYTNiYjEzNWM2YWU0ZDZhNDY2MzI4IGpkazh1MTAyLWIxMgotZTlkZTAzN2MzYjRjNzY5MTY2MmQ5OTZjNDliNDJmM2U2MzllNjVlZSBqZGs4dTEwMi1iMTMKLTFmMDMyMDAwZmY0YjcwYzNhZGMwMjY2OWI2MzI0ODgwMTk5ZjhkYjggamRrOHUxMDItYjE0Ci1mZjYwMzQ2MzE5OWY4YTIxNDBjYjk3ZmQzZmY5ODA0NmRmZWVjYjNmIGpkazh1MTAyLWIzMQotNThkZWE1MzRjMWQ0OTczMWE0MGRlNjQ1Y2ZhMzQ1MDk0OWYzMWQyNiBqZGs4dTEwMi1iMzIKLWQzMWFhZDg0YzI3MjdlNDA3OTJjYmE4NTA3MzcxMzQyNGI2YjIwOWYgamRrOHUxMDItYjMzCi02ZDI4YWFmOTllOTM4M2U5Njg2NTQ4NjdlOWZkMjE5NTA0NmYzM2Y0IGpkazh1MTAyLWIzNAotZDNjNTc4NWRmNmI1YWFjZGJhMjAyMjFiMmY4MTlhYWU5M2JlY2FjNyBqZGs4dTEwMi1iMzUKLWE2YTAzMmE1NDkwZjQwMDBiZGZiMjVhMmY2MDRiMjJiY2RmOTVlY2YgamRrOHUxMTEtYjAwCi00Mzg5YjNjZGE4OGM5OGRmMzZiMzYxMTY5OTljNDU5MWE5YjhlMTJjIGpkazh1MTExLWIwMQotMWZmYzI4NGM0NWUwZmI4NmMwNjZiODMyZDdiZTUwNzY2YjY4ZWIyNSBqZGs4dTExMS1iMDIKLWY1MThmYTQ1ZjBmMDRkYmFkZDAyNmEzOTAyNTRiNTcxNjlhMGM4YWIgamRrOHUxMTEtYjAzCi00ZGFjY2IzMGMwNDQ5NjI1MmJmN2Q0M2RlOGUyZWUwNDcxZTQzMTlmIGpkazh1MTExLWIwNAotOWJiYmEwMThjOTZhMTdjNWI1NTgzZTI2YTM4ZDNjMWU5MTAxNzhlZiBqZGs4dTExMS1iMDUKLWJkMzc3MzUyNGMyZGUzODUyNDQ5NjA5N2Q3ZDhiYzJjMWNjMzllOTYgamRrOHUxMTEtYjA2Ci05Yzg4NTZjNmI4MmU0Yjk3NzM4OTYzMjIxNDZjM2IxZDZkMTJhNmVjIGpkazh1MTExLWIwNwotNzZlM2UyMDllNTFjMTc1NDZiNDg0YjBhYzk1ZTc3Y2JiOTQ5ZTRjZiBqZGs4dTExMS1iMDgKLWM0MzAxYzA0NWM3OWI4OTg0MzQ2ZDcwNTk5OWQwODQ3NTc5MjQxOGIgamRrOHUxMTEtYjA5Ci1lYTQ1NTViOWQ5MTMwNzcxZTIyOGZkZjBmMzNiNzgzYmNiYzMxNzJjIGpkazh1MTExLWIxMAotZDgwYWNkNTQzZGNiNGRkYjAxMWRlYzA1ZGEzNjQ3MjdkYTkwN2VjMiBqZGs4dTExMS1iMTEKLTU5YjQwMTExMzZhZTYwYjQzODU1Zjk5ZDMxNjExOWNhNjFkODQ0NjAgamRrOHUxMTEtYjEyCi00MWVkNTIwNTk0OWM4MmU3Mjk1MzNlODk3MzgyYjM5MzQyMDI5Y2ZmIGpkazh1MTExLWIxMwotZjFkMGI2ZTgxMDcwMTFjNDZmY2EzNjIxYmNmOGMwYTg3M2YzNzlmNyBqZGs4dTExMS1iMTQKLTRlODYxZDg0MzA0NjBhNzJlZTNlNWM3OWE4NWU3NzJiMDY2ODRhZGMgamRrOHUxMTItYjAwCi02NjRkZDc3MDE2NTQwY2I5Y2VlN2IxYmZhMjdhMGE2OTcwZjdjZjFmIGpkazh1MTEyLWIwMQotODBjZTU3MTIzZTIzZmY1M2YxOWMwMzRlYTU4OTJiMTg2NzMwZGRmMyBqZGs4dTExMi1iMDIKLWZhODk2MDQyNGI1YmFmNGFhMGMxZTAxNzIxMTVlODUzMTdmMDQxMjcgamRrOHUxMTItYjAzCi1jZmMwYzkyZmRiYWMxNTlhYjM0MzRiOTZkNjUwMzI0Y2Y2ZGM5MWRkIGpkazh1MTEyLWIwNAotZTY3NzIyOGEwNzhhNjgwZDg3NjFiM2ZkMjI5MzhlZmZlOWY3ZTE4ZCBqZGs4dTExMi1iMDYKLTdlYmRjMWZhNTVmYTNmMGMyMWNjMDA5YmYxYmI4Y2ZkMzlhOTIwOTkgamRrOHUxMTItYjA3Ci02ZWU2NTJkMzYzYmIyZTBhOWY3ZjBlYTdkMGQ4ZjRkZTcyN2FlYzdjIGpkazh1MTEyLWIwOAotNDVkN2MzNTQxNzUxNzkzOWE2MDA2MTRmMGRkMGNiMTZhMzA5ODkzNyBqZGs4dTExMi1iMDkKLTE3Y2ZhMGNkN2MzYzYyMTIzNmY0ZGQ4OTFmODgwOGMzYTAzYzM1NDIgamRrOHUxMTItYjEwCi1lZDM2NWVhNGNmNWZiNGQ5NDA3ZTk0ODRmMGNiNWNkMmUyYzc3ODZjIGpkazh1MTEyLWIxMQotMzgyNTE2NTMxNTAxYjAxMzZhZTU2ZTliY2NjNmQwOWRlODA1Y2UzOSBqZGs4dTExMi1iMTIKLWVjYTUzYWJmNjgwMGY4NjE0NmZiY2MwZTgxYWY0MzQ2NTI2ZTNhZDAgamRrOHUxMTItYjEzCi0xNTc0OWY2ZDBkMDViYzFhY2MwMDU2NDNiYTQ5NGZmMDkzODdjYmRjIGpkazh1MTEyLWIxNAotYjA3NzU0ZDQwZWE2NDE1YWYzYjI2NzMyN2U3NDg1MjJlYTE3YjEzMSBqZGs4dTExMi1iMTUKLTY2ZWYzMzg1MmQ5M2ZlODQ2OTcyNGNiZGJiZGQ1N2RkMGU1MDZhNmYgamRrOHUxMTItYjE2Ci0zNzZiYTVlZDg1Y2M0M2VmOGYxM2VkZGM1OTIxMjZlNDI4ODdhYzYwIGpkazh1MTEyLWIzMQotOWJiYmEwMThjOTZhMTdjNWI1NTgzZTI2YTM4ZDNjMWU5MTAxNzhlZiBqZGs4dTEyMS1iMDAKLTIxZGExNTI2YWVhZjA5ZmRlMDZlYzBhNTUwNGI1NjRiNTkxZjdkMDMgamRrOHUxMjEtYjAxCi1hMGFkNjMwZDQ1M2IzYjNjNWIxMTg1MDU2YTkyMTYyODFmMzA4NWNkIGpkazh1MTIxLWIwMgotZTc2YmYyZTg5ZWZkNGI5OGZhMzk5ZTRjN2RiNDg5ZmM4NjI3NTI1NyBqZGs4dTEyMS1iMDMKLTA1YWMyY2I5ODI2YTA4NDU3OGRkM2I1MjU4MjMyM2IyNDczZGE2MzEgamRrOHUxMjEtYjA0Ci00OWUxMDkxOTYwODMyZGRiMjQ3ZGUyODI1NDE0NTc3ZDM5OGJhMTVmIGpkazh1MTIxLWIwNQotZTMxZjVjZWJhNmJmNWFiNmRkZmRkMWJmZmVmMzUzNmU2YWY4Zjc4YiBqZGs4dTEyMS1iMDYKLWQxMmE5YjE2NWI0Nzg5OTE1YTZlZjI2NzA5OWRiOTcyMWE5ODg3ZjggamRrOHUxMjEtYjA3Ci1jNzMyNWQ5NWVhYmE5ZTVlZjMyOTUyNzEwN2JhZmM2ODM0NmQ0MjY0IGpkazh1MTIxLWIwOAotZjgwNWRjYjE4NzA0YTcwMjhiOWQxOTNlOGZlNjYxMzgxZDQ3MzIxMyBqZGs4dTEyMS1iMDkKLTk4OWM2MjRmZGMxZjMwNmYxYjYwNjhiMDUyOTI2OGE0NmUyMWVlNmIgamRrOHUxMjEtYjEwCi03N2MzZDYxN2FlNGMyOGM2ZTI5ZDUxNDExYWIyYjJjOWViMjQ2ODNmIGpkazh1MTIxLWIxMQotZjljYjI2NWZkMzVmYzYwZGNjZDc1MDc1NjE0ZjhlODk3YWY5MmFiMyBqZGs4dTEyMS1iMTIKLWI4ZDRlNDcyNDA3MTFmZjY2ZjkzNDc0ODNkMjBjODQ0NjZkNzVjODkgamRrOHUxMjEtYjEzCi0yZTVhNDcwNjkxZjIzZWJmOGQxZjBmMGRlYThlZjdkZTlhNzBhOTQzIGpkazh1MTIyLWIwMAotY2JiOGVmZTEzOTI3NWE0ZTdjNTQxZjllNDVlYjQxMGMyN2E1ZWE2MSBqZGs4dTEyMi1iMDEKLWUyNzlmMjQ1NTdkNDNkOGVkZmUzMTNjYjFhNTNhZGQ3YWM2Y2ViMmMgamRrOHUxMjItYjAyCi00ZDAzNzFmMTYwNDk1Y2M2MWUzYjU3Y2EyZDU3ODg0YzJiOWY5MDY4IGpkazh1MTIyLWIwMwotNGQwMzcxZjE2MDQ5NWNjNjFlM2I1N2NhMmQ1Nzg4NGMyYjlmOTA2OCBqZGs4dTEyMi1iMDMKLTAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAgamRrOHUxMjItYjAzCi0wMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwIGpkazh1MTIyLWIwMwotOTU3MjgyMzRjNjlmODQ4ZmRhMjBjM2QxMDdhMmExNDQwNWU4ZThiZCBqZGs4dTEyMi1iMDMKLTU0MGNhNTA3ZjVlMzNhZDQ2Yzg1NzUwZjVkZjExMDUyMjQ1NGNiMmQgamRrOHUxMjItYjA0Ci03ZjZkMGU5YTExOTY3MGJiODNhYjI5NjE1MDM0NzFkNzNmOGE1ZjdlIGpkazh1MTMyLWIwMAotNDIwM2MwOTJhMzUzNTU0MDY3MDkwMjc4MjdlOTEzMGY3OWRkOTZjYSBqZGs4dTE1Mi1iMDAKLWJlZGZkYmMyOTBhYzNjNzcxYzEwN2E2NDQyNTBjMTk4NWYyNmZiMmYgamRrOHUxNTItYjAxCmRpZmYgLS1naXQgYS8uamNoZWNrL2NvbmYgYi8uamNoZWNrL2NvbmYKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDViZDI0YjEuLjAwMDAwMDAKLS0tIGEvLmpjaGVjay9jb25mCisrKyAvZGV2L251bGwKQEAgLTEsMiArMCwwIEBACi1wcm9qZWN0PWpkazgKLWJ1Z2lkcz1kdXAKZGlmZiAtLWdpdCBhL0FTU0VNQkxZX0VYQ0VQVElPTiBiL0FTU0VNQkxZX0VYQ0VQVElPTgpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDY1YjhkOS4uMDAwMDAwMAotLS0gYS9BU1NFTUJMWV9FWENFUFRJT04KKysrIC9kZXYvbnVsbApAQCAtMSwyNyArMCwwIEBACi0KLU9QRU5KREsgQVNTRU1CTFkgRVhDRVBUSU9OCi0KLVRoZSBPcGVuSkRLIHNvdXJjZSBjb2RlIG1hZGUgYXZhaWxhYmxlIGJ5IE9yYWNsZSBBbWVyaWNhLCBJbmMuIChPcmFjbGUpIGF0Ci1vcGVuamRrLmphdmEubmV0ICgiT3BlbkpESyBDb2RlIikgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUKLUdlbmVyYWwgUHVibGljIExpY2Vuc2UgPGh0dHA6Ly93d3cuZ251Lm9yZy9jb3B5bGVmdC9ncGwuaHRtbD4gdmVyc2lvbiAyCi1vbmx5ICgiR1BMMiIpLCB3aXRoIHRoZSBmb2xsb3dpbmcgY2xhcmlmaWNhdGlvbiBhbmQgc3BlY2lhbCBleGNlcHRpb24uCi0KLSAgICBMaW5raW5nIHRoaXMgT3BlbkpESyBDb2RlIHN0YXRpY2FsbHkgb3IgZHluYW1pY2FsbHkgd2l0aCBvdGhlciBjb2RlCi0gICAgaXMgbWFraW5nIGEgY29tYmluZWQgd29yayBiYXNlZCBvbiB0aGlzIGxpYnJhcnkuICBUaHVzLCB0aGUgdGVybXMKLSAgICBhbmQgY29uZGl0aW9ucyBvZiBHUEwyIGNvdmVyIHRoZSB3aG9sZSBjb21iaW5hdGlvbi4KLQotICAgIEFzIGEgc3BlY2lhbCBleGNlcHRpb24sIE9yYWNsZSBnaXZlcyB5b3UgcGVybWlzc2lvbiB0byBsaW5rIHRoaXMKLSAgICBPcGVuSkRLIENvZGUgd2l0aCBjZXJ0YWluIGNvZGUgbGljZW5zZWQgYnkgT3JhY2xlIGFzIGluZGljYXRlZCBhdAotICAgIGh0dHA6Ly9vcGVuamRrLmphdmEubmV0L2xlZ2FsL2V4Y2VwdGlvbi1tb2R1bGVzLTIwMDctMDUtMDguaHRtbAotICAgICgiRGVzaWduYXRlZCBFeGNlcHRpb24gTW9kdWxlcyIpIHRvIHByb2R1Y2UgYW4gZXhlY3V0YWJsZSwKLSAgICByZWdhcmRsZXNzIG9mIHRoZSBsaWNlbnNlIHRlcm1zIG9mIHRoZSBEZXNpZ25hdGVkIEV4Y2VwdGlvbiBNb2R1bGVzLAotICAgIGFuZCB0byBjb3B5IGFuZCBkaXN0cmlidXRlIHRoZSByZXN1bHRpbmcgZXhlY3V0YWJsZSB1bmRlciBHUEwyLAotICAgIHByb3ZpZGVkIHRoYXQgdGhlIERlc2lnbmF0ZWQgRXhjZXB0aW9uIE1vZHVsZXMgY29udGludWUgdG8gYmUKLSAgICBnb3Zlcm5lZCBieSB0aGUgbGljZW5zZXMgdW5kZXIgd2hpY2ggdGhleSB3ZXJlIG9mZmVyZWQgYnkgT3JhY2xlLgotCi1BcyBzdWNoLCBpdCBhbGxvd3MgbGljZW5zZWVzIGFuZCBzdWJsaWNlbnNlZXMgb2YgT3JhY2xlJ3MgR1BMMiBPcGVuSkRLIENvZGUKLXRvIGJ1aWxkIGFuIGV4ZWN1dGFibGUgdGhhdCBpbmNsdWRlcyB0aG9zZSBwb3J0aW9ucyBvZiBuZWNlc3NhcnkgY29kZSB0aGF0Ci1PcmFjbGUgY291bGQgbm90IHByb3ZpZGUgdW5kZXIgR1BMMiAob3IgdGhhdCBPcmFjbGUgaGFzIHByb3ZpZGVkIHVuZGVyIEdQTDIKLXdpdGggdGhlIENsYXNzcGF0aCBleGNlcHRpb24pLiAgSWYgeW91IG1vZGlmeSBvciBhZGQgdG8gdGhlIE9wZW5KREsgY29kZSwKLXRoYXQgbmV3IEdQTDIgY29kZSBtYXkgc3RpbGwgYmUgY29tYmluZWQgd2l0aCBEZXNpZ25hdGVkIEV4Y2VwdGlvbiBNb2R1bGVzCi1pZiB0aGUgbmV3IGNvZGUgaXMgbWFkZSBzdWJqZWN0IHRvIHRoaXMgZXhjZXB0aW9uIGJ5IGl0cyBjb3B5cmlnaHQgaG9sZGVyLgpkaWZmIC0tZ2l0IGEvTElDRU5TRSBiL0xJQ0VOU0UKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDhiNDAwYzcuLjAwMDAwMDAKLS0tIGEvTElDRU5TRQorKysgL2Rldi9udWxsCkBAIC0xLDM0NyArMCwwIEBACi1UaGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgKEdQTCkKLQotVmVyc2lvbiAyLCBKdW5lIDE5OTEKLQotQ29weXJpZ2h0IChDKSAxOTg5LCAxOTkxIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgSW5jLgotNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQQotCi1FdmVyeW9uZSBpcyBwZXJtaXR0ZWQgdG8gY29weSBhbmQgZGlzdHJpYnV0ZSB2ZXJiYXRpbSBjb3BpZXMgb2YgdGhpcyBsaWNlbnNlCi1kb2N1bWVudCwgYnV0IGNoYW5naW5nIGl0IGlzIG5vdCBhbGxvd2VkLgotCi1QcmVhbWJsZQotCi1UaGUgbGljZW5zZXMgZm9yIG1vc3Qgc29mdHdhcmUgYXJlIGRlc2lnbmVkIHRvIHRha2UgYXdheSB5b3VyIGZyZWVkb20gdG8gc2hhcmUKLWFuZCBjaGFuZ2UgaXQuICBCeSBjb250cmFzdCwgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGlzIGludGVuZGVkIHRvCi1ndWFyYW50ZWUgeW91ciBmcmVlZG9tIHRvIHNoYXJlIGFuZCBjaGFuZ2UgZnJlZSBzb2Z0d2FyZS0tdG8gbWFrZSBzdXJlIHRoZQotc29mdHdhcmUgaXMgZnJlZSBmb3IgYWxsIGl0cyB1c2Vycy4gIFRoaXMgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcHBsaWVzIHRvCi1tb3N0IG9mIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24ncyBzb2Z0d2FyZSBhbmQgdG8gYW55IG90aGVyIHByb2dyYW0gd2hvc2UKLWF1dGhvcnMgY29tbWl0IHRvIHVzaW5nIGl0LiAgKFNvbWUgb3RoZXIgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIHNvZnR3YXJlIGlzCi1jb3ZlcmVkIGJ5IHRoZSBHTlUgTGlicmFyeSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGluc3RlYWQuKSBZb3UgY2FuIGFwcGx5IGl0IHRvCi15b3VyIHByb2dyYW1zLCB0b28uCi0KLVdoZW4gd2Ugc3BlYWsgb2YgZnJlZSBzb2Z0d2FyZSwgd2UgYXJlIHJlZmVycmluZyB0byBmcmVlZG9tLCBub3QgcHJpY2UuICBPdXIKLUdlbmVyYWwgUHVibGljIExpY2Vuc2VzIGFyZSBkZXNpZ25lZCB0byBtYWtlIHN1cmUgdGhhdCB5b3UgaGF2ZSB0aGUgZnJlZWRvbSB0bwotZGlzdHJpYnV0ZSBjb3BpZXMgb2YgZnJlZSBzb2Z0d2FyZSAoYW5kIGNoYXJnZSBmb3IgdGhpcyBzZXJ2aWNlIGlmIHlvdSB3aXNoKSwKLXRoYXQgeW91IHJlY2VpdmUgc291cmNlIGNvZGUgb3IgY2FuIGdldCBpdCBpZiB5b3Ugd2FudCBpdCwgdGhhdCB5b3UgY2FuIGNoYW5nZQotdGhlIHNvZnR3YXJlIG9yIHVzZSBwaWVjZXMgb2YgaXQgaW4gbmV3IGZyZWUgcHJvZ3JhbXM7IGFuZCB0aGF0IHlvdSBrbm93IHlvdQotY2FuIGRvIHRoZXNlIHRoaW5ncy4KLQotVG8gcHJvdGVjdCB5b3VyIHJpZ2h0cywgd2UgbmVlZCB0byBtYWtlIHJlc3RyaWN0aW9ucyB0aGF0IGZvcmJpZCBhbnlvbmUgdG8gZGVueQoteW91IHRoZXNlIHJpZ2h0cyBvciB0byBhc2sgeW91IHRvIHN1cnJlbmRlciB0aGUgcmlnaHRzLiAgVGhlc2UgcmVzdHJpY3Rpb25zCi10cmFuc2xhdGUgdG8gY2VydGFpbiByZXNwb25zaWJpbGl0aWVzIGZvciB5b3UgaWYgeW91IGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoZQotc29mdHdhcmUsIG9yIGlmIHlvdSBtb2RpZnkgaXQuCi0KLUZvciBleGFtcGxlLCBpZiB5b3UgZGlzdHJpYnV0ZSBjb3BpZXMgb2Ygc3VjaCBhIHByb2dyYW0sIHdoZXRoZXIgZ3JhdGlzIG9yIGZvcgotYSBmZWUsIHlvdSBtdXN0IGdpdmUgdGhlIHJlY2lwaWVudHMgYWxsIHRoZSByaWdodHMgdGhhdCB5b3UgaGF2ZS4gIFlvdSBtdXN0Ci1tYWtlIHN1cmUgdGhhdCB0aGV5LCB0b28sIHJlY2VpdmUgb3IgY2FuIGdldCB0aGUgc291cmNlIGNvZGUuICBBbmQgeW91IG11c3QKLXNob3cgdGhlbSB0aGVzZSB0ZXJtcyBzbyB0aGV5IGtub3cgdGhlaXIgcmlnaHRzLgotCi1XZSBwcm90ZWN0IHlvdXIgcmlnaHRzIHdpdGggdHdvIHN0ZXBzOiAoMSkgY29weXJpZ2h0IHRoZSBzb2Z0d2FyZSwgYW5kICgyKQotb2ZmZXIgeW91IHRoaXMgbGljZW5zZSB3aGljaCBnaXZlcyB5b3UgbGVnYWwgcGVybWlzc2lvbiB0byBjb3B5LCBkaXN0cmlidXRlCi1hbmQvb3IgbW9kaWZ5IHRoZSBzb2Z0d2FyZS4KLQotQWxzbywgZm9yIGVhY2ggYXV0aG9yJ3MgcHJvdGVjdGlvbiBhbmQgb3Vycywgd2Ugd2FudCB0byBtYWtlIGNlcnRhaW4gdGhhdAotZXZlcnlvbmUgdW5kZXJzdGFuZHMgdGhhdCB0aGVyZSBpcyBubyB3YXJyYW50eSBmb3IgdGhpcyBmcmVlIHNvZnR3YXJlLiAgSWYgdGhlCi1zb2Z0d2FyZSBpcyBtb2RpZmllZCBieSBzb21lb25lIGVsc2UgYW5kIHBhc3NlZCBvbiwgd2Ugd2FudCBpdHMgcmVjaXBpZW50cyB0bwota25vdyB0aGF0IHdoYXQgdGhleSBoYXZlIGlzIG5vdCB0aGUgb3JpZ2luYWwsIHNvIHRoYXQgYW55IHByb2JsZW1zIGludHJvZHVjZWQKLWJ5IG90aGVycyB3aWxsIG5vdCByZWZsZWN0IG9uIHRoZSBvcmlnaW5hbCBhdXRob3JzJyByZXB1dGF0aW9ucy4KLQotRmluYWxseSwgYW55IGZyZWUgcHJvZ3JhbSBpcyB0aHJlYXRlbmVkIGNvbnN0YW50bHkgYnkgc29mdHdhcmUgcGF0ZW50cy4gIFdlCi13aXNoIHRvIGF2b2lkIHRoZSBkYW5nZXIgdGhhdCByZWRpc3RyaWJ1dG9ycyBvZiBhIGZyZWUgcHJvZ3JhbSB3aWxsCi1pbmRpdmlkdWFsbHkgb2J0YWluIHBhdGVudCBsaWNlbnNlcywgaW4gZWZmZWN0IG1ha2luZyB0aGUgcHJvZ3JhbSBwcm9wcmlldGFyeS4KLVRvIHByZXZlbnQgdGhpcywgd2UgaGF2ZSBtYWRlIGl0IGNsZWFyIHRoYXQgYW55IHBhdGVudCBtdXN0IGJlIGxpY2Vuc2VkIGZvcgotZXZlcnlvbmUncyBmcmVlIHVzZSBvciBub3QgbGljZW5zZWQgYXQgYWxsLgotCi1UaGUgcHJlY2lzZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgY29weWluZywgZGlzdHJpYnV0aW9uIGFuZCBtb2RpZmljYXRpb24KLWZvbGxvdy4KLQotVEVSTVMgQU5EIENPTkRJVElPTlMgRk9SIENPUFlJTkcsIERJU1RSSUJVVElPTiBBTkQgTU9ESUZJQ0FUSU9OCi0KLTAuIFRoaXMgTGljZW5zZSBhcHBsaWVzIHRvIGFueSBwcm9ncmFtIG9yIG90aGVyIHdvcmsgd2hpY2ggY29udGFpbnMgYSBub3RpY2UKLXBsYWNlZCBieSB0aGUgY29weXJpZ2h0IGhvbGRlciBzYXlpbmcgaXQgbWF5IGJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSB0ZXJtcyBvZgotdGhpcyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLiAgVGhlICJQcm9ncmFtIiwgYmVsb3csIHJlZmVycyB0byBhbnkgc3VjaCBwcm9ncmFtCi1vciB3b3JrLCBhbmQgYSAid29yayBiYXNlZCBvbiB0aGUgUHJvZ3JhbSIgbWVhbnMgZWl0aGVyIHRoZSBQcm9ncmFtIG9yIGFueQotZGVyaXZhdGl2ZSB3b3JrIHVuZGVyIGNvcHlyaWdodCBsYXc6IHRoYXQgaXMgdG8gc2F5LCBhIHdvcmsgY29udGFpbmluZyB0aGUKLVByb2dyYW0gb3IgYSBwb3J0aW9uIG9mIGl0LCBlaXRoZXIgdmVyYmF0aW0gb3Igd2l0aCBtb2RpZmljYXRpb25zIGFuZC9vcgotdHJhbnNsYXRlZCBpbnRvIGFub3RoZXIgbGFuZ3VhZ2UuICAoSGVyZWluYWZ0ZXIsIHRyYW5zbGF0aW9uIGlzIGluY2x1ZGVkCi13aXRob3V0IGxpbWl0YXRpb24gaW4gdGhlIHRlcm0gIm1vZGlmaWNhdGlvbiIuKSBFYWNoIGxpY2Vuc2VlIGlzIGFkZHJlc3NlZCBhcwotInlvdSIuCi0KLUFjdGl2aXRpZXMgb3RoZXIgdGhhbiBjb3B5aW5nLCBkaXN0cmlidXRpb24gYW5kIG1vZGlmaWNhdGlvbiBhcmUgbm90IGNvdmVyZWQgYnkKLXRoaXMgTGljZW5zZTsgdGhleSBhcmUgb3V0c2lkZSBpdHMgc2NvcGUuICBUaGUgYWN0IG9mIHJ1bm5pbmcgdGhlIFByb2dyYW0gaXMKLW5vdCByZXN0cmljdGVkLCBhbmQgdGhlIG91dHB1dCBmcm9tIHRoZSBQcm9ncmFtIGlzIGNvdmVyZWQgb25seSBpZiBpdHMgY29udGVudHMKLWNvbnN0aXR1dGUgYSB3b3JrIGJhc2VkIG9uIHRoZSBQcm9ncmFtIChpbmRlcGVuZGVudCBvZiBoYXZpbmcgYmVlbiBtYWRlIGJ5Ci1ydW5uaW5nIHRoZSBQcm9ncmFtKS4gIFdoZXRoZXIgdGhhdCBpcyB0cnVlIGRlcGVuZHMgb24gd2hhdCB0aGUgUHJvZ3JhbSBkb2VzLgotCi0xLiBZb3UgbWF5IGNvcHkgYW5kIGRpc3RyaWJ1dGUgdmVyYmF0aW0gY29waWVzIG9mIHRoZSBQcm9ncmFtJ3Mgc291cmNlIGNvZGUgYXMKLXlvdSByZWNlaXZlIGl0LCBpbiBhbnkgbWVkaXVtLCBwcm92aWRlZCB0aGF0IHlvdSBjb25zcGljdW91c2x5IGFuZAotYXBwcm9wcmlhdGVseSBwdWJsaXNoIG9uIGVhY2ggY29weSBhbiBhcHByb3ByaWF0ZSBjb3B5cmlnaHQgbm90aWNlIGFuZAotZGlzY2xhaW1lciBvZiB3YXJyYW50eTsga2VlcCBpbnRhY3QgYWxsIHRoZSBub3RpY2VzIHRoYXQgcmVmZXIgdG8gdGhpcyBMaWNlbnNlCi1hbmQgdG8gdGhlIGFic2VuY2Ugb2YgYW55IHdhcnJhbnR5OyBhbmQgZ2l2ZSBhbnkgb3RoZXIgcmVjaXBpZW50cyBvZiB0aGUKLVByb2dyYW0gYSBjb3B5IG9mIHRoaXMgTGljZW5zZSBhbG9uZyB3aXRoIHRoZSBQcm9ncmFtLgotCi1Zb3UgbWF5IGNoYXJnZSBhIGZlZSBmb3IgdGhlIHBoeXNpY2FsIGFjdCBvZiB0cmFuc2ZlcnJpbmcgYSBjb3B5LCBhbmQgeW91IG1heQotYXQgeW91ciBvcHRpb24gb2ZmZXIgd2FycmFudHkgcHJvdGVjdGlvbiBpbiBleGNoYW5nZSBmb3IgYSBmZWUuCi0KLTIuIFlvdSBtYXkgbW9kaWZ5IHlvdXIgY29weSBvciBjb3BpZXMgb2YgdGhlIFByb2dyYW0gb3IgYW55IHBvcnRpb24gb2YgaXQsIHRodXMKLWZvcm1pbmcgYSB3b3JrIGJhc2VkIG9uIHRoZSBQcm9ncmFtLCBhbmQgY29weSBhbmQgZGlzdHJpYnV0ZSBzdWNoIG1vZGlmaWNhdGlvbnMKLW9yIHdvcmsgdW5kZXIgdGhlIHRlcm1zIG9mIFNlY3Rpb24gMSBhYm92ZSwgcHJvdmlkZWQgdGhhdCB5b3UgYWxzbyBtZWV0IGFsbCBvZgotdGhlc2UgY29uZGl0aW9uczoKLQotICAgIGEpIFlvdSBtdXN0IGNhdXNlIHRoZSBtb2RpZmllZCBmaWxlcyB0byBjYXJyeSBwcm9taW5lbnQgbm90aWNlcyBzdGF0aW5nCi0gICAgdGhhdCB5b3UgY2hhbmdlZCB0aGUgZmlsZXMgYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuCi0KLSAgICBiKSBZb3UgbXVzdCBjYXVzZSBhbnkgd29yayB0aGF0IHlvdSBkaXN0cmlidXRlIG9yIHB1Ymxpc2gsIHRoYXQgaW4gd2hvbGUgb3IKLSAgICBpbiBwYXJ0IGNvbnRhaW5zIG9yIGlzIGRlcml2ZWQgZnJvbSB0aGUgUHJvZ3JhbSBvciBhbnkgcGFydCB0aGVyZW9mLCB0byBiZQotICAgIGxpY2Vuc2VkIGFzIGEgd2hvbGUgYXQgbm8gY2hhcmdlIHRvIGFsbCB0aGlyZCBwYXJ0aWVzIHVuZGVyIHRoZSB0ZXJtcyBvZgotICAgIHRoaXMgTGljZW5zZS4KLQotICAgIGMpIElmIHRoZSBtb2RpZmllZCBwcm9ncmFtIG5vcm1hbGx5IHJlYWRzIGNvbW1hbmRzIGludGVyYWN0aXZlbHkgd2hlbiBydW4sCi0gICAgeW91IG11c3QgY2F1c2UgaXQsIHdoZW4gc3RhcnRlZCBydW5uaW5nIGZvciBzdWNoIGludGVyYWN0aXZlIHVzZSBpbiB0aGUKLSAgICBtb3N0IG9yZGluYXJ5IHdheSwgdG8gcHJpbnQgb3IgZGlzcGxheSBhbiBhbm5vdW5jZW1lbnQgaW5jbHVkaW5nIGFuCi0gICAgYXBwcm9wcmlhdGUgY29weXJpZ2h0IG5vdGljZSBhbmQgYSBub3RpY2UgdGhhdCB0aGVyZSBpcyBubyB3YXJyYW50eSAob3IKLSAgICBlbHNlLCBzYXlpbmcgdGhhdCB5b3UgcHJvdmlkZSBhIHdhcnJhbnR5KSBhbmQgdGhhdCB1c2VycyBtYXkgcmVkaXN0cmlidXRlCi0gICAgdGhlIHByb2dyYW0gdW5kZXIgdGhlc2UgY29uZGl0aW9ucywgYW5kIHRlbGxpbmcgdGhlIHVzZXIgaG93IHRvIHZpZXcgYSBjb3B5Ci0gICAgb2YgdGhpcyBMaWNlbnNlLiAgKEV4Y2VwdGlvbjogaWYgdGhlIFByb2dyYW0gaXRzZWxmIGlzIGludGVyYWN0aXZlIGJ1dCBkb2VzCi0gICAgbm90IG5vcm1hbGx5IHByaW50IHN1Y2ggYW4gYW5ub3VuY2VtZW50LCB5b3VyIHdvcmsgYmFzZWQgb24gdGhlIFByb2dyYW0gaXMKLSAgICBub3QgcmVxdWlyZWQgdG8gcHJpbnQgYW4gYW5ub3VuY2VtZW50LikKLQotVGhlc2UgcmVxdWlyZW1lbnRzIGFwcGx5IHRvIHRoZSBtb2RpZmllZCB3b3JrIGFzIGEgd2hvbGUuICBJZiBpZGVudGlmaWFibGUKLXNlY3Rpb25zIG9mIHRoYXQgd29yayBhcmUgbm90IGRlcml2ZWQgZnJvbSB0aGUgUHJvZ3JhbSwgYW5kIGNhbiBiZSByZWFzb25hYmx5Ci1jb25zaWRlcmVkIGluZGVwZW5kZW50IGFuZCBzZXBhcmF0ZSB3b3JrcyBpbiB0aGVtc2VsdmVzLCB0aGVuIHRoaXMgTGljZW5zZSwgYW5kCi1pdHMgdGVybXMsIGRvIG5vdCBhcHBseSB0byB0aG9zZSBzZWN0aW9ucyB3aGVuIHlvdSBkaXN0cmlidXRlIHRoZW0gYXMgc2VwYXJhdGUKLXdvcmtzLiAgQnV0IHdoZW4geW91IGRpc3RyaWJ1dGUgdGhlIHNhbWUgc2VjdGlvbnMgYXMgcGFydCBvZiBhIHdob2xlIHdoaWNoIGlzIGEKLXdvcmsgYmFzZWQgb24gdGhlIFByb2dyYW0sIHRoZSBkaXN0cmlidXRpb24gb2YgdGhlIHdob2xlIG11c3QgYmUgb24gdGhlIHRlcm1zCi1vZiB0aGlzIExpY2Vuc2UsIHdob3NlIHBlcm1pc3Npb25zIGZvciBvdGhlciBsaWNlbnNlZXMgZXh0ZW5kIHRvIHRoZSBlbnRpcmUKLXdob2xlLCBhbmQgdGh1cyB0byBlYWNoIGFuZCBldmVyeSBwYXJ0IHJlZ2FyZGxlc3Mgb2Ygd2hvIHdyb3RlIGl0LgotCi1UaHVzLCBpdCBpcyBub3QgdGhlIGludGVudCBvZiB0aGlzIHNlY3Rpb24gdG8gY2xhaW0gcmlnaHRzIG9yIGNvbnRlc3QgeW91cgotcmlnaHRzIHRvIHdvcmsgd3JpdHRlbiBlbnRpcmVseSBieSB5b3U7IHJhdGhlciwgdGhlIGludGVudCBpcyB0byBleGVyY2lzZSB0aGUKLXJpZ2h0IHRvIGNvbnRyb2wgdGhlIGRpc3RyaWJ1dGlvbiBvZiBkZXJpdmF0aXZlIG9yIGNvbGxlY3RpdmUgd29ya3MgYmFzZWQgb24KLXRoZSBQcm9ncmFtLgotCi1JbiBhZGRpdGlvbiwgbWVyZSBhZ2dyZWdhdGlvbiBvZiBhbm90aGVyIHdvcmsgbm90IGJhc2VkIG9uIHRoZSBQcm9ncmFtIHdpdGggdGhlCi1Qcm9ncmFtIChvciB3aXRoIGEgd29yayBiYXNlZCBvbiB0aGUgUHJvZ3JhbSkgb24gYSB2b2x1bWUgb2YgYSBzdG9yYWdlIG9yCi1kaXN0cmlidXRpb24gbWVkaXVtIGRvZXMgbm90IGJyaW5nIHRoZSBvdGhlciB3b3JrIHVuZGVyIHRoZSBzY29wZSBvZiB0aGlzCi1MaWNlbnNlLgotCi0zLiBZb3UgbWF5IGNvcHkgYW5kIGRpc3RyaWJ1dGUgdGhlIFByb2dyYW0gKG9yIGEgd29yayBiYXNlZCBvbiBpdCwgdW5kZXIKLVNlY3Rpb24gMikgaW4gb2JqZWN0IGNvZGUgb3IgZXhlY3V0YWJsZSBmb3JtIHVuZGVyIHRoZSB0ZXJtcyBvZiBTZWN0aW9ucyAxIGFuZAotMiBhYm92ZSBwcm92aWRlZCB0aGF0IHlvdSBhbHNvIGRvIG9uZSBvZiB0aGUgZm9sbG93aW5nOgotCi0gICAgYSkgQWNjb21wYW55IGl0IHdpdGggdGhlIGNvbXBsZXRlIGNvcnJlc3BvbmRpbmcgbWFjaGluZS1yZWFkYWJsZSBzb3VyY2UKLSAgICBjb2RlLCB3aGljaCBtdXN0IGJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSB0ZXJtcyBvZiBTZWN0aW9ucyAxIGFuZCAyIGFib3ZlCi0gICAgb24gYSBtZWRpdW0gY3VzdG9tYXJpbHkgdXNlZCBmb3Igc29mdHdhcmUgaW50ZXJjaGFuZ2U7IG9yLAotCi0gICAgYikgQWNjb21wYW55IGl0IHdpdGggYSB3cml0dGVuIG9mZmVyLCB2YWxpZCBmb3IgYXQgbGVhc3QgdGhyZWUgeWVhcnMsIHRvCi0gICAgZ2l2ZSBhbnkgdGhpcmQgcGFydHksIGZvciBhIGNoYXJnZSBubyBtb3JlIHRoYW4geW91ciBjb3N0IG9mIHBoeXNpY2FsbHkKLSAgICBwZXJmb3JtaW5nIHNvdXJjZSBkaXN0cmlidXRpb24sIGEgY29tcGxldGUgbWFjaGluZS1yZWFkYWJsZSBjb3B5IG9mIHRoZQotICAgIGNvcnJlc3BvbmRpbmcgc291cmNlIGNvZGUsIHRvIGJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSB0ZXJtcyBvZiBTZWN0aW9ucyAxCi0gICAgYW5kIDIgYWJvdmUgb24gYSBtZWRpdW0gY3VzdG9tYXJpbHkgdXNlZCBmb3Igc29mdHdhcmUgaW50ZXJjaGFuZ2U7IG9yLAotCi0gICAgYykgQWNjb21wYW55IGl0IHdpdGggdGhlIGluZm9ybWF0aW9uIHlvdSByZWNlaXZlZCBhcyB0byB0aGUgb2ZmZXIgdG8KLSAgICBkaXN0cmlidXRlIGNvcnJlc3BvbmRpbmcgc291cmNlIGNvZGUuICAoVGhpcyBhbHRlcm5hdGl2ZSBpcyBhbGxvd2VkIG9ubHkKLSAgICBmb3Igbm9uY29tbWVyY2lhbCBkaXN0cmlidXRpb24gYW5kIG9ubHkgaWYgeW91IHJlY2VpdmVkIHRoZSBwcm9ncmFtIGluCi0gICAgb2JqZWN0IGNvZGUgb3IgZXhlY3V0YWJsZSBmb3JtIHdpdGggc3VjaCBhbiBvZmZlciwgaW4gYWNjb3JkIHdpdGgKLSAgICBTdWJzZWN0aW9uIGIgYWJvdmUuKQotCi1UaGUgc291cmNlIGNvZGUgZm9yIGEgd29yayBtZWFucyB0aGUgcHJlZmVycmVkIGZvcm0gb2YgdGhlIHdvcmsgZm9yIG1ha2luZwotbW9kaWZpY2F0aW9ucyB0byBpdC4gIEZvciBhbiBleGVjdXRhYmxlIHdvcmssIGNvbXBsZXRlIHNvdXJjZSBjb2RlIG1lYW5zIGFsbAotdGhlIHNvdXJjZSBjb2RlIGZvciBhbGwgbW9kdWxlcyBpdCBjb250YWlucywgcGx1cyBhbnkgYXNzb2NpYXRlZCBpbnRlcmZhY2UKLWRlZmluaXRpb24gZmlsZXMsIHBsdXMgdGhlIHNjcmlwdHMgdXNlZCB0byBjb250cm9sIGNvbXBpbGF0aW9uIGFuZCBpbnN0YWxsYXRpb24KLW9mIHRoZSBleGVjdXRhYmxlLiAgSG93ZXZlciwgYXMgYSBzcGVjaWFsIGV4Y2VwdGlvbiwgdGhlIHNvdXJjZSBjb2RlCi1kaXN0cmlidXRlZCBuZWVkIG5vdCBpbmNsdWRlIGFueXRoaW5nIHRoYXQgaXMgbm9ybWFsbHkgZGlzdHJpYnV0ZWQgKGluIGVpdGhlcgotc291cmNlIG9yIGJpbmFyeSBmb3JtKSB3aXRoIHRoZSBtYWpvciBjb21wb25lbnRzIChjb21waWxlciwga2VybmVsLCBhbmQgc28gb24pCi1vZiB0aGUgb3BlcmF0aW5nIHN5c3RlbSBvbiB3aGljaCB0aGUgZXhlY3V0YWJsZSBydW5zLCB1bmxlc3MgdGhhdCBjb21wb25lbnQKLWl0c2VsZiBhY2NvbXBhbmllcyB0aGUgZXhlY3V0YWJsZS4KLQotSWYgZGlzdHJpYnV0aW9uIG9mIGV4ZWN1dGFibGUgb3Igb2JqZWN0IGNvZGUgaXMgbWFkZSBieSBvZmZlcmluZyBhY2Nlc3MgdG8gY29weQotZnJvbSBhIGRlc2lnbmF0ZWQgcGxhY2UsIHRoZW4gb2ZmZXJpbmcgZXF1aXZhbGVudCBhY2Nlc3MgdG8gY29weSB0aGUgc291cmNlCi1jb2RlIGZyb20gdGhlIHNhbWUgcGxhY2UgY291bnRzIGFzIGRpc3RyaWJ1dGlvbiBvZiB0aGUgc291cmNlIGNvZGUsIGV2ZW4gdGhvdWdoCi10aGlyZCBwYXJ0aWVzIGFyZSBub3QgY29tcGVsbGVkIHRvIGNvcHkgdGhlIHNvdXJjZSBhbG9uZyB3aXRoIHRoZSBvYmplY3QgY29kZS4KLQotNC4gWW91IG1heSBub3QgY29weSwgbW9kaWZ5LCBzdWJsaWNlbnNlLCBvciBkaXN0cmlidXRlIHRoZSBQcm9ncmFtIGV4Y2VwdCBhcwotZXhwcmVzc2x5IHByb3ZpZGVkIHVuZGVyIHRoaXMgTGljZW5zZS4gIEFueSBhdHRlbXB0IG90aGVyd2lzZSB0byBjb3B5LCBtb2RpZnksCi1zdWJsaWNlbnNlIG9yIGRpc3RyaWJ1dGUgdGhlIFByb2dyYW0gaXMgdm9pZCwgYW5kIHdpbGwgYXV0b21hdGljYWxseSB0ZXJtaW5hdGUKLXlvdXIgcmlnaHRzIHVuZGVyIHRoaXMgTGljZW5zZS4gIEhvd2V2ZXIsIHBhcnRpZXMgd2hvIGhhdmUgcmVjZWl2ZWQgY29waWVzLCBvcgotcmlnaHRzLCBmcm9tIHlvdSB1bmRlciB0aGlzIExpY2Vuc2Ugd2lsbCBub3QgaGF2ZSB0aGVpciBsaWNlbnNlcyB0ZXJtaW5hdGVkIHNvCi1sb25nIGFzIHN1Y2ggcGFydGllcyByZW1haW4gaW4gZnVsbCBjb21wbGlhbmNlLgotCi01LiBZb3UgYXJlIG5vdCByZXF1aXJlZCB0byBhY2NlcHQgdGhpcyBMaWNlbnNlLCBzaW5jZSB5b3UgaGF2ZSBub3Qgc2lnbmVkIGl0LgotSG93ZXZlciwgbm90aGluZyBlbHNlIGdyYW50cyB5b3UgcGVybWlzc2lvbiB0byBtb2RpZnkgb3IgZGlzdHJpYnV0ZSB0aGUgUHJvZ3JhbQotb3IgaXRzIGRlcml2YXRpdmUgd29ya3MuICBUaGVzZSBhY3Rpb25zIGFyZSBwcm9oaWJpdGVkIGJ5IGxhdyBpZiB5b3UgZG8gbm90Ci1hY2NlcHQgdGhpcyBMaWNlbnNlLiAgVGhlcmVmb3JlLCBieSBtb2RpZnlpbmcgb3IgZGlzdHJpYnV0aW5nIHRoZSBQcm9ncmFtIChvcgotYW55IHdvcmsgYmFzZWQgb24gdGhlIFByb2dyYW0pLCB5b3UgaW5kaWNhdGUgeW91ciBhY2NlcHRhbmNlIG9mIHRoaXMgTGljZW5zZSB0bwotZG8gc28sIGFuZCBhbGwgaXRzIHRlcm1zIGFuZCBjb25kaXRpb25zIGZvciBjb3B5aW5nLCBkaXN0cmlidXRpbmcgb3IgbW9kaWZ5aW5nCi10aGUgUHJvZ3JhbSBvciB3b3JrcyBiYXNlZCBvbiBpdC4KLQotNi4gRWFjaCB0aW1lIHlvdSByZWRpc3RyaWJ1dGUgdGhlIFByb2dyYW0gKG9yIGFueSB3b3JrIGJhc2VkIG9uIHRoZSBQcm9ncmFtKSwKLXRoZSByZWNpcGllbnQgYXV0b21hdGljYWxseSByZWNlaXZlcyBhIGxpY2Vuc2UgZnJvbSB0aGUgb3JpZ2luYWwgbGljZW5zb3IgdG8KLWNvcHksIGRpc3RyaWJ1dGUgb3IgbW9kaWZ5IHRoZSBQcm9ncmFtIHN1YmplY3QgdG8gdGhlc2UgdGVybXMgYW5kIGNvbmRpdGlvbnMuCi1Zb3UgbWF5IG5vdCBpbXBvc2UgYW55IGZ1cnRoZXIgcmVzdHJpY3Rpb25zIG9uIHRoZSByZWNpcGllbnRzJyBleGVyY2lzZSBvZiB0aGUKLXJpZ2h0cyBncmFudGVkIGhlcmVpbi4gIFlvdSBhcmUgbm90IHJlc3BvbnNpYmxlIGZvciBlbmZvcmNpbmcgY29tcGxpYW5jZSBieQotdGhpcmQgcGFydGllcyB0byB0aGlzIExpY2Vuc2UuCi0KLTcuIElmLCBhcyBhIGNvbnNlcXVlbmNlIG9mIGEgY291cnQganVkZ21lbnQgb3IgYWxsZWdhdGlvbiBvZiBwYXRlbnQKLWluZnJpbmdlbWVudCBvciBmb3IgYW55IG90aGVyIHJlYXNvbiAobm90IGxpbWl0ZWQgdG8gcGF0ZW50IGlzc3VlcyksIGNvbmRpdGlvbnMKLWFyZSBpbXBvc2VkIG9uIHlvdSAod2hldGhlciBieSBjb3VydCBvcmRlciwgYWdyZWVtZW50IG9yIG90aGVyd2lzZSkgdGhhdAotY29udHJhZGljdCB0aGUgY29uZGl0aW9ucyBvZiB0aGlzIExpY2Vuc2UsIHRoZXkgZG8gbm90IGV4Y3VzZSB5b3UgZnJvbSB0aGUKLWNvbmRpdGlvbnMgb2YgdGhpcyBMaWNlbnNlLiAgSWYgeW91IGNhbm5vdCBkaXN0cmlidXRlIHNvIGFzIHRvIHNhdGlzZnkKLXNpbXVsdGFuZW91c2x5IHlvdXIgb2JsaWdhdGlvbnMgdW5kZXIgdGhpcyBMaWNlbnNlIGFuZCBhbnkgb3RoZXIgcGVydGluZW50Ci1vYmxpZ2F0aW9ucywgdGhlbiBhcyBhIGNvbnNlcXVlbmNlIHlvdSBtYXkgbm90IGRpc3RyaWJ1dGUgdGhlIFByb2dyYW0gYXQgYWxsLgotRm9yIGV4YW1wbGUsIGlmIGEgcGF0ZW50IGxpY2Vuc2Ugd291bGQgbm90IHBlcm1pdCByb3lhbHR5LWZyZWUgcmVkaXN0cmlidXRpb24KLW9mIHRoZSBQcm9ncmFtIGJ5IGFsbCB0aG9zZSB3aG8gcmVjZWl2ZSBjb3BpZXMgZGlyZWN0bHkgb3IgaW5kaXJlY3RseSB0aHJvdWdoCi15b3UsIHRoZW4gdGhlIG9ubHkgd2F5IHlvdSBjb3VsZCBzYXRpc2Z5IGJvdGggaXQgYW5kIHRoaXMgTGljZW5zZSB3b3VsZCBiZSB0bwotcmVmcmFpbiBlbnRpcmVseSBmcm9tIGRpc3RyaWJ1dGlvbiBvZiB0aGUgUHJvZ3JhbS4KLQotSWYgYW55IHBvcnRpb24gb2YgdGhpcyBzZWN0aW9uIGlzIGhlbGQgaW52YWxpZCBvciB1bmVuZm9yY2VhYmxlIHVuZGVyIGFueQotcGFydGljdWxhciBjaXJjdW1zdGFuY2UsIHRoZSBiYWxhbmNlIG9mIHRoZSBzZWN0aW9uIGlzIGludGVuZGVkIHRvIGFwcGx5IGFuZAotdGhlIHNlY3Rpb24gYXMgYSB3aG9sZSBpcyBpbnRlbmRlZCB0byBhcHBseSBpbiBvdGhlciBjaXJjdW1zdGFuY2VzLgotCi1JdCBpcyBub3QgdGhlIHB1cnBvc2Ugb2YgdGhpcyBzZWN0aW9uIHRvIGluZHVjZSB5b3UgdG8gaW5mcmluZ2UgYW55IHBhdGVudHMgb3IKLW90aGVyIHByb3BlcnR5IHJpZ2h0IGNsYWltcyBvciB0byBjb250ZXN0IHZhbGlkaXR5IG9mIGFueSBzdWNoIGNsYWltczsgdGhpcwotc2VjdGlvbiBoYXMgdGhlIHNvbGUgcHVycG9zZSBvZiBwcm90ZWN0aW5nIHRoZSBpbnRlZ3JpdHkgb2YgdGhlIGZyZWUgc29mdHdhcmUKLWRpc3RyaWJ1dGlvbiBzeXN0ZW0sIHdoaWNoIGlzIGltcGxlbWVudGVkIGJ5IHB1YmxpYyBsaWNlbnNlIHByYWN0aWNlcy4gIE1hbnkKLXBlb3BsZSBoYXZlIG1hZGUgZ2VuZXJvdXMgY29udHJpYnV0aW9ucyB0byB0aGUgd2lkZSByYW5nZSBvZiBzb2Z0d2FyZQotZGlzdHJpYnV0ZWQgdGhyb3VnaCB0aGF0IHN5c3RlbSBpbiByZWxpYW5jZSBvbiBjb25zaXN0ZW50IGFwcGxpY2F0aW9uIG9mIHRoYXQKLXN5c3RlbTsgaXQgaXMgdXAgdG8gdGhlIGF1dGhvci9kb25vciB0byBkZWNpZGUgaWYgaGUgb3Igc2hlIGlzIHdpbGxpbmcgdG8KLWRpc3RyaWJ1dGUgc29mdHdhcmUgdGhyb3VnaCBhbnkgb3RoZXIgc3lzdGVtIGFuZCBhIGxpY2Vuc2VlIGNhbm5vdCBpbXBvc2UgdGhhdAotY2hvaWNlLgotCi1UaGlzIHNlY3Rpb24gaXMgaW50ZW5kZWQgdG8gbWFrZSB0aG9yb3VnaGx5IGNsZWFyIHdoYXQgaXMgYmVsaWV2ZWQgdG8gYmUgYQotY29uc2VxdWVuY2Ugb2YgdGhlIHJlc3Qgb2YgdGhpcyBMaWNlbnNlLgotCi04LiBJZiB0aGUgZGlzdHJpYnV0aW9uIGFuZC9vciB1c2Ugb2YgdGhlIFByb2dyYW0gaXMgcmVzdHJpY3RlZCBpbiBjZXJ0YWluCi1jb3VudHJpZXMgZWl0aGVyIGJ5IHBhdGVudHMgb3IgYnkgY29weXJpZ2h0ZWQgaW50ZXJmYWNlcywgdGhlIG9yaWdpbmFsCi1jb3B5cmlnaHQgaG9sZGVyIHdobyBwbGFjZXMgdGhlIFByb2dyYW0gdW5kZXIgdGhpcyBMaWNlbnNlIG1heSBhZGQgYW4gZXhwbGljaXQKLWdlb2dyYXBoaWNhbCBkaXN0cmlidXRpb24gbGltaXRhdGlvbiBleGNsdWRpbmcgdGhvc2UgY291bnRyaWVzLCBzbyB0aGF0Ci1kaXN0cmlidXRpb24gaXMgcGVybWl0dGVkIG9ubHkgaW4gb3IgYW1vbmcgY291bnRyaWVzIG5vdCB0aHVzIGV4Y2x1ZGVkLiAgSW4KLXN1Y2ggY2FzZSwgdGhpcyBMaWNlbnNlIGluY29ycG9yYXRlcyB0aGUgbGltaXRhdGlvbiBhcyBpZiB3cml0dGVuIGluIHRoZSBib2R5Ci1vZiB0aGlzIExpY2Vuc2UuCi0KLTkuIFRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24gbWF5IHB1Ymxpc2ggcmV2aXNlZCBhbmQvb3IgbmV3IHZlcnNpb25zIG9mIHRoZQotR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmcm9tIHRpbWUgdG8gdGltZS4gIFN1Y2ggbmV3IHZlcnNpb25zIHdpbGwgYmUgc2ltaWxhciBpbgotc3Bpcml0IHRvIHRoZSBwcmVzZW50IHZlcnNpb24sIGJ1dCBtYXkgZGlmZmVyIGluIGRldGFpbCB0byBhZGRyZXNzIG5ldyBwcm9ibGVtcwotb3IgY29uY2VybnMuCi0KLUVhY2ggdmVyc2lvbiBpcyBnaXZlbiBhIGRpc3Rpbmd1aXNoaW5nIHZlcnNpb24gbnVtYmVyLiAgSWYgdGhlIFByb2dyYW0KLXNwZWNpZmllcyBhIHZlcnNpb24gbnVtYmVyIG9mIHRoaXMgTGljZW5zZSB3aGljaCBhcHBsaWVzIHRvIGl0IGFuZCAiYW55IGxhdGVyCi12ZXJzaW9uIiwgeW91IGhhdmUgdGhlIG9wdGlvbiBvZiBmb2xsb3dpbmcgdGhlIHRlcm1zIGFuZCBjb25kaXRpb25zIGVpdGhlciBvZgotdGhhdCB2ZXJzaW9uIG9yIG9mIGFueSBsYXRlciB2ZXJzaW9uIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotSWYgdGhlIFByb2dyYW0gZG9lcyBub3Qgc3BlY2lmeSBhIHZlcnNpb24gbnVtYmVyIG9mIHRoaXMgTGljZW5zZSwgeW91IG1heQotY2hvb3NlIGFueSB2ZXJzaW9uIGV2ZXIgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0KLTEwLiBJZiB5b3Ugd2lzaCB0byBpbmNvcnBvcmF0ZSBwYXJ0cyBvZiB0aGUgUHJvZ3JhbSBpbnRvIG90aGVyIGZyZWUgcHJvZ3JhbXMKLXdob3NlIGRpc3RyaWJ1dGlvbiBjb25kaXRpb25zIGFyZSBkaWZmZXJlbnQsIHdyaXRlIHRvIHRoZSBhdXRob3IgdG8gYXNrIGZvcgotcGVybWlzc2lvbi4gIEZvciBzb2Z0d2FyZSB3aGljaCBpcyBjb3B5cmlnaHRlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgd2Ugc29tZXRpbWVzIG1ha2UgZXhjZXB0aW9ucyBmb3IgdGhpcy4KLU91ciBkZWNpc2lvbiB3aWxsIGJlIGd1aWRlZCBieSB0aGUgdHdvIGdvYWxzIG9mIHByZXNlcnZpbmcgdGhlIGZyZWUgc3RhdHVzIG9mCi1hbGwgZGVyaXZhdGl2ZXMgb2Ygb3VyIGZyZWUgc29mdHdhcmUgYW5kIG9mIHByb21vdGluZyB0aGUgc2hhcmluZyBhbmQgcmV1c2Ugb2YKLXNvZnR3YXJlIGdlbmVyYWxseS4KLQotTk8gV0FSUkFOVFkKLQotMTEuIEJFQ0FVU0UgVEhFIFBST0dSQU0gSVMgTElDRU5TRUQgRlJFRSBPRiBDSEFSR0UsIFRIRVJFIElTIE5PIFdBUlJBTlRZIEZPUgotVEhFIFBST0dSQU0sIFRPIFRIRSBFWFRFTlQgUEVSTUlUVEVEIEJZIEFQUExJQ0FCTEUgTEFXLiAgRVhDRVBUIFdIRU4gT1RIRVJXSVNFCi1TVEFURUQgSU4gV1JJVElORyBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EL09SIE9USEVSIFBBUlRJRVMgUFJPVklERSBUSEUKLVBST0dSQU0gIkFTIElTIiBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFSVRIRVIgRVhQUkVTU0VEIE9SIElNUExJRUQsCi1JTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5ECi1GSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFRIRSBFTlRJUkUgUklTSyBBUyBUTyBUSEUgUVVBTElUWSBBTkQKLVBFUkZPUk1BTkNFIE9GIFRIRSBQUk9HUkFNIElTIFdJVEggWU9VLiAgU0hPVUxEIFRIRSBQUk9HUkFNIFBST1ZFIERFRkVDVElWRSwKLVlPVSBBU1NVTUUgVEhFIENPU1QgT0YgQUxMIE5FQ0VTU0FSWSBTRVJWSUNJTkcsIFJFUEFJUiBPUiBDT1JSRUNUSU9OLgotCi0xMi4gSU4gTk8gRVZFTlQgVU5MRVNTIFJFUVVJUkVEIEJZIEFQUExJQ0FCTEUgTEFXIE9SIEFHUkVFRCBUTyBJTiBXUklUSU5HIFdJTEwKLUFOWSBDT1BZUklHSFQgSE9MREVSLCBPUiBBTlkgT1RIRVIgUEFSVFkgV0hPIE1BWSBNT0RJRlkgQU5EL09SIFJFRElTVFJJQlVURSBUSEUKLVBST0dSQU0gQVMgUEVSTUlUVEVEIEFCT1ZFLCBCRSBMSUFCTEUgVE8gWU9VIEZPUiBEQU1BR0VTLCBJTkNMVURJTkcgQU5ZCi1HRU5FUkFMLCBTUEVDSUFMLCBJTkNJREVOVEFMIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyBBUklTSU5HIE9VVCBPRiBUSEUgVVNFIE9SCi1JTkFCSUxJVFkgVE8gVVNFIFRIRSBQUk9HUkFNIChJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIExPU1MgT0YgREFUQSBPUiBEQVRBCi1CRUlORyBSRU5ERVJFRCBJTkFDQ1VSQVRFIE9SIExPU1NFUyBTVVNUQUlORUQgQlkgWU9VIE9SIFRISVJEIFBBUlRJRVMgT1IgQQotRkFJTFVSRSBPRiBUSEUgUFJPR1JBTSBUTyBPUEVSQVRFIFdJVEggQU5ZIE9USEVSIFBST0dSQU1TKSwgRVZFTiBJRiBTVUNIIEhPTERFUgotT1IgT1RIRVIgUEFSVFkgSEFTIEJFRU4gQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0VTLgotCi1FTkQgT0YgVEVSTVMgQU5EIENPTkRJVElPTlMKLQotSG93IHRvIEFwcGx5IFRoZXNlIFRlcm1zIHRvIFlvdXIgTmV3IFByb2dyYW1zCi0KLUlmIHlvdSBkZXZlbG9wIGEgbmV3IHByb2dyYW0sIGFuZCB5b3Ugd2FudCBpdCB0byBiZSBvZiB0aGUgZ3JlYXRlc3QgcG9zc2libGUKLXVzZSB0byB0aGUgcHVibGljLCB0aGUgYmVzdCB3YXkgdG8gYWNoaWV2ZSB0aGlzIGlzIHRvIG1ha2UgaXQgZnJlZSBzb2Z0d2FyZQotd2hpY2ggZXZlcnlvbmUgY2FuIHJlZGlzdHJpYnV0ZSBhbmQgY2hhbmdlIHVuZGVyIHRoZXNlIHRlcm1zLgotCi1UbyBkbyBzbywgYXR0YWNoIHRoZSBmb2xsb3dpbmcgbm90aWNlcyB0byB0aGUgcHJvZ3JhbS4gIEl0IGlzIHNhZmVzdCB0byBhdHRhY2gKLXRoZW0gdG8gdGhlIHN0YXJ0IG9mIGVhY2ggc291cmNlIGZpbGUgdG8gbW9zdCBlZmZlY3RpdmVseSBjb252ZXkgdGhlIGV4Y2x1c2lvbgotb2Ygd2FycmFudHk7IGFuZCBlYWNoIGZpbGUgc2hvdWxkIGhhdmUgYXQgbGVhc3QgdGhlICJjb3B5cmlnaHQiIGxpbmUgYW5kIGEKLXBvaW50ZXIgdG8gd2hlcmUgdGhlIGZ1bGwgbm90aWNlIGlzIGZvdW5kLgotCi0gICAgT25lIGxpbmUgdG8gZ2l2ZSB0aGUgcHJvZ3JhbSdzIG5hbWUgYW5kIGEgYnJpZWYgaWRlYSBvZiB3aGF0IGl0IGRvZXMuCi0KLSAgICBDb3B5cmlnaHQgKEMpIDx5ZWFyPiA8bmFtZSBvZiBhdXRob3I+Ci0KLSAgICBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICAgIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlCi0gICAgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMiBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKQotICAgIGFueSBsYXRlciB2ZXJzaW9uLgotCi0gICAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gICAgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gICAgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvcgotICAgIG1vcmUgZGV0YWlscy4KLQotICAgIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFsb25nCi0gICAgd2l0aCB0aGlzIHByb2dyYW07IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgSW5jLiwKLSAgICA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotCi1BbHNvIGFkZCBpbmZvcm1hdGlvbiBvbiBob3cgdG8gY29udGFjdCB5b3UgYnkgZWxlY3Ryb25pYyBhbmQgcGFwZXIgbWFpbC4KLQotSWYgdGhlIHByb2dyYW0gaXMgaW50ZXJhY3RpdmUsIG1ha2UgaXQgb3V0cHV0IGEgc2hvcnQgbm90aWNlIGxpa2UgdGhpcyB3aGVuIGl0Ci1zdGFydHMgaW4gYW4gaW50ZXJhY3RpdmUgbW9kZToKLQotICAgIEdub21vdmlzaW9uIHZlcnNpb24gNjksIENvcHlyaWdodCAoQykgeWVhciBuYW1lIG9mIGF1dGhvciBHbm9tb3Zpc2lvbiBjb21lcwotICAgIHdpdGggQUJTT0xVVEVMWSBOTyBXQVJSQU5UWTsgZm9yIGRldGFpbHMgdHlwZSAnc2hvdyB3Jy4gIFRoaXMgaXMgZnJlZQotICAgIHNvZnR3YXJlLCBhbmQgeW91IGFyZSB3ZWxjb21lIHRvIHJlZGlzdHJpYnV0ZSBpdCB1bmRlciBjZXJ0YWluIGNvbmRpdGlvbnM7Ci0gICAgdHlwZSAnc2hvdyBjJyBmb3IgZGV0YWlscy4KLQotVGhlIGh5cG90aGV0aWNhbCBjb21tYW5kcyAnc2hvdyB3JyBhbmQgJ3Nob3cgYycgc2hvdWxkIHNob3cgdGhlIGFwcHJvcHJpYXRlCi1wYXJ0cyBvZiB0aGUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZS4gIE9mIGNvdXJzZSwgdGhlIGNvbW1hbmRzIHlvdSB1c2UgbWF5IGJlCi1jYWxsZWQgc29tZXRoaW5nIG90aGVyIHRoYW4gJ3Nob3cgdycgYW5kICdzaG93IGMnOyB0aGV5IGNvdWxkIGV2ZW4gYmUKLW1vdXNlLWNsaWNrcyBvciBtZW51IGl0ZW1zLS13aGF0ZXZlciBzdWl0cyB5b3VyIHByb2dyYW0uCi0KLVlvdSBzaG91bGQgYWxzbyBnZXQgeW91ciBlbXBsb3llciAoaWYgeW91IHdvcmsgYXMgYSBwcm9ncmFtbWVyKSBvciB5b3VyIHNjaG9vbCwKLWlmIGFueSwgdG8gc2lnbiBhICJjb3B5cmlnaHQgZGlzY2xhaW1lciIgZm9yIHRoZSBwcm9ncmFtLCBpZiBuZWNlc3NhcnkuICBIZXJlCi1pcyBhIHNhbXBsZTsgYWx0ZXIgdGhlIG5hbWVzOgotCi0gICAgWW95b2R5bmUsIEluYy4sIGhlcmVieSBkaXNjbGFpbXMgYWxsIGNvcHlyaWdodCBpbnRlcmVzdCBpbiB0aGUgcHJvZ3JhbQotICAgICdHbm9tb3Zpc2lvbicgKHdoaWNoIG1ha2VzIHBhc3NlcyBhdCBjb21waWxlcnMpIHdyaXR0ZW4gYnkgSmFtZXMgSGFja2VyLgotCi0gICAgc2lnbmF0dXJlIG9mIFR5IENvb24sIDEgQXByaWwgMTk4OQotCi0gICAgVHkgQ29vbiwgUHJlc2lkZW50IG9mIFZpY2UKLQotVGhpcyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGRvZXMgbm90IHBlcm1pdCBpbmNvcnBvcmF0aW5nIHlvdXIgcHJvZ3JhbSBpbnRvCi1wcm9wcmlldGFyeSBwcm9ncmFtcy4gIElmIHlvdXIgcHJvZ3JhbSBpcyBhIHN1YnJvdXRpbmUgbGlicmFyeSwgeW91IG1heQotY29uc2lkZXIgaXQgbW9yZSB1c2VmdWwgdG8gcGVybWl0IGxpbmtpbmcgcHJvcHJpZXRhcnkgYXBwbGljYXRpb25zIHdpdGggdGhlCi1saWJyYXJ5LiAgSWYgdGhpcyBpcyB3aGF0IHlvdSB3YW50IHRvIGRvLCB1c2UgdGhlIEdOVSBMaWJyYXJ5IEdlbmVyYWwgUHVibGljCi1MaWNlbnNlIGluc3RlYWQgb2YgdGhpcyBMaWNlbnNlLgotCi0KLSJDTEFTU1BBVEgiIEVYQ0VQVElPTiBUTyBUSEUgR1BMCi0KLUNlcnRhaW4gc291cmNlIGZpbGVzIGRpc3RyaWJ1dGVkIGJ5IE9yYWNsZSBBbWVyaWNhIGFuZC9vciBpdHMgYWZmaWxpYXRlcyBhcmUKLXN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjbGFyaWZpY2F0aW9uIGFuZCBzcGVjaWFsIGV4Y2VwdGlvbiB0byB0aGUgR1BMLCBidXQKLW9ubHkgd2hlcmUgT3JhY2xlIGhhcyBleHByZXNzbHkgaW5jbHVkZWQgaW4gdGhlIHBhcnRpY3VsYXIgc291cmNlIGZpbGUncyBoZWFkZXIKLXRoZSB3b3JkcyAiT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcyBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIKLWV4Y2VwdGlvbiBhcyBwcm92aWRlZCBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4iCi0KLSAgICBMaW5raW5nIHRoaXMgbGlicmFyeSBzdGF0aWNhbGx5IG9yIGR5bmFtaWNhbGx5IHdpdGggb3RoZXIgbW9kdWxlcyBpcyBtYWtpbmcKLSAgICBhIGNvbWJpbmVkIHdvcmsgYmFzZWQgb24gdGhpcyBsaWJyYXJ5LiAgVGh1cywgdGhlIHRlcm1zIGFuZCBjb25kaXRpb25zIG9mCi0gICAgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGNvdmVyIHRoZSB3aG9sZSBjb21iaW5hdGlvbi4KLQotICAgIEFzIGEgc3BlY2lhbCBleGNlcHRpb24sIHRoZSBjb3B5cmlnaHQgaG9sZGVycyBvZiB0aGlzIGxpYnJhcnkgZ2l2ZSB5b3UKLSAgICBwZXJtaXNzaW9uIHRvIGxpbmsgdGhpcyBsaWJyYXJ5IHdpdGggaW5kZXBlbmRlbnQgbW9kdWxlcyB0byBwcm9kdWNlIGFuCi0gICAgZXhlY3V0YWJsZSwgcmVnYXJkbGVzcyBvZiB0aGUgbGljZW5zZSB0ZXJtcyBvZiB0aGVzZSBpbmRlcGVuZGVudCBtb2R1bGVzLAotICAgIGFuZCB0byBjb3B5IGFuZCBkaXN0cmlidXRlIHRoZSByZXN1bHRpbmcgZXhlY3V0YWJsZSB1bmRlciB0ZXJtcyBvZiB5b3VyCi0gICAgY2hvaWNlLCBwcm92aWRlZCB0aGF0IHlvdSBhbHNvIG1lZXQsIGZvciBlYWNoIGxpbmtlZCBpbmRlcGVuZGVudCBtb2R1bGUsCi0gICAgdGhlIHRlcm1zIGFuZCBjb25kaXRpb25zIG9mIHRoZSBsaWNlbnNlIG9mIHRoYXQgbW9kdWxlLiAgQW4gaW5kZXBlbmRlbnQKLSAgICBtb2R1bGUgaXMgYSBtb2R1bGUgd2hpY2ggaXMgbm90IGRlcml2ZWQgZnJvbSBvciBiYXNlZCBvbiB0aGlzIGxpYnJhcnkuICBJZgotICAgIHlvdSBtb2RpZnkgdGhpcyBsaWJyYXJ5LCB5b3UgbWF5IGV4dGVuZCB0aGlzIGV4Y2VwdGlvbiB0byB5b3VyIHZlcnNpb24gb2YKLSAgICB0aGUgbGlicmFyeSwgYnV0IHlvdSBhcmUgbm90IG9ibGlnYXRlZCB0byBkbyBzby4gIElmIHlvdSBkbyBub3Qgd2lzaCB0byBkbwotICAgIHNvLCBkZWxldGUgdGhpcyBleGNlcHRpb24gc3RhdGVtZW50IGZyb20geW91ciB2ZXJzaW9uLgpkaWZmIC0tZ2l0IGEvUkVBRE1FIGIvUkVBRE1FCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0ZDY1MTI1Li4wMDAwMDAwCi0tLSBhL1JFQURNRQorKysgL2Rldi9udWxsCkBAIC0xLDE5ICswLDAgQEAKLVJFQURNRToKLSAgCi0gIFRoaXMgZmlsZSBzaG91bGQgYmUgbG9jYXRlZCBhdCB0aGUgdG9wIG9mIHRoZSBNZXJjdXJpYWwgcmVwb3NpdG9yeS4KLQotICBTZWUgaHR0cDovL29wZW5qZGsuamF2YS5uZXQvIGZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IHRoZSBPcGVuSkRLLgotCi0gIFNlZSAuLi9SRUFETUUtYnVpbGRzLmh0bWwgZm9yIGNvbXBsZXRlIGRldGFpbHMgb24gYnVpbGQgbWFjaGluZSByZXF1aXJlbWVudHMuCi0KLVNpbXBsZSBCdWlsZCBJbnN0cnVjdGlvbnM6Ci0gIFRoaXMgcmVwb3NpdG9yeSBjYW4gYmUgbG9hZGVkIGFzIGEgTmV0QmVhbnMgcHJvamVjdCwgYnVpbHQgd2l0aCBhbnQsIG9yCi0gIGJ1aWx0IHdpdGggR05VIG1ha2UsIGUuZy4KLSAgICBhbnQKLSAgICAgICAtT1ItCi0gICAgY2QgbWFrZSAmJiBnbnVtYWtlCi0gICAgIAotICBUaGUgYnVpbHQgZmlsZXMgdGhhdCB3aWxsIGJlIGltcG9ydGVkIGludG8gdGhlIGpkayBidWlsZCB3aWxsIGJlIGluIHRoZSAKLSAgImRpc3QiIGRpcmVjdG9yeS4KLSAgSGVscCBpbmZvcm1hdGlvbiBpcyBhdmFpbGFibGUgYnkgcnVubmluZyAiYW50IC1wcm9qZWN0aGVscCIgb3IgIm1ha2UgaGVscCIuCi0KZGlmZiAtLWdpdCBhL1RISVJEX1BBUlRZX1JFQURNRSBiL1RISVJEX1BBUlRZX1JFQURNRQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMmIyMGRhMi4uMDAwMDAwMAotLS0gYS9USElSRF9QQVJUWV9SRUFETUUKKysrIC9kZXYvbnVsbApAQCAtMSwzNTc0ICswLDAgQEAKLURPIE5PVCBUUkFOU0xBVEUgT1IgTE9DQUxJWkUuCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotCi0lJSBUaGlzIG5vdGljZSBpcyBwcm92aWRlZCB3aXRoIHJlc3BlY3QgdG8gQVNNIEJ5dGVjb2RlIE1hbmlwdWxhdGlvbiAKLUZyYW1ld29yayB2NS4wLjMsIHdoaWNoIG1heSBiZSBpbmNsdWRlZCB3aXRoIEpSRSA4LCBhbmQgSkRLIDgsIGFuZCAKLU9wZW5KREsgOC4KLQotLS0tIGJlZ2luIG9mIExJQ0VOU0UgLS0tCi0KLUNvcHlyaWdodCAoYykgMjAwMC0yMDExIEZyYW5jZSBUw6lsw6ljb20KLUFsbCByaWdodHMgcmVzZXJ2ZWQuCi0KLVJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi1hcmUgbWV0OgotCi0xLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotCi0yLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZQotICAgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi4KLQotMy4gTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgY29weXJpZ2h0IGhvbGRlcnMgbm9yIHRoZSBuYW1lcyBvZiBpdHMKLSAgIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCi0gICB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgotCi1USElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTICJBUyBJUyIKLUFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUKLUlNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFCi1BUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUKLUxJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IKLUNPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GCi1TVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MKLUlOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOCi1DT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKQotQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRgotVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgotCi0tLS0gZW5kIG9mIExJQ0VOU0UgLS0tCi0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0KLSUlIFRoaXMgbm90aWNlIGlzIHByb3ZpZGVkIHdpdGggcmVzcGVjdCB0byBCU0RpZmYgdjQuMywgd2hpY2ggbWF5IGJlIAotaW5jbHVkZWQgd2l0aCBKUkUgOCwgSkRLIDgsIGFuZCBPcGVuSkRLIDguCi0KLS0tLSBiZWdpbiBvZiBMSUNFTlNFIC0tLQotCi1Db3B5cmlnaHQgMjAwMy0yMDA1IENvbGluIFBlcmNpdmFsCi1BbGwgcmlnaHRzIHJlc2VydmVkCi0KLVJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGluZyB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotYXJlIG1ldDoKLTEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci1ub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0yLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZQotZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi4KLQotVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQVVUSE9SIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1MgT1IKLUlNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVECi1XQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UKLUFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SIEJFIExJQUJMRSBGT1IgQU5ZCi1ESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwKLURBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTCi1PUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikKLUhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwKLVNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORwotSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFCi1QT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KLQotLS0tIGVuZCBvZiBMSUNFTlNFIC0tLQotCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0KLSUlIFRoaXMgbm90aWNlIGlzIHByb3ZpZGVkIHdpdGggcmVzcGVjdCB0byBDb2RlVmlld2VyIDEuMCwgd2hpY2ggbWF5IGJlCi1pbmNsdWRlZCB3aXRoIEpESyA4LgotCi0tLS0gYmVnaW4gb2YgTElDRU5TRSAtLS0KLQotQ29weXJpZ2h0IDE5OTkgYnkgQ29vbFNlcnZsZXRzLmNvbS4KLQotQW55IGVycm9ycyBvciBzdWdnZXN0ZWQgaW1wcm92ZW1lbnRzIHRvIHRoaXMgY2xhc3MgY2FuIGJlIHJlcG9ydGVkIGFzCi1pbnN0cnVjdGVkIG9uIENvb2xTZXJ2bGV0cy5jb20uIFdlIGhvcGUgeW91IGVuam95IHRoaXMgcHJvZ3JhbS4uLiB5b3VyCi1jb21tZW50cyB3aWxsIGVuY291cmFnZSBmdXJ0aGVyIGRldmVsb3BtZW50ISAgVGhpcyBzb2Z0d2FyZSBpcyBkaXN0cmlidXRlZAotdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBCU0QgTGljZW5zZS4gIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZAotYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQgbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlCi1mb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OgotCi0xLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXMKLSAgIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotCi0yLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsCi0gICB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uCi0gICBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi4KLQotTmVpdGhlciBuYW1lIG9mIENvb2xTZXJ2bGV0cy5jb20gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzIG1heSBiZQotdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dAotc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgotCi1USElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIENPT0xTRVJWTEVUUy5DT00gQU5EIENPTlRSSUJVVE9SUyBgYEFTIElTJycgQU5ECi1BTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRAotV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkKLURJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTCi0oSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7Ci1MT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04KLUFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCi0oSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUwotU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuIgotCi0KLS0tLSBlbmQgb2YgTElDRU5TRSAtLS0KLQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotCi0lJSBUaGlzIG5vdGljZSBpcyBwcm92aWRlZCB3aXRoIHJlc3BlY3QgdG8gQ3J5cHRpeCBBRVMgMy4yLjAsIHdoaWNoIG1heSBiZQotaW5jbHVkZWQgd2l0aCBKUkUgOCwgSkRLIDgsIGFuZCBPcGVuSkRLIDguCi0KLS0tLSBiZWdpbiBvZiBMSUNFTlNFIC0tLQotCi1DcnlwdGl4IEdlbmVyYWwgTGljZW5zZQotCi1Db3B5cmlnaHQgKGMpIDE5OTUtMjAwNSBUaGUgQ3J5cHRpeCBGb3VuZGF0aW9uIExpbWl0ZWQuCi1BbGwgcmlnaHRzIHJlc2VydmVkLgotCi1SZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLW1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKLW1ldDoKLQotICAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGNvcHlyaWdodCBub3RpY2UsCi0gICAgIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0KLSAgMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAgICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAgICAgZGlzdHJpYnV0aW9uLgotCi1USElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDUllQVElYIEZPVU5EQVRJT04gTElNSVRFRCBBTkQKLUNPTlRSSUJVVE9SUyBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywKLUlOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GCi1NRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELgotSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENSWVBUSVggRk9VTkRBVElPTiBMSU1JVEVEIE9SIENPTlRSSUJVVE9SUyBCRQotTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUgotQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YKLVNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUgotQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksCi1XSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRQotT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTgotSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCi0KLS0tLSBlbmQgb2YgTElDRU5TRSAtLS0KLQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotCi0lJSBUaGlzIG5vdGljZSBpcyBwcm92aWRlZCB3aXRoIHJlc3BlY3QgdG8gQ1VQIFBhcnNlciBHZW5lcmF0b3IgZm9yIAotSmF2YSAwLjEwaywgd2hpY2ggbWF5IGJlIGluY2x1ZGVkIHdpdGggSlJFIDgsIEpESyA4LCBhbmQgT3BlbkpESyA4LgotCi0tLS0gYmVnaW4gb2YgTElDRU5TRSAtLS0KLQotQ29weXJpZ2h0IDE5OTYtMTk5OSBieSBTY290dCBIdWRzb24sIEZyYW5rIEZsYW5uZXJ5LCBDLiBTY290dCBBbmFuaWFuCi0KLVBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGFuZCBkaXN0cmlidXRlIHRoaXMgc29mdHdhcmUgYW5kIGl0cwotZG9jdW1lbnRhdGlvbiBmb3IgYW55IHB1cnBvc2UgYW5kIHdpdGhvdXQgZmVlIGlzIGhlcmVieSBncmFudGVkLCBwcm92aWRlZAotdGhhdCB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhcHBlYXIgaW4gYWxsIGNvcGllcyBhbmQgdGhhdCBib3RoIHRoZQotY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBhbmQgd2FycmFudHkgZGlzY2xhaW1lciBhcHBlYXIgaW4KLXN1cHBvcnRpbmcgZG9jdW1lbnRhdGlvbiwgYW5kIHRoYXQgdGhlIG5hbWVzIG9mIHRoZSBhdXRob3JzIG9yIHRoZWlyCi1lbXBsb3llcnMgbm90IGJlIHVzZWQgaW4gYWR2ZXJ0aXNpbmcgb3IgcHVibGljaXR5IHBlcnRhaW5pbmcgdG8gZGlzdHJpYnV0aW9uIG9mCi10aGUgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYywgd3JpdHRlbiBwcmlvciBwZXJtaXNzaW9uLgotCi1UaGUgYXV0aG9ycyBhbmQgdGhlaXIgZW1wbG95ZXJzIGRpc2NsYWltIGFsbCB3YXJyYW50aWVzIHdpdGggcmVnYXJkIHRvCi10aGlzIHNvZnR3YXJlLCBpbmNsdWRpbmcgYWxsIGltcGxpZWQgd2FycmFudGllcyBvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MuCi1JbiBubyBldmVudCBzaGFsbCB0aGUgYXV0aG9ycyBvciB0aGVpciBlbXBsb3llcnMgYmUgbGlhYmxlIGZvciBhbnkgc3BlY2lhbCwKLWluZGlyZWN0IG9yIGNvbnNlcXVlbnRpYWwgZGFtYWdlcyBvciBhbnkgZGFtYWdlcyB3aGF0c29ldmVyIHJlc3VsdGluZyBmcm9tCi1sb3NzIG9mIHVzZSwgZGF0YSBvciBwcm9maXRzLCB3aGV0aGVyIGluIGFuIGFjdGlvbiBvZiBjb250cmFjdCwgbmVnbGlnZW5jZSBvcgotb3RoZXIgdG9ydGlvdXMgYWN0aW9uLCBhcmlzaW5nIG91dCBvZiBvciBpbiBjb25uZWN0aW9uIHdpdGggdGhlIHVzZSBvcgotcGVyZm9ybWFuY2Ugb2YgdGhpcyBzb2Z0d2FyZS4KLQotLS0tIGVuZCBvZiBMSUNFTlNFIC0tLQotCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0KLSUlIFRoaXMgbm90aWNlIGlzIHByb3ZpZGVkIHdpdGggcmVzcGVjdCB0byBEb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMgotJiAzLCB3aGljaCBtYXkgYmUgaW5jbHVkZWQgd2l0aCBKUkUgOCwgSkRLIDgsIGFuZCBPcGVuSkRLIDguCi0KLS0tLSBiZWdpbiBvZiBMSUNFTlNFIC0tLQotCi1XM0MgU09GVFdBUkUgTk9USUNFIEFORCBMSUNFTlNFCi0KLWh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvMjAwMi9jb3B5cmlnaHQtc29mdHdhcmUtMjAwMjEyMzEKLQotVGhpcyB3b3JrIChhbmQgaW5jbHVkZWQgc29mdHdhcmUsIGRvY3VtZW50YXRpb24gc3VjaCBhcyBSRUFETUVzLCBvciBvdGhlcgotcmVsYXRlZCBpdGVtcykgaXMgYmVpbmcgcHJvdmlkZWQgYnkgdGhlIGNvcHlyaWdodCBob2xkZXJzIHVuZGVyIHRoZSBmb2xsb3dpbmcKLWxpY2Vuc2UuIEJ5IG9idGFpbmluZywgdXNpbmcgYW5kL29yIGNvcHlpbmcgdGhpcyB3b3JrLCB5b3UgKHRoZSBsaWNlbnNlZSkKLWFncmVlIHRoYXQgeW91IGhhdmUgcmVhZCwgdW5kZXJzdG9vZCwgYW5kIHdpbGwgY29tcGx5IHdpdGggdGhlIGZvbGxvd2luZyB0ZXJtcwotYW5kIGNvbmRpdGlvbnMuCi0KLVBlcm1pc3Npb24gdG8gY29weSwgbW9kaWZ5LCBhbmQgZGlzdHJpYnV0ZSB0aGlzIHNvZnR3YXJlIGFuZCBpdHMKLWRvY3VtZW50YXRpb24sIHdpdGggb3Igd2l0aG91dCBtb2RpZmljYXRpb24sIGZvciBhbnkgcHVycG9zZSBhbmQgd2l0aG91dCBmZWUKLW9yIHJveWFsdHkgaXMgaGVyZWJ5IGdyYW50ZWQsIHByb3ZpZGVkIHRoYXQgeW91IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBvbiBBTEwKLWNvcGllcyBvZiB0aGUgc29mdHdhcmUgYW5kIGRvY3VtZW50YXRpb24gb3IgcG9ydGlvbnMgdGhlcmVvZiwgaW5jbHVkaW5nCi1tb2RpZmljYXRpb25zOgotCi0gICAxLlRoZSBmdWxsIHRleHQgb2YgdGhpcyBOT1RJQ0UgaW4gYSBsb2NhdGlvbiB2aWV3YWJsZSB0byB1c2VycyBvZiB0aGUKLSAgIHJlZGlzdHJpYnV0ZWQgb3IgZGVyaXZhdGl2ZSB3b3JrLgotCi0gICAyLkFueSBwcmUtZXhpc3RpbmcgaW50ZWxsZWN0dWFsIHByb3BlcnR5IGRpc2NsYWltZXJzLCBub3RpY2VzLCBvciB0ZXJtcyBhbmQKLSAgIGNvbmRpdGlvbnMuIElmIG5vbmUgZXhpc3QsIHRoZSBXM0MgU29mdHdhcmUgU2hvcnQgTm90aWNlIHNob3VsZCBiZSBpbmNsdWRlZAotICAgKGh5cGVydGV4dCBpcyBwcmVmZXJyZWQsIHRleHQgaXMgcGVybWl0dGVkKSB3aXRoaW4gdGhlIGJvZHkgb2YgYW55Ci0gICByZWRpc3RyaWJ1dGVkIG9yIGRlcml2YXRpdmUgY29kZS4KLQotICAgMy5Ob3RpY2Ugb2YgYW55IGNoYW5nZXMgb3IgbW9kaWZpY2F0aW9ucyB0byB0aGUgZmlsZXMsIGluY2x1ZGluZyB0aGUgZGF0ZQotICAgY2hhbmdlcyB3ZXJlIG1hZGUuIChXZSByZWNvbW1lbmQgeW91IHByb3ZpZGUgVVJJcyB0byB0aGUgbG9jYXRpb24gZnJvbQotICAgd2hpY2ggdGhlIGNvZGUgaXMgZGVyaXZlZC4pCi0KLVRISVMgU09GVFdBUkUgQU5EIERPQ1VNRU5UQVRJT04gSVMgUFJPVklERUQgIkFTIElTLCIgQU5EIENPUFlSSUdIVCBIT0xERVJTCi1NQUtFIE5PIFJFUFJFU0VOVEFUSU9OUyBPUiBXQVJSQU5USUVTLCBFWFBSRVNTIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UCi1MSU1JVEVEIFRPLCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBPUiBGSVRORVNTIEZPUiBBTlkgUEFSVElDVUxBUgotUFVSUE9TRSBPUiBUSEFUIFRIRSBVU0UgT0YgVEhFIFNPRlRXQVJFIE9SIERPQ1VNRU5UQVRJT04gV0lMTCBOT1QgSU5GUklOR0UgQU5ZCi1USElSRCBQQVJUWSBQQVRFTlRTLENPUFlSSUdIVFMsIFRSQURFTUFSS1MgT1IgT1RIRVIgUklHSFRTLgotCi1DT1BZUklHSFQgSE9MREVSUyBXSUxMIE5PVCBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBTUEVDSUFMCi1PUiBDT05TRVFVRU5USUFMIERBTUFHRVMgQVJJU0lORyBPVVQgT0YgQU5ZIFVTRSBPRiBUSEUgU09GVFdBUkUgT1IKLURPQ1VNRU5UQVRJT04uICBUaGUgbmFtZSBhbmQgdHJhZGVtYXJrcyBvZiBjb3B5cmlnaHQgaG9sZGVycyBtYXkgTk9UIGJlIHVzZWQKLWluIGFkdmVydGlzaW5nIG9yIHB1YmxpY2l0eSBwZXJ0YWluaW5nIHRvIHRoZSBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljLAotd3JpdHRlbiBwcmlvciBwZXJtaXNzaW9uLiBUaXRsZSB0byBjb3B5cmlnaHQgaW4gdGhpcyBzb2Z0d2FyZSBhbmQgYW55Ci1hc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gd2lsbCBhdCBhbGwgdGltZXMgcmVtYWluIHdpdGggY29weXJpZ2h0IGhvbGRlcnMuCi0KLV9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwotCi1UaGlzIGZvcm11bGF0aW9uIG9mIFczQydzIG5vdGljZSBhbmQgbGljZW5zZSBiZWNhbWUgYWN0aXZlIG9uIERlY2VtYmVyIDMxCi0yMDAyLiBUaGlzIHZlcnNpb24gcmVtb3ZlcyB0aGUgY29weXJpZ2h0IG93bmVyc2hpcCBub3RpY2Ugc3VjaCB0aGF0IHRoaXMKLWxpY2Vuc2UgY2FuIGJlIHVzZWQgd2l0aCBtYXRlcmlhbHMgb3RoZXIgdGhhbiB0aG9zZSBvd25lZCBieSB0aGUgVzNDLCByZWZsZWN0cwotdGhhdCBFUkNJTSBpcyBub3cgYSBob3N0IG9mIHRoZSBXM0MsIGluY2x1ZGVzIHJlZmVyZW5jZXMgdG8gdGhpcyBzcGVjaWZpYwotZGF0ZWQgdmVyc2lvbiBvZiB0aGUgbGljZW5zZSwgYW5kIHJlbW92ZXMgdGhlIGFtYmlndW91cyBncmFudCBvZiAidXNlIi4KLU90aGVyd2lzZSwgdGhpcyB2ZXJzaW9uIGlzIHRoZSBzYW1lIGFzIHRoZSBwcmV2aW91cyB2ZXJzaW9uIGFuZCBpcyB3cml0dGVuIHNvCi1hcyB0byBwcmVzZXJ2ZSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uJ3MgYXNzZXNzbWVudCBvZiBHUEwgY29tcGF0aWJpbGl0eQotYW5kIE9TSSdzIGNlcnRpZmljYXRpb24gdW5kZXIgdGhlIE9wZW4gU291cmNlIERlZmluaXRpb24uIFBsZWFzZSBzZWUgb3VyCi1Db3B5cmlnaHQgRkFRIGZvciBjb21tb24gcXVlc3Rpb25zIGFib3V0IHVzaW5nIG1hdGVyaWFscyBmcm9tIG91ciBzaXRlLAotaW5jbHVkaW5nIHNwZWNpZmljIHRlcm1zIGFuZCBjb25kaXRpb25zIGZvciBwYWNrYWdlcyBsaWtlIGxpYnd3dywgQW1heWEsIGFuZAotSmlnc2F3LiBPdGhlciBxdWVzdGlvbnMgYWJvdXQgdGhpcyBub3RpY2UgY2FuIGJlIGRpcmVjdGVkIHRvCi1zaXRlLXBvbGljeUB3My5vcmcuCi0KLS0tLSBlbmQgb2YgTElDRU5TRSAtLS0KLQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotCi0lJSBUaGlzIG5vdGljZSBpcyBwcm92aWRlZCB3aXRoIHJlc3BlY3QgdG8gRHluYWxpbmsgdjAuNSwgd2hpY2ggbWF5IGJlIAotaW5jbHVkZWQgd2l0aCBKUkUgOCwgSkRLIDgsIGFuZCBPcGVuSkRLIDguCi0KLS0tLSBiZWdpbiBvZiBMSUNFTlNFIC0tLQotCi1Db3B5cmlnaHQgKGMpIDIwMDktMjAxMywgQXR0aWxhIFN6ZWdlZGkKLQotQWxsIHJpZ2h0cyByZXNlcnZlZC5SZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yCi13aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKLW1ldDoqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwKLXRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuICAqIFJlZGlzdHJpYnV0aW9ucyBpbgotYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsICAgdGhpcyBsaXN0IG9mCi1jb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gIGFuZC9vciBvdGhlcgotbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi4gICogTmVpdGhlciB0aGUgbmFtZSBvZiBBdHRpbGEKLVN6ZWdlZGkgbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZQotcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCi0KLVRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgIkFTIElTIkFORAotQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQKLVdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLURJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUKLUZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMCi1EQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUgotU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIKLUNBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi1PUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQotT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgotCi0tLS0gZW5kIG9mIExJQ0VOU0UgLS0tCi0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLQotJSUgVGhpcyBub3RpY2UgaXMgcHJvdmlkZWQgd2l0aCByZXNwZWN0IHRvIEVsbGlwdGljIEN1cnZlIENyeXB0b2dyYXBoeSwgd2hpY2ggCi1tYXkgYmUgaW5jbHVkZWQgd2l0aCBKUkUgOCwgSkRLIDgsIGFuZCBPcGVuSkRLIDguCi0KLVlvdSBhcmUgcmVjZWl2aW5nIGEgY29weSBvZiB0aGUgRWxsaXB0aWMgQ3VydmUgQ3J5cHRvZ3JhcGh5IGxpYnJhcnkgaW4gc291cmNlCi1mb3JtIHdpdGggdGhlIEpESyA4IGFuZCBPcGVuSkRLIDggc291cmNlIGRpc3RyaWJ1dGlvbnMsIGFuZCBhcyBvYmplY3QgY29kZSBpbgotdGhlIEpSRSA4ICYgSkRLIDggcnVudGltZXMuCi0KLUluIHRoZSBjYXNlIG9mIHRoZSBKUkUgOCAmIEpESyA4IHJ1bnRpbWVzLCB0aGUgdGVybXMgb2YgdGhlIE9yYWNsZSBsaWNlbnNlIGRvCi1OT1QgYXBwbHkgdG8gdGhlIEVsbGlwdGljIEN1cnZlIENyeXB0b2dyYXBoeSBsaWJyYXJ5OyBpdCBpcyBsaWNlbnNlZCB1bmRlciB0aGUKLWZvbGxvd2luZyBsaWNlbnNlLCBzZXBhcmF0ZWx5IGZyb20gT3JhY2xlJ3MgSkRLICYgSlJFLiAgSWYgeW91IGRvIG5vdCB3aXNoIHRvCi1pbnN0YWxsIHRoZSBFbGxpcHRpYyBDdXJ2ZSBDcnlwdG9ncmFwaHkgbGlicmFyeSwgeW91IG1heSBkZWxldGUgdGhlIGxpYnJhcnkKLW5hbWVkIGxpYnN1bmVjLnNvIChvbiBTb2xhcmlzIGFuZCBMaW51eCBzeXN0ZW1zKSBvciBzdW5lYy5kbGwgKG9uIFdpbmRvd3MKLXN5c3RlbXMpIGZyb20gdGhlIEpSRSBiaW4gZGlyZWN0b3J5IHJlc2VydmVkIGZvciBuYXRpdmUgbGlicmFyaWVzLgotCi0KLS0tLSBiZWdpbiBvZiBMSUNFTlNFIC0tLQotCi0gICAgICAgICAgICAgICAgICBHTlUgTEVTU0VSIEdFTkVSQUwgUFVCTElDIExJQ0VOU0UKLSAgICAgICAgICAgICAgICAgICAgICAgVmVyc2lvbiAyLjEsIEZlYnJ1YXJ5IDE5OTkKLQotIENvcHlyaWdodCAoQykgMTk5MSwgMTk5OSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIEluYy4KLSA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0EKLSBFdmVyeW9uZSBpcyBwZXJtaXR0ZWQgdG8gY29weSBhbmQgZGlzdHJpYnV0ZSB2ZXJiYXRpbSBjb3BpZXMKLSBvZiB0aGlzIGxpY2Vuc2UgZG9jdW1lbnQsIGJ1dCBjaGFuZ2luZyBpdCBpcyBub3QgYWxsb3dlZC4KLQotW1RoaXMgaXMgdGhlIGZpcnN0IHJlbGVhc2VkIHZlcnNpb24gb2YgdGhlIExlc3NlciBHUEwuICBJdCBhbHNvIGNvdW50cwotIGFzIHRoZSBzdWNjZXNzb3Igb2YgdGhlIEdOVSBMaWJyYXJ5IFB1YmxpYyBMaWNlbnNlLCB2ZXJzaW9uIDIsIGhlbmNlCi0gdGhlIHZlcnNpb24gbnVtYmVyIDIuMS5dCi0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBQcmVhbWJsZQotCi0gIFRoZSBsaWNlbnNlcyBmb3IgbW9zdCBzb2Z0d2FyZSBhcmUgZGVzaWduZWQgdG8gdGFrZSBhd2F5IHlvdXIKLWZyZWVkb20gdG8gc2hhcmUgYW5kIGNoYW5nZSBpdC4gIEJ5IGNvbnRyYXN0LCB0aGUgR05VIEdlbmVyYWwgUHVibGljCi1MaWNlbnNlcyBhcmUgaW50ZW5kZWQgdG8gZ3VhcmFudGVlIHlvdXIgZnJlZWRvbSB0byBzaGFyZSBhbmQgY2hhbmdlCi1mcmVlIHNvZnR3YXJlLS10byBtYWtlIHN1cmUgdGhlIHNvZnR3YXJlIGlzIGZyZWUgZm9yIGFsbCBpdHMgdXNlcnMuCi0KLSAgVGhpcyBsaWNlbnNlLCB0aGUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsIGFwcGxpZXMgdG8gc29tZQotc3BlY2lhbGx5IGRlc2lnbmF0ZWQgc29mdHdhcmUgcGFja2FnZXMtLXR5cGljYWxseSBsaWJyYXJpZXMtLW9mIHRoZQotRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCBvdGhlciBhdXRob3JzIHdobyBkZWNpZGUgdG8gdXNlIGl0LiAgWW91Ci1jYW4gdXNlIGl0IHRvbywgYnV0IHdlIHN1Z2dlc3QgeW91IGZpcnN0IHRoaW5rIGNhcmVmdWxseSBhYm91dCB3aGV0aGVyCi10aGlzIGxpY2Vuc2Ugb3IgdGhlIG9yZGluYXJ5IEdlbmVyYWwgUHVibGljIExpY2Vuc2UgaXMgdGhlIGJldHRlcgotc3RyYXRlZ3kgdG8gdXNlIGluIGFueSBwYXJ0aWN1bGFyIGNhc2UsIGJhc2VkIG9uIHRoZSBleHBsYW5hdGlvbnMgYmVsb3cuCi0KLSAgV2hlbiB3ZSBzcGVhayBvZiBmcmVlIHNvZnR3YXJlLCB3ZSBhcmUgcmVmZXJyaW5nIHRvIGZyZWVkb20gb2YgdXNlLAotbm90IHByaWNlLiAgT3VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2VzIGFyZSBkZXNpZ25lZCB0byBtYWtlIHN1cmUgdGhhdAoteW91IGhhdmUgdGhlIGZyZWVkb20gdG8gZGlzdHJpYnV0ZSBjb3BpZXMgb2YgZnJlZSBzb2Z0d2FyZSAoYW5kIGNoYXJnZQotZm9yIHRoaXMgc2VydmljZSBpZiB5b3Ugd2lzaCk7IHRoYXQgeW91IHJlY2VpdmUgc291cmNlIGNvZGUgb3IgY2FuIGdldAotaXQgaWYgeW91IHdhbnQgaXQ7IHRoYXQgeW91IGNhbiBjaGFuZ2UgdGhlIHNvZnR3YXJlIGFuZCB1c2UgcGllY2VzIG9mCi1pdCBpbiBuZXcgZnJlZSBwcm9ncmFtczsgYW5kIHRoYXQgeW91IGFyZSBpbmZvcm1lZCB0aGF0IHlvdSBjYW4gZG8KLXRoZXNlIHRoaW5ncy4KLQotICBUbyBwcm90ZWN0IHlvdXIgcmlnaHRzLCB3ZSBuZWVkIHRvIG1ha2UgcmVzdHJpY3Rpb25zIHRoYXQgZm9yYmlkCi1kaXN0cmlidXRvcnMgdG8gZGVueSB5b3UgdGhlc2UgcmlnaHRzIG9yIHRvIGFzayB5b3UgdG8gc3VycmVuZGVyIHRoZXNlCi1yaWdodHMuICBUaGVzZSByZXN0cmljdGlvbnMgdHJhbnNsYXRlIHRvIGNlcnRhaW4gcmVzcG9uc2liaWxpdGllcyBmb3IKLXlvdSBpZiB5b3UgZGlzdHJpYnV0ZSBjb3BpZXMgb2YgdGhlIGxpYnJhcnkgb3IgaWYgeW91IG1vZGlmeSBpdC4KLQotICBGb3IgZXhhbXBsZSwgaWYgeW91IGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoZSBsaWJyYXJ5LCB3aGV0aGVyIGdyYXRpcwotb3IgZm9yIGEgZmVlLCB5b3UgbXVzdCBnaXZlIHRoZSByZWNpcGllbnRzIGFsbCB0aGUgcmlnaHRzIHRoYXQgd2UgZ2F2ZQoteW91LiAgWW91IG11c3QgbWFrZSBzdXJlIHRoYXQgdGhleSwgdG9vLCByZWNlaXZlIG9yIGNhbiBnZXQgdGhlIHNvdXJjZQotY29kZS4gIElmIHlvdSBsaW5rIG90aGVyIGNvZGUgd2l0aCB0aGUgbGlicmFyeSwgeW91IG11c3QgcHJvdmlkZQotY29tcGxldGUgb2JqZWN0IGZpbGVzIHRvIHRoZSByZWNpcGllbnRzLCBzbyB0aGF0IHRoZXkgY2FuIHJlbGluayB0aGVtCi13aXRoIHRoZSBsaWJyYXJ5IGFmdGVyIG1ha2luZyBjaGFuZ2VzIHRvIHRoZSBsaWJyYXJ5IGFuZCByZWNvbXBpbGluZwotaXQuICBBbmQgeW91IG11c3Qgc2hvdyB0aGVtIHRoZXNlIHRlcm1zIHNvIHRoZXkga25vdyB0aGVpciByaWdodHMuCi0KLSAgV2UgcHJvdGVjdCB5b3VyIHJpZ2h0cyB3aXRoIGEgdHdvLXN0ZXAgbWV0aG9kOiAoMSkgd2UgY29weXJpZ2h0IHRoZQotbGlicmFyeSwgYW5kICgyKSB3ZSBvZmZlciB5b3UgdGhpcyBsaWNlbnNlLCB3aGljaCBnaXZlcyB5b3UgbGVnYWwKLXBlcm1pc3Npb24gdG8gY29weSwgZGlzdHJpYnV0ZSBhbmQvb3IgbW9kaWZ5IHRoZSBsaWJyYXJ5LgotCi0gIFRvIHByb3RlY3QgZWFjaCBkaXN0cmlidXRvciwgd2Ugd2FudCB0byBtYWtlIGl0IHZlcnkgY2xlYXIgdGhhdAotdGhlcmUgaXMgbm8gd2FycmFudHkgZm9yIHRoZSBmcmVlIGxpYnJhcnkuICBBbHNvLCBpZiB0aGUgbGlicmFyeSBpcwotbW9kaWZpZWQgYnkgc29tZW9uZSBlbHNlIGFuZCBwYXNzZWQgb24sIHRoZSByZWNpcGllbnRzIHNob3VsZCBrbm93Ci10aGF0IHdoYXQgdGhleSBoYXZlIGlzIG5vdCB0aGUgb3JpZ2luYWwgdmVyc2lvbiwgc28gdGhhdCB0aGUgb3JpZ2luYWwKLWF1dGhvcidzIHJlcHV0YXRpb24gd2lsbCBub3QgYmUgYWZmZWN0ZWQgYnkgcHJvYmxlbXMgdGhhdCBtaWdodCBiZQotaW50cm9kdWNlZCBieSBvdGhlcnMuCi0MCi0gIEZpbmFsbHksIHNvZnR3YXJlIHBhdGVudHMgcG9zZSBhIGNvbnN0YW50IHRocmVhdCB0byB0aGUgZXhpc3RlbmNlIG9mCi1hbnkgZnJlZSBwcm9ncmFtLiAgV2Ugd2lzaCB0byBtYWtlIHN1cmUgdGhhdCBhIGNvbXBhbnkgY2Fubm90Ci1lZmZlY3RpdmVseSByZXN0cmljdCB0aGUgdXNlcnMgb2YgYSBmcmVlIHByb2dyYW0gYnkgb2J0YWluaW5nIGEKLXJlc3RyaWN0aXZlIGxpY2Vuc2UgZnJvbSBhIHBhdGVudCBob2xkZXIuICBUaGVyZWZvcmUsIHdlIGluc2lzdCB0aGF0Ci1hbnkgcGF0ZW50IGxpY2Vuc2Ugb2J0YWluZWQgZm9yIGEgdmVyc2lvbiBvZiB0aGUgbGlicmFyeSBtdXN0IGJlCi1jb25zaXN0ZW50IHdpdGggdGhlIGZ1bGwgZnJlZWRvbSBvZiB1c2Ugc3BlY2lmaWVkIGluIHRoaXMgbGljZW5zZS4KLQotICBNb3N0IEdOVSBzb2Z0d2FyZSwgaW5jbHVkaW5nIHNvbWUgbGlicmFyaWVzLCBpcyBjb3ZlcmVkIGJ5IHRoZQotb3JkaW5hcnkgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UuICBUaGlzIGxpY2Vuc2UsIHRoZSBHTlUgTGVzc2VyCi1HZW5lcmFsIFB1YmxpYyBMaWNlbnNlLCBhcHBsaWVzIHRvIGNlcnRhaW4gZGVzaWduYXRlZCBsaWJyYXJpZXMsIGFuZAotaXMgcXVpdGUgZGlmZmVyZW50IGZyb20gdGhlIG9yZGluYXJ5IEdlbmVyYWwgUHVibGljIExpY2Vuc2UuICBXZSB1c2UKLXRoaXMgbGljZW5zZSBmb3IgY2VydGFpbiBsaWJyYXJpZXMgaW4gb3JkZXIgdG8gcGVybWl0IGxpbmtpbmcgdGhvc2UKLWxpYnJhcmllcyBpbnRvIG5vbi1mcmVlIHByb2dyYW1zLgotCi0gIFdoZW4gYSBwcm9ncmFtIGlzIGxpbmtlZCB3aXRoIGEgbGlicmFyeSwgd2hldGhlciBzdGF0aWNhbGx5IG9yIHVzaW5nCi1hIHNoYXJlZCBsaWJyYXJ5LCB0aGUgY29tYmluYXRpb24gb2YgdGhlIHR3byBpcyBsZWdhbGx5IHNwZWFraW5nIGEKLWNvbWJpbmVkIHdvcmssIGEgZGVyaXZhdGl2ZSBvZiB0aGUgb3JpZ2luYWwgbGlicmFyeS4gIFRoZSBvcmRpbmFyeQotR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB0aGVyZWZvcmUgcGVybWl0cyBzdWNoIGxpbmtpbmcgb25seSBpZiB0aGUKLWVudGlyZSBjb21iaW5hdGlvbiBmaXRzIGl0cyBjcml0ZXJpYSBvZiBmcmVlZG9tLiAgVGhlIExlc3NlciBHZW5lcmFsCi1QdWJsaWMgTGljZW5zZSBwZXJtaXRzIG1vcmUgbGF4IGNyaXRlcmlhIGZvciBsaW5raW5nIG90aGVyIGNvZGUgd2l0aAotdGhlIGxpYnJhcnkuCi0KLSAgV2UgY2FsbCB0aGlzIGxpY2Vuc2UgdGhlICJMZXNzZXIiIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYmVjYXVzZSBpdAotZG9lcyBMZXNzIHRvIHByb3RlY3QgdGhlIHVzZXIncyBmcmVlZG9tIHRoYW4gdGhlIG9yZGluYXJ5IEdlbmVyYWwKLVB1YmxpYyBMaWNlbnNlLiAgSXQgYWxzbyBwcm92aWRlcyBvdGhlciBmcmVlIHNvZnR3YXJlIGRldmVsb3BlcnMgTGVzcwotb2YgYW4gYWR2YW50YWdlIG92ZXIgY29tcGV0aW5nIG5vbi1mcmVlIHByb2dyYW1zLiAgVGhlc2UgZGlzYWR2YW50YWdlcwotYXJlIHRoZSByZWFzb24gd2UgdXNlIHRoZSBvcmRpbmFyeSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtYW55Ci1saWJyYXJpZXMuICBIb3dldmVyLCB0aGUgTGVzc2VyIGxpY2Vuc2UgcHJvdmlkZXMgYWR2YW50YWdlcyBpbiBjZXJ0YWluCi1zcGVjaWFsIGNpcmN1bXN0YW5jZXMuCi0KLSAgRm9yIGV4YW1wbGUsIG9uIHJhcmUgb2NjYXNpb25zLCB0aGVyZSBtYXkgYmUgYSBzcGVjaWFsIG5lZWQgdG8KLWVuY291cmFnZSB0aGUgd2lkZXN0IHBvc3NpYmxlIHVzZSBvZiBhIGNlcnRhaW4gbGlicmFyeSwgc28gdGhhdCBpdCBiZWNvbWVzCi1hIGRlLWZhY3RvIHN0YW5kYXJkLiAgVG8gYWNoaWV2ZSB0aGlzLCBub24tZnJlZSBwcm9ncmFtcyBtdXN0IGJlCi1hbGxvd2VkIHRvIHVzZSB0aGUgbGlicmFyeS4gIEEgbW9yZSBmcmVxdWVudCBjYXNlIGlzIHRoYXQgYSBmcmVlCi1saWJyYXJ5IGRvZXMgdGhlIHNhbWUgam9iIGFzIHdpZGVseSB1c2VkIG5vbi1mcmVlIGxpYnJhcmllcy4gIEluIHRoaXMKLWNhc2UsIHRoZXJlIGlzIGxpdHRsZSB0byBnYWluIGJ5IGxpbWl0aW5nIHRoZSBmcmVlIGxpYnJhcnkgdG8gZnJlZQotc29mdHdhcmUgb25seSwgc28gd2UgdXNlIHRoZSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZS4KLQotICBJbiBvdGhlciBjYXNlcywgcGVybWlzc2lvbiB0byB1c2UgYSBwYXJ0aWN1bGFyIGxpYnJhcnkgaW4gbm9uLWZyZWUKLXByb2dyYW1zIGVuYWJsZXMgYSBncmVhdGVyIG51bWJlciBvZiBwZW9wbGUgdG8gdXNlIGEgbGFyZ2UgYm9keSBvZgotZnJlZSBzb2Z0d2FyZS4gIEZvciBleGFtcGxlLCBwZXJtaXNzaW9uIHRvIHVzZSB0aGUgR05VIEMgTGlicmFyeSBpbgotbm9uLWZyZWUgcHJvZ3JhbXMgZW5hYmxlcyBtYW55IG1vcmUgcGVvcGxlIHRvIHVzZSB0aGUgd2hvbGUgR05VCi1vcGVyYXRpbmcgc3lzdGVtLCBhcyB3ZWxsIGFzIGl0cyB2YXJpYW50LCB0aGUgR05VL0xpbnV4IG9wZXJhdGluZwotc3lzdGVtLgotCi0gIEFsdGhvdWdoIHRoZSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBpcyBMZXNzIHByb3RlY3RpdmUgb2YgdGhlCi11c2VycycgZnJlZWRvbSwgaXQgZG9lcyBlbnN1cmUgdGhhdCB0aGUgdXNlciBvZiBhIHByb2dyYW0gdGhhdCBpcwotbGlua2VkIHdpdGggdGhlIExpYnJhcnkgaGFzIHRoZSBmcmVlZG9tIGFuZCB0aGUgd2hlcmV3aXRoYWwgdG8gcnVuCi10aGF0IHByb2dyYW0gdXNpbmcgYSBtb2RpZmllZCB2ZXJzaW9uIG9mIHRoZSBMaWJyYXJ5LgotCi0gIFRoZSBwcmVjaXNlIHRlcm1zIGFuZCBjb25kaXRpb25zIGZvciBjb3B5aW5nLCBkaXN0cmlidXRpb24gYW5kCi1tb2RpZmljYXRpb24gZm9sbG93LiAgUGF5IGNsb3NlIGF0dGVudGlvbiB0byB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIGEKLSJ3b3JrIGJhc2VkIG9uIHRoZSBsaWJyYXJ5IiBhbmQgYSAid29yayB0aGF0IHVzZXMgdGhlIGxpYnJhcnkiLiAgVGhlCi1mb3JtZXIgY29udGFpbnMgY29kZSBkZXJpdmVkIGZyb20gdGhlIGxpYnJhcnksIHdoZXJlYXMgdGhlIGxhdHRlciBtdXN0Ci1iZSBjb21iaW5lZCB3aXRoIHRoZSBsaWJyYXJ5IGluIG9yZGVyIHRvIHJ1bi4KLQwKLSAgICAgICAgICAgICAgICAgIEdOVSBMRVNTRVIgR0VORVJBTCBQVUJMSUMgTElDRU5TRQotICAgVEVSTVMgQU5EIENPTkRJVElPTlMgRk9SIENPUFlJTkcsIERJU1RSSUJVVElPTiBBTkQgTU9ESUZJQ0FUSU9OCi0KLSAgMC4gVGhpcyBMaWNlbnNlIEFncmVlbWVudCBhcHBsaWVzIHRvIGFueSBzb2Z0d2FyZSBsaWJyYXJ5IG9yIG90aGVyCi1wcm9ncmFtIHdoaWNoIGNvbnRhaW5zIGEgbm90aWNlIHBsYWNlZCBieSB0aGUgY29weXJpZ2h0IGhvbGRlciBvcgotb3RoZXIgYXV0aG9yaXplZCBwYXJ0eSBzYXlpbmcgaXQgbWF5IGJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSB0ZXJtcyBvZgotdGhpcyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSAoYWxzbyBjYWxsZWQgInRoaXMgTGljZW5zZSIpLgotRWFjaCBsaWNlbnNlZSBpcyBhZGRyZXNzZWQgYXMgInlvdSIuCi0KLSAgQSAibGlicmFyeSIgbWVhbnMgYSBjb2xsZWN0aW9uIG9mIHNvZnR3YXJlIGZ1bmN0aW9ucyBhbmQvb3IgZGF0YQotcHJlcGFyZWQgc28gYXMgdG8gYmUgY29udmVuaWVudGx5IGxpbmtlZCB3aXRoIGFwcGxpY2F0aW9uIHByb2dyYW1zCi0od2hpY2ggdXNlIHNvbWUgb2YgdGhvc2UgZnVuY3Rpb25zIGFuZCBkYXRhKSB0byBmb3JtIGV4ZWN1dGFibGVzLgotCi0gIFRoZSAiTGlicmFyeSIsIGJlbG93LCByZWZlcnMgdG8gYW55IHN1Y2ggc29mdHdhcmUgbGlicmFyeSBvciB3b3JrCi13aGljaCBoYXMgYmVlbiBkaXN0cmlidXRlZCB1bmRlciB0aGVzZSB0ZXJtcy4gIEEgIndvcmsgYmFzZWQgb24gdGhlCi1MaWJyYXJ5IiBtZWFucyBlaXRoZXIgdGhlIExpYnJhcnkgb3IgYW55IGRlcml2YXRpdmUgd29yayB1bmRlcgotY29weXJpZ2h0IGxhdzogdGhhdCBpcyB0byBzYXksIGEgd29yayBjb250YWluaW5nIHRoZSBMaWJyYXJ5IG9yIGEKLXBvcnRpb24gb2YgaXQsIGVpdGhlciB2ZXJiYXRpbSBvciB3aXRoIG1vZGlmaWNhdGlvbnMgYW5kL29yIHRyYW5zbGF0ZWQKLXN0cmFpZ2h0Zm9yd2FyZGx5IGludG8gYW5vdGhlciBsYW5ndWFnZS4gIChIZXJlaW5hZnRlciwgdHJhbnNsYXRpb24gaXMKLWluY2x1ZGVkIHdpdGhvdXQgbGltaXRhdGlvbiBpbiB0aGUgdGVybSAibW9kaWZpY2F0aW9uIi4pCi0KLSAgIlNvdXJjZSBjb2RlIiBmb3IgYSB3b3JrIG1lYW5zIHRoZSBwcmVmZXJyZWQgZm9ybSBvZiB0aGUgd29yayBmb3IKLW1ha2luZyBtb2RpZmljYXRpb25zIHRvIGl0LiAgRm9yIGEgbGlicmFyeSwgY29tcGxldGUgc291cmNlIGNvZGUgbWVhbnMKLWFsbCB0aGUgc291cmNlIGNvZGUgZm9yIGFsbCBtb2R1bGVzIGl0IGNvbnRhaW5zLCBwbHVzIGFueSBhc3NvY2lhdGVkCi1pbnRlcmZhY2UgZGVmaW5pdGlvbiBmaWxlcywgcGx1cyB0aGUgc2NyaXB0cyB1c2VkIHRvIGNvbnRyb2wgY29tcGlsYXRpb24KLWFuZCBpbnN0YWxsYXRpb24gb2YgdGhlIGxpYnJhcnkuCi0KLSAgQWN0aXZpdGllcyBvdGhlciB0aGFuIGNvcHlpbmcsIGRpc3RyaWJ1dGlvbiBhbmQgbW9kaWZpY2F0aW9uIGFyZSBub3QKLWNvdmVyZWQgYnkgdGhpcyBMaWNlbnNlOyB0aGV5IGFyZSBvdXRzaWRlIGl0cyBzY29wZS4gIFRoZSBhY3Qgb2YKLXJ1bm5pbmcgYSBwcm9ncmFtIHVzaW5nIHRoZSBMaWJyYXJ5IGlzIG5vdCByZXN0cmljdGVkLCBhbmQgb3V0cHV0IGZyb20KLXN1Y2ggYSBwcm9ncmFtIGlzIGNvdmVyZWQgb25seSBpZiBpdHMgY29udGVudHMgY29uc3RpdHV0ZSBhIHdvcmsgYmFzZWQKLW9uIHRoZSBMaWJyYXJ5IChpbmRlcGVuZGVudCBvZiB0aGUgdXNlIG9mIHRoZSBMaWJyYXJ5IGluIGEgdG9vbCBmb3IKLXdyaXRpbmcgaXQpLiAgV2hldGhlciB0aGF0IGlzIHRydWUgZGVwZW5kcyBvbiB3aGF0IHRoZSBMaWJyYXJ5IGRvZXMKLWFuZCB3aGF0IHRoZSBwcm9ncmFtIHRoYXQgdXNlcyB0aGUgTGlicmFyeSBkb2VzLgotCi0gIDEuIFlvdSBtYXkgY29weSBhbmQgZGlzdHJpYnV0ZSB2ZXJiYXRpbSBjb3BpZXMgb2YgdGhlIExpYnJhcnkncwotY29tcGxldGUgc291cmNlIGNvZGUgYXMgeW91IHJlY2VpdmUgaXQsIGluIGFueSBtZWRpdW0sIHByb3ZpZGVkIHRoYXQKLXlvdSBjb25zcGljdW91c2x5IGFuZCBhcHByb3ByaWF0ZWx5IHB1Ymxpc2ggb24gZWFjaCBjb3B5IGFuCi1hcHByb3ByaWF0ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCBkaXNjbGFpbWVyIG9mIHdhcnJhbnR5OyBrZWVwIGludGFjdAotYWxsIHRoZSBub3RpY2VzIHRoYXQgcmVmZXIgdG8gdGhpcyBMaWNlbnNlIGFuZCB0byB0aGUgYWJzZW5jZSBvZiBhbnkKLXdhcnJhbnR5OyBhbmQgZGlzdHJpYnV0ZSBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlIGFsb25nIHdpdGggdGhlCi1MaWJyYXJ5LgotCi0gIFlvdSBtYXkgY2hhcmdlIGEgZmVlIGZvciB0aGUgcGh5c2ljYWwgYWN0IG9mIHRyYW5zZmVycmluZyBhIGNvcHksCi1hbmQgeW91IG1heSBhdCB5b3VyIG9wdGlvbiBvZmZlciB3YXJyYW50eSBwcm90ZWN0aW9uIGluIGV4Y2hhbmdlIGZvciBhCi1mZWUuCi0MCi0gIDIuIFlvdSBtYXkgbW9kaWZ5IHlvdXIgY29weSBvciBjb3BpZXMgb2YgdGhlIExpYnJhcnkgb3IgYW55IHBvcnRpb24KLW9mIGl0LCB0aHVzIGZvcm1pbmcgYSB3b3JrIGJhc2VkIG9uIHRoZSBMaWJyYXJ5LCBhbmQgY29weSBhbmQKLWRpc3RyaWJ1dGUgc3VjaCBtb2RpZmljYXRpb25zIG9yIHdvcmsgdW5kZXIgdGhlIHRlcm1zIG9mIFNlY3Rpb24gMQotYWJvdmUsIHByb3ZpZGVkIHRoYXQgeW91IGFsc28gbWVldCBhbGwgb2YgdGhlc2UgY29uZGl0aW9uczoKLQotICAgIGEpIFRoZSBtb2RpZmllZCB3b3JrIG11c3QgaXRzZWxmIGJlIGEgc29mdHdhcmUgbGlicmFyeS4KLQotICAgIGIpIFlvdSBtdXN0IGNhdXNlIHRoZSBmaWxlcyBtb2RpZmllZCB0byBjYXJyeSBwcm9taW5lbnQgbm90aWNlcwotICAgIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgZmlsZXMgYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuCi0KLSAgICBjKSBZb3UgbXVzdCBjYXVzZSB0aGUgd2hvbGUgb2YgdGhlIHdvcmsgdG8gYmUgbGljZW5zZWQgYXQgbm8KLSAgICBjaGFyZ2UgdG8gYWxsIHRoaXJkIHBhcnRpZXMgdW5kZXIgdGhlIHRlcm1zIG9mIHRoaXMgTGljZW5zZS4KLQotICAgIGQpIElmIGEgZmFjaWxpdHkgaW4gdGhlIG1vZGlmaWVkIExpYnJhcnkgcmVmZXJzIHRvIGEgZnVuY3Rpb24gb3IgYQotICAgIHRhYmxlIG9mIGRhdGEgdG8gYmUgc3VwcGxpZWQgYnkgYW4gYXBwbGljYXRpb24gcHJvZ3JhbSB0aGF0IHVzZXMKLSAgICB0aGUgZmFjaWxpdHksIG90aGVyIHRoYW4gYXMgYW4gYXJndW1lbnQgcGFzc2VkIHdoZW4gdGhlIGZhY2lsaXR5Ci0gICAgaXMgaW52b2tlZCwgdGhlbiB5b3UgbXVzdCBtYWtlIGEgZ29vZCBmYWl0aCBlZmZvcnQgdG8gZW5zdXJlIHRoYXQsCi0gICAgaW4gdGhlIGV2ZW50IGFuIGFwcGxpY2F0aW9uIGRvZXMgbm90IHN1cHBseSBzdWNoIGZ1bmN0aW9uIG9yCi0gICAgdGFibGUsIHRoZSBmYWNpbGl0eSBzdGlsbCBvcGVyYXRlcywgYW5kIHBlcmZvcm1zIHdoYXRldmVyIHBhcnQgb2YKLSAgICBpdHMgcHVycG9zZSByZW1haW5zIG1lYW5pbmdmdWwuCi0KLSAgICAoRm9yIGV4YW1wbGUsIGEgZnVuY3Rpb24gaW4gYSBsaWJyYXJ5IHRvIGNvbXB1dGUgc3F1YXJlIHJvb3RzIGhhcwotICAgIGEgcHVycG9zZSB0aGF0IGlzIGVudGlyZWx5IHdlbGwtZGVmaW5lZCBpbmRlcGVuZGVudCBvZiB0aGUKLSAgICBhcHBsaWNhdGlvbi4gIFRoZXJlZm9yZSwgU3Vic2VjdGlvbiAyZCByZXF1aXJlcyB0aGF0IGFueQotICAgIGFwcGxpY2F0aW9uLXN1cHBsaWVkIGZ1bmN0aW9uIG9yIHRhYmxlIHVzZWQgYnkgdGhpcyBmdW5jdGlvbiBtdXN0Ci0gICAgYmUgb3B0aW9uYWw6IGlmIHRoZSBhcHBsaWNhdGlvbiBkb2VzIG5vdCBzdXBwbHkgaXQsIHRoZSBzcXVhcmUKLSAgICByb290IGZ1bmN0aW9uIG11c3Qgc3RpbGwgY29tcHV0ZSBzcXVhcmUgcm9vdHMuKQotCi1UaGVzZSByZXF1aXJlbWVudHMgYXBwbHkgdG8gdGhlIG1vZGlmaWVkIHdvcmsgYXMgYSB3aG9sZS4gIElmCi1pZGVudGlmaWFibGUgc2VjdGlvbnMgb2YgdGhhdCB3b3JrIGFyZSBub3QgZGVyaXZlZCBmcm9tIHRoZSBMaWJyYXJ5LAotYW5kIGNhbiBiZSByZWFzb25hYmx5IGNvbnNpZGVyZWQgaW5kZXBlbmRlbnQgYW5kIHNlcGFyYXRlIHdvcmtzIGluCi10aGVtc2VsdmVzLCB0aGVuIHRoaXMgTGljZW5zZSwgYW5kIGl0cyB0ZXJtcywgZG8gbm90IGFwcGx5IHRvIHRob3NlCi1zZWN0aW9ucyB3aGVuIHlvdSBkaXN0cmlidXRlIHRoZW0gYXMgc2VwYXJhdGUgd29ya3MuICBCdXQgd2hlbiB5b3UKLWRpc3RyaWJ1dGUgdGhlIHNhbWUgc2VjdGlvbnMgYXMgcGFydCBvZiBhIHdob2xlIHdoaWNoIGlzIGEgd29yayBiYXNlZAotb24gdGhlIExpYnJhcnksIHRoZSBkaXN0cmlidXRpb24gb2YgdGhlIHdob2xlIG11c3QgYmUgb24gdGhlIHRlcm1zIG9mCi10aGlzIExpY2Vuc2UsIHdob3NlIHBlcm1pc3Npb25zIGZvciBvdGhlciBsaWNlbnNlZXMgZXh0ZW5kIHRvIHRoZQotZW50aXJlIHdob2xlLCBhbmQgdGh1cyB0byBlYWNoIGFuZCBldmVyeSBwYXJ0IHJlZ2FyZGxlc3Mgb2Ygd2hvIHdyb3RlCi1pdC4KLQotVGh1cywgaXQgaXMgbm90IHRoZSBpbnRlbnQgb2YgdGhpcyBzZWN0aW9uIHRvIGNsYWltIHJpZ2h0cyBvciBjb250ZXN0Ci15b3VyIHJpZ2h0cyB0byB3b3JrIHdyaXR0ZW4gZW50aXJlbHkgYnkgeW91OyByYXRoZXIsIHRoZSBpbnRlbnQgaXMgdG8KLWV4ZXJjaXNlIHRoZSByaWdodCB0byBjb250cm9sIHRoZSBkaXN0cmlidXRpb24gb2YgZGVyaXZhdGl2ZSBvcgotY29sbGVjdGl2ZSB3b3JrcyBiYXNlZCBvbiB0aGUgTGlicmFyeS4KLQotSW4gYWRkaXRpb24sIG1lcmUgYWdncmVnYXRpb24gb2YgYW5vdGhlciB3b3JrIG5vdCBiYXNlZCBvbiB0aGUgTGlicmFyeQotd2l0aCB0aGUgTGlicmFyeSAob3Igd2l0aCBhIHdvcmsgYmFzZWQgb24gdGhlIExpYnJhcnkpIG9uIGEgdm9sdW1lIG9mCi1hIHN0b3JhZ2Ugb3IgZGlzdHJpYnV0aW9uIG1lZGl1bSBkb2VzIG5vdCBicmluZyB0aGUgb3RoZXIgd29yayB1bmRlcgotdGhlIHNjb3BlIG9mIHRoaXMgTGljZW5zZS4KLQotICAzLiBZb3UgbWF5IG9wdCB0byBhcHBseSB0aGUgdGVybXMgb2YgdGhlIG9yZGluYXJ5IEdOVSBHZW5lcmFsIFB1YmxpYwotTGljZW5zZSBpbnN0ZWFkIG9mIHRoaXMgTGljZW5zZSB0byBhIGdpdmVuIGNvcHkgb2YgdGhlIExpYnJhcnkuICBUbyBkbwotdGhpcywgeW91IG11c3QgYWx0ZXIgYWxsIHRoZSBub3RpY2VzIHRoYXQgcmVmZXIgdG8gdGhpcyBMaWNlbnNlLCBzbwotdGhhdCB0aGV5IHJlZmVyIHRvIHRoZSBvcmRpbmFyeSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwgdmVyc2lvbiAyLAotaW5zdGVhZCBvZiB0byB0aGlzIExpY2Vuc2UuICAoSWYgYSBuZXdlciB2ZXJzaW9uIHRoYW4gdmVyc2lvbiAyIG9mIHRoZQotb3JkaW5hcnkgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgaGFzIGFwcGVhcmVkLCB0aGVuIHlvdSBjYW4gc3BlY2lmeQotdGhhdCB2ZXJzaW9uIGluc3RlYWQgaWYgeW91IHdpc2guKSAgRG8gbm90IG1ha2UgYW55IG90aGVyIGNoYW5nZSBpbgotdGhlc2Ugbm90aWNlcy4KLQwKLSAgT25jZSB0aGlzIGNoYW5nZSBpcyBtYWRlIGluIGEgZ2l2ZW4gY29weSwgaXQgaXMgaXJyZXZlcnNpYmxlIGZvcgotdGhhdCBjb3B5LCBzbyB0aGUgb3JkaW5hcnkgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXBwbGllcyB0byBhbGwKLXN1YnNlcXVlbnQgY29waWVzIGFuZCBkZXJpdmF0aXZlIHdvcmtzIG1hZGUgZnJvbSB0aGF0IGNvcHkuCi0KLSAgVGhpcyBvcHRpb24gaXMgdXNlZnVsIHdoZW4geW91IHdpc2ggdG8gY29weSBwYXJ0IG9mIHRoZSBjb2RlIG9mCi10aGUgTGlicmFyeSBpbnRvIGEgcHJvZ3JhbSB0aGF0IGlzIG5vdCBhIGxpYnJhcnkuCi0KLSAgNC4gWW91IG1heSBjb3B5IGFuZCBkaXN0cmlidXRlIHRoZSBMaWJyYXJ5IChvciBhIHBvcnRpb24gb3IKLWRlcml2YXRpdmUgb2YgaXQsIHVuZGVyIFNlY3Rpb24gMikgaW4gb2JqZWN0IGNvZGUgb3IgZXhlY3V0YWJsZSBmb3JtCi11bmRlciB0aGUgdGVybXMgb2YgU2VjdGlvbnMgMSBhbmQgMiBhYm92ZSBwcm92aWRlZCB0aGF0IHlvdSBhY2NvbXBhbnkKLWl0IHdpdGggdGhlIGNvbXBsZXRlIGNvcnJlc3BvbmRpbmcgbWFjaGluZS1yZWFkYWJsZSBzb3VyY2UgY29kZSwgd2hpY2gKLW11c3QgYmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIHRlcm1zIG9mIFNlY3Rpb25zIDEgYW5kIDIgYWJvdmUgb24gYQotbWVkaXVtIGN1c3RvbWFyaWx5IHVzZWQgZm9yIHNvZnR3YXJlIGludGVyY2hhbmdlLgotCi0gIElmIGRpc3RyaWJ1dGlvbiBvZiBvYmplY3QgY29kZSBpcyBtYWRlIGJ5IG9mZmVyaW5nIGFjY2VzcyB0byBjb3B5Ci1mcm9tIGEgZGVzaWduYXRlZCBwbGFjZSwgdGhlbiBvZmZlcmluZyBlcXVpdmFsZW50IGFjY2VzcyB0byBjb3B5IHRoZQotc291cmNlIGNvZGUgZnJvbSB0aGUgc2FtZSBwbGFjZSBzYXRpc2ZpZXMgdGhlIHJlcXVpcmVtZW50IHRvCi1kaXN0cmlidXRlIHRoZSBzb3VyY2UgY29kZSwgZXZlbiB0aG91Z2ggdGhpcmQgcGFydGllcyBhcmUgbm90Ci1jb21wZWxsZWQgdG8gY29weSB0aGUgc291cmNlIGFsb25nIHdpdGggdGhlIG9iamVjdCBjb2RlLgotCi0gIDUuIEEgcHJvZ3JhbSB0aGF0IGNvbnRhaW5zIG5vIGRlcml2YXRpdmUgb2YgYW55IHBvcnRpb24gb2YgdGhlCi1MaWJyYXJ5LCBidXQgaXMgZGVzaWduZWQgdG8gd29yayB3aXRoIHRoZSBMaWJyYXJ5IGJ5IGJlaW5nIGNvbXBpbGVkIG9yCi1saW5rZWQgd2l0aCBpdCwgaXMgY2FsbGVkIGEgIndvcmsgdGhhdCB1c2VzIHRoZSBMaWJyYXJ5Ii4gIFN1Y2ggYQotd29yaywgaW4gaXNvbGF0aW9uLCBpcyBub3QgYSBkZXJpdmF0aXZlIHdvcmsgb2YgdGhlIExpYnJhcnksIGFuZAotdGhlcmVmb3JlIGZhbGxzIG91dHNpZGUgdGhlIHNjb3BlIG9mIHRoaXMgTGljZW5zZS4KLQotICBIb3dldmVyLCBsaW5raW5nIGEgIndvcmsgdGhhdCB1c2VzIHRoZSBMaWJyYXJ5IiB3aXRoIHRoZSBMaWJyYXJ5Ci1jcmVhdGVzIGFuIGV4ZWN1dGFibGUgdGhhdCBpcyBhIGRlcml2YXRpdmUgb2YgdGhlIExpYnJhcnkgKGJlY2F1c2UgaXQKLWNvbnRhaW5zIHBvcnRpb25zIG9mIHRoZSBMaWJyYXJ5KSwgcmF0aGVyIHRoYW4gYSAid29yayB0aGF0IHVzZXMgdGhlCi1saWJyYXJ5Ii4gIFRoZSBleGVjdXRhYmxlIGlzIHRoZXJlZm9yZSBjb3ZlcmVkIGJ5IHRoaXMgTGljZW5zZS4KLVNlY3Rpb24gNiBzdGF0ZXMgdGVybXMgZm9yIGRpc3RyaWJ1dGlvbiBvZiBzdWNoIGV4ZWN1dGFibGVzLgotCi0gIFdoZW4gYSAid29yayB0aGF0IHVzZXMgdGhlIExpYnJhcnkiIHVzZXMgbWF0ZXJpYWwgZnJvbSBhIGhlYWRlciBmaWxlCi10aGF0IGlzIHBhcnQgb2YgdGhlIExpYnJhcnksIHRoZSBvYmplY3QgY29kZSBmb3IgdGhlIHdvcmsgbWF5IGJlIGEKLWRlcml2YXRpdmUgd29yayBvZiB0aGUgTGlicmFyeSBldmVuIHRob3VnaCB0aGUgc291cmNlIGNvZGUgaXMgbm90LgotV2hldGhlciB0aGlzIGlzIHRydWUgaXMgZXNwZWNpYWxseSBzaWduaWZpY2FudCBpZiB0aGUgd29yayBjYW4gYmUKLWxpbmtlZCB3aXRob3V0IHRoZSBMaWJyYXJ5LCBvciBpZiB0aGUgd29yayBpcyBpdHNlbGYgYSBsaWJyYXJ5LiAgVGhlCi10aHJlc2hvbGQgZm9yIHRoaXMgdG8gYmUgdHJ1ZSBpcyBub3QgcHJlY2lzZWx5IGRlZmluZWQgYnkgbGF3LgotCi0gIElmIHN1Y2ggYW4gb2JqZWN0IGZpbGUgdXNlcyBvbmx5IG51bWVyaWNhbCBwYXJhbWV0ZXJzLCBkYXRhCi1zdHJ1Y3R1cmUgbGF5b3V0cyBhbmQgYWNjZXNzb3JzLCBhbmQgc21hbGwgbWFjcm9zIGFuZCBzbWFsbCBpbmxpbmUKLWZ1bmN0aW9ucyAodGVuIGxpbmVzIG9yIGxlc3MgaW4gbGVuZ3RoKSwgdGhlbiB0aGUgdXNlIG9mIHRoZSBvYmplY3QKLWZpbGUgaXMgdW5yZXN0cmljdGVkLCByZWdhcmRsZXNzIG9mIHdoZXRoZXIgaXQgaXMgbGVnYWxseSBhIGRlcml2YXRpdmUKLXdvcmsuICAoRXhlY3V0YWJsZXMgY29udGFpbmluZyB0aGlzIG9iamVjdCBjb2RlIHBsdXMgcG9ydGlvbnMgb2YgdGhlCi1MaWJyYXJ5IHdpbGwgc3RpbGwgZmFsbCB1bmRlciBTZWN0aW9uIDYuKQotCi0gIE90aGVyd2lzZSwgaWYgdGhlIHdvcmsgaXMgYSBkZXJpdmF0aXZlIG9mIHRoZSBMaWJyYXJ5LCB5b3UgbWF5Ci1kaXN0cmlidXRlIHRoZSBvYmplY3QgY29kZSBmb3IgdGhlIHdvcmsgdW5kZXIgdGhlIHRlcm1zIG9mIFNlY3Rpb24gNi4KLUFueSBleGVjdXRhYmxlcyBjb250YWluaW5nIHRoYXQgd29yayBhbHNvIGZhbGwgdW5kZXIgU2VjdGlvbiA2LAotd2hldGhlciBvciBub3QgdGhleSBhcmUgbGlua2VkIGRpcmVjdGx5IHdpdGggdGhlIExpYnJhcnkgaXRzZWxmLgotDAotICA2LiBBcyBhbiBleGNlcHRpb24gdG8gdGhlIFNlY3Rpb25zIGFib3ZlLCB5b3UgbWF5IGFsc28gY29tYmluZSBvcgotbGluayBhICJ3b3JrIHRoYXQgdXNlcyB0aGUgTGlicmFyeSIgd2l0aCB0aGUgTGlicmFyeSB0byBwcm9kdWNlIGEKLXdvcmsgY29udGFpbmluZyBwb3J0aW9ucyBvZiB0aGUgTGlicmFyeSwgYW5kIGRpc3RyaWJ1dGUgdGhhdCB3b3JrCi11bmRlciB0ZXJtcyBvZiB5b3VyIGNob2ljZSwgcHJvdmlkZWQgdGhhdCB0aGUgdGVybXMgcGVybWl0Ci1tb2RpZmljYXRpb24gb2YgdGhlIHdvcmsgZm9yIHRoZSBjdXN0b21lcidzIG93biB1c2UgYW5kIHJldmVyc2UKLWVuZ2luZWVyaW5nIGZvciBkZWJ1Z2dpbmcgc3VjaCBtb2RpZmljYXRpb25zLgotCi0gIFlvdSBtdXN0IGdpdmUgcHJvbWluZW50IG5vdGljZSB3aXRoIGVhY2ggY29weSBvZiB0aGUgd29yayB0aGF0IHRoZQotTGlicmFyeSBpcyB1c2VkIGluIGl0IGFuZCB0aGF0IHRoZSBMaWJyYXJ5IGFuZCBpdHMgdXNlIGFyZSBjb3ZlcmVkIGJ5Ci10aGlzIExpY2Vuc2UuICBZb3UgbXVzdCBzdXBwbHkgYSBjb3B5IG9mIHRoaXMgTGljZW5zZS4gIElmIHRoZSB3b3JrCi1kdXJpbmcgZXhlY3V0aW9uIGRpc3BsYXlzIGNvcHlyaWdodCBub3RpY2VzLCB5b3UgbXVzdCBpbmNsdWRlIHRoZQotY29weXJpZ2h0IG5vdGljZSBmb3IgdGhlIExpYnJhcnkgYW1vbmcgdGhlbSwgYXMgd2VsbCBhcyBhIHJlZmVyZW5jZQotZGlyZWN0aW5nIHRoZSB1c2VyIHRvIHRoZSBjb3B5IG9mIHRoaXMgTGljZW5zZS4gIEFsc28sIHlvdSBtdXN0IGRvIG9uZQotb2YgdGhlc2UgdGhpbmdzOgotCi0gICAgYSkgQWNjb21wYW55IHRoZSB3b3JrIHdpdGggdGhlIGNvbXBsZXRlIGNvcnJlc3BvbmRpbmcKLSAgICBtYWNoaW5lLXJlYWRhYmxlIHNvdXJjZSBjb2RlIGZvciB0aGUgTGlicmFyeSBpbmNsdWRpbmcgd2hhdGV2ZXIKLSAgICBjaGFuZ2VzIHdlcmUgdXNlZCBpbiB0aGUgd29yayAod2hpY2ggbXVzdCBiZSBkaXN0cmlidXRlZCB1bmRlcgotICAgIFNlY3Rpb25zIDEgYW5kIDIgYWJvdmUpOyBhbmQsIGlmIHRoZSB3b3JrIGlzIGFuIGV4ZWN1dGFibGUgbGlua2VkCi0gICAgd2l0aCB0aGUgTGlicmFyeSwgd2l0aCB0aGUgY29tcGxldGUgbWFjaGluZS1yZWFkYWJsZSAid29yayB0aGF0Ci0gICAgdXNlcyB0aGUgTGlicmFyeSIsIGFzIG9iamVjdCBjb2RlIGFuZC9vciBzb3VyY2UgY29kZSwgc28gdGhhdCB0aGUKLSAgICB1c2VyIGNhbiBtb2RpZnkgdGhlIExpYnJhcnkgYW5kIHRoZW4gcmVsaW5rIHRvIHByb2R1Y2UgYSBtb2RpZmllZAotICAgIGV4ZWN1dGFibGUgY29udGFpbmluZyB0aGUgbW9kaWZpZWQgTGlicmFyeS4gIChJdCBpcyB1bmRlcnN0b29kCi0gICAgdGhhdCB0aGUgdXNlciB3aG8gY2hhbmdlcyB0aGUgY29udGVudHMgb2YgZGVmaW5pdGlvbnMgZmlsZXMgaW4gdGhlCi0gICAgTGlicmFyeSB3aWxsIG5vdCBuZWNlc3NhcmlseSBiZSBhYmxlIHRvIHJlY29tcGlsZSB0aGUgYXBwbGljYXRpb24KLSAgICB0byB1c2UgdGhlIG1vZGlmaWVkIGRlZmluaXRpb25zLikKLQotICAgIGIpIFVzZSBhIHN1aXRhYmxlIHNoYXJlZCBsaWJyYXJ5IG1lY2hhbmlzbSBmb3IgbGlua2luZyB3aXRoIHRoZQotICAgIExpYnJhcnkuICBBIHN1aXRhYmxlIG1lY2hhbmlzbSBpcyBvbmUgdGhhdCAoMSkgdXNlcyBhdCBydW4gdGltZSBhCi0gICAgY29weSBvZiB0aGUgbGlicmFyeSBhbHJlYWR5IHByZXNlbnQgb24gdGhlIHVzZXIncyBjb21wdXRlciBzeXN0ZW0sCi0gICAgcmF0aGVyIHRoYW4gY29weWluZyBsaWJyYXJ5IGZ1bmN0aW9ucyBpbnRvIHRoZSBleGVjdXRhYmxlLCBhbmQgKDIpCi0gICAgd2lsbCBvcGVyYXRlIHByb3Blcmx5IHdpdGggYSBtb2RpZmllZCB2ZXJzaW9uIG9mIHRoZSBsaWJyYXJ5LCBpZgotICAgIHRoZSB1c2VyIGluc3RhbGxzIG9uZSwgYXMgbG9uZyBhcyB0aGUgbW9kaWZpZWQgdmVyc2lvbiBpcwotICAgIGludGVyZmFjZS1jb21wYXRpYmxlIHdpdGggdGhlIHZlcnNpb24gdGhhdCB0aGUgd29yayB3YXMgbWFkZSB3aXRoLgotCi0gICAgYykgQWNjb21wYW55IHRoZSB3b3JrIHdpdGggYSB3cml0dGVuIG9mZmVyLCB2YWxpZCBmb3IgYXQKLSAgICBsZWFzdCB0aHJlZSB5ZWFycywgdG8gZ2l2ZSB0aGUgc2FtZSB1c2VyIHRoZSBtYXRlcmlhbHMKLSAgICBzcGVjaWZpZWQgaW4gU3Vic2VjdGlvbiA2YSwgYWJvdmUsIGZvciBhIGNoYXJnZSBubyBtb3JlCi0gICAgdGhhbiB0aGUgY29zdCBvZiBwZXJmb3JtaW5nIHRoaXMgZGlzdHJpYnV0aW9uLgotCi0gICAgZCkgSWYgZGlzdHJpYnV0aW9uIG9mIHRoZSB3b3JrIGlzIG1hZGUgYnkgb2ZmZXJpbmcgYWNjZXNzIHRvIGNvcHkKLSAgICBmcm9tIGEgZGVzaWduYXRlZCBwbGFjZSwgb2ZmZXIgZXF1aXZhbGVudCBhY2Nlc3MgdG8gY29weSB0aGUgYWJvdmUKLSAgICBzcGVjaWZpZWQgbWF0ZXJpYWxzIGZyb20gdGhlIHNhbWUgcGxhY2UuCi0KLSAgICBlKSBWZXJpZnkgdGhhdCB0aGUgdXNlciBoYXMgYWxyZWFkeSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlc2UKLSAgICBtYXRlcmlhbHMgb3IgdGhhdCB5b3UgaGF2ZSBhbHJlYWR5IHNlbnQgdGhpcyB1c2VyIGEgY29weS4KLQotICBGb3IgYW4gZXhlY3V0YWJsZSwgdGhlIHJlcXVpcmVkIGZvcm0gb2YgdGhlICJ3b3JrIHRoYXQgdXNlcyB0aGUKLUxpYnJhcnkiIG11c3QgaW5jbHVkZSBhbnkgZGF0YSBhbmQgdXRpbGl0eSBwcm9ncmFtcyBuZWVkZWQgZm9yCi1yZXByb2R1Y2luZyB0aGUgZXhlY3V0YWJsZSBmcm9tIGl0LiAgSG93ZXZlciwgYXMgYSBzcGVjaWFsIGV4Y2VwdGlvbiwKLXRoZSBtYXRlcmlhbHMgdG8gYmUgZGlzdHJpYnV0ZWQgbmVlZCBub3QgaW5jbHVkZSBhbnl0aGluZyB0aGF0IGlzCi1ub3JtYWxseSBkaXN0cmlidXRlZCAoaW4gZWl0aGVyIHNvdXJjZSBvciBiaW5hcnkgZm9ybSkgd2l0aCB0aGUgbWFqb3IKLWNvbXBvbmVudHMgKGNvbXBpbGVyLCBrZXJuZWwsIGFuZCBzbyBvbikgb2YgdGhlIG9wZXJhdGluZyBzeXN0ZW0gb24KLXdoaWNoIHRoZSBleGVjdXRhYmxlIHJ1bnMsIHVubGVzcyB0aGF0IGNvbXBvbmVudCBpdHNlbGYgYWNjb21wYW5pZXMKLXRoZSBleGVjdXRhYmxlLgotCi0gIEl0IG1heSBoYXBwZW4gdGhhdCB0aGlzIHJlcXVpcmVtZW50IGNvbnRyYWRpY3RzIHRoZSBsaWNlbnNlCi1yZXN0cmljdGlvbnMgb2Ygb3RoZXIgcHJvcHJpZXRhcnkgbGlicmFyaWVzIHRoYXQgZG8gbm90IG5vcm1hbGx5Ci1hY2NvbXBhbnkgdGhlIG9wZXJhdGluZyBzeXN0ZW0uICBTdWNoIGEgY29udHJhZGljdGlvbiBtZWFucyB5b3UgY2Fubm90Ci11c2UgYm90aCB0aGVtIGFuZCB0aGUgTGlicmFyeSB0b2dldGhlciBpbiBhbiBleGVjdXRhYmxlIHRoYXQgeW91Ci1kaXN0cmlidXRlLgotDAotICA3LiBZb3UgbWF5IHBsYWNlIGxpYnJhcnkgZmFjaWxpdGllcyB0aGF0IGFyZSBhIHdvcmsgYmFzZWQgb24gdGhlCi1MaWJyYXJ5IHNpZGUtYnktc2lkZSBpbiBhIHNpbmdsZSBsaWJyYXJ5IHRvZ2V0aGVyIHdpdGggb3RoZXIgbGlicmFyeQotZmFjaWxpdGllcyBub3QgY292ZXJlZCBieSB0aGlzIExpY2Vuc2UsIGFuZCBkaXN0cmlidXRlIHN1Y2ggYSBjb21iaW5lZAotbGlicmFyeSwgcHJvdmlkZWQgdGhhdCB0aGUgc2VwYXJhdGUgZGlzdHJpYnV0aW9uIG9mIHRoZSB3b3JrIGJhc2VkIG9uCi10aGUgTGlicmFyeSBhbmQgb2YgdGhlIG90aGVyIGxpYnJhcnkgZmFjaWxpdGllcyBpcyBvdGhlcndpc2UKLXBlcm1pdHRlZCwgYW5kIHByb3ZpZGVkIHRoYXQgeW91IGRvIHRoZXNlIHR3byB0aGluZ3M6Ci0KLSAgICBhKSBBY2NvbXBhbnkgdGhlIGNvbWJpbmVkIGxpYnJhcnkgd2l0aCBhIGNvcHkgb2YgdGhlIHNhbWUgd29yawotICAgIGJhc2VkIG9uIHRoZSBMaWJyYXJ5LCB1bmNvbWJpbmVkIHdpdGggYW55IG90aGVyIGxpYnJhcnkKLSAgICBmYWNpbGl0aWVzLiAgVGhpcyBtdXN0IGJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUKLSAgICBTZWN0aW9ucyBhYm92ZS4KLQotICAgIGIpIEdpdmUgcHJvbWluZW50IG5vdGljZSB3aXRoIHRoZSBjb21iaW5lZCBsaWJyYXJ5IG9mIHRoZSBmYWN0Ci0gICAgdGhhdCBwYXJ0IG9mIGl0IGlzIGEgd29yayBiYXNlZCBvbiB0aGUgTGlicmFyeSwgYW5kIGV4cGxhaW5pbmcKLSAgICB3aGVyZSB0byBmaW5kIHRoZSBhY2NvbXBhbnlpbmcgdW5jb21iaW5lZCBmb3JtIG9mIHRoZSBzYW1lIHdvcmsuCi0KLSAgOC4gWW91IG1heSBub3QgY29weSwgbW9kaWZ5LCBzdWJsaWNlbnNlLCBsaW5rIHdpdGgsIG9yIGRpc3RyaWJ1dGUKLXRoZSBMaWJyYXJ5IGV4Y2VwdCBhcyBleHByZXNzbHkgcHJvdmlkZWQgdW5kZXIgdGhpcyBMaWNlbnNlLiAgQW55Ci1hdHRlbXB0IG90aGVyd2lzZSB0byBjb3B5LCBtb2RpZnksIHN1YmxpY2Vuc2UsIGxpbmsgd2l0aCwgb3IKLWRpc3RyaWJ1dGUgdGhlIExpYnJhcnkgaXMgdm9pZCwgYW5kIHdpbGwgYXV0b21hdGljYWxseSB0ZXJtaW5hdGUgeW91cgotcmlnaHRzIHVuZGVyIHRoaXMgTGljZW5zZS4gIEhvd2V2ZXIsIHBhcnRpZXMgd2hvIGhhdmUgcmVjZWl2ZWQgY29waWVzLAotb3IgcmlnaHRzLCBmcm9tIHlvdSB1bmRlciB0aGlzIExpY2Vuc2Ugd2lsbCBub3QgaGF2ZSB0aGVpciBsaWNlbnNlcwotdGVybWluYXRlZCBzbyBsb25nIGFzIHN1Y2ggcGFydGllcyByZW1haW4gaW4gZnVsbCBjb21wbGlhbmNlLgotCi0gIDkuIFlvdSBhcmUgbm90IHJlcXVpcmVkIHRvIGFjY2VwdCB0aGlzIExpY2Vuc2UsIHNpbmNlIHlvdSBoYXZlIG5vdAotc2lnbmVkIGl0LiAgSG93ZXZlciwgbm90aGluZyBlbHNlIGdyYW50cyB5b3UgcGVybWlzc2lvbiB0byBtb2RpZnkgb3IKLWRpc3RyaWJ1dGUgdGhlIExpYnJhcnkgb3IgaXRzIGRlcml2YXRpdmUgd29ya3MuICBUaGVzZSBhY3Rpb25zIGFyZQotcHJvaGliaXRlZCBieSBsYXcgaWYgeW91IGRvIG5vdCBhY2NlcHQgdGhpcyBMaWNlbnNlLiAgVGhlcmVmb3JlLCBieQotbW9kaWZ5aW5nIG9yIGRpc3RyaWJ1dGluZyB0aGUgTGlicmFyeSAob3IgYW55IHdvcmsgYmFzZWQgb24gdGhlCi1MaWJyYXJ5KSwgeW91IGluZGljYXRlIHlvdXIgYWNjZXB0YW5jZSBvZiB0aGlzIExpY2Vuc2UgdG8gZG8gc28sIGFuZAotYWxsIGl0cyB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgY29weWluZywgZGlzdHJpYnV0aW5nIG9yIG1vZGlmeWluZwotdGhlIExpYnJhcnkgb3Igd29ya3MgYmFzZWQgb24gaXQuCi0KLSAgMTAuIEVhY2ggdGltZSB5b3UgcmVkaXN0cmlidXRlIHRoZSBMaWJyYXJ5IChvciBhbnkgd29yayBiYXNlZCBvbiB0aGUKLUxpYnJhcnkpLCB0aGUgcmVjaXBpZW50IGF1dG9tYXRpY2FsbHkgcmVjZWl2ZXMgYSBsaWNlbnNlIGZyb20gdGhlCi1vcmlnaW5hbCBsaWNlbnNvciB0byBjb3B5LCBkaXN0cmlidXRlLCBsaW5rIHdpdGggb3IgbW9kaWZ5IHRoZSBMaWJyYXJ5Ci1zdWJqZWN0IHRvIHRoZXNlIHRlcm1zIGFuZCBjb25kaXRpb25zLiAgWW91IG1heSBub3QgaW1wb3NlIGFueSBmdXJ0aGVyCi1yZXN0cmljdGlvbnMgb24gdGhlIHJlY2lwaWVudHMnIGV4ZXJjaXNlIG9mIHRoZSByaWdodHMgZ3JhbnRlZCBoZXJlaW4uCi1Zb3UgYXJlIG5vdCByZXNwb25zaWJsZSBmb3IgZW5mb3JjaW5nIGNvbXBsaWFuY2UgYnkgdGhpcmQgcGFydGllcyB3aXRoCi10aGlzIExpY2Vuc2UuCi0MCi0gIDExLiBJZiwgYXMgYSBjb25zZXF1ZW5jZSBvZiBhIGNvdXJ0IGp1ZGdtZW50IG9yIGFsbGVnYXRpb24gb2YgcGF0ZW50Ci1pbmZyaW5nZW1lbnQgb3IgZm9yIGFueSBvdGhlciByZWFzb24gKG5vdCBsaW1pdGVkIHRvIHBhdGVudCBpc3N1ZXMpLAotY29uZGl0aW9ucyBhcmUgaW1wb3NlZCBvbiB5b3UgKHdoZXRoZXIgYnkgY291cnQgb3JkZXIsIGFncmVlbWVudCBvcgotb3RoZXJ3aXNlKSB0aGF0IGNvbnRyYWRpY3QgdGhlIGNvbmRpdGlvbnMgb2YgdGhpcyBMaWNlbnNlLCB0aGV5IGRvIG5vdAotZXhjdXNlIHlvdSBmcm9tIHRoZSBjb25kaXRpb25zIG9mIHRoaXMgTGljZW5zZS4gIElmIHlvdSBjYW5ub3QKLWRpc3RyaWJ1dGUgc28gYXMgdG8gc2F0aXNmeSBzaW11bHRhbmVvdXNseSB5b3VyIG9ibGlnYXRpb25zIHVuZGVyIHRoaXMKLUxpY2Vuc2UgYW5kIGFueSBvdGhlciBwZXJ0aW5lbnQgb2JsaWdhdGlvbnMsIHRoZW4gYXMgYSBjb25zZXF1ZW5jZSB5b3UKLW1heSBub3QgZGlzdHJpYnV0ZSB0aGUgTGlicmFyeSBhdCBhbGwuICBGb3IgZXhhbXBsZSwgaWYgYSBwYXRlbnQKLWxpY2Vuc2Ugd291bGQgbm90IHBlcm1pdCByb3lhbHR5LWZyZWUgcmVkaXN0cmlidXRpb24gb2YgdGhlIExpYnJhcnkgYnkKLWFsbCB0aG9zZSB3aG8gcmVjZWl2ZSBjb3BpZXMgZGlyZWN0bHkgb3IgaW5kaXJlY3RseSB0aHJvdWdoIHlvdSwgdGhlbgotdGhlIG9ubHkgd2F5IHlvdSBjb3VsZCBzYXRpc2Z5IGJvdGggaXQgYW5kIHRoaXMgTGljZW5zZSB3b3VsZCBiZSB0bwotcmVmcmFpbiBlbnRpcmVseSBmcm9tIGRpc3RyaWJ1dGlvbiBvZiB0aGUgTGlicmFyeS4KLQotSWYgYW55IHBvcnRpb24gb2YgdGhpcyBzZWN0aW9uIGlzIGhlbGQgaW52YWxpZCBvciB1bmVuZm9yY2VhYmxlIHVuZGVyIGFueQotcGFydGljdWxhciBjaXJjdW1zdGFuY2UsIHRoZSBiYWxhbmNlIG9mIHRoZSBzZWN0aW9uIGlzIGludGVuZGVkIHRvIGFwcGx5LAotYW5kIHRoZSBzZWN0aW9uIGFzIGEgd2hvbGUgaXMgaW50ZW5kZWQgdG8gYXBwbHkgaW4gb3RoZXIgY2lyY3Vtc3RhbmNlcy4KLQotSXQgaXMgbm90IHRoZSBwdXJwb3NlIG9mIHRoaXMgc2VjdGlvbiB0byBpbmR1Y2UgeW91IHRvIGluZnJpbmdlIGFueQotcGF0ZW50cyBvciBvdGhlciBwcm9wZXJ0eSByaWdodCBjbGFpbXMgb3IgdG8gY29udGVzdCB2YWxpZGl0eSBvZiBhbnkKLXN1Y2ggY2xhaW1zOyB0aGlzIHNlY3Rpb24gaGFzIHRoZSBzb2xlIHB1cnBvc2Ugb2YgcHJvdGVjdGluZyB0aGUKLWludGVncml0eSBvZiB0aGUgZnJlZSBzb2Z0d2FyZSBkaXN0cmlidXRpb24gc3lzdGVtIHdoaWNoIGlzCi1pbXBsZW1lbnRlZCBieSBwdWJsaWMgbGljZW5zZSBwcmFjdGljZXMuICBNYW55IHBlb3BsZSBoYXZlIG1hZGUKLWdlbmVyb3VzIGNvbnRyaWJ1dGlvbnMgdG8gdGhlIHdpZGUgcmFuZ2Ugb2Ygc29mdHdhcmUgZGlzdHJpYnV0ZWQKLXRocm91Z2ggdGhhdCBzeXN0ZW0gaW4gcmVsaWFuY2Ugb24gY29uc2lzdGVudCBhcHBsaWNhdGlvbiBvZiB0aGF0Ci1zeXN0ZW07IGl0IGlzIHVwIHRvIHRoZSBhdXRob3IvZG9ub3IgdG8gZGVjaWRlIGlmIGhlIG9yIHNoZSBpcyB3aWxsaW5nCi10byBkaXN0cmlidXRlIHNvZnR3YXJlIHRocm91Z2ggYW55IG90aGVyIHN5c3RlbSBhbmQgYSBsaWNlbnNlZSBjYW5ub3QKLWltcG9zZSB0aGF0IGNob2ljZS4KLQotVGhpcyBzZWN0aW9uIGlzIGludGVuZGVkIHRvIG1ha2UgdGhvcm91Z2hseSBjbGVhciB3aGF0IGlzIGJlbGlldmVkIHRvCi1iZSBhIGNvbnNlcXVlbmNlIG9mIHRoZSByZXN0IG9mIHRoaXMgTGljZW5zZS4KLQotICAxMi4gSWYgdGhlIGRpc3RyaWJ1dGlvbiBhbmQvb3IgdXNlIG9mIHRoZSBMaWJyYXJ5IGlzIHJlc3RyaWN0ZWQgaW4KLWNlcnRhaW4gY291bnRyaWVzIGVpdGhlciBieSBwYXRlbnRzIG9yIGJ5IGNvcHlyaWdodGVkIGludGVyZmFjZXMsIHRoZQotb3JpZ2luYWwgY29weXJpZ2h0IGhvbGRlciB3aG8gcGxhY2VzIHRoZSBMaWJyYXJ5IHVuZGVyIHRoaXMgTGljZW5zZSBtYXkgYWRkCi1hbiBleHBsaWNpdCBnZW9ncmFwaGljYWwgZGlzdHJpYnV0aW9uIGxpbWl0YXRpb24gZXhjbHVkaW5nIHRob3NlIGNvdW50cmllcywKLXNvIHRoYXQgZGlzdHJpYnV0aW9uIGlzIHBlcm1pdHRlZCBvbmx5IGluIG9yIGFtb25nIGNvdW50cmllcyBub3QgdGh1cwotZXhjbHVkZWQuICBJbiBzdWNoIGNhc2UsIHRoaXMgTGljZW5zZSBpbmNvcnBvcmF0ZXMgdGhlIGxpbWl0YXRpb24gYXMgaWYKLXdyaXR0ZW4gaW4gdGhlIGJvZHkgb2YgdGhpcyBMaWNlbnNlLgotCi0gIDEzLiBUaGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIG1heSBwdWJsaXNoIHJldmlzZWQgYW5kL29yIG5ldwotdmVyc2lvbnMgb2YgdGhlIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZyb20gdGltZSB0byB0aW1lLgotU3VjaCBuZXcgdmVyc2lvbnMgd2lsbCBiZSBzaW1pbGFyIGluIHNwaXJpdCB0byB0aGUgcHJlc2VudCB2ZXJzaW9uLAotYnV0IG1heSBkaWZmZXIgaW4gZGV0YWlsIHRvIGFkZHJlc3MgbmV3IHByb2JsZW1zIG9yIGNvbmNlcm5zLgotCi1FYWNoIHZlcnNpb24gaXMgZ2l2ZW4gYSBkaXN0aW5ndWlzaGluZyB2ZXJzaW9uIG51bWJlci4gIElmIHRoZSBMaWJyYXJ5Ci1zcGVjaWZpZXMgYSB2ZXJzaW9uIG51bWJlciBvZiB0aGlzIExpY2Vuc2Ugd2hpY2ggYXBwbGllcyB0byBpdCBhbmQKLSJhbnkgbGF0ZXIgdmVyc2lvbiIsIHlvdSBoYXZlIHRoZSBvcHRpb24gb2YgZm9sbG93aW5nIHRoZSB0ZXJtcyBhbmQKLWNvbmRpdGlvbnMgZWl0aGVyIG9mIHRoYXQgdmVyc2lvbiBvciBvZiBhbnkgbGF0ZXIgdmVyc2lvbiBwdWJsaXNoZWQgYnkKLXRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBJZiB0aGUgTGlicmFyeSBkb2VzIG5vdCBzcGVjaWZ5IGEKLWxpY2Vuc2UgdmVyc2lvbiBudW1iZXIsIHlvdSBtYXkgY2hvb3NlIGFueSB2ZXJzaW9uIGV2ZXIgcHVibGlzaGVkIGJ5Ci10aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotDAotICAxNC4gSWYgeW91IHdpc2ggdG8gaW5jb3Jwb3JhdGUgcGFydHMgb2YgdGhlIExpYnJhcnkgaW50byBvdGhlciBmcmVlCi1wcm9ncmFtcyB3aG9zZSBkaXN0cmlidXRpb24gY29uZGl0aW9ucyBhcmUgaW5jb21wYXRpYmxlIHdpdGggdGhlc2UsCi13cml0ZSB0byB0aGUgYXV0aG9yIHRvIGFzayBmb3IgcGVybWlzc2lvbi4gIEZvciBzb2Z0d2FyZSB3aGljaCBpcwotY29weXJpZ2h0ZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgd3JpdGUgdG8gdGhlIEZyZWUKLVNvZnR3YXJlIEZvdW5kYXRpb247IHdlIHNvbWV0aW1lcyBtYWtlIGV4Y2VwdGlvbnMgZm9yIHRoaXMuICBPdXIKLWRlY2lzaW9uIHdpbGwgYmUgZ3VpZGVkIGJ5IHRoZSB0d28gZ29hbHMgb2YgcHJlc2VydmluZyB0aGUgZnJlZSBzdGF0dXMKLW9mIGFsbCBkZXJpdmF0aXZlcyBvZiBvdXIgZnJlZSBzb2Z0d2FyZSBhbmQgb2YgcHJvbW90aW5nIHRoZSBzaGFyaW5nCi1hbmQgcmV1c2Ugb2Ygc29mdHdhcmUgZ2VuZXJhbGx5LgotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgTk8gV0FSUkFOVFkKLQotICAxNS4gQkVDQVVTRSBUSEUgTElCUkFSWSBJUyBMSUNFTlNFRCBGUkVFIE9GIENIQVJHRSwgVEhFUkUgSVMgTk8KLVdBUlJBTlRZIEZPUiBUSEUgTElCUkFSWSwgVE8gVEhFIEVYVEVOVCBQRVJNSVRURUQgQlkgQVBQTElDQUJMRSBMQVcuCi1FWENFUFQgV0hFTiBPVEhFUldJU0UgU1RBVEVEIElOIFdSSVRJTkcgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORC9PUgotT1RIRVIgUEFSVElFUyBQUk9WSURFIFRIRSBMSUJSQVJZICJBUyBJUyIgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkKLUtJTkQsIEVJVEhFUiBFWFBSRVNTRUQgT1IgSU1QTElFRCwgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRQotSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCi1QVVJQT1NFLiAgVEhFIEVOVElSRSBSSVNLIEFTIFRPIFRIRSBRVUFMSVRZIEFORCBQRVJGT1JNQU5DRSBPRiBUSEUKLUxJQlJBUlkgSVMgV0lUSCBZT1UuICBTSE9VTEQgVEhFIExJQlJBUlkgUFJPVkUgREVGRUNUSVZFLCBZT1UgQVNTVU1FCi1USEUgQ09TVCBPRiBBTEwgTkVDRVNTQVJZIFNFUlZJQ0lORywgUkVQQUlSIE9SIENPUlJFQ1RJT04uCi0KLSAgMTYuIElOIE5PIEVWRU5UIFVOTEVTUyBSRVFVSVJFRCBCWSBBUFBMSUNBQkxFIExBVyBPUiBBR1JFRUQgVE8gSU4KLVdSSVRJTkcgV0lMTCBBTlkgQ09QWVJJR0hUIEhPTERFUiwgT1IgQU5ZIE9USEVSIFBBUlRZIFdITyBNQVkgTU9ESUZZCi1BTkQvT1IgUkVESVNUUklCVVRFIFRIRSBMSUJSQVJZIEFTIFBFUk1JVFRFRCBBQk9WRSwgQkUgTElBQkxFIFRPIFlPVQotRk9SIERBTUFHRVMsIElOQ0xVRElORyBBTlkgR0VORVJBTCwgU1BFQ0lBTCwgSU5DSURFTlRBTCBPUgotQ09OU0VRVUVOVElBTCBEQU1BR0VTIEFSSVNJTkcgT1VUIE9GIFRIRSBVU0UgT1IgSU5BQklMSVRZIFRPIFVTRSBUSEUKLUxJQlJBUlkgKElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gTE9TUyBPRiBEQVRBIE9SIERBVEEgQkVJTkcKLVJFTkRFUkVEIElOQUNDVVJBVEUgT1IgTE9TU0VTIFNVU1RBSU5FRCBCWSBZT1UgT1IgVEhJUkQgUEFSVElFUyBPUiBBCi1GQUlMVVJFIE9GIFRIRSBMSUJSQVJZIFRPIE9QRVJBVEUgV0lUSCBBTlkgT1RIRVIgU09GVFdBUkUpLCBFVkVOIElGCi1TVUNIIEhPTERFUiBPUiBPVEhFUiBQQVJUWSBIQVMgQkVFTiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNICi1EQU1BR0VTLgotCi0gICAgICAgICAgICAgICAgICAgICBFTkQgT0YgVEVSTVMgQU5EIENPTkRJVElPTlMKLQwKLSAgICAgICAgICAgSG93IHRvIEFwcGx5IFRoZXNlIFRlcm1zIHRvIFlvdXIgTmV3IExpYnJhcmllcwotCi0gIElmIHlvdSBkZXZlbG9wIGEgbmV3IGxpYnJhcnksIGFuZCB5b3Ugd2FudCBpdCB0byBiZSBvZiB0aGUgZ3JlYXRlc3QKLXBvc3NpYmxlIHVzZSB0byB0aGUgcHVibGljLCB3ZSByZWNvbW1lbmQgbWFraW5nIGl0IGZyZWUgc29mdHdhcmUgdGhhdAotZXZlcnlvbmUgY2FuIHJlZGlzdHJpYnV0ZSBhbmQgY2hhbmdlLiAgWW91IGNhbiBkbyBzbyBieSBwZXJtaXR0aW5nCi1yZWRpc3RyaWJ1dGlvbiB1bmRlciB0aGVzZSB0ZXJtcyAob3IsIGFsdGVybmF0aXZlbHksIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUKLW9yZGluYXJ5IEdlbmVyYWwgUHVibGljIExpY2Vuc2UpLgotCi0gIFRvIGFwcGx5IHRoZXNlIHRlcm1zLCBhdHRhY2ggdGhlIGZvbGxvd2luZyBub3RpY2VzIHRvIHRoZSBsaWJyYXJ5LiAgSXQgaXMKLXNhZmVzdCB0byBhdHRhY2ggdGhlbSB0byB0aGUgc3RhcnQgb2YgZWFjaCBzb3VyY2UgZmlsZSB0byBtb3N0IGVmZmVjdGl2ZWx5Ci1jb252ZXkgdGhlIGV4Y2x1c2lvbiBvZiB3YXJyYW50eTsgYW5kIGVhY2ggZmlsZSBzaG91bGQgaGF2ZSBhdCBsZWFzdCB0aGUKLSJjb3B5cmlnaHQiIGxpbmUgYW5kIGEgcG9pbnRlciB0byB3aGVyZSB0aGUgZnVsbCBub3RpY2UgaXMgZm91bmQuCi0KLSAgICA8b25lIGxpbmUgdG8gZ2l2ZSB0aGUgbGlicmFyeSdzIG5hbWUgYW5kIGEgYnJpZWYgaWRlYSBvZiB3aGF0IGl0IGRvZXMuPgotICAgIENvcHlyaWdodCAoQykgPHllYXI+ICA8bmFtZSBvZiBhdXRob3I+Ci0KLSAgICBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCi0gICAgbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwotICAgIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgotICAgIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgotCi0gICAgVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCi0gICAgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKLSAgICBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQotICAgIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCi0KLSAgICBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCi0gICAgTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQotICAgIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQQotCi1BbHNvIGFkZCBpbmZvcm1hdGlvbiBvbiBob3cgdG8gY29udGFjdCB5b3UgYnkgZWxlY3Ryb25pYyBhbmQgcGFwZXIgbWFpbC4KLQotWW91IHNob3VsZCBhbHNvIGdldCB5b3VyIGVtcGxveWVyIChpZiB5b3Ugd29yayBhcyBhIHByb2dyYW1tZXIpIG9yIHlvdXIKLXNjaG9vbCwgaWYgYW55LCB0byBzaWduIGEgImNvcHlyaWdodCBkaXNjbGFpbWVyIiBmb3IgdGhlIGxpYnJhcnksIGlmCi1uZWNlc3NhcnkuICBIZXJlIGlzIGEgc2FtcGxlOyBhbHRlciB0aGUgbmFtZXM6Ci0KLSAgWW95b2R5bmUsIEluYy4sIGhlcmVieSBkaXNjbGFpbXMgYWxsIGNvcHlyaWdodCBpbnRlcmVzdCBpbiB0aGUKLSAgbGlicmFyeSBgRnJvYicgKGEgbGlicmFyeSBmb3IgdHdlYWtpbmcga25vYnMpIHdyaXR0ZW4gYnkgSmFtZXMgUmFuZG9tIEhhY2tlci4KLQotICA8c2lnbmF0dXJlIG9mIFR5IENvb24+LCAxIEFwcmlsIDE5OTAKLSAgVHkgQ29vbiwgUHJlc2lkZW50IG9mIFZpY2UKLQotVGhhdCdzIGFsbCB0aGVyZSBpcyB0byBpdCEKLQotLS0tIGVuZCBvZiBMSUNFTlNFIC0tLQotCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0KLSUlIFRoaXMgbm90aWNlIGlzIHByb3ZpZGVkIHdpdGggcmVzcGVjdCB0byAgRUNNQVNjcmlwdCBMYW5ndWFnZQotU3BlY2lmaWNhdGlvbiBFQ01BLTI2MiBFZGl0aW9uIDUuMSB3aGljaCBtYXkgYmUgaW5jbHVkZWQgd2l0aCAKLUpSRSA4LCBKREsgOCwgYW5kIE9wZW5KREsgOC4KLQotLS0tIGJlZ2luIG9mIExJQ0VOU0UgLS0tCi0KLUNvcHlyaWdodCBub3RpY2UKLUNvcHlyaWdodCDCqSAyMDExIEVjbWEgSW50ZXJuYXRpb25hbAotRWNtYSBJbnRlcm5hdGlvbmFsCi1SdWUgZHUgUmhvbmUgMTE0Ci1DSC0xMjA0IEdlbmV2YQotVGVsOiArNDEgMjIgODQ5IDYwMDAKLUZheDogKzQxIDIyIDg0OSA2MDAxCi1XZWI6IGh0dHA6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZwotCi1UaGlzIGRvY3VtZW50IGFuZCBwb3NzaWJsZSB0cmFuc2xhdGlvbnMgb2YgaXQgbWF5IGJlIGNvcGllZCBhbmQgZnVybmlzaGVkIHRvCi1vdGhlcnMsIGFuZCBkZXJpdmF0aXZlIHdvcmtzIHRoYXQgY29tbWVudCBvbiBvciBvdGhlcndpc2UgZXhwbGFpbiBpdCBvciBhc3Npc3QKLWluIGl0cyBpbXBsZW1lbnRhdGlvbiBtYXkgYmUgcHJlcGFyZWQsIGNvcGllZCwgcHVibGlzaGVkLCBhbmQgZGlzdHJpYnV0ZWQsIGluCi13aG9sZSBvciBpbiBwYXJ0LCB3aXRob3V0IHJlc3RyaWN0aW9uIG9mIGFueSBraW5kLCBwcm92aWRlZCB0aGF0IHRoZSBhYm92ZQotY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBzZWN0aW9uIGFyZSBpbmNsdWRlZCBvbiBhbGwgc3VjaCBjb3BpZXMgYW5kIGRlcml2YXRpdmUKLXdvcmtzLiBIb3dldmVyLCB0aGlzIGRvY3VtZW50IGl0c2VsZiBtYXkgbm90IGJlIG1vZGlmaWVkIGluIGFueSB3YXksIGluY2x1ZGluZwotYnkgcmVtb3ZpbmcgdGhlIGNvcHlyaWdodCBub3RpY2Ugb3IgcmVmZXJlbmNlcyB0byBFY21hIEludGVybmF0aW9uYWwsIGV4Y2VwdCBhcwotbmVlZGVkIGZvciB0aGUgcHVycG9zZSBvZiBkZXZlbG9waW5nIGFueSBkb2N1bWVudCBvciBkZWxpdmVyYWJsZSBwcm9kdWNlZCBieQotRWNtYSBJbnRlcm5hdGlvbmFsIChpbiB3aGljaCBjYXNlIHRoZSBydWxlcyBhcHBsaWVkIHRvIGNvcHlyaWdodHMgbXVzdCBiZQotZm9sbG93ZWQpIG9yIGFzIHJlcXVpcmVkIHRvIHRyYW5zbGF0ZSBpdCBpbnRvIGxhbmd1YWdlcyBvdGhlciB0aGFuIEVuZ2xpc2guIFRoZQotbGltaXRlZCBwZXJtaXNzaW9ucyBncmFudGVkIGFib3ZlIGFyZSBwZXJwZXR1YWwgYW5kIHdpbGwgbm90IGJlIHJldm9rZWQgYnkgRWNtYQotSW50ZXJuYXRpb25hbCBvciBpdHMgc3VjY2Vzc29ycyBvciBhc3NpZ25zLiBUaGlzIGRvY3VtZW50IGFuZCB0aGUgaW5mb3JtYXRpb24KLWNvbnRhaW5lZCBoZXJlaW4gaXMgcHJvdmlkZWQgb24gYW4gIkFTIElTIiBiYXNpcyBhbmQgRUNNQSBJTlRFUk5BVElPTkFMCi1ESVNDTEFJTVMgQUxMIFdBUlJBTlRJRVMsIEVYUFJFU1MgT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBBTlkKLVdBUlJBTlRZIFRIQVQgVEhFIFVTRSBPRiBUSEUgSU5GT1JNQVRJT04gSEVSRUlOIFdJTEwgTk9UIElORlJJTkdFIEFOWSBPV05FUlNISVAKLVJJR0hUUyBPUiBBTlkgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBPUiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKLVBVUlBPU0UuIiBTb2Z0d2FyZSBMaWNlbnNlCi0KLUFsbCBTb2Z0d2FyZSBjb250YWluZWQgaW4gdGhpcyBkb2N1bWVudCAoIlNvZnR3YXJlKSIgaXMgcHJvdGVjdGVkIGJ5IGNvcHlyaWdodAotYW5kIGlzIGJlaW5nIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSAiQlNEIExpY2Vuc2UiLCBpbmNsdWRlZCBiZWxvdy4gVGhpcwotU29mdHdhcmUgbWF5IGJlIHN1YmplY3QgdG8gdGhpcmQgcGFydHkgcmlnaHRzIChyaWdodHMgZnJvbSBwYXJ0aWVzIG90aGVyIHRoYW4KLUVjbWEgSW50ZXJuYXRpb25hbCksIGluY2x1ZGluZyBwYXRlbnQgcmlnaHRzLCBhbmQgbm8gbGljZW5zZXMgdW5kZXIgc3VjaCB0aGlyZAotcGFydHkgcmlnaHRzIGFyZSBncmFudGVkIHVuZGVyIHRoaXMgbGljZW5zZSBldmVuIGlmIHRoZSB0aGlyZCBwYXJ0eSBjb25jZXJuZWQgaXMKLWEgbWVtYmVyIG9mIEVjbWEgSW50ZXJuYXRpb25hbC4gU0VFIFRIRSBFQ01BIENPREUgT0YgQ09ORFVDVCBJTiBQQVRFTlQgTUFUVEVSUwotQVZBSUxBQkxFIEFUIGh0dHA6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9tZW1lbnRvL2NvZGVvZmNvbmR1Y3QuaHRtIEZPUgotSU5GT1JNQVRJT04gUkVHQVJESU5HIFRIRSBMSUNFTlNJTkcgT0YgUEFURU5UIENMQUlNUyBUSEFUIEFSRSBSRVFVSVJFRCBUTwotSU1QTEVNRU5UIEVDTUEgSU5URVJOQVRJT05BTCBTVEFOREFSRFMqLiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQKLWJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZQotZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDoKLQotMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzCi1saXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLQotMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLAotdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3IKLW90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uCi0KLTMuIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIGF1dGhvcnMgbm9yIEVjbWEgSW50ZXJuYXRpb25hbCBtYXkgYmUgdXNlZCB0byBlbmRvcnNlCi1vciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbgotcGVybWlzc2lvbi4KLQotVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgRUNNQSBJTlRFUk5BVElPTkFMICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SCi1JTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GCi1NRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVAotU0hBTEwgRUNNQSBJTlRFUk5BVElPTkFMIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi1TUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sCi1QUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IKLUJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOCi1DT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HCi1JTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkKLU9GIFNVQ0ggREFNQUdFLgotLS0tIGVuZCBvZiBMSUNFTlNFIC0tLQotCi0lJSBUaGlzIG5vdGljZSBpcyBwcm92aWRlZCB3aXRoIHJlc3BlY3QgdG8gRHluYWxpbmsgbGlicmFyeSB3aGljaCBpcyBpbmNsdWRlZAotd2l0aCB0aGUgTmFzaG9ybiB0ZWNobm9sb2d5LgotCi0tLS0gYmVnaW4gb2YgTElDRU5TRSAtLS0KLUNvcHlyaWdodCAoYykgMjAwOS0yMDEzLCBBdHRpbGEgU3plZ2VkaQotCi1SZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLW1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKLW1ldDoKLSogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlCi0gIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uCi0qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIGNvcHlyaWdodCBob2xkZXIgbm9yIHRoZSBuYW1lcyBvZgotICBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQotICB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgotCi1USElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTICJBUwotSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVECi1UTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEKLVBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgQ09QWVJJR0hUIEhPTERFUgotQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUgotQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YKLVNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUgotQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksCi1XSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUgotT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRgotQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCi0tLS0gZW5kIG9mIExJQ0VOU0UgLS0tCi0KLSUlIFRoaXMgbm90aWNlIGlzIHByb3ZpZGVkIHdpdGggcmVzcGVjdCB0byBKb25pIGxpYnJhcnkgd2hpY2ggaXMgaW5jbHVkZWQKLXdpdGggdGhlIE5hc2hvcm4gdGVjaG5vbG9neS4KLQotLS0tIGJlZ2luIG9mIExJQ0VOU0UgLS0tCi1QZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5IG9mCi10aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSAiU29mdHdhcmUiKSwgdG8gZGVhbCBpbgotdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0bwotdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMKLW9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbwotc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgotCi1UaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpbiBhbGwKLWNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuCi0KLVRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAiQVMgSVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SCi1JTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwKLUZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRQotQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUgotTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwKLU9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFCi1TT0ZUV0FSRS4KLQotLS0tIGVuZCBvZiBMSUNFTlNFIC0tLQotCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0KLSUlIFRoaXMgbm90aWNlIGlzIHByb3ZpZGVkIHdpdGggcmVzcGVjdCB0byBGb250Q29uZmlnIDIuNSwgd2hpY2ggbWF5IGJlIAotaW5jbHVkZWQgd2l0aCBKUkUgOCwgSkRLIDgsIGFuZCBPcGVuSkRLIDggc291cmNlIGRpc3RyaWJ1dGlvbnMgb24KLUxpbnV4IGFuZCBTb2xhcmlzLgotCi0tLS0gYmVnaW4gb2YgTElDRU5TRSAtLS0KLQotQ29weXJpZ2h0IMKpIDIwMDEsMjAwMyBLZWl0aCBQYWNrYXJkCi0KLVBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGRpc3RyaWJ1dGUsIGFuZCBzZWxsIHRoaXMgc29mdHdhcmUgYW5kIGl0cwotZG9jdW1lbnRhdGlvbiBmb3IgYW55IHB1cnBvc2UgaXMgaGVyZWJ5IGdyYW50ZWQgd2l0aG91dCBmZWUsIHByb3ZpZGVkIHRoYXQgdGhlCi1hYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFwcGVhciBpbiBhbGwgY29waWVzIGFuZCB0aGF0IGJvdGggdGhhdCBjb3B5cmlnaHQKLW5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBhcHBlYXIgaW4gc3VwcG9ydGluZyBkb2N1bWVudGF0aW9uLCBhbmQgdGhhdAotdGhlIG5hbWUgb2YgS2VpdGggUGFja2FyZCBub3QgYmUgdXNlZCBpbiBhZHZlcnRpc2luZyBvciBwdWJsaWNpdHkgcGVydGFpbmluZwotdG8gZGlzdHJpYnV0aW9uIG9mIHRoZSBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljLCB3cml0dGVuIHByaW9yIHBlcm1pc3Npb24uCi1LZWl0aCBQYWNrYXJkIG1ha2VzIG5vIHJlcHJlc2VudGF0aW9ucyBhYm91dCB0aGUgc3VpdGFiaWxpdHkgb2YgdGhpcyBzb2Z0d2FyZQotZm9yIGFueSBwdXJwb3NlLiAgSXQgaXMgcHJvdmlkZWQgImFzIGlzIiB3aXRob3V0IGV4cHJlc3Mgb3IgaW1wbGllZCB3YXJyYW50eS4KLQotS0VJVEggUEFDS0FSRCBESVNDTEFJTVMgQUxMIFdBUlJBTlRJRVMgV0lUSCBSRUdBUkQgVE8gVEhJUyBTT0ZUV0FSRSwgSU5DTFVESU5HCi1BTEwgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUywgSU4gTk8gRVZFTlQgU0hBTEwgS0VJVEgKLVBBQ0tBUkQgQkUgTElBQkxFIEZPUiBBTlkgU1BFQ0lBTCwgSU5ESVJFQ1QgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIE9SIEFOWQotREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NIExPU1MgT0YgVVNFLCBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4KLUFDVElPTiBPRiBDT05UUkFDVCwgTkVHTElHRU5DRSBPUiBPVEhFUiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GIE9SIElOCi1DT05ORUNUSU9OIFdJVEggVEhFIFVTRSBPUiBQRVJGT1JNQU5DRSBPRiBUSElTIFNPRlRXQVJFLgotCi0KLS0tLSBlbmQgb2YgTElDRU5TRSAtLS0KLQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotCi0lJSBUaGlzIG5vdGljZSBpcyBwcm92aWRlZCB3aXRoIHJlc3BlY3QgdG8gSUFJSyBQS0NTIzExIFdyYXBwZXIsIAotd2hpY2ggbWF5IGJlIGluY2x1ZGVkIHdpdGggSlJFIDgsIEpESyA4LCBhbmQgT3BlbkpESyA4LgotCi0tLS0gYmVnaW4gb2YgTElDRU5TRSAtLS0KLQotSUFJSyBQS0NTIzExIFdyYXBwZXIgTGljZW5zZQotCi1Db3B5cmlnaHQgKGMpIDIwMDIgR3JheiBVbml2ZXJzaXR5IG9mIFRlY2hub2xvZ3kuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0KLVJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6Ci0KLTEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpcwotICAgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0KLTIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwKLSAgIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24KLSAgIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgotCi0zLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwgaWYgYW55LCBtdXN0Ci0gICBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0KLSAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IElBSUsgb2YgR3JheiBVbml2ZXJzaXR5IG9mCi0gICAgVGVjaG5vbG9neS4iCi0KLSAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwgaWYgYW5kCi0gICB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0KLTQuIFRoZSBuYW1lcyAiR3JheiBVbml2ZXJzaXR5IG9mIFRlY2hub2xvZ3kiIGFuZCAiSUFJSyBvZiBHcmF6IFVuaXZlcnNpdHkgb2YKLSAgIFRlY2hub2xvZ3kiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KLQotNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIklBSUsgUEtDUyBXcmFwcGVyIiwKLSAgIG5vciBtYXkgIklBSUsiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZgotICAgR3JheiBVbml2ZXJzaXR5IG9mIFRlY2hub2xvZ3kuCi0KLVRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsCi1JTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5ECi1GSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFCi1MSUNFTlNPUiBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksCi1PUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRgotU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTCi1JTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTgotQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkKLUFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFCi1QT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KLQotLS0tIGVuZCBvZiBMSUNFTlNFIC0tLQotCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0KLSUlIFRoaXMgbm90aWNlIGlzIHByb3ZpZGVkIHdpdGggcmVzcGVjdCB0byBJQ1U0QyA0LjAuMSBhbmQgSUNVNEogNC40LCB3aGljaCAKLW1heSBiZSBpbmNsdWRlZCB3aXRoIEpSRSA4LCBKREsgOCwgYW5kIE9wZW5KREsgOC4KLQotLS0tIGJlZ2luIG9mIExJQ0VOU0UgLS0tCi0KLUNvcHlyaWdodCAoYykgMTk5NS0yMDEwIEludGVybmF0aW9uYWwgQnVzaW5lc3MgTWFjaGluZXMgQ29ycG9yYXRpb24gYW5kIG90aGVycyAKLQotQWxsIHJpZ2h0cyByZXNlcnZlZC4gCi0KLVBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHkKLW9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlICJTb2Z0d2FyZSIpLCB0byBkZWFsCi1pbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzCi10byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUKLVNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLAotcHJvdmlkZWQgdGhhdCB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZShzKSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBhcHBlYXIKLWluIGFsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlIGFuZCB0aGF0IGJvdGggdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UocykgYW5kCi10aGlzIHBlcm1pc3Npb24gbm90aWNlIGFwcGVhciBpbiBzdXBwb3J0aW5nIGRvY3VtZW50YXRpb24uCi0KLVRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAiQVMgSVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SCi1JTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwKLUZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQgT0YgVEhJUkQgUEFSVFkgUklHSFRTLiBJTgotTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgSE9MREVSUyBJTkNMVURFRCBJTiBUSElTIE5PVElDRSBCRQotTElBQkxFIEZPUiBBTlkgQ0xBSU0sIE9SIEFOWSBTUEVDSUFMIElORElSRUNUIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUywgT1IgQU5ZCi1EQU1BR0VTIFdIQVRTT0VWRVIgUkVTVUxUSU5HIEZST00gTE9TUyBPRiBVU0UsIERBVEEgT1IgUFJPRklUUywgV0hFVEhFUiBJTiBBTgotQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SIE9USEVSIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4KLUNPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SIFBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuCi0KLUV4Y2VwdCBhcyBjb250YWluZWQgaW4gdGhpcyBub3RpY2UsIHRoZSBuYW1lIG9mIGEgY29weXJpZ2h0IGhvbGRlciBzaGFsbCBub3QKLWJlIHVzZWQgaW4gYWR2ZXJ0aXNpbmcgb3Igb3RoZXJ3aXNlIHRvIHByb21vdGUgdGhlIHNhbGUsIHVzZSBvciBvdGhlciBkZWFsaW5ncwotaW4gdGhpcyBTb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gYXV0aG9yaXphdGlvbiBvZiB0aGUgY29weXJpZ2h0IGhvbGRlci4KLUFsbCB0cmFkZW1hcmtzIGFuZCByZWdpc3RlcmVkIHRyYWRlbWFya3MgbWVudGlvbmVkIGhlcmVpbiBhcmUgdGhlIHByb3BlcnR5IG9mCi10aGVpciByZXNwZWN0aXZlIG93bmVycy4KLQotLS0tIGVuZCBvZiBMSUNFTlNFIC0tLQotCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0KLSUlIFRoaXMgbm90aWNlIGlzIHByb3ZpZGVkIHdpdGggcmVzcGVjdCB0byBJSkcgSlBFRyA2Yiwgd2hpY2ggbWF5IGJlIAotaW5jbHVkZWQgd2l0aCBKUkUgOCwgSkRLIDgsIGFuZCBPcGVuSkRLIDguCi0KLS0tLSBiZWdpbiBvZiBMSUNFTlNFIC0tLQotCi1UaGlzIHNvZnR3YXJlIGlzIGNvcHlyaWdodCAoQykgMTk5MS0xOTk4LCBUaG9tYXMgRy4gTGFuZS4KLUFsbCBSaWdodHMgUmVzZXJ2ZWQgZXhjZXB0IGFzIHNwZWNpZmllZCBiZWxvdy4KLQotUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCB0byB1c2UsIGNvcHksIG1vZGlmeSwgYW5kIGRpc3RyaWJ1dGUgdGhpcwotc29mdHdhcmUgKG9yIHBvcnRpb25zIHRoZXJlb2YpIGZvciBhbnkgcHVycG9zZSwgd2l0aG91dCBmZWUsIHN1YmplY3QgdG8gdGhlc2UKLWNvbmRpdGlvbnM6Ci0oMSkgSWYgYW55IHBhcnQgb2YgdGhlIHNvdXJjZSBjb2RlIGZvciB0aGlzIHNvZnR3YXJlIGlzIGRpc3RyaWJ1dGVkLCB0aGVuIHRoaXMKLVJFQURNRSBmaWxlIG11c3QgYmUgaW5jbHVkZWQsIHdpdGggdGhpcyBjb3B5cmlnaHQgYW5kIG5vLXdhcnJhbnR5IG5vdGljZQotdW5hbHRlcmVkOyBhbmQgYW55IGFkZGl0aW9ucywgZGVsZXRpb25zLCBvciBjaGFuZ2VzIHRvIHRoZSBvcmlnaW5hbCBmaWxlcwotbXVzdCBiZSBjbGVhcmx5IGluZGljYXRlZCBpbiBhY2NvbXBhbnlpbmcgZG9jdW1lbnRhdGlvbi4KLSgyKSBJZiBvbmx5IGV4ZWN1dGFibGUgY29kZSBpcyBkaXN0cmlidXRlZCwgdGhlbiB0aGUgYWNjb21wYW55aW5nCi1kb2N1bWVudGF0aW9uIG11c3Qgc3RhdGUgdGhhdCAidGhpcyBzb2Z0d2FyZSBpcyBiYXNlZCBpbiBwYXJ0IG9uIHRoZSB3b3JrIG9mCi10aGUgSW5kZXBlbmRlbnQgSlBFRyBHcm91cCIuCi0oMykgUGVybWlzc2lvbiBmb3IgdXNlIG9mIHRoaXMgc29mdHdhcmUgaXMgZ3JhbnRlZCBvbmx5IGlmIHRoZSB1c2VyIGFjY2VwdHMKLWZ1bGwgcmVzcG9uc2liaWxpdHkgZm9yIGFueSB1bmRlc2lyYWJsZSBjb25zZXF1ZW5jZXM7IHRoZSBhdXRob3JzIGFjY2VwdAotTk8gTElBQklMSVRZIGZvciBkYW1hZ2VzIG9mIGFueSBraW5kLgotCi1UaGVzZSBjb25kaXRpb25zIGFwcGx5IHRvIGFueSBzb2Z0d2FyZSBkZXJpdmVkIGZyb20gb3IgYmFzZWQgb24gdGhlIElKRyBjb2RlLAotbm90IGp1c3QgdG8gdGhlIHVubW9kaWZpZWQgbGlicmFyeS4gIElmIHlvdSB1c2Ugb3VyIHdvcmssIHlvdSBvdWdodCB0bwotYWNrbm93bGVkZ2UgdXMuCi0KLVBlcm1pc3Npb24gaXMgTk9UIGdyYW50ZWQgZm9yIHRoZSB1c2Ugb2YgYW55IElKRyBhdXRob3IncyBuYW1lIG9yIGNvbXBhbnkgbmFtZQotaW4gYWR2ZXJ0aXNpbmcgb3IgcHVibGljaXR5IHJlbGF0aW5nIHRvIHRoaXMgc29mdHdhcmUgb3IgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCi1pdC4gIFRoaXMgc29mdHdhcmUgbWF5IGJlIHJlZmVycmVkIHRvIG9ubHkgYXMgInRoZSBJbmRlcGVuZGVudCBKUEVHIEdyb3VwJ3MKLXNvZnR3YXJlIi4KLQotV2Ugc3BlY2lmaWNhbGx5IHBlcm1pdCBhbmQgZW5jb3VyYWdlIHRoZSB1c2Ugb2YgdGhpcyBzb2Z0d2FyZSBhcyB0aGUgYmFzaXMgb2YKLWNvbW1lcmNpYWwgcHJvZHVjdHMsIHByb3ZpZGVkIHRoYXQgYWxsIHdhcnJhbnR5IG9yIGxpYWJpbGl0eSBjbGFpbXMgYXJlCi1hc3N1bWVkIGJ5IHRoZSBwcm9kdWN0IHZlbmRvci4KLQotLS0tIGVuZCBvZiBMSUNFTlNFIC0tLQotCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotCi0lJSBUaGlzIG5vdGljZSBpcyBwcm92aWRlZCB3aXRoIHJlc3BlY3QgdG8gSm9uaSB2MS4xLjksIHdoaWNoIG1heSBiZSAKLWluY2x1ZGVkIHdpdGggSlJFIDgsIEpESyA4LCBhbmQgT3BlbkpESyA4LgotCi0tLS0gYmVnaW4gb2YgTElDRU5TRSAtLS0KLQotUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weQotb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgIlNvZnR3YXJlIiksIHRvIGRlYWwKLWluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMKLXRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwKLWNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcwotZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKLQotVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW4gYWxsCi1jb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLgotCi1USEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUgotSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksCi1GSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUKLUFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVIKLUxJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sCi1PVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRQotU09GVFdBUkUuCi0KLS0tLSBlbmQgb2YgTElDRU5TRSAtLS0KLQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotCi0lJSBUaGlzIG5vdGljZSBpcyBwcm92aWRlZCB3aXRoIHJlc3BlY3QgdG8gSk9wdC1TaW1wbGUgdjMuMCwgIHdoaWNoIG1heSBiZSAKLWluY2x1ZGVkIHdpdGggSlJFIDgsIEpESyA4LCBhbmQgT3BlbkpESyA4LgotCi0tLS0gYmVnaW4gb2YgTElDRU5TRSAtLS0KLQotIENvcHlyaWdodCAoYykgMjAwNC0yMDA5IFBhdWwgUi4gSG9sc2VyLCBKci4KLQotIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZwotIGEgY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZQotICJTb2Z0d2FyZSIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcKLSB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsCi0gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvCi0gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvCi0gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgotCi0gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUKLSBpbmNsdWRlZCBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS4KLQotIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAiQVMgSVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELAotIEVYUFJFU1MgT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRgotIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5ECi0gTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRQotIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04KLSBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04KLSBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS4KLQotLS0tIGVuZCBvZiBMSUNFTlNFIC0tLQotCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotCi0lJSBUaGlzIG5vdGljZSBpcyBwcm92aWRlZCB3aXRoIHJlc3BlY3QgdG8gS2VyYmVyb3MgZnVuY3Rpb25hbGl0eSwgd2hpY2ggCi13aGljaCBtYXkgYmUgaW5jbHVkZWQgd2l0aCBKUkUgOCwgSkRLIDgsIGFuZCBPcGVuSkRLIDguCi0KLS0tLSBiZWdpbiBvZiBMSUNFTlNFIC0tLQotCi0gKEMpIENvcHlyaWdodCBJQk0gQ29ycC4gMTk5OSBBbGwgUmlnaHRzIFJlc2VydmVkLgotIENvcHlyaWdodCAxOTk3IFRoZSBPcGVuIEdyb3VwIFJlc2VhcmNoIEluc3RpdHV0ZS4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLQotLS0tIGVuZCBvZiBMSUNFTlNFIC0tLQotCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0KLSUlIFRoaXMgbm90aWNlIGlzIHByb3ZpZGVkIHdpdGggcmVzcGVjdCB0byBLZXJiZXJvcyBmdW5jdGlvbmFsaXR5IGZyb20gCi1GdW5kc1hwcmVzcywgSU5DLiwgd2hpY2ggbWF5IGJlIGluY2x1ZGVkIHdpdGggSlJFIDgsIEpESyA4LCBhbmQgT3BlbkpESyA4LgotCi0tLS0gYmVnaW4gb2YgTElDRU5TRSAtLS0KLQotIENvcHlyaWdodCAoQykgMTk5OCBieSB0aGUgRnVuZHNYcHJlc3MsIElOQy4KLQotIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0KLSBFeHBvcnQgb2YgdGhpcyBzb2Z0d2FyZSBmcm9tIHRoZSBVbml0ZWQgU3RhdGVzIG9mIEFtZXJpY2EgbWF5IHJlcXVpcmUKLSBhIHNwZWNpZmljIGxpY2Vuc2UgZnJvbSB0aGUgVW5pdGVkIFN0YXRlcyBHb3Zlcm5tZW50LiAgSXQgaXMgdGhlCi0gcmVzcG9uc2liaWxpdHkgb2YgYW55IHBlcnNvbiBvciBvcmdhbml6YXRpb24gY29udGVtcGxhdGluZyBleHBvcnQgdG8KLSBvYnRhaW4gc3VjaCBhIGxpY2Vuc2UgYmVmb3JlIGV4cG9ydGluZy4KLQotIFdJVEhJTiBUSEFUIENPTlNUUkFJTlQsIHBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGFuZAotIGRpc3RyaWJ1dGUgdGhpcyBzb2Z0d2FyZSBhbmQgaXRzIGRvY3VtZW50YXRpb24gZm9yIGFueSBwdXJwb3NlIGFuZAotIHdpdGhvdXQgZmVlIGlzIGhlcmVieSBncmFudGVkLCBwcm92aWRlZCB0aGF0IHRoZSBhYm92ZSBjb3B5cmlnaHQKLSBub3RpY2UgYXBwZWFyIGluIGFsbCBjb3BpZXMgYW5kIHRoYXQgYm90aCB0aGF0IGNvcHlyaWdodCBub3RpY2UgYW5kCi0gdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBhcHBlYXIgaW4gc3VwcG9ydGluZyBkb2N1bWVudGF0aW9uLCBhbmQgdGhhdAotIHRoZSBuYW1lIG9mIEZ1bmRzWHByZXNzLiBub3QgYmUgdXNlZCBpbiBhZHZlcnRpc2luZyBvciBwdWJsaWNpdHkgcGVydGFpbmluZwotIHRvIGRpc3RyaWJ1dGlvbiBvZiB0aGUgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYywgd3JpdHRlbiBwcmlvcgotIHBlcm1pc3Npb24uICBGdW5kc1hwcmVzcyBtYWtlcyBubyByZXByZXNlbnRhdGlvbnMgYWJvdXQgdGhlIHN1aXRhYmlsaXR5IG9mCi0gdGhpcyBzb2Z0d2FyZSBmb3IgYW55IHB1cnBvc2UuICBJdCBpcyBwcm92aWRlZCAiYXMgaXMiIHdpdGhvdXQgZXhwcmVzcwotIG9yIGltcGxpZWQgd2FycmFudHkuCi0KLSBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUgotIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBXSVRIT1VUIExJTUlUQVRJT04sIFRIRSBJTVBMSUVECi0gV0FSUkFOVElFUyBPRiBNRVJDSEFOVElCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLgotCi0KLS0tLSBlbmQgb2YgTElDRU5TRSAtLS0KLQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotCi0lJSBUaGlzIG5vdGljZSBpcyBwcm92aWRlZCB3aXRoIHJlc3BlY3QgdG8gS3Jvbm9zIE9wZW5HTCBoZWFkZXJzLCB3aGljaCBtYXkgYmUgCi1pbmNsdWRlZCB3aXRoIEpESyA4IGFuZCBPcGVuSkRLIDggc291cmNlIGRpc3RyaWJ1dGlvbnMuCi0KLS0tLSBiZWdpbiBvZiBMSUNFTlNFIC0tLQotCi0gQ29weXJpZ2h0IChjKSAyMDA3IFRoZSBLaHJvbm9zIEdyb3VwIEluYy4KLQotIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHkKLSBvZiB0aGlzIHNvZnR3YXJlIGFuZC9vciBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSAiTWF0ZXJpYWxzIiksIHRvCi0gZGVhbCBpbiB0aGUgTWF0ZXJpYWxzIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlCi0gcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yCi0gc2VsbCBjb3BpZXMgb2YgdGhlIE1hdGVyaWFscywgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIE1hdGVyaWFscyBhcmUKLSBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgotCi0gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW4gYWxsCi0gY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBNYXRlcmlhbHMuCi0KLSBUSEUgTUFURVJJQUxTIEFSRSBQUk9WSURFRCAiQVMgSVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SCi0gSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksCi0gRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRQotIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVIKLSBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLAotIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIE1BVEVSSUFMUyBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRQotIE1BVEVSSUFMUy4KLQotLS0tIGVuZCBvZiBMSUNFTlNFIC0tLQotCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0KLSUlIFBvcnRpb25zIENvcHlyaWdodCBFYXN0bWFuIEtvZGFrIENvbXBhbnkgMTk5MgotCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0KLSUlIFRoaXMgbm90aWNlIGlzIHByb3ZpZGVkIHdpdGggcmVzcGVjdCB0byBsaWJwbmcgMS42LjE2LCB3aGljaCBtYXkgYmUgCi1pbmNsdWRlZCB3aXRoIEpSRSA4LCBKREsgOCwgYW5kIE9wZW5KREsgOC4KLQotLS0tIGJlZ2luIG9mIExJQ0VOU0UgLS0tCi0KLVRoaXMgY29weSBvZiB0aGUgbGlicG5nIG5vdGljZXMgaXMgcHJvdmlkZWQgZm9yIHlvdXIgY29udmVuaWVuY2UuICBJbiBjYXNlIG9mCi1hbnkgZGlzY3JlcGFuY3kgYmV0d2VlbiB0aGlzIGNvcHkgYW5kIHRoZSBub3RpY2VzIGluIHRoZSBmaWxlIHBuZy5oIHRoYXQgaXMKLWluY2x1ZGVkIGluIHRoZSBsaWJwbmcgZGlzdHJpYnV0aW9uLCB0aGUgbGF0dGVyIHNoYWxsIHByZXZhaWwuCi0KLUNPUFlSSUdIVCBOT1RJQ0UsIERJU0NMQUlNRVIsIGFuZCBMSUNFTlNFOgotCi1JZiB5b3UgbW9kaWZ5IGxpYnBuZyB5b3UgbWF5IGluc2VydCBhZGRpdGlvbmFsIG5vdGljZXMgaW1tZWRpYXRlbHkgZm9sbG93aW5nCi10aGlzIHNlbnRlbmNlLgotCi1UaGlzIGNvZGUgaXMgcmVsZWFzZWQgdW5kZXIgdGhlIGxpYnBuZyBsaWNlbnNlLgotCi1saWJwbmcgdmVyc2lvbnMgMS4yLjYsIEF1Z3VzdCAxNSwgMjAwNCwgdGhyb3VnaCAxLjYuMTYsIERlY2VtYmVyIDIyLCAyMDE0LCBhcmUKLUNvcHlyaWdodCAoYykgMjAwNCwgMjAwNi0yMDE0IEdsZW5uIFJhbmRlcnMtUGVocnNvbiwgYW5kIGFyZQotZGlzdHJpYnV0ZWQgYWNjb3JkaW5nIHRvIHRoZSBzYW1lIGRpc2NsYWltZXIgYW5kIGxpY2Vuc2UgYXMgbGlicG5nLTEuMi41Ci13aXRoIHRoZSBmb2xsb3dpbmcgaW5kaXZpZHVhbCBhZGRlZCB0byB0aGUgbGlzdCBvZiBDb250cmlidXRpbmcgQXV0aG9ycwotCi0gICBDb3NtaW4gVHJ1dGEKLQotbGlicG5nIHZlcnNpb25zIDEuMC43LCBKdWx5IDEsIDIwMDAsIHRocm91Z2ggMS4yLjUgLSBPY3RvYmVyIDMsIDIwMDIsIGFyZQotQ29weXJpZ2h0IChjKSAyMDAwLTIwMDIgR2xlbm4gUmFuZGVycy1QZWhyc29uLCBhbmQgYXJlCi1kaXN0cmlidXRlZCBhY2NvcmRpbmcgdG8gdGhlIHNhbWUgZGlzY2xhaW1lciBhbmQgbGljZW5zZSBhcyBsaWJwbmctMS4wLjYKLXdpdGggdGhlIGZvbGxvd2luZyBpbmRpdmlkdWFscyBhZGRlZCB0byB0aGUgbGlzdCBvZiBDb250cmlidXRpbmcgQXV0aG9ycwotCi0gICBTaW1vbi1QaWVycmUgQ2FkaWV1eAotICAgRXJpYyBTLiBSYXltb25kCi0gICBHaWxsZXMgVm9sbGFudAotCi1hbmQgd2l0aCB0aGUgZm9sbG93aW5nIGFkZGl0aW9ucyB0byB0aGUgZGlzY2xhaW1lcjoKLQotICAgVGhlcmUgaXMgbm8gd2FycmFudHkgYWdhaW5zdCBpbnRlcmZlcmVuY2Ugd2l0aCB5b3VyIGVuam95bWVudCBvZiB0aGUKLSAgIGxpYnJhcnkgb3IgYWdhaW5zdCBpbmZyaW5nZW1lbnQuICBUaGVyZSBpcyBubyB3YXJyYW50eSB0aGF0IG91cgotICAgZWZmb3J0cyBvciB0aGUgbGlicmFyeSB3aWxsIGZ1bGZpbGwgYW55IG9mIHlvdXIgcGFydGljdWxhciBwdXJwb3NlcwotICAgb3IgbmVlZHMuICBUaGlzIGxpYnJhcnkgaXMgcHJvdmlkZWQgd2l0aCBhbGwgZmF1bHRzLCBhbmQgdGhlIGVudGlyZQotICAgcmlzayBvZiBzYXRpc2ZhY3RvcnkgcXVhbGl0eSwgcGVyZm9ybWFuY2UsIGFjY3VyYWN5LCBhbmQgZWZmb3J0IGlzIHdpdGgKLSAgIHRoZSB1c2VyLgotCi1saWJwbmcgdmVyc2lvbnMgMC45NywgSmFudWFyeSAxOTk4LCB0aHJvdWdoIDEuMC42LCBNYXJjaCAyMCwgMjAwMCwgYXJlCi1Db3B5cmlnaHQgKGMpIDE5OTgsIDE5OTkgR2xlbm4gUmFuZGVycy1QZWhyc29uLCBhbmQgYXJlCi1kaXN0cmlidXRlZCBhY2NvcmRpbmcgdG8gdGhlIHNhbWUgZGlzY2xhaW1lciBhbmQgbGljZW5zZSBhcyBsaWJwbmctMC45NiwKLXdpdGggdGhlIGZvbGxvd2luZyBpbmRpdmlkdWFscyBhZGRlZCB0byB0aGUgbGlzdCBvZiBDb250cmlidXRpbmcgQXV0aG9yczoKLQotICAgVG9tIExhbmUKLSAgIEdsZW5uIFJhbmRlcnMtUGVocnNvbgotICAgV2lsbGVtIHZhbiBTY2hhaWsKLQotbGlicG5nIHZlcnNpb25zIDAuODksIEp1bmUgMTk5NiwgdGhyb3VnaCAwLjk2LCBNYXkgMTk5NywgYXJlCi1Db3B5cmlnaHQgKGMpIDE5OTYsIDE5OTcgQW5kcmVhcyBEaWxnZXIKLURpc3RyaWJ1dGVkIGFjY29yZGluZyB0byB0aGUgc2FtZSBkaXNjbGFpbWVyIGFuZCBsaWNlbnNlIGFzIGxpYnBuZy0wLjg4LAotd2l0aCB0aGUgZm9sbG93aW5nIGluZGl2aWR1YWxzIGFkZGVkIHRvIHRoZSBsaXN0IG9mIENvbnRyaWJ1dGluZyBBdXRob3JzOgotCi0gICBKb2huIEJvd2xlcgotICAgS2V2aW4gQnJhY2V5Ci0gICBTYW0gQnVzaGVsbAotICAgTWFnbnVzIEhvbG1ncmVuCi0gICBHcmVnIFJvZWxvZnMKLSAgIFRvbSBUYW5uZXIKLQotbGlicG5nIHZlcnNpb25zIDAuNSwgTWF5IDE5OTUsIHRocm91Z2ggMC44OCwgSmFudWFyeSAxOTk2LCBhcmUKLUNvcHlyaWdodCAoYykgMTk5NSwgMTk5NiBHdXkgRXJpYyBTY2hhbG5hdCwgR3JvdXAgNDIsIEluYy4KLQotRm9yIHRoZSBwdXJwb3NlcyBvZiB0aGlzIGNvcHlyaWdodCBhbmQgbGljZW5zZSwgIkNvbnRyaWJ1dGluZyBBdXRob3JzIgotaXMgZGVmaW5lZCBhcyB0aGUgZm9sbG93aW5nIHNldCBvZiBpbmRpdmlkdWFsczoKLQotICAgQW5kcmVhcyBEaWxnZXIKLSAgIERhdmUgTWFydGluZGFsZQotICAgR3V5IEVyaWMgU2NoYWxuYXQKLSAgIFBhdWwgU2NobWlkdAotICAgVGltIFdlZ25lcgotCi1UaGUgUE5HIFJlZmVyZW5jZSBMaWJyYXJ5IGlzIHN1cHBsaWVkICJBUyBJUyIuICBUaGUgQ29udHJpYnV0aW5nIEF1dGhvcnMKLWFuZCBHcm91cCA0MiwgSW5jLiBkaXNjbGFpbSBhbGwgd2FycmFudGllcywgZXhwcmVzc2VkIG9yIGltcGxpZWQsCi1pbmNsdWRpbmcsIHdpdGhvdXQgbGltaXRhdGlvbiwgdGhlIHdhcnJhbnRpZXMgb2YgbWVyY2hhbnRhYmlsaXR5IGFuZCBvZgotZml0bmVzcyBmb3IgYW55IHB1cnBvc2UuICBUaGUgQ29udHJpYnV0aW5nIEF1dGhvcnMgYW5kIEdyb3VwIDQyLCBJbmMuCi1hc3N1bWUgbm8gbGlhYmlsaXR5IGZvciBkaXJlY3QsIGluZGlyZWN0LCBpbmNpZGVudGFsLCBzcGVjaWFsLCBleGVtcGxhcnksCi1vciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsIHdoaWNoIG1heSByZXN1bHQgZnJvbSB0aGUgdXNlIG9mIHRoZSBQTkcKLVJlZmVyZW5jZSBMaWJyYXJ5LCBldmVuIGlmIGFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgotCi1QZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBhbmQgZGlzdHJpYnV0ZSB0aGlzCi1zb3VyY2UgY29kZSwgb3IgcG9ydGlvbnMgaGVyZW9mLCBmb3IgYW55IHB1cnBvc2UsIHdpdGhvdXQgZmVlLCBzdWJqZWN0Ci10byB0aGUgZm9sbG93aW5nIHJlc3RyaWN0aW9uczoKLQotMS4gVGhlIG9yaWdpbiBvZiB0aGlzIHNvdXJjZSBjb2RlIG11c3Qgbm90IGJlIG1pc3JlcHJlc2VudGVkLgotCi0yLiBBbHRlcmVkIHZlcnNpb25zIG11c3QgYmUgcGxhaW5seSBtYXJrZWQgYXMgc3VjaCBhbmQgbXVzdCBub3QKLSAgIGJlIG1pc3JlcHJlc2VudGVkIGFzIGJlaW5nIHRoZSBvcmlnaW5hbCBzb3VyY2UuCi0KLTMuIFRoaXMgQ29weXJpZ2h0IG5vdGljZSBtYXkgbm90IGJlIHJlbW92ZWQgb3IgYWx0ZXJlZCBmcm9tIGFueQotICAgc291cmNlIG9yIGFsdGVyZWQgc291cmNlIGRpc3RyaWJ1dGlvbi4KLQotVGhlIENvbnRyaWJ1dGluZyBBdXRob3JzIGFuZCBHcm91cCA0MiwgSW5jLiBzcGVjaWZpY2FsbHkgcGVybWl0LCB3aXRob3V0Ci1mZWUsIGFuZCBlbmNvdXJhZ2UgdGhlIHVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGFzIGEgY29tcG9uZW50IHRvCi1zdXBwb3J0aW5nIHRoZSBQTkcgZmlsZSBmb3JtYXQgaW4gY29tbWVyY2lhbCBwcm9kdWN0cy4gIElmIHlvdSB1c2UgdGhpcwotc291cmNlIGNvZGUgaW4gYSBwcm9kdWN0LCBhY2tub3dsZWRnbWVudCBpcyBub3QgcmVxdWlyZWQgYnV0IHdvdWxkIGJlCi1hcHByZWNpYXRlZC4KLQotCi1BICJwbmdfZ2V0X2NvcHlyaWdodCIgZnVuY3Rpb24gaXMgYXZhaWxhYmxlLCBmb3IgY29udmVuaWVudCB1c2UgaW4gImFib3V0IgotYm94ZXMgYW5kIHRoZSBsaWtlOgotCi0gICBwcmludGYoIiVzIixwbmdfZ2V0X2NvcHlyaWdodChOVUxMKSk7Ci0KLUFsc28sIHRoZSBQTkcgbG9nbyAoaW4gUE5HIGZvcm1hdCwgb2YgY291cnNlKSBpcyBzdXBwbGllZCBpbiB0aGUKLWZpbGVzICJwbmdiYXIucG5nIiBhbmQgInBuZ2Jhci5qcGcgKDg4eDMxKSBhbmQgInBuZ25vdy5wbmciICg5OHgzMSkuCi0KLUxpYnBuZyBpcyBPU0kgQ2VydGlmaWVkIE9wZW4gU291cmNlIFNvZnR3YXJlLiAgT1NJIENlcnRpZmllZCBPcGVuIFNvdXJjZSBpcyBhCi1jZXJ0aWZpY2F0aW9uIG1hcmsgb2YgdGhlIE9wZW4gU291cmNlIEluaXRpYXRpdmUuCi0KLUdsZW5uIFJhbmRlcnMtUGVocnNvbgotZ2xlbm5ycCBhdCB1c2Vycy5zb3VyY2Vmb3JnZS5uZXQKLURlY2VtYmVyIDIyLCAyMDE0Ci0KLS0tLSBlbmQgb2YgTElDRU5TRSAtLS0KLQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotCi0lJSBUaGlzIG5vdGljZSBpcyBwcm92aWRlZCB3aXRoIHJlc3BlY3QgdG8gR0lGTElCIDUuMS4xICYgbGlidW5naWYgNC4xLjMsIHdoaWNoIG1heSBiZSAKLWluY2x1ZGVkIHdpdGggSlJFIDgsIEpESyA4LCBhbmQgT3BlbkpESyA4LgotCi0tLS0gYmVnaW4gb2YgTElDRU5TRSAtLS0KLQotVGhlIEdJRkxJQiBkaXN0cmlidXRpb24gaXMgQ29weXJpZ2h0IChjKSAxOTk3ICBFcmljIFMuIFJheW1vbmQKLQotUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weQotb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgIlNvZnR3YXJlIiksIHRvIGRlYWwKLWluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMKLXRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwKLWNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcwotZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKLQotVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW4KLWFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLgotCi1USEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUgotSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksCi1GSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFCi1BVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSCi1MSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLAotT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTgotVEhFIFNPRlRXQVJFLgotCi0tLS0gZW5kIG9mIExJQ0VOU0UgLS0tCi0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLQotJSUgVGhpcyBub3RpY2UgaXMgcHJvdmlkZWQgd2l0aCByZXNwZWN0IHRvIExpdHRsZSBDTVMgMi43LCB3aGljaCBtYXkgYmUgCi1pbmNsdWRlZCB3aXRoIEpSRSA4LCBKREsgOCwgYW5kIE9wZW5KREsgOC4KLQotLS0tIGJlZ2luIG9mIExJQ0VOU0UgLS0tCi0KLUxpdHRsZSBDTVMKLUNvcHlyaWdodCAoYykgMTk5OC0yMDE1IE1hcnRpIE1hcmlhIFNhZ3VlcgotCi1QZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5Ci1vZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSAiU29mdHdhcmUiKSwgdG8gZGVhbAotaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cwotdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbAotY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzCi1mdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgotCi1UaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpbiBhbGwKLWNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuCi0KLVRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAiQVMgSVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SCi1JTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwKLUZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRQotQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUgotTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwKLU9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFCi1TT0ZUV0FSRS4KLQotLS0tIGVuZCBvZiBMSUNFTlNFIC0tLQotCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0KLSUlIEx1Y2lkYSBpcyBhIHJlZ2lzdGVyZWQgdHJhZGVtYXJrIG9yIHRyYWRlbWFyayBvZiBCaWdlbG93ICYgSG9sbWVzIGluIHRoZQotVS5TLiBhbmQgb3RoZXIgY291bnRyaWVzLgotCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0KLSUlIFRoaXMgbm90aWNlIGlzIHByb3ZpZGVkIHdpdGggcmVzcGVjdCB0byBNZXNhIDNEIEdyYXBoaWNzIExpYnJhcnkgdjQuMSwKLXdoaWNoIG1heSBiZSBpbmNsdWRlZCB3aXRoIEpSRSA4LCBKREsgOCwgYW5kIE9wZW5KREsgOCBzb3VyY2UgZGlzdHJpYnV0aW9ucy4KLQotLS0tIGJlZ2luIG9mIExJQ0VOU0UgLS0tCi0KLSBNZXNhIDMtRCBncmFwaGljcyBsaWJyYXJ5Ci0gVmVyc2lvbjogIDQuMQotCi0gQ29weXJpZ2h0IChDKSAxOTk5LTIwMDIgIEJyaWFuIFBhdWwgICBBbGwgUmlnaHRzIFJlc2VydmVkLgotCi0gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEKLSBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlICJTb2Z0d2FyZSIpLAotIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24KLSB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwKLSBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUKLSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgotCi0gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQKLSBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS4KLQotIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAiQVMgSVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTCi0gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksCi0gRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gIElOIE5PIEVWRU5UIFNIQUxMCi0gQlJJQU4gUEFVTCBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4KLSBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTgotIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuCi0KLS0tLSBlbmQgb2YgTElDRU5TRSAtLS0KLQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotCi0lJSBUaGlzIG5vdGljZSBpcyBwcm92aWRlZCB3aXRoIHJlc3BlY3QgdG8gTW96aWxsYSBOZXR3b3JrIFNlY3VyaXR5Ci1TZXJ2aWNlcyAoTlNTKSwgd2hpY2ggaXMgc3VwcGxpZWQgd2l0aCB0aGUgSkRLIHRlc3Qgc3VpdGUgaW4gdGhlIE9wZW5KREsKLXNvdXJjZSBjb2RlIHJlcG9zaXRvcnkuIEl0IGlzIGxpY2Vuc2VkIHVuZGVyIE1vemlsbGEgUHVibGljIExpY2Vuc2UgKE1QTCksCi12ZXJzaW9uIDIuMC4KLQotVGhlIE5TUyBsaWJyYXJpZXMgYXJlIHN1cHBsaWVkIGluIGV4ZWN1dGFibGUgZm9ybSwgYnVpbHQgZnJvbSB1bm1vZGlmaWVkCi1OU1Mgc291cmNlIGNvZGUgbGFiZWxlZCB3aXRoIHRoZSAiTlNTXzNfMTZfUlRNIiBIRyB0YWcuCi0KLVRoZSBOU1Mgc291cmNlIGNvZGUgaXMgYXZhaWxhYmxlIGluIHRoZSBPcGVuSkRLIHNvdXJjZSBjb2RlIHJlcG9zaXRvcnkgYXQ6Ci0gICAgamRrL3Rlc3Qvc3VuL3NlY3VyaXR5L3BrY3MxMS9uc3Mvc3JjCi0KLVRoZSBOU1MgbGlicmFyaWVzIGFyZSBhdmFpbGFibGUgaW4gdGhlIE9wZW5KREsgc291cmNlIGNvZGUgcmVwb3NpdG9yeSBhdDoKLSAgICBqZGsvdGVzdC9zdW4vc2VjdXJpdHkvcGtjczExL25zcy9saWIKLQotLS0tIGJlZ2luIG9mIExJQ0VOU0UgLS0tCi0KLU1vemlsbGEgUHVibGljIExpY2Vuc2UgVmVyc2lvbiAyLjAKLT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLQotMS4gRGVmaW5pdGlvbnMKLS0tLS0tLS0tLS0tLS0tCi0KLTEuMS4gIkNvbnRyaWJ1dG9yIgotICAgIG1lYW5zIGVhY2ggaW5kaXZpZHVhbCBvciBsZWdhbCBlbnRpdHkgdGhhdCBjcmVhdGVzLCBjb250cmlidXRlcyB0bwotICAgIHRoZSBjcmVhdGlvbiBvZiwgb3Igb3ducyBDb3ZlcmVkIFNvZnR3YXJlLgotCi0xLjIuICJDb250cmlidXRvciBWZXJzaW9uIgotICAgIG1lYW5zIHRoZSBjb21iaW5hdGlvbiBvZiB0aGUgQ29udHJpYnV0aW9ucyBvZiBvdGhlcnMgKGlmIGFueSkgdXNlZAotICAgIGJ5IGEgQ29udHJpYnV0b3IgYW5kIHRoYXQgcGFydGljdWxhciBDb250cmlidXRvcidzIENvbnRyaWJ1dGlvbi4KLQotMS4zLiAiQ29udHJpYnV0aW9uIgotICAgIG1lYW5zIENvdmVyZWQgU29mdHdhcmUgb2YgYSBwYXJ0aWN1bGFyIENvbnRyaWJ1dG9yLgotCi0xLjQuICJDb3ZlcmVkIFNvZnR3YXJlIgotICAgIG1lYW5zIFNvdXJjZSBDb2RlIEZvcm0gdG8gd2hpY2ggdGhlIGluaXRpYWwgQ29udHJpYnV0b3IgaGFzIGF0dGFjaGVkCi0gICAgdGhlIG5vdGljZSBpbiBFeGhpYml0IEEsIHRoZSBFeGVjdXRhYmxlIEZvcm0gb2Ygc3VjaCBTb3VyY2UgQ29kZQotICAgIEZvcm0sIGFuZCBNb2RpZmljYXRpb25zIG9mIHN1Y2ggU291cmNlIENvZGUgRm9ybSwgaW4gZWFjaCBjYXNlCi0gICAgaW5jbHVkaW5nIHBvcnRpb25zIHRoZXJlb2YuCi0KLTEuNS4gIkluY29tcGF0aWJsZSBXaXRoIFNlY29uZGFyeSBMaWNlbnNlcyIKLSAgICBtZWFucwotCi0gICAgKGEpIHRoYXQgdGhlIGluaXRpYWwgQ29udHJpYnV0b3IgaGFzIGF0dGFjaGVkIHRoZSBub3RpY2UgZGVzY3JpYmVkCi0gICAgICAgIGluIEV4aGliaXQgQiB0byB0aGUgQ292ZXJlZCBTb2Z0d2FyZTsgb3IKLQotICAgIChiKSB0aGF0IHRoZSBDb3ZlcmVkIFNvZnR3YXJlIHdhcyBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YKLSAgICAgICAgdmVyc2lvbiAxLjEgb3IgZWFybGllciBvZiB0aGUgTGljZW5zZSwgYnV0IG5vdCBhbHNvIHVuZGVyIHRoZQotICAgICAgICB0ZXJtcyBvZiBhIFNlY29uZGFyeSBMaWNlbnNlLgotCi0xLjYuICJFeGVjdXRhYmxlIEZvcm0iCi0gICAgbWVhbnMgYW55IGZvcm0gb2YgdGhlIHdvcmsgb3RoZXIgdGhhbiBTb3VyY2UgQ29kZSBGb3JtLgotCi0xLjcuICJMYXJnZXIgV29yayIKLSAgICBtZWFucyBhIHdvcmsgdGhhdCBjb21iaW5lcyBDb3ZlcmVkIFNvZnR3YXJlIHdpdGggb3RoZXIgbWF0ZXJpYWwsIGluIAotICAgIGEgc2VwYXJhdGUgZmlsZSBvciBmaWxlcywgdGhhdCBpcyBub3QgQ292ZXJlZCBTb2Z0d2FyZS4KLQotMS44LiAiTGljZW5zZSIKLSAgICBtZWFucyB0aGlzIGRvY3VtZW50LgotCi0xLjkuICJMaWNlbnNhYmxlIgotICAgIG1lYW5zIGhhdmluZyB0aGUgcmlnaHQgdG8gZ3JhbnQsIHRvIHRoZSBtYXhpbXVtIGV4dGVudCBwb3NzaWJsZSwKLSAgICB3aGV0aGVyIGF0IHRoZSB0aW1lIG9mIHRoZSBpbml0aWFsIGdyYW50IG9yIHN1YnNlcXVlbnRseSwgYW55IGFuZAotICAgIGFsbCBvZiB0aGUgcmlnaHRzIGNvbnZleWVkIGJ5IHRoaXMgTGljZW5zZS4KLQotMS4xMC4gIk1vZGlmaWNhdGlvbnMiCi0gICAgbWVhbnMgYW55IG9mIHRoZSBmb2xsb3dpbmc6Ci0KLSAgICAoYSkgYW55IGZpbGUgaW4gU291cmNlIENvZGUgRm9ybSB0aGF0IHJlc3VsdHMgZnJvbSBhbiBhZGRpdGlvbiB0bywKLSAgICAgICAgZGVsZXRpb24gZnJvbSwgb3IgbW9kaWZpY2F0aW9uIG9mIHRoZSBjb250ZW50cyBvZiBDb3ZlcmVkCi0gICAgICAgIFNvZnR3YXJlOyBvcgotCi0gICAgKGIpIGFueSBuZXcgZmlsZSBpbiBTb3VyY2UgQ29kZSBGb3JtIHRoYXQgY29udGFpbnMgYW55IENvdmVyZWQKLSAgICAgICAgU29mdHdhcmUuCi0KLTEuMTEuICJQYXRlbnQgQ2xhaW1zIiBvZiBhIENvbnRyaWJ1dG9yCi0gICAgbWVhbnMgYW55IHBhdGVudCBjbGFpbShzKSwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiwgbWV0aG9kLAotICAgIHByb2Nlc3MsIGFuZCBhcHBhcmF0dXMgY2xhaW1zLCBpbiBhbnkgcGF0ZW50IExpY2Vuc2FibGUgYnkgc3VjaAotICAgIENvbnRyaWJ1dG9yIHRoYXQgd291bGQgYmUgaW5mcmluZ2VkLCBidXQgZm9yIHRoZSBncmFudCBvZiB0aGUKLSAgICBMaWNlbnNlLCBieSB0aGUgbWFraW5nLCB1c2luZywgc2VsbGluZywgb2ZmZXJpbmcgZm9yIHNhbGUsIGhhdmluZwotICAgIG1hZGUsIGltcG9ydCwgb3IgdHJhbnNmZXIgb2YgZWl0aGVyIGl0cyBDb250cmlidXRpb25zIG9yIGl0cwotICAgIENvbnRyaWJ1dG9yIFZlcnNpb24uCi0KLTEuMTIuICJTZWNvbmRhcnkgTGljZW5zZSIKLSAgICBtZWFucyBlaXRoZXIgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLCBWZXJzaW9uIDIuMCwgdGhlIEdOVQotICAgIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLCBWZXJzaW9uIDIuMSwgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbAotICAgIFB1YmxpYyBMaWNlbnNlLCBWZXJzaW9uIDMuMCwgb3IgYW55IGxhdGVyIHZlcnNpb25zIG9mIHRob3NlCi0gICAgbGljZW5zZXMuCi0KLTEuMTMuICJTb3VyY2UgQ29kZSBGb3JtIgotICAgIG1lYW5zIHRoZSBmb3JtIG9mIHRoZSB3b3JrIHByZWZlcnJlZCBmb3IgbWFraW5nIG1vZGlmaWNhdGlvbnMuCi0KLTEuMTQuICJZb3UiIChvciAiWW91ciIpCi0gICAgbWVhbnMgYW4gaW5kaXZpZHVhbCBvciBhIGxlZ2FsIGVudGl0eSBleGVyY2lzaW5nIHJpZ2h0cyB1bmRlciB0aGlzCi0gICAgTGljZW5zZS4gRm9yIGxlZ2FsIGVudGl0aWVzLCAiWW91IiBpbmNsdWRlcyBhbnkgZW50aXR5IHRoYXQKLSAgICBjb250cm9scywgaXMgY29udHJvbGxlZCBieSwgb3IgaXMgdW5kZXIgY29tbW9uIGNvbnRyb2wgd2l0aCBZb3UuIEZvcgotICAgIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwgImNvbnRyb2wiIG1lYW5zIChhKSB0aGUgcG93ZXIsIGRpcmVjdAotICAgIG9yIGluZGlyZWN0LCB0byBjYXVzZSB0aGUgZGlyZWN0aW9uIG9yIG1hbmFnZW1lbnQgb2Ygc3VjaCBlbnRpdHksCi0gICAgd2hldGhlciBieSBjb250cmFjdCBvciBvdGhlcndpc2UsIG9yIChiKSBvd25lcnNoaXAgb2YgbW9yZSB0aGFuCi0gICAgZmlmdHkgcGVyY2VudCAoNTAlKSBvZiB0aGUgb3V0c3RhbmRpbmcgc2hhcmVzIG9yIGJlbmVmaWNpYWwKLSAgICBvd25lcnNoaXAgb2Ygc3VjaCBlbnRpdHkuCi0KLTIuIExpY2Vuc2UgR3JhbnRzIGFuZCBDb25kaXRpb25zCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotCi0yLjEuIEdyYW50cwotCi1FYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgWW91IGEgd29ybGQtd2lkZSwgcm95YWx0eS1mcmVlLAotbm9uLWV4Y2x1c2l2ZSBsaWNlbnNlOgotCi0oYSkgdW5kZXIgaW50ZWxsZWN0dWFsIHByb3BlcnR5IHJpZ2h0cyAob3RoZXIgdGhhbiBwYXRlbnQgb3IgdHJhZGVtYXJrKQotICAgIExpY2Vuc2FibGUgYnkgc3VjaCBDb250cmlidXRvciB0byB1c2UsIHJlcHJvZHVjZSwgbWFrZSBhdmFpbGFibGUsCi0gICAgbW9kaWZ5LCBkaXNwbGF5LCBwZXJmb3JtLCBkaXN0cmlidXRlLCBhbmQgb3RoZXJ3aXNlIGV4cGxvaXQgaXRzCi0gICAgQ29udHJpYnV0aW9ucywgZWl0aGVyIG9uIGFuIHVubW9kaWZpZWQgYmFzaXMsIHdpdGggTW9kaWZpY2F0aW9ucywgb3IKLSAgICBhcyBwYXJ0IG9mIGEgTGFyZ2VyIFdvcms7IGFuZAotCi0oYikgdW5kZXIgUGF0ZW50IENsYWltcyBvZiBzdWNoIENvbnRyaWJ1dG9yIHRvIG1ha2UsIHVzZSwgc2VsbCwgb2ZmZXIKLSAgICBmb3Igc2FsZSwgaGF2ZSBtYWRlLCBpbXBvcnQsIGFuZCBvdGhlcndpc2UgdHJhbnNmZXIgZWl0aGVyIGl0cwotICAgIENvbnRyaWJ1dGlvbnMgb3IgaXRzIENvbnRyaWJ1dG9yIFZlcnNpb24uCi0KLTIuMi4gRWZmZWN0aXZlIERhdGUKLQotVGhlIGxpY2Vuc2VzIGdyYW50ZWQgaW4gU2VjdGlvbiAyLjEgd2l0aCByZXNwZWN0IHRvIGFueSBDb250cmlidXRpb24KLWJlY29tZSBlZmZlY3RpdmUgZm9yIGVhY2ggQ29udHJpYnV0aW9uIG9uIHRoZSBkYXRlIHRoZSBDb250cmlidXRvciBmaXJzdAotZGlzdHJpYnV0ZXMgc3VjaCBDb250cmlidXRpb24uCi0KLTIuMy4gTGltaXRhdGlvbnMgb24gR3JhbnQgU2NvcGUKLQotVGhlIGxpY2Vuc2VzIGdyYW50ZWQgaW4gdGhpcyBTZWN0aW9uIDIgYXJlIHRoZSBvbmx5IHJpZ2h0cyBncmFudGVkIHVuZGVyCi10aGlzIExpY2Vuc2UuIE5vIGFkZGl0aW9uYWwgcmlnaHRzIG9yIGxpY2Vuc2VzIHdpbGwgYmUgaW1wbGllZCBmcm9tIHRoZQotZGlzdHJpYnV0aW9uIG9yIGxpY2Vuc2luZyBvZiBDb3ZlcmVkIFNvZnR3YXJlIHVuZGVyIHRoaXMgTGljZW5zZS4KLU5vdHdpdGhzdGFuZGluZyBTZWN0aW9uIDIuMShiKSBhYm92ZSwgbm8gcGF0ZW50IGxpY2Vuc2UgaXMgZ3JhbnRlZCBieSBhCi1Db250cmlidXRvcjoKLQotKGEpIGZvciBhbnkgY29kZSB0aGF0IGEgQ29udHJpYnV0b3IgaGFzIHJlbW92ZWQgZnJvbSBDb3ZlcmVkIFNvZnR3YXJlOwotICAgIG9yCi0KLShiKSBmb3IgaW5mcmluZ2VtZW50cyBjYXVzZWQgYnk6IChpKSBZb3VyIGFuZCBhbnkgb3RoZXIgdGhpcmQgcGFydHkncwotICAgIG1vZGlmaWNhdGlvbnMgb2YgQ292ZXJlZCBTb2Z0d2FyZSwgb3IgKGlpKSB0aGUgY29tYmluYXRpb24gb2YgaXRzCi0gICAgQ29udHJpYnV0aW9ucyB3aXRoIG90aGVyIHNvZnR3YXJlIChleGNlcHQgYXMgcGFydCBvZiBpdHMgQ29udHJpYnV0b3IKLSAgICBWZXJzaW9uKTsgb3IKLQotKGMpIHVuZGVyIFBhdGVudCBDbGFpbXMgaW5mcmluZ2VkIGJ5IENvdmVyZWQgU29mdHdhcmUgaW4gdGhlIGFic2VuY2Ugb2YKLSAgICBpdHMgQ29udHJpYnV0aW9ucy4KLQotVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IGFueSByaWdodHMgaW4gdGhlIHRyYWRlbWFya3MsIHNlcnZpY2UgbWFya3MsCi1vciBsb2dvcyBvZiBhbnkgQ29udHJpYnV0b3IgKGV4Y2VwdCBhcyBtYXkgYmUgbmVjZXNzYXJ5IHRvIGNvbXBseSB3aXRoCi10aGUgbm90aWNlIHJlcXVpcmVtZW50cyBpbiBTZWN0aW9uIDMuNCkuCi0KLTIuNC4gU3Vic2VxdWVudCBMaWNlbnNlcwotCi1ObyBDb250cmlidXRvciBtYWtlcyBhZGRpdGlvbmFsIGdyYW50cyBhcyBhIHJlc3VsdCBvZiBZb3VyIGNob2ljZSB0bwotZGlzdHJpYnV0ZSB0aGUgQ292ZXJlZCBTb2Z0d2FyZSB1bmRlciBhIHN1YnNlcXVlbnQgdmVyc2lvbiBvZiB0aGlzCi1MaWNlbnNlIChzZWUgU2VjdGlvbiAxMC4yKSBvciB1bmRlciB0aGUgdGVybXMgb2YgYSBTZWNvbmRhcnkgTGljZW5zZSAoaWYKLXBlcm1pdHRlZCB1bmRlciB0aGUgdGVybXMgb2YgU2VjdGlvbiAzLjMpLgotCi0yLjUuIFJlcHJlc2VudGF0aW9uCi0KLUVhY2ggQ29udHJpYnV0b3IgcmVwcmVzZW50cyB0aGF0IHRoZSBDb250cmlidXRvciBiZWxpZXZlcyBpdHMKLUNvbnRyaWJ1dGlvbnMgYXJlIGl0cyBvcmlnaW5hbCBjcmVhdGlvbihzKSBvciBpdCBoYXMgc3VmZmljaWVudCByaWdodHMKLXRvIGdyYW50IHRoZSByaWdodHMgdG8gaXRzIENvbnRyaWJ1dGlvbnMgY29udmV5ZWQgYnkgdGhpcyBMaWNlbnNlLgotCi0yLjYuIEZhaXIgVXNlCi0KLVRoaXMgTGljZW5zZSBpcyBub3QgaW50ZW5kZWQgdG8gbGltaXQgYW55IHJpZ2h0cyBZb3UgaGF2ZSB1bmRlcgotYXBwbGljYWJsZSBjb3B5cmlnaHQgZG9jdHJpbmVzIG9mIGZhaXIgdXNlLCBmYWlyIGRlYWxpbmcsIG9yIG90aGVyCi1lcXVpdmFsZW50cy4KLQotMi43LiBDb25kaXRpb25zCi0KLVNlY3Rpb25zIDMuMSwgMy4yLCAzLjMsIGFuZCAzLjQgYXJlIGNvbmRpdGlvbnMgb2YgdGhlIGxpY2Vuc2VzIGdyYW50ZWQKLWluIFNlY3Rpb24gMi4xLgotCi0zLiBSZXNwb25zaWJpbGl0aWVzCi0tLS0tLS0tLS0tLS0tLS0tLS0tCi0KLTMuMS4gRGlzdHJpYnV0aW9uIG9mIFNvdXJjZSBGb3JtCi0KLUFsbCBkaXN0cmlidXRpb24gb2YgQ292ZXJlZCBTb2Z0d2FyZSBpbiBTb3VyY2UgQ29kZSBGb3JtLCBpbmNsdWRpbmcgYW55Ci1Nb2RpZmljYXRpb25zIHRoYXQgWW91IGNyZWF0ZSBvciB0byB3aGljaCBZb3UgY29udHJpYnV0ZSwgbXVzdCBiZSB1bmRlcgotdGhlIHRlcm1zIG9mIHRoaXMgTGljZW5zZS4gWW91IG11c3QgaW5mb3JtIHJlY2lwaWVudHMgdGhhdCB0aGUgU291cmNlCi1Db2RlIEZvcm0gb2YgdGhlIENvdmVyZWQgU29mdHdhcmUgaXMgZ292ZXJuZWQgYnkgdGhlIHRlcm1zIG9mIHRoaXMKLUxpY2Vuc2UsIGFuZCBob3cgdGhleSBjYW4gb2J0YWluIGEgY29weSBvZiB0aGlzIExpY2Vuc2UuIFlvdSBtYXkgbm90Ci1hdHRlbXB0IHRvIGFsdGVyIG9yIHJlc3RyaWN0IHRoZSByZWNpcGllbnRzJyByaWdodHMgaW4gdGhlIFNvdXJjZSBDb2RlCi1Gb3JtLgotCi0zLjIuIERpc3RyaWJ1dGlvbiBvZiBFeGVjdXRhYmxlIEZvcm0KLQotSWYgWW91IGRpc3RyaWJ1dGUgQ292ZXJlZCBTb2Z0d2FyZSBpbiBFeGVjdXRhYmxlIEZvcm0gdGhlbjoKLQotKGEpIHN1Y2ggQ292ZXJlZCBTb2Z0d2FyZSBtdXN0IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgaW4gU291cmNlIENvZGUKLSAgICBGb3JtLCBhcyBkZXNjcmliZWQgaW4gU2VjdGlvbiAzLjEsIGFuZCBZb3UgbXVzdCBpbmZvcm0gcmVjaXBpZW50cyBvZgotICAgIHRoZSBFeGVjdXRhYmxlIEZvcm0gaG93IHRoZXkgY2FuIG9idGFpbiBhIGNvcHkgb2Ygc3VjaCBTb3VyY2UgQ29kZQotICAgIEZvcm0gYnkgcmVhc29uYWJsZSBtZWFucyBpbiBhIHRpbWVseSBtYW5uZXIsIGF0IGEgY2hhcmdlIG5vIG1vcmUKLSAgICB0aGFuIHRoZSBjb3N0IG9mIGRpc3RyaWJ1dGlvbiB0byB0aGUgcmVjaXBpZW50OyBhbmQKLQotKGIpIFlvdSBtYXkgZGlzdHJpYnV0ZSBzdWNoIEV4ZWN1dGFibGUgRm9ybSB1bmRlciB0aGUgdGVybXMgb2YgdGhpcwotICAgIExpY2Vuc2UsIG9yIHN1YmxpY2Vuc2UgaXQgdW5kZXIgZGlmZmVyZW50IHRlcm1zLCBwcm92aWRlZCB0aGF0IHRoZQotICAgIGxpY2Vuc2UgZm9yIHRoZSBFeGVjdXRhYmxlIEZvcm0gZG9lcyBub3QgYXR0ZW1wdCB0byBsaW1pdCBvciBhbHRlcgotICAgIHRoZSByZWNpcGllbnRzJyByaWdodHMgaW4gdGhlIFNvdXJjZSBDb2RlIEZvcm0gdW5kZXIgdGhpcyBMaWNlbnNlLgotCi0zLjMuIERpc3RyaWJ1dGlvbiBvZiBhIExhcmdlciBXb3JrCi0KLVlvdSBtYXkgY3JlYXRlIGFuZCBkaXN0cmlidXRlIGEgTGFyZ2VyIFdvcmsgdW5kZXIgdGVybXMgb2YgWW91ciBjaG9pY2UsCi1wcm92aWRlZCB0aGF0IFlvdSBhbHNvIGNvbXBseSB3aXRoIHRoZSByZXF1aXJlbWVudHMgb2YgdGhpcyBMaWNlbnNlIGZvcgotdGhlIENvdmVyZWQgU29mdHdhcmUuIElmIHRoZSBMYXJnZXIgV29yayBpcyBhIGNvbWJpbmF0aW9uIG9mIENvdmVyZWQKLVNvZnR3YXJlIHdpdGggYSB3b3JrIGdvdmVybmVkIGJ5IG9uZSBvciBtb3JlIFNlY29uZGFyeSBMaWNlbnNlcywgYW5kIHRoZQotQ292ZXJlZCBTb2Z0d2FyZSBpcyBub3QgSW5jb21wYXRpYmxlIFdpdGggU2Vjb25kYXJ5IExpY2Vuc2VzLCB0aGlzCi1MaWNlbnNlIHBlcm1pdHMgWW91IHRvIGFkZGl0aW9uYWxseSBkaXN0cmlidXRlIHN1Y2ggQ292ZXJlZCBTb2Z0d2FyZQotdW5kZXIgdGhlIHRlcm1zIG9mIHN1Y2ggU2Vjb25kYXJ5IExpY2Vuc2UocyksIHNvIHRoYXQgdGhlIHJlY2lwaWVudCBvZgotdGhlIExhcmdlciBXb3JrIG1heSwgYXQgdGhlaXIgb3B0aW9uLCBmdXJ0aGVyIGRpc3RyaWJ1dGUgdGhlIENvdmVyZWQKLVNvZnR3YXJlIHVuZGVyIHRoZSB0ZXJtcyBvZiBlaXRoZXIgdGhpcyBMaWNlbnNlIG9yIHN1Y2ggU2Vjb25kYXJ5Ci1MaWNlbnNlKHMpLgotCi0zLjQuIE5vdGljZXMKLQotWW91IG1heSBub3QgcmVtb3ZlIG9yIGFsdGVyIHRoZSBzdWJzdGFuY2Ugb2YgYW55IGxpY2Vuc2Ugbm90aWNlcwotKGluY2x1ZGluZyBjb3B5cmlnaHQgbm90aWNlcywgcGF0ZW50IG5vdGljZXMsIGRpc2NsYWltZXJzIG9mIHdhcnJhbnR5LAotb3IgbGltaXRhdGlvbnMgb2YgbGlhYmlsaXR5KSBjb250YWluZWQgd2l0aGluIHRoZSBTb3VyY2UgQ29kZSBGb3JtIG9mCi10aGUgQ292ZXJlZCBTb2Z0d2FyZSwgZXhjZXB0IHRoYXQgWW91IG1heSBhbHRlciBhbnkgbGljZW5zZSBub3RpY2VzIHRvCi10aGUgZXh0ZW50IHJlcXVpcmVkIHRvIHJlbWVkeSBrbm93biBmYWN0dWFsIGluYWNjdXJhY2llcy4KLQotMy41LiBBcHBsaWNhdGlvbiBvZiBBZGRpdGlvbmFsIFRlcm1zCi0KLVlvdSBtYXkgY2hvb3NlIHRvIG9mZmVyLCBhbmQgdG8gY2hhcmdlIGEgZmVlIGZvciwgd2FycmFudHksIHN1cHBvcnQsCi1pbmRlbW5pdHkgb3IgbGlhYmlsaXR5IG9ibGlnYXRpb25zIHRvIG9uZSBvciBtb3JlIHJlY2lwaWVudHMgb2YgQ292ZXJlZAotU29mdHdhcmUuIEhvd2V2ZXIsIFlvdSBtYXkgZG8gc28gb25seSBvbiBZb3VyIG93biBiZWhhbGYsIGFuZCBub3Qgb24KLWJlaGFsZiBvZiBhbnkgQ29udHJpYnV0b3IuIFlvdSBtdXN0IG1ha2UgaXQgYWJzb2x1dGVseSBjbGVhciB0aGF0IGFueQotc3VjaCB3YXJyYW50eSwgc3VwcG9ydCwgaW5kZW1uaXR5LCBvciBsaWFiaWxpdHkgb2JsaWdhdGlvbiBpcyBvZmZlcmVkIGJ5Ci1Zb3UgYWxvbmUsIGFuZCBZb3UgaGVyZWJ5IGFncmVlIHRvIGluZGVtbmlmeSBldmVyeSBDb250cmlidXRvciBmb3IgYW55Ci1saWFiaWxpdHkgaW5jdXJyZWQgYnkgc3VjaCBDb250cmlidXRvciBhcyBhIHJlc3VsdCBvZiB3YXJyYW50eSwgc3VwcG9ydCwKLWluZGVtbml0eSBvciBsaWFiaWxpdHkgdGVybXMgWW91IG9mZmVyLiBZb3UgbWF5IGluY2x1ZGUgYWRkaXRpb25hbAotZGlzY2xhaW1lcnMgb2Ygd2FycmFudHkgYW5kIGxpbWl0YXRpb25zIG9mIGxpYWJpbGl0eSBzcGVjaWZpYyB0byBhbnkKLWp1cmlzZGljdGlvbi4KLQotNC4gSW5hYmlsaXR5IHRvIENvbXBseSBEdWUgdG8gU3RhdHV0ZSBvciBSZWd1bGF0aW9uCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLQotSWYgaXQgaXMgaW1wb3NzaWJsZSBmb3IgWW91IHRvIGNvbXBseSB3aXRoIGFueSBvZiB0aGUgdGVybXMgb2YgdGhpcwotTGljZW5zZSB3aXRoIHJlc3BlY3QgdG8gc29tZSBvciBhbGwgb2YgdGhlIENvdmVyZWQgU29mdHdhcmUgZHVlIHRvCi1zdGF0dXRlLCBqdWRpY2lhbCBvcmRlciwgb3IgcmVndWxhdGlvbiB0aGVuIFlvdSBtdXN0OiAoYSkgY29tcGx5IHdpdGgKLXRoZSB0ZXJtcyBvZiB0aGlzIExpY2Vuc2UgdG8gdGhlIG1heGltdW0gZXh0ZW50IHBvc3NpYmxlOyBhbmQgKGIpCi1kZXNjcmliZSB0aGUgbGltaXRhdGlvbnMgYW5kIHRoZSBjb2RlIHRoZXkgYWZmZWN0LiBTdWNoIGRlc2NyaXB0aW9uIG11c3QKLWJlIHBsYWNlZCBpbiBhIHRleHQgZmlsZSBpbmNsdWRlZCB3aXRoIGFsbCBkaXN0cmlidXRpb25zIG9mIHRoZSBDb3ZlcmVkCi1Tb2Z0d2FyZSB1bmRlciB0aGlzIExpY2Vuc2UuIEV4Y2VwdCB0byB0aGUgZXh0ZW50IHByb2hpYml0ZWQgYnkgc3RhdHV0ZQotb3IgcmVndWxhdGlvbiwgc3VjaCBkZXNjcmlwdGlvbiBtdXN0IGJlIHN1ZmZpY2llbnRseSBkZXRhaWxlZCBmb3IgYQotcmVjaXBpZW50IG9mIG9yZGluYXJ5IHNraWxsIHRvIGJlIGFibGUgdG8gdW5kZXJzdGFuZCBpdC4KLQotNS4gVGVybWluYXRpb24KLS0tLS0tLS0tLS0tLS0tCi0KLTUuMS4gVGhlIHJpZ2h0cyBncmFudGVkIHVuZGVyIHRoaXMgTGljZW5zZSB3aWxsIHRlcm1pbmF0ZSBhdXRvbWF0aWNhbGx5Ci1pZiBZb3UgZmFpbCB0byBjb21wbHkgd2l0aCBhbnkgb2YgaXRzIHRlcm1zLiBIb3dldmVyLCBpZiBZb3UgYmVjb21lCi1jb21wbGlhbnQsIHRoZW4gdGhlIHJpZ2h0cyBncmFudGVkIHVuZGVyIHRoaXMgTGljZW5zZSBmcm9tIGEgcGFydGljdWxhcgotQ29udHJpYnV0b3IgYXJlIHJlaW5zdGF0ZWQgKGEpIHByb3Zpc2lvbmFsbHksIHVubGVzcyBhbmQgdW50aWwgc3VjaAotQ29udHJpYnV0b3IgZXhwbGljaXRseSBhbmQgZmluYWxseSB0ZXJtaW5hdGVzIFlvdXIgZ3JhbnRzLCBhbmQgKGIpIG9uIGFuCi1vbmdvaW5nIGJhc2lzLCBpZiBzdWNoIENvbnRyaWJ1dG9yIGZhaWxzIHRvIG5vdGlmeSBZb3Ugb2YgdGhlCi1ub24tY29tcGxpYW5jZSBieSBzb21lIHJlYXNvbmFibGUgbWVhbnMgcHJpb3IgdG8gNjAgZGF5cyBhZnRlciBZb3UgaGF2ZQotY29tZSBiYWNrIGludG8gY29tcGxpYW5jZS4gTW9yZW92ZXIsIFlvdXIgZ3JhbnRzIGZyb20gYSBwYXJ0aWN1bGFyCi1Db250cmlidXRvciBhcmUgcmVpbnN0YXRlZCBvbiBhbiBvbmdvaW5nIGJhc2lzIGlmIHN1Y2ggQ29udHJpYnV0b3IKLW5vdGlmaWVzIFlvdSBvZiB0aGUgbm9uLWNvbXBsaWFuY2UgYnkgc29tZSByZWFzb25hYmxlIG1lYW5zLCB0aGlzIGlzIHRoZQotZmlyc3QgdGltZSBZb3UgaGF2ZSByZWNlaXZlZCBub3RpY2Ugb2Ygbm9uLWNvbXBsaWFuY2Ugd2l0aCB0aGlzIExpY2Vuc2UKLWZyb20gc3VjaCBDb250cmlidXRvciwgYW5kIFlvdSBiZWNvbWUgY29tcGxpYW50IHByaW9yIHRvIDMwIGRheXMgYWZ0ZXIKLVlvdXIgcmVjZWlwdCBvZiB0aGUgbm90aWNlLgotCi01LjIuIElmIFlvdSBpbml0aWF0ZSBsaXRpZ2F0aW9uIGFnYWluc3QgYW55IGVudGl0eSBieSBhc3NlcnRpbmcgYSBwYXRlbnQKLWluZnJpbmdlbWVudCBjbGFpbSAoZXhjbHVkaW5nIGRlY2xhcmF0b3J5IGp1ZGdtZW50IGFjdGlvbnMsCi1jb3VudGVyLWNsYWltcywgYW5kIGNyb3NzLWNsYWltcykgYWxsZWdpbmcgdGhhdCBhIENvbnRyaWJ1dG9yIFZlcnNpb24KLWRpcmVjdGx5IG9yIGluZGlyZWN0bHkgaW5mcmluZ2VzIGFueSBwYXRlbnQsIHRoZW4gdGhlIHJpZ2h0cyBncmFudGVkIHRvCi1Zb3UgYnkgYW55IGFuZCBhbGwgQ29udHJpYnV0b3JzIGZvciB0aGUgQ292ZXJlZCBTb2Z0d2FyZSB1bmRlciBTZWN0aW9uCi0yLjEgb2YgdGhpcyBMaWNlbnNlIHNoYWxsIHRlcm1pbmF0ZS4KLQotNS4zLiBJbiB0aGUgZXZlbnQgb2YgdGVybWluYXRpb24gdW5kZXIgU2VjdGlvbnMgNS4xIG9yIDUuMiBhYm92ZSwgYWxsCi1lbmQgdXNlciBsaWNlbnNlIGFncmVlbWVudHMgKGV4Y2x1ZGluZyBkaXN0cmlidXRvcnMgYW5kIHJlc2VsbGVycykgd2hpY2gKLWhhdmUgYmVlbiB2YWxpZGx5IGdyYW50ZWQgYnkgWW91IG9yIFlvdXIgZGlzdHJpYnV0b3JzIHVuZGVyIHRoaXMgTGljZW5zZQotcHJpb3IgdG8gdGVybWluYXRpb24gc2hhbGwgc3Vydml2ZSB0ZXJtaW5hdGlvbi4KLQotKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKLSogIDYuIERpc2NsYWltZXIgb2YgV2FycmFudHkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKgotKiAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqCi0qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKLSogIENvdmVyZWQgU29mdHdhcmUgaXMgcHJvdmlkZWQgdW5kZXIgdGhpcyBMaWNlbnNlIG9uIGFuICJhcyBpcyIgICAgICAgKgotKiAgYmFzaXMsIHdpdGhvdXQgd2FycmFudHkgb2YgYW55IGtpbmQsIGVpdGhlciBleHByZXNzZWQsIGltcGxpZWQsIG9yICAqCi0qICBzdGF0dXRvcnksIGluY2x1ZGluZywgd2l0aG91dCBsaW1pdGF0aW9uLCB3YXJyYW50aWVzIHRoYXQgdGhlICAgICAgICoKLSogIENvdmVyZWQgU29mdHdhcmUgaXMgZnJlZSBvZiBkZWZlY3RzLCBtZXJjaGFudGFibGUsIGZpdCBmb3IgYSAgICAgICAgKgotKiAgcGFydGljdWxhciBwdXJwb3NlIG9yIG5vbi1pbmZyaW5naW5nLiBUaGUgZW50aXJlIHJpc2sgYXMgdG8gdGhlICAgICAqCi0qICBxdWFsaXR5IGFuZCBwZXJmb3JtYW5jZSBvZiB0aGUgQ292ZXJlZCBTb2Z0d2FyZSBpcyB3aXRoIFlvdS4gICAgICAgICoKLSogIFNob3VsZCBhbnkgQ292ZXJlZCBTb2Z0d2FyZSBwcm92ZSBkZWZlY3RpdmUgaW4gYW55IHJlc3BlY3QsIFlvdSAgICAgKgotKiAgKG5vdCBhbnkgQ29udHJpYnV0b3IpIGFzc3VtZSB0aGUgY29zdCBvZiBhbnkgbmVjZXNzYXJ5IHNlcnZpY2luZywgICAqCi0qICByZXBhaXIsIG9yIGNvcnJlY3Rpb24uIFRoaXMgZGlzY2xhaW1lciBvZiB3YXJyYW50eSBjb25zdGl0dXRlcyBhbiAgICoKLSogIGVzc2VudGlhbCBwYXJ0IG9mIHRoaXMgTGljZW5zZS4gTm8gdXNlIG9mIGFueSBDb3ZlcmVkIFNvZnR3YXJlIGlzICAgKgotKiAgYXV0aG9yaXplZCB1bmRlciB0aGlzIExpY2Vuc2UgZXhjZXB0IHVuZGVyIHRoaXMgZGlzY2xhaW1lci4gICAgICAgICAqCi0qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKLSoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgotCi0qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLSogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKgotKiAgNy4gTGltaXRhdGlvbiBvZiBMaWFiaWxpdHkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqCi0qICAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKLSogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKgotKiAgVW5kZXIgbm8gY2lyY3Vtc3RhbmNlcyBhbmQgdW5kZXIgbm8gbGVnYWwgdGhlb3J5LCB3aGV0aGVyIHRvcnQgICAgICAqCi0qICAoaW5jbHVkaW5nIG5lZ2xpZ2VuY2UpLCBjb250cmFjdCwgb3Igb3RoZXJ3aXNlLCBzaGFsbCBhbnkgICAgICAgICAgICoKLSogIENvbnRyaWJ1dG9yLCBvciBhbnlvbmUgd2hvIGRpc3RyaWJ1dGVzIENvdmVyZWQgU29mdHdhcmUgYXMgICAgICAgICAgKgotKiAgcGVybWl0dGVkIGFib3ZlLCBiZSBsaWFibGUgdG8gWW91IGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgICAgICAgICAqCi0qICBzcGVjaWFsLCBpbmNpZGVudGFsLCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMgb2YgYW55IGNoYXJhY3RlciAgICAgICoKLSogIGluY2x1ZGluZywgd2l0aG91dCBsaW1pdGF0aW9uLCBkYW1hZ2VzIGZvciBsb3N0IHByb2ZpdHMsIGxvc3Mgb2YgICAgKgotKiAgZ29vZHdpbGwsIHdvcmsgc3RvcHBhZ2UsIGNvbXB1dGVyIGZhaWx1cmUgb3IgbWFsZnVuY3Rpb24sIG9yIGFueSAgICAqCi0qICBhbmQgYWxsIG90aGVyIGNvbW1lcmNpYWwgZGFtYWdlcyBvciBsb3NzZXMsIGV2ZW4gaWYgc3VjaCBwYXJ0eSAgICAgICoKLSogIHNoYWxsIGhhdmUgYmVlbiBpbmZvcm1lZCBvZiB0aGUgcG9zc2liaWxpdHkgb2Ygc3VjaCBkYW1hZ2VzLiBUaGlzICAgKgotKiAgbGltaXRhdGlvbiBvZiBsaWFiaWxpdHkgc2hhbGwgbm90IGFwcGx5IHRvIGxpYWJpbGl0eSBmb3IgZGVhdGggb3IgICAqCi0qICBwZXJzb25hbCBpbmp1cnkgcmVzdWx0aW5nIGZyb20gc3VjaCBwYXJ0eSdzIG5lZ2xpZ2VuY2UgdG8gdGhlICAgICAgICoKLSogIGV4dGVudCBhcHBsaWNhYmxlIGxhdyBwcm9oaWJpdHMgc3VjaCBsaW1pdGF0aW9uLiBTb21lICAgICAgICAgICAgICAgKgotKiAganVyaXNkaWN0aW9ucyBkbyBub3QgYWxsb3cgdGhlIGV4Y2x1c2lvbiBvciBsaW1pdGF0aW9uIG9mICAgICAgICAgICAqCi0qICBpbmNpZGVudGFsIG9yIGNvbnNlcXVlbnRpYWwgZGFtYWdlcywgc28gdGhpcyBleGNsdXNpb24gYW5kICAgICAgICAgICoKLSogIGxpbWl0YXRpb24gbWF5IG5vdCBhcHBseSB0byBZb3UuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKgotKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqCi0qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLQotOC4gTGl0aWdhdGlvbgotLS0tLS0tLS0tLS0tLQotCi1BbnkgbGl0aWdhdGlvbiByZWxhdGluZyB0byB0aGlzIExpY2Vuc2UgbWF5IGJlIGJyb3VnaHQgb25seSBpbiB0aGUKLWNvdXJ0cyBvZiBhIGp1cmlzZGljdGlvbiB3aGVyZSB0aGUgZGVmZW5kYW50IG1haW50YWlucyBpdHMgcHJpbmNpcGFsCi1wbGFjZSBvZiBidXNpbmVzcyBhbmQgc3VjaCBsaXRpZ2F0aW9uIHNoYWxsIGJlIGdvdmVybmVkIGJ5IGxhd3Mgb2YgdGhhdAotanVyaXNkaWN0aW9uLCB3aXRob3V0IHJlZmVyZW5jZSB0byBpdHMgY29uZmxpY3Qtb2YtbGF3IHByb3Zpc2lvbnMuCi1Ob3RoaW5nIGluIHRoaXMgU2VjdGlvbiBzaGFsbCBwcmV2ZW50IGEgcGFydHkncyBhYmlsaXR5IHRvIGJyaW5nCi1jcm9zcy1jbGFpbXMgb3IgY291bnRlci1jbGFpbXMuCi0KLTkuIE1pc2NlbGxhbmVvdXMKLS0tLS0tLS0tLS0tLS0tLS0KLQotVGhpcyBMaWNlbnNlIHJlcHJlc2VudHMgdGhlIGNvbXBsZXRlIGFncmVlbWVudCBjb25jZXJuaW5nIHRoZSBzdWJqZWN0Ci1tYXR0ZXIgaGVyZW9mLiBJZiBhbnkgcHJvdmlzaW9uIG9mIHRoaXMgTGljZW5zZSBpcyBoZWxkIHRvIGJlCi11bmVuZm9yY2VhYmxlLCBzdWNoIHByb3Zpc2lvbiBzaGFsbCBiZSByZWZvcm1lZCBvbmx5IHRvIHRoZSBleHRlbnQKLW5lY2Vzc2FyeSB0byBtYWtlIGl0IGVuZm9yY2VhYmxlLiBBbnkgbGF3IG9yIHJlZ3VsYXRpb24gd2hpY2ggcHJvdmlkZXMKLXRoYXQgdGhlIGxhbmd1YWdlIG9mIGEgY29udHJhY3Qgc2hhbGwgYmUgY29uc3RydWVkIGFnYWluc3QgdGhlIGRyYWZ0ZXIKLXNoYWxsIG5vdCBiZSB1c2VkIHRvIGNvbnN0cnVlIHRoaXMgTGljZW5zZSBhZ2FpbnN0IGEgQ29udHJpYnV0b3IuCi0KLTEwLiBWZXJzaW9ucyBvZiB0aGUgTGljZW5zZQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0KLTEwLjEuIE5ldyBWZXJzaW9ucwotCi1Nb3ppbGxhIEZvdW5kYXRpb24gaXMgdGhlIGxpY2Vuc2Ugc3Rld2FyZC4gRXhjZXB0IGFzIHByb3ZpZGVkIGluIFNlY3Rpb24KLTEwLjMsIG5vIG9uZSBvdGhlciB0aGFuIHRoZSBsaWNlbnNlIHN0ZXdhcmQgaGFzIHRoZSByaWdodCB0byBtb2RpZnkgb3IKLXB1Ymxpc2ggbmV3IHZlcnNpb25zIG9mIHRoaXMgTGljZW5zZS4gRWFjaCB2ZXJzaW9uIHdpbGwgYmUgZ2l2ZW4gYQotZGlzdGluZ3Vpc2hpbmcgdmVyc2lvbiBudW1iZXIuCi0KLTEwLjIuIEVmZmVjdCBvZiBOZXcgVmVyc2lvbnMKLQotWW91IG1heSBkaXN0cmlidXRlIHRoZSBDb3ZlcmVkIFNvZnR3YXJlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgdmVyc2lvbgotb2YgdGhlIExpY2Vuc2UgdW5kZXIgd2hpY2ggWW91IG9yaWdpbmFsbHkgcmVjZWl2ZWQgdGhlIENvdmVyZWQgU29mdHdhcmUsCi1vciB1bmRlciB0aGUgdGVybXMgb2YgYW55IHN1YnNlcXVlbnQgdmVyc2lvbiBwdWJsaXNoZWQgYnkgdGhlIGxpY2Vuc2UKLXN0ZXdhcmQuCi0KLTEwLjMuIE1vZGlmaWVkIFZlcnNpb25zCi0KLUlmIHlvdSBjcmVhdGUgc29mdHdhcmUgbm90IGdvdmVybmVkIGJ5IHRoaXMgTGljZW5zZSwgYW5kIHlvdSB3YW50IHRvCi1jcmVhdGUgYSBuZXcgbGljZW5zZSBmb3Igc3VjaCBzb2Z0d2FyZSwgeW91IG1heSBjcmVhdGUgYW5kIHVzZSBhCi1tb2RpZmllZCB2ZXJzaW9uIG9mIHRoaXMgTGljZW5zZSBpZiB5b3UgcmVuYW1lIHRoZSBsaWNlbnNlIGFuZCByZW1vdmUKLWFueSByZWZlcmVuY2VzIHRvIHRoZSBuYW1lIG9mIHRoZSBsaWNlbnNlIHN0ZXdhcmQgKGV4Y2VwdCB0byBub3RlIHRoYXQKLXN1Y2ggbW9kaWZpZWQgbGljZW5zZSBkaWZmZXJzIGZyb20gdGhpcyBMaWNlbnNlKS4KLQotMTAuNC4gRGlzdHJpYnV0aW5nIFNvdXJjZSBDb2RlIEZvcm0gdGhhdCBpcyBJbmNvbXBhdGlibGUgV2l0aCBTZWNvbmRhcnkKLUxpY2Vuc2VzCi0KLUlmIFlvdSBjaG9vc2UgdG8gZGlzdHJpYnV0ZSBTb3VyY2UgQ29kZSBGb3JtIHRoYXQgaXMgSW5jb21wYXRpYmxlIFdpdGgKLVNlY29uZGFyeSBMaWNlbnNlcyB1bmRlciB0aGUgdGVybXMgb2YgdGhpcyB2ZXJzaW9uIG9mIHRoZSBMaWNlbnNlLCB0aGUKLW5vdGljZSBkZXNjcmliZWQgaW4gRXhoaWJpdCBCIG9mIHRoaXMgTGljZW5zZSBtdXN0IGJlIGF0dGFjaGVkLgotCi1FeGhpYml0IEEgLSBTb3VyY2UgQ29kZSBGb3JtIExpY2Vuc2UgTm90aWNlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0KLSAgVGhpcyBTb3VyY2UgQ29kZSBGb3JtIGlzIHN1YmplY3QgdG8gdGhlIHRlcm1zIG9mIHRoZSBNb3ppbGxhIFB1YmxpYwotICBMaWNlbnNlLCB2LiAyLjAuIElmIGEgY29weSBvZiB0aGUgTVBMIHdhcyBub3QgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzCi0gIGZpbGUsIFlvdSBjYW4gb2J0YWluIG9uZSBhdCBodHRwOi8vbW96aWxsYS5vcmcvTVBMLzIuMC8uCi0KLUlmIGl0IGlzIG5vdCBwb3NzaWJsZSBvciBkZXNpcmFibGUgdG8gcHV0IHRoZSBub3RpY2UgaW4gYSBwYXJ0aWN1bGFyCi1maWxlLCB0aGVuIFlvdSBtYXkgaW5jbHVkZSB0aGUgbm90aWNlIGluIGEgbG9jYXRpb24gKHN1Y2ggYXMgYSBMSUNFTlNFCi1maWxlIGluIGEgcmVsZXZhbnQgZGlyZWN0b3J5KSB3aGVyZSBhIHJlY2lwaWVudCB3b3VsZCBiZSBsaWtlbHkgdG8gbG9vawotZm9yIHN1Y2ggYSBub3RpY2UuCi0KLVlvdSBtYXkgYWRkIGFkZGl0aW9uYWwgYWNjdXJhdGUgbm90aWNlcyBvZiBjb3B5cmlnaHQgb3duZXJzaGlwLgotCi1FeGhpYml0IEIgLSAiSW5jb21wYXRpYmxlIFdpdGggU2Vjb25kYXJ5IExpY2Vuc2VzIiBOb3RpY2UKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotCi0gIFRoaXMgU291cmNlIENvZGUgRm9ybSBpcyAiSW5jb21wYXRpYmxlIFdpdGggU2Vjb25kYXJ5IExpY2Vuc2VzIiwgYXMKLSAgZGVmaW5lZCBieSB0aGUgTW96aWxsYSBQdWJsaWMgTGljZW5zZSwgdi4gMi4wLgotCi0tLS0gZW5kIG9mIExJQ0VOU0UgLS0tCi0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLQotJSUgVGhpcyBub3RpY2UgaXMgcHJvdmlkZWQgd2l0aCByZXNwZWN0IHRvIFBDL1NDIExpdGUgZm9yIFN1c2UgTGludXggdi4xLjEuMSwKLXdoaWNoIG1heSBiZSBpbmNsdWRlZCB3aXRoIEpSRSA4LCBKREsgOCwgYW5kIE9wZW5KREsgOCBvbiBMaW51eCBhbmQgU29sYXJpcy4KLQotLS0tIGJlZ2luIG9mIExJQ0VOU0UgLS0tCi0KLUNvcHlyaWdodCAoYykgMTk5OS0yMDA0IERhdmlkIENvcmNvcmFuIDxjb3Jjb3JhbkBsaW51eG5ldC5jb20+Ci1Db3B5cmlnaHQgKGMpIDE5OTktMjAwNCBMdWRvdmljIFJvdXNzZWF1IDxsdWRvdmljLnJvdXNzZWF1IChhdCkgZnJlZS5mcj4KLUFsbCByaWdodHMgcmVzZXJ2ZWQuCi0KLVJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi1hcmUgbWV0OgotCi0xLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGUKLSAgIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uCi0zLiBBbGwgYWR2ZXJ0aXNpbmcgbWF0ZXJpYWxzIG1lbnRpb25pbmcgZmVhdHVyZXMgb3IgdXNlIG9mIHRoaXMgc29mdHdhcmUKLSAgIG11c3QgZGlzcGxheSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdlbWVudDoKLSAgICAgVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieTogCi0gICAgICBEYXZpZCBDb3Jjb3JhbiA8Y29yY29yYW5AbGludXhuZXQuY29tPgotICAgICAgaHR0cDovL3d3dy5saW51eG5ldC5jb20gKE1VU0NMRSkKLTQuIFRoZSBuYW1lIG9mIHRoZSBhdXRob3IgbWF5IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCi0KLUNoYW5nZXMgdG8gdGhpcyBsaWNlbnNlIGNhbiBiZSBtYWRlIG9ubHkgYnkgdGhlIGNvcHlyaWdodCBhdXRob3Igd2l0aCAKLWV4cGxpY2l0IHdyaXR0ZW4gY29uc2VudC4KLQotVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQVVUSE9SIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1MgT1IKLUlNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLU9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuCi1JTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsCi1JTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQKLU5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKLURBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQotVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAotKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GCi1USElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgotCi0tLS0gZW5kIG9mIExJQ0VOU0UgLS0tCi0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLQotJSUgVGhpcyBub3RpY2UgaXMgcHJvdmlkZWQgd2l0aCByZXNwZWN0IHRvIFBvcnRlclN0ZW1tZXIgdjQsIHdoaWNoIG1heSBiZSAKLWluY2x1ZGVkIHdpdGggSlJFIDgsIEpESyA4LCBhbmQgT3BlbkpESyA4LgotCi0tLS0gYmVnaW4gb2YgTElDRU5TRSAtLS0KLQotU2VlOiBodHRwOi8vdGFydGFydXMub3JnL35tYXJ0aW4vUG9ydGVyU3RlbW1lcgotCi1UaGUgc29mdHdhcmUgaXMgY29tcGxldGVseSBmcmVlIGZvciBhbnkgcHVycG9zZSwgdW5sZXNzIG5vdGVzIGF0IHRoZSBoZWFkIG9mCi10aGUgcHJvZ3JhbSB0ZXh0IGluZGljYXRlcyBvdGhlcndpc2UgKHdoaWNoIGlzIHJhcmUpLiBJbiBhbnkgY2FzZSwgdGhlIG5vdGVzCi1hYm91dCBsaWNlbnNpbmcgYXJlIG5ldmVyIG1vcmUgcmVzdHJpY3RpdmUgdGhhbiB0aGUgQlNEIExpY2Vuc2UuCi0KLUluIGV2ZXJ5IGNhc2Ugd2hlcmUgdGhlIHNvZnR3YXJlIGlzIG5vdCB3cml0dGVuIGJ5IG1lIChNYXJ0aW4gUG9ydGVyKSwgdGhpcwotbGljZW5zaW5nIGFycmFuZ2VtZW50IGhhcyBiZWVuIGVuZG9yc2VkIGJ5IHRoZSBjb250cmlidXRvciwgYW5kIGl0IGlzCi10aGVyZWZvcmUgdW5uZWNlc3NhcnkgdG8gYXNrIHRoZSBjb250cmlidXRvciBhZ2FpbiB0byBjb25maXJtIGl0LgotCi1JIGhhdmUgbm90IGFza2VkIGFueSBjb250cmlidXRvcnMgKG9yIHRoZWlyIGVtcGxveWVycywgaWYgdGhleSBoYXZlIHRoZW0pIGZvcgotcHJvb2ZzIHRoYXQgdGhleSBoYXZlIHRoZSByaWdodCB0byBkaXN0cmlidXRlIHRoZWlyIHNvZnR3YXJlIGluIHRoaXMgd2F5LgotCi0tLS0gZW5kIG9mIExJQ0VOU0UgLS0tCi0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLQotJSUgVGhpcyBub3RpY2UgaXMgcHJvdmlkZWQgd2l0aCByZXNwZWN0IHRvIFJlbGF4IE5HIE9iamVjdC9QYXJzZXIgdi4yMDA1MDUxMCwKLXdoaWNoIG1heSBiZSBpbmNsdWRlZCB3aXRoIEpSRSA4LCBKREsgOCwgYW5kIE9wZW5KREsgOC4KLQotLS0tIGJlZ2luIG9mIExJQ0VOU0UgLS0tCi0KLUNvcHlyaWdodCAoYykgS29oc3VrZSBLYXdhZ3VjaGkKLQotUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weQotb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgIlNvZnR3YXJlIiksIHRvIGRlYWwKLWluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMKLXRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwKLWNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcwotZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczogVGhlIGFib3ZlIGNvcHlyaWdodAotbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluIGFsbCBjb3BpZXMgb3IKLXN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS4KLQotVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyBJUyIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1IKLUlNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLAotRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFCi1BVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSCi1MSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLAotT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUKLVNPRlRXQVJFLgotCi0tLS0gZW5kIG9mIExJQ0VOU0UgLS0tCi0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLQotJSUgVGhpcyBub3RpY2UgaXMgcHJvdmlkZWQgd2l0aCByZXNwZWN0IHRvIFJlbGF4TkdDQyB2MS4xMiwgd2hpY2ggbWF5IGJlIAotaW5jbHVkZWQgd2l0aCBKUkUgOCwgSkRLIDgsIGFuZCBPcGVuSkRLIDguCi0KLS0tLSBiZWdpbiBvZiBMSUNFTlNFIC0tLQotCi1Db3B5cmlnaHQgKGMpIDIwMDAtMjAwMyBEYWlzdWtlIE9rYWppbWEgYW5kIEtvaHN1a2UgS2F3YWd1Y2hpLiAgCi1BbGwgcmlnaHRzIHJlc2VydmVkLgotCi1SZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLW1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OgotCi0xLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXMKLSAgIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotCi0yLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsCi0gICB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uCi0gICBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi4KLQotMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sIGlmIGFueSwgbXVzdAotICAgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotCi0gICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgRGFpc3VrZSBPa2FqaW1hCi0gICAgYW5kIEtvaHN1a2UgS2F3YWd1Y2hpIChodHRwOi8vcmVsYXhuZ2NjLnNmLm5ldC8pLiIKLQotQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLCBpZiBhbmQKLXdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLQotNC4gVGhlIG5hbWVzIG9mIHRoZSBjb3B5cmlnaHQgaG9sZGVycyBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZQotICAgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCB0aGUgY29weXJpZ2h0IGhvbGRlcnMuCi0KLTUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJSRUxBWE5HQ0MiLCBub3IgbWF5Ci0gICJSRUxBWE5HQ0MiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUKLSAgY29weXJpZ2h0IGhvbGRlcnMuCi0KLVRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsCi1JTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5ECi1GSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC5JTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFCi1TT0ZUV0FSRSBGT1VOREFUSU9OIE9SIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwKLUlOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLUxJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUgotUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRgotTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcKLU5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwKLUVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCi0KLS0tLSBlbmQgb2YgTElDRU5TRSAtLS0KLQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotCi0lJSBUaGlzIG5vdGljZSBpcyBwcm92aWRlZCB3aXRoIHJlc3BlY3QgdG8gU0FYIDIuMC4xLCB3aGljaCBtYXkgYmUgaW5jbHVkZWQgCi13aXRoIEpSRSA4LCBKREsgOCwgYW5kIE9wZW5KREsgOC4KLQotLS0tIGJlZ2luIG9mIExJQ0VOU0UgLS0tCi0KLSBTQVggaXMgZnJlZSEKLQotIEluIGZhY3QsIGl0J3Mgbm90IHBvc3NpYmxlIHRvIG93biBhIGxpY2Vuc2UgdG8gU0FYLCBzaW5jZSBpdCdzIGJlZW4gcGxhY2VkIGluCi0gdGhlIHB1YmxpYyBkb21haW4uCi0KLSBObyBXYXJyYW50eQotCi0gQmVjYXVzZSBTQVggaXMgcmVsZWFzZWQgdG8gdGhlIHB1YmxpYyBkb21haW4sIHRoZXJlIGlzIG5vIHdhcnJhbnR5IGZvciB0aGUKLSBkZXNpZ24gb3IgZm9yIHRoZSBzb2Z0d2FyZSBpbXBsZW1lbnRhdGlvbiwgdG8gdGhlIGV4dGVudCBwZXJtaXR0ZWQgYnkKLSBhcHBsaWNhYmxlIGxhdy4gRXhjZXB0IHdoZW4gb3RoZXJ3aXNlIHN0YXRlZCBpbiB3cml0aW5nIHRoZSBjb3B5cmlnaHQgaG9sZGVycwotIGFuZC9vciBvdGhlciBwYXJ0aWVzIHByb3ZpZGUgU0FYICJhcyBpcyIgd2l0aG91dCB3YXJyYW50eSBvZiBhbnkga2luZCwgZWl0aGVyCi0gZXhwcmVzc2VkIG9yIGltcGxpZWQsIGluY2x1ZGluZywgYnV0IG5vdCBsaW1pdGVkIHRvLCB0aGUgaW1wbGllZCB3YXJyYW50aWVzCi0gb2YgbWVyY2hhbnRhYmlsaXR5IGFuZCBmaXRuZXNzIGZvciBhIHBhcnRpY3VsYXIgcHVycG9zZS4gVGhlIGVudGlyZSByaXNrIGFzCi0gdG8gdGhlIHF1YWxpdHkgYW5kIHBlcmZvcm1hbmNlIG9mIFNBWCBpcyB3aXRoIHlvdS4gU2hvdWxkIFNBWCBwcm92ZQotIGRlZmVjdGl2ZSwgeW91IGFzc3VtZSB0aGUgY29zdCBvZiBhbGwgbmVjZXNzYXJ5IHNlcnZpY2luZywgcmVwYWlyIG9yCi0gY29ycmVjdGlvbi4KLQotIEluIG5vIGV2ZW50IHVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZyB3aWxsCi0gYW55IGNvcHlyaWdodCBob2xkZXIsIG9yIGFueSBvdGhlciBwYXJ0eSB3aG8gbWF5IG1vZGlmeSBhbmQvb3IgcmVkaXN0cmlidXRlCi0gU0FYLCBiZSBsaWFibGUgdG8geW91IGZvciBkYW1hZ2VzLCBpbmNsdWRpbmcgYW55IGdlbmVyYWwsIHNwZWNpYWwsIGluY2lkZW50YWwKLSBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMgYXJpc2luZyBvdXQgb2YgdGhlIHVzZSBvciBpbmFiaWxpdHkgdG8gdXNlIFNBWAotIChpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIGxvc3Mgb2YgZGF0YSBvciBkYXRhIGJlaW5nIHJlbmRlcmVkIGluYWNjdXJhdGUKLSBvciBsb3NzZXMgc3VzdGFpbmVkIGJ5IHlvdSBvciB0aGlyZCBwYXJ0aWVzIG9yIGEgZmFpbHVyZSBvZiB0aGUgU0FYIHRvCi0gb3BlcmF0ZSB3aXRoIGFueSBvdGhlciBwcm9ncmFtcyksIGV2ZW4gaWYgc3VjaCBob2xkZXIgb3Igb3RoZXIgcGFydHkgaGFzIGJlZW4KLSBhZHZpc2VkIG9mIHRoZSBwb3NzaWJpbGl0eSBvZiBzdWNoIGRhbWFnZXMuCi0KLSBDb3B5cmlnaHQgRGlzY2xhaW1lcnMgCi0KLSBUaGlzIHBhZ2UgaW5jbHVkZXMgc3RhdGVtZW50cyB0byB0aGF0IGVmZmVjdCBieSBEYXZpZCBNZWdnaW5zb24sIHdobyB3b3VsZAotIGhhdmUgYmVlbiBhYmxlIHRvIGNsYWltIGNvcHlyaWdodCBmb3IgdGhlIG9yaWdpbmFsIHdvcmsuICBTQVggMS4wCi0KLSBWZXJzaW9uIDEuMCBvZiB0aGUgU2ltcGxlIEFQSSBmb3IgWE1MIChTQVgpLCBjcmVhdGVkIGNvbGxlY3RpdmVseSBieSB0aGUKLSBtZW1iZXJzaGlwIG9mIHRoZSBYTUwtREVWIG1haWxpbmcgbGlzdCwgaXMgaGVyZWJ5IHJlbGVhc2VkIGludG8gdGhlIHB1YmxpYwotIGRvbWFpbi4KLQotIE5vIG9uZSBvd25zIFNBWDogeW91IG1heSB1c2UgaXQgZnJlZWx5IGluIGJvdGggY29tbWVyY2lhbCBhbmQgbm9uLWNvbW1lcmNpYWwKLSBhcHBsaWNhdGlvbnMsIGJ1bmRsZSBpdCB3aXRoIHlvdXIgc29mdHdhcmUgZGlzdHJpYnV0aW9uLCBpbmNsdWRlIGl0IG9uIGEKLSBDRC1ST00sIGxpc3QgdGhlIHNvdXJjZSBjb2RlIGluIGEgYm9vaywgbWlycm9yIHRoZSBkb2N1bWVudGF0aW9uIGF0IHlvdXIgb3duCi0gd2ViIHNpdGUsIG9yIHVzZSBpdCBpbiBhbnkgb3RoZXIgd2F5IHlvdSBzZWUgZml0LgotCi0gRGF2aWQgTWVnZ2luc29uLCBzYXhAbWVnZ2luc29uLmNvbQotIDE5OTgtMDUtMTEKLQotIFNBWCAyLjAgCi0KLSBJIGhlcmVieSBhYmFuZG9uIGFueSBwcm9wZXJ0eSByaWdodHMgdG8gU0FYIDIuMCAodGhlIFNpbXBsZSBBUEkgZm9yIFhNTCksIGFuZAotIHJlbGVhc2UgYWxsIG9mIHRoZSBTQVggMi4wIHNvdXJjZSBjb2RlLCBjb21waWxlZCBjb2RlLCBhbmQgZG9jdW1lbnRhdGlvbgotIGNvbnRhaW5lZCBpbiB0aGlzIGRpc3RyaWJ1dGlvbiBpbnRvIHRoZSBQdWJsaWMgRG9tYWluLiBTQVggY29tZXMgd2l0aCBOTwotIFdBUlJBTlRZIG9yIGd1YXJhbnRlZSBvZiBmaXRuZXNzIGZvciBhbnkgcHVycG9zZS4KLQotIERhdmlkIE1lZ2dpbnNvbiwgZGF2aWRAbWVnZ2luc29uLmNvbQotIDIwMDAtMDUtMDUKLQotLS0tIGVuZCBvZiBMSUNFTlNFIC0tLQotCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0KLSUlIFRoaXMgbm90aWNlIGlzIHByb3ZpZGVkIHdpdGggcmVzcGVjdCB0byBTb2Z0RmxvYXQgdmVyc2lvbiAyYiwgd2hpY2ggbWF5IGJlIAotaW5jbHVkZWQgd2l0aCBKUkUgOCwgSkRLIDgsIGFuZCBPcGVuSkRLIDggb24gTGludXgvQVJNLgotCi0tLS0gYmVnaW4gb2YgTElDRU5TRSAtLS0KLQotVXNlIG9mIGFueSBvZiB0aGlzIHNvZnR3YXJlIGlzIGdvdmVybmVkIGJ5IHRoZSB0ZXJtcyBvZiB0aGUgbGljZW5zZSBiZWxvdzoKLQotU29mdEZsb2F0IHdhcyB3cml0dGVuIGJ5IG1lLCBKb2huIFIuIEhhdXNlci4gVGhpcyB3b3JrIHdhcyBtYWRlIHBvc3NpYmxlIGluIAotcGFydCBieSB0aGUgSW50ZXJuYXRpb25hbCBDb21wdXRlciBTY2llbmNlIEluc3RpdHV0ZSwgbG9jYXRlZCBhdCBTdWl0ZSA2MDAsIAotMTk0NyBDZW50ZXIgU3RyZWV0LCBCZXJrZWxleSwgQ2FsaWZvcm5pYSA5NDcwNC4gRnVuZGluZyB3YXMgcGFydGlhbGx5IAotcHJvdmlkZWQgYnkgdGhlIE5hdGlvbmFsIFNjaWVuY2UgRm91bmRhdGlvbiB1bmRlciBncmFudCBNSVAtOTMxMTk4MC4gVGhlIAotb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGlzIGNvZGUgd2FzIHdyaXR0ZW4gYXMgcGFydCBvZiBhIHByb2plY3QgdG8gYnVpbGQgCi1hIGZpeGVkLXBvaW50IHZlY3RvciBwcm9jZXNzb3IgaW4gY29sbGFib3JhdGlvbiB3aXRoIHRoZSBVbml2ZXJzaXR5IG9mIAotQ2FsaWZvcm5pYSBhdCBCZXJrZWxleSwgb3ZlcnNlZW4gYnkgUHJvZnMuIE5lbHNvbiBNb3JnYW4gYW5kIEpvaG4gV2F3cnp5bmVrLiAKLQotVEhJUyBTT0ZUV0FSRSBJUyBESVNUUklCVVRFRCBBUyBJUywgRk9SIEZSRUUuIEFsdGhvdWdoIHJlYXNvbmFibGUgZWZmb3J0IAotaGFzIGJlZW4gbWFkZSB0byBhdm9pZCBpdCwgVEhJUyBTT0ZUV0FSRSBNQVkgQ09OVEFJTiBGQVVMVFMgVEhBVCBXSUxMIEFUIAotVElNRVMgUkVTVUxUIElOIElOQ09SUkVDVCBCRUhBVklPUi4gVVNFIE9GIFRISVMgU09GVFdBUkUgSVMgUkVTVFJJQ1RFRCBUTyAKLVBFUlNPTlMgQU5EIE9SR0FOSVpBVElPTlMgV0hPIENBTiBBTkQgV0lMTCBUQUtFIEZVTEwgUkVTUE9OU0lCSUxJVFkgRk9SIEFMTCAKLUxPU1NFUywgQ09TVFMsIE9SIE9USEVSIFBST0JMRU1TIFRIRVkgSU5DVVIgRFVFIFRPIFRIRSBTT0ZUV0FSRSwgQU5EIFdITyAKLUZVUlRIRVJNT1JFIEVGRkVDVElWRUxZIElOREVNTklGWSBKT0hOIEhBVVNFUiBBTkQgVEhFIElOVEVSTkFUSU9OQUwgQ09NUFVURVIgCi1TQ0lFTkNFIElOU1RJVFVURSAocG9zc2libHkgdmlhIHNpbWlsYXIgbGVnYWwgd2FybmluZykgQUdBSU5TVCBBTEwgTE9TU0VTLCAKLUNPU1RTLCBPUiBPVEhFUiBQUk9CTEVNUyBJTkNVUlJFRCBCWSBUSEVJUiBDVVNUT01FUlMgQU5EIENMSUVOVFMgRFVFIFRPIFRIRSAKLVNPRlRXQVJFLiAKLQotRGVyaXZhdGl2ZSB3b3JrcyBhcmUgYWNjZXB0YWJsZSwgZXZlbiBmb3IgY29tbWVyY2lhbCBwdXJwb3NlcywgcHJvdmlkZWQgCi10aGF0IHRoZSBtaW5pbWFsIGRvY3VtZW50YXRpb24gcmVxdWlyZW1lbnRzIHN0YXRlZCBpbiB0aGUgc291cmNlIGNvZGUgYXJlIAotc2F0aXNmaWVkLiAKLQotLS0tIGVuZCBvZiBMSUNFTlNFIC0tLQotCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0KLSUlIFRoaXMgbm90aWNlIGlzIHByb3ZpZGVkIHdpdGggcmVzcGVjdCB0byBTcGFya2xlIDEuNSwKLXdoaWNoIG1heSBiZSBpbmNsdWRlZCB3aXRoIEpSRSA4IG9uIE1hYyBPUyBYLgotCi0tLS0gYmVnaW4gb2YgTElDRU5TRSAtLS0KLQotQ29weXJpZ2h0IChjKSAyMDEyIFNwYXJrbGUub3JnIGFuZCBBbmR5IE1hdHVzY2hhawotCi1QZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5Ci1vZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSAiU29mdHdhcmUiKSwgdG8gZGVhbAotaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cwotdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbAotY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzCi1mdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgotCi1UaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpbiBhbGwKLWNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuCi0KLVRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAiQVMgSVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SCi1JTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwKLUZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRQotQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUgotTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwKLU9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFCi1TT0ZUV0FSRS4KLQotLS0tIGVuZCBvZiBMSUNFTlNFIC0tLQotCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0KLSUlIFBvcnRpb25zIGxpY2Vuc2VkIGZyb20gVGFsaWdlbnQsIEluYy4KLQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotCi0lJSBUaGlzIG5vdGljZSBpcyBwcm92aWRlZCB3aXRoIHJlc3BlY3QgdG8gVGhhaSBEaWN0aW9uYXJ5LCB3aGljaCBtYXkgYmUgCi1pbmNsdWRlZCB3aXRoIEpSRSA4LCBKREsgOCwgYW5kIE9wZW5KREsgOC4KLQotLS0tIGJlZ2luIG9mIExJQ0VOU0UgLS0tCi0KLUNvcHlyaWdodCAoQykgMTk4MiBUaGUgUm95YWwgSW5zdGl0dXRlLCBUaGFpIFJveWFsIEdvdmVybm1lbnQuCi0KLUNvcHlyaWdodCAoQykgMTk5OCBOYXRpb25hbCBFbGVjdHJvbmljcyBhbmQgQ29tcHV0ZXIgVGVjaG5vbG9neSBDZW50ZXIsCi1OYXRpb25hbCBTY2llbmNlIGFuZCBUZWNobm9sb2d5IERldmVsb3BtZW50IEFnZW5jeSwKLU1pbmlzdHJ5IG9mIFNjaWVuY2UgVGVjaG5vbG9neSBhbmQgRW52aXJvbm1lbnQsCi1UaGFpIFJveWFsIEdvdmVybm1lbnQuCi0KLVBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHkKLW9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlICJTb2Z0d2FyZSIpLCB0byBkZWFsCi1pbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzCi10byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsCi1jb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMKLWZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6Ci0KLVRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluIGFsbAotY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS4KLQotVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyBJUyIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1IKLUlNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLAotRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFCi1BVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSCi1MSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLAotT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUKLVNPRlRXQVJFLgotCi0tLS0gZW5kIG9mIExJQ0VOU0UgLS0tCi0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLQotJSUgVGhpcyBub3RpY2UgaXMgcHJvdmlkZWQgd2l0aCByZXNwZWN0IHRvIFVuaWNvZGUgNi4yLjAgJiBDTERSIDIxLjAuMQotd2hpY2ggbWF5IGJlIGluY2x1ZGVkIHdpdGggSlJFIDgsIEpESyA4LCBhbmQgT3BlbkpESyA4LgotCi0tLS0gYmVnaW4gb2YgTElDRU5TRSAtLS0KLQotVW5pY29kZSBUZXJtcyBvZiBVc2UKLQotRm9yIHRoZSBnZW5lcmFsIHByaXZhY3kgcG9saWN5IGdvdmVybmluZyBhY2Nlc3MgdG8gdGhpcyBzaXRlLCBzZWUgdGhlIFVuaWNvZGUKLVByaXZhY3kgUG9saWN5LiBGb3IgdHJhZGVtYXJrIHVzYWdlLCBzZWUgdGhlIFVuaWNvZGXCriBDb25zb3J0aXVtIE5hbWUgYW5kCi1UcmFkZW1hcmsgVXNhZ2UgUG9saWN5LgotCi1BLiBVbmljb2RlIENvcHlyaWdodC4KLSAgIDEuIENvcHlyaWdodCDCqSAxOTkxLTIwMTMgVW5pY29kZSwgSW5jLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotCi0gICAyLiBDZXJ0YWluIGRvY3VtZW50cyBhbmQgZmlsZXMgb24gdGhpcyB3ZWJzaXRlIGNvbnRhaW4gYSBsZWdlbmQgaW5kaWNhdGluZwotICAgICAgdGhhdCAiTW9kaWZpY2F0aW9uIGlzIHBlcm1pdHRlZC4iIEFueSBwZXJzb24gaXMgaGVyZWJ5IGF1dGhvcml6ZWQsCi0gICAgICB3aXRob3V0IGZlZSwgdG8gbW9kaWZ5IHN1Y2ggZG9jdW1lbnRzIGFuZCBmaWxlcyB0byBjcmVhdGUgZGVyaXZhdGl2ZQotICAgICAgd29ya3MgY29uZm9ybWluZyB0byB0aGUgVW5pY29kZcKuIFN0YW5kYXJkLCBzdWJqZWN0IHRvIFRlcm1zIGFuZAotICAgICAgQ29uZGl0aW9ucyBoZXJlaW4uCi0KLSAgICAzLiBBbnkgcGVyc29uIGlzIGhlcmVieSBhdXRob3JpemVkLCB3aXRob3V0IGZlZSwgdG8gdmlldywgdXNlLCByZXByb2R1Y2UsCi0gICAgICAgYW5kIGRpc3RyaWJ1dGUgYWxsIGRvY3VtZW50cyBhbmQgZmlsZXMgc29sZWx5IGZvciBpbmZvcm1hdGlvbmFsCi0gICAgICAgcHVycG9zZXMgaW4gdGhlIGNyZWF0aW9uIG9mIHByb2R1Y3RzIHN1cHBvcnRpbmcgdGhlIFVuaWNvZGUgU3RhbmRhcmQsCi0gICAgICAgc3ViamVjdCB0byB0aGUgVGVybXMgYW5kIENvbmRpdGlvbnMgaGVyZWluLgotCi0gICAgNC4gRnVydGhlciBzcGVjaWZpY2F0aW9ucyBvZiByaWdodHMgYW5kIHJlc3RyaWN0aW9ucyBwZXJ0YWluaW5nIHRvIHRoZSB1c2UKLSAgICAgICBvZiB0aGUgcGFydGljdWxhciBzZXQgb2YgZGF0YSBmaWxlcyBrbm93biBhcyB0aGUgIlVuaWNvZGUgQ2hhcmFjdGVyCi0gICAgICAgRGF0YWJhc2UiIGNhbiBiZSBmb3VuZCBpbiBFeGhpYml0IDEuCi0KLSAgICA1LiBFYWNoIHZlcnNpb24gb2YgdGhlIFVuaWNvZGUgU3RhbmRhcmQgaGFzIGZ1cnRoZXIgc3BlY2lmaWNhdGlvbnMgb2YKLSAgICAgICByaWdodHMgYW5kIHJlc3RyaWN0aW9ucyBvZiB1c2UuIEZvciB0aGUgYm9vayBlZGl0aW9ucyAoVW5pY29kZSA1LjAgYW5kCi0gICAgICAgZWFybGllciksIHRoZXNlIGFyZSBmb3VuZCBvbiB0aGUgYmFjayBvZiB0aGUgdGl0bGUgcGFnZS4gVGhlIG9ubGluZQotICAgICAgIGNvZGUgY2hhcnRzIGNhcnJ5IHNwZWNpZmljIHJlc3RyaWN0aW9ucy4gQWxsIG90aGVyIGZpbGVzLCBpbmNsdWRpbmcKLSAgICAgICBvbmxpbmUgZG9jdW1lbnRhdGlvbiBvZiB0aGUgY29yZSBzcGVjaWZpY2F0aW9uIGZvciBVbmljb2RlIDYuMCBhbmQKLSAgICAgICBsYXRlciwgYXJlIGNvdmVyZWQgdW5kZXIgdGhlc2UgZ2VuZXJhbCBUZXJtcyBvZiBVc2UuCi0KLSAgICA2LiBObyBsaWNlbnNlIGlzIGdyYW50ZWQgdG8gIm1pcnJvciIgdGhlIFVuaWNvZGUgd2Vic2l0ZSB3aGVyZSBhIGZlZSBpcwotICAgICAgIGNoYXJnZWQgZm9yIGFjY2VzcyB0byB0aGUgIm1pcnJvciIgc2l0ZS4KLQotICAgIDcuIE1vZGlmaWNhdGlvbiBpcyBub3QgcGVybWl0dGVkIHdpdGggcmVzcGVjdCB0byB0aGlzIGRvY3VtZW50LiBBbGwgY29waWVzCi0gICAgICAgb2YgdGhpcyBkb2N1bWVudCBtdXN0IGJlIHZlcmJhdGltLgotCi1CLiBSZXN0cmljdGVkIFJpZ2h0cyBMZWdlbmQuIEFueSB0ZWNobmljYWwgZGF0YSBvciBzb2Z0d2FyZSB3aGljaCBpcyBsaWNlbnNlZAotICAgdG8gdGhlIFVuaXRlZCBTdGF0ZXMgb2YgQW1lcmljYSwgaXRzIGFnZW5jaWVzIGFuZC9vciBpbnN0cnVtZW50YWxpdGllcwotICAgdW5kZXIgdGhpcyBBZ3JlZW1lbnQgaXMgY29tbWVyY2lhbCB0ZWNobmljYWwgZGF0YSBvciBjb21tZXJjaWFsIGNvbXB1dGVyCi0gICBzb2Z0d2FyZSBkZXZlbG9wZWQgZXhjbHVzaXZlbHkgYXQgcHJpdmF0ZSBleHBlbnNlIGFzIGRlZmluZWQgaW4gRkFSIDIuMTAxLAotICAgb3IgREZBUlMgMjUyLjIyNy03MDE0IChKdW5lIDE5OTUpLCBhcyBhcHBsaWNhYmxlLiBGb3IgdGVjaG5pY2FsIGRhdGEsIHVzZSwKLSAgIGR1cGxpY2F0aW9uLCBvciBkaXNjbG9zdXJlIGJ5IHRoZSBHb3Zlcm5tZW50IGlzIHN1YmplY3QgdG8gcmVzdHJpY3Rpb25zIGFzCi0gICBzZXQgZm9ydGggaW4gREZBUlMgMjAyLjIyNy03MDE1IFRlY2huaWNhbCBEYXRhLCBDb21tZXJjaWFsIGFuZCBJdGVtcyAoTm92Ci0gICAxOTk1KSBhbmQgdGhpcyBBZ3JlZW1lbnQuIEZvciBTb2Z0d2FyZSwgaW4gYWNjb3JkYW5jZSB3aXRoIEZBUiAxMi0yMTIgb3IKLSAgIERGQVJTIDIyNy03MjAyLCBhcyBhcHBsaWNhYmxlLCB1c2UsIGR1cGxpY2F0aW9uIG9yIGRpc2Nsb3N1cmUgYnkgdGhlCi0gICBHb3Zlcm5tZW50IGlzIHN1YmplY3QgdG8gdGhlIHJlc3RyaWN0aW9ucyBzZXQgZm9ydGggaW4gdGhpcyBBZ3JlZW1lbnQuCi0KLUMuIFdhcnJhbnRpZXMgYW5kIERpc2NsYWltZXJzLgotICAgMS4gVGhpcyBwdWJsaWNhdGlvbiBhbmQvb3Igd2Vic2l0ZSBtYXkgaW5jbHVkZSB0ZWNobmljYWwgb3IgdHlwb2dyYXBoaWNhbAotICAgICAgZXJyb3JzIG9yIG90aGVyIGluYWNjdXJhY2llcyAuIENoYW5nZXMgYXJlIHBlcmlvZGljYWxseSBhZGRlZCB0byB0aGUKLSAgICAgIGluZm9ybWF0aW9uIGhlcmVpbjsgdGhlc2UgY2hhbmdlcyB3aWxsIGJlIGluY29ycG9yYXRlZCBpbiBuZXcgZWRpdGlvbnMKLSAgICAgIG9mIHRoZSBwdWJsaWNhdGlvbiBhbmQvb3Igd2Vic2l0ZS4gVW5pY29kZSBtYXkgbWFrZSBpbXByb3ZlbWVudHMgYW5kL29yCi0gICAgICBjaGFuZ2VzIGluIHRoZSBwcm9kdWN0KHMpIGFuZC9vciBwcm9ncmFtKHMpIGRlc2NyaWJlZCBpbiB0aGlzCi0gICAgICBwdWJsaWNhdGlvbiBhbmQvb3Igd2Vic2l0ZSBhdCBhbnkgdGltZS4KLQotICAgIDIuIElmIHRoaXMgZmlsZSBoYXMgYmVlbiBwdXJjaGFzZWQgb24gbWFnbmV0aWMgb3Igb3B0aWNhbCBtZWRpYSBmcm9tCi0gICAgICAgVW5pY29kZSwgSW5jLiB0aGUgc29sZSBhbmQgZXhjbHVzaXZlIHJlbWVkeSBmb3IgYW55IGNsYWltIHdpbGwgYmUKLSAgICAgICBleGNoYW5nZSBvZiB0aGUgZGVmZWN0aXZlIG1lZGlhIHdpdGhpbiBuaW5ldHkgKDkwKSBkYXlzIG9mIG9yaWdpbmFsCi0gICAgICAgcHVyY2hhc2UuCi0KLSAgICAzLiBFWENFUFQgQVMgUFJPVklERUQgSU4gU0VDVElPTiBDLjIsIFRISVMgUFVCTElDQVRJT04gQU5EL09SIFNPRlRXQVJFIElTCi0gICAgICAgUFJPVklERUQgIkFTIElTIiBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5EIEVJVEhFUiBFWFBSRVNTLCBJTVBMSUVELAotICAgICAgIE9SIFNUQVRVVE9SWSwgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIEFOWSBXQVJSQU5USUVTIE9GCi0gICAgICAgTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSwgT1IgTk9OLUlORlJJTkdFTUVOVC4KLSAgICAgICBVTklDT0RFIEFORCBJVFMgTElDRU5TT1JTIEFTU1VNRSBOTyBSRVNQT05TSUJJTElUWSBGT1IgRVJST1JTIE9SCi0gICAgICAgT01JU1NJT05TIElOIFRISVMgUFVCTElDQVRJT04gQU5EL09SIFNPRlRXQVJFIE9SIE9USEVSIERPQ1VNRU5UUyBXSElDSAotICAgICAgIEFSRSBSRUZFUkVOQ0VEIEJZIE9SIExJTktFRCBUTyBUSElTIFBVQkxJQ0FUSU9OIE9SIFRIRSBVTklDT0RFIFdFQlNJVEUuCi0KLUQuIFdhaXZlciBvZiBEYW1hZ2VzLiBJbiBubyBldmVudCBzaGFsbCBVbmljb2RlIG9yIGl0cyBsaWNlbnNvcnMgYmUgbGlhYmxlIGZvcgotICAgYW55IHNwZWNpYWwsIGluY2lkZW50YWwsIGluZGlyZWN0IG9yIGNvbnNlcXVlbnRpYWwgZGFtYWdlcyBvZiBhbnkga2luZCwgb3IKLSAgIGFueSBkYW1hZ2VzIHdoYXRzb2V2ZXIsIHdoZXRoZXIgb3Igbm90IFVuaWNvZGUgd2FzIGFkdmlzZWQgb2YgdGhlCi0gICBwb3NzaWJpbGl0eSBvZiB0aGUgZGFtYWdlLCBpbmNsdWRpbmcsIHdpdGhvdXQgbGltaXRhdGlvbiwgdGhvc2UgcmVzdWx0aW5nCi0gICBmcm9tIHRoZSBmb2xsb3dpbmc6IGxvc3Mgb2YgdXNlLCBkYXRhIG9yIHByb2ZpdHMsIGluIGNvbm5lY3Rpb24gd2l0aCB0aGUKLSAgIHVzZSwgbW9kaWZpY2F0aW9uIG9yIGRpc3RyaWJ1dGlvbiBvZiB0aGlzIGluZm9ybWF0aW9uIG9yIGl0cyBkZXJpdmF0aXZlcy4KLQotRS5UcmFkZW1hcmtzICYgTG9nb3MuCi0gICAxLiBUaGUgVW5pY29kZSBXb3JkIE1hcmsgYW5kIHRoZSBVbmljb2RlIExvZ28gYXJlIHRyYWRlbWFya3Mgb2YgVW5pY29kZSwKLSAgICAgIEluYy4gIOKAnFRoZSBVbmljb2RlIENvbnNvcnRpdW3igJ0gYW5kIOKAnFVuaWNvZGUsIEluYy7igJ0gYXJlIHRyYWRlIG5hbWVzIG9mCi0gICAgICBVbmljb2RlLCBJbmMuICBVc2Ugb2YgdGhlIGluZm9ybWF0aW9uIGFuZCBtYXRlcmlhbHMgZm91bmQgb24gdGhpcwotICAgICAgd2Vic2l0ZSBpbmRpY2F0ZXMgeW91ciBhY2tub3dsZWRnZW1lbnQgb2YgVW5pY29kZSwgSW5jLuKAmXMgZXhjbHVzaXZlCi0gICAgICB3b3JsZHdpZGUgcmlnaHRzIGluIHRoZSBVbmljb2RlIFdvcmQgTWFyaywgdGhlIFVuaWNvZGUgTG9nbywgYW5kIHRoZQotICAgICAgVW5pY29kZSB0cmFkZSBuYW1lcy4KLQotICAgMi4gVGhlIFVuaWNvZGUgQ29uc29ydGl1bSBOYW1lIGFuZCBUcmFkZW1hcmsgVXNhZ2UgUG9saWN5ICjigJxUcmFkZW1hcmsKLSAgICAgIFBvbGljeeKAnSkgYXJlIGluY29ycG9yYXRlZCBoZXJlaW4gYnkgcmVmZXJlbmNlIGFuZCB5b3UgYWdyZWUgdG8gYWJpZGUgYnkKLSAgICAgIHRoZSBwcm92aXNpb25zIG9mIHRoZSBUcmFkZW1hcmsgUG9saWN5LCB3aGljaCBtYXkgYmUgY2hhbmdlZCBmcm9tIHRpbWUKLSAgICAgIHRvIHRpbWUgaW4gdGhlIHNvbGUgZGlzY3JldGlvbiBvZiBVbmljb2RlLCBJbmMuCi0KLSAgIDMuIEFsbCB0aGlyZCBwYXJ0eSB0cmFkZW1hcmtzIHJlZmVyZW5jZWQgaGVyZWluIGFyZSB0aGUgcHJvcGVydHkgb2YgdGhlaXIKLSAgICAgIHJlc3BlY3RpdmUgb3duZXJzLgotCi1NaXNjZWxsYW5lb3VzLgotICAgMS4gSnVyaXNkaWN0aW9uIGFuZCBWZW51ZS4gVGhpcyBzZXJ2ZXIgaXMgb3BlcmF0ZWQgZnJvbSBhIGxvY2F0aW9uIGluIHRoZQotICAgICAgU3RhdGUgb2YgQ2FsaWZvcm5pYSwgVW5pdGVkIFN0YXRlcyBvZiBBbWVyaWNhLiBVbmljb2RlIG1ha2VzIG5vCi0gICAgICByZXByZXNlbnRhdGlvbiB0aGF0IHRoZSBtYXRlcmlhbHMgYXJlIGFwcHJvcHJpYXRlIGZvciB1c2UgaW4gb3RoZXIKLSAgICAgIGxvY2F0aW9ucy4gSWYgeW91IGFjY2VzcyB0aGlzIHNlcnZlciBmcm9tIG90aGVyIGxvY2F0aW9ucywgeW91IGFyZQotICAgICAgcmVzcG9uc2libGUgZm9yIGNvbXBsaWFuY2Ugd2l0aCBsb2NhbCBsYXdzLiBUaGlzIEFncmVlbWVudCwgYWxsIHVzZSBvZgotICAgICAgdGhpcyBzaXRlIGFuZCBhbnkgY2xhaW1zIGFuZCBkYW1hZ2VzIHJlc3VsdGluZyBmcm9tIHVzZSBvZiB0aGlzIHNpdGUgYXJlCi0gICAgICBnb3Zlcm5lZCBzb2xlbHkgYnkgdGhlIGxhd3Mgb2YgdGhlIFN0YXRlIG9mIENhbGlmb3JuaWEgd2l0aG91dCByZWdhcmQgdG8KLSAgICAgIGFueSBwcmluY2lwbGVzIHdoaWNoIHdvdWxkIGFwcGx5IHRoZSBsYXdzIG9mIGEgZGlmZmVyZW50IGp1cmlzZGljdGlvbi4KLSAgICAgIFRoZSB1c2VyIGFncmVlcyB0aGF0IGFueSBkaXNwdXRlcyByZWdhcmRpbmcgdGhpcyBzaXRlIHNoYWxsIGJlIHJlc29sdmVkCi0gICAgICBzb2xlbHkgaW4gdGhlIGNvdXJ0cyBsb2NhdGVkIGluIFNhbnRhIENsYXJhIENvdW50eSwgQ2FsaWZvcm5pYS4gVGhlIHVzZXIKLSAgICAgIGFncmVlcyBzYWlkIGNvdXJ0cyBoYXZlIHBlcnNvbmFsIGp1cmlzZGljdGlvbiBhbmQgYWdyZWUgdG8gd2FpdmUgYW55Ci0gICAgICByaWdodCB0byB0cmFuc2ZlciB0aGUgZGlzcHV0ZSB0byBhbnkgb3RoZXIgZm9ydW0uCi0KLSAgIDIuIE1vZGlmaWNhdGlvbiBieSBVbmljb2RlLiAgVW5pY29kZSBzaGFsbCBoYXZlIHRoZSByaWdodCB0byBtb2RpZnkgdGhpcwotICAgICAgQWdyZWVtZW50IGF0IGFueSB0aW1lIGJ5IHBvc3RpbmcgaXQgdG8gdGhpcyBzaXRlLiBUaGUgdXNlciBtYXkgbm90Ci0gICAgICBhc3NpZ24gYW55IHBhcnQgb2YgdGhpcyBBZ3JlZW1lbnQgd2l0aG91dCBVbmljb2Rl4oCZcyBwcmlvciB3cml0dGVuCi0gICAgICBjb25zZW50LgotCi0gICAzLiBUYXhlcy4gVGhlIHVzZXIgYWdyZWVzIHRvIHBheSBhbnkgdGF4ZXMgYXJpc2luZyBmcm9tIGFjY2VzcyB0byB0aGlzCi0gICAgICB3ZWJzaXRlIG9yIHVzZSBvZiB0aGUgaW5mb3JtYXRpb24gaGVyZWluLCBleGNlcHQgZm9yIHRob3NlIGJhc2VkIG9uCi0gICAgICBVbmljb2Rl4oCZcyBuZXQgaW5jb21lLgotCi0gICA0LiBTZXZlcmFiaWxpdHkuICBJZiBhbnkgcHJvdmlzaW9uIG9mIHRoaXMgQWdyZWVtZW50IGlzIGRlY2xhcmVkIGludmFsaWQgb3IKLSAgICAgIHVuZW5mb3JjZWFibGUsIHRoZSByZW1haW5pbmcgcHJvdmlzaW9ucyBvZiB0aGlzIEFncmVlbWVudCBzaGFsbCByZW1haW4KLSAgICAgIGluIGVmZmVjdC4KLQotICAgNS4gRW50aXJlIEFncmVlbWVudC4gVGhpcyBBZ3JlZW1lbnQgY29uc3RpdHV0ZXMgdGhlIGVudGlyZSBhZ3JlZW1lbnQKLSAgICAgIGJldHdlZW4gdGhlIHBhcnRpZXMuCi0KLUVYSElCSVQgMQotVU5JQ09ERSwgSU5DLiBMSUNFTlNFIEFHUkVFTUVOVCAtIERBVEEgRklMRVMgQU5EIFNPRlRXQVJFCi0KLVVuaWNvZGUgRGF0YSBGaWxlcyBpbmNsdWRlIGFsbCBkYXRhIGZpbGVzIHVuZGVyIHRoZSBkaXJlY3RvcmllcwotaHR0cDovL3d3dy51bmljb2RlLm9yZy9QdWJsaWMvLCBodHRwOi8vd3d3LnVuaWNvZGUub3JnL3JlcG9ydHMvLCBhbmQKLWh0dHA6Ly93d3cudW5pY29kZS5vcmcvY2xkci9kYXRhLy4gVW5pY29kZSBEYXRhIEZpbGVzIGRvIG5vdCBpbmNsdWRlIFBERgotb25saW5lIGNvZGUgY2hhcnRzIHVuZGVyIHRoZSBkaXJlY3RvcnkgaHR0cDovL3d3dy51bmljb2RlLm9yZy9QdWJsaWMvLgotU29mdHdhcmUgaW5jbHVkZXMgYW55IHNvdXJjZSBjb2RlIHB1Ymxpc2hlZCBpbiB0aGUgVW5pY29kZSBTdGFuZGFyZCBvciB1bmRlcgotdGhlIGRpcmVjdG9yaWVzIGh0dHA6Ly93d3cudW5pY29kZS5vcmcvUHVibGljLywKLWh0dHA6Ly93d3cudW5pY29kZS5vcmcvcmVwb3J0cy8sIGFuZCBodHRwOi8vd3d3LnVuaWNvZGUub3JnL2NsZHIvZGF0YS8uCi0KLU5PVElDRSBUTyBVU0VSOiBDYXJlZnVsbHkgcmVhZCB0aGUgZm9sbG93aW5nIGxlZ2FsIGFncmVlbWVudC4gQlkgRE9XTkxPQURJTkcsCi1JTlNUQUxMSU5HLCBDT1BZSU5HIE9SIE9USEVSV0lTRSBVU0lORyBVTklDT0RFIElOQy4nUyBEQVRBIEZJTEVTICgiREFUQQotRklMRVMiKSwgQU5EL09SIFNPRlRXQVJFICgiU09GVFdBUkUiKSwgWU9VIFVORVFVSVZPQ0FMTFkgQUNDRVBULCBBTkQgQUdSRUUgVE8KLUJFIEJPVU5EIEJZLCBBTEwgT0YgVEhFIFRFUk1TIEFORCBDT05ESVRJT05TIE9GIFRISVMgQUdSRUVNRU5ULiBJRiBZT1UgRE8gTk9UCi1BR1JFRSwgRE8gTk9UIERPV05MT0FELCBJTlNUQUxMLCBDT1BZLCBESVNUUklCVVRFIE9SIFVTRSBUSEUgREFUQSBGSUxFUyBPUgotU09GVFdBUkUuCi0KLUNPUFlSSUdIVCBBTkQgUEVSTUlTU0lPTiBOT1RJQ0UKLQotQ29weXJpZ2h0IMKpIDE5OTEtMjAxMiBVbmljb2RlLCBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuIERpc3RyaWJ1dGVkIHVuZGVyIHRoZQotVGVybXMgb2YgVXNlIGluIGh0dHA6Ly93d3cudW5pY29kZS5vcmcvY29weXJpZ2h0Lmh0bWwuCi0KLVBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHkKLW9mIHRoZSBVbmljb2RlIGRhdGEgZmlsZXMgYW5kIGFueSBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gKHRoZSAiRGF0YSBGaWxlcyIpCi1vciBVbmljb2RlIHNvZnR3YXJlIGFuZCBhbnkgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uICh0aGUgIlNvZnR3YXJlIikgdG8gZGVhbAotaW4gdGhlIERhdGEgRmlsZXMgb3IgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQKLWxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIGFuZC9vcgotc2VsbCBjb3BpZXMgb2YgdGhlIERhdGEgRmlsZXMgb3IgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZQotRGF0YSBGaWxlcyBvciBTb2Z0d2FyZSBhcmUgZnVybmlzaGVkIHRvIGRvIHNvLCBwcm92aWRlZCB0aGF0IChhKSB0aGUgYWJvdmUKLWNvcHlyaWdodCBub3RpY2UocykgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2UgYXBwZWFyIHdpdGggYWxsIGNvcGllcyBvZiB0aGUKLURhdGEgRmlsZXMgb3IgU29mdHdhcmUsIChiKSBib3RoIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlKHMpIGFuZCB0aGlzCi1wZXJtaXNzaW9uIG5vdGljZSBhcHBlYXIgaW4gYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uLCBhbmQgKGMpIHRoZXJlIGlzIGNsZWFyCi1ub3RpY2UgaW4gZWFjaCBtb2RpZmllZCBEYXRhIEZpbGUgb3IgaW4gdGhlIFNvZnR3YXJlIGFzIHdlbGwgYXMgaW4gdGhlCi1kb2N1bWVudGF0aW9uIGFzc29jaWF0ZWQgd2l0aCB0aGUgRGF0YSBGaWxlKHMpIG9yIFNvZnR3YXJlIHRoYXQgdGhlIGRhdGEgb3IKLXNvZnR3YXJlIGhhcyBiZWVuIG1vZGlmaWVkLgotCi1USEUgREFUQSBGSUxFUyBBTkQgU09GVFdBUkUgQVJFIFBST1ZJREVEICJBUyBJUyIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZCi1LSU5ELCBFWFBSRVNTIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YKLU1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVCBPRiBUSElSRAotUEFSVFkgUklHSFRTLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBIT0xERVJTIElOQ0xVREVEIElOCi1USElTIE5PVElDRSBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgT1IgQU5ZIFNQRUNJQUwgSU5ESVJFQ1QgT1IgQ09OU0VRVUVOVElBTAotREFNQUdFUywgT1IgQU5ZIERBTUFHRVMgV0hBVFNPRVZFUiBSRVNVTFRJTkcgRlJPTSBMT1NTIE9GIFVTRSwgREFUQSBPUgotUFJPRklUUywgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIE5FR0xJR0VOQ0UgT1IgT1RIRVIgVE9SVElPVVMKLUFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1IgUEVSRk9STUFOQ0UgT0YgVEhFCi1EQVRBIEZJTEVTIE9SIFNPRlRXQVJFLgotCi1FeGNlcHQgYXMgY29udGFpbmVkIGluIHRoaXMgbm90aWNlLCB0aGUgbmFtZSBvZiBhIGNvcHlyaWdodCBob2xkZXIgc2hhbGwgbm90Ci1iZSB1c2VkIGluIGFkdmVydGlzaW5nIG9yIG90aGVyd2lzZSB0byBwcm9tb3RlIHRoZSBzYWxlLCB1c2Ugb3Igb3RoZXIgZGVhbGluZ3MKLWluIHRoZXNlIERhdGEgRmlsZXMgb3IgU29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIGF1dGhvcml6YXRpb24gb2YgdGhlCi1jb3B5cmlnaHQgaG9sZGVyLgotCi1Vbmljb2RlIGFuZCB0aGUgVW5pY29kZSBsb2dvIGFyZSB0cmFkZW1hcmtzIG9mIFVuaWNvZGUsIEluYy4gaW4gdGhlIFVuaXRlZAotU3RhdGVzIGFuZCBvdGhlciBjb3VudHJpZXMuIEFsbCB0aGlyZCBwYXJ0eSB0cmFkZW1hcmtzIHJlZmVyZW5jZWQgaGVyZWluIGFyZQotdGhlIHByb3BlcnR5IG9mIHRoZWlyIHJlc3BlY3RpdmUgb3duZXJzLgotCi0tLS0gZW5kIG9mIExJQ0VOU0UgLS0tCi0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLQotJSUgVGhpcyBub3RpY2UgaXMgcHJvdmlkZWQgd2l0aCByZXNwZWN0IHRvIFVQWCB2My4wMSwgd2hpY2ggbWF5IGJlIGluY2x1ZGVkIAotd2l0aCBKUkUgOCBvbiBXaW5kb3dzLgotCi0tLS0gYmVnaW4gb2YgTElDRU5TRSAtLS0KLQotVXNlIG9mIGFueSBvZiB0aGlzIHNvZnR3YXJlIGlzIGdvdmVybmVkIGJ5IHRoZSB0ZXJtcyBvZiB0aGUgbGljZW5zZSBiZWxvdzoKLQotCi0gICAgICAgICAgICAgICAgIG9vb29vICAgICBvb28gb29vb29vb29vLiAgIG9vb29vb28gIG9vb29vCi0gICAgICAgICAgICAgICAgIGA4ODgnICAgICBgOCcgYDg4OCAgIGBZODguICBgODg4OCAgICBkOCcKLSAgICAgICAgICAgICAgICAgIDg4OCAgICAgICA4ICAgODg4ICAgLmQ4OCcgICAgWTg4OC4uOFAKLSAgICAgICAgICAgICAgICAgIDg4OCAgICAgICA4ICAgODg4b29vODhQJyAgICAgIGA4ODg4JwotICAgICAgICAgICAgICAgICAgODg4ICAgICAgIDggICA4ODggICAgICAgICAgICAuOFBZODg4LgotICAgICAgICAgICAgICAgICAgYDg4LiAgICAuOCcgICA4ODggICAgICAgICAgIGQ4JyAgYDg4OGIKLSAgICAgICAgICAgICAgICAgICAgYFlib2RQJyAgICBvODg4byAgICAgICAgbzg4OG8gIG84ODg4OG8KLQotCi0gICAgICAgICAgICAgICAgICAgIFRoZSBVbHRpbWF0ZSBQYWNrZXIgZm9yIGVYZWN1dGFibGVzCi0gICAgICAgICAgQ29weXJpZ2h0IChjKSAxOTk2LTIwMDAgTWFya3VzIE9iZXJodW1lciAmIExhc3psbyBNb2xuYXIKLSAgICAgICAgICAgICAgIGh0dHA6Ly93aWxkc2F1Lmlkdi51bmktbGluei5hYy5hdC9tZngvdXB4Lmh0bWwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5uZXh1cy5odS91cHgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBodHRwOi8vdXB4LnRzeC5vcmcKLQotCi1QTEVBU0UgQ0FSRUZVTExZIFJFQUQgVEhJUyBMSUNFTlNFIEFHUkVFTUVOVCwgRVNQRUNJQUxMWSBJRiBZT1UgUExBTgotVE8gTU9ESUZZIFRIRSBVUFggU09VUkNFIENPREUgT1IgVVNFIEEgTU9ESUZJRUQgVVBYIFZFUlNJT04uCi0KLQotQUJTVFJBQ1QKLT09PT09PT09Ci0KLSAgIFVQWCBhbmQgVUNMIGFyZSBjb3B5cmlnaHRlZCBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgdGVybXMKLSAgIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSAoaGVyZWluYWZ0ZXIgdGhlICJHUEwiKS4KLQotICAgVGhlIHN0dWIgd2hpY2ggaXMgaW1iZWRkZWQgaW4gZWFjaCBVUFggY29tcHJlc3NlZCBwcm9ncmFtIGlzIHBhcnQKLSAgIG9mIFVQWCBhbmQgVUNMLCBhbmQgY29udGFpbnMgY29kZSB0aGF0IGlzIHVuZGVyIG91ciBjb3B5cmlnaHQuIFRoZQotICAgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHN0aWxsIGFwcGx5IGFzIGNvbXByZXNzaW5nCi0gICBhIHByb2dyYW0gaXMgYSBzcGVjaWFsIGZvcm0gb2YgbGlua2luZyB3aXRoIG91ciBzdHViLgotCi0gICBBcyBhIHNwZWNpYWwgZXhjZXB0aW9uIHdlIGdyYW50IHRoZSBmcmVlIHVzYWdlIG9mIFVQWCBmb3IgYWxsCi0gICBleGVjdXRhYmxlcywgaW5jbHVkaW5nIGNvbW1lcmNpYWwgcHJvZ3JhbXMuCi0gICBTZWUgYmVsb3cgZm9yIGRldGFpbHMgYW5kIHJlc3RyaWN0aW9ucy4KLQotCi1DT1BZUklHSFQKLT09PT09PT09PQotCi0gICBVUFggYW5kIFVDTCBhcmUgY29weXJpZ2h0ZWQgc29mdHdhcmUuIEFsbCByaWdodHMgcmVtYWluIHdpdGggdGhlIGF1dGhvcnMuCi0KLSAgIFVQWCBpcyBDb3B5cmlnaHQgKEMpIDE5OTYtMjAwMCBNYXJrdXMgRnJhbnogWGF2ZXIgSm9oYW5uZXMgT2Jlcmh1bWVyCi0gICBVUFggaXMgQ29weXJpZ2h0IChDKSAxOTk2LTIwMDAgTGFzemxvIE1vbG5hcgotCi0gICBVQ0wgaXMgQ29weXJpZ2h0IChDKSAxOTk2LTIwMDAgTWFya3VzIEZyYW56IFhhdmVyIEpvaGFubmVzIE9iZXJodW1lcgotCi0KLUdOVSBHRU5FUkFMIFBVQkxJQyBMSUNFTlNFCi09PT09PT09PT09PT09PT09PT09PT09PT09PQotCi0gICBVUFggYW5kIHRoZSBVQ0wgbGlicmFyeSBhcmUgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgdGhlbQotICAgYW5kL29yIG1vZGlmeSB0aGVtIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMKLSAgIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mCi0gICB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KLQotICAgVVBYIGFuZCBVQ0wgYXJlIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgdGhleSB3aWxsIGJlIHVzZWZ1bCwKLSAgIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCi0gICBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCi0gICBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgotCi0gICBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICAgYWxvbmcgd2l0aCB0aGlzIHByb2dyYW07IHNlZSB0aGUgZmlsZSBDT1BZSU5HLgotCi0KLVNQRUNJQUwgRVhDRVBUSU9OIEZPUiBDT01QUkVTU0VEIEVYRUNVVEFCTEVTCi09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotCi0gICBUaGUgc3R1YiB3aGljaCBpcyBpbWJlZGRlZCBpbiBlYWNoIFVQWCBjb21wcmVzc2VkIHByb2dyYW0gaXMgcGFydAotICAgb2YgVVBYIGFuZCBVQ0wsIGFuZCBjb250YWlucyBjb2RlIHRoYXQgaXMgdW5kZXIgb3VyIGNvcHlyaWdodC4gVGhlCi0gICB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2Ugc3RpbGwgYXBwbHkgYXMgY29tcHJlc3NpbmcKLSAgIGEgcHJvZ3JhbSBpcyBhIHNwZWNpYWwgZm9ybSBvZiBsaW5raW5nIHdpdGggb3VyIHN0dWIuCi0KLSAgIEhlcmVieSBNYXJrdXMgRi5YLkouIE9iZXJodW1lciBhbmQgTGFzemxvIE1vbG5hciBncmFudCB5b3Ugc3BlY2lhbAotICAgcGVybWlzc2lvbiB0byBmcmVlbHkgdXNlIGFuZCBkaXN0cmlidXRlIGFsbCBVUFggY29tcHJlc3NlZCBwcm9ncmFtcwotICAgKGluY2x1ZGluZyBjb21tZXJjaWFsIG9uZXMpLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgcmVzdHJpY3Rpb25zOgotCi0gICAxLiBZb3UgbXVzdCBjb21wcmVzcyB5b3VyIHByb2dyYW0gd2l0aCBhIGNvbXBsZXRlbHkgdW5tb2RpZmllZCBVUFgKLSAgICAgIHZlcnNpb247IGVpdGhlciB3aXRoIG91ciBwcmVjb21waWxlZCB2ZXJzaW9uLCBvciAoYXQgeW91ciBvcHRpb24pCi0gICAgICB3aXRoIGEgc2VsZiBjb21waWxlZCB2ZXJzaW9uIG9mIHRoZSB1bm1vZGlmaWVkIFVQWCBzb3VyY2VzIGFzCi0gICAgICBkaXN0cmlidXRlZCBieSB1cy4KLSAgIDIuIFRoaXMgYWxzbyBpbXBsaWVzIHRoYXQgdGhlIFVQWCBzdHViIG11c3QgYmUgY29tcGxldGVseSB1bm1vZGZpZWQsIGkuZS4KLSAgICAgIHRoZSBzdHViIGltYmVkZGVkIGluIHlvdXIgY29tcHJlc3NlZCBwcm9ncmFtIG11c3QgYmUgYnl0ZS1pZGVudGljYWwKLSAgICAgIHRvIHRoZSBzdHViIHRoYXQgaXMgcHJvZHVjZWQgYnkgdGhlIG9mZmljaWFsIHVubW9kaWZpZWQgVVBYIHZlcnNpb24uCi0gICAzLiBUaGUgZGVjb21wcmVzc29yIGFuZCBhbnkgb3RoZXIgY29kZSBmcm9tIHRoZSBzdHViIG11c3QgZXhjbHVzaXZlbHkgZ2V0Ci0gICAgICB1c2VkIGJ5IHRoZSB1bm1vZGlmaWVkIFVQWCBzdHViIGZvciBkZWNvbXByZXNzaW5nIHlvdXIgcHJvZ3JhbSBhdAotICAgICAgcHJvZ3JhbSBzdGFydHVwLiBObyBwb3J0aW9uIG9mIHRoZSBzdHViIG1heSBnZXQgcmVhZCwgY29waWVkLAotICAgICAgY2FsbGVkIG9yIG90aGVyd2lzZSBnZXQgdXNlZCBvciBhY2Nlc3NlZCBieSB5b3VyIHByb2dyYW0uCi0KLQotQU5OT1RBVElPTlMKLT09PT09PT09PT09Ci0KLSAgLSBZb3UgY2FuIHVzZSBhIG1vZGlmaWVkIFVQWCB2ZXJzaW9uIG9yIG1vZGlmaWVkIFVQWCBzdHViIG9ubHkgZm9yCi0gICAgcHJvZ3JhbXMgdGhhdCBhcmUgY29tcGF0aWJsZSB3aXRoIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZS4KLQotICAtIFdlIGdyYW50IHlvdSBzcGVjaWFsIHBlcm1pc3Npb24gdG8gZnJlZWx5IHVzZSBhbmQgZGlzdHJpYnV0ZSBhbGwgVVBYCi0gICAgY29tcHJlc3NlZCBwcm9ncmFtcy4gQnV0IGFueSBtb2RpZmljYXRpb24gb2YgdGhlIFVQWCBzdHViIChzdWNoIGFzLAotICAgIGJ1dCBub3QgbGltaXRlZCB0bywgcmVtb3Zpbmcgb3VyIGNvcHlyaWdodCBzdHJpbmcgb3IgbWFraW5nIHlvdXIKLSAgICBwcm9ncmFtIG5vbi1kZWNvbXByZXNzaWJsZSkgd2lsbCBpbW1lZGlhdGVseSByZXZva2UgeW91ciByaWdodCB0bwotICAgIHVzZSBhbmQgZGlzdHJpYnV0ZSBhIFVQWCBjb21wcmVzc2VkIHByb2dyYW0uCi0KLSAgLSBVUFggaXMgbm90IGEgc29mdHdhcmUgcHJvdGVjdGlvbiB0b29sOyBieSByZXF1aXJpbmcgdGhhdCB5b3UgdXNlCi0gICAgdGhlIHVubW9kaWZpZWQgVVBYIHZlcnNpb24gZm9yIHlvdXIgcHJvcHJpZXRhcnkgcHJvZ3JhbXMgd2UKLSAgICBtYWtlIHN1cmUgdGhhdCBhbnkgdXNlciBjYW4gZGVjb21wcmVzcyB5b3VyIHByb2dyYW0uIFRoaXMgcHJvdGVjdHMKLSAgICBib3RoIHlvdSBhbmQgeW91ciB1c2VycyBhcyBub2JvZHkgY2FuIGhpZGUgbWFsaWNpb3VzIGNvZGUgLQotICAgIGFueSBwcm9ncmFtIHRoYXQgY2Fubm90IGJlIGRlY29tcHJlc3NlZCBpcyBoaWdobHkgc3VzcGljaW91cwotICAgIGJ5IGRlZmluaXRpb24uCi0KLSAgLSBZb3UgY2FuIGludGVncmF0ZSBhbGwgb3IgcGFydCBvZiBVUFggYW5kIFVDTCBpbnRvIHByb2plY3RzIHRoYXQKLSAgICBhcmUgY29tcGF0aWJsZSB3aXRoIHRoZSBHTlUgR1BMLCBidXQgb2J2aW91c2x5IHlvdSBjYW5ub3QgZ3JhbnQKLSAgICBhbnkgc3BlY2lhbCBleGNlcHRpb25zIGJleW9uZCB0aGUgR1BMIGZvciBvdXIgY29kZSBpbiB5b3VyIHByb2plY3QuCi0KLSAgLSBXZSB3YW50IHRvIGFjdGl2ZWx5IHN1cHBvcnQgbWFudWZhY3R1cmVycyBvZiB2aXJ1cyBzY2FubmVycyBhbmQKLSAgICBzaW1pbGFyIHNlY3VyaXR5IHNvZnR3YXJlLiBQbGVhc2UgY29udGFjdCB1cyBpZiB5b3Ugd291bGQgbGlrZSB0bwotICAgIGluY29ycG9yYXRlIHBhcnRzIG9mIFVQWCBvciBVQ0wgaW50byBzdWNoIGEgcHJvZHVjdC4KLQotCi0KLU1hcmt1cyBGLlguSi4gT2Jlcmh1bWVyICAgICAgICAgICAgICAgICAgIExhc3psbyBNb2xuYXIKLW1hcmt1cy5vYmVyaHVtZXJAamsudW5pLWxpbnouYWMuYXQgICAgICAgIG1sMTA1MEBjZGF0YS50dm5ldC5odQotCi1MaW56LCBBdXN0cmlhLCAyNSBGZWIgMjAwMAotCi1BZGRpdGlvbmFsIExpY2Vuc2UocykKLQotVGhlIFVQWCBsaWNlbnNlIGZpbGUgaXMgYXQgaHR0cDovL3VweC5zb3VyY2Vmb3JnZS5uZXQvdXB4LWxpY2Vuc2UuaHRtbC4KLQotLS0tIGVuZCBvZiBMSUNFTlNFIC0tLQotCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0KLSUlIFRoaXMgbm90aWNlIGlzIHByb3ZpZGVkIHdpdGggcmVzcGVjdCB0byBYZnJlZTg2LVZpZE1vZGUgRXh0ZW5zaW9uIDEuMCwKLXdoaWNoIG1heSBiZSBpbmNsdWRlZCB3aXRoIEpSRSA4LCBKREsgOCwgYW5kIE9wZW5KREsgOCBvbiBMaW51eCBhbmQgU29sYXJpcy4KLQotLS0tIGJlZ2luIG9mIExJQ0VOU0UgLS0tCi0KLVZlcnNpb24gMS4xIG9mIFhGcmVlODYgUHJvamVjdExpY2VuY2UuCi0KLUNvcHlyaWdodCAoQykgMTk5NC0yMDA0IFRoZSBYRnJlZTg2IFByb2plY3QsIEluYy4gICAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KLQotUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weSBvZgotdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgIlNvZnR3YXJlIiksIHRvIGRlYWwKLWluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMKLXRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5jZSwgYW5kL29yIHNlbGwKLWNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQKLXRvIGRvIHNvLHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgotCi0gICAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICAgbm90aWNlLHRoaXMgbGlzdCBvZiBjb25kaXRpb25zLCBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotCi0gICAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsCi0gICB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uCi0gICBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbiwgYW5kIGluIHRoZSBzYW1lIHBsYWNlCi0gICBhbmQgZm9ybSBhcyBvdGhlciBjb3B5cmlnaHQsIGxpY2Vuc2UgYW5kIGRpc2NsYWltZXIgaW5mb3JtYXRpb24uCi0KLSAgIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLCBpZiBhbnksbXVzdAotICAgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzCi0gICBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgVGhlIFhGcmVlODYgUHJvamVjdCwgSW5jIChodHRwOi8vd3d3LnhmcmVlODYub3JnLykgYW5kCi0gICBpdHMgY29udHJpYnV0b3JzIiwgaW4gdGhlIHNhbWUgcGxhY2UgYW5kIGZvcm0gYXMgb3RoZXIgdGhpcmQtcGFydHkKLSAgIGFja25vd2xlZGdtZW50cy4gQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUKLSAgIGl0c2VsZiwgaW4gdGhlIHNhbWUgZm9ybSBhbmQgbG9jYXRpb24gYXMgb3RoZXIgc3VjaCB0aGlyZC1wYXJ0eQotICAgYWNrbm93bGVkZ21lbnRzLgotCi0gICAgNC4gRXhjZXB0IGFzIGNvbnRhaW5lZCBpbiB0aGlzIG5vdGljZSwgdGhlIG5hbWUgb2YgVGhlIFhGcmVlODYgUHJvamVjdCxJbmMKLSAgICBzaGFsbCBub3QgYmUgdXNlZCBpbiBhZHZlcnRpc2luZyBvciBvdGhlcndpc2UgdG8gcHJvbW90ZSB0aGUgc2FsZSwgdXNlCi0gICAgb3Igb3RoZXIgZGVhbGluZ3MgaW4gdGhpcyBTb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gYXV0aG9yaXphdGlvbiBmcm9tCi0gICAgVGhlIFhGcmVlODYgUHJvamVjdCwgSW5jLgotCi0gICAgVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICAgIFdBUlJBTlRJRVMsSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YKLSAgICBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTwotICAgIEVWRU5UIFNIQUxMIFRIRSBYRlJFRTg2IFBST0pFQ1QsIElOQyBPUiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZCi0gICAgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCxTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUwotICAgIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTyxQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SCi0gICAgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIKLSAgICBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QKLSAgICBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZCi0gICAgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNICi0gICAgREFNQUdFLiAgCi0KLS0tLSBlbmQgb2YgTElDRU5TRSAtLS0KLQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotCi0lJSBUaGlzIG5vdGljZSBpcyBwcm92aWRlZCB3aXRoIHJlc3BlY3QgdG8gWCBXaW5kb3cgU3lzdGVtIDYuOC4yLCB3aGljaCBtYXkgYmUgCi1pbmNsdWRlZCB3aXRoIEpSRSA4LCBKREsgOCwgYW5kIE9wZW5KREsgOCBvbiBMaW51eCBhbmQgU29sYXJpcy4KLQotLS0tIGJlZ2luIG9mIExJQ0VOU0UgLS0tCi0KLSAgICAgICAgICBMaWNlbnNlcwotVGhlIFguT3JnIEZvdW5kYXRpb24gTWFyY2ggMjAwNAotCi0xLiBJbnRyb2R1Y3Rpb24KLQotVGhlIFgub3JnIEZvdW5kYXRpb24gWCBXaW5kb3cgU3lzdGVtIGRpc3RyaWJ1dGlvbiBpcyBhIGNvbXBpbGF0aW9uIG9mIGNvZGUgYW5kCi1kb2N1bWVudGF0aW9uIGZyb20gbWFueSBzb3VyY2VzLiBUaGlzIGRvY3VtZW50IGlzIGludGVuZGVkIHByaW1hcmlseSBhcyBhCi1ndWlkZSB0byB0aGUgbGljZW5zZXMgdXNlZCBpbiB0aGUgZGlzdHJpYnV0aW9uOiB5b3UgbXVzdCBjaGVjayBlYWNoIGZpbGUKLWFuZC9vciBwYWNrYWdlIGZvciBwcmVjaXNlIHJlZGlzdHJpYnV0aW9uIHRlcm1zLiBOb25lLXRoZS1sZXNzLCB0aGlzIHN1bW1hcnkKLW1heSBiZSB1c2VmdWwgdG8gbWFueSB1c2Vycy4gTm8gc29mdHdhcmUgaW5jb3Jwb3JhdGluZyB0aGUgWEZyZWU4NiAxLjEgbGljZW5zZQotaGFzIGJlZW4gaW5jb3Jwb3JhdGVkLgotCi1UaGlzIGRvY3VtZW50IGlzIGJhc2VkIG9uIHRoZSBjb21waWxhdGlvbiBmcm9tIFhGcmVlODYuCi0KLTIuIFhGcmVlODYgTGljZW5zZQotCi1YRnJlZTg2IGNvZGUgd2l0aG91dCBhbiBleHBsaWNpdCBjb3B5cmlnaHQgaXMgY292ZXJlZCBieSB0aGUgZm9sbG93aW5nCi1jb3B5cmlnaHQvbGljZW5zZToKLQotQ29weXJpZ2h0IChDKSAxOTk0LTIwMDMgVGhlIFhGcmVlODYgUHJvamVjdCwgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLgotCi1QZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5Ci1vZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSAiU29mdHdhcmUiKSwgdG8gZGVhbAotaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cwotdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbAotY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzCi1mdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgotCi1UaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpbiBhbGwKLWNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuCi0KLVRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAiQVMgSVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SCi1JTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwKLUZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRQotWEZSRUU4NiBQUk9KRUNUIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUgotSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4KLUNPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuCi0KLUV4Y2VwdCBhcyBjb250YWluZWQgaW4gdGhpcyBub3RpY2UsIHRoZSBuYW1lIG9mIHRoZSBYRnJlZTg2IFByb2plY3Qgc2hhbGwgbm90Ci1iZSB1c2VkIGluIGFkdmVydGlzaW5nIG9yIG90aGVyd2lzZSB0byBwcm9tb3RlIHRoZSBzYWxlLCB1c2Ugb3Igb3RoZXIgZGVhbGluZ3MKLWluIHRoaXMgU29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIGF1dGhvcml6YXRpb24gZnJvbSB0aGUgWEZyZWU4NiBQcm9qZWN0LgotCi0zLiBPdGhlciBMaWNlbnNlcwotCi1Qb3J0aW9ucyBvZiBjb2RlIGFyZSBjb3ZlcmVkIGJ5IHRoZSBmb2xsb3dpbmcgbGljZW5zZXMvY29weXJpZ2h0cy4gU2VlCi1pbmRpdmlkdWFsIGZpbGVzIGZvciB0aGUgY29weXJpZ2h0IGRhdGVzLgotCi0zLjEuIFgvTUlUIENvcHlyaWdodHMKLQotMy4xLjEuIFggQ29uc29ydGl1bQotCi1Db3B5cmlnaHQgKEMpIDxkYXRlPiBYIENvbnNvcnRpdW0KLQotUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weQotb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgIlNvZnR3YXJlIiksIHRvIGRlYWwKLWluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMKLXRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwKLWNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcwotZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKLQotVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW4gYWxsCi1jb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLgotCi1USEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUgotSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksCi1GSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgWAotQ09OU09SVElVTSBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4KLUFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04KLVdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLgotCi1FeGNlcHQgYXMgY29udGFpbmVkIGluIHRoaXMgbm90aWNlLCB0aGUgbmFtZSBvZiB0aGUgWCBDb25zb3J0aXVtIHNoYWxsIG5vdCBiZQotdXNlZCBpbiBhZHZlcnRpc2luZyBvciBvdGhlcndpc2UgdG8gcHJvbW90ZSB0aGUgc2FsZSwgdXNlIG9yIG90aGVyIGRlYWxpbmdzIGluCi10aGlzIFNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBhdXRob3JpemF0aW9uIGZyb20gdGhlIFggQ29uc29ydGl1bS4KLQotWCBXaW5kb3cgU3lzdGVtIGlzIGEgdHJhZGVtYXJrIG9mIFggQ29uc29ydGl1bSwgSW5jLgotCi0zLjEuMi4gVGhlIE9wZW4gR3JvdXAKLQotQ29weXJpZ2h0IDxkYXRlPiBUaGUgT3BlbiBHcm91cAotCi1QZXJtaXNzaW9uIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBkaXN0cmlidXRlLCBhbmQgc2VsbCB0aGlzIHNvZnR3YXJlIGFuZCBpdHMKLWRvY3VtZW50YXRpb24gZm9yIGFueSBwdXJwb3NlIGlzIGhlcmVieSBncmFudGVkIHdpdGhvdXQgZmVlLCBwcm92aWRlZCB0aGF0IHRoZQotYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhcHBlYXIgaW4gYWxsIGNvcGllcyBhbmQgdGhhdCBib3RoIHRoYXQgY29weXJpZ2h0Ci1ub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2UgYXBwZWFyIGluIHN1cHBvcnRpbmcgZG9jdW1lbnRhdGlvbi4KLQotVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW4gYWxsCi1jb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLgotCi1USEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUgotSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksCi1GSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUKLU9QRU4gR1JPVVAgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOCi1BQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OCi1XSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS4KLQotRXhjZXB0IGFzIGNvbnRhaW5lZCBpbiB0aGlzIG5vdGljZSwgdGhlIG5hbWUgb2YgVGhlIE9wZW4gR3JvdXAgc2hhbGwgbm90IGJlCi11c2VkIGluIGFkdmVydGlzaW5nIG9yIG90aGVyd2lzZSB0byBwcm9tb3RlIHRoZSBzYWxlLCB1c2Ugb3Igb3RoZXIgZGVhbGluZ3MgaW4KLXRoaXMgU29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIGF1dGhvcml6YXRpb24gZnJvbSBUaGUgT3BlbiBHcm91cC4gIDMuMi4KLUJlcmtlbGV5LWJhc2VkIGNvcHlyaWdodHM6Ci0KLW8KLTMuMi4xLiBHZW5lcmFsCi0KLVJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6Ci0KLSAgIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwKLSAgIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0KLSAgIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlCi0gICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgotCi0gICAzLiBUaGUgbmFtZSBvZiB0aGUgYXV0aG9yIG1heSBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgotCi1USElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBBVVRIT1IgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVECi1XQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRgotTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8KLUVWRU5UIFNIQUxMIFRIRSBBVVRIT1IgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLVNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywKLVBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUgotQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIKLUlOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpCi1BUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRQotUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuICAzLjIuMi4gVUNCL0xCTAotCi1Db3B5cmlnaHQgKGMpIDE5OTMgVGhlIFJlZ2VudHMgb2YgdGhlIFVuaXZlcnNpdHkgb2YgQ2FsaWZvcm5pYS4gQWxsIHJpZ2h0cwotcmVzZXJ2ZWQuCi0KLVRoaXMgc29mdHdhcmUgd2FzIGRldmVsb3BlZCBieSB0aGUgQ29tcHV0ZXIgU3lzdGVtcyBFbmdpbmVlcmluZyBncm91cCBhdAotTGF3cmVuY2UgQmVya2VsZXkgTGFib3JhdG9yeSB1bmRlciBEQVJQQSBjb250cmFjdCBCRyA5MS02NiBhbmQgY29udHJpYnV0ZWQgdG8KLUJlcmtlbGV5LgotCi1BbGwgYWR2ZXJ0aXNpbmcgbWF0ZXJpYWxzIG1lbnRpb25pbmcgZmVhdHVyZXMgb3IgdXNlIG9mIHRoaXMgc29mdHdhcmUgbXVzdAotZGlzcGxheSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdlbWVudDogVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlCi1kZXZlbG9wZWQgYnkgdGhlIFVuaXZlcnNpdHkgb2YgQ2FsaWZvcm5pYSwgTGF3cmVuY2UgQmVya2VsZXkgTGFib3JhdG9yeS4KLQotUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci1tb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDoKLQotICAgMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLAotICAgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLQotICAgMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGUKLSAgIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uCi0KLSAgIDMuIEFsbCBhZHZlcnRpc2luZyBtYXRlcmlhbHMgbWVudGlvbmluZyBmZWF0dXJlcyBvciB1c2Ugb2YgdGhpcyBzb2Z0d2FyZQotICAgbXVzdCBkaXNwbGF5IHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ2VtZW50OiBUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUKLSAgIGRldmVsb3BlZCBieSB0aGUgVW5pdmVyc2l0eSBvZiBDYWxpZm9ybmlhLCBCZXJrZWxleSBhbmQgaXRzIGNvbnRyaWJ1dG9ycy4KLQotICAgNC4gTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgVW5pdmVyc2l0eSBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnMgbWF5Ci0gICBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0Ci0gICBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCi0KLVRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIFJFR0VOVFMgQU5EIENPTlRSSUJVVE9SUyBgYEFTIElTJycgQU5EIEFOWQotRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRAotV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIFJFR0VOVFMgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZCi1ESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUwotKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOwotTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OCi1BTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAotKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMKLVNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLiAgMy4yLjMuIFRoZQotTmV0QlNEIEZvdW5kYXRpb24sIEluYy4KLQotQ29weXJpZ2h0IChjKSAyMDAzIFRoZSBOZXRCU0QgRm91bmRhdGlvbiwgSW5jLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotCi1UaGlzIGNvZGUgaXMgZGVyaXZlZCBmcm9tIHNvZnR3YXJlIGNvbnRyaWJ1dGVkIHRvIFRoZSBOZXRCU0QgRm91bmRhdGlvbiBieSBCZW4KLUNvbGx2ZXIgPGNvbGx2ZXIxQGF0dGJpLmNvbT4KLQotUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci1tb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDoKLQotICAgMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLAotICAgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLQotICAgMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGUKLSAgIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uCi0KLSAgIDMuIEFsbCBhZHZlcnRpc2luZyBtYXRlcmlhbHMgbWVudGlvbmluZyBmZWF0dXJlcyBvciB1c2Ugb2YgdGhpcyBzb2Z0d2FyZQotICAgbXVzdCBkaXNwbGF5IHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ2VtZW50OiBUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUKLSAgIGRldmVsb3BlZCBieSB0aGUgTmV0QlNEIEZvdW5kYXRpb24sIEluYy4gYW5kIGl0cyBjb250cmlidXRvcnMuCi0KLSAgIDQuIE5laXRoZXIgdGhlIG5hbWUgb2YgVGhlIE5ldEJTRCBGb3VuZGF0aW9uIG5vciB0aGUgbmFtZXMgb2YgaXRzCi0gICBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gICBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KLQotVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgTkVUQlNEIEZPVU5EQVRJT04sIElOQy4gQU5EIENPTlRSSUJVVE9SUyBgYEFTCi1JUycnIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUKLUlNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEZPVU5EQVRJT04gT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZCi1ESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUwotKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOwotTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OCi1BTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAotKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMKLVNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLiAgMy4yLjQuIFRoZW9kb3JlCi1UcydvLgotCi1Db3B5cmlnaHQgVGhlb2RvcmUgVHMnbywgMTk5NCwgMTk5NSwgMTk5NiwgMTk5NywgMTk5OCwgMTk5OS4gQWxsIHJpZ2h0cwotcmVzZXJ2ZWQuCi0KLVJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6Ci0KLSAgIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwKLSAgIGFuZCB0aGUgZW50aXJlIHBlcm1pc3Npb24gbm90aWNlIGluIGl0cyBlbnRpcmV0eSwgaW5jbHVkaW5nIHRoZSBkaXNjbGFpbWVyCi0gICBvZiB3YXJyYW50aWVzLgotCi0gICAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZQotICAgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi4KLQotICAgMy4gaGUgbmFtZSBvZiB0aGUgYXV0aG9yIG1heSBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgotCi1USElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLAotSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORAotRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UsIEFMTCBPRiBXSElDSCBBUkUgSEVSRUJZIERJU0NMQUlNRUQuIElOIE5PCi1FVkVOVCBTSEFMTCBUSEUgQVVUSE9SIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi1TUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sCi1QUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IKLUJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSCi1JTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKQotQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgTk9UIEFEVklTRUQgT0YgVEhFCi1QT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4gIDMuMi41LiBUaGVvIGRlIFJhYWR0IGFuZCBEYW1pZW4gTWlsbGVyCi0KLUNvcHlyaWdodCAoYykgMTk5NSwxOTk5IFRoZW8gZGUgUmFhZHQuIEFsbCByaWdodHMgcmVzZXJ2ZWQuIENvcHlyaWdodCAoYykKLTIwMDEtMjAwMiBEYW1pZW4gTWlsbGVyLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotCi1SZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLW1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OgotCi0gICAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsCi0gICB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotCi0gICAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZQotICAgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi4KLQotVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQVVUSE9SIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRAotV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YKLU1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PCi1FVkVOVCBTSEFMTCBUSEUgQVVUSE9SIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi1TUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sCi1QUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IKLUJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSCi1JTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKQotQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUKLVBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLiAgMy4yLjYuIFRvZGQgQy4gTWlsbGVyCi0KLUNvcHlyaWdodCAoYykgMTk5OCBUb2RkIEMuIE1pbGxlciA8VG9kZC5NaWxsZXJAY291cnRlc2FuLmNvbT4KLQotUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgYW5kIGRpc3RyaWJ1dGUgdGhpcyBzb2Z0d2FyZSBmb3IgYW55IHB1cnBvc2UKLXdpdGggb3Igd2l0aG91dCBmZWUgaXMgaGVyZWJ5IGdyYW50ZWQsIHByb3ZpZGVkIHRoYXQgdGhlIGFib3ZlIGNvcHlyaWdodAotbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIGFwcGVhciBpbiBhbGwgY29waWVzLgotCi1USEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiBBTkQgVE9ERCBDLiBNSUxMRVIgRElTQ0xBSU1TIEFMTCBXQVJSQU5USUVTCi1XSVRIIFJFR0FSRCBUTyBUSElTIFNPRlRXQVJFIElOQ0xVRElORyBBTEwgSU1QTElFRCBXQVJSQU5USUVTIE9GCi1NRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MuIElOIE5PIEVWRU5UIFNIQUxMIFRPREQgQy4gTUlMTEVSIEJFIExJQUJMRSBGT1IKLUFOWSBTUEVDSUFMLCBESVJFQ1QsIElORElSRUNULCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgT1IgQU5ZIERBTUFHRVMKLVdIQVRTT0VWRVIgUkVTVUxUSU5HIEZST00gTE9TUyBPRiBVU0UsIERBVEEgT1IgUFJPRklUUywgV0hFVEhFUiBJTiBBTiBBQ1RJT04KLU9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SIE9USEVSIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4KLUNPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SIFBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuICAzLjIuNy4gVGhvbWFzCi1XaW5pc2NoaG9mZXIKLQotQ29weXJpZ2h0IChDKSAyMDAxLTIwMDQgVGhvbWFzIFdpbmlzY2hob2ZlcgotCi1SZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLW1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OgotCi0gICAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsCi0gICB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotCi0gICAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZQotICAgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi4KLQotICAgMy4gVGhlIG5hbWUgb2YgdGhlIGF1dGhvciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KLQotVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQVVUSE9SIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi1XQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRgotTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8KLUVWRU5UIFNIQUxMIFRIRSBBVVRIT1IgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLVNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywKLVBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUgotQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIKLUlOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpCi1BUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRQotUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuICAzLjMuIE5WSURJQSBDb3JwCi0KLUNvcHlyaWdodCAoYykgMTk5NiBOVklESUEsIENvcnAuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0KLU5PVElDRSBUTyBVU0VSOiBUaGUgc291cmNlIGNvZGUgaXMgY29weXJpZ2h0ZWQgdW5kZXIgVS5TLiBhbmQgaW50ZXJuYXRpb25hbAotbGF3cy4gTlZJRElBLCBDb3JwLiBvZiBTdW5ueXZhbGUsIENhbGlmb3JuaWEgb3ducyB0aGUgY29weXJpZ2h0IGFuZCBhcyBkZXNpZ24KLXBhdGVudHMgcGVuZGluZyBvbiB0aGUgZGVzaWduIGFuZCBpbnRlcmZhY2Ugb2YgdGhlIE5WIGNoaXBzLiBVc2VycyBhbmQKLXBvc3Nlc3NvcnMgb2YgdGhpcyBzb3VyY2UgY29kZSBhcmUgaGVyZWJ5IGdyYW50ZWQgYSBub25leGNsdXNpdmUsIHJveWFsdHktZnJlZQotY29weXJpZ2h0IGFuZCBkZXNpZ24gcGF0ZW50IGxpY2Vuc2UgdG8gdXNlIHRoaXMgY29kZSBpbiBpbmRpdmlkdWFsIGFuZAotY29tbWVyY2lhbCBzb2Z0d2FyZS4KLQotQW55IHVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIG11c3QgaW5jbHVkZSwgaW4gdGhlIHVzZXIgZG9jdW1lbnRhdGlvbiBhbmQKLWludGVybmFsIGNvbW1lbnRzIHRvIHRoZSBjb2RlLCBub3RpY2VzIHRvIHRoZSBlbmQgdXNlciBhcyBmb2xsb3dzOgotCi1Db3B5cmlnaHQgKGMpIDE5OTYgTlZJRElBLCBDb3JwLiBOVklESUEgZGVzaWduIHBhdGVudHMgcGVuZGluZyBpbiB0aGUgVS5TLiBhbmQKLWZvcmVpZ24gY291bnRyaWVzLgotCi1OVklESUEsIENPUlAuIE1BS0VTIE5PIFJFUFJFU0VOVEFUSU9OIEFCT1VUIFRIRSBTVUlUQUJJTElUWSBPRiBUSElTIFNPVVJDRQotQ09ERSBGT1IgQU5ZIFBVUlBPU0UuIElUIElTIFBST1ZJREVEICJBUyBJUyIgV0lUSE9VVCBFWFBSRVNTIE9SIElNUExJRUQKLVdBUlJBTlRZIE9GIEFOWSBLSU5ELiBOVklESUEsIENPUlAuIERJU0NMQUlNUyBBTEwgV0FSUkFOVElFUyBXSVRIIFJFR0FSRCBUTwotVEhJUyBTT1VSQ0UgQ09ERSwgSU5DTFVESU5HIEFMTCBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORAotRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuIElOIE5PIEVWRU5UIFNIQUxMIE5WSURJQSwgQ09SUC4gQkUgTElBQkxFCi1GT1IgQU5ZIFNQRUNJQUwsIElORElSRUNULCBJTkNJREVOVEFMLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMsIE9SIEFOWQotREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NIExPU1MgT0YgVVNFLCBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4KLUFDVElPTiBPRiBDT05UUkFDVCwgTkVHTElHRU5DRSBPUiBPVEhFUiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GIE9SIElOCi1DT05ORUNUSU9OIFdJVEggVEhFIFVTRSBPUiBQRVJGT1JNQU5DRSBPRiBUSElTIFNPVVJDRSBDT0RFLiAgMy40LiBHTFggUHVibGljCi1MaWNlbnNlCi0KLUdMWCBQVUJMSUMgTElDRU5TRSAoVmVyc2lvbiAxLjAgKDIvMTEvOTkpKSAoIkxpY2Vuc2UiKQotCi1TdWJqZWN0IHRvIGFueSB0aGlyZCBwYXJ0eSBjbGFpbXMsIFNpbGljb24gR3JhcGhpY3MsIEluYy4gKCJTR0kiKSBoZXJlYnkKLWdyYW50cyBwZXJtaXNzaW9uIHRvIFJlY2lwaWVudCAoZGVmaW5lZCBiZWxvdyksIHVuZGVyIFJlY2lwaWVudCdzIGNvcHlyaWdodHMKLWluIHRoZSBPcmlnaW5hbCBTb2Z0d2FyZSAoZGVmaW5lZCBiZWxvdyksIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwKLXB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UgYW5kL29yIHNlbGwgY29waWVzIG9mIFN1YmplY3QgU29mdHdhcmUKLShkZWZpbmVkIGJlbG93KSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFN1YmplY3QgU29mdHdhcmUgaXMKLWZ1cm5pc2hlZCBpbiBhY2NvcmRhbmNlIHdpdGggdGhpcyBMaWNlbnNlIHRvIGRvIHRoZSBzYW1lLCBzdWJqZWN0IHRvIGFsbCBvZgotdGhlIGZvbGxvd2luZyB0ZXJtcyBhbmQgY29uZGl0aW9ucywgd2hpY2ggUmVjaXBpZW50IGFjY2VwdHMgYnkgZW5nYWdpbmcgaW4gYW55Ci1zdWNoIHVzZSwgY29weWluZywgbW9kaWZ5aW5nLCBtZXJnaW5nLCBwdWJsaXNoaW5nLCBkaXN0cmlidXRpbmcsIHN1YmxpY2Vuc2luZwotb3Igc2VsbGluZzoKLQotMS4gRGVmaW5pdGlvbnMuCi0KLSAgICAoYSkgIk9yaWdpbmFsIFNvZnR3YXJlIiBtZWFucyBzb3VyY2UgY29kZSBvZiBjb21wdXRlciBzb2Z0d2FyZSBjb2RlIHdoaWNoCi0gICAgaXMgZGVzY3JpYmVkIGluIEV4aGliaXQgQSBhcyBPcmlnaW5hbCBTb2Z0d2FyZS4KLQotICAgIChiKSAiTW9kaWZpY2F0aW9ucyIgbWVhbnMgYW55IGFkZGl0aW9uIHRvIG9yIGRlbGV0aW9uIGZyb20gdGhlIHN1YnN0YW5jZQotICAgIG9yIHN0cnVjdHVyZSBvZiBlaXRoZXIgdGhlIE9yaWdpbmFsIFNvZnR3YXJlIG9yIGFueSBwcmV2aW91cwotICAgIE1vZGlmaWNhdGlvbnMuIFdoZW4gU3ViamVjdCBTb2Z0d2FyZSBpcyByZWxlYXNlZCBhcyBhIHNlcmllcyBvZiBmaWxlcywgYQotICAgIE1vZGlmaWNhdGlvbiBtZWFucyAoaSkgYW55IGFkZGl0aW9uIHRvIG9yIGRlbGV0aW9uIGZyb20gdGhlIGNvbnRlbnRzIG9mIGEKLSAgICBmaWxlIGNvbnRhaW5pbmcgT3JpZ2luYWwgU29mdHdhcmUgb3IgcHJldmlvdXMgTW9kaWZpY2F0aW9ucyBhbmQgKGlpKSBhbnkKLSAgICBuZXcgZmlsZSB0aGF0IGNvbnRhaW5zIGFueSBwYXJ0IG9mIHRoZSBPcmlnaW5hbCBDb2RlIG9yIHByZXZpb3VzCi0gICAgTW9kaWZpY2F0aW9ucy4KLQotICAgIChjKSAiU3ViamVjdCBTb2Z0d2FyZSIgbWVhbnMgdGhlIE9yaWdpbmFsIFNvZnR3YXJlIG9yIE1vZGlmaWNhdGlvbnMgb3IgdGhlCi0gICAgY29tYmluYXRpb24gb2YgdGhlIE9yaWdpbmFsIFNvZnR3YXJlIGFuZCBNb2RpZmljYXRpb25zLCBvciBwb3J0aW9ucyBvZiBhbnkKLSAgICBvZiB0aGUgZm9yZWdvaW5nLgotCi0gICAgKGQpICJSZWNpcGllbnQiIG1lYW5zIGFuIGluZGl2aWR1YWwgb3IgYSBsZWdhbCBlbnRpdHkgZXhlcmNpc2luZyByaWdodHMKLSAgICB1bmRlciwgYW5kIGNvbXBseWluZyB3aXRoIGFsbCBvZiB0aGUgdGVybXMgb2YsIHRoaXMgTGljZW5zZS4gRm9yIGxlZ2FsCi0gICAgZW50aXRpZXMsICJSZWNpcGllbnQiIGluY2x1ZGVzIGFueSBlbnRpdHkgd2hpY2ggY29udHJvbHMsIGlzIGNvbnRyb2xsZWQKLSAgICBieSwgb3IgaXMgdW5kZXIgY29tbW9uIGNvbnRyb2wgd2l0aCBSZWNpcGllbnQuIEZvciBwdXJwb3NlcyBvZiB0aGlzCi0gICAgZGVmaW5pdGlvbiwgImNvbnRyb2wiIG9mIGFuIGVudGl0eSBtZWFucyAoYSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IKLSAgICBpbmRpcmVjdCwgdG8gZGlyZWN0IG9yIG1hbmFnZSBzdWNoIGVudGl0eSwgb3IgKGIpIG93bmVyc2hpcCBvZiBmaWZ0eQotICAgIHBlcmNlbnQgKDUwJSkgb3IgbW9yZSBvZiB0aGUgb3V0c3RhbmRpbmcgc2hhcmVzIG9yIGJlbmVmaWNpYWwgb3duZXJzaGlwIG9mCi0gICAgc3VjaCBlbnRpdHkuCi0KLTIuIFJlZGlzdHJpYnV0aW9uIG9mIFNvdXJjZSBDb2RlIFN1YmplY3QgdG8gVGhlc2UgVGVybXMuIFJlZGlzdHJpYnV0aW9ucyBvZgotU3ViamVjdCBTb2Z0d2FyZSBpbiBzb3VyY2UgY29kZSBmb3JtIG11c3QgcmV0YWluIHRoZSBub3RpY2Ugc2V0IGZvcnRoIGluCi1FeGhpYml0IEEsIGJlbG93LCBpbiBldmVyeSBmaWxlLiBBIGNvcHkgb2YgdGhpcyBMaWNlbnNlIG11c3QgYmUgaW5jbHVkZWQgaW4KLWFueSBkb2N1bWVudGF0aW9uIGZvciBzdWNoIFN1YmplY3QgU29mdHdhcmUgd2hlcmUgdGhlIHJlY2lwaWVudHMnIHJpZ2h0cwotcmVsYXRpbmcgdG8gU3ViamVjdCBTb2Z0d2FyZSBhcmUgZGVzY3JpYmVkLiBSZWNpcGllbnQgbWF5IGRpc3RyaWJ1dGUgdGhlCi1zb3VyY2UgY29kZSB2ZXJzaW9uIG9mIFN1YmplY3QgU29mdHdhcmUgdW5kZXIgYSBsaWNlbnNlIG9mIFJlY2lwaWVudCdzIGNob2ljZSwKLXdoaWNoIG1heSBjb250YWluIHRlcm1zIGRpZmZlcmVudCBmcm9tIHRoaXMgTGljZW5zZSwgcHJvdmlkZWQgdGhhdCAoaSkKLVJlY2lwaWVudCBpcyBpbiBjb21wbGlhbmNlIHdpdGggdGhlIHRlcm1zIG9mIHRoaXMgTGljZW5zZSwgYW5kIChpaSkgdGhlCi1saWNlbnNlIHRlcm1zIGluY2x1ZGUgdGhpcyBTZWN0aW9uIDIgYW5kIFNlY3Rpb25zIDMsIDQsIDcsIDgsIDEwLCAxMiBhbmQgMTMgb2YKLXRoaXMgTGljZW5zZSwgd2hpY2ggdGVybXMgbWF5IG5vdCBiZSBtb2RpZmllZCBvciBzdXBlcnNlZGVkIGJ5IGFueSBvdGhlciB0ZXJtcwotb2Ygc3VjaCBsaWNlbnNlLiBJZiBSZWNpcGllbnQgZGlzdHJpYnV0ZXMgdGhlIHNvdXJjZSBjb2RlIHZlcnNpb24gdW5kZXIgYQotZGlmZmVyZW50IGxpY2Vuc2UgUmVjaXBpZW50IG11c3QgbWFrZSBpdCBhYnNvbHV0ZWx5IGNsZWFyIHRoYXQgYW55IHRlcm1zIHdoaWNoCi1kaWZmZXIgZnJvbSB0aGlzIExpY2Vuc2UgYXJlIG9mZmVyZWQgYnkgUmVjaXBpZW50IGFsb25lLCBub3QgYnkgU0dJLiBSZWNpcGllbnQKLWhlcmVieSBhZ3JlZXMgdG8gaW5kZW1uaWZ5IFNHSSBmb3IgYW55IGxpYWJpbGl0eSBpbmN1cnJlZCBieSBTR0kgYXMgYSByZXN1bHQKLW9mIGFueSBzdWNoIHRlcm1zIFJlY2lwaWVudCBvZmZlcnMuCi0KLTMuIFJlZGlzdHJpYnV0aW9uIGluIEV4ZWN1dGFibGUgRm9ybS4gVGhlIG5vdGljZSBzZXQgZm9ydGggaW4gRXhoaWJpdCBBIG11c3QKLWJlIGNvbnNwaWN1b3VzbHkgaW5jbHVkZWQgaW4gYW55IG5vdGljZSBpbiBhbiBleGVjdXRhYmxlIHZlcnNpb24gb2YgU3ViamVjdAotU29mdHdhcmUsIHJlbGF0ZWQgZG9jdW1lbnRhdGlvbiBvciBjb2xsYXRlcmFsIGluIHdoaWNoIFJlY2lwaWVudCBkZXNjcmliZXMgdGhlCi11c2VyJ3MgcmlnaHRzIHJlbGF0aW5nIHRvIHRoZSBTdWJqZWN0IFNvZnR3YXJlLiBSZWNpcGllbnQgbWF5IGRpc3RyaWJ1dGUgdGhlCi1leGVjdXRhYmxlIHZlcnNpb24gb2YgU3ViamVjdCBTb2Z0d2FyZSB1bmRlciBhIGxpY2Vuc2Ugb2YgUmVjaXBpZW50J3MgY2hvaWNlLAotd2hpY2ggbWF5IGNvbnRhaW4gdGVybXMgZGlmZmVyZW50IGZyb20gdGhpcyBMaWNlbnNlLCBwcm92aWRlZCB0aGF0IChpKQotUmVjaXBpZW50IGlzIGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgdGVybXMgb2YgdGhpcyBMaWNlbnNlLCBhbmQgKGlpKSB0aGUKLWxpY2Vuc2UgdGVybXMgaW5jbHVkZSB0aGlzIFNlY3Rpb24gMyBhbmQgU2VjdGlvbnMgNCwgNywgOCwgMTAsIDEyIGFuZCAxMyBvZgotdGhpcyBMaWNlbnNlLCB3aGljaCB0ZXJtcyBtYXkgbm90IGJlIG1vZGlmaWVkIG9yIHN1cGVyc2VkZWQgYnkgYW55IG90aGVyIHRlcm1zCi1vZiBzdWNoIGxpY2Vuc2UuIElmIFJlY2lwaWVudCBkaXN0cmlidXRlcyB0aGUgZXhlY3V0YWJsZSB2ZXJzaW9uIHVuZGVyIGEKLWRpZmZlcmVudCBsaWNlbnNlIFJlY2lwaWVudCBtdXN0IG1ha2UgaXQgYWJzb2x1dGVseSBjbGVhciB0aGF0IGFueSB0ZXJtcyB3aGljaAotZGlmZmVyIGZyb20gdGhpcyBMaWNlbnNlIGFyZSBvZmZlcmVkIGJ5IFJlY2lwaWVudCBhbG9uZSwgbm90IGJ5IFNHSS4gUmVjaXBpZW50Ci1oZXJlYnkgYWdyZWVzIHRvIGluZGVtbmlmeSBTR0kgZm9yIGFueSBsaWFiaWxpdHkgaW5jdXJyZWQgYnkgU0dJIGFzIGEgcmVzdWx0Ci1vZiBhbnkgc3VjaCB0ZXJtcyBSZWNpcGllbnQgb2ZmZXJzLgotCi00LiBUZXJtaW5hdGlvbi4gVGhpcyBMaWNlbnNlIGFuZCB0aGUgcmlnaHRzIGdyYW50ZWQgaGVyZXVuZGVyIHdpbGwgdGVybWluYXRlCi1hdXRvbWF0aWNhbGx5IGlmIFJlY2lwaWVudCBmYWlscyB0byBjb21wbHkgd2l0aCB0ZXJtcyBoZXJlaW4gYW5kIGZhaWxzIHRvIGN1cmUKLXN1Y2ggYnJlYWNoIHdpdGhpbiAzMCBkYXlzIG9mIHRoZSBicmVhY2guIEFueSBzdWJsaWNlbnNlIHRvIHRoZSBTdWJqZWN0Ci1Tb2Z0d2FyZSB3aGljaCBpcyBwcm9wZXJseSBncmFudGVkIHNoYWxsIHN1cnZpdmUgYW55IHRlcm1pbmF0aW9uIG9mIHRoaXMKLUxpY2Vuc2UgYWJzZW50IHRlcm1pbmF0aW9uIGJ5IHRoZSB0ZXJtcyBvZiBzdWNoIHN1YmxpY2Vuc2UuIFByb3Zpc2lvbnMgd2hpY2gsCi1ieSB0aGVpciBuYXR1cmUsIG11c3QgcmVtYWluIGluIGVmZmVjdCBiZXlvbmQgdGhlIHRlcm1pbmF0aW9uIG9mIHRoaXMgTGljZW5zZQotc2hhbGwgc3Vydml2ZS4KLQotNS4gTm8gVHJhZGVtYXJrIFJpZ2h0cy4gVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IGFueSByaWdodHMgdG8gdXNlIGFueQotdHJhZGUgbmFtZSwgdHJhZGVtYXJrIG9yIHNlcnZpY2UgbWFyayB3aGF0c29ldmVyLiBObyB0cmFkZSBuYW1lLCB0cmFkZW1hcmsgb3IKLXNlcnZpY2UgbWFyayBvZiBTR0kgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQotdGhlIFN1YmplY3QgU29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgU0dJLgotCi02LiBObyBPdGhlciBSaWdodHMuIFRoaXMgTGljZW5zZSBkb2VzIG5vdCBncmFudCBhbnkgcmlnaHRzIHdpdGggcmVzcGVjdCB0byB0aGUKLU9wZW5HTCBBUEkgb3IgdG8gYW55IHNvZnR3YXJlIG9yIGhhcmR3YXJlIGltcGxlbWVudGF0aW9uIHRoZXJlb2Ygb3IgdG8gYW55Ci1vdGhlciBzb2Z0d2FyZSB3aGF0c29ldmVyLCBub3Igc2hhbGwgYW55IG90aGVyIHJpZ2h0cyBvciBsaWNlbnNlcyBub3QKLWV4cHJlc3NseSBncmFudGVkIGhlcmV1bmRlciBhcmlzZSBieSBpbXBsaWNhdGlvbiwgZXN0b3BwZWwgb3Igb3RoZXJ3aXNlIHdpdGgKLXJlc3BlY3QgdG8gdGhlIFN1YmplY3QgU29mdHdhcmUuIFRpdGxlIHRvIGFuZCBvd25lcnNoaXAgb2YgdGhlIE9yaWdpbmFsCi1Tb2Z0d2FyZSBhdCBhbGwgdGltZXMgcmVtYWlucyB3aXRoIFNHSS4gQWxsIHJpZ2h0cyBpbiB0aGUgT3JpZ2luYWwgU29mdHdhcmUKLW5vdCBleHByZXNzbHkgZ3JhbnRlZCB1bmRlciB0aGlzIExpY2Vuc2UgYXJlIHJlc2VydmVkLgotCi03LiBDb21wbGlhbmNlIHdpdGggTGF3czsgTm9uLUluZnJpbmdlbWVudC4gUmVjaXBpZW50IHNoYWxsIGNvbXBseSB3aXRoIGFsbAotYXBwbGljYWJsZSBsYXdzIGFuZCByZWd1bGF0aW9ucyBpbiBjb25uZWN0aW9uIHdpdGggdXNlIGFuZCBkaXN0cmlidXRpb24gb2YgdGhlCi1TdWJqZWN0IFNvZnR3YXJlLCBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvLCBhbGwgZXhwb3J0IGFuZCBpbXBvcnQgY29udHJvbAotbGF3cyBhbmQgcmVndWxhdGlvbnMgb2YgdGhlIFUuUy4gZ292ZXJubWVudCBhbmQgb3RoZXIgY291bnRyaWVzLiBSZWNpcGllbnQgbWF5Ci1ub3QgZGlzdHJpYnV0ZSBTdWJqZWN0IFNvZnR3YXJlIHRoYXQgKGkpIGluIGFueSB3YXkgaW5mcmluZ2VzIChkaXJlY3RseSBvcgotY29udHJpYnV0b3JpbHkpIHRoZSByaWdodHMgKGluY2x1ZGluZyBwYXRlbnQsIGNvcHlyaWdodCwgdHJhZGUgc2VjcmV0LAotdHJhZGVtYXJrIG9yIG90aGVyIGludGVsbGVjdHVhbCBwcm9wZXJ0eSByaWdodHMgb2YgYW55IGtpbmQpIG9mIGFueSBvdGhlcgotcGVyc29uIG9yIGVudGl0eSBvciAoaWkpIGJyZWFjaGVzIGFueSByZXByZXNlbnRhdGlvbiBvciB3YXJyYW50eSwgZXhwcmVzcywKLWltcGxpZWQgb3Igc3RhdHV0b3J5LCB3aGljaCB1bmRlciBhbnkgYXBwbGljYWJsZSBsYXcgaXQgbWlnaHQgYmUgZGVlbWVkIHRvCi1oYXZlIGJlZW4gZGlzdHJpYnV0ZWQuCi0KLTguIENsYWltcyBvZiBJbmZyaW5nZW1lbnQuIElmIFJlY2lwaWVudCBhdCBhbnkgdGltZSBoYXMga25vd2xlZGdlIG9mIGFueSBvbmUKLW9yIG1vcmUgdGhpcmQgcGFydHkgY2xhaW1zIHRoYXQgcmVwcm9kdWN0aW9uLCBtb2RpZmljYXRpb24sIHVzZSwgZGlzdHJpYnV0aW9uLAotaW1wb3J0IG9yIHNhbGUgb2YgU3ViamVjdCBTb2Z0d2FyZSAoaW5jbHVkaW5nIHBhcnRpY3VsYXIgZnVuY3Rpb25hbGl0eSBvciBjb2RlCi1pbmNvcnBvcmF0ZWQgaW4gU3ViamVjdCBTb2Z0d2FyZSkgaW5mcmluZ2VzIHRoZSB0aGlyZCBwYXJ0eSdzIGludGVsbGVjdHVhbAotcHJvcGVydHkgcmlnaHRzLCBSZWNpcGllbnQgbXVzdCBwbGFjZSBpbiBhIHdlbGwtaWRlbnRpZmllZCB3ZWIgcGFnZSBiZWFyaW5nCi10aGUgdGl0bGUgIkxFR0FMIiBhIGRlc2NyaXB0aW9uIG9mIGVhY2ggc3VjaCBjbGFpbSBhbmQgYSBkZXNjcmlwdGlvbiBvZiB0aGUKLXBhcnR5IG1ha2luZyBlYWNoIHN1Y2ggY2xhaW0gaW4gc3VmZmljaWVudCBkZXRhaWwgdGhhdCBhIHVzZXIgb2YgdGhlIFN1YmplY3QKLVNvZnR3YXJlIHdpbGwga25vdyB3aG9tIHRvIGNvbnRhY3QgcmVnYXJkaW5nIHRoZSBjbGFpbS4gQWxzbywgdXBvbiBnYWluaW5nCi1zdWNoIGtub3dsZWRnZSBvZiBhbnkgc3VjaCBjbGFpbSwgUmVjaXBpZW50IG11c3QgY29uc3BpY3VvdXNseSBpbmNsdWRlIHRoZSBVUkwKLWZvciBzdWNoIHdlYiBwYWdlIGluIHRoZSBFeGhpYml0IEEgbm90aWNlIHJlcXVpcmVkIHVuZGVyIFNlY3Rpb25zIDIgYW5kIDMsCi1hYm92ZSwgYW5kIGluIHRoZSB0ZXh0IG9mIGFueSByZWxhdGVkIGRvY3VtZW50YXRpb24sIGxpY2Vuc2UgYWdyZWVtZW50IG9yCi1jb2xsYXRlcmFsIGluIHdoaWNoIFJlY2lwaWVudCBkZXNjcmliZXMgZW5kIHVzZXIncyByaWdodHMgcmVsYXRpbmcgdG8gdGhlCi1TdWJqZWN0IFNvZnR3YXJlLiBJZiBSZWNpcGllbnQgb2J0YWlucyBzdWNoIGtub3dsZWRnZSBhZnRlciBpdCBtYWtlcyBTdWJqZWN0Ci1Tb2Z0d2FyZSBhdmFpbGFibGUgdG8gYW55IG90aGVyIHBlcnNvbiBvciBlbnRpdHksIFJlY2lwaWVudCBzaGFsbCB0YWtlIG90aGVyCi1zdGVwcyAoc3VjaCBhcyBub3RpZnlpbmcgYXBwcm9wcmlhdGUgbWFpbGluZyBsaXN0cyBvciBuZXdzZ3JvdXBzKSByZWFzb25hYmx5Ci1jYWxjdWxhdGVkIHRvIGluZm9ybSB0aG9zZSB3aG8gcmVjZWl2ZWQgdGhlIFN1YmplY3QgU29mdHdhcmUgdGhhdCBuZXcKLWtub3dsZWRnZSBoYXMgYmVlbiBvYnRhaW5lZC4KLQotOS4gRElTQ0xBSU1FUiBPRiBXQVJSQU5UWS4gU1VCSkVDVCBTT0ZUV0FSRSBJUyBQUk9WSURFRCBPTiBBTiAiQVMgSVMiIEJBU0lTLAotV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRUlUSEVSIEVYUFJFU1NFRCBPUiBJTVBMSUVELCBJTkNMVURJTkcsIFdJVEhPVVQKLUxJTUlUQVRJT04sIFdBUlJBTlRJRVMgVEhBVCBUSEUgU1VCSkVDVCBTT0ZUV0FSRSBJUyBGUkVFIE9GIERFRkVDVFMsCi1NRVJDSEFOVEFCTEUsIEZJVCBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgT1IgTk9OLSBJTkZSSU5HSU5HLiBTR0kgQVNTVU1FUyBOTwotUklTSyBBUyBUTyBUSEUgUVVBTElUWSBBTkQgUEVSRk9STUFOQ0UgT0YgVEhFIFNPRlRXQVJFLiBTSE9VTEQgQU5ZIFNPRlRXQVJFCi1QUk9WRSBERUZFQ1RJVkUgSU4gQU5ZIFJFU1BFQ1QsIFNHSSBBU1NVTUVTIE5PIENPU1QgT1IgTElBQklMSVRZIEZPUiBBTlkKLVNFUlZJQ0lORywgUkVQQUlSIE9SIENPUlJFQ1RJT04uIFRISVMgRElTQ0xBSU1FUiBPRiBXQVJSQU5UWSBDT05TVElUVVRFUyBBTgotRVNTRU5USUFMIFBBUlQgT0YgVEhJUyBMSUNFTlNFLiBOTyBVU0UgT0YgQU5ZIFNVQkpFQ1QgU09GVFdBUkUgSVMgQVVUSE9SSVpFRAotSEVSRVVOREVSIEVYQ0VQVCBVTkRFUiBUSElTIERJU0NMQUlNRVIuCi0KLTEwLiBMSU1JVEFUSU9OIE9GIExJQUJJTElUWS4gVU5ERVIgTk8gQ0lSQ1VNU1RBTkNFUyBBTkQgVU5ERVIgTk8gTEVHQUwgVEhFT1JZLAotV0hFVEhFUiBUT1JUIChJTkNMVURJTkcsIFdJVEhPVVQgTElNSVRBVElPTiwgTkVHTElHRU5DRSBPUiBTVFJJQ1QgTElBQklMSVRZKSwKLUNPTlRSQUNULCBPUiBPVEhFUldJU0UsIFNIQUxMIFNHSSBPUiBBTlkgU0dJIExJQ0VOU09SIEJFIExJQUJMRSBGT1IgQU5ZCi1ESVJFQ1QsIElORElSRUNULCBTUEVDSUFMLCBJTkNJREVOVEFMLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgT0YgQU5ZCi1DSEFSQUNURVIgSU5DTFVESU5HLCBXSVRIT1VUIExJTUlUQVRJT04sIERBTUFHRVMgRk9SIExPU1MgT0YgR09PRFdJTEwsIFdPUksKLVNUT1BQQUdFLCBMT1NTIE9GIERBVEEsIENPTVBVVEVSIEZBSUxVUkUgT1IgTUFMRlVOQ1RJT04sIE9SIEFOWSBBTkQgQUxMIE9USEVSCi1DT01NRVJDSUFMIERBTUFHRVMgT1IgTE9TU0VTLCBFVkVOIElGIFNVQ0ggUEFSVFkgU0hBTEwgSEFWRSBCRUVOIElORk9STUVEIE9GCi1USEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0VTLiBUSElTIExJTUlUQVRJT04gT0YgTElBQklMSVRZIFNIQUxMIE5PVCBBUFBMWQotVE8gTElBQklMSVRZIEZPUiBERUFUSCBPUiBQRVJTT05BTCBJTkpVUlkgUkVTVUxUSU5HIEZST00gU0dJJ3MgTkVHTElHRU5DRSBUTwotVEhFIEVYVEVOVCBBUFBMSUNBQkxFIExBVyBQUk9ISUJJVFMgU1VDSCBMSU1JVEFUSU9OLiBTT01FIEpVUklTRElDVElPTlMgRE8gTk9UCi1BTExPVyBUSEUgRVhDTFVTSU9OIE9SIExJTUlUQVRJT04gT0YgSU5DSURFTlRBTCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMsIFNPCi1USEFUIEVYQ0xVU0lPTiBBTkQgTElNSVRBVElPTiBNQVkgTk9UIEFQUExZIFRPIFJFQ0lQSUVOVC4KLQotMTEuIEluZGVtbml0eS4gUmVjaXBpZW50IHNoYWxsIGJlIHNvbGVseSByZXNwb25zaWJsZSBmb3IgZGFtYWdlcyBhcmlzaW5nLAotZGlyZWN0bHkgb3IgaW5kaXJlY3RseSwgb3V0IG9mIGl0cyB1dGlsaXphdGlvbiBvZiByaWdodHMgdW5kZXIgdGhpcyBMaWNlbnNlLgotUmVjaXBpZW50IHdpbGwgZGVmZW5kLCBpbmRlbW5pZnkgYW5kIGhvbGQgaGFybWxlc3MgU2lsaWNvbiBHcmFwaGljcywgSW5jLiBmcm9tCi1hbmQgYWdhaW5zdCBhbnkgbG9zcywgbGlhYmlsaXR5LCBkYW1hZ2VzLCBjb3N0cyBvciBleHBlbnNlcyAoaW5jbHVkaW5nIHRoZQotcGF5bWVudCBvZiByZWFzb25hYmxlIGF0dG9ybmV5cyBmZWVzKSBhcmlzaW5nIG91dCBvZiBSZWNpcGllbnQncyB1c2UsCi1tb2RpZmljYXRpb24sIHJlcHJvZHVjdGlvbiBhbmQgZGlzdHJpYnV0aW9uIG9mIHRoZSBTdWJqZWN0IFNvZnR3YXJlIG9yIG91dCBvZgotYW55IHJlcHJlc2VudGF0aW9uIG9yIHdhcnJhbnR5IG1hZGUgYnkgUmVjaXBpZW50LgotCi0xMi4gVS5TLiBHb3Zlcm5tZW50IEVuZCBVc2Vycy4gVGhlIFN1YmplY3QgU29mdHdhcmUgaXMgYSAiY29tbWVyY2lhbCBpdGVtIgotY29uc2lzdGluZyBvZiAiY29tbWVyY2lhbCBjb21wdXRlciBzb2Z0d2FyZSIgYXMgc3VjaCB0ZXJtcyBhcmUgZGVmaW5lZCBpbgotdGl0bGUgNDggb2YgdGhlIENvZGUgb2YgRmVkZXJhbCBSZWd1bGF0aW9ucyBhbmQgYWxsIFUuUy4gR292ZXJubWVudCBFbmQgVXNlcnMKLWFjcXVpcmUgb25seSB0aGUgcmlnaHRzIHNldCBmb3J0aCBpbiB0aGlzIExpY2Vuc2UgYW5kIGFyZSBzdWJqZWN0IHRvIHRoZSB0ZXJtcwotb2YgdGhpcyBMaWNlbnNlLgotCi0xMy4gTWlzY2VsbGFuZW91cy4gVGhpcyBMaWNlbnNlIHJlcHJlc2VudHMgdGhlIGNvbXBsZXRlIGFncmVlbWVudCBjb25jZXJuaW5nCi1zdWJqZWN0IG1hdHRlciBoZXJlb2YuIElmIGFueSBwcm92aXNpb24gb2YgdGhpcyBMaWNlbnNlIGlzIGhlbGQgdG8gYmUKLXVuZW5mb3JjZWFibGUsIHN1Y2ggcHJvdmlzaW9uIHNoYWxsIGJlIHJlZm9ybWVkIHNvIGFzIHRvIGFjaGlldmUgYXMgbmVhcmx5IGFzCi1wb3NzaWJsZSB0aGUgc2FtZSBlY29ub21pYyBlZmZlY3QgYXMgdGhlIG9yaWdpbmFsIHByb3Zpc2lvbiBhbmQgdGhlIHJlbWFpbmRlcgotb2YgdGhpcyBMaWNlbnNlIHdpbGwgcmVtYWluIGluIGVmZmVjdC4gVGhpcyBMaWNlbnNlIHNoYWxsIGJlIGdvdmVybmVkIGJ5IGFuZAotY29uc3RydWVkIGluIGFjY29yZGFuY2Ugd2l0aCB0aGUgbGF3cyBvZiB0aGUgVW5pdGVkIFN0YXRlcyBhbmQgdGhlIFN0YXRlIG9mCi1DYWxpZm9ybmlhIGFzIGFwcGxpZWQgdG8gYWdyZWVtZW50cyBlbnRlcmVkIGludG8gYW5kIHRvIGJlIHBlcmZvcm1lZCBlbnRpcmVseQotd2l0aGluIENhbGlmb3JuaWEgYmV0d2VlbiBDYWxpZm9ybmlhIHJlc2lkZW50cy4gQW55IGxpdGlnYXRpb24gcmVsYXRpbmcgdG8KLXRoaXMgTGljZW5zZSBzaGFsbCBiZSBzdWJqZWN0IHRvIHRoZSBleGNsdXNpdmUganVyaXNkaWN0aW9uIG9mIHRoZSBGZWRlcmFsCi1Db3VydHMgb2YgdGhlIE5vcnRoZXJuIERpc3RyaWN0IG9mIENhbGlmb3JuaWEgKG9yLCBhYnNlbnQgc3ViamVjdCBtYXR0ZXIKLWp1cmlzZGljdGlvbiBpbiBzdWNoIGNvdXJ0cywgdGhlIGNvdXJ0cyBvZiB0aGUgU3RhdGUgb2YgQ2FsaWZvcm5pYSksIHdpdGgKLXZlbnVlIGx5aW5nIGV4Y2x1c2l2ZWx5IGluIFNhbnRhIENsYXJhIENvdW50eSwgQ2FsaWZvcm5pYSwgd2l0aCB0aGUgbG9zaW5nCi1wYXJ0eSByZXNwb25zaWJsZSBmb3IgY29zdHMsIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24sIGNvdXJ0IGNvc3RzIGFuZAotcmVhc29uYWJsZSBhdHRvcm5leXMgZmVlcyBhbmQgZXhwZW5zZXMuIFRoZSBhcHBsaWNhdGlvbiBvZiB0aGUgVW5pdGVkIE5hdGlvbnMKLUNvbnZlbnRpb24gb24gQ29udHJhY3RzIGZvciB0aGUgSW50ZXJuYXRpb25hbCBTYWxlIG9mIEdvb2RzIGlzIGV4cHJlc3NseQotZXhjbHVkZWQuIEFueSBsYXcgb3IgcmVndWxhdGlvbiB3aGljaCBwcm92aWRlcyB0aGF0IHRoZSBsYW5ndWFnZSBvZiBhIGNvbnRyYWN0Ci1zaGFsbCBiZSBjb25zdHJ1ZWQgYWdhaW5zdCB0aGUgZHJhZnRlciBzaGFsbCBub3QgYXBwbHkgdG8gdGhpcyBMaWNlbnNlLgotCi1FeGhpYml0IEEKLQotVGhlIGNvbnRlbnRzIG9mIHRoaXMgZmlsZSBhcmUgc3ViamVjdCB0byBTZWN0aW9ucyAyLCAzLCA0LCA3LCA4LCAxMCwgMTIgYW5kIDEzCi1vZiB0aGUgR0xYIFB1YmxpYyBMaWNlbnNlIFZlcnNpb24gMS4wICh0aGUgIkxpY2Vuc2UiKS4gWW91IG1heSBub3QgdXNlIHRoaXMKLWZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aG9zZSBzZWN0aW9ucyBvZiB0aGUgTGljZW5zZS4gWW91IG1heSBvYnRhaW4gYQotY29weSBvZiB0aGUgTGljZW5zZSBhdCBTaWxpY29uIEdyYXBoaWNzLCBJbmMuLCBhdHRuOiBMZWdhbCBTZXJ2aWNlcywgMjAxMSBOLgotU2hvcmVsaW5lIEJsdmQuLCBNb3VudGFpbiBWaWV3LCBDQSA5NDA0MyBvciBhdAotaHR0cDovL3d3dy5zZ2kuY29tL3NvZnR3YXJlL29wZW5zb3VyY2UvZ2x4L2xpY2Vuc2UuaHRtbC4KLQotU29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBiYXNpcy4gQUxMCi1XQVJSQU5USUVTIEFSRSBESVNDTEFJTUVELCBJTkNMVURJTkcsIFdJVEhPVVQgTElNSVRBVElPTiwgQU5ZIElNUExJRUQKLVdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLCBPRiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBPUiBPRiBOT04tCi1JTkZSSU5HRU1FTlQuIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyByaWdodHMgYW5kCi1saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLQotVGhlIE9yaWdpbmFsIFNvZnR3YXJlIGlzIEdMWCB2ZXJzaW9uIDEuMiBzb3VyY2UgY29kZSwgcmVsZWFzZWQgRmVicnVhcnksIDE5OTkuCi1UaGUgZGV2ZWxvcGVyIG9mIHRoZSBPcmlnaW5hbCBTb2Z0d2FyZSBpcyBTaWxpY29uIEdyYXBoaWNzLCBJbmMuIFRob3NlCi1wb3J0aW9ucyBvZiB0aGUgU3ViamVjdCBTb2Z0d2FyZSBjcmVhdGVkIGJ5IFNpbGljb24gR3JhcGhpY3MsIEluYy4gYXJlCi1Db3B5cmlnaHQgKGMpIDE5OTEtOSBTaWxpY29uIEdyYXBoaWNzLCBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuICAzLjUuIENJRAotRm9udCBDb2RlIFB1YmxpYyBMaWNlbnNlCi0KLUNJRCBGT05UIENPREUgUFVCTElDIExJQ0VOU0UgKFZlcnNpb24gMS4wICgzLzMxLzk5KSkoIkxpY2Vuc2UiKQotCi1TdWJqZWN0IHRvIGFueSBhcHBsaWNhYmxlIHRoaXJkIHBhcnR5IGNsYWltcywgU2lsaWNvbiBHcmFwaGljcywgSW5jLiAoIlNHSSIpCi1oZXJlYnkgZ3JhbnRzIHBlcm1pc3Npb24gdG8gUmVjaXBpZW50IChkZWZpbmVkIGJlbG93KSwgdW5kZXIgU0dJJ3MgY29weXJpZ2h0cwotaW4gdGhlIE9yaWdpbmFsIFNvZnR3YXJlIChkZWZpbmVkIGJlbG93KSwgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLAotcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgU3ViamVjdCBTb2Z0d2FyZQotKGRlZmluZWQgYmVsb3cpIGluIGJvdGggc291cmNlIGNvZGUgYW5kIGV4ZWN1dGFibGUgZm9ybSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zCi10byB3aG9tIHRoZSBTdWJqZWN0IFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCBpbiBhY2NvcmRhbmNlIHdpdGggdGhpcyBMaWNlbnNlIHRvCi1kbyB0aGUgc2FtZSwgc3ViamVjdCB0byBhbGwgb2YgdGhlIGZvbGxvd2luZyB0ZXJtcyBhbmQgY29uZGl0aW9ucywgd2hpY2gKLVJlY2lwaWVudCBhY2NlcHRzIGJ5IGVuZ2FnaW5nIGluIGFueSBzdWNoIHVzZSwgY29weWluZywgbW9kaWZ5aW5nLCBtZXJnaW5nLAotcHVibGljYXRpb24sIGRpc3RyaWJ1dGluZywgc3VibGljZW5zaW5nIG9yIHNlbGxpbmc6Ci0KLTEuIERlZmluaXRpb25zLgotCi0gICAgYS4gIk9yaWdpbmFsIFNvZnR3YXJlIiBtZWFucyBzb3VyY2UgY29kZSBvZiBjb21wdXRlciBzb2Z0d2FyZSBjb2RlIHRoYXQgaXMKLSAgICBkZXNjcmliZWQgaW4gRXhoaWJpdCBBIGFzIE9yaWdpbmFsIFNvZnR3YXJlLgotCi0gICAgYi4gIk1vZGlmaWNhdGlvbnMiIG1lYW5zIGFueSBhZGRpdGlvbiB0byBvciBkZWxldGlvbiBmcm9tIHRoZSBzdWJzdGFuY2Ugb3IKLSAgICBzdHJ1Y3R1cmUgb2YgZWl0aGVyIHRoZSBPcmlnaW5hbCBTb2Z0d2FyZSBvciBhbnkgcHJldmlvdXMgTW9kaWZpY2F0aW9ucy4KLSAgICBXaGVuIFN1YmplY3QgU29mdHdhcmUgaXMgcmVsZWFzZWQgYXMgYSBzZXJpZXMgb2YgZmlsZXMsIGEgTW9kaWZpY2F0aW9uCi0gICAgbWVhbnMgKGkpIGFueSBhZGRpdGlvbiB0byBvciBkZWxldGlvbiBmcm9tIHRoZSBjb250ZW50cyBvZiBhIGZpbGUKLSAgICBjb250YWluaW5nIE9yaWdpbmFsIFNvZnR3YXJlIG9yIHByZXZpb3VzIE1vZGlmaWNhdGlvbnMgYW5kIChpaSkgYW55IG5ldwotICAgIGZpbGUgdGhhdCBjb250YWlucyBhbnkgcGFydCBvZiB0aGUgT3JpZ2luYWwgQ29kZSBvciBwcmV2aW91cwotICAgIE1vZGlmaWNhdGlvbnMuCi0KLSAgICBjLiAiU3ViamVjdCBTb2Z0d2FyZSIgbWVhbnMgdGhlIE9yaWdpbmFsIFNvZnR3YXJlIG9yIE1vZGlmaWNhdGlvbnMgb3IgdGhlCi0gICAgY29tYmluYXRpb24gb2YgdGhlIE9yaWdpbmFsIFNvZnR3YXJlIGFuZCBNb2RpZmljYXRpb25zLCBvciBwb3J0aW9ucyBvZiBhbnkKLSAgICBvZiB0aGUgZm9yZWdvaW5nLgotCi0gICAgZC4gIlJlY2lwaWVudCIgbWVhbnMgYW4gaW5kaXZpZHVhbCBvciBhIGxlZ2FsIGVudGl0eSBleGVyY2lzaW5nIHJpZ2h0cwotICAgIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGlzIExpY2Vuc2UuIEZvciBsZWdhbCBlbnRpdGllcywgIlJlY2lwaWVudCIgaW5jbHVkZXMKLSAgICBhbnkgZW50aXR5IHRoYXQgY29udHJvbHMsIGlzIGNvbnRyb2xsZWQgYnksIG9yIGlzIHVuZGVyIGNvbW1vbiBjb250cm9sCi0gICAgd2l0aCBSZWNpcGllbnQuIEZvciBwdXJwb3NlcyBvZiB0aGlzIGRlZmluaXRpb24sICJjb250cm9sIiBvZiBhbiBlbnRpdHkKLSAgICBtZWFucyAoaSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IgaW5kaXJlY3QsIHRvIGRpcmVjdCBvciBtYW5hZ2Ugc3VjaCBlbnRpdHksCi0gICAgb3IgKGlpKSBvd25lcnNoaXAgb2YgZmlmdHkgcGVyY2VudCAoNTAlKSBvciBtb3JlIG9mIHRoZSBvdXRzdGFuZGluZyBzaGFyZXMKLSAgICBvciBiZW5lZmljaWFsIG93bmVyc2hpcCBvZiBzdWNoIGVudGl0eS4KLQotICAgIGUuICJSZXF1aXJlZCBOb3RpY2UiIG1lYW5zIHRoZSBub3RpY2Ugc2V0IGZvcnRoIGluIEV4aGliaXQgQSB0byB0aGlzCi0gICAgTGljZW5zZS4KLQotICAgIGYuICJBY2NvbXBhbnlpbmcgVGVjaG5vbG9neSIgbWVhbnMgYW55IHNvZnR3YXJlIG9yIG90aGVyIHRlY2hub2xvZ3kgdGhhdAotICAgIGlzIG5vdCBhIE1vZGlmaWNhdGlvbiBhbmQgdGhhdCBpcyBkaXN0cmlidXRlZCBvciBtYWRlIHB1YmxpY2x5IGF2YWlsYWJsZQotICAgIGJ5IFJlY2lwaWVudCB3aXRoIHRoZSBTdWJqZWN0IFNvZnR3YXJlLiBTZXBhcmF0ZSBzb2Z0d2FyZSBmaWxlcyB0aGF0IGRvCi0gICAgbm90IGNvbnRhaW4gYW55IE9yaWdpbmFsIFNvZnR3YXJlIG9yIGFueSBwcmV2aW91cyBNb2RpZmljYXRpb24gc2hhbGwgbm90Ci0gICAgYmUgZGVlbWVkIGEgTW9kaWZpY2F0aW9uLCBldmVuIGlmIHN1Y2ggc29mdHdhcmUgZmlsZXMgYXJlIGFnZ3JlZ2F0ZWQgYXMKLSAgICBwYXJ0IG9mIGEgcHJvZHVjdCwgb3IgaW4gYW55IG1lZGl1bSBvZiBzdG9yYWdlLCB3aXRoIGFueSBmaWxlIHRoYXQgZG9lcwotICAgIGNvbnRhaW4gT3JpZ2luYWwgU29mdHdhcmUgb3IgYW55IHByZXZpb3VzIE1vZGlmaWNhdGlvbi4KLQotMi4gTGljZW5zZSBUZXJtcy4gQWxsIGRpc3RyaWJ1dGlvbiBvZiB0aGUgU3ViamVjdCBTb2Z0d2FyZSBtdXN0IGJlIG1hZGUKLXN1YmplY3QgdG8gdGhlIHRlcm1zIG9mIHRoaXMgTGljZW5zZS4gQSBjb3B5IG9mIHRoaXMgTGljZW5zZSBhbmQgdGhlIFJlcXVpcmVkCi1Ob3RpY2UgbXVzdCBiZSBpbmNsdWRlZCBpbiBhbnkgZG9jdW1lbnRhdGlvbiBmb3IgU3ViamVjdCBTb2Z0d2FyZSB3aGVyZQotUmVjaXBpZW50J3MgcmlnaHRzIHJlbGF0aW5nIHRvIFN1YmplY3QgU29mdHdhcmUgYW5kL29yIGFueSBBY2NvbXBhbnlpbmcKLVRlY2hub2xvZ3kgYXJlIGRlc2NyaWJlZC4gRGlzdHJpYnV0aW9ucyBvZiBTdWJqZWN0IFNvZnR3YXJlIGluIHNvdXJjZSBjb2RlCi1mb3JtIG11c3QgYWxzbyBpbmNsdWRlIHRoZSBSZXF1aXJlZCBOb3RpY2UgaW4gZXZlcnkgZmlsZSBkaXN0cmlidXRlZC4gSW4KLWFkZGl0aW9uLCBhIFJlYWRNZSBmaWxlIGVudGl0bGVkICJJbXBvcnRhbnQgTGVnYWwgTm90aWNlIiBtdXN0IGJlIGRpc3RyaWJ1dGVkCi13aXRoIGVhY2ggZGlzdHJpYnV0aW9uIG9mIG9uZSBvciBtb3JlIGZpbGVzIHRoYXQgaW5jb3Jwb3JhdGUgU3ViamVjdCBTb2Z0d2FyZS4KLVRoYXQgZmlsZSBtdXN0IGJlIGluY2x1ZGVkIHdpdGggZGlzdHJpYnV0aW9ucyBtYWRlIGluIGJvdGggc291cmNlIGNvZGUgYW5kCi1leGVjdXRhYmxlIGZvcm0uIEEgY29weSBvZiB0aGUgTGljZW5zZSBhbmQgdGhlIFJlcXVpcmVkIE5vdGljZSBtdXN0IGJlCi1pbmNsdWRlZCBpbiB0aGF0IGZpbGUuIFJlY2lwaWVudCBtYXkgZGlzdHJpYnV0ZSBBY2NvbXBhbnlpbmcgVGVjaG5vbG9neSB1bmRlcgotYSBsaWNlbnNlIG9mIFJlY2lwaWVudCdzIGNob2ljZSwgd2hpY2ggbWF5IGNvbnRhaW4gdGVybXMgZGlmZmVyZW50IGZyb20gdGhpcwotTGljZW5zZSwgcHJvdmlkZWQgdGhhdCAoaSkgUmVjaXBpZW50IGlzIGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgdGVybXMgb2YgdGhpcwotTGljZW5zZSwgKGlpKSBzdWNoIG90aGVyIGxpY2Vuc2UgdGVybXMgZG8gbm90IG1vZGlmeSBvciBzdXBlcnNlZGUgdGhlIHRlcm1zIG9mCi10aGlzIExpY2Vuc2UgYXMgYXBwbGljYWJsZSB0byB0aGUgU3ViamVjdCBTb2Z0d2FyZSwgKGlpaSkgUmVjaXBpZW50IGhlcmVieQotaW5kZW1uaWZpZXMgU0dJIGZvciBhbnkgbGlhYmlsaXR5IGluY3VycmVkIGJ5IFNHSSBhcyBhIHJlc3VsdCBvZiB0aGUKLWRpc3RyaWJ1dGlvbiBvZiBBY2NvbXBhbnlpbmcgVGVjaG5vbG9neSBvciB0aGUgdXNlIG9mIG90aGVyIGxpY2Vuc2UgdGVybXMuCi0KLTMuIFRlcm1pbmF0aW9uLiBUaGlzIExpY2Vuc2UgYW5kIHRoZSByaWdodHMgZ3JhbnRlZCBoZXJldW5kZXIgd2lsbCB0ZXJtaW5hdGUKLWF1dG9tYXRpY2FsbHkgaWYgUmVjaXBpZW50IGZhaWxzIHRvIGNvbXBseSB3aXRoIHRlcm1zIGhlcmVpbiBhbmQgZmFpbHMgdG8gY3VyZQotc3VjaCBicmVhY2ggd2l0aGluIDMwIGRheXMgb2YgdGhlIGJyZWFjaC4gQW55IHN1YmxpY2Vuc2UgdG8gdGhlIFN1YmplY3QKLVNvZnR3YXJlIHRoYXQgaXMgcHJvcGVybHkgZ3JhbnRlZCBzaGFsbCBzdXJ2aXZlIGFueSB0ZXJtaW5hdGlvbiBvZiB0aGlzCi1MaWNlbnNlIGFic2VudCB0ZXJtaW5hdGlvbiBieSB0aGUgdGVybXMgb2Ygc3VjaCBzdWJsaWNlbnNlLiBQcm92aXNpb25zIHdoaWNoLAotYnkgdGhlaXIgbmF0dXJlLCBtdXN0IHJlbWFpbiBpbiBlZmZlY3QgYmV5b25kIHRoZSB0ZXJtaW5hdGlvbiBvZiB0aGlzIExpY2Vuc2UKLXNoYWxsIHN1cnZpdmUuCi0KLTQuIFRyYWRlbWFyayBSaWdodHMuIFRoaXMgTGljZW5zZSBkb2VzIG5vdCBncmFudCBhbnkgcmlnaHRzIHRvIHVzZSBhbnkgdHJhZGUKLW5hbWUsIHRyYWRlbWFyayBvciBzZXJ2aWNlIG1hcmsgd2hhdHNvZXZlci4gTm8gdHJhZGUgbmFtZSwgdHJhZGVtYXJrIG9yCi1zZXJ2aWNlIG1hcmsgb2YgU0dJIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gb3IKLWluY29ycG9yYXRpbmcgYW55IFN1YmplY3QgU29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgU0dJLgotCi01LiBObyBPdGhlciBSaWdodHMuIE5vIHJpZ2h0cyBvciBsaWNlbnNlcyBub3QgZXhwcmVzc2x5IGdyYW50ZWQgaGVyZXVuZGVyCi1zaGFsbCBhcmlzZSBieSBpbXBsaWNhdGlvbiwgZXN0b3BwZWwgb3Igb3RoZXJ3aXNlLiBUaXRsZSB0byBhbmQgb3duZXJzaGlwIG9mCi10aGUgT3JpZ2luYWwgU29mdHdhcmUgYXQgYWxsIHRpbWVzIHJlbWFpbnMgd2l0aCBTR0kuIEFsbCByaWdodHMgaW4gdGhlCi1PcmlnaW5hbCBTb2Z0d2FyZSBub3QgZXhwcmVzc2x5IGdyYW50ZWQgdW5kZXIgdGhpcyBMaWNlbnNlIGFyZSByZXNlcnZlZC4KLQotNi4gQ29tcGxpYW5jZSB3aXRoIExhd3M7IE5vbi1JbmZyaW5nZW1lbnQuIFJlY2lwaWVudCBzaGFsbCBjb21wbHkgd2l0aCBhbGwKLWFwcGxpY2FibGUgbGF3cyBhbmQgcmVndWxhdGlvbnMgaW4gY29ubmVjdGlvbiB3aXRoIHVzZSBhbmQgZGlzdHJpYnV0aW9uIG9mIHRoZQotU3ViamVjdCBTb2Z0d2FyZSwgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0bywgYWxsIGV4cG9ydCBhbmQgaW1wb3J0IGNvbnRyb2wKLWxhd3MgYW5kIHJlZ3VsYXRpb25zIG9mIHRoZSBVLlMuIGdvdmVybm1lbnQgYW5kIG90aGVyIGNvdW50cmllcy4gUmVjaXBpZW50IG1heQotbm90IGRpc3RyaWJ1dGUgU3ViamVjdCBTb2Z0d2FyZSB0aGF0IChpKSBpbiBhbnkgd2F5IGluZnJpbmdlcyAoZGlyZWN0bHkgb3IKLWNvbnRyaWJ1dG9yaWx5KSB0aGUgcmlnaHRzIChpbmNsdWRpbmcgcGF0ZW50LCBjb3B5cmlnaHQsIHRyYWRlIHNlY3JldCwKLXRyYWRlbWFyayBvciBvdGhlciBpbnRlbGxlY3R1YWwgcHJvcGVydHkgcmlnaHRzIG9mIGFueSBraW5kKSBvZiBhbnkgb3RoZXIKLXBlcnNvbiBvciBlbnRpdHksIG9yIChpaSkgYnJlYWNoZXMgYW55IHJlcHJlc2VudGF0aW9uIG9yIHdhcnJhbnR5LCBleHByZXNzLAotaW1wbGllZCBvciBzdGF0dXRvcnksIHdoaWNoIHVuZGVyIGFueSBhcHBsaWNhYmxlIGxhdyBpdCBtaWdodCBiZSBkZWVtZWQgdG8KLWhhdmUgYmVlbiBkaXN0cmlidXRlZC4KLQotNy4gQ2xhaW1zIG9mIEluZnJpbmdlbWVudC4gSWYgUmVjaXBpZW50IGF0IGFueSB0aW1lIGhhcyBrbm93bGVkZ2Ugb2YgYW55IG9uZQotb3IgbW9yZSB0aGlyZCBwYXJ0eSBjbGFpbXMgdGhhdCByZXByb2R1Y3Rpb24sIG1vZGlmaWNhdGlvbiwgdXNlLCBkaXN0cmlidXRpb24sCi1pbXBvcnQgb3Igc2FsZSBvZiBTdWJqZWN0IFNvZnR3YXJlIChpbmNsdWRpbmcgcGFydGljdWxhciBmdW5jdGlvbmFsaXR5IG9yIGNvZGUKLWluY29ycG9yYXRlZCBpbiBTdWJqZWN0IFNvZnR3YXJlKSBpbmZyaW5nZXMgdGhlIHRoaXJkIHBhcnR5J3MgaW50ZWxsZWN0dWFsCi1wcm9wZXJ0eSByaWdodHMsIFJlY2lwaWVudCBtdXN0IHBsYWNlIGluIGEgd2VsbC1pZGVudGlmaWVkIHdlYiBwYWdlIGJlYXJpbmcKLXRoZSB0aXRsZSAiTEVHQUwiIGEgZGVzY3JpcHRpb24gb2YgZWFjaCBzdWNoIGNsYWltIGFuZCBhIGRlc2NyaXB0aW9uIG9mIHRoZQotcGFydHkgbWFraW5nIGVhY2ggc3VjaCBjbGFpbSBpbiBzdWZmaWNpZW50IGRldGFpbCB0aGF0IGEgdXNlciBvZiB0aGUgU3ViamVjdAotU29mdHdhcmUgd2lsbCBrbm93IHdob20gdG8gY29udGFjdCByZWdhcmRpbmcgdGhlIGNsYWltLiBBbHNvLCB1cG9uIGdhaW5pbmcKLXN1Y2gga25vd2xlZGdlIG9mIGFueSBzdWNoIGNsYWltLCBSZWNpcGllbnQgbXVzdCBjb25zcGljdW91c2x5IGluY2x1ZGUgdGhlIFVSTAotZm9yIHN1Y2ggd2ViIHBhZ2UgaW4gdGhlIFJlcXVpcmVkIE5vdGljZSwgYW5kIGluIHRoZSB0ZXh0IG9mIGFueSByZWxhdGVkCi1kb2N1bWVudGF0aW9uLCBsaWNlbnNlIGFncmVlbWVudCBvciBjb2xsYXRlcmFsIGluIHdoaWNoIFJlY2lwaWVudCBkZXNjcmliZXMKLWVuZCB1c2VyJ3MgcmlnaHRzIHJlbGF0aW5nIHRvIHRoZSBTdWJqZWN0IFNvZnR3YXJlLiBJZiBSZWNpcGllbnQgb2J0YWlucyBzdWNoCi1rbm93bGVkZ2UgYWZ0ZXIgaXQgbWFrZXMgU3ViamVjdCBTb2Z0d2FyZSBhdmFpbGFibGUgdG8gYW55IG90aGVyIHBlcnNvbiBvcgotZW50aXR5LCBSZWNpcGllbnQgc2hhbGwgdGFrZSBvdGhlciBzdGVwcyAoc3VjaCBhcyBub3RpZnlpbmcgYXBwcm9wcmlhdGUKLW1haWxpbmcgbGlzdHMgb3IgbmV3c2dyb3VwcykgcmVhc29uYWJseSBjYWxjdWxhdGVkIHRvIHByb3ZpZGUgc3VjaCBrbm93bGVkZ2UKLXRvIHRob3NlIHdobyByZWNlaXZlZCB0aGUgU3ViamVjdCBTb2Z0d2FyZS4KLQotOC4gRElTQ0xBSU1FUiBPRiBXQVJSQU5UWS4gU1VCSkVDVCBTT0ZUV0FSRSBJUyBQUk9WSURFRCBPTiBBTiAiQVMgSVMiIEJBU0lTLAotV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRUlUSEVSIEVYUFJFU1NFRCBPUiBJTVBMSUVELCBJTkNMVURJTkcsIFdJVEhPVVQKLUxJTUlUQVRJT04sIFdBUlJBTlRJRVMgVEhBVCBUSEUgU1VCSkVDVCBTT0ZUV0FSRSBJUyBGUkVFIE9GIERFRkVDVFMsCi1NRVJDSEFOVEFCTEUsIEZJVCBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgT1IgTk9OLUlORlJJTkdJTkcuIFNHSSBBU1NVTUVTIE5PCi1SSVNLIEFTIFRPIFRIRSBRVUFMSVRZIEFORCBQRVJGT1JNQU5DRSBPRiBUSEUgU09GVFdBUkUuIFNIT1VMRCBBTlkgU09GVFdBUkUKLVBST1ZFIERFRkVDVElWRSBJTiBBTlkgUkVTUEVDVCwgU0dJIEFTU1VNRVMgTk8gQ09TVCBPUiBMSUFCSUxJVFkgRk9SIEFOWQotU0VSVklDSU5HLCBSRVBBSVIgT1IgQ09SUkVDVElPTi4gVEhJUyBESVNDTEFJTUVSIE9GIFdBUlJBTlRZIENPTlNUSVRVVEVTIEFOCi1FU1NFTlRJQUwgUEFSVCBPRiBUSElTIExJQ0VOU0UuIE5PIFVTRSBPRiBBTlkgU1VCSkVDVCBTT0ZUV0FSRSBJUyBBVVRIT1JJWkVECi1IRVJFVU5ERVIgRVhDRVBUIFVOREVSIFRISVMgRElTQ0xBSU1FUi4KLQotOS4gTElNSVRBVElPTiBPRiBMSUFCSUxJVFkuIFVOREVSIE5PIENJUkNVTVNUQU5DRVMgQU5EIFVOREVSIE5PIExFR0FMIFRIRU9SWSwKLVdIRVRIRVIgVE9SVCAoSU5DTFVESU5HLCBXSVRIT1VUIExJTUlUQVRJT04sIE5FR0xJR0VOQ0UgT1IgU1RSSUNUIExJQUJJTElUWSksCi1DT05UUkFDVCwgT1IgT1RIRVJXSVNFLCBTSEFMTCBTR0kgT1IgQU5ZIFNHSSBMSUNFTlNPUiBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwKLURBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUgotT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNVQkpFQ1QgU09GVFdBUkUgT1IKLVRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNVQkpFQ1QgU09GVFdBUkUuIFNPTUUgSlVSSVNESUNUSU9OUyBETyBOT1QKLUFMTE9XIFRIRSBFWENMVVNJT04gT1IgTElNSVRBVElPTiBPRiBDRVJUQUlOIERBTUFHRVMsIFNPIFRISVMgRVhDTFVTSU9OIEFORAotTElNSVRBVElPTiBNQVkgTk9UIEFQUExZIFRPIFJFQ0lQSUVOVCBUTyBUSEUgRVhURU5UIFNPIERJU0FMTE9XRUQuCi0KLTEwLiBJbmRlbW5pdHkuIFJlY2lwaWVudCBzaGFsbCBiZSBzb2xlbHkgcmVzcG9uc2libGUgZm9yIGRhbWFnZXMgYXJpc2luZywKLWRpcmVjdGx5IG9yIGluZGlyZWN0bHksIG91dCBvZiBpdHMgdXRpbGl6YXRpb24gb2YgcmlnaHRzIHVuZGVyIHRoaXMgTGljZW5zZS4KLVJlY2lwaWVudCB3aWxsIGRlZmVuZCwgaW5kZW1uaWZ5IGFuZCBob2xkIFNHSSBhbmQgaXRzIHN1Y2Nlc3NvcnMgYW5kIGFzc2lnbnMKLWhhcm1sZXNzIGZyb20gYW5kIGFnYWluc3QgYW55IGxvc3MsIGxpYWJpbGl0eSwgZGFtYWdlcywgY29zdHMgb3IgZXhwZW5zZXMKLShpbmNsdWRpbmcgdGhlIHBheW1lbnQgb2YgcmVhc29uYWJsZSBhdHRvcm5leXMgZmVlcykgYXJpc2luZyBvdXQgb2YKLShSZWNpcGllbnQncyB1c2UsIG1vZGlmaWNhdGlvbiwgcmVwcm9kdWN0aW9uIGFuZCBkaXN0cmlidXRpb24gb2YgdGhlIFN1YmplY3QKLVNvZnR3YXJlIG9yIG91dCBvZiBhbnkgcmVwcmVzZW50YXRpb24gb3Igd2FycmFudHkgbWFkZSBieSBSZWNpcGllbnQuCi0KLTExLiBVLlMuIEdvdmVybm1lbnQgRW5kIFVzZXJzLiBUaGUgU3ViamVjdCBTb2Z0d2FyZSBpcyBhICJjb21tZXJjaWFsIGl0ZW0iCi1jb25zaXN0aW5nIG9mICJjb21tZXJjaWFsIGNvbXB1dGVyIHNvZnR3YXJlIiBhcyBzdWNoIHRlcm1zIGFyZSBkZWZpbmVkIGluCi10aXRsZSA0OCBvZiB0aGUgQ29kZSBvZiBGZWRlcmFsIFJlZ3VsYXRpb25zIGFuZCBhbGwgVS5TLiBHb3Zlcm5tZW50IEVuZCBVc2VycwotYWNxdWlyZSBvbmx5IHRoZSByaWdodHMgc2V0IGZvcnRoIGluIHRoaXMgTGljZW5zZSBhbmQgYXJlIHN1YmplY3QgdG8gdGhlIHRlcm1zCi1vZiB0aGlzIExpY2Vuc2UuCi0KLTEyLiBNaXNjZWxsYW5lb3VzLiBUaGlzIExpY2Vuc2UgcmVwcmVzZW50cyB0aGUgY29tcGxldGUgYWdyZWVtZW50IGNvbmNlcm5pbmcKLXN1YmplY3QgbWF0dGVyIGhlcmVvZi4gSWYgYW55IHByb3Zpc2lvbiBvZiB0aGlzIExpY2Vuc2UgaXMgaGVsZCB0byBiZQotdW5lbmZvcmNlYWJsZSBieSBhbnkganVkaWNpYWwgb3IgYWRtaW5pc3RyYXRpdmUgYXV0aG9yaXR5IGhhdmluZyBwcm9wZXIKLWp1cmlzZGljdGlvbiB3aXRoIHJlc3BlY3QgdGhlcmV0bywgc3VjaCBwcm92aXNpb24gc2hhbGwgYmUgcmVmb3JtZWQgc28gYXMgdG8KLWFjaGlldmUgYXMgbmVhcmx5IGFzIHBvc3NpYmxlIHRoZSBzYW1lIGVjb25vbWljIGVmZmVjdCBhcyB0aGUgb3JpZ2luYWwKLXByb3Zpc2lvbiBhbmQgdGhlIHJlbWFpbmRlciBvZiB0aGlzIExpY2Vuc2Ugd2lsbCByZW1haW4gaW4gZWZmZWN0LiBUaGlzCi1MaWNlbnNlIHNoYWxsIGJlIGdvdmVybmVkIGJ5IGFuZCBjb25zdHJ1ZWQgaW4gYWNjb3JkYW5jZSB3aXRoIHRoZSBsYXdzIG9mIHRoZQotVW5pdGVkIFN0YXRlcyBhbmQgdGhlIFN0YXRlIG9mIENhbGlmb3JuaWEgYXMgYXBwbGllZCB0byBhZ3JlZW1lbnRzIGVudGVyZWQKLWludG8gYW5kIHRvIGJlIHBlcmZvcm1lZCBlbnRpcmVseSB3aXRoaW4gQ2FsaWZvcm5pYSBiZXR3ZWVuIENhbGlmb3JuaWEKLXJlc2lkZW50cy4gQW55IGxpdGlnYXRpb24gcmVsYXRpbmcgdG8gdGhpcyBMaWNlbnNlIHNoYWxsIGJlIHN1YmplY3QgdG8gdGhlCi1leGNsdXNpdmUganVyaXNkaWN0aW9uIG9mIHRoZSBGZWRlcmFsIENvdXJ0cyBvZiB0aGUgTm9ydGhlcm4gRGlzdHJpY3Qgb2YKLUNhbGlmb3JuaWEgKG9yLCBhYnNlbnQgc3ViamVjdCBtYXR0ZXIganVyaXNkaWN0aW9uIGluIHN1Y2ggY291cnRzLCB0aGUgY291cnRzCi1vZiB0aGUgU3RhdGUgb2YgQ2FsaWZvcm5pYSksIHdpdGggdmVudWUgbHlpbmcgZXhjbHVzaXZlbHkgaW4gU2FudGEgQ2xhcmEKLUNvdW50eSwgQ2FsaWZvcm5pYSwgd2l0aCB0aGUgbG9zaW5nIHBhcnR5IHJlc3BvbnNpYmxlIGZvciBjb3N0cywgaW5jbHVkaW5nCi13aXRob3V0IGxpbWl0YXRpb24sIGNvdXJ0IGNvc3RzIGFuZCByZWFzb25hYmxlIGF0dG9ybmV5cyBmZWVzIGFuZCBleHBlbnNlcy4KLVRoZSBhcHBsaWNhdGlvbiBvZiB0aGUgVW5pdGVkIE5hdGlvbnMgQ29udmVudGlvbiBvbiBDb250cmFjdHMgZm9yIHRoZQotSW50ZXJuYXRpb25hbCBTYWxlIG9mIEdvb2RzIGlzIGV4cHJlc3NseSBleGNsdWRlZC4gQW55IGxhdyBvciByZWd1bGF0aW9uIHRoYXQKLXByb3ZpZGVzIHRoYXQgdGhlIGxhbmd1YWdlIG9mIGEgY29udHJhY3Qgc2hhbGwgYmUgY29uc3RydWVkIGFnYWluc3QgdGhlCi1kcmFmdGVyIHNoYWxsIG5vdCBhcHBseSB0byB0aGlzIExpY2Vuc2UuCi0KLUV4aGliaXQgQQotCi1Db3B5cmlnaHQgKGMpIDE5OTQtMTk5OSBTaWxpY29uIEdyYXBoaWNzLCBJbmMuCi0KLVRoZSBjb250ZW50cyBvZiB0aGlzIGZpbGUgYXJlIHN1YmplY3QgdG8gdGhlIENJRCBGb250IENvZGUgUHVibGljIExpY2Vuc2UKLVZlcnNpb24gMS4wICh0aGUgIkxpY2Vuc2UiKS4gWW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQotd2l0aCB0aGUgTGljZW5zZS4gWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0IFNpbGljb24gR3JhcGhpY3MsCi1JbmMuLCBhdHRuOiBMZWdhbCBTZXJ2aWNlcywgMjAxMSBOLiBTaG9yZWxpbmUgQmx2ZC4sIE1vdW50YWluIFZpZXcsIENBIDk0MDQzCi1vciBhdCBodHRwOi8vd3d3LnNnaS5jb20vc29mdHdhcmUvb3BlbnNvdXJjZS9jaWQvbGljZW5zZS5odG1sCi0KLVNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgYmFzaXMuIEFMTAotV0FSUkFOVElFUyBBUkUgRElTQ0xBSU1FRCwgSU5DTFVESU5HLCBXSVRIT1VUIExJTUlUQVRJT04sIEFOWSBJTVBMSUVECi1XQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwgT0YgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgT1IgT0YKLU5PTi1JTkZSSU5HRU1FTlQuIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyByaWdodHMKLWFuZCBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLQotVGhlIE9yaWdpbmFsIFNvZnR3YXJlIChhcyBkZWZpbmVkIGluIHRoZSBMaWNlbnNlKSBpcyBDSUQgZm9udCBjb2RlIHRoYXQgd2FzCi1kZXZlbG9wZWQgYnkgU2lsaWNvbiBHcmFwaGljcywgSW5jLiBUaG9zZSBwb3J0aW9ucyBvZiB0aGUgU3ViamVjdCBTb2Z0d2FyZSAoYXMKLWRlZmluZWQgaW4gdGhlIExpY2Vuc2UpIHRoYXQgd2VyZSBjcmVhdGVkIGJ5IFNpbGljb24gR3JhcGhpY3MsIEluYy4gYXJlCi1Db3B5cmlnaHQgKGMpIDE5OTQtMTk5OSBTaWxpY29uIEdyYXBoaWNzLCBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCi0KLVtOT1RFOiBXaGVuIHVzaW5nIHRoaXMgdGV4dCBpbiBjb25uZWN0aW9uIHdpdGggU3ViamVjdCBTb2Z0d2FyZSBkZWxpdmVyZWQKLXNvbGVseSBpbiBvYmplY3QgY29kZSBmb3JtLCBSZWNpcGllbnQgbWF5IHJlcGxhY2UgdGhlIHdvcmRzICJ0aGlzIGZpbGUiIHdpdGgKLSJ0aGlzIHNvZnR3YXJlIiBpbiBib3RoIHRoZSBmaXJzdCBhbmQgc2Vjb25kIHNlbnRlbmNlcy5dIDMuNi4gQml0c3RyZWFtIFZlcmEKLUZvbnRzIENvcHlyaWdodAotCi1UaGUgZm9udHMgaGF2ZSBhIGdlbmVyb3VzIGNvcHlyaWdodCwgYWxsb3dpbmcgZGVyaXZhdGl2ZSB3b3JrcyAoYXMgbG9uZyBhcwotIkJpdHN0cmVhbSIgb3IgIlZlcmEiIGFyZSBub3QgaW4gdGhlIG5hbWVzKSwgYW5kIGZ1bGwgcmVkaXN0cmlidXRpb24gKHNvIGxvbmcKLWFzIHRoZXkgYXJlIG5vdCAqc29sZCogYnkgdGhlbXNlbHZlcykuIFRoZXkgY2FuIGJlIGJlIGJ1bmRsZWQsIHJlZGlzdHJpYnV0ZWQKLWFuZCBzb2xkIHdpdGggYW55IHNvZnR3YXJlLgotCi1UaGUgZm9udHMgYXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBmb2xsb3dpbmcgY29weXJpZ2h0OgotCi1Db3B5cmlnaHQgKGMpIDIwMDMgYnkgQml0c3RyZWFtLCBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuIEJpdHN0cmVhbSBWZXJhIGlzIGEKLXRyYWRlbWFyayBvZiBCaXRzdHJlYW0sIEluYy4KLQotUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weQotb2YgdGhlIGZvbnRzIGFjY29tcGFueWluZyB0aGlzIGxpY2Vuc2UgKCJGb250cyIpIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24KLWZpbGVzICh0aGUgIkZvbnQgU29mdHdhcmUiKSwgdG8gcmVwcm9kdWNlIGFuZCBkaXN0cmlidXRlIHRoZSBGb250IFNvZnR3YXJlLAotaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbWVyZ2UsIHB1Ymxpc2gsCi1kaXN0cmlidXRlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIEZvbnQgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0bwotd2hvbSB0aGUgRm9udCBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZwotY29uZGl0aW9uczoKLQotVGhlIGFib3ZlIGNvcHlyaWdodCBhbmQgdHJhZGVtYXJrIG5vdGljZXMgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUKLWluY2x1ZGVkIGluIGFsbCBjb3BpZXMgb2Ygb25lIG9yIG1vcmUgb2YgdGhlIEZvbnQgU29mdHdhcmUgdHlwZWZhY2VzLgotCi1UaGUgRm9udCBTb2Z0d2FyZSBtYXkgYmUgbW9kaWZpZWQsIGFsdGVyZWQsIG9yIGFkZGVkIHRvLCBhbmQgaW4gcGFydGljdWxhciB0aGUKLWRlc2lnbnMgb2YgZ2x5cGhzIG9yIGNoYXJhY3RlcnMgaW4gdGhlIEZvbnRzIG1heSBiZSBtb2RpZmllZCBhbmQgYWRkaXRpb25hbAotZ2x5cGhzIG9yIGNoYXJhY3RlcnMgbWF5IGJlIGFkZGVkIHRvIHRoZSBGb250cywgb25seSBpZiB0aGUgZm9udHMgYXJlIHJlbmFtZWQKLXRvIG5hbWVzIG5vdCBjb250YWluaW5nIGVpdGhlciB0aGUgd29yZHMgIkJpdHN0cmVhbSIgb3IgdGhlIHdvcmQgIlZlcmEiLgotCi1UaGlzIExpY2Vuc2UgYmVjb21lcyBudWxsIGFuZCB2b2lkIHRvIHRoZSBleHRlbnQgYXBwbGljYWJsZSB0byBGb250cyBvciBGb250Ci1Tb2Z0d2FyZSB0aGF0IGhhcyBiZWVuIG1vZGlmaWVkIGFuZCBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgIkJpdHN0cmVhbSBWZXJhIgotbmFtZXMuCi0KLVRoZSBGb250IFNvZnR3YXJlIG1heSBiZSBzb2xkIGFzIHBhcnQgb2YgYSBsYXJnZXIgc29mdHdhcmUgcGFja2FnZSBidXQgbm8gY29weQotb2Ygb25lIG9yIG1vcmUgb2YgdGhlIEZvbnQgU29mdHdhcmUgdHlwZWZhY2VzIG1heSBiZSBzb2xkIGJ5IGl0c2VsZi4KLQotVEhFIEZPTlQgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUwotT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBBTlkgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksCi1GSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5UIE9GIENPUFlSSUdIVCwgUEFURU5ULAotVFJBREVNQVJLLCBPUiBPVEhFUiBSSUdIVC4gSU4gTk8gRVZFTlQgU0hBTEwgQklUU1RSRUFNIE9SIFRIRSBHTk9NRSBGT1VOREFUSU9OCi1CRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIElOQ0xVRElORyBBTlkgR0VORVJBTCwKLVNQRUNJQUwsIElORElSRUNULCBJTkNJREVOVEFMLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OCi1PRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIFRIRSBVU0UgT1IgSU5BQklMSVRZIFRPCi1VU0UgVEhFIEZPTlQgU09GVFdBUkUgT1IgRlJPTSBPVEhFUiBERUFMSU5HUyBJTiBUSEUgRk9OVCBTT0ZUV0FSRS4KLQotRXhjZXB0IGFzIGNvbnRhaW5lZCBpbiB0aGlzIG5vdGljZSwgdGhlIG5hbWVzIG9mIEdub21lLCB0aGUgR25vbWUgRm91bmRhdGlvbiwKLWFuZCBCaXRzdHJlYW0gSW5jLiwgc2hhbGwgbm90IGJlIHVzZWQgaW4gYWR2ZXJ0aXNpbmcgb3Igb3RoZXJ3aXNlIHRvIHByb21vdGUKLXRoZSBzYWxlLCB1c2Ugb3Igb3RoZXIgZGVhbGluZ3MgaW4gdGhpcyBGb250IFNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotYXV0aG9yaXphdGlvbiBmcm9tIHRoZSBHbm9tZSBGb3VuZGF0aW9uIG9yIEJpdHN0cmVhbSBJbmMuLCByZXNwZWN0aXZlbHkuIEZvcgotZnVydGhlciBpbmZvcm1hdGlvbiwgY29udGFjdDogZm9udHMgYXQgZ25vbWUgZG90IG9yZy4gIDMuNy4gQmlnZWxvdyAmIEhvbG1lcwotSW5jIGFuZCBVUlcrKyBHbWJIIEx1eGkgZm9udCBsaWNlbnNlCi0KLUx1eGkgZm9udHMgY29weXJpZ2h0IChjKSAyMDAxIGJ5IEJpZ2Vsb3cgJiBIb2xtZXMgSW5jLiBMdXhpIGZvbnQgaW5zdHJ1Y3Rpb24KLWNvZGUgY29weXJpZ2h0IChjKSAyMDAxIGJ5IFVSVysrIEdtYkguIEFsbCBSaWdodHMgUmVzZXJ2ZWQuIEx1eGkgaXMgYQotcmVnaXN0ZXJlZCB0cmFkZW1hcmsgb2YgQmlnZWxvdyAmIEhvbG1lcyBJbmMuCi0KLVBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHkKLW9mIHRoZXNlIEZvbnRzIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSAiRm9udCBTb2Z0d2FyZSIpLCB0bwotZGVhbCBpbiB0aGUgRm9udCBTb2Z0d2FyZSwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwKLWNvcHksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIEZvbnQKLVNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgRm9udCBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8KLXNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKLQotVGhlIGFib3ZlIGNvcHlyaWdodCBhbmQgdHJhZGVtYXJrIG5vdGljZXMgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUKLWluY2x1ZGVkIGluIGFsbCBjb3BpZXMgb2Ygb25lIG9yIG1vcmUgb2YgdGhlIEZvbnQgU29mdHdhcmUuCi0KLVRoZSBGb250IFNvZnR3YXJlIG1heSBub3QgYmUgbW9kaWZpZWQsIGFsdGVyZWQsIG9yIGFkZGVkIHRvLCBhbmQgaW4gcGFydGljdWxhcgotdGhlIGRlc2lnbnMgb2YgZ2x5cGhzIG9yIGNoYXJhY3RlcnMgaW4gdGhlIEZvbnRzIG1heSBub3QgYmUgbW9kaWZpZWQgbm9yIG1heQotYWRkaXRpb25hbCBnbHlwaHMgb3IgY2hhcmFjdGVycyBiZSBhZGRlZCB0byB0aGUgRm9udHMuIFRoaXMgTGljZW5zZSBiZWNvbWVzCi1udWxsIGFuZCB2b2lkIHdoZW4gdGhlIEZvbnRzIG9yIEZvbnQgU29mdHdhcmUgaGF2ZSBiZWVuIG1vZGlmaWVkLgotCi1USEUgRk9OVCBTT0ZUV0FSRSBJUyBQUk9WSURFRCAiQVMgSVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTCi1PUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIEFOWSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwKLUZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQgT0YgQ09QWVJJR0hULCBQQVRFTlQsCi1UUkFERU1BUkssIE9SIE9USEVSIFJJR0hULiBJTiBOTyBFVkVOVCBTSEFMTCBCSUdFTE9XICYgSE9MTUVTIElOQy4gT1IgVVJXKysKLUdNQkguIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgSU5DTFVESU5HIEFOWQotR0VORVJBTCwgU1BFQ0lBTCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUywgV0hFVEhFUiBJTgotQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgVEhFIFVTRSBPUgotSU5BQklMSVRZIFRPIFVTRSBUSEUgRk9OVCBTT0ZUV0FSRSBPUiBGUk9NIE9USEVSIERFQUxJTkdTIElOIFRIRSBGT05UCi1TT0ZUV0FSRS4KLQotRXhjZXB0IGFzIGNvbnRhaW5lZCBpbiB0aGlzIG5vdGljZSwgdGhlIG5hbWVzIG9mIEJpZ2Vsb3cgJiBIb2xtZXMgSW5jLiBhbmQKLVVSVysrIEdtYkguIHNoYWxsIG5vdCBiZSB1c2VkIGluIGFkdmVydGlzaW5nIG9yIG90aGVyd2lzZSB0byBwcm9tb3RlIHRoZSBzYWxlLAotdXNlIG9yIG90aGVyIGRlYWxpbmdzIGluIHRoaXMgRm9udCBTb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLWF1dGhvcml6YXRpb24gZnJvbSBCaWdlbG93ICYgSG9sbWVzIEluYy4gYW5kIFVSVysrIEdtYkguCi0KLUZvciBmdXJ0aGVyIGluZm9ybWF0aW9uLCBjb250YWN0OgotCi1pbmZvQHVyd3BwLmRlIG9yIGRlc2lnbkBiaWdlbG93YW5kaG9sbWVzLmNvbQotCi0KLS0tLSBlbmQgb2YgTElDRU5TRSAtLS0KLQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotCi0lJSBUaGlzIG5vdGljZSBpcyBwcm92aWRlZCB3aXRoIHJlc3BlY3QgdG8gemxpYiB2MS4yLjgsIHdoaWNoIG1heSBiZSBpbmNsdWRlZCAKLXdpdGggSlJFIDgsIEpESyA4LCBhbmQgT3BlbkpESyA4LgotCi0tLS0gYmVnaW4gb2YgTElDRU5TRSAtLS0KLQotICB2ZXJzaW9uIDEuMi44LCBBcHJpbCAyOHRoLCAyMDEzCi0KLSAgQ29weXJpZ2h0IChDKSAxOTk1LTIwMTMgSmVhbi1sb3VwIEdhaWxseSBhbmQgTWFyayBBZGxlcgotCi0gIFRoaXMgc29mdHdhcmUgaXMgcHJvdmlkZWQgJ2FzLWlzJywgd2l0aG91dCBhbnkgZXhwcmVzcyBvciBpbXBsaWVkCi0gIHdhcnJhbnR5LiAgSW4gbm8gZXZlbnQgd2lsbCB0aGUgYXV0aG9ycyBiZSBoZWxkIGxpYWJsZSBmb3IgYW55IGRhbWFnZXMKLSAgYXJpc2luZyBmcm9tIHRoZSB1c2Ugb2YgdGhpcyBzb2Z0d2FyZS4KLQotICBQZXJtaXNzaW9uIGlzIGdyYW50ZWQgdG8gYW55b25lIHRvIHVzZSB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZSwKLSAgaW5jbHVkaW5nIGNvbW1lcmNpYWwgYXBwbGljYXRpb25zLCBhbmQgdG8gYWx0ZXIgaXQgYW5kIHJlZGlzdHJpYnV0ZSBpdAotICBmcmVlbHksIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyByZXN0cmljdGlvbnM6Ci0KLSAgMS4gVGhlIG9yaWdpbiBvZiB0aGlzIHNvZnR3YXJlIG11c3Qgbm90IGJlIG1pc3JlcHJlc2VudGVkOyB5b3UgbXVzdCBub3QKLSAgICAgY2xhaW0gdGhhdCB5b3Ugd3JvdGUgdGhlIG9yaWdpbmFsIHNvZnR3YXJlLiBJZiB5b3UgdXNlIHRoaXMgc29mdHdhcmUKLSAgICAgaW4gYSBwcm9kdWN0LCBhbiBhY2tub3dsZWRnbWVudCBpbiB0aGUgcHJvZHVjdCBkb2N1bWVudGF0aW9uIHdvdWxkIGJlCi0gICAgIGFwcHJlY2lhdGVkIGJ1dCBpcyBub3QgcmVxdWlyZWQuCi0gIDIuIEFsdGVyZWQgc291cmNlIHZlcnNpb25zIG11c3QgYmUgcGxhaW5seSBtYXJrZWQgYXMgc3VjaCwgYW5kIG11c3Qgbm90IGJlCi0gICAgIG1pc3JlcHJlc2VudGVkIGFzIGJlaW5nIHRoZSBvcmlnaW5hbCBzb2Z0d2FyZS4KLSAgMy4gVGhpcyBub3RpY2UgbWF5IG5vdCBiZSByZW1vdmVkIG9yIGFsdGVyZWQgZnJvbSBhbnkgc291cmNlIGRpc3RyaWJ1dGlvbi4KLQotICBKZWFuLWxvdXAgR2FpbGx5ICAgICAgICBNYXJrIEFkbGVyCi0gIGpsb3VwQGd6aXAub3JnICAgICAgICAgIG1hZGxlckBhbHVtbmkuY2FsdGVjaC5lZHUKLQotLS0tIGVuZCBvZiBMSUNFTlNFIC0tLQotCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0KLSUlIFRoaXMgbm90aWNlIGlzIHByb3ZpZGVkIHdpdGggcmVzcGVjdCB0byB0aGUgZm9sbG93aW5nIHdoaWNoIG1heSBiZSAKLWluY2x1ZGVkIHdpdGggSlJFIDgsIEpESyA4LCBhbmQgT3BlbkpESyA4LgotCi0gIEFwYWNoZSBDb21tb25zIE1hdGggMy4yCi0gIEFwYWNoZSBEZXJieSAxMC4xMS4xLjIKLSAgQXBhY2hlIEpha2FydGEgQkNFTCA1LjEgCi0gIEFwYWNoZSBKYWthcnRhIFJlZ2V4cCAxLjQgCi0gIEFwYWNoZSBTYW50dWFyaW8gWE1MIFNlY3VyaXR5IGZvciBKYXZhIDEuNS40Ci0gIEFwYWNoZSBYYWxhbi1KYXZhIDIuNy4xIAotICBBcGFjaGUgWGVyY2VzIEphdmEgMi4xMC4wIAotICBBcGFjaGUgWE1MIFJlc29sdmVyIDEuMSAKLSAgRHluYWxpbmsgMC41Ci0KLQotLS0tIGJlZ2luIG9mIExJQ0VOU0UgLS0tCi0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwYWNoZSBMaWNlbnNlCi0gICAgICAgICAgICAgICAgICAgICAgICAgICBWZXJzaW9uIDIuMCwgSmFudWFyeSAyMDA0Ci0gICAgICAgICAgICAgICAgICAgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvCi0KLSAgIFRFUk1TIEFORCBDT05ESVRJT05TIEZPUiBVU0UsIFJFUFJPRFVDVElPTiwgQU5EIERJU1RSSUJVVElPTgotCi0gICAxLiBEZWZpbml0aW9ucy4KLQotICAgICAgIkxpY2Vuc2UiIHNoYWxsIG1lYW4gdGhlIHRlcm1zIGFuZCBjb25kaXRpb25zIGZvciB1c2UsIHJlcHJvZHVjdGlvbiwKLSAgICAgIGFuZCBkaXN0cmlidXRpb24gYXMgZGVmaW5lZCBieSBTZWN0aW9ucyAxIHRocm91Z2ggOSBvZiB0aGlzIGRvY3VtZW50LgotCi0gICAgICAiTGljZW5zb3IiIHNoYWxsIG1lYW4gdGhlIGNvcHlyaWdodCBvd25lciBvciBlbnRpdHkgYXV0aG9yaXplZCBieQotICAgICAgdGhlIGNvcHlyaWdodCBvd25lciB0aGF0IGlzIGdyYW50aW5nIHRoZSBMaWNlbnNlLgotCi0gICAgICAiTGVnYWwgRW50aXR5IiBzaGFsbCBtZWFuIHRoZSB1bmlvbiBvZiB0aGUgYWN0aW5nIGVudGl0eSBhbmQgYWxsCi0gICAgICBvdGhlciBlbnRpdGllcyB0aGF0IGNvbnRyb2wsIGFyZSBjb250cm9sbGVkIGJ5LCBvciBhcmUgdW5kZXIgY29tbW9uCi0gICAgICBjb250cm9sIHdpdGggdGhhdCBlbnRpdHkuIEZvciB0aGUgcHVycG9zZXMgb2YgdGhpcyBkZWZpbml0aW9uLAotICAgICAgImNvbnRyb2wiIG1lYW5zIChpKSB0aGUgcG93ZXIsIGRpcmVjdCBvciBpbmRpcmVjdCwgdG8gY2F1c2UgdGhlCi0gICAgICBkaXJlY3Rpb24gb3IgbWFuYWdlbWVudCBvZiBzdWNoIGVudGl0eSwgd2hldGhlciBieSBjb250cmFjdCBvcgotICAgICAgb3RoZXJ3aXNlLCBvciAoaWkpIG93bmVyc2hpcCBvZiBmaWZ0eSBwZXJjZW50ICg1MCUpIG9yIG1vcmUgb2YgdGhlCi0gICAgICBvdXRzdGFuZGluZyBzaGFyZXMsIG9yIChpaWkpIGJlbmVmaWNpYWwgb3duZXJzaGlwIG9mIHN1Y2ggZW50aXR5LgotCi0gICAgICAiWW91IiAob3IgIllvdXIiKSBzaGFsbCBtZWFuIGFuIGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5Ci0gICAgICBleGVyY2lzaW5nIHBlcm1pc3Npb25zIGdyYW50ZWQgYnkgdGhpcyBMaWNlbnNlLgotCi0gICAgICAiU291cmNlIiBmb3JtIHNoYWxsIG1lYW4gdGhlIHByZWZlcnJlZCBmb3JtIGZvciBtYWtpbmcgbW9kaWZpY2F0aW9ucywKLSAgICAgIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gc29mdHdhcmUgc291cmNlIGNvZGUsIGRvY3VtZW50YXRpb24KLSAgICAgIHNvdXJjZSwgYW5kIGNvbmZpZ3VyYXRpb24gZmlsZXMuCi0KLSAgICAgICJPYmplY3QiIGZvcm0gc2hhbGwgbWVhbiBhbnkgZm9ybSByZXN1bHRpbmcgZnJvbSBtZWNoYW5pY2FsCi0gICAgICB0cmFuc2Zvcm1hdGlvbiBvciB0cmFuc2xhdGlvbiBvZiBhIFNvdXJjZSBmb3JtLCBpbmNsdWRpbmcgYnV0Ci0gICAgICBub3QgbGltaXRlZCB0byBjb21waWxlZCBvYmplY3QgY29kZSwgZ2VuZXJhdGVkIGRvY3VtZW50YXRpb24sCi0gICAgICBhbmQgY29udmVyc2lvbnMgdG8gb3RoZXIgbWVkaWEgdHlwZXMuCi0KLSAgICAgICJXb3JrIiBzaGFsbCBtZWFuIHRoZSB3b3JrIG9mIGF1dGhvcnNoaXAsIHdoZXRoZXIgaW4gU291cmNlIG9yCi0gICAgICBPYmplY3QgZm9ybSwgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIExpY2Vuc2UsIGFzIGluZGljYXRlZCBieSBhCi0gICAgICBjb3B5cmlnaHQgbm90aWNlIHRoYXQgaXMgaW5jbHVkZWQgaW4gb3IgYXR0YWNoZWQgdG8gdGhlIHdvcmsKLSAgICAgIChhbiBleGFtcGxlIGlzIHByb3ZpZGVkIGluIHRoZSBBcHBlbmRpeCBiZWxvdykuCi0KLSAgICAgICJEZXJpdmF0aXZlIFdvcmtzIiBzaGFsbCBtZWFuIGFueSB3b3JrLCB3aGV0aGVyIGluIFNvdXJjZSBvciBPYmplY3QKLSAgICAgIGZvcm0sIHRoYXQgaXMgYmFzZWQgb24gKG9yIGRlcml2ZWQgZnJvbSkgdGhlIFdvcmsgYW5kIGZvciB3aGljaCB0aGUKLSAgICAgIGVkaXRvcmlhbCByZXZpc2lvbnMsIGFubm90YXRpb25zLCBlbGFib3JhdGlvbnMsIG9yIG90aGVyIG1vZGlmaWNhdGlvbnMKLSAgICAgIHJlcHJlc2VudCwgYXMgYSB3aG9sZSwgYW4gb3JpZ2luYWwgd29yayBvZiBhdXRob3JzaGlwLiBGb3IgdGhlIHB1cnBvc2VzCi0gICAgICBvZiB0aGlzIExpY2Vuc2UsIERlcml2YXRpdmUgV29ya3Mgc2hhbGwgbm90IGluY2x1ZGUgd29ya3MgdGhhdCByZW1haW4KLSAgICAgIHNlcGFyYWJsZSBmcm9tLCBvciBtZXJlbHkgbGluayAob3IgYmluZCBieSBuYW1lKSB0byB0aGUgaW50ZXJmYWNlcyBvZiwKLSAgICAgIHRoZSBXb3JrIGFuZCBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YuCi0KLSAgICAgICJDb250cmlidXRpb24iIHNoYWxsIG1lYW4gYW55IHdvcmsgb2YgYXV0aG9yc2hpcCwgaW5jbHVkaW5nCi0gICAgICB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGUgV29yayBhbmQgYW55IG1vZGlmaWNhdGlvbnMgb3IgYWRkaXRpb25zCi0gICAgICB0byB0aGF0IFdvcmsgb3IgRGVyaXZhdGl2ZSBXb3JrcyB0aGVyZW9mLCB0aGF0IGlzIGludGVudGlvbmFsbHkKLSAgICAgIHN1Ym1pdHRlZCB0byBMaWNlbnNvciBmb3IgaW5jbHVzaW9uIGluIHRoZSBXb3JrIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIKLSAgICAgIG9yIGJ5IGFuIGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5IGF1dGhvcml6ZWQgdG8gc3VibWl0IG9uIGJlaGFsZiBvZgotICAgICAgdGhlIGNvcHlyaWdodCBvd25lci4gRm9yIHRoZSBwdXJwb3NlcyBvZiB0aGlzIGRlZmluaXRpb24sICJzdWJtaXR0ZWQiCi0gICAgICBtZWFucyBhbnkgZm9ybSBvZiBlbGVjdHJvbmljLCB2ZXJiYWwsIG9yIHdyaXR0ZW4gY29tbXVuaWNhdGlvbiBzZW50Ci0gICAgICB0byB0aGUgTGljZW5zb3Igb3IgaXRzIHJlcHJlc2VudGF0aXZlcywgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0bwotICAgICAgY29tbXVuaWNhdGlvbiBvbiBlbGVjdHJvbmljIG1haWxpbmcgbGlzdHMsIHNvdXJjZSBjb2RlIGNvbnRyb2wgc3lzdGVtcywKLSAgICAgIGFuZCBpc3N1ZSB0cmFja2luZyBzeXN0ZW1zIHRoYXQgYXJlIG1hbmFnZWQgYnksIG9yIG9uIGJlaGFsZiBvZiwgdGhlCi0gICAgICBMaWNlbnNvciBmb3IgdGhlIHB1cnBvc2Ugb2YgZGlzY3Vzc2luZyBhbmQgaW1wcm92aW5nIHRoZSBXb3JrLCBidXQKLSAgICAgIGV4Y2x1ZGluZyBjb21tdW5pY2F0aW9uIHRoYXQgaXMgY29uc3BpY3VvdXNseSBtYXJrZWQgb3Igb3RoZXJ3aXNlCi0gICAgICBkZXNpZ25hdGVkIGluIHdyaXRpbmcgYnkgdGhlIGNvcHlyaWdodCBvd25lciBhcyAiTm90IGEgQ29udHJpYnV0aW9uLiIKLQotICAgICAgIkNvbnRyaWJ1dG9yIiBzaGFsbCBtZWFuIExpY2Vuc29yIGFuZCBhbnkgaW5kaXZpZHVhbCBvciBMZWdhbCBFbnRpdHkKLSAgICAgIG9uIGJlaGFsZiBvZiB3aG9tIGEgQ29udHJpYnV0aW9uIGhhcyBiZWVuIHJlY2VpdmVkIGJ5IExpY2Vuc29yIGFuZAotICAgICAgc3Vic2VxdWVudGx5IGluY29ycG9yYXRlZCB3aXRoaW4gdGhlIFdvcmsuCi0KLSAgIDIuIEdyYW50IG9mIENvcHlyaWdodCBMaWNlbnNlLiBTdWJqZWN0IHRvIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZgotICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAotICAgICAgd29ybGR3aWRlLCBub24tZXhjbHVzaXZlLCBuby1jaGFyZ2UsIHJveWFsdHktZnJlZSwgaXJyZXZvY2FibGUKLSAgICAgIGNvcHlyaWdodCBsaWNlbnNlIHRvIHJlcHJvZHVjZSwgcHJlcGFyZSBEZXJpdmF0aXZlIFdvcmtzIG9mLAotICAgICAgcHVibGljbHkgZGlzcGxheSwgcHVibGljbHkgcGVyZm9ybSwgc3VibGljZW5zZSwgYW5kIGRpc3RyaWJ1dGUgdGhlCi0gICAgICBXb3JrIGFuZCBzdWNoIERlcml2YXRpdmUgV29ya3MgaW4gU291cmNlIG9yIE9iamVjdCBmb3JtLgotCi0gICAzLiBHcmFudCBvZiBQYXRlbnQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKLSAgICAgIHRoaXMgTGljZW5zZSwgZWFjaCBDb250cmlidXRvciBoZXJlYnkgZ3JhbnRzIHRvIFlvdSBhIHBlcnBldHVhbCwKLSAgICAgIHdvcmxkd2lkZSwgbm9uLWV4Y2x1c2l2ZSwgbm8tY2hhcmdlLCByb3lhbHR5LWZyZWUsIGlycmV2b2NhYmxlCi0gICAgICAoZXhjZXB0IGFzIHN0YXRlZCBpbiB0aGlzIHNlY3Rpb24pIHBhdGVudCBsaWNlbnNlIHRvIG1ha2UsIGhhdmUgbWFkZSwKLSAgICAgIHVzZSwgb2ZmZXIgdG8gc2VsbCwgc2VsbCwgaW1wb3J0LCBhbmQgb3RoZXJ3aXNlIHRyYW5zZmVyIHRoZSBXb3JrLAotICAgICAgd2hlcmUgc3VjaCBsaWNlbnNlIGFwcGxpZXMgb25seSB0byB0aG9zZSBwYXRlbnQgY2xhaW1zIGxpY2Vuc2FibGUKLSAgICAgIGJ5IHN1Y2ggQ29udHJpYnV0b3IgdGhhdCBhcmUgbmVjZXNzYXJpbHkgaW5mcmluZ2VkIGJ5IHRoZWlyCi0gICAgICBDb250cmlidXRpb24ocykgYWxvbmUgb3IgYnkgY29tYmluYXRpb24gb2YgdGhlaXIgQ29udHJpYnV0aW9uKHMpCi0gICAgICB3aXRoIHRoZSBXb3JrIHRvIHdoaWNoIHN1Y2ggQ29udHJpYnV0aW9uKHMpIHdhcyBzdWJtaXR0ZWQuIElmIFlvdQotICAgICAgaW5zdGl0dXRlIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYW55IGVudGl0eSAoaW5jbHVkaW5nIGEKLSAgICAgIGNyb3NzLWNsYWltIG9yIGNvdW50ZXJjbGFpbSBpbiBhIGxhd3N1aXQpIGFsbGVnaW5nIHRoYXQgdGhlIFdvcmsKLSAgICAgIG9yIGEgQ29udHJpYnV0aW9uIGluY29ycG9yYXRlZCB3aXRoaW4gdGhlIFdvcmsgY29uc3RpdHV0ZXMgZGlyZWN0Ci0gICAgICBvciBjb250cmlidXRvcnkgcGF0ZW50IGluZnJpbmdlbWVudCwgdGhlbiBhbnkgcGF0ZW50IGxpY2Vuc2VzCi0gICAgICBncmFudGVkIHRvIFlvdSB1bmRlciB0aGlzIExpY2Vuc2UgZm9yIHRoYXQgV29yayBzaGFsbCB0ZXJtaW5hdGUKLSAgICAgIGFzIG9mIHRoZSBkYXRlIHN1Y2ggbGl0aWdhdGlvbiBpcyBmaWxlZC4KLQotICAgNC4gUmVkaXN0cmlidXRpb24uIFlvdSBtYXkgcmVwcm9kdWNlIGFuZCBkaXN0cmlidXRlIGNvcGllcyBvZiB0aGUKLSAgICAgIFdvcmsgb3IgRGVyaXZhdGl2ZSBXb3JrcyB0aGVyZW9mIGluIGFueSBtZWRpdW0sIHdpdGggb3Igd2l0aG91dAotICAgICAgbW9kaWZpY2F0aW9ucywgYW5kIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybSwgcHJvdmlkZWQgdGhhdCBZb3UKLSAgICAgIG1lZXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgotCi0gICAgICAoYSkgWW91IG11c3QgZ2l2ZSBhbnkgb3RoZXIgcmVjaXBpZW50cyBvZiB0aGUgV29yayBvcgotICAgICAgICAgIERlcml2YXRpdmUgV29ya3MgYSBjb3B5IG9mIHRoaXMgTGljZW5zZTsgYW5kCi0KLSAgICAgIChiKSBZb3UgbXVzdCBjYXVzZSBhbnkgbW9kaWZpZWQgZmlsZXMgdG8gY2FycnkgcHJvbWluZW50IG5vdGljZXMKLSAgICAgICAgICBzdGF0aW5nIHRoYXQgWW91IGNoYW5nZWQgdGhlIGZpbGVzOyBhbmQKLQotICAgICAgKGMpIFlvdSBtdXN0IHJldGFpbiwgaW4gdGhlIFNvdXJjZSBmb3JtIG9mIGFueSBEZXJpdmF0aXZlIFdvcmtzCi0gICAgICAgICAgdGhhdCBZb3UgZGlzdHJpYnV0ZSwgYWxsIGNvcHlyaWdodCwgcGF0ZW50LCB0cmFkZW1hcmssIGFuZAotICAgICAgICAgIGF0dHJpYnV0aW9uIG5vdGljZXMgZnJvbSB0aGUgU291cmNlIGZvcm0gb2YgdGhlIFdvcmssCi0gICAgICAgICAgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QgcGVydGFpbiB0byBhbnkgcGFydCBvZgotICAgICAgICAgIHRoZSBEZXJpdmF0aXZlIFdvcmtzOyBhbmQKLQotICAgICAgKGQpIElmIHRoZSBXb3JrIGluY2x1ZGVzIGEgIk5PVElDRSIgdGV4dCBmaWxlIGFzIHBhcnQgb2YgaXRzCi0gICAgICAgICAgZGlzdHJpYnV0aW9uLCB0aGVuIGFueSBEZXJpdmF0aXZlIFdvcmtzIHRoYXQgWW91IGRpc3RyaWJ1dGUgbXVzdAotICAgICAgICAgIGluY2x1ZGUgYSByZWFkYWJsZSBjb3B5IG9mIHRoZSBhdHRyaWJ1dGlvbiBub3RpY2VzIGNvbnRhaW5lZAotICAgICAgICAgIHdpdGhpbiBzdWNoIE5PVElDRSBmaWxlLCBleGNsdWRpbmcgdGhvc2Ugbm90aWNlcyB0aGF0IGRvIG5vdAotICAgICAgICAgIHBlcnRhaW4gdG8gYW55IHBhcnQgb2YgdGhlIERlcml2YXRpdmUgV29ya3MsIGluIGF0IGxlYXN0IG9uZQotICAgICAgICAgIG9mIHRoZSBmb2xsb3dpbmcgcGxhY2VzOiB3aXRoaW4gYSBOT1RJQ0UgdGV4dCBmaWxlIGRpc3RyaWJ1dGVkCi0gICAgICAgICAgYXMgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgd2l0aGluIHRoZSBTb3VyY2UgZm9ybSBvcgotICAgICAgICAgIGRvY3VtZW50YXRpb24sIGlmIHByb3ZpZGVkIGFsb25nIHdpdGggdGhlIERlcml2YXRpdmUgV29ya3M7IG9yLAotICAgICAgICAgIHdpdGhpbiBhIGRpc3BsYXkgZ2VuZXJhdGVkIGJ5IHRoZSBEZXJpdmF0aXZlIFdvcmtzLCBpZiBhbmQKLSAgICAgICAgICB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IG5vdGljZXMgbm9ybWFsbHkgYXBwZWFyLiBUaGUgY29udGVudHMKLSAgICAgICAgICBvZiB0aGUgTk9USUNFIGZpbGUgYXJlIGZvciBpbmZvcm1hdGlvbmFsIHB1cnBvc2VzIG9ubHkgYW5kCi0gICAgICAgICAgZG8gbm90IG1vZGlmeSB0aGUgTGljZW5zZS4gWW91IG1heSBhZGQgWW91ciBvd24gYXR0cmlidXRpb24KLSAgICAgICAgICBub3RpY2VzIHdpdGhpbiBEZXJpdmF0aXZlIFdvcmtzIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsb25nc2lkZQotICAgICAgICAgIG9yIGFzIGFuIGFkZGVuZHVtIHRvIHRoZSBOT1RJQ0UgdGV4dCBmcm9tIHRoZSBXb3JrLCBwcm92aWRlZAotICAgICAgICAgIHRoYXQgc3VjaCBhZGRpdGlvbmFsIGF0dHJpYnV0aW9uIG5vdGljZXMgY2Fubm90IGJlIGNvbnN0cnVlZAotICAgICAgICAgIGFzIG1vZGlmeWluZyB0aGUgTGljZW5zZS4KLQotICAgICAgWW91IG1heSBhZGQgWW91ciBvd24gY29weXJpZ2h0IHN0YXRlbWVudCB0byBZb3VyIG1vZGlmaWNhdGlvbnMgYW5kCi0gICAgICBtYXkgcHJvdmlkZSBhZGRpdGlvbmFsIG9yIGRpZmZlcmVudCBsaWNlbnNlIHRlcm1zIGFuZCBjb25kaXRpb25zCi0gICAgICBmb3IgdXNlLCByZXByb2R1Y3Rpb24sIG9yIGRpc3RyaWJ1dGlvbiBvZiBZb3VyIG1vZGlmaWNhdGlvbnMsIG9yCi0gICAgICBmb3IgYW55IHN1Y2ggRGVyaXZhdGl2ZSBXb3JrcyBhcyBhIHdob2xlLCBwcm92aWRlZCBZb3VyIHVzZSwKLSAgICAgIHJlcHJvZHVjdGlvbiwgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgV29yayBvdGhlcndpc2UgY29tcGxpZXMgd2l0aAotICAgICAgdGhlIGNvbmRpdGlvbnMgc3RhdGVkIGluIHRoaXMgTGljZW5zZS4KLQotICAgNS4gU3VibWlzc2lvbiBvZiBDb250cmlidXRpb25zLiBVbmxlc3MgWW91IGV4cGxpY2l0bHkgc3RhdGUgb3RoZXJ3aXNlLAotICAgICAgYW55IENvbnRyaWJ1dGlvbiBpbnRlbnRpb25hbGx5IHN1Ym1pdHRlZCBmb3IgaW5jbHVzaW9uIGluIHRoZSBXb3JrCi0gICAgICBieSBZb3UgdG8gdGhlIExpY2Vuc29yIHNoYWxsIGJlIHVuZGVyIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZgotICAgICAgdGhpcyBMaWNlbnNlLCB3aXRob3V0IGFueSBhZGRpdGlvbmFsIHRlcm1zIG9yIGNvbmRpdGlvbnMuCi0gICAgICBOb3R3aXRoc3RhbmRpbmcgdGhlIGFib3ZlLCBub3RoaW5nIGhlcmVpbiBzaGFsbCBzdXBlcnNlZGUgb3IgbW9kaWZ5Ci0gICAgICB0aGUgdGVybXMgb2YgYW55IHNlcGFyYXRlIGxpY2Vuc2UgYWdyZWVtZW50IHlvdSBtYXkgaGF2ZSBleGVjdXRlZAotICAgICAgd2l0aCBMaWNlbnNvciByZWdhcmRpbmcgc3VjaCBDb250cmlidXRpb25zLgotCi0gICA2LiBUcmFkZW1hcmtzLiBUaGlzIExpY2Vuc2UgZG9lcyBub3QgZ3JhbnQgcGVybWlzc2lvbiB0byB1c2UgdGhlIHRyYWRlCi0gICAgICBuYW1lcywgdHJhZGVtYXJrcywgc2VydmljZSBtYXJrcywgb3IgcHJvZHVjdCBuYW1lcyBvZiB0aGUgTGljZW5zb3IsCi0gICAgICBleGNlcHQgYXMgcmVxdWlyZWQgZm9yIHJlYXNvbmFibGUgYW5kIGN1c3RvbWFyeSB1c2UgaW4gZGVzY3JpYmluZyB0aGUKLSAgICAgIG9yaWdpbiBvZiB0aGUgV29yayBhbmQgcmVwcm9kdWNpbmcgdGhlIGNvbnRlbnQgb2YgdGhlIE5PVElDRSBmaWxlLgotCi0gICA3LiBEaXNjbGFpbWVyIG9mIFdhcnJhbnR5LiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IKLSAgICAgIGFncmVlZCB0byBpbiB3cml0aW5nLCBMaWNlbnNvciBwcm92aWRlcyB0aGUgV29yayAoYW5kIGVhY2gKLSAgICAgIENvbnRyaWJ1dG9yIHByb3ZpZGVzIGl0cyBDb250cmlidXRpb25zKSBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICAgICAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yCi0gICAgICBpbXBsaWVkLCBpbmNsdWRpbmcsIHdpdGhvdXQgbGltaXRhdGlvbiwgYW55IHdhcnJhbnRpZXMgb3IgY29uZGl0aW9ucwotICAgICAgb2YgVElUTEUsIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWSwgb3IgRklUTkVTUyBGT1IgQQotICAgICAgUEFSVElDVUxBUiBQVVJQT1NFLiBZb3UgYXJlIHNvbGVseSByZXNwb25zaWJsZSBmb3IgZGV0ZXJtaW5pbmcgdGhlCi0gICAgICBhcHByb3ByaWF0ZW5lc3Mgb2YgdXNpbmcgb3IgcmVkaXN0cmlidXRpbmcgdGhlIFdvcmsgYW5kIGFzc3VtZSBhbnkKLSAgICAgIHJpc2tzIGFzc29jaWF0ZWQgd2l0aCBZb3VyIGV4ZXJjaXNlIG9mIHBlcm1pc3Npb25zIHVuZGVyIHRoaXMgTGljZW5zZS4KLQotICAgOC4gTGltaXRhdGlvbiBvZiBMaWFiaWxpdHkuIEluIG5vIGV2ZW50IGFuZCB1bmRlciBubyBsZWdhbCB0aGVvcnksCi0gICAgICB3aGV0aGVyIGluIHRvcnQgKGluY2x1ZGluZyBuZWdsaWdlbmNlKSwgY29udHJhY3QsIG9yIG90aGVyd2lzZSwKLSAgICAgIHVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyAoc3VjaCBhcyBkZWxpYmVyYXRlIGFuZCBncm9zc2x5Ci0gICAgICBuZWdsaWdlbnQgYWN0cykgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNoYWxsIGFueSBDb250cmlidXRvciBiZQotICAgICAgbGlhYmxlIHRvIFlvdSBmb3IgZGFtYWdlcywgaW5jbHVkaW5nIGFueSBkaXJlY3QsIGluZGlyZWN0LCBzcGVjaWFsLAotICAgICAgaW5jaWRlbnRhbCwgb3IgY29uc2VxdWVudGlhbCBkYW1hZ2VzIG9mIGFueSBjaGFyYWN0ZXIgYXJpc2luZyBhcyBhCi0gICAgICByZXN1bHQgb2YgdGhpcyBMaWNlbnNlIG9yIG91dCBvZiB0aGUgdXNlIG9yIGluYWJpbGl0eSB0byB1c2UgdGhlCi0gICAgICBXb3JrIChpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIGRhbWFnZXMgZm9yIGxvc3Mgb2YgZ29vZHdpbGwsCi0gICAgICB3b3JrIHN0b3BwYWdlLCBjb21wdXRlciBmYWlsdXJlIG9yIG1hbGZ1bmN0aW9uLCBvciBhbnkgYW5kIGFsbAotICAgICAgb3RoZXIgY29tbWVyY2lhbCBkYW1hZ2VzIG9yIGxvc3NlcyksIGV2ZW4gaWYgc3VjaCBDb250cmlidXRvcgotICAgICAgaGFzIGJlZW4gYWR2aXNlZCBvZiB0aGUgcG9zc2liaWxpdHkgb2Ygc3VjaCBkYW1hZ2VzLgotCi0gICA5LiBBY2NlcHRpbmcgV2FycmFudHkgb3IgQWRkaXRpb25hbCBMaWFiaWxpdHkuIFdoaWxlIHJlZGlzdHJpYnV0aW5nCi0gICAgICB0aGUgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIFlvdSBtYXkgY2hvb3NlIHRvIG9mZmVyLAotICAgICAgYW5kIGNoYXJnZSBhIGZlZSBmb3IsIGFjY2VwdGFuY2Ugb2Ygc3VwcG9ydCwgd2FycmFudHksIGluZGVtbml0eSwKLSAgICAgIG9yIG90aGVyIGxpYWJpbGl0eSBvYmxpZ2F0aW9ucyBhbmQvb3IgcmlnaHRzIGNvbnNpc3RlbnQgd2l0aCB0aGlzCi0gICAgICBMaWNlbnNlLiBIb3dldmVyLCBpbiBhY2NlcHRpbmcgc3VjaCBvYmxpZ2F0aW9ucywgWW91IG1heSBhY3Qgb25seQotICAgICAgb24gWW91ciBvd24gYmVoYWxmIGFuZCBvbiBZb3VyIHNvbGUgcmVzcG9uc2liaWxpdHksIG5vdCBvbiBiZWhhbGYKLSAgICAgIG9mIGFueSBvdGhlciBDb250cmlidXRvciwgYW5kIG9ubHkgaWYgWW91IGFncmVlIHRvIGluZGVtbmlmeSwKLSAgICAgIGRlZmVuZCwgYW5kIGhvbGQgZWFjaCBDb250cmlidXRvciBoYXJtbGVzcyBmb3IgYW55IGxpYWJpbGl0eQotICAgICAgaW5jdXJyZWQgYnksIG9yIGNsYWltcyBhc3NlcnRlZCBhZ2FpbnN0LCBzdWNoIENvbnRyaWJ1dG9yIGJ5IHJlYXNvbgotICAgICAgb2YgeW91ciBhY2NlcHRpbmcgYW55IHN1Y2ggd2FycmFudHkgb3IgYWRkaXRpb25hbCBsaWFiaWxpdHkuCi0KLSAgIEVORCBPRiBURVJNUyBBTkQgQ09ORElUSU9OUwotCi0gICBBUFBFTkRJWDogSG93IHRvIGFwcGx5IHRoZSBBcGFjaGUgTGljZW5zZSB0byB5b3VyIHdvcmsuCi0KLSAgICAgIFRvIGFwcGx5IHRoZSBBcGFjaGUgTGljZW5zZSB0byB5b3VyIHdvcmssIGF0dGFjaCB0aGUgZm9sbG93aW5nCi0gICAgICBib2lsZXJwbGF0ZSBub3RpY2UsIHdpdGggdGhlIGZpZWxkcyBlbmNsb3NlZCBieSBicmFja2V0cyAiW10iCi0gICAgICByZXBsYWNlZCB3aXRoIHlvdXIgb3duIGlkZW50aWZ5aW5nIGluZm9ybWF0aW9uLiAoRG9uJ3QgaW5jbHVkZQotICAgICAgdGhlIGJyYWNrZXRzISkgIFRoZSB0ZXh0IHNob3VsZCBiZSBlbmNsb3NlZCBpbiB0aGUgYXBwcm9wcmlhdGUKLSAgICAgIGNvbW1lbnQgc3ludGF4IGZvciB0aGUgZmlsZSBmb3JtYXQuIFdlIGFsc28gcmVjb21tZW5kIHRoYXQgYQotICAgICAgZmlsZSBvciBjbGFzcyBuYW1lIGFuZCBkZXNjcmlwdGlvbiBvZiBwdXJwb3NlIGJlIGluY2x1ZGVkIG9uIHRoZQotICAgICAgc2FtZSAicHJpbnRlZCBwYWdlIiBhcyB0aGUgY29weXJpZ2h0IG5vdGljZSBmb3IgZWFzaWVyCi0gICAgICBpZGVudGlmaWNhdGlvbiB3aXRoaW4gdGhpcmQtcGFydHkgYXJjaGl2ZXMuCi0KLSAgIENvcHlyaWdodCBbeXl5eV0gW25hbWUgb2YgY29weXJpZ2h0IG93bmVyXQotCi0gICBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAgIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotCi0gICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0KLSAgIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAgIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAgIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAgIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotCi0tLS0gZW5kIG9mIExJQ0VOU0UgLS0tCi0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLQpkaWZmIC0tZ2l0IGEvVFJBREVNQVJLIGIvVFJBREVNQVJLCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2NTg3YmFmLi4wMDAwMDAwCi0tLSBhL1RSQURFTUFSSworKysgL2Rldi9udWxsCkBAIC0xLDQxICswLDAgQEAKLU9wZW5KREsgVHJhZGVtYXJrIE5vdGljZQotVmVyc2lvbiAxLjEsIDIwMDgvMy8xMAotCi1PcGVuSkRLICh0aGUgIk5hbWUiKSBpcyBhIHRyYWRlbWFyayBvZiBTdW4gTWljcm9zeXN0ZW1zLCBJbmMuICh0aGUgIk93bmVyIikuCi1Pd25lciBwZXJtaXRzIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weSBvZiB0aGlzIHNvZnR3YXJlICh0aGUgIlNvZnR3YXJlIikKLXdoaWNoIGlzIGJhc2VkIG9uIG9yaWdpbmFsIHNvZnR3YXJlIHJldHJpZXZlZCBmcm9tIG9uZSBvZiB0aGUgZm9sbG93aW5nCi13ZWJzaXRlczogaHR0cDovL2Rvd25sb2FkLmphdmEubmV0L29wZW5qZGssIGh0dHA6Ly9oZy5vcGVuamRrLmphdmEubmV0L2pkazYsCi1vciBodHRwOi8vb3Blbmpkay5qYXZhLm5ldCAoZWFjaCBhICJXZWJzaXRlIiwgd2l0aCB0aGUgb3JpZ2luYWwgc29mdHdhcmUgbWFkZQotYXZhaWxhYmxlIGJ5IHRoZSBPd25lciBvbiBhIFdlYnNpdGUgYmVpbmcga25vd24gYXMgdGhlICJXZWJzaXRlIFNvZnR3YXJlIikgdG8KLXVzZSB0aGUgTmFtZSBpbiBwYWNrYWdlIG5hbWVzIGFuZCB2ZXJzaW9uIHN0cmluZ3Mgb2YgdGhlIFNvZnR3YXJlIHN1YmplY3QgdG8KLXRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKLQotICAtIFRoZSBTb2Z0d2FyZSBpcyBhIHN1YnN0YW50aWFsbHkgY29tcGxldGUgaW1wbGVtZW50YXRpb24gb2YgdGhlIE9wZW5KREsKLSAgICBkZXZlbG9wbWVudCBraXQgb3IgcnVudGltZSBlbnZpcm9ubWVudCBjb2RlIG1hZGUgYXZhaWxhYmxlIGJ5IE93bmVyIG9uIGEKLSAgICBXZWJzaXRlLCBhbmQgdGhlIHZhc3QgbWFqb3JpdHkgb2YgdGhlIFNvZnR3YXJlIGNvZGUgaXMgaWRlbnRpY2FsIHRvIHRoZQotICAgIHVwc3RyZWFtIFdlYnNpdGUgU29mdHdhcmU7Ci0KLSAgLSBObyBwZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkIHRvIHVzZSB0aGUgTmFtZSBpbiBhbnkgb3RoZXIgbWFubmVyLAotICAgIHVubGVzcyBzdWNoIHVzZSBjb25zdGl0dXRlcyAiZmFpciB1c2UuIgotCi0gIC0gVGhlIE93bmVyIG1ha2VzIG5vIHdhcnJhbnRpZXMgb2YgYW55IGtpbmQgcmVzcGVjdGluZyB0aGUgTmFtZSBhbmQgYWxsCi0gICAgcmVwcmVzZW50YXRpb25zIGFuZCB3YXJyYW50aWVzLCBpbmNsdWRpbmcgYW55IGltcGxpZWQgd2FycmFudHkgb2YKLSAgICBtZXJjaGFudGFiaWxpdHksIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlIG9yIG5vbi1pbmZyaW5nZW1lbnQKLSAgICBhcmUgaGVyZWJ5IGRpc2NsYWltZWQ7IGFuZAotCi0gIC0gVGhpcyBub3RpY2UgYW5kIHRoZSBmb2xsb3dpbmcgbGVnZW5kIGFyZSBpbmNsdWRlZCBpbiBhbGwgY29waWVzIG9mIHRoZQotICAgIFNvZnR3YXJlIG9yIHBvcnRpb25zIG9mIGl0OgotCi0gICAgICAgIE9wZW5KREsgaXMgYSB0cmFkZW1hcmsgb3IgcmVnaXN0ZXJlZCB0cmFkZW1hcmsgb2YgU3VuIE1pY3Jvc3lzdGVtcywKLSAgICAgICAgSW5jLiBpbiB0aGUgVW5pdGVkIFN0YXRlcyBhbmQgb3RoZXIgY291bnRyaWVzLgotCi1UaGUgTmFtZSBtYXkgYWxzbyBiZSB1c2VkIGluIGNvbm5lY3Rpb24gd2l0aCBkZXNjcmlwdGlvbnMgb2YgdGhlIFNvZnR3YXJlIHRoYXQKLWNvbnN0aXR1dGUgImZhaXIgdXNlLCIgc3VjaCBhcyAiZGVyaXZlZCBmcm9tIHRoZSBPcGVuSkRLIGNvZGUgYmFzZSIgb3IgImJhc2VkCi1vbiB0aGUgT3BlbkpESyBzb3VyY2UgY29kZS4iCi0KLU93bmVyIGludGVuZHMgdG8gcmV2aXNlIHRoaXMgTm90aWNlIGFzIG5lY2Vzc2FyeSBpbiBvcmRlciB0byBtZWV0IHRoZSBuZWVkcyBvZgotdGhlIE9wZW5KREsgQ29tbXVuaXR5LiAgUGxlYXNlIHNlbmQgcXVlc3Rpb25zIG9yIGNvbW1lbnRzIGFib3V0IHRoaXMgTm90aWNlIHRvCi1TdW4gTWljcm9zeXN0ZW1zIGF0IG9wZW5qZGstdG1Ac3VuLmNvbS4gIFJldmlzaW9ucyB0byB0aGlzIE5vdGljZSB3aWxsIGJlCi1hbm5vdW5jZWQgb24gdGhlIHB1YmxpYyBtYWlsaW5nIGxpc3QgYW5ub3VuY2VAb3Blbmpkay5qYXZhLm5ldCwgdG8gd2hpY2ggeW91Ci1tYXkgc3Vic2NyaWJlIGJ5IHZpc2l0aW5nIGh0dHA6Ly9tYWlsLm9wZW5qZGsuamF2YS5uZXQuICBUaGUgbGF0ZXN0IHZlcnNpb24gb2YKLXRoaXMgTm90aWNlIG1heSBiZSBmb3VuZCBhdCBodHRwOi8vb3Blbmpkay5qYXZhLm5ldC9sZWdhbC4KZGlmZiAtLWdpdCBhL2J1aWxkLnByb3BlcnRpZXMgYi9idWlsZC5wcm9wZXJ0aWVzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA5MjQwYWNjLi4wMDAwMDAwCi0tLSBhL2J1aWxkLnByb3BlcnRpZXMKKysrIC9kZXYvbnVsbApAQCAtMSw5MiArMCwwIEBACi0jCi0jIENvcHlyaWdodCAoYykgMjAwNywgMjAxMSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSMgRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotIwotIyBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotIyB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotIyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSMgcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotIyBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSMKLSMgVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0jIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotIyBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSMgdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSMgYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSMKLSMgWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotIyAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0jIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSMKLSMgUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSMgb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotIyBxdWVzdGlvbnMuCi0jCi0KLSMgVGhpcyBpcyB0aGUgSkRLIHVzZWQgdG8gYnVpbGQgYW5kIHJ1biB0aGUgYm9vdHN0cmFwIHZlcnNpb24gb2YgamF2YWMuCi0jIFRoZSBib290c3RyYXAgamF2YWMgaXMgdXNlZCB0byBjb21waWxlIGJvdGggYm9vc3RyYXAgdmVyc2lvbnMgb2YgdGhlCi0jIG90aGVyIHRvb2xzLCBhbmQgcHJvZHVjdCB2ZXJzaW9ucyBvZiBhbGwgdGhlIHRvb2xzLgotIyBPdmVycmlkZSB0aGlzIHBhdGggYXMgbmVlZGVkLCBlaXRoZXIgb24gdGhlIGNvbW1hbmQgbGluZSBvciBpbiAKLSMgb25lIG9mIHRoZSBzdGFuZGFyZCB1c2VyIGJ1aWxkLnByb3BlcnRpZXMgZmlsZXMgKHNlZSBidWlsZC54bWwpCi1qYXZhYy5qYXI9JHtib290c3RyYXAuZGlyfS9saWIvamF2YWMuamFyCi0KLSMgVGhlIHRvb2xzLmphciBpcyBuZWVkZWQgaW4gdGhlIGNsYXNzcGF0aCB0byBjb21waWxlIHRoZXNlIHNvdXJjZXMKLWpkay5ob21lPSR7amF2YS5ob21lfS8uLgotdG9vbHMuamFyPSR7amRrLmhvbWV9L2xpYi90b29scy5qYXIKLQotIyBvcHRpb25zIGZvciB0aGUgPGphdmFjPiB0YXNrcyB1c2VkIHRvIGNvbXBpbGUgdGhlIHRvb2xzCi1qYXZhYy5zb3VyY2UgPSA3Ci1qYXZhYy50YXJnZXQgPSA3Ci1qYXZhYy5kZWJ1ZyA9IHRydWUKLWphdmFjLm5vLmpkay53YXJuaW5ncyA9IC1YRGlnbm9yZS5zeW1ib2wuZmlsZT10cnVlCi0jIHNldCB0aGUgZm9sbG93aW5nIHRvIC12ZXJzaW9uIHRvIHZlcmlmeSB0aGUgdmVyc2lvbnMgb2YgamF2YWMgYmVpbmcgdXNlZAotamF2YWMudmVyc2lvbi5vcHQgPSAKLSMgaW4gdGltZSwgdGhlcmUgc2hvdWxkIGJlIG5vIGV4Y2VwdGlvbnMgdG8gLVhsaW50OmFsbAotI2phdmFjLmxpbnQub3B0cyA9IC1YbGludDphbGwsLXVuY2hlY2tlZCwtZGVwcmVjYXRpb24sLWZhbGx0aHJvdWdoLC1jYXN0LC1zZXJpYWwKLWphdmFjLmxpbnQub3B0cz0KLQotIyBKVk0gbWVtb3J5IHNpemUKLWphdmFjLm1lbW9yeUluaXRpYWxTaXplID0gMjU2bQotamF2YWMubWVtb3J5TWF4aW11bVNpemUgPSA1MTJtCi0KLSMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLQotIyBSb290IG9mIG91dHB1dCBkaXJlY3Rvcmllcwotb3V0cHV0LmRpcj0uCi0KLSMgQnVpbHQgZmlsZXMKLWJ1aWxkLmRpcj0ke291dHB1dC5kaXJ9L2J1aWxkCi1idWlsZC5jbGFzc2VzLmRpcj0ke2J1aWxkLmRpcn0vY2xhc3NlcwotCi0jIERpc3RyaWJ1dGVkIHJlc3VsdHMKLWRpc3QuZGlyPSR7b3V0cHV0LmRpcn0vZGlzdAotZGlzdC5saWIuZGlyPSR7ZGlzdC5kaXJ9L2xpYgotZGlzdC5jbGFzc2VzLmphcj0ke2Rpc3QubGliLmRpcn0vY2xhc3Nlcy5qYXIKLWRpc3Quc3JjLnppcD0ke2Rpc3QubGliLmRpcn0vc3JjLnppcAotCi0jIFNhbml0eSBpbmZvcm1hdGlvbgotc2FuaXR5LmluZm89IFNhbml0eSBTZXR0aW5nczoke2xpbmUuc2VwYXJhdG9yfVwKLSAgYW50LmhvbWU9JHthbnQuaG9tZX0ke2xpbmUuc2VwYXJhdG9yfVwKLSAgYW50LnZlcnNpb249JHthbnQudmVyc2lvbn0ke2xpbmUuc2VwYXJhdG9yfVwKLSAgYW50LmphdmEudmVyc2lvbj0ke2FudC5qYXZhLnZlcnNpb259JHtsaW5lLnNlcGFyYXRvcn1cCi0gIGphdmEuaG9tZT0ke2phdmEuaG9tZX0ke2xpbmUuc2VwYXJhdG9yfVwKLSAgamF2YS52ZXJzaW9uPSR7amF2YS52ZXJzaW9ufSR7bGluZS5zZXBhcmF0b3J9XAotICBvcy5uYW1lPSR7b3MubmFtZX0ke2xpbmUuc2VwYXJhdG9yfVwKLSAgb3MuYXJjaD0ke29zLmFyY2h9JHtsaW5lLnNlcGFyYXRvcn1cCi0gIG9zLnZlcnNpb249JHtvcy52ZXJzaW9ufSR7bGluZS5zZXBhcmF0b3J9XAotICBib290c3RyYXAuZGlyPSR7Ym9vdHN0cmFwLmRpcn0ke2xpbmUuc2VwYXJhdG9yfVwKLSAgamF2YWMuamFyPSR7amF2YWMuamFyfSR7bGluZS5zZXBhcmF0b3J9XAotICBqYXZhYy5tZW1vcnlJbml0aWFsU2l6ZT0ke2phdmFjLm1lbW9yeUluaXRpYWxTaXplfSR7bGluZS5zZXBhcmF0b3J9XAotICBqYXZhYy5tZW1vcnlNYXhpbXVtU2l6ZT0ke2phdmFjLm1lbW9yeU1heGltdW1TaXplfSR7bGluZS5zZXBhcmF0b3J9XAotICBqYXZhYy5zb3VyY2U9JHtqYXZhYy5zb3VyY2V9JHtsaW5lLnNlcGFyYXRvcn1cCi0gIGphdmFjLmRlYnVnPSR7amF2YWMuZGVidWd9JHtsaW5lLnNlcGFyYXRvcn1cCi0gIGphdmFjLnRhcmdldD0ke2phdmFjLnRhcmdldH0ke2xpbmUuc2VwYXJhdG9yfVwKLSAgamF2YWMudmVyc2lvbi5vcHQ9JHtqYXZhYy52ZXJzaW9uLm9wdH0ke2xpbmUuc2VwYXJhdG9yfVwKLSAgamF2YWMubGludC5vcHRzPSR7amF2YWMubGludC5vcHRzfSR7bGluZS5zZXBhcmF0b3J9XAotICBqYXZhYy5uby5qZGsud2FybmluZ3M9JHtqYXZhYy5uby5qZGsud2FybmluZ3N9JHtsaW5lLnNlcGFyYXRvcn1cCi0gIG91dHB1dC5kaXI9JHtvdXRwdXQuZGlyfSR7bGluZS5zZXBhcmF0b3J9XAotICBidWlsZC5kaXI9JHtidWlsZC5kaXJ9JHtsaW5lLnNlcGFyYXRvcn1cCi0gIGRpc3QuZGlyPSR7ZGlzdC5kaXJ9JHtsaW5lLnNlcGFyYXRvcn1cCi0ke2xpbmUuc2VwYXJhdG9yfQotCi0jLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCmRpZmYgLS1naXQgYS9idWlsZC54bWwgYi9idWlsZC54bWwKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDcyY2RjYTIuLjAwMDAwMDAKLS0tIGEvYnVpbGQueG1sCisrKyAvZGV2L251bGwKQEAgLTEsMjE3ICswLDAgQEAKLTw/eG1sIHZlcnNpb249IjEuMCI/PgotPCEtLQotIENvcHlyaWdodCAoYykgMjAwOSwgMjAxMCwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0KLSBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotCi0gVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotCi0gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0KLSBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSBxdWVzdGlvbnMuCi0tLT4KLQotPHByb2plY3QgbmFtZT0iamF4cCIgZGVmYXVsdD0iYWxsIiBiYXNlZGlyPSIuIj4KLSAgIAotICAgIDwhLS0gRm9yICdhbnQgLXAnIG9yICdhbnQgLXByb2plY3RoZWxwJyAtLT4KLSAgICAKLSAgICA8ZGVzY3JpcHRpb24+Ci0gICAgQW50IGJ1aWxkIHNjcmlwdCBmb3IgdGhlICR7YW50LnByb2plY3QubmFtZX0gcGFydCBvZiB0aGUgamRrLgotCi0gICAgSW5wdXQgUHJvcGVydGllczogKHNlZSBidWlsZC5wcm9wZXJ0aWVzIGZvciB0aGUgYW50IGRlZmF1bHRzKQotICAgICAgYm9vdHN0cmFwLmRpciAgICAgICAgLSBkaXIgd2l0aCBsaWIvamF2YWMuamFyLCBhZGRlZCB0byBqYXZhYyBib290Y2xhc3NwYXRoCi0gICAgICBqYXZhYy5kZWJ1ZyAgICAgICAgICAtIHRydWUgb3IgZmFsc2UgZm9yIGRlYnVnIGNsYXNzZmlsZXMKLSAgICAgIGphdmFjLnRhcmdldCAgICAgICAgIC0gY2xhc3NmaWxlIHZlcnNpb24gdGFyZ2V0Ci0gICAgICBqYXZhYy5zb3VyY2UgICAgICAgICAtIHNvdXJjZSB2ZXJzaW9uCi0KLSAgICAgIFJ1biAnbWFrZSBoZWxwJyBmb3IgaGVscCB1c2luZyB0aGUgTWFrZWZpbGUuCi0gICAgPC9kZXNjcmlwdGlvbj4KLQotICAgIDwhLS0gUHJvamVjdCBidWlsZCBwcm9wZXJ0aWVzLiAtLT4KLSAgICA8cHJvcGVydHkgZmlsZT0iYnVpbGQucHJvcGVydGllcyIvPgotCi0gICAgPCEtLSBTb3VyY2UgZGlyIGRlZiAtLT4KLSAgICA8cHJvcGVydHkgbmFtZT0iamF4cC5zcmMuZGlyIiB2YWx1ZT0ic3JjIi8+Ci0gICAgPHBhdGggaWQ9InNyYy5kaXIuaWQiPgotICAgICAgPHBhdGhlbGVtZW50IHBhdGg9IiR7amF4cC5zcmMuZGlyfSIvPgotICAgIDwvcGF0aD4KLQotICAgIDwhLS0gSW5pdGlhbGl6YXRpb24gb2YgZGlyZWN0b3JpZXMgbmVlZGVkIGZvciBidWlsZC4gLS0+Ci0gICAgPHRhcmdldCBuYW1lPSJpbml0Ij4KLSAgICAgICAgPG1rZGlyIGRpcj0iJHtidWlsZC5kaXJ9Ii8+Ci0gICAgICAgIDxta2RpciBkaXI9IiR7YnVpbGQuY2xhc3Nlcy5kaXJ9Ii8+Ci0gICAgICAgIDxta2RpciBkaXI9IiR7ZGlzdC5kaXJ9Ii8+Ci0gICAgICAgIDxta2RpciBkaXI9IiR7ZGlzdC5saWIuZGlyfSIvPgotICAgIDwvdGFyZ2V0PgotICAgIAotICAgIDwhLS0gU2FuaXR5IGNoZWNrcyBhbmQgc2V0dGluZ3MgLS0+Ci0gICAgPHRhcmdldCBuYW1lPSJzYW5pdHkiCi0JICAgIGRlcGVuZHM9Ii1qYXZhYy1qYXItZXhpc3RzIgotICAgICAgICAgICAgZGVzY3JpcHRpb249IkRpc3BsYXkgc2V0dGluZ3Mgb2YgY29uZmlndXJhdGlvbiB2YWx1ZXMiPgotICAgICAgICA8ZWNobyBtZXNzYWdlPSIke3Nhbml0eS5pbmZvfSIvPgotICAgIDwvdGFyZ2V0PgotCi0gICAgIDwhLS0gQ2hlY2sgZm9yIGJvb3RzdHJhcCBqYXZhYy5qYXIgZmlsZSwgd2FybiBpZiBtaXNzaW5nLiAtLT4KLSAgICA8Y29uZGl0aW9uIHByb3BlcnR5PSJqYXZhYy5qYXIuZXhpc3RzIj4KLSAgICAgICAgPGF2YWlsYWJsZSBmaWxlPSIke2phdmFjLmphcn0iIHR5cGU9ImZpbGUiLz4KLSAgICA8L2NvbmRpdGlvbj4KLSAgICA8dGFyZ2V0IG5hbWU9Ii1qYXZhYy1qYXItZXhpc3RzIgotICAgICAgICAgICAgdW5sZXNzPSJqYXZhYy5qYXIuZXhpc3RzIj4KLSAgICAgICAgPGVjaG8gbWVzc2FnZT0iV0FSTklORzogQ2Fubm90IGZpbmQgJHtqYXZhYy5qYXJ9Ii8+Ci0gICAgPC90YXJnZXQ+Ci0KLSAgICA8IS0tIENyZWF0aW9uIG9mIGRpc3RyaWJ1dGlvbiBmaWxlcyB0byBqZGsgYnVpbGQgcHJvY2Vzcy4gLS0+Ci0gICAgPHRhcmdldCBuYW1lPSJkaXN0IgotCSAgICBkZXBlbmRzPSJpbml0LCBidWlsZCwgLWRpc3QtY2xhc3Nlcy1qYXIsIC1kaXN0LXNyYy16aXAiCi0gICAgICAgICAgICBkZXNjcmlwdGlvbj0iQ3JlYXRlIGFsbCBidWlsdCBkaXN0cmlidXRpb24gZmlsZXMuIj4KLSAgICA8L3RhcmdldD4KLSAgICA8dGFyZ2V0IG5hbWU9Ii1kaXN0LWNsYXNzZXMtamFyLXVwdG9kYXRlIgotCSAgICBkZXBlbmRzPSJpbml0Ij4KLSAgICAgICAgPGNvbmRpdGlvbiBwcm9wZXJ0eT0iZGlzdC5jbGFzc2VzLmphci51cHRvZGF0ZSI+Ci0gICAgICAgICAgICA8YW5kPgotICAgICAgICAgICAgICAgIDxhdmFpbGFibGUgZmlsZT0iJHtkaXN0LmNsYXNzZXMuamFyfSIgdHlwZT0iZmlsZSIvPgotICAgICAgICAgICAgICAgIDx1cHRvZGF0ZSB0YXJnZXRmaWxlPSIke2Rpc3QuY2xhc3Nlcy5qYXJ9Ij4KLSAgICAgICAgICAgICAgICAgICAgPHNyY2ZpbGVzIGRpcj0iJHtidWlsZC5jbGFzc2VzLmRpcn0iIGluY2x1ZGVzPSIqKiIvPgotICAgICAgICAgICAgICAgIDwvdXB0b2RhdGU+Ci0gICAgICAgICAgICA8L2FuZD4KLSAgICAgICAgPC9jb25kaXRpb24+Ci0gICAgPC90YXJnZXQ+Ci0gICAgPHRhcmdldCBuYW1lPSItZGlzdC1jbGFzc2VzLWphciIKLQkgICAgZGVwZW5kcz0iaW5pdCwgLWRpc3QtY2xhc3Nlcy1qYXItdXB0b2RhdGUiCi0gICAgICAgICAgICB1bmxlc3M9ImRpc3QuY2xhc3Nlcy5qYXIudXB0b2RhdGUiPgotICAgICAgICA8ZGVsZXRlIGZpbGU9IiR7ZGlzdC5jbGFzc2VzLmphcn0iLz4KLSAgICAgICAgPGphciBmaWxlPSIke2Rpc3QuY2xhc3Nlcy5qYXJ9IiBiYXNlZGlyPSIke2J1aWxkLmNsYXNzZXMuZGlyfSIvPgotICAgIDwvdGFyZ2V0PgotCi0gICAgPCEtLSBTcGVjaWFsIGJ1aWxkIGFyZWEgc2V0dXAuIC0tPgotICAgIDx0YXJnZXQgbmFtZT0iLWJ1aWxkLXNldHVwIiBkZXBlbmRzPSJpbml0Ij4KLSAgICAgICAgPG1rZGlyIGRpcj0iJHtidWlsZC5jbGFzc2VzLmRpcn0iLz4KLSAgICAgICAgPGNvcHkgdG9kaXI9IiR7YnVpbGQuY2xhc3Nlcy5kaXJ9Ij4KLSAgICAgICAgICAgIDxmaWxlc2V0IGRpcj0iJHtqYXhwLnNyYy5kaXJ9IgotICAgICAgICAgICAgICAgICAgICAgaW5jbHVkZXM9IioqLyoucHJvcGVydGllcyIvPgotICAgICAgICA8L2NvcHk+Ci0gICAgICAgIDxyZXBsYWNlcmVnZXhwIG1hdGNoPSIjKC4qKSQiIHJlcGxhY2U9IiMiIGZsYWdzPSJnbSI+Ci0gICAgICAgICAgICA8ZmlsZXNldCBkaXI9IiR7YnVpbGQuY2xhc3Nlcy5kaXJ9IiBpbmNsdWRlcz0iKiovKi5wcm9wZXJ0aWVzIi8+Ci0gICAgICAgIDwvcmVwbGFjZXJlZ2V4cD4KLSAgICA8L3RhcmdldD4KLQotICAgIDwhLS0gQ3JlYXRlIHNyYy56aXAuIC0tPgotICAgIDx0YXJnZXQgbmFtZT0iLWRpc3Qtc3JjLXppcCIgZGVwZW5kcz0iaW5pdCI+Ci0gICAgICAgIDx6aXAgZmlsZT0iJHtkaXN0LnNyYy56aXB9IiBiYXNlZGlyPSIke2pheHAuc3JjLmRpcn0iLz4KLSAgICA8L3RhcmdldD4KLSAgICAKLSAgICA8IS0tIEJ1aWxkIChjb21waWxhdGlvbikgb2Ygc291cmNlcyB0byBjbGFzcyBmaWxlcy4gLS0+Ci0gICAgPHRhcmdldCBuYW1lPSJidWlsZCIKLQkgICAgZGVwZW5kcz0iY29tcGlsZSwgLWJ1aWxkLXNldHVwIj4KLSAgICA8L3RhcmdldD4KLSAgICA8dGFyZ2V0IG5hbWU9ImNvbXBpbGUiCi0JICAgIGRlcGVuZHM9ImluaXQiPgotICAgICAgICA8bWtkaXIgZGlyPSIke2J1aWxkLmNsYXNzZXMuZGlyfSIvPgotICAgICAgICA8amF2YWMgCi0JICAgICBpbmNsdWRlQW50UnVudGltZT0iZmFsc2UiIAotCSAgICAgY2xhc3NwYXRoPSIke2J1aWxkLmNsYXNzZXMuZGlyfToke3Rvb2xzLmphcn0iCi0JICAgICBmb3JrPSJ0cnVlIgotICAgICAgICAgICAgIGRlc3RkaXI9IiR7YnVpbGQuY2xhc3Nlcy5kaXJ9IgotICAgICAgICAgICAgIG1lbW9yeUluaXRpYWxTaXplPSIke2phdmFjLm1lbW9yeUluaXRpYWxTaXplfSIKLSAgICAgICAgICAgICBtZW1vcnlNYXhpbXVtU2l6ZT0iJHtqYXZhYy5tZW1vcnlNYXhpbXVtU2l6ZX0iCi0gICAgICAgICAgICAgc291cmNlPSIke2phdmFjLnNvdXJjZX0iCi0JICAgICBkZWJ1Zz0iJHtqYXZhYy5kZWJ1Z30iCi0gICAgICAgICAgICAgdGFyZ2V0PSIke2phdmFjLnRhcmdldH0iPgotICAgICAgICAgICAgPGNvbXBpbGVyYXJnIHZhbHVlPSItSi1YYm9vdGNsYXNzcGF0aC9wOiR7amF2YWMuamFyfSIvPgotICAgICAgICAgICAgPGNvbXBpbGVyYXJnIGxpbmU9IiR7amF2YWMudmVyc2lvbi5vcHR9ICR7amF2YWMubGludC5vcHRzfSAke2phdmFjLm5vLmpkay53YXJuaW5nc30iLz4KLSAgICAgICAgICAgIDxzcmMgcmVmaWQ9InNyYy5kaXIuaWQiLz4KLSAgICAgICAgPC9qYXZhYz4KLSAgICA8L3RhcmdldD4KLQotICAgIDwhLS0gVGVzdC4gKEZJWE1FOiBOZWVkIHRvIGtub3cgaG93IHRvIHJ1biB0ZXN0cy4pIC0tPgotICAgIDx0YXJnZXQgbmFtZT0idGVzdCIKLQkgICAgZGVwZW5kcz0iaW5pdCwgZGlzdCI+Ci0gICAgICAgIDxlY2hvIG1lc3NhZ2U9IkZJWE1FOiBIb3cgZG8geW91IHJ1biB0aGUgdGVzdHMiLz4KLSAgICA8L3RhcmdldD4KLSAgICAKLSAgICA8IS0tIFBvcHVsYXRlIHNvdXJjZSBhcmVhIGlmIG5lZWRlZC4gLS0+Ci0gICAgPHRhcmdldCBuYW1lPSJzb3VyY2UiCi0gICAgICAgICAgICBkZXBlbmRzPSJpbml0IgotICAgICAgICAgICAgZGVzY3JpcHRpb249IlBvcHVsYXRlIGFsbCBzb3VyY2UgZmlsZSBkaXJlY3RvcmllcyI+Ci0gICAgPC90YXJnZXQ+Ci0KLSAgICA8IS0tIENsZWFuIHVwIGNvbXBpbGVkIGZpbGVzLiAtLT4KLSAgICA8dGFyZ2V0IG5hbWU9ImNsZWFuIgotICAgICAgICAgICAgZGVzY3JpcHRpb249IkRlbGV0ZSBhbGwgZ2VuZXJhdGVkIGZpbGVzIj4KLSAgICAgICAgPGRlbGV0ZSBkaXI9IiR7YnVpbGQuZGlyfSIvPgotICAgICAgICA8ZGVsZXRlIGRpcj0iJHtkaXN0LmRpcn0iLz4KLSAgICA8L3RhcmdldD4KLQotICAgIDwhLS0gQ2xlYW4gdXAgY29tcGlsZWQgZmlsZXMgYW5kIGFsbCBpbXBvcnRlZCBzb3VyY2UgZmlsZXMuIC0tPgotICAgIDx0YXJnZXQgbmFtZT0iY2xvYmJlciIKLQkgICAgZGVwZW5kcz0iY2xlYW4iCi0gICAgICAgICAgICBkZXNjcmlwdGlvbj0iRGVsZXRlIGFsbCBnZW5lcmF0ZWQgZmlsZXMsIGluY2x1ZGluZyBpbXBvcnRlZCBzb3VyY2VzIj4KLSAgICA8L3RhcmdldD4KLQotICAgIDx0YXJnZXQgbmFtZT0iLWJhbm5lciI+Ci0gICAgICAgIDxlY2hvIG1lc3NhZ2U9IistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rIi8+Ci0gICAgICAgIDxlY2hvIG1lc3NhZ2U9IisgU3RhcnRpbmcgYW50IHByb2plY3QgJHthbnQucHJvamVjdC5uYW1lfSArIi8+Ci0gICAgICAgIDxlY2hvIG1lc3NhZ2U9IistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rIi8+Ci0gICAgPC90YXJnZXQ+Ci0gICAKLSAgICA8IS0tIERvIGV2ZXJ5dGhpbmcgYnV0IHRlc3QuIC0tPgotICAgIDx0YXJnZXQgbmFtZT0iYWxsIgotCSAgICBkZXBlbmRzPSItYmFubmVyLCBzYW5pdHksIGRpc3QiCi0gICAgICAgICAgICBkZXNjcmlwdGlvbj0iQnVpbGQgZXZlcnl0aGluZy4iPgotICAgICAgICA8ZWNobyBtZXNzYWdlPSIrLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKyIvPgotICAgICAgICA8ZWNobyBtZXNzYWdlPSIrIEZpbmlzaGluZyBhbnQgcHJvamVjdCAke2FudC5wcm9qZWN0Lm5hbWV9Ii8+Ci0gICAgICAgIDxlY2hvIG1lc3NhZ2U9IistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rIi8+Ci0gICAgPC90YXJnZXQ+Ci0KLSAgICA8dGFyZ2V0IG5hbWU9ImphdmFkb2MiIGRlcGVuZHM9ImluaXQiIGRlc2NyaXB0aW9uPSJCdWlsZCBiYXNpYyBKYXZhZG9jIGZvciBwdWJsaWMgcGFja2FnZXMuIj4KLSAgICAgICAgPHByb3BlcnR5IG5hbWU9ImphdmFkb2Mub3B0aW9ucyIgdmFsdWU9IiIvPiA8IS0tIGRlZmF1bHQsIGNhbiBiZSBvdmVycmlkZGVuIHBlciB1c2VyIG9yIHBlciBwcm9qZWN0IC0tPgotICAgICAgICA8IS0tIE5vdGU6IGV2ZW4gd2l0aCB0aGlzIGRlZmF1bHQgdmFsdWUsIGluY2x1ZGVzL2V4Y2x1ZGVzCi0gICAgICAgICBmcm9tIHNoYXJlLnNyYy5kaXIgZ2V0IGphdmFkb2MnZDsgc2VlIHBhY2thZ2VzZXQgYmVsb3cgLS0+Ci0gICAgICAgIDxwcm9wZXJ0eSBuYW1lPSJqYXZhZG9jLnBhY2thZ2VuYW1lcyIgdmFsdWU9Im5vbmUiLz4gPCEtLSBkZWZhdWx0LCBjYW4gYmUgb3ZlcnJpZGRlbiBwZXIgdXNlciBvciBwZXIgcHJvamVjdCAtLT4KLSAgICAgICAgPHByb3BlcnR5IG5hbWU9ImphdmFkb2MuZGlyIiB2YWx1ZT0iJHtidWlsZC5kaXJ9L2RvY3MvYXBpIi8+Ci0gICAgICAgIDxwcm9wZXJ0eSBuYW1lPSJpbmNsdWRlcyIgdmFsdWU9IioqIi8+Ci0gICAgICAgIDxqYXZhZG9jIGRlc3RkaXI9IiR7amF2YWRvYy5kaXJ9IiBzb3VyY2U9IjEuNSIKLSAgICAgICAgICAgIHdpbmRvd3RpdGxlPSJVTk9GRklDSUFMIiBmYWlsb25lcnJvcj0idHJ1ZSIgdXNlPSJ0cnVlIgotICAgICAgICAgICAgYXV0aG9yPSJmYWxzZSIgdmVyc2lvbj0iZmFsc2UiCi0gICAgICAgICAgICBwYWNrYWdlbmFtZXM9IiR7amF2YWRvYy5wYWNrYWdlbmFtZXN9Ij4KLSAgICAgICAgICAgIDxoZWFkZXI+PCFbQ0RBVEFbPHN0cm9uZz5Vbm9mZmljaWFsIEphdmFkb2M8L3N0cm9uZz4gZ2VuZXJhdGVkIGZyb20gZGV2ZWxvcGVyIHNvdXJjZXMgZm9yIHByZXZpZXcgcHVycG9zZXMgb25seV1dPjwvaGVhZGVyPgotICAgICAgICAgICAgPGFyZyBsaW5lPSIke2phdmFkb2Mub3B0aW9uc30iLz4KLSAgICAgICAgICAgIDxib290Y2xhc3NwYXRoPgotICAgICAgICAgICAgICAgIDxwYXRoIGxvY2F0aW9uPSIke2phdmEuaG9tZX0vbGliL3J0LmphciIvPgotICAgICAgICAgICAgICAgIDxwYXRoIGxvY2F0aW9uPSIke2J1aWxkLmNsYXNzZXMuZGlyfSIvPgotICAgICAgICAgICAgPC9ib290Y2xhc3NwYXRoPgotICAgICAgICAgICAgPHNvdXJjZXBhdGg+Ci0gICAgICAgICAgICAgICAgPHBhdGhlbGVtZW50IGxvY2F0aW9uPSIke2pheHAuc3JjLmRpcn0iLz4KLSAgICAgICAgICAgIDwvc291cmNlcGF0aD4KLSAgICAgICAgICAgIDwhLS0gWFhYIGp1c3QgPGZpbGVzZXQ+IChyZXN0cmljdGVkIGZ1cnRoZXIgdG8gKiovKi5qYXZhKSBhbmQgbm8gPHBhY2thZ2VzZXQ+IC0tPgotICAgICAgICAgICAgPCEtLSBtZWFucyB0aGF0IHtAbGluayBzb21lLnBhY2thZ2V9IHdpbGwgbm90IHdvcmssIHdoaWNoIGlzIG5vIGdvb2QuIC0tPgotICAgICAgICAgICAgPCEtLSAoSXQgY29ycmVjdGx5IHNraXBzIGV4Y2x1ZGVkIHNpbmdsZSBjbGFzc2VzLCBidXQgbm90IGlmIHBhY2thZ2VzZXQgaXMgYWxzbyBpbmNsdWRlZCwgLS0+Ci0gICAgICAgICAgICA8IS0tIHdoaWNoIGFsc28gY2F1c2VzIGR1cGxpY2F0ZXMgaW4gdGhlIGNsYXNzIGluZGV4IGZvciBpbmNsdWRlZCBmaWxlcy4pIC0tPgotICAgICAgICAgICAgPHBhY2thZ2VzZXQgZGlyPSIke2pheHAuc3JjLmRpcn0iIGluY2x1ZGVzPSIke2luY2x1ZGVzfSIgZXhjbHVkZXM9IiR7ZXhjbHVkZXN9Ij4KLSAgICAgICAgICAgICAgICA8b3I+Ci0gICAgICAgICAgICAgICAgICAgIDxmaWxlbmFtZSBuYW1lPSJqYXZheC8iLz4KLSAgICAgICAgICAgICAgICAgICAgPGZpbGVuYW1lIG5hbWU9Im9yZy93M2MvIi8+Ci0gICAgICAgICAgICAgICAgICAgIDxmaWxlbmFtZSBuYW1lPSJvcmcveG1sL3NheC8iLz4KLSAgICAgICAgICAgICAgICA8L29yPgotICAgICAgICAgICAgPC9wYWNrYWdlc2V0PgotICAgICAgICA8L2phdmFkb2M+Ci0gICAgPC90YXJnZXQ+Ci0gICAgPHRhcmdldCBuYW1lPSJqYXZhZG9jLW5iIiBkZXBlbmRzPSJqYXZhZG9jIiBpZj0ibmV0YmVhbnMuaG9tZSI+Ci0gICAgICAgIDxwcm9wZXJ0eSBuYW1lPSJqYXZhZG9jLmRpcj0iIHZhbHVlPSIke2J1aWxkLmRpcn0vZG9jcy9hcGkiLz4KLSAgICAgICAgPG5iYnJvd3NlIGZpbGU9IiR7amF2YWRvYy5kaXJ9L2luZGV4Lmh0bWwiLz4KLSAgICA8L3RhcmdldD4KLQotPC9wcm9qZWN0PgpkaWZmIC0tZ2l0IGEvbWFrZS9CdWlsZEpheHAuZ21rIGIvbWFrZS9CdWlsZEpheHAuZ21rCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3OTUwYjBjLi4wMDAwMDAwCi0tLSBhL21ha2UvQnVpbGRKYXhwLmdtaworKysgL2Rldi9udWxsCkBAIC0xLDcxICswLDAgQEAKLSMKLSMgQ29weXJpZ2h0IChjKSAyMDA3LCAyMDEzLCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotIyBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0jCi0jIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0jIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0jIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotIyBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0jIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotIwotIyBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSMgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0jIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotIyB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotIyBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotIwotIyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0jIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSMgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotIwotIyBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotIyBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0jIHF1ZXN0aW9ucy4KLSMKLQotIyBUaGlzIG11c3QgYmUgdGhlIGZpcnN0IHJ1bGUKLWRlZmF1bHQ6IGFsbAotCi0taW5jbHVkZSAkKFNQRUMpCi1pbmNsdWRlIE1ha2VCYXNlLmdtawotaW5jbHVkZSBKYXZhQ29tcGlsYXRpb24uZ21rCi0KLURJU0FCTEVfSkFYUF9XQVJOSU5HUyA6PSAtWGxpbnQ6YWxsLC1kZXByZWNhdGlvbiwtdW5jaGVja2VkLC1yYXd0eXBlcywtY2FzdCwtc2VyaWFsLC1kZXAtYW5uLC1zdGF0aWMsLWZhbGx0aHJvdWdoCi0KLSMgVGhlIGdlbmVyYXRlIG5ldyBieXRlY29kZSB1c2VzIHRoZSBuZXcgY29tcGlsZXIgZm9yIHRvIGdlbmVyYXRlIGJ5dGVjb2RlCi0jIGZvciB0aGUgbmV3IGpkayB0aGF0IGlzIGJlaW5nIGJ1aWx0LiBUaGUgY29kZSBjb21waWxlZCBieSB0aGlzIHNldHVwCi0jIGNhbm5vdCBuZWNlc3NhcmlseSBiZSBydW4gd2l0aCB0aGUgYm9vdCBqZGsuCi0kKGV2YWwgJChjYWxsIFNldHVwSmF2YUNvbXBpbGVyLEdFTkVSQVRFX05FV0JZVEVDT0RFX0RFQlVHLCBcCi0gICAgSlZNIDo9ICQoSkFWQSksIFwKLSAgICBKQVZBQyA6PSAkKE5FV19KQVZBQyksIFwKLSAgICBGTEFHUyA6PSAtWERpZ25vcmUuc3ltYm9sLmZpbGU9dHJ1ZSAkKERJU0FCTEVfSkFYUF9XQVJOSU5HUykgLWcsIFwKLSAgICBTRVJWRVJfRElSIDo9ICQoU0pBVkFDX1NFUlZFUl9ESVIpLCBcCi0gICAgU0VSVkVSX0pWTSA6PSAkKFNKQVZBQ19TRVJWRVJfSkFWQSkpKQotCi0kKGV2YWwgJChjYWxsIFNldHVwSmF2YUNvbXBpbGF0aW9uLEJVSUxEX0pBWFAsIFwKLSAgICBTRVRVUCA6PSBHRU5FUkFURV9ORVdCWVRFQ09ERV9ERUJVRywgXAotICAgIFNSQyA6PSAkKEpBWFBfVE9QRElSKS9zcmMsIFwKLSAgICBCSU4gOj0gJChKQVhQX09VVFBVVERJUikvY2xhc3NlcywgXAotICAgIFNSQ1pJUCA6PSAkKEpBWFBfT1VUUFVURElSKS9kaXN0L2xpYi9zcmMuemlwKSkKLQotIyBJbWl0YXRlIHRoZSBwcm9wZXJ0eSBjbGVhbmluZyBtZWNoYW5pc20gaW4gdGhlIG9sZCBidWlsZC4gVGhpcyB3aWxsIGxpa2VseSBiZSByZXBsYWNlZAotIyBieSB0aGUgdW5pZmllZCBmdW5jdGlvbmFsaXR5IGluIEphdmFDb21waWxhdGlvbi5nbWssIGJ1dCBrZWVwIGl0IHRoZSBzYW1lIGFzIG9sZCBidWlsZAotIyBmb3Igbm93LCBldmVuIHRob3VnaCBpdCBhY3R1YWxseSBicmVha3MgcHJvcGVydGllcyBjb250YWluaW5nICMgaW4gdGhlIHZhbHVlLgotIyBVc2luZyBuYXdrIHRvIGF2b2lkIHNvbGFyaXMgc2VkLgotJChKQVhQX09VVFBVVERJUikvY2xhc3Nlcy8lLnByb3BlcnRpZXM6ICQoSkFYUF9UT1BESVIpL3NyYy8lLnByb3BlcnRpZXMKLQkkKE1LRElSKSAtcCAkKEBEKQotCSQoUk0pICRAICRALnRtcAotCSQoQ0FUKSAkPCB8IExBTkc9QyAkKE5BV0spICd7IHN1YigvIy4qJCQvLCIjIik7IHByaW50IH0nID4gJEAudG1wCi0JJChNVikgJEAudG1wICRACi0KLVNSQ19QUk9QX0ZJTEVTIDo9ICQoc2hlbGwgJChGSU5EKSAkKEpBWFBfVE9QRElSKS9zcmMgLW5hbWUgIioucHJvcGVydGllcyIpCi1UQVJHRVRfUFJPUF9GSUxFUyA6PSAkKHBhdHN1YnN0ICQoSkFYUF9UT1BESVIpL3NyYy8lLCAkKEpBWFBfT1VUUFVURElSKS9jbGFzc2VzLyUsICQoU1JDX1BST1BfRklMRVMpKQotCi0kKGV2YWwgJChjYWxsIFNldHVwQXJjaGl2ZSxBUkNISVZFX0pBWFAsICQoQlVJTERfSkFYUCkgJChUQVJHRVRfUFJPUF9GSUxFUyksIFwKLSAgICBTUkNTIDo9ICQoSkFYUF9PVVRQVVRESVIpL2NsYXNzZXMsIFwKLSAgICBTVUZGSVhFUyA6PSAuY2xhc3MgLnByb3BlcnRpZXMsIFwKLSAgICBKQVIgOj0gJChKQVhQX09VVFBVVERJUikvZGlzdC9saWIvY2xhc3Nlcy5qYXIpKQotCi1hbGw6ICQoSkFYUF9PVVRQVVRESVIpL2Rpc3QvbGliL2NsYXNzZXMuamFyICQoSkFYUF9PVVRQVVRESVIpL2Rpc3QvbGliL3NyYy56aXAKLQotLlBIT05ZOiBkZWZhdWx0IGFsbApkaWZmIC0tZ2l0IGEvbWFrZS9NYWtlZmlsZSBiL21ha2UvTWFrZWZpbGUKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDQ1NzAwNzAuLjAwMDAwMDAKLS0tIGEvbWFrZS9NYWtlZmlsZQorKysgL2Rldi9udWxsCkBAIC0xLDQ5ICswLDAgQEAKLSMKLSMgQ29weXJpZ2h0IChjKSAyMDEyLCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotIyBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0jCi0jIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0jIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0jIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotIyBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0jIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotIwotIyBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSMgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0jIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotIyB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotIyBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotIwotIyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0jIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSMgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotIwotIyBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotIyBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0jIHF1ZXN0aW9ucy4KLSMKLQotIyBMb2NhdGUgdGhpcyBNYWtlZmlsZQotaWZlcSAoJChmaWx0ZXIgLyUsICQobGFzdHdvcmQgJChNQUtFRklMRV9MSVNUKSkpLCApCi0gIG1ha2VmaWxlX3BhdGggOj0gJChDVVJESVIpLyQobGFzdHdvcmQgJChNQUtFRklMRV9MSVNUKSkKLWVsc2UKLSAgbWFrZWZpbGVfcGF0aCA6PSAkKGxhc3R3b3JkICQoTUFLRUZJTEVfTElTVCkpCi1lbmRpZgotcmVwb19kaXIgOj0gJChwYXRzdWJzdCAlL21ha2UvTWFrZWZpbGUsICUsICQobWFrZWZpbGVfcGF0aCkpCi0KLSMgV2hhdCBpcyB0aGUgbmFtZSBvZiB0aGlzIHN1YnN5c3RlbSAobGFuZ3Rvb2xzLCBjb3JiYSwgZXRjKT8KLXN1YnN5c3RlbV9uYW1lIDo9ICQobm90ZGlyICQocmVwb19kaXIpKQotCi0jIFRyeSB0byBsb2NhdGUgdG9wLWxldmVsIG1ha2VmaWxlCi10b3BfbGV2ZWxfbWFrZWZpbGUgOj0gJChyZXBvX2RpcikvLi4vTWFrZWZpbGUKLWlmbmVxICgkKHdpbGRjYXJkICQodG9wX2xldmVsX21ha2VmaWxlKSksICkKLSAgJChpbmZvIFdpbGwgcnVuICQoc3Vic3lzdGVtX25hbWUpIHRhcmdldCBvbiB0b3AtbGV2ZWwgTWFrZWZpbGUpCi0gICQoaW5mbyBXQVJOSU5HOiBUaGlzIGlzIGEgbm9uLXJlY29tbWVuZGVkIHdheSBvZiBidWlsZGluZyEpCi0gICQoaW5mbyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0pCi1lbHNlCi0gICQoaW5mbyBDYW5ub3QgbG9jYXRlIHRvcC1sZXZlbCBNYWtlZmlsZS4gSXMgdGhpcyByZXBvIG5vdCBjaGVja2VkIG91dCBhcyBwYXJ0IG9mIGEgY29tcGxldGUgZm9yZXN0PykKLSAgJChlcnJvciBCdWlsZCBmcm9tIHRvcC1sZXZlbCBNYWtlZmlsZSBpbnN0ZWFkKQotZW5kaWYKLQotYWxsOgotCUAkKE1BS0UpIC1mICQodG9wX2xldmVsX21ha2VmaWxlKSAkKHN1YnN5c3RlbV9uYW1lKQpkaWZmIC0tZ2l0IGEvbmJwcm9qZWN0L2ZpbmRidWdzLnNldHRpbmdzIGIvbmJwcm9qZWN0L2ZpbmRidWdzLnNldHRpbmdzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhNWQ3NjMxLi4wMDAwMDAwCi0tLSBhL25icHJvamVjdC9maW5kYnVncy5zZXR0aW5ncworKysgL2Rldi9udWxsCkBAIC0xLDcyICswLDAgQEAKLSNGaW5kQnVncyBVc2VyIFByZWZlcmVuY2VzCi0jVHVlIEp1biAzMCAxODozMzoxMSBQRFQgMjAwOQotZGV0ZWN0b3JBYm5vcm1hbEZpbmFsbHlCbG9ja1JldHVybj1BYm5vcm1hbEZpbmFsbHlCbG9ja1JldHVybnxmYWxzZQotZGV0ZWN0b3JBYnN0cmFjdENsYXNzRW1wdHlNZXRob2RzPUFic3RyYWN0Q2xhc3NFbXB0eU1ldGhvZHN8ZmFsc2UKLWRldGVjdG9yQWJzdHJhY3RPdmVycmlkZGVuTWV0aG9kPUFic3RyYWN0T3ZlcnJpZGRlbk1ldGhvZHxmYWxzZQotZGV0ZWN0b3JBcnJheUJhc2VkQ29sbGVjdGlvbnM9QXJyYXlCYXNlZENvbGxlY3Rpb25zfGZhbHNlCi1kZXRlY3RvckFycmF5V3JhcHBlZENhbGxCeVJlZmVyZW5jZT1BcnJheVdyYXBwZWRDYWxsQnlSZWZlcmVuY2V8ZmFsc2UKLWRldGVjdG9yQmxvYXRlZEFzc2lnbm1lbnRTY29wZT1CbG9hdGVkQXNzaWdubWVudFNjb3BlfGZhbHNlCi1kZXRlY3RvckJsb2F0ZWRTeW5jaHJvbml6ZWRCbG9jaz1CbG9hdGVkU3luY2hyb25pemVkQmxvY2t8ZmFsc2UKLWRldGVjdG9yQ2xhc3NFbnZ5PUNsYXNzRW52eXxmYWxzZQotZGV0ZWN0b3JDb2xsZWN0U3RhdGlzdGljcz1Db2xsZWN0U3RhdGlzdGljc3xmYWxzZQotZGV0ZWN0b3JDb25mdXNpbmdBdXRvYm94ZWRPdmVybG9hZGluZz1Db25mdXNpbmdBdXRvYm94ZWRPdmVybG9hZGluZ3xmYWxzZQotZGV0ZWN0b3JDb25zdGFudExpc3RJbmRleD1Db25zdGFudExpc3RJbmRleHxmYWxzZQotZGV0ZWN0b3JDb3BpZWRPdmVycmlkZGVuTWV0aG9kPUNvcGllZE92ZXJyaWRkZW5NZXRob2R8ZmFsc2UKLWRldGVjdG9yQ3VzdG9tQnVpbHRYTUw9Q3VzdG9tQnVpbHRYTUx8ZmFsc2UKLWRldGVjdG9yQ3ljbG9tYXRpY0NvbXBsZXhpdHk9Q3ljbG9tYXRpY0NvbXBsZXhpdHl8ZmFsc2UKLWRldGVjdG9yRGF0ZUNvbXBhcmlzb249RGF0ZUNvbXBhcmlzb258ZmFsc2UKLWRldGVjdG9yRGVjbGFyZWRSdW50aW1lRXhjZXB0aW9uPURlY2xhcmVkUnVudGltZUV4Y2VwdGlvbnxmYWxzZQotZGV0ZWN0b3JEZWxldGluZ1doaWxlSXRlcmF0aW5nPURlbGV0aW5nV2hpbGVJdGVyYXRpbmd8ZmFsc2UKLWRldGVjdG9yRHViaW91c0xpc3RDb2xsZWN0aW9uPUR1YmlvdXNMaXN0Q29sbGVjdGlvbnxmYWxzZQotZGV0ZWN0b3JGaWVsZENvdWxkQmVMb2NhbD1GaWVsZENvdWxkQmVMb2NhbHxmYWxzZQotZGV0ZWN0b3JGaW5hbFBhcmFtZXRlcnM9RmluYWxQYXJhbWV0ZXJzfGZhbHNlCi1kZXRlY3RvckZsb2F0aW5nUG9pbnRMb29wcz1GbG9hdGluZ1BvaW50TG9vcHN8ZmFsc2UKLWRldGVjdG9ySW5lZmZpY2llbnRTdHJpbmdCdWZmZXJpbmc9SW5lZmZpY2llbnRTdHJpbmdCdWZmZXJpbmd8ZmFsc2UKLWRldGVjdG9ySW5oZXJpdGFuY2VUeXBlQ2hlY2tpbmc9SW5oZXJpdGFuY2VUeXBlQ2hlY2tpbmd8ZmFsc2UKLWRldGVjdG9ySkRCQ1ZlbmRvclJlbGlhbmNlPUpEQkNWZW5kb3JSZWxpYW5jZXxmYWxzZQotZGV0ZWN0b3JMaXN0SW5kZXhlZEl0ZXJhdGluZz1MaXN0SW5kZXhlZEl0ZXJhdGluZ3xmYWxzZQotZGV0ZWN0b3JMaXRlcmFsU3RyaW5nQ29tcGFyaXNvbj1MaXRlcmFsU3RyaW5nQ29tcGFyaXNvbnxmYWxzZQotZGV0ZWN0b3JMb2NhbFN5bmNocm9uaXplZENvbGxlY3Rpb249TG9jYWxTeW5jaHJvbml6ZWRDb2xsZWN0aW9ufGZhbHNlCi1kZXRlY3Rvckxvc3RFeGNlcHRpb25TdGFja1RyYWNlPUxvc3RFeGNlcHRpb25TdGFja1RyYWNlfGZhbHNlCi1kZXRlY3Rvck1hbnVhbEFycmF5Q29weT1NYW51YWxBcnJheUNvcHl8ZmFsc2UKLWRldGVjdG9yTWV0aG9kUmV0dXJuc0NvbnN0YW50PU1ldGhvZFJldHVybnNDb25zdGFudHxmYWxzZQotZGV0ZWN0b3JOZWVkbGVzc0F1dG9ib3hpbmc9TmVlZGxlc3NBdXRvYm94aW5nfGZhbHNlCi1kZXRlY3Rvck5lZWRsZXNzQ3VzdG9tU2VyaWFsaXphdGlvbj1OZWVkbGVzc0N1c3RvbVNlcmlhbGl6YXRpb258ZmFsc2UKLWRldGVjdG9yTmVlZGxlc3NJbnN0YW5jZVJldHJpZXZhbD1OZWVkbGVzc0luc3RhbmNlUmV0cmlldmFsfGZhbHNlCi1kZXRlY3Rvck5lZWRsZXNzTWVtYmVyQ29sbGVjdGlvblN5bmNocm9uaXphdGlvbj1OZWVkbGVzc01lbWJlckNvbGxlY3Rpb25TeW5jaHJvbml6YXRpb258ZmFsc2UKLWRldGVjdG9yTm9uQ29sbGVjdGlvbk1ldGhvZFVzZT1Ob25Db2xsZWN0aW9uTWV0aG9kVXNlfGZhbHNlCi1kZXRlY3Rvck5vbk93bmVkU3luY2hyb25pemF0aW9uPU5vbk93bmVkU3luY2hyb25pemF0aW9ufGZhbHNlCi1kZXRlY3Rvck5vblJlY3ljbGVhYmxlVGFnbGlicz1Ob25SZWN5Y2xlYWJsZVRhZ2xpYnN8ZmFsc2UKLWRldGVjdG9yT3JwaGFuZWRET01Ob2RlPU9ycGhhbmVkRE9NTm9kZXxmYWxzZQotZGV0ZWN0b3JPdmVybHlDb25jcmV0ZVBhcmFtZXRlcj1PdmVybHlDb25jcmV0ZVBhcmFtZXRlcnxmYWxzZQotZGV0ZWN0b3JQYXJhbGxlbExpc3RzPVBhcmFsbGVsTGlzdHN8ZmFsc2UKLWRldGVjdG9yUGFydGlhbGx5Q29uc3RydWN0ZWRPYmplY3RBY2Nlc3M9UGFydGlhbGx5Q29uc3RydWN0ZWRPYmplY3RBY2Nlc3N8ZmFsc2UKLWRldGVjdG9yUG9zc2libGVJbmNvbXBsZXRlU2VyaWFsaXphdGlvbj1Qb3NzaWJsZUluY29tcGxldGVTZXJpYWxpemF0aW9ufGZhbHNlCi1kZXRlY3RvclBvc3NpYmxlTWVtb3J5QmxvYXQ9UG9zc2libGVNZW1vcnlCbG9hdHxmYWxzZQotZGV0ZWN0b3JQb3NzaWJseVJlZHVuZGFudE1ldGhvZENhbGxzPVBvc3NpYmx5UmVkdW5kYW50TWV0aG9kQ2FsbHN8ZmFsc2UKLWRldGVjdG9yU1FMSW5Mb29wPVNRTEluTG9vcHxmYWxzZQotZGV0ZWN0b3JTZWN0aW9uNTA4Q29tcGxpYW5jZT1TZWN0aW9uNTA4Q29tcGxpYW5jZXxmYWxzZQotZGV0ZWN0b3JTaWxseW5lc3NQb3RQb3Vycmk9U2lsbHluZXNzUG90UG91cnJpfGZhbHNlCi1kZXRlY3RvclNsb3BweUNsYXNzUmVmbGVjdGlvbj1TbG9wcHlDbGFzc1JlZmxlY3Rpb258ZmFsc2UKLWRldGVjdG9yU2x1Z2dpc2hHdWk9U2x1Z2dpc2hHdWl8ZmFsc2UKLWRldGVjdG9yU3BvaWxlZENoaWxkSW50ZXJmYWNlSW1wbGVtZW50b3I9U3BvaWxlZENoaWxkSW50ZXJmYWNlSW1wbGVtZW50b3J8ZmFsc2UKLWRldGVjdG9yU3B1cmlvdXNUaHJlYWRTdGF0ZXM9U3B1cmlvdXNUaHJlYWRTdGF0ZXN8ZmFsc2UKLWRldGVjdG9yU3RhdGljQXJyYXlDcmVhdGVkSW5NZXRob2Q9U3RhdGljQXJyYXlDcmVhdGVkSW5NZXRob2R8ZmFsc2UKLWRldGVjdG9yU3RhdGljTWV0aG9kSW5zdGFuY2VJbnZvY2F0aW9uPVN0YXRpY01ldGhvZEluc3RhbmNlSW52b2NhdGlvbnxmYWxzZQotZGV0ZWN0b3JTdXNwaWNpb3VzQ29tcGFyYXRvclJldHVyblZhbHVlcz1TdXNwaWNpb3VzQ29tcGFyYXRvclJldHVyblZhbHVlc3xmYWxzZQotZGV0ZWN0b3JTdXNwaWNpb3VzSkRLVmVyc2lvblVzZT1TdXNwaWNpb3VzSkRLVmVyc2lvblVzZXxmYWxzZQotZGV0ZWN0b3JTdXNwaWNpb3VzV2FpdE9uQ29uY3VycmVudE9iamVjdD1TdXNwaWNpb3VzV2FpdE9uQ29uY3VycmVudE9iamVjdHxmYWxzZQotZGV0ZWN0b3JTeW5jQ29sbGVjdGlvbkl0ZXJhdG9ycz1TeW5jQ29sbGVjdGlvbkl0ZXJhdG9yc3xmYWxzZQotZGV0ZWN0b3JUYWlsUmVjdXJzaW9uPVRhaWxSZWN1cnNpb258ZmFsc2UKLWRldGVjdG9yVW5uZWNlc3NhcnlTdG9yZUJlZm9yZVJldHVybj1Vbm5lY2Vzc2FyeVN0b3JlQmVmb3JlUmV0dXJufGZhbHNlCi1kZXRlY3RvclVucmVsYXRlZENvbGxlY3Rpb25Db250ZW50cz1VbnJlbGF0ZWRDb2xsZWN0aW9uQ29udGVudHN8ZmFsc2UKLWRldGVjdG9yVW5yZWxhdGVkUmV0dXJuVmFsdWVzPVVucmVsYXRlZFJldHVyblZhbHVlc3xmYWxzZQotZGV0ZWN0b3JVc2VBZGRBbGw9VXNlQWRkQWxsfGZhbHNlCi1kZXRlY3RvclVzZUNoYXJhY3RlclBhcmFtZXRlcml6ZWRNZXRob2Q9VXNlQ2hhcmFjdGVyUGFyYW1ldGVyaXplZE1ldGhvZHxmYWxzZQotZGV0ZWN0b3JVc2VFbnVtQ29sbGVjdGlvbnM9VXNlRW51bUNvbGxlY3Rpb25zfGZhbHNlCi1kZXRlY3RvclVzZVNwbGl0PVVzZVNwbGl0fGZhbHNlCi1kZXRlY3RvclVzZVRvQXJyYXk9VXNlVG9BcnJheXxmYWxzZQotZGV0ZWN0b3JfdGhyZXNob2xkPTIKLWVmZm9ydD1kZWZhdWx0Ci1maWx0ZXJfc2V0dGluZ3M9TWVkaXVtfEJBRF9QUkFDVElDRSxDT1JSRUNUTkVTUyxJMThOLE1BTElDSU9VU19DT0RFLE1UX0NPUlJFQ1RORVNTLFBFUkZPUk1BTkNFLFNFQ1VSSVRZLFNUWUxFfGZhbHNlCi1maWx0ZXJfc2V0dGluZ3NfbmVnPXwKZGlmZiAtLWdpdCBhL25icHJvamVjdC9wcm9qZWN0LnhtbCBiL25icHJvamVjdC9wcm9qZWN0LnhtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNGQzMzIyYy4uMDAwMDAwMAotLS0gYS9uYnByb2plY3QvcHJvamVjdC54bWwKKysrIC9kZXYvbnVsbApAQCAtMSw2OCArMCwwIEBACi08P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJVVEYtOCI/PgotPHByb2plY3QgeG1sbnM9Imh0dHA6Ly93d3cubmV0YmVhbnMub3JnL25zL3Byb2plY3QvMSI+Ci0gICAgPHR5cGU+b3JnLm5ldGJlYW5zLm1vZHVsZXMuYW50LmZyZWVmb3JtPC90eXBlPgotICAgIDxjb25maWd1cmF0aW9uPgotICAgICAgICA8Z2VuZXJhbC1kYXRhIHhtbG5zPSJodHRwOi8vd3d3Lm5ldGJlYW5zLm9yZy9ucy9mcmVlZm9ybS1wcm9qZWN0LzEiPgotICAgICAgICAgICAgPG5hbWU+amF4cDwvbmFtZT4KLSAgICAgICAgPC9nZW5lcmFsLWRhdGE+Ci0gICAgICAgIDxnZW5lcmFsLWRhdGEgeG1sbnM9Imh0dHA6Ly93d3cubmV0YmVhbnMub3JnL25zL2ZyZWVmb3JtLXByb2plY3QvMiI+Ci0gICAgICAgICAgICA8IS0tIERvIG5vdCB1c2UgUHJvamVjdCBQcm9wZXJ0aWVzIGN1c3RvbWl6ZXIgd2hlbiBlZGl0aW5nIHRoaXMgZmlsZSBtYW51YWxseS4gLS0+Ci0gICAgICAgICAgICA8bmFtZT5qYXhwPC9uYW1lPgotICAgICAgICAgICAgPHByb3BlcnRpZXMvPgotICAgICAgICAgICAgPGZvbGRlcnM+Ci0gICAgICAgICAgICAgICAgPHNvdXJjZS1mb2xkZXI+Ci0gICAgICAgICAgICAgICAgICAgIDxsYWJlbD5qYXhwPC9sYWJlbD4KLSAgICAgICAgICAgICAgICAgICAgPGxvY2F0aW9uPi48L2xvY2F0aW9uPgotICAgICAgICAgICAgICAgICAgICA8ZW5jb2Rpbmc+VVRGLTg8L2VuY29kaW5nPgotICAgICAgICAgICAgICAgIDwvc291cmNlLWZvbGRlcj4KLSAgICAgICAgICAgICAgICA8c291cmNlLWZvbGRlcj4KLSAgICAgICAgICAgICAgICAgICAgPGxhYmVsPnNyYzwvbGFiZWw+Ci0gICAgICAgICAgICAgICAgICAgIDx0eXBlPmphdmE8L3R5cGU+Ci0gICAgICAgICAgICAgICAgICAgIDxsb2NhdGlvbj5zcmM8L2xvY2F0aW9uPgotICAgICAgICAgICAgICAgICAgICA8ZW5jb2Rpbmc+VVRGLTg8L2VuY29kaW5nPgotICAgICAgICAgICAgICAgIDwvc291cmNlLWZvbGRlcj4KLSAgICAgICAgICAgIDwvZm9sZGVycz4KLSAgICAgICAgICAgIDxpZGUtYWN0aW9ucz4KLSAgICAgICAgICAgICAgICA8YWN0aW9uIG5hbWU9ImJ1aWxkIj4KLSAgICAgICAgICAgICAgICAgICAgPHRhcmdldD5idWlsZDwvdGFyZ2V0PgotICAgICAgICAgICAgICAgIDwvYWN0aW9uPgotICAgICAgICAgICAgICAgIDxhY3Rpb24gbmFtZT0iY2xlYW4iPgotICAgICAgICAgICAgICAgICAgICA8dGFyZ2V0PmNsZWFuPC90YXJnZXQ+Ci0gICAgICAgICAgICAgICAgPC9hY3Rpb24+Ci0gICAgICAgICAgICAgICAgPGFjdGlvbiBuYW1lPSJyZWJ1aWxkIj4KLSAgICAgICAgICAgICAgICAgICAgPHRhcmdldD5jbGVhbjwvdGFyZ2V0PgotICAgICAgICAgICAgICAgICAgICA8dGFyZ2V0PmJ1aWxkPC90YXJnZXQ+Ci0gICAgICAgICAgICAgICAgPC9hY3Rpb24+Ci0gICAgICAgICAgICAgICAgPGFjdGlvbiBuYW1lPSJqYXZhZG9jIj4KLSAgICAgICAgICAgICAgICAgICAgPHRhcmdldD5qYXZhZG9jLW5iPC90YXJnZXQ+Ci0gICAgICAgICAgICAgICAgPC9hY3Rpb24+Ci0gICAgICAgICAgICA8L2lkZS1hY3Rpb25zPgotICAgICAgICAgICAgPHZpZXc+Ci0gICAgICAgICAgICAgICAgPGl0ZW1zPgotICAgICAgICAgICAgICAgICAgICA8c291cmNlLWZvbGRlciBzdHlsZT0icGFja2FnZXMiPgotICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsPnNyYzwvbGFiZWw+Ci0gICAgICAgICAgICAgICAgICAgICAgICA8bG9jYXRpb24+c3JjPC9sb2NhdGlvbj4KLSAgICAgICAgICAgICAgICAgICAgPC9zb3VyY2UtZm9sZGVyPgotICAgICAgICAgICAgICAgICAgICA8c291cmNlLWZpbGU+Ci0gICAgICAgICAgICAgICAgICAgICAgICA8bG9jYXRpb24+YnVpbGQueG1sPC9sb2NhdGlvbj4KLSAgICAgICAgICAgICAgICAgICAgPC9zb3VyY2UtZmlsZT4KLSAgICAgICAgICAgICAgICA8L2l0ZW1zPgotICAgICAgICAgICAgICAgIDxjb250ZXh0LW1lbnU+Ci0gICAgICAgICAgICAgICAgICAgIDxpZGUtYWN0aW9uIG5hbWU9ImJ1aWxkIi8+Ci0gICAgICAgICAgICAgICAgICAgIDxpZGUtYWN0aW9uIG5hbWU9InJlYnVpbGQiLz4KLSAgICAgICAgICAgICAgICAgICAgPGlkZS1hY3Rpb24gbmFtZT0iY2xlYW4iLz4KLSAgICAgICAgICAgICAgICAgICAgPGlkZS1hY3Rpb24gbmFtZT0iamF2YWRvYyIvPgotICAgICAgICAgICAgICAgIDwvY29udGV4dC1tZW51PgotICAgICAgICAgICAgPC92aWV3PgotICAgICAgICAgICAgPHN1YnByb2plY3RzLz4KLSAgICAgICAgPC9nZW5lcmFsLWRhdGE+Ci0gICAgICAgIDxqYXZhLWRhdGEgeG1sbnM9Imh0dHA6Ly93d3cubmV0YmVhbnMub3JnL25zL2ZyZWVmb3JtLXByb2plY3QtamF2YS8xIj4KLSAgICAgICAgICAgIDxjb21waWxhdGlvbi11bml0PgotICAgICAgICAgICAgICAgIDxwYWNrYWdlLXJvb3Q+c3JjPC9wYWNrYWdlLXJvb3Q+Ci0gICAgICAgICAgICA8L2NvbXBpbGF0aW9uLXVuaXQ+Ci0gICAgICAgIDwvamF2YS1kYXRhPgotICAgICAgICA8cHJlZmVyZW5jZXMgeG1sbnM9Imh0dHA6Ly93d3cubmV0YmVhbnMub3JnL25zL2F1eGlsaWFyeS1jb25maWd1cmF0aW9uLXByZWZlcmVuY2VzLzEiPgotICAgICAgICAgICAgPG1vZHVsZSBuYW1lPSJvcmctbmV0YmVhbnMtbW9kdWxlcy1lZGl0b3ItaW5kZW50Ii8+Ci0gICAgICAgIDwvcHJlZmVyZW5jZXM+Ci0gICAgPC9jb25maWd1cmF0aW9uPgotPC9wcm9qZWN0PgpkaWZmIC0tZ2l0IGEvbmJwcm9qZWN0L3NxZS5wcm9wZXJ0aWVzIGIvbmJwcm9qZWN0L3NxZS5wcm9wZXJ0aWVzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA5NzhlZjViLi4wMDAwMDAwCi0tLSBhL25icHJvamVjdC9zcWUucHJvcGVydGllcworKysgL2Rldi9udWxsCkBAIC0xLDIgKzAsMCBAQAotI1BhdGggdG8gRmluZGJ1Z3NTZXR0aW5nc0ZpbGUgKHJlbGF0aXZlKQotZmluZGJ1Z3Muc2V0dGluZ3MuZmlsZT1maW5kYnVncy5zZXR0aW5ncwpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vamF2YV9jdXAvaW50ZXJuYWwvcnVudGltZS9TY2FubmVyLmphdmEgYi9zcmMvY29tL3N1bi9qYXZhX2N1cC9pbnRlcm5hbC9ydW50aW1lL1NjYW5uZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYTM5MDY4OC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9qYXZhX2N1cC9pbnRlcm5hbC9ydW50aW1lL1NjYW5uZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQ1ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDMsIDIwMDUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lOwotCi0vKioKLSAqIERlZmluZXMgdGhlIFNjYW5uZXIgaW50ZXJmYWNlLCB3aGljaCBDVVAgdXNlcyBpbiB0aGUgZGVmYXVsdAotICogaW1wbGVtZW50YXRpb24gb2YgPGNvZGU+bHJfcGFyc2VyLnNjYW4oKTwvY29kZT4uICBJbnRlZ3JhdGlvbgotICogb2Ygc2Nhbm5lcnMgaW1wbGVtZW50aW5nIDxjb2RlPlNjYW5uZXI8L2NvZGU+IGlzIGZhY2lsaXRhdGVkLgotICoKLSAqIEBhdXRob3IgRGF2aWQgTWFjTWFob24gPGRhdmlkbUBzbWFydHNjLmNvbT4KLSAqLwotCi0vKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0gIEludGVyZmFjZSBTY2FubmVyCi0KLSAgRGVjbGFyZXMgdGhlIG5leHRfdG9rZW4oKSBtZXRob2QgdGhhdCBzaG91bGQgYmUKLSAgaW1wbGVtZW50ZWQgYnkgc2Nhbm5lcnMuICBUaGlzIG1ldGhvZCBpcyB0eXBpY2FsbHkKLSAgY2FsbGVkIGJ5IGxyX3BhcnNlci5zY2FuKCkuCi0gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwotcHVibGljIGludGVyZmFjZSBTY2FubmVyIHsKLSAgICBwdWJsaWMgU3ltYm9sIG5leHRfdG9rZW4oKSB0aHJvd3MgamF2YS5sYW5nLkV4Y2VwdGlvbjsKLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL2phdmFfY3VwL2ludGVybmFsL3J1bnRpbWUvU3ltYm9sLmphdmEgYi9zcmMvY29tL3N1bi9qYXZhX2N1cC9pbnRlcm5hbC9ydW50aW1lL1N5bWJvbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkMjVlMmU4Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL2phdmFfY3VwL2ludGVybmFsL3J1bnRpbWUvU3ltYm9sLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMjkgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwMywgMjAwNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWU7Ci0KLS8qKgotICogRGVmaW5lcyB0aGUgU3ltYm9sIGNsYXNzLCB3aGljaCBpcyB1c2VkIHRvIHJlcHJlc2VudCBhbGwgdGVybWluYWxzCi0gKiBhbmQgbm9udGVybWluYWxzIHdoaWxlIHBhcnNpbmcuICBUaGUgbGV4ZXIgc2hvdWxkIHBhc3MgQ1VQIFN5bWJvbHMKLSAqIGFuZCBDVVAgcmV0dXJucyBhIFN5bWJvbC4KLSAqCi0gKiBAYXV0aG9yICBGcmFuayBGbGFubmVyeQotICovCi0KLS8qICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLSAgQ2xhc3MgU3ltYm9sCi0gIHdoYXQgdGhlIHBhcnNlciBleHBlY3RzIHRvIHJlY2VpdmUgZnJvbSB0aGUgbGV4ZXIuCi0gIHRoZSB0b2tlbiBpcyBpZGVudGlmaWVkIGFzIGZvbGxvd3M6Ci0gIHN5bTogICAgdGhlIHN5bWJvbCB0eXBlCi0gIHBhcnNlX3N0YXRlOiB0aGUgcGFyc2Ugc3RhdGUuCi0gIHZhbHVlOiAgaXMgdGhlIGxleGljYWwgdmFsdWUgb2YgdHlwZSBPYmplY3QKLSAgbGVmdCA6ICBpcyB0aGUgbGVmdCBwb3NpdGlvbiBpbiB0aGUgb3JpZ2luYWwgaW5wdXQgZmlsZQotICByaWdodDogIGlzIHRoZSByaWdodCBwb3NpdGlvbiBpbiB0aGUgb3JpZ2luYWwgaW5wdXQgZmlsZQotKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwotCi1wdWJsaWMgY2xhc3MgU3ltYm9sIHsKLQotLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLSAgQ29uc3RydWN0b3IgZm9yIGwsciB2YWx1ZXMKLSAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwotCi0gIHB1YmxpYyBTeW1ib2woaW50IGlkLCBpbnQgbCwgaW50IHIsIE9iamVjdCBvKSB7Ci0gICAgdGhpcyhpZCk7Ci0gICAgbGVmdCA9IGw7Ci0gICAgcmlnaHQgPSByOwotICAgIHZhbHVlID0gbzsKLSAgfQotCi0vKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgotICBDb25zdHJ1Y3RvciBmb3Igbm8gbCxyIHZhbHVlcwotKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi0KLSAgcHVibGljIFN5bWJvbChpbnQgaWQsIE9iamVjdCBvKSB7Ci0gICAgdGhpcyhpZCk7Ci0gICAgbGVmdCA9IC0xOwotICAgIHJpZ2h0ID0gLTE7Ci0gICAgdmFsdWUgPSBvOwotICB9Ci0KLS8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKgotICBDb25zdHJ1Y3RvciBmb3Igbm8gdmFsdWUKLSAgKioqKioqKioqKioqKioqKioqKioqKioqKioqLwotCi0gIHB1YmxpYyBTeW1ib2woaW50IHN5bV9udW0sIGludCBsLCBpbnQgcikgewotICAgIHN5bSA9IHN5bV9udW07Ci0gICAgbGVmdCA9IGw7Ci0gICAgcmlnaHQgPSByOwotICAgIHZhbHVlID0gbnVsbDsKLSAgfQotCi0vKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLSAgQ29uc3RydWN0b3IgZm9yIG5vIHZhbHVlIG9yIGwscgotKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi0KLSAgcHVibGljIFN5bWJvbChpbnQgc3ltX251bSkgewotICAgIHRoaXMoc3ltX251bSwgLTEpOwotICAgIGxlZnQgPSAtMTsKLSAgICByaWdodCA9IC0xOwotICAgIHZhbHVlID0gbnVsbDsKLSAgfQotCi0vKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLSAgQ29uc3RydWN0b3IgdG8gZ2l2ZSBhIHN0YXJ0IHN0YXRlCi0qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLSAgcHVibGljIFN5bWJvbChpbnQgc3ltX251bSwgaW50IHN0YXRlKQotICAgIHsKLSAgICAgIHN5bSA9IHN5bV9udW07Ci0gICAgICBwYXJzZV9zdGF0ZSA9IHN0YXRlOwotICAgIH0KLQotLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0KLSAgLyoqIFRoZSBzeW1ib2wgbnVtYmVyIG9mIHRoZSB0ZXJtaW5hbCBvciBub24gdGVybWluYWwgYmVpbmcgcmVwcmVzZW50ZWQgKi8KLSAgcHVibGljIGludCBzeW07Ci0KLSAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0KLSAgLyoqIFRoZSBwYXJzZSBzdGF0ZSB0byBiZSByZWNvcmRlZCBvbiB0aGUgcGFyc2Ugc3RhY2sgd2l0aCB0aGlzIHN5bWJvbC4KLSAgICogIFRoaXMgZmllbGQgaXMgZm9yIHRoZSBjb252ZW5pZW5jZSBvZiB0aGUgcGFyc2VyIGFuZCBzaG91bGRuJ3QgYmUKLSAgICogIG1vZGlmaWVkIGV4Y2VwdCBieSB0aGUgcGFyc2VyLgotICAgKi8KLSAgcHVibGljIGludCBwYXJzZV9zdGF0ZTsKLSAgLyoqIFRoaXMgYWxsb3dzIHVzIHRvIGNhdGNoIHNvbWUgZXJyb3JzIGNhdXNlZCBieSBzY2FubmVycyByZWN5Y2xpbmcKLSAgICogIHN5bWJvbHMuICBGb3IgdGhlIHVzZSBvZiB0aGUgcGFyc2VyIG9ubHkuIFtDU0EsIDIzLUp1bC0xOTk5XSAqLwotICBib29sZWFuIHVzZWRfYnlfcGFyc2VyID0gZmFsc2U7Ci0KLS8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0gIFRoZSBkYXRhIHBhc3NlZCB0byBwYXJzZXIKLSAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwotCi0gIHB1YmxpYyBpbnQgbGVmdCwgcmlnaHQ7Ci0gIHB1YmxpYyBPYmplY3QgdmFsdWU7Ci0KLSAgLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0gICAgUHJpbnRpbmcgdGhpcyB0b2tlbiBvdXQuIChPdmVycmlkZSBmb3IgcHJldHR5LXByaW50KS4KLSAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwotICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeyByZXR1cm4gIiMiK3N5bTsgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vamF2YV9jdXAvaW50ZXJuYWwvcnVudGltZS9scl9wYXJzZXIuamF2YSBiL3NyYy9jb20vc3VuL2phdmFfY3VwL2ludGVybmFsL3J1bnRpbWUvbHJfcGFyc2VyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGE5NGRmZjguLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vamF2YV9jdXAvaW50ZXJuYWwvcnVudGltZS9scl9wYXJzZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEyNTEgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwMywgMjAwNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotCi1wYWNrYWdlIGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZTsKLQotaW1wb3J0IGphdmEudXRpbC5TdGFjazsKLQotLyoqIFRoaXMgY2xhc3MgaW1wbGVtZW50cyBhIHNrZWxldG9uIHRhYmxlIGRyaXZlbiBMUiBwYXJzZXIuICBJbiBnZW5lcmFsLAotICogIExSIHBhcnNlcnMgYXJlIGEgZm9ybSBvZiBib3R0b20gdXAgc2hpZnQtcmVkdWNlIHBhcnNlcnMuICBTaGlmdC1yZWR1Y2UKLSAqICBwYXJzZXJzIGFjdCBieSBzaGlmdGluZyBpbnB1dCBvbnRvIGEgcGFyc2Ugc3RhY2sgdW50aWwgdGhlIFN5bWJvbHMKLSAqICBtYXRjaGluZyB0aGUgcmlnaHQgaGFuZCBzaWRlIG9mIGEgcHJvZHVjdGlvbiBhcHBlYXIgb24gdGhlIHRvcCBvZiB0aGUKLSAqICBzdGFjay4gIE9uY2UgdGhpcyBvY2N1cnMsIGEgcmVkdWNlIGlzIHBlcmZvcm1lZC4gIFRoaXMgaW52b2x2ZXMgcmVtb3ZpbmcKLSAqICB0aGUgU3ltYm9scyBjb3JyZXNwb25kaW5nIHRvIHRoZSByaWdodCBoYW5kIHNpZGUgb2YgdGhlIHByb2R1Y3Rpb24KLSAqICAodGhlIHNvIGNhbGxlZCAiaGFuZGxlIikgYW5kIHJlcGxhY2luZyB0aGVtIHdpdGggdGhlIG5vbi10ZXJtaW5hbCBmcm9tCi0gKiAgdGhlIGxlZnQgaGFuZCBzaWRlIG9mIHRoZSBwcm9kdWN0aW9uLiAgPHA+Ci0gKgotICogIFRvIGNvbnRyb2wgdGhlIGRlY2lzaW9uIG9mIHdoZXRoZXIgdG8gc2hpZnQgb3IgcmVkdWNlIGF0IGFueSBnaXZlbiBwb2ludCwKLSAqICB0aGUgcGFyc2VyIHVzZXMgYSBzdGF0ZSBtYWNoaW5lICh0aGUgInZpYWJsZSBwcmVmaXggcmVjb2duaXRpb24gbWFjaGluZSIKLSAqICBidWlsdCBieSB0aGUgcGFyc2VyIGdlbmVyYXRvcikuICBUaGUgY3VycmVudCBzdGF0ZSBvZiB0aGUgbWFjaGluZSBpcyBwbGFjZWQKLSAqICBvbiB0b3Agb2YgdGhlIHBhcnNlIHN0YWNrIChzdG9yZWQgYXMgcGFydCBvZiBhIFN5bWJvbCBvYmplY3QgcmVwcmVzZW50aW5nCi0gKiAgYSB0ZXJtaW5hbCBvciBub24gdGVybWluYWwpLiAgVGhlIHBhcnNlIGFjdGlvbiB0YWJsZSBpcyBjb25zdWx0ZWQKLSAqICAodXNpbmcgdGhlIGN1cnJlbnQgc3RhdGUgYW5kIHRoZSBjdXJyZW50IGxvb2thaGVhZCBTeW1ib2wgYXMgaW5kZXhlcykgdG8KLSAqICBkZXRlcm1pbmUgd2hldGhlciB0byBzaGlmdCBvciB0byByZWR1Y2UuICBXaGVuIHRoZSBwYXJzZXIgc2hpZnRzLCBpdAotICogIGNoYW5nZXMgdG8gYSBuZXcgc3RhdGUgYnkgcHVzaGluZyBhIG5ldyBTeW1ib2wgKGNvbnRhaW5pbmcgYSBuZXcgc3RhdGUpCi0gKiAgb250byB0aGUgc3RhY2suICBXaGVuIHRoZSBwYXJzZXIgcmVkdWNlcywgaXQgcG9wcyB0aGUgaGFuZGxlIChyaWdodCBoYW5kCi0gKiAgc2lkZSBvZiBhIHByb2R1Y3Rpb24pIG9mZiB0aGUgc3RhY2suICBUaGlzIGxlYXZlcyB0aGUgcGFyc2VyIGluIHRoZSBzdGF0ZQotICogIGl0IHdhcyBpbiBiZWZvcmUgYW55IG9mIHRob3NlIFN5bWJvbHMgd2VyZSBtYXRjaGVkLiAgTmV4dCB0aGUgcmVkdWNlLWdvdG8KLSAqICB0YWJsZSBpcyBjb25zdWx0ZWQgKHVzaW5nIHRoZSBuZXcgc3RhdGUgYW5kIGN1cnJlbnQgbG9va2FoZWFkIFN5bWJvbCBhcwotICogIGluZGV4ZXMpIHRvIGRldGVybWluZSBhIG5ldyBzdGF0ZSB0byBnbyB0by4gIFRoZSBwYXJzZXIgdGhlbiBzaGlmdHMgdG8KLSAqICB0aGlzIGdvdG8gc3RhdGUgYnkgcHVzaGluZyB0aGUgbGVmdCBoYW5kIHNpZGUgU3ltYm9sIG9mIHRoZSBwcm9kdWN0aW9uCi0gKiAgKGFsc28gY29udGFpbmluZyB0aGUgbmV3IHN0YXRlKSBvbnRvIHRoZSBzdGFjay48cD4KLSAqCi0gKiAgVGhpcyBjbGFzcyBhY3R1YWxseSBwcm92aWRlcyBmb3VyIExSIHBhcnNlcnMuICBUaGUgbWV0aG9kcyBwYXJzZSgpIGFuZAotICogIGRlYnVnX3BhcnNlKCkgcHJvdmlkZSB0d28gdmVyc2lvbnMgb2YgdGhlIG1haW4gcGFyc2VyICh0aGUgb25seSBkaWZmZXJlbmNlCi0gKiAgYmVpbmcgdGhhdCBkZWJ1Z19wYXJzZSgpIGVtaXRzIGRlYnVnZ2luZyB0cmFjZSBtZXNzYWdlcyBhcyBpdCBwYXJzZXMpLgotICogIEluIGFkZGl0aW9uIHRvIHRoZXNlIG1haW4gcGFyc2VycywgdGhlIGVycm9yIHJlY292ZXJ5IG1lY2hhbmlzbSB1c2VzIHR3bwotICogIG1vcmUuICBPbmUgb2YgdGhlc2UgaXMgdXNlZCB0byBzaW11bGF0ZSAicGFyc2luZyBhaGVhZCIgaW4gdGhlIGlucHV0Ci0gKiAgd2l0aG91dCBjYXJyeWluZyBvdXQgYWN0aW9ucyAodG8gdmVyaWZ5IHRoYXQgYSBwb3RlbnRpYWwgZXJyb3IgcmVjb3ZlcnkKLSAqICBoYXMgd29ya2VkKSwgYW5kIHRoZSBvdGhlciBpcyB1c2VkIHRvIHBhcnNlIHRocm91Z2ggYnVmZmVyZWQgInBhcnNlIGFoZWFkIgotICogIGlucHV0IGluIG9yZGVyIHRvIGV4ZWN1dGUgYWxsIGFjdGlvbnMgYW5kIHJlLXN5bmNocm9uaXplIHRoZSBhY3R1YWwgcGFyc2VyCi0gKiAgY29uZmlndXJhdGlvbi48cD4KLSAqCi0gKiAgVGhpcyBpcyBhbiBhYnN0cmFjdCBjbGFzcyB3aGljaCBpcyBub3JtYWxseSBmaWxsZWQgb3V0IGJ5IGEgc3ViY2xhc3MKLSAqICBnZW5lcmF0ZWQgYnkgdGhlIEphdmFDdXAgcGFyc2VyIGdlbmVyYXRvci4gIEluIGFkZGl0aW9uIHRvIHN1cHBseWluZwotICogIHRoZSBhY3R1YWwgcGFyc2UgdGFibGVzLCBnZW5lcmF0ZWQgY29kZSBhbHNvIHN1cHBsaWVzIG1ldGhvZHMgd2hpY2gKLSAqICBpbnZva2UgdmFyaW91cyBwaWVjZXMgb2YgdXNlciBzdXBwbGllZCBjb2RlLCBwcm92aWRlIGFjY2VzcyB0byBjZXJ0YWluCi0gKiAgc3BlY2lhbCBTeW1ib2xzIChlLmcuLCBFT0YgYW5kIGVycm9yKSwgZXRjLiAgU3BlY2lmaWNhbGx5LCB0aGUgZm9sbG93aW5nCi0gKiAgYWJzdHJhY3QgbWV0aG9kcyBhcmUgbm9ybWFsbHkgc3VwcGxpZWQgYnkgZ2VuZXJhdGVkIGNvZGU6Ci0gKiAgPGRsIGNvbXBhY3Q+Ci0gKiAgPGR0PiBzaG9ydFtdW10gcHJvZHVjdGlvbl90YWJsZSgpCi0gKiAgPGRkPiBQcm92aWRlcyBhIHJlZmVyZW5jZSB0byB0aGUgcHJvZHVjdGlvbiB0YWJsZSAoaW5kaWNhdGluZyB0aGUgaW5kZXggb2YKLSAqICAgICAgIHRoZSBsZWZ0IGhhbmQgc2lkZSBub24gdGVybWluYWwgYW5kIHRoZSBsZW5ndGggb2YgdGhlIHJpZ2h0IGhhbmQgc2lkZQotICogICAgICAgZm9yIGVhY2ggcHJvZHVjdGlvbiBpbiB0aGUgZ3JhbW1hcikuCi0gKiAgPGR0PiBzaG9ydFtdW10gYWN0aW9uX3RhYmxlKCkKLSAqICA8ZGQ+IFByb3ZpZGVzIGEgcmVmZXJlbmNlIHRvIHRoZSBwYXJzZSBhY3Rpb24gdGFibGUuCi0gKiAgPGR0PiBzaG9ydFtdW10gcmVkdWNlX3RhYmxlKCkKLSAqICA8ZGQ+IFByb3ZpZGVzIGEgcmVmZXJlbmNlIHRvIHRoZSByZWR1Y2UtZ290byB0YWJsZS4KLSAqICA8ZHQ+IGludCBzdGFydF9zdGF0ZSgpCi0gKiAgPGRkPiBJbmRpY2F0ZXMgdGhlIGluZGV4IG9mIHRoZSBzdGFydCBzdGF0ZS4KLSAqICA8ZHQ+IGludCBzdGFydF9wcm9kdWN0aW9uKCkKLSAqICA8ZGQ+IEluZGljYXRlcyB0aGUgaW5kZXggb2YgdGhlIHN0YXJ0aW5nIHByb2R1Y3Rpb24uCi0gKiAgPGR0PiBpbnQgRU9GX3N5bSgpCi0gKiAgPGRkPiBJbmRpY2F0ZXMgdGhlIGluZGV4IG9mIHRoZSBFT0YgU3ltYm9sLgotICogIDxkdD4gaW50IGVycm9yX3N5bSgpCi0gKiAgPGRkPiBJbmRpY2F0ZXMgdGhlIGluZGV4IG9mIHRoZSBlcnJvciBTeW1ib2wuCi0gKiAgPGR0PiBTeW1ib2wgZG9fYWN0aW9uKCkKLSAqICA8ZGQ+IEV4ZWN1dGVzIGEgcGllY2Ugb2YgdXNlciBzdXBwbGllZCBhY3Rpb24gY29kZS4gIFRoaXMgYWx3YXlzIGNvbWVzIGF0Ci0gKiAgICAgICB0aGUgcG9pbnQgb2YgYSByZWR1Y2UgaW4gdGhlIHBhcnNlLCBzbyB0aGlzIGNvZGUgYWxzbyBhbGxvY2F0ZXMgYW5kCi0gKiAgICAgICBmaWxscyBpbiB0aGUgbGVmdCBoYW5kIHNpZGUgbm9uIHRlcm1pbmFsIFN5bWJvbCBvYmplY3QgdGhhdCBpcyB0byBiZQotICogICAgICAgcHVzaGVkIG9udG8gdGhlIHN0YWNrIGZvciB0aGUgcmVkdWNlLgotICogIDxkdD4gdm9pZCBpbml0X2FjdGlvbnMoKQotICogIDxkZD4gQ29kZSB0byBpbml0aWFsaXplIGEgc3BlY2lhbCBvYmplY3QgdGhhdCBlbmNhcHN1bGF0ZXMgdXNlciBzdXBwbGllZAotICogICAgICAgYWN0aW9ucyAodGhpcyBvYmplY3QgaXMgdXNlZCBieSBkb19hY3Rpb24oKSB0byBhY3R1YWxseSBjYXJyeSBvdXQgdGhlCi0gKiAgICAgICBhY3Rpb25zKS4KLSAqICA8L2RsPgotICoKLSAqICBJbiBhZGRpdGlvbiB0byB0aGVzZSByb3V0aW5lcyB0aGF0IDxpPm11c3Q8L2k+IGJlIHN1cHBsaWVkIGJ5IHRoZQotICogIGdlbmVyYXRlZCBzdWJjbGFzcyB0aGVyZSBhcmUgYWxzbyBhIHNlcmllcyBvZiByb3V0aW5lcyB0aGF0IDxpPm1heTwvaT4KLSAqICBiZSBzdXBwbGllZC4gIFRoZXNlIGluY2x1ZGU6Ci0gKiAgPGRsPgotICogIDxkdD4gU3ltYm9sIHNjYW4oKQotICogIDxkZD4gVXNlZCB0byBnZXQgdGhlIG5leHQgaW5wdXQgU3ltYm9sIGZyb20gdGhlIHNjYW5uZXIuCi0gKiAgPGR0PiBTY2FubmVyIGdldFNjYW5uZXIoKQotICogIDxkZD4gVXNlZCB0byBwcm92aWRlIGEgc2Nhbm5lciBmb3IgdGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gb2YKLSAqICAgICAgIHNjYW4oKS4KLSAqICA8ZHQ+IGludCBlcnJvcl9zeW5jX3NpemUoKQotICogIDxkZD4gVGhpcyBkZXRlcm1pbmVzIGhvdyBtYW55IFN5bWJvbHMgcGFzdCB0aGUgcG9pbnQgb2YgYW4gZXJyb3IKLSAqICAgICAgIG11c3QgYmUgcGFyc2VkIHdpdGhvdXQgZXJyb3IgaW4gb3JkZXIgdG8gY29uc2lkZXIgYSByZWNvdmVyeSB0bwotICogICAgICAgYmUgdmFsaWQuICBUaGlzIGRlZmF1bHRzIHRvIDMuICBWYWx1ZXMgbGVzcyB0aGFuIDIgYXJlIG5vdAotICogICAgICAgcmVjb21tZW5kZWQuCi0gKiAgPGR0PiB2b2lkIHJlcG9ydF9lcnJvcihTdHJpbmcgbWVzc2FnZSwgT2JqZWN0IGluZm8pCi0gKiAgPGRkPiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgdG8gcmVwb3J0IGFuIGVycm9yLiAgVGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24KLSAqICAgICAgIHNpbXBseSBwcmludHMgYSBtZXNzYWdlIHRvIFN5c3RlbS5lcnIgYW5kIHdoZXJlIHRoZSBlcnJvciBvY2N1cnJlZC4KLSAqICAgICAgIFRoaXMgbWV0aG9kIGlzIG9mdGVuIHJlcGxhY2VkIGluIG9yZGVyIHRvIHByb3ZpZGUgYSBtb3JlIHNvcGhpc3RpY2F0ZWQKLSAqICAgICAgIGVycm9yIHJlcG9ydGluZyBtZWNoYW5pc20uCi0gKiAgPGR0PiB2b2lkIHJlcG9ydF9mYXRhbF9lcnJvcihTdHJpbmcgbWVzc2FnZSwgT2JqZWN0IGluZm8pCi0gKiAgPGRkPiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgd2hlbiBhIGZhdGFsIGVycm9yIHRoYXQgY2Fubm90IGJlIHJlY292ZXJlZCBmcm9tCi0gKiAgICAgICBpcyBlbmNvdW50ZXJlZC4gIEluIHRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uLCBpdCBjYWxscwotICogICAgICAgcmVwb3J0X2Vycm9yKCkgdG8gZW1pdCBhIG1lc3NhZ2UsIHRoZW4gdGhyb3dzIGFuIGV4Y2VwdGlvbi4KLSAqICA8ZHQ+IHZvaWQgc3ludGF4X2Vycm9yKFN5bWJvbCBjdXJfdG9rZW4pCi0gKiAgPGRkPiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYXMgc29vbiBhcyBzeW50YXggZXJyb3IgaXMgZGV0ZWN0ZWQgKGJ1dAotICogICAgICAgYmVmb3JlIHJlY292ZXJ5IGlzIGF0dGVtcHRlZCkuICBJbiB0aGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBpdAotICogICAgICAgaW52b2tlczogcmVwb3J0X2Vycm9yKCJTeW50YXggZXJyb3IiLCBudWxsKTsKLSAqICA8ZHQ+IHZvaWQgdW5yZWNvdmVyZWRfc3ludGF4X2Vycm9yKFN5bWJvbCBjdXJfdG9rZW4pCi0gKiAgPGRkPiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgaWYgc3ludGF4IGVycm9yIHJlY292ZXJ5IGZhaWxzLiAgSW4gdGhlIGRlZmF1bHQKLSAqICAgICAgIGltcGxlbWVudGF0aW9uIGl0IGludm9rZXM6PGJyPgotICogICAgICAgICByZXBvcnRfZmF0YWxfZXJyb3IoIkNvdWxkbid0IHJlcGFpciBhbmQgY29udGludWUgcGFyc2UiLCBudWxsKTsKLSAqICA8L2RsPgotICoKLSAqIEBzZWUgICAgIGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wKLSAqIEBzZWUgICAgIGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wKLSAqIEBzZWUgICAgIGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS52aXJ0dWFsX3BhcnNlX3N0YWNrCi0gKiBAYXV0aG9yICBGcmFuayBGbGFubmVyeQotICovCi0KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBscl9wYXJzZXIgewotCi0gIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwotICAvKi0tLSBDb25zdHJ1Y3RvcihzKSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KLSAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCi0KLSAgLyoqIFNpbXBsZSBjb25zdHJ1Y3Rvci4gKi8KLSAgcHVibGljIGxyX3BhcnNlcigpCi0gICAgewotICAgICAgLyogbm90aGluZyB0byBkbyBoZXJlICovCi0gICAgfQotCi0gIC8qKiBDb25zdHJ1Y3RvciB0aGF0IHNldHMgdGhlIGRlZmF1bHQgc2Nhbm5lci4gW0NTQS9kYXZpZG1dICovCi0gIHB1YmxpYyBscl9wYXJzZXIoU2Nhbm5lciBzKSB7Ci0gICAgdGhpcygpOyAvKiBpbiBjYXNlIGRlZmF1bHQgY29uc3RydWN0b3Igc29tZWRheSBkb2VzIHNvbWV0aGluZyAqLwotICAgIHNldFNjYW5uZXIocyk7Ci0gIH0KLQotICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KLSAgLyotLS0gKEFjY2VzcyB0bykgU3RhdGljIChDbGFzcykgVmFyaWFibGVzIC0tLS0tLS0tLS0tLS0tLS0tLSovCi0gIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwotCi0gIC8qKiBUaGUgZGVmYXVsdCBudW1iZXIgb2YgU3ltYm9scyBhZnRlciBhbiBlcnJvciB3ZSBtdWNoIG1hdGNoIHRvIGNvbnNpZGVyCi0gICAqICBpdCByZWNvdmVyZWQgZnJvbS4KLSAgICovCi0gIHByb3RlY3RlZCBmaW5hbCBzdGF0aWMgaW50IF9lcnJvcl9zeW5jX3NpemUgPSAzOwotCi0gIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotCi0gIC8qKiBUaGUgbnVtYmVyIG9mIFN5bWJvbHMgYWZ0ZXIgYW4gZXJyb3Igd2UgbXVjaCBtYXRjaCB0byBjb25zaWRlciBpdAotICAgKiAgcmVjb3ZlcmVkIGZyb20uCi0gICAqLwotICBwcm90ZWN0ZWQgaW50IGVycm9yX3N5bmNfc2l6ZSgpIHtyZXR1cm4gX2Vycm9yX3N5bmNfc2l6ZTsgfQotCi0gIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwotICAvKi0tLSAoQWNjZXNzIHRvKSBJbnN0YW5jZSBWYXJpYWJsZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KLSAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCi0KLSAgLyoqIFRhYmxlIG9mIHByb2R1Y3Rpb24gaW5mb3JtYXRpb24gKHN1cHBsaWVkIGJ5IGdlbmVyYXRlZCBzdWJjbGFzcykuCi0gICAqICBUaGlzIHRhYmxlIGNvbnRhaW5zIG9uZSBlbnRyeSBwZXIgcHJvZHVjdGlvbiBhbmQgaXMgaW5kZXhlZCBieQotICAgKiAgdGhlIG5lZ2F0aXZlLWVuY29kZWQgdmFsdWVzIChyZWR1Y2UgYWN0aW9ucykgaW4gdGhlIGFjdGlvbl90YWJsZS4KLSAgICogIEVhY2ggZW50cnkgaGFzIHR3byBwYXJ0cywgdGhlIGluZGV4IG9mIHRoZSBub24tdGVybWluYWwgb24gdGhlCi0gICAqICBsZWZ0IGhhbmQgc2lkZSBvZiB0aGUgcHJvZHVjdGlvbiwgYW5kIHRoZSBudW1iZXIgb2YgU3ltYm9scwotICAgKiAgb24gdGhlIHJpZ2h0IGhhbmQgc2lkZS4KLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBzaG9ydFtdW10gcHJvZHVjdGlvbl90YWJsZSgpOwotCi0gIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotCi0gIC8qKiBUaGUgYWN0aW9uIHRhYmxlIChzdXBwbGllZCBieSBnZW5lcmF0ZWQgc3ViY2xhc3MpLiAgVGhpcyB0YWJsZSBpcwotICAgKiAgaW5kZXhlZCBieSBzdGF0ZSBhbmQgdGVybWluYWwgbnVtYmVyIGluZGljYXRpbmcgd2hhdCBhY3Rpb24gaXMgdG8KLSAgICogIGJlIHRha2VuIHdoZW4gdGhlIHBhcnNlciBpcyBpbiB0aGUgZ2l2ZW4gc3RhdGUgKGkuZS4sIHRoZSBnaXZlbiBzdGF0ZQotICAgKiAgaXMgb24gdG9wIG9mIHRoZSBzdGFjaykgYW5kIHRoZSBnaXZlbiB0ZXJtaW5hbCBpcyBuZXh0IG9uIHRoZSBpbnB1dC4KLSAgICogIFN0YXRlcyBhcmUgaW5kZXhlZCB1c2luZyB0aGUgZmlyc3QgZGltZW5zaW9uLCBob3dldmVyLCB0aGUgZW50cmllcyBmb3IKLSAgICogIGEgZ2l2ZW4gc3RhdGUgYXJlIGNvbXBhY3RlZCBhbmQgc3RvcmVkIGluIGFkamFjZW50IGluZGV4LCB2YWx1ZSBwYWlycwotICAgKiAgd2hpY2ggYXJlIHNlYXJjaGVkIGZvciByYXRoZXIgdGhhbiBhY2Nlc3NlZCBkaXJlY3RseSAoc2VlIGdldF9hY3Rpb24oKSkuCi0gICAqICBUaGUgYWN0aW9ucyBzdG9yZWQgaW4gdGhlIHRhYmxlIHdpbGwgYmUgZWl0aGVyIHNoaWZ0cywgcmVkdWNlcywgb3IKLSAgICogIGVycm9ycy4gIFNoaWZ0cyBhcmUgZW5jb2RlZCBhcyBwb3NpdGl2ZSB2YWx1ZXMgKG9uZSBncmVhdGVyIHRoYW4gdGhlCi0gICAqICBzdGF0ZSBzaGlmdGVkIHRvKS4gIFJlZHVjZXMgYXJlIGVuY29kZWQgYXMgbmVnYXRpdmUgdmFsdWVzIChvbmUgbGVzcwotICAgKiAgdGhhbiB0aGUgcHJvZHVjdGlvbiByZWR1Y2VkIGJ5KS4gIEVycm9yIGVudHJpZXMgYXJlIGRlbm90ZWQgYnkgemVyby4KLSAgICoKLSAgICogQHNlZSBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUubHJfcGFyc2VyI2dldF9hY3Rpb24KLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBzaG9ydFtdW10gYWN0aW9uX3RhYmxlKCk7Ci0KLSAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0KLSAgLyoqIFRoZSByZWR1Y2UtZ290byB0YWJsZSAoc3VwcGxpZWQgYnkgZ2VuZXJhdGVkIHN1YmNsYXNzKS4gIFRoaXMKLSAgICogIHRhYmxlIGlzIGluZGV4ZWQgYnkgc3RhdGUgYW5kIG5vbi10ZXJtaW5hbCBudW1iZXIgYW5kIGNvbnRhaW5zCi0gICAqICBzdGF0ZSBudW1iZXJzLiAgU3RhdGVzIGFyZSBpbmRleGVkIHVzaW5nIHRoZSBmaXJzdCBkaW1lbnNpb24sIGhvd2V2ZXIsCi0gICAqICB0aGUgZW50cmllcyBmb3IgYSBnaXZlbiBzdGF0ZSBhcmUgY29tcGFjdGVkIGFuZCBzdG9yZWQgaW4gYWRqYWNlbnQKLSAgICogIGluZGV4LCB2YWx1ZSBwYWlycyB3aGljaCBhcmUgc2VhcmNoZWQgZm9yIHJhdGhlciB0aGFuIGFjY2Vzc2VkCi0gICAqICBkaXJlY3RseSAoc2VlIGdldF9yZWR1Y2UoKSkuICBXaGVuIGEgcmVkdWNlIG9jY3VycywgdGhlIGhhbmRsZQotICAgKiAgKGNvcnJlc3BvbmRpbmcgdG8gdGhlIFJIUyBvZiB0aGUgbWF0Y2hlZCBwcm9kdWN0aW9uKSBpcyBwb3BwZWQgb2ZmCi0gICAqICB0aGUgc3RhY2suICBUaGUgbmV3IHRvcCBvZiBzdGFjayBpbmRpY2F0ZXMgYSBzdGF0ZS4gIFRoaXMgdGFibGUgaXMKLSAgICogIHRoZW4gaW5kZXhlZCBieSB0aGF0IHN0YXRlIGFuZCB0aGUgTEhTIG9mIHRoZSByZWR1Y2luZyBwcm9kdWN0aW9uIHRvCi0gICAqICBpbmRpY2F0ZSB3aGVyZSB0byAic2hpZnQiIHRvLgotICAgKgotICAgKiBAc2VlIGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5scl9wYXJzZXIjZ2V0X3JlZHVjZQotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IHNob3J0W11bXSByZWR1Y2VfdGFibGUoKTsKLQotICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuKi8KLQotICAvKiogVGhlIGluZGV4IG9mIHRoZSBzdGFydCBzdGF0ZSAoc3VwcGxpZWQgYnkgZ2VuZXJhdGVkIHN1YmNsYXNzKS4gKi8KLSAgcHVibGljIGFic3RyYWN0IGludCBzdGFydF9zdGF0ZSgpOwotCi0gIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotCi0gIC8qKiBUaGUgaW5kZXggb2YgdGhlIHN0YXJ0IHByb2R1Y3Rpb24gKHN1cHBsaWVkIGJ5IGdlbmVyYXRlZCBzdWJjbGFzcykuICovCi0gIHB1YmxpYyBhYnN0cmFjdCBpbnQgc3RhcnRfcHJvZHVjdGlvbigpOwotCi0gIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotCi0gIC8qKiBUaGUgaW5kZXggb2YgdGhlIGVuZCBvZiBmaWxlIHRlcm1pbmFsIFN5bWJvbCAoc3VwcGxpZWQgYnkgZ2VuZXJhdGVkCi0gICAqICBzdWJjbGFzcykuCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgaW50IEVPRl9zeW0oKTsKLQotICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuKi8KLQotICAvKiogVGhlIGluZGV4IG9mIHRoZSBzcGVjaWFsIGVycm9yIFN5bWJvbCAoc3VwcGxpZWQgYnkgZ2VuZXJhdGVkIHN1YmNsYXNzKS4gKi8KLSAgcHVibGljIGFic3RyYWN0IGludCBlcnJvcl9zeW0oKTsKLQotICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuKi8KLQotICAvKiogSW50ZXJuYWwgZmxhZyB0byBpbmRpY2F0ZSB3aGVuIHBhcnNlciBzaG91bGQgcXVpdC4gKi8KLSAgcHJvdGVjdGVkIGJvb2xlYW4gX2RvbmVfcGFyc2luZyA9IGZhbHNlOwotCi0gIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotCi0gIC8qKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgdG8gaW5kaWNhdGUgdGhhdCB0aGUgcGFyc2VyIHNob3VsZCBxdWl0LiAgVGhpcyBpcwotICAgKiAgbm9ybWFsbHkgY2FsbGVkIGJ5IGFuIGFjY2VwdCBhY3Rpb24sIGJ1dCBjYW4gYmUgdXNlZCB0byBjYW5jZWwgcGFyc2luZwotICAgKiAgZWFybHkgaW4gb3RoZXIgY2lyY3Vtc3RhbmNlcyBpZiBkZXNpcmVkLgotICAgKi8KLSAgcHVibGljIHZvaWQgZG9uZV9wYXJzaW5nKCkKLSAgICB7Ci0gICAgICBfZG9uZV9wYXJzaW5nID0gdHJ1ZTsKLSAgICB9Ci0KLSAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0gIC8qIEdsb2JhbCBwYXJzZSBzdGF0ZSBzaGFyZWQgYnkgcGFyc2UoKSwgZXJyb3IgcmVjb3ZlcnksIGFuZAotICAgKiBkZWJ1Z2dpbmcgcm91dGluZXMgKi8KLSAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0KLSAgLyoqIEluZGljYXRpb24gb2YgdGhlIGluZGV4IGZvciB0b3Agb2Ygc3RhY2sgKGZvciB1c2UgYnkgYWN0aW9ucykuICovCi0gIHByb3RlY3RlZCBpbnQgdG9zOwotCi0gIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotCi0gIC8qKiBUaGUgY3VycmVudCBsb29rYWhlYWQgU3ltYm9sLiAqLwotICBwcm90ZWN0ZWQgU3ltYm9sIGN1cl90b2tlbjsKLQotICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuKi8KLQotICAvKiogVGhlIHBhcnNlIHN0YWNrIGl0c2VsZi4gKi8KLSAgcHJvdGVjdGVkIFN0YWNrIHN0YWNrID0gbmV3IFN0YWNrKCk7Ci0KLSAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0KLSAgLyoqIERpcmVjdCByZWZlcmVuY2UgdG8gdGhlIHByb2R1Y3Rpb24gdGFibGUuICovCi0gIHByb3RlY3RlZCBzaG9ydFtdW10gcHJvZHVjdGlvbl90YWI7Ci0KLSAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0KLSAgLyoqIERpcmVjdCByZWZlcmVuY2UgdG8gdGhlIGFjdGlvbiB0YWJsZS4gKi8KLSAgcHJvdGVjdGVkIHNob3J0W11bXSBhY3Rpb25fdGFiOwotCi0gIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotCi0gIC8qKiBEaXJlY3QgcmVmZXJlbmNlIHRvIHRoZSByZWR1Y2UtZ290byB0YWJsZS4gKi8KLSAgcHJvdGVjdGVkIHNob3J0W11bXSByZWR1Y2VfdGFiOwotCi0gIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotCi0gIC8qKiBUaGlzIGlzIHRoZSBzY2FubmVyIG9iamVjdCB1c2VkIGJ5IHRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uCi0gICAqICBvZiBzY2FuKCkgdG8gZ2V0IFN5bWJvbHMuICBUbyBhdm9pZCBuYW1lIGNvbmZsaWN0cyB3aXRoIGV4aXN0aW5nCi0gICAqICBjb2RlLCB0aGlzIGZpZWxkIGlzIHByaXZhdGUuIFtDU0EvZGF2aWRtXSAqLwotICBwcml2YXRlIFNjYW5uZXIgX3NjYW5uZXI7Ci0KLSAgLyoqCi0gICAqIFNpbXBsZSBhY2Nlc3NvciBtZXRob2QgdG8gc2V0IHRoZSBkZWZhdWx0IHNjYW5uZXIuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRTY2FubmVyKFNjYW5uZXIgcykgeyBfc2Nhbm5lciA9IHM7IH0KLQotICAvKioKLSAgICogU2ltcGxlIGFjY2Vzc29yIG1ldGhvZCB0byBnZXQgdGhlIGRlZmF1bHQgc2Nhbm5lci4KLSAgICovCi0gIHB1YmxpYyBTY2FubmVyIGdldFNjYW5uZXIoKSB7IHJldHVybiBfc2Nhbm5lcjsgfQotCi0gIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwotICAvKi0tLSBHZW5lcmFsIE1ldGhvZHMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KLSAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCi0KLSAgLyoqIFBlcmZvcm0gYSBiaXQgb2YgdXNlciBzdXBwbGllZCBhY3Rpb24gY29kZSAoc3VwcGxpZWQgYnkgZ2VuZXJhdGVkCi0gICAqICBzdWJjbGFzcykuICBBY3Rpb25zIGFyZSBpbmRleGVkIGJ5IGFuIGludGVybmFsIGFjdGlvbiBudW1iZXIgYXNzaWduZWQKLSAgICogIGF0IHBhcnNlciBnZW5lcmF0aW9uIHRpbWUuCi0gICAqCi0gICAqIEBwYXJhbSBhY3RfbnVtICAgdGhlIGludGVybmFsIGluZGV4IG9mIHRoZSBhY3Rpb24gdG8gYmUgcGVyZm9ybWVkLgotICAgKiBAcGFyYW0gcGFyc2VyICAgIHRoZSBwYXJzZXIgb2JqZWN0IHdlIGFyZSBhY3RpbmcgZm9yLgotICAgKiBAcGFyYW0gc3RhY2sgICAgIHRoZSBwYXJzZSBzdGFjayBvZiB0aGF0IG9iamVjdC4KLSAgICogQHBhcmFtIHRvcCAgICAgICB0aGUgaW5kZXggb2YgdGhlIHRvcCBlbGVtZW50IG9mIHRoZSBwYXJzZSBzdGFjay4KLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBTeW1ib2wgZG9fYWN0aW9uKAotICAgIGludCAgICAgICBhY3RfbnVtLAotICAgIGxyX3BhcnNlciBwYXJzZXIsCi0gICAgU3RhY2sgICAgIHN0YWNrLAotICAgIGludCAgICAgICB0b3ApCi0gICAgdGhyb3dzIGphdmEubGFuZy5FeGNlcHRpb247Ci0KLSAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0KLSAgLyoqIFVzZXIgY29kZSBmb3IgaW5pdGlhbGl6YXRpb24gaW5zaWRlIHRoZSBwYXJzZXIuICBUeXBpY2FsbHkgdGhpcwotICAgKiAgaW5pdGlhbGl6ZXMgdGhlIHNjYW5uZXIuICBUaGlzIGlzIGNhbGxlZCBiZWZvcmUgdGhlIHBhcnNlciByZXF1ZXN0cwotICAgKiAgdGhlIGZpcnN0IFN5bWJvbC4gIEhlcmUgdGhpcyBpcyBqdXN0IGEgcGxhY2Vob2xkZXIgZm9yIHN1YmNsYXNzZXMgdGhhdAotICAgKiAgbWlnaHQgbmVlZCB0aGlzIGFuZCB3ZSBwZXJmb3JtIG5vIGFjdGlvbi4gICBUaGlzIG1ldGhvZCBpcyBub3JtYWxseQotICAgKiAgb3ZlcnJpZGRlbiBieSB0aGUgZ2VuZXJhdGVkIGNvZGUgdXNpbmcgdGhpcyBjb250ZW50cyBvZiB0aGUgImluaXQgd2l0aCIKLSAgICogIGNsYXVzZSBhcyBpdHMgYm9keS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHVzZXJfaW5pdCgpIHRocm93cyBqYXZhLmxhbmcuRXhjZXB0aW9uIHsgfQotCi0gIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotCi0gIC8qKiBJbml0aWFsaXplIHRoZSBhY3Rpb24gb2JqZWN0LiAgVGhpcyBpcyBjYWxsZWQgYmVmb3JlIHRoZSBwYXJzZXIgZG9lcwotICAgKiAgYW55IHBhcnNlIGFjdGlvbnMuIFRoaXMgaXMgZmlsbGVkIGluIGJ5IGdlbmVyYXRlZCBjb2RlIHRvIGNyZWF0ZQotICAgKiAgYW4gb2JqZWN0IHRoYXQgZW5jYXBzdWxhdGVzIGFsbCBhY3Rpb24gY29kZS4KLSAgICovCi0gIHByb3RlY3RlZCBhYnN0cmFjdCB2b2lkIGluaXRfYWN0aW9ucygpIHRocm93cyBqYXZhLmxhbmcuRXhjZXB0aW9uOwotCi0gIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotCi0gIC8qKiBHZXQgdGhlIG5leHQgU3ltYm9sIGZyb20gdGhlIGlucHV0IChzdXBwbGllZCBieSBnZW5lcmF0ZWQgc3ViY2xhc3MpLgotICAgKiAgT25jZSBlbmQgb2YgZmlsZSBoYXMgYmVlbiByZWFjaGVkLCBhbGwgc3Vic2VxdWVudCBjYWxscyB0byBzY2FuCi0gICAqICBzaG91bGQgcmV0dXJuIGFuIEVPRiBTeW1ib2wgKHdoaWNoIGlzIFN5bWJvbCBudW1iZXIgMCkuICBCeSBkZWZhdWx0Ci0gICAqICB0aGlzIG1ldGhvZCByZXR1cm5zIGdldFNjYW5uZXIoKS5uZXh0X3Rva2VuKCk7IHRoaXMgaW1wbGVtZW50YXRpb24KLSAgICogIGNhbiBiZSBvdmVycmlkZW4gYnkgdGhlIGdlbmVyYXRlZCBwYXJzZXIgdXNpbmcgdGhlIGNvZGUgZGVjbGFyZWQgaW4KLSAgICogIHRoZSAic2NhbiB3aXRoIiBjbGF1c2UuICBEbyBub3QgcmVjeWNsZSBvYmplY3RzOyBldmVyeSBjYWxsIHRvCi0gICAqICBzY2FuKCkgc2hvdWxkIHJldHVybiBhIGZyZXNoIG9iamVjdC4KLSAgICovCi0gIHB1YmxpYyBTeW1ib2wgc2NhbigpIHRocm93cyBqYXZhLmxhbmcuRXhjZXB0aW9uIHsKLSAgICByZXR1cm4gZ2V0U2Nhbm5lcigpLm5leHRfdG9rZW4oKTsKLSAgfQotCi0gIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotCi0gIC8qKiBSZXBvcnQgYSBmYXRhbCBlcnJvci4gIFRoaXMgbWV0aG9kIHRha2VzIGEgIG1lc3NhZ2Ugc3RyaW5nIGFuZCBhbgotICAgKiAgYWRkaXRpb25hbCBvYmplY3QgKHRvIGJlIHVzZWQgYnkgc3BlY2lhbGl6YXRpb25zIGltcGxlbWVudGVkIGluCi0gICAqICBzdWJjbGFzc2VzKS4gIEhlcmUgaW4gdGhlIGJhc2UgY2xhc3MgYSB2ZXJ5IHNpbXBsZSBpbXBsZW1lbnRhdGlvbgotICAgKiAgaXMgcHJvdmlkZWQgd2hpY2ggcmVwb3J0cyB0aGUgZXJyb3IgdGhlbiB0aHJvd3MgYW4gZXhjZXB0aW9uLgotICAgKgotICAgKiBAcGFyYW0gbWVzc2FnZSBhbiBlcnJvciBtZXNzYWdlLgotICAgKiBAcGFyYW0gaW5mbyAgICBhbiBleHRyYSBvYmplY3QgcmVzZXJ2ZWQgZm9yIHVzZSBieSBzcGVjaWFsaXplZCBzdWJjbGFzc2VzLgotICAgKi8KLSAgcHVibGljIHZvaWQgcmVwb3J0X2ZhdGFsX2Vycm9yKAotICAgIFN0cmluZyAgIG1lc3NhZ2UsCi0gICAgT2JqZWN0ICAgaW5mbykKLSAgICB0aHJvd3MgamF2YS5sYW5nLkV4Y2VwdGlvbgotICAgIHsKLSAgICAgIC8qIHN0b3AgcGFyc2luZyAobm90IHJlYWxseSBuZWNlc3Nhcnkgc2luY2Ugd2UgdGhyb3cgYW4gZXhjZXB0aW9uLCBidXQpICovCi0gICAgICBkb25lX3BhcnNpbmcoKTsKLQotICAgICAgLyogdXNlIHRoZSBub3JtYWwgZXJyb3IgbWVzc2FnZSByZXBvcnRpbmcgdG8gcHV0IG91dCB0aGUgbWVzc2FnZSAqLwotICAgICAgcmVwb3J0X2Vycm9yKG1lc3NhZ2UsIGluZm8pOwotCi0gICAgICAvKiB0aHJvdyBhbiBleGNlcHRpb24gKi8KLSAgICAgIHRocm93IG5ldyBFeGNlcHRpb24oIkNhbid0IHJlY292ZXIgZnJvbSBwcmV2aW91cyBlcnJvcihzKSIpOwotICAgIH0KLQotICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuKi8KLQotICAvKiogUmVwb3J0IGEgbm9uIGZhdGFsIGVycm9yIChvciB3YXJuaW5nKS4gIFRoaXMgbWV0aG9kIHRha2VzIGEgbWVzc2FnZQotICAgKiAgc3RyaW5nIGFuZCBhbiBhZGRpdGlvbmFsIG9iamVjdCAodG8gYmUgdXNlZCBieSBzcGVjaWFsaXphdGlvbnMKLSAgICogIGltcGxlbWVudGVkIGluIHN1YmNsYXNzZXMpLiAgSGVyZSBpbiB0aGUgYmFzZSBjbGFzcyBhIHZlcnkgc2ltcGxlCi0gICAqICBpbXBsZW1lbnRhdGlvbiBpcyBwcm92aWRlZCB3aGljaCBzaW1wbHkgcHJpbnRzIHRoZSBtZXNzYWdlIHRvCi0gICAqICBTeXN0ZW0uZXJyLgotICAgKgotICAgKiBAcGFyYW0gbWVzc2FnZSBhbiBlcnJvciBtZXNzYWdlLgotICAgKiBAcGFyYW0gaW5mbyAgICBhbiBleHRyYSBvYmplY3QgcmVzZXJ2ZWQgZm9yIHVzZSBieSBzcGVjaWFsaXplZCBzdWJjbGFzc2VzLgotICAgKi8KLSAgcHVibGljIHZvaWQgcmVwb3J0X2Vycm9yKFN0cmluZyBtZXNzYWdlLCBPYmplY3QgaW5mbykKLSAgICB7Ci0gICAgICBTeXN0ZW0uZXJyLnByaW50KG1lc3NhZ2UpOwotICAgICAgaWYgKGluZm8gaW5zdGFuY2VvZiBTeW1ib2wpCi0gICAgICAgIGlmICgoKFN5bWJvbClpbmZvKS5sZWZ0ICE9IC0xKQotICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIiBhdCBjaGFyYWN0ZXIgIiArICgoU3ltYm9sKWluZm8pLmxlZnQgKwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIiBvZiBpbnB1dCIpOwotICAgICAgICBlbHNlIFN5c3RlbS5lcnIucHJpbnRsbigiIik7Ci0gICAgICBlbHNlIFN5c3RlbS5lcnIucHJpbnRsbigiIik7Ci0gICAgfQotCi0gIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotCi0gIC8qKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgd2hlbiBhIHN5bnRheCBlcnJvciBoYXMgYmVlbiBkZXRlY3RlZCBhbmQgcmVjb3ZlcnkKLSAgICogIGlzIGFib3V0IHRvIGJlIGludm9rZWQuICBIZXJlIGluIHRoZSBiYXNlIGNsYXNzIHdlIGp1c3QgZW1pdCBhCi0gICAqICAiU3ludGF4IGVycm9yIiBlcnJvciBtZXNzYWdlLgotICAgKgotICAgKiBAcGFyYW0gY3VyX3Rva2VuIHRoZSBjdXJyZW50IGxvb2thaGVhZCBTeW1ib2wuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzeW50YXhfZXJyb3IoU3ltYm9sIGN1cl90b2tlbikKLSAgICB7Ci0gICAgICByZXBvcnRfZXJyb3IoIlN5bnRheCBlcnJvciIsIGN1cl90b2tlbik7Ci0gICAgfQotCi0gIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotCi0gIC8qKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgaWYgaXQgaXMgZGV0ZXJtaW5lZCB0aGF0IHN5bnRheCBlcnJvciByZWNvdmVyeQotICAgKiAgaGFzIGJlZW4gdW5zdWNjZXNzZnVsLiAgSGVyZSBpbiB0aGUgYmFzZSBjbGFzcyB3ZSByZXBvcnQgYSBmYXRhbCBlcnJvci4KLSAgICoKLSAgICogQHBhcmFtIGN1cl90b2tlbiB0aGUgY3VycmVudCBsb29rYWhlYWQgU3ltYm9sLgotICAgKi8KLSAgcHVibGljIHZvaWQgdW5yZWNvdmVyZWRfc3ludGF4X2Vycm9yKFN5bWJvbCBjdXJfdG9rZW4pCi0gICAgdGhyb3dzIGphdmEubGFuZy5FeGNlcHRpb24KLSAgICB7Ci0gICAgICByZXBvcnRfZmF0YWxfZXJyb3IoIkNvdWxkbid0IHJlcGFpciBhbmQgY29udGludWUgcGFyc2UiLCBjdXJfdG9rZW4pOwotICAgIH0KLQotICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuKi8KLQotICAvKiogRmV0Y2ggYW4gYWN0aW9uIGZyb20gdGhlIGFjdGlvbiB0YWJsZS4gIFRoZSB0YWJsZSBpcyBicm9rZW4gdXAgaW50bwotICAgKiAgcm93cywgb25lIHBlciBzdGF0ZSAocm93cyBhcmUgaW5kZXhlZCBkaXJlY3RseSBieSBzdGF0ZSBudW1iZXIpLgotICAgKiAgV2l0aGluIGVhY2ggcm93LCBhIGxpc3Qgb2YgaW5kZXgsIHZhbHVlIHBhaXJzIGFyZSBnaXZlbiAoYXMgc2VxdWVudGlhbAotICAgKiAgZW50cmllcyBpbiB0aGUgdGFibGUpLCBhbmQgdGhlIGxpc3QgaXMgdGVybWluYXRlZCBieSBhIGRlZmF1bHQgZW50cnkKLSAgICogIChkZW5vdGVkIHdpdGggYSBTeW1ib2wgaW5kZXggb2YgLTEpLiAgVG8gZmluZCB0aGUgcHJvcGVyIGVudHJ5IGluIGEgcm93Ci0gICAqICB3ZSBkbyBhIGxpbmVhciBvciBiaW5hcnkgc2VhcmNoIChkZXBlbmRpbmcgb24gdGhlIHNpemUgb2YgdGhlIHJvdykuCi0gICAqCi0gICAqIEBwYXJhbSBzdGF0ZSB0aGUgc3RhdGUgaW5kZXggb2YgdGhlIGFjdGlvbiBiZWluZyBhY2Nlc3NlZC4KLSAgICogQHBhcmFtIHN5bSAgIHRoZSBTeW1ib2wgaW5kZXggb2YgdGhlIGFjdGlvbiBiZWluZyBhY2Nlc3NlZC4KLSAgICovCi0gIHByb3RlY3RlZCBmaW5hbCBzaG9ydCBnZXRfYWN0aW9uKGludCBzdGF0ZSwgaW50IHN5bSkKLSAgICB7Ci0gICAgICBzaG9ydCB0YWc7Ci0gICAgICBpbnQgZmlyc3QsIGxhc3QsIHByb2JlOwotICAgICAgc2hvcnRbXSByb3cgPSBhY3Rpb25fdGFiW3N0YXRlXTsKLQotICAgICAgLyogbGluZWFyIHNlYXJjaCBpZiB3ZSBhcmUgPCAxMCBlbnRyaWVzICovCi0gICAgICBpZiAocm93Lmxlbmd0aCA8IDIwKQotICAgICAgICBmb3IgKHByb2JlID0gMDsgcHJvYmUgPCByb3cubGVuZ3RoOyBwcm9iZSsrKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIC8qIGlzIHRoaXMgZW50cnkgbGFiZWxlZCB3aXRoIG91ciBTeW1ib2wgb3IgdGhlIGRlZmF1bHQ/ICovCi0gICAgICAgICAgICB0YWcgPSByb3dbcHJvYmUrK107Ci0gICAgICAgICAgICBpZiAodGFnID09IHN5bSB8fCB0YWcgPT0gLTEpCi0gICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAvKiByZXR1cm4gdGhlIG5leHQgZW50cnkgKi8KLSAgICAgICAgICAgICAgICByZXR1cm4gcm93W3Byb2JlXTsKLSAgICAgICAgICAgICAgfQotICAgICAgICAgIH0KLSAgICAgIC8qIG90aGVyd2lzZSBiaW5hcnkgc2VhcmNoICovCi0gICAgICBlbHNlCi0gICAgICAgIHsKLSAgICAgICAgICBmaXJzdCA9IDA7Ci0gICAgICAgICAgbGFzdCA9IChyb3cubGVuZ3RoLTEpLzIgLSAxOyAgLyogbGVhdmUgb3V0IHRyYWlsaW5nIGRlZmF1bHQgZW50cnkgKi8KLSAgICAgICAgICB3aGlsZSAoZmlyc3QgPD0gbGFzdCkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgcHJvYmUgPSAoZmlyc3QrbGFzdCkvMjsKLSAgICAgICAgICAgICAgaWYgKHN5bSA9PSByb3dbcHJvYmUqMl0pCi0gICAgICAgICAgICAgICAgcmV0dXJuIHJvd1twcm9iZSoyKzFdOwotICAgICAgICAgICAgICBlbHNlIGlmIChzeW0gPiByb3dbcHJvYmUqMl0pCi0gICAgICAgICAgICAgICAgZmlyc3QgPSBwcm9iZSsxOwotICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgbGFzdCA9IHByb2JlLTE7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAvKiBub3QgZm91bmQsIHVzZSB0aGUgZGVmYXVsdCBhdCB0aGUgZW5kICovCi0gICAgICAgICAgcmV0dXJuIHJvd1tyb3cubGVuZ3RoLTFdOwotICAgICAgICB9Ci0KLSAgICAgIC8qIHNob3VsZG4ndCBoYXBwZW5lZCwgYnV0IGlmIHdlIHJ1biBvZmYgdGhlIGVuZCB3ZSByZXR1cm4gdGhlCi0gICAgICAgICBkZWZhdWx0IChlcnJvciA9PSAwKSAqLwotICAgICAgcmV0dXJuIDA7Ci0gICAgfQotCi0gIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotCi0gIC8qKiBGZXRjaCBhIHN0YXRlIGZyb20gdGhlIHJlZHVjZS1nb3RvIHRhYmxlLiAgVGhlIHRhYmxlIGlzIGJyb2tlbiB1cCBpbnRvCi0gICAqICByb3dzLCBvbmUgcGVyIHN0YXRlIChyb3dzIGFyZSBpbmRleGVkIGRpcmVjdGx5IGJ5IHN0YXRlIG51bWJlcikuCi0gICAqICBXaXRoaW4gZWFjaCByb3csIGEgbGlzdCBvZiBpbmRleCwgdmFsdWUgcGFpcnMgYXJlIGdpdmVuIChhcyBzZXF1ZW50aWFsCi0gICAqICBlbnRyaWVzIGluIHRoZSB0YWJsZSksIGFuZCB0aGUgbGlzdCBpcyB0ZXJtaW5hdGVkIGJ5IGEgZGVmYXVsdCBlbnRyeQotICAgKiAgKGRlbm90ZWQgd2l0aCBhIFN5bWJvbCBpbmRleCBvZiAtMSkuICBUbyBmaW5kIHRoZSBwcm9wZXIgZW50cnkgaW4gYSByb3cKLSAgICogIHdlIGRvIGEgbGluZWFyIHNlYXJjaC4KLSAgICoKLSAgICogQHBhcmFtIHN0YXRlIHRoZSBzdGF0ZSBpbmRleCBvZiB0aGUgZW50cnkgYmVpbmcgYWNjZXNzZWQuCi0gICAqIEBwYXJhbSBzeW0gICB0aGUgU3ltYm9sIGluZGV4IG9mIHRoZSBlbnRyeSBiZWluZyBhY2Nlc3NlZC4KLSAgICovCi0gIHByb3RlY3RlZCBmaW5hbCBzaG9ydCBnZXRfcmVkdWNlKGludCBzdGF0ZSwgaW50IHN5bSkKLSAgICB7Ci0gICAgICBzaG9ydCB0YWc7Ci0gICAgICBzaG9ydFtdIHJvdyA9IHJlZHVjZV90YWJbc3RhdGVdOwotCi0gICAgICAvKiBpZiB3ZSBoYXZlIGEgbnVsbCByb3cgd2UgZ28gd2l0aCB0aGUgZGVmYXVsdCAqLwotICAgICAgaWYgKHJvdyA9PSBudWxsKQotICAgICAgICByZXR1cm4gLTE7Ci0KLSAgICAgIGZvciAoaW50IHByb2JlID0gMDsgcHJvYmUgPCByb3cubGVuZ3RoOyBwcm9iZSsrKQotICAgICAgICB7Ci0gICAgICAgICAgLyogaXMgdGhpcyBlbnRyeSBsYWJlbGVkIHdpdGggb3VyIFN5bWJvbCBvciB0aGUgZGVmYXVsdD8gKi8KLSAgICAgICAgICB0YWcgPSByb3dbcHJvYmUrK107Ci0gICAgICAgICAgaWYgKHRhZyA9PSBzeW0gfHwgdGFnID09IC0xKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAvKiByZXR1cm4gdGhlIG5leHQgZW50cnkgKi8KLSAgICAgICAgICAgICAgcmV0dXJuIHJvd1twcm9iZV07Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgIC8qIGlmIHdlIHJ1biBvZmYgdGhlIGVuZCB3ZSByZXR1cm4gdGhlIGRlZmF1bHQgKGVycm9yID09IC0xKSAqLwotICAgICAgcmV0dXJuIC0xOwotICAgIH0KLQotICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuKi8KLQotICAvKiogVGhpcyBtZXRob2QgcHJvdmlkZXMgdGhlIG1haW4gcGFyc2luZyByb3V0aW5lLiAgSXQgcmV0dXJucyBvbmx5IHdoZW4KLSAgICogIGRvbmVfcGFyc2luZygpIGhhcyBiZWVuIGNhbGxlZCAodHlwaWNhbGx5IGJlY2F1c2UgdGhlIHBhcnNlciBoYXMKLSAgICogIGFjY2VwdGVkLCBvciBhIGZhdGFsIGVycm9yIGhhcyBiZWVuIHJlcG9ydGVkKS4gIFNlZSB0aGUgaGVhZGVyCi0gICAqICBkb2N1bWVudGF0aW9uIGZvciB0aGUgY2xhc3MgcmVnYXJkaW5nIGhvdyBzaGlmdC9yZWR1Y2UgcGFyc2VycyBvcGVyYXRlCi0gICAqICBhbmQgaG93IHRoZSB2YXJpb3VzIHRhYmxlcyBhcmUgdXNlZC4KLSAgICovCi0gIHB1YmxpYyBTeW1ib2wgcGFyc2UoKSB0aHJvd3MgamF2YS5sYW5nLkV4Y2VwdGlvbgotICAgIHsKLSAgICAgIC8qIHRoZSBjdXJyZW50IGFjdGlvbiBjb2RlICovCi0gICAgICBpbnQgYWN0OwotCi0gICAgICAvKiB0aGUgU3ltYm9sL3N0YWNrIGVsZW1lbnQgcmV0dXJuZWQgYnkgYSByZWR1Y2UgKi8KLSAgICAgIFN5bWJvbCBsaHNfc3ltID0gbnVsbDsKLQotICAgICAgLyogaW5mb3JtYXRpb24gYWJvdXQgcHJvZHVjdGlvbiBiZWluZyByZWR1Y2VkIHdpdGggKi8KLSAgICAgIHNob3J0IGhhbmRsZV9zaXplLCBsaHNfc3ltX251bTsKLQotICAgICAgLyogc2V0IHVwIGRpcmVjdCByZWZlcmVuY2UgdG8gdGFibGVzIHRvIGRyaXZlIHRoZSBwYXJzZXIgKi8KLQotICAgICAgcHJvZHVjdGlvbl90YWIgPSBwcm9kdWN0aW9uX3RhYmxlKCk7Ci0gICAgICBhY3Rpb25fdGFiICAgICA9IGFjdGlvbl90YWJsZSgpOwotICAgICAgcmVkdWNlX3RhYiAgICAgPSByZWR1Y2VfdGFibGUoKTsKLQotICAgICAgLyogaW5pdGlhbGl6ZSB0aGUgYWN0aW9uIGVuY2Fwc3VsYXRpb24gb2JqZWN0ICovCi0gICAgICBpbml0X2FjdGlvbnMoKTsKLQotICAgICAgLyogZG8gdXNlciBpbml0aWFsaXphdGlvbiAqLwotICAgICAgdXNlcl9pbml0KCk7Ci0KLSAgICAgIC8qIGdldCB0aGUgZmlyc3QgdG9rZW4gKi8KLSAgICAgIGN1cl90b2tlbiA9IHNjYW4oKTsKLQotICAgICAgLyogcHVzaCBkdW1teSBTeW1ib2wgd2l0aCBzdGFydCBzdGF0ZSB0byBnZXQgdXMgdW5kZXJ3YXkgKi8KLSAgICAgIHN0YWNrLnJlbW92ZUFsbEVsZW1lbnRzKCk7Ci0gICAgICBzdGFjay5wdXNoKG5ldyBTeW1ib2woMCwgc3RhcnRfc3RhdGUoKSkpOwotICAgICAgdG9zID0gMDsKLQotICAgICAgLyogY29udGludWUgdW50aWwgd2UgYXJlIHRvbGQgdG8gc3RvcCAqLwotICAgICAgZm9yIChfZG9uZV9wYXJzaW5nID0gZmFsc2U7ICFfZG9uZV9wYXJzaW5nOyApCi0gICAgICAgIHsKLSAgICAgICAgICAvKiBDaGVjayBjdXJyZW50IHRva2VuIGZvciBmcmVzaG5lc3MuICovCi0gICAgICAgICAgaWYgKGN1cl90b2tlbi51c2VkX2J5X3BhcnNlcikKLSAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigiU3ltYm9sIHJlY3ljbGluZyBkZXRlY3RlZCAoZml4IHlvdXIgc2Nhbm5lcikuIik7Ci0KLSAgICAgICAgICAvKiBjdXJyZW50IHN0YXRlIGlzIGFsd2F5cyBvbiB0aGUgdG9wIG9mIHRoZSBzdGFjayAqLwotCi0gICAgICAgICAgLyogbG9vayB1cCBhY3Rpb24gb3V0IG9mIHRoZSBjdXJyZW50IHN0YXRlIHdpdGggdGhlIGN1cnJlbnQgaW5wdXQgKi8KLSAgICAgICAgICBhY3QgPSBnZXRfYWN0aW9uKCgoU3ltYm9sKXN0YWNrLnBlZWsoKSkucGFyc2Vfc3RhdGUsIGN1cl90b2tlbi5zeW0pOwotCi0gICAgICAgICAgLyogZGVjb2RlIHRoZSBhY3Rpb24gLS0gPiAwIGVuY29kZXMgc2hpZnQgKi8KLSAgICAgICAgICBpZiAoYWN0ID4gMCkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgLyogc2hpZnQgdG8gdGhlIGVuY29kZWQgc3RhdGUgYnkgcHVzaGluZyBpdCBvbiB0aGUgc3RhY2sgKi8KLSAgICAgICAgICAgICAgY3VyX3Rva2VuLnBhcnNlX3N0YXRlID0gYWN0LTE7Ci0gICAgICAgICAgICAgIGN1cl90b2tlbi51c2VkX2J5X3BhcnNlciA9IHRydWU7Ci0gICAgICAgICAgICAgIHN0YWNrLnB1c2goY3VyX3Rva2VuKTsKLSAgICAgICAgICAgICAgdG9zKys7Ci0KLSAgICAgICAgICAgICAgLyogYWR2YW5jZSB0byB0aGUgbmV4dCBTeW1ib2wgKi8KLSAgICAgICAgICAgICAgY3VyX3Rva2VuID0gc2NhbigpOwotICAgICAgICAgICAgfQotICAgICAgICAgIC8qIGlmIGl0cyBsZXNzIHRoYW4gemVybywgdGhlbiBpdCBlbmNvZGVzIGEgcmVkdWNlIGFjdGlvbiAqLwotICAgICAgICAgIGVsc2UgaWYgKGFjdCA8IDApCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIC8qIHBlcmZvcm0gdGhlIGFjdGlvbiBmb3IgdGhlIHJlZHVjZSAqLwotICAgICAgICAgICAgICBsaHNfc3ltID0gZG9fYWN0aW9uKCgtYWN0KS0xLCB0aGlzLCBzdGFjaywgdG9zKTsKLQotICAgICAgICAgICAgICAvKiBsb29rIHVwIGluZm9ybWF0aW9uIGFib3V0IHRoZSBwcm9kdWN0aW9uICovCi0gICAgICAgICAgICAgIGxoc19zeW1fbnVtID0gcHJvZHVjdGlvbl90YWJbKC1hY3QpLTFdWzBdOwotICAgICAgICAgICAgICBoYW5kbGVfc2l6ZSA9IHByb2R1Y3Rpb25fdGFiWygtYWN0KS0xXVsxXTsKLQotICAgICAgICAgICAgICAvKiBwb3AgdGhlIGhhbmRsZSBvZmYgdGhlIHN0YWNrICovCi0gICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaGFuZGxlX3NpemU7IGkrKykKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICBzdGFjay5wb3AoKTsKLSAgICAgICAgICAgICAgICAgIHRvcy0tOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAvKiBsb29rIHVwIHRoZSBzdGF0ZSB0byBnbyB0byBmcm9tIHRoZSBvbmUgcG9wcGVkIGJhY2sgdG8gKi8KLSAgICAgICAgICAgICAgYWN0ID0gZ2V0X3JlZHVjZSgoKFN5bWJvbClzdGFjay5wZWVrKCkpLnBhcnNlX3N0YXRlLCBsaHNfc3ltX251bSk7Ci0KLSAgICAgICAgICAgICAgLyogc2hpZnQgdG8gdGhhdCBzdGF0ZSAqLwotICAgICAgICAgICAgICBsaHNfc3ltLnBhcnNlX3N0YXRlID0gYWN0OwotICAgICAgICAgICAgICBsaHNfc3ltLnVzZWRfYnlfcGFyc2VyID0gdHJ1ZTsKLSAgICAgICAgICAgICAgc3RhY2sucHVzaChsaHNfc3ltKTsKLSAgICAgICAgICAgICAgdG9zKys7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgLyogZmluYWxseSBpZiB0aGUgZW50cnkgaXMgemVybywgd2UgaGF2ZSBhbiBlcnJvciAqLwotICAgICAgICAgIGVsc2UgaWYgKGFjdCA9PSAwKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAvKiBjYWxsIHVzZXIgc3ludGF4IGVycm9yIHJlcG9ydGluZyByb3V0aW5lICovCi0gICAgICAgICAgICAgIHN5bnRheF9lcnJvcihjdXJfdG9rZW4pOwotCi0gICAgICAgICAgICAgIC8qIHRyeSB0byBlcnJvciByZWNvdmVyICovCi0gICAgICAgICAgICAgIGlmICghZXJyb3JfcmVjb3ZlcnkoZmFsc2UpKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgIC8qIGlmIHRoYXQgZmFpbHMgZ2l2ZSB1cCB3aXRoIGEgZmF0YWwgc3ludGF4IGVycm9yICovCi0gICAgICAgICAgICAgICAgICB1bnJlY292ZXJlZF9zeW50YXhfZXJyb3IoY3VyX3Rva2VuKTsKLQotICAgICAgICAgICAgICAgICAgLyoganVzdCBpbiBjYXNlIHRoYXQgd2Fzbid0IGZhdGFsIGVub3VnaCwgZW5kIHBhcnNlICovCi0gICAgICAgICAgICAgICAgICBkb25lX3BhcnNpbmcoKTsKLSAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgbGhzX3N5bSA9IChTeW1ib2wpc3RhY2sucGVlaygpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgcmV0dXJuIGxoc19zeW07Ci0gICAgfQotCi0gIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotCi0gIC8qKiBXcml0ZSBhIGRlYnVnZ2luZyBtZXNzYWdlIHRvIFN5c3RlbS5lcnIgZm9yIHRoZSBkZWJ1Z2dpbmcgdmVyc2lvbgotICAgKiAgb2YgdGhlIHBhcnNlci4KLSAgICoKLSAgICogQHBhcmFtIG1lc3MgdGhlIHRleHQgb2YgdGhlIGRlYnVnZ2luZyBtZXNzYWdlLgotICAgKi8KLSAgcHVibGljIHZvaWQgZGVidWdfbWVzc2FnZShTdHJpbmcgbWVzcykKLSAgICB7Ci0gICAgICBTeXN0ZW0uZXJyLnByaW50bG4obWVzcyk7Ci0gICAgfQotCi0gIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotCi0gIC8qKiBEdW1wIHRoZSBwYXJzZSBzdGFjayBmb3IgZGVidWdnaW5nIHB1cnBvc2VzLiAqLwotICBwdWJsaWMgdm9pZCBkdW1wX3N0YWNrKCkKLSAgICB7Ci0gICAgICBpZiAoc3RhY2sgPT0gbnVsbCkKLSAgICAgICAgewotICAgICAgICAgIGRlYnVnX21lc3NhZ2UoIiMgU3RhY2sgZHVtcCByZXF1ZXN0ZWQsIGJ1dCBzdGFjayBpcyBudWxsIik7Ci0gICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0KLSAgICAgIGRlYnVnX21lc3NhZ2UoIj09PT09PT09PT09PSBQYXJzZSBTdGFjayBEdW1wID09PT09PT09PT09PSIpOwotCi0gICAgICAvKiBkdW1wIHRoZSBzdGFjayAqLwotICAgICAgZm9yIChpbnQgaT0wOyBpPHN0YWNrLnNpemUoKTsgaSsrKQotICAgICAgICB7Ci0gICAgICAgICAgZGVidWdfbWVzc2FnZSgiU3ltYm9sOiAiICsgKChTeW1ib2wpc3RhY2suZWxlbWVudEF0KGkpKS5zeW0gKwotICAgICAgICAgICAgICAgICAgICAgICAgIiBTdGF0ZTogIiArICgoU3ltYm9sKXN0YWNrLmVsZW1lbnRBdChpKSkucGFyc2Vfc3RhdGUpOwotICAgICAgICB9Ci0gICAgICBkZWJ1Z19tZXNzYWdlKCI9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0iKTsKLSAgICB9Ci0KLSAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0KLSAgLyoqIERvIGRlYnVnIG91dHB1dCBmb3IgYSByZWR1Y2UuCi0gICAqCi0gICAqIEBwYXJhbSBwcm9kX251bSAgdGhlIHByb2R1Y3Rpb24gd2UgYXJlIHJlZHVjaW5nIHdpdGguCi0gICAqIEBwYXJhbSBudF9udW0gICAgdGhlIGluZGV4IG9mIHRoZSBMSFMgbm9uIHRlcm1pbmFsLgotICAgKiBAcGFyYW0gcmhzX3NpemUgIHRoZSBzaXplIG9mIHRoZSBSSFMuCi0gICAqLwotICBwdWJsaWMgdm9pZCBkZWJ1Z19yZWR1Y2UoaW50IHByb2RfbnVtLCBpbnQgbnRfbnVtLCBpbnQgcmhzX3NpemUpCi0gICAgewotICAgICAgZGVidWdfbWVzc2FnZSgiIyBSZWR1Y2Ugd2l0aCBwcm9kICMiICsgcHJvZF9udW0gKyAiIFtOVD0iICsgbnRfbnVtICsKLSAgICAgICAgICAgICAgICAgICAgIiwgIiArICJTWj0iICsgcmhzX3NpemUgKyAiXSIpOwotICAgIH0KLQotICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuKi8KLQotICAvKiogRG8gZGVidWcgb3V0cHV0IGZvciBzaGlmdC4KLSAgICoKLSAgICogQHBhcmFtIHNoaWZ0X3RrbiB0aGUgU3ltYm9sIGJlaW5nIHNoaWZ0ZWQgb250byB0aGUgc3RhY2suCi0gICAqLwotICBwdWJsaWMgdm9pZCBkZWJ1Z19zaGlmdChTeW1ib2wgc2hpZnRfdGtuKQotICAgIHsKLSAgICAgIGRlYnVnX21lc3NhZ2UoIiMgU2hpZnQgdW5kZXIgdGVybSAjIiArIHNoaWZ0X3Rrbi5zeW0gKwotICAgICAgICAgICAgICAgICAgICAiIHRvIHN0YXRlICMiICsgc2hpZnRfdGtuLnBhcnNlX3N0YXRlKTsKLSAgICB9Ci0KLSAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0KLSAgLyoqIERvIGRlYnVnIG91dHB1dCBmb3Igc3RhY2sgc3RhdGUuIFtDU0FdCi0gICAqLwotICBwdWJsaWMgdm9pZCBkZWJ1Z19zdGFjaygpIHsKLSAgICAgIFN0cmluZ0J1ZmZlciBzYj1uZXcgU3RyaW5nQnVmZmVyKCIjIyBTVEFDSzoiKTsKLSAgICAgIGZvciAoaW50IGk9MDsgaTxzdGFjay5zaXplKCk7IGkrKykgewotICAgICAgICAgIFN5bWJvbCBzID0gKFN5bWJvbCkgc3RhY2suZWxlbWVudEF0KGkpOwotICAgICAgICAgIHNiLmFwcGVuZCgiIDxzdGF0ZSAiK3MucGFyc2Vfc3RhdGUrIiwgc3ltICIrcy5zeW0rIj4iKTsKLSAgICAgICAgICBpZiAoKGklMyk9PTIgfHwgKGk9PShzdGFjay5zaXplKCktMSkpKSB7Ci0gICAgICAgICAgICAgIGRlYnVnX21lc3NhZ2Uoc2IudG9TdHJpbmcoKSk7Ci0gICAgICAgICAgICAgIHNiID0gbmV3IFN0cmluZ0J1ZmZlcigiICAgICAgICAgIik7Ci0gICAgICAgICAgfQotICAgICAgfQotICB9Ci0KLSAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0KLSAgLyoqIFBlcmZvcm0gYSBwYXJzZSB3aXRoIGRlYnVnZ2luZyBvdXRwdXQuICBUaGlzIGRvZXMgZXhhY3RseSB0aGUKLSAgICogIHNhbWUgdGhpbmdzIGFzIHBhcnNlKCksIGV4Y2VwdCB0aGF0IGl0IGNhbGxzIGRlYnVnX3NoaWZ0KCkgYW5kCi0gICAqICBkZWJ1Z19yZWR1Y2UoKSB3aGVuIHNoaWZ0IGFuZCByZWR1Y2UgbW92ZXMgYXJlIHRha2VuIGJ5IHRoZSBwYXJzZXIKLSAgICogIGFuZCBwcm9kdWNlcyB2YXJpb3VzIG90aGVyIGRlYnVnZ2luZyBtZXNzYWdlcy4KLSAgICovCi0gIHB1YmxpYyBTeW1ib2wgZGVidWdfcGFyc2UoKQotICAgIHRocm93cyBqYXZhLmxhbmcuRXhjZXB0aW9uCi0gICAgewotICAgICAgLyogdGhlIGN1cnJlbnQgYWN0aW9uIGNvZGUgKi8KLSAgICAgIGludCBhY3Q7Ci0KLSAgICAgIC8qIHRoZSBTeW1ib2wvc3RhY2sgZWxlbWVudCByZXR1cm5lZCBieSBhIHJlZHVjZSAqLwotICAgICAgU3ltYm9sIGxoc19zeW0gPSBudWxsOwotCi0gICAgICAvKiBpbmZvcm1hdGlvbiBhYm91dCBwcm9kdWN0aW9uIGJlaW5nIHJlZHVjZWQgd2l0aCAqLwotICAgICAgc2hvcnQgaGFuZGxlX3NpemUsIGxoc19zeW1fbnVtOwotCi0gICAgICAvKiBzZXQgdXAgZGlyZWN0IHJlZmVyZW5jZSB0byB0YWJsZXMgdG8gZHJpdmUgdGhlIHBhcnNlciAqLwotICAgICAgcHJvZHVjdGlvbl90YWIgPSBwcm9kdWN0aW9uX3RhYmxlKCk7Ci0gICAgICBhY3Rpb25fdGFiICAgICA9IGFjdGlvbl90YWJsZSgpOwotICAgICAgcmVkdWNlX3RhYiAgICAgPSByZWR1Y2VfdGFibGUoKTsKLQotICAgICAgZGVidWdfbWVzc2FnZSgiIyBJbml0aWFsaXppbmcgcGFyc2VyIik7Ci0KLSAgICAgIC8qIGluaXRpYWxpemUgdGhlIGFjdGlvbiBlbmNhcHN1bGF0aW9uIG9iamVjdCAqLwotICAgICAgaW5pdF9hY3Rpb25zKCk7Ci0KLSAgICAgIC8qIGRvIHVzZXIgaW5pdGlhbGl6YXRpb24gKi8KLSAgICAgIHVzZXJfaW5pdCgpOwotCi0gICAgICAvKiB0aGUgY3VycmVudCBTeW1ib2wgKi8KLSAgICAgIGN1cl90b2tlbiA9IHNjYW4oKTsKLQotICAgICAgZGVidWdfbWVzc2FnZSgiIyBDdXJyZW50IFN5bWJvbCBpcyAjIiArIGN1cl90b2tlbi5zeW0pOwotCi0gICAgICAvKiBwdXNoIGR1bW15IFN5bWJvbCB3aXRoIHN0YXJ0IHN0YXRlIHRvIGdldCB1cyB1bmRlcndheSAqLwotICAgICAgc3RhY2sucmVtb3ZlQWxsRWxlbWVudHMoKTsKLSAgICAgIHN0YWNrLnB1c2gobmV3IFN5bWJvbCgwLCBzdGFydF9zdGF0ZSgpKSk7Ci0gICAgICB0b3MgPSAwOwotCi0gICAgICAvKiBjb250aW51ZSB1bnRpbCB3ZSBhcmUgdG9sZCB0byBzdG9wICovCi0gICAgICBmb3IgKF9kb25lX3BhcnNpbmcgPSBmYWxzZTsgIV9kb25lX3BhcnNpbmc7ICkKLSAgICAgICAgewotICAgICAgICAgIC8qIENoZWNrIGN1cnJlbnQgdG9rZW4gZm9yIGZyZXNobmVzcy4gKi8KLSAgICAgICAgICBpZiAoY3VyX3Rva2VuLnVzZWRfYnlfcGFyc2VyKQotICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJTeW1ib2wgcmVjeWNsaW5nIGRldGVjdGVkIChmaXggeW91ciBzY2FubmVyKS4iKTsKLQotICAgICAgICAgIC8qIGN1cnJlbnQgc3RhdGUgaXMgYWx3YXlzIG9uIHRoZSB0b3Agb2YgdGhlIHN0YWNrICovCi0gICAgICAgICAgLy9kZWJ1Z19zdGFjaygpOwotCi0gICAgICAgICAgLyogbG9vayB1cCBhY3Rpb24gb3V0IG9mIHRoZSBjdXJyZW50IHN0YXRlIHdpdGggdGhlIGN1cnJlbnQgaW5wdXQgKi8KLSAgICAgICAgICBhY3QgPSBnZXRfYWN0aW9uKCgoU3ltYm9sKXN0YWNrLnBlZWsoKSkucGFyc2Vfc3RhdGUsIGN1cl90b2tlbi5zeW0pOwotCi0gICAgICAgICAgLyogZGVjb2RlIHRoZSBhY3Rpb24gLS0gPiAwIGVuY29kZXMgc2hpZnQgKi8KLSAgICAgICAgICBpZiAoYWN0ID4gMCkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgLyogc2hpZnQgdG8gdGhlIGVuY29kZWQgc3RhdGUgYnkgcHVzaGluZyBpdCBvbiB0aGUgc3RhY2sgKi8KLSAgICAgICAgICAgICAgY3VyX3Rva2VuLnBhcnNlX3N0YXRlID0gYWN0LTE7Ci0gICAgICAgICAgICAgIGN1cl90b2tlbi51c2VkX2J5X3BhcnNlciA9IHRydWU7Ci0gICAgICAgICAgICAgIGRlYnVnX3NoaWZ0KGN1cl90b2tlbik7Ci0gICAgICAgICAgICAgIHN0YWNrLnB1c2goY3VyX3Rva2VuKTsKLSAgICAgICAgICAgICAgdG9zKys7Ci0KLSAgICAgICAgICAgICAgLyogYWR2YW5jZSB0byB0aGUgbmV4dCBTeW1ib2wgKi8KLSAgICAgICAgICAgICAgY3VyX3Rva2VuID0gc2NhbigpOwotICAgICAgICAgICAgICBkZWJ1Z19tZXNzYWdlKCIjIEN1cnJlbnQgdG9rZW4gaXMgIiArIGN1cl90b2tlbik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgLyogaWYgaXRzIGxlc3MgdGhhbiB6ZXJvLCB0aGVuIGl0IGVuY29kZXMgYSByZWR1Y2UgYWN0aW9uICovCi0gICAgICAgICAgZWxzZSBpZiAoYWN0IDwgMCkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgLyogcGVyZm9ybSB0aGUgYWN0aW9uIGZvciB0aGUgcmVkdWNlICovCi0gICAgICAgICAgICAgIGxoc19zeW0gPSBkb19hY3Rpb24oKC1hY3QpLTEsIHRoaXMsIHN0YWNrLCB0b3MpOwotCi0gICAgICAgICAgICAgIC8qIGxvb2sgdXAgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHByb2R1Y3Rpb24gKi8KLSAgICAgICAgICAgICAgbGhzX3N5bV9udW0gPSBwcm9kdWN0aW9uX3RhYlsoLWFjdCktMV1bMF07Ci0gICAgICAgICAgICAgIGhhbmRsZV9zaXplID0gcHJvZHVjdGlvbl90YWJbKC1hY3QpLTFdWzFdOwotCi0gICAgICAgICAgICAgIGRlYnVnX3JlZHVjZSgoLWFjdCktMSwgbGhzX3N5bV9udW0sIGhhbmRsZV9zaXplKTsKLQotICAgICAgICAgICAgICAvKiBwb3AgdGhlIGhhbmRsZSBvZmYgdGhlIHN0YWNrICovCi0gICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaGFuZGxlX3NpemU7IGkrKykKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICBzdGFjay5wb3AoKTsKLSAgICAgICAgICAgICAgICAgIHRvcy0tOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAvKiBsb29rIHVwIHRoZSBzdGF0ZSB0byBnbyB0byBmcm9tIHRoZSBvbmUgcG9wcGVkIGJhY2sgdG8gKi8KLSAgICAgICAgICAgICAgYWN0ID0gZ2V0X3JlZHVjZSgoKFN5bWJvbClzdGFjay5wZWVrKCkpLnBhcnNlX3N0YXRlLCBsaHNfc3ltX251bSk7Ci0gICAgICAgICAgICAgIGRlYnVnX21lc3NhZ2UoIiMgUmVkdWNlIHJ1bGU6IHRvcCBzdGF0ZSAiICsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKChTeW1ib2wpc3RhY2sucGVlaygpKS5wYXJzZV9zdGF0ZSArCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICIsIGxocyBzeW0gIiArIGxoc19zeW1fbnVtICsgIiAtPiBzdGF0ZSAiICsgYWN0KTsKLQotICAgICAgICAgICAgICAvKiBzaGlmdCB0byB0aGF0IHN0YXRlICovCi0gICAgICAgICAgICAgIGxoc19zeW0ucGFyc2Vfc3RhdGUgPSBhY3Q7Ci0gICAgICAgICAgICAgIGxoc19zeW0udXNlZF9ieV9wYXJzZXIgPSB0cnVlOwotICAgICAgICAgICAgICBzdGFjay5wdXNoKGxoc19zeW0pOwotICAgICAgICAgICAgICB0b3MrKzsKLQotICAgICAgICAgICAgICBkZWJ1Z19tZXNzYWdlKCIjIEdvdG8gc3RhdGUgIyIgKyBhY3QpOwotICAgICAgICAgICAgfQotICAgICAgICAgIC8qIGZpbmFsbHkgaWYgdGhlIGVudHJ5IGlzIHplcm8sIHdlIGhhdmUgYW4gZXJyb3IgKi8KLSAgICAgICAgICBlbHNlIGlmIChhY3QgPT0gMCkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgLyogY2FsbCB1c2VyIHN5bnRheCBlcnJvciByZXBvcnRpbmcgcm91dGluZSAqLwotICAgICAgICAgICAgICBzeW50YXhfZXJyb3IoY3VyX3Rva2VuKTsKLQotICAgICAgICAgICAgICAvKiB0cnkgdG8gZXJyb3IgcmVjb3ZlciAqLwotICAgICAgICAgICAgICBpZiAoIWVycm9yX3JlY292ZXJ5KHRydWUpKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgIC8qIGlmIHRoYXQgZmFpbHMgZ2l2ZSB1cCB3aXRoIGEgZmF0YWwgc3ludGF4IGVycm9yICovCi0gICAgICAgICAgICAgICAgICB1bnJlY292ZXJlZF9zeW50YXhfZXJyb3IoY3VyX3Rva2VuKTsKLQotICAgICAgICAgICAgICAgICAgLyoganVzdCBpbiBjYXNlIHRoYXQgd2Fzbid0IGZhdGFsIGVub3VnaCwgZW5kIHBhcnNlICovCi0gICAgICAgICAgICAgICAgICBkb25lX3BhcnNpbmcoKTsKLSAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgbGhzX3N5bSA9IChTeW1ib2wpc3RhY2sucGVlaygpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgcmV0dXJuIGxoc19zeW07Ci0gICAgfQotCi0gIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotICAvKiBFcnJvciByZWNvdmVyeSBjb2RlICovCi0gIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotCi0gIC8qKiBBdHRlbXB0IHRvIHJlY292ZXIgZnJvbSBhIHN5bnRheCBlcnJvci4gIFRoaXMgcmV0dXJucyBmYWxzZSBpZiByZWNvdmVyeQotICAgKiAgZmFpbHMsIHRydWUgaWYgaXQgc3VjY2VlZHMuICBSZWNvdmVyeSBoYXBwZW5zIGluIDQgc3RlcHMuICBGaXJzdCB3ZQotICAgKiAgcG9wIHRoZSBwYXJzZSBzdGFjayBkb3duIHRvIGEgcG9pbnQgYXQgd2hpY2ggd2UgaGF2ZSBhIHNoaWZ0IG91dAotICAgKiAgb2YgdGhlIHRvcC1tb3N0IHN0YXRlIG9uIHRoZSBlcnJvciBTeW1ib2wuICBUaGlzIHJlcHJlc2VudHMgdGhlCi0gICAqICBpbml0aWFsIGVycm9yIHJlY292ZXJ5IGNvbmZpZ3VyYXRpb24uICBJZiBubyBzdWNoIGNvbmZpZ3VyYXRpb24gaXMKLSAgICogIGZvdW5kLCB0aGVuIHdlIGZhaWwuICBOZXh0IGEgc21hbGwgbnVtYmVyIG9mICJsb29rYWhlYWQiIG9yICJwYXJzZQotICAgKiAgYWhlYWQiIFN5bWJvbHMgYXJlIHJlYWQgaW50byBhIGJ1ZmZlci4gIFRoZSBzaXplIG9mIHRoaXMgYnVmZmVyIGlzCi0gICAqICBkZXRlcm1pbmVkIGJ5IGVycm9yX3N5bmNfc2l6ZSgpIGFuZCBkZXRlcm1pbmVzIGhvdyBtYW55IFN5bWJvbHMgYmV5b25kCi0gICAqICB0aGUgZXJyb3IgbXVzdCBiZSBtYXRjaGVkIHRvIGNvbnNpZGVyIHRoZSByZWNvdmVyeSBhIHN1Y2Nlc3MuICBOZXh0LAotICAgKiAgd2UgYmVnaW4gdG8gZGlzY2FyZCBTeW1ib2xzIGluIGF0dGVtcHQgdG8gZ2V0IHBhc3QgdGhlIHBvaW50IG9mIGVycm9yCi0gICAqICB0byBhIHBvaW50IHdoZXJlIHdlIGNhbiBjb250aW51ZSBwYXJzaW5nLiAgQWZ0ZXIgZWFjaCBTeW1ib2wsIHdlIGF0dGVtcHQKLSAgICogIHRvICJwYXJzZSBhaGVhZCIgdGhvdWdoIHRoZSBidWZmZXJlZCBsb29rYWhlYWQgU3ltYm9scy4gIFRoZSAicGFyc2UgYWhlYWQiCi0gICAqICBwcm9jZXNzIHNpbXVsYXRlcyB0aGF0IGFjdHVhbCBwYXJzZSwgYnV0IGRvZXMgbm90IG1vZGlmeSB0aGUgcmVhbAotICAgKiAgcGFyc2VyJ3MgY29uZmlndXJhdGlvbiwgbm9yIGV4ZWN1dGUgYW55IGFjdGlvbnMuIElmIHdlIGNhbiAgcGFyc2UgYWxsCi0gICAqICB0aGUgc3RvcmVkIFN5bWJvbHMgd2l0aG91dCBlcnJvciwgdGhlbiB0aGUgcmVjb3ZlcnkgaXMgY29uc2lkZXJlZCBhCi0gICAqICBzdWNjZXNzLiAgT25jZSBhIHN1Y2Nlc3NmdWwgcmVjb3ZlcnkgcG9pbnQgaXMgZGV0ZXJtaW5lZCwgd2UgZG8gYW4KLSAgICogIGFjdHVhbCBwYXJzZSBvdmVyIHRoZSBzdG9yZWQgaW5wdXQgLS0gbW9kaWZ5aW5nIHRoZSByZWFsIHBhcnNlCi0gICAqICBjb25maWd1cmF0aW9uIGFuZCBleGVjdXRpbmcgYWxsIGFjdGlvbnMuICBGaW5hbGx5LCB3ZSByZXR1cm4gdGhlIHRoZQotICAgKiAgbm9ybWFsIHBhcnNlciB0byBjb250aW51ZSB3aXRoIHRoZSBvdmVyYWxsIHBhcnNlLgotICAgKgotICAgKiBAcGFyYW0gZGVidWcgc2hvdWxkIHdlIHByb2R1Y2UgZGVidWdnaW5nIG1lc3NhZ2VzIGFzIHdlIHBhcnNlLgotICAgKi8KLSAgcHJvdGVjdGVkIGJvb2xlYW4gZXJyb3JfcmVjb3ZlcnkoYm9vbGVhbiBkZWJ1ZykKLSAgICB0aHJvd3MgamF2YS5sYW5nLkV4Y2VwdGlvbgotICAgIHsKLSAgICAgIGlmIChkZWJ1ZykgZGVidWdfbWVzc2FnZSgiIyBBdHRlbXB0aW5nIGVycm9yIHJlY292ZXJ5Iik7Ci0KLSAgICAgIC8qIGZpcnN0IHBvcCB0aGUgc3RhY2sgYmFjayBpbnRvIGEgc3RhdGUgdGhhdCBjYW4gc2hpZnQgb24gZXJyb3IgYW5kCi0gICAgICAgICBkbyB0aGF0IHNoaWZ0IChpZiB0aGF0IGZhaWxzLCB3ZSBmYWlsKSAqLwotICAgICAgaWYgKCFmaW5kX3JlY292ZXJ5X2NvbmZpZyhkZWJ1ZykpCi0gICAgICAgIHsKLSAgICAgICAgICBpZiAoZGVidWcpIGRlYnVnX21lc3NhZ2UoIiMgRXJyb3IgcmVjb3ZlcnkgZmFpbHMiKTsKLSAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLQotICAgICAgLyogcmVhZCBhaGVhZCB0byBjcmVhdGUgbG9va2FoZWFkIHdlIGNhbiBwYXJzZSBtdWx0aXBsZSB0aW1lcyAqLwotICAgICAgcmVhZF9sb29rYWhlYWQoKTsKLQotICAgICAgLyogcmVwZWF0ZWRseSB0cnkgdG8gcGFyc2UgZm9yd2FyZCB1bnRpbCB3ZSBtYWtlIGl0IHRoZSByZXF1aXJlZCBkaXN0ICovCi0gICAgICBmb3IgKDs7KQotICAgICAgICB7Ci0gICAgICAgICAgLyogdHJ5IHRvIHBhcnNlIGZvcndhcmQsIGlmIGl0IG1ha2VzIGl0LCBiYWlsIG91dCBvZiBsb29wICovCi0gICAgICAgICAgaWYgKGRlYnVnKSBkZWJ1Z19tZXNzYWdlKCIjIFRyeWluZyB0byBwYXJzZSBhaGVhZCIpOwotICAgICAgICAgIGlmICh0cnlfcGFyc2VfYWhlYWQoZGVidWcpKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgIC8qIGlmIHdlIGFyZSBub3cgYXQgRU9GLCB3ZSBoYXZlIGZhaWxlZCAqLwotICAgICAgICAgIGlmIChsb29rYWhlYWRbMF0uc3ltID09IEVPRl9zeW0oKSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgaWYgKGRlYnVnKSBkZWJ1Z19tZXNzYWdlKCIjIEVycm9yIHJlY292ZXJ5IGZhaWxzIGF0IEVPRiIpOwotICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAvKiBvdGhlcndpc2UsIHdlIGNvbnN1bWUgYW5vdGhlciBTeW1ib2wgYW5kIHRyeSBhZ2FpbiAqLwotICAgICAgICAgIGlmIChkZWJ1ZykKLSAgICAgICAgICBkZWJ1Z19tZXNzYWdlKCIjIENvbnN1bWluZyBTeW1ib2wgIyIgKyBjdXJfZXJyX3Rva2VuKCkuc3ltKTsKLSAgICAgICAgICByZXN0YXJ0X2xvb2thaGVhZCgpOwotICAgICAgICB9Ci0KLSAgICAgIC8qIHdlIGhhdmUgY29uc3VtZWQgdG8gYSBwb2ludCB3aGVyZSB3ZSBjYW4gcGFyc2UgZm9yd2FyZCAqLwotICAgICAgaWYgKGRlYnVnKSBkZWJ1Z19tZXNzYWdlKCIjIFBhcnNlLWFoZWFkIG9rLCBnb2luZyBiYWNrIHRvIG5vcm1hbCBwYXJzZSIpOwotCi0gICAgICAvKiBkbyB0aGUgcmVhbCBwYXJzZSAoaW5jbHVkaW5nIGFjdGlvbnMpIGFjcm9zcyB0aGUgbG9va2FoZWFkICovCi0gICAgICBwYXJzZV9sb29rYWhlYWQoZGVidWcpOwotCi0gICAgICAvKiB3ZSBoYXZlIHN1Y2Nlc3MgKi8KLSAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuKi8KLQotICAvKiogRGV0ZXJtaW5lIGlmIHdlIGNhbiBzaGlmdCB1bmRlciB0aGUgc3BlY2lhbCBlcnJvciBTeW1ib2wgb3V0IG9mIHRoZQotICAgKiAgc3RhdGUgY3VycmVudGx5IG9uIHRoZSB0b3Agb2YgdGhlIChyZWFsKSBwYXJzZSBzdGFjay4KLSAgICovCi0gIHByb3RlY3RlZCBib29sZWFuIHNoaWZ0X3VuZGVyX2Vycm9yKCkKLSAgICB7Ci0gICAgICAvKiBpcyB0aGVyZSBhIHNoaWZ0IHVuZGVyIGVycm9yIFN5bWJvbCAqLwotICAgICAgcmV0dXJuIGdldF9hY3Rpb24oKChTeW1ib2wpc3RhY2sucGVlaygpKS5wYXJzZV9zdGF0ZSwgZXJyb3Jfc3ltKCkpID4gMDsKLSAgICB9Ci0KLSAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0KLSAgLyoqIFB1dCB0aGUgKHJlYWwpIHBhcnNlIHN0YWNrIGludG8gZXJyb3IgcmVjb3ZlcnkgY29uZmlndXJhdGlvbiBieQotICAgKiAgcG9wcGluZyB0aGUgc3RhY2sgZG93biB0byBhIHN0YXRlIHRoYXQgY2FuIHNoaWZ0IG9uIHRoZSBzcGVjaWFsCi0gICAqICBlcnJvciBTeW1ib2wsIHRoZW4gZG9pbmcgdGhlIHNoaWZ0LiAgSWYgbm8gc3VpdGFibGUgc3RhdGUgZXhpc3RzIG9uCi0gICAqICB0aGUgc3RhY2sgd2UgcmV0dXJuIGZhbHNlCi0gICAqCi0gICAqIEBwYXJhbSBkZWJ1ZyBzaG91bGQgd2UgcHJvZHVjZSBkZWJ1Z2dpbmcgbWVzc2FnZXMgYXMgd2UgcGFyc2UuCi0gICAqLwotICBwcm90ZWN0ZWQgYm9vbGVhbiBmaW5kX3JlY292ZXJ5X2NvbmZpZyhib29sZWFuIGRlYnVnKQotICAgIHsKLSAgICAgIFN5bWJvbCBlcnJvcl90b2tlbjsKLSAgICAgIGludCBhY3Q7Ci0KLSAgICAgIGlmIChkZWJ1ZykgZGVidWdfbWVzc2FnZSgiIyBGaW5kaW5nIHJlY292ZXJ5IHN0YXRlIG9uIHN0YWNrIik7Ci0KLSAgICAgIC8qIFJlbWVtYmVyIHRoZSByaWdodC1wb3NpdGlvbiBvZiB0aGUgdG9wIHN5bWJvbCBvbiB0aGUgc3RhY2sgKi8KLSAgICAgIGludCByaWdodF9wb3MgPSAoKFN5bWJvbClzdGFjay5wZWVrKCkpLnJpZ2h0OwotICAgICAgaW50IGxlZnRfcG9zICA9ICgoU3ltYm9sKXN0YWNrLnBlZWsoKSkubGVmdDsKLQotICAgICAgLyogcG9wIGRvd24gdW50aWwgd2UgY2FuIHNoaWZ0IHVuZGVyIGVycm9yIFN5bWJvbCAqLwotICAgICAgd2hpbGUgKCFzaGlmdF91bmRlcl9lcnJvcigpKQotICAgICAgICB7Ci0gICAgICAgICAgLyogcG9wIHRoZSBzdGFjayAqLwotICAgICAgICAgIGlmIChkZWJ1ZykKLSAgICAgICAgICAgIGRlYnVnX21lc3NhZ2UoIiMgUG9wIHN0YWNrIGJ5IG9uZSwgc3RhdGUgd2FzICMgIiArCi0gICAgICAgICAgICAgICAgICAgICAgICAgICgoU3ltYm9sKXN0YWNrLnBlZWsoKSkucGFyc2Vfc3RhdGUpOwotICAgICAgICAgIGxlZnRfcG9zID0gKChTeW1ib2wpc3RhY2sucG9wKCkpLmxlZnQ7Ci0gICAgICAgICAgdG9zLS07Ci0KLSAgICAgICAgICAvKiBpZiB3ZSBoYXZlIGhpdCBib3R0b20sIHdlIGZhaWwgKi8KLSAgICAgICAgICBpZiAoc3RhY2suZW1wdHkoKSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgaWYgKGRlYnVnKSBkZWJ1Z19tZXNzYWdlKCIjIE5vIHJlY292ZXJ5IHN0YXRlIGZvdW5kIG9uIHN0YWNrIik7Ci0gICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAvKiBzdGF0ZSBvbiB0b3Agb2YgdGhlIHN0YWNrIGNhbiBzaGlmdCB1bmRlciBlcnJvciwgZmluZCB0aGUgc2hpZnQgKi8KLSAgICAgIGFjdCA9IGdldF9hY3Rpb24oKChTeW1ib2wpc3RhY2sucGVlaygpKS5wYXJzZV9zdGF0ZSwgZXJyb3Jfc3ltKCkpOwotICAgICAgaWYgKGRlYnVnKQotICAgICAgICB7Ci0gICAgICAgICAgZGVidWdfbWVzc2FnZSgiIyBSZWNvdmVyIHN0YXRlIGZvdW5kICgjIiArCi0gICAgICAgICAgICAgICAgICAgICAgICAoKFN5bWJvbClzdGFjay5wZWVrKCkpLnBhcnNlX3N0YXRlICsgIikiKTsKLSAgICAgICAgICBkZWJ1Z19tZXNzYWdlKCIjIFNoaWZ0aW5nIG9uIGVycm9yIHRvIHN0YXRlICMiICsgKGFjdC0xKSk7Ci0gICAgICAgIH0KLQotICAgICAgLyogYnVpbGQgYW5kIHNoaWZ0IGEgc3BlY2lhbCBlcnJvciBTeW1ib2wgKi8KLSAgICAgIGVycm9yX3Rva2VuID0gbmV3IFN5bWJvbChlcnJvcl9zeW0oKSwgbGVmdF9wb3MsIHJpZ2h0X3Bvcyk7Ci0gICAgICBlcnJvcl90b2tlbi5wYXJzZV9zdGF0ZSA9IGFjdC0xOwotICAgICAgZXJyb3JfdG9rZW4udXNlZF9ieV9wYXJzZXIgPSB0cnVlOwotICAgICAgc3RhY2sucHVzaChlcnJvcl90b2tlbik7Ci0gICAgICB0b3MrKzsKLQotICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotCi0gIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotCi0gIC8qKiBMb29rYWhlYWQgU3ltYm9scyB1c2VkIGZvciBhdHRlbXB0aW5nIGVycm9yIHJlY292ZXJ5ICJwYXJzZSBhaGVhZHMiLiAqLwotICBwcm90ZWN0ZWQgU3ltYm9sIGxvb2thaGVhZFtdOwotCi0gIC8qKiBQb3NpdGlvbiBpbiBsb29rYWhlYWQgaW5wdXQgYnVmZmVyIHVzZWQgZm9yICJwYXJzZSBhaGVhZCIuICovCi0gIHByb3RlY3RlZCBpbnQgbG9va2FoZWFkX3BvczsKLQotICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuKi8KLQotICAvKiogUmVhZCBmcm9tIGlucHV0IHRvIGVzdGFibGlzaCBvdXIgYnVmZmVyIG9mICJwYXJzZSBhaGVhZCIgbG9va2FoZWFkCi0gICAqICBTeW1ib2xzLgotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgcmVhZF9sb29rYWhlYWQoKSB0aHJvd3MgamF2YS5sYW5nLkV4Y2VwdGlvbgotICAgIHsKLSAgICAgIC8qIGNyZWF0ZSB0aGUgbG9va2FoZWFkIGFycmF5ICovCi0gICAgICBsb29rYWhlYWQgPSBuZXcgU3ltYm9sW2Vycm9yX3N5bmNfc2l6ZSgpXTsKLQotICAgICAgLyogZmlsbCBpbiB0aGUgYXJyYXkgKi8KLSAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZXJyb3Jfc3luY19zaXplKCk7IGkrKykKLSAgICAgICAgewotICAgICAgICAgIGxvb2thaGVhZFtpXSA9IGN1cl90b2tlbjsKLSAgICAgICAgICBjdXJfdG9rZW4gPSBzY2FuKCk7Ci0gICAgICAgIH0KLQotICAgICAgLyogc3RhcnQgYXQgdGhlIGJlZ2lubmluZyAqLwotICAgICAgbG9va2FoZWFkX3BvcyA9IDA7Ci0gICAgfQotCi0gIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotCi0gIC8qKiBSZXR1cm4gdGhlIGN1cnJlbnQgbG9va2FoZWFkIGluIG91ciBlcnJvciAicGFyc2UgYWhlYWQiIGJ1ZmZlci4gKi8KLSAgcHJvdGVjdGVkIFN5bWJvbCBjdXJfZXJyX3Rva2VuKCkgeyByZXR1cm4gbG9va2FoZWFkW2xvb2thaGVhZF9wb3NdOyB9Ci0KLSAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0KLSAgLyoqIEFkdmFuY2UgdG8gbmV4dCAicGFyc2UgYWhlYWQiIGlucHV0IFN5bWJvbC4gUmV0dXJuIHRydWUgaWYgd2UgaGF2ZQotICAgKiAgaW5wdXQgdG8gYWR2YW5jZSB0bywgZmFsc2Ugb3RoZXJ3aXNlLgotICAgKi8KLSAgcHJvdGVjdGVkIGJvb2xlYW4gYWR2YW5jZV9sb29rYWhlYWQoKQotICAgIHsKLSAgICAgIC8qIGFkdmFuY2UgdGhlIGlucHV0IGxvY2F0aW9uICovCi0gICAgICBsb29rYWhlYWRfcG9zKys7Ci0KLSAgICAgIC8qIHJldHVybiB0cnVlIGlmIHdlIGRpZG4ndCBnbyBvZmYgdGhlIGVuZCAqLwotICAgICAgcmV0dXJuIGxvb2thaGVhZF9wb3MgPCBlcnJvcl9zeW5jX3NpemUoKTsKLSAgICB9Ci0KLSAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0KLSAgLyoqIFJlc2V0IHRoZSBwYXJzZSBhaGVhZCBpbnB1dCB0byBvbmUgU3ltYm9sIHBhc3Qgd2hlcmUgd2Ugc3RhcnRlZCBlcnJvcgotICAgKiAgcmVjb3ZlcnkgKHRoaXMgY29uc3VtZXMgb25lIG5ldyBTeW1ib2wgZnJvbSB0aGUgcmVhbCBpbnB1dCkuCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCByZXN0YXJ0X2xvb2thaGVhZCgpIHRocm93cyBqYXZhLmxhbmcuRXhjZXB0aW9uCi0gICAgewotICAgICAgLyogbW92ZSBhbGwgdGhlIGV4aXN0aW5nIGlucHV0IG92ZXIgKi8KLSAgICAgIGZvciAoaW50IGkgPSAxOyBpIDwgZXJyb3Jfc3luY19zaXplKCk7IGkrKykKLSAgICAgICAgbG9va2FoZWFkW2ktMV0gPSBsb29rYWhlYWRbaV07Ci0KLSAgICAgIC8qIHJlYWQgYSBuZXcgU3ltYm9sIGludG8gdGhlIGxhc3Qgc3BvdCAqLwotICAgICAgY3VyX3Rva2VuID0gc2NhbigpOwotICAgICAgbG9va2FoZWFkW2Vycm9yX3N5bmNfc2l6ZSgpLTFdID0gY3VyX3Rva2VuOwotCi0gICAgICAvKiByZXNldCBvdXIgaW50ZXJuYWwgcG9zaXRpb24gbWFya2VyICovCi0gICAgICBsb29rYWhlYWRfcG9zID0gMDsKLSAgICB9Ci0KLSAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0KLSAgLyoqIERvIGEgc2ltdWxhdGVkIHBhcnNlIGZvcndhcmQgKGEgInBhcnNlIGFoZWFkIikgZnJvbSB0aGUgY3VycmVudAotICAgKiAgc3RhY2sgY29uZmlndXJhdGlvbiB1c2luZyBzdG9yZWQgbG9va2FoZWFkIGlucHV0IGFuZCBhIHZpcnR1YWwgcGFyc2UKLSAgICogIHN0YWNrLiAgUmV0dXJuIHRydWUgaWYgd2UgbWFrZSBpdCBhbGwgdGhlIHdheSB0aHJvdWdoIHRoZSBzdG9yZWQKLSAgICogIGxvb2thaGVhZCBpbnB1dCB3aXRob3V0IGVycm9yLiBUaGlzIGJhc2ljYWxseSBzaW11bGF0ZXMgdGhlIGFjdGlvbiBvZgotICAgKiAgcGFyc2UoKSB1c2luZyBvbmx5IG91ciBzYXZlZCAicGFyc2UgYWhlYWQiIGlucHV0LCBhbmQgbm90IGV4ZWN1dGluZyBhbnkKLSAgICogIGFjdGlvbnMuCi0gICAqCi0gICAqIEBwYXJhbSBkZWJ1ZyBzaG91bGQgd2UgcHJvZHVjZSBkZWJ1Z2dpbmcgbWVzc2FnZXMgYXMgd2UgcGFyc2UuCi0gICAqLwotICBwcm90ZWN0ZWQgYm9vbGVhbiB0cnlfcGFyc2VfYWhlYWQoYm9vbGVhbiBkZWJ1ZykKLSAgICB0aHJvd3MgamF2YS5sYW5nLkV4Y2VwdGlvbgotICAgIHsKLSAgICAgIGludCBhY3Q7Ci0gICAgICBzaG9ydCBsaHMsIHJoc19zaXplOwotCi0gICAgICAvKiBjcmVhdGUgYSB2aXJ0dWFsIHN0YWNrIGZyb20gdGhlIHJlYWwgcGFyc2Ugc3RhY2sgKi8KLSAgICAgIHZpcnR1YWxfcGFyc2Vfc3RhY2sgdnN0YWNrID0gbmV3IHZpcnR1YWxfcGFyc2Vfc3RhY2soc3RhY2spOwotCi0gICAgICAvKiBwYXJzZSB1bnRpbCB3ZSBmYWlsIG9yIGdldCBwYXN0IHRoZSBsb29rYWhlYWQgaW5wdXQgKi8KLSAgICAgIGZvciAoOzspCi0gICAgICAgIHsKLSAgICAgICAgICAvKiBsb29rIHVwIHRoZSBhY3Rpb24gZnJvbSB0aGUgY3VycmVudCBzdGF0ZSAob24gdG9wIG9mIHN0YWNrKSAqLwotICAgICAgICAgIGFjdCA9IGdldF9hY3Rpb24odnN0YWNrLnRvcCgpLCBjdXJfZXJyX3Rva2VuKCkuc3ltKTsKLQotICAgICAgICAgIC8qIGlmIGl0cyBhbiBlcnJvciwgd2UgZmFpbCAqLwotICAgICAgICAgIGlmIChhY3QgPT0gMCkgcmV0dXJuIGZhbHNlOwotCi0gICAgICAgICAgLyogPiAwIGVuY29kZXMgYSBzaGlmdCAqLwotICAgICAgICAgIGlmIChhY3QgPiAwKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAvKiBwdXNoIHRoZSBuZXcgc3RhdGUgb24gdGhlIHN0YWNrICovCi0gICAgICAgICAgICAgIHZzdGFjay5wdXNoKGFjdC0xKTsKLQotICAgICAgICAgICAgICBpZiAoZGVidWcpIGRlYnVnX21lc3NhZ2UoIiMgUGFyc2UtYWhlYWQgc2hpZnRzIFN5bWJvbCAjIiArCi0gICAgICAgICAgICAgICAgICAgICAgIGN1cl9lcnJfdG9rZW4oKS5zeW0gKyAiIGludG8gc3RhdGUgIyIgKyAoYWN0LTEpKTsKLQotICAgICAgICAgICAgICAvKiBhZHZhbmNlIHNpbXVsYXRlZCBpbnB1dCwgaWYgd2UgcnVuIG9mZiB0aGUgZW5kLCB3ZSBhcmUgZG9uZSAqLwotICAgICAgICAgICAgICBpZiAoIWFkdmFuY2VfbG9va2FoZWFkKCkpIHJldHVybiB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICAgIC8qIDwgMCBlbmNvZGVzIGEgcmVkdWNlICovCi0gICAgICAgICAgZWxzZQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAvKiBpZiB0aGlzIGlzIGEgcmVkdWNlIHdpdGggdGhlIHN0YXJ0IHByb2R1Y3Rpb24gd2UgYXJlIGRvbmUgKi8KLSAgICAgICAgICAgICAgaWYgKCgtYWN0KS0xID09IHN0YXJ0X3Byb2R1Y3Rpb24oKSkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICBpZiAoZGVidWcpIGRlYnVnX21lc3NhZ2UoIiMgUGFyc2UtYWhlYWQgYWNjZXB0cyIpOwotICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgIC8qIGdldCB0aGUgbGhzIFN5bWJvbCBhbmQgdGhlIHJocyBzaXplICovCi0gICAgICAgICAgICAgIGxocyA9IHByb2R1Y3Rpb25fdGFiWygtYWN0KS0xXVswXTsKLSAgICAgICAgICAgICAgcmhzX3NpemUgPSBwcm9kdWN0aW9uX3RhYlsoLWFjdCktMV1bMV07Ci0KLSAgICAgICAgICAgICAgLyogcG9wIGhhbmRsZSBvZmYgdGhlIHN0YWNrICovCi0gICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmhzX3NpemU7IGkrKykKLSAgICAgICAgICAgICAgICB2c3RhY2sucG9wKCk7Ci0KLSAgICAgICAgICAgICAgaWYgKGRlYnVnKQotICAgICAgICAgICAgICAgIGRlYnVnX21lc3NhZ2UoIiMgUGFyc2UtYWhlYWQgcmVkdWNlczogaGFuZGxlIHNpemUgPSAiICsKLSAgICAgICAgICAgICAgICAgIHJoc19zaXplICsgIiBsaHMgPSAjIiArIGxocyArICIgZnJvbSBzdGF0ZSAjIiArIHZzdGFjay50b3AoKSk7Ci0KLSAgICAgICAgICAgICAgLyogbG9vayB1cCBnb3RvIGFuZCBwdXNoIGl0IG9udG8gdGhlIHN0YWNrICovCi0gICAgICAgICAgICAgIHZzdGFjay5wdXNoKGdldF9yZWR1Y2UodnN0YWNrLnRvcCgpLCBsaHMpKTsKLSAgICAgICAgICAgICAgaWYgKGRlYnVnKQotICAgICAgICAgICAgICAgIGRlYnVnX21lc3NhZ2UoIiMgR290byBzdGF0ZSAjIiArIHZzdGFjay50b3AoKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0KLSAgLyoqIFBhcnNlIGZvcndhcmQgdXNpbmcgc3RvcmVkIGxvb2thaGVhZCBTeW1ib2xzLiAgSW4gdGhpcyBjYXNlIHdlIGhhdmUKLSAgICogIGFscmVhZHkgdmVyaWZpZWQgdGhhdCBwYXJzaW5nIHdpbGwgbWFrZSBpdCB0aHJvdWdoIHRoZSBzdG9yZWQgbG9va2FoZWFkCi0gICAqICBTeW1ib2xzIGFuZCB3ZSBhcmUgbm93IGdldHRpbmcgYmFjayB0byB0aGUgcG9pbnQgYXQgd2hpY2ggd2UgY2FuIGhhbmQKLSAgICogIGNvbnRyb2wgYmFjayB0byB0aGUgbm9ybWFsIHBhcnNlci4gIENvbnNlcXVlbnRseSwgdGhpcyB2ZXJzaW9uIG9mIHRoZQotICAgKiAgcGFyc2VyIHBlcmZvcm1zIGFsbCBhY3Rpb25zIGFuZCBtb2RpZmllcyB0aGUgcmVhbCBwYXJzZSBjb25maWd1cmF0aW9uLgotICAgKiAgVGhpcyByZXR1cm5zIG9uY2Ugd2UgaGF2ZSBjb25zdW1lZCBhbGwgdGhlIHN0b3JlZCBpbnB1dCBvciB3ZSBhY2NlcHQuCi0gICAqCi0gICAqIEBwYXJhbSBkZWJ1ZyBzaG91bGQgd2UgcHJvZHVjZSBkZWJ1Z2dpbmcgbWVzc2FnZXMgYXMgd2UgcGFyc2UuCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBwYXJzZV9sb29rYWhlYWQoYm9vbGVhbiBkZWJ1ZykKLSAgICB0aHJvd3MgamF2YS5sYW5nLkV4Y2VwdGlvbgotICAgIHsKLSAgICAgIC8qIHRoZSBjdXJyZW50IGFjdGlvbiBjb2RlICovCi0gICAgICBpbnQgYWN0OwotCi0gICAgICAvKiB0aGUgU3ltYm9sL3N0YWNrIGVsZW1lbnQgcmV0dXJuZWQgYnkgYSByZWR1Y2UgKi8KLSAgICAgIFN5bWJvbCBsaHNfc3ltID0gbnVsbDsKLQotICAgICAgLyogaW5mb3JtYXRpb24gYWJvdXQgcHJvZHVjdGlvbiBiZWluZyByZWR1Y2VkIHdpdGggKi8KLSAgICAgIHNob3J0IGhhbmRsZV9zaXplLCBsaHNfc3ltX251bTsKLQotICAgICAgLyogcmVzdGFydCB0aGUgc2F2ZWQgaW5wdXQgYXQgdGhlIGJlZ2lubmluZyAqLwotICAgICAgbG9va2FoZWFkX3BvcyA9IDA7Ci0KLSAgICAgIGlmIChkZWJ1ZykKLSAgICAgICAgewotICAgICAgICAgIGRlYnVnX21lc3NhZ2UoIiMgUmVwYXJzaW5nIHNhdmVkIGlucHV0IHdpdGggYWN0aW9ucyIpOwotICAgICAgICAgIGRlYnVnX21lc3NhZ2UoIiMgQ3VycmVudCBTeW1ib2wgaXMgIyIgKyBjdXJfZXJyX3Rva2VuKCkuc3ltKTsKLSAgICAgICAgICBkZWJ1Z19tZXNzYWdlKCIjIEN1cnJlbnQgc3RhdGUgaXMgIyIgKwotICAgICAgICAgICAgICAgICAgICAgICAgKChTeW1ib2wpc3RhY2sucGVlaygpKS5wYXJzZV9zdGF0ZSk7Ci0gICAgICAgIH0KLQotICAgICAgLyogY29udGludWUgdW50aWwgd2UgYWNjZXB0IG9yIGhhdmUgcmVhZCBhbGwgbG9va2FoZWFkIGlucHV0ICovCi0gICAgICB3aGlsZSghX2RvbmVfcGFyc2luZykKLSAgICAgICAgewotICAgICAgICAgIC8qIGN1cnJlbnQgc3RhdGUgaXMgYWx3YXlzIG9uIHRoZSB0b3Agb2YgdGhlIHN0YWNrICovCi0KLSAgICAgICAgICAvKiBsb29rIHVwIGFjdGlvbiBvdXQgb2YgdGhlIGN1cnJlbnQgc3RhdGUgd2l0aCB0aGUgY3VycmVudCBpbnB1dCAqLwotICAgICAgICAgIGFjdCA9Ci0gICAgICAgICAgICBnZXRfYWN0aW9uKCgoU3ltYm9sKXN0YWNrLnBlZWsoKSkucGFyc2Vfc3RhdGUsIGN1cl9lcnJfdG9rZW4oKS5zeW0pOwotCi0gICAgICAgICAgLyogZGVjb2RlIHRoZSBhY3Rpb24gLS0gPiAwIGVuY29kZXMgc2hpZnQgKi8KLSAgICAgICAgICBpZiAoYWN0ID4gMCkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgLyogc2hpZnQgdG8gdGhlIGVuY29kZWQgc3RhdGUgYnkgcHVzaGluZyBpdCBvbiB0aGUgc3RhY2sgKi8KLSAgICAgICAgICAgICAgY3VyX2Vycl90b2tlbigpLnBhcnNlX3N0YXRlID0gYWN0LTE7Ci0gICAgICAgICAgICAgIGN1cl9lcnJfdG9rZW4oKS51c2VkX2J5X3BhcnNlciA9IHRydWU7Ci0gICAgICAgICAgICAgIGlmIChkZWJ1ZykgZGVidWdfc2hpZnQoY3VyX2Vycl90b2tlbigpKTsKLSAgICAgICAgICAgICAgc3RhY2sucHVzaChjdXJfZXJyX3Rva2VuKCkpOwotICAgICAgICAgICAgICB0b3MrKzsKLQotICAgICAgICAgICAgICAvKiBhZHZhbmNlIHRvIHRoZSBuZXh0IFN5bWJvbCwgaWYgdGhlcmUgaXMgbm9uZSwgd2UgYXJlIGRvbmUgKi8KLSAgICAgICAgICAgICAgaWYgKCFhZHZhbmNlX2xvb2thaGVhZCgpKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgIGlmIChkZWJ1ZykgZGVidWdfbWVzc2FnZSgiIyBDb21wbGV0ZWQgcmVwYXJzZSIpOwotCi0gICAgICAgICAgICAgICAgICAvKiBzY2FuIG5leHQgU3ltYm9sIHNvIHdlIGNhbiBjb250aW51ZSBwYXJzZSAqLwotICAgICAgICAgICAgICAgICAgLy8gQlVHRklYIGJ5IENocmlzIEhhcnJpcyA8Y2toYXJyaXNAdWNzZC5lZHU+OgotICAgICAgICAgICAgICAgICAgLy8gICBjb3JyZWN0IGEgb25lLW9mZiBlcnJvciBieSBjb21tZW50aW5nIG91dAotICAgICAgICAgICAgICAgICAgLy8gICB0aGlzIG5leHQgbGluZS4KLSAgICAgICAgICAgICAgICAgIC8qY3VyX3Rva2VuID0gc2NhbigpOyovCi0KLSAgICAgICAgICAgICAgICAgIC8qIGdvIGJhY2sgdG8gbm9ybWFsIHBhcnNlciAqLwotICAgICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICBpZiAoZGVidWcpCi0gICAgICAgICAgICAgICAgZGVidWdfbWVzc2FnZSgiIyBDdXJyZW50IFN5bWJvbCBpcyAjIiArIGN1cl9lcnJfdG9rZW4oKS5zeW0pOwotICAgICAgICAgICAgfQotICAgICAgICAgIC8qIGlmIGl0cyBsZXNzIHRoYW4gemVybywgdGhlbiBpdCBlbmNvZGVzIGEgcmVkdWNlIGFjdGlvbiAqLwotICAgICAgICAgIGVsc2UgaWYgKGFjdCA8IDApCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIC8qIHBlcmZvcm0gdGhlIGFjdGlvbiBmb3IgdGhlIHJlZHVjZSAqLwotICAgICAgICAgICAgICBsaHNfc3ltID0gZG9fYWN0aW9uKCgtYWN0KS0xLCB0aGlzLCBzdGFjaywgdG9zKTsKLQotICAgICAgICAgICAgICAvKiBsb29rIHVwIGluZm9ybWF0aW9uIGFib3V0IHRoZSBwcm9kdWN0aW9uICovCi0gICAgICAgICAgICAgIGxoc19zeW1fbnVtID0gcHJvZHVjdGlvbl90YWJbKC1hY3QpLTFdWzBdOwotICAgICAgICAgICAgICBoYW5kbGVfc2l6ZSA9IHByb2R1Y3Rpb25fdGFiWygtYWN0KS0xXVsxXTsKLQotICAgICAgICAgICAgICBpZiAoZGVidWcpIGRlYnVnX3JlZHVjZSgoLWFjdCktMSwgbGhzX3N5bV9udW0sIGhhbmRsZV9zaXplKTsKLQotICAgICAgICAgICAgICAvKiBwb3AgdGhlIGhhbmRsZSBvZmYgdGhlIHN0YWNrICovCi0gICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaGFuZGxlX3NpemU7IGkrKykKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICBzdGFjay5wb3AoKTsKLSAgICAgICAgICAgICAgICAgIHRvcy0tOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAvKiBsb29rIHVwIHRoZSBzdGF0ZSB0byBnbyB0byBmcm9tIHRoZSBvbmUgcG9wcGVkIGJhY2sgdG8gKi8KLSAgICAgICAgICAgICAgYWN0ID0gZ2V0X3JlZHVjZSgoKFN5bWJvbClzdGFjay5wZWVrKCkpLnBhcnNlX3N0YXRlLCBsaHNfc3ltX251bSk7Ci0KLSAgICAgICAgICAgICAgLyogc2hpZnQgdG8gdGhhdCBzdGF0ZSAqLwotICAgICAgICAgICAgICBsaHNfc3ltLnBhcnNlX3N0YXRlID0gYWN0OwotICAgICAgICAgICAgICBsaHNfc3ltLnVzZWRfYnlfcGFyc2VyID0gdHJ1ZTsKLSAgICAgICAgICAgICAgc3RhY2sucHVzaChsaHNfc3ltKTsKLSAgICAgICAgICAgICAgdG9zKys7Ci0KLSAgICAgICAgICAgICAgaWYgKGRlYnVnKSBkZWJ1Z19tZXNzYWdlKCIjIEdvdG8gc3RhdGUgIyIgKyBhY3QpOwotCi0gICAgICAgICAgICB9Ci0gICAgICAgICAgLyogZmluYWxseSBpZiB0aGUgZW50cnkgaXMgemVybywgd2UgaGF2ZSBhbiBlcnJvcgotICAgICAgICAgICAgIChzaG91bGRuJ3QgaGFwcGVuIGhlcmUsIGJ1dC4uLikqLwotICAgICAgICAgIGVsc2UgaWYgKGFjdCA9PSAwKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICByZXBvcnRfZmF0YWxfZXJyb3IoIlN5bnRheCBlcnJvciIsIGxoc19zeW0pOwotICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotCi0gICAgfQotCi0gIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwotCi0gIC8qKiBVdGlsaXR5IGZ1bmN0aW9uOiB1bnBhY2tzIHBhcnNlIHRhYmxlcyBmcm9tIHN0cmluZ3MgKi8KLSAgcHJvdGVjdGVkIHN0YXRpYyBzaG9ydFtdW10gdW5wYWNrRnJvbVN0cmluZ3MoU3RyaW5nW10gc2EpCi0gICAgewotICAgICAgLy8gQ29uY2F0YW5hdGUgaW5pdGlhbGl6YXRpb24gc3RyaW5ncy4KLSAgICAgIFN0cmluZ0J1ZmZlciBzYiA9IG5ldyBTdHJpbmdCdWZmZXIoc2FbMF0pOwotICAgICAgZm9yIChpbnQgaT0xOyBpPHNhLmxlbmd0aDsgaSsrKQotICAgICAgICBzYi5hcHBlbmQoc2FbaV0pOwotICAgICAgaW50IG49MDsgLy8gbG9jYXRpb24gaW4gaW5pdGlhbGl6YXRpb24gc3RyaW5nCi0gICAgICBpbnQgc2l6ZTEgPSAoKChpbnQpc2IuY2hhckF0KG4pKTw8MTYpIHwgKChpbnQpc2IuY2hhckF0KG4rMSkpOyBuKz0yOwotICAgICAgc2hvcnRbXVtdIHJlc3VsdCA9IG5ldyBzaG9ydFtzaXplMV1bXTsKLSAgICAgIGZvciAoaW50IGk9MDsgaTxzaXplMTsgaSsrKSB7Ci0gICAgICAgIGludCBzaXplMiA9ICgoKGludClzYi5jaGFyQXQobikpPDwxNikgfCAoKGludClzYi5jaGFyQXQobisxKSk7IG4rPTI7Ci0gICAgICAgIHJlc3VsdFtpXSA9IG5ldyBzaG9ydFtzaXplMl07Ci0gICAgICAgIGZvciAoaW50IGo9MDsgajxzaXplMjsgaisrKQotICAgICAgICAgIHJlc3VsdFtpXVtqXSA9IChzaG9ydCkgKHNiLmNoYXJBdChuKyspLTIpOwotICAgICAgfQotICAgICAgcmV0dXJuIHJlc3VsdDsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9qYXZhX2N1cC9pbnRlcm5hbC9ydW50aW1lL3ZpcnR1YWxfcGFyc2Vfc3RhY2suamF2YSBiL3NyYy9jb20vc3VuL2phdmFfY3VwL2ludGVybmFsL3J1bnRpbWUvdmlydHVhbF9wYXJzZV9zdGFjay5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA5MzgyNGM4Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL2phdmFfY3VwL2ludGVybmFsL3J1bnRpbWUvdmlydHVhbF9wYXJzZV9zdGFjay5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTY5ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDMsIDIwMDUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLQotcGFja2FnZSBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWU7Ci0KLWltcG9ydCBqYXZhLnV0aWwuU3RhY2s7Ci0KLS8qKiBUaGlzIGNsYXNzIGltcGxlbWVudHMgYSB0ZW1wb3Jhcnkgb3IgInZpcnR1YWwiIHBhcnNlIHN0YWNrIHRoYXQKLSAqICByZXBsYWNlcyB0aGUgdG9wIHBvcnRpb24gb2YgdGhlIGFjdHVhbCBwYXJzZSBzdGFjayAodGhlIHBhcnQgdGhhdAotICogIGhhcyBiZWVuIGNoYW5nZWQgYnkgc29tZSBzZXQgb2Ygb3BlcmF0aW9ucykgd2hpbGUgbWFpbnRhaW5pbmcgaXRzCi0gKiAgb3JpZ2luYWwgY29udGVudHMuICBUaGlzIGRhdGEgc3RydWN0dXJlIGlzIHVzZWQgd2hlbiB0aGUgcGFyc2UgbmVlZHMKLSAqICB0byAicGFyc2UgYWhlYWQiIHRvIGRldGVybWluZSBpZiBhIGdpdmVuIGVycm9yIHJlY292ZXJ5IGF0dGVtcHQgd2lsbAotICogIGFsbG93IHRoZSBwYXJzZSB0byBjb250aW51ZSBmYXIgZW5vdWdoIHRvIGNvbnNpZGVyIGl0IHN1Y2Nlc3NmdWwuICBPbmNlCi0gKiAgc3VjY2VzcyBvciBmYWlsdXJlIG9mIHBhcnNlIGFoZWFkIGlzIGRldGVybWluZWQgdGhlIHN5c3RlbSB0aGVuCi0gKiAgcmV2ZXJ0cyB0byB0aGUgb3JpZ2luYWwgcGFyc2Ugc3RhY2sgKHdoaWNoIGhhcyBub3QgYWN0dWFsbHkgYmVlbgotICogIG1vZGlmaWVkKS4gIFNpbmNlIHBhcnNlIGFoZWFkIGRvZXMgbm90IGV4ZWN1dGUgYWN0aW9ucywgb25seSBwYXJzZQotICogIHN0YXRlIGlzIG1haW50YWluZWQgb24gdGhlIHZpcnR1YWwgc3RhY2ssIG5vdCBmdWxsIFN5bWJvbCBvYmplY3RzLgotICoKLSAqIEBzZWUgICAgIGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5scl9wYXJzZXIKLSAqIEBhdXRob3IgIEZyYW5rIEZsYW5uZXJ5Ci0gKi8KLQotcHVibGljIGNsYXNzIHZpcnR1YWxfcGFyc2Vfc3RhY2sgewotICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KLSAgLyotLS0gQ29uc3RydWN0b3IocykgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCi0gIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwotCi0gIC8qKiBDb25zdHJ1Y3RvciB0byBidWlsZCBhIHZpcnR1YWwgc3RhY2sgb3V0IG9mIGEgcmVhbCBzdGFjay4gKi8KLSAgcHVibGljIHZpcnR1YWxfcGFyc2Vfc3RhY2soU3RhY2sgc2hhZG93aW5nX3N0YWNrKSB0aHJvd3MgamF2YS5sYW5nLkV4Y2VwdGlvbgotICAgIHsKLSAgICAgIC8qIHNhbml0eSBjaGVjayAqLwotICAgICAgaWYgKHNoYWRvd2luZ19zdGFjayA9PSBudWxsKQotICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKAotICAgICAgICAgICJJbnRlcm5hbCBwYXJzZXIgZXJyb3I6IGF0dGVtcHQgdG8gY3JlYXRlIG51bGwgdmlydHVhbCBzdGFjayIpOwotCi0gICAgICAvKiBzZXQgdXAgb3VyIGludGVybmFscyAqLwotICAgICAgcmVhbF9zdGFjayA9IHNoYWRvd2luZ19zdGFjazsKLSAgICAgIHZzdGFjayAgICAgPSBuZXcgU3RhY2soKTsKLSAgICAgIHJlYWxfbmV4dCAgPSAwOwotCi0gICAgICAvKiBnZXQgb25lIGVsZW1lbnQgb250byB0aGUgdmlydHVhbCBwb3J0aW9uIG9mIHRoZSBzdGFjayAqLwotICAgICAgZ2V0X2Zyb21fcmVhbCgpOwotICAgIH0KLQotICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KLSAgLyotLS0gKEFjY2VzcyB0bykgSW5zdGFuY2UgVmFyaWFibGVzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCi0gIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwotCi0gIC8qKiBUaGUgcmVhbCBzdGFjayB0aGF0IHdlIHNoYWRvdy4gIFRoaXMgaXMgYWNjZXNzZWQgd2hlbiB3ZSBtb3ZlIG9mZgotICAgKiAgdGhlIGJvdHRvbSBvZiB0aGUgdmlydHVhbCBwb3J0aW9uIG9mIHRoZSBzdGFjaywgYnV0IGlzIGFsd2F5cyBsZWZ0Ci0gICAqICB1bm1vZGlmaWVkLgotICAgKi8KLSAgcHJvdGVjdGVkIFN0YWNrIHJlYWxfc3RhY2s7Ci0KLSAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0KLSAgLyoqIFRvcCBvZiBzdGFjayBpbmRpY2F0b3IgZm9yIHdoZXJlIHdlIGxlYXZlIG9mZiBpbiB0aGUgcmVhbCBzdGFjay4KLSAgICogIFRoaXMgaXMgbWVhc3VyZWQgZnJvbSB0b3Agb2Ygc3RhY2ssIHNvIDAgd291bGQgaW5kaWNhdGUgdGhhdCBubwotICAgKiAgZWxlbWVudHMgaGF2ZSBiZWVuICJtb3ZlZCIgZnJvbSB0aGUgcmVhbCB0byB2aXJ0dWFsIHN0YWNrLgotICAgKi8KLSAgcHJvdGVjdGVkIGludCByZWFsX25leHQ7Ci0KLSAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0KLSAgLyoqIFRoZSB2aXJ0dWFsIHRvcCBwb3J0aW9uIG9mIHRoZSBzdGFjay4gIFRoaXMgc3RhY2sgY29udGFpbnMgSW50ZWdlcgotICAgKiAgb2JqZWN0cyB3aXRoIHN0YXRlIG51bWJlcnMuICBUaGlzIHN0YWNrIHNoYWRvd3MgdGhlIHRvcCBwb3J0aW9uCi0gICAqICBvZiB0aGUgcmVhbCBzdGFjayB3aXRoaW4gdGhlIGFyZWEgdGhhdCBoYXMgYmVlbiBtb2RpZmllZCAodmlhIG9wZXJhdGlvbnMKLSAgICogIG9uIHRoZSB2aXJ0dWFsIHN0YWNrKS4gIFdoZW4gdGhpcyBwb3J0aW9uIG9mIHRoZSBzdGFjayBiZWNvbWVzIGVtcHR5IHdlCi0gICAqICB0cmFuc2ZlciBlbGVtZW50cyBmcm9tIHRoZSB1bmRlcmx5aW5nIHN0YWNrIG9udG8gdGhpcyBzdGFjay4KLSAgICovCi0gIHByb3RlY3RlZCBTdGFjayB2c3RhY2s7Ci0KLSAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCi0gIC8qLS0tIEdlbmVyYWwgTWV0aG9kcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwotICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KLQotICAvKiogVHJhbnNmZXIgYW4gZWxlbWVudCBmcm9tIHRoZSByZWFsIHRvIHRoZSB2aXJ0dWFsIHN0YWNrLiAgVGhpcyBhc3N1bWVzCi0gICAqICB0aGF0IHRoZSB2aXJ0dWFsIHN0YWNrIGlzIGN1cnJlbnRseSBlbXB0eS4KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIGdldF9mcm9tX3JlYWwoKQotICAgIHsKLSAgICAgIFN5bWJvbCBzdGFja19zeW07Ci0KLSAgICAgIC8qIGRvbid0IHRyYW5zZmVyIGlmIHRoZSByZWFsIHN0YWNrIGlzIGVtcHR5ICovCi0gICAgICBpZiAocmVhbF9uZXh0ID49IHJlYWxfc3RhY2suc2l6ZSgpKSByZXR1cm47Ci0KLSAgICAgIC8qIGdldCBhIGNvcHkgb2YgdGhlIGZpcnN0IFN5bWJvbCB3ZSBoYXZlIG5vdCB0cmFuc2ZlcmVkICovCi0gICAgICBzdGFja19zeW0gPSAoU3ltYm9sKXJlYWxfc3RhY2suZWxlbWVudEF0KHJlYWxfc3RhY2suc2l6ZSgpLTEtcmVhbF9uZXh0KTsKLQotICAgICAgLyogcmVjb3JkIHRoZSB0cmFuc2ZlciAqLwotICAgICAgcmVhbF9uZXh0Kys7Ci0KLSAgICAgIC8qIHB1dCB0aGUgc3RhdGUgbnVtYmVyIGZyb20gdGhlIFN5bWJvbCBvbnRvIHRoZSB2aXJ0dWFsIHN0YWNrICovCi0gICAgICB2c3RhY2sucHVzaChuZXcgSW50ZWdlcihzdGFja19zeW0ucGFyc2Vfc3RhdGUpKTsKLSAgICB9Ci0KLSAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0KLSAgLyoqIEluZGljYXRlIHdoZXRoZXIgdGhlIHN0YWNrIGlzIGVtcHR5LiAqLwotICBwdWJsaWMgYm9vbGVhbiBlbXB0eSgpCi0gICAgewotICAgICAgLyogaWYgdnN0YWNrIGlzIGVtcHR5IHRoZW4gd2Ugd2VyZSB1bmFibGUgdG8gdHJhbnNmZXIgb250byBpdCBhbmQKLSAgICAgICAgIHRoZSB3aG9sZSB0aGluZyBpcyBlbXB0eS4gKi8KLSAgICAgIHJldHVybiB2c3RhY2suZW1wdHkoKTsKLSAgICB9Ci0KLSAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0KLSAgLyoqIFJldHVybiB2YWx1ZSBvbiB0aGUgdG9wIG9mIHRoZSBzdGFjayAod2l0aG91dCBwb3BwaW5nIGl0KS4gKi8KLSAgcHVibGljIGludCB0b3AoKSB0aHJvd3MgamF2YS5sYW5nLkV4Y2VwdGlvbgotICAgIHsKLSAgICAgIGlmICh2c3RhY2suZW1wdHkoKSkKLSAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICJJbnRlcm5hbCBwYXJzZXIgZXJyb3I6IHRvcCgpIGNhbGxlZCBvbiBlbXB0eSB2aXJ0dWFsIHN0YWNrIik7Ci0KLSAgICAgIHJldHVybiAoKEludGVnZXIpdnN0YWNrLnBlZWsoKSkuaW50VmFsdWUoKTsKLSAgICB9Ci0KLSAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0KLSAgLyoqIFBvcCB0aGUgc3RhY2suICovCi0gIHB1YmxpYyB2b2lkIHBvcCgpIHRocm93cyBqYXZhLmxhbmcuRXhjZXB0aW9uCi0gICAgewotICAgICAgaWYgKHZzdGFjay5lbXB0eSgpKQotICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgIkludGVybmFsIHBhcnNlciBlcnJvcjogcG9wIGZyb20gZW1wdHkgdmlydHVhbCBzdGFjayIpOwotCi0gICAgICAvKiBwb3AgaXQgKi8KLSAgICAgIHZzdGFjay5wb3AoKTsKLQotICAgICAgLyogaWYgd2UgYXJlIG5vdyBlbXB0eSB0cmFuc2ZlciBhbiBlbGVtZW50IChpZiB0aGVyZSBpcyBvbmUpICovCi0gICAgICBpZiAodnN0YWNrLmVtcHR5KCkpCi0gICAgICAgIGdldF9mcm9tX3JlYWwoKTsKLSAgICB9Ci0KLSAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0KLSAgLyoqIFB1c2ggYSBzdGF0ZSBudW1iZXIgb250byB0aGUgc3RhY2suICovCi0gIHB1YmxpYyB2b2lkIHB1c2goaW50IHN0YXRlX251bSkKLSAgICB7Ci0gICAgICB2c3RhY2sucHVzaChuZXcgSW50ZWdlcihzdGF0ZV9udW0pKTsKLSAgICB9Ci0KLSAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCi0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9Db25zdGFudHMuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9Db25zdGFudHMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZDdmYzZiYy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvQ29uc3RhbnRzLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3OTAgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWw7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8qKgotICogQ29uc3RhbnRzIGZvciB0aGUgcHJvamVjdCwgbW9zdGx5IGRlZmluZWQgaW4gdGhlIEpWTSBzcGVjaWZpY2F0aW9uLgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgQ29uc3RhbnRzIHsKLSAgLyoqIE1ham9yIGFuZCBtaW5vciB2ZXJzaW9uIG9mIHRoZSBjb2RlLgotICAgKi8KLSAgcHVibGljIGZpbmFsIHN0YXRpYyBzaG9ydCBNQUpPUl8xXzEgPSA0NTsKLSAgcHVibGljIGZpbmFsIHN0YXRpYyBzaG9ydCBNSU5PUl8xXzEgPSAzOwotICBwdWJsaWMgZmluYWwgc3RhdGljIHNob3J0IE1BSk9SXzFfMiA9IDQ2OwotICBwdWJsaWMgZmluYWwgc3RhdGljIHNob3J0IE1JTk9SXzFfMiA9IDA7Ci0gIHB1YmxpYyBmaW5hbCBzdGF0aWMgc2hvcnQgTUFKT1JfMV8zID0gNDc7Ci0gIHB1YmxpYyBmaW5hbCBzdGF0aWMgc2hvcnQgTUlOT1JfMV8zID0gMDsKLSAgcHVibGljIGZpbmFsIHN0YXRpYyBzaG9ydCBNQUpPUiAgICAgPSBNQUpPUl8xXzE7IC8vIERlZmF1bHRzCi0gIHB1YmxpYyBmaW5hbCBzdGF0aWMgc2hvcnQgTUlOT1IgICAgID0gTUlOT1JfMV8xOwotCi0gIC8qKiBNYXhpbXVtIHZhbHVlIGZvciBhbiB1bnNpZ25lZCBzaG9ydC4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBzdGF0aWMgaW50IE1BWF9TSE9SVCA9IDY1NTM1OyAvLyAyXjE2IC0gMQotCi0gIC8qKiBNYXhpbXVtIHZhbHVlIGZvciBhbiB1bnNpZ25lZCBieXRlLgotICAgKi8KLSAgcHVibGljIGZpbmFsIHN0YXRpYyBpbnQgTUFYX0JZVEUgID0gMjU1OyAvLyAyXjggLSAxCi0KLSAgLyoqIEFjY2VzcyBmbGFncyBmb3IgY2xhc3NlcywgZmllbGRzIGFuZCBtZXRob2RzLgotICAgKi8KLSAgcHVibGljIGZpbmFsIHN0YXRpYyBzaG9ydCBBQ0NfUFVCTElDICAgICAgID0gMHgwMDAxOwotICBwdWJsaWMgZmluYWwgc3RhdGljIHNob3J0IEFDQ19QUklWQVRFICAgICAgPSAweDAwMDI7Ci0gIHB1YmxpYyBmaW5hbCBzdGF0aWMgc2hvcnQgQUNDX1BST1RFQ1RFRCAgICA9IDB4MDAwNDsKLSAgcHVibGljIGZpbmFsIHN0YXRpYyBzaG9ydCBBQ0NfU1RBVElDICAgICAgID0gMHgwMDA4OwotCi0gIHB1YmxpYyBmaW5hbCBzdGF0aWMgc2hvcnQgQUNDX0ZJTkFMICAgICAgICA9IDB4MDAxMDsKLSAgcHVibGljIGZpbmFsIHN0YXRpYyBzaG9ydCBBQ0NfU1lOQ0hST05JWkVEID0gMHgwMDIwOwotICBwdWJsaWMgZmluYWwgc3RhdGljIHNob3J0IEFDQ19WT0xBVElMRSAgICAgPSAweDAwNDA7Ci0gIHB1YmxpYyBmaW5hbCBzdGF0aWMgc2hvcnQgQUNDX1RSQU5TSUVOVCAgICA9IDB4MDA4MDsKLQotICBwdWJsaWMgZmluYWwgc3RhdGljIHNob3J0IEFDQ19OQVRJVkUgICAgICAgPSAweDAxMDA7Ci0gIHB1YmxpYyBmaW5hbCBzdGF0aWMgc2hvcnQgQUNDX0lOVEVSRkFDRSAgICA9IDB4MDIwMDsKLSAgcHVibGljIGZpbmFsIHN0YXRpYyBzaG9ydCBBQ0NfQUJTVFJBQ1QgICAgID0gMHgwNDAwOwotICBwdWJsaWMgZmluYWwgc3RhdGljIHNob3J0IEFDQ19TVFJJQ1QgICAgICAgPSAweDA4MDA7Ci0KLSAgLy8gQXBwbGllcyB0byBjbGFzc2VzIGNvbXBpbGVkIGJ5IG5ldyBjb21waWxlcnMgb25seQotICBwdWJsaWMgZmluYWwgc3RhdGljIHNob3J0IEFDQ19TVVBFUiAgICAgICAgPSAweDAwMjA7Ci0KLSAgcHVibGljIGZpbmFsIHN0YXRpYyBzaG9ydCBNQVhfQUNDX0ZMQUcgICAgID0gQUNDX1NUUklDVDsKLQotICBwdWJsaWMgZmluYWwgc3RhdGljIFN0cmluZ1tdIEFDQ0VTU19OQU1FUyA9IHsKLSAgICAicHVibGljIiwgInByaXZhdGUiLCAicHJvdGVjdGVkIiwgInN0YXRpYyIsICJmaW5hbCIsICJzeW5jaHJvbml6ZWQiLAotICAgICJ2b2xhdGlsZSIsICJ0cmFuc2llbnQiLCAibmF0aXZlIiwgImludGVyZmFjZSIsICJhYnN0cmFjdCIsICJzdHJpY3RmcCIKLSAgfTsKLQotICAvKiogVGFncyBpbiBjb25zdGFudCBwb29sIHRvIGRlbm90ZSB0eXBlIG9mIGNvbnN0YW50LgotICAgKi8KLSAgcHVibGljIGZpbmFsIHN0YXRpYyBieXRlIENPTlNUQU5UX1V0ZjggICAgICAgICAgICAgICA9IDE7Ci0gIHB1YmxpYyBmaW5hbCBzdGF0aWMgYnl0ZSBDT05TVEFOVF9JbnRlZ2VyICAgICAgICAgICAgPSAzOwotICBwdWJsaWMgZmluYWwgc3RhdGljIGJ5dGUgQ09OU1RBTlRfRmxvYXQgICAgICAgICAgICAgID0gNDsKLSAgcHVibGljIGZpbmFsIHN0YXRpYyBieXRlIENPTlNUQU5UX0xvbmcgICAgICAgICAgICAgICA9IDU7Ci0gIHB1YmxpYyBmaW5hbCBzdGF0aWMgYnl0ZSBDT05TVEFOVF9Eb3VibGUgICAgICAgICAgICAgPSA2OwotICBwdWJsaWMgZmluYWwgc3RhdGljIGJ5dGUgQ09OU1RBTlRfQ2xhc3MgICAgICAgICAgICAgID0gNzsKLSAgcHVibGljIGZpbmFsIHN0YXRpYyBieXRlIENPTlNUQU5UX0ZpZWxkcmVmICAgICAgICAgICA9IDk7Ci0gIHB1YmxpYyBmaW5hbCBzdGF0aWMgYnl0ZSBDT05TVEFOVF9TdHJpbmcgICAgICAgICAgICAgPSA4OwotICBwdWJsaWMgZmluYWwgc3RhdGljIGJ5dGUgQ09OU1RBTlRfTWV0aG9kcmVmICAgICAgICAgID0gMTA7Ci0gIHB1YmxpYyBmaW5hbCBzdGF0aWMgYnl0ZSBDT05TVEFOVF9JbnRlcmZhY2VNZXRob2RyZWYgPSAxMTsKLSAgcHVibGljIGZpbmFsIHN0YXRpYyBieXRlIENPTlNUQU5UX05hbWVBbmRUeXBlICAgICAgICA9IDEyOwotCi0gIHB1YmxpYyBmaW5hbCBzdGF0aWMgU3RyaW5nW10gQ09OU1RBTlRfTkFNRVMgPSB7Ci0gICAgIiIsICJDT05TVEFOVF9VdGY4IiwgIiIsICJDT05TVEFOVF9JbnRlZ2VyIiwKLSAgICAiQ09OU1RBTlRfRmxvYXQiLCAiQ09OU1RBTlRfTG9uZyIsICJDT05TVEFOVF9Eb3VibGUiLAotICAgICJDT05TVEFOVF9DbGFzcyIsICJDT05TVEFOVF9TdHJpbmciLCAiQ09OU1RBTlRfRmllbGRyZWYiLAotICAgICJDT05TVEFOVF9NZXRob2RyZWYiLCAiQ09OU1RBTlRfSW50ZXJmYWNlTWV0aG9kcmVmIiwKLSAgICAiQ09OU1RBTlRfTmFtZUFuZFR5cGUiIH07Ci0KLSAgLyoqIFRoZSBuYW1lIG9mIHRoZSBzdGF0aWMgaW5pdGlhbGl6ZXIsIGFsc28gY2FsbGVkICZxdW90O2NsYXNzCi0gICAqICBpbml0aWFsaXphdGlvbiBtZXRob2QmcXVvdDsgb3IgJnF1b3Q7aW50ZXJmYWNlIGluaXRpYWxpemF0aW9uCi0gICAqICAgbWV0aG9kJnF1b3Q7LiBUaGlzIGlzICZxdW90OyZsdDtjbGluaXQmZ3Q7JnF1b3Q7LgotICAgKi8KLSAgcHVibGljIGZpbmFsIHN0YXRpYyBTdHJpbmcgU1RBVElDX0lOSVRJQUxJWkVSX05BTUUgPSAiPGNsaW5pdD4iOwotCi0gIC8qKiBUaGUgbmFtZSBvZiBldmVyeSBjb25zdHJ1Y3RvciBtZXRob2QgaW4gYSBjbGFzcywgYWxzbyBjYWxsZWQKLSAgICogJnF1b3Q7aW5zdGFuY2UgaW5pdGlhbGl6YXRpb24gbWV0aG9kJnF1b3Q7LiBUaGlzIGlzICZxdW90OyZsdDtpbml0Jmd0OyZxdW90Oy4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBzdGF0aWMgU3RyaW5nIENPTlNUUlVDVE9SX05BTUUgPSAiPGluaXQ+IjsKLQotICAvKiogVGhlIG5hbWVzIG9mIHRoZSBpbnRlcmZhY2VzIGltcGxlbWVudGVkIGJ5IGFycmF5cyAqLwotICBwdWJsaWMgZmluYWwgc3RhdGljIFN0cmluZ1tdIElOVEVSRkFDRVNfSU1QTEVNRU5URURfQllfQVJSQVlTID0geyJqYXZhLmxhbmcuQ2xvbmVhYmxlIiwgImphdmEuaW8uU2VyaWFsaXphYmxlIn07Ci0KLSAgLyoqCi0gICAqIExpbWl0YXRpb25zIG9mIHRoZSBKYXZhIFZpcnR1YWwgTWFjaGluZS4KLSAgICogU2VlIFRoZSBKYXZhIFZpcnR1YWwgTWFjaGluZSBTcGVjaWZpY2F0aW9uLCBTZWNvbmQgRWRpdGlvbiwgcGFnZSAxNTIsIGNoYXB0ZXIgNC4xMC4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BWF9DUF9FTlRSSUVTICAgICA9IDY1NTM1OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVhfQ09ERV9TSVpFICAgICAgPSA2NTUzNjsgLy9ieXRlcwotCi0gIC8qKiBKYXZhIFZNIG9wY29kZXMuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IE5PUCAgICAgICAgICAgICAgPSAwOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IEFDT05TVF9OVUxMICAgICAgPSAxOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IElDT05TVF9NMSAgICAgICAgPSAyOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IElDT05TVF8wICAgICAgICAgPSAzOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IElDT05TVF8xICAgICAgICAgPSA0OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IElDT05TVF8yICAgICAgICAgPSA1OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IElDT05TVF8zICAgICAgICAgPSA2OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IElDT05TVF80ICAgICAgICAgPSA3OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IElDT05TVF81ICAgICAgICAgPSA4OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IExDT05TVF8wICAgICAgICAgPSA5OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IExDT05TVF8xICAgICAgICAgPSAxMDsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBGQ09OU1RfMCAgICAgICAgID0gMTE7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgRkNPTlNUXzEgICAgICAgICA9IDEyOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IEZDT05TVF8yICAgICAgICAgPSAxMzsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBEQ09OU1RfMCAgICAgICAgID0gMTQ7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgRENPTlNUXzEgICAgICAgICA9IDE1OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IEJJUFVTSCAgICAgICAgICAgPSAxNjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBTSVBVU0ggICAgICAgICAgID0gMTc7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgTERDICAgICAgICAgICAgICA9IDE4OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IExEQ19XICAgICAgICAgICAgPSAxOTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBMREMyX1cgICAgICAgICAgID0gMjA7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgSUxPQUQgICAgICAgICAgICA9IDIxOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IExMT0FEICAgICAgICAgICAgPSAyMjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBGTE9BRCAgICAgICAgICAgID0gMjM7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgRExPQUQgICAgICAgICAgICA9IDI0OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IEFMT0FEICAgICAgICAgICAgPSAyNTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBJTE9BRF8wICAgICAgICAgID0gMjY7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgSUxPQURfMSAgICAgICAgICA9IDI3OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IElMT0FEXzIgICAgICAgICAgPSAyODsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBJTE9BRF8zICAgICAgICAgID0gMjk7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgTExPQURfMCAgICAgICAgICA9IDMwOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IExMT0FEXzEgICAgICAgICAgPSAzMTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBMTE9BRF8yICAgICAgICAgID0gMzI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgTExPQURfMyAgICAgICAgICA9IDMzOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IEZMT0FEXzAgICAgICAgICAgPSAzNDsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBGTE9BRF8xICAgICAgICAgID0gMzU7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgRkxPQURfMiAgICAgICAgICA9IDM2OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IEZMT0FEXzMgICAgICAgICAgPSAzNzsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBETE9BRF8wICAgICAgICAgID0gMzg7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgRExPQURfMSAgICAgICAgICA9IDM5OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IERMT0FEXzIgICAgICAgICAgPSA0MDsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBETE9BRF8zICAgICAgICAgID0gNDE7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgQUxPQURfMCAgICAgICAgICA9IDQyOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IEFMT0FEXzEgICAgICAgICAgPSA0MzsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBBTE9BRF8yICAgICAgICAgID0gNDQ7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgQUxPQURfMyAgICAgICAgICA9IDQ1OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IElBTE9BRCAgICAgICAgICAgPSA0NjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBMQUxPQUQgICAgICAgICAgID0gNDc7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgRkFMT0FEICAgICAgICAgICA9IDQ4OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IERBTE9BRCAgICAgICAgICAgPSA0OTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBBQUxPQUQgICAgICAgICAgID0gNTA7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgQkFMT0FEICAgICAgICAgICA9IDUxOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IENBTE9BRCAgICAgICAgICAgPSA1MjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBTQUxPQUQgICAgICAgICAgID0gNTM7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgSVNUT1JFICAgICAgICAgICA9IDU0OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IExTVE9SRSAgICAgICAgICAgPSA1NTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBGU1RPUkUgICAgICAgICAgID0gNTY7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgRFNUT1JFICAgICAgICAgICA9IDU3OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IEFTVE9SRSAgICAgICAgICAgPSA1ODsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBJU1RPUkVfMCAgICAgICAgID0gNTk7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgSVNUT1JFXzEgICAgICAgICA9IDYwOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IElTVE9SRV8yICAgICAgICAgPSA2MTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBJU1RPUkVfMyAgICAgICAgID0gNjI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgTFNUT1JFXzAgICAgICAgICA9IDYzOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IExTVE9SRV8xICAgICAgICAgPSA2NDsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBMU1RPUkVfMiAgICAgICAgID0gNjU7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgTFNUT1JFXzMgICAgICAgICA9IDY2OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IEZTVE9SRV8wICAgICAgICAgPSA2NzsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBGU1RPUkVfMSAgICAgICAgID0gNjg7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgRlNUT1JFXzIgICAgICAgICA9IDY5OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IEZTVE9SRV8zICAgICAgICAgPSA3MDsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBEU1RPUkVfMCAgICAgICAgID0gNzE7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgRFNUT1JFXzEgICAgICAgICA9IDcyOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IERTVE9SRV8yICAgICAgICAgPSA3MzsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBEU1RPUkVfMyAgICAgICAgID0gNzQ7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgQVNUT1JFXzAgICAgICAgICA9IDc1OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IEFTVE9SRV8xICAgICAgICAgPSA3NjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBBU1RPUkVfMiAgICAgICAgID0gNzc7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgQVNUT1JFXzMgICAgICAgICA9IDc4OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IElBU1RPUkUgICAgICAgICAgPSA3OTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBMQVNUT1JFICAgICAgICAgID0gODA7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgRkFTVE9SRSAgICAgICAgICA9IDgxOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IERBU1RPUkUgICAgICAgICAgPSA4MjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBBQVNUT1JFICAgICAgICAgID0gODM7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgQkFTVE9SRSAgICAgICAgICA9IDg0OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IENBU1RPUkUgICAgICAgICAgPSA4NTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBTQVNUT1JFICAgICAgICAgID0gODY7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgUE9QICAgICAgICAgICAgICA9IDg3OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFBPUDIgICAgICAgICAgICAgPSA4ODsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBEVVAgICAgICAgICAgICAgID0gODk7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgRFVQX1gxICAgICAgICAgICA9IDkwOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IERVUF9YMiAgICAgICAgICAgPSA5MTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBEVVAyICAgICAgICAgICAgID0gOTI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgRFVQMl9YMSAgICAgICAgICA9IDkzOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IERVUDJfWDIgICAgICAgICAgPSA5NDsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBTV0FQICAgICAgICAgICAgID0gOTU7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgSUFERCAgICAgICAgICAgICA9IDk2OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IExBREQgICAgICAgICAgICAgPSA5NzsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBGQUREICAgICAgICAgICAgID0gOTg7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgREFERCAgICAgICAgICAgICA9IDk5OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IElTVUIgICAgICAgICAgICAgPSAxMDA7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgTFNVQiAgICAgICAgICAgICA9IDEwMTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBGU1VCICAgICAgICAgICAgID0gMTAyOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IERTVUIgICAgICAgICAgICAgPSAxMDM7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgSU1VTCAgICAgICAgICAgICA9IDEwNDsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBMTVVMICAgICAgICAgICAgID0gMTA1OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IEZNVUwgICAgICAgICAgICAgPSAxMDY7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgRE1VTCAgICAgICAgICAgICA9IDEwNzsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBJRElWICAgICAgICAgICAgID0gMTA4OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IExESVYgICAgICAgICAgICAgPSAxMDk7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgRkRJViAgICAgICAgICAgICA9IDExMDsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBERElWICAgICAgICAgICAgID0gMTExOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IElSRU0gICAgICAgICAgICAgPSAxMTI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgTFJFTSAgICAgICAgICAgICA9IDExMzsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBGUkVNICAgICAgICAgICAgID0gMTE0OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IERSRU0gICAgICAgICAgICAgPSAxMTU7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgSU5FRyAgICAgICAgICAgICA9IDExNjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBMTkVHICAgICAgICAgICAgID0gMTE3OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IEZORUcgICAgICAgICAgICAgPSAxMTg7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgRE5FRyAgICAgICAgICAgICA9IDExOTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBJU0hMICAgICAgICAgICAgID0gMTIwOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IExTSEwgICAgICAgICAgICAgPSAxMjE7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgSVNIUiAgICAgICAgICAgICA9IDEyMjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBMU0hSICAgICAgICAgICAgID0gMTIzOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IElVU0hSICAgICAgICAgICAgPSAxMjQ7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgTFVTSFIgICAgICAgICAgICA9IDEyNTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBJQU5EICAgICAgICAgICAgID0gMTI2OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IExBTkQgICAgICAgICAgICAgPSAxMjc7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgSU9SICAgICAgICAgICAgICA9IDEyODsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBMT1IgICAgICAgICAgICAgID0gMTI5OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IElYT1IgICAgICAgICAgICAgPSAxMzA7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgTFhPUiAgICAgICAgICAgICA9IDEzMTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBJSU5DICAgICAgICAgICAgID0gMTMyOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IEkyTCAgICAgICAgICAgICAgPSAxMzM7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgSTJGICAgICAgICAgICAgICA9IDEzNDsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBJMkQgICAgICAgICAgICAgID0gMTM1OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IEwySSAgICAgICAgICAgICAgPSAxMzY7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgTDJGICAgICAgICAgICAgICA9IDEzNzsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBMMkQgICAgICAgICAgICAgID0gMTM4OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IEYySSAgICAgICAgICAgICAgPSAxMzk7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgRjJMICAgICAgICAgICAgICA9IDE0MDsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBGMkQgICAgICAgICAgICAgID0gMTQxOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IEQySSAgICAgICAgICAgICAgPSAxNDI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgRDJMICAgICAgICAgICAgICA9IDE0MzsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBEMkYgICAgICAgICAgICAgID0gMTQ0OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IEkyQiAgICAgICAgICAgICAgPSAxNDU7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgSU5UMkJZVEUgICAgICAgICA9IDE0NTsgLy8gT2xkIG5vdGlvbgotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IEkyQyAgICAgICAgICAgICAgPSAxNDY7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgSU5UMkNIQVIgICAgICAgICA9IDE0NjsgLy8gT2xkIG5vdGlvbgotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IEkyUyAgICAgICAgICAgICAgPSAxNDc7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgSU5UMlNIT1JUICAgICAgICA9IDE0NzsgLy8gT2xkIG5vdGlvbgotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IExDTVAgICAgICAgICAgICAgPSAxNDg7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgRkNNUEwgICAgICAgICAgICA9IDE0OTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBGQ01QRyAgICAgICAgICAgID0gMTUwOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IERDTVBMICAgICAgICAgICAgPSAxNTE7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgRENNUEcgICAgICAgICAgICA9IDE1MjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBJRkVRICAgICAgICAgICAgID0gMTUzOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IElGTkUgICAgICAgICAgICAgPSAxNTQ7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgSUZMVCAgICAgICAgICAgICA9IDE1NTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBJRkdFICAgICAgICAgICAgID0gMTU2OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IElGR1QgICAgICAgICAgICAgPSAxNTc7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgSUZMRSAgICAgICAgICAgICA9IDE1ODsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBJRl9JQ01QRVEgICAgICAgID0gMTU5OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IElGX0lDTVBORSAgICAgICAgPSAxNjA7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgSUZfSUNNUExUICAgICAgICA9IDE2MTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBJRl9JQ01QR0UgICAgICAgID0gMTYyOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IElGX0lDTVBHVCAgICAgICAgPSAxNjM7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgSUZfSUNNUExFICAgICAgICA9IDE2NDsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBJRl9BQ01QRVEgICAgICAgID0gMTY1OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IElGX0FDTVBORSAgICAgICAgPSAxNjY7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgR09UTyAgICAgICAgICAgICA9IDE2NzsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBKU1IgICAgICAgICAgICAgID0gMTY4OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFJFVCAgICAgICAgICAgICAgPSAxNjk7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgVEFCTEVTV0lUQ0ggICAgICA9IDE3MDsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBMT09LVVBTV0lUQ0ggICAgID0gMTcxOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IElSRVRVUk4gICAgICAgICAgPSAxNzI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgTFJFVFVSTiAgICAgICAgICA9IDE3MzsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBGUkVUVVJOICAgICAgICAgID0gMTc0OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IERSRVRVUk4gICAgICAgICAgPSAxNzU7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgQVJFVFVSTiAgICAgICAgICA9IDE3NjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBSRVRVUk4gICAgICAgICAgID0gMTc3OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IEdFVFNUQVRJQyAgICAgICAgPSAxNzg7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgUFVUU1RBVElDICAgICAgICA9IDE3OTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBHRVRGSUVMRCAgICAgICAgID0gMTgwOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFBVVEZJRUxEICAgICAgICAgPSAxODE7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgSU5WT0tFVklSVFVBTCAgICA9IDE4MjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBJTlZPS0VTUEVDSUFMICAgID0gMTgzOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IElOVk9LRU5PTlZJUlRVQUwgPSAxODM7IC8vIE9sZCBuYW1lIGluIEpESyAxLjAKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBJTlZPS0VTVEFUSUMgICAgID0gMTg0OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IElOVk9LRUlOVEVSRkFDRSAgPSAxODU7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgTkVXICAgICAgICAgICAgICA9IDE4NzsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBORVdBUlJBWSAgICAgICAgID0gMTg4OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IEFORVdBUlJBWSAgICAgICAgPSAxODk7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgQVJSQVlMRU5HVEggICAgICA9IDE5MDsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBBVEhST1cgICAgICAgICAgID0gMTkxOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IENIRUNLQ0FTVCAgICAgICAgPSAxOTI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgSU5TVEFOQ0VPRiAgICAgICA9IDE5MzsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBNT05JVE9SRU5URVIgICAgID0gMTk0OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IE1PTklUT1JFWElUICAgICAgPSAxOTU7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgV0lERSAgICAgICAgICAgICA9IDE5NjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBNVUxUSUFORVdBUlJBWSAgID0gMTk3OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IElGTlVMTCAgICAgICAgICAgPSAxOTg7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgSUZOT05OVUxMICAgICAgICA9IDE5OTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBHT1RPX1cgICAgICAgICAgID0gMjAwOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IEpTUl9XICAgICAgICAgICAgPSAyMDE7Ci0KLSAgLyoqCi0gICAqIE5vbi1sZWdhbCBvcGNvZGVzLCBtYXkgYmUgdXNlZCBieSBKVk0gaW50ZXJuYWxseS4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgQlJFQUtQT0lOVCAgICAgICAgICAgICAgICA9IDIwMjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBMRENfUVVJQ0sgICAgICAgICAgICAgICAgID0gMjAzOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IExEQ19XX1FVSUNLICAgICAgICAgICAgICAgPSAyMDQ7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgTERDMl9XX1FVSUNLICAgICAgICAgICAgICA9IDIwNTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBHRVRGSUVMRF9RVUlDSyAgICAgICAgICAgID0gMjA2OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFBVVEZJRUxEX1FVSUNLICAgICAgICAgICAgPSAyMDc7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgR0VURklFTEQyX1FVSUNLICAgICAgICAgICA9IDIwODsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBQVVRGSUVMRDJfUVVJQ0sgICAgICAgICAgID0gMjA5OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IEdFVFNUQVRJQ19RVUlDSyAgICAgICAgICAgPSAyMTA7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgUFVUU1RBVElDX1FVSUNLICAgICAgICAgICA9IDIxMTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBHRVRTVEFUSUMyX1FVSUNLICAgICAgICAgID0gMjEyOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFBVVFNUQVRJQzJfUVVJQ0sgICAgICAgICAgPSAyMTM7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgSU5WT0tFVklSVFVBTF9RVUlDSyAgICAgICA9IDIxNDsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBJTlZPS0VOT05WSVJUVUFMX1FVSUNLICAgID0gMjE1OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IElOVk9LRVNVUEVSX1FVSUNLICAgICAgICAgPSAyMTY7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgSU5WT0tFU1RBVElDX1FVSUNLICAgICAgICA9IDIxNzsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBJTlZPS0VJTlRFUkZBQ0VfUVVJQ0sgICAgID0gMjE4OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IElOVk9LRVZJUlRVQUxPQkpFQ1RfUVVJQ0sgPSAyMTk7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgTkVXX1FVSUNLICAgICAgICAgICAgICAgICA9IDIyMTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBBTkVXQVJSQVlfUVVJQ0sgICAgICAgICAgID0gMjIyOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IE1VTFRJQU5FV0FSUkFZX1FVSUNLICAgICAgPSAyMjM7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgQ0hFQ0tDQVNUX1FVSUNLICAgICAgICAgICA9IDIyNDsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBJTlNUQU5DRU9GX1FVSUNLICAgICAgICAgID0gMjI1OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IElOVk9LRVZJUlRVQUxfUVVJQ0tfVyAgICAgPSAyMjY7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgR0VURklFTERfUVVJQ0tfVyAgICAgICAgICA9IDIyNzsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBQVVRGSUVMRF9RVUlDS19XICAgICAgICAgID0gMjI4OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IElNUERFUDEgICAgICAgICAgICAgICAgICAgPSAyNTQ7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgSU1QREVQMiAgICAgICAgICAgICAgICAgICA9IDI1NTsKLQotICAvKioKLSAgICogRm9yIGludGVybmFsIHB1cnBvc2VzIG9ubHkuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFBVU0ggICAgICAgICAgICAgPSA0NzExOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFNXSVRDSCAgICAgICAgICAgPSA0NzEyOwotCi0gIC8qKgotICAgKiBJbGxlZ2FsIGNvZGVzCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0ICBVTkRFRklORUQgICAgICA9IC0xOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0ICBVTlBSRURJQ1RBQkxFICA9IC0yOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0ICBSRVNFUlZFRCAgICAgICA9IC0zOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBJTExFR0FMX09QQ09ERSA9ICI8aWxsZWdhbCBvcGNvZGU+IjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSUxMRUdBTF9UWVBFICAgPSAiPGlsbGVnYWwgdHlwZT4iOwotCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZSBUX0JPT0xFQU4gPSA0OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgVF9DSEFSICAgID0gNTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBieXRlIFRfRkxPQVQgICA9IDY7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZSBUX0RPVUJMRSAgPSA3OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgVF9CWVRFICAgID0gODsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBieXRlIFRfU0hPUlQgICA9IDk7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZSBUX0lOVCAgICAgPSAxMDsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBieXRlIFRfTE9ORyAgICA9IDExOwotCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZSBUX1ZPSUQgICAgICA9IDEyOyAvLyBOb24tc3RhbmRhcmQKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBieXRlIFRfQVJSQVkgICAgID0gMTM7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZSBUX09CSkVDVCAgICA9IDE0OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgVF9SRUZFUkVOQ0UgPSAxNDsgLy8gRGVwcmVjYXRlZAotICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgVF9VTktOT1dOICAgPSAxNTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBieXRlIFRfQUREUkVTUyAgID0gMTY7Ci0KLSAgLyoqIFRoZSBwcmltaXRpdmUgdHlwZSBuYW1lcyBjb3JyZXNwb25kaW5nIHRvIHRoZSBUX1hYIGNvbnN0YW50cywKLSAgICogZS5nLiwgVFlQRV9OQU1FU1tUX0lOVF0gPSAiaW50IgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSBUWVBFX05BTUVTID0gewotICAgIElMTEVHQUxfVFlQRSwgSUxMRUdBTF9UWVBFLCAgSUxMRUdBTF9UWVBFLCBJTExFR0FMX1RZUEUsCi0gICAgImJvb2xlYW4iLCAiY2hhciIsICJmbG9hdCIsICJkb3VibGUiLCAiYnl0ZSIsICJzaG9ydCIsICJpbnQiLCAibG9uZyIsCi0gICAgInZvaWQiLCAiYXJyYXkiLCAib2JqZWN0IiwgInVua25vd24iIC8vIE5vbi1zdGFuZGFyZAotICB9OwotCi0gIC8qKiBUaGUgcHJpbWl0aXZlIGNsYXNzIG5hbWVzIGNvcnJlc3BvbmRpbmcgdG8gdGhlIFRfWFggY29uc3RhbnRzLAotICAgKiBlLmcuLCBDTEFTU19UWVBFX05BTUVTW1RfSU5UXSA9ICJqYXZhLmxhbmcuSW50ZWdlciIKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nW10gQ0xBU1NfVFlQRV9OQU1FUyA9IHsKLSAgICBJTExFR0FMX1RZUEUsIElMTEVHQUxfVFlQRSwgIElMTEVHQUxfVFlQRSwgSUxMRUdBTF9UWVBFLAotICAgICJqYXZhLmxhbmcuQm9vbGVhbiIsICJqYXZhLmxhbmcuQ2hhcmFjdGVyIiwgImphdmEubGFuZy5GbG9hdCIsCi0gICAgImphdmEubGFuZy5Eb3VibGUiLCAiamF2YS5sYW5nLkJ5dGUiLCAiamF2YS5sYW5nLlNob3J0IiwKLSAgICAiamF2YS5sYW5nLkludGVnZXIiLCAiamF2YS5sYW5nLkxvbmciLCAiamF2YS5sYW5nLlZvaWQiLAotICAgIElMTEVHQUxfVFlQRSwgSUxMRUdBTF9UWVBFLCAgSUxMRUdBTF9UWVBFCi0gIH07Ci0KLSAgLyoqIFRoZSBzaWduYXR1cmUgY2hhcmFjdGVycyBjb3JyZXNwb25kaW5nIHRvIHByaW1pdGl2ZSB0eXBlcywKLSAgICogZS5nLiwgU0hPUlRfVFlQRV9OQU1FU1tUX0lOVF0gPSAiSSIKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nW10gU0hPUlRfVFlQRV9OQU1FUyA9IHsKLSAgICBJTExFR0FMX1RZUEUsIElMTEVHQUxfVFlQRSwgIElMTEVHQUxfVFlQRSwgSUxMRUdBTF9UWVBFLAotICAgICJaIiwgIkMiLCAiRiIsICJEIiwgIkIiLCAiUyIsICJJIiwgIkoiLAotICAgICJWIiwgSUxMRUdBTF9UWVBFLCBJTExFR0FMX1RZUEUsIElMTEVHQUxfVFlQRQotICB9OwotCi0gIC8qKgotICAgKiBOdW1iZXIgb2YgYnl0ZSBjb2RlIG9wZXJhbmRzLCBpLmUuLCBudW1iZXIgb2YgYnl0ZXMgYWZ0ZXIgdGhlIHRhZyBieXRlCi0gICAqIGl0c2VsZi4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnRbXSBOT19PRl9PUEVSQU5EUyA9IHsKLSAgICAwLypub3AqLywgMC8qYWNvbnN0X251bGwqLywgMC8qaWNvbnN0X20xKi8sIDAvKmljb25zdF8wKi8sCi0gICAgMC8qaWNvbnN0XzEqLywgMC8qaWNvbnN0XzIqLywgMC8qaWNvbnN0XzMqLywgMC8qaWNvbnN0XzQqLywKLSAgICAwLyppY29uc3RfNSovLCAwLypsY29uc3RfMCovLCAwLypsY29uc3RfMSovLCAwLypmY29uc3RfMCovLAotICAgIDAvKmZjb25zdF8xKi8sIDAvKmZjb25zdF8yKi8sIDAvKmRjb25zdF8wKi8sIDAvKmRjb25zdF8xKi8sCi0gICAgMS8qYmlwdXNoKi8sIDIvKnNpcHVzaCovLCAxLypsZGMqLywgMi8qbGRjX3cqLywgMi8qbGRjMl93Ki8sCi0gICAgMS8qaWxvYWQqLywgMS8qbGxvYWQqLywgMS8qZmxvYWQqLywgMS8qZGxvYWQqLywgMS8qYWxvYWQqLywKLSAgICAwLyppbG9hZF8wKi8sIDAvKmlsb2FkXzEqLywgMC8qaWxvYWRfMiovLCAwLyppbG9hZF8zKi8sCi0gICAgMC8qbGxvYWRfMCovLCAwLypsbG9hZF8xKi8sIDAvKmxsb2FkXzIqLywgMC8qbGxvYWRfMyovLAotICAgIDAvKmZsb2FkXzAqLywgMC8qZmxvYWRfMSovLCAwLypmbG9hZF8yKi8sIDAvKmZsb2FkXzMqLywKLSAgICAwLypkbG9hZF8wKi8sIDAvKmRsb2FkXzEqLywgMC8qZGxvYWRfMiovLCAwLypkbG9hZF8zKi8sCi0gICAgMC8qYWxvYWRfMCovLCAwLyphbG9hZF8xKi8sIDAvKmFsb2FkXzIqLywgMC8qYWxvYWRfMyovLAotICAgIDAvKmlhbG9hZCovLCAwLypsYWxvYWQqLywgMC8qZmFsb2FkKi8sIDAvKmRhbG9hZCovLAotICAgIDAvKmFhbG9hZCovLCAwLypiYWxvYWQqLywgMC8qY2Fsb2FkKi8sIDAvKnNhbG9hZCovLAotICAgIDEvKmlzdG9yZSovLCAxLypsc3RvcmUqLywgMS8qZnN0b3JlKi8sIDEvKmRzdG9yZSovLAotICAgIDEvKmFzdG9yZSovLCAwLyppc3RvcmVfMCovLCAwLyppc3RvcmVfMSovLCAwLyppc3RvcmVfMiovLAotICAgIDAvKmlzdG9yZV8zKi8sIDAvKmxzdG9yZV8wKi8sIDAvKmxzdG9yZV8xKi8sIDAvKmxzdG9yZV8yKi8sCi0gICAgMC8qbHN0b3JlXzMqLywgMC8qZnN0b3JlXzAqLywgMC8qZnN0b3JlXzEqLywgMC8qZnN0b3JlXzIqLywKLSAgICAwLypmc3RvcmVfMyovLCAwLypkc3RvcmVfMCovLCAwLypkc3RvcmVfMSovLCAwLypkc3RvcmVfMiovLAotICAgIDAvKmRzdG9yZV8zKi8sIDAvKmFzdG9yZV8wKi8sIDAvKmFzdG9yZV8xKi8sIDAvKmFzdG9yZV8yKi8sCi0gICAgMC8qYXN0b3JlXzMqLywgMC8qaWFzdG9yZSovLCAwLypsYXN0b3JlKi8sIDAvKmZhc3RvcmUqLywKLSAgICAwLypkYXN0b3JlKi8sIDAvKmFhc3RvcmUqLywgMC8qYmFzdG9yZSovLCAwLypjYXN0b3JlKi8sCi0gICAgMC8qc2FzdG9yZSovLCAwLypwb3AqLywgMC8qcG9wMiovLCAwLypkdXAqLywgMC8qZHVwX3gxKi8sCi0gICAgMC8qZHVwX3gyKi8sIDAvKmR1cDIqLywgMC8qZHVwMl94MSovLCAwLypkdXAyX3gyKi8sIDAvKnN3YXAqLywKLSAgICAwLyppYWRkKi8sIDAvKmxhZGQqLywgMC8qZmFkZCovLCAwLypkYWRkKi8sIDAvKmlzdWIqLywKLSAgICAwLypsc3ViKi8sIDAvKmZzdWIqLywgMC8qZHN1YiovLCAwLyppbXVsKi8sIDAvKmxtdWwqLywKLSAgICAwLypmbXVsKi8sIDAvKmRtdWwqLywgMC8qaWRpdiovLCAwLypsZGl2Ki8sIDAvKmZkaXYqLywKLSAgICAwLypkZGl2Ki8sIDAvKmlyZW0qLywgMC8qbHJlbSovLCAwLypmcmVtKi8sIDAvKmRyZW0qLywKLSAgICAwLyppbmVnKi8sIDAvKmxuZWcqLywgMC8qZm5lZyovLCAwLypkbmVnKi8sIDAvKmlzaGwqLywKLSAgICAwLypsc2hsKi8sIDAvKmlzaHIqLywgMC8qbHNociovLCAwLyppdXNociovLCAwLypsdXNociovLAotICAgIDAvKmlhbmQqLywgMC8qbGFuZCovLCAwLyppb3IqLywgMC8qbG9yKi8sIDAvKml4b3IqLywgMC8qbHhvciovLAotICAgIDIvKmlpbmMqLywgMC8qaTJsKi8sIDAvKmkyZiovLCAwLyppMmQqLywgMC8qbDJpKi8sIDAvKmwyZiovLAotICAgIDAvKmwyZCovLCAwLypmMmkqLywgMC8qZjJsKi8sIDAvKmYyZCovLCAwLypkMmkqLywgMC8qZDJsKi8sCi0gICAgMC8qZDJmKi8sIDAvKmkyYiovLCAwLyppMmMqLywgMC8qaTJzKi8sIDAvKmxjbXAqLywgMC8qZmNtcGwqLywKLSAgICAwLypmY21wZyovLCAwLypkY21wbCovLCAwLypkY21wZyovLCAyLyppZmVxKi8sIDIvKmlmbmUqLywKLSAgICAyLyppZmx0Ki8sIDIvKmlmZ2UqLywgMi8qaWZndCovLCAyLyppZmxlKi8sIDIvKmlmX2ljbXBlcSovLAotICAgIDIvKmlmX2ljbXBuZSovLCAyLyppZl9pY21wbHQqLywgMi8qaWZfaWNtcGdlKi8sIDIvKmlmX2ljbXBndCovLAotICAgIDIvKmlmX2ljbXBsZSovLCAyLyppZl9hY21wZXEqLywgMi8qaWZfYWNtcG5lKi8sIDIvKmdvdG8qLywKLSAgICAyLypqc3IqLywgMS8qcmV0Ki8sIFVOUFJFRElDVEFCTEUvKnRhYmxlc3dpdGNoKi8sIFVOUFJFRElDVEFCTEUvKmxvb2t1cHN3aXRjaCovLAotICAgIDAvKmlyZXR1cm4qLywgMC8qbHJldHVybiovLCAwLypmcmV0dXJuKi8sCi0gICAgMC8qZHJldHVybiovLCAwLyphcmV0dXJuKi8sIDAvKnJldHVybiovLAotICAgIDIvKmdldHN0YXRpYyovLCAyLypwdXRzdGF0aWMqLywgMi8qZ2V0ZmllbGQqLywKLSAgICAyLypwdXRmaWVsZCovLCAyLyppbnZva2V2aXJ0dWFsKi8sIDIvKmludm9rZXNwZWNpYWwqLywgMi8qaW52b2tlc3RhdGljKi8sCi0gICAgNC8qaW52b2tlaW50ZXJmYWNlKi8sIFVOREVGSU5FRCwgMi8qbmV3Ki8sCi0gICAgMS8qbmV3YXJyYXkqLywgMi8qYW5ld2FycmF5Ki8sCi0gICAgMC8qYXJyYXlsZW5ndGgqLywgMC8qYXRocm93Ki8sIDIvKmNoZWNrY2FzdCovLAotICAgIDIvKmluc3RhbmNlb2YqLywgMC8qbW9uaXRvcmVudGVyKi8sCi0gICAgMC8qbW9uaXRvcmV4aXQqLywgVU5QUkVESUNUQUJMRS8qd2lkZSovLCAzLyptdWx0aWFuZXdhcnJheSovLAotICAgIDIvKmlmbnVsbCovLCAyLyppZm5vbm51bGwqLywgNC8qZ290b193Ki8sCi0gICAgNC8qanNyX3cqLywgMC8qYnJlYWtwb2ludCovLCBVTkRFRklORUQsCi0gICAgVU5ERUZJTkVELCBVTkRFRklORUQsIFVOREVGSU5FRCwgVU5ERUZJTkVELCBVTkRFRklORUQsIFVOREVGSU5FRCwKLSAgICBVTkRFRklORUQsIFVOREVGSU5FRCwgVU5ERUZJTkVELCBVTkRFRklORUQsIFVOREVGSU5FRCwgVU5ERUZJTkVELAotICAgIFVOREVGSU5FRCwgVU5ERUZJTkVELCBVTkRFRklORUQsIFVOREVGSU5FRCwgVU5ERUZJTkVELCBVTkRFRklORUQsCi0gICAgVU5ERUZJTkVELCBVTkRFRklORUQsIFVOREVGSU5FRCwgVU5ERUZJTkVELCBVTkRFRklORUQsIFVOREVGSU5FRCwKLSAgICBVTkRFRklORUQsIFVOREVGSU5FRCwgVU5ERUZJTkVELCBVTkRFRklORUQsIFVOREVGSU5FRCwgVU5ERUZJTkVELAotICAgIFVOREVGSU5FRCwgVU5ERUZJTkVELCBVTkRFRklORUQsIFVOREVGSU5FRCwgVU5ERUZJTkVELCBVTkRFRklORUQsCi0gICAgVU5ERUZJTkVELCBVTkRFRklORUQsIFVOREVGSU5FRCwgVU5ERUZJTkVELCBVTkRFRklORUQsIFVOREVGSU5FRCwKLSAgICBVTkRFRklORUQsIFVOREVGSU5FRCwgVU5ERUZJTkVELCBVTkRFRklORUQsIFVOREVGSU5FRCwgVU5ERUZJTkVELAotICAgIFVOREVGSU5FRCwgVU5ERUZJTkVELCBSRVNFUlZFRC8qaW1wZGVwMSovLCBSRVNFUlZFRC8qaW1wZGVwMiovCi0gIH07Ci0KLSAgLyoqCi0gICAqIEhvdyB0aGUgYnl0ZSBjb2RlIG9wZXJhbmRzIGFyZSB0byBiZSBpbnRlcnByZXRlZC4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnRbXVtdIFRZUEVfT0ZfT1BFUkFORFMgPSB7Ci0gICAge30vKm5vcCovLCB7fS8qYWNvbnN0X251bGwqLywge30vKmljb25zdF9tMSovLCB7fS8qaWNvbnN0XzAqLywKLSAgICB7fS8qaWNvbnN0XzEqLywge30vKmljb25zdF8yKi8sIHt9LyppY29uc3RfMyovLCB7fS8qaWNvbnN0XzQqLywKLSAgICB7fS8qaWNvbnN0XzUqLywge30vKmxjb25zdF8wKi8sIHt9LypsY29uc3RfMSovLCB7fS8qZmNvbnN0XzAqLywKLSAgICB7fS8qZmNvbnN0XzEqLywge30vKmZjb25zdF8yKi8sIHt9LypkY29uc3RfMCovLCB7fS8qZGNvbnN0XzEqLywKLSAgICB7VF9CWVRFfS8qYmlwdXNoKi8sIHtUX1NIT1JUfS8qc2lwdXNoKi8sIHtUX0JZVEV9LypsZGMqLywKLSAgICB7VF9TSE9SVH0vKmxkY193Ki8sIHtUX1NIT1JUfS8qbGRjMl93Ki8sCi0gICAge1RfQllURX0vKmlsb2FkKi8sIHtUX0JZVEV9LypsbG9hZCovLCB7VF9CWVRFfS8qZmxvYWQqLywKLSAgICB7VF9CWVRFfS8qZGxvYWQqLywge1RfQllURX0vKmFsb2FkKi8sIHt9LyppbG9hZF8wKi8sCi0gICAge30vKmlsb2FkXzEqLywge30vKmlsb2FkXzIqLywge30vKmlsb2FkXzMqLywge30vKmxsb2FkXzAqLywKLSAgICB7fS8qbGxvYWRfMSovLCB7fS8qbGxvYWRfMiovLCB7fS8qbGxvYWRfMyovLCB7fS8qZmxvYWRfMCovLAotICAgIHt9LypmbG9hZF8xKi8sIHt9LypmbG9hZF8yKi8sIHt9LypmbG9hZF8zKi8sIHt9LypkbG9hZF8wKi8sCi0gICAge30vKmRsb2FkXzEqLywge30vKmRsb2FkXzIqLywge30vKmRsb2FkXzMqLywge30vKmFsb2FkXzAqLywKLSAgICB7fS8qYWxvYWRfMSovLCB7fS8qYWxvYWRfMiovLCB7fS8qYWxvYWRfMyovLCB7fS8qaWFsb2FkKi8sCi0gICAge30vKmxhbG9hZCovLCB7fS8qZmFsb2FkKi8sIHt9LypkYWxvYWQqLywge30vKmFhbG9hZCovLAotICAgIHt9LypiYWxvYWQqLywge30vKmNhbG9hZCovLCB7fS8qc2Fsb2FkKi8sIHtUX0JZVEV9Lyppc3RvcmUqLywKLSAgICB7VF9CWVRFfS8qbHN0b3JlKi8sIHtUX0JZVEV9Lypmc3RvcmUqLywge1RfQllURX0vKmRzdG9yZSovLAotICAgIHtUX0JZVEV9Lyphc3RvcmUqLywge30vKmlzdG9yZV8wKi8sIHt9Lyppc3RvcmVfMSovLAotICAgIHt9Lyppc3RvcmVfMiovLCB7fS8qaXN0b3JlXzMqLywge30vKmxzdG9yZV8wKi8sIHt9Lypsc3RvcmVfMSovLAotICAgIHt9Lypsc3RvcmVfMiovLCB7fS8qbHN0b3JlXzMqLywge30vKmZzdG9yZV8wKi8sIHt9Lypmc3RvcmVfMSovLAotICAgIHt9Lypmc3RvcmVfMiovLCB7fS8qZnN0b3JlXzMqLywge30vKmRzdG9yZV8wKi8sIHt9Lypkc3RvcmVfMSovLAotICAgIHt9Lypkc3RvcmVfMiovLCB7fS8qZHN0b3JlXzMqLywge30vKmFzdG9yZV8wKi8sIHt9Lyphc3RvcmVfMSovLAotICAgIHt9Lyphc3RvcmVfMiovLCB7fS8qYXN0b3JlXzMqLywge30vKmlhc3RvcmUqLywge30vKmxhc3RvcmUqLywKLSAgICB7fS8qZmFzdG9yZSovLCB7fS8qZGFzdG9yZSovLCB7fS8qYWFzdG9yZSovLCB7fS8qYmFzdG9yZSovLAotICAgIHt9LypjYXN0b3JlKi8sIHt9LypzYXN0b3JlKi8sIHt9Lypwb3AqLywge30vKnBvcDIqLywge30vKmR1cCovLAotICAgIHt9LypkdXBfeDEqLywge30vKmR1cF94MiovLCB7fS8qZHVwMiovLCB7fS8qZHVwMl94MSovLAotICAgIHt9LypkdXAyX3gyKi8sIHt9Lypzd2FwKi8sIHt9LyppYWRkKi8sIHt9LypsYWRkKi8sIHt9LypmYWRkKi8sCi0gICAge30vKmRhZGQqLywge30vKmlzdWIqLywge30vKmxzdWIqLywge30vKmZzdWIqLywge30vKmRzdWIqLywKLSAgICB7fS8qaW11bCovLCB7fS8qbG11bCovLCB7fS8qZm11bCovLCB7fS8qZG11bCovLCB7fS8qaWRpdiovLAotICAgIHt9LypsZGl2Ki8sIHt9LypmZGl2Ki8sIHt9LypkZGl2Ki8sIHt9LyppcmVtKi8sIHt9LypscmVtKi8sCi0gICAge30vKmZyZW0qLywge30vKmRyZW0qLywge30vKmluZWcqLywge30vKmxuZWcqLywge30vKmZuZWcqLywKLSAgICB7fS8qZG5lZyovLCB7fS8qaXNobCovLCB7fS8qbHNobCovLCB7fS8qaXNociovLCB7fS8qbHNociovLAotICAgIHt9LyppdXNociovLCB7fS8qbHVzaHIqLywge30vKmlhbmQqLywge30vKmxhbmQqLywge30vKmlvciovLAotICAgIHt9Lypsb3IqLywge30vKml4b3IqLywge30vKmx4b3IqLywge1RfQllURSwgVF9CWVRFfS8qaWluYyovLAotICAgIHt9LyppMmwqLywge30vKmkyZiovLCB7fS8qaTJkKi8sIHt9LypsMmkqLywge30vKmwyZiovLCB7fS8qbDJkKi8sCi0gICAge30vKmYyaSovLCB7fS8qZjJsKi8sIHt9LypmMmQqLywge30vKmQyaSovLCB7fS8qZDJsKi8sIHt9LypkMmYqLywKLSAgICB7fS8qaTJiKi8sIHt9LyppMmMqLyx7fS8qaTJzKi8sIHt9LypsY21wKi8sIHt9LypmY21wbCovLAotICAgIHt9LypmY21wZyovLCB7fS8qZGNtcGwqLywge30vKmRjbXBnKi8sIHtUX1NIT1JUfS8qaWZlcSovLAotICAgIHtUX1NIT1JUfS8qaWZuZSovLCB7VF9TSE9SVH0vKmlmbHQqLywge1RfU0hPUlR9LyppZmdlKi8sCi0gICAge1RfU0hPUlR9LyppZmd0Ki8sIHtUX1NIT1JUfS8qaWZsZSovLCB7VF9TSE9SVH0vKmlmX2ljbXBlcSovLAotICAgIHtUX1NIT1JUfS8qaWZfaWNtcG5lKi8sIHtUX1NIT1JUfS8qaWZfaWNtcGx0Ki8sCi0gICAge1RfU0hPUlR9LyppZl9pY21wZ2UqLywge1RfU0hPUlR9LyppZl9pY21wZ3QqLywKLSAgICB7VF9TSE9SVH0vKmlmX2ljbXBsZSovLCB7VF9TSE9SVH0vKmlmX2FjbXBlcSovLAotICAgIHtUX1NIT1JUfS8qaWZfYWNtcG5lKi8sIHtUX1NIT1JUfS8qZ290byovLCB7VF9TSE9SVH0vKmpzciovLAotICAgIHtUX0JZVEV9LypyZXQqLywge30vKnRhYmxlc3dpdGNoKi8sIHt9Lypsb29rdXBzd2l0Y2gqLywKLSAgICB7fS8qaXJldHVybiovLCB7fS8qbHJldHVybiovLCB7fS8qZnJldHVybiovLCB7fS8qZHJldHVybiovLAotICAgIHt9LyphcmV0dXJuKi8sIHt9LypyZXR1cm4qLywge1RfU0hPUlR9LypnZXRzdGF0aWMqLywKLSAgICB7VF9TSE9SVH0vKnB1dHN0YXRpYyovLCB7VF9TSE9SVH0vKmdldGZpZWxkKi8sCi0gICAge1RfU0hPUlR9LypwdXRmaWVsZCovLCB7VF9TSE9SVH0vKmludm9rZXZpcnR1YWwqLywKLSAgICB7VF9TSE9SVH0vKmludm9rZXNwZWNpYWwqLywge1RfU0hPUlR9LyppbnZva2VzdGF0aWMqLywKLSAgICB7VF9TSE9SVCwgVF9CWVRFLCBUX0JZVEV9LyppbnZva2VpbnRlcmZhY2UqLywge30sCi0gICAge1RfU0hPUlR9LypuZXcqLywge1RfQllURX0vKm5ld2FycmF5Ki8sCi0gICAge1RfU0hPUlR9LyphbmV3YXJyYXkqLywge30vKmFycmF5bGVuZ3RoKi8sIHt9LyphdGhyb3cqLywKLSAgICB7VF9TSE9SVH0vKmNoZWNrY2FzdCovLCB7VF9TSE9SVH0vKmluc3RhbmNlb2YqLywKLSAgICB7fS8qbW9uaXRvcmVudGVyKi8sIHt9Lyptb25pdG9yZXhpdCovLCB7VF9CWVRFfS8qd2lkZSovLAotICAgIHtUX1NIT1JULCBUX0JZVEV9LyptdWx0aWFuZXdhcnJheSovLCB7VF9TSE9SVH0vKmlmbnVsbCovLAotICAgIHtUX1NIT1JUfS8qaWZub25udWxsKi8sIHtUX0lOVH0vKmdvdG9fdyovLCB7VF9JTlR9Lypqc3JfdyovLAotICAgIHt9LypicmVha3BvaW50Ki8sIHt9LCB7fSwge30sIHt9LCB7fSwge30sIHt9LAotICAgIHt9LCB7fSwge30sIHt9LCB7fSwge30sIHt9LCB7fSwge30sIHt9LCB7fSwge30sIHt9LCB7fSwge30sCi0gICAge30sIHt9LCB7fSwge30sIHt9LCB7fSwge30sIHt9LCB7fSwge30sIHt9LCB7fSwge30sIHt9LCB7fSwKLSAgICB7fSwge30sIHt9LCB7fSwge30sIHt9LCB7fSwge30sIHt9LCB7fSwge30sIHt9LCB7fSwge30sCi0gICAge30vKmltcGRlcDEqLywge30vKmltcGRlcDIqLwotICB9OwotCi0gIC8qKgotICAgKiBOYW1lcyBvZiBvcGNvZGVzLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSBPUENPREVfTkFNRVMgPSB7Ci0gICAgIm5vcCIsICJhY29uc3RfbnVsbCIsICJpY29uc3RfbTEiLCAiaWNvbnN0XzAiLCAiaWNvbnN0XzEiLAotICAgICJpY29uc3RfMiIsICJpY29uc3RfMyIsICJpY29uc3RfNCIsICJpY29uc3RfNSIsICJsY29uc3RfMCIsCi0gICAgImxjb25zdF8xIiwgImZjb25zdF8wIiwgImZjb25zdF8xIiwgImZjb25zdF8yIiwgImRjb25zdF8wIiwKLSAgICAiZGNvbnN0XzEiLCAiYmlwdXNoIiwgInNpcHVzaCIsICJsZGMiLCAibGRjX3ciLCAibGRjMl93IiwgImlsb2FkIiwKLSAgICAibGxvYWQiLCAiZmxvYWQiLCAiZGxvYWQiLCAiYWxvYWQiLCAiaWxvYWRfMCIsICJpbG9hZF8xIiwgImlsb2FkXzIiLAotICAgICJpbG9hZF8zIiwgImxsb2FkXzAiLCAibGxvYWRfMSIsICJsbG9hZF8yIiwgImxsb2FkXzMiLCAiZmxvYWRfMCIsCi0gICAgImZsb2FkXzEiLCAiZmxvYWRfMiIsICJmbG9hZF8zIiwgImRsb2FkXzAiLCAiZGxvYWRfMSIsICJkbG9hZF8yIiwKLSAgICAiZGxvYWRfMyIsICJhbG9hZF8wIiwgImFsb2FkXzEiLCAiYWxvYWRfMiIsICJhbG9hZF8zIiwgImlhbG9hZCIsCi0gICAgImxhbG9hZCIsICJmYWxvYWQiLCAiZGFsb2FkIiwgImFhbG9hZCIsICJiYWxvYWQiLCAiY2Fsb2FkIiwgInNhbG9hZCIsCi0gICAgImlzdG9yZSIsICJsc3RvcmUiLCAiZnN0b3JlIiwgImRzdG9yZSIsICJhc3RvcmUiLCAiaXN0b3JlXzAiLAotICAgICJpc3RvcmVfMSIsICJpc3RvcmVfMiIsICJpc3RvcmVfMyIsICJsc3RvcmVfMCIsICJsc3RvcmVfMSIsCi0gICAgImxzdG9yZV8yIiwgImxzdG9yZV8zIiwgImZzdG9yZV8wIiwgImZzdG9yZV8xIiwgImZzdG9yZV8yIiwKLSAgICAiZnN0b3JlXzMiLCAiZHN0b3JlXzAiLCAiZHN0b3JlXzEiLCAiZHN0b3JlXzIiLCAiZHN0b3JlXzMiLAotICAgICJhc3RvcmVfMCIsICJhc3RvcmVfMSIsICJhc3RvcmVfMiIsICJhc3RvcmVfMyIsICJpYXN0b3JlIiwgImxhc3RvcmUiLAotICAgICJmYXN0b3JlIiwgImRhc3RvcmUiLCAiYWFzdG9yZSIsICJiYXN0b3JlIiwgImNhc3RvcmUiLCAic2FzdG9yZSIsCi0gICAgInBvcCIsICJwb3AyIiwgImR1cCIsICJkdXBfeDEiLCAiZHVwX3gyIiwgImR1cDIiLCAiZHVwMl94MSIsCi0gICAgImR1cDJfeDIiLCAic3dhcCIsICJpYWRkIiwgImxhZGQiLCAiZmFkZCIsICJkYWRkIiwgImlzdWIiLCAibHN1YiIsCi0gICAgImZzdWIiLCAiZHN1YiIsICJpbXVsIiwgImxtdWwiLCAiZm11bCIsICJkbXVsIiwgImlkaXYiLCAibGRpdiIsCi0gICAgImZkaXYiLCAiZGRpdiIsICJpcmVtIiwgImxyZW0iLCAiZnJlbSIsICJkcmVtIiwgImluZWciLCAibG5lZyIsCi0gICAgImZuZWciLCAiZG5lZyIsICJpc2hsIiwgImxzaGwiLCAiaXNociIsICJsc2hyIiwgIml1c2hyIiwgImx1c2hyIiwKLSAgICAiaWFuZCIsICJsYW5kIiwgImlvciIsICJsb3IiLCAiaXhvciIsICJseG9yIiwgImlpbmMiLCAiaTJsIiwgImkyZiIsCi0gICAgImkyZCIsICJsMmkiLCAibDJmIiwgImwyZCIsICJmMmkiLCAiZjJsIiwgImYyZCIsICJkMmkiLCAiZDJsIiwgImQyZiIsCi0gICAgImkyYiIsICJpMmMiLCAiaTJzIiwgImxjbXAiLCAiZmNtcGwiLCAiZmNtcGciLAotICAgICJkY21wbCIsICJkY21wZyIsICJpZmVxIiwgImlmbmUiLCAiaWZsdCIsICJpZmdlIiwgImlmZ3QiLCAiaWZsZSIsCi0gICAgImlmX2ljbXBlcSIsICJpZl9pY21wbmUiLCAiaWZfaWNtcGx0IiwgImlmX2ljbXBnZSIsICJpZl9pY21wZ3QiLAotICAgICJpZl9pY21wbGUiLCAiaWZfYWNtcGVxIiwgImlmX2FjbXBuZSIsICJnb3RvIiwgImpzciIsICJyZXQiLAotICAgICJ0YWJsZXN3aXRjaCIsICJsb29rdXBzd2l0Y2giLCAiaXJldHVybiIsICJscmV0dXJuIiwgImZyZXR1cm4iLAotICAgICJkcmV0dXJuIiwgImFyZXR1cm4iLCAicmV0dXJuIiwgImdldHN0YXRpYyIsICJwdXRzdGF0aWMiLCAiZ2V0ZmllbGQiLAotICAgICJwdXRmaWVsZCIsICJpbnZva2V2aXJ0dWFsIiwgImludm9rZXNwZWNpYWwiLCAiaW52b2tlc3RhdGljIiwKLSAgICAiaW52b2tlaW50ZXJmYWNlIiwgSUxMRUdBTF9PUENPREUsICJuZXciLCAibmV3YXJyYXkiLCAiYW5ld2FycmF5IiwKLSAgICAiYXJyYXlsZW5ndGgiLCAiYXRocm93IiwgImNoZWNrY2FzdCIsICJpbnN0YW5jZW9mIiwgIm1vbml0b3JlbnRlciIsCi0gICAgIm1vbml0b3JleGl0IiwgIndpZGUiLCAibXVsdGlhbmV3YXJyYXkiLCAiaWZudWxsIiwgImlmbm9ubnVsbCIsCi0gICAgImdvdG9fdyIsICJqc3JfdyIsICJicmVha3BvaW50IiwgSUxMRUdBTF9PUENPREUsIElMTEVHQUxfT1BDT0RFLAotICAgIElMTEVHQUxfT1BDT0RFLCBJTExFR0FMX09QQ09ERSwgSUxMRUdBTF9PUENPREUsIElMTEVHQUxfT1BDT0RFLAotICAgIElMTEVHQUxfT1BDT0RFLCBJTExFR0FMX09QQ09ERSwgSUxMRUdBTF9PUENPREUsIElMTEVHQUxfT1BDT0RFLAotICAgIElMTEVHQUxfT1BDT0RFLCBJTExFR0FMX09QQ09ERSwgSUxMRUdBTF9PUENPREUsIElMTEVHQUxfT1BDT0RFLAotICAgIElMTEVHQUxfT1BDT0RFLCBJTExFR0FMX09QQ09ERSwgSUxMRUdBTF9PUENPREUsIElMTEVHQUxfT1BDT0RFLAotICAgIElMTEVHQUxfT1BDT0RFLCBJTExFR0FMX09QQ09ERSwgSUxMRUdBTF9PUENPREUsIElMTEVHQUxfT1BDT0RFLAotICAgIElMTEVHQUxfT1BDT0RFLCBJTExFR0FMX09QQ09ERSwgSUxMRUdBTF9PUENPREUsIElMTEVHQUxfT1BDT0RFLAotICAgIElMTEVHQUxfT1BDT0RFLCBJTExFR0FMX09QQ09ERSwgSUxMRUdBTF9PUENPREUsIElMTEVHQUxfT1BDT0RFLAotICAgIElMTEVHQUxfT1BDT0RFLCBJTExFR0FMX09QQ09ERSwgSUxMRUdBTF9PUENPREUsIElMTEVHQUxfT1BDT0RFLAotICAgIElMTEVHQUxfT1BDT0RFLCBJTExFR0FMX09QQ09ERSwgSUxMRUdBTF9PUENPREUsIElMTEVHQUxfT1BDT0RFLAotICAgIElMTEVHQUxfT1BDT0RFLCBJTExFR0FMX09QQ09ERSwgSUxMRUdBTF9PUENPREUsIElMTEVHQUxfT1BDT0RFLAotICAgIElMTEVHQUxfT1BDT0RFLCBJTExFR0FMX09QQ09ERSwgSUxMRUdBTF9PUENPREUsIElMTEVHQUxfT1BDT0RFLAotICAgIElMTEVHQUxfT1BDT0RFLCBJTExFR0FMX09QQ09ERSwgSUxMRUdBTF9PUENPREUsIElMTEVHQUxfT1BDT0RFLAotICAgIElMTEVHQUxfT1BDT0RFLCAiaW1wZGVwMSIsICJpbXBkZXAyIgotICB9OwotCi0gIC8qKgotICAgKiBOdW1iZXIgb2Ygd29yZHMgY29uc3VtZWQgb24gb3BlcmFuZCBzdGFjayBieSBpbnN0cnVjdGlvbnMuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludFtdIENPTlNVTUVfU1RBQ0sgPSB7Ci0gICAgMC8qbm9wKi8sIDAvKmFjb25zdF9udWxsKi8sIDAvKmljb25zdF9tMSovLCAwLyppY29uc3RfMCovLCAwLyppY29uc3RfMSovLAotICAgIDAvKmljb25zdF8yKi8sIDAvKmljb25zdF8zKi8sIDAvKmljb25zdF80Ki8sIDAvKmljb25zdF81Ki8sIDAvKmxjb25zdF8wKi8sCi0gICAgMC8qbGNvbnN0XzEqLywgMC8qZmNvbnN0XzAqLywgMC8qZmNvbnN0XzEqLywgMC8qZmNvbnN0XzIqLywgMC8qZGNvbnN0XzAqLywKLSAgICAwLypkY29uc3RfMSovLCAwLypiaXB1c2gqLywgMC8qc2lwdXNoKi8sIDAvKmxkYyovLCAwLypsZGNfdyovLCAwLypsZGMyX3cqLywgMC8qaWxvYWQqLywKLSAgICAwLypsbG9hZCovLCAwLypmbG9hZCovLCAwLypkbG9hZCovLCAwLyphbG9hZCovLCAwLyppbG9hZF8wKi8sIDAvKmlsb2FkXzEqLywgMC8qaWxvYWRfMiovLAotICAgIDAvKmlsb2FkXzMqLywgMC8qbGxvYWRfMCovLCAwLypsbG9hZF8xKi8sIDAvKmxsb2FkXzIqLywgMC8qbGxvYWRfMyovLCAwLypmbG9hZF8wKi8sCi0gICAgMC8qZmxvYWRfMSovLCAwLypmbG9hZF8yKi8sIDAvKmZsb2FkXzMqLywgMC8qZGxvYWRfMCovLCAwLypkbG9hZF8xKi8sIDAvKmRsb2FkXzIqLywKLSAgICAwLypkbG9hZF8zKi8sIDAvKmFsb2FkXzAqLywgMC8qYWxvYWRfMSovLCAwLyphbG9hZF8yKi8sIDAvKmFsb2FkXzMqLywgMi8qaWFsb2FkKi8sCi0gICAgMi8qbGFsb2FkKi8sIDIvKmZhbG9hZCovLCAyLypkYWxvYWQqLywgMi8qYWFsb2FkKi8sIDIvKmJhbG9hZCovLCAyLypjYWxvYWQqLywgMi8qc2Fsb2FkKi8sCi0gICAgMS8qaXN0b3JlKi8sIDIvKmxzdG9yZSovLCAxLypmc3RvcmUqLywgMi8qZHN0b3JlKi8sIDEvKmFzdG9yZSovLCAxLyppc3RvcmVfMCovLAotICAgIDEvKmlzdG9yZV8xKi8sIDEvKmlzdG9yZV8yKi8sIDEvKmlzdG9yZV8zKi8sIDIvKmxzdG9yZV8wKi8sIDIvKmxzdG9yZV8xKi8sCi0gICAgMi8qbHN0b3JlXzIqLywgMi8qbHN0b3JlXzMqLywgMS8qZnN0b3JlXzAqLywgMS8qZnN0b3JlXzEqLywgMS8qZnN0b3JlXzIqLywKLSAgICAxLypmc3RvcmVfMyovLCAyLypkc3RvcmVfMCovLCAyLypkc3RvcmVfMSovLCAyLypkc3RvcmVfMiovLCAyLypkc3RvcmVfMyovLAotICAgIDEvKmFzdG9yZV8wKi8sIDEvKmFzdG9yZV8xKi8sIDEvKmFzdG9yZV8yKi8sIDEvKmFzdG9yZV8zKi8sIDMvKmlhc3RvcmUqLywgNC8qbGFzdG9yZSovLAotICAgIDMvKmZhc3RvcmUqLywgNC8qZGFzdG9yZSovLCAzLyphYXN0b3JlKi8sIDMvKmJhc3RvcmUqLywgMy8qY2FzdG9yZSovLCAzLypzYXN0b3JlKi8sCi0gICAgMS8qcG9wKi8sIDIvKnBvcDIqLywgMS8qZHVwKi8sIDIvKmR1cF94MSovLCAzLypkdXBfeDIqLywgMi8qZHVwMiovLCAzLypkdXAyX3gxKi8sCi0gICAgNC8qZHVwMl94MiovLCAyLypzd2FwKi8sIDIvKmlhZGQqLywgNC8qbGFkZCovLCAyLypmYWRkKi8sIDQvKmRhZGQqLywgMi8qaXN1YiovLCA0Lypsc3ViKi8sCi0gICAgMi8qZnN1YiovLCA0Lypkc3ViKi8sIDIvKmltdWwqLywgNC8qbG11bCovLCAyLypmbXVsKi8sIDQvKmRtdWwqLywgMi8qaWRpdiovLCA0LypsZGl2Ki8sCi0gICAgMi8qZmRpdiovLCA0LypkZGl2Ki8sIDIvKmlyZW0qLywgNC8qbHJlbSovLCAyLypmcmVtKi8sIDQvKmRyZW0qLywgMS8qaW5lZyovLCAyLypsbmVnKi8sCi0gICAgMS8qZm5lZyovLCAyLypkbmVnKi8sIDIvKmlzaGwqLywgMy8qbHNobCovLCAyLyppc2hyKi8sIDMvKmxzaHIqLywgMi8qaXVzaHIqLywgMy8qbHVzaHIqLywKLSAgICAyLyppYW5kKi8sIDQvKmxhbmQqLywgMi8qaW9yKi8sIDQvKmxvciovLCAyLyppeG9yKi8sIDQvKmx4b3IqLywgMC8qaWluYyovLAotICAgIDEvKmkybCovLCAxLyppMmYqLywgMS8qaTJkKi8sIDIvKmwyaSovLCAyLypsMmYqLywgMi8qbDJkKi8sIDEvKmYyaSovLCAxLypmMmwqLywKLSAgICAxLypmMmQqLywgMi8qZDJpKi8sIDIvKmQybCovLCAyLypkMmYqLywgMS8qaTJiKi8sIDEvKmkyYyovLCAxLyppMnMqLywKLSAgICA0LypsY21wKi8sIDIvKmZjbXBsKi8sIDIvKmZjbXBnKi8sIDQvKmRjbXBsKi8sIDQvKmRjbXBnKi8sIDEvKmlmZXEqLywgMS8qaWZuZSovLAotICAgIDEvKmlmbHQqLywgMS8qaWZnZSovLCAxLyppZmd0Ki8sIDEvKmlmbGUqLywgMi8qaWZfaWNtcGVxKi8sIDIvKmlmX2ljbXBuZSovLCAyLyppZl9pY21wbHQqLywKLSAgICAyIC8qaWZfaWNtcGdlKi8sIDIvKmlmX2ljbXBndCovLCAyLyppZl9pY21wbGUqLywgMi8qaWZfYWNtcGVxKi8sIDIvKmlmX2FjbXBuZSovLAotICAgIDAvKmdvdG8qLywgMC8qanNyKi8sIDAvKnJldCovLCAxLyp0YWJsZXN3aXRjaCovLCAxLypsb29rdXBzd2l0Y2gqLywgMS8qaXJldHVybiovLAotICAgIDIvKmxyZXR1cm4qLywgMS8qZnJldHVybiovLCAyLypkcmV0dXJuKi8sIDEvKmFyZXR1cm4qLywgMC8qcmV0dXJuKi8sIDAvKmdldHN0YXRpYyovLAotICAgIFVOUFJFRElDVEFCTEUvKnB1dHN0YXRpYyovLCAxLypnZXRmaWVsZCovLCBVTlBSRURJQ1RBQkxFLypwdXRmaWVsZCovLAotICAgIFVOUFJFRElDVEFCTEUvKmludm9rZXZpcnR1YWwqLywgVU5QUkVESUNUQUJMRS8qaW52b2tlc3BlY2lhbCovLAotICAgIFVOUFJFRElDVEFCTEUvKmludm9rZXN0YXRpYyovLAotICAgIFVOUFJFRElDVEFCTEUvKmludm9rZWludGVyZmFjZSovLCBVTkRFRklORUQsIDAvKm5ldyovLCAxLypuZXdhcnJheSovLCAxLyphbmV3YXJyYXkqLywKLSAgICAxLyphcnJheWxlbmd0aCovLCAxLyphdGhyb3cqLywgMS8qY2hlY2tjYXN0Ki8sIDEvKmluc3RhbmNlb2YqLywgMS8qbW9uaXRvcmVudGVyKi8sCi0gICAgMS8qbW9uaXRvcmV4aXQqLywgMC8qd2lkZSovLCBVTlBSRURJQ1RBQkxFLyptdWx0aWFuZXdhcnJheSovLCAxLyppZm51bGwqLywgMS8qaWZub25udWxsKi8sCi0gICAgMC8qZ290b193Ki8sIDAvKmpzcl93Ki8sIDAvKmJyZWFrcG9pbnQqLywgVU5ERUZJTkVELCBVTkRFRklORUQsCi0gICAgVU5ERUZJTkVELCBVTkRFRklORUQsIFVOREVGSU5FRCwgVU5ERUZJTkVELAotICAgIFVOREVGSU5FRCwgVU5ERUZJTkVELCBVTkRFRklORUQsIFVOREVGSU5FRCwKLSAgICBVTkRFRklORUQsIFVOREVGSU5FRCwgVU5ERUZJTkVELCBVTkRFRklORUQsCi0gICAgVU5ERUZJTkVELCBVTkRFRklORUQsIFVOREVGSU5FRCwgVU5ERUZJTkVELAotICAgIFVOREVGSU5FRCwgVU5ERUZJTkVELCBVTkRFRklORUQsIFVOREVGSU5FRCwKLSAgICBVTkRFRklORUQsIFVOREVGSU5FRCwgVU5ERUZJTkVELCBVTkRFRklORUQsCi0gICAgVU5ERUZJTkVELCBVTkRFRklORUQsIFVOREVGSU5FRCwgVU5ERUZJTkVELAotICAgIFVOREVGSU5FRCwgVU5ERUZJTkVELCBVTkRFRklORUQsIFVOREVGSU5FRCwKLSAgICBVTkRFRklORUQsIFVOREVGSU5FRCwgVU5ERUZJTkVELCBVTkRFRklORUQsCi0gICAgVU5ERUZJTkVELCBVTkRFRklORUQsIFVOREVGSU5FRCwgVU5ERUZJTkVELAotICAgIFVOREVGSU5FRCwgVU5ERUZJTkVELCBVTkRFRklORUQsIFVOREVGSU5FRCwKLSAgICBVTkRFRklORUQsIFVOREVGSU5FRCwgVU5ERUZJTkVELCBVTkRFRklORUQsCi0gICAgVU5ERUZJTkVELCBVTlBSRURJQ1RBQkxFLyppbXBkZXAxKi8sIFVOUFJFRElDVEFCTEUvKmltcGRlcDIqLwotICB9OwotCi0gIC8qKgotICAgKiBOdW1iZXIgb2Ygd29yZHMgcHJvZHVjZWQgb250byBvcGVyYW5kIHN0YWNrIGJ5IGluc3RydWN0aW9ucy4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50W10gUFJPRFVDRV9TVEFDSyA9IHsKLSAgICAwLypub3AqLywgMS8qYWNvbnN0X251bGwqLywgMS8qaWNvbnN0X20xKi8sIDEvKmljb25zdF8wKi8sIDEvKmljb25zdF8xKi8sCi0gICAgMS8qaWNvbnN0XzIqLywgMS8qaWNvbnN0XzMqLywgMS8qaWNvbnN0XzQqLywgMS8qaWNvbnN0XzUqLywgMi8qbGNvbnN0XzAqLywKLSAgICAyLypsY29uc3RfMSovLCAxLypmY29uc3RfMCovLCAxLypmY29uc3RfMSovLCAxLypmY29uc3RfMiovLCAyLypkY29uc3RfMCovLAotICAgIDIvKmRjb25zdF8xKi8sIDEvKmJpcHVzaCovLCAxLypzaXB1c2gqLywgMS8qbGRjKi8sIDEvKmxkY193Ki8sIDIvKmxkYzJfdyovLCAxLyppbG9hZCovLAotICAgIDIvKmxsb2FkKi8sIDEvKmZsb2FkKi8sIDIvKmRsb2FkKi8sIDEvKmFsb2FkKi8sIDEvKmlsb2FkXzAqLywgMS8qaWxvYWRfMSovLCAxLyppbG9hZF8yKi8sCi0gICAgMS8qaWxvYWRfMyovLCAyLypsbG9hZF8wKi8sIDIvKmxsb2FkXzEqLywgMi8qbGxvYWRfMiovLCAyLypsbG9hZF8zKi8sIDEvKmZsb2FkXzAqLywKLSAgICAxLypmbG9hZF8xKi8sIDEvKmZsb2FkXzIqLywgMS8qZmxvYWRfMyovLCAyLypkbG9hZF8wKi8sIDIvKmRsb2FkXzEqLywgMi8qZGxvYWRfMiovLAotICAgIDIvKmRsb2FkXzMqLywgMS8qYWxvYWRfMCovLCAxLyphbG9hZF8xKi8sIDEvKmFsb2FkXzIqLywgMS8qYWxvYWRfMyovLCAxLyppYWxvYWQqLywKLSAgICAyLypsYWxvYWQqLywgMS8qZmFsb2FkKi8sIDIvKmRhbG9hZCovLCAxLyphYWxvYWQqLywgMS8qYmFsb2FkKi8sIDEvKmNhbG9hZCovLCAxLypzYWxvYWQqLywKLSAgICAwLyppc3RvcmUqLywgMC8qbHN0b3JlKi8sIDAvKmZzdG9yZSovLCAwLypkc3RvcmUqLywgMC8qYXN0b3JlKi8sIDAvKmlzdG9yZV8wKi8sCi0gICAgMC8qaXN0b3JlXzEqLywgMC8qaXN0b3JlXzIqLywgMC8qaXN0b3JlXzMqLywgMC8qbHN0b3JlXzAqLywgMC8qbHN0b3JlXzEqLywKLSAgICAwLypsc3RvcmVfMiovLCAwLypsc3RvcmVfMyovLCAwLypmc3RvcmVfMCovLCAwLypmc3RvcmVfMSovLCAwLypmc3RvcmVfMiovLAotICAgIDAvKmZzdG9yZV8zKi8sIDAvKmRzdG9yZV8wKi8sIDAvKmRzdG9yZV8xKi8sIDAvKmRzdG9yZV8yKi8sIDAvKmRzdG9yZV8zKi8sCi0gICAgMC8qYXN0b3JlXzAqLywgMC8qYXN0b3JlXzEqLywgMC8qYXN0b3JlXzIqLywgMC8qYXN0b3JlXzMqLywgMC8qaWFzdG9yZSovLCAwLypsYXN0b3JlKi8sCi0gICAgMC8qZmFzdG9yZSovLCAwLypkYXN0b3JlKi8sIDAvKmFhc3RvcmUqLywgMC8qYmFzdG9yZSovLCAwLypjYXN0b3JlKi8sIDAvKnNhc3RvcmUqLywKLSAgICAwLypwb3AqLywgMC8qcG9wMiovLCAyLypkdXAqLywgMy8qZHVwX3gxKi8sIDQvKmR1cF94MiovLCA0LypkdXAyKi8sIDUvKmR1cDJfeDEqLywKLSAgICA2LypkdXAyX3gyKi8sIDIvKnN3YXAqLywgMS8qaWFkZCovLCAyLypsYWRkKi8sIDEvKmZhZGQqLywgMi8qZGFkZCovLCAxLyppc3ViKi8sIDIvKmxzdWIqLywKLSAgICAxLypmc3ViKi8sIDIvKmRzdWIqLywgMS8qaW11bCovLCAyLypsbXVsKi8sIDEvKmZtdWwqLywgMi8qZG11bCovLCAxLyppZGl2Ki8sIDIvKmxkaXYqLywKLSAgICAxLypmZGl2Ki8sIDIvKmRkaXYqLywgMS8qaXJlbSovLCAyLypscmVtKi8sIDEvKmZyZW0qLywgMi8qZHJlbSovLCAxLyppbmVnKi8sIDIvKmxuZWcqLywKLSAgICAxLypmbmVnKi8sIDIvKmRuZWcqLywgMS8qaXNobCovLCAyLypsc2hsKi8sIDEvKmlzaHIqLywgMi8qbHNociovLCAxLyppdXNociovLCAyLypsdXNociovLAotICAgIDEvKmlhbmQqLywgMi8qbGFuZCovLCAxLyppb3IqLywgMi8qbG9yKi8sIDEvKml4b3IqLywgMi8qbHhvciovLAotICAgIDAvKmlpbmMqLywgMi8qaTJsKi8sIDEvKmkyZiovLCAyLyppMmQqLywgMS8qbDJpKi8sIDEvKmwyZiovLCAyLypsMmQqLywgMS8qZjJpKi8sCi0gICAgMi8qZjJsKi8sIDIvKmYyZCovLCAxLypkMmkqLywgMi8qZDJsKi8sIDEvKmQyZiovLAotICAgIDEvKmkyYiovLCAxLyppMmMqLywgMS8qaTJzKi8sIDEvKmxjbXAqLywgMS8qZmNtcGwqLywgMS8qZmNtcGcqLywKLSAgICAxLypkY21wbCovLCAxLypkY21wZyovLCAwLyppZmVxKi8sIDAvKmlmbmUqLywgMC8qaWZsdCovLCAwLyppZmdlKi8sIDAvKmlmZ3QqLywgMC8qaWZsZSovLAotICAgIDAvKmlmX2ljbXBlcSovLCAwLyppZl9pY21wbmUqLywgMC8qaWZfaWNtcGx0Ki8sIDAvKmlmX2ljbXBnZSovLCAwLyppZl9pY21wZ3QqLywKLSAgICAwLyppZl9pY21wbGUqLywgMC8qaWZfYWNtcGVxKi8sIDAvKmlmX2FjbXBuZSovLCAwLypnb3RvKi8sIDEvKmpzciovLCAwLypyZXQqLywKLSAgICAwLyp0YWJsZXN3aXRjaCovLCAwLypsb29rdXBzd2l0Y2gqLywgMC8qaXJldHVybiovLCAwLypscmV0dXJuKi8sIDAvKmZyZXR1cm4qLywKLSAgICAwLypkcmV0dXJuKi8sIDAvKmFyZXR1cm4qLywgMC8qcmV0dXJuKi8sIFVOUFJFRElDVEFCTEUvKmdldHN0YXRpYyovLCAwLypwdXRzdGF0aWMqLywKLSAgICBVTlBSRURJQ1RBQkxFLypnZXRmaWVsZCovLCAwLypwdXRmaWVsZCovLCBVTlBSRURJQ1RBQkxFLyppbnZva2V2aXJ0dWFsKi8sCi0gICAgVU5QUkVESUNUQUJMRS8qaW52b2tlc3BlY2lhbCovLCBVTlBSRURJQ1RBQkxFLyppbnZva2VzdGF0aWMqLywKLSAgICBVTlBSRURJQ1RBQkxFLyppbnZva2VpbnRlcmZhY2UqLywgVU5ERUZJTkVELCAxLypuZXcqLywgMS8qbmV3YXJyYXkqLywgMS8qYW5ld2FycmF5Ki8sCi0gICAgMS8qYXJyYXlsZW5ndGgqLywgMS8qYXRocm93Ki8sIDEvKmNoZWNrY2FzdCovLCAxLyppbnN0YW5jZW9mKi8sIDAvKm1vbml0b3JlbnRlciovLAotICAgIDAvKm1vbml0b3JleGl0Ki8sIDAvKndpZGUqLywgMS8qbXVsdGlhbmV3YXJyYXkqLywgMC8qaWZudWxsKi8sIDAvKmlmbm9ubnVsbCovLAotICAgIDAvKmdvdG9fdyovLCAxLypqc3JfdyovLCAwLypicmVha3BvaW50Ki8sIFVOREVGSU5FRCwgVU5ERUZJTkVELAotICAgIFVOREVGSU5FRCwgVU5ERUZJTkVELCBVTkRFRklORUQsIFVOREVGSU5FRCwKLSAgICBVTkRFRklORUQsIFVOREVGSU5FRCwgVU5ERUZJTkVELCBVTkRFRklORUQsCi0gICAgVU5ERUZJTkVELCBVTkRFRklORUQsIFVOREVGSU5FRCwgVU5ERUZJTkVELAotICAgIFVOREVGSU5FRCwgVU5ERUZJTkVELCBVTkRFRklORUQsIFVOREVGSU5FRCwKLSAgICBVTkRFRklORUQsIFVOREVGSU5FRCwgVU5ERUZJTkVELCBVTkRFRklORUQsCi0gICAgVU5ERUZJTkVELCBVTkRFRklORUQsIFVOREVGSU5FRCwgVU5ERUZJTkVELAotICAgIFVOREVGSU5FRCwgVU5ERUZJTkVELCBVTkRFRklORUQsIFVOREVGSU5FRCwKLSAgICBVTkRFRklORUQsIFVOREVGSU5FRCwgVU5ERUZJTkVELCBVTkRFRklORUQsCi0gICAgVU5ERUZJTkVELCBVTkRFRklORUQsIFVOREVGSU5FRCwgVU5ERUZJTkVELAotICAgIFVOREVGSU5FRCwgVU5ERUZJTkVELCBVTkRFRklORUQsIFVOREVGSU5FRCwKLSAgICBVTkRFRklORUQsIFVOREVGSU5FRCwgVU5ERUZJTkVELCBVTkRFRklORUQsCi0gICAgVU5ERUZJTkVELCBVTkRFRklORUQsIFVOREVGSU5FRCwgVU5ERUZJTkVELAotICAgIFVOREVGSU5FRCwgVU5QUkVESUNUQUJMRS8qaW1wZGVwMSovLCBVTlBSRURJQ1RBQkxFLyppbXBkZXAyKi8KLSAgfTsKLQotICAvKiogQXR0cmlidXRlcyBhbmQgdGhlaXIgY29ycmVzcG9uZGluZyBuYW1lcy4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZSBBVFRSX1VOS05PV04gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IC0xOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgQVRUUl9TT1VSQ0VfRklMRSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAwOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgQVRUUl9DT05TVEFOVF9WQUxVRSAgICAgICAgICAgICAgICAgICAgICAgICAgPSAxOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgQVRUUl9DT0RFICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAyOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgQVRUUl9FWENFUFRJT05TICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAzOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgQVRUUl9MSU5FX05VTUJFUl9UQUJMRSAgICAgICAgICAgICAgICAgICAgICAgPSA0OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgQVRUUl9MT0NBTF9WQVJJQUJMRV9UQUJMRSAgICAgICAgICAgICAgICAgICAgPSA1OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgQVRUUl9JTk5FUl9DTEFTU0VTICAgICAgICAgICAgICAgICAgICAgICAgICAgPSA2OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgQVRUUl9TWU5USEVUSUMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSA3OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgQVRUUl9ERVBSRUNBVEVEICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSA4OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgQVRUUl9QTUcgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSA5OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgQVRUUl9TSUdOQVRVUkUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAxMDsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBieXRlIEFUVFJfU1RBQ0tfTUFQICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gMTE7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZSBBVFRSX0xPQ0FMX1ZBUklBQkxFX1RZUEVfVEFCTEUgICAgICAgICAgICAgICA9IDEyOwotCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgS05PV05fQVRUUklCVVRFUyA9IDEzOwotCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nW10gQVRUUklCVVRFX05BTUVTID0gewotICAgICJTb3VyY2VGaWxlIiwgIkNvbnN0YW50VmFsdWUiLCAiQ29kZSIsICJFeGNlcHRpb25zIiwKLSAgICAiTGluZU51bWJlclRhYmxlIiwgIkxvY2FsVmFyaWFibGVUYWJsZSIsCi0gICAgIklubmVyQ2xhc3NlcyIsICJTeW50aGV0aWMiLCAiRGVwcmVjYXRlZCIsCi0gICAgIlBNR0NsYXNzIiwgIlNpZ25hdHVyZSIsICJTdGFja01hcCIsCi0gICAgIkxvY2FsVmFyaWFibGVUeXBlVGFibGUiCi0gIH07Ci0KLSAgLyoqIENvbnN0YW50cyB1c2VkIGluIHRoZSBTdGFja01hcCBhdHRyaWJ1dGUuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgSVRFTV9Cb2d1cyAgICAgID0gMDsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBieXRlIElURU1fSW50ZWdlciAgICA9IDE7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZSBJVEVNX0Zsb2F0ICAgICAgPSAyOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgSVRFTV9Eb3VibGUgICAgID0gMzsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBieXRlIElURU1fTG9uZyAgICAgICA9IDQ7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZSBJVEVNX051bGwgICAgICAgPSA1OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgSVRFTV9Jbml0T2JqZWN0ID0gNjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBieXRlIElURU1fT2JqZWN0ICAgICA9IDc7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZSBJVEVNX05ld09iamVjdCAgPSA4OwotCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nW10gSVRFTV9OQU1FUyA9IHsKLSAgICAiQm9ndXMiLCAiSW50ZWdlciIsICJGbG9hdCIsICJEb3VibGUiLCAiTG9uZyIsCi0gICAgIk51bGwiLCAiSW5pdE9iamVjdCIsICJPYmplY3QiLCAiTmV3T2JqZWN0IgotICB9OwotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL0V4Y2VwdGlvbkNvbnN0YW50cy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL0V4Y2VwdGlvbkNvbnN0YW50cy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4ZmQzMjA0Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9FeGNlcHRpb25Db25zdGFudHMuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEyNiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbDsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotLyoqCi0gKiBFeGNlcHRpb24gY29uc3RhbnRzLgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Imh0dHA6Ly93d3cuaW5mLmZ1LWJlcmxpbi5kZS9+ZWhhYXNlIj5FLiBIYWFzZTwvQT4KLSAqLwotcHVibGljIGludGVyZmFjZSBFeGNlcHRpb25Db25zdGFudHMgewotICAvKiogVGhlIG1vdGhlciBvZiBhbGwgZXhjZXB0aW9ucwotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBDbGFzcyBUSFJPV0FCTEUgPSBUaHJvd2FibGUuY2xhc3M7Ci0KLSAgLyoqIFN1cGVyIGNsYXNzIG9mIGFueSBydW4tdGltZSBleGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgQ2xhc3MgUlVOVElNRV9FWENFUFRJT04gPSBSdW50aW1lRXhjZXB0aW9uLmNsYXNzOwotCi0gIC8qKiBTdXBlciBjbGFzcyBvZiBhbnkgbGlua2luZyBleGNlcHRpb24gKGFrYSBMaW5rYWdlIEVycm9yKQotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBDbGFzcyBMSU5LSU5HX0VYQ0VQVElPTiA9IExpbmthZ2VFcnJvci5jbGFzczsKLQotICAvKiogTGlua2luZyBFeGNlcHRpb25zCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIENsYXNzIENMQVNTX0NJUkNVTEFSSVRZX0VSUk9SICAgICAgICAgPSBDbGFzc0NpcmN1bGFyaXR5RXJyb3IuY2xhc3M7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgQ2xhc3MgQ0xBU1NfRk9STUFUX0VSUk9SICAgICAgICAgICAgICA9IENsYXNzRm9ybWF0RXJyb3IuY2xhc3M7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgQ2xhc3MgRVhDRVBUSU9OX0lOX0lOSVRJQUxJWkVSX0VSUk9SICA9IEV4Y2VwdGlvbkluSW5pdGlhbGl6ZXJFcnJvci5jbGFzczsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBDbGFzcyBJTkNPTVBBVElCTEVfQ0xBU1NfQ0hBTkdFX0VSUk9SID0gSW5jb21wYXRpYmxlQ2xhc3NDaGFuZ2VFcnJvci5jbGFzczsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBDbGFzcyBBQlNUUkFDVF9NRVRIT0RfRVJST1IgICAgICAgICAgID0gQWJzdHJhY3RNZXRob2RFcnJvci5jbGFzczsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBDbGFzcyBJTExFR0FMX0FDQ0VTU19FUlJPUiAgICAgICAgICAgID0gSWxsZWdhbEFjY2Vzc0Vycm9yLmNsYXNzOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIENsYXNzIElOU1RBTlRJQVRJT05fRVJST1IgICAgICAgICAgICAgPSBJbnN0YW50aWF0aW9uRXJyb3IuY2xhc3M7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgQ2xhc3MgTk9fU1VDSF9GSUVMRF9FUlJPUiAgICAgICAgICAgICA9IE5vU3VjaEZpZWxkRXJyb3IuY2xhc3M7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgQ2xhc3MgTk9fU1VDSF9NRVRIT0RfRVJST1IgICAgICAgICAgICA9IE5vU3VjaE1ldGhvZEVycm9yLmNsYXNzOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIENsYXNzIE5PX0NMQVNTX0RFRl9GT1VORF9FUlJPUiAgICAgICAgPSBOb0NsYXNzRGVmRm91bmRFcnJvci5jbGFzczsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBDbGFzcyBVTlNBVElTRklFRF9MSU5LX0VSUk9SICAgICAgICAgID0gVW5zYXRpc2ZpZWRMaW5rRXJyb3IuY2xhc3M7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgQ2xhc3MgVkVSSUZZX0VSUk9SICAgICAgICAgICAgICAgICAgICA9IFZlcmlmeUVycm9yLmNsYXNzOwotCi0gIC8qIFVuc3VwcG9ydGVkQ2xhc3NWZXJzaW9uRXJyb3IgaXMgbmV3IGluIEpESyAxLjIgKi8KLSAgLy9wdWJsaWMgc3RhdGljIGZpbmFsIENsYXNzIFVuc3VwcG9ydGVkQ2xhc3NWZXJzaW9uRXJyb3IgPSBVbnN1cHBvcnRlZENsYXNzVmVyc2lvbkVycm9yLmNsYXNzOwotCi0gIC8qKiBSdW4tVGltZSBFeGNlcHRpb25zCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIENsYXNzIE5VTExfUE9JTlRFUl9FWENFUFRJT04gICAgICAgICAgICAgID0gTnVsbFBvaW50ZXJFeGNlcHRpb24uY2xhc3M7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgQ2xhc3MgQVJSQVlfSU5ERVhfT1VUX09GX0JPVU5EU19FWENFUFRJT04gPSBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24uY2xhc3M7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgQ2xhc3MgQVJJVEhNRVRJQ19FWENFUFRJT04gICAgICAgICAgICAgICAgPSBBcml0aG1ldGljRXhjZXB0aW9uLmNsYXNzOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIENsYXNzIE5FR0FUSVZFX0FSUkFZX1NJWkVfRVhDRVBUSU9OICAgICAgID0gTmVnYXRpdmVBcnJheVNpemVFeGNlcHRpb24uY2xhc3M7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgQ2xhc3MgQ0xBU1NfQ0FTVF9FWENFUFRJT04gICAgICAgICAgICAgICAgPSBDbGFzc0Nhc3RFeGNlcHRpb24uY2xhc3M7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgQ2xhc3MgSUxMRUdBTF9NT05JVE9SX1NUQVRFICAgICAgICAgICAgICAgPSBJbGxlZ2FsTW9uaXRvclN0YXRlRXhjZXB0aW9uLmNsYXNzOwotCi0gIC8qKiBQcmUtZGVmaW5lZCBleGNlcHRpb24gYXJyYXlzIGFjY29yZGluZyB0byBjaGFwdGVycyA1LjEtNS40IG9mIHRoZSBKYXZhIFZpcnR1YWwKLSAgICogTWFjaGluZSBTcGVjaWZpY2F0aW9uCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIENsYXNzW10gRVhDU19DTEFTU19BTkRfSU5URVJGQUNFX1JFU09MVVRJT04gPSB7Ci0gICAgTk9fQ0xBU1NfREVGX0ZPVU5EX0VSUk9SLCBDTEFTU19GT1JNQVRfRVJST1IsIFZFUklGWV9FUlJPUiwgQUJTVFJBQ1RfTUVUSE9EX0VSUk9SLAotICAgIEVYQ0VQVElPTl9JTl9JTklUSUFMSVpFUl9FUlJPUiwgSUxMRUdBTF9BQ0NFU1NfRVJST1IKLSAgfTsgLy8gQ2hhcHRlciA1LjEKLQotICBwdWJsaWMgc3RhdGljIGZpbmFsIENsYXNzW10gRVhDU19GSUVMRF9BTkRfTUVUSE9EX1JFU09MVVRJT04gPSB7Ci0gICAgTk9fU1VDSF9GSUVMRF9FUlJPUiwgSUxMRUdBTF9BQ0NFU1NfRVJST1IsIE5PX1NVQ0hfTUVUSE9EX0VSUk9SCi0gIH07IC8vIENoYXB0ZXIgNS4yCi0KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBDbGFzc1tdIEVYQ1NfSU5URVJGQUNFX01FVEhPRF9SRVNPTFVUSU9OID0gbmV3IENsYXNzWzBdOyAvLyBDaGFwdGVyIDUuMyAoYXMgYmVsb3cpCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgQ2xhc3NbXSBFWENTX1NUUklOR19SRVNPTFVUSU9OICAgICAgICAgICA9IG5ldyBDbGFzc1swXTsKLSAgLy8gQ2hhcHRlciA1LjQgKG5vIGVycm9ycyBidXQgdGhlIG9uZXMgdGhhdCBfYWx3YXlzXyBjb3VsZCBoYXBwZW4hIEhvdyBzdHVwaWQuKQotCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgQ2xhc3NbXSBFWENTX0FSUkFZX0VYQ0VQVElPTiA9IHsKLSAgICBOVUxMX1BPSU5URVJfRVhDRVBUSU9OLCBBUlJBWV9JTkRFWF9PVVRfT0ZfQk9VTkRTX0VYQ0VQVElPTgotICB9OwotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvUmVwb3NpdG9yeS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL1JlcG9zaXRvcnkuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggY2E3YzY1YS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvUmVwb3NpdG9yeS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjUwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuY2xhc3NmaWxlLkphdmFDbGFzczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC51dGlsLio7Ci1pbXBvcnQgamF2YS5pby4qOwotCi0vKioKLSAqIFRoZSByZXBvc2l0b3J5IG1haW50YWlucyBpbmZvcm1hdGlvbnMgYWJvdXQgY2xhc3MgaW50ZXJkZXBlbmRlbmNpZXMsIGUuZy4sCi0gKiB3aGV0aGVyIGEgY2xhc3MgaXMgYSBzdWItY2xhc3Mgb2YgYW5vdGhlci4gRGVsZWdhdGVzIGFjdHVhbCBjbGFzcyBsb2FkaW5nCi0gKiB0byBTeW50aGV0aWNSZXBvc2l0b3J5IHdpdGggY3VycmVudCBjbGFzcyBwYXRoIGJ5IGRlZmF1bHQuCi0gKgotICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC51dGlsLlJlcG9zaXRvcnkKLSAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwudXRpbC5TeW50aGV0aWNSZXBvc2l0b3J5Ci0gKgotICogQGF1dGhvciA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgYWJzdHJhY3QgY2xhc3MgUmVwb3NpdG9yeSB7Ci0gIHByaXZhdGUgc3RhdGljIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLnV0aWwuUmVwb3NpdG9yeSBfcmVwb3NpdG9yeSA9Ci0gICAgU3ludGhldGljUmVwb3NpdG9yeS5nZXRJbnN0YW5jZSgpOwotCi0gIC8qKiBAcmV0dXJuIGN1cnJlbnRseSB1c2VkIHJlcG9zaXRvcnkgaW5zdGFuY2UKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwudXRpbC5SZXBvc2l0b3J5IGdldFJlcG9zaXRvcnkoKSB7Ci0gICAgcmV0dXJuIF9yZXBvc2l0b3J5OwotICB9Ci0KLSAgLyoqIFNldCByZXBvc2l0b3J5IGluc3RhbmNlIHRvIGJlIHVzZWQgZm9yIGNsYXNzIGxvYWRpbmcKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgdm9pZCBzZXRSZXBvc2l0b3J5KGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLnV0aWwuUmVwb3NpdG9yeSByZXApIHsKLSAgICBfcmVwb3NpdG9yeSA9IHJlcDsKLSAgfQotCi0gIC8qKiBMb29rdXAgY2xhc3Mgc29tZXdoZXJlIGZvdW5kIG9uIHlvdXIgQ0xBU1NQQVRILCBvciB3aGVyZWV2ZXIgdGhlCi0gICAqIHJlcG9zaXRvcnkgaW5zdGFuY2UgbG9va3MgZm9yIGl0LgotICAgKgotICAgKiBAcmV0dXJuIGNsYXNzIG9iamVjdCBmb3IgZ2l2ZW4gZnVsbHkgcXVhbGlmaWVkIGNsYXNzIG5hbWUsIG9yIG51bGwKLSAgICogaWYgdGhlIGNsYXNzIGNvdWxkIG5vdCBiZSBmb3VuZCBvciBwYXJzZWQgY29ycmVjdGx5Ci0gICAqLwotICBwdWJsaWMgc3RhdGljIEphdmFDbGFzcyBsb29rdXBDbGFzcyhTdHJpbmcgY2xhc3NfbmFtZSkgewotICAgIHRyeSB7Ci0gICAgICBKYXZhQ2xhc3MgY2xhenogPSBfcmVwb3NpdG9yeS5maW5kQ2xhc3MoY2xhc3NfbmFtZSk7Ci0KLSAgICAgIGlmKGNsYXp6ID09IG51bGwpIHsKLSAgICAgICAgcmV0dXJuIF9yZXBvc2l0b3J5LmxvYWRDbGFzcyhjbGFzc19uYW1lKTsKLSAgICAgIH0gZWxzZSB7Ci0gICAgICAgIHJldHVybiBjbGF6ejsKLSAgICAgIH0KLSAgICB9IGNhdGNoKENsYXNzTm90Rm91bmRFeGNlcHRpb24gZXgpIHsgcmV0dXJuIG51bGw7IH0KLSAgfQotCi0gIC8qKgotICAgKiBUcnkgdG8gZmluZCBjbGFzcyBzb3VyY2UgdmlhIGdldFJlc291cmNlQXNTdHJlYW0oKS4KLSAgICogQHNlZSBDbGFzcwotICAgKiBAcmV0dXJuIEphdmFDbGFzcyBvYmplY3QgZm9yIGdpdmVuIHJ1bnRpbWUgY2xhc3MKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgSmF2YUNsYXNzIGxvb2t1cENsYXNzKENsYXNzIGNsYXp6KSB7Ci0gICAgdHJ5IHsKLSAgICAgIHJldHVybiBfcmVwb3NpdG9yeS5sb2FkQ2xhc3MoY2xhenopOwotICAgIH0gY2F0Y2goQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBleCkgeyByZXR1cm4gbnVsbDsgfQotICB9Ci0KLSAgLyoqIEByZXR1cm4gY2xhc3MgZmlsZSBvYmplY3QgZm9yIGdpdmVuIEphdmEgY2xhc3MuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIENsYXNzUGF0aC5DbGFzc0ZpbGUgbG9va3VwQ2xhc3NGaWxlKFN0cmluZyBjbGFzc19uYW1lKSB7Ci0gICAgdHJ5IHsKLSAgICAgIHJldHVybiBDbGFzc1BhdGguU1lTVEVNX0NMQVNTX1BBVEguZ2V0Q2xhc3NGaWxlKGNsYXNzX25hbWUpOwotICAgIH0gY2F0Y2goSU9FeGNlcHRpb24gZSkgeyByZXR1cm4gbnVsbDsgfQotICB9Ci0KLSAgLyoqIENsZWFyIHRoZSByZXBvc2l0b3J5LgotICAgKi8KLSAgcHVibGljIHN0YXRpYyB2b2lkIGNsZWFyQ2FjaGUoKSB7Ci0gICAgX3JlcG9zaXRvcnkuY2xlYXIoKTsKLSAgfQotCi0gIC8qKgotICAgKiBBZGQgY2xhenogdG8gcmVwb3NpdG9yeSBpZiB0aGVyZSBpc24ndCBhbiBlcXVhbGx5IG5hbWVkIGNsYXNzIGFscmVhZHkgaW4gdGhlcmUuCi0gICAqCi0gICAqIEByZXR1cm4gb2xkIGVudHJ5IGluIHJlcG9zaXRvcnkKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgSmF2YUNsYXNzIGFkZENsYXNzKEphdmFDbGFzcyBjbGF6eikgewotICAgIEphdmFDbGFzcyBvbGQgPSBfcmVwb3NpdG9yeS5maW5kQ2xhc3MoY2xhenouZ2V0Q2xhc3NOYW1lKCkpOwotICAgIF9yZXBvc2l0b3J5LnN0b3JlQ2xhc3MoY2xhenopOwotICAgIHJldHVybiBvbGQ7Ci0gIH0KLQotICAvKioKLSAgICogUmVtb3ZlIGNsYXNzIHdpdGggZ2l2ZW4gKGZ1bGx5IHF1YWxpZmllZCkgbmFtZSBmcm9tIHJlcG9zaXRvcnkuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIHZvaWQgcmVtb3ZlQ2xhc3MoU3RyaW5nIGNsYXp6KSB7Ci0gICAgX3JlcG9zaXRvcnkucmVtb3ZlQ2xhc3MoX3JlcG9zaXRvcnkuZmluZENsYXNzKGNsYXp6KSk7Ci0gIH0KLQotICAvKioKLSAgICogUmVtb3ZlIGdpdmVuIGNsYXNzIGZyb20gcmVwb3NpdG9yeS4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgdm9pZCByZW1vdmVDbGFzcyhKYXZhQ2xhc3MgY2xhenopIHsKLSAgICBfcmVwb3NpdG9yeS5yZW1vdmVDbGFzcyhjbGF6eik7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBsaXN0IG9mIHN1cGVyIGNsYXNzZXMgb2YgY2xhenogaW4gYXNjZW5kaW5nIG9yZGVyLCBpLmUuLAotICAgKiBPYmplY3QgaXMgYWx3YXlzIHRoZSBsYXN0IGVsZW1lbnQKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgSmF2YUNsYXNzW10gZ2V0U3VwZXJDbGFzc2VzKEphdmFDbGFzcyBjbGF6eikgewotICAgIHJldHVybiBjbGF6ei5nZXRTdXBlckNsYXNzZXMoKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIGxpc3Qgb2Ygc3VwZXIgY2xhc3NlcyBvZiBjbGF6eiBpbiBhc2NlbmRpbmcgb3JkZXIsIGkuZS4sCi0gICAqIE9iamVjdCBpcyBhbHdheXMgdGhlIGxhc3QgZWxlbWVudC4gcmV0dXJuICJudWxsIiwgaWYgY2xhc3MKLSAgICogY2Fubm90IGJlIGZvdW5kLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBKYXZhQ2xhc3NbXSBnZXRTdXBlckNsYXNzZXMoU3RyaW5nIGNsYXNzX25hbWUpIHsKLSAgICBKYXZhQ2xhc3MgamMgPSBsb29rdXBDbGFzcyhjbGFzc19uYW1lKTsKLSAgICByZXR1cm4gKGpjID09IG51bGw/IG51bGwgOiBnZXRTdXBlckNsYXNzZXMoamMpKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIGFsbCBpbnRlcmZhY2VzIGltcGxlbWVudGVkIGJ5IGNsYXNzIGFuZCBpdHMgc3VwZXIKLSAgICogY2xhc3NlcyBhbmQgdGhlIGludGVyZmFjZXMgdGhhdCB0aG9zZSBpbnRlcmZhY2VzIGV4dGVuZCwgYW5kIHNvIG9uLgotICAgKiAoU29tZSBwZW9wbGUgY2FsbCB0aGlzIGEgdHJhbnNpdGl2ZSBodWxsKS4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgSmF2YUNsYXNzW10gZ2V0SW50ZXJmYWNlcyhKYXZhQ2xhc3MgY2xhenopIHsKLSAgICByZXR1cm4gY2xhenouZ2V0QWxsSW50ZXJmYWNlcygpOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gYWxsIGludGVyZmFjZXMgaW1wbGVtZW50ZWQgYnkgY2xhc3MgYW5kIGl0cyBzdXBlcgotICAgKiBjbGFzc2VzIGFuZCB0aGUgaW50ZXJmYWNlcyB0aGF0IGV4dGVuZCB0aG9zZSBpbnRlcmZhY2VzLCBhbmQgc28gb24KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgSmF2YUNsYXNzW10gZ2V0SW50ZXJmYWNlcyhTdHJpbmcgY2xhc3NfbmFtZSkgewotICAgIHJldHVybiBnZXRJbnRlcmZhY2VzKGxvb2t1cENsYXNzKGNsYXNzX25hbWUpKTsKLSAgfQotCi0gIC8qKgotICAgKiBFcXVpdmFsZW50IHRvIHJ1bnRpbWUgImluc3RhbmNlb2YiIG9wZXJhdG9yLgotICAgKiBAcmV0dXJuIHRydWUsIGlmIGNsYXp6IGlzIGFuIGluc3RhbmNlIG9mIHN1cGVyX2NsYXNzCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaW5zdGFuY2VPZihKYXZhQ2xhc3MgY2xhenosIEphdmFDbGFzcyBzdXBlcl9jbGFzcykgewotICAgIHJldHVybiBjbGF6ei5pbnN0YW5jZU9mKHN1cGVyX2NsYXNzKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIHRydWUsIGlmIGNsYXp6IGlzIGFuIGluc3RhbmNlIG9mIHN1cGVyX2NsYXNzCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaW5zdGFuY2VPZihTdHJpbmcgY2xhenosIFN0cmluZyBzdXBlcl9jbGFzcykgewotICAgIHJldHVybiBpbnN0YW5jZU9mKGxvb2t1cENsYXNzKGNsYXp6KSwgbG9va3VwQ2xhc3Moc3VwZXJfY2xhc3MpKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIHRydWUsIGlmIGNsYXp6IGlzIGFuIGluc3RhbmNlIG9mIHN1cGVyX2NsYXNzCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaW5zdGFuY2VPZihKYXZhQ2xhc3MgY2xhenosIFN0cmluZyBzdXBlcl9jbGFzcykgewotICAgIHJldHVybiBpbnN0YW5jZU9mKGNsYXp6LCBsb29rdXBDbGFzcyhzdXBlcl9jbGFzcykpOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gdHJ1ZSwgaWYgY2xhenogaXMgYW4gaW5zdGFuY2Ugb2Ygc3VwZXJfY2xhc3MKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpbnN0YW5jZU9mKFN0cmluZyBjbGF6eiwgSmF2YUNsYXNzIHN1cGVyX2NsYXNzKSB7Ci0gICAgcmV0dXJuIGluc3RhbmNlT2YobG9va3VwQ2xhc3MoY2xhenopLCBzdXBlcl9jbGFzcyk7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiB0cnVlLCBpZiBjbGF6eiBpcyBhbiBpbXBsZW1lbnRhdGlvbiBvZiBpbnRlcmZhY2UgaW50ZXIKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpbXBsZW1lbnRhdGlvbk9mKEphdmFDbGFzcyBjbGF6eiwgSmF2YUNsYXNzIGludGVyKSB7Ci0gICAgcmV0dXJuIGNsYXp6LmltcGxlbWVudGF0aW9uT2YoaW50ZXIpOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gdHJ1ZSwgaWYgY2xhenogaXMgYW4gaW1wbGVtZW50YXRpb24gb2YgaW50ZXJmYWNlIGludGVyCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaW1wbGVtZW50YXRpb25PZihTdHJpbmcgY2xhenosIFN0cmluZyBpbnRlcikgewotICAgIHJldHVybiBpbXBsZW1lbnRhdGlvbk9mKGxvb2t1cENsYXNzKGNsYXp6KSwgbG9va3VwQ2xhc3MoaW50ZXIpKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIHRydWUsIGlmIGNsYXp6IGlzIGFuIGltcGxlbWVudGF0aW9uIG9mIGludGVyZmFjZSBpbnRlcgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBib29sZWFuIGltcGxlbWVudGF0aW9uT2YoSmF2YUNsYXNzIGNsYXp6LCBTdHJpbmcgaW50ZXIpIHsKLSAgICByZXR1cm4gaW1wbGVtZW50YXRpb25PZihjbGF6eiwgbG9va3VwQ2xhc3MoaW50ZXIpKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIHRydWUsIGlmIGNsYXp6IGlzIGFuIGltcGxlbWVudGF0aW9uIG9mIGludGVyZmFjZSBpbnRlcgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBib29sZWFuIGltcGxlbWVudGF0aW9uT2YoU3RyaW5nIGNsYXp6LCBKYXZhQ2xhc3MgaW50ZXIpIHsKLSAgICByZXR1cm4gaW1wbGVtZW50YXRpb25PZihsb29rdXBDbGFzcyhjbGF6eiksIGludGVyKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2NsYXNzZmlsZS9BY2Nlc3NGbGFncy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2NsYXNzZmlsZS9BY2Nlc3NGbGFncy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhZDUwYTk3Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvQWNjZXNzRmxhZ3MuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE3NCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5jbGFzc2ZpbGU7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLWltcG9ydCAgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzOwotCi0vKioKLSAqIFN1cGVyIGNsYXNzIGZvciBhbGwgb2JqZWN0cyB0aGF0IGhhdmUgbW9kaWZpZXJzIGxpa2UgcHJpdmF0ZSwgZmluYWwsIC4uLgotICogSS5lLiBjbGFzc2VzLCBmaWVsZHMsIGFuZCBtZXRob2RzLgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBBY2Nlc3NGbGFncyBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKLSAgcHJvdGVjdGVkIGludCBhY2Nlc3NfZmxhZ3M7Ci0KLSAgcHVibGljIEFjY2Vzc0ZsYWdzKCkge30KLQotICAvKioKLSAgICogQHBhcmFtIGEgaW5pdGFsIGFjY2VzcyBmbGFncwotICAgKi8KLSAgcHVibGljIEFjY2Vzc0ZsYWdzKGludCBhKSB7Ci0gICAgYWNjZXNzX2ZsYWdzID0gYTsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIEFjY2VzcyBmbGFncyBvZiB0aGUgb2JqZWN0IGFrYS4gIm1vZGlmaWVycyIuCi0gICAqLwotICBwdWJsaWMgZmluYWwgaW50IGdldEFjY2Vzc0ZsYWdzKCkgeyByZXR1cm4gYWNjZXNzX2ZsYWdzOyB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gQWNjZXNzIGZsYWdzIG9mIHRoZSBvYmplY3QgYWthLiAibW9kaWZpZXJzIi4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBpbnQgZ2V0TW9kaWZpZXJzKCkgeyByZXR1cm4gYWNjZXNzX2ZsYWdzOyB9Ci0KLSAgLyoqIFNldCBhY2Nlc3MgZmxhZ3MgYWthICJtb2RpZmllcnMiLgotICAgKiBAcGFyYW0gYWNjZXNzX2ZsYWdzIEFjY2VzcyBmbGFncyBvZiB0aGUgb2JqZWN0LgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgc2V0QWNjZXNzRmxhZ3MoaW50IGFjY2Vzc19mbGFncykgewotICAgIHRoaXMuYWNjZXNzX2ZsYWdzID0gYWNjZXNzX2ZsYWdzOwotICB9Ci0KLSAgLyoqIFNldCBhY2Nlc3MgZmxhZ3MgYWthICJtb2RpZmllcnMiLgotICAgKiBAcGFyYW0gYWNjZXNzX2ZsYWdzIEFjY2VzcyBmbGFncyBvZiB0aGUgb2JqZWN0LgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgc2V0TW9kaWZpZXJzKGludCBhY2Nlc3NfZmxhZ3MpIHsKLSAgICBzZXRBY2Nlc3NGbGFncyhhY2Nlc3NfZmxhZ3MpOwotICB9Ci0KLSAgcHJpdmF0ZSBmaW5hbCB2b2lkIHNldEZsYWcoaW50IGZsYWcsIGJvb2xlYW4gc2V0KSB7Ci0gICAgaWYoKGFjY2Vzc19mbGFncyAmIGZsYWcpICE9IDApIHsgLy8gRmxhZyBpcyBzZXQgYWxyZWFkeQotICAgICAgaWYoIXNldCkgLy8gRGVsZXRlIGZsYWcgPwotICAgICAgICBhY2Nlc3NfZmxhZ3MgXj0gZmxhZzsKLSAgICB9IGVsc2UgeyAgIC8vIEZsYWcgbm90IHNldAotICAgICAgaWYoc2V0KSAgLy8gU2V0IGZsYWcgPwotICAgICAgICBhY2Nlc3NfZmxhZ3MgfD0gZmxhZzsKLSAgICB9Ci0gIH0KLQotICBwdWJsaWMgZmluYWwgdm9pZCBpc1B1YmxpYyhib29sZWFuIGZsYWcpIHsgc2V0RmxhZyhDb25zdGFudHMuQUNDX1BVQkxJQywgZmxhZyk7IH0KLSAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNQdWJsaWMoKSB7Ci0gICAgcmV0dXJuIChhY2Nlc3NfZmxhZ3MgJiBDb25zdGFudHMuQUNDX1BVQkxJQykgIT0gMDsKLSAgfQotCi0gIHB1YmxpYyBmaW5hbCB2b2lkIGlzUHJpdmF0ZShib29sZWFuIGZsYWcpIHsgc2V0RmxhZyhDb25zdGFudHMuQUNDX1BSSVZBVEUsIGZsYWcpOyB9Ci0gIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzUHJpdmF0ZSgpIHsKLSAgICByZXR1cm4gKGFjY2Vzc19mbGFncyAmIENvbnN0YW50cy5BQ0NfUFJJVkFURSkgIT0gMDsKLSAgfQotCi0gIHB1YmxpYyBmaW5hbCB2b2lkIGlzUHJvdGVjdGVkKGJvb2xlYW4gZmxhZykgeyBzZXRGbGFnKENvbnN0YW50cy5BQ0NfUFJPVEVDVEVELCBmbGFnKTsgfQotICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc1Byb3RlY3RlZCgpIHsKLSAgICByZXR1cm4gKGFjY2Vzc19mbGFncyAmIENvbnN0YW50cy5BQ0NfUFJPVEVDVEVEKSAhPSAwOwotICB9Ci0KLSAgcHVibGljIGZpbmFsIHZvaWQgaXNTdGF0aWMoYm9vbGVhbiBmbGFnKSB7IHNldEZsYWcoQ29uc3RhbnRzLkFDQ19TVEFUSUMsIGZsYWcpOyB9Ci0gIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzU3RhdGljKCkgewotICAgIHJldHVybiAoYWNjZXNzX2ZsYWdzICYgQ29uc3RhbnRzLkFDQ19TVEFUSUMpICE9IDA7Ci0gIH0KLQotICBwdWJsaWMgZmluYWwgdm9pZCBpc0ZpbmFsKGJvb2xlYW4gZmxhZykgeyBzZXRGbGFnKENvbnN0YW50cy5BQ0NfRklOQUwsIGZsYWcpOyB9Ci0gIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzRmluYWwoKSB7Ci0gICAgcmV0dXJuIChhY2Nlc3NfZmxhZ3MgJiBDb25zdGFudHMuQUNDX0ZJTkFMKSAhPSAwOwotICB9Ci0KLSAgcHVibGljIGZpbmFsIHZvaWQgaXNTeW5jaHJvbml6ZWQoYm9vbGVhbiBmbGFnKSB7IHNldEZsYWcoQ29uc3RhbnRzLkFDQ19TWU5DSFJPTklaRUQsIGZsYWcpOyB9Ci0gIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzU3luY2hyb25pemVkKCkgewotICAgIHJldHVybiAoYWNjZXNzX2ZsYWdzICYgQ29uc3RhbnRzLkFDQ19TWU5DSFJPTklaRUQpICE9IDA7Ci0gIH0KLQotICBwdWJsaWMgZmluYWwgdm9pZCBpc1ZvbGF0aWxlKGJvb2xlYW4gZmxhZykgeyBzZXRGbGFnKENvbnN0YW50cy5BQ0NfVk9MQVRJTEUsIGZsYWcpOyB9Ci0gIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzVm9sYXRpbGUoKSB7Ci0gICAgcmV0dXJuIChhY2Nlc3NfZmxhZ3MgJiBDb25zdGFudHMuQUNDX1ZPTEFUSUxFKSAhPSAwOwotICB9Ci0KLSAgcHVibGljIGZpbmFsIHZvaWQgaXNUcmFuc2llbnQoYm9vbGVhbiBmbGFnKSB7IHNldEZsYWcoQ29uc3RhbnRzLkFDQ19UUkFOU0lFTlQsIGZsYWcpOyB9Ci0gIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzVHJhbnNpZW50KCkgewotICAgIHJldHVybiAoYWNjZXNzX2ZsYWdzICYgQ29uc3RhbnRzLkFDQ19UUkFOU0lFTlQpICE9IDA7Ci0gIH0KLQotICBwdWJsaWMgZmluYWwgdm9pZCBpc05hdGl2ZShib29sZWFuIGZsYWcpIHsgc2V0RmxhZyhDb25zdGFudHMuQUNDX05BVElWRSwgZmxhZyk7IH0KLSAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNOYXRpdmUoKSB7Ci0gICAgcmV0dXJuIChhY2Nlc3NfZmxhZ3MgJiBDb25zdGFudHMuQUNDX05BVElWRSkgIT0gMDsKLSAgfQotCi0gIHB1YmxpYyBmaW5hbCB2b2lkIGlzSW50ZXJmYWNlKGJvb2xlYW4gZmxhZykgeyBzZXRGbGFnKENvbnN0YW50cy5BQ0NfSU5URVJGQUNFLCBmbGFnKTsgfQotICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0ludGVyZmFjZSgpIHsKLSAgICByZXR1cm4gKGFjY2Vzc19mbGFncyAmIENvbnN0YW50cy5BQ0NfSU5URVJGQUNFKSAhPSAwOwotICB9Ci0KLSAgcHVibGljIGZpbmFsIHZvaWQgaXNBYnN0cmFjdChib29sZWFuIGZsYWcpIHsgc2V0RmxhZyhDb25zdGFudHMuQUNDX0FCU1RSQUNULCBmbGFnKTsgfQotICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0Fic3RyYWN0KCkgewotICAgIHJldHVybiAoYWNjZXNzX2ZsYWdzICYgQ29uc3RhbnRzLkFDQ19BQlNUUkFDVCkgIT0gMDsKLSAgfQotCi0gIHB1YmxpYyBmaW5hbCB2b2lkIGlzU3RyaWN0ZnAoYm9vbGVhbiBmbGFnKSB7IHNldEZsYWcoQ29uc3RhbnRzLkFDQ19TVFJJQ1QsIGZsYWcpOyB9Ci0gIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzU3RyaWN0ZnAoKSB7Ci0gICAgcmV0dXJuIChhY2Nlc3NfZmxhZ3MgJiBDb25zdGFudHMuQUNDX1NUUklDVCkgIT0gMDsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2NsYXNzZmlsZS9BdHRyaWJ1dGUuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvQXR0cmlidXRlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDIwNGJiMjUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2NsYXNzZmlsZS9BdHRyaWJ1dGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDMwOCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5jbGFzc2ZpbGU7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHM7Ci1pbXBvcnQgamF2YS5pby4qOwotaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwotCi0vKioKLSAqIEFic3RyYWN0IHN1cGVyIGNsYXNzIGZvciA8ZW0+QXR0cmlidXRlPC9lbT4gb2JqZWN0cy4gQ3VycmVudGx5IHRoZQotICogPGVtPkNvbnN0YW50VmFsdWU8L2VtPiwgPGVtPlNvdXJjZUZpbGU8L2VtPiwgPGVtPkNvZGU8L2VtPiwKLSAqIDxlbT5FeGNlcHRpb250YWJsZTwvZW0+LCA8ZW0+TGluZU51bWJlclRhYmxlPC9lbT4sCi0gKiA8ZW0+TG9jYWxWYXJpYWJsZVRhYmxlPC9lbT4sIDxlbT5Jbm5lckNsYXNzZXM8L2VtPiBhbmQKLSAqIDxlbT5TeW50aGV0aWM8L2VtPiBhdHRyaWJ1dGVzIGFyZSBzdXBwb3J0ZWQuIFRoZQotICogPGVtPlVua25vd248L2VtPiBhdHRyaWJ1dGUgc3RhbmRzIGZvciBub24tc3RhbmRhcmQtYXR0cmlidXRlcy4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICogQHNlZSAgICAgQ29uc3RhbnRWYWx1ZQotICogQHNlZSAgICAgU291cmNlRmlsZQotICogQHNlZSAgICAgQ29kZQotICogQHNlZSAgICAgVW5rbm93bgotICogQHNlZSAgICAgRXhjZXB0aW9uVGFibGUKLSAqIEBzZWUgICAgIExpbmVOdW1iZXJUYWJsZQotICogQHNlZSAgICAgTG9jYWxWYXJpYWJsZVRhYmxlCi0gKiBAc2VlICAgICBJbm5lckNsYXNzZXMKLSAqIEBzZWUgICAgIFN5bnRoZXRpYwotICogQHNlZSAgICAgRGVwcmVjYXRlZAotICogQHNlZSAgICAgU2lnbmF0dXJlCi0qLwotcHVibGljIGFic3RyYWN0IGNsYXNzIEF0dHJpYnV0ZSBpbXBsZW1lbnRzIENsb25lYWJsZSwgTm9kZSwgU2VyaWFsaXphYmxlIHsKLSAgcHJvdGVjdGVkIGludCAgICAgICAgICBuYW1lX2luZGV4OyAvLyBQb2ludHMgdG8gYXR0cmlidXRlIG5hbWUgaW4gY29uc3RhbnQgcG9vbAotICBwcm90ZWN0ZWQgaW50ICAgICAgICAgIGxlbmd0aDsgICAgIC8vIENvbnRlbnQgbGVuZ3RoIG9mIGF0dHJpYnV0ZSBmaWVsZAotICBwcm90ZWN0ZWQgYnl0ZSAgICAgICAgIHRhZzsgICAgICAgIC8vIFRhZyB0byBkaXN0aWd1aXNoIHN1YmNsYXNzZXMKLSAgcHJvdGVjdGVkIENvbnN0YW50UG9vbCBjb25zdGFudF9wb29sOwotCi0gIHByb3RlY3RlZCBBdHRyaWJ1dGUoYnl0ZSB0YWcsIGludCBuYW1lX2luZGV4LCBpbnQgbGVuZ3RoLAotICAgICAgICAgICAgICAgICAgICAgIENvbnN0YW50UG9vbCBjb25zdGFudF9wb29sKSB7Ci0gICAgdGhpcy50YWcgICAgICAgICAgID0gdGFnOwotICAgIHRoaXMubmFtZV9pbmRleCAgICA9IG5hbWVfaW5kZXg7Ci0gICAgdGhpcy5sZW5ndGggICAgICAgID0gbGVuZ3RoOwotICAgIHRoaXMuY29uc3RhbnRfcG9vbCA9IGNvbnN0YW50X3Bvb2w7Ci0gIH0KLQotICAvKioKLSAgICogQ2FsbGVkIGJ5IG9iamVjdHMgdGhhdCBhcmUgdHJhdmVyc2luZyB0aGUgbm9kZXMgb2YgdGhlIHRyZWUgaW1wbGljaXRlbHkKLSAgICogZGVmaW5lZCBieSB0aGUgY29udGVudHMgb2YgYSBKYXZhIGNsYXNzLiBJLmUuLCB0aGUgaGllcmFyY2h5IG9mIG1ldGhvZHMsCi0gICAqIGZpZWxkcywgYXR0cmlidXRlcywgZXRjLiBzcGF3bnMgYSB0cmVlIG9mIG9iamVjdHMuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBhY2NlcHQoVmlzaXRvciB2KTsKLQotICAvKioKLSAgICogRHVtcCBhdHRyaWJ1dGUgdG8gZmlsZSBzdHJlYW0gaW4gYmluYXJ5IGZvcm1hdC4KLSAgICoKLSAgICogQHBhcmFtIGZpbGUgT3V0cHV0IGZpbGUgc3RyZWFtCi0gICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGR1bXAoRGF0YU91dHB1dFN0cmVhbSBmaWxlKSB0aHJvd3MgSU9FeGNlcHRpb24KLSAgewotICAgIGZpbGUud3JpdGVTaG9ydChuYW1lX2luZGV4KTsKLSAgICBmaWxlLndyaXRlSW50KGxlbmd0aCk7Ci0gIH0KLQotICBwcml2YXRlIHN0YXRpYyBIYXNoTWFwIHJlYWRlcnMgPSBuZXcgSGFzaE1hcCgpOwotCi0gIC8qKiBBZGQgYW4gQXR0cmlidXRlIHJlYWRlciBjYXBhYmxlIG9mIHBhcnNpbmcgKHVzZXItZGVmaW5lZCkgYXR0cmlidXRlcwotICAgKiBuYW1lZCAibmFtZSIuIFlvdSBzaG91bGQgbm90IGFkZCByZWFkZXJzIGZvciB0aGUgc3RhbmRhcmQgYXR0cmlidXRlcwotICAgKiBzdWNoIGFzICJMaW5lTnVtYmVyVGFibGUiLCBiZWNhdXNlIHRob3NlIGFyZSBoYW5kbGVkIGludGVybmFsbHkuCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lIHRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUgYXMgc3RvcmVkIGluIHRoZSBjbGFzcyBmaWxlCi0gICAqIEBwYXJhbSByIHRoZSByZWFkZXIgb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgc3RhdGljIHZvaWQgYWRkQXR0cmlidXRlUmVhZGVyKFN0cmluZyBuYW1lLCBBdHRyaWJ1dGVSZWFkZXIgcikgewotICAgIHJlYWRlcnMucHV0KG5hbWUsIHIpOwotICB9Ci0KLSAgLyoqIFJlbW92ZSBhdHRyaWJ1dGUgcmVhZGVyCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lIHRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUgYXMgc3RvcmVkIGluIHRoZSBjbGFzcyBmaWxlCi0gICAqLwotICBwdWJsaWMgc3RhdGljIHZvaWQgcmVtb3ZlQXR0cmlidXRlUmVhZGVyKFN0cmluZyBuYW1lKSB7Ci0gICAgcmVhZGVycy5yZW1vdmUobmFtZSk7Ci0gIH0KLQotICAvKiBDbGFzcyBtZXRob2QgcmVhZHMgb25lIGF0dHJpYnV0ZSBmcm9tIHRoZSBpbnB1dCBkYXRhIHN0cmVhbS4KLSAgICogVGhpcyBtZXRob2QgbXVzdCBub3QgYmUgYWNjZXNzaWJsZSBmcm9tIHRoZSBvdXRzaWRlLiAgSXQgaXMKLSAgICogY2FsbGVkIGJ5IHRoZSBGaWVsZCBhbmQgTWV0aG9kIGNvbnN0cnVjdG9yIG1ldGhvZHMuCi0gICAqCi0gICAqIEBzZWUgICAgRmllbGQKLSAgICogQHNlZSAgICBNZXRob2QKLSAgICogQHBhcmFtICBmaWxlIElucHV0IHN0cmVhbQotICAgKiBAcGFyYW0gIGNvbnN0YW50X3Bvb2wgQXJyYXkgb2YgY29uc3RhbnRzCi0gICAqIEByZXR1cm4gQXR0cmlidXRlCi0gICAqIEB0aHJvd3MgIElPRXhjZXB0aW9uCi0gICAqIEB0aHJvd3MgIENsYXNzRm9ybWF0RXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEF0dHJpYnV0ZSByZWFkQXR0cmlidXRlKERhdGFJbnB1dFN0cmVhbSBmaWxlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbnN0YW50UG9vbCBjb25zdGFudF9wb29sKQotICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgQ2xhc3NGb3JtYXRFeGNlcHRpb24KLSAgewotICAgIENvbnN0YW50VXRmOCBjOwotICAgIFN0cmluZyAgICAgICBuYW1lOwotICAgIGludCAgICAgICAgICBuYW1lX2luZGV4OwotICAgIGludCAgICAgICAgICBsZW5ndGg7Ci0gICAgYnl0ZSAgICAgICAgIHRhZyA9IENvbnN0YW50cy5BVFRSX1VOS05PV047IC8vIFVua25vd24gYXR0cmlidXRlCi0KLSAgICAvLyBHZXQgY2xhc3MgbmFtZSBmcm9tIGNvbnN0YW50IHBvb2wgdmlhIGBuYW1lX2luZGV4JyBpbmRpcmVjdGlvbgotICAgIG5hbWVfaW5kZXggPSAoaW50KWZpbGUucmVhZFVuc2lnbmVkU2hvcnQoKTsKLSAgICBjICAgICAgICAgID0gKENvbnN0YW50VXRmOCljb25zdGFudF9wb29sLmdldENvbnN0YW50KG5hbWVfaW5kZXgsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb25zdGFudHMuQ09OU1RBTlRfVXRmOCk7Ci0gICAgbmFtZSAgICAgICA9IGMuZ2V0Qnl0ZXMoKTsKLQotICAgIC8vIExlbmd0aCBvZiBkYXRhIGluIGJ5dGVzCi0gICAgbGVuZ3RoID0gZmlsZS5yZWFkSW50KCk7Ci0KLSAgICAvLyBDb21wYXJlIHN0cmluZ3MgdG8gZmluZCBrbm93biBhdHRyaWJ1dGUKLSAgICBmb3IoYnl0ZSBpPTA7IGkgPCBDb25zdGFudHMuS05PV05fQVRUUklCVVRFUzsgaSsrKSB7Ci0gICAgICBpZihuYW1lLmVxdWFscyhDb25zdGFudHMuQVRUUklCVVRFX05BTUVTW2ldKSkgewotICAgICAgICB0YWcgPSBpOyAvLyBmb3VuZCEKLSAgICAgICAgYnJlYWs7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgLy8gQ2FsbCBwcm9wZXIgY29uc3RydWN0b3IsIGRlcGVuZGluZyBvbiBgdGFnJwotICAgIHN3aXRjaCh0YWcpIHsKLSAgICBjYXNlIENvbnN0YW50cy5BVFRSX1VOS05PV046Ci0gICAgICBBdHRyaWJ1dGVSZWFkZXIgciA9IChBdHRyaWJ1dGVSZWFkZXIpcmVhZGVycy5nZXQobmFtZSk7Ci0KLSAgICAgIGlmKHIgIT0gbnVsbCkKLSAgICAgICAgcmV0dXJuIHIuY3JlYXRlQXR0cmlidXRlKG5hbWVfaW5kZXgsIGxlbmd0aCwgZmlsZSwgY29uc3RhbnRfcG9vbCk7Ci0gICAgICBlbHNlCi0gICAgICAgIHJldHVybiBuZXcgVW5rbm93bihuYW1lX2luZGV4LCBsZW5ndGgsIGZpbGUsIGNvbnN0YW50X3Bvb2wpOwotCi0gICAgY2FzZSBDb25zdGFudHMuQVRUUl9DT05TVEFOVF9WQUxVRToKLSAgICAgIHJldHVybiBuZXcgQ29uc3RhbnRWYWx1ZShuYW1lX2luZGV4LCBsZW5ndGgsIGZpbGUsIGNvbnN0YW50X3Bvb2wpOwotCi0gICAgY2FzZSBDb25zdGFudHMuQVRUUl9TT1VSQ0VfRklMRToKLSAgICAgIHJldHVybiBuZXcgU291cmNlRmlsZShuYW1lX2luZGV4LCBsZW5ndGgsIGZpbGUsIGNvbnN0YW50X3Bvb2wpOwotCi0gICAgY2FzZSBDb25zdGFudHMuQVRUUl9DT0RFOgotICAgICAgcmV0dXJuIG5ldyBDb2RlKG5hbWVfaW5kZXgsIGxlbmd0aCwgZmlsZSwgY29uc3RhbnRfcG9vbCk7Ci0KLSAgICBjYXNlIENvbnN0YW50cy5BVFRSX0VYQ0VQVElPTlM6Ci0gICAgICByZXR1cm4gbmV3IEV4Y2VwdGlvblRhYmxlKG5hbWVfaW5kZXgsIGxlbmd0aCwgZmlsZSwgY29uc3RhbnRfcG9vbCk7Ci0KLSAgICBjYXNlIENvbnN0YW50cy5BVFRSX0xJTkVfTlVNQkVSX1RBQkxFOgotICAgICAgcmV0dXJuIG5ldyBMaW5lTnVtYmVyVGFibGUobmFtZV9pbmRleCwgbGVuZ3RoLCBmaWxlLCBjb25zdGFudF9wb29sKTsKLQotICAgIGNhc2UgQ29uc3RhbnRzLkFUVFJfTE9DQUxfVkFSSUFCTEVfVEFCTEU6Ci0gICAgICByZXR1cm4gbmV3IExvY2FsVmFyaWFibGVUYWJsZShuYW1lX2luZGV4LCBsZW5ndGgsIGZpbGUsIGNvbnN0YW50X3Bvb2wpOwotCi0gICAgY2FzZSBDb25zdGFudHMuQVRUUl9MT0NBTF9WQVJJQUJMRV9UWVBFX1RBQkxFOgotICAgICAgcmV0dXJuIG5ldyBMb2NhbFZhcmlhYmxlVHlwZVRhYmxlKG5hbWVfaW5kZXgsIGxlbmd0aCwgZmlsZSwgY29uc3RhbnRfcG9vbCk7Ci0KLSAgICBjYXNlIENvbnN0YW50cy5BVFRSX0lOTkVSX0NMQVNTRVM6Ci0gICAgICByZXR1cm4gbmV3IElubmVyQ2xhc3NlcyhuYW1lX2luZGV4LCBsZW5ndGgsIGZpbGUsIGNvbnN0YW50X3Bvb2wpOwotCi0gICAgY2FzZSBDb25zdGFudHMuQVRUUl9TWU5USEVUSUM6Ci0gICAgICByZXR1cm4gbmV3IFN5bnRoZXRpYyhuYW1lX2luZGV4LCBsZW5ndGgsIGZpbGUsIGNvbnN0YW50X3Bvb2wpOwotCi0gICAgY2FzZSBDb25zdGFudHMuQVRUUl9ERVBSRUNBVEVEOgotICAgICAgcmV0dXJuIG5ldyBEZXByZWNhdGVkKG5hbWVfaW5kZXgsIGxlbmd0aCwgZmlsZSwgY29uc3RhbnRfcG9vbCk7Ci0KLSAgICBjYXNlIENvbnN0YW50cy5BVFRSX1BNRzoKLSAgICAgIHJldHVybiBuZXcgUE1HQ2xhc3MobmFtZV9pbmRleCwgbGVuZ3RoLCBmaWxlLCBjb25zdGFudF9wb29sKTsKLQotICAgIGNhc2UgQ29uc3RhbnRzLkFUVFJfU0lHTkFUVVJFOgotICAgICAgcmV0dXJuIG5ldyBTaWduYXR1cmUobmFtZV9pbmRleCwgbGVuZ3RoLCBmaWxlLCBjb25zdGFudF9wb29sKTsKLQotICAgIGNhc2UgQ29uc3RhbnRzLkFUVFJfU1RBQ0tfTUFQOgotICAgICAgcmV0dXJuIG5ldyBTdGFja01hcChuYW1lX2luZGV4LCBsZW5ndGgsIGZpbGUsIGNvbnN0YW50X3Bvb2wpOwotCi0gICAgZGVmYXVsdDogLy8gTmV2ZXIgcmVhY2hlZAotICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiT29vcHMhIGRlZmF1bHQgY2FzZSByZWFjaGVkLiIpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIExlbmd0aCBvZiBhdHRyaWJ1dGUgZmllbGQgaW4gYnl0ZXMuCi0gICAqLwotICBwdWJsaWMgZmluYWwgaW50ICAgZ2V0TGVuZ3RoKCkgICAgeyByZXR1cm4gbGVuZ3RoOyB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBBdHRyaWJ1dGUgbGVuZ3RoIGluIGJ5dGVzLgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgc2V0TGVuZ3RoKGludCBsZW5ndGgpIHsKLSAgICB0aGlzLmxlbmd0aCA9IGxlbmd0aDsKLSAgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gbmFtZV9pbmRleCBvZiBhdHRyaWJ1dGUuCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBzZXROYW1lSW5kZXgoaW50IG5hbWVfaW5kZXgpIHsKLSAgICB0aGlzLm5hbWVfaW5kZXggPSBuYW1lX2luZGV4OwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gTmFtZSBpbmRleCBpbiBjb25zdGFudCBwb29sIG9mIGF0dHJpYnV0ZSBuYW1lLgotICAgKi8KLSAgcHVibGljIGZpbmFsIGludCBnZXROYW1lSW5kZXgoKSB7IHJldHVybiBuYW1lX2luZGV4OyB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gVGFnIG9mIGF0dHJpYnV0ZSwgaS5lLiwgaXRzIHR5cGUuIFZhbHVlIG1heSBub3QgYmUgYWx0ZXJlZCwgdGh1cwotICAgKiB0aGVyZSBpcyBubyBzZXRUYWcoKSBtZXRob2QuCi0gICAqLwotICBwdWJsaWMgZmluYWwgYnl0ZSAgZ2V0VGFnKCkgICAgICAgeyByZXR1cm4gdGFnOyB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gQ29uc3RhbnQgcG9vbCB1c2VkIGJ5IHRoaXMgb2JqZWN0LgotICAgKiBAc2VlIENvbnN0YW50UG9vbAotICAgKi8KLSAgcHVibGljIGZpbmFsIENvbnN0YW50UG9vbCBnZXRDb25zdGFudFBvb2woKSB7IHJldHVybiBjb25zdGFudF9wb29sOyB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBjb25zdGFudF9wb29sIENvbnN0YW50IHBvb2wgdG8gYmUgdXNlZCBmb3IgdGhpcyBvYmplY3QuCi0gICAqIEBzZWUgQ29uc3RhbnRQb29sCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBzZXRDb25zdGFudFBvb2woQ29uc3RhbnRQb29sIGNvbnN0YW50X3Bvb2wpIHsKLSAgICB0aGlzLmNvbnN0YW50X3Bvb2wgPSBjb25zdGFudF9wb29sOwotICB9Ci0KLSAgLyoqCi0gICAqIFVzZSBjb3B5KCkgaWYgeW91IHdhbnQgdG8gaGF2ZSBhIGRlZXAgY29weSgpLCBpLmUuLCB3aXRoIGFsbCByZWZlcmVuY2VzCi0gICAqIGNvcGllZCBjb3JyZWN0bHkuCi0gICAqCi0gICAqIEByZXR1cm4gc2hhbGxvdyBjb3B5IG9mIHRoaXMgYXR0cmlidXRlCi0gICAqLwotICBwdWJsaWMgT2JqZWN0IGNsb25lKCkgewotICAgIE9iamVjdCBvID0gbnVsbDsKLQotICAgIHRyeSB7Ci0gICAgICBvID0gc3VwZXIuY2xvbmUoKTsKLSAgICB9IGNhdGNoKENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGUpIHsKLSAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7IC8vIE5ldmVyIG9jY3VycwotICAgIH0KLQotICAgIHJldHVybiBvOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gZGVlcCBjb3B5IG9mIHRoaXMgYXR0cmlidXRlCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgQXR0cmlidXRlIGNvcHkoQ29uc3RhbnRQb29sIGNvbnN0YW50X3Bvb2wpOwotCi0gIC8qKgotICAgKiBAcmV0dXJuIGF0dHJpYnV0ZSBuYW1lLgotICAgKi8KLSAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKLSAgICByZXR1cm4gQ29uc3RhbnRzLkFUVFJJQlVURV9OQU1FU1t0YWddOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvY2xhc3NmaWxlL0F0dHJpYnV0ZVJlYWRlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2NsYXNzZmlsZS9BdHRyaWJ1dGVSZWFkZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZDFmMzk1MS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvY2xhc3NmaWxlL0F0dHJpYnV0ZVJlYWRlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTAwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmNsYXNzZmlsZTsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotLyoqCi0gKiBVbmtub3duIChub24tc3RhbmRhcmQpIGF0dHJpYnV0ZXMgbWF5IGJlIHJlYWQgdmlhIHVzZXItZGVmaW5lZCBmYWN0b3J5Ci0gKiBvYmplY3RzIHRoYXQgY2FuIGJlIHJlZ2lzdGVyZWQgd2l0aCB0aGUgQXR0cmlidXRlLmFkZEF0dHJpYnV0ZVJlYWRlcgotICogbWV0aG9kLiBUaGVzZSBmYWN0b3J5IG9iamVjdHMgc2hvdWxkIGltcGxlbWVudCB0aGlzIGludGVyZmFjZS4KLQotICogQHNlZSBBdHRyaWJ1dGUKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgQXR0cmlidXRlUmVhZGVyIHsKLSAgLyoqCi0gICAgIFdoZW4gdGhpcyBhdHRyaWJ1dGUgcmVhZGVyIGlzIGFkZGVkIHZpYSB0aGUgc3RhdGljIG1ldGhvZAotICAgICBBdHRyaWJ1dGUuYWRkQXR0cmlidXRlUmVhZGVyLCBhbiBhdHRyaWJ1dGUgbmFtZSBpcyBhc3NvY2lhdGVkIHdpdGggaXQuCi0gICAgIEFzIHRoZSBjbGFzcyBmaWxlIHBhcnNlciBwYXJzZXMgYXR0cmlidXRlcywgaXQgd2lsbCBjYWxsIHZhcmlvdXMKLSAgICAgQXR0cmlidXRlUmVhZGVycyBiYXNlZCBvbiB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlcyBpdCBpcwotICAgICBjb25zdHJ1Y3RpbmcuCi0KLSAgICAgQHBhcmFtIG5hbWVfaW5kZXggQW4gaW5kZXggaW50byB0aGUgY29uc3RhbnQgcG9vbCwgaW5kZXhpbmcgYQotICAgICBDb25zdGFudFV0ZjggdGhhdCByZXByZXNlbnRzIHRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUuCi0KLSAgICAgQHBhcmFtIGxlbmd0aCBUaGUgbGVuZ3RoIG9mIHRoZSBkYXRhIGNvbnRhaW5lZCBpbiB0aGUgYXR0cmlidXRlLiAgVGhpcwotICAgICBpcyB3cml0dGVuIGludG8gdGhlIGNvbnN0YW50IHBvb2wgYW5kIHNob3VsZCBhZ3JlZSB3aXRoIHdoYXQgdGhlCi0gICAgIGZhY3RvcnkgZXhwZWN0cyB0aGUgbGVuZ3RoIHRvIGJlLgotCi0gICAgIEBwYXJhbSBmaWxlIFRoaXMgaXMgdGhlIGRhdGEgaW5wdXQgc3RyZWFtIHRoYXQgdGhlIGZhY3RvcnkgbmVlZHMgdG8gcmVhZAotICAgICBpdHMgZGF0YSBmcm9tLgotCi0gICAgIEBwYXJhbSBjb25zdGFudF9wb29sIFRoaXMgaXMgdGhlIGNvbnN0YW50IHBvb2wgYXNzb2NpYXRlZCB3aXRoIHRoZQotICAgICBBdHRyaWJ1dGUgdGhhdCB3ZSBhcmUgY29uc3RydWN0aW5nLgotCi0gICAgIEByZXR1cm4gVGhlIHVzZXItZGVmaW5lZCBBdHRyaWJ1dGVSZWFkZXIgc2hvdWxkIHRha2UgdGhpcyBkYXRhIGFuZCB1c2UKLSAgICAgaXQgdG8gY29uc3RydWN0IGFuIGF0dHJpYnV0ZS4gIEluIHRoZSBjYXNlIG9mIGVycm9ycywgYSBudWxsIGNhbiBiZQotICAgICByZXR1cm5lZCB3aGljaCB3aWxsIGNhdXNlIHRoZSBwYXJzaW5nIG9mIHRoZSBjbGFzcyBmaWxlIHRvIGZhaWwuCi0KLSAgICAgQHNlZSBBdHRyaWJ1dGUjYWRkQXR0cmlidXRlUmVhZGVyKCBTdHJpbmcsIEF0dHJpYnV0ZVJlYWRlciApCi0gICovCi0gIHB1YmxpYyBBdHRyaWJ1dGUgY3JlYXRlQXR0cmlidXRlKGludCBuYW1lX2luZGV4LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqYXZhLmlvLkRhdGFJbnB1dFN0cmVhbSBmaWxlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb25zdGFudFBvb2wgY29uc3RhbnRfcG9vbCk7Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvY2xhc3NmaWxlL0NsYXNzRm9ybWF0RXhjZXB0aW9uLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvY2xhc3NmaWxlL0NsYXNzRm9ybWF0RXhjZXB0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDIwM2ZhZjMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2NsYXNzZmlsZS9DbGFzc0Zvcm1hdEV4Y2VwdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNzEgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuY2xhc3NmaWxlOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIFRocm93biB3aGVuIHRoZSBCQ0VMIGF0dGVtcHRzIHRvIHJlYWQgYSBjbGFzcyBmaWxlIGFuZCBkZXRlcm1pbmVzCi0gKiB0aGF0IHRoZSBmaWxlIGlzIG1hbGZvcm1lZCBvciBvdGhlcndpc2UgY2Fubm90IGJlIGludGVycHJldGVkIGFzIGEKLSAqIGNsYXNzIGZpbGUuCi0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGNsYXNzIENsYXNzRm9ybWF0RXhjZXB0aW9uIGV4dGVuZHMgUnVudGltZUV4Y2VwdGlvbiB7Ci0gIHB1YmxpYyBDbGFzc0Zvcm1hdEV4Y2VwdGlvbigpIHsgc3VwZXIoKTsgfQotICBwdWJsaWMgQ2xhc3NGb3JtYXRFeGNlcHRpb24oU3RyaW5nIHMpIHsgc3VwZXIocyk7IH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvQ2xhc3NQYXJzZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvQ2xhc3NQYXJzZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZDhmMzJmYy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvY2xhc3NmaWxlL0NsYXNzUGFyc2VyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzMzEgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuY2xhc3NmaWxlOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi1pbXBvcnQgIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50czsKLWltcG9ydCAgamF2YS5pby4qOwotaW1wb3J0ICBqYXZhLnV0aWwuemlwLio7Ci0KLS8qKgotICogV3JhcHBlciBjbGFzcyB0aGF0IHBhcnNlcyBhIGdpdmVuIEphdmEgLmNsYXNzIGZpbGUuIFRoZSBtZXRob2QgPEEKLSAqIGhyZWYgPSIjcGFyc2UiPnBhcnNlPC9BPiByZXR1cm5zIGEgPEEgaHJlZiA9IkphdmFDbGFzcy5odG1sIj4KLSAqIEphdmFDbGFzczwvQT4gb2JqZWN0IG9uIHN1Y2Nlc3MuIFdoZW4gYW4gSS9PIGVycm9yIG9yIGFuCi0gKiBpbmNvbnNpc3RlbmN5IG9jY3VycyBhbiBhcHByb3BpYXRlIGV4Y2VwdGlvbiBpcyBwcm9wYWdhdGVkIGJhY2sgdG8KLSAqIHRoZSBjYWxsZXIuCi0gKgotICogVGhlIHN0cnVjdHVyZSBhbmQgdGhlIG5hbWVzIGNvbXBseSwgZXhjZXB0IGZvciBhIGZldyBjb252ZW5pZW5jZXMsCi0gKiBleGFjdGx5IHdpdGggdGhlIDxBIGhyZWY9ImZ0cDovL2phdmEuc3VuLmNvbS9kb2NzL3NwZWNzL3Ztc3BlYy5wcyI+Ci0gKiBKVk0gc3BlY2lmaWNhdGlvbiAxLjA8L2E+LiBTZWUgdGhpcyBwYXBlciBmb3IKLSAqIGZ1cnRoZXIgZGV0YWlscyBhYm91dCB0aGUgc3RydWN0dXJlIG9mIGEgYnl0ZWNvZGUgZmlsZS4KLSAqCi0gKiBAYXV0aG9yIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBDbGFzc1BhcnNlciB7Ci0gIHByaXZhdGUgRGF0YUlucHV0U3RyZWFtIGZpbGU7Ci0gIHByaXZhdGUgWmlwRmlsZSAgICAgICAgIHppcDsKLSAgcHJpdmF0ZSBTdHJpbmcgICAgICAgICAgZmlsZV9uYW1lOwotICBwcml2YXRlIGludCAgICAgICAgICAgICBjbGFzc19uYW1lX2luZGV4LCBzdXBlcmNsYXNzX25hbWVfaW5kZXg7Ci0gIHByaXZhdGUgaW50ICAgICAgICAgICAgIG1ham9yLCBtaW5vcjsgLy8gQ29tcGlsZXIgdmVyc2lvbgotICBwcml2YXRlIGludCAgICAgICAgICAgICBhY2Nlc3NfZmxhZ3M7IC8vIEFjY2VzcyByaWdodHMgb2YgcGFyc2VkIGNsYXNzCi0gIHByaXZhdGUgaW50W10gICAgICAgICAgIGludGVyZmFjZXM7IC8vIE5hbWVzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMKLSAgcHJpdmF0ZSBDb25zdGFudFBvb2wgICAgY29uc3RhbnRfcG9vbDsgLy8gY29sbGVjdGlvbiBvZiBjb25zdGFudHMKLSAgcHJpdmF0ZSBGaWVsZFtdICAgICAgICAgZmllbGRzOyAvLyBjbGFzcyBmaWVsZHMsIGkuZS4sIGl0cyB2YXJpYWJsZXMKLSAgcHJpdmF0ZSBNZXRob2RbXSAgICAgICAgbWV0aG9kczsgLy8gbWV0aG9kcyBkZWZpbmVkIGluIHRoZSBjbGFzcwotICBwcml2YXRlIEF0dHJpYnV0ZVtdICAgICBhdHRyaWJ1dGVzOyAvLyBhdHRyaWJ1dGVzIGRlZmluZWQgaW4gdGhlIGNsYXNzCi0gIHByaXZhdGUgYm9vbGVhbiAgICAgICAgIGlzX3ppcDsgLy8gTG9hZGVkIGZyb20gemlwIGZpbGUKLQotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQlVGU0laRSA9IDgxOTI7Ci0KLSAgLyoqCi0gICAqIFBhcnNlIGNsYXNzIGZyb20gdGhlIGdpdmVuIHN0cmVhbS4KLSAgICoKLSAgICogQHBhcmFtIGZpbGUgSW5wdXQgc3RyZWFtCi0gICAqIEBwYXJhbSBmaWxlX25hbWUgRmlsZSBuYW1lCi0gICAqLwotICBwdWJsaWMgQ2xhc3NQYXJzZXIoSW5wdXRTdHJlYW0gZmlsZSwgU3RyaW5nIGZpbGVfbmFtZSkgewotICAgIHRoaXMuZmlsZV9uYW1lID0gZmlsZV9uYW1lOwotCi0gICAgU3RyaW5nIGNsYXp6ID0gZmlsZS5nZXRDbGFzcygpLmdldE5hbWUoKTsgLy8gTm90IGEgdmVyeSBjbGVhbiBzb2x1dGlvbiAuLi4KLSAgICBpc196aXAgPSBjbGF6ei5zdGFydHNXaXRoKCJqYXZhLnV0aWwuemlwLiIpIHx8IGNsYXp6LnN0YXJ0c1dpdGgoImphdmEudXRpbC5qYXIuIik7Ci0KLSAgICBpZihmaWxlIGluc3RhbmNlb2YgRGF0YUlucHV0U3RyZWFtKSAvLyBJcyBhbHJlYWR5IGEgZGF0YSBzdHJlYW0KLSAgICAgIHRoaXMuZmlsZSA9IChEYXRhSW5wdXRTdHJlYW0pZmlsZTsKLSAgICBlbHNlCi0gICAgICB0aGlzLmZpbGUgPSBuZXcgRGF0YUlucHV0U3RyZWFtKG5ldyBCdWZmZXJlZElucHV0U3RyZWFtKGZpbGUsIEJVRlNJWkUpKTsKLSAgfQotCi0gIC8qKiBQYXJzZSBjbGFzcyBmcm9tIGdpdmVuIC5jbGFzcyBmaWxlLgotICAgKgotICAgKiBAcGFyYW0gZmlsZV9uYW1lIGZpbGUgbmFtZQotICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgQ2xhc3NQYXJzZXIoU3RyaW5nIGZpbGVfbmFtZSkgdGhyb3dzIElPRXhjZXB0aW9uCi0gIHsKLSAgICBpc196aXAgPSBmYWxzZTsKLSAgICB0aGlzLmZpbGVfbmFtZSA9IGZpbGVfbmFtZTsKLSAgICBmaWxlID0gbmV3IERhdGFJbnB1dFN0cmVhbShuZXcgQnVmZmVyZWRJbnB1dFN0cmVhbQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChuZXcgRmlsZUlucHV0U3RyZWFtKGZpbGVfbmFtZSksIEJVRlNJWkUpKTsKLSAgfQotCi0gIC8qKiBQYXJzZSBjbGFzcyBmcm9tIGdpdmVuIC5jbGFzcyBmaWxlIGluIGEgWklQLWFyY2hpdmUKLSAgICoKLSAgICogQHBhcmFtIGZpbGVfbmFtZSBmaWxlIG5hbWUKLSAgICogQHRocm93cyBJT0V4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIENsYXNzUGFyc2VyKFN0cmluZyB6aXBfZmlsZSwgU3RyaW5nIGZpbGVfbmFtZSkgdGhyb3dzIElPRXhjZXB0aW9uCi0gIHsKLSAgICBpc196aXAgPSB0cnVlOwotICAgIHppcCA9IG5ldyBaaXBGaWxlKHppcF9maWxlKTsKLSAgICBaaXBFbnRyeSBlbnRyeSA9IHppcC5nZXRFbnRyeShmaWxlX25hbWUpOwotCi0gICAgdGhpcy5maWxlX25hbWUgPSBmaWxlX25hbWU7Ci0KLSAgICBmaWxlID0gbmV3IERhdGFJbnB1dFN0cmVhbShuZXcgQnVmZmVyZWRJbnB1dFN0cmVhbSh6aXAuZ2V0SW5wdXRTdHJlYW0oZW50cnkpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJVRlNJWkUpKTsKLSAgfQotCi0gIC8qKgotICAgKiBQYXJzZSB0aGUgZ2l2ZW4gSmF2YSBjbGFzcyBmaWxlIGFuZCByZXR1cm4gYW4gb2JqZWN0IHRoYXQgcmVwcmVzZW50cwotICAgKiB0aGUgY29udGFpbmVkIGRhdGEsIGkuZS4sIGNvbnN0YW50cywgbWV0aG9kcywgZmllbGRzIGFuZCBjb21tYW5kcy4KLSAgICogQSA8ZW0+Q2xhc3NGb3JtYXRFeGNlcHRpb248L2VtPiBpcyByYWlzZWQsIGlmIHRoZSBmaWxlIGlzIG5vdCBhIHZhbGlkCi0gICAqIC5jbGFzcyBmaWxlLiAoVGhpcyBkb2VzIG5vdCBpbmNsdWRlIHZlcmlmaWNhdGlvbiBvZiB0aGUgYnl0ZSBjb2RlIGFzIGl0Ci0gICAqIGlzIHBlcmZvcm1lZCBieSB0aGUgamF2YSBpbnRlcnByZXRlcikuCi0gICAqCi0gICAqIEByZXR1cm4gQ2xhc3Mgb2JqZWN0IHJlcHJlc2VudGluZyB0aGUgcGFyc2VkIGNsYXNzIGZpbGUKLSAgICogQHRocm93cyAgSU9FeGNlcHRpb24KLSAgICogQHRocm93cyAgQ2xhc3NGb3JtYXRFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBKYXZhQ2xhc3MgcGFyc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24sIENsYXNzRm9ybWF0RXhjZXB0aW9uCi0gIHsKLSAgICAvKioqKioqKioqKioqKioqKioqIFJlYWQgaGVhZGVycyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLSAgICAvLyBDaGVjayBtYWdpYyB0YWcgb2YgY2xhc3MgZmlsZQotICAgIHJlYWRJRCgpOwotCi0gICAgLy8gR2V0IGNvbXBpbGVyIHZlcnNpb24KLSAgICByZWFkVmVyc2lvbigpOwotCi0gICAgLyoqKioqKioqKioqKioqKioqKiBSZWFkIGNvbnN0YW50IHBvb2wgYW5kIHJlbGF0ZWQgKioqKioqKioqKioqKiovCi0gICAgLy8gUmVhZCBjb25zdGFudCBwb29sIGVudHJpZXMKLSAgICByZWFkQ29uc3RhbnRQb29sKCk7Ci0KLSAgICAvLyBHZXQgY2xhc3MgaW5mb3JtYXRpb24KLSAgICByZWFkQ2xhc3NJbmZvKCk7Ci0KLSAgICAvLyBHZXQgaW50ZXJmYWNlIGluZm9ybWF0aW9uLCBpLmUuLCBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzCi0gICAgcmVhZEludGVyZmFjZXMoKTsKLQotICAgIC8qKioqKioqKioqKioqKioqKiogUmVhZCBjbGFzcyBmaWVsZHMgYW5kIG1ldGhvZHMgKioqKioqKioqKioqKioqLwotICAgIC8vIFJlYWQgY2xhc3MgZmllbGRzLCBpLmUuLCB0aGUgdmFyaWFibGVzIG9mIHRoZSBjbGFzcwotICAgIHJlYWRGaWVsZHMoKTsKLQotICAgIC8vIFJlYWQgY2xhc3MgbWV0aG9kcywgaS5lLiwgdGhlIGZ1bmN0aW9ucyBpbiB0aGUgY2xhc3MKLSAgICByZWFkTWV0aG9kcygpOwotCi0gICAgLy8gUmVhZCBjbGFzcyBhdHRyaWJ1dGVzCi0gICAgcmVhZEF0dHJpYnV0ZXMoKTsKLQotICAgIC8vIENoZWNrIGZvciB1bmtub3duIHZhcmlhYmxlcwotICAgIC8vVW5rbm93bltdIHUgPSBVbmtub3duLmdldFVua25vd25BdHRyaWJ1dGVzKCk7Ci0gICAgLy9mb3IoaW50IGk9MDsgaSA8IHUubGVuZ3RoOyBpKyspCi0gICAgLy8gIFN5c3RlbS5lcnIucHJpbnRsbigiV0FSTklORzogIiArIHVbaV0pOwotCi0gICAgLy8gRXZlcnl0aGluZyBzaG91bGQgaGF2ZSBiZWVuIHJlYWQgbm93Ci0gICAgLy8gICAgICBpZihmaWxlLmF2YWlsYWJsZSgpID4gMCkgewotICAgIC8vICAgICAgICBpbnQgYnl0ZXMgPSBmaWxlLmF2YWlsYWJsZSgpOwotICAgIC8vICAgICAgICBieXRlW10gYnVmID0gbmV3IGJ5dGVbYnl0ZXNdOwotICAgIC8vICAgICAgICBmaWxlLnJlYWQoYnVmKTsKLQotICAgIC8vICAgICAgICBpZighKGlzX3ppcCAmJiAoYnVmLmxlbmd0aCA9PSAxKSkpIHsKLSAgICAvLyAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIldBUk5JTkc6IFRyYWlsaW5nIGdhcmJhZ2UgYXQgZW5kIG9mICIgKyBmaWxlX25hbWUpOwotICAgIC8vICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbihieXRlcyArICIgZXh0cmEgYnl0ZXM6ICIgKyBVdGlsaXR5LnRvSGV4U3RyaW5nKGJ1ZikpOwotICAgIC8vICAgICAgICB9Ci0gICAgLy8gICAgICB9Ci0KLSAgICAvLyBSZWFkIGV2ZXJ5dGhpbmcgb2YgaW50ZXJlc3QsIHNvIGNsb3NlIHRoZSBmaWxlCi0gICAgZmlsZS5jbG9zZSgpOwotICAgIGlmKHppcCAhPSBudWxsKQotICAgICAgemlwLmNsb3NlKCk7Ci0KLSAgICAvLyBSZXR1cm4gdGhlIGluZm9ybWF0aW9uIHdlIGhhdmUgZ2F0aGVyZWQgaW4gYSBuZXcgb2JqZWN0Ci0gICAgcmV0dXJuIG5ldyBKYXZhQ2xhc3MoY2xhc3NfbmFtZV9pbmRleCwgc3VwZXJjbGFzc19uYW1lX2luZGV4LAotICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVfbmFtZSwgbWFqb3IsIG1pbm9yLCBhY2Nlc3NfZmxhZ3MsCi0gICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RhbnRfcG9vbCwgaW50ZXJmYWNlcywgZmllbGRzLAotICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZHMsIGF0dHJpYnV0ZXMsIGlzX3ppcD8gSmF2YUNsYXNzLlpJUCA6IEphdmFDbGFzcy5GSUxFKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZWFkIGluZm9ybWF0aW9uIGFib3V0IHRoZSBhdHRyaWJ1dGVzIG9mIHRoZSBjbGFzcy4KLSAgICogQHRocm93cyAgSU9FeGNlcHRpb24KLSAgICogQHRocm93cyAgQ2xhc3NGb3JtYXRFeGNlcHRpb24KLSAgICovCi0gIHByaXZhdGUgZmluYWwgdm9pZCByZWFkQXR0cmlidXRlcygpIHRocm93cyBJT0V4Y2VwdGlvbiwgQ2xhc3NGb3JtYXRFeGNlcHRpb24KLSAgewotICAgIGludCBhdHRyaWJ1dGVzX2NvdW50OwotCi0gICAgYXR0cmlidXRlc19jb3VudCA9IGZpbGUucmVhZFVuc2lnbmVkU2hvcnQoKTsKLSAgICBhdHRyaWJ1dGVzICAgICAgID0gbmV3IEF0dHJpYnV0ZVthdHRyaWJ1dGVzX2NvdW50XTsKLQotICAgIGZvcihpbnQgaT0wOyBpIDwgYXR0cmlidXRlc19jb3VudDsgaSsrKQotICAgICAgYXR0cmlidXRlc1tpXSA9IEF0dHJpYnV0ZS5yZWFkQXR0cmlidXRlKGZpbGUsIGNvbnN0YW50X3Bvb2wpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlYWQgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGNsYXNzIGFuZCBpdHMgc3VwZXIgY2xhc3MuCi0gICAqIEB0aHJvd3MgIElPRXhjZXB0aW9uCi0gICAqIEB0aHJvd3MgIENsYXNzRm9ybWF0RXhjZXB0aW9uCi0gICAqLwotICBwcml2YXRlIGZpbmFsIHZvaWQgcmVhZENsYXNzSW5mbygpIHRocm93cyBJT0V4Y2VwdGlvbiwgQ2xhc3NGb3JtYXRFeGNlcHRpb24KLSAgewotICAgIGFjY2Vzc19mbGFncyA9IGZpbGUucmVhZFVuc2lnbmVkU2hvcnQoKTsKLQotICAgIC8qIEludGVyZmFjZXMgYXJlIGltcGxpY2l0ZWx5IGFic3RyYWN0LCB0aGUgZmxhZyBzaG91bGQgYmUgc2V0Ci0gICAgICogYWNjb3JkaW5nIHRvIHRoZSBKVk0gc3BlY2lmaWNhdGlvbi4KLSAgICAgKi8KLSAgICBpZigoYWNjZXNzX2ZsYWdzICYgQ29uc3RhbnRzLkFDQ19JTlRFUkZBQ0UpICE9IDApCi0gICAgICBhY2Nlc3NfZmxhZ3MgfD0gQ29uc3RhbnRzLkFDQ19BQlNUUkFDVDsKLQotICAgIGlmKCgoYWNjZXNzX2ZsYWdzICYgQ29uc3RhbnRzLkFDQ19BQlNUUkFDVCkgIT0gMCkgJiYKLSAgICAgICAoKGFjY2Vzc19mbGFncyAmIENvbnN0YW50cy5BQ0NfRklOQUwpICAgICE9IDAgKSkKLSAgICAgIHRocm93IG5ldyBDbGFzc0Zvcm1hdEV4Y2VwdGlvbigiQ2xhc3MgY2FuJ3QgYmUgYm90aCBmaW5hbCBhbmQgYWJzdHJhY3QiKTsKLQotICAgIGNsYXNzX25hbWVfaW5kZXggICAgICA9IGZpbGUucmVhZFVuc2lnbmVkU2hvcnQoKTsKLSAgICBzdXBlcmNsYXNzX25hbWVfaW5kZXggPSBmaWxlLnJlYWRVbnNpZ25lZFNob3J0KCk7Ci0gIH0KLSAgLyoqCi0gICAqIFJlYWQgY29uc3RhbnQgcG9vbCBlbnRyaWVzLgotICAgKiBAdGhyb3dzICBJT0V4Y2VwdGlvbgotICAgKiBAdGhyb3dzICBDbGFzc0Zvcm1hdEV4Y2VwdGlvbgotICAgKi8KLSAgcHJpdmF0ZSBmaW5hbCB2b2lkIHJlYWRDb25zdGFudFBvb2woKSB0aHJvd3MgSU9FeGNlcHRpb24sIENsYXNzRm9ybWF0RXhjZXB0aW9uCi0gIHsKLSAgICBjb25zdGFudF9wb29sID0gbmV3IENvbnN0YW50UG9vbChmaWxlKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZWFkIGluZm9ybWF0aW9uIGFib3V0IHRoZSBmaWVsZHMgb2YgdGhlIGNsYXNzLCBpLmUuLCBpdHMgdmFyaWFibGVzLgotICAgKiBAdGhyb3dzICBJT0V4Y2VwdGlvbgotICAgKiBAdGhyb3dzICBDbGFzc0Zvcm1hdEV4Y2VwdGlvbgotICAgKi8KLSAgcHJpdmF0ZSBmaW5hbCB2b2lkIHJlYWRGaWVsZHMoKSB0aHJvd3MgSU9FeGNlcHRpb24sIENsYXNzRm9ybWF0RXhjZXB0aW9uCi0gIHsKLSAgICBpbnQgZmllbGRzX2NvdW50OwotCi0gICAgZmllbGRzX2NvdW50ID0gZmlsZS5yZWFkVW5zaWduZWRTaG9ydCgpOwotICAgIGZpZWxkcyAgICAgICA9IG5ldyBGaWVsZFtmaWVsZHNfY291bnRdOwotCi0gICAgZm9yKGludCBpPTA7IGkgPCBmaWVsZHNfY291bnQ7IGkrKykKLSAgICAgIGZpZWxkc1tpXSA9IG5ldyBGaWVsZChmaWxlLCBjb25zdGFudF9wb29sKTsKLSAgfQotCi0gIC8qKioqKioqKioqKioqKioqKioqKiBQcml2YXRlIHV0aWxpdHkgbWV0aG9kcyAqKioqKioqKioqKioqKioqKioqKioqLwotCi0gIC8qKgotICAgKiBDaGVjayB3aGV0aGVyIHRoZSBoZWFkZXIgb2YgdGhlIGZpbGUgaXMgb2suCi0gICAqIE9mIGNvdXJzZSwgdGhpcyBoYXMgdG8gYmUgdGhlIGZpcnN0IGFjdGlvbiBvbiBzdWNjZXNzaXZlIGZpbGUgcmVhZHMuCi0gICAqIEB0aHJvd3MgIElPRXhjZXB0aW9uCi0gICAqIEB0aHJvd3MgIENsYXNzRm9ybWF0RXhjZXB0aW9uCi0gICAqLwotICBwcml2YXRlIGZpbmFsIHZvaWQgcmVhZElEKCkgdGhyb3dzIElPRXhjZXB0aW9uLCBDbGFzc0Zvcm1hdEV4Y2VwdGlvbgotICB7Ci0gICAgaW50IG1hZ2ljID0gMHhDQUZFQkFCRTsKLQotICAgIGlmKGZpbGUucmVhZEludCgpICE9IG1hZ2ljKQotICAgICAgdGhyb3cgbmV3IENsYXNzRm9ybWF0RXhjZXB0aW9uKGZpbGVfbmFtZSArICIgaXMgbm90IGEgSmF2YSAuY2xhc3MgZmlsZSIpOwotICB9Ci0gIC8qKgotICAgKiBSZWFkIGluZm9ybWF0aW9uIGFib3V0IHRoZSBpbnRlcmZhY2VzIGltcGxlbWVudGVkIGJ5IHRoaXMgY2xhc3MuCi0gICAqIEB0aHJvd3MgIElPRXhjZXB0aW9uCi0gICAqIEB0aHJvd3MgIENsYXNzRm9ybWF0RXhjZXB0aW9uCi0gICAqLwotICBwcml2YXRlIGZpbmFsIHZvaWQgcmVhZEludGVyZmFjZXMoKSB0aHJvd3MgSU9FeGNlcHRpb24sIENsYXNzRm9ybWF0RXhjZXB0aW9uCi0gIHsKLSAgICBpbnQgaW50ZXJmYWNlc19jb3VudDsKLQotICAgIGludGVyZmFjZXNfY291bnQgPSBmaWxlLnJlYWRVbnNpZ25lZFNob3J0KCk7Ci0gICAgaW50ZXJmYWNlcyAgICAgICA9IG5ldyBpbnRbaW50ZXJmYWNlc19jb3VudF07Ci0KLSAgICBmb3IoaW50IGk9MDsgaSA8IGludGVyZmFjZXNfY291bnQ7IGkrKykKLSAgICAgIGludGVyZmFjZXNbaV0gPSBmaWxlLnJlYWRVbnNpZ25lZFNob3J0KCk7Ci0gIH0KLSAgLyoqCi0gICAqIFJlYWQgaW5mb3JtYXRpb24gYWJvdXQgdGhlIG1ldGhvZHMgb2YgdGhlIGNsYXNzLgotICAgKiBAdGhyb3dzICBJT0V4Y2VwdGlvbgotICAgKiBAdGhyb3dzICBDbGFzc0Zvcm1hdEV4Y2VwdGlvbgotICAgKi8KLSAgcHJpdmF0ZSBmaW5hbCB2b2lkIHJlYWRNZXRob2RzKCkgdGhyb3dzIElPRXhjZXB0aW9uLCBDbGFzc0Zvcm1hdEV4Y2VwdGlvbgotICB7Ci0gICAgaW50IG1ldGhvZHNfY291bnQ7Ci0KLSAgICBtZXRob2RzX2NvdW50ID0gZmlsZS5yZWFkVW5zaWduZWRTaG9ydCgpOwotICAgIG1ldGhvZHMgICAgICAgPSBuZXcgTWV0aG9kW21ldGhvZHNfY291bnRdOwotCi0gICAgZm9yKGludCBpPTA7IGkgPCBtZXRob2RzX2NvdW50OyBpKyspCi0gICAgICBtZXRob2RzW2ldID0gbmV3IE1ldGhvZChmaWxlLCBjb25zdGFudF9wb29sKTsKLSAgfQotICAvKioKLSAgICogUmVhZCBtYWpvciBhbmQgbWlub3IgdmVyc2lvbiBvZiBjb21waWxlciB3aGljaCBjcmVhdGVkIHRoZSBmaWxlLgotICAgKiBAdGhyb3dzICBJT0V4Y2VwdGlvbgotICAgKiBAdGhyb3dzICBDbGFzc0Zvcm1hdEV4Y2VwdGlvbgotICAgKi8KLSAgcHJpdmF0ZSBmaW5hbCB2b2lkIHJlYWRWZXJzaW9uKCkgdGhyb3dzIElPRXhjZXB0aW9uLCBDbGFzc0Zvcm1hdEV4Y2VwdGlvbgotICB7Ci0gICAgbWlub3IgPSBmaWxlLnJlYWRVbnNpZ25lZFNob3J0KCk7Ci0gICAgbWFqb3IgPSBmaWxlLnJlYWRVbnNpZ25lZFNob3J0KCk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvQ29kZS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2NsYXNzZmlsZS9Db2RlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGY3YWNlNmYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2NsYXNzZmlsZS9Db2RlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzNzYgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuY2xhc3NmaWxlOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi1pbXBvcnQgIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50czsKLWltcG9ydCAgamF2YS5pby4qOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgcmVwcmVzZW50cyBhIGNodW5rIG9mIEphdmEgYnl0ZSBjb2RlIGNvbnRhaW5lZCBpbiBhCi0gKiBtZXRob2QuIEl0IGlzIGluc3RhbnRpYXRlZCBieSB0aGUKLSAqIDxlbT5BdHRyaWJ1dGUucmVhZEF0dHJpYnV0ZSgpPC9lbT4gbWV0aG9kLiBBIDxlbT5Db2RlPC9lbT4KLSAqIGF0dHJpYnV0ZSBjb250YWlucyBpbmZvcm1hdGlvbnMgYWJvdXQgb3BlcmFuZCBzdGFjaywgbG9jYWwKLSAqIHZhcmlhYmxlcywgYnl0ZSBjb2RlIGFuZCB0aGUgZXhjZXB0aW9ucyBoYW5kbGVkIHdpdGhpbiB0aGlzCi0gKiBtZXRob2QuCi0gKgotICogVGhpcyBhdHRyaWJ1dGUgaGFzIGF0dHJpYnV0ZXMgaXRzZWxmLCBuYW1lbHkgPGVtPkxpbmVOdW1iZXJUYWJsZTwvZW0+IHdoaWNoCi0gKiBpcyB1c2VkIGZvciBkZWJ1Z2dpbmcgcHVycG9zZXMgYW5kIDxlbT5Mb2NhbFZhcmlhYmxlVGFibGU8L2VtPiB3aGljaAotICogY29udGFpbnMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGxvY2FsIHZhcmlhYmxlcy4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICogQHNlZSAgICAgQXR0cmlidXRlCi0gKiBAc2VlICAgICBDb2RlRXhjZXB0aW9uCi0gKiBAc2VlICAgICBMaW5lTnVtYmVyVGFibGUKLSAqIEBzZWUgTG9jYWxWYXJpYWJsZVRhYmxlCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBDb2RlIGV4dGVuZHMgQXR0cmlidXRlIHsKLSAgcHJpdmF0ZSBpbnQgICAgICAgICAgICAgbWF4X3N0YWNrOyAgIC8vIE1heGltdW0gc2l6ZSBvZiBzdGFjayB1c2VkIGJ5IHRoaXMgbWV0aG9kCi0gIHByaXZhdGUgaW50ICAgICAgICAgICAgIG1heF9sb2NhbHM7ICAvLyBOdW1iZXIgb2YgbG9jYWwgdmFyaWFibGVzCi0gIHByaXZhdGUgaW50ICAgICAgICAgICAgIGNvZGVfbGVuZ3RoOyAvLyBMZW5ndGggb2YgY29kZSBpbiBieXRlcwotICBwcml2YXRlIGJ5dGVbXSAgICAgICAgICBjb2RlOyAgICAgICAgLy8gQWN0dWFsIGJ5dGUgY29kZQotCi0gIHByaXZhdGUgaW50ICAgICAgICAgICAgIGV4Y2VwdGlvbl90YWJsZV9sZW5ndGg7Ci0gIHByaXZhdGUgQ29kZUV4Y2VwdGlvbltdIGV4Y2VwdGlvbl90YWJsZTsgIC8vIFRhYmxlIG9mIGhhbmRsZWQgZXhjZXB0aW9ucwotICBwcml2YXRlIGludCAgICAgICAgICAgICBhdHRyaWJ1dGVzX2NvdW50OyAvLyBBdHRyaWJ1dGVzIG9mIGNvZGU6IExpbmVOdW1iZXIKLSAgcHJpdmF0ZSBBdHRyaWJ1dGVbXSAgICAgYXR0cmlidXRlczsgICAgICAgLy8gb3IgTG9jYWxWYXJpYWJsZQotCi0gIC8qKgotICAgKiBJbml0aWFsaXplIGZyb20gYW5vdGhlciBvYmplY3QuIE5vdGUgdGhhdCBib3RoIG9iamVjdHMgdXNlIHRoZSBzYW1lCi0gICAqIHJlZmVyZW5jZXMgKHNoYWxsb3cgY29weSkuIFVzZSBjb3B5KCkgZm9yIGEgcGh5c2ljYWwgY29weS4KLSAgICovCi0gIHB1YmxpYyBDb2RlKENvZGUgYykgewotICAgIHRoaXMoYy5nZXROYW1lSW5kZXgoKSwgYy5nZXRMZW5ndGgoKSwgYy5nZXRNYXhTdGFjaygpLCBjLmdldE1heExvY2FscygpLAotICAgICAgICAgYy5nZXRDb2RlKCksIGMuZ2V0RXhjZXB0aW9uVGFibGUoKSwgYy5nZXRBdHRyaWJ1dGVzKCksCi0gICAgICAgICBjLmdldENvbnN0YW50UG9vbCgpKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gbmFtZV9pbmRleCBJbmRleCBwb2ludGluZyB0byB0aGUgbmFtZSA8ZW0+Q29kZTwvZW0+Ci0gICAqIEBwYXJhbSBsZW5ndGggQ29udGVudCBsZW5ndGggaW4gYnl0ZXMKLSAgICogQHBhcmFtIGZpbGUgSW5wdXQgc3RyZWFtCi0gICAqIEBwYXJhbSBjb25zdGFudF9wb29sIEFycmF5IG9mIGNvbnN0YW50cwotICAgKi8KLSAgQ29kZShpbnQgbmFtZV9pbmRleCwgaW50IGxlbmd0aCwgRGF0YUlucHV0U3RyZWFtIGZpbGUsCi0gICAgICAgQ29uc3RhbnRQb29sIGNvbnN0YW50X3Bvb2wpIHRocm93cyBJT0V4Y2VwdGlvbgotICB7Ci0gICAgLy8gSW5pdGlhbGl6ZSB3aXRoIHNvbWUgZGVmYXVsdCB2YWx1ZXMgd2hpY2ggd2lsbCBiZSBvdmVyd3JpdHRlbiBsYXRlcgotICAgIHRoaXMobmFtZV9pbmRleCwgbGVuZ3RoLAotICAgICAgICAgZmlsZS5yZWFkVW5zaWduZWRTaG9ydCgpLCBmaWxlLnJlYWRVbnNpZ25lZFNob3J0KCksCi0gICAgICAgICAoYnl0ZVtdKW51bGwsIChDb2RlRXhjZXB0aW9uW10pbnVsbCwgKEF0dHJpYnV0ZVtdKW51bGwsCi0gICAgICAgICBjb25zdGFudF9wb29sKTsKLQotICAgIGNvZGVfbGVuZ3RoID0gZmlsZS5yZWFkSW50KCk7Ci0gICAgY29kZSA9IG5ldyBieXRlW2NvZGVfbGVuZ3RoXTsgLy8gUmVhZCBieXRlIGNvZGUKLSAgICBmaWxlLnJlYWRGdWxseShjb2RlKTsKLQotICAgIC8qIFJlYWQgZXhjZXB0aW9uIHRhYmxlIHRoYXQgY29udGFpbnMgYWxsIHJlZ2lvbnMgd2hlcmUgYW4gZXhjZXB0aW9uCi0gICAgICogaGFuZGxlciBpcyBhY3RpdmUsIGkuZS4sIGEgdHJ5IHsgLi4uIH0gY2F0Y2goKSBibG9jay4KLSAgICAgKi8KLSAgICBleGNlcHRpb25fdGFibGVfbGVuZ3RoID0gZmlsZS5yZWFkVW5zaWduZWRTaG9ydCgpOwotICAgIGV4Y2VwdGlvbl90YWJsZSAgICAgICAgPSBuZXcgQ29kZUV4Y2VwdGlvbltleGNlcHRpb25fdGFibGVfbGVuZ3RoXTsKLQotICAgIGZvcihpbnQgaT0wOyBpIDwgZXhjZXB0aW9uX3RhYmxlX2xlbmd0aDsgaSsrKQotICAgICAgZXhjZXB0aW9uX3RhYmxlW2ldID0gbmV3IENvZGVFeGNlcHRpb24oZmlsZSk7Ci0KLSAgICAvKiBSZWFkIGFsbCBhdHRyaWJ1dGVzLCBjdXJyZW50bHkgYExpbmVOdW1iZXJUYWJsZScgYW5kCi0gICAgICogYExvY2FsVmFyaWFibGVUYWJsZScKLSAgICAgKi8KLSAgICBhdHRyaWJ1dGVzX2NvdW50ID0gZmlsZS5yZWFkVW5zaWduZWRTaG9ydCgpOwotICAgIGF0dHJpYnV0ZXMgPSBuZXcgQXR0cmlidXRlW2F0dHJpYnV0ZXNfY291bnRdOwotICAgIGZvcihpbnQgaT0wOyBpIDwgYXR0cmlidXRlc19jb3VudDsgaSsrKQotICAgICAgYXR0cmlidXRlc1tpXSA9IEF0dHJpYnV0ZS5yZWFkQXR0cmlidXRlKGZpbGUsIGNvbnN0YW50X3Bvb2wpOwotCi0gICAgLyogQWRqdXN0IGxlbmd0aCwgYmVjYXVzZSBvZiBzZXRBdHRyaWJ1dGVzIGluIHRoaXMoKSwgcy5iLiAgbGVuZ3RoCi0gICAgICogaXMgaW5jb3JyZWN0LCBiZWNhdXNlIGl0IGRpZG4ndCB0YWtlIHRoZSBpbnRlcm5hbCBhdHRyaWJ1dGVzCi0gICAgICogaW50byBhY2NvdW50IHlldCEgVmVyeSBzdWJ0bGUgYnVnLCBmaXhlZCBpbiAzLjEuMS4KLSAgICAgKi8KLSAgICB0aGlzLmxlbmd0aCA9IGxlbmd0aDsKLSAgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gbmFtZV9pbmRleCBJbmRleCBwb2ludGluZyB0byB0aGUgbmFtZSA8ZW0+Q29kZTwvZW0+Ci0gICAqIEBwYXJhbSBsZW5ndGggQ29udGVudCBsZW5ndGggaW4gYnl0ZXMKLSAgICogQHBhcmFtIG1heF9zdGFjayBNYXhpbXVtIHNpemUgb2Ygc3RhY2sKLSAgICogQHBhcmFtIG1heF9sb2NhbHMgTnVtYmVyIG9mIGxvY2FsIHZhcmlhYmxlcwotICAgKiBAcGFyYW0gY29kZSBBY3R1YWwgYnl0ZSBjb2RlCi0gICAqIEBwYXJhbSBleGNlcHRpb25fdGFibGUgVGFibGUgb2YgaGFuZGxlZCBleGNlcHRpb25zCi0gICAqIEBwYXJhbSBhdHRyaWJ1dGVzIEF0dHJpYnV0ZXMgb2YgY29kZTogTGluZU51bWJlciBvciBMb2NhbFZhcmlhYmxlCi0gICAqIEBwYXJhbSBjb25zdGFudF9wb29sIEFycmF5IG9mIGNvbnN0YW50cwotICAgKi8KLSAgcHVibGljIENvZGUoaW50IG5hbWVfaW5kZXgsIGludCBsZW5ndGgsCi0gICAgICAgICAgICAgIGludCBtYXhfc3RhY2ssICBpbnQgbWF4X2xvY2FscywKLSAgICAgICAgICAgICAgYnl0ZVtdICAgICAgICAgIGNvZGUsCi0gICAgICAgICAgICAgIENvZGVFeGNlcHRpb25bXSBleGNlcHRpb25fdGFibGUsCi0gICAgICAgICAgICAgIEF0dHJpYnV0ZVtdICAgICBhdHRyaWJ1dGVzLAotICAgICAgICAgICAgICBDb25zdGFudFBvb2wgICAgY29uc3RhbnRfcG9vbCkKLSAgewotICAgIHN1cGVyKENvbnN0YW50cy5BVFRSX0NPREUsIG5hbWVfaW5kZXgsIGxlbmd0aCwgY29uc3RhbnRfcG9vbCk7Ci0KLSAgICB0aGlzLm1heF9zdGFjayAgICAgICAgID0gbWF4X3N0YWNrOwotICAgIHRoaXMubWF4X2xvY2FscyAgICAgICAgPSBtYXhfbG9jYWxzOwotCi0gICAgc2V0Q29kZShjb2RlKTsKLSAgICBzZXRFeGNlcHRpb25UYWJsZShleGNlcHRpb25fdGFibGUpOwotICAgIHNldEF0dHJpYnV0ZXMoYXR0cmlidXRlcyk7IC8vIE92ZXJ3cml0ZXMgbGVuZ3RoIQotICB9Ci0KLSAgLyoqCi0gICAqIENhbGxlZCBieSBvYmplY3RzIHRoYXQgYXJlIHRyYXZlcnNpbmcgdGhlIG5vZGVzIG9mIHRoZSB0cmVlIGltcGxpY2l0ZWx5Ci0gICAqIGRlZmluZWQgYnkgdGhlIGNvbnRlbnRzIG9mIGEgSmF2YSBjbGFzcy4gSS5lLiwgdGhlIGhpZXJhcmNoeSBvZiBtZXRob2RzLAotICAgKiBmaWVsZHMsIGF0dHJpYnV0ZXMsIGV0Yy4gc3Bhd25zIGEgdHJlZSBvZiBvYmplY3RzLgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRDb2RlKHRoaXMpOwotICB9Ci0KLSAgLyoqCi0gICAqIER1bXAgY29kZSBhdHRyaWJ1dGUgdG8gZmlsZSBzdHJlYW0gaW4gYmluYXJ5IGZvcm1hdC4KLSAgICoKLSAgICogQHBhcmFtIGZpbGUgT3V0cHV0IGZpbGUgc3RyZWFtCi0gICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIGR1bXAoRGF0YU91dHB1dFN0cmVhbSBmaWxlKSB0aHJvd3MgSU9FeGNlcHRpb24KLSAgewotICAgIHN1cGVyLmR1bXAoZmlsZSk7Ci0KLSAgICBmaWxlLndyaXRlU2hvcnQobWF4X3N0YWNrKTsKLSAgICBmaWxlLndyaXRlU2hvcnQobWF4X2xvY2Fscyk7Ci0gICAgZmlsZS53cml0ZUludChjb2RlX2xlbmd0aCk7Ci0gICAgZmlsZS53cml0ZShjb2RlLCAwLCBjb2RlX2xlbmd0aCk7Ci0KLSAgICBmaWxlLndyaXRlU2hvcnQoZXhjZXB0aW9uX3RhYmxlX2xlbmd0aCk7Ci0gICAgZm9yKGludCBpPTA7IGkgPCBleGNlcHRpb25fdGFibGVfbGVuZ3RoOyBpKyspCi0gICAgICBleGNlcHRpb25fdGFibGVbaV0uZHVtcChmaWxlKTsKLQotICAgIGZpbGUud3JpdGVTaG9ydChhdHRyaWJ1dGVzX2NvdW50KTsKLSAgICBmb3IoaW50IGk9MDsgaSA8IGF0dHJpYnV0ZXNfY291bnQ7IGkrKykKLSAgICAgIGF0dHJpYnV0ZXNbaV0uZHVtcChmaWxlKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIENvbGxlY3Rpb24gb2YgY29kZSBhdHRyaWJ1dGVzLgotICAgKiBAc2VlIEF0dHJpYnV0ZQotICAgKi8KLSAgcHVibGljIGZpbmFsIEF0dHJpYnV0ZVtdIGdldEF0dHJpYnV0ZXMoKSAgICAgICAgIHsgcmV0dXJuIGF0dHJpYnV0ZXM7IH0KLQotICAvKioKLSAgICogQHJldHVybiBMaW5lTnVtYmVyVGFibGUgb2YgQ29kZSwgaWYgaXQgaGFzIG9uZQotICAgKi8KLSAgcHVibGljIExpbmVOdW1iZXJUYWJsZSBnZXRMaW5lTnVtYmVyVGFibGUoKSB7Ci0gICAgZm9yKGludCBpPTA7IGkgPCBhdHRyaWJ1dGVzX2NvdW50OyBpKyspCi0gICAgICBpZihhdHRyaWJ1dGVzW2ldIGluc3RhbmNlb2YgTGluZU51bWJlclRhYmxlKQotICAgICAgICByZXR1cm4gKExpbmVOdW1iZXJUYWJsZSlhdHRyaWJ1dGVzW2ldOwotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBMb2NhbFZhcmlhYmxlVGFibGUgb2YgQ29kZSwgaWYgaXQgaGFzIG9uZQotICAgKi8KLSAgcHVibGljIExvY2FsVmFyaWFibGVUYWJsZSBnZXRMb2NhbFZhcmlhYmxlVGFibGUoKSB7Ci0gICAgZm9yKGludCBpPTA7IGkgPCBhdHRyaWJ1dGVzX2NvdW50OyBpKyspCi0gICAgICBpZihhdHRyaWJ1dGVzW2ldIGluc3RhbmNlb2YgTG9jYWxWYXJpYWJsZVRhYmxlKQotICAgICAgICByZXR1cm4gKExvY2FsVmFyaWFibGVUYWJsZSlhdHRyaWJ1dGVzW2ldOwotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBBY3R1YWwgYnl0ZSBjb2RlIG9mIHRoZSBtZXRob2QuCi0gICAqLwotICBwdWJsaWMgZmluYWwgYnl0ZVtdIGdldENvZGUoKSAgICAgIHsgcmV0dXJuIGNvZGU7IH0KLQotICAvKioKLSAgICogQHJldHVybiBUYWJsZSBvZiBoYW5kbGVkIGV4Y2VwdGlvbnMuCi0gICAqIEBzZWUgQ29kZUV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGZpbmFsIENvZGVFeGNlcHRpb25bXSBnZXRFeGNlcHRpb25UYWJsZSgpIHsgcmV0dXJuIGV4Y2VwdGlvbl90YWJsZTsgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIE51bWJlciBvZiBsb2NhbCB2YXJpYWJsZXMuCi0gICAqLwotICBwdWJsaWMgZmluYWwgaW50ICBnZXRNYXhMb2NhbHMoKSB7IHJldHVybiBtYXhfbG9jYWxzOyB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gTWF4aW11bSBzaXplIG9mIHN0YWNrIHVzZWQgYnkgdGhpcyBtZXRob2QuCi0gICAqLwotCi0gIHB1YmxpYyBmaW5hbCBpbnQgIGdldE1heFN0YWNrKCkgIHsgcmV0dXJuIG1heF9zdGFjazsgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIHRoZSBpbnRlcm5hbCBsZW5ndGggb2YgdGhpcyBjb2RlIGF0dHJpYnV0ZSAobWludXMgdGhlIGZpcnN0IDYgYnl0ZXMpCi0gICAqIGFuZCBleGNsdWRpbmcgYWxsIGl0cyBhdHRyaWJ1dGVzCi0gICAqLwotICBwcml2YXRlIGZpbmFsIGludCBnZXRJbnRlcm5hbExlbmd0aCgpIHsKLSAgICByZXR1cm4gMiAvKm1heF9zdGFjayovICsgMiAvKm1heF9sb2NhbHMqLyArIDQgLypjb2RlIGxlbmd0aCovCi0gICAgICArIGNvZGVfbGVuZ3RoIC8qYnl0ZS1jb2RlKi8KLSAgICAgICsgMiAvKmV4Y2VwdGlvbi10YWJsZSBsZW5ndGgqLwotICAgICAgKyA4ICogZXhjZXB0aW9uX3RhYmxlX2xlbmd0aCAvKiBleGNlcHRpb24gdGFibGUgKi8KLSAgICAgICsgMiAvKiBhdHRyaWJ1dGVzIGNvdW50ICovOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gdGhlIGZ1bGwgc2l6ZSBvZiB0aGlzIGNvZGUgYXR0cmlidXRlLCBtaW51cyBpdHMgZmlyc3QgNiBieXRlcywKLSAgICogaW5jbHVkaW5nIHRoZSBzaXplIG9mIGFsbCBpdHMgY29udGFpbmVkIGF0dHJpYnV0ZXMKLSAgICovCi0gIHByaXZhdGUgZmluYWwgaW50IGNhbGN1bGF0ZUxlbmd0aCgpIHsKLSAgICBpbnQgbGVuID0gMDsKLQotICAgIGZvcihpbnQgaT0wOyBpIDwgYXR0cmlidXRlc19jb3VudDsgaSsrKQotICAgICAgbGVuICs9IGF0dHJpYnV0ZXNbaV0ubGVuZ3RoICsgNiAvKmF0dHJpYnV0ZSBoZWFkZXIgc2l6ZSovOwotCi0gICAgcmV0dXJuIGxlbiArIGdldEludGVybmFsTGVuZ3RoKCk7Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIGF0dHJpYnV0ZXMuCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBzZXRBdHRyaWJ1dGVzKEF0dHJpYnV0ZVtdIGF0dHJpYnV0ZXMpIHsKLSAgICB0aGlzLmF0dHJpYnV0ZXMgID0gYXR0cmlidXRlczsKLSAgICBhdHRyaWJ1dGVzX2NvdW50ID0gKGF0dHJpYnV0ZXMgPT0gbnVsbCk/IDAgOiBhdHRyaWJ1dGVzLmxlbmd0aDsKLSAgICBsZW5ndGggPSBjYWxjdWxhdGVMZW5ndGgoKTsgLy8gQWRqdXN0IGxlbmd0aAotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBjb2RlIGJ5dGUgY29kZQotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgc2V0Q29kZShieXRlW10gY29kZSkgewotICAgIHRoaXMuY29kZSAgID0gY29kZTsKLSAgICBjb2RlX2xlbmd0aCA9IChjb2RlID09IG51bGwpPyAwIDogY29kZS5sZW5ndGg7Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIGV4Y2VwdGlvbl90YWJsZSBleGNlcHRpb24gdGFibGUKLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHNldEV4Y2VwdGlvblRhYmxlKENvZGVFeGNlcHRpb25bXSBleGNlcHRpb25fdGFibGUpIHsKLSAgICB0aGlzLmV4Y2VwdGlvbl90YWJsZSAgID0gZXhjZXB0aW9uX3RhYmxlOwotICAgIGV4Y2VwdGlvbl90YWJsZV9sZW5ndGggPSAoZXhjZXB0aW9uX3RhYmxlID09IG51bGwpPyAwIDoKLSAgICAgIGV4Y2VwdGlvbl90YWJsZS5sZW5ndGg7Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIG1heF9sb2NhbHMgbWF4aW11bSBudW1iZXIgb2YgbG9jYWwgdmFyaWFibGVzCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBzZXRNYXhMb2NhbHMoaW50IG1heF9sb2NhbHMpIHsKLSAgICB0aGlzLm1heF9sb2NhbHMgPSBtYXhfbG9jYWxzOwotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBtYXhfc3RhY2sgbWF4aW11bSBzdGFjayBzaXplCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBzZXRNYXhTdGFjayhpbnQgbWF4X3N0YWNrKSB7Ci0gICAgdGhpcy5tYXhfc3RhY2sgPSBtYXhfc3RhY2s7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBTdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgY29kZSBjaHVuay4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBTdHJpbmcgdG9TdHJpbmcoYm9vbGVhbiB2ZXJib3NlKSB7Ci0gICAgU3RyaW5nQnVmZmVyIGJ1ZjsKLQotICAgIGJ1ZiA9IG5ldyBTdHJpbmdCdWZmZXIoIkNvZGUobWF4X3N0YWNrID0gIiArIG1heF9zdGFjayArCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAiLCBtYXhfbG9jYWxzID0gIiArIG1heF9sb2NhbHMgKwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIiwgY29kZV9sZW5ndGggPSAiICsgY29kZV9sZW5ndGggKyAiKVxuIiArCi0gICAgICAgICAgICAgICAgICAgICAgICAgICBVdGlsaXR5LmNvZGVUb1N0cmluZyhjb2RlLCBjb25zdGFudF9wb29sLCAwLCAtMSwgdmVyYm9zZSkpOwotCi0gICAgaWYoZXhjZXB0aW9uX3RhYmxlX2xlbmd0aCA+IDApIHsKLSAgICAgIGJ1Zi5hcHBlbmQoIlxuRXhjZXB0aW9uIGhhbmRsZXIocykgPSBcbiIgKyAiRnJvbVx0VG9cdEhhbmRsZXJcdFR5cGVcbiIpOwotCi0gICAgICBmb3IoaW50IGk9MDsgaSA8IGV4Y2VwdGlvbl90YWJsZV9sZW5ndGg7IGkrKykKLSAgICAgICAgYnVmLmFwcGVuZChleGNlcHRpb25fdGFibGVbaV0udG9TdHJpbmcoY29uc3RhbnRfcG9vbCwgdmVyYm9zZSkgKyAiXG4iKTsKLSAgICB9Ci0KLSAgICBpZihhdHRyaWJ1dGVzX2NvdW50ID4gMCkgewotICAgICAgYnVmLmFwcGVuZCgiXG5BdHRyaWJ1dGUocykgPSBcbiIpOwotCi0gICAgICBmb3IoaW50IGk9MDsgaSA8IGF0dHJpYnV0ZXNfY291bnQ7IGkrKykKLSAgICAgICAgYnVmLmFwcGVuZChhdHRyaWJ1dGVzW2ldLnRvU3RyaW5nKCkgKyAiXG4iKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gYnVmLnRvU3RyaW5nKCk7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBTdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgY29kZSBjaHVuay4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0gICAgcmV0dXJuIHRvU3RyaW5nKHRydWUpOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gZGVlcCBjb3B5IG9mIHRoaXMgYXR0cmlidXRlCi0gICAqLwotICBwdWJsaWMgQXR0cmlidXRlIGNvcHkoQ29uc3RhbnRQb29sIGNvbnN0YW50X3Bvb2wpIHsKLSAgICBDb2RlIGMgPSAoQ29kZSljbG9uZSgpOwotICAgIGMuY29kZSAgICAgICAgICA9IChieXRlW10pY29kZS5jbG9uZSgpOwotICAgIGMuY29uc3RhbnRfcG9vbCA9IGNvbnN0YW50X3Bvb2w7Ci0KLSAgICBjLmV4Y2VwdGlvbl90YWJsZSA9IG5ldyBDb2RlRXhjZXB0aW9uW2V4Y2VwdGlvbl90YWJsZV9sZW5ndGhdOwotICAgIGZvcihpbnQgaT0wOyBpIDwgZXhjZXB0aW9uX3RhYmxlX2xlbmd0aDsgaSsrKQotICAgICAgYy5leGNlcHRpb25fdGFibGVbaV0gPSBleGNlcHRpb25fdGFibGVbaV0uY29weSgpOwotCi0gICAgYy5hdHRyaWJ1dGVzID0gbmV3IEF0dHJpYnV0ZVthdHRyaWJ1dGVzX2NvdW50XTsKLSAgICBmb3IoaW50IGk9MDsgaSA8IGF0dHJpYnV0ZXNfY291bnQ7IGkrKykKLSAgICAgIGMuYXR0cmlidXRlc1tpXSA9IGF0dHJpYnV0ZXNbaV0uY29weShjb25zdGFudF9wb29sKTsKLQotICAgIHJldHVybiBjOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvY2xhc3NmaWxlL0NvZGVFeGNlcHRpb24uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvQ29kZUV4Y2VwdGlvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0Y2YxNzI1Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvQ29kZUV4Y2VwdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjMyICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmNsYXNzZmlsZTsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotaW1wb3J0ICBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHM7Ci1pbXBvcnQgIGphdmEuaW8uKjsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIHJlcHJlc2VudHMgYW4gZW50cnkgaW4gdGhlIGV4Y2VwdGlvbiB0YWJsZSBvZiB0aGUgPGVtPkNvZGU8L2VtPgotICogYXR0cmlidXRlIGFuZCBpcyB1c2VkIG9ubHkgdGhlcmUuIEl0IGNvbnRhaW5zIGEgcmFuZ2UgaW4gd2hpY2ggYQotICogcGFydGljdWxhciBleGNlcHRpb24gaGFuZGxlciBpcyBhY3RpdmUuCi0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqIEBzZWUgICAgIENvZGUKLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIENvZGVFeGNlcHRpb24KLSAgaW1wbGVtZW50cyBDbG9uZWFibGUsIENvbnN0YW50cywgTm9kZSwgU2VyaWFsaXphYmxlCi17Ci0gIHByaXZhdGUgaW50IHN0YXJ0X3BjOyAgIC8vIFJhbmdlIGluIHRoZSBjb2RlIHRoZSBleGNlcHRpb24gaGFuZGxlciBpcwotICBwcml2YXRlIGludCBlbmRfcGM7ICAgICAvLyBhY3RpdmUuIHN0YXJ0X3BjIGlzIGluY2x1c2l2ZSwgZW5kX3BjIGV4Y2x1c2l2ZQotICBwcml2YXRlIGludCBoYW5kbGVyX3BjOyAvKiBTdGFydGluZyBhZGRyZXNzIG9mIGV4Y2VwdGlvbiBoYW5kbGVyLCBpLmUuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBhbiBvZmZzZXQgZnJvbSBzdGFydCBvZiBjb2RlLgotICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLSAgcHJpdmF0ZSBpbnQgY2F0Y2hfdHlwZTsgLyogSWYgdGhpcyBpcyB6ZXJvIHRoZSBoYW5kbGVyIGNhdGNoZXMgYW55Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAqIGV4Y2VwdGlvbiwgb3RoZXJ3aXNlIGl0IHBvaW50cyB0byB0aGUKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICogZXhjZXB0aW9uIGNsYXNzIHdoaWNoIGlzIHRvIGJlIGNhdWdodC4KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi0gIC8qKgotICAgKiBJbml0aWFsaXplIGZyb20gYW5vdGhlciBvYmplY3QuCi0gICAqLwotICBwdWJsaWMgQ29kZUV4Y2VwdGlvbihDb2RlRXhjZXB0aW9uIGMpIHsKLSAgICB0aGlzKGMuZ2V0U3RhcnRQQygpLCBjLmdldEVuZFBDKCksIGMuZ2V0SGFuZGxlclBDKCksIGMuZ2V0Q2F0Y2hUeXBlKCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBvYmplY3QgZnJvbSBmaWxlIHN0cmVhbS4KLSAgICogQHBhcmFtIGZpbGUgSW5wdXQgc3RyZWFtCi0gICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLSAgICovCi0gIENvZGVFeGNlcHRpb24oRGF0YUlucHV0U3RyZWFtIGZpbGUpIHRocm93cyBJT0V4Y2VwdGlvbgotICB7Ci0gICAgdGhpcyhmaWxlLnJlYWRVbnNpZ25lZFNob3J0KCksIGZpbGUucmVhZFVuc2lnbmVkU2hvcnQoKSwKLSAgICAgICAgIGZpbGUucmVhZFVuc2lnbmVkU2hvcnQoKSwgZmlsZS5yZWFkVW5zaWduZWRTaG9ydCgpKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gc3RhcnRfcGMgUmFuZ2UgaW4gdGhlIGNvZGUgdGhlIGV4Y2VwdGlvbiBoYW5kbGVyIGlzIGFjdGl2ZSwKLSAgICogc3RhcnRfcGMgaXMgaW5jbHVzaXZlIHdoaWxlCi0gICAqIEBwYXJhbSBlbmRfcGMgaXMgZXhjbHVzaXZlCi0gICAqIEBwYXJhbSBoYW5kbGVyX3BjIFN0YXJ0aW5nIGFkZHJlc3Mgb2YgZXhjZXB0aW9uIGhhbmRsZXIsIGkuZS4sCi0gICAqIGFuIG9mZnNldCBmcm9tIHN0YXJ0IG9mIGNvZGUuCi0gICAqIEBwYXJhbSBjYXRjaF90eXBlIElmIHplcm8gdGhlIGhhbmRsZXIgY2F0Y2hlcyBhbnkKLSAgICogZXhjZXB0aW9uLCBvdGhlcndpc2UgaXQgcG9pbnRzIHRvIHRoZSBleGNlcHRpb24gY2xhc3Mgd2hpY2ggaXMKLSAgICogdG8gYmUgY2F1Z2h0LgotICAgKi8KLSAgcHVibGljIENvZGVFeGNlcHRpb24oaW50IHN0YXJ0X3BjLCBpbnQgZW5kX3BjLCBpbnQgaGFuZGxlcl9wYywKLSAgICAgICAgICAgICAgICAgICAgICAgaW50IGNhdGNoX3R5cGUpCi0gIHsKLSAgICB0aGlzLnN0YXJ0X3BjICAgPSBzdGFydF9wYzsKLSAgICB0aGlzLmVuZF9wYyAgICAgPSBlbmRfcGM7Ci0gICAgdGhpcy5oYW5kbGVyX3BjID0gaGFuZGxlcl9wYzsKLSAgICB0aGlzLmNhdGNoX3R5cGUgPSBjYXRjaF90eXBlOwotICB9Ci0KLSAgLyoqCi0gICAqIENhbGxlZCBieSBvYmplY3RzIHRoYXQgYXJlIHRyYXZlcnNpbmcgdGhlIG5vZGVzIG9mIHRoZSB0cmVlIGltcGxpY2l0ZWx5Ci0gICAqIGRlZmluZWQgYnkgdGhlIGNvbnRlbnRzIG9mIGEgSmF2YSBjbGFzcy4gSS5lLiwgdGhlIGhpZXJhcmNoeSBvZiBtZXRob2RzLAotICAgKiBmaWVsZHMsIGF0dHJpYnV0ZXMsIGV0Yy4gc3Bhd25zIGEgdHJlZSBvZiBvYmplY3RzLgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRDb2RlRXhjZXB0aW9uKHRoaXMpOwotICB9Ci0gIC8qKgotICAgKiBEdW1wIGNvZGUgZXhjZXB0aW9uIHRvIGZpbGUgc3RyZWFtIGluIGJpbmFyeSBmb3JtYXQuCi0gICAqCi0gICAqIEBwYXJhbSBmaWxlIE91dHB1dCBmaWxlIHN0cmVhbQotICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBkdW1wKERhdGFPdXRwdXRTdHJlYW0gZmlsZSkgdGhyb3dzIElPRXhjZXB0aW9uCi0gIHsKLSAgICBmaWxlLndyaXRlU2hvcnQoc3RhcnRfcGMpOwotICAgIGZpbGUud3JpdGVTaG9ydChlbmRfcGMpOwotICAgIGZpbGUud3JpdGVTaG9ydChoYW5kbGVyX3BjKTsKLSAgICBmaWxlLndyaXRlU2hvcnQoY2F0Y2hfdHlwZSk7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiAwLCBpZiB0aGUgaGFuZGxlciBjYXRjaGVzIGFueSBleGNlcHRpb24sIG90aGVyd2lzZSBpdCBwb2ludHMgdG8KLSAgICogdGhlIGV4Y2VwdGlvbiBjbGFzcyB3aGljaCBpcyB0byBiZSBjYXVnaHQuCi0gICAqLwotICBwdWJsaWMgZmluYWwgaW50IGdldENhdGNoVHlwZSgpIHsgcmV0dXJuIGNhdGNoX3R5cGU7IH0KLQotICAvKioKLSAgICogQHJldHVybiBFeGNsdXNpdmUgZW5kIGluZGV4IG9mIHRoZSByZWdpb24gd2hlcmUgdGhlIGhhbmRsZXIgaXMgYWN0aXZlLgotICAgKi8KLSAgcHVibGljIGZpbmFsIGludCBnZXRFbmRQQygpIHsgcmV0dXJuIGVuZF9wYzsgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIFN0YXJ0aW5nIGFkZHJlc3Mgb2YgZXhjZXB0aW9uIGhhbmRsZXIsIHJlbGF0aXZlIHRvIHRoZSBjb2RlLgotICAgKi8KLSAgcHVibGljIGZpbmFsIGludCBnZXRIYW5kbGVyUEMoKSB7IHJldHVybiBoYW5kbGVyX3BjOyB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gSW5jbHVzaXZlIHN0YXJ0IGluZGV4IG9mIHRoZSByZWdpb24gd2hlcmUgdGhlIGhhbmRsZXIgaXMgYWN0aXZlLgotICAgKi8KLSAgcHVibGljIGZpbmFsIGludCBnZXRTdGFydFBDKCkgeyByZXR1cm4gc3RhcnRfcGM7IH0KLQotICAvKioKLSAgICogQHBhcmFtIGNhdGNoX3R5cGUuCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBzZXRDYXRjaFR5cGUoaW50IGNhdGNoX3R5cGUpIHsKLSAgICB0aGlzLmNhdGNoX3R5cGUgPSBjYXRjaF90eXBlOwotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBlbmRfcGMgZW5kIG9mIGhhbmRsZWQgYmxvY2sKLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHNldEVuZFBDKGludCBlbmRfcGMpIHsKLSAgICB0aGlzLmVuZF9wYyA9IGVuZF9wYzsKLSAgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gaGFuZGxlcl9wYyB3aGVyZSB0aGUgYWN0dWFsIGNvZGUgaXMKLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHNldEhhbmRsZXJQQyhpbnQgaGFuZGxlcl9wYykgewotICAgIHRoaXMuaGFuZGxlcl9wYyA9IGhhbmRsZXJfcGM7Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIHN0YXJ0X3BjIHN0YXJ0IG9mIGhhbmRsZWQgYmxvY2sKLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHNldFN0YXJ0UEMoaW50IHN0YXJ0X3BjKSB7Ci0gICAgdGhpcy5zdGFydF9wYyA9IHN0YXJ0X3BjOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gU3RyaW5nIHJlcHJlc2VudGF0aW9uLgotICAgKi8KLSAgcHVibGljIGZpbmFsIFN0cmluZyB0b1N0cmluZygpIHsKLSAgICByZXR1cm4gIkNvZGVFeGNlcHRpb24oc3RhcnRfcGMgPSAiICsgc3RhcnRfcGMgKwotICAgICAgIiwgZW5kX3BjID0gIiArIGVuZF9wYyArCi0gICAgICAiLCBoYW5kbGVyX3BjID0gIiArIGhhbmRsZXJfcGMgKyAiLCBjYXRjaF90eXBlID0gIiArIGNhdGNoX3R5cGUgKyAiKSI7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBTdHJpbmcgcmVwcmVzZW50YXRpb24uCi0gICAqLwotICBwdWJsaWMgZmluYWwgU3RyaW5nIHRvU3RyaW5nKENvbnN0YW50UG9vbCBjcCwgYm9vbGVhbiB2ZXJib3NlKSB7Ci0gICAgU3RyaW5nIHN0cjsKLQotICAgIGlmKGNhdGNoX3R5cGUgPT0gMCkKLSAgICAgIHN0ciA9ICI8QW55IGV4Y2VwdGlvbj4oMCkiOwotICAgIGVsc2UKLSAgICAgIHN0ciA9IFV0aWxpdHkuY29tcGFjdENsYXNzTmFtZShjcC5nZXRDb25zdGFudFN0cmluZyhjYXRjaF90eXBlLCBDT05TVEFOVF9DbGFzcyksIGZhbHNlKSArCi0gICAgICAgICh2ZXJib3NlPyAiKCIgKyBjYXRjaF90eXBlICsgIikiIDogIiIpOwotCi0gICAgcmV0dXJuIHN0YXJ0X3BjICsgIlx0IiArIGVuZF9wYyArICJcdCIgKyBoYW5kbGVyX3BjICsgIlx0IiArIHN0cjsKLSAgfQotCi0gIHB1YmxpYyBmaW5hbCBTdHJpbmcgdG9TdHJpbmcoQ29uc3RhbnRQb29sIGNwKSB7Ci0gICAgcmV0dXJuIHRvU3RyaW5nKGNwLCB0cnVlKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIGRlZXAgY29weSBvZiB0aGlzIG9iamVjdAotICAgKi8KLSAgcHVibGljIENvZGVFeGNlcHRpb24gY29weSgpIHsKLSAgICB0cnkgewotICAgICAgcmV0dXJuIChDb2RlRXhjZXB0aW9uKWNsb25lKCk7Ci0gICAgfSBjYXRjaChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKSB7fQotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvQ29uc3RhbnQuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvQ29uc3RhbnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOTMxYjhlMi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvY2xhc3NmaWxlL0NvbnN0YW50LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNTEgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuY2xhc3NmaWxlOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi1pbXBvcnQgIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50czsKLWltcG9ydCAgamF2YS5pby4qOwotCi0vKioKLSAqIEFic3RyYWN0IHN1cGVyY2xhc3MgZm9yIGNsYXNzZXMgdG8gcmVwcmVzZW50IHRoZSBkaWZmZXJlbnQgY29uc3RhbnQgdHlwZXMKLSAqIGluIHRoZSBjb25zdGFudCBwb29sIG9mIGEgY2xhc3MgZmlsZS4gVGhlIGNsYXNzZXMga2VlcCBjbG9zZWx5IHRvCi0gKiB0aGUgSlZNIHNwZWNpZmljYXRpb24uCi0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGFic3RyYWN0IGNsYXNzIENvbnN0YW50IGltcGxlbWVudHMgQ2xvbmVhYmxlLCBOb2RlLCBTZXJpYWxpemFibGUgewotICAvKiBJbiBmYWN0IHRoaXMgdGFnIGlzIHJlZHVuZGFudCBzaW5jZSB3ZSBjYW4gZGlzdGluZ3Vpc2ggZGlmZmVyZW50Ci0gICAqIGBDb25zdGFudCcgb2JqZWN0cyBieSB0aGVpciB0eXBlLCBpLmUuLCB2aWEgYGluc3RhbmNlb2YnLiBJbiBzb21lCi0gICAqIHBsYWNlcyB3ZSB3aWxsIHVzZSB0aGUgdGFnIGZvciBzd2l0Y2goKWVzIGFueXdheS4KLSAgICoKLSAgICogRmlyc3QsIHdlIHdhbnQgbWF0Y2ggdGhlIHNwZWNpZmljYXRpb24gYXMgY2xvc2VseSBhcyBwb3NzaWJsZS4gU2Vjb25kIHdlCi0gICAqIG5lZWQgdGhlIHRhZyBhcyBhbiBpbmRleCB0byBzZWxlY3QgdGhlIGNvcnJlc3BvbmRpbmcgY2xhc3MgbmFtZSBmcm9tIHRoZQotICAgKiBgQ09OU1RBTlRfTkFNRVMnIGFycmF5LgotICAgKi8KLSAgcHJvdGVjdGVkIGJ5dGUgdGFnOwotCi0gIENvbnN0YW50KGJ5dGUgdGFnKSB7IHRoaXMudGFnID0gdGFnOyB9Ci0KLSAgLyoqCi0gICAqIENhbGxlZCBieSBvYmplY3RzIHRoYXQgYXJlIHRyYXZlcnNpbmcgdGhlIG5vZGVzIG9mIHRoZSB0cmVlIGltcGxpY2l0ZWx5Ci0gICAqIGRlZmluZWQgYnkgdGhlIGNvbnRlbnRzIG9mIGEgSmF2YSBjbGFzcy4gSS5lLiwgdGhlIGhpZXJhcmNoeSBvZiBtZXRob2RzLAotICAgKiBmaWVsZHMsIGF0dHJpYnV0ZXMsIGV0Yy4gc3Bhd25zIGEgdHJlZSBvZiBvYmplY3RzLgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IHZvaWQgYWNjZXB0KFZpc2l0b3Igdik7Ci0KLSAgcHVibGljIGFic3RyYWN0IHZvaWQgZHVtcChEYXRhT3V0cHV0U3RyZWFtIGZpbGUpIHRocm93cyBJT0V4Y2VwdGlvbjsKLQotICAvKioKLSAgICogQHJldHVybiBUYWcgb2YgY29uc3RhbnQsIGkuZS4sIGl0cyB0eXBlLiBObyBzZXRUYWcoKSBtZXRob2QgdG8gYXZvaWQKLSAgICogY29uZnVzaW9uLgotICAgKi8KLSAgcHVibGljIGZpbmFsIGJ5dGUgZ2V0VGFnKCkgeyByZXR1cm4gdGFnOyB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gU3RyaW5nIHJlcHJlc2VudGF0aW9uLgotICAgKi8KLSAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKLSAgICByZXR1cm4gQ29uc3RhbnRzLkNPTlNUQU5UX05BTUVTW3RhZ10gKyAiWyIgKyB0YWcgKyAiXSI7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBkZWVwIGNvcHkgb2YgdGhpcyBjb25zdGFudAotICAgKi8KLSAgcHVibGljIENvbnN0YW50IGNvcHkoKSB7Ci0gICAgdHJ5IHsKLSAgICAgIHJldHVybiAoQ29uc3RhbnQpc3VwZXIuY2xvbmUoKTsKLSAgICB9IGNhdGNoKENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGUpIHt9Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIHB1YmxpYyBPYmplY3QgY2xvbmUoKSB0aHJvd3MgQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gewotICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlYWQgb25lIGNvbnN0YW50IGZyb20gdGhlIGdpdmVuIGZpbGUsIHRoZSB0eXBlIGRlcGVuZHMgb24gYSB0YWcgYnl0ZS4KLSAgICoKLSAgICogQHBhcmFtIGZpbGUgSW5wdXQgc3RyZWFtCi0gICAqIEByZXR1cm4gQ29uc3RhbnQgb2JqZWN0Ci0gICAqLwotICBzdGF0aWMgZmluYWwgQ29uc3RhbnQgcmVhZENvbnN0YW50KERhdGFJbnB1dFN0cmVhbSBmaWxlKQotICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgQ2xhc3NGb3JtYXRFeGNlcHRpb24KLSAgewotICAgIGJ5dGUgYiA9IGZpbGUucmVhZEJ5dGUoKTsgLy8gUmVhZCB0YWcgYnl0ZQotCi0gICAgc3dpdGNoKGIpIHsKLSAgICBjYXNlIENvbnN0YW50cy5DT05TVEFOVF9DbGFzczogICAgICAgICAgICAgIHJldHVybiBuZXcgQ29uc3RhbnRDbGFzcyhmaWxlKTsKLSAgICBjYXNlIENvbnN0YW50cy5DT05TVEFOVF9GaWVsZHJlZjogICAgICAgICAgIHJldHVybiBuZXcgQ29uc3RhbnRGaWVsZHJlZihmaWxlKTsKLSAgICBjYXNlIENvbnN0YW50cy5DT05TVEFOVF9NZXRob2RyZWY6ICAgICAgICAgIHJldHVybiBuZXcgQ29uc3RhbnRNZXRob2RyZWYoZmlsZSk7Ci0gICAgY2FzZSBDb25zdGFudHMuQ09OU1RBTlRfSW50ZXJmYWNlTWV0aG9kcmVmOiByZXR1cm4gbmV3Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29uc3RhbnRJbnRlcmZhY2VNZXRob2RyZWYoZmlsZSk7Ci0gICAgY2FzZSBDb25zdGFudHMuQ09OU1RBTlRfU3RyaW5nOiAgICAgICAgICAgICByZXR1cm4gbmV3IENvbnN0YW50U3RyaW5nKGZpbGUpOwotICAgIGNhc2UgQ29uc3RhbnRzLkNPTlNUQU5UX0ludGVnZXI6ICAgICAgICAgICAgcmV0dXJuIG5ldyBDb25zdGFudEludGVnZXIoZmlsZSk7Ci0gICAgY2FzZSBDb25zdGFudHMuQ09OU1RBTlRfRmxvYXQ6ICAgICAgICAgICAgICByZXR1cm4gbmV3IENvbnN0YW50RmxvYXQoZmlsZSk7Ci0gICAgY2FzZSBDb25zdGFudHMuQ09OU1RBTlRfTG9uZzogICAgICAgICAgICAgICByZXR1cm4gbmV3IENvbnN0YW50TG9uZyhmaWxlKTsKLSAgICBjYXNlIENvbnN0YW50cy5DT05TVEFOVF9Eb3VibGU6ICAgICAgICAgICAgIHJldHVybiBuZXcgQ29uc3RhbnREb3VibGUoZmlsZSk7Ci0gICAgY2FzZSBDb25zdGFudHMuQ09OU1RBTlRfTmFtZUFuZFR5cGU6ICAgICAgICByZXR1cm4gbmV3IENvbnN0YW50TmFtZUFuZFR5cGUoZmlsZSk7Ci0gICAgY2FzZSBDb25zdGFudHMuQ09OU1RBTlRfVXRmODogICAgICAgICAgICAgICByZXR1cm4gbmV3IENvbnN0YW50VXRmOChmaWxlKTsKLSAgICBkZWZhdWx0OgotICAgICAgdGhyb3cgbmV3IENsYXNzRm9ybWF0RXhjZXB0aW9uKCJJbnZhbGlkIGJ5dGUgdGFnIGluIGNvbnN0YW50IHBvb2w6ICIgKyBiKTsKLSAgICB9Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvQ29uc3RhbnRDUC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2NsYXNzZmlsZS9Db25zdGFudENQLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGIxMmQ3NTIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2NsYXNzZmlsZS9Db25zdGFudENQLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNTcgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuY2xhc3NmaWxlOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotaW1wb3J0IGphdmEuaW8uKjsKLWltcG9ydCAgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzOwotCi0vKioKLSAqIEFic3RyYWN0IHN1cGVyIGNsYXNzIGZvciBGaWVsZHJlZiBhbmQgTWV0aG9kcmVmIGNvbnN0YW50cy4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICogQHNlZSAgICAgQ29uc3RhbnRGaWVsZHJlZgotICogQHNlZSAgICAgQ29uc3RhbnRNZXRob2RyZWYKLSAqIEBzZWUgICAgIENvbnN0YW50SW50ZXJmYWNlTWV0aG9kcmVmCi0gKi8KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBDb25zdGFudENQIGV4dGVuZHMgQ29uc3RhbnQgewotICAvKiogUmVmZXJlbmNlcyB0byB0aGUgY29uc3RhbnRzIGNvbnRhaW5pbmcgdGhlIGNsYXNzIGFuZCB0aGUgZmllbGQgc2lnbmF0dXJlCi0gICAqLwotICBwcm90ZWN0ZWQgaW50IGNsYXNzX2luZGV4LCBuYW1lX2FuZF90eXBlX2luZGV4OwotCi0gIC8qKgotICAgKiBJbml0aWFsaXplIGZyb20gYW5vdGhlciBvYmplY3QuCi0gICAqLwotICBwdWJsaWMgQ29uc3RhbnRDUChDb25zdGFudENQIGMpIHsKLSAgICB0aGlzKGMuZ2V0VGFnKCksIGMuZ2V0Q2xhc3NJbmRleCgpLCBjLmdldE5hbWVBbmRUeXBlSW5kZXgoKSk7Ci0gIH0KLQotICAvKioKLSAgICogSW5pdGlhbGl6ZSBpbnN0YW5jZSBmcm9tIGZpbGUgZGF0YS4KLSAgICoKLSAgICogQHBhcmFtIHRhZyAgQ29uc3RhbnQgdHlwZSB0YWcKLSAgICogQHBhcmFtIGZpbGUgSW5wdXQgc3RyZWFtCi0gICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLSAgICovCi0gIENvbnN0YW50Q1AoYnl0ZSB0YWcsIERhdGFJbnB1dFN0cmVhbSBmaWxlKSB0aHJvd3MgSU9FeGNlcHRpb24KLSAgewotICAgIHRoaXModGFnLCBmaWxlLnJlYWRVbnNpZ25lZFNob3J0KCksIGZpbGUucmVhZFVuc2lnbmVkU2hvcnQoKSk7Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIGNsYXNzX2luZGV4IFJlZmVyZW5jZSB0byB0aGUgY2xhc3MgY29udGFpbmluZyB0aGUgZmllbGQKLSAgICogQHBhcmFtIG5hbWVfYW5kX3R5cGVfaW5kZXggYW5kIHRoZSBmaWVsZCBzaWduYXR1cmUKLSAgICovCi0gIHByb3RlY3RlZCBDb25zdGFudENQKGJ5dGUgdGFnLCBpbnQgY2xhc3NfaW5kZXgsCi0gICAgICAgICAgICAgICAgICAgICAgIGludCBuYW1lX2FuZF90eXBlX2luZGV4KSB7Ci0gICAgc3VwZXIodGFnKTsKLSAgICB0aGlzLmNsYXNzX2luZGV4ICAgICAgICAgPSBjbGFzc19pbmRleDsKLSAgICB0aGlzLm5hbWVfYW5kX3R5cGVfaW5kZXggPSBuYW1lX2FuZF90eXBlX2luZGV4OwotICB9Ci0KLSAgLyoqCi0gICAqIER1bXAgY29uc3RhbnQgZmllbGQgcmVmZXJlbmNlIHRvIGZpbGUgc3RyZWFtIGluIGJpbmFyeSBmb3JtYXQuCi0gICAqCi0gICAqIEBwYXJhbSBmaWxlIE91dHB1dCBmaWxlIHN0cmVhbQotICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBkdW1wKERhdGFPdXRwdXRTdHJlYW0gZmlsZSkgdGhyb3dzIElPRXhjZXB0aW9uCi0gIHsKLSAgICBmaWxlLndyaXRlQnl0ZSh0YWcpOwotICAgIGZpbGUud3JpdGVTaG9ydChjbGFzc19pbmRleCk7Ci0gICAgZmlsZS53cml0ZVNob3J0KG5hbWVfYW5kX3R5cGVfaW5kZXgpOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gUmVmZXJlbmNlIChpbmRleCkgdG8gY2xhc3MgdGhpcyBmaWVsZCBvciBtZXRob2QgYmVsb25ncyB0by4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBpbnQgZ2V0Q2xhc3NJbmRleCgpICAgICAgIHsgcmV0dXJuIGNsYXNzX2luZGV4OyB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gUmVmZXJlbmNlIChpbmRleCkgdG8gc2lnbmF0dXJlIG9mIHRoZSBmaWVsZC4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBpbnQgZ2V0TmFtZUFuZFR5cGVJbmRleCgpIHsgcmV0dXJuIG5hbWVfYW5kX3R5cGVfaW5kZXg7IH0KLQotICAvKioKLSAgICogQHBhcmFtIGNsYXNzX2luZGV4IHBvaW50cyB0byBDb25zdGFudF9jbGFzcwotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgc2V0Q2xhc3NJbmRleChpbnQgY2xhc3NfaW5kZXgpIHsKLSAgICB0aGlzLmNsYXNzX2luZGV4ID0gY2xhc3NfaW5kZXg7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBDbGFzcyB0aGlzIGZpZWxkIGJlbG9uZ3MgdG8uCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldENsYXNzKENvbnN0YW50UG9vbCBjcCkgewotICAgIHJldHVybiBjcC5jb25zdGFudFRvU3RyaW5nKGNsYXNzX2luZGV4LCBDb25zdGFudHMuQ09OU1RBTlRfQ2xhc3MpOwotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBuYW1lX2FuZF90eXBlX2luZGV4IHBvaW50cyB0byBDb25zdGFudF9OYW1lQW5kVHlwZQotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgc2V0TmFtZUFuZFR5cGVJbmRleChpbnQgbmFtZV9hbmRfdHlwZV9pbmRleCkgewotICAgIHRoaXMubmFtZV9hbmRfdHlwZV9pbmRleCA9IG5hbWVfYW5kX3R5cGVfaW5kZXg7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBTdHJpbmcgcmVwcmVzZW50YXRpb24uCi0gICAqLwotICBwdWJsaWMgZmluYWwgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgIHJldHVybiBzdXBlci50b1N0cmluZygpICsgIihjbGFzc19pbmRleCA9ICIgKyBjbGFzc19pbmRleCArCi0gICAgICAiLCBuYW1lX2FuZF90eXBlX2luZGV4ID0gIiArIG5hbWVfYW5kX3R5cGVfaW5kZXggKyAiKSI7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvQ29uc3RhbnRDbGFzcy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2NsYXNzZmlsZS9Db25zdGFudENsYXNzLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGUwNDdjYTguLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2NsYXNzZmlsZS9Db25zdGFudENsYXNzLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNTcgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuY2xhc3NmaWxlOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi1pbXBvcnQgIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50czsKLWltcG9ydCAgamF2YS5pby4qOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgaXMgZGVyaXZlZCBmcm9tIHRoZSBhYnN0cmFjdAotICogPEEgSFJFRj0iY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuY2xhc3NmaWxlLkNvbnN0YW50Lmh0bWwiPkNvbnN0YW50PC9BPiBjbGFzcwotICogYW5kIHJlcHJlc2VudHMgYSByZWZlcmVuY2UgdG8gYSAoZXh0ZXJuYWwpIGNsYXNzLgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKiBAc2VlICAgICBDb25zdGFudAotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgQ29uc3RhbnRDbGFzcyBleHRlbmRzIENvbnN0YW50IGltcGxlbWVudHMgQ29uc3RhbnRPYmplY3QgewotICBwcml2YXRlIGludCBuYW1lX2luZGV4OyAvLyBJZGVudGljYWwgdG8gQ29uc3RhbnRTdHJpbmcgZXhjZXB0IGZvciB0aGUgbmFtZQotCi0gIC8qKgotICAgKiBJbml0aWFsaXplIGZyb20gYW5vdGhlciBvYmplY3QuCi0gICAqLwotICBwdWJsaWMgQ29uc3RhbnRDbGFzcyhDb25zdGFudENsYXNzIGMpIHsKLSAgICB0aGlzKGMuZ2V0TmFtZUluZGV4KCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIEluaXRpYWxpemUgaW5zdGFuY2UgZnJvbSBmaWxlIGRhdGEuCi0gICAqCi0gICAqIEBwYXJhbSBmaWxlIElucHV0IHN0cmVhbQotICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0gICAqLwotICBDb25zdGFudENsYXNzKERhdGFJbnB1dFN0cmVhbSBmaWxlKSB0aHJvd3MgSU9FeGNlcHRpb24KLSAgewotICAgIHRoaXMoZmlsZS5yZWFkVW5zaWduZWRTaG9ydCgpKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gbmFtZV9pbmRleCBOYW1lIGluZGV4IGluIGNvbnN0YW50IHBvb2wuICBTaG91bGQgcmVmZXIgdG8gYQotICAgKiBDb25zdGFudFV0ZjguCi0gICAqLwotICBwdWJsaWMgQ29uc3RhbnRDbGFzcyhpbnQgbmFtZV9pbmRleCkgewotICAgIHN1cGVyKENvbnN0YW50cy5DT05TVEFOVF9DbGFzcyk7Ci0gICAgdGhpcy5uYW1lX2luZGV4ID0gbmFtZV9pbmRleDsKLSAgfQotCi0gIC8qKgotICAgKiBDYWxsZWQgYnkgb2JqZWN0cyB0aGF0IGFyZSB0cmF2ZXJzaW5nIHRoZSBub2RlcyBvZiB0aGUgdHJlZSBpbXBsaWNpdGVseQotICAgKiBkZWZpbmVkIGJ5IHRoZSBjb250ZW50cyBvZiBhIEphdmEgY2xhc3MuIEkuZS4sIHRoZSBoaWVyYXJjaHkgb2YgbWV0aG9kcywKLSAgICogZmllbGRzLCBhdHRyaWJ1dGVzLCBldGMuIHNwYXducyBhIHRyZWUgb2Ygb2JqZWN0cy4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0Q29uc3RhbnRDbGFzcyh0aGlzKTsKLSAgfQotCi0gIC8qKgotICAgKiBEdW1wIGNvbnN0YW50IGNsYXNzIHRvIGZpbGUgc3RyZWFtIGluIGJpbmFyeSBmb3JtYXQuCi0gICAqCi0gICAqIEBwYXJhbSBmaWxlIE91dHB1dCBmaWxlIHN0cmVhbQotICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBkdW1wKERhdGFPdXRwdXRTdHJlYW0gZmlsZSkgdGhyb3dzIElPRXhjZXB0aW9uCi0gIHsKLSAgICBmaWxlLndyaXRlQnl0ZSh0YWcpOwotICAgIGZpbGUud3JpdGVTaG9ydChuYW1lX2luZGV4KTsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIE5hbWUgaW5kZXggaW4gY29uc3RhbnQgcG9vbCBvZiBjbGFzcyBuYW1lLgotICAgKi8KLSAgcHVibGljIGZpbmFsIGludCBnZXROYW1lSW5kZXgoKSB7IHJldHVybiBuYW1lX2luZGV4OyB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBuYW1lX2luZGV4LgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgc2V0TmFtZUluZGV4KGludCBuYW1lX2luZGV4KSB7Ci0gICAgdGhpcy5uYW1lX2luZGV4ID0gbmFtZV9pbmRleDsKLSAgfQotCi0KLSAgLyoqIEByZXR1cm4gU3RyaW5nIG9iamVjdAotICAgKi8KLSAgcHVibGljIE9iamVjdCBnZXRDb25zdGFudFZhbHVlKENvbnN0YW50UG9vbCBjcCkgewotICAgIENvbnN0YW50IGMgPSBjcC5nZXRDb25zdGFudChuYW1lX2luZGV4LCBDb25zdGFudHMuQ09OU1RBTlRfVXRmOCk7Ci0gICAgcmV0dXJuICgoQ29uc3RhbnRVdGY4KWMpLmdldEJ5dGVzKCk7Ci0gIH0KLQotICAvKiogQHJldHVybiBkZXJlZmVyZW5jZWQgc3RyaW5nCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldEJ5dGVzKENvbnN0YW50UG9vbCBjcCkgewotICAgIHJldHVybiAoU3RyaW5nKWdldENvbnN0YW50VmFsdWUoY3ApOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gU3RyaW5nIHJlcHJlc2VudGF0aW9uLgotICAgKi8KLSAgcHVibGljIGZpbmFsIFN0cmluZyB0b1N0cmluZygpIHsKLSAgICByZXR1cm4gc3VwZXIudG9TdHJpbmcoKSArICIobmFtZV9pbmRleCA9ICIgKyBuYW1lX2luZGV4ICsgIikiOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvY2xhc3NmaWxlL0NvbnN0YW50RG91YmxlLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvY2xhc3NmaWxlL0NvbnN0YW50RG91YmxlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDc0ZTdlZjguLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2NsYXNzZmlsZS9Db25zdGFudERvdWJsZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTQ1ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmNsYXNzZmlsZTsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotaW1wb3J0ICBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHM7Ci1pbXBvcnQgIGphdmEuaW8uKjsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGlzIGRlcml2ZWQgZnJvbSB0aGUgYWJzdHJhY3QKLSAqIDxBIEhSRUY9ImNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmNsYXNzZmlsZS5Db25zdGFudC5odG1sIj5Db25zdGFudDwvQT4gY2xhc3MKLSAqIGFuZCByZXByZXNlbnRzIGEgcmVmZXJlbmNlIHRvIGEgRG91YmxlIG9iamVjdC4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICogQHNlZSAgICAgQ29uc3RhbnQKLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIENvbnN0YW50RG91YmxlIGV4dGVuZHMgQ29uc3RhbnQgaW1wbGVtZW50cyBDb25zdGFudE9iamVjdCB7Ci0gIHByaXZhdGUgZG91YmxlIGJ5dGVzOwotCi0gIC8qKgotICAgKiBAcGFyYW0gYnl0ZXMgRGF0YQotICAgKi8KLSAgcHVibGljIENvbnN0YW50RG91YmxlKGRvdWJsZSBieXRlcykgewotICAgIHN1cGVyKENvbnN0YW50cy5DT05TVEFOVF9Eb3VibGUpOwotICAgIHRoaXMuYnl0ZXMgPSBieXRlczsKLSAgfQotCi0gIC8qKgotICAgKiBJbml0aWFsaXplIGZyb20gYW5vdGhlciBvYmplY3QuCi0gICAqLwotICBwdWJsaWMgQ29uc3RhbnREb3VibGUoQ29uc3RhbnREb3VibGUgYykgewotICAgIHRoaXMoYy5nZXRCeXRlcygpKTsKLSAgfQotCi0gIC8qKgotICAgKiBJbml0aWFsaXplIGluc3RhbmNlIGZyb20gZmlsZSBkYXRhLgotICAgKgotICAgKiBAcGFyYW0gZmlsZSBJbnB1dCBzdHJlYW0KLSAgICogQHRocm93cyBJT0V4Y2VwdGlvbgotICAgKi8KLSAgQ29uc3RhbnREb3VibGUoRGF0YUlucHV0U3RyZWFtIGZpbGUpIHRocm93cyBJT0V4Y2VwdGlvbgotICB7Ci0gICAgdGhpcyhmaWxlLnJlYWREb3VibGUoKSk7Ci0gIH0KLQotICAvKioKLSAgICogQ2FsbGVkIGJ5IG9iamVjdHMgdGhhdCBhcmUgdHJhdmVyc2luZyB0aGUgbm9kZXMgb2YgdGhlIHRyZWUgaW1wbGljaXRlbHkKLSAgICogZGVmaW5lZCBieSB0aGUgY29udGVudHMgb2YgYSBKYXZhIGNsYXNzLiBJLmUuLCB0aGUgaGllcmFyY2h5IG9mIG1ldGhvZHMsCi0gICAqIGZpZWxkcywgYXR0cmlidXRlcywgZXRjLiBzcGF3bnMgYSB0cmVlIG9mIG9iamVjdHMuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgdi52aXNpdENvbnN0YW50RG91YmxlKHRoaXMpOwotICB9Ci0gIC8qKgotICAgKiBEdW1wIGNvbnN0YW50IGRvdWJsZSB0byBmaWxlIHN0cmVhbSBpbiBiaW5hcnkgZm9ybWF0LgotICAgKgotICAgKiBAcGFyYW0gZmlsZSBPdXRwdXQgZmlsZSBzdHJlYW0KLSAgICogQHRocm93cyBJT0V4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgZHVtcChEYXRhT3V0cHV0U3RyZWFtIGZpbGUpIHRocm93cyBJT0V4Y2VwdGlvbgotICB7Ci0gICAgZmlsZS53cml0ZUJ5dGUodGFnKTsKLSAgICBmaWxlLndyaXRlRG91YmxlKGJ5dGVzKTsKLSAgfQotICAvKioKLSAgICogQHJldHVybiBkYXRhLCBpLmUuLCA4IGJ5dGVzLgotICAgKi8KLSAgcHVibGljIGZpbmFsIGRvdWJsZSBnZXRCeXRlcygpIHsgcmV0dXJuIGJ5dGVzOyB9Ci0gIC8qKgotICAgKiBAcGFyYW0gYnl0ZXMuCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBzZXRCeXRlcyhkb3VibGUgYnl0ZXMpIHsKLSAgICB0aGlzLmJ5dGVzID0gYnl0ZXM7Ci0gIH0KLSAgLyoqCi0gICAqIEByZXR1cm4gU3RyaW5nIHJlcHJlc2VudGF0aW9uLgotICAgKi8KLSAgcHVibGljIGZpbmFsIFN0cmluZyB0b1N0cmluZygpCi0gIHsKLSAgICByZXR1cm4gc3VwZXIudG9TdHJpbmcoKSArICIoYnl0ZXMgPSAiICsgYnl0ZXMgKyAiKSI7Ci0gIH0KLQotICAvKiogQHJldHVybiBEb3VibGUgb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgT2JqZWN0IGdldENvbnN0YW50VmFsdWUoQ29uc3RhbnRQb29sIGNwKSB7Ci0gICAgcmV0dXJuIG5ldyBEb3VibGUoYnl0ZXMpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvY2xhc3NmaWxlL0NvbnN0YW50RmllbGRyZWYuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvQ29uc3RhbnRGaWVsZHJlZi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1ZDc2ZTExLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvQ29uc3RhbnRGaWVsZHJlZi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTA3ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmNsYXNzZmlsZTsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50czsKLWltcG9ydCBqYXZhLmlvLio7Ci0KLS8qKgotICogVGhpcyBjbGFzcyByZXByZXNlbnRzIGEgY29uc3RhbnQgcG9vbCByZWZlcmVuY2UgdG8gYSBmaWVsZC4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgQ29uc3RhbnRGaWVsZHJlZiBleHRlbmRzIENvbnN0YW50Q1AgewotICAvKioKLSAgICogSW5pdGlhbGl6ZSBmcm9tIGFub3RoZXIgb2JqZWN0LgotICAgKi8KLSAgcHVibGljIENvbnN0YW50RmllbGRyZWYoQ29uc3RhbnRGaWVsZHJlZiBjKSB7Ci0gICAgc3VwZXIoQ29uc3RhbnRzLkNPTlNUQU5UX0ZpZWxkcmVmLCBjLmdldENsYXNzSW5kZXgoKSwgYy5nZXROYW1lQW5kVHlwZUluZGV4KCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIEluaXRpYWxpemUgaW5zdGFuY2UgZnJvbSBmaWxlIGRhdGEuCi0gICAqCi0gICAqIEBwYXJhbSBmaWxlIGlucHV0IHN0cmVhbQotICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0gICAqLwotICBDb25zdGFudEZpZWxkcmVmKERhdGFJbnB1dFN0cmVhbSBmaWxlKSB0aHJvd3MgSU9FeGNlcHRpb24KLSAgewotICAgIHN1cGVyKENvbnN0YW50cy5DT05TVEFOVF9GaWVsZHJlZiwgZmlsZSk7Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIGNsYXNzX2luZGV4IFJlZmVyZW5jZSB0byB0aGUgY2xhc3MgY29udGFpbmluZyB0aGUgRmllbGQKLSAgICogQHBhcmFtIG5hbWVfYW5kX3R5cGVfaW5kZXggYW5kIHRoZSBGaWVsZCBzaWduYXR1cmUKLSAgICovCi0gIHB1YmxpYyBDb25zdGFudEZpZWxkcmVmKGludCBjbGFzc19pbmRleCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBuYW1lX2FuZF90eXBlX2luZGV4KSB7Ci0gICAgc3VwZXIoQ29uc3RhbnRzLkNPTlNUQU5UX0ZpZWxkcmVmLCBjbGFzc19pbmRleCwgbmFtZV9hbmRfdHlwZV9pbmRleCk7Ci0gIH0KLQotICAvKioKLSAgICogQ2FsbGVkIGJ5IG9iamVjdHMgdGhhdCBhcmUgdHJhdmVyc2luZyB0aGUgbm9kZXMgb2YgdGhlIHRyZWUgaW1wbGljaXRlbHkKLSAgICogZGVmaW5lZCBieSB0aGUgY29udGVudHMgb2YgYSBKYXZhIGNsYXNzLiBJLmUuLCB0aGUgaGllcmFyY2h5IG9mIEZpZWxkcywKLSAgICogZmllbGRzLCBhdHRyaWJ1dGVzLCBldGMuIHNwYXducyBhIHRyZWUgb2Ygb2JqZWN0cy4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0Q29uc3RhbnRGaWVsZHJlZih0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2NsYXNzZmlsZS9Db25zdGFudEZsb2F0LmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvY2xhc3NmaWxlL0NvbnN0YW50RmxvYXQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZTE4ZWIxNC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvY2xhc3NmaWxlL0NvbnN0YW50RmxvYXQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE0NCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5jbGFzc2ZpbGU7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHM7Ci1pbXBvcnQgamF2YS5pby4qOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgaXMgZGVyaXZlZCBmcm9tIHRoZSBhYnN0cmFjdAotICogPEEgSFJFRj0iY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuY2xhc3NmaWxlLkNvbnN0YW50Lmh0bWwiPkNvbnN0YW50PC9BPiBjbGFzcwotICogYW5kIHJlcHJlc2VudHMgYSByZWZlcmVuY2UgdG8gYSBmbG9hdCBvYmplY3QuCi0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqIEBzZWUgICAgIENvbnN0YW50Ci0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBDb25zdGFudEZsb2F0IGV4dGVuZHMgQ29uc3RhbnQgaW1wbGVtZW50cyBDb25zdGFudE9iamVjdCB7Ci0gIHByaXZhdGUgZmxvYXQgYnl0ZXM7Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBieXRlcyBEYXRhCi0gICAqLwotICBwdWJsaWMgQ29uc3RhbnRGbG9hdChmbG9hdCBieXRlcykKLSAgewotICAgIHN1cGVyKENvbnN0YW50cy5DT05TVEFOVF9GbG9hdCk7Ci0gICAgdGhpcy5ieXRlcyA9IGJ5dGVzOwotICB9Ci0gIC8qKgotICAgKiBJbml0aWFsaXplIGZyb20gYW5vdGhlciBvYmplY3QuIE5vdGUgdGhhdCBib3RoIG9iamVjdHMgdXNlIHRoZSBzYW1lCi0gICAqIHJlZmVyZW5jZXMgKHNoYWxsb3cgY29weSkuIFVzZSBjbG9uZSgpIGZvciBhIHBoeXNpY2FsIGNvcHkuCi0gICAqLwotICBwdWJsaWMgQ29uc3RhbnRGbG9hdChDb25zdGFudEZsb2F0IGMpIHsKLSAgICB0aGlzKGMuZ2V0Qnl0ZXMoKSk7Ci0gIH0KLSAgLyoqCi0gICAqIEluaXRpYWxpemUgaW5zdGFuY2UgZnJvbSBmaWxlIGRhdGEuCi0gICAqCi0gICAqIEBwYXJhbSBmaWxlIElucHV0IHN0cmVhbQotICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0gICAqLwotICBDb25zdGFudEZsb2F0KERhdGFJbnB1dFN0cmVhbSBmaWxlKSB0aHJvd3MgSU9FeGNlcHRpb24KLSAgewotICAgIHRoaXMoZmlsZS5yZWFkRmxvYXQoKSk7Ci0gIH0KLSAgLyoqCi0gICAqIENhbGxlZCBieSBvYmplY3RzIHRoYXQgYXJlIHRyYXZlcnNpbmcgdGhlIG5vZGVzIG9mIHRoZSB0cmVlIGltcGxpY2l0ZWx5Ci0gICAqIGRlZmluZWQgYnkgdGhlIGNvbnRlbnRzIG9mIGEgSmF2YSBjbGFzcy4gSS5lLiwgdGhlIGhpZXJhcmNoeSBvZiBtZXRob2RzLAotICAgKiBmaWVsZHMsIGF0dHJpYnV0ZXMsIGV0Yy4gc3Bhd25zIGEgdHJlZSBvZiBvYmplY3RzLgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRDb25zdGFudEZsb2F0KHRoaXMpOwotICB9Ci0gIC8qKgotICAgKiBEdW1wIGNvbnN0YW50IGZsb2F0IHRvIGZpbGUgc3RyZWFtIGluIGJpbmFyeSBmb3JtYXQuCi0gICAqCi0gICAqIEBwYXJhbSBmaWxlIE91dHB1dCBmaWxlIHN0cmVhbQotICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBkdW1wKERhdGFPdXRwdXRTdHJlYW0gZmlsZSkgdGhyb3dzIElPRXhjZXB0aW9uCi0gIHsKLSAgICBmaWxlLndyaXRlQnl0ZSh0YWcpOwotICAgIGZpbGUud3JpdGVGbG9hdChieXRlcyk7Ci0gIH0KLSAgLyoqCi0gICAqIEByZXR1cm4gZGF0YSwgaS5lLiwgNCBieXRlcy4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBmbG9hdCBnZXRCeXRlcygpIHsgcmV0dXJuIGJ5dGVzOyB9Ci0gIC8qKgotICAgKiBAcGFyYW0gYnl0ZXMuCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBzZXRCeXRlcyhmbG9hdCBieXRlcykgewotICAgIHRoaXMuYnl0ZXMgPSBieXRlczsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIFN0cmluZyByZXByZXNlbnRhdGlvbi4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0gICAgcmV0dXJuIHN1cGVyLnRvU3RyaW5nKCkgKyAiKGJ5dGVzID0gIiArIGJ5dGVzICsgIikiOwotICB9Ci0KLSAgLyoqIEByZXR1cm4gRmxvYXQgb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgT2JqZWN0IGdldENvbnN0YW50VmFsdWUoQ29uc3RhbnRQb29sIGNwKSB7Ci0gICAgcmV0dXJuIG5ldyBGbG9hdChieXRlcyk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvQ29uc3RhbnRJbnRlZ2VyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvY2xhc3NmaWxlL0NvbnN0YW50SW50ZWdlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhMWU4MTFlLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvQ29uc3RhbnRJbnRlZ2VyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNTEgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5jbGFzc2ZpbGU7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLQotaW1wb3J0ICBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHM7Ci1pbXBvcnQgIGphdmEuaW8uKjsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGlzIGRlcml2ZWQgZnJvbSB0aGUgYWJzdHJhY3QKLSAqIDxBIEhSRUY9ImNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmNsYXNzZmlsZS5Db25zdGFudC5odG1sIj5Db25zdGFudDwvQT4gY2xhc3MKLSAqIGFuZCByZXByZXNlbnRzIGEgcmVmZXJlbmNlIHRvIGFuIGludCBvYmplY3QuCi0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqIEBzZWUgICAgIENvbnN0YW50Ci0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBDb25zdGFudEludGVnZXIgZXh0ZW5kcyBDb25zdGFudCBpbXBsZW1lbnRzIENvbnN0YW50T2JqZWN0IHsKLSAgcHJpdmF0ZSBpbnQgYnl0ZXM7Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBieXRlcyBEYXRhCi0gICAqLwotICBwdWJsaWMgQ29uc3RhbnRJbnRlZ2VyKGludCBieXRlcykKLSAgewotICAgIHN1cGVyKENvbnN0YW50cy5DT05TVEFOVF9JbnRlZ2VyKTsKLSAgICB0aGlzLmJ5dGVzID0gYnl0ZXM7Ci0gIH0KLQotICAvKioKLSAgICogSW5pdGlhbGl6ZSBmcm9tIGFub3RoZXIgb2JqZWN0LgotICAgKi8KLSAgcHVibGljIENvbnN0YW50SW50ZWdlcihDb25zdGFudEludGVnZXIgYykgewotICAgIHRoaXMoYy5nZXRCeXRlcygpKTsKLSAgfQotCi0gIC8qKgotICAgKiBJbml0aWFsaXplIGluc3RhbmNlIGZyb20gZmlsZSBkYXRhLgotICAgKgotICAgKiBAcGFyYW0gZmlsZSBJbnB1dCBzdHJlYW0KLSAgICogQHRocm93cyBJT0V4Y2VwdGlvbgotICAgKi8KLSAgQ29uc3RhbnRJbnRlZ2VyKERhdGFJbnB1dFN0cmVhbSBmaWxlKSB0aHJvd3MgSU9FeGNlcHRpb24KLSAgewotICAgIHRoaXMoZmlsZS5yZWFkSW50KCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIENhbGxlZCBieSBvYmplY3RzIHRoYXQgYXJlIHRyYXZlcnNpbmcgdGhlIG5vZGVzIG9mIHRoZSB0cmVlIGltcGxpY2l0ZWx5Ci0gICAqIGRlZmluZWQgYnkgdGhlIGNvbnRlbnRzIG9mIGEgSmF2YSBjbGFzcy4gSS5lLiwgdGhlIGhpZXJhcmNoeSBvZiBtZXRob2RzLAotICAgKiBmaWVsZHMsIGF0dHJpYnV0ZXMsIGV0Yy4gc3Bhd25zIGEgdHJlZSBvZiBvYmplY3RzLgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRDb25zdGFudEludGVnZXIodGhpcyk7Ci0gIH0KLQotICAvKioKLSAgICogRHVtcCBjb25zdGFudCBpbnRlZ2VyIHRvIGZpbGUgc3RyZWFtIGluIGJpbmFyeSBmb3JtYXQuCi0gICAqCi0gICAqIEBwYXJhbSBmaWxlIE91dHB1dCBmaWxlIHN0cmVhbQotICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBkdW1wKERhdGFPdXRwdXRTdHJlYW0gZmlsZSkgdGhyb3dzIElPRXhjZXB0aW9uCi0gIHsKLSAgICBmaWxlLndyaXRlQnl0ZSh0YWcpOwotICAgIGZpbGUud3JpdGVJbnQoYnl0ZXMpOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gZGF0YSwgaS5lLiwgNCBieXRlcy4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBpbnQgZ2V0Qnl0ZXMoKSB7IHJldHVybiBieXRlczsgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gYnl0ZXMuCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBzZXRCeXRlcyhpbnQgYnl0ZXMpIHsKLSAgICB0aGlzLmJ5dGVzID0gYnl0ZXM7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBTdHJpbmcgcmVwcmVzZW50YXRpb24uCi0gICAqLwotICBwdWJsaWMgZmluYWwgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgIHJldHVybiBzdXBlci50b1N0cmluZygpICsgIihieXRlcyA9ICIgKyBieXRlcyArICIpIjsKLSAgfQotCi0gIC8qKiBAcmV0dXJuIEludGVnZXIgb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgT2JqZWN0IGdldENvbnN0YW50VmFsdWUoQ29uc3RhbnRQb29sIGNwKSB7Ci0gICAgcmV0dXJuIG5ldyBJbnRlZ2VyKGJ5dGVzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2NsYXNzZmlsZS9Db25zdGFudEludGVyZmFjZU1ldGhvZHJlZi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2NsYXNzZmlsZS9Db25zdGFudEludGVyZmFjZU1ldGhvZHJlZi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0NmI3NDI2Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvQ29uc3RhbnRJbnRlcmZhY2VNZXRob2RyZWYuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEwNyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5jbGFzc2ZpbGU7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHM7Ci1pbXBvcnQgamF2YS5pby4qOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgcmVwcmVzZW50cyBhIGNvbnN0YW50IHBvb2wgcmVmZXJlbmNlIHRvIGFuIGludGVyZmFjZSBtZXRob2QuCi0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIENvbnN0YW50SW50ZXJmYWNlTWV0aG9kcmVmIGV4dGVuZHMgQ29uc3RhbnRDUCB7Ci0gIC8qKgotICAgKiBJbml0aWFsaXplIGZyb20gYW5vdGhlciBvYmplY3QuCi0gICAqLwotICBwdWJsaWMgQ29uc3RhbnRJbnRlcmZhY2VNZXRob2RyZWYoQ29uc3RhbnRJbnRlcmZhY2VNZXRob2RyZWYgYykgewotICAgIHN1cGVyKENvbnN0YW50cy5DT05TVEFOVF9JbnRlcmZhY2VNZXRob2RyZWYsIGMuZ2V0Q2xhc3NJbmRleCgpLCBjLmdldE5hbWVBbmRUeXBlSW5kZXgoKSk7Ci0gIH0KLQotICAvKioKLSAgICogSW5pdGlhbGl6ZSBpbnN0YW5jZSBmcm9tIGZpbGUgZGF0YS4KLSAgICoKLSAgICogQHBhcmFtIGZpbGUgaW5wdXQgc3RyZWFtCi0gICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLSAgICovCi0gIENvbnN0YW50SW50ZXJmYWNlTWV0aG9kcmVmKERhdGFJbnB1dFN0cmVhbSBmaWxlKSB0aHJvd3MgSU9FeGNlcHRpb24KLSAgewotICAgIHN1cGVyKENvbnN0YW50cy5DT05TVEFOVF9JbnRlcmZhY2VNZXRob2RyZWYsIGZpbGUpOwotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBjbGFzc19pbmRleCBSZWZlcmVuY2UgdG8gdGhlIGNsYXNzIGNvbnRhaW5pbmcgdGhlIG1ldGhvZAotICAgKiBAcGFyYW0gbmFtZV9hbmRfdHlwZV9pbmRleCBhbmQgdGhlIG1ldGhvZCBzaWduYXR1cmUKLSAgICovCi0gIHB1YmxpYyBDb25zdGFudEludGVyZmFjZU1ldGhvZHJlZihpbnQgY2xhc3NfaW5kZXgsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbmFtZV9hbmRfdHlwZV9pbmRleCkgewotICAgIHN1cGVyKENvbnN0YW50cy5DT05TVEFOVF9JbnRlcmZhY2VNZXRob2RyZWYsIGNsYXNzX2luZGV4LCBuYW1lX2FuZF90eXBlX2luZGV4KTsKLSAgfQotCi0gIC8qKgotICAgKiBDYWxsZWQgYnkgb2JqZWN0cyB0aGF0IGFyZSB0cmF2ZXJzaW5nIHRoZSBub2RlcyBvZiB0aGUgdHJlZSBpbXBsaWNpdGVseQotICAgKiBkZWZpbmVkIGJ5IHRoZSBjb250ZW50cyBvZiBhIEphdmEgY2xhc3MuIEkuZS4sIHRoZSBoaWVyYXJjaHkgb2YgbWV0aG9kcywKLSAgICogZmllbGRzLCBhdHRyaWJ1dGVzLCBldGMuIHNwYXducyBhIHRyZWUgb2Ygb2JqZWN0cy4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0Q29uc3RhbnRJbnRlcmZhY2VNZXRob2RyZWYodGhpcyk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvQ29uc3RhbnRMb25nLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvY2xhc3NmaWxlL0NvbnN0YW50TG9uZy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlMjlhN2M5Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvQ29uc3RhbnRMb25nLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNDIgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuY2xhc3NmaWxlOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi1pbXBvcnQgIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50czsKLWltcG9ydCAgamF2YS5pby4qOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgaXMgZGVyaXZlZCBmcm9tIHRoZSBhYnN0cmFjdAotICogPEEgSFJFRj0iY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuY2xhc3NmaWxlLkNvbnN0YW50Lmh0bWwiPkNvbnN0YW50PC9BPiBjbGFzcwotICogYW5kIHJlcHJlc2VudHMgYSByZWZlcmVuY2UgdG8gYSBsb25nIG9iamVjdC4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICogQHNlZSAgICAgQ29uc3RhbnQKLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIENvbnN0YW50TG9uZyBleHRlbmRzIENvbnN0YW50IGltcGxlbWVudHMgQ29uc3RhbnRPYmplY3QgewotICBwcml2YXRlIGxvbmcgYnl0ZXM7Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBieXRlcyBEYXRhCi0gICAqLwotICBwdWJsaWMgQ29uc3RhbnRMb25nKGxvbmcgYnl0ZXMpCi0gIHsKLSAgICBzdXBlcihDb25zdGFudHMuQ09OU1RBTlRfTG9uZyk7Ci0gICAgdGhpcy5ieXRlcyA9IGJ5dGVzOwotICB9Ci0gIC8qKgotICAgKiBJbml0aWFsaXplIGZyb20gYW5vdGhlciBvYmplY3QuCi0gICAqLwotICBwdWJsaWMgQ29uc3RhbnRMb25nKENvbnN0YW50TG9uZyBjKSB7Ci0gICAgdGhpcyhjLmdldEJ5dGVzKCkpOwotICB9Ci0gIC8qKgotICAgKiBJbml0aWFsaXplIGluc3RhbmNlIGZyb20gZmlsZSBkYXRhLgotICAgKgotICAgKiBAcGFyYW0gZmlsZSBJbnB1dCBzdHJlYW0KLSAgICogQHRocm93cyBJT0V4Y2VwdGlvbgotICAgKi8KLSAgQ29uc3RhbnRMb25nKERhdGFJbnB1dFN0cmVhbSBmaWxlKSB0aHJvd3MgSU9FeGNlcHRpb24KLSAgewotICAgIHRoaXMoZmlsZS5yZWFkTG9uZygpKTsKLSAgfQotICAvKioKLSAgICogQ2FsbGVkIGJ5IG9iamVjdHMgdGhhdCBhcmUgdHJhdmVyc2luZyB0aGUgbm9kZXMgb2YgdGhlIHRyZWUgaW1wbGljaXRlbHkKLSAgICogZGVmaW5lZCBieSB0aGUgY29udGVudHMgb2YgYSBKYXZhIGNsYXNzLiBJLmUuLCB0aGUgaGllcmFyY2h5IG9mIG1ldGhvZHMsCi0gICAqIGZpZWxkcywgYXR0cmlidXRlcywgZXRjLiBzcGF3bnMgYSB0cmVlIG9mIG9iamVjdHMuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgdi52aXNpdENvbnN0YW50TG9uZyh0aGlzKTsKLSAgfQotICAvKioKLSAgICogRHVtcCBjb25zdGFudCBsb25nIHRvIGZpbGUgc3RyZWFtIGluIGJpbmFyeSBmb3JtYXQuCi0gICAqCi0gICAqIEBwYXJhbSBmaWxlIE91dHB1dCBmaWxlIHN0cmVhbQotICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBkdW1wKERhdGFPdXRwdXRTdHJlYW0gZmlsZSkgdGhyb3dzIElPRXhjZXB0aW9uCi0gIHsKLSAgICBmaWxlLndyaXRlQnl0ZSh0YWcpOwotICAgIGZpbGUud3JpdGVMb25nKGJ5dGVzKTsKLSAgfQotICAvKioKLSAgICogQHJldHVybiBkYXRhLCBpLmUuLCA4IGJ5dGVzLgotICAgKi8KLSAgcHVibGljIGZpbmFsIGxvbmcgZ2V0Qnl0ZXMoKSB7IHJldHVybiBieXRlczsgfQotICAvKioKLSAgICogQHBhcmFtIGJ5dGVzLgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgc2V0Qnl0ZXMobG9uZyBieXRlcykgewotICAgIHRoaXMuYnl0ZXMgPSBieXRlczsKLSAgfQotICAvKioKLSAgICogQHJldHVybiBTdHJpbmcgcmVwcmVzZW50YXRpb24uCi0gICAqLwotICBwdWJsaWMgZmluYWwgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgIHJldHVybiBzdXBlci50b1N0cmluZygpICsgIihieXRlcyA9ICIgKyBieXRlcyArICIpIjsKLSAgfQotCi0gIC8qKiBAcmV0dXJuIExvbmcgb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgT2JqZWN0IGdldENvbnN0YW50VmFsdWUoQ29uc3RhbnRQb29sIGNwKSB7Ci0gICAgcmV0dXJuIG5ldyBMb25nKGJ5dGVzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2NsYXNzZmlsZS9Db25zdGFudE1ldGhvZHJlZi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2NsYXNzZmlsZS9Db25zdGFudE1ldGhvZHJlZi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwNDRjOTliLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvQ29uc3RhbnRNZXRob2RyZWYuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEwNyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5jbGFzc2ZpbGU7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHM7Ci1pbXBvcnQgamF2YS5pby4qOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgcmVwcmVzZW50cyBhIGNvbnN0YW50IHBvb2wgcmVmZXJlbmNlIHRvIGEgbWV0aG9kLgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBDb25zdGFudE1ldGhvZHJlZiBleHRlbmRzIENvbnN0YW50Q1AgewotICAvKioKLSAgICogSW5pdGlhbGl6ZSBmcm9tIGFub3RoZXIgb2JqZWN0LgotICAgKi8KLSAgcHVibGljIENvbnN0YW50TWV0aG9kcmVmKENvbnN0YW50TWV0aG9kcmVmIGMpIHsKLSAgICBzdXBlcihDb25zdGFudHMuQ09OU1RBTlRfTWV0aG9kcmVmLCBjLmdldENsYXNzSW5kZXgoKSwgYy5nZXROYW1lQW5kVHlwZUluZGV4KCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIEluaXRpYWxpemUgaW5zdGFuY2UgZnJvbSBmaWxlIGRhdGEuCi0gICAqCi0gICAqIEBwYXJhbSBmaWxlIGlucHV0IHN0cmVhbQotICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0gICAqLwotICBDb25zdGFudE1ldGhvZHJlZihEYXRhSW5wdXRTdHJlYW0gZmlsZSkgdGhyb3dzIElPRXhjZXB0aW9uCi0gIHsKLSAgICBzdXBlcihDb25zdGFudHMuQ09OU1RBTlRfTWV0aG9kcmVmLCBmaWxlKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gY2xhc3NfaW5kZXggUmVmZXJlbmNlIHRvIHRoZSBjbGFzcyBjb250YWluaW5nIHRoZSBtZXRob2QKLSAgICogQHBhcmFtIG5hbWVfYW5kX3R5cGVfaW5kZXggYW5kIHRoZSBtZXRob2Qgc2lnbmF0dXJlCi0gICAqLwotICBwdWJsaWMgQ29uc3RhbnRNZXRob2RyZWYoaW50IGNsYXNzX2luZGV4LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG5hbWVfYW5kX3R5cGVfaW5kZXgpIHsKLSAgICBzdXBlcihDb25zdGFudHMuQ09OU1RBTlRfTWV0aG9kcmVmLCBjbGFzc19pbmRleCwgbmFtZV9hbmRfdHlwZV9pbmRleCk7Ci0gIH0KLQotICAvKioKLSAgICogQ2FsbGVkIGJ5IG9iamVjdHMgdGhhdCBhcmUgdHJhdmVyc2luZyB0aGUgbm9kZXMgb2YgdGhlIHRyZWUgaW1wbGljaXRlbHkKLSAgICogZGVmaW5lZCBieSB0aGUgY29udGVudHMgb2YgYSBKYXZhIGNsYXNzLiBJLmUuLCB0aGUgaGllcmFyY2h5IG9mIG1ldGhvZHMsCi0gICAqIGZpZWxkcywgYXR0cmlidXRlcywgZXRjLiBzcGF3bnMgYSB0cmVlIG9mIG9iamVjdHMuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgdi52aXNpdENvbnN0YW50TWV0aG9kcmVmKHRoaXMpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvY2xhc3NmaWxlL0NvbnN0YW50TmFtZUFuZFR5cGUuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvQ29uc3RhbnROYW1lQW5kVHlwZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxOWFkNDY4Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvQ29uc3RhbnROYW1lQW5kVHlwZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTc0ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmNsYXNzZmlsZTsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotaW1wb3J0ICBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHM7Ci1pbXBvcnQgIGphdmEuaW8uKjsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGlzIGRlcml2ZWQgZnJvbSB0aGUgYWJzdHJhY3QKLSAqIDxBIEhSRUY9ImNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmNsYXNzZmlsZS5Db25zdGFudC5odG1sIj5Db25zdGFudDwvQT4gY2xhc3MKLSAqIGFuZCByZXByZXNlbnRzIGEgcmVmZXJlbmNlIHRvIHRoZSBuYW1lIGFuZCBzaWduYXR1cmUKLSAqIG9mIGEgZmllbGQgb3IgbWV0aG9kLgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKiBAc2VlICAgICBDb25zdGFudAotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgQ29uc3RhbnROYW1lQW5kVHlwZSBleHRlbmRzIENvbnN0YW50IHsKLSAgcHJpdmF0ZSBpbnQgbmFtZV9pbmRleDsgICAgICAvLyBOYW1lIG9mIGZpZWxkL21ldGhvZAotICBwcml2YXRlIGludCBzaWduYXR1cmVfaW5kZXg7IC8vIGFuZCBpdHMgc2lnbmF0dXJlLgotCi0gIC8qKgotICAgKiBJbml0aWFsaXplIGZyb20gYW5vdGhlciBvYmplY3QuCi0gICAqLwotICBwdWJsaWMgQ29uc3RhbnROYW1lQW5kVHlwZShDb25zdGFudE5hbWVBbmRUeXBlIGMpIHsKLSAgICB0aGlzKGMuZ2V0TmFtZUluZGV4KCksIGMuZ2V0U2lnbmF0dXJlSW5kZXgoKSk7Ci0gIH0KLQotICAvKioKLSAgICogSW5pdGlhbGl6ZSBpbnN0YW5jZSBmcm9tIGZpbGUgZGF0YS4KLSAgICoKLSAgICogQHBhcmFtIGZpbGUgSW5wdXQgc3RyZWFtCi0gICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLSAgICovCi0gIENvbnN0YW50TmFtZUFuZFR5cGUoRGF0YUlucHV0U3RyZWFtIGZpbGUpIHRocm93cyBJT0V4Y2VwdGlvbgotICB7Ci0gICAgdGhpcygoaW50KWZpbGUucmVhZFVuc2lnbmVkU2hvcnQoKSwgKGludClmaWxlLnJlYWRVbnNpZ25lZFNob3J0KCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBuYW1lX2luZGV4IE5hbWUgb2YgZmllbGQvbWV0aG9kCi0gICAqIEBwYXJhbSBzaWduYXR1cmVfaW5kZXggYW5kIGl0cyBzaWduYXR1cmUKLSAgICovCi0gIHB1YmxpYyBDb25zdGFudE5hbWVBbmRUeXBlKGludCBuYW1lX2luZGV4LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgc2lnbmF0dXJlX2luZGV4KQotICB7Ci0gICAgc3VwZXIoQ29uc3RhbnRzLkNPTlNUQU5UX05hbWVBbmRUeXBlKTsKLSAgICB0aGlzLm5hbWVfaW5kZXggICAgICA9IG5hbWVfaW5kZXg7Ci0gICAgdGhpcy5zaWduYXR1cmVfaW5kZXggPSBzaWduYXR1cmVfaW5kZXg7Ci0gIH0KLQotICAvKioKLSAgICogQ2FsbGVkIGJ5IG9iamVjdHMgdGhhdCBhcmUgdHJhdmVyc2luZyB0aGUgbm9kZXMgb2YgdGhlIHRyZWUgaW1wbGljaXRlbHkKLSAgICogZGVmaW5lZCBieSB0aGUgY29udGVudHMgb2YgYSBKYXZhIGNsYXNzLiBJLmUuLCB0aGUgaGllcmFyY2h5IG9mIG1ldGhvZHMsCi0gICAqIGZpZWxkcywgYXR0cmlidXRlcywgZXRjLiBzcGF3bnMgYSB0cmVlIG9mIG9iamVjdHMuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgdi52aXNpdENvbnN0YW50TmFtZUFuZFR5cGUodGhpcyk7Ci0gIH0KLQotICAvKioKLSAgICogRHVtcCBuYW1lIGFuZCBzaWduYXR1cmUgaW5kZXggdG8gZmlsZSBzdHJlYW0gaW4gYmluYXJ5IGZvcm1hdC4KLSAgICoKLSAgICogQHBhcmFtIGZpbGUgT3V0cHV0IGZpbGUgc3RyZWFtCi0gICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIGR1bXAoRGF0YU91dHB1dFN0cmVhbSBmaWxlKSB0aHJvd3MgSU9FeGNlcHRpb24KLSAgewotICAgIGZpbGUud3JpdGVCeXRlKHRhZyk7Ci0gICAgZmlsZS53cml0ZVNob3J0KG5hbWVfaW5kZXgpOwotICAgIGZpbGUud3JpdGVTaG9ydChzaWduYXR1cmVfaW5kZXgpOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gTmFtZSBpbmRleCBpbiBjb25zdGFudCBwb29sIG9mIGZpZWxkL21ldGhvZCBuYW1lLgotICAgKi8KLSAgcHVibGljIGZpbmFsIGludCBnZXROYW1lSW5kZXgoKSAgICAgIHsgcmV0dXJuIG5hbWVfaW5kZXg7IH0KLQotICAvKiogQHJldHVybiBuYW1lCi0gICAqLwotICBwdWJsaWMgZmluYWwgU3RyaW5nIGdldE5hbWUoQ29uc3RhbnRQb29sIGNwKSB7Ci0gICAgcmV0dXJuIGNwLmNvbnN0YW50VG9TdHJpbmcoZ2V0TmFtZUluZGV4KCksIENvbnN0YW50cy5DT05TVEFOVF9VdGY4KTsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIEluZGV4IGluIGNvbnN0YW50IHBvb2wgb2YgZmllbGQvbWV0aG9kIHNpZ25hdHVyZS4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBpbnQgZ2V0U2lnbmF0dXJlSW5kZXgoKSB7IHJldHVybiBzaWduYXR1cmVfaW5kZXg7IH0KLQotICAvKiogQHJldHVybiBzaWduYXR1cmUKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBTdHJpbmcgZ2V0U2lnbmF0dXJlKENvbnN0YW50UG9vbCBjcCkgewotICAgIHJldHVybiBjcC5jb25zdGFudFRvU3RyaW5nKGdldFNpZ25hdHVyZUluZGV4KCksIENvbnN0YW50cy5DT05TVEFOVF9VdGY4KTsKLSAgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gbmFtZV9pbmRleC4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHNldE5hbWVJbmRleChpbnQgbmFtZV9pbmRleCkgewotICAgIHRoaXMubmFtZV9pbmRleCA9IG5hbWVfaW5kZXg7Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIHNpZ25hdHVyZV9pbmRleC4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHNldFNpZ25hdHVyZUluZGV4KGludCBzaWduYXR1cmVfaW5kZXgpIHsKLSAgICB0aGlzLnNpZ25hdHVyZV9pbmRleCA9IHNpZ25hdHVyZV9pbmRleDsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIFN0cmluZyByZXByZXNlbnRhdGlvbgotICAgKi8KLSAgcHVibGljIGZpbmFsIFN0cmluZyB0b1N0cmluZygpIHsKLSAgICByZXR1cm4gc3VwZXIudG9TdHJpbmcoKSArICIobmFtZV9pbmRleCA9ICIgKyBuYW1lX2luZGV4ICsKLSAgICAgICIsIHNpZ25hdHVyZV9pbmRleCA9ICIgKyBzaWduYXR1cmVfaW5kZXggKyAiKSI7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvQ29uc3RhbnRPYmplY3QuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvQ29uc3RhbnRPYmplY3QuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNjE0NDBlNS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvY2xhc3NmaWxlL0NvbnN0YW50T2JqZWN0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3MiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5jbGFzc2ZpbGU7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8qKgotICogVGhpcyBpbnRlcmZhY2UgZGVub3RlcyB0aG9zZSBjb25zdGFudHMgdGhhdCBoYXZlIGEgIm5hdHVyYWwiIHZhbHVlLAotICogc3VjaCBhcyBDb25zdGFudExvbmcsIENvbnN0YW50U3RyaW5nLCBldGMuLgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKiBAc2VlICAgICBDb25zdGFudAotICovCi1wdWJsaWMgaW50ZXJmYWNlIENvbnN0YW50T2JqZWN0IHsKLSAgLyoqIEByZXR1cm4gb2JqZWN0IHJlcHJlc2VudGluZyB0aGUgY29uc3RhbnQsIGUuZy4sIExvbmcgZm9yIENvbnN0YW50TG9uZwotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IE9iamVjdCBnZXRDb25zdGFudFZhbHVlKENvbnN0YW50UG9vbCBjcCk7Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvY2xhc3NmaWxlL0NvbnN0YW50UG9vbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2NsYXNzZmlsZS9Db25zdGFudFBvb2wuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDkxZTcwYy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvY2xhc3NmaWxlL0NvbnN0YW50UG9vbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzc1ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmNsYXNzZmlsZTsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotaW1wb3J0ICBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHM7Ci1pbXBvcnQgIGphdmEuaW8uKjsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIHJlcHJlc2VudHMgdGhlIGNvbnN0YW50IHBvb2wsIGkuZS4sIGEgdGFibGUgb2YgY29uc3RhbnRzLCBvZgotICogYSBwYXJzZWQgY2xhc3NmaWxlLiBJdCBtYXkgY29udGFpbiBudWxsIHJlZmVyZW5jZXMsIGR1ZSB0byB0aGUgSlZNCi0gKiBzcGVjaWZpY2F0aW9uIHRoYXQgc2tpcHMgYW4gZW50cnkgYWZ0ZXIgYW4gOC1ieXRlIGNvbnN0YW50IChkb3VibGUsCi0gKiBsb25nKSBlbnRyeS4gIFRob3NlIGludGVyZXN0ZWQgaW4gZ2VuZXJhdGluZyBjb25zdGFudCBwb29scwotICogcHJvZ3JhbWF0aWNhbGx5IHNob3VsZCBzZWUgPGEgaHJlZj0iLi4vZ2VuZXJpYy9Db25zdGFudFBvb2xHZW4uaHRtbCI+Ci0gKiBDb25zdGFudFBvb2xHZW48L2E+LgotCi0gKiBAc2VlICAgICBDb25zdGFudAotICogQHNlZSAgICAgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5Db25zdGFudFBvb2xHZW4KLSAqIEBhdXRob3IgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGNsYXNzIENvbnN0YW50UG9vbCBpbXBsZW1lbnRzIENsb25lYWJsZSwgTm9kZSwgU2VyaWFsaXphYmxlIHsKLSAgcHJpdmF0ZSBpbnQgICAgICAgIGNvbnN0YW50X3Bvb2xfY291bnQ7Ci0gIHByaXZhdGUgQ29uc3RhbnRbXSBjb25zdGFudF9wb29sOwotCi0gIC8qKgotICAgKiBAcGFyYW0gY29uc3RhbnRfcG9vbCBBcnJheSBvZiBjb25zdGFudHMKLSAgICovCi0gIHB1YmxpYyBDb25zdGFudFBvb2woQ29uc3RhbnRbXSBjb25zdGFudF9wb29sKQotICB7Ci0gICAgc2V0Q29uc3RhbnRQb29sKGNvbnN0YW50X3Bvb2wpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlYWQgY29uc3RhbnRzIGZyb20gZ2l2ZW4gZmlsZSBzdHJlYW0uCi0gICAqCi0gICAqIEBwYXJhbSBmaWxlIElucHV0IHN0cmVhbQotICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0gICAqIEB0aHJvd3MgQ2xhc3NGb3JtYXRFeGNlcHRpb24KLSAgICovCi0gIENvbnN0YW50UG9vbChEYXRhSW5wdXRTdHJlYW0gZmlsZSkgdGhyb3dzIElPRXhjZXB0aW9uLCBDbGFzc0Zvcm1hdEV4Y2VwdGlvbgotICB7Ci0gICAgYnl0ZSB0YWc7Ci0KLSAgICBjb25zdGFudF9wb29sX2NvdW50ID0gZmlsZS5yZWFkVW5zaWduZWRTaG9ydCgpOwotICAgIGNvbnN0YW50X3Bvb2wgICAgICAgPSBuZXcgQ29uc3RhbnRbY29uc3RhbnRfcG9vbF9jb3VudF07Ci0KLSAgICAvKiBjb25zdGFudF9wb29sWzBdIGlzIHVudXNlZCBieSB0aGUgY29tcGlsZXIgYW5kIG1heSBiZSB1c2VkIGZyZWVseQotICAgICAqIGJ5IHRoZSBpbXBsZW1lbnRhdGlvbi4KLSAgICAgKi8KLSAgICBmb3IoaW50IGk9MTsgaSA8IGNvbnN0YW50X3Bvb2xfY291bnQ7IGkrKykgewotICAgICAgY29uc3RhbnRfcG9vbFtpXSA9IENvbnN0YW50LnJlYWRDb25zdGFudChmaWxlKTsKLQotICAgICAgLyogUXVvdGUgZnJvbSB0aGUgSlZNIHNwZWNpZmljYXRpb246Ci0gICAgICAgKiAiQWxsIGVpZ2h0IGJ5dGUgY29uc3RhbnRzIHRha2UgdXAgdHdvIHNwb3RzIGluIHRoZSBjb25zdGFudCBwb29sLgotICAgICAgICogSWYgdGhpcyBpcyB0aGUgbid0aCBieXRlIGluIHRoZSBjb25zdGFudCBwb29sLCB0aGVuIHRoZSBuZXh0IGl0ZW0KLSAgICAgICAqIHdpbGwgYmUgbnVtYmVyZWQgbisyIgotICAgICAgICoKLSAgICAgICAqIFRodXMgd2UgaGF2ZSB0byBpbmNyZW1lbnQgdGhlIGluZGV4IGNvdW50ZXIuCi0gICAgICAgKi8KLSAgICAgIHRhZyA9IGNvbnN0YW50X3Bvb2xbaV0uZ2V0VGFnKCk7Ci0gICAgICBpZigodGFnID09IENvbnN0YW50cy5DT05TVEFOVF9Eb3VibGUpIHx8ICh0YWcgPT0gQ29uc3RhbnRzLkNPTlNUQU5UX0xvbmcpKQotICAgICAgICBpKys7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIENhbGxlZCBieSBvYmplY3RzIHRoYXQgYXJlIHRyYXZlcnNpbmcgdGhlIG5vZGVzIG9mIHRoZSB0cmVlIGltcGxpY2l0ZWx5Ci0gICAqIGRlZmluZWQgYnkgdGhlIGNvbnRlbnRzIG9mIGEgSmF2YSBjbGFzcy4gSS5lLiwgdGhlIGhpZXJhcmNoeSBvZiBtZXRob2RzLAotICAgKiBmaWVsZHMsIGF0dHJpYnV0ZXMsIGV0Yy4gc3Bhd25zIGEgdHJlZSBvZiBvYmplY3RzLgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRDb25zdGFudFBvb2wodGhpcyk7Ci0gIH0KLQotICAvKioKLSAgICogUmVzb2x2ZSBjb25zdGFudCB0byBhIHN0cmluZyByZXByZXNlbnRhdGlvbi4KLSAgICoKLSAgICogQHBhcmFtICBjb25zdGFudCBDb25zdGFudCB0byBiZSBwcmludGVkCi0gICAqIEByZXR1cm4gU3RyaW5nIHJlcHJlc2VudGF0aW9uCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGNvbnN0YW50VG9TdHJpbmcoQ29uc3RhbnQgYykKLSAgICAgICB0aHJvd3MgQ2xhc3NGb3JtYXRFeGNlcHRpb24KLSAgewotICAgIFN0cmluZyAgIHN0cjsKLSAgICBpbnQgICAgICBpOwotICAgIGJ5dGUgICAgIHRhZyA9IGMuZ2V0VGFnKCk7Ci0KLSAgICBzd2l0Y2godGFnKSB7Ci0gICAgY2FzZSBDb25zdGFudHMuQ09OU1RBTlRfQ2xhc3M6Ci0gICAgICBpICAgPSAoKENvbnN0YW50Q2xhc3MpYykuZ2V0TmFtZUluZGV4KCk7Ci0gICAgICBjICAgPSBnZXRDb25zdGFudChpLCBDb25zdGFudHMuQ09OU1RBTlRfVXRmOCk7Ci0gICAgICBzdHIgPSBVdGlsaXR5LmNvbXBhY3RDbGFzc05hbWUoKChDb25zdGFudFV0ZjgpYykuZ2V0Qnl0ZXMoKSwgZmFsc2UpOwotICAgICAgYnJlYWs7Ci0KLSAgICBjYXNlIENvbnN0YW50cy5DT05TVEFOVF9TdHJpbmc6Ci0gICAgICBpICAgPSAoKENvbnN0YW50U3RyaW5nKWMpLmdldFN0cmluZ0luZGV4KCk7Ci0gICAgICBjICAgPSBnZXRDb25zdGFudChpLCBDb25zdGFudHMuQ09OU1RBTlRfVXRmOCk7Ci0gICAgICBzdHIgPSAiXCIiICsgZXNjYXBlKCgoQ29uc3RhbnRVdGY4KWMpLmdldEJ5dGVzKCkpICsgIlwiIjsKLSAgICAgIGJyZWFrOwotCi0gICAgY2FzZSBDb25zdGFudHMuQ09OU1RBTlRfVXRmODogICAgc3RyID0gKChDb25zdGFudFV0ZjgpYykuZ2V0Qnl0ZXMoKTsgICAgICAgICBicmVhazsKLSAgICBjYXNlIENvbnN0YW50cy5DT05TVEFOVF9Eb3VibGU6ICBzdHIgPSAiIiArICgoQ29uc3RhbnREb3VibGUpYykuZ2V0Qnl0ZXMoKTsgIGJyZWFrOwotICAgIGNhc2UgQ29uc3RhbnRzLkNPTlNUQU5UX0Zsb2F0OiAgIHN0ciA9ICIiICsgKChDb25zdGFudEZsb2F0KWMpLmdldEJ5dGVzKCk7ICAgYnJlYWs7Ci0gICAgY2FzZSBDb25zdGFudHMuQ09OU1RBTlRfTG9uZzogICAgc3RyID0gIiIgKyAoKENvbnN0YW50TG9uZyljKS5nZXRCeXRlcygpOyAgICBicmVhazsKLSAgICBjYXNlIENvbnN0YW50cy5DT05TVEFOVF9JbnRlZ2VyOiBzdHIgPSAiIiArICgoQ29uc3RhbnRJbnRlZ2VyKWMpLmdldEJ5dGVzKCk7IGJyZWFrOwotCi0gICAgY2FzZSBDb25zdGFudHMuQ09OU1RBTlRfTmFtZUFuZFR5cGU6Ci0gICAgICBzdHIgPSAoY29uc3RhbnRUb1N0cmluZygoKENvbnN0YW50TmFtZUFuZFR5cGUpYykuZ2V0TmFtZUluZGV4KCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb25zdGFudHMuQ09OU1RBTlRfVXRmOCkgKyAiICIgKwotICAgICAgICAgICAgIGNvbnN0YW50VG9TdHJpbmcoKChDb25zdGFudE5hbWVBbmRUeXBlKWMpLmdldFNpZ25hdHVyZUluZGV4KCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb25zdGFudHMuQ09OU1RBTlRfVXRmOCkpOwotICAgICAgYnJlYWs7Ci0KLSAgICBjYXNlIENvbnN0YW50cy5DT05TVEFOVF9JbnRlcmZhY2VNZXRob2RyZWY6IGNhc2UgQ29uc3RhbnRzLkNPTlNUQU5UX01ldGhvZHJlZjoKLSAgICBjYXNlIENvbnN0YW50cy5DT05TVEFOVF9GaWVsZHJlZjoKLSAgICAgIHN0ciA9IChjb25zdGFudFRvU3RyaW5nKCgoQ29uc3RhbnRDUCljKS5nZXRDbGFzc0luZGV4KCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb25zdGFudHMuQ09OU1RBTlRfQ2xhc3MpICsgIi4iICsKLSAgICAgICAgICAgICBjb25zdGFudFRvU3RyaW5nKCgoQ29uc3RhbnRDUCljKS5nZXROYW1lQW5kVHlwZUluZGV4KCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb25zdGFudHMuQ09OU1RBTlRfTmFtZUFuZFR5cGUpKTsKLSAgICAgIGJyZWFrOwotCi0gICAgZGVmYXVsdDogLy8gTmV2ZXIgcmVhY2hlZAotICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlVua25vd24gY29uc3RhbnQgdHlwZSAiICsgdGFnKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gc3RyOwotICB9Ci0KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIGVzY2FwZShTdHJpbmcgc3RyKSB7Ci0gICAgaW50ICAgICAgICAgIGxlbiA9IHN0ci5sZW5ndGgoKTsKLSAgICBTdHJpbmdCdWZmZXIgYnVmID0gbmV3IFN0cmluZ0J1ZmZlcihsZW4gKyA1KTsKLSAgICBjaGFyW10gICAgICAgY2ggID0gc3RyLnRvQ2hhckFycmF5KCk7Ci0KLSAgICBmb3IoaW50IGk9MDsgaSA8IGxlbjsgaSsrKSB7Ci0gICAgICBzd2l0Y2goY2hbaV0pIHsKLSAgICAgIGNhc2UgJ1xuJyA6IGJ1Zi5hcHBlbmQoIlxcbiIpOyBicmVhazsKLSAgICAgIGNhc2UgJ1xyJyA6IGJ1Zi5hcHBlbmQoIlxcciIpOyBicmVhazsKLSAgICAgIGNhc2UgJ1x0JyA6IGJ1Zi5hcHBlbmQoIlxcdCIpOyBicmVhazsKLSAgICAgIGNhc2UgJ1xiJyA6IGJ1Zi5hcHBlbmQoIlxcYiIpOyBicmVhazsKLSAgICAgIGNhc2UgJyInICA6IGJ1Zi5hcHBlbmQoIlxcXCIiKTsgYnJlYWs7Ci0gICAgICBkZWZhdWx0OiBidWYuYXBwZW5kKGNoW2ldKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gYnVmLnRvU3RyaW5nKCk7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBSZXRyaWV2ZSBjb25zdGFudCBhdCBgaW5kZXgnIGZyb20gY29uc3RhbnQgcG9vbCBhbmQgcmVzb2x2ZSBpdCB0bwotICAgKiBhIHN0cmluZyByZXByZXNlbnRhdGlvbi4KLSAgICoKLSAgICogQHBhcmFtICBpbmRleCBvZiBjb25zdGFudCBpbiBjb25zdGFudCBwb29sCi0gICAqIEBwYXJhbSAgdGFnIGV4cGVjdGVkIHR5cGUKLSAgICogQHJldHVybiBTdHJpbmcgcmVwcmVzZW50YXRpb24KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgY29uc3RhbnRUb1N0cmluZyhpbnQgaW5kZXgsIGJ5dGUgdGFnKQotICAgICAgIHRocm93cyBDbGFzc0Zvcm1hdEV4Y2VwdGlvbgotICB7Ci0gICAgQ29uc3RhbnQgYyA9IGdldENvbnN0YW50KGluZGV4LCB0YWcpOwotICAgIHJldHVybiBjb25zdGFudFRvU3RyaW5nKGMpOwotICB9Ci0KLSAgLyoqCi0gICAqIER1bXAgY29uc3RhbnQgcG9vbCB0byBmaWxlIHN0cmVhbSBpbiBiaW5hcnkgZm9ybWF0LgotICAgKgotICAgKiBAcGFyYW0gZmlsZSBPdXRwdXQgZmlsZSBzdHJlYW0KLSAgICogQHRocm93cyBJT0V4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgZHVtcChEYXRhT3V0cHV0U3RyZWFtIGZpbGUpIHRocm93cyBJT0V4Y2VwdGlvbgotICB7Ci0gICAgZmlsZS53cml0ZVNob3J0KGNvbnN0YW50X3Bvb2xfY291bnQpOwotCi0gICAgZm9yKGludCBpPTE7IGkgPCBjb25zdGFudF9wb29sX2NvdW50OyBpKyspCi0gICAgICBpZihjb25zdGFudF9wb29sW2ldICE9IG51bGwpCi0gICAgICAgIGNvbnN0YW50X3Bvb2xbaV0uZHVtcChmaWxlKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgY29uc3RhbnQgZnJvbSBjb25zdGFudCBwb29sLgotICAgKgotICAgKiBAcGFyYW0gIGluZGV4IEluZGV4IGluIGNvbnN0YW50IHBvb2wKLSAgICogQHJldHVybiBDb25zdGFudCB2YWx1ZQotICAgKiBAc2VlICAgIENvbnN0YW50Ci0gICAqLwotICBwdWJsaWMgQ29uc3RhbnQgZ2V0Q29uc3RhbnQoaW50IGluZGV4KSB7Ci0gICAgaWYgKGluZGV4ID49IGNvbnN0YW50X3Bvb2wubGVuZ3RoIHx8IGluZGV4IDwgMCkKLSAgICAgIHRocm93IG5ldyBDbGFzc0Zvcm1hdEV4Y2VwdGlvbigiSW52YWxpZCBjb25zdGFudCBwb29sIHJlZmVyZW5jZTogIiArCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmRleCArICIuIENvbnN0YW50IHBvb2wgc2l6ZSBpczogIiArCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdGFudF9wb29sLmxlbmd0aCk7Ci0gICAgcmV0dXJuIGNvbnN0YW50X3Bvb2xbaW5kZXhdOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBjb25zdGFudCBmcm9tIGNvbnN0YW50IHBvb2wgYW5kIGNoZWNrIHdoZXRoZXIgaXQgaGFzIHRoZQotICAgKiBleHBlY3RlZCB0eXBlLgotICAgKgotICAgKiBAcGFyYW0gIGluZGV4IEluZGV4IGluIGNvbnN0YW50IHBvb2wKLSAgICogQHBhcmFtICB0YWcgVGFnIG9mIGV4cGVjdGVkIGNvbnN0YW50LCBpLmUuLCBpdHMgdHlwZQotICAgKiBAcmV0dXJuIENvbnN0YW50IHZhbHVlCi0gICAqIEBzZWUgICAgQ29uc3RhbnQKLSAgICogQHRocm93cyAgQ2xhc3NGb3JtYXRFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBDb25zdGFudCBnZXRDb25zdGFudChpbnQgaW5kZXgsIGJ5dGUgdGFnKQotICAgICAgIHRocm93cyBDbGFzc0Zvcm1hdEV4Y2VwdGlvbgotICB7Ci0gICAgQ29uc3RhbnQgYzsKLQotICAgIGMgPSBnZXRDb25zdGFudChpbmRleCk7Ci0KLSAgICBpZihjID09IG51bGwpCi0gICAgICB0aHJvdyBuZXcgQ2xhc3NGb3JtYXRFeGNlcHRpb24oIkNvbnN0YW50IHBvb2wgYXQgaW5kZXggIiArIGluZGV4ICsgIiBpcyBudWxsLiIpOwotCi0gICAgaWYoYy5nZXRUYWcoKSA9PSB0YWcpCi0gICAgICByZXR1cm4gYzsKLSAgICBlbHNlCi0gICAgICB0aHJvdyBuZXcgQ2xhc3NGb3JtYXRFeGNlcHRpb24oIkV4cGVjdGVkIGNsYXNzIGAiICsgQ29uc3RhbnRzLkNPTlNUQU5UX05BTUVTW3RhZ10gKwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIicgYXQgaW5kZXggIiArIGluZGV4ICsgIiBhbmQgZ290ICIgKyBjKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIEFycmF5IG9mIGNvbnN0YW50cy4KLSAgICogQHNlZSAgICBDb25zdGFudAotICAgKi8KLSAgcHVibGljIENvbnN0YW50W10gZ2V0Q29uc3RhbnRQb29sKCkgeyByZXR1cm4gY29uc3RhbnRfcG9vbDsgIH0KLSAgLyoqCi0gICAqIEdldCBzdHJpbmcgZnJvbSBjb25zdGFudCBwb29sIGFuZCBieXBhc3MgdGhlIGluZGlyZWN0aW9uIG9mCi0gICAqIGBDb25zdGFudENsYXNzJyBhbmQgYENvbnN0YW50U3RyaW5nJyBvYmplY3RzLiBJLmUuIHRoZXNlIGNsYXNzZXMgaGF2ZQotICAgKiBhbiBpbmRleCBmaWVsZCB0aGF0IHBvaW50cyB0byBhbm90aGVyIGVudHJ5IG9mIHRoZSBjb25zdGFudCBwb29sIG9mCi0gICAqIHR5cGUgYENvbnN0YW50VXRmOCcgd2hpY2ggY29udGFpbnMgdGhlIHJlYWwgZGF0YS4KLSAgICoKLSAgICogQHBhcmFtICBpbmRleCBJbmRleCBpbiBjb25zdGFudCBwb29sCi0gICAqIEBwYXJhbSAgdGFnIFRhZyBvZiBleHBlY3RlZCBjb25zdGFudCwgZWl0aGVyIENvbnN0YW50Q2xhc3Mgb3IgQ29uc3RhbnRTdHJpbmcKLSAgICogQHJldHVybiBDb250ZW50cyBvZiBzdHJpbmcgcmVmZXJlbmNlCi0gICAqIEBzZWUgICAgQ29uc3RhbnRDbGFzcwotICAgKiBAc2VlICAgIENvbnN0YW50U3RyaW5nCi0gICAqIEB0aHJvd3MgIENsYXNzRm9ybWF0RXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldENvbnN0YW50U3RyaW5nKGludCBpbmRleCwgYnl0ZSB0YWcpCi0gICAgICAgdGhyb3dzIENsYXNzRm9ybWF0RXhjZXB0aW9uCi0gIHsKLSAgICBDb25zdGFudCBjOwotICAgIGludCAgICBpOwotCi0gICAgYyA9IGdldENvbnN0YW50KGluZGV4LCB0YWcpOwotCi0gICAgLyogVGhpcyBzd2l0Y2goKSBpcyBub3QgdGhhdCBlbGVnYW50LCBzaW5jZSB0aGUgdHdvIGNsYXNzZXMgaGF2ZSB0aGUKLSAgICAgKiBzYW1lIGNvbnRlbnRzLCB0aGV5IGp1c3QgZGlmZmVyIGluIHRoZSBuYW1lIG9mIHRoZSBpbmRleAotICAgICAqIGZpZWxkIHZhcmlhYmxlLgotICAgICAqIEJ1dCB3ZSB3YW50IHRvIHN0aWNrIHRvIHRoZSBKVk0gbmFtaW5nIGNvbnZlbnRpb25zIGNsb3NlbHkgdGhvdWdoCi0gICAgICogd2UgY291bGQgaGF2ZSBzb2x2ZWQgdGhlc2UgbW9yZSBlbGVnYW50bHkgYnkgdXNpbmcgdGhlIHNhbWUKLSAgICAgKiB2YXJpYWJsZSBuYW1lIG9yIGJ5IHN1YmNsYXNzaW5nLgotICAgICAqLwotICAgIHN3aXRjaCh0YWcpIHsKLSAgICBjYXNlIENvbnN0YW50cy5DT05TVEFOVF9DbGFzczogIGkgPSAoKENvbnN0YW50Q2xhc3MpYykuZ2V0TmFtZUluZGV4KCk7ICAgIGJyZWFrOwotICAgIGNhc2UgQ29uc3RhbnRzLkNPTlNUQU5UX1N0cmluZzogaSA9ICgoQ29uc3RhbnRTdHJpbmcpYykuZ2V0U3RyaW5nSW5kZXgoKTsgYnJlYWs7Ci0gICAgZGVmYXVsdDoKLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJnZXRDb25zdGFudFN0cmluZyBjYWxsZWQgd2l0aCBpbGxlZ2FsIHRhZyAiICsgdGFnKTsKLSAgICB9Ci0KLSAgICAvLyBGaW5hbGx5IGdldCB0aGUgc3RyaW5nIGZyb20gdGhlIGNvbnN0YW50IHBvb2wKLSAgICBjID0gZ2V0Q29uc3RhbnQoaSwgQ29uc3RhbnRzLkNPTlNUQU5UX1V0ZjgpOwotICAgIHJldHVybiAoKENvbnN0YW50VXRmOCljKS5nZXRCeXRlcygpOwotICB9Ci0gIC8qKgotICAgKiBAcmV0dXJuIExlbmd0aCBvZiBjb25zdGFudCBwb29sLgotICAgKi8KLSAgcHVibGljIGludCBnZXRMZW5ndGgoKQotICB7Ci0gICAgcmV0dXJuIGNvbnN0YW50X3Bvb2xfY291bnQ7Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIGNvbnN0YW50IENvbnN0YW50IHRvIHNldAotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0Q29uc3RhbnQoaW50IGluZGV4LCBDb25zdGFudCBjb25zdGFudCkgewotICAgIGNvbnN0YW50X3Bvb2xbaW5kZXhdID0gY29uc3RhbnQ7Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIGNvbnN0YW50X3Bvb2wKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldENvbnN0YW50UG9vbChDb25zdGFudFtdIGNvbnN0YW50X3Bvb2wpIHsKLSAgICB0aGlzLmNvbnN0YW50X3Bvb2wgPSBjb25zdGFudF9wb29sOwotICAgIGNvbnN0YW50X3Bvb2xfY291bnQgPSAoY29uc3RhbnRfcG9vbCA9PSBudWxsKT8gMCA6IGNvbnN0YW50X3Bvb2wubGVuZ3RoOwotICB9Ci0gIC8qKgotICAgKiBAcmV0dXJuIFN0cmluZyByZXByZXNlbnRhdGlvbi4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0gICAgU3RyaW5nQnVmZmVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLQotICAgIGZvcihpbnQgaT0xOyBpIDwgY29uc3RhbnRfcG9vbF9jb3VudDsgaSsrKQotICAgICAgYnVmLmFwcGVuZChpICsgIikiICsgY29uc3RhbnRfcG9vbFtpXSArICJcbiIpOwotCi0gICAgcmV0dXJuIGJ1Zi50b1N0cmluZygpOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gZGVlcCBjb3B5IG9mIHRoaXMgY29uc3RhbnQgcG9vbAotICAgKi8KLSAgcHVibGljIENvbnN0YW50UG9vbCBjb3B5KCkgewotICAgIENvbnN0YW50UG9vbCBjID0gbnVsbDsKLQotICAgIHRyeSB7Ci0gICAgICBjID0gKENvbnN0YW50UG9vbCljbG9uZSgpOwotICAgIH0gY2F0Y2goQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gZSkge30KLQotICAgIGMuY29uc3RhbnRfcG9vbCA9IG5ldyBDb25zdGFudFtjb25zdGFudF9wb29sX2NvdW50XTsKLQotICAgIGZvcihpbnQgaT0xOyBpIDwgY29uc3RhbnRfcG9vbF9jb3VudDsgaSsrKSB7Ci0gICAgICBpZihjb25zdGFudF9wb29sW2ldICE9IG51bGwpCi0gICAgICAgIGMuY29uc3RhbnRfcG9vbFtpXSA9IGNvbnN0YW50X3Bvb2xbaV0uY29weSgpOwotICAgIH0KLQotICAgIHJldHVybiBjOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvY2xhc3NmaWxlL0NvbnN0YW50U3RyaW5nLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvY2xhc3NmaWxlL0NvbnN0YW50U3RyaW5nLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDQwZWE1MjkuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2NsYXNzZmlsZS9Db25zdGFudFN0cmluZy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTUwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmNsYXNzZmlsZTsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotaW1wb3J0ICBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHM7Ci1pbXBvcnQgIGphdmEuaW8uKjsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGlzIGRlcml2ZWQgZnJvbSB0aGUgYWJzdHJhY3QKLSAqIDxBIEhSRUY9ImNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmNsYXNzZmlsZS5Db25zdGFudC5odG1sIj5Db25zdGFudDwvQT4gY2xhc3MKLSAqIGFuZCByZXByZXNlbnRzIGEgcmVmZXJlbmNlIHRvIGEgU3RyaW5nIG9iamVjdC4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICogQHNlZSAgICAgQ29uc3RhbnQKLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIENvbnN0YW50U3RyaW5nIGV4dGVuZHMgQ29uc3RhbnQgaW1wbGVtZW50cyBDb25zdGFudE9iamVjdCB7Ci0gIHByaXZhdGUgaW50IHN0cmluZ19pbmRleDsgLy8gSWRlbnRpY2FsIHRvIENvbnN0YW50Q2xhc3MgZXhjZXB0IGZvciB0aGlzIG5hbWUKLQotICAvKioKLSAgICogSW5pdGlhbGl6ZSBmcm9tIGFub3RoZXIgb2JqZWN0LgotICAgKi8KLSAgcHVibGljIENvbnN0YW50U3RyaW5nKENvbnN0YW50U3RyaW5nIGMpIHsKLSAgICB0aGlzKGMuZ2V0U3RyaW5nSW5kZXgoKSk7Ci0gIH0KLSAgLyoqCi0gICAqIEluaXRpYWxpemUgaW5zdGFuY2UgZnJvbSBmaWxlIGRhdGEuCi0gICAqCi0gICAqIEBwYXJhbSBmaWxlIElucHV0IHN0cmVhbQotICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0gICAqLwotICBDb25zdGFudFN0cmluZyhEYXRhSW5wdXRTdHJlYW0gZmlsZSkgdGhyb3dzIElPRXhjZXB0aW9uCi0gIHsKLSAgICB0aGlzKChpbnQpZmlsZS5yZWFkVW5zaWduZWRTaG9ydCgpKTsKLSAgfQotICAvKioKLSAgICogQHBhcmFtIHN0cmluZ19pbmRleCBJbmRleCBvZiBDb25zdGFudF9VdGY4IGluIGNvbnN0YW50IHBvb2wKLSAgICovCi0gIHB1YmxpYyBDb25zdGFudFN0cmluZyhpbnQgc3RyaW5nX2luZGV4KQotICB7Ci0gICAgc3VwZXIoQ29uc3RhbnRzLkNPTlNUQU5UX1N0cmluZyk7Ci0gICAgdGhpcy5zdHJpbmdfaW5kZXggPSBzdHJpbmdfaW5kZXg7Ci0gIH0KLSAgLyoqCi0gICAqIENhbGxlZCBieSBvYmplY3RzIHRoYXQgYXJlIHRyYXZlcnNpbmcgdGhlIG5vZGVzIG9mIHRoZSB0cmVlIGltcGxpY2l0ZWx5Ci0gICAqIGRlZmluZWQgYnkgdGhlIGNvbnRlbnRzIG9mIGEgSmF2YSBjbGFzcy4gSS5lLiwgdGhlIGhpZXJhcmNoeSBvZiBtZXRob2RzLAotICAgKiBmaWVsZHMsIGF0dHJpYnV0ZXMsIGV0Yy4gc3Bhd25zIGEgdHJlZSBvZiBvYmplY3RzLgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRDb25zdGFudFN0cmluZyh0aGlzKTsKLSAgfQotICAvKioKLSAgICogRHVtcCBjb25zdGFudCBmaWVsZCByZWZlcmVuY2UgdG8gZmlsZSBzdHJlYW0gaW4gYmluYXJ5IGZvcm1hdC4KLSAgICoKLSAgICogQHBhcmFtIGZpbGUgT3V0cHV0IGZpbGUgc3RyZWFtCi0gICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIGR1bXAoRGF0YU91dHB1dFN0cmVhbSBmaWxlKSB0aHJvd3MgSU9FeGNlcHRpb24KLSAgewotICAgIGZpbGUud3JpdGVCeXRlKHRhZyk7Ci0gICAgZmlsZS53cml0ZVNob3J0KHN0cmluZ19pbmRleCk7Ci0gIH0KLSAgLyoqCi0gICAqIEByZXR1cm4gSW5kZXggaW4gY29uc3RhbnQgcG9vbCBvZiB0aGUgc3RyaW5nIChDb25zdGFudFV0ZjgpLgotICAgKi8KLSAgcHVibGljIGZpbmFsIGludCBnZXRTdHJpbmdJbmRleCgpIHsgcmV0dXJuIHN0cmluZ19pbmRleDsgfQotICAvKioKLSAgICogQHBhcmFtIHN0cmluZ19pbmRleC4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHNldFN0cmluZ0luZGV4KGludCBzdHJpbmdfaW5kZXgpIHsKLSAgICB0aGlzLnN0cmluZ19pbmRleCA9IHN0cmluZ19pbmRleDsKLSAgfQotICAvKioKLSAgICogQHJldHVybiBTdHJpbmcgcmVwcmVzZW50YXRpb24uCi0gICAqLwotICBwdWJsaWMgZmluYWwgU3RyaW5nIHRvU3RyaW5nKCkKLSAgewotICAgIHJldHVybiBzdXBlci50b1N0cmluZygpICsgIihzdHJpbmdfaW5kZXggPSAiICsgc3RyaW5nX2luZGV4ICsgIikiOwotICB9Ci0KLSAgLyoqIEByZXR1cm4gU3RyaW5nIG9iamVjdAotICAgKi8KLSAgcHVibGljIE9iamVjdCBnZXRDb25zdGFudFZhbHVlKENvbnN0YW50UG9vbCBjcCkgewotICAgIENvbnN0YW50IGMgPSBjcC5nZXRDb25zdGFudChzdHJpbmdfaW5kZXgsIENvbnN0YW50cy5DT05TVEFOVF9VdGY4KTsKLSAgICByZXR1cm4gKChDb25zdGFudFV0ZjgpYykuZ2V0Qnl0ZXMoKTsKLSAgfQotCi0gIC8qKiBAcmV0dXJuIGRlcmVmZXJlbmNlZCBzdHJpbmcKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0Qnl0ZXMoQ29uc3RhbnRQb29sIGNwKSB7Ci0gICAgcmV0dXJuIChTdHJpbmcpZ2V0Q29uc3RhbnRWYWx1ZShjcCk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvQ29uc3RhbnRVdGY4LmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvY2xhc3NmaWxlL0NvbnN0YW50VXRmOC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzMmU5NTU1Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvQ29uc3RhbnRVdGY4LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNTAgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuY2xhc3NmaWxlOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi1pbXBvcnQgIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50czsKLWltcG9ydCAgamF2YS5pby4qOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgaXMgZGVyaXZlZCBmcm9tIHRoZSBhYnN0cmFjdAotICogPEEgSFJFRj0iY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuY2xhc3NmaWxlLkNvbnN0YW50Lmh0bWwiPkNvbnN0YW50PC9BPiBjbGFzcwotICogYW5kIHJlcHJlc2VudHMgYSByZWZlcmVuY2UgdG8gYSBVdGY4IGVuY29kZWQgc3RyaW5nLgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKiBAc2VlICAgICBDb25zdGFudAotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgQ29uc3RhbnRVdGY4IGV4dGVuZHMgQ29uc3RhbnQgewotICBwcml2YXRlIFN0cmluZyBieXRlczsKLQotICAvKioKLSAgICogSW5pdGlhbGl6ZSBmcm9tIGFub3RoZXIgb2JqZWN0LgotICAgKi8KLSAgcHVibGljIENvbnN0YW50VXRmOChDb25zdGFudFV0ZjggYykgewotICAgIHRoaXMoYy5nZXRCeXRlcygpKTsKLSAgfQotCi0gIC8qKgotICAgKiBJbml0aWFsaXplIGluc3RhbmNlIGZyb20gZmlsZSBkYXRhLgotICAgKgotICAgKiBAcGFyYW0gZmlsZSBJbnB1dCBzdHJlYW0KLSAgICogQHRocm93cyBJT0V4Y2VwdGlvbgotICAgKi8KLSAgQ29uc3RhbnRVdGY4KERhdGFJbnB1dFN0cmVhbSBmaWxlKSB0aHJvd3MgSU9FeGNlcHRpb24KLSAgewotICAgIHN1cGVyKENvbnN0YW50cy5DT05TVEFOVF9VdGY4KTsKLQotICAgIGJ5dGVzID0gZmlsZS5yZWFkVVRGKCk7Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIGJ5dGVzIERhdGEKLSAgICovCi0gIHB1YmxpYyBDb25zdGFudFV0ZjgoU3RyaW5nIGJ5dGVzKQotICB7Ci0gICAgc3VwZXIoQ29uc3RhbnRzLkNPTlNUQU5UX1V0ZjgpOwotCi0gICAgaWYoYnl0ZXMgPT0gbnVsbCkKLSAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oImJ5dGVzIG11c3Qgbm90IGJlIG51bGwhIik7Ci0KLSAgICB0aGlzLmJ5dGVzICA9IGJ5dGVzOwotICB9Ci0KLSAgLyoqCi0gICAqIENhbGxlZCBieSBvYmplY3RzIHRoYXQgYXJlIHRyYXZlcnNpbmcgdGhlIG5vZGVzIG9mIHRoZSB0cmVlIGltcGxpY2l0ZWx5Ci0gICAqIGRlZmluZWQgYnkgdGhlIGNvbnRlbnRzIG9mIGEgSmF2YSBjbGFzcy4gSS5lLiwgdGhlIGhpZXJhcmNoeSBvZiBtZXRob2RzLAotICAgKiBmaWVsZHMsIGF0dHJpYnV0ZXMsIGV0Yy4gc3Bhd25zIGEgdHJlZSBvZiBvYmplY3RzLgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRDb25zdGFudFV0ZjgodGhpcyk7Ci0gIH0KLQotICAvKioKLSAgICogRHVtcCBTdHJpbmcgaW4gVXRmOCBmb3JtYXQgdG8gZmlsZSBzdHJlYW0uCi0gICAqCi0gICAqIEBwYXJhbSBmaWxlIE91dHB1dCBmaWxlIHN0cmVhbQotICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBkdW1wKERhdGFPdXRwdXRTdHJlYW0gZmlsZSkgdGhyb3dzIElPRXhjZXB0aW9uCi0gIHsKLSAgICBmaWxlLndyaXRlQnl0ZSh0YWcpOwotICAgIGZpbGUud3JpdGVVVEYoYnl0ZXMpOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gRGF0YSBjb252ZXJ0ZWQgdG8gc3RyaW5nLgotICAgKi8KLSAgcHVibGljIGZpbmFsIFN0cmluZyBnZXRCeXRlcygpIHsgcmV0dXJuIGJ5dGVzOyB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBieXRlcy4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHNldEJ5dGVzKFN0cmluZyBieXRlcykgewotICAgIHRoaXMuYnl0ZXMgPSBieXRlczsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIFN0cmluZyByZXByZXNlbnRhdGlvbgotICAgKi8KLSAgcHVibGljIGZpbmFsIFN0cmluZyB0b1N0cmluZygpCi0gIHsKLSAgICByZXR1cm4gc3VwZXIudG9TdHJpbmcoKSArICIoXCIiICsgVXRpbGl0eS5yZXBsYWNlKGJ5dGVzLCAiXG4iLCAiXFxuIikgKyAiXCIpIjsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2NsYXNzZmlsZS9Db25zdGFudFZhbHVlLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvY2xhc3NmaWxlL0NvbnN0YW50VmFsdWUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZTE2ZDQ3Yi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvY2xhc3NmaWxlL0NvbnN0YW50VmFsdWUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE4MSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5jbGFzc2ZpbGU7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLWltcG9ydCAgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzOwotaW1wb3J0ICBqYXZhLmlvLio7Ci0KLS8qKgotICogVGhpcyBjbGFzcyBpcyBkZXJpdmVkIGZyb20gPGVtPkF0dHJpYnV0ZTwvZW0+IGFuZCByZXByZXNlbnRzIGEgY29uc3RhbnQKLSAqIHZhbHVlLCBpLmUuLCBhIGRlZmF1bHQgdmFsdWUgZm9yIGluaXRpYWxpemluZyBhIGNsYXNzIGZpZWxkLgotICogVGhpcyBjbGFzcyBpcyBpbnN0YW50aWF0ZWQgYnkgdGhlIDxlbT5BdHRyaWJ1dGUucmVhZEF0dHJpYnV0ZSgpPC9lbT4gbWV0aG9kLgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKiBAc2VlICAgICBBdHRyaWJ1dGUKLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIENvbnN0YW50VmFsdWUgZXh0ZW5kcyBBdHRyaWJ1dGUgewotICBwcml2YXRlIGludCBjb25zdGFudHZhbHVlX2luZGV4OwotCi0gIC8qKgotICAgKiBJbml0aWFsaXplIGZyb20gYW5vdGhlciBvYmplY3QuIE5vdGUgdGhhdCBib3RoIG9iamVjdHMgdXNlIHRoZSBzYW1lCi0gICAqIHJlZmVyZW5jZXMgKHNoYWxsb3cgY29weSkuIFVzZSBjbG9uZSgpIGZvciBhIHBoeXNpY2FsIGNvcHkuCi0gICAqLwotICBwdWJsaWMgQ29uc3RhbnRWYWx1ZShDb25zdGFudFZhbHVlIGMpIHsKLSAgICB0aGlzKGMuZ2V0TmFtZUluZGV4KCksIGMuZ2V0TGVuZ3RoKCksIGMuZ2V0Q29uc3RhbnRWYWx1ZUluZGV4KCksCi0gICAgICAgICBjLmdldENvbnN0YW50UG9vbCgpKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3Qgb2JqZWN0IGZyb20gZmlsZSBzdHJlYW0uCi0gICAqIEBwYXJhbSBuYW1lX2luZGV4IE5hbWUgaW5kZXggaW4gY29uc3RhbnQgcG9vbAotICAgKiBAcGFyYW0gbGVuZ3RoIENvbnRlbnQgbGVuZ3RoIGluIGJ5dGVzCi0gICAqIEBwYXJhbSBmaWxlIElucHV0IHN0cmVhbQotICAgKiBAcGFyYW0gY29uc3RhbnRfcG9vbCBBcnJheSBvZiBjb25zdGFudHMKLSAgICogQHRocm93IElPRXhjZXB0aW9uCi0gICAqLwotICBDb25zdGFudFZhbHVlKGludCBuYW1lX2luZGV4LCBpbnQgbGVuZ3RoLCBEYXRhSW5wdXRTdHJlYW0gZmlsZSwKLSAgICAgICAgICAgICAgICBDb25zdGFudFBvb2wgY29uc3RhbnRfcG9vbCkgdGhyb3dzIElPRXhjZXB0aW9uCi0gIHsKLSAgICB0aGlzKG5hbWVfaW5kZXgsIGxlbmd0aCwgKGludClmaWxlLnJlYWRVbnNpZ25lZFNob3J0KCksIGNvbnN0YW50X3Bvb2wpOwotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBuYW1lX2luZGV4IE5hbWUgaW5kZXggaW4gY29uc3RhbnQgcG9vbAotICAgKiBAcGFyYW0gbGVuZ3RoIENvbnRlbnQgbGVuZ3RoIGluIGJ5dGVzCi0gICAqIEBwYXJhbSBjb25zdGFudHZhbHVlX2luZGV4IEluZGV4IGluIGNvbnN0YW50IHBvb2wKLSAgICogQHBhcmFtIGNvbnN0YW50X3Bvb2wgQXJyYXkgb2YgY29uc3RhbnRzCi0gICAqLwotICBwdWJsaWMgQ29uc3RhbnRWYWx1ZShpbnQgbmFtZV9pbmRleCwgaW50IGxlbmd0aCwKLSAgICAgICAgICAgICAgICAgICAgICAgaW50IGNvbnN0YW50dmFsdWVfaW5kZXgsCi0gICAgICAgICAgICAgICAgICAgICAgIENvbnN0YW50UG9vbCBjb25zdGFudF9wb29sKQotICB7Ci0gICAgc3VwZXIoQ29uc3RhbnRzLkFUVFJfQ09OU1RBTlRfVkFMVUUsIG5hbWVfaW5kZXgsIGxlbmd0aCwgY29uc3RhbnRfcG9vbCk7Ci0gICAgdGhpcy5jb25zdGFudHZhbHVlX2luZGV4ID0gY29uc3RhbnR2YWx1ZV9pbmRleDsKLSAgfQotCi0gIC8qKgotICAgKiBDYWxsZWQgYnkgb2JqZWN0cyB0aGF0IGFyZSB0cmF2ZXJzaW5nIHRoZSBub2RlcyBvZiB0aGUgdHJlZSBpbXBsaWNpdGVseQotICAgKiBkZWZpbmVkIGJ5IHRoZSBjb250ZW50cyBvZiBhIEphdmEgY2xhc3MuIEkuZS4sIHRoZSBoaWVyYXJjaHkgb2YgbWV0aG9kcywKLSAgICogZmllbGRzLCBhdHRyaWJ1dGVzLCBldGMuIHNwYXducyBhIHRyZWUgb2Ygb2JqZWN0cy4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0Q29uc3RhbnRWYWx1ZSh0aGlzKTsKLSAgfQotICAvKioKLSAgICogRHVtcCBjb25zdGFudCB2YWx1ZSBhdHRyaWJ1dGUgdG8gZmlsZSBzdHJlYW0gb24gYmluYXJ5IGZvcm1hdC4KLSAgICoKLSAgICogQHBhcmFtIGZpbGUgT3V0cHV0IGZpbGUgc3RyZWFtCi0gICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIGR1bXAoRGF0YU91dHB1dFN0cmVhbSBmaWxlKSB0aHJvd3MgSU9FeGNlcHRpb24KLSAgewotICAgIHN1cGVyLmR1bXAoZmlsZSk7Ci0gICAgZmlsZS53cml0ZVNob3J0KGNvbnN0YW50dmFsdWVfaW5kZXgpOwotICB9Ci0gIC8qKgotICAgKiBAcmV0dXJuIEluZGV4IGluIGNvbnN0YW50IHBvb2wgb2YgY29uc3RhbnQgdmFsdWUuCi0gICAqLwotICBwdWJsaWMgZmluYWwgaW50IGdldENvbnN0YW50VmFsdWVJbmRleCgpIHsgcmV0dXJuIGNvbnN0YW50dmFsdWVfaW5kZXg7IH0KLQotICAvKioKLSAgICogQHBhcmFtIGNvbnN0YW50dmFsdWVfaW5kZXguCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBzZXRDb25zdGFudFZhbHVlSW5kZXgoaW50IGNvbnN0YW50dmFsdWVfaW5kZXgpIHsKLSAgICB0aGlzLmNvbnN0YW50dmFsdWVfaW5kZXggPSBjb25zdGFudHZhbHVlX2luZGV4OwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gU3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIGNvbnN0YW50IHZhbHVlLgotICAgKi8KLSAgcHVibGljIGZpbmFsIFN0cmluZyB0b1N0cmluZygpIHsKLSAgICBDb25zdGFudCBjID0gY29uc3RhbnRfcG9vbC5nZXRDb25zdGFudChjb25zdGFudHZhbHVlX2luZGV4KTsKLQotICAgIFN0cmluZyAgIGJ1ZjsKLSAgICBpbnQgICAgaTsKLQotICAgIC8vIFByaW50IGNvbnN0YW50IHRvIHN0cmluZyBkZXBlbmRpbmcgb24gaXRzIHR5cGUKLSAgICBzd2l0Y2goYy5nZXRUYWcoKSkgewotICAgIGNhc2UgQ29uc3RhbnRzLkNPTlNUQU5UX0xvbmc6ICAgIGJ1ZiA9ICIiICsgKChDb25zdGFudExvbmcpYykuZ2V0Qnl0ZXMoKTsgICAgYnJlYWs7Ci0gICAgY2FzZSBDb25zdGFudHMuQ09OU1RBTlRfRmxvYXQ6ICAgYnVmID0gIiIgKyAoKENvbnN0YW50RmxvYXQpYykuZ2V0Qnl0ZXMoKTsgICBicmVhazsKLSAgICBjYXNlIENvbnN0YW50cy5DT05TVEFOVF9Eb3VibGU6ICBidWYgPSAiIiArICgoQ29uc3RhbnREb3VibGUpYykuZ2V0Qnl0ZXMoKTsgIGJyZWFrOwotICAgIGNhc2UgQ29uc3RhbnRzLkNPTlNUQU5UX0ludGVnZXI6IGJ1ZiA9ICIiICsgKChDb25zdGFudEludGVnZXIpYykuZ2V0Qnl0ZXMoKTsgYnJlYWs7Ci0gICAgY2FzZSBDb25zdGFudHMuQ09OU1RBTlRfU3RyaW5nOgotICAgICAgaSAgID0gKChDb25zdGFudFN0cmluZyljKS5nZXRTdHJpbmdJbmRleCgpOwotICAgICAgYyAgID0gY29uc3RhbnRfcG9vbC5nZXRDb25zdGFudChpLCBDb25zdGFudHMuQ09OU1RBTlRfVXRmOCk7Ci0gICAgICBidWYgPSAiXCIiICsgVXRpbGl0eS5jb252ZXJ0U3RyaW5nKCgoQ29uc3RhbnRVdGY4KWMpLmdldEJ5dGVzKCkpICsgIlwiIjsKLSAgICAgIGJyZWFrOwotCi0gICAgZGVmYXVsdDoKLSAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oIlR5cGUgb2YgQ29uc3RWYWx1ZSBpbnZhbGlkOiAiICsgYyk7Ci0gICAgfQotCi0gICAgcmV0dXJuIGJ1ZjsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIGRlZXAgY29weSBvZiB0aGlzIGF0dHJpYnV0ZQotICAgKi8KLSAgcHVibGljIEF0dHJpYnV0ZSBjb3B5KENvbnN0YW50UG9vbCBjb25zdGFudF9wb29sKSB7Ci0gICAgQ29uc3RhbnRWYWx1ZSBjID0gKENvbnN0YW50VmFsdWUpY2xvbmUoKTsKLSAgICBjLmNvbnN0YW50X3Bvb2wgPSBjb25zdGFudF9wb29sOwotICAgIHJldHVybiBjOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvY2xhc3NmaWxlL0RlcHJlY2F0ZWQuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvRGVwcmVjYXRlZC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwOTZmNzdmLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvRGVwcmVjYXRlZC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTcyICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmNsYXNzZmlsZTsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotaW1wb3J0ICBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHM7Ci1pbXBvcnQgIGphdmEuaW8uKjsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGlzIGRlcml2ZWQgZnJvbSA8ZW0+QXR0cmlidXRlPC9lbT4gYW5kIGRlbm90ZXMgdGhhdCB0aGlzIGlzIGEKLSAqIGRlcHJlY2F0ZWQgbWV0aG9kLgotICogSXQgaXMgaW5zdGFudGlhdGVkIGZyb20gdGhlIDxlbT5BdHRyaWJ1dGUucmVhZEF0dHJpYnV0ZSgpPC9lbT4gbWV0aG9kLgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKiBAc2VlICAgICBBdHRyaWJ1dGUKLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIERlcHJlY2F0ZWQgZXh0ZW5kcyBBdHRyaWJ1dGUgewotICBwcml2YXRlIGJ5dGVbXSBieXRlczsKLQotICAvKioKLSAgICogSW5pdGlhbGl6ZSBmcm9tIGFub3RoZXIgb2JqZWN0LiBOb3RlIHRoYXQgYm90aCBvYmplY3RzIHVzZSB0aGUgc2FtZQotICAgKiByZWZlcmVuY2VzIChzaGFsbG93IGNvcHkpLiBVc2UgY2xvbmUoKSBmb3IgYSBwaHlzaWNhbCBjb3B5LgotICAgKi8KLSAgcHVibGljIERlcHJlY2F0ZWQoRGVwcmVjYXRlZCBjKSB7Ci0gICAgdGhpcyhjLmdldE5hbWVJbmRleCgpLCBjLmdldExlbmd0aCgpLCBjLmdldEJ5dGVzKCksIGMuZ2V0Q29uc3RhbnRQb29sKCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBuYW1lX2luZGV4IEluZGV4IGluIGNvbnN0YW50IHBvb2wgdG8gQ09OU1RBTlRfVXRmOAotICAgKiBAcGFyYW0gbGVuZ3RoIENvbnRlbnQgbGVuZ3RoIGluIGJ5dGVzCi0gICAqIEBwYXJhbSBieXRlcyBBdHRyaWJ1dGUgY29udGVudHMKLSAgICogQHBhcmFtIGNvbnN0YW50X3Bvb2wgQXJyYXkgb2YgY29uc3RhbnRzCi0gICAqLwotICBwdWJsaWMgRGVwcmVjYXRlZChpbnQgbmFtZV9pbmRleCwgaW50IGxlbmd0aCwgYnl0ZVtdIGJ5dGVzLAotICAgICAgICAgICAgICAgICAgICBDb25zdGFudFBvb2wgY29uc3RhbnRfcG9vbCkKLSAgewotICAgIHN1cGVyKENvbnN0YW50cy5BVFRSX0RFUFJFQ0FURUQsIG5hbWVfaW5kZXgsIGxlbmd0aCwgY29uc3RhbnRfcG9vbCk7Ci0gICAgdGhpcy5ieXRlcyA9IGJ5dGVzOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBvYmplY3QgZnJvbSBmaWxlIHN0cmVhbS4KLSAgICogQHBhcmFtIG5hbWVfaW5kZXggSW5kZXggaW4gY29uc3RhbnQgcG9vbCB0byBDT05TVEFOVF9VdGY4Ci0gICAqIEBwYXJhbSBsZW5ndGggQ29udGVudCBsZW5ndGggaW4gYnl0ZXMKLSAgICogQHBhcmFtIGZpbGUgSW5wdXQgc3RyZWFtCi0gICAqIEBwYXJhbSBjb25zdGFudF9wb29sIEFycmF5IG9mIGNvbnN0YW50cwotICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0gICAqLwotICBEZXByZWNhdGVkKGludCBuYW1lX2luZGV4LCBpbnQgbGVuZ3RoLCBEYXRhSW5wdXRTdHJlYW0gZmlsZSwKLSAgICAgICAgICAgICBDb25zdGFudFBvb2wgY29uc3RhbnRfcG9vbCkgdGhyb3dzIElPRXhjZXB0aW9uCi0gIHsKLSAgICB0aGlzKG5hbWVfaW5kZXgsIGxlbmd0aCwgKGJ5dGUgW10pbnVsbCwgY29uc3RhbnRfcG9vbCk7Ci0KLSAgICBpZihsZW5ndGggPiAwKSB7Ci0gICAgICBieXRlcyA9IG5ldyBieXRlW2xlbmd0aF07Ci0gICAgICBmaWxlLnJlYWRGdWxseShieXRlcyk7Ci0gICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIkRlcHJlY2F0ZWQgYXR0cmlidXRlIHdpdGggbGVuZ3RoID4gMCIpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBDYWxsZWQgYnkgb2JqZWN0cyB0aGF0IGFyZSB0cmF2ZXJzaW5nIHRoZSBub2RlcyBvZiB0aGUgdHJlZSBpbXBsaWNpdGVseQotICAgKiBkZWZpbmVkIGJ5IHRoZSBjb250ZW50cyBvZiBhIEphdmEgY2xhc3MuIEkuZS4sIHRoZSBoaWVyYXJjaHkgb2YgbWV0aG9kcywKLSAgICogZmllbGRzLCBhdHRyaWJ1dGVzLCBldGMuIHNwYXducyBhIHRyZWUgb2Ygb2JqZWN0cy4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0RGVwcmVjYXRlZCh0aGlzKTsKLSAgfQotCi0gIC8qKgotICAgKiBEdW1wIHNvdXJjZSBmaWxlIGF0dHJpYnV0ZSB0byBmaWxlIHN0cmVhbSBpbiBiaW5hcnkgZm9ybWF0LgotICAgKgotICAgKiBAcGFyYW0gZmlsZSBPdXRwdXQgZmlsZSBzdHJlYW0KLSAgICogQHRocm93cyBJT0V4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgZHVtcChEYXRhT3V0cHV0U3RyZWFtIGZpbGUpIHRocm93cyBJT0V4Y2VwdGlvbgotICB7Ci0gICAgc3VwZXIuZHVtcChmaWxlKTsKLQotICAgIGlmKGxlbmd0aCA+IDApCi0gICAgICBmaWxlLndyaXRlKGJ5dGVzLCAwLCBsZW5ndGgpOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gZGF0YSBieXRlcy4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBieXRlW10gZ2V0Qnl0ZXMoKSB7IHJldHVybiBieXRlczsgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gYnl0ZXMuCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBzZXRCeXRlcyhieXRlW10gYnl0ZXMpIHsKLSAgICB0aGlzLmJ5dGVzID0gYnl0ZXM7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBhdHRyaWJ1dGUgbmFtZQotICAgKi8KLSAgcHVibGljIGZpbmFsIFN0cmluZyB0b1N0cmluZygpIHsKLSAgICByZXR1cm4gQ29uc3RhbnRzLkFUVFJJQlVURV9OQU1FU1tDb25zdGFudHMuQVRUUl9ERVBSRUNBVEVEXTsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIGRlZXAgY29weSBvZiB0aGlzIGF0dHJpYnV0ZQotICAgKi8KLSAgcHVibGljIEF0dHJpYnV0ZSBjb3B5KENvbnN0YW50UG9vbCBjb25zdGFudF9wb29sKSB7Ci0gICAgRGVwcmVjYXRlZCBjID0gKERlcHJlY2F0ZWQpY2xvbmUoKTsKLQotICAgIGlmKGJ5dGVzICE9IG51bGwpCi0gICAgICBjLmJ5dGVzID0gKGJ5dGVbXSlieXRlcy5jbG9uZSgpOwotCi0gICAgYy5jb25zdGFudF9wb29sID0gY29uc3RhbnRfcG9vbDsKLSAgICByZXR1cm4gYzsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2NsYXNzZmlsZS9EZXNjZW5kaW5nVmlzaXRvci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2NsYXNzZmlsZS9EZXNjZW5kaW5nVmlzaXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3NjNlY2E2Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvRGVzY2VuZGluZ1Zpc2l0b3IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDM3MCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5jbGFzc2ZpbGU7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1pbXBvcnQgamF2YS51dGlsLlN0YWNrOwotCi0vKioKLSAqIFRyYXZlcnNlcyBhIEphdmFDbGFzcyB3aXRoIGFub3RoZXIgVmlzaXRvciBvYmplY3QgJ3BpZ2d5LWJhY2tlZCcKLSAqIHRoYXQgaXMgYXBwbGllZCB0byBhbGwgY29tcG9uZW50cyBvZiBhIEphdmFDbGFzcyBvYmplY3QuIEkuZS4gdGhpcwotICogY2xhc3Mgc3VwcGxpZXMgdGhlIHRyYXZlcnNhbCBzdHJhdGVneSwgb3RoZXIgY2xhc3NlcyBjYW4gbWFrZSB1c2UKLSAqIG9mIGl0LgotICoKLSAqIEBhdXRob3IgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGNsYXNzIERlc2NlbmRpbmdWaXNpdG9yIGltcGxlbWVudHMgVmlzaXRvciB7Ci0gIHByaXZhdGUgSmF2YUNsYXNzIGNsYXp6OwotICBwcml2YXRlIFZpc2l0b3IgICB2aXNpdG9yOwotICBwcml2YXRlIFN0YWNrICAgICBzdGFjayA9IG5ldyBTdGFjaygpOwotCi0gIC8qKiBAcmV0dXJuIGNvbnRhaW5lciBvZiBjdXJyZW50IGVudGl0aXR5LCBpLmUuLCBwcmVkZWNlc3NvciBkdXJpbmcgdHJhdmVyc2FsCi0gICAqLwotICBwdWJsaWMgT2JqZWN0IHByZWRlY2Vzc29yKCkgewotICAgIHJldHVybiBwcmVkZWNlc3NvcigwKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gbGV2ZWwgbmVzdGluZyBsZXZlbCwgaS5lLiwgMCByZXR1cm5zIHRoZSBkaXJlY3QgcHJlZGVjZXNzb3IKLSAgICogQHJldHVybiBjb250YWluZXIgb2YgY3VycmVudCBlbnRpdGl0eSwgaS5lLiwgcHJlZGVjZXNzb3IgZHVyaW5nIHRyYXZlcnNhbAotICAgKi8KLSAgcHVibGljIE9iamVjdCBwcmVkZWNlc3NvcihpbnQgbGV2ZWwpIHsKLSAgICBpbnQgc2l6ZSA9IHN0YWNrLnNpemUoKTsKLQotICAgIGlmKChzaXplIDwgMikgfHwgKGxldmVsIDwgMCkpCi0gICAgICByZXR1cm4gbnVsbDsKLSAgICBlbHNlCi0gICAgICByZXR1cm4gc3RhY2suZWxlbWVudEF0KHNpemUgLSAobGV2ZWwgKyAyKSk7IC8vIHNpemUgLSAxID09IGN1cnJlbnQKLSAgfQotCi0gIC8qKiBAcmV0dXJuIGN1cnJlbnQgb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgT2JqZWN0IGN1cnJlbnQoKSB7Ci0gICAgcmV0dXJuIHN0YWNrLnBlZWsoKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gY2xhenogQ2xhc3MgdG8gdHJhdmVyc2UKLSAgICogQHBhcmFtIHZpc2l0b3IgdmlzaXRvciBvYmplY3QgdG8gYXBwbHkgdG8gYWxsIGNvbXBvbmVudHMKLSAgICovCi0gIHB1YmxpYyBEZXNjZW5kaW5nVmlzaXRvcihKYXZhQ2xhc3MgY2xhenosIFZpc2l0b3IgdmlzaXRvcikgewotICAgIHRoaXMuY2xhenogICA9IGNsYXp6OwotICAgIHRoaXMudmlzaXRvciA9IHZpc2l0b3I7Ci0gIH0KLQotICAvKioKLSAgICogU3RhcnQgdHJhdmVyc2FsLgotICAgKi8KLSAgcHVibGljIHZvaWQgdmlzaXQoKSB7IGNsYXp6LmFjY2VwdCh0aGlzKTsgfQotCi0gIHB1YmxpYyB2b2lkIHZpc2l0SmF2YUNsYXNzKEphdmFDbGFzcyBjbGF6eikgewotICAgIHN0YWNrLnB1c2goY2xhenopOwotICAgIGNsYXp6LmFjY2VwdCh2aXNpdG9yKTsKLQotICAgIEZpZWxkW10gZmllbGRzID0gY2xhenouZ2V0RmllbGRzKCk7Ci0gICAgZm9yKGludCBpPTA7IGkgPCBmaWVsZHMubGVuZ3RoOyBpKyspCi0gICAgICBmaWVsZHNbaV0uYWNjZXB0KHRoaXMpOwotCi0gICAgTWV0aG9kW10gbWV0aG9kcyA9IGNsYXp6LmdldE1ldGhvZHMoKTsKLSAgICBmb3IoaW50IGk9MDsgaSA8IG1ldGhvZHMubGVuZ3RoOyBpKyspCi0gICAgICBtZXRob2RzW2ldLmFjY2VwdCh0aGlzKTsKLQotICAgIEF0dHJpYnV0ZVtdIGF0dHJpYnV0ZXMgPSBjbGF6ei5nZXRBdHRyaWJ1dGVzKCk7Ci0gICAgZm9yKGludCBpPTA7IGkgPCBhdHRyaWJ1dGVzLmxlbmd0aDsgaSsrKQotICAgICAgYXR0cmlidXRlc1tpXS5hY2NlcHQodGhpcyk7Ci0KLSAgICBjbGF6ei5nZXRDb25zdGFudFBvb2woKS5hY2NlcHQodGhpcyk7Ci0gICAgc3RhY2sucG9wKCk7Ci0gIH0KLQotICBwdWJsaWMgdm9pZCB2aXNpdEZpZWxkKEZpZWxkIGZpZWxkKSB7Ci0gICAgc3RhY2sucHVzaChmaWVsZCk7Ci0gICAgZmllbGQuYWNjZXB0KHZpc2l0b3IpOwotCi0gICAgQXR0cmlidXRlW10gYXR0cmlidXRlcyA9IGZpZWxkLmdldEF0dHJpYnV0ZXMoKTsKLSAgICBmb3IoaW50IGk9MDsgaSA8IGF0dHJpYnV0ZXMubGVuZ3RoOyBpKyspCi0gICAgICBhdHRyaWJ1dGVzW2ldLmFjY2VwdCh0aGlzKTsKLSAgICBzdGFjay5wb3AoKTsKLSAgfQotCi0gIHB1YmxpYyB2b2lkIHZpc2l0Q29uc3RhbnRWYWx1ZShDb25zdGFudFZhbHVlIGN2KSB7Ci0gICAgc3RhY2sucHVzaChjdik7Ci0gICAgY3YuYWNjZXB0KHZpc2l0b3IpOwotICAgIHN0YWNrLnBvcCgpOwotICB9Ci0KLSAgcHVibGljIHZvaWQgdmlzaXRNZXRob2QoTWV0aG9kIG1ldGhvZCkgewotICAgIHN0YWNrLnB1c2gobWV0aG9kKTsKLSAgICBtZXRob2QuYWNjZXB0KHZpc2l0b3IpOwotCi0gICAgQXR0cmlidXRlW10gYXR0cmlidXRlcyA9IG1ldGhvZC5nZXRBdHRyaWJ1dGVzKCk7Ci0gICAgZm9yKGludCBpPTA7IGkgPCBhdHRyaWJ1dGVzLmxlbmd0aDsgaSsrKQotICAgICAgYXR0cmlidXRlc1tpXS5hY2NlcHQodGhpcyk7Ci0KLSAgICBzdGFjay5wb3AoKTsKLSAgfQotCi0gIHB1YmxpYyB2b2lkIHZpc2l0RXhjZXB0aW9uVGFibGUoRXhjZXB0aW9uVGFibGUgdGFibGUpIHsKLSAgICBzdGFjay5wdXNoKHRhYmxlKTsKLSAgICB0YWJsZS5hY2NlcHQodmlzaXRvcik7Ci0gICAgc3RhY2sucG9wKCk7Ci0gIH0KLQotICBwdWJsaWMgdm9pZCB2aXNpdENvZGUoQ29kZSBjb2RlKSB7Ci0gICAgc3RhY2sucHVzaChjb2RlKTsKLSAgICBjb2RlLmFjY2VwdCh2aXNpdG9yKTsKLQotICAgIENvZGVFeGNlcHRpb25bXSB0YWJsZSA9IGNvZGUuZ2V0RXhjZXB0aW9uVGFibGUoKTsKLSAgICBmb3IoaW50IGk9MDsgaSA8IHRhYmxlLmxlbmd0aDsgaSsrKQotICAgICAgdGFibGVbaV0uYWNjZXB0KHRoaXMpOwotCi0gICAgQXR0cmlidXRlW10gYXR0cmlidXRlcyA9IGNvZGUuZ2V0QXR0cmlidXRlcygpOwotICAgIGZvcihpbnQgaT0wOyBpIDwgYXR0cmlidXRlcy5sZW5ndGg7IGkrKykKLSAgICAgIGF0dHJpYnV0ZXNbaV0uYWNjZXB0KHRoaXMpOwotICAgIHN0YWNrLnBvcCgpOwotICB9Ci0KLSAgcHVibGljIHZvaWQgdmlzaXRDb2RlRXhjZXB0aW9uKENvZGVFeGNlcHRpb24gY2UpIHsKLSAgICBzdGFjay5wdXNoKGNlKTsKLSAgICBjZS5hY2NlcHQodmlzaXRvcik7Ci0gICAgc3RhY2sucG9wKCk7Ci0gIH0KLQotICBwdWJsaWMgdm9pZCB2aXNpdExpbmVOdW1iZXJUYWJsZShMaW5lTnVtYmVyVGFibGUgdGFibGUpIHsKLSAgICBzdGFjay5wdXNoKHRhYmxlKTsKLSAgICB0YWJsZS5hY2NlcHQodmlzaXRvcik7Ci0KLSAgICBMaW5lTnVtYmVyW10gbnVtYmVycyA9IHRhYmxlLmdldExpbmVOdW1iZXJUYWJsZSgpOwotICAgIGZvcihpbnQgaT0wOyBpIDwgbnVtYmVycy5sZW5ndGg7IGkrKykKLSAgICAgIG51bWJlcnNbaV0uYWNjZXB0KHRoaXMpOwotICAgIHN0YWNrLnBvcCgpOwotICB9Ci0KLSAgcHVibGljIHZvaWQgdmlzaXRMaW5lTnVtYmVyKExpbmVOdW1iZXIgbnVtYmVyKSB7Ci0gICAgc3RhY2sucHVzaChudW1iZXIpOwotICAgIG51bWJlci5hY2NlcHQodmlzaXRvcik7Ci0gICAgc3RhY2sucG9wKCk7Ci0gIH0KLQotICBwdWJsaWMgdm9pZCB2aXNpdExvY2FsVmFyaWFibGVUYWJsZShMb2NhbFZhcmlhYmxlVGFibGUgdGFibGUpIHsKLSAgICBzdGFjay5wdXNoKHRhYmxlKTsKLSAgICB0YWJsZS5hY2NlcHQodmlzaXRvcik7Ci0KLSAgICBMb2NhbFZhcmlhYmxlW10gdmFycyA9IHRhYmxlLmdldExvY2FsVmFyaWFibGVUYWJsZSgpOwotICAgIGZvcihpbnQgaT0wOyBpIDwgdmFycy5sZW5ndGg7IGkrKykKLSAgICAgIHZhcnNbaV0uYWNjZXB0KHRoaXMpOwotICAgIHN0YWNrLnBvcCgpOwotICB9Ci0KLSAgcHVibGljIHZvaWQgdmlzaXRMb2NhbFZhcmlhYmxlVHlwZVRhYmxlKExvY2FsVmFyaWFibGVUeXBlVGFibGUgb2JqKSB7Ci0gICAgc3RhY2sucHVzaChvYmopOwotICAgIG9iai5hY2NlcHQodmlzaXRvcik7Ci0KLSAgICBMb2NhbFZhcmlhYmxlW10gdmFycyA9IG9iai5nZXRMb2NhbFZhcmlhYmxlVHlwZVRhYmxlKCk7Ci0gICAgZm9yKGludCBpPTA7IGkgPCB2YXJzLmxlbmd0aDsgaSsrKQotICAgICAgdmFyc1tpXS5hY2NlcHQodGhpcyk7Ci0gICAgc3RhY2sucG9wKCk7Ci0gIH0KLQotICBwdWJsaWMgdm9pZCB2aXNpdFN0YWNrTWFwKFN0YWNrTWFwIHRhYmxlKSB7Ci0gICAgc3RhY2sucHVzaCh0YWJsZSk7Ci0gICAgdGFibGUuYWNjZXB0KHZpc2l0b3IpOwotCi0gICAgU3RhY2tNYXBFbnRyeVtdIHZhcnMgPSB0YWJsZS5nZXRTdGFja01hcCgpOwotCi0gICAgZm9yKGludCBpPTA7IGkgPCB2YXJzLmxlbmd0aDsgaSsrKQotICAgICAgdmFyc1tpXS5hY2NlcHQodGhpcyk7Ci0gICAgc3RhY2sucG9wKCk7Ci0gIH0KLQotICBwdWJsaWMgdm9pZCB2aXNpdFN0YWNrTWFwRW50cnkoU3RhY2tNYXBFbnRyeSB2YXIpIHsKLSAgICBzdGFjay5wdXNoKHZhcik7Ci0gICAgdmFyLmFjY2VwdCh2aXNpdG9yKTsKLSAgICBzdGFjay5wb3AoKTsKLSAgfQotCi0gIHB1YmxpYyB2b2lkIHZpc2l0TG9jYWxWYXJpYWJsZShMb2NhbFZhcmlhYmxlIHZhcikgewotICAgIHN0YWNrLnB1c2godmFyKTsKLSAgICB2YXIuYWNjZXB0KHZpc2l0b3IpOwotICAgIHN0YWNrLnBvcCgpOwotICB9Ci0KLSAgcHVibGljIHZvaWQgdmlzaXRDb25zdGFudFBvb2woQ29uc3RhbnRQb29sIGNwKSB7Ci0gICAgc3RhY2sucHVzaChjcCk7Ci0gICAgY3AuYWNjZXB0KHZpc2l0b3IpOwotCi0gICAgQ29uc3RhbnRbXSBjb25zdGFudHMgPSBjcC5nZXRDb25zdGFudFBvb2woKTsKLSAgICBmb3IoaW50IGk9MTsgaSA8IGNvbnN0YW50cy5sZW5ndGg7IGkrKykgewotICAgICAgaWYoY29uc3RhbnRzW2ldICE9IG51bGwpCi0gICAgICAgIGNvbnN0YW50c1tpXS5hY2NlcHQodGhpcyk7Ci0gICAgfQotCi0gICAgc3RhY2sucG9wKCk7Ci0gIH0KLQotICBwdWJsaWMgdm9pZCB2aXNpdENvbnN0YW50Q2xhc3MoQ29uc3RhbnRDbGFzcyBjb25zdGFudCkgewotICAgIHN0YWNrLnB1c2goY29uc3RhbnQpOwotICAgIGNvbnN0YW50LmFjY2VwdCh2aXNpdG9yKTsKLSAgICBzdGFjay5wb3AoKTsKLSAgfQotCi0gIHB1YmxpYyB2b2lkIHZpc2l0Q29uc3RhbnREb3VibGUoQ29uc3RhbnREb3VibGUgY29uc3RhbnQpIHsKLSAgICBzdGFjay5wdXNoKGNvbnN0YW50KTsKLSAgICBjb25zdGFudC5hY2NlcHQodmlzaXRvcik7Ci0gICAgc3RhY2sucG9wKCk7Ci0gIH0KLQotICBwdWJsaWMgdm9pZCB2aXNpdENvbnN0YW50RmllbGRyZWYoQ29uc3RhbnRGaWVsZHJlZiBjb25zdGFudCkgewotICAgIHN0YWNrLnB1c2goY29uc3RhbnQpOwotICAgIGNvbnN0YW50LmFjY2VwdCh2aXNpdG9yKTsKLSAgICBzdGFjay5wb3AoKTsKLSAgfQotCi0gIHB1YmxpYyB2b2lkIHZpc2l0Q29uc3RhbnRGbG9hdChDb25zdGFudEZsb2F0IGNvbnN0YW50KSB7Ci0gICAgc3RhY2sucHVzaChjb25zdGFudCk7Ci0gICAgY29uc3RhbnQuYWNjZXB0KHZpc2l0b3IpOwotICAgIHN0YWNrLnBvcCgpOwotIH0KLQotICBwdWJsaWMgdm9pZCB2aXNpdENvbnN0YW50SW50ZWdlcihDb25zdGFudEludGVnZXIgY29uc3RhbnQpIHsKLSAgICBzdGFjay5wdXNoKGNvbnN0YW50KTsKLSAgICBjb25zdGFudC5hY2NlcHQodmlzaXRvcik7Ci0gICAgc3RhY2sucG9wKCk7Ci0gIH0KLQotICBwdWJsaWMgdm9pZCB2aXNpdENvbnN0YW50SW50ZXJmYWNlTWV0aG9kcmVmKENvbnN0YW50SW50ZXJmYWNlTWV0aG9kcmVmIGNvbnN0YW50KSB7Ci0gICAgc3RhY2sucHVzaChjb25zdGFudCk7Ci0gICAgY29uc3RhbnQuYWNjZXB0KHZpc2l0b3IpOwotICAgIHN0YWNrLnBvcCgpOwotICB9Ci0KLSAgcHVibGljIHZvaWQgdmlzaXRDb25zdGFudExvbmcoQ29uc3RhbnRMb25nIGNvbnN0YW50KSB7Ci0gICAgc3RhY2sucHVzaChjb25zdGFudCk7Ci0gICAgY29uc3RhbnQuYWNjZXB0KHZpc2l0b3IpOwotICAgIHN0YWNrLnBvcCgpOwotICB9Ci0KLSAgcHVibGljIHZvaWQgdmlzaXRDb25zdGFudE1ldGhvZHJlZihDb25zdGFudE1ldGhvZHJlZiBjb25zdGFudCkgewotICAgIHN0YWNrLnB1c2goY29uc3RhbnQpOwotICAgIGNvbnN0YW50LmFjY2VwdCh2aXNpdG9yKTsKLSAgICBzdGFjay5wb3AoKTsKLSAgfQotCi0gIHB1YmxpYyB2b2lkIHZpc2l0Q29uc3RhbnROYW1lQW5kVHlwZShDb25zdGFudE5hbWVBbmRUeXBlIGNvbnN0YW50KSB7Ci0gICAgc3RhY2sucHVzaChjb25zdGFudCk7Ci0gICAgY29uc3RhbnQuYWNjZXB0KHZpc2l0b3IpOwotICAgIHN0YWNrLnBvcCgpOwotICB9Ci0KLSAgcHVibGljIHZvaWQgdmlzaXRDb25zdGFudFN0cmluZyhDb25zdGFudFN0cmluZyBjb25zdGFudCkgewotICAgIHN0YWNrLnB1c2goY29uc3RhbnQpOwotICAgIGNvbnN0YW50LmFjY2VwdCh2aXNpdG9yKTsKLSAgICBzdGFjay5wb3AoKTsKLSAgfQotCi0gIHB1YmxpYyB2b2lkIHZpc2l0Q29uc3RhbnRVdGY4KENvbnN0YW50VXRmOCBjb25zdGFudCkgewotICAgIHN0YWNrLnB1c2goY29uc3RhbnQpOwotICAgIGNvbnN0YW50LmFjY2VwdCh2aXNpdG9yKTsKLSAgICBzdGFjay5wb3AoKTsKLSAgfQotCi0gIHB1YmxpYyB2b2lkIHZpc2l0SW5uZXJDbGFzc2VzKElubmVyQ2xhc3NlcyBpYykgewotICAgIHN0YWNrLnB1c2goaWMpOwotICAgIGljLmFjY2VwdCh2aXNpdG9yKTsKLQotICAgIElubmVyQ2xhc3NbXSBpY3MgPSBpYy5nZXRJbm5lckNsYXNzZXMoKTsKLSAgICBmb3IoaW50IGk9MDsgaSA8IGljcy5sZW5ndGg7IGkrKykKLSAgICAgIGljc1tpXS5hY2NlcHQodGhpcyk7Ci0gICAgc3RhY2sucG9wKCk7Ci0gIH0KLQotICBwdWJsaWMgdm9pZCB2aXNpdElubmVyQ2xhc3MoSW5uZXJDbGFzcyBpbm5lcikgewotICAgIHN0YWNrLnB1c2goaW5uZXIpOwotICAgIGlubmVyLmFjY2VwdCh2aXNpdG9yKTsKLSAgICBzdGFjay5wb3AoKTsKLSAgfQotCi0gIHB1YmxpYyB2b2lkIHZpc2l0RGVwcmVjYXRlZChEZXByZWNhdGVkIGF0dHJpYnV0ZSkgewotICAgIHN0YWNrLnB1c2goYXR0cmlidXRlKTsKLSAgICBhdHRyaWJ1dGUuYWNjZXB0KHZpc2l0b3IpOwotICAgIHN0YWNrLnBvcCgpOwotICB9Ci0KLSAgcHVibGljIHZvaWQgdmlzaXRTaWduYXR1cmUoU2lnbmF0dXJlIGF0dHJpYnV0ZSkgewotICAgIHN0YWNrLnB1c2goYXR0cmlidXRlKTsKLSAgICBhdHRyaWJ1dGUuYWNjZXB0KHZpc2l0b3IpOwotICAgIHN0YWNrLnBvcCgpOwotICB9Ci0KLSAgcHVibGljIHZvaWQgdmlzaXRTb3VyY2VGaWxlKFNvdXJjZUZpbGUgYXR0cmlidXRlKSB7Ci0gICAgc3RhY2sucHVzaChhdHRyaWJ1dGUpOwotICAgIGF0dHJpYnV0ZS5hY2NlcHQodmlzaXRvcik7Ci0gICAgc3RhY2sucG9wKCk7Ci0gIH0KLQotICBwdWJsaWMgdm9pZCB2aXNpdFN5bnRoZXRpYyhTeW50aGV0aWMgYXR0cmlidXRlKSB7Ci0gICAgc3RhY2sucHVzaChhdHRyaWJ1dGUpOwotICAgIGF0dHJpYnV0ZS5hY2NlcHQodmlzaXRvcik7Ci0gICAgc3RhY2sucG9wKCk7Ci0gIH0KLQotICBwdWJsaWMgdm9pZCB2aXNpdFVua25vd24oVW5rbm93biBhdHRyaWJ1dGUpIHsKLSAgICBzdGFjay5wdXNoKGF0dHJpYnV0ZSk7Ci0gICAgYXR0cmlidXRlLmFjY2VwdCh2aXNpdG9yKTsKLSAgICBzdGFjay5wb3AoKTsKLSB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvY2xhc3NmaWxlL0VtcHR5VmlzaXRvci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2NsYXNzZmlsZS9FbXB0eVZpc2l0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMzJhMWNjMS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvY2xhc3NmaWxlL0VtcHR5VmlzaXRvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTA5ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmNsYXNzZmlsZTsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmNsYXNzZmlsZS4qOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLio7Ci0KLS8qKgotICogVmlzaXRvciB3aXRoIGVtcHR5IG1ldGhvZCBib2RpZXMsIGNhbiBiZSBleHRlbmRlZCBhbmQgdXNlZCBpbiBjb25qdW5jdGlvbiB3aXRoIHRoZQotICogRGVzY2VuZGluZ1Zpc2l0b3IgY2xhc3MsIGUuZy4KLSAqCi0gKiBCeSBjb3VydGVzeSBvZiBEYXZpZCBTcGVuY2VyLgotICoKLSAqIEBzZWUgRGVzY2VuZGluZ1Zpc2l0b3IKLSAqCi0gKi8KLXB1YmxpYyBjbGFzcyBFbXB0eVZpc2l0b3IgaW1wbGVtZW50cyBWaXNpdG9yIHsKLSAgcHJvdGVjdGVkIEVtcHR5VmlzaXRvcigpIHsgfQotCi0gIHB1YmxpYyB2b2lkIHZpc2l0Q29kZShDb2RlIG9iaikge30KLSAgcHVibGljIHZvaWQgdmlzaXRDb2RlRXhjZXB0aW9uKENvZGVFeGNlcHRpb24gb2JqKSB7fQotICBwdWJsaWMgdm9pZCB2aXNpdENvbnN0YW50Q2xhc3MoQ29uc3RhbnRDbGFzcyBvYmopIHt9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0Q29uc3RhbnREb3VibGUoQ29uc3RhbnREb3VibGUgb2JqKSB7fQotICBwdWJsaWMgdm9pZCB2aXNpdENvbnN0YW50RmllbGRyZWYoQ29uc3RhbnRGaWVsZHJlZiBvYmopIHt9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0Q29uc3RhbnRGbG9hdChDb25zdGFudEZsb2F0IG9iaikge30KLSAgcHVibGljIHZvaWQgdmlzaXRDb25zdGFudEludGVnZXIoQ29uc3RhbnRJbnRlZ2VyIG9iaikge30KLSAgcHVibGljIHZvaWQgdmlzaXRDb25zdGFudEludGVyZmFjZU1ldGhvZHJlZihDb25zdGFudEludGVyZmFjZU1ldGhvZHJlZiBvYmopIHt9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0Q29uc3RhbnRMb25nKENvbnN0YW50TG9uZyBvYmopIHt9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0Q29uc3RhbnRNZXRob2RyZWYoQ29uc3RhbnRNZXRob2RyZWYgb2JqKSB7fQotICBwdWJsaWMgdm9pZCB2aXNpdENvbnN0YW50TmFtZUFuZFR5cGUoQ29uc3RhbnROYW1lQW5kVHlwZSBvYmopIHt9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0Q29uc3RhbnRQb29sKENvbnN0YW50UG9vbCBvYmopIHt9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0Q29uc3RhbnRTdHJpbmcoQ29uc3RhbnRTdHJpbmcgb2JqKSB7fQotICBwdWJsaWMgdm9pZCB2aXNpdENvbnN0YW50VXRmOChDb25zdGFudFV0Zjggb2JqKSB7fQotICBwdWJsaWMgdm9pZCB2aXNpdENvbnN0YW50VmFsdWUoQ29uc3RhbnRWYWx1ZSBvYmopIHt9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0RGVwcmVjYXRlZChEZXByZWNhdGVkIG9iaikge30KLSAgcHVibGljIHZvaWQgdmlzaXRFeGNlcHRpb25UYWJsZShFeGNlcHRpb25UYWJsZSBvYmopIHt9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0RmllbGQoRmllbGQgb2JqKSB7fQotICBwdWJsaWMgdm9pZCB2aXNpdElubmVyQ2xhc3MoSW5uZXJDbGFzcyBvYmopIHt9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0SW5uZXJDbGFzc2VzKElubmVyQ2xhc3NlcyBvYmopIHt9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0SmF2YUNsYXNzKEphdmFDbGFzcyBvYmopIHt9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0TGluZU51bWJlcihMaW5lTnVtYmVyIG9iaikge30KLSAgcHVibGljIHZvaWQgdmlzaXRMaW5lTnVtYmVyVGFibGUoTGluZU51bWJlclRhYmxlIG9iaikge30KLSAgcHVibGljIHZvaWQgdmlzaXRMb2NhbFZhcmlhYmxlKExvY2FsVmFyaWFibGUgb2JqKSB7fQotICBwdWJsaWMgdm9pZCB2aXNpdExvY2FsVmFyaWFibGVUYWJsZShMb2NhbFZhcmlhYmxlVGFibGUgb2JqKSB7fQotICBwdWJsaWMgdm9pZCB2aXNpdExvY2FsVmFyaWFibGVUeXBlVGFibGUoTG9jYWxWYXJpYWJsZVR5cGVUYWJsZSBvYmopIHt9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0TWV0aG9kKE1ldGhvZCBvYmopIHt9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0U2lnbmF0dXJlKFNpZ25hdHVyZSBvYmopIHt9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0U291cmNlRmlsZShTb3VyY2VGaWxlIG9iaikge30KLSAgcHVibGljIHZvaWQgdmlzaXRTeW50aGV0aWMoU3ludGhldGljIG9iaikge30KLSAgcHVibGljIHZvaWQgdmlzaXRVbmtub3duKFVua25vd24gb2JqKSB7fQotICBwdWJsaWMgdm9pZCB2aXNpdFN0YWNrTWFwKFN0YWNrTWFwIG9iaikge30KLSAgcHVibGljIHZvaWQgdmlzaXRTdGFja01hcEVudHJ5KFN0YWNrTWFwRW50cnkgb2JqKSB7fQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2NsYXNzZmlsZS9FeGNlcHRpb25UYWJsZS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2NsYXNzZmlsZS9FeGNlcHRpb25UYWJsZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwYTllMWRjLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvRXhjZXB0aW9uVGFibGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIwNSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5jbGFzc2ZpbGU7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLWltcG9ydCAgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzOwotaW1wb3J0ICBqYXZhLmlvLio7Ci0KLS8qKgotICogVGhpcyBjbGFzcyByZXByZXNlbnRzIHRoZSB0YWJsZSBvZiBleGNlcHRpb25zIHRoYXQgYXJlIHRocm93biBieSBhCi0gKiBtZXRob2QuIFRoaXMgYXR0cmlidXRlIG1heSBiZSB1c2VkIG9uY2UgcGVyIG1ldGhvZC4gIFRoZSBuYW1lIG9mCi0gKiB0aGlzIGNsYXNzIGlzIDxlbT5FeGNlcHRpb25UYWJsZTwvZW0+IGZvciBoaXN0b3JpY2FsIHJlYXNvbnM7IFRoZQotICogSmF2YSBWaXJ0dWFsIE1hY2hpbmUgU3BlY2lmaWNhdGlvbiwgU2Vjb25kIEVkaXRpb24gZGVmaW5lcyB0aGlzCi0gKiBhdHRyaWJ1dGUgdXNpbmcgdGhlIG5hbWUgPGVtPkV4Y2VwdGlvbnM8L2VtPiAod2hpY2ggaXMgaW5jb25zaXN0ZW50Ci0gKiB3aXRoIHRoZSBvdGhlciBjbGFzc2VzKS4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICogQHNlZSAgICAgQ29kZQotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgRXhjZXB0aW9uVGFibGUgZXh0ZW5kcyBBdHRyaWJ1dGUgewotICBwcml2YXRlIGludCAgIG51bWJlcl9vZl9leGNlcHRpb25zOyAgLy8gVGFibGUgb2YgaW5kaWNlcyBpbnRvCi0gIHByaXZhdGUgaW50W10gZXhjZXB0aW9uX2luZGV4X3RhYmxlOyAvLyBjb25zdGFudCBwb29sCi0KLSAgLyoqCi0gICAqIEluaXRpYWxpemUgZnJvbSBhbm90aGVyIG9iamVjdC4gTm90ZSB0aGF0IGJvdGggb2JqZWN0cyB1c2UgdGhlIHNhbWUKLSAgICogcmVmZXJlbmNlcyAoc2hhbGxvdyBjb3B5KS4gVXNlIGNvcHkoKSBmb3IgYSBwaHlzaWNhbCBjb3B5LgotICAgKi8KLSAgcHVibGljIEV4Y2VwdGlvblRhYmxlKEV4Y2VwdGlvblRhYmxlIGMpIHsKLSAgICB0aGlzKGMuZ2V0TmFtZUluZGV4KCksIGMuZ2V0TGVuZ3RoKCksIGMuZ2V0RXhjZXB0aW9uSW5kZXhUYWJsZSgpLAotICAgICAgICAgYy5nZXRDb25zdGFudFBvb2woKSk7Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIG5hbWVfaW5kZXggSW5kZXggaW4gY29uc3RhbnQgcG9vbAotICAgKiBAcGFyYW0gbGVuZ3RoIENvbnRlbnQgbGVuZ3RoIGluIGJ5dGVzCi0gICAqIEBwYXJhbSBleGNlcHRpb25faW5kZXhfdGFibGUgVGFibGUgb2YgaW5kaWNlcyBpbiBjb25zdGFudCBwb29sCi0gICAqIEBwYXJhbSBjb25zdGFudF9wb29sIEFycmF5IG9mIGNvbnN0YW50cwotICAgKi8KLSAgcHVibGljIEV4Y2VwdGlvblRhYmxlKGludCAgICAgICAgbmFtZV9pbmRleCwgaW50IGxlbmd0aCwKLSAgICAgICAgICAgICAgICAgICAgICAgIGludFtdICAgICAgZXhjZXB0aW9uX2luZGV4X3RhYmxlLAotICAgICAgICAgICAgICAgICAgICAgICAgQ29uc3RhbnRQb29sIGNvbnN0YW50X3Bvb2wpCi0gIHsKLSAgICBzdXBlcihDb25zdGFudHMuQVRUUl9FWENFUFRJT05TLCBuYW1lX2luZGV4LCBsZW5ndGgsIGNvbnN0YW50X3Bvb2wpOwotICAgIHNldEV4Y2VwdGlvbkluZGV4VGFibGUoZXhjZXB0aW9uX2luZGV4X3RhYmxlKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3Qgb2JqZWN0IGZyb20gZmlsZSBzdHJlYW0uCi0gICAqIEBwYXJhbSBuYW1lX2luZGV4IEluZGV4IGluIGNvbnN0YW50IHBvb2wKLSAgICogQHBhcmFtIGxlbmd0aCBDb250ZW50IGxlbmd0aCBpbiBieXRlcwotICAgKiBAcGFyYW0gZmlsZSBJbnB1dCBzdHJlYW0KLSAgICogQHBhcmFtIGNvbnN0YW50X3Bvb2wgQXJyYXkgb2YgY29uc3RhbnRzCi0gICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLSAgICovCi0gIEV4Y2VwdGlvblRhYmxlKGludCBuYW1lX2luZGV4LCBpbnQgbGVuZ3RoLCBEYXRhSW5wdXRTdHJlYW0gZmlsZSwKLSAgICAgICAgICAgICAgICAgQ29uc3RhbnRQb29sIGNvbnN0YW50X3Bvb2wpIHRocm93cyBJT0V4Y2VwdGlvbgotICB7Ci0gICAgdGhpcyhuYW1lX2luZGV4LCBsZW5ndGgsIChpbnRbXSludWxsLCBjb25zdGFudF9wb29sKTsKLQotICAgIG51bWJlcl9vZl9leGNlcHRpb25zICA9IGZpbGUucmVhZFVuc2lnbmVkU2hvcnQoKTsKLSAgICBleGNlcHRpb25faW5kZXhfdGFibGUgPSBuZXcgaW50W251bWJlcl9vZl9leGNlcHRpb25zXTsKLQotICAgIGZvcihpbnQgaT0wOyBpIDwgbnVtYmVyX29mX2V4Y2VwdGlvbnM7IGkrKykKLSAgICAgIGV4Y2VwdGlvbl9pbmRleF90YWJsZVtpXSA9IGZpbGUucmVhZFVuc2lnbmVkU2hvcnQoKTsKLSAgfQotCi0gIC8qKgotICAgKiBDYWxsZWQgYnkgb2JqZWN0cyB0aGF0IGFyZSB0cmF2ZXJzaW5nIHRoZSBub2RlcyBvZiB0aGUgdHJlZSBpbXBsaWNpdGVseQotICAgKiBkZWZpbmVkIGJ5IHRoZSBjb250ZW50cyBvZiBhIEphdmEgY2xhc3MuIEkuZS4sIHRoZSBoaWVyYXJjaHkgb2YgbWV0aG9kcywKLSAgICogZmllbGRzLCBhdHRyaWJ1dGVzLCBldGMuIHNwYXducyBhIHRyZWUgb2Ygb2JqZWN0cy4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0RXhjZXB0aW9uVGFibGUodGhpcyk7Ci0gIH0KLQotICAvKioKLSAgICogRHVtcCBleGNlcHRpb25zIGF0dHJpYnV0ZSB0byBmaWxlIHN0cmVhbSBpbiBiaW5hcnkgZm9ybWF0LgotICAgKgotICAgKiBAcGFyYW0gZmlsZSBPdXRwdXQgZmlsZSBzdHJlYW0KLSAgICogQHRocm93cyBJT0V4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgZHVtcChEYXRhT3V0cHV0U3RyZWFtIGZpbGUpIHRocm93cyBJT0V4Y2VwdGlvbgotICB7Ci0gICAgc3VwZXIuZHVtcChmaWxlKTsKLSAgICBmaWxlLndyaXRlU2hvcnQobnVtYmVyX29mX2V4Y2VwdGlvbnMpOwotICAgIGZvcihpbnQgaT0wOyBpIDwgbnVtYmVyX29mX2V4Y2VwdGlvbnM7IGkrKykKLSAgICAgIGZpbGUud3JpdGVTaG9ydChleGNlcHRpb25faW5kZXhfdGFibGVbaV0pOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gQXJyYXkgb2YgaW5kaWNlcyBpbnRvIGNvbnN0YW50IHBvb2wgb2YgdGhyb3duIGV4Y2VwdGlvbnMuCi0gICAqLwotICBwdWJsaWMgZmluYWwgaW50W10gZ2V0RXhjZXB0aW9uSW5kZXhUYWJsZSgpIHtyZXR1cm4gZXhjZXB0aW9uX2luZGV4X3RhYmxlO30KLSAgLyoqCi0gICAqIEByZXR1cm4gTGVuZ3RoIG9mIGV4Y2VwdGlvbiB0YWJsZS4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBpbnQgZ2V0TnVtYmVyT2ZFeGNlcHRpb25zKCkgeyByZXR1cm4gbnVtYmVyX29mX2V4Y2VwdGlvbnM7IH0KLQotICAvKioKLSAgICogQHJldHVybiBjbGFzcyBuYW1lcyBvZiB0aHJvd24gZXhjZXB0aW9ucwotICAgKi8KLSAgcHVibGljIGZpbmFsIFN0cmluZ1tdIGdldEV4Y2VwdGlvbk5hbWVzKCkgewotICAgIFN0cmluZ1tdIG5hbWVzID0gbmV3IFN0cmluZ1tudW1iZXJfb2ZfZXhjZXB0aW9uc107Ci0gICAgZm9yKGludCBpPTA7IGkgPCBudW1iZXJfb2ZfZXhjZXB0aW9uczsgaSsrKQotICAgICAgbmFtZXNbaV0gPSBjb25zdGFudF9wb29sLmdldENvbnN0YW50U3RyaW5nKGV4Y2VwdGlvbl9pbmRleF90YWJsZVtpXSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb25zdGFudHMuQ09OU1RBTlRfQ2xhc3MpLgotICAgICAgICByZXBsYWNlKCcvJywgJy4nKTsKLSAgICByZXR1cm4gbmFtZXM7Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIGV4Y2VwdGlvbl9pbmRleF90YWJsZS4KLSAgICogQWxzbyByZWRlZmluZXMgbnVtYmVyX29mX2V4Y2VwdGlvbnMgYWNjb3JkaW5nIHRvIHRhYmxlIGxlbmd0aC4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHNldEV4Y2VwdGlvbkluZGV4VGFibGUoaW50W10gZXhjZXB0aW9uX2luZGV4X3RhYmxlKSB7Ci0gICAgdGhpcy5leGNlcHRpb25faW5kZXhfdGFibGUgPSBleGNlcHRpb25faW5kZXhfdGFibGU7Ci0gICAgbnVtYmVyX29mX2V4Y2VwdGlvbnMgICAgICAgPSAoZXhjZXB0aW9uX2luZGV4X3RhYmxlID09IG51bGwpPyAwIDoKLSAgICAgIGV4Y2VwdGlvbl9pbmRleF90YWJsZS5sZW5ndGg7Ci0gIH0KLSAgLyoqCi0gICAqIEByZXR1cm4gU3RyaW5nIHJlcHJlc2VudGF0aW9uLCBpLmUuLCBhIGxpc3Qgb2YgdGhyb3duIGV4Y2VwdGlvbnMuCi0gICAqLwotICBwdWJsaWMgZmluYWwgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgIFN0cmluZ0J1ZmZlciBidWYgPSBuZXcgU3RyaW5nQnVmZmVyKCIiKTsKLSAgICBTdHJpbmcgICAgICAgc3RyOwotCi0gICAgZm9yKGludCBpPTA7IGkgPCBudW1iZXJfb2ZfZXhjZXB0aW9uczsgaSsrKSB7Ci0gICAgICBzdHIgPSBjb25zdGFudF9wb29sLmdldENvbnN0YW50U3RyaW5nKGV4Y2VwdGlvbl9pbmRleF90YWJsZVtpXSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29uc3RhbnRzLkNPTlNUQU5UX0NsYXNzKTsKLSAgICAgIGJ1Zi5hcHBlbmQoVXRpbGl0eS5jb21wYWN0Q2xhc3NOYW1lKHN0ciwgZmFsc2UpKTsKLQotICAgICAgaWYoaSA8IG51bWJlcl9vZl9leGNlcHRpb25zIC0gMSkKLSAgICAgICAgYnVmLmFwcGVuZCgiLCAiKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gYnVmLnRvU3RyaW5nKCk7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBkZWVwIGNvcHkgb2YgdGhpcyBhdHRyaWJ1dGUKLSAgICovCi0gIHB1YmxpYyBBdHRyaWJ1dGUgY29weShDb25zdGFudFBvb2wgY29uc3RhbnRfcG9vbCkgewotICAgIEV4Y2VwdGlvblRhYmxlIGMgPSAoRXhjZXB0aW9uVGFibGUpY2xvbmUoKTsKLSAgICBjLmV4Y2VwdGlvbl9pbmRleF90YWJsZSA9IChpbnRbXSlleGNlcHRpb25faW5kZXhfdGFibGUuY2xvbmUoKTsKLSAgICBjLmNvbnN0YW50X3Bvb2wgPSBjb25zdGFudF9wb29sOwotICAgIHJldHVybiBjOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvY2xhc3NmaWxlL0ZpZWxkLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvY2xhc3NmaWxlL0ZpZWxkLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDZiYzQyZWUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2NsYXNzZmlsZS9GaWVsZC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTY4ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmNsYXNzZmlsZTsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLWltcG9ydCAgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuVHlwZTsKLWltcG9ydCBqYXZhLmlvLio7Ci0KLS8qKgotICogVGhpcyBjbGFzcyByZXByZXNlbnRzIHRoZSBmaWVsZCBpbmZvIHN0cnVjdHVyZSwgaS5lLiwgdGhlIHJlcHJlc2VudGF0aW9uCi0gKiBmb3IgYSB2YXJpYWJsZSBpbiB0aGUgY2xhc3MuIFNlZSBKVk0gc3BlY2lmaWNhdGlvbiBmb3IgZGV0YWlscy4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgRmllbGQgZXh0ZW5kcyBGaWVsZE9yTWV0aG9kIHsKLSAgLyoqCi0gICAqIEluaXRpYWxpemUgZnJvbSBhbm90aGVyIG9iamVjdC4gTm90ZSB0aGF0IGJvdGggb2JqZWN0cyB1c2UgdGhlIHNhbWUKLSAgICogcmVmZXJlbmNlcyAoc2hhbGxvdyBjb3B5KS4gVXNlIGNsb25lKCkgZm9yIGEgcGh5c2ljYWwgY29weS4KLSAgICovCi0gIHB1YmxpYyBGaWVsZChGaWVsZCBjKSB7Ci0gICAgc3VwZXIoYyk7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IG9iamVjdCBmcm9tIGZpbGUgc3RyZWFtLgotICAgKiBAcGFyYW0gZmlsZSBJbnB1dCBzdHJlYW0KLSAgICovCi0gIEZpZWxkKERhdGFJbnB1dFN0cmVhbSBmaWxlLCBDb25zdGFudFBvb2wgY29uc3RhbnRfcG9vbCkKLSAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIENsYXNzRm9ybWF0RXhjZXB0aW9uCi0gIHsKLSAgICBzdXBlcihmaWxlLCBjb25zdGFudF9wb29sKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gYWNjZXNzX2ZsYWdzIEFjY2VzcyByaWdodHMgb2YgZmllbGQKLSAgICogQHBhcmFtIG5hbWVfaW5kZXggUG9pbnRzIHRvIGZpZWxkIG5hbWUgaW4gY29uc3RhbnQgcG9vbAotICAgKiBAcGFyYW0gc2lnbmF0dXJlX2luZGV4IFBvaW50cyB0byBlbmNvZGVkIHNpZ25hdHVyZQotICAgKiBAcGFyYW0gYXR0cmlidXRlcyBDb2xsZWN0aW9uIG9mIGF0dHJpYnV0ZXMKLSAgICogQHBhcmFtIGNvbnN0YW50X3Bvb2wgQXJyYXkgb2YgY29uc3RhbnRzCi0gICAqLwotICBwdWJsaWMgRmllbGQoaW50IGFjY2Vzc19mbGFncywgaW50IG5hbWVfaW5kZXgsIGludCBzaWduYXR1cmVfaW5kZXgsCi0gICAgICAgICAgICAgICBBdHRyaWJ1dGVbXSBhdHRyaWJ1dGVzLCBDb25zdGFudFBvb2wgY29uc3RhbnRfcG9vbCkKLSAgewotICAgIHN1cGVyKGFjY2Vzc19mbGFncywgbmFtZV9pbmRleCwgc2lnbmF0dXJlX2luZGV4LCBhdHRyaWJ1dGVzLCBjb25zdGFudF9wb29sKTsKLSAgfQotCi0gIC8qKgotICAgKiBDYWxsZWQgYnkgb2JqZWN0cyB0aGF0IGFyZSB0cmF2ZXJzaW5nIHRoZSBub2RlcyBvZiB0aGUgdHJlZSBpbXBsaWNpdGVseQotICAgKiBkZWZpbmVkIGJ5IHRoZSBjb250ZW50cyBvZiBhIEphdmEgY2xhc3MuIEkuZS4sIHRoZSBoaWVyYXJjaHkgb2YgbWV0aG9kcywKLSAgICogZmllbGRzLCBhdHRyaWJ1dGVzLCBldGMuIHNwYXducyBhIHRyZWUgb2Ygb2JqZWN0cy4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0RmllbGQodGhpcyk7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBjb25zdGFudCB2YWx1ZSBhc3NvY2lhdGVkIHdpdGggdGhpcyBmaWVsZCAobWF5IGJlIG51bGwpCi0gICAqLwotICBwdWJsaWMgZmluYWwgQ29uc3RhbnRWYWx1ZSBnZXRDb25zdGFudFZhbHVlKCkgewotICAgIGZvcihpbnQgaT0wOyBpIDwgYXR0cmlidXRlc19jb3VudDsgaSsrKQotICAgICAgaWYoYXR0cmlidXRlc1tpXS5nZXRUYWcoKSA9PSBDb25zdGFudHMuQVRUUl9DT05TVEFOVF9WQUxVRSkKLSAgICAgICAgcmV0dXJuIChDb25zdGFudFZhbHVlKWF0dHJpYnV0ZXNbaV07Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gc3RyaW5nIHJlcHJlc2VudGF0aW9uIGNsb3NlIHRvIGRlY2xhcmF0aW9uIGZvcm1hdCwKLSAgICogYHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgTUFYID0gMTAwJywgZS5nLi4KLSAgICoKLSAgICogQHJldHVybiBTdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgZmllbGQsIGluY2x1ZGluZyB0aGUgc2lnbmF0dXJlLgotICAgKi8KLSAgcHVibGljIGZpbmFsIFN0cmluZyB0b1N0cmluZygpIHsKLSAgICBTdHJpbmcgbmFtZSwgc2lnbmF0dXJlLCBhY2Nlc3M7IC8vIFNob3J0IGN1dHMgdG8gY29uc3RhbnQgcG9vbAotCi0gICAgLy8gR2V0IG5hbWVzIGZyb20gY29uc3RhbnQgcG9vbAotICAgIGFjY2VzcyAgICA9IFV0aWxpdHkuYWNjZXNzVG9TdHJpbmcoYWNjZXNzX2ZsYWdzKTsKLSAgICBhY2Nlc3MgICAgPSBhY2Nlc3MuZXF1YWxzKCIiKT8gIiIgOiAoYWNjZXNzICsgIiAiKTsKLSAgICBzaWduYXR1cmUgPSBVdGlsaXR5LnNpZ25hdHVyZVRvU3RyaW5nKGdldFNpZ25hdHVyZSgpKTsKLSAgICBuYW1lICAgICAgPSBnZXROYW1lKCk7Ci0KLSAgICBTdHJpbmdCdWZmZXIgIGJ1ZiA9IG5ldyBTdHJpbmdCdWZmZXIoYWNjZXNzICsgc2lnbmF0dXJlICsgIiAiICsgbmFtZSk7Ci0gICAgQ29uc3RhbnRWYWx1ZSBjdiAgPSBnZXRDb25zdGFudFZhbHVlKCk7Ci0KLSAgICBpZihjdiAhPSBudWxsKQotICAgICAgYnVmLmFwcGVuZCgiID0gIiArIGN2KTsKLQotICAgIGZvcihpbnQgaT0wOyBpIDwgYXR0cmlidXRlc19jb3VudDsgaSsrKSB7Ci0gICAgICBBdHRyaWJ1dGUgYSA9IGF0dHJpYnV0ZXNbaV07Ci0KLSAgICAgIGlmKCEoYSBpbnN0YW5jZW9mIENvbnN0YW50VmFsdWUpKQotICAgICAgICBidWYuYXBwZW5kKCIgWyIgKyBhLnRvU3RyaW5nKCkgKyAiXSIpOwotICAgIH0KLQotICAgIHJldHVybiBidWYudG9TdHJpbmcoKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIGRlZXAgY29weSBvZiB0aGlzIGZpZWxkCi0gICAqLwotICBwdWJsaWMgZmluYWwgRmllbGQgY29weShDb25zdGFudFBvb2wgY29uc3RhbnRfcG9vbCkgewotICAgIHJldHVybiAoRmllbGQpY29weV8oY29uc3RhbnRfcG9vbCk7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiB0eXBlIG9mIGZpZWxkCi0gICAqLwotICBwdWJsaWMgVHlwZSBnZXRUeXBlKCkgewotICAgIHJldHVybiBUeXBlLmdldFJldHVyblR5cGUoZ2V0U2lnbmF0dXJlKCkpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvY2xhc3NmaWxlL0ZpZWxkT3JNZXRob2QuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvRmllbGRPck1ldGhvZC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4NmI3ZGEyLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvRmllbGRPck1ldGhvZC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjI2ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmNsYXNzZmlsZTsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLWltcG9ydCAgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzOwotaW1wb3J0IGphdmEuaW8uKjsKLQotLyoqCi0gKiBBYnN0cmFjdCBzdXBlciBjbGFzcyBmb3IgZmllbGRzIGFuZCBtZXRob2RzLgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBGaWVsZE9yTWV0aG9kIGV4dGVuZHMgQWNjZXNzRmxhZ3MgaW1wbGVtZW50cyBDbG9uZWFibGUsIE5vZGUgewotICBwcm90ZWN0ZWQgaW50ICAgICAgICAgIG5hbWVfaW5kZXg7ICAgICAgLy8gUG9pbnRzIHRvIGZpZWxkIG5hbWUgaW4gY29uc3RhbnQgcG9vbAotICBwcm90ZWN0ZWQgaW50ICAgICAgICAgIHNpZ25hdHVyZV9pbmRleDsgLy8gUG9pbnRzIHRvIGVuY29kZWQgc2lnbmF0dXJlCi0gIHByb3RlY3RlZCBpbnQgICAgICAgICAgYXR0cmlidXRlc19jb3VudDsvLyBOby4gb2YgYXR0cmlidXRlcwotICBwcm90ZWN0ZWQgQXR0cmlidXRlW10gIGF0dHJpYnV0ZXM7ICAgICAgLy8gQ29sbGVjdGlvbiBvZiBhdHRyaWJ1dGVzCi0gIHByb3RlY3RlZCBDb25zdGFudFBvb2wgY29uc3RhbnRfcG9vbDsKLQotICBGaWVsZE9yTWV0aG9kKCkge30KLQotICAvKioKLSAgICogSW5pdGlhbGl6ZSBmcm9tIGFub3RoZXIgb2JqZWN0LiBOb3RlIHRoYXQgYm90aCBvYmplY3RzIHVzZSB0aGUgc2FtZQotICAgKiByZWZlcmVuY2VzIChzaGFsbG93IGNvcHkpLiBVc2UgY2xvbmUoKSBmb3IgYSBwaHlzaWNhbCBjb3B5LgotICAgKi8KLSAgcHJvdGVjdGVkIEZpZWxkT3JNZXRob2QoRmllbGRPck1ldGhvZCBjKSB7Ci0gICAgdGhpcyhjLmdldEFjY2Vzc0ZsYWdzKCksIGMuZ2V0TmFtZUluZGV4KCksIGMuZ2V0U2lnbmF0dXJlSW5kZXgoKSwKLSAgICAgICAgIGMuZ2V0QXR0cmlidXRlcygpLCBjLmdldENvbnN0YW50UG9vbCgpKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3Qgb2JqZWN0IGZyb20gZmlsZSBzdHJlYW0uCi0gICAqIEBwYXJhbSBmaWxlIElucHV0IHN0cmVhbQotICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0gICAqIEB0aHJvd3MgQ2xhc3NGb3JtYXRFeGNlcHRpb24KLSAgICovCi0gIHByb3RlY3RlZCBGaWVsZE9yTWV0aG9kKERhdGFJbnB1dFN0cmVhbSBmaWxlLCBDb25zdGFudFBvb2wgY29uc3RhbnRfcG9vbCkKLSAgICB0aHJvd3MgSU9FeGNlcHRpb24sIENsYXNzRm9ybWF0RXhjZXB0aW9uCi0gIHsKLSAgICB0aGlzKGZpbGUucmVhZFVuc2lnbmVkU2hvcnQoKSwgZmlsZS5yZWFkVW5zaWduZWRTaG9ydCgpLAotICAgICAgICAgZmlsZS5yZWFkVW5zaWduZWRTaG9ydCgpLCBudWxsLCBjb25zdGFudF9wb29sKTsKLQotICAgIGF0dHJpYnV0ZXNfY291bnQgPSBmaWxlLnJlYWRVbnNpZ25lZFNob3J0KCk7Ci0gICAgYXR0cmlidXRlcyAgICAgICA9IG5ldyBBdHRyaWJ1dGVbYXR0cmlidXRlc19jb3VudF07Ci0gICAgZm9yKGludCBpPTA7IGkgPCBhdHRyaWJ1dGVzX2NvdW50OyBpKyspCi0gICAgICBhdHRyaWJ1dGVzW2ldID0gQXR0cmlidXRlLnJlYWRBdHRyaWJ1dGUoZmlsZSwgY29uc3RhbnRfcG9vbCk7Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIGFjY2Vzc19mbGFncyBBY2Nlc3MgcmlnaHRzIG9mIG1ldGhvZAotICAgKiBAcGFyYW0gbmFtZV9pbmRleCBQb2ludHMgdG8gZmllbGQgbmFtZSBpbiBjb25zdGFudCBwb29sCi0gICAqIEBwYXJhbSBzaWduYXR1cmVfaW5kZXggUG9pbnRzIHRvIGVuY29kZWQgc2lnbmF0dXJlCi0gICAqIEBwYXJhbSBhdHRyaWJ1dGVzIENvbGxlY3Rpb24gb2YgYXR0cmlidXRlcwotICAgKiBAcGFyYW0gY29uc3RhbnRfcG9vbCBBcnJheSBvZiBjb25zdGFudHMKLSAgICovCi0gIHByb3RlY3RlZCBGaWVsZE9yTWV0aG9kKGludCBhY2Nlc3NfZmxhZ3MsIGludCBuYW1lX2luZGV4LCBpbnQgc2lnbmF0dXJlX2luZGV4LAotICAgICAgICAgICAgICAgICAgICAgICAgICBBdHRyaWJ1dGVbXSBhdHRyaWJ1dGVzLCBDb25zdGFudFBvb2wgY29uc3RhbnRfcG9vbCkKLSAgewotICAgIHRoaXMuYWNjZXNzX2ZsYWdzICAgID0gYWNjZXNzX2ZsYWdzOwotICAgIHRoaXMubmFtZV9pbmRleCAgICAgID0gbmFtZV9pbmRleDsKLSAgICB0aGlzLnNpZ25hdHVyZV9pbmRleCA9IHNpZ25hdHVyZV9pbmRleDsKLSAgICB0aGlzLmNvbnN0YW50X3Bvb2wgICA9IGNvbnN0YW50X3Bvb2w7Ci0KLSAgICBzZXRBdHRyaWJ1dGVzKGF0dHJpYnV0ZXMpOwotICB9Ci0KLSAgLyoqCi0gICAqIER1bXAgb2JqZWN0IHRvIGZpbGUgc3RyZWFtIG9uIGJpbmFyeSBmb3JtYXQuCi0gICAqCi0gICAqIEBwYXJhbSBmaWxlIE91dHB1dCBmaWxlIHN0cmVhbQotICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBkdW1wKERhdGFPdXRwdXRTdHJlYW0gZmlsZSkgdGhyb3dzIElPRXhjZXB0aW9uCi0gIHsKLSAgICBmaWxlLndyaXRlU2hvcnQoYWNjZXNzX2ZsYWdzKTsKLSAgICBmaWxlLndyaXRlU2hvcnQobmFtZV9pbmRleCk7Ci0gICAgZmlsZS53cml0ZVNob3J0KHNpZ25hdHVyZV9pbmRleCk7Ci0gICAgZmlsZS53cml0ZVNob3J0KGF0dHJpYnV0ZXNfY291bnQpOwotCi0gICAgZm9yKGludCBpPTA7IGkgPCBhdHRyaWJ1dGVzX2NvdW50OyBpKyspCi0gICAgICBhdHRyaWJ1dGVzW2ldLmR1bXAoZmlsZSk7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBDb2xsZWN0aW9uIG9mIG9iamVjdCBhdHRyaWJ1dGVzLgotICAgKi8KLSAgcHVibGljIGZpbmFsIEF0dHJpYnV0ZVtdIGdldEF0dHJpYnV0ZXMoKSB7IHJldHVybiBhdHRyaWJ1dGVzOyB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBhdHRyaWJ1dGVzIENvbGxlY3Rpb24gb2Ygb2JqZWN0IGF0dHJpYnV0ZXMuCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBzZXRBdHRyaWJ1dGVzKEF0dHJpYnV0ZVtdIGF0dHJpYnV0ZXMpIHsKLSAgICB0aGlzLmF0dHJpYnV0ZXMgID0gYXR0cmlidXRlczsKLSAgICBhdHRyaWJ1dGVzX2NvdW50ID0gKGF0dHJpYnV0ZXMgPT0gbnVsbCk/IDAgOiBhdHRyaWJ1dGVzLmxlbmd0aDsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIENvbnN0YW50IHBvb2wgdXNlZCBieSB0aGlzIG9iamVjdC4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBDb25zdGFudFBvb2wgZ2V0Q29uc3RhbnRQb29sKCkgeyByZXR1cm4gY29uc3RhbnRfcG9vbDsgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gY29uc3RhbnRfcG9vbCBDb25zdGFudCBwb29sIHRvIGJlIHVzZWQgZm9yIHRoaXMgb2JqZWN0LgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgc2V0Q29uc3RhbnRQb29sKENvbnN0YW50UG9vbCBjb25zdGFudF9wb29sKSB7Ci0gICAgdGhpcy5jb25zdGFudF9wb29sID0gY29uc3RhbnRfcG9vbDsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIEluZGV4IGluIGNvbnN0YW50IHBvb2wgb2Ygb2JqZWN0J3MgbmFtZS4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBpbnQgZ2V0TmFtZUluZGV4KCkgeyByZXR1cm4gbmFtZV9pbmRleDsgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gbmFtZV9pbmRleCBJbmRleCBpbiBjb25zdGFudCBwb29sIG9mIG9iamVjdCdzIG5hbWUuCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBzZXROYW1lSW5kZXgoaW50IG5hbWVfaW5kZXgpIHsKLSAgICB0aGlzLm5hbWVfaW5kZXggPSBuYW1lX2luZGV4OwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gSW5kZXggaW4gY29uc3RhbnQgcG9vbCBvZiBmaWVsZCBzaWduYXR1cmUuCi0gICAqLwotICBwdWJsaWMgZmluYWwgaW50IGdldFNpZ25hdHVyZUluZGV4KCkgeyByZXR1cm4gc2lnbmF0dXJlX2luZGV4OyB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBzaWduYXR1cmVfaW5kZXggSW5kZXggaW4gY29uc3RhbnQgcG9vbCBvZiBmaWVsZCBzaWduYXR1cmUuCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBzZXRTaWduYXR1cmVJbmRleChpbnQgc2lnbmF0dXJlX2luZGV4KSB7Ci0gICAgdGhpcy5zaWduYXR1cmVfaW5kZXggPSBzaWduYXR1cmVfaW5kZXg7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBOYW1lIG9mIG9iamVjdCwgaS5lLiwgbWV0aG9kIG5hbWUgb3IgZmllbGQgbmFtZQotICAgKi8KLSAgcHVibGljIGZpbmFsIFN0cmluZyBnZXROYW1lKCkgewotICAgIENvbnN0YW50VXRmOCAgYzsKLSAgICBjID0gKENvbnN0YW50VXRmOCljb25zdGFudF9wb29sLmdldENvbnN0YW50KG5hbWVfaW5kZXgsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb25zdGFudHMuQ09OU1RBTlRfVXRmOCk7Ci0gICAgcmV0dXJuIGMuZ2V0Qnl0ZXMoKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIFN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBvYmplY3QncyB0eXBlIHNpZ25hdHVyZSAoamF2YSBzdHlsZSkKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBTdHJpbmcgZ2V0U2lnbmF0dXJlKCkgewotICAgIENvbnN0YW50VXRmOCAgYzsKLSAgICBjID0gKENvbnN0YW50VXRmOCljb25zdGFudF9wb29sLmdldENvbnN0YW50KHNpZ25hdHVyZV9pbmRleCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbnN0YW50cy5DT05TVEFOVF9VdGY4KTsKLSAgICByZXR1cm4gYy5nZXRCeXRlcygpOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gZGVlcCBjb3B5IG9mIHRoaXMgZmllbGQKLSAgICovCi0gIHByb3RlY3RlZCBGaWVsZE9yTWV0aG9kIGNvcHlfKENvbnN0YW50UG9vbCBjb25zdGFudF9wb29sKSB7Ci0gICAgRmllbGRPck1ldGhvZCBjID0gbnVsbDsKLQotICAgIHRyeSB7Ci0gICAgICBjID0gKEZpZWxkT3JNZXRob2QpY2xvbmUoKTsKLSAgICB9IGNhdGNoKENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGUpIHt9Ci0KLSAgICBjLmNvbnN0YW50X3Bvb2wgICAgPSBjb25zdGFudF9wb29sOwotICAgIGMuYXR0cmlidXRlcyAgICAgICA9IG5ldyBBdHRyaWJ1dGVbYXR0cmlidXRlc19jb3VudF07Ci0KLSAgICBmb3IoaW50IGk9MDsgaSA8IGF0dHJpYnV0ZXNfY291bnQ7IGkrKykKLSAgICAgIGMuYXR0cmlidXRlc1tpXSA9IGF0dHJpYnV0ZXNbaV0uY29weShjb25zdGFudF9wb29sKTsKLQotICAgIHJldHVybiBjOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvY2xhc3NmaWxlL0lubmVyQ2xhc3MuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvSW5uZXJDbGFzcy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4NjkzZmE2Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvSW5uZXJDbGFzcy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjI0ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmNsYXNzZmlsZTsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotaW1wb3J0ICBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHM7Ci1pbXBvcnQgIGphdmEuaW8uKjsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIHJlcHJlc2VudHMgYSBpbm5lciBjbGFzcyBhdHRyaWJ1dGUsIGkuZS4sIHRoZSBjbGFzcwotICogaW5kaWNlcyBvZiB0aGUgaW5uZXIgYW5kIG91dGVyIGNsYXNzZXMsIHRoZSBuYW1lIGFuZCB0aGUgYXR0cmlidXRlcwotICogb2YgdGhlIGlubmVyIGNsYXNzLgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKiBAc2VlIElubmVyQ2xhc3NlcwotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgSW5uZXJDbGFzcyBpbXBsZW1lbnRzIENsb25lYWJsZSwgTm9kZSB7Ci0gIHByaXZhdGUgaW50IGlubmVyX2NsYXNzX2luZGV4OwotICBwcml2YXRlIGludCBvdXRlcl9jbGFzc19pbmRleDsKLSAgcHJpdmF0ZSBpbnQgaW5uZXJfbmFtZV9pbmRleDsKLSAgcHJpdmF0ZSBpbnQgaW5uZXJfYWNjZXNzX2ZsYWdzOwotCi0gIC8qKgotICAgKiBJbml0aWFsaXplIGZyb20gYW5vdGhlciBvYmplY3QuCi0gICAqLwotICBwdWJsaWMgSW5uZXJDbGFzcyhJbm5lckNsYXNzIGMpIHsKLSAgICB0aGlzKGMuZ2V0SW5uZXJDbGFzc0luZGV4KCksIGMuZ2V0T3V0ZXJDbGFzc0luZGV4KCksIGMuZ2V0SW5uZXJOYW1lSW5kZXgoKSwKLSAgICAgICAgIGMuZ2V0SW5uZXJBY2Nlc3NGbGFncygpKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3Qgb2JqZWN0IGZyb20gZmlsZSBzdHJlYW0uCi0gICAqIEBwYXJhbSBmaWxlIElucHV0IHN0cmVhbQotICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0gICAqLwotICBJbm5lckNsYXNzKERhdGFJbnB1dFN0cmVhbSBmaWxlKSB0aHJvd3MgSU9FeGNlcHRpb24KLSAgewotICAgIHRoaXMoZmlsZS5yZWFkVW5zaWduZWRTaG9ydCgpLCBmaWxlLnJlYWRVbnNpZ25lZFNob3J0KCksCi0gICAgICAgICBmaWxlLnJlYWRVbnNpZ25lZFNob3J0KCksIGZpbGUucmVhZFVuc2lnbmVkU2hvcnQoKSk7Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIGlubmVyX2NsYXNzX2luZGV4IENsYXNzIGluZGV4IGluIGNvbnN0YW50IHBvb2wgb2YgaW5uZXIgY2xhc3MKLSAgICogQHBhcmFtIG91dGVyX2NsYXNzX2luZGV4IENsYXNzIGluZGV4IGluIGNvbnN0YW50IHBvb2wgb2Ygb3V0ZXIgY2xhc3MKLSAgICogQHBhcmFtIGlubmVyX25hbWVfaW5kZXggIE5hbWUgaW5kZXggaW4gY29uc3RhbnQgcG9vbCBvZiBpbm5lciBjbGFzcwotICAgKiBAcGFyYW0gaW5uZXJfYWNjZXNzX2ZsYWdzIEFjY2VzcyBmbGFncyBvZiBpbm5lciBjbGFzcwotICAgKi8KLSAgcHVibGljIElubmVyQ2xhc3MoaW50IGlubmVyX2NsYXNzX2luZGV4LCBpbnQgb3V0ZXJfY2xhc3NfaW5kZXgsCi0gICAgICAgICAgICAgICAgICAgIGludCBpbm5lcl9uYW1lX2luZGV4LCBpbnQgaW5uZXJfYWNjZXNzX2ZsYWdzKQotICB7Ci0gICAgdGhpcy5pbm5lcl9jbGFzc19pbmRleCAgPSBpbm5lcl9jbGFzc19pbmRleDsKLSAgICB0aGlzLm91dGVyX2NsYXNzX2luZGV4ICA9IG91dGVyX2NsYXNzX2luZGV4OwotICAgIHRoaXMuaW5uZXJfbmFtZV9pbmRleCAgID0gaW5uZXJfbmFtZV9pbmRleDsKLSAgICB0aGlzLmlubmVyX2FjY2Vzc19mbGFncyA9IGlubmVyX2FjY2Vzc19mbGFnczsKLSAgfQotCi0gIC8qKgotICAgKiBDYWxsZWQgYnkgb2JqZWN0cyB0aGF0IGFyZSB0cmF2ZXJzaW5nIHRoZSBub2RlcyBvZiB0aGUgdHJlZSBpbXBsaWNpdGVseQotICAgKiBkZWZpbmVkIGJ5IHRoZSBjb250ZW50cyBvZiBhIEphdmEgY2xhc3MuIEkuZS4sIHRoZSBoaWVyYXJjaHkgb2YgbWV0aG9kcywKLSAgICogZmllbGRzLCBhdHRyaWJ1dGVzLCBldGMuIHNwYXducyBhIHRyZWUgb2Ygb2JqZWN0cy4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0SW5uZXJDbGFzcyh0aGlzKTsKLSAgfQotICAvKioKLSAgICogRHVtcCBpbm5lciBjbGFzcyBhdHRyaWJ1dGUgdG8gZmlsZSBzdHJlYW0gaW4gYmluYXJ5IGZvcm1hdC4KLSAgICoKLSAgICogQHBhcmFtIGZpbGUgT3V0cHV0IGZpbGUgc3RyZWFtCi0gICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIGR1bXAoRGF0YU91dHB1dFN0cmVhbSBmaWxlKSB0aHJvd3MgSU9FeGNlcHRpb24KLSAgewotICAgIGZpbGUud3JpdGVTaG9ydChpbm5lcl9jbGFzc19pbmRleCk7Ci0gICAgZmlsZS53cml0ZVNob3J0KG91dGVyX2NsYXNzX2luZGV4KTsKLSAgICBmaWxlLndyaXRlU2hvcnQoaW5uZXJfbmFtZV9pbmRleCk7Ci0gICAgZmlsZS53cml0ZVNob3J0KGlubmVyX2FjY2Vzc19mbGFncyk7Ci0gIH0KLSAgLyoqCi0gICAqIEByZXR1cm4gYWNjZXNzIGZsYWdzIG9mIGlubmVyIGNsYXNzLgotICAgKi8KLSAgcHVibGljIGZpbmFsIGludCBnZXRJbm5lckFjY2Vzc0ZsYWdzKCkgeyByZXR1cm4gaW5uZXJfYWNjZXNzX2ZsYWdzOyB9Ci0gIC8qKgotICAgKiBAcmV0dXJuIGNsYXNzIGluZGV4IG9mIGlubmVyIGNsYXNzLgotICAgKi8KLSAgcHVibGljIGZpbmFsIGludCBnZXRJbm5lckNsYXNzSW5kZXgoKSB7IHJldHVybiBpbm5lcl9jbGFzc19pbmRleDsgfQotICAvKioKLSAgICogQHJldHVybiBuYW1lIGluZGV4IG9mIGlubmVyIGNsYXNzLgotICAgKi8KLSAgcHVibGljIGZpbmFsIGludCBnZXRJbm5lck5hbWVJbmRleCgpIHsgcmV0dXJuIGlubmVyX25hbWVfaW5kZXg7IH0KLSAgLyoqCi0gICAqIEByZXR1cm4gY2xhc3MgaW5kZXggb2Ygb3V0ZXIgY2xhc3MuCi0gICAqLwotICBwdWJsaWMgZmluYWwgaW50IGdldE91dGVyQ2xhc3NJbmRleCgpIHsgcmV0dXJuIG91dGVyX2NsYXNzX2luZGV4OyB9Ci0gIC8qKgotICAgKiBAcGFyYW0gaW5uZXJfYWNjZXNzX2ZsYWdzLgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgc2V0SW5uZXJBY2Nlc3NGbGFncyhpbnQgaW5uZXJfYWNjZXNzX2ZsYWdzKSB7Ci0gICAgdGhpcy5pbm5lcl9hY2Nlc3NfZmxhZ3MgPSBpbm5lcl9hY2Nlc3NfZmxhZ3M7Ci0gIH0KLSAgLyoqCi0gICAqIEBwYXJhbSBpbm5lcl9jbGFzc19pbmRleC4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHNldElubmVyQ2xhc3NJbmRleChpbnQgaW5uZXJfY2xhc3NfaW5kZXgpIHsKLSAgICB0aGlzLmlubmVyX2NsYXNzX2luZGV4ID0gaW5uZXJfY2xhc3NfaW5kZXg7Ci0gIH0KLSAgLyoqCi0gICAqIEBwYXJhbSBpbm5lcl9uYW1lX2luZGV4LgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgc2V0SW5uZXJOYW1lSW5kZXgoaW50IGlubmVyX25hbWVfaW5kZXgpIHsKLSAgICB0aGlzLmlubmVyX25hbWVfaW5kZXggPSBpbm5lcl9uYW1lX2luZGV4OwotICB9Ci0gIC8qKgotICAgKiBAcGFyYW0gb3V0ZXJfY2xhc3NfaW5kZXguCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBzZXRPdXRlckNsYXNzSW5kZXgoaW50IG91dGVyX2NsYXNzX2luZGV4KSB7Ci0gICAgdGhpcy5vdXRlcl9jbGFzc19pbmRleCA9IG91dGVyX2NsYXNzX2luZGV4OwotICB9Ci0gIC8qKgotICAgKiBAcmV0dXJuIFN0cmluZyByZXByZXNlbnRhdGlvbi4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0gICAgcmV0dXJuICJJbm5lckNsYXNzKCIgKyBpbm5lcl9jbGFzc19pbmRleCArICIsICIgKyBvdXRlcl9jbGFzc19pbmRleCArCi0gICAgICAiLCAiICsgaW5uZXJfbmFtZV9pbmRleCArICIsICIgKyBpbm5lcl9hY2Nlc3NfZmxhZ3MgKyAiKSI7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBSZXNvbHZlZCBzdHJpbmcgcmVwcmVzZW50YXRpb24KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBTdHJpbmcgdG9TdHJpbmcoQ29uc3RhbnRQb29sIGNvbnN0YW50X3Bvb2wpIHsKLSAgICBTdHJpbmcgaW5uZXJfY2xhc3NfbmFtZSwgb3V0ZXJfY2xhc3NfbmFtZSwgaW5uZXJfbmFtZSwgYWNjZXNzOwotCi0gICAgaW5uZXJfY2xhc3NfbmFtZSA9IGNvbnN0YW50X3Bvb2wuZ2V0Q29uc3RhbnRTdHJpbmcoaW5uZXJfY2xhc3NfaW5kZXgsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29uc3RhbnRzLkNPTlNUQU5UX0NsYXNzKTsKLSAgICBpbm5lcl9jbGFzc19uYW1lID0gVXRpbGl0eS5jb21wYWN0Q2xhc3NOYW1lKGlubmVyX2NsYXNzX25hbWUpOwotCi0gICAgaWYgKG91dGVyX2NsYXNzX2luZGV4ICE9IDApIHsKLSAgICAgIG91dGVyX2NsYXNzX25hbWUgPSBjb25zdGFudF9wb29sLmdldENvbnN0YW50U3RyaW5nKG91dGVyX2NsYXNzX2luZGV4LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29uc3RhbnRzLkNPTlNUQU5UX0NsYXNzKTsKLSAgICAgIG91dGVyX2NsYXNzX25hbWUgPSBVdGlsaXR5LmNvbXBhY3RDbGFzc05hbWUob3V0ZXJfY2xhc3NfbmFtZSk7Ci0gICAgfQotICAgIGVsc2UKLSAgICAgIG91dGVyX2NsYXNzX25hbWUgPSAiPG5vdCBhIG1lbWJlcj4iOwotCi0gICAgaWYoaW5uZXJfbmFtZV9pbmRleCAhPSAwKQotICAgICAgaW5uZXJfbmFtZSA9ICgoQ29uc3RhbnRVdGY4KWNvbnN0YW50X3Bvb2wuCi0gICAgICAgICAgICAgICAgICAgIGdldENvbnN0YW50KGlubmVyX25hbWVfaW5kZXgsIENvbnN0YW50cy5DT05TVEFOVF9VdGY4KSkuZ2V0Qnl0ZXMoKTsKLSAgICBlbHNlCi0gICAgICBpbm5lcl9uYW1lID0gIjxhbm9ueW1vdXM+IjsKLQotICAgIGFjY2VzcyA9IFV0aWxpdHkuYWNjZXNzVG9TdHJpbmcoaW5uZXJfYWNjZXNzX2ZsYWdzLCB0cnVlKTsKLSAgICBhY2Nlc3MgPSBhY2Nlc3MuZXF1YWxzKCIiKT8gIiIgOiAoYWNjZXNzICsgIiAiKTsKLQotICAgIHJldHVybiAiSW5uZXJDbGFzczoiICsgYWNjZXNzICsgaW5uZXJfY2xhc3NfbmFtZSArCi0gICAgICAiKFwiIiArIG91dGVyX2NsYXNzX25hbWUgKyAiXCIsIFwiIiArIGlubmVyX25hbWUgKyAiXCIpIjsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIGRlZXAgY29weSBvZiB0aGlzIG9iamVjdAotICAgKi8KLSAgcHVibGljIElubmVyQ2xhc3MgY29weSgpIHsKLSAgICB0cnkgewotICAgICAgcmV0dXJuIChJbm5lckNsYXNzKWNsb25lKCk7Ci0gICAgfSBjYXRjaChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKSB7fQotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvSW5uZXJDbGFzc2VzLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvY2xhc3NmaWxlL0lubmVyQ2xhc3Nlcy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkYTMyMDM2Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvSW5uZXJDbGFzc2VzLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxODQgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuY2xhc3NmaWxlOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi1pbXBvcnQgIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50czsKLWltcG9ydCAgamF2YS5pby4qOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgaXMgZGVyaXZlZCBmcm9tIDxlbT5BdHRyaWJ1dGU8L2VtPiBhbmQgZGVub3RlcyB0aGF0IHRoaXMgY2xhc3MKLSAqIGlzIGFuIElubmVyIGNsYXNzIG9mIGFub3RoZXIuCi0gKiB0byB0aGUgc291cmNlIGZpbGUgb2YgdGhpcyBjbGFzcy4KLSAqIEl0IGlzIGluc3RhbnRpYXRlZCBmcm9tIHRoZSA8ZW0+QXR0cmlidXRlLnJlYWRBdHRyaWJ1dGUoKTwvZW0+IG1ldGhvZC4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICogQHNlZSAgICAgQXR0cmlidXRlCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBJbm5lckNsYXNzZXMgZXh0ZW5kcyBBdHRyaWJ1dGUgewotICBwcml2YXRlIElubmVyQ2xhc3NbXSBpbm5lcl9jbGFzc2VzOwotICBwcml2YXRlIGludCAgICAgICAgICBudW1iZXJfb2ZfY2xhc3NlczsKLQotICAvKioKLSAgICogSW5pdGlhbGl6ZSBmcm9tIGFub3RoZXIgb2JqZWN0LiBOb3RlIHRoYXQgYm90aCBvYmplY3RzIHVzZSB0aGUgc2FtZQotICAgKiByZWZlcmVuY2VzIChzaGFsbG93IGNvcHkpLiBVc2UgY2xvbmUoKSBmb3IgYSBwaHlzaWNhbCBjb3B5LgotICAgKi8KLSAgcHVibGljIElubmVyQ2xhc3NlcyhJbm5lckNsYXNzZXMgYykgewotICAgIHRoaXMoYy5nZXROYW1lSW5kZXgoKSwgYy5nZXRMZW5ndGgoKSwgYy5nZXRJbm5lckNsYXNzZXMoKSwKLSAgICAgICAgIGMuZ2V0Q29uc3RhbnRQb29sKCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBuYW1lX2luZGV4IEluZGV4IGluIGNvbnN0YW50IHBvb2wgdG8gQ09OU1RBTlRfVXRmOAotICAgKiBAcGFyYW0gbGVuZ3RoIENvbnRlbnQgbGVuZ3RoIGluIGJ5dGVzCi0gICAqIEBwYXJhbSBpbm5lcl9jbGFzc2VzIGFycmF5IG9mIGlubmVyIGNsYXNzZXMgYXR0cmlidXRlcwotICAgKiBAcGFyYW0gY29uc3RhbnRfcG9vbCBBcnJheSBvZiBjb25zdGFudHMKLSAgICogQHBhcmFtIHNvdXJjZWZpbGVfaW5kZXggSW5kZXggaW4gY29uc3RhbnQgcG9vbCB0byBDT05TVEFOVF9VdGY4Ci0gICAqLwotICBwdWJsaWMgSW5uZXJDbGFzc2VzKGludCBuYW1lX2luZGV4LCBpbnQgbGVuZ3RoLAotICAgICAgICAgICAgICAgICAgICAgIElubmVyQ2xhc3NbXSBpbm5lcl9jbGFzc2VzLAotICAgICAgICAgICAgICAgICAgICAgIENvbnN0YW50UG9vbCBjb25zdGFudF9wb29sKQotICB7Ci0gICAgc3VwZXIoQ29uc3RhbnRzLkFUVFJfSU5ORVJfQ0xBU1NFUywgbmFtZV9pbmRleCwgbGVuZ3RoLCBjb25zdGFudF9wb29sKTsKLSAgICBzZXRJbm5lckNsYXNzZXMoaW5uZXJfY2xhc3Nlcyk7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IG9iamVjdCBmcm9tIGZpbGUgc3RyZWFtLgotICAgKgotICAgKiBAcGFyYW0gbmFtZV9pbmRleCBJbmRleCBpbiBjb25zdGFudCBwb29sIHRvIENPTlNUQU5UX1V0ZjgKLSAgICogQHBhcmFtIGxlbmd0aCBDb250ZW50IGxlbmd0aCBpbiBieXRlcwotICAgKiBAcGFyYW0gZmlsZSBJbnB1dCBzdHJlYW0KLSAgICogQHBhcmFtIGNvbnN0YW50X3Bvb2wgQXJyYXkgb2YgY29uc3RhbnRzCi0gICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLSAgICovCi0gIElubmVyQ2xhc3NlcyhpbnQgbmFtZV9pbmRleCwgaW50IGxlbmd0aCwgRGF0YUlucHV0U3RyZWFtIGZpbGUsCi0gICAgICAgICAgICAgICBDb25zdGFudFBvb2wgY29uc3RhbnRfcG9vbCkgdGhyb3dzIElPRXhjZXB0aW9uCi0gIHsKLSAgICB0aGlzKG5hbWVfaW5kZXgsIGxlbmd0aCwgKElubmVyQ2xhc3NbXSludWxsLCBjb25zdGFudF9wb29sKTsKLQotICAgIG51bWJlcl9vZl9jbGFzc2VzID0gZmlsZS5yZWFkVW5zaWduZWRTaG9ydCgpOwotICAgIGlubmVyX2NsYXNzZXMgPSBuZXcgSW5uZXJDbGFzc1tudW1iZXJfb2ZfY2xhc3Nlc107Ci0KLSAgICBmb3IoaW50IGk9MDsgaSA8IG51bWJlcl9vZl9jbGFzc2VzOyBpKyspCi0gICAgICBpbm5lcl9jbGFzc2VzW2ldID0gbmV3IElubmVyQ2xhc3MoZmlsZSk7Ci0gIH0KLSAgLyoqCi0gICAqIENhbGxlZCBieSBvYmplY3RzIHRoYXQgYXJlIHRyYXZlcnNpbmcgdGhlIG5vZGVzIG9mIHRoZSB0cmVlIGltcGxpY2l0ZWx5Ci0gICAqIGRlZmluZWQgYnkgdGhlIGNvbnRlbnRzIG9mIGEgSmF2YSBjbGFzcy4gSS5lLiwgdGhlIGhpZXJhcmNoeSBvZiBtZXRob2RzLAotICAgKiBmaWVsZHMsIGF0dHJpYnV0ZXMsIGV0Yy4gc3Bhd25zIGEgdHJlZSBvZiBvYmplY3RzLgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRJbm5lckNsYXNzZXModGhpcyk7Ci0gIH0KLSAgLyoqCi0gICAqIER1bXAgc291cmNlIGZpbGUgYXR0cmlidXRlIHRvIGZpbGUgc3RyZWFtIGluIGJpbmFyeSBmb3JtYXQuCi0gICAqCi0gICAqIEBwYXJhbSBmaWxlIE91dHB1dCBmaWxlIHN0cmVhbQotICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBkdW1wKERhdGFPdXRwdXRTdHJlYW0gZmlsZSkgdGhyb3dzIElPRXhjZXB0aW9uCi0gIHsKLSAgICBzdXBlci5kdW1wKGZpbGUpOwotICAgIGZpbGUud3JpdGVTaG9ydChudW1iZXJfb2ZfY2xhc3Nlcyk7Ci0KLSAgICBmb3IoaW50IGk9MDsgaSA8IG51bWJlcl9vZl9jbGFzc2VzOyBpKyspCi0gICAgICBpbm5lcl9jbGFzc2VzW2ldLmR1bXAoZmlsZSk7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBhcnJheSBvZiBpbm5lciBjbGFzcyAicmVjb3JkcyIKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBJbm5lckNsYXNzW10gZ2V0SW5uZXJDbGFzc2VzKCkgeyByZXR1cm4gaW5uZXJfY2xhc3NlczsgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gaW5uZXJfY2xhc3Nlcy4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHNldElubmVyQ2xhc3NlcyhJbm5lckNsYXNzW10gaW5uZXJfY2xhc3NlcykgewotICAgIHRoaXMuaW5uZXJfY2xhc3NlcyA9IGlubmVyX2NsYXNzZXM7Ci0gICAgbnVtYmVyX29mX2NsYXNzZXMgPSAoaW5uZXJfY2xhc3NlcyA9PSBudWxsKT8gMCA6IGlubmVyX2NsYXNzZXMubGVuZ3RoOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gU3RyaW5nIHJlcHJlc2VudGF0aW9uLgotICAgKi8KLSAgcHVibGljIGZpbmFsIFN0cmluZyB0b1N0cmluZygpIHsKLSAgICBTdHJpbmdCdWZmZXIgYnVmID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotCi0gICAgZm9yKGludCBpPTA7IGkgPCBudW1iZXJfb2ZfY2xhc3NlczsgaSsrKQotICAgICAgYnVmLmFwcGVuZChpbm5lcl9jbGFzc2VzW2ldLnRvU3RyaW5nKGNvbnN0YW50X3Bvb2wpICsgIlxuIik7Ci0KLSAgICByZXR1cm4gYnVmLnRvU3RyaW5nKCk7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBkZWVwIGNvcHkgb2YgdGhpcyBhdHRyaWJ1dGUKLSAgICovCi0gIHB1YmxpYyBBdHRyaWJ1dGUgY29weShDb25zdGFudFBvb2wgY29uc3RhbnRfcG9vbCkgewotICAgIElubmVyQ2xhc3NlcyBjID0gKElubmVyQ2xhc3NlcyljbG9uZSgpOwotCi0gICAgYy5pbm5lcl9jbGFzc2VzID0gbmV3IElubmVyQ2xhc3NbbnVtYmVyX29mX2NsYXNzZXNdOwotICAgIGZvcihpbnQgaT0wOyBpIDwgbnVtYmVyX29mX2NsYXNzZXM7IGkrKykKLSAgICAgIGMuaW5uZXJfY2xhc3Nlc1tpXSA9IGlubmVyX2NsYXNzZXNbaV0uY29weSgpOwotCi0gICAgYy5jb25zdGFudF9wb29sID0gY29uc3RhbnRfcG9vbDsKLSAgICByZXR1cm4gYzsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2NsYXNzZmlsZS9KYXZhQ2xhc3MuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvSmF2YUNsYXNzLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDRkMjhmMmEuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2NsYXNzZmlsZS9KYXZhQ2xhc3MuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDgyNiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5jbGFzc2ZpbGU7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLWltcG9ydCAgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzOwotaW1wb3J0ICBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC51dGlsLlN5bnRoZXRpY1JlcG9zaXRvcnk7Ci1pbXBvcnQgIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLnV0aWwuQ2xhc3NWZWN0b3I7Ci1pbXBvcnQgIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLnV0aWwuQ2xhc3NRdWV1ZTsKLWltcG9ydCAgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5UeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC51dGlscy5TZWN1cml0eVN1cHBvcnQ7Ci0KLWltcG9ydCAgamF2YS5pby4qOwotaW1wb3J0ICBqYXZhLnV0aWwuU3RyaW5nVG9rZW5pemVyOwotCi0vKioKLSAqIFJlcHJlc2VudHMgYSBKYXZhIGNsYXNzLCBpLmUuLCB0aGUgZGF0YSBzdHJ1Y3R1cmVzLCBjb25zdGFudCBwb29sLAotICogZmllbGRzLCBtZXRob2RzIGFuZCBjb21tYW5kcyBjb250YWluZWQgaW4gYSBKYXZhIC5jbGFzcyBmaWxlLgotICogU2VlIDxhIGhyZWY9ImZ0cDovL2phdmEuc3VuLmNvbS9kb2NzL3NwZWNzLyI+SlZNCi0gKiBzcGVjaWZpY2F0aW9uPC9hPiBmb3IgZGV0YWlscy4KLQotICogVGhlIGludGVudCBvZiB0aGlzIGNsYXNzIGlzIHRvIHJlcHJlc2VudCBhIHBhcnNlZCBvciBvdGhlcndpc2UgZXhpc3RpbmcKLSAqIGNsYXNzIGZpbGUuICBUaG9zZSBpbnRlcmVzdGVkIGluIHByb2dyYW1hdGljYWxseSBnZW5lcmF0aW5nIGNsYXNzZXMKLSAqIHNob3VsZCBzZWUgdGhlIDxhIGhyZWY9Ii4uL2dlbmVyaWMvQ2xhc3NHZW4uaHRtbCI+Q2xhc3NHZW48L2E+IGNsYXNzLgotCi0gKiBAdmVyc2lvbiAkSWQ6IEphdmFDbGFzcy5qYXZhLHYgMS40IDIwMDctMDctMTkgMDQ6MzQ6NDIgb2Z1bmcgRXhwICQKLSAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5DbGFzc0dlbgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGNsYXNzIEphdmFDbGFzcyBleHRlbmRzIEFjY2Vzc0ZsYWdzIGltcGxlbWVudHMgQ2xvbmVhYmxlLCBOb2RlIHsKLSAgcHJpdmF0ZSBTdHJpbmcgICAgICAgZmlsZV9uYW1lOwotICBwcml2YXRlIFN0cmluZyAgICAgICBwYWNrYWdlX25hbWU7Ci0gIHByaXZhdGUgU3RyaW5nICAgICAgIHNvdXJjZV9maWxlX25hbWUgPSAiPFVua25vd24+IjsKLSAgcHJpdmF0ZSBpbnQgICAgICAgICAgY2xhc3NfbmFtZV9pbmRleDsKLSAgcHJpdmF0ZSBpbnQgICAgICAgICAgc3VwZXJjbGFzc19uYW1lX2luZGV4OwotICBwcml2YXRlIFN0cmluZyAgICAgICBjbGFzc19uYW1lOwotICBwcml2YXRlIFN0cmluZyAgICAgICBzdXBlcmNsYXNzX25hbWU7Ci0gIHByaXZhdGUgaW50ICAgICAgICAgIG1ham9yLCBtaW5vcjsgIC8vIENvbXBpbGVyIHZlcnNpb24KLSAgcHJpdmF0ZSBDb25zdGFudFBvb2wgY29uc3RhbnRfcG9vbDsgLy8gQ29uc3RhbnQgcG9vbAotICBwcml2YXRlIGludFtdICAgICAgICBpbnRlcmZhY2VzOyAgICAvLyBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzCi0gIHByaXZhdGUgU3RyaW5nW10gICAgIGludGVyZmFjZV9uYW1lczsKLSAgcHJpdmF0ZSBGaWVsZFtdICAgICAgZmllbGRzOyAgICAgICAgLy8gRmllbGRzLCBpLmUuLCB2YXJpYWJsZXMgb2YgY2xhc3MKLSAgcHJpdmF0ZSBNZXRob2RbXSAgICAgbWV0aG9kczsgICAgICAgLy8gbWV0aG9kcyBkZWZpbmVkIGluIHRoZSBjbGFzcwotICBwcml2YXRlIEF0dHJpYnV0ZVtdICBhdHRyaWJ1dGVzOyAgICAvLyBhdHRyaWJ1dGVzIGRlZmluZWQgaW4gdGhlIGNsYXNzCi0gIHByaXZhdGUgYnl0ZSAgICAgICAgIHNvdXJjZSA9IEhFQVA7IC8vIEdlbmVyYXRlZCBpbiBtZW1vcnkKLQotICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgSEVBUCA9IDE7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZSBGSUxFID0gMjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBieXRlIFpJUCAgPSAzOwotCi0gIHN0YXRpYyBib29sZWFuIGRlYnVnID0gZmFsc2U7IC8vIERlYnVnZ2luZyBvbi9vZmYKLSAgc3RhdGljIGNoYXIgICAgc2VwICAgPSAnLyc7ICAgLy8gZGlyZWN0b3J5IHNlcGFyYXRvcgotCi0gIC8qKgotICAgKiBJbiBjYXNlcyB3aGVyZSB3ZSBnbyBhaGVhZCBhbmQgY3JlYXRlIHNvbWV0aGluZywKLSAgICogdXNlIHRoZSBkZWZhdWx0IFN5bnRoZXRpY1JlcG9zaXRvcnksIGJlY2F1c2Ugd2UKLSAgICogZG9uJ3Qga25vdyBhbnkgYmV0dGVyLgotICAgKi8KLSAgcHJpdmF0ZSB0cmFuc2llbnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwudXRpbC5SZXBvc2l0b3J5IHJlcG9zaXRvcnkgPQotICAgIFN5bnRoZXRpY1JlcG9zaXRvcnkuZ2V0SW5zdGFuY2UoKTsKLQotICAvKioKLSAgICogQ29uc3RydWN0b3IgZ2V0cyBhbGwgY29udGVudHMgYXMgYXJndW1lbnRzLgotICAgKgotICAgKiBAcGFyYW0gY2xhc3NfbmFtZV9pbmRleCBJbmRleCBpbnRvIGNvbnN0YW50IHBvb2wgcmVmZXJlbmNpbmcgYQotICAgKiBDb25zdGFudENsYXNzIHRoYXQgcmVwcmVzZW50cyB0aGlzIGNsYXNzLgotICAgKiBAcGFyYW0gc3VwZXJjbGFzc19uYW1lX2luZGV4IEluZGV4IGludG8gY29uc3RhbnQgcG9vbCByZWZlcmVuY2luZyBhCi0gICAqIENvbnN0YW50Q2xhc3MgdGhhdCByZXByZXNlbnRzIHRoaXMgY2xhc3MncyBzdXBlcmNsYXNzLgotICAgKiBAcGFyYW0gZmlsZV9uYW1lIEZpbGUgbmFtZQotICAgKiBAcGFyYW0gbWFqb3IgTWFqb3IgY29tcGlsZXIgdmVyc2lvbgotICAgKiBAcGFyYW0gbWlub3IgTWlub3IgY29tcGlsZXIgdmVyc2lvbgotICAgKiBAcGFyYW0gYWNjZXNzX2ZsYWdzIEFjY2VzcyByaWdodHMgZGVmaW5lZCBieSBiaXQgZmxhZ3MKLSAgICogQHBhcmFtIGNvbnN0YW50X3Bvb2wgQXJyYXkgb2YgY29uc3RhbnRzCi0gICAqIEBwYXJhbSBpbnRlcmZhY2VzIEltcGxlbWVudGVkIGludGVyZmFjZXMKLSAgICogQHBhcmFtIGZpZWxkcyBDbGFzcyBmaWVsZHMKLSAgICogQHBhcmFtIG1ldGhvZHMgQ2xhc3MgbWV0aG9kcwotICAgKiBAcGFyYW0gYXR0cmlidXRlcyBDbGFzcyBhdHRyaWJ1dGVzCi0gICAqIEBwYXJhbSBzb3VyY2UgUmVhZCBmcm9tIGZpbGUgb3IgZ2VuZXJhdGVkIGluIG1lbW9yeT8KLSAgICovCi0gIHB1YmxpYyBKYXZhQ2xhc3MoaW50ICAgICAgICBjbGFzc19uYW1lX2luZGV4LAotICAgICAgICAgICAgICAgICAgIGludCAgICAgICAgc3VwZXJjbGFzc19uYW1lX2luZGV4LAotICAgICAgICAgICAgICAgICAgIFN0cmluZyAgICAgZmlsZV9uYW1lLAotICAgICAgICAgICAgICAgICAgIGludCAgICAgICAgbWFqb3IsCi0gICAgICAgICAgICAgICAgICAgaW50ICAgICAgICBtaW5vciwKLSAgICAgICAgICAgICAgICAgICBpbnQgICAgICAgIGFjY2Vzc19mbGFncywKLSAgICAgICAgICAgICAgICAgICBDb25zdGFudFBvb2wgY29uc3RhbnRfcG9vbCwKLSAgICAgICAgICAgICAgICAgICBpbnRbXSAgICAgIGludGVyZmFjZXMsCi0gICAgICAgICAgICAgICAgICAgRmllbGRbXSAgICAgIGZpZWxkcywKLSAgICAgICAgICAgICAgICAgICBNZXRob2RbXSAgICAgbWV0aG9kcywKLSAgICAgICAgICAgICAgICAgICBBdHRyaWJ1dGVbXSAgYXR0cmlidXRlcywKLSAgICAgICAgICAgICAgICAgICBieXRlICAgICAgICAgIHNvdXJjZSkKLSAgewotICAgIGlmKGludGVyZmFjZXMgPT0gbnVsbCkgLy8gQWxsb3dlZCBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eQotICAgICAgaW50ZXJmYWNlcyA9IG5ldyBpbnRbMF07Ci0gICAgaWYoYXR0cmlidXRlcyA9PSBudWxsKQotICAgICAgdGhpcy5hdHRyaWJ1dGVzID0gbmV3IEF0dHJpYnV0ZVswXTsKLSAgICBpZihmaWVsZHMgPT0gbnVsbCkKLSAgICAgIGZpZWxkcyA9IG5ldyBGaWVsZFswXTsKLSAgICBpZihtZXRob2RzID09IG51bGwpCi0gICAgICBtZXRob2RzID0gbmV3IE1ldGhvZFswXTsKLQotICAgIHRoaXMuY2xhc3NfbmFtZV9pbmRleCAgICAgID0gY2xhc3NfbmFtZV9pbmRleDsKLSAgICB0aGlzLnN1cGVyY2xhc3NfbmFtZV9pbmRleCA9IHN1cGVyY2xhc3NfbmFtZV9pbmRleDsKLSAgICB0aGlzLmZpbGVfbmFtZSAgICAgICAgICAgICA9IGZpbGVfbmFtZTsKLSAgICB0aGlzLm1ham9yICAgICAgICAgICAgICAgICA9IG1ham9yOwotICAgIHRoaXMubWlub3IgICAgICAgICAgICAgICAgID0gbWlub3I7Ci0gICAgdGhpcy5hY2Nlc3NfZmxhZ3MgICAgICAgICAgPSBhY2Nlc3NfZmxhZ3M7Ci0gICAgdGhpcy5jb25zdGFudF9wb29sICAgICAgICAgPSBjb25zdGFudF9wb29sOwotICAgIHRoaXMuaW50ZXJmYWNlcyAgICAgICAgICAgID0gaW50ZXJmYWNlczsKLSAgICB0aGlzLmZpZWxkcyAgICAgICAgICAgICAgICA9IGZpZWxkczsKLSAgICB0aGlzLm1ldGhvZHMgICAgICAgICAgICAgICA9IG1ldGhvZHM7Ci0gICAgdGhpcy5hdHRyaWJ1dGVzICAgICAgICAgICAgPSBhdHRyaWJ1dGVzOwotICAgIHRoaXMuc291cmNlICAgICAgICAgICAgICAgID0gc291cmNlOwotCi0gICAgLy8gR2V0IHNvdXJjZSBmaWxlIG5hbWUgaWYgYXZhaWxhYmxlCi0gICAgZm9yKGludCBpPTA7IGkgPCBhdHRyaWJ1dGVzLmxlbmd0aDsgaSsrKSB7Ci0gICAgICBpZihhdHRyaWJ1dGVzW2ldIGluc3RhbmNlb2YgU291cmNlRmlsZSkgewotICAgICAgICBzb3VyY2VfZmlsZV9uYW1lID0gKChTb3VyY2VGaWxlKWF0dHJpYnV0ZXNbaV0pLmdldFNvdXJjZUZpbGVOYW1lKCk7Ci0gICAgICAgIGJyZWFrOwotICAgICAgfQotICAgIH0KLQotICAgIC8qIEFjY29yZGluZyB0byB0aGUgc3BlY2lmaWNhdGlvbiB0aGUgZm9sbG93aW5nIGVudHJpZXMgbXVzdCBiZSBvZiB0eXBlCi0gICAgICogYENvbnN0YW50Q2xhc3MnIGJ1dCB3ZSBjaGVjayB0aGF0IGFueXdheSB2aWEgdGhlCi0gICAgICogYENvbnN0UG9vbC5nZXRDb25zdGFudCcgbWV0aG9kLgotICAgICAqLwotICAgIGNsYXNzX25hbWUgPSBjb25zdGFudF9wb29sLmdldENvbnN0YW50U3RyaW5nKGNsYXNzX25hbWVfaW5kZXgsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29uc3RhbnRzLkNPTlNUQU5UX0NsYXNzKTsKLSAgICBjbGFzc19uYW1lID0gVXRpbGl0eS5jb21wYWN0Q2xhc3NOYW1lKGNsYXNzX25hbWUsIGZhbHNlKTsKLQotICAgIGludCBpbmRleCA9IGNsYXNzX25hbWUubGFzdEluZGV4T2YoJy4nKTsKLSAgICBpZihpbmRleCA8IDApCi0gICAgICBwYWNrYWdlX25hbWUgPSAiIjsKLSAgICBlbHNlCi0gICAgICBwYWNrYWdlX25hbWUgPSBjbGFzc19uYW1lLnN1YnN0cmluZygwLCBpbmRleCk7Ci0KLSAgICBpZihzdXBlcmNsYXNzX25hbWVfaW5kZXggPiAwKSB7IC8vIE1heSBiZSB6ZXJvIC0+IGNsYXNzIGlzIGphdmEubGFuZy5PYmplY3QKLSAgICAgIHN1cGVyY2xhc3NfbmFtZSA9IGNvbnN0YW50X3Bvb2wuZ2V0Q29uc3RhbnRTdHJpbmcoc3VwZXJjbGFzc19uYW1lX2luZGV4LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb25zdGFudHMuQ09OU1RBTlRfQ2xhc3MpOwotICAgICAgc3VwZXJjbGFzc19uYW1lID0gVXRpbGl0eS5jb21wYWN0Q2xhc3NOYW1lKHN1cGVyY2xhc3NfbmFtZSwgZmFsc2UpOwotICAgIH0KLSAgICBlbHNlCi0gICAgICBzdXBlcmNsYXNzX25hbWUgPSAiamF2YS5sYW5nLk9iamVjdCI7Ci0KLSAgICBpbnRlcmZhY2VfbmFtZXMgPSBuZXcgU3RyaW5nW2ludGVyZmFjZXMubGVuZ3RoXTsKLSAgICBmb3IoaW50IGk9MDsgaSA8IGludGVyZmFjZXMubGVuZ3RoOyBpKyspIHsKLSAgICAgIFN0cmluZyBzdHIgPSBjb25zdGFudF9wb29sLmdldENvbnN0YW50U3RyaW5nKGludGVyZmFjZXNbaV0sIENvbnN0YW50cy5DT05TVEFOVF9DbGFzcyk7Ci0gICAgICBpbnRlcmZhY2VfbmFtZXNbaV0gPSBVdGlsaXR5LmNvbXBhY3RDbGFzc05hbWUoc3RyLCBmYWxzZSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdG9yIGdldHMgYWxsIGNvbnRlbnRzIGFzIGFyZ3VtZW50cy4KLSAgICoKLSAgICogQHBhcmFtIGNsYXNzX25hbWVfaW5kZXggQ2xhc3MgbmFtZQotICAgKiBAcGFyYW0gc3VwZXJjbGFzc19uYW1lX2luZGV4IFN1cGVyY2xhc3MgbmFtZQotICAgKiBAcGFyYW0gZmlsZV9uYW1lIEZpbGUgbmFtZQotICAgKiBAcGFyYW0gbWFqb3IgTWFqb3IgY29tcGlsZXIgdmVyc2lvbgotICAgKiBAcGFyYW0gbWlub3IgTWlub3IgY29tcGlsZXIgdmVyc2lvbgotICAgKiBAcGFyYW0gYWNjZXNzX2ZsYWdzIEFjY2VzcyByaWdodHMgZGVmaW5lZCBieSBiaXQgZmxhZ3MKLSAgICogQHBhcmFtIGNvbnN0YW50X3Bvb2wgQXJyYXkgb2YgY29uc3RhbnRzCi0gICAqIEBwYXJhbSBpbnRlcmZhY2VzIEltcGxlbWVudGVkIGludGVyZmFjZXMKLSAgICogQHBhcmFtIGZpZWxkcyBDbGFzcyBmaWVsZHMKLSAgICogQHBhcmFtIG1ldGhvZHMgQ2xhc3MgbWV0aG9kcwotICAgKiBAcGFyYW0gYXR0cmlidXRlcyBDbGFzcyBhdHRyaWJ1dGVzCi0gICAqLwotICBwdWJsaWMgSmF2YUNsYXNzKGludCAgICAgICAgY2xhc3NfbmFtZV9pbmRleCwKLSAgICAgICAgICAgICAgICAgICBpbnQgICAgICAgIHN1cGVyY2xhc3NfbmFtZV9pbmRleCwKLSAgICAgICAgICAgICAgICAgICBTdHJpbmcgICAgIGZpbGVfbmFtZSwKLSAgICAgICAgICAgICAgICAgICBpbnQgICAgICAgIG1ham9yLAotICAgICAgICAgICAgICAgICAgIGludCAgICAgICAgbWlub3IsCi0gICAgICAgICAgICAgICAgICAgaW50ICAgICAgICBhY2Nlc3NfZmxhZ3MsCi0gICAgICAgICAgICAgICAgICAgQ29uc3RhbnRQb29sIGNvbnN0YW50X3Bvb2wsCi0gICAgICAgICAgICAgICAgICAgaW50W10gICAgICBpbnRlcmZhY2VzLAotICAgICAgICAgICAgICAgICAgIEZpZWxkW10gICAgICBmaWVsZHMsCi0gICAgICAgICAgICAgICAgICAgTWV0aG9kW10gICAgIG1ldGhvZHMsCi0gICAgICAgICAgICAgICAgICAgQXR0cmlidXRlW10gIGF0dHJpYnV0ZXMpIHsKLSAgICB0aGlzKGNsYXNzX25hbWVfaW5kZXgsIHN1cGVyY2xhc3NfbmFtZV9pbmRleCwgZmlsZV9uYW1lLCBtYWpvciwgbWlub3IsIGFjY2Vzc19mbGFncywKLSAgICAgICAgIGNvbnN0YW50X3Bvb2wsIGludGVyZmFjZXMsIGZpZWxkcywgbWV0aG9kcywgYXR0cmlidXRlcywgSEVBUCk7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBDYWxsZWQgYnkgb2JqZWN0cyB0aGF0IGFyZSB0cmF2ZXJzaW5nIHRoZSBub2RlcyBvZiB0aGUgdHJlZSBpbXBsaWNpdGVseQotICAgKiBkZWZpbmVkIGJ5IHRoZSBjb250ZW50cyBvZiBhIEphdmEgY2xhc3MuIEkuZS4sIHRoZSBoaWVyYXJjaHkgb2YgbWV0aG9kcywKLSAgICogZmllbGRzLCBhdHRyaWJ1dGVzLCBldGMuIHNwYXducyBhIHRyZWUgb2Ygb2JqZWN0cy4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0SmF2YUNsYXNzKHRoaXMpOwotICB9Ci0KLSAgLyogUHJpbnQgZGVidWcgaW5mb3JtYXRpb24gZGVwZW5kaW5nIG9uIGBKYXZhQ2xhc3MuZGVidWcnCi0gICAqLwotICBzdGF0aWMgZmluYWwgdm9pZCBEZWJ1ZyhTdHJpbmcgc3RyKSB7Ci0gICAgaWYoZGVidWcpCi0gICAgICBTeXN0ZW0ub3V0LnByaW50bG4oc3RyKTsKLSAgfQotCi0gIC8qKgotICAgKiBEdW1wIGNsYXNzIHRvIGEgZmlsZS4KLSAgICoKLSAgICogQHBhcmFtIGZpbGUgT3V0cHV0IGZpbGUKLSAgICogQHRocm93cyBJT0V4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgZHVtcChGaWxlIGZpbGUpIHRocm93cyBJT0V4Y2VwdGlvbgotICB7Ci0gICAgU3RyaW5nIHBhcmVudCA9IGZpbGUuZ2V0UGFyZW50KCk7Ci0KLSAgICBpZihwYXJlbnQgIT0gbnVsbCkgewotICAgICAgRmlsZSBkaXIgPSBuZXcgRmlsZShwYXJlbnQpOwotCi0gICAgICBpZihkaXIgIT0gbnVsbCkKLSAgICAgICAgZGlyLm1rZGlycygpOwotICAgIH0KLQotICAgIGR1bXAobmV3IERhdGFPdXRwdXRTdHJlYW0obmV3IEZpbGVPdXRwdXRTdHJlYW0oZmlsZSkpKTsKLSAgfQotCi0gIC8qKgotICAgKiBEdW1wIGNsYXNzIHRvIGEgZmlsZSBuYW1lZCBmaWxlX25hbWUuCi0gICAqCi0gICAqIEBwYXJhbSBmaWxlX25hbWUgT3V0cHV0IGZpbGUgbmFtZQotICAgKiBAZXhjZXB0aW9uIElPRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBkdW1wKFN0cmluZyBmaWxlX25hbWUpIHRocm93cyBJT0V4Y2VwdGlvbgotICB7Ci0gICAgZHVtcChuZXcgRmlsZShmaWxlX25hbWUpKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIGNsYXNzIGluIGJpbmFyeSBmb3JtYXQKLSAgICovCi0gIHB1YmxpYyBieXRlW10gZ2V0Qnl0ZXMoKSB7Ci0gICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIHMgID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOwotICAgIERhdGFPdXRwdXRTdHJlYW0gICAgICBkcyA9IG5ldyBEYXRhT3V0cHV0U3RyZWFtKHMpOwotCi0gICAgdHJ5IHsKLSAgICAgIGR1bXAoZHMpOwotICAgIH0gY2F0Y2goSU9FeGNlcHRpb24gZSkgewotICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKLSAgICB9IGZpbmFsbHkgewotICAgICAgdHJ5IHsgZHMuY2xvc2UoKTsgfSBjYXRjaChJT0V4Y2VwdGlvbiBlMikgeyBlMi5wcmludFN0YWNrVHJhY2UoKTsgfQotICAgIH0KLQotICAgIHJldHVybiBzLnRvQnl0ZUFycmF5KCk7Ci0gIH0KLQotICAvKioKLSAgICogRHVtcCBKYXZhIGNsYXNzIHRvIG91dHB1dCBzdHJlYW0gaW4gYmluYXJ5IGZvcm1hdC4KLSAgICoKLSAgICogQHBhcmFtIGZpbGUgT3V0cHV0IHN0cmVhbQotICAgKiBAZXhjZXB0aW9uIElPRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBkdW1wKE91dHB1dFN0cmVhbSBmaWxlKSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgIGR1bXAobmV3IERhdGFPdXRwdXRTdHJlYW0oZmlsZSkpOwotICB9Ci0KLSAgLyoqCi0gICAqIER1bXAgSmF2YSBjbGFzcyB0byBvdXRwdXQgc3RyZWFtIGluIGJpbmFyeSBmb3JtYXQuCi0gICAqCi0gICAqIEBwYXJhbSBmaWxlIE91dHB1dCBzdHJlYW0KLSAgICogQGV4Y2VwdGlvbiBJT0V4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgZHVtcChEYXRhT3V0cHV0U3RyZWFtIGZpbGUpIHRocm93cyBJT0V4Y2VwdGlvbgotICB7Ci0gICAgZmlsZS53cml0ZUludCgweGNhZmViYWJlKTsKLSAgICBmaWxlLndyaXRlU2hvcnQobWlub3IpOwotICAgIGZpbGUud3JpdGVTaG9ydChtYWpvcik7Ci0KLSAgICBjb25zdGFudF9wb29sLmR1bXAoZmlsZSk7Ci0KLSAgICBmaWxlLndyaXRlU2hvcnQoYWNjZXNzX2ZsYWdzKTsKLSAgICBmaWxlLndyaXRlU2hvcnQoY2xhc3NfbmFtZV9pbmRleCk7Ci0gICAgZmlsZS53cml0ZVNob3J0KHN1cGVyY2xhc3NfbmFtZV9pbmRleCk7Ci0KLSAgICBmaWxlLndyaXRlU2hvcnQoaW50ZXJmYWNlcy5sZW5ndGgpOwotICAgIGZvcihpbnQgaT0wOyBpIDwgaW50ZXJmYWNlcy5sZW5ndGg7IGkrKykKLSAgICAgIGZpbGUud3JpdGVTaG9ydChpbnRlcmZhY2VzW2ldKTsKLQotICAgIGZpbGUud3JpdGVTaG9ydChmaWVsZHMubGVuZ3RoKTsKLSAgICBmb3IoaW50IGk9MDsgaSA8IGZpZWxkcy5sZW5ndGg7IGkrKykKLSAgICAgIGZpZWxkc1tpXS5kdW1wKGZpbGUpOwotCi0gICAgZmlsZS53cml0ZVNob3J0KG1ldGhvZHMubGVuZ3RoKTsKLSAgICBmb3IoaW50IGk9MDsgaSA8IG1ldGhvZHMubGVuZ3RoOyBpKyspCi0gICAgICBtZXRob2RzW2ldLmR1bXAoZmlsZSk7Ci0KLSAgICBpZihhdHRyaWJ1dGVzICE9IG51bGwpIHsKLSAgICAgIGZpbGUud3JpdGVTaG9ydChhdHRyaWJ1dGVzLmxlbmd0aCk7Ci0gICAgICBmb3IoaW50IGk9MDsgaSA8IGF0dHJpYnV0ZXMubGVuZ3RoOyBpKyspCi0gICAgICAgIGF0dHJpYnV0ZXNbaV0uZHVtcChmaWxlKTsKLSAgICB9Ci0gICAgZWxzZQotICAgICAgZmlsZS53cml0ZVNob3J0KDApOwotCi0gICAgZmlsZS5jbG9zZSgpOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gQXR0cmlidXRlcyBvZiB0aGUgY2xhc3MuCi0gICAqLwotICBwdWJsaWMgQXR0cmlidXRlW10gZ2V0QXR0cmlidXRlcygpIHsgcmV0dXJuIGF0dHJpYnV0ZXM7IH0KLQotICAvKioKLSAgICogQHJldHVybiBDbGFzcyBuYW1lLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRDbGFzc05hbWUoKSAgICAgICB7IHJldHVybiBjbGFzc19uYW1lOyB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gUGFja2FnZSBuYW1lLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRQYWNrYWdlTmFtZSgpICAgICAgIHsgcmV0dXJuIHBhY2thZ2VfbmFtZTsgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIENsYXNzIG5hbWUgaW5kZXguCi0gICAqLwotICBwdWJsaWMgaW50IGdldENsYXNzTmFtZUluZGV4KCkgICB7IHJldHVybiBjbGFzc19uYW1lX2luZGV4OyB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gQ29uc3RhbnQgcG9vbC4KLSAgICovCi0gIHB1YmxpYyBDb25zdGFudFBvb2wgZ2V0Q29uc3RhbnRQb29sKCkgeyByZXR1cm4gY29uc3RhbnRfcG9vbDsgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIEZpZWxkcywgaS5lLiwgdmFyaWFibGVzIG9mIHRoZSBjbGFzcy4gTGlrZSB0aGUgSlZNIHNwZWMKLSAgICogbWFuZGF0ZXMgZm9yIHRoZSBjbGFzc2ZpbGUgZm9ybWF0LCB0aGVzZSBmaWVsZHMgYXJlIHRob3NlIHNwZWNpZmljIHRvCi0gICAqIHRoaXMgY2xhc3MsIGFuZCBub3QgdGhvc2Ugb2YgdGhlIHN1cGVyY2xhc3Mgb3Igc3VwZXJpbnRlcmZhY2VzLgotICAgKi8KLSAgcHVibGljIEZpZWxkW10gZ2V0RmllbGRzKCkgICAgICAgICB7IHJldHVybiBmaWVsZHM7IH0KLQotICAvKioKLSAgICogQHJldHVybiBGaWxlIG5hbWUgb2YgY2xhc3MsIGFrYSBTb3VyY2VGaWxlIGF0dHJpYnV0ZSB2YWx1ZQotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRGaWxlTmFtZSgpICAgICAgICB7IHJldHVybiBmaWxlX25hbWU7IH0KLQotICAvKioKLSAgICogQHJldHVybiBOYW1lcyBvZiBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzLgotICAgKi8KLSAgcHVibGljIFN0cmluZ1tdIGdldEludGVyZmFjZU5hbWVzKCkgIHsgcmV0dXJuIGludGVyZmFjZV9uYW1lczsgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIEluZGljZXMgaW4gY29uc3RhbnQgcG9vbCBvZiBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzLgotICAgKi8KLSAgcHVibGljIGludFtdIGdldEludGVyZmFjZUluZGljZXMoKSAgICAgeyByZXR1cm4gaW50ZXJmYWNlczsgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIE1ham9yIG51bWJlciBvZiBjbGFzcyBmaWxlIHZlcnNpb24uCi0gICAqLwotICBwdWJsaWMgaW50ICBnZXRNYWpvcigpICAgICAgICAgICB7IHJldHVybiBtYWpvcjsgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIE1ldGhvZHMgb2YgdGhlIGNsYXNzLgotICAgKi8KLSAgcHVibGljIE1ldGhvZFtdIGdldE1ldGhvZHMoKSAgICAgICB7IHJldHVybiBtZXRob2RzOyB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gQSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5jbGFzc2ZpbGUuTWV0aG9kIGNvcnJlc3BvbmRpbmcgdG8KLSAgICogamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kIGlmIGFueQotICAgKi8KLSAgcHVibGljIE1ldGhvZCBnZXRNZXRob2QoamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kIG0pIHsKLSAgICBmb3IoaW50IGkgPSAwOyBpIDwgbWV0aG9kcy5sZW5ndGg7IGkrKykgewotICAgICAgTWV0aG9kIG1ldGhvZCA9IG1ldGhvZHNbaV07Ci0KLSAgICAgIGlmKG0uZ2V0TmFtZSgpLmVxdWFscyhtZXRob2QuZ2V0TmFtZSgpKSAmJgotICAgICAgICAgKG0uZ2V0TW9kaWZpZXJzKCkgPT0gbWV0aG9kLmdldE1vZGlmaWVycygpKSAmJgotICAgICAgICAgVHlwZS5nZXRTaWduYXR1cmUobSkuZXF1YWxzKG1ldGhvZC5nZXRTaWduYXR1cmUoKSkpIHsKLSAgICAgICAgcmV0dXJuIG1ldGhvZDsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIE1pbm9yIG51bWJlciBvZiBjbGFzcyBmaWxlIHZlcnNpb24uCi0gICAqLwotICBwdWJsaWMgaW50ICBnZXRNaW5vcigpICAgICAgICAgICB7IHJldHVybiBtaW5vcjsgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIHNic29sdXRlIHBhdGggdG8gZmlsZSB3aGVyZSB0aGlzIGNsYXNzIHdhcyByZWFkIGZyb20KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0U291cmNlRmlsZU5hbWUoKSAgeyByZXR1cm4gc291cmNlX2ZpbGVfbmFtZTsgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIFN1cGVyY2xhc3MgbmFtZS4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0U3VwZXJjbGFzc05hbWUoKSAgeyByZXR1cm4gc3VwZXJjbGFzc19uYW1lOyB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gQ2xhc3MgbmFtZSBpbmRleC4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0U3VwZXJjbGFzc05hbWVJbmRleCgpIHsgcmV0dXJuIHN1cGVyY2xhc3NfbmFtZV9pbmRleDsgfQotCi0gIHN0YXRpYyB7Ci0gICAgLy8gRGVidWdnaW5nIC4uLiBvbi9vZmYKLSAgICBTdHJpbmcgZGVidWcgPSBudWxsLCBzZXAgPSBudWxsOwotCi0gICAgdHJ5IHsKLSAgICAgIGRlYnVnID0gU2VjdXJpdHlTdXBwb3J0LmdldFN5c3RlbVByb3BlcnR5KCJKYXZhQ2xhc3MuZGVidWciKTsKLSAgICAgIC8vIEdldCBwYXRoIHNlcGFyYXRvciBlaXRoZXIgLyBvciBcIHVzdWFsbHkKLSAgICAgIHNlcCA9IFNlY3VyaXR5U3VwcG9ydC5nZXRTeXN0ZW1Qcm9wZXJ0eSgiZmlsZS5zZXBhcmF0b3IiKTsKLSAgICB9Ci0gICAgY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIGUpIHsKLSAgICAgICAgLy8gZmFsbHMgdGhyb3VnaAotICAgIH0KLQotICAgIGlmKGRlYnVnICE9IG51bGwpCi0gICAgICBKYXZhQ2xhc3MuZGVidWcgPSBuZXcgQm9vbGVhbihkZWJ1ZykuYm9vbGVhblZhbHVlKCk7Ci0KLSAgICBpZihzZXAgIT0gbnVsbCkKLSAgICAgIHRyeSB7Ci0gICAgICAgIEphdmFDbGFzcy5zZXAgPSBzZXAuY2hhckF0KDApOwotICAgICAgfSBjYXRjaChTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHt9IC8vIE5ldmVyIHJlYWNoZWQKLSAgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gYXR0cmlidXRlcyAuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRBdHRyaWJ1dGVzKEF0dHJpYnV0ZVtdIGF0dHJpYnV0ZXMpIHsKLSAgICB0aGlzLmF0dHJpYnV0ZXMgPSBhdHRyaWJ1dGVzOwotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBjbGFzc19uYW1lIC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldENsYXNzTmFtZShTdHJpbmcgY2xhc3NfbmFtZSkgewotICAgIHRoaXMuY2xhc3NfbmFtZSA9IGNsYXNzX25hbWU7Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIGNsYXNzX25hbWVfaW5kZXggLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0Q2xhc3NOYW1lSW5kZXgoaW50IGNsYXNzX25hbWVfaW5kZXgpIHsKLSAgICB0aGlzLmNsYXNzX25hbWVfaW5kZXggPSBjbGFzc19uYW1lX2luZGV4OwotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBjb25zdGFudF9wb29sIC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldENvbnN0YW50UG9vbChDb25zdGFudFBvb2wgY29uc3RhbnRfcG9vbCkgewotICAgIHRoaXMuY29uc3RhbnRfcG9vbCA9IGNvbnN0YW50X3Bvb2w7Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIGZpZWxkcyAuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRGaWVsZHMoRmllbGRbXSBmaWVsZHMpIHsKLSAgICB0aGlzLmZpZWxkcyA9IGZpZWxkczsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgRmlsZSBuYW1lIG9mIGNsYXNzLCBha2EgU291cmNlRmlsZSBhdHRyaWJ1dGUgdmFsdWUKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldEZpbGVOYW1lKFN0cmluZyBmaWxlX25hbWUpIHsKLSAgICB0aGlzLmZpbGVfbmFtZSA9IGZpbGVfbmFtZTsKLSAgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gaW50ZXJmYWNlX25hbWVzIC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldEludGVyZmFjZU5hbWVzKFN0cmluZ1tdIGludGVyZmFjZV9uYW1lcykgewotICAgIHRoaXMuaW50ZXJmYWNlX25hbWVzID0gaW50ZXJmYWNlX25hbWVzOwotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBpbnRlcmZhY2VzIC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldEludGVyZmFjZXMoaW50W10gaW50ZXJmYWNlcykgewotICAgIHRoaXMuaW50ZXJmYWNlcyA9IGludGVyZmFjZXM7Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIG1ham9yIC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldE1ham9yKGludCBtYWpvcikgewotICAgIHRoaXMubWFqb3IgPSBtYWpvcjsKLSAgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gbWV0aG9kcyAuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRNZXRob2RzKE1ldGhvZFtdIG1ldGhvZHMpIHsKLSAgICB0aGlzLm1ldGhvZHMgPSBtZXRob2RzOwotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBtaW5vciAuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRNaW5vcihpbnQgbWlub3IpIHsKLSAgICB0aGlzLm1pbm9yID0gbWlub3I7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IGFic29sdXRlIHBhdGggdG8gZmlsZSB0aGlzIGNsYXNzIHdhcyByZWFkIGZyb20uCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRTb3VyY2VGaWxlTmFtZShTdHJpbmcgc291cmNlX2ZpbGVfbmFtZSkgewotICAgIHRoaXMuc291cmNlX2ZpbGVfbmFtZSA9IHNvdXJjZV9maWxlX25hbWU7Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIHN1cGVyY2xhc3NfbmFtZSAuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRTdXBlcmNsYXNzTmFtZShTdHJpbmcgc3VwZXJjbGFzc19uYW1lKSB7Ci0gICAgdGhpcy5zdXBlcmNsYXNzX25hbWUgPSBzdXBlcmNsYXNzX25hbWU7Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIHN1cGVyY2xhc3NfbmFtZV9pbmRleCAuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRTdXBlcmNsYXNzTmFtZUluZGV4KGludCBzdXBlcmNsYXNzX25hbWVfaW5kZXgpIHsKLSAgICB0aGlzLnN1cGVyY2xhc3NfbmFtZV9pbmRleCA9IHN1cGVyY2xhc3NfbmFtZV9pbmRleDsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIFN0cmluZyByZXByZXNlbnRpbmcgY2xhc3MgY29udGVudHMuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgIFN0cmluZyBhY2Nlc3MgPSBVdGlsaXR5LmFjY2Vzc1RvU3RyaW5nKGFjY2Vzc19mbGFncywgdHJ1ZSk7Ci0gICAgYWNjZXNzID0gYWNjZXNzLmVxdWFscygiIik/ICIiIDogKGFjY2VzcyArICIgIik7Ci0KLSAgICBTdHJpbmdCdWZmZXIgYnVmID0gbmV3IFN0cmluZ0J1ZmZlcihhY2Nlc3MgKwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFV0aWxpdHkuY2xhc3NPckludGVyZmFjZShhY2Nlc3NfZmxhZ3MpICsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiICIgKwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzX25hbWUgKyAiIGV4dGVuZHMgIiArCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVXRpbGl0eS5jb21wYWN0Q2xhc3NOYW1lKHN1cGVyY2xhc3NfbmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UpICsgJ1xuJyk7Ci0gICAgaW50IHNpemUgPSBpbnRlcmZhY2VzLmxlbmd0aDsKLQotICAgIGlmKHNpemUgPiAwKSB7Ci0gICAgICBidWYuYXBwZW5kKCJpbXBsZW1lbnRzXHRcdCIpOwotCi0gICAgICBmb3IoaW50IGk9MDsgaSA8IHNpemU7IGkrKykgewotICAgICAgICBidWYuYXBwZW5kKGludGVyZmFjZV9uYW1lc1tpXSk7Ci0gICAgICAgIGlmKGkgPCBzaXplIC0gMSkKLSAgICAgICAgICBidWYuYXBwZW5kKCIsICIpOwotICAgICAgfQotCi0gICAgICBidWYuYXBwZW5kKCdcbicpOwotICAgIH0KLQotICAgIGJ1Zi5hcHBlbmQoImZpbGVuYW1lXHRcdCIgKyBmaWxlX25hbWUgKyAnXG4nKTsKLSAgICBidWYuYXBwZW5kKCJjb21waWxlZCBmcm9tXHRcdCIgKyBzb3VyY2VfZmlsZV9uYW1lICsgJ1xuJyk7Ci0gICAgYnVmLmFwcGVuZCgiY29tcGlsZXIgdmVyc2lvblx0IiArIG1ham9yICsgIi4iICsgbWlub3IgKyAnXG4nKTsKLSAgICBidWYuYXBwZW5kKCJhY2Nlc3MgZmxhZ3NcdFx0IiArIGFjY2Vzc19mbGFncyArICdcbicpOwotICAgIGJ1Zi5hcHBlbmQoImNvbnN0YW50IHBvb2xcdFx0IiArIGNvbnN0YW50X3Bvb2wuZ2V0TGVuZ3RoKCkgKyAiIGVudHJpZXNcbiIpOwotICAgIGJ1Zi5hcHBlbmQoIkFDQ19TVVBFUiBmbGFnXHRcdCIgKyBpc1N1cGVyKCkgKyAiXG4iKTsKLQotICAgIGlmKGF0dHJpYnV0ZXMubGVuZ3RoID4gMCkgewotICAgICAgYnVmLmFwcGVuZCgiXG5BdHRyaWJ1dGUocyk6XG4iKTsKLSAgICAgIGZvcihpbnQgaT0wOyBpIDwgYXR0cmlidXRlcy5sZW5ndGg7IGkrKykKLSAgICAgICAgYnVmLmFwcGVuZChpbmRlbnQoYXR0cmlidXRlc1tpXSkpOwotICAgIH0KLQotICAgIGlmKGZpZWxkcy5sZW5ndGggPiAwKSB7Ci0gICAgICBidWYuYXBwZW5kKCJcbiIgKyBmaWVsZHMubGVuZ3RoICsgIiBmaWVsZHM6XG4iKTsKLSAgICAgIGZvcihpbnQgaT0wOyBpIDwgZmllbGRzLmxlbmd0aDsgaSsrKQotICAgICAgICBidWYuYXBwZW5kKCJcdCIgKyBmaWVsZHNbaV0gKyAnXG4nKTsKLSAgICB9Ci0KLSAgICBpZihtZXRob2RzLmxlbmd0aCA+IDApIHsKLSAgICAgIGJ1Zi5hcHBlbmQoIlxuIiArIG1ldGhvZHMubGVuZ3RoICsgIiBtZXRob2RzOlxuIik7Ci0gICAgICBmb3IoaW50IGk9MDsgaSA8IG1ldGhvZHMubGVuZ3RoOyBpKyspCi0gICAgICAgIGJ1Zi5hcHBlbmQoIlx0IiArIG1ldGhvZHNbaV0gKyAnXG4nKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gYnVmLnRvU3RyaW5nKCk7Ci0gIH0KLQotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgaW5kZW50KE9iamVjdCBvYmopIHsKLSAgICBTdHJpbmdUb2tlbml6ZXIgdG9rID0gbmV3IFN0cmluZ1Rva2VuaXplcihvYmoudG9TdHJpbmcoKSwgIlxuIik7Ci0gICAgU3RyaW5nQnVmZmVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLQotICAgIHdoaWxlKHRvay5oYXNNb3JlVG9rZW5zKCkpCi0gICAgICBidWYuYXBwZW5kKCJcdCIgKyB0b2submV4dFRva2VuKCkgKyAiXG4iKTsKLQotICAgIHJldHVybiBidWYudG9TdHJpbmcoKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIGRlZXAgY29weSBvZiB0aGlzIGNsYXNzCi0gICAqLwotICBwdWJsaWMgSmF2YUNsYXNzIGNvcHkoKSB7Ci0gICAgSmF2YUNsYXNzIGMgPSBudWxsOwotCi0gICAgdHJ5IHsKLSAgICAgIGMgPSAoSmF2YUNsYXNzKWNsb25lKCk7Ci0gICAgfSBjYXRjaChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKSB7fQotCi0gICAgYy5jb25zdGFudF9wb29sICAgPSBjb25zdGFudF9wb29sLmNvcHkoKTsKLSAgICBjLmludGVyZmFjZXMgICAgICA9IChpbnRbXSlpbnRlcmZhY2VzLmNsb25lKCk7Ci0gICAgYy5pbnRlcmZhY2VfbmFtZXMgPSAoU3RyaW5nW10paW50ZXJmYWNlX25hbWVzLmNsb25lKCk7Ci0KLSAgICBjLmZpZWxkcyA9IG5ldyBGaWVsZFtmaWVsZHMubGVuZ3RoXTsKLSAgICBmb3IoaW50IGk9MDsgaSA8IGZpZWxkcy5sZW5ndGg7IGkrKykKLSAgICAgIGMuZmllbGRzW2ldID0gZmllbGRzW2ldLmNvcHkoYy5jb25zdGFudF9wb29sKTsKLQotICAgIGMubWV0aG9kcyA9IG5ldyBNZXRob2RbbWV0aG9kcy5sZW5ndGhdOwotICAgIGZvcihpbnQgaT0wOyBpIDwgbWV0aG9kcy5sZW5ndGg7IGkrKykKLSAgICAgIGMubWV0aG9kc1tpXSA9IG1ldGhvZHNbaV0uY29weShjLmNvbnN0YW50X3Bvb2wpOwotCi0gICAgYy5hdHRyaWJ1dGVzID0gbmV3IEF0dHJpYnV0ZVthdHRyaWJ1dGVzLmxlbmd0aF07Ci0gICAgZm9yKGludCBpPTA7IGkgPCBhdHRyaWJ1dGVzLmxlbmd0aDsgaSsrKQotICAgICAgYy5hdHRyaWJ1dGVzW2ldID0gYXR0cmlidXRlc1tpXS5jb3B5KGMuY29uc3RhbnRfcG9vbCk7Ci0KLSAgICByZXR1cm4gYzsKLSAgfQotCi0gIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzU3VwZXIoKSB7Ci0gICAgcmV0dXJuIChhY2Nlc3NfZmxhZ3MgJiBDb25zdGFudHMuQUNDX1NVUEVSKSAhPSAwOwotICB9Ci0KLSAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNDbGFzcygpIHsKLSAgICByZXR1cm4gKGFjY2Vzc19mbGFncyAmIENvbnN0YW50cy5BQ0NfSU5URVJGQUNFKSA9PSAwOwotICB9Ci0KLSAgLyoqIEByZXR1cm4gcmV0dXJucyBlaXRoZXIgSEVBUCAoZ2VuZXJhdGVkKSwgRklMRSwgb3IgWklQCi0gICAqLwotICBwdWJsaWMgZmluYWwgYnl0ZSBnZXRTb3VyY2UoKSB7Ci0gICAgcmV0dXJuIHNvdXJjZTsKLSAgfQotCi0gIC8qKioqKioqKioqKioqKioqKioqKiogTmV3IHJlcG9zaXRvcnkgZnVuY3Rpb25hbGl0eSAqKioqKioqKioqKioqKioqKioqKiovCi0KLSAgLyoqCi0gICAqIEdldHMgdGhlIENsYXNzUmVwb3NpdG9yeSB3aGljaCBob2xkcyBpdHMgZGVmaW5pdGlvbi4gQnkgZGVmYXVsdAotICAgKiB0aGlzIGlzIHRoZSBzYW1lIGFzIFN5bnRoZXRpY1JlcG9zaXRvcnkuZ2V0SW5zdGFuY2UoKTsKLSAgICovCi0gIHB1YmxpYyBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC51dGlsLlJlcG9zaXRvcnkgZ2V0UmVwb3NpdG9yeSgpIHsKLSAgICByZXR1cm4gcmVwb3NpdG9yeTsKLSAgfQotCi0gIC8qKgotICAgKiBTZXRzIHRoZSBDbGFzc1JlcG9zaXRvcnkgd2hpY2ggbG9hZGVkIHRoZSBKYXZhQ2xhc3MuCi0gICAqIFNob3VsZCBiZSBjYWxsZWQgaW1tZWRpYXRlbHkgYWZ0ZXIgcGFyc2luZyBpcyBkb25lLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0UmVwb3NpdG9yeShjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC51dGlsLlJlcG9zaXRvcnkgcmVwb3NpdG9yeSkgewotICAgIHRoaXMucmVwb3NpdG9yeSA9IHJlcG9zaXRvcnk7Ci0gIH0KLQotICAvKiogRXF1aXZhbGVudCB0byBydW50aW1lICJpbnN0YW5jZW9mIiBvcGVyYXRvci4KLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHRoaXMgSmF2YUNsYXNzIGlzIGRlcml2ZWQgZnJvbSB0ZWggc3VwZXIgY2xhc3MKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBib29sZWFuIGluc3RhbmNlT2YoSmF2YUNsYXNzIHN1cGVyX2NsYXNzKSB7Ci0gICAgaWYodGhpcy5lcXVhbHMoc3VwZXJfY2xhc3MpKQotICAgICAgcmV0dXJuIHRydWU7Ci0KLSAgICBKYXZhQ2xhc3NbXSBzdXBlcl9jbGFzc2VzID0gZ2V0U3VwZXJDbGFzc2VzKCk7Ci0KLSAgICBmb3IoaW50IGk9MDsgaSA8IHN1cGVyX2NsYXNzZXMubGVuZ3RoOyBpKyspIHsKLSAgICAgIGlmKHN1cGVyX2NsYXNzZXNbaV0uZXF1YWxzKHN1cGVyX2NsYXNzKSkgewotICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICBpZihzdXBlcl9jbGFzcy5pc0ludGVyZmFjZSgpKSB7Ci0gICAgICByZXR1cm4gaW1wbGVtZW50YXRpb25PZihzdXBlcl9jbGFzcyk7Ci0gICAgfQotCi0gICAgcmV0dXJuIGZhbHNlOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gdHJ1ZSwgaWYgY2xhenogaXMgYW4gaW1wbGVtZW50YXRpb24gb2YgaW50ZXJmYWNlIGludGVyCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBpbXBsZW1lbnRhdGlvbk9mKEphdmFDbGFzcyBpbnRlcikgewotICAgIGlmKCFpbnRlci5pc0ludGVyZmFjZSgpKSB7Ci0gICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKGludGVyLmdldENsYXNzTmFtZSgpICsgIiBpcyBubyBpbnRlcmZhY2UiKTsKLSAgICB9Ci0KLSAgICBpZih0aGlzLmVxdWFscyhpbnRlcikpIHsKLSAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotICAgIEphdmFDbGFzc1tdIHN1cGVyX2ludGVyZmFjZXMgPSBnZXRBbGxJbnRlcmZhY2VzKCk7Ci0KLSAgICBmb3IoaW50IGk9MDsgaSA8IHN1cGVyX2ludGVyZmFjZXMubGVuZ3RoOyBpKyspIHsKLSAgICAgIGlmKHN1cGVyX2ludGVyZmFjZXNbaV0uZXF1YWxzKGludGVyKSkgewotICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gZmFsc2U7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiB0aGUgc3VwZXJjbGFzcyBmb3IgdGhpcyBKYXZhQ2xhc3Mgb2JqZWN0LCBvciBudWxsIGlmIHRoaXMKLSAgICogaXMgamF2YS5sYW5nLk9iamVjdAotICAgKi8KLSAgcHVibGljIEphdmFDbGFzcyBnZXRTdXBlckNsYXNzKCkgewotICAgIGlmKCJqYXZhLmxhbmcuT2JqZWN0Ii5lcXVhbHMoZ2V0Q2xhc3NOYW1lKCkpKSB7Ci0gICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICB0cnkgewotICAgICAgcmV0dXJuIHJlcG9zaXRvcnkubG9hZENsYXNzKGdldFN1cGVyY2xhc3NOYW1lKCkpOwotICAgIH0gY2F0Y2goQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBlKSB7Ci0gICAgICBTeXN0ZW0uZXJyLnByaW50bG4oZSk7Ci0gICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBsaXN0IG9mIHN1cGVyIGNsYXNzZXMgb2YgdGhpcyBjbGFzcyBpbiBhc2NlbmRpbmcgb3JkZXIsIGkuZS4sCi0gICAqIGphdmEubGFuZy5PYmplY3QgaXMgYWx3YXlzIHRoZSBsYXN0IGVsZW1lbnQKLSAgICovCi0gIHB1YmxpYyBKYXZhQ2xhc3NbXSBnZXRTdXBlckNsYXNzZXMoKSB7Ci0gICAgSmF2YUNsYXNzICAgY2xhenogPSB0aGlzOwotICAgIENsYXNzVmVjdG9yIHZlYyAgID0gbmV3IENsYXNzVmVjdG9yKCk7Ci0KLSAgICBmb3IoY2xhenogPSBjbGF6ei5nZXRTdXBlckNsYXNzKCk7IGNsYXp6ICE9IG51bGw7Ci0gICAgICAgIGNsYXp6ID0gY2xhenouZ2V0U3VwZXJDbGFzcygpKQotICAgIHsKLSAgICAgIHZlYy5hZGRFbGVtZW50KGNsYXp6KTsKLSAgICB9Ci0KLSAgICByZXR1cm4gdmVjLnRvQXJyYXkoKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgaW50ZXJmYWNlcyBkaXJlY3RseSBpbXBsZW1lbnRlZCBieSB0aGlzIEphdmFDbGFzcy4KLSAgICovCi0gIHB1YmxpYyBKYXZhQ2xhc3NbXSBnZXRJbnRlcmZhY2VzKCkgewotICAgIFN0cmluZ1tdICAgIGludGVyZmFjZXMgPSBnZXRJbnRlcmZhY2VOYW1lcygpOwotICAgIEphdmFDbGFzc1tdIGNsYXNzZXMgICAgPSBuZXcgSmF2YUNsYXNzW2ludGVyZmFjZXMubGVuZ3RoXTsKLQotICAgIHRyeSB7Ci0gICAgICBmb3IoaW50IGkgPSAwOyBpIDwgaW50ZXJmYWNlcy5sZW5ndGg7IGkrKykgewotICAgICAgICBjbGFzc2VzW2ldID0gcmVwb3NpdG9yeS5sb2FkQ2xhc3MoaW50ZXJmYWNlc1tpXSk7Ci0gICAgICB9Ci0gICAgfSBjYXRjaChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGUpIHsKLSAgICAgIFN5c3RlbS5lcnIucHJpbnRsbihlKTsKLSAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIHJldHVybiBjbGFzc2VzOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBhbGwgaW50ZXJmYWNlcyBpbXBsZW1lbnRlZCBieSB0aGlzIEphdmFDbGFzcyAodHJhbnNpdGl2ZWx5KS4KLSAgICovCi0gIHB1YmxpYyBKYXZhQ2xhc3NbXSBnZXRBbGxJbnRlcmZhY2VzKCkgewotICAgIENsYXNzUXVldWUgIHF1ZXVlID0gbmV3IENsYXNzUXVldWUoKTsKLSAgICBDbGFzc1ZlY3RvciB2ZWMgICA9IG5ldyBDbGFzc1ZlY3RvcigpOwotCi0gICAgcXVldWUuZW5xdWV1ZSh0aGlzKTsKLQotICAgIHdoaWxlKCFxdWV1ZS5lbXB0eSgpKSB7Ci0gICAgICBKYXZhQ2xhc3MgY2xhenogPSBxdWV1ZS5kZXF1ZXVlKCk7Ci0KLSAgICAgIEphdmFDbGFzcyAgIHNvdXBlciAgICAgPSBjbGF6ei5nZXRTdXBlckNsYXNzKCk7Ci0gICAgICBKYXZhQ2xhc3NbXSBpbnRlcmZhY2VzID0gY2xhenouZ2V0SW50ZXJmYWNlcygpOwotCi0gICAgICBpZihjbGF6ei5pc0ludGVyZmFjZSgpKSB7Ci0gICAgICAgIHZlYy5hZGRFbGVtZW50KGNsYXp6KTsKLSAgICAgIH0gZWxzZSB7Ci0gICAgICAgIGlmKHNvdXBlciAhPSBudWxsKSB7Ci0gICAgICAgICAgcXVldWUuZW5xdWV1ZShzb3VwZXIpOwotICAgICAgICB9Ci0gICAgICB9Ci0KLSAgICAgIGZvcihpbnQgaSA9IDA7IGkgPCBpbnRlcmZhY2VzLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgIHF1ZXVlLmVucXVldWUoaW50ZXJmYWNlc1tpXSk7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgcmV0dXJuIHZlYy50b0FycmF5KCk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvTGluZU51bWJlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2NsYXNzZmlsZS9MaW5lTnVtYmVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGVjOGI0NzIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2NsYXNzZmlsZS9MaW5lTnVtYmVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNjcgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuY2xhc3NmaWxlOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi1pbXBvcnQgIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50czsKLWltcG9ydCAgamF2YS5pby4qOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgcmVwcmVzZW50cyBhIChQQyBvZmZzZXQsIGxpbmUgbnVtYmVyKSBwYWlyLCBpLmUuLCBhIGxpbmUgbnVtYmVyIGluCi0gKiB0aGUgc291cmNlIHRoYXQgY29ycmVzcG9uZHMgdG8gYSByZWxhdGl2ZSBhZGRyZXNzIGluIHRoZSBieXRlIGNvZGUuIFRoaXMKLSAqIGlzIHVzZWQgZm9yIGRlYnVnZ2luZyBwdXJwb3Nlcy4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICogQHNlZSAgICAgTGluZU51bWJlclRhYmxlCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBMaW5lTnVtYmVyIGltcGxlbWVudHMgQ2xvbmVhYmxlLCBOb2RlLCBTZXJpYWxpemFibGUgewotICBwcml2YXRlIGludCBzdGFydF9wYzsgICAgLy8gUHJvZ3JhbSBDb3VudGVyIChQQykgY29ycmVzcG9uZHMgdG8gbGluZQotICBwcml2YXRlIGludCBsaW5lX251bWJlcjsgLy8gbnVtYmVyIGluIHNvdXJjZSBmaWxlCi0KLSAgLyoqCi0gICAqIEluaXRpYWxpemUgZnJvbSBhbm90aGVyIG9iamVjdC4KLSAgICovCi0gIHB1YmxpYyBMaW5lTnVtYmVyKExpbmVOdW1iZXIgYykgewotICAgIHRoaXMoYy5nZXRTdGFydFBDKCksIGMuZ2V0TGluZU51bWJlcigpKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3Qgb2JqZWN0IGZyb20gZmlsZSBzdHJlYW0uCi0gICAqIEBwYXJhbSBmaWxlIElucHV0IHN0cmVhbQotICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0gICAqLwotICBMaW5lTnVtYmVyKERhdGFJbnB1dFN0cmVhbSBmaWxlKSB0aHJvd3MgSU9FeGNlcHRpb24KLSAgewotICAgIHRoaXMoZmlsZS5yZWFkVW5zaWduZWRTaG9ydCgpLCBmaWxlLnJlYWRVbnNpZ25lZFNob3J0KCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBzdGFydF9wYyBQcm9ncmFtIENvdW50ZXIgKFBDKSBjb3JyZXNwb25kcyB0bwotICAgKiBAcGFyYW0gbGluZV9udW1iZXIgbGluZSBudW1iZXIgaW4gc291cmNlIGZpbGUKLSAgICovCi0gIHB1YmxpYyBMaW5lTnVtYmVyKGludCBzdGFydF9wYywgaW50IGxpbmVfbnVtYmVyKQotICB7Ci0gICAgdGhpcy5zdGFydF9wYyAgICA9IHN0YXJ0X3BjOwotICAgIHRoaXMubGluZV9udW1iZXIgPSBsaW5lX251bWJlcjsKLSAgfQotCi0gIC8qKgotICAgKiBDYWxsZWQgYnkgb2JqZWN0cyB0aGF0IGFyZSB0cmF2ZXJzaW5nIHRoZSBub2RlcyBvZiB0aGUgdHJlZSBpbXBsaWNpdGVseQotICAgKiBkZWZpbmVkIGJ5IHRoZSBjb250ZW50cyBvZiBhIEphdmEgY2xhc3MuIEkuZS4sIHRoZSBoaWVyYXJjaHkgb2YgbWV0aG9kcywKLSAgICogZmllbGRzLCBhdHRyaWJ1dGVzLCBldGMuIHNwYXducyBhIHRyZWUgb2Ygb2JqZWN0cy4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0TGluZU51bWJlcih0aGlzKTsKLSAgfQotCi0gIC8qKgotICAgKiBEdW1wIGxpbmUgbnVtYmVyL3BjIHBhaXIgdG8gZmlsZSBzdHJlYW0gaW4gYmluYXJ5IGZvcm1hdC4KLSAgICoKLSAgICogQHBhcmFtIGZpbGUgT3V0cHV0IGZpbGUgc3RyZWFtCi0gICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIGR1bXAoRGF0YU91dHB1dFN0cmVhbSBmaWxlKSB0aHJvd3MgSU9FeGNlcHRpb24KLSAgewotICAgIGZpbGUud3JpdGVTaG9ydChzdGFydF9wYyk7Ci0gICAgZmlsZS53cml0ZVNob3J0KGxpbmVfbnVtYmVyKTsKLQotICB9Ci0gIC8qKgotICAgKiBAcmV0dXJuIENvcnJlc3BvbmRpbmcgc291cmNlIGxpbmUKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBpbnQgZ2V0TGluZU51bWJlcigpIHsgcmV0dXJuIGxpbmVfbnVtYmVyOyB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gUEMgaW4gY29kZQotICAgKi8KLSAgcHVibGljIGZpbmFsIGludCBnZXRTdGFydFBDKCkgeyByZXR1cm4gc3RhcnRfcGM7IH0KLQotICAvKioKLSAgICogQHBhcmFtIGxpbmVfbnVtYmVyLgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgc2V0TGluZU51bWJlcihpbnQgbGluZV9udW1iZXIpIHsKLSAgICB0aGlzLmxpbmVfbnVtYmVyID0gbGluZV9udW1iZXI7Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIHN0YXJ0X3BjLgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgc2V0U3RhcnRQQyhpbnQgc3RhcnRfcGMpIHsKLSAgICB0aGlzLnN0YXJ0X3BjID0gc3RhcnRfcGM7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBTdHJpbmcgcmVwcmVzZW50YXRpb24KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0gICAgcmV0dXJuICJMaW5lTnVtYmVyKCIgKyBzdGFydF9wYyArICIsICIgKyBsaW5lX251bWJlciArICIpIjsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIGRlZXAgY29weSBvZiB0aGlzIG9iamVjdAotICAgKi8KLSAgcHVibGljIExpbmVOdW1iZXIgY29weSgpIHsKLSAgICB0cnkgewotICAgICAgcmV0dXJuIChMaW5lTnVtYmVyKWNsb25lKCk7Ci0gICAgfSBjYXRjaChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKSB7fQotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvTGluZU51bWJlclRhYmxlLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvY2xhc3NmaWxlL0xpbmVOdW1iZXJUYWJsZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxZmE5YmZlLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvTGluZU51bWJlclRhYmxlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyNDMgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuY2xhc3NmaWxlOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi1pbXBvcnQgIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50czsKLWltcG9ydCAgamF2YS5pby4qOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgcmVwcmVzZW50cyBhIHRhYmxlIG9mIGxpbmUgbnVtYmVycyBmb3IgZGVidWdnaW5nCi0gKiBwdXJwb3Nlcy4gVGhpcyBhdHRyaWJ1dGUgaXMgdXNlZCBieSB0aGUgPGVtPkNvZGU8L2VtPiBhdHRyaWJ1dGUuIEl0Ci0gKiBjb250YWlucyBwYWlycyBvZiBQQ3MgYW5kIGxpbmUgbnVtYmVycy4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICogQHNlZSAgICAgQ29kZQotICogQHNlZSBMaW5lTnVtYmVyCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBMaW5lTnVtYmVyVGFibGUgZXh0ZW5kcyBBdHRyaWJ1dGUgewotICBwcml2YXRlIGludCAgICAgICAgICBsaW5lX251bWJlcl90YWJsZV9sZW5ndGg7Ci0gIHByaXZhdGUgTGluZU51bWJlcltdIGxpbmVfbnVtYmVyX3RhYmxlOyAvLyBUYWJsZSBvZiBsaW5lL251bWJlcnMgcGFpcnMKLQotICAvKgotICAgKiBJbml0aWFsaXplIGZyb20gYW5vdGhlciBvYmplY3QuIE5vdGUgdGhhdCBib3RoIG9iamVjdHMgdXNlIHRoZSBzYW1lCi0gICAqIHJlZmVyZW5jZXMgKHNoYWxsb3cgY29weSkuIFVzZSBjb3B5KCkgZm9yIGEgcGh5c2ljYWwgY29weS4KLSAgICovCi0gIHB1YmxpYyBMaW5lTnVtYmVyVGFibGUoTGluZU51bWJlclRhYmxlIGMpIHsKLSAgICB0aGlzKGMuZ2V0TmFtZUluZGV4KCksIGMuZ2V0TGVuZ3RoKCksIGMuZ2V0TGluZU51bWJlclRhYmxlKCksCi0gICAgICAgICBjLmdldENvbnN0YW50UG9vbCgpKTsKLSAgfQotCi0gIC8qCi0gICAqIEBwYXJhbSBuYW1lX2luZGV4IEluZGV4IG9mIG5hbWUKLSAgICogQHBhcmFtIGxlbmd0aCBDb250ZW50IGxlbmd0aCBpbiBieXRlcwotICAgKiBAcGFyYW0gbGluZV9udW1iZXJfdGFibGUgVGFibGUgb2YgbGluZS9udW1iZXJzIHBhaXJzCi0gICAqIEBwYXJhbSBjb25zdGFudF9wb29sIEFycmF5IG9mIGNvbnN0YW50cwotICAgKi8KLSAgcHVibGljIExpbmVOdW1iZXJUYWJsZShpbnQgbmFtZV9pbmRleCwgaW50IGxlbmd0aCwKLSAgICAgICAgICAgICAgICAgICAgICAgICBMaW5lTnVtYmVyW10gbGluZV9udW1iZXJfdGFibGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgQ29uc3RhbnRQb29sIGNvbnN0YW50X3Bvb2wpCi0gIHsKLSAgICBzdXBlcihDb25zdGFudHMuQVRUUl9MSU5FX05VTUJFUl9UQUJMRSwgbmFtZV9pbmRleCwgbGVuZ3RoLCBjb25zdGFudF9wb29sKTsKLSAgICBzZXRMaW5lTnVtYmVyVGFibGUobGluZV9udW1iZXJfdGFibGUpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBvYmplY3QgZnJvbSBmaWxlIHN0cmVhbS4KLSAgICogQHBhcmFtIG5hbWVfaW5kZXggSW5kZXggb2YgbmFtZQotICAgKiBAcGFyYW0gbGVuZ3RoIENvbnRlbnQgbGVuZ3RoIGluIGJ5dGVzCi0gICAqIEBwYXJhbSBmaWxlIElucHV0IHN0cmVhbQotICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0gICAqIEBwYXJhbSBjb25zdGFudF9wb29sIEFycmF5IG9mIGNvbnN0YW50cwotICAgKi8KLSAgTGluZU51bWJlclRhYmxlKGludCBuYW1lX2luZGV4LCBpbnQgbGVuZ3RoLCBEYXRhSW5wdXRTdHJlYW0gZmlsZSwKLSAgICAgICAgICAgICAgICAgIENvbnN0YW50UG9vbCBjb25zdGFudF9wb29sKSB0aHJvd3MgSU9FeGNlcHRpb24KLSAgewotICAgIHRoaXMobmFtZV9pbmRleCwgbGVuZ3RoLCAoTGluZU51bWJlcltdKW51bGwsIGNvbnN0YW50X3Bvb2wpOwotICAgIGxpbmVfbnVtYmVyX3RhYmxlX2xlbmd0aCA9IChmaWxlLnJlYWRVbnNpZ25lZFNob3J0KCkpOwotICAgIGxpbmVfbnVtYmVyX3RhYmxlID0gbmV3IExpbmVOdW1iZXJbbGluZV9udW1iZXJfdGFibGVfbGVuZ3RoXTsKLQotICAgIGZvcihpbnQgaT0wOyBpIDwgbGluZV9udW1iZXJfdGFibGVfbGVuZ3RoOyBpKyspCi0gICAgICBsaW5lX251bWJlcl90YWJsZVtpXSA9IG5ldyBMaW5lTnVtYmVyKGZpbGUpOwotICB9Ci0gIC8qKgotICAgKiBDYWxsZWQgYnkgb2JqZWN0cyB0aGF0IGFyZSB0cmF2ZXJzaW5nIHRoZSBub2RlcyBvZiB0aGUgdHJlZSBpbXBsaWNpdGVseQotICAgKiBkZWZpbmVkIGJ5IHRoZSBjb250ZW50cyBvZiBhIEphdmEgY2xhc3MuIEkuZS4sIHRoZSBoaWVyYXJjaHkgb2YgbWV0aG9kcywKLSAgICogZmllbGRzLCBhdHRyaWJ1dGVzLCBldGMuIHNwYXducyBhIHRyZWUgb2Ygb2JqZWN0cy4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0TGluZU51bWJlclRhYmxlKHRoaXMpOwotICB9Ci0gIC8qKgotICAgKiBEdW1wIGxpbmUgbnVtYmVyIHRhYmxlIGF0dHJpYnV0ZSB0byBmaWxlIHN0cmVhbSBpbiBiaW5hcnkgZm9ybWF0LgotICAgKgotICAgKiBAcGFyYW0gZmlsZSBPdXRwdXQgZmlsZSBzdHJlYW0KLSAgICogQHRocm93cyBJT0V4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgZHVtcChEYXRhT3V0cHV0U3RyZWFtIGZpbGUpIHRocm93cyBJT0V4Y2VwdGlvbgotICB7Ci0gICAgc3VwZXIuZHVtcChmaWxlKTsKLSAgICBmaWxlLndyaXRlU2hvcnQobGluZV9udW1iZXJfdGFibGVfbGVuZ3RoKTsKLSAgICBmb3IoaW50IGk9MDsgaSA8IGxpbmVfbnVtYmVyX3RhYmxlX2xlbmd0aDsgaSsrKQotICAgICAgbGluZV9udW1iZXJfdGFibGVbaV0uZHVtcChmaWxlKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIEFycmF5IG9mIChwYyBvZmZzZXQsIGxpbmUgbnVtYmVyKSBwYWlycy4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBMaW5lTnVtYmVyW10gZ2V0TGluZU51bWJlclRhYmxlKCkgeyByZXR1cm4gbGluZV9udW1iZXJfdGFibGU7IH0KLQotICAvKioKLSAgICogQHBhcmFtIGxpbmVfbnVtYmVyX3RhYmxlLgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgc2V0TGluZU51bWJlclRhYmxlKExpbmVOdW1iZXJbXSBsaW5lX251bWJlcl90YWJsZSkgewotICAgIHRoaXMubGluZV9udW1iZXJfdGFibGUgPSBsaW5lX251bWJlcl90YWJsZTsKLQotICAgIGxpbmVfbnVtYmVyX3RhYmxlX2xlbmd0aCA9IChsaW5lX251bWJlcl90YWJsZSA9PSBudWxsKT8gMCA6Ci0gICAgICBsaW5lX251bWJlcl90YWJsZS5sZW5ndGg7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBTdHJpbmcgcmVwcmVzZW50YXRpb24uCi0gICAqLwotICBwdWJsaWMgZmluYWwgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgIFN0cmluZ0J1ZmZlciBidWYgID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotICAgIFN0cmluZ0J1ZmZlciBsaW5lID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotCi0gICAgZm9yKGludCBpPTA7IGkgPCBsaW5lX251bWJlcl90YWJsZV9sZW5ndGg7IGkrKykgewotICAgICAgbGluZS5hcHBlbmQobGluZV9udW1iZXJfdGFibGVbaV0udG9TdHJpbmcoKSk7Ci0KLSAgICAgIGlmKGkgPCBsaW5lX251bWJlcl90YWJsZV9sZW5ndGggLSAxKQotICAgICAgICBsaW5lLmFwcGVuZCgiLCAiKTsKLQotICAgICAgaWYobGluZS5sZW5ndGgoKSA+IDcyKSB7Ci0gICAgICAgIGxpbmUuYXBwZW5kKCdcbicpOwotICAgICAgICBidWYuYXBwZW5kKGxpbmUpOwotICAgICAgICBsaW5lLnNldExlbmd0aCgwKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICBidWYuYXBwZW5kKGxpbmUpOwotCi0gICAgcmV0dXJuIGJ1Zi50b1N0cmluZygpOwotICB9Ci0KLSAgLyoqCi0gICAqIE1hcCBieXRlIGNvZGUgcG9zaXRpb25zIHRvIHNvdXJjZSBjb2RlIGxpbmVzLgotICAgKgotICAgKiBAcGFyYW0gcG9zIGJ5dGUgY29kZSBvZmZzZXQKLSAgICogQHJldHVybiBjb3JyZXNwb25kaW5nIGxpbmUgaW4gc291cmNlIGNvZGUKLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0U291cmNlTGluZShpbnQgcG9zKSB7Ci0gICAgaW50IGwgPSAwLCByID0gbGluZV9udW1iZXJfdGFibGVfbGVuZ3RoLTE7Ci0KLSAgICBpZihyIDwgMCkgLy8gYXJyYXkgaXMgZW1wdHkKLSAgICAgIHJldHVybiAtMTsKLQotICAgIGludCBtaW5faW5kZXggPSAtMSwgbWluPS0xOwotCi0gICAgLyogRG8gYSBiaW5hcnkgc2VhcmNoIHNpbmNlIHRoZSBhcnJheSBpcyBvcmRlcmVkLgotICAgICAqLwotICAgIGRvIHsKLSAgICAgIGludCBpID0gKGwgKyByKSAvIDI7Ci0gICAgICBpbnQgaiA9IGxpbmVfbnVtYmVyX3RhYmxlW2ldLmdldFN0YXJ0UEMoKTsKLQotICAgICAgaWYoaiA9PSBwb3MpCi0gICAgICAgIHJldHVybiBsaW5lX251bWJlcl90YWJsZVtpXS5nZXRMaW5lTnVtYmVyKCk7Ci0gICAgICBlbHNlIGlmKHBvcyA8IGopIC8vIGVsc2UgY29uc3RyYWluIHNlYXJjaCBhcmVhCi0gICAgICAgIHIgPSBpIC0gMTsKLSAgICAgIGVsc2UgLy8gcG9zID4gagotICAgICAgICBsID0gaSArIDE7Ci0KLSAgICAgIC8qIElmIGV4YWN0IG1hdGNoIGNhbid0IGJlIGZvdW5kICh3aGljaCBpcyB0aGUgbW9zdCBjb21tb24gY2FzZSkKLSAgICAgICAqIHJldHVybiB0aGUgbGluZSBudW1iZXIgdGhhdCBjb3JyZXNwb25kcyB0byB0aGUgZ3JlYXRlc3QgaW5kZXggbGVzcwotICAgICAgICogdGhhbiBwb3MuCi0gICAgICAgKi8KLSAgICAgIGlmKGogPCBwb3MgJiYgaiA+IG1pbikgewotICAgICAgICBtaW4gICAgICAgPSBqOwotICAgICAgICBtaW5faW5kZXggPSBpOwotICAgICAgfQotICAgIH0gd2hpbGUobCA8PSByKTsKLQotICAgIC8qIEl0J3MgcG9zc2libGUgdGhhdCB3ZSBkaWQgbm90IGZpbmQgYW55IHZhbGlkIGVudHJ5IGZvciB0aGUgYnl0ZWNvZGUKLSAgICAgKiBvZmZzZXQgd2Ugd2VyZSBsb29raW5nIGZvci4KLSAgICAgKi8KLSAgICBpZiAobWluX2luZGV4IDwgMCkKLSAgICAgIHJldHVybiAtMTsKLQotICAgIHJldHVybiBsaW5lX251bWJlcl90YWJsZVttaW5faW5kZXhdLmdldExpbmVOdW1iZXIoKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIGRlZXAgY29weSBvZiB0aGlzIGF0dHJpYnV0ZQotICAgKi8KLSAgcHVibGljIEF0dHJpYnV0ZSBjb3B5KENvbnN0YW50UG9vbCBjb25zdGFudF9wb29sKSB7Ci0gICAgTGluZU51bWJlclRhYmxlIGMgPSAoTGluZU51bWJlclRhYmxlKWNsb25lKCk7Ci0KLSAgICBjLmxpbmVfbnVtYmVyX3RhYmxlID0gbmV3IExpbmVOdW1iZXJbbGluZV9udW1iZXJfdGFibGVfbGVuZ3RoXTsKLSAgICBmb3IoaW50IGk9MDsgaSA8IGxpbmVfbnVtYmVyX3RhYmxlX2xlbmd0aDsgaSsrKQotICAgICAgYy5saW5lX251bWJlcl90YWJsZVtpXSA9IGxpbmVfbnVtYmVyX3RhYmxlW2ldLmNvcHkoKTsKLQotICAgIGMuY29uc3RhbnRfcG9vbCA9IGNvbnN0YW50X3Bvb2w7Ci0gICAgcmV0dXJuIGM7Ci0gIH0KLQotICBwdWJsaWMgZmluYWwgaW50IGdldFRhYmxlTGVuZ3RoKCkgeyByZXR1cm4gbGluZV9udW1iZXJfdGFibGVfbGVuZ3RoOyB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvY2xhc3NmaWxlL0xvY2FsVmFyaWFibGUuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvTG9jYWxWYXJpYWJsZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhODBiYzNiLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvTG9jYWxWYXJpYWJsZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjYyICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmNsYXNzZmlsZTsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotaW1wb3J0ICBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHM7Ci1pbXBvcnQgIGphdmEuaW8uKjsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIHJlcHJlc2VudHMgYSBsb2NhbCB2YXJpYWJsZSB3aXRoaW4gYSBtZXRob2QuIEl0IGNvbnRhaW5zIGl0cwotICogc2NvcGUsIG5hbWUsIHNpZ25hdHVyZSBhbmQgaW5kZXggb24gdGhlIG1ldGhvZCdzIGZyYW1lLgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKiBAc2VlICAgICBMb2NhbFZhcmlhYmxlVGFibGUKLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIExvY2FsVmFyaWFibGUKLSAgaW1wbGVtZW50cyBDb25zdGFudHMsIENsb25lYWJsZSwgTm9kZSwgU2VyaWFsaXphYmxlCi17Ci0gIHByaXZhdGUgaW50IHN0YXJ0X3BjOyAgICAgICAgLy8gUmFuZ2UgaW4gd2hpY2ggdGhlIHZhcmlhYmxlIGlzIHZhbGlkCi0gIHByaXZhdGUgaW50IGxlbmd0aDsKLSAgcHJpdmF0ZSBpbnQgbmFtZV9pbmRleDsgICAgICAvLyBJbmRleCBpbiBjb25zdGFudCBwb29sIG9mIHZhcmlhYmxlIG5hbWUKLSAgcHJpdmF0ZSBpbnQgc2lnbmF0dXJlX2luZGV4OyAvLyBJbmRleCBvZiB2YXJpYWJsZSBzaWduYXR1cmUKLSAgcHJpdmF0ZSBpbnQgaW5kZXg7ICAgICAgICAgICAgLyogVmFyaWFibGUgaXMgYGluZGV4J3RoIGxvY2FsIHZhcmlhYmxlIG9uCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogdGhpcyBtZXRob2QncyBmcmFtZS4KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICBwcml2YXRlIENvbnN0YW50UG9vbCBjb25zdGFudF9wb29sOwotCi0gIC8qKgotICAgKiBJbml0aWFsaXplIGZyb20gYW5vdGhlciBvYmplY3QuIE5vdGUgdGhhdCBib3RoIG9iamVjdHMgdXNlIHRoZSBzYW1lCi0gICAqIHJlZmVyZW5jZXMgKHNoYWxsb3cgY29weSkuIFVzZSBjb3B5KCkgZm9yIGEgcGh5c2ljYWwgY29weS4KLSAgICovCi0gIHB1YmxpYyBMb2NhbFZhcmlhYmxlKExvY2FsVmFyaWFibGUgYykgewotICAgIHRoaXMoYy5nZXRTdGFydFBDKCksIGMuZ2V0TGVuZ3RoKCksIGMuZ2V0TmFtZUluZGV4KCksCi0gICAgICAgICBjLmdldFNpZ25hdHVyZUluZGV4KCksIGMuZ2V0SW5kZXgoKSwgYy5nZXRDb25zdGFudFBvb2woKSk7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IG9iamVjdCBmcm9tIGZpbGUgc3RyZWFtLgotICAgKiBAcGFyYW0gZmlsZSBJbnB1dCBzdHJlYW0KLSAgICogQHRocm93cyBJT0V4Y2VwdGlvbgotICAgKi8KLSAgTG9jYWxWYXJpYWJsZShEYXRhSW5wdXRTdHJlYW0gZmlsZSwgQ29uc3RhbnRQb29sIGNvbnN0YW50X3Bvb2wpCi0gICAgICAgdGhyb3dzIElPRXhjZXB0aW9uCi0gIHsKLSAgICB0aGlzKGZpbGUucmVhZFVuc2lnbmVkU2hvcnQoKSwgZmlsZS5yZWFkVW5zaWduZWRTaG9ydCgpLAotICAgICAgICAgZmlsZS5yZWFkVW5zaWduZWRTaG9ydCgpLCBmaWxlLnJlYWRVbnNpZ25lZFNob3J0KCksCi0gICAgICAgICBmaWxlLnJlYWRVbnNpZ25lZFNob3J0KCksIGNvbnN0YW50X3Bvb2wpOwotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBzdGFydF9wYyBSYW5nZSBpbiB3aGljaCB0aGUgdmFyaWFibGUKLSAgICogQHBhcmFtIGxlbmd0aCAuLi4gaXMgdmFsaWQKLSAgICogQHBhcmFtIG5hbWVfaW5kZXggSW5kZXggaW4gY29uc3RhbnQgcG9vbCBvZiB2YXJpYWJsZSBuYW1lCi0gICAqIEBwYXJhbSBzaWduYXR1cmVfaW5kZXggSW5kZXggb2YgdmFyaWFibGUncyBzaWduYXR1cmUKLSAgICogQHBhcmFtIGluZGV4IFZhcmlhYmxlIGlzIGBpbmRleCd0aCBsb2NhbCB2YXJpYWJsZSBvbiB0aGUgbWV0aG9kJ3MgZnJhbWUKLSAgICogQHBhcmFtIGNvbnN0YW50X3Bvb2wgQXJyYXkgb2YgY29uc3RhbnRzCi0gICAqLwotICBwdWJsaWMgTG9jYWxWYXJpYWJsZShpbnQgc3RhcnRfcGMsIGludCBsZW5ndGgsIGludCBuYW1lX2luZGV4LAotICAgICAgICAgICAgICAgICAgICAgICBpbnQgc2lnbmF0dXJlX2luZGV4LCBpbnQgaW5kZXgsCi0gICAgICAgICAgICAgICAgICAgICAgIENvbnN0YW50UG9vbCBjb25zdGFudF9wb29sKQotICB7Ci0gICAgdGhpcy5zdGFydF9wYyAgICAgICAgPSBzdGFydF9wYzsKLSAgICB0aGlzLmxlbmd0aCAgICAgICAgICA9IGxlbmd0aDsKLSAgICB0aGlzLm5hbWVfaW5kZXggICAgICA9IG5hbWVfaW5kZXg7Ci0gICAgdGhpcy5zaWduYXR1cmVfaW5kZXggPSBzaWduYXR1cmVfaW5kZXg7Ci0gICAgdGhpcy5pbmRleCAgICAgICAgICAgPSBpbmRleDsKLSAgICB0aGlzLmNvbnN0YW50X3Bvb2wgICA9IGNvbnN0YW50X3Bvb2w7Ci0gIH0KLQotICAvKioKLSAgICogQ2FsbGVkIGJ5IG9iamVjdHMgdGhhdCBhcmUgdHJhdmVyc2luZyB0aGUgbm9kZXMgb2YgdGhlIHRyZWUgaW1wbGljaXRlbHkKLSAgICogZGVmaW5lZCBieSB0aGUgY29udGVudHMgb2YgYSBKYXZhIGNsYXNzLiBJLmUuLCB0aGUgaGllcmFyY2h5IG9mIG1ldGhvZHMsCi0gICAqIGZpZWxkcywgYXR0cmlidXRlcywgZXRjLiBzcGF3bnMgYSB0cmVlIG9mIG9iamVjdHMuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgdi52aXNpdExvY2FsVmFyaWFibGUodGhpcyk7Ci0gIH0KLQotICAvKioKLSAgICogRHVtcCBsb2NhbCB2YXJpYWJsZSB0byBmaWxlIHN0cmVhbSBpbiBiaW5hcnkgZm9ybWF0LgotICAgKgotICAgKiBAcGFyYW0gZmlsZSBPdXRwdXQgZmlsZSBzdHJlYW0KLSAgICogQHRocm93cyBJT0V4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgZHVtcChEYXRhT3V0cHV0U3RyZWFtIGZpbGUpIHRocm93cyBJT0V4Y2VwdGlvbgotICB7Ci0gICAgZmlsZS53cml0ZVNob3J0KHN0YXJ0X3BjKTsKLSAgICBmaWxlLndyaXRlU2hvcnQobGVuZ3RoKTsKLSAgICBmaWxlLndyaXRlU2hvcnQobmFtZV9pbmRleCk7Ci0gICAgZmlsZS53cml0ZVNob3J0KHNpZ25hdHVyZV9pbmRleCk7Ci0gICAgZmlsZS53cml0ZVNob3J0KGluZGV4KTsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIENvbnN0YW50IHBvb2wgdXNlZCBieSB0aGlzIG9iamVjdC4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBDb25zdGFudFBvb2wgZ2V0Q29uc3RhbnRQb29sKCkgeyByZXR1cm4gY29uc3RhbnRfcG9vbDsgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIFZhcmlhYmxlIGlzIHZhbGlkIHdpdGhpbiBnZXRTdGFydFBDKCkgLi4gZ2V0U3RhcnRQQygpK2dldExlbmd0aCgpCi0gICAqLwotICBwdWJsaWMgZmluYWwgaW50IGdldExlbmd0aCgpICAgICAgICAgeyByZXR1cm4gbGVuZ3RoOyB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gVmFyaWFibGUgbmFtZS4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBTdHJpbmcgZ2V0TmFtZSgpIHsKLSAgICBDb25zdGFudFV0ZjggIGM7Ci0KLSAgICBjID0gKENvbnN0YW50VXRmOCljb25zdGFudF9wb29sLmdldENvbnN0YW50KG5hbWVfaW5kZXgsIENPTlNUQU5UX1V0ZjgpOwotICAgIHJldHVybiBjLmdldEJ5dGVzKCk7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBJbmRleCBpbiBjb25zdGFudCBwb29sIG9mIHZhcmlhYmxlIG5hbWUuCi0gICAqLwotICBwdWJsaWMgZmluYWwgaW50IGdldE5hbWVJbmRleCgpICAgICAgeyByZXR1cm4gbmFtZV9pbmRleDsgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIFNpZ25hdHVyZS4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBTdHJpbmcgZ2V0U2lnbmF0dXJlKCkgewotICAgIENvbnN0YW50VXRmOCAgYzsKLSAgICBjID0gKENvbnN0YW50VXRmOCljb25zdGFudF9wb29sLmdldENvbnN0YW50KHNpZ25hdHVyZV9pbmRleCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPTlNUQU5UX1V0ZjgpOwotICAgIHJldHVybiBjLmdldEJ5dGVzKCk7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBJbmRleCBpbiBjb25zdGFudCBwb29sIG9mIHZhcmlhYmxlIHNpZ25hdHVyZS4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBpbnQgZ2V0U2lnbmF0dXJlSW5kZXgoKSB7IHJldHVybiBzaWduYXR1cmVfaW5kZXg7IH0KLQotICAvKioKLSAgICogQHJldHVybiBpbmRleCBvZiByZWdpc3RlciB3aGVyZSB2YXJpYWJsZSBpcyBzdG9yZWQKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBpbnQgZ2V0SW5kZXgoKSAgICAgICAgICAgeyByZXR1cm4gaW5kZXg7IH0KLQotICAvKioKLSAgICogQHJldHVybiBTdGFydCBvZiByYW5nZSB3aGVyZSBoZSB2YXJpYWJsZSBpcyB2YWxpZAotICAgKi8KLSAgcHVibGljIGZpbmFsIGludCBnZXRTdGFydFBDKCkgICAgICAgIHsgcmV0dXJuIHN0YXJ0X3BjOyB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBjb25zdGFudF9wb29sIENvbnN0YW50IHBvb2wgdG8gYmUgdXNlZCBmb3IgdGhpcyBvYmplY3QuCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBzZXRDb25zdGFudFBvb2woQ29uc3RhbnRQb29sIGNvbnN0YW50X3Bvb2wpIHsKLSAgICB0aGlzLmNvbnN0YW50X3Bvb2wgPSBjb25zdGFudF9wb29sOwotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBsZW5ndGguCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBzZXRMZW5ndGgoaW50IGxlbmd0aCkgewotICAgIHRoaXMubGVuZ3RoID0gbGVuZ3RoOwotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBuYW1lX2luZGV4LgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgc2V0TmFtZUluZGV4KGludCBuYW1lX2luZGV4KSB7Ci0gICAgdGhpcy5uYW1lX2luZGV4ID0gbmFtZV9pbmRleDsKLSAgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gc2lnbmF0dXJlX2luZGV4LgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgc2V0U2lnbmF0dXJlSW5kZXgoaW50IHNpZ25hdHVyZV9pbmRleCkgewotICAgIHRoaXMuc2lnbmF0dXJlX2luZGV4ID0gc2lnbmF0dXJlX2luZGV4OwotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBpbmRleC4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHNldEluZGV4KGludCBpbmRleCkgeyB0aGlzLmluZGV4ID0gaW5kZXg7IH0KLQotICAvKioKLSAgICogQHBhcmFtIHN0YXJ0X3BjIFNwZWNpZnkgcmFuZ2Ugd2hlcmUgdGhlIGxvY2FsIHZhcmlhYmxlIGlzIHZhbGlkLgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgc2V0U3RhcnRQQyhpbnQgc3RhcnRfcGMpIHsKLSAgICB0aGlzLnN0YXJ0X3BjID0gc3RhcnRfcGM7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBzdHJpbmcgcmVwcmVzZW50YXRpb24uCi0gICAqLwotICBwdWJsaWMgZmluYWwgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgIFN0cmluZyBuYW1lID0gZ2V0TmFtZSgpLCBzaWduYXR1cmUgPSBVdGlsaXR5LnNpZ25hdHVyZVRvU3RyaW5nKGdldFNpZ25hdHVyZSgpKTsKLQotICAgIHJldHVybiAiTG9jYWxWYXJpYWJsZShzdGFydF9wYyA9ICIgKyBzdGFydF9wYyArICIsIGxlbmd0aCA9ICIgKyBsZW5ndGggKwotICAgICAgIiwgaW5kZXggPSAiICsgaW5kZXggKyAiOiIgKyBzaWduYXR1cmUgKyAiICIgKyBuYW1lICsgIikiOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gZGVlcCBjb3B5IG9mIHRoaXMgb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgTG9jYWxWYXJpYWJsZSBjb3B5KCkgewotICAgIHRyeSB7Ci0gICAgICByZXR1cm4gKExvY2FsVmFyaWFibGUpY2xvbmUoKTsKLSAgICB9IGNhdGNoKENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGUpIHt9Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2NsYXNzZmlsZS9Mb2NhbFZhcmlhYmxlVGFibGUuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvTG9jYWxWYXJpYWJsZVRhYmxlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGRiMDYzMWYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2NsYXNzZmlsZS9Mb2NhbFZhcmlhYmxlVGFibGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE5OSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5jbGFzc2ZpbGU7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLWltcG9ydCAgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzOwotaW1wb3J0ICBqYXZhLmlvLio7Ci0KLS8qKgotICogVGhpcyBjbGFzcyByZXByZXNlbnRzIGNvbGVjdGlvbiBvZiBsb2NhbCB2YXJpYWJsZXMgaW4gYQotICogbWV0aG9kLiBUaGlzIGF0dHJpYnV0ZSBpcyBjb250YWluZWQgaW4gdGhlIDxlbT5Db2RlPC9lbT4gYXR0cmlidXRlLgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKiBAc2VlICAgICBDb2RlCi0gKiBAc2VlIExvY2FsVmFyaWFibGUKLSAqLwotcHVibGljIGNsYXNzIExvY2FsVmFyaWFibGVUYWJsZSBleHRlbmRzIEF0dHJpYnV0ZSB7Ci0gIHByaXZhdGUgaW50ICAgICAgICAgICAgIGxvY2FsX3ZhcmlhYmxlX3RhYmxlX2xlbmd0aDsgLy8gVGFibGUgb2YgbG9jYWwKLSAgcHJpdmF0ZSBMb2NhbFZhcmlhYmxlW10gbG9jYWxfdmFyaWFibGVfdGFibGU7ICAgICAgICAvLyB2YXJpYWJsZXMKLQotICAvKioKLSAgICogSW5pdGlhbGl6ZSBmcm9tIGFub3RoZXIgb2JqZWN0LiBOb3RlIHRoYXQgYm90aCBvYmplY3RzIHVzZSB0aGUgc2FtZQotICAgKiByZWZlcmVuY2VzIChzaGFsbG93IGNvcHkpLiBVc2UgY29weSgpIGZvciBhIHBoeXNpY2FsIGNvcHkuCi0gICAqLwotICBwdWJsaWMgTG9jYWxWYXJpYWJsZVRhYmxlKExvY2FsVmFyaWFibGVUYWJsZSBjKSB7Ci0gICAgdGhpcyhjLmdldE5hbWVJbmRleCgpLCBjLmdldExlbmd0aCgpLCBjLmdldExvY2FsVmFyaWFibGVUYWJsZSgpLAotICAgICAgICAgYy5nZXRDb25zdGFudFBvb2woKSk7Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIG5hbWVfaW5kZXggSW5kZXggaW4gY29uc3RhbnQgcG9vbCB0byBgTG9jYWxWYXJpYWJsZVRhYmxlJwotICAgKiBAcGFyYW0gbGVuZ3RoIENvbnRlbnQgbGVuZ3RoIGluIGJ5dGVzCi0gICAqIEBwYXJhbSBsb2NhbF92YXJpYWJsZV90YWJsZSBUYWJsZSBvZiBsb2NhbCB2YXJpYWJsZXMKLSAgICogQHBhcmFtIGNvbnN0YW50X3Bvb2wgQXJyYXkgb2YgY29uc3RhbnRzCi0gICAqLwotICBwdWJsaWMgTG9jYWxWYXJpYWJsZVRhYmxlKGludCBuYW1lX2luZGV4LCBpbnQgbGVuZ3RoLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIExvY2FsVmFyaWFibGVbXSBsb2NhbF92YXJpYWJsZV90YWJsZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb25zdGFudFBvb2wgICAgY29uc3RhbnRfcG9vbCkKLSAgewotICAgIHN1cGVyKENvbnN0YW50cy5BVFRSX0xPQ0FMX1ZBUklBQkxFX1RBQkxFLCBuYW1lX2luZGV4LCBsZW5ndGgsIGNvbnN0YW50X3Bvb2wpOwotICAgIHNldExvY2FsVmFyaWFibGVUYWJsZShsb2NhbF92YXJpYWJsZV90YWJsZSk7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IG9iamVjdCBmcm9tIGZpbGUgc3RyZWFtLgotICAgKiBAcGFyYW0gbmFtZV9pbmRleCBJbmRleCBpbiBjb25zdGFudCBwb29sCi0gICAqIEBwYXJhbSBsZW5ndGggQ29udGVudCBsZW5ndGggaW4gYnl0ZXMKLSAgICogQHBhcmFtIGZpbGUgSW5wdXQgc3RyZWFtCi0gICAqIEBwYXJhbSBjb25zdGFudF9wb29sIEFycmF5IG9mIGNvbnN0YW50cwotICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0gICAqLwotICBMb2NhbFZhcmlhYmxlVGFibGUoaW50IG5hbWVfaW5kZXgsIGludCBsZW5ndGgsIERhdGFJbnB1dFN0cmVhbSBmaWxlLAotICAgICAgICAgICAgICAgICAgICAgQ29uc3RhbnRQb29sIGNvbnN0YW50X3Bvb2wpIHRocm93cyBJT0V4Y2VwdGlvbgotICB7Ci0gICAgdGhpcyhuYW1lX2luZGV4LCBsZW5ndGgsIChMb2NhbFZhcmlhYmxlW10pbnVsbCwgY29uc3RhbnRfcG9vbCk7Ci0KLSAgICBsb2NhbF92YXJpYWJsZV90YWJsZV9sZW5ndGggPSAoZmlsZS5yZWFkVW5zaWduZWRTaG9ydCgpKTsKLSAgICBsb2NhbF92YXJpYWJsZV90YWJsZSA9IG5ldyBMb2NhbFZhcmlhYmxlW2xvY2FsX3ZhcmlhYmxlX3RhYmxlX2xlbmd0aF07Ci0KLSAgICBmb3IoaW50IGk9MDsgaSA8IGxvY2FsX3ZhcmlhYmxlX3RhYmxlX2xlbmd0aDsgaSsrKQotICAgICAgbG9jYWxfdmFyaWFibGVfdGFibGVbaV0gPSBuZXcgTG9jYWxWYXJpYWJsZShmaWxlLCBjb25zdGFudF9wb29sKTsKLSAgfQotCi0gIC8qKgotICAgKiBDYWxsZWQgYnkgb2JqZWN0cyB0aGF0IGFyZSB0cmF2ZXJzaW5nIHRoZSBub2RlcyBvZiB0aGUgdHJlZSBpbXBsaWNpdGVseQotICAgKiBkZWZpbmVkIGJ5IHRoZSBjb250ZW50cyBvZiBhIEphdmEgY2xhc3MuIEkuZS4sIHRoZSBoaWVyYXJjaHkgb2YgbWV0aG9kcywKLSAgICogZmllbGRzLCBhdHRyaWJ1dGVzLCBldGMuIHNwYXducyBhIHRyZWUgb2Ygb2JqZWN0cy4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0TG9jYWxWYXJpYWJsZVRhYmxlKHRoaXMpOwotICB9Ci0KLSAgLyoqCi0gICAqIER1bXAgbG9jYWwgdmFyaWFibGUgdGFibGUgYXR0cmlidXRlIHRvIGZpbGUgc3RyZWFtIGluIGJpbmFyeSBmb3JtYXQuCi0gICAqCi0gICAqIEBwYXJhbSBmaWxlIE91dHB1dCBmaWxlIHN0cmVhbQotICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBkdW1wKERhdGFPdXRwdXRTdHJlYW0gZmlsZSkgdGhyb3dzIElPRXhjZXB0aW9uCi0gIHsKLSAgICBzdXBlci5kdW1wKGZpbGUpOwotICAgIGZpbGUud3JpdGVTaG9ydChsb2NhbF92YXJpYWJsZV90YWJsZV9sZW5ndGgpOwotICAgIGZvcihpbnQgaT0wOyBpIDwgbG9jYWxfdmFyaWFibGVfdGFibGVfbGVuZ3RoOyBpKyspCi0gICAgICBsb2NhbF92YXJpYWJsZV90YWJsZVtpXS5kdW1wKGZpbGUpOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gQXJyYXkgb2YgbG9jYWwgdmFyaWFibGVzIG9mIG1ldGhvZC4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBMb2NhbFZhcmlhYmxlW10gZ2V0TG9jYWxWYXJpYWJsZVRhYmxlKCkgewotICAgIHJldHVybiBsb2NhbF92YXJpYWJsZV90YWJsZTsKLSAgfQotCi0gIC8qKiBAcmV0dXJuIGZpcnN0IG1hdGNoaW5nIHZhcmlhYmxlIHVzaW5nIGluZGV4Ci0gICAqLwotICBwdWJsaWMgZmluYWwgTG9jYWxWYXJpYWJsZSBnZXRMb2NhbFZhcmlhYmxlKGludCBpbmRleCkgewotICAgIGZvcihpbnQgaT0wOyBpIDwgbG9jYWxfdmFyaWFibGVfdGFibGVfbGVuZ3RoOyBpKyspCi0gICAgICBpZihsb2NhbF92YXJpYWJsZV90YWJsZVtpXS5nZXRJbmRleCgpID09IGluZGV4KQotICAgICAgICByZXR1cm4gbG9jYWxfdmFyaWFibGVfdGFibGVbaV07Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHNldExvY2FsVmFyaWFibGVUYWJsZShMb2NhbFZhcmlhYmxlW10gbG9jYWxfdmFyaWFibGVfdGFibGUpCi0gIHsKLSAgICB0aGlzLmxvY2FsX3ZhcmlhYmxlX3RhYmxlID0gbG9jYWxfdmFyaWFibGVfdGFibGU7Ci0gICAgbG9jYWxfdmFyaWFibGVfdGFibGVfbGVuZ3RoID0gKGxvY2FsX3ZhcmlhYmxlX3RhYmxlID09IG51bGwpPyAwIDoKLSAgICAgIGxvY2FsX3ZhcmlhYmxlX3RhYmxlLmxlbmd0aDsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIFN0cmluZyByZXByZXNlbnRhdGlvbi4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0gICAgU3RyaW5nQnVmZmVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWZmZXIoIiIpOwotCi0gICAgZm9yKGludCBpPTA7IGkgPCBsb2NhbF92YXJpYWJsZV90YWJsZV9sZW5ndGg7IGkrKykgewotICAgICAgYnVmLmFwcGVuZChsb2NhbF92YXJpYWJsZV90YWJsZVtpXS50b1N0cmluZygpKTsKLQotICAgICAgaWYoaSA8IGxvY2FsX3ZhcmlhYmxlX3RhYmxlX2xlbmd0aCAtIDEpCi0gICAgICAgIGJ1Zi5hcHBlbmQoJ1xuJyk7Ci0gICAgfQotCi0gICAgcmV0dXJuIGJ1Zi50b1N0cmluZygpOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gZGVlcCBjb3B5IG9mIHRoaXMgYXR0cmlidXRlCi0gICAqLwotICBwdWJsaWMgQXR0cmlidXRlIGNvcHkoQ29uc3RhbnRQb29sIGNvbnN0YW50X3Bvb2wpIHsKLSAgICBMb2NhbFZhcmlhYmxlVGFibGUgYyA9IChMb2NhbFZhcmlhYmxlVGFibGUpY2xvbmUoKTsKLQotICAgIGMubG9jYWxfdmFyaWFibGVfdGFibGUgPSBuZXcgTG9jYWxWYXJpYWJsZVtsb2NhbF92YXJpYWJsZV90YWJsZV9sZW5ndGhdOwotICAgIGZvcihpbnQgaT0wOyBpIDwgbG9jYWxfdmFyaWFibGVfdGFibGVfbGVuZ3RoOyBpKyspCi0gICAgICBjLmxvY2FsX3ZhcmlhYmxlX3RhYmxlW2ldID0gbG9jYWxfdmFyaWFibGVfdGFibGVbaV0uY29weSgpOwotCi0gICAgYy5jb25zdGFudF9wb29sID0gY29uc3RhbnRfcG9vbDsKLSAgICByZXR1cm4gYzsKLSAgfQotCi0gIHB1YmxpYyBmaW5hbCBpbnQgZ2V0VGFibGVMZW5ndGgoKSB7IHJldHVybiBsb2NhbF92YXJpYWJsZV90YWJsZV9sZW5ndGg7IH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvTG9jYWxWYXJpYWJsZVR5cGVUYWJsZS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2NsYXNzZmlsZS9Mb2NhbFZhcmlhYmxlVHlwZVRhYmxlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDQ3MmY1M2EuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2NsYXNzZmlsZS9Mb2NhbFZhcmlhYmxlVHlwZVRhYmxlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNDYgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuY2xhc3NmaWxlOwotLyoqCi0gKiAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCi0gKiAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCi0gKiAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgotICogIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCi0gKiAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKLSAqICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLWltcG9ydCAgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzOwotaW1wb3J0ICBqYXZhLmlvLio7Ci0KLS8vIFRoZSBuZXcgdGFibGUgaXMgdXNlZCB3aGVuIGdlbmVyaWMgdHlwZXMgYXJlIGFib3V0Li4uCi0KLS8vTG9jYWxWYXJpYWJsZVRhYmxlX2F0dHJpYnV0ZSB7Ci0vLyAgICAgICAgIHUyIGF0dHJpYnV0ZV9uYW1lX2luZGV4OwotLy8gICAgICAgICB1NCBhdHRyaWJ1dGVfbGVuZ3RoOwotLy8gICAgICAgICB1MiBsb2NhbF92YXJpYWJsZV90YWJsZV9sZW5ndGg7Ci0vLyAgICAgICAgIHsgIHUyIHN0YXJ0X3BjOwotLy8gICAgICAgICAgICB1MiBsZW5ndGg7Ci0vLyAgICAgICAgICAgIHUyIG5hbWVfaW5kZXg7Ci0vLyAgICAgICAgICAgIHUyIGRlc2NyaXB0b3JfaW5kZXg7Ci0vLyAgICAgICAgICAgIHUyIGluZGV4OwotLy8gICAgICAgICB9IGxvY2FsX3ZhcmlhYmxlX3RhYmxlW2xvY2FsX3ZhcmlhYmxlX3RhYmxlX2xlbmd0aF07Ci0vLyAgICAgICB9Ci0KLS8vTG9jYWxWYXJpYWJsZVR5cGVUYWJsZV9hdHRyaWJ1dGUgewotLy8gICAgdTIgYXR0cmlidXRlX25hbWVfaW5kZXg7Ci0vLyAgICB1NCBhdHRyaWJ1dGVfbGVuZ3RoOwotLy8gICAgdTIgbG9jYWxfdmFyaWFibGVfdHlwZV90YWJsZV9sZW5ndGg7Ci0vLyAgICB7Ci0vLyAgICAgIHUyIHN0YXJ0X3BjOwotLy8gICAgICB1MiBsZW5ndGg7Ci0vLyAgICAgIHUyIG5hbWVfaW5kZXg7Ci0vLyAgICAgIHUyIHNpZ25hdHVyZV9pbmRleDsKLS8vICAgICAgdTIgaW5kZXg7Ci0vLyAgICB9IGxvY2FsX3ZhcmlhYmxlX3R5cGVfdGFibGVbbG9jYWxfdmFyaWFibGVfdHlwZV90YWJsZV9sZW5ndGhdOwotLy8gIH0KLS8vIEo1VE9ETzogTmVlZHMgc29tZSB0ZXN0aW5nICEKLXB1YmxpYyBjbGFzcyBMb2NhbFZhcmlhYmxlVHlwZVRhYmxlIGV4dGVuZHMgQXR0cmlidXRlIHsKLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTEwODIxNTc4OTEwOTUxNzcxMTRMOwotcHJpdmF0ZSBpbnQgICAgICAgICAgICAgbG9jYWxfdmFyaWFibGVfdHlwZV90YWJsZV9sZW5ndGg7IC8vIFRhYmxlIG9mIGxvY2FsCi0gIHByaXZhdGUgTG9jYWxWYXJpYWJsZVtdIGxvY2FsX3ZhcmlhYmxlX3R5cGVfdGFibGU7ICAgICAgICAvLyB2YXJpYWJsZXMKLQotICBwdWJsaWMgTG9jYWxWYXJpYWJsZVR5cGVUYWJsZShMb2NhbFZhcmlhYmxlVHlwZVRhYmxlIGMpIHsKLSAgICB0aGlzKGMuZ2V0TmFtZUluZGV4KCksIGMuZ2V0TGVuZ3RoKCksIGMuZ2V0TG9jYWxWYXJpYWJsZVR5cGVUYWJsZSgpLAotICAgICAgICAgYy5nZXRDb25zdGFudFBvb2woKSk7Ci0gIH0KLQotICBwdWJsaWMgTG9jYWxWYXJpYWJsZVR5cGVUYWJsZShpbnQgbmFtZV9pbmRleCwgaW50IGxlbmd0aCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBMb2NhbFZhcmlhYmxlW10gbG9jYWxfdmFyaWFibGVfdGFibGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29uc3RhbnRQb29sICAgIGNvbnN0YW50X3Bvb2wpCi0gIHsKLSAgICBzdXBlcihDb25zdGFudHMuQVRUUl9MT0NBTF9WQVJJQUJMRV9UWVBFX1RBQkxFLCBuYW1lX2luZGV4LCBsZW5ndGgsIGNvbnN0YW50X3Bvb2wpOwotICAgIHNldExvY2FsVmFyaWFibGVUYWJsZShsb2NhbF92YXJpYWJsZV90YWJsZSk7Ci0gIH0KLQotICBMb2NhbFZhcmlhYmxlVHlwZVRhYmxlKGludCBuYW1lSWR4LCBpbnQgbGVuLCBEYXRhSW5wdXRTdHJlYW0gZGlzLENvbnN0YW50UG9vbCBjcG9vbCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLSAgICB0aGlzKG5hbWVJZHgsIGxlbiwgKExvY2FsVmFyaWFibGVbXSludWxsLCBjcG9vbCk7Ci0KLSAgICBsb2NhbF92YXJpYWJsZV90eXBlX3RhYmxlX2xlbmd0aCA9IChkaXMucmVhZFVuc2lnbmVkU2hvcnQoKSk7Ci0gICAgbG9jYWxfdmFyaWFibGVfdHlwZV90YWJsZSA9IG5ldyBMb2NhbFZhcmlhYmxlW2xvY2FsX3ZhcmlhYmxlX3R5cGVfdGFibGVfbGVuZ3RoXTsKLQotICAgIGZvcihpbnQgaT0wOyBpIDwgbG9jYWxfdmFyaWFibGVfdHlwZV90YWJsZV9sZW5ndGg7IGkrKykKLSAgICAgIGxvY2FsX3ZhcmlhYmxlX3R5cGVfdGFibGVbaV0gPSBuZXcgTG9jYWxWYXJpYWJsZShkaXMsIGNwb29sKTsKLSAgfQotCi0gIEBPdmVycmlkZQotcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRMb2NhbFZhcmlhYmxlVHlwZVRhYmxlKHRoaXMpOwotICB9Ci0KLSAgQE92ZXJyaWRlCi1wdWJsaWMgZmluYWwgdm9pZCBkdW1wKERhdGFPdXRwdXRTdHJlYW0gZmlsZSkgdGhyb3dzIElPRXhjZXB0aW9uCi0gIHsKLSAgICBzdXBlci5kdW1wKGZpbGUpOwotICAgIGZpbGUud3JpdGVTaG9ydChsb2NhbF92YXJpYWJsZV90eXBlX3RhYmxlX2xlbmd0aCk7Ci0gICAgZm9yKGludCBpPTA7IGkgPCBsb2NhbF92YXJpYWJsZV90eXBlX3RhYmxlX2xlbmd0aDsgaSsrKQotICAgICAgbG9jYWxfdmFyaWFibGVfdHlwZV90YWJsZVtpXS5kdW1wKGZpbGUpOwotICB9Ci0KLSAgcHVibGljIGZpbmFsIExvY2FsVmFyaWFibGVbXSBnZXRMb2NhbFZhcmlhYmxlVHlwZVRhYmxlKCkgewotICAgIHJldHVybiBsb2NhbF92YXJpYWJsZV90eXBlX3RhYmxlOwotICB9Ci0KLSAgcHVibGljIGZpbmFsIExvY2FsVmFyaWFibGUgZ2V0TG9jYWxWYXJpYWJsZShpbnQgaW5kZXgpIHsKLSAgICBmb3IoaW50IGk9MDsgaSA8IGxvY2FsX3ZhcmlhYmxlX3R5cGVfdGFibGVfbGVuZ3RoOyBpKyspCi0gICAgICBpZihsb2NhbF92YXJpYWJsZV90eXBlX3RhYmxlW2ldLmdldEluZGV4KCkgPT0gaW5kZXgpCi0gICAgICAgIHJldHVybiBsb2NhbF92YXJpYWJsZV90eXBlX3RhYmxlW2ldOwotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICBwdWJsaWMgZmluYWwgdm9pZCBzZXRMb2NhbFZhcmlhYmxlVGFibGUoTG9jYWxWYXJpYWJsZVtdIGxvY2FsX3ZhcmlhYmxlX3RhYmxlKQotICB7Ci0gICAgdGhpcy5sb2NhbF92YXJpYWJsZV90eXBlX3RhYmxlID0gbG9jYWxfdmFyaWFibGVfdGFibGU7Ci0gICAgbG9jYWxfdmFyaWFibGVfdHlwZV90YWJsZV9sZW5ndGggPSAobG9jYWxfdmFyaWFibGVfdGFibGUgPT0gbnVsbCk/IDAgOgotICAgICAgbG9jYWxfdmFyaWFibGVfdGFibGUubGVuZ3RoOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gU3RyaW5nIHJlcHJlc2VudGF0aW9uLgotICAgKi8KLSAgQE92ZXJyaWRlCi1wdWJsaWMgZmluYWwgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgICAgU3RyaW5nQnVpbGRlciBidWYgPSBuZXcgU3RyaW5nQnVpbGRlcigpOwotCi0gICAgZm9yKGludCBpPTA7IGkgPCBsb2NhbF92YXJpYWJsZV90eXBlX3RhYmxlX2xlbmd0aDsgaSsrKSB7Ci0gICAgICBidWYuYXBwZW5kKGxvY2FsX3ZhcmlhYmxlX3R5cGVfdGFibGVbaV0udG9TdHJpbmcoKSk7Ci0KLSAgICAgIGlmKGkgPCBsb2NhbF92YXJpYWJsZV90eXBlX3RhYmxlX2xlbmd0aCAtIDEpIGJ1Zi5hcHBlbmQoJ1xuJyk7Ci0gICAgfQotCi0gICAgcmV0dXJuIGJ1Zi50b1N0cmluZygpOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gZGVlcCBjb3B5IG9mIHRoaXMgYXR0cmlidXRlCi0gICAqLwotICBAT3ZlcnJpZGUKLXB1YmxpYyBBdHRyaWJ1dGUgY29weShDb25zdGFudFBvb2wgY29uc3RhbnRfcG9vbCkgewotICAgIExvY2FsVmFyaWFibGVUeXBlVGFibGUgYyA9IChMb2NhbFZhcmlhYmxlVHlwZVRhYmxlKWNsb25lKCk7Ci0KLSAgICBjLmxvY2FsX3ZhcmlhYmxlX3R5cGVfdGFibGUgPSBuZXcgTG9jYWxWYXJpYWJsZVtsb2NhbF92YXJpYWJsZV90eXBlX3RhYmxlX2xlbmd0aF07Ci0gICAgZm9yKGludCBpPTA7IGkgPCBsb2NhbF92YXJpYWJsZV90eXBlX3RhYmxlX2xlbmd0aDsgaSsrKQotICAgICAgYy5sb2NhbF92YXJpYWJsZV90eXBlX3RhYmxlW2ldID0gbG9jYWxfdmFyaWFibGVfdHlwZV90YWJsZVtpXS5jb3B5KCk7Ci0KLSAgICBjLmNvbnN0YW50X3Bvb2wgPSBjb25zdGFudF9wb29sOwotICAgIHJldHVybiBjOwotICB9Ci0KLSAgcHVibGljIGZpbmFsIGludCBnZXRUYWJsZUxlbmd0aCgpIHsgcmV0dXJuIGxvY2FsX3ZhcmlhYmxlX3R5cGVfdGFibGVfbGVuZ3RoOyB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvY2xhc3NmaWxlL01ldGhvZC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2NsYXNzZmlsZS9NZXRob2QuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNjNkNzY4OS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvY2xhc3NmaWxlL01ldGhvZC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjMxICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmNsYXNzZmlsZTsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5UeXBlOwotaW1wb3J0IGphdmEuaW8uKjsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIHJlcHJlc2VudHMgdGhlIG1ldGhvZCBpbmZvIHN0cnVjdHVyZSwgaS5lLiwgdGhlIHJlcHJlc2VudGF0aW9uCi0gKiBmb3IgYSBtZXRob2QgaW4gdGhlIGNsYXNzLiBTZWUgSlZNIHNwZWNpZmljYXRpb24gZm9yIGRldGFpbHMuCi0gKiBBIG1ldGhvZCBoYXMgYWNjZXNzIGZsYWdzLCBhIG5hbWUsIGEgc2lnbmF0dXJlIGFuZCBhIG51bWJlciBvZiBhdHRyaWJ1dGVzLgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBNZXRob2QgZXh0ZW5kcyBGaWVsZE9yTWV0aG9kIHsKLSAgLyoqCi0gICAqIEVtcHR5IGNvbnN0cnVjdG9yLCBhbGwgYXR0cmlidXRlcyBoYXZlIHRvIGJlIGRlZmluZWQgdmlhIGBzZXRYWFgnCi0gICAqIG1ldGhvZHMuIFVzZSBhdCB5b3VyIG93biByaXNrLgotICAgKi8KLSAgcHVibGljIE1ldGhvZCgpIHt9Ci0KLSAgLyoqCi0gICAqIEluaXRpYWxpemUgZnJvbSBhbm90aGVyIG9iamVjdC4gTm90ZSB0aGF0IGJvdGggb2JqZWN0cyB1c2UgdGhlIHNhbWUKLSAgICogcmVmZXJlbmNlcyAoc2hhbGxvdyBjb3B5KS4gVXNlIGNsb25lKCkgZm9yIGEgcGh5c2ljYWwgY29weS4KLSAgICovCi0gIHB1YmxpYyBNZXRob2QoTWV0aG9kIGMpIHsKLSAgICBzdXBlcihjKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3Qgb2JqZWN0IGZyb20gZmlsZSBzdHJlYW0uCi0gICAqIEBwYXJhbSBmaWxlIElucHV0IHN0cmVhbQotICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0gICAqIEB0aHJvd3MgQ2xhc3NGb3JtYXRFeGNlcHRpb24KLSAgICovCi0gIE1ldGhvZChEYXRhSW5wdXRTdHJlYW0gZmlsZSwgQ29uc3RhbnRQb29sIGNvbnN0YW50X3Bvb2wpCi0gICAgdGhyb3dzIElPRXhjZXB0aW9uLCBDbGFzc0Zvcm1hdEV4Y2VwdGlvbgotICB7Ci0gICAgc3VwZXIoZmlsZSwgY29uc3RhbnRfcG9vbCk7Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIGFjY2Vzc19mbGFncyBBY2Nlc3MgcmlnaHRzIG9mIG1ldGhvZAotICAgKiBAcGFyYW0gbmFtZV9pbmRleCBQb2ludHMgdG8gZmllbGQgbmFtZSBpbiBjb25zdGFudCBwb29sCi0gICAqIEBwYXJhbSBzaWduYXR1cmVfaW5kZXggUG9pbnRzIHRvIGVuY29kZWQgc2lnbmF0dXJlCi0gICAqIEBwYXJhbSBhdHRyaWJ1dGVzIENvbGxlY3Rpb24gb2YgYXR0cmlidXRlcwotICAgKiBAcGFyYW0gY29uc3RhbnRfcG9vbCBBcnJheSBvZiBjb25zdGFudHMKLSAgICovCi0gIHB1YmxpYyBNZXRob2QoaW50IGFjY2Vzc19mbGFncywgaW50IG5hbWVfaW5kZXgsIGludCBzaWduYXR1cmVfaW5kZXgsCi0gICAgICAgICAgICAgICAgQXR0cmlidXRlW10gYXR0cmlidXRlcywgQ29uc3RhbnRQb29sIGNvbnN0YW50X3Bvb2wpCi0gIHsKLSAgICBzdXBlcihhY2Nlc3NfZmxhZ3MsIG5hbWVfaW5kZXgsIHNpZ25hdHVyZV9pbmRleCwgYXR0cmlidXRlcywgY29uc3RhbnRfcG9vbCk7Ci0gIH0KLQotICAvKioKLSAgICogQ2FsbGVkIGJ5IG9iamVjdHMgdGhhdCBhcmUgdHJhdmVyc2luZyB0aGUgbm9kZXMgb2YgdGhlIHRyZWUgaW1wbGljaXRlbHkKLSAgICogZGVmaW5lZCBieSB0aGUgY29udGVudHMgb2YgYSBKYXZhIGNsYXNzLiBJLmUuLCB0aGUgaGllcmFyY2h5IG9mIG1ldGhvZHMsCi0gICAqIGZpZWxkcywgYXR0cmlidXRlcywgZXRjLiBzcGF3bnMgYSB0cmVlIG9mIG9iamVjdHMuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgdi52aXNpdE1ldGhvZCh0aGlzKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIENvZGUgYXR0cmlidXRlIG9mIG1ldGhvZCwgaWYgYW55Ci0gICAqLwotICBwdWJsaWMgZmluYWwgQ29kZSBnZXRDb2RlKCkgewotICAgIGZvcihpbnQgaT0wOyBpIDwgYXR0cmlidXRlc19jb3VudDsgaSsrKQotICAgICAgaWYoYXR0cmlidXRlc1tpXSBpbnN0YW5jZW9mIENvZGUpCi0gICAgICAgIHJldHVybiAoQ29kZSlhdHRyaWJ1dGVzW2ldOwotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBFeGNlcHRpb25UYWJsZSBhdHRyaWJ1dGUgb2YgbWV0aG9kLCBpZiBhbnksIGkuZS4sIGxpc3QgYWxsCi0gICAqIGV4Y2VwdGlvbnMgdGhlIG1ldGhvZCBtYXkgdGhyb3cgbm90IGV4Y2VwdGlvbiBoYW5kbGVycyEKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBFeGNlcHRpb25UYWJsZSBnZXRFeGNlcHRpb25UYWJsZSgpIHsKLSAgICBmb3IoaW50IGk9MDsgaSA8IGF0dHJpYnV0ZXNfY291bnQ7IGkrKykKLSAgICAgIGlmKGF0dHJpYnV0ZXNbaV0gaW5zdGFuY2VvZiBFeGNlcHRpb25UYWJsZSkKLSAgICAgICAgcmV0dXJuIChFeGNlcHRpb25UYWJsZSlhdHRyaWJ1dGVzW2ldOwotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKiogQHJldHVybiBMb2NhbFZhcmlhYmxlVGFibGUgb2YgY29kZSBhdHRyaWJ1dGUgaWYgYW55LCBpLmUuIHRoZSBjYWxsIGlzIGZvcndhcmRlZAotICAgKiB0byB0aGUgQ29kZSBhdHJpYnV0ZS4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBMb2NhbFZhcmlhYmxlVGFibGUgZ2V0TG9jYWxWYXJpYWJsZVRhYmxlKCkgewotICAgIENvZGUgY29kZSA9IGdldENvZGUoKTsKLQotICAgIGlmKGNvZGUgIT0gbnVsbCkKLSAgICAgIHJldHVybiBjb2RlLmdldExvY2FsVmFyaWFibGVUYWJsZSgpOwotICAgIGVsc2UKLSAgICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqIEByZXR1cm4gTGluZU51bWJlclRhYmxlIG9mIGNvZGUgYXR0cmlidXRlIGlmIGFueSwgaS5lLiB0aGUgY2FsbCBpcyBmb3J3YXJkZWQKLSAgICogdG8gdGhlIENvZGUgYXRyaWJ1dGUuCi0gICAqLwotICBwdWJsaWMgZmluYWwgTGluZU51bWJlclRhYmxlIGdldExpbmVOdW1iZXJUYWJsZSgpIHsKLSAgICBDb2RlIGNvZGUgPSBnZXRDb2RlKCk7Ci0KLSAgICBpZihjb2RlICE9IG51bGwpCi0gICAgICByZXR1cm4gY29kZS5nZXRMaW5lTnVtYmVyVGFibGUoKTsKLSAgICBlbHNlCi0gICAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gc3RyaW5nIHJlcHJlc2VudGF0aW9uIGNsb3NlIHRvIGRlY2xhcmF0aW9uIGZvcm1hdCwKLSAgICogYHB1YmxpYyBzdGF0aWMgdm9pZCBfbWFpbihTdHJpbmdbXSBhcmdzKSB0aHJvd3MgSU9FeGNlcHRpb24nLCBlLmcuCi0gICAqCi0gICAqIEByZXR1cm4gU3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBtZXRob2QuCi0gICAqLwotICBwdWJsaWMgZmluYWwgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgIENvbnN0YW50VXRmOCAgYzsKLSAgICBTdHJpbmcgICAgICAgIG5hbWUsIHNpZ25hdHVyZSwgYWNjZXNzOyAvLyBTaG9ydCBjdXRzIHRvIGNvbnN0YW50IHBvb2wKLSAgICBTdHJpbmdCdWZmZXIgIGJ1ZjsKLQotICAgIGFjY2VzcyA9IFV0aWxpdHkuYWNjZXNzVG9TdHJpbmcoYWNjZXNzX2ZsYWdzKTsKLQotICAgIC8vIEdldCBuYW1lIGFuZCBzaWduYXR1cmUgZnJvbSBjb25zdGFudCBwb29sCi0gICAgYyA9IChDb25zdGFudFV0ZjgpY29uc3RhbnRfcG9vbC5nZXRDb25zdGFudChzaWduYXR1cmVfaW5kZXgsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb25zdGFudHMuQ09OU1RBTlRfVXRmOCk7Ci0gICAgc2lnbmF0dXJlID0gYy5nZXRCeXRlcygpOwotCi0gICAgYyA9IChDb25zdGFudFV0ZjgpY29uc3RhbnRfcG9vbC5nZXRDb25zdGFudChuYW1lX2luZGV4LCBDb25zdGFudHMuQ09OU1RBTlRfVXRmOCk7Ci0gICAgbmFtZSA9IGMuZ2V0Qnl0ZXMoKTsKLQotICAgIHNpZ25hdHVyZSA9IFV0aWxpdHkubWV0aG9kU2lnbmF0dXJlVG9TdHJpbmcoc2lnbmF0dXJlLCBuYW1lLCBhY2Nlc3MsIHRydWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRMb2NhbFZhcmlhYmxlVGFibGUoKSk7Ci0gICAgYnVmID0gbmV3IFN0cmluZ0J1ZmZlcihzaWduYXR1cmUpOwotCi0gICAgZm9yKGludCBpPTA7IGkgPCBhdHRyaWJ1dGVzX2NvdW50OyBpKyspIHsKLSAgICAgIEF0dHJpYnV0ZSBhID0gYXR0cmlidXRlc1tpXTsKLQotICAgICAgaWYoISgoYSBpbnN0YW5jZW9mIENvZGUpIHx8IChhIGluc3RhbmNlb2YgRXhjZXB0aW9uVGFibGUpKSkKLSAgICAgICAgYnVmLmFwcGVuZCgiIFsiICsgYS50b1N0cmluZygpICsgIl0iKTsKLSAgICB9Ci0KLSAgICBFeGNlcHRpb25UYWJsZSBlID0gZ2V0RXhjZXB0aW9uVGFibGUoKTsKLSAgICBpZihlICE9IG51bGwpIHsKLSAgICAgIFN0cmluZyBzdHIgPSBlLnRvU3RyaW5nKCk7Ci0gICAgICBpZighc3RyLmVxdWFscygiIikpCi0gICAgICAgIGJ1Zi5hcHBlbmQoIlxuXHRcdHRocm93cyAiICsgc3RyKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gYnVmLnRvU3RyaW5nKCk7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBkZWVwIGNvcHkgb2YgdGhpcyBtZXRob2QKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBNZXRob2QgY29weShDb25zdGFudFBvb2wgY29uc3RhbnRfcG9vbCkgewotICAgIHJldHVybiAoTWV0aG9kKWNvcHlfKGNvbnN0YW50X3Bvb2wpOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gcmV0dXJuIHR5cGUgb2YgbWV0aG9kCi0gICAqLwotICBwdWJsaWMgVHlwZSBnZXRSZXR1cm5UeXBlKCkgewotICAgIHJldHVybiBUeXBlLmdldFJldHVyblR5cGUoZ2V0U2lnbmF0dXJlKCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gYXJyYXkgb2YgbWV0aG9kIGFyZ3VtZW50IHR5cGVzCi0gICAqLwotICBwdWJsaWMgVHlwZVtdIGdldEFyZ3VtZW50VHlwZXMoKSB7Ci0gICAgcmV0dXJuIFR5cGUuZ2V0QXJndW1lbnRUeXBlcyhnZXRTaWduYXR1cmUoKSk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvTm9kZS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2NsYXNzZmlsZS9Ob2RlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDhkMjM5YzQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2NsYXNzZmlsZS9Ob2RlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw2OCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5jbGFzc2ZpbGU7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8qKgotICogRGVub3RlIGNsYXNzIHRvIGhhdmUgYW4gYWNjZXB0IG1ldGhvZCgpOwotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgTm9kZSB7Ci0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIG9iaik7Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvY2xhc3NmaWxlL1BNR0NsYXNzLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvY2xhc3NmaWxlL1BNR0NsYXNzLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDk5OWQ4NzYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2NsYXNzZmlsZS9QTUdDbGFzcy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTkyICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmNsYXNzZmlsZTsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotaW1wb3J0ICBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHM7Ci1pbXBvcnQgIGphdmEuaW8uKjsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGlzIGRlcml2ZWQgZnJvbSA8ZW0+QXR0cmlidXRlPC9lbT4gYW5kIHJlcHJlc2VudHMgYSByZWZlcmVuY2UKLSAqIHRvIGEgPGEgaHJlZj0iaHR0cDovL3d3dy5pbmYuZnUtYmVybGluLmRlL35ib2tvd3NraS9wbWdqYXZhL2luZGV4Lmh0bWwiPlBNRzwvYT4KLSAqIGF0dHJpYnV0ZS4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICogQHNlZSAgICAgQXR0cmlidXRlCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBQTUdDbGFzcyBleHRlbmRzIEF0dHJpYnV0ZSB7Ci0gIHByaXZhdGUgaW50IHBtZ19jbGFzc19pbmRleCwgcG1nX2luZGV4OwotCi0gIC8qKgotICAgKiBJbml0aWFsaXplIGZyb20gYW5vdGhlciBvYmplY3QuIE5vdGUgdGhhdCBib3RoIG9iamVjdHMgdXNlIHRoZSBzYW1lCi0gICAqIHJlZmVyZW5jZXMgKHNoYWxsb3cgY29weSkuIFVzZSBjbG9uZSgpIGZvciBhIHBoeXNpY2FsIGNvcHkuCi0gICAqLwotICBwdWJsaWMgUE1HQ2xhc3MoUE1HQ2xhc3MgYykgewotICAgIHRoaXMoYy5nZXROYW1lSW5kZXgoKSwgYy5nZXRMZW5ndGgoKSwgYy5nZXRQTUdJbmRleCgpLCBjLmdldFBNR0NsYXNzSW5kZXgoKSwKLSAgICAgICAgIGMuZ2V0Q29uc3RhbnRQb29sKCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBvYmplY3QgZnJvbSBmaWxlIHN0cmVhbS4KLSAgICogQHBhcmFtIG5hbWVfaW5kZXggSW5kZXggaW4gY29uc3RhbnQgcG9vbCB0byBDT05TVEFOVF9VdGY4Ci0gICAqIEBwYXJhbSBsZW5ndGggQ29udGVudCBsZW5ndGggaW4gYnl0ZXMKLSAgICogQHBhcmFtIGZpbGUgSW5wdXQgc3RyZWFtCi0gICAqIEBwYXJhbSBjb25zdGFudF9wb29sIEFycmF5IG9mIGNvbnN0YW50cwotICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0gICAqLwotICBQTUdDbGFzcyhpbnQgbmFtZV9pbmRleCwgaW50IGxlbmd0aCwgRGF0YUlucHV0U3RyZWFtIGZpbGUsCi0gICAgICAgICAgIENvbnN0YW50UG9vbCBjb25zdGFudF9wb29sKSB0aHJvd3MgSU9FeGNlcHRpb24KLSAgewotICAgIHRoaXMobmFtZV9pbmRleCwgbGVuZ3RoLCBmaWxlLnJlYWRVbnNpZ25lZFNob3J0KCksIGZpbGUucmVhZFVuc2lnbmVkU2hvcnQoKSwKLSAgICAgICAgIGNvbnN0YW50X3Bvb2wpOwotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBuYW1lX2luZGV4IEluZGV4IGluIGNvbnN0YW50IHBvb2wgdG8gQ09OU1RBTlRfVXRmOAotICAgKiBAcGFyYW0gbGVuZ3RoIENvbnRlbnQgbGVuZ3RoIGluIGJ5dGVzCi0gICAqIEBwYXJhbSBjb25zdGFudF9wb29sIEFycmF5IG9mIGNvbnN0YW50cwotICAgKiBAcGFyYW0gUE1HQ2xhc3NfaW5kZXggSW5kZXggaW4gY29uc3RhbnQgcG9vbCB0byBDT05TVEFOVF9VdGY4Ci0gICAqLwotICBwdWJsaWMgUE1HQ2xhc3MoaW50IG5hbWVfaW5kZXgsIGludCBsZW5ndGgsIGludCBwbWdfaW5kZXgsIGludCBwbWdfY2xhc3NfaW5kZXgsCi0gICAgICAgICAgICAgICAgICBDb25zdGFudFBvb2wgY29uc3RhbnRfcG9vbCkKLSAgewotICAgIHN1cGVyKENvbnN0YW50cy5BVFRSX1BNRywgbmFtZV9pbmRleCwgbGVuZ3RoLCBjb25zdGFudF9wb29sKTsKLSAgICB0aGlzLnBtZ19pbmRleCAgICAgICA9IHBtZ19pbmRleDsKLSAgICB0aGlzLnBtZ19jbGFzc19pbmRleCA9IHBtZ19jbGFzc19pbmRleDsKLSAgfQotCi0gIC8qKgotICAgKiBDYWxsZWQgYnkgb2JqZWN0cyB0aGF0IGFyZSB0cmF2ZXJzaW5nIHRoZSBub2RlcyBvZiB0aGUgdHJlZSBpbXBsaWNpdGVseQotICAgKiBkZWZpbmVkIGJ5IHRoZSBjb250ZW50cyBvZiBhIEphdmEgY2xhc3MuIEkuZS4sIHRoZSBoaWVyYXJjaHkgb2YgbWV0aG9kcywKLSAgICogZmllbGRzLCBhdHRyaWJ1dGVzLCBldGMuIHNwYXducyBhIHRyZWUgb2Ygb2JqZWN0cy4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgIFN5c3RlbS5lcnIucHJpbnRsbigiVmlzaXRpbmcgbm9uLXN0YW5kYXJkIFBNR0NsYXNzIG9iamVjdCIpOwotICAgfQotCi0gIC8qKgotICAgKiBEdW1wIHNvdXJjZSBmaWxlIGF0dHJpYnV0ZSB0byBmaWxlIHN0cmVhbSBpbiBiaW5hcnkgZm9ybWF0LgotICAgKgotICAgKiBAcGFyYW0gZmlsZSBPdXRwdXQgZmlsZSBzdHJlYW0KLSAgICogQHRocm93cyBJT0V4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgZHVtcChEYXRhT3V0cHV0U3RyZWFtIGZpbGUpIHRocm93cyBJT0V4Y2VwdGlvbgotICB7Ci0gICAgc3VwZXIuZHVtcChmaWxlKTsKLSAgICBmaWxlLndyaXRlU2hvcnQocG1nX2luZGV4KTsKLSAgICBmaWxlLndyaXRlU2hvcnQocG1nX2NsYXNzX2luZGV4KTsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIEluZGV4IGluIGNvbnN0YW50IHBvb2wgb2Ygc291cmNlIGZpbGUgbmFtZS4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBpbnQgZ2V0UE1HQ2xhc3NJbmRleCgpIHsgcmV0dXJuIHBtZ19jbGFzc19pbmRleDsgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gUE1HQ2xhc3NfaW5kZXguCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBzZXRQTUdDbGFzc0luZGV4KGludCBwbWdfY2xhc3NfaW5kZXgpIHsKLSAgICB0aGlzLnBtZ19jbGFzc19pbmRleCA9IHBtZ19jbGFzc19pbmRleDsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIEluZGV4IGluIGNvbnN0YW50IHBvb2wgb2Ygc291cmNlIGZpbGUgbmFtZS4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBpbnQgZ2V0UE1HSW5kZXgoKSB7IHJldHVybiBwbWdfaW5kZXg7IH0KLQotICAvKioKLSAgICogQHBhcmFtIFBNR0NsYXNzX2luZGV4LgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgc2V0UE1HSW5kZXgoaW50IHBtZ19pbmRleCkgewotICAgIHRoaXMucG1nX2luZGV4ID0gcG1nX2luZGV4OwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gUE1HIG5hbWUuCi0gICAqLwotICBwdWJsaWMgZmluYWwgU3RyaW5nIGdldFBNR05hbWUoKSB7Ci0gICAgQ29uc3RhbnRVdGY4IGMgPSAoQ29uc3RhbnRVdGY4KWNvbnN0YW50X3Bvb2wuZ2V0Q29uc3RhbnQocG1nX2luZGV4LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbnN0YW50cy5DT05TVEFOVF9VdGY4KTsKLSAgICByZXR1cm4gYy5nZXRCeXRlcygpOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gUE1HIGNsYXNzIG5hbWUuCi0gICAqLwotICBwdWJsaWMgZmluYWwgU3RyaW5nIGdldFBNR0NsYXNzTmFtZSgpIHsKLSAgICBDb25zdGFudFV0ZjggYyA9IChDb25zdGFudFV0ZjgpY29uc3RhbnRfcG9vbC5nZXRDb25zdGFudChwbWdfY2xhc3NfaW5kZXgsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29uc3RhbnRzLkNPTlNUQU5UX1V0ZjgpOwotICAgIHJldHVybiBjLmdldEJ5dGVzKCk7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBTdHJpbmcgcmVwcmVzZW50YXRpb24KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0gICAgcmV0dXJuICJQTUdDbGFzcygiICsgZ2V0UE1HTmFtZSgpICsgIiwgIiArIGdldFBNR0NsYXNzTmFtZSgpICsgIikiOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gZGVlcCBjb3B5IG9mIHRoaXMgYXR0cmlidXRlCi0gICAqLwotICBwdWJsaWMgQXR0cmlidXRlIGNvcHkoQ29uc3RhbnRQb29sIGNvbnN0YW50X3Bvb2wpIHsKLSAgICByZXR1cm4gKFBNR0NsYXNzKWNsb25lKCk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvU2lnbmF0dXJlLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvY2xhc3NmaWxlL1NpZ25hdHVyZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlMGI5Y2M1Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvU2lnbmF0dXJlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyOTkgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuY2xhc3NmaWxlOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi1pbXBvcnQgIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50czsKLWltcG9ydCAgamF2YS5pby4qOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgaXMgZGVyaXZlZCBmcm9tIDxlbT5BdHRyaWJ1dGU8L2VtPiBhbmQgcmVwcmVzZW50cyBhIHJlZmVyZW5jZQotICogdG8gYSA8aHJlZj0iaHR0cDovL3d3d2lwZC5pcmEudWthLmRlL35waXp6YS9nai8iPkdKPC9hPiBhdHRyaWJ1dGUuCi0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqIEBzZWUgICAgIEF0dHJpYnV0ZQotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgU2lnbmF0dXJlIGV4dGVuZHMgQXR0cmlidXRlIHsKLSAgcHJpdmF0ZSBpbnQgc2lnbmF0dXJlX2luZGV4OwotCi0gIC8qKgotICAgKiBJbml0aWFsaXplIGZyb20gYW5vdGhlciBvYmplY3QuIE5vdGUgdGhhdCBib3RoIG9iamVjdHMgdXNlIHRoZSBzYW1lCi0gICAqIHJlZmVyZW5jZXMgKHNoYWxsb3cgY29weSkuIFVzZSBjbG9uZSgpIGZvciBhIHBoeXNpY2FsIGNvcHkuCi0gICAqLwotICBwdWJsaWMgU2lnbmF0dXJlKFNpZ25hdHVyZSBjKSB7Ci0gICAgdGhpcyhjLmdldE5hbWVJbmRleCgpLCBjLmdldExlbmd0aCgpLCBjLmdldFNpZ25hdHVyZUluZGV4KCksIGMuZ2V0Q29uc3RhbnRQb29sKCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBvYmplY3QgZnJvbSBmaWxlIHN0cmVhbS4KLSAgICogQHBhcmFtIG5hbWVfaW5kZXggSW5kZXggaW4gY29uc3RhbnQgcG9vbCB0byBDT05TVEFOVF9VdGY4Ci0gICAqIEBwYXJhbSBsZW5ndGggQ29udGVudCBsZW5ndGggaW4gYnl0ZXMKLSAgICogQHBhcmFtIGZpbGUgSW5wdXQgc3RyZWFtCi0gICAqIEBwYXJhbSBjb25zdGFudF9wb29sIEFycmF5IG9mIGNvbnN0YW50cwotICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0gICAqLwotICBTaWduYXR1cmUoaW50IG5hbWVfaW5kZXgsIGludCBsZW5ndGgsIERhdGFJbnB1dFN0cmVhbSBmaWxlLAotICAgICAgICAgICBDb25zdGFudFBvb2wgY29uc3RhbnRfcG9vbCkgdGhyb3dzIElPRXhjZXB0aW9uCi0gIHsKLSAgICB0aGlzKG5hbWVfaW5kZXgsIGxlbmd0aCwgZmlsZS5yZWFkVW5zaWduZWRTaG9ydCgpLCBjb25zdGFudF9wb29sKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gbmFtZV9pbmRleCBJbmRleCBpbiBjb25zdGFudCBwb29sIHRvIENPTlNUQU5UX1V0ZjgKLSAgICogQHBhcmFtIGxlbmd0aCBDb250ZW50IGxlbmd0aCBpbiBieXRlcwotICAgKiBAcGFyYW0gY29uc3RhbnRfcG9vbCBBcnJheSBvZiBjb25zdGFudHMKLSAgICogQHBhcmFtIFNpZ25hdHVyZV9pbmRleCBJbmRleCBpbiBjb25zdGFudCBwb29sIHRvIENPTlNUQU5UX1V0ZjgKLSAgICovCi0gIHB1YmxpYyBTaWduYXR1cmUoaW50IG5hbWVfaW5kZXgsIGludCBsZW5ndGgsIGludCBzaWduYXR1cmVfaW5kZXgsCi0gICAgICAgICAgICAgICAgICBDb25zdGFudFBvb2wgY29uc3RhbnRfcG9vbCkKLSAgewotICAgIHN1cGVyKENvbnN0YW50cy5BVFRSX1NJR05BVFVSRSwgbmFtZV9pbmRleCwgbGVuZ3RoLCBjb25zdGFudF9wb29sKTsKLSAgICB0aGlzLnNpZ25hdHVyZV9pbmRleCA9IHNpZ25hdHVyZV9pbmRleDsKLSAgfQotCi0gIC8qKgotICAgKiBDYWxsZWQgYnkgb2JqZWN0cyB0aGF0IGFyZSB0cmF2ZXJzaW5nIHRoZSBub2RlcyBvZiB0aGUgdHJlZSBpbXBsaWNpdGVseQotICAgKiBkZWZpbmVkIGJ5IHRoZSBjb250ZW50cyBvZiBhIEphdmEgY2xhc3MuIEkuZS4sIHRoZSBoaWVyYXJjaHkgb2YgbWV0aG9kcywKLSAgICogZmllbGRzLCBhdHRyaWJ1dGVzLCBldGMuIHNwYXducyBhIHRyZWUgb2Ygb2JqZWN0cy4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgIFN5c3RlbS5lcnIucHJpbnRsbigiVmlzaXRpbmcgbm9uLXN0YW5kYXJkIFNpZ25hdHVyZSBvYmplY3QiKTsKLSAgICAgdi52aXNpdFNpZ25hdHVyZSh0aGlzKTsKLSAgIH0KLQotICAvKioKLSAgICogRHVtcCBzb3VyY2UgZmlsZSBhdHRyaWJ1dGUgdG8gZmlsZSBzdHJlYW0gaW4gYmluYXJ5IGZvcm1hdC4KLSAgICoKLSAgICogQHBhcmFtIGZpbGUgT3V0cHV0IGZpbGUgc3RyZWFtCi0gICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIGR1bXAoRGF0YU91dHB1dFN0cmVhbSBmaWxlKSB0aHJvd3MgSU9FeGNlcHRpb24KLSAgewotICAgIHN1cGVyLmR1bXAoZmlsZSk7Ci0gICAgZmlsZS53cml0ZVNob3J0KHNpZ25hdHVyZV9pbmRleCk7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBJbmRleCBpbiBjb25zdGFudCBwb29sIG9mIHNvdXJjZSBmaWxlIG5hbWUuCi0gICAqLwotICBwdWJsaWMgZmluYWwgaW50IGdldFNpZ25hdHVyZUluZGV4KCkgeyByZXR1cm4gc2lnbmF0dXJlX2luZGV4OyB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBTaWduYXR1cmVfaW5kZXguCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBzZXRTaWduYXR1cmVJbmRleChpbnQgc2lnbmF0dXJlX2luZGV4KSB7Ci0gICAgdGhpcy5zaWduYXR1cmVfaW5kZXggPSBzaWduYXR1cmVfaW5kZXg7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBHSiBzaWduYXR1cmUuCi0gICAqLwotICBwdWJsaWMgZmluYWwgU3RyaW5nIGdldFNpZ25hdHVyZSgpIHsKLSAgICBDb25zdGFudFV0ZjggYyA9IChDb25zdGFudFV0ZjgpY29uc3RhbnRfcG9vbC5nZXRDb25zdGFudChzaWduYXR1cmVfaW5kZXgsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29uc3RhbnRzLkNPTlNUQU5UX1V0ZjgpOwotICAgIHJldHVybiBjLmdldEJ5dGVzKCk7Ci0gIH0KLQotICAvKioKLSAgICogRXh0ZW5kcyBCeXRlQXJyYXlJbnB1dFN0cmVhbSB0byBtYWtlICd1bnJlYWRpbmcnIGNoYXJzIHBvc3NpYmxlLgotICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgTXlCeXRlQXJyYXlJbnB1dFN0cmVhbSBleHRlbmRzIEJ5dGVBcnJheUlucHV0U3RyZWFtIHsKLSAgICBNeUJ5dGVBcnJheUlucHV0U3RyZWFtKFN0cmluZyBkYXRhKSB7IHN1cGVyKGRhdGEuZ2V0Qnl0ZXMoKSk7IH0KLSAgICBmaW5hbCBpbnQgIG1hcmsoKSAgICAgICAgICAgICAgICAgICB7IHJldHVybiBwb3M7IH0KLSAgICBmaW5hbCBTdHJpbmcgZ2V0RGF0YSgpICAgICAgICAgICAgICB7IHJldHVybiBuZXcgU3RyaW5nKGJ1Zik7IH0KLSAgICBmaW5hbCB2b2lkIHJlc2V0KGludCBwKSAgICAgICAgICAgICB7IHBvcyA9IHA7IH0KLSAgICBmaW5hbCB2b2lkIHVucmVhZCgpICAgICAgICAgICAgICAgICB7IGlmKHBvcyA+IDApIHBvcy0tOyB9Ci0gIH0KLQotICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGlkZW50U3RhcnQoaW50IGNoKSB7Ci0gICAgcmV0dXJuIGNoID09ICdUJyB8fCBjaCA9PSAnTCc7Ci0gIH0KLQotICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGlkZW50UGFydChpbnQgY2gpIHsKLSAgICByZXR1cm4gY2ggPT0gJy8nIHx8IGNoID09ICc7JzsKLSAgfQotCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIHZvaWQgbWF0Y2hJZGVudChNeUJ5dGVBcnJheUlucHV0U3RyZWFtIGluLCBTdHJpbmdCdWZmZXIgYnVmKSB7Ci0gICAgaW50IGNoOwotCi0gICAgaWYoKGNoID0gaW4ucmVhZCgpKSA9PSAtMSkKLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJJbGxlZ2FsIHNpZ25hdHVyZTogIiArIGluLmdldERhdGEoKSArCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIG5vIGlkZW50LCByZWFjaGluZyBFT0YiKTsKLQotICAgIC8vU3lzdGVtLm91dC5wcmludGxuKCJyZXR1cm4gZnJvbSBpZGVudDoiICsgKGNoYXIpY2gpOwotCi0gICAgaWYoIWlkZW50U3RhcnQoY2gpKSB7Ci0gICAgICBTdHJpbmdCdWZmZXIgYnVmMiA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLQotICAgICAgaW50IGNvdW50ID0gMTsKLSAgICAgIHdoaWxlKENoYXJhY3Rlci5pc0phdmFJZGVudGlmaWVyUGFydCgoY2hhciljaCkpIHsKLSAgICAgICAgYnVmMi5hcHBlbmQoKGNoYXIpY2gpOwotICAgICAgICBjb3VudCsrOwotICAgICAgICBjaCA9IGluLnJlYWQoKTsKLSAgICAgIH0KLQotICAgICAgaWYoY2ggPT0gJzonKSB7IC8vIE9rLCBmb3JtYWwgcGFyYW1ldGVyCi0gICAgICAgIGluLnNraXAoIkxqYXZhL2xhbmcvT2JqZWN0Ii5sZW5ndGgoKSk7Ci0gICAgICAgIGJ1Zi5hcHBlbmQoYnVmMik7Ci0KLSAgICAgICAgY2ggPSBpbi5yZWFkKCk7Ci0gICAgICAgIGluLnVucmVhZCgpOwotICAgICAgICAvL1N5c3RlbS5vdXQucHJpbnRsbigic28gZmFyOiIgKyBidWYyICsgIjpuZXh0OiIgKyhjaGFyKWNoKTsKLSAgICAgIH0gZWxzZSB7Ci0gICAgICAgIGZvcihpbnQgaT0wOyBpIDwgY291bnQ7IGkrKykKLSAgICAgICAgICBpbi51bnJlYWQoKTsKLSAgICAgIH0KLQotICAgICAgcmV0dXJuOwotICAgIH0KLQotICAgIFN0cmluZ0J1ZmZlciBidWYyID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotICAgIGNoID0gaW4ucmVhZCgpOwotCi0gICAgZG8gewotICAgICAgYnVmMi5hcHBlbmQoKGNoYXIpY2gpOwotICAgICAgY2ggPSBpbi5yZWFkKCk7Ci0gICAgICAvL1N5c3RlbS5vdXQucHJpbnRsbigid2l0aGluIGlkZW50OiIrIChjaGFyKWNoKTsKLQotICAgIH0gd2hpbGUoKGNoICE9IC0xKSAmJiAoQ2hhcmFjdGVyLmlzSmF2YUlkZW50aWZpZXJQYXJ0KChjaGFyKWNoKSB8fCAoY2ggPT0gJy8nKSkpOwotCi0gICAgYnVmLmFwcGVuZChidWYyLnRvU3RyaW5nKCkucmVwbGFjZSgnLycsICcuJykpOwotCi0gICAgLy9TeXN0ZW0ub3V0LnByaW50bG4oInJlZ3VsYXIgcmV0dXJuIGlkZW50OiIrIChjaGFyKWNoICsgIjoiICsgYnVmMik7Ci0KLSAgICBpZihjaCAhPSAtMSkKLSAgICAgIGluLnVucmVhZCgpOwotICB9Ci0KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgdm9pZCBtYXRjaEdKSWRlbnQoTXlCeXRlQXJyYXlJbnB1dFN0cmVhbSBpbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nQnVmZmVyIGJ1ZikKLSAgewotICAgIGludCBjaDsKLQotICAgIG1hdGNoSWRlbnQoaW4sIGJ1Zik7Ci0KLSAgICBjaCA9IGluLnJlYWQoKTsKLSAgICBpZigoY2ggPT0gJzwnKSB8fCBjaCA9PSAnKCcpIHsgLy8gUGFyYW1ldGVyaXplZCBvciBtZXRob2QKLSAgICAgIC8vU3lzdGVtLm91dC5wcmludGxuKCJFbnRlciA8Iik7Ci0gICAgICBidWYuYXBwZW5kKChjaGFyKWNoKTsKLSAgICAgIG1hdGNoR0pJZGVudChpbiwgYnVmKTsKLQotICAgICAgd2hpbGUoKChjaCA9IGluLnJlYWQoKSkgIT0gJz4nKSAmJiAoY2ggIT0gJyknKSkgeyAvLyBMaXN0IG9mIHBhcmFtZXRlcnMKLSAgICAgICAgaWYoY2ggPT0gLTEpCi0gICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIklsbGVnYWwgc2lnbmF0dXJlOiAiICsgaW4uZ2V0RGF0YSgpICsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIHJlYWNoaW5nIEVPRiIpOwotCi0gICAgICAgIC8vU3lzdGVtLm91dC5wcmludGxuKCJTdGlsbCBubyA+Iik7Ci0gICAgICAgIGJ1Zi5hcHBlbmQoIiwgIik7Ci0gICAgICAgIGluLnVucmVhZCgpOwotICAgICAgICBtYXRjaEdKSWRlbnQoaW4sIGJ1Zik7IC8vIFJlY3Vyc2l2ZSBjYWxsCi0gICAgICB9Ci0KLSAgICAgIC8vU3lzdGVtLm91dC5wcmludGxuKCJFeGl0ID4iKTsKLQotICAgICAgYnVmLmFwcGVuZCgoY2hhciljaCk7Ci0gICAgfSBlbHNlCi0gICAgICBpbi51bnJlYWQoKTsKLQotICAgIGNoID0gaW4ucmVhZCgpOwotICAgIGlmKGlkZW50U3RhcnQoY2gpKSB7Ci0gICAgICBpbi51bnJlYWQoKTsKLSAgICAgIG1hdGNoR0pJZGVudChpbiwgYnVmKTsKLSAgICB9IGVsc2UgaWYoY2ggPT0gJyknKSB7Ci0gICAgICBpbi51bnJlYWQoKTsKLSAgICAgIHJldHVybjsKLSAgICB9IGVsc2UgaWYoY2ggIT0gJzsnKQotICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIklsbGVnYWwgc2lnbmF0dXJlOiAiICsgaW4uZ2V0RGF0YSgpICsgIiByZWFkICIgKwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNoYXIpY2gpOwotICB9Ci0KLSAgcHVibGljIHN0YXRpYyBTdHJpbmcgdHJhbnNsYXRlKFN0cmluZyBzKSB7Ci0gICAgLy9TeXN0ZW0ub3V0LnByaW50bG4oIlNpZzoiICsgcyk7Ci0gICAgU3RyaW5nQnVmZmVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLQotICAgIG1hdGNoR0pJZGVudChuZXcgTXlCeXRlQXJyYXlJbnB1dFN0cmVhbShzKSwgYnVmKTsKLQotICAgIHJldHVybiBidWYudG9TdHJpbmcoKTsKLSAgfQotCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgYm9vbGVhbiBpc0Zvcm1hbFBhcmFtZXRlckxpc3QoU3RyaW5nIHMpIHsKLSAgICByZXR1cm4gcy5zdGFydHNXaXRoKCI8IikgJiYgKHMuaW5kZXhPZignOicpID4gMCk7Ci0gIH0KLQotICBwdWJsaWMgc3RhdGljIGZpbmFsIGJvb2xlYW4gaXNBY3R1YWxQYXJhbWV0ZXJMaXN0KFN0cmluZyBzKSB7Ci0gICAgcmV0dXJuIHMuc3RhcnRzV2l0aCgiTCIpICYmIHMuZW5kc1dpdGgoIj47Iik7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBTdHJpbmcgcmVwcmVzZW50YXRpb24KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0gICAgU3RyaW5nIHMgPSBnZXRTaWduYXR1cmUoKTsKLQotICAgIHJldHVybiAiU2lnbmF0dXJlKCIgKyBzICsgIikiOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gZGVlcCBjb3B5IG9mIHRoaXMgYXR0cmlidXRlCi0gICAqLwotICBwdWJsaWMgQXR0cmlidXRlIGNvcHkoQ29uc3RhbnRQb29sIGNvbnN0YW50X3Bvb2wpIHsKLSAgICByZXR1cm4gKFNpZ25hdHVyZSljbG9uZSgpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvY2xhc3NmaWxlL1NvdXJjZUZpbGUuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvU291cmNlRmlsZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1MTIwY2Q2Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvU291cmNlRmlsZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTc2ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmNsYXNzZmlsZTsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotaW1wb3J0ICBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHM7Ci1pbXBvcnQgIGphdmEuaW8uKjsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGlzIGRlcml2ZWQgZnJvbSA8ZW0+QXR0cmlidXRlPC9lbT4gYW5kIHJlcHJlc2VudHMgYSByZWZlcmVuY2UKLSAqIHRvIHRoZSBzb3VyY2UgZmlsZSBvZiB0aGlzIGNsYXNzLiAgQXQgbW9zdCBvbmUgU291cmNlRmlsZSBhdHRyaWJ1dGUKLSAqIHNob3VsZCBhcHBlYXIgcGVyIGNsYXNzZmlsZS4gIFRoZSBpbnRlbnRpb24gb2YgdGhpcyBjbGFzcyBpcyB0aGF0IGl0IGlzCi0gKiBpbnN0YW50aWF0ZWQgZnJvbSB0aGUgPGVtPkF0dHJpYnV0ZS5yZWFkQXR0cmlidXRlKCk8L2VtPiBtZXRob2QuCi0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqIEBzZWUgICAgIEF0dHJpYnV0ZQotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgU291cmNlRmlsZSBleHRlbmRzIEF0dHJpYnV0ZSB7Ci0gIHByaXZhdGUgaW50IHNvdXJjZWZpbGVfaW5kZXg7Ci0KLSAgLyoqCi0gICAqIEluaXRpYWxpemUgZnJvbSBhbm90aGVyIG9iamVjdC4gTm90ZSB0aGF0IGJvdGggb2JqZWN0cyB1c2UgdGhlIHNhbWUKLSAgICogcmVmZXJlbmNlcyAoc2hhbGxvdyBjb3B5KS4gVXNlIGNsb25lKCkgZm9yIGEgcGh5c2ljYWwgY29weS4KLSAgICovCi0gIHB1YmxpYyBTb3VyY2VGaWxlKFNvdXJjZUZpbGUgYykgewotICAgIHRoaXMoYy5nZXROYW1lSW5kZXgoKSwgYy5nZXRMZW5ndGgoKSwgYy5nZXRTb3VyY2VGaWxlSW5kZXgoKSwKLSAgICAgICAgIGMuZ2V0Q29uc3RhbnRQb29sKCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBvYmplY3QgZnJvbSBmaWxlIHN0cmVhbS4KLSAgICogQHBhcmFtIG5hbWVfaW5kZXggSW5kZXggaW4gY29uc3RhbnQgcG9vbCB0byBDT05TVEFOVF9VdGY4Ci0gICAqIEBwYXJhbSBsZW5ndGggQ29udGVudCBsZW5ndGggaW4gYnl0ZXMKLSAgICogQHBhcmFtIGZpbGUgSW5wdXQgc3RyZWFtCi0gICAqIEBwYXJhbSBjb25zdGFudF9wb29sIEFycmF5IG9mIGNvbnN0YW50cwotICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0gICAqLwotICBTb3VyY2VGaWxlKGludCBuYW1lX2luZGV4LCBpbnQgbGVuZ3RoLCBEYXRhSW5wdXRTdHJlYW0gZmlsZSwKLSAgICAgICAgICAgICBDb25zdGFudFBvb2wgY29uc3RhbnRfcG9vbCkgdGhyb3dzIElPRXhjZXB0aW9uCi0gIHsKLSAgICB0aGlzKG5hbWVfaW5kZXgsIGxlbmd0aCwgZmlsZS5yZWFkVW5zaWduZWRTaG9ydCgpLCBjb25zdGFudF9wb29sKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gbmFtZV9pbmRleCBJbmRleCBpbiBjb25zdGFudCBwb29sIHRvIENPTlNUQU5UX1V0ZjgsIHdoaWNoCi0gICAqIHNob3VsZCByZXByZXNlbnQgdGhlIHN0cmluZyAiU291cmNlRmlsZSIuCi0gICAqIEBwYXJhbSBsZW5ndGggQ29udGVudCBsZW5ndGggaW4gYnl0ZXMsIHRoZSB2YWx1ZSBzaG91bGQgYmUgMi4KLSAgICogQHBhcmFtIGNvbnN0YW50X3Bvb2wgVGhlIGNvbnN0YW50IHBvb2wgdGhhdCB0aGlzIGF0dHJpYnV0ZSBpcwotICAgKiBhc3NvY2lhdGVkIHdpdGguCi0gICAqIEBwYXJhbSBzb3VyY2VmaWxlX2luZGV4IEluZGV4IGluIGNvbnN0YW50IHBvb2wgdG8gQ09OU1RBTlRfVXRmOC4gIFRoaXMKLSAgICogc3RyaW5nIHdpbGwgYmUgaW50ZXJwcmV0ZWQgYXMgdGhlIG5hbWUgb2YgdGhlIGZpbGUgZnJvbSB3aGljaCB0aGlzCi0gICAqIGNsYXNzIHdhcyBjb21waWxlZC4gIEl0IHdpbGwgbm90IGJlIGludGVycHJldGVkIGFzIGluZGljYXRpbmcgdGhlIG5hbWUKLSAgICogb2YgdGhlIGRpcmVjdG9yeSBjb250cWluaW5nIHRoZSBmaWxlIG9yIGFuIGFic29sdXRlIHBhdGg7IHRoaXMKLSAgICogaW5mb3JtYXRpb24gaGFzIHRvIGJlIHN1cHBsaWVkIHRoZSBjb25zdW1lciBvZiB0aGlzIGF0dHJpYnV0ZSAtIGluCi0gICAqIG1hbnkgY2FzZXMsIHRoZSBKVk0uCi0gICAqLwotICBwdWJsaWMgU291cmNlRmlsZShpbnQgbmFtZV9pbmRleCwgaW50IGxlbmd0aCwgaW50IHNvdXJjZWZpbGVfaW5kZXgsCi0gICAgICAgICAgICAgICAgICAgIENvbnN0YW50UG9vbCBjb25zdGFudF9wb29sKQotICB7Ci0gICAgc3VwZXIoQ29uc3RhbnRzLkFUVFJfU09VUkNFX0ZJTEUsIG5hbWVfaW5kZXgsIGxlbmd0aCwgY29uc3RhbnRfcG9vbCk7Ci0gICAgdGhpcy5zb3VyY2VmaWxlX2luZGV4ID0gc291cmNlZmlsZV9pbmRleDsKLSAgfQotCi0gIC8qKgotICAgKiBDYWxsZWQgYnkgb2JqZWN0cyB0aGF0IGFyZSB0cmF2ZXJzaW5nIHRoZSBub2RlcyBvZiB0aGUgdHJlZSBpbXBsaWNpdGVseQotICAgKiBkZWZpbmVkIGJ5IHRoZSBjb250ZW50cyBvZiBhIEphdmEgY2xhc3MuIEkuZS4sIHRoZSBoaWVyYXJjaHkgb2YgbWV0aG9kcywKLSAgICogZmllbGRzLCBhdHRyaWJ1dGVzLCBldGMuIHNwYXducyBhIHRyZWUgb2Ygb2JqZWN0cy4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0U291cmNlRmlsZSh0aGlzKTsKLSAgfQotCi0gIC8qKgotICAgKiBEdW1wIHNvdXJjZSBmaWxlIGF0dHJpYnV0ZSB0byBmaWxlIHN0cmVhbSBpbiBiaW5hcnkgZm9ybWF0LgotICAgKgotICAgKiBAcGFyYW0gZmlsZSBPdXRwdXQgZmlsZSBzdHJlYW0KLSAgICogQHRocm93cyBJT0V4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgZHVtcChEYXRhT3V0cHV0U3RyZWFtIGZpbGUpIHRocm93cyBJT0V4Y2VwdGlvbgotICB7Ci0gICAgc3VwZXIuZHVtcChmaWxlKTsKLSAgICBmaWxlLndyaXRlU2hvcnQoc291cmNlZmlsZV9pbmRleCk7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBJbmRleCBpbiBjb25zdGFudCBwb29sIG9mIHNvdXJjZSBmaWxlIG5hbWUuCi0gICAqLwotICBwdWJsaWMgZmluYWwgaW50IGdldFNvdXJjZUZpbGVJbmRleCgpIHsgcmV0dXJuIHNvdXJjZWZpbGVfaW5kZXg7IH0KLQotICAvKioKLSAgICogQHBhcmFtIHNvdXJjZWZpbGVfaW5kZXguCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBzZXRTb3VyY2VGaWxlSW5kZXgoaW50IHNvdXJjZWZpbGVfaW5kZXgpIHsKLSAgICB0aGlzLnNvdXJjZWZpbGVfaW5kZXggPSBzb3VyY2VmaWxlX2luZGV4OwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gU291cmNlIGZpbGUgbmFtZS4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBTdHJpbmcgZ2V0U291cmNlRmlsZU5hbWUoKSB7Ci0gICAgQ29uc3RhbnRVdGY4IGMgPSAoQ29uc3RhbnRVdGY4KWNvbnN0YW50X3Bvb2wuZ2V0Q29uc3RhbnQoc291cmNlZmlsZV9pbmRleCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb25zdGFudHMuQ09OU1RBTlRfVXRmOCk7Ci0gICAgcmV0dXJuIGMuZ2V0Qnl0ZXMoKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIFN0cmluZyByZXByZXNlbnRhdGlvbgotICAgKi8KLSAgcHVibGljIGZpbmFsIFN0cmluZyB0b1N0cmluZygpIHsKLSAgICByZXR1cm4gIlNvdXJjZUZpbGUoIiArIGdldFNvdXJjZUZpbGVOYW1lKCkgKyAiKSI7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBkZWVwIGNvcHkgb2YgdGhpcyBhdHRyaWJ1dGUKLSAgICovCi0gIHB1YmxpYyBBdHRyaWJ1dGUgY29weShDb25zdGFudFBvb2wgY29uc3RhbnRfcG9vbCkgewotICAgIHJldHVybiAoU291cmNlRmlsZSljbG9uZSgpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvY2xhc3NmaWxlL1N0YWNrTWFwLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvY2xhc3NmaWxlL1N0YWNrTWFwLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDRkNDRhNmYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2NsYXNzZmlsZS9TdGFja01hcC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTg4ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmNsYXNzZmlsZTsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotaW1wb3J0ICBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHM7Ci1pbXBvcnQgIGphdmEuaW8uKjsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIHJlcHJlc2VudHMgYSBzdGFjayBtYXAgYXR0cmlidXRlIHVzZWQgZm9yCi0gKiBwcmV2ZXJpZmljYXRpb24gb2YgSmF2YSBjbGFzc2VzIGZvciB0aGUgPGEKLSAqIGhyZWY9Imh0dHA6Ly9qYXZhLnN1bi5jb20vajJtZS8iPiBKYXZhIDIgTWljcm8gRWRpdGlvbjwvYT4KLSAqIChKMk1FKS4gVGhpcyBhdHRyaWJ1dGUgaXMgdXNlZCBieSB0aGUgPGEKLSAqIGhyZWY9Imh0dHA6Ly9qYXZhLnN1bi5jb20vcHJvZHVjdHMvY2xkYy8iPktWTTwvYT4gYW5kIGNvbnRhaW5lZAotICogd2l0aGluIHRoZSBDb2RlIGF0dHJpYnV0ZSBvZiBhIG1ldGhvZC4gU2VlIENMREMgc3BlY2lmaWNhdGlvbgotICogNS4zLjEuMgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKiBAc2VlICAgICBDb2RlCi0gKiBAc2VlICAgICBTdGFja01hcEVudHJ5Ci0gKiBAc2VlICAgICBTdGFja01hcFR5cGUKLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIFN0YWNrTWFwIGV4dGVuZHMgQXR0cmlidXRlIGltcGxlbWVudHMgTm9kZSB7Ci0gIHByaXZhdGUgaW50ICAgICAgICAgICAgIG1hcF9sZW5ndGg7Ci0gIHByaXZhdGUgU3RhY2tNYXBFbnRyeVtdIG1hcDsgLy8gVGFibGUgb2Ygc3RhY2sgbWFwIGVudHJpZXMKLQotICAvKgotICAgKiBAcGFyYW0gbmFtZV9pbmRleCBJbmRleCBvZiBuYW1lCi0gICAqIEBwYXJhbSBsZW5ndGggQ29udGVudCBsZW5ndGggaW4gYnl0ZXMKLSAgICogQHBhcmFtIG1hcCBUYWJsZSBvZiBzdGFjayBtYXAgZW50cmllcwotICAgKiBAcGFyYW0gY29uc3RhbnRfcG9vbCBBcnJheSBvZiBjb25zdGFudHMKLSAgICovCi0gIHB1YmxpYyBTdGFja01hcChpbnQgbmFtZV9pbmRleCwgaW50IGxlbmd0aCwgIFN0YWNrTWFwRW50cnlbXSBtYXAsCi0gICAgICAgICAgICAgICAgICBDb25zdGFudFBvb2wgY29uc3RhbnRfcG9vbCkKLSAgewotICAgIHN1cGVyKENvbnN0YW50cy5BVFRSX1NUQUNLX01BUCwgbmFtZV9pbmRleCwgbGVuZ3RoLCBjb25zdGFudF9wb29sKTsKLQotICAgIHNldFN0YWNrTWFwKG1hcCk7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IG9iamVjdCBmcm9tIGZpbGUgc3RyZWFtLgotICAgKiBAcGFyYW0gbmFtZV9pbmRleCBJbmRleCBvZiBuYW1lCi0gICAqIEBwYXJhbSBsZW5ndGggQ29udGVudCBsZW5ndGggaW4gYnl0ZXMKLSAgICogQHBhcmFtIGZpbGUgSW5wdXQgc3RyZWFtCi0gICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLSAgICogQHBhcmFtIGNvbnN0YW50X3Bvb2wgQXJyYXkgb2YgY29uc3RhbnRzCi0gICAqLwotICBTdGFja01hcChpbnQgbmFtZV9pbmRleCwgaW50IGxlbmd0aCwgRGF0YUlucHV0U3RyZWFtIGZpbGUsCi0gICAgICAgICAgIENvbnN0YW50UG9vbCBjb25zdGFudF9wb29sKSB0aHJvd3MgSU9FeGNlcHRpb24KLSAgewotICAgIHRoaXMobmFtZV9pbmRleCwgbGVuZ3RoLCAoU3RhY2tNYXBFbnRyeVtdKW51bGwsIGNvbnN0YW50X3Bvb2wpOwotCi0gICAgbWFwX2xlbmd0aCA9IGZpbGUucmVhZFVuc2lnbmVkU2hvcnQoKTsKLSAgICBtYXAgPSBuZXcgU3RhY2tNYXBFbnRyeVttYXBfbGVuZ3RoXTsKLQotICAgIGZvcihpbnQgaT0wOyBpIDwgbWFwX2xlbmd0aDsgaSsrKQotICAgICAgbWFwW2ldID0gbmV3IFN0YWNrTWFwRW50cnkoZmlsZSwgY29uc3RhbnRfcG9vbCk7Ci0gIH0KLQotICAvKioKLSAgICogRHVtcCBsaW5lIG51bWJlciB0YWJsZSBhdHRyaWJ1dGUgdG8gZmlsZSBzdHJlYW0gaW4gYmluYXJ5IGZvcm1hdC4KLSAgICoKLSAgICogQHBhcmFtIGZpbGUgT3V0cHV0IGZpbGUgc3RyZWFtCi0gICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIGR1bXAoRGF0YU91dHB1dFN0cmVhbSBmaWxlKSB0aHJvd3MgSU9FeGNlcHRpb24KLSAgewotICAgIHN1cGVyLmR1bXAoZmlsZSk7Ci0gICAgZmlsZS53cml0ZVNob3J0KG1hcF9sZW5ndGgpOwotICAgIGZvcihpbnQgaT0wOyBpIDwgbWFwX2xlbmd0aDsgaSsrKQotICAgICAgbWFwW2ldLmR1bXAoZmlsZSk7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBBcnJheSBvZiBzdGFjayBtYXAgZW50cmllcwotICAgKi8KLSAgcHVibGljIGZpbmFsIFN0YWNrTWFwRW50cnlbXSBnZXRTdGFja01hcCgpIHsgcmV0dXJuIG1hcDsgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gbWFwIEFycmF5IG9mIHN0YWNrIG1hcCBlbnRyaWVzCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBzZXRTdGFja01hcChTdGFja01hcEVudHJ5W10gbWFwKSB7Ci0gICAgdGhpcy5tYXAgPSBtYXA7Ci0KLSAgICBtYXBfbGVuZ3RoID0gKG1hcCA9PSBudWxsKT8gMCA6IG1hcC5sZW5ndGg7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBTdHJpbmcgcmVwcmVzZW50YXRpb24uCi0gICAqLwotICBwdWJsaWMgZmluYWwgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgIFN0cmluZ0J1ZmZlciBidWYgPSBuZXcgU3RyaW5nQnVmZmVyKCJTdGFja01hcCgiKTsKLQotICAgIGZvcihpbnQgaT0wOyBpIDwgbWFwX2xlbmd0aDsgaSsrKSB7Ci0gICAgICBidWYuYXBwZW5kKG1hcFtpXS50b1N0cmluZygpKTsKLQotICAgICAgaWYoaSA8IG1hcF9sZW5ndGggLSAxKQotICAgICAgICBidWYuYXBwZW5kKCIsICIpOwotICAgIH0KLQotICAgIGJ1Zi5hcHBlbmQoJyknKTsKLQotICAgIHJldHVybiBidWYudG9TdHJpbmcoKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIGRlZXAgY29weSBvZiB0aGlzIGF0dHJpYnV0ZQotICAgKi8KLSAgcHVibGljIEF0dHJpYnV0ZSBjb3B5KENvbnN0YW50UG9vbCBjb25zdGFudF9wb29sKSB7Ci0gICAgU3RhY2tNYXAgYyA9IChTdGFja01hcCljbG9uZSgpOwotCi0gICAgYy5tYXAgPSBuZXcgU3RhY2tNYXBFbnRyeVttYXBfbGVuZ3RoXTsKLSAgICBmb3IoaW50IGk9MDsgaSA8IG1hcF9sZW5ndGg7IGkrKykKLSAgICAgIGMubWFwW2ldID0gbWFwW2ldLmNvcHkoKTsKLQotICAgIGMuY29uc3RhbnRfcG9vbCA9IGNvbnN0YW50X3Bvb2w7Ci0gICAgcmV0dXJuIGM7Ci0gIH0KLQotICAvKioKLSAgICogQ2FsbGVkIGJ5IG9iamVjdHMgdGhhdCBhcmUgdHJhdmVyc2luZyB0aGUgbm9kZXMgb2YgdGhlIHRyZWUgaW1wbGljaXRlbHkKLSAgICogZGVmaW5lZCBieSB0aGUgY29udGVudHMgb2YgYSBKYXZhIGNsYXNzLiBJLmUuLCB0aGUgaGllcmFyY2h5IG9mIG1ldGhvZHMsCi0gICAqIGZpZWxkcywgYXR0cmlidXRlcywgZXRjLiBzcGF3bnMgYSB0cmVlIG9mIG9iamVjdHMuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgICB2LnZpc2l0U3RhY2tNYXAodGhpcyk7Ci0gICB9Ci0KLSAgcHVibGljIGZpbmFsIGludCBnZXRNYXBMZW5ndGgoKSB7IHJldHVybiBtYXBfbGVuZ3RoOyB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvY2xhc3NmaWxlL1N0YWNrTWFwRW50cnkuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvU3RhY2tNYXBFbnRyeS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1YjVjNDZmLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvU3RhY2tNYXBFbnRyeS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjEyICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmNsYXNzZmlsZTsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotaW1wb3J0ICBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHM7Ci1pbXBvcnQgIGphdmEuaW8uKjsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIHJlcHJlc2VudHMgYSBzdGFjayBtYXAgZW50cnkgcmVjb3JkaW5nIHRoZSB0eXBlcyBvZgotICogbG9jYWwgdmFyaWFibGVzIGFuZCB0aGUgdGhlIG9mIHN0YWNrIGl0ZW1zIGF0IGEgZ2l2ZW4gYnl0ZSBjb2RlIG9mZnNldC4KLSAqIFNlZSBDTERDIHNwZWNpZmljYXRpb24gNS4zLjEuMgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKiBAc2VlICAgICBTdGFja01hcAotICogQHNlZSAgICAgU3RhY2tNYXBUeXBlCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBTdGFja01hcEVudHJ5IGltcGxlbWVudHMgQ2xvbmVhYmxlIHsKLSAgcHJpdmF0ZSBpbnQgICAgICAgICAgICBieXRlX2NvZGVfb2Zmc2V0OwotICBwcml2YXRlIGludCAgICAgICAgICAgIG51bWJlcl9vZl9sb2NhbHM7Ci0gIHByaXZhdGUgU3RhY2tNYXBUeXBlW10gdHlwZXNfb2ZfbG9jYWxzOwotICBwcml2YXRlIGludCAgICAgICAgICAgIG51bWJlcl9vZl9zdGFja19pdGVtczsKLSAgcHJpdmF0ZSBTdGFja01hcFR5cGVbXSB0eXBlc19vZl9zdGFja19pdGVtczsKLSAgcHJpdmF0ZSBDb25zdGFudFBvb2wgICBjb25zdGFudF9wb29sOwotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3Qgb2JqZWN0IGZyb20gZmlsZSBzdHJlYW0uCi0gICAqIEBwYXJhbSBmaWxlIElucHV0IHN0cmVhbQotICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0gICAqLwotICBTdGFja01hcEVudHJ5KERhdGFJbnB1dFN0cmVhbSBmaWxlLCBDb25zdGFudFBvb2wgY29uc3RhbnRfcG9vbCkgdGhyb3dzIElPRXhjZXB0aW9uCi0gIHsKLSAgICB0aGlzKGZpbGUucmVhZFNob3J0KCksIGZpbGUucmVhZFNob3J0KCksIG51bGwsIC0xLCBudWxsLCBjb25zdGFudF9wb29sKTsKLQotICAgIHR5cGVzX29mX2xvY2FscyA9IG5ldyBTdGFja01hcFR5cGVbbnVtYmVyX29mX2xvY2Fsc107Ci0gICAgZm9yKGludCBpPTA7IGkgPCBudW1iZXJfb2ZfbG9jYWxzOyBpKyspCi0gICAgICB0eXBlc19vZl9sb2NhbHNbaV0gPSBuZXcgU3RhY2tNYXBUeXBlKGZpbGUsIGNvbnN0YW50X3Bvb2wpOwotCi0gICAgbnVtYmVyX29mX3N0YWNrX2l0ZW1zID0gZmlsZS5yZWFkU2hvcnQoKTsKLSAgICB0eXBlc19vZl9zdGFja19pdGVtcyA9IG5ldyBTdGFja01hcFR5cGVbbnVtYmVyX29mX3N0YWNrX2l0ZW1zXTsKLSAgICBmb3IoaW50IGk9MDsgaSA8IG51bWJlcl9vZl9zdGFja19pdGVtczsgaSsrKQotICAgICAgdHlwZXNfb2Zfc3RhY2tfaXRlbXNbaV0gPSBuZXcgU3RhY2tNYXBUeXBlKGZpbGUsIGNvbnN0YW50X3Bvb2wpOwotICB9Ci0KLSAgcHVibGljIFN0YWNrTWFwRW50cnkoaW50IGJ5dGVfY29kZV9vZmZzZXQsIGludCBudW1iZXJfb2ZfbG9jYWxzLAotICAgICAgICAgICAgICAgICAgICAgICBTdGFja01hcFR5cGVbXSB0eXBlc19vZl9sb2NhbHMsCi0gICAgICAgICAgICAgICAgICAgICAgIGludCBudW1iZXJfb2Zfc3RhY2tfaXRlbXMsCi0gICAgICAgICAgICAgICAgICAgICAgIFN0YWNrTWFwVHlwZVtdIHR5cGVzX29mX3N0YWNrX2l0ZW1zLAotICAgICAgICAgICAgICAgICAgICAgICBDb25zdGFudFBvb2wgY29uc3RhbnRfcG9vbCkgewotICAgIHRoaXMuYnl0ZV9jb2RlX29mZnNldCA9IGJ5dGVfY29kZV9vZmZzZXQ7Ci0gICAgdGhpcy5udW1iZXJfb2ZfbG9jYWxzID0gbnVtYmVyX29mX2xvY2FsczsKLSAgICB0aGlzLnR5cGVzX29mX2xvY2FscyA9IHR5cGVzX29mX2xvY2FsczsKLSAgICB0aGlzLm51bWJlcl9vZl9zdGFja19pdGVtcyA9IG51bWJlcl9vZl9zdGFja19pdGVtczsKLSAgICB0aGlzLnR5cGVzX29mX3N0YWNrX2l0ZW1zID0gdHlwZXNfb2Zfc3RhY2tfaXRlbXM7Ci0gICAgdGhpcy5jb25zdGFudF9wb29sID0gY29uc3RhbnRfcG9vbDsKLSAgfQotCi0gIC8qKgotICAgKiBEdW1wIHN0YWNrIG1hcCBlbnRyeQotICAgKgotICAgKiBAcGFyYW0gZmlsZSBPdXRwdXQgZmlsZSBzdHJlYW0KLSAgICogQHRocm93cyBJT0V4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgZHVtcChEYXRhT3V0cHV0U3RyZWFtIGZpbGUpIHRocm93cyBJT0V4Y2VwdGlvbgotICB7Ci0gICAgZmlsZS53cml0ZVNob3J0KGJ5dGVfY29kZV9vZmZzZXQpOwotCi0gICAgZmlsZS53cml0ZVNob3J0KG51bWJlcl9vZl9sb2NhbHMpOwotICAgIGZvcihpbnQgaT0wOyBpIDwgbnVtYmVyX29mX2xvY2FsczsgaSsrKQotICAgICAgdHlwZXNfb2ZfbG9jYWxzW2ldLmR1bXAoZmlsZSk7Ci0KLSAgICBmaWxlLndyaXRlU2hvcnQobnVtYmVyX29mX3N0YWNrX2l0ZW1zKTsKLSAgICBmb3IoaW50IGk9MDsgaSA8IG51bWJlcl9vZl9zdGFja19pdGVtczsgaSsrKQotICAgICAgdHlwZXNfb2Zfc3RhY2tfaXRlbXNbaV0uZHVtcChmaWxlKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIFN0cmluZyByZXByZXNlbnRhdGlvbi4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0gICAgU3RyaW5nQnVmZmVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWZmZXIoIihvZmZzZXQ9IiArIGJ5dGVfY29kZV9vZmZzZXQpOwotCi0gICAgaWYobnVtYmVyX29mX2xvY2FscyA+IDApIHsKLSAgICAgIGJ1Zi5hcHBlbmQoIiwgbG9jYWxzPXsiKTsKLQotICAgICAgZm9yKGludCBpPTA7IGkgPCBudW1iZXJfb2ZfbG9jYWxzOyBpKyspIHsKLSAgICAgICAgYnVmLmFwcGVuZCh0eXBlc19vZl9sb2NhbHNbaV0pOwotICAgICAgICBpZihpIDwgbnVtYmVyX29mX2xvY2FscyAtIDEpCi0gICAgICAgICAgYnVmLmFwcGVuZCgiLCAiKTsKLSAgICAgIH0KLQotICAgICAgYnVmLmFwcGVuZCgifSIpOwotICAgIH0KLQotICAgIGlmKG51bWJlcl9vZl9zdGFja19pdGVtcyA+IDApIHsKLSAgICAgIGJ1Zi5hcHBlbmQoIiwgc3RhY2sgaXRlbXM9eyIpOwotCi0gICAgICBmb3IoaW50IGk9MDsgaSA8IG51bWJlcl9vZl9zdGFja19pdGVtczsgaSsrKSB7Ci0gICAgICAgIGJ1Zi5hcHBlbmQodHlwZXNfb2Zfc3RhY2tfaXRlbXNbaV0pOwotICAgICAgICBpZihpIDwgbnVtYmVyX29mX3N0YWNrX2l0ZW1zIC0gMSkKLSAgICAgICAgICBidWYuYXBwZW5kKCIsICIpOwotICAgICAgfQotCi0gICAgICBidWYuYXBwZW5kKCJ9Iik7Ci0gICAgfQotCi0gICAgYnVmLmFwcGVuZCgiKSIpOwotCi0gICAgcmV0dXJuIGJ1Zi50b1N0cmluZygpOwotICB9Ci0KLQotICBwdWJsaWMgdm9pZCAgICAgICAgICAgc2V0Qnl0ZUNvZGVPZmZzZXQoaW50IGIpICAgICAgICAgICAgICAgeyBieXRlX2NvZGVfb2Zmc2V0ID0gYjsgfQotICBwdWJsaWMgaW50ICAgICAgICAgICAgZ2V0Qnl0ZUNvZGVPZmZzZXQoKSAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gYnl0ZV9jb2RlX29mZnNldDsgfQotICBwdWJsaWMgdm9pZCAgICAgICAgICAgc2V0TnVtYmVyT2ZMb2NhbHMoaW50IG4pICAgICAgICAgICAgICAgeyBudW1iZXJfb2ZfbG9jYWxzID0gbjsgfQotICBwdWJsaWMgaW50ICAgICAgICAgICAgZ2V0TnVtYmVyT2ZMb2NhbHMoKSAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbnVtYmVyX29mX2xvY2FsczsgfQotICBwdWJsaWMgdm9pZCAgICAgICAgICAgc2V0VHlwZXNPZkxvY2FscyhTdGFja01hcFR5cGVbXSB0KSAgICAgeyB0eXBlc19vZl9sb2NhbHMgPSB0OyB9Ci0gIHB1YmxpYyBTdGFja01hcFR5cGVbXSBnZXRUeXBlc09mTG9jYWxzKCkgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiB0eXBlc19vZl9sb2NhbHM7IH0KLSAgcHVibGljIHZvaWQgICAgICAgICAgIHNldE51bWJlck9mU3RhY2tJdGVtcyhpbnQgbikgICAgICAgICAgIHsgbnVtYmVyX29mX3N0YWNrX2l0ZW1zID0gbjsgfQotICBwdWJsaWMgaW50ICAgICAgICAgICAgZ2V0TnVtYmVyT2ZTdGFja0l0ZW1zKCkgICAgICAgICAgICAgICAgeyByZXR1cm4gbnVtYmVyX29mX3N0YWNrX2l0ZW1zOyB9Ci0gIHB1YmxpYyB2b2lkICAgICAgICAgICBzZXRUeXBlc09mU3RhY2tJdGVtcyhTdGFja01hcFR5cGVbXSB0KSB7IHR5cGVzX29mX3N0YWNrX2l0ZW1zID0gdDsgfQotICBwdWJsaWMgU3RhY2tNYXBUeXBlW10gZ2V0VHlwZXNPZlN0YWNrSXRlbXMoKSAgICAgICAgICAgICAgICAgeyByZXR1cm4gdHlwZXNfb2Zfc3RhY2tfaXRlbXM7IH0KLQotICAvKioKLSAgICogQHJldHVybiBkZWVwIGNvcHkgb2YgdGhpcyBvYmplY3QKLSAgICovCi0gIHB1YmxpYyBTdGFja01hcEVudHJ5IGNvcHkoKSB7Ci0gICAgdHJ5IHsKLSAgICAgIHJldHVybiAoU3RhY2tNYXBFbnRyeSljbG9uZSgpOwotICAgIH0gY2F0Y2goQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gZSkge30KLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIENhbGxlZCBieSBvYmplY3RzIHRoYXQgYXJlIHRyYXZlcnNpbmcgdGhlIG5vZGVzIG9mIHRoZSB0cmVlIGltcGxpY2l0ZWx5Ci0gICAqIGRlZmluZWQgYnkgdGhlIGNvbnRlbnRzIG9mIGEgSmF2YSBjbGFzcy4gSS5lLiwgdGhlIGhpZXJhcmNoeSBvZiBtZXRob2RzLAotICAgKiBmaWVsZHMsIGF0dHJpYnV0ZXMsIGV0Yy4gc3Bhd25zIGEgdHJlZSBvZiBvYmplY3RzLgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRTdGFja01hcEVudHJ5KHRoaXMpOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gQ29uc3RhbnQgcG9vbCB1c2VkIGJ5IHRoaXMgb2JqZWN0LgotICAgKi8KLSAgcHVibGljIGZpbmFsIENvbnN0YW50UG9vbCBnZXRDb25zdGFudFBvb2woKSB7IHJldHVybiBjb25zdGFudF9wb29sOyB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBjb25zdGFudF9wb29sIENvbnN0YW50IHBvb2wgdG8gYmUgdXNlZCBmb3IgdGhpcyBvYmplY3QuCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBzZXRDb25zdGFudFBvb2woQ29uc3RhbnRQb29sIGNvbnN0YW50X3Bvb2wpIHsKLSAgICB0aGlzLmNvbnN0YW50X3Bvb2wgPSBjb25zdGFudF9wb29sOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvY2xhc3NmaWxlL1N0YWNrTWFwVHlwZS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2NsYXNzZmlsZS9TdGFja01hcFR5cGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMzU3ZDUzZC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvY2xhc3NmaWxlL1N0YWNrTWFwVHlwZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTc1ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmNsYXNzZmlsZTsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotaW1wb3J0ICBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHM7Ci1pbXBvcnQgIGphdmEuaW8uKjsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIHJlcHJlc2VudHMgdGhlIHR5cGUgb2YgYSBsb2NhbCB2YXJpYWJsZSBvciBpdGVtIG9uIHN0YWNrCi0gKiB1c2VkIGluIHRoZSBTdGFja01hcCBlbnRyaWVzLgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKiBAc2VlICAgICBTdGFja01hcEVudHJ5Ci0gKiBAc2VlICAgICBTdGFja01hcAotICogQHNlZSAgICAgQ29uc3RhbnRzCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBTdGFja01hcFR5cGUgaW1wbGVtZW50cyBDbG9uZWFibGUgewotICBwcml2YXRlIGJ5dGUgICAgICAgICB0eXBlOwotICBwcml2YXRlIGludCAgICAgICAgICBpbmRleCA9IC0xOyAvLyBJbmRleCB0byBDT05TVEFOVF9DbGFzcyBvciBvZmZzZXQKLSAgcHJpdmF0ZSBDb25zdGFudFBvb2wgY29uc3RhbnRfcG9vbDsKLQotICAvKioKLSAgICogQ29uc3RydWN0IG9iamVjdCBmcm9tIGZpbGUgc3RyZWFtLgotICAgKiBAcGFyYW0gZmlsZSBJbnB1dCBzdHJlYW0KLSAgICogQHRocm93cyBJT0V4Y2VwdGlvbgotICAgKi8KLSAgU3RhY2tNYXBUeXBlKERhdGFJbnB1dFN0cmVhbSBmaWxlLCBDb25zdGFudFBvb2wgY29uc3RhbnRfcG9vbCkgdGhyb3dzIElPRXhjZXB0aW9uCi0gIHsKLSAgICB0aGlzKGZpbGUucmVhZEJ5dGUoKSwgLTEsIGNvbnN0YW50X3Bvb2wpOwotCi0gICAgaWYoaGFzSW5kZXgoKSkKLSAgICAgIHNldEluZGV4KGZpbGUucmVhZFNob3J0KCkpOwotCi0gICAgc2V0Q29uc3RhbnRQb29sKGNvbnN0YW50X3Bvb2wpOwotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSB0eXBlIHR5cGUgdGFnIGFzIGRlZmluZWQgaW4gdGhlIENvbnN0YW50cyBpbnRlcmZhY2UKLSAgICogQHBhcmFtIGluZGV4IGluZGV4IHRvIGNvbnN0YW50IHBvb2wsIG9yIGJ5dGUgY29kZSBvZmZzZXQKLSAgICovCi0gIHB1YmxpYyBTdGFja01hcFR5cGUoYnl0ZSB0eXBlLCBpbnQgaW5kZXgsIENvbnN0YW50UG9vbCBjb25zdGFudF9wb29sKSB7Ci0gICAgc2V0VHlwZSh0eXBlKTsKLSAgICBzZXRJbmRleChpbmRleCk7Ci0gICAgc2V0Q29uc3RhbnRQb29sKGNvbnN0YW50X3Bvb2wpOwotICB9Ci0KLSAgcHVibGljIHZvaWQgc2V0VHlwZShieXRlIHQpIHsKLSAgICBpZigodCA8IENvbnN0YW50cy5JVEVNX0JvZ3VzKSB8fCAodCA+IENvbnN0YW50cy5JVEVNX05ld09iamVjdCkpCi0gICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiSWxsZWdhbCB0eXBlIGZvciBTdGFja01hcFR5cGU6ICIgKyB0KTsKLSAgICB0eXBlID0gdDsKLSAgfQotCi0gIHB1YmxpYyBieXRlIGdldFR5cGUoKSAgICAgICB7IHJldHVybiB0eXBlOyB9Ci0gIHB1YmxpYyB2b2lkIHNldEluZGV4KGludCB0KSB7IGluZGV4ID0gdDsgfQotCi0gIC8qKiBAcmV0dXJuIGluZGV4IHRvIGNvbnN0YW50IHBvb2wgaWYgdHlwZSA9PSBJVEVNX09iamVjdCwgb3Igb2Zmc2V0Ci0gICAqIGluIGJ5dGUgY29kZSwgaWYgdHlwZSA9PSBJVEVNX05ld09iamVjdCwgYW5kIC0xIG90aGVyd2lzZQotICAgKi8KLSAgcHVibGljIGludCAgZ2V0SW5kZXgoKSAgICAgIHsgcmV0dXJuIGluZGV4OyB9Ci0KLSAgLyoqCi0gICAqIER1bXAgdHlwZSBlbnRyaWVzIHRvIGZpbGUuCi0gICAqCi0gICAqIEBwYXJhbSBmaWxlIE91dHB1dCBmaWxlIHN0cmVhbQotICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBkdW1wKERhdGFPdXRwdXRTdHJlYW0gZmlsZSkgdGhyb3dzIElPRXhjZXB0aW9uCi0gIHsKLSAgICBmaWxlLndyaXRlQnl0ZSh0eXBlKTsKLSAgICBpZihoYXNJbmRleCgpKQotICAgICAgZmlsZS53cml0ZVNob3J0KGdldEluZGV4KCkpOwotICB9Ci0KLSAgLyoqIEByZXR1cm4gdHJ1ZSwgaWYgdHlwZSBpcyBlaXRoZXIgSVRFTV9PYmplY3Qgb3IgSVRFTV9OZXdPYmplY3QKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBib29sZWFuIGhhc0luZGV4KCkgewotICAgIHJldHVybiAoKHR5cGUgPT0gQ29uc3RhbnRzLklURU1fT2JqZWN0KSB8fAotICAgICAgICAgICAgKHR5cGUgPT0gQ29uc3RhbnRzLklURU1fTmV3T2JqZWN0KSk7Ci0gIH0KLQotICBwcml2YXRlIFN0cmluZyBwcmludEluZGV4KCkgewotICAgIGlmKHR5cGUgPT0gQ29uc3RhbnRzLklURU1fT2JqZWN0KQotICAgICAgcmV0dXJuICIsIGNsYXNzPSIgKyBjb25zdGFudF9wb29sLmNvbnN0YW50VG9TdHJpbmcoaW5kZXgsIENvbnN0YW50cy5DT05TVEFOVF9DbGFzcyk7Ci0gICAgZWxzZSBpZih0eXBlID09IENvbnN0YW50cy5JVEVNX05ld09iamVjdCkKLSAgICAgIHJldHVybiAiLCBvZmZzZXQ9IiArIGluZGV4OwotICAgIGVsc2UKLSAgICAgIHJldHVybiAiIjsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIFN0cmluZyByZXByZXNlbnRhdGlvbgotICAgKi8KLSAgcHVibGljIGZpbmFsIFN0cmluZyB0b1N0cmluZygpIHsKLSAgICByZXR1cm4gIih0eXBlPSIgKyBDb25zdGFudHMuSVRFTV9OQU1FU1t0eXBlXSArIHByaW50SW5kZXgoKSArICIpIjsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIGRlZXAgY29weSBvZiB0aGlzIG9iamVjdAotICAgKi8KLSAgcHVibGljIFN0YWNrTWFwVHlwZSBjb3B5KCkgewotICAgIHRyeSB7Ci0gICAgICByZXR1cm4gKFN0YWNrTWFwVHlwZSljbG9uZSgpOwotICAgIH0gY2F0Y2goQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gZSkge30KLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gQ29uc3RhbnQgcG9vbCB1c2VkIGJ5IHRoaXMgb2JqZWN0LgotICAgKi8KLSAgcHVibGljIGZpbmFsIENvbnN0YW50UG9vbCBnZXRDb25zdGFudFBvb2woKSB7IHJldHVybiBjb25zdGFudF9wb29sOyB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBjb25zdGFudF9wb29sIENvbnN0YW50IHBvb2wgdG8gYmUgdXNlZCBmb3IgdGhpcyBvYmplY3QuCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBzZXRDb25zdGFudFBvb2woQ29uc3RhbnRQb29sIGNvbnN0YW50X3Bvb2wpIHsKLSAgICB0aGlzLmNvbnN0YW50X3Bvb2wgPSBjb25zdGFudF9wb29sOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvY2xhc3NmaWxlL1N5bnRoZXRpYy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2NsYXNzZmlsZS9TeW50aGV0aWMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNGI3NDNhNi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvY2xhc3NmaWxlL1N5bnRoZXRpYy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTc5ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmNsYXNzZmlsZTsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotaW1wb3J0ICBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHM7Ci1pbXBvcnQgIGphdmEuaW8uKjsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGlzIGRlcml2ZWQgZnJvbSA8ZW0+QXR0cmlidXRlPC9lbT4gYW5kIGRlY2xhcmVzIHRoaXMgY2xhc3MgYXMKLSAqIGBzeW50aGV0aWMnLCBpLmUuLCBpdCBuZWVkcyBzcGVjaWFsIGhhbmRsaW5nLiAgVGhlIEpWTSBzcGVjaWZpY2F0aW9uCi0gKiBzdGF0ZXMgIkEgY2xhc3MgbWVtYmVyIHRoYXQgZG9lcyBub3QgYXBwZWFyIGluIHRoZSBzb3VyY2UgY29kZSBtdXN0IGJlCi0gKiBtYXJrZWQgdXNpbmcgYSBTeW50aGV0aWMgYXR0cmlidXRlLiIgIEl0IG1heSBhcHBlYXIgaW4gdGhlIENsYXNzRmlsZQotICogYXR0cmlidXRlIHRhYmxlLCBhIGZpZWxkX2luZm8gdGFibGUgb3IgYSBtZXRob2RfaW5mbyB0YWJsZS4gIFRoaXMgY2xhc3MKLSAqIGlzIGludGVuZGVkIHRvIGJlIGluc3RhbnRpYXRlZCBmcm9tIHRoZQotICogPGVtPkF0dHJpYnV0ZS5yZWFkQXR0cmlidXRlKCk8L2VtPiBtZXRob2QuCi0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqIEBzZWUgICAgIEF0dHJpYnV0ZQotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgU3ludGhldGljIGV4dGVuZHMgQXR0cmlidXRlIHsKLSAgcHJpdmF0ZSBieXRlW10gYnl0ZXM7Ci0KLSAgLyoqCi0gICAqIEluaXRpYWxpemUgZnJvbSBhbm90aGVyIG9iamVjdC4gTm90ZSB0aGF0IGJvdGggb2JqZWN0cyB1c2UgdGhlIHNhbWUKLSAgICogcmVmZXJlbmNlcyAoc2hhbGxvdyBjb3B5KS4gVXNlIGNvcHkoKSBmb3IgYSBwaHlzaWNhbCBjb3B5LgotICAgKi8KLSAgcHVibGljIFN5bnRoZXRpYyhTeW50aGV0aWMgYykgewotICAgIHRoaXMoYy5nZXROYW1lSW5kZXgoKSwgYy5nZXRMZW5ndGgoKSwgYy5nZXRCeXRlcygpLCBjLmdldENvbnN0YW50UG9vbCgpKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gbmFtZV9pbmRleCBJbmRleCBpbiBjb25zdGFudCBwb29sIHRvIENPTlNUQU5UX1V0ZjgsIHdoaWNoCi0gICAqIHNob3VsZCByZXByZXNlbnQgdGhlIHN0cmluZyAiU3ludGhldGljIi4KLSAgICogQHBhcmFtIGxlbmd0aCBDb250ZW50IGxlbmd0aCBpbiBieXRlcyAtIHNob3VsZCBiZSB6ZXJvLgotICAgKiBAcGFyYW0gYnl0ZXMgQXR0cmlidXRlIGNvbnRlbnRzCi0gICAqIEBwYXJhbSBjb25zdGFudF9wb29sIFRoZSBjb25zdGFudCBwb29sIHRoaXMgYXR0cmlidXRlIGlzIGFzc29jaWF0ZWQKLSAgICogd2l0aC4KLSAgICovCi0gIHB1YmxpYyBTeW50aGV0aWMoaW50IG5hbWVfaW5kZXgsIGludCBsZW5ndGgsIGJ5dGVbXSBieXRlcywKLSAgICAgICAgICAgICAgICAgICBDb25zdGFudFBvb2wgY29uc3RhbnRfcG9vbCkKLSAgewotICAgIHN1cGVyKENvbnN0YW50cy5BVFRSX1NZTlRIRVRJQywgbmFtZV9pbmRleCwgbGVuZ3RoLCBjb25zdGFudF9wb29sKTsKLSAgICB0aGlzLmJ5dGVzICAgICAgICAgPSBieXRlczsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3Qgb2JqZWN0IGZyb20gZmlsZSBzdHJlYW0uCi0gICAqIEBwYXJhbSBuYW1lX2luZGV4IEluZGV4IGluIGNvbnN0YW50IHBvb2wgdG8gQ09OU1RBTlRfVXRmOAotICAgKiBAcGFyYW0gbGVuZ3RoIENvbnRlbnQgbGVuZ3RoIGluIGJ5dGVzCi0gICAqIEBwYXJhbSBmaWxlIElucHV0IHN0cmVhbQotICAgKiBAcGFyYW0gY29uc3RhbnRfcG9vbCBBcnJheSBvZiBjb25zdGFudHMKLSAgICogQHRocm93cyBJT0V4Y2VwdGlvbgotICAgKi8KLSAgU3ludGhldGljKGludCBuYW1lX2luZGV4LCBpbnQgbGVuZ3RoLCBEYXRhSW5wdXRTdHJlYW0gZmlsZSwKLSAgICAgICAgICAgIENvbnN0YW50UG9vbCBjb25zdGFudF9wb29sKSB0aHJvd3MgSU9FeGNlcHRpb24KLSAgewotICAgIHRoaXMobmFtZV9pbmRleCwgbGVuZ3RoLCAoYnl0ZSBbXSludWxsLCBjb25zdGFudF9wb29sKTsKLQotICAgIGlmKGxlbmd0aCA+IDApIHsKLSAgICAgIGJ5dGVzID0gbmV3IGJ5dGVbbGVuZ3RoXTsKLSAgICAgIGZpbGUucmVhZEZ1bGx5KGJ5dGVzKTsKLSAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiU3ludGhldGljIGF0dHJpYnV0ZSB3aXRoIGxlbmd0aCA+IDAiKTsKLSAgICB9Ci0gIH0KLSAgLyoqCi0gICAqIENhbGxlZCBieSBvYmplY3RzIHRoYXQgYXJlIHRyYXZlcnNpbmcgdGhlIG5vZGVzIG9mIHRoZSB0cmVlIGltcGxpY2l0ZWx5Ci0gICAqIGRlZmluZWQgYnkgdGhlIGNvbnRlbnRzIG9mIGEgSmF2YSBjbGFzcy4gSS5lLiwgdGhlIGhpZXJhcmNoeSBvZiBtZXRob2RzLAotICAgKiBmaWVsZHMsIGF0dHJpYnV0ZXMsIGV0Yy4gc3Bhd25zIGEgdHJlZSBvZiBvYmplY3RzLgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRTeW50aGV0aWModGhpcyk7Ci0gIH0KLSAgLyoqCi0gICAqIER1bXAgc291cmNlIGZpbGUgYXR0cmlidXRlIHRvIGZpbGUgc3RyZWFtIGluIGJpbmFyeSBmb3JtYXQuCi0gICAqCi0gICAqIEBwYXJhbSBmaWxlIE91dHB1dCBmaWxlIHN0cmVhbQotICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBkdW1wKERhdGFPdXRwdXRTdHJlYW0gZmlsZSkgdGhyb3dzIElPRXhjZXB0aW9uCi0gIHsKLSAgICBzdXBlci5kdW1wKGZpbGUpOwotICAgIGlmKGxlbmd0aCA+IDApCi0gICAgICBmaWxlLndyaXRlKGJ5dGVzLCAwLCBsZW5ndGgpOwotICB9Ci0gIC8qKgotICAgKiBAcmV0dXJuIGRhdGEgYnl0ZXMuCi0gICAqLwotICBwdWJsaWMgZmluYWwgYnl0ZVtdIGdldEJ5dGVzKCkgeyByZXR1cm4gYnl0ZXM7IH0KLQotICAvKioKLSAgICogQHBhcmFtIGJ5dGVzLgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgc2V0Qnl0ZXMoYnl0ZVtdIGJ5dGVzKSB7Ci0gICAgdGhpcy5ieXRlcyA9IGJ5dGVzOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gU3RyaW5nIHJlcHJlc2VudGF0aW9uLgotICAgKi8KLSAgcHVibGljIGZpbmFsIFN0cmluZyB0b1N0cmluZygpIHsKLSAgICBTdHJpbmdCdWZmZXIgYnVmID0gbmV3IFN0cmluZ0J1ZmZlcigiU3ludGhldGljIik7Ci0KLSAgICBpZihsZW5ndGggPiAwKQotICAgICAgYnVmLmFwcGVuZCgiICIgKyBVdGlsaXR5LnRvSGV4U3RyaW5nKGJ5dGVzKSk7Ci0KLSAgICByZXR1cm4gYnVmLnRvU3RyaW5nKCk7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBkZWVwIGNvcHkgb2YgdGhpcyBhdHRyaWJ1dGUKLSAgICovCi0gIHB1YmxpYyBBdHRyaWJ1dGUgY29weShDb25zdGFudFBvb2wgY29uc3RhbnRfcG9vbCkgewotICAgIFN5bnRoZXRpYyBjID0gKFN5bnRoZXRpYyljbG9uZSgpOwotCi0gICAgaWYoYnl0ZXMgIT0gbnVsbCkKLSAgICAgIGMuYnl0ZXMgPSAoYnl0ZVtdKWJ5dGVzLmNsb25lKCk7Ci0KLSAgICBjLmNvbnN0YW50X3Bvb2wgPSBjb25zdGFudF9wb29sOwotICAgIHJldHVybiBjOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvY2xhc3NmaWxlL1Vua25vd24uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvVW5rbm93bi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxNmZjNDc2Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvVW5rbm93bi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjE2ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmNsYXNzZmlsZTsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50czsKLWltcG9ydCBqYXZhLmlvLio7Ci1pbXBvcnQgamF2YS51dGlsLio7Ci0KLS8qKgotICogVGhpcyBjbGFzcyByZXByZXNlbnRzIGEgcmVmZXJlbmNlIHRvIGFuIHVua25vd24gKGkuZS4sCi0gKiBhcHBsaWNhdGlvbi1zcGVjaWZpYykgYXR0cmlidXRlIG9mIGEgY2xhc3MuICBJdCBpcyBpbnN0YW50aWF0ZWQgZnJvbSB0aGUKLSAqIDxlbT5BdHRyaWJ1dGUucmVhZEF0dHJpYnV0ZSgpPC9lbT4gbWV0aG9kLiAgQXBwbGljYXRpb25zIHRoYXQgbmVlZCB0bwotICogcmVhZCBpbiBhcHBsaWNhdGlvbi1zcGVjaWZpYyBhdHRyaWJ1dGVzIHNob3VsZCBjcmVhdGUgYW4gPGEKLSAqIGhyZWY9Ii4vQXR0cmlidXRlUmVhZGVyLmh0bWwiPkF0dHJpYnV0ZVJlYWRlcjwvYT4gaW1wbGVtZW50YXRpb24gYW5kCi0gKiBhdHRhY2ggaXQgdmlhIDxhCi0gKiBocmVmPSIuL0F0dHJpYnV0ZS5odG1sI2FkZEF0dHJpYnV0ZVJlYWRlcihqYXZhLmxhbmcuU3RyaW5nLAotICogY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuY2xhc3NmaWxlLkF0dHJpYnV0ZVJlYWRlcikiPkF0dHJpYnV0ZS5hZGRBdHRyaWJ1dGVSZWFkZXI8L2E+LgotCi0gKgotICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5jbGFzc2ZpbGUuQXR0cmlidXRlCi0gKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmNsYXNzZmlsZS5BdHRyaWJ1dGVSZWFkZXIKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBVbmtub3duIGV4dGVuZHMgQXR0cmlidXRlIHsKLSAgcHJpdmF0ZSBieXRlW10gYnl0ZXM7Ci0gIHByaXZhdGUgU3RyaW5nIG5hbWU7Ci0KLSAgcHJpdmF0ZSBzdGF0aWMgSGFzaE1hcCB1bmtub3duX2F0dHJpYnV0ZXMgPSBuZXcgSGFzaE1hcCgpOwotCi0gIC8qKiBAcmV0dXJuIGFycmF5IG9mIHVua25vd24gYXR0cmlidXRlcywgYnV0IGp1c3Qgb25lIGZvciBlYWNoIGtpbmQuCi0gICAqLwotICBzdGF0aWMgVW5rbm93bltdIGdldFVua25vd25BdHRyaWJ1dGVzKCkgewotICAgIFVua25vd25bXSB1bmtub3ducyA9IG5ldyBVbmtub3duW3Vua25vd25fYXR0cmlidXRlcy5zaXplKCldOwotICAgIEl0ZXJhdG9yICBlbnRyaWVzICA9IHVua25vd25fYXR0cmlidXRlcy52YWx1ZXMoKS5pdGVyYXRvcigpOwotCi0gICAgZm9yKGludCBpPTA7IGVudHJpZXMuaGFzTmV4dCgpOyBpKyspCi0gICAgICB1bmtub3duc1tpXSA9IChVbmtub3duKWVudHJpZXMubmV4dCgpOwotCi0gICAgdW5rbm93bl9hdHRyaWJ1dGVzLmNsZWFyKCk7Ci0gICAgcmV0dXJuIHVua25vd25zOwotICB9Ci0KLSAgLyoqCi0gICAqIEluaXRpYWxpemUgZnJvbSBhbm90aGVyIG9iamVjdC4gTm90ZSB0aGF0IGJvdGggb2JqZWN0cyB1c2UgdGhlIHNhbWUKLSAgICogcmVmZXJlbmNlcyAoc2hhbGxvdyBjb3B5KS4gVXNlIGNsb25lKCkgZm9yIGEgcGh5c2ljYWwgY29weS4KLSAgICovCi0gIHB1YmxpYyBVbmtub3duKFVua25vd24gYykgewotICAgIHRoaXMoYy5nZXROYW1lSW5kZXgoKSwgYy5nZXRMZW5ndGgoKSwgYy5nZXRCeXRlcygpLCBjLmdldENvbnN0YW50UG9vbCgpKTsKLSAgfQotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBub24tc3RhbmRhcmQgYXR0cmlidXRlLgotICAgKgotICAgKiBAcGFyYW0gbmFtZV9pbmRleCBJbmRleCBpbiBjb25zdGFudCBwb29sCi0gICAqIEBwYXJhbSBsZW5ndGggQ29udGVudCBsZW5ndGggaW4gYnl0ZXMKLSAgICogQHBhcmFtIGJ5dGVzIEF0dHJpYnV0ZSBjb250ZW50cwotICAgKiBAcGFyYW0gY29uc3RhbnRfcG9vbCBBcnJheSBvZiBjb25zdGFudHMKLSAgICovCi0gIHB1YmxpYyBVbmtub3duKGludCBuYW1lX2luZGV4LCBpbnQgbGVuZ3RoLCBieXRlW10gYnl0ZXMsCi0gICAgICAgICAgICAgICAgIENvbnN0YW50UG9vbCBjb25zdGFudF9wb29sKQotICB7Ci0gICAgc3VwZXIoQ29uc3RhbnRzLkFUVFJfVU5LTk9XTiwgbmFtZV9pbmRleCwgbGVuZ3RoLCBjb25zdGFudF9wb29sKTsKLSAgICB0aGlzLmJ5dGVzID0gYnl0ZXM7Ci0KLSAgICBuYW1lID0gKChDb25zdGFudFV0ZjgpY29uc3RhbnRfcG9vbC5nZXRDb25zdGFudChuYW1lX2luZGV4LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbnN0YW50cy5DT05TVEFOVF9VdGY4KSkuZ2V0Qnl0ZXMoKTsKLSAgICB1bmtub3duX2F0dHJpYnV0ZXMucHV0KG5hbWUsIHRoaXMpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBvYmplY3QgZnJvbSBmaWxlIHN0cmVhbS4KLSAgICogQHBhcmFtIG5hbWVfaW5kZXggSW5kZXggaW4gY29uc3RhbnQgcG9vbAotICAgKiBAcGFyYW0gbGVuZ3RoIENvbnRlbnQgbGVuZ3RoIGluIGJ5dGVzCi0gICAqIEBwYXJhbSBmaWxlIElucHV0IHN0cmVhbQotICAgKiBAcGFyYW0gY29uc3RhbnRfcG9vbCBBcnJheSBvZiBjb25zdGFudHMKLSAgICogQHRocm93cyBJT0V4Y2VwdGlvbgotICAgKi8KLSAgVW5rbm93bihpbnQgbmFtZV9pbmRleCwgaW50IGxlbmd0aCwgRGF0YUlucHV0U3RyZWFtIGZpbGUsCi0gICAgICAgICAgQ29uc3RhbnRQb29sIGNvbnN0YW50X3Bvb2wpCi0gICAgICAgdGhyb3dzIElPRXhjZXB0aW9uCi0gIHsKLSAgICB0aGlzKG5hbWVfaW5kZXgsIGxlbmd0aCwgKGJ5dGUgW10pbnVsbCwgY29uc3RhbnRfcG9vbCk7Ci0KLSAgICBpZihsZW5ndGggPiAwKSB7Ci0gICAgICBieXRlcyA9IG5ldyBieXRlW2xlbmd0aF07Ci0gICAgICBmaWxlLnJlYWRGdWxseShieXRlcyk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIENhbGxlZCBieSBvYmplY3RzIHRoYXQgYXJlIHRyYXZlcnNpbmcgdGhlIG5vZGVzIG9mIHRoZSB0cmVlIGltcGxpY2l0ZWx5Ci0gICAqIGRlZmluZWQgYnkgdGhlIGNvbnRlbnRzIG9mIGEgSmF2YSBjbGFzcy4gSS5lLiwgdGhlIGhpZXJhcmNoeSBvZiBtZXRob2RzLAotICAgKiBmaWVsZHMsIGF0dHJpYnV0ZXMsIGV0Yy4gc3Bhd25zIGEgdHJlZSBvZiBvYmplY3RzLgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRVbmtub3duKHRoaXMpOwotICB9Ci0gIC8qKgotICAgKiBEdW1wIHVua25vd24gYnl0ZXMgdG8gZmlsZSBzdHJlYW0uCi0gICAqCi0gICAqIEBwYXJhbSBmaWxlIE91dHB1dCBmaWxlIHN0cmVhbQotICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBkdW1wKERhdGFPdXRwdXRTdHJlYW0gZmlsZSkgdGhyb3dzIElPRXhjZXB0aW9uCi0gIHsKLSAgICBzdXBlci5kdW1wKGZpbGUpOwotICAgIGlmKGxlbmd0aCA+IDApCi0gICAgICBmaWxlLndyaXRlKGJ5dGVzLCAwLCBsZW5ndGgpOwotICB9Ci0gIC8qKgotICAgKiBAcmV0dXJuIGRhdGEgYnl0ZXMuCi0gICAqLwotICBwdWJsaWMgZmluYWwgYnl0ZVtdIGdldEJ5dGVzKCkgeyByZXR1cm4gYnl0ZXM7IH0KLQotICAvKioKLSAgICogQHJldHVybiBuYW1lIG9mIGF0dHJpYnV0ZS4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBTdHJpbmcgZ2V0TmFtZSgpIHsgcmV0dXJuIG5hbWU7IH0KLQotICAvKioKLSAgICogQHBhcmFtIGJ5dGVzLgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgc2V0Qnl0ZXMoYnl0ZVtdIGJ5dGVzKSB7Ci0gICAgdGhpcy5ieXRlcyA9IGJ5dGVzOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gU3RyaW5nIHJlcHJlc2VudGF0aW9uLgotICAgKi8KLSAgcHVibGljIGZpbmFsIFN0cmluZyB0b1N0cmluZygpIHsKLSAgICBpZihsZW5ndGggPT0gMCB8fCBieXRlcyA9PSBudWxsKQotICAgICAgcmV0dXJuICIoVW5rbm93biBhdHRyaWJ1dGUgIiArIG5hbWUgKyAiKSI7Ci0KLSAgICBTdHJpbmcgaGV4OwotICAgIGlmKGxlbmd0aCA+IDEwKSB7Ci0gICAgICBieXRlW10gdG1wID0gbmV3IGJ5dGVbMTBdOwotICAgICAgU3lzdGVtLmFycmF5Y29weShieXRlcywgMCwgdG1wLCAwLCAxMCk7Ci0gICAgICBoZXggPSBVdGlsaXR5LnRvSGV4U3RyaW5nKHRtcCkgKyAiLi4uICh0cnVuY2F0ZWQpIjsKLSAgICB9Ci0gICAgZWxzZQotICAgICAgaGV4ID0gVXRpbGl0eS50b0hleFN0cmluZyhieXRlcyk7Ci0KLSAgICByZXR1cm4gIihVbmtub3duIGF0dHJpYnV0ZSAiICsgbmFtZSArICI6ICIgKyBoZXggKyAiKSI7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBkZWVwIGNvcHkgb2YgdGhpcyBhdHRyaWJ1dGUKLSAgICovCi0gIHB1YmxpYyBBdHRyaWJ1dGUgY29weShDb25zdGFudFBvb2wgY29uc3RhbnRfcG9vbCkgewotICAgIFVua25vd24gYyA9IChVbmtub3duKWNsb25lKCk7Ci0KLSAgICBpZihieXRlcyAhPSBudWxsKQotICAgICAgYy5ieXRlcyA9IChieXRlW10pYnl0ZXMuY2xvbmUoKTsKLQotICAgIGMuY29uc3RhbnRfcG9vbCA9IGNvbnN0YW50X3Bvb2w7Ci0gICAgcmV0dXJuIGM7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvVXRpbGl0eS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2NsYXNzZmlsZS9VdGlsaXR5LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDllNGNkZGMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2NsYXNzZmlsZS9VdGlsaXR5LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMzk3ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmNsYXNzZmlsZTsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50czsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC51dGlsLkJ5dGVTZXF1ZW5jZTsKLWltcG9ydCBqYXZhLmlvLio7Ci1pbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKLWltcG9ydCBqYXZhLnV0aWwuemlwLio7Ci0KLS8qKgotICogVXRpbGl0eSBmdW5jdGlvbnMgdGhhdCBkbyBub3QgcmVhbGx5IGJlbG9uZyB0byBhbnkgY2xhc3MgaW4gcGFydGljdWxhci4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgYWJzdHJhY3QgY2xhc3MgVXRpbGl0eSB7Ci0gIHByaXZhdGUgc3RhdGljIGludCBjb25zdW1lZF9jaGFyczsgLyogSG93IG1hbnkgY2hhcnMgaGF2ZSBiZWVuIGNvbnN1bWVkCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogZHVyaW5nIHBhcnNpbmcgaW4gc2lnbmF0dXJlVG9TdHJpbmcoKS4KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBSZWFkIGJ5IG1ldGhvZFNpZ25hdHVyZVRvU3RyaW5nKCkuCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogU2V0IGJ5IHNpZGUgZWZmZWN0LGJ1dCBvbmx5IGludGVybmFsbHkuCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi0gIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gd2lkZT1mYWxzZTsgLyogVGhlIGBXSURFJyBpbnN0cnVjdGlvbiBpcyB1c2VkIGluIHRoZQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIGJ5dGUgY29kZSB0byBhbGxvdyAxNi1iaXQgd2lkZSBpbmRpY2VzCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogZm9yIGxvY2FsIHZhcmlhYmxlcy4gVGhpcyBvcGNvZGUKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBwcmVjZWRlcyBhbiBgSUxPQUQnLCBlLmcuLiBUaGUgb3Bjb2RlCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogaW1tZWRpYXRlbHkgZm9sbG93aW5nIHRha2VzIGFuIGV4dHJhCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogYnl0ZSB3aGljaCBpcyBjb21iaW5lZCB3aXRoIHRoZQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIGZvbGxvd2luZyBieXRlIHRvIGZvcm0gYQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIDE2LWJpdCB2YWx1ZS4KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLSAgLyoqCi0gICAqIENvbnZlcnQgYml0IGZpZWxkIG9mIGZsYWdzIGludG8gc3RyaW5nIHN1Y2ggYXMgYHN0YXRpYyBmaW5hbCcuCi0gICAqCi0gICAqIEBwYXJhbSAgYWNjZXNzX2ZsYWdzIEFjY2VzcyBmbGFncwotICAgKiBAcmV0dXJuIFN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBmbGFncwotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgYWNjZXNzVG9TdHJpbmcoaW50IGFjY2Vzc19mbGFncykgewotICAgIHJldHVybiBhY2Nlc3NUb1N0cmluZyhhY2Nlc3NfZmxhZ3MsIGZhbHNlKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb252ZXJ0IGJpdCBmaWVsZCBvZiBmbGFncyBpbnRvIHN0cmluZyBzdWNoIGFzIGBzdGF0aWMgZmluYWwnLgotICAgKgotICAgKiBTcGVjaWFsIGNhc2U6IENsYXNzZXMgY29tcGlsZWQgd2l0aCBuZXcgY29tcGlsZXJzIGFuZCB3aXRoIHRoZQotICAgKiBgQUNDX1NVUEVSJyBmbGFnIHdvdWxkIGJlIHNhaWQgdG8gYmUgInN5bmNocm9uaXplZCIuIFRoaXMgaXMKLSAgICogYmVjYXVzZSBTVU4gdXNlZCB0aGUgc2FtZSB2YWx1ZSBmb3IgdGhlIGZsYWdzIGBBQ0NfU1VQRVInIGFuZAotICAgKiBgQUNDX1NZTkNIUk9OSVpFRCcuCi0gICAqCi0gICAqIEBwYXJhbSAgYWNjZXNzX2ZsYWdzIEFjY2VzcyBmbGFncwotICAgKiBAcGFyYW0gIGZvcl9jbGFzcyBhY2Nlc3MgZmxhZ3MgYXJlIGZvciBjbGFzcyBxdWFsaWZpZXJzID8KLSAgICogQHJldHVybiBTdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgZmxhZ3MKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIGFjY2Vzc1RvU3RyaW5nKGludCBhY2Nlc3NfZmxhZ3MsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gZm9yX2NsYXNzKQotICB7Ci0gICAgU3RyaW5nQnVmZmVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLQotICAgIGludCBwID0gMDsKLSAgICBmb3IoaW50IGk9MDsgcCA8IENvbnN0YW50cy5NQVhfQUNDX0ZMQUc7IGkrKykgeyAvLyBMb29wIHRocm91Z2gga25vd24gZmxhZ3MKLSAgICAgIHAgPSBwb3cyKGkpOwotCi0gICAgICBpZigoYWNjZXNzX2ZsYWdzICYgcCkgIT0gMCkgewotICAgICAgICAvKiBTcGVjaWFsIGNhc2U6IENsYXNzZXMgY29tcGlsZWQgd2l0aCBuZXcgY29tcGlsZXJzIGFuZCB3aXRoIHRoZQotICAgICAgICAgKiBgQUNDX1NVUEVSJyBmbGFnIHdvdWxkIGJlIHNhaWQgdG8gYmUgInN5bmNocm9uaXplZCIuIFRoaXMgaXMKLSAgICAgICAgICogYmVjYXVzZSBTVU4gdXNlZCB0aGUgc2FtZSB2YWx1ZSBmb3IgdGhlIGZsYWdzIGBBQ0NfU1VQRVInIGFuZAotICAgICAgICAgKiBgQUNDX1NZTkNIUk9OSVpFRCcuCi0gICAgICAgICAqLwotICAgICAgICBpZihmb3JfY2xhc3MgJiYgKChwID09IENvbnN0YW50cy5BQ0NfU1VQRVIpIHx8IChwID09IENvbnN0YW50cy5BQ0NfSU5URVJGQUNFKSkpCi0gICAgICAgICAgY29udGludWU7Ci0KLSAgICAgICAgYnVmLmFwcGVuZChDb25zdGFudHMuQUNDRVNTX05BTUVTW2ldICsgIiAiKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gYnVmLnRvU3RyaW5nKCkudHJpbSgpOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gImNsYXNzIiBvciAiaW50ZXJmYWNlIiwgZGVwZW5kaW5nIG9uIHRoZSBBQ0NfSU5URVJGQUNFIGZsYWcKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIGNsYXNzT3JJbnRlcmZhY2UoaW50IGFjY2Vzc19mbGFncykgewotICAgIHJldHVybiAoKGFjY2Vzc19mbGFncyAmIENvbnN0YW50cy5BQ0NfSU5URVJGQUNFKSAhPSAwKT8gImludGVyZmFjZSIgOiAiY2xhc3MiOwotICB9Ci0KLSAgLyoqCi0gICAqIERpc2Fzc2VtYmxlIGEgYnl0ZSBhcnJheSBvZiBKVk0gYnl0ZSBjb2RlcyBzdGFydGluZyBmcm9tIGNvZGUgbGluZQotICAgKiBgaW5kZXgnIGFuZCByZXR1cm4gdGhlIGRpc2Fzc2VtYmxlZCBzdHJpbmcgcmVwcmVzZW50YXRpb24uIERlY29kZSBvbmx5Ci0gICAqIGBudW0nIG9wY29kZXMgKGluY2x1ZGluZyB0aGVpciBvcGVyYW5kcyksIHVzZSAtMSBpZiB5b3Ugd2FudCB0bwotICAgKiBkZWNvbXBpbGUgZXZlcnl0aGluZy4KLSAgICoKLSAgICogQHBhcmFtICBjb2RlIGJ5dGUgY29kZSBhcnJheQotICAgKiBAcGFyYW0gIGNvbnN0YW50X3Bvb2wgQXJyYXkgb2YgY29uc3RhbnRzCi0gICAqIEBwYXJhbSAgaW5kZXggb2Zmc2V0IGluIGBjb2RlJyBhcnJheQotICAgKiA8RU0+KG51bWJlciBvZiBvcGNvZGVzLCBub3QgYnl0ZXMhKTwvRU0+Ci0gICAqIEBwYXJhbSAgbGVuZ3RoIG51bWJlciBvZiBvcGNvZGVzIHRvIGRlY29tcGlsZSwgLTEgZm9yIGFsbAotICAgKiBAcGFyYW0gIHZlcmJvc2UgYmUgdmVyYm9zZSwgZS5nLiBwcmludCBjb25zdGFudCBwb29sIGluZGV4Ci0gICAqIEByZXR1cm4gU3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIGJ5dGUgY29kZXMKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIGNvZGVUb1N0cmluZyhieXRlW10gY29kZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbnN0YW50UG9vbCBjb25zdGFudF9wb29sLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGluZGV4LCBpbnQgbGVuZ3RoLCBib29sZWFuIHZlcmJvc2UpCi0gIHsKLSAgICBTdHJpbmdCdWZmZXIgYnVmICAgID0gbmV3IFN0cmluZ0J1ZmZlcihjb2RlLmxlbmd0aCAqIDIwKTsgLy8gU2hvdWxkIGJlIHN1ZmZpY2llbnQKLSAgICBCeXRlU2VxdWVuY2Ugc3RyZWFtID0gbmV3IEJ5dGVTZXF1ZW5jZShjb2RlKTsKLQotICAgIHRyeSB7Ci0gICAgICBmb3IoaW50IGk9MDsgaSA8IGluZGV4OyBpKyspIC8vIFNraXAgYGluZGV4JyBsaW5lcyBvZiBjb2RlCi0gICAgICAgIGNvZGVUb1N0cmluZyhzdHJlYW0sIGNvbnN0YW50X3Bvb2wsIHZlcmJvc2UpOwotCi0gICAgICBmb3IoaW50IGk9MDsgc3RyZWFtLmF2YWlsYWJsZSgpID4gMDsgaSsrKSB7Ci0gICAgICAgIGlmKChsZW5ndGggPCAwKSB8fCAoaSA8IGxlbmd0aCkpIHsKLSAgICAgICAgICBTdHJpbmcgaW5kaWNlcyA9IGZpbGx1cChzdHJlYW0uZ2V0SW5kZXgoKSArICI6IiwgNiwgdHJ1ZSwgJyAnKTsKLSAgICAgICAgICBidWYuYXBwZW5kKGluZGljZXMgKyBjb2RlVG9TdHJpbmcoc3RyZWFtLCBjb25zdGFudF9wb29sLCB2ZXJib3NlKSArICdcbicpOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfSBjYXRjaChJT0V4Y2VwdGlvbiBlKSB7Ci0gICAgICBTeXN0ZW0ub3V0LnByaW50bG4oYnVmLnRvU3RyaW5nKCkpOwotICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgIHRocm93IG5ldyBDbGFzc0Zvcm1hdEV4Y2VwdGlvbigiQnl0ZSBjb2RlIGVycm9yOiAiICsgZSk7Ci0gICAgfQotCi0gICAgcmV0dXJuIGJ1Zi50b1N0cmluZygpOwotICB9Ci0KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgY29kZVRvU3RyaW5nKGJ5dGVbXSBjb2RlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29uc3RhbnRQb29sIGNvbnN0YW50X3Bvb2wsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaW5kZXgsIGludCBsZW5ndGgpIHsKLSAgICByZXR1cm4gY29kZVRvU3RyaW5nKGNvZGUsIGNvbnN0YW50X3Bvb2wsIGluZGV4LCBsZW5ndGgsIHRydWUpOwotICB9Ci0KLSAgLyoqCi0gICAqIERpc2Fzc2VtYmxlIGEgc3RyZWFtIG9mIGJ5dGUgY29kZXMgYW5kIHJldHVybiB0aGUKLSAgICogc3RyaW5nIHJlcHJlc2VudGF0aW9uLgotICAgKgotICAgKiBAcGFyYW0gIGJ5dGVzIHN0cmVhbSBvZiBieXRlcwotICAgKiBAcGFyYW0gIGNvbnN0YW50X3Bvb2wgQXJyYXkgb2YgY29uc3RhbnRzCi0gICAqIEBwYXJhbSAgdmVyYm9zZSBiZSB2ZXJib3NlLCBlLmcuIHByaW50IGNvbnN0YW50IHBvb2wgaW5kZXgKLSAgICogQHJldHVybiBTdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgYnl0ZSBjb2RlCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBjb2RlVG9TdHJpbmcoQnl0ZVNlcXVlbmNlIGJ5dGVzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29uc3RhbnRQb29sIGNvbnN0YW50X3Bvb2wsIGJvb2xlYW4gdmVyYm9zZSkKLSAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24KLSAgewotICAgIHNob3J0ICAgICAgICBvcGNvZGUgPSAoc2hvcnQpYnl0ZXMucmVhZFVuc2lnbmVkQnl0ZSgpOwotICAgIGludCAgICAgICAgICBkZWZhdWx0X29mZnNldD0wLCBsb3csIGhpZ2gsIG5wYWlyczsKLSAgICBpbnQgICAgICAgICAgaW5kZXgsIHZpbmRleCwgY29uc3RhbnQ7Ci0gICAgaW50W10gICAgICAgIG1hdGNoLCBqdW1wX3RhYmxlOwotICAgIGludCAgICAgICAgICBub19wYWRfYnl0ZXM9MCwgb2Zmc2V0OwotICAgIFN0cmluZ0J1ZmZlciBidWYgPSBuZXcgU3RyaW5nQnVmZmVyKENvbnN0YW50cy5PUENPREVfTkFNRVNbb3Bjb2RlXSk7Ci0KLSAgICAvKiBTcGVjaWFsIGNhc2U6IFNraXAgKDAtMykgcGFkZGluZyBieXRlcywgaS5lLiwgdGhlCi0gICAgICogZm9sbG93aW5nIGJ5dGVzIGFyZSA0LWJ5dGUtYWxpZ25lZAotICAgICAqLwotICAgIGlmKChvcGNvZGUgPT0gQ29uc3RhbnRzLlRBQkxFU1dJVENIKSB8fCAob3Bjb2RlID09IENvbnN0YW50cy5MT09LVVBTV0lUQ0gpKSB7Ci0gICAgICBpbnQgcmVtYWluZGVyID0gYnl0ZXMuZ2V0SW5kZXgoKSAlIDQ7Ci0gICAgICBub19wYWRfYnl0ZXMgID0gKHJlbWFpbmRlciA9PSAwKT8gMCA6IDQgLSByZW1haW5kZXI7Ci0KLSAgICAgIGZvcihpbnQgaT0wOyBpIDwgbm9fcGFkX2J5dGVzOyBpKyspIHsKLSAgICAgICAgYnl0ZSBiOwotCi0gICAgICAgIGlmKChiPWJ5dGVzLnJlYWRCeXRlKCkpICE9IDApCi0gICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJXYXJuaW5nOiBQYWRkaW5nIGJ5dGUgIT0gMCBpbiAiICsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29uc3RhbnRzLk9QQ09ERV9OQU1FU1tvcGNvZGVdICsgIjoiICsgYik7Ci0gICAgICB9Ci0KLSAgICAgIC8vIEJvdGggY2FzZXMgaGF2ZSBhIGZpZWxkIGRlZmF1bHRfb2Zmc2V0IGluIGNvbW1vbgotICAgICAgZGVmYXVsdF9vZmZzZXQgPSBieXRlcy5yZWFkSW50KCk7Ci0gICAgfQotCi0gICAgc3dpdGNoKG9wY29kZSkgewotICAgICAgLyogVGFibGUgc3dpdGNoIGhhcyB2YXJpYWJsZSBsZW5ndGggYXJndW1lbnRzLgotICAgICAgICovCi0gICAgY2FzZSBDb25zdGFudHMuVEFCTEVTV0lUQ0g6Ci0gICAgICBsb3cgID0gYnl0ZXMucmVhZEludCgpOwotICAgICAgaGlnaCA9IGJ5dGVzLnJlYWRJbnQoKTsKLQotICAgICAgb2Zmc2V0ID0gYnl0ZXMuZ2V0SW5kZXgoKSAtIDEyIC0gbm9fcGFkX2J5dGVzIC0gMTsKLSAgICAgIGRlZmF1bHRfb2Zmc2V0ICs9IG9mZnNldDsKLQotICAgICAgYnVmLmFwcGVuZCgiXHRkZWZhdWx0ID0gIiArIGRlZmF1bHRfb2Zmc2V0ICsgIiwgbG93ID0gIiArIGxvdyArCi0gICAgICAgICAgICAgICAgICIsIGhpZ2ggPSAiICsgaGlnaCArICIoIik7Ci0KLSAgICAgIGp1bXBfdGFibGUgPSBuZXcgaW50W2hpZ2ggLSBsb3cgKyAxXTsKLSAgICAgIGZvcihpbnQgaT0wOyBpIDwganVtcF90YWJsZS5sZW5ndGg7IGkrKykgewotICAgICAgICBqdW1wX3RhYmxlW2ldID0gb2Zmc2V0ICsgYnl0ZXMucmVhZEludCgpOwotICAgICAgICBidWYuYXBwZW5kKGp1bXBfdGFibGVbaV0pOwotCi0gICAgICAgIGlmKGkgPCBqdW1wX3RhYmxlLmxlbmd0aCAtIDEpCi0gICAgICAgICAgYnVmLmFwcGVuZCgiLCAiKTsKLSAgICAgIH0KLSAgICAgIGJ1Zi5hcHBlbmQoIikiKTsKLQotICAgICAgYnJlYWs7Ci0KLSAgICAgIC8qIExvb2t1cCBzd2l0Y2ggaGFzIHZhcmlhYmxlIGxlbmd0aCBhcmd1bWVudHMuCi0gICAgICAgKi8KLSAgICBjYXNlIENvbnN0YW50cy5MT09LVVBTV0lUQ0g6IHsKLQotICAgICAgbnBhaXJzID0gYnl0ZXMucmVhZEludCgpOwotICAgICAgb2Zmc2V0ID0gYnl0ZXMuZ2V0SW5kZXgoKSAtIDggLSBub19wYWRfYnl0ZXMgLSAxOwotCi0gICAgICBtYXRjaCAgICAgID0gbmV3IGludFtucGFpcnNdOwotICAgICAganVtcF90YWJsZSA9IG5ldyBpbnRbbnBhaXJzXTsKLSAgICAgIGRlZmF1bHRfb2Zmc2V0ICs9IG9mZnNldDsKLQotICAgICAgYnVmLmFwcGVuZCgiXHRkZWZhdWx0ID0gIiArIGRlZmF1bHRfb2Zmc2V0ICsgIiwgbnBhaXJzID0gIiArIG5wYWlycyArCi0gICAgICAgICAgICAgICAgICIgKCIpOwotCi0gICAgICBmb3IoaW50IGk9MDsgaSA8IG5wYWlyczsgaSsrKSB7Ci0gICAgICAgIG1hdGNoW2ldICAgICAgPSBieXRlcy5yZWFkSW50KCk7Ci0KLSAgICAgICAganVtcF90YWJsZVtpXSA9IG9mZnNldCArIGJ5dGVzLnJlYWRJbnQoKTsKLQotICAgICAgICBidWYuYXBwZW5kKCIoIiArIG1hdGNoW2ldICsgIiwgIiArIGp1bXBfdGFibGVbaV0gKyAiKSIpOwotCi0gICAgICAgIGlmKGkgPCBucGFpcnMgLSAxKQotICAgICAgICAgIGJ1Zi5hcHBlbmQoIiwgIik7Ci0gICAgICB9Ci0gICAgICBidWYuYXBwZW5kKCIpIik7Ci0gICAgfQotICAgIGJyZWFrOwotCi0gICAgLyogVHdvIGFkZHJlc3MgYnl0ZXMgKyBvZmZzZXQgZnJvbSBzdGFydCBvZiBieXRlIHN0cmVhbSBmb3JtIHRoZQotICAgICAqIGp1bXAgdGFyZ2V0Ci0gICAgICovCi0gICAgY2FzZSBDb25zdGFudHMuR09UTzogICAgICBjYXNlIENvbnN0YW50cy5JRkVROiAgICAgIGNhc2UgQ29uc3RhbnRzLklGR0U6ICAgICAgY2FzZSBDb25zdGFudHMuSUZHVDoKLSAgICBjYXNlIENvbnN0YW50cy5JRkxFOiAgICAgIGNhc2UgQ29uc3RhbnRzLklGTFQ6ICAgICAgY2FzZSBDb25zdGFudHMuSlNSOiBjYXNlIENvbnN0YW50cy5JRk5FOgotICAgIGNhc2UgQ29uc3RhbnRzLklGTk9OTlVMTDogY2FzZSBDb25zdGFudHMuSUZOVUxMOiAgICBjYXNlIENvbnN0YW50cy5JRl9BQ01QRVE6Ci0gICAgY2FzZSBDb25zdGFudHMuSUZfQUNNUE5FOiBjYXNlIENvbnN0YW50cy5JRl9JQ01QRVE6IGNhc2UgQ29uc3RhbnRzLklGX0lDTVBHRTogY2FzZSBDb25zdGFudHMuSUZfSUNNUEdUOgotICAgIGNhc2UgQ29uc3RhbnRzLklGX0lDTVBMRTogY2FzZSBDb25zdGFudHMuSUZfSUNNUExUOiBjYXNlIENvbnN0YW50cy5JRl9JQ01QTkU6Ci0gICAgICBidWYuYXBwZW5kKCJcdFx0IyIgKyAoKGJ5dGVzLmdldEluZGV4KCkgLSAxKSArIGJ5dGVzLnJlYWRTaG9ydCgpKSk7Ci0gICAgICBicmVhazsKLQotICAgICAgLyogMzItYml0IHdpZGUganVtcHMKLSAgICAgICAqLwotICAgIGNhc2UgQ29uc3RhbnRzLkdPVE9fVzogY2FzZSBDb25zdGFudHMuSlNSX1c6Ci0gICAgICBidWYuYXBwZW5kKCJcdFx0IyIgKyAoKGJ5dGVzLmdldEluZGV4KCkgLSAxKSArIGJ5dGVzLnJlYWRJbnQoKSkpOwotICAgICAgYnJlYWs7Ci0KLSAgICAgIC8qIEluZGV4IGJ5dGUgcmVmZXJlbmNlcyBsb2NhbCB2YXJpYWJsZSAocmVnaXN0ZXIpCi0gICAgICAgKi8KLSAgICBjYXNlIENvbnN0YW50cy5BTE9BRDogIGNhc2UgQ29uc3RhbnRzLkFTVE9SRTogY2FzZSBDb25zdGFudHMuRExPQUQ6ICBjYXNlIENvbnN0YW50cy5EU1RPUkU6IGNhc2UgQ29uc3RhbnRzLkZMT0FEOgotICAgIGNhc2UgQ29uc3RhbnRzLkZTVE9SRTogY2FzZSBDb25zdGFudHMuSUxPQUQ6ICBjYXNlIENvbnN0YW50cy5JU1RPUkU6IGNhc2UgQ29uc3RhbnRzLkxMT0FEOiAgY2FzZSBDb25zdGFudHMuTFNUT1JFOgotICAgIGNhc2UgQ29uc3RhbnRzLlJFVDoKLSAgICAgIGlmKHdpZGUpIHsKLSAgICAgICAgdmluZGV4ID0gYnl0ZXMucmVhZFVuc2lnbmVkU2hvcnQoKTsKLSAgICAgICAgd2lkZT1mYWxzZTsgLy8gQ2xlYXIgZmxhZwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgICB2aW5kZXggPSBieXRlcy5yZWFkVW5zaWduZWRCeXRlKCk7Ci0KLSAgICAgIGJ1Zi5hcHBlbmQoIlx0XHQlIiArIHZpbmRleCk7Ci0gICAgICBicmVhazsKLQotICAgICAgLyoKLSAgICAgICAqIFJlbWVtYmVyIHdpZGUgYnl0ZSB3aGljaCBpcyB1c2VkIHRvIGZvcm0gYSAxNi1iaXQgYWRkcmVzcyBpbiB0aGUKLSAgICAgICAqIGZvbGxvd2luZyBpbnN0cnVjdGlvbi4gUmVsaWVzIG9uIHRoYXQgdGhlIG1ldGhvZCBpcyBjYWxsZWQgYWdhaW4gd2l0aAotICAgICAgICogdGhlIGZvbGxvd2luZyBvcGNvZGUuCi0gICAgICAgKi8KLSAgICBjYXNlIENvbnN0YW50cy5XSURFOgotICAgICAgd2lkZSAgICAgID0gdHJ1ZTsKLSAgICAgIGJ1Zi5hcHBlbmQoIlx0KHdpZGUpIik7Ci0gICAgICBicmVhazsKLQotICAgICAgLyogQXJyYXkgb2YgYmFzaWMgdHlwZS4KLSAgICAgICAqLwotICAgIGNhc2UgQ29uc3RhbnRzLk5FV0FSUkFZOgotICAgICAgYnVmLmFwcGVuZCgiXHRcdDwiICsgQ29uc3RhbnRzLlRZUEVfTkFNRVNbYnl0ZXMucmVhZEJ5dGUoKV0gKyAiPiIpOwotICAgICAgYnJlYWs7Ci0KLSAgICAgIC8qIEFjY2VzcyBvYmplY3QvY2xhc3MgZmllbGRzLgotICAgICAgICovCi0gICAgY2FzZSBDb25zdGFudHMuR0VURklFTEQ6IGNhc2UgQ29uc3RhbnRzLkdFVFNUQVRJQzogY2FzZSBDb25zdGFudHMuUFVURklFTEQ6IGNhc2UgQ29uc3RhbnRzLlBVVFNUQVRJQzoKLSAgICAgIGluZGV4ID0gYnl0ZXMucmVhZFVuc2lnbmVkU2hvcnQoKTsKLSAgICAgIGJ1Zi5hcHBlbmQoIlx0XHQiICsKLSAgICAgICAgICAgICAgICAgY29uc3RhbnRfcG9vbC5jb25zdGFudFRvU3RyaW5nKGluZGV4LCBDb25zdGFudHMuQ09OU1RBTlRfRmllbGRyZWYpICsKLSAgICAgICAgICAgICAgICAgKHZlcmJvc2U/ICIgKCIgKyBpbmRleCArICIpIiA6ICIiKSk7Ci0gICAgICBicmVhazsKLQotICAgICAgLyogT3BlcmFuZHMgYXJlIHJlZmVyZW5jZXMgdG8gY2xhc3NlcyBpbiBjb25zdGFudCBwb29sCi0gICAgICAgKi8KLSAgICBjYXNlIENvbnN0YW50cy5ORVc6Ci0gICAgY2FzZSBDb25zdGFudHMuQ0hFQ0tDQVNUOgotICAgICAgYnVmLmFwcGVuZCgiXHQiKTsKLSAgICBjYXNlIENvbnN0YW50cy5JTlNUQU5DRU9GOgotICAgICAgaW5kZXggPSBieXRlcy5yZWFkVW5zaWduZWRTaG9ydCgpOwotICAgICAgYnVmLmFwcGVuZCgiXHQ8IiArIGNvbnN0YW50X3Bvb2wuY29uc3RhbnRUb1N0cmluZyhpbmRleCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29uc3RhbnRzLkNPTlNUQU5UX0NsYXNzKSArCi0gICAgICAgICAgICAgICAgICI+IiArICh2ZXJib3NlPyAiICgiICsgaW5kZXggKyAiKSIgOiAiIikpOwotICAgICAgYnJlYWs7Ci0KLSAgICAgIC8qIE9wZXJhbmRzIGFyZSByZWZlcmVuY2VzIHRvIG1ldGhvZHMgaW4gY29uc3RhbnQgcG9vbAotICAgICAgICovCi0gICAgY2FzZSBDb25zdGFudHMuSU5WT0tFU1BFQ0lBTDogY2FzZSBDb25zdGFudHMuSU5WT0tFU1RBVElDOiBjYXNlIENvbnN0YW50cy5JTlZPS0VWSVJUVUFMOgotICAgICAgaW5kZXggPSBieXRlcy5yZWFkVW5zaWduZWRTaG9ydCgpOwotICAgICAgYnVmLmFwcGVuZCgiXHQiICsgY29uc3RhbnRfcG9vbC5jb25zdGFudFRvU3RyaW5nKGluZGV4LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbnN0YW50cy5DT05TVEFOVF9NZXRob2RyZWYpICsKLSAgICAgICAgICAgICAgICAgKHZlcmJvc2U/ICIgKCIgKyBpbmRleCArICIpIiA6ICIiKSk7Ci0gICAgICBicmVhazsKLQotICAgIGNhc2UgQ29uc3RhbnRzLklOVk9LRUlOVEVSRkFDRToKLSAgICAgIGluZGV4ID0gYnl0ZXMucmVhZFVuc2lnbmVkU2hvcnQoKTsKLSAgICAgIGludCBuYXJncyA9IGJ5dGVzLnJlYWRVbnNpZ25lZEJ5dGUoKTsgLy8gaGlzdG9yaWNhbCwgcmVkdW5kYW50Ci0gICAgICBidWYuYXBwZW5kKCJcdCIgKwotICAgICAgICAgICAgICAgICBjb25zdGFudF9wb29sLmNvbnN0YW50VG9TdHJpbmcoaW5kZXgsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb25zdGFudHMuQ09OU1RBTlRfSW50ZXJmYWNlTWV0aG9kcmVmKSArCi0gICAgICAgICAgICAgICAgICh2ZXJib3NlPyAiICgiICsgaW5kZXggKyAiKVx0IiA6ICIiKSArIG5hcmdzICsgIlx0IiArCi0gICAgICAgICAgICAgICAgIGJ5dGVzLnJlYWRVbnNpZ25lZEJ5dGUoKSk7IC8vIExhc3QgYnl0ZSBpcyBhIHJlc2VydmVkIHNwYWNlCi0gICAgICBicmVhazsKLQotICAgICAgLyogT3BlcmFuZHMgYXJlIHJlZmVyZW5jZXMgdG8gaXRlbXMgaW4gY29uc3RhbnQgcG9vbAotICAgICAgICovCi0gICAgY2FzZSBDb25zdGFudHMuTERDX1c6IGNhc2UgQ29uc3RhbnRzLkxEQzJfVzoKLSAgICAgIGluZGV4ID0gYnl0ZXMucmVhZFVuc2lnbmVkU2hvcnQoKTsKLQotICAgICAgYnVmLmFwcGVuZCgiXHRcdCIgKyBjb25zdGFudF9wb29sLmNvbnN0YW50VG9TdHJpbmcKLSAgICAgICAgICAgICAgICAgKGluZGV4LCBjb25zdGFudF9wb29sLmdldENvbnN0YW50KGluZGV4KS5nZXRUYWcoKSkgKwotICAgICAgICAgICAgICAgICAodmVyYm9zZT8gIiAoIiArIGluZGV4ICsgIikiIDogIiIpKTsKLSAgICAgIGJyZWFrOwotCi0gICAgY2FzZSBDb25zdGFudHMuTERDOgotICAgICAgaW5kZXggPSBieXRlcy5yZWFkVW5zaWduZWRCeXRlKCk7Ci0KLSAgICAgIGJ1Zi5hcHBlbmQoIlx0XHQiICsKLSAgICAgICAgICAgICAgICAgY29uc3RhbnRfcG9vbC5jb25zdGFudFRvU3RyaW5nCi0gICAgICAgICAgICAgICAgIChpbmRleCwgY29uc3RhbnRfcG9vbC5nZXRDb25zdGFudChpbmRleCkuZ2V0VGFnKCkpICsKLSAgICAgICAgICAgICAgICAgKHZlcmJvc2U/ICIgKCIgKyBpbmRleCArICIpIiA6ICIiKSk7Ci0gICAgICBicmVhazsKLQotICAgICAgLyogQXJyYXkgb2YgcmVmZXJlbmNlcy4KLSAgICAgICAqLwotICAgIGNhc2UgQ29uc3RhbnRzLkFORVdBUlJBWToKLSAgICAgIGluZGV4ID0gYnl0ZXMucmVhZFVuc2lnbmVkU2hvcnQoKTsKLQotICAgICAgYnVmLmFwcGVuZCgiXHRcdDwiICsgY29tcGFjdENsYXNzTmFtZShjb25zdGFudF9wb29sLmdldENvbnN0YW50U3RyaW5nCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoaW5kZXgsIENvbnN0YW50cy5DT05TVEFOVF9DbGFzcyksIGZhbHNlKSArCi0gICAgICAgICAgICAgICAgICI+IiArICh2ZXJib3NlPyAiICgiICsgaW5kZXggKyAiKSI6ICIiKSk7Ci0gICAgICBicmVhazsKLQotICAgICAgLyogTXVsdGlkaW1lbnNpb25hbCBhcnJheSBvZiByZWZlcmVuY2VzLgotICAgICAgICovCi0gICAgY2FzZSBDb25zdGFudHMuTVVMVElBTkVXQVJSQVk6IHsKLSAgICAgIGluZGV4ICAgICAgICAgID0gYnl0ZXMucmVhZFVuc2lnbmVkU2hvcnQoKTsKLSAgICAgIGludCBkaW1lbnNpb25zID0gYnl0ZXMucmVhZFVuc2lnbmVkQnl0ZSgpOwotCi0gICAgICBidWYuYXBwZW5kKCJcdDwiICsgY29tcGFjdENsYXNzTmFtZShjb25zdGFudF9wb29sLmdldENvbnN0YW50U3RyaW5nCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoaW5kZXgsIENvbnN0YW50cy5DT05TVEFOVF9DbGFzcyksIGZhbHNlKSArCi0gICAgICAgICAgICAgICAgICI+XHQiICsgZGltZW5zaW9ucyArICh2ZXJib3NlPyAiICgiICsgaW5kZXggKyAiKSIgOiAiIikpOwotICAgIH0KLSAgICBicmVhazsKLQotICAgIC8qIEluY3JlbWVudCBsb2NhbCB2YXJpYWJsZS4KLSAgICAgKi8KLSAgICBjYXNlIENvbnN0YW50cy5JSU5DOgotICAgICAgaWYod2lkZSkgewotICAgICAgICB2aW5kZXggICA9IGJ5dGVzLnJlYWRVbnNpZ25lZFNob3J0KCk7Ci0gICAgICAgIGNvbnN0YW50ID0gYnl0ZXMucmVhZFNob3J0KCk7Ci0gICAgICAgIHdpZGUgICAgID0gZmFsc2U7Ci0gICAgICB9Ci0gICAgICBlbHNlIHsKLSAgICAgICAgdmluZGV4ICAgPSBieXRlcy5yZWFkVW5zaWduZWRCeXRlKCk7Ci0gICAgICAgIGNvbnN0YW50ID0gYnl0ZXMucmVhZEJ5dGUoKTsKLSAgICAgIH0KLSAgICAgIGJ1Zi5hcHBlbmQoIlx0XHQlIiArIHZpbmRleCArICJcdCIgKyBjb25zdGFudCk7Ci0gICAgICBicmVhazsKLQotICAgIGRlZmF1bHQ6Ci0gICAgICBpZihDb25zdGFudHMuTk9fT0ZfT1BFUkFORFNbb3Bjb2RlXSA+IDApIHsKLSAgICAgICAgZm9yKGludCBpPTA7IGkgPCBDb25zdGFudHMuVFlQRV9PRl9PUEVSQU5EU1tvcGNvZGVdLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgYnVmLmFwcGVuZCgiXHRcdCIpOwotICAgICAgICAgIHN3aXRjaChDb25zdGFudHMuVFlQRV9PRl9PUEVSQU5EU1tvcGNvZGVdW2ldKSB7Ci0gICAgICAgICAgY2FzZSBDb25zdGFudHMuVF9CWVRFOiAgYnVmLmFwcGVuZChieXRlcy5yZWFkQnl0ZSgpKTsgYnJlYWs7Ci0gICAgICAgICAgY2FzZSBDb25zdGFudHMuVF9TSE9SVDogYnVmLmFwcGVuZChieXRlcy5yZWFkU2hvcnQoKSk7ICAgICAgIGJyZWFrOwotICAgICAgICAgIGNhc2UgQ29uc3RhbnRzLlRfSU5UOiAgIGJ1Zi5hcHBlbmQoYnl0ZXMucmVhZEludCgpKTsgICAgICAgICBicmVhazsKLQotICAgICAgICAgIGRlZmF1bHQ6IC8vIE5ldmVyIHJlYWNoZWQKLSAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiVW5yZWFjaGFibGUgZGVmYXVsdCBjYXNlIHJlYWNoZWQhIik7Ci0gICAgICAgICAgICBidWYuc2V0TGVuZ3RoKDApOwotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiBidWYudG9TdHJpbmcoKTsKLSAgfQotCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIGNvZGVUb1N0cmluZyhCeXRlU2VxdWVuY2UgYnl0ZXMsIENvbnN0YW50UG9vbCBjb25zdGFudF9wb29sKQotICAgIHRocm93cyBJT0V4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIGNvZGVUb1N0cmluZyhieXRlcywgY29uc3RhbnRfcG9vbCwgdHJ1ZSk7Ci0gIH0KLQotICAvKioKLSAgICogU2hvcnRlbiBsb25nIGNsYXNzIG5hbWVzLCA8ZW0+amF2YS9sYW5nL1N0cmluZzwvZW0+IGJlY29tZXMKLSAgICogPGVtPlN0cmluZzwvZW0+LgotICAgKgotICAgKiBAcGFyYW0gc3RyIFRoZSBsb25nIGNsYXNzIG5hbWUKLSAgICogQHJldHVybiBDb21wYWN0ZWQgY2xhc3MgbmFtZQotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgY29tcGFjdENsYXNzTmFtZShTdHJpbmcgc3RyKSB7Ci0gICAgcmV0dXJuIGNvbXBhY3RDbGFzc05hbWUoc3RyLCB0cnVlKTsKLSAgfQotCi0gIC8qKgotICAgKiBTaG9ydGVuIGxvbmcgY2xhc3MgbmFtZSA8ZW0+c3RyPC9lbT4sIGkuZS4sIGNob3Agb2ZmIHRoZSA8ZW0+cHJlZml4PC9lbT4sCi0gICAqIGlmIHRoZQotICAgKiBjbGFzcyBuYW1lIHN0YXJ0cyB3aXRoIHRoaXMgc3RyaW5nIGFuZCB0aGUgZmxhZyA8ZW0+Y2hvcGl0PC9lbT4gaXMgdHJ1ZS4KLSAgICogU2xhc2hlcyA8ZW0+LzwvZW0+IGFyZSBjb252ZXJ0ZWQgdG8gZG90cyA8ZW0+LjwvZW0+LgotICAgKgotICAgKiBAcGFyYW0gc3RyIFRoZSBsb25nIGNsYXNzIG5hbWUKLSAgICogQHBhcmFtIHByZWZpeCBUaGUgcHJlZml4IHRoZSBnZXQgcmlkIG9mZgotICAgKiBAcGFyYW0gY2hvcGl0IEZsYWcgdGhhdCBkZXRlcm1pbmVzIHdoZXRoZXIgY2hvcHBpbmcgaXMgZXhlY3V0ZWQgb3Igbm90Ci0gICAqIEByZXR1cm4gQ29tcGFjdGVkIGNsYXNzIG5hbWUKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIGNvbXBhY3RDbGFzc05hbWUoU3RyaW5nIHN0ciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcHJlZml4LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gY2hvcGl0KQotICB7Ci0gICAgaW50IGxlbiA9IHByZWZpeC5sZW5ndGgoKTsKLQotICAgIHN0ciA9IHN0ci5yZXBsYWNlKCcvJywgJy4nKTsgLy8gSXMgYC8nIG9uIGFsbCBzeXN0ZW1zLCBldmVuIERPUwotCi0gICAgaWYoY2hvcGl0KSB7Ci0gICAgICAvLyBJZiBzdHJpbmcgc3RhcnRzIHdpdGggYHByZWZpeCcgYW5kIGNvbnRhaW5zIG5vIGZ1cnRoZXIgZG90cwotICAgICAgaWYoc3RyLnN0YXJ0c1dpdGgocHJlZml4KSAmJgotICAgICAgICAgKHN0ci5zdWJzdHJpbmcobGVuKS5pbmRleE9mKCcuJykgPT0gLTEpKQotICAgICAgICBzdHIgPSBzdHIuc3Vic3RyaW5nKGxlbik7Ci0gICAgfQotCi0gICAgcmV0dXJuIHN0cjsKLSAgfQotCi0gIC8qKgotICAgKiBTaG9ydGVuIGxvbmcgY2xhc3MgbmFtZXMsIDxlbT5qYXZhL2xhbmcvU3RyaW5nPC9lbT4gYmVjb21lcwotICAgKiA8ZW0+amF2YS5sYW5nLlN0cmluZzwvZW0+LAotICAgKiBlLmcuLiBJZiA8ZW0+Y2hvcGl0PC9lbT4gaXMgPGVtPnRydWU8L2VtPiB0aGUgcHJlZml4IDxlbT5qYXZhLmxhbmc8L2VtPgotICAgKiBpcyBhbHNvIHJlbW92ZWQuCi0gICAqCi0gICAqIEBwYXJhbSBzdHIgVGhlIGxvbmcgY2xhc3MgbmFtZQotICAgKiBAcGFyYW0gY2hvcGl0IEZsYWcgdGhhdCBkZXRlcm1pbmVzIHdoZXRoZXIgY2hvcHBpbmcgaXMgZXhlY3V0ZWQgb3Igbm90Ci0gICAqIEByZXR1cm4gQ29tcGFjdGVkIGNsYXNzIG5hbWUKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIGNvbXBhY3RDbGFzc05hbWUoU3RyaW5nIHN0ciwgYm9vbGVhbiBjaG9waXQpIHsKLSAgICByZXR1cm4gY29tcGFjdENsYXNzTmFtZShzdHIsICJqYXZhLmxhbmcuIiwgY2hvcGl0KTsKLSAgfQotCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW4gaXNfZGlnaXQoY2hhciBjaCkgewotICAgIHJldHVybiAoY2ggPj0gJzAnKSAmJiAoY2ggPD0gJzknKTsKLSAgfQotCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW4gaXNfc3BhY2UoY2hhciBjaCkgewotICAgIHJldHVybiAoY2ggPT0gJyAnKSB8fCAoY2ggPT0gJ1x0JykgfHwgKGNoID09ICdccicpIHx8IChjaCA9PSAnXG4nKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIGBmbGFnJyB3aXRoIGJpdCBgaScgc2V0IHRvIDEKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IHNldEJpdChpbnQgZmxhZywgaW50IGkpIHsKLSAgICByZXR1cm4gZmxhZyB8IHBvdzIoaSk7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBgZmxhZycgd2l0aCBiaXQgYGknIHNldCB0byAwCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBjbGVhckJpdChpbnQgZmxhZywgaW50IGkpIHsKLSAgICBpbnQgYml0ID0gcG93MihpKTsKLSAgICByZXR1cm4gKGZsYWcgJiBiaXQpID09IDA/IGZsYWcgOiBmbGFnIF4gYml0OwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gdHJ1ZSwgaWYgYml0IGBpJyBpbiBgZmxhZycgaXMgc2V0Ci0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGJvb2xlYW4gaXNTZXQoaW50IGZsYWcsIGludCBpKSB7Ci0gICAgcmV0dXJuIChmbGFnICYgcG93MihpKSkgIT0gMDsKLSAgfQotCi0gIC8qKgotICAgKiBDb252ZXJ0cyBzdHJpbmcgY29udGFpbmluZyB0aGUgbWV0aG9kIHJldHVybiBhbmQgYXJndW1lbnQgdHlwZXMKLSAgICogdG8gYSBieXRlIGNvZGUgbWV0aG9kIHNpZ25hdHVyZS4KLSAgICoKLSAgICogQHBhcmFtICByZXQgUmV0dXJuIHR5cGUgb2YgbWV0aG9kCi0gICAqIEBwYXJhbSAgYXJndiBUeXBlcyBvZiBtZXRob2QgYXJndW1lbnRzCi0gICAqIEByZXR1cm4gQnl0ZSBjb2RlIHJlcHJlc2VudGF0aW9uIG9mIG1ldGhvZCBzaWduYXR1cmUKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBzdGF0aWMgU3RyaW5nIG1ldGhvZFR5cGVUb1NpZ25hdHVyZShTdHJpbmcgcmV0LCBTdHJpbmdbXSBhcmd2KQotICAgIHRocm93cyBDbGFzc0Zvcm1hdEV4Y2VwdGlvbgotICB7Ci0gICAgU3RyaW5nQnVmZmVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWZmZXIoIigiKTsKLSAgICBTdHJpbmcgICAgICAgc3RyOwotCi0gICAgaWYoYXJndiAhPSBudWxsKQotICAgICAgZm9yKGludCBpPTA7IGkgPCBhcmd2Lmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgIHN0ciA9IGdldFNpZ25hdHVyZShhcmd2W2ldKTsKLQotICAgICAgICBpZihzdHIuZW5kc1dpdGgoIlYiKSkgLy8gdm9pZCBjYW4ndCBiZSBhIG1ldGhvZCBhcmd1bWVudAotICAgICAgICAgIHRocm93IG5ldyBDbGFzc0Zvcm1hdEV4Y2VwdGlvbigiSW52YWxpZCB0eXBlOiAiICsgYXJndltpXSk7Ci0KLSAgICAgICAgYnVmLmFwcGVuZChzdHIpOwotICAgICAgfQotCi0gICAgc3RyID0gZ2V0U2lnbmF0dXJlKHJldCk7Ci0KLSAgICBidWYuYXBwZW5kKCIpIiArIHN0cik7Ci0KLSAgICByZXR1cm4gYnVmLnRvU3RyaW5nKCk7Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtICBzaWduYXR1cmUgICAgTWV0aG9kIHNpZ25hdHVyZQotICAgKiBAcmV0dXJuIEFycmF5IG9mIGFyZ3VtZW50IHR5cGVzCi0gICAqIEB0aHJvd3MgIENsYXNzRm9ybWF0RXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZ1tdIG1ldGhvZFNpZ25hdHVyZUFyZ3VtZW50VHlwZXMoU3RyaW5nIHNpZ25hdHVyZSkKLSAgICB0aHJvd3MgQ2xhc3NGb3JtYXRFeGNlcHRpb24KLSAgewotICAgIHJldHVybiBtZXRob2RTaWduYXR1cmVBcmd1bWVudFR5cGVzKHNpZ25hdHVyZSwgdHJ1ZSk7Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtICBzaWduYXR1cmUgICAgTWV0aG9kIHNpZ25hdHVyZQotICAgKiBAcGFyYW0gY2hvcGl0IFNob3J0ZW4gY2xhc3MgbmFtZXMgPwotICAgKiBAcmV0dXJuIEFycmF5IG9mIGFyZ3VtZW50IHR5cGVzCi0gICAqIEB0aHJvd3MgIENsYXNzRm9ybWF0RXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZ1tdIG1ldGhvZFNpZ25hdHVyZUFyZ3VtZW50VHlwZXMoU3RyaW5nIHNpZ25hdHVyZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gY2hvcGl0KQotICAgIHRocm93cyBDbGFzc0Zvcm1hdEV4Y2VwdGlvbgotICB7Ci0gICAgQXJyYXlMaXN0IHZlYyA9IG5ldyBBcnJheUxpc3QoKTsKLSAgICBpbnQgICAgICAgaW5kZXg7Ci0gICAgU3RyaW5nW10gIHR5cGVzOwotCi0gICAgdHJ5IHsgLy8gUmVhZCBhbGwgZGVjbGFyYXRpb25zIGJldHdlZW4gZm9yIGAoJyBhbmQgYCknCi0gICAgICBpZihzaWduYXR1cmUuY2hhckF0KDApICE9ICcoJykKLSAgICAgICAgdGhyb3cgbmV3IENsYXNzRm9ybWF0RXhjZXB0aW9uKCJJbnZhbGlkIG1ldGhvZCBzaWduYXR1cmU6ICIgKyBzaWduYXR1cmUpOwotCi0gICAgICBpbmRleCA9IDE7IC8vIGN1cnJlbnQgc3RyaW5nIHBvc2l0aW9uCi0KLSAgICAgIHdoaWxlKHNpZ25hdHVyZS5jaGFyQXQoaW5kZXgpICE9ICcpJykgewotICAgICAgICB2ZWMuYWRkKHNpZ25hdHVyZVRvU3RyaW5nKHNpZ25hdHVyZS5zdWJzdHJpbmcoaW5kZXgpLCBjaG9waXQpKTsKLSAgICAgICAgaW5kZXggKz0gY29uc3VtZWRfY2hhcnM7IC8vIHVwZGF0ZSBwb3NpdGlvbgotICAgICAgfQotICAgIH0gY2F0Y2goU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7IC8vIFNob3VsZCBuZXZlciBvY2N1cgotICAgICAgdGhyb3cgbmV3IENsYXNzRm9ybWF0RXhjZXB0aW9uKCJJbnZhbGlkIG1ldGhvZCBzaWduYXR1cmU6ICIgKyBzaWduYXR1cmUpOwotICAgIH0KLQotICAgIHR5cGVzID0gbmV3IFN0cmluZ1t2ZWMuc2l6ZSgpXTsKLSAgICB2ZWMudG9BcnJheSh0eXBlcyk7Ci0gICAgcmV0dXJuIHR5cGVzOwotICB9Ci0gIC8qKgotICAgKiBAcGFyYW0gIHNpZ25hdHVyZSAgICBNZXRob2Qgc2lnbmF0dXJlCi0gICAqIEByZXR1cm4gcmV0dXJuIHR5cGUgb2YgbWV0aG9kCi0gICAqIEB0aHJvd3MgIENsYXNzRm9ybWF0RXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBtZXRob2RTaWduYXR1cmVSZXR1cm5UeXBlKFN0cmluZyBzaWduYXR1cmUpCi0gICAgICAgdGhyb3dzIENsYXNzRm9ybWF0RXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gbWV0aG9kU2lnbmF0dXJlUmV0dXJuVHlwZShzaWduYXR1cmUsIHRydWUpOwotICB9Ci0gIC8qKgotICAgKiBAcGFyYW0gIHNpZ25hdHVyZSAgICBNZXRob2Qgc2lnbmF0dXJlCi0gICAqIEBwYXJhbSBjaG9waXQgU2hvcnRlbiBjbGFzcyBuYW1lcyA/Ci0gICAqIEByZXR1cm4gcmV0dXJuIHR5cGUgb2YgbWV0aG9kCi0gICAqIEB0aHJvd3MgIENsYXNzRm9ybWF0RXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBtZXRob2RTaWduYXR1cmVSZXR1cm5UeXBlKFN0cmluZyBzaWduYXR1cmUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBjaG9waXQpCi0gICAgICAgdGhyb3dzIENsYXNzRm9ybWF0RXhjZXB0aW9uCi0gIHsKLSAgICBpbnQgICAgaW5kZXg7Ci0gICAgU3RyaW5nIHR5cGU7Ci0KLSAgICB0cnkgewotICAgICAgLy8gUmVhZCByZXR1cm4gdHlwZSBhZnRlciBgKScKLSAgICAgIGluZGV4ID0gc2lnbmF0dXJlLmxhc3RJbmRleE9mKCcpJykgKyAxOwotICAgICAgdHlwZSA9IHNpZ25hdHVyZVRvU3RyaW5nKHNpZ25hdHVyZS5zdWJzdHJpbmcoaW5kZXgpLCBjaG9waXQpOwotICAgIH0gY2F0Y2goU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7IC8vIFNob3VsZCBuZXZlciBvY2N1cgotICAgICAgdGhyb3cgbmV3IENsYXNzRm9ybWF0RXhjZXB0aW9uKCJJbnZhbGlkIG1ldGhvZCBzaWduYXR1cmU6ICIgKyBzaWduYXR1cmUpOwotICAgIH0KLQotICAgIHJldHVybiB0eXBlOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbnZlcnRzIG1ldGhvZCBzaWduYXR1cmUgdG8gc3RyaW5nIHdpdGggYWxsIGNsYXNzIG5hbWVzIGNvbXBhY3RlZC4KLSAgICoKLSAgICogQHBhcmFtIHNpZ25hdHVyZSB0byBjb252ZXJ0Ci0gICAqIEBwYXJhbSBuYW1lIG9mIG1ldGhvZAotICAgKiBAcGFyYW0gYWNjZXNzIGZsYWdzIG9mIG1ldGhvZAotICAgKiBAcmV0dXJuIEh1bWFuIHJlYWRhYmxlIHNpZ25hdHVyZQotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgbWV0aG9kU2lnbmF0dXJlVG9TdHJpbmcoU3RyaW5nIHNpZ25hdHVyZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBhY2Nlc3MpIHsKLSAgICByZXR1cm4gbWV0aG9kU2lnbmF0dXJlVG9TdHJpbmcoc2lnbmF0dXJlLCBuYW1lLCBhY2Nlc3MsIHRydWUpOwotICB9Ci0KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgbWV0aG9kU2lnbmF0dXJlVG9TdHJpbmcoU3RyaW5nIHNpZ25hdHVyZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBhY2Nlc3MsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gY2hvcGl0KSB7Ci0gICAgcmV0dXJuIG1ldGhvZFNpZ25hdHVyZVRvU3RyaW5nKHNpZ25hdHVyZSwgbmFtZSwgYWNjZXNzLCBjaG9waXQsIG51bGwpOwotICB9Ci0KLSAgLyoqCi0gICAqIEEgcmV0dXJuIHR5cGUgc2lnbmF0dXJlIHJlcHJlc2VudHMgdGhlIHJldHVybiB2YWx1ZSBmcm9tIGEgbWV0aG9kLgotICAgKiBJdCBpcyBhIHNlcmllcyBvZiBieXRlcyBpbiB0aGUgZm9sbG93aW5nIGdyYW1tYXI6Ci0gICAqCi0gICAqIDxyZXR1cm5fc2lnbmF0dXJlPiA6Oj0gPGZpZWxkX3R5cGU+IHwgVgotICAgKgotICAgKiBUaGUgY2hhcmFjdGVyIFYgaW5kaWNhdGVzIHRoYXQgdGhlIG1ldGhvZCByZXR1cm5zIG5vIHZhbHVlLiBPdGhlcndpc2UsIHRoZQotICAgKiBzaWduYXR1cmUgaW5kaWNhdGVzIHRoZSB0eXBlIG9mIHRoZSByZXR1cm4gdmFsdWUuCi0gICAqIEFuIGFyZ3VtZW50IHNpZ25hdHVyZSByZXByZXNlbnRzIGFuIGFyZ3VtZW50IHBhc3NlZCB0byBhIG1ldGhvZDoKLSAgICoKLSAgICogPGFyZ3VtZW50X3NpZ25hdHVyZT4gOjo9IDxmaWVsZF90eXBlPgotICAgKgotICAgKiBBIG1ldGhvZCBzaWduYXR1cmUgcmVwcmVzZW50cyB0aGUgYXJndW1lbnRzIHRoYXQgdGhlIG1ldGhvZCBleHBlY3RzLCBhbmQKLSAgICogdGhlIHZhbHVlIHRoYXQgaXQgcmV0dXJucy4KLSAgICogPG1ldGhvZF9zaWduYXR1cmU+IDo6PSAoPGFyZ3VtZW50c19zaWduYXR1cmU+KSA8cmV0dXJuX3NpZ25hdHVyZT4KLSAgICogPGFyZ3VtZW50c19zaWduYXR1cmU+Ojo9IDxhcmd1bWVudF9zaWduYXR1cmU+KgotICAgKgotICAgKiBUaGlzIG1ldGhvZCBjb252ZXJ0cyBzdWNoIGEgc3RyaW5nIGludG8gYSBKYXZhIHR5cGUgZGVjbGFyYXRpb24gbGlrZQotICAgKiBgdm9pZCBfbWFpbihTdHJpbmdbXSknIGFuZCB0aHJvd3MgYSBgQ2xhc3NGb3JtYXRFeGNlcHRpb24nIHdoZW4gdGhlIHBhcnNlZAotICAgKiB0eXBlIGlzIGludmFsaWQuCi0gICAqCi0gICAqIEBwYXJhbSAgc2lnbmF0dXJlICAgIE1ldGhvZCBzaWduYXR1cmUKLSAgICogQHBhcmFtICBuYW1lICAgICAgICAgTWV0aG9kIG5hbWUKLSAgICogQHBhcmFtICBhY2Nlc3MgICAgICAgTWV0aG9kIGFjY2VzcyByaWdodHMKLSAgICogQHJldHVybiBKYXZhIHR5cGUgZGVjbGFyYXRpb24KLSAgICogQHRocm93cyAgQ2xhc3NGb3JtYXRFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIG1ldGhvZFNpZ25hdHVyZVRvU3RyaW5nKFN0cmluZyBzaWduYXR1cmUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBuYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgYWNjZXNzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGNob3BpdCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTG9jYWxWYXJpYWJsZVRhYmxlIHZhcnMpCi0gICAgdGhyb3dzIENsYXNzRm9ybWF0RXhjZXB0aW9uCi0gIHsKLSAgICBTdHJpbmdCdWZmZXIgYnVmID0gbmV3IFN0cmluZ0J1ZmZlcigiKCIpOwotICAgIFN0cmluZyAgICAgICB0eXBlOwotICAgIGludCAgICAgICAgICBpbmRleDsKLSAgICBpbnQgICAgICAgICAgdmFyX2luZGV4ID0gKGFjY2Vzcy5pbmRleE9mKCJzdGF0aWMiKSA+PSAwKT8gMCA6IDE7Ci0KLSAgICB0cnkgeyAvLyBSZWFkIGFsbCBkZWNsYXJhdGlvbnMgYmV0d2VlbiBmb3IgYCgnIGFuZCBgKScKLSAgICAgIGlmKHNpZ25hdHVyZS5jaGFyQXQoMCkgIT0gJygnKQotICAgICAgICB0aHJvdyBuZXcgQ2xhc3NGb3JtYXRFeGNlcHRpb24oIkludmFsaWQgbWV0aG9kIHNpZ25hdHVyZTogIiArIHNpZ25hdHVyZSk7Ci0KLSAgICAgIGluZGV4ID0gMTsgLy8gY3VycmVudCBzdHJpbmcgcG9zaXRpb24KLQotICAgICAgd2hpbGUoc2lnbmF0dXJlLmNoYXJBdChpbmRleCkgIT0gJyknKSB7Ci0gICAgICAgIFN0cmluZyBwYXJhbV90eXBlID0gc2lnbmF0dXJlVG9TdHJpbmcoc2lnbmF0dXJlLnN1YnN0cmluZyhpbmRleCksIGNob3BpdCk7Ci0gICAgICAgIGJ1Zi5hcHBlbmQocGFyYW1fdHlwZSk7Ci0KLSAgICAgICAgaWYodmFycyAhPSBudWxsKSB7Ci0gICAgICAgICAgTG9jYWxWYXJpYWJsZSBsID0gdmFycy5nZXRMb2NhbFZhcmlhYmxlKHZhcl9pbmRleCk7Ci0KLSAgICAgICAgICBpZihsICE9IG51bGwpCi0gICAgICAgICAgICBidWYuYXBwZW5kKCIgIiArIGwuZ2V0TmFtZSgpKTsKLSAgICAgICAgfSBlbHNlCi0gICAgICAgICAgYnVmLmFwcGVuZCgiIGFyZyIgKyB2YXJfaW5kZXgpOwotCi0gICAgICAgIGlmKCJkb3VibGUiLmVxdWFscyhwYXJhbV90eXBlKSB8fCAibG9uZyIuZXF1YWxzKHBhcmFtX3R5cGUpKQotICAgICAgICAgIHZhcl9pbmRleCArPSAyOwotICAgICAgICBlbHNlCi0gICAgICAgICAgdmFyX2luZGV4Kys7Ci0KLSAgICAgICAgYnVmLmFwcGVuZCgiLCAiKTsKLSAgICAgICAgaW5kZXggKz0gY29uc3VtZWRfY2hhcnM7IC8vIHVwZGF0ZSBwb3NpdGlvbgotICAgICAgfQotCi0gICAgICBpbmRleCsrOyAvLyB1cGRhdGUgcG9zaXRpb24KLQotICAgICAgLy8gUmVhZCByZXR1cm4gdHlwZSBhZnRlciBgKScKLSAgICAgIHR5cGUgPSBzaWduYXR1cmVUb1N0cmluZyhzaWduYXR1cmUuc3Vic3RyaW5nKGluZGV4KSwgY2hvcGl0KTsKLQotICAgIH0gY2F0Y2goU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7IC8vIFNob3VsZCBuZXZlciBvY2N1cgotICAgICAgdGhyb3cgbmV3IENsYXNzRm9ybWF0RXhjZXB0aW9uKCJJbnZhbGlkIG1ldGhvZCBzaWduYXR1cmU6ICIgKyBzaWduYXR1cmUpOwotICAgIH0KLQotICAgIGlmKGJ1Zi5sZW5ndGgoKSA+IDEpIC8vIFRhY2sgb2ZmIHRoZSBleHRyYSAiLCAiCi0gICAgICBidWYuc2V0TGVuZ3RoKGJ1Zi5sZW5ndGgoKSAtIDIpOwotCi0gICAgYnVmLmFwcGVuZCgiKSIpOwotCi0gICAgcmV0dXJuIGFjY2VzcyArICgoYWNjZXNzLmxlbmd0aCgpID4gMCk/ICIgIiA6ICIiKSArIC8vIE1heSBiZSBhbiBlbXB0eSBzdHJpbmcKLSAgICAgIHR5cGUgKyAiICIgKyBuYW1lICsgYnVmLnRvU3RyaW5nKCk7Ci0gIH0KLQotICAvLyBHdWVzcyB3aGF0IHRoaXMgZG9lcwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgcG93MihpbnQgbikgewotICAgIHJldHVybiAxIDw8IG47Ci0gIH0KLQotICAvKioKLSAgICogUmVwbGFjZSBhbGwgb2NjdXJlbmNlcyBvZiA8ZW0+b2xkPC9lbT4gaW4gPGVtPnN0cjwvZW0+IHdpdGggPGVtPm5ldzwvZW0+LgotICAgKgotICAgKiBAcGFyYW0gc3RyIFN0cmluZyB0byBwZXJtdXRlCi0gICAqIEBwYXJhbSBvbGQgU3RyaW5nIHRvIGJlIHJlcGxhY2VkCi0gICAqIEBwYXJhbSBuZXcgUmVwbGFjZW1lbnQgc3RyaW5nCi0gICAqIEByZXR1cm4gbmV3IFN0cmluZyBvYmplY3QKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIHJlcGxhY2UoU3RyaW5nIHN0ciwgU3RyaW5nIG9sZCwgU3RyaW5nIG5ld18pIHsKLSAgICBpbnQgICAgICAgICAgaW5kZXgsIG9sZF9pbmRleDsKLSAgICBTdHJpbmdCdWZmZXIgYnVmID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotCi0gICAgdHJ5IHsKLSAgICAgIGlmKChpbmRleCA9IHN0ci5pbmRleE9mKG9sZCkpICE9IC0xKSB7IC8vIGBvbGQnIGZvdW5kIGluIHN0cgotICAgICAgICBvbGRfaW5kZXggPSAwOyAgICAgICAgICAgICAgICAgICAgICAgLy8gU3RyaW5nIHN0YXJ0IG9mZnNldAotCi0gICAgICAgIC8vIFdoaWxlIHdlIGhhdmUgc29tZXRoaW5nIHRvIHJlcGxhY2UKLSAgICAgICAgd2hpbGUoKGluZGV4ID0gc3RyLmluZGV4T2Yob2xkLCBvbGRfaW5kZXgpKSAhPSAtMSkgewotICAgICAgICAgIGJ1Zi5hcHBlbmQoc3RyLnN1YnN0cmluZyhvbGRfaW5kZXgsIGluZGV4KSk7IC8vIGFwcGVuZCBwcmVmaXgKLSAgICAgICAgICBidWYuYXBwZW5kKG5ld18pOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBhcHBlbmQgcmVwbGFjZW1lbnQKLQotICAgICAgICAgIG9sZF9pbmRleCA9IGluZGV4ICsgb2xkLmxlbmd0aCgpOyAvLyBTa2lwIGBvbGQnLmxlbmd0aCBjaGFycwotICAgICAgICB9Ci0KLSAgICAgICAgYnVmLmFwcGVuZChzdHIuc3Vic3RyaW5nKG9sZF9pbmRleCkpOyAvLyBhcHBlbmQgcmVzdCBvZiBzdHJpbmcKLSAgICAgICAgc3RyID0gYnVmLnRvU3RyaW5nKCk7Ci0gICAgICB9Ci0gICAgfSBjYXRjaChTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsgLy8gU2hvdWxkIG5vdCBvY2N1cgotICAgICAgU3lzdGVtLmVyci5wcmludGxuKGUpOwotICAgIH0KLQotICAgIHJldHVybiBzdHI7Ci0gIH0KLQotICAvKioKLSAgICogQ29udmVydHMgc2lnbmF0dXJlIHRvIHN0cmluZyB3aXRoIGFsbCBjbGFzcyBuYW1lcyBjb21wYWN0ZWQuCi0gICAqCi0gICAqIEBwYXJhbSBzaWduYXR1cmUgdG8gY29udmVydAotICAgKiBAcmV0dXJuIEh1bWFuIHJlYWRhYmxlIHNpZ25hdHVyZQotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgc2lnbmF0dXJlVG9TdHJpbmcoU3RyaW5nIHNpZ25hdHVyZSkgewotICAgIHJldHVybiBzaWduYXR1cmVUb1N0cmluZyhzaWduYXR1cmUsIHRydWUpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoZSBmaWVsZCBzaWduYXR1cmUgcmVwcmVzZW50cyB0aGUgdmFsdWUgb2YgYW4gYXJndW1lbnQgdG8gYSBmdW5jdGlvbiBvcgotICAgKiB0aGUgdmFsdWUgb2YgYSB2YXJpYWJsZS4gSXQgaXMgYSBzZXJpZXMgb2YgYnl0ZXMgZ2VuZXJhdGVkIGJ5IHRoZQotICAgKiBmb2xsb3dpbmcgZ3JhbW1hcjoKLSAgICoKLSAgICogPFBSRT4KLSAgICogPGZpZWxkX3NpZ25hdHVyZT4gOjo9IDxmaWVsZF90eXBlPgotICAgKiA8ZmllbGRfdHlwZT4gICAgICA6Oj0gPGJhc2VfdHlwZT58PG9iamVjdF90eXBlPnw8YXJyYXlfdHlwZT4KLSAgICogPGJhc2VfdHlwZT4gICAgICAgOjo9IEJ8Q3xEfEZ8SXxKfFN8WgotICAgKiA8b2JqZWN0X3R5cGU+ICAgICA6Oj0gTDxmdWxsY2xhc3NuYW1lPjsKLSAgICogPGFycmF5X3R5cGU+ICAgICAgOjo9IFs8ZmllbGRfdHlwZT4KLSAgICoKLSAgICogVGhlIG1lYW5pbmcgb2YgdGhlIGJhc2UgdHlwZXMgaXMgYXMgZm9sbG93czoKLSAgICogQiBieXRlIHNpZ25lZCBieXRlCi0gICAqIEMgY2hhciBjaGFyYWN0ZXIKLSAgICogRCBkb3VibGUgZG91YmxlIHByZWNpc2lvbiBJRUVFIGZsb2F0Ci0gICAqIEYgZmxvYXQgc2luZ2xlIHByZWNpc2lvbiBJRUVFIGZsb2F0Ci0gICAqIEkgaW50IGludGVnZXIKLSAgICogSiBsb25nIGxvbmcgaW50ZWdlcgotICAgKiBMPGZ1bGxjbGFzc25hbWU+OyAuLi4gYW4gb2JqZWN0IG9mIHRoZSBnaXZlbiBjbGFzcwotICAgKiBTIHNob3J0IHNpZ25lZCBzaG9ydAotICAgKiBaIGJvb2xlYW4gdHJ1ZSBvciBmYWxzZQotICAgKiBbPGZpZWxkIHNpZz4gLi4uIGFycmF5Ci0gICAqIDwvUFJFPgotICAgKgotICAgKiBUaGlzIG1ldGhvZCBjb252ZXJ0cyB0aGlzIHN0cmluZyBpbnRvIGEgSmF2YSB0eXBlIGRlY2xhcmF0aW9uIHN1Y2ggYXMKLSAgICogYFN0cmluZ1tdJyBhbmQgdGhyb3dzIGEgYENsYXNzRm9ybWF0RXhjZXB0aW9uJyB3aGVuIHRoZSBwYXJzZWQgdHlwZSBpcwotICAgKiBpbnZhbGlkLgotICAgKgotICAgKiBAcGFyYW0gIHNpZ25hdHVyZSAgQ2xhc3Mgc2lnbmF0dXJlCi0gICAqIEBwYXJhbSBjaG9waXQgRmxhZyB0aGF0IGRldGVybWluZXMgd2hldGhlciBjaG9wcGluZyBpcyBleGVjdXRlZCBvciBub3QKLSAgICogQHJldHVybiBKYXZhIHR5cGUgZGVjbGFyYXRpb24KLSAgICogQHRocm93cyBDbGFzc0Zvcm1hdEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgc2lnbmF0dXJlVG9TdHJpbmcoU3RyaW5nIHNpZ25hdHVyZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBjaG9waXQpCi0gIHsKLSAgICBjb25zdW1lZF9jaGFycyA9IDE7IC8vIFRoaXMgaXMgdGhlIGRlZmF1bHQsIHJlYWQganVzdCBvbmUgY2hhciBsaWtlIGBCJwotCi0gICAgdHJ5IHsKLSAgICAgIHN3aXRjaChzaWduYXR1cmUuY2hhckF0KDApKSB7Ci0gICAgICBjYXNlICdCJyA6IHJldHVybiAiYnl0ZSI7Ci0gICAgICBjYXNlICdDJyA6IHJldHVybiAiY2hhciI7Ci0gICAgICBjYXNlICdEJyA6IHJldHVybiAiZG91YmxlIjsKLSAgICAgIGNhc2UgJ0YnIDogcmV0dXJuICJmbG9hdCI7Ci0gICAgICBjYXNlICdJJyA6IHJldHVybiAiaW50IjsKLSAgICAgIGNhc2UgJ0onIDogcmV0dXJuICJsb25nIjsKLQotICAgICAgY2FzZSAnTCcgOiB7IC8vIEZ1bGwgY2xhc3MgbmFtZQotICAgICAgICBpbnQgICAgaW5kZXggPSBzaWduYXR1cmUuaW5kZXhPZignOycpOyAvLyBMb29rIGZvciBjbG9zaW5nIGA7JwotCi0gICAgICAgIGlmKGluZGV4IDwgMCkKLSAgICAgICAgICB0aHJvdyBuZXcgQ2xhc3NGb3JtYXRFeGNlcHRpb24oIkludmFsaWQgc2lnbmF0dXJlOiAiICsgc2lnbmF0dXJlKTsKLQotICAgICAgICBjb25zdW1lZF9jaGFycyA9IGluZGV4ICsgMTsgLy8gIkxibGFibGE7IiBgTCcgYW5kIGA7JyBhcmUgcmVtb3ZlZAotCi0gICAgICAgIHJldHVybiBjb21wYWN0Q2xhc3NOYW1lKHNpZ25hdHVyZS5zdWJzdHJpbmcoMSwgaW5kZXgpLCBjaG9waXQpOwotICAgICAgfQotCi0gICAgICBjYXNlICdTJyA6IHJldHVybiAic2hvcnQiOwotICAgICAgY2FzZSAnWicgOiByZXR1cm4gImJvb2xlYW4iOwotCi0gICAgICBjYXNlICdbJyA6IHsgLy8gQXJyYXkgZGVjbGFyYXRpb24KLSAgICAgICAgaW50ICAgICAgICAgIG47Ci0gICAgICAgIFN0cmluZ0J1ZmZlciBidWYsIGJyYWNrZXRzOwotICAgICAgICBTdHJpbmcgICAgICAgdHlwZTsKLSAgICAgICAgY2hhciAgICAgICAgIGNoOwotICAgICAgICBpbnQgICAgICAgICAgY29uc3VtZWRfY2hhcnM7IC8vIFNoYWRvd3MgZ2xvYmFsIHZhcgotCi0gICAgICAgIGJyYWNrZXRzID0gbmV3IFN0cmluZ0J1ZmZlcigpOyAvLyBBY2N1bXVsYXRlIFtdJ3MKLQotICAgICAgICAvLyBDb3VudCBvcGVuaW5nIGJyYWNrZXRzIGFuZCBsb29rIGZvciBvcHRpb25hbCBzaXplIGFyZ3VtZW50Ci0gICAgICAgIGZvcihuPTA7IHNpZ25hdHVyZS5jaGFyQXQobikgPT0gJ1snOyBuKyspCi0gICAgICAgICAgYnJhY2tldHMuYXBwZW5kKCJbXSIpOwotCi0gICAgICAgIGNvbnN1bWVkX2NoYXJzID0gbjsgLy8gUmVtZW1iZXIgdmFsdWUKLQotICAgICAgICAvLyBUaGUgcmVzdCBvZiB0aGUgc3RyaW5nIGRlbm90ZXMgYSBgPGZpZWxkX3R5cGU+JwotICAgICAgICB0eXBlID0gc2lnbmF0dXJlVG9TdHJpbmcoc2lnbmF0dXJlLnN1YnN0cmluZyhuKSwgY2hvcGl0KTsKLQotICAgICAgICBVdGlsaXR5LmNvbnN1bWVkX2NoYXJzICs9IGNvbnN1bWVkX2NoYXJzOwotICAgICAgICByZXR1cm4gdHlwZSArIGJyYWNrZXRzLnRvU3RyaW5nKCk7Ci0gICAgICB9Ci0KLSAgICAgIGNhc2UgJ1YnIDogcmV0dXJuICJ2b2lkIjsKLQotICAgICAgZGVmYXVsdCAgOiB0aHJvdyBuZXcgQ2xhc3NGb3JtYXRFeGNlcHRpb24oIkludmFsaWQgc2lnbmF0dXJlOiBgIiArCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpZ25hdHVyZSArICInIik7Ci0gICAgICB9Ci0gICAgfSBjYXRjaChTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsgLy8gU2hvdWxkIG5ldmVyIG9jY3VyCi0gICAgICB0aHJvdyBuZXcgQ2xhc3NGb3JtYXRFeGNlcHRpb24oIkludmFsaWQgc2lnbmF0dXJlOiAiICsgZSArICI6IiArIHNpZ25hdHVyZSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqIFBhcnNlIEphdmEgdHlwZSBzdWNoIGFzICJjaGFyIiwgb3IgImphdmEubGFuZy5TdHJpbmdbXSIgYW5kIHJldHVybiB0aGUKLSAgICogc2lnbmF0dXJlIGluIGJ5dGUgY29kZSBmb3JtYXQsIGUuZy4gIkMiIG9yICJbTGphdmEvbGFuZy9TdHJpbmc7IiByZXNwZWN0aXZlbHkuCi0gICAqCi0gICAqIEBwYXJhbSAgdHlwZSBKYXZhIHR5cGUKLSAgICogQHJldHVybiBieXRlIGNvZGUgc2lnbmF0dXJlCi0gICAqLwotICBwdWJsaWMgc3RhdGljIFN0cmluZyBnZXRTaWduYXR1cmUoU3RyaW5nIHR5cGUpIHsKLSAgICBTdHJpbmdCdWZmZXIgYnVmICAgICAgICA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLSAgICBjaGFyW10gICAgICAgY2hhcnMgICAgICA9IHR5cGUudG9DaGFyQXJyYXkoKTsKLSAgICBib29sZWFuICAgICAgY2hhcl9mb3VuZCA9IGZhbHNlLCBkZWxpbSA9IGZhbHNlOwotICAgIGludCAgICAgICAgICBpbmRleCAgICAgID0gLTE7Ci0KLSAgbG9vcDoKLSAgICBmb3IoaW50IGk9MDsgaSA8IGNoYXJzLmxlbmd0aDsgaSsrKSB7Ci0gICAgICBzd2l0Y2goY2hhcnNbaV0pIHsKLSAgICAgIGNhc2UgJyAnOiBjYXNlICdcdCc6IGNhc2UgJ1xuJzogY2FzZSAnXHInOiBjYXNlICdcZic6Ci0gICAgICAgIGlmKGNoYXJfZm91bmQpCi0gICAgICAgICAgZGVsaW0gPSB0cnVlOwotICAgICAgICBicmVhazsKLQotICAgICAgY2FzZSAnWyc6Ci0gICAgICAgIGlmKCFjaGFyX2ZvdW5kKQotICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJJbGxlZ2FsIHR5cGU6ICIgKyB0eXBlKTsKLQotICAgICAgICBpbmRleCA9IGk7Ci0gICAgICAgIGJyZWFrIGxvb3A7Ci0KLSAgICAgIGRlZmF1bHQ6Ci0gICAgICAgIGNoYXJfZm91bmQgPSB0cnVlOwotICAgICAgICBpZighZGVsaW0pCi0gICAgICAgICAgYnVmLmFwcGVuZChjaGFyc1tpXSk7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgaW50IGJyYWNrZXRzID0gMDsKLQotICAgIGlmKGluZGV4ID4gMCkKLSAgICAgIGJyYWNrZXRzID0gY291bnRCcmFja2V0cyh0eXBlLnN1YnN0cmluZyhpbmRleCkpOwotCi0gICAgdHlwZSA9IGJ1Zi50b1N0cmluZygpOwotICAgIGJ1Zi5zZXRMZW5ndGgoMCk7Ci0KLSAgICBmb3IoaW50IGk9MDsgaSA8IGJyYWNrZXRzOyBpKyspCi0gICAgICBidWYuYXBwZW5kKCdbJyk7Ci0KLSAgICBib29sZWFuIGZvdW5kID0gZmFsc2U7Ci0KLSAgICBmb3IoaW50IGk9Q29uc3RhbnRzLlRfQk9PTEVBTjsgKGkgPD0gQ29uc3RhbnRzLlRfVk9JRCkgJiYgIWZvdW5kOyBpKyspIHsKLSAgICAgIGlmKENvbnN0YW50cy5UWVBFX05BTUVTW2ldLmVxdWFscyh0eXBlKSkgewotICAgICAgICBmb3VuZCA9IHRydWU7Ci0gICAgICAgIGJ1Zi5hcHBlbmQoQ29uc3RhbnRzLlNIT1JUX1RZUEVfTkFNRVNbaV0pOwotICAgICAgfQotICAgIH0KLQotICAgIGlmKCFmb3VuZCkgLy8gQ2xhc3MgbmFtZQotICAgICAgYnVmLmFwcGVuZCgnTCcgKyB0eXBlLnJlcGxhY2UoJy4nLCAnLycpICsgJzsnKTsKLQotICAgIHJldHVybiBidWYudG9TdHJpbmcoKTsKLSAgfQotCi0gIHByaXZhdGUgc3RhdGljIGludCBjb3VudEJyYWNrZXRzKFN0cmluZyBicmFja2V0cykgewotICAgIGNoYXJbXSAgY2hhcnMgPSBicmFja2V0cy50b0NoYXJBcnJheSgpOwotICAgIGludCAgICAgY291bnQgPSAwOwotICAgIGJvb2xlYW4gb3BlbiAgPSBmYWxzZTsKLQotICAgIGZvcihpbnQgaT0wOyBpPGNoYXJzLmxlbmd0aDsgaSsrKSB7Ci0gICAgICBzd2l0Y2goY2hhcnNbaV0pIHsKLSAgICAgIGNhc2UgJ1snOgotICAgICAgICBpZihvcGVuKQotICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJJbGxlZ2FsbHkgbmVzdGVkIGJyYWNrZXRzOiIgKyBicmFja2V0cyk7Ci0gICAgICAgIG9wZW4gPSB0cnVlOwotICAgICAgICBicmVhazsKLQotICAgICAgY2FzZSAnXSc6Ci0gICAgICAgIGlmKCFvcGVuKQotICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJJbGxlZ2FsbHkgbmVzdGVkIGJyYWNrZXRzOiIgKyBicmFja2V0cyk7Ci0gICAgICAgIG9wZW4gPSBmYWxzZTsKLSAgICAgICAgY291bnQrKzsKLSAgICAgICAgYnJlYWs7Ci0KLSAgICAgIGRlZmF1bHQ6Ci0gICAgICAgIC8vIERvbid0IGNhcmUKLSAgICAgIH0KLSAgICB9Ci0KLSAgICBpZihvcGVuKQotICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIklsbGVnYWxseSBuZXN0ZWQgYnJhY2tldHM6IiArIGJyYWNrZXRzKTsKLQotICAgIHJldHVybiBjb3VudDsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdHlwZSBvZiBtZXRob2Qgc2lnbmF0dXJlIGFzIGEgYnl0ZSB2YWx1ZSBhcyBkZWZpbmVkIGluIDxlbT5Db25zdGFudHM8L2VtPgotICAgKgotICAgKiBAcGFyYW0gIHNpZ25hdHVyZSBpbiBmb3JtYXQgZGVzY3JpYmVkIGFib3ZlCi0gICAqIEByZXR1cm4gdHlwZSBvZiBtZXRob2Qgc2lnbmF0dXJlCi0gICAqIEBzZWUgICAgQ29uc3RhbnRzCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgdHlwZU9mTWV0aG9kU2lnbmF0dXJlKFN0cmluZyBzaWduYXR1cmUpCi0gICAgdGhyb3dzIENsYXNzRm9ybWF0RXhjZXB0aW9uCi0gIHsKLSAgICBpbnQgaW5kZXg7Ci0KLSAgICB0cnkgewotICAgICAgaWYoc2lnbmF0dXJlLmNoYXJBdCgwKSAhPSAnKCcpCi0gICAgICAgIHRocm93IG5ldyBDbGFzc0Zvcm1hdEV4Y2VwdGlvbigiSW52YWxpZCBtZXRob2Qgc2lnbmF0dXJlOiAiICsgc2lnbmF0dXJlKTsKLQotICAgICAgaW5kZXggPSBzaWduYXR1cmUubGFzdEluZGV4T2YoJyknKSArIDE7Ci0gICAgICByZXR1cm4gdHlwZU9mU2lnbmF0dXJlKHNpZ25hdHVyZS5zdWJzdHJpbmcoaW5kZXgpKTsKLSAgICB9IGNhdGNoKFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgewotICAgICAgdGhyb3cgbmV3IENsYXNzRm9ybWF0RXhjZXB0aW9uKCJJbnZhbGlkIG1ldGhvZCBzaWduYXR1cmU6ICIgKyBzaWduYXR1cmUpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdHlwZSBvZiBzaWduYXR1cmUgYXMgYSBieXRlIHZhbHVlIGFzIGRlZmluZWQgaW4gPGVtPkNvbnN0YW50czwvZW0+Ci0gICAqCi0gICAqIEBwYXJhbSAgc2lnbmF0dXJlIGluIGZvcm1hdCBkZXNjcmliZWQgYWJvdmUKLSAgICogQHJldHVybiB0eXBlIG9mIHNpZ25hdHVyZQotICAgKiBAc2VlICAgIENvbnN0YW50cwotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBieXRlIHR5cGVPZlNpZ25hdHVyZShTdHJpbmcgc2lnbmF0dXJlKQotICAgIHRocm93cyBDbGFzc0Zvcm1hdEV4Y2VwdGlvbgotICB7Ci0gICAgdHJ5IHsKLSAgICAgIHN3aXRjaChzaWduYXR1cmUuY2hhckF0KDApKSB7Ci0gICAgICBjYXNlICdCJyA6IHJldHVybiBDb25zdGFudHMuVF9CWVRFOwotICAgICAgY2FzZSAnQycgOiByZXR1cm4gQ29uc3RhbnRzLlRfQ0hBUjsKLSAgICAgIGNhc2UgJ0QnIDogcmV0dXJuIENvbnN0YW50cy5UX0RPVUJMRTsKLSAgICAgIGNhc2UgJ0YnIDogcmV0dXJuIENvbnN0YW50cy5UX0ZMT0FUOwotICAgICAgY2FzZSAnSScgOiByZXR1cm4gQ29uc3RhbnRzLlRfSU5UOwotICAgICAgY2FzZSAnSicgOiByZXR1cm4gQ29uc3RhbnRzLlRfTE9ORzsKLSAgICAgIGNhc2UgJ0wnIDogcmV0dXJuIENvbnN0YW50cy5UX1JFRkVSRU5DRTsKLSAgICAgIGNhc2UgJ1snIDogcmV0dXJuIENvbnN0YW50cy5UX0FSUkFZOwotICAgICAgY2FzZSAnVicgOiByZXR1cm4gQ29uc3RhbnRzLlRfVk9JRDsKLSAgICAgIGNhc2UgJ1onIDogcmV0dXJuIENvbnN0YW50cy5UX0JPT0xFQU47Ci0gICAgICBjYXNlICdTJyA6IHJldHVybiBDb25zdGFudHMuVF9TSE9SVDsKLSAgICAgIGRlZmF1bHQ6Ci0gICAgICAgIHRocm93IG5ldyBDbGFzc0Zvcm1hdEV4Y2VwdGlvbigiSW52YWxpZCBtZXRob2Qgc2lnbmF0dXJlOiAiICsgc2lnbmF0dXJlKTsKLSAgICAgIH0KLSAgICB9IGNhdGNoKFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgewotICAgICAgdGhyb3cgbmV3IENsYXNzRm9ybWF0RXhjZXB0aW9uKCJJbnZhbGlkIG1ldGhvZCBzaWduYXR1cmU6ICIgKyBzaWduYXR1cmUpOwotICAgIH0KLSAgfQotCi0gIC8qKiBNYXAgb3Bjb2RlIG5hbWVzIHRvIG9wY29kZSBudW1iZXJzLiBFLmcuLCByZXR1cm4gQ29uc3RhbnRzLkFMT0FEIGZvciAiYWxvYWQiCi0gICAqLwotICBwdWJsaWMgc3RhdGljIHNob3J0IHNlYXJjaE9wY29kZShTdHJpbmcgbmFtZSkgewotICAgIG5hbWUgPSBuYW1lLnRvTG93ZXJDYXNlKCk7Ci0KLSAgICBmb3Ioc2hvcnQgaT0wOyBpIDwgQ29uc3RhbnRzLk9QQ09ERV9OQU1FUy5sZW5ndGg7IGkrKykKLSAgICAgIGlmKENvbnN0YW50cy5PUENPREVfTkFNRVNbaV0uZXF1YWxzKG5hbWUpKQotICAgICAgICByZXR1cm4gaTsKLQotICAgIHJldHVybiAtMTsKLSAgfQotCi0gIC8qKgotICAgKiBDb252ZXJ0IChzaWduZWQpIGJ5dGUgdG8gKHVuc2lnbmVkKSBzaG9ydCB2YWx1ZSwgaS5lLiwgYWxsIG5lZ2F0aXZlCi0gICAqIHZhbHVlcyBiZWNvbWUgcG9zaXRpdmUuCi0gICAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBzaG9ydCBieXRlVG9TaG9ydChieXRlIGIpIHsKLSAgICByZXR1cm4gKGIgPCAwKT8gKHNob3J0KSgyNTYgKyBiKSA6IChzaG9ydCliOwotICB9Ci0KLSAgLyoqIENvbnZlcnQgYnl0ZXMgaW50byBoZXhpZGVjaW1hbCBzdHJpbmcKLSAgICoKLSAgICogQHJldHVybiBieXRlcyBhcyBoZXhpZGVjaW1hbCBzdHJpbmcsIGUuZy4gMDAgRkEgMTIgLi4uCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyB0b0hleFN0cmluZyhieXRlW10gYnl0ZXMpIHsKLSAgICBTdHJpbmdCdWZmZXIgYnVmID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotCi0gICAgZm9yKGludCBpPTA7IGkgPCBieXRlcy5sZW5ndGg7IGkrKykgewotICAgICAgc2hvcnQgIGIgICA9IGJ5dGVUb1Nob3J0KGJ5dGVzW2ldKTsKLSAgICAgIFN0cmluZyBoZXggPSBJbnRlZ2VyLnRvU3RyaW5nKGIsIDB4MTApOwotCi0gICAgICBpZihiIDwgMHgxMCkgLy8ganVzdCBvbmUgZGlnaXQsIHByZXBlbmQgJzAnCi0gICAgICAgIGJ1Zi5hcHBlbmQoJzAnKTsKLQotICAgICAgYnVmLmFwcGVuZChoZXgpOwotCi0gICAgICBpZihpIDwgYnl0ZXMubGVuZ3RoIC0gMSkKLSAgICAgICAgYnVmLmFwcGVuZCgnICcpOwotICAgIH0KLQotICAgIHJldHVybiBidWYudG9TdHJpbmcoKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gYSBzdHJpbmcgZm9yIGFuIGludGVnZXIganVzdGlmaWVkIGxlZnQgb3IgcmlnaHQgYW5kIGZpbGxlZCB1cCB3aXRoCi0gICAqIGBmaWxsJyBjaGFyYWN0ZXJzIGlmIG5lY2Vzc2FyeS4KLSAgICoKLSAgICogQHBhcmFtIGkgaW50ZWdlciB0byBmb3JtYXQKLSAgICogQHBhcmFtIGxlbmd0aCBsZW5ndGggb2YgZGVzaXJlZCBzdHJpbmcKLSAgICogQHBhcmFtIGxlZnRfanVzdGlmeSBmb3JtYXQgbGVmdCBvciByaWdodAotICAgKiBAcGFyYW0gZmlsbCBmaWxsIGNoYXJhY3RlcgotICAgKiBAcmV0dXJuIGZvcm1hdHRlZCBpbnQKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIGZvcm1hdChpbnQgaSwgaW50IGxlbmd0aCwgYm9vbGVhbiBsZWZ0X2p1c3RpZnksIGNoYXIgZmlsbCkgewotICAgIHJldHVybiBmaWxsdXAoSW50ZWdlci50b1N0cmluZyhpKSwgbGVuZ3RoLCBsZWZ0X2p1c3RpZnksIGZpbGwpOwotICB9Ci0KLSAgLyoqCi0gICAqIEZpbGx1cCBjaGFyIHdpdGggdXAgdG8gbGVuZ3RoIGNoYXJhY3RlcnMgd2l0aCBjaGFyIGBmaWxsJyBhbmQganVzdGlmeSBpdCBsZWZ0IG9yIHJpZ2h0LgotICAgKgotICAgKiBAcGFyYW0gc3RyIHN0cmluZyB0byBmb3JtYXQKLSAgICogQHBhcmFtIGxlbmd0aCBsZW5ndGggb2YgZGVzaXJlZCBzdHJpbmcKLSAgICogQHBhcmFtIGxlZnRfanVzdGlmeSBmb3JtYXQgbGVmdCBvciByaWdodAotICAgKiBAcGFyYW0gZmlsbCBmaWxsIGNoYXJhY3RlcgotICAgKiBAcmV0dXJuIGZvcm1hdHRlZCBzdHJpbmcKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIGZpbGx1cChTdHJpbmcgc3RyLCBpbnQgbGVuZ3RoLCBib29sZWFuIGxlZnRfanVzdGlmeSwgY2hhciBmaWxsKSB7Ci0gICAgaW50ICAgIGxlbiA9IGxlbmd0aCAtIHN0ci5sZW5ndGgoKTsKLSAgICBjaGFyW10gYnVmID0gbmV3IGNoYXJbKGxlbiA8IDApPyAwIDogbGVuXTsKLQotICAgIGZvcihpbnQgaj0wOyBqIDwgYnVmLmxlbmd0aDsgaisrKQotICAgICAgYnVmW2pdID0gZmlsbDsKLQotICAgIGlmKGxlZnRfanVzdGlmeSkKLSAgICAgIHJldHVybiBzdHIgKyBuZXcgU3RyaW5nKGJ1Zik7Ci0gICAgZWxzZQotICAgICAgcmV0dXJuIG5ldyBTdHJpbmcoYnVmKSArIHN0cjsKLSAgfQotCi0gIHN0YXRpYyBmaW5hbCBib29sZWFuIGVxdWFscyhieXRlW10gYSwgYnl0ZVtdIGIpIHsKLSAgICBpbnQgc2l6ZTsKLQotICAgIGlmKChzaXplPWEubGVuZ3RoKSAhPSBiLmxlbmd0aCkKLSAgICAgIHJldHVybiBmYWxzZTsKLQotICAgIGZvcihpbnQgaT0wOyBpIDwgc2l6ZTsgaSsrKQotICAgICAgaWYoYVtpXSAhPSBiW2ldKQotICAgICAgICByZXR1cm4gZmFsc2U7Ci0KLSAgICByZXR1cm4gdHJ1ZTsKLSAgfQotCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgdm9pZCBwcmludEFycmF5KFByaW50U3RyZWFtIG91dCwgT2JqZWN0W10gb2JqKSB7Ci0gICAgb3V0LnByaW50bG4ocHJpbnRBcnJheShvYmosIHRydWUpKTsKLSAgfQotCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgdm9pZCBwcmludEFycmF5KFByaW50V3JpdGVyIG91dCwgT2JqZWN0W10gb2JqKSB7Ci0gICAgb3V0LnByaW50bG4ocHJpbnRBcnJheShvYmosIHRydWUpKTsKLSAgfQotCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIHByaW50QXJyYXkoT2JqZWN0W10gb2JqKSB7Ci0gICAgcmV0dXJuIHByaW50QXJyYXkob2JqLCB0cnVlKTsKLSAgfQotCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIHByaW50QXJyYXkoT2JqZWN0W10gb2JqLCBib29sZWFuIGJyYWNlcykgewotICAgIHJldHVybiBwcmludEFycmF5KG9iaiwgYnJhY2VzLCBmYWxzZSk7Ci0gIH0KLQotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBwcmludEFycmF5KE9iamVjdFtdIG9iaiwgYm9vbGVhbiBicmFjZXMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBxdW90ZSkgewotICAgIGlmKG9iaiA9PSBudWxsKQotICAgICAgcmV0dXJuIG51bGw7Ci0KLSAgICBTdHJpbmdCdWZmZXIgYnVmID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotICAgIGlmKGJyYWNlcykKLSAgICAgIGJ1Zi5hcHBlbmQoJ3snKTsKLQotICAgIGZvcihpbnQgaT0wOyBpIDwgb2JqLmxlbmd0aDsgaSsrKSB7Ci0gICAgICBpZihvYmpbaV0gIT0gbnVsbCkgewotICAgICAgICBidWYuYXBwZW5kKChxdW90ZT8gIlwiIiA6ICIiKSArIG9ialtpXS50b1N0cmluZygpICsgKHF1b3RlPyAiXCIiIDogIiIpKTsKLSAgICAgIH0gZWxzZSB7Ci0gICAgICAgIGJ1Zi5hcHBlbmQoIm51bGwiKTsKLSAgICAgIH0KLQotICAgICAgaWYoaSA8IG9iai5sZW5ndGggLSAxKSB7Ci0gICAgICAgIGJ1Zi5hcHBlbmQoIiwgIik7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgaWYoYnJhY2VzKQotICAgICAgYnVmLmFwcGVuZCgnfScpOwotCi0gICAgcmV0dXJuIGJ1Zi50b1N0cmluZygpOwotICB9Ci0KLSAgLyoqIEByZXR1cm4gdHJ1ZSwgaWYgY2hhcmFjdGVyIGlzIG9uZSBvZiAoYSwgLi4uIHosIEEsIC4uLiBaLCAwLCAuLi4gOSwgXykKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0phdmFJZGVudGlmaWVyUGFydChjaGFyIGNoKSB7Ci0gICAgcmV0dXJuICgoY2ggPj0gJ2EnKSAmJiAoY2ggPD0gJ3onKSkgfHwKLSAgICAgICgoY2ggPj0gJ0EnKSAmJiAoY2ggPD0gJ1onKSkgfHwKLSAgICAgICgoY2ggPj0gJzAnKSAmJiAoY2ggPD0gJzknKSkgfHwKLSAgICAgIChjaCA9PSAnXycpOwotICB9Ci0KLSAgLyoqIEVuY29kZSBieXRlIGFycmF5IGl0IGludG8gSmF2YSBpZGVudGlmaWVyIHN0cmluZywgaS5lLiwgYSBzdHJpbmcKLSAgICogdGhhdCBvbmx5IGNvbnRhaW5zIHRoZSBmb2xsb3dpbmcgY2hhcmFjdGVyczogKGEsIC4uLiB6LCBBLCAuLi4gWiwKLSAgICogMCwgLi4uIDksIF8sICQpLiAgVGhlIGVuY29kaW5nIGFsZ29yaXRobSBpdHNlbGYgaXMgbm90IHRvbwotICAgKiBjbGV2ZXI6IGlmIHRoZSBjdXJyZW50IGJ5dGUncyBBU0NJSSB2YWx1ZSBhbHJlYWR5IGlzIGEgdmFsaWQgSmF2YQotICAgKiBpZGVudGlmaWVyIHBhcnQsIGxlYXZlIGl0IGFzIGl0IGlzLiBPdGhlcndpc2UgaXQgd3JpdGVzIHRoZQotICAgKiBlc2NhcGUgY2hhcmFjdGVyKCQpIGZvbGxvd2VkIGJ5IDxwPjx1bD48bGk+IHRoZSBBU0NJSSB2YWx1ZSBhcyBhCi0gICAqIGhleGFkZWNpbWFsIHN0cmluZywgaWYgdGhlIHZhbHVlIGlzIG5vdCBpbiB0aGUgcmFuZ2UKLSAgICogMjAwLi4yNDc8L2xpPiA8bGk+YSBKYXZhIGlkZW50aWZpZXIgY2hhciBub3QgdXNlZCBpbiBhIGxvd2VyY2FzZQotICAgKiBoZXhhZGVjaW1hbCBzdHJpbmcsIGlmIHRoZSB2YWx1ZSBpcyBpbiB0aGUgcmFuZ2UKLSAgICogMjAwLi4yNDc8L2xpPjx1bD48L3A+Ci0gICAqCi0gICAqIDxwPlRoaXMgb3BlcmF0aW9uIGluZmxhdGVzIHRoZSBvcmlnaW5hbCBieXRlIGFycmF5IGJ5IHJvdWdobHkgNDAtNTAlPC9wPgotICAgKgotICAgKiBAcGFyYW0gYnl0ZXMgdGhlIGJ5dGUgYXJyYXkgdG8gY29udmVydAotICAgKiBAcGFyYW0gY29tcHJlc3MgdXNlIGd6aXAgdG8gbWluaW1pemUgc3RyaW5nCi0gICAqLwotICBwdWJsaWMgc3RhdGljIFN0cmluZyBlbmNvZGUoYnl0ZVtdIGJ5dGVzLCBib29sZWFuIGNvbXByZXNzKSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgIGlmKGNvbXByZXNzKSB7Ci0gICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYmFvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKLSAgICAgIEdaSVBPdXRwdXRTdHJlYW0gICAgICBnb3MgID0gbmV3IEdaSVBPdXRwdXRTdHJlYW0oYmFvcyk7Ci0KLSAgICAgIGdvcy53cml0ZShieXRlcywgMCwgYnl0ZXMubGVuZ3RoKTsKLSAgICAgIGdvcy5jbG9zZSgpOwotICAgICAgYmFvcy5jbG9zZSgpOwotCi0gICAgICBieXRlcyA9IGJhb3MudG9CeXRlQXJyYXkoKTsKLSAgICB9Ci0KLSAgICBDaGFyQXJyYXlXcml0ZXIgY2F3ID0gbmV3IENoYXJBcnJheVdyaXRlcigpOwotICAgIEphdmFXcml0ZXIgICAgICBqdyAgPSBuZXcgSmF2YVdyaXRlcihjYXcpOwotCi0gICAgZm9yKGludCBpPTA7IGkgPCBieXRlcy5sZW5ndGg7IGkrKykgewotICAgICAgaW50IGluID0gYnl0ZXNbaV0gJiAweDAwMDAwMGZmOyAvLyBOb3JtYWxpemUgdG8gdW5zaWduZWQKLSAgICAgIGp3LndyaXRlKGluKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gY2F3LnRvU3RyaW5nKCk7Ci0gIH0KLQotICAvKiogRGVjb2RlIGEgc3RyaW5nIGJhY2sgdG8gYSBieXRlIGFycmF5LgotICAgKgotICAgKiBAcGFyYW0gYnl0ZXMgdGhlIGJ5dGUgYXJyYXkgdG8gY29udmVydAotICAgKiBAcGFyYW0gdW5jb21wcmVzcyB1c2UgZ3ppcCB0byB1bmNvbXByZXNzIHRoZSBzdHJlYW0gb2YgYnl0ZXMKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgYnl0ZVtdIGRlY29kZShTdHJpbmcgcywgYm9vbGVhbiB1bmNvbXByZXNzKSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgIGNoYXJbXSBjaGFycyA9IHMudG9DaGFyQXJyYXkoKTsKLQotICAgIENoYXJBcnJheVJlYWRlciBjYXIgPSBuZXcgQ2hhckFycmF5UmVhZGVyKGNoYXJzKTsKLSAgICBKYXZhUmVhZGVyICAgICAganIgID0gbmV3IEphdmFSZWFkZXIoY2FyKTsKLQotICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBib3MgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7Ci0KLSAgICBpbnQgY2g7Ci0KLSAgICB3aGlsZSgoY2ggPSBqci5yZWFkKCkpID49IDApIHsKLSAgICAgIGJvcy53cml0ZShjaCk7Ci0gICAgfQotCi0gICAgYm9zLmNsb3NlKCk7Ci0gICAgY2FyLmNsb3NlKCk7Ci0gICAganIuY2xvc2UoKTsKLQotICAgIGJ5dGVbXSBieXRlcyA9IGJvcy50b0J5dGVBcnJheSgpOwotCi0gICAgaWYodW5jb21wcmVzcykgewotICAgICAgR1pJUElucHV0U3RyZWFtIGdpcyA9IG5ldyBHWklQSW5wdXRTdHJlYW0obmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGJ5dGVzKSk7Ci0KLSAgICAgIGJ5dGVbXSB0bXAgICA9IG5ldyBieXRlW2J5dGVzLmxlbmd0aCAqIDNdOyAvLyBSb3VnaCBlc3RpbWF0ZQotICAgICAgaW50ICAgIGNvdW50ID0gMDsKLSAgICAgIGludCAgICBiOwotCi0gICAgICB3aGlsZSgoYiA9IGdpcy5yZWFkKCkpID49IDApCi0gICAgICAgIHRtcFtjb3VudCsrXSA9IChieXRlKWI7Ci0KLSAgICAgIGJ5dGVzID0gbmV3IGJ5dGVbY291bnRdOwotICAgICAgU3lzdGVtLmFycmF5Y29weSh0bXAsIDAsIGJ5dGVzLCAwLCBjb3VudCk7Ci0gICAgfQotCi0gICAgcmV0dXJuIGJ5dGVzOwotICB9Ci0KLSAgLy8gQS1aLCBnLXosIF8sICQKLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50ICAgRlJFRV9DSEFSUyAgPSA0ODsKLSAgcHJpdmF0ZSBzdGF0aWMgICAgICAgaW50W10gQ0hBUl9NQVAgICAgPSBuZXcgaW50W0ZSRUVfQ0hBUlNdOwotICBwcml2YXRlIHN0YXRpYyAgICAgICBpbnRbXSBNQVBfQ0hBUiAgICA9IG5ldyBpbnRbMjU2XTsgLy8gUmV2ZXJzZSBtYXAKLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2hhciAgRVNDQVBFX0NIQVIgPSAnJCc7Ci0KLSAgc3RhdGljIHsKLSAgICBpbnQgaiA9IDAsIGsgPSAwOwotICAgIGZvcihpbnQgaT0nQSc7IGkgPD0gJ1onOyBpKyspIHsKLSAgICAgIENIQVJfTUFQW2pdID0gaTsKLSAgICAgIE1BUF9DSEFSW2ldID0gajsKLSAgICAgIGorKzsKLSAgICB9Ci0KLSAgICBmb3IoaW50IGk9J2cnOyBpIDw9ICd6JzsgaSsrKSB7Ci0gICAgICBDSEFSX01BUFtqXSA9IGk7Ci0gICAgICBNQVBfQ0hBUltpXSA9IGo7Ci0gICAgICBqKys7Ci0gICAgfQotCi0gICAgQ0hBUl9NQVBbal0gICA9ICckJzsKLSAgICBNQVBfQ0hBUlsnJCddID0gajsKLSAgICBqKys7Ci0KLSAgICBDSEFSX01BUFtqXSAgID0gJ18nOwotICAgIE1BUF9DSEFSWydfJ10gPSBqOwotICB9Ci0KLSAgLyoqIERlY29kZSBjaGFyYWN0ZXJzIGludG8gYnl0ZXMuCi0gICAqIFVzZWQgYnkgPGEgaHJlZj0iVXRpbGl0eS5odG1sI2RlY29kZShqYXZhLmxhbmcuU3RyaW5nLCBib29sZWFuKSI+ZGVjb2RlKCk8L2E+Ci0gICAqLwotICBwcml2YXRlIHN0YXRpYyBjbGFzcyBKYXZhUmVhZGVyIGV4dGVuZHMgRmlsdGVyUmVhZGVyIHsKLSAgICBwdWJsaWMgSmF2YVJlYWRlcihSZWFkZXIgaW4pIHsKLSAgICAgIHN1cGVyKGluKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IHJlYWQoKSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgICAgaW50IGIgPSBpbi5yZWFkKCk7Ci0KLSAgICAgIGlmKGIgIT0gRVNDQVBFX0NIQVIpIHsKLSAgICAgICAgcmV0dXJuIGI7Ci0gICAgICB9IGVsc2UgewotICAgICAgICBpbnQgaSA9IGluLnJlYWQoKTsKLQotICAgICAgICBpZihpIDwgMCkKLSAgICAgICAgICByZXR1cm4gLTE7Ci0KLSAgICAgICAgaWYoKChpID49ICcwJykgJiYgKGkgPD0gJzknKSkgfHwgKChpID49ICdhJykgJiYgKGkgPD0gJ2YnKSkpIHsgLy8gTm9ybWFsIGVzY2FwZQotICAgICAgICAgIGludCBqID0gaW4ucmVhZCgpOwotCi0gICAgICAgICAgaWYoaiA8IDApCi0gICAgICAgICAgICByZXR1cm4gLTE7Ci0KLSAgICAgICAgICBjaGFyW10gdG1wID0geyAoY2hhcilpLCAoY2hhcilqIH07Ci0gICAgICAgICAgaW50ICAgIHMgICA9IEludGVnZXIucGFyc2VJbnQobmV3IFN0cmluZyh0bXApLCAxNik7Ci0KLSAgICAgICAgICByZXR1cm4gczsKLSAgICAgICAgfSBlbHNlIHsgLy8gU3BlY2lhbCBlc2NhcGUKLSAgICAgICAgICByZXR1cm4gTUFQX0NIQVJbaV07Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IHJlYWQoY2hhcltdIGNidWYsIGludCBvZmYsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgICBmb3IoaW50IGk9MDsgaSA8IGxlbjsgaSsrKQotICAgICAgICBjYnVmW29mZiArIGldID0gKGNoYXIpcmVhZCgpOwotCi0gICAgICByZXR1cm4gbGVuOwotICAgIH0KLSAgfQotCi0gIC8qKiBFbmNvZGUgYnl0ZXMgaW50byB2YWxpZCBqYXZhIGlkZW50aWZpZXIgY2hhcmFjdGVycy4KLSAgICogVXNlZCBieSA8YSBocmVmPSJVdGlsaXR5Lmh0bWwjZW5jb2RlKGJ5dGVbXSwgYm9vbGVhbikiPmVuY29kZSgpPC9hPgotICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgSmF2YVdyaXRlciBleHRlbmRzIEZpbHRlcldyaXRlciB7Ci0gICAgcHVibGljIEphdmFXcml0ZXIoV3JpdGVyIG91dCkgewotICAgICAgc3VwZXIob3V0KTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCB3cml0ZShpbnQgYikgdGhyb3dzIElPRXhjZXB0aW9uIHsKLSAgICAgIGlmKGlzSmF2YUlkZW50aWZpZXJQYXJ0KChjaGFyKWIpICYmIChiICE9IEVTQ0FQRV9DSEFSKSkgewotICAgICAgICBvdXQud3JpdGUoYik7Ci0gICAgICB9IGVsc2UgewotICAgICAgICBvdXQud3JpdGUoRVNDQVBFX0NIQVIpOyAvLyBFc2NhcGUgY2hhcmFjdGVyCi0KLSAgICAgICAgLy8gU3BlY2lhbCBlc2NhcGUKLSAgICAgICAgaWYoYiA+PSAwICYmIGIgPCBGUkVFX0NIQVJTKSB7Ci0gICAgICAgICAgb3V0LndyaXRlKENIQVJfTUFQW2JdKTsKLSAgICAgICAgfSBlbHNlIHsgLy8gTm9ybWFsIGVzY2FwZQotICAgICAgICAgIGNoYXJbXSB0bXAgPSBJbnRlZ2VyLnRvSGV4U3RyaW5nKGIpLnRvQ2hhckFycmF5KCk7Ci0KLSAgICAgICAgICBpZih0bXAubGVuZ3RoID09IDEpIHsKLSAgICAgICAgICAgIG91dC53cml0ZSgnMCcpOwotICAgICAgICAgICAgb3V0LndyaXRlKHRtcFswXSk7Ci0gICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIG91dC53cml0ZSh0bXBbMF0pOwotICAgICAgICAgICAgb3V0LndyaXRlKHRtcFsxXSk7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgd3JpdGUoY2hhcltdIGNidWYsIGludCBvZmYsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgICBmb3IoaW50IGk9MDsgaSA8IGxlbjsgaSsrKQotICAgICAgICB3cml0ZShjYnVmW29mZiArIGldKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCB3cml0ZShTdHJpbmcgc3RyLCBpbnQgb2ZmLCBpbnQgbGVuKSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgICAgd3JpdGUoc3RyLnRvQ2hhckFycmF5KCksIG9mZiwgbGVuKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogRXNjYXBlIGFsbCBvY2N1cmVuY2VzIG9mIG5ld2xpbmUgY2hhcnMgJ1xuJywgcXVvdGVzIFwiLCBldGMuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBjb252ZXJ0U3RyaW5nKFN0cmluZyBsYWJlbCkgewotICAgIGNoYXJbXSAgICAgICBjaCAgPSBsYWJlbC50b0NoYXJBcnJheSgpOwotICAgIFN0cmluZ0J1ZmZlciBidWYgPSBuZXcgU3RyaW5nQnVmZmVyKCk7Ci0KLSAgICBmb3IoaW50IGk9MDsgaSA8IGNoLmxlbmd0aDsgaSsrKSB7Ci0gICAgICBzd2l0Y2goY2hbaV0pIHsKLSAgICAgIGNhc2UgJ1xuJzoKLSAgICAgICAgYnVmLmFwcGVuZCgiXFxuIik7IGJyZWFrOwotICAgICAgY2FzZSAnXHInOgotICAgICAgICBidWYuYXBwZW5kKCJcXHIiKTsgYnJlYWs7Ci0gICAgICBjYXNlICdcIic6Ci0gICAgICAgIGJ1Zi5hcHBlbmQoIlxcXCIiKTsgYnJlYWs7Ci0gICAgICBjYXNlICdcJyc6Ci0gICAgICAgIGJ1Zi5hcHBlbmQoIlxcJyIpOyBicmVhazsKLSAgICAgIGNhc2UgJ1xcJzoKLSAgICAgICAgYnVmLmFwcGVuZCgiXFxcXCIpOyBicmVhazsKLSAgICAgIGRlZmF1bHQ6Ci0gICAgICAgIGJ1Zi5hcHBlbmQoY2hbaV0pOyBicmVhazsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gYnVmLnRvU3RyaW5nKCk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvVmlzaXRvci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2NsYXNzZmlsZS9WaXNpdG9yLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGEwNzY3NjguLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2NsYXNzZmlsZS9WaXNpdG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMDUgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuY2xhc3NmaWxlOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIEludGVyZmFjZSB0byBtYWtlIHVzZSBvZiB0aGUgVmlzaXRvciBwYXR0ZXJuIHByb2dyYW1taW5nIHN0eWxlLgotICogSS5lLiBhIGNsYXNzIHRoYXQgaW1wbGVtZW50cyB0aGlzIGludGVyZmFjZSBjYW4gdHJhdmVyc2UgdGhlIGNvbnRlbnRzIG9mCi0gKiBhIEphdmEgY2xhc3MganVzdCBieSBjYWxsaW5nIHRoZSBgYWNjZXB0JyBtZXRob2Qgd2hpY2ggYWxsIGNsYXNzZXMgaGF2ZS4KLSAqCi0gKiBJbXBsZW1lbnRlZCBieSB3aXNoIG9mCi0gKiA8QSBIUkVGPSJodHRwOi8vd3d3LmluZi5mdS1iZXJsaW4uZGUvfmJva293c2tpIj5Cb3JpcyBCb2tvd3NraTwvQT4uCi0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGludGVyZmFjZSBWaXNpdG9yIHsKLSAgcHVibGljIHZvaWQgdmlzaXRDb2RlKENvZGUgb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRDb2RlRXhjZXB0aW9uKENvZGVFeGNlcHRpb24gb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRDb25zdGFudENsYXNzKENvbnN0YW50Q2xhc3Mgb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRDb25zdGFudERvdWJsZShDb25zdGFudERvdWJsZSBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdENvbnN0YW50RmllbGRyZWYoQ29uc3RhbnRGaWVsZHJlZiBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdENvbnN0YW50RmxvYXQoQ29uc3RhbnRGbG9hdCBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdENvbnN0YW50SW50ZWdlcihDb25zdGFudEludGVnZXIgb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRDb25zdGFudEludGVyZmFjZU1ldGhvZHJlZihDb25zdGFudEludGVyZmFjZU1ldGhvZHJlZiBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdENvbnN0YW50TG9uZyhDb25zdGFudExvbmcgb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRDb25zdGFudE1ldGhvZHJlZihDb25zdGFudE1ldGhvZHJlZiBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdENvbnN0YW50TmFtZUFuZFR5cGUoQ29uc3RhbnROYW1lQW5kVHlwZSBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdENvbnN0YW50UG9vbChDb25zdGFudFBvb2wgb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRDb25zdGFudFN0cmluZyhDb25zdGFudFN0cmluZyBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdENvbnN0YW50VXRmOChDb25zdGFudFV0Zjggb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRDb25zdGFudFZhbHVlKENvbnN0YW50VmFsdWUgb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXREZXByZWNhdGVkKERlcHJlY2F0ZWQgb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRFeGNlcHRpb25UYWJsZShFeGNlcHRpb25UYWJsZSBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdEZpZWxkKEZpZWxkIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0SW5uZXJDbGFzcyhJbm5lckNsYXNzIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0SW5uZXJDbGFzc2VzKElubmVyQ2xhc3NlcyBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdEphdmFDbGFzcyhKYXZhQ2xhc3Mgb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRMaW5lTnVtYmVyKExpbmVOdW1iZXIgb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRMaW5lTnVtYmVyVGFibGUoTGluZU51bWJlclRhYmxlIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0TG9jYWxWYXJpYWJsZShMb2NhbFZhcmlhYmxlIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0TG9jYWxWYXJpYWJsZVRhYmxlKExvY2FsVmFyaWFibGVUYWJsZSBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdExvY2FsVmFyaWFibGVUeXBlVGFibGUoTG9jYWxWYXJpYWJsZVR5cGVUYWJsZSBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdE1ldGhvZChNZXRob2Qgb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRTaWduYXR1cmUoU2lnbmF0dXJlIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0U291cmNlRmlsZShTb3VyY2VGaWxlIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0U3ludGhldGljKFN5bnRoZXRpYyBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdFVua25vd24oVW5rbm93biBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdFN0YWNrTWFwKFN0YWNrTWFwIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0U3RhY2tNYXBFbnRyeShTdGFja01hcEVudHJ5IG9iaik7Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvY2xhc3NmaWxlL3BhY2thZ2UuaHRtbCBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvcGFja2FnZS5odG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmZjBhYjRkLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvcGFja2FnZS5odG1sCisrKyAvZGV2L251bGwKQEAgLTEsMTQgKzAsMCBAQAotPCFET0NUWVBFIEhUTUwgUFVCTElDICItLy9XM0MvL0RURCBIVE1MIDMuMiBGaW5hbC8vRU4iPgotPGh0bWw+Ci08aGVhZD4KLTwhLS0KLSRJZDogcGFja2FnZS5odG1sLHYgMS4xLjIuMSAyMDA1LzA3LzMxIDIzOjQ2OjMzIGplZmZzdXR0b3IgRXhwICQKLS0tPgotPC9oZWFkPgotPGJvZHkgYmdjb2xvcj0id2hpdGUiPgotPHA+Ci1UaGlzIHBhY2thZ2UgY29udGFpbnMgdGhlIGNsYXNzZXMgdGhhdCBkZXNjcmliZSB0aGUgc3RydWN0dXJlIG9mIGEKLUphdmEgY2xhc3MgZmlsZSBhbmQgYSBjbGFzcyBmaWxlIHBhcnNlci4KLTwvcD4KLTwvYm9keT4KLTwvaHRtbD4KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0FBTE9BRC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvQUFMT0FELmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDkxNGQ1YjMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvQUFMT0FELmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5MCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIEFBTE9BRCAtIExvYWQgcmVmZXJlbmNlIGZyb20gYXJyYXkKLSAqIDxQUkU+U3RhY2s6IC4uLiwgYXJyYXlyZWYsIGluZGV4IC0mZ3Q7IHZhbHVlPC9QUkU+Ci0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGNsYXNzIEFBTE9BRCBleHRlbmRzIEFycmF5SW5zdHJ1Y3Rpb24gaW1wbGVtZW50cyBTdGFja1Byb2R1Y2VyIHsKLSAgLyoqIExvYWQgcmVmZXJlbmNlIGZyb20gYXJyYXkKLSAgICovCi0gIHB1YmxpYyBBQUxPQUQoKSB7Ci0gICAgc3VwZXIoY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkFBTE9BRCk7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBDYWxsIGNvcnJlc3BvbmRpbmcgdmlzaXRvciBtZXRob2QocykuIFRoZSBvcmRlciBpczoKLSAgICogQ2FsbCB2aXNpdG9yIG1ldGhvZHMgb2YgaW1wbGVtZW50ZWQgaW50ZXJmYWNlcyBmaXJzdCwgdGhlbgotICAgKiBjYWxsIG1ldGhvZHMgYWNjb3JkaW5nIHRvIHRoZSBjbGFzcyBoaWVyYXJjaHkgaW4gZGVzY2VuZGluZyBvcmRlciwKLSAgICogaS5lLiwgdGhlIG1vc3Qgc3BlY2lmaWMgdmlzaXRYWFgoKSBjYWxsIGNvbWVzIGxhc3QuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgdi52aXNpdFN0YWNrUHJvZHVjZXIodGhpcyk7Ci0gICAgdi52aXNpdEV4Y2VwdGlvblRocm93ZXIodGhpcyk7Ci0gICAgdi52aXNpdFR5cGVkSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdEFycmF5SW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdEFBTE9BRCh0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvQUFTVE9SRS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvQUFTVE9SRS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlOGEyZGRkLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0FBU1RPUkUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDkwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8qKgotICogQUFTVE9SRSAtICBTdG9yZSBpbnRvIHJlZmVyZW5jZSBhcnJheQotICogPFBSRT5TdGFjazogLi4uLCBhcnJheXJlZiwgaW5kZXgsIHZhbHVlIC0mZ3Q7IC4uLjwvUFJFPgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBBQVNUT1JFIGV4dGVuZHMgQXJyYXlJbnN0cnVjdGlvbiBpbXBsZW1lbnRzIFN0YWNrQ29uc3VtZXIgewotICAvKiogU3RvcmUgaW50byByZWZlcmVuY2UgYXJyYXkKLSAgICovCi0gIHB1YmxpYyBBQVNUT1JFKCkgewotICAgIHN1cGVyKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5BQVNUT1JFKTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIENhbGwgY29ycmVzcG9uZGluZyB2aXNpdG9yIG1ldGhvZChzKS4gVGhlIG9yZGVyIGlzOgotICAgKiBDYWxsIHZpc2l0b3IgbWV0aG9kcyBvZiBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzIGZpcnN0LCB0aGVuCi0gICAqIGNhbGwgbWV0aG9kcyBhY2NvcmRpbmcgdG8gdGhlIGNsYXNzIGhpZXJhcmNoeSBpbiBkZXNjZW5kaW5nIG9yZGVyLAotICAgKiBpLmUuLCB0aGUgbW9zdCBzcGVjaWZpYyB2aXNpdFhYWCgpIGNhbGwgY29tZXMgbGFzdC4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0U3RhY2tDb25zdW1lcih0aGlzKTsKLSAgICB2LnZpc2l0RXhjZXB0aW9uVGhyb3dlcih0aGlzKTsKLSAgICB2LnZpc2l0VHlwZWRJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0QXJyYXlJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0QUFTVE9SRSh0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvQUNPTlNUX05VTEwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0FDT05TVF9OVUxMLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDdkMTAwMzUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvQUNPTlNUX05VTEwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDk3ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8qKgotICogQUNPTlNUX05VTEwgLSBQdXNoIG51bGwgcmVmZXJlbmNlCi0gKiA8UFJFPlN0YWNrOiAuLi4gLSZndDsgLi4uLCBudWxsPC9QUkU+Ci0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGNsYXNzIEFDT05TVF9OVUxMIGV4dGVuZHMgSW5zdHJ1Y3Rpb24KLSAgaW1wbGVtZW50cyBQdXNoSW5zdHJ1Y3Rpb24sIFR5cGVkSW5zdHJ1Y3Rpb24gewotICAvKioKLSAgICogUHVzaCBudWxsIHJlZmVyZW5jZQotICAgKi8KLSAgcHVibGljIEFDT05TVF9OVUxMKCkgewotICAgIHN1cGVyKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5BQ09OU1RfTlVMTCwgKHNob3J0KTEpOwotICB9Ci0KLSAgLyoqIEByZXR1cm4gVHlwZS5OVUxMCi0gICAqLwotICBwdWJsaWMgVHlwZSBnZXRUeXBlKENvbnN0YW50UG9vbEdlbiBjcCkgewotICAgIHJldHVybiBUeXBlLk5VTEw7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBDYWxsIGNvcnJlc3BvbmRpbmcgdmlzaXRvciBtZXRob2QocykuIFRoZSBvcmRlciBpczoKLSAgICogQ2FsbCB2aXNpdG9yIG1ldGhvZHMgb2YgaW1wbGVtZW50ZWQgaW50ZXJmYWNlcyBmaXJzdCwgdGhlbgotICAgKiBjYWxsIG1ldGhvZHMgYWNjb3JkaW5nIHRvIHRoZSBjbGFzcyBoaWVyYXJjaHkgaW4gZGVzY2VuZGluZyBvcmRlciwKLSAgICogaS5lLiwgdGhlIG1vc3Qgc3BlY2lmaWMgdmlzaXRYWFgoKSBjYWxsIGNvbWVzIGxhc3QuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgdi52aXNpdFN0YWNrUHJvZHVjZXIodGhpcyk7Ci0gICAgdi52aXNpdFB1c2hJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0VHlwZWRJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0QUNPTlNUX05VTEwodGhpcyk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0FMT0FELmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9BTE9BRC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyZDBhMTEzLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0FMT0FELmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5NSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIEFMT0FEIC0gTG9hZCByZWZlcmVuY2UgZnJvbSBsb2NhbCB2YXJpYWJsZQotICogPFBSRT5TdGFjazogLi4uIC0mZ3Q7IC4uLiwgb2JqZWN0cmVmPC9QUkU+Ci0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGNsYXNzIEFMT0FEIGV4dGVuZHMgTG9hZEluc3RydWN0aW9uIHsKLSAgLyoqCi0gICAqIEVtcHR5IGNvbnN0cnVjdG9yIG5lZWRlZCBmb3IgdGhlIENsYXNzLm5ld0luc3RhbmNlKCkgc3RhdGVtZW50IGluCi0gICAqIEluc3RydWN0aW9uLnJlYWRJbnN0cnVjdGlvbigpLiBOb3QgdG8gYmUgdXNlZCBvdGhlcndpc2UuCi0gICAqLwotICBBTE9BRCgpIHsKLSAgICBzdXBlcihjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuQUxPQUQsIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5BTE9BRF8wKTsKLSAgfQotCi0gIC8qKiBMb2FkIHJlZmVyZW5jZSBmcm9tIGxvY2FsIHZhcmlhYmxlCi0gICAqIEBwYXJhbSBuIGluZGV4IG9mIGxvY2FsIHZhcmlhYmxlCi0gICAqLwotICBwdWJsaWMgQUxPQUQoaW50IG4pIHsKLSAgICBzdXBlcihjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuQUxPQUQsIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5BTE9BRF8wLCBuKTsKLSAgfQotCi0gIC8qKgotICAgKiBDYWxsIGNvcnJlc3BvbmRpbmcgdmlzaXRvciBtZXRob2QocykuIFRoZSBvcmRlciBpczoKLSAgICogQ2FsbCB2aXNpdG9yIG1ldGhvZHMgb2YgaW1wbGVtZW50ZWQgaW50ZXJmYWNlcyBmaXJzdCwgdGhlbgotICAgKiBjYWxsIG1ldGhvZHMgYWNjb3JkaW5nIHRvIHRoZSBjbGFzcyBoaWVyYXJjaHkgaW4gZGVzY2VuZGluZyBvcmRlciwKLSAgICogaS5lLiwgdGhlIG1vc3Qgc3BlY2lmaWMgdmlzaXRYWFgoKSBjYWxsIGNvbWVzIGxhc3QuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgc3VwZXIuYWNjZXB0KHYpOwotICAgIHYudmlzaXRBTE9BRCh0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvQU5FV0FSUkFZLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9BTkVXQVJSQVkuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNGFiNTU1MC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9BTkVXQVJSQVkuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExNyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkV4Y2VwdGlvbkNvbnN0YW50czsKLQotLyoqCi0gKiBBTkVXQVJSQVkgLSAgQ3JlYXRlIG5ldyBhcnJheSBvZiByZWZlcmVuY2VzCi0gKiA8UFJFPlN0YWNrOiAuLi4sIGNvdW50IC0mZ3Q7IC4uLiwgYXJyYXlyZWY8L1BSRT4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgQU5FV0FSUkFZIGV4dGVuZHMgQ1BJbnN0cnVjdGlvbgotICBpbXBsZW1lbnRzIExvYWRDbGFzcywgQWxsb2NhdGlvbkluc3RydWN0aW9uLCBFeGNlcHRpb25UaHJvd2VyLCBTdGFja1Byb2R1Y2VyIHsKLSAgLyoqCi0gICAqIEVtcHR5IGNvbnN0cnVjdG9yIG5lZWRlZCBmb3IgdGhlIENsYXNzLm5ld0luc3RhbmNlKCkgc3RhdGVtZW50IGluCi0gICAqIEluc3RydWN0aW9uLnJlYWRJbnN0cnVjdGlvbigpLiBOb3QgdG8gYmUgdXNlZCBvdGhlcndpc2UuCi0gICAqLwotICBBTkVXQVJSQVkoKSB7fQotCi0gIHB1YmxpYyBBTkVXQVJSQVkoaW50IGluZGV4KSB7Ci0gICAgc3VwZXIoY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkFORVdBUlJBWSwgaW5kZXgpOwotICB9Ci0KLSAgcHVibGljIENsYXNzW10gZ2V0RXhjZXB0aW9ucygpewotICAgIENsYXNzW10gY3MgPSBuZXcgQ2xhc3NbMSArIEV4Y2VwdGlvbkNvbnN0YW50cy5FWENTX0NMQVNTX0FORF9JTlRFUkZBQ0VfUkVTT0xVVElPTi5sZW5ndGhdOwotCi0gICAgU3lzdGVtLmFycmF5Y29weShFeGNlcHRpb25Db25zdGFudHMuRVhDU19DTEFTU19BTkRfSU5URVJGQUNFX1JFU09MVVRJT04sIDAsCi0gICAgICAgICAgICAgICAgICAgICBjcywgMCwgRXhjZXB0aW9uQ29uc3RhbnRzLkVYQ1NfQ0xBU1NfQU5EX0lOVEVSRkFDRV9SRVNPTFVUSU9OLmxlbmd0aCk7Ci0gICAgY3NbRXhjZXB0aW9uQ29uc3RhbnRzLkVYQ1NfQ0xBU1NfQU5EX0lOVEVSRkFDRV9SRVNPTFVUSU9OLmxlbmd0aF0gPQotICAgICAgRXhjZXB0aW9uQ29uc3RhbnRzLk5FR0FUSVZFX0FSUkFZX1NJWkVfRVhDRVBUSU9OOwotICAgIHJldHVybiBjczsKLSAgfQotCi0gIC8qKgotICAgKiBDYWxsIGNvcnJlc3BvbmRpbmcgdmlzaXRvciBtZXRob2QocykuIFRoZSBvcmRlciBpczoKLSAgICogQ2FsbCB2aXNpdG9yIG1ldGhvZHMgb2YgaW1wbGVtZW50ZWQgaW50ZXJmYWNlcyBmaXJzdCwgdGhlbgotICAgKiBjYWxsIG1ldGhvZHMgYWNjb3JkaW5nIHRvIHRoZSBjbGFzcyBoaWVyYXJjaHkgaW4gZGVzY2VuZGluZyBvcmRlciwKLSAgICogaS5lLiwgdGhlIG1vc3Qgc3BlY2lmaWMgdmlzaXRYWFgoKSBjYWxsIGNvbWVzIGxhc3QuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgdi52aXNpdExvYWRDbGFzcyh0aGlzKTsKLSAgICB2LnZpc2l0QWxsb2NhdGlvbkluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRFeGNlcHRpb25UaHJvd2VyKHRoaXMpOwotICAgIHYudmlzaXRTdGFja1Byb2R1Y2VyKHRoaXMpOwotICAgIHYudmlzaXRUeXBlZEluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRDUEluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRBTkVXQVJSQVkodGhpcyk7Ci0gIH0KLQotICBwdWJsaWMgT2JqZWN0VHlwZSBnZXRMb2FkQ2xhc3NUeXBlKENvbnN0YW50UG9vbEdlbiBjcGcpIHsKLSAgICBUeXBlIHQgPSBnZXRUeXBlKGNwZyk7Ci0KLSAgICBpZiAodCBpbnN0YW5jZW9mIEFycmF5VHlwZSl7Ci0gICAgICB0ID0gKChBcnJheVR5cGUpIHQpLmdldEJhc2ljVHlwZSgpOwotICAgIH0KLQotICAgIHJldHVybiAodCBpbnN0YW5jZW9mIE9iamVjdFR5cGUpPyAoT2JqZWN0VHlwZSkgdCA6IG51bGw7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0FSRVRVUk4uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0FSRVRVUk4uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYjBjNzM4OS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9BUkVUVVJOLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5MSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIEFSRVRVUk4gLSAgUmV0dXJuIHJlZmVyZW5jZSBmcm9tIG1ldGhvZAotICogPFBSRT5TdGFjazogLi4uLCBvYmplY3RyZWYgLSZndDsgJmx0O2VtcHR5Jmd0OzwvUFJFPgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBBUkVUVVJOIGV4dGVuZHMgUmV0dXJuSW5zdHJ1Y3Rpb24gewotICAvKioKLSAgICogUmV0dXJuIHJlZmVyZW5jZSBmcm9tIG1ldGhvZAotICAgKi8KLSAgcHVibGljIEFSRVRVUk4oKSB7Ci0gICAgc3VwZXIoY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkFSRVRVUk4pOwotICB9Ci0KLQotICAvKioKLSAgICogQ2FsbCBjb3JyZXNwb25kaW5nIHZpc2l0b3IgbWV0aG9kKHMpLiBUaGUgb3JkZXIgaXM6Ci0gICAqIENhbGwgdmlzaXRvciBtZXRob2RzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMgZmlyc3QsIHRoZW4KLSAgICogY2FsbCBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY2xhc3MgaGllcmFyY2h5IGluIGRlc2NlbmRpbmcgb3JkZXIsCi0gICAqIGkuZS4sIHRoZSBtb3N0IHNwZWNpZmljIHZpc2l0WFhYKCkgY2FsbCBjb21lcyBsYXN0LgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRFeGNlcHRpb25UaHJvd2VyKHRoaXMpOwotICAgIHYudmlzaXRUeXBlZEluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRTdGFja0NvbnN1bWVyKHRoaXMpOwotICAgIHYudmlzaXRSZXR1cm5JbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0QVJFVFVSTih0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvQVJSQVlMRU5HVEguamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0FSUkFZTEVOR1RILmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDMzZjEwZTYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvQVJSQVlMRU5HVEguamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDk1ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8qKgotICogQVJSQVlMRU5HVEggLSAgR2V0IGxlbmd0aCBvZiBhcnJheQotICogPFBSRT5TdGFjazogLi4uLCBhcnJheXJlZiAtJmd0OyAuLi4sIGxlbmd0aDwvUFJFPgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBBUlJBWUxFTkdUSCBleHRlbmRzIEluc3RydWN0aW9uCi0gIGltcGxlbWVudHMgRXhjZXB0aW9uVGhyb3dlciwgU3RhY2tQcm9kdWNlciB7Ci0gIC8qKiBHZXQgbGVuZ3RoIG9mIGFycmF5Ci0gICAqLwotICBwdWJsaWMgQVJSQVlMRU5HVEgoKSB7Ci0gICAgc3VwZXIoY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkFSUkFZTEVOR1RILCAoc2hvcnQpMSk7Ci0gIH0KLQotICAvKiogQHJldHVybiBleGNlcHRpb25zIHRoaXMgaW5zdHJ1Y3Rpb24gbWF5IGNhdXNlCi0gICAqLwotICBwdWJsaWMgQ2xhc3NbXSBnZXRFeGNlcHRpb25zKCkgewotICAgIHJldHVybiBuZXcgQ2xhc3NbXSB7IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkV4Y2VwdGlvbkNvbnN0YW50cy5OVUxMX1BPSU5URVJfRVhDRVBUSU9OIH07Ci0gIH0KLQotCi0gIC8qKgotICAgKiBDYWxsIGNvcnJlc3BvbmRpbmcgdmlzaXRvciBtZXRob2QocykuIFRoZSBvcmRlciBpczoKLSAgICogQ2FsbCB2aXNpdG9yIG1ldGhvZHMgb2YgaW1wbGVtZW50ZWQgaW50ZXJmYWNlcyBmaXJzdCwgdGhlbgotICAgKiBjYWxsIG1ldGhvZHMgYWNjb3JkaW5nIHRvIHRoZSBjbGFzcyBoaWVyYXJjaHkgaW4gZGVzY2VuZGluZyBvcmRlciwKLSAgICogaS5lLiwgdGhlIG1vc3Qgc3BlY2lmaWMgdmlzaXRYWFgoKSBjYWxsIGNvbWVzIGxhc3QuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgdi52aXNpdEV4Y2VwdGlvblRocm93ZXIodGhpcyk7Ci0gICAgdi52aXNpdFN0YWNrUHJvZHVjZXIodGhpcyk7Ci0gICAgdi52aXNpdEFSUkFZTEVOR1RIKHRoaXMpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9BU1RPUkUuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0FTVE9SRS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0YjE1ZWZlLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0FTVE9SRS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTUgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotLyoqCi0gKiBBU1RPUkUgLSBTdG9yZSByZWZlcmVuY2UgaW50byBsb2NhbCB2YXJpYWJsZQotICogPFBSRT5TdGFjayAuLi4sIG9iamVjdHJlZiAtJmd0OyAuLi4gPC9QUkU+Ci0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGNsYXNzIEFTVE9SRSBleHRlbmRzIFN0b3JlSW5zdHJ1Y3Rpb24gewotICAvKioKLSAgICogRW1wdHkgY29uc3RydWN0b3IgbmVlZGVkIGZvciB0aGUgQ2xhc3MubmV3SW5zdGFuY2UoKSBzdGF0ZW1lbnQgaW4KLSAgICogSW5zdHJ1Y3Rpb24ucmVhZEluc3RydWN0aW9uKCkuIE5vdCB0byBiZSB1c2VkIG90aGVyd2lzZS4KLSAgICovCi0gIEFTVE9SRSgpIHsKLSAgICBzdXBlcihjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuQVNUT1JFLCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuQVNUT1JFXzApOwotICB9Ci0KLSAgLyoqIFN0b3JlIHJlZmVyZW5jZSBpbnRvIGxvY2FsIHZhcmlhYmxlCi0gICAqIEBwYXJhbSBuIGluZGV4IG9mIGxvY2FsIHZhcmlhYmxlCi0gICAqLwotICBwdWJsaWMgQVNUT1JFKGludCBuKSB7Ci0gICAgc3VwZXIoY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkFTVE9SRSwgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkFTVE9SRV8wLCBuKTsKLSAgfQotCi0gIC8qKgotICAgKiBDYWxsIGNvcnJlc3BvbmRpbmcgdmlzaXRvciBtZXRob2QocykuIFRoZSBvcmRlciBpczoKLSAgICogQ2FsbCB2aXNpdG9yIG1ldGhvZHMgb2YgaW1wbGVtZW50ZWQgaW50ZXJmYWNlcyBmaXJzdCwgdGhlbgotICAgKiBjYWxsIG1ldGhvZHMgYWNjb3JkaW5nIHRvIHRoZSBjbGFzcyBoaWVyYXJjaHkgaW4gZGVzY2VuZGluZyBvcmRlciwKLSAgICogaS5lLiwgdGhlIG1vc3Qgc3BlY2lmaWMgdmlzaXRYWFgoKSBjYWxsIGNvbWVzIGxhc3QuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgc3VwZXIuYWNjZXB0KHYpOwotICAgIHYudmlzaXRBU1RPUkUodGhpcyk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0FUSFJPVy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvQVRIUk9XLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGYwYWZlYTcuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvQVRIUk9XLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5NSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIEFUSFJPVyAtICBUaHJvdyBleGNlcHRpb24KLSAqIDxQUkU+U3RhY2s6IC4uLiwgb2JqZWN0cmVmIC0mZ3Q7IG9iamVjdHJlZjwvUFJFPgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBBVEhST1cgZXh0ZW5kcyBJbnN0cnVjdGlvbiBpbXBsZW1lbnRzIFVuY29uZGl0aW9uYWxCcmFuY2gsIEV4Y2VwdGlvblRocm93ZXIgewotICAvKioKLSAgICogIFRocm93IGV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIEFUSFJPVygpIHsKLSAgICBzdXBlcihjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuQVRIUk9XLCAoc2hvcnQpMSk7Ci0gIH0KLQotICAvKiogQHJldHVybiBleGNlcHRpb25zIHRoaXMgaW5zdHJ1Y3Rpb24gbWF5IGNhdXNlCi0gICAqLwotICBwdWJsaWMgQ2xhc3NbXSBnZXRFeGNlcHRpb25zKCkgewotICAgIHJldHVybiBuZXcgQ2xhc3NbXSB7IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkV4Y2VwdGlvbkNvbnN0YW50cy5USFJPV0FCTEUgfTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIENhbGwgY29ycmVzcG9uZGluZyB2aXNpdG9yIG1ldGhvZChzKS4gVGhlIG9yZGVyIGlzOgotICAgKiBDYWxsIHZpc2l0b3IgbWV0aG9kcyBvZiBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzIGZpcnN0LCB0aGVuCi0gICAqIGNhbGwgbWV0aG9kcyBhY2NvcmRpbmcgdG8gdGhlIGNsYXNzIGhpZXJhcmNoeSBpbiBkZXNjZW5kaW5nIG9yZGVyLAotICAgKiBpLmUuLCB0aGUgbW9zdCBzcGVjaWZpYyB2aXNpdFhYWCgpIGNhbGwgY29tZXMgbGFzdC4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0VW5jb25kaXRpb25hbEJyYW5jaCh0aGlzKTsKLSAgICB2LnZpc2l0RXhjZXB0aW9uVGhyb3dlcih0aGlzKTsKLSAgICB2LnZpc2l0QVRIUk9XKHRoaXMpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9BbGxvY2F0aW9uSW5zdHJ1Y3Rpb24uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0FsbG9jYXRpb25JbnN0cnVjdGlvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxMDA2NDQwLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0FsbG9jYXRpb25JbnN0cnVjdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNjYgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotLyoqCi0gKiBEZW5vdGUgZmFtaWx5IG9mIGluc3RydWN0aW9ucyB0aGF0IGFsbG9jYXRlcyBzcGFjZSBpbiB0aGUgaGVhcC4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgaW50ZXJmYWNlIEFsbG9jYXRpb25JbnN0cnVjdGlvbiB7fQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvQXJpdGhtZXRpY0luc3RydWN0aW9uLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9Bcml0aG1ldGljSW5zdHJ1Y3Rpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNWIzNWE4Yy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9Bcml0aG1ldGljSW5zdHJ1Y3Rpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEwOSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50czsKLS8qKgotICogU3VwZXIgY2xhc3MgZm9yIHRoZSBmYW1pbHkgb2YgYXJpdGhtZXRpYyBpbnN0cnVjdGlvbnMuCi0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGFic3RyYWN0IGNsYXNzIEFyaXRobWV0aWNJbnN0cnVjdGlvbiBleHRlbmRzIEluc3RydWN0aW9uCi0gIGltcGxlbWVudHMgVHlwZWRJbnN0cnVjdGlvbiwgU3RhY2tQcm9kdWNlciwgU3RhY2tDb25zdW1lciB7Ci0gIC8qKgotICAgKiBFbXB0eSBjb25zdHJ1Y3RvciBuZWVkZWQgZm9yIHRoZSBDbGFzcy5uZXdJbnN0YW5jZSgpIHN0YXRlbWVudCBpbgotICAgKiBJbnN0cnVjdGlvbi5yZWFkSW5zdHJ1Y3Rpb24oKS4gTm90IHRvIGJlIHVzZWQgb3RoZXJ3aXNlLgotICAgKi8KLSAgQXJpdGhtZXRpY0luc3RydWN0aW9uKCkge30KLQotICAvKioKLSAgICogQHBhcmFtIG9wY29kZSBvZiBpbnN0cnVjdGlvbgotICAgKi8KLSAgcHJvdGVjdGVkIEFyaXRobWV0aWNJbnN0cnVjdGlvbihzaG9ydCBvcGNvZGUpIHsKLSAgICBzdXBlcihvcGNvZGUsIChzaG9ydCkxKTsKLSAgfQotCi0gIC8qKiBAcmV0dXJuIHR5cGUgYXNzb2NpYXRlZCB3aXRoIHRoZSBpbnN0cnVjdGlvbgotICAgKi8KLSAgcHVibGljIFR5cGUgZ2V0VHlwZShDb25zdGFudFBvb2xHZW4gY3ApIHsKLSAgICBzd2l0Y2gob3Bjb2RlKSB7Ci0gICAgY2FzZSBDb25zdGFudHMuREFERDogY2FzZSBDb25zdGFudHMuRERJVjogY2FzZSBDb25zdGFudHMuRE1VTDoKLSAgICBjYXNlIENvbnN0YW50cy5ETkVHOiBjYXNlIENvbnN0YW50cy5EUkVNOiBjYXNlIENvbnN0YW50cy5EU1VCOgotICAgICAgcmV0dXJuIFR5cGUuRE9VQkxFOwotCi0gICAgY2FzZSBDb25zdGFudHMuRkFERDogY2FzZSBDb25zdGFudHMuRkRJVjogY2FzZSBDb25zdGFudHMuRk1VTDoKLSAgICBjYXNlIENvbnN0YW50cy5GTkVHOiBjYXNlIENvbnN0YW50cy5GUkVNOiBjYXNlIENvbnN0YW50cy5GU1VCOgotICAgICAgcmV0dXJuIFR5cGUuRkxPQVQ7Ci0KLSAgICBjYXNlIENvbnN0YW50cy5JQUREOiBjYXNlIENvbnN0YW50cy5JQU5EOiBjYXNlIENvbnN0YW50cy5JRElWOgotICAgIGNhc2UgQ29uc3RhbnRzLklNVUw6IGNhc2UgQ29uc3RhbnRzLklORUc6IGNhc2UgQ29uc3RhbnRzLklPUjogY2FzZSBDb25zdGFudHMuSVJFTToKLSAgICBjYXNlIENvbnN0YW50cy5JU0hMOiBjYXNlIENvbnN0YW50cy5JU0hSOiBjYXNlIENvbnN0YW50cy5JU1VCOgotICAgIGNhc2UgQ29uc3RhbnRzLklVU0hSOiBjYXNlIENvbnN0YW50cy5JWE9SOgotICAgICAgcmV0dXJuIFR5cGUuSU5UOwotCi0gICAgY2FzZSBDb25zdGFudHMuTEFERDogY2FzZSBDb25zdGFudHMuTEFORDogY2FzZSBDb25zdGFudHMuTERJVjoKLSAgICBjYXNlIENvbnN0YW50cy5MTVVMOiBjYXNlIENvbnN0YW50cy5MTkVHOiBjYXNlIENvbnN0YW50cy5MT1I6IGNhc2UgQ29uc3RhbnRzLkxSRU06Ci0gICAgY2FzZSBDb25zdGFudHMuTFNITDogY2FzZSBDb25zdGFudHMuTFNIUjogY2FzZSBDb25zdGFudHMuTFNVQjoKLSAgICBjYXNlIENvbnN0YW50cy5MVVNIUjogY2FzZSBDb25zdGFudHMuTFhPUjoKLSAgICAgIHJldHVybiBUeXBlLkxPTkc7Ci0KLSAgICBkZWZhdWx0OiAvLyBOZXZlciByZWFjaGVkCi0gICAgICB0aHJvdyBuZXcgQ2xhc3NHZW5FeGNlcHRpb24oIlVua25vd24gdHlwZSAiICsgb3Bjb2RlKTsKLSAgICB9Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0FycmF5SW5zdHJ1Y3Rpb24uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0FycmF5SW5zdHJ1Y3Rpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNWI5MDJjMy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9BcnJheUluc3RydWN0aW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMDkgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotLyoqCi0gKiBTdXBlciBjbGFzcyBmb3IgaW5zdHJ1Y3Rpb25zIGRlYWxpbmcgd2l0aCBhcnJheSBhY2Nlc3Mgc3VjaCBhcyBJQUxPQUQuCi0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGFic3RyYWN0IGNsYXNzIEFycmF5SW5zdHJ1Y3Rpb24gZXh0ZW5kcyBJbnN0cnVjdGlvbgotICBpbXBsZW1lbnRzIEV4Y2VwdGlvblRocm93ZXIsIFR5cGVkSW5zdHJ1Y3Rpb24gewotICAvKioKLSAgICogRW1wdHkgY29uc3RydWN0b3IgbmVlZGVkIGZvciB0aGUgQ2xhc3MubmV3SW5zdGFuY2UoKSBzdGF0ZW1lbnQgaW4KLSAgICogSW5zdHJ1Y3Rpb24ucmVhZEluc3RydWN0aW9uKCkuIE5vdCB0byBiZSB1c2VkIG90aGVyd2lzZS4KLSAgICovCi0gIEFycmF5SW5zdHJ1Y3Rpb24oKSB7fQotCi0gIC8qKgotICAgKiBAcGFyYW0gb3Bjb2RlIG9mIGluc3RydWN0aW9uCi0gICAqLwotICBwcm90ZWN0ZWQgQXJyYXlJbnN0cnVjdGlvbihzaG9ydCBvcGNvZGUpIHsKLSAgICBzdXBlcihvcGNvZGUsIChzaG9ydCkxKTsKLSAgfQotCi0gIHB1YmxpYyBDbGFzc1tdIGdldEV4Y2VwdGlvbnMoKSB7Ci0gICAgcmV0dXJuIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkV4Y2VwdGlvbkNvbnN0YW50cy5FWENTX0FSUkFZX0VYQ0VQVElPTjsKLSAgfQotCi0gIC8qKiBAcmV0dXJuIHR5cGUgYXNzb2NpYXRlZCB3aXRoIHRoZSBpbnN0cnVjdGlvbgotICAgKi8KLSAgcHVibGljIFR5cGUgZ2V0VHlwZShDb25zdGFudFBvb2xHZW4gY3ApIHsKLSAgICBzd2l0Y2gob3Bjb2RlKSB7Ci0gICAgY2FzZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuSUFMT0FEOiBjYXNlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5JQVNUT1JFOgotICAgICAgcmV0dXJuIFR5cGUuSU5UOwotICAgIGNhc2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkNBTE9BRDogY2FzZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuQ0FTVE9SRToKLSAgICAgIHJldHVybiBUeXBlLkNIQVI7Ci0gICAgY2FzZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuQkFMT0FEOiBjYXNlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5CQVNUT1JFOgotICAgICAgcmV0dXJuIFR5cGUuQllURTsKLSAgICBjYXNlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5TQUxPQUQ6IGNhc2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLlNBU1RPUkU6Ci0gICAgICByZXR1cm4gVHlwZS5TSE9SVDsKLSAgICBjYXNlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5MQUxPQUQ6IGNhc2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkxBU1RPUkU6Ci0gICAgICByZXR1cm4gVHlwZS5MT05HOwotICAgIGNhc2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkRBTE9BRDogY2FzZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuREFTVE9SRToKLSAgICAgIHJldHVybiBUeXBlLkRPVUJMRTsKLSAgICBjYXNlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5GQUxPQUQ6IGNhc2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkZBU1RPUkU6Ci0gICAgICByZXR1cm4gVHlwZS5GTE9BVDsKLSAgICBjYXNlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5BQUxPQUQ6IGNhc2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkFBU1RPUkU6Ci0gICAgICByZXR1cm4gVHlwZS5PQkpFQ1Q7Ci0KLSAgICBkZWZhdWx0OiB0aHJvdyBuZXcgQ2xhc3NHZW5FeGNlcHRpb24oIk9vcHM6IHVua25vd24gY2FzZSBpbiBzd2l0Y2giICsgb3Bjb2RlKTsKLSAgICB9Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0FycmF5VHlwZS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvQXJyYXlUeXBlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDU0YmQ4M2EuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvQXJyYXlUeXBlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNTkgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHM7Ci0KLS8qKgotICogRGVub3RlcyBhcnJheSB0eXBlLCBzdWNoIGFzIGludFtdW10KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgQXJyYXlUeXBlIGV4dGVuZHMgUmVmZXJlbmNlVHlwZSB7Ci0gIHByaXZhdGUgaW50ICBkaW1lbnNpb25zOwotICBwcml2YXRlIFR5cGUgYmFzaWNfdHlwZTsKLQotICAvKioKLSAgICogQ29udmVuaWVuY2UgY29uc3RydWN0b3IgZm9yIGFycmF5IHR5cGUsIGUuZy4gaW50W10KLSAgICoKLSAgICogQHBhcmFtIHR5cGUgYXJyYXkgdHlwZSwgZS5nLiBUX0lOVAotICAgKi8KLSAgcHVibGljIEFycmF5VHlwZShieXRlIHR5cGUsIGludCBkaW1lbnNpb25zKSB7Ci0gICAgdGhpcyhCYXNpY1R5cGUuZ2V0VHlwZSh0eXBlKSwgZGltZW5zaW9ucyk7Ci0gIH0KLQotICAvKioKLSAgICogQ29udmVuaWVuY2UgY29uc3RydWN0b3IgZm9yIHJlZmVyZW5jZSBhcnJheSB0eXBlLCBlLmcuIE9iamVjdFtdCi0gICAqCi0gICAqIEBwYXJhbSBjbGFzc19uYW1lIGNvbXBsZXRlIG5hbWUgb2YgY2xhc3MgKGphdmEubGFuZy5TdHJpbmcsIGUuZy4pCi0gICAqLwotICBwdWJsaWMgQXJyYXlUeXBlKFN0cmluZyBjbGFzc19uYW1lLCBpbnQgZGltZW5zaW9ucykgewotICAgIHRoaXMobmV3IE9iamVjdFR5cGUoY2xhc3NfbmFtZSksIGRpbWVuc2lvbnMpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdG9yIGZvciBhcnJheSBvZiBnaXZlbiB0eXBlCi0gICAqCi0gICAqIEBwYXJhbSB0eXBlIHR5cGUgb2YgYXJyYXkgKG1heSBiZSBhbiBhcnJheSBpdHNlbGYpCi0gICAqLwotICBwdWJsaWMgQXJyYXlUeXBlKFR5cGUgdHlwZSwgaW50IGRpbWVuc2lvbnMpIHsKLSAgICBzdXBlcihDb25zdGFudHMuVF9BUlJBWSwgIjxkdW1teT4iKTsKLQotICAgIGlmKChkaW1lbnNpb25zIDwgMSkgfHwgKGRpbWVuc2lvbnMgPiBDb25zdGFudHMuTUFYX0JZVEUpKQotICAgICAgdGhyb3cgbmV3IENsYXNzR2VuRXhjZXB0aW9uKCJJbnZhbGlkIG51bWJlciBvZiBkaW1lbnNpb25zOiAiICsgZGltZW5zaW9ucyk7Ci0KLSAgICBzd2l0Y2godHlwZS5nZXRUeXBlKCkpIHsKLSAgICBjYXNlIENvbnN0YW50cy5UX0FSUkFZOgotICAgICAgQXJyYXlUeXBlIGFycmF5ID0gKEFycmF5VHlwZSl0eXBlOwotICAgICAgdGhpcy5kaW1lbnNpb25zID0gZGltZW5zaW9ucyArIGFycmF5LmRpbWVuc2lvbnM7Ci0gICAgICBiYXNpY190eXBlICAgICAgPSBhcnJheS5iYXNpY190eXBlOwotICAgICAgYnJlYWs7Ci0KLSAgICBjYXNlIENvbnN0YW50cy5UX1ZPSUQ6Ci0gICAgICB0aHJvdyBuZXcgQ2xhc3NHZW5FeGNlcHRpb24oIkludmFsaWQgdHlwZTogdm9pZFtdIik7Ci0KLSAgICBkZWZhdWx0OiAvLyBCYXNpYyB0eXBlIG9yIHJlZmVyZW5jZQotICAgICAgdGhpcy5kaW1lbnNpb25zID0gZGltZW5zaW9uczsKLSAgICAgIGJhc2ljX3R5cGUgPSB0eXBlOwotICAgICAgYnJlYWs7Ci0gICAgfQotCi0gICAgU3RyaW5nQnVmZmVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLSAgICBmb3IoaW50IGk9MDsgaSA8IHRoaXMuZGltZW5zaW9uczsgaSsrKQotICAgICAgYnVmLmFwcGVuZCgnWycpOwotCi0gICAgYnVmLmFwcGVuZChiYXNpY190eXBlLmdldFNpZ25hdHVyZSgpKTsKLQotICAgIHNpZ25hdHVyZSA9IGJ1Zi50b1N0cmluZygpOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gYmFzaWMgdHlwZSBvZiBhcnJheSwgaS5lLiwgZm9yIGludFtdW11bXSB0aGUgYmFzaWMgdHlwZSBpcyBpbnQKLSAgICovCi0gIHB1YmxpYyBUeXBlIGdldEJhc2ljVHlwZSgpIHsKLSAgICByZXR1cm4gYmFzaWNfdHlwZTsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIGVsZW1lbnQgdHlwZSBvZiBhcnJheSwgaS5lLiwgZm9yIGludFtdW11bXSB0aGUgZWxlbWVudCB0eXBlIGlzIGludFtdW10KLSAgICovCi0gIHB1YmxpYyBUeXBlIGdldEVsZW1lbnRUeXBlKCkgewotICAgIGlmKGRpbWVuc2lvbnMgPT0gMSkKLSAgICAgIHJldHVybiBiYXNpY190eXBlOwotICAgIGVsc2UKLSAgICAgIHJldHVybiBuZXcgQXJyYXlUeXBlKGJhc2ljX3R5cGUsIGRpbWVuc2lvbnMgLSAxKTsKLSAgfQotCi0gIC8qKiBAcmV0dXJuIG51bWJlciBvZiBkaW1lbnNpb25zIG9mIGFycmF5Ci0gICAqLwotICBwdWJsaWMgaW50IGdldERpbWVuc2lvbnMoKSB7IHJldHVybiBkaW1lbnNpb25zOyB9Ci0KLSAgLyoqIEByZXR1cm4gYSBoYXNoIGNvZGUgdmFsdWUgZm9yIHRoZSBvYmplY3QuCi0gICAqLwotICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeyByZXR1cm4gYmFzaWNfdHlwZS5oYXNoQ29kZSgpIF4gZGltZW5zaW9uczsgfQotCi0gIC8qKiBAcmV0dXJuIHRydWUgaWYgYm90aCB0eXBlIG9iamVjdHMgcmVmZXIgdG8gdGhlIHNhbWUgYXJyYXkgdHlwZS4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgdHlwZSkgewotICAgIGlmKHR5cGUgaW5zdGFuY2VvZiBBcnJheVR5cGUpIHsKLSAgICAgIEFycmF5VHlwZSBhcnJheSA9IChBcnJheVR5cGUpdHlwZTsKLSAgICAgIHJldHVybiAoYXJyYXkuZGltZW5zaW9ucyA9PSBkaW1lbnNpb25zKSAmJiBhcnJheS5iYXNpY190eXBlLmVxdWFscyhiYXNpY190eXBlKTsKLSAgICB9IGVsc2UKLSAgICAgIHJldHVybiBmYWxzZTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvQkFMT0FELmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9CQUxPQUQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOWVkOWFmYS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9CQUxPQUQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDkwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8qKgotICogQkFMT0FEIC0gTG9hZCBieXRlIG9yIGJvb2xlYW4gZnJvbSBhcnJheQotICogPFBSRT5TdGFjazogLi4uLCBhcnJheXJlZiwgaW5kZXggLSZndDsgLi4uLCB2YWx1ZTwvUFJFPgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBCQUxPQUQgZXh0ZW5kcyBBcnJheUluc3RydWN0aW9uIGltcGxlbWVudHMgU3RhY2tQcm9kdWNlciB7Ci0gIC8qKiBMb2FkIGJ5dGUgb3IgYm9vbGVhbiBmcm9tIGFycmF5Ci0gICAqLwotICBwdWJsaWMgQkFMT0FEKCkgewotICAgIHN1cGVyKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5CQUxPQUQpOwotICB9Ci0KLQotICAvKioKLSAgICogQ2FsbCBjb3JyZXNwb25kaW5nIHZpc2l0b3IgbWV0aG9kKHMpLiBUaGUgb3JkZXIgaXM6Ci0gICAqIENhbGwgdmlzaXRvciBtZXRob2RzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMgZmlyc3QsIHRoZW4KLSAgICogY2FsbCBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY2xhc3MgaGllcmFyY2h5IGluIGRlc2NlbmRpbmcgb3JkZXIsCi0gICAqIGkuZS4sIHRoZSBtb3N0IHNwZWNpZmljIHZpc2l0WFhYKCkgY2FsbCBjb21lcyBsYXN0LgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRTdGFja1Byb2R1Y2VyKHRoaXMpOwotICAgIHYudmlzaXRFeGNlcHRpb25UaHJvd2VyKHRoaXMpOwotICAgIHYudmlzaXRUeXBlZEluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRBcnJheUluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRCQUxPQUQodGhpcyk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0JBU1RPUkUuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0JBU1RPUkUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMzAwNzE5ZS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9CQVNUT1JFLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5MCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIEJBU1RPUkUgLSAgU3RvcmUgaW50byBieXRlIG9yIGJvb2xlYW4gYXJyYXkKLSAqIDxQUkU+U3RhY2s6IC4uLiwgYXJyYXlyZWYsIGluZGV4LCB2YWx1ZSAtJmd0OyAuLi48L1BSRT4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgQkFTVE9SRSBleHRlbmRzIEFycmF5SW5zdHJ1Y3Rpb24gaW1wbGVtZW50cyBTdGFja0NvbnN1bWVyIHsKLSAgLyoqIFN0b3JlIGJ5dGUgb3IgYm9vbGVhbiBpbnRvIGFycmF5Ci0gICAqLwotICBwdWJsaWMgQkFTVE9SRSgpIHsKLSAgICBzdXBlcihjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuQkFTVE9SRSk7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBDYWxsIGNvcnJlc3BvbmRpbmcgdmlzaXRvciBtZXRob2QocykuIFRoZSBvcmRlciBpczoKLSAgICogQ2FsbCB2aXNpdG9yIG1ldGhvZHMgb2YgaW1wbGVtZW50ZWQgaW50ZXJmYWNlcyBmaXJzdCwgdGhlbgotICAgKiBjYWxsIG1ldGhvZHMgYWNjb3JkaW5nIHRvIHRoZSBjbGFzcyBoaWVyYXJjaHkgaW4gZGVzY2VuZGluZyBvcmRlciwKLSAgICogaS5lLiwgdGhlIG1vc3Qgc3BlY2lmaWMgdmlzaXRYWFgoKSBjYWxsIGNvbWVzIGxhc3QuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgdi52aXNpdFN0YWNrQ29uc3VtZXIodGhpcyk7Ci0gICAgdi52aXNpdEV4Y2VwdGlvblRocm93ZXIodGhpcyk7Ci0gICAgdi52aXNpdFR5cGVkSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdEFycmF5SW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdEJBU1RPUkUodGhpcyk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0JJUFVTSC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvQklQVVNILmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDBlZDk5NjIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvQklQVVNILmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMzQgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotaW1wb3J0IGphdmEuaW8uKjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC51dGlsLkJ5dGVTZXF1ZW5jZTsKLQotLyoqCi0gKiBCSVBVU0ggLSBQdXNoIGJ5dGUgb24gc3RhY2sKLSAqCi0gKiA8UFJFPlN0YWNrOiAuLi4gLSZndDsgLi4uLCB2YWx1ZTwvUFJFPgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBCSVBVU0ggZXh0ZW5kcyBJbnN0cnVjdGlvbiBpbXBsZW1lbnRzIENvbnN0YW50UHVzaEluc3RydWN0aW9uIHsKLSAgcHJpdmF0ZSBieXRlIGI7Ci0KLSAgLyoqCi0gICAqIEVtcHR5IGNvbnN0cnVjdG9yIG5lZWRlZCBmb3IgdGhlIENsYXNzLm5ld0luc3RhbmNlKCkgc3RhdGVtZW50IGluCi0gICAqIEluc3RydWN0aW9uLnJlYWRJbnN0cnVjdGlvbigpLiBOb3QgdG8gYmUgdXNlZCBvdGhlcndpc2UuCi0gICAqLwotICBCSVBVU0goKSB7fQotCi0gIC8qKiBQdXNoIGJ5dGUgb24gc3RhY2sKLSAgICovCi0gIHB1YmxpYyBCSVBVU0goYnl0ZSBiKSB7Ci0gICAgc3VwZXIoY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkJJUFVTSCwgKHNob3J0KTIpOwotICAgIHRoaXMuYiA9IGI7Ci0gIH0KLQotICAvKioKLSAgICogRHVtcCBpbnN0cnVjdGlvbiBhcyBieXRlIGNvZGUgdG8gc3RyZWFtIG91dC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGR1bXAoRGF0YU91dHB1dFN0cmVhbSBvdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgc3VwZXIuZHVtcChvdXQpOwotICAgIG91dC53cml0ZUJ5dGUoYik7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBtbmVtb25pYyBmb3IgaW5zdHJ1Y3Rpb24KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoYm9vbGVhbiB2ZXJib3NlKSB7Ci0gICAgcmV0dXJuIHN1cGVyLnRvU3RyaW5nKHZlcmJvc2UpICsgIiAiICsgYjsKLSAgfQotCi0gIC8qKgotICAgKiBSZWFkIG5lZWRlZCBkYXRhIChlLmcuIGluZGV4KSBmcm9tIGZpbGUuCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBpbml0RnJvbUZpbGUoQnl0ZVNlcXVlbmNlIGJ5dGVzLCBib29sZWFuIHdpZGUpIHRocm93cyBJT0V4Y2VwdGlvbgotICB7Ci0gICAgbGVuZ3RoID0gMjsKLSAgICBiICAgICAgPSBieXRlcy5yZWFkQnl0ZSgpOwotICB9Ci0KLSAgcHVibGljIE51bWJlciBnZXRWYWx1ZSgpIHsgcmV0dXJuIG5ldyBJbnRlZ2VyKGIpOyB9Ci0KLSAgLyoqIEByZXR1cm4gVHlwZS5CWVRFCi0gICAqLwotICBwdWJsaWMgVHlwZSBnZXRUeXBlKENvbnN0YW50UG9vbEdlbiBjcCkgewotICAgIHJldHVybiBUeXBlLkJZVEU7Ci0gIH0KLQotICAvKioKLSAgICogQ2FsbCBjb3JyZXNwb25kaW5nIHZpc2l0b3IgbWV0aG9kKHMpLiBUaGUgb3JkZXIgaXM6Ci0gICAqIENhbGwgdmlzaXRvciBtZXRob2RzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMgZmlyc3QsIHRoZW4KLSAgICogY2FsbCBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY2xhc3MgaGllcmFyY2h5IGluIGRlc2NlbmRpbmcgb3JkZXIsCi0gICAqIGkuZS4sIHRoZSBtb3N0IHNwZWNpZmljIHZpc2l0WFhYKCkgY2FsbCBjb21lcyBsYXN0LgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRQdXNoSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdFN0YWNrUHJvZHVjZXIodGhpcyk7Ci0gICAgdi52aXNpdFR5cGVkSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdENvbnN0YW50UHVzaEluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRCSVBVU0godGhpcyk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0JSRUFLUE9JTlQuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0JSRUFLUE9JTlQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDQ5MGJlNi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9CUkVBS1BPSU5ULmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4MiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIEJSRUFLUE9JTlQsIEpWTSBkZXBlbmRlbnQsIGlnbm9yZWQgYnkgZGVmYXVsdAotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBCUkVBS1BPSU5UIGV4dGVuZHMgSW5zdHJ1Y3Rpb24gewotICBwdWJsaWMgQlJFQUtQT0lOVCgpIHsKLSAgICBzdXBlcihjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuQlJFQUtQT0lOVCwgKHNob3J0KTEpOwotICB9Ci0KLSAgLyoqCi0gICAqIENhbGwgY29ycmVzcG9uZGluZyB2aXNpdG9yIG1ldGhvZChzKS4gVGhlIG9yZGVyIGlzOgotICAgKiBDYWxsIHZpc2l0b3IgbWV0aG9kcyBvZiBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzIGZpcnN0LCB0aGVuCi0gICAqIGNhbGwgbWV0aG9kcyBhY2NvcmRpbmcgdG8gdGhlIGNsYXNzIGhpZXJhcmNoeSBpbiBkZXNjZW5kaW5nIG9yZGVyLAotICAgKiBpLmUuLCB0aGUgbW9zdCBzcGVjaWZpYyB2aXNpdFhYWCgpIGNhbGwgY29tZXMgbGFzdC4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0QlJFQUtQT0lOVCh0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvQmFzaWNUeXBlLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9CYXNpY1R5cGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYzczNDBhNi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9CYXNpY1R5cGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExMCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50czsKLQotLyoqCi0gKiBEZW5vdGVzIGJhc2ljIHR5cGUgc3VjaCBhcyBpbnQuCi0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIEJhc2ljVHlwZSBleHRlbmRzIFR5cGUgewotICAvKioKLSAgICogQ29uc3RydWN0b3IgZm9yIGJhc2ljIHR5cGVzIHN1Y2ggYXMgaW50LCBsb25nLCBgdm9pZCcKLSAgICoKLSAgICogQHBhcmFtIHR5cGUgb25lIG9mIFRfSU5ULCBUX0JPT0xFQU4sIC4uLiwgVF9WT0lECi0gICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzCi0gICAqLwotICBCYXNpY1R5cGUoYnl0ZSB0eXBlKSB7Ci0gICAgc3VwZXIodHlwZSwgQ29uc3RhbnRzLlNIT1JUX1RZUEVfTkFNRVNbdHlwZV0pOwotCi0gICAgaWYoKHR5cGUgPCBDb25zdGFudHMuVF9CT09MRUFOKSB8fCAodHlwZSA+IENvbnN0YW50cy5UX1ZPSUQpKQotICAgICAgdGhyb3cgbmV3IENsYXNzR2VuRXhjZXB0aW9uKCJJbnZhbGlkIHR5cGU6ICIgKyB0eXBlKTsKLSAgfQotCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgQmFzaWNUeXBlIGdldFR5cGUoYnl0ZSB0eXBlKSB7Ci0gICAgc3dpdGNoKHR5cGUpIHsKLSAgICBjYXNlIENvbnN0YW50cy5UX1ZPSUQ6ICAgIHJldHVybiBWT0lEOwotICAgIGNhc2UgQ29uc3RhbnRzLlRfQk9PTEVBTjogcmV0dXJuIEJPT0xFQU47Ci0gICAgY2FzZSBDb25zdGFudHMuVF9CWVRFOiAgICByZXR1cm4gQllURTsKLSAgICBjYXNlIENvbnN0YW50cy5UX1NIT1JUOiAgIHJldHVybiBTSE9SVDsKLSAgICBjYXNlIENvbnN0YW50cy5UX0NIQVI6ICAgIHJldHVybiBDSEFSOwotICAgIGNhc2UgQ29uc3RhbnRzLlRfSU5UOiAgICAgcmV0dXJuIElOVDsKLSAgICBjYXNlIENvbnN0YW50cy5UX0xPTkc6ICAgIHJldHVybiBMT05HOwotICAgIGNhc2UgQ29uc3RhbnRzLlRfRE9VQkxFOiAgcmV0dXJuIERPVUJMRTsKLSAgICBjYXNlIENvbnN0YW50cy5UX0ZMT0FUOiAgIHJldHVybiBGTE9BVDsKLQotICAgIGRlZmF1bHQ6Ci0gICAgICB0aHJvdyBuZXcgQ2xhc3NHZW5FeGNlcHRpb24oIkludmFsaWQgdHlwZTogIiArIHR5cGUpOwotICAgIH0KLSAgfQotCi0gIC8qKiBAcmV0dXJuIHRydWUgaWYgYm90aCB0eXBlIG9iamVjdHMgcmVmZXIgdG8gdGhlIHNhbWUgdHlwZQotICAgKi8KLSAgQE92ZXJyaWRlCi0gIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgdHlwZSkgewotICAgIHJldHVybiAodHlwZSBpbnN0YW5jZW9mIEJhc2ljVHlwZSk/Ci0gICAgICAoKEJhc2ljVHlwZSl0eXBlKS50eXBlID09IHRoaXMudHlwZSA6IGZhbHNlOwotICB9Ci0KLSAgQE92ZXJyaWRlCi0gIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7Ci0gICAgICByZXR1cm4gdHlwZTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvQnJhbmNoSGFuZGxlLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9CcmFuY2hIYW5kbGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMWY3Y2JiMC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9CcmFuY2hIYW5kbGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE1MyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIEJyYW5jaEhhbmRsZSBpcyByZXR1cm5lZCBieSBzcGVjaWFsaXplZCBJbnN0cnVjdGlvbkxpc3QuYXBwZW5kKCkgd2hlbmV2ZXIgYQotICogQnJhbmNoSW5zdHJ1Y3Rpb24gaXMgYXBwZW5kZWQuIFRoaXMgaXMgdXNlZnVsIHdoZW4gdGhlIHRhcmdldCBvZiB0aGlzCi0gKiBpbnN0cnVjdGlvbiBpcyBub3Qga25vd24gYXQgdGltZSBvZiBjcmVhdGlvbiBhbmQgbXVzdCBiZSBzZXQgbGF0ZXIKLSAqIHZpYSBzZXRUYXJnZXQoKS4KLSAqCi0gKiBAc2VlIEluc3RydWN0aW9uSGFuZGxlCi0gKiBAc2VlIEluc3RydWN0aW9uCi0gKiBAc2VlIEluc3RydWN0aW9uTGlzdAotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIEJyYW5jaEhhbmRsZSBleHRlbmRzIEluc3RydWN0aW9uSGFuZGxlIHsKLSAgcHJpdmF0ZSBCcmFuY2hJbnN0cnVjdGlvbiBiaTsgLy8gQW4gYWxpYXMgaW4gZmFjdCwgYnV0IHNhdmVzIGxvdHMgb2YgY2FzdHMKLQotICBwcml2YXRlIEJyYW5jaEhhbmRsZShCcmFuY2hJbnN0cnVjdGlvbiBpKSB7Ci0gICAgc3VwZXIoaSk7Ci0gICAgYmkgPSBpOwotICB9Ci0KLSAgLyoqIEZhY3RvcnkgbWV0aG9kcy4KLSAgICovCi0gIHByaXZhdGUgc3RhdGljIEJyYW5jaEhhbmRsZSBiaF9saXN0ID0gbnVsbDsgLy8gTGlzdCBvZiByZXVzYWJsZSBoYW5kbGVzCi0KLSAgc3RhdGljIGZpbmFsIEJyYW5jaEhhbmRsZSBnZXRCcmFuY2hIYW5kbGUoQnJhbmNoSW5zdHJ1Y3Rpb24gaSkgewotICAgIGlmKGJoX2xpc3QgPT0gbnVsbCkKLSAgICAgIHJldHVybiBuZXcgQnJhbmNoSGFuZGxlKGkpOwotICAgIGVsc2UgewotICAgICAgQnJhbmNoSGFuZGxlIGJoID0gYmhfbGlzdDsKLSAgICAgIGJoX2xpc3QgPSAoQnJhbmNoSGFuZGxlKWJoLm5leHQ7Ci0KLSAgICAgIGJoLnNldEluc3RydWN0aW9uKGkpOwotCi0gICAgICByZXR1cm4gYmg7Ci0gICAgfQotICB9Ci0KLSAgLyoqIEhhbmRsZSBhZGRzIGl0c2VsZiB0byB0aGUgbGlzdCBvZiByZXN1YWJsZSBoYW5kbGVzLgotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgYWRkSGFuZGxlKCkgewotICAgIG5leHQgICAgPSBiaF9saXN0OwotICAgIGJoX2xpc3QgPSB0aGlzOwotICB9Ci0KLSAgLyogT3ZlcnJpZGUgSW5zdHJ1Y3Rpb25IYW5kbGUgbWV0aG9kczogZGVsZWdhdGUgdG8gYnJhbmNoIGluc3RydWN0aW9uLgotICAgKiBUaHJvdWdoIHRoaXMgb3ZlcnJpZGluZyBhbGwgYWNjZXNzIHRvIHRoZSBwcml2YXRlIGlfcG9zaXRpb24gZmllbGQgc2hvdWxkCi0gICAqIGJlIHByZXZlbnRlZC4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0UG9zaXRpb24oKSB7IHJldHVybiBiaS5wb3NpdGlvbjsgfQotCi0gIHZvaWQgc2V0UG9zaXRpb24oaW50IHBvcykgewotICAgIGlfcG9zaXRpb24gPSBiaS5wb3NpdGlvbiA9IHBvczsKLSAgfQotCi0gIHByb3RlY3RlZCBpbnQgdXBkYXRlUG9zaXRpb24oaW50IG9mZnNldCwgaW50IG1heF9vZmZzZXQpIHsKLSAgICBpbnQgeCA9IGJpLnVwZGF0ZVBvc2l0aW9uKG9mZnNldCwgbWF4X29mZnNldCk7Ci0gICAgaV9wb3NpdGlvbiA9IGJpLnBvc2l0aW9uOwotICAgIHJldHVybiB4OwotICB9Ci0KLSAgLyoqCi0gICAqIFBhc3MgbmV3IHRhcmdldCB0byBpbnN0cnVjdGlvbi4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFRhcmdldChJbnN0cnVjdGlvbkhhbmRsZSBpaCkgewotICAgIGJpLnNldFRhcmdldChpaCk7Ci0gIH0KLQotICAvKioKLSAgICogVXBkYXRlIHRhcmdldCBvZiBpbnN0cnVjdGlvbi4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHVwZGF0ZVRhcmdldChJbnN0cnVjdGlvbkhhbmRsZSBvbGRfaWgsIEluc3RydWN0aW9uSGFuZGxlIG5ld19paCkgewotICAgIGJpLnVwZGF0ZVRhcmdldChvbGRfaWgsIG5ld19paCk7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiB0YXJnZXQgb2YgaW5zdHJ1Y3Rpb24uCi0gICAqLwotICBwdWJsaWMgSW5zdHJ1Y3Rpb25IYW5kbGUgZ2V0VGFyZ2V0KCkgewotICAgIHJldHVybiBiaS5nZXRUYXJnZXQoKTsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgbmV3IGNvbnRlbnRzLiBPbGQgaW5zdHJ1Y3Rpb24gaXMgZGlzcG9zZWQgYW5kIG1heSBub3QgYmUgdXNlZCBhbnltb3JlLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0SW5zdHJ1Y3Rpb24oSW5zdHJ1Y3Rpb24gaSkgewotICAgIHN1cGVyLnNldEluc3RydWN0aW9uKGkpOwotCi0gICAgaWYoIShpIGluc3RhbmNlb2YgQnJhbmNoSW5zdHJ1Y3Rpb24pKQotICAgICAgdGhyb3cgbmV3IENsYXNzR2VuRXhjZXB0aW9uKCJBc3NpZ25pbmcgIiArIGkgKwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgdG8gYnJhbmNoIGhhbmRsZSB3aGljaCBpcyBub3QgYSBicmFuY2ggaW5zdHJ1Y3Rpb24iKTsKLQotICAgIGJpID0gKEJyYW5jaEluc3RydWN0aW9uKWk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0JyYW5jaEluc3RydWN0aW9uLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9CcmFuY2hJbnN0cnVjdGlvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzNjk2MGY4Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0JyYW5jaEluc3RydWN0aW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyNjkgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotaW1wb3J0IGphdmEuaW8uKjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC51dGlsLkJ5dGVTZXF1ZW5jZTsKLQotLyoqCi0gKiBBYnN0cmFjdCBzdXBlciBjbGFzcyBmb3IgYnJhbmNoaW5nIGluc3RydWN0aW9ucyBsaWtlIEdPVE8sIElGRVEsIGV0Yy4uCi0gKiBCcmFuY2ggaW5zdHJ1Y3Rpb25zIG1heSBoYXZlIGEgdmFyaWFibGUgbGVuZ3RoLCBuYW1lbHkgR09UTywgSlNSLAotICogTE9PS1VQU1dJVENIIGFuZCBUQUJMRVNXSVRDSC4KLSAqCi0gKiBAc2VlIEluc3RydWN0aW9uTGlzdAotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGFic3RyYWN0IGNsYXNzIEJyYW5jaEluc3RydWN0aW9uIGV4dGVuZHMgSW5zdHJ1Y3Rpb24gaW1wbGVtZW50cyBJbnN0cnVjdGlvblRhcmdldGVyIHsKLSAgcHJvdGVjdGVkIGludCAgICAgICAgICAgICAgIGluZGV4OyAgICAvLyBCcmFuY2ggdGFyZ2V0IHJlbGF0aXZlIHRvIHRoaXMgaW5zdHJ1Y3Rpb24KLSAgcHJvdGVjdGVkIEluc3RydWN0aW9uSGFuZGxlIHRhcmdldDsgICAvLyBUYXJnZXQgb2JqZWN0IGluIGluc3RydWN0aW9uIGxpc3QKLSAgcHJvdGVjdGVkIGludCAgICAgICAgICAgICAgIHBvc2l0aW9uOyAvLyBCeXRlIGNvZGUgb2Zmc2V0Ci0KLSAgLyoqCi0gICAqIEVtcHR5IGNvbnN0cnVjdG9yIG5lZWRlZCBmb3IgdGhlIENsYXNzLm5ld0luc3RhbmNlKCkgc3RhdGVtZW50IGluCi0gICAqIEluc3RydWN0aW9uLnJlYWRJbnN0cnVjdGlvbigpLiBOb3QgdG8gYmUgdXNlZCBvdGhlcndpc2UuCi0gICAqLwotICBCcmFuY2hJbnN0cnVjdGlvbigpIHt9Ci0KLSAgLyoqIENvbW1vbiBzdXBlciBjb25zdHJ1Y3RvcgotICAgKiBAcGFyYW0gb3Bjb2RlZSBJbnN0cnVjdGlvbiBvcGNvZGUKLSAgICogQHBhcmFtIHRhcmdldCBpbnN0cnVjdGlvbiB0byBicmFuY2ggdG8KLSAgICovCi0gIHByb3RlY3RlZCBCcmFuY2hJbnN0cnVjdGlvbihzaG9ydCBvcGNvZGUsIEluc3RydWN0aW9uSGFuZGxlIHRhcmdldCkgewotICAgIHN1cGVyKG9wY29kZSwgKHNob3J0KTMpOwotICAgIHNldFRhcmdldCh0YXJnZXQpOwotICB9Ci0KLSAgLyoqCi0gICAqIER1bXAgaW5zdHJ1Y3Rpb24gYXMgYnl0ZSBjb2RlIHRvIHN0cmVhbSBvdXQuCi0gICAqIEBwYXJhbSBvdXQgT3V0cHV0IHN0cmVhbQotICAgKi8KLSAgQE92ZXJyaWRlCi0gIHB1YmxpYyB2b2lkIGR1bXAoRGF0YU91dHB1dFN0cmVhbSBvdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgb3V0LndyaXRlQnl0ZShvcGNvZGUpOwotCi0gICAgaW5kZXggPSBnZXRUYXJnZXRPZmZzZXQoKTsKLQotICAgIGlmKE1hdGguYWJzKGluZGV4KSA+PSAzMjc2NykgLy8gdG9vIGxhcmdlIGZvciBzaG9ydAotICAgICAgdGhyb3cgbmV3IENsYXNzR2VuRXhjZXB0aW9uKCJCcmFuY2ggdGFyZ2V0IG9mZnNldCB0b28gbGFyZ2UgZm9yIHNob3J0Iik7Ci0KLSAgICBvdXQud3JpdGVTaG9ydChpbmRleCk7IC8vIE1heSBiZSBuZWdhdGl2ZSwgaS5lLiwgcG9pbnQgYmFja3dhcmRzCi0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIHRhcmdldCBicmFuY2ggdGFyZ2V0Ci0gICAqIEByZXR1cm4gdGhlIG9mZnNldCB0byAgYHRhcmdldCcgcmVsYXRpdmUgdG8gdGhpcyBpbnN0cnVjdGlvbgotICAgKi8KLSAgcHJvdGVjdGVkIGludCBnZXRUYXJnZXRPZmZzZXQoSW5zdHJ1Y3Rpb25IYW5kbGUgdGFyZ2V0KSB7Ci0gICAgaWYodGFyZ2V0ID09IG51bGwpCi0gICAgICB0aHJvdyBuZXcgQ2xhc3NHZW5FeGNlcHRpb24oIlRhcmdldCBvZiAiICsgc3VwZXIudG9TdHJpbmcodHJ1ZSkgKwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgaXMgaW52YWxpZCBudWxsIGhhbmRsZSIpOwotCi0gICAgaW50IHQgPSB0YXJnZXQuZ2V0UG9zaXRpb24oKTsKLQotICAgIGlmKHQgPCAwKQotICAgICAgdGhyb3cgbmV3IENsYXNzR2VuRXhjZXB0aW9uKCJJbnZhbGlkIGJyYW5jaCB0YXJnZXQgcG9zaXRpb24gb2Zmc2V0IGZvciAiICsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdXBlci50b1N0cmluZyh0cnVlKSArICI6IiArIHQgKyAiOiIgKyB0YXJnZXQpOwotCi0gICAgcmV0dXJuIHQgLSBwb3NpdGlvbjsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIHRoZSBvZmZzZXQgdG8gdGhpcyBpbnN0cnVjdGlvbidzIHRhcmdldAotICAgKi8KLSAgcHJvdGVjdGVkIGludCBnZXRUYXJnZXRPZmZzZXQoKSB7IHJldHVybiBnZXRUYXJnZXRPZmZzZXQodGFyZ2V0KTsgfQotCi0gIC8qKgotICAgKiBDYWxsZWQgYnkgSW5zdHJ1Y3Rpb25MaXN0LnNldFBvc2l0aW9ucyB3aGVuIHNldHRpbmcgdGhlIHBvc2l0aW9uIGZvciBldmVyeQotICAgKiBpbnN0cnVjdGlvbi4gSW4gdGhlIHByZXNlbmNlIG9mIHZhcmlhYmxlIGxlbmd0aCBpbnN0cnVjdGlvbnMgYHNldFBvc2l0aW9ucycKLSAgICogcGVyZm9ybXMgbXVsdGlwbGUgcGFzc2VzIG92ZXIgdGhlIGluc3RydWN0aW9uIGxpc3QgdG8gY2FsY3VsYXRlIHRoZQotICAgKiBjb3JyZWN0IChieXRlKSBwb3NpdGlvbnMgYW5kIG9mZnNldHMgYnkgY2FsbGluZyB0aGlzIGZ1bmN0aW9uLgotICAgKgotICAgKiBAcGFyYW0gb2Zmc2V0IGFkZGl0aW9uYWwgb2Zmc2V0IGNhdXNlZCBieSBwcmVjZWRpbmcgKHZhcmlhYmxlIGxlbmd0aCkgaW5zdHJ1Y3Rpb25zCi0gICAqIEBwYXJhbSBtYXhfb2Zmc2V0IHRoZSBtYXhpbXVtIG9mZnNldCB0aGF0IG1heSBiZSBjYXVzZWQgYnkgdGhlc2UgaW5zdHJ1Y3Rpb25zCi0gICAqIEByZXR1cm4gYWRkaXRpb25hbCBvZmZzZXQgY2F1c2VkIGJ5IHBvc3NpYmxlIGNoYW5nZSBvZiB0aGlzIGluc3RydWN0aW9uJ3MgbGVuZ3RoCi0gICAqLwotICBwcm90ZWN0ZWQgaW50IHVwZGF0ZVBvc2l0aW9uKGludCBvZmZzZXQsIGludCBtYXhfb2Zmc2V0KSB7Ci0gICAgcG9zaXRpb24gKz0gb2Zmc2V0OwotICAgIHJldHVybiAwOwotICB9Ci0KLSAgLyoqCi0gICAqIExvbmcgb3V0cHV0IGZvcm1hdDoKLSAgICoKLSAgICogJmx0O3Bvc2l0aW9uIGluIGJ5dGUgY29kZSZndDsKLSAgICogJmx0O25hbWUgb2Ygb3Bjb2RlJmd0OyAiWyImbHQ7b3Bjb2RlIG51bWJlciZndDsiXSIKLSAgICogIigiJmx0O2xlbmd0aCBvZiBpbnN0cnVjdGlvbiZndDsiKSIKLSAgICogIiZsdDsiJmx0O3RhcmdldCBpbnN0cnVjdGlvbiZndDsiJmd0OyIgIkAiJmx0O2JyYW5jaCB0YXJnZXQgb2Zmc2V0Jmd0OwotICAgKgotICAgKiBAcGFyYW0gdmVyYm9zZSBsb25nL3Nob3J0IGZvcm1hdCBzd2l0Y2gKLSAgICogQHJldHVybiBtbmVtb25pYyBmb3IgaW5zdHJ1Y3Rpb24KLSAgICovCi0gIEBPdmVycmlkZQotICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKGJvb2xlYW4gdmVyYm9zZSkgewotICAgIFN0cmluZyBzID0gc3VwZXIudG9TdHJpbmcodmVyYm9zZSk7Ci0gICAgU3RyaW5nIHQgPSAibnVsbCI7Ci0KLSAgICBpZih2ZXJib3NlKSB7Ci0gICAgICBpZih0YXJnZXQgIT0gbnVsbCkgewotICAgICAgICBpZih0YXJnZXQuZ2V0SW5zdHJ1Y3Rpb24oKSA9PSB0aGlzKQotICAgICAgICAgIHQgPSAiPHBvaW50cyB0byBpdHNlbGY+IjsKLSAgICAgICAgZWxzZSBpZih0YXJnZXQuZ2V0SW5zdHJ1Y3Rpb24oKSA9PSBudWxsKQotICAgICAgICAgIHQgPSAiPG51bGwgaW5zdHJ1Y3Rpb24hISE/PiI7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICB0ID0gdGFyZ2V0LmdldEluc3RydWN0aW9uKCkudG9TdHJpbmcoZmFsc2UpOyAvLyBBdm9pZCBjaXJjbGVzCi0gICAgICB9Ci0gICAgfSBlbHNlIHsKLSAgICAgIGlmKHRhcmdldCAhPSBudWxsKSB7Ci0gICAgICAgIGluZGV4ID0gZ2V0VGFyZ2V0T2Zmc2V0KCk7Ci0gICAgICAgIHQgPSAiIiArIChpbmRleCArIHBvc2l0aW9uKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gcyArICIgLT4gIiArIHQ7Ci0gIH0KLQotICAvKioKLSAgICogUmVhZCBuZWVkZWQgZGF0YSAoZS5nLiBpbmRleCkgZnJvbSBmaWxlLiBDb252ZXJzaW9uIHRvIGEgSW5zdHJ1Y3Rpb25IYW5kbGUKLSAgICogaXMgZG9uZSBpbiBJbnN0cnVjdGlvbkxpc3QoYnl0ZVtdKS4KLSAgICoKLSAgICogQHBhcmFtIGJ5dGVzIGlucHV0IHN0cmVhbQotICAgKiBAcGFyYW0gd2lkZSB3aWRlIHByZWZpeD8KLSAgICogQHNlZSBJbnN0cnVjdGlvbkxpc3QKLSAgICovCi0gIEBPdmVycmlkZQotICBwcm90ZWN0ZWQgdm9pZCBpbml0RnJvbUZpbGUoQnl0ZVNlcXVlbmNlIGJ5dGVzLCBib29sZWFuIHdpZGUpIHRocm93cyBJT0V4Y2VwdGlvbgotICB7Ci0gICAgbGVuZ3RoID0gMzsKLSAgICBpbmRleCAgPSBieXRlcy5yZWFkU2hvcnQoKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIHRhcmdldCBvZmZzZXQgaW4gYnl0ZSBjb2RlCi0gICAqLwotICBwdWJsaWMgZmluYWwgaW50IGdldEluZGV4KCkgeyByZXR1cm4gaW5kZXg7IH0KLQotICAvKioKLSAgICogQHJldHVybiB0YXJnZXQgb2YgYnJhbmNoIGluc3RydWN0aW9uCi0gICAqLwotICBwdWJsaWMgSW5zdHJ1Y3Rpb25IYW5kbGUgZ2V0VGFyZ2V0KCkgeyByZXR1cm4gdGFyZ2V0OyB9Ci0KLSAgLyoqCi0gICAqIFNldCBicmFuY2ggdGFyZ2V0Ci0gICAqIEBwYXJhbSB0YXJnZXQgYnJhbmNoIHRhcmdldAotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgc2V0VGFyZ2V0KEluc3RydWN0aW9uSGFuZGxlIHRhcmdldCkgewotICAgIG5vdGlmeVRhcmdldENoYW5naW5nKHRoaXMudGFyZ2V0LCB0aGlzKTsKLSAgICB0aGlzLnRhcmdldCA9IHRhcmdldDsKLSAgICBub3RpZnlUYXJnZXRDaGFuZ2VkKHRoaXMudGFyZ2V0LCB0aGlzKTsKLSAgfQotCi0gIC8qKgotICAgKiBVc2VkIGJ5IEJyYW5jaEluc3RydWN0aW9uLCBMb2NhbFZhcmlhYmxlR2VuLCBDb2RlRXhjZXB0aW9uR2VuLgotICAgKiBNdXN0IGJlIGNhbGxlZCBiZWZvcmUgdGhlIHRhcmdldCBpcyBhY3R1YWxseSBjaGFuZ2VkIGluIHRoZQotICAgKiBJbnN0cnVjdGlvblRhcmdldGVyLgotICAgKi8KLSAgc3RhdGljIHZvaWQgbm90aWZ5VGFyZ2V0Q2hhbmdpbmcoSW5zdHJ1Y3Rpb25IYW5kbGUgb2xkX2loLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW5zdHJ1Y3Rpb25UYXJnZXRlciB0KSB7Ci0gICAgaWYob2xkX2loICE9IG51bGwpIHsKLSAgICAgIG9sZF9paC5yZW1vdmVUYXJnZXRlcih0KTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogVXNlZCBieSBCcmFuY2hJbnN0cnVjdGlvbiwgTG9jYWxWYXJpYWJsZUdlbiwgQ29kZUV4Y2VwdGlvbkdlbi4KLSAgICogTXVzdCBiZSBjYWxsZWQgYWZ0ZXIgdGhlIHRhcmdldCBpcyBhY3R1YWxseSBjaGFuZ2VkIGluIHRoZQotICAgKiBJbnN0cnVjdGlvblRhcmdldGVyLgotICAgKi8KLSAgc3RhdGljIHZvaWQgbm90aWZ5VGFyZ2V0Q2hhbmdlZChJbnN0cnVjdGlvbkhhbmRsZSBuZXdfaWgsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbnN0cnVjdGlvblRhcmdldGVyIHQpIHsKLSAgICBpZihuZXdfaWggIT0gbnVsbCkgewotICAgICAgbmV3X2loLmFkZFRhcmdldGVyKHQpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gb2xkX2loIG9sZCB0YXJnZXQKLSAgICogQHBhcmFtIG5ld19paCBuZXcgdGFyZ2V0Ci0gICAqLwotICBAT3ZlcnJpZGUKLSAgcHVibGljIHZvaWQgdXBkYXRlVGFyZ2V0KEluc3RydWN0aW9uSGFuZGxlIG9sZF9paCwgSW5zdHJ1Y3Rpb25IYW5kbGUgbmV3X2loKSB7Ci0gICAgaWYodGFyZ2V0ID09IG9sZF9paCkKLSAgICAgIHNldFRhcmdldChuZXdfaWgpOwotICAgIGVsc2UKLSAgICAgIHRocm93IG5ldyBDbGFzc0dlbkV4Y2VwdGlvbigiTm90IHRhcmdldGluZyAiICsgb2xkX2loICsgIiwgYnV0ICIgKyB0YXJnZXQpOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gdHJ1ZSwgaWYgaWggaXMgdGFyZ2V0IG9mIHRoaXMgaW5zdHJ1Y3Rpb24KLSAgICovCi0gIEBPdmVycmlkZQotICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1RhcmdldChJbnN0cnVjdGlvbkhhbmRsZSBpaCkgewotICAgIHJldHVybiAodGFyZ2V0ID09IGloKTsKLSAgfQotCi0gIC8qKgotICAgKiBJbmZvcm0gdGFyZ2V0IHRoYXQgaXQncyBub3QgdGFyZ2V0ZWQgYW55bW9yZS4KLSAgICovCi0gIEBPdmVycmlkZQotICB2b2lkIGRpc3Bvc2UoKSB7Ci0gICAgc2V0VGFyZ2V0KG51bGwpOwotICAgIGluZGV4PS0xOwotICAgIHBvc2l0aW9uPS0xOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9DQUxPQUQuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0NBTE9BRC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmNzM4ZjAwLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0NBTE9BRC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTAgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotLyoqCi0gKiBDQUxPQUQgLSBMb2FkIGNoYXIgZnJvbSBhcnJheQotICogPFBSRT5TdGFjazogLi4uLCBhcnJheXJlZiwgaW5kZXggLSZndDsgLi4uLCB2YWx1ZTwvUFJFPgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBDQUxPQUQgZXh0ZW5kcyBBcnJheUluc3RydWN0aW9uIGltcGxlbWVudHMgU3RhY2tQcm9kdWNlciB7Ci0gIC8qKiBMb2FkIGNoYXIgZnJvbSBhcnJheQotICAgKi8KLSAgcHVibGljIENBTE9BRCgpIHsKLSAgICBzdXBlcihjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuQ0FMT0FEKTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIENhbGwgY29ycmVzcG9uZGluZyB2aXNpdG9yIG1ldGhvZChzKS4gVGhlIG9yZGVyIGlzOgotICAgKiBDYWxsIHZpc2l0b3IgbWV0aG9kcyBvZiBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzIGZpcnN0LCB0aGVuCi0gICAqIGNhbGwgbWV0aG9kcyBhY2NvcmRpbmcgdG8gdGhlIGNsYXNzIGhpZXJhcmNoeSBpbiBkZXNjZW5kaW5nIG9yZGVyLAotICAgKiBpLmUuLCB0aGUgbW9zdCBzcGVjaWZpYyB2aXNpdFhYWCgpIGNhbGwgY29tZXMgbGFzdC4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0U3RhY2tQcm9kdWNlcih0aGlzKTsKLSAgICB2LnZpc2l0RXhjZXB0aW9uVGhyb3dlcih0aGlzKTsKLSAgICB2LnZpc2l0VHlwZWRJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0QXJyYXlJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0Q0FMT0FEKHRoaXMpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9DQVNUT1JFLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9DQVNUT1JFLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDk0MTg3Y2MuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvQ0FTVE9SRS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTAgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotLyoqCi0gKiBDQVNUT1JFIC0gIFN0b3JlIGludG8gY2hhciBhcnJheQotICogPFBSRT5TdGFjazogLi4uLCBhcnJheXJlZiwgaW5kZXgsIHZhbHVlIC0mZ3Q7IC4uLjwvUFJFPgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBDQVNUT1JFIGV4dGVuZHMgQXJyYXlJbnN0cnVjdGlvbiBpbXBsZW1lbnRzIFN0YWNrQ29uc3VtZXIgewotICAvKiogU3RvcmUgY2hhciBpbnRvIGFycmF5Ci0gICAqLwotICBwdWJsaWMgQ0FTVE9SRSgpIHsKLSAgICBzdXBlcihjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuQ0FTVE9SRSk7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBDYWxsIGNvcnJlc3BvbmRpbmcgdmlzaXRvciBtZXRob2QocykuIFRoZSBvcmRlciBpczoKLSAgICogQ2FsbCB2aXNpdG9yIG1ldGhvZHMgb2YgaW1wbGVtZW50ZWQgaW50ZXJmYWNlcyBmaXJzdCwgdGhlbgotICAgKiBjYWxsIG1ldGhvZHMgYWNjb3JkaW5nIHRvIHRoZSBjbGFzcyBoaWVyYXJjaHkgaW4gZGVzY2VuZGluZyBvcmRlciwKLSAgICogaS5lLiwgdGhlIG1vc3Qgc3BlY2lmaWMgdmlzaXRYWFgoKSBjYWxsIGNvbWVzIGxhc3QuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgdi52aXNpdFN0YWNrQ29uc3VtZXIodGhpcyk7Ci0gICAgdi52aXNpdEV4Y2VwdGlvblRocm93ZXIodGhpcyk7Ci0gICAgdi52aXNpdFR5cGVkSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdEFycmF5SW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdENBU1RPUkUodGhpcyk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0NIRUNLQ0FTVC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvQ0hFQ0tDQVNULmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDIwMzAyZjkuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvQ0hFQ0tDQVNULmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMjAgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5FeGNlcHRpb25Db25zdGFudHM7Ci0vKioKLSAqIENIRUNLQ0FTVCAtIENoZWNrIHdoZXRoZXIgb2JqZWN0IGlzIG9mIGdpdmVuIHR5cGUKLSAqIDxQUkU+U3RhY2s6IC4uLiwgb2JqZWN0cmVmIC0mZ3Q7IC4uLiwgb2JqZWN0cmVmPC9QUkU+Ci0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGNsYXNzIENIRUNLQ0FTVCBleHRlbmRzIENQSW5zdHJ1Y3Rpb24KLSAgaW1wbGVtZW50cyBMb2FkQ2xhc3MsIEV4Y2VwdGlvblRocm93ZXIsIFN0YWNrUHJvZHVjZXIsIFN0YWNrQ29uc3VtZXIgewotICAvKioKLSAgICogRW1wdHkgY29uc3RydWN0b3IgbmVlZGVkIGZvciB0aGUgQ2xhc3MubmV3SW5zdGFuY2UoKSBzdGF0ZW1lbnQgaW4KLSAgICogSW5zdHJ1Y3Rpb24ucmVhZEluc3RydWN0aW9uKCkuIE5vdCB0byBiZSB1c2VkIG90aGVyd2lzZS4KLSAgICovCi0gIENIRUNLQ0FTVCgpIHt9Ci0KLSAgLyoqIENoZWNrIHdoZXRoZXIgb2JqZWN0IGlzIG9mIGdpdmVuIHR5cGUKLSAgICogQHBhcmFtIG4gaW5kZXggdG8gY2xhc3MgaW4gY29uc3RhbnQgcG9vbAotICAgKi8KLSAgcHVibGljIENIRUNLQ0FTVChpbnQgaW5kZXgpIHsKLSAgICBzdXBlcihjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuQ0hFQ0tDQVNULCBpbmRleCk7Ci0gIH0KLQotICAvKiogQHJldHVybiBleGNlcHRpb25zIHRoaXMgaW5zdHJ1Y3Rpb24gbWF5IGNhdXNlCi0gICAqLwotICBwdWJsaWMgQ2xhc3NbXSBnZXRFeGNlcHRpb25zKCkgewotICAgIENsYXNzW10gY3MgPSBuZXcgQ2xhc3NbMSArIEV4Y2VwdGlvbkNvbnN0YW50cy5FWENTX0NMQVNTX0FORF9JTlRFUkZBQ0VfUkVTT0xVVElPTi5sZW5ndGhdOwotCi0gICAgU3lzdGVtLmFycmF5Y29weShFeGNlcHRpb25Db25zdGFudHMuRVhDU19DTEFTU19BTkRfSU5URVJGQUNFX1JFU09MVVRJT04sIDAsCi0gICAgICAgICAgICAgICAgICAgICBjcywgMCwgRXhjZXB0aW9uQ29uc3RhbnRzLkVYQ1NfQ0xBU1NfQU5EX0lOVEVSRkFDRV9SRVNPTFVUSU9OLmxlbmd0aCk7Ci0gICAgY3NbRXhjZXB0aW9uQ29uc3RhbnRzLkVYQ1NfQ0xBU1NfQU5EX0lOVEVSRkFDRV9SRVNPTFVUSU9OLmxlbmd0aF0gPQotICAgICAgRXhjZXB0aW9uQ29uc3RhbnRzLkNMQVNTX0NBU1RfRVhDRVBUSU9OOwotICAgIHJldHVybiBjczsKLSAgfQotCi0gIHB1YmxpYyBPYmplY3RUeXBlIGdldExvYWRDbGFzc1R5cGUoQ29uc3RhbnRQb29sR2VuIGNwZykgewotICAgIFR5cGUgdCA9IGdldFR5cGUoY3BnKTsKLQotICAgIGlmKHQgaW5zdGFuY2VvZiBBcnJheVR5cGUpCi0gICAgICB0ID0gKChBcnJheVR5cGUpIHQpLmdldEJhc2ljVHlwZSgpOwotCi0gICAgcmV0dXJuICh0IGluc3RhbmNlb2YgT2JqZWN0VHlwZSk/IChPYmplY3RUeXBlKSB0IDogbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBDYWxsIGNvcnJlc3BvbmRpbmcgdmlzaXRvciBtZXRob2QocykuIFRoZSBvcmRlciBpczoKLSAgICogQ2FsbCB2aXNpdG9yIG1ldGhvZHMgb2YgaW1wbGVtZW50ZWQgaW50ZXJmYWNlcyBmaXJzdCwgdGhlbgotICAgKiBjYWxsIG1ldGhvZHMgYWNjb3JkaW5nIHRvIHRoZSBjbGFzcyBoaWVyYXJjaHkgaW4gZGVzY2VuZGluZyBvcmRlciwKLSAgICogaS5lLiwgdGhlIG1vc3Qgc3BlY2lmaWMgdmlzaXRYWFgoKSBjYWxsIGNvbWVzIGxhc3QuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgdi52aXNpdExvYWRDbGFzcyh0aGlzKTsKLSAgICB2LnZpc2l0RXhjZXB0aW9uVGhyb3dlcih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tQcm9kdWNlcih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tDb25zdW1lcih0aGlzKTsKLSAgICB2LnZpc2l0VHlwZWRJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0Q1BJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0Q0hFQ0tDQVNUKHRoaXMpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9DUEluc3RydWN0aW9uLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9DUEluc3RydWN0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDVmOTY1MGIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvQ1BJbnN0cnVjdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTY5ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLWltcG9ydCBqYXZhLmlvLio7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwudXRpbC5CeXRlU2VxdWVuY2U7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmNsYXNzZmlsZS4qOwotCi0vKioKLSAqIEFic3RyYWN0IHN1cGVyIGNsYXNzIGZvciBpbnN0cnVjdGlvbnMgdGhhdCB1c2UgYW4gaW5kZXggaW50byB0aGUKLSAqIGNvbnN0YW50IHBvb2wgc3VjaCBhcyBMREMsIElOVk9LRVZJUlRVQUwsIGV0Yy4KLSAqCi0gKiBAc2VlIENvbnN0YW50UG9vbEdlbgotICogQHNlZSBMREMKLSAqIEBzZWUgSU5WT0tFVklSVFVBTAotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBDUEluc3RydWN0aW9uIGV4dGVuZHMgSW5zdHJ1Y3Rpb24KLSAgaW1wbGVtZW50cyBUeXBlZEluc3RydWN0aW9uLCBJbmRleGVkSW5zdHJ1Y3Rpb24KLXsKLSAgcHJvdGVjdGVkIGludCBpbmRleDsgLy8gaW5kZXggdG8gY29uc3RhbnQgcG9vbAotCi0gIC8qKgotICAgKiBFbXB0eSBjb25zdHJ1Y3RvciBuZWVkZWQgZm9yIHRoZSBDbGFzcy5uZXdJbnN0YW5jZSgpIHN0YXRlbWVudCBpbgotICAgKiBJbnN0cnVjdGlvbi5yZWFkSW5zdHJ1Y3Rpb24oKS4gTm90IHRvIGJlIHVzZWQgb3RoZXJ3aXNlLgotICAgKi8KLSAgQ1BJbnN0cnVjdGlvbigpIHt9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBpbmRleCB0byBjb25zdGFudCBwb29sCi0gICAqLwotICBwcm90ZWN0ZWQgQ1BJbnN0cnVjdGlvbihzaG9ydCBvcGNvZGUsIGludCBpbmRleCkgewotICAgIHN1cGVyKG9wY29kZSwgKHNob3J0KTMpOwotICAgIHNldEluZGV4KGluZGV4KTsKLSAgfQotCi0gIC8qKgotICAgKiBEdW1wIGluc3RydWN0aW9uIGFzIGJ5dGUgY29kZSB0byBzdHJlYW0gb3V0LgotICAgKiBAcGFyYW0gb3V0IE91dHB1dCBzdHJlYW0KLSAgICovCi0gIHB1YmxpYyB2b2lkIGR1bXAoRGF0YU91dHB1dFN0cmVhbSBvdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgb3V0LndyaXRlQnl0ZShvcGNvZGUpOwotICAgIG91dC53cml0ZVNob3J0KGluZGV4KTsKLSAgfQotCi0gIC8qKgotICAgKiBMb25nIG91dHB1dCBmb3JtYXQ6Ci0gICAqCi0gICAqICZsdDtuYW1lIG9mIG9wY29kZSZndDsgIlsiJmx0O29wY29kZSBudW1iZXImZ3Q7Il0iCi0gICAqICIoIiZsdDtsZW5ndGggb2YgaW5zdHJ1Y3Rpb24mZ3Q7IikiICImbHQ7IiZsdDsgY29uc3RhbnQgcG9vbCBpbmRleCZndDsiJmd0OyIKLSAgICoKLSAgICogQHBhcmFtIHZlcmJvc2UgbG9uZy9zaG9ydCBmb3JtYXQgc3dpdGNoCi0gICAqIEByZXR1cm4gbW5lbW9uaWMgZm9yIGluc3RydWN0aW9uCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKGJvb2xlYW4gdmVyYm9zZSkgewotICAgIHJldHVybiBzdXBlci50b1N0cmluZyh2ZXJib3NlKSArICIgIiArIGluZGV4OwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gbW5lbW9uaWMgZm9yIGluc3RydWN0aW9uIHdpdGggc3ltYm9saWMgcmVmZXJlbmNlcyByZXNvbHZlZAotICAgKi8KLSAgcHVibGljIFN0cmluZyB0b1N0cmluZyhDb25zdGFudFBvb2wgY3ApIHsKLSAgICBDb25zdGFudCBjICAgPSBjcC5nZXRDb25zdGFudChpbmRleCk7Ci0gICAgU3RyaW5nICAgc3RyID0gY3AuY29uc3RhbnRUb1N0cmluZyhjKTsKLQotICAgIGlmKGMgaW5zdGFuY2VvZiBDb25zdGFudENsYXNzKQotICAgICAgc3RyID0gc3RyLnJlcGxhY2UoJy4nLCAnLycpOwotCi0gICAgcmV0dXJuIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5PUENPREVfTkFNRVNbb3Bjb2RlXSArICIgIiArIHN0cjsKLSAgfQotCi0gIC8qKgotICAgKiBSZWFkIG5lZWRlZCBkYXRhIChpLmUuLCBpbmRleCkgZnJvbSBmaWxlLgotICAgKiBAcGFyYW0gYnl0ZXMgaW5wdXQgc3RyZWFtCi0gICAqIEBwYXJhbSB3aWRlIHdpZGUgcHJlZml4PwotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgaW5pdEZyb21GaWxlKEJ5dGVTZXF1ZW5jZSBieXRlcywgYm9vbGVhbiB3aWRlKQotICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbgotICB7Ci0gICAgc2V0SW5kZXgoYnl0ZXMucmVhZFVuc2lnbmVkU2hvcnQoKSk7Ci0gICAgbGVuZ3RoID0gMzsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIGluZGV4IGluIGNvbnN0YW50IHBvb2wgcmVmZXJyZWQgYnkgdGhpcyBpbnN0cnVjdGlvbi4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBpbnQgZ2V0SW5kZXgoKSB7IHJldHVybiBpbmRleDsgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIGluZGV4IHRvIGNvbnN0YW50IHBvb2wuCi0gICAqIEBwYXJhbSBpbmRleCBpbiAgY29uc3RhbnQgcG9vbC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldEluZGV4KGludCBpbmRleCkgewotICAgIGlmKGluZGV4IDwgMCkKLSAgICAgIHRocm93IG5ldyBDbGFzc0dlbkV4Y2VwdGlvbigiTmVnYXRpdmUgaW5kZXggdmFsdWU6ICIgKyBpbmRleCk7Ci0KLSAgICB0aGlzLmluZGV4ID0gaW5kZXg7Ci0gIH0KLQotICAvKiogQHJldHVybiB0eXBlIHJlbGF0ZWQgd2l0aCB0aGlzIGluc3RydWN0aW9uLgotICAgKi8KLSAgcHVibGljIFR5cGUgZ2V0VHlwZShDb25zdGFudFBvb2xHZW4gY3BnKSB7Ci0gICAgQ29uc3RhbnRQb29sIGNwICAgPSBjcGcuZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgU3RyaW5nICAgICAgIG5hbWUgPSBjcC5nZXRDb25zdGFudFN0cmluZyhpbmRleCwgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkNPTlNUQU5UX0NsYXNzKTsKLQotICAgIGlmKCFuYW1lLnN0YXJ0c1dpdGgoIlsiKSkKLSAgICAgIG5hbWUgPSAiTCIgKyBuYW1lICsgIjsiOwotCi0gICAgcmV0dXJuIFR5cGUuZ2V0VHlwZShuYW1lKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvQ2xhc3NHZW4uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0NsYXNzR2VuLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwNWE1MGIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvQ2xhc3NHZW4uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQ1NCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmNsYXNzZmlsZS4qOwotaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7Ci1pbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOwotCi0vKioKLSAqIFRlbXBsYXRlIGNsYXNzIGZvciBidWlsZGluZyB1cCBhIGphdmEgY2xhc3MuIE1heSBiZSBpbml0aWFsaXplZCB3aXRoIGFuCi0gKiBleGlzdGluZyBqYXZhIGNsYXNzIChmaWxlKS4KLSAqCi0gKiBAc2VlIEphdmFDbGFzcwotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGNsYXNzIENsYXNzR2VuIGV4dGVuZHMgQWNjZXNzRmxhZ3MgaW1wbGVtZW50cyBDbG9uZWFibGUgewotICAvKiBDb3JyZXNwb25kcyB0byB0aGUgZmllbGRzIGZvdW5kIGluIGEgSmF2YUNsYXNzIG9iamVjdC4KLSAgICovCi0gIHByaXZhdGUgU3RyaW5nICAgY2xhc3NfbmFtZSwgc3VwZXJfY2xhc3NfbmFtZSwgZmlsZV9uYW1lOwotICBwcml2YXRlIGludCAgICAgIGNsYXNzX25hbWVfaW5kZXggPSAtMSwgc3VwZXJjbGFzc19uYW1lX2luZGV4ID0gLTE7Ci0gIHByaXZhdGUgaW50ICAgICAgbWFqb3IgPSBDb25zdGFudHMuTUFKT1JfMV8xLCBtaW5vciA9IENvbnN0YW50cy5NSU5PUl8xXzE7Ci0KLSAgcHJpdmF0ZSBDb25zdGFudFBvb2xHZW4gY3A7IC8vIFRlbXBsYXRlIGZvciBidWlsZGluZyB1cCBjb25zdGFudCBwb29sCi0KLSAgLy8gQXJyYXlMaXN0cyBpbnN0ZWFkIG9mIGFycmF5cyB0byBnYXRoZXIgZmllbGRzLCBtZXRob2RzLCBldGMuCi0gIHByaXZhdGUgQXJyYXlMaXN0ICAgZmllbGRfdmVjICAgICA9IG5ldyBBcnJheUxpc3QoKTsKLSAgcHJpdmF0ZSBBcnJheUxpc3QgICBtZXRob2RfdmVjICAgID0gbmV3IEFycmF5TGlzdCgpOwotICBwcml2YXRlIEFycmF5TGlzdCAgIGF0dHJpYnV0ZV92ZWMgPSBuZXcgQXJyYXlMaXN0KCk7Ci0gIHByaXZhdGUgQXJyYXlMaXN0ICAgaW50ZXJmYWNlX3ZlYyA9IG5ldyBBcnJheUxpc3QoKTsKLQotICAvKiogQ29udmVuaWVuY2UgY29uc3RydWN0b3IgdG8gc2V0IHVwIHNvbWUgaW1wb3J0YW50IHZhbHVlcyBpbml0aWFsbHkuCi0gICAqCi0gICAqIEBwYXJhbSBjbGFzc19uYW1lIGZ1bGx5IHF1YWxpZmllZCBjbGFzcyBuYW1lCi0gICAqIEBwYXJhbSBzdXBlcl9jbGFzc19uYW1lIGZ1bGx5IHF1YWxpZmllZCBzdXBlcmNsYXNzIG5hbWUKLSAgICogQHBhcmFtIGZpbGVfbmFtZSBzb3VyY2UgZmlsZSBuYW1lCi0gICAqIEBwYXJhbSBhY2Nlc3NfZmxhZ3MgYWNjZXNzIHF1YWxpZmllcnMKLSAgICogQHBhcmFtIGludGVyZmFjZXMgaW1wbGVtZW50ZWQgaW50ZXJmYWNlcwotICAgKiBAcGFyYW0gY3AgY29uc3RhbnQgcG9vbCB0byB1c2UKLSAgICovCi0gIHB1YmxpYyBDbGFzc0dlbihTdHJpbmcgY2xhc3NfbmFtZSwgU3RyaW5nIHN1cGVyX2NsYXNzX25hbWUsIFN0cmluZyBmaWxlX25hbWUsCi0gICAgICAgICAgICAgICAgICBpbnQgYWNjZXNzX2ZsYWdzLCBTdHJpbmdbXSBpbnRlcmZhY2VzLCBDb25zdGFudFBvb2xHZW4gY3ApIHsKLSAgICB0aGlzLmNsYXNzX25hbWUgICAgICAgPSBjbGFzc19uYW1lOwotICAgIHRoaXMuc3VwZXJfY2xhc3NfbmFtZSA9IHN1cGVyX2NsYXNzX25hbWU7Ci0gICAgdGhpcy5maWxlX25hbWUgICAgICAgID0gZmlsZV9uYW1lOwotICAgIHRoaXMuYWNjZXNzX2ZsYWdzICAgICA9IGFjY2Vzc19mbGFnczsKLSAgICB0aGlzLmNwICAgICAgICAgICAgICAgPSBjcDsKLQotICAgIC8vIFB1dCBldmVyeXRoaW5nIG5lZWRlZCBieSBkZWZhdWx0IGludG8gdGhlIGNvbnN0YW50IHBvb2wgYW5kIHRoZSB2ZWN0b3JzCi0gICAgaWYoZmlsZV9uYW1lICE9IG51bGwpCi0gICAgICBhZGRBdHRyaWJ1dGUobmV3IFNvdXJjZUZpbGUoY3AuYWRkVXRmOCgiU291cmNlRmlsZSIpLCAyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNwLmFkZFV0ZjgoZmlsZV9uYW1lKSwgY3AuZ2V0Q29uc3RhbnRQb29sKCkpKTsKLQotICAgIGNsYXNzX25hbWVfaW5kZXggICAgICA9IGNwLmFkZENsYXNzKGNsYXNzX25hbWUpOwotICAgIHN1cGVyY2xhc3NfbmFtZV9pbmRleCA9IGNwLmFkZENsYXNzKHN1cGVyX2NsYXNzX25hbWUpOwotCi0gICAgaWYoaW50ZXJmYWNlcyAhPSBudWxsKQotICAgICAgZm9yKGludCBpPTA7IGkgPCBpbnRlcmZhY2VzLmxlbmd0aDsgaSsrKQotICAgICAgICBhZGRJbnRlcmZhY2UoaW50ZXJmYWNlc1tpXSk7Ci0gIH0KLQotICAvKiogQ29udmVuaWVuY2UgY29uc3RydWN0b3IgdG8gc2V0IHVwIHNvbWUgaW1wb3J0YW50IHZhbHVlcyBpbml0aWFsbHkuCi0gICAqCi0gICAqIEBwYXJhbSBjbGFzc19uYW1lIGZ1bGx5IHF1YWxpZmllZCBjbGFzcyBuYW1lCi0gICAqIEBwYXJhbSBzdXBlcl9jbGFzc19uYW1lIGZ1bGx5IHF1YWxpZmllZCBzdXBlcmNsYXNzIG5hbWUKLSAgICogQHBhcmFtIGZpbGVfbmFtZSBzb3VyY2UgZmlsZSBuYW1lCi0gICAqIEBwYXJhbSBhY2Nlc3NfZmxhZ3MgYWNjZXNzIHF1YWxpZmllcnMKLSAgICogQHBhcmFtIGludGVyZmFjZXMgaW1wbGVtZW50ZWQgaW50ZXJmYWNlcwotICAgKi8KLSAgcHVibGljIENsYXNzR2VuKFN0cmluZyBjbGFzc19uYW1lLCBTdHJpbmcgc3VwZXJfY2xhc3NfbmFtZSwgU3RyaW5nIGZpbGVfbmFtZSwKLSAgICAgICAgICAgICAgICAgIGludCBhY2Nlc3NfZmxhZ3MsIFN0cmluZ1tdIGludGVyZmFjZXMpIHsKLSAgICB0aGlzKGNsYXNzX25hbWUsIHN1cGVyX2NsYXNzX25hbWUsIGZpbGVfbmFtZSwgYWNjZXNzX2ZsYWdzLCBpbnRlcmZhY2VzLAotICAgICAgICAgbmV3IENvbnN0YW50UG9vbEdlbigpKTsKLSAgfQotCi0gIC8qKgotICAgKiBJbml0aWFsaXplIHdpdGggZXhpc3RpbmcgY2xhc3MuCi0gICAqIEBwYXJhbSBjbGF6eiBKYXZhQ2xhc3Mgb2JqZWN0IChlLmcuIHJlYWQgZnJvbSBmaWxlKQotICAgKi8KLSAgcHVibGljIENsYXNzR2VuKEphdmFDbGFzcyBjbGF6eikgewotICAgIGNsYXNzX25hbWVfaW5kZXggICAgICA9IGNsYXp6LmdldENsYXNzTmFtZUluZGV4KCk7Ci0gICAgc3VwZXJjbGFzc19uYW1lX2luZGV4ID0gY2xhenouZ2V0U3VwZXJjbGFzc05hbWVJbmRleCgpOwotICAgIGNsYXNzX25hbWUgICAgICAgICAgICA9IGNsYXp6LmdldENsYXNzTmFtZSgpOwotICAgIHN1cGVyX2NsYXNzX25hbWUgICAgICA9IGNsYXp6LmdldFN1cGVyY2xhc3NOYW1lKCk7Ci0gICAgZmlsZV9uYW1lICAgICAgICAgICAgID0gY2xhenouZ2V0U291cmNlRmlsZU5hbWUoKTsKLSAgICBhY2Nlc3NfZmxhZ3MgICAgICAgICAgPSBjbGF6ei5nZXRBY2Nlc3NGbGFncygpOwotICAgIGNwICAgICAgICAgICAgICAgICAgICA9IG5ldyBDb25zdGFudFBvb2xHZW4oY2xhenouZ2V0Q29uc3RhbnRQb29sKCkpOwotICAgIG1ham9yICAgICAgICAgICAgICAgICA9IGNsYXp6LmdldE1ham9yKCk7Ci0gICAgbWlub3IgICAgICAgICAgICAgICAgID0gY2xhenouZ2V0TWlub3IoKTsKLQotICAgIEF0dHJpYnV0ZVtdIGF0dHJpYnV0ZXMgPSBjbGF6ei5nZXRBdHRyaWJ1dGVzKCk7Ci0gICAgTWV0aG9kW10gICAgbWV0aG9kcyAgICA9IGNsYXp6LmdldE1ldGhvZHMoKTsKLSAgICBGaWVsZFtdICAgICBmaWVsZHMgICAgID0gY2xhenouZ2V0RmllbGRzKCk7Ci0gICAgU3RyaW5nW10gICAgaW50ZXJmYWNlcyA9IGNsYXp6LmdldEludGVyZmFjZU5hbWVzKCk7Ci0KLSAgICBmb3IoaW50IGk9MDsgaSA8IGludGVyZmFjZXMubGVuZ3RoOyBpKyspCi0gICAgICBhZGRJbnRlcmZhY2UoaW50ZXJmYWNlc1tpXSk7Ci0KLSAgICBmb3IoaW50IGk9MDsgaSA8IGF0dHJpYnV0ZXMubGVuZ3RoOyBpKyspCi0gICAgICBhZGRBdHRyaWJ1dGUoYXR0cmlidXRlc1tpXSk7Ci0KLSAgICBmb3IoaW50IGk9MDsgaSA8IG1ldGhvZHMubGVuZ3RoOyBpKyspCi0gICAgICBhZGRNZXRob2QobWV0aG9kc1tpXSk7Ci0KLSAgICBmb3IoaW50IGk9MDsgaSA8IGZpZWxkcy5sZW5ndGg7IGkrKykKLSAgICAgIGFkZEZpZWxkKGZpZWxkc1tpXSk7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiB0aGUgKGZpbmFsbHkpIGJ1aWx0IHVwIEphdmEgY2xhc3Mgb2JqZWN0LgotICAgKi8KLSAgcHVibGljIEphdmFDbGFzcyBnZXRKYXZhQ2xhc3MoKSB7Ci0gICAgaW50W10gICAgICAgIGludGVyZmFjZXMgPSBnZXRJbnRlcmZhY2VzKCk7Ci0gICAgRmllbGRbXSAgICAgIGZpZWxkcyAgICAgPSBnZXRGaWVsZHMoKTsKLSAgICBNZXRob2RbXSAgICAgbWV0aG9kcyAgICA9IGdldE1ldGhvZHMoKTsKLSAgICBBdHRyaWJ1dGVbXSAgYXR0cmlidXRlcyA9IGdldEF0dHJpYnV0ZXMoKTsKLQotICAgIC8vIE11c3QgYmUgbGFzdCBzaW5jZSB0aGUgYWJvdmUgY2FsbHMgbWF5IHN0aWxsIGFkZCBzb21ldGhpbmcgdG8gaXQKLSAgICBDb25zdGFudFBvb2wgY3AgICAgICAgICA9IHRoaXMuY3AuZ2V0RmluYWxDb25zdGFudFBvb2woKTsKLQotICAgIHJldHVybiBuZXcgSmF2YUNsYXNzKGNsYXNzX25hbWVfaW5kZXgsIHN1cGVyY2xhc3NfbmFtZV9pbmRleCwKLSAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlX25hbWUsIG1ham9yLCBtaW5vciwgYWNjZXNzX2ZsYWdzLAotICAgICAgICAgICAgICAgICAgICAgICAgIGNwLCBpbnRlcmZhY2VzLCBmaWVsZHMsIG1ldGhvZHMsIGF0dHJpYnV0ZXMpOwotICB9Ci0KLSAgLyoqCi0gICAqIEFkZCBhbiBpbnRlcmZhY2UgdG8gdGhpcyBjbGFzcywgaS5lLiwgdGhpcyBjbGFzcyBoYXMgdG8gaW1wbGVtZW50IGl0LgotICAgKiBAcGFyYW0gbmFtZSBpbnRlcmZhY2UgdG8gaW1wbGVtZW50IChmdWxseSBxdWFsaWZpZWQgY2xhc3MgbmFtZSkKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFkZEludGVyZmFjZShTdHJpbmcgbmFtZSkgewotICAgIGludGVyZmFjZV92ZWMuYWRkKG5hbWUpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlbW92ZSBhbiBpbnRlcmZhY2UgZnJvbSB0aGlzIGNsYXNzLgotICAgKiBAcGFyYW0gbmFtZSBpbnRlcmZhY2UgdG8gcmVtb3ZlIChmdWxseSBxdWFsaWZpZWQgbmFtZSkKLSAgICovCi0gIHB1YmxpYyB2b2lkIHJlbW92ZUludGVyZmFjZShTdHJpbmcgbmFtZSkgewotICAgIGludGVyZmFjZV92ZWMucmVtb3ZlKG5hbWUpOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gbWFqb3IgdmVyc2lvbiBudW1iZXIgb2YgY2xhc3MgZmlsZQotICAgKi8KLSAgcHVibGljIGludCAgZ2V0TWFqb3IoKSAgICAgIHsgcmV0dXJuIG1ham9yOyB9Ci0KLSAgLyoqIFNldCBtYWpvciB2ZXJzaW9uIG51bWJlciBvZiBjbGFzcyBmaWxlLCBkZWZhdWx0IHZhbHVlIGlzIDQ1IChKREsgMS4xKQotICAgKiBAcGFyYW0gbWFqb3IgbWFqb3IgdmVyc2lvbiBudW1iZXIKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldE1ham9yKGludCBtYWpvcikgewotICAgIHRoaXMubWFqb3IgPSBtYWpvcjsKLSAgfQotCi0gIC8qKiBTZXQgbWlub3IgdmVyc2lvbiBudW1iZXIgb2YgY2xhc3MgZmlsZSwgZGVmYXVsdCB2YWx1ZSBpcyAzIChKREsgMS4xKQotICAgKiBAcGFyYW0gbWlub3IgbWlub3IgdmVyc2lvbiBudW1iZXIKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldE1pbm9yKGludCBtaW5vcikgewotICAgIHRoaXMubWlub3IgPSBtaW5vcjsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIG1pbm9yIHZlcnNpb24gbnVtYmVyIG9mIGNsYXNzIGZpbGUKLSAgICovCi0gIHB1YmxpYyBpbnQgIGdldE1pbm9yKCkgICAgICB7IHJldHVybiBtaW5vcjsgfQotCi0gIC8qKgotICAgKiBBZGQgYW4gYXR0cmlidXRlIHRvIHRoaXMgY2xhc3MuCi0gICAqIEBwYXJhbSBhIGF0dHJpYnV0ZSB0byBhZGQKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFkZEF0dHJpYnV0ZShBdHRyaWJ1dGUgYSkgICAgeyBhdHRyaWJ1dGVfdmVjLmFkZChhKTsgfQotCi0gIC8qKgotICAgKiBBZGQgYSBtZXRob2QgdG8gdGhpcyBjbGFzcy4KLSAgICogQHBhcmFtIG0gbWV0aG9kIHRvIGFkZAotICAgKi8KLSAgcHVibGljIHZvaWQgYWRkTWV0aG9kKE1ldGhvZCBtKSAgICAgICAgICB7IG1ldGhvZF92ZWMuYWRkKG0pOyB9Ci0KLSAgLyoqCi0gICAqIENvbnZlbmllbmNlIG1ldGhvZC4KLSAgICoKLSAgICogQWRkIGFuIGVtcHR5IGNvbnN0cnVjdG9yIHRvIHRoaXMgY2xhc3MgdGhhdCBkb2VzIG5vdGhpbmcgYnV0IGNhbGxpbmcgc3VwZXIoKS4KLSAgICogQHBhcmFtIGFjY2VzcyByaWdodHMgZm9yIGNvbnN0cnVjdG9yCi0gICAqLwotICBwdWJsaWMgdm9pZCBhZGRFbXB0eUNvbnN0cnVjdG9yKGludCBhY2Nlc3NfZmxhZ3MpIHsKLSAgICBJbnN0cnVjdGlvbkxpc3QgaWwgPSBuZXcgSW5zdHJ1Y3Rpb25MaXN0KCk7Ci0gICAgaWwuYXBwZW5kKEluc3RydWN0aW9uQ29uc3RhbnRzLlRISVMpOyAvLyBQdXNoIGB0aGlzJwotICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFU1BFQ0lBTChjcC5hZGRNZXRob2RyZWYoc3VwZXJfY2xhc3NfbmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI8aW5pdD4iLCAiKClWIikpKTsKLSAgICBpbC5hcHBlbmQoSW5zdHJ1Y3Rpb25Db25zdGFudHMuUkVUVVJOKTsKLQotICAgIE1ldGhvZEdlbiBtZyA9IG5ldyBNZXRob2RHZW4oYWNjZXNzX2ZsYWdzLCBUeXBlLlZPSUQsIFR5cGUuTk9fQVJHUywgbnVsbCwKLSAgICAgICAgICAgICAgICAgICAgICAgIjxpbml0PiIsIGNsYXNzX25hbWUsIGlsLCBjcCk7Ci0gICAgbWcuc2V0TWF4U3RhY2soMSk7Ci0gICAgYWRkTWV0aG9kKG1nLmdldE1ldGhvZCgpKTsKLSAgfQotCi0gIC8qKgotICAgKiBBZGQgYSBmaWVsZCB0byB0aGlzIGNsYXNzLgotICAgKiBAcGFyYW0gZiBmaWVsZCB0byBhZGQKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFkZEZpZWxkKEZpZWxkIGYpICAgICAgICAgICAgeyBmaWVsZF92ZWMuYWRkKGYpOyB9Ci0KLSAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZChGaWVsZCBmKSAgICB7IHJldHVybiBmaWVsZF92ZWMuY29udGFpbnMoZik7IH0KLQotICAvKiogQHJldHVybiBmaWVsZCBvYmplY3Qgd2l0aCBnaXZlbiBuYW1lLCBvciBudWxsCi0gICAqLwotICBwdWJsaWMgRmllbGQgY29udGFpbnNGaWVsZChTdHJpbmcgbmFtZSkgewotICAgIGZvcihJdGVyYXRvciBlPWZpZWxkX3ZlYy5pdGVyYXRvcigpOyBlLmhhc05leHQoKTsgKSB7Ci0gICAgICBGaWVsZCBmID0gKEZpZWxkKWUubmV4dCgpOwotICAgICAgaWYoZi5nZXROYW1lKCkuZXF1YWxzKG5hbWUpKQotICAgICAgICByZXR1cm4gZjsKLSAgICB9Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKiBAcmV0dXJuIG1ldGhvZCBvYmplY3Qgd2l0aCBnaXZlbiBuYW1lIGFuZCBzaWduYXR1cmUsIG9yIG51bGwKLSAgICovCi0gIHB1YmxpYyBNZXRob2QgY29udGFpbnNNZXRob2QoU3RyaW5nIG5hbWUsIFN0cmluZyBzaWduYXR1cmUpIHsKLSAgICBmb3IoSXRlcmF0b3IgZT1tZXRob2RfdmVjLml0ZXJhdG9yKCk7IGUuaGFzTmV4dCgpOykgewotICAgICAgTWV0aG9kIG0gPSAoTWV0aG9kKWUubmV4dCgpOwotICAgICAgaWYobS5nZXROYW1lKCkuZXF1YWxzKG5hbWUpICYmIG0uZ2V0U2lnbmF0dXJlKCkuZXF1YWxzKHNpZ25hdHVyZSkpCi0gICAgICAgIHJldHVybiBtOwotICAgIH0KLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlbW92ZSBhbiBhdHRyaWJ1dGUgZnJvbSB0aGlzIGNsYXNzLgotICAgKiBAcGFyYW0gYSBhdHRyaWJ1dGUgdG8gcmVtb3ZlCi0gICAqLwotICBwdWJsaWMgdm9pZCByZW1vdmVBdHRyaWJ1dGUoQXR0cmlidXRlIGEpIHsgYXR0cmlidXRlX3ZlYy5yZW1vdmUoYSk7IH0KLQotICAvKioKLSAgICogUmVtb3ZlIGEgbWV0aG9kIGZyb20gdGhpcyBjbGFzcy4KLSAgICogQHBhcmFtIG0gbWV0aG9kIHRvIHJlbW92ZQotICAgKi8KLSAgcHVibGljIHZvaWQgcmVtb3ZlTWV0aG9kKE1ldGhvZCBtKSAgICAgICB7IG1ldGhvZF92ZWMucmVtb3ZlKG0pOyB9Ci0KLSAgLyoqIFJlcGxhY2UgZ2l2ZW4gbWV0aG9kIHdpdGggbmV3IG9uZS4gSWYgdGhlIG9sZCBvbmUgZG9lcyBub3QgZXhpc3QKLSAgICogYWRkIHRoZSBuZXdfIG1ldGhvZCB0byB0aGUgY2xhc3MgYW55d2F5LgotICAgKi8KLSAgcHVibGljIHZvaWQgcmVwbGFjZU1ldGhvZChNZXRob2Qgb2xkLCBNZXRob2QgbmV3XykgewotICAgIGlmKG5ld18gPT0gbnVsbCkKLSAgICAgIHRocm93IG5ldyBDbGFzc0dlbkV4Y2VwdGlvbigiUmVwbGFjZW1lbnQgbWV0aG9kIG11c3Qgbm90IGJlIG51bGwiKTsKLQotICAgIGludCBpID0gbWV0aG9kX3ZlYy5pbmRleE9mKG9sZCk7Ci0KLSAgICBpZihpIDwgMCkKLSAgICAgIG1ldGhvZF92ZWMuYWRkKG5ld18pOwotICAgIGVsc2UKLSAgICAgIG1ldGhvZF92ZWMuc2V0KGksIG5ld18pOwotICB9Ci0KLSAgLyoqIFJlcGxhY2UgZ2l2ZW4gZmllbGQgd2l0aCBuZXcgb25lLiBJZiB0aGUgb2xkIG9uZSBkb2VzIG5vdCBleGlzdAotICAgKiBhZGQgdGhlIG5ld18gZmllbGQgdG8gdGhlIGNsYXNzIGFueXdheS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHJlcGxhY2VGaWVsZChGaWVsZCBvbGQsIEZpZWxkIG5ld18pIHsKLSAgICBpZihuZXdfID09IG51bGwpCi0gICAgICB0aHJvdyBuZXcgQ2xhc3NHZW5FeGNlcHRpb24oIlJlcGxhY2VtZW50IG1ldGhvZCBtdXN0IG5vdCBiZSBudWxsIik7Ci0KLSAgICBpbnQgaSA9IGZpZWxkX3ZlYy5pbmRleE9mKG9sZCk7Ci0KLSAgICBpZihpIDwgMCkKLSAgICAgIGZpZWxkX3ZlYy5hZGQobmV3Xyk7Ci0gICAgZWxzZQotICAgICAgZmllbGRfdmVjLnNldChpLCBuZXdfKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZW1vdmUgYSBmaWVsZCB0byB0aGlzIGNsYXNzLgotICAgKiBAcGFyYW0gZiBmaWVsZCB0byByZW1vdmUKLSAgICovCi0gIHB1YmxpYyB2b2lkIHJlbW92ZUZpZWxkKEZpZWxkIGYpICAgICAgICAgeyBmaWVsZF92ZWMucmVtb3ZlKGYpOyB9Ci0KLSAgcHVibGljIFN0cmluZyBnZXRDbGFzc05hbWUoKSAgICAgIHsgcmV0dXJuIGNsYXNzX25hbWU7IH0KLSAgcHVibGljIFN0cmluZyBnZXRTdXBlcmNsYXNzTmFtZSgpIHsgcmV0dXJuIHN1cGVyX2NsYXNzX25hbWU7IH0KLSAgcHVibGljIFN0cmluZyBnZXRGaWxlTmFtZSgpICAgICAgIHsgcmV0dXJuIGZpbGVfbmFtZTsgfQotCi0gIHB1YmxpYyB2b2lkIHNldENsYXNzTmFtZShTdHJpbmcgbmFtZSkgewotICAgIGNsYXNzX25hbWUgPSBuYW1lLnJlcGxhY2UoJy8nLCAnLicpOwotICAgIGNsYXNzX25hbWVfaW5kZXggPSBjcC5hZGRDbGFzcyhuYW1lKTsKLSAgfQotCi0gIHB1YmxpYyB2b2lkIHNldFN1cGVyY2xhc3NOYW1lKFN0cmluZyBuYW1lKSB7Ci0gICAgc3VwZXJfY2xhc3NfbmFtZSA9IG5hbWUucmVwbGFjZSgnLycsICcuJyk7Ci0gICAgc3VwZXJjbGFzc19uYW1lX2luZGV4ID0gY3AuYWRkQ2xhc3MobmFtZSk7Ci0gIH0KLQotICBwdWJsaWMgTWV0aG9kW10gZ2V0TWV0aG9kcygpIHsKLSAgICBNZXRob2RbXSBtZXRob2RzID0gbmV3IE1ldGhvZFttZXRob2RfdmVjLnNpemUoKV07Ci0gICAgbWV0aG9kX3ZlYy50b0FycmF5KG1ldGhvZHMpOwotICAgIHJldHVybiBtZXRob2RzOwotICB9Ci0KLSAgcHVibGljIHZvaWQgc2V0TWV0aG9kcyhNZXRob2RbXSBtZXRob2RzKSB7Ci0gICAgbWV0aG9kX3ZlYy5jbGVhcigpOwotICAgIGZvcihpbnQgbT0wOyBtPG1ldGhvZHMubGVuZ3RoOyBtKyspCi0gICAgICBhZGRNZXRob2QobWV0aG9kc1ttXSk7Ci0gIH0KLQotICBwdWJsaWMgdm9pZCBzZXRNZXRob2RBdChNZXRob2QgbWV0aG9kLCBpbnQgcG9zKSB7Ci0gICAgbWV0aG9kX3ZlYy5zZXQocG9zLCBtZXRob2QpOwotICB9Ci0KLSAgcHVibGljIE1ldGhvZCBnZXRNZXRob2RBdChpbnQgcG9zKSB7Ci0gICAgcmV0dXJuIChNZXRob2QpbWV0aG9kX3ZlYy5nZXQocG9zKTsKLSAgfQotCi0gIHB1YmxpYyBTdHJpbmdbXSBnZXRJbnRlcmZhY2VOYW1lcygpIHsKLSAgICBpbnQgICAgICBzaXplID0gaW50ZXJmYWNlX3ZlYy5zaXplKCk7Ci0gICAgU3RyaW5nW10gaW50ZXJmYWNlcyA9IG5ldyBTdHJpbmdbc2l6ZV07Ci0KLSAgICBpbnRlcmZhY2VfdmVjLnRvQXJyYXkoaW50ZXJmYWNlcyk7Ci0gICAgcmV0dXJuIGludGVyZmFjZXM7Ci0gIH0KLQotICBwdWJsaWMgaW50W10gZ2V0SW50ZXJmYWNlcygpIHsKLSAgICBpbnQgICBzaXplID0gaW50ZXJmYWNlX3ZlYy5zaXplKCk7Ci0gICAgaW50W10gaW50ZXJmYWNlcyA9IG5ldyBpbnRbc2l6ZV07Ci0KLSAgICBmb3IoaW50IGk9MDsgaSA8IHNpemU7IGkrKykKLSAgICAgIGludGVyZmFjZXNbaV0gPSBjcC5hZGRDbGFzcygoU3RyaW5nKWludGVyZmFjZV92ZWMuZ2V0KGkpKTsKLQotICAgIHJldHVybiBpbnRlcmZhY2VzOwotICB9Ci0KLSAgcHVibGljIEZpZWxkW10gZ2V0RmllbGRzKCkgewotICAgIEZpZWxkW10gZmllbGRzID0gbmV3IEZpZWxkW2ZpZWxkX3ZlYy5zaXplKCldOwotICAgIGZpZWxkX3ZlYy50b0FycmF5KGZpZWxkcyk7Ci0gICAgcmV0dXJuIGZpZWxkczsKLSAgfQotCi0gIHB1YmxpYyBBdHRyaWJ1dGVbXSBnZXRBdHRyaWJ1dGVzKCkgewotICAgIEF0dHJpYnV0ZVtdIGF0dHJpYnV0ZXMgPSBuZXcgQXR0cmlidXRlW2F0dHJpYnV0ZV92ZWMuc2l6ZSgpXTsKLSAgICBhdHRyaWJ1dGVfdmVjLnRvQXJyYXkoYXR0cmlidXRlcyk7Ci0gICAgcmV0dXJuIGF0dHJpYnV0ZXM7Ci0gIH0KLQotICBwdWJsaWMgQ29uc3RhbnRQb29sR2VuIGdldENvbnN0YW50UG9vbCgpIHsgcmV0dXJuIGNwOyB9Ci0gIHB1YmxpYyB2b2lkIHNldENvbnN0YW50UG9vbChDb25zdGFudFBvb2xHZW4gY29uc3RhbnRfcG9vbCkgewotICAgIGNwID0gY29uc3RhbnRfcG9vbDsKLSAgfQotCi0gIHB1YmxpYyB2b2lkIHNldENsYXNzTmFtZUluZGV4KGludCBjbGFzc19uYW1lX2luZGV4KSB7Ci0gICAgdGhpcy5jbGFzc19uYW1lX2luZGV4ID0gY2xhc3NfbmFtZV9pbmRleDsKLSAgICBjbGFzc19uYW1lID0gY3AuZ2V0Q29uc3RhbnRQb29sKCkuCi0gICAgICBnZXRDb25zdGFudFN0cmluZyhjbGFzc19uYW1lX2luZGV4LCBDb25zdGFudHMuQ09OU1RBTlRfQ2xhc3MpLnJlcGxhY2UoJy8nLCAnLicpOwotICB9Ci0KLSAgcHVibGljIHZvaWQgc2V0U3VwZXJjbGFzc05hbWVJbmRleChpbnQgc3VwZXJjbGFzc19uYW1lX2luZGV4KSB7Ci0gICAgdGhpcy5zdXBlcmNsYXNzX25hbWVfaW5kZXggPSBzdXBlcmNsYXNzX25hbWVfaW5kZXg7Ci0gICAgc3VwZXJfY2xhc3NfbmFtZSA9IGNwLmdldENvbnN0YW50UG9vbCgpLgotICAgICAgZ2V0Q29uc3RhbnRTdHJpbmcoc3VwZXJjbGFzc19uYW1lX2luZGV4LCBDb25zdGFudHMuQ09OU1RBTlRfQ2xhc3MpLnJlcGxhY2UoJy8nLCAnLicpOwotICB9Ci0KLSAgcHVibGljIGludCBnZXRTdXBlcmNsYXNzTmFtZUluZGV4KCkgeyByZXR1cm4gc3VwZXJjbGFzc19uYW1lX2luZGV4OyB9Ci0KLSAgcHVibGljIGludCBnZXRDbGFzc05hbWVJbmRleCgpICAgeyByZXR1cm4gY2xhc3NfbmFtZV9pbmRleDsgfQotCi0gIHByaXZhdGUgQXJyYXlMaXN0IG9ic2VydmVyczsKLQotICAvKiogQWRkIG9ic2VydmVyIGZvciB0aGlzIG9iamVjdC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGFkZE9ic2VydmVyKENsYXNzT2JzZXJ2ZXIgbykgewotICAgIGlmKG9ic2VydmVycyA9PSBudWxsKQotICAgICAgb2JzZXJ2ZXJzID0gbmV3IEFycmF5TGlzdCgpOwotCi0gICAgb2JzZXJ2ZXJzLmFkZChvKTsKLSAgfQotCi0gIC8qKiBSZW1vdmUgb2JzZXJ2ZXIgZm9yIHRoaXMgb2JqZWN0LgotICAgKi8KLSAgcHVibGljIHZvaWQgcmVtb3ZlT2JzZXJ2ZXIoQ2xhc3NPYnNlcnZlciBvKSB7Ci0gICAgaWYob2JzZXJ2ZXJzICE9IG51bGwpCi0gICAgICBvYnNlcnZlcnMucmVtb3ZlKG8pOwotICB9Ci0KLSAgLyoqIENhbGwgbm90aWZ5KCkgbWV0aG9kIG9uIGFsbCBvYnNlcnZlcnMuIFRoaXMgbWV0aG9kIGlzIG5vdCBjYWxsZWQKLSAgICogYXV0b21hdGljYWxseSB3aGVuZXZlciB0aGUgc3RhdGUgaGFzIGNoYW5nZWQsIGJ1dCBoYXMgdG8gYmUKLSAgICogY2FsbGVkIGJ5IHRoZSB1c2VyIGFmdGVyIGhlIGhhcyBmaW5pc2hlZCBlZGl0aW5nIHRoZSBvYmplY3QuCi0gICAqLwotICBwdWJsaWMgdm9pZCB1cGRhdGUoKSB7Ci0gICAgaWYob2JzZXJ2ZXJzICE9IG51bGwpCi0gICAgICBmb3IoSXRlcmF0b3IgZSA9IG9ic2VydmVycy5pdGVyYXRvcigpOyBlLmhhc05leHQoKTsgKQotICAgICAgICAoKENsYXNzT2JzZXJ2ZXIpZS5uZXh0KCkpLm5vdGlmeSh0aGlzKTsKLSAgfQotCi0gIHB1YmxpYyBPYmplY3QgY2xvbmUoKSB7Ci0gICAgdHJ5IHsKLSAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwotICAgIH0gY2F0Y2goQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gZSkgewotICAgICAgU3lzdGVtLmVyci5wcmludGxuKGUpOwotICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9DbGFzc0dlbkV4Y2VwdGlvbi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvQ2xhc3NHZW5FeGNlcHRpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYmM0YmI3MS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9DbGFzc0dlbkV4Y2VwdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNzAgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotLyoqCi0gKiBUaHJvd24gb24gaW50ZXJuYWwgZXJyb3JzLiBFeHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24gc28gaXQgaGFzbid0IHRvIGJlIGRlY2xhcmVkCi0gKiBpbiB0aGUgdGhyb3dzIGNsYXVzZSBldmVyeSB0aW1lLgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBDbGFzc0dlbkV4Y2VwdGlvbiBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24gewotICBwdWJsaWMgQ2xhc3NHZW5FeGNlcHRpb24oKSB7IHN1cGVyKCk7IH0KLSAgcHVibGljIENsYXNzR2VuRXhjZXB0aW9uKFN0cmluZyBzKSB7IHN1cGVyKHMpOyB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9DbGFzc09ic2VydmVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9DbGFzc09ic2VydmVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDNlZjcxNGQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvQ2xhc3NPYnNlcnZlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNjkgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotLyoqCi0gKiBJbXBsZW1lbnQgdGhpcyBpbnRlcmZhY2UgaWYgeW91J3JlIGludGVyZXN0ZWQgaW4gY2hhbmdlcyB0byBhIENsYXNzR2VuIG9iamVjdAotICogYW5kIHJlZ2lzdGVyIHlvdXJzZWxmIHdpdGggYWRkT2JzZXJ2ZXIoKS4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgaW50ZXJmYWNlIENsYXNzT2JzZXJ2ZXIgewotICBwdWJsaWMgdm9pZCBub3RpZnkoQ2xhc3NHZW4gY2xhenopOwotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvQ29kZUV4Y2VwdGlvbkdlbi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvQ29kZUV4Y2VwdGlvbkdlbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwZmIyNTJiLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0NvZGVFeGNlcHRpb25HZW4uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIxMSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuY2xhc3NmaWxlLio7Ci0KLS8qKgotICogVGhpcyBjbGFzcyByZXByZXNlbnRzIGFuIGV4Y2VwdGlvbiBoYW5kbGVyLCBpLmUuLCBzcGVjaWZpZXMgdGhlICByZWdpb24gd2hlcmUKLSAqIGEgaGFuZGxlciBpcyBhY3RpdmUgYW5kIGFuIGluc3RydWN0aW9uIHdoZXJlIHRoZSBhY3R1YWwgaGFuZGxpbmcgaXMgZG9uZS4KLSAqIHBvb2wgYXMgcGFyYW1ldGVycy4gT3Bwb3NlZCB0byB0aGUgSlZNIHNwZWNpZmljYXRpb24gdGhlIGVuZCBvZiB0aGUgaGFuZGxlZAotICogcmVnaW9uIGlzIHNldCB0byBiZSBpbmNsdXNpdmUsIGkuZS4gYWxsIGluc3RydWN0aW9ucyBiZXR3ZWVuIHN0YXJ0IGFuZCBlbmQKLSAqIGFyZSBwcm90ZWN0ZWQgaW5jbHVkaW5nIHRoZSBzdGFydCBhbmQgZW5kIGluc3RydWN0aW9ucyAoaGFuZGxlcykgdGhlbXNlbHZlcy4KLSAqIFRoZSBlbmQgb2YgdGhlIHJlZ2lvbiBpcyBhdXRvbWF0aWNhbGx5IG1hcHBlZCB0byBiZSBleGNsdXNpdmUgd2hlbiBjYWxsaW5nCi0gKiBnZXRDb2RlRXhjZXB0aW9uKCksIGkuZS4sIHRoZXJlIGlzIG5vIGRpZmZlcmVuY2Ugc2VtYW50aWNhbGx5LgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKiBAc2VlICAgICBNZXRob2RHZW4KLSAqIEBzZWUgICAgIENvZGVFeGNlcHRpb24KLSAqIEBzZWUgICAgIEluc3RydWN0aW9uSGFuZGxlCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBDb2RlRXhjZXB0aW9uR2VuCi0gIGltcGxlbWVudHMgSW5zdHJ1Y3Rpb25UYXJnZXRlciwgQ2xvbmVhYmxlLCBqYXZhLmlvLlNlcmlhbGl6YWJsZSB7Ci0gIHByaXZhdGUgSW5zdHJ1Y3Rpb25IYW5kbGUgc3RhcnRfcGM7Ci0gIHByaXZhdGUgSW5zdHJ1Y3Rpb25IYW5kbGUgZW5kX3BjOwotICBwcml2YXRlIEluc3RydWN0aW9uSGFuZGxlIGhhbmRsZXJfcGM7Ci0gIHByaXZhdGUgT2JqZWN0VHlwZSAgICAgICAgY2F0Y2hfdHlwZTsKLQotICAvKioKLSAgICogQWRkIGFuIGV4Y2VwdGlvbiBoYW5kbGVyLCBpLmUuLCBzcGVjaWZ5IHJlZ2lvbiB3aGVyZSBhIGhhbmRsZXIgaXMgYWN0aXZlIGFuZCBhbgotICAgKiBpbnN0cnVjdGlvbiB3aGVyZSB0aGUgYWN0dWFsIGhhbmRsaW5nIGlzIGRvbmUuCi0gICAqCi0gICAqIEBwYXJhbSBzdGFydF9wYyBTdGFydCBvZiBoYW5kbGVkIHJlZ2lvbiAoaW5jbHVzaXZlKQotICAgKiBAcGFyYW0gZW5kX3BjIEVuZCBvZiBoYW5kbGVkIHJlZ2lvbiAoaW5jbHVzaXZlKQotICAgKiBAcGFyYW0gaGFuZGxlcl9wYyBXaGVyZSBoYW5kbGluZyBpcyBkb25lCi0gICAqIEBwYXJhbSBjYXRjaF90eXBlIHdoaWNoIGV4Y2VwdGlvbiBpcyBoYW5kbGVkLCBudWxsIGZvciBBTlkKLSAgICovCi0gIHB1YmxpYyBDb2RlRXhjZXB0aW9uR2VuKEluc3RydWN0aW9uSGFuZGxlIHN0YXJ0X3BjLCBJbnN0cnVjdGlvbkhhbmRsZSBlbmRfcGMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIEluc3RydWN0aW9uSGFuZGxlIGhhbmRsZXJfcGMsIE9iamVjdFR5cGUgY2F0Y2hfdHlwZSkgewotICAgIHNldFN0YXJ0UEMoc3RhcnRfcGMpOwotICAgIHNldEVuZFBDKGVuZF9wYyk7Ci0gICAgc2V0SGFuZGxlclBDKGhhbmRsZXJfcGMpOwotICAgIHRoaXMuY2F0Y2hfdHlwZSA9IGNhdGNoX3R5cGU7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IENvZGVFeGNlcHRpb24gb2JqZWN0LjxCUj4KLSAgICoKLSAgICogVGhpcyByZWxpZXMgb24gdGhhdCB0aGUgaW5zdHJ1Y3Rpb24gbGlzdCBoYXMgYWxyZWFkeSBiZWVuIGR1bXBlZAotICAgKiB0byBieXRlIGNvZGUgb3Igb3IgdGhhdCB0aGUgYHNldFBvc2l0aW9ucycgbWV0aG9kcyBoYXMgYmVlbgotICAgKiBjYWxsZWQgZm9yIHRoZSBpbnN0cnVjdGlvbiBsaXN0LgotICAgKgotICAgKiBAcGFyYW0gY3AgY29uc3RhbnQgcG9vbAotICAgKi8KLSAgcHVibGljIENvZGVFeGNlcHRpb24gZ2V0Q29kZUV4Y2VwdGlvbihDb25zdGFudFBvb2xHZW4gY3ApIHsKLSAgICByZXR1cm4gbmV3IENvZGVFeGNlcHRpb24oc3RhcnRfcGMuZ2V0UG9zaXRpb24oKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5kX3BjLmdldFBvc2l0aW9uKCkgKyBlbmRfcGMuZ2V0SW5zdHJ1Y3Rpb24oKS5nZXRMZW5ndGgoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlcl9wYy5nZXRQb3NpdGlvbigpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2F0Y2hfdHlwZSA9PSBudWxsKT8gMCA6IGNwLmFkZENsYXNzKGNhdGNoX3R5cGUpKTsKLSAgfQotCi0gIC8qIFNldCBzdGFydCBvZiBoYW5kbGVyCi0gICAqIEBwYXJhbSBzdGFydF9wYyBTdGFydCBvZiBoYW5kbGVkIHJlZ2lvbiAoaW5jbHVzaXZlKQotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgc2V0U3RhcnRQQyhJbnN0cnVjdGlvbkhhbmRsZSBzdGFydF9wYykgewotICAgIEJyYW5jaEluc3RydWN0aW9uLm5vdGlmeVRhcmdldENoYW5naW5nKHRoaXMuc3RhcnRfcGMsIHRoaXMpOwotICAgIHRoaXMuc3RhcnRfcGMgPSBzdGFydF9wYzsKLSAgICBCcmFuY2hJbnN0cnVjdGlvbi5ub3RpZnlUYXJnZXRDaGFuZ2VkKHRoaXMuc3RhcnRfcGMsIHRoaXMpOwotICB9Ci0KLSAgLyogU2V0IGVuZCBvZiBoYW5kbGVyCi0gICAqIEBwYXJhbSBlbmRfcGMgRW5kIG9mIGhhbmRsZWQgcmVnaW9uIChpbmNsdXNpdmUpCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBzZXRFbmRQQyhJbnN0cnVjdGlvbkhhbmRsZSBlbmRfcGMpIHsKLSAgICBCcmFuY2hJbnN0cnVjdGlvbi5ub3RpZnlUYXJnZXRDaGFuZ2luZyh0aGlzLmVuZF9wYywgdGhpcyk7Ci0gICAgdGhpcy5lbmRfcGMgPSBlbmRfcGM7Ci0gICAgQnJhbmNoSW5zdHJ1Y3Rpb24ubm90aWZ5VGFyZ2V0Q2hhbmdlZCh0aGlzLmVuZF9wYywgdGhpcyk7Ci0gIH0KLQotICAvKiBTZXQgaGFuZGxlciBjb2RlCi0gICAqIEBwYXJhbSBoYW5kbGVyX3BjIFN0YXJ0IG9mIGhhbmRsZXIKLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHNldEhhbmRsZXJQQyhJbnN0cnVjdGlvbkhhbmRsZSBoYW5kbGVyX3BjKSB7Ci0gICAgQnJhbmNoSW5zdHJ1Y3Rpb24ubm90aWZ5VGFyZ2V0Q2hhbmdpbmcodGhpcy5oYW5kbGVyX3BjLCB0aGlzKTsKLSAgICB0aGlzLmhhbmRsZXJfcGMgPSBoYW5kbGVyX3BjOwotICAgIEJyYW5jaEluc3RydWN0aW9uLm5vdGlmeVRhcmdldENoYW5nZWQodGhpcy5oYW5kbGVyX3BjLCB0aGlzKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gb2xkX2loIG9sZCB0YXJnZXQsIGVpdGhlciBzdGFydCBvciBlbmQKLSAgICogQHBhcmFtIG5ld19paCBuZXcgdGFyZ2V0Ci0gICAqLwotICBAT3ZlcnJpZGUKLSAgcHVibGljIHZvaWQgdXBkYXRlVGFyZ2V0KEluc3RydWN0aW9uSGFuZGxlIG9sZF9paCwgSW5zdHJ1Y3Rpb25IYW5kbGUgbmV3X2loKSB7Ci0gICAgYm9vbGVhbiB0YXJnZXRlZCA9IGZhbHNlOwotCi0gICAgaWYoc3RhcnRfcGMgPT0gb2xkX2loKSB7Ci0gICAgICB0YXJnZXRlZCA9IHRydWU7Ci0gICAgICBzZXRTdGFydFBDKG5ld19paCk7Ci0gICAgfQotCi0gICAgaWYoZW5kX3BjID09IG9sZF9paCkgewotICAgICAgdGFyZ2V0ZWQgPSB0cnVlOwotICAgICAgc2V0RW5kUEMobmV3X2loKTsKLSAgICB9Ci0KLSAgICBpZihoYW5kbGVyX3BjID09IG9sZF9paCkgewotICAgICAgdGFyZ2V0ZWQgPSB0cnVlOwotICAgICAgc2V0SGFuZGxlclBDKG5ld19paCk7Ci0gICAgfQotCi0gICAgaWYoIXRhcmdldGVkKQotICAgICAgdGhyb3cgbmV3IENsYXNzR2VuRXhjZXB0aW9uKCJOb3QgdGFyZ2V0aW5nICIgKyBvbGRfaWggKyAiLCBidXQgeyIgKyBzdGFydF9wYyArICIsICIgKwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuZF9wYyArICIsICIgKyBoYW5kbGVyX3BjICsgIn0iKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIHRydWUsIGlmIGloIGlzIHRhcmdldCBvZiB0aGlzIGhhbmRsZXIKLSAgICovCi0gIEBPdmVycmlkZQotICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1RhcmdldChJbnN0cnVjdGlvbkhhbmRsZSBpaCkgewotICAgIHJldHVybiAoc3RhcnRfcGMgPT0gaWgpIHx8IChlbmRfcGMgPT0gaWgpIHx8IChoYW5kbGVyX3BjID09IGloKTsKLSAgfQotCi0gIC8qKiBTZXRzIHRoZSB0eXBlIG9mIHRoZSBFeGNlcHRpb24gdG8gY2F0Y2guIFNldCAnbnVsbCcgZm9yIEFOWS4gKi8KLSAgcHVibGljIHZvaWQgICAgICAgICAgICAgIHNldENhdGNoVHlwZShPYmplY3RUeXBlIGNhdGNoX3R5cGUpICAgICAgICB7IHRoaXMuY2F0Y2hfdHlwZSA9IGNhdGNoX3R5cGU7IH0KLSAgLyoqIEdldHMgdGhlIHR5cGUgb2YgdGhlIEV4Y2VwdGlvbiB0byBjYXRjaCwgJ251bGwnIGZvciBBTlkuICovCi0gIHB1YmxpYyBPYmplY3RUeXBlICAgICAgICBnZXRDYXRjaFR5cGUoKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gY2F0Y2hfdHlwZTsgfQotCi0gIC8qKiBAcmV0dXJuIHN0YXJ0IG9mIGhhbmRsZWQgcmVnaW9uIChpbmNsdXNpdmUpCi0gICAqLwotICBwdWJsaWMgSW5zdHJ1Y3Rpb25IYW5kbGUgZ2V0U3RhcnRQQygpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIHN0YXJ0X3BjOyB9Ci0KLSAgLyoqIEByZXR1cm4gZW5kIG9mIGhhbmRsZWQgcmVnaW9uIChpbmNsdXNpdmUpCi0gICAqLwotICBwdWJsaWMgSW5zdHJ1Y3Rpb25IYW5kbGUgZ2V0RW5kUEMoKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIGVuZF9wYzsgfQotCi0gIC8qKiBAcmV0dXJuIHN0YXJ0IG9mIGhhbmRsZXIKLSAgICovCi0gIHB1YmxpYyBJbnN0cnVjdGlvbkhhbmRsZSBnZXRIYW5kbGVyUEMoKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gaGFuZGxlcl9wYzsgfQotCi0gIEBPdmVycmlkZQotICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgIHJldHVybiAiQ29kZUV4Y2VwdGlvbkdlbigiICsgc3RhcnRfcGMgKyAiLCAiICsgZW5kX3BjICsgIiwgIiArIGhhbmRsZXJfcGMgKyAiKSI7Ci0gIH0KLQotICBAT3ZlcnJpZGUKLSAgcHVibGljIE9iamVjdCBjbG9uZSgpIHsKLSAgICB0cnkgewotICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7Ci0gICAgfSBjYXRjaChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKSB7Ci0gICAgICBTeXN0ZW0uZXJyLnByaW50bG4oZSk7Ci0gICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0NvbXBvdW5kSW5zdHJ1Y3Rpb24uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0NvbXBvdW5kSW5zdHJ1Y3Rpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYjU0M2EyZS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9Db21wb3VuZEluc3RydWN0aW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3OCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIFdyYXBwZXIgY2xhc3MgZm9yIGBjb21wb3VuZCcgb3BlcmF0aW9ucywgdmlydHVhbCBpbnN0cnVjdGlvbnMgdGhhdAotICogZG9uJ3QgZXhpc3QgYXMgYnl0ZSBjb2RlLCBidXQgZ2l2ZSBhIHVzZWZ1bCBtZWFuaW5nLiBGb3IgZXhhbXBsZSwKLSAqIHRoZSAodmlydHVhbCkgUFVTSCBpbnN0cnVjdGlvbiB0YWtlcyBhbiBhcmJpdHJheSBhcmd1bWVudCBhbmQgcHJvZHVjZXMgdGhlCi0gKiBhcHByb3BpYXRlIGNvZGUgYXQgZHVtcCB0aW1lIChJQ09OU1QsIExEQywgQklQVVNILCAuLi4pLiBBbHNvIHlvdSBjYW4gdXNlIHRoZQotICogU1dJVENIIGluc3RydWN0aW9uIGFzIGEgdXNlZnVsIHRlbXBsYXRlIGZvciBlaXRoZXIgTE9PS1VQU1dJVENIIG9yCi0gKiBUQUJMRVNXSVRDSC4KLSAqCi0gKiBUaGUgaW50ZXJmYWNlIHByb3ZpZGVzIHRoZSBwb3NzaWJpbHR5IGZvciB0aGUgdXNlciB0byB3cml0ZQotICogYHRlbXBsYXRlcycgb3IgYG1hY3JvcycgZm9yIHN1Y2ggcmV1c2VhYmxlIGNvZGUgcGF0dGVybnMuCi0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqIEBzZWUgUFVTSAotICogQHNlZSBTV0lUQ0gKLSAqLwotcHVibGljIGludGVyZmFjZSBDb21wb3VuZEluc3RydWN0aW9uIHsKLSAgcHVibGljIEluc3RydWN0aW9uTGlzdCBnZXRJbnN0cnVjdGlvbkxpc3QoKTsKLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0NvbnN0YW50UG9vbEdlbi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvQ29uc3RhbnRQb29sR2VuLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDFiNTNhZWIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvQ29uc3RhbnRQb29sR2VuLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3ODkgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50czsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5jbGFzc2ZpbGUuKjsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGlzIHVzZWQgdG8gYnVpbGQgdXAgYSBjb25zdGFudCBwb29sLiBUaGUgdXNlciBhZGRzCi0gKiBjb25zdGFudHMgdmlhIGBhZGRYWFgnIG1ldGhvZHMsIGBhZGRTdHJpbmcnLCBgYWRkQ2xhc3MnLAotICogZXRjLi4gVGhlc2UgbWV0aG9kcyByZXR1cm4gYW4gaW5kZXggaW50byB0aGUgY29uc3RhbnQKLSAqIHBvb2wuIEZpbmFsbHksIGBnZXRGaW5hbENvbnN0YW50UG9vbCgpJyByZXR1cm5zIHRoZSBjb25zdGFudCBwb29sCi0gKiBidWlsdCB1cC4gSW50ZXJtZWRpYXRlIHZlcnNpb25zIG9mIHRoZSBjb25zdGFudCBwb29sIGNhbiBiZQotICogb2J0YWluZWQgd2l0aCBgZ2V0Q29uc3RhbnRQb29sKCknLiBBIGNvbnN0YW50IHBvb2wgaGFzIGNhcGFjaXR5IGZvcgotICogQ29uc3RhbnRzLk1BWF9TSE9SVCBlbnRyaWVzLiBOb3RlIHRoYXQgdGhlIGZpcnN0ICgwKSBpcyB1c2VkIGJ5IHRoZQotICogSlZNIGFuZCB0aGF0IERvdWJsZSBhbmQgTG9uZyBjb25zdGFudHMgbmVlZCB0d28gc2xvdHMuCi0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqIEBzZWUgQ29uc3RhbnQKLSAqLwotcHVibGljIGNsYXNzIENvbnN0YW50UG9vbEdlbiBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKLSAgcHJvdGVjdGVkIGludCAgICAgICAgc2l6ZSAgICAgID0gMTAyNDsgLy8gSW5pdGFsIHNpemUsIHN1ZmZpY2llbnQgaW4gbW9zdCBjYXNlcwotICBwcm90ZWN0ZWQgQ29uc3RhbnRbXSBjb25zdGFudHMgPSBuZXcgQ29uc3RhbnRbc2l6ZV07Ci0gIHByb3RlY3RlZCBpbnQgICAgICAgIGluZGV4ICAgICA9IDE7IC8vIEZpcnN0IGVudHJ5ICgwKSB1c2VkIGJ5IEpWTQotCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBNRVRIT0RSRUZfREVMSU0gID0gIjoiOwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgSU1FVEhPRFJFRl9ERUxJTSA9ICIjIjsKLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEZJRUxEUkVGX0RFTElNICAgPSAiJiI7Ci0gIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBOQVRfREVMSU0gICAgICAgID0gIiUiOwotCi0gIHByaXZhdGUgc3RhdGljIGNsYXNzIEluZGV4IGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUgewotICAgIGludCBpbmRleDsKLSAgICBJbmRleChpbnQgaSkgeyBpbmRleCA9IGk7IH0KLSAgfQotCi0gIC8qKgotICAgKiBJbml0aWFsaXplIHdpdGggZ2l2ZW4gYXJyYXkgb2YgY29uc3RhbnRzLgotICAgKgotICAgKiBAcGFyYW0gYyBhcnJheSBvZiBnaXZlbiBjb25zdGFudHMsIG5ldyBvbmVzIHdpbGwgYmUgYXBwZW5kZWQKLSAgICovCi0gIHB1YmxpYyBDb25zdGFudFBvb2xHZW4oQ29uc3RhbnRbXSBjcykgewotICAgIGlmKGNzLmxlbmd0aCA+IHNpemUpIHsKLSAgICAgIHNpemUgICAgICA9IGNzLmxlbmd0aDsKLSAgICAgIGNvbnN0YW50cyA9IG5ldyBDb25zdGFudFtzaXplXTsKLSAgICB9Ci0KLSAgICBTeXN0ZW0uYXJyYXljb3B5KGNzLCAwLCBjb25zdGFudHMsIDAsIGNzLmxlbmd0aCk7Ci0KLSAgICBpZihjcy5sZW5ndGggPiAwKQotICAgICAgaW5kZXggPSBjcy5sZW5ndGg7Ci0KLSAgICBmb3IoaW50IGk9MTsgaSA8IGluZGV4OyBpKyspIHsKLSAgICAgIENvbnN0YW50IGMgPSBjb25zdGFudHNbaV07Ci0KLSAgICAgIGlmKGMgaW5zdGFuY2VvZiBDb25zdGFudFN0cmluZykgewotICAgICAgICBDb25zdGFudFN0cmluZyBzICA9IChDb25zdGFudFN0cmluZyljOwotICAgICAgICBDb25zdGFudFV0ZjggICB1OCA9IChDb25zdGFudFV0ZjgpY29uc3RhbnRzW3MuZ2V0U3RyaW5nSW5kZXgoKV07Ci0KLSAgICAgICAgc3RyaW5nX3RhYmxlLnB1dCh1OC5nZXRCeXRlcygpLCBuZXcgSW5kZXgoaSkpOwotICAgICAgfSBlbHNlIGlmKGMgaW5zdGFuY2VvZiBDb25zdGFudENsYXNzKSB7Ci0gICAgICAgIENvbnN0YW50Q2xhc3MgcyAgPSAoQ29uc3RhbnRDbGFzcyljOwotICAgICAgICBDb25zdGFudFV0ZjggIHU4ID0gKENvbnN0YW50VXRmOCljb25zdGFudHNbcy5nZXROYW1lSW5kZXgoKV07Ci0KLSAgICAgICAgY2xhc3NfdGFibGUucHV0KHU4LmdldEJ5dGVzKCksIG5ldyBJbmRleChpKSk7Ci0gICAgICB9IGVsc2UgaWYoYyBpbnN0YW5jZW9mIENvbnN0YW50TmFtZUFuZFR5cGUpIHsKLSAgICAgICAgQ29uc3RhbnROYW1lQW5kVHlwZSBuICAgID0gKENvbnN0YW50TmFtZUFuZFR5cGUpYzsKLSAgICAgICAgQ29uc3RhbnRVdGY4ICAgICAgICB1OCAgID0gKENvbnN0YW50VXRmOCljb25zdGFudHNbbi5nZXROYW1lSW5kZXgoKV07Ci0gICAgICAgIENvbnN0YW50VXRmOCAgICAgICAgdThfMiA9IChDb25zdGFudFV0ZjgpY29uc3RhbnRzW24uZ2V0U2lnbmF0dXJlSW5kZXgoKV07Ci0KLSAgICAgICAgbl9hX3RfdGFibGUucHV0KHU4LmdldEJ5dGVzKCkgKyBOQVRfREVMSU0gKyB1OF8yLmdldEJ5dGVzKCksIG5ldyBJbmRleChpKSk7Ci0gICAgICAgfSBlbHNlIGlmKGMgaW5zdGFuY2VvZiBDb25zdGFudFV0ZjgpIHsKLSAgICAgICAgIENvbnN0YW50VXRmOCB1ID0gKENvbnN0YW50VXRmOCljOwotCi0gICAgICAgICB1dGY4X3RhYmxlLnB1dCh1LmdldEJ5dGVzKCksIG5ldyBJbmRleChpKSk7Ci0gICAgICB9IGVsc2UgaWYoYyBpbnN0YW5jZW9mIENvbnN0YW50Q1ApIHsKLSAgICAgICAgQ29uc3RhbnRDUCAgICAgICAgICBtICAgICA9IChDb25zdGFudENQKWM7Ci0gICAgICAgIENvbnN0YW50Q2xhc3MgICAgICAgY2xhenogPSAoQ29uc3RhbnRDbGFzcyljb25zdGFudHNbbS5nZXRDbGFzc0luZGV4KCldOwotICAgICAgICBDb25zdGFudE5hbWVBbmRUeXBlIG4gICAgID0gKENvbnN0YW50TmFtZUFuZFR5cGUpY29uc3RhbnRzW20uZ2V0TmFtZUFuZFR5cGVJbmRleCgpXTsKLQotICAgICAgICBDb25zdGFudFV0ZjggdTggICAgICAgICA9IChDb25zdGFudFV0ZjgpY29uc3RhbnRzW2NsYXp6LmdldE5hbWVJbmRleCgpXTsKLSAgICAgICAgU3RyaW5nICAgICAgIGNsYXNzX25hbWUgPSB1OC5nZXRCeXRlcygpLnJlcGxhY2UoJy8nLCAnLicpOwotCi0gICAgICAgIHU4ID0gKENvbnN0YW50VXRmOCljb25zdGFudHNbbi5nZXROYW1lSW5kZXgoKV07Ci0gICAgICAgIFN0cmluZyBtZXRob2RfbmFtZSA9IHU4LmdldEJ5dGVzKCk7Ci0KLSAgICAgICAgdTggPSAoQ29uc3RhbnRVdGY4KWNvbnN0YW50c1tuLmdldFNpZ25hdHVyZUluZGV4KCldOwotICAgICAgICBTdHJpbmcgc2lnbmF0dXJlID0gdTguZ2V0Qnl0ZXMoKTsKLQotICAgICAgICBTdHJpbmcgZGVsaW0gPSBNRVRIT0RSRUZfREVMSU07Ci0KLSAgICAgICAgaWYoYyBpbnN0YW5jZW9mIENvbnN0YW50SW50ZXJmYWNlTWV0aG9kcmVmKQotICAgICAgICAgIGRlbGltID0gSU1FVEhPRFJFRl9ERUxJTTsKLSAgICAgICAgZWxzZSBpZihjIGluc3RhbmNlb2YgQ29uc3RhbnRGaWVsZHJlZikKLSAgICAgICAgICBkZWxpbSA9IEZJRUxEUkVGX0RFTElNOwotCi0gICAgICAgIGNwX3RhYmxlLnB1dChjbGFzc19uYW1lICsgZGVsaW0gKyBtZXRob2RfbmFtZSArIGRlbGltICsgc2lnbmF0dXJlLCBuZXcgSW5kZXgoaSkpOwotICAgICAgfQotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBJbml0aWFsaXplIHdpdGggZ2l2ZW4gY29uc3RhbnQgcG9vbC4KLSAgICovCi0gIHB1YmxpYyBDb25zdGFudFBvb2xHZW4oQ29uc3RhbnRQb29sIGNwKSB7Ci0gICAgdGhpcyhjcC5nZXRDb25zdGFudFBvb2woKSk7Ci0gIH0KLQotICAvKioKLSAgICogQ3JlYXRlIGVtcHR5IGNvbnN0YW50IHBvb2wuCi0gICAqLwotICBwdWJsaWMgQ29uc3RhbnRQb29sR2VuKCkge30KLQotICAvKiogUmVzaXplIGludGVybmFsIGFycmF5IG9mIGNvbnN0YW50cy4KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIGFkanVzdFNpemUoKSB7Ci0gICAgaWYoaW5kZXggKyAzID49IHNpemUpIHsKLSAgICAgIENvbnN0YW50W10gY3MgPSBjb25zdGFudHM7Ci0KLSAgICAgIHNpemUgICAgICAqPSAyOwotICAgICAgY29uc3RhbnRzICA9IG5ldyBDb25zdGFudFtzaXplXTsKLSAgICAgIFN5c3RlbS5hcnJheWNvcHkoY3MsIDAsIGNvbnN0YW50cywgMCwgaW5kZXgpOwotICAgIH0KLSAgfQotCi0gIHByaXZhdGUgSGFzaE1hcCBzdHJpbmdfdGFibGUgPSBuZXcgSGFzaE1hcCgpOwotCi0gIC8qKgotICAgKiBMb29rIGZvciBDb25zdGFudFN0cmluZyBpbiBDb25zdGFudFBvb2wgY29udGFpbmluZyBTdHJpbmcgYHN0cicuCi0gICAqCi0gICAqIEBwYXJhbSBzdHIgU3RyaW5nIHRvIHNlYXJjaCBmb3IKLSAgICogQHJldHVybiBpbmRleCBvbiBzdWNjZXNzLCAtMSBvdGhlcndpc2UKLSAgICovCi0gIHB1YmxpYyBpbnQgbG9va3VwU3RyaW5nKFN0cmluZyBzdHIpIHsKLSAgICBJbmRleCBpbmRleCA9IChJbmRleClzdHJpbmdfdGFibGUuZ2V0KHN0cik7Ci0gICAgcmV0dXJuIChpbmRleCAhPSBudWxsKT8gaW5kZXguaW5kZXggOiAtMTsKLSAgfQotCi0gIC8qKgotICAgKiBBZGQgYSBuZXcgU3RyaW5nIGNvbnN0YW50IHRvIHRoZSBDb25zdGFudFBvb2wsIGlmIGl0IGlzIG5vdCBhbHJlYWR5IGluIHRoZXJlLgotICAgKgotICAgKiBAcGFyYW0gc3RyIFN0cmluZyB0byBhZGQKLSAgICogQHJldHVybiBpbmRleCBvZiBlbnRyeQotICAgKi8KLSAgcHVibGljIGludCBhZGRTdHJpbmcoU3RyaW5nIHN0cikgewotICAgIGludCByZXQ7Ci0KLSAgICBpZigocmV0ID0gbG9va3VwU3RyaW5nKHN0cikpICE9IC0xKQotICAgICAgcmV0dXJuIHJldDsgLy8gQWxyZWFkeSBpbiBDUAotCi0gICAgaW50IHV0ZjggPSBhZGRVdGY4KHN0cik7Ci0KLSAgICBhZGp1c3RTaXplKCk7Ci0KLSAgICBDb25zdGFudFN0cmluZyBzICA9IG5ldyBDb25zdGFudFN0cmluZyh1dGY4KTsKLQotICAgIHJldCA9IGluZGV4OwotICAgIGNvbnN0YW50c1tpbmRleCsrXSA9IHM7Ci0KLSAgICBzdHJpbmdfdGFibGUucHV0KHN0ciwgbmV3IEluZGV4KHJldCkpOwotCi0gICAgcmV0dXJuIHJldDsKLSAgfQotCi0gIHByaXZhdGUgSGFzaE1hcCBjbGFzc190YWJsZSA9IG5ldyBIYXNoTWFwKCk7Ci0KLSAgLyoqCi0gICAqIExvb2sgZm9yIENvbnN0YW50Q2xhc3MgaW4gQ29uc3RhbnRQb29sIG5hbWVkIGBzdHInLgotICAgKgotICAgKiBAcGFyYW0gc3RyIFN0cmluZyB0byBzZWFyY2ggZm9yCi0gICAqIEByZXR1cm4gaW5kZXggb24gc3VjY2VzcywgLTEgb3RoZXJ3aXNlCi0gICAqLwotICBwdWJsaWMgaW50IGxvb2t1cENsYXNzKFN0cmluZyBzdHIpIHsKLSAgICBJbmRleCBpbmRleCA9IChJbmRleCljbGFzc190YWJsZS5nZXQoc3RyLnJlcGxhY2UoJy4nLCAnLycpKTsKLSAgICByZXR1cm4gKGluZGV4ICE9IG51bGwpPyBpbmRleC5pbmRleCA6IC0xOwotICB9Ci0KLSAgcHJpdmF0ZSBpbnQgYWRkQ2xhc3NfKFN0cmluZyBjbGF6eikgewotICAgIGludCAgICByZXQ7Ci0KLSAgICBpZigocmV0ID0gbG9va3VwQ2xhc3MoY2xhenopKSAhPSAtMSkKLSAgICAgIHJldHVybiByZXQ7IC8vIEFscmVhZHkgaW4gQ1AKLQotICAgIGFkanVzdFNpemUoKTsKLQotICAgIENvbnN0YW50Q2xhc3MgYyA9IG5ldyBDb25zdGFudENsYXNzKGFkZFV0ZjgoY2xhenopKTsKLQotICAgIHJldCA9IGluZGV4OwotICAgIGNvbnN0YW50c1tpbmRleCsrXSA9IGM7Ci0KLSAgICBjbGFzc190YWJsZS5wdXQoY2xhenosIG5ldyBJbmRleChyZXQpKTsKLQotICAgIHJldHVybiByZXQ7Ci0gIH0KLQotICAvKioKLSAgICogQWRkIGEgbmV3IENsYXNzIHJlZmVyZW5jZSB0byB0aGUgQ29uc3RhbnRQb29sLCBpZiBpdCBpcyBub3QgYWxyZWFkeSBpbiB0aGVyZS4KLSAgICoKLSAgICogQHBhcmFtIHN0ciBDbGFzcyB0byBhZGQKLSAgICogQHJldHVybiBpbmRleCBvZiBlbnRyeQotICAgKi8KLSAgcHVibGljIGludCBhZGRDbGFzcyhTdHJpbmcgc3RyKSB7Ci0gICAgcmV0dXJuIGFkZENsYXNzXyhzdHIucmVwbGFjZSgnLicsICcvJykpOwotICB9Ci0KLSAgLyoqCi0gICAqIEFkZCBhIG5ldyBDbGFzcyByZWZlcmVuY2UgdG8gdGhlIENvbnN0YW50UG9vbCBmb3IgYSBnaXZlbiB0eXBlLgotICAgKgotICAgKiBAcGFyYW0gc3RyIENsYXNzIHRvIGFkZAotICAgKiBAcmV0dXJuIGluZGV4IG9mIGVudHJ5Ci0gICAqLwotICBwdWJsaWMgaW50IGFkZENsYXNzKE9iamVjdFR5cGUgdHlwZSkgewotICAgIHJldHVybiBhZGRDbGFzcyh0eXBlLmdldENsYXNzTmFtZSgpKTsKLSAgfQotCi0gIC8qKgotICAgKiBBZGQgYSByZWZlcmVuY2UgdG8gYW4gYXJyYXkgY2xhc3MgKGUuZy4gU3RyaW5nW11bXSkgYXMgbmVlZGVkIGJ5IE1VTFRJQU5FV0FSUkFZCi0gICAqIGluc3RydWN0aW9uLCBlLmcuIHRvIHRoZSBDb25zdGFudFBvb2wuCi0gICAqCi0gICAqIEBwYXJhbSB0eXBlIHR5cGUgb2YgYXJyYXkgY2xhc3MKLSAgICogQHJldHVybiBpbmRleCBvZiBlbnRyeQotICAgKi8KLSAgcHVibGljIGludCBhZGRBcnJheUNsYXNzKEFycmF5VHlwZSB0eXBlKSB7Ci0gICAgcmV0dXJuIGFkZENsYXNzXyh0eXBlLmdldFNpZ25hdHVyZSgpKTsKLSAgfQotCi0gIC8qKgotICAgKiBMb29rIGZvciBDb25zdGFudEludGVnZXIgaW4gQ29uc3RhbnRQb29sLgotICAgKgotICAgKiBAcGFyYW0gbiBpbnRlZ2VyIG51bWJlciB0byBsb29rIGZvcgotICAgKiBAcmV0dXJuIGluZGV4IG9uIHN1Y2Nlc3MsIC0xIG90aGVyd2lzZQotICAgKi8KLSAgcHVibGljIGludCBsb29rdXBJbnRlZ2VyKGludCBuKSB7Ci0gICAgZm9yKGludCBpPTE7IGkgPCBpbmRleDsgaSsrKSB7Ci0gICAgICBpZihjb25zdGFudHNbaV0gaW5zdGFuY2VvZiBDb25zdGFudEludGVnZXIpIHsKLSAgICAgICAgQ29uc3RhbnRJbnRlZ2VyIGMgPSAoQ29uc3RhbnRJbnRlZ2VyKWNvbnN0YW50c1tpXTsKLQotICAgICAgICBpZihjLmdldEJ5dGVzKCkgPT0gbikKLSAgICAgICAgICByZXR1cm4gaTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gLTE7Ci0gIH0KLQotICAvKioKLSAgICogQWRkIGEgbmV3IEludGVnZXIgY29uc3RhbnQgdG8gdGhlIENvbnN0YW50UG9vbCwgaWYgaXQgaXMgbm90IGFscmVhZHkgaW4gdGhlcmUuCi0gICAqCi0gICAqIEBwYXJhbSBuIGludGVnZXIgbnVtYmVyIHRvIGFkZAotICAgKiBAcmV0dXJuIGluZGV4IG9mIGVudHJ5Ci0gICAqLwotICBwdWJsaWMgaW50IGFkZEludGVnZXIoaW50IG4pIHsKLSAgICBpbnQgIHJldDsKLQotICAgIGlmKChyZXQgPSBsb29rdXBJbnRlZ2VyKG4pKSAhPSAtMSkKLSAgICAgIHJldHVybiByZXQ7IC8vIEFscmVhZHkgaW4gQ1AKLQotICAgIGFkanVzdFNpemUoKTsKLQotICAgIHJldCA9IGluZGV4OwotICAgIGNvbnN0YW50c1tpbmRleCsrXSA9IG5ldyBDb25zdGFudEludGVnZXIobik7Ci0KLSAgICByZXR1cm4gcmV0OwotICB9Ci0KLSAgLyoqCi0gICAqIExvb2sgZm9yIENvbnN0YW50RmxvYXQgaW4gQ29uc3RhbnRQb29sLgotICAgKgotICAgKiBAcGFyYW0gbiBGbG9hdCBudW1iZXIgdG8gbG9vayBmb3IKLSAgICogQHJldHVybiBpbmRleCBvbiBzdWNjZXNzLCAtMSBvdGhlcndpc2UKLSAgICovCi0gIHB1YmxpYyBpbnQgbG9va3VwRmxvYXQoZmxvYXQgbikgewotICAgIGludCBiaXRzID0gRmxvYXQuZmxvYXRUb0ludEJpdHMobik7Ci0KLSAgICBmb3IoaW50IGk9MTsgaSA8IGluZGV4OyBpKyspIHsKLSAgICAgIGlmKGNvbnN0YW50c1tpXSBpbnN0YW5jZW9mIENvbnN0YW50RmxvYXQpIHsKLSAgICAgICAgQ29uc3RhbnRGbG9hdCBjID0gKENvbnN0YW50RmxvYXQpY29uc3RhbnRzW2ldOwotCi0gICAgICAgIGlmKEZsb2F0LmZsb2F0VG9JbnRCaXRzKGMuZ2V0Qnl0ZXMoKSkgPT0gYml0cykKLSAgICAgICAgICByZXR1cm4gaTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gLTE7Ci0gIH0KLQotICAvKioKLSAgICogQWRkIGEgbmV3IEZsb2F0IGNvbnN0YW50IHRvIHRoZSBDb25zdGFudFBvb2wsIGlmIGl0IGlzIG5vdCBhbHJlYWR5IGluIHRoZXJlLgotICAgKgotICAgKiBAcGFyYW0gbiBGbG9hdCBudW1iZXIgdG8gYWRkCi0gICAqIEByZXR1cm4gaW5kZXggb2YgZW50cnkKLSAgICovCi0gIHB1YmxpYyBpbnQgYWRkRmxvYXQoZmxvYXQgbikgewotICAgIGludCAgcmV0OwotCi0gICAgaWYoKHJldCA9IGxvb2t1cEZsb2F0KG4pKSAhPSAtMSkKLSAgICAgIHJldHVybiByZXQ7IC8vIEFscmVhZHkgaW4gQ1AKLQotICAgIGFkanVzdFNpemUoKTsKLQotICAgIHJldCA9IGluZGV4OwotICAgIGNvbnN0YW50c1tpbmRleCsrXSA9IG5ldyBDb25zdGFudEZsb2F0KG4pOwotCi0gICAgcmV0dXJuIHJldDsKLSAgfQotCi0gIHByaXZhdGUgSGFzaE1hcCB1dGY4X3RhYmxlID0gbmV3IEhhc2hNYXAoKTsKLQotICAvKioKLSAgICogTG9vayBmb3IgQ29uc3RhbnRVdGY4IGluIENvbnN0YW50UG9vbC4KLSAgICoKLSAgICogQHBhcmFtIG4gVXRmOCBzdHJpbmcgdG8gbG9vayBmb3IKLSAgICogQHJldHVybiBpbmRleCBvbiBzdWNjZXNzLCAtMSBvdGhlcndpc2UKLSAgICovCi0gIHB1YmxpYyBpbnQgbG9va3VwVXRmOChTdHJpbmcgbikgewotICAgIEluZGV4IGluZGV4ID0gKEluZGV4KXV0ZjhfdGFibGUuZ2V0KG4pOwotCi0gICAgcmV0dXJuIChpbmRleCAhPSBudWxsKT8gaW5kZXguaW5kZXggOiAtMTsKLSAgfQotCi0gIC8qKgotICAgKiBBZGQgYSBuZXcgVXRmOCBjb25zdGFudCB0byB0aGUgQ29uc3RhbnRQb29sLCBpZiBpdCBpcyBub3QgYWxyZWFkeSBpbiB0aGVyZS4KLSAgICoKLSAgICogQHBhcmFtIG4gVXRmOCBzdHJpbmcgdG8gYWRkCi0gICAqIEByZXR1cm4gaW5kZXggb2YgZW50cnkKLSAgICovCi0gIHB1YmxpYyBpbnQgYWRkVXRmOChTdHJpbmcgbikgewotICAgIGludCAgcmV0OwotCi0gICAgaWYoKHJldCA9IGxvb2t1cFV0ZjgobikpICE9IC0xKQotICAgICAgcmV0dXJuIHJldDsgLy8gQWxyZWFkeSBpbiBDUAotCi0gICAgYWRqdXN0U2l6ZSgpOwotCi0gICAgcmV0ID0gaW5kZXg7Ci0gICAgY29uc3RhbnRzW2luZGV4KytdID0gbmV3IENvbnN0YW50VXRmOChuKTsKLQotICAgIHV0ZjhfdGFibGUucHV0KG4sIG5ldyBJbmRleChyZXQpKTsKLQotICAgIHJldHVybiByZXQ7Ci0gIH0KLQotICAvKioKLSAgICogTG9vayBmb3IgQ29uc3RhbnRMb25nIGluIENvbnN0YW50UG9vbC4KLSAgICoKLSAgICogQHBhcmFtIG4gTG9uZyBudW1iZXIgdG8gbG9vayBmb3IKLSAgICogQHJldHVybiBpbmRleCBvbiBzdWNjZXNzLCAtMSBvdGhlcndpc2UKLSAgICovCi0gIHB1YmxpYyBpbnQgbG9va3VwTG9uZyhsb25nIG4pIHsKLSAgICBmb3IoaW50IGk9MTsgaSA8IGluZGV4OyBpKyspIHsKLSAgICAgIGlmKGNvbnN0YW50c1tpXSBpbnN0YW5jZW9mIENvbnN0YW50TG9uZykgewotICAgICAgICBDb25zdGFudExvbmcgYyA9IChDb25zdGFudExvbmcpY29uc3RhbnRzW2ldOwotCi0gICAgICAgIGlmKGMuZ2V0Qnl0ZXMoKSA9PSBuKQotICAgICAgICAgIHJldHVybiBpOwotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiAtMTsKLSAgfQotCi0gIC8qKgotICAgKiBBZGQgYSBuZXcgbG9uZyBjb25zdGFudCB0byB0aGUgQ29uc3RhbnRQb29sLCBpZiBpdCBpcyBub3QgYWxyZWFkeSBpbiB0aGVyZS4KLSAgICoKLSAgICogQHBhcmFtIG4gTG9uZyBudW1iZXIgdG8gYWRkCi0gICAqIEByZXR1cm4gaW5kZXggb2YgZW50cnkKLSAgICovCi0gIHB1YmxpYyBpbnQgYWRkTG9uZyhsb25nIG4pIHsKLSAgICBpbnQgIHJldDsKLQotICAgIGlmKChyZXQgPSBsb29rdXBMb25nKG4pKSAhPSAtMSkKLSAgICAgIHJldHVybiByZXQ7IC8vIEFscmVhZHkgaW4gQ1AKLQotICAgIGFkanVzdFNpemUoKTsKLQotICAgIHJldCA9IGluZGV4OwotICAgIGNvbnN0YW50c1tpbmRleF0gPSBuZXcgQ29uc3RhbnRMb25nKG4pOwotICAgIGluZGV4ICs9IDI7ICAgLy8gV2FzdGVzIG9uZSBlbnRyeSBhY2NvcmRpbmcgdG8gc3BlYwotCi0gICAgcmV0dXJuIHJldDsKLSAgfQotCi0gIC8qKgotICAgKiBMb29rIGZvciBDb25zdGFudERvdWJsZSBpbiBDb25zdGFudFBvb2wuCi0gICAqCi0gICAqIEBwYXJhbSBuIERvdWJsZSBudW1iZXIgdG8gbG9vayBmb3IKLSAgICogQHJldHVybiBpbmRleCBvbiBzdWNjZXNzLCAtMSBvdGhlcndpc2UKLSAgICovCi0gIHB1YmxpYyBpbnQgbG9va3VwRG91YmxlKGRvdWJsZSBuKSB7Ci0gICAgbG9uZyBiaXRzID0gRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMobik7Ci0KLSAgICBmb3IoaW50IGk9MTsgaSA8IGluZGV4OyBpKyspIHsKLSAgICAgIGlmKGNvbnN0YW50c1tpXSBpbnN0YW5jZW9mIENvbnN0YW50RG91YmxlKSB7Ci0gICAgICAgIENvbnN0YW50RG91YmxlIGMgPSAoQ29uc3RhbnREb3VibGUpY29uc3RhbnRzW2ldOwotCi0gICAgICAgIGlmKERvdWJsZS5kb3VibGVUb0xvbmdCaXRzKGMuZ2V0Qnl0ZXMoKSkgPT0gYml0cykKLSAgICAgICAgICByZXR1cm4gaTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gLTE7Ci0gIH0KLQotICAvKioKLSAgICogQWRkIGEgbmV3IGRvdWJsZSBjb25zdGFudCB0byB0aGUgQ29uc3RhbnRQb29sLCBpZiBpdCBpcyBub3QgYWxyZWFkeSBpbiB0aGVyZS4KLSAgICoKLSAgICogQHBhcmFtIG4gRG91YmxlIG51bWJlciB0byBhZGQKLSAgICogQHJldHVybiBpbmRleCBvZiBlbnRyeQotICAgKi8KLSAgcHVibGljIGludCBhZGREb3VibGUoZG91YmxlIG4pIHsKLSAgICBpbnQgIHJldDsKLQotICAgIGlmKChyZXQgPSBsb29rdXBEb3VibGUobikpICE9IC0xKQotICAgICAgcmV0dXJuIHJldDsgLy8gQWxyZWFkeSBpbiBDUAotCi0gICAgYWRqdXN0U2l6ZSgpOwotCi0gICAgcmV0ID0gaW5kZXg7Ci0gICAgY29uc3RhbnRzW2luZGV4XSA9IG5ldyBDb25zdGFudERvdWJsZShuKTsKLSAgICBpbmRleCArPSAyOyAgIC8vIFdhc3RlcyBvbmUgZW50cnkgYWNjb3JkaW5nIHRvIHNwZWMKLQotICAgIHJldHVybiByZXQ7Ci0gIH0KLQotICBwcml2YXRlIEhhc2hNYXAgbl9hX3RfdGFibGUgPSBuZXcgSGFzaE1hcCgpOwotCi0gIC8qKgotICAgKiBMb29rIGZvciBDb25zdGFudE5hbWVBbmRUeXBlIGluIENvbnN0YW50UG9vbC4KLSAgICoKLSAgICogQHBhcmFtIG5hbWUgb2YgdmFyaWFibGUvbWV0aG9kCi0gICAqIEBwYXJhbSBzaWduYXR1cmUgb2YgdmFyaWFibGUvbWV0aG9kCi0gICAqIEByZXR1cm4gaW5kZXggb24gc3VjY2VzcywgLTEgb3RoZXJ3aXNlCi0gICAqLwotICBwdWJsaWMgaW50IGxvb2t1cE5hbWVBbmRUeXBlKFN0cmluZyBuYW1lLCBTdHJpbmcgc2lnbmF0dXJlKSB7Ci0gICAgSW5kZXggaW5kZXggPSAoSW5kZXgpbl9hX3RfdGFibGUuZ2V0KG5hbWUgKyBOQVRfREVMSU0gKyBzaWduYXR1cmUpOwotICAgIHJldHVybiAoaW5kZXggIT0gbnVsbCk/IGluZGV4LmluZGV4IDogLTE7Ci0gIH0KLQotICAvKioKLSAgICogQWRkIGEgbmV3IE5hbWVBbmRUeXBlIGNvbnN0YW50IHRvIHRoZSBDb25zdGFudFBvb2wgaWYgaXQgaXMgbm90IGFscmVhZHkKLSAgICogaW4gdGhlcmUuCi0gICAqCi0gICAqIEBwYXJhbSBuIE5hbWVBbmRUeXBlIHN0cmluZyB0byBhZGQKLSAgICogQHJldHVybiBpbmRleCBvZiBlbnRyeQotICAgKi8KLSAgcHVibGljIGludCBhZGROYW1lQW5kVHlwZShTdHJpbmcgbmFtZSwgU3RyaW5nIHNpZ25hdHVyZSkgewotICAgIGludCAgcmV0OwotICAgIGludCAgbmFtZV9pbmRleCwgc2lnbmF0dXJlX2luZGV4OwotCi0gICAgaWYoKHJldCA9IGxvb2t1cE5hbWVBbmRUeXBlKG5hbWUsIHNpZ25hdHVyZSkpICE9IC0xKQotICAgICAgcmV0dXJuIHJldDsgLy8gQWxyZWFkeSBpbiBDUAotCi0gICAgYWRqdXN0U2l6ZSgpOwotCi0gICAgbmFtZV9pbmRleCAgICAgID0gYWRkVXRmOChuYW1lKTsKLSAgICBzaWduYXR1cmVfaW5kZXggPSBhZGRVdGY4KHNpZ25hdHVyZSk7Ci0gICAgcmV0ID0gaW5kZXg7Ci0gICAgY29uc3RhbnRzW2luZGV4KytdID0gbmV3IENvbnN0YW50TmFtZUFuZFR5cGUobmFtZV9pbmRleCwgc2lnbmF0dXJlX2luZGV4KTsKLQotICAgIG5fYV90X3RhYmxlLnB1dChuYW1lICsgTkFUX0RFTElNICsgc2lnbmF0dXJlLCBuZXcgSW5kZXgocmV0KSk7Ci0gICAgcmV0dXJuIHJldDsKLSAgfQotCi0gIHByaXZhdGUgSGFzaE1hcCBjcF90YWJsZSA9IG5ldyBIYXNoTWFwKCk7Ci0KLSAgLyoqCi0gICAqIExvb2sgZm9yIENvbnN0YW50TWV0aG9kcmVmIGluIENvbnN0YW50UG9vbC4KLSAgICoKLSAgICogQHBhcmFtIGNsYXNzX25hbWUgV2hlcmUgdG8gZmluZCBtZXRob2QKLSAgICogQHBhcmFtIG1ldGhvZF9uYW1lIEd1ZXNzIHdoYXQKLSAgICogQHBhcmFtIHNpZ25hdHVyZSByZXR1cm4gYW5kIGFyZ3VtZW50IHR5cGVzCi0gICAqIEByZXR1cm4gaW5kZXggb24gc3VjY2VzcywgLTEgb3RoZXJ3aXNlCi0gICAqLwotICBwdWJsaWMgaW50IGxvb2t1cE1ldGhvZHJlZihTdHJpbmcgY2xhc3NfbmFtZSwgU3RyaW5nIG1ldGhvZF9uYW1lLCBTdHJpbmcgc2lnbmF0dXJlKSB7Ci0gICAgSW5kZXggaW5kZXggPSAoSW5kZXgpY3BfdGFibGUuZ2V0KGNsYXNzX25hbWUgKyBNRVRIT0RSRUZfREVMSU0gKyBtZXRob2RfbmFtZSArCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1FVEhPRFJFRl9ERUxJTSArIHNpZ25hdHVyZSk7Ci0gICAgcmV0dXJuIChpbmRleCAhPSBudWxsKT8gaW5kZXguaW5kZXggOiAtMTsKLSAgfQotCi0gIHB1YmxpYyBpbnQgbG9va3VwTWV0aG9kcmVmKE1ldGhvZEdlbiBtZXRob2QpIHsKLSAgICByZXR1cm4gbG9va3VwTWV0aG9kcmVmKG1ldGhvZC5nZXRDbGFzc05hbWUoKSwgbWV0aG9kLmdldE5hbWUoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kLmdldFNpZ25hdHVyZSgpKTsKLSAgfQotCi0gIC8qKgotICAgKiBBZGQgYSBuZXcgTWV0aG9kcmVmIGNvbnN0YW50IHRvIHRoZSBDb25zdGFudFBvb2wsIGlmIGl0IGlzIG5vdCBhbHJlYWR5Ci0gICAqIGluIHRoZXJlLgotICAgKgotICAgKiBAcGFyYW0gbiBNZXRob2RyZWYgc3RyaW5nIHRvIGFkZAotICAgKiBAcmV0dXJuIGluZGV4IG9mIGVudHJ5Ci0gICAqLwotICBwdWJsaWMgaW50IGFkZE1ldGhvZHJlZihTdHJpbmcgY2xhc3NfbmFtZSwgU3RyaW5nIG1ldGhvZF9uYW1lLCBTdHJpbmcgc2lnbmF0dXJlKSB7Ci0gICAgaW50ICByZXQsIGNsYXNzX2luZGV4LCBuYW1lX2FuZF90eXBlX2luZGV4OwotCi0gICAgaWYoKHJldCA9IGxvb2t1cE1ldGhvZHJlZihjbGFzc19uYW1lLCBtZXRob2RfbmFtZSwgc2lnbmF0dXJlKSkgIT0gLTEpCi0gICAgICByZXR1cm4gcmV0OyAvLyBBbHJlYWR5IGluIENQCi0KLSAgICBhZGp1c3RTaXplKCk7Ci0KLSAgICBuYW1lX2FuZF90eXBlX2luZGV4ID0gYWRkTmFtZUFuZFR5cGUobWV0aG9kX25hbWUsIHNpZ25hdHVyZSk7Ci0gICAgY2xhc3NfaW5kZXggICAgICAgICA9IGFkZENsYXNzKGNsYXNzX25hbWUpOwotICAgIHJldCA9IGluZGV4OwotICAgIGNvbnN0YW50c1tpbmRleCsrXSA9IG5ldyBDb25zdGFudE1ldGhvZHJlZihjbGFzc19pbmRleCwgbmFtZV9hbmRfdHlwZV9pbmRleCk7Ci0KLSAgICBjcF90YWJsZS5wdXQoY2xhc3NfbmFtZSArIE1FVEhPRFJFRl9ERUxJTSArIG1ldGhvZF9uYW1lICsKLSAgICAgICAgICAgICAgICAgTUVUSE9EUkVGX0RFTElNICsgc2lnbmF0dXJlLCBuZXcgSW5kZXgocmV0KSk7Ci0KLSAgICByZXR1cm4gcmV0OwotICB9Ci0KLSAgcHVibGljIGludCBhZGRNZXRob2RyZWYoTWV0aG9kR2VuIG1ldGhvZCkgewotICAgIHJldHVybiBhZGRNZXRob2RyZWYobWV0aG9kLmdldENsYXNzTmFtZSgpLCBtZXRob2QuZ2V0TmFtZSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kLmdldFNpZ25hdHVyZSgpKTsKLSAgfQotCi0gIC8qKgotICAgKiBMb29rIGZvciBDb25zdGFudEludGVyZmFjZU1ldGhvZHJlZiBpbiBDb25zdGFudFBvb2wuCi0gICAqCi0gICAqIEBwYXJhbSBjbGFzc19uYW1lIFdoZXJlIHRvIGZpbmQgbWV0aG9kCi0gICAqIEBwYXJhbSBtZXRob2RfbmFtZSBHdWVzcyB3aGF0Ci0gICAqIEBwYXJhbSBzaWduYXR1cmUgcmV0dXJuIGFuZCBhcmd1bWVudCB0eXBlcwotICAgKiBAcmV0dXJuIGluZGV4IG9uIHN1Y2Nlc3MsIC0xIG90aGVyd2lzZQotICAgKi8KLSAgcHVibGljIGludCBsb29rdXBJbnRlcmZhY2VNZXRob2RyZWYoU3RyaW5nIGNsYXNzX25hbWUsIFN0cmluZyBtZXRob2RfbmFtZSwgU3RyaW5nIHNpZ25hdHVyZSkgewotICAgIEluZGV4IGluZGV4ID0gKEluZGV4KWNwX3RhYmxlLmdldChjbGFzc19uYW1lICsgSU1FVEhPRFJFRl9ERUxJTSArIG1ldGhvZF9uYW1lICsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU1FVEhPRFJFRl9ERUxJTSArIHNpZ25hdHVyZSk7Ci0gICAgcmV0dXJuIChpbmRleCAhPSBudWxsKT8gaW5kZXguaW5kZXggOiAtMTsKLSAgfQotCi0gIHB1YmxpYyBpbnQgbG9va3VwSW50ZXJmYWNlTWV0aG9kcmVmKE1ldGhvZEdlbiBtZXRob2QpIHsKLSAgICByZXR1cm4gbG9va3VwSW50ZXJmYWNlTWV0aG9kcmVmKG1ldGhvZC5nZXRDbGFzc05hbWUoKSwgbWV0aG9kLmdldE5hbWUoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZC5nZXRTaWduYXR1cmUoKSk7Ci0gIH0KLQotICAvKioKLSAgICogQWRkIGEgbmV3IEludGVyZmFjZU1ldGhvZHJlZiBjb25zdGFudCB0byB0aGUgQ29uc3RhbnRQb29sLCBpZiBpdCBpcyBub3QgYWxyZWFkeQotICAgKiBpbiB0aGVyZS4KLSAgICoKLSAgICogQHBhcmFtIG4gSW50ZXJmYWNlTWV0aG9kcmVmIHN0cmluZyB0byBhZGQKLSAgICogQHJldHVybiBpbmRleCBvZiBlbnRyeQotICAgKi8KLSAgcHVibGljIGludCBhZGRJbnRlcmZhY2VNZXRob2RyZWYoU3RyaW5nIGNsYXNzX25hbWUsIFN0cmluZyBtZXRob2RfbmFtZSwgU3RyaW5nIHNpZ25hdHVyZSkgewotICAgIGludCByZXQsIGNsYXNzX2luZGV4LCBuYW1lX2FuZF90eXBlX2luZGV4OwotCi0gICAgaWYoKHJldCA9IGxvb2t1cEludGVyZmFjZU1ldGhvZHJlZihjbGFzc19uYW1lLCBtZXRob2RfbmFtZSwgc2lnbmF0dXJlKSkgIT0gLTEpCi0gICAgICByZXR1cm4gcmV0OyAvLyBBbHJlYWR5IGluIENQCi0KLSAgICBhZGp1c3RTaXplKCk7Ci0KLSAgICBjbGFzc19pbmRleCAgICAgICAgID0gYWRkQ2xhc3MoY2xhc3NfbmFtZSk7Ci0gICAgbmFtZV9hbmRfdHlwZV9pbmRleCA9IGFkZE5hbWVBbmRUeXBlKG1ldGhvZF9uYW1lLCBzaWduYXR1cmUpOwotICAgIHJldCA9IGluZGV4OwotICAgIGNvbnN0YW50c1tpbmRleCsrXSA9IG5ldyBDb25zdGFudEludGVyZmFjZU1ldGhvZHJlZihjbGFzc19pbmRleCwgbmFtZV9hbmRfdHlwZV9pbmRleCk7Ci0KLSAgICBjcF90YWJsZS5wdXQoY2xhc3NfbmFtZSArIElNRVRIT0RSRUZfREVMSU0gKyBtZXRob2RfbmFtZSArCi0gICAgICAgICAgICAgICAgIElNRVRIT0RSRUZfREVMSU0gKyBzaWduYXR1cmUsIG5ldyBJbmRleChyZXQpKTsKLQotICAgIHJldHVybiByZXQ7Ci0gIH0KLQotICBwdWJsaWMgaW50IGFkZEludGVyZmFjZU1ldGhvZHJlZihNZXRob2RHZW4gbWV0aG9kKSB7Ci0gICAgcmV0dXJuIGFkZEludGVyZmFjZU1ldGhvZHJlZihtZXRob2QuZ2V0Q2xhc3NOYW1lKCksIG1ldGhvZC5nZXROYW1lKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRob2QuZ2V0U2lnbmF0dXJlKCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIExvb2sgZm9yIENvbnN0YW50RmllbGRyZWYgaW4gQ29uc3RhbnRQb29sLgotICAgKgotICAgKiBAcGFyYW0gY2xhc3NfbmFtZSBXaGVyZSB0byBmaW5kIG1ldGhvZAotICAgKiBAcGFyYW0gZmllbGRfbmFtZSBHdWVzcyB3aGF0Ci0gICAqIEBwYXJhbSBzaWduYXR1cmUgcmV0dXJuIGFuZCBhcmd1bWVudCB0eXBlcwotICAgKiBAcmV0dXJuIGluZGV4IG9uIHN1Y2Nlc3MsIC0xIG90aGVyd2lzZQotICAgKi8KLSAgcHVibGljIGludCBsb29rdXBGaWVsZHJlZihTdHJpbmcgY2xhc3NfbmFtZSwgU3RyaW5nIGZpZWxkX25hbWUsIFN0cmluZyBzaWduYXR1cmUpIHsKLSAgICBJbmRleCBpbmRleCA9IChJbmRleCljcF90YWJsZS5nZXQoY2xhc3NfbmFtZSArIEZJRUxEUkVGX0RFTElNICsgZmllbGRfbmFtZSArCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJRUxEUkVGX0RFTElNICsgc2lnbmF0dXJlKTsKLSAgICByZXR1cm4gKGluZGV4ICE9IG51bGwpPyBpbmRleC5pbmRleCA6IC0xOwotICB9Ci0KLSAgLyoqCi0gICAqIEFkZCBhIG5ldyBGaWVsZHJlZiBjb25zdGFudCB0byB0aGUgQ29uc3RhbnRQb29sLCBpZiBpdCBpcyBub3QgYWxyZWFkeQotICAgKiBpbiB0aGVyZS4KLSAgICoKLSAgICogQHBhcmFtIG4gRmllbGRyZWYgc3RyaW5nIHRvIGFkZAotICAgKiBAcmV0dXJuIGluZGV4IG9mIGVudHJ5Ci0gICAqLwotICBwdWJsaWMgaW50IGFkZEZpZWxkcmVmKFN0cmluZyBjbGFzc19uYW1lLCBTdHJpbmcgZmllbGRfbmFtZSwgU3RyaW5nIHNpZ25hdHVyZSkgewotICAgIGludCAgcmV0OwotICAgIGludCAgY2xhc3NfaW5kZXgsIG5hbWVfYW5kX3R5cGVfaW5kZXg7Ci0KLSAgICBpZigocmV0ID0gbG9va3VwRmllbGRyZWYoY2xhc3NfbmFtZSwgZmllbGRfbmFtZSwgc2lnbmF0dXJlKSkgIT0gLTEpCi0gICAgICByZXR1cm4gcmV0OyAvLyBBbHJlYWR5IGluIENQCi0KLSAgICBhZGp1c3RTaXplKCk7Ci0KLSAgICBjbGFzc19pbmRleCAgICAgICAgID0gYWRkQ2xhc3MoY2xhc3NfbmFtZSk7Ci0gICAgbmFtZV9hbmRfdHlwZV9pbmRleCA9IGFkZE5hbWVBbmRUeXBlKGZpZWxkX25hbWUsIHNpZ25hdHVyZSk7Ci0gICAgcmV0ID0gaW5kZXg7Ci0gICAgY29uc3RhbnRzW2luZGV4KytdID0gbmV3IENvbnN0YW50RmllbGRyZWYoY2xhc3NfaW5kZXgsIG5hbWVfYW5kX3R5cGVfaW5kZXgpOwotCi0gICAgY3BfdGFibGUucHV0KGNsYXNzX25hbWUgKyBGSUVMRFJFRl9ERUxJTSArIGZpZWxkX25hbWUgKyBGSUVMRFJFRl9ERUxJTSArIHNpZ25hdHVyZSwgbmV3IEluZGV4KHJldCkpOwotCi0gICAgcmV0dXJuIHJldDsKLSAgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gaSBpbmRleCBpbiBjb25zdGFudCBwb29sCi0gICAqIEByZXR1cm4gY29uc3RhbnQgcG9vbCBlbnRyeSBhdCBpbmRleCBpCi0gICAqLwotICBwdWJsaWMgQ29uc3RhbnQgZ2V0Q29uc3RhbnQoaW50IGkpIHsgcmV0dXJuIGNvbnN0YW50c1tpXTsgfQotCi0gIC8qKgotICAgKiBVc2Ugd2l0aCBjYXJlIQotICAgKgotICAgKiBAcGFyYW0gaSBpbmRleCBpbiBjb25zdGFudCBwb29sCi0gICAqIEBwYXJhbSBjIG5ldyBjb25zdGFudCBwb29sIGVudHJ5IGF0IGluZGV4IGkKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldENvbnN0YW50KGludCBpLCBDb25zdGFudCBjKSB7IGNvbnN0YW50c1tpXSA9IGM7IH0KLQotICAvKioKLSAgICogQHJldHVybiBpbnRlcm1lZGlhdGUgY29uc3RhbnQgcG9vbAotICAgKi8KLSAgcHVibGljIENvbnN0YW50UG9vbCBnZXRDb25zdGFudFBvb2woKSB7Ci0gICAgcmV0dXJuIG5ldyBDb25zdGFudFBvb2woY29uc3RhbnRzKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIGN1cnJlbnQgc2l6ZSBvZiBjb25zdGFudCBwb29sCi0gICAqLwotICBwdWJsaWMgaW50IGdldFNpemUoKSB7Ci0gICAgcmV0dXJuIGluZGV4OwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gY29uc3RhbnQgcG9vbCB3aXRoIHByb3BlciBsZW5ndGgKLSAgICovCi0gIHB1YmxpYyBDb25zdGFudFBvb2wgZ2V0RmluYWxDb25zdGFudFBvb2woKSB7Ci0gICAgQ29uc3RhbnRbXSBjcyA9IG5ldyBDb25zdGFudFtpbmRleF07Ci0KLSAgICBTeXN0ZW0uYXJyYXljb3B5KGNvbnN0YW50cywgMCwgY3MsIDAsIGluZGV4KTsKLQotICAgIHJldHVybiBuZXcgQ29uc3RhbnRQb29sKGNzKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIFN0cmluZyByZXByZXNlbnRhdGlvbi4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0gICAgU3RyaW5nQnVmZmVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLQotICAgIGZvcihpbnQgaT0xOyBpIDwgaW5kZXg7IGkrKykKLSAgICAgIGJ1Zi5hcHBlbmQoaSArICIpIiArIGNvbnN0YW50c1tpXSArICJcbiIpOwotCi0gICAgcmV0dXJuIGJ1Zi50b1N0cmluZygpOwotICB9Ci0KLSAgLyoqIEltcG9ydCBjb25zdGFudCBmcm9tIGFub3RoZXIgQ29uc3RhbnRQb29sIGFuZCByZXR1cm4gbmV3IGluZGV4LgotICAgKi8KLSAgcHVibGljIGludCBhZGRDb25zdGFudChDb25zdGFudCBjLCBDb25zdGFudFBvb2xHZW4gY3ApIHsKLSAgICBDb25zdGFudFtdIGNvbnN0YW50cyA9IGNwLmdldENvbnN0YW50UG9vbCgpLmdldENvbnN0YW50UG9vbCgpOwotCi0gICAgc3dpdGNoKGMuZ2V0VGFnKCkpIHsKLSAgICBjYXNlIENvbnN0YW50cy5DT05TVEFOVF9TdHJpbmc6IHsKLSAgICAgIENvbnN0YW50U3RyaW5nIHMgID0gKENvbnN0YW50U3RyaW5nKWM7Ci0gICAgICBDb25zdGFudFV0ZjggICB1OCA9IChDb25zdGFudFV0ZjgpY29uc3RhbnRzW3MuZ2V0U3RyaW5nSW5kZXgoKV07Ci0KLSAgICAgIHJldHVybiBhZGRTdHJpbmcodTguZ2V0Qnl0ZXMoKSk7Ci0gICAgfQotCi0gICAgY2FzZSBDb25zdGFudHMuQ09OU1RBTlRfQ2xhc3M6IHsKLSAgICAgIENvbnN0YW50Q2xhc3MgcyAgPSAoQ29uc3RhbnRDbGFzcyljOwotICAgICAgQ29uc3RhbnRVdGY4ICB1OCA9IChDb25zdGFudFV0ZjgpY29uc3RhbnRzW3MuZ2V0TmFtZUluZGV4KCldOwotCi0gICAgICByZXR1cm4gYWRkQ2xhc3ModTguZ2V0Qnl0ZXMoKSk7Ci0gICAgfQotCi0gICAgY2FzZSBDb25zdGFudHMuQ09OU1RBTlRfTmFtZUFuZFR5cGU6IHsKLSAgICAgIENvbnN0YW50TmFtZUFuZFR5cGUgbiAgICA9IChDb25zdGFudE5hbWVBbmRUeXBlKWM7Ci0gICAgICBDb25zdGFudFV0ZjggICAgICAgIHU4ICAgPSAoQ29uc3RhbnRVdGY4KWNvbnN0YW50c1tuLmdldE5hbWVJbmRleCgpXTsKLSAgICAgIENvbnN0YW50VXRmOCAgICAgICAgdThfMiA9IChDb25zdGFudFV0ZjgpY29uc3RhbnRzW24uZ2V0U2lnbmF0dXJlSW5kZXgoKV07Ci0KLSAgICAgIHJldHVybiBhZGROYW1lQW5kVHlwZSh1OC5nZXRCeXRlcygpLCB1OF8yLmdldEJ5dGVzKCkpOwotICAgIH0KLQotICAgIGNhc2UgQ29uc3RhbnRzLkNPTlNUQU5UX1V0Zjg6Ci0gICAgICByZXR1cm4gYWRkVXRmOCgoKENvbnN0YW50VXRmOCljKS5nZXRCeXRlcygpKTsKLQotICAgIGNhc2UgQ29uc3RhbnRzLkNPTlNUQU5UX0RvdWJsZToKLSAgICAgIHJldHVybiBhZGREb3VibGUoKChDb25zdGFudERvdWJsZSljKS5nZXRCeXRlcygpKTsKLQotICAgIGNhc2UgQ29uc3RhbnRzLkNPTlNUQU5UX0Zsb2F0OgotICAgICAgcmV0dXJuIGFkZEZsb2F0KCgoQ29uc3RhbnRGbG9hdCljKS5nZXRCeXRlcygpKTsKLQotICAgIGNhc2UgQ29uc3RhbnRzLkNPTlNUQU5UX0xvbmc6Ci0gICAgICByZXR1cm4gYWRkTG9uZygoKENvbnN0YW50TG9uZyljKS5nZXRCeXRlcygpKTsKLQotICAgIGNhc2UgQ29uc3RhbnRzLkNPTlNUQU5UX0ludGVnZXI6Ci0gICAgICByZXR1cm4gYWRkSW50ZWdlcigoKENvbnN0YW50SW50ZWdlciljKS5nZXRCeXRlcygpKTsKLQotICAgIGNhc2UgQ29uc3RhbnRzLkNPTlNUQU5UX0ludGVyZmFjZU1ldGhvZHJlZjogY2FzZSBDb25zdGFudHMuQ09OU1RBTlRfTWV0aG9kcmVmOgotICAgIGNhc2UgQ29uc3RhbnRzLkNPTlNUQU5UX0ZpZWxkcmVmOiB7Ci0gICAgICBDb25zdGFudENQICAgICAgICAgIG0gICAgID0gKENvbnN0YW50Q1ApYzsKLSAgICAgIENvbnN0YW50Q2xhc3MgICAgICAgY2xhenogPSAoQ29uc3RhbnRDbGFzcyljb25zdGFudHNbbS5nZXRDbGFzc0luZGV4KCldOwotICAgICAgQ29uc3RhbnROYW1lQW5kVHlwZSBuICAgICA9IChDb25zdGFudE5hbWVBbmRUeXBlKWNvbnN0YW50c1ttLmdldE5hbWVBbmRUeXBlSW5kZXgoKV07Ci0gICAgICBDb25zdGFudFV0ZjggdTggICAgICAgICAgID0gKENvbnN0YW50VXRmOCljb25zdGFudHNbY2xhenouZ2V0TmFtZUluZGV4KCldOwotICAgICAgU3RyaW5nICAgICAgIGNsYXNzX25hbWUgICA9IHU4LmdldEJ5dGVzKCkucmVwbGFjZSgnLycsICcuJyk7Ci0KLSAgICAgIHU4ID0gKENvbnN0YW50VXRmOCljb25zdGFudHNbbi5nZXROYW1lSW5kZXgoKV07Ci0gICAgICBTdHJpbmcgbmFtZSA9IHU4LmdldEJ5dGVzKCk7Ci0KLSAgICAgIHU4ID0gKENvbnN0YW50VXRmOCljb25zdGFudHNbbi5nZXRTaWduYXR1cmVJbmRleCgpXTsKLSAgICAgIFN0cmluZyBzaWduYXR1cmUgPSB1OC5nZXRCeXRlcygpOwotCi0gICAgICBzd2l0Y2goYy5nZXRUYWcoKSkgewotICAgICAgY2FzZSBDb25zdGFudHMuQ09OU1RBTlRfSW50ZXJmYWNlTWV0aG9kcmVmOgotICAgICAgICByZXR1cm4gYWRkSW50ZXJmYWNlTWV0aG9kcmVmKGNsYXNzX25hbWUsIG5hbWUsIHNpZ25hdHVyZSk7Ci0KLSAgICAgIGNhc2UgQ29uc3RhbnRzLkNPTlNUQU5UX01ldGhvZHJlZjoKLSAgICAgICAgcmV0dXJuIGFkZE1ldGhvZHJlZihjbGFzc19uYW1lLCBuYW1lLCBzaWduYXR1cmUpOwotCi0gICAgICBjYXNlIENvbnN0YW50cy5DT05TVEFOVF9GaWVsZHJlZjoKLSAgICAgICAgcmV0dXJuIGFkZEZpZWxkcmVmKGNsYXNzX25hbWUsIG5hbWUsIHNpZ25hdHVyZSk7Ci0KLSAgICAgIGRlZmF1bHQ6IC8vIE5ldmVyIHJlYWNoZWQKLSAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlVua25vd24gY29uc3RhbnQgdHlwZSAiICsgYyk7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgZGVmYXVsdDogLy8gTmV2ZXIgcmVhY2hlZAotICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlVua25vd24gY29uc3RhbnQgdHlwZSAiICsgYyk7Ci0gICAgfQotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9Db25zdGFudFB1c2hJbnN0cnVjdGlvbi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvQ29uc3RhbnRQdXNoSW5zdHJ1Y3Rpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZTdhZDY5OC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9Db25zdGFudFB1c2hJbnN0cnVjdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNzIgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotLyoqCi0gKiBEZW5vdGVzIGEgcHVzaCBpbnN0cnVjdGlvbiB0aGF0IHByb2R1Y2VzIGEgbGl0ZXJhbCBvbiB0aGUgc3RhY2sKLSAqIHN1Y2ggYXMgIFNJUFVTSCwgQklQVVNILCBJQ09OU1QsIGV0Yy4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotCi0gKiBAc2VlIElDT05TVAotICogQHNlZSBTSVBVU0gKLSAqLwotcHVibGljIGludGVyZmFjZSBDb25zdGFudFB1c2hJbnN0cnVjdGlvbiBleHRlbmRzIFB1c2hJbnN0cnVjdGlvbiwgVHlwZWRJbnN0cnVjdGlvbiB7Ci0gIHB1YmxpYyBOdW1iZXIgZ2V0VmFsdWUoKTsKLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0NvbnZlcnNpb25JbnN0cnVjdGlvbi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvQ29udmVyc2lvbkluc3RydWN0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDgyMjdhYjAuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvQ29udmVyc2lvbkluc3RydWN0aW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMDQgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHM7Ci0vKioKLSAqIFN1cGVyIGNsYXNzIGZvciB0aGUgeDJ5IGZhbWlseSBvZiBpbnN0cnVjdGlvbnMuCi0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGFic3RyYWN0IGNsYXNzIENvbnZlcnNpb25JbnN0cnVjdGlvbiBleHRlbmRzIEluc3RydWN0aW9uCi0gIGltcGxlbWVudHMgVHlwZWRJbnN0cnVjdGlvbiwgU3RhY2tQcm9kdWNlciwgU3RhY2tDb25zdW1lciB7Ci0gIC8qKgotICAgKiBFbXB0eSBjb25zdHJ1Y3RvciBuZWVkZWQgZm9yIHRoZSBDbGFzcy5uZXdJbnN0YW5jZSgpIHN0YXRlbWVudCBpbgotICAgKiBJbnN0cnVjdGlvbi5yZWFkSW5zdHJ1Y3Rpb24oKS4gTm90IHRvIGJlIHVzZWQgb3RoZXJ3aXNlLgotICAgKi8KLSAgQ29udmVyc2lvbkluc3RydWN0aW9uKCkge30KLQotICAvKioKLSAgICogQHBhcmFtIG9wY29kZSBvcGNvZGUgb2YgaW5zdHJ1Y3Rpb24KLSAgICovCi0gIHByb3RlY3RlZCBDb252ZXJzaW9uSW5zdHJ1Y3Rpb24oc2hvcnQgb3Bjb2RlKSB7Ci0gICAgc3VwZXIob3Bjb2RlLCAoc2hvcnQpMSk7Ci0gIH0KLQotICAvKiogQHJldHVybiB0eXBlIGFzc29jaWF0ZWQgd2l0aCB0aGUgaW5zdHJ1Y3Rpb24KLSAgICovCi0gIHB1YmxpYyBUeXBlIGdldFR5cGUoQ29uc3RhbnRQb29sR2VuIGNwKSB7Ci0gICAgc3dpdGNoKG9wY29kZSkgewotICAgIGNhc2UgQ29uc3RhbnRzLkQySTogY2FzZSBDb25zdGFudHMuRjJJOiBjYXNlIENvbnN0YW50cy5MMkk6Ci0gICAgICByZXR1cm4gVHlwZS5JTlQ7Ci0gICAgY2FzZSBDb25zdGFudHMuRDJGOiBjYXNlIENvbnN0YW50cy5JMkY6IGNhc2UgQ29uc3RhbnRzLkwyRjoKLSAgICAgIHJldHVybiBUeXBlLkZMT0FUOwotICAgIGNhc2UgQ29uc3RhbnRzLkQyTDogY2FzZSBDb25zdGFudHMuRjJMOiBjYXNlIENvbnN0YW50cy5JMkw6Ci0gICAgICByZXR1cm4gVHlwZS5MT05HOwotICAgIGNhc2UgQ29uc3RhbnRzLkYyRDogIGNhc2UgQ29uc3RhbnRzLkkyRDogY2FzZSBDb25zdGFudHMuTDJEOgotICAgICAgICByZXR1cm4gVHlwZS5ET1VCTEU7Ci0gICAgY2FzZSBDb25zdGFudHMuSTJCOgotICAgICAgcmV0dXJuIFR5cGUuQllURTsKLSAgICBjYXNlIENvbnN0YW50cy5JMkM6Ci0gICAgICByZXR1cm4gVHlwZS5DSEFSOwotICAgIGNhc2UgQ29uc3RhbnRzLkkyUzoKLSAgICAgIHJldHVybiBUeXBlLlNIT1JUOwotCi0gICAgZGVmYXVsdDogLy8gTmV2ZXIgcmVhY2hlZAotICAgICAgdGhyb3cgbmV3IENsYXNzR2VuRXhjZXB0aW9uKCJVbmtub3duIHR5cGUgIiArIG9wY29kZSk7Ci0gICAgfQotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9EMkYuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0QyRi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiMTlkNTlmLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0QyRi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTAgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotLyoqCi0gKiBEMkYgLSBDb252ZXJ0IGRvdWJsZSB0byBmbG9hdAotICogPFBSRT5TdGFjazogLi4uLCB2YWx1ZS53b3JkMSwgdmFsdWUud29yZDIgLSZndDsgLi4uLCByZXN1bHQ8L1BSRT4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgRDJGIGV4dGVuZHMgQ29udmVyc2lvbkluc3RydWN0aW9uIHsKLSAgLyoqIENvbnZlcnQgZG91YmxlIHRvIGZsb2F0Ci0gICAqLwotICBwdWJsaWMgRDJGKCkgewotICAgIHN1cGVyKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5EMkYpOwotICB9Ci0KLQotICAvKioKLSAgICogQ2FsbCBjb3JyZXNwb25kaW5nIHZpc2l0b3IgbWV0aG9kKHMpLiBUaGUgb3JkZXIgaXM6Ci0gICAqIENhbGwgdmlzaXRvciBtZXRob2RzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMgZmlyc3QsIHRoZW4KLSAgICogY2FsbCBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY2xhc3MgaGllcmFyY2h5IGluIGRlc2NlbmRpbmcgb3JkZXIsCi0gICAqIGkuZS4sIHRoZSBtb3N0IHNwZWNpZmljIHZpc2l0WFhYKCkgY2FsbCBjb21lcyBsYXN0LgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRUeXBlZEluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRTdGFja1Byb2R1Y2VyKHRoaXMpOwotICAgIHYudmlzaXRTdGFja0NvbnN1bWVyKHRoaXMpOwotICAgIHYudmlzaXRDb252ZXJzaW9uSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdEQyRih0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvRDJJLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9EMkkuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOWFmZjFmMS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9EMkkuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDkwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8qKgotICogRDJJIC0gQ29udmVydCBkb3VibGUgdG8gaW50Ci0gKiA8UFJFPlN0YWNrOiAuLi4sIHZhbHVlLndvcmQxLCB2YWx1ZS53b3JkMiAtJmd0OyAuLi4sIHJlc3VsdDwvUFJFPgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBEMkkgZXh0ZW5kcyBDb252ZXJzaW9uSW5zdHJ1Y3Rpb24gewotICAvKiogQ29udmVydCBkb3VibGUgdG8gaW50Ci0gICAqLwotICBwdWJsaWMgRDJJKCkgewotICAgIHN1cGVyKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5EMkkpOwotICB9Ci0KLQotICAvKioKLSAgICogQ2FsbCBjb3JyZXNwb25kaW5nIHZpc2l0b3IgbWV0aG9kKHMpLiBUaGUgb3JkZXIgaXM6Ci0gICAqIENhbGwgdmlzaXRvciBtZXRob2RzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMgZmlyc3QsIHRoZW4KLSAgICogY2FsbCBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY2xhc3MgaGllcmFyY2h5IGluIGRlc2NlbmRpbmcgb3JkZXIsCi0gICAqIGkuZS4sIHRoZSBtb3N0IHNwZWNpZmljIHZpc2l0WFhYKCkgY2FsbCBjb21lcyBsYXN0LgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRUeXBlZEluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRTdGFja1Byb2R1Y2VyKHRoaXMpOwotICAgIHYudmlzaXRTdGFja0NvbnN1bWVyKHRoaXMpOwotICAgIHYudmlzaXRDb252ZXJzaW9uSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdEQySSh0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvRDJMLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9EMkwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOWNiODdhMi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9EMkwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDkwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8qKgotICogRDJMIC0gQ29udmVydCBkb3VibGUgdG8gbG9uZwotICogPFBSRT5TdGFjazogLi4uLCB2YWx1ZS53b3JkMSwgdmFsdWUud29yZDIgLSZndDsgLi4uLCByZXN1bHQud29yZDEsIHJlc3VsdC53b3JkMjwvUFJFPgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBEMkwgZXh0ZW5kcyBDb252ZXJzaW9uSW5zdHJ1Y3Rpb24gewotICAvKiogQ29udmVydCBkb3VibGUgdG8gbG9uZwotICAgKi8KLSAgcHVibGljIEQyTCgpIHsKLSAgICBzdXBlcihjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuRDJMKTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIENhbGwgY29ycmVzcG9uZGluZyB2aXNpdG9yIG1ldGhvZChzKS4gVGhlIG9yZGVyIGlzOgotICAgKiBDYWxsIHZpc2l0b3IgbWV0aG9kcyBvZiBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzIGZpcnN0LCB0aGVuCi0gICAqIGNhbGwgbWV0aG9kcyBhY2NvcmRpbmcgdG8gdGhlIGNsYXNzIGhpZXJhcmNoeSBpbiBkZXNjZW5kaW5nIG9yZGVyLAotICAgKiBpLmUuLCB0aGUgbW9zdCBzcGVjaWZpYyB2aXNpdFhYWCgpIGNhbGwgY29tZXMgbGFzdC4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0VHlwZWRJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tQcm9kdWNlcih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tDb25zdW1lcih0aGlzKTsKLSAgICB2LnZpc2l0Q29udmVyc2lvbkluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXREMkwodGhpcyk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0RBREQuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0RBREQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMTkwNzkwYi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9EQURELmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5MSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIERBREQgLSBBZGQgZG91YmxlcwotICogPFBSRT5TdGFjazogLi4uLCB2YWx1ZTEud29yZDEsIHZhbHVlMS53b3JkMiwgdmFsdWUyLndvcmQxLCB2YWx1ZTIud29yZDIgLSZndDs8L1BSRT4KLSAqICAgICAgICAuLi4sIHJlc3VsdC53b3JkMSwgcmVzdWx0MS53b3JkMgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBEQUREIGV4dGVuZHMgQXJpdGhtZXRpY0luc3RydWN0aW9uIHsKLSAgLyoqIEFkZCBkb3VibGVzCi0gICAqLwotICBwdWJsaWMgREFERCgpIHsKLSAgICBzdXBlcihjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuREFERCk7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBDYWxsIGNvcnJlc3BvbmRpbmcgdmlzaXRvciBtZXRob2QocykuIFRoZSBvcmRlciBpczoKLSAgICogQ2FsbCB2aXNpdG9yIG1ldGhvZHMgb2YgaW1wbGVtZW50ZWQgaW50ZXJmYWNlcyBmaXJzdCwgdGhlbgotICAgKiBjYWxsIG1ldGhvZHMgYWNjb3JkaW5nIHRvIHRoZSBjbGFzcyBoaWVyYXJjaHkgaW4gZGVzY2VuZGluZyBvcmRlciwKLSAgICogaS5lLiwgdGhlIG1vc3Qgc3BlY2lmaWMgdmlzaXRYWFgoKSBjYWxsIGNvbWVzIGxhc3QuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgdi52aXNpdFR5cGVkSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdFN0YWNrUHJvZHVjZXIodGhpcyk7Ci0gICAgdi52aXNpdFN0YWNrQ29uc3VtZXIodGhpcyk7Ci0gICAgdi52aXNpdEFyaXRobWV0aWNJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0REFERCh0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvREFMT0FELmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9EQUxPQUQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYWIzYjM2MS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9EQUxPQUQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDkwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8qKgotICogREFMT0FEIC0gTG9hZCBkb3VibGUgZnJvbSBhcnJheQotICogPFBSRT5TdGFjazogLi4uLCBhcnJheXJlZiwgaW5kZXggLSZndDsgLi4uLCByZXN1bHQud29yZDEsIHJlc3VsdC53b3JkMjwvUFJFPgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBEQUxPQUQgZXh0ZW5kcyBBcnJheUluc3RydWN0aW9uIGltcGxlbWVudHMgU3RhY2tQcm9kdWNlciB7Ci0gIC8qKiBMb2FkIGRvdWJsZSBmcm9tIGFycmF5Ci0gICAqLwotICBwdWJsaWMgREFMT0FEKCkgewotICAgIHN1cGVyKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5EQUxPQUQpOwotICB9Ci0KLQotICAvKioKLSAgICogQ2FsbCBjb3JyZXNwb25kaW5nIHZpc2l0b3IgbWV0aG9kKHMpLiBUaGUgb3JkZXIgaXM6Ci0gICAqIENhbGwgdmlzaXRvciBtZXRob2RzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMgZmlyc3QsIHRoZW4KLSAgICogY2FsbCBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY2xhc3MgaGllcmFyY2h5IGluIGRlc2NlbmRpbmcgb3JkZXIsCi0gICAqIGkuZS4sIHRoZSBtb3N0IHNwZWNpZmljIHZpc2l0WFhYKCkgY2FsbCBjb21lcyBsYXN0LgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRTdGFja1Byb2R1Y2VyKHRoaXMpOwotICAgIHYudmlzaXRFeGNlcHRpb25UaHJvd2VyKHRoaXMpOwotICAgIHYudmlzaXRUeXBlZEluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRBcnJheUluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXREQUxPQUQodGhpcyk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0RBU1RPUkUuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0RBU1RPUkUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYjYxNTQ3OS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9EQVNUT1JFLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5MCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIERBU1RPUkUgLSAgU3RvcmUgaW50byBkb3VibGUgYXJyYXkKLSAqIDxQUkU+U3RhY2s6IC4uLiwgYXJyYXlyZWYsIGluZGV4LCB2YWx1ZS53b3JkMSwgdmFsdWUud29yZDIgLSZndDsgLi4uPC9QUkU+Ci0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGNsYXNzIERBU1RPUkUgZXh0ZW5kcyBBcnJheUluc3RydWN0aW9uIGltcGxlbWVudHMgU3RhY2tDb25zdW1lciB7Ci0gIC8qKiBTdG9yZSBkb3VibGUgaW50byBhcnJheQotICAgKi8KLSAgcHVibGljIERBU1RPUkUoKSB7Ci0gICAgc3VwZXIoY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkRBU1RPUkUpOwotICB9Ci0KLQotICAvKioKLSAgICogQ2FsbCBjb3JyZXNwb25kaW5nIHZpc2l0b3IgbWV0aG9kKHMpLiBUaGUgb3JkZXIgaXM6Ci0gICAqIENhbGwgdmlzaXRvciBtZXRob2RzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMgZmlyc3QsIHRoZW4KLSAgICogY2FsbCBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY2xhc3MgaGllcmFyY2h5IGluIGRlc2NlbmRpbmcgb3JkZXIsCi0gICAqIGkuZS4sIHRoZSBtb3N0IHNwZWNpZmljIHZpc2l0WFhYKCkgY2FsbCBjb21lcyBsYXN0LgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRTdGFja0NvbnN1bWVyKHRoaXMpOwotICAgIHYudmlzaXRFeGNlcHRpb25UaHJvd2VyKHRoaXMpOwotICAgIHYudmlzaXRUeXBlZEluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRBcnJheUluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXREQVNUT1JFKHRoaXMpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9EQ01QRy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvRENNUEcuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggM2VhMmZkOC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9EQ01QRy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTYgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotLyoqCi0gKiBEQ01QRyAtIENvbXBhcmUgZG91YmxlczogdmFsdWUxID4gdmFsdWUyCi0gKiA8UFJFPlN0YWNrOiAuLi4sIHZhbHVlMS53b3JkMSwgdmFsdWUxLndvcmQyLCB2YWx1ZTIud29yZDEsIHZhbHVlMi53b3JkMiAtJmd0OzwvUFJFPgotICogICAgICAgIC4uLiwgcmVzdWx0Ci0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGNsYXNzIERDTVBHIGV4dGVuZHMgSW5zdHJ1Y3Rpb24KLSAgaW1wbGVtZW50cyBUeXBlZEluc3RydWN0aW9uLCBTdGFja1Byb2R1Y2VyLCBTdGFja0NvbnN1bWVyIHsKLQotICBwdWJsaWMgRENNUEcoKSB7Ci0gICAgc3VwZXIoY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkRDTVBHLCAoc2hvcnQpMSk7Ci0gIH0KLQotICAvKiogQHJldHVybiBUeXBlLkRPVUJMRQotICAgKi8KLSAgcHVibGljIFR5cGUgZ2V0VHlwZShDb25zdGFudFBvb2xHZW4gY3ApIHsKLSAgICByZXR1cm4gVHlwZS5ET1VCTEU7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBDYWxsIGNvcnJlc3BvbmRpbmcgdmlzaXRvciBtZXRob2QocykuIFRoZSBvcmRlciBpczoKLSAgICogQ2FsbCB2aXNpdG9yIG1ldGhvZHMgb2YgaW1wbGVtZW50ZWQgaW50ZXJmYWNlcyBmaXJzdCwgdGhlbgotICAgKiBjYWxsIG1ldGhvZHMgYWNjb3JkaW5nIHRvIHRoZSBjbGFzcyBoaWVyYXJjaHkgaW4gZGVzY2VuZGluZyBvcmRlciwKLSAgICogaS5lLiwgdGhlIG1vc3Qgc3BlY2lmaWMgdmlzaXRYWFgoKSBjYWxsIGNvbWVzIGxhc3QuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgdi52aXNpdFR5cGVkSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdFN0YWNrUHJvZHVjZXIodGhpcyk7Ci0gICAgdi52aXNpdFN0YWNrQ29uc3VtZXIodGhpcyk7Ci0gICAgdi52aXNpdERDTVBHKHRoaXMpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9EQ01QTC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvRENNUEwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMWI5YzViZC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9EQ01QTC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTUgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotLyoqCi0gKiBEQ01QTCAtIENvbXBhcmUgZG91YmxlczogdmFsdWUxIDwgdmFsdWUyCi0gKiA8UFJFPlN0YWNrOiAuLi4sIHZhbHVlMS53b3JkMSwgdmFsdWUxLndvcmQyLCB2YWx1ZTIud29yZDEsIHZhbHVlMi53b3JkMiAtJmd0OzwvUFJFPgotICogICAgICAgIC4uLiwgcmVzdWx0Ci0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGNsYXNzIERDTVBMIGV4dGVuZHMgSW5zdHJ1Y3Rpb24KLSAgaW1wbGVtZW50cyBUeXBlZEluc3RydWN0aW9uLCBTdGFja1Byb2R1Y2VyLCBTdGFja0NvbnN1bWVyIHsKLSAgcHVibGljIERDTVBMKCkgewotICAgIHN1cGVyKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5EQ01QTCwgKHNob3J0KTEpOwotICB9Ci0KLSAgLyoqIEByZXR1cm4gVHlwZS5ET1VCTEUKLSAgICovCi0gIHB1YmxpYyBUeXBlIGdldFR5cGUoQ29uc3RhbnRQb29sR2VuIGNwKSB7Ci0gICAgcmV0dXJuIFR5cGUuRE9VQkxFOwotICB9Ci0KLQotICAvKioKLSAgICogQ2FsbCBjb3JyZXNwb25kaW5nIHZpc2l0b3IgbWV0aG9kKHMpLiBUaGUgb3JkZXIgaXM6Ci0gICAqIENhbGwgdmlzaXRvciBtZXRob2RzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMgZmlyc3QsIHRoZW4KLSAgICogY2FsbCBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY2xhc3MgaGllcmFyY2h5IGluIGRlc2NlbmRpbmcgb3JkZXIsCi0gICAqIGkuZS4sIHRoZSBtb3N0IHNwZWNpZmljIHZpc2l0WFhYKCkgY2FsbCBjb21lcyBsYXN0LgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRUeXBlZEluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRTdGFja1Byb2R1Y2VyKHRoaXMpOwotICAgIHYudmlzaXRTdGFja0NvbnN1bWVyKHRoaXMpOwotICAgIHYudmlzaXREQ01QTCh0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvRENPTlNULmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9EQ09OU1QuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOGQ0M2UwOS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9EQ09OU1QuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExNCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIERDT05TVCAtIFB1c2ggMC4wIG9yIDEuMCwgb3RoZXIgdmFsdWVzIGNhdXNlIGFuIGV4Y2VwdGlvbgotICoKLSAqIDxQUkU+U3RhY2s6IC4uLiAtJmd0OyAuLi4sIDwvUFJFPgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBEQ09OU1QgZXh0ZW5kcyBJbnN0cnVjdGlvbgotICBpbXBsZW1lbnRzIENvbnN0YW50UHVzaEluc3RydWN0aW9uLCBUeXBlZEluc3RydWN0aW9uIHsKLSAgcHJpdmF0ZSBkb3VibGUgdmFsdWU7Ci0KLSAgLyoqCi0gICAqIEVtcHR5IGNvbnN0cnVjdG9yIG5lZWRlZCBmb3IgdGhlIENsYXNzLm5ld0luc3RhbmNlKCkgc3RhdGVtZW50IGluCi0gICAqIEluc3RydWN0aW9uLnJlYWRJbnN0cnVjdGlvbigpLiBOb3QgdG8gYmUgdXNlZCBvdGhlcndpc2UuCi0gICAqLwotICBEQ09OU1QoKSB7fQotCi0gIHB1YmxpYyBEQ09OU1QoZG91YmxlIGYpIHsKLSAgICBzdXBlcihjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuRENPTlNUXzAsIChzaG9ydCkxKTsKLQotICAgIGlmKGYgPT0gMC4wKQotICAgICAgb3Bjb2RlID0gY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkRDT05TVF8wOwotICAgIGVsc2UgaWYoZiA9PSAxLjApCi0gICAgICBvcGNvZGUgPSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuRENPTlNUXzE7Ci0gICAgZWxzZQotICAgICAgdGhyb3cgbmV3IENsYXNzR2VuRXhjZXB0aW9uKCJEQ09OU1QgY2FuIGJlIHVzZWQgb25seSBmb3IgMC4wIGFuZCAxLjA6ICIgKyBmKTsKLQotICAgIHZhbHVlID0gZjsKLSAgfQotCi0gIHB1YmxpYyBOdW1iZXIgZ2V0VmFsdWUoKSB7IHJldHVybiBuZXcgRG91YmxlKHZhbHVlKTsgfQotCi0gIC8qKiBAcmV0dXJuIFR5cGUuRE9VQkxFCi0gICAqLwotICBwdWJsaWMgVHlwZSBnZXRUeXBlKENvbnN0YW50UG9vbEdlbiBjcCkgewotICAgIHJldHVybiBUeXBlLkRPVUJMRTsKLSAgfQotCi0gIC8qKgotICAgKiBDYWxsIGNvcnJlc3BvbmRpbmcgdmlzaXRvciBtZXRob2QocykuIFRoZSBvcmRlciBpczoKLSAgICogQ2FsbCB2aXNpdG9yIG1ldGhvZHMgb2YgaW1wbGVtZW50ZWQgaW50ZXJmYWNlcyBmaXJzdCwgdGhlbgotICAgKiBjYWxsIG1ldGhvZHMgYWNjb3JkaW5nIHRvIHRoZSBjbGFzcyBoaWVyYXJjaHkgaW4gZGVzY2VuZGluZyBvcmRlciwKLSAgICogaS5lLiwgdGhlIG1vc3Qgc3BlY2lmaWMgdmlzaXRYWFgoKSBjYWxsIGNvbWVzIGxhc3QuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgdi52aXNpdFB1c2hJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tQcm9kdWNlcih0aGlzKTsKLSAgICB2LnZpc2l0VHlwZWRJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0Q29uc3RhbnRQdXNoSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdERDT05TVCh0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvRERJVi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvRERJVi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxMDNiY2MzLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0RESVYuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDkxICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8qKgotICogRERJViAtICBEaXZpZGUgZG91YmxlcwotICogPFBSRT5TdGFjazogLi4uLCB2YWx1ZTEud29yZDEsIHZhbHVlMS53b3JkMiwgdmFsdWUyLndvcmQxLCB2YWx1ZTIud29yZDIgLSZndDs8L1BSRT4KLSAqICAgICAgICAuLi4sIHJlc3VsdC53b3JkMSwgcmVzdWx0LndvcmQyCi0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGNsYXNzIERESVYgZXh0ZW5kcyBBcml0aG1ldGljSW5zdHJ1Y3Rpb24gewotICAvKiogRGl2aWRlIGRvdWJsZXMKLSAgICovCi0gIHB1YmxpYyBERElWKCkgewotICAgIHN1cGVyKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5ERElWKTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIENhbGwgY29ycmVzcG9uZGluZyB2aXNpdG9yIG1ldGhvZChzKS4gVGhlIG9yZGVyIGlzOgotICAgKiBDYWxsIHZpc2l0b3IgbWV0aG9kcyBvZiBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzIGZpcnN0LCB0aGVuCi0gICAqIGNhbGwgbWV0aG9kcyBhY2NvcmRpbmcgdG8gdGhlIGNsYXNzIGhpZXJhcmNoeSBpbiBkZXNjZW5kaW5nIG9yZGVyLAotICAgKiBpLmUuLCB0aGUgbW9zdCBzcGVjaWZpYyB2aXNpdFhYWCgpIGNhbGwgY29tZXMgbGFzdC4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0VHlwZWRJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tQcm9kdWNlcih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tDb25zdW1lcih0aGlzKTsKLSAgICB2LnZpc2l0QXJpdGhtZXRpY0luc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRERElWKHRoaXMpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9ETE9BRC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvRExPQUQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMGRhNmE1Yi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9ETE9BRC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTUgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotLyoqCi0gKiBETE9BRCAtIExvYWQgZG91YmxlIGZyb20gbG9jYWwgdmFyaWFibGUKLSAqIDxQUkU+U3RhY2sgLi4uIC0mZ3Q7IC4uLiwgcmVzdWx0LndvcmQxLCByZXN1bHQud29yZDI8L1BSRT4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgRExPQUQgZXh0ZW5kcyBMb2FkSW5zdHJ1Y3Rpb24gewotICAvKioKLSAgICogRW1wdHkgY29uc3RydWN0b3IgbmVlZGVkIGZvciB0aGUgQ2xhc3MubmV3SW5zdGFuY2UoKSBzdGF0ZW1lbnQgaW4KLSAgICogSW5zdHJ1Y3Rpb24ucmVhZEluc3RydWN0aW9uKCkuIE5vdCB0byBiZSB1c2VkIG90aGVyd2lzZS4KLSAgICovCi0gIERMT0FEKCkgewotICAgIHN1cGVyKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5ETE9BRCwgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkRMT0FEXzApOwotICB9Ci0KLSAgLyoqIExvYWQgZG91YmxlIGZyb20gbG9jYWwgdmFyaWFibGUKLSAgICogQHBhcmFtIG4gaW5kZXggb2YgbG9jYWwgdmFyaWFibGUKLSAgICovCi0gIHB1YmxpYyBETE9BRChpbnQgbikgewotICAgIHN1cGVyKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5ETE9BRCwgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkRMT0FEXzAsIG4pOwotICB9Ci0KLSAgLyoqCi0gICAqIENhbGwgY29ycmVzcG9uZGluZyB2aXNpdG9yIG1ldGhvZChzKS4gVGhlIG9yZGVyIGlzOgotICAgKiBDYWxsIHZpc2l0b3IgbWV0aG9kcyBvZiBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzIGZpcnN0LCB0aGVuCi0gICAqIGNhbGwgbWV0aG9kcyBhY2NvcmRpbmcgdG8gdGhlIGNsYXNzIGhpZXJhcmNoeSBpbiBkZXNjZW5kaW5nIG9yZGVyLAotICAgKiBpLmUuLCB0aGUgbW9zdCBzcGVjaWZpYyB2aXNpdFhYWCgpIGNhbGwgY29tZXMgbGFzdC4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICBzdXBlci5hY2NlcHQodik7Ci0gICAgdi52aXNpdERMT0FEKHRoaXMpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9ETVVMLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9ETVVMLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGZmMzFmYWQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvRE1VTC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTEgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotLyoqCi0gKiBETVVMIC0gTXVsdGlwbHkgZG91YmxlcwotICogPFBSRT5TdGFjazogLi4uLCB2YWx1ZTEud29yZDEsIHZhbHVlMS53b3JkMiwgdmFsdWUyLndvcmQxLCB2YWx1ZTIud29yZDIgLSZndDs8L1BSRT4KLSAqICAgICAgICAuLi4sIHJlc3VsdC53b3JkMSwgcmVzdWx0LndvcmQyCi0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGNsYXNzIERNVUwgZXh0ZW5kcyBBcml0aG1ldGljSW5zdHJ1Y3Rpb24gewotICAvKiogTXVsdGlwbHkgZG91YmxlcwotICAgKi8KLSAgcHVibGljIERNVUwoKSB7Ci0gICAgc3VwZXIoY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkRNVUwpOwotICB9Ci0KLQotICAvKioKLSAgICogQ2FsbCBjb3JyZXNwb25kaW5nIHZpc2l0b3IgbWV0aG9kKHMpLiBUaGUgb3JkZXIgaXM6Ci0gICAqIENhbGwgdmlzaXRvciBtZXRob2RzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMgZmlyc3QsIHRoZW4KLSAgICogY2FsbCBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY2xhc3MgaGllcmFyY2h5IGluIGRlc2NlbmRpbmcgb3JkZXIsCi0gICAqIGkuZS4sIHRoZSBtb3N0IHNwZWNpZmljIHZpc2l0WFhYKCkgY2FsbCBjb21lcyBsYXN0LgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRUeXBlZEluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRTdGFja1Byb2R1Y2VyKHRoaXMpOwotICAgIHYudmlzaXRTdGFja0NvbnN1bWVyKHRoaXMpOwotICAgIHYudmlzaXRBcml0aG1ldGljSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdERNVUwodGhpcyk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0RORUcuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0RORUcuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggN2JmNTkxNy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9ETkVHLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4OCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIERORUcgLSBOZWdhdGUgZG91YmxlCi0gKiA8UFJFPlN0YWNrOiAuLi4sIHZhbHVlLndvcmQxLCB2YWx1ZS53b3JkMiAtJmd0OyAuLi4sIHJlc3VsdC53b3JkMSwgcmVzdWx0LndvcmQyPC9QUkU+Ci0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGNsYXNzIERORUcgZXh0ZW5kcyBBcml0aG1ldGljSW5zdHJ1Y3Rpb24gewotICBwdWJsaWMgRE5FRygpIHsKLSAgICBzdXBlcihjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuRE5FRyk7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBDYWxsIGNvcnJlc3BvbmRpbmcgdmlzaXRvciBtZXRob2QocykuIFRoZSBvcmRlciBpczoKLSAgICogQ2FsbCB2aXNpdG9yIG1ldGhvZHMgb2YgaW1wbGVtZW50ZWQgaW50ZXJmYWNlcyBmaXJzdCwgdGhlbgotICAgKiBjYWxsIG1ldGhvZHMgYWNjb3JkaW5nIHRvIHRoZSBjbGFzcyBoaWVyYXJjaHkgaW4gZGVzY2VuZGluZyBvcmRlciwKLSAgICogaS5lLiwgdGhlIG1vc3Qgc3BlY2lmaWMgdmlzaXRYWFgoKSBjYWxsIGNvbWVzIGxhc3QuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgdi52aXNpdFR5cGVkSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdFN0YWNrUHJvZHVjZXIodGhpcyk7Ci0gICAgdi52aXNpdFN0YWNrQ29uc3VtZXIodGhpcyk7Ci0gICAgdi52aXNpdEFyaXRobWV0aWNJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0RE5FRyh0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvRFJFTS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvRFJFTS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1Y2NkNTYzLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0RSRU0uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDkxICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8qKgotICogRFJFTSAtIFJlbWFpbmRlciBvZiBkb3VibGVzCi0gKiA8UFJFPlN0YWNrOiAuLi4sIHZhbHVlMS53b3JkMSwgdmFsdWUxLndvcmQyLCB2YWx1ZTIud29yZDEsIHZhbHVlMi53b3JkMiAtJmd0OzwvUFJFPgotICogICAgICAgIC4uLiwgcmVzdWx0LndvcmQxLCByZXN1bHQud29yZDIKLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgRFJFTSBleHRlbmRzIEFyaXRobWV0aWNJbnN0cnVjdGlvbiB7Ci0gIC8qKiBSZW1haW5kZXIgb2YgZG91YmxlcwotICAgKi8KLSAgcHVibGljIERSRU0oKSB7Ci0gICAgc3VwZXIoY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkRSRU0pOwotICB9Ci0KLQotICAvKioKLSAgICogQ2FsbCBjb3JyZXNwb25kaW5nIHZpc2l0b3IgbWV0aG9kKHMpLiBUaGUgb3JkZXIgaXM6Ci0gICAqIENhbGwgdmlzaXRvciBtZXRob2RzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMgZmlyc3QsIHRoZW4KLSAgICogY2FsbCBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY2xhc3MgaGllcmFyY2h5IGluIGRlc2NlbmRpbmcgb3JkZXIsCi0gICAqIGkuZS4sIHRoZSBtb3N0IHNwZWNpZmljIHZpc2l0WFhYKCkgY2FsbCBjb21lcyBsYXN0LgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRUeXBlZEluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRTdGFja1Byb2R1Y2VyKHRoaXMpOwotICAgIHYudmlzaXRTdGFja0NvbnN1bWVyKHRoaXMpOwotICAgIHYudmlzaXRBcml0aG1ldGljSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdERSRU0odGhpcyk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0RSRVRVUk4uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0RSRVRVUk4uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNjgzMjllYi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9EUkVUVVJOLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5MCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIERSRVRVUk4gLSAgUmV0dXJuIGRvdWJsZSBmcm9tIG1ldGhvZAotICogPFBSRT5TdGFjazogLi4uLCB2YWx1ZS53b3JkMSwgdmFsdWUud29yZDIgLSZndDsgJmx0O2VtcHR5Jmd0OzwvUFJFPgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBEUkVUVVJOIGV4dGVuZHMgUmV0dXJuSW5zdHJ1Y3Rpb24gewotICAvKiogUmV0dXJuIGRvdWJsZSBmcm9tIG1ldGhvZAotICAgKi8KLSAgcHVibGljIERSRVRVUk4oKSB7Ci0gICAgc3VwZXIoY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkRSRVRVUk4pOwotICB9Ci0KLQotICAvKioKLSAgICogQ2FsbCBjb3JyZXNwb25kaW5nIHZpc2l0b3IgbWV0aG9kKHMpLiBUaGUgb3JkZXIgaXM6Ci0gICAqIENhbGwgdmlzaXRvciBtZXRob2RzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMgZmlyc3QsIHRoZW4KLSAgICogY2FsbCBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY2xhc3MgaGllcmFyY2h5IGluIGRlc2NlbmRpbmcgb3JkZXIsCi0gICAqIGkuZS4sIHRoZSBtb3N0IHNwZWNpZmljIHZpc2l0WFhYKCkgY2FsbCBjb21lcyBsYXN0LgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRFeGNlcHRpb25UaHJvd2VyKHRoaXMpOwotICAgIHYudmlzaXRUeXBlZEluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRTdGFja0NvbnN1bWVyKHRoaXMpOwotICAgIHYudmlzaXRSZXR1cm5JbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0RFJFVFVSTih0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvRFNUT1JFLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9EU1RPUkUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZjljNDFmOC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9EU1RPUkUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDk1ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8qKgotICogRFNUT1JFIC0gU3RvcmUgZG91YmxlIGludG8gbG9jYWwgdmFyaWFibGUKLSAqIDxwcmU+U3RhY2s6IC4uLiwgdmFsdWUud29yZDEsIHZhbHVlLndvcmQyIC0mZ3Q7IC4uLiA8L1BSRT4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgRFNUT1JFIGV4dGVuZHMgU3RvcmVJbnN0cnVjdGlvbiB7Ci0gIC8qKgotICAgKiBFbXB0eSBjb25zdHJ1Y3RvciBuZWVkZWQgZm9yIHRoZSBDbGFzcy5uZXdJbnN0YW5jZSgpIHN0YXRlbWVudCBpbgotICAgKiBJbnN0cnVjdGlvbi5yZWFkSW5zdHJ1Y3Rpb24oKS4gTm90IHRvIGJlIHVzZWQgb3RoZXJ3aXNlLgotICAgKi8KLSAgRFNUT1JFKCkgewotICAgIHN1cGVyKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5EU1RPUkUsIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5EU1RPUkVfMCk7Ci0gIH0KLQotICAvKiogU3RvcmUgZG91YmxlIGludG8gbG9jYWwgdmFyaWFibGUKLSAgICogQHBhcmFtIG4gaW5kZXggb2YgbG9jYWwgdmFyaWFibGUKLSAgICovCi0gIHB1YmxpYyBEU1RPUkUoaW50IG4pIHsKLSAgICBzdXBlcihjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuRFNUT1JFLCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuRFNUT1JFXzAsIG4pOwotICB9Ci0KLSAgLyoqCi0gICAqIENhbGwgY29ycmVzcG9uZGluZyB2aXNpdG9yIG1ldGhvZChzKS4gVGhlIG9yZGVyIGlzOgotICAgKiBDYWxsIHZpc2l0b3IgbWV0aG9kcyBvZiBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzIGZpcnN0LCB0aGVuCi0gICAqIGNhbGwgbWV0aG9kcyBhY2NvcmRpbmcgdG8gdGhlIGNsYXNzIGhpZXJhcmNoeSBpbiBkZXNjZW5kaW5nIG9yZGVyLAotICAgKiBpLmUuLCB0aGUgbW9zdCBzcGVjaWZpYyB2aXNpdFhYWCgpIGNhbGwgY29tZXMgbGFzdC4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICBzdXBlci5hY2NlcHQodik7Ci0gICAgdi52aXNpdERTVE9SRSh0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvRFNVQi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvRFNVQi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlOTA0MjU3Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0RTVUIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDkxICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8qKgotICogRFNVQiAtIFN1YnN0cmFjdCBkb3VibGVzCi0gKiA8UFJFPlN0YWNrOiAuLi4sIHZhbHVlMS53b3JkMSwgdmFsdWUxLndvcmQyLCB2YWx1ZTIud29yZDEsIHZhbHVlMi53b3JkMiAtJmd0OzwvUFJFPgotICogICAgICAgIC4uLiwgcmVzdWx0LndvcmQxLCByZXN1bHQud29yZDIKLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgRFNVQiBleHRlbmRzIEFyaXRobWV0aWNJbnN0cnVjdGlvbiB7Ci0gIC8qKiBTdWJzdHJhY3QgZG91YmxlcwotICAgKi8KLSAgcHVibGljIERTVUIoKSB7Ci0gICAgc3VwZXIoY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkRTVUIpOwotICB9Ci0KLQotICAvKioKLSAgICogQ2FsbCBjb3JyZXNwb25kaW5nIHZpc2l0b3IgbWV0aG9kKHMpLiBUaGUgb3JkZXIgaXM6Ci0gICAqIENhbGwgdmlzaXRvciBtZXRob2RzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMgZmlyc3QsIHRoZW4KLSAgICogY2FsbCBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY2xhc3MgaGllcmFyY2h5IGluIGRlc2NlbmRpbmcgb3JkZXIsCi0gICAqIGkuZS4sIHRoZSBtb3N0IHNwZWNpZmljIHZpc2l0WFhYKCkgY2FsbCBjb21lcyBsYXN0LgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRUeXBlZEluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRTdGFja1Byb2R1Y2VyKHRoaXMpOwotICAgIHYudmlzaXRTdGFja0NvbnN1bWVyKHRoaXMpOwotICAgIHYudmlzaXRBcml0aG1ldGljSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdERTVUIodGhpcyk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0RVUC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvRFVQLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDE2MWRmZTQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvRFVQLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4NyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIERVUCAtIER1cGxpY2F0ZSB0b3Agb3BlcmFuZCBzdGFjayB3b3JkCi0gKiA8UFJFPlN0YWNrOiAuLi4sIHdvcmQgLSZndDsgLi4uLCB3b3JkLCB3b3JkPC9QUkU+Ci0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGNsYXNzIERVUCBleHRlbmRzIFN0YWNrSW5zdHJ1Y3Rpb24gaW1wbGVtZW50cyBQdXNoSW5zdHJ1Y3Rpb24gewotICBwdWJsaWMgRFVQKCkgewotICAgIHN1cGVyKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5EVVApOwotICB9Ci0KLQotICAvKioKLSAgICogQ2FsbCBjb3JyZXNwb25kaW5nIHZpc2l0b3IgbWV0aG9kKHMpLiBUaGUgb3JkZXIgaXM6Ci0gICAqIENhbGwgdmlzaXRvciBtZXRob2RzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMgZmlyc3QsIHRoZW4KLSAgICogY2FsbCBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY2xhc3MgaGllcmFyY2h5IGluIGRlc2NlbmRpbmcgb3JkZXIsCi0gICAqIGkuZS4sIHRoZSBtb3N0IHNwZWNpZmljIHZpc2l0WFhYKCkgY2FsbCBjb21lcyBsYXN0LgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRTdGFja1Byb2R1Y2VyKHRoaXMpOwotICAgIHYudmlzaXRQdXNoSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdFN0YWNrSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdERVUCh0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvRFVQMi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvRFVQMi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjYmQxOTcyLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0RVUDIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDg3ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8qKgotICogRFVQMiAtIER1cGxpY2F0ZSB0d28gdG9wIG9wZXJhbmQgc3RhY2sgd29yZHMKLSAqIDxQUkU+U3RhY2s6IC4uLiwgd29yZDIsIHdvcmQxIC0mZ3Q7IC4uLiwgd29yZDIsIHdvcmQxLCB3b3JkMiwgd29yZDE8L1BSRT4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgRFVQMiBleHRlbmRzIFN0YWNrSW5zdHJ1Y3Rpb24gaW1wbGVtZW50cyBQdXNoSW5zdHJ1Y3Rpb24gewotICBwdWJsaWMgRFVQMigpIHsKLSAgICBzdXBlcihjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuRFVQMik7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBDYWxsIGNvcnJlc3BvbmRpbmcgdmlzaXRvciBtZXRob2QocykuIFRoZSBvcmRlciBpczoKLSAgICogQ2FsbCB2aXNpdG9yIG1ldGhvZHMgb2YgaW1wbGVtZW50ZWQgaW50ZXJmYWNlcyBmaXJzdCwgdGhlbgotICAgKiBjYWxsIG1ldGhvZHMgYWNjb3JkaW5nIHRvIHRoZSBjbGFzcyBoaWVyYXJjaHkgaW4gZGVzY2VuZGluZyBvcmRlciwKLSAgICogaS5lLiwgdGhlIG1vc3Qgc3BlY2lmaWMgdmlzaXRYWFgoKSBjYWxsIGNvbWVzIGxhc3QuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgdi52aXNpdFN0YWNrUHJvZHVjZXIodGhpcyk7Ci0gICAgdi52aXNpdFB1c2hJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0RFVQMih0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvRFVQMl9YMS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvRFVQMl9YMS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2MzYyYzA3Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0RVUDJfWDEuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDg1ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8qKgotICogRFVQMl9YMSAtIER1cGxpY2F0ZSB0d28gdG9wIG9wZXJhbmQgc3RhY2sgd29yZHMgYW5kIHB1dCB0aHJlZSBkb3duCi0gKiA8UFJFPlN0YWNrOiAuLi4sIHdvcmQzLCB3b3JkMiwgd29yZDEgLSZndDsgLi4uLCB3b3JkMiwgd29yZDEsIHdvcmQzLCB3b3JkMiwgd29yZDE8L1BSRT4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgRFVQMl9YMSBleHRlbmRzIFN0YWNrSW5zdHJ1Y3Rpb24gewotICBwdWJsaWMgRFVQMl9YMSgpIHsKLSAgICBzdXBlcihjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuRFVQMl9YMSk7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBDYWxsIGNvcnJlc3BvbmRpbmcgdmlzaXRvciBtZXRob2QocykuIFRoZSBvcmRlciBpczoKLSAgICogQ2FsbCB2aXNpdG9yIG1ldGhvZHMgb2YgaW1wbGVtZW50ZWQgaW50ZXJmYWNlcyBmaXJzdCwgdGhlbgotICAgKiBjYWxsIG1ldGhvZHMgYWNjb3JkaW5nIHRvIHRoZSBjbGFzcyBoaWVyYXJjaHkgaW4gZGVzY2VuZGluZyBvcmRlciwKLSAgICogaS5lLiwgdGhlIG1vc3Qgc3BlY2lmaWMgdmlzaXRYWFgoKSBjYWxsIGNvbWVzIGxhc3QuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgdi52aXNpdFN0YWNrSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdERVUDJfWDEodGhpcyk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0RVUDJfWDIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0RVUDJfWDIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZDgwNmIxMi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9EVVAyX1gyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4NSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIERVUDJfWDIgLSBEdXBsaWNhdGUgdHdvIHRvcCBvcGVyYW5kIHN0YWNrIHdvcmRzIGFuZCBwdXQgZm91ciBkb3duCi0gKiA8UFJFPlN0YWNrOiAuLi4sIHdvcmQ0LCB3b3JkMywgd29yZDIsIHdvcmQxIC0mZ3Q7IC4uLiwgd29yZDIsIHdvcmQxLCB3b3JkNCwgd29yZDMsIHdvcmQyLCB3b3JkMTwvUFJFPgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBEVVAyX1gyIGV4dGVuZHMgU3RhY2tJbnN0cnVjdGlvbiB7Ci0gIHB1YmxpYyBEVVAyX1gyKCkgewotICAgIHN1cGVyKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5EVVAyX1gyKTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIENhbGwgY29ycmVzcG9uZGluZyB2aXNpdG9yIG1ldGhvZChzKS4gVGhlIG9yZGVyIGlzOgotICAgKiBDYWxsIHZpc2l0b3IgbWV0aG9kcyBvZiBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzIGZpcnN0LCB0aGVuCi0gICAqIGNhbGwgbWV0aG9kcyBhY2NvcmRpbmcgdG8gdGhlIGNsYXNzIGhpZXJhcmNoeSBpbiBkZXNjZW5kaW5nIG9yZGVyLAotICAgKiBpLmUuLCB0aGUgbW9zdCBzcGVjaWZpYyB2aXNpdFhYWCgpIGNhbGwgY29tZXMgbGFzdC4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0U3RhY2tJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0RFVQMl9YMih0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvRFVQX1gxLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9EVVBfWDEuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggN2Y1YjliNy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9EVVBfWDEuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDg1ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8qKgotICogRFVQX1gxIC0gRHVwbGljYXRlIHRvcCBvcGVyYW5kIHN0YWNrIHdvcmQgYW5kIHB1dCB0d28gZG93bgotICogPFBSRT5TdGFjazogLi4uLCB3b3JkMiwgd29yZDEgLSZndDsgLi4uLCB3b3JkMSwgd29yZDIsIHdvcmQxPC9QUkU+Ci0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGNsYXNzIERVUF9YMSBleHRlbmRzIFN0YWNrSW5zdHJ1Y3Rpb24gewotICBwdWJsaWMgRFVQX1gxKCkgewotICAgIHN1cGVyKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5EVVBfWDEpOwotICB9Ci0KLQotICAvKioKLSAgICogQ2FsbCBjb3JyZXNwb25kaW5nIHZpc2l0b3IgbWV0aG9kKHMpLiBUaGUgb3JkZXIgaXM6Ci0gICAqIENhbGwgdmlzaXRvciBtZXRob2RzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMgZmlyc3QsIHRoZW4KLSAgICogY2FsbCBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY2xhc3MgaGllcmFyY2h5IGluIGRlc2NlbmRpbmcgb3JkZXIsCi0gICAqIGkuZS4sIHRoZSBtb3N0IHNwZWNpZmljIHZpc2l0WFhYKCkgY2FsbCBjb21lcyBsYXN0LgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRTdGFja0luc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXREVVBfWDEodGhpcyk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0RVUF9YMi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvRFVQX1gyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDk0YzM2MDguLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvRFVQX1gyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4NSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIERVUF9YMiAtIER1cGxpY2F0ZSB0b3Agb3BlcmFuZCBzdGFjayB3b3JkIGFuZCBwdXQgdGhyZWUgZG93bgotICogPFBSRT5TdGFjazogLi4uLCB3b3JkMywgd29yZDIsIHdvcmQxIC0mZ3Q7IC4uLiwgd29yZDEsIHdvcmQzLCB3b3JkMiwgd29yZDE8L1BSRT4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgRFVQX1gyIGV4dGVuZHMgU3RhY2tJbnN0cnVjdGlvbiB7Ci0gIHB1YmxpYyBEVVBfWDIoKSB7Ci0gICAgc3VwZXIoY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkRVUF9YMik7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBDYWxsIGNvcnJlc3BvbmRpbmcgdmlzaXRvciBtZXRob2QocykuIFRoZSBvcmRlciBpczoKLSAgICogQ2FsbCB2aXNpdG9yIG1ldGhvZHMgb2YgaW1wbGVtZW50ZWQgaW50ZXJmYWNlcyBmaXJzdCwgdGhlbgotICAgKiBjYWxsIG1ldGhvZHMgYWNjb3JkaW5nIHRvIHRoZSBjbGFzcyBoaWVyYXJjaHkgaW4gZGVzY2VuZGluZyBvcmRlciwKLSAgICogaS5lLiwgdGhlIG1vc3Qgc3BlY2lmaWMgdmlzaXRYWFgoKSBjYWxsIGNvbWVzIGxhc3QuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgdi52aXNpdFN0YWNrSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdERVUF9YMih0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvRW1wdHlWaXNpdG9yLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9FbXB0eVZpc2l0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZmRjNzdiMS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9FbXB0eVZpc2l0b3IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI0NyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIFN1cHBsaWVzIGVtcHR5IG1ldGhvZCBib2RpZXMgdG8gYmUgb3ZlcnJpZGRlbiBieSBzdWJjbGFzc2VzLgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBFbXB0eVZpc2l0b3IgaW1wbGVtZW50cyBWaXNpdG9yIHsKLSAgcHVibGljIHZvaWQgdmlzaXRTdGFja0luc3RydWN0aW9uKFN0YWNrSW5zdHJ1Y3Rpb24gb2JqKSB7IH0KLSAgcHVibGljIHZvaWQgdmlzaXRMb2NhbFZhcmlhYmxlSW5zdHJ1Y3Rpb24oTG9jYWxWYXJpYWJsZUluc3RydWN0aW9uIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0QnJhbmNoSW5zdHJ1Y3Rpb24oQnJhbmNoSW5zdHJ1Y3Rpb24gb2JqKSB7IH0KLSAgcHVibGljIHZvaWQgdmlzaXRMb2FkQ2xhc3MoTG9hZENsYXNzIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0RmllbGRJbnN0cnVjdGlvbihGaWVsZEluc3RydWN0aW9uIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0SWZJbnN0cnVjdGlvbihJZkluc3RydWN0aW9uIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0Q29udmVyc2lvbkluc3RydWN0aW9uKENvbnZlcnNpb25JbnN0cnVjdGlvbiBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdFBvcEluc3RydWN0aW9uKFBvcEluc3RydWN0aW9uIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0SnNySW5zdHJ1Y3Rpb24oSnNySW5zdHJ1Y3Rpb24gb2JqKSB7IH0KLSAgcHVibGljIHZvaWQgdmlzaXRHb3RvSW5zdHJ1Y3Rpb24oR290b0luc3RydWN0aW9uIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0U3RvcmVJbnN0cnVjdGlvbihTdG9yZUluc3RydWN0aW9uIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0VHlwZWRJbnN0cnVjdGlvbihUeXBlZEluc3RydWN0aW9uIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0U2VsZWN0KFNlbGVjdCBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdFVuY29uZGl0aW9uYWxCcmFuY2goVW5jb25kaXRpb25hbEJyYW5jaCBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdFB1c2hJbnN0cnVjdGlvbihQdXNoSW5zdHJ1Y3Rpb24gb2JqKSB7IH0KLSAgcHVibGljIHZvaWQgdmlzaXRBcml0aG1ldGljSW5zdHJ1Y3Rpb24oQXJpdGhtZXRpY0luc3RydWN0aW9uIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0Q1BJbnN0cnVjdGlvbihDUEluc3RydWN0aW9uIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0SW52b2tlSW5zdHJ1Y3Rpb24oSW52b2tlSW5zdHJ1Y3Rpb24gb2JqKSB7IH0KLSAgcHVibGljIHZvaWQgdmlzaXRBcnJheUluc3RydWN0aW9uKEFycmF5SW5zdHJ1Y3Rpb24gb2JqKSB7IH0KLSAgcHVibGljIHZvaWQgdmlzaXRBbGxvY2F0aW9uSW5zdHJ1Y3Rpb24oQWxsb2NhdGlvbkluc3RydWN0aW9uIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0UmV0dXJuSW5zdHJ1Y3Rpb24oUmV0dXJuSW5zdHJ1Y3Rpb24gb2JqKSB7IH0KLSAgcHVibGljIHZvaWQgdmlzaXRGaWVsZE9yTWV0aG9kKEZpZWxkT3JNZXRob2Qgb2JqKSB7IH0KLSAgcHVibGljIHZvaWQgdmlzaXRDb25zdGFudFB1c2hJbnN0cnVjdGlvbihDb25zdGFudFB1c2hJbnN0cnVjdGlvbiBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdEV4Y2VwdGlvblRocm93ZXIoRXhjZXB0aW9uVGhyb3dlciBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdExvYWRJbnN0cnVjdGlvbihMb2FkSW5zdHJ1Y3Rpb24gb2JqKSB7IH0KLSAgcHVibGljIHZvaWQgdmlzaXRWYXJpYWJsZUxlbmd0aEluc3RydWN0aW9uKFZhcmlhYmxlTGVuZ3RoSW5zdHJ1Y3Rpb24gb2JqKSB7IH0KLSAgcHVibGljIHZvaWQgdmlzaXRTdGFja1Byb2R1Y2VyKFN0YWNrUHJvZHVjZXIgb2JqKSB7IH0KLSAgcHVibGljIHZvaWQgdmlzaXRTdGFja0NvbnN1bWVyKFN0YWNrQ29uc3VtZXIgb2JqKSB7IH0KLSAgcHVibGljIHZvaWQgdmlzaXRBQ09OU1RfTlVMTChBQ09OU1RfTlVMTCBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdEdFVFNUQVRJQyhHRVRTVEFUSUMgb2JqKSB7IH0KLSAgcHVibGljIHZvaWQgdmlzaXRJRl9JQ01QTFQoSUZfSUNNUExUIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0TU9OSVRPUkVYSVQoTU9OSVRPUkVYSVQgb2JqKSB7IH0KLSAgcHVibGljIHZvaWQgdmlzaXRJRkxUKElGTFQgb2JqKSB7IH0KLSAgcHVibGljIHZvaWQgdmlzaXRMU1RPUkUoTFNUT1JFIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0UE9QMihQT1AyIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0QkFTVE9SRShCQVNUT1JFIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0SVNUT1JFKElTVE9SRSBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdENIRUNLQ0FTVChDSEVDS0NBU1Qgb2JqKSB7IH0KLSAgcHVibGljIHZvaWQgdmlzaXRGQ01QRyhGQ01QRyBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdEkyRihJMkYgb2JqKSB7IH0KLSAgcHVibGljIHZvaWQgdmlzaXRBVEhST1coQVRIUk9XIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0RENNUEwoRENNUEwgb2JqKSB7IH0KLSAgcHVibGljIHZvaWQgdmlzaXRBUlJBWUxFTkdUSChBUlJBWUxFTkdUSCBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdERVUChEVVAgb2JqKSB7IH0KLSAgcHVibGljIHZvaWQgdmlzaXRJTlZPS0VTVEFUSUMoSU5WT0tFU1RBVElDIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0TENPTlNUKExDT05TVCBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdERSRU0oRFJFTSBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdElGR0UoSUZHRSBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdENBTE9BRChDQUxPQUQgb2JqKSB7IH0KLSAgcHVibGljIHZvaWQgdmlzaXRMQVNUT1JFKExBU1RPUkUgb2JqKSB7IH0KLSAgcHVibGljIHZvaWQgdmlzaXRJMkQoSTJEIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0REFERChEQUREIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0SU5WT0tFU1BFQ0lBTChJTlZPS0VTUEVDSUFMIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0SUFORChJQU5EIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0UFVURklFTEQoUFVURklFTEQgb2JqKSB7IH0KLSAgcHVibGljIHZvaWQgdmlzaXRJTE9BRChJTE9BRCBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdERMT0FEKERMT0FEIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0RENPTlNUKERDT05TVCBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdE5FVyhORVcgb2JqKSB7IH0KLSAgcHVibGljIHZvaWQgdmlzaXRJRk5VTEwoSUZOVUxMIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0TFNVQihMU1VCIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0TDJJKEwySSBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdElTSFIoSVNIUiBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdFRBQkxFU1dJVENIKFRBQkxFU1dJVENIIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0SUlOQyhJSU5DIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0RFJFVFVSTihEUkVUVVJOIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0RlNUT1JFKEZTVE9SRSBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdERBU1RPUkUoREFTVE9SRSBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdElBTE9BRChJQUxPQUQgb2JqKSB7IH0KLSAgcHVibGljIHZvaWQgdmlzaXRERElWKERESVYgb2JqKSB7IH0KLSAgcHVibGljIHZvaWQgdmlzaXRJRl9JQ01QR0UoSUZfSUNNUEdFIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0TEFORChMQU5EIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0SURJVihJRElWIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0TE9SKExPUiBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdENBU1RPUkUoQ0FTVE9SRSBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdEZSRU0oRlJFTSBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdExEQyhMREMgb2JqKSB7IH0KLSAgcHVibGljIHZvaWQgdmlzaXRCSVBVU0goQklQVVNIIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0RFNUT1JFKERTVE9SRSBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdEYyTChGMkwgb2JqKSB7IH0KLSAgcHVibGljIHZvaWQgdmlzaXRGTVVMKEZNVUwgb2JqKSB7IH0KLSAgcHVibGljIHZvaWQgdmlzaXRMTE9BRChMTE9BRCBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdEpTUihKU1Igb2JqKSB7IH0KLSAgcHVibGljIHZvaWQgdmlzaXRGU1VCKEZTVUIgb2JqKSB7IH0KLSAgcHVibGljIHZvaWQgdmlzaXRTQVNUT1JFKFNBU1RPUkUgb2JqKSB7IH0KLSAgcHVibGljIHZvaWQgdmlzaXRBTE9BRChBTE9BRCBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdERVUDJfWDIoRFVQMl9YMiBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdFJFVFVSTihSRVRVUk4gb2JqKSB7IH0KLSAgcHVibGljIHZvaWQgdmlzaXREQUxPQUQoREFMT0FEIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0U0lQVVNIKFNJUFVTSCBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdERTVUIoRFNVQiBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdEwyRihMMkYgb2JqKSB7IH0KLSAgcHVibGljIHZvaWQgdmlzaXRJRl9JQ01QR1QoSUZfSUNNUEdUIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0RjJEKEYyRCBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdEkyTChJMkwgb2JqKSB7IH0KLSAgcHVibGljIHZvaWQgdmlzaXRJRl9BQ01QTkUoSUZfQUNNUE5FIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0UE9QKFBPUCBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdEkyUyhJMlMgb2JqKSB7IH0KLSAgcHVibGljIHZvaWQgdmlzaXRJRkVRKElGRVEgb2JqKSB7IH0KLSAgcHVibGljIHZvaWQgdmlzaXRTV0FQKFNXQVAgb2JqKSB7IH0KLSAgcHVibGljIHZvaWQgdmlzaXRJT1IoSU9SIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0SVJFTShJUkVNIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0SUFTVE9SRShJQVNUT1JFIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0TkVXQVJSQVkoTkVXQVJSQVkgb2JqKSB7IH0KLSAgcHVibGljIHZvaWQgdmlzaXRJTlZPS0VJTlRFUkZBQ0UoSU5WT0tFSU5URVJGQUNFIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0SU5FRyhJTkVHIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0TENNUChMQ01QIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0SlNSX1coSlNSX1cgb2JqKSB7IH0KLSAgcHVibGljIHZvaWQgdmlzaXRNVUxUSUFORVdBUlJBWShNVUxUSUFORVdBUlJBWSBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdERVUF9YMihEVVBfWDIgb2JqKSB7IH0KLSAgcHVibGljIHZvaWQgdmlzaXRTQUxPQUQoU0FMT0FEIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0SUZOT05OVUxMKElGTk9OTlVMTCBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdERNVUwoRE1VTCBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdElGTkUoSUZORSBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdElGX0lDTVBMRShJRl9JQ01QTEUgb2JqKSB7IH0KLSAgcHVibGljIHZvaWQgdmlzaXRMREMyX1coTERDMl9XIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0R0VURklFTEQoR0VURklFTEQgb2JqKSB7IH0KLSAgcHVibGljIHZvaWQgdmlzaXRMQUREKExBREQgb2JqKSB7IH0KLSAgcHVibGljIHZvaWQgdmlzaXROT1AoTk9QIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0RkFMT0FEKEZBTE9BRCBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdElOU1RBTkNFT0YoSU5TVEFOQ0VPRiBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdElGTEUoSUZMRSBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdExYT1IoTFhPUiBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdExSRVRVUk4oTFJFVFVSTiBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdEZDT05TVChGQ09OU1Qgb2JqKSB7IH0KLSAgcHVibGljIHZvaWQgdmlzaXRJVVNIUihJVVNIUiBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdEJBTE9BRChCQUxPQUQgb2JqKSB7IH0KLSAgcHVibGljIHZvaWQgdmlzaXREVVAyKERVUDIgb2JqKSB7IH0KLSAgcHVibGljIHZvaWQgdmlzaXRJRl9BQ01QRVEoSUZfQUNNUEVRIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0SU1QREVQMShJTVBERVAxIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0TU9OSVRPUkVOVEVSKE1PTklUT1JFTlRFUiBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdExTSEwoTFNITCBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdERDTVBHKERDTVBHIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0RDJMKEQyTCBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdElNUERFUDIoSU1QREVQMiBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdEwyRChMMkQgb2JqKSB7IH0KLSAgcHVibGljIHZvaWQgdmlzaXRSRVQoUkVUIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0SUZHVChJRkdUIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0SVhPUihJWE9SIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0SU5WT0tFVklSVFVBTChJTlZPS0VWSVJUVUFMIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0RkFTVE9SRShGQVNUT1JFIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0SVJFVFVSTihJUkVUVVJOIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0SUZfSUNNUE5FKElGX0lDTVBORSBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdEZMT0FEKEZMT0FEIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0TERJVihMRElWIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0UFVUU1RBVElDKFBVVFNUQVRJQyBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdEFBTE9BRChBQUxPQUQgb2JqKSB7IH0KLSAgcHVibGljIHZvaWQgdmlzaXREMkkoRDJJIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0SUZfSUNNUEVRKElGX0lDTVBFUSBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdEFBU1RPUkUoQUFTVE9SRSBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdEFSRVRVUk4oQVJFVFVSTiBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdERVUDJfWDEoRFVQMl9YMSBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdEZORUcoRk5FRyBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdEdPVE9fVyhHT1RPX1cgb2JqKSB7IH0KLSAgcHVibGljIHZvaWQgdmlzaXREMkYoRDJGIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0R09UTyhHT1RPIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0SVNVQihJU1VCIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0RjJJKEYySSBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdERORUcoRE5FRyBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdElDT05TVChJQ09OU1Qgb2JqKSB7IH0KLSAgcHVibGljIHZvaWQgdmlzaXRGRElWKEZESVYgb2JqKSB7IH0KLSAgcHVibGljIHZvaWQgdmlzaXRJMkIoSTJCIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0TE5FRyhMTkVHIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0TFJFTShMUkVNIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0SU1VTChJTVVMIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0SUFERChJQUREIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0TFNIUihMU0hSIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0TE9PS1VQU1dJVENIKExPT0tVUFNXSVRDSCBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdERVUF9YMShEVVBfWDEgb2JqKSB7IH0KLSAgcHVibGljIHZvaWQgdmlzaXRGQ01QTChGQ01QTCBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdEkyQyhJMkMgb2JqKSB7IH0KLSAgcHVibGljIHZvaWQgdmlzaXRMTVVMKExNVUwgb2JqKSB7IH0KLSAgcHVibGljIHZvaWQgdmlzaXRMVVNIUihMVVNIUiBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdElTSEwoSVNITCBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdExBTE9BRChMQUxPQUQgb2JqKSB7IH0KLSAgcHVibGljIHZvaWQgdmlzaXRBU1RPUkUoQVNUT1JFIG9iaikgeyB9Ci0gIHB1YmxpYyB2b2lkIHZpc2l0QU5FV0FSUkFZKEFORVdBUlJBWSBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdEZSRVRVUk4oRlJFVFVSTiBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdEZBREQoRkFERCBvYmopIHsgfQotICBwdWJsaWMgdm9pZCB2aXNpdEJSRUFLUE9JTlQoQlJFQUtQT0lOVCBvYmopIHsgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvRXhjZXB0aW9uVGhyb3dlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvRXhjZXB0aW9uVGhyb3dlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyM2I4NDkwLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0V4Y2VwdGlvblRocm93ZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDgyICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8qKgotICogRGVub3RlIGFuIGluc3RydWN0aW9uIHRoYXQgbWF5IHRocm93IGEgcnVuLXRpbWUgb3IgYSBsaW5raW5nCi0gKiBleGNlcHRpb24gKG9yIGJvdGgpIGR1cmluZyBleGVjdXRpb24uICBUaGlzIGlzIG5vdCBxdWl0ZSB0aGUgdHJ1dGgKLSAqIGFzIHN1Y2g7IGJlY2F1c2UgYWxsIGluc3RydWN0aW9ucyBtYXkgdGhyb3cgYW4KLSAqIGphdmEubGFuZy5WaXJ0dWFsTWFjaGluZUVycm9yLiBUaGVzZSBleGNlcHRpb25zIGFyZSBvbWl0dGVkLgotICoKLSAqIFRoZSBMYXZhIExhbmd1YWdlIFNwZWNpZmljYXRpb24gc3BlY2lmaWVzIGV4YWN0bHkgd2hpY2gKLSAqIDxpPlJVTi1USU1FPC9pPiBhbmQgd2hpY2ggPGk+TElOS0lORzwvaT4gZXhjZXB0aW9ucyBlYWNoCi0gKiBpbnN0cnVjdGlvbiBtYXkgdGhyb3cgd2hpY2ggaXMgcmVmbGVjdGVkIGJ5IHRoZSBpbXBsZW1lbnRlcnMuICBEdWUKLSAqIHRvIHRoZSBzdHJ1Y3R1cmUgb2YgdGhlIEpWTSBzcGVjaWZpY2F0aW9uLCBpdCBtYXkgYmUgcG9zc2libGUgdGhhdAotICogYW4gSW5zdHJ1Y3Rpb24gaW1wbGVtZW50aW5nIHRoaXMgaW50ZXJmYWNlIHJldHVybnMgYSBDbGFzc1tdIG9mCi0gKiBzaXplIDAuCi0gKgotICogUGxlYXNlIG5vdGUgdGhhdCB3ZSBzcGVhayBvZiBhbiAiZXhjZXB0aW9uIiBoZXJlIHdoZW4gd2UgbWVhbiBhbnkKLSAqICJUaHJvd2FibGUiIG9iamVjdDsgc28gdGhpcyB0ZXJtIGlzIGVxdWFsbHkgdXNlZCBmb3IgIkV4Y2VwdGlvbiIKLSAqIGFuZCAiRXJyb3IiIG9iamVjdHMuCi0gKgotICogQGF1dGhvciAgPEEgSFJFRj0iaHR0cDovL3d3dy5pbmYuZnUtYmVybGluLmRlL35laGFhc2UiPkVudmVyIEhhYXNlPC9BPgotICovCi1wdWJsaWMgaW50ZXJmYWNlIEV4Y2VwdGlvblRocm93ZXIgewotICBwdWJsaWMgamF2YS5sYW5nLkNsYXNzW10gZ2V0RXhjZXB0aW9ucygpOwotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvRjJELmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9GMkQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNDliMWFlNi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9GMkQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDkwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8qKgotICogRjJEIC0gQ29udmVydCBmbG9hdCB0byBkb3VibGUKLSAqIDxQUkU+U3RhY2s6IC4uLiwgdmFsdWUgLSZndDsgLi4uLCByZXN1bHQud29yZDEsIHJlc3VsdC53b3JkMjwvUFJFPgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBGMkQgZXh0ZW5kcyBDb252ZXJzaW9uSW5zdHJ1Y3Rpb24gewotICAvKiogQ29udmVydCBmbG9hdCB0byBkb3VibGUKLSAgICovCi0gIHB1YmxpYyBGMkQoKSB7Ci0gICAgc3VwZXIoY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkYyRCk7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBDYWxsIGNvcnJlc3BvbmRpbmcgdmlzaXRvciBtZXRob2QocykuIFRoZSBvcmRlciBpczoKLSAgICogQ2FsbCB2aXNpdG9yIG1ldGhvZHMgb2YgaW1wbGVtZW50ZWQgaW50ZXJmYWNlcyBmaXJzdCwgdGhlbgotICAgKiBjYWxsIG1ldGhvZHMgYWNjb3JkaW5nIHRvIHRoZSBjbGFzcyBoaWVyYXJjaHkgaW4gZGVzY2VuZGluZyBvcmRlciwKLSAgICogaS5lLiwgdGhlIG1vc3Qgc3BlY2lmaWMgdmlzaXRYWFgoKSBjYWxsIGNvbWVzIGxhc3QuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgdi52aXNpdFR5cGVkSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdFN0YWNrUHJvZHVjZXIodGhpcyk7Ci0gICAgdi52aXNpdFN0YWNrQ29uc3VtZXIodGhpcyk7Ci0gICAgdi52aXNpdENvbnZlcnNpb25JbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0RjJEKHRoaXMpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9GMkkuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0YySS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0NzFhOWY0Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0YySS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTAgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotLyoqCi0gKiBGMkkgLSBDb252ZXJ0IGZsb2F0IHRvIGludAotICogPFBSRT5TdGFjazogLi4uLCB2YWx1ZSAtJmd0OyAuLi4sIHJlc3VsdDwvUFJFPgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBGMkkgZXh0ZW5kcyBDb252ZXJzaW9uSW5zdHJ1Y3Rpb24gewotICAvKiogQ29udmVydCBmbG9hdCB0byBpbnQKLSAgICovCi0gIHB1YmxpYyBGMkkoKSB7Ci0gICAgc3VwZXIoY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkYySSk7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBDYWxsIGNvcnJlc3BvbmRpbmcgdmlzaXRvciBtZXRob2QocykuIFRoZSBvcmRlciBpczoKLSAgICogQ2FsbCB2aXNpdG9yIG1ldGhvZHMgb2YgaW1wbGVtZW50ZWQgaW50ZXJmYWNlcyBmaXJzdCwgdGhlbgotICAgKiBjYWxsIG1ldGhvZHMgYWNjb3JkaW5nIHRvIHRoZSBjbGFzcyBoaWVyYXJjaHkgaW4gZGVzY2VuZGluZyBvcmRlciwKLSAgICogaS5lLiwgdGhlIG1vc3Qgc3BlY2lmaWMgdmlzaXRYWFgoKSBjYWxsIGNvbWVzIGxhc3QuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgdi52aXNpdFR5cGVkSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdFN0YWNrUHJvZHVjZXIodGhpcyk7Ci0gICAgdi52aXNpdFN0YWNrQ29uc3VtZXIodGhpcyk7Ci0gICAgdi52aXNpdENvbnZlcnNpb25JbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0RjJJKHRoaXMpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9GMkwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0YyTC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2NzQyNTA3Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0YyTC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTAgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotLyoqCi0gKiBGMkwgLSBDb252ZXJ0IGZsb2F0IHRvIGxvbmcKLSAqIDxQUkU+U3RhY2s6IC4uLiwgdmFsdWUgLSZndDsgLi4uLCByZXN1bHQud29yZDEsIHJlc3VsdC53b3JkMjwvUFJFPgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBGMkwgZXh0ZW5kcyBDb252ZXJzaW9uSW5zdHJ1Y3Rpb24gewotICAvKiogQ29udmVydCBmbG9hdCB0byBsb25nCi0gICAqLwotICBwdWJsaWMgRjJMKCkgewotICAgIHN1cGVyKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5GMkwpOwotICB9Ci0KLQotICAvKioKLSAgICogQ2FsbCBjb3JyZXNwb25kaW5nIHZpc2l0b3IgbWV0aG9kKHMpLiBUaGUgb3JkZXIgaXM6Ci0gICAqIENhbGwgdmlzaXRvciBtZXRob2RzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMgZmlyc3QsIHRoZW4KLSAgICogY2FsbCBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY2xhc3MgaGllcmFyY2h5IGluIGRlc2NlbmRpbmcgb3JkZXIsCi0gICAqIGkuZS4sIHRoZSBtb3N0IHNwZWNpZmljIHZpc2l0WFhYKCkgY2FsbCBjb21lcyBsYXN0LgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRUeXBlZEluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRTdGFja1Byb2R1Y2VyKHRoaXMpOwotICAgIHYudmlzaXRTdGFja0NvbnN1bWVyKHRoaXMpOwotICAgIHYudmlzaXRDb252ZXJzaW9uSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdEYyTCh0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvRkFERC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvRkFERC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzZGFhYjYyLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0ZBREQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDkwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8qKgotICogRkFERCAtIEFkZCBmbG9hdHMKLSAqIDxQUkU+U3RhY2s6IC4uLiwgdmFsdWUxLCB2YWx1ZTIgLSZndDsgcmVzdWx0PC9QUkU+Ci0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGNsYXNzIEZBREQgZXh0ZW5kcyBBcml0aG1ldGljSW5zdHJ1Y3Rpb24gewotICAvKiogQWRkIGZsb2F0cwotICAgKi8KLSAgcHVibGljIEZBREQoKSB7Ci0gICAgc3VwZXIoY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkZBREQpOwotICB9Ci0KLQotICAvKioKLSAgICogQ2FsbCBjb3JyZXNwb25kaW5nIHZpc2l0b3IgbWV0aG9kKHMpLiBUaGUgb3JkZXIgaXM6Ci0gICAqIENhbGwgdmlzaXRvciBtZXRob2RzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMgZmlyc3QsIHRoZW4KLSAgICogY2FsbCBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY2xhc3MgaGllcmFyY2h5IGluIGRlc2NlbmRpbmcgb3JkZXIsCi0gICAqIGkuZS4sIHRoZSBtb3N0IHNwZWNpZmljIHZpc2l0WFhYKCkgY2FsbCBjb21lcyBsYXN0LgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRUeXBlZEluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRTdGFja1Byb2R1Y2VyKHRoaXMpOwotICAgIHYudmlzaXRTdGFja0NvbnN1bWVyKHRoaXMpOwotICAgIHYudmlzaXRBcml0aG1ldGljSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdEZBREQodGhpcyk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0ZBTE9BRC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvRkFMT0FELmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGY4MjAwMTUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvRkFMT0FELmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5MCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIEZBTE9BRCAtIExvYWQgZmxvYXQgZnJvbSBhcnJheQotICogPFBSRT5TdGFjazogLi4uLCBhcnJheXJlZiwgaW5kZXggLSZndDsgLi4uLCB2YWx1ZTwvUFJFPgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBGQUxPQUQgZXh0ZW5kcyBBcnJheUluc3RydWN0aW9uIGltcGxlbWVudHMgU3RhY2tQcm9kdWNlciB7Ci0gIC8qKiBMb2FkIGZsb2F0IGZyb20gYXJyYXkKLSAgICovCi0gIHB1YmxpYyBGQUxPQUQoKSB7Ci0gICAgc3VwZXIoY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkZBTE9BRCk7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBDYWxsIGNvcnJlc3BvbmRpbmcgdmlzaXRvciBtZXRob2QocykuIFRoZSBvcmRlciBpczoKLSAgICogQ2FsbCB2aXNpdG9yIG1ldGhvZHMgb2YgaW1wbGVtZW50ZWQgaW50ZXJmYWNlcyBmaXJzdCwgdGhlbgotICAgKiBjYWxsIG1ldGhvZHMgYWNjb3JkaW5nIHRvIHRoZSBjbGFzcyBoaWVyYXJjaHkgaW4gZGVzY2VuZGluZyBvcmRlciwKLSAgICogaS5lLiwgdGhlIG1vc3Qgc3BlY2lmaWMgdmlzaXRYWFgoKSBjYWxsIGNvbWVzIGxhc3QuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgdi52aXNpdFN0YWNrUHJvZHVjZXIodGhpcyk7Ci0gICAgdi52aXNpdEV4Y2VwdGlvblRocm93ZXIodGhpcyk7Ci0gICAgdi52aXNpdFR5cGVkSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdEFycmF5SW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdEZBTE9BRCh0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvRkFTVE9SRS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvRkFTVE9SRS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0ODMzNmQxLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0ZBU1RPUkUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDkwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8qKgotICogRkFTVE9SRSAtICBTdG9yZSBpbnRvIGZsb2F0IGFycmF5Ci0gKiA8UFJFPlN0YWNrOiAuLi4sIGFycmF5cmVmLCBpbmRleCwgdmFsdWUgLSZndDsgLi4uPC9QUkU+Ci0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGNsYXNzIEZBU1RPUkUgZXh0ZW5kcyBBcnJheUluc3RydWN0aW9uIGltcGxlbWVudHMgU3RhY2tDb25zdW1lciB7Ci0gIC8qKiBTdG9yZSBmbG9hdCBpbnRvIGFycmF5Ci0gICAqLwotICBwdWJsaWMgRkFTVE9SRSgpIHsKLSAgICBzdXBlcihjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuRkFTVE9SRSk7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBDYWxsIGNvcnJlc3BvbmRpbmcgdmlzaXRvciBtZXRob2QocykuIFRoZSBvcmRlciBpczoKLSAgICogQ2FsbCB2aXNpdG9yIG1ldGhvZHMgb2YgaW1wbGVtZW50ZWQgaW50ZXJmYWNlcyBmaXJzdCwgdGhlbgotICAgKiBjYWxsIG1ldGhvZHMgYWNjb3JkaW5nIHRvIHRoZSBjbGFzcyBoaWVyYXJjaHkgaW4gZGVzY2VuZGluZyBvcmRlciwKLSAgICogaS5lLiwgdGhlIG1vc3Qgc3BlY2lmaWMgdmlzaXRYWFgoKSBjYWxsIGNvbWVzIGxhc3QuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgdi52aXNpdFN0YWNrQ29uc3VtZXIodGhpcyk7Ci0gICAgdi52aXNpdEV4Y2VwdGlvblRocm93ZXIodGhpcyk7Ci0gICAgdi52aXNpdFR5cGVkSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdEFycmF5SW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdEZBU1RPUkUodGhpcyk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0ZDTVBHLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9GQ01QRy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjMTkyNmUxLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0ZDTVBHLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5NCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIEZDTVBHIC0gQ29tcGFyZSBmbG9hdHM6IHZhbHVlMSA+IHZhbHVlMgotICogPFBSRT5TdGFjazogLi4uLCB2YWx1ZTEsIHZhbHVlMiAtJmd0OyAuLi4sIHJlc3VsdDwvUFJFPgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBGQ01QRyBleHRlbmRzIEluc3RydWN0aW9uCi0gIGltcGxlbWVudHMgVHlwZWRJbnN0cnVjdGlvbiwgU3RhY2tQcm9kdWNlciwgU3RhY2tDb25zdW1lciB7Ci0gIHB1YmxpYyBGQ01QRygpIHsKLSAgICBzdXBlcihjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuRkNNUEcsIChzaG9ydCkxKTsKLSAgfQotCi0gIC8qKiBAcmV0dXJuIFR5cGUuRkxPQVQKLSAgICovCi0gIHB1YmxpYyBUeXBlIGdldFR5cGUoQ29uc3RhbnRQb29sR2VuIGNwKSB7Ci0gICAgcmV0dXJuIFR5cGUuRkxPQVQ7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBDYWxsIGNvcnJlc3BvbmRpbmcgdmlzaXRvciBtZXRob2QocykuIFRoZSBvcmRlciBpczoKLSAgICogQ2FsbCB2aXNpdG9yIG1ldGhvZHMgb2YgaW1wbGVtZW50ZWQgaW50ZXJmYWNlcyBmaXJzdCwgdGhlbgotICAgKiBjYWxsIG1ldGhvZHMgYWNjb3JkaW5nIHRvIHRoZSBjbGFzcyBoaWVyYXJjaHkgaW4gZGVzY2VuZGluZyBvcmRlciwKLSAgICogaS5lLiwgdGhlIG1vc3Qgc3BlY2lmaWMgdmlzaXRYWFgoKSBjYWxsIGNvbWVzIGxhc3QuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgdi52aXNpdFR5cGVkSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdFN0YWNrUHJvZHVjZXIodGhpcyk7Ci0gICAgdi52aXNpdFN0YWNrQ29uc3VtZXIodGhpcyk7Ci0gICAgdi52aXNpdEZDTVBHKHRoaXMpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9GQ01QTC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvRkNNUEwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNGVkNjJiZi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9GQ01QTC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTQgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotLyoqCi0gKiBGQ01QTCAtIENvbXBhcmUgZmxvYXRzOiB2YWx1ZTEgPCB2YWx1ZTIKLSAqIDxQUkU+U3RhY2s6IC4uLiwgdmFsdWUxLCB2YWx1ZTIgLSZndDsgLi4uLCByZXN1bHQ8L1BSRT4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgRkNNUEwgZXh0ZW5kcyBJbnN0cnVjdGlvbgotICBpbXBsZW1lbnRzIFR5cGVkSW5zdHJ1Y3Rpb24sIFN0YWNrUHJvZHVjZXIsIFN0YWNrQ29uc3VtZXIgewotICBwdWJsaWMgRkNNUEwoKSB7Ci0gICAgc3VwZXIoY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkZDTVBMLCAoc2hvcnQpMSk7Ci0gIH0KLQotICAvKiogQHJldHVybiBUeXBlLkZMT0FUCi0gICAqLwotICBwdWJsaWMgVHlwZSBnZXRUeXBlKENvbnN0YW50UG9vbEdlbiBjcCkgewotICAgIHJldHVybiBUeXBlLkZMT0FUOwotICB9Ci0KLQotICAvKioKLSAgICogQ2FsbCBjb3JyZXNwb25kaW5nIHZpc2l0b3IgbWV0aG9kKHMpLiBUaGUgb3JkZXIgaXM6Ci0gICAqIENhbGwgdmlzaXRvciBtZXRob2RzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMgZmlyc3QsIHRoZW4KLSAgICogY2FsbCBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY2xhc3MgaGllcmFyY2h5IGluIGRlc2NlbmRpbmcgb3JkZXIsCi0gICAqIGkuZS4sIHRoZSBtb3N0IHNwZWNpZmljIHZpc2l0WFhYKCkgY2FsbCBjb21lcyBsYXN0LgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRUeXBlZEluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRTdGFja1Byb2R1Y2VyKHRoaXMpOwotICAgIHYudmlzaXRTdGFja0NvbnN1bWVyKHRoaXMpOwotICAgIHYudmlzaXRGQ01QTCh0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvRkNPTlNULmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9GQ09OU1QuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMTJlOGJjZC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9GQ09OU1QuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExNiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIEZDT05TVCAtIFB1c2ggMC4wLCAxLjAgb3IgMi4wLCBvdGhlciB2YWx1ZXMgY2F1c2UgYW4gZXhjZXB0aW9uCi0gKgotICogPFBSRT5TdGFjazogLi4uIC0mZ3Q7IC4uLiwgPC9QUkU+Ci0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGNsYXNzIEZDT05TVCBleHRlbmRzIEluc3RydWN0aW9uCi0gIGltcGxlbWVudHMgQ29uc3RhbnRQdXNoSW5zdHJ1Y3Rpb24sIFR5cGVkSW5zdHJ1Y3Rpb24gewotICBwcml2YXRlIGZsb2F0IHZhbHVlOwotCi0gIC8qKgotICAgKiBFbXB0eSBjb25zdHJ1Y3RvciBuZWVkZWQgZm9yIHRoZSBDbGFzcy5uZXdJbnN0YW5jZSgpIHN0YXRlbWVudCBpbgotICAgKiBJbnN0cnVjdGlvbi5yZWFkSW5zdHJ1Y3Rpb24oKS4gTm90IHRvIGJlIHVzZWQgb3RoZXJ3aXNlLgotICAgKi8KLSAgRkNPTlNUKCkge30KLQotICBwdWJsaWMgRkNPTlNUKGZsb2F0IGYpIHsKLSAgICBzdXBlcihjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuRkNPTlNUXzAsIChzaG9ydCkxKTsKLQotICAgIGlmKGYgPT0gMC4wKQotICAgICAgb3Bjb2RlID0gY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkZDT05TVF8wOwotICAgIGVsc2UgaWYoZiA9PSAxLjApCi0gICAgICBvcGNvZGUgPSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuRkNPTlNUXzE7Ci0gICAgZWxzZSBpZihmID09IDIuMCkKLSAgICAgIG9wY29kZSA9IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5GQ09OU1RfMjsKLSAgICBlbHNlCi0gICAgICB0aHJvdyBuZXcgQ2xhc3NHZW5FeGNlcHRpb24oIkZDT05TVCBjYW4gYmUgdXNlZCBvbmx5IGZvciAwLjAsIDEuMCBhbmQgMi4wOiAiICsgZik7Ci0KLSAgICB2YWx1ZSA9IGY7Ci0gIH0KLQotICBwdWJsaWMgTnVtYmVyIGdldFZhbHVlKCkgeyByZXR1cm4gbmV3IEZsb2F0KHZhbHVlKTsgfQotCi0gIC8qKiBAcmV0dXJuIFR5cGUuRkxPQVQKLSAgICovCi0gIHB1YmxpYyBUeXBlIGdldFR5cGUoQ29uc3RhbnRQb29sR2VuIGNwKSB7Ci0gICAgcmV0dXJuIFR5cGUuRkxPQVQ7Ci0gIH0KLQotICAvKioKLSAgICogQ2FsbCBjb3JyZXNwb25kaW5nIHZpc2l0b3IgbWV0aG9kKHMpLiBUaGUgb3JkZXIgaXM6Ci0gICAqIENhbGwgdmlzaXRvciBtZXRob2RzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMgZmlyc3QsIHRoZW4KLSAgICogY2FsbCBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY2xhc3MgaGllcmFyY2h5IGluIGRlc2NlbmRpbmcgb3JkZXIsCi0gICAqIGkuZS4sIHRoZSBtb3N0IHNwZWNpZmljIHZpc2l0WFhYKCkgY2FsbCBjb21lcyBsYXN0LgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRQdXNoSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdFN0YWNrUHJvZHVjZXIodGhpcyk7Ci0gICAgdi52aXNpdFR5cGVkSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdENvbnN0YW50UHVzaEluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRGQ09OU1QodGhpcyk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0ZESVYuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0ZESVYuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNjM5ZWE1Yi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9GRElWLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5MCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIEZESVYgLSBEaXZpZGUgZmxvYXRzCi0gKiA8UFJFPlN0YWNrOiAuLi4sIHZhbHVlMSwgdmFsdWUyIC0mZ3Q7IHJlc3VsdDwvUFJFPgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBGRElWIGV4dGVuZHMgQXJpdGhtZXRpY0luc3RydWN0aW9uIHsKLSAgLyoqIERpdmlkZSBmbG9hdHMKLSAgICovCi0gIHB1YmxpYyBGRElWKCkgewotICAgIHN1cGVyKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5GRElWKTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIENhbGwgY29ycmVzcG9uZGluZyB2aXNpdG9yIG1ldGhvZChzKS4gVGhlIG9yZGVyIGlzOgotICAgKiBDYWxsIHZpc2l0b3IgbWV0aG9kcyBvZiBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzIGZpcnN0LCB0aGVuCi0gICAqIGNhbGwgbWV0aG9kcyBhY2NvcmRpbmcgdG8gdGhlIGNsYXNzIGhpZXJhcmNoeSBpbiBkZXNjZW5kaW5nIG9yZGVyLAotICAgKiBpLmUuLCB0aGUgbW9zdCBzcGVjaWZpYyB2aXNpdFhYWCgpIGNhbGwgY29tZXMgbGFzdC4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0VHlwZWRJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tQcm9kdWNlcih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tDb25zdW1lcih0aGlzKTsKLSAgICB2LnZpc2l0QXJpdGhtZXRpY0luc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRGRElWKHRoaXMpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9GTE9BRC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvRkxPQUQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNmZmYjg2ZC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9GTE9BRC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTUgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotLyoqCi0gKiBGTE9BRCAtIExvYWQgZmxvYXQgZnJvbSBsb2NhbCB2YXJpYWJsZQotICogPFBSRT5TdGFjayAuLi4gLSZndDsgLi4uLCByZXN1bHQ8L1BSRT4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgRkxPQUQgZXh0ZW5kcyBMb2FkSW5zdHJ1Y3Rpb24gewotICAvKioKLSAgICogRW1wdHkgY29uc3RydWN0b3IgbmVlZGVkIGZvciB0aGUgQ2xhc3MubmV3SW5zdGFuY2UoKSBzdGF0ZW1lbnQgaW4KLSAgICogSW5zdHJ1Y3Rpb24ucmVhZEluc3RydWN0aW9uKCkuIE5vdCB0byBiZSB1c2VkIG90aGVyd2lzZS4KLSAgICovCi0gIEZMT0FEKCkgewotICAgIHN1cGVyKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5GTE9BRCwgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkZMT0FEXzApOwotICB9Ci0KLSAgLyoqIExvYWQgZmxvYXQgZnJvbSBsb2NhbCB2YXJpYWJsZQotICAgKiBAcGFyYW0gbiBpbmRleCBvZiBsb2NhbCB2YXJpYWJsZQotICAgKi8KLSAgcHVibGljIEZMT0FEKGludCBuKSB7Ci0gICAgc3VwZXIoY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkZMT0FELCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuRkxPQURfMCwgbik7Ci0gIH0KLQotICAvKioKLSAgICogQ2FsbCBjb3JyZXNwb25kaW5nIHZpc2l0b3IgbWV0aG9kKHMpLiBUaGUgb3JkZXIgaXM6Ci0gICAqIENhbGwgdmlzaXRvciBtZXRob2RzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMgZmlyc3QsIHRoZW4KLSAgICogY2FsbCBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY2xhc3MgaGllcmFyY2h5IGluIGRlc2NlbmRpbmcgb3JkZXIsCi0gICAqIGkuZS4sIHRoZSBtb3N0IHNwZWNpZmljIHZpc2l0WFhYKCkgY2FsbCBjb21lcyBsYXN0LgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHN1cGVyLmFjY2VwdCh2KTsKLSAgICB2LnZpc2l0RkxPQUQodGhpcyk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0ZNVUwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0ZNVUwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZjhmYzQ5ZS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9GTVVMLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5MCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIEZNVUwgLSBNdWx0aXBseSBmbG9hdHMKLSAqIDxQUkU+U3RhY2s6IC4uLiwgdmFsdWUxLCB2YWx1ZTIgLSZndDsgcmVzdWx0PC9QUkU+Ci0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGNsYXNzIEZNVUwgZXh0ZW5kcyBBcml0aG1ldGljSW5zdHJ1Y3Rpb24gewotICAvKiogTXVsdGlwbHkgZmxvYXRzCi0gICAqLwotICBwdWJsaWMgRk1VTCgpIHsKLSAgICBzdXBlcihjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuRk1VTCk7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBDYWxsIGNvcnJlc3BvbmRpbmcgdmlzaXRvciBtZXRob2QocykuIFRoZSBvcmRlciBpczoKLSAgICogQ2FsbCB2aXNpdG9yIG1ldGhvZHMgb2YgaW1wbGVtZW50ZWQgaW50ZXJmYWNlcyBmaXJzdCwgdGhlbgotICAgKiBjYWxsIG1ldGhvZHMgYWNjb3JkaW5nIHRvIHRoZSBjbGFzcyBoaWVyYXJjaHkgaW4gZGVzY2VuZGluZyBvcmRlciwKLSAgICogaS5lLiwgdGhlIG1vc3Qgc3BlY2lmaWMgdmlzaXRYWFgoKSBjYWxsIGNvbWVzIGxhc3QuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgdi52aXNpdFR5cGVkSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdFN0YWNrUHJvZHVjZXIodGhpcyk7Ci0gICAgdi52aXNpdFN0YWNrQ29uc3VtZXIodGhpcyk7Ci0gICAgdi52aXNpdEFyaXRobWV0aWNJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0Rk1VTCh0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvRk5FRy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvRk5FRy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2NDI4ZmI2Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0ZORUcuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDg4ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8qKgotICogRk5FRyAtIE5lZ2F0ZSBmbG9hdAotICogPFBSRT5TdGFjazogLi4uLCB2YWx1ZSAtJmd0OyAuLi4sIHJlc3VsdDwvUFJFPgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBGTkVHIGV4dGVuZHMgQXJpdGhtZXRpY0luc3RydWN0aW9uIHsKLSAgcHVibGljIEZORUcoKSB7Ci0gICAgc3VwZXIoY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkZORUcpOwotICB9Ci0KLQotICAvKioKLSAgICogQ2FsbCBjb3JyZXNwb25kaW5nIHZpc2l0b3IgbWV0aG9kKHMpLiBUaGUgb3JkZXIgaXM6Ci0gICAqIENhbGwgdmlzaXRvciBtZXRob2RzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMgZmlyc3QsIHRoZW4KLSAgICogY2FsbCBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY2xhc3MgaGllcmFyY2h5IGluIGRlc2NlbmRpbmcgb3JkZXIsCi0gICAqIGkuZS4sIHRoZSBtb3N0IHNwZWNpZmljIHZpc2l0WFhYKCkgY2FsbCBjb21lcyBsYXN0LgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRUeXBlZEluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRTdGFja1Byb2R1Y2VyKHRoaXMpOwotICAgIHYudmlzaXRTdGFja0NvbnN1bWVyKHRoaXMpOwotICAgIHYudmlzaXRBcml0aG1ldGljSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdEZORUcodGhpcyk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0ZSRU0uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0ZSRU0uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNmVjOTlhMC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9GUkVNLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5MCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIEZSRU0gLSBSZW1haW5kZXIgb2YgZmxvYXRzCi0gKiA8UFJFPlN0YWNrOiAuLi4sIHZhbHVlMSwgdmFsdWUyIC0mZ3Q7IHJlc3VsdDwvUFJFPgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBGUkVNIGV4dGVuZHMgQXJpdGhtZXRpY0luc3RydWN0aW9uIHsKLSAgLyoqIFJlbWFpbmRlciBvZiBmbG9hdHMKLSAgICovCi0gIHB1YmxpYyBGUkVNKCkgewotICAgIHN1cGVyKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5GUkVNKTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIENhbGwgY29ycmVzcG9uZGluZyB2aXNpdG9yIG1ldGhvZChzKS4gVGhlIG9yZGVyIGlzOgotICAgKiBDYWxsIHZpc2l0b3IgbWV0aG9kcyBvZiBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzIGZpcnN0LCB0aGVuCi0gICAqIGNhbGwgbWV0aG9kcyBhY2NvcmRpbmcgdG8gdGhlIGNsYXNzIGhpZXJhcmNoeSBpbiBkZXNjZW5kaW5nIG9yZGVyLAotICAgKiBpLmUuLCB0aGUgbW9zdCBzcGVjaWZpYyB2aXNpdFhYWCgpIGNhbGwgY29tZXMgbGFzdC4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0VHlwZWRJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tQcm9kdWNlcih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tDb25zdW1lcih0aGlzKTsKLSAgICB2LnZpc2l0QXJpdGhtZXRpY0luc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRGUkVNKHRoaXMpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9GUkVUVVJOLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9GUkVUVVJOLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDMyZTlhODAuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvRlJFVFVSTi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTAgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotLyoqCi0gKiBGUkVUVVJOIC0gIFJldHVybiBmbG9hdCBmcm9tIG1ldGhvZAotICogPFBSRT5TdGFjazogLi4uLCB2YWx1ZSAtJmd0OyAmbHQ7ZW1wdHkmZ3Q7PC9QUkU+Ci0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGNsYXNzIEZSRVRVUk4gZXh0ZW5kcyBSZXR1cm5JbnN0cnVjdGlvbiB7Ci0gIC8qKiBSZXR1cm4gZmxvYXQgZnJvbSBtZXRob2QKLSAgICovCi0gIHB1YmxpYyBGUkVUVVJOKCkgewotICAgIHN1cGVyKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5GUkVUVVJOKTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIENhbGwgY29ycmVzcG9uZGluZyB2aXNpdG9yIG1ldGhvZChzKS4gVGhlIG9yZGVyIGlzOgotICAgKiBDYWxsIHZpc2l0b3IgbWV0aG9kcyBvZiBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzIGZpcnN0LCB0aGVuCi0gICAqIGNhbGwgbWV0aG9kcyBhY2NvcmRpbmcgdG8gdGhlIGNsYXNzIGhpZXJhcmNoeSBpbiBkZXNjZW5kaW5nIG9yZGVyLAotICAgKiBpLmUuLCB0aGUgbW9zdCBzcGVjaWZpYyB2aXNpdFhYWCgpIGNhbGwgY29tZXMgbGFzdC4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0RXhjZXB0aW9uVGhyb3dlcih0aGlzKTsKLSAgICB2LnZpc2l0VHlwZWRJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tDb25zdW1lcih0aGlzKTsKLSAgICB2LnZpc2l0UmV0dXJuSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdEZSRVRVUk4odGhpcyk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0ZTVE9SRS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvRlNUT1JFLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGJmODA3OTEuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvRlNUT1JFLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5NSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIEZTVE9SRSAtIFN0b3JlIGZsb2F0IGludG8gbG9jYWwgdmFyaWFibGUKLSAqIDxQUkU+U3RhY2s6IC4uLiwgdmFsdWUgLSZndDsgLi4uIDwvUFJFPgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBGU1RPUkUgZXh0ZW5kcyBTdG9yZUluc3RydWN0aW9uIHsKLSAgLyoqCi0gICAqIEVtcHR5IGNvbnN0cnVjdG9yIG5lZWRlZCBmb3IgdGhlIENsYXNzLm5ld0luc3RhbmNlKCkgc3RhdGVtZW50IGluCi0gICAqIEluc3RydWN0aW9uLnJlYWRJbnN0cnVjdGlvbigpLiBOb3QgdG8gYmUgdXNlZCBvdGhlcndpc2UuCi0gICAqLwotICBGU1RPUkUoKSB7Ci0gICAgc3VwZXIoY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkZTVE9SRSwgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkZTVE9SRV8wKTsKLSAgfQotCi0gIC8qKiBTdG9yZSBmbG9hdCBpbnRvIGxvY2FsIHZhcmlhYmxlCi0gICAqIEBwYXJhbSBuIGluZGV4IG9mIGxvY2FsIHZhcmlhYmxlCi0gICAqLwotICBwdWJsaWMgRlNUT1JFKGludCBuKSB7Ci0gICAgc3VwZXIoY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkZTVE9SRSwgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkZTVE9SRV8wLCBuKTsKLSAgfQotCi0gIC8qKgotICAgKiBDYWxsIGNvcnJlc3BvbmRpbmcgdmlzaXRvciBtZXRob2QocykuIFRoZSBvcmRlciBpczoKLSAgICogQ2FsbCB2aXNpdG9yIG1ldGhvZHMgb2YgaW1wbGVtZW50ZWQgaW50ZXJmYWNlcyBmaXJzdCwgdGhlbgotICAgKiBjYWxsIG1ldGhvZHMgYWNjb3JkaW5nIHRvIHRoZSBjbGFzcyBoaWVyYXJjaHkgaW4gZGVzY2VuZGluZyBvcmRlciwKLSAgICogaS5lLiwgdGhlIG1vc3Qgc3BlY2lmaWMgdmlzaXRYWFgoKSBjYWxsIGNvbWVzIGxhc3QuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgc3VwZXIuYWNjZXB0KHYpOwotICAgIHYudmlzaXRGU1RPUkUodGhpcyk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0ZTVUIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0ZTVUIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZGE1OWZjZi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9GU1VCLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5MCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIEZTVUIgLSBTdWJzdHJhY3QgZmxvYXRzCi0gKiA8UFJFPlN0YWNrOiAuLi4sIHZhbHVlMSwgdmFsdWUyIC0mZ3Q7IHJlc3VsdDwvUFJFPgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBGU1VCIGV4dGVuZHMgQXJpdGhtZXRpY0luc3RydWN0aW9uIHsKLSAgLyoqIFN1YnN0cmFjdCBmbG9hdHMKLSAgICovCi0gIHB1YmxpYyBGU1VCKCkgewotICAgIHN1cGVyKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5GU1VCKTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIENhbGwgY29ycmVzcG9uZGluZyB2aXNpdG9yIG1ldGhvZChzKS4gVGhlIG9yZGVyIGlzOgotICAgKiBDYWxsIHZpc2l0b3IgbWV0aG9kcyBvZiBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzIGZpcnN0LCB0aGVuCi0gICAqIGNhbGwgbWV0aG9kcyBhY2NvcmRpbmcgdG8gdGhlIGNsYXNzIGhpZXJhcmNoeSBpbiBkZXNjZW5kaW5nIG9yZGVyLAotICAgKiBpLmUuLCB0aGUgbW9zdCBzcGVjaWZpYyB2aXNpdFhYWCgpIGNhbGwgY29tZXMgbGFzdC4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0VHlwZWRJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tQcm9kdWNlcih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tDb25zdW1lcih0aGlzKTsKLSAgICB2LnZpc2l0QXJpdGhtZXRpY0luc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRGU1VCKHRoaXMpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9GaWVsZEdlbi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvRmllbGRHZW4uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMjkwYTNjMC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9GaWVsZEdlbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzEzICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuY2xhc3NmaWxlLio7Ci1pbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKLWltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7Ci0KLS8qKgotICogVGVtcGxhdGUgY2xhc3MgZm9yIGJ1aWxkaW5nIHVwIGEgZmllbGQuICBUaGUgb25seSBleHRyYW9yZGluYXJ5IHRoaW5nCi0gKiBvbmUgY2FuIGRvIGlzIHRvIGFkZCBhIGNvbnN0YW50IHZhbHVlIGF0dHJpYnV0ZSB0byBhIGZpZWxkICh3aGljaCBtdXN0IG9mCi0gKiBjb3Vyc2UgYmUgY29tcGF0aWJsZSB3aXRoIHRvIHRoZSBkZWNsYXJlZCB0eXBlKS4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICogQHNlZSBGaWVsZAotICovCi1wdWJsaWMgY2xhc3MgRmllbGRHZW4gZXh0ZW5kcyBGaWVsZEdlbk9yTWV0aG9kR2VuIHsKLSAgcHJpdmF0ZSBPYmplY3QgdmFsdWUgPSBudWxsOwotCi0gIC8qKgotICAgKiBEZWNsYXJlIGEgZmllbGQuIElmIGl0IGlzIHN0YXRpYyAoaXNTdGF0aWMoKSA9PSB0cnVlKSBhbmQgaGFzIGEKLSAgICogYmFzaWMgdHlwZSBsaWtlIGludCBvciBTdHJpbmcgaXQgbWF5IGhhdmUgYW4gaW5pdGlhbCB2YWx1ZQotICAgKiBhc3NvY2lhdGVkIHdpdGggaXQgYXMgZGVmaW5lZCBieSBzZXRJbml0VmFsdWUoKS4KLSAgICoKLSAgICogQHBhcmFtIGFjY2Vzc19mbGFncyBhY2Nlc3MgcXVhbGlmaWVycwotICAgKiBAcGFyYW0gdHlwZSAgZmllbGQgdHlwZQotICAgKiBAcGFyYW0gbmFtZSBmaWVsZCBuYW1lCi0gICAqIEBwYXJhbSBjcCBjb25zdGFudCBwb29sCi0gICAqLwotICBwdWJsaWMgRmllbGRHZW4oaW50IGFjY2Vzc19mbGFncywgVHlwZSB0eXBlLCBTdHJpbmcgbmFtZSwgQ29uc3RhbnRQb29sR2VuIGNwKSB7Ci0gICAgc2V0QWNjZXNzRmxhZ3MoYWNjZXNzX2ZsYWdzKTsKLSAgICBzZXRUeXBlKHR5cGUpOwotICAgIHNldE5hbWUobmFtZSk7Ci0gICAgc2V0Q29uc3RhbnRQb29sKGNwKTsKLSAgfQotCi0gIC8qKgotICAgKiBJbnN0YW50aWF0ZSBmcm9tIGV4aXN0aW5nIGZpZWxkLgotICAgKgotICAgKiBAcGFyYW0gZmllbGQgRmllbGQgb2JqZWN0Ci0gICAqIEBwYXJhbSBjcCBjb25zdGFudCBwb29sIChtdXN0IGNvbnRhaW4gdGhlIHNhbWUgZW50cmllcyBhcyB0aGUgZmllbGQncyBjb25zdGFudCBwb29sKQotICAgKi8KLSAgcHVibGljIEZpZWxkR2VuKEZpZWxkIGZpZWxkLCBDb25zdGFudFBvb2xHZW4gY3ApIHsKLSAgICB0aGlzKGZpZWxkLmdldEFjY2Vzc0ZsYWdzKCksIFR5cGUuZ2V0VHlwZShmaWVsZC5nZXRTaWduYXR1cmUoKSksIGZpZWxkLmdldE5hbWUoKSwgY3ApOwotCi0gICAgQXR0cmlidXRlW10gYXR0cnMgPSBmaWVsZC5nZXRBdHRyaWJ1dGVzKCk7Ci0KLSAgICBmb3IoaW50IGk9MDsgaSA8IGF0dHJzLmxlbmd0aDsgaSsrKSB7Ci0gICAgICBpZihhdHRyc1tpXSBpbnN0YW5jZW9mIENvbnN0YW50VmFsdWUpCi0gICAgICAgIHNldFZhbHVlKCgoQ29uc3RhbnRWYWx1ZSlhdHRyc1tpXSkuZ2V0Q29uc3RhbnRWYWx1ZUluZGV4KCkpOwotICAgICAgZWxzZQotICAgICAgICBhZGRBdHRyaWJ1dGUoYXR0cnNbaV0pOwotICAgIH0KLSAgfQotCi0gIHByaXZhdGUgdm9pZCBzZXRWYWx1ZShpbnQgaW5kZXgpIHsKLSAgICBDb25zdGFudFBvb2wgY3AgID0gdGhpcy5jcC5nZXRDb25zdGFudFBvb2woKTsKLSAgICBDb25zdGFudCAgICAgYyAgID0gY3AuZ2V0Q29uc3RhbnQoaW5kZXgpOwotICAgIHZhbHVlID0gKChDb25zdGFudE9iamVjdCljKS5nZXRDb25zdGFudFZhbHVlKGNwKTsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgKG9wdGlvbmFsKSBpbml0aWFsIHZhbHVlIG9mIGZpZWxkLCBvdGhlcndpc2UgaXQgd2lsbCBiZSBzZXQgdG8gbnVsbC8wL2ZhbHNlCi0gICAqIGJ5IHRoZSBKVk0gYXV0b21hdGljYWxseS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldEluaXRWYWx1ZShTdHJpbmcgc3RyKSB7Ci0gICAgY2hlY2tUeXBlKG5ldyBPYmplY3RUeXBlKCJqYXZhLmxhbmcuU3RyaW5nIikpOwotCi0gICAgaWYoc3RyICE9IG51bGwpCi0gICAgICB2YWx1ZSA9IHN0cjsKLSAgfQotCi0gIHB1YmxpYyB2b2lkIHNldEluaXRWYWx1ZShsb25nIGwpIHsKLSAgICBjaGVja1R5cGUoVHlwZS5MT05HKTsKLQotICAgIGlmKGwgIT0gMEwpCi0gICAgICB2YWx1ZSA9IG5ldyBMb25nKGwpOwotICB9Ci0KLSAgcHVibGljIHZvaWQgc2V0SW5pdFZhbHVlKGludCBpKSB7Ci0gICAgY2hlY2tUeXBlKFR5cGUuSU5UKTsKLQotICAgIGlmKGkgIT0gMCkKLSAgICAgIHZhbHVlID0gbmV3IEludGVnZXIoaSk7Ci0gIH0KLQotICBwdWJsaWMgdm9pZCBzZXRJbml0VmFsdWUoc2hvcnQgcykgewotICAgIGNoZWNrVHlwZShUeXBlLlNIT1JUKTsKLQotICAgIGlmKHMgIT0gMCkKLSAgICAgIHZhbHVlID0gbmV3IEludGVnZXIocyk7Ci0gIH0KLQotICBwdWJsaWMgdm9pZCBzZXRJbml0VmFsdWUoY2hhciBjKSB7Ci0gICAgY2hlY2tUeXBlKFR5cGUuQ0hBUik7Ci0KLSAgICBpZihjICE9IDApCi0gICAgICB2YWx1ZSA9IG5ldyBJbnRlZ2VyKGMpOwotICB9Ci0KLSAgcHVibGljIHZvaWQgc2V0SW5pdFZhbHVlKGJ5dGUgYikgewotICAgIGNoZWNrVHlwZShUeXBlLkJZVEUpOwotCi0gICAgaWYoYiAhPSAwKQotICAgICAgdmFsdWUgPSBuZXcgSW50ZWdlcihiKTsKLSAgfQotCi0gIHB1YmxpYyB2b2lkIHNldEluaXRWYWx1ZShib29sZWFuIGIpIHsKLSAgICBjaGVja1R5cGUoVHlwZS5CT09MRUFOKTsKLQotICAgIGlmKGIpCi0gICAgICB2YWx1ZSA9IG5ldyBJbnRlZ2VyKDEpOwotICB9Ci0KLSAgcHVibGljIHZvaWQgc2V0SW5pdFZhbHVlKGZsb2F0IGYpIHsKLSAgICBjaGVja1R5cGUoVHlwZS5GTE9BVCk7Ci0KLSAgICBpZihmICE9IDAuMCkKLSAgICAgIHZhbHVlID0gbmV3IEZsb2F0KGYpOwotICB9Ci0KLSAgcHVibGljIHZvaWQgc2V0SW5pdFZhbHVlKGRvdWJsZSBkKSB7Ci0gICAgY2hlY2tUeXBlKFR5cGUuRE9VQkxFKTsKLQotICAgIGlmKGQgIT0gMC4wKQotICAgICAgdmFsdWUgPSBuZXcgRG91YmxlKGQpOwotICB9Ci0KLSAgLyoqIFJlbW92ZSBhbnkgaW5pdGlhbCB2YWx1ZS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGNhbmNlbEluaXRWYWx1ZSgpIHsKLSAgICB2YWx1ZSA9IG51bGw7Ci0gIH0KLQotICBwcml2YXRlIHZvaWQgY2hlY2tUeXBlKFR5cGUgYXR5cGUpIHsKLSAgICBpZih0eXBlID09IG51bGwpCi0gICAgICB0aHJvdyBuZXcgQ2xhc3NHZW5FeGNlcHRpb24oIllvdSBoYXZlbid0IGRlZmluZWQgdGhlIHR5cGUgb2YgdGhlIGZpZWxkIHlldCIpOwotCi0gICAgaWYoIWlzRmluYWwoKSkKLSAgICAgIHRocm93IG5ldyBDbGFzc0dlbkV4Y2VwdGlvbigiT25seSBmaW5hbCBmaWVsZHMgbWF5IGhhdmUgYW4gaW5pdGlhbCB2YWx1ZSEiKTsKLQotICAgIGlmKCF0eXBlLmVxdWFscyhhdHlwZSkpCi0gICAgICB0aHJvdyBuZXcgQ2xhc3NHZW5FeGNlcHRpb24oIlR5cGVzIGFyZSBub3QgY29tcGF0aWJsZTogIiArIHR5cGUgKyAiIHZzLiAiICsgYXR5cGUpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBmaWVsZCBvYmplY3QgYWZ0ZXIgaGF2aW5nIHNldCB1cCBhbGwgbmVjZXNzYXJ5IHZhbHVlcy4KLSAgICovCi0gIHB1YmxpYyBGaWVsZCBnZXRGaWVsZCgpIHsKLSAgICBTdHJpbmcgICAgICBzaWduYXR1cmUgICAgICAgPSBnZXRTaWduYXR1cmUoKTsKLSAgICBpbnQgICAgICAgICBuYW1lX2luZGV4ICAgICAgPSBjcC5hZGRVdGY4KG5hbWUpOwotICAgIGludCAgICAgICAgIHNpZ25hdHVyZV9pbmRleCA9IGNwLmFkZFV0Zjgoc2lnbmF0dXJlKTsKLQotICAgIGlmKHZhbHVlICE9IG51bGwpIHsKLSAgICAgIGNoZWNrVHlwZSh0eXBlKTsKLSAgICAgIGludCBpbmRleCA9IGFkZENvbnN0YW50KCk7Ci0gICAgICBhZGRBdHRyaWJ1dGUobmV3IENvbnN0YW50VmFsdWUoY3AuYWRkVXRmOCgiQ29uc3RhbnRWYWx1ZSIpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDIsIGluZGV4LCBjcC5nZXRDb25zdGFudFBvb2woKSkpOwotICAgIH0KLQotICAgIHJldHVybiBuZXcgRmllbGQoYWNjZXNzX2ZsYWdzLCBuYW1lX2luZGV4LCBzaWduYXR1cmVfaW5kZXgsIGdldEF0dHJpYnV0ZXMoKSwKLSAgICAgICAgICAgICAgICAgICAgIGNwLmdldENvbnN0YW50UG9vbCgpKTsKLSAgfQotCi0gIHByaXZhdGUgaW50IGFkZENvbnN0YW50KCkgewotICAgIHN3aXRjaCh0eXBlLmdldFR5cGUoKSkgewotICAgIGNhc2UgQ29uc3RhbnRzLlRfSU5UOiBjYXNlIENvbnN0YW50cy5UX0NIQVI6IGNhc2UgQ29uc3RhbnRzLlRfQllURToKLSAgICBjYXNlIENvbnN0YW50cy5UX0JPT0xFQU46IGNhc2UgQ29uc3RhbnRzLlRfU0hPUlQ6Ci0gICAgICByZXR1cm4gY3AuYWRkSW50ZWdlcigoKEludGVnZXIpdmFsdWUpLmludFZhbHVlKCkpOwotCi0gICAgY2FzZSBDb25zdGFudHMuVF9GTE9BVDoKLSAgICAgIHJldHVybiBjcC5hZGRGbG9hdCgoKEZsb2F0KXZhbHVlKS5mbG9hdFZhbHVlKCkpOwotCi0gICAgY2FzZSBDb25zdGFudHMuVF9ET1VCTEU6Ci0gICAgICByZXR1cm4gY3AuYWRkRG91YmxlKCgoRG91YmxlKXZhbHVlKS5kb3VibGVWYWx1ZSgpKTsKLQotICAgIGNhc2UgQ29uc3RhbnRzLlRfTE9ORzoKLSAgICAgIHJldHVybiBjcC5hZGRMb25nKCgoTG9uZyl2YWx1ZSkubG9uZ1ZhbHVlKCkpOwotCi0gICAgY2FzZSBDb25zdGFudHMuVF9SRUZFUkVOQ0U6Ci0gICAgICByZXR1cm4gY3AuYWRkU3RyaW5nKCgoU3RyaW5nKXZhbHVlKSk7Ci0KLSAgICBkZWZhdWx0OgotICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIk9vcHM6IFVuaGFuZGxlZCA6ICIgKyB0eXBlLmdldFR5cGUoKSk7Ci0gICAgfQotICB9Ci0KLSAgcHVibGljIFN0cmluZyAgZ2V0U2lnbmF0dXJlKCkgIHsgcmV0dXJuIHR5cGUuZ2V0U2lnbmF0dXJlKCk7IH0KLQotICBwcml2YXRlIEFycmF5TGlzdCBvYnNlcnZlcnM7Ci0KLSAgLyoqIEFkZCBvYnNlcnZlciBmb3IgdGhpcyBvYmplY3QuCi0gICAqLwotICBwdWJsaWMgdm9pZCBhZGRPYnNlcnZlcihGaWVsZE9ic2VydmVyIG8pIHsKLSAgICBpZihvYnNlcnZlcnMgPT0gbnVsbCkKLSAgICAgIG9ic2VydmVycyA9IG5ldyBBcnJheUxpc3QoKTsKLQotICAgIG9ic2VydmVycy5hZGQobyk7Ci0gIH0KLQotICAvKiogUmVtb3ZlIG9ic2VydmVyIGZvciB0aGlzIG9iamVjdC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHJlbW92ZU9ic2VydmVyKEZpZWxkT2JzZXJ2ZXIgbykgewotICAgIGlmKG9ic2VydmVycyAhPSBudWxsKQotICAgICAgb2JzZXJ2ZXJzLnJlbW92ZShvKTsKLSAgfQotCi0gIC8qKiBDYWxsIG5vdGlmeSgpIG1ldGhvZCBvbiBhbGwgb2JzZXJ2ZXJzLiBUaGlzIG1ldGhvZCBpcyBub3QgY2FsbGVkCi0gICAqIGF1dG9tYXRpY2FsbHkgd2hlbmV2ZXIgdGhlIHN0YXRlIGhhcyBjaGFuZ2VkLCBidXQgaGFzIHRvIGJlCi0gICAqIGNhbGxlZCBieSB0aGUgdXNlciBhZnRlciBoZSBoYXMgZmluaXNoZWQgZWRpdGluZyB0aGUgb2JqZWN0LgotICAgKi8KLSAgcHVibGljIHZvaWQgdXBkYXRlKCkgewotICAgIGlmKG9ic2VydmVycyAhPSBudWxsKQotICAgICAgZm9yKEl0ZXJhdG9yIGUgPSBvYnNlcnZlcnMuaXRlcmF0b3IoKTsgZS5oYXNOZXh0KCk7ICkKLSAgICAgICAgKChGaWVsZE9ic2VydmVyKWUubmV4dCgpKS5ub3RpZnkodGhpcyk7Ci0gIH0KLQotICBwdWJsaWMgU3RyaW5nIGdldEluaXRWYWx1ZSgpIHsKLSAgICBpZih2YWx1ZSAhPSBudWxsKSB7Ci0gICAgICByZXR1cm4gdmFsdWUudG9TdHJpbmcoKTsKLSAgICB9IGVsc2UKLSAgICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiBzdHJpbmcgcmVwcmVzZW50YXRpb24gY2xvc2UgdG8gZGVjbGFyYXRpb24gZm9ybWF0LAotICAgKiBgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBNQVggPSAxMDAnLCBlLmcuLgotICAgKgotICAgKiBAcmV0dXJuIFN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBmaWVsZAotICAgKi8KLSAgcHVibGljIGZpbmFsIFN0cmluZyB0b1N0cmluZygpIHsKLSAgICBTdHJpbmcgbmFtZSwgc2lnbmF0dXJlLCBhY2Nlc3M7IC8vIFNob3J0IGN1dHMgdG8gY29uc3RhbnQgcG9vbAotCi0gICAgYWNjZXNzICAgID0gVXRpbGl0eS5hY2Nlc3NUb1N0cmluZyhhY2Nlc3NfZmxhZ3MpOwotICAgIGFjY2VzcyAgICA9IGFjY2Vzcy5lcXVhbHMoIiIpPyAiIiA6IChhY2Nlc3MgKyAiICIpOwotICAgIHNpZ25hdHVyZSA9IHR5cGUudG9TdHJpbmcoKTsKLSAgICBuYW1lICAgICAgPSBnZXROYW1lKCk7Ci0KLSAgICBTdHJpbmdCdWZmZXIgYnVmID0gbmV3IFN0cmluZ0J1ZmZlcihhY2Nlc3MgKyBzaWduYXR1cmUgKyAiICIgKyBuYW1lKTsKLSAgICBTdHJpbmcgdmFsdWUgPSBnZXRJbml0VmFsdWUoKTsKLQotICAgIGlmKHZhbHVlICE9IG51bGwpCi0gICAgICBidWYuYXBwZW5kKCIgPSAiICsgdmFsdWUpOwotCi0gICAgcmV0dXJuIGJ1Zi50b1N0cmluZygpOwotICB9Ci0KLSAgLyoqIEByZXR1cm4gZGVlcCBjb3B5IG9mIHRoaXMgZmllbGQKLSAgICovCi0gIHB1YmxpYyBGaWVsZEdlbiBjb3B5KENvbnN0YW50UG9vbEdlbiBjcCkgewotICAgIEZpZWxkR2VuIGZnID0gKEZpZWxkR2VuKWNsb25lKCk7Ci0KLSAgICBmZy5zZXRDb25zdGFudFBvb2woY3ApOwotICAgIHJldHVybiBmZzsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvRmllbGRHZW5Pck1ldGhvZEdlbi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvRmllbGRHZW5Pck1ldGhvZEdlbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlNzVkOGQ4Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0ZpZWxkR2VuT3JNZXRob2RHZW4uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEzOCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50czsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmNsYXNzZmlsZS4qOwotaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7Ci0KLS8qKgotICogU3VwZXIgY2xhc3MgZm9yIEZpZWxkR2VuIGFuZCBNZXRob2RHZW4gb2JqZWN0cywgc2luY2UgdGhleSBoYXZlCi0gKiBzb21lIG1ldGhvZHMgaW4gY29tbW9uIQotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBGaWVsZEdlbk9yTWV0aG9kR2VuIGV4dGVuZHMgQWNjZXNzRmxhZ3MKLSAgaW1wbGVtZW50cyBOYW1lZEFuZFR5cGVkLCBDbG9uZWFibGUKLXsKLSAgcHJvdGVjdGVkIFN0cmluZyAgICAgICAgICBuYW1lOwotICBwcm90ZWN0ZWQgVHlwZSAgICAgICAgICAgIHR5cGU7Ci0gIHByb3RlY3RlZCBDb25zdGFudFBvb2xHZW4gY3A7Ci0gIHByaXZhdGUgICBBcnJheUxpc3QgICAgICAgYXR0cmlidXRlX3ZlYyA9IG5ldyBBcnJheUxpc3QoKTsKLQotICBwcm90ZWN0ZWQgRmllbGRHZW5Pck1ldGhvZEdlbigpIHt9Ci0KLSAgcHVibGljIHZvaWQgICAgICAgICAgICBzZXRUeXBlKFR5cGUgdHlwZSkgICB7Ci0gICAgaWYodHlwZS5nZXRUeXBlKCkgPT0gQ29uc3RhbnRzLlRfQUREUkVTUykKLSAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIlR5cGUgY2FuIG5vdCBiZSAiICsgdHlwZSk7Ci0KLSAgICB0aGlzLnR5cGUgPSB0eXBlOwotICB9Ci0gIHB1YmxpYyBUeXBlICAgICAgICAgICAgZ2V0VHlwZSgpICAgICAgICAgICAgeyByZXR1cm4gdHlwZTsgfQotCi0gIC8qKiBAcmV0dXJuIG5hbWUgb2YgbWV0aG9kL2ZpZWxkLgotICAgKi8KLSAgcHVibGljIFN0cmluZyAgICAgICAgICBnZXROYW1lKCkgICAgICAgICAgICB7IHJldHVybiBuYW1lOyB9Ci0gIHB1YmxpYyB2b2lkICAgICAgICAgICAgc2V0TmFtZShTdHJpbmcgbmFtZSkgeyB0aGlzLm5hbWUgPSBuYW1lOyB9Ci0KLSAgcHVibGljIENvbnN0YW50UG9vbEdlbiBnZXRDb25zdGFudFBvb2woKSAgICAgICAgICAgICAgICAgICB7IHJldHVybiBjcDsgfQotICBwdWJsaWMgdm9pZCAgICAgICAgICAgIHNldENvbnN0YW50UG9vbChDb25zdGFudFBvb2xHZW4gY3ApIHsgdGhpcy5jcCA9IGNwOyB9Ci0KLSAgLyoqCi0gICAqIEFkZCBhbiBhdHRyaWJ1dGUgdG8gdGhpcyBtZXRob2QuIEN1cnJlbnRseSwgdGhlIEpWTSBrbm93cyBhYm91dAotICAgKiB0aGUgYENvZGUnLCBgQ29uc3RhbnRWYWx1ZScsIGBTeW50aGV0aWMnIGFuZCBgRXhjZXB0aW9ucycKLSAgICogYXR0cmlidXRlcy4gT3RoZXIgYXR0cmlidXRlcyB3aWxsIGJlIGlnbm9yZWQgYnkgdGhlIEpWTSBidXQgZG8gbm8KLSAgICogaGFybS4KLSAgICoKLSAgICogQHBhcmFtIGEgYXR0cmlidXRlIHRvIGJlIGFkZGVkCi0gICAqLwotICBwdWJsaWMgdm9pZCBhZGRBdHRyaWJ1dGUoQXR0cmlidXRlIGEpIHsgYXR0cmlidXRlX3ZlYy5hZGQoYSk7IH0KLQotICAvKioKLSAgICogUmVtb3ZlIGFuIGF0dHJpYnV0ZS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHJlbW92ZUF0dHJpYnV0ZShBdHRyaWJ1dGUgYSkgeyBhdHRyaWJ1dGVfdmVjLnJlbW92ZShhKTsgfQotCi0gIC8qKgotICAgKiBSZW1vdmUgYWxsIGF0dHJpYnV0ZXMuCi0gICAqLwotICBwdWJsaWMgdm9pZCByZW1vdmVBdHRyaWJ1dGVzKCkgeyBhdHRyaWJ1dGVfdmVjLmNsZWFyKCk7IH0KLQotICAvKioKLSAgICogQHJldHVybiBhbGwgYXR0cmlidXRlcyBvZiB0aGlzIG1ldGhvZC4KLSAgICovCi0gIHB1YmxpYyBBdHRyaWJ1dGVbXSBnZXRBdHRyaWJ1dGVzKCkgewotICAgIEF0dHJpYnV0ZVtdIGF0dHJpYnV0ZXMgPSBuZXcgQXR0cmlidXRlW2F0dHJpYnV0ZV92ZWMuc2l6ZSgpXTsKLSAgICBhdHRyaWJ1dGVfdmVjLnRvQXJyYXkoYXR0cmlidXRlcyk7Ci0gICAgcmV0dXJuIGF0dHJpYnV0ZXM7Ci0gIH0KLQotICAvKiogQHJldHVybiBzaWduYXR1cmUgb2YgbWV0aG9kL2ZpZWxkLgotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IFN0cmluZyAgZ2V0U2lnbmF0dXJlKCk7Ci0KLSAgcHVibGljIE9iamVjdCBjbG9uZSgpIHsKLSAgICB0cnkgewotICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7Ci0gICAgfSBjYXRjaChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKSB7Ci0gICAgICBTeXN0ZW0uZXJyLnByaW50bG4oZSk7Ci0gICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0ZpZWxkSW5zdHJ1Y3Rpb24uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0ZpZWxkSW5zdHJ1Y3Rpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMWM5ZjZlMy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9GaWVsZEluc3RydWN0aW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMTggKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmNsYXNzZmlsZS5Db25zdGFudFBvb2w7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuY2xhc3NmaWxlLkNvbnN0YW50VXRmODsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5jbGFzc2ZpbGUuQ29uc3RhbnROYW1lQW5kVHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5jbGFzc2ZpbGUuQ29uc3RhbnRDUDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5jbGFzc2ZpbGUuKjsKLQotLyoqCi0gKiBTdXBlciBjbGFzcyBmb3IgdGhlIEdFVC9QVVR4eHggZmFtaWx5IG9mIGluc3RydWN0aW9ucy4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgYWJzdHJhY3QgY2xhc3MgRmllbGRJbnN0cnVjdGlvbiBleHRlbmRzIEZpZWxkT3JNZXRob2QKLSAgaW1wbGVtZW50cyBUeXBlZEluc3RydWN0aW9uIHsKLSAgLyoqCi0gICAqIEVtcHR5IGNvbnN0cnVjdG9yIG5lZWRlZCBmb3IgdGhlIENsYXNzLm5ld0luc3RhbmNlKCkgc3RhdGVtZW50IGluCi0gICAqIEluc3RydWN0aW9uLnJlYWRJbnN0cnVjdGlvbigpLiBOb3QgdG8gYmUgdXNlZCBvdGhlcndpc2UuCi0gICAqLwotICBGaWVsZEluc3RydWN0aW9uKCkge30KLQotICAvKioKLSAgICogQHBhcmFtIGluZGV4IHRvIGNvbnN0YW50IHBvb2wKLSAgICovCi0gIHByb3RlY3RlZCBGaWVsZEluc3RydWN0aW9uKHNob3J0IG9wY29kZSwgaW50IGluZGV4KSB7Ci0gICAgc3VwZXIob3Bjb2RlLCBpbmRleCk7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBtbmVtb25pYyBmb3IgaW5zdHJ1Y3Rpb24gd2l0aCBzeW1ib2xpYyByZWZlcmVuY2VzIHJlc29sdmVkCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKENvbnN0YW50UG9vbCBjcCkgewotICAgIHJldHVybiBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuT1BDT0RFX05BTUVTW29wY29kZV0gKyAiICIgKwotICAgICAgY3AuY29uc3RhbnRUb1N0cmluZyhpbmRleCwgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkNPTlNUQU5UX0ZpZWxkcmVmKTsKLSAgfQotCi0gIC8qKiBAcmV0dXJuIHNpemUgb2YgZmllbGQgKDEgb3IgMikKLSAgICovCi0gIHByb3RlY3RlZCBpbnQgZ2V0RmllbGRTaXplKENvbnN0YW50UG9vbEdlbiBjcGcpIHsKLSAgICByZXR1cm4gZ2V0VHlwZShjcGcpLmdldFNpemUoKTsKLSAgfQotCi0gIC8qKiBAcmV0dXJuIHJldHVybiB0eXBlIG9mIHJlZmVyZW5jZWQgZmllbGQKLSAgICovCi0gIHB1YmxpYyBUeXBlIGdldFR5cGUoQ29uc3RhbnRQb29sR2VuIGNwZykgewotICAgIHJldHVybiBnZXRGaWVsZFR5cGUoY3BnKTsKLSAgfQotCi0gIC8qKiBAcmV0dXJuIHR5cGUgb2YgZmllbGQKLSAgICovCi0gIHB1YmxpYyBUeXBlIGdldEZpZWxkVHlwZShDb25zdGFudFBvb2xHZW4gY3BnKSB7Ci0gICAgcmV0dXJuIFR5cGUuZ2V0VHlwZShnZXRTaWduYXR1cmUoY3BnKSk7Ci0gIH0KLQotICAvKiogQHJldHVybiBuYW1lIG9mIHJlZmVyZW5jZWQgZmllbGQuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldEZpZWxkTmFtZShDb25zdGFudFBvb2xHZW4gY3BnKSB7Ci0gICAgcmV0dXJuIGdldE5hbWUoY3BnKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvRmllbGRPYnNlcnZlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvRmllbGRPYnNlcnZlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlNGQ3YmE1Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0ZpZWxkT2JzZXJ2ZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDY5ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8qKgotICogSW1ucGxlbWVudCB0aGlzIGludGVyZmFjZSBpZiB5b3UncmUgaW50ZXJlc3RlZCBpbiBjaGFuZ2VzIHRvIGEgRmllbGRHZW4gb2JqZWN0Ci0gKiBhbmQgcmVnaXN0ZXIgeW91cnNlbGYgd2l0aCBhZGRPYnNlcnZlcigpLgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgRmllbGRPYnNlcnZlciB7Ci0gIHB1YmxpYyB2b2lkIG5vdGlmeShGaWVsZEdlbiBmaWVsZCk7Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9GaWVsZE9yTWV0aG9kLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9GaWVsZE9yTWV0aG9kLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGFjNGU4M2IuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvRmllbGRPck1ldGhvZC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTIwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuY2xhc3NmaWxlLio7Ci0KLS8qKgotICogU3VwZXIgY2xhc3MgZm9yIEludm9rZUluc3RydWN0aW9uIGFuZCBGaWVsZEluc3RydWN0aW9uLCBzaW5jZSB0aGV5IGhhdmUKLSAqIHNvbWUgbWV0aG9kcyBpbiBjb21tb24hCi0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGFic3RyYWN0IGNsYXNzIEZpZWxkT3JNZXRob2QgZXh0ZW5kcyBDUEluc3RydWN0aW9uIGltcGxlbWVudHMgTG9hZENsYXNzIHsKLSAgLyoqCi0gICAqIEVtcHR5IGNvbnN0cnVjdG9yIG5lZWRlZCBmb3IgdGhlIENsYXNzLm5ld0luc3RhbmNlKCkgc3RhdGVtZW50IGluCi0gICAqIEluc3RydWN0aW9uLnJlYWRJbnN0cnVjdGlvbigpLiBOb3QgdG8gYmUgdXNlZCBvdGhlcndpc2UuCi0gICAqLwotICBGaWVsZE9yTWV0aG9kKCkge30KLQotICAvKioKLSAgICogQHBhcmFtIGluZGV4IHRvIGNvbnN0YW50IHBvb2wKLSAgICovCi0gIHByb3RlY3RlZCBGaWVsZE9yTWV0aG9kKHNob3J0IG9wY29kZSwgaW50IGluZGV4KSB7Ci0gICAgc3VwZXIob3Bjb2RlLCBpbmRleCk7Ci0gIH0KLQotICAvKiogQHJldHVybiBzaWduYXR1cmUgb2YgcmVmZXJlbmNlZCBtZXRob2QvZmllbGQuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFNpZ25hdHVyZShDb25zdGFudFBvb2xHZW4gY3BnKSB7Ci0gICAgQ29uc3RhbnRQb29sICAgICAgICBjcCAgID0gY3BnLmdldENvbnN0YW50UG9vbCgpOwotICAgIENvbnN0YW50Q1AgICAgICAgICAgY21yICA9IChDb25zdGFudENQKWNwLmdldENvbnN0YW50KGluZGV4KTsKLSAgICBDb25zdGFudE5hbWVBbmRUeXBlIGNuYXQgPSAoQ29uc3RhbnROYW1lQW5kVHlwZSljcC5nZXRDb25zdGFudChjbXIuZ2V0TmFtZUFuZFR5cGVJbmRleCgpKTsKLQotICAgIHJldHVybiAoKENvbnN0YW50VXRmOCljcC5nZXRDb25zdGFudChjbmF0LmdldFNpZ25hdHVyZUluZGV4KCkpKS5nZXRCeXRlcygpOwotICB9Ci0KLSAgLyoqIEByZXR1cm4gbmFtZSBvZiByZWZlcmVuY2VkIG1ldGhvZC9maWVsZC4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZShDb25zdGFudFBvb2xHZW4gY3BnKSB7Ci0gICAgQ29uc3RhbnRQb29sICAgICAgICBjcCAgID0gY3BnLmdldENvbnN0YW50UG9vbCgpOwotICAgIENvbnN0YW50Q1AgICAgICAgICAgY21yICA9IChDb25zdGFudENQKWNwLmdldENvbnN0YW50KGluZGV4KTsKLSAgICBDb25zdGFudE5hbWVBbmRUeXBlIGNuYXQgPSAoQ29uc3RhbnROYW1lQW5kVHlwZSljcC5nZXRDb25zdGFudChjbXIuZ2V0TmFtZUFuZFR5cGVJbmRleCgpKTsKLSAgICByZXR1cm4gKChDb25zdGFudFV0ZjgpY3AuZ2V0Q29uc3RhbnQoY25hdC5nZXROYW1lSW5kZXgoKSkpLmdldEJ5dGVzKCk7Ci0gIH0KLQotICAvKiogQHJldHVybiBuYW1lIG9mIHRoZSByZWZlcmVuY2VkIGNsYXNzL2ludGVyZmFjZQotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRDbGFzc05hbWUoQ29uc3RhbnRQb29sR2VuIGNwZykgewotICAgIENvbnN0YW50UG9vbCBjcCAgPSBjcGcuZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgQ29uc3RhbnRDUCAgIGNtciA9IChDb25zdGFudENQKWNwLmdldENvbnN0YW50KGluZGV4KTsKLSAgICByZXR1cm4gY3AuZ2V0Q29uc3RhbnRTdHJpbmcoY21yLmdldENsYXNzSW5kZXgoKSwgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkNPTlNUQU5UX0NsYXNzKS5yZXBsYWNlKCcvJywgJy4nKTsKLSAgfQotCi0gIC8qKiBAcmV0dXJuIHR5cGUgb2YgdGhlIHJlZmVyZW5jZWQgY2xhc3MvaW50ZXJmYWNlCi0gICAqLwotICBwdWJsaWMgT2JqZWN0VHlwZSBnZXRDbGFzc1R5cGUoQ29uc3RhbnRQb29sR2VuIGNwZykgewotICAgIHJldHVybiBuZXcgT2JqZWN0VHlwZShnZXRDbGFzc05hbWUoY3BnKSk7Ci0gIH0KLQotICAvKiogQHJldHVybiB0eXBlIG9mIHRoZSByZWZlcmVuY2VkIGNsYXNzL2ludGVyZmFjZQotICAgKi8KLSAgcHVibGljIE9iamVjdFR5cGUgZ2V0TG9hZENsYXNzVHlwZShDb25zdGFudFBvb2xHZW4gY3BnKSB7Ci0gICAgcmV0dXJuIGdldENsYXNzVHlwZShjcGcpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9HRVRGSUVMRC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvR0VURklFTEQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMTM5ZjEzOS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9HRVRGSUVMRC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTIwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuRXhjZXB0aW9uQ29uc3RhbnRzOwotCi0vKioKLSAqIEdFVEZJRUxEIC0gRmV0Y2ggZmllbGQgZnJvbSBvYmplY3QKLSAqIDxQUkU+U3RhY2s6IC4uLiwgb2JqZWN0cmVmIC0mZ3Q7IC4uLiwgdmFsdWU8L1BSRT4KLSAqIE9SCi0gKiA8UFJFPlN0YWNrOiAuLi4sIG9iamVjdHJlZiAtJmd0OyAuLi4sIHZhbHVlLndvcmQxLCB2YWx1ZS53b3JkMjwvUFJFPgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBHRVRGSUVMRCBleHRlbmRzIEZpZWxkSW5zdHJ1Y3Rpb24KLSAgaW1wbGVtZW50cyBFeGNlcHRpb25UaHJvd2VyLCBTdGFja0NvbnN1bWVyLCBTdGFja1Byb2R1Y2VyIHsKLSAgLyoqCi0gICAqIEVtcHR5IGNvbnN0cnVjdG9yIG5lZWRlZCBmb3IgdGhlIENsYXNzLm5ld0luc3RhbmNlKCkgc3RhdGVtZW50IGluCi0gICAqIEluc3RydWN0aW9uLnJlYWRJbnN0cnVjdGlvbigpLiBOb3QgdG8gYmUgdXNlZCBvdGhlcndpc2UuCi0gICAqLwotICBHRVRGSUVMRCgpIHt9Ci0KLSAgcHVibGljIEdFVEZJRUxEKGludCBpbmRleCkgewotICAgIHN1cGVyKENvbnN0YW50cy5HRVRGSUVMRCwgaW5kZXgpOwotICB9Ci0KLSAgcHVibGljIGludCBwcm9kdWNlU3RhY2soQ29uc3RhbnRQb29sR2VuIGNwZykgeyByZXR1cm4gZ2V0RmllbGRTaXplKGNwZyk7IH0KLQotICBwdWJsaWMgQ2xhc3NbXSBnZXRFeGNlcHRpb25zKCkgewotICAgIENsYXNzW10gY3MgPSBuZXcgQ2xhc3NbMiArIEV4Y2VwdGlvbkNvbnN0YW50cy5FWENTX0ZJRUxEX0FORF9NRVRIT0RfUkVTT0xVVElPTi5sZW5ndGhdOwotCi0gICAgU3lzdGVtLmFycmF5Y29weShFeGNlcHRpb25Db25zdGFudHMuRVhDU19GSUVMRF9BTkRfTUVUSE9EX1JFU09MVVRJT04sIDAsCi0gICAgICAgICAgICAgICAgICAgICBjcywgMCwgRXhjZXB0aW9uQ29uc3RhbnRzLkVYQ1NfRklFTERfQU5EX01FVEhPRF9SRVNPTFVUSU9OLmxlbmd0aCk7Ci0KLSAgICBjc1tFeGNlcHRpb25Db25zdGFudHMuRVhDU19GSUVMRF9BTkRfTUVUSE9EX1JFU09MVVRJT04ubGVuZ3RoKzFdID0KLSAgICAgIEV4Y2VwdGlvbkNvbnN0YW50cy5JTkNPTVBBVElCTEVfQ0xBU1NfQ0hBTkdFX0VSUk9SOwotICAgIGNzW0V4Y2VwdGlvbkNvbnN0YW50cy5FWENTX0ZJRUxEX0FORF9NRVRIT0RfUkVTT0xVVElPTi5sZW5ndGhdID0KLSAgICAgIEV4Y2VwdGlvbkNvbnN0YW50cy5OVUxMX1BPSU5URVJfRVhDRVBUSU9OOwotCi0gICAgcmV0dXJuIGNzOwotICB9Ci0KLQotICAvKioKLSAgICogQ2FsbCBjb3JyZXNwb25kaW5nIHZpc2l0b3IgbWV0aG9kKHMpLiBUaGUgb3JkZXIgaXM6Ci0gICAqIENhbGwgdmlzaXRvciBtZXRob2RzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMgZmlyc3QsIHRoZW4KLSAgICogY2FsbCBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY2xhc3MgaGllcmFyY2h5IGluIGRlc2NlbmRpbmcgb3JkZXIsCi0gICAqIGkuZS4sIHRoZSBtb3N0IHNwZWNpZmljIHZpc2l0WFhYKCkgY2FsbCBjb21lcyBsYXN0LgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRFeGNlcHRpb25UaHJvd2VyKHRoaXMpOwotICAgIHYudmlzaXRTdGFja0NvbnN1bWVyKHRoaXMpOwotICAgIHYudmlzaXRTdGFja1Byb2R1Y2VyKHRoaXMpOwotICAgIHYudmlzaXRUeXBlZEluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRMb2FkQ2xhc3ModGhpcyk7Ci0gICAgdi52aXNpdENQSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdEZpZWxkT3JNZXRob2QodGhpcyk7Ci0gICAgdi52aXNpdEZpZWxkSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdEdFVEZJRUxEKHRoaXMpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9HRVRTVEFUSUMuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0dFVFNUQVRJQy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxOTY4Y2UzLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0dFVFNUQVRJQy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTE2ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuRXhjZXB0aW9uQ29uc3RhbnRzOwotCi0vKioKLSAqIEdFVFNUQVRJQyAtIEZldGNoIHN0YXRpYyBmaWVsZCBmcm9tIGNsYXNzCi0gKiA8UFJFPlN0YWNrOiAuLi4sIC0mZ3Q7IC4uLiwgdmFsdWU8L1BSRT4KLSAqIE9SCi0gKiA8UFJFPlN0YWNrOiAuLi4sIC0mZ3Q7IC4uLiwgdmFsdWUud29yZDEsIHZhbHVlLndvcmQyPC9QUkU+Ci0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGNsYXNzIEdFVFNUQVRJQyBleHRlbmRzIEZpZWxkSW5zdHJ1Y3Rpb24gaW1wbGVtZW50cyBQdXNoSW5zdHJ1Y3Rpb24sIEV4Y2VwdGlvblRocm93ZXIgewotICAvKioKLSAgICogRW1wdHkgY29uc3RydWN0b3IgbmVlZGVkIGZvciB0aGUgQ2xhc3MubmV3SW5zdGFuY2UoKSBzdGF0ZW1lbnQgaW4KLSAgICogSW5zdHJ1Y3Rpb24ucmVhZEluc3RydWN0aW9uKCkuIE5vdCB0byBiZSB1c2VkIG90aGVyd2lzZS4KLSAgICovCi0gIEdFVFNUQVRJQygpIHt9Ci0KLSAgcHVibGljIEdFVFNUQVRJQyhpbnQgaW5kZXgpIHsKLSAgICBzdXBlcihDb25zdGFudHMuR0VUU1RBVElDLCBpbmRleCk7Ci0gIH0KLQotICBwdWJsaWMgaW50IHByb2R1Y2VTdGFjayhDb25zdGFudFBvb2xHZW4gY3BnKSB7IHJldHVybiBnZXRGaWVsZFNpemUoY3BnKTsgfQotCi0gIHB1YmxpYyBDbGFzc1tdIGdldEV4Y2VwdGlvbnMoKSB7Ci0gICAgQ2xhc3NbXSBjcyA9IG5ldyBDbGFzc1sxICsgRXhjZXB0aW9uQ29uc3RhbnRzLkVYQ1NfRklFTERfQU5EX01FVEhPRF9SRVNPTFVUSU9OLmxlbmd0aF07Ci0KLSAgICBTeXN0ZW0uYXJyYXljb3B5KEV4Y2VwdGlvbkNvbnN0YW50cy5FWENTX0ZJRUxEX0FORF9NRVRIT0RfUkVTT0xVVElPTiwgMCwKLSAgICAgICAgICAgICAgICAgICAgIGNzLCAwLCBFeGNlcHRpb25Db25zdGFudHMuRVhDU19GSUVMRF9BTkRfTUVUSE9EX1JFU09MVVRJT04ubGVuZ3RoKTsKLSAgICBjc1tFeGNlcHRpb25Db25zdGFudHMuRVhDU19GSUVMRF9BTkRfTUVUSE9EX1JFU09MVVRJT04ubGVuZ3RoXSA9Ci0gICAgICBFeGNlcHRpb25Db25zdGFudHMuSU5DT01QQVRJQkxFX0NMQVNTX0NIQU5HRV9FUlJPUjsKLQotICAgIHJldHVybiBjczsKLSAgfQotCi0KLSAgLyoqCi0gICAqIENhbGwgY29ycmVzcG9uZGluZyB2aXNpdG9yIG1ldGhvZChzKS4gVGhlIG9yZGVyIGlzOgotICAgKiBDYWxsIHZpc2l0b3IgbWV0aG9kcyBvZiBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzIGZpcnN0LCB0aGVuCi0gICAqIGNhbGwgbWV0aG9kcyBhY2NvcmRpbmcgdG8gdGhlIGNsYXNzIGhpZXJhcmNoeSBpbiBkZXNjZW5kaW5nIG9yZGVyLAotICAgKiBpLmUuLCB0aGUgbW9zdCBzcGVjaWZpYyB2aXNpdFhYWCgpIGNhbGwgY29tZXMgbGFzdC4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0U3RhY2tQcm9kdWNlcih0aGlzKTsKLSAgICB2LnZpc2l0UHVzaEluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRFeGNlcHRpb25UaHJvd2VyKHRoaXMpOwotICAgIHYudmlzaXRUeXBlZEluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRMb2FkQ2xhc3ModGhpcyk7Ci0gICAgdi52aXNpdENQSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdEZpZWxkT3JNZXRob2QodGhpcyk7Ci0gICAgdi52aXNpdEZpZWxkSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdEdFVFNUQVRJQyh0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvR09UTy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvR09UTy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjZmRiNDIxLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0dPVE8uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEyNSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotaW1wb3J0IGphdmEuaW8uKjsKLQotLyoqCi0gKiBHT1RPIC0gQnJhbmNoIGFsd2F5cyAodG8gcmVsYXRpdmUgb2Zmc2V0LCBub3QgYWJzb2x1dGUgYWRkcmVzcykKLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgR09UTyBleHRlbmRzIEdvdG9JbnN0cnVjdGlvbiBpbXBsZW1lbnRzIFZhcmlhYmxlTGVuZ3RoSW5zdHJ1Y3Rpb24gewotICAvKioKLSAgICogRW1wdHkgY29uc3RydWN0b3IgbmVlZGVkIGZvciB0aGUgQ2xhc3MubmV3SW5zdGFuY2UoKSBzdGF0ZW1lbnQgaW4KLSAgICogSW5zdHJ1Y3Rpb24ucmVhZEluc3RydWN0aW9uKCkuIE5vdCB0byBiZSB1c2VkIG90aGVyd2lzZS4KLSAgICovCi0gIEdPVE8oKSB7fQotCi0gIHB1YmxpYyBHT1RPKEluc3RydWN0aW9uSGFuZGxlIHRhcmdldCkgewotICAgIHN1cGVyKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5HT1RPLCB0YXJnZXQpOwotICB9Ci0KLSAgLyoqCi0gICAqIER1bXAgaW5zdHJ1Y3Rpb24gYXMgYnl0ZSBjb2RlIHRvIHN0cmVhbSBvdXQuCi0gICAqIEBwYXJhbSBvdXQgT3V0cHV0IHN0cmVhbQotICAgKi8KLSAgcHVibGljIHZvaWQgZHVtcChEYXRhT3V0cHV0U3RyZWFtIG91dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLSAgICBpbmRleCA9IGdldFRhcmdldE9mZnNldCgpOwotICAgIGlmKG9wY29kZSA9PSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuR09UTykKLSAgICAgIHN1cGVyLmR1bXAob3V0KTsKLSAgICBlbHNlIHsgLy8gR09UT19XCi0gICAgICBpbmRleCA9IGdldFRhcmdldE9mZnNldCgpOwotICAgICAgb3V0LndyaXRlQnl0ZShvcGNvZGUpOwotICAgICAgb3V0LndyaXRlSW50KGluZGV4KTsKLSAgICB9Ci0gIH0KLQotICAvKiogQ2FsbGVkIGluIHBhc3MgMiBvZiBJbnN0cnVjdGlvbkxpc3Quc2V0UG9zaXRpb25zKCkgaW4gb3JkZXIgdG8gdXBkYXRlCi0gICAqIHRoZSBicmFuY2ggdGFyZ2V0LCB0aGF0IG1heSBzaGlmdCBkdWUgdG8gdmFyaWFibGUgbGVuZ3RoIGluc3RydWN0aW9ucy4KLSAgICovCi0gIHByb3RlY3RlZCBpbnQgdXBkYXRlUG9zaXRpb24oaW50IG9mZnNldCwgaW50IG1heF9vZmZzZXQpIHsKLSAgICBpbnQgaSA9IGdldFRhcmdldE9mZnNldCgpOyAvLyBEZXBlbmRpbmcgb24gb2xkIHBvc2l0aW9uIHZhbHVlCi0KLSAgICBwb3NpdGlvbiArPSBvZmZzZXQ7IC8vIFBvc2l0aW9uIG1heSBiZSBzaGlmdGVkIGJ5IHByZWNlZGluZyBleHBhbnNpb25zCi0KLSAgICBpZihNYXRoLmFicyhpKSA+PSAoMzI3NjcgLSBtYXhfb2Zmc2V0KSkgeyAvLyB0byBsYXJnZSBmb3Igc2hvcnQgKGVzdGltYXRlKQotICAgICAgb3Bjb2RlID0gY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkdPVE9fVzsKLSAgICAgIGxlbmd0aCA9IDU7Ci0gICAgICByZXR1cm4gMjsgLy8gNSAtIDMKLSAgICB9Ci0KLSAgICByZXR1cm4gMDsKLSAgfQotCi0gIC8qKgotICAgKiBDYWxsIGNvcnJlc3BvbmRpbmcgdmlzaXRvciBtZXRob2QocykuIFRoZSBvcmRlciBpczoKLSAgICogQ2FsbCB2aXNpdG9yIG1ldGhvZHMgb2YgaW1wbGVtZW50ZWQgaW50ZXJmYWNlcyBmaXJzdCwgdGhlbgotICAgKiBjYWxsIG1ldGhvZHMgYWNjb3JkaW5nIHRvIHRoZSBjbGFzcyBoaWVyYXJjaHkgaW4gZGVzY2VuZGluZyBvcmRlciwKLSAgICogaS5lLiwgdGhlIG1vc3Qgc3BlY2lmaWMgdmlzaXRYWFgoKSBjYWxsIGNvbWVzIGxhc3QuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgdi52aXNpdFZhcmlhYmxlTGVuZ3RoSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdFVuY29uZGl0aW9uYWxCcmFuY2godGhpcyk7Ci0gICAgdi52aXNpdEJyYW5jaEluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRHb3RvSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdEdPVE8odGhpcyk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0dPVE9fVy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvR09UT19XLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGI0OTQ0ODIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvR09UT19XLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMTMgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLWltcG9ydCBqYXZhLmlvLio7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwudXRpbC5CeXRlU2VxdWVuY2U7Ci0KLS8qKgotICogR09UT19XIC0gQnJhbmNoIGFsd2F5cyAodG8gcmVsYXRpdmUgb2Zmc2V0LCBub3QgYWJzb2x1dGUgYWRkcmVzcykKLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgR09UT19XIGV4dGVuZHMgR290b0luc3RydWN0aW9uIHsKLSAgLyoqCi0gICAqIEVtcHR5IGNvbnN0cnVjdG9yIG5lZWRlZCBmb3IgdGhlIENsYXNzLm5ld0luc3RhbmNlKCkgc3RhdGVtZW50IGluCi0gICAqIEluc3RydWN0aW9uLnJlYWRJbnN0cnVjdGlvbigpLiBOb3QgdG8gYmUgdXNlZCBvdGhlcndpc2UuCi0gICAqLwotICBHT1RPX1coKSB7fQotCi0gIHB1YmxpYyBHT1RPX1coSW5zdHJ1Y3Rpb25IYW5kbGUgdGFyZ2V0KSB7Ci0gICAgc3VwZXIoY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkdPVE9fVywgdGFyZ2V0KTsKLSAgICBsZW5ndGggPSA1OwotICB9Ci0KLSAgLyoqCi0gICAqIER1bXAgaW5zdHJ1Y3Rpb24gYXMgYnl0ZSBjb2RlIHRvIHN0cmVhbSBvdXQuCi0gICAqIEBwYXJhbSBvdXQgT3V0cHV0IHN0cmVhbQotICAgKi8KLSAgcHVibGljIHZvaWQgZHVtcChEYXRhT3V0cHV0U3RyZWFtIG91dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLSAgICBpbmRleCA9IGdldFRhcmdldE9mZnNldCgpOwotICAgIG91dC53cml0ZUJ5dGUob3Bjb2RlKTsKLSAgICBvdXQud3JpdGVJbnQoaW5kZXgpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlYWQgbmVlZGVkIGRhdGEgKGUuZy4gaW5kZXgpIGZyb20gZmlsZS4KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIGluaXRGcm9tRmlsZShCeXRlU2VxdWVuY2UgYnl0ZXMsIGJvb2xlYW4gd2lkZSkgdGhyb3dzIElPRXhjZXB0aW9uCi0gIHsKLSAgICBpbmRleCAgPSBieXRlcy5yZWFkSW50KCk7Ci0gICAgbGVuZ3RoID0gNTsKLSAgfQotCi0gIC8qKgotICAgKiBDYWxsIGNvcnJlc3BvbmRpbmcgdmlzaXRvciBtZXRob2QocykuIFRoZSBvcmRlciBpczoKLSAgICogQ2FsbCB2aXNpdG9yIG1ldGhvZHMgb2YgaW1wbGVtZW50ZWQgaW50ZXJmYWNlcyBmaXJzdCwgdGhlbgotICAgKiBjYWxsIG1ldGhvZHMgYWNjb3JkaW5nIHRvIHRoZSBjbGFzcyBoaWVyYXJjaHkgaW4gZGVzY2VuZGluZyBvcmRlciwKLSAgICogaS5lLiwgdGhlIG1vc3Qgc3BlY2lmaWMgdmlzaXRYWFgoKSBjYWxsIGNvbWVzIGxhc3QuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgdi52aXNpdFVuY29uZGl0aW9uYWxCcmFuY2godGhpcyk7Ci0gICAgdi52aXNpdEJyYW5jaEluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRHb3RvSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdEdPVE9fVyh0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvR290b0luc3RydWN0aW9uLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9Hb3RvSW5zdHJ1Y3Rpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMmJlYWVhNS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9Hb3RvSW5zdHJ1Y3Rpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDc4ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8qKgotICogU3VwZXIgY2xhc3MgZm9yIEdPVE8KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgYWJzdHJhY3QgY2xhc3MgR290b0luc3RydWN0aW9uIGV4dGVuZHMgQnJhbmNoSW5zdHJ1Y3Rpb24KLSAgaW1wbGVtZW50cyBVbmNvbmRpdGlvbmFsQnJhbmNoCi17Ci0gIEdvdG9JbnN0cnVjdGlvbihzaG9ydCBvcGNvZGUsIEluc3RydWN0aW9uSGFuZGxlIHRhcmdldCkgewotICAgIHN1cGVyKG9wY29kZSwgdGFyZ2V0KTsKLSAgfQotCi0gIC8qKgotICAgKiBFbXB0eSBjb25zdHJ1Y3RvciBuZWVkZWQgZm9yIHRoZSBDbGFzcy5uZXdJbnN0YW5jZSgpIHN0YXRlbWVudCBpbgotICAgKiBJbnN0cnVjdGlvbi5yZWFkSW5zdHJ1Y3Rpb24oKS4gTm90IHRvIGJlIHVzZWQgb3RoZXJ3aXNlLgotICAgKi8KLSAgR290b0luc3RydWN0aW9uKCl7fQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSTJCLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JMkIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYzkzM2NmNC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JMkIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDkwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8qKgotICogSTJCIC0gQ29udmVydCBpbnQgdG8gYnl0ZQotICogPFBSRT5TdGFjazogLi4uLCB2YWx1ZSAtJmd0OyAuLi4sIHJlc3VsdDwvUFJFPgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBJMkIgZXh0ZW5kcyBDb252ZXJzaW9uSW5zdHJ1Y3Rpb24gewotICAvKiogQ29udmVydCBpbnQgdG8gYnl0ZQotICAgKi8KLSAgcHVibGljIEkyQigpIHsKLSAgICBzdXBlcihjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuSTJCKTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIENhbGwgY29ycmVzcG9uZGluZyB2aXNpdG9yIG1ldGhvZChzKS4gVGhlIG9yZGVyIGlzOgotICAgKiBDYWxsIHZpc2l0b3IgbWV0aG9kcyBvZiBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzIGZpcnN0LCB0aGVuCi0gICAqIGNhbGwgbWV0aG9kcyBhY2NvcmRpbmcgdG8gdGhlIGNsYXNzIGhpZXJhcmNoeSBpbiBkZXNjZW5kaW5nIG9yZGVyLAotICAgKiBpLmUuLCB0aGUgbW9zdCBzcGVjaWZpYyB2aXNpdFhYWCgpIGNhbGwgY29tZXMgbGFzdC4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0VHlwZWRJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tQcm9kdWNlcih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tDb25zdW1lcih0aGlzKTsKLSAgICB2LnZpc2l0Q29udmVyc2lvbkluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRJMkIodGhpcyk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0kyQy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSTJDLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDdkYTQzZTQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSTJDLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5MCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIEkyQyAtIENvbnZlcnQgaW50IHRvIGNoYXIKLSAqIDxQUkU+U3RhY2s6IC4uLiwgdmFsdWUgLSZndDsgLi4uLCByZXN1bHQ8L1BSRT4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgSTJDIGV4dGVuZHMgQ29udmVyc2lvbkluc3RydWN0aW9uIHsKLSAgLyoqIENvbnZlcnQgaW50IHRvIGNoYXIKLSAgICovCi0gIHB1YmxpYyBJMkMoKSB7Ci0gICAgc3VwZXIoY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkkyQyk7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBDYWxsIGNvcnJlc3BvbmRpbmcgdmlzaXRvciBtZXRob2QocykuIFRoZSBvcmRlciBpczoKLSAgICogQ2FsbCB2aXNpdG9yIG1ldGhvZHMgb2YgaW1wbGVtZW50ZWQgaW50ZXJmYWNlcyBmaXJzdCwgdGhlbgotICAgKiBjYWxsIG1ldGhvZHMgYWNjb3JkaW5nIHRvIHRoZSBjbGFzcyBoaWVyYXJjaHkgaW4gZGVzY2VuZGluZyBvcmRlciwKLSAgICogaS5lLiwgdGhlIG1vc3Qgc3BlY2lmaWMgdmlzaXRYWFgoKSBjYWxsIGNvbWVzIGxhc3QuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgdi52aXNpdFR5cGVkSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdFN0YWNrUHJvZHVjZXIodGhpcyk7Ci0gICAgdi52aXNpdFN0YWNrQ29uc3VtZXIodGhpcyk7Ci0gICAgdi52aXNpdENvbnZlcnNpb25JbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0STJDKHRoaXMpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JMkQuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0kyRC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhNzU5MDdhLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0kyRC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTAgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotLyoqCi0gKiBJMkQgLSBDb252ZXJ0IGludCB0byBkb3VibGUKLSAqIDxQUkU+U3RhY2s6IC4uLiwgdmFsdWUgLSZndDsgLi4uLCByZXN1bHQud29yZDEsIHJlc3VsdC53b3JkMjwvUFJFPgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBJMkQgZXh0ZW5kcyBDb252ZXJzaW9uSW5zdHJ1Y3Rpb24gewotICAvKiogQ29udmVydCBpbnQgdG8gZG91YmxlCi0gICAqLwotICBwdWJsaWMgSTJEKCkgewotICAgIHN1cGVyKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5JMkQpOwotICB9Ci0KLQotICAvKioKLSAgICogQ2FsbCBjb3JyZXNwb25kaW5nIHZpc2l0b3IgbWV0aG9kKHMpLiBUaGUgb3JkZXIgaXM6Ci0gICAqIENhbGwgdmlzaXRvciBtZXRob2RzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMgZmlyc3QsIHRoZW4KLSAgICogY2FsbCBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY2xhc3MgaGllcmFyY2h5IGluIGRlc2NlbmRpbmcgb3JkZXIsCi0gICAqIGkuZS4sIHRoZSBtb3N0IHNwZWNpZmljIHZpc2l0WFhYKCkgY2FsbCBjb21lcyBsYXN0LgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRUeXBlZEluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRTdGFja1Byb2R1Y2VyKHRoaXMpOwotICAgIHYudmlzaXRTdGFja0NvbnN1bWVyKHRoaXMpOwotICAgIHYudmlzaXRDb252ZXJzaW9uSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdEkyRCh0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSTJGLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JMkYuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggN2VjN2JlZi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JMkYuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDkwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8qKgotICogSTJGIC0gQ29udmVydCBpbnQgdG8gZmxvYXQKLSAqIDxQUkU+U3RhY2s6IC4uLiwgdmFsdWUgLSZndDsgLi4uLCByZXN1bHQ8L1BSRT4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgSTJGIGV4dGVuZHMgQ29udmVyc2lvbkluc3RydWN0aW9uIHsKLSAgLyoqIENvbnZlcnQgaW50IHRvIGZsb2F0Ci0gICAqLwotICBwdWJsaWMgSTJGKCkgewotICAgIHN1cGVyKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5JMkYpOwotICB9Ci0KLQotICAvKioKLSAgICogQ2FsbCBjb3JyZXNwb25kaW5nIHZpc2l0b3IgbWV0aG9kKHMpLiBUaGUgb3JkZXIgaXM6Ci0gICAqIENhbGwgdmlzaXRvciBtZXRob2RzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMgZmlyc3QsIHRoZW4KLSAgICogY2FsbCBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY2xhc3MgaGllcmFyY2h5IGluIGRlc2NlbmRpbmcgb3JkZXIsCi0gICAqIGkuZS4sIHRoZSBtb3N0IHNwZWNpZmljIHZpc2l0WFhYKCkgY2FsbCBjb21lcyBsYXN0LgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRUeXBlZEluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRTdGFja1Byb2R1Y2VyKHRoaXMpOwotICAgIHYudmlzaXRTdGFja0NvbnN1bWVyKHRoaXMpOwotICAgIHYudmlzaXRDb252ZXJzaW9uSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdEkyRih0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSTJMLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JMkwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNDY2MzU4OC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JMkwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDkwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8qKgotICogSTJMIC0gQ29udmVydCBpbnQgdG8gbG9uZwotICogPFBSRT5TdGFjazogLi4uLCB2YWx1ZSAtJmd0OyAuLi4sIHJlc3VsdC53b3JkMSwgcmVzdWx0LndvcmQyPC9QUkU+Ci0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGNsYXNzIEkyTCBleHRlbmRzIENvbnZlcnNpb25JbnN0cnVjdGlvbiB7Ci0gIC8qKiBDb252ZXJ0IGludCB0byBsb25nCi0gICAqLwotICBwdWJsaWMgSTJMKCkgewotICAgIHN1cGVyKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5JMkwpOwotICB9Ci0KLQotICAvKioKLSAgICogQ2FsbCBjb3JyZXNwb25kaW5nIHZpc2l0b3IgbWV0aG9kKHMpLiBUaGUgb3JkZXIgaXM6Ci0gICAqIENhbGwgdmlzaXRvciBtZXRob2RzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMgZmlyc3QsIHRoZW4KLSAgICogY2FsbCBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY2xhc3MgaGllcmFyY2h5IGluIGRlc2NlbmRpbmcgb3JkZXIsCi0gICAqIGkuZS4sIHRoZSBtb3N0IHNwZWNpZmljIHZpc2l0WFhYKCkgY2FsbCBjb21lcyBsYXN0LgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRUeXBlZEluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRTdGFja1Byb2R1Y2VyKHRoaXMpOwotICAgIHYudmlzaXRTdGFja0NvbnN1bWVyKHRoaXMpOwotICAgIHYudmlzaXRDb252ZXJzaW9uSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdEkyTCh0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSTJTLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JMlMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNTJhNzFhNi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JMlMuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDg4ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8qKgotICogSTJTIC0gQ29udmVydCBpbnQgdG8gc2hvcnQKLSAqIDxQUkU+U3RhY2s6IC4uLiwgdmFsdWUgLSZndDsgLi4uLCByZXN1bHQ8L1BSRT4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgSTJTIGV4dGVuZHMgQ29udmVyc2lvbkluc3RydWN0aW9uIHsKLSAgcHVibGljIEkyUygpIHsKLSAgICBzdXBlcihjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuSTJTKTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIENhbGwgY29ycmVzcG9uZGluZyB2aXNpdG9yIG1ldGhvZChzKS4gVGhlIG9yZGVyIGlzOgotICAgKiBDYWxsIHZpc2l0b3IgbWV0aG9kcyBvZiBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzIGZpcnN0LCB0aGVuCi0gICAqIGNhbGwgbWV0aG9kcyBhY2NvcmRpbmcgdG8gdGhlIGNsYXNzIGhpZXJhcmNoeSBpbiBkZXNjZW5kaW5nIG9yZGVyLAotICAgKiBpLmUuLCB0aGUgbW9zdCBzcGVjaWZpYyB2aXNpdFhYWCgpIGNhbGwgY29tZXMgbGFzdC4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0VHlwZWRJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tQcm9kdWNlcih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tDb25zdW1lcih0aGlzKTsKLSAgICB2LnZpc2l0Q29udmVyc2lvbkluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRJMlModGhpcyk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0lBREQuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0lBREQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYWM4MDRlNS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JQURELmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5MCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIElBREQgLSBBZGQgaW50cwotICogPFBSRT5TdGFjazogLi4uLCB2YWx1ZTEsIHZhbHVlMiAtJmd0OyByZXN1bHQ8L1BSRT4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgSUFERCBleHRlbmRzIEFyaXRobWV0aWNJbnN0cnVjdGlvbiB7Ci0gIC8qKiBBZGQgaW50cwotICAgKi8KLSAgcHVibGljIElBREQoKSB7Ci0gICAgc3VwZXIoY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLklBREQpOwotICB9Ci0KLQotICAvKioKLSAgICogQ2FsbCBjb3JyZXNwb25kaW5nIHZpc2l0b3IgbWV0aG9kKHMpLiBUaGUgb3JkZXIgaXM6Ci0gICAqIENhbGwgdmlzaXRvciBtZXRob2RzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMgZmlyc3QsIHRoZW4KLSAgICogY2FsbCBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY2xhc3MgaGllcmFyY2h5IGluIGRlc2NlbmRpbmcgb3JkZXIsCi0gICAqIGkuZS4sIHRoZSBtb3N0IHNwZWNpZmljIHZpc2l0WFhYKCkgY2FsbCBjb21lcyBsYXN0LgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRUeXBlZEluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRTdGFja1Byb2R1Y2VyKHRoaXMpOwotICAgIHYudmlzaXRTdGFja0NvbnN1bWVyKHRoaXMpOwotICAgIHYudmlzaXRBcml0aG1ldGljSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdElBREQodGhpcyk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0lBTE9BRC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSUFMT0FELmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDBlOTk5MzQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSUFMT0FELmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5MSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIElBTE9BRCAtIExvYWQgaW50IGZyb20gYXJyYXkKLSAqIDxQUkU+U3RhY2s6IC4uLiwgYXJyYXlyZWYsIGluZGV4IC0mZ3Q7IC4uLiwgdmFsdWU8L1BSRT4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgSUFMT0FEIGV4dGVuZHMgQXJyYXlJbnN0cnVjdGlvbiBpbXBsZW1lbnRzIFN0YWNrUHJvZHVjZXIgewotICAvKioKLSAgICogTG9hZCBpbnQgZnJvbSBhcnJheQotICAgKi8KLSAgcHVibGljIElBTE9BRCgpIHsKLSAgICBzdXBlcihjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuSUFMT0FEKTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIENhbGwgY29ycmVzcG9uZGluZyB2aXNpdG9yIG1ldGhvZChzKS4gVGhlIG9yZGVyIGlzOgotICAgKiBDYWxsIHZpc2l0b3IgbWV0aG9kcyBvZiBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzIGZpcnN0LCB0aGVuCi0gICAqIGNhbGwgbWV0aG9kcyBhY2NvcmRpbmcgdG8gdGhlIGNsYXNzIGhpZXJhcmNoeSBpbiBkZXNjZW5kaW5nIG9yZGVyLAotICAgKiBpLmUuLCB0aGUgbW9zdCBzcGVjaWZpYyB2aXNpdFhYWCgpIGNhbGwgY29tZXMgbGFzdC4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0U3RhY2tQcm9kdWNlcih0aGlzKTsKLSAgICB2LnZpc2l0RXhjZXB0aW9uVGhyb3dlcih0aGlzKTsKLSAgICB2LnZpc2l0VHlwZWRJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0QXJyYXlJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0SUFMT0FEKHRoaXMpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JQU5ELmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JQU5ELmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDY5ODI2ODUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSUFORC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsODggKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotLyoqCi0gKiBJQU5EIC0gQml0d2lzZSBBTkQgaW50Ci0gKiA8UFJFPlN0YWNrOiAuLi4sIHZhbHVlMSwgdmFsdWUyIC0mZ3Q7IC4uLiwgcmVzdWx0PC9QUkU+Ci0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGNsYXNzIElBTkQgZXh0ZW5kcyBBcml0aG1ldGljSW5zdHJ1Y3Rpb24gewotICBwdWJsaWMgSUFORCgpIHsKLSAgICBzdXBlcihjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuSUFORCk7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBDYWxsIGNvcnJlc3BvbmRpbmcgdmlzaXRvciBtZXRob2QocykuIFRoZSBvcmRlciBpczoKLSAgICogQ2FsbCB2aXNpdG9yIG1ldGhvZHMgb2YgaW1wbGVtZW50ZWQgaW50ZXJmYWNlcyBmaXJzdCwgdGhlbgotICAgKiBjYWxsIG1ldGhvZHMgYWNjb3JkaW5nIHRvIHRoZSBjbGFzcyBoaWVyYXJjaHkgaW4gZGVzY2VuZGluZyBvcmRlciwKLSAgICogaS5lLiwgdGhlIG1vc3Qgc3BlY2lmaWMgdmlzaXRYWFgoKSBjYWxsIGNvbWVzIGxhc3QuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgdi52aXNpdFR5cGVkSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdFN0YWNrUHJvZHVjZXIodGhpcyk7Ci0gICAgdi52aXNpdFN0YWNrQ29uc3VtZXIodGhpcyk7Ci0gICAgdi52aXNpdEFyaXRobWV0aWNJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0SUFORCh0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSUFTVE9SRS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSUFTVE9SRS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjZjEyNzdmLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0lBU1RPUkUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDkxICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8qKgotICogSUFTVE9SRSAtICBTdG9yZSBpbnRvIGludCBhcnJheQotICogPFBSRT5TdGFjazogLi4uLCBhcnJheXJlZiwgaW5kZXgsIHZhbHVlIC0mZ3Q7IC4uLjwvUFJFPgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBJQVNUT1JFIGV4dGVuZHMgQXJyYXlJbnN0cnVjdGlvbiBpbXBsZW1lbnRzIFN0YWNrQ29uc3VtZXIgewotICAvKioKLSAgICogU3RvcmUgaW50byBpbnQgYXJyYXkKLSAgICovCi0gIHB1YmxpYyBJQVNUT1JFKCkgewotICAgIHN1cGVyKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5JQVNUT1JFKTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIENhbGwgY29ycmVzcG9uZGluZyB2aXNpdG9yIG1ldGhvZChzKS4gVGhlIG9yZGVyIGlzOgotICAgKiBDYWxsIHZpc2l0b3IgbWV0aG9kcyBvZiBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzIGZpcnN0LCB0aGVuCi0gICAqIGNhbGwgbWV0aG9kcyBhY2NvcmRpbmcgdG8gdGhlIGNsYXNzIGhpZXJhcmNoeSBpbiBkZXNjZW5kaW5nIG9yZGVyLAotICAgKiBpLmUuLCB0aGUgbW9zdCBzcGVjaWZpYyB2aXNpdFhYWCgpIGNhbGwgY29tZXMgbGFzdC4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0U3RhY2tDb25zdW1lcih0aGlzKTsKLSAgICB2LnZpc2l0RXhjZXB0aW9uVGhyb3dlcih0aGlzKTsKLSAgICB2LnZpc2l0VHlwZWRJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0QXJyYXlJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0SUFTVE9SRSh0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSUNPTlNULmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JQ09OU1QuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNTJkMWVlYy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JQ09OU1QuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExMiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIElDT05TVCAtIFB1c2ggdmFsdWUgYmV0d2VlbiAtMSwgLi4uLCA1LCBvdGhlciB2YWx1ZXMgY2F1c2UgYW4gZXhjZXB0aW9uCi0gKgotICogPFBSRT5TdGFjazogLi4uIC0mZ3Q7IC4uLiwgPC9QUkU+Ci0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGNsYXNzIElDT05TVCBleHRlbmRzIEluc3RydWN0aW9uCi0gIGltcGxlbWVudHMgQ29uc3RhbnRQdXNoSW5zdHJ1Y3Rpb24sIFR5cGVkSW5zdHJ1Y3Rpb24gewotICBwcml2YXRlIGludCB2YWx1ZTsKLQotICAvKioKLSAgICogRW1wdHkgY29uc3RydWN0b3IgbmVlZGVkIGZvciB0aGUgQ2xhc3MubmV3SW5zdGFuY2UoKSBzdGF0ZW1lbnQgaW4KLSAgICogSW5zdHJ1Y3Rpb24ucmVhZEluc3RydWN0aW9uKCkuIE5vdCB0byBiZSB1c2VkIG90aGVyd2lzZS4KLSAgICovCi0gIElDT05TVCgpIHt9Ci0KLSAgcHVibGljIElDT05TVChpbnQgaSkgewotICAgIHN1cGVyKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5JQ09OU1RfMCwgKHNob3J0KTEpOwotCi0gICAgaWYoKGkgPj0gLTEpICYmIChpIDw9IDUpKQotICAgICAgb3Bjb2RlID0gKHNob3J0KShjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuSUNPTlNUXzAgKyBpKTsgLy8gRXZlbiB3b3JrcyBmb3IgaSA9PSAtMQotICAgIGVsc2UKLSAgICAgIHRocm93IG5ldyBDbGFzc0dlbkV4Y2VwdGlvbigiSUNPTlNUIGNhbiBiZSB1c2VkIG9ubHkgZm9yIHZhbHVlIGJldHdlZW4gLTEgYW5kIDU6ICIgKwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkpOwotICAgIHZhbHVlID0gaTsKLSAgfQotCi0gIHB1YmxpYyBOdW1iZXIgZ2V0VmFsdWUoKSB7IHJldHVybiBuZXcgSW50ZWdlcih2YWx1ZSk7IH0KLQotICAvKiogQHJldHVybiBUeXBlLklOVAotICAgKi8KLSAgcHVibGljIFR5cGUgZ2V0VHlwZShDb25zdGFudFBvb2xHZW4gY3ApIHsKLSAgICByZXR1cm4gVHlwZS5JTlQ7Ci0gIH0KLQotICAvKioKLSAgICogQ2FsbCBjb3JyZXNwb25kaW5nIHZpc2l0b3IgbWV0aG9kKHMpLiBUaGUgb3JkZXIgaXM6Ci0gICAqIENhbGwgdmlzaXRvciBtZXRob2RzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMgZmlyc3QsIHRoZW4KLSAgICogY2FsbCBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY2xhc3MgaGllcmFyY2h5IGluIGRlc2NlbmRpbmcgb3JkZXIsCi0gICAqIGkuZS4sIHRoZSBtb3N0IHNwZWNpZmljIHZpc2l0WFhYKCkgY2FsbCBjb21lcyBsYXN0LgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRQdXNoSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdFN0YWNrUHJvZHVjZXIodGhpcyk7Ci0gICAgdi52aXNpdFR5cGVkSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdENvbnN0YW50UHVzaEluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRJQ09OU1QodGhpcyk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0lESVYuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0lESVYuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZmJhMTQ5Yi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JRElWLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5NyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIElESVYgLSBEaXZpZGUgaW50cwotICogPFBSRT5TdGFjazogLi4uLCB2YWx1ZTEsIHZhbHVlMiAtJmd0OyByZXN1bHQ8L1BSRT4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgSURJViBleHRlbmRzIEFyaXRobWV0aWNJbnN0cnVjdGlvbiBpbXBsZW1lbnRzIEV4Y2VwdGlvblRocm93ZXIgewotICAvKiogRGl2aWRlIGludHMKLSAgICovCi0gIHB1YmxpYyBJRElWKCkgewotICAgIHN1cGVyKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5JRElWKTsKLSAgfQotCi0gIC8qKiBAcmV0dXJuIGV4Y2VwdGlvbnMgdGhpcyBpbnN0cnVjdGlvbiBtYXkgY2F1c2UKLSAgICovCi0gIHB1YmxpYyBDbGFzc1tdIGdldEV4Y2VwdGlvbnMoKSB7Ci0gICAgcmV0dXJuIG5ldyBDbGFzc1tdIHsgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuRXhjZXB0aW9uQ29uc3RhbnRzLkFSSVRITUVUSUNfRVhDRVBUSU9OIH07Ci0gIH0KLQotCi0gIC8qKgotICAgKiBDYWxsIGNvcnJlc3BvbmRpbmcgdmlzaXRvciBtZXRob2QocykuIFRoZSBvcmRlciBpczoKLSAgICogQ2FsbCB2aXNpdG9yIG1ldGhvZHMgb2YgaW1wbGVtZW50ZWQgaW50ZXJmYWNlcyBmaXJzdCwgdGhlbgotICAgKiBjYWxsIG1ldGhvZHMgYWNjb3JkaW5nIHRvIHRoZSBjbGFzcyBoaWVyYXJjaHkgaW4gZGVzY2VuZGluZyBvcmRlciwKLSAgICogaS5lLiwgdGhlIG1vc3Qgc3BlY2lmaWMgdmlzaXRYWFgoKSBjYWxsIGNvbWVzIGxhc3QuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgdi52aXNpdEV4Y2VwdGlvblRocm93ZXIodGhpcyk7Ci0gICAgdi52aXNpdFR5cGVkSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdFN0YWNrUHJvZHVjZXIodGhpcyk7Ci0gICAgdi52aXNpdFN0YWNrQ29uc3VtZXIodGhpcyk7Ci0gICAgdi52aXNpdEFyaXRobWV0aWNJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0SURJVih0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSUZFUS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSUZFUS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3MzQ5NmNiLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0lGRVEuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEwMSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIElGRVEgLSBCcmFuY2ggaWYgaW50IGNvbXBhcmlzb24gd2l0aCB6ZXJvIHN1Y2NlZWRzCi0gKgotICogPFBSRT5TdGFjazogLi4uLCB2YWx1ZSAtJmd0OyAuLi48L1BSRT4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgSUZFUSBleHRlbmRzIElmSW5zdHJ1Y3Rpb24gewotICAvKioKLSAgICogRW1wdHkgY29uc3RydWN0b3IgbmVlZGVkIGZvciB0aGUgQ2xhc3MubmV3SW5zdGFuY2UoKSBzdGF0ZW1lbnQgaW4KLSAgICogSW5zdHJ1Y3Rpb24ucmVhZEluc3RydWN0aW9uKCkuIE5vdCB0byBiZSB1c2VkIG90aGVyd2lzZS4KLSAgICovCi0gIElGRVEoKSB7fQotCi0gIHB1YmxpYyBJRkVRKEluc3RydWN0aW9uSGFuZGxlIHRhcmdldCkgewotICAgIHN1cGVyKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5JRkVRLCB0YXJnZXQpOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gbmVnYXRpb24gb2YgaW5zdHJ1Y3Rpb24sIGUuZy4gSUZFUS5uZWdhdGUoKSA9PSBJRk5FCi0gICAqLwotICBwdWJsaWMgSWZJbnN0cnVjdGlvbiBuZWdhdGUoKSB7Ci0gICAgcmV0dXJuIG5ldyBJRk5FKHRhcmdldCk7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBDYWxsIGNvcnJlc3BvbmRpbmcgdmlzaXRvciBtZXRob2QocykuIFRoZSBvcmRlciBpczoKLSAgICogQ2FsbCB2aXNpdG9yIG1ldGhvZHMgb2YgaW1wbGVtZW50ZWQgaW50ZXJmYWNlcyBmaXJzdCwgdGhlbgotICAgKiBjYWxsIG1ldGhvZHMgYWNjb3JkaW5nIHRvIHRoZSBjbGFzcyBoaWVyYXJjaHkgaW4gZGVzY2VuZGluZyBvcmRlciwKLSAgICogaS5lLiwgdGhlIG1vc3Qgc3BlY2lmaWMgdmlzaXRYWFgoKSBjYWxsIGNvbWVzIGxhc3QuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgdi52aXNpdFN0YWNrQ29uc3VtZXIodGhpcyk7Ci0gICAgdi52aXNpdEJyYW5jaEluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRJZkluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRJRkVRKHRoaXMpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JRkdFLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JRkdFLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDczYTE0YTQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSUZHRS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTAxICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8qKgotICogSUZHRSAtIEJyYW5jaCBpZiBpbnQgY29tcGFyaXNvbiB3aXRoIHplcm8gc3VjY2VlZHMKLSAqCi0gKiA8UFJFPlN0YWNrOiAuLi4sIHZhbHVlIC0mZ3Q7IC4uLjwvUFJFPgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBJRkdFIGV4dGVuZHMgSWZJbnN0cnVjdGlvbiB7Ci0gIC8qKgotICAgKiBFbXB0eSBjb25zdHJ1Y3RvciBuZWVkZWQgZm9yIHRoZSBDbGFzcy5uZXdJbnN0YW5jZSgpIHN0YXRlbWVudCBpbgotICAgKiBJbnN0cnVjdGlvbi5yZWFkSW5zdHJ1Y3Rpb24oKS4gTm90IHRvIGJlIHVzZWQgb3RoZXJ3aXNlLgotICAgKi8KLSAgSUZHRSgpIHt9Ci0KLSAgcHVibGljIElGR0UoSW5zdHJ1Y3Rpb25IYW5kbGUgdGFyZ2V0KSB7Ci0gICAgc3VwZXIoY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLklGR0UsIHRhcmdldCk7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBuZWdhdGlvbiBvZiBpbnN0cnVjdGlvbgotICAgKi8KLSAgcHVibGljIElmSW5zdHJ1Y3Rpb24gbmVnYXRlKCkgewotICAgIHJldHVybiBuZXcgSUZMVCh0YXJnZXQpOwotICB9Ci0KLQotICAvKioKLSAgICogQ2FsbCBjb3JyZXNwb25kaW5nIHZpc2l0b3IgbWV0aG9kKHMpLiBUaGUgb3JkZXIgaXM6Ci0gICAqIENhbGwgdmlzaXRvciBtZXRob2RzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMgZmlyc3QsIHRoZW4KLSAgICogY2FsbCBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY2xhc3MgaGllcmFyY2h5IGluIGRlc2NlbmRpbmcgb3JkZXIsCi0gICAqIGkuZS4sIHRoZSBtb3N0IHNwZWNpZmljIHZpc2l0WFhYKCkgY2FsbCBjb21lcyBsYXN0LgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRTdGFja0NvbnN1bWVyKHRoaXMpOwotICAgIHYudmlzaXRCcmFuY2hJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0SWZJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0SUZHRSh0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSUZHVC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSUZHVC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxNjc4MjZjLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0lGR1QuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEwMSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIElGR1QgLSBCcmFuY2ggaWYgaW50IGNvbXBhcmlzb24gd2l0aCB6ZXJvIHN1Y2NlZWRzCi0gKgotICogPFBSRT5TdGFjazogLi4uLCB2YWx1ZSAtJmd0OyAuLi48L1BSRT4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgSUZHVCBleHRlbmRzIElmSW5zdHJ1Y3Rpb24gewotICAvKioKLSAgICogRW1wdHkgY29uc3RydWN0b3IgbmVlZGVkIGZvciB0aGUgQ2xhc3MubmV3SW5zdGFuY2UoKSBzdGF0ZW1lbnQgaW4KLSAgICogSW5zdHJ1Y3Rpb24ucmVhZEluc3RydWN0aW9uKCkuIE5vdCB0byBiZSB1c2VkIG90aGVyd2lzZS4KLSAgICovCi0gIElGR1QoKSB7fQotCi0gIHB1YmxpYyBJRkdUKEluc3RydWN0aW9uSGFuZGxlIHRhcmdldCkgewotICAgIHN1cGVyKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5JRkdULCB0YXJnZXQpOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gbmVnYXRpb24gb2YgaW5zdHJ1Y3Rpb24KLSAgICovCi0gIHB1YmxpYyBJZkluc3RydWN0aW9uIG5lZ2F0ZSgpIHsKLSAgICByZXR1cm4gbmV3IElGTEUodGFyZ2V0KTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIENhbGwgY29ycmVzcG9uZGluZyB2aXNpdG9yIG1ldGhvZChzKS4gVGhlIG9yZGVyIGlzOgotICAgKiBDYWxsIHZpc2l0b3IgbWV0aG9kcyBvZiBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzIGZpcnN0LCB0aGVuCi0gICAqIGNhbGwgbWV0aG9kcyBhY2NvcmRpbmcgdG8gdGhlIGNsYXNzIGhpZXJhcmNoeSBpbiBkZXNjZW5kaW5nIG9yZGVyLAotICAgKiBpLmUuLCB0aGUgbW9zdCBzcGVjaWZpYyB2aXNpdFhYWCgpIGNhbGwgY29tZXMgbGFzdC4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0U3RhY2tDb25zdW1lcih0aGlzKTsKLSAgICB2LnZpc2l0QnJhbmNoSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdElmSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdElGR1QodGhpcyk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0lGTEUuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0lGTEUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggODRiN2ZhMy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JRkxFLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMDEgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotLyoqCi0gKiBJRkxFIC0gQnJhbmNoIGlmIGludCBjb21wYXJpc29uIHdpdGggemVybyBzdWNjZWVkcwotICoKLSAqIDxQUkU+U3RhY2s6IC4uLiwgdmFsdWUgLSZndDsgLi4uPC9QUkU+Ci0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGNsYXNzIElGTEUgZXh0ZW5kcyBJZkluc3RydWN0aW9uIHsKLSAgLyoqCi0gICAqIEVtcHR5IGNvbnN0cnVjdG9yIG5lZWRlZCBmb3IgdGhlIENsYXNzLm5ld0luc3RhbmNlKCkgc3RhdGVtZW50IGluCi0gICAqIEluc3RydWN0aW9uLnJlYWRJbnN0cnVjdGlvbigpLiBOb3QgdG8gYmUgdXNlZCBvdGhlcndpc2UuCi0gICAqLwotICBJRkxFKCkge30KLQotICBwdWJsaWMgSUZMRShJbnN0cnVjdGlvbkhhbmRsZSB0YXJnZXQpIHsKLSAgICBzdXBlcihjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuSUZMRSwgdGFyZ2V0KTsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIG5lZ2F0aW9uIG9mIGluc3RydWN0aW9uCi0gICAqLwotICBwdWJsaWMgSWZJbnN0cnVjdGlvbiBuZWdhdGUoKSB7Ci0gICAgcmV0dXJuIG5ldyBJRkdUKHRhcmdldCk7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBDYWxsIGNvcnJlc3BvbmRpbmcgdmlzaXRvciBtZXRob2QocykuIFRoZSBvcmRlciBpczoKLSAgICogQ2FsbCB2aXNpdG9yIG1ldGhvZHMgb2YgaW1wbGVtZW50ZWQgaW50ZXJmYWNlcyBmaXJzdCwgdGhlbgotICAgKiBjYWxsIG1ldGhvZHMgYWNjb3JkaW5nIHRvIHRoZSBjbGFzcyBoaWVyYXJjaHkgaW4gZGVzY2VuZGluZyBvcmRlciwKLSAgICogaS5lLiwgdGhlIG1vc3Qgc3BlY2lmaWMgdmlzaXRYWFgoKSBjYWxsIGNvbWVzIGxhc3QuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgdi52aXNpdFN0YWNrQ29uc3VtZXIodGhpcyk7Ci0gICAgdi52aXNpdEJyYW5jaEluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRJZkluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRJRkxFKHRoaXMpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JRkxULmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JRkxULmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDVmOTA0Y2QuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSUZMVC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTAxICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8qKgotICogSUZMVCAtIEJyYW5jaCBpZiBpbnQgY29tcGFyaXNvbiB3aXRoIHplcm8gc3VjY2VlZHMKLSAqCi0gKiA8UFJFPlN0YWNrOiAuLi4sIHZhbHVlIC0mZ3Q7IC4uLjwvUFJFPgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBJRkxUIGV4dGVuZHMgSWZJbnN0cnVjdGlvbiB7Ci0gIC8qKgotICAgKiBFbXB0eSBjb25zdHJ1Y3RvciBuZWVkZWQgZm9yIHRoZSBDbGFzcy5uZXdJbnN0YW5jZSgpIHN0YXRlbWVudCBpbgotICAgKiBJbnN0cnVjdGlvbi5yZWFkSW5zdHJ1Y3Rpb24oKS4gTm90IHRvIGJlIHVzZWQgb3RoZXJ3aXNlLgotICAgKi8KLSAgSUZMVCgpIHt9Ci0KLSAgcHVibGljIElGTFQoSW5zdHJ1Y3Rpb25IYW5kbGUgdGFyZ2V0KSB7Ci0gICAgc3VwZXIoY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLklGTFQsIHRhcmdldCk7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBuZWdhdGlvbiBvZiBpbnN0cnVjdGlvbgotICAgKi8KLSAgcHVibGljIElmSW5zdHJ1Y3Rpb24gbmVnYXRlKCkgewotICAgIHJldHVybiBuZXcgSUZHRSh0YXJnZXQpOwotICB9Ci0KLQotICAvKioKLSAgICogQ2FsbCBjb3JyZXNwb25kaW5nIHZpc2l0b3IgbWV0aG9kKHMpLiBUaGUgb3JkZXIgaXM6Ci0gICAqIENhbGwgdmlzaXRvciBtZXRob2RzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMgZmlyc3QsIHRoZW4KLSAgICogY2FsbCBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY2xhc3MgaGllcmFyY2h5IGluIGRlc2NlbmRpbmcgb3JkZXIsCi0gICAqIGkuZS4sIHRoZSBtb3N0IHNwZWNpZmljIHZpc2l0WFhYKCkgY2FsbCBjb21lcyBsYXN0LgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRTdGFja0NvbnN1bWVyKHRoaXMpOwotICAgIHYudmlzaXRCcmFuY2hJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0SWZJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0SUZMVCh0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSUZORS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSUZORS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwYmFmNGE4Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0lGTkUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEwMSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIElGTkUgLSBCcmFuY2ggaWYgaW50IGNvbXBhcmlzb24gd2l0aCB6ZXJvIHN1Y2NlZWRzCi0gKgotICogPFBSRT5TdGFjazogLi4uLCB2YWx1ZSAtJmd0OyAuLi48L1BSRT4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgSUZORSBleHRlbmRzIElmSW5zdHJ1Y3Rpb24gewotICAvKioKLSAgICogRW1wdHkgY29uc3RydWN0b3IgbmVlZGVkIGZvciB0aGUgQ2xhc3MubmV3SW5zdGFuY2UoKSBzdGF0ZW1lbnQgaW4KLSAgICogSW5zdHJ1Y3Rpb24ucmVhZEluc3RydWN0aW9uKCkuIE5vdCB0byBiZSB1c2VkIG90aGVyd2lzZS4KLSAgICovCi0gIElGTkUoKSB7fQotCi0gIHB1YmxpYyBJRk5FKEluc3RydWN0aW9uSGFuZGxlIHRhcmdldCkgewotICAgIHN1cGVyKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5JRk5FLCB0YXJnZXQpOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gbmVnYXRpb24gb2YgaW5zdHJ1Y3Rpb24KLSAgICovCi0gIHB1YmxpYyBJZkluc3RydWN0aW9uIG5lZ2F0ZSgpIHsKLSAgICByZXR1cm4gbmV3IElGRVEodGFyZ2V0KTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIENhbGwgY29ycmVzcG9uZGluZyB2aXNpdG9yIG1ldGhvZChzKS4gVGhlIG9yZGVyIGlzOgotICAgKiBDYWxsIHZpc2l0b3IgbWV0aG9kcyBvZiBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzIGZpcnN0LCB0aGVuCi0gICAqIGNhbGwgbWV0aG9kcyBhY2NvcmRpbmcgdG8gdGhlIGNsYXNzIGhpZXJhcmNoeSBpbiBkZXNjZW5kaW5nIG9yZGVyLAotICAgKiBpLmUuLCB0aGUgbW9zdCBzcGVjaWZpYyB2aXNpdFhYWCgpIGNhbGwgY29tZXMgbGFzdC4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0U3RhY2tDb25zdW1lcih0aGlzKTsKLSAgICB2LnZpc2l0QnJhbmNoSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdElmSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdElGTkUodGhpcyk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0lGTk9OTlVMTC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSUZOT05OVUxMLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDkxMzFiYjIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSUZOT05OVUxMLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMDAgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotLyoqCi0gKiBJRk5PTk5VTEwgLSBCcmFuY2ggaWYgcmVmZXJlbmNlIGlzIG5vdCBudWxsCi0gKgotICogPFBSRT5TdGFjazogLi4uLCByZWZlcmVuY2UgLSZndDsgLi4uPC9QUkU+Ci0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGNsYXNzIElGTk9OTlVMTCBleHRlbmRzIElmSW5zdHJ1Y3Rpb24gewotICAvKioKLSAgICogRW1wdHkgY29uc3RydWN0b3IgbmVlZGVkIGZvciB0aGUgQ2xhc3MubmV3SW5zdGFuY2UoKSBzdGF0ZW1lbnQgaW4KLSAgICogSW5zdHJ1Y3Rpb24ucmVhZEluc3RydWN0aW9uKCkuIE5vdCB0byBiZSB1c2VkIG90aGVyd2lzZS4KLSAgICovCi0gIElGTk9OTlVMTCgpIHt9Ci0KLSAgcHVibGljIElGTk9OTlVMTChJbnN0cnVjdGlvbkhhbmRsZSB0YXJnZXQpIHsKLSAgICBzdXBlcihjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuSUZOT05OVUxMLCB0YXJnZXQpOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gbmVnYXRpb24gb2YgaW5zdHJ1Y3Rpb24KLSAgICovCi0gIHB1YmxpYyBJZkluc3RydWN0aW9uIG5lZ2F0ZSgpIHsKLSAgICByZXR1cm4gbmV3IElGTlVMTCh0YXJnZXQpOwotICB9Ci0KLSAgLyoqCi0gICAqIENhbGwgY29ycmVzcG9uZGluZyB2aXNpdG9yIG1ldGhvZChzKS4gVGhlIG9yZGVyIGlzOgotICAgKiBDYWxsIHZpc2l0b3IgbWV0aG9kcyBvZiBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzIGZpcnN0LCB0aGVuCi0gICAqIGNhbGwgbWV0aG9kcyBhY2NvcmRpbmcgdG8gdGhlIGNsYXNzIGhpZXJhcmNoeSBpbiBkZXNjZW5kaW5nIG9yZGVyLAotICAgKiBpLmUuLCB0aGUgbW9zdCBzcGVjaWZpYyB2aXNpdFhYWCgpIGNhbGwgY29tZXMgbGFzdC4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0U3RhY2tDb25zdW1lcih0aGlzKTsKLSAgICB2LnZpc2l0QnJhbmNoSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdElmSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdElGTk9OTlVMTCh0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSUZOVUxMLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JRk5VTEwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMWE1Y2NhZi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JRk5VTEwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEwMSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIElGTlVMTCAtIEJyYW5jaCBpZiByZWZlcmVuY2UgaXMgbm90IG51bGwKLSAqCi0gKiA8UFJFPlN0YWNrOiAuLi4sIHJlZmVyZW5jZSAtJmd0OyAuLi48L1BSRT4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgSUZOVUxMIGV4dGVuZHMgSWZJbnN0cnVjdGlvbiB7Ci0gIC8qKgotICAgKiBFbXB0eSBjb25zdHJ1Y3RvciBuZWVkZWQgZm9yIHRoZSBDbGFzcy5uZXdJbnN0YW5jZSgpIHN0YXRlbWVudCBpbgotICAgKiBJbnN0cnVjdGlvbi5yZWFkSW5zdHJ1Y3Rpb24oKS4gTm90IHRvIGJlIHVzZWQgb3RoZXJ3aXNlLgotICAgKi8KLSAgSUZOVUxMKCkge30KLQotICBwdWJsaWMgSUZOVUxMKEluc3RydWN0aW9uSGFuZGxlIHRhcmdldCkgewotICAgIHN1cGVyKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5JRk5VTEwsIHRhcmdldCk7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBuZWdhdGlvbiBvZiBpbnN0cnVjdGlvbgotICAgKi8KLSAgcHVibGljIElmSW5zdHJ1Y3Rpb24gbmVnYXRlKCkgewotICAgIHJldHVybiBuZXcgSUZOT05OVUxMKHRhcmdldCk7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBDYWxsIGNvcnJlc3BvbmRpbmcgdmlzaXRvciBtZXRob2QocykuIFRoZSBvcmRlciBpczoKLSAgICogQ2FsbCB2aXNpdG9yIG1ldGhvZHMgb2YgaW1wbGVtZW50ZWQgaW50ZXJmYWNlcyBmaXJzdCwgdGhlbgotICAgKiBjYWxsIG1ldGhvZHMgYWNjb3JkaW5nIHRvIHRoZSBjbGFzcyBoaWVyYXJjaHkgaW4gZGVzY2VuZGluZyBvcmRlciwKLSAgICogaS5lLiwgdGhlIG1vc3Qgc3BlY2lmaWMgdmlzaXRYWFgoKSBjYWxsIGNvbWVzIGxhc3QuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgdi52aXNpdFN0YWNrQ29uc3VtZXIodGhpcyk7Ci0gICAgdi52aXNpdEJyYW5jaEluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRJZkluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRJRk5VTEwodGhpcyk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0lGX0FDTVBFUS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSUZfQUNNUEVRLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDdjMDkyMGYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSUZfQUNNUEVRLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMDAgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotLyoqCi0gKiBJRl9BQ01QRVEgLSBCcmFuY2ggaWYgcmVmZXJlbmNlIGNvbXBhcmlzb24gc3VjY2VlZHMKLSAqCi0gKiA8UFJFPlN0YWNrOiAuLi4sIHZhbHVlMSwgdmFsdWUyIC0mZ3Q7IC4uLjwvUFJFPgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBJRl9BQ01QRVEgZXh0ZW5kcyBJZkluc3RydWN0aW9uIHsKLSAgLyoqCi0gICAqIEVtcHR5IGNvbnN0cnVjdG9yIG5lZWRlZCBmb3IgdGhlIENsYXNzLm5ld0luc3RhbmNlKCkgc3RhdGVtZW50IGluCi0gICAqIEluc3RydWN0aW9uLnJlYWRJbnN0cnVjdGlvbigpLiBOb3QgdG8gYmUgdXNlZCBvdGhlcndpc2UuCi0gICAqLwotICBJRl9BQ01QRVEoKSB7fQotCi0gIHB1YmxpYyBJRl9BQ01QRVEoSW5zdHJ1Y3Rpb25IYW5kbGUgdGFyZ2V0KSB7Ci0gICAgc3VwZXIoY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLklGX0FDTVBFUSwgdGFyZ2V0KTsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIG5lZ2F0aW9uIG9mIGluc3RydWN0aW9uCi0gICAqLwotICBwdWJsaWMgSWZJbnN0cnVjdGlvbiBuZWdhdGUoKSB7Ci0gICAgcmV0dXJuIG5ldyBJRl9BQ01QTkUodGFyZ2V0KTsKLSAgfQotCi0gIC8qKgotICAgKiBDYWxsIGNvcnJlc3BvbmRpbmcgdmlzaXRvciBtZXRob2QocykuIFRoZSBvcmRlciBpczoKLSAgICogQ2FsbCB2aXNpdG9yIG1ldGhvZHMgb2YgaW1wbGVtZW50ZWQgaW50ZXJmYWNlcyBmaXJzdCwgdGhlbgotICAgKiBjYWxsIG1ldGhvZHMgYWNjb3JkaW5nIHRvIHRoZSBjbGFzcyBoaWVyYXJjaHkgaW4gZGVzY2VuZGluZyBvcmRlciwKLSAgICogaS5lLiwgdGhlIG1vc3Qgc3BlY2lmaWMgdmlzaXRYWFgoKSBjYWxsIGNvbWVzIGxhc3QuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgdi52aXNpdFN0YWNrQ29uc3VtZXIodGhpcyk7Ci0gICAgdi52aXNpdEJyYW5jaEluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRJZkluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRJRl9BQ01QRVEodGhpcyk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0lGX0FDTVBORS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSUZfQUNNUE5FLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDI4MTMwMDcuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSUZfQUNNUE5FLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMDEgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotLyoqCi0gKiBJRl9BQ01QTkUgLSBCcmFuY2ggaWYgcmVmZXJlbmNlIGNvbXBhcmlzb24gZG9lc24ndCBzdWNjZWVkCi0gKgotICogPFBSRT5TdGFjazogLi4uLCB2YWx1ZTEsIHZhbHVlMiAtJmd0OyAuLi48L1BSRT4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgSUZfQUNNUE5FIGV4dGVuZHMgSWZJbnN0cnVjdGlvbiB7Ci0gIC8qKgotICAgKiBFbXB0eSBjb25zdHJ1Y3RvciBuZWVkZWQgZm9yIHRoZSBDbGFzcy5uZXdJbnN0YW5jZSgpIHN0YXRlbWVudCBpbgotICAgKiBJbnN0cnVjdGlvbi5yZWFkSW5zdHJ1Y3Rpb24oKS4gTm90IHRvIGJlIHVzZWQgb3RoZXJ3aXNlLgotICAgKi8KLSAgSUZfQUNNUE5FKCkge30KLQotICBwdWJsaWMgSUZfQUNNUE5FKEluc3RydWN0aW9uSGFuZGxlIHRhcmdldCkgewotICAgIHN1cGVyKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5JRl9BQ01QTkUsIHRhcmdldCk7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBuZWdhdGlvbiBvZiBpbnN0cnVjdGlvbgotICAgKi8KLSAgcHVibGljIElmSW5zdHJ1Y3Rpb24gbmVnYXRlKCkgewotICAgIHJldHVybiBuZXcgSUZfQUNNUEVRKHRhcmdldCk7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBDYWxsIGNvcnJlc3BvbmRpbmcgdmlzaXRvciBtZXRob2QocykuIFRoZSBvcmRlciBpczoKLSAgICogQ2FsbCB2aXNpdG9yIG1ldGhvZHMgb2YgaW1wbGVtZW50ZWQgaW50ZXJmYWNlcyBmaXJzdCwgdGhlbgotICAgKiBjYWxsIG1ldGhvZHMgYWNjb3JkaW5nIHRvIHRoZSBjbGFzcyBoaWVyYXJjaHkgaW4gZGVzY2VuZGluZyBvcmRlciwKLSAgICogaS5lLiwgdGhlIG1vc3Qgc3BlY2lmaWMgdmlzaXRYWFgoKSBjYWxsIGNvbWVzIGxhc3QuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgdi52aXNpdFN0YWNrQ29uc3VtZXIodGhpcyk7Ci0gICAgdi52aXNpdEJyYW5jaEluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRJZkluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRJRl9BQ01QTkUodGhpcyk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0lGX0lDTVBFUS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSUZfSUNNUEVRLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGExNDU3MzYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSUZfSUNNUEVRLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMDEgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotLyoqCi0gKiBJRl9JQ01QRVEgLSBCcmFuY2ggaWYgaW50IGNvbXBhcmlzb24gc3VjY2VlZHMKLSAqCi0gKiA8UFJFPlN0YWNrOiAuLi4sIHZhbHVlMSwgdmFsdWUyIC0mZ3Q7IC4uLjwvUFJFPgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBJRl9JQ01QRVEgZXh0ZW5kcyBJZkluc3RydWN0aW9uIHsKLSAgLyoqCi0gICAqIEVtcHR5IGNvbnN0cnVjdG9yIG5lZWRlZCBmb3IgdGhlIENsYXNzLm5ld0luc3RhbmNlKCkgc3RhdGVtZW50IGluCi0gICAqIEluc3RydWN0aW9uLnJlYWRJbnN0cnVjdGlvbigpLiBOb3QgdG8gYmUgdXNlZCBvdGhlcndpc2UuCi0gICAqLwotICBJRl9JQ01QRVEoKSB7fQotCi0gIHB1YmxpYyBJRl9JQ01QRVEoSW5zdHJ1Y3Rpb25IYW5kbGUgdGFyZ2V0KSB7Ci0gICAgc3VwZXIoY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLklGX0lDTVBFUSwgdGFyZ2V0KTsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIG5lZ2F0aW9uIG9mIGluc3RydWN0aW9uCi0gICAqLwotICBwdWJsaWMgSWZJbnN0cnVjdGlvbiBuZWdhdGUoKSB7Ci0gICAgcmV0dXJuIG5ldyBJRl9JQ01QTkUodGFyZ2V0KTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIENhbGwgY29ycmVzcG9uZGluZyB2aXNpdG9yIG1ldGhvZChzKS4gVGhlIG9yZGVyIGlzOgotICAgKiBDYWxsIHZpc2l0b3IgbWV0aG9kcyBvZiBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzIGZpcnN0LCB0aGVuCi0gICAqIGNhbGwgbWV0aG9kcyBhY2NvcmRpbmcgdG8gdGhlIGNsYXNzIGhpZXJhcmNoeSBpbiBkZXNjZW5kaW5nIG9yZGVyLAotICAgKiBpLmUuLCB0aGUgbW9zdCBzcGVjaWZpYyB2aXNpdFhYWCgpIGNhbGwgY29tZXMgbGFzdC4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0U3RhY2tDb25zdW1lcih0aGlzKTsKLSAgICB2LnZpc2l0QnJhbmNoSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdElmSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdElGX0lDTVBFUSh0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSUZfSUNNUEdFLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JRl9JQ01QR0UuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYzYyOWYyYy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JRl9JQ01QR0UuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEwMSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIElGX0lDTVBHRSAtIEJyYW5jaCBpZiBpbnQgY29tcGFyaXNvbiBzdWNjZWVkcwotICoKLSAqIDxQUkU+U3RhY2s6IC4uLiwgdmFsdWUxLCB2YWx1ZTIgLSZndDsgLi4uPC9QUkU+Ci0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGNsYXNzIElGX0lDTVBHRSBleHRlbmRzIElmSW5zdHJ1Y3Rpb24gewotICAvKioKLSAgICogRW1wdHkgY29uc3RydWN0b3IgbmVlZGVkIGZvciB0aGUgQ2xhc3MubmV3SW5zdGFuY2UoKSBzdGF0ZW1lbnQgaW4KLSAgICogSW5zdHJ1Y3Rpb24ucmVhZEluc3RydWN0aW9uKCkuIE5vdCB0byBiZSB1c2VkIG90aGVyd2lzZS4KLSAgICovCi0gIElGX0lDTVBHRSgpIHt9Ci0KLSAgcHVibGljIElGX0lDTVBHRShJbnN0cnVjdGlvbkhhbmRsZSB0YXJnZXQpIHsKLSAgICBzdXBlcihjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuSUZfSUNNUEdFLCB0YXJnZXQpOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gbmVnYXRpb24gb2YgaW5zdHJ1Y3Rpb24KLSAgICovCi0gIHB1YmxpYyBJZkluc3RydWN0aW9uIG5lZ2F0ZSgpIHsKLSAgICByZXR1cm4gbmV3IElGX0lDTVBMVCh0YXJnZXQpOwotICB9Ci0KLQotICAvKioKLSAgICogQ2FsbCBjb3JyZXNwb25kaW5nIHZpc2l0b3IgbWV0aG9kKHMpLiBUaGUgb3JkZXIgaXM6Ci0gICAqIENhbGwgdmlzaXRvciBtZXRob2RzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMgZmlyc3QsIHRoZW4KLSAgICogY2FsbCBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY2xhc3MgaGllcmFyY2h5IGluIGRlc2NlbmRpbmcgb3JkZXIsCi0gICAqIGkuZS4sIHRoZSBtb3N0IHNwZWNpZmljIHZpc2l0WFhYKCkgY2FsbCBjb21lcyBsYXN0LgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRTdGFja0NvbnN1bWVyKHRoaXMpOwotICAgIHYudmlzaXRCcmFuY2hJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0SWZJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0SUZfSUNNUEdFKHRoaXMpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JRl9JQ01QR1QuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0lGX0lDTVBHVC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMTNhNzJlLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0lGX0lDTVBHVC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTAxICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8qKgotICogSUZfSUNNUEdUIC0gQnJhbmNoIGlmIGludCBjb21wYXJpc29uIHN1Y2NlZWRzCi0gKgotICogPFBSRT5TdGFjazogLi4uLCB2YWx1ZTEsIHZhbHVlMiAtJmd0OyAuLi48L1BSRT4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgSUZfSUNNUEdUIGV4dGVuZHMgSWZJbnN0cnVjdGlvbiB7Ci0gIC8qKgotICAgKiBFbXB0eSBjb25zdHJ1Y3RvciBuZWVkZWQgZm9yIHRoZSBDbGFzcy5uZXdJbnN0YW5jZSgpIHN0YXRlbWVudCBpbgotICAgKiBJbnN0cnVjdGlvbi5yZWFkSW5zdHJ1Y3Rpb24oKS4gTm90IHRvIGJlIHVzZWQgb3RoZXJ3aXNlLgotICAgKi8KLSAgSUZfSUNNUEdUKCkge30KLQotICBwdWJsaWMgSUZfSUNNUEdUKEluc3RydWN0aW9uSGFuZGxlIHRhcmdldCkgewotICAgIHN1cGVyKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5JRl9JQ01QR1QsIHRhcmdldCk7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBuZWdhdGlvbiBvZiBpbnN0cnVjdGlvbgotICAgKi8KLSAgcHVibGljIElmSW5zdHJ1Y3Rpb24gbmVnYXRlKCkgewotICAgIHJldHVybiBuZXcgSUZfSUNNUExFKHRhcmdldCk7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBDYWxsIGNvcnJlc3BvbmRpbmcgdmlzaXRvciBtZXRob2QocykuIFRoZSBvcmRlciBpczoKLSAgICogQ2FsbCB2aXNpdG9yIG1ldGhvZHMgb2YgaW1wbGVtZW50ZWQgaW50ZXJmYWNlcyBmaXJzdCwgdGhlbgotICAgKiBjYWxsIG1ldGhvZHMgYWNjb3JkaW5nIHRvIHRoZSBjbGFzcyBoaWVyYXJjaHkgaW4gZGVzY2VuZGluZyBvcmRlciwKLSAgICogaS5lLiwgdGhlIG1vc3Qgc3BlY2lmaWMgdmlzaXRYWFgoKSBjYWxsIGNvbWVzIGxhc3QuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgdi52aXNpdFN0YWNrQ29uc3VtZXIodGhpcyk7Ci0gICAgdi52aXNpdEJyYW5jaEluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRJZkluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRJRl9JQ01QR1QodGhpcyk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0lGX0lDTVBMRS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSUZfSUNNUExFLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDdhZGExMzIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSUZfSUNNUExFLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMDEgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotLyoqCi0gKiBJRl9JQ01QTEUgLSBCcmFuY2ggaWYgaW50IGNvbXBhcmlzb24gc3VjY2VlZHMKLSAqCi0gKiA8UFJFPlN0YWNrOiAuLi4sIHZhbHVlMSwgdmFsdWUyIC0mZ3Q7IC4uLjwvUFJFPgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBJRl9JQ01QTEUgZXh0ZW5kcyBJZkluc3RydWN0aW9uIHsKLSAgLyoqCi0gICAqIEVtcHR5IGNvbnN0cnVjdG9yIG5lZWRlZCBmb3IgdGhlIENsYXNzLm5ld0luc3RhbmNlKCkgc3RhdGVtZW50IGluCi0gICAqIEluc3RydWN0aW9uLnJlYWRJbnN0cnVjdGlvbigpLiBOb3QgdG8gYmUgdXNlZCBvdGhlcndpc2UuCi0gICAqLwotICBJRl9JQ01QTEUoKSB7fQotCi0gIHB1YmxpYyBJRl9JQ01QTEUoSW5zdHJ1Y3Rpb25IYW5kbGUgdGFyZ2V0KSB7Ci0gICAgc3VwZXIoY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLklGX0lDTVBMRSwgdGFyZ2V0KTsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIG5lZ2F0aW9uIG9mIGluc3RydWN0aW9uCi0gICAqLwotICBwdWJsaWMgSWZJbnN0cnVjdGlvbiBuZWdhdGUoKSB7Ci0gICAgcmV0dXJuIG5ldyBJRl9JQ01QR1QodGFyZ2V0KTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIENhbGwgY29ycmVzcG9uZGluZyB2aXNpdG9yIG1ldGhvZChzKS4gVGhlIG9yZGVyIGlzOgotICAgKiBDYWxsIHZpc2l0b3IgbWV0aG9kcyBvZiBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzIGZpcnN0LCB0aGVuCi0gICAqIGNhbGwgbWV0aG9kcyBhY2NvcmRpbmcgdG8gdGhlIGNsYXNzIGhpZXJhcmNoeSBpbiBkZXNjZW5kaW5nIG9yZGVyLAotICAgKiBpLmUuLCB0aGUgbW9zdCBzcGVjaWZpYyB2aXNpdFhYWCgpIGNhbGwgY29tZXMgbGFzdC4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0U3RhY2tDb25zdW1lcih0aGlzKTsKLSAgICB2LnZpc2l0QnJhbmNoSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdElmSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdElGX0lDTVBMRSh0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSUZfSUNNUExULmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JRl9JQ01QTFQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggODMzZjA2Yy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JRl9JQ01QTFQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEwMSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIElGX0lDTVBMVCAtIEJyYW5jaCBpZiBpbnQgY29tcGFyaXNvbiBzdWNjZWVkcwotICoKLSAqIDxQUkU+U3RhY2s6IC4uLiwgdmFsdWUxLCB2YWx1ZTIgLSZndDsgLi4uPC9QUkU+Ci0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGNsYXNzIElGX0lDTVBMVCBleHRlbmRzIElmSW5zdHJ1Y3Rpb24gewotICAvKioKLSAgICogRW1wdHkgY29uc3RydWN0b3IgbmVlZGVkIGZvciB0aGUgQ2xhc3MubmV3SW5zdGFuY2UoKSBzdGF0ZW1lbnQgaW4KLSAgICogSW5zdHJ1Y3Rpb24ucmVhZEluc3RydWN0aW9uKCkuIE5vdCB0byBiZSB1c2VkIG90aGVyd2lzZS4KLSAgICovCi0gIElGX0lDTVBMVCgpIHt9Ci0KLSAgcHVibGljIElGX0lDTVBMVChJbnN0cnVjdGlvbkhhbmRsZSB0YXJnZXQpIHsKLSAgICBzdXBlcihjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuSUZfSUNNUExULCB0YXJnZXQpOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gbmVnYXRpb24gb2YgaW5zdHJ1Y3Rpb24KLSAgICovCi0gIHB1YmxpYyBJZkluc3RydWN0aW9uIG5lZ2F0ZSgpIHsKLSAgICByZXR1cm4gbmV3IElGX0lDTVBHRSh0YXJnZXQpOwotICB9Ci0KLQotICAvKioKLSAgICogQ2FsbCBjb3JyZXNwb25kaW5nIHZpc2l0b3IgbWV0aG9kKHMpLiBUaGUgb3JkZXIgaXM6Ci0gICAqIENhbGwgdmlzaXRvciBtZXRob2RzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMgZmlyc3QsIHRoZW4KLSAgICogY2FsbCBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY2xhc3MgaGllcmFyY2h5IGluIGRlc2NlbmRpbmcgb3JkZXIsCi0gICAqIGkuZS4sIHRoZSBtb3N0IHNwZWNpZmljIHZpc2l0WFhYKCkgY2FsbCBjb21lcyBsYXN0LgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRTdGFja0NvbnN1bWVyKHRoaXMpOwotICAgIHYudmlzaXRCcmFuY2hJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0SWZJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0SUZfSUNNUExUKHRoaXMpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JRl9JQ01QTkUuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0lGX0lDTVBORS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhZTVhZTg3Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0lGX0lDTVBORS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTAxICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8qKgotICogSUZfSUNNUE5FIC0gQnJhbmNoIGlmIGludCBjb21wYXJpc29uIGRvZXNuJ3Qgc3VjY2VlZAotICoKLSAqIDxQUkU+U3RhY2s6IC4uLiwgdmFsdWUxLCB2YWx1ZTIgLSZndDsgLi4uPC9QUkU+Ci0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGNsYXNzIElGX0lDTVBORSBleHRlbmRzIElmSW5zdHJ1Y3Rpb24gewotICAvKioKLSAgICogRW1wdHkgY29uc3RydWN0b3IgbmVlZGVkIGZvciB0aGUgQ2xhc3MubmV3SW5zdGFuY2UoKSBzdGF0ZW1lbnQgaW4KLSAgICogSW5zdHJ1Y3Rpb24ucmVhZEluc3RydWN0aW9uKCkuIE5vdCB0byBiZSB1c2VkIG90aGVyd2lzZS4KLSAgICovCi0gIElGX0lDTVBORSgpIHt9Ci0KLSAgcHVibGljIElGX0lDTVBORShJbnN0cnVjdGlvbkhhbmRsZSB0YXJnZXQpIHsKLSAgICBzdXBlcihjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuSUZfSUNNUE5FLCB0YXJnZXQpOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gbmVnYXRpb24gb2YgaW5zdHJ1Y3Rpb24KLSAgICovCi0gIHB1YmxpYyBJZkluc3RydWN0aW9uIG5lZ2F0ZSgpIHsKLSAgICByZXR1cm4gbmV3IElGX0lDTVBFUSh0YXJnZXQpOwotICB9Ci0KLQotICAvKioKLSAgICogQ2FsbCBjb3JyZXNwb25kaW5nIHZpc2l0b3IgbWV0aG9kKHMpLiBUaGUgb3JkZXIgaXM6Ci0gICAqIENhbGwgdmlzaXRvciBtZXRob2RzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMgZmlyc3QsIHRoZW4KLSAgICogY2FsbCBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY2xhc3MgaGllcmFyY2h5IGluIGRlc2NlbmRpbmcgb3JkZXIsCi0gICAqIGkuZS4sIHRoZSBtb3N0IHNwZWNpZmljIHZpc2l0WFhYKCkgY2FsbCBjb21lcyBsYXN0LgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRTdGFja0NvbnN1bWVyKHRoaXMpOwotICAgIHYudmlzaXRCcmFuY2hJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0SWZJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0SUZfSUNNUE5FKHRoaXMpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JSU5DLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JSU5DLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDkyODYwMDcuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSUlOQy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTg2ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1pbXBvcnQgamF2YS5pby4qOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLnV0aWwuQnl0ZVNlcXVlbmNlOwotCi0vKioKLSAqIElJTkMgLSBJbmNyZW1lbnQgbG9jYWwgdmFyaWFibGUgYnkgY29uc3RhbnQKLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgSUlOQyBleHRlbmRzIExvY2FsVmFyaWFibGVJbnN0cnVjdGlvbiB7Ci0gIHByaXZhdGUgYm9vbGVhbiB3aWRlOwotICBwcml2YXRlIGludCAgICAgYzsKLQotICAvKioKLSAgICogRW1wdHkgY29uc3RydWN0b3IgbmVlZGVkIGZvciB0aGUgQ2xhc3MubmV3SW5zdGFuY2UoKSBzdGF0ZW1lbnQgaW4KLSAgICogSW5zdHJ1Y3Rpb24ucmVhZEluc3RydWN0aW9uKCkuIE5vdCB0byBiZSB1c2VkIG90aGVyd2lzZS4KLSAgICovCi0gIElJTkMoKSB7fQotCi0gIC8qKgotICAgKiBAcGFyYW0gbiBpbmRleCBvZiBsb2NhbCB2YXJpYWJsZQotICAgKiBAcGFyYW0gYyBpbmNyZW1lbnQgZmFjdG9yCi0gICAqLwotICBwdWJsaWMgSUlOQyhpbnQgbiwgaW50IGMpIHsKLSAgICBzdXBlcigpOyAvLyBEZWZhdWx0IGJlaGF2aW91ciBvZiBMb2NhbFZhcmlhYmxlSW5zdHJ1Y3Rpb24gY2F1c2VzIGVycm9yCi0KLSAgICB0aGlzLm9wY29kZSA9IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5JSU5DOwotICAgIHRoaXMubGVuZ3RoID0gKHNob3J0KTM7Ci0KLSAgICBzZXRJbmRleChuKTsgICAgLy8gTWF5IHNldCB3aWRlIGFzIHNpZGUgZWZmZWN0Ci0gICAgc2V0SW5jcmVtZW50KGMpOwotICB9Ci0KLSAgLyoqCi0gICAqIER1bXAgaW5zdHJ1Y3Rpb24gYXMgYnl0ZSBjb2RlIHRvIHN0cmVhbSBvdXQuCi0gICAqIEBwYXJhbSBvdXQgT3V0cHV0IHN0cmVhbQotICAgKi8KLSAgcHVibGljIHZvaWQgZHVtcChEYXRhT3V0cHV0U3RyZWFtIG91dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLSAgICBpZih3aWRlKSAvLyBOZWVkIFdJREUgcHJlZml4ID8KLSAgICAgIG91dC53cml0ZUJ5dGUoY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLldJREUpOwotCi0gICAgb3V0LndyaXRlQnl0ZShvcGNvZGUpOwotCi0gICAgaWYod2lkZSkgewotICAgICAgb3V0LndyaXRlU2hvcnQobik7Ci0gICAgICBvdXQud3JpdGVTaG9ydChjKTsKLSAgICB9IGVsc2UgewotICAgICAgb3V0LndyaXRlQnl0ZShuKTsKLSAgICAgIG91dC53cml0ZUJ5dGUoYyk7Ci0gICAgfQotICB9Ci0KLSAgcHJpdmF0ZSBmaW5hbCB2b2lkIHNldFdpZGUoKSB7Ci0gICAgaWYod2lkZSA9ICgobiA+IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5NQVhfU0hPUlQpIHx8Ci0gICAgICAgICAgICAgICAoTWF0aC5hYnMoYykgPiBCeXRlLk1BWF9WQUxVRSkpKQotICAgICAgbGVuZ3RoID0gNjsgLy8gd2lkZSBieXRlIGluY2x1ZGVkCi0gICAgZWxzZQotICAgICAgbGVuZ3RoID0gMzsKLSAgfQotCi0gIC8qKgotICAgKiBSZWFkIG5lZWRlZCBkYXRhIChlLmcuIGluZGV4KSBmcm9tIGZpbGUuCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBpbml0RnJvbUZpbGUoQnl0ZVNlcXVlbmNlIGJ5dGVzLCBib29sZWFuIHdpZGUpIHRocm93cyBJT0V4Y2VwdGlvbgotICB7Ci0gICAgdGhpcy53aWRlID0gd2lkZTsKLQotICAgIGlmKHdpZGUpIHsKLSAgICAgIGxlbmd0aCA9IDY7Ci0gICAgICBuID0gYnl0ZXMucmVhZFVuc2lnbmVkU2hvcnQoKTsKLSAgICAgIGMgPSBieXRlcy5yZWFkU2hvcnQoKTsKLSAgICB9IGVsc2UgewotICAgICAgbGVuZ3RoID0gMzsKLSAgICAgIG4gPSBieXRlcy5yZWFkVW5zaWduZWRCeXRlKCk7Ci0gICAgICBjID0gYnl0ZXMucmVhZEJ5dGUoKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBtbmVtb25pYyBmb3IgaW5zdHJ1Y3Rpb24KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoYm9vbGVhbiB2ZXJib3NlKSB7Ci0gICAgcmV0dXJuIHN1cGVyLnRvU3RyaW5nKHZlcmJvc2UpICsgIiAiICsgYzsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgaW5kZXggb2YgbG9jYWwgdmFyaWFibGUuCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBzZXRJbmRleChpbnQgbikgewotICAgIGlmKG4gPCAwKQotICAgICAgdGhyb3cgbmV3IENsYXNzR2VuRXhjZXB0aW9uKCJOZWdhdGl2ZSBpbmRleCB2YWx1ZTogIiArIG4pOwotCi0gICAgdGhpcy5uID0gbjsKLSAgICBzZXRXaWRlKCk7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBpbmNyZW1lbnQgZmFjdG9yCi0gICAqLwotICBwdWJsaWMgZmluYWwgaW50IGdldEluY3JlbWVudCgpIHsgcmV0dXJuIGM7IH0KLQotICAvKioKLSAgICogU2V0IGluY3JlbWVudCBmYWN0b3IuCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBzZXRJbmNyZW1lbnQoaW50IGMpIHsKLSAgICB0aGlzLmMgPSBjOwotICAgIHNldFdpZGUoKTsKLSAgfQotCi0gIC8qKiBAcmV0dXJuIGludCB0eXBlCi0gICAqLwotICBwdWJsaWMgVHlwZSBnZXRUeXBlKENvbnN0YW50UG9vbEdlbiBjcCkgewotICAgIHJldHVybiBUeXBlLklOVDsKLSAgfQotCi0gIC8qKgotICAgKiBDYWxsIGNvcnJlc3BvbmRpbmcgdmlzaXRvciBtZXRob2QocykuIFRoZSBvcmRlciBpczoKLSAgICogQ2FsbCB2aXNpdG9yIG1ldGhvZHMgb2YgaW1wbGVtZW50ZWQgaW50ZXJmYWNlcyBmaXJzdCwgdGhlbgotICAgKiBjYWxsIG1ldGhvZHMgYWNjb3JkaW5nIHRvIHRoZSBjbGFzcyBoaWVyYXJjaHkgaW4gZGVzY2VuZGluZyBvcmRlciwKLSAgICogaS5lLiwgdGhlIG1vc3Qgc3BlY2lmaWMgdmlzaXRYWFgoKSBjYWxsIGNvbWVzIGxhc3QuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgdi52aXNpdExvY2FsVmFyaWFibGVJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0SUlOQyh0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSUxPQUQuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0lMT0FELmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDA1OTg5ZDkuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSUxPQUQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDk1ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8qKgotICogSUxPQUQgLSBMb2FkIGludCBmcm9tIGxvY2FsIHZhcmlhYmxlIG9udG8gc3RhY2sKLSAqIDxQUkU+U3RhY2s6IC4uLiAtJmd0OyAuLi4sIHJlc3VsdDwvUFJFPgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBJTE9BRCBleHRlbmRzIExvYWRJbnN0cnVjdGlvbiB7Ci0gIC8qKgotICAgKiBFbXB0eSBjb25zdHJ1Y3RvciBuZWVkZWQgZm9yIHRoZSBDbGFzcy5uZXdJbnN0YW5jZSgpIHN0YXRlbWVudCBpbgotICAgKiBJbnN0cnVjdGlvbi5yZWFkSW5zdHJ1Y3Rpb24oKS4gTm90IHRvIGJlIHVzZWQgb3RoZXJ3aXNlLgotICAgKi8KLSAgSUxPQUQoKSB7Ci0gICAgc3VwZXIoY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLklMT0FELCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuSUxPQURfMCk7Ci0gIH0KLQotICAvKiogTG9hZCBpbnQgZnJvbSBsb2NhbCB2YXJpYWJsZQotICAgKiBAcGFyYW0gbiBpbmRleCBvZiBsb2NhbCB2YXJpYWJsZQotICAgKi8KLSAgcHVibGljIElMT0FEKGludCBuKSB7Ci0gICAgc3VwZXIoY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLklMT0FELCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuSUxPQURfMCwgbik7Ci0gIH0KLQotICAvKioKLSAgICogQ2FsbCBjb3JyZXNwb25kaW5nIHZpc2l0b3IgbWV0aG9kKHMpLiBUaGUgb3JkZXIgaXM6Ci0gICAqIENhbGwgdmlzaXRvciBtZXRob2RzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMgZmlyc3QsIHRoZW4KLSAgICogY2FsbCBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY2xhc3MgaGllcmFyY2h5IGluIGRlc2NlbmRpbmcgb3JkZXIsCi0gICAqIGkuZS4sIHRoZSBtb3N0IHNwZWNpZmljIHZpc2l0WFhYKCkgY2FsbCBjb21lcyBsYXN0LgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHN1cGVyLmFjY2VwdCh2KTsKLSAgICB2LnZpc2l0SUxPQUQodGhpcyk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0lNUERFUDEuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0lNUERFUDEuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMjgxZjA4Ny4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JTVBERVAxLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4MyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIElNUERFUDEgLSBJbXBsZW1lbnRhdGlvbiBkZXBlbmRlbnQKLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgSU1QREVQMSBleHRlbmRzIEluc3RydWN0aW9uIHsKLSAgcHVibGljIElNUERFUDEoKSB7Ci0gICAgc3VwZXIoY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLklNUERFUDEsIChzaG9ydCkxKTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIENhbGwgY29ycmVzcG9uZGluZyB2aXNpdG9yIG1ldGhvZChzKS4gVGhlIG9yZGVyIGlzOgotICAgKiBDYWxsIHZpc2l0b3IgbWV0aG9kcyBvZiBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzIGZpcnN0LCB0aGVuCi0gICAqIGNhbGwgbWV0aG9kcyBhY2NvcmRpbmcgdG8gdGhlIGNsYXNzIGhpZXJhcmNoeSBpbiBkZXNjZW5kaW5nIG9yZGVyLAotICAgKiBpLmUuLCB0aGUgbW9zdCBzcGVjaWZpYyB2aXNpdFhYWCgpIGNhbGwgY29tZXMgbGFzdC4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0SU1QREVQMSh0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSU1QREVQMi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSU1QREVQMi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiYTU3ODliLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0lNUERFUDIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDgzICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8qKgotICogSU1QREVQMiAtIEltcGxlbWVudGF0aW9uIGRlcGVuZGVudAotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBJTVBERVAyIGV4dGVuZHMgSW5zdHJ1Y3Rpb24gewotICBwdWJsaWMgSU1QREVQMigpIHsKLSAgICBzdXBlcihjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuSU1QREVQMiwgKHNob3J0KTEpOwotICB9Ci0KLQotICAvKioKLSAgICogQ2FsbCBjb3JyZXNwb25kaW5nIHZpc2l0b3IgbWV0aG9kKHMpLiBUaGUgb3JkZXIgaXM6Ci0gICAqIENhbGwgdmlzaXRvciBtZXRob2RzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMgZmlyc3QsIHRoZW4KLSAgICogY2FsbCBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY2xhc3MgaGllcmFyY2h5IGluIGRlc2NlbmRpbmcgb3JkZXIsCi0gICAqIGkuZS4sIHRoZSBtb3N0IHNwZWNpZmljIHZpc2l0WFhYKCkgY2FsbCBjb21lcyBsYXN0LgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRJTVBERVAyKHRoaXMpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JTVVMLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JTVVMLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDFkZjc4MGYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSU1VTC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTAgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotLyoqCi0gKiBJTVVMIC0gTXVsdGlwbHkgaW50cwotICogPFBSRT5TdGFjazogLi4uLCB2YWx1ZTEsIHZhbHVlMiAtJmd0OyByZXN1bHQ8L1BSRT4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgSU1VTCBleHRlbmRzIEFyaXRobWV0aWNJbnN0cnVjdGlvbiB7Ci0gIC8qKiBNdWx0aXBseSBpbnRzCi0gICAqLwotICBwdWJsaWMgSU1VTCgpIHsKLSAgICBzdXBlcihjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuSU1VTCk7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBDYWxsIGNvcnJlc3BvbmRpbmcgdmlzaXRvciBtZXRob2QocykuIFRoZSBvcmRlciBpczoKLSAgICogQ2FsbCB2aXNpdG9yIG1ldGhvZHMgb2YgaW1wbGVtZW50ZWQgaW50ZXJmYWNlcyBmaXJzdCwgdGhlbgotICAgKiBjYWxsIG1ldGhvZHMgYWNjb3JkaW5nIHRvIHRoZSBjbGFzcyBoaWVyYXJjaHkgaW4gZGVzY2VuZGluZyBvcmRlciwKLSAgICogaS5lLiwgdGhlIG1vc3Qgc3BlY2lmaWMgdmlzaXRYWFgoKSBjYWxsIGNvbWVzIGxhc3QuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgdi52aXNpdFR5cGVkSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdFN0YWNrUHJvZHVjZXIodGhpcyk7Ci0gICAgdi52aXNpdFN0YWNrQ29uc3VtZXIodGhpcyk7Ci0gICAgdi52aXNpdEFyaXRobWV0aWNJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0SU1VTCh0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSU5FRy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSU5FRy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmYTg5MzFkLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0lORUcuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDg4ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8qKgotICogSU5FRyAtIE5lZ2F0ZSBpbnQKLSAqIDxQUkU+U3RhY2s6IC4uLiwgdmFsdWUgLSZndDsgLi4uLCByZXN1bHQ8L1BSRT4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgSU5FRyBleHRlbmRzIEFyaXRobWV0aWNJbnN0cnVjdGlvbiB7Ci0gIHB1YmxpYyBJTkVHKCkgewotICAgIHN1cGVyKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5JTkVHKTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIENhbGwgY29ycmVzcG9uZGluZyB2aXNpdG9yIG1ldGhvZChzKS4gVGhlIG9yZGVyIGlzOgotICAgKiBDYWxsIHZpc2l0b3IgbWV0aG9kcyBvZiBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzIGZpcnN0LCB0aGVuCi0gICAqIGNhbGwgbWV0aG9kcyBhY2NvcmRpbmcgdG8gdGhlIGNsYXNzIGhpZXJhcmNoeSBpbiBkZXNjZW5kaW5nIG9yZGVyLAotICAgKiBpLmUuLCB0aGUgbW9zdCBzcGVjaWZpYyB2aXNpdFhYWCgpIGNhbGwgY29tZXMgbGFzdC4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0VHlwZWRJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tQcm9kdWNlcih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tDb25zdW1lcih0aGlzKTsKLSAgICB2LnZpc2l0QXJpdGhtZXRpY0luc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRJTkVHKHRoaXMpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JTlNUQU5DRU9GLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JTlNUQU5DRU9GLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGVkMWM0OTEuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSU5TVEFOQ0VPRi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTA5ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8qKgotICogSU5TVEFOQ0VPRiAtIERldGVybWluZSBpZiBvYmplY3QgaXMgb2YgZ2l2ZW4gdHlwZQotICogPFBSRT5TdGFjazogLi4uLCBvYmplY3RyZWYgLSZndDsgLi4uLCByZXN1bHQ8L1BSRT4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgSU5TVEFOQ0VPRiBleHRlbmRzIENQSW5zdHJ1Y3Rpb24KLSAgaW1wbGVtZW50cyBMb2FkQ2xhc3MsIEV4Y2VwdGlvblRocm93ZXIsIFN0YWNrUHJvZHVjZXIsIFN0YWNrQ29uc3VtZXIgewotICAvKioKLSAgICogRW1wdHkgY29uc3RydWN0b3IgbmVlZGVkIGZvciB0aGUgQ2xhc3MubmV3SW5zdGFuY2UoKSBzdGF0ZW1lbnQgaW4KLSAgICogSW5zdHJ1Y3Rpb24ucmVhZEluc3RydWN0aW9uKCkuIE5vdCB0byBiZSB1c2VkIG90aGVyd2lzZS4KLSAgICovCi0gIElOU1RBTkNFT0YoKSB7fQotCi0gIHB1YmxpYyBJTlNUQU5DRU9GKGludCBpbmRleCkgewotICAgIHN1cGVyKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5JTlNUQU5DRU9GLCBpbmRleCk7Ci0gIH0KLQotICBwdWJsaWMgQ2xhc3NbXSBnZXRFeGNlcHRpb25zKCkgewotICAgIHJldHVybiBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5FeGNlcHRpb25Db25zdGFudHMuRVhDU19DTEFTU19BTkRfSU5URVJGQUNFX1JFU09MVVRJT047Ci0gIH0KLQotICBwdWJsaWMgT2JqZWN0VHlwZSBnZXRMb2FkQ2xhc3NUeXBlKENvbnN0YW50UG9vbEdlbiBjcGcpIHsKLSAgICBUeXBlIHQgPSBnZXRUeXBlKGNwZyk7Ci0KLSAgICBpZih0IGluc3RhbmNlb2YgQXJyYXlUeXBlKQotICAgICAgdCA9ICgoQXJyYXlUeXBlKSB0KS5nZXRCYXNpY1R5cGUoKTsKLQotICAgIHJldHVybiAodCBpbnN0YW5jZW9mIE9iamVjdFR5cGUpPyAoT2JqZWN0VHlwZSkgdCA6IG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogQ2FsbCBjb3JyZXNwb25kaW5nIHZpc2l0b3IgbWV0aG9kKHMpLiBUaGUgb3JkZXIgaXM6Ci0gICAqIENhbGwgdmlzaXRvciBtZXRob2RzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMgZmlyc3QsIHRoZW4KLSAgICogY2FsbCBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY2xhc3MgaGllcmFyY2h5IGluIGRlc2NlbmRpbmcgb3JkZXIsCi0gICAqIGkuZS4sIHRoZSBtb3N0IHNwZWNpZmljIHZpc2l0WFhYKCkgY2FsbCBjb21lcyBsYXN0LgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRMb2FkQ2xhc3ModGhpcyk7Ci0gICAgdi52aXNpdEV4Y2VwdGlvblRocm93ZXIodGhpcyk7Ci0gICAgdi52aXNpdFN0YWNrUHJvZHVjZXIodGhpcyk7Ci0gICAgdi52aXNpdFN0YWNrQ29uc3VtZXIodGhpcyk7Ci0gICAgdi52aXNpdFR5cGVkSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdENQSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdElOU1RBTkNFT0YodGhpcyk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0lOVk9LRUlOVEVSRkFDRS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSU5WT0tFSU5URVJGQUNFLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGFlZDM0YmQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSU5WT0tFSU5URVJGQUNFLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNjYgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5jbGFzc2ZpbGUuQ29uc3RhbnRQb29sOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50czsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5FeGNlcHRpb25Db25zdGFudHM7Ci0KLWltcG9ydCBqYXZhLmlvLio7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwudXRpbC5CeXRlU2VxdWVuY2U7Ci0KLS8qKgotICogSU5WT0tFSU5URVJGQUNFIC0gSW52b2tlIGludGVyZmFjZSBtZXRob2QKLSAqIDxQUkU+U3RhY2s6IC4uLiwgb2JqZWN0cmVmLCBbYXJnMSwgW2FyZzIgLi4uXV0gLSZndDsgLi4uPC9QUkU+Ci0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIElOVk9LRUlOVEVSRkFDRSBleHRlbmRzIEludm9rZUluc3RydWN0aW9uIHsKLSAgcHJpdmF0ZSBpbnQgbmFyZ3M7IC8vIE51bWJlciBvZiBhcmd1bWVudHMgb24gc3RhY2sgKG51bWJlciBvZiBzdGFjayBzbG90cyksIGNhbGxlZCAiY291bnQiIGluIHZtc3BlYzIKLQotICAvKioKLSAgICogRW1wdHkgY29uc3RydWN0b3IgbmVlZGVkIGZvciB0aGUgQ2xhc3MubmV3SW5zdGFuY2UoKSBzdGF0ZW1lbnQgaW4KLSAgICogSW5zdHJ1Y3Rpb24ucmVhZEluc3RydWN0aW9uKCkuIE5vdCB0byBiZSB1c2VkIG90aGVyd2lzZS4KLSAgICovCi0gIElOVk9LRUlOVEVSRkFDRSgpIHt9Ci0KLSAgcHVibGljIElOVk9LRUlOVEVSRkFDRShpbnQgaW5kZXgsIGludCBuYXJncykgewotICAgIHN1cGVyKENvbnN0YW50cy5JTlZPS0VJTlRFUkZBQ0UsIGluZGV4KTsKLSAgICBsZW5ndGggPSA1OwotCi0gICAgaWYobmFyZ3MgPCAxKQotICAgICAgdGhyb3cgbmV3IENsYXNzR2VuRXhjZXB0aW9uKCJOdW1iZXIgb2YgYXJndW1lbnRzIG11c3QgYmUgPiAwICIgKyBuYXJncyk7Ci0KLSAgICB0aGlzLm5hcmdzID0gbmFyZ3M7Ci0gIH0KLQotICAvKioKLSAgICogRHVtcCBpbnN0cnVjdGlvbiBhcyBieXRlIGNvZGUgdG8gc3RyZWFtIG91dC4KLSAgICogQHBhcmFtIG91dCBPdXRwdXQgc3RyZWFtCi0gICAqLwotICBwdWJsaWMgdm9pZCBkdW1wKERhdGFPdXRwdXRTdHJlYW0gb3V0KSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgIG91dC53cml0ZUJ5dGUob3Bjb2RlKTsKLSAgICBvdXQud3JpdGVTaG9ydChpbmRleCk7Ci0gICAgb3V0LndyaXRlQnl0ZShuYXJncyk7Ci0gICAgb3V0LndyaXRlQnl0ZSgwKTsKLSAgfQotCi0gIC8qKgotICAgKiBUaGUgPEI+Y291bnQ8L0I+IGFyZ3VtZW50IGFjY29yZGluZyB0byB0aGUgSmF2YSBMYW5ndWFnZSBTcGVjaWZpY2F0aW9uLAotICAgKiBTZWNvbmQgRWRpdGlvbi4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0Q291bnQoKSB7IHJldHVybiBuYXJnczsgfQotCi0gIC8qKgotICAgKiBSZWFkIG5lZWRlZCBkYXRhIChpLmUuLCBpbmRleCkgZnJvbSBmaWxlLgotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgaW5pdEZyb21GaWxlKEJ5dGVTZXF1ZW5jZSBieXRlcywgYm9vbGVhbiB3aWRlKQotICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbgotICB7Ci0gICAgc3VwZXIuaW5pdEZyb21GaWxlKGJ5dGVzLCB3aWRlKTsKLQotICAgIGxlbmd0aCA9IDU7Ci0gICAgbmFyZ3MgPSBieXRlcy5yZWFkVW5zaWduZWRCeXRlKCk7Ci0gICAgYnl0ZXMucmVhZEJ5dGUoKTsgLy8gU2tpcCAwIGJ5dGUKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIG1uZW1vbmljIGZvciBpbnN0cnVjdGlvbiB3aXRoIHN5bWJvbGljIHJlZmVyZW5jZXMgcmVzb2x2ZWQKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoQ29uc3RhbnRQb29sIGNwKSB7Ci0gICAgcmV0dXJuIHN1cGVyLnRvU3RyaW5nKGNwKSArICIgIiArIG5hcmdzOwotICB9Ci0KLSAgcHVibGljIGludCBjb25zdW1lU3RhY2soQ29uc3RhbnRQb29sR2VuIGNwZykgeyAvLyBuYXJncyBpcyBnaXZlbiBpbiBieXRlLWNvZGUKLSAgICByZXR1cm4gbmFyZ3M7ICAvLyBuYXJncyBpbmNsdWRlcyB0aGlzIHJlZmVyZW5jZQotICB9Ci0KLSAgcHVibGljIENsYXNzW10gZ2V0RXhjZXB0aW9ucygpIHsKLSAgICBDbGFzc1tdIGNzID0gbmV3IENsYXNzWzQgKyBFeGNlcHRpb25Db25zdGFudHMuRVhDU19JTlRFUkZBQ0VfTUVUSE9EX1JFU09MVVRJT04ubGVuZ3RoXTsKLQotICAgIFN5c3RlbS5hcnJheWNvcHkoRXhjZXB0aW9uQ29uc3RhbnRzLkVYQ1NfSU5URVJGQUNFX01FVEhPRF9SRVNPTFVUSU9OLCAwLAotICAgICAgICAgICAgICAgICAgICAgY3MsIDAsIEV4Y2VwdGlvbkNvbnN0YW50cy5FWENTX0lOVEVSRkFDRV9NRVRIT0RfUkVTT0xVVElPTi5sZW5ndGgpOwotCi0gICAgY3NbRXhjZXB0aW9uQ29uc3RhbnRzLkVYQ1NfSU5URVJGQUNFX01FVEhPRF9SRVNPTFVUSU9OLmxlbmd0aCszXSA9IEV4Y2VwdGlvbkNvbnN0YW50cy5JTkNPTVBBVElCTEVfQ0xBU1NfQ0hBTkdFX0VSUk9SOwotICAgIGNzW0V4Y2VwdGlvbkNvbnN0YW50cy5FWENTX0lOVEVSRkFDRV9NRVRIT0RfUkVTT0xVVElPTi5sZW5ndGgrMl0gPSBFeGNlcHRpb25Db25zdGFudHMuSUxMRUdBTF9BQ0NFU1NfRVJST1I7Ci0gICAgY3NbRXhjZXB0aW9uQ29uc3RhbnRzLkVYQ1NfSU5URVJGQUNFX01FVEhPRF9SRVNPTFVUSU9OLmxlbmd0aCsxXSA9IEV4Y2VwdGlvbkNvbnN0YW50cy5BQlNUUkFDVF9NRVRIT0RfRVJST1I7Ci0gICAgY3NbRXhjZXB0aW9uQ29uc3RhbnRzLkVYQ1NfSU5URVJGQUNFX01FVEhPRF9SRVNPTFVUSU9OLmxlbmd0aF0gICA9IEV4Y2VwdGlvbkNvbnN0YW50cy5VTlNBVElTRklFRF9MSU5LX0VSUk9SOwotCi0gICAgcmV0dXJuIGNzOwotICB9Ci0KLSAgLyoqCi0gICAqIENhbGwgY29ycmVzcG9uZGluZyB2aXNpdG9yIG1ldGhvZChzKS4gVGhlIG9yZGVyIGlzOgotICAgKiBDYWxsIHZpc2l0b3IgbWV0aG9kcyBvZiBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzIGZpcnN0LCB0aGVuCi0gICAqIGNhbGwgbWV0aG9kcyBhY2NvcmRpbmcgdG8gdGhlIGNsYXNzIGhpZXJhcmNoeSBpbiBkZXNjZW5kaW5nIG9yZGVyLAotICAgKiBpLmUuLCB0aGUgbW9zdCBzcGVjaWZpYyB2aXNpdFhYWCgpIGNhbGwgY29tZXMgbGFzdC4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0RXhjZXB0aW9uVGhyb3dlcih0aGlzKTsKLSAgICB2LnZpc2l0VHlwZWRJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tDb25zdW1lcih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tQcm9kdWNlcih0aGlzKTsKLSAgICB2LnZpc2l0TG9hZENsYXNzKHRoaXMpOwotICAgIHYudmlzaXRDUEluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRGaWVsZE9yTWV0aG9kKHRoaXMpOwotICAgIHYudmlzaXRJbnZva2VJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0SU5WT0tFSU5URVJGQUNFKHRoaXMpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JTlZPS0VTUEVDSUFMLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JTlZPS0VTUEVDSUFMLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGQ0MGRlZWQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSU5WT0tFU1BFQ0lBTC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTE2ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkV4Y2VwdGlvbkNvbnN0YW50czsKLQotLyoqCi0gKiBJTlZPS0VTUEVDSUFMIC0gSW52b2tlIGluc3RhbmNlIG1ldGhvZDsgc3BlY2lhbCBoYW5kbGluZyBmb3Igc3VwZXJjbGFzcywgcHJpdmF0ZQotICogYW5kIGluc3RhbmNlIGluaXRpYWxpemF0aW9uIG1ldGhvZCBpbnZvY2F0aW9ucwotICoKLSAqIDxQUkU+U3RhY2s6IC4uLiwgb2JqZWN0cmVmLCBbYXJnMSwgW2FyZzIgLi4uXV0gLSZndDsgLi4uPC9QUkU+Ci0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGNsYXNzIElOVk9LRVNQRUNJQUwgZXh0ZW5kcyBJbnZva2VJbnN0cnVjdGlvbiB7Ci0gIC8qKgotICAgKiBFbXB0eSBjb25zdHJ1Y3RvciBuZWVkZWQgZm9yIHRoZSBDbGFzcy5uZXdJbnN0YW5jZSgpIHN0YXRlbWVudCBpbgotICAgKiBJbnN0cnVjdGlvbi5yZWFkSW5zdHJ1Y3Rpb24oKS4gTm90IHRvIGJlIHVzZWQgb3RoZXJ3aXNlLgotICAgKi8KLSAgSU5WT0tFU1BFQ0lBTCgpIHt9Ci0KLSAgcHVibGljIElOVk9LRVNQRUNJQUwoaW50IGluZGV4KSB7Ci0gICAgc3VwZXIoQ29uc3RhbnRzLklOVk9LRVNQRUNJQUwsIGluZGV4KTsKLSAgfQotCi0gIHB1YmxpYyBDbGFzc1tdIGdldEV4Y2VwdGlvbnMoKSB7Ci0gICAgQ2xhc3NbXSBjcyA9IG5ldyBDbGFzc1s0ICsgRXhjZXB0aW9uQ29uc3RhbnRzLkVYQ1NfRklFTERfQU5EX01FVEhPRF9SRVNPTFVUSU9OLmxlbmd0aF07Ci0KLSAgICBTeXN0ZW0uYXJyYXljb3B5KEV4Y2VwdGlvbkNvbnN0YW50cy5FWENTX0ZJRUxEX0FORF9NRVRIT0RfUkVTT0xVVElPTiwgMCwKLSAgICAgICAgICAgICAgICAgICAgIGNzLCAwLCBFeGNlcHRpb25Db25zdGFudHMuRVhDU19GSUVMRF9BTkRfTUVUSE9EX1JFU09MVVRJT04ubGVuZ3RoKTsKLQotICAgIGNzW0V4Y2VwdGlvbkNvbnN0YW50cy5FWENTX0ZJRUxEX0FORF9NRVRIT0RfUkVTT0xVVElPTi5sZW5ndGgrM10gPSBFeGNlcHRpb25Db25zdGFudHMuVU5TQVRJU0ZJRURfTElOS19FUlJPUjsKLSAgICBjc1tFeGNlcHRpb25Db25zdGFudHMuRVhDU19GSUVMRF9BTkRfTUVUSE9EX1JFU09MVVRJT04ubGVuZ3RoKzJdID0gRXhjZXB0aW9uQ29uc3RhbnRzLkFCU1RSQUNUX01FVEhPRF9FUlJPUjsKLSAgICBjc1tFeGNlcHRpb25Db25zdGFudHMuRVhDU19GSUVMRF9BTkRfTUVUSE9EX1JFU09MVVRJT04ubGVuZ3RoKzFdID0gRXhjZXB0aW9uQ29uc3RhbnRzLklOQ09NUEFUSUJMRV9DTEFTU19DSEFOR0VfRVJST1I7Ci0gICAgY3NbRXhjZXB0aW9uQ29uc3RhbnRzLkVYQ1NfRklFTERfQU5EX01FVEhPRF9SRVNPTFVUSU9OLmxlbmd0aF0gICA9IEV4Y2VwdGlvbkNvbnN0YW50cy5OVUxMX1BPSU5URVJfRVhDRVBUSU9OOwotCi0gICAgcmV0dXJuIGNzOwotICB9Ci0KLQotICAvKioKLSAgICogQ2FsbCBjb3JyZXNwb25kaW5nIHZpc2l0b3IgbWV0aG9kKHMpLiBUaGUgb3JkZXIgaXM6Ci0gICAqIENhbGwgdmlzaXRvciBtZXRob2RzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMgZmlyc3QsIHRoZW4KLSAgICogY2FsbCBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY2xhc3MgaGllcmFyY2h5IGluIGRlc2NlbmRpbmcgb3JkZXIsCi0gICAqIGkuZS4sIHRoZSBtb3N0IHNwZWNpZmljIHZpc2l0WFhYKCkgY2FsbCBjb21lcyBsYXN0LgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRFeGNlcHRpb25UaHJvd2VyKHRoaXMpOwotICAgIHYudmlzaXRUeXBlZEluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRTdGFja0NvbnN1bWVyKHRoaXMpOwotICAgIHYudmlzaXRTdGFja1Byb2R1Y2VyKHRoaXMpOwotICAgIHYudmlzaXRMb2FkQ2xhc3ModGhpcyk7Ci0gICAgdi52aXNpdENQSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdEZpZWxkT3JNZXRob2QodGhpcyk7Ci0gICAgdi52aXNpdEludm9rZUluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRJTlZPS0VTUEVDSUFMKHRoaXMpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JTlZPS0VTVEFUSUMuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0lOVk9LRVNUQVRJQy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyYTMyYzY5Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0lOVk9LRVNUQVRJQy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTEzICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkV4Y2VwdGlvbkNvbnN0YW50czsKLQotLyoqCi0gKiBJTlZPS0VTVEFUSUMgLSBJbnZva2UgYSBjbGFzcyAoc3RhdGljKSBtZXRob2QKLSAqCi0gKiA8UFJFPlN0YWNrOiAuLi4sIFthcmcxLCBbYXJnMiAuLi5dXSAtJmd0OyAuLi48L1BSRT4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgSU5WT0tFU1RBVElDIGV4dGVuZHMgSW52b2tlSW5zdHJ1Y3Rpb24gewotICAvKioKLSAgICogRW1wdHkgY29uc3RydWN0b3IgbmVlZGVkIGZvciB0aGUgQ2xhc3MubmV3SW5zdGFuY2UoKSBzdGF0ZW1lbnQgaW4KLSAgICogSW5zdHJ1Y3Rpb24ucmVhZEluc3RydWN0aW9uKCkuIE5vdCB0byBiZSB1c2VkIG90aGVyd2lzZS4KLSAgICovCi0gIElOVk9LRVNUQVRJQygpIHt9Ci0KLSAgcHVibGljIElOVk9LRVNUQVRJQyhpbnQgaW5kZXgpIHsKLSAgICBzdXBlcihDb25zdGFudHMuSU5WT0tFU1RBVElDLCBpbmRleCk7Ci0gIH0KLQotICBwdWJsaWMgQ2xhc3NbXSBnZXRFeGNlcHRpb25zKCkgewotICAgIENsYXNzW10gY3MgPSBuZXcgQ2xhc3NbMiArIEV4Y2VwdGlvbkNvbnN0YW50cy5FWENTX0ZJRUxEX0FORF9NRVRIT0RfUkVTT0xVVElPTi5sZW5ndGhdOwotCi0gICAgU3lzdGVtLmFycmF5Y29weShFeGNlcHRpb25Db25zdGFudHMuRVhDU19GSUVMRF9BTkRfTUVUSE9EX1JFU09MVVRJT04sIDAsCi0gICAgICAgICAgICAgICAgICAgICBjcywgMCwgRXhjZXB0aW9uQ29uc3RhbnRzLkVYQ1NfRklFTERfQU5EX01FVEhPRF9SRVNPTFVUSU9OLmxlbmd0aCk7Ci0KLSAgICBjc1tFeGNlcHRpb25Db25zdGFudHMuRVhDU19GSUVMRF9BTkRfTUVUSE9EX1JFU09MVVRJT04ubGVuZ3RoXSA9IEV4Y2VwdGlvbkNvbnN0YW50cy5VTlNBVElTRklFRF9MSU5LX0VSUk9SOwotICAgIGNzW0V4Y2VwdGlvbkNvbnN0YW50cy5FWENTX0ZJRUxEX0FORF9NRVRIT0RfUkVTT0xVVElPTi5sZW5ndGgrMV0gPSBFeGNlcHRpb25Db25zdGFudHMuSU5DT01QQVRJQkxFX0NMQVNTX0NIQU5HRV9FUlJPUjsKLQotICAgIHJldHVybiBjczsKLSAgfQotCi0KLSAgLyoqCi0gICAqIENhbGwgY29ycmVzcG9uZGluZyB2aXNpdG9yIG1ldGhvZChzKS4gVGhlIG9yZGVyIGlzOgotICAgKiBDYWxsIHZpc2l0b3IgbWV0aG9kcyBvZiBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzIGZpcnN0LCB0aGVuCi0gICAqIGNhbGwgbWV0aG9kcyBhY2NvcmRpbmcgdG8gdGhlIGNsYXNzIGhpZXJhcmNoeSBpbiBkZXNjZW5kaW5nIG9yZGVyLAotICAgKiBpLmUuLCB0aGUgbW9zdCBzcGVjaWZpYyB2aXNpdFhYWCgpIGNhbGwgY29tZXMgbGFzdC4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0RXhjZXB0aW9uVGhyb3dlcih0aGlzKTsKLSAgICB2LnZpc2l0VHlwZWRJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tDb25zdW1lcih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tQcm9kdWNlcih0aGlzKTsKLSAgICB2LnZpc2l0TG9hZENsYXNzKHRoaXMpOwotICAgIHYudmlzaXRDUEluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRGaWVsZE9yTWV0aG9kKHRoaXMpOwotICAgIHYudmlzaXRJbnZva2VJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0SU5WT0tFU1RBVElDKHRoaXMpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JTlZPS0VWSVJUVUFMLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JTlZPS0VWSVJUVUFMLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGE0ZmZlNWIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSU5WT0tFVklSVFVBTC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTE1ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkV4Y2VwdGlvbkNvbnN0YW50czsKLQotLyoqCi0gKiBJTlZPS0VWSVJUVUFMIC0gSW52b2tlIGluc3RhbmNlIG1ldGhvZDsgZGlzcGF0Y2ggYmFzZWQgb24gY2xhc3MKLSAqCi0gKiA8UFJFPlN0YWNrOiAuLi4sIG9iamVjdHJlZiwgW2FyZzEsIFthcmcyIC4uLl1dIC0mZ3Q7IC4uLjwvUFJFPgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBJTlZPS0VWSVJUVUFMIGV4dGVuZHMgSW52b2tlSW5zdHJ1Y3Rpb24gewotICAvKioKLSAgICogRW1wdHkgY29uc3RydWN0b3IgbmVlZGVkIGZvciB0aGUgQ2xhc3MubmV3SW5zdGFuY2UoKSBzdGF0ZW1lbnQgaW4KLSAgICogSW5zdHJ1Y3Rpb24ucmVhZEluc3RydWN0aW9uKCkuIE5vdCB0byBiZSB1c2VkIG90aGVyd2lzZS4KLSAgICovCi0gIElOVk9LRVZJUlRVQUwoKSB7fQotCi0gIHB1YmxpYyBJTlZPS0VWSVJUVUFMKGludCBpbmRleCkgewotICAgIHN1cGVyKENvbnN0YW50cy5JTlZPS0VWSVJUVUFMLCBpbmRleCk7Ci0gIH0KLQotICBwdWJsaWMgQ2xhc3NbXSBnZXRFeGNlcHRpb25zKCkgewotICAgIENsYXNzW10gY3MgPSBuZXcgQ2xhc3NbNCArIEV4Y2VwdGlvbkNvbnN0YW50cy5FWENTX0ZJRUxEX0FORF9NRVRIT0RfUkVTT0xVVElPTi5sZW5ndGhdOwotCi0gICAgU3lzdGVtLmFycmF5Y29weShFeGNlcHRpb25Db25zdGFudHMuRVhDU19GSUVMRF9BTkRfTUVUSE9EX1JFU09MVVRJT04sIDAsCi0gICAgICAgICAgICAgICAgICAgICBjcywgMCwgRXhjZXB0aW9uQ29uc3RhbnRzLkVYQ1NfRklFTERfQU5EX01FVEhPRF9SRVNPTFVUSU9OLmxlbmd0aCk7Ci0KLSAgICBjc1tFeGNlcHRpb25Db25zdGFudHMuRVhDU19GSUVMRF9BTkRfTUVUSE9EX1JFU09MVVRJT04ubGVuZ3RoKzNdID0gRXhjZXB0aW9uQ29uc3RhbnRzLlVOU0FUSVNGSUVEX0xJTktfRVJST1I7Ci0gICAgY3NbRXhjZXB0aW9uQ29uc3RhbnRzLkVYQ1NfRklFTERfQU5EX01FVEhPRF9SRVNPTFVUSU9OLmxlbmd0aCsyXSA9IEV4Y2VwdGlvbkNvbnN0YW50cy5BQlNUUkFDVF9NRVRIT0RfRVJST1I7Ci0gICAgY3NbRXhjZXB0aW9uQ29uc3RhbnRzLkVYQ1NfRklFTERfQU5EX01FVEhPRF9SRVNPTFVUSU9OLmxlbmd0aCsxXSA9IEV4Y2VwdGlvbkNvbnN0YW50cy5JTkNPTVBBVElCTEVfQ0xBU1NfQ0hBTkdFX0VSUk9SOwotICAgIGNzW0V4Y2VwdGlvbkNvbnN0YW50cy5FWENTX0ZJRUxEX0FORF9NRVRIT0RfUkVTT0xVVElPTi5sZW5ndGhdICAgPSBFeGNlcHRpb25Db25zdGFudHMuTlVMTF9QT0lOVEVSX0VYQ0VQVElPTjsKLQotICAgIHJldHVybiBjczsKLSAgfQotCi0KLSAgLyoqCi0gICAqIENhbGwgY29ycmVzcG9uZGluZyB2aXNpdG9yIG1ldGhvZChzKS4gVGhlIG9yZGVyIGlzOgotICAgKiBDYWxsIHZpc2l0b3IgbWV0aG9kcyBvZiBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzIGZpcnN0LCB0aGVuCi0gICAqIGNhbGwgbWV0aG9kcyBhY2NvcmRpbmcgdG8gdGhlIGNsYXNzIGhpZXJhcmNoeSBpbiBkZXNjZW5kaW5nIG9yZGVyLAotICAgKiBpLmUuLCB0aGUgbW9zdCBzcGVjaWZpYyB2aXNpdFhYWCgpIGNhbGwgY29tZXMgbGFzdC4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0RXhjZXB0aW9uVGhyb3dlcih0aGlzKTsKLSAgICB2LnZpc2l0VHlwZWRJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tDb25zdW1lcih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tQcm9kdWNlcih0aGlzKTsKLSAgICB2LnZpc2l0TG9hZENsYXNzKHRoaXMpOwotICAgIHYudmlzaXRDUEluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRGaWVsZE9yTWV0aG9kKHRoaXMpOwotICAgIHYudmlzaXRJbnZva2VJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0SU5WT0tFVklSVFVBTCh0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSU9SLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JT1IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOGNmMGYwOS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JT1IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDg4ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8qKgotICogSU9SIC0gQml0d2lzZSBPUiBpbnQKLSAqIDxQUkU+U3RhY2s6IC4uLiwgdmFsdWUxLCB2YWx1ZTIgLSZndDsgLi4uLCByZXN1bHQ8L1BSRT4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgSU9SIGV4dGVuZHMgQXJpdGhtZXRpY0luc3RydWN0aW9uIHsKLSAgcHVibGljIElPUigpIHsKLSAgICBzdXBlcihjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuSU9SKTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIENhbGwgY29ycmVzcG9uZGluZyB2aXNpdG9yIG1ldGhvZChzKS4gVGhlIG9yZGVyIGlzOgotICAgKiBDYWxsIHZpc2l0b3IgbWV0aG9kcyBvZiBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzIGZpcnN0LCB0aGVuCi0gICAqIGNhbGwgbWV0aG9kcyBhY2NvcmRpbmcgdG8gdGhlIGNsYXNzIGhpZXJhcmNoeSBpbiBkZXNjZW5kaW5nIG9yZGVyLAotICAgKiBpLmUuLCB0aGUgbW9zdCBzcGVjaWZpYyB2aXNpdFhYWCgpIGNhbGwgY29tZXMgbGFzdC4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0VHlwZWRJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tQcm9kdWNlcih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tDb25zdW1lcih0aGlzKTsKLSAgICB2LnZpc2l0QXJpdGhtZXRpY0luc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRJT1IodGhpcyk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0lSRU0uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0lSRU0uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNjUwZjc3My4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JUkVNLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5NyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIElSRU0gLSBSZW1haW5kZXIgb2YgaW50Ci0gKiA8UFJFPlN0YWNrOiAuLi4sIHZhbHVlMSwgdmFsdWUyIC0mZ3Q7IHJlc3VsdDwvUFJFPgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBJUkVNIGV4dGVuZHMgQXJpdGhtZXRpY0luc3RydWN0aW9uIGltcGxlbWVudHMgRXhjZXB0aW9uVGhyb3dlciB7Ci0gIC8qKiBSZW1haW5kZXIgb2YgaW50cwotICAgKi8KLSAgcHVibGljIElSRU0oKSB7Ci0gICAgc3VwZXIoY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLklSRU0pOwotICB9Ci0KLSAgLyoqIEByZXR1cm4gZXhjZXB0aW9ucyB0aGlzIGluc3RydWN0aW9uIG1heSBjYXVzZQotICAgKi8KLSAgcHVibGljIENsYXNzW10gZ2V0RXhjZXB0aW9ucygpIHsKLSAgICByZXR1cm4gbmV3IENsYXNzW10geyBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5FeGNlcHRpb25Db25zdGFudHMuQVJJVEhNRVRJQ19FWENFUFRJT04gfTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIENhbGwgY29ycmVzcG9uZGluZyB2aXNpdG9yIG1ldGhvZChzKS4gVGhlIG9yZGVyIGlzOgotICAgKiBDYWxsIHZpc2l0b3IgbWV0aG9kcyBvZiBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzIGZpcnN0LCB0aGVuCi0gICAqIGNhbGwgbWV0aG9kcyBhY2NvcmRpbmcgdG8gdGhlIGNsYXNzIGhpZXJhcmNoeSBpbiBkZXNjZW5kaW5nIG9yZGVyLAotICAgKiBpLmUuLCB0aGUgbW9zdCBzcGVjaWZpYyB2aXNpdFhYWCgpIGNhbGwgY29tZXMgbGFzdC4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0RXhjZXB0aW9uVGhyb3dlcih0aGlzKTsKLSAgICB2LnZpc2l0VHlwZWRJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tQcm9kdWNlcih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tDb25zdW1lcih0aGlzKTsKLSAgICB2LnZpc2l0QXJpdGhtZXRpY0luc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRJUkVNKHRoaXMpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JUkVUVVJOLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JUkVUVVJOLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDk2NzhiNWIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSVJFVFVSTi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTAgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotLyoqCi0gKiBJUkVUVVJOIC0gIFJldHVybiBpbnQgZnJvbSBtZXRob2QKLSAqIDxQUkU+U3RhY2s6IC4uLiwgdmFsdWUgLSZndDsgJmx0O2VtcHR5Jmd0OzwvUFJFPgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBJUkVUVVJOIGV4dGVuZHMgUmV0dXJuSW5zdHJ1Y3Rpb24gewotICAvKiogUmV0dXJuIGludCBmcm9tIG1ldGhvZAotICAgKi8KLSAgcHVibGljIElSRVRVUk4oKSB7Ci0gICAgc3VwZXIoY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLklSRVRVUk4pOwotICB9Ci0KLQotICAvKioKLSAgICogQ2FsbCBjb3JyZXNwb25kaW5nIHZpc2l0b3IgbWV0aG9kKHMpLiBUaGUgb3JkZXIgaXM6Ci0gICAqIENhbGwgdmlzaXRvciBtZXRob2RzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMgZmlyc3QsIHRoZW4KLSAgICogY2FsbCBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY2xhc3MgaGllcmFyY2h5IGluIGRlc2NlbmRpbmcgb3JkZXIsCi0gICAqIGkuZS4sIHRoZSBtb3N0IHNwZWNpZmljIHZpc2l0WFhYKCkgY2FsbCBjb21lcyBsYXN0LgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRFeGNlcHRpb25UaHJvd2VyKHRoaXMpOwotICAgIHYudmlzaXRUeXBlZEluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRTdGFja0NvbnN1bWVyKHRoaXMpOwotICAgIHYudmlzaXRSZXR1cm5JbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0SVJFVFVSTih0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSVNITC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSVNITC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1ZjI2YjlhLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0lTSEwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDg4ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8qKgotICogSVNITCAtIEFyaXRobWV0aWMgc2hpZnQgbGVmdCBpbnQKLSAqIDxQUkU+U3RhY2s6IC4uLiwgdmFsdWUxLCB2YWx1ZTIgLSZndDsgLi4uLCByZXN1bHQ8L1BSRT4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgSVNITCBleHRlbmRzIEFyaXRobWV0aWNJbnN0cnVjdGlvbiB7Ci0gIHB1YmxpYyBJU0hMKCkgewotICAgIHN1cGVyKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5JU0hMKTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIENhbGwgY29ycmVzcG9uZGluZyB2aXNpdG9yIG1ldGhvZChzKS4gVGhlIG9yZGVyIGlzOgotICAgKiBDYWxsIHZpc2l0b3IgbWV0aG9kcyBvZiBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzIGZpcnN0LCB0aGVuCi0gICAqIGNhbGwgbWV0aG9kcyBhY2NvcmRpbmcgdG8gdGhlIGNsYXNzIGhpZXJhcmNoeSBpbiBkZXNjZW5kaW5nIG9yZGVyLAotICAgKiBpLmUuLCB0aGUgbW9zdCBzcGVjaWZpYyB2aXNpdFhYWCgpIGNhbGwgY29tZXMgbGFzdC4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0VHlwZWRJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tQcm9kdWNlcih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tDb25zdW1lcih0aGlzKTsKLSAgICB2LnZpc2l0QXJpdGhtZXRpY0luc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRJU0hMKHRoaXMpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JU0hSLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JU0hSLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDZhM2NiM2UuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSVNIUi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsODggKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotLyoqCi0gKiBJU0hSIC0gQXJpdGhtZXRpYyBzaGlmdCByaWdodCBpbnQKLSAqIDxQUkU+U3RhY2s6IC4uLiwgdmFsdWUxLCB2YWx1ZTIgLSZndDsgLi4uLCByZXN1bHQ8L1BSRT4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgSVNIUiBleHRlbmRzIEFyaXRobWV0aWNJbnN0cnVjdGlvbiB7Ci0gIHB1YmxpYyBJU0hSKCkgewotICAgIHN1cGVyKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5JU0hSKTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIENhbGwgY29ycmVzcG9uZGluZyB2aXNpdG9yIG1ldGhvZChzKS4gVGhlIG9yZGVyIGlzOgotICAgKiBDYWxsIHZpc2l0b3IgbWV0aG9kcyBvZiBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzIGZpcnN0LCB0aGVuCi0gICAqIGNhbGwgbWV0aG9kcyBhY2NvcmRpbmcgdG8gdGhlIGNsYXNzIGhpZXJhcmNoeSBpbiBkZXNjZW5kaW5nIG9yZGVyLAotICAgKiBpLmUuLCB0aGUgbW9zdCBzcGVjaWZpYyB2aXNpdFhYWCgpIGNhbGwgY29tZXMgbGFzdC4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0VHlwZWRJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tQcm9kdWNlcih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tDb25zdW1lcih0aGlzKTsKLSAgICB2LnZpc2l0QXJpdGhtZXRpY0luc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRJU0hSKHRoaXMpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JU1RPUkUuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0lTVE9SRS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyMmNkMTRkLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0lTVE9SRS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTUgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotLyoqCi0gKiBJU1RPUkUgLSBTdG9yZSBpbnQgZnJvbSBzdGFjayBpbnRvIGxvY2FsIHZhcmlhYmxlCi0gKiA8UFJFPlN0YWNrOiAuLi4sIHZhbHVlIC0mZ3Q7IC4uLiA8L1BSRT4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgSVNUT1JFIGV4dGVuZHMgU3RvcmVJbnN0cnVjdGlvbiB7Ci0gIC8qKgotICAgKiBFbXB0eSBjb25zdHJ1Y3RvciBuZWVkZWQgZm9yIHRoZSBDbGFzcy5uZXdJbnN0YW5jZSgpIHN0YXRlbWVudCBpbgotICAgKiBJbnN0cnVjdGlvbi5yZWFkSW5zdHJ1Y3Rpb24oKS4gTm90IHRvIGJlIHVzZWQgb3RoZXJ3aXNlLgotICAgKi8KLSAgSVNUT1JFKCkgewotICAgIHN1cGVyKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5JU1RPUkUsIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5JU1RPUkVfMCk7Ci0gIH0KLQotICAvKiogU3RvcmUgaW50IGludG8gbG9jYWwgdmFyaWFibGUKLSAgICogQHBhcmFtIG4gaW5kZXggb2YgbG9jYWwgdmFyaWFibGUKLSAgICovCi0gIHB1YmxpYyBJU1RPUkUoaW50IG4pIHsKLSAgICBzdXBlcihjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuSVNUT1JFLCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuSVNUT1JFXzAsIG4pOwotICB9Ci0KLSAgLyoqCi0gICAqIENhbGwgY29ycmVzcG9uZGluZyB2aXNpdG9yIG1ldGhvZChzKS4gVGhlIG9yZGVyIGlzOgotICAgKiBDYWxsIHZpc2l0b3IgbWV0aG9kcyBvZiBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzIGZpcnN0LCB0aGVuCi0gICAqIGNhbGwgbWV0aG9kcyBhY2NvcmRpbmcgdG8gdGhlIGNsYXNzIGhpZXJhcmNoeSBpbiBkZXNjZW5kaW5nIG9yZGVyLAotICAgKiBpLmUuLCB0aGUgbW9zdCBzcGVjaWZpYyB2aXNpdFhYWCgpIGNhbGwgY29tZXMgbGFzdC4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICBzdXBlci5hY2NlcHQodik7Ci0gICAgdi52aXNpdElTVE9SRSh0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSVNVQi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSVNVQi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0MTNlOWQ0Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0lTVUIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDkwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8qKgotICogSVNVQiAtIFN1YnN0cmFjdCBpbnRzCi0gKiA8UFJFPlN0YWNrOiAuLi4sIHZhbHVlMSwgdmFsdWUyIC0mZ3Q7IHJlc3VsdDwvUFJFPgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBJU1VCIGV4dGVuZHMgQXJpdGhtZXRpY0luc3RydWN0aW9uIHsKLSAgLyoqIFN1YnN0cmFjdCBpbnRzCi0gICAqLwotICBwdWJsaWMgSVNVQigpIHsKLSAgICBzdXBlcihjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuSVNVQik7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBDYWxsIGNvcnJlc3BvbmRpbmcgdmlzaXRvciBtZXRob2QocykuIFRoZSBvcmRlciBpczoKLSAgICogQ2FsbCB2aXNpdG9yIG1ldGhvZHMgb2YgaW1wbGVtZW50ZWQgaW50ZXJmYWNlcyBmaXJzdCwgdGhlbgotICAgKiBjYWxsIG1ldGhvZHMgYWNjb3JkaW5nIHRvIHRoZSBjbGFzcyBoaWVyYXJjaHkgaW4gZGVzY2VuZGluZyBvcmRlciwKLSAgICogaS5lLiwgdGhlIG1vc3Qgc3BlY2lmaWMgdmlzaXRYWFgoKSBjYWxsIGNvbWVzIGxhc3QuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgdi52aXNpdFR5cGVkSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdFN0YWNrUHJvZHVjZXIodGhpcyk7Ci0gICAgdi52aXNpdFN0YWNrQ29uc3VtZXIodGhpcyk7Ci0gICAgdi52aXNpdEFyaXRobWV0aWNJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0SVNVQih0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSVVTSFIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0lVU0hSLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDkxN2FkMzkuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSVVTSFIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDg4ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8qKgotICogSVVTSFIgLSBMb2dpY2FsIHNoaWZ0IHJpZ2h0IGludAotICogPFBSRT5TdGFjazogLi4uLCB2YWx1ZTEsIHZhbHVlMiAtJmd0OyAuLi4sIHJlc3VsdDwvUFJFPgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBJVVNIUiBleHRlbmRzIEFyaXRobWV0aWNJbnN0cnVjdGlvbiB7Ci0gIHB1YmxpYyBJVVNIUigpIHsKLSAgICBzdXBlcihjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuSVVTSFIpOwotICB9Ci0KLQotICAvKioKLSAgICogQ2FsbCBjb3JyZXNwb25kaW5nIHZpc2l0b3IgbWV0aG9kKHMpLiBUaGUgb3JkZXIgaXM6Ci0gICAqIENhbGwgdmlzaXRvciBtZXRob2RzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMgZmlyc3QsIHRoZW4KLSAgICogY2FsbCBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY2xhc3MgaGllcmFyY2h5IGluIGRlc2NlbmRpbmcgb3JkZXIsCi0gICAqIGkuZS4sIHRoZSBtb3N0IHNwZWNpZmljIHZpc2l0WFhYKCkgY2FsbCBjb21lcyBsYXN0LgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRUeXBlZEluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRTdGFja1Byb2R1Y2VyKHRoaXMpOwotICAgIHYudmlzaXRTdGFja0NvbnN1bWVyKHRoaXMpOwotICAgIHYudmlzaXRBcml0aG1ldGljSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdElVU0hSKHRoaXMpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JWE9SLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JWE9SLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGQ1MWFkNmMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSVhPUi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsODggKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotLyoqCi0gKiBJWE9SIC0gQml0d2lzZSBYT1IgaW50Ci0gKiA8UFJFPlN0YWNrOiAuLi4sIHZhbHVlMSwgdmFsdWUyIC0mZ3Q7IC4uLiwgcmVzdWx0PC9QUkU+Ci0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGNsYXNzIElYT1IgZXh0ZW5kcyBBcml0aG1ldGljSW5zdHJ1Y3Rpb24gewotICBwdWJsaWMgSVhPUigpIHsKLSAgICBzdXBlcihjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuSVhPUik7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBDYWxsIGNvcnJlc3BvbmRpbmcgdmlzaXRvciBtZXRob2QocykuIFRoZSBvcmRlciBpczoKLSAgICogQ2FsbCB2aXNpdG9yIG1ldGhvZHMgb2YgaW1wbGVtZW50ZWQgaW50ZXJmYWNlcyBmaXJzdCwgdGhlbgotICAgKiBjYWxsIG1ldGhvZHMgYWNjb3JkaW5nIHRvIHRoZSBjbGFzcyBoaWVyYXJjaHkgaW4gZGVzY2VuZGluZyBvcmRlciwKLSAgICogaS5lLiwgdGhlIG1vc3Qgc3BlY2lmaWMgdmlzaXRYWFgoKSBjYWxsIGNvbWVzIGxhc3QuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgdi52aXNpdFR5cGVkSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdFN0YWNrUHJvZHVjZXIodGhpcyk7Ci0gICAgdi52aXNpdFN0YWNrQ29uc3VtZXIodGhpcyk7Ci0gICAgdi52aXNpdEFyaXRobWV0aWNJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0SVhPUih0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSWZJbnN0cnVjdGlvbi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSWZJbnN0cnVjdGlvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlNWZhNDg0Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0lmSW5zdHJ1Y3Rpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDg0ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8qKgotICogU3VwZXIgY2xhc3MgZm9yIHRoZSBJRnh4eCBmYW1pbHkgb2YgaW5zdHJ1Y3Rpb25zLgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBJZkluc3RydWN0aW9uIGV4dGVuZHMgQnJhbmNoSW5zdHJ1Y3Rpb24gaW1wbGVtZW50cyBTdGFja0NvbnN1bWVyIHsKLSAgLyoqCi0gICAqIEVtcHR5IGNvbnN0cnVjdG9yIG5lZWRlZCBmb3IgdGhlIENsYXNzLm5ld0luc3RhbmNlKCkgc3RhdGVtZW50IGluCi0gICAqIEluc3RydWN0aW9uLnJlYWRJbnN0cnVjdGlvbigpLiBOb3QgdG8gYmUgdXNlZCBvdGhlcndpc2UuCi0gICAqLwotICBJZkluc3RydWN0aW9uKCkge30KLQotICAvKioKLSAgICogQHBhcmFtIGluc3RydWN0aW9uIFRhcmdldCBpbnN0cnVjdGlvbiB0byBicmFuY2ggdG8KLSAgICovCi0gIHByb3RlY3RlZCBJZkluc3RydWN0aW9uKHNob3J0IG9wY29kZSwgSW5zdHJ1Y3Rpb25IYW5kbGUgdGFyZ2V0KSB7Ci0gICAgc3VwZXIob3Bjb2RlLCB0YXJnZXQpOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gbmVnYXRpb24gb2YgaW5zdHJ1Y3Rpb24sIGUuZy4gSUZFUS5uZWdhdGUoKSA9PSBJRk5FCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgSWZJbnN0cnVjdGlvbiBuZWdhdGUoKTsKLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0luZGV4ZWRJbnN0cnVjdGlvbi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSW5kZXhlZEluc3RydWN0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGRiOGUwNWYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSW5kZXhlZEluc3RydWN0aW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3MCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIERlbm90ZSBlbnRpdHkgdGhhdCByZWZlcnMgdG8gYW4gaW5kZXgsIGUuZy4gbG9jYWwgdmFyaWFibGUgaW5zdHJ1Y3Rpb25zLAotICogUkVULCBDUEluc3RydWN0aW9uLCBldGMuCi0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGludGVyZmFjZSBJbmRleGVkSW5zdHJ1Y3Rpb24gewotICBwdWJsaWMgaW50IGdldEluZGV4KCk7Ci0gIHB1YmxpYyB2b2lkIHNldEluZGV4KGludCBpbmRleCk7Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JbnN0cnVjdGlvbi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSW5zdHJ1Y3Rpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZWQ1OGI1ZC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JbnN0cnVjdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzA4ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuY2xhc3NmaWxlLlV0aWxpdHk7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuY2xhc3NmaWxlLkNvbnN0YW50UG9vbDsKLWltcG9ydCBqYXZhLmlvLio7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwudXRpbC5CeXRlU2VxdWVuY2U7Ci0KLS8qKgotICogQWJzdHJhY3Qgc3VwZXIgY2xhc3MgZm9yIGFsbCBKYXZhIGJ5dGUgY29kZXMuCi0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGFic3RyYWN0IGNsYXNzIEluc3RydWN0aW9uIGltcGxlbWVudHMgQ2xvbmVhYmxlLCBTZXJpYWxpemFibGUgewotICBwcm90ZWN0ZWQgc2hvcnQgbGVuZ3RoID0gMTsgIC8vIExlbmd0aCBvZiBpbnN0cnVjdGlvbiBpbiBieXRlcwotICBwcm90ZWN0ZWQgc2hvcnQgb3Bjb2RlID0gLTE7IC8vIE9wY29kZSBudW1iZXIKLQotICBwcml2YXRlIHN0YXRpYyBJbnN0cnVjdGlvbkNvbXBhcmF0b3IgY21wID0gSW5zdHJ1Y3Rpb25Db21wYXJhdG9yLkRFRkFVTFQ7Ci0KLSAgLyoqCi0gICAqIEVtcHR5IGNvbnN0cnVjdG9yIG5lZWRlZCBmb3IgdGhlIENsYXNzLm5ld0luc3RhbmNlKCkgc3RhdGVtZW50IGluCi0gICAqIEluc3RydWN0aW9uLnJlYWRJbnN0cnVjdGlvbigpLiBOb3QgdG8gYmUgdXNlZCBvdGhlcndpc2UuCi0gICAqLwotICBJbnN0cnVjdGlvbigpIHt9Ci0KLSAgcHVibGljIEluc3RydWN0aW9uKHNob3J0IG9wY29kZSwgc2hvcnQgbGVuZ3RoKSB7Ci0gICAgdGhpcy5sZW5ndGggPSBsZW5ndGg7Ci0gICAgdGhpcy5vcGNvZGUgPSBvcGNvZGU7Ci0gIH0KLQotICAvKioKLSAgICogRHVtcCBpbnN0cnVjdGlvbiBhcyBieXRlIGNvZGUgdG8gc3RyZWFtIG91dC4KLSAgICogQHBhcmFtIG91dCBPdXRwdXQgc3RyZWFtCi0gICAqLwotICBwdWJsaWMgdm9pZCBkdW1wKERhdGFPdXRwdXRTdHJlYW0gb3V0KSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgIG91dC53cml0ZUJ5dGUob3Bjb2RlKTsgLy8gQ29tbW9uIGZvciBhbGwgaW5zdHJ1Y3Rpb25zCi0gIH0KLQotICAvKiogQHJldHVybiBuYW1lIG9mIGluc3RydWN0aW9uLCBpLmUuLCBvcGNvZGUgbmFtZQotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXROYW1lKCkgewotICAgIHJldHVybiBDb25zdGFudHMuT1BDT0RFX05BTUVTW29wY29kZV07Ci0gIH0KLQotICAvKioKLSAgICogTG9uZyBvdXRwdXQgZm9ybWF0OgotICAgKgotICAgKiAmbHQ7bmFtZSBvZiBvcGNvZGUmZ3Q7ICJbIiZsdDtvcGNvZGUgbnVtYmVyJmd0OyJdIgotICAgKiAiKCImbHQ7bGVuZ3RoIG9mIGluc3RydWN0aW9uJmd0OyIpIgotICAgKgotICAgKiBAcGFyYW0gdmVyYm9zZSBsb25nL3Nob3J0IGZvcm1hdCBzd2l0Y2gKLSAgICogQHJldHVybiBtbmVtb25pYyBmb3IgaW5zdHJ1Y3Rpb24KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoYm9vbGVhbiB2ZXJib3NlKSB7Ci0gICAgaWYodmVyYm9zZSkKLSAgICAgIHJldHVybiBnZXROYW1lKCkgKyAiWyIgKyBvcGNvZGUgKyAiXSgiICsgbGVuZ3RoICsgIikiOwotICAgIGVsc2UKLSAgICAgIHJldHVybiBnZXROYW1lKCk7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBtbmVtb25pYyBmb3IgaW5zdHJ1Y3Rpb24gaW4gdmVyYm9zZSBmb3JtYXQKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0gICAgcmV0dXJuIHRvU3RyaW5nKHRydWUpOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gbW5lbW9uaWMgZm9yIGluc3RydWN0aW9uIHdpdGggc3VtYm9saWMgcmVmZXJlbmNlcyByZXNvbHZlZAotICAgKi8KLSAgcHVibGljIFN0cmluZyB0b1N0cmluZyhDb25zdGFudFBvb2wgY3ApIHsKLSAgICByZXR1cm4gdG9TdHJpbmcoZmFsc2UpOwotICB9Ci0KLSAgLyoqCi0gICAqIFVzZSB3aXRoIGNhdXRpb24sIHNpbmNlIGBCcmFuY2hJbnN0cnVjdGlvbidzIGhhdmUgYSBgdGFyZ2V0JyByZWZlcmVuY2Ugd2hpY2gKLSAgICogaXMgbm90IGNvcGllZCBjb3JyZWN0bHkgKG9ubHkgYmFzaWMgdHlwZXMgYXJlKS4gVGhpcyBhbHNvIGFwcGxpZXMgZm9yCi0gICAqIGBTZWxlY3QnIGluc3RydWN0aW9ucyB3aXRoIHRoZWlyIG11bHRpcGxlIGJyYW5jaCB0YXJnZXRzLgotICAgKgotICAgKiBAc2VlIEJyYW5jaEluc3RydWN0aW9uCi0gICAqIEByZXR1cm4gKHNoYWxsb3cpIGNvcHkgb2YgYW4gaW5zdHJ1Y3Rpb24KLSAgICovCi0gIHB1YmxpYyBJbnN0cnVjdGlvbiBjb3B5KCkgewotICAgIEluc3RydWN0aW9uIGkgPSBudWxsOwotCi0gICAgLy8gIkNvbnN0YW50IiBpbnN0cnVjdGlvbiwgbm8gbmVlZCB0byBkdXBsaWNhdGUKLSAgICBpZihJbnN0cnVjdGlvbkNvbnN0YW50cy5JTlNUUlVDVElPTlNbdGhpcy5nZXRPcGNvZGUoKV0gIT0gbnVsbCkKLSAgICAgIGkgPSB0aGlzOwotICAgIGVsc2UgewotICAgICAgdHJ5IHsKLSAgICAgICAgaSA9IChJbnN0cnVjdGlvbiljbG9uZSgpOwotICAgICAgfSBjYXRjaChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbihlKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gaTsKLSAgfQotCi0gIC8qKgotICAgKiBSZWFkIG5lZWRlZCBkYXRhIChlLmcuIGluZGV4KSBmcm9tIGZpbGUuCi0gICAqCi0gICAqIEBwYXJhbSBieXRlcyBieXRlIHNlcXVlbmNlIHRvIHJlYWQgZnJvbQotICAgKiBAcGFyYW0gd2lkZSAid2lkZSIgaW5zdHJ1Y3Rpb24gZmxhZwotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgaW5pdEZyb21GaWxlKEJ5dGVTZXF1ZW5jZSBieXRlcywgYm9vbGVhbiB3aWRlKQotICAgIHRocm93cyBJT0V4Y2VwdGlvbgotICB7fQotCi0gIC8qKgotICAgKiBSZWFkIGFuIGluc3RydWN0aW9uIGZyb20gKGJ5dGUgY29kZSkgaW5wdXQgc3RyZWFtIGFuZCByZXR1cm4gdGhlCi0gICAqIGFwcHJvcGlhdGUgb2JqZWN0LgotICAgKgotICAgKiBAcGFyYW0gZmlsZSBmaWxlIHRvIHJlYWQgZnJvbQotICAgKiBAcmV0dXJuIGluc3RydWN0aW9uIG9iamVjdCBiZWluZyByZWFkCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEluc3RydWN0aW9uIHJlYWRJbnN0cnVjdGlvbihCeXRlU2VxdWVuY2UgYnl0ZXMpCi0gICAgdGhyb3dzIElPRXhjZXB0aW9uCi0gIHsKLSAgICBib29sZWFuICAgICB3aWRlICAgPSBmYWxzZTsKLSAgICBzaG9ydCAgICAgICBvcGNvZGUgPSAoc2hvcnQpYnl0ZXMucmVhZFVuc2lnbmVkQnl0ZSgpOwotICAgIEluc3RydWN0aW9uIG9iaiAgICA9IG51bGw7Ci0KLSAgICBpZihvcGNvZGUgPT0gQ29uc3RhbnRzLldJREUpIHsgLy8gUmVhZCBuZXh0IG9wY29kZSBhZnRlciB3aWRlIGJ5dGUKLSAgICAgIHdpZGUgPSB0cnVlOwotICAgICAgb3Bjb2RlICA9IChzaG9ydClieXRlcy5yZWFkVW5zaWduZWRCeXRlKCk7Ci0gICAgfQotCi0gICAgaWYoSW5zdHJ1Y3Rpb25Db25zdGFudHMuSU5TVFJVQ1RJT05TW29wY29kZV0gIT0gbnVsbCkKLSAgICAgIHJldHVybiBJbnN0cnVjdGlvbkNvbnN0YW50cy5JTlNUUlVDVElPTlNbb3Bjb2RlXTsgLy8gVXNlZCBwcmVkZWZpbmVkIGltbXV0YWJsZSBvYmplY3QsIGlmIGF2YWlsYWJsZQotCi0gICAgLyogRmluZCBhcHByb3BpYXRlIGNsYXNzLCBpbnN0YW50aWF0ZSBhbiAoZW1wdHkpIGluc3RydWN0aW9uIG9iamVjdAotICAgICAqIGFuZCBpbml0aWFsaXplIGl0IGJ5IGhhbmQuCi0gICAgICovCi0gICAgQ2xhc3MgY2xheno7Ci0KLSAgICB0cnkgewotICAgICAgY2xhenogPSBDbGFzcy5mb3JOYW1lKGNsYXNzTmFtZShvcGNvZGUpKTsKLSAgICB9IGNhdGNoIChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGNuZmUpewotICAgICAgLy8gSWYgYSBjbGFzcyBieSB0aGF0IG5hbWUgZG9lcyBub3QgZXhpc3QsIHRoZSBvcGNvZGUgaXMgaWxsZWdhbC4KLSAgICAgIC8vIE5vdGUgdGhhdCBJTVBERVAxLCBJTVBERVAyLCBCUkVBS1BPSU5UIGFyZSBhbHNvIGlsbGVnYWwgaW4gYSBzZW5zZS4KLSAgICAgIHRocm93IG5ldyBDbGFzc0dlbkV4Y2VwdGlvbigiSWxsZWdhbCBvcGNvZGUgZGV0ZWN0ZWQuIik7Ci0gICAgfQotCi0gICAgdHJ5IHsKLSAgICAgIG9iaiA9IChJbnN0cnVjdGlvbiljbGF6ei5uZXdJbnN0YW5jZSgpOwotCi0gICAgICBpZih3aWRlICYmICEoKG9iaiBpbnN0YW5jZW9mIExvY2FsVmFyaWFibGVJbnN0cnVjdGlvbikgfHwKLSAgICAgICAgICAgICAgICAgICAob2JqIGluc3RhbmNlb2YgSUlOQykgfHwKLSAgICAgICAgICAgICAgICAgICAob2JqIGluc3RhbmNlb2YgUkVUKSkpCi0gICAgICAgIHRocm93IG5ldyBFeGNlcHRpb24oIklsbGVnYWwgb3Bjb2RlIGFmdGVyIHdpZGU6ICIgKyBvcGNvZGUpOwotCi0gICAgICBvYmouc2V0T3Bjb2RlKG9wY29kZSk7Ci0gICAgICBvYmouaW5pdEZyb21GaWxlKGJ5dGVzLCB3aWRlKTsgLy8gRG8gZnVydGhlciBpbml0aWFsaXphdGlvbnMsIGlmIGFueQotICAgICAgLy8gQnl0ZSBjb2RlIG9mZnNldCBzZXQgaW4gSW5zdHJ1Y3Rpb25MaXN0Ci0gICAgfSBjYXRjaChFeGNlcHRpb24gZSkgeyB0aHJvdyBuZXcgQ2xhc3NHZW5FeGNlcHRpb24oZS50b1N0cmluZygpKTsgfQotCi0gICAgcmV0dXJuIG9iajsKLSAgfQotCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBjbGFzc05hbWUoc2hvcnQgb3Bjb2RlKSB7Ci0gICAgU3RyaW5nIG5hbWUgPSBDb25zdGFudHMuT1BDT0RFX05BTUVTW29wY29kZV0udG9VcHBlckNhc2UoKTsKLQotICAgIC8qIElDT05TVF8wLCBldGMuIHdpbGwgYmUgc2hvcnRlbmVkIHRvIElDT05TVCwgZXRjLiwgc2luY2UgSUNPTlNUXzAgYW5kIHRoZSBsaWtlCi0gICAgICogYXJlIG5vdCBpbXBsZW1lbnRlZCAoZGlyZWN0bHkpLgotICAgICAqLwotICAgIHRyeSB7Ci0gICAgICBpbnQgIGxlbiA9IG5hbWUubGVuZ3RoKCk7Ci0gICAgICBjaGFyIGNoMSA9IG5hbWUuY2hhckF0KGxlbiAtIDIpLCBjaDIgPSBuYW1lLmNoYXJBdChsZW4gLSAxKTsKLQotICAgICAgaWYoKGNoMSA9PSAnXycpICYmIChjaDIgPj0gJzAnKSAgJiYgKGNoMiA8PSAnNScpKQotICAgICAgICBuYW1lID0gbmFtZS5zdWJzdHJpbmcoMCwgbGVuIC0gMik7Ci0KLSAgICAgIGlmKG5hbWUuZXF1YWxzKCJJQ09OU1RfTTEiKSkgLy8gU3BlY2lhbCBjYXNlCi0gICAgICAgIG5hbWUgPSAiSUNPTlNUIjsKLSAgICB9IGNhdGNoKFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeyBTeXN0ZW0uZXJyLnByaW50bG4oZSk7IH0KLQotICAgIHJldHVybiAiY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy4iICsgbmFtZTsKLSAgfQotCi0gIC8qKgotICAgKiBUaGlzIG1ldGhvZCBhbHNvIGdpdmVzIHJpZ2h0IHJlc3VsdHMgZm9yIGluc3RydWN0aW9ucyB3aG9zZQotICAgKiBlZmZlY3Qgb24gdGhlIHN0YWNrIGRlcGVuZHMgb24gdGhlIGNvbnN0YW50IHBvb2wgZW50cnkgdGhleQotICAgKiByZWZlcmVuY2UuCi0gICAqICBAcmV0dXJuIE51bWJlciBvZiB3b3JkcyBjb25zdW1lZCBmcm9tIHN0YWNrIGJ5IHRoaXMgaW5zdHJ1Y3Rpb24sCi0gICAqIG9yIENvbnN0YW50cy5VTlBSRURJQ1RBQkxFLCBpZiB0aGlzIGNhbiBub3QgYmUgY29tcHV0ZWQgc3RhdGljYWxseQotICAgKi8KLSAgcHVibGljIGludCBjb25zdW1lU3RhY2soQ29uc3RhbnRQb29sR2VuIGNwZykgewotICAgIHJldHVybiBDb25zdGFudHMuQ09OU1VNRV9TVEFDS1tvcGNvZGVdOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoaXMgbWV0aG9kIGFsc28gZ2l2ZXMgcmlnaHQgcmVzdWx0cyBmb3IgaW5zdHJ1Y3Rpb25zIHdob3NlCi0gICAqIGVmZmVjdCBvbiB0aGUgc3RhY2sgZGVwZW5kcyBvbiB0aGUgY29uc3RhbnQgcG9vbCBlbnRyeSB0aGV5Ci0gICAqIHJlZmVyZW5jZS4KLSAgICogQHJldHVybiBOdW1iZXIgb2Ygd29yZHMgcHJvZHVjZWQgb250byBzdGFjayBieSB0aGlzIGluc3RydWN0aW9uLAotICAgKiBvciBDb25zdGFudHMuVU5QUkVESUNUQUJMRSwgaWYgdGhpcyBjYW4gbm90IGJlIGNvbXB1dGVkIHN0YXRpY2FsbHkKLSAgICovCi0gIHB1YmxpYyBpbnQgcHJvZHVjZVN0YWNrKENvbnN0YW50UG9vbEdlbiBjcGcpIHsKLSAgICByZXR1cm4gQ29uc3RhbnRzLlBST0RVQ0VfU1RBQ0tbb3Bjb2RlXTsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIHRoaXMgaW5zdHJ1Y3Rpb25zIG9wY29kZQotICAgKi8KLSAgcHVibGljIHNob3J0IGdldE9wY29kZSgpICAgIHsgcmV0dXJuIG9wY29kZTsgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIGxlbmd0aCAoaW4gYnl0ZXMpIG9mIGluc3RydWN0aW9uCi0gICAqLwotICBwdWJsaWMgaW50IGdldExlbmd0aCgpICAgeyByZXR1cm4gbGVuZ3RoOyB9Ci0KLSAgLyoqCi0gICAqIE5lZWRlZCBpbiByZWFkSW5zdHJ1Y3Rpb24uCi0gICAqLwotICBwcml2YXRlIHZvaWQgc2V0T3Bjb2RlKHNob3J0IG9wY29kZSkgeyB0aGlzLm9wY29kZSA9IG9wY29kZTsgfQotCi0gIC8qKiBTb21lIGluc3RydWN0aW9ucyBtYXkgYmUgcmV1c2VkLCBzbyBkb24ndCBkbyBhbnl0aGluZyBieSBkZWZhdWx0LgotICAgKi8KLSAgdm9pZCBkaXNwb3NlKCkge30KLQotICAvKioKLSAgICogQ2FsbCBjb3JyZXNwb25kaW5nIHZpc2l0b3IgbWV0aG9kKHMpLiBUaGUgb3JkZXIgaXM6Ci0gICAqIENhbGwgdmlzaXRvciBtZXRob2RzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMgZmlyc3QsIHRoZW4KLSAgICogY2FsbCBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY2xhc3MgaGllcmFyY2h5IGluIGRlc2NlbmRpbmcgb3JkZXIsCi0gICAqIGkuZS4sIHRoZSBtb3N0IHNwZWNpZmljIHZpc2l0WFhYKCkgY2FsbCBjb21lcyBsYXN0LgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IHZvaWQgYWNjZXB0KFZpc2l0b3Igdik7Ci0KLSAgLyoqIEdldCBDb21wYXJhdG9yIG9iamVjdCB1c2VkIGluIHRoZSBlcXVhbHMoKSBtZXRob2QgdG8gZGV0ZXJtaW5lCi0gICAqIGVxdWFsaXR5IG9mIGluc3RydWN0aW9ucy4KLSAgICoKLSAgICogQHJldHVybiBjdXJyZW50bHkgdXNlZCBjb21wYXJhdG9yIGZvciBlcXVhbHMoKQotICAgKi8KLSAgcHVibGljIHN0YXRpYyBJbnN0cnVjdGlvbkNvbXBhcmF0b3IgZ2V0Q29tcGFyYXRvcigpIHsgcmV0dXJuIGNtcDsgfQotCi0gIC8qKiBTZXQgY29tcGFyYXRvciB0byBiZSB1c2VkIGZvciBlcXVhbHMoKS4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgdm9pZCBzZXRDb21wYXJhdG9yKEluc3RydWN0aW9uQ29tcGFyYXRvciBjKSB7IGNtcCA9IGM7IH0KLQotICAvKiogQ2hlY2sgZm9yIGVxdWFsaXR5LCBkZWxlZ2F0ZWQgdG8gY29tcGFyYXRvcgotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhhdCBpcyBhbiBJbnN0cnVjdGlvbiBhbmQgaGFzIHRoZSBzYW1lIG9wY29kZQotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCB0aGF0KSB7Ci0gICAgcmV0dXJuICh0aGF0IGluc3RhbmNlb2YgSW5zdHJ1Y3Rpb24pPwotICAgICAgY21wLmVxdWFscyh0aGlzLCAoSW5zdHJ1Y3Rpb24pdGhhdCkgOiBmYWxzZTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSW5zdHJ1Y3Rpb25Db21wYXJhdG9yLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JbnN0cnVjdGlvbkNvbXBhcmF0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNWE0MjY1Mi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JbnN0cnVjdGlvbkNvbXBhcmF0b3IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExMiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIEVxdWFsaXR5IG9mIGluc3RydWN0aW9ucyBpc24ndCBjbGVhcmx5IHRvIGJlIGRlZmluZWQuIFlvdSBtaWdodAotICogd2lzaCwgZm9yIGV4YW1wbGUsIHRvIGNvbXBhcmUgd2hldGhlciBpbnN0cnVjdGlvbnMgaGF2ZSB0aGUgc2FtZQotICogbWVhbmluZy4gRS5nLiwgd2hldGhlciB0d28gSU5WT0tFVklSVFVBTHMgZGVzY3JpYmUgdGhlIHNhbWUKLSAqIGNhbGwuPGJyPlRoZSBERUZBVUxUIGNvbXBhcmF0b3IgaG93ZXZlciwgY29uc2lkZXJzIHR3byBpbnN0cnVjdGlvbnMKLSAqIHRvIGJlIGVxdWFsIGlmIHRoZXkgaGF2ZSBzYW1lIG9wY29kZSBhbmQgcG9pbnQgdG8gdGhlIHNhbWUgaW5kZXhlcwotICogKGlmIGFueSkgaW4gdGhlIGNvbnN0YW50IHBvb2wgb3IgdGhlIHNhbWUgbG9jYWwgdmFyaWFibGUgaW5kZXguIEJyYW5jaAotICogaW5zdHJ1Y3Rpb25zIG11c3QgaGF2ZSB0aGUgc2FtZSB0YXJnZXQuCi0gKgotICogQHNlZSBJbnN0cnVjdGlvbgotICogQGF1dGhvciA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgaW50ZXJmYWNlIEluc3RydWN0aW9uQ29tcGFyYXRvciB7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgSW5zdHJ1Y3Rpb25Db21wYXJhdG9yIERFRkFVTFQgPQotICAgIG5ldyBJbnN0cnVjdGlvbkNvbXBhcmF0b3IoKSB7Ci0gICAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhJbnN0cnVjdGlvbiBpMSwgSW5zdHJ1Y3Rpb24gaTIpIHsKLSAgICAgICAgICBpZihpMS5vcGNvZGUgPT0gaTIub3Bjb2RlKSB7Ci0gICAgICAgICAgICBpZihpMSBpbnN0YW5jZW9mIFNlbGVjdCkgewotICAgICAgICAgICAgICBJbnN0cnVjdGlvbkhhbmRsZVtdIHQxID0gKChTZWxlY3QpaTEpLmdldFRhcmdldHMoKTsKLSAgICAgICAgICAgICAgSW5zdHJ1Y3Rpb25IYW5kbGVbXSB0MiA9ICgoU2VsZWN0KWkyKS5nZXRUYXJnZXRzKCk7Ci0KLSAgICAgICAgICAgICAgaWYodDEubGVuZ3RoID09IHQyLmxlbmd0aCkgewotICAgICAgICAgICAgICAgIGZvcihpbnQgaSA9IDA7IGkgPCB0MS5sZW5ndGg7IGkrKykgewotICAgICAgICAgICAgICAgICAgaWYodDFbaV0gIT0gdDJbaV0pIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9IGVsc2UgaWYoaTEgaW5zdGFuY2VvZiBCcmFuY2hJbnN0cnVjdGlvbikgewotICAgICAgICAgICAgICByZXR1cm4gKChCcmFuY2hJbnN0cnVjdGlvbilpMSkudGFyZ2V0ID09Ci0gICAgICAgICAgICAgICAgKChCcmFuY2hJbnN0cnVjdGlvbilpMikudGFyZ2V0OwotICAgICAgICAgICAgfSBlbHNlIGlmKGkxIGluc3RhbmNlb2YgQ29uc3RhbnRQdXNoSW5zdHJ1Y3Rpb24pIHsKLSAgICAgICAgICAgICAgcmV0dXJuICgoQ29uc3RhbnRQdXNoSW5zdHJ1Y3Rpb24paTEpLmdldFZhbHVlKCkuCi0gICAgICAgICAgICAgICAgZXF1YWxzKCgoQ29uc3RhbnRQdXNoSW5zdHJ1Y3Rpb24paTIpLmdldFZhbHVlKCkpOwotICAgICAgICAgICAgfSBlbHNlIGlmKGkxIGluc3RhbmNlb2YgSW5kZXhlZEluc3RydWN0aW9uKSB7Ci0gICAgICAgICAgICAgIHJldHVybiAoKEluZGV4ZWRJbnN0cnVjdGlvbilpMSkuZ2V0SW5kZXgoKSA9PQotICAgICAgICAgICAgICAgICgoSW5kZXhlZEluc3RydWN0aW9uKWkyKS5nZXRJbmRleCgpOwotICAgICAgICAgICAgfSBlbHNlIGlmKGkxIGluc3RhbmNlb2YgTkVXQVJSQVkpIHsKLSAgICAgICAgICAgICAgcmV0dXJuICgoTkVXQVJSQVkpaTEpLmdldFR5cGVjb2RlKCkgPT0gKChORVdBUlJBWSlpMikuZ2V0VHlwZWNvZGUoKTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICAgIH0KLQotICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotICAgICAgfTsKLQotICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoSW5zdHJ1Y3Rpb24gaTEsIEluc3RydWN0aW9uIGkyKTsKLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0luc3RydWN0aW9uQ29uc3RhbnRzLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JbnN0cnVjdGlvbkNvbnN0YW50cy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxZmY1NWRkLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0luc3RydWN0aW9uQ29uc3RhbnRzLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzMjkgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50czsKLQotLyoqCi0gKiBUaGlzIGludGVyZmFjZSBjb250YWlucyBzaGFyZWFibGUgaW5zdHJ1Y3Rpb24gb2JqZWN0cy4KLSAqCi0gKiBJbiBvcmRlciB0byBzYXZlIG1lbW9yeSB5b3UgY2FuIHVzZSBzb21lIGluc3RydWN0aW9ucyBtdWx0aXBseSwKLSAqIHNpbmNlIHRoZXkgaGF2ZSBhbiBpbW11dGFibGUgc3RhdGUgYW5kIGFyZSBkaXJlY3RseSBkZXJpdmVkIGZyb20KLSAqIEluc3RydWN0aW9uLiAgSS5lLiB0aGV5IGhhdmUgbm8gaW5zdGFuY2UgZmllbGRzIHRoYXQgY291bGQgYmUKLSAqIGNoYW5nZWQuIFNpbmNlIHNvbWUgb2YgdGhlc2UgaW5zdHJ1Y3Rpb25zIGxpa2UgSUNPTlNUXzAgb2NjdXIKLSAqIHZlcnkgZnJlcXVlbnRseSB0aGlzIGNhbiBzYXZlIGEgbG90IG9mIHRpbWUgYW5kIHNwYWNlLiBUaGlzCi0gKiBmZWF0dXJlIGlzIGFuIGFkYXB0YXRpb24gb2YgdGhlIEZseVdlaWdodCBkZXNpZ24gcGF0dGVybiwgd2UKLSAqIGp1c3QgdXNlIGFuIGFycmF5IGluc3RlYWQgb2YgYSBmYWN0b3J5LgotICoKLSAqIFRoZSBJbnN0cnVjdGlvbnMgY2FuIGFsc28gYWNjZXNzZWQgZGlyZWN0bHkgdW5kZXIgdGhlaXIgbmFtZXMsIHNvCi0gKiBpdCdzIHBvc3NpYmxlIHRvIHdyaXRlIGlsLmFwcGVuZChJbnN0cnVjdGlvbi5JQ09OU1RfMCk7Ci0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGludGVyZmFjZSBJbnN0cnVjdGlvbkNvbnN0YW50cyB7Ci0gIC8qKiBQcmVkZWZpbmVkIGluc3RydWN0aW9uIG9iamVjdHMKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgSW5zdHJ1Y3Rpb24gICAgICAgICAgIE5PUCAgICAgICAgICA9IG5ldyBOT1AoKTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBJbnN0cnVjdGlvbiAgICAgICAgICAgQUNPTlNUX05VTEwgID0gbmV3IEFDT05TVF9OVUxMKCk7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgSW5zdHJ1Y3Rpb24gICAgICAgICAgIElDT05TVF9NMSAgICA9IG5ldyBJQ09OU1QoLTEpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEluc3RydWN0aW9uICAgICAgICAgICBJQ09OU1RfMCAgICAgPSBuZXcgSUNPTlNUKDApOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEluc3RydWN0aW9uICAgICAgICAgICBJQ09OU1RfMSAgICAgPSBuZXcgSUNPTlNUKDEpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEluc3RydWN0aW9uICAgICAgICAgICBJQ09OU1RfMiAgICAgPSBuZXcgSUNPTlNUKDIpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEluc3RydWN0aW9uICAgICAgICAgICBJQ09OU1RfMyAgICAgPSBuZXcgSUNPTlNUKDMpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEluc3RydWN0aW9uICAgICAgICAgICBJQ09OU1RfNCAgICAgPSBuZXcgSUNPTlNUKDQpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEluc3RydWN0aW9uICAgICAgICAgICBJQ09OU1RfNSAgICAgPSBuZXcgSUNPTlNUKDUpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEluc3RydWN0aW9uICAgICAgICAgICBMQ09OU1RfMCAgICAgPSBuZXcgTENPTlNUKDApOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEluc3RydWN0aW9uICAgICAgICAgICBMQ09OU1RfMSAgICAgPSBuZXcgTENPTlNUKDEpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEluc3RydWN0aW9uICAgICAgICAgICBGQ09OU1RfMCAgICAgPSBuZXcgRkNPTlNUKDApOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEluc3RydWN0aW9uICAgICAgICAgICBGQ09OU1RfMSAgICAgPSBuZXcgRkNPTlNUKDEpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEluc3RydWN0aW9uICAgICAgICAgICBGQ09OU1RfMiAgICAgPSBuZXcgRkNPTlNUKDIpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEluc3RydWN0aW9uICAgICAgICAgICBEQ09OU1RfMCAgICAgPSBuZXcgRENPTlNUKDApOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEluc3RydWN0aW9uICAgICAgICAgICBEQ09OU1RfMSAgICAgPSBuZXcgRENPTlNUKDEpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEFycmF5SW5zdHJ1Y3Rpb24gICAgICBJQUxPQUQgICAgICAgPSBuZXcgSUFMT0FEKCk7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgQXJyYXlJbnN0cnVjdGlvbiAgICAgIExBTE9BRCAgICAgICA9IG5ldyBMQUxPQUQoKTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBBcnJheUluc3RydWN0aW9uICAgICAgRkFMT0FEICAgICAgID0gbmV3IEZBTE9BRCgpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEFycmF5SW5zdHJ1Y3Rpb24gICAgICBEQUxPQUQgICAgICAgPSBuZXcgREFMT0FEKCk7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgQXJyYXlJbnN0cnVjdGlvbiAgICAgIEFBTE9BRCAgICAgICA9IG5ldyBBQUxPQUQoKTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBBcnJheUluc3RydWN0aW9uICAgICAgQkFMT0FEICAgICAgID0gbmV3IEJBTE9BRCgpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEFycmF5SW5zdHJ1Y3Rpb24gICAgICBDQUxPQUQgICAgICAgPSBuZXcgQ0FMT0FEKCk7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgQXJyYXlJbnN0cnVjdGlvbiAgICAgIFNBTE9BRCAgICAgICA9IG5ldyBTQUxPQUQoKTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBBcnJheUluc3RydWN0aW9uICAgICAgSUFTVE9SRSAgICAgID0gbmV3IElBU1RPUkUoKTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBBcnJheUluc3RydWN0aW9uICAgICAgTEFTVE9SRSAgICAgID0gbmV3IExBU1RPUkUoKTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBBcnJheUluc3RydWN0aW9uICAgICAgRkFTVE9SRSAgICAgID0gbmV3IEZBU1RPUkUoKTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBBcnJheUluc3RydWN0aW9uICAgICAgREFTVE9SRSAgICAgID0gbmV3IERBU1RPUkUoKTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBBcnJheUluc3RydWN0aW9uICAgICAgQUFTVE9SRSAgICAgID0gbmV3IEFBU1RPUkUoKTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBBcnJheUluc3RydWN0aW9uICAgICAgQkFTVE9SRSAgICAgID0gbmV3IEJBU1RPUkUoKTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBBcnJheUluc3RydWN0aW9uICAgICAgQ0FTVE9SRSAgICAgID0gbmV3IENBU1RPUkUoKTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBBcnJheUluc3RydWN0aW9uICAgICAgU0FTVE9SRSAgICAgID0gbmV3IFNBU1RPUkUoKTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdGFja0luc3RydWN0aW9uICAgICAgUE9QICAgICAgICAgID0gbmV3IFBPUCgpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0YWNrSW5zdHJ1Y3Rpb24gICAgICBQT1AyICAgICAgICAgPSBuZXcgUE9QMigpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0YWNrSW5zdHJ1Y3Rpb24gICAgICBEVVAgICAgICAgICAgPSBuZXcgRFVQKCk7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RhY2tJbnN0cnVjdGlvbiAgICAgIERVUF9YMSAgICAgICA9IG5ldyBEVVBfWDEoKTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdGFja0luc3RydWN0aW9uICAgICAgRFVQX1gyICAgICAgID0gbmV3IERVUF9YMigpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0YWNrSW5zdHJ1Y3Rpb24gICAgICBEVVAyICAgICAgICAgPSBuZXcgRFVQMigpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0YWNrSW5zdHJ1Y3Rpb24gICAgICBEVVAyX1gxICAgICAgPSBuZXcgRFVQMl9YMSgpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0YWNrSW5zdHJ1Y3Rpb24gICAgICBEVVAyX1gyICAgICAgPSBuZXcgRFVQMl9YMigpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0YWNrSW5zdHJ1Y3Rpb24gICAgICBTV0FQICAgICAgICAgPSBuZXcgU1dBUCgpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEFyaXRobWV0aWNJbnN0cnVjdGlvbiBJQUREICAgICAgICAgPSBuZXcgSUFERCgpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEFyaXRobWV0aWNJbnN0cnVjdGlvbiBMQUREICAgICAgICAgPSBuZXcgTEFERCgpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEFyaXRobWV0aWNJbnN0cnVjdGlvbiBGQUREICAgICAgICAgPSBuZXcgRkFERCgpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEFyaXRobWV0aWNJbnN0cnVjdGlvbiBEQUREICAgICAgICAgPSBuZXcgREFERCgpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEFyaXRobWV0aWNJbnN0cnVjdGlvbiBJU1VCICAgICAgICAgPSBuZXcgSVNVQigpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEFyaXRobWV0aWNJbnN0cnVjdGlvbiBMU1VCICAgICAgICAgPSBuZXcgTFNVQigpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEFyaXRobWV0aWNJbnN0cnVjdGlvbiBGU1VCICAgICAgICAgPSBuZXcgRlNVQigpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEFyaXRobWV0aWNJbnN0cnVjdGlvbiBEU1VCICAgICAgICAgPSBuZXcgRFNVQigpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEFyaXRobWV0aWNJbnN0cnVjdGlvbiBJTVVMICAgICAgICAgPSBuZXcgSU1VTCgpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEFyaXRobWV0aWNJbnN0cnVjdGlvbiBMTVVMICAgICAgICAgPSBuZXcgTE1VTCgpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEFyaXRobWV0aWNJbnN0cnVjdGlvbiBGTVVMICAgICAgICAgPSBuZXcgRk1VTCgpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEFyaXRobWV0aWNJbnN0cnVjdGlvbiBETVVMICAgICAgICAgPSBuZXcgRE1VTCgpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEFyaXRobWV0aWNJbnN0cnVjdGlvbiBJRElWICAgICAgICAgPSBuZXcgSURJVigpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEFyaXRobWV0aWNJbnN0cnVjdGlvbiBMRElWICAgICAgICAgPSBuZXcgTERJVigpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEFyaXRobWV0aWNJbnN0cnVjdGlvbiBGRElWICAgICAgICAgPSBuZXcgRkRJVigpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEFyaXRobWV0aWNJbnN0cnVjdGlvbiBERElWICAgICAgICAgPSBuZXcgRERJVigpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEFyaXRobWV0aWNJbnN0cnVjdGlvbiBJUkVNICAgICAgICAgPSBuZXcgSVJFTSgpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEFyaXRobWV0aWNJbnN0cnVjdGlvbiBMUkVNICAgICAgICAgPSBuZXcgTFJFTSgpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEFyaXRobWV0aWNJbnN0cnVjdGlvbiBGUkVNICAgICAgICAgPSBuZXcgRlJFTSgpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEFyaXRobWV0aWNJbnN0cnVjdGlvbiBEUkVNICAgICAgICAgPSBuZXcgRFJFTSgpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEFyaXRobWV0aWNJbnN0cnVjdGlvbiBJTkVHICAgICAgICAgPSBuZXcgSU5FRygpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEFyaXRobWV0aWNJbnN0cnVjdGlvbiBMTkVHICAgICAgICAgPSBuZXcgTE5FRygpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEFyaXRobWV0aWNJbnN0cnVjdGlvbiBGTkVHICAgICAgICAgPSBuZXcgRk5FRygpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEFyaXRobWV0aWNJbnN0cnVjdGlvbiBETkVHICAgICAgICAgPSBuZXcgRE5FRygpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEFyaXRobWV0aWNJbnN0cnVjdGlvbiBJU0hMICAgICAgICAgPSBuZXcgSVNITCgpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEFyaXRobWV0aWNJbnN0cnVjdGlvbiBMU0hMICAgICAgICAgPSBuZXcgTFNITCgpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEFyaXRobWV0aWNJbnN0cnVjdGlvbiBJU0hSICAgICAgICAgPSBuZXcgSVNIUigpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEFyaXRobWV0aWNJbnN0cnVjdGlvbiBMU0hSICAgICAgICAgPSBuZXcgTFNIUigpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEFyaXRobWV0aWNJbnN0cnVjdGlvbiBJVVNIUiAgICAgICAgPSBuZXcgSVVTSFIoKTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBBcml0aG1ldGljSW5zdHJ1Y3Rpb24gTFVTSFIgICAgICAgID0gbmV3IExVU0hSKCk7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgQXJpdGhtZXRpY0luc3RydWN0aW9uIElBTkQgICAgICAgICA9IG5ldyBJQU5EKCk7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgQXJpdGhtZXRpY0luc3RydWN0aW9uIExBTkQgICAgICAgICA9IG5ldyBMQU5EKCk7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgQXJpdGhtZXRpY0luc3RydWN0aW9uIElPUiAgICAgICAgICA9IG5ldyBJT1IoKTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBBcml0aG1ldGljSW5zdHJ1Y3Rpb24gTE9SICAgICAgICAgID0gbmV3IExPUigpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEFyaXRobWV0aWNJbnN0cnVjdGlvbiBJWE9SICAgICAgICAgPSBuZXcgSVhPUigpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEFyaXRobWV0aWNJbnN0cnVjdGlvbiBMWE9SICAgICAgICAgPSBuZXcgTFhPUigpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIENvbnZlcnNpb25JbnN0cnVjdGlvbiBJMkwgICAgICAgICAgPSBuZXcgSTJMKCk7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgQ29udmVyc2lvbkluc3RydWN0aW9uIEkyRiAgICAgICAgICA9IG5ldyBJMkYoKTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBDb252ZXJzaW9uSW5zdHJ1Y3Rpb24gSTJEICAgICAgICAgID0gbmV3IEkyRCgpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIENvbnZlcnNpb25JbnN0cnVjdGlvbiBMMkkgICAgICAgICAgPSBuZXcgTDJJKCk7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgQ29udmVyc2lvbkluc3RydWN0aW9uIEwyRiAgICAgICAgICA9IG5ldyBMMkYoKTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBDb252ZXJzaW9uSW5zdHJ1Y3Rpb24gTDJEICAgICAgICAgID0gbmV3IEwyRCgpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIENvbnZlcnNpb25JbnN0cnVjdGlvbiBGMkkgICAgICAgICAgPSBuZXcgRjJJKCk7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgQ29udmVyc2lvbkluc3RydWN0aW9uIEYyTCAgICAgICAgICA9IG5ldyBGMkwoKTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBDb252ZXJzaW9uSW5zdHJ1Y3Rpb24gRjJEICAgICAgICAgID0gbmV3IEYyRCgpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIENvbnZlcnNpb25JbnN0cnVjdGlvbiBEMkkgICAgICAgICAgPSBuZXcgRDJJKCk7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgQ29udmVyc2lvbkluc3RydWN0aW9uIEQyTCAgICAgICAgICA9IG5ldyBEMkwoKTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBDb252ZXJzaW9uSW5zdHJ1Y3Rpb24gRDJGICAgICAgICAgID0gbmV3IEQyRigpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIENvbnZlcnNpb25JbnN0cnVjdGlvbiBJMkIgICAgICAgICAgPSBuZXcgSTJCKCk7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgQ29udmVyc2lvbkluc3RydWN0aW9uIEkyQyAgICAgICAgICA9IG5ldyBJMkMoKTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBDb252ZXJzaW9uSW5zdHJ1Y3Rpb24gSTJTICAgICAgICAgID0gbmV3IEkyUygpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEluc3RydWN0aW9uICAgICAgICAgICBMQ01QICAgICAgICAgPSBuZXcgTENNUCgpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEluc3RydWN0aW9uICAgICAgICAgICBGQ01QTCAgICAgICAgPSBuZXcgRkNNUEwoKTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBJbnN0cnVjdGlvbiAgICAgICAgICAgRkNNUEcgICAgICAgID0gbmV3IEZDTVBHKCk7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgSW5zdHJ1Y3Rpb24gICAgICAgICAgIERDTVBMICAgICAgICA9IG5ldyBEQ01QTCgpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEluc3RydWN0aW9uICAgICAgICAgICBEQ01QRyAgICAgICAgPSBuZXcgRENNUEcoKTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBSZXR1cm5JbnN0cnVjdGlvbiAgICAgSVJFVFVSTiAgICAgID0gbmV3IElSRVRVUk4oKTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBSZXR1cm5JbnN0cnVjdGlvbiAgICAgTFJFVFVSTiAgICAgID0gbmV3IExSRVRVUk4oKTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBSZXR1cm5JbnN0cnVjdGlvbiAgICAgRlJFVFVSTiAgICAgID0gbmV3IEZSRVRVUk4oKTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBSZXR1cm5JbnN0cnVjdGlvbiAgICAgRFJFVFVSTiAgICAgID0gbmV3IERSRVRVUk4oKTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBSZXR1cm5JbnN0cnVjdGlvbiAgICAgQVJFVFVSTiAgICAgID0gbmV3IEFSRVRVUk4oKTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBSZXR1cm5JbnN0cnVjdGlvbiAgICAgUkVUVVJOICAgICAgID0gbmV3IFJFVFVSTigpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEluc3RydWN0aW9uICAgICAgICAgICBBUlJBWUxFTkdUSCAgPSBuZXcgQVJSQVlMRU5HVEgoKTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBJbnN0cnVjdGlvbiAgICAgICAgICAgQVRIUk9XICAgICAgID0gbmV3IEFUSFJPVygpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEluc3RydWN0aW9uICAgICAgICAgICBNT05JVE9SRU5URVIgPSBuZXcgTU9OSVRPUkVOVEVSKCk7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgSW5zdHJ1Y3Rpb24gICAgICAgICAgIE1PTklUT1JFWElUICA9IG5ldyBNT05JVE9SRVhJVCgpOwotCi0gIC8qKiBZb3UgY2FuIHVzZSB0aGVzZSBjb25zdGFudHMgaW4gbXVsdGlwbGUgcGxhY2VzIHNhZmVseSwgaWYgeW91IGNhbiBndWFyYW50ZWUKLSAgICogdGhhdCB5b3Ugd2lsbCBuZXZlciBhbHRlciB0aGVpciBpbnRlcm5hbCB2YWx1ZXMsIGUuZy4gY2FsbCBzZXRJbmRleCgpLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBMb2NhbFZhcmlhYmxlSW5zdHJ1Y3Rpb24gVEhJUyAgICA9IG5ldyBBTE9BRCgwKTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBMb2NhbFZhcmlhYmxlSW5zdHJ1Y3Rpb24gQUxPQURfMCA9IFRISVM7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgTG9jYWxWYXJpYWJsZUluc3RydWN0aW9uIEFMT0FEXzEgPSBuZXcgQUxPQUQoMSk7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgTG9jYWxWYXJpYWJsZUluc3RydWN0aW9uIEFMT0FEXzIgPSBuZXcgQUxPQUQoMik7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgTG9jYWxWYXJpYWJsZUluc3RydWN0aW9uIElMT0FEXzAgPSBuZXcgSUxPQUQoMCk7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgTG9jYWxWYXJpYWJsZUluc3RydWN0aW9uIElMT0FEXzEgPSBuZXcgSUxPQUQoMSk7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgTG9jYWxWYXJpYWJsZUluc3RydWN0aW9uIElMT0FEXzIgPSBuZXcgSUxPQUQoMik7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgTG9jYWxWYXJpYWJsZUluc3RydWN0aW9uIEFTVE9SRV8wID0gbmV3IEFTVE9SRSgwKTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBMb2NhbFZhcmlhYmxlSW5zdHJ1Y3Rpb24gQVNUT1JFXzEgPSBuZXcgQVNUT1JFKDEpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIExvY2FsVmFyaWFibGVJbnN0cnVjdGlvbiBBU1RPUkVfMiA9IG5ldyBBU1RPUkUoMik7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgTG9jYWxWYXJpYWJsZUluc3RydWN0aW9uIElTVE9SRV8wID0gbmV3IElTVE9SRSgwKTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBMb2NhbFZhcmlhYmxlSW5zdHJ1Y3Rpb24gSVNUT1JFXzEgPSBuZXcgSVNUT1JFKDEpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIExvY2FsVmFyaWFibGVJbnN0cnVjdGlvbiBJU1RPUkVfMiA9IG5ldyBJU1RPUkUoMik7Ci0KLQotICAvKiogR2V0IG9iamVjdCB2aWEgaXRzIG9wY29kZSwgZm9yIGltbXV0YWJsZSBpbnN0cnVjdGlvbnMgbGlrZQotICAgKiBicmFuY2ggaW5zdHJ1Y3Rpb25zIGVudHJpZXMgYXJlIHNldCB0byBudWxsLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBJbnN0cnVjdGlvbltdIElOU1RSVUNUSU9OUyA9IG5ldyBJbnN0cnVjdGlvblsyNTZdOwotCi0gIC8qKiBJbnRlcmZhY2VzIG1heSBoYXZlIG5vIHN0YXRpYyBpbml0aWFsaXplcnMsIHNvIHdlIHNpbXVsYXRlIHRoaXMKLSAgICogd2l0aCBhbiBpbm5lciBjbGFzcy4KLSAgICovCi0gIHN0YXRpYyBmaW5hbCBDbGluaXQgYmxhID0gbmV3IENsaW5pdCgpOwotCi0gIHN0YXRpYyBjbGFzcyBDbGluaXQgewotICAgIENsaW5pdCgpIHsKLSAgICAgIElOU1RSVUNUSU9OU1tDb25zdGFudHMuTk9QXSA9IE5PUDsKLSAgICAgIElOU1RSVUNUSU9OU1tDb25zdGFudHMuQUNPTlNUX05VTExdID0gQUNPTlNUX05VTEw7Ci0gICAgICBJTlNUUlVDVElPTlNbQ29uc3RhbnRzLklDT05TVF9NMV0gPSBJQ09OU1RfTTE7Ci0gICAgICBJTlNUUlVDVElPTlNbQ29uc3RhbnRzLklDT05TVF8wXSA9IElDT05TVF8wOwotICAgICAgSU5TVFJVQ1RJT05TW0NvbnN0YW50cy5JQ09OU1RfMV0gPSBJQ09OU1RfMTsKLSAgICAgIElOU1RSVUNUSU9OU1tDb25zdGFudHMuSUNPTlNUXzJdID0gSUNPTlNUXzI7Ci0gICAgICBJTlNUUlVDVElPTlNbQ29uc3RhbnRzLklDT05TVF8zXSA9IElDT05TVF8zOwotICAgICAgSU5TVFJVQ1RJT05TW0NvbnN0YW50cy5JQ09OU1RfNF0gPSBJQ09OU1RfNDsKLSAgICAgIElOU1RSVUNUSU9OU1tDb25zdGFudHMuSUNPTlNUXzVdID0gSUNPTlNUXzU7Ci0gICAgICBJTlNUUlVDVElPTlNbQ29uc3RhbnRzLkxDT05TVF8wXSA9IExDT05TVF8wOwotICAgICAgSU5TVFJVQ1RJT05TW0NvbnN0YW50cy5MQ09OU1RfMV0gPSBMQ09OU1RfMTsKLSAgICAgIElOU1RSVUNUSU9OU1tDb25zdGFudHMuRkNPTlNUXzBdID0gRkNPTlNUXzA7Ci0gICAgICBJTlNUUlVDVElPTlNbQ29uc3RhbnRzLkZDT05TVF8xXSA9IEZDT05TVF8xOwotICAgICAgSU5TVFJVQ1RJT05TW0NvbnN0YW50cy5GQ09OU1RfMl0gPSBGQ09OU1RfMjsKLSAgICAgIElOU1RSVUNUSU9OU1tDb25zdGFudHMuRENPTlNUXzBdID0gRENPTlNUXzA7Ci0gICAgICBJTlNUUlVDVElPTlNbQ29uc3RhbnRzLkRDT05TVF8xXSA9IERDT05TVF8xOwotICAgICAgSU5TVFJVQ1RJT05TW0NvbnN0YW50cy5JQUxPQURdID0gSUFMT0FEOwotICAgICAgSU5TVFJVQ1RJT05TW0NvbnN0YW50cy5MQUxPQURdID0gTEFMT0FEOwotICAgICAgSU5TVFJVQ1RJT05TW0NvbnN0YW50cy5GQUxPQURdID0gRkFMT0FEOwotICAgICAgSU5TVFJVQ1RJT05TW0NvbnN0YW50cy5EQUxPQURdID0gREFMT0FEOwotICAgICAgSU5TVFJVQ1RJT05TW0NvbnN0YW50cy5BQUxPQURdID0gQUFMT0FEOwotICAgICAgSU5TVFJVQ1RJT05TW0NvbnN0YW50cy5CQUxPQURdID0gQkFMT0FEOwotICAgICAgSU5TVFJVQ1RJT05TW0NvbnN0YW50cy5DQUxPQURdID0gQ0FMT0FEOwotICAgICAgSU5TVFJVQ1RJT05TW0NvbnN0YW50cy5TQUxPQURdID0gU0FMT0FEOwotICAgICAgSU5TVFJVQ1RJT05TW0NvbnN0YW50cy5JQVNUT1JFXSA9IElBU1RPUkU7Ci0gICAgICBJTlNUUlVDVElPTlNbQ29uc3RhbnRzLkxBU1RPUkVdID0gTEFTVE9SRTsKLSAgICAgIElOU1RSVUNUSU9OU1tDb25zdGFudHMuRkFTVE9SRV0gPSBGQVNUT1JFOwotICAgICAgSU5TVFJVQ1RJT05TW0NvbnN0YW50cy5EQVNUT1JFXSA9IERBU1RPUkU7Ci0gICAgICBJTlNUUlVDVElPTlNbQ29uc3RhbnRzLkFBU1RPUkVdID0gQUFTVE9SRTsKLSAgICAgIElOU1RSVUNUSU9OU1tDb25zdGFudHMuQkFTVE9SRV0gPSBCQVNUT1JFOwotICAgICAgSU5TVFJVQ1RJT05TW0NvbnN0YW50cy5DQVNUT1JFXSA9IENBU1RPUkU7Ci0gICAgICBJTlNUUlVDVElPTlNbQ29uc3RhbnRzLlNBU1RPUkVdID0gU0FTVE9SRTsKLSAgICAgIElOU1RSVUNUSU9OU1tDb25zdGFudHMuUE9QXSA9IFBPUDsKLSAgICAgIElOU1RSVUNUSU9OU1tDb25zdGFudHMuUE9QMl0gPSBQT1AyOwotICAgICAgSU5TVFJVQ1RJT05TW0NvbnN0YW50cy5EVVBdID0gRFVQOwotICAgICAgSU5TVFJVQ1RJT05TW0NvbnN0YW50cy5EVVBfWDFdID0gRFVQX1gxOwotICAgICAgSU5TVFJVQ1RJT05TW0NvbnN0YW50cy5EVVBfWDJdID0gRFVQX1gyOwotICAgICAgSU5TVFJVQ1RJT05TW0NvbnN0YW50cy5EVVAyXSA9IERVUDI7Ci0gICAgICBJTlNUUlVDVElPTlNbQ29uc3RhbnRzLkRVUDJfWDFdID0gRFVQMl9YMTsKLSAgICAgIElOU1RSVUNUSU9OU1tDb25zdGFudHMuRFVQMl9YMl0gPSBEVVAyX1gyOwotICAgICAgSU5TVFJVQ1RJT05TW0NvbnN0YW50cy5TV0FQXSA9IFNXQVA7Ci0gICAgICBJTlNUUlVDVElPTlNbQ29uc3RhbnRzLklBRERdID0gSUFERDsKLSAgICAgIElOU1RSVUNUSU9OU1tDb25zdGFudHMuTEFERF0gPSBMQUREOwotICAgICAgSU5TVFJVQ1RJT05TW0NvbnN0YW50cy5GQUREXSA9IEZBREQ7Ci0gICAgICBJTlNUUlVDVElPTlNbQ29uc3RhbnRzLkRBRERdID0gREFERDsKLSAgICAgIElOU1RSVUNUSU9OU1tDb25zdGFudHMuSVNVQl0gPSBJU1VCOwotICAgICAgSU5TVFJVQ1RJT05TW0NvbnN0YW50cy5MU1VCXSA9IExTVUI7Ci0gICAgICBJTlNUUlVDVElPTlNbQ29uc3RhbnRzLkZTVUJdID0gRlNVQjsKLSAgICAgIElOU1RSVUNUSU9OU1tDb25zdGFudHMuRFNVQl0gPSBEU1VCOwotICAgICAgSU5TVFJVQ1RJT05TW0NvbnN0YW50cy5JTVVMXSA9IElNVUw7Ci0gICAgICBJTlNUUlVDVElPTlNbQ29uc3RhbnRzLkxNVUxdID0gTE1VTDsKLSAgICAgIElOU1RSVUNUSU9OU1tDb25zdGFudHMuRk1VTF0gPSBGTVVMOwotICAgICAgSU5TVFJVQ1RJT05TW0NvbnN0YW50cy5ETVVMXSA9IERNVUw7Ci0gICAgICBJTlNUUlVDVElPTlNbQ29uc3RhbnRzLklESVZdID0gSURJVjsKLSAgICAgIElOU1RSVUNUSU9OU1tDb25zdGFudHMuTERJVl0gPSBMRElWOwotICAgICAgSU5TVFJVQ1RJT05TW0NvbnN0YW50cy5GRElWXSA9IEZESVY7Ci0gICAgICBJTlNUUlVDVElPTlNbQ29uc3RhbnRzLkRESVZdID0gRERJVjsKLSAgICAgIElOU1RSVUNUSU9OU1tDb25zdGFudHMuSVJFTV0gPSBJUkVNOwotICAgICAgSU5TVFJVQ1RJT05TW0NvbnN0YW50cy5MUkVNXSA9IExSRU07Ci0gICAgICBJTlNUUlVDVElPTlNbQ29uc3RhbnRzLkZSRU1dID0gRlJFTTsKLSAgICAgIElOU1RSVUNUSU9OU1tDb25zdGFudHMuRFJFTV0gPSBEUkVNOwotICAgICAgSU5TVFJVQ1RJT05TW0NvbnN0YW50cy5JTkVHXSA9IElORUc7Ci0gICAgICBJTlNUUlVDVElPTlNbQ29uc3RhbnRzLkxORUddID0gTE5FRzsKLSAgICAgIElOU1RSVUNUSU9OU1tDb25zdGFudHMuRk5FR10gPSBGTkVHOwotICAgICAgSU5TVFJVQ1RJT05TW0NvbnN0YW50cy5ETkVHXSA9IERORUc7Ci0gICAgICBJTlNUUlVDVElPTlNbQ29uc3RhbnRzLklTSExdID0gSVNITDsKLSAgICAgIElOU1RSVUNUSU9OU1tDb25zdGFudHMuTFNITF0gPSBMU0hMOwotICAgICAgSU5TVFJVQ1RJT05TW0NvbnN0YW50cy5JU0hSXSA9IElTSFI7Ci0gICAgICBJTlNUUlVDVElPTlNbQ29uc3RhbnRzLkxTSFJdID0gTFNIUjsKLSAgICAgIElOU1RSVUNUSU9OU1tDb25zdGFudHMuSVVTSFJdID0gSVVTSFI7Ci0gICAgICBJTlNUUlVDVElPTlNbQ29uc3RhbnRzLkxVU0hSXSA9IExVU0hSOwotICAgICAgSU5TVFJVQ1RJT05TW0NvbnN0YW50cy5JQU5EXSA9IElBTkQ7Ci0gICAgICBJTlNUUlVDVElPTlNbQ29uc3RhbnRzLkxBTkRdID0gTEFORDsKLSAgICAgIElOU1RSVUNUSU9OU1tDb25zdGFudHMuSU9SXSA9IElPUjsKLSAgICAgIElOU1RSVUNUSU9OU1tDb25zdGFudHMuTE9SXSA9IExPUjsKLSAgICAgIElOU1RSVUNUSU9OU1tDb25zdGFudHMuSVhPUl0gPSBJWE9SOwotICAgICAgSU5TVFJVQ1RJT05TW0NvbnN0YW50cy5MWE9SXSA9IExYT1I7Ci0gICAgICBJTlNUUlVDVElPTlNbQ29uc3RhbnRzLkkyTF0gPSBJMkw7Ci0gICAgICBJTlNUUlVDVElPTlNbQ29uc3RhbnRzLkkyRl0gPSBJMkY7Ci0gICAgICBJTlNUUlVDVElPTlNbQ29uc3RhbnRzLkkyRF0gPSBJMkQ7Ci0gICAgICBJTlNUUlVDVElPTlNbQ29uc3RhbnRzLkwySV0gPSBMMkk7Ci0gICAgICBJTlNUUlVDVElPTlNbQ29uc3RhbnRzLkwyRl0gPSBMMkY7Ci0gICAgICBJTlNUUlVDVElPTlNbQ29uc3RhbnRzLkwyRF0gPSBMMkQ7Ci0gICAgICBJTlNUUlVDVElPTlNbQ29uc3RhbnRzLkYySV0gPSBGMkk7Ci0gICAgICBJTlNUUlVDVElPTlNbQ29uc3RhbnRzLkYyTF0gPSBGMkw7Ci0gICAgICBJTlNUUlVDVElPTlNbQ29uc3RhbnRzLkYyRF0gPSBGMkQ7Ci0gICAgICBJTlNUUlVDVElPTlNbQ29uc3RhbnRzLkQySV0gPSBEMkk7Ci0gICAgICBJTlNUUlVDVElPTlNbQ29uc3RhbnRzLkQyTF0gPSBEMkw7Ci0gICAgICBJTlNUUlVDVElPTlNbQ29uc3RhbnRzLkQyRl0gPSBEMkY7Ci0gICAgICBJTlNUUlVDVElPTlNbQ29uc3RhbnRzLkkyQl0gPSBJMkI7Ci0gICAgICBJTlNUUlVDVElPTlNbQ29uc3RhbnRzLkkyQ10gPSBJMkM7Ci0gICAgICBJTlNUUlVDVElPTlNbQ29uc3RhbnRzLkkyU10gPSBJMlM7Ci0gICAgICBJTlNUUlVDVElPTlNbQ29uc3RhbnRzLkxDTVBdID0gTENNUDsKLSAgICAgIElOU1RSVUNUSU9OU1tDb25zdGFudHMuRkNNUExdID0gRkNNUEw7Ci0gICAgICBJTlNUUlVDVElPTlNbQ29uc3RhbnRzLkZDTVBHXSA9IEZDTVBHOwotICAgICAgSU5TVFJVQ1RJT05TW0NvbnN0YW50cy5EQ01QTF0gPSBEQ01QTDsKLSAgICAgIElOU1RSVUNUSU9OU1tDb25zdGFudHMuRENNUEddID0gRENNUEc7Ci0gICAgICBJTlNUUlVDVElPTlNbQ29uc3RhbnRzLklSRVRVUk5dID0gSVJFVFVSTjsKLSAgICAgIElOU1RSVUNUSU9OU1tDb25zdGFudHMuTFJFVFVSTl0gPSBMUkVUVVJOOwotICAgICAgSU5TVFJVQ1RJT05TW0NvbnN0YW50cy5GUkVUVVJOXSA9IEZSRVRVUk47Ci0gICAgICBJTlNUUlVDVElPTlNbQ29uc3RhbnRzLkRSRVRVUk5dID0gRFJFVFVSTjsKLSAgICAgIElOU1RSVUNUSU9OU1tDb25zdGFudHMuQVJFVFVSTl0gPSBBUkVUVVJOOwotICAgICAgSU5TVFJVQ1RJT05TW0NvbnN0YW50cy5SRVRVUk5dID0gUkVUVVJOOwotICAgICAgSU5TVFJVQ1RJT05TW0NvbnN0YW50cy5BUlJBWUxFTkdUSF0gPSBBUlJBWUxFTkdUSDsKLSAgICAgIElOU1RSVUNUSU9OU1tDb25zdGFudHMuQVRIUk9XXSA9IEFUSFJPVzsKLSAgICAgIElOU1RSVUNUSU9OU1tDb25zdGFudHMuTU9OSVRPUkVOVEVSXSA9IE1PTklUT1JFTlRFUjsKLSAgICAgIElOU1RSVUNUSU9OU1tDb25zdGFudHMuTU9OSVRPUkVYSVRdID0gTU9OSVRPUkVYSVQ7Ci0gICAgfQotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JbnN0cnVjdGlvbkZhY3RvcnkuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0luc3RydWN0aW9uRmFjdG9yeS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmNzM3OGFhLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0luc3RydWN0aW9uRmFjdG9yeS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNjI2ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzOwotCi0vKioKLSAqIEluc3RhbmNlcyBvZiB0aGlzIGNsYXNzIG1heSBiZSB1c2VkLCBlLmcuLCB0byBnZW5lcmF0ZSB0eXBlZAotICogdmVyc2lvbnMgb2YgaW5zdHJ1Y3Rpb25zLiBJdHMgbWFpbiBwdXJwb3NlIGlzIHRvIGJlIHVzZWQgYXMgdGhlCi0gKiBieXRlIGNvZGUgZ2VuZXJhdGluZyBiYWNrZW5kIG9mIGEgY29tcGlsZXIuIFlvdSBjYW4gc3ViY2xhc3MgaXQgdG8KLSAqIGFkZCB5b3VyIG93biBjcmVhdGUgbWV0aG9kcy4KLSAqCi0gKiBAYXV0aG9yIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKiBAc2VlIENvbnN0YW50cwotICovCi1wdWJsaWMgY2xhc3MgSW5zdHJ1Y3Rpb25GYWN0b3J5Ci0gIGltcGxlbWVudHMgSW5zdHJ1Y3Rpb25Db25zdGFudHMsIGphdmEuaW8uU2VyaWFsaXphYmxlCi17Ci0gIHByb3RlY3RlZCBDbGFzc0dlbiAgICAgICAgY2c7Ci0gIHByb3RlY3RlZCBDb25zdGFudFBvb2xHZW4gY3A7Ci0KLSAgcHVibGljIEluc3RydWN0aW9uRmFjdG9yeShDbGFzc0dlbiBjZywgQ29uc3RhbnRQb29sR2VuIGNwKSB7Ci0gICAgdGhpcy5jZyA9IGNnOwotICAgIHRoaXMuY3AgPSBjcDsKLSAgfQotCi0gIC8qKiBJbml0aWFsaXplIHdpdGggQ2xhc3NHZW4gb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgSW5zdHJ1Y3Rpb25GYWN0b3J5KENsYXNzR2VuIGNnKSB7Ci0gICAgdGhpcyhjZywgY2cuZ2V0Q29uc3RhbnRQb29sKCkpOwotICB9Ci0KLSAgLyoqIEluaXRpYWxpemUganVzdCB3aXRoIENvbnN0YW50UG9vbEdlbiBvYmplY3QKLSAgICovCi0gIHB1YmxpYyBJbnN0cnVjdGlvbkZhY3RvcnkoQ29uc3RhbnRQb29sR2VuIGNwKSB7Ci0gICAgdGhpcyhudWxsLCBjcCk7Ci0gIH0KLQotICAvKiogQ3JlYXRlIGFuIGludm9rZSBpbnN0cnVjdGlvbi4KLSAgICoKLSAgICogQHBhcmFtIGNsYXNzX25hbWUgbmFtZSBvZiB0aGUgY2FsbGVkIGNsYXNzCi0gICAqIEBwYXJhbSBuYW1lIG5hbWUgb2YgdGhlIGNhbGxlZCBtZXRob2QKLSAgICogQHBhcmFtIHJldF90eXBlIHJldHVybiB0eXBlIG9mIG1ldGhvZAotICAgKiBAcGFyYW0gYXJnX3R5cGVzIGFyZ3VtZW50IHR5cGVzIG9mIG1ldGhvZAotICAgKiBAcGFyYW0ga2luZCBob3cgdG8gaW52b2tlLCBpLmUuLCBJTlZPS0VJTlRFUkZBQ0UsIElOVk9LRVNUQVRJQywgSU5WT0tFVklSVFVBTCwKLSAgICogb3IgSU5WT0tFU1BFQ0lBTAotICAgKiBAc2VlIENvbnN0YW50cwotICAgKi8KLSAgcHVibGljIEludm9rZUluc3RydWN0aW9uIGNyZWF0ZUludm9rZShTdHJpbmcgY2xhc3NfbmFtZSwgU3RyaW5nIG5hbWUsIFR5cGUgcmV0X3R5cGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHlwZVtdIGFyZ190eXBlcywgc2hvcnQga2luZCkgewotICAgIGludCAgICBpbmRleDsKLSAgICBpbnQgICAgbmFyZ3MgICAgICA9IDA7Ci0gICAgU3RyaW5nIHNpZ25hdHVyZSAgPSBUeXBlLmdldE1ldGhvZFNpZ25hdHVyZShyZXRfdHlwZSwgYXJnX3R5cGVzKTsKLQotICAgIGZvcihpbnQgaT0wOyBpIDwgYXJnX3R5cGVzLmxlbmd0aDsgaSsrKSAvLyBDb3VudCBzaXplIG9mIGFyZ3VtZW50cwotICAgICAgbmFyZ3MgKz0gYXJnX3R5cGVzW2ldLmdldFNpemUoKTsKLQotICAgIGlmKGtpbmQgPT0gQ29uc3RhbnRzLklOVk9LRUlOVEVSRkFDRSkKLSAgICAgIGluZGV4ID0gY3AuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKGNsYXNzX25hbWUsIG5hbWUsIHNpZ25hdHVyZSk7Ci0gICAgZWxzZQotICAgICAgaW5kZXggPSBjcC5hZGRNZXRob2RyZWYoY2xhc3NfbmFtZSwgbmFtZSwgc2lnbmF0dXJlKTsKLQotICAgIHN3aXRjaChraW5kKSB7Ci0gICAgY2FzZSBDb25zdGFudHMuSU5WT0tFU1BFQ0lBTDogICByZXR1cm4gbmV3IElOVk9LRVNQRUNJQUwoaW5kZXgpOwotICAgIGNhc2UgQ29uc3RhbnRzLklOVk9LRVZJUlRVQUw6ICAgcmV0dXJuIG5ldyBJTlZPS0VWSVJUVUFMKGluZGV4KTsKLSAgICBjYXNlIENvbnN0YW50cy5JTlZPS0VTVEFUSUM6ICAgIHJldHVybiBuZXcgSU5WT0tFU1RBVElDKGluZGV4KTsKLSAgICBjYXNlIENvbnN0YW50cy5JTlZPS0VJTlRFUkZBQ0U6IHJldHVybiBuZXcgSU5WT0tFSU5URVJGQUNFKGluZGV4LCBuYXJncyArIDEpOwotICAgIGRlZmF1bHQ6Ci0gICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiT29wczogVW5rbm93biBpbnZva2Uga2luZDoiICsga2luZCk7Ci0gICAgfQotICB9Ci0KLSAgLyoqIENyZWF0ZSBhIGNhbGwgdG8gdGhlIG1vc3QgcG9wdWxhciBTeXN0ZW0ub3V0LnByaW50bG4oKSBtZXRob2QuCi0gICAqCi0gICAqIEBwYXJhbSBzIHRoZSBzdHJpbmcgdG8gcHJpbnQKLSAgICovCi0gIHB1YmxpYyBJbnN0cnVjdGlvbkxpc3QgY3JlYXRlUHJpbnRsbihTdHJpbmcgcykgewotICAgIEluc3RydWN0aW9uTGlzdCBpbCAgICAgID0gbmV3IEluc3RydWN0aW9uTGlzdCgpOwotICAgIGludCAgICAgICAgICAgICBvdXQgICAgID0gY3AuYWRkRmllbGRyZWYoImphdmEubGFuZy5TeXN0ZW0iLCAib3V0IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJMamF2YS9pby9QcmludFN0cmVhbTsiKTsKLSAgICBpbnQgICAgICAgICAgICAgcHJpbnRsbiA9IGNwLmFkZE1ldGhvZHJlZigiamF2YS5pby5QcmludFN0cmVhbSIsICJwcmludGxuIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKExqYXZhL2xhbmcvU3RyaW5nOylWIik7Ci0KLSAgICBpbC5hcHBlbmQobmV3IEdFVFNUQVRJQyhvdXQpKTsKLSAgICBpbC5hcHBlbmQobmV3IFBVU0goY3AsIHMpKTsKLSAgICBpbC5hcHBlbmQobmV3IElOVk9LRVZJUlRVQUwocHJpbnRsbikpOwotCi0gICAgcmV0dXJuIGlsOwotICB9Ci0KLSAgLyoqIFVzZXMgUFVTSCB0byBwdXNoIGEgY29uc3RhbnQgdmFsdWUgb250byB0aGUgc3RhY2suCi0gICAqIEBwYXJhbSB2YWx1ZSBtdXN0IGJlIG9mIHR5cGUgTnVtYmVyLCBCb29sZWFuLCBDaGFyYWN0ZXIgb3IgU3RyaW5nCi0gICAqLwotICBwdWJsaWMgSW5zdHJ1Y3Rpb24gY3JlYXRlQ29uc3RhbnQoT2JqZWN0IHZhbHVlKSB7Ci0gICAgUFVTSCBwdXNoOwotCi0gICAgaWYodmFsdWUgaW5zdGFuY2VvZiBOdW1iZXIpCi0gICAgICBwdXNoID0gbmV3IFBVU0goY3AsIChOdW1iZXIpdmFsdWUpOwotICAgIGVsc2UgaWYodmFsdWUgaW5zdGFuY2VvZiBTdHJpbmcpCi0gICAgICBwdXNoID0gbmV3IFBVU0goY3AsIChTdHJpbmcpdmFsdWUpOwotICAgIGVsc2UgaWYodmFsdWUgaW5zdGFuY2VvZiBCb29sZWFuKQotICAgICAgcHVzaCA9IG5ldyBQVVNIKGNwLCAoQm9vbGVhbil2YWx1ZSk7Ci0gICAgZWxzZSBpZih2YWx1ZSBpbnN0YW5jZW9mIENoYXJhY3RlcikKLSAgICAgIHB1c2ggPSBuZXcgUFVTSChjcCwgKENoYXJhY3Rlcil2YWx1ZSk7Ci0gICAgZWxzZQotICAgICAgdGhyb3cgbmV3IENsYXNzR2VuRXhjZXB0aW9uKCJJbGxlZ2FsIHR5cGU6ICIgKyB2YWx1ZS5nZXRDbGFzcygpKTsKLQotICAgIHJldHVybiBwdXNoLmdldEluc3RydWN0aW9uKCk7Ci0gIH0KLQotICBwcml2YXRlIHN0YXRpYyBjbGFzcyBNZXRob2RPYmplY3QgewotICAgIFR5cGVbXSAgIGFyZ190eXBlczsKLSAgICBUeXBlICAgICByZXN1bHRfdHlwZTsKLSAgICBTdHJpbmdbXSBhcmdfbmFtZXM7Ci0gICAgU3RyaW5nICAgY2xhc3NfbmFtZTsKLSAgICBTdHJpbmcgICBuYW1lOwotICAgIGludCAgICAgIGFjY2VzczsKLQotICAgIE1ldGhvZE9iamVjdChTdHJpbmcgYywgU3RyaW5nIG4sIFR5cGUgciwgVHlwZVtdIGEsIGludCBhY2MpIHsKLSAgICAgIGNsYXNzX25hbWUgID0gYzsKLSAgICAgIG5hbWUgICAgICAgID0gbjsKLSAgICAgIHJlc3VsdF90eXBlID0gcjsKLSAgICAgIGFyZ190eXBlcyAgID0gYTsKLSAgICAgIGFjY2VzcyAgICAgID0gYWNjOwotICAgIH0KLSAgfQotCi0gIHByaXZhdGUgSW52b2tlSW5zdHJ1Y3Rpb24gY3JlYXRlSW52b2tlKE1ldGhvZE9iamVjdCBtLCBzaG9ydCBraW5kKSB7Ci0gICAgcmV0dXJuIGNyZWF0ZUludm9rZShtLmNsYXNzX25hbWUsIG0ubmFtZSwgbS5yZXN1bHRfdHlwZSwgbS5hcmdfdHlwZXMsIGtpbmQpOwotICB9Ci0KLSAgcHJpdmF0ZSBzdGF0aWMgTWV0aG9kT2JqZWN0W10gYXBwZW5kX21vcyA9IHsKLSAgICBuZXcgTWV0aG9kT2JqZWN0KCJqYXZhLmxhbmcuU3RyaW5nQnVmZmVyIiwgImFwcGVuZCIsIFR5cGUuU1RSSU5HQlVGRkVSLAotICAgICAgICAgICAgICAgICAgICAgbmV3IFR5cGVbXSB7IFR5cGUuU1RSSU5HIH0sIENvbnN0YW50cy5BQ0NfUFVCTElDKSwKLSAgICBuZXcgTWV0aG9kT2JqZWN0KCJqYXZhLmxhbmcuU3RyaW5nQnVmZmVyIiwgImFwcGVuZCIsIFR5cGUuU1RSSU5HQlVGRkVSLAotICAgICAgICAgICAgICAgICAgICAgbmV3IFR5cGVbXSB7IFR5cGUuT0JKRUNUIH0sIENvbnN0YW50cy5BQ0NfUFVCTElDKSwKLSAgICBudWxsLCBudWxsLCAvLyBpbmRpY2VzIDIsIDMKLSAgICBuZXcgTWV0aG9kT2JqZWN0KCJqYXZhLmxhbmcuU3RyaW5nQnVmZmVyIiwgImFwcGVuZCIsIFR5cGUuU1RSSU5HQlVGRkVSLAotICAgICAgICAgICAgICAgICAgICAgbmV3IFR5cGVbXSB7IFR5cGUuQk9PTEVBTiB9LCBDb25zdGFudHMuQUNDX1BVQkxJQyksCi0gICAgbmV3IE1ldGhvZE9iamVjdCgiamF2YS5sYW5nLlN0cmluZ0J1ZmZlciIsICJhcHBlbmQiLCBUeXBlLlNUUklOR0JVRkZFUiwKLSAgICAgICAgICAgICAgICAgICAgIG5ldyBUeXBlW10geyBUeXBlLkNIQVIgfSwgQ29uc3RhbnRzLkFDQ19QVUJMSUMpLAotICAgIG5ldyBNZXRob2RPYmplY3QoImphdmEubGFuZy5TdHJpbmdCdWZmZXIiLCAiYXBwZW5kIiwgVHlwZS5TVFJJTkdCVUZGRVIsCi0gICAgICAgICAgICAgICAgICAgICBuZXcgVHlwZVtdIHsgVHlwZS5GTE9BVCB9LCBDb25zdGFudHMuQUNDX1BVQkxJQyksCi0gICAgbmV3IE1ldGhvZE9iamVjdCgiamF2YS5sYW5nLlN0cmluZ0J1ZmZlciIsICJhcHBlbmQiLCBUeXBlLlNUUklOR0JVRkZFUiwKLSAgICAgICAgICAgICAgICAgICAgIG5ldyBUeXBlW10geyBUeXBlLkRPVUJMRSB9LCBDb25zdGFudHMuQUNDX1BVQkxJQyksCi0gICAgbmV3IE1ldGhvZE9iamVjdCgiamF2YS5sYW5nLlN0cmluZ0J1ZmZlciIsICJhcHBlbmQiLCBUeXBlLlNUUklOR0JVRkZFUiwKLSAgICAgICAgICAgICAgICAgICAgIG5ldyBUeXBlW10geyBUeXBlLklOVCB9LCBDb25zdGFudHMuQUNDX1BVQkxJQyksCi0gICAgbmV3IE1ldGhvZE9iamVjdCgiamF2YS5sYW5nLlN0cmluZ0J1ZmZlciIsICJhcHBlbmQiLCBUeXBlLlNUUklOR0JVRkZFUiwgLy8gTm8gYXBwZW5kKGJ5dGUpCi0gICAgICAgICAgICAgICAgICAgICBuZXcgVHlwZVtdIHsgVHlwZS5JTlQgfSwgQ29uc3RhbnRzLkFDQ19QVUJMSUMpLAotICAgIG5ldyBNZXRob2RPYmplY3QoImphdmEubGFuZy5TdHJpbmdCdWZmZXIiLCAiYXBwZW5kIiwgVHlwZS5TVFJJTkdCVUZGRVIsIC8vIE5vIGFwcGVuZChzaG9ydCkKLSAgICAgICAgICAgICAgICAgICAgIG5ldyBUeXBlW10geyBUeXBlLklOVCB9LCBDb25zdGFudHMuQUNDX1BVQkxJQyksCi0gICAgbmV3IE1ldGhvZE9iamVjdCgiamF2YS5sYW5nLlN0cmluZ0J1ZmZlciIsICJhcHBlbmQiLCBUeXBlLlNUUklOR0JVRkZFUiwKLSAgICAgICAgICAgICAgICAgICAgIG5ldyBUeXBlW10geyBUeXBlLkxPTkcgfSwgQ29uc3RhbnRzLkFDQ19QVUJMSUMpCi0gIH07Ci0KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbiBpc1N0cmluZyhUeXBlIHR5cGUpIHsKLSAgICByZXR1cm4gKCh0eXBlIGluc3RhbmNlb2YgT2JqZWN0VHlwZSkgJiYKLSAgICAgICAgICAgICgoT2JqZWN0VHlwZSl0eXBlKS5nZXRDbGFzc05hbWUoKS5lcXVhbHMoImphdmEubGFuZy5TdHJpbmciKSk7Ci0gIH0KLQotICBwdWJsaWMgSW5zdHJ1Y3Rpb24gY3JlYXRlQXBwZW5kKFR5cGUgdHlwZSkgewotICAgIGJ5dGUgdCA9IHR5cGUuZ2V0VHlwZSgpOwotCi0gICAgaWYoaXNTdHJpbmcodHlwZSkpCi0gICAgICByZXR1cm4gY3JlYXRlSW52b2tlKGFwcGVuZF9tb3NbMF0sIENvbnN0YW50cy5JTlZPS0VWSVJUVUFMKTsKLQotICAgIHN3aXRjaCh0KSB7Ci0gICAgY2FzZSBDb25zdGFudHMuVF9CT09MRUFOOgotICAgIGNhc2UgQ29uc3RhbnRzLlRfQ0hBUjoKLSAgICBjYXNlIENvbnN0YW50cy5UX0ZMT0FUOgotICAgIGNhc2UgQ29uc3RhbnRzLlRfRE9VQkxFOgotICAgIGNhc2UgQ29uc3RhbnRzLlRfQllURToKLSAgICBjYXNlIENvbnN0YW50cy5UX1NIT1JUOgotICAgIGNhc2UgQ29uc3RhbnRzLlRfSU5UOgotICAgIGNhc2UgQ29uc3RhbnRzLlRfTE9ORwotICAgICAgOiAgIHJldHVybiBjcmVhdGVJbnZva2UoYXBwZW5kX21vc1t0XSwgQ29uc3RhbnRzLklOVk9LRVZJUlRVQUwpOwotICAgIGNhc2UgQ29uc3RhbnRzLlRfQVJSQVk6Ci0gICAgY2FzZSBDb25zdGFudHMuVF9PQkpFQ1Q6Ci0gICAgICByZXR1cm4gY3JlYXRlSW52b2tlKGFwcGVuZF9tb3NbMV0sIENvbnN0YW50cy5JTlZPS0VWSVJUVUFMKTsKLSAgICBkZWZhdWx0OgotICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIk9vcHM6IE5vIGFwcGVuZCBmb3IgdGhpcyB0eXBlPyAiICsgdHlwZSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqIENyZWF0ZSBhIGZpZWxkIGluc3RydWN0aW9uLgotICAgKgotICAgKiBAcGFyYW0gY2xhc3NfbmFtZSBuYW1lIG9mIHRoZSBhY2Nlc3NlZCBjbGFzcwotICAgKiBAcGFyYW0gbmFtZSBuYW1lIG9mIHRoZSByZWZlcmVuY2VkIGZpZWxkCi0gICAqIEBwYXJhbSB0eXBlICB0eXBlIG9mIGZpZWxkCi0gICAqIEBwYXJhbSBraW5kIGhvdyB0byBhY2Nlc3MsIGkuZS4sIEdFVEZJRUxELCBQVVRGSUVMRCwgR0VUU1RBVElDLCBQVVRTVEFUSUMKLSAgICogQHNlZSBDb25zdGFudHMKLSAgICovCi0gIHB1YmxpYyBGaWVsZEluc3RydWN0aW9uIGNyZWF0ZUZpZWxkQWNjZXNzKFN0cmluZyBjbGFzc19uYW1lLCBTdHJpbmcgbmFtZSwgVHlwZSB0eXBlLCBzaG9ydCBraW5kKSB7Ci0gICAgaW50ICAgIGluZGV4OwotICAgIFN0cmluZyBzaWduYXR1cmUgID0gdHlwZS5nZXRTaWduYXR1cmUoKTsKLQotICAgIGluZGV4ID0gY3AuYWRkRmllbGRyZWYoY2xhc3NfbmFtZSwgbmFtZSwgc2lnbmF0dXJlKTsKLQotICAgIHN3aXRjaChraW5kKSB7Ci0gICAgY2FzZSBDb25zdGFudHMuR0VURklFTEQ6ICByZXR1cm4gbmV3IEdFVEZJRUxEKGluZGV4KTsKLSAgICBjYXNlIENvbnN0YW50cy5QVVRGSUVMRDogIHJldHVybiBuZXcgUFVURklFTEQoaW5kZXgpOwotICAgIGNhc2UgQ29uc3RhbnRzLkdFVFNUQVRJQzogcmV0dXJuIG5ldyBHRVRTVEFUSUMoaW5kZXgpOwotICAgIGNhc2UgQ29uc3RhbnRzLlBVVFNUQVRJQzogcmV0dXJuIG5ldyBQVVRTVEFUSUMoaW5kZXgpOwotCi0gICAgZGVmYXVsdDoKLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJPb3BzOiBVbmtub3duIGdldGZpZWxkIGtpbmQ6IiArIGtpbmQpOwotICAgIH0KLSAgfQotCi0gIC8qKiBDcmVhdGUgcmVmZXJlbmNlIHRvIGB0aGlzJwotICAgKi8KLSAgcHVibGljIHN0YXRpYyBJbnN0cnVjdGlvbiBjcmVhdGVUaGlzKCkgewotICAgIHJldHVybiBuZXcgQUxPQUQoMCk7Ci0gIH0KLQotICAvKiogQ3JlYXRlIHR5cGVkIHJldHVybgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBSZXR1cm5JbnN0cnVjdGlvbiBjcmVhdGVSZXR1cm4oVHlwZSB0eXBlKSB7Ci0gICAgc3dpdGNoKHR5cGUuZ2V0VHlwZSgpKSB7Ci0gICAgY2FzZSBDb25zdGFudHMuVF9BUlJBWToKLSAgICBjYXNlIENvbnN0YW50cy5UX09CSkVDVDogIHJldHVybiBBUkVUVVJOOwotICAgIGNhc2UgQ29uc3RhbnRzLlRfSU5UOgotICAgIGNhc2UgQ29uc3RhbnRzLlRfU0hPUlQ6Ci0gICAgY2FzZSBDb25zdGFudHMuVF9CT09MRUFOOgotICAgIGNhc2UgQ29uc3RhbnRzLlRfQ0hBUjoKLSAgICBjYXNlIENvbnN0YW50cy5UX0JZVEU6ICAgIHJldHVybiBJUkVUVVJOOwotICAgIGNhc2UgQ29uc3RhbnRzLlRfRkxPQVQ6ICAgcmV0dXJuIEZSRVRVUk47Ci0gICAgY2FzZSBDb25zdGFudHMuVF9ET1VCTEU6ICByZXR1cm4gRFJFVFVSTjsKLSAgICBjYXNlIENvbnN0YW50cy5UX0xPTkc6ICAgIHJldHVybiBMUkVUVVJOOwotICAgIGNhc2UgQ29uc3RhbnRzLlRfVk9JRDogICAgcmV0dXJuIFJFVFVSTjsKLQotICAgIGRlZmF1bHQ6Ci0gICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiSW52YWxpZCB0eXBlOiAiICsgdHlwZSk7Ci0gICAgfQotICB9Ci0KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQXJpdGhtZXRpY0luc3RydWN0aW9uIGNyZWF0ZUJpbmFyeUludE9wKGNoYXIgZmlyc3QsIFN0cmluZyBvcCkgewotICAgIHN3aXRjaChmaXJzdCkgewotICAgIGNhc2UgJy0nIDogcmV0dXJuIElTVUI7Ci0gICAgY2FzZSAnKycgOiByZXR1cm4gSUFERDsKLSAgICBjYXNlICclJyA6IHJldHVybiBJUkVNOwotICAgIGNhc2UgJyonIDogcmV0dXJuIElNVUw7Ci0gICAgY2FzZSAnLycgOiByZXR1cm4gSURJVjsKLSAgICBjYXNlICcmJyA6IHJldHVybiBJQU5EOwotICAgIGNhc2UgJ3wnIDogcmV0dXJuIElPUjsKLSAgICBjYXNlICdeJyA6IHJldHVybiBJWE9SOwotICAgIGNhc2UgJzwnIDogcmV0dXJuIElTSEw7Ci0gICAgY2FzZSAnPicgOiByZXR1cm4gb3AuZXF1YWxzKCI+Pj4iKT8gKEFyaXRobWV0aWNJbnN0cnVjdGlvbilJVVNIUiA6Ci0gICAgICAoQXJpdGhtZXRpY0luc3RydWN0aW9uKUlTSFI7Ci0gICAgZGVmYXVsdDogdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIkludmFsaWQgb3BlcmFuZCAiICsgb3ApOwotICAgIH0KLSAgfQotCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIEFyaXRobWV0aWNJbnN0cnVjdGlvbiBjcmVhdGVCaW5hcnlMb25nT3AoY2hhciBmaXJzdCwgU3RyaW5nIG9wKSB7Ci0gICAgc3dpdGNoKGZpcnN0KSB7Ci0gICAgY2FzZSAnLScgOiByZXR1cm4gTFNVQjsKLSAgICBjYXNlICcrJyA6IHJldHVybiBMQUREOwotICAgIGNhc2UgJyUnIDogcmV0dXJuIExSRU07Ci0gICAgY2FzZSAnKicgOiByZXR1cm4gTE1VTDsKLSAgICBjYXNlICcvJyA6IHJldHVybiBMRElWOwotICAgIGNhc2UgJyYnIDogcmV0dXJuIExBTkQ7Ci0gICAgY2FzZSAnfCcgOiByZXR1cm4gTE9SOwotICAgIGNhc2UgJ14nIDogcmV0dXJuIExYT1I7Ci0gICAgY2FzZSAnPCcgOiByZXR1cm4gTFNITDsKLSAgICBjYXNlICc+JyA6IHJldHVybiBvcC5lcXVhbHMoIj4+PiIpPyAoQXJpdGhtZXRpY0luc3RydWN0aW9uKUxVU0hSIDoKLSAgICAgIChBcml0aG1ldGljSW5zdHJ1Y3Rpb24pTFNIUjsKLSAgICBkZWZhdWx0OiB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiSW52YWxpZCBvcGVyYW5kICIgKyBvcCk7Ci0gICAgfQotICB9Ci0KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQXJpdGhtZXRpY0luc3RydWN0aW9uIGNyZWF0ZUJpbmFyeUZsb2F0T3AoY2hhciBvcCkgewotICAgIHN3aXRjaChvcCkgewotICAgIGNhc2UgJy0nIDogcmV0dXJuIEZTVUI7Ci0gICAgY2FzZSAnKycgOiByZXR1cm4gRkFERDsKLSAgICBjYXNlICcqJyA6IHJldHVybiBGTVVMOwotICAgIGNhc2UgJy8nIDogcmV0dXJuIEZESVY7Ci0gICAgZGVmYXVsdDogdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIkludmFsaWQgb3BlcmFuZCAiICsgb3ApOwotICAgIH0KLSAgfQotCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIEFyaXRobWV0aWNJbnN0cnVjdGlvbiBjcmVhdGVCaW5hcnlEb3VibGVPcChjaGFyIG9wKSB7Ci0gICAgc3dpdGNoKG9wKSB7Ci0gICAgY2FzZSAnLScgOiByZXR1cm4gRFNVQjsKLSAgICBjYXNlICcrJyA6IHJldHVybiBEQUREOwotICAgIGNhc2UgJyonIDogcmV0dXJuIERNVUw7Ci0gICAgY2FzZSAnLycgOiByZXR1cm4gRERJVjsKLSAgICBkZWZhdWx0OiB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiSW52YWxpZCBvcGVyYW5kICIgKyBvcCk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBiaW5hcnkgb3BlcmF0aW9uIGZvciBzaW1wbGUgYmFzaWMgdHlwZXMsIHN1Y2ggYXMgaW50IGFuZCBmbG9hdC4KLSAgICoKLSAgICogQHBhcmFtIG9wIG9wZXJhdGlvbiwgc3VjaCBhcyAiKyIsICIqIiwgIjw8IiwgZXRjLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBBcml0aG1ldGljSW5zdHJ1Y3Rpb24gY3JlYXRlQmluYXJ5T3BlcmF0aW9uKFN0cmluZyBvcCwgVHlwZSB0eXBlKSB7Ci0gICAgY2hhciBmaXJzdCA9IG9wLnRvQ2hhckFycmF5KClbMF07Ci0KLSAgICBzd2l0Y2godHlwZS5nZXRUeXBlKCkpIHsKLSAgICBjYXNlIENvbnN0YW50cy5UX0JZVEU6Ci0gICAgY2FzZSBDb25zdGFudHMuVF9TSE9SVDoKLSAgICBjYXNlIENvbnN0YW50cy5UX0lOVDoKLSAgICBjYXNlIENvbnN0YW50cy5UX0NIQVI6ICAgIHJldHVybiBjcmVhdGVCaW5hcnlJbnRPcChmaXJzdCwgb3ApOwotICAgIGNhc2UgQ29uc3RhbnRzLlRfTE9ORzogICAgcmV0dXJuIGNyZWF0ZUJpbmFyeUxvbmdPcChmaXJzdCwgb3ApOwotICAgIGNhc2UgQ29uc3RhbnRzLlRfRkxPQVQ6ICAgcmV0dXJuIGNyZWF0ZUJpbmFyeUZsb2F0T3AoZmlyc3QpOwotICAgIGNhc2UgQ29uc3RhbnRzLlRfRE9VQkxFOiAgcmV0dXJuIGNyZWF0ZUJpbmFyeURvdWJsZU9wKGZpcnN0KTsKLSAgICBkZWZhdWx0OiAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIkludmFsaWQgdHlwZSAiICsgdHlwZSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBzaXplIHNpemUgb2Ygb3BlcmFuZCwgZWl0aGVyIDEgKGludCwgZS5nLikgb3IgMiAoZG91YmxlKQotICAgKi8KLSAgcHVibGljIHN0YXRpYyBTdGFja0luc3RydWN0aW9uIGNyZWF0ZVBvcChpbnQgc2l6ZSkgewotICAgIHJldHVybiAoc2l6ZSA9PSAyKT8gKFN0YWNrSW5zdHJ1Y3Rpb24pUE9QMiA6Ci0gICAgICAoU3RhY2tJbnN0cnVjdGlvbilQT1A7Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIHNpemUgc2l6ZSBvZiBvcGVyYW5kLCBlaXRoZXIgMSAoaW50LCBlLmcuKSBvciAyIChkb3VibGUpCi0gICAqLwotICBwdWJsaWMgc3RhdGljIFN0YWNrSW5zdHJ1Y3Rpb24gY3JlYXRlRHVwKGludCBzaXplKSB7Ci0gICAgcmV0dXJuIChzaXplID09IDIpPyAoU3RhY2tJbnN0cnVjdGlvbilEVVAyIDoKLSAgICAgIChTdGFja0luc3RydWN0aW9uKURVUDsKLSAgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gc2l6ZSBzaXplIG9mIG9wZXJhbmQsIGVpdGhlciAxIChpbnQsIGUuZy4pIG9yIDIgKGRvdWJsZSkKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgU3RhY2tJbnN0cnVjdGlvbiBjcmVhdGVEdXBfMihpbnQgc2l6ZSkgewotICAgIHJldHVybiAoc2l6ZSA9PSAyKT8gKFN0YWNrSW5zdHJ1Y3Rpb24pRFVQMl9YMiA6Ci0gICAgICAoU3RhY2tJbnN0cnVjdGlvbilEVVBfWDI7Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIHNpemUgc2l6ZSBvZiBvcGVyYW5kLCBlaXRoZXIgMSAoaW50LCBlLmcuKSBvciAyIChkb3VibGUpCi0gICAqLwotICBwdWJsaWMgc3RhdGljIFN0YWNrSW5zdHJ1Y3Rpb24gY3JlYXRlRHVwXzEoaW50IHNpemUpIHsKLSAgICByZXR1cm4gKHNpemUgPT0gMik/IChTdGFja0luc3RydWN0aW9uKURVUDJfWDEgOgotICAgICAgKFN0YWNrSW5zdHJ1Y3Rpb24pRFVQX1gxOwotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBpbmRleCBpbmRleCBvZiBsb2NhbCB2YXJpYWJsZQotICAgKi8KLSAgcHVibGljIHN0YXRpYyBMb2NhbFZhcmlhYmxlSW5zdHJ1Y3Rpb24gY3JlYXRlU3RvcmUoVHlwZSB0eXBlLCBpbnQgaW5kZXgpIHsKLSAgICBzd2l0Y2godHlwZS5nZXRUeXBlKCkpIHsKLSAgICBjYXNlIENvbnN0YW50cy5UX0JPT0xFQU46Ci0gICAgY2FzZSBDb25zdGFudHMuVF9DSEFSOgotICAgIGNhc2UgQ29uc3RhbnRzLlRfQllURToKLSAgICBjYXNlIENvbnN0YW50cy5UX1NIT1JUOgotICAgIGNhc2UgQ29uc3RhbnRzLlRfSU5UOiAgICByZXR1cm4gbmV3IElTVE9SRShpbmRleCk7Ci0gICAgY2FzZSBDb25zdGFudHMuVF9GTE9BVDogIHJldHVybiBuZXcgRlNUT1JFKGluZGV4KTsKLSAgICBjYXNlIENvbnN0YW50cy5UX0RPVUJMRTogcmV0dXJuIG5ldyBEU1RPUkUoaW5kZXgpOwotICAgIGNhc2UgQ29uc3RhbnRzLlRfTE9ORzogICByZXR1cm4gbmV3IExTVE9SRShpbmRleCk7Ci0gICAgY2FzZSBDb25zdGFudHMuVF9BUlJBWToKLSAgICBjYXNlIENvbnN0YW50cy5UX09CSkVDVDogcmV0dXJuIG5ldyBBU1RPUkUoaW5kZXgpOwotICAgIGRlZmF1bHQ6ICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJJbnZhbGlkIHR5cGUgIiArIHR5cGUpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gaW5kZXggaW5kZXggb2YgbG9jYWwgdmFyaWFibGUKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgTG9jYWxWYXJpYWJsZUluc3RydWN0aW9uIGNyZWF0ZUxvYWQoVHlwZSB0eXBlLCBpbnQgaW5kZXgpIHsKLSAgICBzd2l0Y2godHlwZS5nZXRUeXBlKCkpIHsKLSAgICBjYXNlIENvbnN0YW50cy5UX0JPT0xFQU46Ci0gICAgY2FzZSBDb25zdGFudHMuVF9DSEFSOgotICAgIGNhc2UgQ29uc3RhbnRzLlRfQllURToKLSAgICBjYXNlIENvbnN0YW50cy5UX1NIT1JUOgotICAgIGNhc2UgQ29uc3RhbnRzLlRfSU5UOiAgICByZXR1cm4gbmV3IElMT0FEKGluZGV4KTsKLSAgICBjYXNlIENvbnN0YW50cy5UX0ZMT0FUOiAgcmV0dXJuIG5ldyBGTE9BRChpbmRleCk7Ci0gICAgY2FzZSBDb25zdGFudHMuVF9ET1VCTEU6IHJldHVybiBuZXcgRExPQUQoaW5kZXgpOwotICAgIGNhc2UgQ29uc3RhbnRzLlRfTE9ORzogICByZXR1cm4gbmV3IExMT0FEKGluZGV4KTsKLSAgICBjYXNlIENvbnN0YW50cy5UX0FSUkFZOgotICAgIGNhc2UgQ29uc3RhbnRzLlRfT0JKRUNUOiByZXR1cm4gbmV3IEFMT0FEKGluZGV4KTsKLSAgICBkZWZhdWx0OiAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiSW52YWxpZCB0eXBlICIgKyB0eXBlKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIHR5cGUgdHlwZSBvZiBlbGVtZW50cyBvZiBhcnJheSwgaS5lLiwgYXJyYXkuZ2V0RWxlbWVudFR5cGUoKQotICAgKi8KLSAgcHVibGljIHN0YXRpYyBBcnJheUluc3RydWN0aW9uIGNyZWF0ZUFycmF5TG9hZChUeXBlIHR5cGUpIHsKLSAgICBzd2l0Y2godHlwZS5nZXRUeXBlKCkpIHsKLSAgICBjYXNlIENvbnN0YW50cy5UX0JPT0xFQU46Ci0gICAgY2FzZSBDb25zdGFudHMuVF9CWVRFOiAgIHJldHVybiBCQUxPQUQ7Ci0gICAgY2FzZSBDb25zdGFudHMuVF9DSEFSOiAgIHJldHVybiBDQUxPQUQ7Ci0gICAgY2FzZSBDb25zdGFudHMuVF9TSE9SVDogIHJldHVybiBTQUxPQUQ7Ci0gICAgY2FzZSBDb25zdGFudHMuVF9JTlQ6ICAgIHJldHVybiBJQUxPQUQ7Ci0gICAgY2FzZSBDb25zdGFudHMuVF9GTE9BVDogIHJldHVybiBGQUxPQUQ7Ci0gICAgY2FzZSBDb25zdGFudHMuVF9ET1VCTEU6IHJldHVybiBEQUxPQUQ7Ci0gICAgY2FzZSBDb25zdGFudHMuVF9MT05HOiAgIHJldHVybiBMQUxPQUQ7Ci0gICAgY2FzZSBDb25zdGFudHMuVF9BUlJBWToKLSAgICBjYXNlIENvbnN0YW50cy5UX09CSkVDVDogcmV0dXJuIEFBTE9BRDsKLSAgICBkZWZhdWx0OiAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiSW52YWxpZCB0eXBlICIgKyB0eXBlKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIHR5cGUgdHlwZSBvZiBlbGVtZW50cyBvZiBhcnJheSwgaS5lLiwgYXJyYXkuZ2V0RWxlbWVudFR5cGUoKQotICAgKi8KLSAgcHVibGljIHN0YXRpYyBBcnJheUluc3RydWN0aW9uIGNyZWF0ZUFycmF5U3RvcmUoVHlwZSB0eXBlKSB7Ci0gICAgc3dpdGNoKHR5cGUuZ2V0VHlwZSgpKSB7Ci0gICAgY2FzZSBDb25zdGFudHMuVF9CT09MRUFOOgotICAgIGNhc2UgQ29uc3RhbnRzLlRfQllURTogICByZXR1cm4gQkFTVE9SRTsKLSAgICBjYXNlIENvbnN0YW50cy5UX0NIQVI6ICAgcmV0dXJuIENBU1RPUkU7Ci0gICAgY2FzZSBDb25zdGFudHMuVF9TSE9SVDogIHJldHVybiBTQVNUT1JFOwotICAgIGNhc2UgQ29uc3RhbnRzLlRfSU5UOiAgICByZXR1cm4gSUFTVE9SRTsKLSAgICBjYXNlIENvbnN0YW50cy5UX0ZMT0FUOiAgcmV0dXJuIEZBU1RPUkU7Ci0gICAgY2FzZSBDb25zdGFudHMuVF9ET1VCTEU6IHJldHVybiBEQVNUT1JFOwotICAgIGNhc2UgQ29uc3RhbnRzLlRfTE9ORzogICByZXR1cm4gTEFTVE9SRTsKLSAgICBjYXNlIENvbnN0YW50cy5UX0FSUkFZOgotICAgIGNhc2UgQ29uc3RhbnRzLlRfT0JKRUNUOiByZXR1cm4gQUFTVE9SRTsKLSAgICBkZWZhdWx0OiAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiSW52YWxpZCB0eXBlICIgKyB0eXBlKTsKLSAgICB9Ci0gIH0KLQotCi0gIC8qKiBDcmVhdGUgY29udmVyc2lvbiBvcGVyYXRpb24gZm9yIHR3byBzdGFjayBvcGVyYW5kcywgdGhpcyBtYXkgYmUgYW4gSTJDLCBpbnN0cnVjdGlvbiwgZS5nLiwKLSAgICogaWYgdGhlIG9wZXJhbmRzIGFyZSBiYXNpYyB0eXBlcyBhbmQgQ0hFQ0tDQVNUIGlmIHRoZXkgYXJlIHJlZmVyZW5jZSB0eXBlcy4KLSAgICovCi0gIHB1YmxpYyBJbnN0cnVjdGlvbiBjcmVhdGVDYXN0KFR5cGUgc3JjX3R5cGUsIFR5cGUgZGVzdF90eXBlKSB7Ci0gICAgaWYoKHNyY190eXBlIGluc3RhbmNlb2YgQmFzaWNUeXBlKSAmJiAoZGVzdF90eXBlIGluc3RhbmNlb2YgQmFzaWNUeXBlKSkgewotICAgICAgYnl0ZSBkZXN0ID0gZGVzdF90eXBlLmdldFR5cGUoKTsKLSAgICAgIGJ5dGUgc3JjICA9IHNyY190eXBlLmdldFR5cGUoKTsKLQotICAgICAgaWYoZGVzdCA9PSBDb25zdGFudHMuVF9MT05HICYmIChzcmMgPT0gQ29uc3RhbnRzLlRfQ0hBUiB8fCBzcmMgPT0gQ29uc3RhbnRzLlRfQllURSB8fAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcmMgPT0gQ29uc3RhbnRzLlRfU0hPUlQpKQotICAgICAgICBzcmMgPSBDb25zdGFudHMuVF9JTlQ7Ci0KLSAgICAgIFN0cmluZ1tdIHNob3J0X25hbWVzID0geyAiQyIsICJGIiwgIkQiLCAiQiIsICJTIiwgIkkiLCAiTCIgfTsKLQotICAgICAgU3RyaW5nIG5hbWUgPSAiY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy4iICsgc2hvcnRfbmFtZXNbc3JjIC0gQ29uc3RhbnRzLlRfQ0hBUl0gKwotICAgICAgICAiMiIgKyBzaG9ydF9uYW1lc1tkZXN0IC0gQ29uc3RhbnRzLlRfQ0hBUl07Ci0KLSAgICAgIEluc3RydWN0aW9uIGkgPSBudWxsOwotICAgICAgdHJ5IHsKLSAgICAgICAgaSA9IChJbnN0cnVjdGlvbilqYXZhLmxhbmcuQ2xhc3MuZm9yTmFtZShuYW1lKS5uZXdJbnN0YW5jZSgpOwotICAgICAgfSBjYXRjaChFeGNlcHRpb24gZSkgewotICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiQ291bGQgbm90IGZpbmQgaW5zdHJ1Y3Rpb246ICIgKyBuYW1lKTsKLSAgICAgIH0KLQotICAgICAgcmV0dXJuIGk7Ci0gICAgfSBlbHNlIGlmKChzcmNfdHlwZSBpbnN0YW5jZW9mIFJlZmVyZW5jZVR5cGUpICYmIChkZXN0X3R5cGUgaW5zdGFuY2VvZiBSZWZlcmVuY2VUeXBlKSkgewotICAgICAgaWYoZGVzdF90eXBlIGluc3RhbmNlb2YgQXJyYXlUeXBlKQotICAgICAgICByZXR1cm4gbmV3IENIRUNLQ0FTVChjcC5hZGRBcnJheUNsYXNzKChBcnJheVR5cGUpZGVzdF90eXBlKSk7Ci0gICAgICBlbHNlCi0gICAgICAgIHJldHVybiBuZXcgQ0hFQ0tDQVNUKGNwLmFkZENsYXNzKCgoT2JqZWN0VHlwZSlkZXN0X3R5cGUpLmdldENsYXNzTmFtZSgpKSk7Ci0gICAgfQotICAgIGVsc2UKLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJDYW4gbm90IGNhc3QgIiArIHNyY190eXBlICsgIiB0byAiICsgZGVzdF90eXBlKTsKLSAgfQotCi0gIHB1YmxpYyBHRVRGSUVMRCBjcmVhdGVHZXRGaWVsZChTdHJpbmcgY2xhc3NfbmFtZSwgU3RyaW5nIG5hbWUsIFR5cGUgdCkgewotICAgIHJldHVybiBuZXcgR0VURklFTEQoY3AuYWRkRmllbGRyZWYoY2xhc3NfbmFtZSwgbmFtZSwgdC5nZXRTaWduYXR1cmUoKSkpOwotICB9Ci0KLSAgcHVibGljIEdFVFNUQVRJQyBjcmVhdGVHZXRTdGF0aWMoU3RyaW5nIGNsYXNzX25hbWUsIFN0cmluZyBuYW1lLCBUeXBlIHQpIHsKLSAgICByZXR1cm4gbmV3IEdFVFNUQVRJQyhjcC5hZGRGaWVsZHJlZihjbGFzc19uYW1lLCBuYW1lLCB0LmdldFNpZ25hdHVyZSgpKSk7Ci0gIH0KLQotICBwdWJsaWMgUFVURklFTEQgY3JlYXRlUHV0RmllbGQoU3RyaW5nIGNsYXNzX25hbWUsIFN0cmluZyBuYW1lLCBUeXBlIHQpIHsKLSAgICByZXR1cm4gbmV3IFBVVEZJRUxEKGNwLmFkZEZpZWxkcmVmKGNsYXNzX25hbWUsIG5hbWUsIHQuZ2V0U2lnbmF0dXJlKCkpKTsKLSAgfQotCi0gIHB1YmxpYyBQVVRTVEFUSUMgY3JlYXRlUHV0U3RhdGljKFN0cmluZyBjbGFzc19uYW1lLCBTdHJpbmcgbmFtZSwgVHlwZSB0KSB7Ci0gICAgcmV0dXJuIG5ldyBQVVRTVEFUSUMoY3AuYWRkRmllbGRyZWYoY2xhc3NfbmFtZSwgbmFtZSwgdC5nZXRTaWduYXR1cmUoKSkpOwotICB9Ci0KLSAgcHVibGljIENIRUNLQ0FTVCBjcmVhdGVDaGVja0Nhc3QoUmVmZXJlbmNlVHlwZSB0KSB7Ci0gICAgaWYodCBpbnN0YW5jZW9mIEFycmF5VHlwZSkKLSAgICAgIHJldHVybiBuZXcgQ0hFQ0tDQVNUKGNwLmFkZEFycmF5Q2xhc3MoKEFycmF5VHlwZSl0KSk7Ci0gICAgZWxzZQotICAgICAgcmV0dXJuIG5ldyBDSEVDS0NBU1QoY3AuYWRkQ2xhc3MoKE9iamVjdFR5cGUpdCkpOwotICB9Ci0KLSAgcHVibGljIElOU1RBTkNFT0YgY3JlYXRlSW5zdGFuY2VPZihSZWZlcmVuY2VUeXBlIHQpIHsKLSAgICBpZih0IGluc3RhbmNlb2YgQXJyYXlUeXBlKQotICAgICAgcmV0dXJuIG5ldyBJTlNUQU5DRU9GKGNwLmFkZEFycmF5Q2xhc3MoKEFycmF5VHlwZSl0KSk7Ci0gICAgZWxzZQotICAgICAgcmV0dXJuIG5ldyBJTlNUQU5DRU9GKGNwLmFkZENsYXNzKChPYmplY3RUeXBlKXQpKTsKLSAgfQotCi0gIHB1YmxpYyBORVcgY3JlYXRlTmV3KE9iamVjdFR5cGUgdCkgewotICAgIHJldHVybiBuZXcgTkVXKGNwLmFkZENsYXNzKHQpKTsKLSAgfQotCi0gIHB1YmxpYyBORVcgY3JlYXRlTmV3KFN0cmluZyBzKSB7Ci0gICAgcmV0dXJuIGNyZWF0ZU5ldyhuZXcgT2JqZWN0VHlwZShzKSk7Ci0gIH0KLQotICAvKiogQ3JlYXRlIG5ldyBhcnJheSBvZiBnaXZlbiBzaXplIGFuZCB0eXBlLgotICAgKiBAcmV0dXJuIGFuIGluc3RydWN0aW9uIHRoYXQgY3JlYXRlcyB0aGUgY29ycmVzcG9uZGluZyBhcnJheSBhdCBydW50aW1lLCBpLmUuIGlzIGFuIEFsbG9jYXRpb25JbnN0cnVjdGlvbgotICAgKi8KLSAgcHVibGljIEluc3RydWN0aW9uIGNyZWF0ZU5ld0FycmF5KFR5cGUgdCwgc2hvcnQgZGltKSB7Ci0gICAgaWYoZGltID09IDEpIHsKLSAgICAgIGlmKHQgaW5zdGFuY2VvZiBPYmplY3RUeXBlKQotICAgICAgICByZXR1cm4gbmV3IEFORVdBUlJBWShjcC5hZGRDbGFzcygoT2JqZWN0VHlwZSl0KSk7Ci0gICAgICBlbHNlIGlmKHQgaW5zdGFuY2VvZiBBcnJheVR5cGUpCi0gICAgICAgIHJldHVybiBuZXcgQU5FV0FSUkFZKGNwLmFkZEFycmF5Q2xhc3MoKEFycmF5VHlwZSl0KSk7Ci0gICAgICBlbHNlCi0gICAgICAgIHJldHVybiBuZXcgTkVXQVJSQVkoKChCYXNpY1R5cGUpdCkuZ2V0VHlwZSgpKTsKLSAgICB9IGVsc2UgewotICAgICAgQXJyYXlUeXBlIGF0OwotCi0gICAgICBpZih0IGluc3RhbmNlb2YgQXJyYXlUeXBlKQotICAgICAgICBhdCA9IChBcnJheVR5cGUpdDsKLSAgICAgIGVsc2UKLSAgICAgICAgYXQgPSBuZXcgQXJyYXlUeXBlKHQsIGRpbSk7Ci0KLSAgICAgIHJldHVybiBuZXcgTVVMVElBTkVXQVJSQVkoY3AuYWRkQXJyYXlDbGFzcyhhdCksIGRpbSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqIENyZWF0ZSAibnVsbCIgdmFsdWUgZm9yIHJlZmVyZW5jZSB0eXBlcywgMCBmb3IgYmFzaWMgdHlwZXMgbGlrZSBpbnQKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgSW5zdHJ1Y3Rpb24gY3JlYXRlTnVsbChUeXBlIHR5cGUpIHsKLSAgICBzd2l0Y2godHlwZS5nZXRUeXBlKCkpIHsKLSAgICBjYXNlIENvbnN0YW50cy5UX0FSUkFZOgotICAgIGNhc2UgQ29uc3RhbnRzLlRfT0JKRUNUOiAgcmV0dXJuIEFDT05TVF9OVUxMOwotICAgIGNhc2UgQ29uc3RhbnRzLlRfSU5UOgotICAgIGNhc2UgQ29uc3RhbnRzLlRfU0hPUlQ6Ci0gICAgY2FzZSBDb25zdGFudHMuVF9CT09MRUFOOgotICAgIGNhc2UgQ29uc3RhbnRzLlRfQ0hBUjoKLSAgICBjYXNlIENvbnN0YW50cy5UX0JZVEU6ICAgIHJldHVybiBJQ09OU1RfMDsKLSAgICBjYXNlIENvbnN0YW50cy5UX0ZMT0FUOiAgIHJldHVybiBGQ09OU1RfMDsKLSAgICBjYXNlIENvbnN0YW50cy5UX0RPVUJMRTogIHJldHVybiBEQ09OU1RfMDsKLSAgICBjYXNlIENvbnN0YW50cy5UX0xPTkc6ICAgIHJldHVybiBMQ09OU1RfMDsKLSAgICBjYXNlIENvbnN0YW50cy5UX1ZPSUQ6ICAgIHJldHVybiBOT1A7Ci0KLSAgICBkZWZhdWx0OgotICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIkludmFsaWQgdHlwZTogIiArIHR5cGUpOwotICAgIH0KLSAgfQotCi0gIC8qKiBDcmVhdGUgYnJhbmNoIGluc3RydWN0aW9uIGJ5IGdpdmVuIG9wY29kZSwgZXhjZXB0IExPT0tVUFNXSVRDSCBhbmQgVEFCTEVTV0lUQ0guCi0gICAqIEZvciB0aG9zZSB5b3Ugc2hvdWxkIHVzZSB0aGUgU1dJVENIIGNvbXBvdW5kIGluc3RydWN0aW9uLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBCcmFuY2hJbnN0cnVjdGlvbiBjcmVhdGVCcmFuY2hJbnN0cnVjdGlvbihzaG9ydCBvcGNvZGUsIEluc3RydWN0aW9uSGFuZGxlIHRhcmdldCkgewotICAgIHN3aXRjaChvcGNvZGUpIHsKLSAgICBjYXNlIENvbnN0YW50cy5JRkVROiAgICAgIHJldHVybiBuZXcgSUZFUSh0YXJnZXQpOwotICAgIGNhc2UgQ29uc3RhbnRzLklGTkU6ICAgICAgcmV0dXJuIG5ldyBJRk5FKHRhcmdldCk7Ci0gICAgY2FzZSBDb25zdGFudHMuSUZMVDogICAgICByZXR1cm4gbmV3IElGTFQodGFyZ2V0KTsKLSAgICBjYXNlIENvbnN0YW50cy5JRkdFOiAgICAgIHJldHVybiBuZXcgSUZHRSh0YXJnZXQpOwotICAgIGNhc2UgQ29uc3RhbnRzLklGR1Q6ICAgICAgcmV0dXJuIG5ldyBJRkdUKHRhcmdldCk7Ci0gICAgY2FzZSBDb25zdGFudHMuSUZMRTogICAgICByZXR1cm4gbmV3IElGTEUodGFyZ2V0KTsKLSAgICBjYXNlIENvbnN0YW50cy5JRl9JQ01QRVE6IHJldHVybiBuZXcgSUZfSUNNUEVRKHRhcmdldCk7Ci0gICAgY2FzZSBDb25zdGFudHMuSUZfSUNNUE5FOiByZXR1cm4gbmV3IElGX0lDTVBORSh0YXJnZXQpOwotICAgIGNhc2UgQ29uc3RhbnRzLklGX0lDTVBMVDogcmV0dXJuIG5ldyBJRl9JQ01QTFQodGFyZ2V0KTsKLSAgICBjYXNlIENvbnN0YW50cy5JRl9JQ01QR0U6IHJldHVybiBuZXcgSUZfSUNNUEdFKHRhcmdldCk7Ci0gICAgY2FzZSBDb25zdGFudHMuSUZfSUNNUEdUOiByZXR1cm4gbmV3IElGX0lDTVBHVCh0YXJnZXQpOwotICAgIGNhc2UgQ29uc3RhbnRzLklGX0lDTVBMRTogcmV0dXJuIG5ldyBJRl9JQ01QTEUodGFyZ2V0KTsKLSAgICBjYXNlIENvbnN0YW50cy5JRl9BQ01QRVE6IHJldHVybiBuZXcgSUZfQUNNUEVRKHRhcmdldCk7Ci0gICAgY2FzZSBDb25zdGFudHMuSUZfQUNNUE5FOiByZXR1cm4gbmV3IElGX0FDTVBORSh0YXJnZXQpOwotICAgIGNhc2UgQ29uc3RhbnRzLkdPVE86ICAgICAgcmV0dXJuIG5ldyBHT1RPKHRhcmdldCk7Ci0gICAgY2FzZSBDb25zdGFudHMuSlNSOiAgICAgICByZXR1cm4gbmV3IEpTUih0YXJnZXQpOwotICAgIGNhc2UgQ29uc3RhbnRzLklGTlVMTDogICAgcmV0dXJuIG5ldyBJRk5VTEwodGFyZ2V0KTsKLSAgICBjYXNlIENvbnN0YW50cy5JRk5PTk5VTEw6IHJldHVybiBuZXcgSUZOT05OVUxMKHRhcmdldCk7Ci0gICAgY2FzZSBDb25zdGFudHMuR09UT19XOiAgICByZXR1cm4gbmV3IEdPVE9fVyh0YXJnZXQpOwotICAgIGNhc2UgQ29uc3RhbnRzLkpTUl9XOiAgICAgcmV0dXJuIG5ldyBKU1JfVyh0YXJnZXQpOwotICAgIGRlZmF1bHQ6Ci0gICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJJbnZhbGlkIG9wY29kZTogIiArIG9wY29kZSk7Ci0gICAgfQotICB9Ci0KLSAgcHVibGljIHZvaWQgICAgICAgICAgICBzZXRDbGFzc0dlbihDbGFzc0dlbiBjKSAgICAgICAgICAgIHsgY2cgPSBjOyB9Ci0gIHB1YmxpYyBDbGFzc0dlbiAgICAgICAgZ2V0Q2xhc3NHZW4oKSAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBjZzsgfQotICBwdWJsaWMgdm9pZCAgICAgICAgICAgIHNldENvbnN0YW50UG9vbChDb25zdGFudFBvb2xHZW4gYykgeyBjcCA9IGM7IH0KLSAgcHVibGljIENvbnN0YW50UG9vbEdlbiBnZXRDb25zdGFudFBvb2woKSAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIGNwOyB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JbnN0cnVjdGlvbkhhbmRsZS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSW5zdHJ1Y3Rpb25IYW5kbGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNjU5NGUwMS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JbnN0cnVjdGlvbkhhbmRsZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjg3ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5jbGFzc2ZpbGUuVXRpbGl0eTsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaFNldDsKLWltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKLQotLyoqCi0gKiBJbnN0YW5jZXMgb2YgdGhpcyBjbGFzcyBnaXZlIHVzZXJzIGEgaGFuZGxlIHRvIHRoZSBpbnN0cnVjdGlvbnMgY29udGFpbmVkIGluCi0gKiBhbiBJbnN0cnVjdGlvbkxpc3QuIEluc3RydWN0aW9uIG9iamVjdHMgbWF5IGJlIHVzZWQgbW9yZSB0aGFuIG9uY2Ugd2l0aGluIGEKLSAqIGxpc3QsIHRoaXMgaXMgdXNlZnVsIGJlY2F1c2UgaXQgc2F2ZXMgbWVtb3J5IGFuZCBtYXkgYmUgbXVjaCBmYXN0ZXIuCi0gKgotICogV2l0aGluIGFuIEluc3RydWN0aW9uTGlzdCBhbiBJbnN0cnVjdGlvbkhhbmRsZSBvYmplY3QgaXMgd3JhcHBlZAotICogYXJvdW5kIGFsbCBpbnN0cnVjdGlvbnMsIGkuZS4sIGl0IGltcGxlbWVudHMgYSBjZWxsIGluIGEKLSAqIGRvdWJseS1saW5rZWQgbGlzdC4gRnJvbSB0aGUgb3V0c2lkZSBvbmx5IHRoZSBuZXh0IGFuZCB0aGUKLSAqIHByZXZpb3VzIGluc3RydWN0aW9uIChoYW5kbGUpIGFyZSBhY2Nlc3NpYmxlLiBPbmUKLSAqIGNhbiB0cmF2ZXJzZSB0aGUgbGlzdCB2aWEgYW4gRW51bWVyYXRpb24gcmV0dXJuZWQgYnkKLSAqIEluc3RydWN0aW9uTGlzdC5lbGVtZW50cygpLgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKiBAc2VlIEluc3RydWN0aW9uCi0gKiBAc2VlIEJyYW5jaEhhbmRsZQotICogQHNlZSBJbnN0cnVjdGlvbkxpc3QKLSAqLwotcHVibGljIGNsYXNzIEluc3RydWN0aW9uSGFuZGxlIGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUgewotICBJbnN0cnVjdGlvbkhhbmRsZSBuZXh0LCBwcmV2OyAgLy8gV2lsbCBiZSBzZXQgZnJvbSB0aGUgb3V0c2lkZQotICBJbnN0cnVjdGlvbiAgICAgICBpbnN0cnVjdGlvbjsKLSAgcHJvdGVjdGVkIGludCAgICAgaV9wb3NpdGlvbiA9IC0xOyAvLyBieXRlIGNvZGUgb2Zmc2V0IG9mIGluc3RydWN0aW9uCi0gIHByaXZhdGUgSGFzaFNldCAgIHRhcmdldGVyczsKLSAgcHJpdmF0ZSBIYXNoTWFwICAgYXR0cmlidXRlczsKLQotICBwdWJsaWMgZmluYWwgSW5zdHJ1Y3Rpb25IYW5kbGUgZ2V0TmV4dCgpICAgICAgICB7IHJldHVybiBuZXh0OyB9Ci0gIHB1YmxpYyBmaW5hbCBJbnN0cnVjdGlvbkhhbmRsZSBnZXRQcmV2KCkgICAgICAgIHsgcmV0dXJuIHByZXY7IH0KLSAgcHVibGljIGZpbmFsIEluc3RydWN0aW9uICAgICAgIGdldEluc3RydWN0aW9uKCkgeyByZXR1cm4gaW5zdHJ1Y3Rpb247IH0KLQotICAvKioKLSAgICogUmVwbGFjZSBjdXJyZW50IGluc3RydWN0aW9uIGNvbnRhaW5lZCBpbiB0aGlzIGhhbmRsZS4KLSAgICogT2xkIGluc3RydWN0aW9uIGlzIGRpc3Bvc2VkIHVzaW5nIEluc3RydWN0aW9uLmRpc3Bvc2UoKS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldEluc3RydWN0aW9uKEluc3RydWN0aW9uIGkpIHsgLy8gT3ZlcnJpZGRlbiBpbiBCcmFuY2hIYW5kbGUKLSAgICBpZihpID09IG51bGwpCi0gICAgICB0aHJvdyBuZXcgQ2xhc3NHZW5FeGNlcHRpb24oIkFzc2lnbmluZyBudWxsIHRvIGhhbmRsZSIpOwotCi0gICAgaWYoKHRoaXMuZ2V0Q2xhc3MoKSAhPSBCcmFuY2hIYW5kbGUuY2xhc3MpICYmIChpIGluc3RhbmNlb2YgQnJhbmNoSW5zdHJ1Y3Rpb24pKQotICAgICAgdGhyb3cgbmV3IENsYXNzR2VuRXhjZXB0aW9uKCJBc3NpZ25pbmcgYnJhbmNoIGluc3RydWN0aW9uICIgKyBpICsgIiB0byBwbGFpbiBoYW5kbGUiKTsKLQotICAgIGlmKGluc3RydWN0aW9uICE9IG51bGwpCi0gICAgICBpbnN0cnVjdGlvbi5kaXNwb3NlKCk7Ci0KLSAgICBpbnN0cnVjdGlvbiA9IGk7Ci0gIH0KLQotICAvKioKLSAgICogVGVtcG9yYXJpbHkgc3dhcCB0aGUgY3VycmVudCBpbnN0cnVjdGlvbiwgd2l0aG91dCBkaXN0dXJiaW5nCi0gICAqIGFueXRoaW5nLiBNZWFudCB0byBiZSB1c2VkIGJ5IGEgZGVidWdnZXIsIGltcGxlbWVudGluZwotICAgKiBicmVha3BvaW50cy4gQ3VycmVudCBpbnN0cnVjdGlvbiBpcyByZXR1cm5lZC4KLSAgICovCi0gIHB1YmxpYyBJbnN0cnVjdGlvbiBzd2FwSW5zdHJ1Y3Rpb24oSW5zdHJ1Y3Rpb24gaSkgewotICAgIEluc3RydWN0aW9uIG9sZEluc3RydWN0aW9uID0gaW5zdHJ1Y3Rpb247Ci0gICAgaW5zdHJ1Y3Rpb24gPSBpOwotICAgIHJldHVybiBvbGRJbnN0cnVjdGlvbjsKLSAgfQotCi0gIC8qcHJpdmF0ZSovIHByb3RlY3RlZCBJbnN0cnVjdGlvbkhhbmRsZShJbnN0cnVjdGlvbiBpKSB7Ci0gICAgc2V0SW5zdHJ1Y3Rpb24oaSk7Ci0gIH0KLQotICBwcml2YXRlIHN0YXRpYyBJbnN0cnVjdGlvbkhhbmRsZSBpaF9saXN0ID0gbnVsbDsgLy8gTGlzdCBvZiByZXVzYWJsZSBoYW5kbGVzCi0KLSAgLyoqIEZhY3RvcnkgbWV0aG9kLgotICAgKi8KLSAgc3RhdGljIGZpbmFsIEluc3RydWN0aW9uSGFuZGxlIGdldEluc3RydWN0aW9uSGFuZGxlKEluc3RydWN0aW9uIGkpIHsKLSAgICBpZihpaF9saXN0ID09IG51bGwpCi0gICAgICByZXR1cm4gbmV3IEluc3RydWN0aW9uSGFuZGxlKGkpOwotICAgIGVsc2UgewotICAgICAgSW5zdHJ1Y3Rpb25IYW5kbGUgaWggPSBpaF9saXN0OwotICAgICAgaWhfbGlzdCA9IGloLm5leHQ7Ci0KLSAgICAgIGloLnNldEluc3RydWN0aW9uKGkpOwotCi0gICAgICByZXR1cm4gaWg7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIENhbGxlZCBieSBJbnN0cnVjdGlvbkxpc3Quc2V0UG9zaXRpb25zIHdoZW4gc2V0dGluZyB0aGUgcG9zaXRpb24gZm9yIGV2ZXJ5Ci0gICAqIGluc3RydWN0aW9uLiBJbiB0aGUgcHJlc2VuY2Ugb2YgdmFyaWFibGUgbGVuZ3RoIGluc3RydWN0aW9ucyBgc2V0UG9zaXRpb25zKCknCi0gICAqIHBlcmZvcm1zIG11bHRpcGxlIHBhc3NlcyBvdmVyIHRoZSBpbnN0cnVjdGlvbiBsaXN0IHRvIGNhbGN1bGF0ZSB0aGUKLSAgICogY29ycmVjdCAoYnl0ZSkgcG9zaXRpb25zIGFuZCBvZmZzZXRzIGJ5IGNhbGxpbmcgdGhpcyBmdW5jdGlvbi4KLSAgICoKLSAgICogQHBhcmFtIG9mZnNldCBhZGRpdGlvbmFsIG9mZnNldCBjYXVzZWQgYnkgcHJlY2VkaW5nICh2YXJpYWJsZSBsZW5ndGgpIGluc3RydWN0aW9ucwotICAgKiBAcGFyYW0gbWF4X29mZnNldCB0aGUgbWF4aW11bSBvZmZzZXQgdGhhdCBtYXkgYmUgY2F1c2VkIGJ5IHRoZXNlIGluc3RydWN0aW9ucwotICAgKiBAcmV0dXJuIGFkZGl0aW9uYWwgb2Zmc2V0IGNhdXNlZCBieSBwb3NzaWJsZSBjaGFuZ2Ugb2YgdGhpcyBpbnN0cnVjdGlvbidzIGxlbmd0aAotICAgKi8KLSAgcHJvdGVjdGVkIGludCB1cGRhdGVQb3NpdGlvbihpbnQgb2Zmc2V0LCBpbnQgbWF4X29mZnNldCkgewotICAgIGlfcG9zaXRpb24gKz0gb2Zmc2V0OwotICAgIHJldHVybiAwOwotICB9Ci0KLSAgLyoqIEByZXR1cm4gdGhlIHBvc2l0aW9uLCBpLmUuLCB0aGUgYnl0ZSBjb2RlIG9mZnNldCBvZiB0aGUgY29udGFpbmVkCi0gICAqIGluc3RydWN0aW9uLiBUaGlzIGlzIGFjY3VyYXRlIG9ubHkgYWZ0ZXIKLSAgICogSW5zdHJ1Y3Rpb25MaXN0LnNldFBvc2l0aW9ucygpIGhhcyBiZWVuIGNhbGxlZC4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0UG9zaXRpb24oKSB7IHJldHVybiBpX3Bvc2l0aW9uOyB9Ci0KLSAgLyoqIFNldCB0aGUgcG9zaXRpb24sIGkuZS4sIHRoZSBieXRlIGNvZGUgb2Zmc2V0IG9mIHRoZSBjb250YWluZWQKLSAgICogaW5zdHJ1Y3Rpb24uCi0gICAqLwotICB2b2lkIHNldFBvc2l0aW9uKGludCBwb3MpIHsgaV9wb3NpdGlvbiA9IHBvczsgfQotCi0gIC8qKiBPdmVycmlkZGVuIGluIEJyYW5jaEhhbmRsZQotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgYWRkSGFuZGxlKCkgewotICAgIG5leHQgICAgPSBpaF9saXN0OwotICAgIGloX2xpc3QgPSB0aGlzOwotICB9Ci0KLSAgLyoqCi0gICAqIERlbGV0ZSBjb250ZW50cywgaS5lLiwgcmVtb3ZlIHVzZXIgYWNjZXNzIGFuZCBtYWtlIGhhbmRsZSByZXVzYWJsZS4KLSAgICovCi0gIHZvaWQgZGlzcG9zZSgpIHsKLSAgICBuZXh0ID0gcHJldiA9IG51bGw7Ci0gICAgaW5zdHJ1Y3Rpb24uZGlzcG9zZSgpOwotICAgIGluc3RydWN0aW9uID0gbnVsbDsKLSAgICBpX3Bvc2l0aW9uID0gLTE7Ci0gICAgYXR0cmlidXRlcyA9IG51bGw7Ci0gICAgcmVtb3ZlQWxsVGFyZ2V0ZXJzKCk7Ci0gICAgYWRkSGFuZGxlKCk7Ci0gIH0KLQotICAvKiogUmVtb3ZlIGFsbCB0YXJnZXRlcnMsIGlmIGFueS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHJlbW92ZUFsbFRhcmdldGVycygpIHsKLSAgICBpZih0YXJnZXRlcnMgIT0gbnVsbCkKLSAgICAgIHRhcmdldGVycy5jbGVhcigpOwotICB9Ci0KLSAgLyoqCi0gICAqIERlbm90ZSB0aGlzIGhhbmRsZSBpc24ndCByZWZlcmVuY2VkIGFueW1vcmUgYnkgdC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHJlbW92ZVRhcmdldGVyKEluc3RydWN0aW9uVGFyZ2V0ZXIgdCkgewotICAgIHRhcmdldGVycy5yZW1vdmUodCk7Ci0gIH0KLQotICAvKioKLSAgICogRGVub3RlIHRoaXMgaGFuZGxlIGlzIGJlaW5nIHJlZmVyZW5jZWQgYnkgdC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGFkZFRhcmdldGVyKEluc3RydWN0aW9uVGFyZ2V0ZXIgdCkgewotICAgIGlmKHRhcmdldGVycyA9PSBudWxsKQotICAgICAgdGFyZ2V0ZXJzID0gbmV3IEhhc2hTZXQoKTsKLQotICAgIC8vaWYoIXRhcmdldGVycy5jb250YWlucyh0KSkKLSAgICB0YXJnZXRlcnMuYWRkKHQpOwotICB9Ci0KLSAgcHVibGljIGJvb2xlYW4gaGFzVGFyZ2V0ZXJzKCkgewotICAgIHJldHVybiAodGFyZ2V0ZXJzICE9IG51bGwpICYmICh0YXJnZXRlcnMuc2l6ZSgpID4gMCk7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBudWxsLCBpZiB0aGVyZSBhcmUgbm8gdGFyZ2V0ZXJzCi0gICAqLwotICBwdWJsaWMgSW5zdHJ1Y3Rpb25UYXJnZXRlcltdIGdldFRhcmdldGVycygpIHsKLSAgICBpZighaGFzVGFyZ2V0ZXJzKCkpCi0gICAgICByZXR1cm4gbnVsbDsKLQotICAgIEluc3RydWN0aW9uVGFyZ2V0ZXJbXSB0ID0gbmV3IEluc3RydWN0aW9uVGFyZ2V0ZXJbdGFyZ2V0ZXJzLnNpemUoKV07Ci0gICAgdGFyZ2V0ZXJzLnRvQXJyYXkodCk7Ci0gICAgcmV0dXJuIHQ7Ci0gIH0KLQotICAvKiogQHJldHVybiBhICh2ZXJib3NlKSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGNvbnRhaW5lZCBpbnN0cnVjdGlvbi4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoYm9vbGVhbiB2ZXJib3NlKSB7Ci0gICAgcmV0dXJuIFV0aWxpdHkuZm9ybWF0KGlfcG9zaXRpb24sIDQsIGZhbHNlLCAnICcpICsgIjogIiArIGluc3RydWN0aW9uLnRvU3RyaW5nKHZlcmJvc2UpOwotICB9Ci0KLSAgLyoqIEByZXR1cm4gYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGNvbnRhaW5lZCBpbnN0cnVjdGlvbi4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0gICAgcmV0dXJuIHRvU3RyaW5nKHRydWUpOwotICB9Ci0KLSAgLyoqIEFkZCBhbiBhdHRyaWJ1dGUgdG8gYW4gaW5zdHJ1Y3Rpb24gaGFuZGxlLgotICAgKgotICAgKiBAcGFyYW0ga2V5IHRoZSBrZXkgb2JqZWN0IHRvIHN0b3JlL3JldHJpZXZlIHRoZSBhdHRyaWJ1dGUKLSAgICogQHBhcmFtIGF0dHIgdGhlIGF0dHJpYnV0ZSB0byBhc3NvY2lhdGUgd2l0aCB0aGlzIGhhbmRsZQotICAgKi8KLSAgcHVibGljIHZvaWQgYWRkQXR0cmlidXRlKE9iamVjdCBrZXksIE9iamVjdCBhdHRyKSB7Ci0gICAgaWYoYXR0cmlidXRlcyA9PSBudWxsKQotICAgICAgYXR0cmlidXRlcyA9IG5ldyBIYXNoTWFwKDMpOwotCi0gICAgYXR0cmlidXRlcy5wdXQoa2V5LCBhdHRyKTsKLSAgfQotCi0gIC8qKiBEZWxldGUgYW4gYXR0cmlidXRlIG9mIGFuIGluc3RydWN0aW9uIGhhbmRsZS4KLSAgICoKLSAgICogQHBhcmFtIGtleSB0aGUga2V5IG9iamVjdCB0byByZXRyaWV2ZSB0aGUgYXR0cmlidXRlCi0gICAqLwotICBwdWJsaWMgdm9pZCByZW1vdmVBdHRyaWJ1dGUoT2JqZWN0IGtleSkgewotICAgIGlmKGF0dHJpYnV0ZXMgIT0gbnVsbCkKLSAgICAgIGF0dHJpYnV0ZXMucmVtb3ZlKGtleSk7Ci0gIH0KLQotICAvKiogR2V0IGF0dHJpYnV0ZSBvZiBhbiBpbnN0cnVjdGlvbiBoYW5kbGUuCi0gICAqCi0gICAqIEBwYXJhbSBrZXkgdGhlIGtleSBvYmplY3QgdG8gc3RvcmUvcmV0cmlldmUgdGhlIGF0dHJpYnV0ZQotICAgKi8KLSAgcHVibGljIE9iamVjdCBnZXRBdHRyaWJ1dGUoT2JqZWN0IGtleSkgewotICAgIGlmKGF0dHJpYnV0ZXMgIT0gbnVsbCkKLSAgICAgIHJldHVybiBhdHRyaWJ1dGVzLmdldChrZXkpOwotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKiogQHJldHVybiBhbGwgYXR0cmlidXRlcyBhc3NvY2lhdGVkIHdpdGggdGhpcyBoYW5kbGUKLSAgICovCi0gIHB1YmxpYyBDb2xsZWN0aW9uIGdldEF0dHJpYnV0ZXMoKSB7Ci0gICAgcmV0dXJuIGF0dHJpYnV0ZXMudmFsdWVzKCk7Ci0gIH0KLQotICAvKiogQ29udmVuaWVuY2UgbWV0aG9kLCBzaW1wbHkgY2FsbHMgYWNjZXB0KCkgb24gdGhlIGNvbnRhaW5lZCBpbnN0cnVjdGlvbi4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICBpbnN0cnVjdGlvbi5hY2NlcHQodik7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0luc3RydWN0aW9uTGlzdC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSW5zdHJ1Y3Rpb25MaXN0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDIzNTk1MGYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSW5zdHJ1Y3Rpb25MaXN0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMjg5ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuY2xhc3NmaWxlLkNvbnN0YW50OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLnV0aWwuQnl0ZVNlcXVlbmNlOwotaW1wb3J0IGphdmEuaW8uKjsKLWltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7Ci1pbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7Ci1pbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGlzIGEgY29udGFpbmVyIGZvciBhIGxpc3Qgb2YgPGEKLSAqIGhyZWY9Ikluc3RydWN0aW9uLmh0bWwiPkluc3RydWN0aW9uPC9hPiBvYmplY3RzLiBJbnN0cnVjdGlvbnMgY2FuCi0gKiBiZSBhcHBlbmRlZCwgaW5zZXJ0ZWQsIG1vdmVkLCBkZWxldGVkLCBldGMuLiBJbnN0cnVjdGlvbnMgYXJlIGJlaW5nCi0gKiB3cmFwcGVkIGludG8gPGEKLSAqIGhyZWY9Ikluc3RydWN0aW9uSGFuZGxlLmh0bWwiPkluc3RydWN0aW9uSGFuZGxlczwvYT4gb2JqZWN0cyB0aGF0Ci0gKiBhcmUgcmV0dXJuZWQgdXBvbiBhcHBlbmQvaW5zZXJ0IG9wZXJhdGlvbnMuIFRoZXkgZ2l2ZSB0aGUgdXNlcgotICogKHJlYWQgb25seSkgYWNjZXNzIHRvIHRoZSBsaXN0IHN0cnVjdHVyZSwgc3VjaCB0aGF0IGl0IGNhbiBiZSB0cmF2ZXJzZWQgYW5kCi0gKiBtYW5pcHVsYXRlZCBpbiBhIGNvbnRyb2xsZWQgd2F5LgotICoKLSAqIEEgbGlzdCBpcyBmaW5hbGx5IGR1bXBlZCB0byBhIGJ5dGUgY29kZSBhcnJheSB3aXRoIDxhCi0gKiBocmVmPSIjZ2V0Qnl0ZUNvZGUoKSI+Z2V0Qnl0ZUNvZGU8L2E+LgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKiBAc2VlICAgICBJbnN0cnVjdGlvbgotICogQHNlZSAgICAgSW5zdHJ1Y3Rpb25IYW5kbGUKLSAqIEBzZWUgQnJhbmNoSGFuZGxlCi0gKi8KLXB1YmxpYyBjbGFzcyBJbnN0cnVjdGlvbkxpc3QgaW1wbGVtZW50cyBTZXJpYWxpemFibGUgewotICBwcml2YXRlIEluc3RydWN0aW9uSGFuZGxlIHN0YXJ0ICA9IG51bGwsIGVuZCA9IG51bGw7Ci0gIHByaXZhdGUgaW50ICAgICAgICAgICAgICAgbGVuZ3RoID0gMDsgLy8gbnVtYmVyIG9mIGVsZW1lbnRzIGluIGxpc3QKLSAgcHJpdmF0ZSBpbnRbXSAgICAgICAgICAgICBieXRlX3Bvc2l0aW9uczsgLy8gYnl0ZSBjb2RlIG9mZnNldHMgY29ycmVzcG9uZGluZyB0byBpbnN0cnVjdGlvbnMKLQotICAvKioKLSAgICogQ3JlYXRlIChlbXB0eSkgaW5zdHJ1Y3Rpb24gbGlzdC4KLSAgICovCi0gIHB1YmxpYyBJbnN0cnVjdGlvbkxpc3QoKSB7fQotCi0gIC8qKgotICAgKiBDcmVhdGUgaW5zdHJ1Y3Rpb24gbGlzdCBjb250YWluaW5nIG9uZSBpbnN0cnVjdGlvbi4KLSAgICogQHBhcmFtIGkgaW5pdGlhbCBpbnN0cnVjdGlvbgotICAgKi8KLSAgcHVibGljIEluc3RydWN0aW9uTGlzdChJbnN0cnVjdGlvbiBpKSB7Ci0gICAgYXBwZW5kKGkpOwotICB9Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBpbnN0cnVjdGlvbiBsaXN0IGNvbnRhaW5pbmcgb25lIGluc3RydWN0aW9uLgotICAgKiBAcGFyYW0gaSBpbml0aWFsIGluc3RydWN0aW9uCi0gICAqLwotICBwdWJsaWMgSW5zdHJ1Y3Rpb25MaXN0KEJyYW5jaEluc3RydWN0aW9uIGkpIHsKLSAgICBhcHBlbmQoaSk7Ci0gIH0KLQotICAvKioKLSAgICogSW5pdGlhbGl6ZSBsaXN0IHdpdGggKG5vbm51bGwpIGNvbXBvdW5kIGluc3RydWN0aW9uLiBDb25zdW1lcyBhcmd1bWVudAotICAgKiBsaXN0LCBpLmUuLCBpdCBiZWNvbWVzIGVtcHR5LgotICAgKgotICAgKiBAcGFyYW0gYyBjb21wb3VuZCBpbnN0cnVjdGlvbiAobGlzdCkKLSAgICovCi0gIHB1YmxpYyBJbnN0cnVjdGlvbkxpc3QoQ29tcG91bmRJbnN0cnVjdGlvbiBjKSB7Ci0gICAgYXBwZW5kKGMuZ2V0SW5zdHJ1Y3Rpb25MaXN0KCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlc3QgZm9yIGVtcHR5IGxpc3QuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBpc0VtcHR5KCkgeyByZXR1cm4gc3RhcnQgPT0gbnVsbDsgfSAvLyAmJiBlbmQgPT0gbnVsbAotCi0gIC8qKgotICAgKiBGaW5kIHRoZSB0YXJnZXQgaW5zdHJ1Y3Rpb24gKGhhbmRsZSkgdGhhdCBjb3JyZXNwb25kcyB0byB0aGUgZ2l2ZW4gdGFyZ2V0Ci0gICAqIHBvc2l0aW9uIChieXRlIGNvZGUgb2Zmc2V0KS4KLSAgICoKLSAgICogQHBhcmFtIGlocyBhcnJheSBvZiBpbnN0cnVjdGlvbiBoYW5kbGVzLCBpLmUuIGlsLmdldEluc3RydWN0aW9uSGFuZGxlcygpCi0gICAqIEBwYXJhbSBwb3MgYXJyYXkgb2YgcG9zaXRpb25zIGNvcnJlc3BvbmRpbmcgdG8gaWhzLCBpLmUuIGlsLmdldEluc3RydWN0aW9uUG9zaXRpb25zKCkKLSAgICogQHBhcmFtIGNvdW50IGxlbmd0aCBvZiBhcnJheXMKLSAgICogQHBhcmFtIHRhcmdldCB0YXJnZXQgcG9zaXRpb24gdG8gc2VhcmNoIGZvcgotICAgKiBAcmV0dXJuIHRhcmdldCBwb3NpdGlvbidzIGluc3RydWN0aW9uIGhhbmRsZSBpZiBhdmFpbGFibGUKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgSW5zdHJ1Y3Rpb25IYW5kbGUgZmluZEhhbmRsZShJbnN0cnVjdGlvbkhhbmRsZVtdIGlocywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludFtdIHBvcywgaW50IGNvdW50LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHRhcmdldCkgewotICAgIGludCBsPTAsIHIgPSBjb3VudCAtIDE7Ci0KLSAgICAvKiBEbyBhIGJpbmFyeSBzZWFyY2ggc2luY2UgdGhlIHBvcyBhcnJheSBpcyBvcmRlcmQuCi0gICAgICovCi0gICAgZG8gewotICAgICAgaW50IGkgPSAobCArIHIpIC8gMjsKLSAgICAgIGludCBqID0gcG9zW2ldOwotCi0gICAgICBpZihqID09IHRhcmdldCkgLy8gdGFyZ2V0IGZvdW5kCi0gICAgICAgIHJldHVybiBpaHNbaV07Ci0gICAgICBlbHNlIGlmKHRhcmdldCA8IGopIC8vIGVsc2UgY29uc3RyYWluIHNlYXJjaCBhcmVhCi0gICAgICAgIHIgPSBpIC0gMTsKLSAgICAgIGVsc2UgLy8gdGFyZ2V0ID4gagotICAgICAgICBsID0gaSArIDE7Ci0gICAgfSB3aGlsZShsIDw9IHIpOwotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IGluc3RydWN0aW9uIGhhbmRsZSBmb3IgaW5zdHJ1Y3Rpb24gYXQgYnl0ZSBjb2RlIHBvc2l0aW9uIHBvcy4KLSAgICogVGhpcyBvbmx5IHdvcmtzIHByb3Blcmx5LCBpZiB0aGUgbGlzdCBpcyBmcmVzaGx5IGluaXRpYWxpemVkIGZyb20gYSBieXRlIGFycmF5IG9yCi0gICAqIHNldFBvc2l0aW9ucygpIGhhcyBiZWVuIGNhbGxlZCBiZWZvcmUgdGhpcyBtZXRob2QuCi0gICAqCi0gICAqIEBwYXJhbSBwb3MgYnl0ZSBjb2RlIHBvc2l0aW9uIHRvIHNlYXJjaCBmb3IKLSAgICogQHJldHVybiB0YXJnZXQgcG9zaXRpb24ncyBpbnN0cnVjdGlvbiBoYW5kbGUgaWYgYXZhaWxhYmxlCi0gICAqLwotICBwdWJsaWMgSW5zdHJ1Y3Rpb25IYW5kbGUgZmluZEhhbmRsZShpbnQgcG9zKSB7Ci0gICAgSW5zdHJ1Y3Rpb25IYW5kbGVbXSBpaHMgPSBnZXRJbnN0cnVjdGlvbkhhbmRsZXMoKTsKLSAgICByZXR1cm4gZmluZEhhbmRsZShpaHMsIGJ5dGVfcG9zaXRpb25zLCBsZW5ndGgsIHBvcyk7Ci0gIH0KLQotICAvKioKLSAgICogSW5pdGlhbGl6ZSBpbnN0cnVjdGlvbiBsaXN0IGZyb20gYnl0ZSBhcnJheS4KLSAgICoKLSAgICogQHBhcmFtIGNvZGUgYnl0ZSBhcnJheSBjb250YWluaW5nIHRoZSBpbnN0cnVjdGlvbnMKLSAgICovCi0gIHB1YmxpYyBJbnN0cnVjdGlvbkxpc3QoYnl0ZVtdIGNvZGUpIHsKLSAgICBCeXRlU2VxdWVuY2UgICAgICAgIGJ5dGVzID0gbmV3IEJ5dGVTZXF1ZW5jZShjb2RlKTsKLSAgICBJbnN0cnVjdGlvbkhhbmRsZVtdIGlocyAgID0gbmV3IEluc3RydWN0aW9uSGFuZGxlW2NvZGUubGVuZ3RoXTsKLSAgICBpbnRbXSAgICAgICAgICAgICAgIHBvcyAgID0gbmV3IGludFtjb2RlLmxlbmd0aF07IC8vIENhbid0IGJlIG1vcmUgdGhhbiB0aGF0Ci0gICAgaW50ICAgICAgICAgICAgICAgICBjb3VudCA9IDA7IC8vIENvbnRhaW5zIGFjdHVhbCBsZW5ndGgKLQotICAgIC8qIFBhc3MgMTogQ3JlYXRlIGFuIG9iamVjdCBmb3IgZWFjaCBieXRlIGNvZGUgYW5kIGFwcGVuZCB0aGVtCi0gICAgICogdG8gdGhlIGxpc3QuCi0gICAgICovCi0gICAgdHJ5IHsKLSAgICAgIHdoaWxlKGJ5dGVzLmF2YWlsYWJsZSgpID4gMCkgewotICAgICAgICAvLyBSZW1lbWJlciBieXRlIG9mZnNldCBhbmQgYXNzb2NpYXRlIGl0IHdpdGggdGhlIGluc3RydWN0aW9uCi0gICAgICAgIGludCBvZmYgPSAgYnl0ZXMuZ2V0SW5kZXgoKTsKLSAgICAgICAgcG9zW2NvdW50XSA9IG9mZjsKLQotICAgICAgICAvKiBSZWFkIG9uZSBpbnN0cnVjdGlvbiBmcm9tIHRoZSBieXRlIHN0cmVhbSwgdGhlIGJ5dGUgcG9zaXRpb24gaXMgc2V0Ci0gICAgICAgICAqIGFjY29yZGluZ2x5LgotICAgICAgICAgKi8KLSAgICAgICAgSW5zdHJ1Y3Rpb24gICAgICAgaSA9IEluc3RydWN0aW9uLnJlYWRJbnN0cnVjdGlvbihieXRlcyk7Ci0gICAgICAgIEluc3RydWN0aW9uSGFuZGxlIGloOwotICAgICAgICBpZihpIGluc3RhbmNlb2YgQnJhbmNoSW5zdHJ1Y3Rpb24pIC8vIFVzZSBwcm9wZXIgYXBwZW5kKCkgbWV0aG9kCi0gICAgICAgICAgaWggPSBhcHBlbmQoKEJyYW5jaEluc3RydWN0aW9uKWkpOwotICAgICAgICBlbHNlCi0gICAgICAgICAgaWggPSBhcHBlbmQoaSk7Ci0KLSAgICAgICAgaWguc2V0UG9zaXRpb24ob2ZmKTsKLSAgICAgICAgaWhzW2NvdW50XSA9IGloOwotCi0gICAgICAgIGNvdW50Kys7Ci0gICAgICB9Ci0gICAgfSBjYXRjaChJT0V4Y2VwdGlvbiBlKSB7IHRocm93IG5ldyBDbGFzc0dlbkV4Y2VwdGlvbihlLnRvU3RyaW5nKCkpOyB9Ci0KLSAgICBieXRlX3Bvc2l0aW9ucyA9IG5ldyBpbnRbY291bnRdOyAvLyBUcmltIHRvIHByb3BlciBzaXplCi0gICAgU3lzdGVtLmFycmF5Y29weShwb3MsIDAsIGJ5dGVfcG9zaXRpb25zLCAwLCBjb3VudCk7Ci0KLSAgICAvKiBQYXNzIDI6IExvb2sgZm9yIEJyYW5jaEluc3RydWN0aW9uIGFuZCB1cGRhdGUgdGhlaXIgdGFyZ2V0cywgaS5lLiwKLSAgICAgKiBjb252ZXJ0IG9mZnNldHMgdG8gaW5zdHJ1Y3Rpb24gaGFuZGxlcy4KLSAgICAgKi8KLSAgICBmb3IoaW50IGk9MDsgaSA8IGNvdW50OyBpKyspIHsKLSAgICAgIGlmKGloc1tpXSBpbnN0YW5jZW9mIEJyYW5jaEhhbmRsZSkgewotICAgICAgICBCcmFuY2hJbnN0cnVjdGlvbiBiaSA9IChCcmFuY2hJbnN0cnVjdGlvbilpaHNbaV0uaW5zdHJ1Y3Rpb247Ci0gICAgICAgIGludCB0YXJnZXQgPSBiaS5wb3NpdGlvbiArIGJpLmdldEluZGV4KCk7IC8qIEJ5dGUgY29kZSBwb3NpdGlvbjoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogcmVsYXRpdmUgLT4gYWJzb2x1dGUuICovCi0gICAgICAgIC8vIFNlYXJjaCBmb3IgdGFyZ2V0IHBvc2l0aW9uCi0gICAgICAgIEluc3RydWN0aW9uSGFuZGxlIGloID0gZmluZEhhbmRsZShpaHMsIHBvcywgY291bnQsIHRhcmdldCk7Ci0KLSAgICAgICAgaWYoaWggPT0gbnVsbCkgLy8gU2VhcmNoIGZhaWxlZAotICAgICAgICAgIHRocm93IG5ldyBDbGFzc0dlbkV4Y2VwdGlvbigiQ291bGRuJ3QgZmluZCB0YXJnZXQgZm9yIGJyYW5jaDogIiArIGJpKTsKLQotICAgICAgICBiaS5zZXRUYXJnZXQoaWgpOyAvLyBVcGRhdGUgdGFyZ2V0Ci0KLSAgICAgICAgLy8gSWYgaXQgaXMgYSBTZWxlY3QgaW5zdHJ1Y3Rpb24sIHVwZGF0ZSBhbGwgYnJhbmNoIHRhcmdldHMKLSAgICAgICAgaWYoYmkgaW5zdGFuY2VvZiBTZWxlY3QpIHsgLy8gRWl0aGVyIExPT0tVUFNXSVRDSCBvciBUQUJMRVNXSVRDSAotICAgICAgICAgIFNlbGVjdCBzICAgICAgID0gKFNlbGVjdCliaTsKLSAgICAgICAgICBpbnRbXSAgaW5kaWNlcyA9IHMuZ2V0SW5kaWNlcygpOwotCi0gICAgICAgICAgZm9yKGludCBqPTA7IGogPCBpbmRpY2VzLmxlbmd0aDsgaisrKSB7Ci0gICAgICAgICAgICB0YXJnZXQgPSBiaS5wb3NpdGlvbiArIGluZGljZXNbal07Ci0gICAgICAgICAgICBpaCAgICAgPSBmaW5kSGFuZGxlKGlocywgcG9zLCBjb3VudCwgdGFyZ2V0KTsKLQotICAgICAgICAgICAgaWYoaWggPT0gbnVsbCkgLy8gU2VhcmNoIGZhaWxlZAotICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2xhc3NHZW5FeGNlcHRpb24oIkNvdWxkbid0IGZpbmQgdGFyZ2V0IGZvciBzd2l0Y2g6ICIgKyBiaSk7Ci0KLSAgICAgICAgICAgIHMuc2V0VGFyZ2V0KGosIGloKTsgLy8gVXBkYXRlIHRhcmdldAotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBBcHBlbmQgYW5vdGhlciBsaXN0IGFmdGVyIGluc3RydWN0aW9uIChoYW5kbGUpIGloIGNvbnRhaW5lZCBpbiB0aGlzIGxpc3QuCi0gICAqIENvbnN1bWVzIGFyZ3VtZW50IGxpc3QsIGkuZS4sIGl0IGJlY29tZXMgZW1wdHkuCi0gICAqCi0gICAqIEBwYXJhbSBpaCB3aGVyZSB0byBhcHBlbmQgdGhlIGluc3RydWN0aW9uIGxpc3QKLSAgICogQHBhcmFtIGlsIEluc3RydWN0aW9uIGxpc3QgdG8gYXBwZW5kIHRvIHRoaXMgb25lCi0gICAqIEByZXR1cm4gaW5zdHJ1Y3Rpb24gaGFuZGxlIHBvaW50aW5nIHRvIHRoZSA8Qj5maXJzdDwvQj4gYXBwZW5kZWQgaW5zdHJ1Y3Rpb24KLSAgICovCi0gIHB1YmxpYyBJbnN0cnVjdGlvbkhhbmRsZSBhcHBlbmQoSW5zdHJ1Y3Rpb25IYW5kbGUgaWgsIEluc3RydWN0aW9uTGlzdCBpbCkgewotICAgIGlmKGlsID09IG51bGwpCi0gICAgICB0aHJvdyBuZXcgQ2xhc3NHZW5FeGNlcHRpb24oIkFwcGVuZGluZyBudWxsIEluc3RydWN0aW9uTGlzdCIpOwotCi0gICAgaWYoaWwuaXNFbXB0eSgpKSAvLyBOb3RoaW5nIHRvIGRvCi0gICAgICByZXR1cm4gaWg7Ci0KLSAgICBJbnN0cnVjdGlvbkhhbmRsZSBuZXh0ID0gaWgubmV4dCwgcmV0ID0gaWwuc3RhcnQ7Ci0KLSAgICBpaC5uZXh0ID0gaWwuc3RhcnQ7Ci0gICAgaWwuc3RhcnQucHJldiA9IGloOwotCi0gICAgaWwuZW5kLm5leHQgPSBuZXh0OwotCi0gICAgaWYobmV4dCAhPSBudWxsKSAvLyBpID09IGVuZCA/Ci0gICAgICBuZXh0LnByZXYgPSBpbC5lbmQ7Ci0gICAgZWxzZQotICAgICAgZW5kID0gaWwuZW5kOyAvLyBVcGRhdGUgZW5kIC4uLgotCi0gICAgbGVuZ3RoICs9IGlsLmxlbmd0aDsgLy8gVXBkYXRlIGxlbmd0aAotCi0gICAgaWwuY2xlYXIoKTsKLQotICAgIHJldHVybiByZXQ7Ci0gIH0KLQotICAvKioKLSAgICogQXBwZW5kIGFub3RoZXIgbGlzdCBhZnRlciBpbnN0cnVjdGlvbiBpIGNvbnRhaW5lZCBpbiB0aGlzIGxpc3QuCi0gICAqIENvbnN1bWVzIGFyZ3VtZW50IGxpc3QsIGkuZS4sIGl0IGJlY29tZXMgZW1wdHkuCi0gICAqCi0gICAqIEBwYXJhbSBpICB3aGVyZSB0byBhcHBlbmQgdGhlIGluc3RydWN0aW9uIGxpc3QKLSAgICogQHBhcmFtIGlsIEluc3RydWN0aW9uIGxpc3QgdG8gYXBwZW5kIHRvIHRoaXMgb25lCi0gICAqIEByZXR1cm4gaW5zdHJ1Y3Rpb24gaGFuZGxlIHBvaW50aW5nIHRvIHRoZSA8Qj5maXJzdDwvQj4gYXBwZW5kZWQgaW5zdHJ1Y3Rpb24KLSAgICovCi0gIHB1YmxpYyBJbnN0cnVjdGlvbkhhbmRsZSBhcHBlbmQoSW5zdHJ1Y3Rpb24gaSwgSW5zdHJ1Y3Rpb25MaXN0IGlsKSB7Ci0gICAgSW5zdHJ1Y3Rpb25IYW5kbGUgaWg7Ci0KLSAgICBpZigoaWggPSBmaW5kSW5zdHJ1Y3Rpb24yKGkpKSA9PSBudWxsKSAvLyBBbHNvIGFwcGxpZXMgZm9yIGVtcHR5IGxpc3QKLSAgICAgIHRocm93IG5ldyBDbGFzc0dlbkV4Y2VwdGlvbigiSW5zdHJ1Y3Rpb24gIiArIGkgKwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgaXMgbm90IGNvbnRhaW5lZCBpbiB0aGlzIGxpc3QuIik7Ci0KLSAgICByZXR1cm4gYXBwZW5kKGloLCBpbCk7Ci0gIH0KLQotICAvKioKLSAgICogQXBwZW5kIGFub3RoZXIgbGlzdCB0byB0aGlzIG9uZS4KLSAgICogQ29uc3VtZXMgYXJndW1lbnQgbGlzdCwgaS5lLiwgaXQgYmVjb21lcyBlbXB0eS4KLSAgICoKLSAgICogQHBhcmFtIGlsIGxpc3QgdG8gYXBwZW5kIHRvIGVuZCBvZiB0aGlzIGxpc3QKLSAgICogQHJldHVybiBpbnN0cnVjdGlvbiBoYW5kbGUgb2YgdGhlIDxCPmZpcnN0PC9CPiBhcHBlbmRlZCBpbnN0cnVjdGlvbgotICAgKi8KLSAgcHVibGljIEluc3RydWN0aW9uSGFuZGxlIGFwcGVuZChJbnN0cnVjdGlvbkxpc3QgaWwpIHsKLSAgICBpZihpbCA9PSBudWxsKQotICAgICAgdGhyb3cgbmV3IENsYXNzR2VuRXhjZXB0aW9uKCJBcHBlbmRpbmcgbnVsbCBJbnN0cnVjdGlvbkxpc3QiKTsKLQotICAgIGlmKGlsLmlzRW1wdHkoKSkgLy8gTm90aGluZyB0byBkbwotICAgICAgcmV0dXJuIG51bGw7Ci0KLSAgICBpZihpc0VtcHR5KCkpIHsKLSAgICAgIHN0YXJ0ICA9IGlsLnN0YXJ0OwotICAgICAgZW5kICAgID0gaWwuZW5kOwotICAgICAgbGVuZ3RoID0gaWwubGVuZ3RoOwotCi0gICAgICBpbC5jbGVhcigpOwotCi0gICAgICByZXR1cm4gc3RhcnQ7Ci0gICAgfSBlbHNlCi0gICAgICByZXR1cm4gYXBwZW5kKGVuZCwgaWwpOyAgLy8gd2FzIGVuZC5pbnN0cnVjdGlvbgotICB9Ci0KLSAgLyoqCi0gICAqIEFwcGVuZCBhbiBpbnN0cnVjdGlvbiB0byB0aGUgZW5kIG9mIHRoaXMgbGlzdC4KLSAgICoKLSAgICogQHBhcmFtIGloIGluc3RydWN0aW9uIHRvIGFwcGVuZAotICAgKi8KLSAgcHJpdmF0ZSB2b2lkIGFwcGVuZChJbnN0cnVjdGlvbkhhbmRsZSBpaCkgewotICAgIGlmKGlzRW1wdHkoKSkgewotICAgICAgc3RhcnQgPSBlbmQgPSBpaDsKLSAgICAgIGloLm5leHQgPSBpaC5wcmV2ID0gbnVsbDsKLSAgICB9Ci0gICAgZWxzZSB7Ci0gICAgICBlbmQubmV4dCA9IGloOwotICAgICAgaWgucHJldiAgPSBlbmQ7Ci0gICAgICBpaC5uZXh0ICA9IG51bGw7Ci0gICAgICBlbmQgICAgICA9IGloOwotICAgIH0KLQotICAgIGxlbmd0aCsrOyAvLyBVcGRhdGUgbGVuZ3RoCi0gIH0KLQotICAvKioKLSAgICogQXBwZW5kIGFuIGluc3RydWN0aW9uIHRvIHRoZSBlbmQgb2YgdGhpcyBsaXN0LgotICAgKgotICAgKiBAcGFyYW0gaSBpbnN0cnVjdGlvbiB0byBhcHBlbmQKLSAgICogQHJldHVybiBpbnN0cnVjdGlvbiBoYW5kbGUgb2YgdGhlIGFwcGVuZGVkIGluc3RydWN0aW9uCi0gICAqLwotICBwdWJsaWMgSW5zdHJ1Y3Rpb25IYW5kbGUgYXBwZW5kKEluc3RydWN0aW9uIGkpIHsKLSAgICBJbnN0cnVjdGlvbkhhbmRsZSBpaCA9IEluc3RydWN0aW9uSGFuZGxlLmdldEluc3RydWN0aW9uSGFuZGxlKGkpOwotICAgIGFwcGVuZChpaCk7Ci0KLSAgICByZXR1cm4gaWg7Ci0gIH0KLQotICAvKioKLSAgICogQXBwZW5kIGEgYnJhbmNoIGluc3RydWN0aW9uIHRvIHRoZSBlbmQgb2YgdGhpcyBsaXN0LgotICAgKgotICAgKiBAcGFyYW0gaSBicmFuY2ggaW5zdHJ1Y3Rpb24gdG8gYXBwZW5kCi0gICAqIEByZXR1cm4gYnJhbmNoIGluc3RydWN0aW9uIGhhbmRsZSBvZiB0aGUgYXBwZW5kZWQgaW5zdHJ1Y3Rpb24KLSAgICovCi0gIHB1YmxpYyBCcmFuY2hIYW5kbGUgYXBwZW5kKEJyYW5jaEluc3RydWN0aW9uIGkpIHsKLSAgICBCcmFuY2hIYW5kbGUgaWggPSBCcmFuY2hIYW5kbGUuZ2V0QnJhbmNoSGFuZGxlKGkpOwotICAgIGFwcGVuZChpaCk7Ci0KLSAgICByZXR1cm4gaWg7Ci0gIH0KLQotICAvKioKLSAgICogQXBwZW5kIGEgc2luZ2xlIGluc3RydWN0aW9uIGogYWZ0ZXIgYW5vdGhlciBpbnN0cnVjdGlvbiBpLCB3aGljaAotICAgKiBtdXN0IGJlIGluIHRoaXMgbGlzdCBvZiBjb3Vyc2UhCi0gICAqCi0gICAqIEBwYXJhbSBpIEluc3RydWN0aW9uIGluIGxpc3QKLSAgICogQHBhcmFtIGogSW5zdHJ1Y3Rpb24gdG8gYXBwZW5kIGFmdGVyIGkgaW4gbGlzdAotICAgKiBAcmV0dXJuIGluc3RydWN0aW9uIGhhbmRsZSBvZiB0aGUgZmlyc3QgYXBwZW5kZWQgaW5zdHJ1Y3Rpb24KLSAgICovCi0gIHB1YmxpYyBJbnN0cnVjdGlvbkhhbmRsZSBhcHBlbmQoSW5zdHJ1Y3Rpb24gaSwgSW5zdHJ1Y3Rpb24gaikgewotICAgIHJldHVybiBhcHBlbmQoaSwgbmV3IEluc3RydWN0aW9uTGlzdChqKSk7Ci0gIH0KLQotICAvKioKLSAgICogQXBwZW5kIGEgY29tcG91bmQgaW5zdHJ1Y3Rpb24sIGFmdGVyIGluc3RydWN0aW9uIGkuCi0gICAqCi0gICAqIEBwYXJhbSBpIEluc3RydWN0aW9uIGluIGxpc3QKLSAgICogQHBhcmFtIGMgVGhlIGNvbXBvc2l0ZSBpbnN0cnVjdGlvbiAoY29udGFpbmluZyBhbiBJbnN0cnVjdGlvbkxpc3QpCi0gICAqIEByZXR1cm4gaW5zdHJ1Y3Rpb24gaGFuZGxlIG9mIHRoZSBmaXJzdCBhcHBlbmRlZCBpbnN0cnVjdGlvbgotICAgKi8KLSAgcHVibGljIEluc3RydWN0aW9uSGFuZGxlIGFwcGVuZChJbnN0cnVjdGlvbiBpLCBDb21wb3VuZEluc3RydWN0aW9uIGMpIHsKLSAgICByZXR1cm4gYXBwZW5kKGksIGMuZ2V0SW5zdHJ1Y3Rpb25MaXN0KCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIEFwcGVuZCBhIGNvbXBvdW5kIGluc3RydWN0aW9uLgotICAgKgotICAgKiBAcGFyYW0gYyBUaGUgY29tcG9zaXRlIGluc3RydWN0aW9uIChjb250YWluaW5nIGFuIEluc3RydWN0aW9uTGlzdCkKLSAgICogQHJldHVybiBpbnN0cnVjdGlvbiBoYW5kbGUgb2YgdGhlIGZpcnN0IGFwcGVuZGVkIGluc3RydWN0aW9uCi0gICAqLwotICBwdWJsaWMgSW5zdHJ1Y3Rpb25IYW5kbGUgYXBwZW5kKENvbXBvdW5kSW5zdHJ1Y3Rpb24gYykgewotICAgIHJldHVybiBhcHBlbmQoYy5nZXRJbnN0cnVjdGlvbkxpc3QoKSk7Ci0gIH0KLQotICAvKioKLSAgICogQXBwZW5kIGEgY29tcG91bmQgaW5zdHJ1Y3Rpb24uCi0gICAqCi0gICAqIEBwYXJhbSBpaCB3aGVyZSB0byBhcHBlbmQgdGhlIGluc3RydWN0aW9uIGxpc3QKLSAgICogQHBhcmFtIGMgVGhlIGNvbXBvc2l0ZSBpbnN0cnVjdGlvbiAoY29udGFpbmluZyBhbiBJbnN0cnVjdGlvbkxpc3QpCi0gICAqIEByZXR1cm4gaW5zdHJ1Y3Rpb24gaGFuZGxlIG9mIHRoZSBmaXJzdCBhcHBlbmRlZCBpbnN0cnVjdGlvbgotICAgKi8KLSAgcHVibGljIEluc3RydWN0aW9uSGFuZGxlIGFwcGVuZChJbnN0cnVjdGlvbkhhbmRsZSBpaCwgQ29tcG91bmRJbnN0cnVjdGlvbiBjKSB7Ci0gICAgcmV0dXJuIGFwcGVuZChpaCwgYy5nZXRJbnN0cnVjdGlvbkxpc3QoKSk7Ci0gIH0KLQotICAvKioKLSAgICogQXBwZW5kIGFuIGluc3RydWN0aW9uIGFmdGVyIGluc3RydWN0aW9uIChoYW5kbGUpIGloIGNvbnRhaW5lZCBpbiB0aGlzIGxpc3QuCi0gICAqCi0gICAqIEBwYXJhbSBpaCB3aGVyZSB0byBhcHBlbmQgdGhlIGluc3RydWN0aW9uIGxpc3QKLSAgICogQHBhcmFtIGkgSW5zdHJ1Y3Rpb24gdG8gYXBwZW5kCi0gICAqIEByZXR1cm4gaW5zdHJ1Y3Rpb24gaGFuZGxlIHBvaW50aW5nIHRvIHRoZSA8Qj5maXJzdDwvQj4gYXBwZW5kZWQgaW5zdHJ1Y3Rpb24KLSAgICovCi0gIHB1YmxpYyBJbnN0cnVjdGlvbkhhbmRsZSBhcHBlbmQoSW5zdHJ1Y3Rpb25IYW5kbGUgaWgsIEluc3RydWN0aW9uIGkpIHsKLSAgICByZXR1cm4gYXBwZW5kKGloLCBuZXcgSW5zdHJ1Y3Rpb25MaXN0KGkpKTsKLSAgfQotCi0gIC8qKgotICAgKiBBcHBlbmQgYW4gaW5zdHJ1Y3Rpb24gYWZ0ZXIgaW5zdHJ1Y3Rpb24gKGhhbmRsZSkgaWggY29udGFpbmVkIGluIHRoaXMgbGlzdC4KLSAgICoKLSAgICogQHBhcmFtIGloIHdoZXJlIHRvIGFwcGVuZCB0aGUgaW5zdHJ1Y3Rpb24gbGlzdAotICAgKiBAcGFyYW0gaSBJbnN0cnVjdGlvbiB0byBhcHBlbmQKLSAgICogQHJldHVybiBpbnN0cnVjdGlvbiBoYW5kbGUgcG9pbnRpbmcgdG8gdGhlIDxCPmZpcnN0PC9CPiBhcHBlbmRlZCBpbnN0cnVjdGlvbgotICAgKi8KLSAgcHVibGljIEJyYW5jaEhhbmRsZSBhcHBlbmQoSW5zdHJ1Y3Rpb25IYW5kbGUgaWgsIEJyYW5jaEluc3RydWN0aW9uIGkpIHsKLSAgICBCcmFuY2hIYW5kbGUgICAgYmggPSBCcmFuY2hIYW5kbGUuZ2V0QnJhbmNoSGFuZGxlKGkpOwotICAgIEluc3RydWN0aW9uTGlzdCBpbCA9IG5ldyBJbnN0cnVjdGlvbkxpc3QoKTsKLSAgICBpbC5hcHBlbmQoYmgpOwotCi0gICAgYXBwZW5kKGloLCBpbCk7Ci0KLSAgICByZXR1cm4gYmg7Ci0gIH0KLQotICAvKioKLSAgICogSW5zZXJ0IGFub3RoZXIgbGlzdCBiZWZvcmUgSW5zdHJ1Y3Rpb24gaGFuZGxlIGloIGNvbnRhaW5lZCBpbiB0aGlzIGxpc3QuCi0gICAqIENvbnN1bWVzIGFyZ3VtZW50IGxpc3QsIGkuZS4sIGl0IGJlY29tZXMgZW1wdHkuCi0gICAqCi0gICAqIEBwYXJhbSBpICB3aGVyZSB0byBhcHBlbmQgdGhlIGluc3RydWN0aW9uIGxpc3QKLSAgICogQHBhcmFtIGlsIEluc3RydWN0aW9uIGxpc3QgdG8gaW5zZXJ0Ci0gICAqIEByZXR1cm4gaW5zdHJ1Y3Rpb24gaGFuZGxlIG9mIHRoZSBmaXJzdCBpbnNlcnRlZCBpbnN0cnVjdGlvbgotICAgKi8KLSAgcHVibGljIEluc3RydWN0aW9uSGFuZGxlIGluc2VydChJbnN0cnVjdGlvbkhhbmRsZSBpaCwgSW5zdHJ1Y3Rpb25MaXN0IGlsKSB7Ci0gICAgaWYoaWwgPT0gbnVsbCkKLSAgICAgIHRocm93IG5ldyBDbGFzc0dlbkV4Y2VwdGlvbigiSW5zZXJ0aW5nIG51bGwgSW5zdHJ1Y3Rpb25MaXN0Iik7Ci0KLSAgICBpZihpbC5pc0VtcHR5KCkpIC8vIE5vdGhpbmcgdG8gZG8KLSAgICAgIHJldHVybiBpaDsKLQotICAgIEluc3RydWN0aW9uSGFuZGxlIHByZXYgPSBpaC5wcmV2LCByZXQgPSBpbC5zdGFydDsKLQotICAgIGloLnByZXYgPSBpbC5lbmQ7Ci0gICAgaWwuZW5kLm5leHQgPSBpaDsKLQotICAgIGlsLnN0YXJ0LnByZXYgPSBwcmV2OwotCi0gICAgaWYocHJldiAhPSBudWxsKSAvLyBpaCA9PSBzdGFydCA/Ci0gICAgICBwcmV2Lm5leHQgPSBpbC5zdGFydDsKLSAgICBlbHNlCi0gICAgICBzdGFydCA9IGlsLnN0YXJ0OyAvLyBVcGRhdGUgc3RhcnQgLi4uCi0KLSAgICBsZW5ndGggKz0gaWwubGVuZ3RoOyAvLyBVcGRhdGUgbGVuZ3RoCi0KLSAgICBpbC5jbGVhcigpOwotCi0gICAgcmV0dXJuIHJldDsKLSAgfQotCi0gIC8qKgotICAgKiBJbnNlcnQgYW5vdGhlciBsaXN0LgotICAgKgotICAgKiBAcGFyYW0gaWwgbGlzdCB0byBpbnNlcnQgYmVmb3JlIHN0YXJ0IG9mIHRoaXMgbGlzdAotICAgKiBAcmV0dXJuIGluc3RydWN0aW9uIGhhbmRsZSBvZiB0aGUgZmlyc3QgaW5zZXJ0ZWQgaW5zdHJ1Y3Rpb24KLSAgICovCi0gIHB1YmxpYyBJbnN0cnVjdGlvbkhhbmRsZSBpbnNlcnQoSW5zdHJ1Y3Rpb25MaXN0IGlsKSB7Ci0gICAgaWYoaXNFbXB0eSgpKSB7Ci0gICAgICBhcHBlbmQoaWwpOyAvLyBDb2RlIGlzIGlkZW50aWNhbCBmb3IgdGhpcyBjYXNlCi0gICAgICByZXR1cm4gc3RhcnQ7Ci0gICAgfQotICAgIGVsc2UKLSAgICAgIHJldHVybiBpbnNlcnQoc3RhcnQsIGlsKTsKLSAgfQotCi0gIC8qKgotICAgKiBJbnNlcnQgYW4gaW5zdHJ1Y3Rpb24gYXQgc3RhcnQgb2YgdGhpcyBsaXN0LgotICAgKgotICAgKiBAcGFyYW0gaWggaW5zdHJ1Y3Rpb24gdG8gaW5zZXJ0Ci0gICAqLwotICBwcml2YXRlIHZvaWQgaW5zZXJ0KEluc3RydWN0aW9uSGFuZGxlIGloKSB7Ci0gICAgaWYoaXNFbXB0eSgpKSB7Ci0gICAgICBzdGFydCA9IGVuZCA9IGloOwotICAgICAgaWgubmV4dCA9IGloLnByZXYgPSBudWxsOwotICAgIH0gZWxzZSB7Ci0gICAgICBzdGFydC5wcmV2ID0gaWg7Ci0gICAgICBpaC5uZXh0ICAgID0gc3RhcnQ7Ci0gICAgICBpaC5wcmV2ICAgID0gbnVsbDsKLSAgICAgIHN0YXJ0ICAgICAgPSBpaDsKLSAgICB9Ci0KLSAgICBsZW5ndGgrKzsKLSAgfQotCi0gIC8qKgotICAgKiBJbnNlcnQgYW5vdGhlciBsaXN0IGJlZm9yZSBJbnN0cnVjdGlvbiBpIGNvbnRhaW5lZCBpbiB0aGlzIGxpc3QuCi0gICAqIENvbnN1bWVzIGFyZ3VtZW50IGxpc3QsIGkuZS4sIGl0IGJlY29tZXMgZW1wdHkuCi0gICAqCi0gICAqIEBwYXJhbSBpICB3aGVyZSB0byBhcHBlbmQgdGhlIGluc3RydWN0aW9uIGxpc3QKLSAgICogQHBhcmFtIGlsIEluc3RydWN0aW9uIGxpc3QgdG8gaW5zZXJ0Ci0gICAqIEByZXR1cm4gaW5zdHJ1Y3Rpb24gaGFuZGxlIHBvaW50aW5nIHRvIHRoZSBmaXJzdCBpbnNlcnRlZCBpbnN0cnVjdGlvbiwKLSAgICogaS5lLiwgaWwuZ2V0U3RhcnQoKQotICAgKi8KLSAgcHVibGljIEluc3RydWN0aW9uSGFuZGxlIGluc2VydChJbnN0cnVjdGlvbiBpLCBJbnN0cnVjdGlvbkxpc3QgaWwpIHsKLSAgICBJbnN0cnVjdGlvbkhhbmRsZSBpaDsKLQotICAgIGlmKChpaCA9IGZpbmRJbnN0cnVjdGlvbjEoaSkpID09IG51bGwpCi0gICAgICB0aHJvdyBuZXcgQ2xhc3NHZW5FeGNlcHRpb24oIkluc3RydWN0aW9uICIgKyBpICsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIGlzIG5vdCBjb250YWluZWQgaW4gdGhpcyBsaXN0LiIpOwotCi0gICAgcmV0dXJuIGluc2VydChpaCwgaWwpOwotICB9Ci0KLSAgLyoqCi0gICAqIEluc2VydCBhbiBpbnN0cnVjdGlvbiBhdCBzdGFydCBvZiB0aGlzIGxpc3QuCi0gICAqCi0gICAqIEBwYXJhbSBpIGluc3RydWN0aW9uIHRvIGluc2VydAotICAgKiBAcmV0dXJuIGluc3RydWN0aW9uIGhhbmRsZSBvZiB0aGUgaW5zZXJ0ZWQgaW5zdHJ1Y3Rpb24KLSAgICovCi0gIHB1YmxpYyBJbnN0cnVjdGlvbkhhbmRsZSBpbnNlcnQoSW5zdHJ1Y3Rpb24gaSkgewotICAgIEluc3RydWN0aW9uSGFuZGxlIGloID0gSW5zdHJ1Y3Rpb25IYW5kbGUuZ2V0SW5zdHJ1Y3Rpb25IYW5kbGUoaSk7Ci0gICAgaW5zZXJ0KGloKTsKLQotICAgIHJldHVybiBpaDsKLSAgfQotCi0gIC8qKgotICAgKiBJbnNlcnQgYSBicmFuY2ggaW5zdHJ1Y3Rpb24gYXQgc3RhcnQgb2YgdGhpcyBsaXN0LgotICAgKgotICAgKiBAcGFyYW0gaSBicmFuY2ggaW5zdHJ1Y3Rpb24gdG8gaW5zZXJ0Ci0gICAqIEByZXR1cm4gYnJhbmNoIGluc3RydWN0aW9uIGhhbmRsZSBvZiB0aGUgYXBwZW5kZWQgaW5zdHJ1Y3Rpb24KLSAgICovCi0gIHB1YmxpYyBCcmFuY2hIYW5kbGUgaW5zZXJ0KEJyYW5jaEluc3RydWN0aW9uIGkpIHsKLSAgICBCcmFuY2hIYW5kbGUgaWggPSBCcmFuY2hIYW5kbGUuZ2V0QnJhbmNoSGFuZGxlKGkpOwotICAgIGluc2VydChpaCk7Ci0gICAgcmV0dXJuIGloOwotICB9Ci0KLSAgLyoqCi0gICAqIEluc2VydCBhIHNpbmdsZSBpbnN0cnVjdGlvbiBqIGJlZm9yZSBhbm90aGVyIGluc3RydWN0aW9uIGksIHdoaWNoCi0gICAqIG11c3QgYmUgaW4gdGhpcyBsaXN0IG9mIGNvdXJzZSEKLSAgICoKLSAgICogQHBhcmFtIGkgSW5zdHJ1Y3Rpb24gaW4gbGlzdAotICAgKiBAcGFyYW0gaiBJbnN0cnVjdGlvbiB0byBpbnNlcnQgYmVmb3JlIGkgaW4gbGlzdAotICAgKiBAcmV0dXJuIGluc3RydWN0aW9uIGhhbmRsZSBvZiB0aGUgZmlyc3QgaW5zZXJ0ZWQgaW5zdHJ1Y3Rpb24KLSAgICovCi0gIHB1YmxpYyBJbnN0cnVjdGlvbkhhbmRsZSBpbnNlcnQoSW5zdHJ1Y3Rpb24gaSwgSW5zdHJ1Y3Rpb24gaikgewotICAgIHJldHVybiBpbnNlcnQoaSwgbmV3IEluc3RydWN0aW9uTGlzdChqKSk7Ci0gIH0KLQotICAvKioKLSAgICogSW5zZXJ0IGEgY29tcG91bmQgaW5zdHJ1Y3Rpb24gYmVmb3JlIGluc3RydWN0aW9uIGkuCi0gICAqCi0gICAqIEBwYXJhbSBpIEluc3RydWN0aW9uIGluIGxpc3QKLSAgICogQHBhcmFtIGMgVGhlIGNvbXBvc2l0ZSBpbnN0cnVjdGlvbiAoY29udGFpbmluZyBhbiBJbnN0cnVjdGlvbkxpc3QpCi0gICAqIEByZXR1cm4gaW5zdHJ1Y3Rpb24gaGFuZGxlIG9mIHRoZSBmaXJzdCBpbnNlcnRlZCBpbnN0cnVjdGlvbgotICAgKi8KLSAgcHVibGljIEluc3RydWN0aW9uSGFuZGxlIGluc2VydChJbnN0cnVjdGlvbiBpLCBDb21wb3VuZEluc3RydWN0aW9uIGMpIHsKLSAgICByZXR1cm4gaW5zZXJ0KGksIGMuZ2V0SW5zdHJ1Y3Rpb25MaXN0KCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIEluc2VydCBhIGNvbXBvdW5kIGluc3RydWN0aW9uLgotICAgKgotICAgKiBAcGFyYW0gYyBUaGUgY29tcG9zaXRlIGluc3RydWN0aW9uIChjb250YWluaW5nIGFuIEluc3RydWN0aW9uTGlzdCkKLSAgICogQHJldHVybiBpbnN0cnVjdGlvbiBoYW5kbGUgb2YgdGhlIGZpcnN0IGluc2VydGVkIGluc3RydWN0aW9uCi0gICAqLwotICBwdWJsaWMgSW5zdHJ1Y3Rpb25IYW5kbGUgaW5zZXJ0KENvbXBvdW5kSW5zdHJ1Y3Rpb24gYykgewotICAgIHJldHVybiBpbnNlcnQoYy5nZXRJbnN0cnVjdGlvbkxpc3QoKSk7Ci0gIH0KLQotICAvKioKLSAgICogSW5zZXJ0IGFuIGluc3RydWN0aW9uIGJlZm9yZSBpbnN0cnVjdGlvbiAoaGFuZGxlKSBpaCBjb250YWluZWQgaW4gdGhpcyBsaXN0LgotICAgKgotICAgKiBAcGFyYW0gaWggd2hlcmUgdG8gaW5zZXJ0IHRvIHRoZSBpbnN0cnVjdGlvbiBsaXN0Ci0gICAqIEBwYXJhbSBpIEluc3RydWN0aW9uIHRvIGluc2VydAotICAgKiBAcmV0dXJuIGluc3RydWN0aW9uIGhhbmRsZSBvZiB0aGUgZmlyc3QgaW5zZXJ0ZWQgaW5zdHJ1Y3Rpb24KLSAgICovCi0gIHB1YmxpYyBJbnN0cnVjdGlvbkhhbmRsZSBpbnNlcnQoSW5zdHJ1Y3Rpb25IYW5kbGUgaWgsIEluc3RydWN0aW9uIGkpIHsKLSAgICByZXR1cm4gaW5zZXJ0KGloLCBuZXcgSW5zdHJ1Y3Rpb25MaXN0KGkpKTsKLSAgfQotCi0gIC8qKgotICAgKiBJbnNlcnQgYSBjb21wb3VuZCBpbnN0cnVjdGlvbi4KLSAgICoKLSAgICogQHBhcmFtIGloIHdoZXJlIHRvIGluc2VydCB0aGUgaW5zdHJ1Y3Rpb24gbGlzdAotICAgKiBAcGFyYW0gYyBUaGUgY29tcG9zaXRlIGluc3RydWN0aW9uIChjb250YWluaW5nIGFuIEluc3RydWN0aW9uTGlzdCkKLSAgICogQHJldHVybiBpbnN0cnVjdGlvbiBoYW5kbGUgb2YgdGhlIGZpcnN0IGluc2VydGVkIGluc3RydWN0aW9uCi0gICAqLwotICBwdWJsaWMgSW5zdHJ1Y3Rpb25IYW5kbGUgaW5zZXJ0KEluc3RydWN0aW9uSGFuZGxlIGloLCBDb21wb3VuZEluc3RydWN0aW9uIGMpIHsKLSAgICByZXR1cm4gaW5zZXJ0KGloLCBjLmdldEluc3RydWN0aW9uTGlzdCgpKTsKLSAgfQotCi0gIC8qKgotICAgKiBJbnNlcnQgYW4gaW5zdHJ1Y3Rpb24gYmVmb3JlIGluc3RydWN0aW9uIChoYW5kbGUpIGloIGNvbnRhaW5lZCBpbiB0aGlzIGxpc3QuCi0gICAqCi0gICAqIEBwYXJhbSBpaCB3aGVyZSB0byBpbnNlcnQgdG8gdGhlIGluc3RydWN0aW9uIGxpc3QKLSAgICogQHBhcmFtIGkgSW5zdHJ1Y3Rpb24gdG8gaW5zZXJ0Ci0gICAqIEByZXR1cm4gaW5zdHJ1Y3Rpb24gaGFuZGxlIG9mIHRoZSBmaXJzdCBpbnNlcnRlZCBpbnN0cnVjdGlvbgotICAgKi8KLSAgcHVibGljIEJyYW5jaEhhbmRsZSBpbnNlcnQoSW5zdHJ1Y3Rpb25IYW5kbGUgaWgsIEJyYW5jaEluc3RydWN0aW9uIGkpIHsKLSAgICBCcmFuY2hIYW5kbGUgICAgYmggPSBCcmFuY2hIYW5kbGUuZ2V0QnJhbmNoSGFuZGxlKGkpOwotICAgIEluc3RydWN0aW9uTGlzdCBpbCA9IG5ldyBJbnN0cnVjdGlvbkxpc3QoKTsKLSAgICBpbC5hcHBlbmQoYmgpOwotCi0gICAgaW5zZXJ0KGloLCBpbCk7Ci0KLSAgICByZXR1cm4gYmg7Ci0gIH0KLQotICAvKioKLSAgICogVGFrZSBhbGwgaW5zdHJ1Y3Rpb25zIChoYW5kbGVzKSBmcm9tICJzdGFydCIgdG8gImVuZCIgYW5kIGFwcGVuZCB0aGVtIGFmdGVyIHRoZQotICAgKiBuZXcgbG9jYXRpb24gInRhcmdldCIuIE9mIGNvdXJzZSwgImVuZCIgbXVzdCBiZSBhZnRlciAic3RhcnQiIGFuZCB0YXJnZXQgbXVzdAotICAgKiBub3QgYmUgbG9jYXRlZCB3aXRoaW5nIHRoaXMgcmFuZ2UuIElmIHlvdSB3YW50IHRvIG1vdmUgc29tZXRoaW5nIHRvIHRoZSBzdGFydCBvZgotICAgKiB0aGUgbGlzdCB1c2UgbnVsbCBhcyB2YWx1ZSBmb3IgdGFyZ2V0Ljxicj4KLSAgICogQW55IGluc3RydWN0aW9uIHRhcmdldGVycyBwb2ludGluZyB0byBoYW5kbGVzIHdpdGhpbiB0aGUgYmxvY2ssIGtlZXAgdGhlaXIgdGFyZ2V0cy4KLSAgICoKLSAgICogQHBhcmFtIHN0YXJ0ICBvZiBtb3ZlZCBibG9jawotICAgKiBAcGFyYW0gZW5kICAgIG9mIG1vdmVkIGJsb2NrCi0gICAqIEBwYXJhbSB0YXJnZXQgb2YgbW92ZWQgYmxvY2sKLSAgICovCi0gIHB1YmxpYyB2b2lkIG1vdmUoSW5zdHJ1Y3Rpb25IYW5kbGUgc3RhcnQsIEluc3RydWN0aW9uSGFuZGxlIGVuZCwgSW5zdHJ1Y3Rpb25IYW5kbGUgdGFyZ2V0KSB7Ci0gICAgLy8gU3RlcCAxOiBDaGVjayBjb25zdHJhaW50cwotCi0gICAgaWYoKHN0YXJ0ID09IG51bGwpIHx8IChlbmQgPT0gbnVsbCkpCi0gICAgICB0aHJvdyBuZXcgQ2xhc3NHZW5FeGNlcHRpb24oIkludmFsaWQgbnVsbCBoYW5kbGU6IEZyb20gIiArIHN0YXJ0ICsgIiB0byAiICsgZW5kKTsKLQotICAgIGlmKCh0YXJnZXQgPT0gc3RhcnQpIHx8ICh0YXJnZXQgPT0gZW5kKSkKLSAgICAgIHRocm93IG5ldyBDbGFzc0dlbkV4Y2VwdGlvbigiSW52YWxpZCByYW5nZTogRnJvbSAiICsgc3RhcnQgKyAiIHRvICIgKyBlbmQgKwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgY29udGFpbnMgdGFyZ2V0ICIgKyB0YXJnZXQpOwotCi0gICAgZm9yKEluc3RydWN0aW9uSGFuZGxlIGloID0gc3RhcnQ7IGloICE9IGVuZC5uZXh0OyBpaCA9IGloLm5leHQpIHsKLSAgICAgIGlmKGloID09IG51bGwpIC8vIEF0IGVuZCBvZiBsaXN0LCBlbmQgbm90IGZvdW5kIHlldAotICAgICAgICB0aHJvdyBuZXcgQ2xhc3NHZW5FeGNlcHRpb24oIkludmFsaWQgcmFuZ2U6IEZyb20gIiArIHN0YXJ0ICsgIiB0byAiICsgZW5kKTsKLSAgICAgIGVsc2UgaWYoaWggPT0gdGFyZ2V0KSAvLyB0YXJnZXQgbWF5IGJlIG51bGwKLSAgICAgICAgdGhyb3cgbmV3IENsYXNzR2VuRXhjZXB0aW9uKCJJbnZhbGlkIHJhbmdlOiBGcm9tICIgKyBzdGFydCArICIgdG8gIiArIGVuZCArCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIGNvbnRhaW5zIHRhcmdldCAiICsgdGFyZ2V0KTsKLSAgICB9Ci0KLSAgICAvLyBTdGVwIDI6IFRlbXBvcmFyaWx5IHJlbW92ZSB0aGUgZ2l2ZW4gaW5zdHJ1Y3Rpb25zIGZyb20gdGhlIGxpc3QKLQotICAgIEluc3RydWN0aW9uSGFuZGxlIHByZXYgPSBzdGFydC5wcmV2LCBuZXh0ID0gZW5kLm5leHQ7Ci0KLSAgICBpZihwcmV2ICE9IG51bGwpCi0gICAgICBwcmV2Lm5leHQgPSBuZXh0OwotICAgIGVsc2UgLy8gc3RhcnQgPT0gdGhpcy5zdGFydCEKLSAgICAgIHRoaXMuc3RhcnQgPSBuZXh0OwotCi0gICAgaWYobmV4dCAhPSBudWxsKQotICAgICAgbmV4dC5wcmV2ID0gcHJldjsKLSAgICBlbHNlIC8vIGVuZCA9PSB0aGlzLmVuZCEKLSAgICAgIHRoaXMuZW5kID0gcHJldjsKLQotICAgIHN0YXJ0LnByZXYgPSBlbmQubmV4dCA9IG51bGw7Ci0KLSAgICAvLyBTdGVwIDM6IGFwcGVuZCBhZnRlciB0YXJnZXQKLQotICAgIGlmKHRhcmdldCA9PSBudWxsKSB7IC8vIGFwcGVuZCB0byBzdGFydCBvZiBsaXN0Ci0gICAgICBlbmQubmV4dCA9IHRoaXMuc3RhcnQ7Ci0gICAgICB0aGlzLnN0YXJ0ID0gc3RhcnQ7Ci0gICAgfSBlbHNlIHsKLSAgICAgIG5leHQgPSB0YXJnZXQubmV4dDsKLQotICAgICAgdGFyZ2V0Lm5leHQgPSBzdGFydDsKLSAgICAgIHN0YXJ0LnByZXYgID0gdGFyZ2V0OwotICAgICAgZW5kLm5leHQgICAgPSBuZXh0OwotCi0gICAgICBpZihuZXh0ICE9IG51bGwpCi0gICAgICAgIG5leHQucHJldiA9IGVuZDsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogTW92ZSBhIHNpbmdsZSBpbnN0cnVjdGlvbiAoaGFuZGxlKSB0byBhIG5ldyBsb2NhdGlvbi4KLSAgICoKLSAgICogQHBhcmFtIGloICAgICBtb3ZlZCBpbnN0cnVjdGlvbgotICAgKiBAcGFyYW0gdGFyZ2V0IG5ldyBsb2NhdGlvbiBvZiBtb3ZlZCBpbnN0cnVjdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgbW92ZShJbnN0cnVjdGlvbkhhbmRsZSBpaCwgSW5zdHJ1Y3Rpb25IYW5kbGUgdGFyZ2V0KSB7Ci0gICAgbW92ZShpaCwgaWgsIHRhcmdldCk7Ci0gIH0KLQotICAvKioKLSAgICogUmVtb3ZlIGZyb20gaW5zdHJ1Y3Rpb24gYHByZXYnIHRvIGluc3RydWN0aW9uIGBuZXh0JyBib3RoIGNvbnRhaW5lZAotICAgKiBpbiB0aGlzIGxpc3QuIFRocm93cyBUYXJnZXRMb3N0RXhjZXB0aW9uIHdoZW4gb25lIG9mIHRoZSByZW1vdmVkIGluc3RydWN0aW9uIGhhbmRsZXMKLSAgICogaXMgc3RpbGwgYmVpbmcgdGFyZ2V0ZWQuCi0gICAqCi0gICAqIEBwYXJhbSBwcmV2IHdoZXJlIHRvIHN0YXJ0IGRlbGV0aW5nIChwcmVkZWNlc3NvciwgZXhjbHVzaXZlKQotICAgKiBAcGFyYW0gbmV4dCB3aGVyZSB0byBlbmQgZGVsZXRpbmcgKHN1Y2Nlc3NvciwgZXhjbHVzaXZlKQotICAgKi8KLSAgcHJpdmF0ZSB2b2lkIHJlbW92ZShJbnN0cnVjdGlvbkhhbmRsZSBwcmV2LCBJbnN0cnVjdGlvbkhhbmRsZSBuZXh0KQotICAgIHRocm93cyBUYXJnZXRMb3N0RXhjZXB0aW9uCi0gIHsKLSAgICBJbnN0cnVjdGlvbkhhbmRsZSBmaXJzdCwgbGFzdDsgLy8gRmlyc3QgYW5kIGxhc3QgZGVsZXRlZCBpbnN0cnVjdGlvbgotCi0gICAgaWYoKHByZXYgPT0gbnVsbCkgJiYgKG5leHQgPT0gbnVsbCkpIHsgLy8gc2luZ2xldG9uIGxpc3QKLSAgICAgIGZpcnN0ID0gbGFzdCA9IHN0YXJ0OwotICAgICAgc3RhcnQgPSBlbmQgPSBudWxsOwotICAgIH0gZWxzZSB7Ci0gICAgICBpZihwcmV2ID09IG51bGwpIHsgLy8gQXQgc3RhcnQgb2YgbGlzdAotICAgICAgICBmaXJzdCA9IHN0YXJ0OwotICAgICAgICBzdGFydCA9IG5leHQ7Ci0gICAgICB9IGVsc2UgewotICAgICAgICBmaXJzdCAgICAgPSBwcmV2Lm5leHQ7Ci0gICAgICAgIHByZXYubmV4dCA9IG5leHQ7Ci0gICAgICB9Ci0KLSAgICAgIGlmKG5leHQgPT0gbnVsbCkgeyAvLyBBdCBlbmQgb2YgbGlzdAotICAgICAgICBsYXN0ID0gZW5kOwotICAgICAgICBlbmQgID0gcHJldjsKLSAgICAgIH0gZWxzZSB7Ci0gICAgICAgIGxhc3QgICAgICA9IG5leHQucHJldjsKLSAgICAgICAgbmV4dC5wcmV2ID0gcHJldjsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICBmaXJzdC5wcmV2ID0gbnVsbDsgLy8gQ29tcGxldGVseSBzZXBhcmF0ZWQgZnJvbSByZXN0IG9mIGxpc3QKLSAgICBsYXN0Lm5leHQgID0gbnVsbDsKLQotICAgIEFycmF5TGlzdCB0YXJnZXRfdmVjID0gbmV3IEFycmF5TGlzdCgpOwotCi0gICAgZm9yKEluc3RydWN0aW9uSGFuZGxlIGloPWZpcnN0OyBpaCAhPSBudWxsOyBpaCA9IGloLm5leHQpCi0gICAgICBpaC5nZXRJbnN0cnVjdGlvbigpLmRpc3Bvc2UoKTsgLy8gZS5nLiBCcmFuY2hJbnN0cnVjdGlvbnMgcmVsZWFzZSB0aGVpciB0YXJnZXRzCi0KLSAgICBTdHJpbmdCdWZmZXIgYnVmID0gbmV3IFN0cmluZ0J1ZmZlcigieyAiKTsKLSAgICBmb3IoSW5zdHJ1Y3Rpb25IYW5kbGUgaWg9Zmlyc3Q7IGloICE9IG51bGw7IGloID0gbmV4dCkgewotICAgICAgbmV4dCA9IGloLm5leHQ7Ci0gICAgICBsZW5ndGgtLTsKLQotICAgICAgaWYoaWguaGFzVGFyZ2V0ZXJzKCkpIHsgLy8gU3RpbGwgZ290IHRhcmdldGVycz8KLSAgICAgICAgdGFyZ2V0X3ZlYy5hZGQoaWgpOwotICAgICAgICBidWYuYXBwZW5kKGloLnRvU3RyaW5nKHRydWUpICsgIiAiKTsKLSAgICAgICAgaWgubmV4dCA9IGloLnByZXYgPSBudWxsOwotICAgICAgfSBlbHNlCi0gICAgICAgIGloLmRpc3Bvc2UoKTsKLSAgICB9Ci0KLSAgICBidWYuYXBwZW5kKCJ9Iik7Ci0KLSAgICBpZighdGFyZ2V0X3ZlYy5pc0VtcHR5KCkpIHsKLSAgICAgIEluc3RydWN0aW9uSGFuZGxlW10gdGFyZ2V0ZWQgPSBuZXcgSW5zdHJ1Y3Rpb25IYW5kbGVbdGFyZ2V0X3ZlYy5zaXplKCldOwotICAgICAgdGFyZ2V0X3ZlYy50b0FycmF5KHRhcmdldGVkKTsKLSAgICAgIHRocm93IG5ldyBUYXJnZXRMb3N0RXhjZXB0aW9uKHRhcmdldGVkLCBidWYudG9TdHJpbmcoKSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFJlbW92ZSBpbnN0cnVjdGlvbiBmcm9tIHRoaXMgbGlzdC4gVGhlIGNvcnJlc3BvbmRpbmcgSW5zdHJ1Y3Rpb24KLSAgICogaGFuZGxlcyBtdXN0IG5vdCBiZSByZXVzZWQhCi0gICAqCi0gICAqIEBwYXJhbSBpaCBpbnN0cnVjdGlvbiAoaGFuZGxlKSB0byByZW1vdmUKLSAgICovCi0gIHB1YmxpYyB2b2lkIGRlbGV0ZShJbnN0cnVjdGlvbkhhbmRsZSBpaCkgdGhyb3dzIFRhcmdldExvc3RFeGNlcHRpb24gewotICAgIHJlbW92ZShpaC5wcmV2LCBpaC5uZXh0KTsKLSAgfQotCi0gIC8qKgotICAgKiBSZW1vdmUgaW5zdHJ1Y3Rpb24gZnJvbSB0aGlzIGxpc3QuIFRoZSBjb3JyZXNwb25kaW5nIEluc3RydWN0aW9uCi0gICAqIGhhbmRsZXMgbXVzdCBub3QgYmUgcmV1c2VkIQotICAgKgotICAgKiBAcGFyYW0gaSBpbnN0cnVjdGlvbiB0byByZW1vdmUKLSAgICovCi0gIHB1YmxpYyB2b2lkIGRlbGV0ZShJbnN0cnVjdGlvbiBpKSB0aHJvd3MgVGFyZ2V0TG9zdEV4Y2VwdGlvbiB7Ci0gICAgSW5zdHJ1Y3Rpb25IYW5kbGUgaWg7Ci0KLSAgICBpZigoaWggPSBmaW5kSW5zdHJ1Y3Rpb24xKGkpKSA9PSBudWxsKQotICAgICAgdGhyb3cgbmV3IENsYXNzR2VuRXhjZXB0aW9uKCJJbnN0cnVjdGlvbiAiICsgaSArCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiBpcyBub3QgY29udGFpbmVkIGluIHRoaXMgbGlzdC4iKTsKLSAgICBkZWxldGUoaWgpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlbW92ZSBpbnN0cnVjdGlvbnMgZnJvbSBpbnN0cnVjdGlvbiBgZnJvbScgdG8gaW5zdHJ1Y3Rpb24gYHRvJyBjb250YWluZWQKLSAgICogaW4gdGhpcyBsaXN0LiBUaGUgdXNlciBtdXN0IGVuc3VyZSB0aGF0IGBmcm9tJyBpcyBhbiBpbnN0cnVjdGlvbiBiZWZvcmUKLSAgICogYHRvJywgb3IgcmlzayBoYXZvYy4gVGhlIGNvcnJlc3BvbmRpbmcgSW5zdHJ1Y3Rpb24gaGFuZGxlcyBtdXN0IG5vdCBiZSByZXVzZWQhCi0gICAqCi0gICAqIEBwYXJhbSBmcm9tIHdoZXJlIHRvIHN0YXJ0IGRlbGV0aW5nIChpbmNsdXNpdmUpCi0gICAqIEBwYXJhbSB0byAgIHdoZXJlIHRvIGVuZCBkZWxldGluZyAoaW5jbHVzaXZlKQotICAgKi8KLSAgcHVibGljIHZvaWQgZGVsZXRlKEluc3RydWN0aW9uSGFuZGxlIGZyb20sIEluc3RydWN0aW9uSGFuZGxlIHRvKQotICAgIHRocm93cyBUYXJnZXRMb3N0RXhjZXB0aW9uCi0gIHsKLSAgICByZW1vdmUoZnJvbS5wcmV2LCB0by5uZXh0KTsKLSAgfQotCi0gIC8qKgotICAgKiBSZW1vdmUgaW5zdHJ1Y3Rpb25zIGZyb20gaW5zdHJ1Y3Rpb24gYGZyb20nIHRvIGluc3RydWN0aW9uIGB0bycgY29udGFpbmVkCi0gICAqIGluIHRoaXMgbGlzdC4gVGhlIHVzZXIgbXVzdCBlbnN1cmUgdGhhdCBgZnJvbScgaXMgYW4gaW5zdHJ1Y3Rpb24gYmVmb3JlCi0gICAqIGB0bycsIG9yIHJpc2sgaGF2b2MuIFRoZSBjb3JyZXNwb25kaW5nIEluc3RydWN0aW9uIGhhbmRsZXMgbXVzdCBub3QgYmUgcmV1c2VkIQotICAgKgotICAgKiBAcGFyYW0gZnJvbSB3aGVyZSB0byBzdGFydCBkZWxldGluZyAoaW5jbHVzaXZlKQotICAgKiBAcGFyYW0gdG8gICB3aGVyZSB0byBlbmQgZGVsZXRpbmcgKGluY2x1c2l2ZSkKLSAgICovCi0gIHB1YmxpYyB2b2lkIGRlbGV0ZShJbnN0cnVjdGlvbiBmcm9tLCBJbnN0cnVjdGlvbiB0bykgdGhyb3dzIFRhcmdldExvc3RFeGNlcHRpb24gewotICAgIEluc3RydWN0aW9uSGFuZGxlIGZyb21faWgsIHRvX2loOwotCi0gICAgaWYoKGZyb21faWggPSBmaW5kSW5zdHJ1Y3Rpb24xKGZyb20pKSA9PSBudWxsKQotICAgICAgdGhyb3cgbmV3IENsYXNzR2VuRXhjZXB0aW9uKCJJbnN0cnVjdGlvbiAiICsgZnJvbSArCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiBpcyBub3QgY29udGFpbmVkIGluIHRoaXMgbGlzdC4iKTsKLQotICAgIGlmKCh0b19paCA9IGZpbmRJbnN0cnVjdGlvbjIodG8pKSA9PSBudWxsKQotICAgICAgdGhyb3cgbmV3IENsYXNzR2VuRXhjZXB0aW9uKCJJbnN0cnVjdGlvbiAiICsgdG8gKwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgaXMgbm90IGNvbnRhaW5lZCBpbiB0aGlzIGxpc3QuIik7Ci0gICAgZGVsZXRlKGZyb21faWgsIHRvX2loKTsKLSAgfQotCi0gIC8qKgotICAgKiBTZWFyY2ggZm9yIGdpdmVuIEluc3RydWN0aW9uIHJlZmVyZW5jZSwgc3RhcnQgYXQgYmVnaW5uaW5nIG9mIGxpc3QuCi0gICAqCi0gICAqIEBwYXJhbSBpIGluc3RydWN0aW9uIHRvIHNlYXJjaCBmb3IKLSAgICogQHJldHVybiBpbnN0cnVjdGlvbiBmb3VuZCBvbiBzdWNjZXNzLCBudWxsIG90aGVyd2lzZQotICAgKi8KLSAgcHJpdmF0ZSBJbnN0cnVjdGlvbkhhbmRsZSBmaW5kSW5zdHJ1Y3Rpb24xKEluc3RydWN0aW9uIGkpIHsKLSAgICBmb3IoSW5zdHJ1Y3Rpb25IYW5kbGUgaWg9c3RhcnQ7IGloICE9IG51bGw7IGloID0gaWgubmV4dCkKLSAgICAgIGlmKGloLmluc3RydWN0aW9uID09IGkpCi0gICAgICAgIHJldHVybiBpaDsKLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFNlYXJjaCBmb3IgZ2l2ZW4gSW5zdHJ1Y3Rpb24gcmVmZXJlbmNlLCBzdGFydCBhdCBlbmQgb2YgbGlzdAotICAgKgotICAgKiBAcGFyYW0gaSBpbnN0cnVjdGlvbiB0byBzZWFyY2ggZm9yCi0gICAqIEByZXR1cm4gaW5zdHJ1Y3Rpb24gZm91bmQgb24gc3VjY2VzcywgbnVsbCBvdGhlcndpc2UKLSAgICovCi0gIHByaXZhdGUgSW5zdHJ1Y3Rpb25IYW5kbGUgZmluZEluc3RydWN0aW9uMihJbnN0cnVjdGlvbiBpKSB7Ci0gICAgZm9yKEluc3RydWN0aW9uSGFuZGxlIGloPWVuZDsgaWggIT0gbnVsbDsgaWggPSBpaC5wcmV2KQotICAgICAgaWYoaWguaW5zdHJ1Y3Rpb24gPT0gaSkKLSAgICAgICAgcmV0dXJuIGloOwotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICBwdWJsaWMgYm9vbGVhbiBjb250YWlucyhJbnN0cnVjdGlvbkhhbmRsZSBpKSB7Ci0gICAgaWYoaSA9PSBudWxsKQotICAgICAgcmV0dXJuIGZhbHNlOwotCi0gICAgZm9yKEluc3RydWN0aW9uSGFuZGxlIGloPXN0YXJ0OyBpaCAhPSBudWxsOyBpaCA9IGloLm5leHQpCi0gICAgICBpZihpaCA9PSBpKQotICAgICAgICByZXR1cm4gdHJ1ZTsKLQotICAgIHJldHVybiBmYWxzZTsKLSAgfQotCi0gIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKEluc3RydWN0aW9uIGkpIHsKLSAgICByZXR1cm4gZmluZEluc3RydWN0aW9uMShpKSAhPSBudWxsOwotICB9Ci0KLSAgcHVibGljIHZvaWQgc2V0UG9zaXRpb25zKCkgewotICAgIHNldFBvc2l0aW9ucyhmYWxzZSk7Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZSBhbGwgaW5zdHJ1Y3Rpb25zIHRoZWlyIHBvc2l0aW9uIG51bWJlciAob2Zmc2V0IGluIGJ5dGUgc3RyZWFtKSwgaS5lLiwKLSAgICogbWFrZSB0aGUgbGlzdCByZWFkeSB0byBiZSBkdW1wZWQuCi0gICAqCi0gICAqIEBwYXJhbSBjaGVjayBQZXJmb3JtIHNhbml0eSBjaGVja3MsIGUuZy4gaWYgYWxsIHRhcmdldGVkIGluc3RydWN0aW9ucyByZWFsbHkgYmVsb25nCi0gICAqIHRvIHRoaXMgbGlzdAotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0UG9zaXRpb25zKGJvb2xlYW4gY2hlY2spIHsKLSAgICBpbnQgbWF4X2FkZGl0aW9uYWxfYnl0ZXMgPSAwLCBhZGRpdGlvbmFsX2J5dGVzID0gMDsKLSAgICBpbnQgaW5kZXggPSAwLCBjb3VudCA9IDA7Ci0gICAgaW50W10gcG9zID0gbmV3IGludFtsZW5ndGhdOwotCi0gICAgLyogUGFzcyAwOiBTYW5pdHkgY2hlY2tzCi0gICAgICovCi0gICAgaWYoY2hlY2spIHsKLSAgICAgIGZvcihJbnN0cnVjdGlvbkhhbmRsZSBpaD1zdGFydDsgaWggIT0gbnVsbDsgaWggPSBpaC5uZXh0KSB7Ci0gICAgICAgIEluc3RydWN0aW9uIGkgPSBpaC5pbnN0cnVjdGlvbjsKLQotICAgICAgICBpZihpIGluc3RhbmNlb2YgQnJhbmNoSW5zdHJ1Y3Rpb24pIHsgLy8gdGFyZ2V0IGluc3RydWN0aW9uIHdpdGhpbiBsaXN0PwotICAgICAgICAgIEluc3RydWN0aW9uIGluc3QgPSAoKEJyYW5jaEluc3RydWN0aW9uKWkpLmdldFRhcmdldCgpLmluc3RydWN0aW9uOwotICAgICAgICAgIGlmKCFjb250YWlucyhpbnN0KSkKLSAgICAgICAgICAgIHRocm93IG5ldyBDbGFzc0dlbkV4Y2VwdGlvbigiQnJhbmNoIHRhcmdldCBvZiAiICsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb25zdGFudHMuT1BDT0RFX05BTUVTW2kub3Bjb2RlXSArICI6IiArCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5zdCArICIgbm90IGluIGluc3RydWN0aW9uIGxpc3QiKTsKLQotICAgICAgICAgIGlmKGkgaW5zdGFuY2VvZiBTZWxlY3QpIHsKLSAgICAgICAgICAgIEluc3RydWN0aW9uSGFuZGxlW10gdGFyZ2V0cyA9ICgoU2VsZWN0KWkpLmdldFRhcmdldHMoKTsKLQotICAgICAgICAgICAgZm9yKGludCBqPTA7IGogPCB0YXJnZXRzLmxlbmd0aDsgaisrKSB7Ci0gICAgICAgICAgICAgIGluc3QgPSB0YXJnZXRzW2pdLmluc3RydWN0aW9uOwotICAgICAgICAgICAgICBpZighY29udGFpbnMoaW5zdCkpCi0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IENsYXNzR2VuRXhjZXB0aW9uKCJCcmFuY2ggdGFyZ2V0IG9mICIgKwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb25zdGFudHMuT1BDT0RFX05BTUVTW2kub3Bjb2RlXSArICI6IiArCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc3QgKyAiIG5vdCBpbiBpbnN0cnVjdGlvbiBsaXN0Iik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgfQotCi0gICAgICAgICAgaWYoIShpaCBpbnN0YW5jZW9mIEJyYW5jaEhhbmRsZSkpCi0gICAgICAgICAgICB0aHJvdyBuZXcgQ2xhc3NHZW5FeGNlcHRpb24oIkJyYW5jaCBpbnN0cnVjdGlvbiAiICsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb25zdGFudHMuT1BDT0RFX05BTUVTW2kub3Bjb2RlXSArICI6IiArCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5zdCArICIgbm90IGNvbnRhaW5lZCBpbiBCcmFuY2hIYW5kbGUuIik7Ci0KLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLQotICAgIC8qIFBhc3MgMTogU2V0IHBvc2l0aW9uIG51bWJlcnMgYW5kIHN1bSB1cCB0aGUgbWF4aW11bSBudW1iZXIgb2YgYnl0ZXMgYW4KLSAgICAgKiBpbnN0cnVjdGlvbiBtYXkgYmUgc2hpZnRlZC4KLSAgICAgKi8KLSAgICBmb3IoSW5zdHJ1Y3Rpb25IYW5kbGUgaWg9c3RhcnQ7IGloICE9IG51bGw7IGloID0gaWgubmV4dCkgewotICAgICAgSW5zdHJ1Y3Rpb24gaSA9IGloLmluc3RydWN0aW9uOwotCi0gICAgICBpaC5zZXRQb3NpdGlvbihpbmRleCk7Ci0gICAgICBwb3NbY291bnQrK10gPSBpbmRleDsKLQotICAgICAgLyogR2V0IGFuIGVzdGltYXRlIGFib3V0IGhvdyBtYW55IGFkZGl0aW9uYWwgYnl0ZXMgbWF5IGJlIGFkZGVkLCBiZWNhdXNlCi0gICAgICAgKiBCcmFuY2hJbnN0cnVjdGlvbnMgbWF5IGhhdmUgdmFyaWFibGUgbGVuZ3RoIGRlcGVuZGluZyBvbiB0aGUgdGFyZ2V0Ci0gICAgICAgKiBvZmZzZXQgKHNob3J0IHZzLiBpbnQpIG9yIGFsaWdubWVudCBpc3N1ZXMgKFRBQkxFU1dJVENIIGFuZAotICAgICAgICogTE9PS1VQU1dJVENIKS4KLSAgICAgICAqLwotICAgICAgc3dpdGNoKGkuZ2V0T3Bjb2RlKCkpIHsKLSAgICAgIGNhc2UgQ29uc3RhbnRzLkpTUjogY2FzZSBDb25zdGFudHMuR09UTzoKLSAgICAgICAgbWF4X2FkZGl0aW9uYWxfYnl0ZXMgKz0gMjsKLSAgICAgICAgYnJlYWs7Ci0KLSAgICAgIGNhc2UgQ29uc3RhbnRzLlRBQkxFU1dJVENIOiBjYXNlIENvbnN0YW50cy5MT09LVVBTV0lUQ0g6Ci0gICAgICAgIG1heF9hZGRpdGlvbmFsX2J5dGVzICs9IDM7Ci0gICAgICAgIGJyZWFrOwotICAgICAgfQotCi0gICAgICBpbmRleCArPSBpLmdldExlbmd0aCgpOwotICAgIH0KLQotICAgIC8qIFBhc3MgMjogRXhwYW5kIHRoZSB2YXJpYWJsZS1sZW5ndGggKEJyYW5jaClJbnN0cnVjdGlvbnMgZGVwZW5kaW5nIG9uCi0gICAgICogdGhlIHRhcmdldCBvZmZzZXQgKHNob3J0IG9yIGludCkgYW5kIGVuc3VyZSB0aGF0IGJyYW5jaCB0YXJnZXRzIGFyZQotICAgICAqIHdpdGhpbiB0aGlzIGxpc3QuCi0gICAgICovCi0gICAgZm9yKEluc3RydWN0aW9uSGFuZGxlIGloPXN0YXJ0OyBpaCAhPSBudWxsOyBpaCA9IGloLm5leHQpCi0gICAgICBhZGRpdGlvbmFsX2J5dGVzICs9IGloLnVwZGF0ZVBvc2l0aW9uKGFkZGl0aW9uYWxfYnl0ZXMsIG1heF9hZGRpdGlvbmFsX2J5dGVzKTsKLQotICAgIC8qIFBhc3MgMzogVXBkYXRlIHBvc2l0aW9uIG51bWJlcnMgKHdoaWNoIG1heSBoYXZlIGNoYW5nZWQgZHVlIHRvIHRoZQotICAgICAqIHByZWNlZGluZyBleHBhbnNpb25zKSwgbGlrZSBwYXNzIDEuCi0gICAgICovCi0gICAgaW5kZXg9Y291bnQ9MDsKLSAgICBmb3IoSW5zdHJ1Y3Rpb25IYW5kbGUgaWg9c3RhcnQ7IGloICE9IG51bGw7IGloID0gaWgubmV4dCkgewotICAgICAgSW5zdHJ1Y3Rpb24gaSA9IGloLmluc3RydWN0aW9uOwotCi0gICAgICBpaC5zZXRQb3NpdGlvbihpbmRleCk7Ci0gICAgICBwb3NbY291bnQrK10gPSBpbmRleDsKLSAgICAgIGluZGV4ICs9IGkuZ2V0TGVuZ3RoKCk7Ci0gICAgfQotCi0gICAgYnl0ZV9wb3NpdGlvbnMgPSBuZXcgaW50W2NvdW50XTsgLy8gVHJpbSB0byBwcm9wZXIgc2l6ZQotICAgIFN5c3RlbS5hcnJheWNvcHkocG9zLCAwLCBieXRlX3Bvc2l0aW9ucywgMCwgY291bnQpOwotICB9Ci0KLSAgLyoqCi0gICAqIFdoZW4gZXZlcnl0aGluZyBpcyBmaW5pc2hlZCwgdXNlIHRoaXMgbWV0aG9kIHRvIGNvbnZlcnQgdGhlIGluc3RydWN0aW9uCi0gICAqIGxpc3QgaW50byBhbiBhcnJheSBvZiBieXRlcy4KLSAgICoKLSAgICogQHJldHVybiB0aGUgYnl0ZSBjb2RlIHJlYWR5IHRvIGJlIGR1bXBlZAotICAgKi8KLSAgcHVibGljIGJ5dGVbXSBnZXRCeXRlQ29kZSgpIHsKLSAgICAvLyBVcGRhdGUgcG9zaXRpb24gaW5kaWNlcyBvZiBpbnN0cnVjdGlvbnMKLSAgICBzZXRQb3NpdGlvbnMoKTsKLQotICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBiICAgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7Ci0gICAgRGF0YU91dHB1dFN0cmVhbSAgICAgIG91dCA9IG5ldyBEYXRhT3V0cHV0U3RyZWFtKGIpOwotCi0gICAgdHJ5IHsKLSAgICAgIGZvcihJbnN0cnVjdGlvbkhhbmRsZSBpaD1zdGFydDsgaWggIT0gbnVsbDsgaWggPSBpaC5uZXh0KSB7Ci0gICAgICAgIEluc3RydWN0aW9uIGkgPSBpaC5pbnN0cnVjdGlvbjsKLSAgICAgICAgaS5kdW1wKG91dCk7IC8vIFRyYXZlcnNlIGxpc3QKLSAgICAgIH0KLSAgICB9IGNhdGNoKElPRXhjZXB0aW9uIGUpIHsKLSAgICAgIFN5c3RlbS5lcnIucHJpbnRsbihlKTsKLSAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIHJldHVybiBiLnRvQnl0ZUFycmF5KCk7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBhbiBhcnJheSBvZiBpbnN0cnVjdGlvbnMgd2l0aG91dCB0YXJnZXQgaW5mb3JtYXRpb24gZm9yIGJyYW5jaCBpbnN0cnVjdGlvbnMuCi0gICAqLwotICBwdWJsaWMgSW5zdHJ1Y3Rpb25bXSBnZXRJbnN0cnVjdGlvbnMoKSB7Ci0gICAgQnl0ZVNlcXVlbmNlICBieXRlcyAgICAgICAgPSBuZXcgQnl0ZVNlcXVlbmNlKGdldEJ5dGVDb2RlKCkpOwotICAgIEFycmF5TGlzdCAgICAgaW5zdHJ1Y3Rpb25zID0gbmV3IEFycmF5TGlzdCgpOwotCi0gICAgdHJ5IHsKLSAgICAgIHdoaWxlKGJ5dGVzLmF2YWlsYWJsZSgpID4gMCkgewotICAgICAgICBpbnN0cnVjdGlvbnMuYWRkKEluc3RydWN0aW9uLnJlYWRJbnN0cnVjdGlvbihieXRlcykpOwotICAgICAgfQotICAgIH0gY2F0Y2goSU9FeGNlcHRpb24gZSkgeyB0aHJvdyBuZXcgQ2xhc3NHZW5FeGNlcHRpb24oZS50b1N0cmluZygpKTsgfQotCi0gICAgSW5zdHJ1Y3Rpb25bXSByZXN1bHQgPSBuZXcgSW5zdHJ1Y3Rpb25baW5zdHJ1Y3Rpb25zLnNpemUoKV07Ci0gICAgaW5zdHJ1Y3Rpb25zLnRvQXJyYXkocmVzdWx0KTsKLSAgICByZXR1cm4gcmVzdWx0OwotICB9Ci0KLSAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKLSAgICByZXR1cm4gdG9TdHJpbmcodHJ1ZSk7Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIHZlcmJvc2UgdG9nZ2xlIG91dHB1dCBmb3JtYXQKLSAgICogQHJldHVybiBTdHJpbmcgY29udGFpbmluZyBhbGwgaW5zdHJ1Y3Rpb25zIGluIHRoaXMgbGlzdC4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoYm9vbGVhbiB2ZXJib3NlKSB7Ci0gICAgU3RyaW5nQnVmZmVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLQotICAgIGZvcihJbnN0cnVjdGlvbkhhbmRsZSBpaD1zdGFydDsgaWggIT0gbnVsbDsgaWggPSBpaC5uZXh0KSB7Ci0gICAgICBidWYuYXBwZW5kKGloLnRvU3RyaW5nKHZlcmJvc2UpICsgIlxuIik7Ci0gICAgfQotCi0gICAgcmV0dXJuIGJ1Zi50b1N0cmluZygpOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gRW51bWVyYXRpb24gdGhhdCBsaXN0cyBhbGwgaW5zdHJ1Y3Rpb25zIChoYW5kbGVzKQotICAgKi8KLSAgcHVibGljIEl0ZXJhdG9yIGl0ZXJhdG9yKCkgewotICAgIHJldHVybiBuZXcgSXRlcmF0b3IoKSB7Ci0gICAgICBwcml2YXRlIEluc3RydWN0aW9uSGFuZGxlIGloID0gc3RhcnQ7Ci0KLSAgICAgIHB1YmxpYyBPYmplY3QgbmV4dCgpIHsKLSAgICAgICAgSW5zdHJ1Y3Rpb25IYW5kbGUgaSA9IGloOwotICAgICAgICBpaCA9IGloLm5leHQ7Ci0gICAgICAgIHJldHVybiBpOwotICAgICAgfQotCi0gICAgICBwdWJsaWMgdm9pZCByZW1vdmUoKSB7Ci0gICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOwotICAgICAgfQotCi0gICAgICBwdWJsaWMgYm9vbGVhbiBoYXNOZXh0KCkgeyByZXR1cm4gaWggIT0gbnVsbDsgfQotICAgIH07Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBhcnJheSBjb250YWluaW5nIGFsbCBpbnN0cnVjdGlvbnMgKGhhbmRsZXMpCi0gICAqLwotICBwdWJsaWMgSW5zdHJ1Y3Rpb25IYW5kbGVbXSBnZXRJbnN0cnVjdGlvbkhhbmRsZXMoKSB7Ci0gICAgSW5zdHJ1Y3Rpb25IYW5kbGVbXSBpaHMgPSBuZXcgSW5zdHJ1Y3Rpb25IYW5kbGVbbGVuZ3RoXTsKLSAgICBJbnN0cnVjdGlvbkhhbmRsZSAgIGloICA9IHN0YXJ0OwotCi0gICAgZm9yKGludCBpPTA7IGkgPCBsZW5ndGg7IGkrKykgewotICAgICAgaWhzW2ldID0gaWg7Ci0gICAgICBpaCA9IGloLm5leHQ7Ci0gICAgfQotCi0gICAgcmV0dXJuIGloczsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgcG9zaXRpb25zIChvZmZzZXRzKSBvZiBhbGwgaW5zdHJ1Y3Rpb25zIGluIHRoZSBsaXN0LiBUaGlzIHJlbGllcyBvbiB0aGF0Ci0gICAqIHRoZSBsaXN0IGhhcyBiZWVuIGZyZXNobHkgY3JlYXRlZCBmcm9tIGFuIGJ5dGUgY29kZSBhcnJheSwgb3IgdGhhdCBzZXRQb3NpdGlvbnMoKQotICAgKiBoYXMgYmVlbiBjYWxsZWQuIE90aGVyd2lzZSB0aGlzIG1heSBiZSBpbmFjY3VyYXRlLgotICAgKgotICAgKiBAcmV0dXJuIGFycmF5IGNvbnRhaW5pbmcgYWxsIGluc3RydWN0aW9uJ3Mgb2Zmc2V0IGluIGJ5dGUgY29kZQotICAgKi8KLSAgcHVibGljIGludFtdIGdldEluc3RydWN0aW9uUG9zaXRpb25zKCkgeyByZXR1cm4gYnl0ZV9wb3NpdGlvbnM7IH0KLQotICAvKioKLSAgICogQHJldHVybiBjb21wbGV0ZSwgaS5lLiwgZGVlcCBjb3B5IG9mIHRoaXMgbGlzdAotICAgKi8KLSAgcHVibGljIEluc3RydWN0aW9uTGlzdCBjb3B5KCkgewotICAgIEhhc2hNYXAgICAgICAgICBtYXAgPSBuZXcgSGFzaE1hcCgpOwotICAgIEluc3RydWN0aW9uTGlzdCBpbCAgPSBuZXcgSW5zdHJ1Y3Rpb25MaXN0KCk7Ci0KLSAgICAvKiBQYXNzIDE6IE1ha2UgY29waWVzIG9mIGFsbCBpbnN0cnVjdGlvbnMsIGFwcGVuZCB0aGVtIHRvIHRoZSBuZXcgbGlzdAotICAgICAqIGFuZCBhc3NvY2lhdGUgb2xkIGluc3RydWN0aW9uIHJlZmVyZW5jZXMgd2l0aCB0aGUgbmV3IG9uZXMsIGkuZS4sCi0gICAgICogYSAxOjEgbWFwcGluZy4KLSAgICAgKi8KLSAgICBmb3IoSW5zdHJ1Y3Rpb25IYW5kbGUgaWg9c3RhcnQ7IGloICE9IG51bGw7IGloID0gaWgubmV4dCkgewotICAgICAgSW5zdHJ1Y3Rpb24gaSA9IGloLmluc3RydWN0aW9uOwotICAgICAgSW5zdHJ1Y3Rpb24gYyA9IGkuY29weSgpOyAvLyBVc2UgY2xvbmUgZm9yIHNoYWxsb3cgY29weQotCi0gICAgICBpZihjIGluc3RhbmNlb2YgQnJhbmNoSW5zdHJ1Y3Rpb24pCi0gICAgICAgIG1hcC5wdXQoaWgsIGlsLmFwcGVuZCgoQnJhbmNoSW5zdHJ1Y3Rpb24pYykpOwotICAgICAgZWxzZQotICAgICAgICBtYXAucHV0KGloLCBpbC5hcHBlbmQoYykpOwotICAgIH0KLQotICAgIC8qIFBhc3MgMjogVXBkYXRlIGJyYW5jaCB0YXJnZXRzLgotICAgICAqLwotICAgIEluc3RydWN0aW9uSGFuZGxlIGloPXN0YXJ0OwotICAgIEluc3RydWN0aW9uSGFuZGxlIGNoPWlsLnN0YXJ0OwotCi0gICAgd2hpbGUoaWggIT0gbnVsbCkgewotICAgICAgSW5zdHJ1Y3Rpb24gaSA9IGloLmluc3RydWN0aW9uOwotICAgICAgSW5zdHJ1Y3Rpb24gYyA9IGNoLmluc3RydWN0aW9uOwotCi0gICAgICBpZihpIGluc3RhbmNlb2YgQnJhbmNoSW5zdHJ1Y3Rpb24pIHsKLSAgICAgICAgQnJhbmNoSW5zdHJ1Y3Rpb24gYmkgICAgICA9IChCcmFuY2hJbnN0cnVjdGlvbilpOwotICAgICAgICBCcmFuY2hJbnN0cnVjdGlvbiBiYyAgICAgID0gKEJyYW5jaEluc3RydWN0aW9uKWM7Ci0gICAgICAgIEluc3RydWN0aW9uSGFuZGxlIGl0YXJnZXQgPSBiaS5nZXRUYXJnZXQoKTsgLy8gb2xkIHRhcmdldAotCi0gICAgICAgIC8vIE5ldyB0YXJnZXQgaXMgaW4gaGFzaCBtYXAKLSAgICAgICAgYmMuc2V0VGFyZ2V0KChJbnN0cnVjdGlvbkhhbmRsZSltYXAuZ2V0KGl0YXJnZXQpKTsKLQotICAgICAgICBpZihiaSBpbnN0YW5jZW9mIFNlbGVjdCkgeyAvLyBFaXRoZXIgTE9PS1VQU1dJVENIIG9yIFRBQkxFU1dJVENICi0gICAgICAgICAgSW5zdHJ1Y3Rpb25IYW5kbGVbXSBpdGFyZ2V0cyA9ICgoU2VsZWN0KWJpKS5nZXRUYXJnZXRzKCk7Ci0gICAgICAgICAgSW5zdHJ1Y3Rpb25IYW5kbGVbXSBjdGFyZ2V0cyA9ICgoU2VsZWN0KWJjKS5nZXRUYXJnZXRzKCk7Ci0KLSAgICAgICAgICBmb3IoaW50IGo9MDsgaiA8IGl0YXJnZXRzLmxlbmd0aDsgaisrKSB7IC8vIFVwZGF0ZSBhbGwgdGFyZ2V0cwotICAgICAgICAgICAgY3RhcmdldHNbal0gPSAoSW5zdHJ1Y3Rpb25IYW5kbGUpbWFwLmdldChpdGFyZ2V0c1tqXSk7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICB9Ci0KLSAgICAgIGloID0gaWgubmV4dDsKLSAgICAgIGNoID0gY2gubmV4dDsKLSAgICB9Ci0KLSAgICByZXR1cm4gaWw7Ci0gIH0KLQotICAvKiogUmVwbGFjZSBhbGwgcmVmZXJlbmNlcyB0byB0aGUgb2xkIGNvbnN0YW50IHBvb2wgd2l0aCByZWZlcmVuY2VzIHRvIHRoZSBuZXcKLSAgICogIGNvbnN0YW50IHBvb2wKLSAgICovCi0gIHB1YmxpYyB2b2lkIHJlcGxhY2VDb25zdGFudFBvb2woQ29uc3RhbnRQb29sR2VuIG9sZF9jcCwgQ29uc3RhbnRQb29sR2VuIG5ld19jcCkgewotICAgIGZvcihJbnN0cnVjdGlvbkhhbmRsZSBpaD1zdGFydDsgaWggIT0gbnVsbDsgaWggPSBpaC5uZXh0KSB7Ci0gICAgICBJbnN0cnVjdGlvbiBpID0gaWguaW5zdHJ1Y3Rpb247Ci0KLSAgICAgIGlmKGkgaW5zdGFuY2VvZiBDUEluc3RydWN0aW9uKSB7Ci0gICAgICAgIENQSW5zdHJ1Y3Rpb24gY2kgPSAoQ1BJbnN0cnVjdGlvbilpOwotICAgICAgICBDb25zdGFudCAgICAgIGMgID0gb2xkX2NwLmdldENvbnN0YW50KGNpLmdldEluZGV4KCkpOwotICAgICAgICBjaS5zZXRJbmRleChuZXdfY3AuYWRkQ29uc3RhbnQoYywgb2xkX2NwKSk7Ci0gICAgICB9Ci0gICAgfQotICB9Ci0KLSAgcHJpdmF0ZSB2b2lkIGNsZWFyKCkgewotICAgIHN0YXJ0ID0gZW5kID0gbnVsbDsKLSAgICBsZW5ndGggPSAwOwotICB9Ci0KLSAgLyoqCi0gICAqIERlbGV0ZSBjb250ZW50cyBvZiBsaXN0LiBQcm92aWRlcyBiZXNzZXIgbWVtb3J5IHV0aWxpemF0aW9uLAotICAgKiBiZWNhdXNlIHRoZSBzeXN0ZW0gdGhlbiBtYXkgcmV1c2UgdGhlIGluc3RydWN0aW9uIGhhbmRsZXMuIFRoaXMKLSAgICogbWV0aG9kIGlzIHR5cGljYWxseSBjYWxsZWQgcmlnaHQgYWZ0ZXIKLSAgICogPGhyZWY9Ik1ldGhvZEdlbi5odG1sI2dldE1ldGhvZCgpIj5NZXRob2RHZW4uZ2V0TWV0aG9kKCk8L2E+LgotICAgKi8KLSAgcHVibGljIHZvaWQgZGlzcG9zZSgpIHsKLSAgICAvLyBUcmF2ZXJzZSBpbiByZXZlcnNlIG9yZGVyLCBiZWNhdXNlIGloLm5leHQgaXMgb3ZlcndyaXR0ZW4KLSAgICBmb3IoSW5zdHJ1Y3Rpb25IYW5kbGUgaWg9ZW5kOyBpaCAhPSBudWxsOyBpaCA9IGloLnByZXYpCi0gICAgICAvKiBDYXVzZXMgQnJhbmNoSW5zdHJ1Y3Rpb25zIHRvIHJlbGVhc2UgdGFyZ2V0IGFuZCB0YXJnZXRlcnMsIGJlY2F1c2UgaXQKLSAgICAgICAqIGNhbGxzIGRpc3Bvc2UoKSBvbiB0aGUgY29udGFpbmVkIGluc3RydWN0aW9uLgotICAgICAgICovCi0gICAgICBpaC5kaXNwb3NlKCk7Ci0KLSAgICBjbGVhcigpOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gc3RhcnQgb2YgbGlzdAotICAgKi8KLSAgcHVibGljIEluc3RydWN0aW9uSGFuZGxlIGdldFN0YXJ0KCkgeyByZXR1cm4gc3RhcnQ7IH0KLQotICAvKioKLSAgICogQHJldHVybiBlbmQgb2YgbGlzdAotICAgKi8KLSAgcHVibGljIEluc3RydWN0aW9uSGFuZGxlIGdldEVuZCgpICAgeyByZXR1cm4gZW5kOyB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gbGVuZ3RoIG9mIGxpc3QgKE51bWJlciBvZiBpbnN0cnVjdGlvbnMsIG5vdCBieXRlcykKLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0TGVuZ3RoKCkgeyByZXR1cm4gbGVuZ3RoOyB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gbGVuZ3RoIG9mIGxpc3QgKE51bWJlciBvZiBpbnN0cnVjdGlvbnMsIG5vdCBieXRlcykKLSAgICovCi0gIHB1YmxpYyBpbnQgc2l6ZSgpIHsgcmV0dXJuIGxlbmd0aDsgfQotCi0gIC8qKgotICAgKiBSZWRpcmVjdCBhbGwgcmVmZXJlbmNlcyBmcm9tIG9sZF90YXJnZXQgdG8gbmV3X3RhcmdldCwgaS5lLiwgdXBkYXRlIHRhcmdldHMKLSAgICogb2YgYnJhbmNoIGluc3RydWN0aW9ucy4KLSAgICoKLSAgICogQHBhcmFtIG9sZF90YXJnZXQgdGhlIG9sZCB0YXJnZXQgaW5zdHJ1Y3Rpb24gaGFuZGxlCi0gICAqIEBwYXJhbSBuZXdfdGFyZ2V0IHRoZSBuZXcgdGFyZ2V0IGluc3RydWN0aW9uIGhhbmRsZQotICAgKi8KLSAgcHVibGljIHZvaWQgcmVkaXJlY3RCcmFuY2hlcyhJbnN0cnVjdGlvbkhhbmRsZSBvbGRfdGFyZ2V0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluc3RydWN0aW9uSGFuZGxlIG5ld190YXJnZXQpIHsKLSAgICBmb3IoSW5zdHJ1Y3Rpb25IYW5kbGUgaWggPSBzdGFydDsgaWggIT0gbnVsbDsgaWggPSBpaC5uZXh0KSB7Ci0gICAgICBJbnN0cnVjdGlvbiBpICA9IGloLmdldEluc3RydWN0aW9uKCk7Ci0KLSAgICAgIGlmKGkgaW5zdGFuY2VvZiBCcmFuY2hJbnN0cnVjdGlvbikgewotICAgICAgICBCcmFuY2hJbnN0cnVjdGlvbiBiICAgICAgPSAoQnJhbmNoSW5zdHJ1Y3Rpb24paTsKLSAgICAgICAgSW5zdHJ1Y3Rpb25IYW5kbGUgdGFyZ2V0ID0gYi5nZXRUYXJnZXQoKTsKLQotICAgICAgICBpZih0YXJnZXQgPT0gb2xkX3RhcmdldCkKLSAgICAgICAgICBiLnNldFRhcmdldChuZXdfdGFyZ2V0KTsKLQotICAgICAgICBpZihiIGluc3RhbmNlb2YgU2VsZWN0KSB7IC8vIEVpdGhlciBMT09LVVBTV0lUQ0ggb3IgVEFCTEVTV0lUQ0gKLSAgICAgICAgICBJbnN0cnVjdGlvbkhhbmRsZVtdIHRhcmdldHMgPSAoKFNlbGVjdCliKS5nZXRUYXJnZXRzKCk7Ci0KLSAgICAgICAgICBmb3IoaW50IGo9MDsgaiA8IHRhcmdldHMubGVuZ3RoOyBqKyspIC8vIFVwZGF0ZSB0YXJnZXRzCi0gICAgICAgICAgICBpZih0YXJnZXRzW2pdID09IG9sZF90YXJnZXQpCi0gICAgICAgICAgICAgICgoU2VsZWN0KWIpLnNldFRhcmdldChqLCBuZXdfdGFyZ2V0KTsKLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBSZWRpcmVjdCBhbGwgcmVmZXJlbmNlcyBvZiBsb2NhbCB2YXJpYWJsZXMgZnJvbSBvbGRfdGFyZ2V0IHRvIG5ld190YXJnZXQuCi0gICAqCi0gICAqIEBwYXJhbSBsZyBhcnJheSBvZiBsb2NhbCB2YXJpYWJsZXMKLSAgICogQHBhcmFtIG9sZF90YXJnZXQgdGhlIG9sZCB0YXJnZXQgaW5zdHJ1Y3Rpb24gaGFuZGxlCi0gICAqIEBwYXJhbSBuZXdfdGFyZ2V0IHRoZSBuZXcgdGFyZ2V0IGluc3RydWN0aW9uIGhhbmRsZQotICAgKiBAc2VlIE1ldGhvZEdlbgotICAgKi8KLSAgcHVibGljIHZvaWQgcmVkaXJlY3RMb2NhbFZhcmlhYmxlcyhMb2NhbFZhcmlhYmxlR2VuW10gbGcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW5zdHJ1Y3Rpb25IYW5kbGUgb2xkX3RhcmdldCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbnN0cnVjdGlvbkhhbmRsZSBuZXdfdGFyZ2V0KSB7Ci0gICAgZm9yKGludCBpPTA7IGkgPCBsZy5sZW5ndGg7IGkrKykgewotICAgICAgSW5zdHJ1Y3Rpb25IYW5kbGUgc3RhcnQgPSBsZ1tpXS5nZXRTdGFydCgpOwotICAgICAgSW5zdHJ1Y3Rpb25IYW5kbGUgZW5kICAgPSBsZ1tpXS5nZXRFbmQoKTsKLQotICAgICAgaWYoc3RhcnQgPT0gb2xkX3RhcmdldCkKLSAgICAgICAgbGdbaV0uc2V0U3RhcnQobmV3X3RhcmdldCk7Ci0KLSAgICAgIGlmKGVuZCA9PSBvbGRfdGFyZ2V0KQotICAgICAgICBsZ1tpXS5zZXRFbmQobmV3X3RhcmdldCk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFJlZGlyZWN0IGFsbCByZWZlcmVuY2VzIG9mIGV4Y2VwdGlvbiBoYW5kbGVycyBmcm9tIG9sZF90YXJnZXQgdG8gbmV3X3RhcmdldC4KLSAgICoKLSAgICogQHBhcmFtIGV4Y2VwdGlvbnMgYXJyYXkgb2YgZXhjZXB0aW9uIGhhbmRsZXJzCi0gICAqIEBwYXJhbSBvbGRfdGFyZ2V0IHRoZSBvbGQgdGFyZ2V0IGluc3RydWN0aW9uIGhhbmRsZQotICAgKiBAcGFyYW0gbmV3X3RhcmdldCB0aGUgbmV3IHRhcmdldCBpbnN0cnVjdGlvbiBoYW5kbGUKLSAgICogQHNlZSBNZXRob2RHZW4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHJlZGlyZWN0RXhjZXB0aW9uSGFuZGxlcnMoQ29kZUV4Y2VwdGlvbkdlbltdIGV4Y2VwdGlvbnMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW5zdHJ1Y3Rpb25IYW5kbGUgb2xkX3RhcmdldCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbnN0cnVjdGlvbkhhbmRsZSBuZXdfdGFyZ2V0KSB7Ci0gICAgZm9yKGludCBpPTA7IGkgPCBleGNlcHRpb25zLmxlbmd0aDsgaSsrKSB7Ci0gICAgICBpZihleGNlcHRpb25zW2ldLmdldFN0YXJ0UEMoKSA9PSBvbGRfdGFyZ2V0KQotICAgICAgICBleGNlcHRpb25zW2ldLnNldFN0YXJ0UEMobmV3X3RhcmdldCk7Ci0KLSAgICAgIGlmKGV4Y2VwdGlvbnNbaV0uZ2V0RW5kUEMoKSA9PSBvbGRfdGFyZ2V0KQotICAgICAgICBleGNlcHRpb25zW2ldLnNldEVuZFBDKG5ld190YXJnZXQpOwotCi0gICAgICBpZihleGNlcHRpb25zW2ldLmdldEhhbmRsZXJQQygpID09IG9sZF90YXJnZXQpCi0gICAgICAgIGV4Y2VwdGlvbnNbaV0uc2V0SGFuZGxlclBDKG5ld190YXJnZXQpOwotICAgIH0KLSAgfQotCi0gIHByaXZhdGUgQXJyYXlMaXN0IG9ic2VydmVyczsKLQotICAvKiogQWRkIG9ic2VydmVyIGZvciB0aGlzIG9iamVjdC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGFkZE9ic2VydmVyKEluc3RydWN0aW9uTGlzdE9ic2VydmVyIG8pIHsKLSAgICBpZihvYnNlcnZlcnMgPT0gbnVsbCkKLSAgICAgIG9ic2VydmVycyA9IG5ldyBBcnJheUxpc3QoKTsKLQotICAgIG9ic2VydmVycy5hZGQobyk7Ci0gIH0KLQotICAvKiogUmVtb3ZlIG9ic2VydmVyIGZvciB0aGlzIG9iamVjdC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHJlbW92ZU9ic2VydmVyKEluc3RydWN0aW9uTGlzdE9ic2VydmVyIG8pIHsKLSAgICBpZihvYnNlcnZlcnMgIT0gbnVsbCkKLSAgICAgIG9ic2VydmVycy5yZW1vdmUobyk7Ci0gIH0KLQotICAvKiogQ2FsbCBub3RpZnkoKSBtZXRob2Qgb24gYWxsIG9ic2VydmVycy4gVGhpcyBtZXRob2QgaXMgbm90IGNhbGxlZAotICAgKiBhdXRvbWF0aWNhbGx5IHdoZW5ldmVyIHRoZSBzdGF0ZSBoYXMgY2hhbmdlZCwgYnV0IGhhcyB0byBiZQotICAgKiBjYWxsZWQgYnkgdGhlIHVzZXIgYWZ0ZXIgaGUgaGFzIGZpbmlzaGVkIGVkaXRpbmcgdGhlIG9iamVjdC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHVwZGF0ZSgpIHsKLSAgICBpZihvYnNlcnZlcnMgIT0gbnVsbCkKLSAgICAgIGZvcihJdGVyYXRvciBlID0gb2JzZXJ2ZXJzLml0ZXJhdG9yKCk7IGUuaGFzTmV4dCgpOyApCi0gICAgICAgICgoSW5zdHJ1Y3Rpb25MaXN0T2JzZXJ2ZXIpZS5uZXh0KCkpLm5vdGlmeSh0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSW5zdHJ1Y3Rpb25MaXN0T2JzZXJ2ZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0luc3RydWN0aW9uTGlzdE9ic2VydmVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDkxYWQzMjEuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSW5zdHJ1Y3Rpb25MaXN0T2JzZXJ2ZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDY5ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8qKgotICogSW1wbGVtZW50IHRoaXMgaW50ZXJmYWNlIGlmIHlvdSdyZSBpbnRlcmVzdGVkIGluIGNoYW5nZXMgdG8gYW4gSW5zdHJ1Y3Rpb25MaXN0IG9iamVjdAotICogYW5kIHJlZ2lzdGVyIHlvdXJzZWxmIHdpdGggYWRkT2JzZXJ2ZXIoKS4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgaW50ZXJmYWNlIEluc3RydWN0aW9uTGlzdE9ic2VydmVyIHsKLSAgcHVibGljIHZvaWQgbm90aWZ5KEluc3RydWN0aW9uTGlzdCBsaXN0KTsKLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0luc3RydWN0aW9uVGFyZ2V0ZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0luc3RydWN0aW9uVGFyZ2V0ZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggM2VhZWIzYS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JbnN0cnVjdGlvblRhcmdldGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3MyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIERlbm90ZSB0aGF0IGEgY2xhc3MgdGFyZ2V0cyBJbnN0cnVjdGlvbkhhbmRsZXMgd2l0aGluIGFuIEluc3RydWN0aW9uTGlzdC4gTmFtZWx5Ci0gKiB0aGUgZm9sbG93aW5nIGltcGxlbWVudGVyczoKLSAqCi0gKiBAc2VlIEJyYW5jaEhhbmRsZQotICogQHNlZSBMb2NhbFZhcmlhYmxlR2VuCi0gKiBAc2VlIENvZGVFeGNlcHRpb25HZW4KLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgSW5zdHJ1Y3Rpb25UYXJnZXRlciB7Ci0gIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zVGFyZ2V0KEluc3RydWN0aW9uSGFuZGxlIGloKTsKLSAgcHVibGljIHZvaWQgdXBkYXRlVGFyZ2V0KEluc3RydWN0aW9uSGFuZGxlIG9sZF9paCwgSW5zdHJ1Y3Rpb25IYW5kbGUgbmV3X2loKTsKLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0ludm9rZUluc3RydWN0aW9uLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9JbnZva2VJbnN0cnVjdGlvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjYWUyYmQ1Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0ludm9rZUluc3RydWN0aW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNDkgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuY2xhc3NmaWxlLio7Ci1pbXBvcnQgamF2YS51dGlsLlN0cmluZ1Rva2VuaXplcjsKLQotLyoqCi0gKiBTdXBlciBjbGFzcyBmb3IgdGhlIElOVk9LRXh4eCBmYW1pbHkgb2YgaW5zdHJ1Y3Rpb25zLgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBJbnZva2VJbnN0cnVjdGlvbiBleHRlbmRzIEZpZWxkT3JNZXRob2QKLSAgaW1wbGVtZW50cyBFeGNlcHRpb25UaHJvd2VyLCBUeXBlZEluc3RydWN0aW9uLCBTdGFja0NvbnN1bWVyLCBTdGFja1Byb2R1Y2VyIHsKLSAgLyoqCi0gICAqIEVtcHR5IGNvbnN0cnVjdG9yIG5lZWRlZCBmb3IgdGhlIENsYXNzLm5ld0luc3RhbmNlKCkgc3RhdGVtZW50IGluCi0gICAqIEluc3RydWN0aW9uLnJlYWRJbnN0cnVjdGlvbigpLiBOb3QgdG8gYmUgdXNlZCBvdGhlcndpc2UuCi0gICAqLwotICBJbnZva2VJbnN0cnVjdGlvbigpIHt9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBpbmRleCB0byBjb25zdGFudCBwb29sCi0gICAqLwotICBwcm90ZWN0ZWQgSW52b2tlSW5zdHJ1Y3Rpb24oc2hvcnQgb3Bjb2RlLCBpbnQgaW5kZXgpIHsKLSAgICBzdXBlcihvcGNvZGUsIGluZGV4KTsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIG1uZW1vbmljIGZvciBpbnN0cnVjdGlvbiB3aXRoIHN5bWJvbGljIHJlZmVyZW5jZXMgcmVzb2x2ZWQKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoQ29uc3RhbnRQb29sIGNwKSB7Ci0gICAgQ29uc3RhbnQgICAgICAgIGMgICA9IGNwLmdldENvbnN0YW50KGluZGV4KTsKLSAgICBTdHJpbmdUb2tlbml6ZXIgdG9rID0gbmV3IFN0cmluZ1Rva2VuaXplcihjcC5jb25zdGFudFRvU3RyaW5nKGMpKTsKLQotICAgIHJldHVybiBDb25zdGFudHMuT1BDT0RFX05BTUVTW29wY29kZV0gKyAiICIgKwotICAgICAgdG9rLm5leHRUb2tlbigpLnJlcGxhY2UoJy4nLCAnLycpICsgdG9rLm5leHRUb2tlbigpOwotICB9Ci0KLSAgLyoqCi0gICAqIEFsc28gd29ya3MgZm9yIGluc3RydWN0aW9ucyB3aG9zZSBzdGFjayBlZmZlY3QgZGVwZW5kcyBvbiB0aGUKLSAgICogY29uc3RhbnQgcG9vbCBlbnRyeSB0aGV5IHJlZmVyZW5jZS4KLSAgICogQHJldHVybiBOdW1iZXIgb2Ygd29yZHMgY29uc3VtZWQgZnJvbSBzdGFjayBieSB0aGlzIGluc3RydWN0aW9uCi0gICAqLwotICBwdWJsaWMgaW50IGNvbnN1bWVTdGFjayhDb25zdGFudFBvb2xHZW4gY3BnKSB7Ci0gICAgICBTdHJpbmcgc2lnbmF0dXJlID0gZ2V0U2lnbmF0dXJlKGNwZyk7Ci0gICAgICBUeXBlW10gYXJncyAgICAgID0gVHlwZS5nZXRBcmd1bWVudFR5cGVzKHNpZ25hdHVyZSk7Ci0gICAgICBpbnQgICAgc3VtOwotCi0gICAgICBpZihvcGNvZGUgPT0gQ29uc3RhbnRzLklOVk9LRVNUQVRJQykKLSAgICAgICAgc3VtID0gMDsKLSAgICAgIGVsc2UKLSAgICAgICAgc3VtID0gMTsgIC8vIHRoaXMgcmVmZXJlbmNlCi0KLSAgICAgIGludCBuID0gYXJncy5sZW5ndGg7Ci0gICAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykKLSAgICAgICAgc3VtICs9IGFyZ3NbaV0uZ2V0U2l6ZSgpOwotCi0gICAgICByZXR1cm4gc3VtOwotICAgfQotCi0gIC8qKgotICAgKiBBbHNvIHdvcmtzIGZvciBpbnN0cnVjdGlvbnMgd2hvc2Ugc3RhY2sgZWZmZWN0IGRlcGVuZHMgb24gdGhlCi0gICAqIGNvbnN0YW50IHBvb2wgZW50cnkgdGhleSByZWZlcmVuY2UuCi0gICAqIEByZXR1cm4gTnVtYmVyIG9mIHdvcmRzIHByb2R1Y2VkIG9udG8gc3RhY2sgYnkgdGhpcyBpbnN0cnVjdGlvbgotICAgKi8KLSAgcHVibGljIGludCBwcm9kdWNlU3RhY2soQ29uc3RhbnRQb29sR2VuIGNwZykgewotICAgIHJldHVybiBnZXRSZXR1cm5UeXBlKGNwZykuZ2V0U2l6ZSgpOwotICB9Ci0KLSAgLyoqIEByZXR1cm4gcmV0dXJuIHR5cGUgb2YgcmVmZXJlbmNlZCBtZXRob2QuCi0gICAqLwotICBwdWJsaWMgVHlwZSBnZXRUeXBlKENvbnN0YW50UG9vbEdlbiBjcGcpIHsKLSAgICByZXR1cm4gZ2V0UmV0dXJuVHlwZShjcGcpOwotICB9Ci0KLSAgLyoqIEByZXR1cm4gbmFtZSBvZiByZWZlcmVuY2VkIG1ldGhvZC4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0TWV0aG9kTmFtZShDb25zdGFudFBvb2xHZW4gY3BnKSB7Ci0gICAgcmV0dXJuIGdldE5hbWUoY3BnKTsKLSAgfQotCi0gIC8qKiBAcmV0dXJuIHJldHVybiB0eXBlIG9mIHJlZmVyZW5jZWQgbWV0aG9kLgotICAgKi8KLSAgcHVibGljIFR5cGUgZ2V0UmV0dXJuVHlwZShDb25zdGFudFBvb2xHZW4gY3BnKSB7Ci0gICAgcmV0dXJuIFR5cGUuZ2V0UmV0dXJuVHlwZShnZXRTaWduYXR1cmUoY3BnKSk7Ci0gIH0KLQotICAvKiogQHJldHVybiBhcmd1bWVudCB0eXBlcyBvZiByZWZlcmVuY2VkIG1ldGhvZC4KLSAgICovCi0gIHB1YmxpYyBUeXBlW10gZ2V0QXJndW1lbnRUeXBlcyhDb25zdGFudFBvb2xHZW4gY3BnKSB7Ci0gICAgcmV0dXJuIFR5cGUuZ2V0QXJndW1lbnRUeXBlcyhnZXRTaWduYXR1cmUoY3BnKSk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0pTUi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSlNSLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGQ1YjU2M2IuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSlNSLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMjIgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLWltcG9ydCBqYXZhLmlvLio7Ci0KLS8qKgotICogSlNSIC0gSnVtcCB0byBzdWJyb3V0aW5lCi0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGNsYXNzIEpTUiBleHRlbmRzIEpzckluc3RydWN0aW9uIGltcGxlbWVudHMgVmFyaWFibGVMZW5ndGhJbnN0cnVjdGlvbiB7Ci0gIC8qKgotICAgKiBFbXB0eSBjb25zdHJ1Y3RvciBuZWVkZWQgZm9yIHRoZSBDbGFzcy5uZXdJbnN0YW5jZSgpIHN0YXRlbWVudCBpbgotICAgKiBJbnN0cnVjdGlvbi5yZWFkSW5zdHJ1Y3Rpb24oKS4gTm90IHRvIGJlIHVzZWQgb3RoZXJ3aXNlLgotICAgKi8KLSAgSlNSKCkge30KLQotICBwdWJsaWMgSlNSKEluc3RydWN0aW9uSGFuZGxlIHRhcmdldCkgewotICAgIHN1cGVyKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5KU1IsIHRhcmdldCk7Ci0gIH0KLQotICAvKioKLSAgICogRHVtcCBpbnN0cnVjdGlvbiBhcyBieXRlIGNvZGUgdG8gc3RyZWFtIG91dC4KLSAgICogQHBhcmFtIG91dCBPdXRwdXQgc3RyZWFtCi0gICAqLwotICBwdWJsaWMgdm9pZCBkdW1wKERhdGFPdXRwdXRTdHJlYW0gb3V0KSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgIGluZGV4ID0gZ2V0VGFyZ2V0T2Zmc2V0KCk7Ci0gICAgaWYob3Bjb2RlID09IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5KU1IpCi0gICAgICBzdXBlci5kdW1wKG91dCk7Ci0gICAgZWxzZSB7IC8vIEpTUl9XCi0gICAgICBpbmRleCA9IGdldFRhcmdldE9mZnNldCgpOwotICAgICAgb3V0LndyaXRlQnl0ZShvcGNvZGUpOwotICAgICAgb3V0LndyaXRlSW50KGluZGV4KTsKLSAgICB9Ci0gIH0KLQotICBwcm90ZWN0ZWQgaW50IHVwZGF0ZVBvc2l0aW9uKGludCBvZmZzZXQsIGludCBtYXhfb2Zmc2V0KSB7Ci0gICAgaW50IGkgPSBnZXRUYXJnZXRPZmZzZXQoKTsgLy8gRGVwZW5kaW5nIG9uIG9sZCBwb3NpdGlvbiB2YWx1ZQotCi0gICAgcG9zaXRpb24gKz0gb2Zmc2V0OyAvLyBQb3NpdGlvbiBtYXkgYmUgc2hpZnRlZCBieSBwcmVjZWRpbmcgZXhwYW5zaW9ucwotCi0gICAgaWYoTWF0aC5hYnMoaSkgPj0gKDMyNzY3IC0gbWF4X29mZnNldCkpIHsgLy8gdG8gbGFyZ2UgZm9yIHNob3J0IChlc3RpbWF0ZSkKLSAgICAgIG9wY29kZSAgPSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuSlNSX1c7Ci0gICAgICBsZW5ndGggPSA1OwotICAgICAgcmV0dXJuIDI7IC8vIDUgLSAzCi0gICAgfQotCi0gICAgcmV0dXJuIDA7Ci0gIH0KLQotICAvKioKLSAgICogQ2FsbCBjb3JyZXNwb25kaW5nIHZpc2l0b3IgbWV0aG9kKHMpLiBUaGUgb3JkZXIgaXM6Ci0gICAqIENhbGwgdmlzaXRvciBtZXRob2RzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMgZmlyc3QsIHRoZW4KLSAgICogY2FsbCBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY2xhc3MgaGllcmFyY2h5IGluIGRlc2NlbmRpbmcgb3JkZXIsCi0gICAqIGkuZS4sIHRoZSBtb3N0IHNwZWNpZmljIHZpc2l0WFhYKCkgY2FsbCBjb21lcyBsYXN0LgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRTdGFja1Byb2R1Y2VyKHRoaXMpOwotICAgIHYudmlzaXRWYXJpYWJsZUxlbmd0aEluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRCcmFuY2hJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0SnNySW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdEpTUih0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSlNSX1cuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0pTUl9XLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDMyY2ViMjkuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSlNSX1cuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExMyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotaW1wb3J0IGphdmEuaW8uKjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC51dGlsLkJ5dGVTZXF1ZW5jZTsKLQotLyoqCi0gKiBKU1JfVyAtIEp1bXAgdG8gc3Vicm91dGluZQotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBKU1JfVyBleHRlbmRzIEpzckluc3RydWN0aW9uIHsKLSAgLyoqCi0gICAqIEVtcHR5IGNvbnN0cnVjdG9yIG5lZWRlZCBmb3IgdGhlIENsYXNzLm5ld0luc3RhbmNlKCkgc3RhdGVtZW50IGluCi0gICAqIEluc3RydWN0aW9uLnJlYWRJbnN0cnVjdGlvbigpLiBOb3QgdG8gYmUgdXNlZCBvdGhlcndpc2UuCi0gICAqLwotICBKU1JfVygpIHt9Ci0KLSAgcHVibGljIEpTUl9XKEluc3RydWN0aW9uSGFuZGxlIHRhcmdldCkgewotICAgIHN1cGVyKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5KU1JfVywgdGFyZ2V0KTsKLSAgICBsZW5ndGggPSA1OwotICB9Ci0KLSAgLyoqCi0gICAqIER1bXAgaW5zdHJ1Y3Rpb24gYXMgYnl0ZSBjb2RlIHRvIHN0cmVhbSBvdXQuCi0gICAqIEBwYXJhbSBvdXQgT3V0cHV0IHN0cmVhbQotICAgKi8KLSAgcHVibGljIHZvaWQgZHVtcChEYXRhT3V0cHV0U3RyZWFtIG91dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLSAgICBpbmRleCA9IGdldFRhcmdldE9mZnNldCgpOwotICAgIG91dC53cml0ZUJ5dGUob3Bjb2RlKTsKLSAgICBvdXQud3JpdGVJbnQoaW5kZXgpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlYWQgbmVlZGVkIGRhdGEgKGUuZy4gaW5kZXgpIGZyb20gZmlsZS4KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIGluaXRGcm9tRmlsZShCeXRlU2VxdWVuY2UgYnl0ZXMsIGJvb2xlYW4gd2lkZSkgdGhyb3dzIElPRXhjZXB0aW9uCi0gIHsKLSAgICBpbmRleCA9IGJ5dGVzLnJlYWRJbnQoKTsKLSAgICBsZW5ndGggPSA1OwotICB9Ci0KLSAgLyoqCi0gICAqIENhbGwgY29ycmVzcG9uZGluZyB2aXNpdG9yIG1ldGhvZChzKS4gVGhlIG9yZGVyIGlzOgotICAgKiBDYWxsIHZpc2l0b3IgbWV0aG9kcyBvZiBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzIGZpcnN0LCB0aGVuCi0gICAqIGNhbGwgbWV0aG9kcyBhY2NvcmRpbmcgdG8gdGhlIGNsYXNzIGhpZXJhcmNoeSBpbiBkZXNjZW5kaW5nIG9yZGVyLAotICAgKiBpLmUuLCB0aGUgbW9zdCBzcGVjaWZpYyB2aXNpdFhYWCgpIGNhbGwgY29tZXMgbGFzdC4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0U3RhY2tQcm9kdWNlcih0aGlzKTsKLSAgICB2LnZpc2l0QnJhbmNoSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdEpzckluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRKU1JfVyh0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSnNySW5zdHJ1Y3Rpb24uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0pzckluc3RydWN0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGY3MWUxNjUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvSnNySW5zdHJ1Y3Rpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExOCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIFN1cGVyIGNsYXNzIGZvciBKU1IgLSBKdW1wIHRvIHN1YnJvdXRpbmUKLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgYWJzdHJhY3QgY2xhc3MgSnNySW5zdHJ1Y3Rpb24gZXh0ZW5kcyBCcmFuY2hJbnN0cnVjdGlvbgotICBpbXBsZW1lbnRzIFVuY29uZGl0aW9uYWxCcmFuY2gsIFR5cGVkSW5zdHJ1Y3Rpb24sIFN0YWNrUHJvZHVjZXIKLXsKLSAgSnNySW5zdHJ1Y3Rpb24oc2hvcnQgb3Bjb2RlLCBJbnN0cnVjdGlvbkhhbmRsZSB0YXJnZXQpIHsKLSAgICBzdXBlcihvcGNvZGUsIHRhcmdldCk7Ci0gIH0KLQotICAvKioKLSAgICogRW1wdHkgY29uc3RydWN0b3IgbmVlZGVkIGZvciB0aGUgQ2xhc3MubmV3SW5zdGFuY2UoKSBzdGF0ZW1lbnQgaW4KLSAgICogSW5zdHJ1Y3Rpb24ucmVhZEluc3RydWN0aW9uKCkuIE5vdCB0byBiZSB1c2VkIG90aGVyd2lzZS4KLSAgICovCi0gIEpzckluc3RydWN0aW9uKCl7fQotCi0gIC8qKiBAcmV0dXJuIHJldHVybiBhZGRyZXNzIHR5cGUKLSAgICovCi0gIHB1YmxpYyBUeXBlIGdldFR5cGUoQ29uc3RhbnRQb29sR2VuIGNwKSB7Ci0gICAgcmV0dXJuIG5ldyBSZXR1cm5hZGRyZXNzVHlwZShwaHlzaWNhbFN1Y2Nlc3NvcigpKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIGFuIEluc3RydWN0aW9uSGFuZGxlIHRvIHRoZSBwaHlzaWNhbCBzdWNjZXNzb3IKLSAgICogb2YgdGhpcyBKc3JJbnN0cnVjdGlvbi4gPEI+Rm9yIHRoaXMgbWV0aG9kIHRvIHdvcmssCi0gICAqIHRoaXMgSnNySW5zdHJ1Y3Rpb24gb2JqZWN0IG11c3Qgbm90IGJlIHNoYXJlZCBiZXR3ZWVuCi0gICAqIG11bHRpcGxlIEluc3RydWN0aW9uSGFuZGxlIG9iamVjdHMhPC9CPgotICAgKiBGb3JtYWxseSwgdGhlcmUgbXVzdCBub3QgYmUgSW5zdHJ1Y3Rpb25IYW5kbGUgb2JqZWN0cwotICAgKiBpLCBqIHdoZXJlIGkgIT0gaiBhbmQgaS5nZXRJbnN0cnVjdGlvbigpID09IHRoaXMgPT0KLSAgICogai5nZXRJbnN0cnVjdGlvbigpLgotICAgKiBAcmV0dXJuIGFuIEluc3RydWN0aW9uSGFuZGxlIHRvIHRoZSAibmV4dCIgaW5zdHJ1Y3Rpb24gdGhhdAotICAgKiB3aWxsIGJlIGV4ZWN1dGVkIHdoZW4gUkVUdXJuZWQgZnJvbSBhIHN1YnJvdXRpbmUuCi0gICAqLwotICBwdWJsaWMgSW5zdHJ1Y3Rpb25IYW5kbGUgcGh5c2ljYWxTdWNjZXNzb3IoKXsKLSAgICBJbnN0cnVjdGlvbkhhbmRsZSBpaCA9IHRoaXMudGFyZ2V0OwotCi0gICAgLy8gUmV3aW5kIQotICAgIHdoaWxlKGloLmdldFByZXYoKSAhPSBudWxsKQotICAgICAgaWggPSBpaC5nZXRQcmV2KCk7Ci0KLSAgICAvLyBGaW5kIHRoZSBoYW5kbGUgZm9yICJ0aGlzIiBKc3JJbnN0cnVjdGlvbiBvYmplY3QuCi0gICAgd2hpbGUoaWguZ2V0SW5zdHJ1Y3Rpb24oKSAhPSB0aGlzKQotICAgICAgaWggPSBpaC5nZXROZXh0KCk7Ci0KLSAgICBJbnN0cnVjdGlvbkhhbmRsZSB0b1RoaXMgPSBpaDsKLQotICAgIHdoaWxlKGloICE9IG51bGwpewotICAgICAgICBpaCA9IGloLmdldE5leHQoKTsKLSAgICAgICAgaWYgKChpaCAhPSBudWxsKSAmJiAoaWguZ2V0SW5zdHJ1Y3Rpb24oKSA9PSB0aGlzKSkKLSAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oInBoeXNpY2FsU3VjY2Vzc29yKCkgY2FsbGVkIG9uIGEgc2hhcmVkIEpzckluc3RydWN0aW9uLiIpOwotICAgIH0KLQotICAgIC8vIFJldHVybiB0aGUgcGh5c2ljYWwgc3VjY2Vzc29yCi0gICAgcmV0dXJuIHRvVGhpcy5nZXROZXh0KCk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0wyRC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvTDJELmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDhkMTQ5MTQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvTDJELmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4OCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIEwyRCAtIENvbnZlcnQgbG9uZyB0byBkb3VibGUKLSAqIDxQUkU+U3RhY2s6IC4uLiwgdmFsdWUud29yZDEsIHZhbHVlLndvcmQyIC0mZ3Q7IC4uLiwgcmVzdWx0LndvcmQxLCByZXN1bHQud29yZDI8L1BSRT4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgTDJEIGV4dGVuZHMgQ29udmVyc2lvbkluc3RydWN0aW9uIHsKLSAgcHVibGljIEwyRCgpIHsKLSAgICBzdXBlcihjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuTDJEKTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIENhbGwgY29ycmVzcG9uZGluZyB2aXNpdG9yIG1ldGhvZChzKS4gVGhlIG9yZGVyIGlzOgotICAgKiBDYWxsIHZpc2l0b3IgbWV0aG9kcyBvZiBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzIGZpcnN0LCB0aGVuCi0gICAqIGNhbGwgbWV0aG9kcyBhY2NvcmRpbmcgdG8gdGhlIGNsYXNzIGhpZXJhcmNoeSBpbiBkZXNjZW5kaW5nIG9yZGVyLAotICAgKiBpLmUuLCB0aGUgbW9zdCBzcGVjaWZpYyB2aXNpdFhYWCgpIGNhbGwgY29tZXMgbGFzdC4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0VHlwZWRJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tQcm9kdWNlcih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tDb25zdW1lcih0aGlzKTsKLSAgICB2LnZpc2l0Q29udmVyc2lvbkluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRMMkQodGhpcyk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0wyRi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvTDJGLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDM2NTcxZDYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvTDJGLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4OCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIEwyRiAtIENvbnZlcnQgbG9uZyB0byBmbG9hdAotICogPFBSRT5TdGFjazogLi4uLCB2YWx1ZS53b3JkMSwgdmFsdWUud29yZDIgLSZndDsgLi4uLCByZXN1bHQ8L1BSRT4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgTDJGIGV4dGVuZHMgQ29udmVyc2lvbkluc3RydWN0aW9uIHsKLSAgcHVibGljIEwyRigpIHsKLSAgICBzdXBlcihjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuTDJGKTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIENhbGwgY29ycmVzcG9uZGluZyB2aXNpdG9yIG1ldGhvZChzKS4gVGhlIG9yZGVyIGlzOgotICAgKiBDYWxsIHZpc2l0b3IgbWV0aG9kcyBvZiBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzIGZpcnN0LCB0aGVuCi0gICAqIGNhbGwgbWV0aG9kcyBhY2NvcmRpbmcgdG8gdGhlIGNsYXNzIGhpZXJhcmNoeSBpbiBkZXNjZW5kaW5nIG9yZGVyLAotICAgKiBpLmUuLCB0aGUgbW9zdCBzcGVjaWZpYyB2aXNpdFhYWCgpIGNhbGwgY29tZXMgbGFzdC4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0VHlwZWRJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tQcm9kdWNlcih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tDb25zdW1lcih0aGlzKTsKLSAgICB2LnZpc2l0Q29udmVyc2lvbkluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRMMkYodGhpcyk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0wySS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvTDJJLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGNhY2YzYWQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvTDJJLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4OCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIEwySSAtIENvbnZlcnQgbG9uZyB0byBpbnQKLSAqIDxQUkU+U3RhY2s6IC4uLiwgdmFsdWUud29yZDEsIHZhbHVlLndvcmQyIC0mZ3Q7IC4uLiwgcmVzdWx0PC9QUkU+Ci0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGNsYXNzIEwySSBleHRlbmRzIENvbnZlcnNpb25JbnN0cnVjdGlvbiB7Ci0gIHB1YmxpYyBMMkkoKSB7Ci0gICAgc3VwZXIoY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkwySSk7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBDYWxsIGNvcnJlc3BvbmRpbmcgdmlzaXRvciBtZXRob2QocykuIFRoZSBvcmRlciBpczoKLSAgICogQ2FsbCB2aXNpdG9yIG1ldGhvZHMgb2YgaW1wbGVtZW50ZWQgaW50ZXJmYWNlcyBmaXJzdCwgdGhlbgotICAgKiBjYWxsIG1ldGhvZHMgYWNjb3JkaW5nIHRvIHRoZSBjbGFzcyBoaWVyYXJjaHkgaW4gZGVzY2VuZGluZyBvcmRlciwKLSAgICogaS5lLiwgdGhlIG1vc3Qgc3BlY2lmaWMgdmlzaXRYWFgoKSBjYWxsIGNvbWVzIGxhc3QuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgdi52aXNpdFR5cGVkSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdFN0YWNrUHJvZHVjZXIodGhpcyk7Ci0gICAgdi52aXNpdFN0YWNrQ29uc3VtZXIodGhpcyk7Ci0gICAgdi52aXNpdENvbnZlcnNpb25JbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0TDJJKHRoaXMpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9MQURELmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9MQURELmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDZhYjFmNDIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvTEFERC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsODkgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotLyoqCi0gKiBMQUREIC0gQWRkIGxvbmdzCi0gKiA8UFJFPlN0YWNrOiAuLi4sIHZhbHVlMS53b3JkMSwgdmFsdWUxLndvcmQyLCB2YWx1ZTIud29yZDEsIHZhbHVlMi53b3JkMiAtJmd0OzwvUFJFPgotICogICAgICAgIC4uLiwgcmVzdWx0LndvcmQxLCByZXN1bHQud29yZDIKLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgTEFERCBleHRlbmRzIEFyaXRobWV0aWNJbnN0cnVjdGlvbiB7Ci0gIHB1YmxpYyBMQUREKCkgewotICAgIHN1cGVyKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5MQUREKTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIENhbGwgY29ycmVzcG9uZGluZyB2aXNpdG9yIG1ldGhvZChzKS4gVGhlIG9yZGVyIGlzOgotICAgKiBDYWxsIHZpc2l0b3IgbWV0aG9kcyBvZiBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzIGZpcnN0LCB0aGVuCi0gICAqIGNhbGwgbWV0aG9kcyBhY2NvcmRpbmcgdG8gdGhlIGNsYXNzIGhpZXJhcmNoeSBpbiBkZXNjZW5kaW5nIG9yZGVyLAotICAgKiBpLmUuLCB0aGUgbW9zdCBzcGVjaWZpYyB2aXNpdFhYWCgpIGNhbGwgY29tZXMgbGFzdC4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0VHlwZWRJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tQcm9kdWNlcih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tDb25zdW1lcih0aGlzKTsKLSAgICB2LnZpc2l0QXJpdGhtZXRpY0luc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRMQUREKHRoaXMpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9MQUxPQUQuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0xBTE9BRC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlNzE4NWFjLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0xBTE9BRC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTAgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotLyoqCi0gKiBMQUxPQUQgLSBMb2FkIGxvbmcgZnJvbSBhcnJheQotICogPFBSRT5TdGFjazogLi4uLCBhcnJheXJlZiwgaW5kZXggLSZndDsgLi4uLCB2YWx1ZTEsIHZhbHVlMjwvUFJFPgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBMQUxPQUQgZXh0ZW5kcyBBcnJheUluc3RydWN0aW9uIGltcGxlbWVudHMgU3RhY2tQcm9kdWNlciB7Ci0gIC8qKiBMb2FkIGxvbmcgZnJvbSBhcnJheQotICAgKi8KLSAgcHVibGljIExBTE9BRCgpIHsKLSAgICBzdXBlcihjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuTEFMT0FEKTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIENhbGwgY29ycmVzcG9uZGluZyB2aXNpdG9yIG1ldGhvZChzKS4gVGhlIG9yZGVyIGlzOgotICAgKiBDYWxsIHZpc2l0b3IgbWV0aG9kcyBvZiBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzIGZpcnN0LCB0aGVuCi0gICAqIGNhbGwgbWV0aG9kcyBhY2NvcmRpbmcgdG8gdGhlIGNsYXNzIGhpZXJhcmNoeSBpbiBkZXNjZW5kaW5nIG9yZGVyLAotICAgKiBpLmUuLCB0aGUgbW9zdCBzcGVjaWZpYyB2aXNpdFhYWCgpIGNhbGwgY29tZXMgbGFzdC4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0U3RhY2tQcm9kdWNlcih0aGlzKTsKLSAgICB2LnZpc2l0RXhjZXB0aW9uVGhyb3dlcih0aGlzKTsKLSAgICB2LnZpc2l0VHlwZWRJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0QXJyYXlJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0TEFMT0FEKHRoaXMpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9MQU5ELmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9MQU5ELmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGMyMjVjYWMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvTEFORC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsODkgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotLyoqCi0gKiBMQU5EIC0gQml0d2lzZSBBTkQgbG9uZ3MKLSAqIDxQUkU+U3RhY2s6IC4uLiwgdmFsdWUxLndvcmQxLCB2YWx1ZTEud29yZDIsIHZhbHVlMi53b3JkMSwgdmFsdWUyLndvcmQyIC0mZ3Q7PC9QUkU+Ci0gKiAgICAgICAgLi4uLCByZXN1bHQud29yZDEsIHJlc3VsdC53b3JkMgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBMQU5EIGV4dGVuZHMgQXJpdGhtZXRpY0luc3RydWN0aW9uIHsKLSAgcHVibGljIExBTkQoKSB7Ci0gICAgc3VwZXIoY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkxBTkQpOwotICB9Ci0KLQotICAvKioKLSAgICogQ2FsbCBjb3JyZXNwb25kaW5nIHZpc2l0b3IgbWV0aG9kKHMpLiBUaGUgb3JkZXIgaXM6Ci0gICAqIENhbGwgdmlzaXRvciBtZXRob2RzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMgZmlyc3QsIHRoZW4KLSAgICogY2FsbCBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY2xhc3MgaGllcmFyY2h5IGluIGRlc2NlbmRpbmcgb3JkZXIsCi0gICAqIGkuZS4sIHRoZSBtb3N0IHNwZWNpZmljIHZpc2l0WFhYKCkgY2FsbCBjb21lcyBsYXN0LgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRUeXBlZEluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRTdGFja1Byb2R1Y2VyKHRoaXMpOwotICAgIHYudmlzaXRTdGFja0NvbnN1bWVyKHRoaXMpOwotICAgIHYudmlzaXRBcml0aG1ldGljSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdExBTkQodGhpcyk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0xBU1RPUkUuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0xBU1RPUkUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYzBlOTI4YS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9MQVNUT1JFLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5MCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIExBU1RPUkUgLSAgU3RvcmUgaW50byBsb25nIGFycmF5Ci0gKiA8UFJFPlN0YWNrOiAuLi4sIGFycmF5cmVmLCBpbmRleCwgdmFsdWUud29yZDEsIHZhbHVlLndvcmQyIC0mZ3Q7IC4uLjwvUFJFPgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBMQVNUT1JFIGV4dGVuZHMgQXJyYXlJbnN0cnVjdGlvbiBpbXBsZW1lbnRzIFN0YWNrQ29uc3VtZXIgewotICAvKiogU3RvcmUgbG9uZyBpbnRvIGFycmF5Ci0gICAqLwotICBwdWJsaWMgTEFTVE9SRSgpIHsKLSAgICBzdXBlcihjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuTEFTVE9SRSk7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBDYWxsIGNvcnJlc3BvbmRpbmcgdmlzaXRvciBtZXRob2QocykuIFRoZSBvcmRlciBpczoKLSAgICogQ2FsbCB2aXNpdG9yIG1ldGhvZHMgb2YgaW1wbGVtZW50ZWQgaW50ZXJmYWNlcyBmaXJzdCwgdGhlbgotICAgKiBjYWxsIG1ldGhvZHMgYWNjb3JkaW5nIHRvIHRoZSBjbGFzcyBoaWVyYXJjaHkgaW4gZGVzY2VuZGluZyBvcmRlciwKLSAgICogaS5lLiwgdGhlIG1vc3Qgc3BlY2lmaWMgdmlzaXRYWFgoKSBjYWxsIGNvbWVzIGxhc3QuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgdi52aXNpdFN0YWNrQ29uc3VtZXIodGhpcyk7Ci0gICAgdi52aXNpdEV4Y2VwdGlvblRocm93ZXIodGhpcyk7Ci0gICAgdi52aXNpdFR5cGVkSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdEFycmF5SW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdExBU1RPUkUodGhpcyk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0xDTVAuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0xDTVAuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDVjMWFlZS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9MQ01QLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5NSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIExDTVAgLSBDb21wYXJlIGxvbmdzOgotICogPFBSRT5TdGFjazogLi4uLCB2YWx1ZTEud29yZDEsIHZhbHVlMS53b3JkMiwgdmFsdWUyLndvcmQxLCB2YWx1ZTIud29yZDIgLSZndDs8L1BSRT4KLSAqICAgICAgICAuLi4sIHJlc3VsdCA8PSAtMSwgMCwgMT4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgTENNUCBleHRlbmRzIEluc3RydWN0aW9uCi0gIGltcGxlbWVudHMgVHlwZWRJbnN0cnVjdGlvbiwgU3RhY2tQcm9kdWNlciwgU3RhY2tDb25zdW1lcgotewotICBwdWJsaWMgTENNUCgpIHsKLSAgICBzdXBlcihjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuTENNUCwgKHNob3J0KTEpOwotICB9Ci0KLSAgLyoqIEByZXR1cm4gVHlwZS5MT05HCi0gICAqLwotICBwdWJsaWMgVHlwZSBnZXRUeXBlKENvbnN0YW50UG9vbEdlbiBjcCkgewotICAgIHJldHVybiBUeXBlLkxPTkc7Ci0gIH0KLQotICAvKioKLSAgICogQ2FsbCBjb3JyZXNwb25kaW5nIHZpc2l0b3IgbWV0aG9kKHMpLiBUaGUgb3JkZXIgaXM6Ci0gICAqIENhbGwgdmlzaXRvciBtZXRob2RzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMgZmlyc3QsIHRoZW4KLSAgICogY2FsbCBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY2xhc3MgaGllcmFyY2h5IGluIGRlc2NlbmRpbmcgb3JkZXIsCi0gICAqIGkuZS4sIHRoZSBtb3N0IHNwZWNpZmljIHZpc2l0WFhYKCkgY2FsbCBjb21lcyBsYXN0LgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRUeXBlZEluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRTdGFja1Byb2R1Y2VyKHRoaXMpOwotICAgIHYudmlzaXRTdGFja0NvbnN1bWVyKHRoaXMpOwotICAgIHYudmlzaXRMQ01QKHRoaXMpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9MQ09OU1QuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0xDT05TVC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3ZmU5NGEyLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0xDT05TVC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTE0ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8qKgotICogTENPTlNUIC0gUHVzaCAwIG9yIDEsIG90aGVyIHZhbHVlcyBjYXVzZSBhbiBleGNlcHRpb24KLSAqCi0gKiA8UFJFPlN0YWNrOiAuLi4gLSZndDsgLi4uLCA8L1BSRT4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgTENPTlNUIGV4dGVuZHMgSW5zdHJ1Y3Rpb24KLSAgaW1wbGVtZW50cyBDb25zdGFudFB1c2hJbnN0cnVjdGlvbiwgVHlwZWRJbnN0cnVjdGlvbiB7Ci0gIHByaXZhdGUgbG9uZyB2YWx1ZTsKLQotICAvKioKLSAgICogRW1wdHkgY29uc3RydWN0b3IgbmVlZGVkIGZvciB0aGUgQ2xhc3MubmV3SW5zdGFuY2UoKSBzdGF0ZW1lbnQgaW4KLSAgICogSW5zdHJ1Y3Rpb24ucmVhZEluc3RydWN0aW9uKCkuIE5vdCB0byBiZSB1c2VkIG90aGVyd2lzZS4KLSAgICovCi0gIExDT05TVCgpIHt9Ci0KLSAgcHVibGljIExDT05TVChsb25nIGwpIHsKLSAgICBzdXBlcihjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuTENPTlNUXzAsIChzaG9ydCkxKTsKLQotICAgIGlmKGwgPT0gMCkKLSAgICAgIG9wY29kZSA9IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5MQ09OU1RfMDsKLSAgICBlbHNlIGlmKGwgPT0gMSkKLSAgICAgIG9wY29kZSA9IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5MQ09OU1RfMTsKLSAgICBlbHNlCi0gICAgICB0aHJvdyBuZXcgQ2xhc3NHZW5FeGNlcHRpb24oIkxDT05TVCBjYW4gYmUgdXNlZCBvbmx5IGZvciAwIGFuZCAxOiAiICsgbCk7Ci0KLSAgICB2YWx1ZSA9IGw7Ci0gIH0KLQotICBwdWJsaWMgTnVtYmVyIGdldFZhbHVlKCkgeyByZXR1cm4gbmV3IExvbmcodmFsdWUpOyB9Ci0KLSAgLyoqIEByZXR1cm4gVHlwZS5MT05HCi0gICAqLwotICBwdWJsaWMgVHlwZSBnZXRUeXBlKENvbnN0YW50UG9vbEdlbiBjcCkgewotICAgIHJldHVybiBUeXBlLkxPTkc7Ci0gIH0KLQotICAvKioKLSAgICogQ2FsbCBjb3JyZXNwb25kaW5nIHZpc2l0b3IgbWV0aG9kKHMpLiBUaGUgb3JkZXIgaXM6Ci0gICAqIENhbGwgdmlzaXRvciBtZXRob2RzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMgZmlyc3QsIHRoZW4KLSAgICogY2FsbCBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY2xhc3MgaGllcmFyY2h5IGluIGRlc2NlbmRpbmcgb3JkZXIsCi0gICAqIGkuZS4sIHRoZSBtb3N0IHNwZWNpZmljIHZpc2l0WFhYKCkgY2FsbCBjb21lcyBsYXN0LgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRQdXNoSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdFN0YWNrUHJvZHVjZXIodGhpcyk7Ci0gICAgdi52aXNpdFR5cGVkSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdENvbnN0YW50UHVzaEluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRMQ09OU1QodGhpcyk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0xEQy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvTERDLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMWQ4MGUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvTERDLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNzUgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLWltcG9ydCBqYXZhLmlvLio7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwudXRpbC5CeXRlU2VxdWVuY2U7Ci0KLS8qKgotICogTERDIC0gUHVzaCBpdGVtIGZyb20gY29uc3RhbnQgcG9vbC4KLSAqCi0gKiA8UFJFPlN0YWNrOiAuLi4gLSZndDsgLi4uLCBpdGVtPC9QUkU+Ci0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGNsYXNzIExEQyBleHRlbmRzIENQSW5zdHJ1Y3Rpb24KLSAgaW1wbGVtZW50cyBQdXNoSW5zdHJ1Y3Rpb24sIEV4Y2VwdGlvblRocm93ZXIsIFR5cGVkSW5zdHJ1Y3Rpb24gewotICAvKioKLSAgICogRW1wdHkgY29uc3RydWN0b3IgbmVlZGVkIGZvciB0aGUgQ2xhc3MubmV3SW5zdGFuY2UoKSBzdGF0ZW1lbnQgaW4KLSAgICogSW5zdHJ1Y3Rpb24ucmVhZEluc3RydWN0aW9uKCkuIE5vdCB0byBiZSB1c2VkIG90aGVyd2lzZS4KLSAgICovCi0gIExEQygpIHt9Ci0KLSAgcHVibGljIExEQyhpbnQgaW5kZXgpIHsKLSAgICBzdXBlcihjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuTERDX1csIGluZGV4KTsKLSAgICBzZXRTaXplKCk7Ci0gIH0KLQotICAvLyBBZGp1c3QgdG8gcHJvcGVyIHNpemUKLSAgcHJvdGVjdGVkIGZpbmFsIHZvaWQgc2V0U2l6ZSgpIHsKLSAgICBpZihpbmRleCA8PSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuTUFYX0JZVEUpIHsgLy8gRml0cyBpbiBvbmUgYnl0ZT8KLSAgICAgIG9wY29kZSA9IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5MREM7Ci0gICAgICBsZW5ndGggPSAyOwotICAgIH0gZWxzZSB7Ci0gICAgICBvcGNvZGUgPSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuTERDX1c7Ci0gICAgICBsZW5ndGggPSAzOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBEdW1wIGluc3RydWN0aW9uIGFzIGJ5dGUgY29kZSB0byBzdHJlYW0gb3V0LgotICAgKiBAcGFyYW0gb3V0IE91dHB1dCBzdHJlYW0KLSAgICovCi0gIHB1YmxpYyB2b2lkIGR1bXAoRGF0YU91dHB1dFN0cmVhbSBvdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgb3V0LndyaXRlQnl0ZShvcGNvZGUpOwotCi0gICAgaWYobGVuZ3RoID09IDIpCi0gICAgICBvdXQud3JpdGVCeXRlKGluZGV4KTsKLSAgICBlbHNlIC8vIEFwcGxpZXMgZm9yIExEQ19XCi0gICAgICBvdXQud3JpdGVTaG9ydChpbmRleCk7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBpbmRleCB0byBjb25zdGFudCBwb29sIGFuZCBhZGp1c3Qgc2l6ZS4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHNldEluZGV4KGludCBpbmRleCkgewotICAgIHN1cGVyLnNldEluZGV4KGluZGV4KTsKLSAgICBzZXRTaXplKCk7Ci0gIH0KLQotICAvKioKLSAgICogUmVhZCBuZWVkZWQgZGF0YSAoZS5nLiBpbmRleCkgZnJvbSBmaWxlLgotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgaW5pdEZyb21GaWxlKEJ5dGVTZXF1ZW5jZSBieXRlcywgYm9vbGVhbiB3aWRlKQotICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbgotICB7Ci0gICAgbGVuZ3RoID0gMjsKLSAgICBpbmRleCAgPSBieXRlcy5yZWFkVW5zaWduZWRCeXRlKCk7Ci0gIH0KLQotICBwdWJsaWMgT2JqZWN0IGdldFZhbHVlKENvbnN0YW50UG9vbEdlbiBjcGcpIHsKLSAgICBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5jbGFzc2ZpbGUuQ29uc3RhbnQgYyA9IGNwZy5nZXRDb25zdGFudFBvb2woKS5nZXRDb25zdGFudChpbmRleCk7Ci0KLSAgICBzd2l0Y2goYy5nZXRUYWcoKSkgewotICAgICAgY2FzZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuQ09OU1RBTlRfU3RyaW5nOgotICAgICAgICBpbnQgaSA9ICgoY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuY2xhc3NmaWxlLkNvbnN0YW50U3RyaW5nKWMpLmdldFN0cmluZ0luZGV4KCk7Ci0gICAgICAgIGMgPSBjcGcuZ2V0Q29uc3RhbnRQb29sKCkuZ2V0Q29uc3RhbnQoaSk7Ci0gICAgICAgIHJldHVybiAoKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmNsYXNzZmlsZS5Db25zdGFudFV0ZjgpYykuZ2V0Qnl0ZXMoKTsKLQotICAgIGNhc2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkNPTlNUQU5UX0Zsb2F0OgotICAgICAgICByZXR1cm4gbmV3IEZsb2F0KCgoY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuY2xhc3NmaWxlLkNvbnN0YW50RmxvYXQpYykuZ2V0Qnl0ZXMoKSk7Ci0KLSAgICBjYXNlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5DT05TVEFOVF9JbnRlZ2VyOgotICAgICAgICByZXR1cm4gbmV3IEludGVnZXIoKChjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5jbGFzc2ZpbGUuQ29uc3RhbnRJbnRlZ2VyKWMpLmdldEJ5dGVzKCkpOwotCi0gICAgZGVmYXVsdDogLy8gTmV2ZXIgcmVhY2hlZAotICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlVua25vd24gb3IgaW52YWxpZCBjb25zdGFudCB0eXBlIGF0ICIgKyBpbmRleCk7Ci0gICAgICB9Ci0gIH0KLQotICBwdWJsaWMgVHlwZSBnZXRUeXBlKENvbnN0YW50UG9vbEdlbiBjcGcpIHsKLSAgICBzd2l0Y2goY3BnLmdldENvbnN0YW50UG9vbCgpLmdldENvbnN0YW50KGluZGV4KS5nZXRUYWcoKSkgewotICAgIGNhc2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkNPTlNUQU5UX1N0cmluZzogIHJldHVybiBUeXBlLlNUUklORzsKLSAgICBjYXNlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5DT05TVEFOVF9GbG9hdDogICByZXR1cm4gVHlwZS5GTE9BVDsKLSAgICBjYXNlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5DT05TVEFOVF9JbnRlZ2VyOiByZXR1cm4gVHlwZS5JTlQ7Ci0gICAgZGVmYXVsdDogLy8gTmV2ZXIgcmVhY2hlZAotICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlVua25vd24gb3IgaW52YWxpZCBjb25zdGFudCB0eXBlIGF0ICIgKyBpbmRleCk7Ci0gICAgfQotICB9Ci0KLSAgcHVibGljIENsYXNzW10gZ2V0RXhjZXB0aW9ucygpIHsKLSAgICByZXR1cm4gY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuRXhjZXB0aW9uQ29uc3RhbnRzLkVYQ1NfU1RSSU5HX1JFU09MVVRJT047Ci0gIH0KLQotICAvKioKLSAgICogQ2FsbCBjb3JyZXNwb25kaW5nIHZpc2l0b3IgbWV0aG9kKHMpLiBUaGUgb3JkZXIgaXM6Ci0gICAqIENhbGwgdmlzaXRvciBtZXRob2RzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMgZmlyc3QsIHRoZW4KLSAgICogY2FsbCBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY2xhc3MgaGllcmFyY2h5IGluIGRlc2NlbmRpbmcgb3JkZXIsCi0gICAqIGkuZS4sIHRoZSBtb3N0IHNwZWNpZmljIHZpc2l0WFhYKCkgY2FsbCBjb21lcyBsYXN0LgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRTdGFja1Byb2R1Y2VyKHRoaXMpOwotICAgIHYudmlzaXRQdXNoSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdEV4Y2VwdGlvblRocm93ZXIodGhpcyk7Ci0gICAgdi52aXNpdFR5cGVkSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdENQSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdExEQyh0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvTERDMl9XLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9MREMyX1cuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNGE5N2EyMC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9MREMyX1cuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExOSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIExEQzJfVyAtIFB1c2ggbG9uZyBvciBkb3VibGUgZnJvbSBjb25zdGFudCBwb29sCi0gKgotICogPFBSRT5TdGFjazogLi4uIC0mZ3Q7IC4uLiwgaXRlbS53b3JkMSwgaXRlbS53b3JkMjwvUFJFPgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBMREMyX1cgZXh0ZW5kcyBDUEluc3RydWN0aW9uCi0gIGltcGxlbWVudHMgUHVzaEluc3RydWN0aW9uLCBUeXBlZEluc3RydWN0aW9uIHsKLSAgLyoqCi0gICAqIEVtcHR5IGNvbnN0cnVjdG9yIG5lZWRlZCBmb3IgdGhlIENsYXNzLm5ld0luc3RhbmNlKCkgc3RhdGVtZW50IGluCi0gICAqIEluc3RydWN0aW9uLnJlYWRJbnN0cnVjdGlvbigpLiBOb3QgdG8gYmUgdXNlZCBvdGhlcndpc2UuCi0gICAqLwotICBMREMyX1coKSB7fQotCi0gIHB1YmxpYyBMREMyX1coaW50IGluZGV4KSB7Ci0gICAgc3VwZXIoY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkxEQzJfVywgaW5kZXgpOwotICB9Ci0KLSAgcHVibGljIFR5cGUgZ2V0VHlwZShDb25zdGFudFBvb2xHZW4gY3BnKSB7Ci0gICAgc3dpdGNoKGNwZy5nZXRDb25zdGFudFBvb2woKS5nZXRDb25zdGFudChpbmRleCkuZ2V0VGFnKCkpIHsKLSAgICBjYXNlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5DT05TVEFOVF9Mb25nOiAgIHJldHVybiBUeXBlLkxPTkc7Ci0gICAgY2FzZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuQ09OU1RBTlRfRG91YmxlOiByZXR1cm4gVHlwZS5ET1VCTEU7Ci0gICAgZGVmYXVsdDogLy8gTmV2ZXIgcmVhY2hlZAotICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlVua25vd24gY29uc3RhbnQgdHlwZSAiICsgb3Bjb2RlKTsKLSAgICB9Ci0gIH0KLQotICBwdWJsaWMgTnVtYmVyIGdldFZhbHVlKENvbnN0YW50UG9vbEdlbiBjcGcpIHsKLSAgICBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5jbGFzc2ZpbGUuQ29uc3RhbnQgYyA9IGNwZy5nZXRDb25zdGFudFBvb2woKS5nZXRDb25zdGFudChpbmRleCk7Ci0KLSAgICBzd2l0Y2goYy5nZXRUYWcoKSkgewotICAgIGNhc2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkNPTlNUQU5UX0xvbmc6Ci0gICAgICAgIHJldHVybiBuZXcgTG9uZygoKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmNsYXNzZmlsZS5Db25zdGFudExvbmcpYykuZ2V0Qnl0ZXMoKSk7Ci0KLSAgICBjYXNlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5DT05TVEFOVF9Eb3VibGU6Ci0gICAgICAgIHJldHVybiBuZXcgRG91YmxlKCgoY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuY2xhc3NmaWxlLkNvbnN0YW50RG91YmxlKWMpLmdldEJ5dGVzKCkpOwotCi0gICAgZGVmYXVsdDogLy8gTmV2ZXIgcmVhY2hlZAotICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlVua25vd24gb3IgaW52YWxpZCBjb25zdGFudCB0eXBlIGF0ICIgKyBpbmRleCk7Ci0gICAgICB9Ci0gIH0KLQotICAvKioKLSAgICogQ2FsbCBjb3JyZXNwb25kaW5nIHZpc2l0b3IgbWV0aG9kKHMpLiBUaGUgb3JkZXIgaXM6Ci0gICAqIENhbGwgdmlzaXRvciBtZXRob2RzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMgZmlyc3QsIHRoZW4KLSAgICogY2FsbCBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY2xhc3MgaGllcmFyY2h5IGluIGRlc2NlbmRpbmcgb3JkZXIsCi0gICAqIGkuZS4sIHRoZSBtb3N0IHNwZWNpZmljIHZpc2l0WFhYKCkgY2FsbCBjb21lcyBsYXN0LgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRTdGFja1Byb2R1Y2VyKHRoaXMpOwotICAgIHYudmlzaXRQdXNoSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdFR5cGVkSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdENQSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdExEQzJfVyh0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvTERDX1cuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0xEQ19XLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDY0MDU1NGUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvTERDX1cuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDkxICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC51dGlsLkJ5dGVTZXF1ZW5jZTsKLQotLyoqCi0gKiBMRENfVyAtIFB1c2ggaXRlbSBmcm9tIGNvbnN0YW50IHBvb2wgKHdpZGUgaW5kZXgpCi0gKgotICogPFBSRT5TdGFjazogLi4uIC0mZ3Q7IC4uLiwgaXRlbS53b3JkMSwgaXRlbS53b3JkMjwvUFJFPgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBMRENfVyBleHRlbmRzIExEQyB7Ci0gIC8qKgotICAgKiBFbXB0eSBjb25zdHJ1Y3RvciBuZWVkZWQgZm9yIHRoZSBDbGFzcy5uZXdJbnN0YW5jZSgpIHN0YXRlbWVudCBpbgotICAgKiBJbnN0cnVjdGlvbi5yZWFkSW5zdHJ1Y3Rpb24oKS4gTm90IHRvIGJlIHVzZWQgb3RoZXJ3aXNlLgotICAgKi8KLSAgTERDX1coKSB7fQotCi0gIHB1YmxpYyBMRENfVyhpbnQgaW5kZXgpIHsKLSAgICBzdXBlcihpbmRleCk7Ci0gIH0KLQotICAvKioKLSAgICogUmVhZCBuZWVkZWQgZGF0YSAoaS5lLiwgaW5kZXgpIGZyb20gZmlsZS4KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIGluaXRGcm9tRmlsZShCeXRlU2VxdWVuY2UgYnl0ZXMsIGJvb2xlYW4gd2lkZSkKLSAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24KLSAgewotICAgIHNldEluZGV4KGJ5dGVzLnJlYWRVbnNpZ25lZFNob3J0KCkpOwotICAgIC8vIE92ZXJyaWRlIGp1c3QgaW4gY2FzZSBpdCBoYXMgYmVlbiBjaGFuZ2VkCi0gICAgb3Bjb2RlID0gY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkxEQ19XOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9MRElWLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9MRElWLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDc1NDY5NmUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvTERJVi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTQgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotLyoqCi0gKiBMRElWIC0gRGl2aWRlIGxvbmdzCi0gKiA8UFJFPlN0YWNrOiAuLi4sIHZhbHVlMS53b3JkMSwgdmFsdWUxLndvcmQyLCB2YWx1ZTIud29yZDEsIHZhbHVlMi53b3JkMiAtJmd0OzwvUFJFPgotICogICAgICAgIC4uLiwgcmVzdWx0LndvcmQxLCByZXN1bHQud29yZDIKLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgTERJViBleHRlbmRzIEFyaXRobWV0aWNJbnN0cnVjdGlvbiBpbXBsZW1lbnRzIEV4Y2VwdGlvblRocm93ZXIgIHsKLSAgcHVibGljIExESVYoKSB7Ci0gICAgc3VwZXIoY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkxESVYpOwotICB9Ci0KLSAgcHVibGljIENsYXNzW10gZ2V0RXhjZXB0aW9ucygpIHsKLSAgICByZXR1cm4gbmV3IENsYXNzW10geyBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5FeGNlcHRpb25Db25zdGFudHMuQVJJVEhNRVRJQ19FWENFUFRJT04gfTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIENhbGwgY29ycmVzcG9uZGluZyB2aXNpdG9yIG1ldGhvZChzKS4gVGhlIG9yZGVyIGlzOgotICAgKiBDYWxsIHZpc2l0b3IgbWV0aG9kcyBvZiBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzIGZpcnN0LCB0aGVuCi0gICAqIGNhbGwgbWV0aG9kcyBhY2NvcmRpbmcgdG8gdGhlIGNsYXNzIGhpZXJhcmNoeSBpbiBkZXNjZW5kaW5nIG9yZGVyLAotICAgKiBpLmUuLCB0aGUgbW9zdCBzcGVjaWZpYyB2aXNpdFhYWCgpIGNhbGwgY29tZXMgbGFzdC4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0RXhjZXB0aW9uVGhyb3dlcih0aGlzKTsKLSAgICB2LnZpc2l0VHlwZWRJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tQcm9kdWNlcih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tDb25zdW1lcih0aGlzKTsKLSAgICB2LnZpc2l0QXJpdGhtZXRpY0luc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRMRElWKHRoaXMpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9MTE9BRC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvTExPQUQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMTI3NmQzNy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9MTE9BRC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTIgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotLyoqCi0gKiBMTE9BRCAtIExvYWQgbG9uZyBmcm9tIGxvY2FsIHZhcmlhYmxlCi0gKjxQUkU+U3RhY2sgLi4uIC0mR1Q7IC4uLiwgcmVzdWx0LndvcmQxLCByZXN1bHQud29yZDI8L1BSRT4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgTExPQUQgZXh0ZW5kcyBMb2FkSW5zdHJ1Y3Rpb24gewotICAvKioKLSAgICogRW1wdHkgY29uc3RydWN0b3IgbmVlZGVkIGZvciB0aGUgQ2xhc3MubmV3SW5zdGFuY2UoKSBzdGF0ZW1lbnQgaW4KLSAgICogSW5zdHJ1Y3Rpb24ucmVhZEluc3RydWN0aW9uKCkuIE5vdCB0byBiZSB1c2VkIG90aGVyd2lzZS4KLSAgICovCi0gIExMT0FEKCkgewotICAgIHN1cGVyKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5MTE9BRCwgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkxMT0FEXzApOwotICB9Ci0KLSAgcHVibGljIExMT0FEKGludCBuKSB7Ci0gICAgc3VwZXIoY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkxMT0FELCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuTExPQURfMCwgbik7Ci0gIH0KLQotICAvKioKLSAgICogQ2FsbCBjb3JyZXNwb25kaW5nIHZpc2l0b3IgbWV0aG9kKHMpLiBUaGUgb3JkZXIgaXM6Ci0gICAqIENhbGwgdmlzaXRvciBtZXRob2RzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMgZmlyc3QsIHRoZW4KLSAgICogY2FsbCBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY2xhc3MgaGllcmFyY2h5IGluIGRlc2NlbmRpbmcgb3JkZXIsCi0gICAqIGkuZS4sIHRoZSBtb3N0IHNwZWNpZmljIHZpc2l0WFhYKCkgY2FsbCBjb21lcyBsYXN0LgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHN1cGVyLmFjY2VwdCh2KTsKLSAgICB2LnZpc2l0TExPQUQodGhpcyk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0xNVUwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0xNVUwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMTZjYjA4My4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9MTVVMLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4OSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIExNVUwgLSBNdWx0aXBseSBsb25ncwotICogPFBSRT5TdGFjazogLi4uLCB2YWx1ZTEud29yZDEsIHZhbHVlMS53b3JkMiwgdmFsdWUyLndvcmQxLCB2YWx1ZTIud29yZDIgLSZndDs8L1BSRT4KLSAqICAgICAgICAuLi4sIHJlc3VsdC53b3JkMSwgcmVzdWx0LndvcmQyCi0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGNsYXNzIExNVUwgZXh0ZW5kcyBBcml0aG1ldGljSW5zdHJ1Y3Rpb24gewotICBwdWJsaWMgTE1VTCgpIHsKLSAgICBzdXBlcihjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuTE1VTCk7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBDYWxsIGNvcnJlc3BvbmRpbmcgdmlzaXRvciBtZXRob2QocykuIFRoZSBvcmRlciBpczoKLSAgICogQ2FsbCB2aXNpdG9yIG1ldGhvZHMgb2YgaW1wbGVtZW50ZWQgaW50ZXJmYWNlcyBmaXJzdCwgdGhlbgotICAgKiBjYWxsIG1ldGhvZHMgYWNjb3JkaW5nIHRvIHRoZSBjbGFzcyBoaWVyYXJjaHkgaW4gZGVzY2VuZGluZyBvcmRlciwKLSAgICogaS5lLiwgdGhlIG1vc3Qgc3BlY2lmaWMgdmlzaXRYWFgoKSBjYWxsIGNvbWVzIGxhc3QuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgdi52aXNpdFR5cGVkSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdFN0YWNrUHJvZHVjZXIodGhpcyk7Ci0gICAgdi52aXNpdFN0YWNrQ29uc3VtZXIodGhpcyk7Ci0gICAgdi52aXNpdEFyaXRobWV0aWNJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0TE1VTCh0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvTE5FRy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvTE5FRy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2MWRmMWJiLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0xORUcuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDg4ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8qKgotICogTE5FRyAtIE5lZ2F0ZSBsb25nCi0gKiA8UFJFPlN0YWNrOiAuLi4sIHZhbHVlLndvcmQxLCB2YWx1ZS53b3JkMiAtJmd0OyAuLi4sIHJlc3VsdC53b3JkMSwgcmVzdWx0LndvcmQyPC9QUkU+Ci0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGNsYXNzIExORUcgZXh0ZW5kcyBBcml0aG1ldGljSW5zdHJ1Y3Rpb24gewotICBwdWJsaWMgTE5FRygpIHsKLSAgICBzdXBlcihjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuTE5FRyk7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBDYWxsIGNvcnJlc3BvbmRpbmcgdmlzaXRvciBtZXRob2QocykuIFRoZSBvcmRlciBpczoKLSAgICogQ2FsbCB2aXNpdG9yIG1ldGhvZHMgb2YgaW1wbGVtZW50ZWQgaW50ZXJmYWNlcyBmaXJzdCwgdGhlbgotICAgKiBjYWxsIG1ldGhvZHMgYWNjb3JkaW5nIHRvIHRoZSBjbGFzcyBoaWVyYXJjaHkgaW4gZGVzY2VuZGluZyBvcmRlciwKLSAgICogaS5lLiwgdGhlIG1vc3Qgc3BlY2lmaWMgdmlzaXRYWFgoKSBjYWxsIGNvbWVzIGxhc3QuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgdi52aXNpdFR5cGVkSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdFN0YWNrUHJvZHVjZXIodGhpcyk7Ci0gICAgdi52aXNpdFN0YWNrQ29uc3VtZXIodGhpcyk7Ci0gICAgdi52aXNpdEFyaXRobWV0aWNJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0TE5FRyh0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvTE9PS1VQU1dJVENILmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9MT09LVVBTV0lUQ0guamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMTkxODg4NC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9MT09LVVBTV0lUQ0guamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEzNiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotaW1wb3J0IGphdmEuaW8uKjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC51dGlsLkJ5dGVTZXF1ZW5jZTsKLQotLyoqCi0gKiBMT09LVVBTV0lUQ0ggLSBTd2l0Y2ggd2l0aCB1bm9yZGVyZWQgc2V0IG9mIHZhbHVlcwotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKiBAc2VlIFNXSVRDSAotICovCi1wdWJsaWMgY2xhc3MgTE9PS1VQU1dJVENIIGV4dGVuZHMgU2VsZWN0IHsKLSAgLyoqCi0gICAqIEVtcHR5IGNvbnN0cnVjdG9yIG5lZWRlZCBmb3IgdGhlIENsYXNzLm5ld0luc3RhbmNlKCkgc3RhdGVtZW50IGluCi0gICAqIEluc3RydWN0aW9uLnJlYWRJbnN0cnVjdGlvbigpLiBOb3QgdG8gYmUgdXNlZCBvdGhlcndpc2UuCi0gICAqLwotICBMT09LVVBTV0lUQ0goKSB7fQotCi0gIHB1YmxpYyBMT09LVVBTV0lUQ0goaW50W10gbWF0Y2gsIEluc3RydWN0aW9uSGFuZGxlW10gdGFyZ2V0cywKLSAgICAgICAgICAgICAgICAgICAgICBJbnN0cnVjdGlvbkhhbmRsZSB0YXJnZXQpIHsKLSAgICBzdXBlcihjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuTE9PS1VQU1dJVENILCBtYXRjaCwgdGFyZ2V0cywgdGFyZ2V0KTsKLQotICAgIGxlbmd0aCA9IChzaG9ydCkoOSArIG1hdGNoX2xlbmd0aCAqIDgpOyAvKiBhbGlnbm1lbnQgcmVtYWluZGVyIGFzc3VtZWQKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogMCBoZXJlLCB1bnRpbCBkdW1wIHRpbWUuICovCi0gICAgZml4ZWRfbGVuZ3RoID0gbGVuZ3RoOwotICB9Ci0KLSAgLyoqCi0gICAqIER1bXAgaW5zdHJ1Y3Rpb24gYXMgYnl0ZSBjb2RlIHRvIHN0cmVhbSBvdXQuCi0gICAqIEBwYXJhbSBvdXQgT3V0cHV0IHN0cmVhbQotICAgKi8KLSAgcHVibGljIHZvaWQgZHVtcChEYXRhT3V0cHV0U3RyZWFtIG91dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLSAgICBzdXBlci5kdW1wKG91dCk7Ci0gICAgb3V0LndyaXRlSW50KG1hdGNoX2xlbmd0aCk7ICAgICAgIC8vIG5wYWlycwotCi0gICAgZm9yKGludCBpPTA7IGkgPCBtYXRjaF9sZW5ndGg7IGkrKykgewotICAgICAgb3V0LndyaXRlSW50KG1hdGNoW2ldKTsgICAgICAgICAvLyBtYXRjaC1vZmZzZXQgcGFpcnMKLSAgICAgIG91dC53cml0ZUludChpbmRpY2VzW2ldID0gZ2V0VGFyZ2V0T2Zmc2V0KHRhcmdldHNbaV0pKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogUmVhZCBuZWVkZWQgZGF0YSAoZS5nLiBpbmRleCkgZnJvbSBmaWxlLgotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgaW5pdEZyb21GaWxlKEJ5dGVTZXF1ZW5jZSBieXRlcywgYm9vbGVhbiB3aWRlKSB0aHJvd3MgSU9FeGNlcHRpb24KLSAgewotICAgIHN1cGVyLmluaXRGcm9tRmlsZShieXRlcywgd2lkZSk7IC8vIHJlYWRzIHBhZGRpbmcKLQotICAgIG1hdGNoX2xlbmd0aCA9IGJ5dGVzLnJlYWRJbnQoKTsKLSAgICBmaXhlZF9sZW5ndGggPSAoc2hvcnQpKDkgKyBtYXRjaF9sZW5ndGggKiA4KTsKLSAgICBsZW5ndGggICAgICAgPSAoc2hvcnQpKGZpeGVkX2xlbmd0aCArIHBhZGRpbmcpOwotCi0gICAgbWF0Y2ggICA9IG5ldyBpbnRbbWF0Y2hfbGVuZ3RoXTsKLSAgICBpbmRpY2VzID0gbmV3IGludFttYXRjaF9sZW5ndGhdOwotICAgIHRhcmdldHMgPSBuZXcgSW5zdHJ1Y3Rpb25IYW5kbGVbbWF0Y2hfbGVuZ3RoXTsKLQotICAgIGZvcihpbnQgaT0wOyBpIDwgbWF0Y2hfbGVuZ3RoOyBpKyspIHsKLSAgICAgIG1hdGNoW2ldICAgPSBieXRlcy5yZWFkSW50KCk7Ci0gICAgICBpbmRpY2VzW2ldID0gYnl0ZXMucmVhZEludCgpOwotICAgIH0KLSAgfQotCi0KLSAgLyoqCi0gICAqIENhbGwgY29ycmVzcG9uZGluZyB2aXNpdG9yIG1ldGhvZChzKS4gVGhlIG9yZGVyIGlzOgotICAgKiBDYWxsIHZpc2l0b3IgbWV0aG9kcyBvZiBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzIGZpcnN0LCB0aGVuCi0gICAqIGNhbGwgbWV0aG9kcyBhY2NvcmRpbmcgdG8gdGhlIGNsYXNzIGhpZXJhcmNoeSBpbiBkZXNjZW5kaW5nIG9yZGVyLAotICAgKiBpLmUuLCB0aGUgbW9zdCBzcGVjaWZpYyB2aXNpdFhYWCgpIGNhbGwgY29tZXMgbGFzdC4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0VmFyaWFibGVMZW5ndGhJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tQcm9kdWNlcih0aGlzKTsKLSAgICB2LnZpc2l0QnJhbmNoSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdFNlbGVjdCh0aGlzKTsKLSAgICB2LnZpc2l0TE9PS1VQU1dJVENIKHRoaXMpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9MT1IuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0xPUi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiYWY3OTMzLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0xPUi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsODggKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotLyoqCi0gKiBMT1IgLSBCaXR3aXNlIE9SIGxvbmcKLSAqIDxQUkU+U3RhY2s6IC4uLiwgdmFsdWUxLCB2YWx1ZTIgLSZndDsgLi4uLCByZXN1bHQ8L1BSRT4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgTE9SIGV4dGVuZHMgQXJpdGhtZXRpY0luc3RydWN0aW9uIHsKLSAgcHVibGljIExPUigpIHsKLSAgICBzdXBlcihjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuTE9SKTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIENhbGwgY29ycmVzcG9uZGluZyB2aXNpdG9yIG1ldGhvZChzKS4gVGhlIG9yZGVyIGlzOgotICAgKiBDYWxsIHZpc2l0b3IgbWV0aG9kcyBvZiBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzIGZpcnN0LCB0aGVuCi0gICAqIGNhbGwgbWV0aG9kcyBhY2NvcmRpbmcgdG8gdGhlIGNsYXNzIGhpZXJhcmNoeSBpbiBkZXNjZW5kaW5nIG9yZGVyLAotICAgKiBpLmUuLCB0aGUgbW9zdCBzcGVjaWZpYyB2aXNpdFhYWCgpIGNhbGwgY29tZXMgbGFzdC4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0VHlwZWRJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tQcm9kdWNlcih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tDb25zdW1lcih0aGlzKTsKLSAgICB2LnZpc2l0QXJpdGhtZXRpY0luc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRMT1IodGhpcyk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0xSRU0uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0xSRU0uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMjkzNjg0YS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9MUkVNLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5MSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIExSRU0gLSBSZW1haW5kZXIgb2YgbG9uZwotICogPFBSRT5TdGFjazogLi4uLCB2YWx1ZTEsIHZhbHVlMiAtJmd0OyByZXN1bHQ8L1BSRT4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgTFJFTSBleHRlbmRzIEFyaXRobWV0aWNJbnN0cnVjdGlvbiBpbXBsZW1lbnRzIEV4Y2VwdGlvblRocm93ZXIgewotICBwdWJsaWMgTFJFTSgpIHsKLSAgICBzdXBlcihjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuTFJFTSk7Ci0gIH0KLQotICBwdWJsaWMgQ2xhc3NbXSBnZXRFeGNlcHRpb25zKCkgeyByZXR1cm4gbmV3IENsYXNzW10geyBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5FeGNlcHRpb25Db25zdGFudHMuQVJJVEhNRVRJQ19FWENFUFRJT04gfTsgfQotCi0KLSAgLyoqCi0gICAqIENhbGwgY29ycmVzcG9uZGluZyB2aXNpdG9yIG1ldGhvZChzKS4gVGhlIG9yZGVyIGlzOgotICAgKiBDYWxsIHZpc2l0b3IgbWV0aG9kcyBvZiBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzIGZpcnN0LCB0aGVuCi0gICAqIGNhbGwgbWV0aG9kcyBhY2NvcmRpbmcgdG8gdGhlIGNsYXNzIGhpZXJhcmNoeSBpbiBkZXNjZW5kaW5nIG9yZGVyLAotICAgKiBpLmUuLCB0aGUgbW9zdCBzcGVjaWZpYyB2aXNpdFhYWCgpIGNhbGwgY29tZXMgbGFzdC4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0RXhjZXB0aW9uVGhyb3dlcih0aGlzKTsKLSAgICB2LnZpc2l0VHlwZWRJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tQcm9kdWNlcih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tDb25zdW1lcih0aGlzKTsKLSAgICB2LnZpc2l0QXJpdGhtZXRpY0luc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRMUkVNKHRoaXMpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9MUkVUVVJOLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9MUkVUVVJOLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDQ4MGJhMDEuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvTFJFVFVSTi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsODggKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotLyoqCi0gKiBMUkVUVVJOIC0gIFJldHVybiBsb25nIGZyb20gbWV0aG9kCi0gKiA8UFJFPlN0YWNrOiAuLi4sIHZhbHVlLndvcmQxLCB2YWx1ZS53b3JkMiAtJmd0OyAmbHQ7ZW1wdHkmZ3Q7PC9QUkU+Ci0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGNsYXNzIExSRVRVUk4gZXh0ZW5kcyBSZXR1cm5JbnN0cnVjdGlvbiB7Ci0gIHB1YmxpYyBMUkVUVVJOKCkgewotICAgIHN1cGVyKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5MUkVUVVJOKTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIENhbGwgY29ycmVzcG9uZGluZyB2aXNpdG9yIG1ldGhvZChzKS4gVGhlIG9yZGVyIGlzOgotICAgKiBDYWxsIHZpc2l0b3IgbWV0aG9kcyBvZiBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzIGZpcnN0LCB0aGVuCi0gICAqIGNhbGwgbWV0aG9kcyBhY2NvcmRpbmcgdG8gdGhlIGNsYXNzIGhpZXJhcmNoeSBpbiBkZXNjZW5kaW5nIG9yZGVyLAotICAgKiBpLmUuLCB0aGUgbW9zdCBzcGVjaWZpYyB2aXNpdFhYWCgpIGNhbGwgY29tZXMgbGFzdC4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0RXhjZXB0aW9uVGhyb3dlcih0aGlzKTsKLSAgICB2LnZpc2l0VHlwZWRJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tDb25zdW1lcih0aGlzKTsKLSAgICB2LnZpc2l0UmV0dXJuSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdExSRVRVUk4odGhpcyk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0xTSEwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0xTSEwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNzgwZWY3YS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9MU0hMLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4OCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIExTSEwgLSBBcml0aG1ldGljIHNoaWZ0IGxlZnQgbG9uZwotICogPFBSRT5TdGFjazogLi4uLCB2YWx1ZTEud29yZDEsIHZhbHVlMS53b3JkMiwgdmFsdWUyIC0mZ3Q7IC4uLiwgcmVzdWx0LndvcmQxLCByZXN1bHQud29yZDI8L1BSRT4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgTFNITCBleHRlbmRzIEFyaXRobWV0aWNJbnN0cnVjdGlvbiB7Ci0gIHB1YmxpYyBMU0hMKCkgewotICAgIHN1cGVyKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5MU0hMKTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIENhbGwgY29ycmVzcG9uZGluZyB2aXNpdG9yIG1ldGhvZChzKS4gVGhlIG9yZGVyIGlzOgotICAgKiBDYWxsIHZpc2l0b3IgbWV0aG9kcyBvZiBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzIGZpcnN0LCB0aGVuCi0gICAqIGNhbGwgbWV0aG9kcyBhY2NvcmRpbmcgdG8gdGhlIGNsYXNzIGhpZXJhcmNoeSBpbiBkZXNjZW5kaW5nIG9yZGVyLAotICAgKiBpLmUuLCB0aGUgbW9zdCBzcGVjaWZpYyB2aXNpdFhYWCgpIGNhbGwgY29tZXMgbGFzdC4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0VHlwZWRJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tQcm9kdWNlcih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tDb25zdW1lcih0aGlzKTsKLSAgICB2LnZpc2l0QXJpdGhtZXRpY0luc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRMU0hMKHRoaXMpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9MU0hSLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9MU0hSLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGI0OTkzYjUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvTFNIUi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsODggKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotLyoqCi0gKiBMU0hSIC0gQXJpdGhtZXRpYyBzaGlmdCByaWdodCBsb25nCi0gKiA8UFJFPlN0YWNrOiAuLi4sIHZhbHVlMS53b3JkMSwgdmFsdWUxLndvcmQyLCB2YWx1ZTIgLSZndDsgLi4uLCByZXN1bHQud29yZDEsIHJlc3VsdC53b3JkMjwvUFJFPgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBMU0hSIGV4dGVuZHMgQXJpdGhtZXRpY0luc3RydWN0aW9uIHsKLSAgcHVibGljIExTSFIoKSB7Ci0gICAgc3VwZXIoY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkxTSFIpOwotICB9Ci0KLQotICAvKioKLSAgICogQ2FsbCBjb3JyZXNwb25kaW5nIHZpc2l0b3IgbWV0aG9kKHMpLiBUaGUgb3JkZXIgaXM6Ci0gICAqIENhbGwgdmlzaXRvciBtZXRob2RzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMgZmlyc3QsIHRoZW4KLSAgICogY2FsbCBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY2xhc3MgaGllcmFyY2h5IGluIGRlc2NlbmRpbmcgb3JkZXIsCi0gICAqIGkuZS4sIHRoZSBtb3N0IHNwZWNpZmljIHZpc2l0WFhYKCkgY2FsbCBjb21lcyBsYXN0LgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRUeXBlZEluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRTdGFja1Byb2R1Y2VyKHRoaXMpOwotICAgIHYudmlzaXRTdGFja0NvbnN1bWVyKHRoaXMpOwotICAgIHYudmlzaXRBcml0aG1ldGljSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdExTSFIodGhpcyk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0xTVE9SRS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvTFNUT1JFLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDQxZDM0ODEuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvTFNUT1JFLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5MiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIExTVE9SRSAtIFN0b3JlIGxvbmcgaW50byBsb2NhbCB2YXJpYWJsZQotICogPFBSRT5TdGFjazogLi4uLCB2YWx1ZS53b3JkMSwgdmFsdWUud29yZDIgLSZndDsgLi4uIDwvUFJFPgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBMU1RPUkUgZXh0ZW5kcyBTdG9yZUluc3RydWN0aW9uIHsKLSAgLyoqCi0gICAqIEVtcHR5IGNvbnN0cnVjdG9yIG5lZWRlZCBmb3IgdGhlIENsYXNzLm5ld0luc3RhbmNlKCkgc3RhdGVtZW50IGluCi0gICAqIEluc3RydWN0aW9uLnJlYWRJbnN0cnVjdGlvbigpLiBOb3QgdG8gYmUgdXNlZCBvdGhlcndpc2UuCi0gICAqLwotICBMU1RPUkUoKSB7Ci0gICAgc3VwZXIoY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkxTVE9SRSwgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkxTVE9SRV8wKTsKLSAgfQotCi0gIHB1YmxpYyBMU1RPUkUoaW50IG4pIHsKLSAgICBzdXBlcihjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuTFNUT1JFLCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuTFNUT1JFXzAsIG4pOwotICB9Ci0KLSAgLyoqCi0gICAqIENhbGwgY29ycmVzcG9uZGluZyB2aXNpdG9yIG1ldGhvZChzKS4gVGhlIG9yZGVyIGlzOgotICAgKiBDYWxsIHZpc2l0b3IgbWV0aG9kcyBvZiBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzIGZpcnN0LCB0aGVuCi0gICAqIGNhbGwgbWV0aG9kcyBhY2NvcmRpbmcgdG8gdGhlIGNsYXNzIGhpZXJhcmNoeSBpbiBkZXNjZW5kaW5nIG9yZGVyLAotICAgKiBpLmUuLCB0aGUgbW9zdCBzcGVjaWZpYyB2aXNpdFhYWCgpIGNhbGwgY29tZXMgbGFzdC4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICBzdXBlci5hY2NlcHQodik7Ci0gICAgdi52aXNpdExTVE9SRSh0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvTFNVQi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvTFNVQi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzOGVhNjdkLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0xTVUIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDg5ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8qKgotICogTFNVQiAtIFN1YnN0cmFjdCBsb25ncwotICogPFBSRT5TdGFjazogLi4uLCB2YWx1ZTEud29yZDEsIHZhbHVlMS53b3JkMiwgdmFsdWUyLndvcmQxLCB2YWx1ZTIud29yZDIgLSZndDs8L1BSRT4KLSAqICAgICAgICAuLi4sIHJlc3VsdC53b3JkMSwgcmVzdWx0LndvcmQyCi0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGNsYXNzIExTVUIgZXh0ZW5kcyBBcml0aG1ldGljSW5zdHJ1Y3Rpb24gewotICBwdWJsaWMgTFNVQigpIHsKLSAgICBzdXBlcihjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuTFNVQik7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBDYWxsIGNvcnJlc3BvbmRpbmcgdmlzaXRvciBtZXRob2QocykuIFRoZSBvcmRlciBpczoKLSAgICogQ2FsbCB2aXNpdG9yIG1ldGhvZHMgb2YgaW1wbGVtZW50ZWQgaW50ZXJmYWNlcyBmaXJzdCwgdGhlbgotICAgKiBjYWxsIG1ldGhvZHMgYWNjb3JkaW5nIHRvIHRoZSBjbGFzcyBoaWVyYXJjaHkgaW4gZGVzY2VuZGluZyBvcmRlciwKLSAgICogaS5lLiwgdGhlIG1vc3Qgc3BlY2lmaWMgdmlzaXRYWFgoKSBjYWxsIGNvbWVzIGxhc3QuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgdi52aXNpdFR5cGVkSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdFN0YWNrUHJvZHVjZXIodGhpcyk7Ci0gICAgdi52aXNpdFN0YWNrQ29uc3VtZXIodGhpcyk7Ci0gICAgdi52aXNpdEFyaXRobWV0aWNJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0TFNVQih0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvTFVTSFIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0xVU0hSLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDZkODljMjcuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvTFVTSFIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDg4ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8qKgotICogTFVTSFIgLSBMb2dpY2FsIHNoaWZ0IHJpZ2h0IGxvbmcKLSAqIDxQUkU+U3RhY2s6IC4uLiwgdmFsdWUxLCB2YWx1ZTIgLSZndDsgLi4uLCByZXN1bHQ8L1BSRT4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgTFVTSFIgZXh0ZW5kcyBBcml0aG1ldGljSW5zdHJ1Y3Rpb24gewotICBwdWJsaWMgTFVTSFIoKSB7Ci0gICAgc3VwZXIoY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkxVU0hSKTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIENhbGwgY29ycmVzcG9uZGluZyB2aXNpdG9yIG1ldGhvZChzKS4gVGhlIG9yZGVyIGlzOgotICAgKiBDYWxsIHZpc2l0b3IgbWV0aG9kcyBvZiBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzIGZpcnN0LCB0aGVuCi0gICAqIGNhbGwgbWV0aG9kcyBhY2NvcmRpbmcgdG8gdGhlIGNsYXNzIGhpZXJhcmNoeSBpbiBkZXNjZW5kaW5nIG9yZGVyLAotICAgKiBpLmUuLCB0aGUgbW9zdCBzcGVjaWZpYyB2aXNpdFhYWCgpIGNhbGwgY29tZXMgbGFzdC4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0VHlwZWRJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tQcm9kdWNlcih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tDb25zdW1lcih0aGlzKTsKLSAgICB2LnZpc2l0QXJpdGhtZXRpY0luc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRMVVNIUih0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvTFhPUi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvTFhPUi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2ZWJkNWRhLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0xYT1IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDg4ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8qKgotICogTFhPUiAtIEJpdHdpc2UgWE9SIGxvbmcKLSAqIDxQUkU+U3RhY2s6IC4uLiwgdmFsdWUxLCB2YWx1ZTIgLSZndDsgLi4uLCByZXN1bHQ8L1BSRT4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgTFhPUiBleHRlbmRzIEFyaXRobWV0aWNJbnN0cnVjdGlvbiB7Ci0gIHB1YmxpYyBMWE9SKCkgewotICAgIHN1cGVyKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5MWE9SKTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIENhbGwgY29ycmVzcG9uZGluZyB2aXNpdG9yIG1ldGhvZChzKS4gVGhlIG9yZGVyIGlzOgotICAgKiBDYWxsIHZpc2l0b3IgbWV0aG9kcyBvZiBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzIGZpcnN0LCB0aGVuCi0gICAqIGNhbGwgbWV0aG9kcyBhY2NvcmRpbmcgdG8gdGhlIGNsYXNzIGhpZXJhcmNoeSBpbiBkZXNjZW5kaW5nIG9yZGVyLAotICAgKiBpLmUuLCB0aGUgbW9zdCBzcGVjaWZpYyB2aXNpdFhYWCgpIGNhbGwgY29tZXMgbGFzdC4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0VHlwZWRJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tQcm9kdWNlcih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tDb25zdW1lcih0aGlzKTsKLSAgICB2LnZpc2l0QXJpdGhtZXRpY0luc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRMWE9SKHRoaXMpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9MaW5lTnVtYmVyR2VuLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9MaW5lTnVtYmVyR2VuLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGE4NDI3YTguLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvTGluZU51bWJlckdlbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTM2ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5jbGFzc2ZpbGUuKjsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIHJlcHJlc2VudHMgYSBsaW5lIG51bWJlciB3aXRoaW4gYSBtZXRob2QsIGkuZS4sIGdpdmUgYW4gaW5zdHJ1Y3Rpb24KLSAqIGEgbGluZSBudW1iZXIgY29ycmVzcG9uZGluZyB0byB0aGUgc291cmNlIGNvZGUgbGluZS4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICogQHNlZSAgICAgTGluZU51bWJlcgotICogQHNlZSAgICAgTWV0aG9kR2VuCi0gKi8KLXB1YmxpYyBjbGFzcyBMaW5lTnVtYmVyR2VuCi0gIGltcGxlbWVudHMgSW5zdHJ1Y3Rpb25UYXJnZXRlciwgQ2xvbmVhYmxlLCBqYXZhLmlvLlNlcmlhbGl6YWJsZQotewotICBwcml2YXRlIEluc3RydWN0aW9uSGFuZGxlIGloOwotICBwcml2YXRlIGludCAgICAgICAgICAgICAgIHNyY19saW5lOwotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBsaW5lIG51bWJlci4KLSAgICoKLSAgICogQHBhcmFtIGloIGluc3RydWN0aW9uIGhhbmRsZSB0byByZWZlcmVuY2UKLSAgICovCi0gIHB1YmxpYyBMaW5lTnVtYmVyR2VuKEluc3RydWN0aW9uSGFuZGxlIGloLCBpbnQgc3JjX2xpbmUpIHsKLSAgICBzZXRJbnN0cnVjdGlvbihpaCk7Ci0gICAgc2V0U291cmNlTGluZShzcmNfbGluZSk7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiB0cnVlLCBpZiBpaCBpcyB0YXJnZXQgb2YgdGhpcyBsaW5lIG51bWJlcgotICAgKi8KLSAgQE92ZXJyaWRlCi0gIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zVGFyZ2V0KEluc3RydWN0aW9uSGFuZGxlIGloKSB7Ci0gICAgcmV0dXJuIHRoaXMuaWggPT0gaWg7Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIG9sZF9paCBvbGQgdGFyZ2V0Ci0gICAqIEBwYXJhbSBuZXdfaWggbmV3IHRhcmdldAotICAgKi8KLSAgQE92ZXJyaWRlCi0gIHB1YmxpYyB2b2lkIHVwZGF0ZVRhcmdldChJbnN0cnVjdGlvbkhhbmRsZSBvbGRfaWgsIEluc3RydWN0aW9uSGFuZGxlIG5ld19paCkgewotICAgIGlmKG9sZF9paCAhPSBpaCkKLSAgICAgIHRocm93IG5ldyBDbGFzc0dlbkV4Y2VwdGlvbigiTm90IHRhcmdldGluZyAiICsgb2xkX2loICsgIiwgYnV0ICIgKyBpaCArICJ9Iik7Ci0gICAgZWxzZQotICAgICAgc2V0SW5zdHJ1Y3Rpb24obmV3X2loKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgTGluZU51bWJlciBhdHRyaWJ1dGUgLgotICAgKgotICAgKiBUaGlzIHJlbGllcyBvbiB0aGF0IHRoZSBpbnN0cnVjdGlvbiBsaXN0IGhhcyBhbHJlYWR5IGJlZW4gZHVtcGVkIHRvIGJ5dGUgY29kZSBvcgotICAgKiBvciB0aGF0IHRoZSBgc2V0UG9zaXRpb25zJyBtZXRob2RzIGhhcyBiZWVuIGNhbGxlZCBmb3IgdGhlIGluc3RydWN0aW9uIGxpc3QuCi0gICAqLwotICBwdWJsaWMgTGluZU51bWJlciBnZXRMaW5lTnVtYmVyKCkgewotICAgIHJldHVybiBuZXcgTGluZU51bWJlcihpaC5nZXRQb3NpdGlvbigpLCBzcmNfbGluZSk7Ci0gIH0KLQotICBwdWJsaWMgZmluYWwgdm9pZCBzZXRJbnN0cnVjdGlvbihJbnN0cnVjdGlvbkhhbmRsZSBpaCkgewotICAgIEJyYW5jaEluc3RydWN0aW9uLm5vdGlmeVRhcmdldENoYW5naW5nKHRoaXMuaWgsIHRoaXMpOwotICAgIHRoaXMuaWggPSBpaDsKLSAgICBCcmFuY2hJbnN0cnVjdGlvbi5ub3RpZnlUYXJnZXRDaGFuZ2VkKHRoaXMuaWgsIHRoaXMpOwotICB9Ci0KLSAgQE92ZXJyaWRlCi0gIHB1YmxpYyBPYmplY3QgY2xvbmUoKSB7Ci0gICAgdHJ5IHsKLSAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwotICAgIH0gY2F0Y2goQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gZSkgewotICAgICAgU3lzdGVtLmVyci5wcmludGxuKGUpOwotICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotICB9Ci0KLSAgcHVibGljIEluc3RydWN0aW9uSGFuZGxlIGdldEluc3RydWN0aW9uKCkgICAgICAgICAgICAgICB7IHJldHVybiBpaDsgfQotICBwdWJsaWMgdm9pZCAgICAgICAgICAgICAgc2V0U291cmNlTGluZShpbnQgc3JjX2xpbmUpICAgIHsgdGhpcy5zcmNfbGluZSA9IHNyY19saW5lOyB9Ci0gIHB1YmxpYyBpbnQgICAgICAgICAgICAgICBnZXRTb3VyY2VMaW5lKCkgICAgICAgICAgICAgICAgeyByZXR1cm4gc3JjX2xpbmU7IH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0xvYWRDbGFzcy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvTG9hZENsYXNzLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGU0MDE5MDQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvTG9hZENsYXNzLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4OSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIERlbm90ZXMgdGhhdCBhbiBpbnN0cnVjdGlvbiBtYXkgc3RhcnQgdGhlIHByb2Nlc3Mgb2YgbG9hZGluZyBhbmQgcmVzb2x2aW5nCi0gKiB0aGUgcmVmZXJlbmNlZCBjbGFzcyBpbiB0aGUgVmlydHVhbCBNYWNoaW5lLgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgTG9hZENsYXNzIHsKLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIE9iamVjdFR5cGUgb2YgdGhlIHJlZmVyZW5jZWQgY2xhc3Mgb3IgaW50ZXJmYWNlCi0gICAqIHRoYXQgbWF5IGJlIGxvYWRlZCBhbmQgcmVzb2x2ZWQuCi0gICAqIEByZXR1cm4gb2JqZWN0IHR5cGUgdGhhdCBtYXkgYmUgbG9hZGVkIG9yIG51bGwgaWYgYSBwcmltaXRpdmUgaXMKLSAgICogcmVmZXJlbmNlZAotICAgKi8KLSAgcHVibGljIE9iamVjdFR5cGUgZ2V0TG9hZENsYXNzVHlwZShDb25zdGFudFBvb2xHZW4gY3BnKTsKLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgdHlwZSBhc3NvY2lhdGVkIHdpdGggdGhpcyBpbnN0cnVjdGlvbi4KLSAgICogTG9hZENsYXNzIGluc3RhbmNlcyBhcmUgYWx3YXlzIHR5cGVkLCBidXQgdGhpcyB0eXBlCi0gICAqIGRvZXMgbm90IGFsd2F5cyByZWZlciB0byB0aGUgdHlwZSBvZiB0aGUgY2xhc3Mgb3IgaW50ZXJmYWNlCi0gICAqIHRoYXQgaXQgcG9zc2libHkgZm9yY2VzIHRvIGxvYWQuIEZvciBleGFtcGxlLCBHRVRGSUVMRCB3b3VsZAotICAgKiByZXR1cm4gdGhlIHR5cGUgb2YgdGhlIGZpZWxkIGFuZCBub3QgdGhlIHR5cGUgb2YgdGhlIGNsYXNzCi0gICAqIHdoZXJlIHRoZSBmaWVsZCBpcyBkZWZpbmVkLgotICAgKiBJZiBubyBjbGFzcyBpcyBmb3JjZWQgdG8gYmUgbG9hZGVkLCA8Qj5udWxsPC9CPiBpcyByZXR1cm5lZC4KLSAgICogQW4gZXhhbXBsZSBmb3IgdGhpcyBpcyBhbiBBTkVXQVJSQVkgaW5zdHJ1Y3Rpb24gdGhhdCBjcmVhdGVzCi0gICAqIGFuIGludFtdW10uCi0gICAqIEBzZWUgI2dldExvYWRDbGFzc1R5cGUoQ29uc3RhbnRQb29sR2VuKQotICAgKi8KLSAgcHVibGljIFR5cGUgZ2V0VHlwZShDb25zdGFudFBvb2xHZW4gY3BnKTsKLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0xvYWRJbnN0cnVjdGlvbi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvTG9hZEluc3RydWN0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGEzNWUwMjAuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvTG9hZEluc3RydWN0aW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMDMgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotLyoqCi0gKiBEZW5vdGVzIGFuIHVucGFyYW1ldGVyaXplZCBpbnN0cnVjdGlvbiB0byBsb2FkIGEgdmFsdWUgZnJvbSBhIGxvY2FsCi0gKiB2YXJpYWJsZSwgZS5nLiBJTE9BRC4KLSAqCi0gKiBAYXV0aG9yIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBMb2FkSW5zdHJ1Y3Rpb24gZXh0ZW5kcyBMb2NhbFZhcmlhYmxlSW5zdHJ1Y3Rpb24KLSAgaW1wbGVtZW50cyBQdXNoSW5zdHJ1Y3Rpb24KLXsKLSAgLyoqCi0gICAqIEVtcHR5IGNvbnN0cnVjdG9yIG5lZWRlZCBmb3IgdGhlIENsYXNzLm5ld0luc3RhbmNlKCkgc3RhdGVtZW50IGluCi0gICAqIEluc3RydWN0aW9uLnJlYWRJbnN0cnVjdGlvbigpLiBOb3QgdG8gYmUgdXNlZCBvdGhlcndpc2UuCi0gICAqIHRhZyBhbmQgbGVuZ3RoIGFyZSBkZWZpbmVkIGluIHJlYWRJbnN0cnVjdGlvbiBhbmQgaW5pdEZyb21GaWxlLCByZXNwZWN0aXZlbHkuCi0gICAqLwotICBMb2FkSW5zdHJ1Y3Rpb24oc2hvcnQgY2Fub25fdGFnLCBzaG9ydCBjX3RhZykgewotICAgIHN1cGVyKGNhbm9uX3RhZywgY190YWcpOwotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBvcGNvZGUgSW5zdHJ1Y3Rpb24gb3Bjb2RlCi0gICAqIEBwYXJhbSBjX3RhZyBJbnN0cnVjdGlvbiBudW1iZXIgZm9yIGNvbXBhY3QgdmVyc2lvbiwgQUxPQURfMCwgZS5nLgotICAgKiBAcGFyYW0gbiBsb2NhbCB2YXJpYWJsZSBpbmRleCAodW5zaWduZWQgc2hvcnQpCi0gICAqLwotICBwcm90ZWN0ZWQgTG9hZEluc3RydWN0aW9uKHNob3J0IG9wY29kZSwgc2hvcnQgY190YWcsIGludCBuKSB7Ci0gICAgc3VwZXIob3Bjb2RlLCBjX3RhZywgbik7Ci0gIH0KLQotICAvKioKLSAgICogQ2FsbCBjb3JyZXNwb25kaW5nIHZpc2l0b3IgbWV0aG9kKHMpLiBUaGUgb3JkZXIgaXM6Ci0gICAqIENhbGwgdmlzaXRvciBtZXRob2RzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMgZmlyc3QsIHRoZW4KLSAgICogY2FsbCBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY2xhc3MgaGllcmFyY2h5IGluIGRlc2NlbmRpbmcgb3JkZXIsCi0gICAqIGkuZS4sIHRoZSBtb3N0IHNwZWNpZmljIHZpc2l0WFhYKCkgY2FsbCBjb21lcyBsYXN0LgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRTdGFja1Byb2R1Y2VyKHRoaXMpOwotICAgIHYudmlzaXRQdXNoSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdFR5cGVkSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdExvY2FsVmFyaWFibGVJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0TG9hZEluc3RydWN0aW9uKHRoaXMpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9Mb2NhbFZhcmlhYmxlR2VuLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9Mb2NhbFZhcmlhYmxlR2VuLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDFmMmZkODYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvTG9jYWxWYXJpYWJsZUdlbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjkwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuY2xhc3NmaWxlLio7Ci1pbXBvcnQgamF2YS51dGlsLk9iamVjdHM7Ci0KLS8qKgotICogVGhpcyBjbGFzcyByZXByZXNlbnRzIGEgbG9jYWwgdmFyaWFibGUgd2l0aGluIGEgbWV0aG9kLiBJdCBjb250YWlucyBpdHMKLSAqIHNjb3BlLCBuYW1lIGFuZCB0eXBlLiBUaGUgZ2VuZXJhdGVkIExvY2FsVmFyaWFibGUgb2JqZWN0IGNhbiBiZSBvYnRhaW5lZAotICogd2l0aCBnZXRMb2NhbFZhcmlhYmxlIHdoaWNoIG5lZWRzIHRoZSBpbnN0cnVjdGlvbiBsaXN0IGFuZCB0aGUgY29uc3RhbnQKLSAqIHBvb2wgYXMgcGFyYW1ldGVycy4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICogQHNlZSAgICAgTG9jYWxWYXJpYWJsZQotICogQHNlZSAgICAgTWV0aG9kR2VuCi0gKi8KLXB1YmxpYyBjbGFzcyBMb2NhbFZhcmlhYmxlR2VuCi0gIGltcGxlbWVudHMgSW5zdHJ1Y3Rpb25UYXJnZXRlciwgTmFtZWRBbmRUeXBlZCwgQ2xvbmVhYmxlLAotICAgICAgICAgICAgIGphdmEuaW8uU2VyaWFsaXphYmxlCi17Ci0gIHByaXZhdGUgZmluYWwgaW50ICAgaW5kZXg7Ci0gIHByaXZhdGUgU3RyaW5nICAgICAgbmFtZTsKLSAgcHJpdmF0ZSBUeXBlICAgICAgICB0eXBlOwotICBwcml2YXRlIEluc3RydWN0aW9uSGFuZGxlIHN0YXJ0LCBlbmQ7Ci0KLSAgLyoqCi0gICAqIEdlbmVyYXRlIGEgbG9jYWwgdmFyaWFibGUgdGhhdCB3aXRoIGluZGV4IGBpbmRleCcuIE5vdGUgdGhhdCBkb3VibGUgYW5kIGxvbmcKLSAgICogdmFyaWFibGVzIG5lZWQgdHdvIGluZGV4cy4gSW5kZXggaW5kaWNlcyBoYXZlIHRvIGJlIHByb3ZpZGVkIGJ5IHRoZSB1c2VyLgotICAgKgotICAgKiBAcGFyYW0gaW5kZXggaW5kZXggb2YgbG9jYWwgdmFyaWFibGUKLSAgICogQHBhcmFtIG5hbWUgaXRzIG5hbWUKLSAgICogQHBhcmFtIHR5cGUgaXRzIHR5cGUKLSAgICogQHBhcmFtIHN0YXJ0IGZyb20gd2hlcmUgdGhlIGluc3RydWN0aW9uIGlzIHZhbGlkIChudWxsIG1lYW5zIGZyb20gdGhlIHN0YXJ0KQotICAgKiBAcGFyYW0gZW5kIHVudGlsIHdoZXJlIHRoZSBpbnN0cnVjdGlvbiBpcyB2YWxpZCAobnVsbCBtZWFucyB0byB0aGUgZW5kKQotICAgKi8KLSAgcHVibGljIExvY2FsVmFyaWFibGVHZW4oaW50IGluZGV4LCBTdHJpbmcgbmFtZSwgVHlwZSB0eXBlLAotICAgICAgICAgICAgICAgICAgICAgICAgICBJbnN0cnVjdGlvbkhhbmRsZSBzdGFydCwgSW5zdHJ1Y3Rpb25IYW5kbGUgZW5kKSB7Ci0gICAgaWYoKGluZGV4IDwgMCkgfHwgKGluZGV4ID4gQ29uc3RhbnRzLk1BWF9TSE9SVCkpCi0gICAgICB0aHJvdyBuZXcgQ2xhc3NHZW5FeGNlcHRpb24oIkludmFsaWQgaW5kZXggaW5kZXg6ICIgKyBpbmRleCk7Ci0KLSAgICB0aGlzLm5hbWUgID0gbmFtZTsKLSAgICB0aGlzLnR5cGUgID0gdHlwZTsKLSAgICB0aGlzLmluZGV4ICA9IGluZGV4OwotICAgIHNldFN0YXJ0KHN0YXJ0KTsKLSAgICBzZXRFbmQoZW5kKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgTG9jYWxWYXJpYWJsZSBvYmplY3QuCi0gICAqCi0gICAqIFRoaXMgcmVsaWVzIG9uIHRoYXQgdGhlIGluc3RydWN0aW9uIGxpc3QgaGFzIGFscmVhZHkgYmVlbiBkdW1wZWQgdG8gYnl0ZSBjb2RlIG9yCi0gICAqIG9yIHRoYXQgdGhlIGBzZXRQb3NpdGlvbnMnIG1ldGhvZHMgaGFzIGJlZW4gY2FsbGVkIGZvciB0aGUgaW5zdHJ1Y3Rpb24gbGlzdC4KLSAgICoKLSAgICogTm90ZSB0aGF0IGZvciBsb2NhbCB2YXJpYWJsZXMgd2hvc2Ugc2NvcGUgZW5kIGF0IHRoZSBsYXN0Ci0gICAqIGluc3RydWN0aW9uIG9mIHRoZSBtZXRob2QncyBjb2RlLCB0aGUgSlZNIHNwZWNpZmljYXRpb24gaXMgYW1iaWd1b3VzOgotICAgKiBib3RoIGEgc3RhcnRfcGMrbGVuZ3RoIGVuZGluZyBhdCB0aGUgbGFzdCBpbnN0cnVjdGlvbiBhbmQKLSAgICogc3RhcnRfcGMrbGVuZ3RoIGVuZGluZyBhdCBmaXJzdCBpbmRleCBiZXlvbmQgdGhlIGVuZCBvZiB0aGUgY29kZSBhcmUKLSAgICogdmFsaWQuCi0gICAqCi0gICAqIEBwYXJhbSBpbCBpbnN0cnVjdGlvbiBsaXN0IChieXRlIGNvZGUpIHdoaWNoIHRoaXMgdmFyaWFibGUgYmVsb25ncyB0bwotICAgKiBAcGFyYW0gY3AgY29uc3RhbnQgcG9vbAotICAgKi8KLSAgcHVibGljIExvY2FsVmFyaWFibGUgZ2V0TG9jYWxWYXJpYWJsZShDb25zdGFudFBvb2xHZW4gY3ApIHsKLSAgICBpbnQgc3RhcnRfcGMgICAgICAgID0gc3RhcnQuZ2V0UG9zaXRpb24oKTsKLSAgICBpbnQgbGVuZ3RoICAgICAgICAgID0gZW5kLmdldFBvc2l0aW9uKCkgLSBzdGFydF9wYzsKLQotICAgIGlmKGxlbmd0aCA+IDApCi0gICAgICBsZW5ndGggKz0gZW5kLmdldEluc3RydWN0aW9uKCkuZ2V0TGVuZ3RoKCk7Ci0KLSAgICBpbnQgbmFtZV9pbmRleCAgICAgID0gY3AuYWRkVXRmOChuYW1lKTsKLSAgICBpbnQgc2lnbmF0dXJlX2luZGV4ID0gY3AuYWRkVXRmOCh0eXBlLmdldFNpZ25hdHVyZSgpKTsKLQotICAgIHJldHVybiBuZXcgTG9jYWxWYXJpYWJsZShzdGFydF9wYywgbGVuZ3RoLCBuYW1lX2luZGV4LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaWduYXR1cmVfaW5kZXgsIGluZGV4LCBjcC5nZXRDb25zdGFudFBvb2woKSk7Ci0gIH0KLQotICBwdWJsaWMgaW50ICAgICAgICAgZ2V0SW5kZXgoKSAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIGluZGV4OyB9Ci0gIEBPdmVycmlkZQotICBwdWJsaWMgdm9pZCAgICAgICAgc2V0TmFtZShTdHJpbmcgbmFtZSkgICAgICAgIHsgdGhpcy5uYW1lID0gbmFtZTsgfQotICBAT3ZlcnJpZGUKLSAgcHVibGljIFN0cmluZyAgICAgIGdldE5hbWUoKSAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuYW1lOyB9Ci0gIEBPdmVycmlkZQotICBwdWJsaWMgdm9pZCAgICAgICAgc2V0VHlwZShUeXBlIHR5cGUpICAgICAgICAgIHsgdGhpcy50eXBlID0gdHlwZTsgfQotICBAT3ZlcnJpZGUKLSAgcHVibGljIFR5cGUgICAgICAgIGdldFR5cGUoKSAgICAgICAgICAgICAgICAgICB7IHJldHVybiB0eXBlOyB9Ci0KLSAgcHVibGljIEluc3RydWN0aW9uSGFuZGxlIGdldFN0YXJ0KCkgICAgICAgICAgICAgICAgICB7IHJldHVybiBzdGFydDsgfQotICBwdWJsaWMgSW5zdHJ1Y3Rpb25IYW5kbGUgZ2V0RW5kKCkgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIGVuZDsgfQotCi0gIC8qKgotICAgKiBSZW1vdmUgdGhpcyBmcm9tIGFueSBrbm93biBIYXNoU2V0IGluIHdoaWNoIGl0IG1pZ2h0IGJlIHJlZ2lzdGVyZWQuCi0gICAqLwotICB2b2lkIG5vdGlmeVRhcmdldENoYW5naW5nKCkgewotICAgIC8vIGhhc2hDb2RlIGRlcGVuZHMgb24gJ2luZGV4JywgJ3N0YXJ0JywgYW5kICdlbmQnLgotICAgIC8vIFRoZXJlZm9yZSBiZWZvcmUgY2hhbmdpbmcgYW55IG9mIHRoZXNlIHZhbHVlcyB3ZQotICAgIC8vIG5lZWQgdG8gdW5yZWdpc3RlciAndGhpcycgZnJvbSBhbnkgSGFzaFNldCB3aGVyZQotICAgIC8vIHRoaXMgaXMgcmVnaXN0ZXJlZCwgYW5kIHRoZW4gd2UgbmVlZCB0byBhZGQgaXQKLSAgICAvLyBiYWNrLi4uCi0KLSAgICAvLyBVbnJlZ2lzdGVyICd0aGlzJyBmcm9tIHRoZSBIYXNoU2V0IGhlbGQgYnkgJ3N0YXJ0Jy4KLSAgICBCcmFuY2hJbnN0cnVjdGlvbi5ub3RpZnlUYXJnZXRDaGFuZ2luZyh0aGlzLnN0YXJ0LCB0aGlzKTsKLSAgICBpZiAodGhpcy5lbmQgIT0gdGhpcy5zdGFydCkgewotICAgICAgICAvLyBTaW5jZSBoYXNoQ29kZSgpIGlzIGdvaW5nIHRvIGNoYW5nZSB3ZSBuZWVkIHRvIHVucmVnaXN0ZXIKLSAgICAgICAgLy8gJ3RoaXMnIGJvdGggZm9ybSAnc3RhcnQnIGFuZCAnZW5kJy4KLSAgICAgICAgLy8gVW5yZWdpc3RlciAndGhpcycgZnJvbSB0aGUgSGFzaFNldCBoZWxkIGJ5ICdlbmQnLgotICAgICAgICBCcmFuY2hJbnN0cnVjdGlvbi5ub3RpZnlUYXJnZXRDaGFuZ2luZyh0aGlzLmVuZCwgdGhpcyk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEFkZCBiYWNrICd0aGlzJyBpbiBhbGwgSGFzaFNldCBpbiB3aGljaCBpdCBzaG91bGQgYmUgcmVnaXN0ZXJlZC4KLSAgICoqLwotICB2b2lkIG5vdGlmeVRhcmdldENoYW5nZWQoKSB7Ci0gICAgLy8gaGFzaENvZGUgZGVwZW5kcyBvbiAnaW5kZXgnLCAnc3RhcnQnLCBhbmQgJ2VuZCcuCi0gICAgLy8gVGhlcmVmb3JlIGJlZm9yZSBjaGFuZ2luZyBhbnkgb2YgdGhlc2UgdmFsdWVzIHdlCi0gICAgLy8gbmVlZCB0byB1bnJlZ2lzdGVyICd0aGlzJyBmcm9tIGFueSBIYXNoU2V0IHdoZXJlCi0gICAgLy8gdGhpcyBpcyByZWdpc3RlcmVkLCBhbmQgdGhlbiB3ZSBuZWVkIHRvIGFkZCBpdAotICAgIC8vIGJhY2suLi4KLQotICAgIC8vIFJlZ2lzdGVyICd0aGlzJyBpbiB0aGUgSGFzaFNldCBoZWxkIGJ5IHN0YXJ0LgotICAgIEJyYW5jaEluc3RydWN0aW9uLm5vdGlmeVRhcmdldENoYW5nZWQodGhpcy5zdGFydCwgdGhpcyk7Ci0gICAgaWYgKHRoaXMuZW5kICE9IHRoaXMuc3RhcnQpIHsKLSAgICAgICAgLy8gU2luY2UgaGFzaENvZGUoKSBoYXMgY2hhbmdlZCB3ZSBuZWVkIHRvIHJlZ2lzdGVyCi0gICAgICAgIC8vICd0aGlzJyBhZ2FpbiBpbiAnZW5kJy4KLSAgICAgICAgLy8gQWRkIGJhY2sgJ3RoaXMnIGluIHRoZSBIYXNoU2V0IGhlbGQgYnkgJ2VuZCcuCi0gICAgICAgIEJyYW5jaEluc3RydWN0aW9uLm5vdGlmeVRhcmdldENoYW5nZWQodGhpcy5lbmQsIHRoaXMpOwotICAgIH0KLSAgfQotCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHNldFN0YXJ0KEluc3RydWN0aW9uSGFuZGxlIHN0YXJ0KSB7Ci0KLSAgICAvLyBDYWxsIG5vdGlmeVRhcmdldENoYW5naW5nICpiZWZvcmUqIG1vZGlmeWluZyB0aGlzLAotICAgIC8vIGFzIHRoZSBjb2RlIHRyaWdnZXJlZCBieSBub3RpZnlUYXJnZXRDaGFuZ2luZwotICAgIC8vIGRlcGVuZHMgb24gdGhpcyBwb2ludGluZyB0byB0aGUgJ29sZCcgc3RhcnQuCi0gICAgbm90aWZ5VGFyZ2V0Q2hhbmdpbmcoKTsKLQotICAgIHRoaXMuc3RhcnQgPSBzdGFydDsKLQotICAgIC8vIGNhbGwgbm90aWZ5VGFyZ2V0Q2hhbmdlZCAqYWZ0ZXIqIG1vZGlmeWluZyB0aGlzLAotICAgIC8vIGFzIHRoZSBjb2RlIHRyaWdnZXJlZCBieSBub3RpZnlUYXJnZXRDaGFuZ2VkCi0gICAgLy8gZGVwZW5kcyBvbiB0aGlzIHBvaW50aW5nIHRvIHRoZSAnbmV3JyBzdGFydC4KLSAgICBub3RpZnlUYXJnZXRDaGFuZ2VkKCk7Ci0gIH0KLQotICBwdWJsaWMgZmluYWwgdm9pZCBzZXRFbmQoSW5zdHJ1Y3Rpb25IYW5kbGUgZW5kKSB7Ci0gICAgLy8gY2FsbCBub3RpZnlUYXJnZXRDaGFuZ2luZyAqYmVmb3JlKiBtb2RpZnlpbmcgdGhpcywKLSAgICAvLyBhcyB0aGUgY29kZSB0cmlnZ2VyZWQgYnkgbm90aWZ5VGFyZ2V0Q2hhbmdpbmcKLSAgICAvLyBkZXBlbmRzIG9uIHRoaXMgcG9pbnRpbmcgdG8gdGhlICdvbGQnIGVuZC4KLSAgICAvLyBVbnJlZ2lzdGVyICd0aGlzJyBmcm9tIHRoZSBIYXNoU2V0IGhlbGQgYnkgdGhlICdvbGQnIGVuZC4KLSAgICBub3RpZnlUYXJnZXRDaGFuZ2luZygpOwotCi0gICAgdGhpcy5lbmQgPSBlbmQ7Ci0KLSAgICAvLyBjYWxsIG5vdGlmeVRhcmdldENoYW5nZWQgKmFmdGVyKiBtb2RpZnlpbmcgdGhpcywKLSAgICAvLyBhcyB0aGUgY29kZSB0cmlnZ2VyZWQgYnkgbm90aWZ5VGFyZ2V0Q2hhbmdlZAotICAgIC8vIGRlcGVuZHMgb24gdGhpcyBwb2ludGluZyB0byB0aGUgJ25ldycgZW5kLgotICAgIC8vIFJlZ2lzdGVyICd0aGlzJyBpbiB0aGUgSGFzaFNldCBoZWxkIGJ5IHRoZSAnbmV3JyBlbmQuCi0gICAgbm90aWZ5VGFyZ2V0Q2hhbmdlZCgpOwotCi0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIG9sZF9paCBvbGQgdGFyZ2V0LCBlaXRoZXIgc3RhcnQgb3IgZW5kCi0gICAqIEBwYXJhbSBuZXdfaWggbmV3IHRhcmdldAotICAgKi8KLSAgQE92ZXJyaWRlCi0gIHB1YmxpYyB2b2lkIHVwZGF0ZVRhcmdldChJbnN0cnVjdGlvbkhhbmRsZSBvbGRfaWgsIEluc3RydWN0aW9uSGFuZGxlIG5ld19paCkgewotICAgIGJvb2xlYW4gdGFyZ2V0ZWQgPSBmYWxzZTsKLQotICAgIGlmKHN0YXJ0ID09IG9sZF9paCkgewotICAgICAgdGFyZ2V0ZWQgPSB0cnVlOwotICAgICAgc2V0U3RhcnQobmV3X2loKTsKLSAgICB9Ci0KLSAgICBpZihlbmQgPT0gb2xkX2loKSB7Ci0gICAgICB0YXJnZXRlZCA9IHRydWU7Ci0gICAgICBzZXRFbmQobmV3X2loKTsKLSAgICB9Ci0KLSAgICBpZighdGFyZ2V0ZWQpCi0gICAgICB0aHJvdyBuZXcgQ2xhc3NHZW5FeGNlcHRpb24oIk5vdCB0YXJnZXRpbmcgIiArIG9sZF9paCArICIsIGJ1dCB7IiArIHN0YXJ0ICsgIiwgIiArCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5kICsgIn0iKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIHRydWUsIGlmIGloIGlzIHRhcmdldCBvZiB0aGlzIHZhcmlhYmxlCi0gICAqLwotICBAT3ZlcnJpZGUKLSAgcHVibGljIGJvb2xlYW4gY29udGFpbnNUYXJnZXQoSW5zdHJ1Y3Rpb25IYW5kbGUgaWgpIHsKLSAgICByZXR1cm4gKHN0YXJ0ID09IGloKSB8fCAoZW5kID09IGloKTsKLSAgfQotCi0gIC8qKgotICAgKiBXZSBjb25zaWRlciB0d28gbG9jYWwgdmFyaWFibGVzIHRvIGJlIGVxdWFsLCBpZiB0aGV5IHVzZSB0aGUgc2FtZSBpbmRleCBhbmQKLSAgICogYXJlIHZhbGlkIGluIHRoZSBzYW1lIHJhbmdlLgotICAgKi8KLSAgQE92ZXJyaWRlCi0gIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgbykgewotICAgIGlmIChvPT10aGlzKQotICAgICAgcmV0dXJuIHRydWU7Ci0KLSAgICBpZighKG8gaW5zdGFuY2VvZiBMb2NhbFZhcmlhYmxlR2VuKSkKLSAgICAgIHJldHVybiBmYWxzZTsKLQotICAgIExvY2FsVmFyaWFibGVHZW4gbCA9IChMb2NhbFZhcmlhYmxlR2VuKW87Ci0gICAgcmV0dXJuIChsLmluZGV4ID09IGluZGV4KSAmJiAobC5zdGFydCA9PSBzdGFydCkgJiYgKGwuZW5kID09IGVuZCk7Ci0gIH0KLQotICBAT3ZlcnJpZGUKLSAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKLSAgICBpbnQgaGFzaCA9IDc7Ci0gICAgaGFzaCA9IDU5ICogaGFzaCArIHRoaXMuaW5kZXg7Ci0gICAgaGFzaCA9IDU5ICogaGFzaCArIE9iamVjdHMuaGFzaENvZGUodGhpcy5zdGFydCk7Ci0gICAgaGFzaCA9IDU5ICogaGFzaCArIE9iamVjdHMuaGFzaENvZGUodGhpcy5lbmQpOwotICAgIHJldHVybiBoYXNoOwotICB9Ci0KLSAgQE92ZXJyaWRlCi0gIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0gICAgcmV0dXJuICJMb2NhbFZhcmlhYmxlR2VuKCIgKyBuYW1lICsgICIsICIgKyB0eXBlICsgICIsICIgKyBzdGFydCArICIsICIgKyBlbmQgKyAiKSI7Ci0gIH0KLQotICBAT3ZlcnJpZGUKLSAgcHVibGljIE9iamVjdCBjbG9uZSgpIHsKLSAgICB0cnkgewotICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7Ci0gICAgfSBjYXRjaChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKSB7Ci0gICAgICBTeXN0ZW0uZXJyLnByaW50bG4oZSk7Ci0gICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL0xvY2FsVmFyaWFibGVJbnN0cnVjdGlvbi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvTG9jYWxWYXJpYWJsZUluc3RydWN0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGYxMGI5MWQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvTG9jYWxWYXJpYWJsZUluc3RydWN0aW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMjkgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLWltcG9ydCBqYXZhLmlvLio7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwudXRpbC5CeXRlU2VxdWVuY2U7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuY2xhc3NmaWxlLlV0aWxpdHk7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzOwotCi0vKioKLSAqIEFic3RyYWN0IHN1cGVyIGNsYXNzIGZvciBpbnN0cnVjdGlvbnMgZGVhbGluZyB3aXRoIGxvY2FsIHZhcmlhYmxlcy4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgYWJzdHJhY3QgY2xhc3MgTG9jYWxWYXJpYWJsZUluc3RydWN0aW9uIGV4dGVuZHMgSW5zdHJ1Y3Rpb24KLSAgaW1wbGVtZW50cyBUeXBlZEluc3RydWN0aW9uLCBJbmRleGVkSW5zdHJ1Y3Rpb24gewotICBwcm90ZWN0ZWQgaW50ICAgICBuICAgICAgICAgPSAtMTsgLy8gaW5kZXggb2YgcmVmZXJlbmNlZCB2YXJpYWJsZQotICBwcml2YXRlIHNob3J0ICAgICBjX3RhZyAgICAgPSAtMTsgLy8gY29tcGFjdCB2ZXJzaW9uLCBzdWNoIGFzIElMT0FEXzAKLSAgcHJpdmF0ZSBzaG9ydCAgICAgY2Fub25fdGFnID0gLTE7IC8vIGNhbm9uaWNhbCB0YWcgc3VjaCBhcyBJTE9BRAotCi0gIHByaXZhdGUgZmluYWwgYm9vbGVhbiB3aWRlKCkgeyByZXR1cm4gbiA+IENvbnN0YW50cy5NQVhfQllURTsgfQotCi0gIC8qKgotICAgKiBFbXB0eSBjb25zdHJ1Y3RvciBuZWVkZWQgZm9yIHRoZSBDbGFzcy5uZXdJbnN0YW5jZSgpIHN0YXRlbWVudCBpbgotICAgKiBJbnN0cnVjdGlvbi5yZWFkSW5zdHJ1Y3Rpb24oKS4gTm90IHRvIGJlIHVzZWQgb3RoZXJ3aXNlLgotICAgKiB0YWcgYW5kIGxlbmd0aCBhcmUgZGVmaW5lZCBpbiByZWFkSW5zdHJ1Y3Rpb24gYW5kIGluaXRGcm9tRmlsZSwgcmVzcGVjdGl2ZWx5LgotICAgKi8KLSAgTG9jYWxWYXJpYWJsZUluc3RydWN0aW9uKHNob3J0IGNhbm9uX3RhZywgc2hvcnQgY190YWcpIHsKLSAgICBzdXBlcigpOwotICAgIHRoaXMuY2Fub25fdGFnID0gY2Fub25fdGFnOwotICAgIHRoaXMuY190YWcgICAgID0gY190YWc7Ci0gIH0KLQotICAvKioKLSAgICogRW1wdHkgY29uc3RydWN0b3IgbmVlZGVkIGZvciB0aGUgQ2xhc3MubmV3SW5zdGFuY2UoKSBzdGF0ZW1lbnQgaW4KLSAgICogSW5zdHJ1Y3Rpb24ucmVhZEluc3RydWN0aW9uKCkuIEFsc28gdXNlZCBieSBJSU5DKCkhCi0gICAqLwotICBMb2NhbFZhcmlhYmxlSW5zdHJ1Y3Rpb24oKSB7Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIG9wY29kZSBJbnN0cnVjdGlvbiBvcGNvZGUKLSAgICogQHBhcmFtIGNfdGFnIEluc3RydWN0aW9uIG51bWJlciBmb3IgY29tcGFjdCB2ZXJzaW9uLCBBTE9BRF8wLCBlLmcuCi0gICAqIEBwYXJhbSBuIGxvY2FsIHZhcmlhYmxlIGluZGV4ICh1bnNpZ25lZCBzaG9ydCkKLSAgICovCi0gIHByb3RlY3RlZCBMb2NhbFZhcmlhYmxlSW5zdHJ1Y3Rpb24oc2hvcnQgb3Bjb2RlLCBzaG9ydCBjX3RhZywgaW50IG4pIHsKLSAgICBzdXBlcihvcGNvZGUsIChzaG9ydCkyKTsKLQotICAgIHRoaXMuY190YWcgPSBjX3RhZzsKLSAgICBjYW5vbl90YWcgID0gb3Bjb2RlOwotCi0gICAgc2V0SW5kZXgobik7Ci0gIH0KLQotICAvKioKLSAgICogRHVtcCBpbnN0cnVjdGlvbiBhcyBieXRlIGNvZGUgdG8gc3RyZWFtIG91dC4KLSAgICogQHBhcmFtIG91dCBPdXRwdXQgc3RyZWFtCi0gICAqLwotICBwdWJsaWMgdm9pZCBkdW1wKERhdGFPdXRwdXRTdHJlYW0gb3V0KSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgIGlmKHdpZGUoKSkgLy8gTmVlZCBXSURFIHByZWZpeCA/Ci0gICAgICBvdXQud3JpdGVCeXRlKENvbnN0YW50cy5XSURFKTsKLQotICAgIG91dC53cml0ZUJ5dGUob3Bjb2RlKTsKLQotICAgIGlmKGxlbmd0aCA+IDEpIHsgLy8gT3RoZXJ3aXNlIElMT0FEX24sIGluc3RydWN0aW9uLCBlLmcuCi0gICAgICBpZih3aWRlKCkpCi0gICAgICAgIG91dC53cml0ZVNob3J0KG4pOwotICAgICAgZWxzZQotICAgICAgICBvdXQud3JpdGVCeXRlKG4pOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBMb25nIG91dHB1dCBmb3JtYXQ6Ci0gICAqCi0gICAqICZsdDtuYW1lIG9mIG9wY29kZSZndDsgIlsiJmx0O29wY29kZSBudW1iZXImZ3Q7Il0iCi0gICAqICIoIiZsdDtsZW5ndGggb2YgaW5zdHJ1Y3Rpb24mZ3Q7IikiICImbHQ7IiZsdDsgbG9jYWwgdmFyaWFibGUgaW5kZXgmZ3Q7IiZndDsiCi0gICAqCi0gICAqIEBwYXJhbSB2ZXJib3NlIGxvbmcvc2hvcnQgZm9ybWF0IHN3aXRjaAotICAgKiBAcmV0dXJuIG1uZW1vbmljIGZvciBpbnN0cnVjdGlvbgotICAgKi8KLSAgcHVibGljIFN0cmluZyB0b1N0cmluZyhib29sZWFuIHZlcmJvc2UpIHsKLSAgICBpZigoKG9wY29kZSA+PSBDb25zdGFudHMuSUxPQURfMCkgJiYKLSAgICAgICAgKG9wY29kZSA8PSBDb25zdGFudHMuQUxPQURfMykpIHx8Ci0gICAgICAgKChvcGNvZGUgPj0gQ29uc3RhbnRzLklTVE9SRV8wKSAmJgotICAgICAgICAob3Bjb2RlIDw9IENvbnN0YW50cy5BU1RPUkVfMykpKQotICAgICAgcmV0dXJuIHN1cGVyLnRvU3RyaW5nKHZlcmJvc2UpOwotICAgIGVsc2UKLSAgICAgIHJldHVybiBzdXBlci50b1N0cmluZyh2ZXJib3NlKSArICIgIiArIG47Ci0gIH0KLQotICAvKioKLSAgICogUmVhZCBuZWVkZWQgZGF0YSAoZS5nLiBpbmRleCkgZnJvbSBmaWxlLgotICAgKiBQUkU6IChJTE9BRCA8PSB0YWcgPD0gQUxPQURfMykgfHwgKElTVE9SRSA8PSB0YWcgPD0gQVNUT1JFXzMpCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBpbml0RnJvbUZpbGUoQnl0ZVNlcXVlbmNlIGJ5dGVzLCBib29sZWFuIHdpZGUpCi0gICAgdGhyb3dzIElPRXhjZXB0aW9uCi0gIHsKLSAgICBpZih3aWRlKSB7Ci0gICAgICBuICAgICAgICAgPSBieXRlcy5yZWFkVW5zaWduZWRTaG9ydCgpOwotICAgICAgbGVuZ3RoICAgID0gNDsKLSAgICB9IGVsc2UgaWYoKChvcGNvZGUgPj0gQ29uc3RhbnRzLklMT0FEKSAmJgotICAgICAgICAgICAgICAgKG9wY29kZSA8PSBDb25zdGFudHMuQUxPQUQpKSB8fAotICAgICAgICAgICAgICAoKG9wY29kZSA+PSBDb25zdGFudHMuSVNUT1JFKSAmJgotICAgICAgICAgICAgICAgKG9wY29kZSA8PSBDb25zdGFudHMuQVNUT1JFKSkpIHsKLSAgICAgIG4gICAgICA9IGJ5dGVzLnJlYWRVbnNpZ25lZEJ5dGUoKTsKLSAgICAgIGxlbmd0aCA9IDI7Ci0gICAgfSBlbHNlIGlmKG9wY29kZSA8PSBDb25zdGFudHMuQUxPQURfMykgeyAvLyBjb21wYWN0IGxvYWQgaW5zdHJ1Y3Rpb24gc3VjaCBhcyBJTE9BRF8yCi0gICAgICBuICAgICAgPSAob3Bjb2RlIC0gQ29uc3RhbnRzLklMT0FEXzApICUgNDsKLSAgICAgIGxlbmd0aCA9IDE7Ci0gICAgfSBlbHNlIHsgLy8gQXNzZXJ0IElTVE9SRV8wIDw9IHRhZyA8PSBBU1RPUkVfMwotICAgICAgbiAgICAgID0gKG9wY29kZSAtIENvbnN0YW50cy5JU1RPUkVfMCkgJSA0OwotICAgICAgbGVuZ3RoID0gMTsKLSAgICB9Ci0gfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIGxvY2FsIHZhcmlhYmxlIGluZGV4ICByZWZlcnJlZCBieSB0aGlzIGluc3RydWN0aW9uLgotICAgKi8KLSAgcHVibGljIGZpbmFsIGludCBnZXRJbmRleCgpIHsgcmV0dXJuIG47IH0KLQotICAvKioKLSAgICogU2V0IHRoZSBsb2NhbCB2YXJpYWJsZSBpbmRleAotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0SW5kZXgoaW50IG4pIHsKLSAgICBpZigobiA8IDApIHx8IChuID4gQ29uc3RhbnRzLk1BWF9TSE9SVCkpCi0gICAgICB0aHJvdyBuZXcgQ2xhc3NHZW5FeGNlcHRpb24oIklsbGVnYWwgdmFsdWU6ICIgKyBuKTsKLQotICAgIHRoaXMubiA9IG47Ci0KLSAgICBpZihuID49IDAgJiYgbiA8PSAzKSB7IC8vIFVzZSBtb3JlIGNvbXBhY3QgaW5zdHJ1Y3Rpb24geExPQURfbgotICAgICAgb3Bjb2RlID0gKHNob3J0KShjX3RhZyArIG4pOwotICAgICAgbGVuZ3RoID0gMTsKLSAgICB9IGVsc2UgewotICAgICAgb3Bjb2RlID0gY2Fub25fdGFnOwotCi0gICAgICBpZih3aWRlKCkpIC8vIE5lZWQgV0lERSBwcmVmaXggPwotICAgICAgICBsZW5ndGggPSA0OwotICAgICAgZWxzZQotICAgICAgICBsZW5ndGggPSAyOwotICAgIH0KLSAgfQotCi0gIC8qKiBAcmV0dXJuIGNhbm9uaWNhbCB0YWcgZm9yIGluc3RydWN0aW9uLCBlLmcuLCBBTE9BRCBmb3IgQUxPQURfMAotICAgKi8KLSAgcHVibGljIHNob3J0IGdldENhbm9uaWNhbFRhZygpIHsKLSAgICByZXR1cm4gY2Fub25fdGFnOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIHR5cGUgYXNzb2NpYXRlZCB3aXRoIHRoZSBpbnN0cnVjdGlvbiAtCi0gICAqIGluIGNhc2Ugb2YgQUxPQUQgb3IgQVNUT1JFIFR5cGUuT0JKRUNUIGlzIHJldHVybmVkLgotICAgKiBUaGlzIGlzIGp1c3QgYSBiaXQgaW5jb3JyZWN0LCBiZWNhdXNlIEFMT0FEIGFuZCBBU1RPUkUKLSAgICogbWF5IHdvcmsgb24gZXZlcnkgUmVmZXJlbmNlVHlwZSAoaW5jbHVkaW5nIFR5cGUuTlVMTCkgYW5kCi0gICAqIEFTVE9SRSBtYXkgZXZlbiB3b3JrIG9uIGEgUmV0dXJuYWRkcmVzc1R5cGUgLgotICAgKiBAcmV0dXJuIHR5cGUgYXNzb2NpYXRlZCB3aXRoIHRoZSBpbnN0cnVjdGlvbgotICAgKi8KLSAgcHVibGljIFR5cGUgZ2V0VHlwZShDb25zdGFudFBvb2xHZW4gY3ApIHsKLSAgICBzd2l0Y2goY2Fub25fdGFnKSB7Ci0gICAgY2FzZSBDb25zdGFudHMuSUxPQUQ6IGNhc2UgQ29uc3RhbnRzLklTVE9SRToKLSAgICAgIHJldHVybiBUeXBlLklOVDsKLSAgICBjYXNlIENvbnN0YW50cy5MTE9BRDogY2FzZSBDb25zdGFudHMuTFNUT1JFOgotICAgICAgcmV0dXJuIFR5cGUuTE9ORzsKLSAgICBjYXNlIENvbnN0YW50cy5ETE9BRDogY2FzZSBDb25zdGFudHMuRFNUT1JFOgotICAgICAgcmV0dXJuIFR5cGUuRE9VQkxFOwotICAgIGNhc2UgQ29uc3RhbnRzLkZMT0FEOiBjYXNlIENvbnN0YW50cy5GU1RPUkU6Ci0gICAgICByZXR1cm4gVHlwZS5GTE9BVDsKLSAgICBjYXNlIENvbnN0YW50cy5BTE9BRDogY2FzZSBDb25zdGFudHMuQVNUT1JFOgotICAgICAgcmV0dXJuIFR5cGUuT0JKRUNUOwotCi0gICAgZGVmYXVsdDogdGhyb3cgbmV3IENsYXNzR2VuRXhjZXB0aW9uKCJPb3BzOiB1bmtub3duIGNhc2UgaW4gc3dpdGNoIiArIGNhbm9uX3RhZyk7Ci0gICAgfQotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9NT05JVE9SRU5URVIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL01PTklUT1JFTlRFUi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlNTBkZGU0Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL01PTklUT1JFTlRFUi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTEgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotLyoqCi0gKiBNT05JVE9SRU5URVIgLSBFbnRlciBtb25pdG9yIGZvciBvYmplY3QKLSAqIDxQUkU+U3RhY2s6IC4uLiwgb2JqZWN0cmVmIC0mZ3Q7IC4uLjwvUFJFPgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBNT05JVE9SRU5URVIgZXh0ZW5kcyBJbnN0cnVjdGlvbgotICBpbXBsZW1lbnRzIEV4Y2VwdGlvblRocm93ZXIsIFN0YWNrQ29uc3VtZXIgewotICBwdWJsaWMgTU9OSVRPUkVOVEVSKCkgewotICAgIHN1cGVyKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5NT05JVE9SRU5URVIsIChzaG9ydCkxKTsKLSAgfQotCi0gIHB1YmxpYyBDbGFzc1tdIGdldEV4Y2VwdGlvbnMoKSB7Ci0gICAgcmV0dXJuIG5ldyBDbGFzc1tdIHsgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuRXhjZXB0aW9uQ29uc3RhbnRzLk5VTExfUE9JTlRFUl9FWENFUFRJT04gfTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIENhbGwgY29ycmVzcG9uZGluZyB2aXNpdG9yIG1ldGhvZChzKS4gVGhlIG9yZGVyIGlzOgotICAgKiBDYWxsIHZpc2l0b3IgbWV0aG9kcyBvZiBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzIGZpcnN0LCB0aGVuCi0gICAqIGNhbGwgbWV0aG9kcyBhY2NvcmRpbmcgdG8gdGhlIGNsYXNzIGhpZXJhcmNoeSBpbiBkZXNjZW5kaW5nIG9yZGVyLAotICAgKiBpLmUuLCB0aGUgbW9zdCBzcGVjaWZpYyB2aXNpdFhYWCgpIGNhbGwgY29tZXMgbGFzdC4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0RXhjZXB0aW9uVGhyb3dlcih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tDb25zdW1lcih0aGlzKTsKLSAgICB2LnZpc2l0TU9OSVRPUkVOVEVSKHRoaXMpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9NT05JVE9SRVhJVC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvTU9OSVRPUkVYSVQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYzA4OGFhOC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9NT05JVE9SRVhJVC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTEgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotLyoqCi0gKiBNT05JVE9SRVhJVCAtIEV4aXQgbW9uaXRvciBmb3Igb2JqZWN0Ci0gKiA8UFJFPlN0YWNrOiAuLi4sIG9iamVjdHJlZiAtJmd0OyAuLi48L1BSRT4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgTU9OSVRPUkVYSVQgZXh0ZW5kcyBJbnN0cnVjdGlvbgotICBpbXBsZW1lbnRzIEV4Y2VwdGlvblRocm93ZXIsIFN0YWNrQ29uc3VtZXIgewotICBwdWJsaWMgTU9OSVRPUkVYSVQoKSB7Ci0gICAgc3VwZXIoY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLk1PTklUT1JFWElULCAoc2hvcnQpMSk7Ci0gIH0KLQotICBwdWJsaWMgQ2xhc3NbXSBnZXRFeGNlcHRpb25zKCkgewotICAgIHJldHVybiBuZXcgQ2xhc3NbXSB7IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkV4Y2VwdGlvbkNvbnN0YW50cy5OVUxMX1BPSU5URVJfRVhDRVBUSU9OIH07Ci0gIH0KLQotCi0gIC8qKgotICAgKiBDYWxsIGNvcnJlc3BvbmRpbmcgdmlzaXRvciBtZXRob2QocykuIFRoZSBvcmRlciBpczoKLSAgICogQ2FsbCB2aXNpdG9yIG1ldGhvZHMgb2YgaW1wbGVtZW50ZWQgaW50ZXJmYWNlcyBmaXJzdCwgdGhlbgotICAgKiBjYWxsIG1ldGhvZHMgYWNjb3JkaW5nIHRvIHRoZSBjbGFzcyBoaWVyYXJjaHkgaW4gZGVzY2VuZGluZyBvcmRlciwKLSAgICogaS5lLiwgdGhlIG1vc3Qgc3BlY2lmaWMgdmlzaXRYWFgoKSBjYWxsIGNvbWVzIGxhc3QuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgdi52aXNpdEV4Y2VwdGlvblRocm93ZXIodGhpcyk7Ci0gICAgdi52aXNpdFN0YWNrQ29uc3VtZXIodGhpcyk7Ci0gICAgdi52aXNpdE1PTklUT1JFWElUKHRoaXMpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9NVUxUSUFORVdBUlJBWS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvTVVMVElBTkVXQVJSQVkuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNmE0OTAxMS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9NVUxUSUFORVdBUlJBWS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTc1ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1pbXBvcnQgamF2YS5pby4qOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLnV0aWwuQnl0ZVNlcXVlbmNlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmNsYXNzZmlsZS5Db25zdGFudFBvb2w7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuRXhjZXB0aW9uQ29uc3RhbnRzOwotCi0vKioKLSAqIE1VTFRJQU5FV0FSUkFZIC0gQ3JlYXRlIG5ldyBtdXRpZGltZW5zaW9uYWwgYXJyYXkgb2YgcmVmZXJlbmNlcwotICogPFBSRT5TdGFjazogLi4uLCBjb3VudDEsIFtjb3VudDIsIC4uLl0gLSZndDsgLi4uLCBhcnJheXJlZjwvUFJFPgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBNVUxUSUFORVdBUlJBWSBleHRlbmRzIENQSW5zdHJ1Y3Rpb24gaW1wbGVtZW50cyBMb2FkQ2xhc3MsIEFsbG9jYXRpb25JbnN0cnVjdGlvbiwgRXhjZXB0aW9uVGhyb3dlciB7Ci0gIHByaXZhdGUgc2hvcnQgZGltZW5zaW9uczsKLQotICAvKioKLSAgICogRW1wdHkgY29uc3RydWN0b3IgbmVlZGVkIGZvciB0aGUgQ2xhc3MubmV3SW5zdGFuY2UoKSBzdGF0ZW1lbnQgaW4KLSAgICogSW5zdHJ1Y3Rpb24ucmVhZEluc3RydWN0aW9uKCkuIE5vdCB0byBiZSB1c2VkIG90aGVyd2lzZS4KLSAgICovCi0gIE1VTFRJQU5FV0FSUkFZKCkge30KLQotICBwdWJsaWMgTVVMVElBTkVXQVJSQVkoaW50IGluZGV4LCBzaG9ydCBkaW1lbnNpb25zKSB7Ci0gICAgc3VwZXIoY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLk1VTFRJQU5FV0FSUkFZLCBpbmRleCk7Ci0KLSAgICBpZihkaW1lbnNpb25zIDwgMSkKLSAgICAgIHRocm93IG5ldyBDbGFzc0dlbkV4Y2VwdGlvbigiSW52YWxpZCBkaW1lbnNpb25zIHZhbHVlOiAiICsgZGltZW5zaW9ucyk7Ci0KLSAgICB0aGlzLmRpbWVuc2lvbnMgPSBkaW1lbnNpb25zOwotICAgIGxlbmd0aCA9IDQ7Ci0gIH0KLQotICAvKioKLSAgICogRHVtcCBpbnN0cnVjdGlvbiBhcyBieXRlIGNvZGUgdG8gc3RyZWFtIG91dC4KLSAgICogQHBhcmFtIG91dCBPdXRwdXQgc3RyZWFtCi0gICAqLwotICBwdWJsaWMgdm9pZCBkdW1wKERhdGFPdXRwdXRTdHJlYW0gb3V0KSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgIG91dC53cml0ZUJ5dGUob3Bjb2RlKTsKLSAgICBvdXQud3JpdGVTaG9ydChpbmRleCk7Ci0gICAgb3V0LndyaXRlQnl0ZShkaW1lbnNpb25zKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZWFkIG5lZWRlZCBkYXRhIChpLmUuLCBuby4gZGltZW5zaW9uKSBmcm9tIGZpbGUuCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBpbml0RnJvbUZpbGUoQnl0ZVNlcXVlbmNlIGJ5dGVzLCBib29sZWFuIHdpZGUpCi0gICAgICAgdGhyb3dzIElPRXhjZXB0aW9uCi0gIHsKLSAgICBzdXBlci5pbml0RnJvbUZpbGUoYnl0ZXMsIHdpZGUpOwotICAgIGRpbWVuc2lvbnMgPSBieXRlcy5yZWFkQnl0ZSgpOwotICAgIGxlbmd0aCAgICAgPSA0OwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gbnVtYmVyIG9mIGRpbWVuc2lvbnMgdG8gYmUgY3JlYXRlZAotICAgKi8KLSAgcHVibGljIGZpbmFsIHNob3J0IGdldERpbWVuc2lvbnMoKSB7IHJldHVybiBkaW1lbnNpb25zOyB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gbW5lbW9uaWMgZm9yIGluc3RydWN0aW9uCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKGJvb2xlYW4gdmVyYm9zZSkgewotICAgIHJldHVybiBzdXBlci50b1N0cmluZyh2ZXJib3NlKSArICIgIiArIGluZGV4ICsgIiAiICsgZGltZW5zaW9uczsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIG1uZW1vbmljIGZvciBpbnN0cnVjdGlvbiB3aXRoIHN5bWJvbGljIHJlZmVyZW5jZXMgcmVzb2x2ZWQKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoQ29uc3RhbnRQb29sIGNwKSB7Ci0gICAgcmV0dXJuIHN1cGVyLnRvU3RyaW5nKGNwKSArICIgIiArIGRpbWVuc2lvbnM7Ci0gIH0KLQotICAvKioKLSAgICogQWxzbyB3b3JrcyBmb3IgaW5zdHJ1Y3Rpb25zIHdob3NlIHN0YWNrIGVmZmVjdCBkZXBlbmRzIG9uIHRoZQotICAgKiBjb25zdGFudCBwb29sIGVudHJ5IHRoZXkgcmVmZXJlbmNlLgotICAgKiBAcmV0dXJuIE51bWJlciBvZiB3b3JkcyBjb25zdW1lZCBmcm9tIHN0YWNrIGJ5IHRoaXMgaW5zdHJ1Y3Rpb24KLSAgICovCi0gIHB1YmxpYyBpbnQgY29uc3VtZVN0YWNrKENvbnN0YW50UG9vbEdlbiBjcGcpIHsgcmV0dXJuIGRpbWVuc2lvbnM7IH0KLQotICBwdWJsaWMgQ2xhc3NbXSBnZXRFeGNlcHRpb25zKCkgewotICAgIENsYXNzW10gY3MgPSBuZXcgQ2xhc3NbMiArIEV4Y2VwdGlvbkNvbnN0YW50cy5FWENTX0NMQVNTX0FORF9JTlRFUkZBQ0VfUkVTT0xVVElPTi5sZW5ndGhdOwotCi0gICAgU3lzdGVtLmFycmF5Y29weShFeGNlcHRpb25Db25zdGFudHMuRVhDU19DTEFTU19BTkRfSU5URVJGQUNFX1JFU09MVVRJT04sIDAsCi0gICAgICAgICAgICAgICAgICAgICBjcywgMCwgRXhjZXB0aW9uQ29uc3RhbnRzLkVYQ1NfQ0xBU1NfQU5EX0lOVEVSRkFDRV9SRVNPTFVUSU9OLmxlbmd0aCk7Ci0KLSAgICBjc1tFeGNlcHRpb25Db25zdGFudHMuRVhDU19DTEFTU19BTkRfSU5URVJGQUNFX1JFU09MVVRJT04ubGVuZ3RoKzFdID0gRXhjZXB0aW9uQ29uc3RhbnRzLk5FR0FUSVZFX0FSUkFZX1NJWkVfRVhDRVBUSU9OOwotICAgIGNzW0V4Y2VwdGlvbkNvbnN0YW50cy5FWENTX0NMQVNTX0FORF9JTlRFUkZBQ0VfUkVTT0xVVElPTi5sZW5ndGhdICAgPSBFeGNlcHRpb25Db25zdGFudHMuSUxMRUdBTF9BQ0NFU1NfRVJST1I7Ci0KLSAgICByZXR1cm4gY3M7Ci0gIH0KLQotICBwdWJsaWMgT2JqZWN0VHlwZSBnZXRMb2FkQ2xhc3NUeXBlKENvbnN0YW50UG9vbEdlbiBjcGcpIHsKLSAgICBUeXBlIHQgPSBnZXRUeXBlKGNwZyk7Ci0KLSAgICBpZiAodCBpbnN0YW5jZW9mIEFycmF5VHlwZSl7Ci0gICAgICB0ID0gKChBcnJheVR5cGUpIHQpLmdldEJhc2ljVHlwZSgpOwotICAgIH0KLQotICAgIHJldHVybiAodCBpbnN0YW5jZW9mIE9iamVjdFR5cGUpPyAoT2JqZWN0VHlwZSkgdCA6IG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogQ2FsbCBjb3JyZXNwb25kaW5nIHZpc2l0b3IgbWV0aG9kKHMpLiBUaGUgb3JkZXIgaXM6Ci0gICAqIENhbGwgdmlzaXRvciBtZXRob2RzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMgZmlyc3QsIHRoZW4KLSAgICogY2FsbCBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY2xhc3MgaGllcmFyY2h5IGluIGRlc2NlbmRpbmcgb3JkZXIsCi0gICAqIGkuZS4sIHRoZSBtb3N0IHNwZWNpZmljIHZpc2l0WFhYKCkgY2FsbCBjb21lcyBsYXN0LgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRMb2FkQ2xhc3ModGhpcyk7Ci0gICAgdi52aXNpdEFsbG9jYXRpb25JbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0RXhjZXB0aW9uVGhyb3dlcih0aGlzKTsKLSAgICB2LnZpc2l0VHlwZWRJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0Q1BJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0TVVMVElBTkVXQVJSQVkodGhpcyk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL01ldGhvZEdlbi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvTWV0aG9kR2VuLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDY5MzQ1ODIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvTWV0aG9kR2VuLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMDg5ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuY2xhc3NmaWxlLio7Ci1pbXBvcnQgamF2YS51dGlsLio7Ci0KLS8qKgotICogVGVtcGxhdGUgY2xhc3MgZm9yIGJ1aWxkaW5nIHVwIGEgbWV0aG9kLiBUaGlzIGlzIGRvbmUgYnkgZGVmaW5pbmcgZXhjZXB0aW9uCi0gKiBoYW5kbGVycywgYWRkaW5nIHRocm93biBleGNlcHRpb25zLCBsb2NhbCB2YXJpYWJsZXMgYW5kIGF0dHJpYnV0ZXMsIHdoZXJlYXMKLSAqIHRoZSBgTG9jYWxWYXJpYWJsZVRhYmxlJyBhbmQgYExpbmVOdW1iZXJUYWJsZScgYXR0cmlidXRlcyB3aWxsIGJlIHNldAotICogYXV0b21hdGljYWxseSBmb3IgdGhlIGNvZGUuIFVzZSBzdHJpcEF0dHJpYnV0ZXMoKSBpZiB5b3UgZG9uJ3QgbGlrZSB0aGlzLgotICoKLSAqIFdoaWxlIGdlbmVyYXRpbmcgY29kZSBpdCBtYXkgYmUgbmVjZXNzYXJ5IHRvIGluc2VydCBOT1Agb3BlcmF0aW9ucy4gWW91IGNhbgotICogdXNlIHRoZSBgcmVtb3ZlTk9QcycgbWV0aG9kIHRvIGdldCByaWQgb2ZmIHRoZW0uCi0gKiBUaGUgcmVzdWx0aW5nIG1ldGhvZCBvYmplY3QgY2FuIGJlIG9idGFpbmVkIHZpYSB0aGUgYGdldE1ldGhvZCgpJyBtZXRob2QuCi0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqIEBhdXRob3IgIDxBIEhSRUY9Imh0dHA6Ly93d3cudm1lbmcuY29tL2JlYXJkIj5QYXRyaWNrIEMuIEJlYXJkPC9BPiBbc2V0TWF4U3RhY2soKV0KLSAqIEBzZWUgICAgIEluc3RydWN0aW9uTGlzdAotICogQHNlZSAgICAgTWV0aG9kCi0gKi8KLXB1YmxpYyBjbGFzcyBNZXRob2RHZW4gZXh0ZW5kcyBGaWVsZEdlbk9yTWV0aG9kR2VuIHsKLSAgcHJpdmF0ZSBTdHJpbmcgICAgICAgICAgY2xhc3NfbmFtZTsKLSAgcHJpdmF0ZSBUeXBlW10gICAgICAgICAgYXJnX3R5cGVzOwotICBwcml2YXRlIFN0cmluZ1tdICAgICAgICBhcmdfbmFtZXM7Ci0gIHByaXZhdGUgaW50ICAgICAgICAgICAgIG1heF9sb2NhbHM7Ci0gIHByaXZhdGUgaW50ICAgICAgICAgICAgIG1heF9zdGFjazsKLSAgcHJpdmF0ZSBJbnN0cnVjdGlvbkxpc3QgaWw7Ci0gIHByaXZhdGUgYm9vbGVhbiAgICAgICAgIHN0cmlwX2F0dHJpYnV0ZXM7Ci0KLSAgcHJpdmF0ZSBBcnJheUxpc3QgICAgICAgdmFyaWFibGVfdmVjICAgID0gbmV3IEFycmF5TGlzdCgpOwotICBwcml2YXRlIEFycmF5TGlzdCAgICAgICB0eXBlX3ZlYyAgICAgICAgPSBuZXcgQXJyYXlMaXN0KCk7Ci0gIHByaXZhdGUgQXJyYXlMaXN0ICAgICAgIGxpbmVfbnVtYmVyX3ZlYyA9IG5ldyBBcnJheUxpc3QoKTsKLSAgcHJpdmF0ZSBBcnJheUxpc3QgICAgICAgZXhjZXB0aW9uX3ZlYyAgID0gbmV3IEFycmF5TGlzdCgpOwotICBwcml2YXRlIEFycmF5TGlzdCAgICAgICB0aHJvd3NfdmVjICAgICAgPSBuZXcgQXJyYXlMaXN0KCk7Ci0gIHByaXZhdGUgQXJyYXlMaXN0ICAgICAgIGNvZGVfYXR0cnNfdmVjICA9IG5ldyBBcnJheUxpc3QoKTsKLQotICAvKioKLSAgICogRGVjbGFyZSBtZXRob2QuIElmIHRoZSBtZXRob2QgaXMgbm9uLXN0YXRpYyB0aGUgY29uc3RydWN0b3IKLSAgICogYXV0b21hdGljYWxseSBkZWNsYXJlcyBhIGxvY2FsIHZhcmlhYmxlIGAkdGhpcycgaW4gc2xvdCAwLiBUaGUKLSAgICogYWN0dWFsIGNvZGUgaXMgY29udGFpbmVkIGluIHRoZSBgaWwnIHBhcmFtZXRlciwgd2hpY2ggbWF5IGZ1cnRoZXIKLSAgICogbWFuaXB1bGF0ZWQgYnkgdGhlIHVzZXIuIEJ1dCBoZSBtdXN0IHRha2UgY2FyZSBub3QgdG8gcmVtb3ZlIGFueQotICAgKiBpbnN0cnVjdGlvbiAoaGFuZGxlcykgdGhhdCBhcmUgc3RpbGwgcmVmZXJlbmNlZCBmcm9tIHRoaXMgb2JqZWN0LgotICAgKgotICAgKiBGb3IgZXhhbXBsZSBvbmUgbWF5IG5vdCBhZGQgYSBsb2NhbCB2YXJpYWJsZSBhbmQgbGF0ZXIgcmVtb3ZlIHRoZQotICAgKiBpbnN0cnVjdGlvbnMgaXQgcmVmZXJzIHRvIHdpdGhvdXQgY2F1c2luZyBoYXZvYy4gSXQgaXMgc2FmZQotICAgKiBob3dldmVyIGlmIHlvdSByZW1vdmUgdGhhdCBsb2NhbCB2YXJpYWJsZSwgdG9vLgotICAgKgotICAgKiBAcGFyYW0gYWNjZXNzX2ZsYWdzIGFjY2VzcyBxdWFsaWZpZXJzCi0gICAqIEBwYXJhbSByZXR1cm5fdHlwZSAgbWV0aG9kIHR5cGUKLSAgICogQHBhcmFtIGFyZ190eXBlcyBhcmd1bWVudCB0eXBlcwotICAgKiBAcGFyYW0gYXJnX25hbWVzIGFyZ3VtZW50IG5hbWVzIChpZiB0aGlzIGlzIG51bGwsIGRlZmF1bHQgbmFtZXMgd2lsbCBiZSBwcm92aWRlZAotICAgKiBmb3IgdGhlbSkKLSAgICogQHBhcmFtIG1ldGhvZF9uYW1lIG5hbWUgb2YgbWV0aG9kCi0gICAqIEBwYXJhbSBjbGFzc19uYW1lIGNsYXNzIG5hbWUgY29udGFpbmluZyB0aGlzIG1ldGhvZCAobWF5IGJlIG51bGwsIGlmIHlvdSBkb24ndCBjYXJlKQotICAgKiBAcGFyYW0gaWwgaW5zdHJ1Y3Rpb24gbGlzdCBhc3NvY2lhdGVkIHdpdGggdGhpcyBtZXRob2QsIG1heSBiZSBudWxsIG9ubHkgZm9yCi0gICAqIGFic3RyYWN0IG9yIG5hdGl2ZSBtZXRob2RzCi0gICAqIEBwYXJhbSBjcCBjb25zdGFudCBwb29sCi0gICAqLwotICBwdWJsaWMgTWV0aG9kR2VuKGludCBhY2Nlc3NfZmxhZ3MsIFR5cGUgcmV0dXJuX3R5cGUsIFR5cGVbXSBhcmdfdHlwZXMsCi0gICAgICAgICAgICAgICAgICAgU3RyaW5nW10gYXJnX25hbWVzLCBTdHJpbmcgbWV0aG9kX25hbWUsIFN0cmluZyBjbGFzc19uYW1lLAotICAgICAgICAgICAgICAgICAgIEluc3RydWN0aW9uTGlzdCBpbCwgQ29uc3RhbnRQb29sR2VuIGNwKSB7Ci0gICAgc2V0QWNjZXNzRmxhZ3MoYWNjZXNzX2ZsYWdzKTsKLSAgICBzZXRUeXBlKHJldHVybl90eXBlKTsKLSAgICBzZXRBcmd1bWVudFR5cGVzKGFyZ190eXBlcyk7Ci0gICAgc2V0QXJndW1lbnROYW1lcyhhcmdfbmFtZXMpOwotICAgIHNldE5hbWUobWV0aG9kX25hbWUpOwotICAgIHNldENsYXNzTmFtZShjbGFzc19uYW1lKTsKLSAgICBzZXRJbnN0cnVjdGlvbkxpc3QoaWwpOwotICAgIHNldENvbnN0YW50UG9vbChjcCk7Ci0KLSAgICBib29sZWFuIGFic3RyYWN0XyA9IGlzQWJzdHJhY3QoKSB8fCBpc05hdGl2ZSgpOwotICAgIEluc3RydWN0aW9uSGFuZGxlIHN0YXJ0ID0gbnVsbDsKLSAgICBJbnN0cnVjdGlvbkhhbmRsZSBlbmQgICA9IG51bGw7Ci0KLSAgICBpZighYWJzdHJhY3RfKSB7Ci0gICAgICBzdGFydCA9IGlsLmdldFN0YXJ0KCk7Ci0gICAgICBlbmQgICA9IGlsLmdldEVuZCgpOwotCi0gICAgICAvKiBBZGQgbG9jYWwgdmFyaWFibGVzLCBuYW1lbHkgdGhlIGltcGxpY2l0IGB0aGlzJyBhbmQgdGhlIGFyZ3VtZW50cwotICAgICAgICovCi0gICAgICBpZighaXNTdGF0aWMoKSAmJiAoY2xhc3NfbmFtZSAhPSBudWxsKSkgeyAvLyBJbnN0YW5jZSBtZXRob2QgLT4gYHRoaXMnIGlzIGxvY2FsIHZhciAwCi0gICAgICAgIGFkZExvY2FsVmFyaWFibGUoInRoaXMiLCBuZXcgT2JqZWN0VHlwZShjbGFzc19uYW1lKSwgc3RhcnQsIGVuZCk7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgaWYoYXJnX3R5cGVzICE9IG51bGwpIHsKLSAgICAgIGludCBzaXplID0gYXJnX3R5cGVzLmxlbmd0aDsKLQotICAgICAgZm9yKGludCBpPTA7IGkgPCBzaXplOyBpKyspIHsKLSAgICAgICAgaWYoVHlwZS5WT0lEID09IGFyZ190eXBlc1tpXSkgewotICAgICAgICAgIHRocm93IG5ldyBDbGFzc0dlbkV4Y2VwdGlvbigiJ3ZvaWQnIGlzIGFuIGlsbGVnYWwgYXJndW1lbnQgdHlwZSBmb3IgYSBtZXRob2QiKTsKLSAgICAgICAgfQotICAgICAgfQotCi0gICAgICBpZihhcmdfbmFtZXMgIT0gbnVsbCkgeyAvLyBOYW1lcyBmb3IgdmFyaWFibGVzIHByb3ZpZGVkPwotICAgICAgICBpZihzaXplICE9IGFyZ19uYW1lcy5sZW5ndGgpCi0gICAgICAgICAgdGhyb3cgbmV3IENsYXNzR2VuRXhjZXB0aW9uKCJNaXNtYXRjaCBpbiBhcmd1bWVudCBhcnJheSBsZW5ndGhzOiAiICsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZSArICIgdnMuICIgKyBhcmdfbmFtZXMubGVuZ3RoKTsKLSAgICAgIH0gZWxzZSB7IC8vIEdpdmUgdGhlbSBkdW1teSBuYW1lcwotICAgICAgICBhcmdfbmFtZXMgPSBuZXcgU3RyaW5nW3NpemVdOwotCi0gICAgICAgIGZvcihpbnQgaT0wOyBpIDwgc2l6ZTsgaSsrKQotICAgICAgICAgIGFyZ19uYW1lc1tpXSA9ICJhcmciICsgaTsKLQotICAgICAgICBzZXRBcmd1bWVudE5hbWVzKGFyZ19uYW1lcyk7Ci0gICAgICB9Ci0KLSAgICAgIGlmKCFhYnN0cmFjdF8pIHsKLSAgICAgICAgZm9yKGludCBpPTA7IGkgPCBzaXplOyBpKyspIHsKLSAgICAgICAgICBhZGRMb2NhbFZhcmlhYmxlKGFyZ19uYW1lc1tpXSwgYXJnX3R5cGVzW2ldLCBzdGFydCwgZW5kKTsKLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBJbnN0YW50aWF0ZSBmcm9tIGV4aXN0aW5nIG1ldGhvZC4KLSAgICoKLSAgICogQHBhcmFtIG0gbWV0aG9kCi0gICAqIEBwYXJhbSBjbGFzc19uYW1lIGNsYXNzIG5hbWUgY29udGFpbmluZyB0aGlzIG1ldGhvZAotICAgKiBAcGFyYW0gY3AgY29uc3RhbnQgcG9vbAotICAgKi8KLSAgcHVibGljIE1ldGhvZEdlbihNZXRob2QgbSwgU3RyaW5nIGNsYXNzX25hbWUsIENvbnN0YW50UG9vbEdlbiBjcCkgewotICAgIHRoaXMobS5nZXRBY2Nlc3NGbGFncygpLCBUeXBlLmdldFJldHVyblR5cGUobS5nZXRTaWduYXR1cmUoKSksCi0gICAgICAgICBUeXBlLmdldEFyZ3VtZW50VHlwZXMobS5nZXRTaWduYXR1cmUoKSksIG51bGwgLyogbWF5IGJlIG92ZXJyaWRkZW4gYW55d2F5ICovLAotICAgICAgICAgbS5nZXROYW1lKCksIGNsYXNzX25hbWUsCi0gICAgICAgICAoKG0uZ2V0QWNjZXNzRmxhZ3MoKSAmIChDb25zdGFudHMuQUNDX0FCU1RSQUNUIHwgQ29uc3RhbnRzLkFDQ19OQVRJVkUpKSA9PSAwKT8KLSAgICAgICAgIG5ldyBJbnN0cnVjdGlvbkxpc3QobS5nZXRDb2RlKCkuZ2V0Q29kZSgpKSA6IG51bGwsCi0gICAgICAgICBjcCk7Ci0KLSAgICBBdHRyaWJ1dGVbXSBhdHRyaWJ1dGVzID0gbS5nZXRBdHRyaWJ1dGVzKCk7Ci0gICAgZm9yKGludCBpPTA7IGkgPCBhdHRyaWJ1dGVzLmxlbmd0aDsgaSsrKSB7Ci0gICAgICBBdHRyaWJ1dGUgYSA9IGF0dHJpYnV0ZXNbaV07Ci0KLSAgICAgIGlmKGEgaW5zdGFuY2VvZiBDb2RlKSB7Ci0gICAgICAgIENvZGUgYyA9IChDb2RlKWE7Ci0gICAgICAgIHNldE1heFN0YWNrKGMuZ2V0TWF4U3RhY2soKSk7Ci0gICAgICAgIHNldE1heExvY2FscyhjLmdldE1heExvY2FscygpKTsKLQotICAgICAgICBDb2RlRXhjZXB0aW9uW10gY2VzID0gYy5nZXRFeGNlcHRpb25UYWJsZSgpOwotCi0gICAgICAgIGlmKGNlcyAhPSBudWxsKSB7Ci0gICAgICAgICAgZm9yKGludCBqPTA7IGogPCBjZXMubGVuZ3RoOyBqKyspIHsKLSAgICAgICAgICAgIENvZGVFeGNlcHRpb24gY2UgICAgID0gY2VzW2pdOwotICAgICAgICAgICAgaW50ICAgICAgICAgICB0eXBlICAgPSBjZS5nZXRDYXRjaFR5cGUoKTsKLSAgICAgICAgICAgIE9iamVjdFR5cGUgICAgY190eXBlID0gbnVsbDsKLQotICAgICAgICAgICAgaWYodHlwZSA+IDApIHsKLSAgICAgICAgICAgICAgU3RyaW5nIGNlbiA9IG0uZ2V0Q29uc3RhbnRQb29sKCkuZ2V0Q29uc3RhbnRTdHJpbmcodHlwZSwgQ29uc3RhbnRzLkNPTlNUQU5UX0NsYXNzKTsKLSAgICAgICAgICAgICAgY190eXBlID0gbmV3IE9iamVjdFR5cGUoY2VuKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaW50IGVuZF9wYyA9IGNlLmdldEVuZFBDKCk7Ci0gICAgICAgICAgICBpbnQgbGVuZ3RoID0gbS5nZXRDb2RlKCkuZ2V0Q29kZSgpLmxlbmd0aDsKLQotICAgICAgICAgICAgSW5zdHJ1Y3Rpb25IYW5kbGUgZW5kOwotCi0gICAgICAgICAgICBpZihsZW5ndGggPT0gZW5kX3BjKSB7IC8vIE1heSBoYXBwZW4sIGJlY2F1c2UgZW5kX3BjIGlzIGV4Y2x1c2l2ZQotICAgICAgICAgICAgICBlbmQgPSBpbC5nZXRFbmQoKTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgIGVuZCA9IGlsLmZpbmRIYW5kbGUoZW5kX3BjKTsKLSAgICAgICAgICAgICAgZW5kID0gZW5kLmdldFByZXYoKTsgLy8gTWFrZSBpdCBpbmNsdXNpdmUKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgYWRkRXhjZXB0aW9uSGFuZGxlcihpbC5maW5kSGFuZGxlKGNlLmdldFN0YXJ0UEMoKSksIGVuZCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWwuZmluZEhhbmRsZShjZS5nZXRIYW5kbGVyUEMoKSksIGNfdHlwZSk7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgQXR0cmlidXRlW10gY19hdHRyaWJ1dGVzID0gYy5nZXRBdHRyaWJ1dGVzKCk7Ci0gICAgICAgIGZvcihpbnQgaj0wOyBqIDwgY19hdHRyaWJ1dGVzLmxlbmd0aDsgaisrKSB7Ci0gICAgICAgICAgYSA9IGNfYXR0cmlidXRlc1tqXTsKLQotICAgICAgICAgIGlmKGEgaW5zdGFuY2VvZiBMaW5lTnVtYmVyVGFibGUpIHsKLSAgICAgICAgICAgIExpbmVOdW1iZXJbXSBsbiA9ICgoTGluZU51bWJlclRhYmxlKWEpLmdldExpbmVOdW1iZXJUYWJsZSgpOwotCi0gICAgICAgICAgICBmb3IoaW50IGs9MDsgayA8IGxuLmxlbmd0aDsgaysrKSB7Ci0gICAgICAgICAgICAgIExpbmVOdW1iZXIgbCA9IGxuW2tdOwotICAgICAgICAgICAgICBhZGRMaW5lTnVtYmVyKGlsLmZpbmRIYW5kbGUobC5nZXRTdGFydFBDKCkpLCBsLmdldExpbmVOdW1iZXIoKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgfSBlbHNlIGlmKGEgaW5zdGFuY2VvZiBMb2NhbFZhcmlhYmxlVGFibGUpIHsKLSAgICAgICAgICAgIExvY2FsVmFyaWFibGVbXSBsdiA9ICgoTG9jYWxWYXJpYWJsZVRhYmxlKWEpLmdldExvY2FsVmFyaWFibGVUYWJsZSgpOwotCi0gICAgICAgICAgICByZW1vdmVMb2NhbFZhcmlhYmxlcygpOwotCi0gICAgICAgICAgICBmb3IoaW50IGs9MDsgayA8IGx2Lmxlbmd0aDsgaysrKSB7Ci0gICAgICAgICAgICAgIExvY2FsVmFyaWFibGUgICAgIGwgICAgID0gbHZba107Ci0gICAgICAgICAgICAgIEluc3RydWN0aW9uSGFuZGxlIHN0YXJ0ID0gaWwuZmluZEhhbmRsZShsLmdldFN0YXJ0UEMoKSk7Ci0gICAgICAgICAgICAgIEluc3RydWN0aW9uSGFuZGxlIGVuZCAgID0gaWwuZmluZEhhbmRsZShsLmdldFN0YXJ0UEMoKSArIGwuZ2V0TGVuZ3RoKCkpOwotCi0gICAgICAgICAgICAgIC8vIFJlcGFpciBtYWxmb3JtZWQgaGFuZGxlcwotICAgICAgICAgICAgICBpZihudWxsID09IHN0YXJ0KSB7Ci0gICAgICAgICAgICAgICAgc3RhcnQgPSBpbC5nZXRTdGFydCgpOwotICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgaWYobnVsbCA9PSBlbmQpIHsKLSAgICAgICAgICAgICAgICBlbmQgPSBpbC5nZXRFbmQoKTsKLSAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgIGFkZExvY2FsVmFyaWFibGUobC5nZXROYW1lKCksIFR5cGUuZ2V0VHlwZShsLmdldFNpZ25hdHVyZSgpKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsLmdldEluZGV4KCksIHN0YXJ0LCBlbmQpOwotICAgICAgICAgICAgfQotICAgICAgICAgIH0gZWxzZSBpZiAoYSBpbnN0YW5jZW9mIExvY2FsVmFyaWFibGVUeXBlVGFibGUpIHsKLSAgICAgICAgICAgICBMb2NhbFZhcmlhYmxlW10gbHYgPSAoKExvY2FsVmFyaWFibGVUeXBlVGFibGUpIGEpLmdldExvY2FsVmFyaWFibGVUeXBlVGFibGUoKTsKLSAgICAgICAgICAgICByZW1vdmVMb2NhbFZhcmlhYmxlVHlwZXMoKTsKLSAgICAgICAgICAgICBmb3IgKGludCBrID0gMDsgayA8IGx2Lmxlbmd0aDsgaysrKSB7Ci0gICAgICAgICAgICAgICAgIExvY2FsVmFyaWFibGUgbCA9IGx2W2tdOwotICAgICAgICAgICAgICAgICBJbnN0cnVjdGlvbkhhbmRsZSBzdGFydCA9IGlsLmZpbmRIYW5kbGUobC5nZXRTdGFydFBDKCkpOwotICAgICAgICAgICAgICAgICBJbnN0cnVjdGlvbkhhbmRsZSBlbmQgPSBpbC5maW5kSGFuZGxlKGwuZ2V0U3RhcnRQQygpICsgbC5nZXRMZW5ndGgoKSk7Ci0gICAgICAgICAgICAgICAgIC8vIFJlcGFpciBtYWxmb3JtZWQgaGFuZGxlcwotICAgICAgICAgICAgICAgICBpZiAobnVsbCA9PSBzdGFydCkgewotICAgICAgICAgICAgICAgICAgICAgc3RhcnQgPSBpbC5nZXRTdGFydCgpOwotICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgIGlmIChudWxsID09IGVuZCkgewotICAgICAgICAgICAgICAgICAgICAgZW5kID0gaWwuZ2V0RW5kKCk7Ci0gICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgYWRkTG9jYWxWYXJpYWJsZVR5cGUobC5nZXROYW1lKCksIFR5cGUuZ2V0VHlwZShsLmdldFNpZ25hdHVyZSgpKSwgbAotICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRJbmRleCgpLCBzdGFydCwgZW5kKTsKLSAgICAgICAgICAgICAgfQotICAgICAgICAgIH0gZWxzZQotICAgICAgICAgICAgYWRkQ29kZUF0dHJpYnV0ZShhKTsKLSAgICAgICAgfQotICAgICAgfSBlbHNlIGlmKGEgaW5zdGFuY2VvZiBFeGNlcHRpb25UYWJsZSkgewotICAgICAgICBTdHJpbmdbXSBuYW1lcyA9ICgoRXhjZXB0aW9uVGFibGUpYSkuZ2V0RXhjZXB0aW9uTmFtZXMoKTsKLSAgICAgICAgZm9yKGludCBqPTA7IGogPCBuYW1lcy5sZW5ndGg7IGorKykKLSAgICAgICAgICBhZGRFeGNlcHRpb24obmFtZXNbal0pOwotICAgICAgfSBlbHNlCi0gICAgICAgIGFkZEF0dHJpYnV0ZShhKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogQWRkcyBhIGxvY2FsIHZhcmlhYmxlIHRvIHRoaXMgbWV0aG9kLgotICAgKgotICAgKiBAcGFyYW0gbmFtZSB2YXJpYWJsZSBuYW1lCi0gICAqIEBwYXJhbSB0eXBlIHZhcmlhYmxlIHR5cGUKLSAgICogQHBhcmFtIHNsb3QgdGhlIGluZGV4IG9mIHRoZSBsb2NhbCB2YXJpYWJsZSwgaWYgdHlwZSBpcyBsb25nIG9yIGRvdWJsZSwgdGhlIG5leHQgYXZhaWxhYmxlCi0gICAqIGluZGV4IGlzIHNsb3QrMgotICAgKiBAcGFyYW0gc3RhcnQgZnJvbSB3aGVyZSB0aGUgdmFyaWFibGUgaXMgdmFsaWQKLSAgICogQHBhcmFtIGVuZCB1bnRpbCB3aGVyZSB0aGUgdmFyaWFibGUgaXMgdmFsaWQKLSAgICogQHJldHVybiBuZXcgbG9jYWwgdmFyaWFibGUgb2JqZWN0Ci0gICAqIEBzZWUgTG9jYWxWYXJpYWJsZQotICAgKi8KLSAgcHVibGljIExvY2FsVmFyaWFibGVHZW4gYWRkTG9jYWxWYXJpYWJsZShTdHJpbmcgbmFtZSwgVHlwZSB0eXBlLCBpbnQgc2xvdCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbnN0cnVjdGlvbkhhbmRsZSBzdGFydCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbnN0cnVjdGlvbkhhbmRsZSBlbmQpIHsKLSAgICBieXRlIHQgPSB0eXBlLmdldFR5cGUoKTsKLQotICAgIGlmKHQgIT0gQ29uc3RhbnRzLlRfQUREUkVTUykgewotICAgICAgaW50ICBhZGQgPSB0eXBlLmdldFNpemUoKTsKLQotICAgICAgaWYoc2xvdCArIGFkZCA+IG1heF9sb2NhbHMpCi0gICAgICAgIG1heF9sb2NhbHMgPSBzbG90ICsgYWRkOwotCi0gICAgICBMb2NhbFZhcmlhYmxlR2VuIGwgPSBuZXcgTG9jYWxWYXJpYWJsZUdlbihzbG90LCBuYW1lLCB0eXBlLCBzdGFydCwgZW5kKTsKLSAgICAgIGludCBpOwotCi0gICAgICBpZigoaSA9IHZhcmlhYmxlX3ZlYy5pbmRleE9mKGwpKSA+PSAwKSAvLyBPdmVyd3JpdGUgaWYgbmVjZXNzYXJ5Ci0gICAgICAgIHZhcmlhYmxlX3ZlYy5zZXQoaSwgbCk7Ci0gICAgICBlbHNlCi0gICAgICAgIHZhcmlhYmxlX3ZlYy5hZGQobCk7Ci0KLSAgICAgIHJldHVybiBsOwotICAgIH0gZWxzZSB7Ci0gICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJDYW4gbm90IHVzZSAiICsgdHlwZSArCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgYXMgdHlwZSBmb3IgbG9jYWwgdmFyaWFibGUiKTsKLQotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBBZGRzIGEgbG9jYWwgdmFyaWFibGUgdG8gdGhpcyBtZXRob2QgYW5kIGFzc2lnbnMgYW4gaW5kZXggYXV0b21hdGljYWxseS4KLSAgICoKLSAgICogQHBhcmFtIG5hbWUgdmFyaWFibGUgbmFtZQotICAgKiBAcGFyYW0gdHlwZSB2YXJpYWJsZSB0eXBlCi0gICAqIEBwYXJhbSBzdGFydCBmcm9tIHdoZXJlIHRoZSB2YXJpYWJsZSBpcyB2YWxpZCwgaWYgdGhpcyBpcyBudWxsLAotICAgKiBpdCBpcyB2YWxpZCBmcm9tIHRoZSBzdGFydAotICAgKiBAcGFyYW0gZW5kIHVudGlsIHdoZXJlIHRoZSB2YXJpYWJsZSBpcyB2YWxpZCwgaWYgdGhpcyBpcyBudWxsLAotICAgKiBpdCBpcyB2YWxpZCB0byB0aGUgZW5kCi0gICAqIEByZXR1cm4gbmV3IGxvY2FsIHZhcmlhYmxlIG9iamVjdAotICAgKiBAc2VlIExvY2FsVmFyaWFibGUKLSAgICovCi0gIHB1YmxpYyBMb2NhbFZhcmlhYmxlR2VuIGFkZExvY2FsVmFyaWFibGUoU3RyaW5nIG5hbWUsIFR5cGUgdHlwZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbnN0cnVjdGlvbkhhbmRsZSBzdGFydCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbnN0cnVjdGlvbkhhbmRsZSBlbmQpIHsKLSAgICByZXR1cm4gYWRkTG9jYWxWYXJpYWJsZShuYW1lLCB0eXBlLCBtYXhfbG9jYWxzLCBzdGFydCwgZW5kKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZW1vdmUgYSBsb2NhbCB2YXJpYWJsZSwgaXRzIHNsb3Qgd2lsbCBub3QgYmUgcmV1c2VkLCBpZiB5b3UgZG8gbm90IHVzZSBhZGRMb2NhbFZhcmlhYmxlCi0gICAqIHdpdGggYW4gZXhwbGljaXQgaW5kZXggYXJndW1lbnQuCi0gICAqLwotICBwdWJsaWMgdm9pZCByZW1vdmVMb2NhbFZhcmlhYmxlKExvY2FsVmFyaWFibGVHZW4gbCkgewotICAgIHZhcmlhYmxlX3ZlYy5yZW1vdmUobCk7Ci0gIH0KLQotICAvKioKLSAgICogUmVtb3ZlIGFsbCBsb2NhbCB2YXJpYWJsZXMuCi0gICAqLwotICBwdWJsaWMgdm9pZCByZW1vdmVMb2NhbFZhcmlhYmxlcygpIHsKLSAgICB2YXJpYWJsZV92ZWMuY2xlYXIoKTsKLSAgfQotCi0gIC8qKgotICAgKiBTb3J0IGxvY2FsIHZhcmlhYmxlcyBieSBpbmRleAotICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgdm9pZCBzb3J0KExvY2FsVmFyaWFibGVHZW5bXSB2YXJzLCBpbnQgbCwgaW50IHIpIHsKLSAgICBpbnQgaSA9IGwsIGogPSByOwotICAgIGludCBtID0gdmFyc1sobCArIHIpIC8gMl0uZ2V0SW5kZXgoKTsKLSAgICBMb2NhbFZhcmlhYmxlR2VuIGg7Ci0KLSAgICBkbyB7Ci0gICAgICB3aGlsZSh2YXJzW2ldLmdldEluZGV4KCkgPCBtKSBpKys7Ci0gICAgICB3aGlsZShtIDwgdmFyc1tqXS5nZXRJbmRleCgpKSBqLS07Ci0KLSAgICAgIGlmKGkgPD0gaikgewotICAgICAgICBoPXZhcnNbaV07IHZhcnNbaV09dmFyc1tqXTsgdmFyc1tqXT1oOyAvLyBTd2FwIGVsZW1lbnRzCi0gICAgICAgIGkrKzsgai0tOwotICAgICAgfQotICAgIH0gd2hpbGUoaSA8PSBqKTsKLQotICAgIGlmKGwgPCBqKSBzb3J0KHZhcnMsIGwsIGopOwotICAgIGlmKGkgPCByKSBzb3J0KHZhcnMsIGksIHIpOwotICB9Ci0KLSAgLyoKLSAgICogSWYgdGhlIHJhbmdlIG9mIHRoZSB2YXJpYWJsZSBoYXMgbm90IGJlZW4gc2V0IHlldCwgaXQgd2lsbCBiZSBzZXQgdG8gYmUgdmFsaWQgZnJvbQotICAgKiB0aGUgc3RhcnQgdG8gdGhlIGVuZCBvZiB0aGUgaW5zdHJ1Y3Rpb24gbGlzdC4KLSAgICoKLSAgICogQHJldHVybiBhcnJheSBvZiBkZWNsYXJlZCBsb2NhbCB2YXJpYWJsZXMgc29ydGVkIGJ5IGluZGV4Ci0gICAqLwotICBwdWJsaWMgTG9jYWxWYXJpYWJsZUdlbltdIGdldExvY2FsVmFyaWFibGVzKCkgewotICAgIGludCAgICAgICAgICAgICAgICBzaXplID0gdmFyaWFibGVfdmVjLnNpemUoKTsKLSAgICBMb2NhbFZhcmlhYmxlR2VuW10gbGcgICA9IG5ldyBMb2NhbFZhcmlhYmxlR2VuW3NpemVdOwotICAgIHZhcmlhYmxlX3ZlYy50b0FycmF5KGxnKTsKLQotICAgIGZvcihpbnQgaT0wOyBpIDwgc2l6ZTsgaSsrKSB7Ci0gICAgICBpZihsZ1tpXS5nZXRTdGFydCgpID09IG51bGwpCi0gICAgICAgIGxnW2ldLnNldFN0YXJ0KGlsLmdldFN0YXJ0KCkpOwotCi0gICAgICBpZihsZ1tpXS5nZXRFbmQoKSA9PSBudWxsKQotICAgICAgICBsZ1tpXS5zZXRFbmQoaWwuZ2V0RW5kKCkpOwotICAgIH0KLQotICAgIGlmKHNpemUgPiAxKQotICAgICAgc29ydChsZywgMCwgc2l6ZSAtIDEpOwotCi0gICAgcmV0dXJuIGxnOwotICB9Ci0KLSAgLyoKLSAgICogSWYgdGhlIHJhbmdlIG9mIHRoZSB2YXJpYWJsZSBoYXMgbm90IGJlZW4gc2V0IHlldCwgaXQgd2lsbCBiZSBzZXQgdG8gYmUKLSAgICogdmFsIGlkIGZyb20gdGhlIHN0YXJ0IHRvIHRoZSBlbmQgb2YgdGhlIGluc3RydWN0aW9uIGxpc3QuCi0gICAqCi0gICAqIEByZXR1cm4gYXJyYXkgb2YgZGVjbGFyZWQgbG9jYWwgdmFyaWFibGUgdHlwZXMgc29ydGVkIGJ5IGluZGV4Ci0gICAqLwotICBwcml2YXRlIExvY2FsVmFyaWFibGVHZW5bXSBnZXRMb2NhbFZhcmlhYmxlVHlwZXMoKSB7Ci0gICAgaW50ICAgICAgICAgICAgICAgIHNpemUgPSB0eXBlX3ZlYy5zaXplKCk7Ci0gICAgTG9jYWxWYXJpYWJsZUdlbltdIGxnICAgPSBuZXcgTG9jYWxWYXJpYWJsZUdlbltzaXplXTsKLSAgICB0eXBlX3ZlYy50b0FycmF5KGxnKTsKLQotICAgIGZvcihpbnQgaT0wOyBpIDwgc2l6ZTsgaSsrKSB7Ci0gICAgICBpZihsZ1tpXS5nZXRTdGFydCgpID09IG51bGwpCi0gICAgICAgIGxnW2ldLnNldFN0YXJ0KGlsLmdldFN0YXJ0KCkpOwotCi0gICAgICBpZihsZ1tpXS5nZXRFbmQoKSA9PSBudWxsKQotICAgICAgICBsZ1tpXS5zZXRFbmQoaWwuZ2V0RW5kKCkpOwotICAgIH0KLQotICAgIGlmKHNpemUgPiAxKQotICAgICAgc29ydChsZywgMCwgc2l6ZSAtIDEpOwotCi0gICAgcmV0dXJuIGxnOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gYExvY2FsVmFyaWFibGVUYWJsZScgYXR0cmlidXRlIG9mIGFsbCB0aGUgbG9jYWwgdmFyaWFibGVzIG9mIHRoaXMgbWV0aG9kLgotICAgKi8KLSAgcHVibGljIExvY2FsVmFyaWFibGVUYWJsZSBnZXRMb2NhbFZhcmlhYmxlVGFibGUoQ29uc3RhbnRQb29sR2VuIGNwKSB7Ci0gICAgTG9jYWxWYXJpYWJsZUdlbltdIGxnICAgPSBnZXRMb2NhbFZhcmlhYmxlcygpOwotICAgIGludCAgICAgICAgICAgICAgICBzaXplID0gbGcubGVuZ3RoOwotICAgIExvY2FsVmFyaWFibGVbXSAgICBsdiAgID0gbmV3IExvY2FsVmFyaWFibGVbc2l6ZV07Ci0KLSAgICBmb3IoaW50IGk9MDsgaSA8IHNpemU7IGkrKykKLSAgICAgIGx2W2ldID0gbGdbaV0uZ2V0TG9jYWxWYXJpYWJsZShjcCk7Ci0KLSAgICByZXR1cm4gbmV3IExvY2FsVmFyaWFibGVUYWJsZShjcC5hZGRVdGY4KCJMb2NhbFZhcmlhYmxlVGFibGUiKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAyICsgbHYubGVuZ3RoICogMTAsIGx2LCBjcC5nZXRDb25zdGFudFBvb2woKSk7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBgTG9jYWxWYXJpYWJsZVR5cGVUYWJsZScgYXR0cmlidXRlIG9mIGFsbCB0aGUgbG9jYWwgdmFyaWFibGUKLSAgICogdHlwZXMgb2YgdGhpcyBtZXRob2QuCi0gICAqLwotICBwdWJsaWMgTG9jYWxWYXJpYWJsZVR5cGVUYWJsZSBnZXRMb2NhbFZhcmlhYmxlVHlwZVRhYmxlKENvbnN0YW50UG9vbEdlbiBjcCkgewotICAgIExvY2FsVmFyaWFibGVHZW5bXSBsZyAgID0gZ2V0TG9jYWxWYXJpYWJsZVR5cGVzKCk7Ci0gICAgaW50ICAgICAgICAgICAgICAgIHNpemUgPSBsZy5sZW5ndGg7Ci0gICAgTG9jYWxWYXJpYWJsZVtdICAgIGx2ICAgPSBuZXcgTG9jYWxWYXJpYWJsZVtzaXplXTsKLQotICAgIGZvcihpbnQgaT0wOyBpIDwgc2l6ZTsgaSsrKQotICAgICAgbHZbaV0gPSBsZ1tpXS5nZXRMb2NhbFZhcmlhYmxlKGNwKTsKLQotICAgIHJldHVybiBuZXcgTG9jYWxWYXJpYWJsZVR5cGVUYWJsZShjcC5hZGRVdGY4KCJMb2NhbFZhcmlhYmxlVHlwZVRhYmxlIiksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMiArIGx2Lmxlbmd0aCAqIDEwLCBsdiwgY3AuZ2V0Q29uc3RhbnRQb29sKCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIEFkZHMgYSBsb2NhbCB2YXJpYWJsZSB0eXBlIHRvIHRoaXMgbWV0aG9kLgotICAgKgotICAgKiBAcGFyYW0gbmFtZSB2YXJpYWJsZSBuYW1lCi0gICAqIEBwYXJhbSB0eXBlIHZhcmlhYmxlIHR5cGUKLSAgICogQHBhcmFtIHNsb3QgdGhlIGluZGV4IG9mIHRoZSBsb2NhbCB2YXJpYWJsZSwgaWYgdHlwZSBpcyBsb25nIG9yIGRvdWJsZSwgdGhlIG5leHQgYXZhaWxhYmxlCi0gICAqIGluZGV4IGlzIHNsb3QrMgotICAgKiBAcGFyYW0gc3RhcnQgZnJvbSB3aGVyZSB0aGUgdmFyaWFibGUgaXMgdmFsaWQKLSAgICogQHBhcmFtIGVuZCB1bnRpbCB3aGVyZSB0aGUgdmFyaWFibGUgaXMgdmFsaWQKLSAgICogQHJldHVybiBuZXcgbG9jYWwgdmFyaWFibGUgb2JqZWN0Ci0gICAqIEBzZWUgTG9jYWxWYXJpYWJsZQotICAgKi8KLSAgcHJpdmF0ZSBMb2NhbFZhcmlhYmxlR2VuIGFkZExvY2FsVmFyaWFibGVUeXBlKFN0cmluZyBuYW1lLCBUeXBlIHR5cGUsIGludCBzbG90LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluc3RydWN0aW9uSGFuZGxlIHN0YXJ0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluc3RydWN0aW9uSGFuZGxlIGVuZCkgewotICAgIGJ5dGUgdCA9IHR5cGUuZ2V0VHlwZSgpOwotCi0gICAgaWYodCAhPSBDb25zdGFudHMuVF9BRERSRVNTKSB7Ci0gICAgICBpbnQgIGFkZCA9IHR5cGUuZ2V0U2l6ZSgpOwotCi0gICAgICBpZihzbG90ICsgYWRkID4gbWF4X2xvY2FscykKLSAgICAgICAgbWF4X2xvY2FscyA9IHNsb3QgKyBhZGQ7Ci0KLSAgICAgIExvY2FsVmFyaWFibGVHZW4gbCA9IG5ldyBMb2NhbFZhcmlhYmxlR2VuKHNsb3QsIG5hbWUsIHR5cGUsIHN0YXJ0LCBlbmQpOwotICAgICAgaW50IGk7Ci0KLSAgICAgIGlmKChpID0gdHlwZV92ZWMuaW5kZXhPZihsKSkgPj0gMCkgLy8gT3ZlcndyaXRlIGlmIG5lY2Vzc2FyeQotICAgICAgICB0eXBlX3ZlYy5zZXQoaSwgbCk7Ci0gICAgICBlbHNlCi0gICAgICAgIHR5cGVfdmVjLmFkZChsKTsKLQotICAgICAgcmV0dXJuIGw7Ci0gICAgfSBlbHNlIHsKLSAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkNhbiBub3QgdXNlICIgKyB0eXBlICsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiBhcyB0eXBlIGZvciBsb2NhbCB2YXJpYWJsZSIpOwotCi0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFJlbW92ZSBhbGwgbG9jYWwgdmFyaWFibGUgdHlwZXMuCi0gICAqLwotICBwcml2YXRlIHZvaWQgcmVtb3ZlTG9jYWxWYXJpYWJsZVR5cGVzKCkgewotICAgIHR5cGVfdmVjLmNsZWFyKCk7Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZSBhbiBpbnN0cnVjdGlvbiBhIGxpbmUgbnVtYmVyIGNvcnJlc3BvbmRpbmcgdG8gdGhlIHNvdXJjZSBjb2RlIGxpbmUuCi0gICAqCi0gICAqIEBwYXJhbSBpaCBpbnN0cnVjdGlvbiB0byB0YWcKLSAgICogQHJldHVybiBuZXcgbGluZSBudW1iZXIgb2JqZWN0Ci0gICAqIEBzZWUgTGluZU51bWJlcgotICAgKi8KLSAgcHVibGljIExpbmVOdW1iZXJHZW4gYWRkTGluZU51bWJlcihJbnN0cnVjdGlvbkhhbmRsZSBpaCwgaW50IHNyY19saW5lKSB7Ci0gICAgTGluZU51bWJlckdlbiBsID0gbmV3IExpbmVOdW1iZXJHZW4oaWgsIHNyY19saW5lKTsKLSAgICBsaW5lX251bWJlcl92ZWMuYWRkKGwpOwotICAgIHJldHVybiBsOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlbW92ZSBhIGxpbmUgbnVtYmVyLgotICAgKi8KLSAgcHVibGljIHZvaWQgcmVtb3ZlTGluZU51bWJlcihMaW5lTnVtYmVyR2VuIGwpIHsKLSAgICBsaW5lX251bWJlcl92ZWMucmVtb3ZlKGwpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlbW92ZSBhbGwgbGluZSBudW1iZXJzLgotICAgKi8KLSAgcHVibGljIHZvaWQgcmVtb3ZlTGluZU51bWJlcnMoKSB7Ci0gICAgbGluZV9udW1iZXJfdmVjLmNsZWFyKCk7Ci0gIH0KLQotICAvKgotICAgKiBAcmV0dXJuIGFycmF5IG9mIGxpbmUgbnVtYmVycwotICAgKi8KLSAgcHVibGljIExpbmVOdW1iZXJHZW5bXSBnZXRMaW5lTnVtYmVycygpIHsKLSAgICBMaW5lTnVtYmVyR2VuW10gbGcgPSBuZXcgTGluZU51bWJlckdlbltsaW5lX251bWJlcl92ZWMuc2l6ZSgpXTsKLSAgICBsaW5lX251bWJlcl92ZWMudG9BcnJheShsZyk7Ci0gICAgcmV0dXJuIGxnOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gYExpbmVOdW1iZXJUYWJsZScgYXR0cmlidXRlIG9mIGFsbCB0aGUgbG9jYWwgdmFyaWFibGVzIG9mIHRoaXMgbWV0aG9kLgotICAgKi8KLSAgcHVibGljIExpbmVOdW1iZXJUYWJsZSBnZXRMaW5lTnVtYmVyVGFibGUoQ29uc3RhbnRQb29sR2VuIGNwKSB7Ci0gICAgaW50ICAgICAgICAgIHNpemUgPSBsaW5lX251bWJlcl92ZWMuc2l6ZSgpOwotICAgIExpbmVOdW1iZXJbXSBsbiAgID0gbmV3IExpbmVOdW1iZXJbc2l6ZV07Ci0KLSAgICB0cnkgewotICAgICAgZm9yKGludCBpPTA7IGkgPCBzaXplOyBpKyspCi0gICAgICAgIGxuW2ldID0gKChMaW5lTnVtYmVyR2VuKWxpbmVfbnVtYmVyX3ZlYy5nZXQoaSkpLmdldExpbmVOdW1iZXIoKTsKLSAgICB9IGNhdGNoKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7fSAvLyBOZXZlciBvY2N1cnMKLQotICAgIHJldHVybiBuZXcgTGluZU51bWJlclRhYmxlKGNwLmFkZFV0ZjgoIkxpbmVOdW1iZXJUYWJsZSIpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDIgKyBsbi5sZW5ndGggKiA0LCBsbiwgY3AuZ2V0Q29uc3RhbnRQb29sKCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIEFkZCBhbiBleGNlcHRpb24gaGFuZGxlciwgaS5lLiwgc3BlY2lmeSByZWdpb24gd2hlcmUgYSBoYW5kbGVyIGlzIGFjdGl2ZSBhbmQgYW4KLSAgICogaW5zdHJ1Y3Rpb24gd2hlcmUgdGhlIGFjdHVhbCBoYW5kbGluZyBpcyBkb25lLgotICAgKgotICAgKiBAcGFyYW0gc3RhcnRfcGMgU3RhcnQgb2YgcmVnaW9uIChpbmNsdXNpdmUpCi0gICAqIEBwYXJhbSBlbmRfcGMgRW5kIG9mIHJlZ2lvbiAoaW5jbHVzaXZlKQotICAgKiBAcGFyYW0gaGFuZGxlcl9wYyBXaGVyZSBoYW5kbGluZyBpcyBkb25lCi0gICAqIEBwYXJhbSBjYXRjaF90eXBlIGNsYXNzIHR5cGUgb2YgaGFuZGxlZCBleGNlcHRpb24gb3IgbnVsbCBpZiBhbnkKLSAgICogZXhjZXB0aW9uIGlzIGhhbmRsZWQKLSAgICogQHJldHVybiBuZXcgZXhjZXB0aW9uIGhhbmRsZXIgb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgQ29kZUV4Y2VwdGlvbkdlbiBhZGRFeGNlcHRpb25IYW5kbGVyKEluc3RydWN0aW9uSGFuZGxlIHN0YXJ0X3BjLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluc3RydWN0aW9uSGFuZGxlIGVuZF9wYywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbnN0cnVjdGlvbkhhbmRsZSBoYW5kbGVyX3BjLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9iamVjdFR5cGUgY2F0Y2hfdHlwZSkgewotICAgIGlmKChzdGFydF9wYyA9PSBudWxsKSB8fCAoZW5kX3BjID09IG51bGwpIHx8IChoYW5kbGVyX3BjID09IG51bGwpKQotICAgICAgdGhyb3cgbmV3IENsYXNzR2VuRXhjZXB0aW9uKCJFeGNlcHRpb24gaGFuZGxlciB0YXJnZXQgaXMgbnVsbCBpbnN0cnVjdGlvbiIpOwotCi0gICAgQ29kZUV4Y2VwdGlvbkdlbiBjID0gbmV3IENvZGVFeGNlcHRpb25HZW4oc3RhcnRfcGMsIGVuZF9wYywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVyX3BjLCBjYXRjaF90eXBlKTsKLSAgICBleGNlcHRpb25fdmVjLmFkZChjKTsKLSAgICByZXR1cm4gYzsKLSAgfQotCi0gIC8qKgotICAgKiBSZW1vdmUgYW4gZXhjZXB0aW9uIGhhbmRsZXIuCi0gICAqLwotICBwdWJsaWMgdm9pZCByZW1vdmVFeGNlcHRpb25IYW5kbGVyKENvZGVFeGNlcHRpb25HZW4gYykgewotICAgIGV4Y2VwdGlvbl92ZWMucmVtb3ZlKGMpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlbW92ZSBhbGwgbGluZSBudW1iZXJzLgotICAgKi8KLSAgcHVibGljIHZvaWQgcmVtb3ZlRXhjZXB0aW9uSGFuZGxlcnMoKSB7Ci0gICAgZXhjZXB0aW9uX3ZlYy5jbGVhcigpOwotICB9Ci0KLSAgLyoKLSAgICogQHJldHVybiBhcnJheSBvZiBkZWNsYXJlZCBleGNlcHRpb24gaGFuZGxlcnMKLSAgICovCi0gIHB1YmxpYyBDb2RlRXhjZXB0aW9uR2VuW10gZ2V0RXhjZXB0aW9uSGFuZGxlcnMoKSB7Ci0gICAgQ29kZUV4Y2VwdGlvbkdlbltdIGNnICAgPSBuZXcgQ29kZUV4Y2VwdGlvbkdlbltleGNlcHRpb25fdmVjLnNpemUoKV07Ci0gICAgZXhjZXB0aW9uX3ZlYy50b0FycmF5KGNnKTsKLSAgICByZXR1cm4gY2c7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBjb2RlIGV4Y2VwdGlvbnMgZm9yIGBDb2RlJyBhdHRyaWJ1dGUKLSAgICovCi0gIHByaXZhdGUgQ29kZUV4Y2VwdGlvbltdIGdldENvZGVFeGNlcHRpb25zKCkgewotICAgIGludCAgICAgICAgICAgICBzaXplICA9IGV4Y2VwdGlvbl92ZWMuc2l6ZSgpOwotICAgIENvZGVFeGNlcHRpb25bXSBjX2V4YyA9IG5ldyBDb2RlRXhjZXB0aW9uW3NpemVdOwotCi0gICAgdHJ5IHsKLSAgICAgIGZvcihpbnQgaT0wOyBpIDwgc2l6ZTsgaSsrKSB7Ci0gICAgICAgIENvZGVFeGNlcHRpb25HZW4gYyA9IChDb2RlRXhjZXB0aW9uR2VuKWV4Y2VwdGlvbl92ZWMuZ2V0KGkpOwotICAgICAgICBjX2V4Y1tpXSA9IGMuZ2V0Q29kZUV4Y2VwdGlvbihjcCk7Ci0gICAgICB9Ci0gICAgfSBjYXRjaChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkge30KLQotICAgIHJldHVybiBjX2V4YzsKLSAgfQotCi0gIC8qKgotICAgKiBBZGQgYW4gZXhjZXB0aW9uIHBvc3NpYmx5IHRocm93biBieSB0aGlzIG1ldGhvZC4KLSAgICoKLSAgICogQHBhcmFtIGNsYXNzX25hbWUgKGZ1bGx5IHF1YWxpZmllZCkgbmFtZSBvZiBleGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGFkZEV4Y2VwdGlvbihTdHJpbmcgY2xhc3NfbmFtZSkgewotICAgIHRocm93c192ZWMuYWRkKGNsYXNzX25hbWUpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlbW92ZSBhbiBleGNlcHRpb24uCi0gICAqLwotICBwdWJsaWMgdm9pZCByZW1vdmVFeGNlcHRpb24oU3RyaW5nIGMpIHsKLSAgICB0aHJvd3NfdmVjLnJlbW92ZShjKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZW1vdmUgYWxsIGV4Y2VwdGlvbnMuCi0gICAqLwotICBwdWJsaWMgdm9pZCByZW1vdmVFeGNlcHRpb25zKCkgewotICAgIHRocm93c192ZWMuY2xlYXIoKTsKLSAgfQotCi0gIC8qCi0gICAqIEByZXR1cm4gYXJyYXkgb2YgdGhyb3duIGV4Y2VwdGlvbnMKLSAgICovCi0gIHB1YmxpYyBTdHJpbmdbXSBnZXRFeGNlcHRpb25zKCkgewotICAgIFN0cmluZ1tdIGUgPSBuZXcgU3RyaW5nW3Rocm93c192ZWMuc2l6ZSgpXTsKLSAgICB0aHJvd3NfdmVjLnRvQXJyYXkoZSk7Ci0gICAgcmV0dXJuIGU7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBgRXhjZXB0aW9ucycgYXR0cmlidXRlIG9mIGFsbCB0aGUgZXhjZXB0aW9ucyB0aHJvd24gYnkgdGhpcyBtZXRob2QuCi0gICAqLwotICBwcml2YXRlIEV4Y2VwdGlvblRhYmxlIGdldEV4Y2VwdGlvblRhYmxlKENvbnN0YW50UG9vbEdlbiBjcCkgewotICAgIGludCAgIHNpemUgPSB0aHJvd3NfdmVjLnNpemUoKTsKLSAgICBpbnRbXSBleCAgID0gbmV3IGludFtzaXplXTsKLQotICAgIHRyeSB7Ci0gICAgICBmb3IoaW50IGk9MDsgaSA8IHNpemU7IGkrKykKLSAgICAgICAgZXhbaV0gPSBjcC5hZGRDbGFzcygoU3RyaW5nKXRocm93c192ZWMuZ2V0KGkpKTsKLSAgICB9IGNhdGNoKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7fQotCi0gICAgcmV0dXJuIG5ldyBFeGNlcHRpb25UYWJsZShjcC5hZGRVdGY4KCJFeGNlcHRpb25zIiksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAyICsgMiAqIHNpemUsIGV4LCBjcC5nZXRDb25zdGFudFBvb2woKSk7Ci0gIH0KLQotICAvKioKLSAgICogQWRkIGFuIGF0dHJpYnV0ZSB0byB0aGUgY29kZS4gQ3VycmVudGx5LCB0aGUgSlZNIGtub3dzIGFib3V0IHRoZQotICAgKiBMaW5lTnVtYmVyVGFibGUsIExvY2FsVmFyaWFibGVUYWJsZSBhbmQgU3RhY2tNYXAgYXR0cmlidXRlcywKLSAgICogd2hlcmUgdGhlIGZvcm1lciB0d28gd2lsbCBiZSBnZW5lcmF0ZWQgYXV0b21hdGljYWxseSBhbmQgdGhlCi0gICAqIGxhdHRlciBpcyB1c2VkIGZvciB0aGUgTUlEUCBvbmx5LiBPdGhlciBhdHRyaWJ1dGVzIHdpbGwgYmUKLSAgICogaWdub3JlZCBieSB0aGUgSlZNIGJ1dCBkbyBubyBoYXJtLgotICAgKgotICAgKiBAcGFyYW0gYSBhdHRyaWJ1dGUgdG8gYmUgYWRkZWQKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFkZENvZGVBdHRyaWJ1dGUoQXR0cmlidXRlIGEpIHsgY29kZV9hdHRyc192ZWMuYWRkKGEpOyB9Ci0KLSAgLyoqCi0gICAqIFJlbW92ZSBhIGNvZGUgYXR0cmlidXRlLgotICAgKi8KLSAgcHVibGljIHZvaWQgcmVtb3ZlQ29kZUF0dHJpYnV0ZShBdHRyaWJ1dGUgYSkgeyBjb2RlX2F0dHJzX3ZlYy5yZW1vdmUoYSk7IH0KLQotICAvKioKLSAgICogUmVtb3ZlIGFsbCBjb2RlIGF0dHJpYnV0ZXMuCi0gICAqLwotICBwdWJsaWMgdm9pZCByZW1vdmVDb2RlQXR0cmlidXRlcygpIHsKLSAgICBjb2RlX2F0dHJzX3ZlYy5jbGVhcigpOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gYWxsIGF0dHJpYnV0ZXMgb2YgdGhpcyBtZXRob2QuCi0gICAqLwotICBwdWJsaWMgQXR0cmlidXRlW10gZ2V0Q29kZUF0dHJpYnV0ZXMoKSB7Ci0gICAgQXR0cmlidXRlW10gYXR0cmlidXRlcyA9IG5ldyBBdHRyaWJ1dGVbY29kZV9hdHRyc192ZWMuc2l6ZSgpXTsKLSAgICBjb2RlX2F0dHJzX3ZlYy50b0FycmF5KGF0dHJpYnV0ZXMpOwotICAgIHJldHVybiBhdHRyaWJ1dGVzOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBtZXRob2Qgb2JqZWN0LiBOZXZlciBmb3JnZXQgdG8gY2FsbCBzZXRNYXhTdGFjaygpIG9yIHNldE1heFN0YWNrKG1heCksIHJlc3BlY3RpdmVseSwKLSAgICogYmVmb3JlIGNhbGxpbmcgdGhpcyBtZXRob2QgKHRoZSBzYW1lIGFwcGxpZXMgZm9yIG1heCBsb2NhbHMpLgotICAgKgotICAgKiBAcmV0dXJuIG1ldGhvZCBvYmplY3QKLSAgICovCi0gIHB1YmxpYyBNZXRob2QgZ2V0TWV0aG9kKCkgewotICAgIFN0cmluZyBzaWduYXR1cmUgICAgICAgPSBnZXRTaWduYXR1cmUoKTsKLSAgICBpbnQgICAgbmFtZV9pbmRleCAgICAgID0gY3AuYWRkVXRmOChuYW1lKTsKLSAgICBpbnQgICAgc2lnbmF0dXJlX2luZGV4ID0gY3AuYWRkVXRmOChzaWduYXR1cmUpOwotCi0gICAgLyogQWxzbyB1cGRhdGVzIHBvc2l0aW9ucyBvZiBpbnN0cnVjdGlvbnMsIGkuZS4sIHRoZWlyIGluZGljZXMKLSAgICAgKi8KLSAgICBieXRlW10gYnl0ZV9jb2RlID0gbnVsbDsKLQotICAgIGlmKGlsICE9IG51bGwpCi0gICAgICBieXRlX2NvZGUgPSBpbC5nZXRCeXRlQ29kZSgpOwotCi0gICAgTGluZU51bWJlclRhYmxlICAgIGxudCA9IG51bGw7Ci0gICAgTG9jYWxWYXJpYWJsZVRhYmxlIGx2dCA9IG51bGw7Ci0gICAgTG9jYWxWYXJpYWJsZVR5cGVUYWJsZSBsdnR0ID0gbnVsbDsKLQotICAgIC8qIENyZWF0ZSBMb2NhbFZhcmlhYmxlVGFibGUsIExvY2FsdmFyaWFibGVUeXBlVGFibGUsIGFuZCBMaW5lTnVtYmVyVGFibGUKLSAgICAgKiBhdHRyaWJ1dGVzIChmb3IgZGVidWdnZXJzLCBlLmcuKQotICAgICAqLwotICAgIGlmKCh2YXJpYWJsZV92ZWMuc2l6ZSgpID4gMCkgJiYgIXN0cmlwX2F0dHJpYnV0ZXMpCi0gICAgICBhZGRDb2RlQXR0cmlidXRlKGx2dCA9IGdldExvY2FsVmFyaWFibGVUYWJsZShjcCkpOwotCi0gICAgaWYoKHR5cGVfdmVjLnNpemUoKSA+IDApICYmICFzdHJpcF9hdHRyaWJ1dGVzKQotICAgICAgYWRkQ29kZUF0dHJpYnV0ZShsdnR0ID0gZ2V0TG9jYWxWYXJpYWJsZVR5cGVUYWJsZShjcCkpOwotCi0gICAgaWYoKGxpbmVfbnVtYmVyX3ZlYy5zaXplKCkgPiAwKSAmJiAhc3RyaXBfYXR0cmlidXRlcykKLSAgICAgIGFkZENvZGVBdHRyaWJ1dGUobG50ID0gZ2V0TGluZU51bWJlclRhYmxlKGNwKSk7Ci0KLSAgICBBdHRyaWJ1dGVbXSBjb2RlX2F0dHJzID0gZ2V0Q29kZUF0dHJpYnV0ZXMoKTsKLQotICAgIC8qIEVhY2ggYXR0cmlidXRlIGNhdXNlcyA2IGFkZGl0aW9uYWwgaGVhZGVyIGJ5dGVzCi0gICAgICovCi0gICAgaW50ICAgICAgICAgICAgICAgIGF0dHJzX2xlbiAgPSAwOwotICAgIGZvcihpbnQgaT0wOyBpIDwgY29kZV9hdHRycy5sZW5ndGg7IGkrKykKLSAgICAgIGF0dHJzX2xlbiArPSAoY29kZV9hdHRyc1tpXS5nZXRMZW5ndGgoKSArIDYpOwotCi0gICAgQ29kZUV4Y2VwdGlvbltdIGNfZXhjICAgPSBnZXRDb2RlRXhjZXB0aW9ucygpOwotICAgIGludCAgICAgICAgICAgICBleGNfbGVuID0gY19leGMubGVuZ3RoICogODsgLy8gRXZlcnkgZW50cnkgdGFrZXMgOCBieXRlcwotCi0gICAgQ29kZSBjb2RlID0gbnVsbDsKLQotICAgIGlmKChpbCAhPSBudWxsKSAmJiAhaXNBYnN0cmFjdCgpKSB7Ci0gICAgICAvLyBSZW1vdmUgYW55IHN0YWxlIGNvZGUgYXR0cmlidXRlCi0gICAgICBBdHRyaWJ1dGVbXSBhdHRyaWJ1dGVzID0gZ2V0QXR0cmlidXRlcygpOwotICAgICAgZm9yKGludCBpPTA7IGkgPCBhdHRyaWJ1dGVzLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgIEF0dHJpYnV0ZSBhID0gYXR0cmlidXRlc1tpXTsKLQotICAgICAgICBpZihhIGluc3RhbmNlb2YgQ29kZSkKLSAgICAgICAgICByZW1vdmVBdHRyaWJ1dGUoYSk7Ci0gICAgICB9Ci0KLSAgICAgIGNvZGUgPSBuZXcgQ29kZShjcC5hZGRVdGY4KCJDb2RlIiksCi0gICAgICAgICAgICAgICAgICAgICAgOCArIGJ5dGVfY29kZS5sZW5ndGggKyAvLyBwcm9sb2d1ZSBieXRlIGNvZGUKLSAgICAgICAgICAgICAgICAgICAgICAyICsgZXhjX2xlbiArICAgICAgICAgIC8vIGV4Y2VwdGlvbnMKLSAgICAgICAgICAgICAgICAgICAgICAyICsgYXR0cnNfbGVuLCAgICAgICAgIC8vIGF0dHJpYnV0ZXMKLSAgICAgICAgICAgICAgICAgICAgICBtYXhfc3RhY2ssIG1heF9sb2NhbHMsCi0gICAgICAgICAgICAgICAgICAgICAgYnl0ZV9jb2RlLCBjX2V4YywKLSAgICAgICAgICAgICAgICAgICAgICBjb2RlX2F0dHJzLAotICAgICAgICAgICAgICAgICAgICAgIGNwLmdldENvbnN0YW50UG9vbCgpKTsKLQotICAgICAgYWRkQXR0cmlidXRlKGNvZGUpOwotICAgIH0KLQotICAgIEV4Y2VwdGlvblRhYmxlIGV0ID0gbnVsbDsKLQotICAgIGlmKHRocm93c192ZWMuc2l6ZSgpID4gMCkKLSAgICAgIGFkZEF0dHJpYnV0ZShldCA9IGdldEV4Y2VwdGlvblRhYmxlKGNwKSk7IC8vIEFkZCBgRXhjZXB0aW9ucycgaWYgdGhlcmUgYXJlICJ0aHJvd3MiIGNsYXVzZXMKLQotICAgIE1ldGhvZCBtID0gbmV3IE1ldGhvZChhY2Nlc3NfZmxhZ3MsIG5hbWVfaW5kZXgsIHNpZ25hdHVyZV9pbmRleCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0QXR0cmlidXRlcygpLCBjcC5nZXRDb25zdGFudFBvb2woKSk7Ci0KLSAgICAvLyBVbmRvIGVmZmVjdHMgb2YgYWRkaW5nIGF0dHJpYnV0ZXMKLSAgICBpZihsdnQgIT0gbnVsbCkgIHJlbW92ZUNvZGVBdHRyaWJ1dGUobHZ0KTsKLSAgICBpZihsdnR0ICE9IG51bGwpIHJlbW92ZUNvZGVBdHRyaWJ1dGUobHZ0dCk7Ci0gICAgaWYobG50ICE9IG51bGwpICByZW1vdmVDb2RlQXR0cmlidXRlKGxudCk7Ci0gICAgaWYoY29kZSAhPSBudWxsKSByZW1vdmVBdHRyaWJ1dGUoY29kZSk7Ci0gICAgaWYoZXQgIT0gbnVsbCkgICByZW1vdmVBdHRyaWJ1dGUoZXQpOwotCi0gICAgcmV0dXJuIG07Ci0gIH0KLQotICAvKioKLSAgICogUmVtb3ZlIGFsbCBOT1BzIGZyb20gdGhlIGluc3RydWN0aW9uIGxpc3QgKGlmIHBvc3NpYmxlKSBhbmQgdXBkYXRlIGV2ZXJ5Ci0gICAqIG9iamVjdCByZWZlcmluZyB0byB0aGVtLCBpLmUuLCBicmFuY2ggaW5zdHJ1Y3Rpb25zLCBsb2NhbCB2YXJpYWJsZXMgYW5kCi0gICAqIGV4Y2VwdGlvbiBoYW5kbGVycy4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHJlbW92ZU5PUHMoKSB7Ci0gICAgaWYoaWwgIT0gbnVsbCkgewotICAgICAgSW5zdHJ1Y3Rpb25IYW5kbGUgbmV4dDsKLSAgICAgIC8qIENoZWNrIGJyYW5jaCBpbnN0cnVjdGlvbnMuCi0gICAgICAgKi8KLSAgICAgIGZvcihJbnN0cnVjdGlvbkhhbmRsZSBpaCA9IGlsLmdldFN0YXJ0KCk7IGloICE9IG51bGw7IGloID0gbmV4dCkgewotICAgICAgICBuZXh0ID0gaWgubmV4dDsKLQotICAgICAgICBpZigobmV4dCAhPSBudWxsKSAmJiAoaWguZ2V0SW5zdHJ1Y3Rpb24oKSBpbnN0YW5jZW9mIE5PUCkpIHsKLSAgICAgICAgICB0cnkgewotICAgICAgICAgICAgaWwuZGVsZXRlKGloKTsKLSAgICAgICAgICB9IGNhdGNoKFRhcmdldExvc3RFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgSW5zdHJ1Y3Rpb25IYW5kbGVbXSB0YXJnZXRzID0gZS5nZXRUYXJnZXRzKCk7Ci0KLSAgICAgICAgICAgIGZvcihpbnQgaT0wOyBpIDwgdGFyZ2V0cy5sZW5ndGg7IGkrKykgewotICAgICAgICAgICAgICBJbnN0cnVjdGlvblRhcmdldGVyW10gdGFyZ2V0ZXJzID0gdGFyZ2V0c1tpXS5nZXRUYXJnZXRlcnMoKTsKLQotICAgICAgICAgICAgICBmb3IoaW50IGo9MDsgaiA8IHRhcmdldGVycy5sZW5ndGg7IGorKykKLSAgICAgICAgICAgICAgICB0YXJnZXRlcnNbal0udXBkYXRlVGFyZ2V0KHRhcmdldHNbaV0sIG5leHQpOwotICAgICAgICAgICAgfQotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBTZXQgbWF4aW11bSBudW1iZXIgb2YgbG9jYWwgdmFyaWFibGVzLgotICAgKi8KLSAgcHVibGljIHZvaWQgICBzZXRNYXhMb2NhbHMoaW50IG0pICB7IG1heF9sb2NhbHMgPSBtOyB9Ci0gIHB1YmxpYyBpbnQgICAgZ2V0TWF4TG9jYWxzKCkgICAgICAgeyByZXR1cm4gbWF4X2xvY2FsczsgfQotCi0gIC8qKgotICAgKiBTZXQgbWF4aW11bSBzdGFjayBzaXplIGZvciB0aGlzIG1ldGhvZC4KLSAgICovCi0gIHB1YmxpYyB2b2lkICAgc2V0TWF4U3RhY2soaW50IG0pICB7IG1heF9zdGFjayA9IG07IH0KLSAgcHVibGljIGludCAgICBnZXRNYXhTdGFjaygpICAgICAgIHsgcmV0dXJuIG1heF9zdGFjazsgfQotCi0gIC8qKiBAcmV0dXJuIGNsYXNzIHRoYXQgY29udGFpbnMgdGhpcyBtZXRob2QKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0Q2xhc3NOYW1lKCkgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBjbGFzc19uYW1lOyB9Ci0gIHB1YmxpYyB2b2lkICAgc2V0Q2xhc3NOYW1lKFN0cmluZyBjbGFzc19uYW1lKSAgICB7IHRoaXMuY2xhc3NfbmFtZSA9IGNsYXNzX25hbWU7IH0KLQotICBwdWJsaWMgdm9pZCAgIHNldFJldHVyblR5cGUoVHlwZSByZXR1cm5fdHlwZSkgICAgeyBzZXRUeXBlKHJldHVybl90eXBlKTsgfQotICBwdWJsaWMgVHlwZSAgIGdldFJldHVyblR5cGUoKSAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gZ2V0VHlwZSgpOyB9Ci0KLSAgcHVibGljIHZvaWQgICBzZXRBcmd1bWVudFR5cGVzKFR5cGVbXSBhcmdfdHlwZXMpICB7IHRoaXMuYXJnX3R5cGVzID0gYXJnX3R5cGVzOyB9Ci0gIHB1YmxpYyBUeXBlW10gZ2V0QXJndW1lbnRUeXBlcygpICAgICAgICAgICAgICAgICAgeyByZXR1cm4gKFR5cGVbXSlhcmdfdHlwZXMuY2xvbmUoKTsgfQotICBwdWJsaWMgdm9pZCAgIHNldEFyZ3VtZW50VHlwZShpbnQgaSwgVHlwZSB0eXBlKSAgICAgICB7IGFyZ190eXBlc1tpXSA9IHR5cGU7IH0KLSAgcHVibGljIFR5cGUgICBnZXRBcmd1bWVudFR5cGUoaW50IGkpICAgICAgICAgICAgICAgICAgeyByZXR1cm4gYXJnX3R5cGVzW2ldOyB9Ci0KLSAgcHVibGljIHZvaWQgICAgIHNldEFyZ3VtZW50TmFtZXMoU3RyaW5nW10gYXJnX25hbWVzKSB7IHRoaXMuYXJnX25hbWVzID0gYXJnX25hbWVzOyB9Ci0gIHB1YmxpYyBTdHJpbmdbXSBnZXRBcmd1bWVudE5hbWVzKCkgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gKFN0cmluZ1tdKWFyZ19uYW1lcy5jbG9uZSgpOyB9Ci0gIHB1YmxpYyB2b2lkICAgICBzZXRBcmd1bWVudE5hbWUoaW50IGksIFN0cmluZyBuYW1lKSAgICAgeyBhcmdfbmFtZXNbaV0gPSBuYW1lOyB9Ci0gIHB1YmxpYyBTdHJpbmcgICBnZXRBcmd1bWVudE5hbWUoaW50IGkpICAgICAgICAgICAgICAgICAgeyByZXR1cm4gYXJnX25hbWVzW2ldOyB9Ci0KLSAgcHVibGljIEluc3RydWN0aW9uTGlzdCBnZXRJbnN0cnVjdGlvbkxpc3QoKSAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gaWw7IH0KLSAgcHVibGljIHZvaWQgICAgICAgICAgICBzZXRJbnN0cnVjdGlvbkxpc3QoSW5zdHJ1Y3Rpb25MaXN0IGlsKSAgeyB0aGlzLmlsID0gaWw7IH0KLQotICBwdWJsaWMgU3RyaW5nIGdldFNpZ25hdHVyZSgpIHsKLSAgICByZXR1cm4gVHlwZS5nZXRNZXRob2RTaWduYXR1cmUodHlwZSwgYXJnX3R5cGVzKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb21wdXRlcyBtYXguIHN0YWNrIHNpemUgYnkgcGVyZm9ybWluZyBjb250cm9sIGZsb3cgYW5hbHlzaXMuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRNYXhTdGFjaygpIHsKLSAgICBpZihpbCAhPSBudWxsKQotICAgICAgbWF4X3N0YWNrID0gZ2V0TWF4U3RhY2soY3AsIGlsLCBnZXRFeGNlcHRpb25IYW5kbGVycygpKTsKLSAgICBlbHNlCi0gICAgICBtYXhfc3RhY2sgPSAwOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbXB1dGUgbWF4aW11bSBudW1iZXIgb2YgbG9jYWwgdmFyaWFibGVzLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0TWF4TG9jYWxzKCkgewotICAgIGlmKGlsICE9IG51bGwpIHsKLSAgICAgIGludCBtYXggPSBpc1N0YXRpYygpPyAwIDogMTsKLQotICAgICAgaWYoYXJnX3R5cGVzICE9IG51bGwpCi0gICAgICAgIGZvcihpbnQgaT0wOyBpIDwgYXJnX3R5cGVzLmxlbmd0aDsgaSsrKQotICAgICAgICAgIG1heCArPSBhcmdfdHlwZXNbaV0uZ2V0U2l6ZSgpOwotCi0gICAgICBmb3IoSW5zdHJ1Y3Rpb25IYW5kbGUgaWggPSBpbC5nZXRTdGFydCgpOyBpaCAhPSBudWxsOyBpaCA9IGloLmdldE5leHQoKSkgewotICAgICAgICBJbnN0cnVjdGlvbiBpbnMgPSBpaC5nZXRJbnN0cnVjdGlvbigpOwotCi0gICAgICAgIGlmKChpbnMgaW5zdGFuY2VvZiBMb2NhbFZhcmlhYmxlSW5zdHJ1Y3Rpb24pIHx8Ci0gICAgICAgICAgIChpbnMgaW5zdGFuY2VvZiBSRVQpIHx8IChpbnMgaW5zdGFuY2VvZiBJSU5DKSkKLSAgICAgICAgewotICAgICAgICAgIGludCBpbmRleCA9ICgoSW5kZXhlZEluc3RydWN0aW9uKWlucykuZ2V0SW5kZXgoKSArCi0gICAgICAgICAgICAoKFR5cGVkSW5zdHJ1Y3Rpb24paW5zKS5nZXRUeXBlKGNwKS5nZXRTaXplKCk7Ci0KLSAgICAgICAgICBpZihpbmRleCA+IG1heCkKLSAgICAgICAgICAgIG1heCA9IGluZGV4OwotICAgICAgICB9Ci0gICAgICB9Ci0KLSAgICAgIG1heF9sb2NhbHMgPSBtYXg7Ci0gICAgfSBlbHNlCi0gICAgICBtYXhfbG9jYWxzID0gMDsKLSAgfQotCi0gIC8qKiBEbyBub3QvRG8gcHJvZHVjZSBhdHRyaWJ1dGVzIGNvZGUgYXR0cmlidXRlc0xpbmVOdW1iZXJUYWJsZSBhbmQKLSAgICogTG9jYWxWYXJpYWJsZVRhYmxlLCBsaWtlIGphdmFjIC1PCi0gICAqLwotICBwdWJsaWMgdm9pZCBzdHJpcEF0dHJpYnV0ZXMoYm9vbGVhbiBmbGFnKSB7IHN0cmlwX2F0dHJpYnV0ZXMgPSBmbGFnOyB9Ci0KLSAgc3RhdGljIGZpbmFsIGNsYXNzIEJyYW5jaFRhcmdldCB7Ci0gICAgSW5zdHJ1Y3Rpb25IYW5kbGUgdGFyZ2V0OwotICAgIGludCAgICAgICAgICAgICAgIHN0YWNrRGVwdGg7Ci0KLSAgICBCcmFuY2hUYXJnZXQoSW5zdHJ1Y3Rpb25IYW5kbGUgdGFyZ2V0LCBpbnQgc3RhY2tEZXB0aCkgewotICAgICAgdGhpcy50YXJnZXQgPSB0YXJnZXQ7Ci0gICAgICB0aGlzLnN0YWNrRGVwdGggPSBzdGFja0RlcHRoOwotICAgIH0KLSAgfQotCi0gIHN0YXRpYyBmaW5hbCBjbGFzcyBCcmFuY2hTdGFjayB7Ci0gICAgU3RhY2sgICAgIGJyYW5jaFRhcmdldHMgID0gbmV3IFN0YWNrKCk7Ci0gICAgSGFzaHRhYmxlIHZpc2l0ZWRUYXJnZXRzID0gbmV3IEhhc2h0YWJsZSgpOwotCi0gICAgcHVibGljIHZvaWQgcHVzaChJbnN0cnVjdGlvbkhhbmRsZSB0YXJnZXQsIGludCBzdGFja0RlcHRoKSB7Ci0gICAgICBpZih2aXNpdGVkKHRhcmdldCkpCi0gICAgICAgIHJldHVybjsKLQotICAgICAgYnJhbmNoVGFyZ2V0cy5wdXNoKHZpc2l0KHRhcmdldCwgc3RhY2tEZXB0aCkpOwotICAgIH0KLQotICAgIHB1YmxpYyBCcmFuY2hUYXJnZXQgcG9wKCkgewotICAgICAgaWYoIWJyYW5jaFRhcmdldHMuZW1wdHkoKSkgewotICAgICAgICBCcmFuY2hUYXJnZXQgYnQgPSAoQnJhbmNoVGFyZ2V0KSBicmFuY2hUYXJnZXRzLnBvcCgpOwotICAgICAgICByZXR1cm4gYnQ7Ci0gICAgICB9Ci0KLSAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIHByaXZhdGUgZmluYWwgQnJhbmNoVGFyZ2V0IHZpc2l0KEluc3RydWN0aW9uSGFuZGxlIHRhcmdldCwgaW50IHN0YWNrRGVwdGgpIHsKLSAgICAgIEJyYW5jaFRhcmdldCBidCA9IG5ldyBCcmFuY2hUYXJnZXQodGFyZ2V0LCBzdGFja0RlcHRoKTsKLSAgICAgIHZpc2l0ZWRUYXJnZXRzLnB1dCh0YXJnZXQsIGJ0KTsKLQotICAgICAgcmV0dXJuIGJ0OwotICAgIH0KLQotICAgIHByaXZhdGUgZmluYWwgYm9vbGVhbiB2aXNpdGVkKEluc3RydWN0aW9uSGFuZGxlIHRhcmdldCkgewotICAgICAgcmV0dXJuICh2aXNpdGVkVGFyZ2V0cy5nZXQodGFyZ2V0KSAhPSBudWxsKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogQ29tcHV0ZXMgc3RhY2sgdXNhZ2Ugb2YgYW4gaW5zdHJ1Y3Rpb24gbGlzdCBieSBwZXJmb3JtaW5nIGNvbnRyb2wgZmxvdyBhbmFseXNpcy4KLSAgICoKLSAgICogQHJldHVybiBtYXhpbXVtIHN0YWNrIGRlcHRoIHVzZWQgYnkgbWV0aG9kCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGludCBnZXRNYXhTdGFjayhDb25zdGFudFBvb2xHZW4gY3AsIEluc3RydWN0aW9uTGlzdCBpbCwgQ29kZUV4Y2VwdGlvbkdlbltdIGV0KSB7Ci0gICAgQnJhbmNoU3RhY2sgYnJhbmNoVGFyZ2V0cyA9IG5ldyBCcmFuY2hTdGFjaygpOwotCi0gICAgLyogSW5pdGlhbGx5LCBwb3B1bGF0ZSB0aGUgYnJhbmNoIHN0YWNrIHdpdGggdGhlIGV4Y2VwdGlvbgotICAgICAqIGhhbmRsZXJzLCBiZWNhdXNlIHRoZXNlIGFyZW4ndCAobmVjZXNzYXJpbHkpIGJyYW5jaGVkIHRvCi0gICAgICogZXhwbGljaXRseS4gaW4gZWFjaCBjYXNlLCB0aGUgc3RhY2sgd2lsbCBoYXZlIGRlcHRoIDEsCi0gICAgICogY29udGFpbmluZyB0aGUgZXhjZXB0aW9uIG9iamVjdC4KLSAgICAgKi8KLSAgICBmb3IgKGludCBpID0gMDsgaSA8IGV0Lmxlbmd0aDsgaSsrKSB7Ci0gICAgICBJbnN0cnVjdGlvbkhhbmRsZSBoYW5kbGVyX3BjID0gZXRbaV0uZ2V0SGFuZGxlclBDKCk7Ci0gICAgICBpZiAoaGFuZGxlcl9wYyAhPSBudWxsKQotICAgICAgICBicmFuY2hUYXJnZXRzLnB1c2goaGFuZGxlcl9wYywgMSk7Ci0gICAgfQotCi0gICAgaW50ICAgICAgICAgICAgICAgc3RhY2tEZXB0aCA9IDAsIG1heFN0YWNrRGVwdGggPSAwOwotICAgIEluc3RydWN0aW9uSGFuZGxlIGloICAgICAgICAgPSBpbC5nZXRTdGFydCgpOwotCi0gICAgd2hpbGUoaWggIT0gbnVsbCkgewotICAgICAgSW5zdHJ1Y3Rpb24gaW5zdHJ1Y3Rpb24gPSBpaC5nZXRJbnN0cnVjdGlvbigpOwotICAgICAgc2hvcnQgb3Bjb2RlID0gaW5zdHJ1Y3Rpb24uZ2V0T3Bjb2RlKCk7Ci0gICAgICBpbnQgZGVsdGEgPSBpbnN0cnVjdGlvbi5wcm9kdWNlU3RhY2soY3ApIC0gaW5zdHJ1Y3Rpb24uY29uc3VtZVN0YWNrKGNwKTsKLQotICAgICAgc3RhY2tEZXB0aCArPSBkZWx0YTsKLSAgICAgIGlmKHN0YWNrRGVwdGggPiBtYXhTdGFja0RlcHRoKQotICAgICAgICBtYXhTdGFja0RlcHRoID0gc3RhY2tEZXB0aDsKLQotICAgICAgLy8gY2hvb3NlIHRoZSBuZXh0IGluc3RydWN0aW9uIGJhc2VkIG9uIHdoZXRoZXIgY3VycmVudCBpcyBhIGJyYW5jaC4KLSAgICAgIGlmKGluc3RydWN0aW9uIGluc3RhbmNlb2YgQnJhbmNoSW5zdHJ1Y3Rpb24pIHsKLSAgICAgICAgQnJhbmNoSW5zdHJ1Y3Rpb24gYnJhbmNoID0gKEJyYW5jaEluc3RydWN0aW9uKSBpbnN0cnVjdGlvbjsKLSAgICAgICAgaWYoaW5zdHJ1Y3Rpb24gaW5zdGFuY2VvZiBTZWxlY3QpIHsKLSAgICAgICAgICAvLyBleHBsb3JlIGFsbCBvZiB0aGUgc2VsZWN0J3MgdGFyZ2V0cy4gdGhlIGRlZmF1bHQgdGFyZ2V0IGlzIGhhbmRsZWQgYmVsb3cuCi0gICAgICAgICAgU2VsZWN0IHNlbGVjdCA9IChTZWxlY3QpIGJyYW5jaDsKLSAgICAgICAgICBJbnN0cnVjdGlvbkhhbmRsZVtdIHRhcmdldHMgPSBzZWxlY3QuZ2V0VGFyZ2V0cygpOwotICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdGFyZ2V0cy5sZW5ndGg7IGkrKykKLSAgICAgICAgICAgIGJyYW5jaFRhcmdldHMucHVzaCh0YXJnZXRzW2ldLCBzdGFja0RlcHRoKTsKLSAgICAgICAgICAvLyBub3RoaW5nIHRvIGZhbGwgdGhyb3VnaCB0by4KLSAgICAgICAgICBpaCA9IG51bGw7Ci0gICAgICAgIH0gZWxzZSBpZighKGJyYW5jaCBpbnN0YW5jZW9mIElmSW5zdHJ1Y3Rpb24pKSB7Ci0gICAgICAgICAgLy8gaWYgYW4gaW5zdHJ1Y3Rpb24gdGhhdCBjb21lcyBiYWNrIHRvIGZvbGxvd2luZyBQQywKLSAgICAgICAgICAvLyBwdXNoIG5leHQgaW5zdHJ1Y3Rpb24sIHdpdGggc3RhY2sgZGVwdGggcmVkdWNlZCBieSAxLgotICAgICAgICAgIGlmKG9wY29kZSA9PSBDb25zdGFudHMuSlNSIHx8IG9wY29kZSA9PSBDb25zdGFudHMuSlNSX1cpCi0gICAgICAgICAgICBicmFuY2hUYXJnZXRzLnB1c2goaWguZ2V0TmV4dCgpLCBzdGFja0RlcHRoIC0gMSk7Ci0gICAgICAgICAgaWggPSBudWxsOwotICAgICAgICB9Ci0gICAgICAgIC8vIGZvciBhbGwgYnJhbmNoZXMsIHRoZSB0YXJnZXQgb2YgdGhlIGJyYW5jaCBpcyBwdXNoZWQgb24gdGhlIGJyYW5jaCBzdGFjay4KLSAgICAgICAgLy8gY29uZGl0aW9uYWwgYnJhbmNoZXMgaGF2ZSBhIGZhbGwgdGhyb3VnaCBjYXNlLCBzZWxlY3RzIGRvbid0LCBhbmQKLSAgICAgICAgLy8ganNyL2pzcl93IHJldHVybiB0byB0aGUgbmV4dCBpbnN0cnVjdGlvbi4KLSAgICAgICAgYnJhbmNoVGFyZ2V0cy5wdXNoKGJyYW5jaC5nZXRUYXJnZXQoKSwgc3RhY2tEZXB0aCk7Ci0gICAgICB9IGVsc2UgewotICAgICAgICAvLyBjaGVjayBmb3IgaW5zdHJ1Y3Rpb25zIHRoYXQgdGVybWluYXRlIHRoZSBtZXRob2QuCi0gICAgICAgIGlmKG9wY29kZSA9PSBDb25zdGFudHMuQVRIUk9XIHx8IG9wY29kZSA9PSBDb25zdGFudHMuUkVUIHx8Ci0gICAgICAgICAgIChvcGNvZGUgPj0gQ29uc3RhbnRzLklSRVRVUk4gJiYgb3Bjb2RlIDw9IENvbnN0YW50cy5SRVRVUk4pKQotICAgICAgICAgIGloID0gbnVsbDsKLSAgICAgIH0KLSAgICAgIC8vIG5vcm1hbCBjYXNlLCBnbyB0byB0aGUgbmV4dCBpbnN0cnVjdGlvbi4KLSAgICAgIGlmKGloICE9IG51bGwpCi0gICAgICAgIGloID0gaWguZ2V0TmV4dCgpOwotICAgICAgLy8gaWYgd2UgaGF2ZSBubyBtb3JlIGluc3RydWN0aW9ucywgc2VlIGlmIHRoZXJlIGFyZSBhbnkgZGVmZXJyZWQgYnJhbmNoZXMgdG8gZXhwbG9yZS4KLSAgICAgIGlmKGloID09IG51bGwpIHsKLSAgICAgICAgQnJhbmNoVGFyZ2V0IGJ0ID0gYnJhbmNoVGFyZ2V0cy5wb3AoKTsKLSAgICAgICAgaWYgKGJ0ICE9IG51bGwpIHsKLSAgICAgICAgICBpaCA9IGJ0LnRhcmdldDsKLSAgICAgICAgICBzdGFja0RlcHRoID0gYnQuc3RhY2tEZXB0aDsKLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiBtYXhTdGFja0RlcHRoOwotICB9Ci0KLSAgcHJpdmF0ZSBBcnJheUxpc3Qgb2JzZXJ2ZXJzOwotCi0gIC8qKiBBZGQgb2JzZXJ2ZXIgZm9yIHRoaXMgb2JqZWN0LgotICAgKi8KLSAgcHVibGljIHZvaWQgYWRkT2JzZXJ2ZXIoTWV0aG9kT2JzZXJ2ZXIgbykgewotICAgIGlmKG9ic2VydmVycyA9PSBudWxsKQotICAgICAgb2JzZXJ2ZXJzID0gbmV3IEFycmF5TGlzdCgpOwotCi0gICAgb2JzZXJ2ZXJzLmFkZChvKTsKLSAgfQotCi0gIC8qKiBSZW1vdmUgb2JzZXJ2ZXIgZm9yIHRoaXMgb2JqZWN0LgotICAgKi8KLSAgcHVibGljIHZvaWQgcmVtb3ZlT2JzZXJ2ZXIoTWV0aG9kT2JzZXJ2ZXIgbykgewotICAgIGlmKG9ic2VydmVycyAhPSBudWxsKQotICAgICAgb2JzZXJ2ZXJzLnJlbW92ZShvKTsKLSAgfQotCi0gIC8qKiBDYWxsIG5vdGlmeSgpIG1ldGhvZCBvbiBhbGwgb2JzZXJ2ZXJzLiBUaGlzIG1ldGhvZCBpcyBub3QgY2FsbGVkCi0gICAqIGF1dG9tYXRpY2FsbHkgd2hlbmV2ZXIgdGhlIHN0YXRlIGhhcyBjaGFuZ2VkLCBidXQgaGFzIHRvIGJlCi0gICAqIGNhbGxlZCBieSB0aGUgdXNlciBhZnRlciBoZSBoYXMgZmluaXNoZWQgZWRpdGluZyB0aGUgb2JqZWN0LgotICAgKi8KLSAgcHVibGljIHZvaWQgdXBkYXRlKCkgewotICAgIGlmKG9ic2VydmVycyAhPSBudWxsKQotICAgICAgZm9yKEl0ZXJhdG9yIGUgPSBvYnNlcnZlcnMuaXRlcmF0b3IoKTsgZS5oYXNOZXh0KCk7ICkKLSAgICAgICAgKChNZXRob2RPYnNlcnZlcillLm5leHQoKSkubm90aWZ5KHRoaXMpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiBzdHJpbmcgcmVwcmVzZW50YXRpb24gY2xvc2UgdG8gZGVjbGFyYXRpb24gZm9ybWF0LAotICAgKiBgcHVibGljIHN0YXRpYyB2b2lkIF9tYWluKFN0cmluZ1tdKSB0aHJvd3MgSU9FeGNlcHRpb24nLCBlLmcuCi0gICAqCi0gICAqIEByZXR1cm4gU3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBtZXRob2QuCi0gICAqLwotICBwdWJsaWMgZmluYWwgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgIFN0cmluZyBhY2Nlc3MgICAgPSBVdGlsaXR5LmFjY2Vzc1RvU3RyaW5nKGFjY2Vzc19mbGFncyk7Ci0gICAgU3RyaW5nIHNpZ25hdHVyZSA9IFR5cGUuZ2V0TWV0aG9kU2lnbmF0dXJlKHR5cGUsIGFyZ190eXBlcyk7Ci0KLSAgICBzaWduYXR1cmUgPSBVdGlsaXR5Lm1ldGhvZFNpZ25hdHVyZVRvU3RyaW5nKHNpZ25hdHVyZSwgbmFtZSwgYWNjZXNzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ1ZSwgZ2V0TG9jYWxWYXJpYWJsZVRhYmxlKGNwKSk7Ci0KLSAgICBTdHJpbmdCdWZmZXIgYnVmID0gbmV3IFN0cmluZ0J1ZmZlcihzaWduYXR1cmUpOwotCi0gICAgaWYodGhyb3dzX3ZlYy5zaXplKCkgPiAwKSB7Ci0gICAgICBmb3IoSXRlcmF0b3IgZSA9IHRocm93c192ZWMuaXRlcmF0b3IoKTsgZS5oYXNOZXh0KCk7ICkKLSAgICAgICAgYnVmLmFwcGVuZCgiXG5cdFx0dGhyb3dzICIgKyBlLm5leHQoKSk7Ci0gICAgfQotCi0gICAgcmV0dXJuIGJ1Zi50b1N0cmluZygpOwotICB9Ci0KLSAgLyoqIEByZXR1cm4gZGVlcCBjb3B5IG9mIHRoaXMgbWV0aG9kCi0gICAqLwotICBwdWJsaWMgTWV0aG9kR2VuIGNvcHkoU3RyaW5nIGNsYXNzX25hbWUsIENvbnN0YW50UG9vbEdlbiBjcCkgewotICAgIE1ldGhvZCAgICBtICA9ICgoTWV0aG9kR2VuKWNsb25lKCkpLmdldE1ldGhvZCgpOwotICAgIE1ldGhvZEdlbiBtZyA9IG5ldyBNZXRob2RHZW4obSwgY2xhc3NfbmFtZSwgdGhpcy5jcCk7Ci0KLSAgICBpZih0aGlzLmNwICE9IGNwKSB7Ci0gICAgICBtZy5zZXRDb25zdGFudFBvb2woY3ApOwotICAgICAgbWcuZ2V0SW5zdHJ1Y3Rpb25MaXN0KCkucmVwbGFjZUNvbnN0YW50UG9vbCh0aGlzLmNwLCBjcCk7Ci0gICAgfQotCi0gICAgcmV0dXJuIG1nOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9NZXRob2RPYnNlcnZlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvTWV0aG9kT2JzZXJ2ZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMTEzNTk4NC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9NZXRob2RPYnNlcnZlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNjkgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotLyoqCi0gKiBJbXBsZW1lbnQgdGhpcyBpbnRlcmZhY2UgaWYgeW91J3JlIGludGVyZXN0ZWQgaW4gY2hhbmdlcyB0byBhIE1ldGhvZEdlbiBvYmplY3QKLSAqIGFuZCByZWdpc3RlciB5b3Vyc2VsZiB3aXRoIGFkZE9ic2VydmVyKCkuCi0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGludGVyZmFjZSBNZXRob2RPYnNlcnZlciB7Ci0gIHB1YmxpYyB2b2lkIG5vdGlmeShNZXRob2RHZW4gbWV0aG9kKTsKLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL05FVy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvTkVXLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGRlMGUyZjguLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvTkVXLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMTQgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLWltcG9ydCBqYXZhLmlvLio7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuRXhjZXB0aW9uQ29uc3RhbnRzOwotCi0vKioKLSAqIE5FVyAtIENyZWF0ZSBuZXcgb2JqZWN0Ci0gKiA8UFJFPlN0YWNrOiAuLi4gLSZndDsgLi4uLCBvYmplY3RyZWY8L1BSRT4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgTkVXIGV4dGVuZHMgQ1BJbnN0cnVjdGlvbgotICBpbXBsZW1lbnRzIExvYWRDbGFzcywgQWxsb2NhdGlvbkluc3RydWN0aW9uLCBFeGNlcHRpb25UaHJvd2VyLCBTdGFja1Byb2R1Y2VyIHsKLSAgLyoqCi0gICAqIEVtcHR5IGNvbnN0cnVjdG9yIG5lZWRlZCBmb3IgdGhlIENsYXNzLm5ld0luc3RhbmNlKCkgc3RhdGVtZW50IGluCi0gICAqIEluc3RydWN0aW9uLnJlYWRJbnN0cnVjdGlvbigpLiBOb3QgdG8gYmUgdXNlZCBvdGhlcndpc2UuCi0gICAqLwotICBORVcoKSB7fQotCi0gIHB1YmxpYyBORVcoaW50IGluZGV4KSB7Ci0gICAgc3VwZXIoY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLk5FVywgaW5kZXgpOwotICB9Ci0KLSAgcHVibGljIENsYXNzW10gZ2V0RXhjZXB0aW9ucygpewotICAgIENsYXNzW10gY3MgPSBuZXcgQ2xhc3NbMiArIEV4Y2VwdGlvbkNvbnN0YW50cy5FWENTX0NMQVNTX0FORF9JTlRFUkZBQ0VfUkVTT0xVVElPTi5sZW5ndGhdOwotCi0gICAgU3lzdGVtLmFycmF5Y29weShFeGNlcHRpb25Db25zdGFudHMuRVhDU19DTEFTU19BTkRfSU5URVJGQUNFX1JFU09MVVRJT04sIDAsCi0gICAgICAgICAgICAgICAgICAgICBjcywgMCwgRXhjZXB0aW9uQ29uc3RhbnRzLkVYQ1NfQ0xBU1NfQU5EX0lOVEVSRkFDRV9SRVNPTFVUSU9OLmxlbmd0aCk7Ci0KLSAgICBjc1tFeGNlcHRpb25Db25zdGFudHMuRVhDU19DTEFTU19BTkRfSU5URVJGQUNFX1JFU09MVVRJT04ubGVuZ3RoKzFdID0gRXhjZXB0aW9uQ29uc3RhbnRzLklOU1RBTlRJQVRJT05fRVJST1I7Ci0gICAgY3NbRXhjZXB0aW9uQ29uc3RhbnRzLkVYQ1NfQ0xBU1NfQU5EX0lOVEVSRkFDRV9SRVNPTFVUSU9OLmxlbmd0aF0gICA9IEV4Y2VwdGlvbkNvbnN0YW50cy5JTExFR0FMX0FDQ0VTU19FUlJPUjsKLQotICAgIHJldHVybiBjczsKLSAgfQotCi0gIHB1YmxpYyBPYmplY3RUeXBlIGdldExvYWRDbGFzc1R5cGUoQ29uc3RhbnRQb29sR2VuIGNwZykgewotICAgIHJldHVybiAoT2JqZWN0VHlwZSlnZXRUeXBlKGNwZyk7Ci0gIH0KLQotICAvKioKLSAgICogQ2FsbCBjb3JyZXNwb25kaW5nIHZpc2l0b3IgbWV0aG9kKHMpLiBUaGUgb3JkZXIgaXM6Ci0gICAqIENhbGwgdmlzaXRvciBtZXRob2RzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMgZmlyc3QsIHRoZW4KLSAgICogY2FsbCBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY2xhc3MgaGllcmFyY2h5IGluIGRlc2NlbmRpbmcgb3JkZXIsCi0gICAqIGkuZS4sIHRoZSBtb3N0IHNwZWNpZmljIHZpc2l0WFhYKCkgY2FsbCBjb21lcyBsYXN0LgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRMb2FkQ2xhc3ModGhpcyk7Ci0gICAgdi52aXNpdEFsbG9jYXRpb25JbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0RXhjZXB0aW9uVGhyb3dlcih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tQcm9kdWNlcih0aGlzKTsKLSAgICB2LnZpc2l0VHlwZWRJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0Q1BJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0TkVXKHRoaXMpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9ORVdBUlJBWS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvTkVXQVJSQVkuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYjZkNzE2ZS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9ORVdBUlJBWS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTQzICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1pbXBvcnQgamF2YS5pby4qOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLnV0aWwuQnl0ZVNlcXVlbmNlOwotCi0vKioKLSAqIE5FV0FSUkFZIC0gIENyZWF0ZSBuZXcgYXJyYXkgb2YgYmFzaWMgdHlwZSAoaW50LCBzaG9ydCwgLi4uKQotICogPFBSRT5TdGFjazogLi4uLCBjb3VudCAtJmd0OyAuLi4sIGFycmF5cmVmPC9QUkU+Ci0gKiB0eXBlIG11c3QgYmUgb25lIG9mIFRfSU5ULCBUX1NIT1JULCAuLi4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgTkVXQVJSQVkgZXh0ZW5kcyBJbnN0cnVjdGlvbgotICBpbXBsZW1lbnRzIEFsbG9jYXRpb25JbnN0cnVjdGlvbiwgRXhjZXB0aW9uVGhyb3dlciwgU3RhY2tQcm9kdWNlciB7Ci0gIHByaXZhdGUgYnl0ZSB0eXBlOwotCi0gIC8qKgotICAgKiBFbXB0eSBjb25zdHJ1Y3RvciBuZWVkZWQgZm9yIHRoZSBDbGFzcy5uZXdJbnN0YW5jZSgpIHN0YXRlbWVudCBpbgotICAgKiBJbnN0cnVjdGlvbi5yZWFkSW5zdHJ1Y3Rpb24oKS4gTm90IHRvIGJlIHVzZWQgb3RoZXJ3aXNlLgotICAgKi8KLSAgTkVXQVJSQVkoKSB7fQotCi0gIHB1YmxpYyBORVdBUlJBWShieXRlIHR5cGUpIHsKLSAgICBzdXBlcihjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuTkVXQVJSQVksIChzaG9ydCkyKTsKLSAgICB0aGlzLnR5cGUgPSB0eXBlOwotICB9Ci0KLSAgcHVibGljIE5FV0FSUkFZKEJhc2ljVHlwZSB0eXBlKSB7Ci0gICAgICB0aGlzKHR5cGUuZ2V0VHlwZSgpKTsKLSAgfQotCi0gIC8qKgotICAgKiBEdW1wIGluc3RydWN0aW9uIGFzIGJ5dGUgY29kZSB0byBzdHJlYW0gb3V0LgotICAgKiBAcGFyYW0gb3V0IE91dHB1dCBzdHJlYW0KLSAgICovCi0gIHB1YmxpYyB2b2lkIGR1bXAoRGF0YU91dHB1dFN0cmVhbSBvdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgb3V0LndyaXRlQnl0ZShvcGNvZGUpOwotICAgIG91dC53cml0ZUJ5dGUodHlwZSk7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBudW1lcmljIGNvZGUgZm9yIGJhc2ljIGVsZW1lbnQgdHlwZQotICAgKi8KLSAgcHVibGljIGZpbmFsIGJ5dGUgZ2V0VHlwZWNvZGUoKSB7IHJldHVybiB0eXBlOyB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gdHlwZSBvZiBjb25zdHJ1Y3RlZCBhcnJheQotICAgKi8KLSAgcHVibGljIGZpbmFsIFR5cGUgZ2V0VHlwZSgpIHsKLSAgICByZXR1cm4gbmV3IEFycmF5VHlwZShCYXNpY1R5cGUuZ2V0VHlwZSh0eXBlKSwgMSk7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBtbmVtb25pYyBmb3IgaW5zdHJ1Y3Rpb24KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoYm9vbGVhbiB2ZXJib3NlKSB7Ci0gICAgcmV0dXJuIHN1cGVyLnRvU3RyaW5nKHZlcmJvc2UpICsgIiAiICsgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLlRZUEVfTkFNRVNbdHlwZV07Ci0gIH0KLSAgLyoqCi0gICAqIFJlYWQgbmVlZGVkIGRhdGEgKGUuZy4gaW5kZXgpIGZyb20gZmlsZS4KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIGluaXRGcm9tRmlsZShCeXRlU2VxdWVuY2UgYnl0ZXMsIGJvb2xlYW4gd2lkZSkgdGhyb3dzIElPRXhjZXB0aW9uCi0gIHsKLSAgICB0eXBlICAgPSBieXRlcy5yZWFkQnl0ZSgpOwotICAgIGxlbmd0aCA9IDI7Ci0gIH0KLQotICBwdWJsaWMgQ2xhc3NbXSBnZXRFeGNlcHRpb25zKCkgewotICAgIHJldHVybiBuZXcgQ2xhc3NbXSB7IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkV4Y2VwdGlvbkNvbnN0YW50cy5ORUdBVElWRV9BUlJBWV9TSVpFX0VYQ0VQVElPTiB9OwotICB9Ci0KLSAgLyoqCi0gICAqIENhbGwgY29ycmVzcG9uZGluZyB2aXNpdG9yIG1ldGhvZChzKS4gVGhlIG9yZGVyIGlzOgotICAgKiBDYWxsIHZpc2l0b3IgbWV0aG9kcyBvZiBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzIGZpcnN0LCB0aGVuCi0gICAqIGNhbGwgbWV0aG9kcyBhY2NvcmRpbmcgdG8gdGhlIGNsYXNzIGhpZXJhcmNoeSBpbiBkZXNjZW5kaW5nIG9yZGVyLAotICAgKiBpLmUuLCB0aGUgbW9zdCBzcGVjaWZpYyB2aXNpdFhYWCgpIGNhbGwgY29tZXMgbGFzdC4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0QWxsb2NhdGlvbkluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRFeGNlcHRpb25UaHJvd2VyKHRoaXMpOwotICAgIHYudmlzaXRTdGFja1Byb2R1Y2VyKHRoaXMpOwotICAgIHYudmlzaXRORVdBUlJBWSh0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvTk9QLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9OT1AuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMWU2ZWUwYS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9OT1AuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDgzICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8qKgotICogTk9QIC0gRG8gbm90aGluZwotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBOT1AgZXh0ZW5kcyBJbnN0cnVjdGlvbiB7Ci0gIHB1YmxpYyBOT1AoKSB7Ci0gICAgc3VwZXIoY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLk5PUCwgKHNob3J0KTEpOwotICB9Ci0KLQotICAvKioKLSAgICogQ2FsbCBjb3JyZXNwb25kaW5nIHZpc2l0b3IgbWV0aG9kKHMpLiBUaGUgb3JkZXIgaXM6Ci0gICAqIENhbGwgdmlzaXRvciBtZXRob2RzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMgZmlyc3QsIHRoZW4KLSAgICogY2FsbCBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY2xhc3MgaGllcmFyY2h5IGluIGRlc2NlbmRpbmcgb3JkZXIsCi0gICAqIGkuZS4sIHRoZSBtb3N0IHNwZWNpZmljIHZpc2l0WFhYKCkgY2FsbCBjb21lcyBsYXN0LgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXROT1AodGhpcyk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL05hbWVkQW5kVHlwZWQuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL05hbWVkQW5kVHlwZWQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYTE1MDFmNC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9OYW1lZEFuZFR5cGVkLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3MyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIERlbm90ZSBlbnRpdHkgdGhhdCBoYXMgYm90aCBuYW1lIGFuZCB0eXBlLiBUaGlzIGlzIHRydWUgZm9yIGxvY2FsIHZhcmlhYmxlcywKLSAqIG1ldGhvZHMgYW5kIGZpZWxkcy4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgaW50ZXJmYWNlIE5hbWVkQW5kVHlwZWQgewotICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKTsKLSAgcHVibGljIFR5cGUgICBnZXRUeXBlKCk7Ci0gIHB1YmxpYyB2b2lkICAgc2V0TmFtZShTdHJpbmcgbmFtZSk7Ci0gIHB1YmxpYyB2b2lkICAgc2V0VHlwZShUeXBlIHR5cGUpOwotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9PYmplY3RUeXBlLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9PYmplY3RUeXBlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGE1MDZlZGQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvT2JqZWN0VHlwZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTM5ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLlJlcG9zaXRvcnk7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuY2xhc3NmaWxlLkphdmFDbGFzczsKLQotLyoqCi0gKiBEZW5vdGVzIHJlZmVyZW5jZSBzdWNoIGFzIGphdmEubGFuZy5TdHJpbmcuCi0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIE9iamVjdFR5cGUgZXh0ZW5kcyBSZWZlcmVuY2VUeXBlIHsKLSAgcHJpdmF0ZSBTdHJpbmcgY2xhc3NfbmFtZTsgLy8gQ2xhc3MgbmFtZSBvZiB0eXBlCi0KLSAgLyoqCi0gICAqIEBwYXJhbSBjbGFzc19uYW1lIGZ1bGx5IHF1YWxpZmllZCBjbGFzcyBuYW1lLCBlLmcuIGphdmEubGFuZy5TdHJpbmcKLSAgICovCi0gIHB1YmxpYyBPYmplY3RUeXBlKFN0cmluZyBjbGFzc19uYW1lKSB7Ci0gICAgc3VwZXIoQ29uc3RhbnRzLlRfUkVGRVJFTkNFLCAiTCIgKyBjbGFzc19uYW1lLnJlcGxhY2UoJy4nLCAnLycpICsgIjsiKTsKLSAgICB0aGlzLmNsYXNzX25hbWUgPSBjbGFzc19uYW1lLnJlcGxhY2UoJy8nLCAnLicpOwotICB9Ci0KLSAgLyoqIEByZXR1cm4gbmFtZSBvZiByZWZlcmVuY2VkIGNsYXNzCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldENsYXNzTmFtZSgpIHsgcmV0dXJuIGNsYXNzX25hbWU7IH0KLQotICAvKiogQHJldHVybiBhIGhhc2ggY29kZSB2YWx1ZSBmb3IgdGhlIG9iamVjdC4KLSAgICovCi0gIHB1YmxpYyBpbnQgaGFzaENvZGUoKSAgeyByZXR1cm4gY2xhc3NfbmFtZS5oYXNoQ29kZSgpOyB9Ci0KLSAgLyoqIEByZXR1cm4gdHJ1ZSBpZiBib3RoIHR5cGUgb2JqZWN0cyByZWZlciB0byB0aGUgc2FtZSBjbGFzcy4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgdHlwZSkgewotICAgIHJldHVybiAodHlwZSBpbnN0YW5jZW9mIE9iamVjdFR5cGUpPwotICAgICAgKChPYmplY3RUeXBlKXR5cGUpLmNsYXNzX25hbWUuZXF1YWxzKGNsYXNzX25hbWUpIDogZmFsc2U7Ci0gIH0KLQotICAvKioKLSAgICogSWYgInRoaXMiIGRvZXNuJ3QgcmVmZXJlbmNlIGEgY2xhc3MsIGl0IHJlZmVyZW5jZXMgYW4gaW50ZXJmYWNlCi0gICAqIG9yIGEgbm9uLWV4aXN0YW50IGVudGl0eS4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIHJlZmVyZW5jZXNDbGFzcygpewotICAgIEphdmFDbGFzcyBqYyA9IFJlcG9zaXRvcnkubG9va3VwQ2xhc3MoY2xhc3NfbmFtZSk7Ci0gICAgaWYgKGpjID09IG51bGwpCi0gICAgICByZXR1cm4gZmFsc2U7Ci0gICAgZWxzZQotICAgICAgcmV0dXJuIGpjLmlzQ2xhc3MoKTsKLSAgfQotCi0gIC8qKgotICAgKiBJZiAidGhpcyIgZG9lc24ndCByZWZlcmVuY2UgYW4gaW50ZXJmYWNlLCBpdCByZWZlcmVuY2VzIGEgY2xhc3MKLSAgICogb3IgYSBub24tZXhpc3RhbnQgZW50aXR5LgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gcmVmZXJlbmNlc0ludGVyZmFjZSgpewotICAgIEphdmFDbGFzcyBqYyA9IFJlcG9zaXRvcnkubG9va3VwQ2xhc3MoY2xhc3NfbmFtZSk7Ci0gICAgaWYgKGpjID09IG51bGwpCi0gICAgICByZXR1cm4gZmFsc2U7Ci0gICAgZWxzZQotICAgICAgcmV0dXJuICFqYy5pc0NsYXNzKCk7Ci0gIH0KLQotICBwdWJsaWMgYm9vbGVhbiBzdWJjbGFzc09mKE9iamVjdFR5cGUgc3VwZXJjbGFzcyl7Ci0gICAgaWYgKHRoaXMucmVmZXJlbmNlc0ludGVyZmFjZSgpIHx8IHN1cGVyY2xhc3MucmVmZXJlbmNlc0ludGVyZmFjZSgpKQotICAgICAgcmV0dXJuIGZhbHNlOwotCi0gICAgcmV0dXJuIFJlcG9zaXRvcnkuaW5zdGFuY2VPZih0aGlzLmNsYXNzX25hbWUsIHN1cGVyY2xhc3MuY2xhc3NfbmFtZSk7Ci0gIH0KLQotICAvKioKLSAgICogSmF2YSBWaXJ0dWFsIE1hY2hpbmUgU3BlY2lmaWNhdGlvbiBlZGl0aW9uIDIsIDUuNC40IEFjY2VzcyBDb250cm9sCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBhY2Nlc3NpYmxlVG8oT2JqZWN0VHlwZSBhY2Nlc3NvcikgewotICAgIEphdmFDbGFzcyBqYyA9IFJlcG9zaXRvcnkubG9va3VwQ2xhc3MoY2xhc3NfbmFtZSk7Ci0KLSAgICBpZihqYy5pc1B1YmxpYygpKSB7Ci0gICAgICByZXR1cm4gdHJ1ZTsKLSAgICB9IGVsc2UgewotICAgICAgSmF2YUNsYXNzIGFjYyA9IFJlcG9zaXRvcnkubG9va3VwQ2xhc3MoYWNjZXNzb3IuY2xhc3NfbmFtZSk7Ci0gICAgICByZXR1cm4gYWNjLmdldFBhY2thZ2VOYW1lKCkuZXF1YWxzKGpjLmdldFBhY2thZ2VOYW1lKCkpOwotICAgIH0KLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvUE9QLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9QT1AuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMzAwYTZiZS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9QT1AuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDg4ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8qKgotICogUE9QIC0gUG9wIHRvcCBvcGVyYW5kIHN0YWNrIHdvcmQKLSAqCi0gKiA8UFJFPlN0YWNrOiAuLi4sIHdvcmQgLSZndDsgLi4uPC9QUkU+Ci0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGNsYXNzIFBPUCBleHRlbmRzIFN0YWNrSW5zdHJ1Y3Rpb24gaW1wbGVtZW50cyBQb3BJbnN0cnVjdGlvbiB7Ci0gIHB1YmxpYyBQT1AoKSB7Ci0gICAgc3VwZXIoY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLlBPUCk7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBDYWxsIGNvcnJlc3BvbmRpbmcgdmlzaXRvciBtZXRob2QocykuIFRoZSBvcmRlciBpczoKLSAgICogQ2FsbCB2aXNpdG9yIG1ldGhvZHMgb2YgaW1wbGVtZW50ZWQgaW50ZXJmYWNlcyBmaXJzdCwgdGhlbgotICAgKiBjYWxsIG1ldGhvZHMgYWNjb3JkaW5nIHRvIHRoZSBjbGFzcyBoaWVyYXJjaHkgaW4gZGVzY2VuZGluZyBvcmRlciwKLSAgICogaS5lLiwgdGhlIG1vc3Qgc3BlY2lmaWMgdmlzaXRYWFgoKSBjYWxsIGNvbWVzIGxhc3QuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgdi52aXNpdFN0YWNrQ29uc3VtZXIodGhpcyk7Ci0gICAgdi52aXNpdFBvcEluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRTdGFja0luc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRQT1AodGhpcyk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL1BPUDIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL1BPUDIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYWViY2FkYS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9QT1AyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4OCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIFBPUDIgLSBQb3AgdHdvIHRvcCBvcGVyYW5kIHN0YWNrIHdvcmRzCi0gKgotICogPFBSRT5TdGFjazogLi4uLCB3b3JkMiwgd29yZDEgLSZndDsgLi4uPC9QUkU+Ci0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGNsYXNzIFBPUDIgZXh0ZW5kcyBTdGFja0luc3RydWN0aW9uIGltcGxlbWVudHMgUG9wSW5zdHJ1Y3Rpb24gewotICBwdWJsaWMgUE9QMigpIHsKLSAgICBzdXBlcihjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuUE9QMik7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBDYWxsIGNvcnJlc3BvbmRpbmcgdmlzaXRvciBtZXRob2QocykuIFRoZSBvcmRlciBpczoKLSAgICogQ2FsbCB2aXNpdG9yIG1ldGhvZHMgb2YgaW1wbGVtZW50ZWQgaW50ZXJmYWNlcyBmaXJzdCwgdGhlbgotICAgKiBjYWxsIG1ldGhvZHMgYWNjb3JkaW5nIHRvIHRoZSBjbGFzcyBoaWVyYXJjaHkgaW4gZGVzY2VuZGluZyBvcmRlciwKLSAgICogaS5lLiwgdGhlIG1vc3Qgc3BlY2lmaWMgdmlzaXRYWFgoKSBjYWxsIGNvbWVzIGxhc3QuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgdi52aXNpdFN0YWNrQ29uc3VtZXIodGhpcyk7Ci0gICAgdi52aXNpdFBvcEluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRTdGFja0luc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRQT1AyKHRoaXMpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9QVVNILmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9QVVNILmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDMxYTc4ODQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvUFVTSC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTk4ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzOwotaW1wb3J0IGphdmEuaW8uKjsKLQotLyoqCi0gKiBXcmFwcGVyIGNsYXNzIGZvciBwdXNoIG9wZXJhdGlvbnMsIHdoaWNoIGFyZSBpbXBsZW1lbnRlZCBlaXRoZXIgYXMgQklQVVNILAotICogTERDIG9yIHhDT05TVF9uIGluc3RydWN0aW9ucy4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgUFVTSAotICBpbXBsZW1lbnRzIENvbXBvdW5kSW5zdHJ1Y3Rpb24sIFZhcmlhYmxlTGVuZ3RoSW5zdHJ1Y3Rpb24sIEluc3RydWN0aW9uQ29uc3RhbnRzCi17Ci0gIHByaXZhdGUgSW5zdHJ1Y3Rpb24gaW5zdHJ1Y3Rpb247Ci0KLSAgLyoqCi0gICAqIFRoaXMgY29uc3RydWN0b3IgYWxzbyBhcHBsaWVzIGZvciB2YWx1ZXMgb2YgdHlwZSBzaG9ydCwgY2hhciwgYnl0ZQotICAgKgotICAgKiBAcGFyYW0gY3AgQ29uc3RhbnQgcG9vbAotICAgKiBAcGFyYW0gdmFsdWUgdG8gYmUgcHVzaGVkCi0gICAqLwotICBwdWJsaWMgUFVTSChDb25zdGFudFBvb2xHZW4gY3AsIGludCB2YWx1ZSkgewotICAgIGlmKCh2YWx1ZSA+PSAtMSkgJiYgKHZhbHVlIDw9IDUpKSAvLyBVc2UgSUNPTlNUX24KLSAgICAgIGluc3RydWN0aW9uID0gSU5TVFJVQ1RJT05TW0NvbnN0YW50cy5JQ09OU1RfMCArIHZhbHVlXTsKLSAgICBlbHNlIGlmKCh2YWx1ZSA+PSAtMTI4KSAmJiAodmFsdWUgPD0gMTI3KSkgLy8gVXNlIEJJUFVTSAotICAgICAgaW5zdHJ1Y3Rpb24gPSBuZXcgQklQVVNIKChieXRlKXZhbHVlKTsKLSAgICBlbHNlIGlmKCh2YWx1ZSA+PSAtMzI3NjgpICYmICh2YWx1ZSA8PSAzMjc2NykpIC8vIFVzZSBTSVBVU0gKLSAgICAgIGluc3RydWN0aW9uID0gbmV3IFNJUFVTSCgoc2hvcnQpdmFsdWUpOwotICAgIGVsc2UgLy8gSWYgZXZlcnl0aGluZyBmYWlscyBjcmVhdGUgYSBDb25zdGFudCBwb29sIGVudHJ5Ci0gICAgICBpbnN0cnVjdGlvbiA9IG5ldyBMREMoY3AuYWRkSW50ZWdlcih2YWx1ZSkpOwotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBjcCBDb25zdGFudCBwb29sCi0gICAqIEBwYXJhbSB2YWx1ZSB0byBiZSBwdXNoZWQKLSAgICovCi0gIHB1YmxpYyBQVVNIKENvbnN0YW50UG9vbEdlbiBjcCwgYm9vbGVhbiB2YWx1ZSkgewotICAgIGluc3RydWN0aW9uID0gSU5TVFJVQ1RJT05TW0NvbnN0YW50cy5JQ09OU1RfMCArICh2YWx1ZT8gMSA6IDApXTsKLSAgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gY3AgQ29uc3RhbnQgcG9vbAotICAgKiBAcGFyYW0gdmFsdWUgdG8gYmUgcHVzaGVkCi0gICAqLwotICBwdWJsaWMgUFVTSChDb25zdGFudFBvb2xHZW4gY3AsIGZsb2F0IHZhbHVlKSB7Ci0gICAgaWYodmFsdWUgPT0gMC4wKQotICAgICAgaW5zdHJ1Y3Rpb24gPSBGQ09OU1RfMDsKLSAgICBlbHNlIGlmKHZhbHVlID09IDEuMCkKLSAgICAgIGluc3RydWN0aW9uID0gRkNPTlNUXzE7Ci0gICAgZWxzZSBpZih2YWx1ZSA9PSAyLjApCi0gICAgICBpbnN0cnVjdGlvbiA9IEZDT05TVF8yOwotICAgIGVsc2UgLy8gQ3JlYXRlIGEgQ29uc3RhbnQgcG9vbCBlbnRyeQotICAgICAgaW5zdHJ1Y3Rpb24gPSBuZXcgTERDKGNwLmFkZEZsb2F0KHZhbHVlKSk7Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIGNwIENvbnN0YW50IHBvb2wKLSAgICogQHBhcmFtIHZhbHVlIHRvIGJlIHB1c2hlZAotICAgKi8KLSAgcHVibGljIFBVU0goQ29uc3RhbnRQb29sR2VuIGNwLCBsb25nIHZhbHVlKSB7Ci0gICAgaWYodmFsdWUgPT0gMCkKLSAgICAgIGluc3RydWN0aW9uID0gTENPTlNUXzA7Ci0gICAgZWxzZSBpZih2YWx1ZSA9PSAxKQotICAgICAgaW5zdHJ1Y3Rpb24gPSBMQ09OU1RfMTsKLSAgICBlbHNlIC8vIENyZWF0ZSBhIENvbnN0YW50IHBvb2wgZW50cnkKLSAgICAgIGluc3RydWN0aW9uID0gbmV3IExEQzJfVyhjcC5hZGRMb25nKHZhbHVlKSk7Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIGNwIENvbnN0YW50IHBvb2wKLSAgICogQHBhcmFtIHZhbHVlIHRvIGJlIHB1c2hlZAotICAgKi8KLSAgcHVibGljIFBVU0goQ29uc3RhbnRQb29sR2VuIGNwLCBkb3VibGUgdmFsdWUpIHsKLSAgICBpZih2YWx1ZSA9PSAwLjApCi0gICAgICBpbnN0cnVjdGlvbiA9IERDT05TVF8wOwotICAgIGVsc2UgaWYodmFsdWUgPT0gMS4wKQotICAgICAgaW5zdHJ1Y3Rpb24gPSBEQ09OU1RfMTsKLSAgICBlbHNlIC8vIENyZWF0ZSBhIENvbnN0YW50IHBvb2wgZW50cnkKLSAgICAgIGluc3RydWN0aW9uID0gbmV3IExEQzJfVyhjcC5hZGREb3VibGUodmFsdWUpKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gY3AgQ29uc3RhbnQgcG9vbAotICAgKiBAcGFyYW0gdmFsdWUgdG8gYmUgcHVzaGVkCi0gICAqLwotICBwdWJsaWMgUFVTSChDb25zdGFudFBvb2xHZW4gY3AsIFN0cmluZyB2YWx1ZSkgewotICAgIGlmKHZhbHVlID09IG51bGwpCi0gICAgICBpbnN0cnVjdGlvbiA9IEFDT05TVF9OVUxMOwotICAgIGVsc2UgLy8gQ3JlYXRlIGEgQ29uc3RhbnQgcG9vbCBlbnRyeQotICAgICAgaW5zdHJ1Y3Rpb24gPSBuZXcgTERDKGNwLmFkZFN0cmluZyh2YWx1ZSkpOwotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBjcCBDb25zdGFudCBwb29sCi0gICAqIEBwYXJhbSB2YWx1ZSB0byBiZSBwdXNoZWQKLSAgICovCi0gIHB1YmxpYyBQVVNIKENvbnN0YW50UG9vbEdlbiBjcCwgTnVtYmVyIHZhbHVlKSB7Ci0gICAgaWYoKHZhbHVlIGluc3RhbmNlb2YgSW50ZWdlcikgfHwgKHZhbHVlIGluc3RhbmNlb2YgU2hvcnQpIHx8ICh2YWx1ZSBpbnN0YW5jZW9mIEJ5dGUpKQotICAgICAgaW5zdHJ1Y3Rpb24gPSBuZXcgUFVTSChjcCwgdmFsdWUuaW50VmFsdWUoKSkuaW5zdHJ1Y3Rpb247Ci0gICAgZWxzZSBpZih2YWx1ZSBpbnN0YW5jZW9mIERvdWJsZSkKLSAgICAgIGluc3RydWN0aW9uID0gbmV3IFBVU0goY3AsIHZhbHVlLmRvdWJsZVZhbHVlKCkpLmluc3RydWN0aW9uOwotICAgIGVsc2UgaWYodmFsdWUgaW5zdGFuY2VvZiBGbG9hdCkKLSAgICAgIGluc3RydWN0aW9uID0gbmV3IFBVU0goY3AsIHZhbHVlLmZsb2F0VmFsdWUoKSkuaW5zdHJ1Y3Rpb247Ci0gICAgZWxzZSBpZih2YWx1ZSBpbnN0YW5jZW9mIExvbmcpCi0gICAgICBpbnN0cnVjdGlvbiA9IG5ldyBQVVNIKGNwLCB2YWx1ZS5sb25nVmFsdWUoKSkuaW5zdHJ1Y3Rpb247Ci0gICAgZWxzZQotICAgICAgdGhyb3cgbmV3IENsYXNzR2VuRXhjZXB0aW9uKCJXaGF0J3MgdGhpczogIiArIHZhbHVlKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gY3AgQ29uc3RhbnQgcG9vbAotICAgKiBAcGFyYW0gdmFsdWUgdG8gYmUgcHVzaGVkCi0gICAqLwotICBwdWJsaWMgUFVTSChDb25zdGFudFBvb2xHZW4gY3AsIENoYXJhY3RlciB2YWx1ZSkgewotICAgIHRoaXMoY3AsIChpbnQpdmFsdWUuY2hhclZhbHVlKCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBjcCBDb25zdGFudCBwb29sCi0gICAqIEBwYXJhbSB2YWx1ZSB0byBiZSBwdXNoZWQKLSAgICovCi0gIHB1YmxpYyBQVVNIKENvbnN0YW50UG9vbEdlbiBjcCwgQm9vbGVhbiB2YWx1ZSkgewotICAgIHRoaXMoY3AsIHZhbHVlLmJvb2xlYW5WYWx1ZSgpKTsKLSAgfQotCi0gIHB1YmxpYyBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgZ2V0SW5zdHJ1Y3Rpb25MaXN0KCkgewotICAgIHJldHVybiBuZXcgSW5zdHJ1Y3Rpb25MaXN0KGluc3RydWN0aW9uKTsKLSAgfQotCi0gIHB1YmxpYyBmaW5hbCBJbnN0cnVjdGlvbiBnZXRJbnN0cnVjdGlvbigpIHsKLSAgICByZXR1cm4gaW5zdHJ1Y3Rpb247Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBtbmVtb25pYyBmb3IgaW5zdHJ1Y3Rpb24KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0gICAgcmV0dXJuIGluc3RydWN0aW9uLnRvU3RyaW5nKCkgKyAiIChQVVNIKSI7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL1BVVEZJRUxELmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9QVVRGSUVMRC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA5NTcyNTU0Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL1BVVEZJRUxELmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMjEgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50czsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5FeGNlcHRpb25Db25zdGFudHM7Ci0KLS8qKgotICogUFVURklFTEQgLSBQdXQgZmllbGQgaW4gb2JqZWN0Ci0gKiA8UFJFPlN0YWNrOiAuLi4sIG9iamVjdHJlZiwgdmFsdWUgLSZndDsgLi4uPC9QUkU+Ci0gKiBPUgotICogPFBSRT5TdGFjazogLi4uLCBvYmplY3RyZWYsIHZhbHVlLndvcmQxLCB2YWx1ZS53b3JkMiAtJmd0OyAuLi48L1BSRT4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgUFVURklFTEQKLSAgICBleHRlbmRzIEZpZWxkSW5zdHJ1Y3Rpb24KLSAgICBpbXBsZW1lbnRzIFBvcEluc3RydWN0aW9uLEV4Y2VwdGlvblRocm93ZXJ7Ci0gIC8qKgotICAgKiBFbXB0eSBjb25zdHJ1Y3RvciBuZWVkZWQgZm9yIHRoZSBDbGFzcy5uZXdJbnN0YW5jZSgpIHN0YXRlbWVudCBpbgotICAgKiBJbnN0cnVjdGlvbi5yZWFkSW5zdHJ1Y3Rpb24oKS4gTm90IHRvIGJlIHVzZWQgb3RoZXJ3aXNlLgotICAgKi8KLSAgUFVURklFTEQoKSB7fQotCi0gIHB1YmxpYyBQVVRGSUVMRChpbnQgaW5kZXgpIHsKLSAgICBzdXBlcihDb25zdGFudHMuUFVURklFTEQsIGluZGV4KTsKLSAgfQotCi0gIHB1YmxpYyBpbnQgY29uc3VtZVN0YWNrKENvbnN0YW50UG9vbEdlbiBjcGcpIHsgcmV0dXJuIGdldEZpZWxkU2l6ZShjcGcpICsgMTsgfQotCi0gIHB1YmxpYyBDbGFzc1tdIGdldEV4Y2VwdGlvbnMoKSB7Ci0gICAgQ2xhc3NbXSBjcyA9IG5ldyBDbGFzc1syICsgRXhjZXB0aW9uQ29uc3RhbnRzLkVYQ1NfRklFTERfQU5EX01FVEhPRF9SRVNPTFVUSU9OLmxlbmd0aF07Ci0KLSAgICBTeXN0ZW0uYXJyYXljb3B5KEV4Y2VwdGlvbkNvbnN0YW50cy5FWENTX0ZJRUxEX0FORF9NRVRIT0RfUkVTT0xVVElPTiwgMCwKLSAgICAgICAgICAgICAgICAgICAgIGNzLCAwLCBFeGNlcHRpb25Db25zdGFudHMuRVhDU19GSUVMRF9BTkRfTUVUSE9EX1JFU09MVVRJT04ubGVuZ3RoKTsKLQotICAgIGNzW0V4Y2VwdGlvbkNvbnN0YW50cy5FWENTX0ZJRUxEX0FORF9NRVRIT0RfUkVTT0xVVElPTi5sZW5ndGgrMV0gPQotICAgICAgRXhjZXB0aW9uQ29uc3RhbnRzLklOQ09NUEFUSUJMRV9DTEFTU19DSEFOR0VfRVJST1I7Ci0gICAgY3NbRXhjZXB0aW9uQ29uc3RhbnRzLkVYQ1NfRklFTERfQU5EX01FVEhPRF9SRVNPTFVUSU9OLmxlbmd0aF0gPQotICAgICAgRXhjZXB0aW9uQ29uc3RhbnRzLk5VTExfUE9JTlRFUl9FWENFUFRJT047Ci0KLSAgICByZXR1cm4gY3M7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBDYWxsIGNvcnJlc3BvbmRpbmcgdmlzaXRvciBtZXRob2QocykuIFRoZSBvcmRlciBpczoKLSAgICogQ2FsbCB2aXNpdG9yIG1ldGhvZHMgb2YgaW1wbGVtZW50ZWQgaW50ZXJmYWNlcyBmaXJzdCwgdGhlbgotICAgKiBjYWxsIG1ldGhvZHMgYWNjb3JkaW5nIHRvIHRoZSBjbGFzcyBoaWVyYXJjaHkgaW4gZGVzY2VuZGluZyBvcmRlciwKLSAgICogaS5lLiwgdGhlIG1vc3Qgc3BlY2lmaWMgdmlzaXRYWFgoKSBjYWxsIGNvbWVzIGxhc3QuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgdi52aXNpdEV4Y2VwdGlvblRocm93ZXIodGhpcyk7Ci0gICAgdi52aXNpdFN0YWNrQ29uc3VtZXIodGhpcyk7Ci0gICAgdi52aXNpdFBvcEluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRUeXBlZEluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRMb2FkQ2xhc3ModGhpcyk7Ci0gICAgdi52aXNpdENQSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdEZpZWxkT3JNZXRob2QodGhpcyk7Ci0gICAgdi52aXNpdEZpZWxkSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdFBVVEZJRUxEKHRoaXMpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9QVVRTVEFUSUMuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL1BVVFNUQVRJQy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhNDExNmI2Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL1BVVFNUQVRJQy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTE3ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuRXhjZXB0aW9uQ29uc3RhbnRzOwotCi0vKioKLSAqIFBVVFNUQVRJQyAtIFB1dCBzdGF0aWMgZmllbGQgaW4gY2xhc3MKLSAqIDxQUkU+U3RhY2s6IC4uLiwgdmFsdWUgLSZndDsgLi4uPC9QUkU+Ci0gKiBPUgotICogPFBSRT5TdGFjazogLi4uLCB2YWx1ZS53b3JkMSwgdmFsdWUud29yZDIgLSZndDsgLi4uPC9QUkU+Ci0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGNsYXNzIFBVVFNUQVRJQyBleHRlbmRzIEZpZWxkSW5zdHJ1Y3Rpb24KLSAgaW1wbGVtZW50cyBFeGNlcHRpb25UaHJvd2VyLCBQb3BJbnN0cnVjdGlvbiB7Ci0gIC8qKgotICAgKiBFbXB0eSBjb25zdHJ1Y3RvciBuZWVkZWQgZm9yIHRoZSBDbGFzcy5uZXdJbnN0YW5jZSgpIHN0YXRlbWVudCBpbgotICAgKiBJbnN0cnVjdGlvbi5yZWFkSW5zdHJ1Y3Rpb24oKS4gTm90IHRvIGJlIHVzZWQgb3RoZXJ3aXNlLgotICAgKi8KLSAgUFVUU1RBVElDKCkge30KLQotICBwdWJsaWMgUFVUU1RBVElDKGludCBpbmRleCkgewotICAgIHN1cGVyKENvbnN0YW50cy5QVVRTVEFUSUMsIGluZGV4KTsKLSAgfQotCi0gIHB1YmxpYyBpbnQgY29uc3VtZVN0YWNrKENvbnN0YW50UG9vbEdlbiBjcGcpIHsgcmV0dXJuIGdldEZpZWxkU2l6ZShjcGcpOyB9Ci0KLSAgcHVibGljIENsYXNzW10gZ2V0RXhjZXB0aW9ucygpIHsKLSAgICBDbGFzc1tdIGNzID0gbmV3IENsYXNzWzEgKyBFeGNlcHRpb25Db25zdGFudHMuRVhDU19GSUVMRF9BTkRfTUVUSE9EX1JFU09MVVRJT04ubGVuZ3RoXTsKLQotICAgIFN5c3RlbS5hcnJheWNvcHkoRXhjZXB0aW9uQ29uc3RhbnRzLkVYQ1NfRklFTERfQU5EX01FVEhPRF9SRVNPTFVUSU9OLCAwLAotICAgICAgICAgICAgICAgICAgICAgY3MsIDAsIEV4Y2VwdGlvbkNvbnN0YW50cy5FWENTX0ZJRUxEX0FORF9NRVRIT0RfUkVTT0xVVElPTi5sZW5ndGgpOwotICAgIGNzW0V4Y2VwdGlvbkNvbnN0YW50cy5FWENTX0ZJRUxEX0FORF9NRVRIT0RfUkVTT0xVVElPTi5sZW5ndGhdID0KLSAgICAgIEV4Y2VwdGlvbkNvbnN0YW50cy5JTkNPTVBBVElCTEVfQ0xBU1NfQ0hBTkdFX0VSUk9SOwotCi0gICAgcmV0dXJuIGNzOwotICB9Ci0KLQotICAvKioKLSAgICogQ2FsbCBjb3JyZXNwb25kaW5nIHZpc2l0b3IgbWV0aG9kKHMpLiBUaGUgb3JkZXIgaXM6Ci0gICAqIENhbGwgdmlzaXRvciBtZXRob2RzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMgZmlyc3QsIHRoZW4KLSAgICogY2FsbCBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY2xhc3MgaGllcmFyY2h5IGluIGRlc2NlbmRpbmcgb3JkZXIsCi0gICAqIGkuZS4sIHRoZSBtb3N0IHNwZWNpZmljIHZpc2l0WFhYKCkgY2FsbCBjb21lcyBsYXN0LgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRFeGNlcHRpb25UaHJvd2VyKHRoaXMpOwotICAgIHYudmlzaXRTdGFja0NvbnN1bWVyKHRoaXMpOwotICAgIHYudmlzaXRQb3BJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0VHlwZWRJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0TG9hZENsYXNzKHRoaXMpOwotICAgIHYudmlzaXRDUEluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRGaWVsZE9yTWV0aG9kKHRoaXMpOwotICAgIHYudmlzaXRGaWVsZEluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRQVVRTVEFUSUModGhpcyk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL1BvcEluc3RydWN0aW9uLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9Qb3BJbnN0cnVjdGlvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0MTY4ZDJmLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL1BvcEluc3RydWN0aW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3MCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIERlbm90ZXMgYW4gdW5wYXJhbWV0ZXJpemVkIGluc3RydWN0aW9uIHRvIHBvcCBhIHZhbHVlIG9uIHRvcCBmcm9tIHRoZSBzdGFjaywKLSAqIHN1Y2ggYXMgSVNUT1JFLCBQT1AsIFBVVFNUQVRJQy4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICogQHNlZSBJU1RPUkUKLSAqIEBzZWUgUE9QCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgUG9wSW5zdHJ1Y3Rpb24gZXh0ZW5kcyBTdGFja0NvbnN1bWVyIHsKLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL1B1c2hJbnN0cnVjdGlvbi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvUHVzaEluc3RydWN0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGYxNDNjOTcuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvUHVzaEluc3RydWN0aW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3NSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIERlbm90ZXMgYW4gdW5wYXJhbWV0ZXJpemVkIGluc3RydWN0aW9uIHRvIHByb2R1Y2UgYSB2YWx1ZSBvbiB0b3Agb2YgdGhlIHN0YWNrLAotICogc3VjaCBhcyBJTE9BRCwgTERDLCBTSVBVU0gsIERVUCwgSUNPTlNULCBldGMuCi0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLQotICogQHNlZSBJTE9BRAotICogQHNlZSBJQ09OU1QKLSAqIEBzZWUgTERDCi0gKiBAc2VlIERVUAotICogQHNlZSBTSVBVU0gKLSAqIEBzZWUgR0VUU1RBVElDCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgUHVzaEluc3RydWN0aW9uIGV4dGVuZHMgU3RhY2tQcm9kdWNlciB7Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9SRVQuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL1JFVC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyN2UyNDJhLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL1JFVC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTY0ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1pbXBvcnQgamF2YS5pby4qOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLnV0aWwuQnl0ZVNlcXVlbmNlOwotCi0vKioKLSAqIFJFVCAtIFJldHVybiBmcm9tIHN1YnJvdXRpbmUKLSAqCi0gKiA8UFJFPlN0YWNrOiAuLi4sIC0mZ3Q7IC4uLiwgYWRkcmVzczwvUFJFPgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBSRVQgZXh0ZW5kcyBJbnN0cnVjdGlvbiBpbXBsZW1lbnRzIEluZGV4ZWRJbnN0cnVjdGlvbiwgVHlwZWRJbnN0cnVjdGlvbiB7Ci0gIHByaXZhdGUgYm9vbGVhbiB3aWRlOwotICBwcml2YXRlIGludCAgICAgaW5kZXg7IC8vIGluZGV4IHRvIGxvY2FsIHZhcmlhYmxlIGNvbnRhaW5nIHRoZSByZXR1cm4gYWRkcmVzcwotCi0gIC8qKgotICAgKiBFbXB0eSBjb25zdHJ1Y3RvciBuZWVkZWQgZm9yIHRoZSBDbGFzcy5uZXdJbnN0YW5jZSgpIHN0YXRlbWVudCBpbgotICAgKiBJbnN0cnVjdGlvbi5yZWFkSW5zdHJ1Y3Rpb24oKS4gTm90IHRvIGJlIHVzZWQgb3RoZXJ3aXNlLgotICAgKi8KLSAgUkVUKCkge30KLQotICBwdWJsaWMgUkVUKGludCBpbmRleCkgewotICAgIHN1cGVyKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5SRVQsIChzaG9ydCkyKTsKLSAgICBzZXRJbmRleChpbmRleCk7ICAgLy8gTWF5IHNldCB3aWRlIGFzIHNpZGUgZWZmZWN0Ci0gIH0KLQotICAvKioKLSAgICogRHVtcCBpbnN0cnVjdGlvbiBhcyBieXRlIGNvZGUgdG8gc3RyZWFtIG91dC4KLSAgICogQHBhcmFtIG91dCBPdXRwdXQgc3RyZWFtCi0gICAqLwotICBwdWJsaWMgdm9pZCBkdW1wKERhdGFPdXRwdXRTdHJlYW0gb3V0KSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgIGlmKHdpZGUpCi0gICAgICBvdXQud3JpdGVCeXRlKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5XSURFKTsKLQotICAgIG91dC53cml0ZUJ5dGUob3Bjb2RlKTsKLQotICAgIGlmKHdpZGUpCi0gICAgICBvdXQud3JpdGVTaG9ydChpbmRleCk7Ci0gICAgZWxzZQotICAgICAgb3V0LndyaXRlQnl0ZShpbmRleCk7Ci0gIH0KLQotICBwcml2YXRlIGZpbmFsIHZvaWQgc2V0V2lkZSgpIHsKLSAgICBpZih3aWRlID0gaW5kZXggPiBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuTUFYX0JZVEUpCi0gICAgICBsZW5ndGggPSA0OyAvLyBJbmNsdWRpbmcgdGhlIHdpZGUgYnl0ZQotICAgIGVsc2UKLSAgICAgIGxlbmd0aCA9IDI7Ci0gIH0KLQotICAvKioKLSAgICogUmVhZCBuZWVkZWQgZGF0YSAoZS5nLiBpbmRleCkgZnJvbSBmaWxlLgotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgaW5pdEZyb21GaWxlKEJ5dGVTZXF1ZW5jZSBieXRlcywgYm9vbGVhbiB3aWRlKSB0aHJvd3MgSU9FeGNlcHRpb24KLSAgewotICAgIHRoaXMud2lkZSA9IHdpZGU7Ci0KLSAgICBpZih3aWRlKSB7Ci0gICAgICBpbmRleCAgPSBieXRlcy5yZWFkVW5zaWduZWRTaG9ydCgpOwotICAgICAgbGVuZ3RoID0gNDsKLSAgICB9IGVsc2UgewotICAgICAgaW5kZXggPSBieXRlcy5yZWFkVW5zaWduZWRCeXRlKCk7Ci0gICAgICBsZW5ndGggPSAyOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIGluZGV4IG9mIGxvY2FsIHZhcmlhYmxlIGNvbnRhaW5nIHRoZSByZXR1cm4gYWRkcmVzcwotICAgKi8KLSAgcHVibGljIGZpbmFsIGludCBnZXRJbmRleCgpIHsgcmV0dXJuIGluZGV4OyB9Ci0KLSAgLyoqCi0gICAqIFNldCBpbmRleCBvZiBsb2NhbCB2YXJpYWJsZSBjb250YWluZyB0aGUgcmV0dXJuIGFkZHJlc3MKLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHNldEluZGV4KGludCBuKSB7Ci0gICAgaWYobiA8IDApCi0gICAgICB0aHJvdyBuZXcgQ2xhc3NHZW5FeGNlcHRpb24oIk5lZ2F0aXZlIGluZGV4IHZhbHVlOiAiICsgbik7Ci0KLSAgICBpbmRleCA9IG47Ci0gICAgc2V0V2lkZSgpOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gbW5lbW9uaWMgZm9yIGluc3RydWN0aW9uCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKGJvb2xlYW4gdmVyYm9zZSkgewotICAgIHJldHVybiBzdXBlci50b1N0cmluZyh2ZXJib3NlKSArICIgIiArIGluZGV4OwotICB9Ci0KLSAgLyoqIEByZXR1cm4gcmV0dXJuIGFkZHJlc3MgdHlwZQotICAgKi8KLSAgcHVibGljIFR5cGUgZ2V0VHlwZShDb25zdGFudFBvb2xHZW4gY3ApIHsKLSAgICAgIHJldHVybiBSZXR1cm5hZGRyZXNzVHlwZS5OT19UQVJHRVQ7Ci0gIH0KLQotICAvKioKLSAgICogQ2FsbCBjb3JyZXNwb25kaW5nIHZpc2l0b3IgbWV0aG9kKHMpLiBUaGUgb3JkZXIgaXM6Ci0gICAqIENhbGwgdmlzaXRvciBtZXRob2RzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMgZmlyc3QsIHRoZW4KLSAgICogY2FsbCBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY2xhc3MgaGllcmFyY2h5IGluIGRlc2NlbmRpbmcgb3JkZXIsCi0gICAqIGkuZS4sIHRoZSBtb3N0IHNwZWNpZmljIHZpc2l0WFhYKCkgY2FsbCBjb21lcyBsYXN0LgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRSRVQodGhpcyk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL1JFVFVSTi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvUkVUVVJOLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGY5MzdlNTAuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvUkVUVVJOLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4OCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIFJFVFVSTiAtICBSZXR1cm4gZnJvbSB2b2lkIG1ldGhvZAotICogPFBSRT5TdGFjazogLi4uIC0mZ3Q7ICZsdDtlbXB0eSZndDs8L1BSRT4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgUkVUVVJOIGV4dGVuZHMgUmV0dXJuSW5zdHJ1Y3Rpb24gewotICBwdWJsaWMgUkVUVVJOKCkgewotICAgIHN1cGVyKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5SRVRVUk4pOwotICB9Ci0KLQotICAvKioKLSAgICogQ2FsbCBjb3JyZXNwb25kaW5nIHZpc2l0b3IgbWV0aG9kKHMpLiBUaGUgb3JkZXIgaXM6Ci0gICAqIENhbGwgdmlzaXRvciBtZXRob2RzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMgZmlyc3QsIHRoZW4KLSAgICogY2FsbCBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY2xhc3MgaGllcmFyY2h5IGluIGRlc2NlbmRpbmcgb3JkZXIsCi0gICAqIGkuZS4sIHRoZSBtb3N0IHNwZWNpZmljIHZpc2l0WFhYKCkgY2FsbCBjb21lcyBsYXN0LgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRFeGNlcHRpb25UaHJvd2VyKHRoaXMpOwotICAgIHYudmlzaXRUeXBlZEluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRTdGFja0NvbnN1bWVyKHRoaXMpOwotICAgIHYudmlzaXRSZXR1cm5JbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0UkVUVVJOKHRoaXMpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9SZWZlcmVuY2VUeXBlLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9SZWZlcmVuY2VUeXBlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDA5NTZiNTguLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvUmVmZXJlbmNlVHlwZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzUyICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuUmVwb3NpdG9yeTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5jbGFzc2ZpbGUuSmF2YUNsYXNzOwotCi0vKioKLSAqIFN1cGVyIGNsYXNzIGZvciBvYmplY3QgYW5kIGFycmF5IHR5cGVzLgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBSZWZlcmVuY2VUeXBlIGV4dGVuZHMgVHlwZSB7Ci0gIHByb3RlY3RlZCBSZWZlcmVuY2VUeXBlKGJ5dGUgdCwgU3RyaW5nIHMpIHsKLSAgICBzdXBlcih0LCBzKTsKLSAgfQotCi0gIC8qKiBDbGFzcyBpcyBub24tYWJzdHJhY3QgYnV0IG5vdCBpbnN0YW50aWFibGUgZnJvbSB0aGUgb3V0c2lkZQotICAgKi8KLSAgUmVmZXJlbmNlVHlwZSgpIHsKLSAgICBzdXBlcihDb25zdGFudHMuVF9PQkpFQ1QsICI8bnVsbCBvYmplY3Q+Iik7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRydWUgaWZmIHRoaXMgdHlwZSBpcyBjYXN0YWJsZSB0byBhbm90aGVyIHR5cGUgdCBhcyBkZWZpbmVkIGluCi0gICAqIHRoZSBKVk0gc3BlY2lmaWNhdGlvbi4gIFRoZSBjYXNlIHdoZXJlIHRoaXMgaXMgVHlwZS5OVUxMIGlzIG5vdAotICAgKiBkZWZpbmVkIChzZWUgdGhlIENIRUNLQ0FTVCBkZWZpbml0aW9uIGluIHRoZSBKVk0gc3BlY2lmaWNhdGlvbikuCi0gICAqIEhvd2V2ZXIsIGJlY2F1c2UgZS5nLiBDSEVDS0NBU1QgZG9lc24ndCB0aHJvdyBhCi0gICAqIENsYXNzQ2FzdEV4Y2VwdGlvbiB3aGVuIGNhc3RpbmcgYSBudWxsIHJlZmVyZW5jZSB0byBhbnkgT2JqZWN0LAotICAgKiB0cnVlIGlzIHJldHVybmVkIGluIHRoaXMgY2FzZS4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzQ2FzdGFibGVUbyhUeXBlIHQpIHsKLSAgICBpZiAodGhpcy5lcXVhbHMoVHlwZS5OVUxMKSkKLSAgICAgIHJldHVybiB0cnVlOyAgICAgICAgICAgICAgLy8gSWYgdGhpcyBpcyBldmVyIGNoYW5nZWQgaW4gaXNBc3NpZ25tZW50Q29tcGF0aWJsZSgpCi0KLSAgICByZXR1cm4gaXNBc3NpZ25tZW50Q29tcGF0aWJsZVdpdGgodCk7Ci0gICAgLyogWWVzLCBpdCdzIHRydWU6IEl0J3MgdGhlIHNhbWUgZGVmaW5pdGlvbi4KLSAgICAgKiBTZWUgdm1zcGVjMiBBQVNUT1JFIC8gQ0hFQ0tDQVNUIGRlZmluaXRpb25zLgotICAgICAqLwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0cnVlIGlmZiB0aGlzIGlzIGFzc2lnbm1lbnQgY29tcGF0aWJsZSB3aXRoIGFub3RoZXIgdHlwZSB0Ci0gICAqIGFzIGRlZmluZWQgaW4gdGhlIEpWTSBzcGVjaWZpY2F0aW9uOyBzZWUgdGhlIEFBU1RPUkUgZGVmaW5pdGlvbgotICAgKiB0aGVyZS4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzQXNzaWdubWVudENvbXBhdGlibGVXaXRoKFR5cGUgdCkgewotICAgIGlmICghKHQgaW5zdGFuY2VvZiBSZWZlcmVuY2VUeXBlKSkKLSAgICAgIHJldHVybiBmYWxzZTsKLQotICAgIFJlZmVyZW5jZVR5cGUgVCA9IChSZWZlcmVuY2VUeXBlKSB0OwotCi0gICAgaWYgKHRoaXMuZXF1YWxzKFR5cGUuTlVMTCkpCi0gICAgICByZXR1cm4gdHJ1ZTsgLy8gVGhpcyBpcyBub3QgZXhwbGljaXRlbHkgc3RhdGVkLCBidXQgY2xlYXIuIElzbid0IGl0PwotCi0gICAgLyogSWYgdGhpcyBpcyBhIGNsYXNzIHR5cGUgdGhlbgotICAgICAqLwotICAgIGlmICgodGhpcyBpbnN0YW5jZW9mIE9iamVjdFR5cGUpICYmICgoKE9iamVjdFR5cGUpIHRoaXMpLnJlZmVyZW5jZXNDbGFzcygpKSkgewotICAgICAgLyogSWYgVCBpcyBhIGNsYXNzIHR5cGUsIHRoZW4gdGhpcyBtdXN0IGJlIHRoZSBzYW1lIGNsYXNzIGFzIFQsCi0gICAgICAgICBvciB0aGlzIG11c3QgYmUgYSBzdWJjbGFzcyBvZiBUOwotICAgICAgKi8KLSAgICAgIGlmICgoVCBpbnN0YW5jZW9mIE9iamVjdFR5cGUpICYmICgoKE9iamVjdFR5cGUpIFQpLnJlZmVyZW5jZXNDbGFzcygpKSkgewotICAgICAgICBpZiAodGhpcy5lcXVhbHMoVCkpCi0gICAgICAgICAgcmV0dXJuIHRydWU7Ci0KLSAgICAgICAgaWYgKFJlcG9zaXRvcnkuaW5zdGFuY2VPZigoKE9iamVjdFR5cGUpIHRoaXMpLmdldENsYXNzTmFtZSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoT2JqZWN0VHlwZSkgVCkuZ2V0Q2xhc3NOYW1lKCkpKQotICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgfQotCi0gICAgICAvKiBJZiBUIGlzIGFuIGludGVyZmFjZSB0eXBlLCB0aGlzIG11c3QgaW1wbGVtZW50IGludGVyZmFjZSBULgotICAgICAgICovCi0gICAgICBpZiAoKFQgaW5zdGFuY2VvZiBPYmplY3RUeXBlKSAmJiAoKChPYmplY3RUeXBlKSBUKS5yZWZlcmVuY2VzSW50ZXJmYWNlKCkpKSB7Ci0gICAgICAgIGlmIChSZXBvc2l0b3J5LmltcGxlbWVudGF0aW9uT2YoKChPYmplY3RUeXBlKSB0aGlzKS5nZXRDbGFzc05hbWUoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKE9iamVjdFR5cGUpIFQpLmdldENsYXNzTmFtZSgpKSkKLSAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICAvKiBJZiB0aGlzIGlzIGFuIGludGVyZmFjZSB0eXBlLCB0aGVuOgotICAgICAqLwotICAgIGlmICgodGhpcyBpbnN0YW5jZW9mIE9iamVjdFR5cGUpICYmICgoKE9iamVjdFR5cGUpIHRoaXMpLnJlZmVyZW5jZXNJbnRlcmZhY2UoKSkpIHsKLSAgICAgIC8qIElmIFQgaXMgYSBjbGFzcyB0eXBlLCB0aGVuIFQgbXVzdCBiZSBPYmplY3QgKDIuNC43KS4KLSAgICAgICAqLwotICAgICAgaWYgKChUIGluc3RhbmNlb2YgT2JqZWN0VHlwZSkgJiYgKCgoT2JqZWN0VHlwZSkgVCkucmVmZXJlbmNlc0NsYXNzKCkpKSB7Ci0gICAgICAgIGlmIChULmVxdWFscyhUeXBlLk9CSkVDVCkpIHJldHVybiB0cnVlOwotICAgICAgfQotCi0gICAgICAvKiBJZiBUIGlzIGFuIGludGVyZmFjZSB0eXBlLCB0aGVuIFQgbXVzdCBiZSB0aGUgc2FtZSBpbnRlcmZhY2UKLSAgICAgICAqIGFzIHRoaXMgb3IgYSBzdXBlcmludGVyZmFjZSBvZiB0aGlzICgyLjEzLjIpLgotICAgICAgICovCi0gICAgICBpZiAoKFQgaW5zdGFuY2VvZiBPYmplY3RUeXBlKSAmJiAoKChPYmplY3RUeXBlKSBUKS5yZWZlcmVuY2VzSW50ZXJmYWNlKCkpKSB7Ci0gICAgICAgIGlmICh0aGlzLmVxdWFscyhUKSkgcmV0dXJuIHRydWU7Ci0gICAgICAgIGlmIChSZXBvc2l0b3J5LmltcGxlbWVudGF0aW9uT2YoKChPYmplY3RUeXBlKSB0aGlzKS5nZXRDbGFzc05hbWUoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKE9iamVjdFR5cGUpIFQpLmdldENsYXNzTmFtZSgpKSkKLSAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICAvKiBJZiB0aGlzIGlzIGFuIGFycmF5IHR5cGUsIG5hbWVseSwgdGhlIHR5cGUgU0NbXSwgdGhhdCBpcywgYW4KLSAgICAgKiBhcnJheSBvZiBjb21wb25lbnRzIG9mIHR5cGUgU0MsIHRoZW46Ci0gICAgICovCi0gICAgaWYgKHRoaXMgaW5zdGFuY2VvZiBBcnJheVR5cGUpIHsKLSAgICAgIC8qIElmIFQgaXMgYSBjbGFzcyB0eXBlLCB0aGVuIFQgbXVzdCBiZSBPYmplY3QgKDIuNC43KS4KLSAgICAgICAqLwotICAgICAgaWYgKChUIGluc3RhbmNlb2YgT2JqZWN0VHlwZSkgJiYgKCgoT2JqZWN0VHlwZSkgVCkucmVmZXJlbmNlc0NsYXNzKCkpKSB7Ci0gICAgICAgIGlmIChULmVxdWFscyhUeXBlLk9CSkVDVCkpIHJldHVybiB0cnVlOwotICAgICAgfQotCi0gICAgICAvKiBJZiBUIGlzIGFuIGFycmF5IHR5cGUgVENbXSwgdGhhdCBpcywgYW4gYXJyYXkgb2YgY29tcG9uZW50cwotICAgICAgICogb2YgdHlwZSBUQywgdGhlbiBvbmUgb2YgdGhlIGZvbGxvd2luZyBtdXN0IGJlIHRydWU6Ci0gICAgICAgKi8KLSAgICAgIGlmIChUIGluc3RhbmNlb2YgQXJyYXlUeXBlKSB7Ci0gICAgICAgIC8qIFRDIGFuZCBTQyBhcmUgdGhlIHNhbWUgcHJpbWl0aXZlIHR5cGUgKDIuNC4xKS4KLSAgICAgICAgICovCi0gICAgICAgIFR5cGUgc2MgPSAoKEFycmF5VHlwZSkgdGhpcykuZ2V0RWxlbWVudFR5cGUoKTsKLSAgICAgICAgVHlwZSB0YyA9ICgoQXJyYXlUeXBlKSB0aGlzKS5nZXRFbGVtZW50VHlwZSgpOwotCi0gICAgICAgIGlmIChzYyBpbnN0YW5jZW9mIEJhc2ljVHlwZSAmJiB0YyBpbnN0YW5jZW9mIEJhc2ljVHlwZSAmJiBzYy5lcXVhbHModGMpKQotICAgICAgICAgIHJldHVybiB0cnVlOwotCi0gICAgICAgIC8qIFRDIGFuZCBTQyBhcmUgcmVmZXJlbmNlIHR5cGVzICgyLjQuNiksIGFuZCB0eXBlIFNDIGlzCi0gICAgICAgICAqIGFzc2lnbmFibGUgdG8gVEMgYnkgdGhlc2UgcnVudGltZSBydWxlcy4KLSAgICAgICAgICovCi0gICAgICAgIGlmICh0YyBpbnN0YW5jZW9mIFJlZmVyZW5jZVR5cGUgJiYgc2MgaW5zdGFuY2VvZiBSZWZlcmVuY2VUeXBlICYmCi0gICAgICAgICAgICAoKFJlZmVyZW5jZVR5cGUpIHNjKS5pc0Fzc2lnbm1lbnRDb21wYXRpYmxlV2l0aCgoUmVmZXJlbmNlVHlwZSkgdGMpKQotICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgfQotCi0gICAgICAvKiBJZiBUIGlzIGFuIGludGVyZmFjZSB0eXBlLCBUIG11c3QgYmUgb25lIG9mIHRoZSBpbnRlcmZhY2VzIGltcGxlbWVudGVkIGJ5IGFycmF5cyAoMi4xNSkuICovCi0gICAgICAvLyBUT0RPOiBDaGVjayBpZiB0aGlzIGlzIHN0aWxsIHZhbGlkIG9yIGZpbmQgYSB3YXkgdG8gZHluYW1pY2FsbHkgZmluZCBvdXQgd2hpY2gKLSAgICAgIC8vIGludGVyZmFjZXMgYXJyYXlzIGltcGxlbWVudC4gSG93ZXZlciwgYXMgb2YgdGhlIEpWTSBzcGVjaWZpY2F0aW9uIGVkaXRpb24gMiwgdGhlcmUKLSAgICAgIC8vIGFyZSBhdCBsZWFzdCB0d28gZGlmZmVyZW50IHBhZ2VzIHdoZXJlIGFzc2lnbm1lbnQgY29tcGF0aWJpbGl0eSBpcyBkZWZpbmVkIGFuZAotICAgICAgLy8gb24gb25lIG9mIHRoZW0gImludGVyZmFjZXMgaW1wbGVtZW50ZWQgYnkgYXJyYXlzIiBpcyBleGNoYW5nZWQgd2l0aCAiJ0Nsb25lYWJsZScgb3IKLSAgICAgIC8vICdqYXZhLmlvLlNlcmlhbGl6YWJsZSciCi0gICAgICBpZiAoKFQgaW5zdGFuY2VvZiBPYmplY3RUeXBlKSAmJiAoKChPYmplY3RUeXBlKSBUKS5yZWZlcmVuY2VzSW50ZXJmYWNlKCkpKSB7Ci0gICAgICAgIGZvciAoaW50IGlpID0gMDsgaWkgPCBDb25zdGFudHMuSU5URVJGQUNFU19JTVBMRU1FTlRFRF9CWV9BUlJBWVMubGVuZ3RoOyBpaSsrKSB7Ci0gICAgICAgICAgaWYgKFQuZXF1YWxzKG5ldyBPYmplY3RUeXBlKENvbnN0YW50cy5JTlRFUkZBQ0VTX0lNUExFTUVOVEVEX0JZX0FSUkFZU1tpaV0pKSkgcmV0dXJuIHRydWU7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICB9Ci0gICAgcmV0dXJuIGZhbHNlOyAvLyBkZWZhdWx0LgotICB9Ci0KLSAgLyoqCi0gICAqIFRoaXMgY29tbXV0YXRpdmUgb3BlcmF0aW9uIHJldHVybnMgdGhlIGZpcnN0IGNvbW1vbiBzdXBlcmNsYXNzIChuYXJyb3dlc3QgUmVmZXJlbmNlVHlwZQotICAgKiByZWZlcmVuY2luZyBhIGNsYXNzLCBub3QgYW4gaW50ZXJmYWNlKS4KLSAgICogSWYgb25lIG9mIHRoZSB0eXBlcyBpcyBhIHN1cGVyY2xhc3Mgb2YgdGhlIG90aGVyLCB0aGUgZm9ybWVyIGlzIHJldHVybmVkLgotICAgKiBJZiAidGhpcyIgaXMgVHlwZS5OVUxMLCB0aGVuIHQgaXMgcmV0dXJuZWQuCi0gICAqIElmIHQgaXMgVHlwZS5OVUxMLCB0aGVuICJ0aGlzIiBpcyByZXR1cm5lZC4KLSAgICogSWYgInRoaXMiIGVxdWFscyB0IFsndGhpcy5lcXVhbHModCknXSAidGhpcyIgaXMgcmV0dXJuZWQuCi0gICAqIElmICJ0aGlzIiBvciB0IGlzIGFuIEFycmF5VHlwZSwgdGhlbiBUeXBlLk9CSkVDVCBpcyByZXR1cm5lZDsKLSAgICogdW5sZXNzIHRoZWlyIGRpbWVuc2lvbnMgbWF0Y2guIFRoZW4gYW4gQXJyYXlUeXBlIG9mIHRoZSBzYW1lCi0gICAqIG51bWJlciBvZiBkaW1lbnNpb25zIGlzIHJldHVybmVkLCB3aXRoIGl0cyBiYXNpYyB0eXBlIGJlaW5nIHRoZQotICAgKiBmaXJzdCBjb21tb24gc3VwZXIgY2xhc3Mgb2YgdGhlIGJhc2ljIHR5cGVzIG9mICJ0aGlzIiBhbmQgdC4KLSAgICogSWYgInRoaXMiIG9yIHQgaXMgYSBSZWZlcmVuY2VUeXBlIHJlZmVyZW5jaW5nIGFuIGludGVyZmFjZSwgdGhlbiBUeXBlLk9CSkVDVCBpcyByZXR1cm5lZC4KLSAgICogSWYgbm90IGFsbCBvZiB0aGUgdHdvIGNsYXNzZXMnIHN1cGVyY2xhc3NlcyBjYW5ub3QgYmUgZm91bmQsICJudWxsIiBpcyByZXR1cm5lZC4KLSAgICogU2VlIHRoZSBKVk0gc3BlY2lmaWNhdGlvbiBlZGl0aW9uIDIsICI0LjkuMiBUaGUgQnl0ZWNvZGUgVmVyaWZpZXIiLgotICAgKi8KLSAgcHVibGljIFJlZmVyZW5jZVR5cGUgZ2V0Rmlyc3RDb21tb25TdXBlcmNsYXNzKFJlZmVyZW5jZVR5cGUgdCkgewotICAgIGlmICh0aGlzLmVxdWFscyhUeXBlLk5VTEwpKSByZXR1cm4gdDsKLSAgICBpZiAodC5lcXVhbHMoVHlwZS5OVUxMKSkgcmV0dXJuIHRoaXM7Ci0gICAgaWYgKHRoaXMuZXF1YWxzKHQpKSByZXR1cm4gdGhpczsKLSAgICAvKgotICAgICAqIFRPRE86IEFib3ZlIHNvdW5kcyBhIGxpdHRsZSBhcmJpdHJhcnkuIE9uIHRoZSBvdGhlciBoYW5kLCB0aGVyZSBpcwotICAgICAqIG5vIG9iamVjdCByZWZlcmVuY2VkIGJ5IFR5cGUuTlVMTCBzbyB3ZSBjYW4gYWxzbyBzYXkgYWxsIHRoZSBvYmplY3RzCi0gICAgICogcmVmZXJlbmNlZCBieSBUeXBlLk5VTEwgd2VyZSBkZXJpdmVkIGZyb20gamF2YS5sYW5nLk9iamVjdC4KLSAgICAgKiBIb3dldmVyLCB0aGUgSmF2YSBMYW5ndWFnZSdzICJpbnN0YW5jZW9mIiBvcGVyYXRvciBwcm92ZXMgdXMgd3Jvbmc6Ci0gICAgICogIm51bGwiIGlzIG5vdCByZWZlcnJpbmcgdG8gYW4gaW5zdGFuY2Ugb2YgamF2YS5sYW5nLk9iamVjdCA6KQotICAgICAqLwotCi0gICAgLyogVGhpcyBjb2RlIGlzIGZyb20gYSBidWcgcmVwb3J0IGJ5IEtvbnN0YW50aW4gU2hhZ2luIDxrb25zdEBjcy50ZWNobmlvbi5hYy5pbD4gKi8KLQotICAgIGlmICgodGhpcyBpbnN0YW5jZW9mIEFycmF5VHlwZSkgJiYgKHQgaW5zdGFuY2VvZiBBcnJheVR5cGUpKSB7Ci0gICAgICBBcnJheVR5cGUgYXJyVHlwZTEgPSAoQXJyYXlUeXBlKSB0aGlzOwotICAgICAgQXJyYXlUeXBlIGFyclR5cGUyID0gKEFycmF5VHlwZSkgdDsKLSAgICAgIGlmICgKLSAgICAgICAgICAoYXJyVHlwZTEuZ2V0RGltZW5zaW9ucygpID09IGFyclR5cGUyLmdldERpbWVuc2lvbnMoKSkgJiYKLSAgICAgICAgICBhcnJUeXBlMS5nZXRCYXNpY1R5cGUoKSBpbnN0YW5jZW9mIE9iamVjdFR5cGUgJiYKLSAgICAgICAgICBhcnJUeXBlMi5nZXRCYXNpY1R5cGUoKSBpbnN0YW5jZW9mIE9iamVjdFR5cGUpIHsKLSAgICAgICAgcmV0dXJuIG5ldyBBcnJheVR5cGUoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoT2JqZWN0VHlwZSkgYXJyVHlwZTEuZ2V0QmFzaWNUeXBlKCkpLmdldEZpcnN0Q29tbW9uU3VwZXJjbGFzcygoT2JqZWN0VHlwZSkgYXJyVHlwZTIuZ2V0QmFzaWNUeXBlKCkpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnJUeXBlMS5nZXREaW1lbnNpb25zKCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTsKLQotICAgICAgfQotICAgIH0KLQotICAgIGlmICgodGhpcyBpbnN0YW5jZW9mIEFycmF5VHlwZSkgfHwgKHQgaW5zdGFuY2VvZiBBcnJheVR5cGUpKQotICAgICAgcmV0dXJuIFR5cGUuT0JKRUNUOwotICAgIC8vIFRPRE86IElzIHRoZXJlIGEgcHJvb2Ygb2YgT0JKRUNUIGJlaW5nIHRoZSBkaXJlY3QgYW5jZXN0b3Igb2YgZXZlcnkgQXJyYXlUeXBlPwotCi0gICAgaWYgKCgodGhpcyBpbnN0YW5jZW9mIE9iamVjdFR5cGUpICYmICgoT2JqZWN0VHlwZSkgdGhpcykucmVmZXJlbmNlc0ludGVyZmFjZSgpKSB8fAotICAgICAgICAoKHQgaW5zdGFuY2VvZiBPYmplY3RUeXBlKSAmJiAoKE9iamVjdFR5cGUpIHQpLnJlZmVyZW5jZXNJbnRlcmZhY2UoKSkpCi0gICAgICByZXR1cm4gVHlwZS5PQkpFQ1Q7Ci0gICAgLy8gVE9ETzogVGhlIGFib3ZlIGxpbmUgaXMgY29ycmVjdCBjb21wYXJpbmcgdG8gdGhlIHZtc3BlYzIuIEJ1dCBvbmUgY291bGQKLSAgICAvLyBtYWtlIGNsYXNzIGZpbGUgdmVyaWZpY2F0aW9uIGEgYml0IHN0cm9uZ2VyIGhlcmUgYnkgdXNpbmcgdGhlIG5vdGlvbiBvZgotICAgIC8vIHN1cGVyaW50ZXJmYWNlcyBvciBldmVuIGNhc3RhYmlsaXR5IG9yIGFzc2lnbm1lbnQgY29tcGF0aWJpbGl0eS4KLQotCi0gICAgLy8gdGhpcyBhbmQgdCBhcmUgT2JqZWN0VHlwZXMsIHNlZSBhYm92ZS4KLSAgICBPYmplY3RUeXBlIHRoaXogPSAoT2JqZWN0VHlwZSkgdGhpczsKLSAgICBPYmplY3RUeXBlIG90aGVyID0gKE9iamVjdFR5cGUpIHQ7Ci0gICAgSmF2YUNsYXNzW10gdGhpel9zdXBzID0gUmVwb3NpdG9yeS5nZXRTdXBlckNsYXNzZXModGhpei5nZXRDbGFzc05hbWUoKSk7Ci0gICAgSmF2YUNsYXNzW10gb3RoZXJfc3VwcyA9IFJlcG9zaXRvcnkuZ2V0U3VwZXJDbGFzc2VzKG90aGVyLmdldENsYXNzTmFtZSgpKTsKLQotICAgIGlmICgodGhpel9zdXBzID09IG51bGwpIHx8IChvdGhlcl9zdXBzID09IG51bGwpKSB7Ci0gICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICAvLyBXYWFhaGguLi4KLSAgICBKYXZhQ2xhc3NbXSB0aGlzX3N1cHMgPSBuZXcgSmF2YUNsYXNzW3RoaXpfc3Vwcy5sZW5ndGggKyAxXTsKLSAgICBKYXZhQ2xhc3NbXSB0X3N1cHMgPSBuZXcgSmF2YUNsYXNzW290aGVyX3N1cHMubGVuZ3RoICsgMV07Ci0gICAgU3lzdGVtLmFycmF5Y29weSh0aGl6X3N1cHMsIDAsIHRoaXNfc3VwcywgMSwgdGhpel9zdXBzLmxlbmd0aCk7Ci0gICAgU3lzdGVtLmFycmF5Y29weShvdGhlcl9zdXBzLCAwLCB0X3N1cHMsIDEsIG90aGVyX3N1cHMubGVuZ3RoKTsKLSAgICB0aGlzX3N1cHNbMF0gPSBSZXBvc2l0b3J5Lmxvb2t1cENsYXNzKHRoaXouZ2V0Q2xhc3NOYW1lKCkpOwotICAgIHRfc3Vwc1swXSA9IFJlcG9zaXRvcnkubG9va3VwQ2xhc3Mob3RoZXIuZ2V0Q2xhc3NOYW1lKCkpOwotCi0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCB0X3N1cHMubGVuZ3RoOyBpKyspIHsKLSAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgdGhpc19zdXBzLmxlbmd0aDsgaisrKSB7Ci0gICAgICAgIGlmICh0aGlzX3N1cHNbal0uZXF1YWxzKHRfc3Vwc1tpXSkpIHJldHVybiBuZXcgT2JqZWN0VHlwZSh0aGlzX3N1cHNbal0uZ2V0Q2xhc3NOYW1lKCkpOwotICAgICAgfQotICAgIH0KLQotICAgIC8vIEh1aD8gRGlkIHlvdSBhc2sgZm9yIFR5cGUuT0JKRUNUJ3Mgc3VwZXJjbGFzcz8/Ci0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogVGhpcyBjb21tdXRhdGl2ZSBvcGVyYXRpb24gcmV0dXJucyB0aGUgZmlyc3QgY29tbW9uIHN1cGVyY2xhc3MgKG5hcnJvd2VzdCBSZWZlcmVuY2VUeXBlCi0gICAqIHJlZmVyZW5jaW5nIGEgY2xhc3MsIG5vdCBhbiBpbnRlcmZhY2UpLgotICAgKiBJZiBvbmUgb2YgdGhlIHR5cGVzIGlzIGEgc3VwZXJjbGFzcyBvZiB0aGUgb3RoZXIsIHRoZSBmb3JtZXIgaXMgcmV0dXJuZWQuCi0gICAqIElmICJ0aGlzIiBpcyBUeXBlLk5VTEwsIHRoZW4gdCBpcyByZXR1cm5lZC4KLSAgICogSWYgdCBpcyBUeXBlLk5VTEwsIHRoZW4gInRoaXMiIGlzIHJldHVybmVkLgotICAgKiBJZiAidGhpcyIgZXF1YWxzIHQgWyd0aGlzLmVxdWFscyh0KSddICJ0aGlzIiBpcyByZXR1cm5lZC4KLSAgICogSWYgInRoaXMiIG9yIHQgaXMgYW4gQXJyYXlUeXBlLCB0aGVuIFR5cGUuT0JKRUNUIGlzIHJldHVybmVkLgotICAgKiBJZiAidGhpcyIgb3IgdCBpcyBhIFJlZmVyZW5jZVR5cGUgcmVmZXJlbmNpbmcgYW4gaW50ZXJmYWNlLCB0aGVuIFR5cGUuT0JKRUNUIGlzIHJldHVybmVkLgotICAgKiBJZiBub3QgYWxsIG9mIHRoZSB0d28gY2xhc3Nlcycgc3VwZXJjbGFzc2VzIGNhbm5vdCBiZSBmb3VuZCwgIm51bGwiIGlzIHJldHVybmVkLgotICAgKiBTZWUgdGhlIEpWTSBzcGVjaWZpY2F0aW9uIGVkaXRpb24gMiwgIjQuOS4yIFRoZSBCeXRlY29kZSBWZXJpZmllciIuCi0gICAqCi0gICAqIEBkZXByZWNhdGVkIHVzZSBnZXRGaXJzdENvbW1vblN1cGVyY2xhc3MoUmVmZXJlbmNlVHlwZSB0KSB3aGljaCBoYXMKLSAgICogICAgICAgICAgICAgc2xpZ2h0bHkgY2hhbmdlZCBzZW1hbnRpY3MuCi0gICAqLwotICBwdWJsaWMgUmVmZXJlbmNlVHlwZSBmaXJzdENvbW1vblN1cGVyY2xhc3MoUmVmZXJlbmNlVHlwZSB0KSB7Ci0gICAgaWYgKHRoaXMuZXF1YWxzKFR5cGUuTlVMTCkpIHJldHVybiB0OwotICAgIGlmICh0LmVxdWFscyhUeXBlLk5VTEwpKSByZXR1cm4gdGhpczsKLSAgICBpZiAodGhpcy5lcXVhbHModCkpIHJldHVybiB0aGlzOwotICAgIC8qCi0gICAgICogVE9ETzogQWJvdmUgc291bmRzIGEgbGl0dGxlIGFyYml0cmFyeS4gT24gdGhlIG90aGVyIGhhbmQsIHRoZXJlIGlzCi0gICAgICogbm8gb2JqZWN0IHJlZmVyZW5jZWQgYnkgVHlwZS5OVUxMIHNvIHdlIGNhbiBhbHNvIHNheSBhbGwgdGhlIG9iamVjdHMKLSAgICAgKiByZWZlcmVuY2VkIGJ5IFR5cGUuTlVMTCB3ZXJlIGRlcml2ZWQgZnJvbSBqYXZhLmxhbmcuT2JqZWN0LgotICAgICAqIEhvd2V2ZXIsIHRoZSBKYXZhIExhbmd1YWdlJ3MgImluc3RhbmNlb2YiIG9wZXJhdG9yIHByb3ZlcyB1cyB3cm9uZzoKLSAgICAgKiAibnVsbCIgaXMgbm90IHJlZmVycmluZyB0byBhbiBpbnN0YW5jZSBvZiBqYXZhLmxhbmcuT2JqZWN0IDopCi0gICAgICovCi0KLSAgICBpZiAoKHRoaXMgaW5zdGFuY2VvZiBBcnJheVR5cGUpIHx8ICh0IGluc3RhbmNlb2YgQXJyYXlUeXBlKSkKLSAgICAgIHJldHVybiBUeXBlLk9CSkVDVDsKLSAgICAvLyBUT0RPOiBJcyB0aGVyZSBhIHByb29mIG9mIE9CSkVDVCBiZWluZyB0aGUgZGlyZWN0IGFuY2VzdG9yIG9mIGV2ZXJ5IEFycmF5VHlwZT8KLQotICAgIGlmICgoKHRoaXMgaW5zdGFuY2VvZiBPYmplY3RUeXBlKSAmJiAoKE9iamVjdFR5cGUpIHRoaXMpLnJlZmVyZW5jZXNJbnRlcmZhY2UoKSkgfHwKLSAgICAgICAgKCh0IGluc3RhbmNlb2YgT2JqZWN0VHlwZSkgJiYgKChPYmplY3RUeXBlKSB0KS5yZWZlcmVuY2VzSW50ZXJmYWNlKCkpKQotICAgICAgcmV0dXJuIFR5cGUuT0JKRUNUOwotICAgIC8vIFRPRE86IFRoZSBhYm92ZSBsaW5lIGlzIGNvcnJlY3QgY29tcGFyaW5nIHRvIHRoZSB2bXNwZWMyLiBCdXQgb25lIGNvdWxkCi0gICAgLy8gbWFrZSBjbGFzcyBmaWxlIHZlcmlmaWNhdGlvbiBhIGJpdCBzdHJvbmdlciBoZXJlIGJ5IHVzaW5nIHRoZSBub3Rpb24gb2YKLSAgICAvLyBzdXBlcmludGVyZmFjZXMgb3IgZXZlbiBjYXN0YWJpbGl0eSBvciBhc3NpZ25tZW50IGNvbXBhdGliaWxpdHkuCi0KLQotICAgIC8vIHRoaXMgYW5kIHQgYXJlIE9iamVjdFR5cGVzLCBzZWUgYWJvdmUuCi0gICAgT2JqZWN0VHlwZSB0aGl6ID0gKE9iamVjdFR5cGUpIHRoaXM7Ci0gICAgT2JqZWN0VHlwZSBvdGhlciA9IChPYmplY3RUeXBlKSB0OwotICAgIEphdmFDbGFzc1tdIHRoaXpfc3VwcyA9IFJlcG9zaXRvcnkuZ2V0U3VwZXJDbGFzc2VzKHRoaXouZ2V0Q2xhc3NOYW1lKCkpOwotICAgIEphdmFDbGFzc1tdIG90aGVyX3N1cHMgPSBSZXBvc2l0b3J5LmdldFN1cGVyQ2xhc3NlcyhvdGhlci5nZXRDbGFzc05hbWUoKSk7Ci0KLSAgICBpZiAoKHRoaXpfc3VwcyA9PSBudWxsKSB8fCAob3RoZXJfc3VwcyA9PSBudWxsKSkgewotICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLy8gV2FhYWhoLi4uCi0gICAgSmF2YUNsYXNzW10gdGhpc19zdXBzID0gbmV3IEphdmFDbGFzc1t0aGl6X3N1cHMubGVuZ3RoICsgMV07Ci0gICAgSmF2YUNsYXNzW10gdF9zdXBzID0gbmV3IEphdmFDbGFzc1tvdGhlcl9zdXBzLmxlbmd0aCArIDFdOwotICAgIFN5c3RlbS5hcnJheWNvcHkodGhpel9zdXBzLCAwLCB0aGlzX3N1cHMsIDEsIHRoaXpfc3Vwcy5sZW5ndGgpOwotICAgIFN5c3RlbS5hcnJheWNvcHkob3RoZXJfc3VwcywgMCwgdF9zdXBzLCAxLCBvdGhlcl9zdXBzLmxlbmd0aCk7Ci0gICAgdGhpc19zdXBzWzBdID0gUmVwb3NpdG9yeS5sb29rdXBDbGFzcyh0aGl6LmdldENsYXNzTmFtZSgpKTsKLSAgICB0X3N1cHNbMF0gPSBSZXBvc2l0b3J5Lmxvb2t1cENsYXNzKG90aGVyLmdldENsYXNzTmFtZSgpKTsKLQotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdF9zdXBzLmxlbmd0aDsgaSsrKSB7Ci0gICAgICBmb3IgKGludCBqID0gMDsgaiA8IHRoaXNfc3Vwcy5sZW5ndGg7IGorKykgewotICAgICAgICBpZiAodGhpc19zdXBzW2pdLmVxdWFscyh0X3N1cHNbaV0pKSByZXR1cm4gbmV3IE9iamVjdFR5cGUodGhpc19zdXBzW2pdLmdldENsYXNzTmFtZSgpKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICAvLyBIdWg/IERpZCB5b3UgYXNrIGZvciBUeXBlLk9CSkVDVCdzIHN1cGVyY2xhc3M/PwotICAgIHJldHVybiBudWxsOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9SZXR1cm5JbnN0cnVjdGlvbi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvUmV0dXJuSW5zdHJ1Y3Rpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNjMxODFkMC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9SZXR1cm5JbnN0cnVjdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTA2ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkV4Y2VwdGlvbkNvbnN0YW50czsKLQotLyoqCi0gKiBTdXBlciBjbGFzcyBmb3IgdGhlIHhSRVRVUk4gZmFtaWx5IG9mIGluc3RydWN0aW9ucy4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgYWJzdHJhY3QgY2xhc3MgUmV0dXJuSW5zdHJ1Y3Rpb24gZXh0ZW5kcyBJbnN0cnVjdGlvbgotICBpbXBsZW1lbnRzIEV4Y2VwdGlvblRocm93ZXIsIFR5cGVkSW5zdHJ1Y3Rpb24sIFN0YWNrQ29uc3VtZXIgewotICAvKioKLSAgICogRW1wdHkgY29uc3RydWN0b3IgbmVlZGVkIGZvciB0aGUgQ2xhc3MubmV3SW5zdGFuY2UoKSBzdGF0ZW1lbnQgaW4KLSAgICogSW5zdHJ1Y3Rpb24ucmVhZEluc3RydWN0aW9uKCkuIE5vdCB0byBiZSB1c2VkIG90aGVyd2lzZS4KLSAgICovCi0gIFJldHVybkluc3RydWN0aW9uKCkge30KLQotICAvKioKLSAgICogQHBhcmFtIG9wY29kZSBvZiBpbnN0cnVjdGlvbgotICAgKi8KLSAgcHJvdGVjdGVkIFJldHVybkluc3RydWN0aW9uKHNob3J0IG9wY29kZSkgewotICAgIHN1cGVyKG9wY29kZSwgKHNob3J0KTEpOwotICB9Ci0KLSAgcHVibGljIFR5cGUgZ2V0VHlwZSgpIHsKLSAgICBzd2l0Y2gob3Bjb2RlKSB7Ci0gICAgICBjYXNlIENvbnN0YW50cy5JUkVUVVJOOiByZXR1cm4gVHlwZS5JTlQ7Ci0gICAgICBjYXNlIENvbnN0YW50cy5MUkVUVVJOOiByZXR1cm4gVHlwZS5MT05HOwotICAgICAgY2FzZSBDb25zdGFudHMuRlJFVFVSTjogcmV0dXJuIFR5cGUuRkxPQVQ7Ci0gICAgICBjYXNlIENvbnN0YW50cy5EUkVUVVJOOiByZXR1cm4gVHlwZS5ET1VCTEU7Ci0gICAgICBjYXNlIENvbnN0YW50cy5BUkVUVVJOOiByZXR1cm4gVHlwZS5PQkpFQ1Q7Ci0gICAgICBjYXNlIENvbnN0YW50cy5SRVRVUk46ICByZXR1cm4gVHlwZS5WT0lEOwotCi0gICAgZGVmYXVsdDogLy8gTmV2ZXIgcmVhY2hlZAotICAgICAgdGhyb3cgbmV3IENsYXNzR2VuRXhjZXB0aW9uKCJVbmtub3duIHR5cGUgIiArIG9wY29kZSk7Ci0gICAgfQotICB9Ci0KLSAgcHVibGljIENsYXNzW10gZ2V0RXhjZXB0aW9ucygpIHsKLSAgICByZXR1cm4gbmV3IENsYXNzW10geyBFeGNlcHRpb25Db25zdGFudHMuSUxMRUdBTF9NT05JVE9SX1NUQVRFIH07Ci0gIH0KLQotICAvKiogQHJldHVybiB0eXBlIGFzc29jaWF0ZWQgd2l0aCB0aGUgaW5zdHJ1Y3Rpb24KLSAgICovCi0gIHB1YmxpYyBUeXBlIGdldFR5cGUoQ29uc3RhbnRQb29sR2VuIGNwKSB7Ci0gICAgcmV0dXJuIGdldFR5cGUoKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvUmV0dXJuYWRkcmVzc1R5cGUuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL1JldHVybmFkZHJlc3NUeXBlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDUwMWVmZGQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvUmV0dXJuYWRkcmVzc1R5cGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExMSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50czsKLWltcG9ydCBqYXZhLnV0aWwuT2JqZWN0czsKLQotLyoqCi0gKiBSZXR1cm5hZGRyZXNzLCB0aGUgdHlwZSBKU1Igb3IgSlNSX1cgaW5zdHJ1Y3Rpb25zIHB1c2ggdXBvbiB0aGUgc3RhY2suCi0gKgotICogc2VlIHZtc3BlYzIgMy4zLjMKLSAqIEBhdXRob3IgIDxBIEhSRUY9Imh0dHA6Ly93d3cuaW5mLmZ1LWJlcmxpbi5kZS9+ZWhhYXNlIj5FbnZlciBIYWFzZTwvQT4KLSAqLwotcHVibGljIGNsYXNzIFJldHVybmFkZHJlc3NUeXBlIGV4dGVuZHMgVHlwZSB7Ci0KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBSZXR1cm5hZGRyZXNzVHlwZSBOT19UQVJHRVQgPSBuZXcgUmV0dXJuYWRkcmVzc1R5cGUoKTsKLSAgcHJpdmF0ZSBJbnN0cnVjdGlvbkhhbmRsZSByZXR1cm5UYXJnZXQ7Ci0KLSAgLyoqCi0gICAqIEEgUmV0dXJuYWRkcmVzcyBbdGhhdCBkb2Vzbid0IGtub3cgd2hlcmUgdG8gcmV0dXJuIHRvXS4KLSAgICovCi0gIHByaXZhdGUgUmV0dXJuYWRkcmVzc1R5cGUoKXsKLSAgICBzdXBlcihDb25zdGFudHMuVF9BRERSRVNTLCAiPHJldHVybiBhZGRyZXNzPiIpOwotICB9Ci0KLSAgLyoqCi0gICAqIENyZWF0ZXMgYSBSZXR1cm5hZGRyZXNzVHlwZSBvYmplY3Qgd2l0aCBhIHRhcmdldC4KLSAgICovCi0gIHB1YmxpYyBSZXR1cm5hZGRyZXNzVHlwZShJbnN0cnVjdGlvbkhhbmRsZSByZXR1cm5UYXJnZXQpIHsKLSAgICBzdXBlcihDb25zdGFudHMuVF9BRERSRVNTLCAiPHJldHVybiBhZGRyZXNzIHRhcmdldGluZyAiK3JldHVyblRhcmdldCsiPiIpOwotICAgICAgICB0aGlzLnJldHVyblRhcmdldCA9IHJldHVyblRhcmdldDsKLSAgfQotCi0gIEBPdmVycmlkZQotICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewotICAgICAgcmV0dXJuIE9iamVjdHMuaGFzaENvZGUodGhpcy5yZXR1cm5UYXJnZXQpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgaWYgdGhlIHR3byBSZXR1cm5hZGRyZXNzZXMgcmVmZXIgdG8gdGhlIHNhbWUgdGFyZ2V0LgotICAgKi8KLSAgQE92ZXJyaWRlCi0gIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgcmF0KXsKLSAgICBpZighKHJhdCBpbnN0YW5jZW9mIFJldHVybmFkZHJlc3NUeXBlKSkKLSAgICAgIHJldHVybiBmYWxzZTsKLQotICAgIHJldHVybiAoKFJldHVybmFkZHJlc3NUeXBlKXJhdCkucmV0dXJuVGFyZ2V0LmVxdWFscyh0aGlzLnJldHVyblRhcmdldCk7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiB0aGUgdGFyZ2V0IG9mIHRoaXMgUmV0dXJuYWRkcmVzc1R5cGUKLSAgICovCi0gIHB1YmxpYyBJbnN0cnVjdGlvbkhhbmRsZSBnZXRUYXJnZXQoKXsKLSAgICByZXR1cm4gcmV0dXJuVGFyZ2V0OwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9TQUxPQUQuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL1NBTE9BRC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwNmQwM2FjLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL1NBTE9BRC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsODggKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotLyoqCi0gKiBTQUxPQUQgLSBMb2FkIHNob3J0IGZyb20gYXJyYXkKLSAqIDxQUkU+U3RhY2s6IC4uLiwgYXJyYXlyZWYsIGluZGV4IC0mZ3Q7IC4uLiwgdmFsdWU8L1BSRT4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgU0FMT0FEIGV4dGVuZHMgQXJyYXlJbnN0cnVjdGlvbiBpbXBsZW1lbnRzIFN0YWNrUHJvZHVjZXIgewotICBwdWJsaWMgU0FMT0FEKCkgewotICAgIHN1cGVyKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5TQUxPQUQpOwotICB9Ci0KLQotICAvKioKLSAgICogQ2FsbCBjb3JyZXNwb25kaW5nIHZpc2l0b3IgbWV0aG9kKHMpLiBUaGUgb3JkZXIgaXM6Ci0gICAqIENhbGwgdmlzaXRvciBtZXRob2RzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMgZmlyc3QsIHRoZW4KLSAgICogY2FsbCBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY2xhc3MgaGllcmFyY2h5IGluIGRlc2NlbmRpbmcgb3JkZXIsCi0gICAqIGkuZS4sIHRoZSBtb3N0IHNwZWNpZmljIHZpc2l0WFhYKCkgY2FsbCBjb21lcyBsYXN0LgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRTdGFja1Byb2R1Y2VyKHRoaXMpOwotICAgIHYudmlzaXRFeGNlcHRpb25UaHJvd2VyKHRoaXMpOwotICAgIHYudmlzaXRUeXBlZEluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRBcnJheUluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRTQUxPQUQodGhpcyk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL1NBU1RPUkUuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL1NBU1RPUkUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOWIyMGI5My4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9TQVNUT1JFLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4OCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIFNBU1RPUkUgLSBTdG9yZSBpbnRvIHNob3J0IGFycmF5Ci0gKiA8UFJFPlN0YWNrOiAuLi4sIGFycmF5cmVmLCBpbmRleCwgdmFsdWUgLSZndDsgLi4uPC9QUkU+Ci0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGNsYXNzIFNBU1RPUkUgZXh0ZW5kcyBBcnJheUluc3RydWN0aW9uIGltcGxlbWVudHMgU3RhY2tDb25zdW1lciB7Ci0gIHB1YmxpYyBTQVNUT1JFKCkgewotICAgIHN1cGVyKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5TQVNUT1JFKTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIENhbGwgY29ycmVzcG9uZGluZyB2aXNpdG9yIG1ldGhvZChzKS4gVGhlIG9yZGVyIGlzOgotICAgKiBDYWxsIHZpc2l0b3IgbWV0aG9kcyBvZiBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzIGZpcnN0LCB0aGVuCi0gICAqIGNhbGwgbWV0aG9kcyBhY2NvcmRpbmcgdG8gdGhlIGNsYXNzIGhpZXJhcmNoeSBpbiBkZXNjZW5kaW5nIG9yZGVyLAotICAgKiBpLmUuLCB0aGUgbW9zdCBzcGVjaWZpYyB2aXNpdFhYWCgpIGNhbGwgY29tZXMgbGFzdC4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0U3RhY2tDb25zdW1lcih0aGlzKTsKLSAgICB2LnZpc2l0RXhjZXB0aW9uVGhyb3dlcih0aGlzKTsKLSAgICB2LnZpc2l0VHlwZWRJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0QXJyYXlJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0U0FTVE9SRSh0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvU0lQVVNILmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9TSVBVU0guamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZTE3MTczMS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9TSVBVU0guamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEzMSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotaW1wb3J0IGphdmEuaW8uKjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC51dGlsLkJ5dGVTZXF1ZW5jZTsKLQotLyoqCi0gKiBTSVBVU0ggLSBQdXNoIHNob3J0Ci0gKgotICogPFBSRT5TdGFjazogLi4uIC0mZ3Q7IC4uLiwgdmFsdWU8L1BSRT4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgU0lQVVNIIGV4dGVuZHMgSW5zdHJ1Y3Rpb24gaW1wbGVtZW50cyBDb25zdGFudFB1c2hJbnN0cnVjdGlvbiB7Ci0gIHByaXZhdGUgc2hvcnQgYjsKLQotICAvKioKLSAgICogRW1wdHkgY29uc3RydWN0b3IgbmVlZGVkIGZvciB0aGUgQ2xhc3MubmV3SW5zdGFuY2UoKSBzdGF0ZW1lbnQgaW4KLSAgICogSW5zdHJ1Y3Rpb24ucmVhZEluc3RydWN0aW9uKCkuIE5vdCB0byBiZSB1c2VkIG90aGVyd2lzZS4KLSAgICovCi0gIFNJUFVTSCgpIHt9Ci0KLSAgcHVibGljIFNJUFVTSChzaG9ydCBiKSB7Ci0gICAgc3VwZXIoY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLlNJUFVTSCwgKHNob3J0KTMpOwotICAgIHRoaXMuYiA9IGI7Ci0gIH0KLQotICAvKioKLSAgICogRHVtcCBpbnN0cnVjdGlvbiBhcyBzaG9ydCBjb2RlIHRvIHN0cmVhbSBvdXQuCi0gICAqLwotICBwdWJsaWMgdm9pZCBkdW1wKERhdGFPdXRwdXRTdHJlYW0gb3V0KSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgIHN1cGVyLmR1bXAob3V0KTsKLSAgICBvdXQud3JpdGVTaG9ydChiKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIG1uZW1vbmljIGZvciBpbnN0cnVjdGlvbgotICAgKi8KLSAgcHVibGljIFN0cmluZyB0b1N0cmluZyhib29sZWFuIHZlcmJvc2UpIHsKLSAgICByZXR1cm4gc3VwZXIudG9TdHJpbmcodmVyYm9zZSkgKyAiICIgKyBiOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlYWQgbmVlZGVkIGRhdGEgKGUuZy4gaW5kZXgpIGZyb20gZmlsZS4KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIGluaXRGcm9tRmlsZShCeXRlU2VxdWVuY2UgYnl0ZXMsIGJvb2xlYW4gd2lkZSkgdGhyb3dzIElPRXhjZXB0aW9uCi0gIHsKLSAgICBsZW5ndGggPSAzOwotICAgIGIgICAgICA9IGJ5dGVzLnJlYWRTaG9ydCgpOwotICB9Ci0KLSAgcHVibGljIE51bWJlciBnZXRWYWx1ZSgpIHsgcmV0dXJuIG5ldyBJbnRlZ2VyKGIpOyB9Ci0KLSAgLyoqIEByZXR1cm4gVHlwZS5TSE9SVAotICAgKi8KLSAgcHVibGljIFR5cGUgZ2V0VHlwZShDb25zdGFudFBvb2xHZW4gY3ApIHsKLSAgICByZXR1cm4gVHlwZS5TSE9SVDsKLSAgfQotCi0gIC8qKgotICAgKiBDYWxsIGNvcnJlc3BvbmRpbmcgdmlzaXRvciBtZXRob2QocykuIFRoZSBvcmRlciBpczoKLSAgICogQ2FsbCB2aXNpdG9yIG1ldGhvZHMgb2YgaW1wbGVtZW50ZWQgaW50ZXJmYWNlcyBmaXJzdCwgdGhlbgotICAgKiBjYWxsIG1ldGhvZHMgYWNjb3JkaW5nIHRvIHRoZSBjbGFzcyBoaWVyYXJjaHkgaW4gZGVzY2VuZGluZyBvcmRlciwKLSAgICogaS5lLiwgdGhlIG1vc3Qgc3BlY2lmaWMgdmlzaXRYWFgoKSBjYWxsIGNvbWVzIGxhc3QuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgdi52aXNpdFB1c2hJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0U3RhY2tQcm9kdWNlcih0aGlzKTsKLSAgICB2LnZpc2l0VHlwZWRJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0Q29uc3RhbnRQdXNoSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdFNJUFVTSCh0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvU1dBUC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvU1dBUC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2MjVjYmRiLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL1NXQVAuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDg3ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8qKgotICogU1dBUCAtIFN3YSB0b3Agb3BlcmFuZCBzdGFjayB3b3JkCi0gKiA8UFJFPlN0YWNrOiAuLi4sIHdvcmQyLCB3b3JkMSAtJmd0OyAuLi4sIHdvcmQxLCB3b3JkMjwvUFJFPgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBTV0FQIGV4dGVuZHMgU3RhY2tJbnN0cnVjdGlvbiBpbXBsZW1lbnRzIFN0YWNrQ29uc3VtZXIsIFN0YWNrUHJvZHVjZXIgewotICBwdWJsaWMgU1dBUCgpIHsKLSAgICBzdXBlcihjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMuU1dBUCk7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBDYWxsIGNvcnJlc3BvbmRpbmcgdmlzaXRvciBtZXRob2QocykuIFRoZSBvcmRlciBpczoKLSAgICogQ2FsbCB2aXNpdG9yIG1ldGhvZHMgb2YgaW1wbGVtZW50ZWQgaW50ZXJmYWNlcyBmaXJzdCwgdGhlbgotICAgKiBjYWxsIG1ldGhvZHMgYWNjb3JkaW5nIHRvIHRoZSBjbGFzcyBoaWVyYXJjaHkgaW4gZGVzY2VuZGluZyBvcmRlciwKLSAgICogaS5lLiwgdGhlIG1vc3Qgc3BlY2lmaWMgdmlzaXRYWFgoKSBjYWxsIGNvbWVzIGxhc3QuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZpc2l0b3Igb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgdi52aXNpdFN0YWNrQ29uc3VtZXIodGhpcyk7Ci0gICAgdi52aXNpdFN0YWNrUHJvZHVjZXIodGhpcyk7Ci0gICAgdi52aXNpdFN0YWNrSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdFNXQVAodGhpcyk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL1NXSVRDSC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvU1dJVENILmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGRmMWZkODEuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvU1dJVENILmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxODYgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotLyoqCi0gKiBTV0lUQ0ggLSBCcmFuY2ggZGVwZW5kaW5nIG9uIGludCB2YWx1ZSwgZ2VuZXJhdGVzIGVpdGhlciBMT09LVVBTV0lUQ0ggb3IKLSAqIFRBQkxFU1dJVENIIGluc3RydWN0aW9uLCBkZXBlbmRpbmcgb24gd2hldGhlciB0aGUgbWF0Y2ggdmFsdWVzIChpbnRbXSkgY2FuIGJlCi0gKiBzb3J0ZWQgd2l0aCBubyBnYXBzIGJldHdlZW4gdGhlIG51bWJlcnMuCi0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIFNXSVRDSCBpbXBsZW1lbnRzIENvbXBvdW5kSW5zdHJ1Y3Rpb24gewotICBwcml2YXRlIGludFtdICAgICAgICAgICAgICAgbWF0Y2g7Ci0gIHByaXZhdGUgSW5zdHJ1Y3Rpb25IYW5kbGVbXSB0YXJnZXRzOwotICBwcml2YXRlIFNlbGVjdCAgICAgICAgICAgICAgaW5zdHJ1Y3Rpb247Ci0gIHByaXZhdGUgaW50ICAgICAgICAgICAgICAgICBtYXRjaF9sZW5ndGg7Ci0KLSAgLyoqCi0gICAqIFRlbXBsYXRlIGZvciBzd2l0Y2goKSBjb25zdHJ1Y3RzLiBJZiB0aGUgbWF0Y2ggYXJyYXkgY2FuIGJlCi0gICAqIHNvcnRlZCBpbiBhc2NlbmRpbmcgb3JkZXIgd2l0aCBnYXBzIG5vIGxhcmdlciB0aGFuIG1heF9nYXAKLSAgICogYmV0d2VlbiB0aGUgbnVtYmVycywgYSBUQUJMRVNXSVRDSCBpbnN0cnVjdGlvbiBpcyBnZW5lcmF0ZWQsIGFuZAotICAgKiBhIExPT0tVUFNXSVRDSCBvdGhlcndpc2UuIFRoZSBmb3JtZXIgbWF5IGJlIG1vcmUgZWZmaWNpZW50LCBidXQKLSAgICogbmVlZHMgbW9yZSBzcGFjZS4KLSAgICoKLSAgICogTm90ZSwgdGhhdCB0aGUga2V5IGFycmF5IGFsd2F5cyB3aWxsIGJlIHNvcnRlZCwgdGhvdWdoIHdlIGxlYXZlCi0gICAqIHRoZSBvcmlnaW5hbCBhcnJheXMgdW5hbHRlcmVkLgotICAgKgotICAgKiBAcGFyYW0gbWF0Y2ggYXJyYXkgb2YgbWF0Y2ggdmFsdWVzIChjYXNlIDI6IC4uLiBjYXNlIDc6IC4uLiwgZXRjLikKLSAgICogQHBhcmFtIHRhcmdldHMgdGhlIGluc3RydWN0aW9ucyB0byBiZSBicmFuY2hlZCB0byBmb3IgZWFjaCBjYXNlCi0gICAqIEBwYXJhbSB0YXJnZXQgdGhlIGRlZmF1bHQgdGFyZ2V0Ci0gICAqIEBwYXJhbSBtYXhfZ2FwIG1heGltdW0gZ2FwIHRoYXQgbWF5IGJldHdlZW4gY2FzZSBicmFuY2hlcwotICAgKi8KLSAgcHVibGljIFNXSVRDSChpbnRbXSBtYXRjaCwgSW5zdHJ1Y3Rpb25IYW5kbGVbXSB0YXJnZXRzLAotICAgICAgICAgICAgICAgIEluc3RydWN0aW9uSGFuZGxlIHRhcmdldCwgaW50IG1heF9nYXApIHsKLSAgICB0aGlzLm1hdGNoICAgPSAoaW50W10pbWF0Y2guY2xvbmUoKTsKLSAgICB0aGlzLnRhcmdldHMgPSAoSW5zdHJ1Y3Rpb25IYW5kbGVbXSl0YXJnZXRzLmNsb25lKCk7Ci0KLSAgICBpZigobWF0Y2hfbGVuZ3RoID0gbWF0Y2gubGVuZ3RoKSA8IDIpIC8vIChhbG1vc3QpIGVtcHR5IHN3aXRjaCwgb3IganVzdCBkZWZhdWx0Ci0gICAgICBpbnN0cnVjdGlvbiA9IG5ldyBUQUJMRVNXSVRDSChtYXRjaCwgdGFyZ2V0cywgdGFyZ2V0KTsKLSAgICBlbHNlIHsKLSAgICAgIHNvcnQoMCwgbWF0Y2hfbGVuZ3RoIC0gMSk7Ci0KLSAgICAgIGlmKG1hdGNoSXNPcmRlcmVkKG1heF9nYXApKSB7Ci0gICAgICAgIGZpbGx1cChtYXhfZ2FwLCB0YXJnZXQpOwotCi0gICAgICAgIGluc3RydWN0aW9uID0gbmV3IFRBQkxFU1dJVENIKHRoaXMubWF0Y2gsIHRoaXMudGFyZ2V0cywgdGFyZ2V0KTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgICAgaW5zdHJ1Y3Rpb24gPSBuZXcgTE9PS1VQU1dJVENIKHRoaXMubWF0Y2gsIHRoaXMudGFyZ2V0cywgdGFyZ2V0KTsKLSAgICB9Ci0gIH0KLQotICBwdWJsaWMgU1dJVENIKGludFtdIG1hdGNoLCBJbnN0cnVjdGlvbkhhbmRsZVtdIHRhcmdldHMsCi0gICAgICAgICAgICAgICAgSW5zdHJ1Y3Rpb25IYW5kbGUgdGFyZ2V0KSB7Ci0gICAgdGhpcyhtYXRjaCwgdGFyZ2V0cywgdGFyZ2V0LCAxKTsKLSAgfQotCi0gIHByaXZhdGUgZmluYWwgdm9pZCBmaWxsdXAoaW50IG1heF9nYXAsIEluc3RydWN0aW9uSGFuZGxlIHRhcmdldCkgewotICAgIGludCAgICAgICAgICAgICAgICAgbWF4X3NpemUgPSBtYXRjaF9sZW5ndGggKyBtYXRjaF9sZW5ndGggKiBtYXhfZ2FwOwotICAgIGludFtdICAgICAgICAgICAgICAgbV92ZWMgICAgPSBuZXcgaW50W21heF9zaXplXTsKLSAgICBJbnN0cnVjdGlvbkhhbmRsZVtdIHRfdmVjICAgID0gbmV3IEluc3RydWN0aW9uSGFuZGxlW21heF9zaXplXTsKLSAgICBpbnQgICAgICAgICAgICAgICAgIGNvdW50ICAgID0gMTsKLQotICAgIG1fdmVjWzBdID0gbWF0Y2hbMF07Ci0gICAgdF92ZWNbMF0gPSB0YXJnZXRzWzBdOwotCi0gICAgZm9yKGludCBpPTE7IGkgPCBtYXRjaF9sZW5ndGg7IGkrKykgewotICAgICAgaW50IHByZXYgPSBtYXRjaFtpLTFdOwotICAgICAgaW50IGdhcCAgPSBtYXRjaFtpXSAtIHByZXY7Ci0KLSAgICAgIGZvcihpbnQgaj0xOyBqIDwgZ2FwOyBqKyspIHsKLSAgICAgICAgbV92ZWNbY291bnRdID0gcHJldiArIGo7Ci0gICAgICAgIHRfdmVjW2NvdW50XSA9IHRhcmdldDsKLSAgICAgICAgY291bnQrKzsKLSAgICAgIH0KLQotICAgICAgbV92ZWNbY291bnRdID0gbWF0Y2hbaV07Ci0gICAgICB0X3ZlY1tjb3VudF0gPSB0YXJnZXRzW2ldOwotICAgICAgY291bnQrKzsKLSAgICB9Ci0KLSAgICBtYXRjaCAgID0gbmV3IGludFtjb3VudF07Ci0gICAgdGFyZ2V0cyA9IG5ldyBJbnN0cnVjdGlvbkhhbmRsZVtjb3VudF07Ci0KLSAgICBTeXN0ZW0uYXJyYXljb3B5KG1fdmVjLCAwLCBtYXRjaCwgMCwgY291bnQpOwotICAgIFN5c3RlbS5hcnJheWNvcHkodF92ZWMsIDAsIHRhcmdldHMsIDAsIGNvdW50KTsKLSAgfQotCi0gIC8qKgotICAgKiBTb3J0IG1hdGNoIGFuZCB0YXJnZXRzIGFycmF5IHdpdGggUXVpY2tTb3J0LgotICAgKi8KLSAgcHJpdmF0ZSBmaW5hbCB2b2lkIHNvcnQoaW50IGwsIGludCByKSB7Ci0gICAgaW50IGkgPSBsLCBqID0gcjsKLSAgICBpbnQgaCwgbSA9IG1hdGNoWyhsICsgcikgLyAyXTsKLSAgICBJbnN0cnVjdGlvbkhhbmRsZSBoMjsKLQotICAgIGRvIHsKLSAgICAgIHdoaWxlKG1hdGNoW2ldIDwgbSkgaSsrOwotICAgICAgd2hpbGUobSA8IG1hdGNoW2pdKSBqLS07Ci0KLSAgICAgIGlmKGkgPD0gaikgewotICAgICAgICBoPW1hdGNoW2ldOyBtYXRjaFtpXT1tYXRjaFtqXTsgbWF0Y2hbal09aDsgLy8gU3dhcCBlbGVtZW50cwotICAgICAgICBoMj10YXJnZXRzW2ldOyB0YXJnZXRzW2ldPXRhcmdldHNbal07IHRhcmdldHNbal09aDI7IC8vIFN3YXAgaW5zdHJ1Y3Rpb25zLCB0b28KLSAgICAgICAgaSsrOyBqLS07Ci0gICAgICB9Ci0gICAgfSB3aGlsZShpIDw9IGopOwotCi0gICAgaWYobCA8IGopIHNvcnQobCwgaik7Ci0gICAgaWYoaSA8IHIpIHNvcnQoaSwgcik7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBtYXRjaCBpcyBzb3J0ZWQgaW4gYXNjZW5kaW5nIG9yZGVyIHdpdGggbm8gZ2FwIGJpZ2dlciB0aGFuIG1heF9nYXA/Ci0gICAqLwotICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gbWF0Y2hJc09yZGVyZWQoaW50IG1heF9nYXApIHsKLSAgICBmb3IoaW50IGk9MTsgaSA8IG1hdGNoX2xlbmd0aDsgaSsrKQotICAgICAgaWYobWF0Y2hbaV0gLSBtYXRjaFtpLTFdID4gbWF4X2dhcCkKLSAgICAgICAgcmV0dXJuIGZhbHNlOwotCi0gICAgcmV0dXJuIHRydWU7Ci0gIH0KLQotICBwdWJsaWMgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGdldEluc3RydWN0aW9uTGlzdCgpIHsKLSAgICByZXR1cm4gbmV3IEluc3RydWN0aW9uTGlzdChpbnN0cnVjdGlvbik7Ci0gIH0KLQotICBwdWJsaWMgZmluYWwgSW5zdHJ1Y3Rpb24gZ2V0SW5zdHJ1Y3Rpb24oKSB7Ci0gICAgcmV0dXJuIGluc3RydWN0aW9uOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9TZWxlY3QuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL1NlbGVjdC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwY2Y0N2Y2Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL1NlbGVjdC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjY3ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1pbXBvcnQgamF2YS5pby4qOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLnV0aWwuQnl0ZVNlcXVlbmNlOwotCi0vKioKLSAqIFNlbGVjdCAtIEFic3RyYWN0IHN1cGVyIGNsYXNzIGZvciBMT09LVVBTV0lUQ0ggYW5kIFRBQkxFU1dJVENIIGluc3RydWN0aW9ucy4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICogQHNlZSBMT09LVVBTV0lUQ0gKLSAqIEBzZWUgVEFCTEVTV0lUQ0gKLSAqIEBzZWUgSW5zdHJ1Y3Rpb25MaXN0Ci0gKi8KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBTZWxlY3QgZXh0ZW5kcyBCcmFuY2hJbnN0cnVjdGlvbgotICBpbXBsZW1lbnRzIFZhcmlhYmxlTGVuZ3RoSW5zdHJ1Y3Rpb24sIFN0YWNrUHJvZHVjZXIKLXsKLSAgcHJvdGVjdGVkIGludFtdICAgICAgICAgICAgICAgbWF0Y2g7ICAgICAgICAvLyBtYXRjaGVzLCBpLmUuLCBjYXNlIDE6IC4uLgotICBwcm90ZWN0ZWQgaW50W10gICAgICAgICAgICAgICBpbmRpY2VzOyAgICAgIC8vIHRhcmdldCBvZmZzZXRzCi0gIHByb3RlY3RlZCBJbnN0cnVjdGlvbkhhbmRsZVtdIHRhcmdldHM7ICAgICAgLy8gdGFyZ2V0IG9iamVjdHMgaW4gaW5zdHJ1Y3Rpb24gbGlzdAotICBwcm90ZWN0ZWQgaW50ICAgICAgICAgICAgICAgICBmaXhlZF9sZW5ndGg7IC8vIGZpeGVkIGxlbmd0aCBkZWZpbmVkIGJ5IHN1YmNsYXNzZXMKLSAgcHJvdGVjdGVkIGludCAgICAgICAgICAgICAgICAgbWF0Y2hfbGVuZ3RoOyAvLyBudW1iZXIgb2YgY2FzZXMKLSAgcHJvdGVjdGVkIGludCAgICAgICAgICAgICAgICAgcGFkZGluZyA9IDA7ICAvLyBudW1iZXIgb2YgcGFkIGJ5dGVzIGZvciBhbGlnbm1lbnQKLQotICAvKioKLSAgICogRW1wdHkgY29uc3RydWN0b3IgbmVlZGVkIGZvciB0aGUgQ2xhc3MubmV3SW5zdGFuY2UoKSBzdGF0ZW1lbnQgaW4KLSAgICogSW5zdHJ1Y3Rpb24ucmVhZEluc3RydWN0aW9uKCkuIE5vdCB0byBiZSB1c2VkIG90aGVyd2lzZS4KLSAgICovCi0gIFNlbGVjdCgpIHt9Ci0KLSAgLyoqCi0gICAqIChNYXRjaCwgdGFyZ2V0KSBwYWlycyBmb3Igc3dpdGNoLgotICAgKiBgTWF0Y2gnIGFuZCBgdGFyZ2V0cycgbXVzdCBoYXZlIHRoZSBzYW1lIGxlbmd0aCBvZiBjb3Vyc2UuCi0gICAqCi0gICAqIEBwYXJhbSBtYXRjaCBhcnJheSBvZiBtYXRjaGluZyB2YWx1ZXMKLSAgICogQHBhcmFtIHRhcmdldHMgaW5zdHJ1Y3Rpb24gdGFyZ2V0cwotICAgKiBAcGFyYW0gdGFyZ2V0IGRlZmF1bHQgaW5zdHJ1Y3Rpb24gdGFyZ2V0Ci0gICAqLwotICBTZWxlY3Qoc2hvcnQgb3Bjb2RlLCBpbnRbXSBtYXRjaCwgSW5zdHJ1Y3Rpb25IYW5kbGVbXSB0YXJnZXRzLAotICAgICAgICAgSW5zdHJ1Y3Rpb25IYW5kbGUgdGFyZ2V0KSB7Ci0gICAgc3VwZXIob3Bjb2RlLCB0YXJnZXQpOwotCi0gICAgdGhpcy50YXJnZXRzID0gdGFyZ2V0czsKLSAgICBmb3IoaW50IGk9MDsgaSA8IHRhcmdldHMubGVuZ3RoOyBpKyspIHsKLSAgICAgIEJyYW5jaEluc3RydWN0aW9uLm5vdGlmeVRhcmdldENoYW5nZWQodGFyZ2V0c1tpXSwgdGhpcyk7Ci0gICAgfQotCi0gICAgdGhpcy5tYXRjaCA9IG1hdGNoOwotCi0gICAgaWYoKG1hdGNoX2xlbmd0aCA9IG1hdGNoLmxlbmd0aCkgIT0gdGFyZ2V0cy5sZW5ndGgpCi0gICAgICB0aHJvdyBuZXcgQ2xhc3NHZW5FeGNlcHRpb24oIk1hdGNoIGFuZCB0YXJnZXQgYXJyYXkgaGF2ZSBub3QgdGhlIHNhbWUgbGVuZ3RoIik7Ci0KLSAgICBpbmRpY2VzID0gbmV3IGludFttYXRjaF9sZW5ndGhdOwotICB9Ci0KLSAgLyoqCi0gICAqIFNpbmNlIHRoaXMgaXMgYSB2YXJpYWJsZSBsZW5ndGggaW5zdHJ1Y3Rpb24sIGl0IG1heSBzaGlmdCB0aGUgZm9sbG93aW5nCi0gICAqIGluc3RydWN0aW9ucyB3aGljaCB0aGVuIG5lZWQgdG8gdXBkYXRlIHRoZWlyIHBvc2l0aW9uLgotICAgKgotICAgKiBDYWxsZWQgYnkgSW5zdHJ1Y3Rpb25MaXN0LnNldFBvc2l0aW9ucyB3aGVuIHNldHRpbmcgdGhlIHBvc2l0aW9uIGZvciBldmVyeQotICAgKiBpbnN0cnVjdGlvbi4gSW4gdGhlIHByZXNlbmNlIG9mIHZhcmlhYmxlIGxlbmd0aCBpbnN0cnVjdGlvbnMgYHNldFBvc2l0aW9ucycKLSAgICogcGVyZm9ybXMgbXVsdGlwbGUgcGFzc2VzIG92ZXIgdGhlIGluc3RydWN0aW9uIGxpc3QgdG8gY2FsY3VsYXRlIHRoZQotICAgKiBjb3JyZWN0IChieXRlKSBwb3NpdGlvbnMgYW5kIG9mZnNldHMgYnkgY2FsbGluZyB0aGlzIGZ1bmN0aW9uLgotICAgKgotICAgKiBAcGFyYW0gb2Zmc2V0IGFkZGl0aW9uYWwgb2Zmc2V0IGNhdXNlZCBieSBwcmVjZWRpbmcgKHZhcmlhYmxlIGxlbmd0aCkgaW5zdHJ1Y3Rpb25zCi0gICAqIEBwYXJhbSBtYXhfb2Zmc2V0IHRoZSBtYXhpbXVtIG9mZnNldCB0aGF0IG1heSBiZSBjYXVzZWQgYnkgdGhlc2UgaW5zdHJ1Y3Rpb25zCi0gICAqIEByZXR1cm4gYWRkaXRpb25hbCBvZmZzZXQgY2F1c2VkIGJ5IHBvc3NpYmxlIGNoYW5nZSBvZiB0aGlzIGluc3RydWN0aW9uJ3MgbGVuZ3RoCi0gICAqLwotICBAT3ZlcnJpZGUKLSAgcHJvdGVjdGVkIGludCB1cGRhdGVQb3NpdGlvbihpbnQgb2Zmc2V0LCBpbnQgbWF4X29mZnNldCkgewotICAgIHBvc2l0aW9uICs9IG9mZnNldDsgLy8gQWRkaXRpb25hbCBvZmZzZXQgY2F1c2VkIGJ5IHByZWNlZGluZyBTV0lUQ0hzLCBHT1RPcywgZXRjLgotCi0gICAgc2hvcnQgb2xkX2xlbmd0aCA9IGxlbmd0aDsKLQotICAgIC8qIEFsaWdubWVudCBvbiA0LWJ5dGUtYm91bmRhcnksICsgMSwgYmVjYXVzZSBvZiB0YWcgYnl0ZS4KLSAgICAgKi8KLSAgICBwYWRkaW5nID0gKDQgLSAoKHBvc2l0aW9uICsgMSkgJSA0KSkgJSA0OwotICAgIGxlbmd0aCAgPSAoc2hvcnQpKGZpeGVkX2xlbmd0aCArIHBhZGRpbmcpOyAvLyBVcGRhdGUgbGVuZ3RoCi0KLSAgICByZXR1cm4gbGVuZ3RoIC0gb2xkX2xlbmd0aDsKLSAgfQotCi0gIC8qKgotICAgKiBEdW1wIGluc3RydWN0aW9uIGFzIGJ5dGUgY29kZSB0byBzdHJlYW0gb3V0LgotICAgKiBAcGFyYW0gb3V0IE91dHB1dCBzdHJlYW0KLSAgICovCi0gIEBPdmVycmlkZQotICBwdWJsaWMgdm9pZCBkdW1wKERhdGFPdXRwdXRTdHJlYW0gb3V0KSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgIG91dC53cml0ZUJ5dGUob3Bjb2RlKTsKLQotICAgIGZvcihpbnQgaT0wOyBpIDwgcGFkZGluZzsgaSsrKSAvLyBQYWRkaW5nIGJ5dGVzCi0gICAgICBvdXQud3JpdGVCeXRlKDApOwotCi0gICAgaW5kZXggPSBnZXRUYXJnZXRPZmZzZXQoKTsgICAgIC8vIFdyaXRlIGRlZmF1bHQgdGFyZ2V0IG9mZnNldAotICAgIG91dC53cml0ZUludChpbmRleCk7Ci0gIH0KLQotICAvKioKLSAgICogUmVhZCBuZWVkZWQgZGF0YSAoZS5nLiBpbmRleCkgZnJvbSBmaWxlLgotICAgKi8KLSAgQE92ZXJyaWRlCi0gIHByb3RlY3RlZCB2b2lkIGluaXRGcm9tRmlsZShCeXRlU2VxdWVuY2UgYnl0ZXMsIGJvb2xlYW4gd2lkZSkgdGhyb3dzIElPRXhjZXB0aW9uCi0gIHsKLSAgICBwYWRkaW5nID0gKDQgLSAoYnl0ZXMuZ2V0SW5kZXgoKSAlIDQpKSAlIDQ7IC8vIENvbXB1dGUgbnVtYmVyIG9mIHBhZCBieXRlcwotCi0gICAgZm9yKGludCBpPTA7IGkgPCBwYWRkaW5nOyBpKyspIHsKLSAgICAgIGJ5dGVzLnJlYWRCeXRlKCk7Ci0gICAgfQotCi0gICAgLy8gRGVmYXVsdCBicmFuY2ggdGFyZ2V0IGNvbW1vbiBmb3IgYm90aCBjYXNlcyAoVEFCTEVTV0lUQ0gsIExPT0tVUFNXSVRDSCkKLSAgICBpbmRleCA9IGJ5dGVzLnJlYWRJbnQoKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIG1uZW1vbmljIGZvciBpbnN0cnVjdGlvbgotICAgKi8KLSAgQE92ZXJyaWRlCi0gIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoYm9vbGVhbiB2ZXJib3NlKSB7Ci0gICAgZmluYWwgU3RyaW5nQnVpbGRlciBidWYgPSBuZXcgU3RyaW5nQnVpbGRlcihzdXBlci50b1N0cmluZyh2ZXJib3NlKSk7Ci0KLSAgICBpZih2ZXJib3NlKSB7Ci0gICAgICBmb3IoaW50IGk9MDsgaSA8IG1hdGNoX2xlbmd0aDsgaSsrKSB7Ci0gICAgICAgIFN0cmluZyBzID0gIm51bGwiOwotCi0gICAgICAgIGlmKHRhcmdldHNbaV0gIT0gbnVsbCkKLSAgICAgICAgICBzID0gdGFyZ2V0c1tpXS5nZXRJbnN0cnVjdGlvbigpLnRvU3RyaW5nKCk7Ci0KLSAgICAgICAgICBidWYuYXBwZW5kKCIoIikuYXBwZW5kKG1hdGNoW2ldKS5hcHBlbmQoIiwgIikKLSAgICAgICAgICAgICAuYXBwZW5kKHMpLmFwcGVuZCgiID0geyIpLmFwcGVuZChpbmRpY2VzW2ldKS5hcHBlbmQoIn0pIik7Ci0gICAgICB9Ci0gICAgfQotICAgIGVsc2UKLSAgICAgIGJ1Zi5hcHBlbmQoIiAuLi4iKTsKLQotICAgIHJldHVybiBidWYudG9TdHJpbmcoKTsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgYnJhbmNoIHRhcmdldCBmb3IgYGkndGggY2FzZQotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgc2V0VGFyZ2V0KGludCBpLCBJbnN0cnVjdGlvbkhhbmRsZSB0YXJnZXQpIHsKLSAgICBub3RpZnlUYXJnZXRDaGFuZ2luZyh0YXJnZXRzW2ldLCB0aGlzKTsKLSAgICB0YXJnZXRzW2ldID0gdGFyZ2V0OwotICAgIG5vdGlmeVRhcmdldENoYW5nZWQodGFyZ2V0c1tpXSwgdGhpcyk7Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIG9sZF9paCBvbGQgdGFyZ2V0Ci0gICAqIEBwYXJhbSBuZXdfaWggbmV3IHRhcmdldAotICAgKi8KLSAgQE92ZXJyaWRlCi0gIHB1YmxpYyB2b2lkIHVwZGF0ZVRhcmdldChJbnN0cnVjdGlvbkhhbmRsZSBvbGRfaWgsIEluc3RydWN0aW9uSGFuZGxlIG5ld19paCkgewotICAgIGJvb2xlYW4gdGFyZ2V0ZWQgPSBmYWxzZTsKLQotICAgIGlmKHRhcmdldCA9PSBvbGRfaWgpIHsKLSAgICAgIHRhcmdldGVkID0gdHJ1ZTsKLSAgICAgIHNldFRhcmdldChuZXdfaWgpOwotICAgIH0KLQotICAgIGZvcihpbnQgaT0wOyBpIDwgdGFyZ2V0cy5sZW5ndGg7IGkrKykgewotICAgICAgaWYodGFyZ2V0c1tpXSA9PSBvbGRfaWgpIHsKLSAgICAgICAgdGFyZ2V0ZWQgPSB0cnVlOwotICAgICAgICBzZXRUYXJnZXQoaSwgbmV3X2loKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICBpZighdGFyZ2V0ZWQpCi0gICAgICB0aHJvdyBuZXcgQ2xhc3NHZW5FeGNlcHRpb24oIk5vdCB0YXJnZXRpbmcgIiArIG9sZF9paCk7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiB0cnVlLCBpZiBpaCBpcyB0YXJnZXQgb2YgdGhpcyBpbnN0cnVjdGlvbgotICAgKi8KLSAgQE92ZXJyaWRlCi0gIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zVGFyZ2V0KEluc3RydWN0aW9uSGFuZGxlIGloKSB7Ci0gICAgaWYodGFyZ2V0ID09IGloKQotICAgICAgcmV0dXJuIHRydWU7Ci0KLSAgICBmb3IoaW50IGk9MDsgaSA8IHRhcmdldHMubGVuZ3RoOyBpKyspCi0gICAgICBpZih0YXJnZXRzW2ldID09IGloKQotICAgICAgICByZXR1cm4gdHJ1ZTsKLQotICAgIHJldHVybiBmYWxzZTsKLSAgfQotCi0gIC8qKgotICAgKiBJbmZvcm0gdGFyZ2V0cyB0aGF0IHRoZXkncmUgbm90IHRhcmdldGVkIGFueW1vcmUuCi0gICAqLwotICBAT3ZlcnJpZGUKLSAgdm9pZCBkaXNwb3NlKCkgewotICAgIHN1cGVyLmRpc3Bvc2UoKTsKLQotICAgIGZvcihpbnQgaT0wOyBpIDwgdGFyZ2V0cy5sZW5ndGg7IGkrKykKLSAgICAgIHRhcmdldHNbaV0ucmVtb3ZlVGFyZ2V0ZXIodGhpcyk7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBhcnJheSBvZiBtYXRjaCBpbmRpY2VzCi0gICAqLwotICBwdWJsaWMgaW50W10gZ2V0TWF0Y2hzKCkgeyByZXR1cm4gbWF0Y2g7IH0KLQotICAvKioKLSAgICogQHJldHVybiBhcnJheSBvZiBtYXRjaCB0YXJnZXQgb2Zmc2V0cwotICAgKi8KLSAgcHVibGljIGludFtdIGdldEluZGljZXMoKSB7IHJldHVybiBpbmRpY2VzOyB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gYXJyYXkgb2YgbWF0Y2ggdGFyZ2V0cwotICAgKi8KLSAgcHVibGljIEluc3RydWN0aW9uSGFuZGxlW10gZ2V0VGFyZ2V0cygpIHsgcmV0dXJuIHRhcmdldHM7IH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL1N0YWNrQ29uc3VtZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL1N0YWNrQ29uc3VtZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZWZlYTRhNi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9TdGFja0NvbnN1bWVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3MCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIERlbm90ZSBhbiBpbnN0cnVjdGlvbiB0aGF0IG1heSBjb25zdW1lIGEgdmFsdWUgZnJvbSB0aGUgc3RhY2suCi0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGludGVyZmFjZSBTdGFja0NvbnN1bWVyIHsKLSAgLyoqIEByZXR1cm4gaG93IG1hbnkgd29yZHMgYXJlIGNvbnN1bWVkIGZyb20gc3RhY2sKLSAgICovCi0gIHB1YmxpYyBpbnQgY29uc3VtZVN0YWNrKENvbnN0YW50UG9vbEdlbiBjcGcpOwotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvU3RhY2tJbnN0cnVjdGlvbi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvU3RhY2tJbnN0cnVjdGlvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiNmEwYzM5Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL1N0YWNrSW5zdHJ1Y3Rpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDg1ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8qKgotICogU3VwZXIgY2xhc3MgZm9yIHN0YWNrIG9wZXJhdGlvbnMgbGlrZSBEVVAgYW5kIFBPUC4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgYWJzdHJhY3QgY2xhc3MgU3RhY2tJbnN0cnVjdGlvbiBleHRlbmRzIEluc3RydWN0aW9uIHsKLSAgLyoqCi0gICAqIEVtcHR5IGNvbnN0cnVjdG9yIG5lZWRlZCBmb3IgdGhlIENsYXNzLm5ld0luc3RhbmNlKCkgc3RhdGVtZW50IGluCi0gICAqIEluc3RydWN0aW9uLnJlYWRJbnN0cnVjdGlvbigpLiBOb3QgdG8gYmUgdXNlZCBvdGhlcndpc2UuCi0gICAqLwotICBTdGFja0luc3RydWN0aW9uKCkge30KLQotICAvKioKLSAgICogQHBhcmFtIG9wY29kZSBpbnN0cnVjdGlvbiBvcGNvZGUKLSAgICovCi0gIHByb3RlY3RlZCBTdGFja0luc3RydWN0aW9uKHNob3J0IG9wY29kZSkgewotICAgIHN1cGVyKG9wY29kZSwgKHNob3J0KTEpOwotICB9Ci0KLSAgLyoqIEByZXR1cm4gVHlwZS5VTktOT1dOCi0gICAqLwotICBwdWJsaWMgVHlwZSBnZXRUeXBlKENvbnN0YW50UG9vbEdlbiBjcCkgewotICAgIHJldHVybiBUeXBlLlVOS05PV047Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL1N0YWNrUHJvZHVjZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL1N0YWNrUHJvZHVjZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZGMxMjMxYy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9TdGFja1Byb2R1Y2VyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3MSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIERlbm90ZSBhbiBpbnN0cnVjdGlvbiB0aGF0IG1heSBwcm9kdWNlIGEgdmFsdWUgb24gdG9wIG9mIHRoZSBzdGFjawotICogKHRoaXMgZXhjbHVkZXMgRFVQX1gxLCBlLmcuKQotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgU3RhY2tQcm9kdWNlciB7Ci0gIC8qKiBAcmV0dXJuIGhvdyBtYW55IHdvcmRzIGFyZSBwcm9kdWNlZCBvbiBzdGFjawotICAgKi8KLSAgcHVibGljIGludCBwcm9kdWNlU3RhY2soQ29uc3RhbnRQb29sR2VuIGNwZyk7Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9TdG9yZUluc3RydWN0aW9uLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9TdG9yZUluc3RydWN0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGVkMzE5N2EuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvU3RvcmVJbnN0cnVjdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTAzICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8qKgotICogRGVub3RlcyBhbiB1bnBhcmFtZXRlcml6ZWQgaW5zdHJ1Y3Rpb24gdG8gc3RvcmUgYSB2YWx1ZSBpbnRvIGEgbG9jYWwgdmFyaWFibGUsCi0gKiBlLmcuIElTVE9SRS4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgYWJzdHJhY3QgY2xhc3MgU3RvcmVJbnN0cnVjdGlvbiBleHRlbmRzIExvY2FsVmFyaWFibGVJbnN0cnVjdGlvbgotICBpbXBsZW1lbnRzIFBvcEluc3RydWN0aW9uCi17Ci0gIC8qKgotICAgKiBFbXB0eSBjb25zdHJ1Y3RvciBuZWVkZWQgZm9yIHRoZSBDbGFzcy5uZXdJbnN0YW5jZSgpIHN0YXRlbWVudCBpbgotICAgKiBJbnN0cnVjdGlvbi5yZWFkSW5zdHJ1Y3Rpb24oKS4gTm90IHRvIGJlIHVzZWQgb3RoZXJ3aXNlLgotICAgKiB0YWcgYW5kIGxlbmd0aCBhcmUgZGVmaW5lZCBpbiByZWFkSW5zdHJ1Y3Rpb24gYW5kIGluaXRGcm9tRmlsZSwgcmVzcGVjdGl2ZWx5LgotICAgKi8KLSAgU3RvcmVJbnN0cnVjdGlvbihzaG9ydCBjYW5vbl90YWcsIHNob3J0IGNfdGFnKSB7Ci0gICAgc3VwZXIoY2Fub25fdGFnLCBjX3RhZyk7Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIG9wY29kZSBJbnN0cnVjdGlvbiBvcGNvZGUKLSAgICogQHBhcmFtIGNfdGFnIEluc3RydWN0aW9uIG51bWJlciBmb3IgY29tcGFjdCB2ZXJzaW9uLCBBU1RPUkVfMCwgZS5nLgotICAgKiBAcGFyYW0gbiBsb2NhbCB2YXJpYWJsZSBpbmRleCAodW5zaWduZWQgc2hvcnQpCi0gICAqLwotICBwcm90ZWN0ZWQgU3RvcmVJbnN0cnVjdGlvbihzaG9ydCBvcGNvZGUsIHNob3J0IGNfdGFnLCBpbnQgbikgewotICAgIHN1cGVyKG9wY29kZSwgY190YWcsIG4pOwotICB9Ci0KLSAgLyoqCi0gICAqIENhbGwgY29ycmVzcG9uZGluZyB2aXNpdG9yIG1ldGhvZChzKS4gVGhlIG9yZGVyIGlzOgotICAgKiBDYWxsIHZpc2l0b3IgbWV0aG9kcyBvZiBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzIGZpcnN0LCB0aGVuCi0gICAqIGNhbGwgbWV0aG9kcyBhY2NvcmRpbmcgdG8gdGhlIGNsYXNzIGhpZXJhcmNoeSBpbiBkZXNjZW5kaW5nIG9yZGVyLAotICAgKiBpLmUuLCB0aGUgbW9zdCBzcGVjaWZpYyB2aXNpdFhYWCgpIGNhbGwgY29tZXMgbGFzdC4KLSAgICoKLSAgICogQHBhcmFtIHYgVmlzaXRvciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsKLSAgICB2LnZpc2l0U3RhY2tDb25zdW1lcih0aGlzKTsKLSAgICB2LnZpc2l0UG9wSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdFR5cGVkSW5zdHJ1Y3Rpb24odGhpcyk7Ci0gICAgdi52aXNpdExvY2FsVmFyaWFibGVJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0U3RvcmVJbnN0cnVjdGlvbih0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvVEFCTEVTV0lUQ0guamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL1RBQkxFU1dJVENILmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDVmYjkwNzUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvVEFCTEVTV0lUQ0guamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE1MCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotaW1wb3J0IGphdmEuaW8uKjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC51dGlsLkJ5dGVTZXF1ZW5jZTsKLQotLyoqCi0gKiBUQUJMRVNXSVRDSCAtIFN3aXRjaCB3aXRoaW4gZ2l2ZW4gcmFuZ2Ugb2YgdmFsdWVzLCBpLmUuLCBsb3cuLmhpZ2gKLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICogQHNlZSBTV0lUQ0gKLSAqLwotcHVibGljIGNsYXNzIFRBQkxFU1dJVENIIGV4dGVuZHMgU2VsZWN0IHsKLSAgLyoqCi0gICAqIEVtcHR5IGNvbnN0cnVjdG9yIG5lZWRlZCBmb3IgdGhlIENsYXNzLm5ld0luc3RhbmNlKCkgc3RhdGVtZW50IGluCi0gICAqIEluc3RydWN0aW9uLnJlYWRJbnN0cnVjdGlvbigpLiBOb3QgdG8gYmUgdXNlZCBvdGhlcndpc2UuCi0gICAqLwotICBUQUJMRVNXSVRDSCgpIHt9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBtYXRjaCBzb3J0ZWQgYXJyYXkgb2YgbWF0Y2ggdmFsdWVzLCBtYXRjaFswXSBtdXN0IGJlIGxvdyB2YWx1ZSwKLSAgICogbWF0Y2hbbWF0Y2hfbGVuZ3RoIC0gMV0gaGlnaCB2YWx1ZQotICAgKiBAcGFyYW0gdGFyZ2V0cyB3aGVyZSB0byBicmFuY2ggZm9yIG1hdGNoZWQgdmFsdWVzCi0gICAqIEBwYXJhbSB0YXJnZXQgZGVmYXVsdCBicmFuY2gKLSAgICovCi0gIHB1YmxpYyBUQUJMRVNXSVRDSChpbnRbXSBtYXRjaCwgSW5zdHJ1Y3Rpb25IYW5kbGVbXSB0YXJnZXRzLAotICAgICAgICAgICAgICAgICAgICAgSW5zdHJ1Y3Rpb25IYW5kbGUgdGFyZ2V0KSB7Ci0gICAgc3VwZXIoY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLlRBQkxFU1dJVENILCBtYXRjaCwgdGFyZ2V0cywgdGFyZ2V0KTsKLQotICAgIGxlbmd0aCA9IChzaG9ydCkoMTMgKyBtYXRjaF9sZW5ndGggKiA0KTsgLyogQWxpZ25tZW50IHJlbWFpbmRlciBhc3N1bWVkCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiAwIGhlcmUsIHVudGlsIGR1bXAgdGltZSAqLwotICAgIGZpeGVkX2xlbmd0aCA9IGxlbmd0aDsKLSAgfQotCi0gIC8qKgotICAgKiBEdW1wIGluc3RydWN0aW9uIGFzIGJ5dGUgY29kZSB0byBzdHJlYW0gb3V0LgotICAgKiBAcGFyYW0gb3V0IE91dHB1dCBzdHJlYW0KLSAgICovCi0gIHB1YmxpYyB2b2lkIGR1bXAoRGF0YU91dHB1dFN0cmVhbSBvdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgc3VwZXIuZHVtcChvdXQpOwotCi0gICAgaW50IGxvdyA9IChtYXRjaF9sZW5ndGggPiAwKT8gbWF0Y2hbMF0gOiAwOwotICAgIG91dC53cml0ZUludChsb3cpOwotCi0gICAgaW50IGhpZ2ggPSAobWF0Y2hfbGVuZ3RoID4gMCk/IG1hdGNoW21hdGNoX2xlbmd0aCAtIDFdIDogMDsKLSAgICBvdXQud3JpdGVJbnQoaGlnaCk7Ci0KLSAgICBmb3IoaW50IGk9MDsgaSA8IG1hdGNoX2xlbmd0aDsgaSsrKSAgICAgLy8ganVtcCBvZmZzZXRzCi0gICAgICBvdXQud3JpdGVJbnQoaW5kaWNlc1tpXSA9IGdldFRhcmdldE9mZnNldCh0YXJnZXRzW2ldKSk7Ci0gIH0KLQotICAvKioKLSAgICogUmVhZCBuZWVkZWQgZGF0YSAoZS5nLiBpbmRleCkgZnJvbSBmaWxlLgotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgaW5pdEZyb21GaWxlKEJ5dGVTZXF1ZW5jZSBieXRlcywgYm9vbGVhbiB3aWRlKSB0aHJvd3MgSU9FeGNlcHRpb24KLSAgewotICAgIHN1cGVyLmluaXRGcm9tRmlsZShieXRlcywgd2lkZSk7Ci0KLSAgICBpbnQgbG93ICAgID0gYnl0ZXMucmVhZEludCgpOwotICAgIGludCBoaWdoICAgPSBieXRlcy5yZWFkSW50KCk7Ci0KLSAgICBtYXRjaF9sZW5ndGggPSBoaWdoIC0gbG93ICsgMTsKLSAgICBmaXhlZF9sZW5ndGggPSAoc2hvcnQpKDEzICsgbWF0Y2hfbGVuZ3RoICogNCk7Ci0gICAgbGVuZ3RoICAgICAgID0gKHNob3J0KShmaXhlZF9sZW5ndGggKyBwYWRkaW5nKTsKLQotICAgIG1hdGNoICAgPSBuZXcgaW50W21hdGNoX2xlbmd0aF07Ci0gICAgaW5kaWNlcyA9IG5ldyBpbnRbbWF0Y2hfbGVuZ3RoXTsKLSAgICB0YXJnZXRzID0gbmV3IEluc3RydWN0aW9uSGFuZGxlW21hdGNoX2xlbmd0aF07Ci0KLSAgICBmb3IoaW50IGk9bG93OyBpIDw9IGhpZ2g7IGkrKykKLSAgICAgIG1hdGNoW2kgLSBsb3ddID0gaTsKLQotICAgIGZvcihpbnQgaT0wOyBpIDwgbWF0Y2hfbGVuZ3RoOyBpKyspIHsKLSAgICAgIGluZGljZXNbaV0gPSBieXRlcy5yZWFkSW50KCk7Ci0gICAgfQotICB9Ci0KLQotICAvKioKLSAgICogQ2FsbCBjb3JyZXNwb25kaW5nIHZpc2l0b3IgbWV0aG9kKHMpLiBUaGUgb3JkZXIgaXM6Ci0gICAqIENhbGwgdmlzaXRvciBtZXRob2RzIG9mIGltcGxlbWVudGVkIGludGVyZmFjZXMgZmlyc3QsIHRoZW4KLSAgICogY2FsbCBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY2xhc3MgaGllcmFyY2h5IGluIGRlc2NlbmRpbmcgb3JkZXIsCi0gICAqIGkuZS4sIHRoZSBtb3N0IHNwZWNpZmljIHZpc2l0WFhYKCkgY2FsbCBjb21lcyBsYXN0LgotICAgKgotICAgKiBAcGFyYW0gdiBWaXNpdG9yIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewotICAgIHYudmlzaXRWYXJpYWJsZUxlbmd0aEluc3RydWN0aW9uKHRoaXMpOwotICAgIHYudmlzaXRTdGFja1Byb2R1Y2VyKHRoaXMpOwotICAgIHYudmlzaXRCcmFuY2hJbnN0cnVjdGlvbih0aGlzKTsKLSAgICB2LnZpc2l0U2VsZWN0KHRoaXMpOwotICAgIHYudmlzaXRUQUJMRVNXSVRDSCh0aGlzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvVGFyZ2V0TG9zdEV4Y2VwdGlvbi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvVGFyZ2V0TG9zdEV4Y2VwdGlvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmY2FjMGZlLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL1RhcmdldExvc3RFeGNlcHRpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEwMyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIFRocm93biBieSBJbnN0cnVjdGlvbkxpc3QucmVtb3ZlKCkgd2hlbiBvbmUgb3IgbXVsdGlwbGUgZGlzcG9zZWQgaW5zdHJ1Y3Rpb24KLSAqIGFyZSBzdGlsbCBiZWluZyByZWZlcmVuY2VkIGJ5IGEgSW5zdHJ1Y3Rpb25UYXJnZXRlciBvYmplY3QuIEkuZS4gdGhlCi0gKiBJbnN0cnVjdGlvblRhcmdldGVyIGhhcyB0byBiZSBub3RpZmllZCB0aGF0IChvbmUgb2YpIHRoZSBJbnN0cnVjdGlvbkhhbmRsZSBpdAotICogaXMgcmVmZXJlbmNpbmcgaXMgYmVpbmcgcmVtb3ZlZCBmcm9tIHRoZSBJbnN0cnVjdGlvbkxpc3QgYW5kIHRodXMgbm90IHZhbGlkIGFueW1vcmUuCi0gKgotICogTWFraW5nIHRoaXMgYW4gZXhjZXB0aW9uIGluc3RlYWQgb2YgYSByZXR1cm4gdmFsdWUgZm9yY2VzIHRoZSB1c2VyIHRvIGhhbmRsZQotICogdGhlc2UgY2FzZSBleHBsaWNpdGVseSBpbiBhIHRyeSB7IC4uLiB9IGNhdGNoLiBUaGUgZm9sbG93aW5nIGNvZGUgaWxsdXN0cmF0ZXMKLSAqIGhvdyB0aGlzIG1heSBiZSBkb25lOgotICoKLSAqIDxQUkU+Ci0gKiAgICAgLi4uCi0gKiAgICAgdHJ5IHsKLSAqICAgICAgaWwuZGVsZXRlKHN0YXJ0X2loLCBlbmRfaWgpOwotICogICAgIH0gY2F0Y2goVGFyZ2V0TG9zdEV4Y2VwdGlvbiBlKSB7Ci0gKiAgICAgICBJbnN0cnVjdGlvbkhhbmRsZVtdIHRhcmdldHMgPSBlLmdldFRhcmdldHMoKTsKLSAqICAgICAgIGZvcihpbnQgaT0wOyBpIDwgdGFyZ2V0cy5sZW5ndGg7IGkrKykgewotICogICAgICAgICBJbnN0cnVjdGlvblRhcmdldGVyW10gdGFyZ2V0ZXJzID0gdGFyZ2V0c1tpXS5nZXRUYXJnZXRlcnMoKTsKLSAqCi0gKiAgICAgICAgIGZvcihpbnQgaj0wOyBqIDwgdGFyZ2V0ZXJzLmxlbmd0aDsgaisrKQotICogICAgICAgICAgIHRhcmdldGVyc1tqXS51cGRhdGVUYXJnZXQodGFyZ2V0c1tpXSwgbmV3X3RhcmdldCk7Ci0gKiAgICAgICB9Ci0gKiAgICAgfQotICogPC9QUkU+Ci0gKgotICogQHNlZSBJbnN0cnVjdGlvbkhhbmRsZQotICogQHNlZSBJbnN0cnVjdGlvbkxpc3QKLSAqIEBzZWUgSW5zdHJ1Y3Rpb25UYXJnZXRlcgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIFRhcmdldExvc3RFeGNlcHRpb24gZXh0ZW5kcyBFeGNlcHRpb24gewotICBwcml2YXRlIEluc3RydWN0aW9uSGFuZGxlW10gdGFyZ2V0czsKLQotICBUYXJnZXRMb3N0RXhjZXB0aW9uKEluc3RydWN0aW9uSGFuZGxlW10gdCwgU3RyaW5nIG1lc2cpIHsKLSAgICBzdXBlcihtZXNnKTsKLSAgICB0YXJnZXRzID0gdDsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIGxpc3Qgb2YgaW5zdHJ1Y3Rpb25zIHN0aWxsIGJlaW5nIHRhcmdldGVkLgotICAgKi8KLSAgcHVibGljIEluc3RydWN0aW9uSGFuZGxlW10gZ2V0VGFyZ2V0cygpIHsgcmV0dXJuIHRhcmdldHM7IH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL1R5cGUuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL1R5cGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYjQ5NmVkOC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9UeXBlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyOTAgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50czsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5jbGFzc2ZpbGUuKjsKLWltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwotCi0vKioKLSAqIEFic3RyYWN0IHN1cGVyIGNsYXNzIGZvciBhbGwgcG9zc2libGUgamF2YSB0eXBlcywgbmFtZWx5IGJhc2ljIHR5cGVzCi0gKiBzdWNoIGFzIGludCwgb2JqZWN0IHR5cGVzIGxpa2UgU3RyaW5nIGFuZCBhcnJheSB0eXBlcywgZS5nLiBpbnRbXQotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBUeXBlIGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUgewotICBwcm90ZWN0ZWQgYnl0ZSAgIHR5cGU7Ci0gIHByb3RlY3RlZCBTdHJpbmcgc2lnbmF0dXJlOyAvLyBzaWduYXR1cmUgZm9yIHRoZSB0eXBlCi0KLSAgLyoqIFByZWRlZmluZWQgY29uc3RhbnRzCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEJhc2ljVHlwZSAgICAgVk9JRCAgICAgICAgID0gbmV3IEJhc2ljVHlwZShDb25zdGFudHMuVF9WT0lEKTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBCYXNpY1R5cGUgICAgIEJPT0xFQU4gICAgICA9IG5ldyBCYXNpY1R5cGUoQ29uc3RhbnRzLlRfQk9PTEVBTik7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgQmFzaWNUeXBlICAgICBJTlQgICAgICAgICAgPSBuZXcgQmFzaWNUeXBlKENvbnN0YW50cy5UX0lOVCk7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgQmFzaWNUeXBlICAgICBTSE9SVCAgICAgICAgPSBuZXcgQmFzaWNUeXBlKENvbnN0YW50cy5UX1NIT1JUKTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBCYXNpY1R5cGUgICAgIEJZVEUgICAgICAgICA9IG5ldyBCYXNpY1R5cGUoQ29uc3RhbnRzLlRfQllURSk7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgQmFzaWNUeXBlICAgICBMT05HICAgICAgICAgPSBuZXcgQmFzaWNUeXBlKENvbnN0YW50cy5UX0xPTkcpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEJhc2ljVHlwZSAgICAgRE9VQkxFICAgICAgID0gbmV3IEJhc2ljVHlwZShDb25zdGFudHMuVF9ET1VCTEUpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIEJhc2ljVHlwZSAgICAgRkxPQVQgICAgICAgID0gbmV3IEJhc2ljVHlwZShDb25zdGFudHMuVF9GTE9BVCk7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgQmFzaWNUeXBlICAgICBDSEFSICAgICAgICAgPSBuZXcgQmFzaWNUeXBlKENvbnN0YW50cy5UX0NIQVIpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIE9iamVjdFR5cGUgICAgT0JKRUNUICAgICAgID0gbmV3IE9iamVjdFR5cGUoImphdmEubGFuZy5PYmplY3QiKTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBPYmplY3RUeXBlICAgIFNUUklORyAgICAgICA9IG5ldyBPYmplY3RUeXBlKCJqYXZhLmxhbmcuU3RyaW5nIik7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgT2JqZWN0VHlwZSAgICBTVFJJTkdCVUZGRVIgPSBuZXcgT2JqZWN0VHlwZSgiamF2YS5sYW5nLlN0cmluZ0J1ZmZlciIpOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIE9iamVjdFR5cGUgICAgVEhST1dBQkxFICAgID0gbmV3IE9iamVjdFR5cGUoImphdmEubGFuZy5UaHJvd2FibGUiKTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBUeXBlW10gICAgICAgIE5PX0FSR1MgICAgICA9IG5ldyBUeXBlWzBdOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFJlZmVyZW5jZVR5cGUgTlVMTCAgICAgICAgID0gbmV3IFJlZmVyZW5jZVR5cGUoKXt9OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFR5cGUgICAgICAgICAgVU5LTk9XTiAgICAgID0gbmV3IFR5cGUoQ29uc3RhbnRzLlRfVU5LTk9XTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI8dW5rbm93biBvYmplY3Q+Iil7fTsKLQotICBwcm90ZWN0ZWQgVHlwZShieXRlIHQsIFN0cmluZyBzKSB7Ci0gICAgdHlwZSAgICAgID0gdDsKLSAgICBzaWduYXR1cmUgPSBzOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gc2lnbmF0dXJlIGZvciBnaXZlbiB0eXBlLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRTaWduYXR1cmUoKSB7IHJldHVybiBzaWduYXR1cmU7IH0KLQotICAvKioKLSAgICogQHJldHVybiB0eXBlIGFzIGRlZmluZWQgaW4gQ29uc3RhbnRzCi0gICAqLwotICBwdWJsaWMgYnl0ZSBnZXRUeXBlKCkgeyByZXR1cm4gdHlwZTsgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIHN0YWNrIHNpemUgb2YgdGhpcyB0eXBlICgyIGZvciBsb25nIGFuZCBkb3VibGUsIDAgZm9yIHZvaWQsIDEgb3RoZXJ3aXNlKQotICAgKi8KLSAgcHVibGljIGludCBnZXRTaXplKCkgewotICAgIHN3aXRjaCh0eXBlKSB7Ci0gICAgY2FzZSBDb25zdGFudHMuVF9ET1VCTEU6Ci0gICAgY2FzZSBDb25zdGFudHMuVF9MT05HOiByZXR1cm4gMjsKLSAgICBjYXNlIENvbnN0YW50cy5UX1ZPSUQ6IHJldHVybiAwOwotICAgIGRlZmF1bHQ6ICAgICByZXR1cm4gMTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBUeXBlIHN0cmluZywgZS5nLiBgaW50W10nCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgIHJldHVybiAoKHRoaXMuZXF1YWxzKFR5cGUuTlVMTCkgfHwgKHR5cGUgPj0gQ29uc3RhbnRzLlRfVU5LTk9XTikpKT8gc2lnbmF0dXJlIDoKLSAgICAgIFV0aWxpdHkuc2lnbmF0dXJlVG9TdHJpbmcoc2lnbmF0dXJlLCBmYWxzZSk7Ci0gIH0KLQotICAvKioKLSAgICogQ29udmVydCB0eXBlIHRvIEphdmEgbWV0aG9kIHNpZ25hdHVyZSwgZS5nLiBpbnRbXSBmKGphdmEubGFuZy5TdHJpbmcgeCkKLSAgICogYmVjb21lcyAoTGphdmEvbGFuZy9TdHJpbmc7KVtJCi0gICAqCi0gICAqIEBwYXJhbSByZXR1cm5fdHlwZSB3aGF0IHRoZSBtZXRob2QgcmV0dXJucwotICAgKiBAcGFyYW0gYXJnX3R5cGVzIHdoYXQgYXJlIHRoZSBhcmd1bWVudCB0eXBlcwotICAgKiBAcmV0dXJuIG1ldGhvZCBzaWduYXR1cmUgZm9yIGdpdmVuIHR5cGUocykuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIFN0cmluZyBnZXRNZXRob2RTaWduYXR1cmUoVHlwZSByZXR1cm5fdHlwZSwgVHlwZVtdIGFyZ190eXBlcykgewotICAgIFN0cmluZ0J1ZmZlciBidWYgPSBuZXcgU3RyaW5nQnVmZmVyKCIoIik7Ci0gICAgaW50IGxlbmd0aCA9IChhcmdfdHlwZXMgPT0gbnVsbCk/IDAgOiBhcmdfdHlwZXMubGVuZ3RoOwotCi0gICAgZm9yKGludCBpPTA7IGkgPCBsZW5ndGg7IGkrKykKLSAgICAgIGJ1Zi5hcHBlbmQoYXJnX3R5cGVzW2ldLmdldFNpZ25hdHVyZSgpKTsKLQotICAgIGJ1Zi5hcHBlbmQoJyknKTsKLSAgICBidWYuYXBwZW5kKHJldHVybl90eXBlLmdldFNpZ25hdHVyZSgpKTsKLQotICAgIHJldHVybiBidWYudG9TdHJpbmcoKTsKLSAgfQotCi0gIHByaXZhdGUgc3RhdGljIGludCBjb25zdW1lZF9jaGFycz0wOyAvLyBSZW1lbWJlciBwb3NpdGlvbiBpbiBzdHJpbmcsIHNlZSBnZXRBcmd1bWVudFR5cGVzCi0KLSAgLyoqCi0gICAqIENvbnZlcnQgc2lnbmF0dXJlIHRvIGEgVHlwZSBvYmplY3QuCi0gICAqIEBwYXJhbSBzaWduYXR1cmUgc2lnbmF0dXJlIHN0cmluZyBzdWNoIGFzIExqYXZhL2xhbmcvU3RyaW5nOwotICAgKiBAcmV0dXJuIHR5cGUgb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFR5cGUgZ2V0VHlwZShTdHJpbmcgc2lnbmF0dXJlKQotICAgIHRocm93cyBTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCi0gIHsKLSAgICBieXRlIHR5cGUgPSBVdGlsaXR5LnR5cGVPZlNpZ25hdHVyZShzaWduYXR1cmUpOwotCi0gICAgaWYodHlwZSA8PSBDb25zdGFudHMuVF9WT0lEKSB7Ci0gICAgICBjb25zdW1lZF9jaGFycyA9IDE7Ci0gICAgICByZXR1cm4gQmFzaWNUeXBlLmdldFR5cGUodHlwZSk7Ci0gICAgfSBlbHNlIGlmKHR5cGUgPT0gQ29uc3RhbnRzLlRfQVJSQVkpIHsKLSAgICAgIGludCBkaW09MDsKLSAgICAgIGRvIHsgLy8gQ291bnQgZGltZW5zaW9ucwotICAgICAgICBkaW0rKzsKLSAgICAgIH0gd2hpbGUoc2lnbmF0dXJlLmNoYXJBdChkaW0pID09ICdbJyk7Ci0KLSAgICAgIC8vIFJlY3Vyc2UsIGJ1dCBqdXN0IG9uY2UsIGlmIHRoZSBzaWduYXR1cmUgaXMgb2sKLSAgICAgIFR5cGUgdCA9IGdldFR5cGUoc2lnbmF0dXJlLnN1YnN0cmluZyhkaW0pKTsKLQotICAgICAgY29uc3VtZWRfY2hhcnMgKz0gZGltOyAvLyB1cGRhdGUgY291bnRlcgotCi0gICAgICByZXR1cm4gbmV3IEFycmF5VHlwZSh0LCBkaW0pOwotICAgIH0gZWxzZSB7IC8vIHR5cGUgPT0gVF9SRUZFUkVOQ0UKLSAgICAgIGludCBpbmRleCA9IHNpZ25hdHVyZS5pbmRleE9mKCc7Jyk7IC8vIExvb2sgZm9yIGNsb3NpbmcgYDsnCi0KLSAgICAgIGlmKGluZGV4IDwgMCkKLSAgICAgICAgdGhyb3cgbmV3IENsYXNzRm9ybWF0RXhjZXB0aW9uKCJJbnZhbGlkIHNpZ25hdHVyZTogIiArIHNpZ25hdHVyZSk7Ci0KLSAgICAgIGNvbnN1bWVkX2NoYXJzID0gaW5kZXggKyAxOyAvLyAiTGJsYWJsYTsiIGBMJyBhbmQgYDsnIGFyZSByZW1vdmVkCi0KLSAgICAgIHJldHVybiBuZXcgT2JqZWN0VHlwZShzaWduYXR1cmUuc3Vic3RyaW5nKDEsIGluZGV4KS5yZXBsYWNlKCcvJywgJy4nKSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIENvbnZlcnQgcmV0dXJuIHZhbHVlIG9mIGEgbWV0aG9kIChzaWduYXR1cmUpIHRvIGEgVHlwZSBvYmplY3QuCi0gICAqCi0gICAqIEBwYXJhbSBzaWduYXR1cmUgc2lnbmF0dXJlIHN0cmluZyBzdWNoIGFzIChMamF2YS9sYW5nL1N0cmluZzspVgotICAgKiBAcmV0dXJuIHJldHVybiB0eXBlCi0gICAqLwotICBwdWJsaWMgc3RhdGljIFR5cGUgZ2V0UmV0dXJuVHlwZShTdHJpbmcgc2lnbmF0dXJlKSB7Ci0gICAgdHJ5IHsKLSAgICAgIC8vIFJlYWQgcmV0dXJuIHR5cGUgYWZ0ZXIgYCknCi0gICAgICBpbnQgaW5kZXggPSBzaWduYXR1cmUubGFzdEluZGV4T2YoJyknKSArIDE7Ci0gICAgICByZXR1cm4gZ2V0VHlwZShzaWduYXR1cmUuc3Vic3RyaW5nKGluZGV4KSk7Ci0gICAgfSBjYXRjaChTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsgLy8gU2hvdWxkIG5ldmVyIG9jY3VyCi0gICAgICB0aHJvdyBuZXcgQ2xhc3NGb3JtYXRFeGNlcHRpb24oIkludmFsaWQgbWV0aG9kIHNpZ25hdHVyZTogIiArIHNpZ25hdHVyZSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIENvbnZlcnQgYXJndW1lbnRzIG9mIGEgbWV0aG9kIChzaWduYXR1cmUpIHRvIGFuIGFycmF5IG9mIFR5cGUgb2JqZWN0cy4KLSAgICogQHBhcmFtIHNpZ25hdHVyZSBzaWduYXR1cmUgc3RyaW5nIHN1Y2ggYXMgKExqYXZhL2xhbmcvU3RyaW5nOylWCi0gICAqIEByZXR1cm4gYXJyYXkgb2YgYXJndW1lbnQgdHlwZXMKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgVHlwZVtdIGdldEFyZ3VtZW50VHlwZXMoU3RyaW5nIHNpZ25hdHVyZSkgewotICAgIEFycmF5TGlzdCB2ZWMgPSBuZXcgQXJyYXlMaXN0KCk7Ci0gICAgaW50ICAgICAgIGluZGV4OwotICAgIFR5cGVbXSAgICAgdHlwZXM7Ci0KLSAgICB0cnkgeyAvLyBSZWFkIGFsbCBkZWNsYXJhdGlvbnMgYmV0d2VlbiBmb3IgYCgnIGFuZCBgKScKLSAgICAgIGlmKHNpZ25hdHVyZS5jaGFyQXQoMCkgIT0gJygnKQotICAgICAgICB0aHJvdyBuZXcgQ2xhc3NGb3JtYXRFeGNlcHRpb24oIkludmFsaWQgbWV0aG9kIHNpZ25hdHVyZTogIiArIHNpZ25hdHVyZSk7Ci0KLSAgICAgIGluZGV4ID0gMTsgLy8gY3VycmVudCBzdHJpbmcgcG9zaXRpb24KLQotICAgICAgd2hpbGUoc2lnbmF0dXJlLmNoYXJBdChpbmRleCkgIT0gJyknKSB7Ci0gICAgICAgIHZlYy5hZGQoZ2V0VHlwZShzaWduYXR1cmUuc3Vic3RyaW5nKGluZGV4KSkpOwotICAgICAgICBpbmRleCArPSBjb25zdW1lZF9jaGFyczsgLy8gdXBkYXRlIHBvc2l0aW9uCi0gICAgICB9Ci0gICAgfSBjYXRjaChTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsgLy8gU2hvdWxkIG5ldmVyIG9jY3VyCi0gICAgICB0aHJvdyBuZXcgQ2xhc3NGb3JtYXRFeGNlcHRpb24oIkludmFsaWQgbWV0aG9kIHNpZ25hdHVyZTogIiArIHNpZ25hdHVyZSk7Ci0gICAgfQotCi0gICAgdHlwZXMgPSBuZXcgVHlwZVt2ZWMuc2l6ZSgpXTsKLSAgICB2ZWMudG9BcnJheSh0eXBlcyk7Ci0gICAgcmV0dXJuIHR5cGVzOwotICB9Ci0KLSAgLyoqIENvbnZlcnQgcnVudGltZSBqYXZhLmxhbmcuQ2xhc3MgdG8gQkNFTCBUeXBlIG9iamVjdC4KLSAgICogQHBhcmFtIGNsIEphdmEgY2xhc3MKLSAgICogQHJldHVybiBjb3JyZXNwb25kaW5nIFR5cGUgb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgc3RhdGljIFR5cGUgZ2V0VHlwZShqYXZhLmxhbmcuQ2xhc3MgY2wpIHsKLSAgICBpZihjbCA9PSBudWxsKSB7Ci0gICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJDbGFzcyBtdXN0IG5vdCBiZSBudWxsIik7Ci0gICAgfQotCi0gICAgLyogVGhhdCdzIGFuIGFtemluZ2x5IGVhc3kgY2FzZSwgYmVjYXVzZSBnZXROYW1lKCkgcmV0dXJucwotICAgICAqIHRoZSBzaWduYXR1cmUuIFRoYXQncyB3aGF0IHdlIHdvdWxkIGhhdmUgbGlrZWQgYW55d2F5LgotICAgICAqLwotICAgIGlmKGNsLmlzQXJyYXkoKSkgewotICAgICAgcmV0dXJuIGdldFR5cGUoY2wuZ2V0TmFtZSgpKTsKLSAgICB9IGVsc2UgaWYoY2wuaXNQcmltaXRpdmUoKSkgewotICAgICAgaWYoY2wgPT0gSW50ZWdlci5UWVBFKSB7Ci0gICAgICAgIHJldHVybiBJTlQ7Ci0gICAgICB9IGVsc2UgaWYoY2wgPT0gVm9pZC5UWVBFKSB7Ci0gICAgICAgIHJldHVybiBWT0lEOwotICAgICAgfSBlbHNlIGlmKGNsID09IERvdWJsZS5UWVBFKSB7Ci0gICAgICAgIHJldHVybiBET1VCTEU7Ci0gICAgICB9IGVsc2UgaWYoY2wgPT0gRmxvYXQuVFlQRSkgewotICAgICAgICByZXR1cm4gRkxPQVQ7Ci0gICAgICB9IGVsc2UgaWYoY2wgPT0gQm9vbGVhbi5UWVBFKSB7Ci0gICAgICAgIHJldHVybiBCT09MRUFOOwotICAgICAgfSBlbHNlIGlmKGNsID09IEJ5dGUuVFlQRSkgewotICAgICAgICByZXR1cm4gQllURTsKLSAgICAgIH0gZWxzZSBpZihjbCA9PSBTaG9ydC5UWVBFKSB7Ci0gICAgICAgIHJldHVybiBTSE9SVDsKLSAgICAgIH0gZWxzZSBpZihjbCA9PSBCeXRlLlRZUEUpIHsKLSAgICAgICAgcmV0dXJuIEJZVEU7Ci0gICAgICB9IGVsc2UgaWYoY2wgPT0gTG9uZy5UWVBFKSB7Ci0gICAgICAgIHJldHVybiBMT05HOwotICAgICAgfSBlbHNlIGlmKGNsID09IENoYXJhY3Rlci5UWVBFKSB7Ci0gICAgICAgIHJldHVybiBDSEFSOwotICAgICAgfSBlbHNlIHsKLSAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiT29vcHMsIHdoYXQgcHJpbWl0aXZlIHR5cGUgaXMgIiArIGNsKTsKLSAgICAgIH0KLSAgICB9IGVsc2UgeyAvLyAiUmVhbCIgY2xhc3MKLSAgICAgIHJldHVybiBuZXcgT2JqZWN0VHlwZShjbC5nZXROYW1lKCkpOwotICAgIH0KLSAgfQotCi0gIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldFNpZ25hdHVyZShqYXZhLmxhbmcucmVmbGVjdC5NZXRob2QgbWV0aCkgewotICAgIFN0cmluZ0J1ZmZlciBzYiA9IG5ldyBTdHJpbmdCdWZmZXIoIigiKTsKLSAgICBDbGFzc1tdIHBhcmFtcyA9IG1ldGguZ2V0UGFyYW1ldGVyVHlwZXMoKTsgLy8gYXZvaWQgY2xvbmUKLQotICAgIGZvcihpbnQgaiA9IDA7IGogPCBwYXJhbXMubGVuZ3RoOyBqKyspIHsKLSAgICAgIHNiLmFwcGVuZChnZXRUeXBlKHBhcmFtc1tqXSkuZ2V0U2lnbmF0dXJlKCkpOwotICAgIH0KLQotICAgIHNiLmFwcGVuZCgiKSIpOwotICAgIHNiLmFwcGVuZChnZXRUeXBlKG1ldGguZ2V0UmV0dXJuVHlwZSgpKS5nZXRTaWduYXR1cmUoKSk7Ci0gICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL1R5cGVkSW5zdHJ1Y3Rpb24uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL1R5cGVkSW5zdHJ1Y3Rpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDlkZGFlNC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9UeXBlZEluc3RydWN0aW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw2OSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIEdldCB0aGUgdHlwZSBhc3NvY2lhdGVkIHdpdGggYW4gaW5zdHJ1Y3Rpb24sIGludCBmb3IgSUxPQUQsIG9yIHRoZSB0eXBlCi0gKiBvZiB0aGUgZmllbGQgb2YgYSBQVVRGSUVMRCBpbnN0cnVjdGlvbiwgZS5nLi4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgaW50ZXJmYWNlIFR5cGVkSW5zdHJ1Y3Rpb24gewotICBwdWJsaWMgVHlwZSBnZXRUeXBlKENvbnN0YW50UG9vbEdlbiBjcGcpOwotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvVW5jb25kaXRpb25hbEJyYW5jaC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2dlbmVyaWMvVW5jb25kaXRpb25hbEJyYW5jaC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjMzEwYTQ2Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL1VuY29uZGl0aW9uYWxCcmFuY2guamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDY5ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWM7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8qKgotICogRGVub3RlcyBhbiBpbnN0cnVjdGlvbiB0byBwZXJmb3JtIGFuIHVuY29uZGl0aW9uYWwgYnJhbmNoLCBpLmUuLCBHT1RPLCBKU1IuCi0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLQotICogQHNlZSBHT1RPCi0gKiBAc2VlIEpTUgotICovCi1wdWJsaWMgaW50ZXJmYWNlIFVuY29uZGl0aW9uYWxCcmFuY2gge30KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL1ZhcmlhYmxlTGVuZ3RoSW5zdHJ1Y3Rpb24uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL1ZhcmlhYmxlTGVuZ3RoSW5zdHJ1Y3Rpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOTAyNmExNi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9WYXJpYWJsZUxlbmd0aEluc3RydWN0aW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3MiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIERlbm90ZXMgYW4gaW5zdHJ1Y3Rpb24gdG8gYmUgYSB2YXJpYWJsZSBsZW5ndGggaW5zdHJ1Y3Rpb24sIHN1Y2ggYXMKLSAqIEdPVE8sIEpTUiwgTE9PS1VQU1dJVENIIGFuZCBUQUJMRVNXSVRDSC4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotCi0gKiBAc2VlIEdPVE8KLSAqIEBzZWUgSlNSCi0gKiBAc2VlIExPT0tVUFNXSVRDSAotICogQHNlZSBUQUJMRVNXSVRDSAotICovCi1wdWJsaWMgaW50ZXJmYWNlIFZhcmlhYmxlTGVuZ3RoSW5zdHJ1Y3Rpb24ge30KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL1Zpc2l0b3IuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL1Zpc2l0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOTdjNDQ2OS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9WaXNpdG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyNTAgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYzsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotLyoqCi0gKiBJbnRlcmZhY2UgaW1wbGVtZW50aW5nIHRoZSBWaXNpdG9yIHBhdHRlcm4gcHJvZ3JhbW1pbmcgc3R5bGUuCi0gKiBJLmUuLCBhIGNsYXNzIHRoYXQgaW1wbGVtZW50cyB0aGlzIGludGVyZmFjZSBjYW4gaGFuZGxlIGFsbCB0eXBlcyBvZgotICogaW5zdHJ1Y3Rpb25zIHdpdGggdGhlIHByb3Blcmx5IHR5cGVkIG1ldGhvZHMganVzdCBieSBjYWxsaW5nIHRoZSBhY2NlcHQoKQotICogbWV0aG9kLgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgVmlzaXRvciB7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0U3RhY2tJbnN0cnVjdGlvbihTdGFja0luc3RydWN0aW9uIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0TG9jYWxWYXJpYWJsZUluc3RydWN0aW9uKExvY2FsVmFyaWFibGVJbnN0cnVjdGlvbiBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdEJyYW5jaEluc3RydWN0aW9uKEJyYW5jaEluc3RydWN0aW9uIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0TG9hZENsYXNzKExvYWRDbGFzcyBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdEZpZWxkSW5zdHJ1Y3Rpb24oRmllbGRJbnN0cnVjdGlvbiBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdElmSW5zdHJ1Y3Rpb24oSWZJbnN0cnVjdGlvbiBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdENvbnZlcnNpb25JbnN0cnVjdGlvbihDb252ZXJzaW9uSW5zdHJ1Y3Rpb24gb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRQb3BJbnN0cnVjdGlvbihQb3BJbnN0cnVjdGlvbiBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdFN0b3JlSW5zdHJ1Y3Rpb24oU3RvcmVJbnN0cnVjdGlvbiBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdFR5cGVkSW5zdHJ1Y3Rpb24oVHlwZWRJbnN0cnVjdGlvbiBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdFNlbGVjdChTZWxlY3Qgb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRKc3JJbnN0cnVjdGlvbihKc3JJbnN0cnVjdGlvbiBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdEdvdG9JbnN0cnVjdGlvbihHb3RvSW5zdHJ1Y3Rpb24gb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRVbmNvbmRpdGlvbmFsQnJhbmNoKFVuY29uZGl0aW9uYWxCcmFuY2ggb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRQdXNoSW5zdHJ1Y3Rpb24oUHVzaEluc3RydWN0aW9uIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0QXJpdGhtZXRpY0luc3RydWN0aW9uKEFyaXRobWV0aWNJbnN0cnVjdGlvbiBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdENQSW5zdHJ1Y3Rpb24oQ1BJbnN0cnVjdGlvbiBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdEludm9rZUluc3RydWN0aW9uKEludm9rZUluc3RydWN0aW9uIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0QXJyYXlJbnN0cnVjdGlvbihBcnJheUluc3RydWN0aW9uIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0QWxsb2NhdGlvbkluc3RydWN0aW9uKEFsbG9jYXRpb25JbnN0cnVjdGlvbiBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdFJldHVybkluc3RydWN0aW9uKFJldHVybkluc3RydWN0aW9uIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0RmllbGRPck1ldGhvZChGaWVsZE9yTWV0aG9kIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0Q29uc3RhbnRQdXNoSW5zdHJ1Y3Rpb24oQ29uc3RhbnRQdXNoSW5zdHJ1Y3Rpb24gb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRFeGNlcHRpb25UaHJvd2VyKEV4Y2VwdGlvblRocm93ZXIgb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRMb2FkSW5zdHJ1Y3Rpb24oTG9hZEluc3RydWN0aW9uIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0VmFyaWFibGVMZW5ndGhJbnN0cnVjdGlvbihWYXJpYWJsZUxlbmd0aEluc3RydWN0aW9uIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0U3RhY2tQcm9kdWNlcihTdGFja1Byb2R1Y2VyIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0U3RhY2tDb25zdW1lcihTdGFja0NvbnN1bWVyIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0QUNPTlNUX05VTEwoQUNPTlNUX05VTEwgb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRHRVRTVEFUSUMoR0VUU1RBVElDIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0SUZfSUNNUExUKElGX0lDTVBMVCBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdE1PTklUT1JFWElUKE1PTklUT1JFWElUIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0SUZMVChJRkxUIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0TFNUT1JFKExTVE9SRSBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdFBPUDIoUE9QMiBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdEJBU1RPUkUoQkFTVE9SRSBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdElTVE9SRShJU1RPUkUgb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRDSEVDS0NBU1QoQ0hFQ0tDQVNUIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0RkNNUEcoRkNNUEcgb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRJMkYoSTJGIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0QVRIUk9XKEFUSFJPVyBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdERDTVBMKERDTVBMIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0QVJSQVlMRU5HVEgoQVJSQVlMRU5HVEggb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXREVVAoRFVQIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0SU5WT0tFU1RBVElDKElOVk9LRVNUQVRJQyBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdExDT05TVChMQ09OU1Qgb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXREUkVNKERSRU0gb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRJRkdFKElGR0Ugb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRDQUxPQUQoQ0FMT0FEIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0TEFTVE9SRShMQVNUT1JFIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0STJEKEkyRCBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdERBREQoREFERCBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdElOVk9LRVNQRUNJQUwoSU5WT0tFU1BFQ0lBTCBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdElBTkQoSUFORCBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdFBVVEZJRUxEKFBVVEZJRUxEIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0SUxPQUQoSUxPQUQgb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRETE9BRChETE9BRCBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdERDT05TVChEQ09OU1Qgb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRORVcoTkVXIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0SUZOVUxMKElGTlVMTCBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdExTVUIoTFNVQiBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdEwySShMMkkgb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRJU0hSKElTSFIgb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRUQUJMRVNXSVRDSChUQUJMRVNXSVRDSCBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdElJTkMoSUlOQyBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdERSRVRVUk4oRFJFVFVSTiBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdEZTVE9SRShGU1RPUkUgb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXREQVNUT1JFKERBU1RPUkUgb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRJQUxPQUQoSUFMT0FEIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0RERJVihERElWIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0SUZfSUNNUEdFKElGX0lDTVBHRSBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdExBTkQoTEFORCBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdElESVYoSURJViBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdExPUihMT1Igb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRDQVNUT1JFKENBU1RPUkUgb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRGUkVNKEZSRU0gb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRMREMoTERDIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0QklQVVNIKEJJUFVTSCBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdERTVE9SRShEU1RPUkUgb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRGMkwoRjJMIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0Rk1VTChGTVVMIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0TExPQUQoTExPQUQgb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRKU1IoSlNSIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0RlNVQihGU1VCIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0U0FTVE9SRShTQVNUT1JFIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0QUxPQUQoQUxPQUQgb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXREVVAyX1gyKERVUDJfWDIgb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRSRVRVUk4oUkVUVVJOIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0REFMT0FEKERBTE9BRCBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdFNJUFVTSChTSVBVU0ggb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXREU1VCKERTVUIgb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRMMkYoTDJGIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0SUZfSUNNUEdUKElGX0lDTVBHVCBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdEYyRChGMkQgb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRJMkwoSTJMIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0SUZfQUNNUE5FKElGX0FDTVBORSBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdFBPUChQT1Agb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRJMlMoSTJTIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0SUZFUShJRkVRIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0U1dBUChTV0FQIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0SU9SKElPUiBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdElSRU0oSVJFTSBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdElBU1RPUkUoSUFTVE9SRSBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdE5FV0FSUkFZKE5FV0FSUkFZIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0SU5WT0tFSU5URVJGQUNFKElOVk9LRUlOVEVSRkFDRSBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdElORUcoSU5FRyBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdExDTVAoTENNUCBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdEpTUl9XKEpTUl9XIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0TVVMVElBTkVXQVJSQVkoTVVMVElBTkVXQVJSQVkgb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXREVVBfWDIoRFVQX1gyIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0U0FMT0FEKFNBTE9BRCBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdElGTk9OTlVMTChJRk5PTk5VTEwgb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRETVVMKERNVUwgb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRJRk5FKElGTkUgb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRJRl9JQ01QTEUoSUZfSUNNUExFIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0TERDMl9XKExEQzJfVyBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdEdFVEZJRUxEKEdFVEZJRUxEIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0TEFERChMQUREIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0Tk9QKE5PUCBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdEZBTE9BRChGQUxPQUQgb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRJTlNUQU5DRU9GKElOU1RBTkNFT0Ygb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRJRkxFKElGTEUgb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRMWE9SKExYT1Igb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRMUkVUVVJOKExSRVRVUk4gb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRGQ09OU1QoRkNPTlNUIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0SVVTSFIoSVVTSFIgb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRCQUxPQUQoQkFMT0FEIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0RFVQMihEVVAyIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0SUZfQUNNUEVRKElGX0FDTVBFUSBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdElNUERFUDEoSU1QREVQMSBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdE1PTklUT1JFTlRFUihNT05JVE9SRU5URVIgb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRMU0hMKExTSEwgb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXREQ01QRyhEQ01QRyBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdEQyTChEMkwgb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRJTVBERVAyKElNUERFUDIgb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRMMkQoTDJEIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0UkVUKFJFVCBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdElGR1QoSUZHVCBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdElYT1IoSVhPUiBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdElOVk9LRVZJUlRVQUwoSU5WT0tFVklSVFVBTCBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdEZBU1RPUkUoRkFTVE9SRSBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdElSRVRVUk4oSVJFVFVSTiBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdElGX0lDTVBORShJRl9JQ01QTkUgb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRGTE9BRChGTE9BRCBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdExESVYoTERJViBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdFBVVFNUQVRJQyhQVVRTVEFUSUMgb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRBQUxPQUQoQUFMT0FEIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0RDJJKEQySSBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdElGX0lDTVBFUShJRl9JQ01QRVEgb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRBQVNUT1JFKEFBU1RPUkUgb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRBUkVUVVJOKEFSRVRVUk4gb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXREVVAyX1gxKERVUDJfWDEgb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRGTkVHKEZORUcgb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRHT1RPX1coR09UT19XIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0RDJGKEQyRiBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdEdPVE8oR09UTyBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdElTVUIoSVNVQiBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdEYySShGMkkgb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRETkVHKERORUcgb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRJQ09OU1QoSUNPTlNUIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0RkRJVihGRElWIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0STJCKEkyQiBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdExORUcoTE5FRyBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdExSRU0oTFJFTSBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdElNVUwoSU1VTCBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdElBREQoSUFERCBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdExTSFIoTFNIUiBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdExPT0tVUFNXSVRDSChMT09LVVBTV0lUQ0ggb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXREVVBfWDEoRFVQX1gxIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0RkNNUEwoRkNNUEwgb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRJMkMoSTJDIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0TE1VTChMTVVMIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0TFVTSFIoTFVTSFIgb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRJU0hMKElTSEwgb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRMQUxPQUQoTEFMT0FEIG9iaik7Ci0gIHB1YmxpYyB2b2lkIHZpc2l0QVNUT1JFKEFTVE9SRSBvYmopOwotICBwdWJsaWMgdm9pZCB2aXNpdEFORVdBUlJBWShBTkVXQVJSQVkgb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRGUkVUVVJOKEZSRVRVUk4gb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRGQUREKEZBREQgb2JqKTsKLSAgcHVibGljIHZvaWQgdmlzaXRCUkVBS1BPSU5UKEJSRUFLUE9JTlQgb2JqKTsKLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL3BhY2thZ2UuaHRtbCBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9nZW5lcmljL3BhY2thZ2UuaHRtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZTM5MTg5Yi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvZ2VuZXJpYy9wYWNrYWdlLmh0bWwKKysrIC9kZXYvbnVsbApAQCAtMSwxNiArMCwwIEBACi08IURPQ1RZUEUgSFRNTCBQVUJMSUMgIi0vL1czQy8vRFREIEhUTUwgMy4yIEZpbmFsLy9FTiI+Ci08aHRtbD4KLTxoZWFkPgotPCEtLQotJElkOiBwYWNrYWdlLmh0bWwsdiAxLjEuMi4xIDIwMDUvMDcvMzEgMjM6NDU6MjcgamVmZnN1dHRvciBFeHAgJAotLS0+Ci08L2hlYWQ+Ci08Ym9keSBiZ2NvbG9yPSJ3aGl0ZSI+Ci08cD4KLVRoaXMgcGFja2FnZSBjb250YWlucyB0aGUgImdlbmVyaWMiIHBhcnQgb2YgdGhlCi08YSBocmVmPSJodHRwOi8vamFrYXJ0YS5hcGFjaGUub3JnL2JjZWwvIj5CeXRlIENvZGUgRW5naW5lZXJpbmcKLUxpYnJhcnk8L2E+LCBpLmUuLCBjbGFzc2VzIHRvIGR5bmFtaWNhbGx5IG1vZGlmeSBjbGFzcyBvYmplY3RzIGFuZAotYnl0ZSBjb2RlIGluc3RydWN0aW9ucy4KLTwvcD4KLTwvYm9keT4KLTwvaHRtbD4KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9wYWNrYWdlLmh0bWwgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvcGFja2FnZS5odG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA5MmRlOTlkLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9wYWNrYWdlLmh0bWwKKysrIC9kZXYvbnVsbApAQCAtMSwxNyArMCwwIEBACi08IURPQ1RZUEUgSFRNTCBQVUJMSUMgIi0vL1czQy8vRFREIEhUTUwgMy4yIEZpbmFsLy9FTiI+Ci08aHRtbD4KLTxoZWFkPgotPCEtLQotJElkOiBwYWNrYWdlLmh0bWwsdiAxLjEuMi4xIDIwMDUvMDcvMzEgMjM6NDY6NTUgamVmZnN1dHRvciBFeHAgJAotLS0+Ci08L2hlYWQ+Ci08Ym9keSBiZ2NvbG9yPSJ3aGl0ZSI+Ci08cD4KLVRoaXMgcGFja2FnZSBjb250YWlucyBiYXNpYyBjbGFzc2VzIGZvciB0aGUKLTxhIGhyZWY9Imh0dHA6Ly9qYWthcnRhLmFwYWNoZS5vcmcvYmNlbC8iPkJ5dGUgQ29kZSBFbmdpbmVlcmluZyBMaWJyYXJ5PC9hPgotIGFuZCBjb25zdGFudHMgZGVmaW5lZCBieSB0aGUKLTxhIGhyZWY9Imh0dHA6Ly93d3cuamF2YXNvZnQuY29tL2RvY3MvYm9va3Mvdm1zcGVjL2luZGV4Lmh0bWwiPgotIEpWTSBzcGVjaWZpY2F0aW9uPC9hPi4KLTwvcD4KLTwvYm9keT4KLTwvaHRtbD4KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC91dGlsL0F0dHJpYnV0ZUhUTUwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC91dGlsL0F0dHJpYnV0ZUhUTUwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggM2NhZmNiYS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvdXRpbC9BdHRyaWJ1dGVIVE1MLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyNTggKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwudXRpbDsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmNsYXNzZmlsZS4qOwotaW1wb3J0IGphdmEuaW8uKjsKLQotLyoqCi0gKiBDb252ZXJ0IGZvdW5kIGF0dHJpYnV0ZXMgaW50byBIVE1MIGZpbGUuCi0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqCi0gKi8KLWZpbmFsIGNsYXNzIEF0dHJpYnV0ZUhUTUwgaW1wbGVtZW50cyBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMgewotICBwcml2YXRlIFN0cmluZyAgICAgICBjbGFzc19uYW1lOyAgICAgLy8gbmFtZSBvZiBjdXJyZW50IGNsYXNzCi0gIHByaXZhdGUgUHJpbnRXcml0ZXIgIGZpbGU7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZmlsZSB0byB3cml0ZSB0bwotICBwcml2YXRlIGludCAgICAgICAgICBhdHRyX2NvdW50ID0gMDsKLSAgcHJpdmF0ZSBDb25zdGFudEhUTUwgY29uc3RhbnRfaHRtbDsKLSAgcHJpdmF0ZSBDb25zdGFudFBvb2wgY29uc3RhbnRfcG9vbDsKLQotICBBdHRyaWJ1dGVIVE1MKFN0cmluZyBkaXIsIFN0cmluZyBjbGFzc19uYW1lLCBDb25zdGFudFBvb2wgY29uc3RhbnRfcG9vbCwKLSAgICAgICAgICAgICAgICBDb25zdGFudEhUTUwgY29uc3RhbnRfaHRtbCkgdGhyb3dzIElPRXhjZXB0aW9uCi0gIHsKLSAgICB0aGlzLmNsYXNzX25hbWUgICAgPSBjbGFzc19uYW1lOwotICAgIHRoaXMuY29uc3RhbnRfcG9vbCA9IGNvbnN0YW50X3Bvb2w7Ci0gICAgdGhpcy5jb25zdGFudF9odG1sID0gY29uc3RhbnRfaHRtbDsKLQotICAgIGZpbGUgPSBuZXcgUHJpbnRXcml0ZXIobmV3IEZpbGVPdXRwdXRTdHJlYW0oZGlyICsgY2xhc3NfbmFtZSArICJfYXR0cmlidXRlcy5odG1sIikpOwotICAgIGZpbGUucHJpbnRsbigiPEhUTUw+PEJPRFkgQkdDT0xPUj1cIiNDMEMwQzBcIj48VEFCTEUgQk9SREVSPTA+Iik7Ci0gIH0KLQotICBwcml2YXRlIGZpbmFsIFN0cmluZyBjb2RlTGluayhpbnQgbGluaywgaW50IG1ldGhvZF9udW1iZXIpIHsKLSAgICByZXR1cm4gIjxBIEhSRUY9XCIiICsgY2xhc3NfbmFtZSArICJfY29kZS5odG1sI2NvZGUiICsKLSAgICAgIG1ldGhvZF9udW1iZXIgKyAiQCIgKyBsaW5rICsgIlwiIFRBUkdFVD1Db2RlPiIgKwotICAgICAgbGluayArICI8L0E+IjsKLSAgfQotCi0gIGZpbmFsIHZvaWQgY2xvc2UoKSB7Ci0gICAgZmlsZS5wcmludGxuKCI8L1RBQkxFPjwvQk9EWT48L0hUTUw+Iik7Ci0gICAgZmlsZS5jbG9zZSgpOwotICB9Ci0KLSAgZmluYWwgdm9pZCB3cml0ZUF0dHJpYnV0ZShBdHRyaWJ1dGUgYXR0cmlidXRlLCBTdHJpbmcgYW5jaG9yKSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgIHdyaXRlQXR0cmlidXRlKGF0dHJpYnV0ZSwgYW5jaG9yLCAwKTsKLSAgfQotCi0gIGZpbmFsIHZvaWQgd3JpdGVBdHRyaWJ1dGUoQXR0cmlidXRlIGF0dHJpYnV0ZSwgU3RyaW5nIGFuY2hvciwgaW50IG1ldGhvZF9udW1iZXIpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgYnl0ZSAgICAgICAgIHRhZyA9IGF0dHJpYnV0ZS5nZXRUYWcoKTsKLSAgICBpbnQgICAgICAgIGluZGV4OwotCi0gICAgaWYodGFnID09IEFUVFJfVU5LTk9XTikgLy8gRG9uJ3Qga25vdyB3aGF0IHRvIGRvIGFib3V0IHRoaXMgb25lCi0gICAgICByZXR1cm47Ci0KLSAgICBhdHRyX2NvdW50Kys7IC8vIEluY3JlbWVudCBudW1iZXIgb2YgYXR0cmlidXRlcyBmb3VuZCBzbyBmYXIKLQotICAgIGlmKGF0dHJfY291bnQgJSAyID09IDApCi0gICAgICBmaWxlLnByaW50KCI8VFIgQkdDT0xPUj1cIiNDMEMwQzBcIj48VEQ+Iik7Ci0gICAgZWxzZQotICAgICAgZmlsZS5wcmludCgiPFRSIEJHQ09MT1I9XCIjQTBBMEEwXCI+PFREPiIpOwotCi0gICAgZmlsZS5wcmludGxuKCI8SDQ+PEEgTkFNRT1cIiIgKyBhbmNob3IgKyAiXCI+IiArIGF0dHJfY291bnQgKyAiICIgKyBBVFRSSUJVVEVfTkFNRVNbdGFnXSArICI8L0E+PC9IND4iKTsKLQotICAgIC8qIEhhbmRsZSBkaWZmZXJlbnQgYXR0cmlidXRlcwotICAgICAqLwotICAgIHN3aXRjaCh0YWcpIHsKLSAgICBjYXNlIEFUVFJfQ09ERToKLSAgICAgIENvZGUgICAgICAgIGMgICAgICAgICAgPSAoQ29kZSlhdHRyaWJ1dGU7Ci0KLSAgICAgIC8vIFNvbWUgZGlyZWN0bHkgcHJpbnRhYmxlIHZhbHVlcwotICAgICAgZmlsZS5wcmludCgiPFVMPjxMST5NYXhpbXVtIHN0YWNrIHNpemUgPSAiICsgYy5nZXRNYXhTdGFjaygpICsKLSAgICAgICAgICAgICAgICAgIjwvTEk+XG48TEk+TnVtYmVyIG9mIGxvY2FsIHZhcmlhYmxlcyA9ICIgKwotICAgICAgICAgICAgICAgICBjLmdldE1heExvY2FscygpICsgIjwvTEk+XG48TEk+PEEgSFJFRj1cIiIgKyBjbGFzc19uYW1lICsKLSAgICAgICAgICAgICAgICAgIl9jb2RlLmh0bWwjbWV0aG9kIiArIG1ldGhvZF9udW1iZXIgKyAiXCIgVEFSR0VUPUNvZGU+Qnl0ZSBjb2RlPC9BPjwvTEk+PC9VTD5cbiIpOwotCi0gICAgICAvLyBHZXQgaGFuZGxlZCBleGNlcHRpb25zIGFuZCBsaXN0IHRoZW0KLSAgICAgIENvZGVFeGNlcHRpb25bXSBjZSAgPSBjLmdldEV4Y2VwdGlvblRhYmxlKCk7Ci0gICAgICBpbnQgICAgICAgICAgICAgbGVuID0gY2UubGVuZ3RoOwotCi0gICAgICBpZihsZW4gPiAwKSB7Ci0gICAgICAgIGZpbGUucHJpbnQoIjxQPjxCPkV4Y2VwdGlvbnMgaGFuZGxlZDwvQj48VUw+Iik7Ci0KLSAgICAgICAgZm9yKGludCBpPTA7IGkgPCBsZW47IGkrKykgewotICAgICAgICAgIGludCBjYXRjaF90eXBlID0gY2VbaV0uZ2V0Q2F0Y2hUeXBlKCk7IC8vIEluZGV4IGluIGNvbnN0YW50IHBvb2wKLQotICAgICAgICAgIGZpbGUucHJpbnQoIjxMST4iKTsKLQotICAgICAgICAgIGlmKGNhdGNoX3R5cGUgIT0gMCkKLSAgICAgICAgICAgIGZpbGUucHJpbnQoY29uc3RhbnRfaHRtbC5yZWZlcmVuY2VDb25zdGFudChjYXRjaF90eXBlKSk7IC8vIENyZWF0ZSBMaW5rIHRvIF9jcC5odG1sCi0gICAgICAgICAgZWxzZQotICAgICAgICAgICAgZmlsZS5wcmludCgiQW55IEV4Y2VwdGlvbiIpOwotCi0gICAgICAgICAgZmlsZS5wcmludCgiPEJSPihSYW5naW5nIGZyb20gbGluZXMgIiArIGNvZGVMaW5rKGNlW2ldLmdldFN0YXJ0UEMoKSwgbWV0aG9kX251bWJlcikgKwotICAgICAgICAgICAgICAgICAgICAgIiB0byAiICsgY29kZUxpbmsoY2VbaV0uZ2V0RW5kUEMoKSwgbWV0aG9kX251bWJlcikgKyAiLCBoYW5kbGVkIGF0IGxpbmUgIiArCi0gICAgICAgICAgICAgICAgICAgICBjb2RlTGluayhjZVtpXS5nZXRIYW5kbGVyUEMoKSwgbWV0aG9kX251bWJlcikgKyAiKTwvTEk+Iik7Ci0gICAgICAgIH0KLSAgICAgICAgZmlsZS5wcmludCgiPC9VTD4iKTsKLSAgICAgIH0KLSAgICAgIGJyZWFrOwotCi0gICAgY2FzZSBBVFRSX0NPTlNUQU5UX1ZBTFVFOgotICAgICAgaW5kZXggPSAoKENvbnN0YW50VmFsdWUpYXR0cmlidXRlKS5nZXRDb25zdGFudFZhbHVlSW5kZXgoKTsKLQotICAgICAgLy8gUmVmZXJlbmNlIF9jcC5odG1sCi0gICAgICBmaWxlLnByaW50KCI8VUw+PExJPjxBIEhSRUY9XCIiICsgY2xhc3NfbmFtZSArICJfY3AuaHRtbCNjcCIgKyBpbmRleCArCi0gICAgICAgICAgICAgICAgICJcIiBUQVJHRVQ9XCJDb25zdGFudFBvb2xcIj5Db25zdGFudCB2YWx1ZSBpbmRleCgiICsgaW5kZXggKyIpPC9BPjwvVUw+XG4iKTsKLSAgICAgIGJyZWFrOwotCi0gICAgY2FzZSBBVFRSX1NPVVJDRV9GSUxFOgotICAgICAgaW5kZXggPSAoKFNvdXJjZUZpbGUpYXR0cmlidXRlKS5nZXRTb3VyY2VGaWxlSW5kZXgoKTsKLQotICAgICAgLy8gUmVmZXJlbmNlIF9jcC5odG1sCi0gICAgICBmaWxlLnByaW50KCI8VUw+PExJPjxBIEhSRUY9XCIiICsgY2xhc3NfbmFtZSArICJfY3AuaHRtbCNjcCIgKyBpbmRleCArCi0gICAgICAgICAgICAgICAgICJcIiBUQVJHRVQ9XCJDb25zdGFudFBvb2xcIj5Tb3VyY2UgZmlsZSBpbmRleCgiICsgaW5kZXggKyIpPC9BPjwvVUw+XG4iKTsKLSAgICAgIGJyZWFrOwotCi0gICAgY2FzZSBBVFRSX0VYQ0VQVElPTlM6Ci0gICAgICAvLyBMaXN0IHRocm93biBleGNlcHRpb25zCi0gICAgICBpbnRbXSBpbmRpY2VzID0gKChFeGNlcHRpb25UYWJsZSlhdHRyaWJ1dGUpLmdldEV4Y2VwdGlvbkluZGV4VGFibGUoKTsKLQotICAgICAgZmlsZS5wcmludCgiPFVMPiIpOwotCi0gICAgICBmb3IoaW50IGk9MDsgaSA8IGluZGljZXMubGVuZ3RoOyBpKyspCi0gICAgICAgIGZpbGUucHJpbnQoIjxMST48QSBIUkVGPVwiIiArIGNsYXNzX25hbWUgKyAiX2NwLmh0bWwjY3AiICsgaW5kaWNlc1tpXSArCi0gICAgICAgICAgICAgICAgICAgIlwiIFRBUkdFVD1cIkNvbnN0YW50UG9vbFwiPkV4Y2VwdGlvbiBjbGFzcyBpbmRleCgiICsgaW5kaWNlc1tpXSArICIpPC9BPlxuIik7Ci0KLSAgICAgIGZpbGUucHJpbnQoIjwvVUw+XG4iKTsKLSAgICAgIGJyZWFrOwotCi0gICAgY2FzZSBBVFRSX0xJTkVfTlVNQkVSX1RBQkxFOgotICAgICAgTGluZU51bWJlcltdIGxpbmVfbnVtYmVycyA9KChMaW5lTnVtYmVyVGFibGUpYXR0cmlidXRlKS5nZXRMaW5lTnVtYmVyVGFibGUoKTsKLQotICAgICAgLy8gTGlzdCBsaW5lIG51bWJlciBwYWlycwotICAgICAgZmlsZS5wcmludCgiPFA+Iik7Ci0KLSAgICAgIGZvcihpbnQgaT0wOyBpIDwgbGluZV9udW1iZXJzLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgIGZpbGUucHJpbnQoIigiICsgbGluZV9udW1iZXJzW2ldLmdldFN0YXJ0UEMoKSArICIsJm5ic3A7IiArIGxpbmVfbnVtYmVyc1tpXS5nZXRMaW5lTnVtYmVyKCkgKyAiKSIpOwotCi0gICAgICAgIGlmKGkgPCBsaW5lX251bWJlcnMubGVuZ3RoIC0gMSkKLSAgICAgICAgICBmaWxlLnByaW50KCIsICIpOyAvLyBicmVha2FibGUKLSAgICAgIH0KLSAgICAgIGJyZWFrOwotCi0gICAgY2FzZSBBVFRSX0xPQ0FMX1ZBUklBQkxFX1RBQkxFOgotICAgICAgTG9jYWxWYXJpYWJsZVtdIHZhcnMgPSAoKExvY2FsVmFyaWFibGVUYWJsZSlhdHRyaWJ1dGUpLmdldExvY2FsVmFyaWFibGVUYWJsZSgpOwotCi0gICAgICAvLyBMaXN0IG5hbWUsIHJhbmdlIGFuZCB0eXBlCi0gICAgICBmaWxlLnByaW50KCI8VUw+Iik7Ci0KLSAgICAgIGZvcihpbnQgaT0wOyBpIDwgdmFycy5sZW5ndGg7IGkrKykgewotICAgICAgICBpbmRleCA9IHZhcnNbaV0uZ2V0U2lnbmF0dXJlSW5kZXgoKTsKLSAgICAgICAgU3RyaW5nIHNpZ25hdHVyZSA9ICgoQ29uc3RhbnRVdGY4KWNvbnN0YW50X3Bvb2wuZ2V0Q29uc3RhbnQoaW5kZXgsIENPTlNUQU5UX1V0ZjgpKS5nZXRCeXRlcygpOwotICAgICAgICBzaWduYXR1cmUgPSBVdGlsaXR5LnNpZ25hdHVyZVRvU3RyaW5nKHNpZ25hdHVyZSwgZmFsc2UpOwotICAgICAgICBpbnQgIHN0YXJ0ID0gdmFyc1tpXS5nZXRTdGFydFBDKCk7Ci0gICAgICAgIGludCAgZW5kICAgPSAoc3RhcnQgKyB2YXJzW2ldLmdldExlbmd0aCgpKTsKLQotICAgICAgICBmaWxlLnByaW50bG4oIjxMST4iICsgQ2xhc3MySFRNTC5yZWZlcmVuY2VUeXBlKHNpZ25hdHVyZSkgKwotICAgICAgICAgICAgICAgICAgICAgIiZuYnNwOzxCPiIgKyB2YXJzW2ldLmdldE5hbWUoKSArICI8L0I+IGluIHNsb3QgJSIgKyB2YXJzW2ldLmdldEluZGV4KCkgKwotICAgICAgICAgICAgICAgICAgICAgIjxCUj5WYWxpZCBmcm9tIGxpbmVzICIgKwotICAgICAgICAgICAgICAgICAgICAgIjxBIEhSRUY9XCIiICsgY2xhc3NfbmFtZSArICJfY29kZS5odG1sI2NvZGUiICsgbWV0aG9kX251bWJlciArICJAIiArIHN0YXJ0ICsgIlwiIFRBUkdFVD1Db2RlPiIgKwotICAgICAgICAgICAgICAgICAgICAgc3RhcnQgKyAiPC9BPiB0byAiICsKLSAgICAgICAgICAgICAgICAgICAgICI8QSBIUkVGPVwiIiArIGNsYXNzX25hbWUgKyAiX2NvZGUuaHRtbCNjb2RlIiArIG1ldGhvZF9udW1iZXIgKyAiQCIgKyBlbmQgKyAiXCIgVEFSR0VUPUNvZGU+IiArCi0gICAgICAgICAgICAgICAgICAgICBlbmQgKyAiPC9BPjwvTEk+Iik7Ci0gICAgICB9Ci0gICAgICBmaWxlLnByaW50KCI8L1VMPlxuIik7Ci0KLSAgICAgIGJyZWFrOwotCi0gICAgY2FzZSBBVFRSX0lOTkVSX0NMQVNTRVM6Ci0gICAgICBJbm5lckNsYXNzW10gY2xhc3NlcyA9ICgoSW5uZXJDbGFzc2VzKWF0dHJpYnV0ZSkuZ2V0SW5uZXJDbGFzc2VzKCk7Ci0KLSAgICAgIC8vIExpc3QgaW5uZXIgY2xhc3NlcwotICAgICAgZmlsZS5wcmludCgiPFVMPiIpOwotCi0gICAgICBmb3IoaW50IGk9MDsgaSA8IGNsYXNzZXMubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgU3RyaW5nIG5hbWUsIGFjY2VzczsKLQotICAgICAgICBpbmRleCA9IGNsYXNzZXNbaV0uZ2V0SW5uZXJOYW1lSW5kZXgoKTsKLSAgICAgICAgaWYoaW5kZXggPiAwKQotICAgICAgICAgIG5hbWUgPSgoQ29uc3RhbnRVdGY4KWNvbnN0YW50X3Bvb2wuZ2V0Q29uc3RhbnQoaW5kZXgsIENPTlNUQU5UX1V0ZjgpKS5nZXRCeXRlcygpOwotICAgICAgICBlbHNlCi0gICAgICAgICAgbmFtZSA9ICImbHQ7YW5vbnltb3VzJmd0OyI7Ci0KLSAgICAgICAgYWNjZXNzID0gVXRpbGl0eS5hY2Nlc3NUb1N0cmluZyhjbGFzc2VzW2ldLmdldElubmVyQWNjZXNzRmxhZ3MoKSk7Ci0KLSAgICAgICAgZmlsZS5wcmludCgiPExJPjxGT05UIENPTE9SPVwiI0ZGMDAwMFwiPiIgKyBhY2Nlc3MgKyAiPC9GT05UPiAiKwotICAgICAgICAgICAgICAgICAgIGNvbnN0YW50X2h0bWwucmVmZXJlbmNlQ29uc3RhbnQoY2xhc3Nlc1tpXS5nZXRJbm5lckNsYXNzSW5kZXgoKSkgKwotICAgICAgICAgICAgICAgICAgICIgaW4mbmJzcDtjbGFzcyAiICsKLSAgICAgICAgICAgICAgICAgICBjb25zdGFudF9odG1sLnJlZmVyZW5jZUNvbnN0YW50KGNsYXNzZXNbaV0uZ2V0T3V0ZXJDbGFzc0luZGV4KCkpICsKLSAgICAgICAgICAgICAgICAgICAiIG5hbWVkICIgKyBuYW1lICsgIjwvTEk+XG4iKTsKLSAgICAgIH0KLQotICAgICAgZmlsZS5wcmludCgiPC9VTD5cbiIpOwotICAgICAgYnJlYWs7Ci0KLSAgICBkZWZhdWx0OiAvLyBTdWNoIGFzIFVua25vd24gYXR0cmlidXRlIG9yIERlcHJlY2F0ZWQKLSAgICAgIGZpbGUucHJpbnQoIjxQPiIgKyBhdHRyaWJ1dGUudG9TdHJpbmcoKSk7Ci0gICAgfQotCi0gICAgZmlsZS5wcmludGxuKCI8L1REPjwvVFI+Iik7Ci0gICAgZmlsZS5mbHVzaCgpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvdXRpbC9CQ0VMRmFjdG9yeS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL3V0aWwvQkNFTEZhY3RvcnkuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYTNiMjU0My4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvdXRpbC9CQ0VMRmFjdG9yeS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzYwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLnV0aWw7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLio7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuY2xhc3NmaWxlLlV0aWxpdHk7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzOwotaW1wb3J0IGphdmEuaW8uUHJpbnRXcml0ZXI7Ci1pbXBvcnQgamF2YS51dGlsLio7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAyIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8qKgotICogRmFjdG9yeSBjcmVhdGVzIGlsLmFwcGVuZCgpIHN0YXRlbWVudHMsIGFuZCBzZXRzIGluc3RydWN0aW9uIHRhcmdldHMuCi0gKiBBIGhlbHBlciBjbGFzcyBmb3IgQkNFTGlmaWVyLgotICoKLSAqIEBzZWUgQkNFTGlmaWVyCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1jbGFzcyBCQ0VMRmFjdG9yeSBleHRlbmRzIEVtcHR5VmlzaXRvciB7Ci0gIHByaXZhdGUgTWV0aG9kR2VuICAgICAgIF9tZzsKLSAgcHJpdmF0ZSBQcmludFdyaXRlciAgICAgX291dDsKLSAgcHJpdmF0ZSBDb25zdGFudFBvb2xHZW4gX2NwOwotCi0gIEJDRUxGYWN0b3J5KE1ldGhvZEdlbiBtZywgUHJpbnRXcml0ZXIgb3V0KSB7Ci0gICAgX21nICA9IG1nOwotICAgIF9jcCAgPSBtZy5nZXRDb25zdGFudFBvb2woKTsKLSAgICBfb3V0ID0gb3V0OwotICB9Ci0KLSAgcHJpdmF0ZSBIYXNoTWFwIGJyYW5jaF9tYXAgPSBuZXcgSGFzaE1hcCgpOyAvLyBNYXA8SW5zdHJ1Y3Rpb24sIEluc3RydWN0aW9uSGFuZGxlPgotCi0gIHB1YmxpYyB2b2lkIHN0YXJ0KCkgewotICAgIGlmKCFfbWcuaXNBYnN0cmFjdCgpICYmICFfbWcuaXNOYXRpdmUoKSkgewotICAgICAgZm9yKEluc3RydWN0aW9uSGFuZGxlIGloID0gX21nLmdldEluc3RydWN0aW9uTGlzdCgpLmdldFN0YXJ0KCk7Ci0gICAgICAgICAgaWggIT0gbnVsbDsgaWggPSBpaC5nZXROZXh0KCkpIHsKLSAgICAgICAgSW5zdHJ1Y3Rpb24gaSA9IGloLmdldEluc3RydWN0aW9uKCk7Ci0KLSAgICAgICAgaWYoaSBpbnN0YW5jZW9mIEJyYW5jaEluc3RydWN0aW9uKSB7Ci0gICAgICAgICAgYnJhbmNoX21hcC5wdXQoaSwgaWgpOyAvLyBtZW1vcml6ZSBjb250YWluZXIKLSAgICAgICAgfQotCi0gICAgICAgIGlmKGloLmhhc1RhcmdldGVycygpKSB7Ci0gICAgICAgICAgaWYoaSBpbnN0YW5jZW9mIEJyYW5jaEluc3RydWN0aW9uKSB7Ci0gICAgICAgICAgICBfb3V0LnByaW50bG4oIiAgICBJbnN0cnVjdGlvbkhhbmRsZSBpaF8iICsgaWguZ2V0UG9zaXRpb24oKSArICI7Iik7Ci0gICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIF9vdXQucHJpbnQoIiAgICBJbnN0cnVjdGlvbkhhbmRsZSBpaF8iICsgaWguZ2V0UG9zaXRpb24oKSArICIgPSAiKTsKLSAgICAgICAgICB9Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgX291dC5wcmludCgiICAgICIpOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYoIXZpc2l0SW5zdHJ1Y3Rpb24oaSkpCi0gICAgICAgICAgaS5hY2NlcHQodGhpcyk7Ci0gICAgICB9Ci0KLSAgICAgIHVwZGF0ZUJyYW5jaFRhcmdldHMoKTsKLSAgICAgIHVwZGF0ZUV4Y2VwdGlvbkhhbmRsZXJzKCk7Ci0gICAgfQotICB9Ci0KLSAgcHJpdmF0ZSBib29sZWFuIHZpc2l0SW5zdHJ1Y3Rpb24oSW5zdHJ1Y3Rpb24gaSkgewotICAgIHNob3J0IG9wY29kZSA9IGkuZ2V0T3Bjb2RlKCk7Ci0KLSAgICBpZigoSW5zdHJ1Y3Rpb25Db25zdGFudHMuSU5TVFJVQ1RJT05TW29wY29kZV0gIT0gbnVsbCkgJiYKLSAgICAgICAhKGkgaW5zdGFuY2VvZiBDb25zdGFudFB1c2hJbnN0cnVjdGlvbikgJiYKLSAgICAgICAhKGkgaW5zdGFuY2VvZiBSZXR1cm5JbnN0cnVjdGlvbikpIHsgLy8gSGFuZGxlZCBiZWxvdwotICAgICAgX291dC5wcmludGxuKCJpbC5hcHBlbmQoSW5zdHJ1Y3Rpb25Db25zdGFudHMuIiArCi0gICAgICAgICAgICAgICAgICAgaS5nZXROYW1lKCkudG9VcHBlckNhc2UoKSArICIpOyIpOwotICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotCi0gICAgcmV0dXJuIGZhbHNlOwotICB9Ci0KLSAgcHVibGljIHZvaWQgdmlzaXRMb2NhbFZhcmlhYmxlSW5zdHJ1Y3Rpb24oTG9jYWxWYXJpYWJsZUluc3RydWN0aW9uIGkpIHsKLSAgICBzaG9ydCAgb3Bjb2RlID0gaS5nZXRPcGNvZGUoKTsKLSAgICBUeXBlICAgdHlwZSAgID0gaS5nZXRUeXBlKF9jcCk7Ci0KLSAgICBpZihvcGNvZGUgPT0gQ29uc3RhbnRzLklJTkMpIHsKLSAgICAgIF9vdXQucHJpbnRsbigiaWwuYXBwZW5kKG5ldyBJSU5DKCIgKyBpLmdldEluZGV4KCkgKyAiLCAiICsKLSAgICAgICAgICAgICAgICAgICAoKElJTkMpaSkuZ2V0SW5jcmVtZW50KCkgKyAiKSk7Iik7Ci0gICAgfSBlbHNlIHsKLSAgICAgIFN0cmluZyBraW5kICAgPSAob3Bjb2RlIDwgQ29uc3RhbnRzLklTVE9SRSk/ICJMb2FkIiA6ICJTdG9yZSI7Ci0gICAgICBfb3V0LnByaW50bG4oImlsLmFwcGVuZChfZmFjdG9yeS5jcmVhdGUiICsga2luZCArICIoIiArCi0gICAgICAgICAgICAgICAgICAgQkNFTGlmaWVyLnByaW50VHlwZSh0eXBlKSArICIsICIgKwotICAgICAgICAgICAgICAgICAgIGkuZ2V0SW5kZXgoKSArICIpKTsiKTsKLSAgICB9Ci0gIH0KLQotICBwdWJsaWMgdm9pZCB2aXNpdEFycmF5SW5zdHJ1Y3Rpb24oQXJyYXlJbnN0cnVjdGlvbiBpKSB7Ci0gICAgc2hvcnQgIG9wY29kZSA9IGkuZ2V0T3Bjb2RlKCk7Ci0gICAgVHlwZSAgIHR5cGUgICA9IGkuZ2V0VHlwZShfY3ApOwotICAgIFN0cmluZyBraW5kICAgPSAob3Bjb2RlIDwgQ29uc3RhbnRzLklBU1RPUkUpPyAiTG9hZCIgOiAiU3RvcmUiOwotCi0gICAgX291dC5wcmludGxuKCJpbC5hcHBlbmQoX2ZhY3RvcnkuY3JlYXRlQXJyYXkiICsga2luZCArICIoIiArCi0gICAgICAgICAgICAgICAgIEJDRUxpZmllci5wcmludFR5cGUodHlwZSkgKyAiKSk7Iik7Ci0gIH0KLQotICBwdWJsaWMgdm9pZCB2aXNpdEZpZWxkSW5zdHJ1Y3Rpb24oRmllbGRJbnN0cnVjdGlvbiBpKSB7Ci0gICAgc2hvcnQgIG9wY29kZSA9IGkuZ2V0T3Bjb2RlKCk7Ci0KLSAgICBTdHJpbmcgY2xhc3NfbmFtZSA9IGkuZ2V0Q2xhc3NOYW1lKF9jcCk7Ci0gICAgU3RyaW5nIGZpZWxkX25hbWUgPSBpLmdldEZpZWxkTmFtZShfY3ApOwotICAgIFR5cGUgICB0eXBlICAgICAgID0gaS5nZXRGaWVsZFR5cGUoX2NwKTsKLQotICAgIF9vdXQucHJpbnRsbigiaWwuYXBwZW5kKF9mYWN0b3J5LmNyZWF0ZUZpZWxkQWNjZXNzKFwiIiArCi0gICAgICAgICAgICAgICAgIGNsYXNzX25hbWUgKyAiXCIsIFwiIiArIGZpZWxkX25hbWUgKyAiXCIsICIgKwotICAgICAgICAgICAgICAgICBCQ0VMaWZpZXIucHJpbnRUeXBlKHR5cGUpICsgIiwgIiArCi0gICAgICAgICAgICAgICAgICJDb25zdGFudHMuIiArIENvbnN0YW50cy5PUENPREVfTkFNRVNbb3Bjb2RlXS50b1VwcGVyQ2FzZSgpICsKLSAgICAgICAgICAgICAgICAgIikpOyIpOwotICB9Ci0KLSAgcHVibGljIHZvaWQgdmlzaXRJbnZva2VJbnN0cnVjdGlvbihJbnZva2VJbnN0cnVjdGlvbiBpKSB7Ci0gICAgc2hvcnQgIG9wY29kZSAgICAgID0gaS5nZXRPcGNvZGUoKTsKLSAgICBTdHJpbmcgY2xhc3NfbmFtZSAgPSBpLmdldENsYXNzTmFtZShfY3ApOwotICAgIFN0cmluZyBtZXRob2RfbmFtZSA9IGkuZ2V0TWV0aG9kTmFtZShfY3ApOwotICAgIFR5cGUgICB0eXBlICAgICAgICA9IGkuZ2V0UmV0dXJuVHlwZShfY3ApOwotICAgIFR5cGVbXSBhcmdfdHlwZXMgICA9IGkuZ2V0QXJndW1lbnRUeXBlcyhfY3ApOwotCi0gICAgX291dC5wcmludGxuKCJpbC5hcHBlbmQoX2ZhY3RvcnkuY3JlYXRlSW52b2tlKFwiIiArCi0gICAgICAgICAgICAgICAgIGNsYXNzX25hbWUgKyAiXCIsIFwiIiArIG1ldGhvZF9uYW1lICsgIlwiLCAiICsKLSAgICAgICAgICAgICAgICAgQkNFTGlmaWVyLnByaW50VHlwZSh0eXBlKSArICIsICIgKwotICAgICAgICAgICAgICAgICBCQ0VMaWZpZXIucHJpbnRBcmd1bWVudFR5cGVzKGFyZ190eXBlcykgKyAiLCAiICsKLSAgICAgICAgICAgICAgICAgIkNvbnN0YW50cy4iICsgQ29uc3RhbnRzLk9QQ09ERV9OQU1FU1tvcGNvZGVdLnRvVXBwZXJDYXNlKCkgKwotICAgICAgICAgICAgICAgICAiKSk7Iik7Ci0gIH0KLQotICBwdWJsaWMgdm9pZCB2aXNpdEFsbG9jYXRpb25JbnN0cnVjdGlvbihBbGxvY2F0aW9uSW5zdHJ1Y3Rpb24gaSkgewotICAgIFR5cGUgdHlwZTsKLQotICAgIGlmKGkgaW5zdGFuY2VvZiBDUEluc3RydWN0aW9uKSB7Ci0gICAgICB0eXBlID0gKChDUEluc3RydWN0aW9uKWkpLmdldFR5cGUoX2NwKTsKLSAgICB9IGVsc2UgewotICAgICAgdHlwZSA9ICgoTkVXQVJSQVkpaSkuZ2V0VHlwZSgpOwotICAgIH0KLQotICAgIHNob3J0IG9wY29kZSA9ICgoSW5zdHJ1Y3Rpb24paSkuZ2V0T3Bjb2RlKCk7Ci0gICAgaW50ICAgZGltICAgID0gMTsKLQotICAgIHN3aXRjaChvcGNvZGUpIHsKLSAgICBjYXNlIENvbnN0YW50cy5ORVc6Ci0gICAgICBfb3V0LnByaW50bG4oImlsLmFwcGVuZChfZmFjdG9yeS5jcmVhdGVOZXcoXCIiICsKLSAgICAgICAgICAgICAgICAgICAoKE9iamVjdFR5cGUpdHlwZSkuZ2V0Q2xhc3NOYW1lKCkgKyAiXCIpKTsiKTsKLSAgICAgIGJyZWFrOwotCi0gICAgY2FzZSBDb25zdGFudHMuTVVMVElBTkVXQVJSQVk6Ci0gICAgICBkaW0gPSAoKE1VTFRJQU5FV0FSUkFZKWkpLmdldERpbWVuc2lvbnMoKTsKLQotICAgIGNhc2UgQ29uc3RhbnRzLkFORVdBUlJBWToKLSAgICBjYXNlIENvbnN0YW50cy5ORVdBUlJBWToKLSAgICAgIF9vdXQucHJpbnRsbigiaWwuYXBwZW5kKF9mYWN0b3J5LmNyZWF0ZU5ld0FycmF5KCIgKwotICAgICAgICAgICAgICAgICAgIEJDRUxpZmllci5wcmludFR5cGUodHlwZSkgKyAiLCAoc2hvcnQpICIgKyBkaW0gKyAiKSk7Iik7Ci0gICAgICBicmVhazsKLQotICAgIGRlZmF1bHQ6Ci0gICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiT29wczogIiArIG9wY29kZSk7Ci0gICAgfQotICB9Ci0KLSAgcHJpdmF0ZSB2b2lkIGNyZWF0ZUNvbnN0YW50KE9iamVjdCB2YWx1ZSkgewotICAgIFN0cmluZyBlbWJlZCA9IHZhbHVlLnRvU3RyaW5nKCk7Ci0KLSAgICBpZih2YWx1ZSBpbnN0YW5jZW9mIFN0cmluZykKLSAgICAgIGVtYmVkID0gJyInICsgVXRpbGl0eS5jb252ZXJ0U3RyaW5nKHZhbHVlLnRvU3RyaW5nKCkpICsgJyInOwotICAgIGVsc2UgaWYodmFsdWUgaW5zdGFuY2VvZiBDaGFyYWN0ZXIpCi0gICAgICBlbWJlZCA9ICIoY2hhcikweCIgKyBJbnRlZ2VyLnRvSGV4U3RyaW5nKCgoQ2hhcmFjdGVyKXZhbHVlKS5jaGFyVmFsdWUoKSk7Ci0KLSAgICBfb3V0LnByaW50bG4oImlsLmFwcGVuZChuZXcgUFVTSChfY3AsICIgKyBlbWJlZCArICIpKTsiKTsKLSAgfQotCi0gIHB1YmxpYyB2b2lkIHZpc2l0TERDKExEQyBpKSB7Ci0gICAgY3JlYXRlQ29uc3RhbnQoaS5nZXRWYWx1ZShfY3ApKTsKLSAgfQotCi0gIHB1YmxpYyB2b2lkIHZpc2l0TERDMl9XKExEQzJfVyBpKSB7Ci0gICAgY3JlYXRlQ29uc3RhbnQoaS5nZXRWYWx1ZShfY3ApKTsKLSAgfQotCi0gIHB1YmxpYyB2b2lkIHZpc2l0Q29uc3RhbnRQdXNoSW5zdHJ1Y3Rpb24oQ29uc3RhbnRQdXNoSW5zdHJ1Y3Rpb24gaSkgewotICAgIGNyZWF0ZUNvbnN0YW50KGkuZ2V0VmFsdWUoKSk7Ci0gIH0KLQotICBwdWJsaWMgdm9pZCB2aXNpdElOU1RBTkNFT0YoSU5TVEFOQ0VPRiBpKSB7Ci0gICAgVHlwZSB0eXBlID0gaS5nZXRUeXBlKF9jcCk7Ci0KLSAgICBfb3V0LnByaW50bG4oImlsLmFwcGVuZChuZXcgSU5TVEFOQ0VPRihfY3AuYWRkQ2xhc3MoIiArCi0gICAgICAgICAgICAgICAgIEJDRUxpZmllci5wcmludFR5cGUodHlwZSkgKyAiKSkpOyIpOwotICB9Ci0KLSAgcHVibGljIHZvaWQgdmlzaXRDSEVDS0NBU1QoQ0hFQ0tDQVNUIGkpIHsKLSAgICBUeXBlIHR5cGUgPSBpLmdldFR5cGUoX2NwKTsKLQotICAgIF9vdXQucHJpbnRsbigiaWwuYXBwZW5kKF9mYWN0b3J5LmNyZWF0ZUNoZWNrQ2FzdCgiICsKLSAgICAgICAgICAgICAgICAgQkNFTGlmaWVyLnByaW50VHlwZSh0eXBlKSArICIpKTsiKTsKLSAgfQotCi0gIHB1YmxpYyB2b2lkIHZpc2l0UmV0dXJuSW5zdHJ1Y3Rpb24oUmV0dXJuSW5zdHJ1Y3Rpb24gaSkgewotICAgIFR5cGUgdHlwZSA9IGkuZ2V0VHlwZShfY3ApOwotCi0gICAgX291dC5wcmludGxuKCJpbC5hcHBlbmQoX2ZhY3RvcnkuY3JlYXRlUmV0dXJuKCIgKwotICAgICAgICAgICAgICAgICBCQ0VMaWZpZXIucHJpbnRUeXBlKHR5cGUpICsgIikpOyIpOwotICB9Ci0KLSAgLy8gTWVtb3JpemUgQnJhbmNoSW5zdHJ1Y3Rpb25zIHRoYXQgbmVlZCBhbiB1cGRhdGUKLSAgcHJpdmF0ZSBBcnJheUxpc3QgYnJhbmNoZXMgPSBuZXcgQXJyYXlMaXN0KCk7Ci0KLSAgcHVibGljIHZvaWQgdmlzaXRCcmFuY2hJbnN0cnVjdGlvbihCcmFuY2hJbnN0cnVjdGlvbiBiaSkgewotICAgIEJyYW5jaEhhbmRsZSBiaCAgID0gKEJyYW5jaEhhbmRsZSlicmFuY2hfbWFwLmdldChiaSk7Ci0gICAgaW50ICAgICAgICAgIHBvcyAgPSBiaC5nZXRQb3NpdGlvbigpOwotICAgIFN0cmluZyAgICAgICBuYW1lID0gYmkuZ2V0TmFtZSgpICsgIl8iICsgcG9zOwotCi0gICAgaWYoYmkgaW5zdGFuY2VvZiBTZWxlY3QpIHsKLSAgICAgIFNlbGVjdCBzID0gKFNlbGVjdCliaTsKLSAgICAgIGJyYW5jaGVzLmFkZChiaSk7Ci0KLSAgICAgIFN0cmluZ0J1ZmZlciBhcmdzICAgPSBuZXcgU3RyaW5nQnVmZmVyKCJuZXcgaW50W10geyAiKTsKLSAgICAgIGludFtdICAgICAgICBtYXRjaHMgPSBzLmdldE1hdGNocygpOwotCi0gICAgICBmb3IoaW50IGk9MDsgaSA8IG1hdGNocy5sZW5ndGg7IGkrKykgewotICAgICAgICBhcmdzLmFwcGVuZChtYXRjaHNbaV0pOwotCi0gICAgICAgIGlmKGkgPCBtYXRjaHMubGVuZ3RoIC0gMSkKLSAgICAgICAgICBhcmdzLmFwcGVuZCgiLCAiKTsKLSAgICAgIH0KLQotICAgICAgYXJncy5hcHBlbmQoIiB9Iik7Ci0KLSAgICAgIF9vdXQucHJpbnQoIiAgICBTZWxlY3QgIiArIG5hbWUgKyAiID0gbmV3ICIgKwotICAgICAgICAgICAgICAgICBiaS5nZXROYW1lKCkudG9VcHBlckNhc2UoKSArICIoIiArIGFyZ3MgKwotICAgICAgICAgICAgICAgICAiLCBuZXcgSW5zdHJ1Y3Rpb25IYW5kbGVbXSB7ICIpOwotCi0gICAgICBmb3IoaW50IGk9MDsgaSA8IG1hdGNocy5sZW5ndGg7IGkrKykgewotICAgICAgICBfb3V0LnByaW50KCJudWxsIik7Ci0KLSAgICAgICAgaWYoaSA8IG1hdGNocy5sZW5ndGggLSAxKQotICAgICAgICAgIF9vdXQucHJpbnQoIiwgIik7Ci0gICAgICB9Ci0KLSAgICAgIF9vdXQucHJpbnRsbigiKTsiKTsKLSAgICB9IGVsc2UgewotICAgICAgaW50ICAgIHRfcG9zICA9IGJoLmdldFRhcmdldCgpLmdldFBvc2l0aW9uKCk7Ci0gICAgICBTdHJpbmcgdGFyZ2V0OwotCi0gICAgICBpZihwb3MgPiB0X3BvcykgewotICAgICAgICB0YXJnZXQgPSAiaWhfIiArIHRfcG9zOwotICAgICAgfSBlbHNlIHsKLSAgICAgICAgYnJhbmNoZXMuYWRkKGJpKTsKLSAgICAgICAgdGFyZ2V0ID0gIm51bGwiOwotICAgICAgfQotCi0gICAgICBfb3V0LnByaW50bG4oIiAgICBCcmFuY2hJbnN0cnVjdGlvbiAiICsgbmFtZSArCi0gICAgICAgICAgICAgICAgICAgIiA9IF9mYWN0b3J5LmNyZWF0ZUJyYW5jaEluc3RydWN0aW9uKCIgKwotICAgICAgICAgICAgICAgICAgICJDb25zdGFudHMuIiArIGJpLmdldE5hbWUoKS50b1VwcGVyQ2FzZSgpICsgIiwgIiArCi0gICAgICAgICAgICAgICAgICAgdGFyZ2V0ICsgIik7Iik7Ci0gICAgfQotCi0gICAgaWYoYmguaGFzVGFyZ2V0ZXJzKCkpCi0gICAgICBfb3V0LnByaW50bG4oIiAgICBpaF8iICsgcG9zICsgIiA9IGlsLmFwcGVuZCgiICsgbmFtZSArICIpOyIpOwotICAgIGVsc2UKLSAgICAgIF9vdXQucHJpbnRsbigiICAgIGlsLmFwcGVuZCgiICsgbmFtZSArICIpOyIpOwotICB9Ci0KLSAgcHVibGljIHZvaWQgdmlzaXRSRVQoUkVUIGkpIHsKLSAgICBfb3V0LnByaW50bG4oImlsLmFwcGVuZChuZXcgUkVUKCIgKyBpLmdldEluZGV4KCkgKyAiKSkpOyIpOwotICB9Ci0KLSAgcHJpdmF0ZSB2b2lkIHVwZGF0ZUJyYW5jaFRhcmdldHMoKSB7Ci0gICAgZm9yKEl0ZXJhdG9yIGkgPSBicmFuY2hlcy5pdGVyYXRvcigpOyBpLmhhc05leHQoKTsgKSB7Ci0gICAgICBCcmFuY2hJbnN0cnVjdGlvbiBiaSAgICA9IChCcmFuY2hJbnN0cnVjdGlvbilpLm5leHQoKTsKLSAgICAgIEJyYW5jaEhhbmRsZSAgICAgIGJoICAgID0gKEJyYW5jaEhhbmRsZSlicmFuY2hfbWFwLmdldChiaSk7Ci0gICAgICBpbnQgICAgICAgICAgICAgICBwb3MgICA9IGJoLmdldFBvc2l0aW9uKCk7Ci0gICAgICBTdHJpbmcgICAgICAgICAgICBuYW1lICA9IGJpLmdldE5hbWUoKSArICJfIiArIHBvczsKLSAgICAgIGludCAgICAgICAgICAgICAgIHRfcG9zID0gYmguZ2V0VGFyZ2V0KCkuZ2V0UG9zaXRpb24oKTsKLQotICAgICAgX291dC5wcmludGxuKCIgICAgIiArIG5hbWUgKyAiLnNldFRhcmdldChpaF8iICsgdF9wb3MgKyAiKTsiKTsKLQotICAgICAgaWYoYmkgaW5zdGFuY2VvZiBTZWxlY3QpIHsKLSAgICAgICAgSW5zdHJ1Y3Rpb25IYW5kbGVbXSBpaHMgPSAoKFNlbGVjdCliaSkuZ2V0VGFyZ2V0cygpOwotCi0gICAgICAgIGZvcihpbnQgaiA9IDA7IGogPCBpaHMubGVuZ3RoOyBqKyspIHsKLSAgICAgICAgICB0X3BvcyA9IGloc1tqXS5nZXRQb3NpdGlvbigpOwotCi0gICAgICAgICAgX291dC5wcmludGxuKCIgICAgIiArIG5hbWUgKyAiLnNldFRhcmdldCgiICsgaiArCi0gICAgICAgICAgICAgICAgICAgICAgICIsIGloXyIgKyB0X3BvcyArICIpOyIpOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotICB9Ci0KLSAgcHJpdmF0ZSB2b2lkIHVwZGF0ZUV4Y2VwdGlvbkhhbmRsZXJzKCkgewotICAgIENvZGVFeGNlcHRpb25HZW5bXSBoYW5kbGVycyA9IF9tZy5nZXRFeGNlcHRpb25IYW5kbGVycygpOwotCi0gICAgZm9yKGludCBpPTA7IGkgPCBoYW5kbGVycy5sZW5ndGg7IGkrKykgewotICAgICAgQ29kZUV4Y2VwdGlvbkdlbiBoICAgID0gaGFuZGxlcnNbaV07Ci0gICAgICBTdHJpbmcgICAgICAgICAgIHR5cGUgPSAoaC5nZXRDYXRjaFR5cGUoKSA9PSBudWxsKT8KLSAgICAgICAgIm51bGwiIDogQkNFTGlmaWVyLnByaW50VHlwZShoLmdldENhdGNoVHlwZSgpKTsKLQotICAgICAgX291dC5wcmludGxuKCIgICAgbWV0aG9kLmFkZEV4Y2VwdGlvbkhhbmRsZXIoIiArCi0gICAgICAgICAgICAgICAgICAgImloXyIgKyBoLmdldFN0YXJ0UEMoKS5nZXRQb3NpdGlvbigpICsgIiwgIiArCi0gICAgICAgICAgICAgICAgICAgImloXyIgKyBoLmdldEVuZFBDKCkuZ2V0UG9zaXRpb24oKSArICIsICIgKwotICAgICAgICAgICAgICAgICAgICJpaF8iICsgaC5nZXRIYW5kbGVyUEMoKS5nZXRQb3NpdGlvbigpICsgIiwgIiArCi0gICAgICAgICAgICAgICAgICAgdHlwZSArICIpOyIpOwotICAgIH0KLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL3V0aWwvQkNFTGlmaWVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvdXRpbC9CQ0VMaWZpZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggODdhODI0NC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvdXRpbC9CQ0VMaWZpZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDMwNyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC51dGlsOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMiBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmNsYXNzZmlsZS4qOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuKjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5SZXBvc2l0b3J5OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50czsKLWltcG9ydCBqYXZhLmlvLio7Ci0KLS8qKgotICogVGhpcyBjbGFzcyB0YWtlcyBhIGdpdmVuIEphdmFDbGFzcyBvYmplY3QgYW5kIGNvbnZlcnRzIGl0IHRvIGEKLSAqIEphdmEgcHJvZ3JhbSB0aGF0IGNyZWF0ZXMgdGhhdCB2ZXJ5IGNsYXNzIHVzaW5nIEJDRUwuIFRoaXMKLSAqIGdpdmVzIG5ldyB1c2VycyBvZiBCQ0VMIGEgdXNlZnVsIGV4YW1wbGUgc2hvd2luZyBob3cgdGhpbmdzCi0gKiBhcmUgZG9uZSB3aXRoIEJDRUwuIEl0IGRvZXMgbm90IGNvdmVyIGFsbCBmZWF0dXJlcyBvZiBCQ0VMLAotICogYnV0IHRyaWVzIHRvIG1pbWljIGhhbmQtd3JpdHRlbiBjb2RlIGFzIGNsb3NlIGFzIHBvc3NpYmxlLgotICoKLSAqIEBhdXRob3IgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqLwotcHVibGljIGNsYXNzIEJDRUxpZmllciBleHRlbmRzIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmNsYXNzZmlsZS5FbXB0eVZpc2l0b3IgewotICBwcml2YXRlIEphdmFDbGFzcyAgICAgICAgIF9jbGF6ejsKLSAgcHJpdmF0ZSBQcmludFdyaXRlciAgICAgICBfb3V0OwotICBwcml2YXRlIENvbnN0YW50UG9vbEdlbiAgIF9jcDsKLQotICAvKiogQHBhcmFtIGNsYXp6IEphdmEgY2xhc3MgdG8gImRlY29tcGlsZSIKLSAgICogQHBhcmFtIG91dCB3aGVyZSB0byBvdXRwdXQgSmF2YSBwcm9ncmFtCi0gICAqLwotICBwdWJsaWMgQkNFTGlmaWVyKEphdmFDbGFzcyBjbGF6eiwgT3V0cHV0U3RyZWFtIG91dCkgewotICAgIF9jbGF6eiA9IGNsYXp6OwotICAgIF9vdXQgPSBuZXcgUHJpbnRXcml0ZXIob3V0KTsKLSAgICBfY3AgPSBuZXcgQ29uc3RhbnRQb29sR2VuKF9jbGF6ei5nZXRDb25zdGFudFBvb2woKSk7Ci0gIH0KLQotICAvKiogU3RhcnQgSmF2YSBjb2RlIGdlbmVyYXRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHN0YXJ0KCkgewotICAgIHZpc2l0SmF2YUNsYXNzKF9jbGF6eik7Ci0gICAgX291dC5mbHVzaCgpOwotICB9Ci0KLSAgcHVibGljIHZvaWQgdmlzaXRKYXZhQ2xhc3MoSmF2YUNsYXNzIGNsYXp6KSB7Ci0gICAgU3RyaW5nIGNsYXNzX25hbWUgICA9IGNsYXp6LmdldENsYXNzTmFtZSgpOwotICAgIFN0cmluZyBzdXBlcl9uYW1lICAgPSBjbGF6ei5nZXRTdXBlcmNsYXNzTmFtZSgpOwotICAgIFN0cmluZyBwYWNrYWdlX25hbWUgPSBjbGF6ei5nZXRQYWNrYWdlTmFtZSgpOwotICAgIFN0cmluZyBpbnRlciAgICAgICAgPSBVdGlsaXR5LnByaW50QXJyYXkoY2xhenouZ2V0SW50ZXJmYWNlTmFtZXMoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlLCB0cnVlKTsKLSAgICBpZighIiIuZXF1YWxzKHBhY2thZ2VfbmFtZSkpIHsKLSAgICAgIGNsYXNzX25hbWUgPSBjbGFzc19uYW1lLnN1YnN0cmluZyhwYWNrYWdlX25hbWUubGVuZ3RoKCkgKyAxKTsKLSAgICAgIF9vdXQucHJpbnRsbigicGFja2FnZSAiICsgcGFja2FnZV9uYW1lICsgIjtcbiIpOwotICAgICB9Ci0KLSAgICBfb3V0LnByaW50bG4oImltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLio7Iik7Ci0gICAgX291dC5wcmludGxuKCJpbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuY2xhc3NmaWxlLio7Iik7Ci0gICAgX291dC5wcmludGxuKCJpbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuKjsiKTsKLSAgICBfb3V0LnByaW50bG4oImltcG9ydCBqYXZhLmlvLio7XG4iKTsKLQotICAgIF9vdXQucHJpbnRsbigicHVibGljIGNsYXNzICIgKyBjbGFzc19uYW1lICsgIkNyZWF0b3IgaW1wbGVtZW50cyBDb25zdGFudHMgeyIpOwotICAgIF9vdXQucHJpbnRsbigiICBwcml2YXRlIEluc3RydWN0aW9uRmFjdG9yeSBfZmFjdG9yeTsiKTsKLSAgICBfb3V0LnByaW50bG4oIiAgcHJpdmF0ZSBDb25zdGFudFBvb2xHZW4gICAgX2NwOyIpOwotICAgIF9vdXQucHJpbnRsbigiICBwcml2YXRlIENsYXNzR2VuICAgICAgICAgICBfY2c7XG4iKTsKLQotICAgIF9vdXQucHJpbnRsbigiICBwdWJsaWMgIiArIGNsYXNzX25hbWUgICsgIkNyZWF0b3IoKSB7Iik7Ci0gICAgX291dC5wcmludGxuKCIgICAgX2NnID0gbmV3IENsYXNzR2VuKFwiIiArCi0gICAgICAgICAgICAgICAgICgoIiIuZXF1YWxzKHBhY2thZ2VfbmFtZSkpPyBjbGFzc19uYW1lIDoKLSAgICAgICAgICAgICAgICAgIHBhY2thZ2VfbmFtZSArICIuIiArIGNsYXNzX25hbWUpICsKLSAgICAgICAgICAgICAgICAgIlwiLCBcIiIgKyBzdXBlcl9uYW1lICsgIlwiLCAiICsKLSAgICAgICAgICAgICAgICAgIlwiIiArIGNsYXp6LmdldFNvdXJjZUZpbGVOYW1lKCkgKyAiXCIsICIgKwotICAgICAgICAgICAgICAgICBwcmludEZsYWdzKGNsYXp6LmdldEFjY2Vzc0ZsYWdzKCksIHRydWUpICsgIiwgIiArCi0gICAgICAgICAgICAgICAgICJuZXcgU3RyaW5nW10geyAiICsgaW50ZXIgKyAiIH0pO1xuIik7Ci0KLSAgICBfb3V0LnByaW50bG4oIiAgICBfY3AgPSBfY2cuZ2V0Q29uc3RhbnRQb29sKCk7Iik7Ci0gICAgX291dC5wcmludGxuKCIgICAgX2ZhY3RvcnkgPSBuZXcgSW5zdHJ1Y3Rpb25GYWN0b3J5KF9jZywgX2NwKTsiKTsKLSAgICBfb3V0LnByaW50bG4oIiAgfVxuIik7Ci0KLSAgICBwcmludENyZWF0ZSgpOwotCi0gICAgRmllbGRbXSBmaWVsZHMgPSBjbGF6ei5nZXRGaWVsZHMoKTsKLQotICAgIGlmKGZpZWxkcy5sZW5ndGggPiAwKSB7Ci0gICAgICBfb3V0LnByaW50bG4oIiAgcHJpdmF0ZSB2b2lkIGNyZWF0ZUZpZWxkcygpIHsiKTsKLSAgICAgIF9vdXQucHJpbnRsbigiICAgIEZpZWxkR2VuIGZpZWxkOyIpOwotCi0gICAgICBmb3IoaW50IGk9MDsgaSA8IGZpZWxkcy5sZW5ndGg7IGkrKykgewotICAgICAgICBmaWVsZHNbaV0uYWNjZXB0KHRoaXMpOwotICAgICAgfQotCi0gICAgICBfb3V0LnByaW50bG4oIiAgfVxuIik7Ci0gICAgfQotCi0gICAgTWV0aG9kW10gbWV0aG9kcyA9IGNsYXp6LmdldE1ldGhvZHMoKTsKLQotICAgIGZvcihpbnQgaT0wOyBpIDwgbWV0aG9kcy5sZW5ndGg7IGkrKykgewotICAgICAgX291dC5wcmludGxuKCIgIHByaXZhdGUgdm9pZCBjcmVhdGVNZXRob2RfIiArIGkgKyAiKCkgeyIpOwotCi0gICAgICBtZXRob2RzW2ldLmFjY2VwdCh0aGlzKTsKLSAgICAgIF9vdXQucHJpbnRsbigiICB9XG4iKTsKLSAgICB9Ci0KLSAgICBwcmludE1haW4oKTsKLSAgICBfb3V0LnByaW50bG4oIn0iKTsKLSAgfQotCi0gIHByaXZhdGUgdm9pZCBwcmludENyZWF0ZSgpIHsKLSAgICBfb3V0LnByaW50bG4oIiAgcHVibGljIHZvaWQgY3JlYXRlKE91dHB1dFN0cmVhbSBvdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7Iik7Ci0KLSAgICBGaWVsZFtdIGZpZWxkcyA9IF9jbGF6ei5nZXRGaWVsZHMoKTsKLSAgICBpZihmaWVsZHMubGVuZ3RoID4gMCkgewotICAgICAgX291dC5wcmludGxuKCIgICAgY3JlYXRlRmllbGRzKCk7Iik7Ci0gICAgfQotCi0gICAgTWV0aG9kW10gbWV0aG9kcyA9IF9jbGF6ei5nZXRNZXRob2RzKCk7Ci0gICAgZm9yKGludCBpPTA7IGkgPCBtZXRob2RzLmxlbmd0aDsgaSsrKSB7Ci0gICAgICBfb3V0LnByaW50bG4oIiAgICBjcmVhdGVNZXRob2RfIiArIGkgKyAiKCk7Iik7Ci0gICAgfQotCi0gICAgX291dC5wcmludGxuKCIgICAgX2NnLmdldEphdmFDbGFzcygpLmR1bXAob3V0KTsiKTsKLQotICAgIF9vdXQucHJpbnRsbigiICB9XG4iKTsKLSAgfQotCi0gIHByaXZhdGUgdm9pZCBwcmludE1haW4oKSB7Ci0gICAgU3RyaW5nICAgY2xhc3NfbmFtZSAgID0gX2NsYXp6LmdldENsYXNzTmFtZSgpOwotCi0gICAgX291dC5wcmludGxuKCIgIHB1YmxpYyBzdGF0aWMgdm9pZCBfbWFpbihTdHJpbmdbXSBhcmdzKSB0aHJvd3MgRXhjZXB0aW9uIHsiKTsKLSAgICBfb3V0LnByaW50bG4oIiAgICAiICsgY2xhc3NfbmFtZSArICJDcmVhdG9yIGNyZWF0b3IgPSBuZXcgIiArCi0gICAgICAgICAgICAgICAgIGNsYXNzX25hbWUgKyAiQ3JlYXRvcigpOyIpOwotICAgIF9vdXQucHJpbnRsbigiICAgIGNyZWF0b3IuY3JlYXRlKG5ldyBGaWxlT3V0cHV0U3RyZWFtKFwiIiArIGNsYXNzX25hbWUgKwotICAgICAgICAgICAgICAgICAiLmNsYXNzXCIpKTsiKTsKLSAgICBfb3V0LnByaW50bG4oIiAgfSIpOwotICB9Ci0KLSAgcHVibGljIHZvaWQgdmlzaXRGaWVsZChGaWVsZCBmaWVsZCkgewotICAgIF9vdXQucHJpbnRsbigiXG4gICAgZmllbGQgPSBuZXcgRmllbGRHZW4oIiArCi0gICAgICAgICAgICAgICAgIHByaW50RmxhZ3MoZmllbGQuZ2V0QWNjZXNzRmxhZ3MoKSkgKwotICAgICAgICAgICAgICAgICAiLCAiICsgcHJpbnRUeXBlKGZpZWxkLmdldFNpZ25hdHVyZSgpKSArICIsIFwiIiArCi0gICAgICAgICAgICAgICAgIGZpZWxkLmdldE5hbWUoKSArICJcIiwgX2NwKTsiKTsKLQotICAgIENvbnN0YW50VmFsdWUgY3YgPSBmaWVsZC5nZXRDb25zdGFudFZhbHVlKCk7Ci0KLSAgICBpZihjdiAhPSBudWxsKSB7Ci0gICAgICBTdHJpbmcgdmFsdWUgPSBjdi50b1N0cmluZygpOwotICAgICAgX291dC5wcmludGxuKCIgICAgZmllbGQuc2V0SW5pdFZhbHVlKCIgKyB2YWx1ZSArICIpIik7Ci0gICAgfQotCi0gICAgX291dC5wcmludGxuKCIgICAgX2NnLmFkZEZpZWxkKGZpZWxkLmdldEZpZWxkKCkpOyIpOwotICB9Ci0KLSAgcHVibGljIHZvaWQgdmlzaXRNZXRob2QoTWV0aG9kIG1ldGhvZCkgewotICAgIE1ldGhvZEdlbiBtZyA9IG5ldyBNZXRob2RHZW4obWV0aG9kLCBfY2xhenouZ2V0Q2xhc3NOYW1lKCksIF9jcCk7Ci0KLSAgICBUeXBlICAgcmVzdWx0X3R5cGUgPSBtZy5nZXRSZXR1cm5UeXBlKCk7Ci0gICAgVHlwZVtdIGFyZ190eXBlcyAgID0gbWcuZ2V0QXJndW1lbnRUeXBlcygpOwotCi0gICAgX291dC5wcmludGxuKCIgICAgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbmV3IEluc3RydWN0aW9uTGlzdCgpOyIpOwotICAgIF9vdXQucHJpbnRsbigiICAgIE1ldGhvZEdlbiBtZXRob2QgPSBuZXcgTWV0aG9kR2VuKCIgKwotICAgICAgICAgICAgICAgICBwcmludEZsYWdzKG1ldGhvZC5nZXRBY2Nlc3NGbGFncygpKSArCi0gICAgICAgICAgICAgICAgICIsICIgKyBwcmludFR5cGUocmVzdWx0X3R5cGUpICsKLSAgICAgICAgICAgICAgICAgIiwgIiArIHByaW50QXJndW1lbnRUeXBlcyhhcmdfdHlwZXMpICsgIiwgIiArCi0gICAgICAgICAgICAgICAgICJuZXcgU3RyaW5nW10geyAiICsKLSAgICAgICAgICAgICAgICAgVXRpbGl0eS5wcmludEFycmF5KG1nLmdldEFyZ3VtZW50TmFtZXMoKSwgZmFsc2UsIHRydWUpICsKLSAgICAgICAgICAgICAgICAgIiB9LCBcIiIgKyBtZXRob2QuZ2V0TmFtZSgpICsgIlwiLCBcIiIgKwotICAgICAgICAgICAgICAgICBfY2xhenouZ2V0Q2xhc3NOYW1lKCkgKyAiXCIsIGlsLCBfY3ApO1xuIik7Ci0KLSAgICBCQ0VMRmFjdG9yeSBmYWN0b3J5ID0gbmV3IEJDRUxGYWN0b3J5KG1nLCBfb3V0KTsKLSAgICBmYWN0b3J5LnN0YXJ0KCk7Ci0KLSAgICBfb3V0LnByaW50bG4oIiAgICBtZXRob2Quc2V0TWF4U3RhY2soKTsiKTsKLSAgICBfb3V0LnByaW50bG4oIiAgICBtZXRob2Quc2V0TWF4TG9jYWxzKCk7Iik7Ci0gICAgX291dC5wcmludGxuKCIgICAgX2NnLmFkZE1ldGhvZChtZXRob2QuZ2V0TWV0aG9kKCkpOyIpOwotICAgIF9vdXQucHJpbnRsbigiICAgIGlsLmRpc3Bvc2UoKTsiKTsKLSAgfQotCi0gIHN0YXRpYyBTdHJpbmcgcHJpbnRGbGFncyhpbnQgZmxhZ3MpIHsKLSAgICByZXR1cm4gcHJpbnRGbGFncyhmbGFncywgZmFsc2UpOwotICB9Ci0KLSAgc3RhdGljIFN0cmluZyBwcmludEZsYWdzKGludCBmbGFncywgYm9vbGVhbiBmb3JfY2xhc3MpIHsKLSAgICBpZihmbGFncyA9PSAwKQotICAgICAgcmV0dXJuICIwIjsKLQotICAgIFN0cmluZ0J1ZmZlciBidWYgPSBuZXcgU3RyaW5nQnVmZmVyKCk7Ci0gICAgZm9yKGludCBpPTAsIHBvdz0xOyBpIDw9IENvbnN0YW50cy5NQVhfQUNDX0ZMQUc7IGkrKykgewotICAgICAgaWYoKGZsYWdzICYgcG93KSAhPSAwKSB7Ci0gICAgICAgIGlmKChwb3cgPT0gQ29uc3RhbnRzLkFDQ19TWU5DSFJPTklaRUQpICYmIGZvcl9jbGFzcykKLSAgICAgICAgICBidWYuYXBwZW5kKCJBQ0NfU1VQRVIgfCAiKTsKLSAgICAgICAgZWxzZQotICAgICAgICAgIGJ1Zi5hcHBlbmQoIkFDQ18iICsgQ29uc3RhbnRzLkFDQ0VTU19OQU1FU1tpXS50b1VwcGVyQ2FzZSgpICsgIiB8ICIpOwotICAgICAgfQotCi0gICAgICBwb3cgPDw9IDE7Ci0gICAgfQotCi0gICAgU3RyaW5nIHN0ciA9IGJ1Zi50b1N0cmluZygpOwotICAgIHJldHVybiBzdHIuc3Vic3RyaW5nKDAsIHN0ci5sZW5ndGgoKSAtIDMpOwotICB9Ci0KLSAgc3RhdGljIFN0cmluZyBwcmludEFyZ3VtZW50VHlwZXMoVHlwZVtdIGFyZ190eXBlcykgewotICAgIGlmKGFyZ190eXBlcy5sZW5ndGggPT0gMCkKLSAgICAgIHJldHVybiAiVHlwZS5OT19BUkdTIjsKLQotICAgIFN0cmluZ0J1ZmZlciBhcmdzID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotCi0gICAgZm9yKGludCBpPTA7IGkgPCBhcmdfdHlwZXMubGVuZ3RoOyBpKyspIHsKLSAgICAgIGFyZ3MuYXBwZW5kKHByaW50VHlwZShhcmdfdHlwZXNbaV0pKTsKLQotICAgICAgaWYoaSA8IGFyZ190eXBlcy5sZW5ndGggLSAxKQotICAgICAgICBhcmdzLmFwcGVuZCgiLCAiKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gIm5ldyBUeXBlW10geyAiICsgYXJncy50b1N0cmluZygpICsgIiB9IjsKLSAgfQotCi0gIHN0YXRpYyBTdHJpbmcgcHJpbnRUeXBlKFR5cGUgdHlwZSkgewotICAgIHJldHVybiBwcmludFR5cGUodHlwZS5nZXRTaWduYXR1cmUoKSk7Ci0gIH0KLQotICBzdGF0aWMgU3RyaW5nIHByaW50VHlwZShTdHJpbmcgc2lnbmF0dXJlKSB7Ci0gICAgVHlwZSB0eXBlID0gVHlwZS5nZXRUeXBlKHNpZ25hdHVyZSk7Ci0gICAgYnl0ZSB0ICAgID0gdHlwZS5nZXRUeXBlKCk7Ci0KLSAgICBpZih0IDw9IENvbnN0YW50cy5UX1ZPSUQpIHsKLSAgICAgIHJldHVybiAiVHlwZS4iICsgQ29uc3RhbnRzLlRZUEVfTkFNRVNbdF0udG9VcHBlckNhc2UoKTsKLSAgICB9IGVsc2UgaWYodHlwZS50b1N0cmluZygpLmVxdWFscygiamF2YS5sYW5nLlN0cmluZyIpKSB7Ci0gICAgICByZXR1cm4gIlR5cGUuU1RSSU5HIjsKLSAgICB9IGVsc2UgaWYodHlwZS50b1N0cmluZygpLmVxdWFscygiamF2YS5sYW5nLk9iamVjdCIpKSB7Ci0gICAgICByZXR1cm4gIlR5cGUuT0JKRUNUIjsKLSAgICB9IGVsc2UgaWYodHlwZS50b1N0cmluZygpLmVxdWFscygiamF2YS5sYW5nLlN0cmluZ0J1ZmZlciIpKSB7Ci0gICAgICByZXR1cm4gIlR5cGUuU1RSSU5HQlVGRkVSIjsKLSAgICB9IGVsc2UgaWYodHlwZSBpbnN0YW5jZW9mIEFycmF5VHlwZSkgewotICAgICAgQXJyYXlUeXBlIGF0ID0gKEFycmF5VHlwZSl0eXBlOwotCi0gICAgICByZXR1cm4gIm5ldyBBcnJheVR5cGUoIiArIHByaW50VHlwZShhdC5nZXRCYXNpY1R5cGUoKSkgKwotICAgICAgICAiLCAiICsgYXQuZ2V0RGltZW5zaW9ucygpICsgIikiOwotICAgIH0gZWxzZSB7Ci0gICAgICByZXR1cm4gIm5ldyBPYmplY3RUeXBlKFwiIiArIFV0aWxpdHkuc2lnbmF0dXJlVG9TdHJpbmcoc2lnbmF0dXJlLCBmYWxzZSkgKwotICAgICAgICAiXCIpIjsKLSAgICB9Ci0gIH0KLQotICAvKiogRGVmYXVsdCBfbWFpbiBtZXRob2QKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgdm9pZCBfbWFpbihTdHJpbmdbXSBhcmd2KSB0aHJvd3MgRXhjZXB0aW9uIHsKLSAgICBKYXZhQ2xhc3MgamF2YV9jbGFzczsKLSAgICBTdHJpbmcgICAgbmFtZSA9IGFyZ3ZbMF07Ci0KLSAgICBpZigoamF2YV9jbGFzcyA9IFJlcG9zaXRvcnkubG9va3VwQ2xhc3MobmFtZSkpID09IG51bGwpCi0gICAgICBqYXZhX2NsYXNzID0gbmV3IENsYXNzUGFyc2VyKG5hbWUpLnBhcnNlKCk7IC8vIE1heSB0aHJvdyBJT0V4Y2VwdGlvbgotCi0gICAgQkNFTGlmaWVyIGJjZWxpZmllciA9IG5ldyBCQ0VMaWZpZXIoamF2YV9jbGFzcywgU3lzdGVtLm91dCk7Ci0gICAgYmNlbGlmaWVyLnN0YXJ0KCk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC91dGlsL0J5dGVTZXF1ZW5jZS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL3V0aWwvQnl0ZVNlcXVlbmNlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGUwZGFjZDcuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL3V0aWwvQnl0ZVNlcXVlbmNlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4NSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC51dGlsOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotaW1wb3J0IGphdmEuaW8uKjsKLQotLyoqCi0gKiBVdGlsaXR5IGNsYXNzIHRoYXQgaW1wbGVtZW50cyBhIHNlcXVlbmNlIG9mIGJ5dGVzIHdoaWNoIGNhbiBiZSByZWFkCi0gKiB2aWEgdGhlIGByZWFkQnl0ZSgpJyBtZXRob2QuIFRoaXMgaXMgdXNlZCB0byBpbXBsZW1lbnQgYSB3cmFwcGVyIGZvciB0aGUKLSAqIEphdmEgYnl0ZSBjb2RlIHN0cmVhbSB0byBnYWluIHNvbWUgbW9yZSByZWFkYWJpbGl0eS4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgQnl0ZVNlcXVlbmNlIGV4dGVuZHMgRGF0YUlucHV0U3RyZWFtIHsKLSAgcHJpdmF0ZSBCeXRlQXJyYXlTdHJlYW0gYnl0ZV9zdHJlYW07Ci0KLSAgcHVibGljIEJ5dGVTZXF1ZW5jZShieXRlW10gYnl0ZXMpIHsKLSAgICBzdXBlcihuZXcgQnl0ZUFycmF5U3RyZWFtKGJ5dGVzKSk7Ci0gICAgYnl0ZV9zdHJlYW0gPSAoQnl0ZUFycmF5U3RyZWFtKWluOwotICB9Ci0KLSAgcHVibGljIGZpbmFsIGludCBnZXRJbmRleCgpICAgeyByZXR1cm4gYnl0ZV9zdHJlYW0uZ2V0UG9zaXRpb24oKTsgfQotICBmaW5hbCAgdm9pZCAgICAgIHVucmVhZEJ5dGUoKSB7IGJ5dGVfc3RyZWFtLnVucmVhZEJ5dGUoKTsgfQotCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEJ5dGVBcnJheVN0cmVhbSBleHRlbmRzIEJ5dGVBcnJheUlucHV0U3RyZWFtIHsKLSAgICBCeXRlQXJyYXlTdHJlYW0oYnl0ZVtdIGJ5dGVzKSB7IHN1cGVyKGJ5dGVzKTsgfQotICAgIGZpbmFsIGludCAgZ2V0UG9zaXRpb24oKSB7IHJldHVybiBwb3M7IH0gLy8gaXMgcHJvdGVjdGVkIGluIEJ5dGVBcnJheUlucHV0U3RyZWFtCi0gICAgZmluYWwgdm9pZCB1bnJlYWRCeXRlKCkgIHsgaWYocG9zID4gMCkgcG9zLS07IH0KLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL3V0aWwvQ2xhc3MySFRNTC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL3V0aWwvQ2xhc3MySFRNTC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1YTllMDk0Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC91dGlsL0NsYXNzMkhUTUwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI2NiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC51dGlsOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi1pbXBvcnQgamF2YS5pby4qOwotaW1wb3J0IGphdmEudXRpbC5CaXRTZXQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuY2xhc3NmaWxlLio7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzOwotCi0vKioKLSAqIFJlYWQgY2xhc3MgZmlsZShzKSBhbmQgY29udmVydCB0aGVtIGludG8gSFRNTCBmaWxlcy4KLSAqCi0gKiBHaXZlbiBhIEphdmFDbGFzcyBvYmplY3QgImNsYXNzIiB0aGF0IGlzIGluIHBhY2thZ2UgInBhY2thZ2UiIGZpdmUgZmlsZXMKLSAqIHdpbGwgYmUgY3JlYXRlZCBpbiB0aGUgc3BlY2lmaWVkIGRpcmVjdG9yeS4KLSAqCi0gKiA8T0w+Ci0gKiA8TEk+ICJwYWNrYWdlIi4iY2xhc3MiLmh0bWwgYXMgdGhlIG1haW4gZmlsZSB3aGljaCBkZWZpbmVzIHRoZSBmcmFtZXMgZm9yCi0gKiB0aGUgZm9sbG93aW5nIHN1YmZpbGVzLgotICogPExJPiAgInBhY2thZ2UiLiJjbGFzcyJfYXR0cmlidXRlcy5odG1sIGNvbnRhaW5zIGFsbCAoa25vd24pIGF0dHJpYnV0ZXMgZm91bmQgaW4gdGhlIGZpbGUKLSAqIDxMST4gICJwYWNrYWdlIi4iY2xhc3MiX2NwLmh0bWwgY29udGFpbnMgdGhlIGNvbnN0YW50IHBvb2wKLSAqIDxMST4gICJwYWNrYWdlIi4iY2xhc3MiX2NvZGUuaHRtbCBjb250YWlucyB0aGUgYnl0ZSBjb2RlCi0gKiA8TEk+ICAicGFja2FnZSIuImNsYXNzIl9tZXRob2RzLmh0bWwgY29udGFpbnMgcmVmZXJlbmNlcyB0byBhbGwgbWV0aG9kcyBhbmQgZmllbGRzIG9mIHRoZSBjbGFzcwotICogPC9PTD4KLSAqCi0gKiBBbGwgc3ViZmlsZXMgcmVmZXJlbmNlIGVhY2ggb3RoZXIgYXBwcm9waWF0ZWx5LCBlLmcuIGNsaWNraW5nIG9uIGEKLSAqIG1ldGhvZCBpbiB0aGUgTWV0aG9kJ3MgZnJhbWUgd2lsbCBqdW1wIHRvIHRoZSBhcHByb3BpYXRlIG1ldGhvZCBpbgotICogdGhlIENvZGUgZnJhbWUuCi0gKgotICogQHZlcnNpb24gJElkOiBDbGFzczJIVE1MLmphdmEsdiAxLjMgMjAwNy0wNy0xOSAwNDozNDo1MiBvZnVuZyBFeHAgJAotICogQGF1dGhvciA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotKi8KLXB1YmxpYyBjbGFzcyBDbGFzczJIVE1MIGltcGxlbWVudHMgQ29uc3RhbnRzCi17Ci0gIHByaXZhdGUgSmF2YUNsYXNzIGphdmFfY2xhc3M7ICAgICAvLyBjdXJyZW50IGNsYXNzIG9iamVjdAotICBwcml2YXRlIFN0cmluZyAgICBkaXI7Ci0KLSAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nICAgICAgIGNsYXNzX3BhY2thZ2U7ICAvLyBuYW1lIG9mIHBhY2thZ2UsIHVuY2xlYW4gdG8gbWFrZSBpdCBzdGF0aWMsIGJ1dCAuLi4KLSAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nICAgICAgIGNsYXNzX25hbWU7ICAgICAvLyBuYW1lIG9mIGN1cnJlbnQgY2xhc3MsIGRpdG8KLSAgcHJpdmF0ZSBzdGF0aWMgQ29uc3RhbnRQb29sIGNvbnN0YW50X3Bvb2w7Ci0KLSAgLyoqCi0gICAqIFdyaXRlIGNvbnRlbnRzIG9mIHRoZSBnaXZlbiBKYXZhQ2xhc3MgaW50byBIVE1MIGZpbGVzLgotICAgKgotICAgKiBAcGFyYW0gamF2YV9jbGFzcyBUaGUgY2xhc3MgdG8gd3JpdGUKLSAgICogQHBhcmFtIGRpciBUaGUgZGlyZWN0b3J5IHRvIHB1dCB0aGUgZmlsZXMgaW4KLSAgICovCi0gIHB1YmxpYyBDbGFzczJIVE1MKEphdmFDbGFzcyBqYXZhX2NsYXNzLCBTdHJpbmcgZGlyKSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgIE1ldGhvZFtdICAgICBtZXRob2RzICAgICAgID0gamF2YV9jbGFzcy5nZXRNZXRob2RzKCk7Ci0KLSAgICB0aGlzLmphdmFfY2xhc3MgPSBqYXZhX2NsYXNzOwotICAgIHRoaXMuZGlyICAgICAgICA9IGRpcjsKLSAgICBjbGFzc19uYW1lICAgICAgPSBqYXZhX2NsYXNzLmdldENsYXNzTmFtZSgpOyAgICAgLy8gUmVtZW1iZXIgZnVsbCBuYW1lCi0gICAgY29uc3RhbnRfcG9vbCAgID0gamF2YV9jbGFzcy5nZXRDb25zdGFudFBvb2woKTsKLQotICAgIC8vIEdldCBwYWNrYWdlIG5hbWUgYnkgdGFja2luZyBvZmYgZXZlcnl0aGluZyBhZnRlciB0aGUgbGFzdCBgLicKLSAgICBpbnQgaW5kZXggPSBjbGFzc19uYW1lLmxhc3RJbmRleE9mKCcuJyk7Ci0gICAgaWYoaW5kZXggPiAtMSkKLSAgICAgIGNsYXNzX3BhY2thZ2UgPSBjbGFzc19uYW1lLnN1YnN0cmluZygwLCBpbmRleCk7Ci0gICAgZWxzZQotICAgICAgY2xhc3NfcGFja2FnZSA9ICIiOyAvLyBkZWZhdWx0IHBhY2thZ2UKLQotICAgIENvbnN0YW50SFRNTCBjb25zdGFudF9odG1sID0gbmV3IENvbnN0YW50SFRNTChkaXIsIGNsYXNzX25hbWUsIGNsYXNzX3BhY2thZ2UsIG1ldGhvZHMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0YW50X3Bvb2wpOwotCi0gICAgLyogQXR0cmlidXRlcyBjYW4ndCBiZSB3cml0dGVuIGluIG9uZSBzdGVwLCBzbyB3ZSBqdXN0IG9wZW4gYSBmaWxlCi0gICAgICogd2hpY2ggd2lsbCBiZSB3cml0dGVuIGNvbnNlcXVlbnRseS4KLSAgICAgKi8KLSAgICBBdHRyaWJ1dGVIVE1MIGF0dHJpYnV0ZV9odG1sID0gbmV3IEF0dHJpYnV0ZUhUTUwoZGlyLCBjbGFzc19uYW1lLCBjb25zdGFudF9wb29sLCBjb25zdGFudF9odG1sKTsKLQotICAgIE1ldGhvZEhUTUwgbWV0aG9kX2h0bWwgPSBuZXcgTWV0aG9kSFRNTChkaXIsIGNsYXNzX25hbWUsIG1ldGhvZHMsIGphdmFfY2xhc3MuZ2V0RmllbGRzKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0YW50X2h0bWwsIGF0dHJpYnV0ZV9odG1sKTsKLSAgICAvLyBXcml0ZSBtYWluIGZpbGUgKHdpdGggZnJhbWVzLCB5dWspCi0gICAgd3JpdGVNYWluSFRNTChhdHRyaWJ1dGVfaHRtbCk7Ci0gICAgbmV3IENvZGVIVE1MKGRpciwgY2xhc3NfbmFtZSwgbWV0aG9kcywgY29uc3RhbnRfcG9vbCwgY29uc3RhbnRfaHRtbCk7Ci0gICAgYXR0cmlidXRlX2h0bWwuY2xvc2UoKTsKLSAgfQotCi0gIHB1YmxpYyBzdGF0aWMgdm9pZCBfbWFpbihTdHJpbmcgYXJndltdKQotICB7Ci0gICAgU3RyaW5nW10gICAgZmlsZV9uYW1lID0gbmV3IFN0cmluZ1thcmd2Lmxlbmd0aF07Ci0gICAgaW50ICAgICAgICAgZmlsZXM9MDsKLSAgICBDbGFzc1BhcnNlciBwYXJzZXI9bnVsbDsKLSAgICBKYXZhQ2xhc3MgICBqYXZhX2NsYXNzPW51bGw7Ci0gICAgU3RyaW5nICAgICAgemlwX2ZpbGUgPSBudWxsOwotICAgIGNoYXIgICAgICAgIHNlcCA9IFNlY3VyaXR5U3VwcG9ydC5nZXRTeXN0ZW1Qcm9wZXJ0eSgiZmlsZS5zZXBhcmF0b3IiKS50b0NoYXJBcnJheSgpWzBdOwotICAgIFN0cmluZyAgICAgIGRpciA9ICIuIiArIHNlcDsgLy8gV2hlcmUgdG8gc3RvcmUgSFRNTCBmaWxlcwotCi0gICAgdHJ5IHsKLSAgICAgIC8qIFBhcnNlIGNvbW1hbmQgbGluZSBhcmd1bWVudHMuCi0gICAgICAgKi8KLSAgICAgIGZvcihpbnQgaT0wOyBpIDwgYXJndi5sZW5ndGg7IGkrKykgewotICAgICAgICBpZihhcmd2W2ldLmNoYXJBdCgwKSA9PSAnLScpIHsgIC8vIGNvbW1hbmQgbGluZSBzd2l0Y2gKLSAgICAgICAgICBpZihhcmd2W2ldLmVxdWFscygiLWQiKSkgeyAgIC8vIFNwZWNpZnkgdGFyZ2V0IGRpcmVjdG9yeSwgZGVmYXVsdCAnLicKLSAgICAgICAgICAgIGRpciA9IGFyZ3ZbKytpXTsKLQotICAgICAgICAgICAgaWYoIWRpci5lbmRzV2l0aCgiIiArIHNlcCkpCi0gICAgICAgICAgICAgIGRpciA9IGRpciArIHNlcDsKLQotICAgICAgICAgICAgbmV3IEZpbGUoZGlyKS5ta2RpcnMoKTsgLy8gQ3JlYXRlIHRhcmdldCBkaXJlY3RvcnkgaWYgbmVjZXNzYXJ5Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UgaWYoYXJndltpXS5lcXVhbHMoIi16aXAiKSkKLSAgICAgICAgICAgIHppcF9maWxlID0gYXJndlsrK2ldOwotICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiVW5rbm93biBvcHRpb24gIiArIGFyZ3ZbaV0pOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgLy8gYWRkIGZpbGUgbmFtZSB0byBsaXN0ICovCi0gICAgICAgICAgZmlsZV9uYW1lW2ZpbGVzKytdID0gYXJndltpXTsKLSAgICAgIH0KLQotICAgICAgaWYoZmlsZXMgPT0gMCkKLSAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJDbGFzczJIVE1MOiBObyBpbnB1dCBmaWxlcyBzcGVjaWZpZWQuIik7Ci0gICAgICBlbHNlIHsgLy8gTG9vcCB0aHJvdWdoIGZpbGVzIC4uLgotICAgICAgICBmb3IoaW50IGk9MDsgaSA8IGZpbGVzOyBpKyspIHsKLSAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCJQcm9jZXNzaW5nICIgKyBmaWxlX25hbWVbaV0gKyAiLi4uIik7Ci0gICAgICAgICAgaWYoemlwX2ZpbGUgPT0gbnVsbCkKLSAgICAgICAgICAgIHBhcnNlciA9IG5ldyBDbGFzc1BhcnNlcihmaWxlX25hbWVbaV0pOyAvLyBDcmVhdGUgcGFyc2VyIG9iamVjdCBmcm9tIGZpbGUKLSAgICAgICAgICBlbHNlCi0gICAgICAgICAgICBwYXJzZXIgPSBuZXcgQ2xhc3NQYXJzZXIoemlwX2ZpbGUsIGZpbGVfbmFtZVtpXSk7IC8vIENyZWF0ZSBwYXJzZXIgb2JqZWN0IGZyb20gemlwIGZpbGUKLQotICAgICAgICAgIGphdmFfY2xhc3MgPSBwYXJzZXIucGFyc2UoKTsKLSAgICAgICAgICBuZXcgQ2xhc3MySFRNTChqYXZhX2NsYXNzLCBkaXIpOwotICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiRG9uZS4iKTsKLSAgICAgICAgfQotICAgICAgfQotICAgIH0gY2F0Y2goRXhjZXB0aW9uIGUpIHsKLSAgICAgIFN5c3RlbS5vdXQucHJpbnRsbihlKTsKLSAgICAgIGUucHJpbnRTdGFja1RyYWNlKFN5c3RlbS5vdXQpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBVdGlsaXR5IG1ldGhvZCB0aGF0IGNvbnZlcnRzIGEgY2xhc3MgcmVmZXJlbmNlIGluIHRoZSBjb25zdGFudCBwb29sLAotICAgKiBpLmUuLCBhbiBpbmRleCB0byBhIHN0cmluZy4KLSAgICovCi0gIHN0YXRpYyBTdHJpbmcgcmVmZXJlbmNlQ2xhc3MoaW50IGluZGV4KSB7Ci0gICAgU3RyaW5nIHN0ciA9IGNvbnN0YW50X3Bvb2wuZ2V0Q29uc3RhbnRTdHJpbmcoaW5kZXgsIENPTlNUQU5UX0NsYXNzKTsKLSAgICBzdHIgPSBVdGlsaXR5LmNvbXBhY3RDbGFzc05hbWUoc3RyKTsKLSAgICBzdHIgPSBVdGlsaXR5LmNvbXBhY3RDbGFzc05hbWUoc3RyLCBjbGFzc19wYWNrYWdlICsgIi4iLCB0cnVlKTsKLQotICAgIHJldHVybiAiPEEgSFJFRj1cIiIgKyBjbGFzc19uYW1lICsgIl9jcC5odG1sI2NwIiArIGluZGV4ICsKLSAgICAgICJcIiBUQVJHRVQ9Q29uc3RhbnRQb29sPiIgKyBzdHIgKyAiPC9BPiI7Ci0gIH0KLQotICBzdGF0aWMgZmluYWwgU3RyaW5nIHJlZmVyZW5jZVR5cGUoU3RyaW5nIHR5cGUpIHsKLSAgICBTdHJpbmcgc2hvcnRfdHlwZSA9IFV0aWxpdHkuY29tcGFjdENsYXNzTmFtZSh0eXBlKTsKLSAgICBzaG9ydF90eXBlID0gVXRpbGl0eS5jb21wYWN0Q2xhc3NOYW1lKHNob3J0X3R5cGUsIGNsYXNzX3BhY2thZ2UgKyAiLiIsIHRydWUpOwotCi0gICAgaW50IGluZGV4ID0gdHlwZS5pbmRleE9mKCdbJyk7IC8vIFR5cGUgaXMgYW4gYXJyYXk/Ci0gICAgaWYoaW5kZXggPiAtMSkKLSAgICAgIHR5cGUgPSB0eXBlLnN1YnN0cmluZygwLCBpbmRleCk7IC8vIFRhY2sgb2YgdGhlIGBbJwotCi0gICAgLy8gdGVzdCBmb3IgYmFzaWMgdHlwZQotICAgIGlmKHR5cGUuZXF1YWxzKCJpbnQiKSAgfHwgdHlwZS5lcXVhbHMoInNob3J0IikgfHwgdHlwZS5lcXVhbHMoImJvb2xlYW4iKSB8fCB0eXBlLmVxdWFscygidm9pZCIpICAgfHwKLSAgICAgICB0eXBlLmVxdWFscygiY2hhciIpIHx8IHR5cGUuZXF1YWxzKCJieXRlIikgIHx8IHR5cGUuZXF1YWxzKCJsb25nIikgICAgfHwgdHlwZS5lcXVhbHMoImRvdWJsZSIpIHx8Ci0gICAgICAgdHlwZS5lcXVhbHMoImZsb2F0IikpCi0gICAgICByZXR1cm4gIjxGT05UIENPTE9SPVwiIzAwRkYwMFwiPiIgKyB0eXBlICsgIjwvRk9OVD4iOwotICAgIGVsc2UKLSAgICAgIHJldHVybiAiPEEgSFJFRj1cIiIgKyB0eXBlICsgIi5odG1sXCIgVEFSR0VUPV90b3A+IiArIHNob3J0X3R5cGUgKyAiPC9BPiI7Ci0gIH0KLQotICBzdGF0aWMgU3RyaW5nIHRvSFRNTChTdHJpbmcgc3RyKSB7Ci0gICAgU3RyaW5nQnVmZmVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLQotICAgIHRyeSB7IC8vIEZpbHRlciBhbnkgY2hhcmFjdGVycyBIVE1MIGRvZXNuJ3QgbGlrZSBzdWNoIGFzIDwgYW5kID4gaW4gcGFydGljdWxhcgotICAgICAgZm9yKGludCBpPTA7IGkgPCBzdHIubGVuZ3RoKCk7IGkrKykgewotICAgICAgICBjaGFyIGNoOwotCi0gICAgICAgIHN3aXRjaChjaD1zdHIuY2hhckF0KGkpKSB7Ci0gICAgICAgIGNhc2UgJzwnOiBidWYuYXBwZW5kKCImbHQ7Iik7IGJyZWFrOwotICAgICAgICBjYXNlICc+JzogYnVmLmFwcGVuZCgiJmd0OyIpOyBicmVhazsKLSAgICAgICAgY2FzZSAnXG4nOiBidWYuYXBwZW5kKCJcXG4iKTsgYnJlYWs7Ci0gICAgICAgIGNhc2UgJ1xyJzogYnVmLmFwcGVuZCgiXFxyIik7IGJyZWFrOwotICAgICAgICBkZWZhdWx0OiAgYnVmLmFwcGVuZChjaCk7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICB9IGNhdGNoKFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkge30gLy8gTmV2ZXIgb2NjdXJzCi0KLSAgICByZXR1cm4gYnVmLnRvU3RyaW5nKCk7Ci0gIH0KLQotICBwcml2YXRlIHZvaWQgd3JpdGVNYWluSFRNTChBdHRyaWJ1dGVIVE1MIGF0dHJpYnV0ZV9odG1sKSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgIFByaW50V3JpdGVyIGZpbGUgICAgICAgPSBuZXcgUHJpbnRXcml0ZXIobmV3IEZpbGVPdXRwdXRTdHJlYW0oZGlyICsgY2xhc3NfbmFtZSArICIuaHRtbCIpKTsKLSAgICBBdHRyaWJ1dGVbXSBhdHRyaWJ1dGVzID0gamF2YV9jbGFzcy5nZXRBdHRyaWJ1dGVzKCk7Ci0KLSAgICBmaWxlLnByaW50bG4oIjxIVE1MPlxuIiArICI8SEVBRD48VElUTEU+RG9jdW1lbnRhdGlvbiBmb3IgIiArIGNsYXNzX25hbWUgKyAiPC9USVRMRT4iICsKLSAgICAgICAgICAgICAgICAgIjwvSEVBRD5cbiIgKwotICAgICAgICAgICAgICAgICAiPEZSQU1FU0VUIEJPUkRFUj0xIGNvbHM9XCIzMCUsKlwiPlxuIiArCi0gICAgICAgICAgICAgICAgICI8RlJBTUVTRVQgQk9SREVSPTEgcm93cz1cIjgwJSwqXCI+XG4iICsKLQotICAgICAgICAgICAgICAgICAiPEZSQU1FIE5BTUU9XCJDb25zdGFudFBvb2xcIiBTUkM9XCIiICsgY2xhc3NfbmFtZSArICJfY3AuaHRtbCIgKyAiXCJcbiBNQVJHSU5XSURUSD1cIjBcIiAiICsKLSAgICAgICAgICAgICAgICAgIk1BUkdJTkhFSUdIVD1cIjBcIiBGUkFNRUJPUkRFUj1cIjFcIiBTQ1JPTExJTkc9XCJBVVRPXCI+XG4iICsKLSAgICAgICAgICAgICAgICAgIjxGUkFNRSBOQU1FPVwiQXR0cmlidXRlc1wiIFNSQz1cIiIgKyBjbGFzc19uYW1lICsgIl9hdHRyaWJ1dGVzLmh0bWwiICsKLSAgICAgICAgICAgICAgICAgIlwiXG4gTUFSR0lOV0lEVEg9XCIwXCIgIiArCi0gICAgICAgICAgICAgICAgICJNQVJHSU5IRUlHSFQ9XCIwXCIgRlJBTUVCT1JERVI9XCIxXCIgU0NST0xMSU5HPVwiQVVUT1wiPlxuIiArCi0gICAgICAgICAgICAgICAgICI8L0ZSQU1FU0VUPlxuIiArCi0KLSAgICAgICAgICAgICAgICAgIjxGUkFNRVNFVCBCT1JERVI9MSByb3dzPVwiODAlLCpcIj5cbiIgKwotICAgICAgICAgICAgICAgICAiPEZSQU1FIE5BTUU9XCJDb2RlXCIgU1JDPVwiIiArIGNsYXNzX25hbWUgKyAiX2NvZGUuaHRtbFwiXG4gTUFSR0lOV0lEVEg9MCAiICsKLSAgICAgICAgICAgICAgICAgIk1BUkdJTkhFSUdIVD0wIEZSQU1FQk9SREVSPTEgU0NST0xMSU5HPVwiQVVUT1wiPlxuIiArCi0gICAgICAgICAgICAgICAgICI8RlJBTUUgTkFNRT1cIk1ldGhvZHNcIiBTUkM9XCIiICsgY2xhc3NfbmFtZSArICJfbWV0aG9kcy5odG1sXCJcbiBNQVJHSU5XSURUSD0wICIgKwotICAgICAgICAgICAgICAgICAiTUFSR0lOSEVJR0hUPTAgRlJBTUVCT1JERVI9MSBTQ1JPTExJTkc9XCJBVVRPXCI+XG4iICsKLSAgICAgICAgICAgICAgICAgIjwvRlJBTUVTRVQ+PC9GUkFNRVNFVD48L0hUTUw+IgotICAgICAgICAgICAgICAgICApOwotCi0gICAgZmlsZS5jbG9zZSgpOwotCi0gICAgZm9yKGludCBpPTA7IGkgPCBhdHRyaWJ1dGVzLmxlbmd0aDsgaSsrKQotICAgICAgYXR0cmlidXRlX2h0bWwud3JpdGVBdHRyaWJ1dGUoYXR0cmlidXRlc1tpXSwgImNsYXNzIiArIGkpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvdXRpbC9DbGFzc0xvYWRlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL3V0aWwvQ2xhc3NMb2FkZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMWJlNWIzYi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvdXRpbC9DbGFzc0xvYWRlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjI0ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLnV0aWw7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLWltcG9ydCBqYXZhLnV0aWwuSGFzaHRhYmxlOwotaW1wb3J0IGphdmEuaW8uKjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC4qOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmNsYXNzZmlsZS4qOwotCi0vKioKLSAqIDxwPkRyb3AgaW4gcmVwbGFjZW1lbnQgZm9yIHRoZSBzdGFuZGFyZCBjbGFzcyBsb2FkZXIgb2YgdGhlIEpWTS4gWW91IGNhbiB1c2UgaXQKLSAqIGluIGNvbmp1bmN0aW9uIHdpdGggdGhlIEphdmFXcmFwcGVyIHRvIGR5bmFtaWNhbGx5IG1vZGlmeS9jcmVhdGUgY2xhc3NlcwotICogYXMgdGhleSdyZSByZXF1ZXN0ZWQuPC9wPgotICoKLSAqIDxwPlRoaXMgY2xhc3MgbG9hZGVyIHJlY29nbml6ZXMgc3BlY2lhbCByZXF1ZXN0cyBpbiBhIGRpc3RpbmN0Ci0gKiBmb3JtYXQsIGkuZS4sIHdoZW4gdGhlIG5hbWUgb2YgdGhlIHJlcXVlc3RlZCBjbGFzcyBjb250YWlucyB3aXRoCi0gKiAiJCRCQ0VMJCQiIGl0IGNhbGxzIHRoZSBjcmVhdGVDbGFzcygpIG1ldGhvZCB3aXRoIHRoYXQgbmFtZQotICogKGV2ZXJ5dGhpbmcgYmV2b3IgdGhlICQkQkNFTCQkIGlzIGNvbnNpZGVyZWQgdG8gYmUgdGhlIHBhY2thZ2UKLSAqIG5hbWUuIFlvdSBjYW4gc3ViY2xhc3MgdGhlIGNsYXNzIGxvYWRlciBhbmQgb3ZlcnJpZGUgdGhhdAotICogbWV0aG9kLiAiTm9ybWFsIiBjbGFzc2VzIGNsYXNzIGNhbiBiZSBtb2RpZmllZCBieSBvdmVycmlkaW5nIHRoZQotICogbW9kaWZ5Q2xhc3MoKSBtZXRob2Qgd2hpY2ggaXMgY2FsbGVkIGp1c3QgYmVmb3JlIGRlZmluZUNsYXNzKCkuPC9wPgotICoKLSAqIDxwPlRoZXJlIG1heSBiZSBhIG51bWJlciBvZiBwYWNrYWdlcyB3aGVyZSB5b3UgaGF2ZSB0byB1c2UgdGhlIGRlZmF1bHQKLSAqIGNsYXNzIGxvYWRlciAod2hpY2ggbWF5IGFsc28gYmUgZmFzdGVyKS4gWW91IGNhbiBkZWZpbmUgdGhlIHNldCBvZiBwYWNrYWdlcwotICogd2hlcmUgdG8gdXNlIHRoZSBzeXN0ZW0gY2xhc3MgbG9hZGVyIGluIHRoZSBjb25zdHJ1Y3Rvci4gVGhlIGRlZmF1bHQgdmFsdWUgY29udGFpbnMKLSAqICJqYXZhLiIsICJzdW4uIiwgImphdmF4LiI8L3A+Ci0gKgotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqIEBzZWUgSmF2YVdyYXBwZXIKLSAqIEBzZWUgQ2xhc3NQYXRoCi0gKi8KLXB1YmxpYyBjbGFzcyBDbGFzc0xvYWRlciBleHRlbmRzIGphdmEubGFuZy5DbGFzc0xvYWRlciB7Ci0gIHByaXZhdGUgSGFzaHRhYmxlIGNsYXNzZXMgPSBuZXcgSGFzaHRhYmxlKCk7IC8vIEhhc2h0YWJsZSBpcyBzeW5jaHJvbml6ZWQgdGh1cyB0aHJlYWQtc2FmZQotICBwcml2YXRlIFN0cmluZ1tdIGlnbm9yZWRfcGFja2FnZXMgPSB7Ci0gICAgImphdmEuIiwgImphdmF4LiIsICJzdW4uIgotICB9OwotICBwcml2YXRlIFJlcG9zaXRvcnkgcmVwb3NpdG9yeSA9IFN5bnRoZXRpY1JlcG9zaXRvcnkuZ2V0SW5zdGFuY2UoKTsKLSAgcHJpdmF0ZSBqYXZhLmxhbmcuQ2xhc3NMb2FkZXIgZGVmZXJUbyA9IENsYXNzTG9hZGVyLmdldFN5c3RlbUNsYXNzTG9hZGVyKCk7Ci0KLSAgcHVibGljIENsYXNzTG9hZGVyKCkgewotICB9Ci0KLSAgcHVibGljIENsYXNzTG9hZGVyKGphdmEubGFuZy5DbGFzc0xvYWRlciBkZWZlclRvKSB7Ci0gICAgdGhpcy5kZWZlclRvID0gZGVmZXJUbzsKLSAgICB0aGlzLnJlcG9zaXRvcnkgPSBuZXcgQ2xhc3NMb2FkZXJSZXBvc2l0b3J5KGRlZmVyVG8pOwotICB9Ci0KLSAgLyoqIEBwYXJhbSBpZ25vcmVkX3BhY2thZ2VzIGNsYXNzZXMgY29udGFpbmVkIGluIHRoZXNlIHBhY2thZ2VzIHdpbGwgYmUgbG9hZGVkCi0gICAqIHdpdGggdGhlIHN5c3RlbSBjbGFzcyBsb2FkZXIKLSAgICovCi0gIHB1YmxpYyBDbGFzc0xvYWRlcihTdHJpbmdbXSBpZ25vcmVkX3BhY2thZ2VzKSB7Ci0gICAgYWRkSWdub3JlZFBrZ3MoaWdub3JlZF9wYWNrYWdlcyk7Ci0gIH0KLQotICBwdWJsaWMgQ2xhc3NMb2FkZXIoamF2YS5sYW5nLkNsYXNzTG9hZGVyIGRlZmVyVG8sIFN0cmluZyBbXSBpZ25vcmVkX3BhY2thZ2VzKSB7Ci0gICAgdGhpcy5kZWZlclRvID0gZGVmZXJUbzsKLSAgICB0aGlzLnJlcG9zaXRvcnkgPSBuZXcgQ2xhc3NMb2FkZXJSZXBvc2l0b3J5KGRlZmVyVG8pOwotCi0gICAgYWRkSWdub3JlZFBrZ3MoaWdub3JlZF9wYWNrYWdlcyk7Ci0gIH0KLQotICBwcml2YXRlIHZvaWQgYWRkSWdub3JlZFBrZ3MoU3RyaW5nW10gaWdub3JlZF9wYWNrYWdlcykgewotICAgIFN0cmluZ1tdIG5ld19wID0gbmV3IFN0cmluZ1tpZ25vcmVkX3BhY2thZ2VzLmxlbmd0aCArIHRoaXMuaWdub3JlZF9wYWNrYWdlcy5sZW5ndGhdOwotCi0gICAgU3lzdGVtLmFycmF5Y29weSh0aGlzLmlnbm9yZWRfcGFja2FnZXMsIDAsIG5ld19wLCAwLCB0aGlzLmlnbm9yZWRfcGFja2FnZXMubGVuZ3RoKTsKLSAgICBTeXN0ZW0uYXJyYXljb3B5KGlnbm9yZWRfcGFja2FnZXMsIDAsIG5ld19wLCB0aGlzLmlnbm9yZWRfcGFja2FnZXMubGVuZ3RoLAotICAgICAgICAgICAgICAgICAgICAgaWdub3JlZF9wYWNrYWdlcy5sZW5ndGgpOwotCi0gICAgdGhpcy5pZ25vcmVkX3BhY2thZ2VzID0gbmV3X3A7Ci0gIH0KLQotICBwcm90ZWN0ZWQgQ2xhc3MgbG9hZENsYXNzKFN0cmluZyBjbGFzc19uYW1lLCBib29sZWFuIHJlc29sdmUpCi0gICAgdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb24KLSAgewotICAgIENsYXNzIGNsID0gbnVsbDsKLQotICAgIC8qIEZpcnN0IHRyeTogbG9va3VwIGhhc2ggdGFibGUuCi0gICAgICovCi0gICAgaWYoKGNsPShDbGFzcyljbGFzc2VzLmdldChjbGFzc19uYW1lKSkgPT0gbnVsbCkgewotICAgICAgLyogU2Vjb25kIHRyeTogTG9hZCBzeXN0ZW0gY2xhc3MgdXNpbmcgc3lzdGVtIGNsYXNzIGxvYWRlci4gWW91IGJldHRlcgotICAgICAgICogZG9uJ3QgbWVzcyBhcm91bmQgd2l0aCB0aGVtLgotICAgICAgICovCi0gICAgICBmb3IoaW50IGk9MDsgaSA8IGlnbm9yZWRfcGFja2FnZXMubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgaWYoY2xhc3NfbmFtZS5zdGFydHNXaXRoKGlnbm9yZWRfcGFja2FnZXNbaV0pKSB7Ci0gICAgICAgICAgY2wgPSBkZWZlclRvLmxvYWRDbGFzcyhjbGFzc19uYW1lKTsKLSAgICAgICAgICBicmVhazsKLSAgICAgICAgfQotICAgICAgfQotCi0gICAgICBpZihjbCA9PSBudWxsKSB7Ci0gICAgICAgIEphdmFDbGFzcyBjbGF6eiA9IG51bGw7Ci0KLSAgICAgICAgLyogVGhpcmQgdHJ5OiBTcGVjaWFsIHJlcXVlc3Q/Ci0gICAgICAgICAqLwotICAgICAgICBpZihjbGFzc19uYW1lLmluZGV4T2YoIiQkQkNFTCQkIikgPj0gMCkKLSAgICAgICAgICBjbGF6eiA9IGNyZWF0ZUNsYXNzKGNsYXNzX25hbWUpOwotICAgICAgICBlbHNlIHsgLy8gRm91cnRoIHRyeTogTG9hZCBjbGFzc2VzIHZpYSByZXBvc2l0b3J5Ci0gICAgICAgICAgaWYgKChjbGF6eiA9IHJlcG9zaXRvcnkubG9hZENsYXNzKGNsYXNzX25hbWUpKSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBjbGF6eiA9IG1vZGlmeUNsYXNzKGNsYXp6KTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgICAgdGhyb3cgbmV3IENsYXNzTm90Rm91bmRFeGNlcHRpb24oY2xhc3NfbmFtZSk7Ci0gICAgICAgIH0KLQotICAgICAgICBpZihjbGF6eiAhPSBudWxsKSB7Ci0gICAgICAgICAgYnl0ZVtdIGJ5dGVzICA9IGNsYXp6LmdldEJ5dGVzKCk7Ci0gICAgICAgICAgY2wgPSBkZWZpbmVDbGFzcyhjbGFzc19uYW1lLCBieXRlcywgMCwgYnl0ZXMubGVuZ3RoKTsKLSAgICAgICAgfSBlbHNlIC8vIEZvdXJ0aCB0cnk6IFVzZSBkZWZhdWx0IGNsYXNzIGxvYWRlcgotICAgICAgICAgIGNsID0gQ2xhc3MuZm9yTmFtZShjbGFzc19uYW1lKTsKLSAgICAgIH0KLQotICAgICAgaWYocmVzb2x2ZSkKLSAgICAgICAgcmVzb2x2ZUNsYXNzKGNsKTsKLSAgICB9Ci0KLSAgICBjbGFzc2VzLnB1dChjbGFzc19uYW1lLCBjbCk7Ci0KLSAgICByZXR1cm4gY2w7Ci0gIH0KLQotICAvKiogT3ZlcnJpZGUgdGhpcyBtZXRob2QgaWYgeW91IHdhbnQgdG8gYWx0ZXIgYSBjbGFzcyBiZWZvcmUgaXQgZ2V0cyBhY3R1YWxseQotICAgKiBsb2FkZWQuIERvZXMgbm90aGluZyBieSBkZWZhdWx0LgotICAgKi8KLSAgcHJvdGVjdGVkIEphdmFDbGFzcyBtb2RpZnlDbGFzcyhKYXZhQ2xhc3MgY2xhenopIHsKLSAgICByZXR1cm4gY2xheno7Ci0gIH0KLQotICAvKioKLSAgICogT3ZlcnJpZGUgdGhpcyBtZXRob2QgdG8gY3JlYXRlIHlvdSBvd24gY2xhc3NlcyBvbiB0aGUgZmx5LiBUaGUKLSAgICogbmFtZSBjb250YWlucyB0aGUgc3BlY2lhbCB0b2tlbiAkJEJDRUwkJC4gRXZlcnl0aGluZyBiZWZvcmUgdGhhdAotICAgKiB0b2tlbiBpcyBjb25zZGRlcmVkIHRvIGJlIGEgcGFja2FnZSBuYW1lLiBZb3UgY2FuIGVuY29kZSB5b3Ugb3duCi0gICAqIGFyZ3VtZW50cyBpbnRvIHRoZSBzdWJzZXF1ZW50IHN0cmluZy4gWW91IG11c3QgcmVnYXJkIGhvd2V2ZXIgbm90Ci0gICAqIHRvIHVzZSBhbnkgImlsbGVnYWwiIGNoYXJhY3RlcnMsIGkuZS4sIGNoYXJhY3RlcnMgdGhhdCBtYXkgbm90Ci0gICAqIGFwcGVhciBpbiBhIEphdmEgY2xhc3MgbmFtZSB0b288YnI+Ci0gICAqCi0gICAqIFRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIGludGVycHJldHMgdGhlIHN0cmluZyBhcyBhIGVuY29kZWQgY29tcHJlc3NlZAotICAgKiBKYXZhIGNsYXNzLCB1bnBhY2tzIGFuZCBkZWNvZGVzIGl0IHdpdGggdGhlIFV0aWxpdHkuZGVjb2RlKCkgbWV0aG9kLCBhbmQKLSAgICogcGFyc2VzIHRoZSByZXN1bHRpbmcgYnl0ZSBhcnJheSBhbmQgcmV0dXJucyB0aGUgcmVzdWx0aW5nIEphdmFDbGFzcyBvYmplY3QuCi0gICAqCi0gICAqIEBwYXJhbSBjbGFzc19uYW1lIGNvbXByZXNzZWQgYnl0ZSBjb2RlIHdpdGggIiQkQkNFTCQkIiBpbiBpdAotICAgKi8KLSAgcHJvdGVjdGVkIEphdmFDbGFzcyBjcmVhdGVDbGFzcyhTdHJpbmcgY2xhc3NfbmFtZSkgewotICAgIGludCAgICBpbmRleCAgICAgPSBjbGFzc19uYW1lLmluZGV4T2YoIiQkQkNFTCQkIik7Ci0gICAgU3RyaW5nIHJlYWxfbmFtZSA9IGNsYXNzX25hbWUuc3Vic3RyaW5nKGluZGV4ICsgOCk7Ci0KLSAgICBKYXZhQ2xhc3MgY2xhenogPSBudWxsOwotICAgIHRyeSB7Ci0gICAgICBieXRlW10gICAgICBieXRlcyAgPSBVdGlsaXR5LmRlY29kZShyZWFsX25hbWUsIHRydWUpOwotICAgICAgQ2xhc3NQYXJzZXIgcGFyc2VyID0gbmV3IENsYXNzUGFyc2VyKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShieXRlcyksICJmb28iKTsKLQotICAgICAgY2xhenogPSBwYXJzZXIucGFyc2UoKTsKLSAgICB9IGNhdGNoKFRocm93YWJsZSBlKSB7Ci0gICAgICBlLnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLy8gQWRhcHQgdGhlIGNsYXNzIG5hbWUgdG8gdGhlIHBhc3NlZCB2YWx1ZQotICAgIENvbnN0YW50UG9vbCBjcCA9IGNsYXp6LmdldENvbnN0YW50UG9vbCgpOwotCi0gICAgQ29uc3RhbnRDbGFzcyBjbCA9IChDb25zdGFudENsYXNzKWNwLmdldENvbnN0YW50KGNsYXp6LmdldENsYXNzTmFtZUluZGV4KCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbnN0YW50cy5DT05TVEFOVF9DbGFzcyk7Ci0gICAgQ29uc3RhbnRVdGY4IG5hbWUgPSAoQ29uc3RhbnRVdGY4KWNwLmdldENvbnN0YW50KGNsLmdldE5hbWVJbmRleCgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb25zdGFudHMuQ09OU1RBTlRfVXRmOCk7Ci0gICAgbmFtZS5zZXRCeXRlcyhjbGFzc19uYW1lLnJlcGxhY2UoJy4nLCAnLycpKTsKLQotICAgIHJldHVybiBjbGF6ejsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL3V0aWwvQ2xhc3NMb2FkZXJSZXBvc2l0b3J5LmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvdXRpbC9DbGFzc0xvYWRlclJlcG9zaXRvcnkuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZWVjMTBmNC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvdXRpbC9DbGFzc0xvYWRlclJlcG9zaXRvcnkuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE1NyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC51dGlsOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi1pbXBvcnQgamF2YS5pby4qOwotCi1pbXBvcnQgamF2YS51dGlsLk1hcDsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmNsYXNzZmlsZS4qOwotCi0vKioKLSAqIFRoZSByZXBvc2l0b3J5IG1haW50YWlucyBpbmZvcm1hdGlvbiBhYm91dCB3aGljaCBjbGFzc2VzIGhhdmUKLSAqIGJlZW4gbG9hZGVkLgotICoKLSAqIEl0IGxvYWRzIGl0cyBkYXRhIGZyb20gdGhlIENsYXNzTG9hZGVyIGltcGxlbWVudGF0aW9uCi0gKiBwYXNzZWQgaW50byBpdHMgY29uc3RydWN0b3IuCi0gKgotICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5SZXBvc2l0b3J5Ci0gKgotICogQGF1dGhvciA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICogQGF1dGhvciBEYXZpZCBEaXhvbi1QZXVnaAotICovCi1wdWJsaWMgY2xhc3MgQ2xhc3NMb2FkZXJSZXBvc2l0b3J5Ci0gIGltcGxlbWVudHMgUmVwb3NpdG9yeQotewotICBwcml2YXRlIGphdmEubGFuZy5DbGFzc0xvYWRlciBsb2FkZXI7Ci0gIHByaXZhdGUgSGFzaE1hcCBsb2FkZWRDbGFzc2VzID0KLSAgICBuZXcgSGFzaE1hcCgpOyAvLyBDTEFTU05BTUUgWCBKQVZBQ0xBU1MKLQotICBwdWJsaWMgQ2xhc3NMb2FkZXJSZXBvc2l0b3J5KCBqYXZhLmxhbmcuQ2xhc3NMb2FkZXIgbG9hZGVyICkgewotICAgIHRoaXMubG9hZGVyID0gbG9hZGVyOwotICB9Ci0KLSAgLyoqCi0gICAqIFN0b3JlIGEgbmV3IEphdmFDbGFzcyBpbnRvIHRoaXMgUmVwb3NpdG9yeS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHN0b3JlQ2xhc3MoIEphdmFDbGFzcyBjbGF6eiApIHsKLSAgICBsb2FkZWRDbGFzc2VzLnB1dCggY2xhenouZ2V0Q2xhc3NOYW1lKCksCi0gICAgICAgICAgICAgICAgICAgICAgIGNsYXp6ICk7Ci0gICAgY2xhenouc2V0UmVwb3NpdG9yeSggdGhpcyApOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlbW92ZSBjbGFzcyBmcm9tIHJlcG9zaXRvcnkKLSAgICovCi0gIHB1YmxpYyB2b2lkIHJlbW92ZUNsYXNzKEphdmFDbGFzcyBjbGF6eikgewotICAgIGxvYWRlZENsYXNzZXMucmVtb3ZlKGNsYXp6LmdldENsYXNzTmFtZSgpKTsKLSAgfQotCi0gIC8qKgotICAgKiBGaW5kIGFuIGFscmVhZHkgZGVmaW5lZCBKYXZhQ2xhc3MuCi0gICAqLwotICBwdWJsaWMgSmF2YUNsYXNzIGZpbmRDbGFzcyggU3RyaW5nIGNsYXNzTmFtZSApIHsKLSAgICBpZiAoIGxvYWRlZENsYXNzZXMuY29udGFpbnNLZXkoIGNsYXNzTmFtZSApKSB7Ci0gICAgICByZXR1cm4gKEphdmFDbGFzcykgbG9hZGVkQ2xhc3Nlcy5nZXQoIGNsYXNzTmFtZSApOwotICAgIH0gZWxzZSB7Ci0gICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogTG9va3VwIGEgSmF2YUNsYXNzIG9iamVjdCBmcm9tIHRoZSBDbGFzcyBOYW1lIHByb3ZpZGVkLgotICAgKi8KLSAgcHVibGljIEphdmFDbGFzcyBsb2FkQ2xhc3MoIFN0cmluZyBjbGFzc05hbWUgKQotICAgIHRocm93cyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uCi0gIHsKLSAgICBTdHJpbmcgY2xhc3NGaWxlID0gY2xhc3NOYW1lLnJlcGxhY2UoJy4nLCAnLycpOwotCi0gICAgSmF2YUNsYXNzIFJDID0gZmluZENsYXNzKCBjbGFzc05hbWUgKTsKLSAgICBpZiAoUkMgIT0gbnVsbCkgeyByZXR1cm4gUkM7IH0KLQotICAgIHRyeSB7Ci0gICAgICBJbnB1dFN0cmVhbSBpcyA9Ci0gICAgICAgIGxvYWRlci5nZXRSZXNvdXJjZUFzU3RyZWFtKCBjbGFzc0ZpbGUgKyAiLmNsYXNzIiApOwotCi0gICAgICBpZihpcyA9PSBudWxsKSB7Ci0gICAgICAgIHRocm93IG5ldyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uKGNsYXNzTmFtZSArICIgbm90IGZvdW5kLiIpOwotICAgICAgfQotCi0gICAgICBDbGFzc1BhcnNlciBwYXJzZXIgPSBuZXcgQ2xhc3NQYXJzZXIoIGlzLCBjbGFzc05hbWUgKTsKLSAgICAgIFJDID0gcGFyc2VyLnBhcnNlKCk7Ci0KLSAgICAgIHN0b3JlQ2xhc3MoIFJDICk7Ci0KLSAgICAgIHJldHVybiBSQzsKLSAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7Ci0gICAgICB0aHJvdyBuZXcgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiggZS50b1N0cmluZygpICk7Ci0gICAgfQotICB9Ci0KLSAgcHVibGljIEphdmFDbGFzcyBsb2FkQ2xhc3MoQ2xhc3MgY2xhenopIHRocm93cyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHsKLSAgICByZXR1cm4gbG9hZENsYXNzKGNsYXp6LmdldE5hbWUoKSk7Ci0gIH0KLQotICAvKiogQ2xlYXIgYWxsIGVudHJpZXMgZnJvbSBjYWNoZS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGNsZWFyKCkgewotICAgIGxvYWRlZENsYXNzZXMuY2xlYXIoKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL3V0aWwvQ2xhc3NQYXRoLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvdXRpbC9DbGFzc1BhdGguamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMGNkNTAyMS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvdXRpbC9DbGFzc1BhdGguamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDM4NCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC51dGlsOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi1pbXBvcnQgamF2YS51dGlsLio7Ci1pbXBvcnQgamF2YS51dGlsLnppcC4qOwotaW1wb3J0IGphdmEuaW8uKjsKLQotLyoqCi0gKiBSZXNwb25zaWJsZSBmb3IgbG9hZGluZyAoY2xhc3MpIGZpbGVzIGZyb20gdGhlIENMQVNTUEFUSC4gSW5zcGlyZWQgYnkKLSAqIHN1bi50b29scy5DbGFzc1BhdGguCi0gKgotICogQHZlcnNpb24gJElkOiBDbGFzc1BhdGguamF2YSx2IDEuNCAyMDA3LTA3LTE5IDA0OjM0OjUyIG9mdW5nIEV4cCAkCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICovCi1wdWJsaWMgY2xhc3MgQ2xhc3NQYXRoIGltcGxlbWVudHMgU2VyaWFsaXphYmxlIHsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBDbGFzc1BhdGggU1lTVEVNX0NMQVNTX1BBVEggPSBuZXcgQ2xhc3NQYXRoKCk7Ci0KLSAgcHJpdmF0ZSBQYXRoRW50cnlbXSBwYXRoczsKLSAgcHJpdmF0ZSBTdHJpbmcgICAgICBjbGFzc19wYXRoOwotCi0gIC8qKgotICAgKiBTZWFyY2ggZm9yIGNsYXNzZXMgaW4gZ2l2ZW4gcGF0aC4KLSAgICovCi0gIHB1YmxpYyBDbGFzc1BhdGgoU3RyaW5nIGNsYXNzX3BhdGgpIHsKLSAgICB0aGlzLmNsYXNzX3BhdGggPSBjbGFzc19wYXRoOwotCi0gICAgQXJyYXlMaXN0IHZlYyA9IG5ldyBBcnJheUxpc3QoKTsKLQotICAgIGZvcihTdHJpbmdUb2tlbml6ZXIgdG9rPW5ldyBTdHJpbmdUb2tlbml6ZXIoY2xhc3NfcGF0aCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZWN1cml0eVN1cHBvcnQuZ2V0U3lzdGVtUHJvcGVydHkoInBhdGguc2VwYXJhdG9yIikpOwotICAgICAgICB0b2suaGFzTW9yZVRva2VucygpOykKLSAgICB7Ci0gICAgICBTdHJpbmcgcGF0aCA9IHRvay5uZXh0VG9rZW4oKTsKLQotICAgICAgaWYoIXBhdGguZXF1YWxzKCIiKSkgewotICAgICAgICBGaWxlIGZpbGUgPSBuZXcgRmlsZShwYXRoKTsKLQotICAgICAgICB0cnkgewotICAgICAgICAgIGlmKFNlY3VyaXR5U3VwcG9ydC5nZXRGaWxlRXhpc3RzKGZpbGUpKSB7Ci0gICAgICAgICAgICBpZihmaWxlLmlzRGlyZWN0b3J5KCkpCi0gICAgICAgICAgICAgIHZlYy5hZGQobmV3IERpcihwYXRoKSk7Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgIHZlYy5hZGQobmV3IFppcChuZXcgWmlwRmlsZShmaWxlKSkpOwotICAgICAgICAgIH0KLSAgICAgICAgfSBjYXRjaChJT0V4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJDTEFTU1BBVEggY29tcG9uZW50ICIgKyBmaWxlICsgIjogIiArIGUpOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotCi0gICAgcGF0aHMgPSBuZXcgUGF0aEVudHJ5W3ZlYy5zaXplKCldOwotICAgIHZlYy50b0FycmF5KHBhdGhzKTsKLSAgfQotCi0gIC8qKgotICAgKiBTZWFyY2ggZm9yIGNsYXNzZXMgaW4gQ0xBU1NQQVRILgotICAgKiBAZGVwcmVjYXRlZCBVc2UgU1lTVEVNX0NMQVNTX1BBVEggY29uc3RhbnQKLSAgICovCi0gIHB1YmxpYyBDbGFzc1BhdGgoKSB7Ci0gICAgLy8gdGhpcyhnZXRDbGFzc1BhdGgoKSk7Ci0gICAgdGhpcygiIik7Ci0gIH0KLQotICAvKiogQHJldHVybiB1c2VkIGNsYXNzIHBhdGggc3RyaW5nCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgIHJldHVybiBjbGFzc19wYXRoOwotICB9Ci0KLSAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKLSAgICByZXR1cm4gY2xhc3NfcGF0aC5oYXNoQ29kZSgpOwotICB9Ci0KLSAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvKSB7Ci0gICAgaWYobyBpbnN0YW5jZW9mIENsYXNzUGF0aCkgewotICAgICAgcmV0dXJuIGNsYXNzX3BhdGguZXF1YWxzKCgoQ2xhc3NQYXRoKW8pLmNsYXNzX3BhdGgpOwotICAgIH0KLQotICAgIHJldHVybiBmYWxzZTsKLSAgfQotCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIHZvaWQgZ2V0UGF0aENvbXBvbmVudHMoU3RyaW5nIHBhdGgsIEFycmF5TGlzdCBsaXN0KSB7Ci0gICAgaWYocGF0aCAhPSBudWxsKSB7Ci0gICAgICBTdHJpbmdUb2tlbml6ZXIgdG9rID0gbmV3IFN0cmluZ1Rva2VuaXplcihwYXRoLCBGaWxlLnBhdGhTZXBhcmF0b3IpOwotCi0gICAgICB3aGlsZSh0b2suaGFzTW9yZVRva2VucygpKSB7Ci0gICAgICAgIFN0cmluZyBuYW1lID0gdG9rLm5leHRUb2tlbigpOwotICAgICAgICBGaWxlICAgZmlsZSA9IG5ldyBGaWxlKG5hbWUpOwotCi0gICAgICAgIGlmKFNlY3VyaXR5U3VwcG9ydC5nZXRGaWxlRXhpc3RzKGZpbGUpKSB7Ci0gICAgICAgICAgbGlzdC5hZGQobmFtZSk7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICB9Ci0gIH0KLQotICAvKiogQ2hlY2tzIGZvciBjbGFzcyBwYXRoIGNvbXBvbmVudHMgaW4gdGhlIGZvbGxvd2luZyBwcm9wZXJ0aWVzOgotICAgKiAiamF2YS5jbGFzcy5wYXRoIiwgInN1bi5ib290LmNsYXNzLnBhdGgiLCAiamF2YS5leHQuZGlycyIKLSAgICoKLSAgICogQHJldHVybiBjbGFzcyBwYXRoIGFzIHVzZWQgYnkgZGVmYXVsdCBieSBCQ0VMCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBnZXRDbGFzc1BhdGgoKSB7Ci0KLSAgICBTdHJpbmcgY2xhc3NfcGF0aCwgYm9vdF9wYXRoLCBleHRfcGF0aDsKLQotICAgIHRyeSB7Ci0gICAgICBjbGFzc19wYXRoID0gU2VjdXJpdHlTdXBwb3J0LmdldFN5c3RlbVByb3BlcnR5KCJqYXZhLmNsYXNzLnBhdGgiKTsKLSAgICAgIGJvb3RfcGF0aCAgPSBTZWN1cml0eVN1cHBvcnQuZ2V0U3lzdGVtUHJvcGVydHkoInN1bi5ib290LmNsYXNzLnBhdGgiKTsKLSAgICAgIGV4dF9wYXRoICAgPSBTZWN1cml0eVN1cHBvcnQuZ2V0U3lzdGVtUHJvcGVydHkoImphdmEuZXh0LmRpcnMiKTsKLSAgICB9Ci0gICAgY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIGUpIHsKLSAgICAgICAgcmV0dXJuICIiOwotICAgIH0KLQotICAgIEFycmF5TGlzdCBsaXN0ID0gbmV3IEFycmF5TGlzdCgpOwotCi0gICAgZ2V0UGF0aENvbXBvbmVudHMoY2xhc3NfcGF0aCwgbGlzdCk7Ci0gICAgZ2V0UGF0aENvbXBvbmVudHMoYm9vdF9wYXRoLCBsaXN0KTsKLQotICAgIEFycmF5TGlzdCBkaXJzID0gbmV3IEFycmF5TGlzdCgpOwotICAgIGdldFBhdGhDb21wb25lbnRzKGV4dF9wYXRoLCBkaXJzKTsKLQotICAgIGZvcihJdGVyYXRvciBlID0gZGlycy5pdGVyYXRvcigpOyBlLmhhc05leHQoKTsgKSB7Ci0gICAgICBGaWxlIGV4dF9kaXIgPSBuZXcgRmlsZSgoU3RyaW5nKWUubmV4dCgpKTsKLSAgICAgIFN0cmluZ1tdIGV4dGVuc2lvbnMgPSBTZWN1cml0eVN1cHBvcnQuZ2V0RmlsZUxpc3QoZXh0X2RpciwgbmV3IEZpbGVuYW1lRmlsdGVyKCkgewotICAgICAgICBwdWJsaWMgYm9vbGVhbiBhY2NlcHQoRmlsZSBkaXIsIFN0cmluZyBuYW1lKSB7Ci0gICAgICAgICAgbmFtZSA9IG5hbWUudG9Mb3dlckNhc2UoKTsKLSAgICAgICAgICByZXR1cm4gbmFtZS5lbmRzV2l0aCgiLnppcCIpIHx8IG5hbWUuZW5kc1dpdGgoIi5qYXIiKTsKLSAgICAgICAgfQotICAgICAgfSk7Ci0KLSAgICAgIGlmKGV4dGVuc2lvbnMgIT0gbnVsbCkKLSAgICAgICAgZm9yKGludCBpPTA7IGkgPCBleHRlbnNpb25zLmxlbmd0aDsgaSsrKQotICAgICAgICAgIGxpc3QuYWRkKGV4dF9wYXRoICsgRmlsZS5zZXBhcmF0b3JDaGFyICsgZXh0ZW5zaW9uc1tpXSk7Ci0gICAgfQotCi0gICAgU3RyaW5nQnVmZmVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLQotICAgIGZvcihJdGVyYXRvciBlID0gbGlzdC5pdGVyYXRvcigpOyBlLmhhc05leHQoKTsgKSB7Ci0gICAgICBidWYuYXBwZW5kKChTdHJpbmcpZS5uZXh0KCkpOwotCi0gICAgICBpZihlLmhhc05leHQoKSkKLSAgICAgICAgYnVmLmFwcGVuZChGaWxlLnBhdGhTZXBhcmF0b3JDaGFyKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gYnVmLnRvU3RyaW5nKCkuaW50ZXJuKCk7Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIG5hbWUgZnVsbHkgcXVhbGlmaWVkIGNsYXNzIG5hbWUsIGUuZy4gamF2YS5sYW5nLlN0cmluZwotICAgKiBAcmV0dXJuIGlucHV0IHN0cmVhbSBmb3IgY2xhc3MKLSAgICovCi0gIHB1YmxpYyBJbnB1dFN0cmVhbSBnZXRJbnB1dFN0cmVhbShTdHJpbmcgbmFtZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLSAgICByZXR1cm4gZ2V0SW5wdXRTdHJlYW0obmFtZSwgIi5jbGFzcyIpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiBzdHJlYW0gZm9yIGNsYXNzIG9yIHJlc291cmNlIG9uIENMQVNTUEFUSC4KLSAgICoKLSAgICogQHBhcmFtIG5hbWUgZnVsbHkgcXVhbGlmaWVkIGZpbGUgbmFtZSwgZS5nLiBqYXZhL2xhbmcvU3RyaW5nCi0gICAqIEBwYXJhbSBzdWZmaXggZmlsZSBuYW1lIGVuZHMgd2l0aCBzdWZmLCBlLmcuIC5qYXZhCi0gICAqIEByZXR1cm4gaW5wdXQgc3RyZWFtIGZvciBmaWxlIG9uIGNsYXNzIHBhdGgKLSAgICovCi0gIHB1YmxpYyBJbnB1dFN0cmVhbSBnZXRJbnB1dFN0cmVhbShTdHJpbmcgbmFtZSwgU3RyaW5nIHN1ZmZpeCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLSAgICBJbnB1dFN0cmVhbSBpcyA9IG51bGw7Ci0KLSAgICB0cnkgewotICAgICAgaXMgPSBnZXRDbGFzcygpLmdldENsYXNzTG9hZGVyKCkuZ2V0UmVzb3VyY2VBc1N0cmVhbShuYW1lICsgc3VmZml4KTsKLSAgICB9IGNhdGNoKEV4Y2VwdGlvbiBlKSB7IH0KLQotICAgIGlmKGlzICE9IG51bGwpCi0gICAgICByZXR1cm4gaXM7Ci0KLSAgICByZXR1cm4gZ2V0Q2xhc3NGaWxlKG5hbWUsIHN1ZmZpeCkuZ2V0SW5wdXRTdHJlYW0oKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gbmFtZSBmdWxseSBxdWFsaWZpZWQgZmlsZSBuYW1lLCBlLmcuIGphdmEvbGFuZy9TdHJpbmcKLSAgICogQHBhcmFtIHN1ZmZpeCBmaWxlIG5hbWUgZW5kcyB3aXRoIHN1ZmYsIGUuZy4gLmphdmEKLSAgICogQHJldHVybiBjbGFzcyBmaWxlIGZvciB0aGUgamF2YSBjbGFzcwotICAgKi8KLSAgcHVibGljIENsYXNzRmlsZSBnZXRDbGFzc0ZpbGUoU3RyaW5nIG5hbWUsIFN0cmluZyBzdWZmaXgpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgZm9yKGludCBpPTA7IGkgPCBwYXRocy5sZW5ndGg7IGkrKykgewotICAgICAgQ2xhc3NGaWxlIGNmOwotCi0gICAgICBpZigoY2YgPSBwYXRoc1tpXS5nZXRDbGFzc0ZpbGUobmFtZSwgc3VmZml4KSkgIT0gbnVsbCkKLSAgICAgICAgcmV0dXJuIGNmOwotICAgIH0KLQotICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiQ291bGRuJ3QgZmluZDogIiArIG5hbWUgKyBzdWZmaXgpOwotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBuYW1lIGZ1bGx5IHF1YWxpZmllZCBjbGFzcyBuYW1lLCBlLmcuIGphdmEubGFuZy5TdHJpbmcKLSAgICogQHJldHVybiBpbnB1dCBzdHJlYW0gZm9yIGNsYXNzCi0gICAqLwotICBwdWJsaWMgQ2xhc3NGaWxlIGdldENsYXNzRmlsZShTdHJpbmcgbmFtZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLSAgICByZXR1cm4gZ2V0Q2xhc3NGaWxlKG5hbWUsICIuY2xhc3MiKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gbmFtZSBmdWxseSBxdWFsaWZpZWQgZmlsZSBuYW1lLCBlLmcuIGphdmEvbGFuZy9TdHJpbmcKLSAgICogQHBhcmFtIHN1ZmZpeCBmaWxlIG5hbWUgZW5kcyB3aXRoIHN1ZmZpeCwgZS5nLiAuamF2YQotICAgKiBAcmV0dXJuIGJ5dGUgYXJyYXkgZm9yIGZpbGUgb24gY2xhc3MgcGF0aAotICAgKi8KLSAgcHVibGljIGJ5dGVbXSBnZXRCeXRlcyhTdHJpbmcgbmFtZSwgU3RyaW5nIHN1ZmZpeCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLSAgICBJbnB1dFN0cmVhbSBpcyA9IGdldElucHV0U3RyZWFtKG5hbWUsIHN1ZmZpeCk7Ci0KLSAgICBpZihpcyA9PSBudWxsKQotICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJDb3VsZG4ndCBmaW5kOiAiICsgbmFtZSArIHN1ZmZpeCk7Ci0KLSAgICBEYXRhSW5wdXRTdHJlYW0gZGlzICAgPSBuZXcgRGF0YUlucHV0U3RyZWFtKGlzKTsKLSAgICBieXRlW10gICAgICAgICAgYnl0ZXMgPSBuZXcgYnl0ZVtpcy5hdmFpbGFibGUoKV07Ci0gICAgZGlzLnJlYWRGdWxseShieXRlcyk7Ci0gICAgZGlzLmNsb3NlKCk7IGlzLmNsb3NlKCk7Ci0KLSAgICByZXR1cm4gYnl0ZXM7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBieXRlIGFycmF5IGZvciBjbGFzcwotICAgKi8KLSAgcHVibGljIGJ5dGVbXSBnZXRCeXRlcyhTdHJpbmcgbmFtZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLSAgICByZXR1cm4gZ2V0Qnl0ZXMobmFtZSwgIi5jbGFzcyIpOwotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBuYW1lIG5hbWUgb2YgZmlsZSB0byBzZWFyY2ggZm9yLCBlLmcuIGphdmEvbGFuZy9TdHJpbmcuamF2YQotICAgKiBAcmV0dXJuIGZ1bGwgKGNhbm9uaWNhbCkgcGF0aCBmb3IgZmlsZQotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRQYXRoKFN0cmluZyBuYW1lKSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgIGludCAgICBpbmRleCAgPSBuYW1lLmxhc3RJbmRleE9mKCcuJyk7Ci0gICAgU3RyaW5nIHN1ZmZpeCA9ICIiOwotCi0gICAgaWYoaW5kZXggPiAwKSB7Ci0gICAgICBzdWZmaXggPSBuYW1lLnN1YnN0cmluZyhpbmRleCk7Ci0gICAgICBuYW1lICAgPSBuYW1lLnN1YnN0cmluZygwLCBpbmRleCk7Ci0gICAgfQotCi0gICAgcmV0dXJuIGdldFBhdGgobmFtZSwgc3VmZml4KTsKLSAgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gbmFtZSBuYW1lIG9mIGZpbGUgdG8gc2VhcmNoIGZvciwgZS5nLiBqYXZhL2xhbmcvU3RyaW5nCi0gICAqIEBwYXJhbSBzdWZmaXggZmlsZSBuYW1lIHN1ZmZpeCwgZS5nLiAuamF2YQotICAgKiBAcmV0dXJuIGZ1bGwgKGNhbm9uaWNhbCkgcGF0aCBmb3IgZmlsZSwgaWYgaXQgZXhpc3RzCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFBhdGgoU3RyaW5nIG5hbWUsIFN0cmluZyBzdWZmaXgpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgcmV0dXJuIGdldENsYXNzRmlsZShuYW1lLCBzdWZmaXgpLmdldFBhdGgoKTsKLSAgfQotCi0gIHByaXZhdGUgc3RhdGljIGFic3RyYWN0IGNsYXNzIFBhdGhFbnRyeSBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZSB7Ci0gICAgYWJzdHJhY3QgQ2xhc3NGaWxlIGdldENsYXNzRmlsZShTdHJpbmcgbmFtZSwgU3RyaW5nIHN1ZmZpeCkgdGhyb3dzIElPRXhjZXB0aW9uOwotICB9Ci0KLSAgLyoqIENvbnRhaW5zIGluZm9ybWF0aW9uIGFib3V0IGZpbGUvWklQIGVudHJ5IG9mIHRoZSBKYXZhIGNsYXNzLgotICAgKi8KLSAgcHVibGljIGludGVyZmFjZSBDbGFzc0ZpbGUgewotICAgIC8qKiBAcmV0dXJuIGlucHV0IHN0cmVhbSBmb3IgY2xhc3MgZmlsZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3QgSW5wdXRTdHJlYW0gZ2V0SW5wdXRTdHJlYW0oKSB0aHJvd3MgSU9FeGNlcHRpb247Ci0KLSAgICAvKiogQHJldHVybiBjYW5vbmljYWwgcGF0aCB0byBjbGFzcyBmaWxlLgotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCBTdHJpbmcgZ2V0UGF0aCgpOwotCi0gICAgLyoqIEByZXR1cm4gYmFzZSBwYXRoIG9mIGZvdW5kIGNsYXNzLCBpLmUuIGNsYXNzIGlzIGNvbnRhaW5lZCByZWxhdGl2ZQotICAgICAqIHRvIHRoYXQgcGF0aCwgd2hpY2ggbWF5IGVpdGhlciBkZW5vdGUgYSBkaXJlY3RvcnksIG9yIHppcCBmaWxlCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IFN0cmluZyBnZXRCYXNlKCk7Ci0KLSAgICAvKiogQHJldHVybiBtb2RpZmljYXRpb24gdGltZSBvZiBjbGFzcyBmaWxlLgotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCBsb25nIGdldFRpbWUoKTsKLQotICAgIC8qKiBAcmV0dXJuIHNpemUgb2YgY2xhc3MgZmlsZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3QgbG9uZyBnZXRTaXplKCk7Ci0gIH0KLQotICBwcml2YXRlIHN0YXRpYyBjbGFzcyBEaXIgZXh0ZW5kcyBQYXRoRW50cnkgewotICAgIHByaXZhdGUgU3RyaW5nIGRpcjsKLQotICAgIERpcihTdHJpbmcgZCkgeyBkaXIgPSBkOyB9Ci0KLSAgICBDbGFzc0ZpbGUgZ2V0Q2xhc3NGaWxlKFN0cmluZyBuYW1lLCBTdHJpbmcgc3VmZml4KSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgICAgZmluYWwgRmlsZSBmaWxlID0gbmV3IEZpbGUoZGlyICsgRmlsZS5zZXBhcmF0b3JDaGFyICsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUucmVwbGFjZSgnLicsIEZpbGUuc2VwYXJhdG9yQ2hhcikgKyBzdWZmaXgpOwotCi0gICAgICByZXR1cm4gU2VjdXJpdHlTdXBwb3J0LmdldEZpbGVFeGlzdHMoZmlsZSk/IG5ldyBDbGFzc0ZpbGUoKSB7Ci0gICAgICAgIHB1YmxpYyBJbnB1dFN0cmVhbSBnZXRJbnB1dFN0cmVhbSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7IHJldHVybiBuZXcgRmlsZUlucHV0U3RyZWFtKGZpbGUpOyB9Ci0KLSAgICAgICAgcHVibGljIFN0cmluZyAgICAgIGdldFBhdGgoKSAgICAgICAgeyB0cnkgewotICAgICAgICAgIHJldHVybiBmaWxlLmdldENhbm9uaWNhbFBhdGgoKTsKLSAgICAgICAgfSBjYXRjaChJT0V4Y2VwdGlvbiBlKSB7IHJldHVybiBudWxsOyB9Ci0KLSAgICAgICAgfQotICAgICAgICBwdWJsaWMgbG9uZyAgICAgICAgZ2V0VGltZSgpICAgICAgICB7IHJldHVybiBmaWxlLmxhc3RNb2RpZmllZCgpOyB9Ci0gICAgICAgIHB1YmxpYyBsb25nICAgICAgICBnZXRTaXplKCkgICAgICAgIHsgcmV0dXJuIGZpbGUubGVuZ3RoKCk7IH0KLSAgICAgICAgcHVibGljIFN0cmluZyBnZXRCYXNlKCkgeyAgcmV0dXJuIGRpcjsgIH0KLQotICAgICAgfSA6IG51bGw7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsgcmV0dXJuIGRpcjsgfQotICB9Ci0KLSAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgWmlwIGV4dGVuZHMgUGF0aEVudHJ5IHsKLSAgICBwcml2YXRlIFppcEZpbGUgemlwOwotCi0gICAgWmlwKFppcEZpbGUgeikgeyB6aXAgPSB6OyB9Ci0KLSAgICBDbGFzc0ZpbGUgZ2V0Q2xhc3NGaWxlKFN0cmluZyBuYW1lLCBTdHJpbmcgc3VmZml4KSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgICAgZmluYWwgWmlwRW50cnkgZW50cnkgPSB6aXAuZ2V0RW50cnkobmFtZS5yZXBsYWNlKCcuJywgJy8nKSArIHN1ZmZpeCk7Ci0KLSAgICAgIHJldHVybiAoZW50cnkgIT0gbnVsbCk/IG5ldyBDbGFzc0ZpbGUoKSB7Ci0gICAgICAgIHB1YmxpYyBJbnB1dFN0cmVhbSBnZXRJbnB1dFN0cmVhbSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7IHJldHVybiB6aXAuZ2V0SW5wdXRTdHJlYW0oZW50cnkpOyB9Ci0gICAgICAgIHB1YmxpYyBTdHJpbmcgICAgICBnZXRQYXRoKCkgICAgICAgIHsgcmV0dXJuIGVudHJ5LnRvU3RyaW5nKCk7IH0KLSAgICAgICAgcHVibGljIGxvbmcgICAgICAgIGdldFRpbWUoKSAgICAgICAgeyByZXR1cm4gZW50cnkuZ2V0VGltZSgpOyB9Ci0gICAgICAgIHB1YmxpYyBsb25nICAgICAgICBnZXRTaXplKCkgICAgICAgeyByZXR1cm4gZW50cnkuZ2V0U2l6ZSgpOyB9Ci0gICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0QmFzZSgpIHsKLSAgICAgICAgICByZXR1cm4gemlwLmdldE5hbWUoKTsKLSAgICAgICAgfQotICAgICAgfSA6IG51bGw7Ci0gICAgfQotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvdXRpbC9DbGFzc1F1ZXVlLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvdXRpbC9DbGFzc1F1ZXVlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDI4MTcwOTQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL3V0aWwvQ2xhc3NRdWV1ZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsODQgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwudXRpbDsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLWltcG9ydCBqYXZhLnV0aWwuTGlua2VkTGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5jbGFzc2ZpbGUuSmF2YUNsYXNzOwotCi0vKioKLSAqIFV0aWxpdHkgY2xhc3MgaW1wbGVtZW50aW5nIGEgKHR5cGVzYWZlKSBxdWV1ZSBvZiBKYXZhQ2xhc3MKLSAqIG9iamVjdHMuCi0gKgotICogQGF1dGhvciA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICogQHNlZSBDbGFzc1ZlY3RvcgotKi8KLXB1YmxpYyBjbGFzcyBDbGFzc1F1ZXVlIGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUgewotICBwcm90ZWN0ZWQgTGlua2VkTGlzdCB2ZWMgID0gbmV3IExpbmtlZExpc3QoKTsKLQotICBwdWJsaWMgdm9pZCBlbnF1ZXVlKEphdmFDbGFzcyBjbGF6eikgeyB2ZWMuYWRkTGFzdChjbGF6eik7IH0KLQotICBwdWJsaWMgSmF2YUNsYXNzIGRlcXVldWUoKSAgICAgICAgICAgICAgICB7Ci0gICAgcmV0dXJuIChKYXZhQ2xhc3MpdmVjLnJlbW92ZUZpcnN0KCk7Ci0gIH0KLQotICBwdWJsaWMgYm9vbGVhbiBlbXB0eSgpIHsgcmV0dXJuIHZlYy5pc0VtcHR5KCk7IH0KLQotICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgIHJldHVybiB2ZWMudG9TdHJpbmcoKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL3V0aWwvQ2xhc3NTZXQuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC91dGlsL0NsYXNzU2V0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGU3ZWEyZTQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL3V0aWwvQ2xhc3NTZXQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDk5ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLnV0aWw7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1pbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7Ci1pbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuY2xhc3NmaWxlLkphdmFDbGFzczsKLQotLyoqCi0gKiBVdGlsaXR5IGNsYXNzIGltcGxlbWVudGluZyBhICh0eXBlc2FmZSkgc2V0IG9mIEphdmFDbGFzcyBvYmplY3RzLgotICogU2luY2UgSmF2YUNsYXNzIGhhcyBubyBlcXVhbHMoKSBtZXRob2QsIHRoZSBuYW1lIG9mIHRoZSBjbGFzcyBpcwotICogdXNlZCBmb3IgY29tcGFyaXNvbi4KLSAqCi0gKiBAYXV0aG9yIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKiBAc2VlIENsYXNzU3RhY2sKLSovCi1wdWJsaWMgY2xhc3MgQ2xhc3NTZXQgaW1wbGVtZW50cyBqYXZhLmlvLlNlcmlhbGl6YWJsZSB7Ci0gIHByaXZhdGUgSGFzaE1hcCBfbWFwID0gbmV3IEhhc2hNYXAoKTsKLQotICBwdWJsaWMgYm9vbGVhbiBhZGQoSmF2YUNsYXNzIGNsYXp6KSB7Ci0gICAgYm9vbGVhbiByZXN1bHQgPSBmYWxzZTsKLQotICAgIGlmKCFfbWFwLmNvbnRhaW5zS2V5KGNsYXp6LmdldENsYXNzTmFtZSgpKSkgewotICAgICAgcmVzdWx0ID0gdHJ1ZTsKLSAgICAgIF9tYXAucHV0KGNsYXp6LmdldENsYXNzTmFtZSgpLCBjbGF6eik7Ci0gICAgfQotCi0gICAgcmV0dXJuIHJlc3VsdDsKLSAgfQotCi0gIHB1YmxpYyB2b2lkICAgICAgcmVtb3ZlKEphdmFDbGFzcyBjbGF6eikgeyBfbWFwLnJlbW92ZShjbGF6ei5nZXRDbGFzc05hbWUoKSk7IH0KLSAgcHVibGljIGJvb2xlYW4gICBlbXB0eSgpICAgICAgICAgICAgICAgICB7IHJldHVybiBfbWFwLmlzRW1wdHkoKTsgfQotCi0gIHB1YmxpYyBKYXZhQ2xhc3NbXSB0b0FycmF5KCkgewotICAgIENvbGxlY3Rpb24gdmFsdWVzID0gX21hcC52YWx1ZXMoKTsKLSAgICBKYXZhQ2xhc3NbXSBjbGFzc2VzID0gbmV3IEphdmFDbGFzc1t2YWx1ZXMuc2l6ZSgpXTsKLSAgICB2YWx1ZXMudG9BcnJheShjbGFzc2VzKTsKLSAgICByZXR1cm4gY2xhc3NlczsKLSAgfQotCi0gIHB1YmxpYyBTdHJpbmdbXSBnZXRDbGFzc05hbWVzKCkgewotICAgIHJldHVybiAoU3RyaW5nW10pX21hcC5rZXlTZXQoKS50b0FycmF5KG5ldyBTdHJpbmdbX21hcC5rZXlTZXQoKS5zaXplKCldKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL3V0aWwvQ2xhc3NTdGFjay5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL3V0aWwvQ2xhc3NTdGFjay5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4NzAyOWUyLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC91dGlsL0NsYXNzU3RhY2suamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDc2ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLnV0aWw7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1pbXBvcnQgamF2YS51dGlsLlN0YWNrOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmNsYXNzZmlsZS5KYXZhQ2xhc3M7Ci0KLS8qKgotICogVXRpbGl0eSBjbGFzcyBpbXBsZW1lbnRpbmcgYSAodHlwZXNhZmUpIHN0YWNrIG9mIEphdmFDbGFzcyBvYmplY3RzLgotICoKLSAqIEBhdXRob3IgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqIEBzZWUgU3RhY2sKLSovCi1wdWJsaWMgY2xhc3MgQ2xhc3NTdGFjayBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKLSAgcHJpdmF0ZSBTdGFjayBzdGFjayA9IG5ldyBTdGFjaygpOwotCi0gIHB1YmxpYyB2b2lkICAgICAgcHVzaChKYXZhQ2xhc3MgY2xhenopIHsgc3RhY2sucHVzaChjbGF6eik7IH0KLSAgcHVibGljIEphdmFDbGFzcyBwb3AoKSAgICAgICAgICAgICAgICAgeyByZXR1cm4gKEphdmFDbGFzcylzdGFjay5wb3AoKTsgfQotICBwdWJsaWMgSmF2YUNsYXNzIHRvcCgpICAgICAgICAgICAgICAgICB7IHJldHVybiAoSmF2YUNsYXNzKXN0YWNrLnBlZWsoKTsgfQotICBwdWJsaWMgYm9vbGVhbiAgIGVtcHR5KCkgICAgICAgICAgICAgICB7IHJldHVybiBzdGFjay5lbXB0eSgpOyB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvdXRpbC9DbGFzc1ZlY3Rvci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL3V0aWwvQ2xhc3NWZWN0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMjhjNDc4OS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvdXRpbC9DbGFzc1ZlY3Rvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsODIgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwudXRpbDsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLWltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmNsYXNzZmlsZS5KYXZhQ2xhc3M7Ci0KLS8qKgotICogVXRpbGl0eSBjbGFzcyBpbXBsZW1lbnRpbmcgYSAodHlwZXNhZmUpIGNvbGxlY3Rpb24gb2YgSmF2YUNsYXNzCi0gKiBvYmplY3RzLiBDb250YWlucyB0aGUgbW9zdCBpbXBvcnRhbnQgbWV0aG9kcyBvZiBhIFZlY3Rvci4KLSAqCi0gKiBAYXV0aG9yIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKiBAc2VlIENsYXNzUXVldWUKLSovCi1wdWJsaWMgY2xhc3MgQ2xhc3NWZWN0b3IgaW1wbGVtZW50cyBqYXZhLmlvLlNlcmlhbGl6YWJsZSB7Ci0gIHByb3RlY3RlZCBBcnJheUxpc3QgdmVjID0gbmV3IEFycmF5TGlzdCgpOwotCi0gIHB1YmxpYyB2b2lkICAgICAgYWRkRWxlbWVudChKYXZhQ2xhc3MgY2xhenopIHsgdmVjLmFkZChjbGF6eik7IH0KLSAgcHVibGljIEphdmFDbGFzcyBlbGVtZW50QXQoaW50IGluZGV4KSAgICAgICAgeyByZXR1cm4gKEphdmFDbGFzcyl2ZWMuZ2V0KGluZGV4KTsgfQotICBwdWJsaWMgdm9pZCAgICAgIHJlbW92ZUVsZW1lbnRBdChpbnQgaW5kZXgpICB7IHZlYy5yZW1vdmUoaW5kZXgpOyB9Ci0KLSAgcHVibGljIEphdmFDbGFzc1tdIHRvQXJyYXkoKSB7Ci0gICAgSmF2YUNsYXNzW10gY2xhc3NlcyA9IG5ldyBKYXZhQ2xhc3NbdmVjLnNpemUoKV07Ci0gICAgdmVjLnRvQXJyYXkoY2xhc3Nlcyk7Ci0gICAgcmV0dXJuIGNsYXNzZXM7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC91dGlsL0NvZGVIVE1MLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvdXRpbC9Db2RlSFRNTC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjYWUyZWE2Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC91dGlsL0NvZGVIVE1MLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw2MjEgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwudXRpbDsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmNsYXNzZmlsZS4qOwotaW1wb3J0IGphdmEuaW8uKjsKLWltcG9ydCBqYXZhLnV0aWwuQml0U2V0OwotCi0vKioKLSAqIENvbnZlcnQgY29kZSBpbnRvIEhUTUwgZmlsZS4KLSAqCi0gKiBAYXV0aG9yICA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICoKLSAqLwotZmluYWwgY2xhc3MgQ29kZUhUTUwgaW1wbGVtZW50cyBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMgewotICBwcml2YXRlIFN0cmluZyAgICAgICAgY2xhc3NfbmFtZTsgICAgIC8vIG5hbWUgb2YgY3VycmVudCBjbGFzcwotICBwcml2YXRlIE1ldGhvZFtdICAgICAgbWV0aG9kczsgICAgICAgIC8vIE1ldGhvZHMgdG8gcHJpbnQKLSAgcHJpdmF0ZSBQcmludFdyaXRlciAgIGZpbGU7ICAgICAgICAgICAvLyBmaWxlIHRvIHdyaXRlIHRvCi0gIHByaXZhdGUgQml0U2V0ICAgICAgICBnb3RvX3NldDsKLSAgcHJpdmF0ZSBDb25zdGFudFBvb2wgIGNvbnN0YW50X3Bvb2w7Ci0gIHByaXZhdGUgQ29uc3RhbnRIVE1MICBjb25zdGFudF9odG1sOwotICBwcml2YXRlIHN0YXRpYyBib29sZWFuIHdpZGU9ZmFsc2U7Ci0KLSAgQ29kZUhUTUwoU3RyaW5nIGRpciwgU3RyaW5nIGNsYXNzX25hbWUsCi0gICAgICAgICAgIE1ldGhvZFtdIG1ldGhvZHMsIENvbnN0YW50UG9vbCBjb25zdGFudF9wb29sLAotICAgICAgICAgICBDb25zdGFudEhUTUwgY29uc3RhbnRfaHRtbCkgdGhyb3dzIElPRXhjZXB0aW9uCi0gIHsKLSAgICB0aGlzLmNsYXNzX25hbWUgICAgID0gY2xhc3NfbmFtZTsKLSAgICB0aGlzLm1ldGhvZHMgICAgICAgID0gbWV0aG9kczsKLSAgICB0aGlzLmNvbnN0YW50X3Bvb2wgID0gY29uc3RhbnRfcG9vbDsKLSAgICB0aGlzLmNvbnN0YW50X2h0bWwgPSBjb25zdGFudF9odG1sOwotCi0gICAgZmlsZSA9IG5ldyBQcmludFdyaXRlcihuZXcgRmlsZU91dHB1dFN0cmVhbShkaXIgKyBjbGFzc19uYW1lICsgIl9jb2RlLmh0bWwiKSk7Ci0gICAgZmlsZS5wcmludGxuKCI8SFRNTD48Qk9EWSBCR0NPTE9SPVwiI0MwQzBDMFwiPiIpOwotCi0gICAgZm9yKGludCBpPTA7IGkgPCBtZXRob2RzLmxlbmd0aDsgaSsrKQotICAgICAgd3JpdGVNZXRob2QobWV0aG9kc1tpXSwgaSk7Ci0KLSAgICBmaWxlLnByaW50bG4oIjwvQk9EWT48L0hUTUw+Iik7Ci0gICAgZmlsZS5jbG9zZSgpOwotICB9Ci0KLSAgLyoqCi0gICAqIERpc2Fzc2VtYmxlIGEgc3RyZWFtIG9mIGJ5dGUgY29kZXMgYW5kIHJldHVybiB0aGUKLSAgICogc3RyaW5nIHJlcHJlc2VudGF0aW9uLgotICAgKgotICAgKiBAcGFyYW0gIHN0cmVhbSBkYXRhIGlucHV0IHN0cmVhbQotICAgKiBAcmV0dXJuIFN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBieXRlIGNvZGUKLSAgICovCi0gIHByaXZhdGUgZmluYWwgU3RyaW5nIGNvZGVUb0hUTUwoQnl0ZVNlcXVlbmNlIGJ5dGVzLCBpbnQgbWV0aG9kX251bWJlcikKLSAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24KLSAgewotICAgIHNob3J0ICAgICAgICBvcGNvZGUgPSAoc2hvcnQpYnl0ZXMucmVhZFVuc2lnbmVkQnl0ZSgpOwotICAgIFN0cmluZ0J1ZmZlciBidWY7Ci0gICAgU3RyaW5nICAgICAgIG5hbWUsIHNpZ25hdHVyZTsKLSAgICBpbnQgICAgICAgICAgZGVmYXVsdF9vZmZzZXQ9MCwgbG93LCBoaWdoOwotICAgIGludCAgICAgICAgICBpbmRleCwgY2xhc3NfaW5kZXgsIHZpbmRleCwgY29uc3RhbnQ7Ci0gICAgaW50W10gICAgICAgIGp1bXBfdGFibGU7Ci0gICAgaW50ICAgICAgICAgIG5vX3BhZF9ieXRlcz0wLCBvZmZzZXQ7Ci0KLSAgICBidWYgPSBuZXcgU3RyaW5nQnVmZmVyKCI8VFQ+IiArIE9QQ09ERV9OQU1FU1tvcGNvZGVdICsgIjwvVFQ+PC9URD48VEQ+Iik7Ci0KLSAgICAvKiBTcGVjaWFsIGNhc2U6IFNraXAgKDAtMykgcGFkZGluZyBieXRlcywgaS5lLiwgdGhlCi0gICAgICogZm9sbG93aW5nIGJ5dGVzIGFyZSA0LWJ5dGUtYWxpZ25lZAotICAgICAqLwotICAgIGlmKChvcGNvZGUgPT0gVEFCTEVTV0lUQ0gpIHx8IChvcGNvZGUgPT0gTE9PS1VQU1dJVENIKSkgewotICAgICAgaW50IHJlbWFpbmRlciA9IGJ5dGVzLmdldEluZGV4KCkgJSA0OwotICAgICAgbm9fcGFkX2J5dGVzICA9IChyZW1haW5kZXIgPT0gMCk/IDAgOiA0IC0gcmVtYWluZGVyOwotCi0gICAgICBmb3IoaW50IGk9MDsgaSA8IG5vX3BhZF9ieXRlczsgaSsrKQotICAgICAgICBieXRlcy5yZWFkQnl0ZSgpOwotCi0gICAgICAvLyBCb3RoIGNhc2VzIGhhdmUgYSBmaWVsZCBkZWZhdWx0X29mZnNldCBpbiBjb21tb24KLSAgICAgIGRlZmF1bHRfb2Zmc2V0ID0gYnl0ZXMucmVhZEludCgpOwotICAgIH0KLQotICAgIHN3aXRjaChvcGNvZGUpIHsKLSAgICBjYXNlIFRBQkxFU1dJVENIOgotICAgICAgbG93ICA9IGJ5dGVzLnJlYWRJbnQoKTsKLSAgICAgIGhpZ2ggPSBieXRlcy5yZWFkSW50KCk7Ci0KLSAgICAgIG9mZnNldCA9IGJ5dGVzLmdldEluZGV4KCkgLSAxMiAtIG5vX3BhZF9ieXRlcyAtIDE7Ci0gICAgICBkZWZhdWx0X29mZnNldCArPSBvZmZzZXQ7Ci0KLSAgICAgIGJ1Zi5hcHBlbmQoIjxUQUJMRSBCT1JERVI9MT48VFI+Iik7Ci0KLSAgICAgIC8vIFByaW50IHN3aXRjaCBpbmRpY2VzIGluIGZpcnN0IHJvdyAoYW5kIGRlZmF1bHQpCi0gICAgICBqdW1wX3RhYmxlID0gbmV3IGludFtoaWdoIC0gbG93ICsgMV07Ci0gICAgICBmb3IoaW50IGk9MDsgaSA8IGp1bXBfdGFibGUubGVuZ3RoOyBpKyspIHsKLSAgICAgICAganVtcF90YWJsZVtpXSA9IG9mZnNldCArIGJ5dGVzLnJlYWRJbnQoKTsKLQotICAgICAgICBidWYuYXBwZW5kKCI8VEg+IiArIChsb3cgKyBpKSArICI8L1RIPiIpOwotICAgICAgfQotICAgICAgYnVmLmFwcGVuZCgiPFRIPmRlZmF1bHQ8L1RIPjwvVFI+XG48VFI+Iik7Ci0KLSAgICAgIC8vIFByaW50IHRhcmdldCBhbmQgZGVmYXVsdCBpbmRpY2VzIGluIHNlY29uZCByb3cKLSAgICAgIGZvcihpbnQgaT0wOyBpIDwganVtcF90YWJsZS5sZW5ndGg7IGkrKykKLSAgICAgICAgYnVmLmFwcGVuZCgiPFREPjxBIEhSRUY9XCIjY29kZSIgKyBtZXRob2RfbnVtYmVyICsgIkAiICsKLSAgICAgICAgICAgICAgICAgICBqdW1wX3RhYmxlW2ldICsgIlwiPiIgKyBqdW1wX3RhYmxlW2ldICsgIjwvQT48L1REPiIpOwotICAgICAgYnVmLmFwcGVuZCgiPFREPjxBIEhSRUY9XCIjY29kZSIgKyBtZXRob2RfbnVtYmVyICsgIkAiICsKLSAgICAgICAgICAgICAgICAgZGVmYXVsdF9vZmZzZXQgKyAiXCI+IiArIGRlZmF1bHRfb2Zmc2V0ICsgIjwvQT48L1REPjwvVFI+XG48L1RBQkxFPlxuIik7Ci0KLSAgICAgIGJyZWFrOwotCi0gICAgICAvKiBMb29rdXAgc3dpdGNoIGhhcyB2YXJpYWJsZSBsZW5ndGggYXJndW1lbnRzLgotICAgICAgICovCi0gICAgY2FzZSBMT09LVVBTV0lUQ0g6Ci0gICAgICBpbnQgbnBhaXJzID0gYnl0ZXMucmVhZEludCgpOwotICAgICAgb2Zmc2V0ID0gYnl0ZXMuZ2V0SW5kZXgoKSAtIDggLSBub19wYWRfYnl0ZXMgLSAxOwotICAgICAganVtcF90YWJsZSA9IG5ldyBpbnRbbnBhaXJzXTsKLSAgICAgIGRlZmF1bHRfb2Zmc2V0ICs9IG9mZnNldDsKLQotICAgICAgYnVmLmFwcGVuZCgiPFRBQkxFIEJPUkRFUj0xPjxUUj4iKTsKLQotICAgICAgLy8gUHJpbnQgc3dpdGNoIGluZGljZXMgaW4gZmlyc3Qgcm93IChhbmQgZGVmYXVsdCkKLSAgICAgIGZvcihpbnQgaT0wOyBpIDwgbnBhaXJzOyBpKyspIHsKLSAgICAgICAgaW50IG1hdGNoID0gYnl0ZXMucmVhZEludCgpOwotCi0gICAgICAgIGp1bXBfdGFibGVbaV0gPSBvZmZzZXQgKyBieXRlcy5yZWFkSW50KCk7Ci0gICAgICAgIGJ1Zi5hcHBlbmQoIjxUSD4iICsgbWF0Y2ggKyAiPC9USD4iKTsKLSAgICAgIH0KLSAgICAgIGJ1Zi5hcHBlbmQoIjxUSD5kZWZhdWx0PC9USD48L1RSPlxuPFRSPiIpOwotCi0gICAgICAvLyBQcmludCB0YXJnZXQgYW5kIGRlZmF1bHQgaW5kaWNlcyBpbiBzZWNvbmQgcm93Ci0gICAgICBmb3IoaW50IGk9MDsgaSA8IG5wYWlyczsgaSsrKQotICAgICAgICBidWYuYXBwZW5kKCI8VEQ+PEEgSFJFRj1cIiNjb2RlIiArIG1ldGhvZF9udW1iZXIgKyAiQCIgKwotICAgICAgICAgICAgICAgICAgIGp1bXBfdGFibGVbaV0gKyAiXCI+IiArIGp1bXBfdGFibGVbaV0gKyAiPC9BPjwvVEQ+Iik7Ci0gICAgICBidWYuYXBwZW5kKCI8VEQ+PEEgSFJFRj1cIiNjb2RlIiArIG1ldGhvZF9udW1iZXIgKyAiQCIgKwotICAgICAgICAgICAgICAgICBkZWZhdWx0X29mZnNldCArICJcIj4iICsgZGVmYXVsdF9vZmZzZXQgKyAiPC9BPjwvVEQ+PC9UUj5cbjwvVEFCTEU+XG4iKTsKLSAgICAgIGJyZWFrOwotCi0gICAgICAvKiBUd28gYWRkcmVzcyBieXRlcyArIG9mZnNldCBmcm9tIHN0YXJ0IG9mIGJ5dGUgc3RyZWFtIGZvcm0gdGhlCi0gICAgICAgKiBqdW1wIHRhcmdldC4KLSAgICAgICAqLwotICAgIGNhc2UgR09UTzogICAgICBjYXNlIElGRVE6ICAgICAgY2FzZSBJRkdFOiAgICAgIGNhc2UgSUZHVDoKLSAgICBjYXNlIElGTEU6ICAgICAgY2FzZSBJRkxUOgotICAgIGNhc2UgSUZORTogICAgICBjYXNlIElGTk9OTlVMTDogY2FzZSBJRk5VTEw6ICAgIGNhc2UgSUZfQUNNUEVROgotICAgIGNhc2UgSUZfQUNNUE5FOiBjYXNlIElGX0lDTVBFUTogY2FzZSBJRl9JQ01QR0U6IGNhc2UgSUZfSUNNUEdUOgotICAgIGNhc2UgSUZfSUNNUExFOiBjYXNlIElGX0lDTVBMVDogY2FzZSBJRl9JQ01QTkU6IGNhc2UgSlNSOgotCi0gICAgICBpbmRleCA9IChpbnQpKGJ5dGVzLmdldEluZGV4KCkgKyBieXRlcy5yZWFkU2hvcnQoKSAtIDEpOwotCi0gICAgICBidWYuYXBwZW5kKCI8QSBIUkVGPVwiI2NvZGUiICsgbWV0aG9kX251bWJlciArICJAIiArIGluZGV4ICsgIlwiPiIgKyBpbmRleCArICI8L0E+Iik7Ci0gICAgICBicmVhazsKLQotICAgICAgLyogU2FtZSBmb3IgMzItYml0IHdpZGUganVtcHMKLSAgICAgICAqLwotICAgIGNhc2UgR09UT19XOiBjYXNlIEpTUl9XOgotICAgICAgaW50IHdpbmRleCA9IGJ5dGVzLmdldEluZGV4KCkgKyBieXRlcy5yZWFkSW50KCkgLSAxOwotICAgICAgYnVmLmFwcGVuZCgiPEEgSFJFRj1cIiNjb2RlIiArIG1ldGhvZF9udW1iZXIgKyAiQCIgKyB3aW5kZXggKyAiXCI+IiArCi0gICAgICAgICAgICAgICAgIHdpbmRleCArICI8L0E+Iik7Ci0gICAgICBicmVhazsKLQotICAgICAgLyogSW5kZXggYnl0ZSByZWZlcmVuY2VzIGxvY2FsIHZhcmlhYmxlIChyZWdpc3RlcikKLSAgICAgICAqLwotICAgIGNhc2UgQUxPQUQ6ICBjYXNlIEFTVE9SRTogY2FzZSBETE9BRDogIGNhc2UgRFNUT1JFOiBjYXNlIEZMT0FEOgotICAgIGNhc2UgRlNUT1JFOiBjYXNlIElMT0FEOiAgY2FzZSBJU1RPUkU6IGNhc2UgTExPQUQ6ICBjYXNlIExTVE9SRToKLSAgICBjYXNlIFJFVDoKLSAgICAgIGlmKHdpZGUpIHsKLSAgICAgICAgdmluZGV4ID0gYnl0ZXMucmVhZFNob3J0KCk7Ci0gICAgICAgIHdpZGU9ZmFsc2U7IC8vIENsZWFyIGZsYWcKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgICAgdmluZGV4ID0gYnl0ZXMucmVhZFVuc2lnbmVkQnl0ZSgpOwotCi0gICAgICBidWYuYXBwZW5kKCIlIiArIHZpbmRleCk7Ci0gICAgICBicmVhazsKLQotICAgICAgLyoKLSAgICAgICAqIFJlbWVtYmVyIHdpZGUgYnl0ZSB3aGljaCBpcyB1c2VkIHRvIGZvcm0gYSAxNi1iaXQgYWRkcmVzcyBpbiB0aGUKLSAgICAgICAqIGZvbGxvd2luZyBpbnN0cnVjdGlvbi4gUmVsaWVzIG9uIHRoYXQgdGhlIG1ldGhvZCBpcyBjYWxsZWQgYWdhaW4gd2l0aAotICAgICAgICogdGhlIGZvbGxvd2luZyBvcGNvZGUuCi0gICAgICAgKi8KLSAgICBjYXNlIFdJREU6Ci0gICAgICB3aWRlICAgICAgPSB0cnVlOwotICAgICAgYnVmLmFwcGVuZCgiKHdpZGUpIik7Ci0gICAgICBicmVhazsKLQotICAgICAgLyogQXJyYXkgb2YgYmFzaWMgdHlwZS4KLSAgICAgICAqLwotICAgIGNhc2UgTkVXQVJSQVk6Ci0gICAgICBidWYuYXBwZW5kKCI8Rk9OVCBDT0xPUj1cIiMwMEZGMDBcIj4iICsgVFlQRV9OQU1FU1tieXRlcy5yZWFkQnl0ZSgpXSArICI8L0ZPTlQ+Iik7Ci0gICAgICBicmVhazsKLQotICAgICAgLyogQWNjZXNzIG9iamVjdC9jbGFzcyBmaWVsZHMuCi0gICAgICAgKi8KLSAgICBjYXNlIEdFVEZJRUxEOiBjYXNlIEdFVFNUQVRJQzogY2FzZSBQVVRGSUVMRDogY2FzZSBQVVRTVEFUSUM6Ci0gICAgICBpbmRleCA9IGJ5dGVzLnJlYWRTaG9ydCgpOwotICAgICAgQ29uc3RhbnRGaWVsZHJlZiBjMSA9IChDb25zdGFudEZpZWxkcmVmKWNvbnN0YW50X3Bvb2wuZ2V0Q29uc3RhbnQoaW5kZXgsIENPTlNUQU5UX0ZpZWxkcmVmKTsKLQotICAgICAgY2xhc3NfaW5kZXggPSBjMS5nZXRDbGFzc0luZGV4KCk7Ci0gICAgICBuYW1lID0gY29uc3RhbnRfcG9vbC5nZXRDb25zdGFudFN0cmluZyhjbGFzc19pbmRleCwgQ09OU1RBTlRfQ2xhc3MpOwotICAgICAgbmFtZSA9IFV0aWxpdHkuY29tcGFjdENsYXNzTmFtZShuYW1lLCBmYWxzZSk7Ci0KLSAgICAgIGluZGV4ID0gYzEuZ2V0TmFtZUFuZFR5cGVJbmRleCgpOwotICAgICAgU3RyaW5nIGZpZWxkX25hbWUgPSBjb25zdGFudF9wb29sLmNvbnN0YW50VG9TdHJpbmcoaW5kZXgsIENPTlNUQU5UX05hbWVBbmRUeXBlKTsKLQotICAgICAgaWYobmFtZS5lcXVhbHMoY2xhc3NfbmFtZSkpIHsgLy8gTG9jYWwgZmllbGQKLSAgICAgICAgYnVmLmFwcGVuZCgiPEEgSFJFRj1cIiIgKyBjbGFzc19uYW1lICsgIl9tZXRob2RzLmh0bWwjZmllbGQiICsgZmllbGRfbmFtZSArCi0gICAgICAgICAgICAgICAgICAgIlwiIFRBUkdFVD1NZXRob2RzPiIgKyBmaWVsZF9uYW1lICsgIjwvQT5cbiIpOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgICBidWYuYXBwZW5kKGNvbnN0YW50X2h0bWwucmVmZXJlbmNlQ29uc3RhbnQoY2xhc3NfaW5kZXgpICsgIi4iICsgZmllbGRfbmFtZSk7Ci0KLSAgICAgIGJyZWFrOwotCi0gICAgICAvKiBPcGVyYW5kcyBhcmUgcmVmZXJlbmNlcyB0byBjbGFzc2VzIGluIGNvbnN0YW50IHBvb2wKLSAgICAgICAqLwotICAgIGNhc2UgQ0hFQ0tDQVNUOiBjYXNlIElOU1RBTkNFT0Y6IGNhc2UgTkVXOgotICAgICAgaW5kZXggPSBieXRlcy5yZWFkU2hvcnQoKTsKLSAgICAgIGJ1Zi5hcHBlbmQoY29uc3RhbnRfaHRtbC5yZWZlcmVuY2VDb25zdGFudChpbmRleCkpOwotICAgICAgYnJlYWs7Ci0KLSAgICAgIC8qIE9wZXJhbmRzIGFyZSByZWZlcmVuY2VzIHRvIG1ldGhvZHMgaW4gY29uc3RhbnQgcG9vbAotICAgICAgICovCi0gICAgY2FzZSBJTlZPS0VTUEVDSUFMOiBjYXNlIElOVk9LRVNUQVRJQzogY2FzZSBJTlZPS0VWSVJUVUFMOiBjYXNlIElOVk9LRUlOVEVSRkFDRToKLSAgICAgIGludCBtX2luZGV4ID0gYnl0ZXMucmVhZFNob3J0KCk7Ci0gICAgICBTdHJpbmcgc3RyOwotCi0gICAgICBpZihvcGNvZGUgPT0gSU5WT0tFSU5URVJGQUNFKSB7IC8vIFNwZWNpYWwgdHJlYXRtZW50IG5lZWRlZAotICAgICAgICBpbnQgbmFyZ3MgICAgPSBieXRlcy5yZWFkVW5zaWduZWRCeXRlKCk7IC8vIFJlZHVuZGFudAotICAgICAgICBpbnQgcmVzZXJ2ZWQgPSBieXRlcy5yZWFkVW5zaWduZWRCeXRlKCk7IC8vIFJlc2VydmVkCi0KLSAgICAgICAgQ29uc3RhbnRJbnRlcmZhY2VNZXRob2RyZWYgYz0oQ29uc3RhbnRJbnRlcmZhY2VNZXRob2RyZWYpY29uc3RhbnRfcG9vbC5nZXRDb25zdGFudChtX2luZGV4LCBDT05TVEFOVF9JbnRlcmZhY2VNZXRob2RyZWYpOwotCi0gICAgICAgIGNsYXNzX2luZGV4ID0gYy5nZXRDbGFzc0luZGV4KCk7Ci0gICAgICAgIHN0ciA9IGNvbnN0YW50X3Bvb2wuY29uc3RhbnRUb1N0cmluZyhjKTsKLSAgICAgICAgaW5kZXggPSBjLmdldE5hbWVBbmRUeXBlSW5kZXgoKTsKLSAgICAgIH0KLSAgICAgIGVsc2UgewotICAgICAgICBDb25zdGFudE1ldGhvZHJlZiBjID0gKENvbnN0YW50TWV0aG9kcmVmKWNvbnN0YW50X3Bvb2wuZ2V0Q29uc3RhbnQobV9pbmRleCwgQ09OU1RBTlRfTWV0aG9kcmVmKTsKLSAgICAgICAgY2xhc3NfaW5kZXggPSBjLmdldENsYXNzSW5kZXgoKTsKLQotICAgICAgICBzdHIgID0gY29uc3RhbnRfcG9vbC5jb25zdGFudFRvU3RyaW5nKGMpOwotICAgICAgICBpbmRleCA9IGMuZ2V0TmFtZUFuZFR5cGVJbmRleCgpOwotICAgICAgfQotCi0gICAgICBuYW1lID0gQ2xhc3MySFRNTC5yZWZlcmVuY2VDbGFzcyhjbGFzc19pbmRleCk7Ci0gICAgICBzdHIgPSBDbGFzczJIVE1MLnRvSFRNTChjb25zdGFudF9wb29sLmNvbnN0YW50VG9TdHJpbmcoY29uc3RhbnRfcG9vbC5nZXRDb25zdGFudChpbmRleCwgQ09OU1RBTlRfTmFtZUFuZFR5cGUpKSk7Ci0KLSAgICAgIC8vIEdldCBzaWduYXR1cmUsIGkuZS4sIHR5cGVzCi0gICAgICBDb25zdGFudE5hbWVBbmRUeXBlIGMyID0gKENvbnN0YW50TmFtZUFuZFR5cGUpY29uc3RhbnRfcG9vbC4KLSAgICAgICAgZ2V0Q29uc3RhbnQoaW5kZXgsIENPTlNUQU5UX05hbWVBbmRUeXBlKTsKLSAgICAgIHNpZ25hdHVyZSA9IGNvbnN0YW50X3Bvb2wuY29uc3RhbnRUb1N0cmluZyhjMi5nZXRTaWduYXR1cmVJbmRleCgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPTlNUQU5UX1V0ZjgpOwotICAgICAgU3RyaW5nW10gYXJncyA9IFV0aWxpdHkubWV0aG9kU2lnbmF0dXJlQXJndW1lbnRUeXBlcyhzaWduYXR1cmUsIGZhbHNlKTsKLSAgICAgIFN0cmluZyAgIHR5cGUgPSBVdGlsaXR5Lm1ldGhvZFNpZ25hdHVyZVJldHVyblR5cGUoc2lnbmF0dXJlLCBmYWxzZSk7Ci0KLSAgICAgIGJ1Zi5hcHBlbmQobmFtZSArICIuPEEgSFJFRj1cIiIgKyBjbGFzc19uYW1lICsgIl9jcC5odG1sI2NwIiArIG1faW5kZXggKwotICAgICAgICAgICAgICAgICAiXCIgVEFSR0VUPUNvbnN0YW50UG9vbD4iICsgc3RyICsgIjwvQT4iICsgIigiKTsKLQotICAgICAgLy8gTGlzdCBhcmd1bWVudHMKLSAgICAgIGZvcihpbnQgaT0wOyBpIDwgYXJncy5sZW5ndGg7IGkrKykgewotICAgICAgICBidWYuYXBwZW5kKENsYXNzMkhUTUwucmVmZXJlbmNlVHlwZShhcmdzW2ldKSk7Ci0KLSAgICAgICAgaWYoaSA8IGFyZ3MubGVuZ3RoIC0gMSkKLSAgICAgICAgICBidWYuYXBwZW5kKCIsICIpOwotICAgICAgfQotICAgICAgLy8gQXR0YWNoIHJldHVybiB0eXBlCi0gICAgICBidWYuYXBwZW5kKCIpOiIgKyBDbGFzczJIVE1MLnJlZmVyZW5jZVR5cGUodHlwZSkpOwotCi0gICAgICBicmVhazsKLQotICAgICAgLyogT3BlcmFuZHMgYXJlIHJlZmVyZW5jZXMgdG8gaXRlbXMgaW4gY29uc3RhbnQgcG9vbAotICAgICAgICovCi0gICAgY2FzZSBMRENfVzogY2FzZSBMREMyX1c6Ci0gICAgICBpbmRleCA9IGJ5dGVzLnJlYWRTaG9ydCgpOwotCi0gICAgICBidWYuYXBwZW5kKCI8QSBIUkVGPVwiIiArIGNsYXNzX25hbWUgKyAiX2NwLmh0bWwjY3AiICsgaW5kZXggKwotICAgICAgICAgICAgICAgICAiXCIgVEFSR0VUPVwiQ29uc3RhbnRQb29sXCI+IiArCi0gICAgICAgICAgICAgICAgIENsYXNzMkhUTUwudG9IVE1MKGNvbnN0YW50X3Bvb2wuY29uc3RhbnRUb1N0cmluZyhpbmRleCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0YW50X3Bvb2wuCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRDb25zdGFudChpbmRleCkuZ2V0VGFnKCkpKSsKLSAgICAgICAgICAgICAgICAgIjwvYT4iKTsKLSAgICAgIGJyZWFrOwotCi0gICAgY2FzZSBMREM6Ci0gICAgICBpbmRleCA9IGJ5dGVzLnJlYWRVbnNpZ25lZEJ5dGUoKTsKLSAgICAgIGJ1Zi5hcHBlbmQoIjxBIEhSRUY9XCIiICsgY2xhc3NfbmFtZSArICJfY3AuaHRtbCNjcCIgKyBpbmRleCArCi0gICAgICAgICAgICAgICAgICJcIiBUQVJHRVQ9XCJDb25zdGFudFBvb2xcIj4iICsKLSAgICAgICAgICAgICAgICAgQ2xhc3MySFRNTC50b0hUTUwoY29uc3RhbnRfcG9vbC5jb25zdGFudFRvU3RyaW5nKGluZGV4LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RhbnRfcG9vbC4KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldENvbnN0YW50KGluZGV4KS5nZXRUYWcoKSkpKwotICAgICAgICAgICAgICAgICAiPC9hPiIpOwotICAgICAgYnJlYWs7Ci0KLSAgICAgIC8qIEFycmF5IG9mIHJlZmVyZW5jZXMuCi0gICAgICAgKi8KLSAgICBjYXNlIEFORVdBUlJBWToKLSAgICAgIGluZGV4ID0gYnl0ZXMucmVhZFNob3J0KCk7Ci0KLSAgICAgIGJ1Zi5hcHBlbmQoY29uc3RhbnRfaHRtbC5yZWZlcmVuY2VDb25zdGFudChpbmRleCkpOwotICAgICAgYnJlYWs7Ci0KLSAgICAgIC8qIE11bHRpZGltZW5zaW9uYWwgYXJyYXkgb2YgcmVmZXJlbmNlcy4KLSAgICAgICAqLwotICAgIGNhc2UgTVVMVElBTkVXQVJSQVk6Ci0gICAgICBpbmRleCA9IGJ5dGVzLnJlYWRTaG9ydCgpOwotICAgICAgaW50IGRpbWVuc2lvbnMgPSBieXRlcy5yZWFkQnl0ZSgpOwotICAgICAgYnVmLmFwcGVuZChjb25zdGFudF9odG1sLnJlZmVyZW5jZUNvbnN0YW50KGluZGV4KSArICI6IiArIGRpbWVuc2lvbnMgKyAiLWRpbWVuc2lvbmFsIik7Ci0gICAgICBicmVhazsKLQotICAgICAgLyogSW5jcmVtZW50IGxvY2FsIHZhcmlhYmxlLgotICAgICAgICovCi0gICAgY2FzZSBJSU5DOgotICAgICAgaWYod2lkZSkgewotICAgICAgICB2aW5kZXggICA9IGJ5dGVzLnJlYWRTaG9ydCgpOwotICAgICAgICBjb25zdGFudCA9IGJ5dGVzLnJlYWRTaG9ydCgpOwotICAgICAgICB3aWRlICAgICA9IGZhbHNlOwotICAgICAgfQotICAgICAgZWxzZSB7Ci0gICAgICAgIHZpbmRleCAgID0gYnl0ZXMucmVhZFVuc2lnbmVkQnl0ZSgpOwotICAgICAgICBjb25zdGFudCA9IGJ5dGVzLnJlYWRCeXRlKCk7Ci0gICAgICB9Ci0gICAgICBidWYuYXBwZW5kKCIlIiArIHZpbmRleCArICIgIiArIGNvbnN0YW50KTsKLSAgICAgIGJyZWFrOwotCi0gICAgZGVmYXVsdDoKLSAgICAgIGlmKE5PX09GX09QRVJBTkRTW29wY29kZV0gPiAwKSB7Ci0gICAgICAgIGZvcihpbnQgaT0wOyBpIDwgVFlQRV9PRl9PUEVSQU5EU1tvcGNvZGVdLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgc3dpdGNoKFRZUEVfT0ZfT1BFUkFORFNbb3Bjb2RlXVtpXSkgewotICAgICAgICAgIGNhc2UgVF9CWVRFOgotICAgICAgICAgICAgYnVmLmFwcGVuZChieXRlcy5yZWFkVW5zaWduZWRCeXRlKCkpOwotICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgICBjYXNlIFRfU0hPUlQ6IC8vIEVpdGhlciBicmFuY2ggb3IgaW5kZXgKLSAgICAgICAgICAgIGJ1Zi5hcHBlbmQoYnl0ZXMucmVhZFNob3J0KCkpOwotICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgICBjYXNlIFRfSU5UOgotICAgICAgICAgICAgYnVmLmFwcGVuZChieXRlcy5yZWFkSW50KCkpOwotICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgICBkZWZhdWx0OiAvLyBOZXZlciByZWFjaGVkCi0gICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIlVucmVhY2hhYmxlIGRlZmF1bHQgY2FzZSByZWFjaGVkISIpOwotICAgICAgICAgICAgU3lzdGVtLmV4aXQoLTEpOwotICAgICAgICAgIH0KLSAgICAgICAgICBidWYuYXBwZW5kKCImbmJzcDsiKTsKLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLQotICAgIGJ1Zi5hcHBlbmQoIjwvVEQ+Iik7Ci0gICAgcmV0dXJuIGJ1Zi50b1N0cmluZygpOwotICB9Ci0KLSAgLyoqCi0gICAqIEZpbmQgYWxsIHRhcmdldCBhZGRyZXNzZXMgaW4gY29kZSwgc28gdGhhdCB0aGV5IGNhbiBiZSBtYXJrZWQKLSAgICogd2l0aCAmbHQ7QSBOQU1FID0gLi4uJmd0Oy4gVGFyZ2V0IGFkZHJlc3NlcyBhcmUga2VwdCBpbiBhbiBCaXRTZXQgb2JqZWN0LgotICAgKi8KLSAgcHJpdmF0ZSBmaW5hbCB2b2lkIGZpbmRHb3RvcyhCeXRlU2VxdWVuY2UgYnl0ZXMsIE1ldGhvZCBtZXRob2QsIENvZGUgY29kZSkKLSAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24KLSAgewotICAgIGludCBpbmRleDsKLSAgICBnb3RvX3NldCA9IG5ldyBCaXRTZXQoYnl0ZXMuYXZhaWxhYmxlKCkpOwotICAgIGludCBvcGNvZGU7Ci0KLSAgICAvKiBGaXJzdCBnZXQgQ29kZSBhdHRyaWJ1dGUgZnJvbSBtZXRob2QgYW5kIHRoZSBleGNlcHRpb25zIGhhbmRsZWQKLSAgICAgKiAodHJ5IC4uIGNhdGNoKSBpbiB0aGlzIG1ldGhvZC4gV2Ugb25seSBuZWVkIHRoZSBsaW5lIG51bWJlciBoZXJlLgotICAgICAqLwotCi0gICAgaWYoY29kZSAhPSBudWxsKSB7Ci0gICAgICBDb2RlRXhjZXB0aW9uW10gY2UgID0gY29kZS5nZXRFeGNlcHRpb25UYWJsZSgpOwotICAgICAgaW50ICAgICAgICAgICAgIGxlbiA9IGNlLmxlbmd0aDsKLQotICAgICAgZm9yKGludCBpPTA7IGkgPCBsZW47IGkrKykgewotICAgICAgICBnb3RvX3NldC5zZXQoY2VbaV0uZ2V0U3RhcnRQQygpKTsKLSAgICAgICAgZ290b19zZXQuc2V0KGNlW2ldLmdldEVuZFBDKCkpOwotICAgICAgICBnb3RvX3NldC5zZXQoY2VbaV0uZ2V0SGFuZGxlclBDKCkpOwotICAgICAgfQotCi0gICAgICAvLyBMb29rIGZvciBsb2NhbCB2YXJpYWJsZXMgYW5kIHRoZWlyIHJhbmdlCi0gICAgICBBdHRyaWJ1dGVbXSBhdHRyaWJ1dGVzID0gY29kZS5nZXRBdHRyaWJ1dGVzKCk7Ci0gICAgICBmb3IoaW50IGk9MDsgaSA8IGF0dHJpYnV0ZXMubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgaWYoYXR0cmlidXRlc1tpXS5nZXRUYWcoKSA9PSBBVFRSX0xPQ0FMX1ZBUklBQkxFX1RBQkxFKSB7Ci0gICAgICAgICAgTG9jYWxWYXJpYWJsZVtdIHZhcnMgPSAoKExvY2FsVmFyaWFibGVUYWJsZSlhdHRyaWJ1dGVzW2ldKS5nZXRMb2NhbFZhcmlhYmxlVGFibGUoKTsKLQotICAgICAgICAgIGZvcihpbnQgaj0wOyBqIDwgdmFycy5sZW5ndGg7IGorKykgewotICAgICAgICAgICAgaW50ICBzdGFydCA9IHZhcnNbal0uZ2V0U3RhcnRQQygpOwotICAgICAgICAgICAgaW50ICBlbmQgICA9IChpbnQpKHN0YXJ0ICsgdmFyc1tqXS5nZXRMZW5ndGgoKSk7Ci0gICAgICAgICAgICBnb3RvX3NldC5zZXQoc3RhcnQpOwotICAgICAgICAgICAgZ290b19zZXQuc2V0KGVuZCk7Ci0gICAgICAgICAgfQotICAgICAgICAgIGJyZWFrOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotCi0gICAgLy8gR2V0IHRhcmdldCBhZGRyZXNzZXMgZnJvbSBHT1RPLCBKU1IsIFRBQkxFU1dJVENILCBldGMuCi0gICAgZm9yKGludCBpPTA7IGJ5dGVzLmF2YWlsYWJsZSgpID4gMDsgaSsrKSB7Ci0gICAgICBvcGNvZGUgPSBieXRlcy5yZWFkVW5zaWduZWRCeXRlKCk7Ci0gICAgICAvL1N5c3RlbS5vdXQucHJpbnRsbihPUENPREVfTkFNRVNbb3Bjb2RlXSk7Ci0gICAgICBzd2l0Y2gob3Bjb2RlKSB7Ci0gICAgICBjYXNlIFRBQkxFU1dJVENIOiBjYXNlIExPT0tVUFNXSVRDSDoKLSAgICAgICAgLy9ieXRlcy5yZWFkQnl0ZSgpOyAvLyBTa2lwIGFscmVhZHkgcmVhZCBieXRlCi0KLSAgICAgICAgaW50IHJlbWFpbmRlciA9IGJ5dGVzLmdldEluZGV4KCkgJSA0OwotICAgICAgICBpbnQgbm9fcGFkX2J5dGVzICA9IChyZW1haW5kZXIgPT0gMCk/IDAgOiA0IC0gcmVtYWluZGVyOwotICAgICAgICBpbnQgZGVmYXVsdF9vZmZzZXQsIG9mZnNldDsKLQotICAgICAgICBmb3IoaW50IGo9MDsgaiA8IG5vX3BhZF9ieXRlczsgaisrKQotICAgICAgICAgIGJ5dGVzLnJlYWRCeXRlKCk7Ci0KLSAgICAgICAgLy8gQm90aCBjYXNlcyBoYXZlIGEgZmllbGQgZGVmYXVsdF9vZmZzZXQgaW4gY29tbW9uCi0gICAgICAgIGRlZmF1bHRfb2Zmc2V0ID0gYnl0ZXMucmVhZEludCgpOwotCi0gICAgICAgIGlmKG9wY29kZSA9PSBUQUJMRVNXSVRDSCkgewotICAgICAgICAgIGludCBsb3cgPSBieXRlcy5yZWFkSW50KCk7Ci0gICAgICAgICAgaW50IGhpZ2ggPSBieXRlcy5yZWFkSW50KCk7Ci0KLSAgICAgICAgICBvZmZzZXQgPSBieXRlcy5nZXRJbmRleCgpIC0gMTIgLSBub19wYWRfYnl0ZXMgLSAxOwotICAgICAgICAgIGRlZmF1bHRfb2Zmc2V0ICs9IG9mZnNldDsKLSAgICAgICAgICBnb3RvX3NldC5zZXQoZGVmYXVsdF9vZmZzZXQpOwotCi0gICAgICAgICAgZm9yKGludCBqPTA7IGogPCAoaGlnaCAtIGxvdyArIDEpOyBqKyspIHsKLSAgICAgICAgICAgIGluZGV4ID0gb2Zmc2V0ICsgYnl0ZXMucmVhZEludCgpOwotICAgICAgICAgICAgZ290b19zZXQuc2V0KGluZGV4KTsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7IC8vIExPT0tVUFNXSVRDSAotICAgICAgICAgIGludCBucGFpcnMgPSBieXRlcy5yZWFkSW50KCk7Ci0KLSAgICAgICAgICBvZmZzZXQgPSBieXRlcy5nZXRJbmRleCgpIC0gOCAtIG5vX3BhZF9ieXRlcyAtIDE7Ci0gICAgICAgICAgZGVmYXVsdF9vZmZzZXQgKz0gb2Zmc2V0OwotICAgICAgICAgIGdvdG9fc2V0LnNldChkZWZhdWx0X29mZnNldCk7Ci0KLSAgICAgICAgICBmb3IoaW50IGo9MDsgaiA8IG5wYWlyczsgaisrKSB7Ci0gICAgICAgICAgICBpbnQgbWF0Y2ggPSBieXRlcy5yZWFkSW50KCk7Ci0KLSAgICAgICAgICAgIGluZGV4ID0gb2Zmc2V0ICsgYnl0ZXMucmVhZEludCgpOwotICAgICAgICAgICAgZ290b19zZXQuc2V0KGluZGV4KTsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgYnJlYWs7Ci0KLSAgICAgIGNhc2UgR09UTzogICAgICBjYXNlIElGRVE6ICAgICAgY2FzZSBJRkdFOiAgICAgIGNhc2UgSUZHVDoKLSAgICAgIGNhc2UgSUZMRTogICAgICBjYXNlIElGTFQ6Ci0gICAgICBjYXNlIElGTkU6ICAgICAgY2FzZSBJRk5PTk5VTEw6IGNhc2UgSUZOVUxMOiAgICBjYXNlIElGX0FDTVBFUToKLSAgICAgIGNhc2UgSUZfQUNNUE5FOiBjYXNlIElGX0lDTVBFUTogY2FzZSBJRl9JQ01QR0U6IGNhc2UgSUZfSUNNUEdUOgotICAgICAgY2FzZSBJRl9JQ01QTEU6IGNhc2UgSUZfSUNNUExUOiBjYXNlIElGX0lDTVBORTogY2FzZSBKU1I6Ci0gICAgICAgIC8vYnl0ZXMucmVhZEJ5dGUoKTsgLy8gU2tpcCBhbHJlYWR5IHJlYWQgYnl0ZQotICAgICAgICBpbmRleCA9IGJ5dGVzLmdldEluZGV4KCkgKyBieXRlcy5yZWFkU2hvcnQoKSAtIDE7Ci0KLSAgICAgICAgZ290b19zZXQuc2V0KGluZGV4KTsKLSAgICAgICAgYnJlYWs7Ci0KLSAgICAgIGNhc2UgR09UT19XOiBjYXNlIEpTUl9XOgotICAgICAgICAvL2J5dGVzLnJlYWRCeXRlKCk7IC8vIFNraXAgYWxyZWFkeSByZWFkIGJ5dGUKLSAgICAgICAgaW5kZXggPSBieXRlcy5nZXRJbmRleCgpICsgYnl0ZXMucmVhZEludCgpIC0gMTsKLSAgICAgICAgZ290b19zZXQuc2V0KGluZGV4KTsKLSAgICAgICAgYnJlYWs7Ci0KLSAgICAgIGRlZmF1bHQ6Ci0gICAgICAgIGJ5dGVzLnVucmVhZEJ5dGUoKTsKLSAgICAgICAgY29kZVRvSFRNTChieXRlcywgMCk7IC8vIElnbm9yZSBvdXRwdXQKLSAgICAgIH0KLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogV3JpdGUgYSBzaW5nbGUgbWV0aG9kIHdpdGggdGhlIGJ5dGUgY29kZSBhc3NvY2lhdGVkIHdpdGggaXQuCi0gICAqLwotICBwcml2YXRlIHZvaWQgd3JpdGVNZXRob2QoTWV0aG9kIG1ldGhvZCwgaW50IG1ldGhvZF9udW1iZXIpCi0gICAgICAgdGhyb3dzIElPRXhjZXB0aW9uCi0gIHsKLSAgICAvLyBHZXQgcmF3IHNpZ25hdHVyZQotICAgIFN0cmluZyAgICAgICBzaWduYXR1cmUgPSBtZXRob2QuZ2V0U2lnbmF0dXJlKCk7Ci0gICAgLy8gR2V0IGFycmF5IG9mIHN0cmluZ3MgY29udGFpbmluZyB0aGUgYXJndW1lbnQgdHlwZXMKLSAgICBTdHJpbmdbXSAgICAgYXJncyAgICAgID0gVXRpbGl0eS5tZXRob2RTaWduYXR1cmVBcmd1bWVudFR5cGVzKHNpZ25hdHVyZSwgZmFsc2UpOwotICAgIC8vIEdldCByZXR1cm4gdHlwZSBzdHJpbmcKLSAgICBTdHJpbmcgICAgICAgdHlwZSAgICAgID0gVXRpbGl0eS5tZXRob2RTaWduYXR1cmVSZXR1cm5UeXBlKHNpZ25hdHVyZSwgZmFsc2UpOwotICAgIC8vIEdldCBtZXRob2QgbmFtZQotICAgIFN0cmluZyAgICAgICBuYW1lICAgICAgPSBtZXRob2QuZ2V0TmFtZSgpOwotICAgIFN0cmluZyAgICAgICBodG1sX25hbWUgPSBDbGFzczJIVE1MLnRvSFRNTChuYW1lKTsKLSAgICAvLyBHZXQgbWV0aG9kJ3MgYWNjZXNzIGZsYWdzCi0gICAgU3RyaW5nICAgICAgIGFjY2VzcyAgICA9IFV0aWxpdHkuYWNjZXNzVG9TdHJpbmcobWV0aG9kLmdldEFjY2Vzc0ZsYWdzKCkpOwotICAgIGFjY2VzcyA9IFV0aWxpdHkucmVwbGFjZShhY2Nlc3MsICIgIiwgIiZuYnNwOyIpOwotICAgIC8vIEdldCB0aGUgbWV0aG9kJ3MgYXR0cmlidXRlcywgdGhlIENvZGUgQXR0cmlidXRlIGluIHBhcnRpY3VsYXIKLSAgICBBdHRyaWJ1dGVbXSAgYXR0cmlidXRlcz0gbWV0aG9kLmdldEF0dHJpYnV0ZXMoKTsKLQotICAgIGZpbGUucHJpbnQoIjxQPjxCPjxGT05UIENPTE9SPVwiI0ZGMDAwMFwiPiIgKyBhY2Nlc3MgKyAiPC9GT05UPiZuYnNwOyIgKwotICAgICAgICAgICAgICAgIjxBIE5BTUU9bWV0aG9kIiArIG1ldGhvZF9udW1iZXIgKyAiPiIgKyBDbGFzczJIVE1MLnJlZmVyZW5jZVR5cGUodHlwZSkgKwotICAgICAgICAgICAgICAgIjwvQT4mbmJzcDxBIEhSRUY9XCIiICsgY2xhc3NfbmFtZSArICJfbWV0aG9kcy5odG1sI21ldGhvZCIgKyBtZXRob2RfbnVtYmVyICsKLSAgICAgICAgICAgICAgICJcIiBUQVJHRVQ9TWV0aG9kcz4iICsgaHRtbF9uYW1lICsgIjwvQT4oIik7Ci0KLSAgICBmb3IoaW50IGk9MDsgaSA8IGFyZ3MubGVuZ3RoOyBpKyspIHsKLSAgICAgIGZpbGUucHJpbnQoQ2xhc3MySFRNTC5yZWZlcmVuY2VUeXBlKGFyZ3NbaV0pKTsKLSAgICAgIGlmKGkgPCBhcmdzLmxlbmd0aCAtIDEpCi0gICAgICAgIGZpbGUucHJpbnQoIiwmbmJzcDsiKTsKLSAgICB9Ci0KLSAgICBmaWxlLnByaW50bG4oIik8L0I+PC9QPiIpOwotCi0gICAgQ29kZSBjPW51bGw7Ci0gICAgYnl0ZVtdIGNvZGU9bnVsbDsKLQotICAgIGlmKGF0dHJpYnV0ZXMubGVuZ3RoID4gMCkgewotICAgICAgZmlsZS5wcmludCgiPEg0PkF0dHJpYnV0ZXM8L0g0PjxVTD5cbiIpOwotICAgICAgZm9yKGludCBpPTA7IGkgPCBhdHRyaWJ1dGVzLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgIGJ5dGUgdGFnID0gYXR0cmlidXRlc1tpXS5nZXRUYWcoKTsKLQotICAgICAgICBpZih0YWcgIT0gQVRUUl9VTktOT1dOKQotICAgICAgICAgIGZpbGUucHJpbnQoIjxMST48QSBIUkVGPVwiIiArIGNsYXNzX25hbWUgKyAiX2F0dHJpYnV0ZXMuaHRtbCNtZXRob2QiICsgbWV0aG9kX251bWJlciArICJAIiArIGkgKwotICAgICAgICAgICAgICAgICAgICAgIlwiIFRBUkdFVD1BdHRyaWJ1dGVzPiIgKyBBVFRSSUJVVEVfTkFNRVNbdGFnXSArICI8L0E+PC9MST5cbiIpOwotICAgICAgICBlbHNlCi0gICAgICAgICAgZmlsZS5wcmludCgiPExJPiIgKyBhdHRyaWJ1dGVzW2ldICsgIjwvTEk+Iik7Ci0KLSAgICAgICAgaWYodGFnID09IEFUVFJfQ09ERSkgewotICAgICAgICAgIGMgPSAoQ29kZSlhdHRyaWJ1dGVzW2ldOwotICAgICAgICAgIEF0dHJpYnV0ZVtdIGF0dHJpYnV0ZXMyID0gYy5nZXRBdHRyaWJ1dGVzKCk7Ci0gICAgICAgICAgY29kZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IGMuZ2V0Q29kZSgpOwotCi0gICAgICAgICAgZmlsZS5wcmludCgiPFVMPiIpOwotICAgICAgICAgIGZvcihpbnQgaj0wOyBqIDwgYXR0cmlidXRlczIubGVuZ3RoOyBqKyspIHsKLSAgICAgICAgICAgIHRhZyA9IGF0dHJpYnV0ZXMyW2pdLmdldFRhZygpOwotICAgICAgICAgICAgZmlsZS5wcmludCgiPExJPjxBIEhSRUY9XCIiICsgY2xhc3NfbmFtZSArICJfYXR0cmlidXRlcy5odG1sIyIgKwotICAgICAgICAgICAgICAgICAgICAgICAibWV0aG9kIiArIG1ldGhvZF9udW1iZXIgKyAiQCIgKyBpICsgIkAiICsgaiArICJcIiBUQVJHRVQ9QXR0cmlidXRlcz4iICsKLSAgICAgICAgICAgICAgICAgICAgICAgQVRUUklCVVRFX05BTUVTW3RhZ10gKyAiPC9BPjwvTEk+XG4iKTsKLQotICAgICAgICAgIH0KLSAgICAgICAgICBmaWxlLnByaW50KCI8L1VMPiIpOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgICBmaWxlLnByaW50bG4oIjwvVUw+Iik7Ci0gICAgfQotCi0gICAgaWYoY29kZSAhPSBudWxsKSB7IC8vIE5vIGNvZGUsIGFuIGFic3RyYWN0IG1ldGhvZCwgZS5nLgotICAgICAgLy9TeXN0ZW0ub3V0LnByaW50bG4obmFtZSArICJcbiIgKyBVdGlsaXR5LmNvZGVUb1N0cmluZyhjb2RlLCBjb25zdGFudF9wb29sLCAwLCAtMSkpOwotCi0gICAgICAvLyBQcmludCB0aGUgYnl0ZSBjb2RlCi0gICAgICBCeXRlU2VxdWVuY2Ugc3RyZWFtID0gbmV3IEJ5dGVTZXF1ZW5jZShjb2RlKTsKLSAgICAgIHN0cmVhbS5tYXJrKHN0cmVhbS5hdmFpbGFibGUoKSk7Ci0gICAgICBmaW5kR290b3Moc3RyZWFtLCBtZXRob2QsIGMpOwotICAgICAgc3RyZWFtLnJlc2V0KCk7Ci0KLSAgICAgIGZpbGUucHJpbnRsbigiPFRBQkxFIEJPUkRFUj0wPjxUUj48VEggQUxJR049TEVGVD5CeXRlPEJSPm9mZnNldDwvVEg+IiArCi0gICAgICAgICAgICAgICAgICAgIjxUSCBBTElHTj1MRUZUPkluc3RydWN0aW9uPC9USD48VEggQUxJR049TEVGVD5Bcmd1bWVudDwvVEg+Iik7Ci0KLSAgICAgIGZvcihpbnQgaT0wOyBzdHJlYW0uYXZhaWxhYmxlKCkgPiAwOyBpKyspIHsKLSAgICAgICAgaW50IG9mZnNldCA9IHN0cmVhbS5nZXRJbmRleCgpOwotICAgICAgICBTdHJpbmcgc3RyID0gY29kZVRvSFRNTChzdHJlYW0sIG1ldGhvZF9udW1iZXIpOwotICAgICAgICBTdHJpbmcgYW5jaG9yID0gIiI7Ci0KLSAgICAgICAgLyogU2V0IGFuIGFuY2hvciBtYXJrIGlmIHRoaXMgbGluZSBpcyB0YXJnZXR0ZWQgYnkgYSBnb3RvLCBqc3IsIGV0Yy4KLSAgICAgICAgICogRGVmaW5pbmcgYW4gYW5jaG9yIGZvciBldmVyeSBsaW5lIGlzIHZlcnkgaW5lZmZpY2llbnQhCi0gICAgICAgICAqLwotICAgICAgICBpZihnb3RvX3NldC5nZXQob2Zmc2V0KSkKLSAgICAgICAgICBhbmNob3IgPSAiPEEgTkFNRT1jb2RlIiArIG1ldGhvZF9udW1iZXIgKyAiQCIgKyBvZmZzZXQgKyAgIj48L0E+IjsKLQotICAgICAgICBTdHJpbmcgYW5jaG9yMjsKLSAgICAgICAgaWYoc3RyZWFtLmdldEluZGV4KCkgPT0gY29kZS5sZW5ndGgpIC8vIGxhc3QgbG9vcAotICAgICAgICAgIGFuY2hvcjIgPSAiPEEgTkFNRT1jb2RlIiArIG1ldGhvZF9udW1iZXIgKyAiQCIgKyBjb2RlLmxlbmd0aCArICI+IiArIG9mZnNldCArICI8L0E+IjsKLSAgICAgICAgZWxzZQotICAgICAgICAgIGFuY2hvcjIgPSAiIiArIG9mZnNldDsKLQotICAgICAgICBmaWxlLnByaW50bG4oIjxUUiBWQUxJR049VE9QPjxURD4iICsgYW5jaG9yMiArICI8L1REPjxURD4iICsgYW5jaG9yICsgc3RyICsgIjwvVFI+Iik7Ci0gICAgICB9Ci0KLSAgICAgIC8vIE1hcmsgbGFzdCBsaW5lLCBtYXkgYmUgdGFyZ2V0dGVkIGZyb20gQXR0cmlidXRlcyB3aW5kb3cKLSAgICAgIGZpbGUucHJpbnRsbigiPFRSPjxURD4gPC9BPjwvVEQ+PC9UUj4iKTsKLSAgICAgIGZpbGUucHJpbnRsbigiPC9UQUJMRT4iKTsKLSAgICB9Ci0KLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL3V0aWwvQ29uc3RhbnRIVE1MLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvdXRpbC9Db25zdGFudEhUTUwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNTJmMzU5MS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvdXRpbC9Db25zdGFudEhUTUwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI2NSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLnV0aWw7Ci0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKLSAqICAgICJBcGFjaGUgQkNFTCIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKLSAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3IKLSAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICAiQXBhY2hlIEJDRUwiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0Ci0gKiAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5jbGFzc2ZpbGUuKjsKLWltcG9ydCBqYXZhLmlvLio7Ci0KLS8qKgotICogQ29udmVydCBjb25zdGFudCBwb29sIGludG8gSFRNTCBmaWxlLgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKgotICovCi1maW5hbCBjbGFzcyBDb25zdGFudEhUTUwgaW1wbGVtZW50cyBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHMgewotICBwcml2YXRlIFN0cmluZyAgICAgICAgY2xhc3NfbmFtZTsgICAgIC8vIG5hbWUgb2YgY3VycmVudCBjbGFzcwotICBwcml2YXRlIFN0cmluZyAgICAgICAgY2xhc3NfcGFja2FnZTsgIC8vIG5hbWUgb2YgcGFja2FnZQotICBwcml2YXRlIENvbnN0YW50UG9vbCAgY29uc3RhbnRfcG9vbDsgIC8vIHJlZmVyZW5jZSB0byBjb25zdGFudCBwb29sCi0gIHByaXZhdGUgUHJpbnRXcml0ZXIgICBmaWxlOyAgICAgICAgICAgLy8gZmlsZSB0byB3cml0ZSB0bwotICBwcml2YXRlIFN0cmluZ1tdICAgICAgY29uc3RhbnRfcmVmOyAgIC8vIFN0cmluZyB0byByZXR1cm4gZm9yIGNwW2ldCi0gIHByaXZhdGUgQ29uc3RhbnRbXSAgICBjb25zdGFudHM7ICAgICAgLy8gVGhlIGNvbnN0YW50cyBpbiB0aGUgY3AKLSAgcHJpdmF0ZSBNZXRob2RbXSAgICAgIG1ldGhvZHM7Ci0KLSAgQ29uc3RhbnRIVE1MKFN0cmluZyBkaXIsIFN0cmluZyBjbGFzc19uYW1lLCBTdHJpbmcgY2xhc3NfcGFja2FnZSwgTWV0aG9kW10gbWV0aG9kcywKLSAgICAgICAgICAgICAgIENvbnN0YW50UG9vbCBjb25zdGFudF9wb29sKSB0aHJvd3MgSU9FeGNlcHRpb24KLSAgewotICAgIHRoaXMuY2xhc3NfbmFtZSAgICAgPSBjbGFzc19uYW1lOwotICAgIHRoaXMuY2xhc3NfcGFja2FnZSAgPSBjbGFzc19wYWNrYWdlOwotICAgIHRoaXMuY29uc3RhbnRfcG9vbCAgPSBjb25zdGFudF9wb29sOwotICAgIHRoaXMubWV0aG9kcyAgICAgICAgPSBtZXRob2RzOwotICAgIGNvbnN0YW50cyAgICAgICAgICAgPSBjb25zdGFudF9wb29sLmdldENvbnN0YW50UG9vbCgpOwotICAgIGZpbGUgICAgICAgICAgICAgICAgPSBuZXcgUHJpbnRXcml0ZXIobmV3IEZpbGVPdXRwdXRTdHJlYW0oZGlyICsgY2xhc3NfbmFtZSArICJfY3AuaHRtbCIpKTsKLSAgICBjb25zdGFudF9yZWYgICAgICAgID0gbmV3IFN0cmluZ1tjb25zdGFudHMubGVuZ3RoXTsKLSAgICBjb25zdGFudF9yZWZbMF0gICAgID0gIiZsdDt1bmtub3duJmd0OyI7Ci0KLSAgICBmaWxlLnByaW50bG4oIjxIVE1MPjxCT0RZIEJHQ09MT1I9XCIjQzBDMEMwXCI+PFRBQkxFIEJPUkRFUj0wPiIpOwotCi0gICAgLy8gTG9vcCB0aHJvdWdoIGNvbnN0YW50cywgY29uc3RhbnRzWzBdIGlzIHJlc2VydmVkCi0gICAgZm9yKGludCBpPTE7IGkgPCBjb25zdGFudHMubGVuZ3RoOyBpKyspIHsKLSAgICAgIGlmKGkgJSAyID09IDApCi0gICAgICAgIGZpbGUucHJpbnQoIjxUUiBCR0NPTE9SPVwiI0MwQzBDMFwiPjxURD4iKTsKLSAgICAgIGVsc2UKLSAgICAgICAgZmlsZS5wcmludCgiPFRSIEJHQ09MT1I9XCIjQTBBMEEwXCI+PFREPiIpOwotCi0gICAgICBpZihjb25zdGFudHNbaV0gIT0gbnVsbCkKLSAgICAgICAgd3JpdGVDb25zdGFudChpKTsKLQotICAgICAgZmlsZS5wcmludCgiPC9URD48L1RSPlxuIik7Ci0gICAgfQotCi0gICAgZmlsZS5wcmludGxuKCI8L1RBQkxFPjwvQk9EWT48L0hUTUw+Iik7Ci0gICAgZmlsZS5jbG9zZSgpOwotICB9Ci0KLSAgU3RyaW5nIHJlZmVyZW5jZUNvbnN0YW50KGludCBpbmRleCkgewotICAgIHJldHVybiBjb25zdGFudF9yZWZbaW5kZXhdOwotICB9Ci0KLSAgcHJpdmF0ZSB2b2lkIHdyaXRlQ29uc3RhbnQoaW50IGluZGV4KSB7Ci0gICAgYnl0ZSAgIHRhZyA9IGNvbnN0YW50c1tpbmRleF0uZ2V0VGFnKCk7Ci0gICAgaW50ICAgIGNsYXNzX2luZGV4LCBuYW1lX2luZGV4OwotICAgIFN0cmluZyByZWY7Ci0KLSAgICAvLyBUaGUgaGVhZGVyIGlzIGFsd2F5cyB0aGUgc2FtZQotICAgIGZpbGUucHJpbnRsbigiPEg0PiA8QSBOQU1FPWNwIiArIGluZGV4ICsgIj4iICsgaW5kZXggKyAiPC9BPiAiICsgQ09OU1RBTlRfTkFNRVNbdGFnXSArICI8L0g0PiIpOwotCi0gICAgLyogRm9yIGV2ZXJ5IGNvbnN0YW50IHR5cGUgZ2V0IHRoZSBuZWVkZWQgcGFyYW1ldGVycyBhbmQgcHJpbnQgdGhlbSBhcHByb3BpYXRlbHkKLSAgICAgKi8KLSAgICBzd2l0Y2godGFnKSB7Ci0gICAgY2FzZSBDT05TVEFOVF9JbnRlcmZhY2VNZXRob2RyZWY6Ci0gICAgY2FzZSBDT05TVEFOVF9NZXRob2RyZWY6Ci0gICAgICAvLyBHZXQgY2xhc3NfaW5kZXggYW5kIG5hbWVfYW5kX3R5cGVfaW5kZXgsIGRlcGVuZGluZyBvbiB0eXBlCi0gICAgICBpZih0YWcgPT0gQ09OU1RBTlRfTWV0aG9kcmVmKSB7Ci0gICAgICAgIENvbnN0YW50TWV0aG9kcmVmIGMgPSAoQ29uc3RhbnRNZXRob2RyZWYpY29uc3RhbnRfcG9vbC5nZXRDb25zdGFudChpbmRleCwgQ09OU1RBTlRfTWV0aG9kcmVmKTsKLSAgICAgICAgY2xhc3NfaW5kZXggPSBjLmdldENsYXNzSW5kZXgoKTsKLSAgICAgICAgbmFtZV9pbmRleCAgPSBjLmdldE5hbWVBbmRUeXBlSW5kZXgoKTsKLSAgICAgIH0KLSAgICAgIGVsc2UgewotICAgICAgICBDb25zdGFudEludGVyZmFjZU1ldGhvZHJlZiBjMSA9IChDb25zdGFudEludGVyZmFjZU1ldGhvZHJlZiljb25zdGFudF9wb29sLmdldENvbnN0YW50KGluZGV4LCBDT05TVEFOVF9JbnRlcmZhY2VNZXRob2RyZWYpOwotICAgICAgICBjbGFzc19pbmRleCA9IGMxLmdldENsYXNzSW5kZXgoKTsKLSAgICAgICAgbmFtZV9pbmRleCAgPSBjMS5nZXROYW1lQW5kVHlwZUluZGV4KCk7Ci0gICAgICB9Ci0KLSAgICAgIC8vIEdldCBtZXRob2QgbmFtZSBhbmQgaXRzIGNsYXNzCi0gICAgICBTdHJpbmcgbWV0aG9kX25hbWUgICAgICAgID0gY29uc3RhbnRfcG9vbC5jb25zdGFudFRvU3RyaW5nKG5hbWVfaW5kZXgsIENPTlNUQU5UX05hbWVBbmRUeXBlKTsKLSAgICAgIFN0cmluZyBodG1sX21ldGhvZF9uYW1lID0gQ2xhc3MySFRNTC50b0hUTUwobWV0aG9kX25hbWUpOwotCi0gICAgICAvLyBQYXJ0aWFsbHkgY29tcGFjdGVkIGNsYXNzIG5hbWUsIGkuZS4sIC8gLT4gLgotICAgICAgU3RyaW5nIG1ldGhvZF9jbGFzcyA9IGNvbnN0YW50X3Bvb2wuY29uc3RhbnRUb1N0cmluZyhjbGFzc19pbmRleCwgQ09OU1RBTlRfQ2xhc3MpOwotICAgICAgU3RyaW5nIHNob3J0X21ldGhvZF9jbGFzcyAgICAgICAgID0gVXRpbGl0eS5jb21wYWN0Q2xhc3NOYW1lKG1ldGhvZF9jbGFzcyk7IC8vIEkuZS4sIHJlbW92ZSBqYXZhLmxhbmcuCi0gICAgICBzaG9ydF9tZXRob2RfY2xhc3MgPSBVdGlsaXR5LmNvbXBhY3RDbGFzc05hbWUobWV0aG9kX2NsYXNzKTsgLy8gSS5lLiwgcmVtb3ZlIGphdmEubGFuZy4KLSAgICAgIHNob3J0X21ldGhvZF9jbGFzcyA9IFV0aWxpdHkuY29tcGFjdENsYXNzTmFtZShzaG9ydF9tZXRob2RfY2xhc3MsIGNsYXNzX3BhY2thZ2UgKyAiLiIsIHRydWUpOyAvLyBSZW1vdmUgY2xhc3MgcGFja2FnZSBwcmVmaXgKLQotICAgICAgLy8gR2V0IG1ldGhvZCBzaWduYXR1cmUKLSAgICAgIENvbnN0YW50TmFtZUFuZFR5cGUgYzIgPSAoQ29uc3RhbnROYW1lQW5kVHlwZSljb25zdGFudF9wb29sLmdldENvbnN0YW50KG5hbWVfaW5kZXgsIENPTlNUQU5UX05hbWVBbmRUeXBlKTsKLSAgICAgIFN0cmluZyBzaWduYXR1cmUgPSBjb25zdGFudF9wb29sLmNvbnN0YW50VG9TdHJpbmcoYzIuZ2V0U2lnbmF0dXJlSW5kZXgoKSwgQ09OU1RBTlRfVXRmOCk7Ci0gICAgICAvLyBHZXQgYXJyYXkgb2Ygc3RyaW5ncyBjb250YWluaW5nIHRoZSBhcmd1bWVudCB0eXBlcwotICAgICAgU3RyaW5nW10gYXJncyA9IFV0aWxpdHkubWV0aG9kU2lnbmF0dXJlQXJndW1lbnRUeXBlcyhzaWduYXR1cmUsIGZhbHNlKTsKLQotICAgICAgLy8gR2V0IHJldHVybiB0eXBlIHN0cmluZwotICAgICAgU3RyaW5nIHR5cGUgPSBVdGlsaXR5Lm1ldGhvZFNpZ25hdHVyZVJldHVyblR5cGUoc2lnbmF0dXJlLCBmYWxzZSk7Ci0gICAgICBTdHJpbmcgcmV0X3R5cGUgPSBDbGFzczJIVE1MLnJlZmVyZW5jZVR5cGUodHlwZSk7Ci0KLSAgICAgIFN0cmluZ0J1ZmZlciBidWYgPSBuZXcgU3RyaW5nQnVmZmVyKCIoIik7Ci0gICAgICBmb3IoaW50IGk9MDsgaSA8IGFyZ3MubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgYnVmLmFwcGVuZChDbGFzczJIVE1MLnJlZmVyZW5jZVR5cGUoYXJnc1tpXSkpOwotICAgICAgICBpZihpIDwgYXJncy5sZW5ndGggLSAxKQotICAgICAgICAgIGJ1Zi5hcHBlbmQoIiwmbmJzcDsiKTsKLSAgICAgIH0KLSAgICAgIGJ1Zi5hcHBlbmQoIikiKTsKLQotICAgICAgU3RyaW5nIGFyZ190eXBlcyA9IGJ1Zi50b1N0cmluZygpOwotCi0gICAgICBpZihtZXRob2RfY2xhc3MuZXF1YWxzKGNsYXNzX25hbWUpKSAvLyBNZXRob2QgaXMgbG9jYWwgdG8gY2xhc3MKLSAgICAgICAgcmVmID0gIjxBIEhSRUY9XCIiICsgY2xhc3NfbmFtZSArICJfY29kZS5odG1sI21ldGhvZCIgKyBnZXRNZXRob2ROdW1iZXIobWV0aG9kX25hbWUgKyBzaWduYXR1cmUpICsKLSAgICAgICAgICAiXCIgVEFSR0VUPUNvZGU+IiArIGh0bWxfbWV0aG9kX25hbWUgKyAiPC9BPiI7Ci0gICAgICBlbHNlCi0gICAgICAgIHJlZiA9ICI8QSBIUkVGPVwiIiArIG1ldGhvZF9jbGFzcyArICIuaHRtbCIgKyAiXCIgVEFSR0VUPV90b3A+IiArIHNob3J0X21ldGhvZF9jbGFzcyArCi0gICAgICAgICAgIjwvQT4uIiArIGh0bWxfbWV0aG9kX25hbWU7Ci0KLSAgICAgIGNvbnN0YW50X3JlZltpbmRleF0gPSByZXRfdHlwZSArICImbmJzcDs8QSBIUkVGPVwiIiArIGNsYXNzX25hbWUgKyAiX2NwLmh0bWwjY3AiICsgY2xhc3NfaW5kZXggKwotICAgICAgICAiXCIgVEFSR0VUPUNvbnN0YW50cz4iICsKLSAgICAgICAgc2hvcnRfbWV0aG9kX2NsYXNzICsgIjwvQT4uPEEgSFJFRj1cIiIgKyBjbGFzc19uYW1lICsgIl9jcC5odG1sI2NwIiArCi0gICAgICAgIGluZGV4ICsgIlwiIFRBUkdFVD1Db25zdGFudFBvb2w+IiArIGh0bWxfbWV0aG9kX25hbWUgKyAiPC9BPiZuYnNwOyIgKyBhcmdfdHlwZXM7Ci0KLSAgICAgIGZpbGUucHJpbnRsbigiPFA+PFRUPiIgKyByZXRfdHlwZSArICImbmJzcDsiICsgcmVmICsgYXJnX3R5cGVzICsgIiZuYnNwOzwvVFQ+XG48VUw+IiArCi0gICAgICAgICAgICAgICAgICAgIjxMST48QSBIUkVGPVwiI2NwIiArIGNsYXNzX2luZGV4ICsgIlwiPkNsYXNzIGluZGV4KCIgKyBjbGFzc19pbmRleCArICAgICAgICAiKTwvQT5cbiIgKwotICAgICAgICAgICAgICAgICAgICI8TEk+PEEgSFJFRj1cIiNjcCIgKyBuYW1lX2luZGV4ICsgIlwiPk5hbWVBbmRUeXBlIGluZGV4KCIgKyBuYW1lX2luZGV4ICsgIik8L0E+PC9VTD4iKTsKLSAgICAgIGJyZWFrOwotCi0gICAgY2FzZSBDT05TVEFOVF9GaWVsZHJlZjoKLSAgICAgIC8vIEdldCBjbGFzc19pbmRleCBhbmQgbmFtZV9hbmRfdHlwZV9pbmRleAotICAgICAgQ29uc3RhbnRGaWVsZHJlZiBjMyA9IChDb25zdGFudEZpZWxkcmVmKWNvbnN0YW50X3Bvb2wuZ2V0Q29uc3RhbnQoaW5kZXgsIENPTlNUQU5UX0ZpZWxkcmVmKTsKLSAgICAgIGNsYXNzX2luZGV4ID0gYzMuZ2V0Q2xhc3NJbmRleCgpOwotICAgICAgbmFtZV9pbmRleCAgPSBjMy5nZXROYW1lQW5kVHlwZUluZGV4KCk7Ci0KLSAgICAgIC8vIEdldCBtZXRob2QgbmFtZSBhbmQgaXRzIGNsYXNzIChjb21wYWN0ZWQpCi0gICAgICBTdHJpbmcgZmllbGRfY2xhc3MgPSBjb25zdGFudF9wb29sLmNvbnN0YW50VG9TdHJpbmcoY2xhc3NfaW5kZXgsIENPTlNUQU5UX0NsYXNzKTsKLSAgICAgIFN0cmluZyBzaG9ydF9maWVsZF9jbGFzcyA9IFV0aWxpdHkuY29tcGFjdENsYXNzTmFtZShmaWVsZF9jbGFzcyk7IC8vIEkuZS4sIHJlbW92ZSBqYXZhLmxhbmcuCi0gICAgICBzaG9ydF9maWVsZF9jbGFzcyA9IFV0aWxpdHkuY29tcGFjdENsYXNzTmFtZShzaG9ydF9maWVsZF9jbGFzcywgY2xhc3NfcGFja2FnZSArICIuIiwgdHJ1ZSk7IC8vIFJlbW92ZSBjbGFzcyBwYWNrYWdlIHByZWZpeAotCi0gICAgICBTdHJpbmcgZmllbGRfbmFtZSAgPSBjb25zdGFudF9wb29sLmNvbnN0YW50VG9TdHJpbmcobmFtZV9pbmRleCwgQ09OU1RBTlRfTmFtZUFuZFR5cGUpOwotCi0gICAgICBpZihmaWVsZF9jbGFzcy5lcXVhbHMoY2xhc3NfbmFtZSkpIC8vIEZpZWxkIGlzIGxvY2FsIHRvIGNsYXNzCi0gICAgICAgIHJlZiA9ICI8QSBIUkVGPVwiIiArIGZpZWxkX2NsYXNzICsgIl9tZXRob2RzLmh0bWwjZmllbGQiICsKLSAgICAgICAgICBmaWVsZF9uYW1lICsgIlwiIFRBUkdFVD1NZXRob2RzPiIgKyBmaWVsZF9uYW1lICsgIjwvQT4iOwotICAgICAgZWxzZQotICAgICAgICByZWYgPSAiPEEgSFJFRj1cIiIgKyBmaWVsZF9jbGFzcyArICIuaHRtbFwiIFRBUkdFVD1fdG9wPiIgKwotICAgICAgICAgIHNob3J0X2ZpZWxkX2NsYXNzICsgIjwvQT4uIiArIGZpZWxkX25hbWUgKyAiXG4iOwotCi0gICAgICBjb25zdGFudF9yZWZbaW5kZXhdID0gIjxBIEhSRUY9XCIiICsgY2xhc3NfbmFtZSArICJfY3AuaHRtbCNjcCIgKyBjbGFzc19pbmRleCArICAgIlwiIFRBUkdFVD1Db25zdGFudHM+IiArCi0gICAgICAgIHNob3J0X2ZpZWxkX2NsYXNzICsgIjwvQT4uPEEgSFJFRj1cIiIgKyBjbGFzc19uYW1lICsgIl9jcC5odG1sI2NwIiArCi0gICAgICAgIGluZGV4ICsgIlwiIFRBUkdFVD1Db25zdGFudFBvb2w+IiArIGZpZWxkX25hbWUgKyAiPC9BPiI7Ci0KLSAgICAgIGZpbGUucHJpbnRsbigiPFA+PFRUPiIgKyByZWYgKyAiPC9UVD48QlI+XG4iICsgIjxVTD4iICsKLSAgICAgICAgICAgICAgICAgICAiPExJPjxBIEhSRUY9XCIjY3AiICsgY2xhc3NfaW5kZXggKyAiXCI+Q2xhc3MoIiArIGNsYXNzX2luZGV4ICsgICAgICAiKTwvQT48QlI+XG4iICsKLSAgICAgICAgICAgICAgICAgICAiPExJPjxBIEhSRUY9XCIjY3AiICsgbmFtZV9pbmRleCArICJcIj5OYW1lQW5kVHlwZSgiICsgbmFtZV9pbmRleCArICIpPC9BPjwvVUw+Iik7Ci0gICAgICBicmVhazsKLQotICAgIGNhc2UgQ09OU1RBTlRfQ2xhc3M6Ci0gICAgICBDb25zdGFudENsYXNzIGM0ID0gKENvbnN0YW50Q2xhc3MpY29uc3RhbnRfcG9vbC5nZXRDb25zdGFudChpbmRleCwgQ09OU1RBTlRfQ2xhc3MpOwotICAgICAgbmFtZV9pbmRleCAgPSBjNC5nZXROYW1lSW5kZXgoKTsKLSAgICAgIFN0cmluZyBjbGFzc19uYW1lMiAgPSBjb25zdGFudF9wb29sLmNvbnN0YW50VG9TdHJpbmcoaW5kZXgsIHRhZyk7IC8vIC8gLT4gLgotICAgICAgU3RyaW5nIHNob3J0X2NsYXNzX25hbWUgPSBVdGlsaXR5LmNvbXBhY3RDbGFzc05hbWUoY2xhc3NfbmFtZTIpOyAvLyBJLmUuLCByZW1vdmUgamF2YS5sYW5nLgotICAgICAgc2hvcnRfY2xhc3NfbmFtZSA9IFV0aWxpdHkuY29tcGFjdENsYXNzTmFtZShzaG9ydF9jbGFzc19uYW1lLCBjbGFzc19wYWNrYWdlICsgIi4iLCB0cnVlKTsgLy8gUmVtb3ZlIGNsYXNzIHBhY2thZ2UgcHJlZml4Ci0KLSAgICAgIHJlZiA9ICI8QSBIUkVGPVwiIiArIGNsYXNzX25hbWUyICsgIi5odG1sXCIgVEFSR0VUPV90b3A+IiArIHNob3J0X2NsYXNzX25hbWUgKyAiPC9BPiI7Ci0gICAgICBjb25zdGFudF9yZWZbaW5kZXhdID0gIjxBIEhSRUY9XCIiICsgY2xhc3NfbmFtZSArICJfY3AuaHRtbCNjcCIgKyBpbmRleCArCi0gICAgICAgICJcIiBUQVJHRVQ9Q29uc3RhbnRQb29sPiIgKyBzaG9ydF9jbGFzc19uYW1lICsgIjwvQT4iOwotCi0gICAgICBmaWxlLnByaW50bG4oIjxQPjxUVD4iICsgcmVmICsgIjwvVFQ+PFVMPiIgKwotICAgICAgICAgICAgICAgICAgICI8TEk+PEEgSFJFRj1cIiNjcCIgKyBuYW1lX2luZGV4ICsgIlwiPk5hbWUgaW5kZXgoIiArIG5hbWVfaW5kZXggKyAgICIpPC9BPjwvVUw+XG4iKTsKLSAgICAgIGJyZWFrOwotCi0gICAgY2FzZSBDT05TVEFOVF9TdHJpbmc6Ci0gICAgICBDb25zdGFudFN0cmluZyBjNSA9IChDb25zdGFudFN0cmluZyljb25zdGFudF9wb29sLmdldENvbnN0YW50KGluZGV4LCBDT05TVEFOVF9TdHJpbmcpOwotICAgICAgbmFtZV9pbmRleCA9IGM1LmdldFN0cmluZ0luZGV4KCk7Ci0KLSAgICAgIFN0cmluZyBzdHIgPSBDbGFzczJIVE1MLnRvSFRNTChjb25zdGFudF9wb29sLmNvbnN0YW50VG9TdHJpbmcoaW5kZXgsIHRhZykpOwotCi0gICAgICBmaWxlLnByaW50bG4oIjxQPjxUVD4iICsgc3RyICsgIjwvVFQ+PFVMPiIgKwotICAgICAgICAgICAgICAgICAgICI8TEk+PEEgSFJFRj1cIiNjcCIgKyBuYW1lX2luZGV4ICsgIlwiPk5hbWUgaW5kZXgoIiArIG5hbWVfaW5kZXggKyAgICIpPC9BPjwvVUw+XG4iKTsKLSAgICAgIGJyZWFrOwotCi0gICAgY2FzZSBDT05TVEFOVF9OYW1lQW5kVHlwZToKLSAgICAgIENvbnN0YW50TmFtZUFuZFR5cGUgYzYgPSAoQ29uc3RhbnROYW1lQW5kVHlwZSljb25zdGFudF9wb29sLmdldENvbnN0YW50KGluZGV4LCBDT05TVEFOVF9OYW1lQW5kVHlwZSk7Ci0gICAgICBuYW1lX2luZGV4ID0gYzYuZ2V0TmFtZUluZGV4KCk7Ci0gICAgICBpbnQgc2lnbmF0dXJlX2luZGV4ID0gYzYuZ2V0U2lnbmF0dXJlSW5kZXgoKTsKLQotICAgICAgZmlsZS5wcmludGxuKCI8UD48VFQ+IiArIENsYXNzMkhUTUwudG9IVE1MKGNvbnN0YW50X3Bvb2wuY29uc3RhbnRUb1N0cmluZyhpbmRleCwgdGFnKSkgKyAiPC9UVD48VUw+IiArCi0gICAgICAgICAgICAgICAgICAgIjxMST48QSBIUkVGPVwiI2NwIiArIG5hbWVfaW5kZXggKyAiXCI+TmFtZSBpbmRleCgiICsgbmFtZV9pbmRleCArICIpPC9BPlxuIiArCi0gICAgICAgICAgICAgICAgICAgIjxMST48QSBIUkVGPVwiI2NwIiArIHNpZ25hdHVyZV9pbmRleCArICJcIj5TaWduYXR1cmUgaW5kZXgoIiArCi0gICAgICAgICAgICAgICAgICAgc2lnbmF0dXJlX2luZGV4ICsgIik8L0E+PC9VTD5cbiIpOwotICAgICAgYnJlYWs7Ci0KLSAgICBkZWZhdWx0OgotICAgICAgZmlsZS5wcmludGxuKCI8UD48VFQ+IiArIENsYXNzMkhUTUwudG9IVE1MKGNvbnN0YW50X3Bvb2wuY29uc3RhbnRUb1N0cmluZyhpbmRleCwgdGFnKSkgKyAiPC9UVD5cbiIpOwotICAgIH0gLy8gc3dpdGNoCi0gIH0KLQotICBwcml2YXRlIGZpbmFsIGludCBnZXRNZXRob2ROdW1iZXIoU3RyaW5nIHN0cikgewotICAgIGZvcihpbnQgaT0wOyBpIDwgbWV0aG9kcy5sZW5ndGg7IGkrKykgewotICAgICAgU3RyaW5nIGNtcCA9IG1ldGhvZHNbaV0uZ2V0TmFtZSgpICsgbWV0aG9kc1tpXS5nZXRTaWduYXR1cmUoKTsKLSAgICAgIGlmKGNtcC5lcXVhbHMoc3RyKSkKLSAgICAgICAgcmV0dXJuIGk7Ci0gICAgfQotICAgIHJldHVybiAtMTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL3V0aWwvSW5zdHJ1Y3Rpb25GaW5kZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC91dGlsL0luc3RydWN0aW9uRmluZGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDE2MmFmZDEuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL3V0aWwvSW5zdHJ1Y3Rpb25GaW5kZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQ0MyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC51dGlsOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi1pbXBvcnQgamF2YS51dGlsLio7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuKjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUucmVnZXhwLmludGVybmFsLio7Ci0KLS8qKgotICogSW5zdHJ1Y3Rpb25GaW5kZXIgaXMgYSB0b29sIHRvIHNlYXJjaCBmb3IgZ2l2ZW4gaW5zdHJ1Y3Rpb25zIHBhdHRlcm5zLAotICogaS5lLiwgbWF0Y2ggc2VxdWVuY2VzIG9mIGluc3RydWN0aW9ucyBpbiBhbiBpbnN0cnVjdGlvbiBsaXN0IHZpYQotICogcmVndWxhciBleHByZXNzaW9ucy4gVGhpcyBjYW4gYmUgdXNlZCwgZS5nLiwgaW4gb3JkZXIgdG8gaW1wbGVtZW50Ci0gKiBhIHBlZXAgaG9sZSBvcHRpbWl6ZXIgdGhhdCBsb29rcyBmb3IgY29kZSBwYXR0ZXJucyBhbmQgcmVwbGFjZXMKLSAqIHRoZW0gd2l0aCBmYXN0ZXIgZXF1aXZhbGVudHMuCi0gKgotICogPHA+VGhpcyBjbGFzcyBpbnRlcm5hbGx5IHVzZXMgdGhlIDxhIGhyZWY9Imh0dHA6Ly9qYWthcnRhLmFwYWNoZS5vcmcvcmVnZXhwLyI+Ci0gKiBSZWdleHA8L2E+IHBhY2thZ2UgdG8gc2VhcmNoIGZvciByZWd1bGFyIGV4cHJlc3Npb25zLgotICoKLSAqIEEgdHlwaWNhbCBhcHBsaWNhdGlvbiB3b3VsZCBsb29rIGxpa2UgdGhpczoKLTxwcmU+Ci0gICAgSW5zdHJ1Y3Rpb25GaW5kZXIgZiAgID0gbmV3IEluc3RydWN0aW9uRmluZGVyKGlsKTsKLSAgICBTdHJpbmcgICAgICAgICAgICBwYXQgPSAiSWZJbnN0cnVjdGlvbiBJQ09OU1RfMCBHT1RPIElDT05TVF8xIE5PUCAoSUZFUXxJRk5FKSI7Ci0KLSAgICBmb3IoSXRlcmF0b3IgaSA9IGYuc2VhcmNoKHBhdCwgY29uc3RyYWludCk7IGkuaGFzTmV4dCgpOyApIHsKLSAgICAgIEluc3RydWN0aW9uSGFuZGxlW10gbWF0Y2ggPSAoSW5zdHJ1Y3Rpb25IYW5kbGVbXSlpLm5leHQoKTsKLSAgICAgIC4uLgotICAgICAgaWwuZGVsZXRlKG1hdGNoWzFdLCBtYXRjaFs1XSk7Ci0gICAgICAuLi4KLSAgICB9Ci08L3ByZT4KLSAqIEBhdXRob3IgIDxBIEhSRUY9Imh0dHA6Ly93d3cuYmVybGluLmRlL35tYXJrdXMuZGFobS8iPk0uIERhaG08L0E+Ci0gKiBAc2VlIEluc3RydWN0aW9uCi0gKiBAc2VlIEluc3RydWN0aW9uTGlzdAotICovCi1wdWJsaWMgY2xhc3MgSW5zdHJ1Y3Rpb25GaW5kZXIgewotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgT0ZGU0VUICAgICA9IDMyNzY3OyAvLyBjaGFyICsgT0ZGU0VUIGlzIG91dHNpZGUgb2YgTEFUSU4tMQotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTk9fT1BDT0RFUyA9IDI1NjsgICAvLyBQb3RlbnRpYWwgbnVtYmVyLCBzb21lIGFyZSBub3QgdXNlZAotCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIEhhc2hNYXAgbWFwID0gbmV3IEhhc2hNYXAoKTsgLy8gTWFwPFN0cmluZyxQYXR0ZXJuPgotCi0gIHByaXZhdGUgSW5zdHJ1Y3Rpb25MaXN0ICAgICBpbDsKLSAgcHJpdmF0ZSBTdHJpbmcgICAgICAgICAgICAgIGlsX3N0cmluZzsgICAgLy8gaW5zdHJ1Y3Rpb24gbGlzdCBhcyBzdHJpbmcKLSAgcHJpdmF0ZSBJbnN0cnVjdGlvbkhhbmRsZVtdIGhhbmRsZXM7ICAgICAgLy8gbWFwIGluc3RydWN0aW9uIGxpc3QgdG8gYXJyYXkKLQotICAvKioKLSAgICogQHBhcmFtIGlsIGluc3RydWN0aW9uIGxpc3QgdG8gc2VhcmNoIGZvciBnaXZlbiBwYXR0ZXJucwotICAgKi8KLSAgcHVibGljIEluc3RydWN0aW9uRmluZGVyKEluc3RydWN0aW9uTGlzdCBpbCkgewotICAgIHRoaXMuaWwgPSBpbDsKLSAgICByZXJlYWQoKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXJlYWQgdGhlIGluc3RydWN0aW9uIGxpc3QsIGUuZy4sIGFmdGVyIHlvdSd2ZSBhbHRlcmVkIHRoZSBsaXN0IHVwb24gYSBtYXRjaC4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHJlcmVhZCgpIHsKLSAgICBpbnQgICAgc2l6ZSAgPSBpbC5nZXRMZW5ndGgoKTsKLSAgICBjaGFyW10gYnVmICAgPSBuZXcgY2hhcltzaXplXTsgLy8gQ3JlYXRlIGEgc3RyaW5nIHdpdGggbGVuZ3RoIGVxdWFsIHRvIGlsIGxlbmd0aAotICAgIGhhbmRsZXMgICAgICA9IGlsLmdldEluc3RydWN0aW9uSGFuZGxlcygpOwotCi0gICAgLy8gTWFwIG9wY29kZXMgdG8gY2hhcmFjdGVycwotICAgIGZvcihpbnQgaT0wOyBpIDwgc2l6ZTsgaSsrKQotICAgICAgYnVmW2ldID0gbWFrZUNoYXIoaGFuZGxlc1tpXS5nZXRJbnN0cnVjdGlvbigpLmdldE9wY29kZSgpKTsKLQotICAgIGlsX3N0cmluZyA9IG5ldyBTdHJpbmcoYnVmKTsKLSAgfQotCi0gIC8qKgotICAgKiBNYXAgc3ltYm9saWMgaW5zdHJ1Y3Rpb24gbmFtZXMgbGlrZSAiZ2V0ZmllbGQiIHRvIGEgc2luZ2xlIGNoYXJhY3Rlci4KLSAgICoKLSAgICogQHBhcmFtIHBhdHRlcm4gaW5zdHJ1Y3Rpb24gcGF0dGVybiBpbiBsb3dlciBjYXNlCi0gICAqIEByZXR1cm4gZW5jb2RlZCBzdHJpbmcgZm9yIGEgcGF0dGVybiBzdWNoIGFzICJCcmFuY2hJbnN0cnVjdGlvbiIuCi0gICAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgbWFwTmFtZShTdHJpbmcgcGF0dGVybikgewotICAgIFN0cmluZyByZXN1bHQgPSAoU3RyaW5nKW1hcC5nZXQocGF0dGVybik7Ci0KLSAgICBpZihyZXN1bHQgIT0gbnVsbCkKLSAgICAgIHJldHVybiByZXN1bHQ7Ci0KLSAgICBmb3Ioc2hvcnQgaT0wOyBpIDwgTk9fT1BDT0RFUzsgaSsrKQotICAgICAgaWYocGF0dGVybi5lcXVhbHMoQ29uc3RhbnRzLk9QQ09ERV9OQU1FU1tpXSkpCi0gICAgICAgIHJldHVybiAiIiArIG1ha2VDaGFyKGkpOwotCi0gICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIkluc3RydWN0aW9uIHVua25vd246ICIgKyBwYXR0ZXJuKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXBsYWNlIHN5bWJvbGljIG5hbWVzIG9mIGluc3RydWN0aW9ucyB3aXRoIHRoZSBhcHByb3BpYXRlIGNoYXJhY3RlciBhbmQgcmVtb3ZlCi0gICAqIGFsbCB3aGl0ZSBzcGFjZSBmcm9tIHN0cmluZy4gTWV0YSBjaGFyYWN0ZXJzIHN1Y2ggYXMgKywgKiBhcmUgaWdub3JlZC4KLSAgICoKLSAgICogQHBhcmFtIHBhdHRlcm4gVGhlIHBhdHRlcm4gdG8gY29tcGlsZQotICAgKiBAcmV0dXJuIHRyYW5zbGF0ZWQgcmVndWxhciBleHByZXNzaW9uIHN0cmluZwotICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIGNvbXBpbGVQYXR0ZXJuKFN0cmluZyBwYXR0ZXJuKSB7Ci0gICAgU3RyaW5nICAgICAgIGxvd2VyICAgICAgPSBwYXR0ZXJuLnRvTG93ZXJDYXNlKCk7Ci0gICAgU3RyaW5nQnVmZmVyIGJ1ZiAgICAgICAgPSBuZXcgU3RyaW5nQnVmZmVyKCk7Ci0gICAgaW50ICAgICAgICAgIHNpemUgICAgICAgPSBwYXR0ZXJuLmxlbmd0aCgpOwotCi0gICAgZm9yKGludCBpPTA7IGkgPCBzaXplOyBpKyspIHsKLSAgICAgIGNoYXIgY2ggPSBsb3dlci5jaGFyQXQoaSk7Ci0KLSAgICAgIGlmKENoYXJhY3Rlci5pc0xldHRlck9yRGlnaXQoY2gpKSB7Ci0gICAgICAgIFN0cmluZ0J1ZmZlciBuYW1lID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotCi0gICAgICAgIHdoaWxlKChDaGFyYWN0ZXIuaXNMZXR0ZXJPckRpZ2l0KGNoKSB8fCBjaCA9PSAnXycpICYmIGkgPCBzaXplKSB7Ci0gICAgICAgICAgbmFtZS5hcHBlbmQoY2gpOwotCi0gICAgICAgICAgaWYoKytpIDwgc2l6ZSkKLSAgICAgICAgICAgIGNoID0gbG93ZXIuY2hhckF0KGkpOwotICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICB9Ci0KLSAgICAgICAgaS0tOwotCi0gICAgICAgIGJ1Zi5hcHBlbmQobWFwTmFtZShuYW1lLnRvU3RyaW5nKCkpKTsKLSAgICAgIH0gZWxzZSBpZighQ2hhcmFjdGVyLmlzV2hpdGVzcGFjZShjaCkpCi0gICAgICAgIGJ1Zi5hcHBlbmQoY2gpOwotICAgIH0KLQotICAgIHJldHVybiBidWYudG9TdHJpbmcoKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIHRoZSBtYXRjaGVkIHBpZWNlIG9mIGNvZGUgYXMgYW4gYXJyYXkgb2YgaW5zdHJ1Y3Rpb24gKGhhbmRsZXMpCi0gICAqLwotICBwcml2YXRlIEluc3RydWN0aW9uSGFuZGxlW10gZ2V0TWF0Y2goaW50IG1hdGNoZWRfZnJvbSwgaW50IG1hdGNoX2xlbmd0aCkgewotICAgIEluc3RydWN0aW9uSGFuZGxlW10gbWF0Y2ggPSBuZXcgSW5zdHJ1Y3Rpb25IYW5kbGVbbWF0Y2hfbGVuZ3RoXTsKLSAgICBTeXN0ZW0uYXJyYXljb3B5KGhhbmRsZXMsIG1hdGNoZWRfZnJvbSwgbWF0Y2gsIDAsIG1hdGNoX2xlbmd0aCk7Ci0KLSAgICByZXR1cm4gbWF0Y2g7Ci0gIH0KLQotICAvKioKLSAgICogU2VhcmNoIGZvciB0aGUgZ2l2ZW4gcGF0dGVybiBpbiB0aGUgaW5zdHJ1Y3Rpb24gbGlzdC4gWW91IGNhbiBzZWFyY2ggZm9yIGFueSB2YWxpZAotICAgKiBvcGNvZGUgdmlhIGl0cyBzeW1ib2xpYyBuYW1lLCBlLmcuICJpc3RvcmUiLiBZb3UgY2FuIGFsc28gdXNlIGEgc3VwZXIgY2xhc3Mgb3IKLSAgICogYW4gaW50ZXJmYWNlIG5hbWUgdG8gbWF0Y2ggYSB3aG9sZSBzZXQgb2YgaW5zdHJ1Y3Rpb25zLCBlLmcuICJCcmFuY2hJbnN0cnVjdGlvbiIgb3IKLSAgICogIkxvYWRJbnN0cnVjdGlvbiIuICJpc3RvcmUiIGlzIGFsc28gYW4gYWxpYXMgZm9yIGFsbCAiaXN0b3JlX3giIGluc3RydWN0aW9ucy4gQWRkaXRpb25hbAotICAgKiBhbGlhc2VzIGFyZSAiaWYiIGZvciAiaWZ4eCIsICJpZl9pY21wIiBmb3IgImlmX2ljbXB4eCIsICJpZl9hY21wIiBmb3IgImlmX2FjbXB4eCIuCi0gICAqCi0gICAqIENvbnNlY3V0aXZlIGluc3RydWN0aW9uIG5hbWVzIG11c3QgYmUgc2VwYXJhdGVkIGJ5IHdoaXRlIHNwYWNlIHdoaWNoIHdpbGwgYmUgcmVtb3ZlZAotICAgKiBkdXJpbmcgdGhlIGNvbXBpbGF0aW9uIG9mIHRoZSBwYXR0ZXJuLgotICAgKgotICAgKiBGb3IgdGhlIHJlc3QgdGhlIHVzdWFsIHBhdHRlcm4gbWF0Y2hpbmcgcnVsZXMgZm9yIHJlZ3VsYXIgZXhwcmVzc2lvbnMgYXBwbHkuPFA+Ci0gICAqIEV4YW1wbGUgcGF0dGVybjoKLSAgICogPHByZT4KLSAgICAgc2VhcmNoKCJCcmFuY2hJbnN0cnVjdGlvbiBOT1AgKChJZkluc3RydWN0aW9ufEdPVE8pKyBJU1RPUkUgSW5zdHJ1Y3Rpb24pKiIpOwotICAgKiA8L3ByZT4KLSAgICoKLSAgICogPHA+SWYgeW91IGFsdGVyIHRoZSBpbnN0cnVjdGlvbiBsaXN0IHVwb24gYSBtYXRjaCBzdWNoIHRoYXQgb3RoZXIKLSAgICogbWF0Y2hpbmcgYXJlYXMgYXJlIGFmZmVjdGVkLCB5b3Ugc2hvdWxkIGNhbGwgcmVyZWFkKCkgdG8gdXBkYXRlCi0gICAqIHRoZSBmaW5kZXIgYW5kIGNhbGwgc2VhcmNoKCkgYWdhaW4sIGJlY2F1c2UgdGhlIG1hdGNoZXMgYXJlIGNhY2hlZC4KLSAgICoKLSAgICogQHBhcmFtIHBhdHRlcm4gdGhlIGluc3RydWN0aW9uIHBhdHRlcm4gdG8gc2VhcmNoIGZvciwgd2hlcmUgY2FzZSBpcyBpZ25vcmVkCi0gICAqIEBwYXJhbSBmcm9tIHdoZXJlIHRvIHN0YXJ0IHRoZSBzZWFyY2ggaW4gdGhlIGluc3RydWN0aW9uIGxpc3QKLSAgICogQHBhcmFtIGNvbnN0cmFpbnQgb3B0aW9uYWwgQ29kZUNvbnN0cmFpbnQgdG8gY2hlY2sgdGhlIGZvdW5kIGNvZGUgcGF0dGVybiBmb3IKLSAgICogdXNlci1kZWZpbmVkIGNvbnN0cmFpbnRzCi0gICAqIEByZXR1cm4gaXRlcmF0b3Igb2YgbWF0Y2hlcyB3aGVyZSBlLm5leHRFbGVtZW50KCkgcmV0dXJucyBhbiBhcnJheSBvZiBpbnN0cnVjdGlvbiBoYW5kbGVzCi0gICAqIGRlc2NyaWJpbmcgdGhlIG1hdGNoZWQgYXJlYQotICAgKi8KLSAgcHVibGljIGZpbmFsIEl0ZXJhdG9yIHNlYXJjaChTdHJpbmcgcGF0dGVybiwgSW5zdHJ1Y3Rpb25IYW5kbGUgZnJvbSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb2RlQ29uc3RyYWludCBjb25zdHJhaW50KQotICB7Ci0gICAgU3RyaW5nIHNlYXJjaCA9IGNvbXBpbGVQYXR0ZXJuKHBhdHRlcm4pOwotICAgIGludCAgc3RhcnQgICAgPSAtMTsKLQotICAgIGZvcihpbnQgaT0wOyBpIDwgaGFuZGxlcy5sZW5ndGg7IGkrKykgewotICAgICAgaWYoaGFuZGxlc1tpXSA9PSBmcm9tKSB7Ci0gICAgICAgIHN0YXJ0ID0gaTsgLy8gV2hlcmUgdG8gc3RhcnQgc2VhcmNoIGZyb20gKGluZGV4KQotICAgICAgICBicmVhazsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICBpZihzdGFydCA9PSAtMSkKLSAgICAgIHRocm93IG5ldyBDbGFzc0dlbkV4Y2VwdGlvbigiSW5zdHJ1Y3Rpb24gaGFuZGxlICIgKyBmcm9tICsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIG5vdCBmb3VuZCBpbiBpbnN0cnVjdGlvbiBsaXN0LiIpOwotICAgIHRyeSB7Ci0gICAgICBSRSByZWdleCA9IG5ldyBSRShzZWFyY2gpOwotICAgICAgQXJyYXlMaXN0IG1hdGNoZXMgPSBuZXcgQXJyYXlMaXN0KCk7Ci0KLSAgICAgIHdoaWxlKHN0YXJ0IDwgaWxfc3RyaW5nLmxlbmd0aCgpICYmIHJlZ2V4Lm1hdGNoKGlsX3N0cmluZywgc3RhcnQpKSB7Ci0gICAgICAgIGludCBzdGFydEV4cHIgPSByZWdleC5nZXRQYXJlblN0YXJ0KDApOwotICAgICAgICBpbnQgZW5kRXhwciAgID0gcmVnZXguZ2V0UGFyZW5FbmQoMCk7Ci0gICAgICAgIGludCBsZW5FeHByICAgPSByZWdleC5nZXRQYXJlbkxlbmd0aCgwKTsKLQotICAgICAgICBJbnN0cnVjdGlvbkhhbmRsZVtdIG1hdGNoID0gZ2V0TWF0Y2goc3RhcnRFeHByLCBsZW5FeHByKTsKLQotICAgICAgICBpZigoY29uc3RyYWludCA9PSBudWxsKSB8fCBjb25zdHJhaW50LmNoZWNrQ29kZShtYXRjaCkpCi0gICAgICAgICAgbWF0Y2hlcy5hZGQobWF0Y2gpOwotICAgICAgICBzdGFydCA9IGVuZEV4cHI7Ci0gICAgICB9Ci0KLSAgICAgIHJldHVybiBtYXRjaGVzLml0ZXJhdG9yKCk7Ci0gICAgfSBjYXRjaChSRVN5bnRheEV4Y2VwdGlvbiBlKSB7Ci0gICAgICBTeXN0ZW0uZXJyLnByaW50bG4oZSk7Ci0gICAgfQotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogU3RhcnQgc2VhcmNoIGJlZ2lubmluZyBmcm9tIHRoZSBzdGFydCBvZiB0aGUgZ2l2ZW4gaW5zdHJ1Y3Rpb24gbGlzdC4KLSAgICoKLSAgICogQHBhcmFtIHBhdHRlcm4gdGhlIGluc3RydWN0aW9uIHBhdHRlcm4gdG8gc2VhcmNoIGZvciwgd2hlcmUgY2FzZSBpcyBpZ25vcmVkCi0gICAqIEByZXR1cm4gaXRlcmF0b3Igb2YgbWF0Y2hlcyB3aGVyZSBlLm5leHRFbGVtZW50KCkKLSAgICogcmV0dXJucyBhbiBhcnJheSBvZiBpbnN0cnVjdGlvbiBoYW5kbGVzIGRlc2NyaWJpbmcgdGhlIG1hdGNoZWQKLSAgICogYXJlYQotICAgKi8KLSAgcHVibGljIGZpbmFsIEl0ZXJhdG9yIHNlYXJjaChTdHJpbmcgcGF0dGVybikgewotICAgIHJldHVybiBzZWFyY2gocGF0dGVybiwgaWwuZ2V0U3RhcnQoKSwgbnVsbCk7Ci0gIH0KLQotICAvKioKLSAgICogU3RhcnQgc2VhcmNoIGJlZ2lubmluZyBmcm9tIGBmcm9tJy4KLSAgICoKLSAgICogQHBhcmFtIHBhdHRlcm4gdGhlIGluc3RydWN0aW9uIHBhdHRlcm4gdG8gc2VhcmNoIGZvciwgd2hlcmUgY2FzZSBpcyBpZ25vcmVkCi0gICAqIEBwYXJhbSBmcm9tIHdoZXJlIHRvIHN0YXJ0IHRoZSBzZWFyY2ggaW4gdGhlIGluc3RydWN0aW9uIGxpc3QKLSAgICogQHJldHVybiAgaXRlcmF0b3Igb2YgbWF0Y2hlcyB3aGVyZSBlLm5leHRFbGVtZW50KCkgcmV0dXJucyBhbiBhcnJheSBvZiBpbnN0cnVjdGlvbiBoYW5kbGVzCi0gICAqIGRlc2NyaWJpbmcgdGhlIG1hdGNoZWQgYXJlYQotICAgKi8KLSAgcHVibGljIGZpbmFsIEl0ZXJhdG9yIHNlYXJjaChTdHJpbmcgcGF0dGVybiwgSW5zdHJ1Y3Rpb25IYW5kbGUgZnJvbSkgewotICAgIHJldHVybiBzZWFyY2gocGF0dGVybiwgZnJvbSwgbnVsbCk7Ci0gIH0KLQotICAvKioKLSAgICogU3RhcnQgc2VhcmNoIGJlZ2lubmluZyBmcm9tIHRoZSBzdGFydCBvZiB0aGUgZ2l2ZW4gaW5zdHJ1Y3Rpb24gbGlzdC4KLSAgICogQ2hlY2sgZm91bmQgbWF0Y2hlcyB3aXRoIHRoZSBjb25zdHJhaW50IG9iamVjdC4KLSAgICoKLSAgICogQHBhcmFtIHBhdHRlcm4gdGhlIGluc3RydWN0aW9uIHBhdHRlcm4gdG8gc2VhcmNoIGZvciwgY2FzZSBpcyBpZ25vcmVkCi0gICAqIEBwYXJhbSBjb25zdHJhaW50IGNvbnN0cmFpbnRzIHRvIGJlIGNoZWNrZWQgb24gbWF0Y2hpbmcgY29kZQotICAgKiBAcmV0dXJuIGluc3RydWN0aW9uIGhhbmRsZSBvciBgbnVsbCcgaWYgdGhlIG1hdGNoIGZhaWxlZAotICAgKi8KLSAgcHVibGljIGZpbmFsIEl0ZXJhdG9yIHNlYXJjaChTdHJpbmcgcGF0dGVybiwgQ29kZUNvbnN0cmFpbnQgY29uc3RyYWludCkgewotICAgIHJldHVybiBzZWFyY2gocGF0dGVybiwgaWwuZ2V0U3RhcnQoKSwgY29uc3RyYWludCk7Ci0gIH0KLQotICAvKioKLSAgICogQ29udmVydCBvcGNvZGUgbnVtYmVyIHRvIGNoYXIuCi0gICAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjaGFyIG1ha2VDaGFyKHNob3J0IG9wY29kZSkgewotICAgIHJldHVybiAoY2hhcikob3Bjb2RlICsgT0ZGU0VUKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIHRoZSBpbnF1aXJlZCBpbnN0cnVjdGlvbiBsaXN0Ci0gICAqLwotICBwdWJsaWMgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGdldEluc3RydWN0aW9uTGlzdCgpIHsgcmV0dXJuIGlsOyB9Ci0KLSAgLyoqCi0gICAqIENvZGUgcGF0dGVybnMgZm91bmQgbWF5IGJlIGNoZWNrZWQgdXNpbmcgYW4gYWRkaXRpb25hbAotICAgKiB1c2VyLWRlZmluZWQgY29uc3RyYWludCBvYmplY3Qgd2hldGhlciB0aGV5IHJlYWxseSBtYXRjaCB0aGUgbmVlZGVkIGNyaXRlcmlvbi4KLSAgICogSS5lLiwgY2hlY2sgY29uc3RyYWludHMgdGhhdCBjYW4gbm90IGV4cHJlc3NlZCB3aXRoIHJlZ3VsYXIgZXhwcmVzc2lvbnMuCi0gICAqCi0gICAqLwotICBwdWJsaWMgaW50ZXJmYWNlIENvZGVDb25zdHJhaW50IHsKLSAgICAvKioKLSAgICAgKiBAcGFyYW0gbWF0Y2ggYXJyYXkgb2YgaW5zdHJ1Y3Rpb25zIG1hdGNoaW5nIHRoZSByZXF1ZXN0ZWQgcGF0dGVybgotICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgbWF0Y2hlZCBhcmVhIGlzIHJlYWxseSB1c2VmdWwKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBjaGVja0NvZGUoSW5zdHJ1Y3Rpb25IYW5kbGVbXSBtYXRjaCk7Ci0gIH0KLQotICAvLyBJbml0aWFsaXplIHBhdHRlcm4gbWFwCi0KLSAgc3RhdGljIHsKLSAgICBtYXAucHV0KCJhcml0aG1ldGljaW5zdHJ1Y3Rpb24iLCAiKGlyZW18bHJlbXxpYW5kfGlvcnxpbmVnfGlzdWJ8bG5lZ3xmbmVnfGZtdWx8bGRpdnxmYWRkfGx4b3J8ZnJlbXxpZGl2fGxhbmR8aXhvcnxpc2hyfGZzdWJ8bHNobHxmZGl2fGlhZGR8bG9yfGRtdWx8bHN1Ynxpc2hsfGltdWx8bG11bHxsdXNocnxkbmVnfGl1c2hyfGxzaHJ8ZGRpdnxkcmVtfGRhZGR8bGFkZHxkc3ViKSIpOwotICAgIG1hcC5wdXQoImludm9rZWluc3RydWN0aW9uIiwgIihpbnZva2V2aXJ0dWFsfGludm9rZWludGVyZmFjZXxpbnZva2VzdGF0aWN8aW52b2tlc3BlY2lhbCkiKTsKLSAgICBtYXAucHV0KCJhcnJheWluc3RydWN0aW9uIiwgIihiYWxvYWR8YWFzdG9yZXxzYWxvYWR8Y2Fsb2FkfGZhc3RvcmV8bGFzdG9yZXxpYWxvYWR8Y2FzdG9yZXxpYXN0b3JlfGFhbG9hZHxiYXN0b3JlfHNhc3RvcmV8ZmFsb2FkfGxhbG9hZHxkYWxvYWR8ZGFzdG9yZSkiKTsKLSAgICBtYXAucHV0KCJnb3RvaW5zdHJ1Y3Rpb24iLCAiKGdvdG98Z290b193KSIpOwotICAgIG1hcC5wdXQoImNvbnZlcnNpb25pbnN0cnVjdGlvbiIsICIoZDJsfGwyZHxpMnN8ZDJpfGwyaXxpMmJ8bDJmfGQyZnxmMml8aTJkfGkybHxmMmR8aTJjfGYybHxpMmYpIik7Ci0gICAgbWFwLnB1dCgibG9jYWx2YXJpYWJsZWluc3RydWN0aW9uIiwgIihmc3RvcmV8aWluY3xsbG9hZHxkc3RvcmV8ZGxvYWR8aWxvYWR8YWxvYWR8YXN0b3JlfGlzdG9yZXxmbG9hZHxsc3RvcmUpIik7Ci0gICAgbWFwLnB1dCgibG9hZGluc3RydWN0aW9uIiwgIihmbG9hZHxkbG9hZHxsbG9hZHxpbG9hZHxhbG9hZCkiKTsKLSAgICBtYXAucHV0KCJmaWVsZGluc3RydWN0aW9uIiwgIihnZXRmaWVsZHxwdXRzdGF0aWN8Z2V0c3RhdGljfHB1dGZpZWxkKSIpOwotICAgIG1hcC5wdXQoImNwaW5zdHJ1Y3Rpb24iLCAiKGxkYzJfd3xpbnZva2VpbnRlcmZhY2V8bXVsdGlhbmV3YXJyYXl8cHV0c3RhdGljfGluc3RhbmNlb2Z8Z2V0c3RhdGljfGNoZWNrY2FzdHxnZXRmaWVsZHxpbnZva2VzcGVjaWFsfGxkY193fGludm9rZXN0YXRpY3xpbnZva2V2aXJ0dWFsfHB1dGZpZWxkfGxkY3xuZXd8YW5ld2FycmF5KSIpOwotICAgIG1hcC5wdXQoInN0YWNraW5zdHJ1Y3Rpb24iLCAiKGR1cDJ8c3dhcHxkdXAyX3gyfHBvcHxwb3AyfGR1cHxkdXAyX3gxfGR1cF94MnxkdXBfeDEpIik7Ci0gICAgbWFwLnB1dCgiYnJhbmNoaW5zdHJ1Y3Rpb24iLCAiKGlmbGV8aWZfYWNtcG5lfGlmX2ljbXBlcXxpZl9hY21wZXF8aWZub25udWxsfGdvdG9fd3xpZmx0fGlmbnVsbHxpZl9pY21wbmV8dGFibGVzd2l0Y2h8aWZfaWNtcGxlfGlmZXF8aWZfaWNtcGx0fGpzcl93fGlmX2ljbXBndHxpZmd0fGpzcnxnb3RvfGlmbmV8aWZnZXxsb29rdXBzd2l0Y2h8aWZfaWNtcGdlKSIpOwotICAgIG1hcC5wdXQoInJldHVybmluc3RydWN0aW9uIiwgIihscmV0dXJufGlyZXR1cm58ZnJldHVybnxkcmV0dXJufGFyZXR1cm58cmV0dXJuKSIpOwotICAgIG1hcC5wdXQoInN0b3JlaW5zdHJ1Y3Rpb24iLCAiKGlzdG9yZXxmc3RvcmV8ZHN0b3JlfGFzdG9yZXxsc3RvcmUpIik7Ci0gICAgbWFwLnB1dCgic2VsZWN0IiwgIih0YWJsZXN3aXRjaHxsb29rdXBzd2l0Y2gpIik7Ci0gICAgbWFwLnB1dCgiaWZpbnN0cnVjdGlvbiIsICIoaWZlcXxpZmd0fGlmX2ljbXBuZXxpZl9pY21wZXF8aWZnZXxpZm51bGx8aWZuZXxpZl9pY21wbGV8aWZfaWNtcGdlfGlmX2FjbXBlcXxpZl9pY21wbHR8aWZfYWNtcG5lfGlmbm9ubnVsbHxpZmx0fGlmX2ljbXBndHxpZmxlKSIpOwotICAgIG1hcC5wdXQoImpzcmluc3RydWN0aW9uIiwgIihqc3J8anNyX3cpIik7Ci0gICAgbWFwLnB1dCgidmFyaWFibGVsZW5ndGhpbnN0cnVjdGlvbiIsICIodGFibGVzd2l0Y2h8anNyfGdvdG98bG9va3Vwc3dpdGNoKSIpOwotICAgIG1hcC5wdXQoInVuY29uZGl0aW9uYWxicmFuY2giLCAiKGdvdG98anNyfGpzcl93fGF0aHJvd3xnb3RvX3cpIik7Ci0gICAgbWFwLnB1dCgiY29uc3RhbnRwdXNoaW5zdHJ1Y3Rpb24iLCAiKGRjb25zdHxiaXB1c2h8c2lwdXNofGZjb25zdHxpY29uc3R8bGNvbnN0KSIpOwotICAgIG1hcC5wdXQoInR5cGVkaW5zdHJ1Y3Rpb24iLCAiKGltdWx8bHN1YnxhbG9hZHxmbG9hZHxsb3J8bmV3fGFhbG9hZHxmY21wZ3xpYW5kfGlhbG9hZHxscmVtfGlkaXZ8ZDJsfGlzdWJ8ZGNtcGd8ZGFzdG9yZXxyZXR8ZjJkfGYyaXxkcmVtfGlpbmN8aTJjfGNoZWNrY2FzdHxmcmVtfGxyZXR1cm58YXN0b3JlfGx1c2hyfGRhbG9hZHxkbmVnfGZhc3RvcmV8aXN0b3JlfGxzaGx8bGRpdnxsc3RvcmV8YXJldHVybnxpc2hyfGxkY193fGludm9rZWludGVyZmFjZXxhYXN0b3JlfGx4b3J8aXNobHxsMmR8aTJmfHJldHVybnxmYWxvYWR8c2lwdXNofGl1c2hyfGNhbG9hZHxpbnN0YW5jZW9mfGludm9rZXNwZWNpYWx8cHV0ZmllbGR8Zm11bHxpcmV0dXJufGxhbG9hZHxkMmZ8bG5lZ3xpeG9yfGkybHxmZGl2fGxhc3RvcmV8bXVsdGlhbmV3YXJyYXl8aTJifGdldHN0YXRpY3xpMmR8cHV0c3RhdGljfGZjbXBsfHNhbG9hZHxsYWRkfGlyZW18ZGxvYWR8anNyX3d8ZGNvbnN0fGRjbXBsfGZzdWJ8ZnJldHVybnxsZGN8YWNvbnN0X251bGx8Y2FzdG9yZXxsbXVsfGxkYzJfd3xkYWRkfGljb25zdHxmMmx8ZGRpdnxkc3RvcmV8bGFuZHxqc3J8YW5ld2FycmF5fGRtdWx8YmlwdXNofGRzdWJ8c2FzdG9yZXxkMml8aTJzfGxzaHJ8aWFkZHxsMml8bGxvYWR8YmFzdG9yZXxmc3RvcmV8Zm5lZ3xpbG9hZHxmYWRkfGJhbG9hZHxmY29uc3R8aW9yfGluZWd8ZHJldHVybnxsMmZ8bGNvbnN0fGdldGZpZWxkfGludm9rZXZpcnR1YWx8aW52b2tlc3RhdGljfGlhc3RvcmUpIik7Ci0gICAgbWFwLnB1dCgicG9waW5zdHJ1Y3Rpb24iLCAiKGZzdG9yZXxkc3RvcmV8cG9wfHBvcDJ8YXN0b3JlfHB1dHN0YXRpY3xpc3RvcmV8bHN0b3JlKSIpOwotICAgIG1hcC5wdXQoImFsbG9jYXRpb25pbnN0cnVjdGlvbiIsICIobXVsdGlhbmV3YXJyYXl8bmV3fGFuZXdhcnJheXxuZXdhcnJheSkiKTsKLSAgICBtYXAucHV0KCJpbmRleGVkaW5zdHJ1Y3Rpb24iLCAiKGxsb2FkfGxzdG9yZXxmbG9hZHxsZGMyX3d8aW52b2tlaW50ZXJmYWNlfG11bHRpYW5ld2FycmF5fGFzdG9yZXxkbG9hZHxwdXRzdGF0aWN8aW5zdGFuY2VvZnxnZXRzdGF0aWN8Y2hlY2tjYXN0fGdldGZpZWxkfGludm9rZXNwZWNpYWx8ZHN0b3JlfGlzdG9yZXxpaW5jfGxkY193fHJldHxmc3RvcmV8aW52b2tlc3RhdGljfGlsb2FkfHB1dGZpZWxkfGludm9rZXZpcnR1YWx8bGRjfG5ld3xhbG9hZHxhbmV3YXJyYXkpIik7Ci0gICAgbWFwLnB1dCgicHVzaGluc3RydWN0aW9uIiwgIihkdXB8bGxvYWR8ZHVwMnxiaXB1c2h8ZmxvYWR8bGRjMl93fHNpcHVzaHxsY29uc3R8ZmNvbnN0fGRsb2FkfGdldHN0YXRpY3xsZGNfd3xhY29uc3RfbnVsbHxkY29uc3R8aWxvYWR8bGRjfGljb25zdHxhbG9hZCkiKTsKLSAgICBtYXAucHV0KCJzdGFja3Byb2R1Y2VyIiwgIihpbXVsfGxzdWJ8YWxvYWR8ZmxvYWR8bG9yfG5ld3xhYWxvYWR8ZmNtcGd8aWFuZHxpYWxvYWR8bHJlbXxpZGl2fGQybHxpc3VifGRjbXBnfGR1cHxmMmR8ZjJpfGRyZW18aTJjfGNoZWNrY2FzdHxmcmVtfGx1c2hyfGRhbG9hZHxkbmVnfGxzaGx8bGRpdnxpc2hyfGxkY193fGludm9rZWludGVyZmFjZXxseG9yfGlzaGx8bDJkfGkyZnxmYWxvYWR8c2lwdXNofGl1c2hyfGNhbG9hZHxpbnN0YW5jZW9mfGludm9rZXNwZWNpYWx8Zm11bHxsYWxvYWR8ZDJmfGxuZWd8aXhvcnxpMmx8ZmRpdnxnZXRzdGF0aWN8aTJifHN3YXB8aTJkfGR1cDJ8ZmNtcGx8c2Fsb2FkfGxhZGR8aXJlbXxkbG9hZHxqc3Jfd3xkY29uc3R8ZGNtcGx8ZnN1YnxsZGN8YXJyYXlsZW5ndGh8YWNvbnN0X251bGx8dGFibGVzd2l0Y2h8bG11bHxsZGMyX3d8aWNvbnN0fGRhZGR8ZjJsfGRkaXZ8bGFuZHxqc3J8YW5ld2FycmF5fGRtdWx8YmlwdXNofGRzdWJ8ZDJpfG5ld2FycmF5fGkyc3xsc2hyfGlhZGR8bGxvYWR8bDJpfGZuZWd8aWxvYWR8ZmFkZHxiYWxvYWR8ZmNvbnN0fGxvb2t1cHN3aXRjaHxpb3J8aW5lZ3xsY29uc3R8bDJmfGdldGZpZWxkfGludm9rZXZpcnR1YWx8aW52b2tlc3RhdGljKSIpOwotICAgIG1hcC5wdXQoInN0YWNrY29uc3VtZXIiLCAiKGltdWx8bHN1Ynxsb3J8aWZsdHxmY21wZ3xpZl9pY21wZ3R8aWFuZHxpZmVxfGlmX2ljbXBsdHxscmVtfGlmbm9ubnVsbHxpZGl2fGQybHxpc3VifGRjbXBnfGRhc3RvcmV8aWZfaWNtcGVxfGYyZHxmMml8ZHJlbXxpMmN8Y2hlY2tjYXN0fGZyZW18bHJldHVybnxhc3RvcmV8bHVzaHJ8cG9wMnxtb25pdG9yZXhpdHxkbmVnfGZhc3RvcmV8aXN0b3JlfGxzaGx8bGRpdnxsc3RvcmV8YXJldHVybnxpZl9pY21wZ2V8aXNocnxtb25pdG9yZW50ZXJ8aW52b2tlaW50ZXJmYWNlfGFhc3RvcmV8bHhvcnxpc2hsfGwyZHxpMmZ8cmV0dXJufGl1c2hyfGluc3RhbmNlb2Z8aW52b2tlc3BlY2lhbHxmbXVsfGlyZXR1cm58ZDJmfGxuZWd8aXhvcnxwb3B8aTJsfGlmbnVsbHxmZGl2fGxhc3RvcmV8aTJifGlmX2FjbXBlcXxpZmdlfHN3YXB8aTJkfHB1dHN0YXRpY3xmY21wbHxsYWRkfGlyZW18ZGNtcGx8ZnN1YnxmcmV0dXJufGlmZ3R8Y2FzdG9yZXxsbXVsfGRhZGR8ZjJsfGRkaXZ8ZHN0b3JlfGxhbmR8aWZfaWNtcG5lfGlmX2FjbXBuZXxkbXVsfGRzdWJ8c2FzdG9yZXxpZmxlfGQyaXxpMnN8bHNocnxpYWRkfGwyaXxiYXN0b3JlfGZzdG9yZXxmbmVnfGZhZGR8aW9yfGluZWd8aWZuZXxkcmV0dXJufGwyZnxpZl9pY21wbGV8Z2V0ZmllbGR8aW52b2tldmlydHVhbHxpbnZva2VzdGF0aWN8aWFzdG9yZSkiKTsKLSAgICBtYXAucHV0KCJleGNlcHRpb250aHJvd2VyIiwgIihpcmVtfGxyZW18bGFsb2FkfHB1dHN0YXRpY3xiYWxvYWR8ZGFzdG9yZXxhcmV0dXJufGdldHN0YXRpY3xsZGl2fGFuZXdhcnJheXxpYXN0b3JlfGNhc3RvcmV8aWRpdnxzYWxvYWR8bGFzdG9yZXxmYXN0b3JlfHB1dGZpZWxkfGxyZXR1cm58Y2Fsb2FkfGdldGZpZWxkfHJldHVybnxhYXN0b3JlfGZyZXR1cm58bmV3YXJyYXl8aW5zdGFuY2VvZnxtdWx0aWFuZXdhcnJheXxhdGhyb3d8ZmFsb2FkfGlhbG9hZHxhYWxvYWR8ZHJldHVybnxtb25pdG9yZW50ZXJ8Y2hlY2tjYXN0fGJhc3RvcmV8YXJyYXlsZW5ndGh8bmV3fGludm9rZXZpcnR1YWx8c2FzdG9yZXxsZGNfd3xpcmV0dXJufGludm9rZXNwZWNpYWx8bW9uaXRvcmV4aXR8aW52b2tlaW50ZXJmYWNlfGxkY3xpbnZva2VzdGF0aWN8ZGFsb2FkKSIpOwotICAgIG1hcC5wdXQoImxvYWRjbGFzcyIsICIobXVsdGlhbmV3YXJyYXl8aW52b2tlaW50ZXJmYWNlfGluc3RhbmNlb2Z8aW52b2tlc3BlY2lhbHxwdXRmaWVsZHxjaGVja2Nhc3R8cHV0c3RhdGljfGludm9rZXZpcnR1YWx8bmV3fGdldHN0YXRpY3xpbnZva2VzdGF0aWN8Z2V0ZmllbGR8YW5ld2FycmF5KSIpOwotICAgIG1hcC5wdXQoImluc3RydWN0aW9udGFyZ2V0ZXIiLCAiKGlmbGV8aWZfYWNtcG5lfGlmX2ljbXBlcXxpZl9hY21wZXF8aWZub25udWxsfGdvdG9fd3xpZmx0fGlmbnVsbHxpZl9pY21wbmV8dGFibGVzd2l0Y2h8aWZfaWNtcGxlfGlmZXF8aWZfaWNtcGx0fGpzcl93fGlmX2ljbXBndHxpZmd0fGpzcnxnb3RvfGlmbmV8aWZnZXxsb29rdXBzd2l0Y2h8aWZfaWNtcGdlKSIpOwotCi0gICAgLy8gU29tZSBhbGlhc2VzCi0gICAgbWFwLnB1dCgiaWZfaWNtcCIsICIoaWZfaWNtcG5lfGlmX2ljbXBlcXxpZl9pY21wbGV8aWZfaWNtcGdlfGlmX2ljbXBsdHxpZl9pY21wZ3QpIik7Ci0gICAgbWFwLnB1dCgiaWZfYWNtcCIsICIoaWZfYWNtcGVxfGlmX2FjbXBuZSkiKTsKLSAgICBtYXAucHV0KCJpZiIsICIoaWZlcXxpZm5lfGlmbHR8aWZnZXxpZmd0fGlmbGUpIik7Ci0KLSAgICAvLyBQcmVjb21waWxlIHNvbWUgYWxpYXNlcyBmaXJzdAotICAgIG1hcC5wdXQoImljb25zdCIsIHByZWNvbXBpbGUoQ29uc3RhbnRzLklDT05TVF8wLCBDb25zdGFudHMuSUNPTlNUXzUsIENvbnN0YW50cy5JQ09OU1RfTTEpKTsKLSAgICBtYXAucHV0KCJsY29uc3QiLCBuZXcgU3RyaW5nKG5ldyBjaGFyW10geyAnKCcsIG1ha2VDaGFyKENvbnN0YW50cy5MQ09OU1RfMCksICd8JywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYWtlQ2hhcihDb25zdGFudHMuTENPTlNUXzEpLCAnKScgfSkpOwotICAgIG1hcC5wdXQoImRjb25zdCIsIG5ldyBTdHJpbmcobmV3IGNoYXJbXSB7ICcoJywgbWFrZUNoYXIoQ29uc3RhbnRzLkRDT05TVF8wKSwgJ3wnLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ha2VDaGFyKENvbnN0YW50cy5EQ09OU1RfMSksICcpJyB9KSk7Ci0gICAgbWFwLnB1dCgiZmNvbnN0IiwgbmV3IFN0cmluZyhuZXcgY2hhcltdIHsgJygnLCBtYWtlQ2hhcihDb25zdGFudHMuRkNPTlNUXzApLCAnfCcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFrZUNoYXIoQ29uc3RhbnRzLkZDT05TVF8xKSwgJyknIH0pKTsKLQotICAgIG1hcC5wdXQoImlsb2FkIiwgcHJlY29tcGlsZShDb25zdGFudHMuSUxPQURfMCwgQ29uc3RhbnRzLklMT0FEXzMsIENvbnN0YW50cy5JTE9BRCkpOwotICAgIG1hcC5wdXQoImRsb2FkIiwgcHJlY29tcGlsZShDb25zdGFudHMuRExPQURfMCwgQ29uc3RhbnRzLkRMT0FEXzMsIENvbnN0YW50cy5ETE9BRCkpOwotICAgIG1hcC5wdXQoImZsb2FkIiwgcHJlY29tcGlsZShDb25zdGFudHMuRkxPQURfMCwgQ29uc3RhbnRzLkZMT0FEXzMsIENvbnN0YW50cy5GTE9BRCkpOwotICAgIG1hcC5wdXQoImFsb2FkIiwgcHJlY29tcGlsZShDb25zdGFudHMuQUxPQURfMCwgQ29uc3RhbnRzLkFMT0FEXzMsIENvbnN0YW50cy5BTE9BRCkpOwotCi0gICAgbWFwLnB1dCgiaXN0b3JlIiwgcHJlY29tcGlsZShDb25zdGFudHMuSVNUT1JFXzAsIENvbnN0YW50cy5JU1RPUkVfMywgQ29uc3RhbnRzLklTVE9SRSkpOwotICAgIG1hcC5wdXQoImRzdG9yZSIsIHByZWNvbXBpbGUoQ29uc3RhbnRzLkRTVE9SRV8wLCBDb25zdGFudHMuRFNUT1JFXzMsIENvbnN0YW50cy5EU1RPUkUpKTsKLSAgICBtYXAucHV0KCJmc3RvcmUiLCBwcmVjb21waWxlKENvbnN0YW50cy5GU1RPUkVfMCwgQ29uc3RhbnRzLkZTVE9SRV8zLCBDb25zdGFudHMuRlNUT1JFKSk7Ci0gICAgbWFwLnB1dCgiYXN0b3JlIiwgcHJlY29tcGlsZShDb25zdGFudHMuQVNUT1JFXzAsIENvbnN0YW50cy5BU1RPUkVfMywgQ29uc3RhbnRzLkFTVE9SRSkpOwotCi0gICAgLy8gQ29tcGlsZSBzdHJpbmdzCi0KLSAgICBmb3IoSXRlcmF0b3IgaSA9IG1hcC5rZXlTZXQoKS5pdGVyYXRvcigpOyBpLmhhc05leHQoKTsgKSB7Ci0gICAgICBTdHJpbmcga2V5ICAgPSAoU3RyaW5nKWkubmV4dCgpOwotICAgICAgU3RyaW5nIHZhbHVlID0gKFN0cmluZyltYXAuZ2V0KGtleSk7Ci0KLSAgICAgIGNoYXIgY2ggPSB2YWx1ZS5jaGFyQXQoMSk7IC8vIE9taXQgYWxyZWFkeSBwcmVjb21waWxlZCBwYXR0ZXJucwotICAgICAgaWYoY2ggPCBPRkZTRVQpIHsKLSAgICAgICAgbWFwLnB1dChrZXksIGNvbXBpbGVQYXR0ZXJuKHZhbHVlKSk7IC8vIHByZWNvbXBpbGUgYWxsIHBhdHRlcm5zCi0gICAgICB9Ci0gICAgfQotCi0gICAgLy8gQWRkIGluc3RydWN0aW9uIGFsaWFzIHRvIG1hdGNoIGFueXRoaW5nCi0KLSAgICBTdHJpbmdCdWZmZXIgYnVmID0gbmV3IFN0cmluZ0J1ZmZlcigiKCIpOwotCi0gICAgZm9yKHNob3J0IGk9MDsgaSA8IE5PX09QQ09ERVM7IGkrKykgewotICAgICAgaWYoQ29uc3RhbnRzLk5PX09GX09QRVJBTkRTW2ldICE9IENvbnN0YW50cy5VTkRFRklORUQpIHsgLy8gTm90IGFuIGludmFsaWQgb3Bjb2RlCi0gICAgICAgIGJ1Zi5hcHBlbmQobWFrZUNoYXIoaSkpOwotCi0gICAgICAgIGlmKGkgPCBOT19PUENPREVTIC0gMSkKLSAgICAgICAgICBidWYuYXBwZW5kKCd8Jyk7Ci0gICAgICB9Ci0gICAgfQotICAgIGJ1Zi5hcHBlbmQoJyknKTsKLQotICAgIG1hcC5wdXQoImluc3RydWN0aW9uIiwgYnVmLnRvU3RyaW5nKCkpOwotICB9Ci0KLSAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIHByZWNvbXBpbGUoc2hvcnQgZnJvbSwgc2hvcnQgdG8sIHNob3J0IGV4dHJhKSB7Ci0gICAgU3RyaW5nQnVmZmVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWZmZXIoIigiKTsKLQotICAgIGZvcihzaG9ydCBpPWZyb207IGkgPD0gdG87IGkrKykgewotICAgICAgYnVmLmFwcGVuZChtYWtlQ2hhcihpKSk7Ci0gICAgICBidWYuYXBwZW5kKCd8Jyk7Ci0gICAgfQotCi0gICAgYnVmLmFwcGVuZChtYWtlQ2hhcihleHRyYSkpOwotICAgIGJ1Zi5hcHBlbmQoIikiKTsKLSAgICByZXR1cm4gYnVmLnRvU3RyaW5nKCk7Ci0gIH0KLQotICAvKgotICAgKiBJbnRlcm5hbCBkZWJ1Z2dpbmcgcm91dGluZXMuCi0gICAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgcGF0dGVybjJzdHJpbmcoU3RyaW5nIHBhdHRlcm4pIHsKLSAgICByZXR1cm4gcGF0dGVybjJzdHJpbmcocGF0dGVybiwgdHJ1ZSk7Ci0gIH0KLQotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgcGF0dGVybjJzdHJpbmcoU3RyaW5nIHBhdHRlcm4sIGJvb2xlYW4gbWFrZV9zdHJpbmcpIHsKLSAgICBTdHJpbmdCdWZmZXIgYnVmID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotCi0gICAgZm9yKGludCBpPTA7IGkgPCBwYXR0ZXJuLmxlbmd0aCgpOyBpKyspIHsKLSAgICAgIGNoYXIgY2ggPSBwYXR0ZXJuLmNoYXJBdChpKTsKLQotICAgICAgaWYoY2ggPj0gT0ZGU0VUKSB7Ci0gICAgICAgIGlmKG1ha2Vfc3RyaW5nKQotICAgICAgICAgIGJ1Zi5hcHBlbmQoQ29uc3RhbnRzLk9QQ09ERV9OQU1FU1tjaCAtIE9GRlNFVF0pOwotICAgICAgICBlbHNlCi0gICAgICAgICAgYnVmLmFwcGVuZCgoaW50KShjaCAtIE9GRlNFVCkpOwotICAgICAgfSBlbHNlCi0gICAgICAgIGJ1Zi5hcHBlbmQoY2gpOwotICAgIH0KLQotICAgIHJldHVybiBidWYudG9TdHJpbmcoKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL3V0aWwvSmF2YVdyYXBwZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC91dGlsL0phdmFXcmFwcGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDE1NDBmNmQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL3V0aWwvSmF2YVdyYXBwZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE1NSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC51dGlsOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi1pbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuKjsKLQotLyoqCi0gKiBKYXZhIGludGVycHJldGVyIHJlcGxhY2VtZW50LCBpLmUuLCB3cmFwcGVyIHRoYXQgdXNlcyBpdHMgb3duIENsYXNzTG9hZGVyCi0gKiB0byBtb2RpZnkvZ2VuZXJhdGUgY2xhc3NlcyBhcyB0aGV5J3JlIHJlcXVlc3RlZC4gWW91IGNhbiB0YWtlIHRoaXMgYXMgYSB0ZW1wbGF0ZQotICogZm9yIHlvdXIgb3duIGFwcGxpY2F0aW9ucy48YnI+Ci0gKiBDYWxsIHRoaXMgd3JhcHBlciB3aXRoCi0gKiA8cHJlPmphdmEgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwudXRpbC5KYXZhV3JhcHBlciAmbHQ7cmVhbC5jbGFzcy5uYW1lJmd0OyBbYXJndW1lbnRzXTwvcHJlPgotICogPHA+Ci0gKiBUbyB1c2UgeW91ciBvd24gY2xhc3MgbG9hZGVyIHlvdSBjYW4gc2V0IHRoZSAiYmNlbC5jbGFzc2xvYWRlciIgc3lzdGVtIHByb3BlcnR5Ci0gKiB3aGljaCBkZWZhdWx0cyB0byAiY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwudXRpbC5DbGFzc0xvYWRlciIsIGUuZy4sIHdpdGgKLSAqIDxwcmU+amF2YSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC51dGlsLkphdmFXcmFwcGVyIC1EYmNlbC5jbGFzc2xvYWRlcj1mb28uTXlMb2FkZXIgJmx0O3JlYWwuY2xhc3MubmFtZSZndDsgW2FyZ3VtZW50c108L3ByZT4KLSAqIDwvcD4KLSAqCi0gKiBAdmVyc2lvbiAkSWQ6IEphdmFXcmFwcGVyLmphdmEsdiAxLjMgMjAwNy0wNy0xOSAwNDozNDo1MiBvZnVuZyBFeHAgJAotICogQGF1dGhvciAgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqIEBzZWUgQ2xhc3NMb2FkZXIKLSAqLwotcHVibGljIGNsYXNzIEphdmFXcmFwcGVyIHsKLSAgcHJpdmF0ZSBqYXZhLmxhbmcuQ2xhc3NMb2FkZXIgbG9hZGVyOwotCi0gIHByaXZhdGUgc3RhdGljIGphdmEubGFuZy5DbGFzc0xvYWRlciBnZXRDbGFzc0xvYWRlcigpIHsKLSAgICBTdHJpbmcgcyA9IFNlY3VyaXR5U3VwcG9ydC5nZXRTeXN0ZW1Qcm9wZXJ0eSgiYmNlbC5jbGFzc2xvYWRlciIpOwotCi0gICAgaWYoKHMgPT0gbnVsbCkgfHwgIiIuZXF1YWxzKHMpKQotICAgICAgcyA9ICJjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC51dGlsLkNsYXNzTG9hZGVyIjsKLQotICAgIHRyeSB7Ci0gICAgICByZXR1cm4gKGphdmEubGFuZy5DbGFzc0xvYWRlcilDbGFzcy5mb3JOYW1lKHMpLm5ld0luc3RhbmNlKCk7Ci0gICAgfSBjYXRjaChFeGNlcHRpb24gZSkgewotICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZS50b1N0cmluZygpKTsKLSAgICB9Ci0gIH0KLQotICBwdWJsaWMgSmF2YVdyYXBwZXIoamF2YS5sYW5nLkNsYXNzTG9hZGVyIGxvYWRlcikgewotICAgIHRoaXMubG9hZGVyID0gbG9hZGVyOwotICB9Ci0KLSAgcHVibGljIEphdmFXcmFwcGVyKCkgewotICAgIHRoaXMoZ2V0Q2xhc3NMb2FkZXIoKSk7Ci0gIH0KLQotICAvKiogUnVucyB0aGUgX21haW4gbWV0aG9kIG9mIHRoZSBnaXZlbiBjbGFzcyB3aXRoIHRoZSBhcmd1bWVudHMgcGFzc2VkIGluIGFyZ3YKLSAgICoKLSAgICogQHBhcmFtIGNsYXNzX25hbWUgdGhlIGZ1bGx5IHF1YWxpZmllZCBjbGFzcyBuYW1lCi0gICAqIEBwYXJhbSBhcmd2IHRoZSBhcmd1bWVudHMganVzdCBhcyB5b3Ugd291bGQgcGFzcyB0aGVtIGRpcmVjdGx5Ci0gICAqLwotICBwdWJsaWMgdm9pZCBydW5NYWluKFN0cmluZyBjbGFzc19uYW1lLCBTdHJpbmdbXSBhcmd2KSB0aHJvd3MgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbgotICB7Ci0gICAgQ2xhc3MgICBjbCAgICA9IGxvYWRlci5sb2FkQ2xhc3MoY2xhc3NfbmFtZSk7Ci0gICAgTWV0aG9kIG1ldGhvZCA9IG51bGw7Ci0KLSAgICB0cnkgewotICAgICAgbWV0aG9kID0gY2wuZ2V0TWV0aG9kKCJfbWFpbiIsICBuZXcgQ2xhc3NbXSB7IGFyZ3YuZ2V0Q2xhc3MoKSB9KTsKLQotICAgICAgLyogTWV0aG9kIF9tYWluIGlzIHNhbmUgPwotICAgICAgICovCi0gICAgICBpbnQgICBtID0gbWV0aG9kLmdldE1vZGlmaWVycygpOwotICAgICAgQ2xhc3MgciA9IG1ldGhvZC5nZXRSZXR1cm5UeXBlKCk7Ci0KLSAgICAgIGlmKCEoTW9kaWZpZXIuaXNQdWJsaWMobSkgJiYgTW9kaWZpZXIuaXNTdGF0aWMobSkpIHx8Ci0gICAgICAgICBNb2RpZmllci5pc0Fic3RyYWN0KG0pIHx8IChyICE9IFZvaWQuVFlQRSkpCi0gICAgICAgIHRocm93IG5ldyBOb1N1Y2hNZXRob2RFeGNlcHRpb24oKTsKLSAgICB9IGNhdGNoKE5vU3VjaE1ldGhvZEV4Y2VwdGlvbiBubykgewotICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJJbiBjbGFzcyAiICsgY2xhc3NfbmFtZSArCi0gICAgICAgICAgICAgICAgICAgICAgICAgIjogcHVibGljIHN0YXRpYyB2b2lkIF9tYWluKFN0cmluZ1tdIGFyZ3YpIGlzIG5vdCBkZWZpbmVkIik7Ci0gICAgICByZXR1cm47Ci0gICAgfQotCi0gICAgdHJ5IHsKLSAgICAgIG1ldGhvZC5pbnZva2UobnVsbCwgbmV3IE9iamVjdFtdIHsgYXJndiB9KTsKLSAgICB9IGNhdGNoKEV4Y2VwdGlvbiBleCkgewotICAgICAgZXgucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgfQotICB9Ci0KLSAgLyoqIERlZmF1bHQgX21haW4gbWV0aG9kIHVzZWQgYXMgd3JhcHBlciwgZXhwZWN0cyB0aGUgZnVsbHkgcXVhbGlmaWVkIGNsYXNzIG5hbWUKLSAgICogb2YgdGhlIHJlYWwgY2xhc3MgYXMgdGhlIGZpcnN0IGFyZ3VtZW50LgotICAgKi8KLSAgcHVibGljIHN0YXRpYyB2b2lkIF9tYWluKFN0cmluZ1tdIGFyZ3YpIHRocm93cyBFeGNlcHRpb24gewotICAgIC8qIEV4cGVjdHMgY2xhc3MgbmFtZSBhcyBmaXJzdCBhcmd1bWVudCwgb3RoZXIgYXJndW1lbnRzIGFyZSBieS1wYXNzZWQuCi0gICAgICovCi0gICAgaWYoYXJndi5sZW5ndGggPT0gMCkgewotICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJNaXNzaW5nIGNsYXNzIG5hbWUuIik7Ci0gICAgICByZXR1cm47Ci0gICAgfQotCi0gICAgU3RyaW5nIGNsYXNzX25hbWUgPSBhcmd2WzBdOwotICAgIFN0cmluZ1tdIG5ld19hcmd2ID0gbmV3IFN0cmluZ1thcmd2Lmxlbmd0aCAtIDFdOwotICAgIFN5c3RlbS5hcnJheWNvcHkoYXJndiwgMSwgbmV3X2FyZ3YsIDAsIG5ld19hcmd2Lmxlbmd0aCk7Ci0KLSAgICBKYXZhV3JhcHBlciB3cmFwcGVyID0gbmV3IEphdmFXcmFwcGVyKCk7Ci0gICAgd3JhcHBlci5ydW5NYWluKGNsYXNzX25hbWUsIG5ld19hcmd2KTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL3V0aWwvTWV0aG9kSFRNTC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL3V0aWwvTWV0aG9kSFRNTC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkNmQ1NDI5Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC91dGlsL01ldGhvZEhUTUwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIwMiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC51dGlsOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuY2xhc3NmaWxlLio7Ci1pbXBvcnQgamF2YS5pby4qOwotCi0vKioKLSAqIENvbnZlcnQgbWV0aG9kcyBhbmQgZmllbGRzIGludG8gSFRNTCBmaWxlLgotICoKLSAqIEBhdXRob3IgIDxBIEhSRUY9Im1haWx0bzptYXJrdXMuZGFobUBiZXJsaW4uZGUiPk0uIERhaG08L0E+Ci0gKgotICovCi1maW5hbCBjbGFzcyBNZXRob2RIVE1MIGltcGxlbWVudHMgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzIHsKLSAgcHJpdmF0ZSBTdHJpbmcgICAgICAgIGNsYXNzX25hbWU7ICAgICAvLyBuYW1lIG9mIGN1cnJlbnQgY2xhc3MKLSAgcHJpdmF0ZSBQcmludFdyaXRlciAgIGZpbGU7ICAgICAgICAgICAvLyBmaWxlIHRvIHdyaXRlIHRvCi0gIHByaXZhdGUgQ29uc3RhbnRIVE1MICBjb25zdGFudF9odG1sOwotICBwcml2YXRlIEF0dHJpYnV0ZUhUTUwgYXR0cmlidXRlX2h0bWw7Ci0KLSAgTWV0aG9kSFRNTChTdHJpbmcgZGlyLCBTdHJpbmcgY2xhc3NfbmFtZSwKLSAgICAgICAgICAgICBNZXRob2RbXSBtZXRob2RzLCBGaWVsZFtdIGZpZWxkcywKLSAgICAgICAgICAgICBDb25zdGFudEhUTUwgY29uc3RhbnRfaHRtbCwgQXR0cmlidXRlSFRNTCBhdHRyaWJ1dGVfaHRtbCkgdGhyb3dzIElPRXhjZXB0aW9uCi0gIHsKLSAgICB0aGlzLmNsYXNzX25hbWUgICAgID0gY2xhc3NfbmFtZTsKLSAgICB0aGlzLmF0dHJpYnV0ZV9odG1sID0gYXR0cmlidXRlX2h0bWw7Ci0gICAgdGhpcy5jb25zdGFudF9odG1sICA9IGNvbnN0YW50X2h0bWw7Ci0KLSAgICBmaWxlID0gbmV3IFByaW50V3JpdGVyKG5ldyBGaWxlT3V0cHV0U3RyZWFtKGRpciArIGNsYXNzX25hbWUgKyAiX21ldGhvZHMuaHRtbCIpKTsKLQotICAgIGZpbGUucHJpbnRsbigiPEhUTUw+PEJPRFkgQkdDT0xPUj1cIiNDMEMwQzBcIj48VEFCTEUgQk9SREVSPTA+Iik7Ci0gICAgZmlsZS5wcmludGxuKCI8VFI+PFRIIEFMSUdOPUxFRlQ+QWNjZXNzJm5ic3A7ZmxhZ3M8L1RIPjxUSCBBTElHTj1MRUZUPlR5cGU8L1RIPiIgKwotICAgICAgICAgICAgICAgICAiPFRIIEFMSUdOPUxFRlQ+RmllbGQmbmJzcDtuYW1lPC9USD48L1RSPiIpOwotICAgIGZvcihpbnQgaT0wOyBpIDwgZmllbGRzLmxlbmd0aDsgaSsrKQotICAgICAgd3JpdGVGaWVsZChmaWVsZHNbaV0pOwotICAgIGZpbGUucHJpbnRsbigiPC9UQUJMRT4iKTsKLQotICAgIGZpbGUucHJpbnRsbigiPFRBQkxFIEJPUkRFUj0wPjxUUj48VEggQUxJR049TEVGVD5BY2Nlc3MmbmJzcDtmbGFnczwvVEg+IiArCi0gICAgICAgICAgICAgICAgICI8VEggQUxJR049TEVGVD5SZXR1cm4mbmJzcDt0eXBlPC9USD48VEggQUxJR049TEVGVD5NZXRob2QmbmJzcDtuYW1lPC9USD4iICsKLSAgICAgICAgICAgICAgICAgIjxUSCBBTElHTj1MRUZUPkFyZ3VtZW50czwvVEg+PC9UUj4iKTsKLSAgICBmb3IoaW50IGk9MDsgaSA8IG1ldGhvZHMubGVuZ3RoOyBpKyspCi0gICAgICB3cml0ZU1ldGhvZChtZXRob2RzW2ldLCBpKTsKLQotICAgIGZpbGUucHJpbnRsbigiPC9UQUJMRT48L0JPRFk+PC9IVE1MPiIpOwotICAgIGZpbGUuY2xvc2UoKTsKLSAgfQotCi0gIC8qKgotICAgKiBQcmludCBmaWVsZCBvZiBjbGFzcy4KLSAgICoKLSAgICogQHBhcmFtIGZpZWxkIGZpZWxkIHRvIHByaW50Ci0gICAqIEBleGNlcHRpb24gamF2YS5pby5JT0V4Y2VwdGlvbgotICAgKi8KLSAgcHJpdmF0ZSB2b2lkIHdyaXRlRmllbGQoRmllbGQgZmllbGQpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgU3RyaW5nICAgICAgIHR5cGUgICA9IFV0aWxpdHkuc2lnbmF0dXJlVG9TdHJpbmcoZmllbGQuZ2V0U2lnbmF0dXJlKCkpOwotICAgIFN0cmluZyAgICAgICBuYW1lICAgPSBmaWVsZC5nZXROYW1lKCk7Ci0gICAgU3RyaW5nICAgICAgIGFjY2VzcyA9IFV0aWxpdHkuYWNjZXNzVG9TdHJpbmcoZmllbGQuZ2V0QWNjZXNzRmxhZ3MoKSk7Ci0gICAgQXR0cmlidXRlW10gIGF0dHJpYnV0ZXM7Ci0KLSAgICBhY2Nlc3MgPSBVdGlsaXR5LnJlcGxhY2UoYWNjZXNzLCAiICIsICImbmJzcDsiKTsKLQotICAgIGZpbGUucHJpbnQoIjxUUj48VEQ+PEZPTlQgQ09MT1I9XCIjRkYwMDAwXCI+IiArIGFjY2VzcyArICI8L0ZPTlQ+PC9URD5cbjxURD4iICsKLSAgICAgICAgICAgICAgIENsYXNzMkhUTUwucmVmZXJlbmNlVHlwZSh0eXBlKSArICI8L1REPjxURD48QSBOQU1FPVwiZmllbGQiICsgbmFtZSArICJcIj4iICsKLSAgICAgICAgICAgICAgIG5hbWUgKyAiPC9BPjwvVEQ+Iik7Ci0KLSAgICBhdHRyaWJ1dGVzID0gZmllbGQuZ2V0QXR0cmlidXRlcygpOwotCi0gICAgLy8gV3JpdGUgdGhlbSB0byB0aGUgQXR0cmlidXRlcy5odG1sIGZpbGUgd2l0aCBhbmNob3IgIjxuYW1lPls8aT5dIgotICAgIGZvcihpbnQgaT0wOyBpIDwgYXR0cmlidXRlcy5sZW5ndGg7IGkrKykKLSAgICAgIGF0dHJpYnV0ZV9odG1sLndyaXRlQXR0cmlidXRlKGF0dHJpYnV0ZXNbaV0sIG5hbWUgKyAiQCIgKyBpKTsKLQotICAgIGZvcihpbnQgaT0wOyBpIDwgYXR0cmlidXRlcy5sZW5ndGg7IGkrKykgewotICAgICAgaWYoYXR0cmlidXRlc1tpXS5nZXRUYWcoKSA9PSBBVFRSX0NPTlNUQU5UX1ZBTFVFKSB7IC8vIERlZmF1bHQgdmFsdWUKLSAgICAgICAgU3RyaW5nIHN0ciA9ICgoQ29uc3RhbnRWYWx1ZSlhdHRyaWJ1dGVzW2ldKS50b1N0cmluZygpOwotCi0gICAgICAgIC8vIFJlZmVyZW5jZSBhdHRyaWJ1dGUgaW4gX2F0dHJpYnV0ZXMuaHRtbAotICAgICAgICBmaWxlLnByaW50KCI8VEQ+PSA8QSBIUkVGPVwiIiArIGNsYXNzX25hbWUgKyAiX2F0dHJpYnV0ZXMuaHRtbCMiICsKLSAgICAgICAgICAgICAgICAgICBuYW1lICsgIkAiICsgaSArICJcIiBUQVJHRVQ9XCJBdHRyaWJ1dGVzXCI+IiArIHN0ciArICI8L1REPlxuIik7Ci0gICAgICAgIGJyZWFrOwotICAgICAgfQotICAgIH0KLQotICAgIGZpbGUucHJpbnRsbigiPC9UUj4iKTsKLSAgfQotCi0gIHByaXZhdGUgZmluYWwgdm9pZCB3cml0ZU1ldGhvZChNZXRob2QgbWV0aG9kLCBpbnQgbWV0aG9kX251bWJlcikgdGhyb3dzIElPRXhjZXB0aW9uIHsKLSAgICAvLyBHZXQgcmF3IHNpZ25hdHVyZQotICAgIFN0cmluZyAgICAgICBzaWduYXR1cmUgICAgICA9IG1ldGhvZC5nZXRTaWduYXR1cmUoKTsKLSAgICAvLyBHZXQgYXJyYXkgb2Ygc3RyaW5ncyBjb250YWluaW5nIHRoZSBhcmd1bWVudCB0eXBlcwotICAgIFN0cmluZ1tdICAgICBhcmdzICAgICAgICAgICA9IFV0aWxpdHkubWV0aG9kU2lnbmF0dXJlQXJndW1lbnRUeXBlcyhzaWduYXR1cmUsIGZhbHNlKTsKLSAgICAvLyBHZXQgcmV0dXJuIHR5cGUgc3RyaW5nCi0gICAgU3RyaW5nICAgICAgIHR5cGUgICAgICAgICAgID0gVXRpbGl0eS5tZXRob2RTaWduYXR1cmVSZXR1cm5UeXBlKHNpZ25hdHVyZSwgZmFsc2UpOwotICAgIC8vIEdldCBtZXRob2QgbmFtZQotICAgIFN0cmluZyAgICAgICBuYW1lICAgICAgICAgICA9IG1ldGhvZC5nZXROYW1lKCksIGh0bWxfbmFtZTsKLSAgICAvLyBHZXQgbWV0aG9kJ3MgYWNjZXNzIGZsYWdzCi0gICAgU3RyaW5nICAgICAgIGFjY2VzcyAgICAgICAgID0gVXRpbGl0eS5hY2Nlc3NUb1N0cmluZyhtZXRob2QuZ2V0QWNjZXNzRmxhZ3MoKSk7Ci0gICAgLy8gR2V0IHRoZSBtZXRob2QncyBhdHRyaWJ1dGVzLCB0aGUgQ29kZSBBdHRyaWJ1dGUgaW4gcGFydGljdWxhcgotICAgIEF0dHJpYnV0ZVtdICBhdHRyaWJ1dGVzICAgICA9IG1ldGhvZC5nZXRBdHRyaWJ1dGVzKCk7Ci0KLSAgICAvKiBIVE1MIGRvZXNuJ3QgbGlrZSBuYW1lcyBsaWtlIDxjbGluaXQ+IGFuZCBzcGFjZXMgYXJlIHBsYWNlcyB0byBicmVhawotICAgICAqIGxpbmVzLiBCb3RoIHdlIGRvbid0IHdhbnQuLi4KLSAgICAgKi8KLSAgICBhY2Nlc3MgICAgICA9IFV0aWxpdHkucmVwbGFjZShhY2Nlc3MsICIgIiwgIiZuYnNwOyIpOwotICAgIGh0bWxfbmFtZSAgID0gQ2xhc3MySFRNTC50b0hUTUwobmFtZSk7Ci0KLSAgICBmaWxlLnByaW50KCI8VFIgVkFMSUdOPVRPUD48VEQ+PEZPTlQgQ09MT1I9XCIjRkYwMDAwXCI+PEEgTkFNRT1tZXRob2QiICsgbWV0aG9kX251bWJlciArICI+IiArCi0gICAgICAgICAgICAgICBhY2Nlc3MgKyAiPC9BPjwvRk9OVD48L1REPiIpOwotCi0gICAgZmlsZS5wcmludCgiPFREPiIgKyBDbGFzczJIVE1MLnJlZmVyZW5jZVR5cGUodHlwZSkgKyAiPC9URD48VEQ+IiArCi0gICAgICAgICAgICAgICAiPEEgSFJFRj0iICsgY2xhc3NfbmFtZSArICJfY29kZS5odG1sI21ldGhvZCIgKyBtZXRob2RfbnVtYmVyICsKLSAgICAgICAgICAgICAgICIgVEFSR0VUPUNvZGU+IiArIGh0bWxfbmFtZSArICI8L0E+PC9URD5cbjxURD4oIik7Ci0KLSAgICBmb3IoaW50IGk9MDsgaSA8IGFyZ3MubGVuZ3RoOyBpKyspIHsKLSAgICAgIGZpbGUucHJpbnQoQ2xhc3MySFRNTC5yZWZlcmVuY2VUeXBlKGFyZ3NbaV0pKTsKLSAgICAgIGlmKGkgPCBhcmdzLmxlbmd0aCAtIDEpCi0gICAgICAgIGZpbGUucHJpbnQoIiwgIik7Ci0gICAgfQotCi0gICAgZmlsZS5wcmludCgiKTwvVEQ+PC9UUj4iKTsKLQotICAgIC8vIENoZWNrIGZvciB0aHJvd24gZXhjZXB0aW9ucwotICAgIGZvcihpbnQgaT0wOyBpIDwgYXR0cmlidXRlcy5sZW5ndGg7IGkrKykgewotICAgICAgYXR0cmlidXRlX2h0bWwud3JpdGVBdHRyaWJ1dGUoYXR0cmlidXRlc1tpXSwgIm1ldGhvZCIgKyBtZXRob2RfbnVtYmVyICsgIkAiICsgaSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZF9udW1iZXIpOwotCi0gICAgICBieXRlIHRhZyA9IGF0dHJpYnV0ZXNbaV0uZ2V0VGFnKCk7Ci0gICAgICBpZih0YWcgPT0gQVRUUl9FWENFUFRJT05TKSB7Ci0gICAgICAgIGZpbGUucHJpbnQoIjxUUiBWQUxJR049VE9QPjxURCBDT0xTUEFOPTI+PC9URD48VEggQUxJR049TEVGVD50aHJvd3M8L1RIPjxURD4iKTsKLSAgICAgICAgaW50W10gZXhjZXB0aW9ucyA9ICgoRXhjZXB0aW9uVGFibGUpYXR0cmlidXRlc1tpXSkuZ2V0RXhjZXB0aW9uSW5kZXhUYWJsZSgpOwotCi0gICAgICAgIGZvcihpbnQgaj0wOyBqIDwgZXhjZXB0aW9ucy5sZW5ndGg7IGorKykgewotICAgICAgICAgIGZpbGUucHJpbnQoY29uc3RhbnRfaHRtbC5yZWZlcmVuY2VDb25zdGFudChleGNlcHRpb25zW2pdKSk7Ci0KLSAgICAgICAgICBpZihqIDwgZXhjZXB0aW9ucy5sZW5ndGggLSAxKQotICAgICAgICAgICAgZmlsZS5wcmludCgiLCAiKTsKLSAgICAgICAgfQotICAgICAgICBmaWxlLnByaW50bG4oIjwvVEQ+PC9UUj4iKTsKLSAgICAgIH0gZWxzZSBpZih0YWcgPT0gQVRUUl9DT0RFKSB7Ci0gICAgICAgIEF0dHJpYnV0ZVtdIGNfYSA9ICgoQ29kZSlhdHRyaWJ1dGVzW2ldKS5nZXRBdHRyaWJ1dGVzKCk7Ci0KLSAgICAgICAgZm9yKGludCBqPTA7IGogPCBjX2EubGVuZ3RoOyBqKyspCi0gICAgICAgICAgYXR0cmlidXRlX2h0bWwud3JpdGVBdHRyaWJ1dGUoY19hW2pdLCAibWV0aG9kIiArIG1ldGhvZF9udW1iZXIgKyAiQCIgKyBpICsgIkAiICsgaiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRob2RfbnVtYmVyKTsKLSAgICAgIH0KLSAgICB9Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC91dGlsL1JlcG9zaXRvcnkuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC91dGlsL1JlcG9zaXRvcnkuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZDU4OGJhOS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvdXRpbC9SZXBvc2l0b3J5LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMDUgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwudXRpbDsKLQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJBcGFjaGUiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIGFuZAotICogICAgIkFwYWNoZSBCQ0VMIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwotICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvcgotICogICAgd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgICJBcGFjaGUgQkNFTCIsIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQKLSAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmNsYXNzZmlsZS5KYXZhQ2xhc3M7Ci0KLS8qKgotICogQWJzdHJhY3QgZGVmaW5pdGlvbiBvZiBhIGNsYXNzIHJlcG9zaXRvcnkuIEluc3RhbmNlcyBtYXkgYmUgdXNlZAotICogdG8gbG9hZCBjbGFzc2VzIGZyb20gZGlmZmVyZW50IHNvdXJjZXMgYW5kIG1heSBiZSB1c2VkIGluIHRoZQotICogUmVwb3NpdG9yeS5zZXRSZXBvc2l0b3J5IG1ldGhvZC4KLSAqCi0gKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLlJlcG9zaXRvcnkKLSAqIEBhdXRob3IgPEEgSFJFRj0ibWFpbHRvOm1hcmt1cy5kYWhtQGJlcmxpbi5kZSI+TS4gRGFobTwvQT4KLSAqIEBhdXRob3IgRGF2aWQgRGl4b24tUGV1Z2gKLSAqLwotcHVibGljIGludGVyZmFjZSBSZXBvc2l0b3J5IGV4dGVuZHMgamF2YS5pby5TZXJpYWxpemFibGUgewotICAvKioKLSAgICogU3RvcmUgdGhlIHByb3ZpZGVkIGNsYXNzIHVuZGVyICJjbGF6ei5nZXRDbGFzc05hbWUoKSIKLSAgICovCi0gIHB1YmxpYyB2b2lkIHN0b3JlQ2xhc3MoSmF2YUNsYXNzIGNsYXp6KTsKLQotICAvKioKLSAgICogUmVtb3ZlIGNsYXNzIGZyb20gcmVwb3NpdG9yeQotICAgKi8KLSAgcHVibGljIHZvaWQgcmVtb3ZlQ2xhc3MoSmF2YUNsYXNzIGNsYXp6KTsKLQotICAvKioKLSAgICogRmluZCB0aGUgY2xhc3Mgd2l0aCB0aGUgbmFtZSBwcm92aWRlZCwgaWYgdGhlIGNsYXNzCi0gICAqIGlzbid0IHRoZXJlLCByZXR1cm4gTlVMTC4KLSAgICovCi0gIHB1YmxpYyBKYXZhQ2xhc3MgZmluZENsYXNzKFN0cmluZyBjbGFzc05hbWUpOwotCi0gIC8qKgotICAgKiBGaW5kIHRoZSBjbGFzcyB3aXRoIHRoZSBuYW1lIHByb3ZpZGVkLCBpZiB0aGUgY2xhc3MKLSAgICogaXNuJ3QgdGhlcmUsIG1ha2UgYW4gYXR0ZW1wdCB0byBsb2FkIGl0LgotICAgKi8KLSAgcHVibGljIEphdmFDbGFzcyBsb2FkQ2xhc3MoU3RyaW5nIGNsYXNzTmFtZSkKLSAgICB0aHJvd3MgamF2YS5sYW5nLkNsYXNzTm90Rm91bmRFeGNlcHRpb247Ci0KLSAgLyoqCi0gICAqIEZpbmQgdGhlIEphdmFDbGFzcyBpbnN0YW5jZSBmb3IgdGhlIGdpdmVuIHJ1bi10aW1lIGNsYXNzIG9iamVjdAotICAgKi8KLSAgcHVibGljIEphdmFDbGFzcyBsb2FkQ2xhc3MoQ2xhc3MgY2xhenopCi0gICAgdGhyb3dzIGphdmEubGFuZy5DbGFzc05vdEZvdW5kRXhjZXB0aW9uOwotCi0gIC8qKiBDbGVhciBhbGwgZW50cmllcyBmcm9tIGNhY2hlLgotICAgKi8KLSAgcHVibGljIHZvaWQgY2xlYXIoKTsKLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC91dGlsL1NlY3VyaXR5U3VwcG9ydC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL3V0aWwvU2VjdXJpdHlTdXBwb3J0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDIyZjhkMzkuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL3V0aWwvU2VjdXJpdHlTdXBwb3J0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMjMgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMi0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLnV0aWw7Ci0KLWltcG9ydCBqYXZhLmlvLkZpbGU7Ci1pbXBvcnQgamF2YS5pby5GaWxlSW5wdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5pby5GaWxlTm90Rm91bmRFeGNlcHRpb247Ci1pbXBvcnQgamF2YS5pby5GaWxlbmFtZUZpbHRlcjsKLWltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOwotaW1wb3J0IGphdmEubGFuZy5DbGFzc0xvYWRlcjsKLWltcG9ydCBqYXZhLnNlY3VyaXR5LkFjY2Vzc0NvbnRyb2xsZXI7Ci1pbXBvcnQgamF2YS5zZWN1cml0eS5Qcml2aWxlZ2VkQWN0aW9uOwotaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpdmlsZWdlZEFjdGlvbkV4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLnNlY3VyaXR5LlByaXZpbGVnZWRFeGNlcHRpb25BY3Rpb247Ci1pbXBvcnQgamF2YS51dGlsLkxpc3RSZXNvdXJjZUJ1bmRsZTsKLWltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwotaW1wb3J0IGphdmEudXRpbC5NaXNzaW5nUmVzb3VyY2VFeGNlcHRpb247Ci1pbXBvcnQgamF2YS51dGlsLlJlc291cmNlQnVuZGxlOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgaXMgZHVwbGljYXRlZCBmb3IgZWFjaCBzdWJwYWNrYWdlIHNvIGtlZXAgaXQgaW4gc3luYy4gSXQgaXMKLSAqIHBhY2thZ2UgcHJpdmF0ZSBhbmQgdGhlcmVmb3JlIGlzIG5vdCBleHBvc2VkIGFzIHBhcnQgb2YgYW55IEFQSS4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBTZWN1cml0eVN1cHBvcnQgewotCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU2VjdXJpdHlTdXBwb3J0IHNlY3VyaXR5U3VwcG9ydCA9IG5ldyBTZWN1cml0eVN1cHBvcnQoKTsKLQotICAgIC8qKgotICAgICAqIFJldHVybiBhbiBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgU2VjdXJpdHlTdXBwb3J0IGdldEluc3RhbmNlKCkgewotICAgICAgICByZXR1cm4gc2VjdXJpdHlTdXBwb3J0OwotICAgIH0KLQotICAgIHN0YXRpYyBDbGFzc0xvYWRlciBnZXRDb250ZXh0Q2xhc3NMb2FkZXIoKSB7Ci0gICAgICAgIHJldHVybiAoQ2xhc3NMb2FkZXIpIEFjY2Vzc0NvbnRyb2xsZXIuZG9Qcml2aWxlZ2VkKG5ldyBQcml2aWxlZ2VkQWN0aW9uKCkgewotICAgICAgICAgICAgcHVibGljIE9iamVjdCBydW4oKSB7Ci0gICAgICAgICAgICAgICAgQ2xhc3NMb2FkZXIgY2wgPSBudWxsOwotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgIGNsID0gVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5nZXRDb250ZXh0Q2xhc3NMb2FkZXIoKTsKLSAgICAgICAgICAgICAgICB9IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBleCkgewotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICByZXR1cm4gY2w7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0pOwotICAgIH0KLQotICAgIHN0YXRpYyBDbGFzc0xvYWRlciBnZXRTeXN0ZW1DbGFzc0xvYWRlcigpIHsKLSAgICAgICAgcmV0dXJuIChDbGFzc0xvYWRlcikgQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQobmV3IFByaXZpbGVnZWRBY3Rpb24oKSB7Ci0gICAgICAgICAgICBwdWJsaWMgT2JqZWN0IHJ1bigpIHsKLSAgICAgICAgICAgICAgICBDbGFzc0xvYWRlciBjbCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgY2wgPSBDbGFzc0xvYWRlci5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpOwotICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIGV4KSB7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHJldHVybiBjbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSk7Ci0gICAgfQotCi0gICAgc3RhdGljIENsYXNzTG9hZGVyIGdldFBhcmVudENsYXNzTG9hZGVyKGZpbmFsIENsYXNzTG9hZGVyIGNsKSB7Ci0gICAgICAgIHJldHVybiAoQ2xhc3NMb2FkZXIpIEFjY2Vzc0NvbnRyb2xsZXIuZG9Qcml2aWxlZ2VkKG5ldyBQcml2aWxlZ2VkQWN0aW9uKCkgewotICAgICAgICAgICAgcHVibGljIE9iamVjdCBydW4oKSB7Ci0gICAgICAgICAgICAgICAgQ2xhc3NMb2FkZXIgcGFyZW50ID0gbnVsbDsKLSAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICBwYXJlbnQgPSBjbC5nZXRQYXJlbnQoKTsKLSAgICAgICAgICAgICAgICB9IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBleCkgewotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8vIGVsaW1pbmF0ZSBsb29wcyBpbiBjYXNlIG9mIHRoZSBib290Ci0gICAgICAgICAgICAgICAgLy8gQ2xhc3NMb2FkZXIgcmV0dXJuaW5nIGl0c2VsZiBhcyBhIHBhcmVudAotICAgICAgICAgICAgICAgIHJldHVybiAocGFyZW50ID09IGNsKSA/IG51bGwgOiBwYXJlbnQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0pOwotICAgIH0KLQotICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldFN5c3RlbVByb3BlcnR5KGZpbmFsIFN0cmluZyBwcm9wTmFtZSkgewotICAgICAgICByZXR1cm4gKFN0cmluZykgQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQobmV3IFByaXZpbGVnZWRBY3Rpb24oKSB7Ci0gICAgICAgICAgICBwdWJsaWMgT2JqZWN0IHJ1bigpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gU3lzdGVtLmdldFByb3BlcnR5KHByb3BOYW1lKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSk7Ci0gICAgfQotCi0gICAgc3RhdGljIEZpbGVJbnB1dFN0cmVhbSBnZXRGaWxlSW5wdXRTdHJlYW0oZmluYWwgRmlsZSBmaWxlKQotICAgICAgICAgICAgdGhyb3dzIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICByZXR1cm4gKEZpbGVJbnB1dFN0cmVhbSkgQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQobmV3IFByaXZpbGVnZWRFeGNlcHRpb25BY3Rpb24oKSB7Ci0gICAgICAgICAgICAgICAgcHVibGljIE9iamVjdCBydW4oKSB0aHJvd3MgRmlsZU5vdEZvdW5kRXhjZXB0aW9uIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBGaWxlSW5wdXRTdHJlYW0oZmlsZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfSk7Ci0gICAgICAgIH0gY2F0Y2ggKFByaXZpbGVnZWRBY3Rpb25FeGNlcHRpb24gZSkgewotICAgICAgICAgICAgdGhyb3cgKEZpbGVOb3RGb3VuZEV4Y2VwdGlvbikgZS5nZXRFeGNlcHRpb24oKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybiByZXNvdXJjZSB1c2luZyB0aGUgc2FtZSBjbGFzc2xvYWRlciBmb3IgdGhlIE9iamVjdEZhY3RvcnkgYnkKLSAgICAgKiBkZWZhdWx0IG9yIGJvb3RjbGFzc2xvYWRlciB3aGVuIFNlY3VyaXR5IE1hbmFnZXIgaXMgaW4gcGxhY2UKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIElucHV0U3RyZWFtIGdldFJlc291cmNlQXNTdHJlYW0oZmluYWwgU3RyaW5nIG5hbWUpIHsKLSAgICAgICAgaWYgKFN5c3RlbS5nZXRTZWN1cml0eU1hbmFnZXIoKSAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gZ2V0UmVzb3VyY2VBc1N0cmVhbShudWxsLCBuYW1lKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiBnZXRSZXNvdXJjZUFzU3RyZWFtKGZpbmRDbGFzc0xvYWRlcigpLCBuYW1lKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyBzdGF0aWMgSW5wdXRTdHJlYW0gZ2V0UmVzb3VyY2VBc1N0cmVhbShmaW5hbCBDbGFzc0xvYWRlciBjbCwKLSAgICAgICAgICAgIGZpbmFsIFN0cmluZyBuYW1lKSB7Ci0gICAgICAgIHJldHVybiAoSW5wdXRTdHJlYW0pIEFjY2Vzc0NvbnRyb2xsZXIuZG9Qcml2aWxlZ2VkKG5ldyBQcml2aWxlZ2VkQWN0aW9uKCkgewotICAgICAgICAgICAgcHVibGljIE9iamVjdCBydW4oKSB7Ci0gICAgICAgICAgICAgICAgSW5wdXRTdHJlYW0gcmlzOwotICAgICAgICAgICAgICAgIGlmIChjbCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJpcyA9IE9iamVjdC5jbGFzcy5nZXRSZXNvdXJjZUFzU3RyZWFtKCIvIiArIG5hbWUpOwotICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIHJpcyA9IGNsLmdldFJlc291cmNlQXNTdHJlYW0obmFtZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHJldHVybiByaXM7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0pOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldHMgYSByZXNvdXJjZSBidW5kbGUgdXNpbmcgdGhlIHNwZWNpZmllZCBiYXNlIG5hbWUsIHRoZSBkZWZhdWx0IGxvY2FsZSwKLSAgICAgKiBhbmQgdGhlIGNhbGxlcidzIGNsYXNzIGxvYWRlci4KLSAgICAgKgotICAgICAqIEBwYXJhbSBidW5kbGUgdGhlIGJhc2UgbmFtZSBvZiB0aGUgcmVzb3VyY2UgYnVuZGxlLCBhIGZ1bGx5IHF1YWxpZmllZAotICAgICAqIGNsYXNzIG5hbWUKLSAgICAgKiBAcmV0dXJuIGEgcmVzb3VyY2UgYnVuZGxlIGZvciB0aGUgZ2l2ZW4gYmFzZSBuYW1lIGFuZCB0aGUgZGVmYXVsdCBsb2NhbGUKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIExpc3RSZXNvdXJjZUJ1bmRsZSBnZXRSZXNvdXJjZUJ1bmRsZShTdHJpbmcgYnVuZGxlKSB7Ci0gICAgICAgIHJldHVybiBnZXRSZXNvdXJjZUJ1bmRsZShidW5kbGUsIExvY2FsZS5nZXREZWZhdWx0KCkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldHMgYSByZXNvdXJjZSBidW5kbGUgdXNpbmcgdGhlIHNwZWNpZmllZCBiYXNlIG5hbWUgYW5kIGxvY2FsZSwgYW5kIHRoZQotICAgICAqIGNhbGxlcidzIGNsYXNzIGxvYWRlci4KLSAgICAgKgotICAgICAqIEBwYXJhbSBidW5kbGUgdGhlIGJhc2UgbmFtZSBvZiB0aGUgcmVzb3VyY2UgYnVuZGxlLCBhIGZ1bGx5IHF1YWxpZmllZAotICAgICAqIGNsYXNzIG5hbWUKLSAgICAgKiBAcGFyYW0gbG9jYWxlIHRoZSBsb2NhbGUgZm9yIHdoaWNoIGEgcmVzb3VyY2UgYnVuZGxlIGlzIGRlc2lyZWQKLSAgICAgKiBAcmV0dXJuIGEgcmVzb3VyY2UgYnVuZGxlIGZvciB0aGUgZ2l2ZW4gYmFzZSBuYW1lIGFuZCBsb2NhbGUKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIExpc3RSZXNvdXJjZUJ1bmRsZSBnZXRSZXNvdXJjZUJ1bmRsZShmaW5hbCBTdHJpbmcgYnVuZGxlLCBmaW5hbCBMb2NhbGUgbG9jYWxlKSB7Ci0gICAgICAgIHJldHVybiBBY2Nlc3NDb250cm9sbGVyLmRvUHJpdmlsZWdlZChuZXcgUHJpdmlsZWdlZEFjdGlvbjxMaXN0UmVzb3VyY2VCdW5kbGU+KCkgewotICAgICAgICAgICAgcHVibGljIExpc3RSZXNvdXJjZUJ1bmRsZSBydW4oKSB7Ci0gICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChMaXN0UmVzb3VyY2VCdW5kbGUpIFJlc291cmNlQnVuZGxlLmdldEJ1bmRsZShidW5kbGUsIGxvY2FsZSk7Ci0gICAgICAgICAgICAgICAgfSBjYXRjaCAoTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoTGlzdFJlc291cmNlQnVuZGxlKSBSZXNvdXJjZUJ1bmRsZS5nZXRCdW5kbGUoYnVuZGxlLCBuZXcgTG9jYWxlKCJlbiIsICJVUyIpKTsKLSAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uIGUyKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ291bGQgbm90IGxvYWQgYW55IHJlc291cmNlIGJ1bmRsZSBieSAiICsgYnVuZGxlLCBidW5kbGUsICIiKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfSk7Ci0gICAgfQotCi0gICAgcHVibGljIHN0YXRpYyBTdHJpbmdbXSBnZXRGaWxlTGlzdChmaW5hbCBGaWxlIGYsIGZpbmFsIEZpbGVuYW1lRmlsdGVyIGZpbHRlcikgewotICAgICAgICByZXR1cm4gKChTdHJpbmdbXSkgQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQobmV3IFByaXZpbGVnZWRBY3Rpb24oKSB7Ci0gICAgICAgICAgICBwdWJsaWMgT2JqZWN0IHJ1bigpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZi5saXN0KGZpbHRlcik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0pKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gZ2V0RmlsZUV4aXN0cyhmaW5hbCBGaWxlIGYpIHsKLSAgICAgICAgcmV0dXJuICgoQm9vbGVhbikgQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQobmV3IFByaXZpbGVnZWRBY3Rpb24oKSB7Ci0gICAgICAgICAgICBwdWJsaWMgT2JqZWN0IHJ1bigpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZi5leGlzdHMoKSA/IEJvb2xlYW4uVFJVRSA6IEJvb2xlYW4uRkFMU0U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0pKS5ib29sZWFuVmFsdWUoKTsKLSAgICB9Ci0KLSAgICBzdGF0aWMgbG9uZyBnZXRMYXN0TW9kaWZpZWQoZmluYWwgRmlsZSBmKSB7Ci0gICAgICAgIHJldHVybiAoKExvbmcpIEFjY2Vzc0NvbnRyb2xsZXIuZG9Qcml2aWxlZ2VkKG5ldyBQcml2aWxlZ2VkQWN0aW9uKCkgewotICAgICAgICAgICAgcHVibGljIE9iamVjdCBydW4oKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBMb25nKGYubGFzdE1vZGlmaWVkKCkpOwotICAgICAgICAgICAgfQotICAgICAgICB9KSkubG9uZ1ZhbHVlKCk7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBGaWd1cmUgb3V0IHdoaWNoIENsYXNzTG9hZGVyIHRvIHVzZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIENsYXNzTG9hZGVyIGZpbmRDbGFzc0xvYWRlcigpCi0gICAgewotICAgICAgICBpZiAoU3lzdGVtLmdldFNlY3VyaXR5TWFuYWdlcigpIT1udWxsKSB7Ci0gICAgICAgICAgICAvL3RoaXMgd2lsbCBlbnN1cmUgYm9vdGNsYXNzbG9hZGVyIGlzIHVzZWQKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIFNlY3VyaXR5U3VwcG9ydC5jbGFzcy5nZXRDbGFzc0xvYWRlcigpOwotICAgICAgICB9Ci0gICAgfSAvLyBmaW5kQ2xhc3NMb2FkZXIoKTpDbGFzc0xvYWRlcgotCi0gICAgcHJpdmF0ZSBTZWN1cml0eVN1cHBvcnQoKSB7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL3V0aWwvU3ludGhldGljUmVwb3NpdG9yeS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL3V0aWwvU3ludGhldGljUmVwb3NpdG9yeS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkZGM2NDdhLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC91dGlsL1N5bnRoZXRpY1JlcG9zaXRvcnkuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIwNyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC51dGlsOwotCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgYW5kCi0gKiAgICAiQXBhY2hlIEJDRUwiIG11c3Qgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCi0gKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCi0gKiAgICB3cml0dGVuIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgIkFwYWNoZSBCQ0VMIiwgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dAotICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi1pbXBvcnQgamF2YS5pby4qOwotCi1pbXBvcnQgamF2YS51dGlsLk1hcDsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmNsYXNzZmlsZS4qOwotCi0vKioKLSAqIFRoaXMgcmVwb3NpdG9yeSBpcyB1c2VkIGluIHNpdHVhdGlvbnMgd2hlcmUgYSBDbGFzcyBpcyBjcmVhdGVkCi0gKiBvdXRzaWRlIHRoZSByZWFsbSBvZiBhIENsYXNzTG9hZGVyLiBDbGFzc2VzIGFyZSBsb2FkZWQgZnJvbQotICogdGhlIGZpbGUgc3lzdGVtcyB1c2luZyB0aGUgcGF0aHMgc3BlY2lmaWVkIGluIHRoZSBnaXZlbgotICogY2xhc3MgcGF0aC4gQnkgZGVmYXVsdCwgdGhpcyBpcyB0aGUgdmFsdWUgcmV0dXJuZWQgYnkKLSAqIENsYXNzUGF0aC5nZXRDbGFzc1BhdGgoKS4KLSAqIDxicj4KLSAqIEl0IGlzIGRlc2lnbmVkIHRvIGJlIHVzZWQgYXMgYSBzaW5nbGV0b24sIGhvd2V2ZXIgaXQKLSAqIGNhbiBhbHNvIGJlIHVzZWQgd2l0aCBjdXN0b20gY2xhc3NwYXRocy4KLSAqCi0vKioKLSAqIEFic3RyYWN0IGRlZmluaXRpb24gb2YgYSBjbGFzcyByZXBvc2l0b3J5LiBJbnN0YW5jZXMgbWF5IGJlIHVzZWQKLSAqIHRvIGxvYWQgY2xhc3NlcyBmcm9tIGRpZmZlcmVudCBzb3VyY2VzIGFuZCBtYXkgYmUgdXNlZCBpbiB0aGUKLSAqIFJlcG9zaXRvcnkuc2V0UmVwb3NpdG9yeSBtZXRob2QuCi0gKgotICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5SZXBvc2l0b3J5Ci0gKgotICogQGF1dGhvciA8QSBIUkVGPSJtYWlsdG86bWFya3VzLmRhaG1AYmVybGluLmRlIj5NLiBEYWhtPC9BPgotICogQGF1dGhvciBEYXZpZCBEaXhvbi1QZXVnaAotICovCi1wdWJsaWMgY2xhc3MgU3ludGhldGljUmVwb3NpdG9yeSBpbXBsZW1lbnRzIFJlcG9zaXRvcnkgewotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgREVGQVVMVF9QQVRIID0gQ2xhc3NQYXRoLmdldENsYXNzUGF0aCgpOwotCi0gIHByaXZhdGUgc3RhdGljIEhhc2hNYXAgX2luc3RhbmNlcyA9IG5ldyBIYXNoTWFwKCk7IC8vIENMQVNTUEFUSCBYIFJFUE9TSVRPUlkKLQotICBwcml2YXRlIENsYXNzUGF0aCBfcGF0aCA9IG51bGw7Ci0gIHByaXZhdGUgSGFzaE1hcCAgIF9sb2FkZWRDbGFzc2VzID0gbmV3IEhhc2hNYXAoKTsgLy8gQ0xBU1NOQU1FIFggSkFWQUNMQVNTCi0KLSAgcHJpdmF0ZSBTeW50aGV0aWNSZXBvc2l0b3J5KENsYXNzUGF0aCBwYXRoKSB7Ci0gICAgX3BhdGggPSBwYXRoOwotICB9Ci0KLSAgcHVibGljIHN0YXRpYyBTeW50aGV0aWNSZXBvc2l0b3J5IGdldEluc3RhbmNlKCkgewotICAgIHJldHVybiBnZXRJbnN0YW5jZShDbGFzc1BhdGguU1lTVEVNX0NMQVNTX1BBVEgpOwotICB9Ci0KLSAgcHVibGljIHN0YXRpYyBTeW50aGV0aWNSZXBvc2l0b3J5IGdldEluc3RhbmNlKENsYXNzUGF0aCBjbGFzc1BhdGgpIHsKLSAgICBTeW50aGV0aWNSZXBvc2l0b3J5IHJlcCA9IChTeW50aGV0aWNSZXBvc2l0b3J5KV9pbnN0YW5jZXMuZ2V0KGNsYXNzUGF0aCk7Ci0KLSAgICBpZihyZXAgPT0gbnVsbCkgewotICAgICAgcmVwID0gbmV3IFN5bnRoZXRpY1JlcG9zaXRvcnkoY2xhc3NQYXRoKTsKLSAgICAgIF9pbnN0YW5jZXMucHV0KGNsYXNzUGF0aCwgcmVwKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gcmVwOwotICB9Ci0KLSAgLyoqCi0gICAqIFN0b3JlIGEgbmV3IEphdmFDbGFzcyBpbnN0YW5jZSBpbnRvIHRoaXMgUmVwb3NpdG9yeS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHN0b3JlQ2xhc3MoSmF2YUNsYXNzIGNsYXp6KSB7Ci0gICAgX2xvYWRlZENsYXNzZXMucHV0KGNsYXp6LmdldENsYXNzTmFtZSgpLCBjbGF6eik7Ci0gICAgY2xhenouc2V0UmVwb3NpdG9yeSh0aGlzKTsKLSB9Ci0KLSAgLyoqCi0gICAqIFJlbW92ZSBjbGFzcyBmcm9tIHJlcG9zaXRvcnkKLSAgICovCi0gIHB1YmxpYyB2b2lkIHJlbW92ZUNsYXNzKEphdmFDbGFzcyBjbGF6eikgewotICAgIF9sb2FkZWRDbGFzc2VzLnJlbW92ZShjbGF6ei5nZXRDbGFzc05hbWUoKSk7Ci0gIH0KLQotICAvKioKLSAgICogRmluZCBhbiBhbHJlYWR5IGRlZmluZWQgKGNhY2hlZCkgSmF2YUNsYXNzIG9iamVjdCBieSBuYW1lLgotICAgKi8KLSAgcHVibGljIEphdmFDbGFzcyBmaW5kQ2xhc3MoU3RyaW5nIGNsYXNzTmFtZSkgewotICAgIHJldHVybiAoSmF2YUNsYXNzKV9sb2FkZWRDbGFzc2VzLmdldChjbGFzc05hbWUpOwotICB9Ci0KLSAgLyoqCi0gICAqIExvYWQgYSBKYXZhQ2xhc3Mgb2JqZWN0IGZvciB0aGUgZ2l2ZW4gY2xhc3MgbmFtZSB1c2luZwotICAgKiB0aGUgQ0xBU1NQQVRIIGVudmlyb25tZW50IHZhcmlhYmxlLgotICAgKi8KLSAgcHVibGljIEphdmFDbGFzcyBsb2FkQ2xhc3MoU3RyaW5nIGNsYXNzTmFtZSkKLSAgICB0aHJvd3MgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbgotICB7Ci0gICAgaWYoY2xhc3NOYW1lID09IG51bGwgfHwgY2xhc3NOYW1lLmVxdWFscygiIikpIHsKLSAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkludmFsaWQgY2xhc3MgbmFtZSAiICsgY2xhc3NOYW1lKTsKLSAgICB9Ci0KLSAgICBjbGFzc05hbWUgPSBjbGFzc05hbWUucmVwbGFjZSgnLycsICcuJyk7IC8vIEp1c3QgaW4gY2FzZSwgY2Fub25pY2FsIGZvcm0KLQotICAgIHRyeSB7Ci0gICAgICByZXR1cm4gbG9hZENsYXNzKF9wYXRoLmdldElucHV0U3RyZWFtKGNsYXNzTmFtZSksIGNsYXNzTmFtZSk7Ci0gICAgfSBjYXRjaChJT0V4Y2VwdGlvbiBlKSB7Ci0gICAgICB0aHJvdyBuZXcgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbigiRXhjZXB0aW9uIHdoaWxlIGxvb2tpbmcgZm9yIGNsYXNzICIgKwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lICsgIjogIiArIGUudG9TdHJpbmcoKSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFRyeSB0byBmaW5kIGNsYXNzIHNvdXJjZSB2aWEgZ2V0UmVzb3VyY2VBc1N0cmVhbSgpLgotICAgKiBAc2VlIENsYXNzCi0gICAqIEByZXR1cm4gSmF2YUNsYXNzIG9iamVjdCBmb3IgZ2l2ZW4gcnVudGltZSBjbGFzcwotICAgKi8KLSAgcHVibGljIEphdmFDbGFzcyBsb2FkQ2xhc3MoQ2xhc3MgY2xhenopIHRocm93cyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHsKLSAgICBTdHJpbmcgY2xhc3NOYW1lID0gY2xhenouZ2V0TmFtZSgpOwotICAgIFN0cmluZyBuYW1lICAgICAgPSBjbGFzc05hbWU7Ci0gICAgaW50ICAgIGkgICAgICAgICA9IG5hbWUubGFzdEluZGV4T2YoJy4nKTsKLQotICAgIGlmKGkgPiAwKSB7Ci0gICAgICBuYW1lID0gbmFtZS5zdWJzdHJpbmcoaSArIDEpOwotICAgIH0KLQotICAgIHJldHVybiBsb2FkQ2xhc3MoY2xhenouZ2V0UmVzb3VyY2VBc1N0cmVhbShuYW1lICsgIi5jbGFzcyIpLCBjbGFzc05hbWUpOwotICB9Ci0KLSAgcHJpdmF0ZSBKYXZhQ2xhc3MgbG9hZENsYXNzKElucHV0U3RyZWFtIGlzLCBTdHJpbmcgY2xhc3NOYW1lKQotICAgIHRocm93cyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uCi0gIHsKLSAgICBKYXZhQ2xhc3MgY2xhenogPSBmaW5kQ2xhc3MoY2xhc3NOYW1lKTsKLQotICAgIGlmKGNsYXp6ICE9IG51bGwpIHsKLSAgICAgIHJldHVybiBjbGF6ejsKLSAgICB9Ci0KLSAgICB0cnkgewotICAgICAgaWYoaXMgIT0gbnVsbCkgewotICAgICAgICBDbGFzc1BhcnNlciBwYXJzZXIgPSBuZXcgQ2xhc3NQYXJzZXIoaXMsIGNsYXNzTmFtZSk7Ci0gICAgICAgIGNsYXp6ID0gcGFyc2VyLnBhcnNlKCk7Ci0KLSAgICAgICAgc3RvcmVDbGFzcyhjbGF6eik7Ci0KLSAgICAgICAgcmV0dXJuIGNsYXp6OwotICAgICAgfQotICAgIH0gY2F0Y2goSU9FeGNlcHRpb24gZSkgewotICAgICAgdGhyb3cgbmV3IENsYXNzTm90Rm91bmRFeGNlcHRpb24oIkV4Y2VwdGlvbiB3aGlsZSBsb29raW5nIGZvciBjbGFzcyAiICsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZSArICI6ICIgKyBlLnRvU3RyaW5nKCkpOwotICAgIH0KLQotICAgIHRocm93IG5ldyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uKCJTeW50aGV0aWNSZXBvc2l0b3J5IGNvdWxkIG5vdCBsb2FkICIgKwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZSk7Ci0gIH0KLQotICAvKiogQ2xlYXIgYWxsIGVudHJpZXMgZnJvbSBjYWNoZS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGNsZWFyKCkgewotICAgIF9sb2FkZWRDbGFzc2VzLmNsZWFyKCk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC91dGlsL3BhY2thZ2UuaHRtbCBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC91dGlsL3BhY2thZ2UuaHRtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYjE0ZWM0Ni4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvdXRpbC9wYWNrYWdlLmh0bWwKKysrIC9kZXYvbnVsbApAQCAtMSwyNSArMCwwIEBACi08IURPQ1RZUEUgSFRNTCBQVUJMSUMgIi0vL1czQy8vRFREIEhUTUwgMy4yIEZpbmFsLy9FTiI+Ci08aHRtbD4KLTxoZWFkPgotPCEtLQotJElkOiBwYWNrYWdlLmh0bWwsdiAxLjEuMi4xIDIwMDUvMDcvMzEgMjM6NDY6NTcgamVmZnN1dHRvciBFeHAgJAotLS0+Ci08L2hlYWQ+Ci08Ym9keSBiZ2NvbG9yPSJ3aGl0ZSI+Ci08cD4KLVRoaXMgcGFja2FnZSBjb250YWlucyB1dGlsaXR5IGNsYXNzZXMgZm9yIHRoZQotPGEgaHJlZj0iaHR0cDovL2pha2FydGEuYXBhY2hlLm9yZy9iY2VsLyI+Qnl0ZSBDb2RlIEVuZ2luZWVyaW5nCi1MaWJyYXJ5PC9hPiwgbmFtZWx5OgotPC9wPgotPHA+Ci08dWw+Ci08bGk+Q29sbGVjdGlvbiBjbGFzc2VzIGZvciBKYXZhQ2xhc3Mgb2JqZWN0czwvbGk+Ci08bGk+QSBjb252ZXJ0ZXIgZm9yIGNsYXNzIGZpbGVzIHRvIEhUTUw8L2xpPgotPGxpPkEgdG9vbCB0byBmaW5kIGluc3RydWN0aW9ucyBwYXR0ZXJucyB2aWEgcmVndWxhciBleHByZXNzaW9uczwvbGk+Ci08bGk+QSBjbGFzcyB0byBmaW5kIGNsYXNzZXMgYXMgZGVmaW5lZCBpbiB0aGUgQ0xBU1NQQVRIPC9saT4KLTxsaT5BIGNsYXNzIGxvYWRlciB0aGF0IGFsbG93cyB0byBjcmVhdGUgY2xhc2VzIGF0IHJ1biB0aW1lPC9saT4KLTwvdWw+Ci0KLTwvcD4KLTwvYm9keT4KLTwvaHRtbD4KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvcmVnZXhwL2ludGVybmFsL0NoYXJhY3RlckFycmF5Q2hhcmFjdGVySXRlcmF0b3IuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvcmVnZXhwL2ludGVybmFsL0NoYXJhY3RlckFycmF5Q2hhcmFjdGVySXRlcmF0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNjM4MmQ0Ny4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3JlZ2V4cC9pbnRlcm5hbC9DaGFyYWN0ZXJBcnJheUNoYXJhY3Rlckl0ZXJhdG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3NiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnJlZ2V4cC5pbnRlcm5hbDsKLQotLyoqCi0gKiBFbmNhcHN1bGF0ZXMgY2hhcltdIGFzIENoYXJhY3Rlckl0ZXJhdG9yCi0gKgotICogQGF1dGhvciA8YSBocmVmPSJtYWlsdG86YWxlcy5ub3Zha0BuZXRiZWFucy5jb20iPkFsZXMgTm92YWs8L2E+Ci0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBDaGFyYWN0ZXJBcnJheUNoYXJhY3Rlckl0ZXJhdG9yIGltcGxlbWVudHMgQ2hhcmFjdGVySXRlcmF0b3IKLXsKLSAgICAvKiogZW5jYXBzdWxhdGVkICovCi0gICAgcHJpdmF0ZSBmaW5hbCBjaGFyW10gc3JjOwotICAgIC8qKiBvZmZzZXQgaW4gdGhlIGNoYXIgYXJyYXkgKi8KLSAgICBwcml2YXRlIGZpbmFsIGludCBvZmY7Ci0gICAgLyoqIHVzZWQgcG9ydGlvbiBvZiB0aGUgYXJyYXkgKi8KLSAgICBwcml2YXRlIGZpbmFsIGludCBsZW47Ci0KLSAgICAvKiogQHBhcmFtIHNyYyAtIGVuY2Fwc3VsYXRlZCBTdHJpbmcgKi8KLSAgICBwdWJsaWMgQ2hhcmFjdGVyQXJyYXlDaGFyYWN0ZXJJdGVyYXRvcihjaGFyW10gc3JjLCBpbnQgb2ZmLCBpbnQgbGVuKQotICAgIHsKLSAgICAgICAgdGhpcy5zcmMgPSBzcmM7Ci0gICAgICAgIHRoaXMub2ZmID0gb2ZmOwotICAgICAgICB0aGlzLmxlbiA9IGxlbjsKLSAgICB9Ci0KLSAgICAvKiogQHJldHVybiBhIHN1YnN0cmluZyAqLwotICAgIHB1YmxpYyBTdHJpbmcgc3Vic3RyaW5nKGludCBiZWdpbkluZGV4LCBpbnQgZW5kSW5kZXgpCi0gICAgewotICAgICAgICBpZiAoZW5kSW5kZXggPiBsZW4pIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCJlbmRJbmRleD0iICsgZW5kSW5kZXgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIjsgc2VxdWVuY2Ugc2l6ZT0iICsgbGVuKTsKLSAgICAgICAgfQotICAgICAgICBpZiAoYmVnaW5JbmRleCA8IDAgfHwgYmVnaW5JbmRleCA+IGVuZEluZGV4KSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigiYmVnaW5JbmRleD0iICsgYmVnaW5JbmRleAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiOyBlbmRJbmRleD0iICsgZW5kSW5kZXgpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBuZXcgU3RyaW5nKHNyYywgb2ZmICsgYmVnaW5JbmRleCwgZW5kSW5kZXggLSBiZWdpbkluZGV4KTsKLSAgICB9Ci0KLSAgICAvKiogQHJldHVybiBhIHN1YnN0cmluZyAqLwotICAgIHB1YmxpYyBTdHJpbmcgc3Vic3RyaW5nKGludCBiZWdpbkluZGV4KQotICAgIHsKLSAgICAgICAgcmV0dXJuIHN1YnN0cmluZyhiZWdpbkluZGV4LCBsZW4pOwotICAgIH0KLQotICAgIC8qKiBAcmV0dXJuIGEgY2hhcmFjdGVyIGF0IHRoZSBzcGVjaWZpZWQgcG9zaXRpb24uICovCi0gICAgcHVibGljIGNoYXIgY2hhckF0KGludCBwb3MpCi0gICAgewotICAgICAgICByZXR1cm4gc3JjW29mZiArIHBvc107Ci0gICAgfQotCi0gICAgLyoqIEByZXR1cm4gPHR0PnRydWU8L3R0PiBpZmYgaWYgdGhlIHNwZWNpZmllZCBpbmRleCBpcyBhZnRlciB0aGUgZW5kIG9mIHRoZSBjaGFyYWN0ZXIgc3RyZWFtICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNFbmQoaW50IHBvcykKLSAgICB7Ci0gICAgICAgIHJldHVybiAocG9zID49IGxlbik7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9yZWdleHAvaW50ZXJuYWwvQ2hhcmFjdGVySXRlcmF0b3IuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvcmVnZXhwL2ludGVybmFsL0NoYXJhY3Rlckl0ZXJhdG9yLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDY5ZGI1MzYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9yZWdleHAvaW50ZXJuYWwvQ2hhcmFjdGVySXRlcmF0b3IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQyICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUucmVnZXhwLmludGVybmFsOwotCi0vKioKLSAqIEVuY2Fwc3VsYXRlcyBkaWZmZXJlbnQgdHlwZXMgb2YgY2hhcmFjdGVyIHNvdXJjZXMgLSBTdHJpbmcsIElucHV0U3RyZWFtLCAuLi4KLSAqIERlZmluZXMgYSBzZXQgb2YgY29tbW9uIG1ldGhvZHMKLSAqCi0gKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzphbGVzLm5vdmFrQG5ldGJlYW5zLmNvbSI+QWxlcyBOb3ZhazwvYT4KLSAqLwotcHVibGljIGludGVyZmFjZSBDaGFyYWN0ZXJJdGVyYXRvcgotewotICAgIC8qKiBAcmV0dXJuIGEgc3Vic3RyaW5nICovCi0gICAgU3RyaW5nIHN1YnN0cmluZyhpbnQgYmVnaW5JbmRleCwgaW50IGVuZEluZGV4KTsKLQotICAgIC8qKiBAcmV0dXJuIGEgc3Vic3RyaW5nICovCi0gICAgU3RyaW5nIHN1YnN0cmluZyhpbnQgYmVnaW5JbmRleCk7Ci0KLSAgICAvKiogQHJldHVybiBhIGNoYXJhY3RlciBhdCB0aGUgc3BlY2lmaWVkIHBvc2l0aW9uLiAqLwotICAgIGNoYXIgY2hhckF0KGludCBwb3MpOwotCi0gICAgLyoqIEByZXR1cm4gPHR0PnRydWU8L3R0PiBpZmYgaWYgdGhlIHNwZWNpZmllZCBpbmRleCBpcyBhZnRlciB0aGUgZW5kIG9mIHRoZSBjaGFyYWN0ZXIgc3RyZWFtICovCi0gICAgYm9vbGVhbiBpc0VuZChpbnQgcG9zKTsKLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvcmVnZXhwL2ludGVybmFsL1JFLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3JlZ2V4cC9pbnRlcm5hbC9SRS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwY2RjMDEyLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvcmVnZXhwL2ludGVybmFsL1JFLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNzYwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUucmVnZXhwLmludGVybmFsOwotCi1pbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7Ci1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotLyoqCi0gKiBSRSBpcyBhbiBlZmZpY2llbnQsIGxpZ2h0d2VpZ2h0IHJlZ3VsYXIgZXhwcmVzc2lvbiBldmFsdWF0b3IvbWF0Y2hlcgotICogY2xhc3MuIFJlZ3VsYXIgZXhwcmVzc2lvbnMgYXJlIHBhdHRlcm4gZGVzY3JpcHRpb25zIHdoaWNoIGVuYWJsZQotICogc29waGlzdGljYXRlZCBtYXRjaGluZyBvZiBzdHJpbmdzLiAgSW4gYWRkaXRpb24gdG8gYmVpbmcgYWJsZSB0bwotICogbWF0Y2ggYSBzdHJpbmcgYWdhaW5zdCBhIHBhdHRlcm4sIHlvdSBjYW4gYWxzbyBleHRyYWN0IHBhcnRzIG9mIHRoZQotICogbWF0Y2guICBUaGlzIGlzIGVzcGVjaWFsbHkgdXNlZnVsIGluIHRleHQgcGFyc2luZyEgRGV0YWlscyBvbiB0aGUKLSAqIHN5bnRheCBvZiByZWd1bGFyIGV4cHJlc3Npb24gcGF0dGVybnMgYXJlIGdpdmVuIGJlbG93LgotICoKLSAqIDxwPgotICogVG8gY29tcGlsZSBhIHJlZ3VsYXIgZXhwcmVzc2lvbiAoUkUpLCB5b3UgY2FuIHNpbXBseSBjb25zdHJ1Y3QgYW4gUkUKLSAqIG1hdGNoZXIgb2JqZWN0IGZyb20gdGhlIHN0cmluZyBzcGVjaWZpY2F0aW9uIG9mIHRoZSBwYXR0ZXJuLCBsaWtlIHRoaXM6Ci0gKgotICogPHByZT4KLSAqICBSRSByID0gbmV3IFJFKCJhKmIiKTsKLSAqIDwvcHJlPgotICoKLSAqIDxwPgotICogT25jZSB5b3UgaGF2ZSBkb25lIHRoaXMsIHlvdSBjYW4gY2FsbCBlaXRoZXIgb2YgdGhlIFJFLm1hdGNoIG1ldGhvZHMgdG8KLSAqIHBlcmZvcm0gbWF0Y2hpbmcgb24gYSBTdHJpbmcuICBGb3IgZXhhbXBsZToKLSAqCi0gKiA8cHJlPgotICogIGJvb2xlYW4gbWF0Y2hlZCA9IHIubWF0Y2goImFhYWFiIik7Ci0gKiA8L3ByZT4KLSAqCi0gKiB3aWxsIGNhdXNlIHRoZSBib29sZWFuIG1hdGNoZWQgdG8gYmUgc2V0IHRvIHRydWUgYmVjYXVzZSB0aGUKLSAqIHBhdHRlcm4gImEqYiIgbWF0Y2hlcyB0aGUgc3RyaW5nICJhYWFhYiIuCi0gKgotICogPHA+Ci0gKiBJZiB5b3Ugd2VyZSBpbnRlcmVzdGVkIGluIHRoZSA8aT5udW1iZXI8L2k+IG9mIGEncyB3aGljaCBtYXRjaGVkIHRoZQotICogZmlyc3QgcGFydCBvZiBvdXIgZXhhbXBsZSBleHByZXNzaW9uLCB5b3UgY291bGQgY2hhbmdlIHRoZSBleHByZXNzaW9uIHRvCi0gKiAiKGEqKWIiLiAgVGhlbiB3aGVuIHlvdSBjb21waWxlZCB0aGUgZXhwcmVzc2lvbiBhbmQgbWF0Y2hlZCBpdCBhZ2FpbnN0Ci0gKiBzb21ldGhpbmcgbGlrZSAieGFhYWFiIiwgeW91IHdvdWxkIGdldCByZXN1bHRzIGxpa2UgdGhpczoKLSAqCi0gKiA8cHJlPgotICogIFJFIHIgPSBuZXcgUkUoIihhKiliIik7ICAgICAgICAgICAgICAgICAgLy8gQ29tcGlsZSBleHByZXNzaW9uCi0gKiAgYm9vbGVhbiBtYXRjaGVkID0gci5tYXRjaCgieGFhYWFiIik7ICAgICAvLyBNYXRjaCBhZ2FpbnN0ICJ4YWFhYWIiCi0gKgotICogIFN0cmluZyB3aG9sZUV4cHIgPSByLmdldFBhcmVuKDApOyAgICAgICAgLy8gd2hvbGVFeHByIHdpbGwgYmUgJ2FhYWFiJwotICogIFN0cmluZyBpbnNpZGVQYXJlbnMgPSByLmdldFBhcmVuKDEpOyAgICAgLy8gaW5zaWRlUGFyZW5zIHdpbGwgYmUgJ2FhYWEnCi0gKgotICogIGludCBzdGFydFdob2xlRXhwciA9IHIuZ2V0UGFyZW5TdGFydCgwKTsgLy8gc3RhcnRXaG9sZUV4cHIgd2lsbCBiZSBpbmRleCAxCi0gKiAgaW50IGVuZFdob2xlRXhwciA9IHIuZ2V0UGFyZW5FbmQoMCk7ICAgICAvLyBlbmRXaG9sZUV4cHIgd2lsbCBiZSBpbmRleCA2Ci0gKiAgaW50IGxlbldob2xlRXhwciA9IHIuZ2V0UGFyZW5MZW5ndGgoMCk7ICAvLyBsZW5XaG9sZUV4cHIgd2lsbCBiZSA1Ci0gKgotICogIGludCBzdGFydEluc2lkZSA9IHIuZ2V0UGFyZW5TdGFydCgxKTsgICAgLy8gc3RhcnRJbnNpZGUgd2lsbCBiZSBpbmRleCAxCi0gKiAgaW50IGVuZEluc2lkZSA9IHIuZ2V0UGFyZW5FbmQoMSk7ICAgICAgICAvLyBlbmRJbnNpZGUgd2lsbCBiZSBpbmRleCA1Ci0gKiAgaW50IGxlbkluc2lkZSA9IHIuZ2V0UGFyZW5MZW5ndGgoMSk7ICAgICAvLyBsZW5JbnNpZGUgd2lsbCBiZSA0Ci0gKiA8L3ByZT4KLSAqCi0gKiBZb3UgY2FuIGFsc28gcmVmZXIgdG8gdGhlIGNvbnRlbnRzIG9mIGEgcGFyZW50aGVzaXplZCBleHByZXNzaW9uCi0gKiB3aXRoaW4gYSByZWd1bGFyIGV4cHJlc3Npb24gaXRzZWxmLiAgVGhpcyBpcyBjYWxsZWQgYQotICogJ2JhY2tyZWZlcmVuY2UnLiAgVGhlIGZpcnN0IGJhY2tyZWZlcmVuY2UgaW4gYSByZWd1bGFyIGV4cHJlc3Npb24gaXMKLSAqIGRlbm90ZWQgYnkgXDEsIHRoZSBzZWNvbmQgYnkgXDIgYW5kIHNvIG9uLiAgU28gdGhlIGV4cHJlc3Npb246Ci0gKgotICogPHByZT4KLSAqICAoWzAtOV0rKT1cMQotICogPC9wcmU+Ci0gKgotICogd2lsbCBtYXRjaCBhbnkgc3RyaW5nIG9mIHRoZSBmb3JtIG49biAobGlrZSAwPTAgb3IgMj0yKS4KLSAqCi0gKiA8cD4KLSAqIFRoZSBmdWxsIHJlZ3VsYXIgZXhwcmVzc2lvbiBzeW50YXggYWNjZXB0ZWQgYnkgUkUgaXMgZGVzY3JpYmVkIGhlcmU6Ci0gKgotICogPHByZT4KLSAqCi0gKiAgPGI+PGZvbnQgZmFjZT10aW1lcyByb21hbj5DaGFyYWN0ZXJzPC9mb250PjwvYj4KLSAqCi0gKiAgICA8aT51bmljb2RlQ2hhcjwvaT4gICBNYXRjaGVzIGFueSBpZGVudGljYWwgdW5pY29kZSBjaGFyYWN0ZXIKLSAqICAgIFwgICAgICAgICAgICAgICAgICAgIFVzZWQgdG8gcXVvdGUgYSBtZXRhLWNoYXJhY3RlciAobGlrZSAnKicpCi0gKiAgICBcXCAgICAgICAgICAgICAgICAgICBNYXRjaGVzIGEgc2luZ2xlICdcJyBjaGFyYWN0ZXIKLSAqICAgIFwwbm5uICAgICAgICAgICAgICAgIE1hdGNoZXMgYSBnaXZlbiBvY3RhbCBjaGFyYWN0ZXIKLSAqICAgIFx4aGggICAgICAgICAgICAgICAgIE1hdGNoZXMgYSBnaXZlbiA4LWJpdCBoZXhhZGVjaW1hbCBjaGFyYWN0ZXIKLSAqICAgIFxcdWhoaGggICAgICAgICAgICAgIE1hdGNoZXMgYSBnaXZlbiAxNi1iaXQgaGV4YWRlY2ltYWwgY2hhcmFjdGVyCi0gKiAgICBcdCAgICAgICAgICAgICAgICAgICBNYXRjaGVzIGFuIEFTQ0lJIHRhYiBjaGFyYWN0ZXIKLSAqICAgIFxuICAgICAgICAgICAgICAgICAgIE1hdGNoZXMgYW4gQVNDSUkgbmV3bGluZSBjaGFyYWN0ZXIKLSAqICAgIFxyICAgICAgICAgICAgICAgICAgIE1hdGNoZXMgYW4gQVNDSUkgcmV0dXJuIGNoYXJhY3RlcgotICogICAgXGYgICAgICAgICAgICAgICAgICAgTWF0Y2hlcyBhbiBBU0NJSSBmb3JtIGZlZWQgY2hhcmFjdGVyCi0gKgotICoKLSAqICA8Yj48Zm9udCBmYWNlPXRpbWVzIHJvbWFuPkNoYXJhY3RlciBDbGFzc2VzPC9mb250PjwvYj4KLSAqCi0gKiAgICBbYWJjXSAgICAgICAgICAgICAgICBTaW1wbGUgY2hhcmFjdGVyIGNsYXNzCi0gKiAgICBbYS16QS1aXSAgICAgICAgICAgICBDaGFyYWN0ZXIgY2xhc3Mgd2l0aCByYW5nZXMKLSAqICAgIFteYWJjXSAgICAgICAgICAgICAgIE5lZ2F0ZWQgY2hhcmFjdGVyIGNsYXNzCi0gKiA8L3ByZT4KLSAqCi0gKiA8Yj5OT1RFOjwvYj4gSW5jb21wbGV0ZSByYW5nZXMgd2lsbCBiZSBpbnRlcnByZXRlZCBhcyAmcXVvdDtzdGFydHMKLSAqIGZyb20gemVybyZxdW90OyBvciAmcXVvdDtlbmRzIHdpdGggbGFzdCBjaGFyYWN0ZXImcXVvdDsuCi0gKiA8YnI+Ci0gKiBJLmUuIFstYV0gaXMgdGhlIHNhbWUgYXMgW1xcdTAwMDAtYV0sIGFuZCBbYS1dIGlzIHRoZSBzYW1lIGFzIFthLVxcdUZGRkZdLAotICogWy1dIG1lYW5zICZxdW90O2FsbCBjaGFyYWN0ZXJzJnF1b3Q7LgotICoKLSAqIDxwcmU+Ci0gKgotICogIDxiPjxmb250IGZhY2U9dGltZXMgcm9tYW4+U3RhbmRhcmQgUE9TSVggQ2hhcmFjdGVyIENsYXNzZXM8L2ZvbnQ+PC9iPgotICoKLSAqICAgIFs6YWxudW06XSAgICAgICAgICAgIEFscGhhbnVtZXJpYyBjaGFyYWN0ZXJzLgotICogICAgWzphbHBoYTpdICAgICAgICAgICAgQWxwaGFiZXRpYyBjaGFyYWN0ZXJzLgotICogICAgWzpibGFuazpdICAgICAgICAgICAgU3BhY2UgYW5kIHRhYiBjaGFyYWN0ZXJzLgotICogICAgWzpjbnRybDpdICAgICAgICAgICAgQ29udHJvbCBjaGFyYWN0ZXJzLgotICogICAgWzpkaWdpdDpdICAgICAgICAgICAgTnVtZXJpYyBjaGFyYWN0ZXJzLgotICogICAgWzpncmFwaDpdICAgICAgICAgICAgQ2hhcmFjdGVycyB0aGF0IGFyZSBwcmludGFibGUgYW5kIGFyZSBhbHNvIHZpc2libGUuCi0gKiAgICAgICAgICAgICAgICAgICAgICAgICAoQSBzcGFjZSBpcyBwcmludGFibGUsIGJ1dCBub3QgdmlzaWJsZSwgd2hpbGUgYW4KLSAqICAgICAgICAgICAgICAgICAgICAgICAgIGBhJyBpcyBib3RoLikKLSAqICAgIFs6bG93ZXI6XSAgICAgICAgICAgIExvd2VyLWNhc2UgYWxwaGFiZXRpYyBjaGFyYWN0ZXJzLgotICogICAgWzpwcmludDpdICAgICAgICAgICAgUHJpbnRhYmxlIGNoYXJhY3RlcnMgKGNoYXJhY3RlcnMgdGhhdCBhcmUgbm90Ci0gKiAgICAgICAgICAgICAgICAgICAgICAgICBjb250cm9sIGNoYXJhY3RlcnMuKQotICogICAgWzpwdW5jdDpdICAgICAgICAgICAgUHVuY3R1YXRpb24gY2hhcmFjdGVycyAoY2hhcmFjdGVycyB0aGF0IGFyZSBub3QgbGV0dGVyLAotICogICAgICAgICAgICAgICAgICAgICAgICAgZGlnaXRzLCBjb250cm9sIGNoYXJhY3RlcnMsIG9yIHNwYWNlIGNoYXJhY3RlcnMpLgotICogICAgWzpzcGFjZTpdICAgICAgICAgICAgU3BhY2UgY2hhcmFjdGVycyAoc3VjaCBhcyBzcGFjZSwgdGFiLCBhbmQgZm9ybWZlZWQsCi0gKiAgICAgICAgICAgICAgICAgICAgICAgICB0byBuYW1lIGEgZmV3KS4KLSAqICAgIFs6dXBwZXI6XSAgICAgICAgICAgIFVwcGVyLWNhc2UgYWxwaGFiZXRpYyBjaGFyYWN0ZXJzLgotICogICAgWzp4ZGlnaXQ6XSAgICAgICAgICAgQ2hhcmFjdGVycyB0aGF0IGFyZSBoZXhhZGVjaW1hbCBkaWdpdHMuCi0gKgotICoKLSAqICA8Yj48Zm9udCBmYWNlPXRpbWVzIHJvbWFuPk5vbi1zdGFuZGFyZCBQT1NJWC1zdHlsZSBDaGFyYWN0ZXIgQ2xhc3NlczwvZm9udD48L2I+Ci0gKgotICogICAgWzpqYXZhc3RhcnQ6XSAgICAgICAgU3RhcnQgb2YgYSBKYXZhIGlkZW50aWZpZXIKLSAqICAgIFs6amF2YXBhcnQ6XSAgICAgICAgIFBhcnQgb2YgYSBKYXZhIGlkZW50aWZpZXIKLSAqCi0gKgotICogIDxiPjxmb250IGZhY2U9dGltZXMgcm9tYW4+UHJlZGVmaW5lZCBDbGFzc2VzPC9mb250PjwvYj4KLSAqCi0gKiAgICAuICAgICAgICAgTWF0Y2hlcyBhbnkgY2hhcmFjdGVyIG90aGVyIHRoYW4gbmV3bGluZQotICogICAgXHcgICAgICAgIE1hdGNoZXMgYSAid29yZCIgY2hhcmFjdGVyIChhbHBoYW51bWVyaWMgcGx1cyAiXyIpCi0gKiAgICBcVyAgICAgICAgTWF0Y2hlcyBhIG5vbi13b3JkIGNoYXJhY3RlcgotICogICAgXHMgICAgICAgIE1hdGNoZXMgYSB3aGl0ZXNwYWNlIGNoYXJhY3RlcgotICogICAgXFMgICAgICAgIE1hdGNoZXMgYSBub24td2hpdGVzcGFjZSBjaGFyYWN0ZXIKLSAqICAgIFxkICAgICAgICBNYXRjaGVzIGEgZGlnaXQgY2hhcmFjdGVyCi0gKiAgICBcRCAgICAgICAgTWF0Y2hlcyBhIG5vbi1kaWdpdCBjaGFyYWN0ZXIKLSAqCi0gKgotICogIDxiPjxmb250IGZhY2U9dGltZXMgcm9tYW4+Qm91bmRhcnkgTWF0Y2hlcnM8L2ZvbnQ+PC9iPgotICoKLSAqICAgIF4gICAgICAgICBNYXRjaGVzIG9ubHkgYXQgdGhlIGJlZ2lubmluZyBvZiBhIGxpbmUKLSAqICAgICQgICAgICAgICBNYXRjaGVzIG9ubHkgYXQgdGhlIGVuZCBvZiBhIGxpbmUKLSAqICAgIFxiICAgICAgICBNYXRjaGVzIG9ubHkgYXQgYSB3b3JkIGJvdW5kYXJ5Ci0gKiAgICBcQiAgICAgICAgTWF0Y2hlcyBvbmx5IGF0IGEgbm9uLXdvcmQgYm91bmRhcnkKLSAqCi0gKgotICogIDxiPjxmb250IGZhY2U9dGltZXMgcm9tYW4+R3JlZWR5IENsb3N1cmVzPC9mb250PjwvYj4KLSAqCi0gKiAgICBBKiAgICAgICAgTWF0Y2hlcyBBIDAgb3IgbW9yZSB0aW1lcyAoZ3JlZWR5KQotICogICAgQSsgICAgICAgIE1hdGNoZXMgQSAxIG9yIG1vcmUgdGltZXMgKGdyZWVkeSkKLSAqICAgIEE/ICAgICAgICBNYXRjaGVzIEEgMSBvciAwIHRpbWVzIChncmVlZHkpCi0gKiAgICBBe259ICAgICAgTWF0Y2hlcyBBIGV4YWN0bHkgbiB0aW1lcyAoZ3JlZWR5KQotICogICAgQXtuLH0gICAgIE1hdGNoZXMgQSBhdCBsZWFzdCBuIHRpbWVzIChncmVlZHkpCi0gKiAgICBBe24sbX0gICAgTWF0Y2hlcyBBIGF0IGxlYXN0IG4gYnV0IG5vdCBtb3JlIHRoYW4gbSB0aW1lcyAoZ3JlZWR5KQotICoKLSAqCi0gKiAgPGI+PGZvbnQgZmFjZT10aW1lcyByb21hbj5SZWx1Y3RhbnQgQ2xvc3VyZXM8L2ZvbnQ+PC9iPgotICoKLSAqICAgIEEqPyAgICAgICBNYXRjaGVzIEEgMCBvciBtb3JlIHRpbWVzIChyZWx1Y3RhbnQpCi0gKiAgICBBKz8gICAgICAgTWF0Y2hlcyBBIDEgb3IgbW9yZSB0aW1lcyAocmVsdWN0YW50KQotICogICAgQT8/ICAgICAgIE1hdGNoZXMgQSAwIG9yIDEgdGltZXMgKHJlbHVjdGFudCkKLSAqCi0gKgotICogIDxiPjxmb250IGZhY2U9dGltZXMgcm9tYW4+TG9naWNhbCBPcGVyYXRvcnM8L2ZvbnQ+PC9iPgotICoKLSAqICAgIEFCICAgICAgICBNYXRjaGVzIEEgZm9sbG93ZWQgYnkgQgotICogICAgQXxCICAgICAgIE1hdGNoZXMgZWl0aGVyIEEgb3IgQgotICogICAgKEEpICAgICAgIFVzZWQgZm9yIHN1YmV4cHJlc3Npb24gZ3JvdXBpbmcKLSAqICAgKD86QSkgICAgICBVc2VkIGZvciBzdWJleHByZXNzaW9uIGNsdXN0ZXJpbmcgKGp1c3QgbGlrZSBncm91cGluZyBidXQKLSAqICAgICAgICAgICAgICBubyBiYWNrcmVmcykKLSAqCi0gKgotICogIDxiPjxmb250IGZhY2U9dGltZXMgcm9tYW4+QmFja3JlZmVyZW5jZXM8L2ZvbnQ+PC9iPgotICoKLSAqICAgIFwxICAgIEJhY2tyZWZlcmVuY2UgdG8gMXN0IHBhcmVudGhlc2l6ZWQgc3ViZXhwcmVzc2lvbgotICogICAgXDIgICAgQmFja3JlZmVyZW5jZSB0byAybmQgcGFyZW50aGVzaXplZCBzdWJleHByZXNzaW9uCi0gKiAgICBcMyAgICBCYWNrcmVmZXJlbmNlIHRvIDNyZCBwYXJlbnRoZXNpemVkIHN1YmV4cHJlc3Npb24KLSAqICAgIFw0ICAgIEJhY2tyZWZlcmVuY2UgdG8gNHRoIHBhcmVudGhlc2l6ZWQgc3ViZXhwcmVzc2lvbgotICogICAgXDUgICAgQmFja3JlZmVyZW5jZSB0byA1dGggcGFyZW50aGVzaXplZCBzdWJleHByZXNzaW9uCi0gKiAgICBcNiAgICBCYWNrcmVmZXJlbmNlIHRvIDZ0aCBwYXJlbnRoZXNpemVkIHN1YmV4cHJlc3Npb24KLSAqICAgIFw3ICAgIEJhY2tyZWZlcmVuY2UgdG8gN3RoIHBhcmVudGhlc2l6ZWQgc3ViZXhwcmVzc2lvbgotICogICAgXDggICAgQmFja3JlZmVyZW5jZSB0byA4dGggcGFyZW50aGVzaXplZCBzdWJleHByZXNzaW9uCi0gKiAgICBcOSAgICBCYWNrcmVmZXJlbmNlIHRvIDl0aCBwYXJlbnRoZXNpemVkIHN1YmV4cHJlc3Npb24KLSAqIDwvcHJlPgotICoKLSAqIDxwPgotICogQWxsIGNsb3N1cmUgb3BlcmF0b3JzICgrLCAqLCA/LCB7bSxufSkgYXJlIGdyZWVkeSBieSBkZWZhdWx0LCBtZWFuaW5nCi0gKiB0aGF0IHRoZXkgbWF0Y2ggYXMgbWFueSBlbGVtZW50cyBvZiB0aGUgc3RyaW5nIGFzIHBvc3NpYmxlIHdpdGhvdXQKLSAqIGNhdXNpbmcgdGhlIG92ZXJhbGwgbWF0Y2ggdG8gZmFpbC4gIElmIHlvdSB3YW50IGEgY2xvc3VyZSB0byBiZQotICogcmVsdWN0YW50IChub24tZ3JlZWR5KSwgeW91IGNhbiBzaW1wbHkgZm9sbG93IGl0IHdpdGggYSAnPycuICBBCi0gKiByZWx1Y3RhbnQgY2xvc3VyZSB3aWxsIG1hdGNoIGFzIGZldyBlbGVtZW50cyBvZiB0aGUgc3RyaW5nIGFzCi0gKiBwb3NzaWJsZSB3aGVuIGZpbmRpbmcgbWF0Y2hlcy4gIHttLG59IGNsb3N1cmVzIGRvbid0IGN1cnJlbnRseQotICogc3VwcG9ydCByZWx1Y3RhbmN5LgotICoKLSAqIDxwPgotICogPGI+PGZvbnQgZmFjZT0idGltZXMgcm9tYW4iPkxpbmUgdGVybWluYXRvcnM8L2ZvbnQ+PC9iPgotICogPGJyPgotICogQSBsaW5lIHRlcm1pbmF0b3IgaXMgYSBvbmUtIG9yIHR3by1jaGFyYWN0ZXIgc2VxdWVuY2UgdGhhdCBtYXJrcwotICogdGhlIGVuZCBvZiBhIGxpbmUgb2YgdGhlIGlucHV0IGNoYXJhY3RlciBzZXF1ZW5jZS4gVGhlIGZvbGxvd2luZwotICogYXJlIHJlY29nbml6ZWQgYXMgbGluZSB0ZXJtaW5hdG9yczoKLSAqIDx1bD4KLSAqIDxsaT5BIG5ld2xpbmUgKGxpbmUgZmVlZCkgY2hhcmFjdGVyICgnXG4nKSw8L2xpPgotICogPGxpPkEgY2FycmlhZ2UtcmV0dXJuIGNoYXJhY3RlciBmb2xsb3dlZCBpbW1lZGlhdGVseSBieSBhIG5ld2xpbmUgY2hhcmFjdGVyICgiXHJcbiIpLDwvbGk+Ci0gKiA8bGk+QSBzdGFuZGFsb25lIGNhcnJpYWdlLXJldHVybiBjaGFyYWN0ZXIgKCdccicpLDwvbGk+Ci0gKiA8bGk+QSBuZXh0LWxpbmUgY2hhcmFjdGVyICgnXHUwMDg1JyksPC9saT4KLSAqIDxsaT5BIGxpbmUtc2VwYXJhdG9yIGNoYXJhY3RlciAoJ1x1MjAyOCcpLCBvcjwvbGk+Ci0gKiA8bGk+QSBwYXJhZ3JhcGgtc2VwYXJhdG9yIGNoYXJhY3RlciAoJ1x1MjAyOSkuPC9saT4KLSAqIDwvdWw+Ci0gKgotICogPHA+Ci0gKiBSRSBydW5zIHByb2dyYW1zIGNvbXBpbGVkIGJ5IHRoZSBSRUNvbXBpbGVyIGNsYXNzLiAgQnV0IHRoZSBSRQotICogbWF0Y2hlciBjbGFzcyBkb2VzIG5vdCBpbmNsdWRlIHRoZSBhY3R1YWwgcmVndWxhciBleHByZXNzaW9uIGNvbXBpbGVyCi0gKiBmb3IgcmVhc29ucyBvZiBlZmZpY2llbmN5LiAgSW4gZmFjdCwgaWYgeW91IHdhbnQgdG8gcHJlLWNvbXBpbGUgb25lCi0gKiBvciBtb3JlIHJlZ3VsYXIgZXhwcmVzc2lvbnMsIHRoZSAncmVjb21waWxlJyBjbGFzcyBjYW4gYmUgaW52b2tlZAotICogZnJvbSB0aGUgY29tbWFuZCBsaW5lIHRvIHByb2R1Y2UgY29tcGlsZWQgb3V0cHV0IGxpa2UgdGhpczoKLSAqCi0gKiA8cHJlPgotICogICAgLy8gUHJlLWNvbXBpbGVkIHJlZ3VsYXIgZXhwcmVzc2lvbiAiYSpiIgotICogICAgY2hhcltdIHJlMUluc3RydWN0aW9ucyA9Ci0gKiAgICB7Ci0gKiAgICAgICAgMHgwMDdjLCAweDAwMDAsIDB4MDAxYSwgMHgwMDdjLCAweDAwMDAsIDB4MDAwZCwgMHgwMDQxLAotICogICAgICAgIDB4MDAwMSwgMHgwMDA0LCAweDAwNjEsIDB4MDA3YywgMHgwMDAwLCAweDAwMDMsIDB4MDA0NywKLSAqICAgICAgICAweDAwMDAsIDB4ZmZmNiwgMHgwMDdjLCAweDAwMDAsIDB4MDAwMywgMHgwMDRlLCAweDAwMDAsCi0gKiAgICAgICAgMHgwMDAzLCAweDAwNDEsIDB4MDAwMSwgMHgwMDA0LCAweDAwNjIsIDB4MDA0NSwgMHgwMDAwLAotICogICAgICAgIDB4MDAwMCwKLSAqICAgIH07Ci0gKgotICoKLSAqICAgIFJFUHJvZ3JhbSByZTEgPSBuZXcgUkVQcm9ncmFtKHJlMUluc3RydWN0aW9ucyk7Ci0gKiA8L3ByZT4KLSAqCi0gKiBZb3UgY2FuIHRoZW4gY29uc3RydWN0IGEgcmVndWxhciBleHByZXNzaW9uIG1hdGNoZXIgKFJFKSBvYmplY3QgZnJvbQotICogdGhlIHByZS1jb21waWxlZCBleHByZXNzaW9uIHJlMSBhbmQgdGh1cyBhdm9pZCB0aGUgb3ZlcmhlYWQgb2YKLSAqIGNvbXBpbGluZyB0aGUgZXhwcmVzc2lvbiBhdCBydW50aW1lLiBJZiB5b3UgcmVxdWlyZSBtb3JlIGR5bmFtaWMKLSAqIHJlZ3VsYXIgZXhwcmVzc2lvbnMsIHlvdSBjYW4gY29uc3RydWN0IGEgc2luZ2xlIFJFQ29tcGlsZXIgb2JqZWN0IGFuZAotICogcmUtdXNlIGl0IHRvIGNvbXBpbGUgZWFjaCBleHByZXNzaW9uLiBTaW1pbGFybHksIHlvdSBjYW4gY2hhbmdlIHRoZQotICogcHJvZ3JhbSBydW4gYnkgYSBnaXZlbiBtYXRjaGVyIG9iamVjdCBhdCBhbnkgdGltZS4gSG93ZXZlciwgUkUgYW5kCi0gKiBSRUNvbXBpbGVyIGFyZSBub3QgdGhyZWFkc2FmZSAoZm9yIGVmZmljaWVuY3kgcmVhc29ucywgYW5kIGJlY2F1c2UKLSAqIHJlcXVpcmluZyB0aHJlYWQgc2FmZXR5IGluIHRoaXMgY2xhc3MgaXMgZGVlbWVkIHRvIGJlIGEgcmFyZQotICogcmVxdWlyZW1lbnQpLCBzbyB5b3Ugd2lsbCBuZWVkIHRvIGNvbnN0cnVjdCBhIHNlcGFyYXRlIGNvbXBpbGVyIG9yCi0gKiBtYXRjaGVyIG9iamVjdCBmb3IgZWFjaCB0aHJlYWQgKHVubGVzcyB5b3UgZG8gdGhyZWFkIHN5bmNocm9uaXphdGlvbgotICogeW91cnNlbGYpLiBPbmNlIGV4cHJlc3Npb24gY29tcGlsZWQgaW50byB0aGUgUkVQcm9ncmFtIG9iamVjdCwgUkVQcm9ncmFtCi0gKiBjYW4gYmUgc2FmZWx5IHNoYXJlZCBhY3Jvc3MgbXVsdGlwbGUgdGhyZWFkcyBhbmQgUkUgb2JqZWN0cy4KLSAqCi0gKiA8YnI+PHA+PGJyPgotICoKLSAqIDxmb250IGNvbG9yPSJyZWQiPgotICogPGk+SVNTVUVTOjwvaT4KLSAqCi0gKiA8dWw+Ci0gKiAgPGxpPmNvbS53ZXVzb3Vycy51dGlsLnJlIGlzIG5vdCBjdXJyZW50bHkgY29tcGF0aWJsZSB3aXRoIGFsbAotICogICAgICBzdGFuZGFyZCBQT1NJWCByZWdjb21wIGZsYWdzPC9saT4KLSAqICA8bGk+Y29tLndldXNvdXJzLnV0aWwucmUgZG9lcyBub3Qgc3VwcG9ydCBQT1NJWCBlcXVpdmFsZW5jZSBjbGFzc2VzCi0gKiAgICAgIChbPWZvbz1dIHN5bnRheCkgKEkxOE4vbG9jYWxlIGlzc3VlKTwvbGk+Ci0gKiAgPGxpPmNvbS53ZXVzb3Vycy51dGlsLnJlIGRvZXMgbm90IHN1cHBvcnQgbmVzdGVkIFBPU0lYIGNoYXJhY3RlcgotICogICAgICBjbGFzc2VzIChkZWZpbml0ZWx5IHNob3VsZCwgYnV0IG5vdCBjb21wbGV0ZWx5IHRyaXZpYWwpPC9saT4KLSAqICA8bGk+Y29tLndldXNvdXJzLnV0aWwucmUgRG9lcyBub3Qgc3VwcG9ydCBQT1NJWCBjaGFyYWN0ZXIgY29sbGF0aW9uCi0gKiAgICAgIGNvbmNlcHRzIChbLmZvby5dIHN5bnRheCkgKEkxOE4vbG9jYWxlIGlzc3VlKTwvbGk+Ci0gKiAgPGxpPlNob3VsZCB0aGVyZSBiZSBkaWZmZXJlbnQgbWF0Y2hpbmcgc3R5bGVzIChzaW1wbGUsIFBPU0lYLCBQZXJsIGV0Yz8pPC9saT4KLSAqICA8bGk+U2hvdWxkIFJFIHN1cHBvcnQgY2hhcmFjdGVyIGl0ZXJhdG9ycyAoZm9yIGJhY2t3YXJkcyBSRSBtYXRjaGluZyEpPzwvbGk+Ci0gKiAgPGxpPlNob3VsZCBSRSBzdXBwb3J0IHJlbHVjdGFudCB7bSxufSBjbG9zdXJlcyAoZG9lcyBhbnlvbmUgY2FyZSk/PC9saT4KLSAqICA8bGk+Tm90ICphbGwqIHBvc3NpYmlsaXRpZXMgYXJlIGNvbnNpZGVyZWQgZm9yIGdyZWVkaW5lc3Mgd2hlbiBiYWNrcmVmZXJlbmNlcwotICogICAgICBhcmUgaW52b2x2ZWQgKGFzIFBPU0lYIHN1Z2dlc3RzIHNob3VsZCBiZSB0aGUgY2FzZSkuICBUaGUgUE9TSVggUkUKLSAqICAgICAgIihhYyopYypkW2FjXSpcMSIsIHdoZW4gbWF0Y2hlZCBhZ2FpbnN0ICJhY2RhY2FhIiBzaG91bGQgeWllbGQgYSBtYXRjaAotICogICAgICBvZiBhY2RhY2FhIHdoZXJlIFwxIGlzICJhIi4gIFRoaXMgaXMgbm90IHRoZSBjYXNlIGluIHRoaXMgUkUgcGFja2FnZSwKLSAqICAgICAgYW5kIGFjdHVhbGx5IFBlcmwgZG9lc24ndCBnbyB0byB0aGlzIGV4dGVudCBlaXRoZXIhICBVbnRpbCBzb21lb25lCi0gKiAgICAgIGFjdHVhbGx5IGNvbXBsYWlucyBhYm91dCB0aGlzLCBJJ20gbm90IHN1cmUgaXQncyB3b3J0aCAiZml4aW5nIi4KLSAqICAgICAgSWYgaXQgZXZlciBpcyBmaXhlZCwgdGVzdCAjMTM3IGluIFJFVGVzdC50eHQgc2hvdWxkIGJlIHVwZGF0ZWQuPC9saT4KLSAqIDwvdWw+Ci0gKgotICogPC9mb250PgotICoKLSAqIEBzZWUgcmVjb21waWxlCi0gKiBAc2VlIFJFQ29tcGlsZXIKLSAqCi0gKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzpqb25sQG11cHBldGxhYnMuY29tIj5Kb25hdGhhbiBMb2NrZTwvYT4KLSAqIEBhdXRob3IgPGEgaHJlZj0ibWFpbHRvOnRzQHNjaC1mZXIuZGUiPlRvYmlhcyBTY2gmYXVtbDtmZXI8L2E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBSRSBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZQotewotICAgIC8qKgotICAgICAqIFNwZWNpZmllcyBub3JtYWwsIGNhc2Utc2Vuc2l0aXZlIG1hdGNoaW5nIGJlaGF2aW91ci4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVRDSF9OT1JNQUwgICAgICAgICAgPSAweDAwMDA7Ci0KLSAgICAvKioKLSAgICAgKiBGbGFnIHRvIGluZGljYXRlIHRoYXQgbWF0Y2hpbmcgc2hvdWxkIGJlIGNhc2UtaW5kZXBlbmRlbnQgKGZvbGRlZCkKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVRDSF9DQVNFSU5ERVBFTkRFTlQgPSAweDAwMDE7Ci0KLSAgICAvKioKLSAgICAgKiBOZXdsaW5lcyBzaG91bGQgbWF0Y2ggYXMgQk9ML0VPTCAoXiBhbmQgJCkKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVRDSF9NVUxUSUxJTkUgICAgICAgPSAweDAwMDI7Ci0KLSAgICAvKioKLSAgICAgKiBDb25zaWRlciBhbGwgaW5wdXQgYSBzaW5nbGUgYm9keSBvZiB0ZXh0IC0gbmV3bGluZXMgYXJlIG1hdGNoZWQgYnkgLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BVENIX1NJTkdMRUxJTkUgICAgICA9IDB4MDAwNDsKLQotICAgIC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqCi0gICAgICogVGhlIGZvcm1hdCBvZiBhIG5vZGUgaW4gYSBwcm9ncmFtIGlzOiAgICAgICAgKgotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKLSAgICAgKiBbIE9QQ09ERSBdIFsgT1BEQVRBIF0gWyBPUE5FWFQgXSBbIE9QRVJBTkQgXSAqCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKgotICAgICAqIGNoYXIgT1BDT0RFIC0gaW5zdHJ1Y3Rpb24gICAgICAgICAgICAgICAgICAgICoKLSAgICAgKiBjaGFyIE9QREFUQSAtIG1vZGlmeWluZyBkYXRhICAgICAgICAgICAgICAgICAqCi0gICAgICogY2hhciBPUE5FWFQgLSBuZXh0IG5vZGUgKHJlbGF0aXZlIG9mZnNldCkgICAgKgotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKLSAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwotCi0gICAgICAgICAgICAgICAgIC8vICAgT3Bjb2RlICAgICAgICAgICAgICBDaGFyICAgICAgIE9wZGF0YS9PcGVyYW5kICBNZWFuaW5nCi0gICAgICAgICAgICAgICAgIC8vICAgLS0tLS0tLS0tLSAgICAgICAgICAtLS0tLS0tLS0tIC0tLS0tLS0tLS0tLS0tLSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgIHN0YXRpYyBmaW5hbCBjaGFyIE9QX0VORCAgICAgICAgICAgICAgPSAnRSc7ICAvLyAgICAgICAgICAgICAgICAgZW5kIG9mIHByb2dyYW0KLSAgICBzdGF0aWMgZmluYWwgY2hhciBPUF9CT0wgICAgICAgICAgICAgID0gJ14nOyAgLy8gICAgICAgICAgICAgICAgIG1hdGNoIG9ubHkgaWYgYXQgYmVnaW5uaW5nIG9mIGxpbmUKLSAgICBzdGF0aWMgZmluYWwgY2hhciBPUF9FT0wgICAgICAgICAgICAgID0gJyQnOyAgLy8gICAgICAgICAgICAgICAgIG1hdGNoIG9ubHkgaWYgYXQgZW5kIG9mIGxpbmUKLSAgICBzdGF0aWMgZmluYWwgY2hhciBPUF9BTlkgICAgICAgICAgICAgID0gJy4nOyAgLy8gICAgICAgICAgICAgICAgIG1hdGNoIGFueSBzaW5nbGUgY2hhcmFjdGVyIGV4Y2VwdCBuZXdsaW5lCi0gICAgc3RhdGljIGZpbmFsIGNoYXIgT1BfQU5ZT0YgICAgICAgICAgICA9ICdbJzsgIC8vIGNvdW50L3JhbmdlcyAgICBtYXRjaCBhbnkgY2hhciBpbiB0aGUgbGlzdCBvZiByYW5nZXMKLSAgICBzdGF0aWMgZmluYWwgY2hhciBPUF9CUkFOQ0ggICAgICAgICAgID0gJ3wnOyAgLy8gbm9kZSAgICAgICAgICAgIG1hdGNoIHRoaXMgYWx0ZXJuYXRpdmUgb3IgdGhlIG5leHQgb25lCi0gICAgc3RhdGljIGZpbmFsIGNoYXIgT1BfQVRPTSAgICAgICAgICAgICA9ICdBJzsgIC8vIGxlbmd0aC9zdHJpbmcgICBsZW5ndGggb2Ygc3RyaW5nIGZvbGxvd2VkIGJ5IHN0cmluZyBpdHNlbGYKLSAgICBzdGF0aWMgZmluYWwgY2hhciBPUF9TVEFSICAgICAgICAgICAgID0gJyonOyAgLy8gbm9kZSAgICAgICAgICAgIGtsZWVuZSBjbG9zdXJlCi0gICAgc3RhdGljIGZpbmFsIGNoYXIgT1BfUExVUyAgICAgICAgICAgICA9ICcrJzsgIC8vIG5vZGUgICAgICAgICAgICBwb3NpdGl2ZSBjbG9zdXJlCi0gICAgc3RhdGljIGZpbmFsIGNoYXIgT1BfTUFZQkUgICAgICAgICAgICA9ICc/JzsgIC8vIG5vZGUgICAgICAgICAgICBvcHRpb25hbCBjbG9zdXJlCi0gICAgc3RhdGljIGZpbmFsIGNoYXIgT1BfRVNDQVBFICAgICAgICAgICA9ICdcXCc7IC8vIGVzY2FwZSAgICAgICAgICBzcGVjaWFsIGVzY2FwZSBjb2RlIGNoYXIgY2xhc3MgKGVzY2FwZSBpcyBFXyogY29kZSkKLSAgICBzdGF0aWMgZmluYWwgY2hhciBPUF9PUEVOICAgICAgICAgICAgID0gJygnOyAgLy8gbnVtYmVyICAgICAgICAgIG50aCBvcGVuaW5nIHBhcmVuCi0gICAgc3RhdGljIGZpbmFsIGNoYXIgT1BfT1BFTl9DTFVTVEVSICAgICA9ICc8JzsgIC8vICAgICAgICAgICAgICAgICBvcGVuaW5nIGNsdXN0ZXIKLSAgICBzdGF0aWMgZmluYWwgY2hhciBPUF9DTE9TRSAgICAgICAgICAgID0gJyknOyAgLy8gbnVtYmVyICAgICAgICAgIG50aCBjbG9zaW5nIHBhcmVuCi0gICAgc3RhdGljIGZpbmFsIGNoYXIgT1BfQ0xPU0VfQ0xVU1RFUiAgICA9ICc+JzsgIC8vICAgICAgICAgICAgICAgICBjbG9zaW5nIGNsdXN0ZXIKLSAgICBzdGF0aWMgZmluYWwgY2hhciBPUF9CQUNLUkVGICAgICAgICAgID0gJyMnOyAgLy8gbnVtYmVyICAgICAgICAgIHJlZmVyZW5jZSBudGggYWxyZWFkeSBtYXRjaGVkIHBhcmVudGhlc2l6ZWQgc3RyaW5nCi0gICAgc3RhdGljIGZpbmFsIGNoYXIgT1BfR09UTyAgICAgICAgICAgICA9ICdHJzsgIC8vICAgICAgICAgICAgICAgICBub3RoaW5nIGJ1dCBhIChiYWNrLSlwb2ludGVyCi0gICAgc3RhdGljIGZpbmFsIGNoYXIgT1BfTk9USElORyAgICAgICAgICA9ICdOJzsgIC8vICAgICAgICAgICAgICAgICBtYXRjaCBudWxsIHN0cmluZyBzdWNoIGFzIGluICcoYXwpJwotICAgIHN0YXRpYyBmaW5hbCBjaGFyIE9QX1JFTFVDVEFOVFNUQVIgICAgPSAnOCc7ICAvLyBub25lL2V4cHIgICAgICAgcmVsdWN0YW50ICcqJyAobW5lbW9uaWMgZm9yIGNoYXIgaXMgdW5zaGlmdGVkICcqJykKLSAgICBzdGF0aWMgZmluYWwgY2hhciBPUF9SRUxVQ1RBTlRQTFVTICAgID0gJz0nOyAgLy8gbm9uZS9leHByICAgICAgIHJlbHVjdGFudCAnKycgKG1uZW1vbmljIGZvciBjaGFyIGlzIHVuc2hpZnRlZCAnKycpCi0gICAgc3RhdGljIGZpbmFsIGNoYXIgT1BfUkVMVUNUQU5UTUFZQkUgICA9ICcvJzsgIC8vIG5vbmUvZXhwciAgICAgICByZWx1Y3RhbnQgJz8nIChtbmVtb25pYyBmb3IgY2hhciBpcyB1bnNoaWZ0ZWQgJz8nKQotICAgIHN0YXRpYyBmaW5hbCBjaGFyIE9QX1BPU0lYQ0xBU1MgICAgICAgPSAnUCc7ICAvLyBjbGFzc2lkICAgICAgICAgb25lIG9mIHRoZSBwb3NpeCBjaGFyYWN0ZXIgY2xhc3NlcwotCi0gICAgLy8gRXNjYXBlIGNvZGVzCi0gICAgc3RhdGljIGZpbmFsIGNoYXIgRV9BTE5VTSAgICAgICAgICAgICA9ICd3JzsgIC8vIEFscGhhbnVtZXJpYwotICAgIHN0YXRpYyBmaW5hbCBjaGFyIEVfTkFMTlVNICAgICAgICAgICAgPSAnVyc7ICAvLyBOb24tYWxwaGFudW1lcmljCi0gICAgc3RhdGljIGZpbmFsIGNoYXIgRV9CT1VORCAgICAgICAgICAgICA9ICdiJzsgIC8vIFdvcmQgYm91bmRhcnkKLSAgICBzdGF0aWMgZmluYWwgY2hhciBFX05CT1VORCAgICAgICAgICAgID0gJ0InOyAgLy8gTm9uLXdvcmQgYm91bmRhcnkKLSAgICBzdGF0aWMgZmluYWwgY2hhciBFX1NQQUNFICAgICAgICAgICAgID0gJ3MnOyAgLy8gV2hpdGVzcGFjZQotICAgIHN0YXRpYyBmaW5hbCBjaGFyIEVfTlNQQUNFICAgICAgICAgICAgPSAnUyc7ICAvLyBOb24td2hpdGVzcGFjZQotICAgIHN0YXRpYyBmaW5hbCBjaGFyIEVfRElHSVQgICAgICAgICAgICAgPSAnZCc7ICAvLyBEaWdpdAotICAgIHN0YXRpYyBmaW5hbCBjaGFyIEVfTkRJR0lUICAgICAgICAgICAgPSAnRCc7ICAvLyBOb24tZGlnaXQKLQotICAgIC8vIFBvc2l4IGNoYXJhY3RlciBjbGFzc2VzCi0gICAgc3RhdGljIGZpbmFsIGNoYXIgUE9TSVhfQ0xBU1NfQUxOVU0gICA9ICd3JzsgIC8vIEFscGhhbnVtZXJpY3MKLSAgICBzdGF0aWMgZmluYWwgY2hhciBQT1NJWF9DTEFTU19BTFBIQSAgID0gJ2EnOyAgLy8gQWxwaGFiZXRpY3MKLSAgICBzdGF0aWMgZmluYWwgY2hhciBQT1NJWF9DTEFTU19CTEFOSyAgID0gJ2InOyAgLy8gQmxhbmtzCi0gICAgc3RhdGljIGZpbmFsIGNoYXIgUE9TSVhfQ0xBU1NfQ05UUkwgICA9ICdjJzsgIC8vIENvbnRyb2wgY2hhcmFjdGVycwotICAgIHN0YXRpYyBmaW5hbCBjaGFyIFBPU0lYX0NMQVNTX0RJR0lUICAgPSAnZCc7ICAvLyBEaWdpdHMKLSAgICBzdGF0aWMgZmluYWwgY2hhciBQT1NJWF9DTEFTU19HUkFQSCAgID0gJ2cnOyAgLy8gR3JhcGhpYyBjaGFyYWN0ZXJzCi0gICAgc3RhdGljIGZpbmFsIGNoYXIgUE9TSVhfQ0xBU1NfTE9XRVIgICA9ICdsJzsgIC8vIExvd2VyY2FzZSBjaGFyYWN0ZXJzCi0gICAgc3RhdGljIGZpbmFsIGNoYXIgUE9TSVhfQ0xBU1NfUFJJTlQgICA9ICdwJzsgIC8vIFByaW50YWJsZSBjaGFyYWN0ZXJzCi0gICAgc3RhdGljIGZpbmFsIGNoYXIgUE9TSVhfQ0xBU1NfUFVOQ1QgICA9ICchJzsgIC8vIFB1bmN0dWF0aW9uCi0gICAgc3RhdGljIGZpbmFsIGNoYXIgUE9TSVhfQ0xBU1NfU1BBQ0UgICA9ICdzJzsgIC8vIFNwYWNlcwotICAgIHN0YXRpYyBmaW5hbCBjaGFyIFBPU0lYX0NMQVNTX1VQUEVSICAgPSAndSc7ICAvLyBVcHBlcmNhc2UgY2hhcmFjdGVycwotICAgIHN0YXRpYyBmaW5hbCBjaGFyIFBPU0lYX0NMQVNTX1hESUdJVCAgPSAneCc7ICAvLyBIZXhhZGVjaW1hbCBkaWdpdHMKLSAgICBzdGF0aWMgZmluYWwgY2hhciBQT1NJWF9DTEFTU19KU1RBUlQgID0gJ2onOyAgLy8gSmF2YSBpZGVudGlmaWVyIHN0YXJ0Ci0gICAgc3RhdGljIGZpbmFsIGNoYXIgUE9TSVhfQ0xBU1NfSlBBUlQgICA9ICdrJzsgIC8vIEphdmEgaWRlbnRpZmllciBwYXJ0Ci0KLSAgICAvLyBMaW1pdHMKLSAgICBzdGF0aWMgZmluYWwgaW50IG1heE5vZGUgID0gNjU1MzY7ICAgICAgICAgICAgLy8gTWF4aW11bSBudW1iZXIgb2Ygbm9kZXMgaW4gYSBwcm9ncmFtCi0gICAgc3RhdGljIGZpbmFsIGludCBNQVhfUEFSRU4gPSAxNjsgICAgICAgICAgICAgIC8vIE51bWJlciBvZiBwYXJlbiBwYWlycyAob25seSA5IGNhbiBiZSBiYWNrcmVmcykKLQotICAgIC8vIE5vZGUgbGF5b3V0IGNvbnN0YW50cwotICAgIHN0YXRpYyBmaW5hbCBpbnQgb2Zmc2V0T3Bjb2RlID0gMDsgICAgICAgICAgICAvLyBPcGNvZGUgb2Zmc2V0IChmaXJzdCBjaGFyYWN0ZXIpCi0gICAgc3RhdGljIGZpbmFsIGludCBvZmZzZXRPcGRhdGEgPSAxOyAgICAgICAgICAgIC8vIE9wZGF0YSBvZmZzZXQgKHNlY29uZCBjaGFyKQotICAgIHN0YXRpYyBmaW5hbCBpbnQgb2Zmc2V0TmV4dCAgID0gMjsgICAgICAgICAgICAvLyBOZXh0IGluZGV4IG9mZnNldCAodGhpcmQgY2hhcikKLSAgICBzdGF0aWMgZmluYWwgaW50IG5vZGVTaXplICAgICA9IDM7ICAgICAgICAgICAgLy8gTm9kZSBzaXplIChpbiBjaGFycykKLQotICAgIC8vIFN0YXRlIG9mIGN1cnJlbnQgcHJvZ3JhbQotICAgIFJFUHJvZ3JhbSBwcm9ncmFtOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBDb21waWxlZCByZWd1bGFyIGV4cHJlc3Npb24gJ3Byb2dyYW0nCi0gICAgdHJhbnNpZW50IENoYXJhY3Rlckl0ZXJhdG9yIHNlYXJjaDsgICAgICAgICAgIC8vIFRoZSBzdHJpbmcgYmVpbmcgbWF0Y2hlZCBhZ2FpbnN0Ci0gICAgaW50IG1hdGNoRmxhZ3M7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE1hdGNoIGJlaGF2aW91ciBmbGFncwotICAgIGludCBtYXhQYXJlbiA9IE1BWF9QQVJFTjsKLQotICAgIC8vIFBhcmVudGhlc2l6ZWQgc3ViZXhwcmVzc2lvbnMKLSAgICB0cmFuc2llbnQgaW50IHBhcmVuQ291bnQ7ICAgICAgICAgICAgICAgICAgICAgLy8gTnVtYmVyIG9mIHN1YmV4cHJlc3Npb25zIG1hdGNoZWQgKG51bSBvcGVuIHBhcmVucyArIDEpCi0gICAgdHJhbnNpZW50IGludCBzdGFydDA7ICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENhY2hlIG9mIHN0YXJ0WzBdCi0gICAgdHJhbnNpZW50IGludCBlbmQwOyAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENhY2hlIG9mIHN0YXJ0WzBdCi0gICAgdHJhbnNpZW50IGludCBzdGFydDE7ICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENhY2hlIG9mIHN0YXJ0WzFdCi0gICAgdHJhbnNpZW50IGludCBlbmQxOyAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENhY2hlIG9mIHN0YXJ0WzFdCi0gICAgdHJhbnNpZW50IGludCBzdGFydDI7ICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENhY2hlIG9mIHN0YXJ0WzJdCi0gICAgdHJhbnNpZW50IGludCBlbmQyOyAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENhY2hlIG9mIHN0YXJ0WzJdCi0gICAgdHJhbnNpZW50IGludFtdIHN0YXJ0bjsgICAgICAgICAgICAgICAgICAgICAgIC8vIExhenktYWxsb2NlZCBhcnJheSBvZiBzdWItZXhwcmVzc2lvbiBzdGFydHMKLSAgICB0cmFuc2llbnQgaW50W10gZW5kbjsgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTGF6eS1hbGxvY2VkIGFycmF5IG9mIHN1Yi1leHByZXNzaW9uIGVuZHMKLQotICAgIC8vIEJhY2tyZWZlcmVuY2VzCi0gICAgdHJhbnNpZW50IGludFtdIHN0YXJ0QmFja3JlZjsgICAgICAgICAgICAgICAgIC8vIExhenktYWxsb2NlZCBhcnJheSBvZiBiYWNrcmVmIHN0YXJ0cwotICAgIHRyYW5zaWVudCBpbnRbXSBlbmRCYWNrcmVmOyAgICAgICAgICAgICAgICAgICAvLyBMYXp5LWFsbG9jZWQgYXJyYXkgb2YgYmFja3JlZiBlbmRzCi0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RzIGEgcmVndWxhciBleHByZXNzaW9uIG1hdGNoZXIgZnJvbSBhIFN0cmluZyBieSBjb21waWxpbmcgaXQKLSAgICAgKiB1c2luZyBhIG5ldyBpbnN0YW5jZSBvZiBSRUNvbXBpbGVyLiAgSWYgeW91IHdpbGwgYmUgY29tcGlsaW5nIG1hbnkKLSAgICAgKiBleHByZXNzaW9ucywgeW91IG1heSBwcmVmZXIgdG8gdXNlIGEgc2luZ2xlIFJFQ29tcGlsZXIgb2JqZWN0IGluc3RlYWQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcGF0dGVybiBUaGUgcmVndWxhciBleHByZXNzaW9uIHBhdHRlcm4gdG8gY29tcGlsZS4KLSAgICAgKiBAZXhjZXB0aW9uIFJFU3ludGF4RXhjZXB0aW9uIFRocm93biBpZiB0aGUgcmVndWxhciBleHByZXNzaW9uIGhhcyBpbnZhbGlkIHN5bnRheC4KLSAgICAgKiBAc2VlIFJFQ29tcGlsZXIKLSAgICAgKiBAc2VlIHJlY29tcGlsZQotICAgICAqLwotICAgIHB1YmxpYyBSRShTdHJpbmcgcGF0dGVybikgdGhyb3dzIFJFU3ludGF4RXhjZXB0aW9uCi0gICAgewotICAgICAgICB0aGlzKHBhdHRlcm4sIE1BVENIX05PUk1BTCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0cyBhIHJlZ3VsYXIgZXhwcmVzc2lvbiBtYXRjaGVyIGZyb20gYSBTdHJpbmcgYnkgY29tcGlsaW5nIGl0Ci0gICAgICogdXNpbmcgYSBuZXcgaW5zdGFuY2Ugb2YgUkVDb21waWxlci4gIElmIHlvdSB3aWxsIGJlIGNvbXBpbGluZyBtYW55Ci0gICAgICogZXhwcmVzc2lvbnMsIHlvdSBtYXkgcHJlZmVyIHRvIHVzZSBhIHNpbmdsZSBSRUNvbXBpbGVyIG9iamVjdCBpbnN0ZWFkLgotICAgICAqCi0gICAgICogQHBhcmFtIHBhdHRlcm4gVGhlIHJlZ3VsYXIgZXhwcmVzc2lvbiBwYXR0ZXJuIHRvIGNvbXBpbGUuCi0gICAgICogQHBhcmFtIG1hdGNoRmxhZ3MgVGhlIG1hdGNoaW5nIHN0eWxlCi0gICAgICogQGV4Y2VwdGlvbiBSRVN5bnRheEV4Y2VwdGlvbiBUaHJvd24gaWYgdGhlIHJlZ3VsYXIgZXhwcmVzc2lvbiBoYXMgaW52YWxpZCBzeW50YXguCi0gICAgICogQHNlZSBSRUNvbXBpbGVyCi0gICAgICogQHNlZSByZWNvbXBpbGUKLSAgICAgKi8KLSAgICBwdWJsaWMgUkUoU3RyaW5nIHBhdHRlcm4sIGludCBtYXRjaEZsYWdzKSB0aHJvd3MgUkVTeW50YXhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIHRoaXMobmV3IFJFQ29tcGlsZXIoKS5jb21waWxlKHBhdHRlcm4pKTsKLSAgICAgICAgc2V0TWF0Y2hGbGFncyhtYXRjaEZsYWdzKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3QgYSBtYXRjaGVyIGZvciBhIHByZS1jb21waWxlZCByZWd1bGFyIGV4cHJlc3Npb24gZnJvbSBwcm9ncmFtCi0gICAgICogKGJ5dGVjb2RlKSBkYXRhLiAgUGVybWl0cyBzcGVjaWFsIGZsYWdzIHRvIGJlIHBhc3NlZCBpbiB0byBtb2RpZnkgbWF0Y2hpbmcKLSAgICAgKiBiZWhhdmlvdXIuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcHJvZ3JhbSBDb21waWxlZCByZWd1bGFyIGV4cHJlc3Npb24gcHJvZ3JhbSAoc2VlIFJFQ29tcGlsZXIgYW5kL29yIHJlY29tcGlsZSkKLSAgICAgKiBAcGFyYW0gbWF0Y2hGbGFncyBPbmUgb3IgbW9yZSBvZiB0aGUgUkUgbWF0Y2ggYmVoYXZpb3VyIGZsYWdzIChSRS5NQVRDSF8qKToKLSAgICAgKgotICAgICAqIDxwcmU+Ci0gICAgICogICBNQVRDSF9OT1JNQUwgICAgICAgICAgICAgIC8vIE5vcm1hbCAoY2FzZS1zZW5zaXRpdmUpIG1hdGNoaW5nCi0gICAgICogICBNQVRDSF9DQVNFSU5ERVBFTkRFTlQgICAgIC8vIENhc2UgZm9sZGVkIGNvbXBhcmlzb25zCi0gICAgICogICBNQVRDSF9NVUxUSUxJTkUgICAgICAgICAgIC8vIE5ld2xpbmUgbWF0Y2hlcyBhcyBCT0wvRU9MCi0gICAgICogPC9wcmU+Ci0gICAgICoKLSAgICAgKiBAc2VlIFJFQ29tcGlsZXIKLSAgICAgKiBAc2VlIFJFUHJvZ3JhbQotICAgICAqIEBzZWUgcmVjb21waWxlCi0gICAgICovCi0gICAgcHVibGljIFJFKFJFUHJvZ3JhbSBwcm9ncmFtLCBpbnQgbWF0Y2hGbGFncykKLSAgICB7Ci0gICAgICAgIHNldFByb2dyYW0ocHJvZ3JhbSk7Ci0gICAgICAgIHNldE1hdGNoRmxhZ3MobWF0Y2hGbGFncyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0IGEgbWF0Y2hlciBmb3IgYSBwcmUtY29tcGlsZWQgcmVndWxhciBleHByZXNzaW9uIGZyb20gcHJvZ3JhbQotICAgICAqIChieXRlY29kZSkgZGF0YS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBwcm9ncmFtIENvbXBpbGVkIHJlZ3VsYXIgZXhwcmVzc2lvbiBwcm9ncmFtCi0gICAgICogQHNlZSBSRUNvbXBpbGVyCi0gICAgICogQHNlZSByZWNvbXBpbGUKLSAgICAgKi8KLSAgICBwdWJsaWMgUkUoUkVQcm9ncmFtIHByb2dyYW0pCi0gICAgewotICAgICAgICB0aGlzKHByb2dyYW0sIE1BVENIX05PUk1BTCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0cyBhIHJlZ3VsYXIgZXhwcmVzc2lvbiBtYXRjaGVyIHdpdGggbm8gaW5pdGlhbCBwcm9ncmFtLgotICAgICAqIFRoaXMgaXMgbGlrZWx5IHRvIGJlIGFuIHVuY29tbW9uIHByYWN0aWNlLCBidXQgaXMgc3RpbGwgc3VwcG9ydGVkLgotICAgICAqLwotICAgIHB1YmxpYyBSRSgpCi0gICAgewotICAgICAgICB0aGlzKChSRVByb2dyYW0pbnVsbCwgTUFUQ0hfTk9STUFMKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb252ZXJ0cyBhICdzaW1wbGlmaWVkJyByZWd1bGFyIGV4cHJlc3Npb24gdG8gYSBmdWxsIHJlZ3VsYXIgZXhwcmVzc2lvbgotICAgICAqCi0gICAgICogQHBhcmFtIHBhdHRlcm4gVGhlIHBhdHRlcm4gdG8gY29udmVydAotICAgICAqIEByZXR1cm4gVGhlIGZ1bGwgcmVndWxhciBleHByZXNzaW9uCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBTdHJpbmcgc2ltcGxlUGF0dGVyblRvRnVsbFJlZ3VsYXJFeHByZXNzaW9uKFN0cmluZyBwYXR0ZXJuKQotICAgIHsKLSAgICAgICAgU3RyaW5nQnVmZmVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYXR0ZXJuLmxlbmd0aCgpOyBpKyspCi0gICAgICAgIHsKLSAgICAgICAgICAgIGNoYXIgYyA9IHBhdHRlcm4uY2hhckF0KGkpOwotICAgICAgICAgICAgc3dpdGNoIChjKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIGNhc2UgJyonOgotICAgICAgICAgICAgICAgICAgICBidWYuYXBwZW5kKCIuKiIpOwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLQotICAgICAgICAgICAgICAgIGNhc2UgJy4nOgotICAgICAgICAgICAgICAgIGNhc2UgJ1snOgotICAgICAgICAgICAgICAgIGNhc2UgJ10nOgotICAgICAgICAgICAgICAgIGNhc2UgJ1xcJzoKLSAgICAgICAgICAgICAgICBjYXNlICcrJzoKLSAgICAgICAgICAgICAgICBjYXNlICc/JzoKLSAgICAgICAgICAgICAgICBjYXNlICd7JzoKLSAgICAgICAgICAgICAgICBjYXNlICd9JzoKLSAgICAgICAgICAgICAgICBjYXNlICckJzoKLSAgICAgICAgICAgICAgICBjYXNlICdeJzoKLSAgICAgICAgICAgICAgICBjYXNlICd8JzoKLSAgICAgICAgICAgICAgICBjYXNlICcoJzoKLSAgICAgICAgICAgICAgICBjYXNlICcpJzoKLSAgICAgICAgICAgICAgICAgICAgYnVmLmFwcGVuZCgnXFwnKTsKLSAgICAgICAgICAgICAgICBkZWZhdWx0OgotICAgICAgICAgICAgICAgICAgICBidWYuYXBwZW5kKGMpOwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gYnVmLnRvU3RyaW5nKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0cyBtYXRjaCBiZWhhdmlvdXIgZmxhZ3Mgd2hpY2ggYWx0ZXIgdGhlIHdheSBSRSBkb2VzIG1hdGNoaW5nLgotICAgICAqIEBwYXJhbSBtYXRjaEZsYWdzIE9uZSBvciBtb3JlIG9mIHRoZSBSRSBtYXRjaCBiZWhhdmlvdXIgZmxhZ3MgKFJFLk1BVENIXyopOgotICAgICAqCi0gICAgICogPHByZT4KLSAgICAgKiAgIE1BVENIX05PUk1BTCAgICAgICAgICAgICAgLy8gTm9ybWFsIChjYXNlLXNlbnNpdGl2ZSkgbWF0Y2hpbmcKLSAgICAgKiAgIE1BVENIX0NBU0VJTkRFUEVOREVOVCAgICAgLy8gQ2FzZSBmb2xkZWQgY29tcGFyaXNvbnMKLSAgICAgKiAgIE1BVENIX01VTFRJTElORSAgICAgICAgICAgLy8gTmV3bGluZSBtYXRjaGVzIGFzIEJPTC9FT0wKLSAgICAgKiA8L3ByZT4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRNYXRjaEZsYWdzKGludCBtYXRjaEZsYWdzKQotICAgIHsKLSAgICAgICAgdGhpcy5tYXRjaEZsYWdzID0gbWF0Y2hGbGFnczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IG1hdGNoIGJlaGF2aW91ciBmbGFncy4KLSAgICAgKiBAcmV0dXJuIEN1cnJlbnQgbWF0Y2ggYmVoYXZpb3VyIGZsYWdzIChSRS5NQVRDSF8qKS4KLSAgICAgKgotICAgICAqIDxwcmU+Ci0gICAgICogICBNQVRDSF9OT1JNQUwgICAgICAgICAgICAgIC8vIE5vcm1hbCAoY2FzZS1zZW5zaXRpdmUpIG1hdGNoaW5nCi0gICAgICogICBNQVRDSF9DQVNFSU5ERVBFTkRFTlQgICAgIC8vIENhc2UgZm9sZGVkIGNvbXBhcmlzb25zCi0gICAgICogICBNQVRDSF9NVUxUSUxJTkUgICAgICAgICAgIC8vIE5ld2xpbmUgbWF0Y2hlcyBhcyBCT0wvRU9MCi0gICAgICogPC9wcmU+Ci0gICAgICoKLSAgICAgKiBAc2VlICNzZXRNYXRjaEZsYWdzCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRNYXRjaEZsYWdzKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBtYXRjaEZsYWdzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIGN1cnJlbnQgcmVndWxhciBleHByZXNzaW9uIHByb2dyYW0gdXNlZCBieSB0aGlzIG1hdGNoZXIgb2JqZWN0LgotICAgICAqCi0gICAgICogQHBhcmFtIHByb2dyYW0gUmVndWxhciBleHByZXNzaW9uIHByb2dyYW0gY29tcGlsZWQgYnkgUkVDb21waWxlci4KLSAgICAgKiBAc2VlIFJFQ29tcGlsZXIKLSAgICAgKiBAc2VlIFJFUHJvZ3JhbQotICAgICAqIEBzZWUgcmVjb21waWxlCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0UHJvZ3JhbShSRVByb2dyYW0gcHJvZ3JhbSkKLSAgICB7Ci0gICAgICAgIHRoaXMucHJvZ3JhbSA9IHByb2dyYW07Ci0gICAgICAgIGlmIChwcm9ncmFtICE9IG51bGwgJiYgcHJvZ3JhbS5tYXhQYXJlbnMgIT0gLTEpIHsKLSAgICAgICAgICAgIHRoaXMubWF4UGFyZW4gPSBwcm9ncmFtLm1heFBhcmVuczsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIHRoaXMubWF4UGFyZW4gPSBNQVhfUEFSRU47Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IHJlZ3VsYXIgZXhwcmVzc2lvbiBwcm9ncmFtIGluIHVzZSBieSB0aGlzIG1hdGNoZXIgb2JqZWN0LgotICAgICAqCi0gICAgICogQHJldHVybiBSZWd1bGFyIGV4cHJlc3Npb24gcHJvZ3JhbQotICAgICAqIEBzZWUgI3NldFByb2dyYW0KLSAgICAgKi8KLSAgICBwdWJsaWMgUkVQcm9ncmFtIGdldFByb2dyYW0oKQotICAgIHsKLSAgICAgICAgcmV0dXJuIHByb2dyYW07Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIHBhcmVudGhlc2l6ZWQgc3ViZXhwcmVzc2lvbnMgYXZhaWxhYmxlIGFmdGVyIGEgc3VjY2Vzc2Z1bCBtYXRjaC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gTnVtYmVyIG9mIGF2YWlsYWJsZSBwYXJlbnRoZXNpemVkIHN1YmV4cHJlc3Npb25zCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRQYXJlbkNvdW50KCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBwYXJlbkNvdW50OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldHMgdGhlIGNvbnRlbnRzIG9mIGEgcGFyZW50aGVzaXplZCBzdWJleHByZXNzaW9uIGFmdGVyIGEgc3VjY2Vzc2Z1bCBtYXRjaC4KLSAgICAgKgotICAgICAqIEBwYXJhbSB3aGljaCBOZXN0aW5nIGxldmVsIG9mIHN1YmV4cHJlc3Npb24KLSAgICAgKiBAcmV0dXJuIFN0cmluZwotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0UGFyZW4oaW50IHdoaWNoKQotICAgIHsKLSAgICAgICAgaW50IHN0YXJ0OwotICAgICAgICBpZiAod2hpY2ggPCBwYXJlbkNvdW50ICYmIChzdGFydCA9IGdldFBhcmVuU3RhcnQod2hpY2gpKSA+PSAwKQotICAgICAgICB7Ci0gICAgICAgICAgICByZXR1cm4gc2VhcmNoLnN1YnN0cmluZyhzdGFydCwgZ2V0UGFyZW5FbmQod2hpY2gpKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBzdGFydCBpbmRleCBvZiBhIGdpdmVuIHBhcmVuIGxldmVsLgotICAgICAqCi0gICAgICogQHBhcmFtIHdoaWNoIE5lc3RpbmcgbGV2ZWwgb2Ygc3ViZXhwcmVzc2lvbgotICAgICAqIEByZXR1cm4gU3RyaW5nIGluZGV4Ci0gICAgICovCi0gICAgcHVibGljIGZpbmFsIGludCBnZXRQYXJlblN0YXJ0KGludCB3aGljaCkKLSAgICB7Ci0gICAgICAgIGlmICh3aGljaCA8IHBhcmVuQ291bnQpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHN3aXRjaCAod2hpY2gpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgY2FzZSAwOgotICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3RhcnQwOwotCi0gICAgICAgICAgICAgICAgY2FzZSAxOgotICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3RhcnQxOwotCi0gICAgICAgICAgICAgICAgY2FzZSAyOgotICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3RhcnQyOwotCi0gICAgICAgICAgICAgICAgZGVmYXVsdDoKLSAgICAgICAgICAgICAgICAgICAgaWYgKHN0YXJ0biA9PSBudWxsKQotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBhbGxvY1BhcmVucygpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBzdGFydG5bd2hpY2hdOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiAtMTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBlbmQgaW5kZXggb2YgYSBnaXZlbiBwYXJlbiBsZXZlbC4KLSAgICAgKgotICAgICAqIEBwYXJhbSB3aGljaCBOZXN0aW5nIGxldmVsIG9mIHN1YmV4cHJlc3Npb24KLSAgICAgKiBAcmV0dXJuIFN0cmluZyBpbmRleAotICAgICAqLwotICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0UGFyZW5FbmQoaW50IHdoaWNoKQotICAgIHsKLSAgICAgICAgaWYgKHdoaWNoIDwgcGFyZW5Db3VudCkKLSAgICAgICAgewotICAgICAgICAgICAgc3dpdGNoICh3aGljaCkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBjYXNlIDA6Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBlbmQwOwotCi0gICAgICAgICAgICAgICAgY2FzZSAxOgotICAgICAgICAgICAgICAgICAgICByZXR1cm4gZW5kMTsKLQotICAgICAgICAgICAgICAgIGNhc2UgMjoKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVuZDI7Ci0KLSAgICAgICAgICAgICAgICBkZWZhdWx0OgotICAgICAgICAgICAgICAgICAgICBpZiAoZW5kbiA9PSBudWxsKQotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBhbGxvY1BhcmVucygpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBlbmRuW3doaWNoXTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gLTE7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgbGVuZ3RoIG9mIGEgZ2l2ZW4gcGFyZW4gbGV2ZWwuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gd2hpY2ggTmVzdGluZyBsZXZlbCBvZiBzdWJleHByZXNzaW9uCi0gICAgICogQHJldHVybiBOdW1iZXIgb2YgY2hhcmFjdGVycyBpbiB0aGUgcGFyZW50aGVzaXplZCBzdWJleHByZXNzaW9uCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIGludCBnZXRQYXJlbkxlbmd0aChpbnQgd2hpY2gpCi0gICAgewotICAgICAgICBpZiAod2hpY2ggPCBwYXJlbkNvdW50KQotICAgICAgICB7Ci0gICAgICAgICAgICByZXR1cm4gZ2V0UGFyZW5FbmQod2hpY2gpIC0gZ2V0UGFyZW5TdGFydCh3aGljaCk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIC0xOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIHN0YXJ0IG9mIGEgcGFyZW4gbGV2ZWwKLSAgICAgKgotICAgICAqIEBwYXJhbSB3aGljaCBXaGljaCBwYXJlbiBsZXZlbAotICAgICAqIEBwYXJhbSBpIEluZGV4IGluIGlucHV0IGFycmF5Ci0gICAgICovCi0gICAgcHJvdGVjdGVkIGZpbmFsIHZvaWQgc2V0UGFyZW5TdGFydChpbnQgd2hpY2gsIGludCBpKQotICAgIHsKLSAgICAgICAgaWYgKHdoaWNoIDwgcGFyZW5Db3VudCkKLSAgICAgICAgewotICAgICAgICAgICAgc3dpdGNoICh3aGljaCkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBjYXNlIDA6Ci0gICAgICAgICAgICAgICAgICAgIHN0YXJ0MCA9IGk7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgICAgICAgICAgY2FzZSAxOgotICAgICAgICAgICAgICAgICAgICBzdGFydDEgPSBpOwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLQotICAgICAgICAgICAgICAgIGNhc2UgMjoKLSAgICAgICAgICAgICAgICAgICAgc3RhcnQyID0gaTsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgICAgICAgICBkZWZhdWx0OgotICAgICAgICAgICAgICAgICAgICBpZiAoc3RhcnRuID09IG51bGwpCi0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGFsbG9jUGFyZW5zKCk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgc3RhcnRuW3doaWNoXSA9IGk7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0cyB0aGUgZW5kIG9mIGEgcGFyZW4gbGV2ZWwKLSAgICAgKgotICAgICAqIEBwYXJhbSB3aGljaCBXaGljaCBwYXJlbiBsZXZlbAotICAgICAqIEBwYXJhbSBpIEluZGV4IGluIGlucHV0IGFycmF5Ci0gICAgICovCi0gICAgcHJvdGVjdGVkIGZpbmFsIHZvaWQgc2V0UGFyZW5FbmQoaW50IHdoaWNoLCBpbnQgaSkKLSAgICB7Ci0gICAgICAgIGlmICh3aGljaCA8IHBhcmVuQ291bnQpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHN3aXRjaCAod2hpY2gpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgY2FzZSAwOgotICAgICAgICAgICAgICAgICAgICBlbmQwID0gaTsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgICAgICAgICBjYXNlIDE6Ci0gICAgICAgICAgICAgICAgICAgIGVuZDEgPSBpOwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLQotICAgICAgICAgICAgICAgIGNhc2UgMjoKLSAgICAgICAgICAgICAgICAgICAgZW5kMiA9IGk7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgICAgICAgICAgZGVmYXVsdDoKLSAgICAgICAgICAgICAgICAgICAgaWYgKGVuZG4gPT0gbnVsbCkKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgYWxsb2NQYXJlbnMoKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbmRuW3doaWNoXSA9IGk7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhyb3dzIGFuIEVycm9yIHJlcHJlc2VudGluZyBhbiBpbnRlcm5hbCBlcnJvciBjb25kaXRpb24gcHJvYmFibHkgcmVzdWx0aW5nCi0gICAgICogZnJvbSBhIGJ1ZyBpbiB0aGUgcmVndWxhciBleHByZXNzaW9uIGNvbXBpbGVyIChvciBwb3NzaWJseSBkYXRhIGNvcnJ1cHRpb24pLgotICAgICAqIEluIHByYWN0aWNlLCB0aGlzIHNob3VsZCBiZSB2ZXJ5IHJhcmUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcyBFcnJvciBkZXNjcmlwdGlvbgotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIGludGVybmFsRXJyb3IoU3RyaW5nIHMpIHRocm93cyBFcnJvcgotICAgIHsKLSAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJSRSBpbnRlcm5hbCBlcnJvcjogIiArIHMpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFBlcmZvcm1zIGxhenkgYWxsb2NhdGlvbiBvZiBzdWJleHByZXNzaW9uIGFycmF5cwotICAgICAqLwotICAgIHByaXZhdGUgZmluYWwgdm9pZCBhbGxvY1BhcmVucygpCi0gICAgewotICAgICAgICAvLyBBbGxvY2F0ZSBhcnJheXMgZm9yIHN1YmV4cHJlc3Npb25zCi0gICAgICAgIHN0YXJ0biA9IG5ldyBpbnRbbWF4UGFyZW5dOwotICAgICAgICBlbmRuID0gbmV3IGludFttYXhQYXJlbl07Ci0KLSAgICAgICAgLy8gU2V0IHN1Yi1leHByZXNzaW9uIHBvaW50ZXJzIHRvIGludmFsaWQgdmFsdWVzCi0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbWF4UGFyZW47IGkrKykKLSAgICAgICAgewotICAgICAgICAgICAgc3RhcnRuW2ldID0gLTE7Ci0gICAgICAgICAgICBlbmRuW2ldID0gLTE7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcnkgdG8gbWF0Y2ggYSBzdHJpbmcgYWdhaW5zdCBhIHN1YnNldCBvZiBub2RlcyBpbiB0aGUgcHJvZ3JhbQotICAgICAqCi0gICAgICogQHBhcmFtIGZpcnN0Tm9kZSBOb2RlIHRvIHN0YXJ0IGF0IGluIHByb2dyYW0KLSAgICAgKiBAcGFyYW0gbGFzdE5vZGUgIExhc3QgdmFsaWQgbm9kZSAodXNlZCBmb3IgbWF0Y2hpbmcgYSBzdWJleHByZXNzaW9uIHdpdGhvdXQKLSAgICAgKiAgICAgICAgICAgICAgICAgIG1hdGNoaW5nIHRoZSByZXN0IG9mIHRoZSBwcm9ncmFtIGFzIHdlbGwpLgotICAgICAqIEBwYXJhbSBpZHhTdGFydCAgU3RhcnRpbmcgcG9zaXRpb24gaW4gY2hhcmFjdGVyIGFycmF5Ci0gICAgICogQHJldHVybiBGaW5hbCBpbnB1dCBhcnJheSBpbmRleCBpZiBtYXRjaCBzdWNjZWVkZWQuICAtMSBpZiBub3QuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGludCBtYXRjaE5vZGVzKGludCBmaXJzdE5vZGUsIGludCBsYXN0Tm9kZSwgaW50IGlkeFN0YXJ0KQotICAgIHsKLSAgICAgICAgLy8gT3VyIGN1cnJlbnQgcGxhY2UgaW4gdGhlIHN0cmluZwotICAgICAgICBpbnQgaWR4ID0gaWR4U3RhcnQ7Ci0KLSAgICAgICAgLy8gTG9vcCB3aGlsZSBub2RlIGlzIHZhbGlkCi0gICAgICAgIGludCBuZXh0LCBvcGNvZGUsIG9wZGF0YTsKLSAgICAgICAgaW50IGlkeE5ldzsKLSAgICAgICAgY2hhcltdIGluc3RydWN0aW9uID0gcHJvZ3JhbS5pbnN0cnVjdGlvbjsKLSAgICAgICAgZm9yIChpbnQgbm9kZSA9IGZpcnN0Tm9kZTsgbm9kZSA8IGxhc3ROb2RlOyApCi0gICAgICAgIHsKLSAgICAgICAgICAgIG9wY29kZSA9IGluc3RydWN0aW9uW25vZGUgKyBvZmZzZXRPcGNvZGVdOwotICAgICAgICAgICAgbmV4dCAgID0gbm9kZSArIChzaG9ydClpbnN0cnVjdGlvbltub2RlICsgb2Zmc2V0TmV4dF07Ci0gICAgICAgICAgICBvcGRhdGEgPSBpbnN0cnVjdGlvbltub2RlICsgb2Zmc2V0T3BkYXRhXTsKLQotICAgICAgICAgICAgc3dpdGNoIChvcGNvZGUpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgY2FzZSBPUF9SRUxVQ1RBTlRNQVlCRToKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgaW50IG9uY2UgPSAwOwotICAgICAgICAgICAgICAgICAgICAgICAgZG8KLSAgICAgICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUcnkgdG8gbWF0Y2ggdGhlIHJlc3Qgd2l0aG91dCB1c2luZyB0aGUgcmVsdWN0YW50IHN1YmV4cHIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoKGlkeE5ldyA9IG1hdGNoTm9kZXMobmV4dCwgbWF4Tm9kZSwgaWR4KSkgIT0gLTEpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaWR4TmV3OwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlICgob25jZSsrID09IDApICYmIChpZHggPSBtYXRjaE5vZGVzKG5vZGUgKyBub2RlU2l6ZSwgbmV4dCwgaWR4KSkgIT0gLTEpOwotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xOwotICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBjYXNlIE9QX1JFTFVDVEFOVFBMVVM6Ci0gICAgICAgICAgICAgICAgICAgIHdoaWxlICgoaWR4ID0gbWF0Y2hOb2Rlcyhub2RlICsgbm9kZVNpemUsIG5leHQsIGlkeCkpICE9IC0xKQotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBUcnkgdG8gbWF0Y2ggdGhlIHJlc3Qgd2l0aG91dCB1c2luZyB0aGUgcmVsdWN0YW50IHN1YmV4cHIKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoaWR4TmV3ID0gbWF0Y2hOb2RlcyhuZXh0LCBtYXhOb2RlLCBpZHgpKSAhPSAtMSkKLSAgICAgICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaWR4TmV3OwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiAtMTsKLQotICAgICAgICAgICAgICAgIGNhc2UgT1BfUkVMVUNUQU5UU1RBUjoKLSAgICAgICAgICAgICAgICAgICAgZG8KLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gVHJ5IHRvIG1hdGNoIHRoZSByZXN0IHdpdGhvdXQgdXNpbmcgdGhlIHJlbHVjdGFudCBzdWJleHByCi0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoKGlkeE5ldyA9IG1hdGNoTm9kZXMobmV4dCwgbWF4Tm9kZSwgaWR4KSkgIT0gLTEpCi0gICAgICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGlkeE5ldzsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB3aGlsZSAoKGlkeCA9IG1hdGNoTm9kZXMobm9kZSArIG5vZGVTaXplLCBuZXh0LCBpZHgpKSAhPSAtMSk7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiAtMTsKLQotICAgICAgICAgICAgICAgIGNhc2UgT1BfT1BFTjoKLQotICAgICAgICAgICAgICAgICAgICAvLyBNYXRjaCBzdWJleHByZXNzaW9uCi0gICAgICAgICAgICAgICAgICAgIGlmICgocHJvZ3JhbS5mbGFncyAmIFJFUHJvZ3JhbS5PUFRfSEFTQkFDS1JFRlMpICE9IDApCi0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0QmFja3JlZltvcGRhdGFdID0gaWR4OwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGlmICgoaWR4TmV3ID0gbWF0Y2hOb2RlcyhuZXh0LCBtYXhOb2RlLCBpZHgpKSAhPSAtMSkKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gSW5jcmVhc2UgdmFsaWQgcGFyZW4gY291bnQKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmICgob3BkYXRhICsgMSkgPiBwYXJlbkNvdW50KQotICAgICAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVuQ291bnQgPSBvcGRhdGEgKyAxOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBEb24ndCBzZXQgcGFyZW4gaWYgYWxyZWFkeSBzZXQgbGF0ZXIgb24KLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChnZXRQYXJlblN0YXJ0KG9wZGF0YSkgPT0gLTEpCi0gICAgICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0UGFyZW5TdGFydChvcGRhdGEsIGlkeCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGlkeE5ldzsKLQotICAgICAgICAgICAgICAgIGNhc2UgT1BfQ0xPU0U6Ci0KLSAgICAgICAgICAgICAgICAgICAgLy8gRG9uZSBtYXRjaGluZyBzdWJleHByZXNzaW9uCi0gICAgICAgICAgICAgICAgICAgIGlmICgocHJvZ3JhbS5mbGFncyAmIFJFUHJvZ3JhbS5PUFRfSEFTQkFDS1JFRlMpICE9IDApCi0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGVuZEJhY2tyZWZbb3BkYXRhXSA9IGlkeDsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBpZiAoKGlkeE5ldyA9IG1hdGNoTm9kZXMobmV4dCwgbWF4Tm9kZSwgaWR4KSkgIT0gLTEpCi0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIEluY3JlYXNlIHZhbGlkIHBhcmVuIGNvdW50Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoKG9wZGF0YSArIDEpID4gcGFyZW5Db3VudCkKLSAgICAgICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJlbkNvdW50ID0gb3BkYXRhICsgMTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gRG9uJ3Qgc2V0IHBhcmVuIGlmIGFscmVhZHkgc2V0IGxhdGVyIG9uCi0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZ2V0UGFyZW5FbmQob3BkYXRhKSA9PSAtMSkKLSAgICAgICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRQYXJlbkVuZChvcGRhdGEsIGlkeCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGlkeE5ldzsKLQotICAgICAgICAgICAgICAgIGNhc2UgT1BfT1BFTl9DTFVTVEVSOgotICAgICAgICAgICAgICAgIGNhc2UgT1BfQ0xPU0VfQ0xVU1RFUjoKLSAgICAgICAgICAgICAgICAgICAgLy8gc3RhcnRpbmcgb3IgZW5kaW5nIHRoZSBtYXRjaGluZyBvZiBhIHN1YmV4cHJlc3Npb24gd2hpY2ggaGFzIG5vIGJhY2tyZWYuCi0gICAgICAgICAgICAgICAgICAgIHJldHVybiBtYXRjaE5vZGVzKCBuZXh0LCBtYXhOb2RlLCBpZHggKTsKLQotICAgICAgICAgICAgICAgIGNhc2UgT1BfQkFDS1JFRjoKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gR2V0IHRoZSBzdGFydCBhbmQgZW5kIG9mIHRoZSBiYWNrcmVmCi0gICAgICAgICAgICAgICAgICAgICAgICBpbnQgcyA9IHN0YXJ0QmFja3JlZltvcGRhdGFdOwotICAgICAgICAgICAgICAgICAgICAgICAgaW50IGUgPSBlbmRCYWNrcmVmW29wZGF0YV07Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdlIGRvbid0IGtub3cgdGhlIGJhY2tyZWYgeWV0Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAocyA9PSAtMSB8fCBlID09IC0xKQotICAgICAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAtMTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhlIGJhY2tyZWYgaXMgZW1wdHkgc2l6ZQotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHMgPT0gZSkKLSAgICAgICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gR2V0IHRoZSBsZW5ndGggb2YgdGhlIGJhY2tyZWYKLSAgICAgICAgICAgICAgICAgICAgICAgIGludCBsID0gZSAtIHM7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIElmIHRoZXJlJ3Mgbm90IGVub3VnaCBpbnB1dCBsZWZ0LCBnaXZlIHVwLgotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNlYXJjaC5pc0VuZChpZHggKyBsIC0gMSkpCi0gICAgICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBDYXNlIGZvbGQgdGhlIGJhY2tyZWY/Ci0gICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBib29sZWFuIGNhc2VGb2xkID0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKG1hdGNoRmxhZ3MgJiBNQVRDSF9DQVNFSU5ERVBFTkRFTlQpICE9IDApOwotICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ29tcGFyZSBiYWNrcmVmIHRvIGlucHV0Ci0gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGw7IGkrKykKLSAgICAgICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29tcGFyZUNoYXJzKHNlYXJjaC5jaGFyQXQoaWR4KyspLCBzZWFyY2guY2hhckF0KHMgKyBpKSwgY2FzZUZvbGQpICE9IDApCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgICAgICAgICAgY2FzZSBPUF9CT0w6Ci0KLSAgICAgICAgICAgICAgICAgICAgLy8gRmFpbCBpZiB3ZSdyZSBub3QgYXQgdGhlIHN0YXJ0IG9mIHRoZSBzdHJpbmcKLSAgICAgICAgICAgICAgICAgICAgaWYgKGlkeCAhPSAwKQotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBJZiB3ZSdyZSBtdWx0aWxpbmUgbWF0Y2hpbmcsIHdlIGNvdWxkIHN0aWxsIGJlIGF0IHRoZSBzdGFydCBvZiBhIGxpbmUKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmICgobWF0Y2hGbGFncyAmIE1BVENIX01VTFRJTElORSkgPT0gTUFUQ0hfTVVMVElMSU5FKQotICAgICAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIElmIG5vdCBhdCBzdGFydCBvZiBsaW5lLCBnaXZlIHVwCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlkeCA8PSAwIHx8ICFpc05ld2xpbmUoaWR4IC0gMSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAtMTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBicmVhazsKLQotICAgICAgICAgICAgICAgIGNhc2UgT1BfRU9MOgotCi0gICAgICAgICAgICAgICAgICAgIC8vIElmIHdlJ3JlIG5vdCBhdCB0aGUgZW5kIG9mIHN0cmluZwotICAgICAgICAgICAgICAgICAgICBpZiAoIXNlYXJjaC5pc0VuZCgwKSAmJiAhc2VhcmNoLmlzRW5kKGlkeCkpCi0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIElmIHdlJ3JlIG11bHRpLWxpbmUgbWF0Y2hpbmcKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmICgobWF0Y2hGbGFncyAmIE1BVENIX01VTFRJTElORSkgPT0gTUFUQ0hfTVVMVElMSU5FKQotICAgICAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEdpdmUgdXAgaWYgd2UncmUgbm90IGF0IHRoZSBlbmQgb2YgYSBsaW5lCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFpc05ld2xpbmUoaWR4KSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgICAgICAgICAgY2FzZSBPUF9FU0NBUEU6Ci0KLSAgICAgICAgICAgICAgICAgICAgLy8gV2hpY2ggZXNjYXBlPwotICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKG9wZGF0YSkKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gV29yZCBib3VuZGFyeSBtYXRjaAotICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBFX05CT1VORDoKLSAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgRV9CT1VORDoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYXIgY0xhc3QgPSAoKGlkeCA9PSAwKSA/ICdcbicgOiBzZWFyY2guY2hhckF0KGlkeCAtIDEpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhciBjTmV4dCA9ICgoc2VhcmNoLmlzRW5kKGlkeCkpID8gJ1xuJyA6IHNlYXJjaC5jaGFyQXQoaWR4KSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoQ2hhcmFjdGVyLmlzTGV0dGVyT3JEaWdpdChjTGFzdCkgPT0gQ2hhcmFjdGVyLmlzTGV0dGVyT3JEaWdpdChjTmV4dCkpID09IChvcGRhdGEgPT0gRV9CT1VORCkpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAtMTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gQWxwaGEtbnVtZXJpYywgZGlnaXQsIHNwYWNlLCBqYXZhTGV0dGVyLCBqYXZhTGV0dGVyT3JEaWdpdAotICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBFX0FMTlVNOgotICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBFX05BTE5VTToKLSAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgRV9ESUdJVDoKLSAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgRV9ORElHSVQ6Ci0gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIEVfU1BBQ0U6Ci0gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIEVfTlNQQUNFOgotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gR2l2ZSB1cCBpZiBvdXQgb2YgaW5wdXQKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2VhcmNoLmlzRW5kKGlkeCkpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhciBjID0gc2VhcmNoLmNoYXJBdChpZHgpOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU3dpdGNoIG9uIGVzY2FwZQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN3aXRjaCAob3BkYXRhKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBFX0FMTlVNOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIEVfTkFMTlVNOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEoKENoYXJhY3Rlci5pc0xldHRlck9yRGlnaXQoYykgfHwgYyA9PSAnXycpID09IChvcGRhdGEgPT0gRV9BTE5VTSkpKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAtMTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgRV9ESUdJVDoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBFX05ESUdJVDoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghKENoYXJhY3Rlci5pc0RpZ2l0KGMpID09IChvcGRhdGEgPT0gRV9ESUdJVCkpKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAtMTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgRV9TUEFDRToKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBFX05TUEFDRToKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghKENoYXJhY3Rlci5pc1doaXRlc3BhY2UoYykgPT0gKG9wZGF0YSA9PSBFX1NQQUNFKSkpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlkeCsrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludGVybmFsRXJyb3IoIlVucmVjb2duaXplZCBlc2NhcGUgJyIgKyBvcGRhdGEgKyAiJyIpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgICAgICAgICAgY2FzZSBPUF9BTlk6Ci0KLSAgICAgICAgICAgICAgICAgICAgaWYgKChtYXRjaEZsYWdzICYgTUFUQ0hfU0lOR0xFTElORSkgPT0gTUFUQ0hfU0lOR0xFTElORSkgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gTWF0Y2ggYW55dGhpbmcKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZWFyY2guaXNFbmQoaWR4KSkKLSAgICAgICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBNYXRjaCBhbnl0aGluZyBidXQgYSBuZXdsaW5lCi0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2VhcmNoLmlzRW5kKGlkeCkgfHwgaXNOZXdsaW5lKGlkeCkpCi0gICAgICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGlkeCsrOwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLQotICAgICAgICAgICAgICAgIGNhc2UgT1BfQVRPTToKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gTWF0Y2ggYW4gYXRvbSB2YWx1ZQotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNlYXJjaC5pc0VuZChpZHgpKQotICAgICAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAtMTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gR2V0IGxlbmd0aCBvZiBhdG9tIGFuZCBzdGFydGluZyBpbmRleAotICAgICAgICAgICAgICAgICAgICAgICAgaW50IGxlbkF0b20gPSBvcGRhdGE7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpbnQgc3RhcnRBdG9tID0gbm9kZSArIG5vZGVTaXplOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBHaXZlIHVwIGlmIG5vdCBlbm91Z2ggaW5wdXQgcmVtYWlucyB0byBoYXZlIGEgbWF0Y2gKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZWFyY2guaXNFbmQobGVuQXRvbSArIGlkeCAtIDEpKQotICAgICAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAtMTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gTWF0Y2ggYXRvbSBkaWZmZXJlbnRseSBkZXBlbmRpbmcgb24gY2FzZWZvbGRpbmcgZmxhZwotICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgYm9vbGVhbiBjYXNlRm9sZCA9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgKChtYXRjaEZsYWdzICYgTUFUQ0hfQ0FTRUlOREVQRU5ERU5UKSAhPSAwKTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5BdG9tOyBpKyspCi0gICAgICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvbXBhcmVDaGFycyhzZWFyY2guY2hhckF0KGlkeCsrKSwgaW5zdHJ1Y3Rpb25bc3RhcnRBdG9tICsgaV0sIGNhc2VGb2xkKSAhPSAwKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBicmVhazsKLQotICAgICAgICAgICAgICAgIGNhc2UgT1BfUE9TSVhDTEFTUzoKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gT3V0IG9mIGlucHV0PwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNlYXJjaC5pc0VuZChpZHgpKQotICAgICAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAtMTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChvcGRhdGEpCi0gICAgICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBQT1NJWF9DTEFTU19BTE5VTToKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFDaGFyYWN0ZXIuaXNMZXR0ZXJPckRpZ2l0KHNlYXJjaC5jaGFyQXQoaWR4KSkpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAtMTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgUE9TSVhfQ0xBU1NfQUxQSEE6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghQ2hhcmFjdGVyLmlzTGV0dGVyKHNlYXJjaC5jaGFyQXQoaWR4KSkpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAtMTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgUE9TSVhfQ0xBU1NfRElHSVQ6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghQ2hhcmFjdGVyLmlzRGlnaXQoc2VhcmNoLmNoYXJBdChpZHgpKSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBQT1NJWF9DTEFTU19CTEFOSzogLy8gSldMIC0gYnVnYnVnOiBpcyB0aGlzIHJpZ2h0Pz8KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFDaGFyYWN0ZXIuaXNTcGFjZUNoYXIoc2VhcmNoLmNoYXJBdChpZHgpKSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBQT1NJWF9DTEFTU19TUEFDRToKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFDaGFyYWN0ZXIuaXNXaGl0ZXNwYWNlKHNlYXJjaC5jaGFyQXQoaWR4KSkpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAtMTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgUE9TSVhfQ0xBU1NfQ05UUkw6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChDaGFyYWN0ZXIuZ2V0VHlwZShzZWFyY2guY2hhckF0KGlkeCkpICE9IENoYXJhY3Rlci5DT05UUk9MKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFBPU0lYX0NMQVNTX0dSQVBIOiAvLyBKV0wgLSBidWdidWc/Pz8KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChDaGFyYWN0ZXIuZ2V0VHlwZShzZWFyY2guY2hhckF0KGlkeCkpKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIENoYXJhY3Rlci5NQVRIX1NZTUJPTDoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgQ2hhcmFjdGVyLkNVUlJFTkNZX1NZTUJPTDoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgQ2hhcmFjdGVyLk1PRElGSUVSX1NZTUJPTDoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgQ2hhcmFjdGVyLk9USEVSX1NZTUJPTDoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFBPU0lYX0NMQVNTX0xPV0VSOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoQ2hhcmFjdGVyLmdldFR5cGUoc2VhcmNoLmNoYXJBdChpZHgpKSAhPSBDaGFyYWN0ZXIuTE9XRVJDQVNFX0xFVFRFUikKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBQT1NJWF9DTEFTU19VUFBFUjoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKENoYXJhY3Rlci5nZXRUeXBlKHNlYXJjaC5jaGFyQXQoaWR4KSkgIT0gQ2hhcmFjdGVyLlVQUEVSQ0FTRV9MRVRURVIpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAtMTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgUE9TSVhfQ0xBU1NfUFJJTlQ6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChDaGFyYWN0ZXIuZ2V0VHlwZShzZWFyY2guY2hhckF0KGlkeCkpID09IENoYXJhY3Rlci5DT05UUk9MKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFBPU0lYX0NMQVNTX1BVTkNUOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHR5cGUgPSBDaGFyYWN0ZXIuZ2V0VHlwZShzZWFyY2guY2hhckF0KGlkeCkpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2godHlwZSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBDaGFyYWN0ZXIuREFTSF9QVU5DVFVBVElPTjoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgQ2hhcmFjdGVyLlNUQVJUX1BVTkNUVUFUSU9OOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBDaGFyYWN0ZXIuRU5EX1BVTkNUVUFUSU9OOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBDaGFyYWN0ZXIuQ09OTkVDVE9SX1BVTkNUVUFUSU9OOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBDaGFyYWN0ZXIuT1RIRVJfUFVOQ1RVQVRJT046Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBQT1NJWF9DTEFTU19YRElHSVQ6IC8vIEpXTCAtIGJ1Z2J1Zz8/Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGlzWERpZ2l0ID0gKChzZWFyY2guY2hhckF0KGlkeCkgPj0gJzAnICYmIHNlYXJjaC5jaGFyQXQoaWR4KSA8PSAnOScpIHx8Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHNlYXJjaC5jaGFyQXQoaWR4KSA+PSAnYScgJiYgc2VhcmNoLmNoYXJBdChpZHgpIDw9ICdmJykgfHwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoc2VhcmNoLmNoYXJBdChpZHgpID49ICdBJyAmJiBzZWFyY2guY2hhckF0KGlkeCkgPD0gJ0YnKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghaXNYRGlnaXQpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAtMTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgUE9TSVhfQ0xBU1NfSlNUQVJUOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIUNoYXJhY3Rlci5pc0phdmFJZGVudGlmaWVyU3RhcnQoc2VhcmNoLmNoYXJBdChpZHgpKSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBQT1NJWF9DTEFTU19KUEFSVDoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFDaGFyYWN0ZXIuaXNKYXZhSWRlbnRpZmllclBhcnQoc2VhcmNoLmNoYXJBdChpZHgpKSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50ZXJuYWxFcnJvcigiQmFkIHBvc2l4IGNsYXNzIik7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBNYXRjaGVkLgotICAgICAgICAgICAgICAgICAgICAgICAgaWR4Kys7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgICAgICAgICBjYXNlIE9QX0FOWU9GOgotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBPdXQgb2YgaW5wdXQ/Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2VhcmNoLmlzRW5kKGlkeCkpCi0gICAgICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBHZXQgY2hhcmFjdGVyIHRvIG1hdGNoIGFnYWluc3QgY2hhcmFjdGVyIGNsYXNzIGFuZCBtYXliZSBjYXNlZm9sZAotICAgICAgICAgICAgICAgICAgICAgICAgY2hhciBjID0gc2VhcmNoLmNoYXJBdChpZHgpOwotICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBjYXNlRm9sZCA9IChtYXRjaEZsYWdzICYgTUFUQ0hfQ0FTRUlOREVQRU5ERU5UKSAhPSAwOwotICAgICAgICAgICAgICAgICAgICAgICAgLy8gTG9vcCB0aHJvdWdoIGNoYXJhY3RlciBjbGFzcyBjaGVja2luZyBvdXIgbWF0Y2ggY2hhcmFjdGVyCi0gICAgICAgICAgICAgICAgICAgICAgICBpbnQgaWR4UmFuZ2UgPSBub2RlICsgbm9kZVNpemU7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpbnQgaWR4RW5kID0gaWR4UmFuZ2UgKyAob3BkYXRhICogMik7Ci0gICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIG1hdGNoID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gaWR4UmFuZ2U7ICFtYXRjaCAmJiBpIDwgaWR4RW5kOyApCi0gICAgICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gR2V0IHN0YXJ0LCBlbmQgYW5kIG1hdGNoIGNoYXJhY3RlcnMKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFyIHMgPSBpbnN0cnVjdGlvbltpKytdOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYXIgZSA9IGluc3RydWN0aW9uW2krK107Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRjaCA9ICgoY29tcGFyZUNoYXJzKGMsIHMsIGNhc2VGb2xkKSA+PSAwKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmIChjb21wYXJlQ2hhcnMoYywgZSwgY2FzZUZvbGQpIDw9IDApKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gRmFpbCBpZiB3ZSBkaWRuJ3QgbWF0Y2ggdGhlIGNoYXJhY3RlciBjbGFzcwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFtYXRjaCkKLSAgICAgICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZHgrKzsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBicmVhazsKLQotICAgICAgICAgICAgICAgIGNhc2UgT1BfQlJBTkNIOgotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gQ2hlY2sgZm9yIGNob2ljZXMKLSAgICAgICAgICAgICAgICAgICAgaWYgKGluc3RydWN0aW9uW25leHQgKyBvZmZzZXRPcGNvZGVdICE9IE9QX0JSQU5DSCkKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gSWYgdGhlcmUgYXJlbid0IGFueSBvdGhlciBjaG9pY2VzLCBqdXN0IGV2YWx1YXRlIHRoaXMgYnJhbmNoLgotICAgICAgICAgICAgICAgICAgICAgICAgbm9kZSArPSBub2RlU2l6ZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgLy8gVHJ5IGFsbCBhdmFpbGFibGUgYnJhbmNoZXMKLSAgICAgICAgICAgICAgICAgICAgc2hvcnQgbmV4dEJyYW5jaDsKLSAgICAgICAgICAgICAgICAgICAgZG8KLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gVHJ5IG1hdGNoaW5nIHRoZSBicmFuY2ggYWdhaW5zdCB0aGUgc3RyaW5nCi0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoKGlkeE5ldyA9IG1hdGNoTm9kZXMobm9kZSArIG5vZGVTaXplLCBtYXhOb2RlLCBpZHgpKSAhPSAtMSkKLSAgICAgICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaWR4TmV3OwotICAgICAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBHbyB0byBuZXh0IGJyYW5jaCAoaWYgYW55KQotICAgICAgICAgICAgICAgICAgICAgICAgbmV4dEJyYW5jaCA9IChzaG9ydClpbnN0cnVjdGlvbltub2RlICsgb2Zmc2V0TmV4dF07Ci0gICAgICAgICAgICAgICAgICAgICAgICBub2RlICs9IG5leHRCcmFuY2g7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgd2hpbGUgKG5leHRCcmFuY2ggIT0gMCAmJiAoaW5zdHJ1Y3Rpb25bbm9kZSArIG9mZnNldE9wY29kZV0gPT0gT1BfQlJBTkNIKSk7Ci0KLSAgICAgICAgICAgICAgICAgICAgLy8gRmFpbGVkIHRvIG1hdGNoIGFueSBicmFuY2ghCi0gICAgICAgICAgICAgICAgICAgIHJldHVybiAtMTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBjYXNlIE9QX05PVEhJTkc6Ci0gICAgICAgICAgICAgICAgY2FzZSBPUF9HT1RPOgotCi0gICAgICAgICAgICAgICAgICAgIC8vIEp1c3QgYWR2YW5jZSB0byB0aGUgbmV4dCBub2RlIHdpdGhvdXQgZG9pbmcgYW55dGhpbmcKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgICAgICAgICBjYXNlIE9QX0VORDoKLQotICAgICAgICAgICAgICAgICAgICAvLyBNYXRjaCBoYXMgc3VjY2VlZGVkIQotICAgICAgICAgICAgICAgICAgICBzZXRQYXJlbkVuZCgwLCBpZHgpOwotICAgICAgICAgICAgICAgICAgICByZXR1cm4gaWR4OwotCi0gICAgICAgICAgICAgICAgZGVmYXVsdDoKLQotICAgICAgICAgICAgICAgICAgICAvLyBDb3JydXB0IHByb2dyYW0KLSAgICAgICAgICAgICAgICAgICAgaW50ZXJuYWxFcnJvcigiSW52YWxpZCBvcGNvZGUgJyIgKyBvcGNvZGUgKyAiJyIpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBBZHZhbmNlIHRvIHRoZSBuZXh0IG5vZGUgaW4gdGhlIHByb2dyYW0KLSAgICAgICAgICAgIG5vZGUgPSBuZXh0OwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gV2UgInNob3VsZCIgbmV2ZXIgZW5kIHVwIGhlcmUKLSAgICAgICAgaW50ZXJuYWxFcnJvcigiQ29ycnVwdCBwcm9ncmFtIik7Ci0gICAgICAgIHJldHVybiAtMTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBNYXRjaCB0aGUgY3VycmVudCByZWd1bGFyIGV4cHJlc3Npb24gcHJvZ3JhbSBhZ2FpbnN0IHRoZSBjdXJyZW50Ci0gICAgICogaW5wdXQgc3RyaW5nLCBzdGFydGluZyBhdCBpbmRleCBpIG9mIHRoZSBpbnB1dCBzdHJpbmcuICBUaGlzIG1ldGhvZAotICAgICAqIGlzIG9ubHkgbWVhbnQgZm9yIGludGVybmFsIHVzZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBpIFRoZSBpbnB1dCBzdHJpbmcgaW5kZXggdG8gc3RhcnQgbWF0Y2hpbmcgYXQKLSAgICAgKiBAcmV0dXJuIFRydWUgaWYgdGhlIGlucHV0IG1hdGNoZWQgdGhlIGV4cHJlc3Npb24KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBtYXRjaEF0KGludCBpKQotICAgIHsKLSAgICAgICAgLy8gSW5pdGlhbGl6ZSBzdGFydCBwb2ludGVyLCBwYXJlbiBjYWNoZSBhbmQgcGFyZW4gY291bnQKLSAgICAgICAgc3RhcnQwID0gLTE7Ci0gICAgICAgIGVuZDAgICA9IC0xOwotICAgICAgICBzdGFydDEgPSAtMTsKLSAgICAgICAgZW5kMSAgID0gLTE7Ci0gICAgICAgIHN0YXJ0MiA9IC0xOwotICAgICAgICBlbmQyICAgPSAtMTsKLSAgICAgICAgc3RhcnRuID0gbnVsbDsKLSAgICAgICAgZW5kbiAgID0gbnVsbDsKLSAgICAgICAgcGFyZW5Db3VudCA9IDE7Ci0gICAgICAgIHNldFBhcmVuU3RhcnQoMCwgaSk7Ci0KLSAgICAgICAgLy8gQWxsb2NhdGUgYmFja3JlZiBhcnJheXMgKHVubGVzcyBvcHRpbWl6YXRpb25zIGluZGljYXRlIG90aGVyd2lzZSkKLSAgICAgICAgaWYgKChwcm9ncmFtLmZsYWdzICYgUkVQcm9ncmFtLk9QVF9IQVNCQUNLUkVGUykgIT0gMCkKLSAgICAgICAgewotICAgICAgICAgICAgc3RhcnRCYWNrcmVmID0gbmV3IGludFttYXhQYXJlbl07Ci0gICAgICAgICAgICBlbmRCYWNrcmVmID0gbmV3IGludFttYXhQYXJlbl07Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBNYXRjaCBhZ2FpbnN0IHN0cmluZwotICAgICAgICBpbnQgaWR4OwotICAgICAgICBpZiAoKGlkeCA9IG1hdGNoTm9kZXMoMCwgbWF4Tm9kZSwgaSkpICE9IC0xKQotICAgICAgICB7Ci0gICAgICAgICAgICBzZXRQYXJlbkVuZCgwLCBpZHgpOwotICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBEaWRuJ3QgbWF0Y2gKLSAgICAgICAgcGFyZW5Db3VudCA9IDA7Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBNYXRjaGVzIHRoZSBjdXJyZW50IHJlZ3VsYXIgZXhwcmVzc2lvbiBwcm9ncmFtIGFnYWluc3QgYSBjaGFyYWN0ZXIgYXJyYXksCi0gICAgICogc3RhcnRpbmcgYXQgYSBnaXZlbiBpbmRleC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzZWFyY2ggU3RyaW5nIHRvIG1hdGNoIGFnYWluc3QKLSAgICAgKiBAcGFyYW0gaSBJbmRleCB0byBzdGFydCBzZWFyY2hpbmcgYXQKLSAgICAgKiBAcmV0dXJuIFRydWUgaWYgc3RyaW5nIG1hdGNoZWQKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBtYXRjaChTdHJpbmcgc2VhcmNoLCBpbnQgaSkKLSAgICB7Ci0gICAgICAgIHJldHVybiBtYXRjaChuZXcgU3RyaW5nQ2hhcmFjdGVySXRlcmF0b3Ioc2VhcmNoKSwgaSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogTWF0Y2hlcyB0aGUgY3VycmVudCByZWd1bGFyIGV4cHJlc3Npb24gcHJvZ3JhbSBhZ2FpbnN0IGEgY2hhcmFjdGVyIGFycmF5LAotICAgICAqIHN0YXJ0aW5nIGF0IGEgZ2l2ZW4gaW5kZXguCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc2VhcmNoIFN0cmluZyB0byBtYXRjaCBhZ2FpbnN0Ci0gICAgICogQHBhcmFtIGkgSW5kZXggdG8gc3RhcnQgc2VhcmNoaW5nIGF0Ci0gICAgICogQHJldHVybiBUcnVlIGlmIHN0cmluZyBtYXRjaGVkCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gbWF0Y2goQ2hhcmFjdGVySXRlcmF0b3Igc2VhcmNoLCBpbnQgaSkKLSAgICB7Ci0gICAgICAgIC8vIFRoZXJlIGlzIG5vIGNvbXBpbGVkIHByb2dyYW0gdG8gc2VhcmNoIHdpdGghCi0gICAgICAgIGlmIChwcm9ncmFtID09IG51bGwpCi0gICAgICAgIHsKLSAgICAgICAgICAgIC8vIFRoaXMgc2hvdWxkIGJlIHVuY29tbW9uIGVub3VnaCB0byBiZSBhbiBlcnJvciBjYXNlIHJhdGhlcgotICAgICAgICAgICAgLy8gdGhhbiBhbiBleGNlcHRpb24gKHdoaWNoIHdvdWxkIGhhdmUgdG8gYmUgaGFuZGxlZCBldmVyeXdoZXJlKQotICAgICAgICAgICAgaW50ZXJuYWxFcnJvcigiTm8gUkUgcHJvZ3JhbSB0byBydW4hIik7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBTYXZlIHN0cmluZyB0byBzZWFyY2gKLSAgICAgICAgdGhpcy5zZWFyY2ggPSBzZWFyY2g7Ci0KLSAgICAgICAgLy8gQ2FuIHdlIG9wdGltaXplIHRoZSBzZWFyY2ggYnkgbG9va2luZyBmb3IgYSBwcmVmaXggc3RyaW5nPwotICAgICAgICBpZiAocHJvZ3JhbS5wcmVmaXggPT0gbnVsbCkKLSAgICAgICAgewotICAgICAgICAgICAgLy8gVW5wcmVmaXhlZCBtYXRjaGluZyBtdXN0IHRyeSBmb3IgYSBtYXRjaCBhdCBlYWNoIGNoYXJhY3RlcgotICAgICAgICAgICAgZm9yICggOyEgc2VhcmNoLmlzRW5kKGkgLSAxKTsgaSsrKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIC8vIFRyeSBhIG1hdGNoIGF0IGluZGV4IGkKLSAgICAgICAgICAgICAgICBpZiAobWF0Y2hBdChpKSkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgIHsKLSAgICAgICAgICAgIC8vIFByZWZpeC1hbmNob3JlZCBtYXRjaGluZyBpcyBwb3NzaWJsZQotICAgICAgICAgICAgYm9vbGVhbiBjYXNlSW5kZXBlbmRlbnQgPSAobWF0Y2hGbGFncyAmIE1BVENIX0NBU0VJTkRFUEVOREVOVCkgIT0gMDsKLSAgICAgICAgICAgIGNoYXJbXSBwcmVmaXggPSBwcm9ncmFtLnByZWZpeDsKLSAgICAgICAgICAgIGZvciAoIDsgIXNlYXJjaC5pc0VuZChpICsgcHJlZml4Lmxlbmd0aCAtIDEpOyBpKyspCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgaW50IGogPSBpOwotICAgICAgICAgICAgICAgIGludCBrID0gMDsKLQotICAgICAgICAgICAgICAgIGJvb2xlYW4gbWF0Y2g7Ci0gICAgICAgICAgICAgICAgZG8gewotICAgICAgICAgICAgICAgICAgICAvLyBJZiB0aGVyZSdzIGEgbWlzbWF0Y2ggb2YgYW55IGNoYXJhY3RlciBpbiB0aGUgcHJlZml4LCBnaXZlIHVwCi0gICAgICAgICAgICAgICAgICAgIG1hdGNoID0gKGNvbXBhcmVDaGFycyhzZWFyY2guY2hhckF0KGorKyksIHByZWZpeFtrKytdLCBjYXNlSW5kZXBlbmRlbnQpID09IDApOwotICAgICAgICAgICAgICAgIH0gd2hpbGUgKG1hdGNoICYmIGsgPCBwcmVmaXgubGVuZ3RoKTsKLQotICAgICAgICAgICAgICAgIC8vIFNlZSBpZiB0aGUgd2hvbGUgcHJlZml4IHN0cmluZyBtYXRjaGVkCi0gICAgICAgICAgICAgICAgaWYgKGsgPT0gcHJlZml4Lmxlbmd0aCkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIFdlIG1hdGNoZWQgdGhlIGZ1bGwgcHJlZml4IGF0IGZpcnN0Q2hhciwgc28gdHJ5IGl0Ci0gICAgICAgICAgICAgICAgICAgIGlmIChtYXRjaEF0KGkpKQotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIE1hdGNoZXMgdGhlIGN1cnJlbnQgcmVndWxhciBleHByZXNzaW9uIHByb2dyYW0gYWdhaW5zdCBhIFN0cmluZy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzZWFyY2ggU3RyaW5nIHRvIG1hdGNoIGFnYWluc3QKLSAgICAgKiBAcmV0dXJuIFRydWUgaWYgc3RyaW5nIG1hdGNoZWQKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBtYXRjaChTdHJpbmcgc2VhcmNoKQotICAgIHsKLSAgICAgICAgcmV0dXJuIG1hdGNoKHNlYXJjaCwgMCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU3BsaXRzIGEgc3RyaW5nIGludG8gYW4gYXJyYXkgb2Ygc3RyaW5ncyBvbiByZWd1bGFyIGV4cHJlc3Npb24gYm91bmRhcmllcy4KLSAgICAgKiBUaGlzIGZ1bmN0aW9uIHdvcmtzIHRoZSBzYW1lIHdheSBhcyB0aGUgUGVybCBmdW5jdGlvbiBvZiB0aGUgc2FtZSBuYW1lLgotICAgICAqIEdpdmVuIGEgcmVndWxhciBleHByZXNzaW9uIG9mICJbYWJdKyIgYW5kIGEgc3RyaW5nIHRvIHNwbGl0IG9mCi0gICAgICogInh5enp5YWJhYmJheXl6YWJiYmFiMTIzIiwgdGhlIHJlc3VsdCB3b3VsZCBiZSB0aGUgYXJyYXkgb2YgU3RyaW5ncwotICAgICAqICJbeHl6enksIHl5eiwgMTIzXSIuCi0gICAgICoKLSAgICAgKiA8cD5QbGVhc2Ugbm90ZSB0aGF0IHRoZSBmaXJzdCBzdHJpbmcgaW4gdGhlIHJlc3VsdGluZyBhcnJheSBtYXkgYmUgYW4gZW1wdHkKLSAgICAgKiBzdHJpbmcuIFRoaXMgaGFwcGVucyB3aGVuIHRoZSB2ZXJ5IGZpcnN0IGNoYXJhY3RlciBvZiBpbnB1dCBzdHJpbmcgaXMKLSAgICAgKiBtYXRjaGVkIGJ5IHRoZSBwYXR0ZXJuLgotICAgICAqCi0gICAgICogQHBhcmFtIHMgU3RyaW5nIHRvIHNwbGl0IG9uIHRoaXMgcmVndWxhciBleHJlc3Npb24KLSAgICAgKiBAcmV0dXJuIEFycmF5IG9mIHN0cmluZ3MKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nW10gc3BsaXQoU3RyaW5nIHMpCi0gICAgewotICAgICAgICAvLyBDcmVhdGUgbmV3IHZlY3RvcgotICAgICAgICBWZWN0b3IgdiA9IG5ldyBWZWN0b3IoKTsKLQotICAgICAgICAvLyBTdGFydCBhdCBwb3NpdGlvbiAwIGFuZCBzZWFyY2ggdGhlIHdob2xlIHN0cmluZwotICAgICAgICBpbnQgcG9zID0gMDsKLSAgICAgICAgaW50IGxlbiA9IHMubGVuZ3RoKCk7Ci0KLSAgICAgICAgLy8gVHJ5IGEgbWF0Y2ggYXQgZWFjaCBwb3NpdGlvbgotICAgICAgICB3aGlsZSAocG9zIDwgbGVuICYmIG1hdGNoKHMsIHBvcykpCi0gICAgICAgIHsKLSAgICAgICAgICAgIC8vIEdldCBzdGFydCBvZiBtYXRjaAotICAgICAgICAgICAgaW50IHN0YXJ0ID0gZ2V0UGFyZW5TdGFydCgwKTsKLQotICAgICAgICAgICAgLy8gR2V0IGVuZCBvZiBtYXRjaAotICAgICAgICAgICAgaW50IG5ld3BvcyA9IGdldFBhcmVuRW5kKDApOwotCi0gICAgICAgICAgICAvLyBDaGVjayBpZiBubyBwcm9ncmVzcyB3YXMgbWFkZQotICAgICAgICAgICAgaWYgKG5ld3BvcyA9PSBwb3MpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgdi5hZGRFbGVtZW50KHMuc3Vic3RyaW5nKHBvcywgc3RhcnQgKyAxKSk7Ci0gICAgICAgICAgICAgICAgbmV3cG9zKys7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgdi5hZGRFbGVtZW50KHMuc3Vic3RyaW5nKHBvcywgc3RhcnQpKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gTW92ZSB0byBuZXcgcG9zaXRpb24KLSAgICAgICAgICAgIHBvcyA9IG5ld3BvczsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIFB1c2ggcmVtYWluZGVyIGlmIGl0J3Mgbm90IGVtcHR5Ci0gICAgICAgIFN0cmluZyByZW1haW5kZXIgPSBzLnN1YnN0cmluZyhwb3MpOwotICAgICAgICBpZiAocmVtYWluZGVyLmxlbmd0aCgpICE9IDApCi0gICAgICAgIHsKLSAgICAgICAgICAgIHYuYWRkRWxlbWVudChyZW1haW5kZXIpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gUmV0dXJuIHZlY3RvciBhcyBhbiBhcnJheSBvZiBzdHJpbmdzCi0gICAgICAgIFN0cmluZ1tdIHJldCA9IG5ldyBTdHJpbmdbdi5zaXplKCldOwotICAgICAgICB2LmNvcHlJbnRvKHJldCk7Ci0gICAgICAgIHJldHVybiByZXQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRmxhZyBiaXQgdGhhdCBpbmRpY2F0ZXMgdGhhdCBzdWJzdCBzaG91bGQgcmVwbGFjZSBhbGwgb2NjdXJyZW5jZXMgb2YgdGhpcwotICAgICAqIHJlZ3VsYXIgZXhwcmVzc2lvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBMQUNFX0FMTCAgICAgICAgICAgID0gMHgwMDAwOwotCi0gICAgLyoqCi0gICAgICogRmxhZyBiaXQgdGhhdCBpbmRpY2F0ZXMgdGhhdCBzdWJzdCBzaG91bGQgb25seSByZXBsYWNlIHRoZSBmaXJzdCBvY2N1cnJlbmNlCi0gICAgICogb2YgdGhpcyByZWd1bGFyIGV4cHJlc3Npb24uCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQTEFDRV9GSVJTVE9OTFkgICAgICA9IDB4MDAwMTsKLQotICAgIC8qKgotICAgICAqIEZsYWcgYml0IHRoYXQgaW5kaWNhdGVzIHRoYXQgc3Vic3Qgc2hvdWxkIHJlcGxhY2UgYmFja3JlZmVyZW5jZXMKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBMQUNFX0JBQ0tSRUZFUkVOQ0VTID0gMHgwMDAyOwotCi0gICAgLyoqCi0gICAgICogU3Vic3RpdHV0ZXMgYSBzdHJpbmcgZm9yIHRoaXMgcmVndWxhciBleHByZXNzaW9uIGluIGFub3RoZXIgc3RyaW5nLgotICAgICAqIFRoaXMgbWV0aG9kIHdvcmtzIGxpa2UgdGhlIFBlcmwgZnVuY3Rpb24gb2YgdGhlIHNhbWUgbmFtZS4KLSAgICAgKiBHaXZlbiBhIHJlZ3VsYXIgZXhwcmVzc2lvbiBvZiAiYSpiIiwgYSBTdHJpbmcgdG8gc3Vic3RpdHV0ZUluIG9mCi0gICAgICogImFhYWFiZm9vYWFhYmdhcnBseWFhYWJ3YWNreWIiIGFuZCB0aGUgc3Vic3RpdHV0aW9uIFN0cmluZyAiLSIsIHRoZQotICAgICAqIHJlc3VsdGluZyBTdHJpbmcgcmV0dXJuZWQgYnkgc3Vic3Qgd291bGQgYmUgIi1mb28tZ2FycGx5LXdhY2t5LSIuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc3Vic3RpdHV0ZUluIFN0cmluZyB0byBzdWJzdGl0dXRlIHdpdGhpbgotICAgICAqIEBwYXJhbSBzdWJzdGl0dXRpb24gU3RyaW5nIHRvIHN1YnN0aXR1dGUgZm9yIGFsbCBtYXRjaGVzIG9mIHRoaXMgcmVndWxhciBleHByZXNzaW9uLgotICAgICAqIEByZXR1cm4gVGhlIHN0cmluZyBzdWJzdGl0dXRlSW4gd2l0aCB6ZXJvIG9yIG1vcmUgb2NjdXJyZW5jZXMgb2YgdGhlIGN1cnJlbnQKLSAgICAgKiByZWd1bGFyIGV4cHJlc3Npb24gcmVwbGFjZWQgd2l0aCB0aGUgc3Vic3RpdHV0aW9uIFN0cmluZyAoaWYgdGhpcyByZWd1bGFyCi0gICAgICogZXhwcmVzc2lvbiBvYmplY3QgZG9lc24ndCBtYXRjaCBhdCBhbnkgcG9zaXRpb24sIHRoZSBvcmlnaW5hbCBTdHJpbmcgaXMgcmV0dXJuZWQKLSAgICAgKiB1bmNoYW5nZWQpLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgc3Vic3QoU3RyaW5nIHN1YnN0aXR1dGVJbiwgU3RyaW5nIHN1YnN0aXR1dGlvbikKLSAgICB7Ci0gICAgICAgIHJldHVybiBzdWJzdChzdWJzdGl0dXRlSW4sIHN1YnN0aXR1dGlvbiwgUkVQTEFDRV9BTEwpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFN1YnN0aXR1dGVzIGEgc3RyaW5nIGZvciB0aGlzIHJlZ3VsYXIgZXhwcmVzc2lvbiBpbiBhbm90aGVyIHN0cmluZy4KLSAgICAgKiBUaGlzIG1ldGhvZCB3b3JrcyBsaWtlIHRoZSBQZXJsIGZ1bmN0aW9uIG9mIHRoZSBzYW1lIG5hbWUuCi0gICAgICogR2l2ZW4gYSByZWd1bGFyIGV4cHJlc3Npb24gb2YgImEqYiIsIGEgU3RyaW5nIHRvIHN1YnN0aXR1dGVJbiBvZgotICAgICAqICJhYWFhYmZvb2FhYWJnYXJwbHlhYWFid2Fja3liIiBhbmQgdGhlIHN1YnN0aXR1dGlvbiBTdHJpbmcgIi0iLCB0aGUKLSAgICAgKiByZXN1bHRpbmcgU3RyaW5nIHJldHVybmVkIGJ5IHN1YnN0IHdvdWxkIGJlICItZm9vLWdhcnBseS13YWNreS0iLgotICAgICAqIDxwPgotICAgICAqIEl0IGlzIGFsc28gcG9zc2libGUgdG8gcmVmZXJlbmNlIHRoZSBjb250ZW50cyBvZiBhIHBhcmVudGhlc2l6ZWQgZXhwcmVzc2lvbgotICAgICAqIHdpdGggJDAsICQxLCAuLi4gJDkuIEEgcmVndWxhciBleHByZXNzaW9uIG9mICJodHRwOi8vW1xcLlxcd1xcLVxcPy9+X0AmPSVdKyIsCi0gICAgICogYSBTdHJpbmcgdG8gc3Vic3RpdHV0ZUluIG9mICJ2aXNpdCB1czogaHR0cDovL3d3dy5hcGFjaGUub3JnISIgYW5kIHRoZQotICAgICAqIHN1YnN0aXR1dGlvbiBTdHJpbmcgIiZsdDthIGhyZWY9XCIkMFwiJmd0OyQwJmx0Oy9hJmd0OyIsIHRoZSByZXN1bHRpbmcgU3RyaW5nCi0gICAgICogcmV0dXJuZWQgYnkgc3Vic3Qgd291bGQgYmUKLSAgICAgKiAidmlzaXQgdXM6ICZsdDthIGhyZWY9XCJodHRwOi8vd3d3LmFwYWNoZS5vcmdcIiZndDtodHRwOi8vd3d3LmFwYWNoZS5vcmcmbHQ7L2EmZ3Q7ISIuCi0gICAgICogPHA+Ci0gICAgICogPGk+Tm90ZTo8L2k+ICQwIHJlcHJlc2VudHMgdGhlIHdob2xlIG1hdGNoLgotICAgICAqCi0gICAgICogQHBhcmFtIHN1YnN0aXR1dGVJbiBTdHJpbmcgdG8gc3Vic3RpdHV0ZSB3aXRoaW4KLSAgICAgKiBAcGFyYW0gc3Vic3RpdHV0aW9uIFN0cmluZyB0byBzdWJzdGl0dXRlIGZvciBtYXRjaGVzIG9mIHRoaXMgcmVndWxhciBleHByZXNzaW9uCi0gICAgICogQHBhcmFtIGZsYWdzIE9uZSBvciBtb3JlIGJpdHdpc2UgZmxhZ3MgZnJvbSBSRVBMQUNFXyouICBJZiB0aGUgUkVQTEFDRV9GSVJTVE9OTFkKLSAgICAgKiBmbGFnIGJpdCBpcyBzZXQsIG9ubHkgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgdGhpcyByZWd1bGFyIGV4cHJlc3Npb24gaXMgcmVwbGFjZWQuCi0gICAgICogSWYgdGhlIGJpdCBpcyBub3Qgc2V0IChSRVBMQUNFX0FMTCksIGFsbCBvY2N1cnJlbmNlcyBvZiB0aGlzIHBhdHRlcm4gd2lsbCBiZQotICAgICAqIHJlcGxhY2VkLiBJZiB0aGUgZmxhZyBSRVBMQUNFX0JBQ0tSRUZFUkVOQ0VTIGlzIHNldCwgYWxsIGJhY2tyZWZlcmVuY2VzIHdpbGwKLSAgICAgKiBiZSBwcm9jZXNzZWQuCi0gICAgICogQHJldHVybiBUaGUgc3RyaW5nIHN1YnN0aXR1dGVJbiB3aXRoIHplcm8gb3IgbW9yZSBvY2N1cnJlbmNlcyBvZiB0aGUgY3VycmVudAotICAgICAqIHJlZ3VsYXIgZXhwcmVzc2lvbiByZXBsYWNlZCB3aXRoIHRoZSBzdWJzdGl0dXRpb24gU3RyaW5nIChpZiB0aGlzIHJlZ3VsYXIKLSAgICAgKiBleHByZXNzaW9uIG9iamVjdCBkb2Vzbid0IG1hdGNoIGF0IGFueSBwb3NpdGlvbiwgdGhlIG9yaWdpbmFsIFN0cmluZyBpcyByZXR1cm5lZAotICAgICAqIHVuY2hhbmdlZCkuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBzdWJzdChTdHJpbmcgc3Vic3RpdHV0ZUluLCBTdHJpbmcgc3Vic3RpdHV0aW9uLCBpbnQgZmxhZ3MpCi0gICAgewotICAgICAgICAvLyBTdHJpbmcgdG8gcmV0dXJuCi0gICAgICAgIFN0cmluZ0J1ZmZlciByZXQgPSBuZXcgU3RyaW5nQnVmZmVyKCk7Ci0KLSAgICAgICAgLy8gU3RhcnQgYXQgcG9zaXRpb24gMCBhbmQgc2VhcmNoIHRoZSB3aG9sZSBzdHJpbmcKLSAgICAgICAgaW50IHBvcyA9IDA7Ci0gICAgICAgIGludCBsZW4gPSBzdWJzdGl0dXRlSW4ubGVuZ3RoKCk7Ci0KLSAgICAgICAgLy8gVHJ5IGEgbWF0Y2ggYXQgZWFjaCBwb3NpdGlvbgotICAgICAgICB3aGlsZSAocG9zIDwgbGVuICYmIG1hdGNoKHN1YnN0aXR1dGVJbiwgcG9zKSkKLSAgICAgICAgewotICAgICAgICAgICAgLy8gQXBwZW5kIHN0cmluZyBiZWZvcmUgbWF0Y2gKLSAgICAgICAgICAgIHJldC5hcHBlbmQoc3Vic3RpdHV0ZUluLnN1YnN0cmluZyhwb3MsIGdldFBhcmVuU3RhcnQoMCkpKTsKLQotICAgICAgICAgICAgaWYgKChmbGFncyAmIFJFUExBQ0VfQkFDS1JFRkVSRU5DRVMpICE9IDApCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgLy8gUHJvY2VzcyBiYWNrcmVmZXJlbmNlcwotICAgICAgICAgICAgICAgIGludCBsQ3VycmVudFBvc2l0aW9uID0gMDsKLSAgICAgICAgICAgICAgICBpbnQgbExhc3RQb3NpdGlvbiA9IC0yOwotICAgICAgICAgICAgICAgIGludCBsTGVuZ3RoID0gc3Vic3RpdHV0aW9uLmxlbmd0aCgpOwotICAgICAgICAgICAgICAgIGJvb2xlYW4gYkFkZGVkUHJlZml4ID0gZmFsc2U7Ci0KLSAgICAgICAgICAgICAgICB3aGlsZSAoKGxDdXJyZW50UG9zaXRpb24gPSBzdWJzdGl0dXRpb24uaW5kZXhPZigiJCIsIGxDdXJyZW50UG9zaXRpb24pKSA+PSAwKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKChsQ3VycmVudFBvc2l0aW9uID09IDAgfHwgc3Vic3RpdHV0aW9uLmNoYXJBdChsQ3VycmVudFBvc2l0aW9uIC0gMSkgIT0gJ1xcJykKLSAgICAgICAgICAgICAgICAgICAgICAgICYmIGxDdXJyZW50UG9zaXRpb24rMSA8IGxMZW5ndGgpCi0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGNoYXIgYyA9IHN1YnN0aXR1dGlvbi5jaGFyQXQobEN1cnJlbnRQb3NpdGlvbiArIDEpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGMgPj0gJzAnICYmIGMgPD0gJzknKQotICAgICAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChiQWRkZWRQcmVmaXggPT0gZmFsc2UpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBBcHBlbmQgZXZlcnl0aGluZyBiZXR3ZWVuIHRoZSBiZWdpbm5pbmcgb2YgdGhlCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHN1YnN0aXR1dGlvbiBzdHJpbmcgYW5kIHRoZSBjdXJyZW50ICQgc2lnbgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXQuYXBwZW5kKHN1YnN0aXR1dGlvbi5zdWJzdHJpbmcoMCwgbEN1cnJlbnRQb3NpdGlvbikpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiQWRkZWRQcmVmaXggPSB0cnVlOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBBcHBlbmQgZXZlcnl0aGluZyBiZXR3ZWVuIHRoZSBsYXN0IGFuZCB0aGUgY3VycmVudCAkIHNpZ24KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0LmFwcGVuZChzdWJzdGl0dXRpb24uc3Vic3RyaW5nKGxMYXN0UG9zaXRpb24gKyAyLCBsQ3VycmVudFBvc2l0aW9uKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQXBwZW5kIHRoZSBwYXJlbnRoZXNpemVkIGV4cHJlc3Npb24KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBOb3RlOiBpZiBhIHBhcmVudGhlc2l6ZWQgZXhwcmVzc2lvbiBvZiB0aGUgcmVxdWVzdGVkCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaW5kZXggaXMgbm90IGF2YWlsYWJsZSAibnVsbCIgaXMgYWRkZWQgdG8gdGhlIHN0cmluZwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldC5hcHBlbmQoZ2V0UGFyZW4oYyAtICcwJykpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxMYXN0UG9zaXRpb24gPSBsQ3VycmVudFBvc2l0aW9uOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgLy8gTW92ZSBmb3J3YXJkLCBza2lwcGluZyBwYXN0IG1hdGNoCi0gICAgICAgICAgICAgICAgICAgIGxDdXJyZW50UG9zaXRpb24rKzsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyBBcHBlbmQgZXZlcnl0aGluZyBhZnRlciB0aGUgbGFzdCAkIHNpZ24KLSAgICAgICAgICAgICAgICByZXQuYXBwZW5kKHN1YnN0aXR1dGlvbi5zdWJzdHJpbmcobExhc3RQb3NpdGlvbiArIDIsIGxMZW5ndGgpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAvLyBBcHBlbmQgc3Vic3RpdHV0aW9uIHdpdGhvdXQgcHJvY2Vzc2luZyBiYWNrcmVmZXJlbmNlcwotICAgICAgICAgICAgICAgIHJldC5hcHBlbmQoc3Vic3RpdHV0aW9uKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gTW92ZSBmb3J3YXJkLCBza2lwcGluZyBwYXN0IG1hdGNoCi0gICAgICAgICAgICBpbnQgbmV3cG9zID0gZ2V0UGFyZW5FbmQoMCk7Ci0KLSAgICAgICAgICAgIC8vIFdlIGFsd2F5cyB3YW50IHRvIG1ha2UgcHJvZ3Jlc3MhCi0gICAgICAgICAgICBpZiAobmV3cG9zID09IHBvcykKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBuZXdwb3MrKzsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gVHJ5IG5ldyBwb3NpdGlvbgotICAgICAgICAgICAgcG9zID0gbmV3cG9zOwotCi0gICAgICAgICAgICAvLyBCcmVhayBvdXQgaWYgd2UncmUgb25seSBzdXBwb3NlZCB0byByZXBsYWNlIG9uZSBvY2N1cnJlbmNlCi0gICAgICAgICAgICBpZiAoKGZsYWdzICYgUkVQTEFDRV9GSVJTVE9OTFkpICE9IDApCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBJZiB0aGVyZSdzIHJlbWFpbmluZyBpbnB1dCwgYXBwZW5kIGl0Ci0gICAgICAgIGlmIChwb3MgPCBsZW4pCi0gICAgICAgIHsKLSAgICAgICAgICAgIHJldC5hcHBlbmQoc3Vic3RpdHV0ZUluLnN1YnN0cmluZyhwb3MpKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIFJldHVybiBzdHJpbmcgYnVmZmVyIGFzIHN0cmluZwotICAgICAgICByZXR1cm4gcmV0LnRvU3RyaW5nKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhbiBhcnJheSBvZiBTdHJpbmdzLCB3aG9zZSB0b1N0cmluZyByZXByZXNlbnRhdGlvbiBtYXRjaGVzIGEgcmVndWxhcgotICAgICAqIGV4cHJlc3Npb24uIFRoaXMgbWV0aG9kIHdvcmtzIGxpa2UgdGhlIFBlcmwgZnVuY3Rpb24gb2YgdGhlIHNhbWUgbmFtZS4gIEdpdmVuCi0gICAgICogYSByZWd1bGFyIGV4cHJlc3Npb24gb2YgImEqYiIgYW5kIGFuIGFycmF5IG9mIFN0cmluZyBvYmplY3RzIG9mIFtmb28sIGFhYiwgenp6LAotICAgICAqIGFhYWFiXSwgdGhlIGFycmF5IG9mIFN0cmluZ3MgcmV0dXJuZWQgYnkgZ3JlcCB3b3VsZCBiZSBbYWFiLCBhYWFhYl0uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc2VhcmNoIEFycmF5IG9mIE9iamVjdHMgdG8gc2VhcmNoCi0gICAgICogQHJldHVybiBBcnJheSBvZiBTdHJpbmdzIHdob3NlIHRvU3RyaW5nKCkgdmFsdWUgbWF0Y2hlcyB0aGlzIHJlZ3VsYXIgZXhwcmVzc2lvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nW10gZ3JlcChPYmplY3RbXSBzZWFyY2gpCi0gICAgewotICAgICAgICAvLyBDcmVhdGUgbmV3IHZlY3RvciB0byBob2xkIHJldHVybiBpdGVtcwotICAgICAgICBWZWN0b3IgdiA9IG5ldyBWZWN0b3IoKTsKLQotICAgICAgICAvLyBUcmF2ZXJzZSBhcnJheSBvZiBvYmplY3RzCi0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc2VhcmNoLmxlbmd0aDsgaSsrKQotICAgICAgICB7Ci0gICAgICAgICAgICAvLyBHZXQgbmV4dCBvYmplY3QgYXMgYSBzdHJpbmcKLSAgICAgICAgICAgIFN0cmluZyBzID0gc2VhcmNoW2ldLnRvU3RyaW5nKCk7Ci0KLSAgICAgICAgICAgIC8vIElmIGl0IG1hdGNoZXMgdGhpcyByZWdleHAsIGFkZCBpdCB0byB0aGUgbGlzdAotICAgICAgICAgICAgaWYgKG1hdGNoKHMpKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIHYuYWRkRWxlbWVudChzKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIFJldHVybiB2ZWN0b3IgYXMgYW4gYXJyYXkgb2Ygc3RyaW5ncwotICAgICAgICBTdHJpbmdbXSByZXQgPSBuZXcgU3RyaW5nW3Yuc2l6ZSgpXTsKLSAgICAgICAgdi5jb3B5SW50byhyZXQpOwotICAgICAgICByZXR1cm4gcmV0OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBjaGFyYWN0ZXIgYXQgaS10aCBwb3NpdGlvbiBpbiB0aGUgPGNvZGU+c2VhcmNoPC9jb2RlPiBzdHJpbmcgaXMgYSBuZXdsaW5lCi0gICAgICovCi0gICAgcHJpdmF0ZSBib29sZWFuIGlzTmV3bGluZShpbnQgaSkKLSAgICB7Ci0gICAgICAgIGNoYXIgbmV4dENoYXIgPSBzZWFyY2guY2hhckF0KGkpOwotCi0gICAgICAgIGlmIChuZXh0Q2hhciA9PSAnXG4nIHx8IG5leHRDaGFyID09ICdccicgfHwgbmV4dENoYXIgPT0gJ1x1MDA4NScKLSAgICAgICAgICAgIHx8IG5leHRDaGFyID09ICdcdTIwMjgnIHx8IG5leHRDaGFyID09ICdcdTIwMjknKQotICAgICAgICB7Ci0gICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb21wYXJlcyB0d28gY2hhcmFjdGVycy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjMSBmaXJzdCBjaGFyYWN0ZXIgdG8gY29tcGFyZS4KLSAgICAgKiBAcGFyYW0gYzIgc2Vjb25kIGNoYXJhY3RlciB0byBjb21wYXJlLgotICAgICAqIEBwYXJhbSBjYXNlSW5kZXBlbmRlbnQgd2hldGhlciBjb21wYXJpc2lvbiBpcyBjYXNlIGluc2Vuc2l0aXZlIG9yIG5vdC4KLSAgICAgKiBAcmV0dXJuIG5lZ2F0aXZlLCAwLCBvciBwb3NpdGl2ZSBpbnRlZ2VyIGFzIHRoZSBmaXJzdCBjaGFyYWN0ZXIKLSAgICAgKiAgICAgICAgIGxlc3MgdGhhbiwgZXF1YWwgdG8sIG9yIGdyZWF0ZXIgdGhlbiB0aGUgc2Vjb25kLgotICAgICAqLwotICAgIHByaXZhdGUgaW50IGNvbXBhcmVDaGFycyhjaGFyIGMxLCBjaGFyIGMyLCBib29sZWFuIGNhc2VJbmRlcGVuZGVudCkKLSAgICB7Ci0gICAgICAgIGlmIChjYXNlSW5kZXBlbmRlbnQpCi0gICAgICAgIHsKLSAgICAgICAgICAgIGMxID0gQ2hhcmFjdGVyLnRvTG93ZXJDYXNlKGMxKTsKLSAgICAgICAgICAgIGMyID0gQ2hhcmFjdGVyLnRvTG93ZXJDYXNlKGMyKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gKChpbnQpYzEgLSAoaW50KWMyKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3JlZ2V4cC9pbnRlcm5hbC9SRUNvbXBpbGVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3JlZ2V4cC9pbnRlcm5hbC9SRUNvbXBpbGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDIzODc0ZWUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9yZWdleHAvaW50ZXJuYWwvUkVDb21waWxlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTUyMCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnJlZ2V4cC5pbnRlcm5hbDsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5yZWdleHAuaW50ZXJuYWwuUkU7Ci1pbXBvcnQgamF2YS51dGlsLkhhc2h0YWJsZTsKLQotLyoqCi0gKiBBIHJlZ3VsYXIgZXhwcmVzc2lvbiBjb21waWxlciBjbGFzcy4gIFRoaXMgY2xhc3MgY29tcGlsZXMgYSBwYXR0ZXJuIHN0cmluZyBpbnRvIGEKLSAqIHJlZ3VsYXIgZXhwcmVzc2lvbiBwcm9ncmFtIGludGVycHJldGFibGUgYnkgdGhlIFJFIGV2YWx1YXRvciBjbGFzcy4gIFRoZSAncmVjb21waWxlJwotICogY29tbWFuZCBsaW5lIHRvb2wgdXNlcyB0aGlzIGNvbXBpbGVyIHRvIHByZS1jb21waWxlIHJlZ3VsYXIgZXhwcmVzc2lvbnMgZm9yIHVzZQotICogd2l0aCBSRS4gIEZvciBhIGRlc2NyaXB0aW9uIG9mIHRoZSBzeW50YXggYWNjZXB0ZWQgYnkgUkVDb21waWxlciBhbmQgd2hhdCB5b3UgY2FuCi0gKiBkbyB3aXRoIHJlZ3VsYXIgZXhwcmVzc2lvbnMsIHNlZSB0aGUgZG9jdW1lbnRhdGlvbiBmb3IgdGhlIFJFIG1hdGNoZXIgY2xhc3MuCi0gKgotICogQHNlZSBSRQotICogQHNlZSByZWNvbXBpbGUKLSAqCi0gKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzpqb25sQG11cHBldGxhYnMuY29tIj5Kb25hdGhhbiBMb2NrZTwvYT4KLSAqIEBhdXRob3IgPGEgaHJlZj0ibWFpbHRvOmdob2xhbUB4dHJhLmNvLm56Ij5NaWNoYWVsIE1jQ2FsbHVtPC9hPgotICovCi1wdWJsaWMgY2xhc3MgUkVDb21waWxlcgotewotICAgIC8vIFRoZSBjb21waWxlZCBwcm9ncmFtCi0gICAgY2hhcltdIGluc3RydWN0aW9uOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoZSBjb21waWxlZCBSRSAncHJvZ3JhbScgaW5zdHJ1Y3Rpb24gYnVmZmVyCi0gICAgaW50IGxlbkluc3RydWN0aW9uOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoZSBhbW91bnQgb2YgdGhlIHByb2dyYW0gYnVmZmVyIGN1cnJlbnRseSBpbiB1c2UKLQotICAgIC8vIElucHV0IHN0YXRlIGZvciBjb21waWxpbmcgcmVndWxhciBleHByZXNzaW9uCi0gICAgU3RyaW5nIHBhdHRlcm47ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIElucHV0IHN0cmluZwotICAgIGludCBsZW47ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBMZW5ndGggb2YgdGhlIHBhdHRlcm4gc3RyaW5nCi0gICAgaW50IGlkeDsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEN1cnJlbnQgaW5wdXQgaW5kZXggaW50byBhYwotICAgIGludCBwYXJlbnM7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUb3RhbCBudW1iZXIgb2YgcGFyZW4gcGFpcnMKLQotICAgIC8vIE5vZGUgZmxhZ3MKLSAgICBzdGF0aWMgZmluYWwgaW50IE5PREVfTk9STUFMICAgPSAwOyAgICAgICAgICAgICAgICAgLy8gTm8gZmxhZ3MgKG5vdGhpbmcgc3BlY2lhbCkKLSAgICBzdGF0aWMgZmluYWwgaW50IE5PREVfTlVMTEFCTEUgPSAxOyAgICAgICAgICAgICAgICAgLy8gVHJ1ZSBpZiBub2RlIGlzIHBvdGVudGlhbGx5IG51bGwKLSAgICBzdGF0aWMgZmluYWwgaW50IE5PREVfVE9QTEVWRUwgPSAyOyAgICAgICAgICAgICAgICAgLy8gVHJ1ZSBpZiB0b3AgbGV2ZWwgZXhwcgotCi0gICAgLy8gU3BlY2lhbCB0eXBlcyBvZiAnZXNjYXBlcycKLSAgICBzdGF0aWMgZmluYWwgaW50IEVTQ19NQVNLICAgICAgPSAweGZmZmYwOyAgICAgICAgICAgLy8gRXNjYXBlIGNvbXBsZXhpdHkgbWFzawotICAgIHN0YXRpYyBmaW5hbCBpbnQgRVNDX0JBQ0tSRUYgICA9IDB4ZmZmZmY7ICAgICAgICAgICAvLyBFc2NhcGUgaXMgcmVhbGx5IGEgYmFja3JlZmVyZW5jZQotICAgIHN0YXRpYyBmaW5hbCBpbnQgRVNDX0NPTVBMRVggICA9IDB4ZmZmZmU7ICAgICAgICAgICAvLyBFc2NhcGUgaXNuJ3QgcmVhbGx5IGEgdHJ1ZSBjaGFyYWN0ZXIKLSAgICBzdGF0aWMgZmluYWwgaW50IEVTQ19DTEFTUyAgICAgPSAweGZmZmZkOyAgICAgICAgICAgLy8gRXNjYXBlIHJlcHJlc2VudHMgYSB3aG9sZSBjbGFzcyBvZiBjaGFyYWN0ZXJzCi0KLSAgICAvLyB7bSxufSBzdGFja3MKLSAgICBpbnQgbWF4QnJhY2tldHMgPSAxMDsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTWF4aW11bSBudW1iZXIgb2YgYnJhY2tldCBwYWlycwotICAgIHN0YXRpYyBmaW5hbCBpbnQgYnJhY2tldFVuYm91bmRlZCA9IC0xOyAgICAgICAgICAgICAvLyBVbmJvdW5kZWQgdmFsdWUKLSAgICBpbnQgYnJhY2tldHMgPSAwOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTnVtYmVyIG9mIGJyYWNrZXQgc2V0cwotICAgIGludFtdIGJyYWNrZXRTdGFydCA9IG51bGw7ICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTdGFydGluZyBwb2ludAotICAgIGludFtdIGJyYWNrZXRFbmQgPSBudWxsOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBFbmRpbmcgcG9pbnQKLSAgICBpbnRbXSBicmFja2V0TWluID0gbnVsbDsgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTWluaW11bSBudW1iZXIgb2YgbWF0Y2hlcwotICAgIGludFtdIGJyYWNrZXRPcHQgPSBudWxsOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBBZGRpdGlvbmFsIG9wdGlvbmFsIG1hdGNoZXMKLQotICAgIC8vIExvb2t1cCB0YWJsZSBmb3IgUE9TSVggY2hhcmFjdGVyIGNsYXNzIG5hbWVzCi0gICAgc3RhdGljIEhhc2h0YWJsZSBoYXNoUE9TSVggPSBuZXcgSGFzaHRhYmxlKCk7Ci0gICAgc3RhdGljCi0gICAgewotICAgICAgICBoYXNoUE9TSVgucHV0KCJhbG51bSIsICAgICBuZXcgQ2hhcmFjdGVyKFJFLlBPU0lYX0NMQVNTX0FMTlVNKSk7Ci0gICAgICAgIGhhc2hQT1NJWC5wdXQoImFscGhhIiwgICAgIG5ldyBDaGFyYWN0ZXIoUkUuUE9TSVhfQ0xBU1NfQUxQSEEpKTsKLSAgICAgICAgaGFzaFBPU0lYLnB1dCgiYmxhbmsiLCAgICAgbmV3IENoYXJhY3RlcihSRS5QT1NJWF9DTEFTU19CTEFOSykpOwotICAgICAgICBoYXNoUE9TSVgucHV0KCJjbnRybCIsICAgICBuZXcgQ2hhcmFjdGVyKFJFLlBPU0lYX0NMQVNTX0NOVFJMKSk7Ci0gICAgICAgIGhhc2hQT1NJWC5wdXQoImRpZ2l0IiwgICAgIG5ldyBDaGFyYWN0ZXIoUkUuUE9TSVhfQ0xBU1NfRElHSVQpKTsKLSAgICAgICAgaGFzaFBPU0lYLnB1dCgiZ3JhcGgiLCAgICAgbmV3IENoYXJhY3RlcihSRS5QT1NJWF9DTEFTU19HUkFQSCkpOwotICAgICAgICBoYXNoUE9TSVgucHV0KCJsb3dlciIsICAgICBuZXcgQ2hhcmFjdGVyKFJFLlBPU0lYX0NMQVNTX0xPV0VSKSk7Ci0gICAgICAgIGhhc2hQT1NJWC5wdXQoInByaW50IiwgICAgIG5ldyBDaGFyYWN0ZXIoUkUuUE9TSVhfQ0xBU1NfUFJJTlQpKTsKLSAgICAgICAgaGFzaFBPU0lYLnB1dCgicHVuY3QiLCAgICAgbmV3IENoYXJhY3RlcihSRS5QT1NJWF9DTEFTU19QVU5DVCkpOwotICAgICAgICBoYXNoUE9TSVgucHV0KCJzcGFjZSIsICAgICBuZXcgQ2hhcmFjdGVyKFJFLlBPU0lYX0NMQVNTX1NQQUNFKSk7Ci0gICAgICAgIGhhc2hQT1NJWC5wdXQoInVwcGVyIiwgICAgIG5ldyBDaGFyYWN0ZXIoUkUuUE9TSVhfQ0xBU1NfVVBQRVIpKTsKLSAgICAgICAgaGFzaFBPU0lYLnB1dCgieGRpZ2l0IiwgICAgbmV3IENoYXJhY3RlcihSRS5QT1NJWF9DTEFTU19YRElHSVQpKTsKLSAgICAgICAgaGFzaFBPU0lYLnB1dCgiamF2YXN0YXJ0IiwgbmV3IENoYXJhY3RlcihSRS5QT1NJWF9DTEFTU19KU1RBUlQpKTsKLSAgICAgICAgaGFzaFBPU0lYLnB1dCgiamF2YXBhcnQiLCAgbmV3IENoYXJhY3RlcihSRS5QT1NJWF9DTEFTU19KUEFSVCkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdG9yLiAgQ3JlYXRlcyAoaW5pdGlhbGx5IGVtcHR5KSBzdG9yYWdlIGZvciBhIHJlZ3VsYXIgZXhwcmVzc2lvbiBwcm9ncmFtLgotICAgICAqLwotICAgIHB1YmxpYyBSRUNvbXBpbGVyKCkKLSAgICB7Ci0gICAgICAgIC8vIFN0YXJ0IG9mZiB3aXRoIGEgZ2VuZXJvdXMsIHlldCByZWFzb25hYmxlLCBpbml0aWFsIHNpemUKLSAgICAgICAgaW5zdHJ1Y3Rpb24gPSBuZXcgY2hhclsxMjhdOwotICAgICAgICBsZW5JbnN0cnVjdGlvbiA9IDA7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRW5zdXJlcyB0aGF0IG4gbW9yZSBjaGFyYWN0ZXJzIGNhbiBmaXQgaW4gdGhlIHByb2dyYW0gYnVmZmVyLgotICAgICAqIElmIG4gbW9yZSBjYW4ndCBmaXQsIHRoZW4gdGhlIHNpemUgaXMgZG91YmxlZCB1bnRpbCBpdCBjYW4uCi0gICAgICogQHBhcmFtIG4gTnVtYmVyIG9mIGFkZGl0aW9uYWwgY2hhcmFjdGVycyB0byBlbnN1cmUgd2lsbCBmaXQuCi0gICAgICovCi0gICAgdm9pZCBlbnN1cmUoaW50IG4pCi0gICAgewotICAgICAgICAvLyBHZXQgY3VycmVudCBwcm9ncmFtIGxlbmd0aAotICAgICAgICBpbnQgY3VybGVuID0gaW5zdHJ1Y3Rpb24ubGVuZ3RoOwotCi0gICAgICAgIC8vIElmIHRoZSBjdXJyZW50IGxlbmd0aCArIG4gbW9yZSBpcyB0b28gbXVjaAotICAgICAgICBpZiAobGVuSW5zdHJ1Y3Rpb24gKyBuID49IGN1cmxlbikKLSAgICAgICAgewotICAgICAgICAgICAgLy8gRG91YmxlIHRoZSBzaXplIG9mIHRoZSBwcm9ncmFtIGFycmF5IHVudGlsIG4gbW9yZSB3aWxsIGZpdAotICAgICAgICAgICAgd2hpbGUgKGxlbkluc3RydWN0aW9uICsgbiA+PSBjdXJsZW4pCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgY3VybGVuICo9IDI7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIEFsbG9jYXRlIG5ldyBwcm9ncmFtIGFycmF5IGFuZCBtb3ZlIGRhdGEgaW50byBpdAotICAgICAgICAgICAgY2hhcltdIG5ld0luc3RydWN0aW9uID0gbmV3IGNoYXJbY3VybGVuXTsKLSAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoaW5zdHJ1Y3Rpb24sIDAsIG5ld0luc3RydWN0aW9uLCAwLCBsZW5JbnN0cnVjdGlvbik7Ci0gICAgICAgICAgICBpbnN0cnVjdGlvbiA9IG5ld0luc3RydWN0aW9uOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRW1pdCBhIHNpbmdsZSBjaGFyYWN0ZXIgaW50byB0aGUgcHJvZ3JhbSBzdHJlYW0uCi0gICAgICogQHBhcmFtIGMgQ2hhcmFjdGVyIHRvIGFkZAotICAgICAqLwotICAgIHZvaWQgZW1pdChjaGFyIGMpCi0gICAgewotICAgICAgICAvLyBNYWtlIHJvb20gZm9yIGNoYXJhY3RlcgotICAgICAgICBlbnN1cmUoMSk7Ci0KLSAgICAgICAgLy8gQWRkIGNoYXJhY3RlcgotICAgICAgICBpbnN0cnVjdGlvbltsZW5JbnN0cnVjdGlvbisrXSA9IGM7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSW5zZXJ0cyBhIG5vZGUgd2l0aCBhIGdpdmVuIG9wY29kZSBhbmQgb3BkYXRhIGF0IGluc2VydEF0LiAgVGhlIG5vZGUgcmVsYXRpdmUgbmV4dAotICAgICAqIHBvaW50ZXIgaXMgaW5pdGlhbGl6ZWQgdG8gMC4KLSAgICAgKiBAcGFyYW0gb3Bjb2RlIE9wY29kZSBmb3IgbmV3IG5vZGUKLSAgICAgKiBAcGFyYW0gb3BkYXRhIE9wZGF0YSBmb3IgbmV3IG5vZGUgKG9ubHkgdGhlIGxvdyAxNiBiaXRzIGFyZSBjdXJyZW50bHkgdXNlZCkKLSAgICAgKiBAcGFyYW0gaW5zZXJ0QXQgSW5kZXggYXQgd2hpY2ggdG8gaW5zZXJ0IHRoZSBuZXcgbm9kZSBpbiB0aGUgcHJvZ3JhbQotICAgICAqLwotICAgIHZvaWQgbm9kZUluc2VydChjaGFyIG9wY29kZSwgaW50IG9wZGF0YSwgaW50IGluc2VydEF0KQotICAgIHsKLSAgICAgICAgLy8gTWFrZSByb29tIGZvciBhIG5ldyBub2RlCi0gICAgICAgIGVuc3VyZShSRS5ub2RlU2l6ZSk7Ci0KLSAgICAgICAgLy8gTW92ZSBldmVyeXRoaW5nIGZyb20gaW5zZXJ0QXQgdG8gdGhlIGVuZCBkb3duIG5vZGVTaXplIGVsZW1lbnRzCi0gICAgICAgIFN5c3RlbS5hcnJheWNvcHkoaW5zdHJ1Y3Rpb24sIGluc2VydEF0LCBpbnN0cnVjdGlvbiwgaW5zZXJ0QXQgKyBSRS5ub2RlU2l6ZSwgbGVuSW5zdHJ1Y3Rpb24gLSBpbnNlcnRBdCk7Ci0gICAgICAgIGluc3RydWN0aW9uW2luc2VydEF0ICsgUkUub2Zmc2V0T3Bjb2RlXSA9IG9wY29kZTsKLSAgICAgICAgaW5zdHJ1Y3Rpb25baW5zZXJ0QXQgKyBSRS5vZmZzZXRPcGRhdGFdID0gKGNoYXIpb3BkYXRhOwotICAgICAgICBpbnN0cnVjdGlvbltpbnNlcnRBdCArIFJFLm9mZnNldE5leHRdID0gMDsKLSAgICAgICAgbGVuSW5zdHJ1Y3Rpb24gKz0gUkUubm9kZVNpemU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQXBwZW5kcyBhIG5vZGUgdG8gdGhlIGVuZCBvZiBhIG5vZGUgY2hhaW4KLSAgICAgKiBAcGFyYW0gbm9kZSBTdGFydCBvZiBub2RlIGNoYWluIHRvIHRyYXZlcnNlCi0gICAgICogQHBhcmFtIHBvaW50VG8gTm9kZSB0byBoYXZlIHRoZSB0YWlsIG9mIHRoZSBjaGFpbiBwb2ludCB0bwotICAgICAqLwotICAgIHZvaWQgc2V0TmV4dE9mRW5kKGludCBub2RlLCBpbnQgcG9pbnRUbykKLSAgICB7Ci0gICAgICAgIC8vIFRyYXZlcnNlIHRoZSBjaGFpbiB1bnRpbCB0aGUgbmV4dCBvZmZzZXQgaXMgMAotICAgICAgICBpbnQgbmV4dCA9IGluc3RydWN0aW9uW25vZGUgKyBSRS5vZmZzZXROZXh0XTsKLSAgICAgICAgLy8gd2hpbGUgdGhlICdub2RlJyBpcyBub3QgdGhlIGxhc3QgaW4gdGhlIGNoYWluCi0gICAgICAgIC8vIGFuZCB0aGUgJ25vZGUnIGlzIG5vdCB0aGUgbGFzdCBpbiB0aGUgcHJvZ3JhbS4KLSAgICAgICAgd2hpbGUgKCBuZXh0ICE9IDAgJiYgbm9kZSA8IGxlbkluc3RydWN0aW9uICkKLSAgICAgICAgewotICAgICAgICAgICAgLy8gaWYgdGhlIG5vZGUgd2UgYXJlIHN1cHBvc2VkIHRvIHBvaW50IHRvIGlzIGluIHRoZSBjaGFpbiB0aGVuCi0gICAgICAgICAgICAvLyBwb2ludCB0byB0aGUgZW5kIG9mIHRoZSBwcm9ncmFtIGluc3RlYWQuCi0gICAgICAgICAgICAvLyBNaWNoYWVsIE1jQ2FsbHVtIDxnaG9sYW1AeHRyYS5jby5uej4KLSAgICAgICAgICAgIC8vIEZJWE1FOiAvLyBUaGlzIGlzIGEgX2hhY2tfIHRvIHN0b3AgaW5maW5pdGUgcHJvZ3JhbXMuCi0gICAgICAgICAgICAvLyBJIGJlbGlldmUgdGhhdCB0aGUgaW1wbGVtZW50YXRpb24gb2YgdGhlIHJlbHVjdGFudCBtYXRjaGVzIGlzIHdyb25nIGJ1dAotICAgICAgICAgICAgLy8gaGF2ZSBub3Qgd29ya2VkIG91dCBhIGJldHRlciB3YXkgeWV0LgotICAgICAgICAgICAgaWYgKCBub2RlID09IHBvaW50VG8gKSB7Ci0gICAgICAgICAgICAgIHBvaW50VG8gPSBsZW5JbnN0cnVjdGlvbjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIG5vZGUgKz0gbmV4dDsKLSAgICAgICAgICAgIG5leHQgPSBpbnN0cnVjdGlvbltub2RlICsgUkUub2Zmc2V0TmV4dF07Ci0gICAgICAgIH0KLSAgICAgICAgLy8gaWYgd2UgaGF2ZSByZWFjaGVkIHRoZSBlbmQgb2YgdGhlIHByb2dyYW0gdGhlbiBkb250IHNldCB0aGUgcG9pbnRUby4KLSAgICAgICAgLy8gaW0gbm90IHN1cmUgaWYgdGhpcyB3aWxsIGJyZWFrIGFueSB0aGluZyBidXQgcGFzc2VzIGFsbCB0aGUgdGVzdHMuCi0gICAgICAgIGlmICggbm9kZSA8IGxlbkluc3RydWN0aW9uICkgewotICAgICAgICAgICAgLy8gUG9pbnQgdGhlIGxhc3Qgbm9kZSBpbiB0aGUgY2hhaW4gdG8gcG9pbnRUby4KLSAgICAgICAgICAgIGluc3RydWN0aW9uW25vZGUgKyBSRS5vZmZzZXROZXh0XSA9IChjaGFyKShzaG9ydCkocG9pbnRUbyAtIG5vZGUpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQWRkcyBhIG5ldyBub2RlCi0gICAgICogQHBhcmFtIG9wY29kZSBPcGNvZGUgZm9yIG5vZGUKLSAgICAgKiBAcGFyYW0gb3BkYXRhIE9wZGF0YSBmb3Igbm9kZSAob25seSB0aGUgbG93IDE2IGJpdHMgYXJlIGN1cnJlbnRseSB1c2VkKQotICAgICAqIEByZXR1cm4gSW5kZXggb2YgbmV3IG5vZGUgaW4gcHJvZ3JhbQotICAgICAqLwotICAgIGludCBub2RlKGNoYXIgb3Bjb2RlLCBpbnQgb3BkYXRhKQotICAgIHsKLSAgICAgICAgLy8gTWFrZSByb29tIGZvciBhIG5ldyBub2RlCi0gICAgICAgIGVuc3VyZShSRS5ub2RlU2l6ZSk7Ci0KLSAgICAgICAgLy8gQWRkIG5ldyBub2RlIGF0IGVuZAotICAgICAgICBpbnN0cnVjdGlvbltsZW5JbnN0cnVjdGlvbiArIFJFLm9mZnNldE9wY29kZV0gPSBvcGNvZGU7Ci0gICAgICAgIGluc3RydWN0aW9uW2xlbkluc3RydWN0aW9uICsgUkUub2Zmc2V0T3BkYXRhXSA9IChjaGFyKW9wZGF0YTsKLSAgICAgICAgaW5zdHJ1Y3Rpb25bbGVuSW5zdHJ1Y3Rpb24gKyBSRS5vZmZzZXROZXh0XSA9IDA7Ci0gICAgICAgIGxlbkluc3RydWN0aW9uICs9IFJFLm5vZGVTaXplOwotCi0gICAgICAgIC8vIFJldHVybiBpbmRleCBvZiBuZXcgbm9kZQotICAgICAgICByZXR1cm4gbGVuSW5zdHJ1Y3Rpb24gLSBSRS5ub2RlU2l6ZTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFRocm93cyBhIG5ldyBpbnRlcm5hbCBlcnJvciBleGNlcHRpb24KLSAgICAgKiBAZXhjZXB0aW9uIEVycm9yIFRocm93biBpbiB0aGUgZXZlbnQgb2YgYW4gaW50ZXJuYWwgZXJyb3IuCi0gICAgICovCi0gICAgdm9pZCBpbnRlcm5hbEVycm9yKCkgdGhyb3dzIEVycm9yCi0gICAgewotICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIkludGVybmFsIGVycm9yISIpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRocm93cyBhIG5ldyBzeW50YXggZXJyb3IgZXhjZXB0aW9uCi0gICAgICogQGV4Y2VwdGlvbiBSRVN5bnRheEV4Y2VwdGlvbiBUaHJvd24gaWYgdGhlIHJlZ3VsYXIgZXhwcmVzc2lvbiBoYXMgaW52YWxpZCBzeW50YXguCi0gICAgICovCi0gICAgdm9pZCBzeW50YXhFcnJvcihTdHJpbmcgcykgdGhyb3dzIFJFU3ludGF4RXhjZXB0aW9uCi0gICAgewotICAgICAgICB0aHJvdyBuZXcgUkVTeW50YXhFeGNlcHRpb24ocyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQWxsb2NhdGUgc3RvcmFnZSBmb3IgYnJhY2tldHMgb25seSBhcyBuZWVkZWQKLSAgICAgKi8KLSAgICB2b2lkIGFsbG9jQnJhY2tldHMoKQotICAgIHsKLSAgICAgICAgLy8gQWxsb2NhdGUgYnJhY2tldCBzdGFja3MgaWYgbm90IGFscmVhZHkgZG9uZQotICAgICAgICBpZiAoYnJhY2tldFN0YXJ0ID09IG51bGwpCi0gICAgICAgIHsKLSAgICAgICAgICAgIC8vIEFsbG9jYXRlIHN0b3JhZ2UKLSAgICAgICAgICAgIGJyYWNrZXRTdGFydCA9IG5ldyBpbnRbbWF4QnJhY2tldHNdOwotICAgICAgICAgICAgYnJhY2tldEVuZCAgID0gbmV3IGludFttYXhCcmFja2V0c107Ci0gICAgICAgICAgICBicmFja2V0TWluICAgPSBuZXcgaW50W21heEJyYWNrZXRzXTsKLSAgICAgICAgICAgIGJyYWNrZXRPcHQgICA9IG5ldyBpbnRbbWF4QnJhY2tldHNdOwotCi0gICAgICAgICAgICAvLyBJbml0aWFsaXplIHRvIGludmFsaWQgdmFsdWVzCi0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1heEJyYWNrZXRzOyBpKyspCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgYnJhY2tldFN0YXJ0W2ldID0gYnJhY2tldEVuZFtpXSA9IGJyYWNrZXRNaW5baV0gPSBicmFja2V0T3B0W2ldID0gLTE7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKiogRW5sYXJnZSBzdG9yYWdlIGZvciBicmFja2V0cyBvbmx5IGFzIG5lZWRlZC4gKi8KLSAgICBzeW5jaHJvbml6ZWQgdm9pZCByZWFsbG9jQnJhY2tldHMoKSB7Ci0gICAgICAgIC8vIHRyaWNrIHRoZSB0cmlja3kKLSAgICAgICAgaWYgKGJyYWNrZXRTdGFydCA9PSBudWxsKSB7Ci0gICAgICAgICAgICBhbGxvY0JyYWNrZXRzKCk7Ci0gICAgICAgIH0KLQotICAgICAgICBpbnQgbmV3X3NpemUgPSBtYXhCcmFja2V0cyAqIDI7Ci0gICAgICAgIGludFtdIG5ld19iUyA9IG5ldyBpbnRbbmV3X3NpemVdOwotICAgICAgICBpbnRbXSBuZXdfYkUgPSBuZXcgaW50W25ld19zaXplXTsKLSAgICAgICAgaW50W10gbmV3X2JNID0gbmV3IGludFtuZXdfc2l6ZV07Ci0gICAgICAgIGludFtdIG5ld19iTyA9IG5ldyBpbnRbbmV3X3NpemVdOwotICAgICAgICAvLyBJbml0aWFsaXplIHRvIGludmFsaWQgdmFsdWVzCi0gICAgICAgIGZvciAoaW50IGk9YnJhY2tldHM7IGk8bmV3X3NpemU7IGkrKykgewotICAgICAgICAgICAgbmV3X2JTW2ldID0gbmV3X2JFW2ldID0gbmV3X2JNW2ldID0gbmV3X2JPW2ldID0gLTE7Ci0gICAgICAgIH0KLSAgICAgICAgU3lzdGVtLmFycmF5Y29weShicmFja2V0U3RhcnQsMCwgbmV3X2JTLDAsIGJyYWNrZXRzKTsKLSAgICAgICAgU3lzdGVtLmFycmF5Y29weShicmFja2V0RW5kLDAsICAgbmV3X2JFLDAsIGJyYWNrZXRzKTsKLSAgICAgICAgU3lzdGVtLmFycmF5Y29weShicmFja2V0TWluLDAsICAgbmV3X2JNLDAsIGJyYWNrZXRzKTsKLSAgICAgICAgU3lzdGVtLmFycmF5Y29weShicmFja2V0T3B0LDAsICAgbmV3X2JPLDAsIGJyYWNrZXRzKTsKLSAgICAgICAgYnJhY2tldFN0YXJ0ID0gbmV3X2JTOwotICAgICAgICBicmFja2V0RW5kICAgPSBuZXdfYkU7Ci0gICAgICAgIGJyYWNrZXRNaW4gICA9IG5ld19iTTsKLSAgICAgICAgYnJhY2tldE9wdCAgID0gbmV3X2JPOwotICAgICAgICBtYXhCcmFja2V0cyAgPSBuZXdfc2l6ZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBNYXRjaCBicmFja2V0IHttLG59IGV4cHJlc3Npb24gcHV0IHJlc3VsdHMgaW4gYnJhY2tldCBtZW1iZXIgdmFyaWFibGVzCi0gICAgICogQGV4Y2VwdGlvbiBSRVN5bnRheEV4Y2VwdGlvbiBUaHJvd24gaWYgdGhlIHJlZ3VsYXIgZXhwcmVzc2lvbiBoYXMgaW52YWxpZCBzeW50YXguCi0gICAgICovCi0gICAgdm9pZCBicmFja2V0KCkgdGhyb3dzIFJFU3ludGF4RXhjZXB0aW9uCi0gICAgewotICAgICAgICAvLyBDdXJyZW50IGNoYXJhY3RlciBtdXN0IGJlIGEgJ3snCi0gICAgICAgIGlmIChpZHggPj0gbGVuIHx8IHBhdHRlcm4uY2hhckF0KGlkeCsrKSAhPSAneycpCi0gICAgICAgIHsKLSAgICAgICAgICAgIGludGVybmFsRXJyb3IoKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIE5leHQgY2hhciBtdXN0IGJlIGEgZGlnaXQKLSAgICAgICAgaWYgKGlkeCA+PSBsZW4gfHwgIUNoYXJhY3Rlci5pc0RpZ2l0KHBhdHRlcm4uY2hhckF0KGlkeCkpKQotICAgICAgICB7Ci0gICAgICAgICAgICBzeW50YXhFcnJvcigiRXhwZWN0ZWQgZGlnaXQiKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIEdldCBtaW4gKCdtJyBvZiB7bSxufSkgbnVtYmVyCi0gICAgICAgIFN0cmluZ0J1ZmZlciBudW1iZXIgPSBuZXcgU3RyaW5nQnVmZmVyKCk7Ci0gICAgICAgIHdoaWxlIChpZHggPCBsZW4gJiYgQ2hhcmFjdGVyLmlzRGlnaXQocGF0dGVybi5jaGFyQXQoaWR4KSkpCi0gICAgICAgIHsKLSAgICAgICAgICAgIG51bWJlci5hcHBlbmQocGF0dGVybi5jaGFyQXQoaWR4KyspKTsKLSAgICAgICAgfQotICAgICAgICB0cnkKLSAgICAgICAgewotICAgICAgICAgICAgYnJhY2tldE1pblticmFja2V0c10gPSBJbnRlZ2VyLnBhcnNlSW50KG51bWJlci50b1N0cmluZygpKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGUpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHN5bnRheEVycm9yKCJFeHBlY3RlZCB2YWxpZCBudW1iZXIiKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIElmIG91dCBvZiBpbnB1dCwgZmFpbAotICAgICAgICBpZiAoaWR4ID49IGxlbikKLSAgICAgICAgewotICAgICAgICAgICAgc3ludGF4RXJyb3IoIkV4cGVjdGVkIGNvbW1hIG9yIHJpZ2h0IGJyYWNrZXQiKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIElmIGVuZCBvZiBleHByLCBvcHRpb25hbCBsaW1pdCBpcyAwCi0gICAgICAgIGlmIChwYXR0ZXJuLmNoYXJBdChpZHgpID09ICd9JykKLSAgICAgICAgewotICAgICAgICAgICAgaWR4Kys7Ci0gICAgICAgICAgICBicmFja2V0T3B0W2JyYWNrZXRzXSA9IDA7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBNdXN0IGhhdmUgYXQgbGVhc3Qge20sfSBhbmQgbWF5YmUge20sbn0uCi0gICAgICAgIGlmIChpZHggPj0gbGVuIHx8IHBhdHRlcm4uY2hhckF0KGlkeCsrKSAhPSAnLCcpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHN5bnRheEVycm9yKCJFeHBlY3RlZCBjb21tYSIpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gSWYgb3V0IG9mIGlucHV0LCBmYWlsCi0gICAgICAgIGlmIChpZHggPj0gbGVuKQotICAgICAgICB7Ci0gICAgICAgICAgICBzeW50YXhFcnJvcigiRXhwZWN0ZWQgY29tbWEgb3IgcmlnaHQgYnJhY2tldCIpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gSWYge20sfSBtYXggaXMgdW5saW1pdGVkCi0gICAgICAgIGlmIChwYXR0ZXJuLmNoYXJBdChpZHgpID09ICd9JykKLSAgICAgICAgewotICAgICAgICAgICAgaWR4Kys7Ci0gICAgICAgICAgICBicmFja2V0T3B0W2JyYWNrZXRzXSA9IGJyYWNrZXRVbmJvdW5kZWQ7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBOZXh0IGNoYXIgbXVzdCBiZSBhIGRpZ2l0Ci0gICAgICAgIGlmIChpZHggPj0gbGVuIHx8ICFDaGFyYWN0ZXIuaXNEaWdpdChwYXR0ZXJuLmNoYXJBdChpZHgpKSkKLSAgICAgICAgewotICAgICAgICAgICAgc3ludGF4RXJyb3IoIkV4cGVjdGVkIGRpZ2l0Iik7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBHZXQgbWF4IG51bWJlcgotICAgICAgICBudW1iZXIuc2V0TGVuZ3RoKDApOwotICAgICAgICB3aGlsZSAoaWR4IDwgbGVuICYmIENoYXJhY3Rlci5pc0RpZ2l0KHBhdHRlcm4uY2hhckF0KGlkeCkpKQotICAgICAgICB7Ci0gICAgICAgICAgICBudW1iZXIuYXBwZW5kKHBhdHRlcm4uY2hhckF0KGlkeCsrKSk7Ci0gICAgICAgIH0KLSAgICAgICAgdHJ5Ci0gICAgICAgIHsKLSAgICAgICAgICAgIGJyYWNrZXRPcHRbYnJhY2tldHNdID0gSW50ZWdlci5wYXJzZUludChudW1iZXIudG9TdHJpbmcoKSkgLSBicmFja2V0TWluW2JyYWNrZXRzXTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGUpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHN5bnRheEVycm9yKCJFeHBlY3RlZCB2YWxpZCBudW1iZXIiKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIE9wdGlvbmFsIHJlcGV0aXRpb25zIG11c3QgYmUgPj0gMAotICAgICAgICBpZiAoYnJhY2tldE9wdFticmFja2V0c10gPCAwKQotICAgICAgICB7Ci0gICAgICAgICAgICBzeW50YXhFcnJvcigiQmFkIHJhbmdlIik7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBNdXN0IGhhdmUgY2xvc2UgYnJhY2UKLSAgICAgICAgaWYgKGlkeCA+PSBsZW4gfHwgcGF0dGVybi5jaGFyQXQoaWR4KyspICE9ICd9JykKLSAgICAgICAgewotICAgICAgICAgICAgc3ludGF4RXJyb3IoIk1pc3NpbmcgY2xvc2UgYnJhY2UiKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIE1hdGNoIGFuIGVzY2FwZSBzZXF1ZW5jZS4gIEhhbmRsZXMgcXVvdGVkIGNoYXJzIGFuZCBvY3RhbCBlc2NhcGVzIGFzIHdlbGwKLSAgICAgKiBhcyBub3JtYWwgZXNjYXBlIGNoYXJhY3RlcnMuICBBbHdheXMgYWR2YW5jZXMgdGhlIGlucHV0IHN0cmVhbSBieSB0aGUKLSAgICAgKiByaWdodCBhbW91bnQuIFRoaXMgY29kZSAidW5kZXJzdGFuZHMiIHRoZSBzdWJ0bGUgZGlmZmVyZW5jZSBiZXR3ZWVuIGFuCi0gICAgICogb2N0YWwgZXNjYXBlIGFuZCBhIGJhY2tyZWYuICBZb3UgY2FuIGFjY2VzcyB0aGUgdHlwZSBvZiBFU0NfQ0xBU1Mgb3IKLSAgICAgKiBFU0NfQ09NUExFWCBvciBFU0NfQkFDS1JFRiBieSBsb29raW5nIGF0IHBhdHRlcm5baWR4IC0gMV0uCi0gICAgICogQHJldHVybiBFU0NfKiBjb2RlIG9yIGNoYXJhY3RlciBpZiBzaW1wbGUgZXNjYXBlCi0gICAgICogQGV4Y2VwdGlvbiBSRVN5bnRheEV4Y2VwdGlvbiBUaHJvd24gaWYgdGhlIHJlZ3VsYXIgZXhwcmVzc2lvbiBoYXMgaW52YWxpZCBzeW50YXguCi0gICAgICovCi0gICAgaW50IGVzY2FwZSgpIHRocm93cyBSRVN5bnRheEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgLy8gIlNob3VsZG4ndCIgaGFwcGVuCi0gICAgICAgIGlmIChwYXR0ZXJuLmNoYXJBdChpZHgpICE9ICdcXCcpCi0gICAgICAgIHsKLSAgICAgICAgICAgIGludGVybmFsRXJyb3IoKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIEVzY2FwZSBzaG91bGRuJ3Qgb2NjdXIgYXMgbGFzdCBjaGFyYWN0ZXIgaW4gc3RyaW5nIQotICAgICAgICBpZiAoaWR4ICsgMSA9PSBsZW4pCi0gICAgICAgIHsKLSAgICAgICAgICAgIHN5bnRheEVycm9yKCJFc2NhcGUgdGVybWluYXRlcyBzdHJpbmciKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIFN3aXRjaCBvbiBjaGFyYWN0ZXIgYWZ0ZXIgYmFja3NsYXNoCi0gICAgICAgIGlkeCArPSAyOwotICAgICAgICBjaGFyIGVzY2FwZUNoYXIgPSBwYXR0ZXJuLmNoYXJBdChpZHggLSAxKTsKLSAgICAgICAgc3dpdGNoIChlc2NhcGVDaGFyKQotICAgICAgICB7Ci0gICAgICAgICAgICBjYXNlIFJFLkVfQk9VTkQ6Ci0gICAgICAgICAgICBjYXNlIFJFLkVfTkJPVU5EOgotICAgICAgICAgICAgICAgIHJldHVybiBFU0NfQ09NUExFWDsKLQotICAgICAgICAgICAgY2FzZSBSRS5FX0FMTlVNOgotICAgICAgICAgICAgY2FzZSBSRS5FX05BTE5VTToKLSAgICAgICAgICAgIGNhc2UgUkUuRV9TUEFDRToKLSAgICAgICAgICAgIGNhc2UgUkUuRV9OU1BBQ0U6Ci0gICAgICAgICAgICBjYXNlIFJFLkVfRElHSVQ6Ci0gICAgICAgICAgICBjYXNlIFJFLkVfTkRJR0lUOgotICAgICAgICAgICAgICAgIHJldHVybiBFU0NfQ0xBU1M7Ci0KLSAgICAgICAgICAgIGNhc2UgJ3UnOgotICAgICAgICAgICAgY2FzZSAneCc6Ci0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAvLyBFeGFjdCByZXF1aXJlZCBoZXggZGlnaXRzIGZvciBlc2NhcGUgdHlwZQotICAgICAgICAgICAgICAgICAgICBpbnQgaGV4RGlnaXRzID0gKGVzY2FwZUNoYXIgPT0gJ3UnID8gNCA6IDIpOwotCi0gICAgICAgICAgICAgICAgICAgIC8vIFBhcnNlIHVwIHRvIGhleERpZ2l0cyBjaGFyYWN0ZXJzIGZyb20gaW5wdXQKLSAgICAgICAgICAgICAgICAgICAgaW50IHZhbCA9IDA7Ci0gICAgICAgICAgICAgICAgICAgIGZvciAoIDsgaWR4IDwgbGVuICYmIGhleERpZ2l0cy0tID4gMDsgaWR4KyspCi0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIEdldCBjaGFyCi0gICAgICAgICAgICAgICAgICAgICAgICBjaGFyIGMgPSBwYXR0ZXJuLmNoYXJBdChpZHgpOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBJZiBpdCdzIGEgaGV4YWRlY2ltYWwgZGlnaXQgKDAtOSkKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjID49ICcwJyAmJiBjIDw9ICc5JykKLSAgICAgICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBDb21wdXRlIG5ldyB2YWx1ZQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbCA9ICh2YWwgPDwgNCkgKyBjIC0gJzAnOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIElmIGl0J3MgYSBoZXhhZGVjaW1hbCBsZXR0ZXIgKGEtZikKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjID0gQ2hhcmFjdGVyLnRvTG93ZXJDYXNlKGMpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjID49ICdhJyAmJiBjIDw9ICdmJykKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENvbXB1dGUgbmV3IHZhbHVlCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbCA9ICh2YWwgPDwgNCkgKyAoYyAtICdhJykgKyAxMDsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSWYgaXQncyBub3QgYSB2YWxpZCBkaWdpdCBvciBoZXggbGV0dGVyLCB0aGUgZXNjYXBlIG11c3QgYmUgaW52YWxpZAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBiZWNhdXNlIGhleERpZ2l0cyBvZiBpbnB1dCBoYXZlIG5vdCBiZWVuIGFic29yYmVkIHlldC4KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ludGF4RXJyb3IoIkV4cGVjdGVkICIgKyBoZXhEaWdpdHMgKyAiIGhleGFkZWNpbWFsIGRpZ2l0cyBhZnRlciBcXCIgKyBlc2NhcGVDaGFyKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbDsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGNhc2UgJ3QnOgotICAgICAgICAgICAgICAgIHJldHVybiAnXHQnOwotCi0gICAgICAgICAgICBjYXNlICduJzoKLSAgICAgICAgICAgICAgICByZXR1cm4gJ1xuJzsKLQotICAgICAgICAgICAgY2FzZSAncic6Ci0gICAgICAgICAgICAgICAgcmV0dXJuICdccic7Ci0KLSAgICAgICAgICAgIGNhc2UgJ2YnOgotICAgICAgICAgICAgICAgIHJldHVybiAnXGYnOwotCi0gICAgICAgICAgICBjYXNlICcwJzoKLSAgICAgICAgICAgIGNhc2UgJzEnOgotICAgICAgICAgICAgY2FzZSAnMic6Ci0gICAgICAgICAgICBjYXNlICczJzoKLSAgICAgICAgICAgIGNhc2UgJzQnOgotICAgICAgICAgICAgY2FzZSAnNSc6Ci0gICAgICAgICAgICBjYXNlICc2JzoKLSAgICAgICAgICAgIGNhc2UgJzcnOgotICAgICAgICAgICAgY2FzZSAnOCc6Ci0gICAgICAgICAgICBjYXNlICc5JzoKLQotICAgICAgICAgICAgICAgIC8vIEFuIG9jdGFsIGVzY2FwZSBzdGFydHMgd2l0aCBhIDAgb3IgaGFzIHR3byBkaWdpdHMgaW4gYSByb3cKLSAgICAgICAgICAgICAgICBpZiAoKGlkeCA8IGxlbiAmJiBDaGFyYWN0ZXIuaXNEaWdpdChwYXR0ZXJuLmNoYXJBdChpZHgpKSkgfHwgZXNjYXBlQ2hhciA9PSAnMCcpCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAvLyBIYW5kbGUgXG5ubiBvY3RhbCBlc2NhcGVzCi0gICAgICAgICAgICAgICAgICAgIGludCB2YWwgPSBlc2NhcGVDaGFyIC0gJzAnOwotICAgICAgICAgICAgICAgICAgICBpZiAoaWR4IDwgbGVuICYmIENoYXJhY3Rlci5pc0RpZ2l0KHBhdHRlcm4uY2hhckF0KGlkeCkpKQotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICB2YWwgPSAoKHZhbCA8PCAzKSArIChwYXR0ZXJuLmNoYXJBdChpZHgrKykgLSAnMCcpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpZHggPCBsZW4gJiYgQ2hhcmFjdGVyLmlzRGlnaXQocGF0dGVybi5jaGFyQXQoaWR4KSkpCi0gICAgICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsID0gKCh2YWwgPDwgMykgKyAocGF0dGVybi5jaGFyQXQoaWR4KyspIC0gJzAnKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbDsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyBJdCdzIGFjdHVhbGx5IGEgYmFja3JlZmVyZW5jZSAoXFsxLTldKSwgbm90IGFuIGVzY2FwZQotICAgICAgICAgICAgICAgIHJldHVybiBFU0NfQkFDS1JFRjsKLQotICAgICAgICAgICAgZGVmYXVsdDoKLQotICAgICAgICAgICAgICAgIC8vIFNpbXBsZSBxdW90aW5nIG9mIGEgY2hhcmFjdGVyCi0gICAgICAgICAgICAgICAgcmV0dXJuIGVzY2FwZUNoYXI7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb21waWxlIGEgY2hhcmFjdGVyIGNsYXNzCi0gICAgICogQHJldHVybiBJbmRleCBvZiBjbGFzcyBub2RlCi0gICAgICogQGV4Y2VwdGlvbiBSRVN5bnRheEV4Y2VwdGlvbiBUaHJvd24gaWYgdGhlIHJlZ3VsYXIgZXhwcmVzc2lvbiBoYXMgaW52YWxpZCBzeW50YXguCi0gICAgICovCi0gICAgaW50IGNoYXJhY3RlckNsYXNzKCkgdGhyb3dzIFJFU3ludGF4RXhjZXB0aW9uCi0gICAgewotICAgICAgICAvLyBDaGVjayBmb3IgYmFkIGNhbGxpbmcgb3IgZW1wdHkgY2xhc3MKLSAgICAgICAgaWYgKHBhdHRlcm4uY2hhckF0KGlkeCkgIT0gJ1snKQotICAgICAgICB7Ci0gICAgICAgICAgICBpbnRlcm5hbEVycm9yKCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBDaGVjayBmb3IgdW50ZXJtaW5hdGVkIG9yIGVtcHR5IGNsYXNzCi0gICAgICAgIGlmICgoaWR4ICsgMSkgPj0gbGVuIHx8IHBhdHRlcm4uY2hhckF0KCsraWR4KSA9PSAnXScpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHN5bnRheEVycm9yKCJFbXB0eSBvciB1bnRlcm1pbmF0ZWQgY2xhc3MiKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIENoZWNrIGZvciBQT1NJWCBjaGFyYWN0ZXIgY2xhc3MKLSAgICAgICAgaWYgKGlkeCA8IGxlbiAmJiBwYXR0ZXJuLmNoYXJBdChpZHgpID09ICc6JykKLSAgICAgICAgewotICAgICAgICAgICAgLy8gU2tpcCBjb2xvbgotICAgICAgICAgICAgaWR4Kys7Ci0KLSAgICAgICAgICAgIC8vIFBPU0lYIGNoYXJhY3RlciBjbGFzc2VzIGFyZSBkZW5vdGVkIHdpdGggbG93ZXJjYXNlIEFTQ0lJIHN0cmluZ3MKLSAgICAgICAgICAgIGludCBpZHhTdGFydCA9IGlkeDsKLSAgICAgICAgICAgIHdoaWxlIChpZHggPCBsZW4gJiYgcGF0dGVybi5jaGFyQXQoaWR4KSA+PSAnYScgJiYgcGF0dGVybi5jaGFyQXQoaWR4KSA8PSAneicpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgaWR4Kys7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIFNob3VsZCBiZSBhICI6XSIgdG8gdGVybWluYXRlIHRoZSBQT1NJWCBjaGFyYWN0ZXIgY2xhc3MKLSAgICAgICAgICAgIGlmICgoaWR4ICsgMSkgPCBsZW4gJiYgcGF0dGVybi5jaGFyQXQoaWR4KSA9PSAnOicgJiYgcGF0dGVybi5jaGFyQXQoaWR4ICsgMSkgPT0gJ10nKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIC8vIEdldCBjaGFyYWN0ZXIgY2xhc3MKLSAgICAgICAgICAgICAgICBTdHJpbmcgY2hhckNsYXNzID0gcGF0dGVybi5zdWJzdHJpbmcoaWR4U3RhcnQsIGlkeCk7Ci0KLSAgICAgICAgICAgICAgICAvLyBTZWxlY3QgdGhlIFBPU0lYIGNsYXNzIGlkCi0gICAgICAgICAgICAgICAgQ2hhcmFjdGVyIGkgPSAoQ2hhcmFjdGVyKWhhc2hQT1NJWC5nZXQoY2hhckNsYXNzKTsKLSAgICAgICAgICAgICAgICBpZiAoaSAhPSBudWxsKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gTW92ZSBwYXN0IGNvbG9uIGFuZCByaWdodCBicmFja2V0Ci0gICAgICAgICAgICAgICAgICAgIGlkeCArPSAyOwotCi0gICAgICAgICAgICAgICAgICAgIC8vIFJldHVybiBuZXcgUE9TSVggY2hhcmFjdGVyIGNsYXNzIG5vZGUKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5vZGUoUkUuT1BfUE9TSVhDTEFTUywgaS5jaGFyVmFsdWUoKSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHN5bnRheEVycm9yKCJJbnZhbGlkIFBPU0lYIGNoYXJhY3RlciBjbGFzcyAnIiArIGNoYXJDbGFzcyArICInIik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBzeW50YXhFcnJvcigiSW52YWxpZCBQT1NJWCBjaGFyYWN0ZXIgY2xhc3Mgc3ludGF4Iik7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBUcnkgdG8gYnVpbGQgYSBjbGFzcy4gIENyZWF0ZSBPUF9BTllPRiBub2RlCi0gICAgICAgIGludCByZXQgPSBub2RlKFJFLk9QX0FOWU9GLCAwKTsKLQotICAgICAgICAvLyBQYXJzZSBjbGFzcyBkZWNsYXJhdGlvbgotICAgICAgICBjaGFyIENIQVJfSU5WQUxJRCA9IENoYXJhY3Rlci5NQVhfVkFMVUU7Ci0gICAgICAgIGNoYXIgbGFzdCA9IENIQVJfSU5WQUxJRDsKLSAgICAgICAgY2hhciBzaW1wbGVDaGFyID0gMDsKLSAgICAgICAgYm9vbGVhbiBpbmNsdWRlID0gdHJ1ZTsKLSAgICAgICAgYm9vbGVhbiBkZWZpbmluZ1JhbmdlID0gZmFsc2U7Ci0gICAgICAgIGludCBpZHhGaXJzdCA9IGlkeDsKLSAgICAgICAgY2hhciByYW5nZVN0YXJ0ID0gQ2hhcmFjdGVyLk1JTl9WQUxVRTsKLSAgICAgICAgY2hhciByYW5nZUVuZDsKLSAgICAgICAgUkVSYW5nZSByYW5nZSA9IG5ldyBSRVJhbmdlKCk7Ci0gICAgICAgIHdoaWxlIChpZHggPCBsZW4gJiYgcGF0dGVybi5jaGFyQXQoaWR4KSAhPSAnXScpCi0gICAgICAgIHsKLQotICAgICAgICAgICAgc3dpdGNoT25DaGFyYWN0ZXI6Ci0KLSAgICAgICAgICAgIC8vIFN3aXRjaCBvbiBjaGFyYWN0ZXIKLSAgICAgICAgICAgIHN3aXRjaCAocGF0dGVybi5jaGFyQXQoaWR4KSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBjYXNlICdeJzoKLSAgICAgICAgICAgICAgICAgICAgaW5jbHVkZSA9ICFpbmNsdWRlOwotICAgICAgICAgICAgICAgICAgICBpZiAoaWR4ID09IGlkeEZpcnN0KQotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByYW5nZS5pbmNsdWRlKENoYXJhY3Rlci5NSU5fVkFMVUUsIENoYXJhY3Rlci5NQVhfVkFMVUUsIHRydWUpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGlkeCsrOwotICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKLQotICAgICAgICAgICAgICAgIGNhc2UgJ1xcJzoKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIEVzY2FwZSBhbHdheXMgYWR2YW5jZXMgdGhlIHN0cmVhbQotICAgICAgICAgICAgICAgICAgICBpbnQgYzsKLSAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChjID0gZXNjYXBlICgpKQotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIEVTQ19DT01QTEVYOgotICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBFU0NfQkFDS1JFRjoKLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdvcmQgYm91bmRhcmllcyBhbmQgYmFja3JlZnMgbm90IGFsbG93ZWQgaW4gYSBjaGFyYWN0ZXIgY2xhc3MhCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ludGF4RXJyb3IoIkJhZCBjaGFyYWN0ZXIgY2xhc3MiKTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBFU0NfQ0xBU1M6Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBDbGFzc2VzIGNhbid0IGJlIGFuIGVuZHBvaW50IG9mIGEgcmFuZ2UKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGVmaW5pbmdSYW5nZSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bnRheEVycm9yKCJCYWQgY2hhcmFjdGVyIGNsYXNzIik7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSGFuZGxlIHNwZWNpZmljIHR5cGUgb2YgY2xhc3MgKHNvbWUgYXJlIG9rKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN3aXRjaCAocGF0dGVybi5jaGFyQXQoaWR4IC0gMSkpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFJFLkVfTlNQQUNFOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFJFLkVfTkRJR0lUOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFJFLkVfTkFMTlVNOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ludGF4RXJyb3IoIkJhZCBjaGFyYWN0ZXIgY2xhc3MiKTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFJFLkVfU1BBQ0U6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYW5nZS5pbmNsdWRlKCdcdCcsIGluY2x1ZGUpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmFuZ2UuaW5jbHVkZSgnXHInLCBpbmNsdWRlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhbmdlLmluY2x1ZGUoJ1xmJywgaW5jbHVkZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYW5nZS5pbmNsdWRlKCdcbicsIGluY2x1ZGUpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmFuZ2UuaW5jbHVkZSgnXGInLCBpbmNsdWRlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhbmdlLmluY2x1ZGUoJyAnLCBpbmNsdWRlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgUkUuRV9BTE5VTToKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhbmdlLmluY2x1ZGUoJ2EnLCAneicsIGluY2x1ZGUpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmFuZ2UuaW5jbHVkZSgnQScsICdaJywgaW5jbHVkZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYW5nZS5pbmNsdWRlKCdfJywgaW5jbHVkZSk7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEZhbGwgdGhyb3VnaCEKLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFJFLkVfRElHSVQ6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYW5nZS5pbmNsdWRlKCcwJywgJzknLCBpbmNsdWRlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE1ha2UgbGFzdCBjaGFyIGludmFsaWQgKGNhbid0IGJlIGEgcmFuZ2Ugc3RhcnQpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFzdCA9IENIQVJfSU5WQUxJRDsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLQotICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEVzY2FwZSBpcyBzaW1wbGUgc28gdHJlYXQgYXMgYSBzaW1wbGUgY2hhcgotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpbXBsZUNoYXIgPSAoY2hhcikgYzsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhayBzd2l0Y2hPbkNoYXJhY3RlcjsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBjb250aW51ZTsKLQotICAgICAgICAgICAgICAgIGNhc2UgJy0nOgotCi0gICAgICAgICAgICAgICAgICAgIC8vIFN0YXJ0IGEgcmFuZ2UgaWYgb25lIGlzbid0IGFscmVhZHkgc3RhcnRlZAotICAgICAgICAgICAgICAgICAgICBpZiAoZGVmaW5pbmdSYW5nZSkKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgc3ludGF4RXJyb3IoIkJhZCBjbGFzcyByYW5nZSIpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGRlZmluaW5nUmFuZ2UgPSB0cnVlOwotCi0gICAgICAgICAgICAgICAgICAgIC8vIElmIG5vIGxhc3QgY2hhcmFjdGVyLCBzdGFydCBvZiByYW5nZSBpcyAwCi0gICAgICAgICAgICAgICAgICAgIHJhbmdlU3RhcnQgPSAobGFzdCA9PSBDSEFSX0lOVkFMSUQgPyAwIDogbGFzdCk7Ci0KLSAgICAgICAgICAgICAgICAgICAgLy8gUHJlbWF0dXJlIGVuZCBvZiByYW5nZS4gZGVmaW5lIHVwIHRvIENoYXJhY3Rlci5NQVhfVkFMVUUKLSAgICAgICAgICAgICAgICAgICAgaWYgKChpZHggKyAxKSA8IGxlbiAmJiBwYXR0ZXJuLmNoYXJBdCgrK2lkeCkgPT0gJ10nKQotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzaW1wbGVDaGFyID0gQ2hhcmFjdGVyLk1BWF9WQUxVRTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotCi0gICAgICAgICAgICAgICAgZGVmYXVsdDoKLSAgICAgICAgICAgICAgICAgICAgc2ltcGxlQ2hhciA9IHBhdHRlcm4uY2hhckF0KGlkeCsrKTsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIEhhbmRsZSBzaW1wbGUgY2hhcmFjdGVyIHNpbXBsZUNoYXIKLSAgICAgICAgICAgIGlmIChkZWZpbmluZ1JhbmdlKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIC8vIGlmIHdlIGFyZSBkZWZpbmluZyBhIHJhbmdlIG1ha2UgaXQgbm93Ci0gICAgICAgICAgICAgICAgcmFuZ2VFbmQgPSBzaW1wbGVDaGFyOwotCi0gICAgICAgICAgICAgICAgLy8gQWN0dWFsbHkgY3JlYXRlIGEgcmFuZ2UgaWYgdGhlIHJhbmdlIGlzIG9rCi0gICAgICAgICAgICAgICAgaWYgKHJhbmdlU3RhcnQgPj0gcmFuZ2VFbmQpCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICBzeW50YXhFcnJvcigiQmFkIGNoYXJhY3RlciBjbGFzcyIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICByYW5nZS5pbmNsdWRlKHJhbmdlU3RhcnQsIHJhbmdlRW5kLCBpbmNsdWRlKTsKLQotICAgICAgICAgICAgICAgIC8vIFdlIGFyZSBkb25lIGRlZmluaW5nIHRoZSByYW5nZQotICAgICAgICAgICAgICAgIGxhc3QgPSBDSEFSX0lOVkFMSUQ7Ci0gICAgICAgICAgICAgICAgZGVmaW5pbmdSYW5nZSA9IGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIC8vIElmIHNpbXBsZSBjaGFyYWN0ZXIgYW5kIG5vdCBzdGFydCBvZiByYW5nZSwgaW5jbHVkZSBpdAotICAgICAgICAgICAgICAgIGlmIChpZHggPj0gbGVuIHx8IHBhdHRlcm4uY2hhckF0KGlkeCkgIT0gJy0nKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgcmFuZ2UuaW5jbHVkZShzaW1wbGVDaGFyLCBpbmNsdWRlKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgbGFzdCA9IHNpbXBsZUNoYXI7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBTaG91bGRuJ3QgYmUgb3V0IG9mIGlucHV0Ci0gICAgICAgIGlmIChpZHggPT0gbGVuKQotICAgICAgICB7Ci0gICAgICAgICAgICBzeW50YXhFcnJvcigiVW50ZXJtaW5hdGVkIGNoYXJhY3RlciBjbGFzcyIpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gQWJzb3JiIHRoZSAnXScgZW5kIG9mIGNsYXNzIG1hcmtlcgotICAgICAgICBpZHgrKzsKLQotICAgICAgICAvLyBFbWl0IGNoYXJhY3RlciBjbGFzcyBkZWZpbml0aW9uCi0gICAgICAgIGluc3RydWN0aW9uW3JldCArIFJFLm9mZnNldE9wZGF0YV0gPSAoY2hhcilyYW5nZS5udW07Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmFuZ2UubnVtOyBpKyspCi0gICAgICAgIHsKLSAgICAgICAgICAgIGVtaXQoKGNoYXIpcmFuZ2UubWluUmFuZ2VbaV0pOwotICAgICAgICAgICAgZW1pdCgoY2hhcilyYW5nZS5tYXhSYW5nZVtpXSk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHJldDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBYnNvcmIgYW4gYXRvbWljIGNoYXJhY3RlciBzdHJpbmcuICBUaGlzIG1ldGhvZCBpcyBhIGxpdHRsZSB0cmlja3kgYmVjYXVzZQotICAgICAqIGl0IGNhbiB1bi1pbmNsdWRlIHRoZSBsYXN0IGNoYXJhY3RlciBvZiBzdHJpbmcgaWYgYSBjbG9zdXJlIG9wZXJhdG9yIGZvbGxvd3MuCi0gICAgICogVGhpcyBpcyBjb3JyZWN0IGJlY2F1c2UgKis/IGhhdmUgaGlnaGVyIHByZWNlZGVuY2UgdGhhbiBjb25jYXRlbnRhdGlvbiAodGh1cwotICAgICAqIEFCQyogbWVhbnMgQUIoQyopIGFuZCBOT1QgKEFCQykqKS4KLSAgICAgKiBAcmV0dXJuIEluZGV4IG9mIG5ldyBhdG9tIG5vZGUKLSAgICAgKiBAZXhjZXB0aW9uIFJFU3ludGF4RXhjZXB0aW9uIFRocm93biBpZiB0aGUgcmVndWxhciBleHByZXNzaW9uIGhhcyBpbnZhbGlkIHN5bnRheC4KLSAgICAgKi8KLSAgICBpbnQgYXRvbSgpIHRocm93cyBSRVN5bnRheEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgLy8gQ3JlYXRlIGEgc3RyaW5nIG5vZGUKLSAgICAgICAgaW50IHJldCA9IG5vZGUoUkUuT1BfQVRPTSwgMCk7Ci0KLSAgICAgICAgLy8gTGVuZ3RoIG9mIGF0b20KLSAgICAgICAgaW50IGxlbkF0b20gPSAwOwotCi0gICAgICAgIC8vIExvb3Agd2hpbGUgd2UndmUgZ290IGlucHV0Ci0KLSAgICAgICAgYXRvbUxvb3A6Ci0KLSAgICAgICAgd2hpbGUgKGlkeCA8IGxlbikKLSAgICAgICAgewotICAgICAgICAgICAgLy8gSXMgdGhlcmUgYSBuZXh0IGNoYXI/Ci0gICAgICAgICAgICBpZiAoKGlkeCArIDEpIDwgbGVuKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIGNoYXIgYyA9IHBhdHRlcm4uY2hhckF0KGlkeCArIDEpOwotCi0gICAgICAgICAgICAgICAgLy8gSWYgdGhlIG5leHQgJ2NoYXInIGlzIGFuIGVzY2FwZSwgbG9vayBwYXN0IHRoZSB3aG9sZSBlc2NhcGUKLSAgICAgICAgICAgICAgICBpZiAocGF0dGVybi5jaGFyQXQoaWR4KSA9PSAnXFwnKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgaW50IGlkeEVzY2FwZSA9IGlkeDsKLSAgICAgICAgICAgICAgICAgICAgZXNjYXBlKCk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChpZHggPCBsZW4pCi0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGMgPSBwYXR0ZXJuLmNoYXJBdChpZHgpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGlkeCA9IGlkeEVzY2FwZTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyBTd2l0Y2ggb24gbmV4dCBjaGFyCi0gICAgICAgICAgICAgICAgc3dpdGNoIChjKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgY2FzZSAneyc6Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgJz8nOgotICAgICAgICAgICAgICAgICAgICBjYXNlICcqJzoKLSAgICAgICAgICAgICAgICAgICAgY2FzZSAnKyc6Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIElmIHRoZSBuZXh0IGNoYXJhY3RlciBpcyBhIGNsb3N1cmUgb3BlcmF0b3IgYW5kIG91ciBhdG9tIGlzIG5vbi1lbXB0eSwgdGhlCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBjdXJyZW50IGNoYXJhY3RlciBzaG91bGQgYmluZCB0byB0aGUgY2xvc3VyZSBvcGVyYXRvciByYXRoZXIgdGhhbiB0aGUgYXRvbQotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxlbkF0b20gIT0gMCkKLSAgICAgICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhayBhdG9tTG9vcDsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIFN3aXRjaCBvbiBjdXJyZW50IGNoYXIKLSAgICAgICAgICAgIHN3aXRjaCAocGF0dGVybi5jaGFyQXQoaWR4KSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBjYXNlICddJzoKLSAgICAgICAgICAgICAgICBjYXNlICdeJzoKLSAgICAgICAgICAgICAgICBjYXNlICckJzoKLSAgICAgICAgICAgICAgICBjYXNlICcuJzoKLSAgICAgICAgICAgICAgICBjYXNlICdbJzoKLSAgICAgICAgICAgICAgICBjYXNlICcoJzoKLSAgICAgICAgICAgICAgICBjYXNlICcpJzoKLSAgICAgICAgICAgICAgICBjYXNlICd8JzoKLSAgICAgICAgICAgICAgICAgICAgYnJlYWsgYXRvbUxvb3A7Ci0KLSAgICAgICAgICAgICAgICBjYXNlICd7JzoKLSAgICAgICAgICAgICAgICBjYXNlICc/JzoKLSAgICAgICAgICAgICAgICBjYXNlICcqJzoKLSAgICAgICAgICAgICAgICBjYXNlICcrJzoKLQotICAgICAgICAgICAgICAgICAgICAvLyBXZSBzaG91bGQgaGF2ZSBhbiBhdG9tIGJ5IG5vdwotICAgICAgICAgICAgICAgICAgICBpZiAobGVuQXRvbSA9PSAwKQotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBObyBhdG9tIGJlZm9yZSBjbG9zdXJlCi0gICAgICAgICAgICAgICAgICAgICAgICBzeW50YXhFcnJvcigiTWlzc2luZyBvcGVyYW5kIHRvIGNsb3N1cmUiKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBicmVhayBhdG9tTG9vcDsKLQotICAgICAgICAgICAgICAgIGNhc2UgJ1xcJzoKLQotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBHZXQgdGhlIGVzY2FwZWQgY2hhcmFjdGVyIChhZHZhbmNlcyBpbnB1dCBhdXRvbWF0aWNhbGx5KQotICAgICAgICAgICAgICAgICAgICAgICAgaW50IGlkeEJlZm9yZUVzY2FwZSA9IGlkeDsKLSAgICAgICAgICAgICAgICAgICAgICAgIGludCBjID0gZXNjYXBlKCk7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIGl0J3MgYSBzaW1wbGUgZXNjYXBlIChhcyBvcHBvc2VkIHRvLCBzYXksIGEgYmFja3JlZmVyZW5jZSkKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoYyAmIEVTQ19NQVNLKSA9PSBFU0NfTUFTSykKLSAgICAgICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBOb3QgYSBzaW1wbGUgZXNjYXBlLCBzbyBiYWNrdXAgdG8gd2hlcmUgd2Ugd2VyZSBiZWZvcmUgdGhlIGVzY2FwZS4KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZHggPSBpZHhCZWZvcmVFc2NhcGU7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWsgYXRvbUxvb3A7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIEFkZCBlc2NhcGVkIGNoYXIgdG8gYXRvbQotICAgICAgICAgICAgICAgICAgICAgICAgZW1pdCgoY2hhcikgYyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBsZW5BdG9tKys7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgICAgICAgICBkZWZhdWx0OgotCi0gICAgICAgICAgICAgICAgICAgIC8vIEFkZCBub3JtYWwgY2hhcmFjdGVyIHRvIGF0b20KLSAgICAgICAgICAgICAgICAgICAgZW1pdChwYXR0ZXJuLmNoYXJBdChpZHgrKykpOwotICAgICAgICAgICAgICAgICAgICBsZW5BdG9tKys7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gVGhpcyAic2hvdWxkbid0IiBoYXBwZW4KLSAgICAgICAgaWYgKGxlbkF0b20gPT0gMCkKLSAgICAgICAgewotICAgICAgICAgICAgaW50ZXJuYWxFcnJvcigpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gRW1pdCB0aGUgYXRvbSBsZW5ndGggaW50byB0aGUgcHJvZ3JhbQotICAgICAgICBpbnN0cnVjdGlvbltyZXQgKyBSRS5vZmZzZXRPcGRhdGFdID0gKGNoYXIpbGVuQXRvbTsKLSAgICAgICAgcmV0dXJuIHJldDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBNYXRjaCBhIHRlcm1pbmFsIG5vZGUuCi0gICAgICogQHBhcmFtIGZsYWdzIEZsYWdzCi0gICAgICogQHJldHVybiBJbmRleCBvZiB0ZXJtaW5hbCBub2RlIChjbG9zZWFibGUpCi0gICAgICogQGV4Y2VwdGlvbiBSRVN5bnRheEV4Y2VwdGlvbiBUaHJvd24gaWYgdGhlIHJlZ3VsYXIgZXhwcmVzc2lvbiBoYXMgaW52YWxpZCBzeW50YXguCi0gICAgICovCi0gICAgaW50IHRlcm1pbmFsKGludFtdIGZsYWdzKSB0aHJvd3MgUkVTeW50YXhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIHN3aXRjaCAocGF0dGVybi5jaGFyQXQoaWR4KSkKLSAgICAgICAgewotICAgICAgICBjYXNlIFJFLk9QX0VPTDoKLSAgICAgICAgY2FzZSBSRS5PUF9CT0w6Ci0gICAgICAgIGNhc2UgUkUuT1BfQU5ZOgotICAgICAgICAgICAgcmV0dXJuIG5vZGUocGF0dGVybi5jaGFyQXQoaWR4KyspLCAwKTsKLQotICAgICAgICBjYXNlICdbJzoKLSAgICAgICAgICAgIHJldHVybiBjaGFyYWN0ZXJDbGFzcygpOwotCi0gICAgICAgIGNhc2UgJygnOgotICAgICAgICAgICAgcmV0dXJuIGV4cHIoZmxhZ3MpOwotCi0gICAgICAgIGNhc2UgJyknOgotICAgICAgICAgICAgc3ludGF4RXJyb3IoIlVuZXhwZWN0ZWQgY2xvc2UgcGFyZW4iKTsKLQotICAgICAgICBjYXNlICd8JzoKLSAgICAgICAgICAgIGludGVybmFsRXJyb3IoKTsKLQotICAgICAgICBjYXNlICddJzoKLSAgICAgICAgICAgIHN5bnRheEVycm9yKCJNaXNtYXRjaGVkIGNsYXNzIik7Ci0KLSAgICAgICAgY2FzZSAwOgotICAgICAgICAgICAgc3ludGF4RXJyb3IoIlVuZXhwZWN0ZWQgZW5kIG9mIGlucHV0Iik7Ci0KLSAgICAgICAgY2FzZSAnPyc6Ci0gICAgICAgIGNhc2UgJysnOgotICAgICAgICBjYXNlICd7JzoKLSAgICAgICAgY2FzZSAnKic6Ci0gICAgICAgICAgICBzeW50YXhFcnJvcigiTWlzc2luZyBvcGVyYW5kIHRvIGNsb3N1cmUiKTsKLQotICAgICAgICBjYXNlICdcXCc6Ci0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgLy8gRG9uJ3QgZm9yZ2V0LCBlc2NhcGUoKSBhZHZhbmNlcyB0aGUgaW5wdXQgc3RyZWFtIQotICAgICAgICAgICAgICAgIGludCBpZHhCZWZvcmVFc2NhcGUgPSBpZHg7Ci0KLSAgICAgICAgICAgICAgICAvLyBTd2l0Y2ggb24gZXNjYXBlZCBjaGFyYWN0ZXIKLSAgICAgICAgICAgICAgICBzd2l0Y2ggKGVzY2FwZSgpKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgY2FzZSBFU0NfQ0xBU1M6Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgRVNDX0NPTVBMRVg6Ci0gICAgICAgICAgICAgICAgICAgICAgICBmbGFnc1swXSAmPSB+Tk9ERV9OVUxMQUJMRTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBub2RlKFJFLk9QX0VTQ0FQRSwgcGF0dGVybi5jaGFyQXQoaWR4IC0gMSkpOwotCi0gICAgICAgICAgICAgICAgICAgIGNhc2UgRVNDX0JBQ0tSRUY6Ci0gICAgICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhciBiYWNrcmVmZXJlbmNlID0gKGNoYXIpKHBhdHRlcm4uY2hhckF0KGlkeCAtIDEpIC0gJzAnKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocGFyZW5zIDw9IGJhY2tyZWZlcmVuY2UpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeW50YXhFcnJvcigiQmFkIGJhY2tyZWZlcmVuY2UiKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmxhZ3NbMF0gfD0gTk9ERV9OVUxMQUJMRTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbm9kZShSRS5PUF9CQUNLUkVGLCBiYWNrcmVmZXJlbmNlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgotCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBXZSBoYWQgYSBzaW1wbGUgZXNjYXBlIGFuZCB3ZSB3YW50IHRvIGhhdmUgaXQgZW5kIHVwIGluCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBhbiBhdG9tLCBzbyB3ZSBiYWNrIHVwIGFuZCBmYWxsIHRob3VnaCB0byB0aGUgZGVmYXVsdCBoYW5kbGluZwotICAgICAgICAgICAgICAgICAgICAgICAgaWR4ID0gaWR4QmVmb3JlRXNjYXBlOwotICAgICAgICAgICAgICAgICAgICAgICAgZmxhZ3NbMF0gJj0gfk5PREVfTlVMTEFCTEU7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBFdmVyeXRoaW5nIGFib3ZlIGVpdGhlciBmYWlscyBvciByZXR1cm5zLgotICAgICAgICAvLyBJZiBpdCB3YXNuJ3Qgb25lIG9mIHRoZSBhYm92ZSwgaXQgbXVzdCBiZSB0aGUgc3RhcnQgb2YgYW4gYXRvbS4KLSAgICAgICAgZmxhZ3NbMF0gJj0gfk5PREVfTlVMTEFCTEU7Ci0gICAgICAgIHJldHVybiBhdG9tKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29tcGlsZSBhIHBvc3NpYmx5IGNsb3N1cmVkIHRlcm1pbmFsCi0gICAgICogQHBhcmFtIGZsYWdzIEZsYWdzIHBhc3NlZCBieSByZWZlcmVuY2UKLSAgICAgKiBAcmV0dXJuIEluZGV4IG9mIGNsb3N1cmVkIG5vZGUKLSAgICAgKiBAZXhjZXB0aW9uIFJFU3ludGF4RXhjZXB0aW9uIFRocm93biBpZiB0aGUgcmVndWxhciBleHByZXNzaW9uIGhhcyBpbnZhbGlkIHN5bnRheC4KLSAgICAgKi8KLSAgICBpbnQgY2xvc3VyZShpbnRbXSBmbGFncykgdGhyb3dzIFJFU3ludGF4RXhjZXB0aW9uCi0gICAgewotICAgICAgICAvLyBCZWZvcmUgdGVybWluYWwKLSAgICAgICAgaW50IGlkeEJlZm9yZVRlcm1pbmFsID0gaWR4OwotCi0gICAgICAgIC8vIFZhbHVlcyB0byBwYXNzIGJ5IHJlZmVyZW5jZSB0byB0ZXJtaW5hbCgpCi0gICAgICAgIGludFtdIHRlcm1pbmFsRmxhZ3MgPSB7IE5PREVfTk9STUFMIH07Ci0KLSAgICAgICAgLy8gR2V0IHRlcm1pbmFsIHN5bWJvbAotICAgICAgICBpbnQgcmV0ID0gdGVybWluYWwodGVybWluYWxGbGFncyk7Ci0KLSAgICAgICAgLy8gT3IgaW4gZmxhZ3MgZnJvbSB0ZXJtaW5hbCBzeW1ib2wKLSAgICAgICAgZmxhZ3NbMF0gfD0gdGVybWluYWxGbGFnc1swXTsKLQotICAgICAgICAvLyBBZHZhbmNlIGlucHV0LCBzZXQgTk9ERV9OVUxMQUJMRSBmbGFnIGFuZCBkbyBzYW5pdHkgY2hlY2tzCi0gICAgICAgIGlmIChpZHggPj0gbGVuKQotICAgICAgICB7Ci0gICAgICAgICAgICByZXR1cm4gcmV0OwotICAgICAgICB9Ci0gICAgICAgIGJvb2xlYW4gZ3JlZWR5ID0gdHJ1ZTsKLSAgICAgICAgY2hhciBjbG9zdXJlVHlwZSA9IHBhdHRlcm4uY2hhckF0KGlkeCk7Ci0gICAgICAgIHN3aXRjaCAoY2xvc3VyZVR5cGUpCi0gICAgICAgIHsKLSAgICAgICAgICAgIGNhc2UgJz8nOgotICAgICAgICAgICAgY2FzZSAnKic6Ci0KLSAgICAgICAgICAgICAgICAvLyBUaGUgY3VycmVudCBub2RlIGNhbiBiZSBudWxsCi0gICAgICAgICAgICAgICAgZmxhZ3NbMF0gfD0gTk9ERV9OVUxMQUJMRTsKLQotICAgICAgICAgICAgY2FzZSAnKyc6Ci0KLSAgICAgICAgICAgICAgICAvLyBFYXQgY2xvc3VyZSBjaGFyYWN0ZXIKLSAgICAgICAgICAgICAgICBpZHgrKzsKLQotICAgICAgICAgICAgY2FzZSAneyc6Ci0KLSAgICAgICAgICAgICAgICAvLyBEb24ndCBhbGxvdyBibGFudGFudCBzdHVwaWRpdHkKLSAgICAgICAgICAgICAgICBpbnQgb3Bjb2RlID0gaW5zdHJ1Y3Rpb25bcmV0ICsgUkUub2Zmc2V0T3Bjb2RlXTsKLSAgICAgICAgICAgICAgICBpZiAob3Bjb2RlID09IFJFLk9QX0JPTCB8fCBvcGNvZGUgPT0gUkUuT1BfRU9MKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgc3ludGF4RXJyb3IoIkJhZCBjbG9zdXJlIG9wZXJhbmQiKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaWYgKCh0ZXJtaW5hbEZsYWdzWzBdICYgTk9ERV9OVUxMQUJMRSkgIT0gMCkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIHN5bnRheEVycm9yKCJDbG9zdXJlIG9wZXJhbmQgY2FuJ3QgYmUgbnVsbGFibGUiKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBJZiB0aGUgbmV4dCBjaGFyYWN0ZXIgaXMgYSAnPycsIG1ha2UgdGhlIGNsb3N1cmUgbm9uLWdyZWVkeSAocmVsdWN0YW50KQotICAgICAgICBpZiAoaWR4IDwgbGVuICYmIHBhdHRlcm4uY2hhckF0KGlkeCkgPT0gJz8nKQotICAgICAgICB7Ci0gICAgICAgICAgICBpZHgrKzsKLSAgICAgICAgICAgIGdyZWVkeSA9IGZhbHNlOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKGdyZWVkeSkKLSAgICAgICAgewotICAgICAgICAgICAgLy8gQWN0dWFsbHkgZG8gdGhlIGNsb3N1cmUgbm93Ci0gICAgICAgICAgICBzd2l0Y2ggKGNsb3N1cmVUeXBlKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIGNhc2UgJ3snOgotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gV2UgbG9vayBmb3Igb3VyIGJyYWNrZXQgaW4gdGhlIGxpc3QKLSAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBmb3VuZCA9IGZhbHNlOwotICAgICAgICAgICAgICAgICAgICBpbnQgaTsKLSAgICAgICAgICAgICAgICAgICAgYWxsb2NCcmFja2V0cygpOwotICAgICAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgYnJhY2tldHM7IGkrKykKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGJyYWNrZXRTdGFydFtpXSA9PSBpZHgpCi0gICAgICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZm91bmQgPSB0cnVlOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgLy8gSWYgaXRzIG5vdCBpbiB0aGUgbGlzdCB3ZSBwYXJzZSB0aGUge20sbn0KLSAgICAgICAgICAgICAgICAgICAgaWYgKCFmb3VuZCkKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGJyYWNrZXRzID49IG1heEJyYWNrZXRzKQotICAgICAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlYWxsb2NCcmFja2V0cygpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgYnJhY2tldFN0YXJ0W2JyYWNrZXRzXSA9IGlkeDsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyYWNrZXQoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyYWNrZXRFbmRbYnJhY2tldHNdID0gaWR4OwotICAgICAgICAgICAgICAgICAgICAgICAgaSA9IGJyYWNrZXRzKys7Ci0gICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAvLyBQcm9jZXNzIG1pbiBmaXJzdAotICAgICAgICAgICAgICAgICAgICBpZiAoYnJhY2tldE1pbltpXS0tID4gMCkKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGJyYWNrZXRNaW5baV0gPiAwIHx8IGJyYWNrZXRPcHRbaV0gIT0gMCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJld2luZCBzdHJlYW0gYW5kIHJ1biBpdCB0aHJvdWdoIGFnYWluIC0gbW9yZSBtYXRjaGVycyBjb21pbmcKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IGJyYWNrZXRzOyBqKyspIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGogIT0gaSAmJiBicmFja2V0U3RhcnRbal0gPCBpZHgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmIGJyYWNrZXRTdGFydFtqXSA+PSBpZHhCZWZvcmVUZXJtaW5hbCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJhY2tldHMtLTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyYWNrZXRTdGFydFtqXSA9IGJyYWNrZXRTdGFydFticmFja2V0c107Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmFja2V0RW5kW2pdID0gYnJhY2tldEVuZFticmFja2V0c107Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmFja2V0TWluW2pdID0gYnJhY2tldE1pblticmFja2V0c107Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmFja2V0T3B0W2pdID0gYnJhY2tldE9wdFticmFja2V0c107Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZHggPSBpZHhCZWZvcmVUZXJtaW5hbDsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQnVnICMxMDMwOiBObyBvcHRpbmFsIG1hdGNoZXMgLSBubyBuZWVkIHRvIHJld2luZAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlkeCA9IGJyYWNrZXRFbmRbaV07Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgIC8vIERvIHRoZSByaWdodCB0aGluZyBmb3IgbWF4aW11bSAoe20sfSkKLSAgICAgICAgICAgICAgICAgICAgaWYgKGJyYWNrZXRPcHRbaV0gPT0gYnJhY2tldFVuYm91bmRlZCkKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gRHJvcCB0aHJvdWdoIG5vdyBhbmQgY2xvc3VyZSBleHByZXNzaW9uLgotICAgICAgICAgICAgICAgICAgICAgICAgLy8gV2UgYXJlIGRvbmUgd2l0aCB0aGUge20sfSBleHByLCBzbyBza2lwIHJlc3QKLSAgICAgICAgICAgICAgICAgICAgICAgIGNsb3N1cmVUeXBlID0gJyonOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJhY2tldE9wdFtpXSA9IDA7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZHggPSBicmFja2V0RW5kW2ldOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChicmFja2V0T3B0W2ldLS0gPiAwKQotICAgICAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChicmFja2V0T3B0W2ldID4gMCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE1vcmUgb3B0aW9uYWwgbWF0Y2hlcnMgLSAncGxheSBpdCBhZ2FpbiBzYW0hJwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZHggPSBpZHhCZWZvcmVUZXJtaW5hbDsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBCdWcgIzEwMzA6IFdlIGFyZSBkb25lIC0gdGhpcyBvbmUgaXMgbGFzdCBhbmQgb3B0aW9uYWwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWR4ID0gYnJhY2tldEVuZFtpXTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRHJvcCB0aHJvdWdoIHRvIG9wdGlvbmFsbHkgY2xvc2UKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbG9zdXJlVHlwZSA9ICc/JzsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBSb2xsYmFjayB0ZXJtaW5hbCAtIG5laXRoZXIgbWluIG5vciBvcHQgbWF0Y2hlcnMgcHJlc2VudAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlbkluc3RydWN0aW9uID0gcmV0OwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUoUkUuT1BfTk9USElORywgMCk7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBXZSBhcmUgZG9uZS4gc2tpcCB0aGUgcmVzdCBvZiB7bSxufSBleHByCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWR4ID0gYnJhY2tldEVuZFtpXTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyBGYWxsIHRocm91Z2ghCi0KLSAgICAgICAgICAgICAgICBjYXNlICc/JzoKLSAgICAgICAgICAgICAgICBjYXNlICcqJzoKLQotICAgICAgICAgICAgICAgICAgICBpZiAoIWdyZWVkeSkKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICBpZiAoY2xvc3VyZVR5cGUgPT0gJz8nKQotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBYPyBpcyBjb21waWxlZCBhcyAoWHwpCi0gICAgICAgICAgICAgICAgICAgICAgICBub2RlSW5zZXJ0KFJFLk9QX0JSQU5DSCwgMCwgcmV0KTsgICAgICAgICAgICAgICAgIC8vIGJyYW5jaCBiZWZvcmUgWAotICAgICAgICAgICAgICAgICAgICAgICAgc2V0TmV4dE9mRW5kKHJldCwgbm9kZSAoUkUuT1BfQlJBTkNILCAwKSk7ICAgICAgICAvLyBpbnNlcnRlZCBicmFuY2ggdG8gb3B0aW9uCi0gICAgICAgICAgICAgICAgICAgICAgICBpbnQgbm90aGluZyA9IG5vZGUgKFJFLk9QX05PVEhJTkcsIDApOyAgICAgICAgICAgIC8vIHdoaWNoIGlzIE9QX05PVEhJTkcKLSAgICAgICAgICAgICAgICAgICAgICAgIHNldE5leHRPZkVuZChyZXQsIG5vdGhpbmcpOyAgICAgICAgICAgICAgICAgICAgICAgLy8gcG9pbnQgKHNlY29uZCkgYnJhbmNoIHRvIE9QX05PVEhJTkcKLSAgICAgICAgICAgICAgICAgICAgICAgIHNldE5leHRPZkVuZChyZXQgKyBSRS5ub2RlU2l6ZSwgbm90aGluZyk7ICAgICAgICAgLy8gcG9pbnQgdGhlIGVuZCBvZiBYIHRvIE9QX05PVEhJTkcgbm9kZQotICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgaWYgKGNsb3N1cmVUeXBlID09ICcqJykKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gWCogaXMgY29tcGlsZWQgYXMgKFh7Z290b1h9fCkKLSAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVJbnNlcnQoUkUuT1BfQlJBTkNILCAwLCByZXQpOyAgICAgICAgICAgICAgICAgICAgICAgICAvLyBicmFuY2ggYmVmb3JlIFgKLSAgICAgICAgICAgICAgICAgICAgICAgIHNldE5leHRPZkVuZChyZXQgKyBSRS5ub2RlU2l6ZSwgbm9kZShSRS5PUF9CUkFOQ0gsIDApKTsgICAvLyBlbmQgb2YgWCBwb2ludHMgdG8gYW4gb3B0aW9uCi0gICAgICAgICAgICAgICAgICAgICAgICBzZXROZXh0T2ZFbmQocmV0ICsgUkUubm9kZVNpemUsIG5vZGUoUkUuT1BfR09UTywgMCkpOyAgICAgLy8gdG8gZ290bwotICAgICAgICAgICAgICAgICAgICAgICAgc2V0TmV4dE9mRW5kKHJldCArIFJFLm5vZGVTaXplLCByZXQpOyAgICAgICAgICAgICAgICAgICAgIC8vIHRoZSBzdGFydCBhZ2FpbgotICAgICAgICAgICAgICAgICAgICAgICAgc2V0TmV4dE9mRW5kKHJldCwgbm9kZShSRS5PUF9CUkFOQ0gsIDApKTsgICAgICAgICAgICAgICAgIC8vIHRoZSBvdGhlciBvcHRpb24gaXMKLSAgICAgICAgICAgICAgICAgICAgICAgIHNldE5leHRPZkVuZChyZXQsIG5vZGUoUkUuT1BfTk9USElORywgMCkpOyAgICAgICAgICAgICAgICAvLyBPUF9OT1RISU5HCi0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgICAgICAgICBjYXNlICcrJzoKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIFgrIGlzIGNvbXBpbGVkIGFzIFgoe2dvdG9YfXwpCi0gICAgICAgICAgICAgICAgICAgIGludCBicmFuY2g7Ci0gICAgICAgICAgICAgICAgICAgIGJyYW5jaCA9IG5vZGUoUkUuT1BfQlJBTkNILCAwKTsgICAgICAgICAgICAgICAgICAgLy8gYSBuZXcgYnJhbmNoCi0gICAgICAgICAgICAgICAgICAgIHNldE5leHRPZkVuZChyZXQsIGJyYW5jaCk7ICAgICAgICAgICAgICAgICAgICAgICAgLy8gaXMgYWRkZWQgdG8gdGhlIGVuZCBvZiBYCi0gICAgICAgICAgICAgICAgICAgIHNldE5leHRPZkVuZChub2RlKFJFLk9QX0dPVE8sIDApLCByZXQpOyAgICAgICAgICAgLy8gb25lIG9wdGlvbiBpcyB0byBnbyBiYWNrIHRvIHRoZSBzdGFydAotICAgICAgICAgICAgICAgICAgICBzZXROZXh0T2ZFbmQoYnJhbmNoLCBub2RlKFJFLk9QX0JSQU5DSCwgMCkpOyAgICAgIC8vIHRoZSBvdGhlciBvcHRpb24KLSAgICAgICAgICAgICAgICAgICAgc2V0TmV4dE9mRW5kKHJldCwgbm9kZShSRS5PUF9OT1RISU5HLCAwKSk7ICAgICAgICAvLyBpcyBPUF9OT1RISU5HCi0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotICAgICAgICAgICAgLy8gQWRkIGVuZCBhZnRlciBjbG9zdXJlZCBzdWJleHByCi0gICAgICAgICAgICBzZXROZXh0T2ZFbmQocmV0LCBub2RlKFJFLk9QX0VORCwgMCkpOwotCi0gICAgICAgICAgICAvLyBBY3R1YWxseSBkbyB0aGUgY2xvc3VyZSBub3cKLSAgICAgICAgICAgIHN3aXRjaCAoY2xvc3VyZVR5cGUpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgY2FzZSAnPyc6Ci0gICAgICAgICAgICAgICAgICAgIG5vZGVJbnNlcnQoUkUuT1BfUkVMVUNUQU5UTUFZQkUsIDAsIHJldCk7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgICAgICAgICAgY2FzZSAnKic6Ci0gICAgICAgICAgICAgICAgICAgIG5vZGVJbnNlcnQoUkUuT1BfUkVMVUNUQU5UU1RBUiwgMCwgcmV0KTsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgICAgICAgICBjYXNlICcrJzoKLSAgICAgICAgICAgICAgICAgICAgbm9kZUluc2VydChSRS5PUF9SRUxVQ1RBTlRQTFVTLCAwLCByZXQpOwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gUG9pbnQgdG8gdGhlIGV4cHIgYWZ0ZXIgdGhlIGNsb3N1cmUKLSAgICAgICAgICAgIHNldE5leHRPZkVuZChyZXQsIGxlbkluc3RydWN0aW9uKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gcmV0OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbXBpbGUgb25lIGJyYW5jaCBvZiBhbiBvciBvcGVyYXRvciAoaW1wbGVtZW50cyBjb25jYXRlbmF0aW9uKQotICAgICAqIEBwYXJhbSBmbGFncyBGbGFncyBwYXNzZWQgYnkgcmVmZXJlbmNlCi0gICAgICogQHJldHVybiBQb2ludGVyIHRvIGJyYW5jaCBub2RlCi0gICAgICogQGV4Y2VwdGlvbiBSRVN5bnRheEV4Y2VwdGlvbiBUaHJvd24gaWYgdGhlIHJlZ3VsYXIgZXhwcmVzc2lvbiBoYXMgaW52YWxpZCBzeW50YXguCi0gICAgICovCi0gICAgaW50IGJyYW5jaChpbnRbXSBmbGFncykgdGhyb3dzIFJFU3ludGF4RXhjZXB0aW9uCi0gICAgewotICAgICAgICAvLyBHZXQgZWFjaCBwb3NzaWJseSBjbG9zdXJlZCBwaWVjZSBhbmQgY29uY2F0Ci0gICAgICAgIGludCBub2RlOwotICAgICAgICBpbnQgcmV0ID0gbm9kZShSRS5PUF9CUkFOQ0gsIDApOwotICAgICAgICBpbnQgY2hhaW4gPSAtMTsKLSAgICAgICAgaW50W10gY2xvc3VyZUZsYWdzID0gbmV3IGludFsxXTsKLSAgICAgICAgYm9vbGVhbiBudWxsYWJsZSA9IHRydWU7Ci0gICAgICAgIHdoaWxlIChpZHggPCBsZW4gJiYgcGF0dGVybi5jaGFyQXQoaWR4KSAhPSAnfCcgJiYgcGF0dGVybi5jaGFyQXQoaWR4KSAhPSAnKScpCi0gICAgICAgIHsKLSAgICAgICAgICAgIC8vIEdldCBuZXcgbm9kZQotICAgICAgICAgICAgY2xvc3VyZUZsYWdzWzBdID0gTk9ERV9OT1JNQUw7Ci0gICAgICAgICAgICBub2RlID0gY2xvc3VyZShjbG9zdXJlRmxhZ3MpOwotICAgICAgICAgICAgaWYgKGNsb3N1cmVGbGFnc1swXSA9PSBOT0RFX05PUk1BTCkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBudWxsYWJsZSA9IGZhbHNlOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBJZiB0aGVyZSdzIGEgY2hhaW4sIGFwcGVuZCB0byB0aGUgZW5kCi0gICAgICAgICAgICBpZiAoY2hhaW4gIT0gLTEpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgc2V0TmV4dE9mRW5kKGNoYWluLCBub2RlKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gQ2hhaW4gc3RhcnRzIGF0IGN1cnJlbnQKLSAgICAgICAgICAgIGNoYWluID0gbm9kZTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIElmIHdlIGRvbid0IHJ1biBsb29wLCBtYWtlIGEgbm90aGluZyBub2RlCi0gICAgICAgIGlmIChjaGFpbiA9PSAtMSkKLSAgICAgICAgewotICAgICAgICAgICAgbm9kZShSRS5PUF9OT1RISU5HLCAwKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIFNldCBudWxsYWJsZSBmbGFnIGZvciB0aGlzIGJyYW5jaAotICAgICAgICBpZiAobnVsbGFibGUpCi0gICAgICAgIHsKLSAgICAgICAgICAgIGZsYWdzWzBdIHw9IE5PREVfTlVMTEFCTEU7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHJldDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb21waWxlIGFuIGV4cHJlc3Npb24gd2l0aCBwb3NzaWJsZSBwYXJlbnMgYXJvdW5kIGl0LiAgUGFyZW4gbWF0Y2hpbmcKLSAgICAgKiBpcyBkb25lIGF0IHRoaXMgbGV2ZWwgc28gd2UgY2FuIHRpZSB0aGUgYnJhbmNoIHRhaWxzIHRvZ2V0aGVyLgotICAgICAqIEBwYXJhbSBmbGFncyBGbGFnIHZhbHVlIHBhc3NlZCBieSByZWZlcmVuY2UKLSAgICAgKiBAcmV0dXJuIE5vZGUgaW5kZXggb2YgZXhwcmVzc2lvbiBpbiBpbnN0cnVjdGlvbiBhcnJheQotICAgICAqIEBleGNlcHRpb24gUkVTeW50YXhFeGNlcHRpb24gVGhyb3duIGlmIHRoZSByZWd1bGFyIGV4cHJlc3Npb24gaGFzIGludmFsaWQgc3ludGF4LgotICAgICAqLwotICAgIGludCBleHByKGludFtdIGZsYWdzKSB0aHJvd3MgUkVTeW50YXhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIC8vIENyZWF0ZSBvcGVuIHBhcmVuIG5vZGUgdW5sZXNzIHdlIHdlcmUgY2FsbGVkIGZyb20gdGhlIHRvcCBsZXZlbCAod2hpY2ggaGFzIG5vIHBhcmVucykKLSAgICAgICAgaW50IHBhcmVuID0gLTE7Ci0gICAgICAgIGludCByZXQgPSAtMTsKLSAgICAgICAgaW50IGNsb3NlUGFyZW5zID0gcGFyZW5zOwotICAgICAgICBpZiAoKGZsYWdzWzBdICYgTk9ERV9UT1BMRVZFTCkgPT0gMCAmJiBwYXR0ZXJuLmNoYXJBdChpZHgpID09ICcoJykKLSAgICAgICAgewotICAgICAgICAgICAgLy8gaWYgaXRzIGEgY2x1c3RlciAoIHJhdGhlciB0aGFuIGEgcHJvcGVyIHN1YmV4cHJlc3Npb24gaWUgd2l0aCBiYWNrcmVmcyApCi0gICAgICAgICAgICBpZiAoIGlkeCArIDIgPCBsZW4gJiYgcGF0dGVybi5jaGFyQXQoIGlkeCArIDEgKSA9PSAnPycgJiYgcGF0dGVybi5jaGFyQXQoIGlkeCArIDIgKSA9PSAnOicgKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIHBhcmVuID0gMjsKLSAgICAgICAgICAgICAgICBpZHggKz0gMzsKLSAgICAgICAgICAgICAgICByZXQgPSBub2RlKCBSRS5PUF9PUEVOX0NMVVNURVIsIDAgKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBwYXJlbiA9IDE7Ci0gICAgICAgICAgICAgICAgaWR4Kys7Ci0gICAgICAgICAgICAgICAgcmV0ID0gbm9kZShSRS5PUF9PUEVOLCBwYXJlbnMrKyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZmxhZ3NbMF0gJj0gfk5PREVfVE9QTEVWRUw7Ci0KLSAgICAgICAgLy8gQ3JlYXRlIGEgYnJhbmNoIG5vZGUKLSAgICAgICAgaW50IGJyYW5jaCA9IGJyYW5jaChmbGFncyk7Ci0gICAgICAgIGlmIChyZXQgPT0gLTEpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHJldCA9IGJyYW5jaDsKLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgIHsKLSAgICAgICAgICAgIHNldE5leHRPZkVuZChyZXQsIGJyYW5jaCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBMb29wIHRocm91Z2ggYnJhbmNoZXMKLSAgICAgICAgd2hpbGUgKGlkeCA8IGxlbiAmJiBwYXR0ZXJuLmNoYXJBdChpZHgpID09ICd8JykKLSAgICAgICAgewotICAgICAgICAgICAgaWR4Kys7Ci0gICAgICAgICAgICBicmFuY2ggPSBicmFuY2goZmxhZ3MpOwotICAgICAgICAgICAgc2V0TmV4dE9mRW5kKHJldCwgYnJhbmNoKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIENyZWF0ZSBhbiBlbmRpbmcgbm9kZSAoZWl0aGVyIGEgY2xvc2UgcGFyZW4gb3IgYW4gT1BfRU5EKQotICAgICAgICBpbnQgZW5kOwotICAgICAgICBpZiAoIHBhcmVuID4gMCApCi0gICAgICAgIHsKLSAgICAgICAgICAgIGlmIChpZHggPCBsZW4gJiYgcGF0dGVybi5jaGFyQXQoaWR4KSA9PSAnKScpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgaWR4Kys7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgc3ludGF4RXJyb3IoIk1pc3NpbmcgY2xvc2UgcGFyZW4iKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmICggcGFyZW4gPT0gMSApCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgZW5kID0gbm9kZShSRS5PUF9DTE9TRSwgY2xvc2VQYXJlbnMpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIGVuZCA9IG5vZGUoIFJFLk9QX0NMT1NFX0NMVVNURVIsIDAgKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgIHsKLSAgICAgICAgICAgIGVuZCA9IG5vZGUoUkUuT1BfRU5ELCAwKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIEFwcGVuZCB0aGUgZW5kaW5nIG5vZGUgdG8gdGhlIHJldCBub2RlbGlzdAotICAgICAgICBzZXROZXh0T2ZFbmQocmV0LCBlbmQpOwotCi0gICAgICAgIC8vIEhvb2sgdGhlIGVuZHMgb2YgZWFjaCBicmFuY2ggdG8gdGhlIGVuZCBub2RlCi0gICAgICAgIGludCBjdXJyZW50Tm9kZSA9IHJldDsKLSAgICAgICAgaW50IG5leHROb2RlT2Zmc2V0ID0gaW5zdHJ1Y3Rpb25bIGN1cnJlbnROb2RlICsgUkUub2Zmc2V0TmV4dCBdOwotICAgICAgICAvLyB3aGlsZSB0aGUgbmV4dCBub2RlIG8KLSAgICAgICAgd2hpbGUgKCBuZXh0Tm9kZU9mZnNldCAhPSAwICYmIGN1cnJlbnROb2RlIDwgbGVuSW5zdHJ1Y3Rpb24gKQotICAgICAgICB7Ci0gICAgICAgICAgICAvLyBJZiBicmFuY2gsIG1ha2UgdGhlIGVuZCBvZiB0aGUgYnJhbmNoJ3Mgb3BlcmFuZCBjaGFpbiBwb2ludCB0byB0aGUgZW5kIG5vZGUuCi0gICAgICAgICAgICBpZiAoIGluc3RydWN0aW9uWyBjdXJyZW50Tm9kZSArIFJFLm9mZnNldE9wY29kZSBdID09IFJFLk9QX0JSQU5DSCApCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgc2V0TmV4dE9mRW5kKCBjdXJyZW50Tm9kZSArIFJFLm5vZGVTaXplLCBlbmQgKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIG5leHROb2RlT2Zmc2V0ID0gaW5zdHJ1Y3Rpb25bIGN1cnJlbnROb2RlICsgUkUub2Zmc2V0TmV4dCBdOwotICAgICAgICAgICAgY3VycmVudE5vZGUgKz0gbmV4dE5vZGVPZmZzZXQ7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBSZXR1cm4gdGhlIG5vZGUgbGlzdAotICAgICAgICByZXR1cm4gcmV0OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbXBpbGVzIGEgcmVndWxhciBleHByZXNzaW9uIHBhdHRlcm4gaW50byBhIHByb2dyYW0gcnVubmFibGUgYnkgdGhlIHBhdHRlcm4KLSAgICAgKiBtYXRjaGVyIGNsYXNzICdSRScuCi0gICAgICogQHBhcmFtIHBhdHRlcm4gUmVndWxhciBleHByZXNzaW9uIHBhdHRlcm4gdG8gY29tcGlsZSAoc2VlIFJFQ29tcGlsZXIgY2xhc3MKLSAgICAgKiBmb3IgZGV0YWlscykuCi0gICAgICogQHJldHVybiBBIGNvbXBpbGVkIHJlZ3VsYXIgZXhwcmVzc2lvbiBwcm9ncmFtLgotICAgICAqIEBleGNlcHRpb24gUkVTeW50YXhFeGNlcHRpb24gVGhyb3duIGlmIHRoZSByZWd1bGFyIGV4cHJlc3Npb24gaGFzIGludmFsaWQgc3ludGF4LgotICAgICAqIEBzZWUgUkVDb21waWxlcgotICAgICAqIEBzZWUgUkUKLSAgICAgKi8KLSAgICBwdWJsaWMgUkVQcm9ncmFtIGNvbXBpbGUoU3RyaW5nIHBhdHRlcm4pIHRocm93cyBSRVN5bnRheEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgLy8gSW5pdGlhbGl6ZSB2YXJpYWJsZXMgZm9yIGNvbXBpbGF0aW9uCi0gICAgICAgIHRoaXMucGF0dGVybiA9IHBhdHRlcm47ICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNhdmUgcGF0dGVybiBpbiBpbnN0YW5jZSB2YXJpYWJsZQotICAgICAgICBsZW4gPSBwYXR0ZXJuLmxlbmd0aCgpOyAgICAgICAgICAgICAgICAgICAgICAgICAvLyBQcmVjb21wdXRlIHBhdHRlcm4gbGVuZ3RoIGZvciBzcGVlZAotICAgICAgICBpZHggPSAwOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTZXQgcGFyc2luZyBpbmRleCB0byB0aGUgZmlyc3QgY2hhcmFjdGVyCi0gICAgICAgIGxlbkluc3RydWN0aW9uID0gMDsgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNldCBlbWl0dGVkIGluc3RydWN0aW9uIGNvdW50IHRvIHplcm8KLSAgICAgICAgcGFyZW5zID0gMTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2V0IHBhcmVuIGxldmVsIHRvIDEgKHRoZSBpbXBsaWNpdCBvdXRlciBwYXJlbnMpCi0gICAgICAgIGJyYWNrZXRzID0gMDsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5vIGJyYWNrZXRlZCBjbG9zdXJlcyB5ZXQKLQotICAgICAgICAvLyBJbml0aWFsaXplIHBhc3MgYnkgcmVmZXJlbmNlIGZsYWdzIHZhbHVlCi0gICAgICAgIGludFtdIGZsYWdzID0geyBOT0RFX1RPUExFVkVMIH07Ci0KLSAgICAgICAgLy8gUGFyc2UgZXhwcmVzc2lvbgotICAgICAgICBleHByKGZsYWdzKTsKLQotICAgICAgICAvLyBTaG91bGQgYmUgYXQgZW5kIG9mIGlucHV0Ci0gICAgICAgIGlmIChpZHggIT0gbGVuKQotICAgICAgICB7Ci0gICAgICAgICAgICBpZiAocGF0dGVybi5jaGFyQXQoaWR4KSA9PSAnKScpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgc3ludGF4RXJyb3IoIlVubWF0Y2hlZCBjbG9zZSBwYXJlbiIpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgc3ludGF4RXJyb3IoIlVuZXhwZWN0ZWQgaW5wdXQgcmVtYWlucyIpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gUmV0dXJuIHRoZSByZXN1bHQKLSAgICAgICAgY2hhcltdIGlucyA9IG5ldyBjaGFyW2xlbkluc3RydWN0aW9uXTsKLSAgICAgICAgU3lzdGVtLmFycmF5Y29weShpbnN0cnVjdGlvbiwgMCwgaW5zLCAwLCBsZW5JbnN0cnVjdGlvbik7Ci0gICAgICAgIHJldHVybiBuZXcgUkVQcm9ncmFtKHBhcmVucywgaW5zKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBMb2NhbCwgbmVzdGVkIGNsYXNzIGZvciBtYWludGFpbmluZyBjaGFyYWN0ZXIgcmFuZ2VzIGZvciBjaGFyYWN0ZXIgY2xhc3Nlcy4KLSAgICAgKi8KLSAgICBjbGFzcyBSRVJhbmdlCi0gICAgewotICAgICAgICBpbnQgc2l6ZSA9IDE2OyAgICAgICAgICAgICAgICAgICAgICAvLyBDYXBhY2l0eSBvZiBjdXJyZW50IHJhbmdlIGFycmF5cwotICAgICAgICBpbnRbXSBtaW5SYW5nZSA9IG5ldyBpbnRbc2l6ZV07ICAgICAvLyBSYW5nZSBtaW5pbWEKLSAgICAgICAgaW50W10gbWF4UmFuZ2UgPSBuZXcgaW50W3NpemVdOyAgICAgLy8gUmFuZ2UgbWF4aW1hCi0gICAgICAgIGludCBudW0gPSAwOyAgICAgICAgICAgICAgICAgICAgICAgIC8vIE51bWJlciBvZiByYW5nZSBhcnJheSBlbGVtZW50cyBpbiB1c2UKLQotICAgICAgICAvKioKLSAgICAgICAgICogRGVsZXRlcyB0aGUgcmFuZ2UgYXQgYSBnaXZlbiBpbmRleCBmcm9tIHRoZSByYW5nZSBsaXN0cwotICAgICAgICAgKiBAcGFyYW0gaW5kZXggSW5kZXggb2YgcmFuZ2UgdG8gZGVsZXRlIGZyb20gbWluUmFuZ2UgYW5kIG1heFJhbmdlIGFycmF5cy4KLSAgICAgICAgICovCi0gICAgICAgIHZvaWQgZGVsZXRlKGludCBpbmRleCkKLSAgICAgICAgewotICAgICAgICAgICAgLy8gUmV0dXJuIGlmIG5vIGVsZW1lbnRzIGxlZnQgb3IgaW5kZXggaXMgb3V0IG9mIHJhbmdlCi0gICAgICAgICAgICBpZiAobnVtID09IDAgfHwgaW5kZXggPj0gbnVtKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gTW92ZSBlbGVtZW50cyBkb3duCi0gICAgICAgICAgICB3aGlsZSAoKytpbmRleCA8IG51bSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBpZiAoaW5kZXggLSAxID49IDApCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICBtaW5SYW5nZVtpbmRleC0xXSA9IG1pblJhbmdlW2luZGV4XTsKLSAgICAgICAgICAgICAgICAgICAgbWF4UmFuZ2VbaW5kZXgtMV0gPSBtYXhSYW5nZVtpbmRleF07Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBPbmUgbGVzcyBlbGVtZW50IG5vdwotICAgICAgICAgICAgbnVtLS07Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogTWVyZ2VzIGEgcmFuZ2UgaW50byB0aGUgcmFuZ2UgbGlzdCwgY29hbGVzY2luZyByYW5nZXMgaWYgcG9zc2libGUuCi0gICAgICAgICAqIEBwYXJhbSBtaW4gTWluaW11bSBlbmQgb2YgcmFuZ2UKLSAgICAgICAgICogQHBhcmFtIG1heCBNYXhpbXVtIGVuZCBvZiByYW5nZQotICAgICAgICAgKi8KLSAgICAgICAgdm9pZCBtZXJnZShpbnQgbWluLCBpbnQgbWF4KQotICAgICAgICB7Ci0gICAgICAgICAgICAvLyBMb29wIHRocm91Z2ggcmFuZ2VzCi0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bTsgaSsrKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIC8vIE1pbi1tYXggaXMgc3Vic3VtZWQgYnkgbWluUmFuZ2VbaV0tbWF4UmFuZ2VbaV0KLSAgICAgICAgICAgICAgICBpZiAobWluID49IG1pblJhbmdlW2ldICYmIG1heCA8PSBtYXhSYW5nZVtpXSkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyBNaW4tbWF4IHN1YnN1bWVzIG1pblJhbmdlW2ldLW1heFJhbmdlW2ldCi0gICAgICAgICAgICAgICAgZWxzZSBpZiAobWluIDw9IG1pblJhbmdlW2ldICYmIG1heCA+PSBtYXhSYW5nZVtpXSkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIGRlbGV0ZShpKTsKLSAgICAgICAgICAgICAgICAgICAgbWVyZ2UobWluLCBtYXgpOwotICAgICAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgLy8gTWluIGlzIGluIHRoZSByYW5nZSwgYnV0IG1heCBpcyBvdXRzaWRlCi0gICAgICAgICAgICAgICAgZWxzZSBpZiAobWluID49IG1pblJhbmdlW2ldICYmIG1pbiA8PSBtYXhSYW5nZVtpXSkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIGRlbGV0ZShpKTsKLSAgICAgICAgICAgICAgICAgICAgbWluID0gbWluUmFuZ2VbaV07Ci0gICAgICAgICAgICAgICAgICAgIG1lcmdlKG1pbiwgbWF4KTsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8vIE1heCBpcyBpbiB0aGUgcmFuZ2UsIGJ1dCBtaW4gaXMgb3V0c2lkZQotICAgICAgICAgICAgICAgIGVsc2UgaWYgKG1heCA+PSBtaW5SYW5nZVtpXSAmJiBtYXggPD0gbWF4UmFuZ2VbaV0pCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICBkZWxldGUoaSk7Ci0gICAgICAgICAgICAgICAgICAgIG1heCA9IG1heFJhbmdlW2ldOwotICAgICAgICAgICAgICAgICAgICBtZXJnZShtaW4sIG1heCk7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIE11c3Qgbm90IG92ZXJsYXAgYW55IG90aGVyIHJhbmdlcwotICAgICAgICAgICAgaWYgKG51bSA+PSBzaXplKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIHNpemUgKj0gMjsKLSAgICAgICAgICAgICAgICBpbnRbXSBuZXdNaW4gPSBuZXcgaW50W3NpemVdOwotICAgICAgICAgICAgICAgIGludFtdIG5ld01heCA9IG5ldyBpbnRbc2l6ZV07Ci0gICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShtaW5SYW5nZSwgMCwgbmV3TWluLCAwLCBudW0pOwotICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkobWF4UmFuZ2UsIDAsIG5ld01heCwgMCwgbnVtKTsKLSAgICAgICAgICAgICAgICBtaW5SYW5nZSA9IG5ld01pbjsKLSAgICAgICAgICAgICAgICBtYXhSYW5nZSA9IG5ld01heDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIG1pblJhbmdlW251bV0gPSBtaW47Ci0gICAgICAgICAgICBtYXhSYW5nZVtudW1dID0gbWF4OwotICAgICAgICAgICAgbnVtKys7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogUmVtb3ZlcyBhIHJhbmdlIGJ5IGRlbGV0aW5nIG9yIHNocmlua2luZyBhbGwgb3RoZXIgcmFuZ2VzCi0gICAgICAgICAqIEBwYXJhbSBtaW4gTWluaW11bSBlbmQgb2YgcmFuZ2UKLSAgICAgICAgICogQHBhcmFtIG1heCBNYXhpbXVtIGVuZCBvZiByYW5nZQotICAgICAgICAgKi8KLSAgICAgICAgdm9pZCByZW1vdmUoaW50IG1pbiwgaW50IG1heCkKLSAgICAgICAgewotICAgICAgICAgICAgLy8gTG9vcCB0aHJvdWdoIHJhbmdlcwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW07IGkrKykKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAvLyBtaW5SYW5nZVtpXS1tYXhSYW5nZVtpXSBpcyBzdWJzdW1lZCBieSBtaW4tbWF4Ci0gICAgICAgICAgICAgICAgaWYgKG1pblJhbmdlW2ldID49IG1pbiAmJiBtYXhSYW5nZVtpXSA8PSBtYXgpCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICBkZWxldGUoaSk7Ci0gICAgICAgICAgICAgICAgICAgIGktLTsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8vIG1pbi1tYXggaXMgc3Vic3VtZWQgYnkgbWluUmFuZ2VbaV0tbWF4UmFuZ2VbaV0KLSAgICAgICAgICAgICAgICBlbHNlIGlmIChtaW4gPj0gbWluUmFuZ2VbaV0gJiYgbWF4IDw9IG1heFJhbmdlW2ldKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgaW50IG1pbnIgPSBtaW5SYW5nZVtpXTsKLSAgICAgICAgICAgICAgICAgICAgaW50IG1heHIgPSBtYXhSYW5nZVtpXTsKLSAgICAgICAgICAgICAgICAgICAgZGVsZXRlKGkpOwotICAgICAgICAgICAgICAgICAgICBpZiAobWluciA8IG1pbikKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgbWVyZ2UobWluciwgbWluIC0gMSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgaWYgKG1heCA8IG1heHIpCi0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIG1lcmdlKG1heCArIDEsIG1heHIpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyBtaW5SYW5nZSBpcyBpbiB0aGUgcmFuZ2UsIGJ1dCBtYXhSYW5nZSBpcyBvdXRzaWRlCi0gICAgICAgICAgICAgICAgZWxzZSBpZiAobWluUmFuZ2VbaV0gPj0gbWluICYmIG1pblJhbmdlW2ldIDw9IG1heCkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIG1pblJhbmdlW2ldID0gbWF4ICsgMTsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8vIG1heFJhbmdlIGlzIGluIHRoZSByYW5nZSwgYnV0IG1pblJhbmdlIGlzIG91dHNpZGUKLSAgICAgICAgICAgICAgICBlbHNlIGlmIChtYXhSYW5nZVtpXSA+PSBtaW4gJiYgbWF4UmFuZ2VbaV0gPD0gbWF4KQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgbWF4UmFuZ2VbaV0gPSBtaW4gLSAxOwotICAgICAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIEluY2x1ZGVzIChvciBleGNsdWRlcykgdGhlIHJhbmdlIGZyb20gbWluIHRvIG1heCwgaW5jbHVzaXZlLgotICAgICAgICAgKiBAcGFyYW0gbWluIE1pbmltdW0gZW5kIG9mIHJhbmdlCi0gICAgICAgICAqIEBwYXJhbSBtYXggTWF4aW11bSBlbmQgb2YgcmFuZ2UKLSAgICAgICAgICogQHBhcmFtIGluY2x1ZGUgVHJ1ZSBpZiByYW5nZSBzaG91bGQgYmUgaW5jbHVkZWQuICBGYWxzZSBvdGhlcndpc2UuCi0gICAgICAgICAqLwotICAgICAgICB2b2lkIGluY2x1ZGUoaW50IG1pbiwgaW50IG1heCwgYm9vbGVhbiBpbmNsdWRlKQotICAgICAgICB7Ci0gICAgICAgICAgICBpZiAoaW5jbHVkZSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBtZXJnZShtaW4sIG1heCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgcmVtb3ZlKG1pbiwgbWF4KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBJbmNsdWRlcyBhIHJhbmdlIHdpdGggdGhlIHNhbWUgbWluIGFuZCBtYXgKLSAgICAgICAgICogQHBhcmFtIG1pbm1heCBNaW5pbXVtIGFuZCBtYXhpbXVtIGVuZCBvZiByYW5nZSAoaW5jbHVzaXZlKQotICAgICAgICAgKiBAcGFyYW0gaW5jbHVkZSBUcnVlIGlmIHJhbmdlIHNob3VsZCBiZSBpbmNsdWRlZC4gIEZhbHNlIG90aGVyd2lzZS4KLSAgICAgICAgICovCi0gICAgICAgIHZvaWQgaW5jbHVkZShjaGFyIG1pbm1heCwgYm9vbGVhbiBpbmNsdWRlKQotICAgICAgICB7Ci0gICAgICAgICAgICBpbmNsdWRlKG1pbm1heCwgbWlubWF4LCBpbmNsdWRlKTsKLSAgICAgICAgfQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvcmVnZXhwL2ludGVybmFsL1JFRGVidWdDb21waWxlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9yZWdleHAvaW50ZXJuYWwvUkVEZWJ1Z0NvbXBpbGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDgxNWQ0ZmQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9yZWdleHAvaW50ZXJuYWwvUkVEZWJ1Z0NvbXBpbGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMjUgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5yZWdleHAuaW50ZXJuYWw7Ci0KLWltcG9ydCBqYXZhLmlvLlByaW50V3JpdGVyOwotaW1wb3J0IGphdmEudXRpbC5IYXNodGFibGU7Ci0KLS8qKgotICogQSBzdWJjbGFzcyBvZiBSRUNvbXBpbGVyIHdoaWNoIGNhbiBkdW1wIGEgcmVndWxhciBleHByZXNzaW9uIHByb2dyYW0KLSAqIGZvciBkZWJ1Z2dpbmcgcHVycG9zZXMuCi0gKgotICogQGF1dGhvciA8YSBocmVmPSJtYWlsdG86am9ubEBtdXBwZXRsYWJzLmNvbSI+Sm9uYXRoYW4gTG9ja2U8L2E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBSRURlYnVnQ29tcGlsZXIgZXh0ZW5kcyBSRUNvbXBpbGVyCi17Ci0gICAgLyoqCi0gICAgICogTWFwcGluZyBmcm9tIG9wY29kZXMgdG8gZGVzY3JpcHRpdmUgc3RyaW5ncwotICAgICAqLwotICAgIHN0YXRpYyBIYXNodGFibGUgaGFzaE9wY29kZSA9IG5ldyBIYXNodGFibGUoKTsKLSAgICBzdGF0aWMKLSAgICB7Ci0gICAgICAgIGhhc2hPcGNvZGUucHV0KG5ldyBJbnRlZ2VyKFJFLk9QX1JFTFVDVEFOVFNUQVIpLCAgICAiT1BfUkVMVUNUQU5UU1RBUiIpOwotICAgICAgICBoYXNoT3Bjb2RlLnB1dChuZXcgSW50ZWdlcihSRS5PUF9SRUxVQ1RBTlRQTFVTKSwgICAgIk9QX1JFTFVDVEFOVFBMVVMiKTsKLSAgICAgICAgaGFzaE9wY29kZS5wdXQobmV3IEludGVnZXIoUkUuT1BfUkVMVUNUQU5UTUFZQkUpLCAgICJPUF9SRUxVQ1RBTlRNQVlCRSIpOwotICAgICAgICBoYXNoT3Bjb2RlLnB1dChuZXcgSW50ZWdlcihSRS5PUF9FTkQpLCAgICAgICAgICAgICAgIk9QX0VORCIpOwotICAgICAgICBoYXNoT3Bjb2RlLnB1dChuZXcgSW50ZWdlcihSRS5PUF9CT0wpLCAgICAgICAgICAgICAgIk9QX0JPTCIpOwotICAgICAgICBoYXNoT3Bjb2RlLnB1dChuZXcgSW50ZWdlcihSRS5PUF9FT0wpLCAgICAgICAgICAgICAgIk9QX0VPTCIpOwotICAgICAgICBoYXNoT3Bjb2RlLnB1dChuZXcgSW50ZWdlcihSRS5PUF9BTlkpLCAgICAgICAgICAgICAgIk9QX0FOWSIpOwotICAgICAgICBoYXNoT3Bjb2RlLnB1dChuZXcgSW50ZWdlcihSRS5PUF9BTllPRiksICAgICAgICAgICAgIk9QX0FOWU9GIik7Ci0gICAgICAgIGhhc2hPcGNvZGUucHV0KG5ldyBJbnRlZ2VyKFJFLk9QX0JSQU5DSCksICAgICAgICAgICAiT1BfQlJBTkNIIik7Ci0gICAgICAgIGhhc2hPcGNvZGUucHV0KG5ldyBJbnRlZ2VyKFJFLk9QX0FUT00pLCAgICAgICAgICAgICAiT1BfQVRPTSIpOwotICAgICAgICBoYXNoT3Bjb2RlLnB1dChuZXcgSW50ZWdlcihSRS5PUF9TVEFSKSwgICAgICAgICAgICAgIk9QX1NUQVIiKTsKLSAgICAgICAgaGFzaE9wY29kZS5wdXQobmV3IEludGVnZXIoUkUuT1BfUExVUyksICAgICAgICAgICAgICJPUF9QTFVTIik7Ci0gICAgICAgIGhhc2hPcGNvZGUucHV0KG5ldyBJbnRlZ2VyKFJFLk9QX01BWUJFKSwgICAgICAgICAgICAiT1BfTUFZQkUiKTsKLSAgICAgICAgaGFzaE9wY29kZS5wdXQobmV3IEludGVnZXIoUkUuT1BfTk9USElORyksICAgICAgICAgICJPUF9OT1RISU5HIik7Ci0gICAgICAgIGhhc2hPcGNvZGUucHV0KG5ldyBJbnRlZ2VyKFJFLk9QX0dPVE8pLCAgICAgICAgICAgICAiT1BfR09UTyIpOwotICAgICAgICBoYXNoT3Bjb2RlLnB1dChuZXcgSW50ZWdlcihSRS5PUF9FU0NBUEUpLCAgICAgICAgICAgIk9QX0VTQ0FQRSIpOwotICAgICAgICBoYXNoT3Bjb2RlLnB1dChuZXcgSW50ZWdlcihSRS5PUF9PUEVOKSwgICAgICAgICAgICAgIk9QX09QRU4iKTsKLSAgICAgICAgaGFzaE9wY29kZS5wdXQobmV3IEludGVnZXIoUkUuT1BfQ0xPU0UpLCAgICAgICAgICAgICJPUF9DTE9TRSIpOwotICAgICAgICBoYXNoT3Bjb2RlLnB1dChuZXcgSW50ZWdlcihSRS5PUF9CQUNLUkVGKSwgICAgICAgICAgIk9QX0JBQ0tSRUYiKTsKLSAgICAgICAgaGFzaE9wY29kZS5wdXQobmV3IEludGVnZXIoUkUuT1BfUE9TSVhDTEFTUyksICAgICAgICJPUF9QT1NJWENMQVNTIik7Ci0gICAgICAgIGhhc2hPcGNvZGUucHV0KG5ldyBJbnRlZ2VyKFJFLk9QX09QRU5fQ0xVU1RFUiksICAgICAgIk9QX09QRU5fQ0xVU1RFUiIpOwotICAgICAgICBoYXNoT3Bjb2RlLnB1dChuZXcgSW50ZWdlcihSRS5PUF9DTE9TRV9DTFVTVEVSKSwgICAgICAiT1BfQ0xPU0VfQ0xVU1RFUiIpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYSBkZXNjcmlwdGl2ZSBzdHJpbmcgZm9yIGFuIG9wY29kZS4KLSAgICAgKiBAcGFyYW0gb3Bjb2RlIE9wY29kZSB0byBjb252ZXJ0IHRvIGEgc3RyaW5nCi0gICAgICogQHJldHVybiBEZXNjcmlwdGlvbiBvZiBvcGNvZGUKLSAgICAgKi8KLSAgICBTdHJpbmcgb3Bjb2RlVG9TdHJpbmcoY2hhciBvcGNvZGUpCi0gICAgewotICAgICAgICAvLyBHZXQgc3RyaW5nIGZvciBvcGNvZGUKLSAgICAgICAgU3RyaW5nIHJldCA9KFN0cmluZyloYXNoT3Bjb2RlLmdldChuZXcgSW50ZWdlcihvcGNvZGUpKTsKLQotICAgICAgICAvLyBKdXN0IGluIGNhc2Ugd2UgaGF2ZSBhIGNvcnJ1cHQgcHJvZ3JhbQotICAgICAgICBpZiAocmV0ID09IG51bGwpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHJldCA9ICJPUF8/Pz8/IjsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gcmV0OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybiBhIHN0cmluZyBkZXNjcmliaW5nIGEgKHBvc3NpYmx5IHVucHJpbnRhYmxlKSBjaGFyYWN0ZXIuCi0gICAgICogQHBhcmFtIGMgQ2hhcmFjdGVyIHRvIGNvbnZlcnQgdG8gYSBwcmludGFibGUgcmVwcmVzZW50YXRpb24KLSAgICAgKiBAcmV0dXJuIFN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBjaGFyYWN0ZXIKLSAgICAgKi8KLSAgICBTdHJpbmcgY2hhclRvU3RyaW5nKGNoYXIgYykKLSAgICB7Ci0gICAgICAgIC8vIElmIGl0J3MgdW5wcmludGFibGUsIGNvbnZlcnQgdG8gJ1wjIyMnCi0gICAgICAgIGlmIChjIDwgJyAnIHx8IGMgPiAxMjcpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHJldHVybiAiXFwiICsgKGludCljOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gUmV0dXJuIHRoZSBjaGFyYWN0ZXIgYXMgYSBzdHJpbmcKLSAgICAgICAgcmV0dXJuIFN0cmluZy52YWx1ZU9mKGMpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYSBkZXNjcmlwdGl2ZSBzdHJpbmcgZm9yIGEgbm9kZSBpbiBhIHJlZ3VsYXIgZXhwcmVzc2lvbiBwcm9ncmFtLgotICAgICAqIEBwYXJhbSBub2RlIE5vZGUgdG8gZGVzY3JpYmUKLSAgICAgKiBAcmV0dXJuIERlc2NyaXB0aW9uIG9mIG5vZGUKLSAgICAgKi8KLSAgICBTdHJpbmcgbm9kZVRvU3RyaW5nKGludCBub2RlKQotICAgIHsKLSAgICAgICAgLy8gR2V0IG9wY29kZSBhbmQgb3BkYXRhIGZvciBub2RlCi0gICAgICAgIGNoYXIgb3Bjb2RlID0gICAgICBpbnN0cnVjdGlvbltub2RlICsgUkUub2Zmc2V0T3Bjb2RlXTsKLSAgICAgICAgaW50IG9wZGF0YSAgPSAoaW50KWluc3RydWN0aW9uW25vZGUgKyBSRS5vZmZzZXRPcGRhdGFdOwotCi0gICAgICAgIC8vIFJldHVybiBvcGNvZGUgYXMgYSBzdHJpbmcgYW5kIG9wZGF0YSB2YWx1ZQotICAgICAgICByZXR1cm4gb3Bjb2RlVG9TdHJpbmcob3Bjb2RlKSArICIsIG9wZGF0YSA9ICIgKyBvcGRhdGE7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSW5zZXJ0cyBhIG5vZGUgd2l0aCBhIGdpdmVuIG9wY29kZSBhbmQgb3BkYXRhIGF0IGluc2VydEF0LiAgVGhlIG5vZGUgcmVsYXRpdmUgbmV4dAotICAgICAqIHBvaW50ZXIgaXMgaW5pdGlhbGl6ZWQgdG8gMC4KLSAgICAgKiBAcGFyYW0gb3Bjb2RlIE9wY29kZSBmb3IgbmV3IG5vZGUKLSAgICAgKiBAcGFyYW0gb3BkYXRhIE9wZGF0YSBmb3IgbmV3IG5vZGUgKG9ubHkgdGhlIGxvdyAxNiBiaXRzIGFyZSBjdXJyZW50bHkgdXNlZCkKLSAgICAgKiBAcGFyYW0gaW5zZXJ0QXQgSW5kZXggYXQgd2hpY2ggdG8gaW5zZXJ0IHRoZSBuZXcgbm9kZSBpbiB0aGUgcHJvZ3JhbSAqIC8KLSAgICB2b2lkIG5vZGVJbnNlcnQoY2hhciBvcGNvZGUsIGludCBvcGRhdGEsIGludCBpbnNlcnRBdCkgewotICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oICI9PT09PiAiICsgb3Bjb2RlICsgIiAiICsgb3BkYXRhICsgIiAiICsgaW5zZXJ0QXQgKTsKLSAgICAgICAgUHJpbnRXcml0ZXIgd3JpdGVyID0gbmV3IFByaW50V3JpdGVyKCBTeXN0ZW0ub3V0ICk7Ci0gICAgICAgIGR1bXBQcm9ncmFtKCB3cml0ZXIgKTsKLSAgICAgICAgc3VwZXIubm9kZUluc2VydCggb3Bjb2RlLCBvcGRhdGEsIGluc2VydEF0ICk7Ci0gICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbiggIj09PT08ICIgKTsKLSAgICAgICAgZHVtcFByb2dyYW0oIHdyaXRlciApOwotICAgICAgICB3cml0ZXIuZmx1c2goKTsKLSAgICB9LyoqLwotCi0KLSAgICAvKioKLSAgICAqIEFwcGVuZHMgYSBub2RlIHRvIHRoZSBlbmQgb2YgYSBub2RlIGNoYWluCi0gICAgKiBAcGFyYW0gbm9kZSBTdGFydCBvZiBub2RlIGNoYWluIHRvIHRyYXZlcnNlCi0gICAgKiBAcGFyYW0gcG9pbnRUbyBOb2RlIHRvIGhhdmUgdGhlIHRhaWwgb2YgdGhlIGNoYWluIHBvaW50IHRvICogLwotICAgIHZvaWQgc2V0TmV4dE9mRW5kKGludCBub2RlLCBpbnQgcG9pbnRUbykgewotICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oICI9PT09PiAiICsgbm9kZSArICIgIiArIHBvaW50VG8gKTsKLSAgICAgICAgUHJpbnRXcml0ZXIgd3JpdGVyID0gbmV3IFByaW50V3JpdGVyKCBTeXN0ZW0ub3V0ICk7Ci0gICAgICAgIGR1bXBQcm9ncmFtKCB3cml0ZXIgKTsKLSAgICAgICAgc3VwZXIuc2V0TmV4dE9mRW5kKCBub2RlLCBwb2ludFRvICk7Ci0gICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbiggIj09PT08ICIgKTsKLSAgICAgICAgZHVtcFByb2dyYW0oIHdyaXRlciApOwotICAgICAgICB3cml0ZXIuZmx1c2goKTsKLSAgICB9LyoqLwotCi0KLSAgICAvKioKLSAgICAgKiBEdW1wcyB0aGUgY3VycmVudCBwcm9ncmFtIHRvIGEgUHJpbnRXcml0ZXIKLSAgICAgKiBAcGFyYW0gcCBQcmludFdyaXRlciBmb3IgcHJvZ3JhbSBkdW1wIG91dHB1dAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGR1bXBQcm9ncmFtKFByaW50V3JpdGVyIHApCi0gICAgewotICAgICAgICAvLyBMb29wIHRocm91Z2ggdGhlIHdob2xlIHByb2dyYW0KLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5JbnN0cnVjdGlvbjsgKQotICAgICAgICB7Ci0gICAgICAgICAgICAvLyBHZXQgb3Bjb2RlLCBvcGRhdGEgYW5kIG5leHQgZmllbGRzIG9mIGN1cnJlbnQgcHJvZ3JhbSBub2RlCi0gICAgICAgICAgICBjaGFyIG9wY29kZSA9ICAgICAgICBpbnN0cnVjdGlvbltpICsgUkUub2Zmc2V0T3Bjb2RlXTsKLSAgICAgICAgICAgIGNoYXIgb3BkYXRhID0gICAgICAgIGluc3RydWN0aW9uW2kgKyBSRS5vZmZzZXRPcGRhdGFdOwotICAgICAgICAgICAgc2hvcnQgbmV4dCAgPSAoc2hvcnQpaW5zdHJ1Y3Rpb25baSArIFJFLm9mZnNldE5leHRdOwotCi0gICAgICAgICAgICAvLyBEaXNwbGF5IHRoZSBjdXJyZW50IHByb2dyYW0gbm9kZQotICAgICAgICAgICAgcC5wcmludChpICsgIi4gIiArIG5vZGVUb1N0cmluZyhpKSArICIsIG5leHQgPSAiKTsKLQotICAgICAgICAgICAgLy8gSWYgdGhlcmUncyBubyBuZXh0LCBzYXkgJ25vbmUnLCBvdGhlcndpc2UgZ2l2ZSBhYnNvbHV0ZSBpbmRleCBvZiBuZXh0IG5vZGUKLSAgICAgICAgICAgIGlmIChuZXh0ID09IDApCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgcC5wcmludCgibm9uZSIpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIHAucHJpbnQoaSArIG5leHQpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBNb3ZlIHBhc3Qgbm9kZQotICAgICAgICAgICAgaSArPSBSRS5ub2RlU2l6ZTsKLQotICAgICAgICAgICAgLy8gSWYgY2hhcmFjdGVyIGNsYXNzCi0gICAgICAgICAgICBpZiAob3Bjb2RlID09IFJFLk9QX0FOWU9GKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIC8vIE9wZW5pbmcgYnJhY2tldCBmb3Igc3RhcnQgb2YgY2hhciBjbGFzcwotICAgICAgICAgICAgICAgIHAucHJpbnQoIiwgWyIpOwotCi0gICAgICAgICAgICAgICAgLy8gU2hvdyBlYWNoIHJhbmdlIGluIHRoZSBjaGFyIGNsYXNzCi0gICAgICAgICAgICAgICAgaW50IHJhbmdlQ291bnQgPSBvcGRhdGE7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgciA9IDA7IHIgPCByYW5nZUNvdW50OyByKyspCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAvLyBHZXQgZmlyc3QgYW5kIGxhc3QgY2hhcnMgaW4gcmFuZ2UKLSAgICAgICAgICAgICAgICAgICAgY2hhciBjaGFyRmlyc3QgPSBpbnN0cnVjdGlvbltpKytdOwotICAgICAgICAgICAgICAgICAgICBjaGFyIGNoYXJMYXN0ICA9IGluc3RydWN0aW9uW2krK107Ci0KLSAgICAgICAgICAgICAgICAgICAgLy8gUHJpbnQgcmFuZ2UgYXMgWC1ZLCB1bmxlc3MgcmFuZ2UgZW5jb21wYXNzZXMgb25seSBvbmUgY2hhcgotICAgICAgICAgICAgICAgICAgICBpZiAoY2hhckZpcnN0ID09IGNoYXJMYXN0KQotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBwLnByaW50KGNoYXJUb1N0cmluZyhjaGFyRmlyc3QpKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHAucHJpbnQoY2hhclRvU3RyaW5nKGNoYXJGaXJzdCkgKyAiLSIgKyBjaGFyVG9TdHJpbmcoY2hhckxhc3QpKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8vIEFubm90YXRlIHRoZSBlbmQgb2YgdGhlIGNoYXIgY2xhc3MKLSAgICAgICAgICAgICAgICBwLnByaW50KCJdIik7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIElmIGF0b20KLSAgICAgICAgICAgIGlmIChvcGNvZGUgPT0gUkUuT1BfQVRPTSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAvLyBPcGVuIHF1b3RlCi0gICAgICAgICAgICAgICAgcC5wcmludCgiLCBcIiIpOwotCi0gICAgICAgICAgICAgICAgLy8gUHJpbnQgZWFjaCBjaGFyYWN0ZXIgaW4gdGhlIGF0b20KLSAgICAgICAgICAgICAgICBmb3IgKGludCBsZW4gPSBvcGRhdGE7IGxlbi0tICE9IDA7ICkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIHAucHJpbnQoY2hhclRvU3RyaW5nKGluc3RydWN0aW9uW2krK10pKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyBDbG9zZSBxdW90ZQotICAgICAgICAgICAgICAgIHAucHJpbnQoIlwiIik7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIFByaW50IGEgbmV3bGluZQotICAgICAgICAgICAgcC5wcmludGxuKCIiKTsKLSAgICAgICAgfQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvcmVnZXhwL2ludGVybmFsL1JFUHJvZ3JhbS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9yZWdleHAvaW50ZXJuYWwvUkVQcm9ncmFtLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGY3YTM5Y2UuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9yZWdleHAvaW50ZXJuYWwvUkVQcm9ncmFtLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNTggKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5yZWdleHAuaW50ZXJuYWw7Ci0KLWltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKLQotLyoqCi0gKiBBIGNsYXNzIHRoYXQgaG9sZHMgY29tcGlsZWQgcmVndWxhciBleHByZXNzaW9ucy4gIFRoaXMgaXMgZXhwb3NlZCBtYWlubHkKLSAqIGZvciB1c2UgYnkgdGhlIHJlY29tcGlsZSB1dGlsaXR5ICh3aGljaCBoZWxwcyB5b3UgcHJvZHVjZSBwcmVjb21waWxlZAotICogUkVQcm9ncmFtIG9iamVjdHMpLiBZb3Ugc2hvdWxkIG5vdCBvdGhlcndpc2UgbmVlZCB0byB3b3JrIGRpcmVjdGx5IHdpdGgKLSAqIHRoaXMgY2xhc3MuCi0qCi0gKiBAc2VlIFJFCi0gKiBAc2VlIFJFQ29tcGlsZXIKLSAqCi0gKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzpqb25sQG11cHBldGxhYnMuY29tIj5Kb25hdGhhbiBMb2NrZTwvYT4KLSAqLwotcHVibGljIGNsYXNzIFJFUHJvZ3JhbSBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZQotewotICAgIHN0YXRpYyBmaW5hbCBpbnQgT1BUX0hBU0JBQ0tSRUZTID0gMTsKLQotICAgIGNoYXJbXSBpbnN0cnVjdGlvbjsgICAgICAgICAvLyBUaGUgY29tcGlsZWQgcmVndWxhciBleHByZXNzaW9uICdwcm9ncmFtJwotICAgIGludCBsZW5JbnN0cnVjdGlvbjsgICAgICAgICAvLyBUaGUgYW1vdW50IG9mIHRoZSBpbnN0cnVjdGlvbiBidWZmZXIgaW4gdXNlCi0gICAgY2hhcltdIHByZWZpeDsgICAgICAgICAgICAgIC8vIFByZWZpeCBzdHJpbmcgb3B0aW1pemF0aW9uCi0gICAgaW50IGZsYWdzOyAgICAgICAgICAgICAgICAgIC8vIE9wdGltaXphdGlvbiBmbGFncyAoUkVQcm9ncmFtLk9QVF8qKQotICAgIGludCBtYXhQYXJlbnMgPSAtMTsKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHMgYSBwcm9ncmFtIG9iamVjdCBmcm9tIGEgY2hhcmFjdGVyIGFycmF5Ci0gICAgICogQHBhcmFtIGluc3RydWN0aW9uIENoYXJhY3RlciBhcnJheSB3aXRoIFJFIG9wY29kZSBpbnN0cnVjdGlvbnMgaW4gaXQKLSAgICAgKi8KLSAgICBwdWJsaWMgUkVQcm9ncmFtKGNoYXJbXSBpbnN0cnVjdGlvbikKLSAgICB7Ci0gICAgICAgIHRoaXMoaW5zdHJ1Y3Rpb24sIGluc3RydWN0aW9uLmxlbmd0aCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0cyBhIHByb2dyYW0gb2JqZWN0IGZyb20gYSBjaGFyYWN0ZXIgYXJyYXkKLSAgICAgKiBAcGFyYW0gcGFyZW5zIENvdW50IG9mIHBhcmVucyBpbiB0aGUgcHJvZ3JhbQotICAgICAqIEBwYXJhbSBpbnN0cnVjdGlvbiBDaGFyYWN0ZXIgYXJyYXkgd2l0aCBSRSBvcGNvZGUgaW5zdHJ1Y3Rpb25zIGluIGl0Ci0gICAgICovCi0gICAgcHVibGljIFJFUHJvZ3JhbShpbnQgcGFyZW5zLCBjaGFyW10gaW5zdHJ1Y3Rpb24pCi0gICAgewotICAgICAgICB0aGlzKGluc3RydWN0aW9uLCBpbnN0cnVjdGlvbi5sZW5ndGgpOwotICAgICAgICB0aGlzLm1heFBhcmVucyA9IHBhcmVuczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RzIGEgcHJvZ3JhbSBvYmplY3QgZnJvbSBhIGNoYXJhY3RlciBhcnJheQotICAgICAqIEBwYXJhbSBpbnN0cnVjdGlvbiBDaGFyYWN0ZXIgYXJyYXkgd2l0aCBSRSBvcGNvZGUgaW5zdHJ1Y3Rpb25zIGluIGl0Ci0gICAgICogQHBhcmFtIGxlbkluc3RydWN0aW9uIEFtb3VudCBvZiBpbnN0cnVjdGlvbiBhcnJheSBpbiB1c2UKLSAgICAgKi8KLSAgICBwdWJsaWMgUkVQcm9ncmFtKGNoYXJbXSBpbnN0cnVjdGlvbiwgaW50IGxlbkluc3RydWN0aW9uKQotICAgIHsKLSAgICAgICAgc2V0SW5zdHJ1Y3Rpb25zKGluc3RydWN0aW9uLCBsZW5JbnN0cnVjdGlvbik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhIGNvcHkgb2YgdGhlIGN1cnJlbnQgcmVndWxhciBleHByZXNzaW9uIHByb2dyYW0gaW4gYSBjaGFyYWN0ZXIKLSAgICAgKiBhcnJheSB0aGF0IGlzIGV4YWN0bHkgdGhlIHJpZ2h0IGxlbmd0aCB0byBob2xkIHRoZSBwcm9ncmFtLiAgSWYgdGhlcmUgaXMKLSAgICAgKiBubyBwcm9ncmFtIGNvbXBpbGVkIHlldCwgZ2V0SW5zdHJ1Y3Rpb25zKCkgd2lsbCByZXR1cm4gbnVsbC4KLSAgICAgKiBAcmV0dXJuIEEgY29weSBvZiB0aGUgY3VycmVudCBjb21waWxlZCBSRSBwcm9ncmFtCi0gICAgICovCi0gICAgcHVibGljIGNoYXJbXSBnZXRJbnN0cnVjdGlvbnMoKQotICAgIHsKLSAgICAgICAgLy8gRW5zdXJlIHByb2dyYW0gaGFzIGJlZW4gY29tcGlsZWQhCi0gICAgICAgIGlmIChsZW5JbnN0cnVjdGlvbiAhPSAwKQotICAgICAgICB7Ci0gICAgICAgICAgICAvLyBSZXR1cm4gY29weSBvZiBwcm9ncmFtCi0gICAgICAgICAgICBjaGFyW10gcmV0ID0gbmV3IGNoYXJbbGVuSW5zdHJ1Y3Rpb25dOwotICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShpbnN0cnVjdGlvbiwgMCwgcmV0LCAwLCBsZW5JbnN0cnVjdGlvbik7Ci0gICAgICAgICAgICByZXR1cm4gcmV0OwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldHMgYSBuZXcgcmVndWxhciBleHByZXNzaW9uIHByb2dyYW0gdG8gcnVuLiAgSXQgaXMgdGhpcyBtZXRob2Qgd2hpY2gKLSAgICAgKiBwZXJmb3JtcyBhbnkgc3BlY2lhbCBjb21waWxlLXRpbWUgc2VhcmNoIG9wdGltaXphdGlvbnMuICBDdXJyZW50bHkgb25seQotICAgICAqIHR3byBvcHRpbWl6YXRpb25zIGFyZSBpbiBwbGFjZSAtIG9uZSB3aGljaCBjaGVja3MgZm9yIGJhY2tyZWZlcmVuY2VzCi0gICAgICogKHNvIHRoYXQgdGhleSBjYW4gYmUgbGF6aWx5IGFsbG9jYXRlZCkgYW5kIGFub3RoZXIgd2hpY2ggYXR0ZW1wdHMgdG8KLSAgICAgKiBmaW5kIGFuIHByZWZpeCBhbmNob3Igc3RyaW5nIHNvIHRoYXQgc3Vic3RhbnRpYWwgYW1vdW50cyBvZiBpbnB1dCBjYW4KLSAgICAgKiBwb3RlbnRpYWxseSBiZSBza2lwcGVkIHdpdGhvdXQgcnVubmluZyB0aGUgYWN0dWFsIHByb2dyYW0uCi0gICAgICogQHBhcmFtIGluc3RydWN0aW9uIFByb2dyYW0gaW5zdHJ1Y3Rpb24gYnVmZmVyCi0gICAgICogQHBhcmFtIGxlbkluc3RydWN0aW9uIExlbmd0aCBvZiBpbnN0cnVjdGlvbiBidWZmZXIgaW4gdXNlCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0SW5zdHJ1Y3Rpb25zKGNoYXJbXSBpbnN0cnVjdGlvbiwgaW50IGxlbkluc3RydWN0aW9uKQotICAgIHsKLSAgICAgICAgLy8gU2F2ZSByZWZlcmVuY2UgdG8gaW5zdHJ1Y3Rpb24gYXJyYXkKLSAgICAgICAgdGhpcy5pbnN0cnVjdGlvbiA9IGluc3RydWN0aW9uOwotICAgICAgICB0aGlzLmxlbkluc3RydWN0aW9uID0gbGVuSW5zdHJ1Y3Rpb247Ci0KLSAgICAgICAgLy8gSW5pdGlhbGl6ZSBvdGhlciBwcm9ncmFtLXJlbGF0ZWQgdmFyaWFibGVzCi0gICAgICAgIGZsYWdzID0gMDsKLSAgICAgICAgcHJlZml4ID0gbnVsbDsKLQotICAgICAgICAvLyBUcnkgdmFyaW91cyBjb21waWxlLXRpbWUgb3B0aW1pemF0aW9ucyBpZiB0aGVyZSdzIGEgcHJvZ3JhbQotICAgICAgICBpZiAoaW5zdHJ1Y3Rpb24gIT0gbnVsbCAmJiBsZW5JbnN0cnVjdGlvbiAhPSAwKQotICAgICAgICB7Ci0gICAgICAgICAgICAvLyBJZiB0aGUgZmlyc3Qgbm9kZSBpcyBhIGJyYW5jaAotICAgICAgICAgICAgaWYgKGxlbkluc3RydWN0aW9uID49IFJFLm5vZGVTaXplICYmIGluc3RydWN0aW9uWzAgKyBSRS5vZmZzZXRPcGNvZGVdID09IFJFLk9QX0JSQU5DSCkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAvLyB0byB0aGUgZW5kIG5vZGUKLSAgICAgICAgICAgICAgICBpbnQgbmV4dCA9IGluc3RydWN0aW9uWzAgKyBSRS5vZmZzZXROZXh0XTsKLSAgICAgICAgICAgICAgICBpZiAoaW5zdHJ1Y3Rpb25bbmV4dCArIFJFLm9mZnNldE9wY29kZV0gPT0gUkUuT1BfRU5EKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gYW5kIHRoZSBicmFuY2ggc3RhcnRzIHdpdGggYW4gYXRvbQotICAgICAgICAgICAgICAgICAgICBpZiAobGVuSW5zdHJ1Y3Rpb24gPj0gKFJFLm5vZGVTaXplICogMikgJiYgaW5zdHJ1Y3Rpb25bUkUubm9kZVNpemUgKyBSRS5vZmZzZXRPcGNvZGVdID09IFJFLk9QX0FUT00pCi0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoZW4gZ2V0IHRoYXQgYXRvbSBhcyBhbiBwcmVmaXggYmVjYXVzZSB0aGVyZSdzIG5vIG90aGVyIGNob2ljZQotICAgICAgICAgICAgICAgICAgICAgICAgaW50IGxlbkF0b20gPSBpbnN0cnVjdGlvbltSRS5ub2RlU2l6ZSArIFJFLm9mZnNldE9wZGF0YV07Ci0gICAgICAgICAgICAgICAgICAgICAgICBwcmVmaXggPSBuZXcgY2hhcltsZW5BdG9tXTsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoaW5zdHJ1Y3Rpb24sIFJFLm5vZGVTaXplICogMiwgcHJlZml4LCAwLCBsZW5BdG9tKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgQmFja3JlZlNjYW5Mb29wOgotCi0gICAgICAgICAgICAvLyBDaGVjayBmb3IgYmFja3JlZmVyZW5jZXMKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuSW5zdHJ1Y3Rpb247IGkgKz0gUkUubm9kZVNpemUpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgc3dpdGNoIChpbnN0cnVjdGlvbltpICsgUkUub2Zmc2V0T3Bjb2RlXSkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgUkUuT1BfQU5ZT0Y6Ci0gICAgICAgICAgICAgICAgICAgICAgICBpICs9IChpbnN0cnVjdGlvbltpICsgUkUub2Zmc2V0T3BkYXRhXSAqIDIpOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgICAgICAgICAgICAgY2FzZSBSRS5PUF9BVE9NOgotICAgICAgICAgICAgICAgICAgICAgICAgaSArPSBpbnN0cnVjdGlvbltpICsgUkUub2Zmc2V0T3BkYXRhXTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgICAgICAgICAgICAgIGNhc2UgUkUuT1BfQkFDS1JFRjoKLSAgICAgICAgICAgICAgICAgICAgICAgIGZsYWdzIHw9IE9QVF9IQVNCQUNLUkVGUzsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrIEJhY2tyZWZTY2FuTG9vcDsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3JlZ2V4cC9pbnRlcm5hbC9SRVN5bnRheEV4Y2VwdGlvbi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9yZWdleHAvaW50ZXJuYWwvUkVTeW50YXhFeGNlcHRpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYTEzZjkwMS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3JlZ2V4cC9pbnRlcm5hbC9SRVN5bnRheEV4Y2VwdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDMgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5yZWdleHAuaW50ZXJuYWw7Ci0KLS8qKgotICogRXhjZXB0aW9uIHRocm93biB0byBpbmRpY2F0ZSBhIHN5bnRheCBlcnJvciBpbiBhIHJlZ3VsYXIgZXhwcmVzc2lvbi4KLSAqIFRoaXMgaXMgYSBub24tY2hlY2tlZCBleGNlcHRpb24gYmVjYXVzZSB5b3Ugc2hvdWxkIG9ubHkgaGF2ZSBwcm9ibGVtcyBjb21waWxpbmcKLSAqIGEgcmVndWxhciBleHByZXNzaW9uIGR1cmluZyBkZXZlbG9wbWVudC4KLSAqIElmIHlvdSBhcmUgbWFraW5nIHJlZ3VsYXIgZXhwcmVzaW9uIHByb2dyYW1zIGR5bmFtaWNhbGx5IHRoZW4geW91IGNhbiBjYXRjaCBpdAotICogaWYgeW91IHdpc2guIEJ1dCBzaG91bGQgbm90IGJlIGZvcmNlZCB0by4KLSAqCi0gKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzpqb25sQG11cHBldGxhYnMuY29tIj5Kb25hdGhhbiBMb2NrZTwvYT4KLSAqIEBhdXRob3IgPGEgaHJlZj0ibWFpbHRvOmdob2xhbUB4dHJhLmNvLm56Pk1pY2hhZWwgTWNDYWxsdW08L2E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBSRVN5bnRheEV4Y2VwdGlvbiBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24KLXsKLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3Rvci4KLSAgICAgKiBAcGFyYW0gcyBGdXJ0aGVyIGRlc2NyaXB0aW9uIG9mIHRoZSBzeW50YXggZXJyb3IKLSAgICAgKi8KLSAgICBwdWJsaWMgUkVTeW50YXhFeGNlcHRpb24oU3RyaW5nIHMpCi0gICAgewotICAgICAgICBzdXBlcigiU3ludGF4IGVycm9yOiAiICsgcyk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9yZWdleHAvaW50ZXJuYWwvUkVUZXN0LmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3JlZ2V4cC9pbnRlcm5hbC9SRVRlc3QuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNDYzNzc2ZC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3JlZ2V4cC9pbnRlcm5hbC9SRVRlc3QuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDg4MyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnJlZ2V4cC5pbnRlcm5hbDsKLQotaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRSZWFkZXI7Ci1pbXBvcnQgamF2YS5pby5GaWxlUmVhZGVyOwotaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW1SZWFkZXI7Ci1pbXBvcnQgamF2YS5pby5QcmludFdyaXRlcjsKLWltcG9ydCBqYXZhLmlvLkZpbGU7Ci1pbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5pby5PYmplY3RPdXRwdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKLWltcG9ydCBqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uU3RyaW5nQnVmZmVySW5wdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5pby5TdHJpbmdSZWFkZXI7Ci1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLQotLyoqCi0gKiBEYXRhIGRyaXZlbiAoYW5kIG9wdGlvbmFsbHkgaW50ZXJhY3RpdmUpIHRlc3RpbmcgaGFybmVzcyB0byBleGVyY2lzZSByZWd1bGFyCi0gKiBleHByZXNzaW9uIGNvbXBpbGVyIGFuZCBtYXRjaGluZyBlbmdpbmUuCi0gKgotICogQGF1dGhvciA8YSBocmVmPSJtYWlsdG86am9ubEBtdXBwZXRsYWJzLmNvbSI+Sm9uYXRoYW4gTG9ja2U8L2E+Ci0gKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzpqb25AbGF0Y2hrZXkuY29tIj5Kb24gUy4gU3RldmVuczwvYT4KLSAqIEBhdXRob3IgPGEgaHJlZj0ibWFpbHRvOmdob2xhbUB4dHJhLmNvLm56Ij5NaWNoYWVsIE1jQ2FsbHVtPC9hPgotICovCi1wdWJsaWMgY2xhc3MgUkVUZXN0Ci17Ci0gICAgLy8gVHJ1ZSBpZiB3ZSB3YW50IHRvIHNlZSBvdXRwdXQgZnJvbSBzdWNjZXNzIGNhc2VzCi0gICAgc3RhdGljIGZpbmFsIGJvb2xlYW4gc2hvd1N1Y2Nlc3NlcyA9IGZhbHNlOwotCi0gICAgLy8gQSBuZXcgbGluZSBjaGFyYWN0ZXIuCi0gICAgc3RhdGljIGZpbmFsIFN0cmluZyBORVdfTElORSA9IFN5c3RlbS5nZXRQcm9wZXJ0eSggImxpbmUuc2VwYXJhdG9yIiApOwotCi0gICAgLy8gQ29uc3RydWN0IGEgZGVidWcgY29tcGlsZXIKLSAgICBSRURlYnVnQ29tcGlsZXIgY29tcGlsZXIgPSBuZXcgUkVEZWJ1Z0NvbXBpbGVyKCk7Ci0KLSAgICAvKioKLSAgICAgKiBNYWluIHByb2dyYW0gZW50cnlwb2ludC4gIElmIGFuIGFyZ3VtZW50IGlzIGdpdmVuLCBpdCB3aWxsIGJlIGNvbXBpbGVkCi0gICAgICogYW5kIGludGVyYWN0aXZlIG1hdGNoaW5nIHdpbGwgZW5zdWUuICBJZiBubyBhcmd1bWVudCBpcyBnaXZlbiwgdGhlCi0gICAgICogZmlsZSBSRVRlc3QudHh0IHdpbGwgYmUgdXNlZCBhcyBhdXRvbWF0ZWQgdGVzdGluZyBpbnB1dC4KLSAgICAgKiBAcGFyYW0gYXJncyBDb21tYW5kIGxpbmUgYXJndW1lbnRzIChvcHRpb25hbCByZWd1bGFyIGV4cHJlc3Npb24pCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nW10gYXJncykKLSAgICB7Ci0gICAgICAgIHRyeQotICAgICAgICB7Ci0gICAgICAgICAgICBpZiAoIXRlc3QoIGFyZ3MgKSkgewotICAgICAgICAgICAgICAgIFN5c3RlbS5leGl0KDEpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChFeGNlcHRpb24gZSkKLSAgICAgICAgewotICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgICAgICAgIFN5c3RlbS5leGl0KDEpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGVzdGluZyBlbnRyeXBvaW50LgotICAgICAqIEBwYXJhbSBhcmdzIENvbW1hbmQgbGluZSBhcmd1bWVudHMKLSAgICAgKiBAZXhjZXB0aW9uIEV4Y2VwdGlvbiB0aHJvd24gaW4gY2FzZSBvZiBlcnJvcgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiB0ZXN0KCBTdHJpbmdbXSBhcmdzICkgdGhyb3dzIEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgUkVUZXN0IHRlc3QgPSBuZXcgUkVUZXN0KCk7Ci0gICAgICAgIC8vIFJ1biBpbnRlcmFjdGl2ZSB0ZXN0cyBhZ2FpbnN0IGEgc2luZ2xlIHJlZ2V4cAotICAgICAgICBpZiAoYXJncy5sZW5ndGggPT0gMikKLSAgICAgICAgewotICAgICAgICAgICAgdGVzdC5ydW5JbnRlcmFjdGl2ZVRlc3RzKGFyZ3NbMV0pOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKGFyZ3MubGVuZ3RoID09IDEpCi0gICAgICAgIHsKLSAgICAgICAgICAgIC8vIFJ1biBhdXRvbWF0ZWQgdGVzdHMKLSAgICAgICAgICAgIHRlc3QucnVuQXV0b21hdGVkVGVzdHMoYXJnc1swXSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICB7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oICJVc2FnZTogUkVUZXN0IChbLWldIFtyZWdleF0pIChbL3BhdGgvdG8vdGVzdGZpbGUudHh0XSkiICk7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oICJCeSBEZWZhdWx0IHdpbGwgcnVuIGF1dG9tYXRlZCB0ZXN0cyBmcm9tIGZpbGUgJ2RvY3MvUkVUZXN0LnR4dCcgLi4uIiApOwotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCk7Ci0gICAgICAgICAgICB0ZXN0LnJ1bkF1dG9tYXRlZFRlc3RzKCJkb2NzL1JFVGVzdC50eHQiKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gdGVzdC5mYWlsdXJlcyA9PSAwOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdG9yCi0gICAgICovCi0gICAgcHVibGljIFJFVGVzdCgpCi0gICAgewotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbXBpbGUgYW5kIHRlc3QgbWF0Y2hpbmcgYWdhaW5zdCBhIHNpbmdsZSBleHByZXNzaW9uCi0gICAgICogQHBhcmFtIGV4cHIgRXhwcmVzc2lvbiB0byBjb21waWxlIGFuZCB0ZXN0Ci0gICAgICovCi0gICAgdm9pZCBydW5JbnRlcmFjdGl2ZVRlc3RzKFN0cmluZyBleHByKQotICAgIHsKLSAgICAgICAgUkUgciA9IG5ldyBSRSgpOwotICAgICAgICB0cnkKLSAgICAgICAgewotICAgICAgICAgICAgLy8gQ29tcGlsZSBleHByZXNzaW9uCi0gICAgICAgICAgICByLnNldFByb2dyYW0oY29tcGlsZXIuY29tcGlsZShleHByKSk7Ci0KLSAgICAgICAgICAgIC8vIFNob3cgZXhwcmVzc2lvbgotICAgICAgICAgICAgc2F5KCIiICsgTkVXX0xJTkUgKyAiIiArIGV4cHIgKyAiIiArIE5FV19MSU5FICsgIiIpOwotCi0gICAgICAgICAgICAvLyBTaG93IHByb2dyYW0gZm9yIGNvbXBpbGVkIGV4cHJlc3Npb24KLSAgICAgICAgICAgIFByaW50V3JpdGVyIHdyaXRlciA9IG5ldyBQcmludFdyaXRlciggU3lzdGVtLm91dCApOwotICAgICAgICAgICAgY29tcGlsZXIuZHVtcFByb2dyYW0oIHdyaXRlciApOwotICAgICAgICAgICAgd3JpdGVyLmZsdXNoKCk7Ci0KLSAgICAgICAgICAgIGJvb2xlYW4gcnVubmluZyA9IHRydWU7Ci0gICAgICAgICAgICAvLyBUZXN0IG1hdGNoaW5nIGFnYWluc3QgY29tcGlsZWQgZXhwcmVzc2lvbgotICAgICAgICAgICAgd2hpbGUgKCBydW5uaW5nICkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAvLyBSZWFkIGZyb20ga2V5Ym9hcmQKLSAgICAgICAgICAgICAgICBCdWZmZXJlZFJlYWRlciBiciA9IG5ldyBCdWZmZXJlZFJlYWRlcihuZXcgSW5wdXRTdHJlYW1SZWFkZXIoU3lzdGVtLmluKSk7Ci0gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiPiAiKTsKLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LmZsdXNoKCk7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIG1hdGNoID0gYnIucmVhZExpbmUoKTsKLQotICAgICAgICAgICAgICAgIGlmICggbWF0Y2ggIT0gbnVsbCApCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAvLyBUcnkgYSBtYXRjaCBhZ2FpbnN0IHRoZSBrZXlib2FyZCBpbnB1dAotICAgICAgICAgICAgICAgICAgICBpZiAoci5tYXRjaChtYXRjaCkpCi0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHNheSgiTWF0Y2ggc3VjY2Vzc2Z1bC4iKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHNheSgiTWF0Y2ggZmFpbGVkLiIpOwotICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgLy8gU2hvdyBzdWJwYXJlbiByZWdpc3RlcnMKLSAgICAgICAgICAgICAgICAgICAgc2hvd1BhcmVucyhyKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgcnVubmluZyA9IGZhbHNlOwotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKQotICAgICAgICB7Ci0gICAgICAgICAgICBzYXkoIkVycm9yOiAiICsgZS50b1N0cmluZygpKTsKLSAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBFeGl0IHdpdGggYSBmYXRhbCBlcnJvci4KLSAgICAgKiBAcGFyYW0gcyBMYXN0IGZhbW91cyB3b3JkcyBiZWZvcmUgZXhpdGluZwotICAgICAqLwotICAgIHZvaWQgZGllKFN0cmluZyBzKQotICAgIHsKLSAgICAgICAgc2F5KCJGQVRBTCBFUlJPUjogIiArIHMpOwotICAgICAgICBTeXN0ZW0uZXhpdCgtMSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRmFpbCB3aXRoIGFuIGVycm9yLiBXaWxsIHByaW50IGEgYmlnIGZhaWx1cmUgbWVzc2FnZSB0byBTeXN0ZW0ub3V0LgotICAgICAqCi0gICAgICogQHBhcmFtIGxvZyBPdXRwdXQgYmVmb3JlIGZhaWx1cmUKLSAgICAgKiBAcGFyYW0gcyBGYWlsdXJlIGRlc2NyaXB0aW9uCi0gICAgICovCi0gICAgdm9pZCBmYWlsKFN0cmluZ0J1ZmZlciBsb2csIFN0cmluZyBzKQotICAgIHsKLSAgICAgICAgU3lzdGVtLm91dC5wcmludChsb2cudG9TdHJpbmcoKSk7Ci0gICAgICAgIGZhaWwocyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRmFpbCB3aXRoIGFuIGVycm9yLiBXaWxsIHByaW50IGEgYmlnIGZhaWx1cmUgbWVzc2FnZSB0byBTeXN0ZW0ub3V0LgotICAgICAqCi0gICAgICogQHBhcmFtIHMgRmFpbHVyZSBkZXNjcmlwdGlvbgotICAgICAqLwotICAgIHZvaWQgZmFpbChTdHJpbmcgcykKLSAgICB7Ci0gICAgICAgIGZhaWx1cmVzKys7Ci0gICAgICAgIHNheSgiIiArIE5FV19MSU5FICsgIiIpOwotICAgICAgICBzYXkoIioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioiKTsKLSAgICAgICAgc2F5KCIqKioqKioqKioqKioqKioqKioqKiogIEZBSUxVUkUhICAqKioqKioqKioqKioqKioqKioqKioqIik7Ci0gICAgICAgIHNheSgiKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiIpOwotICAgICAgICBzYXkoIiIgKyBORVdfTElORSArICIiKTsKLSAgICAgICAgc2F5KHMpOwotICAgICAgICBzYXkoIiIpOwotICAgICAgICAvLyBtYWtlIHN1cmUgdGhlIHdyaXRlciBnZXRzIGZsdXNoZWQuCi0gICAgICAgIGlmIChjb21waWxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBQcmludFdyaXRlciB3cml0ZXIgPSBuZXcgUHJpbnRXcml0ZXIoIFN5c3RlbS5vdXQgKTsKLSAgICAgICAgICAgIGNvbXBpbGVyLmR1bXBQcm9ncmFtKCB3cml0ZXIgKTsKLSAgICAgICAgICAgIHdyaXRlci5mbHVzaCgpOwotICAgICAgICAgICAgc2F5KCIiICsgTkVXX0xJTkUgKyAiIik7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTYXkgc29tZXRoaW5nIHRvIHN0YW5kYXJkIG91dAotICAgICAqIEBwYXJhbSBzIFdoYXQgdG8gc2F5Ci0gICAgICovCi0gICAgdm9pZCBzYXkoU3RyaW5nIHMpCi0gICAgewotICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4ocyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRHVtcCBwYXJlbnRoZXNpemVkIHN1YmV4cHJlc3Npb25zIGZvdW5kIGJ5IGEgcmVndWxhciBleHByZXNzaW9uIG1hdGNoZXIgb2JqZWN0Ci0gICAgICogQHBhcmFtIHIgTWF0Y2hlciBvYmplY3Qgd2l0aCByZXN1bHRzIHRvIHNob3cKLSAgICAgKi8KLSAgICB2b2lkIHNob3dQYXJlbnMoUkUgcikKLSAgICB7Ci0gICAgICAgIC8vIExvb3AgdGhyb3VnaCBlYWNoIHBhcmVuCi0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgci5nZXRQYXJlbkNvdW50KCk7IGkrKykKLSAgICAgICAgewotICAgICAgICAgICAgLy8gU2hvdyBwYXJlbiByZWdpc3RlcgotICAgICAgICAgICAgc2F5KCIkIiArIGkgKyAiID0gIiArIHIuZ2V0UGFyZW4oaSkpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoKLSAgICAgKiBudW1iZXIgaW4gYXV0b21hdGVkIHRlc3QKLSAgICAgKi8KLSAgICBpbnQgdGVzdENvdW50ID0gMDsKLQotICAgIC8qCi0gICAgICogQ291bnQgb2YgZmFpbHVyZXMgaW4gYXV0b21hdGVkIHRlc3QKLSAgICAgKi8KLSAgICBpbnQgZmFpbHVyZXMgPSAwOwotCi0gICAgLyoqCi0gICAgICogUnVuIGF1dG9tYXRlZCB0ZXN0cyBpbiBSRVRlc3QudHh0IGZpbGUgKGZyb20gUGVybCA0LjAgdGVzdCBiYXR0ZXJ5KQotICAgICAqIEBleGNlcHRpb24gRXhjZXB0aW9uIHRocm93biBpbiBjYXNlIG9mIGVycm9yCi0gICAgICovCi0gICAgdm9pZCBydW5BdXRvbWF0ZWRUZXN0cyhTdHJpbmcgdGVzdERvY3VtZW50KSB0aHJvd3MgRXhjZXB0aW9uCi0gICAgewotICAgICAgICBsb25nIG1zID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7Ci0KLSAgICAgICAgLy8gU29tZSB1bml0IHRlc3RzCi0gICAgICAgIHRlc3RQcmVjb21waWxlZFJFKCk7Ci0gICAgICAgIHRlc3RTcGxpdEFuZEdyZXAoKTsKLSAgICAgICAgdGVzdFN1YnN0KCk7Ci0gICAgICAgIHRlc3RPdGhlcigpOwotCi0gICAgICAgIC8vIFRlc3QgZnJvbSBzY3JpcHQgZmlsZQotICAgICAgICBGaWxlIHRlc3RJbnB1dCA9IG5ldyBGaWxlKHRlc3REb2N1bWVudCk7Ci0gICAgICAgIGlmICghIHRlc3RJbnB1dC5leGlzdHMoKSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbiAoIkNvdWxkIG5vdCBmaW5kOiAiICsgdGVzdERvY3VtZW50KTsKLSAgICAgICAgfQotCi0gICAgICAgIEJ1ZmZlcmVkUmVhZGVyIGJyID0gbmV3IEJ1ZmZlcmVkUmVhZGVyKG5ldyBGaWxlUmVhZGVyKHRlc3RJbnB1dCkpOwotICAgICAgICB0cnkKLSAgICAgICAgewotICAgICAgICAgICAgLy8gV2hpbGUgaW5wdXQgaXMgYXZhaWxhYmxlLCBwYXJzZSBsaW5lcwotICAgICAgICAgICAgd2hpbGUgKGJyLnJlYWR5KCkpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgUkVUZXN0Q2FzZSB0ZXN0Y2FzZSA9IGdldE5leHRUZXN0Q2FzZShicik7Ci0gICAgICAgICAgICAgICAgaWYgKHRlc3RjYXNlICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgdGVzdGNhc2UucnVuVGVzdCgpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBmaW5hbGx5Ci0gICAgICAgIHsKLSAgICAgICAgICAgIGJyLmNsb3NlKCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBTaG93IG1hdGNoIHRpbWUKLSAgICAgICAgc2F5KE5FV19MSU5FICsgTkVXX0xJTkUgKyAiTWF0Y2ggdGltZSA9ICIgKyAoU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkgLSBtcykgKyAiIG1zLiIpOwotCi0gICAgICAgIC8vIFByaW50IGZpbmFsIHJlc3VsdHMKLSAgICAgICAgaWYgKGZhaWx1cmVzID4gMCkgewotICAgICAgICAgICAgc2F5KCIqKioqKioqKioqKioqKiogVEhFUkUgQVJFIEZBSUxVUkVTISAqKioqKioqKioqKioqKioqKioqIik7Ci0gICAgICAgIH0KLSAgICAgICAgc2F5KCJUZXN0cyBjb21wbGV0ZS4gICIgKyB0ZXN0Q291bnQgKyAiIHRlc3RzLCAiICsgZmFpbHVyZXMgKyAiIGZhaWx1cmUocykuIik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUnVuIGF1dG9tYXRlZCB1bml0IHRlc3QKLSAgICAgKiBAZXhjZXB0aW9uIEV4Y2VwdGlvbiB0aHJvd24gaW4gY2FzZSBvZiBlcnJvcgotICAgICAqLwotICAgIHZvaWQgdGVzdE90aGVyKCkgdGhyb3dzIEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgLy8gU2VyaWFsaXphdGlvbiB0ZXN0IDE6IENvbXBpbGUgcmVnZXhwIGFuZCBzZXJpYWxpemUvZGVzZXJpYWxpemUgaXQKLSAgICAgICAgUkUgciA9IG5ldyBSRSgiKGEqKWIiKTsKLSAgICAgICAgc2F5KCJTZXJpYWxpemVkL2Rlc2VyaWFsaXplZCAoYSopYiIpOwotICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gb3V0ID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgxMjgpOwotICAgICAgICBuZXcgT2JqZWN0T3V0cHV0U3RyZWFtKG91dCkud3JpdGVPYmplY3Qocik7Ci0gICAgICAgIEJ5dGVBcnJheUlucHV0U3RyZWFtIGluID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKG91dC50b0J5dGVBcnJheSgpKTsKLSAgICAgICAgciA9IChSRSluZXcgT2JqZWN0SW5wdXRTdHJlYW0oaW4pLnJlYWRPYmplY3QoKTsKLSAgICAgICAgaWYgKCFyLm1hdGNoKCJhYWFiIikpCi0gICAgICAgIHsKLSAgICAgICAgICAgIGZhaWwoIkRpZCBub3QgbWF0Y2ggJ2FhYWInIHdpdGggZGVzZXJpYWxpemVkIFJFLiIpOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgc2F5KCJhYWFhYiA9IHRydWUiKTsKLSAgICAgICAgICAgIHNob3dQYXJlbnMocik7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBTZXJpYWxpemF0aW9uIHRlc3QgMjogc2VyaWFsaXplL2Rlc2VyaWFsaXplIHVzZWQgcmVnZXhwCi0gICAgICAgIG91dC5yZXNldCgpOwotICAgICAgICBzYXkoIkRlc2VyaWFsaXplZCAoYSopYiIpOwotICAgICAgICBuZXcgT2JqZWN0T3V0cHV0U3RyZWFtKG91dCkud3JpdGVPYmplY3Qocik7Ci0gICAgICAgIGluID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKG91dC50b0J5dGVBcnJheSgpKTsKLSAgICAgICAgciA9IChSRSluZXcgT2JqZWN0SW5wdXRTdHJlYW0oaW4pLnJlYWRPYmplY3QoKTsKLSAgICAgICAgaWYgKHIuZ2V0UGFyZW5Db3VudCgpICE9IDApCi0gICAgICAgIHsKLSAgICAgICAgICAgIGZhaWwoIkhhcyBwYXJlbnMgYWZ0ZXIgZGVzZXJpYWxpemF0aW9uLiIpOwotICAgICAgICB9Ci0gICAgICAgIGlmICghci5tYXRjaCgiYWFhYiIpKQotICAgICAgICB7Ci0gICAgICAgICAgICBmYWlsKCJEaWQgbm90IG1hdGNoICdhYWFiJyB3aXRoIGRlc2VyaWFsaXplZCBSRS4iKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIHNheSgiYWFhYWIgPSB0cnVlIik7Ci0gICAgICAgICAgICBzaG93UGFyZW5zKHIpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gVGVzdCBNQVRDSF9DQVNFSU5ERVBFTkRFTlQKLSAgICAgICAgciA9IG5ldyBSRSgiYWJjKFxcdyopIik7Ci0gICAgICAgIHNheSgiTUFUQ0hfQ0FTRUlOREVQRU5ERU5UIGFiYyhcXHcqKSIpOwotICAgICAgICByLnNldE1hdGNoRmxhZ3MoUkUuTUFUQ0hfQ0FTRUlOREVQRU5ERU5UKTsKLSAgICAgICAgc2F5KCJhYmMoZCopIik7Ci0gICAgICAgIGlmICghci5tYXRjaCgiYWJjZGRkIikpCi0gICAgICAgIHsKLSAgICAgICAgICAgIGZhaWwoIkRpZCBub3QgbWF0Y2ggJ2FiY2RkZCcuIik7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBzYXkoImFiY2RkZCA9IHRydWUiKTsKLSAgICAgICAgICAgIHNob3dQYXJlbnMocik7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoIXIubWF0Y2goImFCY0REZGQiKSkKLSAgICAgICAgewotICAgICAgICAgICAgZmFpbCgiRGlkIG5vdCBtYXRjaCAnYUJjRERkZCcuIik7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBzYXkoImFCY0REZGQgPSB0cnVlIik7Ci0gICAgICAgICAgICBzaG93UGFyZW5zKHIpOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKCFyLm1hdGNoKCJBQkNERERERCIpKQotICAgICAgICB7Ci0gICAgICAgICAgICBmYWlsKCJEaWQgbm90IG1hdGNoICdBQkNERERERCcuIik7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBzYXkoIkFCQ0REREREID0gdHJ1ZSIpOwotICAgICAgICAgICAgc2hvd1BhcmVucyhyKTsKLSAgICAgICAgfQotCi0gICAgICAgIHIgPSBuZXcgUkUoIihBKiliXFwxIik7Ci0gICAgICAgIHIuc2V0TWF0Y2hGbGFncyhSRS5NQVRDSF9DQVNFSU5ERVBFTkRFTlQpOwotICAgICAgICBpZiAoIXIubWF0Y2goIkFhQWFhYUJBQUFBQUEiKSkKLSAgICAgICAgewotICAgICAgICAgICAgZmFpbCgiRGlkIG5vdCBtYXRjaCAnQWFBYWFhQkFBQUFBQScuIik7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBzYXkoIkFhQWFhYUJBQUFBQUEgPSB0cnVlIik7Ci0gICAgICAgICAgICBzaG93UGFyZW5zKHIpOwotICAgICAgICB9Ci0KLSAgICAgICAgciA9IG5ldyBSRSgiW0EtWl0qIik7Ci0gICAgICAgIHIuc2V0TWF0Y2hGbGFncyhSRS5NQVRDSF9DQVNFSU5ERVBFTkRFTlQpOwotICAgICAgICBpZiAoIXIubWF0Y2goIkNhQmdEZTEyIikpCi0gICAgICAgIHsKLSAgICAgICAgICAgIGZhaWwoIkRpZCBub3QgbWF0Y2ggJ0NhQmdEZTEyJy4iKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIHNheSgiQ2FCZ0RlMTIgPSB0cnVlIik7Ci0gICAgICAgICAgICBzaG93UGFyZW5zKHIpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gVGVzdCBNQVRDSF9NVUxUSUxJTkUuIFRlc3QgZm9yIGVvbC9ib2wgc3ltYm9scy4KLSAgICAgICAgciA9IG5ldyBSRSgiXmFiYyQiLCBSRS5NQVRDSF9NVUxUSUxJTkUpOwotICAgICAgICBpZiAoIXIubWF0Y2goIlxuYWJjIikpIHsKLSAgICAgICAgICAgIGZhaWwoIlwiXFxuYWJjXCIgZG9lc24ndCBtYXRjaCBcIl5hYmMkXCIiKTsKLSAgICAgICAgfQotICAgICAgICBpZiAoIXIubWF0Y2goIlxyYWJjIikpIHsKLSAgICAgICAgICAgIGZhaWwoIlwiXFxyYWJjXCIgZG9lc24ndCBtYXRjaCBcIl5hYmMkXCIiKTsKLSAgICAgICAgfQotICAgICAgICBpZiAoIXIubWF0Y2goIlxyXG5hYmMiKSkgewotICAgICAgICAgICAgZmFpbCgiXCJcXHJcXG5hYmNcIiBkb2Vzbid0IG1hdGNoIFwiXmFiYyRcIiIpOwotICAgICAgICB9Ci0gICAgICAgIGlmICghci5tYXRjaCgiXHUwMDg1YWJjIikpIHsKLSAgICAgICAgICAgIGZhaWwoIlwiXFx1MDA4NWFiY1wiIGRvZXNuJ3QgbWF0Y2ggXCJeYWJjJFwiIik7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKCFyLm1hdGNoKCJcdTIwMjhhYmMiKSkgewotICAgICAgICAgICAgZmFpbCgiXCJcXHUyMDI4YWJjXCIgZG9lc24ndCBtYXRjaCBcIl5hYmMkXCIiKTsKLSAgICAgICAgfQotICAgICAgICBpZiAoIXIubWF0Y2goIlx1MjAyOWFiYyIpKSB7Ci0gICAgICAgICAgICBmYWlsKCJcIlxcdTIwMjlhYmNcIiBkb2Vzbid0IG1hdGNoIFwiXmFiYyRcIiIpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gVGVzdCBNQVRDSF9NVUxUSUxJTkUuIFRlc3QgdGhhdCAnLicgZG9lcyBub3QgbWF0Y2hlcyBuZXcgbGluZS4KLSAgICAgICAgciA9IG5ldyBSRSgiXmEuKmIkIiwgUkUuTUFUQ0hfTVVMVElMSU5FKTsKLSAgICAgICAgaWYgKHIubWF0Y2goImFcbmIiKSkgewotICAgICAgICAgICAgZmFpbCgiXCJhXFxuYlwiIG1hdGNoZXMgXCJeYS4qYiRcIiIpOwotICAgICAgICB9Ci0gICAgICAgIGlmIChyLm1hdGNoKCJhXHJiIikpIHsKLSAgICAgICAgICAgIGZhaWwoIlwiYVxccmJcIiBtYXRjaGVzIFwiXmEuKmIkXCIiKTsKLSAgICAgICAgfQotICAgICAgICBpZiAoci5tYXRjaCgiYVxyXG5iIikpIHsKLSAgICAgICAgICAgIGZhaWwoIlwiYVxcclxcbmJcIiBtYXRjaGVzIFwiXmEuKmIkXCIiKTsKLSAgICAgICAgfQotICAgICAgICBpZiAoci5tYXRjaCgiYVx1MDA4NWIiKSkgewotICAgICAgICAgICAgZmFpbCgiXCJhXFx1MDA4NWJcIiBtYXRjaGVzIFwiXmEuKmIkXCIiKTsKLSAgICAgICAgfQotICAgICAgICBpZiAoci5tYXRjaCgiYVx1MjAyOGIiKSkgewotICAgICAgICAgICAgZmFpbCgiXCJhXFx1MjAyOGJcIiBtYXRjaGVzIFwiXmEuKmIkXCIiKTsKLSAgICAgICAgfQotICAgICAgICBpZiAoci5tYXRjaCgiYVx1MjAyOWIiKSkgewotICAgICAgICAgICAgZmFpbCgiXCJhXFx1MjAyOWJcIiBtYXRjaGVzIFwiXmEuKmIkXCIiKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCB0ZXN0UHJlY29tcGlsZWRSRSgpCi0gICAgewotICAgICAgICAvLyBQcmUtY29tcGlsZWQgcmVndWxhciBleHByZXNzaW9uICJhKmIiCi0gICAgICAgIGNoYXJbXSByZTFJbnN0cnVjdGlvbnMgPQotICAgICAgICB7Ci0gICAgICAgICAgICAweDAwN2MsIDB4MDAwMCwgMHgwMDFhLCAweDAwN2MsIDB4MDAwMCwgMHgwMDBkLCAweDAwNDEsCi0gICAgICAgICAgICAweDAwMDEsIDB4MDAwNCwgMHgwMDYxLCAweDAwN2MsIDB4MDAwMCwgMHgwMDAzLCAweDAwNDcsCi0gICAgICAgICAgICAweDAwMDAsIDB4ZmZmNiwgMHgwMDdjLCAweDAwMDAsIDB4MDAwMywgMHgwMDRlLCAweDAwMDAsCi0gICAgICAgICAgICAweDAwMDMsIDB4MDA0MSwgMHgwMDAxLCAweDAwMDQsIDB4MDA2MiwgMHgwMDQ1LCAweDAwMDAsCi0gICAgICAgICAgICAweDAwMDAsCi0gICAgICAgIH07Ci0KLSAgICAgICAgUkVQcm9ncmFtIHJlMSA9IG5ldyBSRVByb2dyYW0ocmUxSW5zdHJ1Y3Rpb25zKTsKLQotICAgICAgICAvLyBTaW1wbGUgdGVzdCBvZiBwcmUtY29tcGlsZWQgcmVndWxhciBleHByZXNzaW9ucwotICAgICAgICBSRSByID0gbmV3IFJFKHJlMSk7Ci0gICAgICAgIHNheSgiYSpiIik7Ci0gICAgICAgIGJvb2xlYW4gcmVzdWx0ID0gci5tYXRjaCgiYWFhYiIpOwotICAgICAgICBzYXkoImFhYWIgPSAiICsgcmVzdWx0KTsKLSAgICAgICAgc2hvd1BhcmVucyhyKTsKLSAgICAgICAgaWYgKCFyZXN1bHQpIHsKLSAgICAgICAgICAgIGZhaWwoIlwiYWFhYlwiIGRvZXNuJ3QgbWF0Y2ggdG8gcHJlY29tcGlsZWQgXCJhKmJcIiIpOwotICAgICAgICB9Ci0KLSAgICAgICAgcmVzdWx0ID0gci5tYXRjaCgiYiIpOwotICAgICAgICBzYXkoImIgPSAiICsgcmVzdWx0KTsKLSAgICAgICAgc2hvd1BhcmVucyhyKTsKLSAgICAgICAgaWYgKCFyZXN1bHQpIHsKLSAgICAgICAgICAgIGZhaWwoIlwiYlwiIGRvZXNuJ3QgbWF0Y2ggdG8gcHJlY29tcGlsZWQgXCJhKmJcIiIpOwotICAgICAgICB9Ci0KLSAgICAgICAgcmVzdWx0ID0gci5tYXRjaCgiYyIpOwotICAgICAgICBzYXkoImMgPSAiICsgcmVzdWx0KTsKLSAgICAgICAgc2hvd1BhcmVucyhyKTsKLSAgICAgICAgaWYgKHJlc3VsdCkgewotICAgICAgICAgICAgZmFpbCgiXCJjXCIgbWF0Y2hlcyB0byBwcmVjb21waWxlZCBcImEqYlwiIik7Ci0gICAgICAgIH0KLQotICAgICAgICByZXN1bHQgPSByLm1hdGNoKCJjY2NjYWFhYWFiIik7Ci0gICAgICAgIHNheSgiY2NjY2FhYWFhYiA9ICIgKyByZXN1bHQpOwotICAgICAgICBzaG93UGFyZW5zKHIpOwotICAgICAgICBpZiAoIXJlc3VsdCkgewotICAgICAgICAgICAgZmFpbCgiXCJjY2NjYWFhYWFiXCIgZG9lc24ndCBtYXRjaCB0byBwcmVjb21waWxlZCBcImEqYlwiIik7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgdGVzdFNwbGl0QW5kR3JlcCgpCi0gICAgewotICAgICAgICBTdHJpbmdbXSBleHBlY3RlZCA9IHsieHh4eCIsICJ4eHh4IiwgInl5eXkiLCAienp6In07Ci0gICAgICAgIFJFIHIgPSBuZXcgUkUoImEqYiIpOwotICAgICAgICBTdHJpbmdbXSBzID0gci5zcGxpdCgieHh4eGFhYnh4eHhieXl5eWFhYWJ6enoiKTsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBleHBlY3RlZC5sZW5ndGggJiYgaSA8IHMubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgIGFzc2VydEVxdWFscygiV3Jvbmcgc3BsaXR0ZWQgcGFydCIsIGV4cGVjdGVkW2ldLCBzW2ldKTsKLSAgICAgICAgfQotICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIG51bWJlciBvZiBzcGxpdHRlZCBwYXJ0cyIsIGV4cGVjdGVkLmxlbmd0aCwKLSAgICAgICAgICAgICAgICAgICAgIHMubGVuZ3RoKTsKLQotICAgICAgICByID0gbmV3IFJFKCJ4KyIpOwotICAgICAgICBleHBlY3RlZCA9IG5ldyBTdHJpbmdbXSB7Inh4eHgiLCAieHh4eCJ9OwotICAgICAgICBzID0gci5ncmVwKHMpOwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHMubGVuZ3RoOyBpKyspCi0gICAgICAgIHsKLSAgICAgICAgICAgIHNheSgic1siICsgaSArICJdID0gIiArIHNbaV0pOwotICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJHcmVwIGZhaWxzIiwgZXhwZWN0ZWRbaV0sIHNbaV0pOwotICAgICAgICB9Ci0gICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgbnVtYmVyIG9mIHN0cmluZyBmb3VuZCBieSBncmVwIiwgZXhwZWN0ZWQubGVuZ3RoLAotICAgICAgICAgICAgICAgICAgICAgcy5sZW5ndGgpOwotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCB0ZXN0U3Vic3QoKQotICAgIHsKLSAgICAgICAgUkUgciA9IG5ldyBSRSgiYSpiIik7Ci0gICAgICAgIFN0cmluZyBleHBlY3RlZCA9ICItZm9vLWdhcnBseS13YWNreS0iOwotICAgICAgICBTdHJpbmcgYWN0dWFsID0gci5zdWJzdCgiYWFhYWJmb29hYWFiZ2FycGx5YWFhYndhY2t5YiIsICItIik7Ci0gICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgcmVzdWx0IG9mIHN1YnN0aXR1dGlvbiBpbiBcImEqYlwiIiwgZXhwZWN0ZWQsIGFjdHVhbCk7Ci0KLSAgICAgICAgLy8gVGVzdCBzdWJzdCgpIHdpdGggYmFja3JlZmVyZW5jZXMKLSAgICAgICAgciA9IG5ldyBSRSgiaHR0cDovL1tcXC5cXHdcXC1cXD8vfl9AJj0lXSsiKTsKLSAgICAgICAgYWN0dWFsID0gci5zdWJzdCgidmlzaXQgdXM6IGh0dHA6Ly93d3cuYXBhY2hlLm9yZyEiLAotICAgICAgICAgICAgICAgICAgICAgICAgICIxMjM0PGEgaHJlZj1cIiQwXCI+JDA8L2E+IiwgUkUuUkVQTEFDRV9CQUNLUkVGRVJFTkNFUyk7Ci0gICAgICAgIGFzc2VydEVxdWFscygiV3Jvbmcgc3Vic3QoKSByZXN1bHQiLCAidmlzaXQgdXM6IDEyMzQ8YSBocmVmPVwiaHR0cDovL3d3dy5hcGFjaGUub3JnXCI+aHR0cDovL3d3dy5hcGFjaGUub3JnPC9hPiEiLCBhY3R1YWwpOwotCi0gICAgICAgIC8vIFRlc3Qgc3Vic3QoKSB3aXRoIGJhY2tyZWZlcmVuY2VzIHdpdGhvdXQgbGVhZGluZyBjaGFyYWN0ZXJzCi0gICAgICAgIC8vIGJlZm9yZSBmaXJzdCBiYWNrcmVmZXJlbmNlCi0gICAgICAgIHIgPSBuZXcgUkUoIiguKj8pPSguKikiKTsKLSAgICAgICAgYWN0dWFsID0gci5zdWJzdCgidmFyaWFibGU9dmFsdWUiLAotICAgICAgICAgICAgICAgICAgICAgICAgICIkMV90ZXN0XyQyMTIiLCBSRS5SRVBMQUNFX0JBQ0tSRUZFUkVOQ0VTKTsKLSAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyBzdWJzdCgpIHJlc3VsdCIsICJ2YXJpYWJsZV90ZXN0X3ZhbHVlMTIiLCBhY3R1YWwpOwotCi0gICAgICAgIC8vIFRlc3Qgc3Vic3QoKSB3aXRoIE5PIGJhY2tyZWZlcmVuY2VzCi0gICAgICAgIHIgPSBuZXcgUkUoIl5hJCIpOwotICAgICAgICBhY3R1YWwgPSByLnN1YnN0KCJhIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAiYiIsIFJFLlJFUExBQ0VfQkFDS1JFRkVSRU5DRVMpOwotICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHN1YnN0KCkgcmVzdWx0IiwgImIiLCBhY3R1YWwpOwotCi0gICAgICAgIC8vIFRlc3Qgc3Vic3QoKSB3aXRoIE5PIGJhY2tyZWZlcmVuY2VzCi0gICAgICAgIHIgPSBuZXcgUkUoIl5hJCIsIFJFLk1BVENIX01VTFRJTElORSk7Ci0gICAgICAgIGFjdHVhbCA9IHIuc3Vic3QoIlxyXG5hXHJcbiIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgImIiLCBSRS5SRVBMQUNFX0JBQ0tSRUZFUkVOQ0VTKTsKLSAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyBzdWJzdCgpIHJlc3VsdCIsICJcclxuYlxyXG4iLCBhY3R1YWwpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGFzc2VydEVxdWFscyhTdHJpbmcgbWVzc2FnZSwgU3RyaW5nIGV4cGVjdGVkLCBTdHJpbmcgYWN0dWFsKQotICAgIHsKLSAgICAgICAgaWYgKGV4cGVjdGVkICE9IG51bGwgJiYgIWV4cGVjdGVkLmVxdWFscyhhY3R1YWwpCi0gICAgICAgICAgICB8fCBhY3R1YWwgIT0gbnVsbCAmJiAhYWN0dWFsLmVxdWFscyhleHBlY3RlZCkpCi0gICAgICAgIHsKLSAgICAgICAgICAgIGZhaWwobWVzc2FnZSArICIgKGV4cGVjdGVkIFwiIiArIGV4cGVjdGVkCi0gICAgICAgICAgICAgICAgICsgIlwiLCBhY3R1YWwgXCIiICsgYWN0dWFsICsgIlwiKSIpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgYXNzZXJ0RXF1YWxzKFN0cmluZyBtZXNzYWdlLCBpbnQgZXhwZWN0ZWQsIGludCBhY3R1YWwpCi0gICAgewotICAgICAgICBpZiAoZXhwZWN0ZWQgIT0gYWN0dWFsKSB7Ci0gICAgICAgICAgICBmYWlsKG1lc3NhZ2UgKyAiIChleHBlY3RlZCBcIiIgKyBleHBlY3RlZAotICAgICAgICAgICAgICAgICArICJcIiwgYWN0dWFsIFwiIiArIGFjdHVhbCArICJcIikiKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbnZlcnRzIHllc25vIHN0cmluZyB0byBib29sZWFuLgotICAgICAqIEBwYXJhbSB5ZXNubyBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgZXhwZWN0ZWQgcmVzdWx0Ci0gICAgICogQHJldHVybiB0cnVlIGlmIHllc25vIGlzICJZRVMiLCBmYWxzZSBpZiB5ZXNubyBpcyAiTk8iCi0gICAgICogICAgICAgICBzdG9wcyBwcm9ncmFtIG90aGVyd2lzZS4KLSAgICAgKi8KLSAgICBwcml2YXRlIGJvb2xlYW4gZ2V0RXhwZWN0ZWRSZXN1bHQoU3RyaW5nIHllc25vKQotICAgIHsKLSAgICAgICAgaWYgKCJOTyIuZXF1YWxzKHllc25vKSkKLSAgICAgICAgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKCJZRVMiLmVxdWFscyh5ZXNubykpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotICAgICAgICAgICAgLy8gQmFkIHRlc3Qgc2NyaXB0Ci0gICAgICAgICAgICBkaWUoIlRlc3Qgc2NyaXB0IGVycm9yISIpOwotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOyAvL3RvIHBsZWFzZSBqYXZhYwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRmluZHMgbmV4dCB0ZXN0IGRlc2NyaXB0aW9uIGluIGEgZ2l2ZW4gc2NyaXB0LgotICAgICAqIEBwYXJhbSBiciA8Y29kZT5CdWZmZXJlZFJlYWRlcjwvY29kZT4gZm9yIGEgc2NyaXB0IGZpbGUKLSAgICAgKiBAcmV0dXJuIHN0cmlnbiB0YWcgZm9yIG5leHQgdGVzdCBkZXNjcmlwdGlvbgotICAgICAqIEBleGNlcHRpb24gSU9FeGNlcHRpb24gaWYgc29tZSBpbyBwcm9ibGVtcyBvY2N1cmVkCi0gICAgICovCi0gICAgcHJpdmF0ZSBTdHJpbmcgZmluZE5leHRUZXN0KEJ1ZmZlcmVkUmVhZGVyIGJyKSB0aHJvd3MgSU9FeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIFN0cmluZyBudW1iZXIgPSAiIjsKLQotICAgICAgICB3aGlsZSAoYnIucmVhZHkoKSkKLSAgICAgICAgewotICAgICAgICAgICAgbnVtYmVyID0gYnIucmVhZExpbmUoKTsKLSAgICAgICAgICAgIGlmIChudW1iZXIgPT0gbnVsbCkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIG51bWJlciA9IG51bWJlci50cmltKCk7Ci0gICAgICAgICAgICBpZiAobnVtYmVyLnN0YXJ0c1dpdGgoIiMiKSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmICghbnVtYmVyLmVxdWFscygiIikpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgc2F5KCJTY3JpcHQgZXJyb3IuICBMaW5lID0gIiArIG51bWJlcik7Ci0gICAgICAgICAgICAgICAgU3lzdGVtLmV4aXQoLTEpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBudW1iZXI7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlcyB0ZXN0Y2FzZSBmb3IgdGhlIG5leHQgdGVzdCBkZXNjcmlwdGlvbiBpbiB0aGUgc2NyaXB0IGZpbGUuCi0gICAgICogQHBhcmFtIGJyIDxjb2RlPkJ1ZmZlcmVkUmVhZGVyPC9jb2RlPiBmb3Igc2NyaXB0IGZpbGUuCi0gICAgICogQHJldHVybiBhIG5ldyB0ZXNjYXNlIG9yIG51bGwuCi0gICAgICogQGV4Y2VwdGlvbiBJT0V4Y2VwdGlvbiBpZiBzb21lIGlvIHByb2JsZW1zIG9jY3VyZWQKLSAgICAgKi8KLSAgICBwcml2YXRlIFJFVGVzdENhc2UgZ2V0TmV4dFRlc3RDYXNlKEJ1ZmZlcmVkUmVhZGVyIGJyKSB0aHJvd3MgSU9FeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIC8vIEZpbmQgbmV4dCByZSB0ZXN0IGNhc2UKLSAgICAgICAgZmluYWwgU3RyaW5nIHRhZyA9IGZpbmROZXh0VGVzdChicik7Ci0KLSAgICAgICAgLy8gQXJlIHdlIGRvbmU/Ci0gICAgICAgIGlmICghYnIucmVhZHkoKSkKLSAgICAgICAgewotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBHZXQgZXhwcmVzc2lvbgotICAgICAgICBmaW5hbCBTdHJpbmcgZXhwciA9IGJyLnJlYWRMaW5lKCk7Ci0KLSAgICAgICAgLy8gR2V0IHRlc3QgaW5mb3JtYXRpb24KLSAgICAgICAgZmluYWwgU3RyaW5nIG1hdGNoQWdhaW5zdCA9IGJyLnJlYWRMaW5lKCk7Ci0gICAgICAgIGZpbmFsIGJvb2xlYW4gYmFkUGF0dGVybiA9ICJFUlIiLmVxdWFscyhtYXRjaEFnYWluc3QpOwotICAgICAgICBib29sZWFuIHNob3VsZE1hdGNoID0gZmFsc2U7Ci0gICAgICAgIGludCBleHBlY3RlZFBhcmVuQ291bnQgPSAwOwotICAgICAgICBTdHJpbmdbXSBleHBlY3RlZFBhcmVucyA9IG51bGw7Ci0KLSAgICAgICAgaWYgKCFiYWRQYXR0ZXJuKSB7Ci0gICAgICAgICAgICBzaG91bGRNYXRjaCA9IGdldEV4cGVjdGVkUmVzdWx0KGJyLnJlYWRMaW5lKCkudHJpbSgpKTsKLSAgICAgICAgICAgIGlmIChzaG91bGRNYXRjaCkgewotICAgICAgICAgICAgICAgIGV4cGVjdGVkUGFyZW5Db3VudCA9IEludGVnZXIucGFyc2VJbnQoYnIucmVhZExpbmUoKS50cmltKCkpOwotICAgICAgICAgICAgICAgIGV4cGVjdGVkUGFyZW5zID0gbmV3IFN0cmluZ1tleHBlY3RlZFBhcmVuQ291bnRdOwotICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZXhwZWN0ZWRQYXJlbkNvdW50OyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgZXhwZWN0ZWRQYXJlbnNbaV0gPSBici5yZWFkTGluZSgpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBuZXcgUkVUZXN0Q2FzZSh0aGlzLCB0YWcsIGV4cHIsIG1hdGNoQWdhaW5zdCwgYmFkUGF0dGVybiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNob3VsZE1hdGNoLCBleHBlY3RlZFBhcmVucyk7Ci0gICAgfQotfQotCi1maW5hbCBjbGFzcyBSRVRlc3RDYXNlCi17Ci0gICAgZmluYWwgcHJpdmF0ZSBTdHJpbmdCdWZmZXIgbG9nID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotICAgIGZpbmFsIHByaXZhdGUgaW50IG51bWJlcjsKLSAgICBmaW5hbCBwcml2YXRlIFN0cmluZyB0YWc7IC8vIG51bWJlciBmcm9tIHNjcmlwdCBmaWxlCi0gICAgZmluYWwgcHJpdmF0ZSBTdHJpbmcgcGF0dGVybjsKLSAgICBmaW5hbCBwcml2YXRlIFN0cmluZyB0b01hdGNoOwotICAgIGZpbmFsIHByaXZhdGUgYm9vbGVhbiBiYWRQYXR0ZXJuOwotICAgIGZpbmFsIHByaXZhdGUgYm9vbGVhbiBzaG91bGRNYXRjaDsKLSAgICBmaW5hbCBwcml2YXRlIFN0cmluZ1tdIHBhcmVuczsKLSAgICBmaW5hbCBwcml2YXRlIFJFVGVzdCB0ZXN0OwotICAgIHByaXZhdGUgUkUgcmVnZXhwOwotCi0gICAgcHVibGljIFJFVGVzdENhc2UoUkVUZXN0IHRlc3QsIFN0cmluZyB0YWcsIFN0cmluZyBwYXR0ZXJuLAotICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyB0b01hdGNoLCBib29sZWFuIGJhZFBhdHRlcm4sCi0gICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBzaG91bGRNYXRjaCwgU3RyaW5nW10gcGFyZW5zKQotICAgIHsKLSAgICAgICAgdGhpcy5udW1iZXIgPSArK3Rlc3QudGVzdENvdW50OwotICAgICAgICB0aGlzLnRlc3QgPSB0ZXN0OwotICAgICAgICB0aGlzLnRhZyA9IHRhZzsKLSAgICAgICAgdGhpcy5wYXR0ZXJuID0gcGF0dGVybjsKLSAgICAgICAgdGhpcy50b01hdGNoID0gdG9NYXRjaDsKLSAgICAgICAgdGhpcy5iYWRQYXR0ZXJuID0gYmFkUGF0dGVybjsKLSAgICAgICAgdGhpcy5zaG91bGRNYXRjaCA9IHNob3VsZE1hdGNoOwotICAgICAgICBpZiAocGFyZW5zICE9IG51bGwpIHsKLSAgICAgICAgICAgIHRoaXMucGFyZW5zID0gbmV3IFN0cmluZ1twYXJlbnMubGVuZ3RoXTsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFyZW5zLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgdGhpcy5wYXJlbnNbaV0gPSBwYXJlbnNbaV07Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICB0aGlzLnBhcmVucyA9IG51bGw7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBydW5UZXN0KCkKLSAgICB7Ci0gICAgICAgIHRlc3Quc2F5KHRhZyArICIoIiArIG51bWJlciArICIpOiAiICsgcGF0dGVybik7Ci0gICAgICAgIGlmICh0ZXN0Q3JlYXRpb24oKSkgewotICAgICAgICAgICAgdGVzdE1hdGNoKCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBib29sZWFuIHRlc3RDcmVhdGlvbigpCi0gICAgewotICAgICAgICB0cnkKLSAgICAgICAgewotICAgICAgICAgICAgLy8gQ29tcGlsZSBpdAotICAgICAgICAgICAgcmVnZXhwID0gbmV3IFJFKCk7Ci0gICAgICAgICAgICByZWdleHAuc2V0UHJvZ3JhbSh0ZXN0LmNvbXBpbGVyLmNvbXBpbGUocGF0dGVybikpOwotICAgICAgICAgICAgLy8gRXhwcmVzc2lvbiBkaWRuJ3QgY2F1c2UgYW4gZXhwZWN0ZWQgZXJyb3IKLSAgICAgICAgICAgIGlmIChiYWRQYXR0ZXJuKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIHRlc3QuZmFpbChsb2csICJXYXMgZXhwZWN0ZWQgdG8gYmUgYW4gZXJyb3IsIGJ1dCB3YXNuJ3QuIik7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgfQotICAgICAgICAvLyBTb21lIGV4cHJlc3Npb25zICpzaG91bGQqIGNhdXNlIGV4Y2VwdGlvbnMgdG8gYmUgdGhyb3duCi0gICAgICAgIGNhdGNoIChFeGNlcHRpb24gZSkKLSAgICAgICAgewotICAgICAgICAgICAgLy8gSWYgaXQgd2FzIHN1cHBvc2VkIHRvIGJlIGFuIGVycm9yLCByZXBvcnQgc3VjY2VzcyBhbmQgY29udGludWUKLSAgICAgICAgICAgIGlmIChiYWRQYXR0ZXJuKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIGxvZy5hcHBlbmQoIiAgIE1hdGNoOiBFUlJcbiIpOwotICAgICAgICAgICAgICAgIHN1Y2Nlc3MoIlByb2R1Y2VzIGFuIGVycm9yICgiICsgZS50b1N0cmluZygpICsgIiksIGFzIGV4cGVjdGVkLiIpOwotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gV2Fzbid0IHN1cHBvc2VkIHRvIGJlIGFuIGVycm9yCi0gICAgICAgICAgICBTdHJpbmcgbWVzc2FnZSA9IChlLmdldE1lc3NhZ2UoKSA9PSBudWxsKSA/IGUudG9TdHJpbmcoKSA6IGUuZ2V0TWVzc2FnZSgpOwotICAgICAgICAgICAgdGVzdC5mYWlsKGxvZywgIlByb2R1Y2VzIGFuIHVuZXhwZWN0ZWQgZXhjZXB0aW9uIFwiIiArIG1lc3NhZ2UgKyAiXCIiKTsKLSAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKEVycm9yIGUpCi0gICAgICAgIHsKLSAgICAgICAgICAgIC8vIEludGVybmFsIGVycm9yIGhhcHBlbmVkCi0gICAgICAgICAgICB0ZXN0LmZhaWwobG9nLCAiQ29tcGlsZXIgdGhyZXcgZmF0YWwgZXJyb3IgXCIiICsgZS5nZXRNZXNzYWdlKCkgKyAiXCIiKTsKLSAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIHRlc3RNYXRjaCgpCi0gICAgewotICAgICAgICBsb2cuYXBwZW5kKCIgICBNYXRjaCBhZ2FpbnN0OiAnIiArIHRvTWF0Y2ggKyAiJ1xuIik7Ci0gICAgICAgIC8vIFRyeSByZWd1bGFyIG1hdGNoaW5nCi0gICAgICAgIHRyeQotICAgICAgICB7Ci0gICAgICAgICAgICAvLyBNYXRjaCBhZ2FpbnN0IHRoZSBzdHJpbmcKLSAgICAgICAgICAgIGJvb2xlYW4gcmVzdWx0ID0gcmVnZXhwLm1hdGNoKHRvTWF0Y2gpOwotICAgICAgICAgICAgbG9nLmFwcGVuZCgiICAgTWF0Y2hlZDogIiArIChyZXN1bHQgPyAiWUVTIiA6ICJOTyIpICsgIlxuIik7Ci0KLSAgICAgICAgICAgIC8vIENoZWNrIHJlc3VsdCwgcGFyZW5zLCBhbmQgaXRlcmF0b3JzCi0gICAgICAgICAgICBpZiAoY2hlY2tSZXN1bHQocmVzdWx0KSAmJiAoIXNob3VsZE1hdGNoIHx8IGNoZWNrUGFyZW5zKCkpKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIC8vIHRlc3QgbWF0Y2goQ2hhcmFjdGVySXRlcmF0b3IsIGludCkKLSAgICAgICAgICAgICAgICAvLyBmb3IgZXZlcnkgQ2hhcmFjdGVySXRlcmF0b3IgaW1wbGVtZW50YXRpb24uCi0gICAgICAgICAgICAgICAgbG9nLmFwcGVuZCgiICAgTWF0Y2ggdXNpbmcgU3RyaW5nQ2hhcmFjdGVySXRlcmF0b3JcbiIpOwotICAgICAgICAgICAgICAgIGlmICghdHJ5TWF0Y2hVc2luZ0NJKG5ldyBTdHJpbmdDaGFyYWN0ZXJJdGVyYXRvcih0b01hdGNoKSkpCi0gICAgICAgICAgICAgICAgICAgIHJldHVybjsKLQotICAgICAgICAgICAgICAgIGxvZy5hcHBlbmQoIiAgIE1hdGNoIHVzaW5nIENoYXJhY3RlckFycmF5Q2hhcmFjdGVySXRlcmF0b3JcbiIpOwotICAgICAgICAgICAgICAgIGlmICghdHJ5TWF0Y2hVc2luZ0NJKG5ldyBDaGFyYWN0ZXJBcnJheUNoYXJhY3Rlckl0ZXJhdG9yKHRvTWF0Y2gudG9DaGFyQXJyYXkoKSwgMCwgdG9NYXRjaC5sZW5ndGgoKSkpKQotICAgICAgICAgICAgICAgICAgICByZXR1cm47Ci0KLSAgICAgICAgICAgICAgICBsb2cuYXBwZW5kKCIgICBNYXRjaCB1c2luZyBTdHJlYW1DaGFyYWN0ZXJJdGVyYXRvclxuIik7Ci0gICAgICAgICAgICAgICAgaWYgKCF0cnlNYXRjaFVzaW5nQ0kobmV3IFN0cmVhbUNoYXJhY3Rlckl0ZXJhdG9yKG5ldyBTdHJpbmdCdWZmZXJJbnB1dFN0cmVhbSh0b01hdGNoKSkpKQotICAgICAgICAgICAgICAgICAgICByZXR1cm47Ci0KLSAgICAgICAgICAgICAgICBsb2cuYXBwZW5kKCIgICBNYXRjaCB1c2luZyBSZWFkZXJDaGFyYWN0ZXJJdGVyYXRvclxuIik7Ci0gICAgICAgICAgICAgICAgaWYgKCF0cnlNYXRjaFVzaW5nQ0kobmV3IFJlYWRlckNoYXJhY3Rlckl0ZXJhdG9yKG5ldyBTdHJpbmdSZWFkZXIodG9NYXRjaCkpKSkKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIC8vIE1hdGNoZXIgYmxldyBpdAotICAgICAgICBjYXRjaChFeGNlcHRpb24gZSkKLSAgICAgICAgewotICAgICAgICAgICAgdGVzdC5mYWlsKGxvZywgIk1hdGNoZXIgdGhyZXcgZXhjZXB0aW9uOiAiICsgZS50b1N0cmluZygpKTsKLSAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgIH0KLSAgICAgICAgLy8gSW50ZXJuYWwgZXJyb3IKLSAgICAgICAgY2F0Y2goRXJyb3IgZSkKLSAgICAgICAgewotICAgICAgICAgICAgdGVzdC5mYWlsKGxvZywgIk1hdGNoZXIgdGhyZXcgZmF0YWwgZXJyb3IgXCIiICsgZS5nZXRNZXNzYWdlKCkgKyAiXCIiKTsKLSAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwcml2YXRlIGJvb2xlYW4gY2hlY2tSZXN1bHQoYm9vbGVhbiByZXN1bHQpCi0gICAgewotICAgICAgICAvLyBXcml0ZSBzdGF0dXMKLSAgICAgICAgaWYgKHJlc3VsdCA9PSBzaG91bGRNYXRjaCkgewotICAgICAgICAgICAgc3VjY2Vzcygoc2hvdWxkTWF0Y2ggPyAiTWF0Y2hlZCIgOiAiRGlkIG5vdCBtYXRjaCIpCi0gICAgICAgICAgICAgICAgICAgICsgIiBcIiIgKyB0b01hdGNoICsgIlwiLCBhcyBleHBlY3RlZDoiKTsKLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgaWYgKHNob3VsZE1hdGNoKSB7Ci0gICAgICAgICAgICAgICAgdGVzdC5mYWlsKGxvZywgIkRpZCBub3QgbWF0Y2ggXCIiICsgdG9NYXRjaCArICJcIiwgd2hlbiBleHBlY3RlZCB0by4iKTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgdGVzdC5mYWlsKGxvZywgIk1hdGNoZWQgXCIiICsgdG9NYXRjaCArICJcIiwgd2hlbiBub3QgZXhwZWN0ZWQgdG8uIik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwcml2YXRlIGJvb2xlYW4gY2hlY2tQYXJlbnMoKQotICAgIHsKLSAgICAgICAgLy8gU2hvdyBzdWJleHByZXNzaW9uIHJlZ2lzdGVycwotICAgICAgICBpZiAoUkVUZXN0LnNob3dTdWNjZXNzZXMpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHRlc3Quc2hvd1BhcmVucyhyZWdleHApOwotICAgICAgICB9Ci0KLSAgICAgICAgbG9nLmFwcGVuZCgiICAgUGFyZW4gY291bnQ6ICIgKyByZWdleHAuZ2V0UGFyZW5Db3VudCgpICsgIlxuIik7Ci0gICAgICAgIGlmICghYXNzZXJ0RXF1YWxzKGxvZywgIldyb25nIG51bWJlciBvZiBwYXJlbnMiLCBwYXJlbnMubGVuZ3RoLCByZWdleHAuZ2V0UGFyZW5Db3VudCgpKSkKLSAgICAgICAgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gQ2hlY2sgcmVnaXN0ZXJzIGFnYWluc3QgZXhwZWN0ZWQgY29udGVudHMKLSAgICAgICAgZm9yIChpbnQgcCA9IDA7IHAgPCByZWdleHAuZ2V0UGFyZW5Db3VudCgpOyBwKyspCi0gICAgICAgIHsKLSAgICAgICAgICAgIGxvZy5hcHBlbmQoIiAgIFBhcmVuICIgKyBwICsgIjogIiArIHJlZ2V4cC5nZXRQYXJlbihwKSArICJcbiIpOwotCi0gICAgICAgICAgICAvLyBDb21wYXJlIGV4cGVjdGVkIHJlc3VsdCB3aXRoIGFjdHVhbAotICAgICAgICAgICAgaWYgKCJudWxsIi5lcXVhbHMocGFyZW5zW3BdKSAmJiByZWdleHAuZ2V0UGFyZW4ocCkgPT0gbnVsbCkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAvLyBDb25zaWRlciAibnVsbCIgaW4gdGVzdCBmaWxlIGVxdWFsIHRvIG51bGwKLSAgICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmICghYXNzZXJ0RXF1YWxzKGxvZywgIldyb25nIHJlZ2lzdGVyICIgKyBwLCBwYXJlbnNbcF0sIHJlZ2V4cC5nZXRQYXJlbihwKSkpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotCi0gICAgYm9vbGVhbiB0cnlNYXRjaFVzaW5nQ0koQ2hhcmFjdGVySXRlcmF0b3IgbWF0Y2hBZ2FpbnN0KQotICAgIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGJvb2xlYW4gcmVzdWx0ID0gcmVnZXhwLm1hdGNoKG1hdGNoQWdhaW5zdCwgMCk7Ci0gICAgICAgICAgICBsb2cuYXBwZW5kKCIgICBNYXRjaDogIiArIChyZXN1bHQgPyAiWUVTIiA6ICJOTyIpICsgIlxuIik7Ci0gICAgICAgICAgICByZXR1cm4gY2hlY2tSZXN1bHQocmVzdWx0KSAmJiAoIXNob3VsZE1hdGNoIHx8IGNoZWNrUGFyZW5zKCkpOwotICAgICAgICB9Ci0gICAgICAgIC8vIE1hdGNoZXIgYmxldyBpdAotICAgICAgICBjYXRjaChFeGNlcHRpb24gZSkKLSAgICAgICAgewotICAgICAgICAgICAgdGVzdC5mYWlsKGxvZywgIk1hdGNoZXIgdGhyZXcgZXhjZXB0aW9uOiAiICsgZS50b1N0cmluZygpKTsKLSAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgIH0KLSAgICAgICAgLy8gSW50ZXJuYWwgZXJyb3IKLSAgICAgICAgY2F0Y2goRXJyb3IgZSkKLSAgICAgICAgewotICAgICAgICAgICAgdGVzdC5mYWlsKGxvZywgIk1hdGNoZXIgdGhyZXcgZmF0YWwgZXJyb3IgXCIiICsgZS5nZXRNZXNzYWdlKCkgKyAiXCIiKTsKLSAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGFzc2VydEVxdWFscyhTdHJpbmdCdWZmZXIgbG9nLCBTdHJpbmcgbWVzc2FnZSwgU3RyaW5nIGV4cGVjdGVkLCBTdHJpbmcgYWN0dWFsKQotICAgIHsKLSAgICAgICAgaWYgKGV4cGVjdGVkICE9IG51bGwgJiYgIWV4cGVjdGVkLmVxdWFscyhhY3R1YWwpCi0gICAgICAgICAgICB8fCBhY3R1YWwgIT0gbnVsbCAmJiAhYWN0dWFsLmVxdWFscyhleHBlY3RlZCkpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHRlc3QuZmFpbChsb2csIG1lc3NhZ2UgKyAiIChleHBlY3RlZCBcIiIgKyBleHBlY3RlZAotICAgICAgICAgICAgICAgICAgICAgICsgIlwiLCBhY3R1YWwgXCIiICsgYWN0dWFsICsgIlwiKSIpOwotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGFzc2VydEVxdWFscyhTdHJpbmdCdWZmZXIgbG9nLCBTdHJpbmcgbWVzc2FnZSwgaW50IGV4cGVjdGVkLCBpbnQgYWN0dWFsKQotICAgIHsKLSAgICAgICAgaWYgKGV4cGVjdGVkICE9IGFjdHVhbCkgewotICAgICAgICAgICAgdGVzdC5mYWlsKGxvZywgbWVzc2FnZSArICIgKGV4cGVjdGVkIFwiIiArIGV4cGVjdGVkCi0gICAgICAgICAgICAgICAgICAgICAgKyAiXCIsIGFjdHVhbCBcIiIgKyBhY3R1YWwgKyAiXCIpIik7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2hvdyBhIHN1Y2Nlc3MKLSAgICAgKiBAcGFyYW0gcyBTdWNjZXNzIHN0b3J5Ci0gICAgICovCi0gICAgdm9pZCBzdWNjZXNzKFN0cmluZyBzKQotICAgIHsKLSAgICAgICAgaWYgKFJFVGVzdC5zaG93U3VjY2Vzc2VzKQotICAgICAgICB7Ci0gICAgICAgICAgICB0ZXN0LnNheSgiIiArIFJFVGVzdC5ORVdfTElORSArICItLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSIgKyBSRVRlc3QuTkVXX0xJTkUgKyAiIik7Ci0gICAgICAgICAgICB0ZXN0LnNheSgiRXhwcmVzc2lvbiAjIiArIChudW1iZXIpICsgIiBcIiIgKyBwYXR0ZXJuICsgIlwiICIpOwotICAgICAgICAgICAgdGVzdC5zYXkoIlN1Y2Nlc3M6ICIgKyBzKTsKLSAgICAgICAgfQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvcmVnZXhwL2ludGVybmFsL1JFVXRpbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9yZWdleHAvaW50ZXJuYWwvUkVVdGlsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDEwOTA3ZWMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9yZWdleHAvaW50ZXJuYWwvUkVVdGlsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw2MSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnJlZ2V4cC5pbnRlcm5hbDsKLQotLyoqCi0gKiBUaGlzIGlzIGEgY2xhc3MgdGhhdCBjb250YWlucyB1dGlsaXR5IGhlbHBlciBtZXRob2RzIGZvciB0aGlzIHBhY2thZ2UuCi0gKgotICogQGF1dGhvciA8YSBocmVmPSJtYWlsdG86am9ubEBtdXBwZXRsYWJzLmNvbSI+Sm9uYXRoYW4gTG9ja2U8L2E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBSRVV0aWwKLXsKLSAgICAvKiogY29tcGxleDogKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgY29tcGxleFByZWZpeCA9ICJjb21wbGV4OiI7Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGVzIGEgcmVndWxhciBleHByZXNzaW9uLCBwZXJtaXR0aW5nIHNpbXBsZSBvciBjb21wbGV4IHN5bnRheAotICAgICAqIEBwYXJhbSBleHByZXNzaW9uIFRoZSBleHByZXNzaW9uLCBiZWdpbm5pbmcgd2l0aCBhIHByZWZpeCBpZiBpdCdzIGNvbXBsZXggb3IKLSAgICAgKiBoYXZpbmcgbm8gcHJlZml4IGlmIGl0J3Mgc2ltcGxlCi0gICAgICogQHBhcmFtIG1hdGNoRmxhZ3MgTWF0Y2hpbmcgc3R5bGUgZmxhZ3MKLSAgICAgKiBAcmV0dXJuIFRoZSByZWd1bGFyIGV4cHJlc3Npb24gb2JqZWN0Ci0gICAgICogQGV4Y2VwdGlvbiBSRVN5bnRheEV4Y2VwdGlvbiB0aHJvd24gaW4gY2FzZSBvZiBlcnJvcgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgUkUgY3JlYXRlUkUoU3RyaW5nIGV4cHJlc3Npb24sIGludCBtYXRjaEZsYWdzKSB0aHJvd3MgUkVTeW50YXhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGlmIChleHByZXNzaW9uLnN0YXJ0c1dpdGgoY29tcGxleFByZWZpeCkpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHJldHVybiBuZXcgUkUoZXhwcmVzc2lvbi5zdWJzdHJpbmcoY29tcGxleFByZWZpeC5sZW5ndGgoKSksIG1hdGNoRmxhZ3MpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBuZXcgUkUoUkUuc2ltcGxlUGF0dGVyblRvRnVsbFJlZ3VsYXJFeHByZXNzaW9uKGV4cHJlc3Npb24pLCBtYXRjaEZsYWdzKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGVzIGEgcmVndWxhciBleHByZXNzaW9uLCBwZXJtaXR0aW5nIHNpbXBsZSBvciBjb21wbGV4IHN5bnRheAotICAgICAqIEBwYXJhbSBleHByZXNzaW9uIFRoZSBleHByZXNzaW9uLCBiZWdpbm5pbmcgd2l0aCBhIHByZWZpeCBpZiBpdCdzIGNvbXBsZXggb3IKLSAgICAgKiBoYXZpbmcgbm8gcHJlZml4IGlmIGl0J3Mgc2ltcGxlCi0gICAgICogQHJldHVybiBUaGUgcmVndWxhciBleHByZXNzaW9uIG9iamVjdAotICAgICAqIEBleGNlcHRpb24gUkVTeW50YXhFeGNlcHRpb24gdGhyb3duIGluIGNhc2Ugb2YgZXJyb3IKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFJFIGNyZWF0ZVJFKFN0cmluZyBleHByZXNzaW9uKSB0aHJvd3MgUkVTeW50YXhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIHJldHVybiBjcmVhdGVSRShleHByZXNzaW9uLCBSRS5NQVRDSF9OT1JNQUwpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvcmVnZXhwL2ludGVybmFsL1JlYWRlckNoYXJhY3Rlckl0ZXJhdG9yLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3JlZ2V4cC9pbnRlcm5hbC9SZWFkZXJDaGFyYWN0ZXJJdGVyYXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3ZWFmZmY0Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvcmVnZXhwL2ludGVybmFsL1JlYWRlckNoYXJhY3Rlckl0ZXJhdG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNjQgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5yZWdleHAuaW50ZXJuYWw7Ci0KLWltcG9ydCBqYXZhLmlvLlJlYWRlcjsKLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotCi0vKioKLSAqIEVuY2Fwc3VsYXRlcyBqYXZhLmlvLlJlYWRlciBhcyBDaGFyYWN0ZXJJdGVyYXRvcgotICoKLSAqIEBhdXRob3IgPGEgaHJlZj0ibWFpbHRvOmFsZXMubm92YWtAbmV0YmVhbnMuY29tIj5BbGVzIE5vdmFrPC9hPgotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgUmVhZGVyQ2hhcmFjdGVySXRlcmF0b3IgaW1wbGVtZW50cyBDaGFyYWN0ZXJJdGVyYXRvcgotewotICAgIC8qKiBVbmRlcmx5aW5nIHJlYWRlciAqLwotICAgIHByaXZhdGUgZmluYWwgUmVhZGVyIHJlYWRlcjsKLQotICAgIC8qKiBCdWZmZXIgb2YgcmVhZCBjaGFycyAqLwotICAgIHByaXZhdGUgZmluYWwgU3RyaW5nQnVmZmVyIGJ1ZmY7Ci0KLSAgICAvKiogcmVhZCBlbmQ/ICovCi0gICAgcHJpdmF0ZSBib29sZWFuIGNsb3NlZDsKLQotICAgIC8qKiBAcGFyYW0gcmVhZGVyIGEgUmVhZGVyLCB3aGljaCBpcyBwYXJzZWQgKi8KLSAgICBwdWJsaWMgUmVhZGVyQ2hhcmFjdGVySXRlcmF0b3IoUmVhZGVyIHJlYWRlcikKLSAgICB7Ci0gICAgICAgIHRoaXMucmVhZGVyID0gcmVhZGVyOwotICAgICAgICB0aGlzLmJ1ZmYgPSBuZXcgU3RyaW5nQnVmZmVyKDUxMik7Ci0gICAgICAgIHRoaXMuY2xvc2VkID0gZmFsc2U7Ci0gICAgfQotCi0gICAgLyoqIEByZXR1cm4gYSBzdWJzdHJpbmcgKi8KLSAgICBwdWJsaWMgU3RyaW5nIHN1YnN0cmluZyhpbnQgYmVnaW5JbmRleCwgaW50IGVuZEluZGV4KQotICAgIHsKLSAgICAgICAgdHJ5Ci0gICAgICAgIHsKLSAgICAgICAgICAgIGVuc3VyZShlbmRJbmRleCk7Ci0gICAgICAgICAgICByZXR1cm4gYnVmZi50b1N0cmluZygpLnN1YnN0cmluZyhiZWdpbkluZGV4LCBlbmRJbmRleCk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKElPRXhjZXB0aW9uIGUpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKGUuZ2V0TWVzc2FnZSgpKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKiBAcmV0dXJuIGEgc3Vic3RyaW5nICovCi0gICAgcHVibGljIFN0cmluZyBzdWJzdHJpbmcoaW50IGJlZ2luSW5kZXgpCi0gICAgewotICAgICAgICB0cnkKLSAgICAgICAgewotICAgICAgICAgICAgcmVhZEFsbCgpOwotICAgICAgICAgICAgcmV0dXJuIGJ1ZmYudG9TdHJpbmcoKS5zdWJzdHJpbmcoYmVnaW5JbmRleCk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKElPRXhjZXB0aW9uIGUpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKGUuZ2V0TWVzc2FnZSgpKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKiBAcmV0dXJuIGEgY2hhcmFjdGVyIGF0IHRoZSBzcGVjaWZpZWQgcG9zaXRpb24uICovCi0gICAgcHVibGljIGNoYXIgY2hhckF0KGludCBwb3MpCi0gICAgewotICAgICAgICB0cnkKLSAgICAgICAgewotICAgICAgICAgICAgZW5zdXJlKHBvcyk7Ci0gICAgICAgICAgICByZXR1cm4gYnVmZi5jaGFyQXQocG9zKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoSU9FeGNlcHRpb24gZSkKLSAgICAgICAgewotICAgICAgICAgICAgdGhyb3cgbmV3IFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oZS5nZXRNZXNzYWdlKCkpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqIEByZXR1cm4gPHR0PnRydWU8L3R0PiBpZmYgaWYgdGhlIHNwZWNpZmllZCBpbmRleCBpcyBhZnRlciB0aGUgZW5kIG9mIHRoZSBjaGFyYWN0ZXIgc3RyZWFtICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNFbmQoaW50IHBvcykKLSAgICB7Ci0gICAgICAgIGlmIChidWZmLmxlbmd0aCgpID4gcG9zKQotICAgICAgICB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICB7Ci0gICAgICAgICAgICB0cnkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBlbnN1cmUocG9zKTsKLSAgICAgICAgICAgICAgICByZXR1cm4gKGJ1ZmYubGVuZ3RoKCkgPD0gcG9zKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhdGNoIChJT0V4Y2VwdGlvbiBlKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKGUuZ2V0TWVzc2FnZSgpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKiBSZWFkcyBuIGNoYXJhY3RlcnMgZnJvbSB0aGUgc3RyZWFtIGFuZCBhcHBlbmRzIHRoZW0gdG8gdGhlIGJ1ZmZlciAqLwotICAgIHByaXZhdGUgaW50IHJlYWQoaW50IG4pIHRocm93cyBJT0V4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaWYgKGNsb3NlZCkKLSAgICAgICAgewotICAgICAgICAgICAgcmV0dXJuIDA7Ci0gICAgICAgIH0KLQotICAgICAgICBjaGFyW10gYyA9IG5ldyBjaGFyW25dOwotICAgICAgICBpbnQgY291bnQgPSAwOwotICAgICAgICBpbnQgcmVhZCA9IDA7Ci0KLSAgICAgICAgZG8KLSAgICAgICAgewotICAgICAgICAgICAgcmVhZCA9IHJlYWRlci5yZWFkKGMpOwotICAgICAgICAgICAgaWYgKHJlYWQgPCAwKSAvLyBFT0YKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBjbG9zZWQgPSB0cnVlOwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY291bnQgKz0gcmVhZDsKLSAgICAgICAgICAgIGJ1ZmYuYXBwZW5kKGMsIDAsIHJlYWQpOwotICAgICAgICB9Ci0gICAgICAgIHdoaWxlIChjb3VudCA8IG4pOwotCi0gICAgICAgIHJldHVybiBjb3VudDsKLSAgICB9Ci0KLSAgICAvKiogUmVhZHMgcmVzdCBvZiB0aGUgc3RyZWFtLiAqLwotICAgIHByaXZhdGUgdm9pZCByZWFkQWxsKCkgdGhyb3dzIElPRXhjZXB0aW9uCi0gICAgewotICAgICAgICB3aGlsZSghIGNsb3NlZCkKLSAgICAgICAgewotICAgICAgICAgICAgcmVhZCgxMDAwKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKiBSZWFkcyBjaGFycyB1cCB0byB0aGUgaWR4ICovCi0gICAgcHJpdmF0ZSB2b2lkIGVuc3VyZShpbnQgaWR4KSB0aHJvd3MgSU9FeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGlmIChjbG9zZWQpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChpZHggPCBidWZmLmxlbmd0aCgpKQotICAgICAgICB7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLSAgICAgICAgcmVhZChpZHggKyAxIC0gYnVmZi5sZW5ndGgoKSk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9yZWdleHAvaW50ZXJuYWwvU3RyZWFtQ2hhcmFjdGVySXRlcmF0b3IuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvcmVnZXhwL2ludGVybmFsL1N0cmVhbUNoYXJhY3Rlckl0ZXJhdG9yLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGU0ODkwNjUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9yZWdleHAvaW50ZXJuYWwvU3RyZWFtQ2hhcmFjdGVySXRlcmF0b3IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE2MSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnJlZ2V4cC5pbnRlcm5hbDsKLQotaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLQotLyoqCi0gKiBFbmNhcHN1bGF0ZXMgamF2YS5pby5JbnB1dFN0cmVhbSBhcyBDaGFyYWN0ZXJJdGVyYXRvci4KLSAqCi0gKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzphbGVzLm5vdmFrQG5ldGJlYW5zLmNvbSI+QWxlcyBOb3ZhazwvYT4KLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIFN0cmVhbUNoYXJhY3Rlckl0ZXJhdG9yIGltcGxlbWVudHMgQ2hhcmFjdGVySXRlcmF0b3IKLXsKLSAgICAvKiogVW5kZXJseWluZyBpcyAqLwotICAgIHByaXZhdGUgZmluYWwgSW5wdXRTdHJlYW0gaXM7Ci0KLSAgICAvKiogQnVmZmVyIG9mIHJlYWQgY2hhcnMgKi8KLSAgICBwcml2YXRlIGZpbmFsIFN0cmluZ0J1ZmZlciBidWZmOwotCi0gICAgLyoqIHJlYWQgZW5kPyAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBjbG9zZWQ7Ci0KLSAgICAvKiogQHBhcmFtIGlzIGFuIElucHV0U3RyZWFtLCB3aGljaCBpcyBwYXJzZWQgKi8KLSAgICBwdWJsaWMgU3RyZWFtQ2hhcmFjdGVySXRlcmF0b3IoSW5wdXRTdHJlYW0gaXMpCi0gICAgewotICAgICAgICB0aGlzLmlzID0gaXM7Ci0gICAgICAgIHRoaXMuYnVmZiA9IG5ldyBTdHJpbmdCdWZmZXIoNTEyKTsKLSAgICAgICAgdGhpcy5jbG9zZWQgPSBmYWxzZTsKLSAgICB9Ci0KLSAgICAvKiogQHJldHVybiBhIHN1YnN0cmluZyAqLwotICAgIHB1YmxpYyBTdHJpbmcgc3Vic3RyaW5nKGludCBiZWdpbkluZGV4LCBpbnQgZW5kSW5kZXgpCi0gICAgewotICAgICAgICB0cnkKLSAgICAgICAgewotICAgICAgICAgICAgZW5zdXJlKGVuZEluZGV4KTsKLSAgICAgICAgICAgIHJldHVybiBidWZmLnRvU3RyaW5nKCkuc3Vic3RyaW5nKGJlZ2luSW5kZXgsIGVuZEluZGV4KTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoSU9FeGNlcHRpb24gZSkKLSAgICAgICAgewotICAgICAgICAgICAgdGhyb3cgbmV3IFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oZS5nZXRNZXNzYWdlKCkpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqIEByZXR1cm4gYSBzdWJzdHJpbmcgKi8KLSAgICBwdWJsaWMgU3RyaW5nIHN1YnN0cmluZyhpbnQgYmVnaW5JbmRleCkKLSAgICB7Ci0gICAgICAgIHRyeQotICAgICAgICB7Ci0gICAgICAgICAgICByZWFkQWxsKCk7Ci0gICAgICAgICAgICByZXR1cm4gYnVmZi50b1N0cmluZygpLnN1YnN0cmluZyhiZWdpbkluZGV4KTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoSU9FeGNlcHRpb24gZSkKLSAgICAgICAgewotICAgICAgICAgICAgdGhyb3cgbmV3IFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oZS5nZXRNZXNzYWdlKCkpOwotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICAvKiogQHJldHVybiBhIGNoYXJhY3RlciBhdCB0aGUgc3BlY2lmaWVkIHBvc2l0aW9uLiAqLwotICAgIHB1YmxpYyBjaGFyIGNoYXJBdChpbnQgcG9zKQotICAgIHsKLSAgICAgICAgdHJ5Ci0gICAgICAgIHsKLSAgICAgICAgICAgIGVuc3VyZShwb3MpOwotICAgICAgICAgICAgcmV0dXJuIGJ1ZmYuY2hhckF0KHBvcyk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKElPRXhjZXB0aW9uIGUpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKGUuZ2V0TWVzc2FnZSgpKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKiBAcmV0dXJuIDx0dD50cnVlPC90dD4gaWZmIGlmIHRoZSBzcGVjaWZpZWQgaW5kZXggaXMgYWZ0ZXIgdGhlIGVuZCBvZiB0aGUgY2hhcmFjdGVyIHN0cmVhbSAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzRW5kKGludCBwb3MpCi0gICAgewotICAgICAgICBpZiAoYnVmZi5sZW5ndGgoKSA+IHBvcykKLSAgICAgICAgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotICAgICAgICAgICAgdHJ5Ci0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgZW5zdXJlKHBvcyk7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIChidWZmLmxlbmd0aCgpIDw9IHBvcyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXRjaCAoSU9FeGNlcHRpb24gZSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihlLmdldE1lc3NhZ2UoKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKiogUmVhZHMgbiBjaGFyYWN0ZXJzIGZyb20gdGhlIHN0cmVhbSBhbmQgYXBwZW5kcyB0aGVtIHRvIHRoZSBidWZmZXIgKi8KLSAgICBwcml2YXRlIGludCByZWFkKGludCBuKSB0aHJvd3MgSU9FeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGlmIChjbG9zZWQpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHJldHVybiAwOwotICAgICAgICB9Ci0KLSAgICAgICAgaW50IGM7Ci0gICAgICAgIGludCBpID0gbjsKLSAgICAgICAgd2hpbGUgKC0taSA+PSAwKQotICAgICAgICB7Ci0gICAgICAgICAgICBjID0gaXMucmVhZCgpOwotICAgICAgICAgICAgaWYgKGMgPCAwKSAvLyBFT0YKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBjbG9zZWQgPSB0cnVlOwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgYnVmZi5hcHBlbmQoKGNoYXIpIGMpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBuIC0gaTsKLSAgICB9Ci0KLSAgICAvKiogUmVhZHMgcmVzdCBvZiB0aGUgc3RyZWFtLiAqLwotICAgIHByaXZhdGUgdm9pZCByZWFkQWxsKCkgdGhyb3dzIElPRXhjZXB0aW9uCi0gICAgewotICAgICAgICB3aGlsZSghIGNsb3NlZCkKLSAgICAgICAgewotICAgICAgICAgICAgcmVhZCgxMDAwKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKiBSZWFkcyBjaGFycyB1cCB0byB0aGUgaWR4ICovCi0gICAgcHJpdmF0ZSB2b2lkIGVuc3VyZShpbnQgaWR4KSB0aHJvd3MgSU9FeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGlmIChjbG9zZWQpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChpZHggPCBidWZmLmxlbmd0aCgpKQotICAgICAgICB7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLQotICAgICAgICByZWFkKGlkeCArIDEgLSBidWZmLmxlbmd0aCgpKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3JlZ2V4cC9pbnRlcm5hbC9TdHJpbmdDaGFyYWN0ZXJJdGVyYXRvci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9yZWdleHAvaW50ZXJuYWwvU3RyaW5nQ2hhcmFjdGVySXRlcmF0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYmM2Yzg1OS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3JlZ2V4cC9pbnRlcm5hbC9TdHJpbmdDaGFyYWN0ZXJJdGVyYXRvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNjIgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5yZWdleHAuaW50ZXJuYWw7Ci0KLS8qKgotICogRW5jYXBzdWxhdGVzIFN0cmluZyBhcyBDaGFyYWN0ZXJJdGVyYXRvci4KLSAqCi0gKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzphbGVzLm5vdmFrQG5ldGJlYW5zLmNvbSI+QWxlcyBOb3ZhazwvYT4KLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIFN0cmluZ0NoYXJhY3Rlckl0ZXJhdG9yIGltcGxlbWVudHMgQ2hhcmFjdGVySXRlcmF0b3IKLXsKLSAgICAvKiogZW5jYXBzdWxhdGVkICovCi0gICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgc3JjOwotCi0gICAgLyoqIEBwYXJhbSBzcmMgLSBlbmNhcHN1bGF0ZWQgU3RyaW5nICovCi0gICAgcHVibGljIFN0cmluZ0NoYXJhY3Rlckl0ZXJhdG9yKFN0cmluZyBzcmMpCi0gICAgewotICAgICAgICB0aGlzLnNyYyA9IHNyYzsKLSAgICB9Ci0KLSAgICAvKiogQHJldHVybiBhIHN1YnN0cmluZyAqLwotICAgIHB1YmxpYyBTdHJpbmcgc3Vic3RyaW5nKGludCBiZWdpbkluZGV4LCBpbnQgZW5kSW5kZXgpCi0gICAgewotICAgICAgICByZXR1cm4gc3JjLnN1YnN0cmluZyhiZWdpbkluZGV4LCBlbmRJbmRleCk7Ci0gICAgfQotCi0gICAgLyoqIEByZXR1cm4gYSBzdWJzdHJpbmcgKi8KLSAgICBwdWJsaWMgU3RyaW5nIHN1YnN0cmluZyhpbnQgYmVnaW5JbmRleCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBzcmMuc3Vic3RyaW5nKGJlZ2luSW5kZXgpOwotICAgIH0KLQotICAgIC8qKiBAcmV0dXJuIGEgY2hhcmFjdGVyIGF0IHRoZSBzcGVjaWZpZWQgcG9zaXRpb24uICovCi0gICAgcHVibGljIGNoYXIgY2hhckF0KGludCBwb3MpCi0gICAgewotICAgICAgICByZXR1cm4gc3JjLmNoYXJBdChwb3MpOwotICAgIH0KLQotICAgIC8qKiBAcmV0dXJuIDx0dD50cnVlPC90dD4gaWZmIGlmIHRoZSBzcGVjaWZpZWQgaW5kZXggaXMgYWZ0ZXIgdGhlIGVuZCBvZiB0aGUgY2hhcmFjdGVyIHN0cmVhbSAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzRW5kKGludCBwb3MpCi0gICAgewotICAgICAgICByZXR1cm4gKHBvcyA+PSBzcmMubGVuZ3RoKCkpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUvcmVnZXhwL2ludGVybmFsL3JlY29tcGlsZS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9yZWdleHAvaW50ZXJuYWwvcmVjb21waWxlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGZjMGNiYjMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS9yZWdleHAvaW50ZXJuYWwvcmVjb21waWxlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMzcgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS5yZWdleHAuaW50ZXJuYWw7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUucmVnZXhwLmludGVybmFsLlJFQ29tcGlsZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnJlZ2V4cC5pbnRlcm5hbC5SRVN5bnRheEV4Y2VwdGlvbjsKLQotLyoqCi0gKiAncmVjb21waWxlJyBpcyBhIGNvbW1hbmQgbGluZSB0b29sIHRoYXQgcHJlLWNvbXBpbGVzIG9uZSBvciBtb3JlIHJlZ3VsYXIgZXhwcmVzc2lvbnMKLSAqIGZvciB1c2Ugd2l0aCB0aGUgcmVndWxhciBleHByZXNzaW9uIG1hdGNoZXIgY2xhc3MgJ1JFJy4gIEZvciBleGFtcGxlLCB0aGUgY29tbWFuZAotICogImphdmEgcmVjb21waWxlIGEqYiIgcHJvZHVjZXMgb3V0cHV0IGxpa2UgdGhpczoKLSAqCi0gKiA8cHJlPgotICoKLSAqICAgIC8vIFByZS1jb21waWxlZCByZWd1bGFyIGV4cHJlc3Npb24gImEqYiIKLSAqICAgIGNoYXJbXSByZTFJbnN0cnVjdGlvbnMgPQotICogICAgewotICogICAgICAgIDB4MDA3YywgMHgwMDAwLCAweDAwMWEsIDB4MDA3YywgMHgwMDAwLCAweDAwMGQsIDB4MDA0MSwKLSAqICAgICAgICAweDAwMDEsIDB4MDAwNCwgMHgwMDYxLCAweDAwN2MsIDB4MDAwMCwgMHgwMDAzLCAweDAwNDcsCi0gKiAgICAgICAgMHgwMDAwLCAweGZmZjYsIDB4MDA3YywgMHgwMDAwLCAweDAwMDMsIDB4MDA0ZSwgMHgwMDAwLAotICogICAgICAgIDB4MDAwMywgMHgwMDQxLCAweDAwMDEsIDB4MDAwNCwgMHgwMDYyLCAweDAwNDUsIDB4MDAwMCwKLSAqICAgICAgICAweDAwMDAsCi0gKiAgICB9OwotICoKLSAqICAgIFJFUHJvZ3JhbSByZTEgPSBuZXcgUkVQcm9ncmFtKHJlMUluc3RydWN0aW9ucyk7Ci0gKgotICogPC9wcmU+Ci0gKgotICogQnkgcGFzdGluZyB0aGlzIG91dHB1dCBpbnRvIHlvdXIgY29kZSwgeW91IGNhbiBjb25zdHJ1Y3QgYSByZWd1bGFyIGV4cHJlc3Npb24gbWF0Y2hlcgotICogKFJFKSBvYmplY3QgZGlyZWN0bHkgZnJvbSB0aGUgcHJlLWNvbXBpbGVkIGRhdGEgKHRoZSBjaGFyYWN0ZXIgYXJyYXkgcmUxKSwgdGh1cyBhdm9pZGluZwotICogdGhlIG92ZXJoZWFkIG9mIGNvbXBpbGluZyB0aGUgZXhwcmVzc2lvbiBhdCBydW50aW1lLiAgRm9yIGV4YW1wbGU6Ci0gKgotICogPHByZT4KLSAqCi0gKiAgICBSRSByID0gbmV3IFJFKHJlMSk7Ci0gKgotICogPC9wcmU+Ci0gKgotICogQHNlZSBSRQotICogQHNlZSBSRUNvbXBpbGVyCi0gKgotICogQGF1dGhvciA8YSBocmVmPSJtYWlsdG86am9ubEBtdXBwZXRsYWJzLmNvbSI+Sm9uYXRoYW4gTG9ja2U8L2E+Ci0gKi8KLXB1YmxpYyBjbGFzcyByZWNvbXBpbGUKLXsKLSAgICAvKioKLSAgICAgKiBNYWluIGFwcGxpY2F0aW9uIGVudHJ5cG9pbnQuCi0gICAgICogQHBhcmFtIGFyZyBDb21tYW5kIGxpbmUgYXJndW1lbnRzCi0gICAgICovCi0gICAgc3RhdGljIHB1YmxpYyB2b2lkIG1haW4oU3RyaW5nW10gYXJnKQotICAgIHsKLSAgICAgICAgLy8gQ3JlYXRlIGEgY29tcGlsZXIgb2JqZWN0Ci0gICAgICAgIFJFQ29tcGlsZXIgciA9IG5ldyBSRUNvbXBpbGVyKCk7Ci0KLSAgICAgICAgLy8gUHJpbnQgdXNhZ2UgaWYgYXJndW1lbnRzIGFyZSBpbmNvcnJlY3QKLSAgICAgICAgaWYgKGFyZy5sZW5ndGggPD0gMCB8fCBhcmcubGVuZ3RoICUgMiAhPSAwKQotICAgICAgICB7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlVzYWdlOiByZWNvbXBpbGUgPHBhdHRlcm5uYW1lPiA8cGF0dGVybj4iKTsKLSAgICAgICAgICAgIFN5c3RlbS5leGl0KDApOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gTG9vcCB0aHJvdWdoIGFyZ3VtZW50cywgY29tcGlsaW5nIGVhY2gKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhcmcubGVuZ3RoOyBpICs9IDIpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHRyeQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIC8vIENvbXBpbGUgcmVndWxhciBleHByZXNzaW9uCi0gICAgICAgICAgICAgICAgU3RyaW5nIG5hbWUgICAgICAgICA9IGFyZ1tpXTsKLSAgICAgICAgICAgICAgICBTdHJpbmcgcGF0dGVybiAgICAgID0gYXJnW2krMV07Ci0gICAgICAgICAgICAgICAgU3RyaW5nIGluc3RydWN0aW9ucyA9IG5hbWUgKyAiUGF0dGVybkluc3RydWN0aW9ucyI7Ci0KLSAgICAgICAgICAgICAgICAvLyBPdXRwdXQgcHJvZ3JhbSBhcyBhIG5pY2UsIGZvcm1hdHRlZCBjaGFyYWN0ZXIgYXJyYXkKLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCJcbiAgICAvLyBQcmUtY29tcGlsZWQgcmVndWxhciBleHByZXNzaW9uICciICsgcGF0dGVybiArICInXG4iCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgICAgcHJpdmF0ZSBzdGF0aWMgY2hhcltdICIgKyBpbnN0cnVjdGlvbnMgKyAiID0gXG4gICAgeyIpOwotCi0gICAgICAgICAgICAgICAgLy8gQ29tcGlsZSBwcm9ncmFtIGZvciBwYXR0ZXJuCi0gICAgICAgICAgICAgICAgUkVQcm9ncmFtIHByb2dyYW0gPSByLmNvbXBpbGUocGF0dGVybik7Ci0KLSAgICAgICAgICAgICAgICAvLyBOdW1iZXIgb2YgY29sdW1ucyBpbiBvdXRwdXQKLSAgICAgICAgICAgICAgICBpbnQgbnVtQ29sdW1ucyA9IDc7Ci0KLSAgICAgICAgICAgICAgICAvLyBMb29wIHRocm91Z2ggcHJvZ3JhbQotICAgICAgICAgICAgICAgIGNoYXJbXSBwID0gcHJvZ3JhbS5nZXRJbnN0cnVjdGlvbnMoKTsKLSAgICAgICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IHAubGVuZ3RoOyBqKyspCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAvLyBFbmQgb2YgY29sdW1uPwotICAgICAgICAgICAgICAgICAgICBpZiAoKGogJSBudW1Db2x1bW5zKSA9PSAwKQotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCJcbiAgICAgICAgIik7Ci0gICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAvLyBQcmludCBjaGFyYWN0ZXIgYXMgcGFkZGVkIGhleCBudW1iZXIKLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGhleCA9IEludGVnZXIudG9IZXhTdHJpbmcocFtqXSk7Ci0gICAgICAgICAgICAgICAgICAgIHdoaWxlIChoZXgubGVuZ3RoKCkgPCA0KQotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBoZXggPSAiMCIgKyBoZXg7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiMHgiICsgaGV4ICsgIiwgIik7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgLy8gRW5kIG9mIHByb2dyYW0gYmxvY2sKLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlxuICAgIH07Iik7Ci0gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJcbiAgICBwcml2YXRlIHN0YXRpYyBSRSAiICsgbmFtZSArICJQYXR0ZXJuID0gbmV3IFJFKG5ldyBSRVByb2dyYW0oIiArIGluc3RydWN0aW9ucyArICIpKTsiKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhdGNoIChSRVN5bnRheEV4Y2VwdGlvbiBlKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiU3ludGF4IGVycm9yIGluIGV4cHJlc3Npb24gXCIiICsgYXJnW2ldICsgIlwiOiAiICsgZS50b1N0cmluZygpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhdGNoIChFeGNlcHRpb24gZSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlVuZXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZS50b1N0cmluZygpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhdGNoIChFcnJvciBlKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiSW50ZXJuYWwgZXJyb3I6ICIgKyBlLnRvU3RyaW5nKCkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC9WZXJzaW9uLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL1ZlcnNpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYmU5YzE5ZC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL1ZlcnNpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE1NSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAzLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBWZXJzaW9uLmphdmEsdiAxLjEuMi4xIDIwMDUvMDgvMDEgMDI6MTE6MTkgamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbDsKLQotLyoqCi0gKiBBZG1pbmlzdHJhdGl2ZSBjbGFzcyB0byBrZWVwIHRyYWNrIG9mIHRoZSB2ZXJzaW9uIG51bWJlciBvZgotICogdGhlIFhhbGFuIHJlbGVhc2UuCi0gKiA8UD5UaGlzIGNsYXNzIGltcGxlbWVudHMgdGhlIHVwY29taW5nIHN0YW5kYXJkIG9mIGhhdmluZwotICogb3JnLmFwYWNoZS5wcm9qZWN0LW5hbWUuVmVyc2lvbi5nZXRWZXJzaW9uKCkgYmUgYSBzdGFuZGFyZCB3YXkKLSAqIHRvIGdldCB2ZXJzaW9uIGluZm9ybWF0aW9uLiAgVGhpcyBjbGFzcyB3aWxsIHJlcGxhY2UgdGhlIG9sZGVyCi0gKiBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwucHJvY2Vzc29yLlZlcnNpb24gY2xhc3MuPC9QPgotICogPFA+U2VlIGFsc286IGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC9yZXMvWFNMVEluZm8ucHJvcGVydGllcyBmb3IKLSAqIGluZm9ybWF0aW9uIGFib3V0IHRoZSB2ZXJzaW9uIG9mIHRoZSBYU0xUIHNwZWMgd2Ugc3VwcG9ydC48L1A+Ci0gKiBAeHNsLnVzYWdlIGdlbmVyYWwKLSAqLwotcHVibGljIGNsYXNzIFZlcnNpb24KLXsKLQotICAvKioKLSAgICogR2V0IHRoZSBiYXNpYyB2ZXJzaW9uIHN0cmluZyBmb3IgdGhlIGN1cnJlbnQgWGFsYW4gcmVsZWFzZS4KLSAgICogVmVyc2lvbiBTdHJpbmcgZm9ybWF0dGVkIGxpa2UKLSAgICogPENPREU+IjxCPlhhbGFuPC9CPiA8Qj5KYXZhPC9CPiB2LnJbLmRkfCA8Qj5EPC9CPm5uXSI8L0NPREU+LgotICAgKgotICAgKiBGdXR1cmV3b3JrOiBoYXZlIHRoaXMgcmVhZCB2ZXJzaW9uIGluZm8gZnJvbSBqYXIgbWFuaWZlc3QuCi0gICAqCi0gICAqIEByZXR1cm4gU3RyaW5nIGRlbm90aW5nIG91ciBjdXJyZW50IHZlcnNpb24KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldFZlcnNpb24oKQotICB7Ci0gICAgIHJldHVybiBnZXRQcm9kdWN0KCkrIiAiK2dldEltcGxlbWVudGF0aW9uTGFuZ3VhZ2UoKSsiICIKLSAgICAgICAgICAgK2dldE1ham9yVmVyc2lvbk51bSgpKyIuIitnZXRSZWxlYXNlVmVyc2lvbk51bSgpKyIuIgotICAgICAgICAgICArKCAoZ2V0RGV2ZWxvcG1lbnRWZXJzaW9uTnVtKCkgPiAwKSA/Ci0gICAgICAgICAgICAgICAoIkQiK2dldERldmVsb3BtZW50VmVyc2lvbk51bSgpKSA6ICgiIitnZXRNYWludGVuYW5jZVZlcnNpb25OdW0oKSkpOwotICB9Ci0KLSAgLyoqCi0gICAqIFByaW50IHRoZSBwcm9jZXNzb3IgdmVyc2lvbiB0byB0aGUgY29tbWFuZCBsaW5lLgotICAgKgotICAgKiBAcGFyYW0gYXJndiBjb21tYW5kIGxpbmUgYXJndW1lbnRzLCB1bnVzZWQuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIHZvaWQgX21haW4oU3RyaW5nIGFyZ3ZbXSkKLSAgewotICAgIFN5c3RlbS5vdXQucHJpbnRsbihnZXRWZXJzaW9uKCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIE5hbWUgb2YgcHJvZHVjdDogWGFsYW4uCi0gICAqLwotICBwdWJsaWMgc3RhdGljIFN0cmluZyBnZXRQcm9kdWN0KCkKLSAgewotICAgIHJldHVybiAiWGFsYW4iOwotICB9Ci0KLSAgLyoqCi0gICAqIEltcGxlbWVudGF0aW9uIExhbmd1YWdlOiBKYXZhLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0SW1wbGVtZW50YXRpb25MYW5ndWFnZSgpCi0gIHsKLSAgICByZXR1cm4gIkphdmEiOwotICB9Ci0KLQotICAvKioKLSAgICogTWFqb3IgdmVyc2lvbiBudW1iZXIuCi0gICAqIFZlcnNpb24gbnVtYmVyLiBUaGlzIGNoYW5nZXMgb25seSB3aGVuIHRoZXJlIGlzIGEKLSAgICogICAgICAgICAgc2lnbmlmaWNhbnQsIGV4dGVybmFsbHkgYXBwYXJlbnQgZW5oYW5jZW1lbnQgZnJvbQotICAgKiAgICAgICAgICB0aGUgcHJldmlvdXMgcmVsZWFzZS4gJ24nIHJlcHJlc2VudHMgdGhlIG4ndGgKLSAgICogICAgICAgICAgdmVyc2lvbi4KLSAgICoKLSAgICogICAgICAgICAgQ2xpZW50cyBzaG91bGQgY2FyZWZ1bGx5IGNvbnNpZGVyIHRoZSBpbXBsaWNhdGlvbnMKLSAgICogICAgICAgICAgb2YgbmV3IHZlcnNpb25zIGFzIGV4dGVybmFsIGludGVyZmFjZXMgYW5kIGJlaGF2aW91cgotICAgKiAgICAgICAgICBtYXkgaGF2ZSBjaGFuZ2VkLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBpbnQgZ2V0TWFqb3JWZXJzaW9uTnVtKCkKLSAgewotICAgIHJldHVybiAyOwotCi0gIH0KLQotICAvKioKLSAgICogUmVsZWFzZSBOdW1iZXIuCi0gICAqIFJlbGVhc2UgbnVtYmVyLiBUaGlzIGNoYW5nZXMgd2hlbjoKLSAgICogICAgICAgICAgICAtICBhIG5ldyBzZXQgb2YgZnVuY3Rpb25hbGl0eSBpcyB0byBiZSBhZGRlZCwgZWcsCi0gICAqICAgICAgICAgICAgICAgaW1wbGVtZW50YXRpb24gb2YgYSBuZXcgVzNDIHNwZWNpZmljYXRpb24uCi0gICAqICAgICAgICAgICAgLSAgQVBJIG9yIGJlaGF2aW91ciBjaGFuZ2UuCi0gICAqICAgICAgICAgICAgLSAgaXRzIGRlc2lnbmF0ZWQgYXMgYSByZWZlcmVuY2UgcmVsZWFzZS4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgaW50IGdldFJlbGVhc2VWZXJzaW9uTnVtKCkKLSAgewotICAgIHJldHVybiA3OwotICB9Ci0KLSAgLyoqCi0gICAqIE1haW50ZW5hbmNlIERyb3AgTnVtYmVyLgotICAgKiBPcHRpb25hbCBpZGVudGlmaWVyIHVzZWQgdG8gZGVzaWduYXRlIG1haW50ZW5hbmNlCi0gICAqICAgICAgICAgIGRyb3AgYXBwbGllZCB0byBhIHNwZWNpZmljIHJlbGVhc2UgYW5kIGNvbnRhaW5zCi0gICAqICAgICAgICAgIGZpeGVzIGZvciBkZWZlY3RzIHJlcG9ydGVkLiBJdCBtYWludGFpbnMgY29tcGF0aWJpbGl0eQotICAgKiAgICAgICAgICB3aXRoIHRoZSByZWxlYXNlIGFuZCBjb250YWlucyBubyBBUEkgY2hhbmdlcy4KLSAgICogICAgICAgICAgV2hlbiBtaXNzaW5nLCBpdCBkZXNpZ25hdGVzIHRoZSBmaW5hbCBhbmQgY29tcGxldGUKLSAgICogICAgICAgICAgZGV2ZWxvcG1lbnQgZHJvcCBmb3IgYSByZWxlYXNlLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBpbnQgZ2V0TWFpbnRlbmFuY2VWZXJzaW9uTnVtKCkKLSAgewotICAgIHJldHVybiAwOwotICB9Ci0KLSAgLyoqCi0gICAqIERldmVsb3BtZW50IERyb3AgTnVtYmVyLgotICAgKiBPcHRpb25hbCBpZGVudGlmaWVyIGRlc2lnbmF0ZXMgZGV2ZWxvcG1lbnQgZHJvcCBvZgotICAgKiAgICAgICAgICBhIHNwZWNpZmljIHJlbGVhc2UuIEQwMSBpcyB0aGUgZmlyc3QgZGV2ZWxvcG1lbnQgZHJvcAotICAgKiAgICAgICAgICBvZiBhIG5ldyByZWxlYXNlLgotICAgKgotICAgKiAgICAgICAgICBEZXZlbG9wbWVudCBkcm9wcyBhcmUgd29ya3MgaW4gcHJvZ3Jlc3MgdG93YXJkcyBhCi0gICAqICAgICAgICAgIGNvbXBlbGV0ZWQsIGZpbmFsIHJlbGVhc2UuIEEgc3BlY2lmaWMgZGV2ZWxvcG1lbnQgZHJvcAotICAgKiAgICAgICAgICBtYXkgbm90IGNvbXBsZXRlbHkgaW1wbGVtZW50IGFsbCBhc3BlY3RzIG9mIGEgbmV3Ci0gICAqICAgICAgICAgIGZlYXR1cmUsIHdoaWNoIG1heSB0YWtlIHNldmVyYWwgZGV2ZWxvcG1lbnQgZHJvcHMgdG8KLSAgICogICAgICAgICAgY29tcGxldGUuIEF0IHRoZSBwb2ludCBvZiB0aGUgZmluYWwgZHJvcCBmb3IgdGhlCi0gICAqICAgICAgICAgIHJlbGVhc2UsIHRoZSBEIHN1ZmZpeCB3aWxsIGJlIG9taXR0ZWQuCi0gICAqCi0gICAqICAgICAgICAgIEVhY2ggJ0QnIGRyb3BzIGNhbiBjb250YWluIGZ1bmN0aW9uYWwgZW5oYW5jZW1lbnRzIGFzCi0gICAqICAgICAgICAgIHdlbGwgYXMgZGVmZWN0IGZpeGVzLiAnRCcgZHJvcHMgbWF5IG5vdCBiZSBhcyBzdGFibGUgYXMKLSAgICogICAgICAgICAgdGhlIGZpbmFsIHJlbGVhc2VzLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBpbnQgZ2V0RGV2ZWxvcG1lbnRWZXJzaW9uTnVtKCkKLSAgewotICAgIHRyeSB7Ci0gICAgICAgIGlmICgobmV3IFN0cmluZygiIikpLmxlbmd0aCgpID09IDApCi0gICAgICAgICAgcmV0dXJuIDA7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICByZXR1cm4gSW50ZWdlci5wYXJzZUludCgiIik7Ci0gICAgfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIG5mZSkgewotICAgICAgICAgICByZXR1cm4gMDsKLSAgICB9Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwvWGFsYW5Db25zdGFudHMuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwvWGFsYW5Db25zdGFudHMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZDc3ZGZiMC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL1hhbGFuQ29uc3RhbnRzLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyNjYgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAxMSwgMjAxNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWw7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwudXRpbHMuU2VjdXJpdHlTdXBwb3J0OwotCi0vKioKLSAqIENvbW1vbmx5IHVzZWQgY29uc3RhbnRzLgotICoKLSAqIEBhdXRob3IgSHVpemhlIFdhbmcsIE9yYWNsZQotICoKLSAqIEB2ZXJzaW9uICRJZDogQ29uc3RhbnRzLmphdmEsdiAxLjE0IDIwMTEtMDYtMDcgMDQ6Mzk6NDAgam9laHcgRXhwICQKLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIFhhbGFuQ29uc3RhbnRzIHsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RhbnRzCi0gICAgLy8KLSAgICAvL1hlcmNlcyBzZWN1cml0eSBtYW5hZ2VyCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU0VDVVJJVFlfTUFOQUdFUiA9Ci0gICAgICAgICAgICAiaHR0cDovL2FwYWNoZS5vcmcveG1sL3Byb3BlcnRpZXMvc2VjdXJpdHktbWFuYWdlciI7Ci0KLSAgICAvLwotICAgIC8vIEltcGxlbWVudGF0aW9uIGxpbWl0czogQVBJIHByb3BlcnRpZXMKLSAgICAvLwotICAgIC8qKiBPcmFjbGUgSkFYUCBwcm9wZXJ0eSBwcmVmaXggKCJodHRwOi8vd3d3Lm9yYWNsZS5jb20veG1sL2pheHAvcHJvcGVydGllcy8iKS4gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBPUkFDTEVfSkFYUF9QUk9QRVJUWV9QUkVGSVggPQotICAgICAgICAiaHR0cDovL3d3dy5vcmFjbGUuY29tL3htbC9qYXhwL3Byb3BlcnRpZXMvIjsKLSAgICAvKioKLSAgICAgKiBKREsgZW50aXR5IGV4cGFuc2lvbiBsaW1pdDsgTm90ZSB0aGF0IHRoZSBleGlzdGluZyBzeXN0ZW0gcHJvcGVydHkKLSAgICAgKiAiZW50aXR5RXhwYW5zaW9uTGltaXQiIHdpdGggbm8gcHJlZml4IGlzIHN0aWxsIG9ic2VydmVkCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSkRLX0VOVElUWV9FWFBBTlNJT05fTElNSVQgPQotICAgICAgICAgICAgT1JBQ0xFX0pBWFBfUFJPUEVSVFlfUFJFRklYICsgImVudGl0eUV4cGFuc2lvbkxpbWl0IjsKLQotICAgIC8qKgotICAgICAqIEpESyBlbGVtZW50IGF0dHJpYnV0ZSBsaW1pdDsgTm90ZSB0aGF0IHRoZSBleGlzdGluZyBzeXN0ZW0gcHJvcGVydHkKLSAgICAgKiAiZWxlbWVudEF0dHJpYnV0ZUxpbWl0IiB3aXRoIG5vIHByZWZpeCBpcyBzdGlsbCBvYnNlcnZlZAotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEpES19FTEVNRU5UX0FUVFJJQlVURV9MSU1JVCA9Ci0gICAgICAgICAgICBPUkFDTEVfSkFYUF9QUk9QRVJUWV9QUkVGSVggKyAiZWxlbWVudEF0dHJpYnV0ZUxpbWl0IjsKLQotICAgIC8qKgotICAgICAqIEpESyBtYXhPY2N1ciBsaW1pdDsgTm90ZSB0aGF0IHRoZSBleGlzdGluZyBzeXN0ZW0gcHJvcGVydHkKLSAgICAgKiAibWF4T2NjdXJMaW1pdCIgd2l0aCBubyBwcmVmaXggaXMgc3RpbGwgb2JzZXJ2ZWQKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBKREtfTUFYX09DQ1VSX0xJTUlUID0KLSAgICAgICAgICAgIE9SQUNMRV9KQVhQX1BST1BFUlRZX1BSRUZJWCArICJtYXhPY2N1ckxpbWl0IjsKLQotICAgIC8qKgotICAgICAqIEpESyB0b3RhbCBlbnRpdHkgc2l6ZSBsaW1pdAotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEpES19UT1RBTF9FTlRJVFlfU0laRV9MSU1JVCA9Ci0gICAgICAgICAgICBPUkFDTEVfSkFYUF9QUk9QRVJUWV9QUkVGSVggKyAidG90YWxFbnRpdHlTaXplTGltaXQiOwotCi0gICAgLyoqCi0gICAgICogSkRLIG1heGltdW0gZ2VuZXJhbCBlbnRpdHkgc2l6ZSBsaW1pdAotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEpES19HRU5FUkFMX0VOVElUWV9TSVpFX0xJTUlUID0KLSAgICAgICAgICAgIE9SQUNMRV9KQVhQX1BST1BFUlRZX1BSRUZJWCArICJtYXhHZW5lcmFsRW50aXR5U2l6ZUxpbWl0IjsKLQotICAgIC8qKgotICAgICAqIEpESyBub2RlIGNvdW50IGxpbWl0IGluIGVudGl0aWVzIHRoYXQgbGltaXRzIHRoZSB0b3RhbCBudW1iZXIgb2Ygbm9kZXMKLSAgICAgKiBpbiBhbGwgb2YgZW50aXR5IHJlZmVyZW5jZXMuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSkRLX0VOVElUWV9SRVBMQUNFTUVOVF9MSU1JVCA9Ci0gICAgICAgICAgICBPUkFDTEVfSkFYUF9QUk9QRVJUWV9QUkVGSVggKyAiZW50aXR5UmVwbGFjZW1lbnRMaW1pdCI7Ci0KLSAgICAvKioKLSAgICAgKiBKREsgbWF4aW11bSBwYXJhbWV0ZXIgZW50aXR5IHNpemUgbGltaXQKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBKREtfUEFSQU1FVEVSX0VOVElUWV9TSVpFX0xJTUlUID0KLSAgICAgICAgICAgIE9SQUNMRV9KQVhQX1BST1BFUlRZX1BSRUZJWCArICJtYXhQYXJhbWV0ZXJFbnRpdHlTaXplTGltaXQiOwotICAgIC8qKgotICAgICAqIEpESyBtYXhpbXVtIFhNTCBuYW1lIGxpbWl0Ci0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSkRLX1hNTF9OQU1FX0xJTUlUID0KLSAgICAgICAgICAgIE9SQUNMRV9KQVhQX1BST1BFUlRZX1BSRUZJWCArICJtYXhYTUxOYW1lTGltaXQiOwotCi0gICAgLyoqCi0gICAgICogSkRLIG1heEVsZW1lbnREZXB0aCBsaW1pdAotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEpES19NQVhfRUxFTUVOVF9ERVBUSCA9Ci0gICAgICAgICAgICBPUkFDTEVfSkFYUF9QUk9QRVJUWV9QUkVGSVggKyAibWF4RWxlbWVudERlcHRoIjsKLQotICAgIC8qKgotICAgICAqIEpESyBwcm9wZXJ0eSBpbmRpY2F0aW5nIHdoZXRoZXIgdGhlIHBhcnNlciBzaGFsbCBwcmludCBvdXQgZW50aXR5Ci0gICAgICogY291bnQgaW5mb3JtYXRpb24KLSAgICAgKiBWYWx1ZTogYSBzdHJpbmcgInllcyIgbWVhbnMgcHJpbnQsICJubyIgb3IgYW55IG90aGVyIHN0cmluZyBtZWFucyBub3QuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSkRLX0VOVElUWV9DT1VOVF9JTkZPID0KLSAgICAgICAgICAgIE9SQUNMRV9KQVhQX1BST1BFUlRZX1BSRUZJWCArICJnZXRFbnRpdHlDb3VudEluZm8iOwotCi0gICAgLy8KLSAgICAvLyBJbXBsZW1lbnRhdGlvbiBsaW1pdHM6IGNvcnJlc3BvbmRpbmcgU3lzdGVtIFByb3BlcnRpZXMgb2YgdGhlIGFib3ZlCi0gICAgLy8gQVBJIHByb3BlcnRpZXMKLSAgICAvLwotICAgIC8qKgotICAgICAqIEpESyBlbnRpdHkgZXhwYW5zaW9uIGxpbWl0OyBOb3RlIHRoYXQgdGhlIGV4aXN0aW5nIHN5c3RlbSBwcm9wZXJ0eQotICAgICAqICJlbnRpdHlFeHBhbnNpb25MaW1pdCIgd2l0aCBubyBwcmVmaXggaXMgc3RpbGwgb2JzZXJ2ZWQKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBTUF9FTlRJVFlfRVhQQU5TSU9OX0xJTUlUID0gImpkay54bWwuZW50aXR5RXhwYW5zaW9uTGltaXQiOwotCi0gICAgLyoqCi0gICAgICogSkRLIGVsZW1lbnQgYXR0cmlidXRlIGxpbWl0OyBOb3RlIHRoYXQgdGhlIGV4aXN0aW5nIHN5c3RlbSBwcm9wZXJ0eQotICAgICAqICJlbGVtZW50QXR0cmlidXRlTGltaXQiIHdpdGggbm8gcHJlZml4IGlzIHN0aWxsIG9ic2VydmVkCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1BfRUxFTUVOVF9BVFRSSUJVVEVfTElNSVQgPSAgImpkay54bWwuZWxlbWVudEF0dHJpYnV0ZUxpbWl0IjsKLQotICAgIC8qKgotICAgICAqIEpESyBtYXhPY2N1ciBsaW1pdDsgTm90ZSB0aGF0IHRoZSBleGlzdGluZyBzeXN0ZW0gcHJvcGVydHkKLSAgICAgKiAibWF4T2NjdXJMaW1pdCIgd2l0aCBubyBwcmVmaXggaXMgc3RpbGwgb2JzZXJ2ZWQKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBTUF9NQVhfT0NDVVJfTElNSVQgPSAiamRrLnhtbC5tYXhPY2N1ckxpbWl0IjsKLQotICAgIC8qKgotICAgICAqIEpESyB0b3RhbCBlbnRpdHkgc2l6ZSBsaW1pdAotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFNQX1RPVEFMX0VOVElUWV9TSVpFX0xJTUlUID0gImpkay54bWwudG90YWxFbnRpdHlTaXplTGltaXQiOwotCi0gICAgLyoqCi0gICAgICogSkRLIG1heGltdW0gZ2VuZXJhbCBlbnRpdHkgc2l6ZSBsaW1pdAotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFNQX0dFTkVSQUxfRU5USVRZX1NJWkVfTElNSVQgPSAiamRrLnhtbC5tYXhHZW5lcmFsRW50aXR5U2l6ZUxpbWl0IjsKLQotICAgIC8qKgotICAgICAqIEpESyBub2RlIGNvdW50IGxpbWl0IGluIGVudGl0aWVzIHRoYXQgbGltaXRzIHRoZSB0b3RhbCBudW1iZXIgb2Ygbm9kZXMKLSAgICAgKiBpbiBhbGwgb2YgZW50aXR5IHJlZmVyZW5jZXMuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1BfRU5USVRZX1JFUExBQ0VNRU5UX0xJTUlUID0gImpkay54bWwuZW50aXR5UmVwbGFjZW1lbnRMaW1pdCI7Ci0KLSAgICAvKioKLSAgICAgKiBKREsgbWF4aW11bSBwYXJhbWV0ZXIgZW50aXR5IHNpemUgbGltaXQKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBTUF9QQVJBTUVURVJfRU5USVRZX1NJWkVfTElNSVQgPSAiamRrLnhtbC5tYXhQYXJhbWV0ZXJFbnRpdHlTaXplTGltaXQiOwotICAgIC8qKgotICAgICAqIEpESyBtYXhpbXVtIFhNTCBuYW1lIGxpbWl0Ci0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1BfWE1MX05BTUVfTElNSVQgPSAiamRrLnhtbC5tYXhYTUxOYW1lTGltaXQiOwotCi0gICAgLyoqCi0gICAgICogSkRLIG1heEVsZW1lbnREZXB0aCBsaW1pdAotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFNQX01BWF9FTEVNRU5UX0RFUFRIID0gImpkay54bWwubWF4RWxlbWVudERlcHRoIjsKLQotICAgIC8qKgotICAgICAqIEpESyBUcmFuc2Zvcm1lckZhY3RvcnkgYW5kIFRyYW5zZm9ybWVyIGF0dHJpYnV0ZSB0aGF0IHNwZWNpZmllcyBhIGNsYXNzCi0gICAgICogbG9hZGVyIHRoYXQgd2lsbCBiZSB1c2VkIGZvciBleHRlbnNpb24gZnVuY3Rpb25zIGNsYXNzIGxvYWRpbmcKLSAgICAgKiBWYWx1ZTogYSAibnVsbCIsIHRoZSBkZWZhdWx0IHZhbHVlLCBtZWFucyB0aGF0IHRoZSBkZWZhdWx0IEVGIGNsYXNzIGxvYWRpbmcKLSAgICAgKiBwYXRoIHdpbGwgYmUgdXNlZC4KLSAgICAgKiBJbnN0YW5jZSBvZiBDbGFzc0xvYWRlcjogdGhlIHNwZWNpZmllZCBpbnN0YW5jZSBvZiBDbGFzc0xvYWRlciB3aWxsIGJlIHVzZWQKLSAgICAgKiBmb3IgZXh0ZW5zaW9uIGZ1bmN0aW9ucyBsb2FkaW5nIGR1cmluZyB0cmFuc2xhdGlvbiBwcm9jZXNzCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSkRLX0VYVEVOU0lPTl9DTEFTU0xPQURFUiA9ICJqZGsueG1sLnRyYW5zZm9ybS5leHRlbnNpb25DbGFzc0xvYWRlciI7Ci0KLSAgICAvL2xlZ2FjeSBTeXN0ZW0gUHJvcGVydGllcwotICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgU3RyaW5nIEVOVElUWV9FWFBBTlNJT05fTElNSVQgPSAiZW50aXR5RXhwYW5zaW9uTGltaXQiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVMRU1FTlRfQVRUUklCVVRFX0xJTUlUID0gImVsZW1lbnRBdHRyaWJ1dGVMaW1pdCIgOwotICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgU3RyaW5nIE1BWF9PQ0NVUl9MSU1JVCA9ICJtYXhPY2N1ckxpbWl0IjsKLQotICAgIC8qKgotICAgICAqIEEgc3RyaW5nICJ5ZXMiIHRoYXQgY2FuIGJlIHVzZWQgZm9yIHByb3BlcnRpZXMgc3VjaCBhcyBnZXRFbnRpdHlDb3VudEluZm8KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBKREtfWUVTID0gInllcyI7Ci0KLSAgICAvLyBPcmFjbGUgRmVhdHVyZToKLSAgICAvKioKLSAgICAgKiA8cD5Vc2UgU2VydmljZSBNZWNoYW5pc208L3A+Ci0gICAgICoKLSAgICAgKiA8dWw+Ci0gICAgICogICA8bGk+Ci0gICAgICAgICAqIHtAY29kZSB0cnVlfSBpbnN0cnVjdCBhbiBvYmplY3QgdG8gdXNlIHNlcnZpY2UgbWVjaGFuaXNtIHRvCi0gICAgICAgICAqIGZpbmQgYSBzZXJ2aWNlIGltcGxlbWVudGF0aW9uLiBUaGlzIGlzIHRoZSBkZWZhdWx0IGJlaGF2aW9yLgotICAgICAgICAgKiAgIDwvbGk+Ci0gICAgICAgICAqICAgPGxpPgotICAgICAgICAgKiB7QGNvZGUgZmFsc2V9IGluc3RydWN0IGFuIG9iamVjdCB0byBza2lwIHNlcnZpY2UgbWVjaGFuaXNtIGFuZAotICAgICAgICAgKiB1c2UgdGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gZm9yIHRoYXQgc2VydmljZS4KLSAgICAgICAgICogICA8L2xpPgotICAgICAgICAgKiA8L3VsPgotICAgICAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBPUkFDTEVfRkVBVFVSRV9TRVJWSUNFX01FQ0hBTklTTSA9ICJodHRwOi8vd3d3Lm9yYWNsZS5jb20vZmVhdHVyZS91c2Utc2VydmljZS1tZWNoYW5pc20iOwotCi0KLSAgICAvL1N5c3RlbSBQcm9wZXJ0aWVzIGNvcnJlc3BvbmRpbmcgdG8gQUNDRVNTX0VYVEVSTkFMXyogcHJvcGVydGllcwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFNQX0FDQ0VTU19FWFRFUk5BTF9TVFlMRVNIRUVUID0gImphdmF4LnhtbC5hY2Nlc3NFeHRlcm5hbFN0eWxlc2hlZXQiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFNQX0FDQ0VTU19FWFRFUk5BTF9EVEQgPSAiamF2YXgueG1sLmFjY2Vzc0V4dGVybmFsRFREIjsKLQotICAgIC8vYWxsIGFjY2VzcyBrZXl3b3JkCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQUNDRVNTX0VYVEVSTkFMX0FMTCA9ICJhbGwiOwotCi0gICAgLyoqCi0gICAgICogRGVmYXVsdCB2YWx1ZSB3aGVuIEZFQVRVUkVfU0VDVVJFX1BST0NFU1NJTkcgKEZTUCkgaXMgc2V0IHRvIHRydWUKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFWFRFUk5BTF9BQ0NFU1NfREVGQVVMVF9GU1AgPSAiIjsKLQotICAgIC8qKgotICAgICAqIEZFQVRVUkVfU0VDVVJFX1BST0NFU1NJTkcgKEZTUCkgaXMgZmFsc2UgYnkgZGVmYXVsdAotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVYVEVSTkFMX0FDQ0VTU19ERUZBVUxUID0gQUNDRVNTX0VYVEVSTkFMX0FMTDsKLQotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFhNTF9TRUNVUklUWV9QUk9QRVJUWV9NQU5BR0VSID0KLSAgICAgICAgICAgIE9SQUNMRV9KQVhQX1BST1BFUlRZX1BSRUZJWCArICJ4bWxTZWN1cml0eVByb3BlcnR5TWFuYWdlciI7Ci0KLSAgICAvKioKLSAgICAgKiBGZWF0dXJlIGVuYWJsZUV4dGVuc2lvbkZ1bmN0aW9ucwotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIE9SQUNMRV9FTkFCTEVfRVhURU5TSU9OX0ZVTkNUSU9OID0KLSAgICAgICAgICAgIE9SQUNMRV9KQVhQX1BST1BFUlRZX1BSRUZJWCArICJlbmFibGVFeHRlbnNpb25GdW5jdGlvbnMiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFNQX09SQUNMRV9FTkFCTEVfRVhURU5TSU9OX0ZVTkNUSU9OID0gImphdmF4LnhtbC5lbmFibGVFeHRlbnNpb25GdW5jdGlvbnMiOwotCi0gICAgLyoqCi0gICAgICogVmFsdWVzIGZvciBhIGZlYXR1cmUKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBGRUFUVVJFX1RSVUUgPSAidHJ1ZSI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRkVBVFVSRV9GQUxTRSA9ICJmYWxzZSI7Ci0KLSAgICAvKioKLSAgICAgKiBDaGVjayBpZiB3ZSdyZSBpbiBqZGs4IG9yIGFib3ZlCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBib29sZWFuIElTX0pESzhfT1JfQUJPVkUgPSBpc0phdmFWZXJzaW9uQXRMZWFzdCg4KTsKLQotICAgIC8qCi0gICAgICogQ2hlY2sgdGhlIHZlcnNpb24gb2YgdGhlIGN1cnJlbnQgSkRLIGFnYWluc3QgdGhhdCBzcGVjaWZpZWQgaW4gdGhlCi0gICAgICogcGFyYW1ldGVyCi0gICAgICoKLSAgICAgKiBUaGVyZSBpcyBhIHByb3Bvc2FsIHRvIGNoYW5nZSB0aGUgamF2YSB2ZXJzaW9uIHN0cmluZyB0bzoKLSAgICAgKiBNQUpPUi5NSU5PUi5GVS5DUFUuUFNVLUJVSUxETlVNQkVSX0JVR0lETlVNQkVSX09QVElPTkFMCi0gICAgICogVGhpcyBtZXRob2Qgd291bGQgd29yayB3aXRoIGJvdGggdGhlIGN1cnJlbnQgZm9ybWF0IGFuZCB0aGF0IHByb3Bvc2VkCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29tcGFyZVRvIGEgSkRLIHZlcnNpb24gdG8gYmUgY29tcGFyZWQgdG8KLSAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGN1cnJlbnQgdmVyc2lvbiBpcyB0aGUgc2FtZSBvciBhYm92ZSB0aGF0IHJlcHJlc2VudGVkCi0gICAgICogYnkgdGhlIHBhcmFtZXRlcgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0phdmFWZXJzaW9uQXRMZWFzdChpbnQgY29tcGFyZVRvKSB7Ci0gICAgICAgIFN0cmluZyBqYXZhVmVyc2lvbiA9IFNlY3VyaXR5U3VwcG9ydC5nZXRTeXN0ZW1Qcm9wZXJ0eSgiamF2YS52ZXJzaW9uIik7Ci0gICAgICAgIFN0cmluZyB2ZXJzaW9uc1tdID0gamF2YVZlcnNpb24uc3BsaXQoIlxcLiIsIDMpOwotICAgICAgICBpZiAoSW50ZWdlci5wYXJzZUludCh2ZXJzaW9uc1swXSkgPj0gY29tcGFyZVRvIHx8Ci0gICAgICAgICAgICBJbnRlZ2VyLnBhcnNlSW50KHZlcnNpb25zWzFdKSA+PSBjb21wYXJlVG8pIHsKLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci19IC8vIGNsYXNzIENvbnN0YW50cwpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC9leHRlbnNpb25zL0V4cHJlc3Npb25Db250ZXh0LmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL2V4dGVuc2lvbnMvRXhwcmVzc2lvbkNvbnRleHQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNzAzZTJhZi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL2V4dGVuc2lvbnMvRXhwcmVzc2lvbkNvbnRleHQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDk1ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IEV4cHJlc3Npb25Db250ZXh0LmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTAgMTk6MzQ6MDMgamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC5leHRlbnNpb25zOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5FcnJvckxpc3RlbmVyOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWE9iamVjdDsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotaW1wb3J0IG9yZy53M2MuZG9tLnRyYXZlcnNhbC5Ob2RlSXRlcmF0b3I7Ci0KLS8qKgotICogQW4gb2JqZWN0IHRoYXQgaW1wbGVtZW50cyB0aGlzIGludGVyZmFjZSBjYW4gc3VwcGx5Ci0gKiBpbmZvcm1hdGlvbiBhYm91dCB0aGUgY3VycmVudCBYUGF0aCBleHByZXNzaW9uIGNvbnRleHQuCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgRXhwcmVzc2lvbkNvbnRleHQKLXsKLQotICAvKioKLSAgICogR2V0IHRoZSBjdXJyZW50IGNvbnRleHQgbm9kZS4KLSAgICogQHJldHVybiBUaGUgY3VycmVudCBjb250ZXh0IG5vZGUuCi0gICAqLwotICBwdWJsaWMgTm9kZSBnZXRDb250ZXh0Tm9kZSgpOwotCi0gIC8qKgotICAgKiBHZXQgdGhlIGN1cnJlbnQgY29udGV4dCBub2RlIGxpc3QuCi0gICAqIEByZXR1cm4gQW4gaXRlcmF0b3IgZm9yIHRoZSBjdXJyZW50IGNvbnRleHQgbGlzdCwgYXMKLSAgICogZGVmaW5lZCBpbiBYU0xULgotICAgKi8KLSAgcHVibGljIE5vZGVJdGVyYXRvciBnZXRDb250ZXh0Tm9kZXMoKTsKLQotICAvKioKLSAgICogR2V0IHRoZSBlcnJvciBsaXN0ZW5lci4KLSAgICogQHJldHVybiBUaGUgcmVnaXN0ZXJlZCBlcnJvciBsaXN0ZW5lci4KLSAgICovCi0gIHB1YmxpYyBFcnJvckxpc3RlbmVyIGdldEVycm9yTGlzdGVuZXIoKTsKLQotICAvKioKLSAgICogR2V0IHRoZSB2YWx1ZSBvZiBhIG5vZGUgYXMgYSBudW1iZXIuCi0gICAqIEBwYXJhbSBuIE5vZGUgdG8gYmUgY29udmVydGVkIHRvIGEgbnVtYmVyLiAgTWF5IGJlIG51bGwuCi0gICAqIEByZXR1cm4gdmFsdWUgb2YgbiBhcyBhIG51bWJlci4KLSAgICovCi0gIHB1YmxpYyBkb3VibGUgdG9OdW1iZXIoTm9kZSBuKTsKLQotICAvKioKLSAgICogR2V0IHRoZSB2YWx1ZSBvZiBhIG5vZGUgYXMgYSBzdHJpbmcuCi0gICAqIEBwYXJhbSBuIE5vZGUgdG8gYmUgY29udmVydGVkIHRvIGEgc3RyaW5nLiAgTWF5IGJlIG51bGwuCi0gICAqIEByZXR1cm4gdmFsdWUgb2YgbiBhcyBhIHN0cmluZywgb3IgYW4gZW1wdHkgc3RyaW5nIGlmIG4gaXMgbnVsbC4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoTm9kZSBuKTsKLQotICAvKioKLSAgICogR2V0IGEgdmFyaWFibGUgYmFzZWQgb24gaXQncyBxdWFsaWZpZWQgbmFtZS4KLSAgICoKLSAgICogQHBhcmFtIHFuYW1lIFRoZSBxdWFsaWZpZWQgbmFtZSBvZiB0aGUgdmFyaWFibGUuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGV2YWx1YXRlZCB2YWx1ZSBvZiB0aGUgdmFyaWFibGUuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFhPYmplY3QgZ2V0VmFyaWFibGVPclBhcmFtKGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuUU5hbWUgcW5hbWUpCi0gICAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLQotICAvKioKLSAgICogR2V0IHRoZSBYUGF0aENvbnRleHQgdGhhdCBvd25zIHRoaXMgRXhwcmVzc2lvbkNvbnRleHQuCi0gICAqCi0gICAqIE5vdGU6IGV4c2x0OmZ1bmN0aW9uIHJlcXVpcmVzIHRoZSBYUGF0aENvbnRleHQgdG8gYWNjZXNzCi0gICAqIHRoZSB2YXJpYWJsZSBzdGFjayBhbmQgVHJhbnNmb3JtZXJJbXBsLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBjdXJyZW50IFhQYXRoQ29udGV4dC4KLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoQ29udGV4dCBnZXRYUGF0aENvbnRleHQoKQotICAgICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwvZXh0ZW5zaW9ucy9wYWNrYWdlLmh0bWwgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL2V4dGVuc2lvbnMvcGFja2FnZS5odG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4ZDFkMzc5Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwvZXh0ZW5zaW9ucy9wYWNrYWdlLmh0bWwKKysrIC9kZXYvbnVsbApAQCAtMSwyOCArMCwwIEBACi08IS0tCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotLS0+Ci08IS0tCi0gKiBDb3B5cmlnaHQgMjAwMC0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLS0tPgotPCEtLSAkSWQgLS0+Ci08aHRtbD4KLSAgPHRpdGxlPlhhbGFuIEV4dGVuc2lvbiBNZWNoYW5pc20gUGFja2FnZS48L3RpdGxlPgotICA8Ym9keT4KLSAgICA8cD5JbXBsZW1lbnRhdGlvbiBvZiBYYWxhbiBFeHRlbnNpb24gTWVjaGFuaXNtLjxwPgotIDwvYm9keT4KLTwvaHRtbD4KLQotCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL2xpYi9FeHNsdEJhc2UuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwvbGliL0V4c2x0QmFzZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzMWY4MGI4Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwvbGliL0V4c2x0QmFzZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsODYgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRXhzbHRCYXNlLmphdmEsdiAxLjEuMi4xIDIwMDUvMDgvMDEgMDI6MDg6NTEgamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC5saWI7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5yZWYuRFRNTm9kZVByb3h5OwotCi1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlTGlzdDsKLQotLyoqCi0gKiBUaGUgYmFzZSBjbGFzcyBmb3Igc29tZSBFWFNMVCBleHRlbnNpb24gY2xhc3Nlcy4KLSAqIEl0IGNvbnRhaW5zIGNvbW1vbiB1dGlsaXR5IG1ldGhvZHMgdG8gYmUgdXNlZCBieSB0aGUgc3ViLWNsYXNzZXMuCi0gKi8KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBFeHNsdEJhc2UKLXsKLSAgLyoqCi0gICAqIFJldHVybiB0aGUgc3RyaW5nIHZhbHVlIG9mIGEgTm9kZQotICAgKgotICAgKiBAcGFyYW0gbiBUaGUgTm9kZS4KLSAgICogQHJldHVybiBUaGUgc3RyaW5nIHZhbHVlIG9mIHRoZSBOb2RlCi0gICAqLwotICBwcm90ZWN0ZWQgc3RhdGljIFN0cmluZyB0b1N0cmluZyhOb2RlIG4pCi0gIHsKLSAgICBpZiAobiBpbnN0YW5jZW9mIERUTU5vZGVQcm94eSkKLSAgICAgICAgIHJldHVybiAoKERUTU5vZGVQcm94eSluKS5nZXRTdHJpbmdWYWx1ZSgpOwotICAgIGVsc2UKLSAgICB7Ci0gICAgICBTdHJpbmcgdmFsdWUgPSBuLmdldE5vZGVWYWx1ZSgpOwotICAgICAgaWYgKHZhbHVlID09IG51bGwpCi0gICAgICB7Ci0gICAgICAgIE5vZGVMaXN0IG5vZGVsaXN0ID0gbi5nZXRDaGlsZE5vZGVzKCk7Ci0gICAgICAgIFN0cmluZ0J1ZmZlciBidWYgPSBuZXcgU3RyaW5nQnVmZmVyKCk7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbm9kZWxpc3QuZ2V0TGVuZ3RoKCk7IGkrKykKLSAgICAgICAgewotICAgICAgICAgIE5vZGUgY2hpbGROb2RlID0gbm9kZWxpc3QuaXRlbShpKTsKLSAgICAgICAgICBidWYuYXBwZW5kKHRvU3RyaW5nKGNoaWxkTm9kZSkpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBidWYudG9TdHJpbmcoKTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgICAgcmV0dXJuIHZhbHVlOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBDb252ZXJ0IHRoZSBzdHJpbmcgdmFsdWUgb2YgYSBOb2RlIHRvIGEgbnVtYmVyLgotICAgKiBSZXR1cm4gTmFOIGlmIHRoZSBzdHJpbmcgaXMgbm90IGEgdmFsaWQgbnVtYmVyLgotICAgKgotICAgKiBAcGFyYW0gbiBUaGUgTm9kZS4KLSAgICogQHJldHVybiBUaGUgbnVtYmVyIHZhbHVlIG9mIHRoZSBOb2RlCi0gICAqLwotICBwcm90ZWN0ZWQgc3RhdGljIGRvdWJsZSB0b051bWJlcihOb2RlIG4pCi0gIHsKLSAgICBkb3VibGUgZCA9IDAuMDsKLSAgICBTdHJpbmcgc3RyID0gdG9TdHJpbmcobik7Ci0gICAgdHJ5Ci0gICAgewotICAgICAgZCA9IERvdWJsZS52YWx1ZU9mKHN0cikuZG91YmxlVmFsdWUoKTsKLSAgICB9Ci0gICAgY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBlKQotICAgIHsKLSAgICAgIGQ9IERvdWJsZS5OYU47Ci0gICAgfQotICAgIHJldHVybiBkOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL2xpYi9FeHNsdENvbW1vbi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC9saWIvRXhzbHRDb21tb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYjQ0OTNjMC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL2xpYi9FeHNsdENvbW1vbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTA4ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IEV4c2x0Q29tbW9uLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTUgMDI6NDU6MjQgamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC5saWI7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwuZXh0ZW5zaW9ucy5FeHByZXNzaW9uQ29udGV4dDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1JdGVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5yZWYuRFRNTm9kZUl0ZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5Ob2RlU2V0OwotCi0vKioKLSAqIFRoaXMgY2xhc3MgY29udGFpbnMgRVhTTFQgY29tbW9uIGV4dGVuc2lvbiBmdW5jdGlvbnMuCi0gKiBJdCBpcyBhY2Nlc3NlZCBieSBzcGVjaWZ5aW5nIGEgbmFtZXNwYWNlIFVSSSBhcyBmb2xsb3dzOgotICogPHByZT4KLSAqICAgIHhtbG5zOmV4c2x0PSJodHRwOi8vZXhzbHQub3JnL2NvbW1vbiIKLSAqIDwvcHJlPgotICoKLSAqIFRoZSBkb2N1bWVudGF0aW9uIGZvciBlYWNoIGZ1bmN0aW9uIGhhcyBiZWVuIGNvcGllZCBmcm9tIHRoZSByZWxldmFudAotICogRVhTTFQgSW1wbGVtZW50ZXIgcGFnZS4KLSAqCi0gKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cuZXhzbHQub3JnLyI+RVhTTFQ8L2E+Ci0gKiBAeHNsLnVzYWdlIGdlbmVyYWwKLSAqLwotcHVibGljIGNsYXNzIEV4c2x0Q29tbW9uCi17Ci0gIC8qKgotICAgKiBUaGUgZXhzbDpvYmplY3QtdHlwZSBmdW5jdGlvbiByZXR1cm5zIGEgc3RyaW5nIGdpdmluZyB0aGUgdHlwZSBvZiB0aGUgb2JqZWN0IHBhc3NlZAotICAgKiBhcyB0aGUgYXJndW1lbnQuIFRoZSBwb3NzaWJsZSBvYmplY3QgdHlwZXMgYXJlOiAnc3RyaW5nJywgJ251bWJlcicsICdib29sZWFuJywKLSAgICogJ25vZGUtc2V0JywgJ1JURicsIG9yICdleHRlcm5hbCcuCi0gICAqCi0gICAqIE1vc3QgWFNMVCBvYmplY3QgdHlwZXMgY2FuIGJlIGNvZXJjZWQgdG8gZWFjaCBvdGhlciB3aXRob3V0IGVycm9yLiBIb3dldmVyLCB0aGVyZSBhcmUKLSAgICogY2VydGFpbiBjb2VyY2lvbnMgdGhhdCByYWlzZSBlcnJvcnMsIG1vc3QgaW1wb3J0YW50bHkgdHJlYXRpbmcgYW55dGhpbmcgb3RoZXIgdGhhbiBhCi0gICAqIG5vZGUgc2V0IGFzIGEgbm9kZSBzZXQuIEF1dGhvcnMgb2YgdXRpbGl0aWVzIHN1Y2ggYXMgbmFtZWQgdGVtcGxhdGVzIG9yIHVzZXItZGVmaW5lZAotICAgKiBleHRlbnNpb24gZnVuY3Rpb25zIG1heSB3aXNoIHRvIGdpdmUgc29tZSBmbGV4aWJpbGl0eSBpbiB0aGUgcGFyYW1ldGVyIGFuZCBhcmd1bWVudCB2YWx1ZXMKLSAgICogdGhhdCBhcmUgYWNjZXB0ZWQgYnkgdGhlIHV0aWxpdHk7IHRoZSBleHNsOm9iamVjdC10eXBlIGZ1bmN0aW9uIGVuYWJsZXMgdGhlbSB0byBkbyBzby4KLSAgICoKLSAgICogVGhlIFhhbGFuIGV4dGVuc2lvbnMgTWV0aG9kUmVzb2x2ZXIgY29udmVydHMgJ29iamVjdC10eXBlJyB0byAnb2JqZWN0VHlwZScuCi0gICAqCi0gICAqIEBwYXJhbSBvYmogVGhlIG9iamVjdCB0byBiZSB0eXBlZC4KLSAgICogQHJldHVybiBvYmplY3RUeXBlICdzdHJpbmcnLCAnbnVtYmVyJywgJ2Jvb2xlYW4nLCAnbm9kZS1zZXQnLCAnUlRGJywgb3IgJ2V4dGVybmFsJy4KLSAgICoKLSAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LmV4c2x0Lm9yZy8iPkVYU0xUPC9hPgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBTdHJpbmcgb2JqZWN0VHlwZSAoT2JqZWN0IG9iaikKLSAgewotICAgIGlmIChvYmogaW5zdGFuY2VvZiBTdHJpbmcpCi0gICAgICByZXR1cm4gInN0cmluZyI7Ci0gICAgZWxzZSBpZiAob2JqIGluc3RhbmNlb2YgQm9vbGVhbikKLSAgICAgIHJldHVybiAiYm9vbGVhbiI7Ci0gICAgZWxzZSBpZiAob2JqIGluc3RhbmNlb2YgTnVtYmVyKQotICAgICAgcmV0dXJuICJudW1iZXIiOwotICAgIGVsc2UgaWYgKG9iaiBpbnN0YW5jZW9mIERUTU5vZGVJdGVyYXRvcikKLSAgICB7Ci0gICAgICBEVE1JdGVyYXRvciBkdG1JID0gKChEVE1Ob2RlSXRlcmF0b3Ipb2JqKS5nZXREVE1JdGVyYXRvcigpOwotICAgICAgaWYgKGR0bUkgaW5zdGFuY2VvZiBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuYXhlcy5SVEZJdGVyYXRvcikKLSAgICAgICAgcmV0dXJuICJSVEYiOwotICAgICAgZWxzZQotICAgICAgICByZXR1cm4gIm5vZGUtc2V0IjsKLSAgICB9Ci0gICAgZWxzZQotICAgICAgcmV0dXJuICJ1bmtub3duIjsKLSAgfQotCi0gIC8qKgotICAgKiBUaGUgZXhzbDpub2RlLXNldCBmdW5jdGlvbiBjb252ZXJ0cyBhIHJlc3VsdCB0cmVlIGZyYWdtZW50ICh3aGljaCBpcyB3aGF0IHlvdSBnZXQKLSAgICogd2hlbiB5b3UgdXNlIHRoZSBjb250ZW50IG9mIHhzbDp2YXJpYWJsZSByYXRoZXIgdGhhbiBpdHMgc2VsZWN0IGF0dHJpYnV0ZSB0byBnaXZlCi0gICAqIGEgdmFyaWFibGUgdmFsdWUpIGludG8gYSBub2RlIHNldC4gVGhpcyBlbmFibGVzIHlvdSB0byBwcm9jZXNzIHRoZSBYTUwgdGhhdCB5b3UgY3JlYXRlCi0gICAqIHdpdGhpbiBhIHZhcmlhYmxlLCBhbmQgdGhlcmVmb3JlIGRvIG11bHRpLXN0ZXAgcHJvY2Vzc2luZy4KLSAgICoKLSAgICogWW91IGNhbiBhbHNvIHVzZSB0aGlzIGZ1bmN0aW9uIHRvIHR1cm4gYSBzdHJpbmcgaW50byBhIHRleHQgbm9kZSwgd2hpY2ggaXMgaGVscGZ1bAotICAgKiBpZiB5b3Ugd2FudCB0byBwYXNzIGEgc3RyaW5nIHRvIGEgZnVuY3Rpb24gdGhhdCBvbmx5IGFjY2VwdHMgYSBub2RlIHNldC4KLSAgICoKLSAgICogVGhlIFhhbGFuIGV4dGVuc2lvbnMgTWV0aG9kUmVzb2x2ZXIgY29udmVydHMgJ25vZGUtc2V0JyB0byAnbm9kZVNldCcuCi0gICAqCi0gICAqIEBwYXJhbSBteVByb2Nlc3NvciBpcyBwYXNzZWQgaW4gYnkgdGhlIFhhbGFuIGV4dGVuc2lvbiBwcm9jZXNzb3IKLSAgICogQHBhcmFtIHJ0ZiBUaGUgcmVzdWx0IHRyZWUgZnJhZ21lbnQgdG8gYmUgY29udmVydGVkIHRvIGEgbm9kZS1zZXQuCi0gICAqCi0gICAqIEByZXR1cm4gbm9kZS1zZXQgd2l0aCB0aGUgY29udGVudHMgb2YgdGhlIHJlc3VsdCB0cmVlIGZyYWdtZW50LgotICAgKgotICAgKiBOb3RlOiBBbHJlYWR5IGltcGxlbWVudGVkIGluIHRoZSB4YWxhbiBuYW1lc3BhY2UgYXMgbm9kZXNldC4KLSAgICoKLSAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LmV4c2x0Lm9yZy8iPkVYU0xUPC9hPgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBOb2RlU2V0IG5vZGVTZXQoRXhwcmVzc2lvbkNvbnRleHQgbXlQcm9jZXNzb3IsIE9iamVjdCBydGYpCi0gIHsKLSAgICByZXR1cm4gRXh0ZW5zaW9ucy5ub2Rlc2V0KG15UHJvY2Vzc29yLCBydGYpOwotICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwvbGliL0V4c2x0RGF0ZXRpbWUuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwvbGliL0V4c2x0RGF0ZXRpbWUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZDcxN2Q4ZC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL2xpYi9FeHNsdERhdGV0aW1lLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMTIyICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IEV4c2x0RGF0ZXRpbWUuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xMCAxODo1MDo0OSBqZWZmc3V0dG9yIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwubGliOwotCi0KLWltcG9ydCBqYXZhLnRleHQuUGFyc2VFeGNlcHRpb247Ci1pbXBvcnQgamF2YS50ZXh0LlNpbXBsZURhdGVGb3JtYXQ7Ci1pbXBvcnQgamF2YS51dGlsLkNhbGVuZGFyOwotaW1wb3J0IGphdmEudXRpbC5EYXRlOwotaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7Ci1pbXBvcnQgamF2YS51dGlsLlRpbWVab25lOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWEJvb2xlYW47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWE51bWJlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YT2JqZWN0OwotCi0vKioKLSAqIFRoaXMgY2xhc3MgY29udGFpbnMgRVhTTFQgZGF0ZXMgYW5kIHRpbWVzIGV4dGVuc2lvbiBmdW5jdGlvbnMuCi0gKiBJdCBpcyBhY2Nlc3NlZCBieSBzcGVjaWZ5aW5nIGEgbmFtZXNwYWNlIFVSSSBhcyBmb2xsb3dzOgotICogPHByZT4KLSAqICAgIHhtbG5zOmRhdGV0aW1lPSJodHRwOi8vZXhzbHQub3JnL2RhdGVzLWFuZC10aW1lcyIKLSAqIDwvcHJlPgotICoKLSAqIFRoZSBkb2N1bWVudGF0aW9uIGZvciBlYWNoIGZ1bmN0aW9uIGhhcyBiZWVuIGNvcGllZCBmcm9tIHRoZSByZWxldmFudAotICogRVhTTFQgSW1wbGVtZW50ZXIgcGFnZS4KLSAqCi0gKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cuZXhzbHQub3JnLyI+RVhTTFQ8L2E+Ci0gKiBAeHNsLnVzYWdlIGdlbmVyYWwKLSAqLwotCi1wdWJsaWMgY2xhc3MgRXhzbHREYXRldGltZQotewotICAgIC8vIERhdGV0aW1lIGZvcm1hdHMgKGVyYSBhbmQgem9uZSBoYW5kbGVkIHNlcGFyYXRlbHkpLgotICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgZHQgPSAieXl5eS1NTS1kZCdUJ0hIOm1tOnNzIjsKLSAgICBzdGF0aWMgZmluYWwgU3RyaW5nIGQgPSAieXl5eS1NTS1kZCI7Ci0gICAgc3RhdGljIGZpbmFsIFN0cmluZyBneW0gPSAieXl5eS1NTSI7Ci0gICAgc3RhdGljIGZpbmFsIFN0cmluZyBneSA9ICJ5eXl5IjsKLSAgICBzdGF0aWMgZmluYWwgU3RyaW5nIGdtZCA9ICItLU1NLWRkIjsKLSAgICBzdGF0aWMgZmluYWwgU3RyaW5nIGdtID0gIi0tTU0tLSI7Ci0gICAgc3RhdGljIGZpbmFsIFN0cmluZyBnZCA9ICItLS1kZCI7Ci0gICAgc3RhdGljIGZpbmFsIFN0cmluZyB0ID0gIkhIOm1tOnNzIjsKLSAgICBzdGF0aWMgZmluYWwgU3RyaW5nIEVNUFRZX1NUUiA9ICIiOwotCi0gICAgLyoqCi0gICAgICogVGhlIGRhdGU6ZGF0ZS10aW1lIGZ1bmN0aW9uIHJldHVybnMgdGhlIGN1cnJlbnQgZGF0ZSBhbmQgdGltZSBhcyBhIGRhdGUvdGltZSBzdHJpbmcuCi0gICAgICogVGhlIGRhdGUvdGltZSBzdHJpbmcgdGhhdCdzIHJldHVybmVkIG11c3QgYmUgYSBzdHJpbmcgaW4gdGhlIGZvcm1hdCBkZWZpbmVkIGFzIHRoZQotICAgICAqIGxleGljYWwgcmVwcmVzZW50YXRpb24gb2YgeHM6ZGF0ZVRpbWUgaW4KLSAgICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94bWxzY2hlbWEtMi8jZGF0ZVRpbWUiPlszLjIuNyBkYXRlVGltZV08L2E+IG9mCi0gICAgICogPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveG1sc2NoZW1hLTIvIj5bWE1MIFNjaGVtYSBQYXJ0IDI6IERhdGF0eXBlc108L2E+LgotICAgICAqIFRoZSBkYXRlL3RpbWUgZm9ybWF0IGlzIGJhc2ljYWxseSBDQ1lZLU1NLUREVGhoOm1tOnNzLCBhbHRob3VnaCBpbXBsZW1lbnRlcnMgc2hvdWxkIGNvbnN1bHQKLSAgICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94bWxzY2hlbWEtMi8iPltYTUwgU2NoZW1hIFBhcnQgMjogRGF0YXR5cGVzXTwvYT4gYW5kCi0gICAgICogPGEgaHJlZj0iaHR0cDovL3d3dy5pc28uY2gvbWFya2V0ZS84NjAxLnBkZiI+W0lTTyA4NjAxXTwvYT4gZm9yIGRldGFpbHMuCi0gICAgICogVGhlIGRhdGUvdGltZSBzdHJpbmcgZm9ybWF0IG11c3QgaW5jbHVkZSBhIHRpbWUgem9uZSwgZWl0aGVyIGEgWiB0byBpbmRpY2F0ZSBDb29yZGluYXRlZAotICAgICAqIFVuaXZlcnNhbCBUaW1lIG9yIGEgKyBvciAtIGZvbGxvd2VkIGJ5IHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIGRpZmZlcmVuY2UgZnJvbSBVVEMKLSAgICAgKiByZXByZXNlbnRlZCBhcyBoaDptbS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBkYXRlVGltZSgpCi0gICAgewotICAgICAgQ2FsZW5kYXIgY2FsID0gQ2FsZW5kYXIuZ2V0SW5zdGFuY2UoKTsKLSAgICAgIERhdGUgZGF0ZXRpbWUgPSBjYWwuZ2V0VGltZSgpOwotICAgICAgLy8gRm9ybWF0IGZvciBkYXRlIGFuZCB0aW1lLgotICAgICAgU2ltcGxlRGF0ZUZvcm1hdCBkYXRlRm9ybWF0ID0gbmV3IFNpbXBsZURhdGVGb3JtYXQoZHQpOwotCi0gICAgICBTdHJpbmdCdWZmZXIgYnVmZiA9IG5ldyBTdHJpbmdCdWZmZXIoZGF0ZUZvcm1hdC5mb3JtYXQoZGF0ZXRpbWUpKTsKLSAgICAgIC8vIE11c3QgYWxzbyBpbmNsdWRlIG9mZnNldCBmcm9tIFVURi4KLSAgICAgIC8vIEdldCB0aGUgb2Zmc2V0IChpbiBtaWxsaXNlY29uZHMpLgotICAgICAgaW50IG9mZnNldCA9IGNhbC5nZXQoQ2FsZW5kYXIuWk9ORV9PRkZTRVQpICsgY2FsLmdldChDYWxlbmRhci5EU1RfT0ZGU0VUKTsKLSAgICAgIC8vIElmIHRoZXJlIGlzIG5vIG9mZnNldCwgd2UgaGF2ZSAiQ29vcmRpbmF0ZWQKLSAgICAgIC8vIFVuaXZlcnNhbCBUaW1lLiIKLSAgICAgIGlmIChvZmZzZXQgPT0gMCkKLSAgICAgICAgYnVmZi5hcHBlbmQoIloiKTsKLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgLy8gQ29udmVydCBtaWxsaXNlY29uZHMgdG8gaG91cnMgYW5kIG1pbnV0ZXMKLSAgICAgICAgaW50IGhycyA9IG9mZnNldC8oNjAqNjAqMTAwMCk7Ci0gICAgICAgIC8vIEluIGEgZmV3IGNhc2VzLCB0aGUgdGltZSB6b25lIG1heSBiZSArLy1oaDozMC4KLSAgICAgICAgaW50IG1pbiA9IG9mZnNldCUoNjAqNjAqMTAwMCk7Ci0gICAgICAgIGNoYXIgcG9zbmVnID0gaHJzIDwgMD8gJy0nOiAnKyc7Ci0gICAgICAgIGJ1ZmYuYXBwZW5kKHBvc25lZykuYXBwZW5kKGZvcm1hdERpZ2l0cyhocnMpKS5hcHBlbmQoJzonKS5hcHBlbmQoZm9ybWF0RGlnaXRzKG1pbikpOwotICAgICAgfQotICAgICAgcmV0dXJuIGJ1ZmYudG9TdHJpbmcoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXByZXNlbnQgdGhlIGhvdXJzIGFuZCBtaW51dGVzIHdpdGggdHdvLWRpZ2l0IHN0cmluZ3MuCi0gICAgICogQHBhcmFtIHEgaHJzIG9yIG1pbnV0ZXMuCi0gICAgICogQHJldHVybiB0d28tZGlnaXQgU3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIGhycyBvciBtaW51dGVzLgotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBmb3JtYXREaWdpdHMoaW50IHEpCi0gICAgewotICAgICAgU3RyaW5nIGRkID0gU3RyaW5nLnZhbHVlT2YoTWF0aC5hYnMocSkpOwotICAgICAgcmV0dXJuIGRkLmxlbmd0aCgpID09IDEgPyAnMCcgKyBkZCA6IGRkOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoZSBkYXRlOmRhdGUgZnVuY3Rpb24gcmV0dXJucyB0aGUgZGF0ZSBzcGVjaWZpZWQgaW4gdGhlIGRhdGUvdGltZSBzdHJpbmcgZ2l2ZW4KLSAgICAgKiBhcyB0aGUgYXJndW1lbnQuIElmIG5vIGFyZ3VtZW50IGlzIGdpdmVuLCB0aGVuIHRoZSBjdXJyZW50IGxvY2FsIGRhdGUvdGltZSwgYXMKLSAgICAgKiByZXR1cm5lZCBieSBkYXRlOmRhdGUtdGltZSBpcyB1c2VkIGFzIGEgZGVmYXVsdCBhcmd1bWVudC4KLSAgICAgKiBUaGUgZGF0ZS90aW1lIHN0cmluZyB0aGF0J3MgcmV0dXJuZWQgbXVzdCBiZSBhIHN0cmluZyBpbiB0aGUgZm9ybWF0IGRlZmluZWQgYXMgdGhlCi0gICAgICogbGV4aWNhbCByZXByZXNlbnRhdGlvbiBvZiB4czpkYXRlVGltZSBpbgotICAgICAqIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3htbHNjaGVtYS0yLyNkYXRlVGltZSI+WzMuMi43IGRhdGVUaW1lXTwvYT4gb2YKLSAgICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94bWxzY2hlbWEtMi8iPltYTUwgU2NoZW1hIFBhcnQgMjogRGF0YXR5cGVzXTwvYT4uCi0gICAgICogSWYgdGhlIGFyZ3VtZW50IGlzIG5vdCBpbiBlaXRoZXIgb2YgdGhlc2UgZm9ybWF0cywgZGF0ZTpkYXRlIHJldHVybnMgYW4gZW1wdHkgc3RyaW5nICgnJykuCi0gICAgICogVGhlIGRhdGUvdGltZSBmb3JtYXQgaXMgYmFzaWNhbGx5IENDWVktTU0tRERUaGg6bW06c3MsIGFsdGhvdWdoIGltcGxlbWVudGVycyBzaG91bGQgY29uc3VsdAotICAgICAqIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3htbHNjaGVtYS0yLyI+W1hNTCBTY2hlbWEgUGFydCAyOiBEYXRhdHlwZXNdPC9hPiBhbmQKLSAgICAgKiA8YSBocmVmPSJodHRwOi8vd3d3Lmlzby5jaC9tYXJrZXRlLzg2MDEucGRmIj5bSVNPIDg2MDFdPC9hPiBmb3IgZGV0YWlscy4KLSAgICAgKiBUaGUgZGF0ZSBpcyByZXR1cm5lZCBhcyBhIHN0cmluZyB3aXRoIGEgbGV4aWNhbCByZXByZXNlbnRhdGlvbiBhcyBkZWZpbmVkIGZvciB4czpkYXRlIGluCi0gICAgICogWzMuMi45IGRhdGVdIG9mIFtYTUwgU2NoZW1hIFBhcnQgMjogRGF0YXR5cGVzXS4gVGhlIGRhdGUgZm9ybWF0IGlzIGJhc2ljYWxseSBDQ1lZLU1NLURELAotICAgICAqIGFsdGhvdWdoIGltcGxlbWVudGVycyBzaG91bGQgY29uc3VsdCBbWE1MIFNjaGVtYSBQYXJ0IDI6IERhdGF0eXBlc10gYW5kIFtJU08gODYwMV0gZm9yIGRldGFpbHMuCi0gICAgICogSWYgbm8gYXJndW1lbnQgaXMgZ2l2ZW4gb3IgdGhlIGFyZ3VtZW50IGRhdGUvdGltZSBzcGVjaWZpZXMgYSB0aW1lIHpvbmUsIHRoZW4gdGhlIGRhdGUgc3RyaW5nCi0gICAgICogZm9ybWF0IG11c3QgaW5jbHVkZSBhIHRpbWUgem9uZSwgZWl0aGVyIGEgWiB0byBpbmRpY2F0ZSBDb29yZGluYXRlZCBVbml2ZXJzYWwgVGltZSBvciBhICsgb3IgLQotICAgICAqIGZvbGxvd2VkIGJ5IHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIGRpZmZlcmVuY2UgZnJvbSBVVEMgcmVwcmVzZW50ZWQgYXMgaGg6bW0uIElmIGFuIGFyZ3VtZW50Ci0gICAgICogaXMgc3BlY2lmaWVkIGFuZCBpdCBkb2VzIG5vdCBzcGVjaWZ5IGEgdGltZSB6b25lLCB0aGVuIHRoZSBkYXRlIHN0cmluZyBmb3JtYXQgbXVzdCBub3QgaW5jbHVkZQotICAgICAqIGEgdGltZSB6b25lLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGRhdGUoU3RyaW5nIGRhdGV0aW1lSW4pCi0gICAgICB0aHJvd3MgUGFyc2VFeGNlcHRpb24KLSAgICB7Ci0gICAgICBTdHJpbmdbXSBlZHogPSBnZXRFcmFEYXRldGltZVpvbmUoZGF0ZXRpbWVJbik7Ci0gICAgICBTdHJpbmcgbGVhZGVyID0gZWR6WzBdOwotICAgICAgU3RyaW5nIGRhdGV0aW1lID0gZWR6WzFdOwotICAgICAgU3RyaW5nIHpvbmUgPSBlZHpbMl07Ci0gICAgICBpZiAoZGF0ZXRpbWUgPT0gbnVsbCB8fCB6b25lID09IG51bGwpCi0gICAgICAgIHJldHVybiBFTVBUWV9TVFI7Ci0KLSAgICAgIFN0cmluZ1tdIGZvcm1hdHNJbiA9IHtkdCwgZH07Ci0gICAgICBTdHJpbmcgZm9ybWF0T3V0ID0gZDsKLSAgICAgIERhdGUgZGF0ZSA9IHRlc3RGb3JtYXRzKGRhdGV0aW1lLCBmb3JtYXRzSW4pOwotICAgICAgaWYgKGRhdGUgPT0gbnVsbCkgcmV0dXJuIEVNUFRZX1NUUjsKLQotICAgICAgU2ltcGxlRGF0ZUZvcm1hdCBkYXRlRm9ybWF0ID0gbmV3IFNpbXBsZURhdGVGb3JtYXQoZm9ybWF0T3V0KTsKLSAgICAgIGRhdGVGb3JtYXQuc2V0TGVuaWVudChmYWxzZSk7Ci0gICAgICBTdHJpbmcgZGF0ZU91dCA9IGRhdGVGb3JtYXQuZm9ybWF0KGRhdGUpOwotICAgICAgaWYgKGRhdGVPdXQubGVuZ3RoKCkgPT0gMCkKLSAgICAgICAgICByZXR1cm4gRU1QVFlfU1RSOwotICAgICAgZWxzZQotICAgICAgICByZXR1cm4gKGxlYWRlciArIGRhdGVPdXQgKyB6b25lKTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFNlZSBhYm92ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBkYXRlKCkKLSAgICB7Ci0gICAgICBTdHJpbmcgZGF0ZXRpbWUgPSBkYXRlVGltZSgpLnRvU3RyaW5nKCk7Ci0gICAgICBTdHJpbmcgZGF0ZSA9IGRhdGV0aW1lLnN1YnN0cmluZygwLCBkYXRldGltZS5pbmRleE9mKCJUIikpOwotICAgICAgU3RyaW5nIHpvbmUgPSBkYXRldGltZS5zdWJzdHJpbmcoZ2V0Wm9uZVN0YXJ0KGRhdGV0aW1lKSk7Ci0gICAgICByZXR1cm4gKGRhdGUgKyB6b25lKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgZGF0ZTp0aW1lIGZ1bmN0aW9uIHJldHVybnMgdGhlIHRpbWUgc3BlY2lmaWVkIGluIHRoZSBkYXRlL3RpbWUgc3RyaW5nIGdpdmVuCi0gICAgICogYXMgdGhlIGFyZ3VtZW50LiBJZiBubyBhcmd1bWVudCBpcyBnaXZlbiwgdGhlbiB0aGUgY3VycmVudCBsb2NhbCBkYXRlL3RpbWUsIGFzCi0gICAgICogcmV0dXJuZWQgYnkgZGF0ZTpkYXRlLXRpbWUgaXMgdXNlZCBhcyBhIGRlZmF1bHQgYXJndW1lbnQuCi0gICAgICogVGhlIGRhdGUvdGltZSBzdHJpbmcgdGhhdCdzIHJldHVybmVkIG11c3QgYmUgYSBzdHJpbmcgaW4gdGhlIGZvcm1hdCBkZWZpbmVkIGFzIHRoZQotICAgICAqIGxleGljYWwgcmVwcmVzZW50YXRpb24gb2YgeHM6ZGF0ZVRpbWUgaW4KLSAgICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94bWxzY2hlbWEtMi8jZGF0ZVRpbWUiPlszLjIuNyBkYXRlVGltZV08L2E+IG9mCi0gICAgICogPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveG1sc2NoZW1hLTIvIj5bWE1MIFNjaGVtYSBQYXJ0IDI6IERhdGF0eXBlc108L2E+LgotICAgICAqIElmIHRoZSBhcmd1bWVudCBzdHJpbmcgaXMgbm90IGluIHRoaXMgZm9ybWF0LCBkYXRlOnRpbWUgcmV0dXJucyBhbiBlbXB0eSBzdHJpbmcgKCcnKS4KLSAgICAgKiBUaGUgZGF0ZS90aW1lIGZvcm1hdCBpcyBiYXNpY2FsbHkgQ0NZWS1NTS1ERFRoaDptbTpzcywgYWx0aG91Z2ggaW1wbGVtZW50ZXJzIHNob3VsZCBjb25zdWx0Ci0gICAgICogPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveG1sc2NoZW1hLTIvIj5bWE1MIFNjaGVtYSBQYXJ0IDI6IERhdGF0eXBlc108L2E+IGFuZAotICAgICAqIDxhIGhyZWY9Imh0dHA6Ly93d3cuaXNvLmNoL21hcmtldGUvODYwMS5wZGYiPltJU08gODYwMV08L2E+IGZvciBkZXRhaWxzLgotICAgICAqIFRoZSBkYXRlIGlzIHJldHVybmVkIGFzIGEgc3RyaW5nIHdpdGggYSBsZXhpY2FsIHJlcHJlc2VudGF0aW9uIGFzIGRlZmluZWQgZm9yIHhzOnRpbWUgaW4KLSAgICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94bWxzY2hlbWEtMi8jdGltZSI+WzMuMi44IHRpbWVdPC9hPiBvZiBbWE1MIFNjaGVtYSBQYXJ0IDI6IERhdGF0eXBlc10uCi0gICAgICogVGhlIHRpbWUgZm9ybWF0IGlzIGJhc2ljYWxseSBoaDptbTpzcywgYWx0aG91Z2ggaW1wbGVtZW50ZXJzIHNob3VsZCBjb25zdWx0IFtYTUwgU2NoZW1hIFBhcnQgMjoKLSAgICAgKiBEYXRhdHlwZXNdIGFuZCBbSVNPIDg2MDFdIGZvciBkZXRhaWxzLgotICAgICAqIElmIG5vIGFyZ3VtZW50IGlzIGdpdmVuIG9yIHRoZSBhcmd1bWVudCBkYXRlL3RpbWUgc3BlY2lmaWVzIGEgdGltZSB6b25lLCB0aGVuIHRoZSB0aW1lIHN0cmluZwotICAgICAqIGZvcm1hdCBtdXN0IGluY2x1ZGUgYSB0aW1lIHpvbmUsIGVpdGhlciBhIFogdG8gaW5kaWNhdGUgQ29vcmRpbmF0ZWQgVW5pdmVyc2FsIFRpbWUgb3IgYSArIG9yIC0KLSAgICAgKiBmb2xsb3dlZCBieSB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSBkaWZmZXJlbmNlIGZyb20gVVRDIHJlcHJlc2VudGVkIGFzIGhoOm1tLiBJZiBhbiBhcmd1bWVudAotICAgICAqIGlzIHNwZWNpZmllZCBhbmQgaXQgZG9lcyBub3Qgc3BlY2lmeSBhIHRpbWUgem9uZSwgdGhlbiB0aGUgdGltZSBzdHJpbmcgZm9ybWF0IG11c3Qgbm90IGluY2x1ZGUKLSAgICAgKiBhIHRpbWUgem9uZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFN0cmluZyB0aW1lKFN0cmluZyB0aW1lSW4pCi0gICAgICB0aHJvd3MgUGFyc2VFeGNlcHRpb24KLSAgICB7Ci0gICAgICBTdHJpbmdbXSBlZHogPSBnZXRFcmFEYXRldGltZVpvbmUodGltZUluKTsKLSAgICAgIFN0cmluZyB0aW1lID0gZWR6WzFdOwotICAgICAgU3RyaW5nIHpvbmUgPSBlZHpbMl07Ci0gICAgICBpZiAodGltZSA9PSBudWxsIHx8IHpvbmUgPT0gbnVsbCkKLSAgICAgICAgcmV0dXJuIEVNUFRZX1NUUjsKLQotICAgICAgU3RyaW5nW10gZm9ybWF0c0luID0ge2R0LCBkLCB0fTsKLSAgICAgIFN0cmluZyBmb3JtYXRPdXQgPSAgdDsKLSAgICAgIERhdGUgZGF0ZSA9IHRlc3RGb3JtYXRzKHRpbWUsIGZvcm1hdHNJbik7Ci0gICAgICBpZiAoZGF0ZSA9PSBudWxsKSByZXR1cm4gRU1QVFlfU1RSOwotICAgICAgU2ltcGxlRGF0ZUZvcm1hdCBkYXRlRm9ybWF0ID0gbmV3IFNpbXBsZURhdGVGb3JtYXQoZm9ybWF0T3V0KTsKLSAgICAgIFN0cmluZyBvdXQgPSBkYXRlRm9ybWF0LmZvcm1hdChkYXRlKTsKLSAgICAgIHJldHVybiAob3V0ICsgem9uZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2VlIGFib3ZlLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHRpbWUoKQotICAgIHsKLSAgICAgIFN0cmluZyBkYXRldGltZSA9IGRhdGVUaW1lKCkudG9TdHJpbmcoKTsKLSAgICAgIFN0cmluZyB0aW1lID0gZGF0ZXRpbWUuc3Vic3RyaW5nKGRhdGV0aW1lLmluZGV4T2YoIlQiKSsxKTsKLQotICAgICAgICAgIC8vIFRoZSBkYXRldGltZSgpIGZ1bmN0aW9uIHJldHVybnMgdGhlIHpvbmUgb24gdGhlIGRhdGV0aW1lIHN0cmluZy4gIElmIHdlCi0gICAgICAgICAgLy8gYXBwZW5kIGl0LCB3ZSBnZXQgdGhlIHpvbmUgc3Vic3RyaW5nIGR1cGxpY2F0ZWQuCi0gICAgICAgICAgLy8gRml4IGZvciBKSVJBIDIwMTMKLQotICAgICAgLy8gU3RyaW5nIHpvbmUgPSBkYXRldGltZS5zdWJzdHJpbmcoZ2V0Wm9uZVN0YXJ0KGRhdGV0aW1lKSk7Ci0gICAgICAvLyByZXR1cm4gKHRpbWUgKyB6b25lKTsKLSAgICAgIHJldHVybiAodGltZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhlIGRhdGU6eWVhciBmdW5jdGlvbiByZXR1cm5zIHRoZSB5ZWFyIG9mIGEgZGF0ZSBhcyBhIG51bWJlci4gSWYgbm8KLSAgICAgKiBhcmd1bWVudCBpcyBnaXZlbiwgdGhlbiB0aGUgY3VycmVudCBsb2NhbCBkYXRlL3RpbWUsIGFzIHJldHVybmVkIGJ5Ci0gICAgICogZGF0ZTpkYXRlLXRpbWUgaXMgdXNlZCBhcyBhIGRlZmF1bHQgYXJndW1lbnQuCi0gICAgICogVGhlIGRhdGUvdGltZSBzdHJpbmcgc3BlY2lmaWVkIGFzIHRoZSBmaXJzdCBhcmd1bWVudCBtdXN0IGJlIGEgcmlnaHQtdHJ1bmNhdGVkCi0gICAgICogc3RyaW5nIGluIHRoZSBmb3JtYXQgZGVmaW5lZCBhcyB0aGUgbGV4aWNhbCByZXByZXNlbnRhdGlvbiBvZiB4czpkYXRlVGltZSBpbiBvbmUKLSAgICAgKiBvZiB0aGUgZm9ybWF0cyBkZWZpbmVkIGluCi0gICAgICogPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveG1sc2NoZW1hLTIvIj5bWE1MIFNjaGVtYSBQYXJ0IDI6IERhdGF0eXBlc108L2E+LgotICAgICAqIFRoZSBwZXJtaXR0ZWQgZm9ybWF0cyBhcmUgYXMgZm9sbG93czoKLSAgICAgKiAgIHhzOmRhdGVUaW1lIChDQ1lZLU1NLUREVGhoOm1tOnNzKQotICAgICAqICAgeHM6ZGF0ZSAoQ0NZWS1NTS1ERCkKLSAgICAgKiAgIHhzOmdZZWFyTW9udGggKENDWVktTU0pCi0gICAgICogICB4czpnWWVhciAoQ0NZWSkKLSAgICAgKiBJZiB0aGUgZGF0ZS90aW1lIHN0cmluZyBpcyBub3QgaW4gb25lIG9mIHRoZXNlIGZvcm1hdHMsIHRoZW4gTmFOIGlzIHJldHVybmVkLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZG91YmxlIHllYXIoU3RyaW5nIGRhdGV0aW1lSW4pCi0gICAgICB0aHJvd3MgUGFyc2VFeGNlcHRpb24KLSAgICB7Ci0gICAgICBTdHJpbmdbXSBlZHogPSBnZXRFcmFEYXRldGltZVpvbmUoZGF0ZXRpbWVJbik7Ci0gICAgICBib29sZWFuIGFkID0gZWR6WzBdLmxlbmd0aCgpID09IDA7IC8vIEFEIChDb21tb24gRXJhIC0tIGVtcHR5IGxlYWRlcikKLSAgICAgIFN0cmluZyBkYXRldGltZSA9IGVkelsxXTsKLSAgICAgIGlmIChkYXRldGltZSA9PSBudWxsKQotICAgICAgICByZXR1cm4gRG91YmxlLk5hTjsKLQotICAgICAgU3RyaW5nW10gZm9ybWF0cyA9IHtkdCwgZCwgZ3ltLCBneX07Ci0gICAgICBkb3VibGUgeXIgPSBnZXROdW1iZXIoZGF0ZXRpbWUsIGZvcm1hdHMsIENhbGVuZGFyLllFQVIpOwotICAgICAgaWYgKGFkIHx8IHlyID09IERvdWJsZS5OYU4pCi0gICAgICAgIHJldHVybiB5cjsKLSAgICAgIGVsc2UKLSAgICAgICAgcmV0dXJuIC15cjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZWUgYWJvdmUuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBkb3VibGUgeWVhcigpCi0gICAgewotICAgICAgQ2FsZW5kYXIgY2FsID0gQ2FsZW5kYXIuZ2V0SW5zdGFuY2UoKTsKLSAgICAgIHJldHVybiBjYWwuZ2V0KENhbGVuZGFyLllFQVIpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoZSBkYXRlOm1vbnRoLWluLXllYXIgZnVuY3Rpb24gcmV0dXJucyB0aGUgbW9udGggb2YgYSBkYXRlIGFzIGEgbnVtYmVyLiBJZiBubyBhcmd1bWVudAotICAgICAqIGlzIGdpdmVuLCB0aGVuIHRoZSBjdXJyZW50IGxvY2FsIGRhdGUvdGltZSwgYXMgcmV0dXJuZWQgYnkgZGF0ZTpkYXRlLXRpbWUgaXMgdXNlZAotICAgICAqIGFzIGEgZGVmYXVsdCBhcmd1bWVudC4KLSAgICAgKiBUaGUgZGF0ZS90aW1lIHN0cmluZyBzcGVjaWZpZWQgYXMgdGhlIGZpcnN0IGFyZ3VtZW50IGlzIGEgbGVmdCBvciByaWdodC10cnVuY2F0ZWQKLSAgICAgKiBzdHJpbmcgaW4gdGhlIGZvcm1hdCBkZWZpbmVkIGFzIHRoZSBsZXhpY2FsIHJlcHJlc2VudGF0aW9uIG9mIHhzOmRhdGVUaW1lIGluIG9uZSBvZgotICAgICAqIHRoZSBmb3JtYXRzIGRlZmluZWQgaW4KLSAgICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94bWxzY2hlbWEtMi8iPltYTUwgU2NoZW1hIFBhcnQgMjogRGF0YXR5cGVzXTwvYT4uCi0gICAgICogVGhlIHBlcm1pdHRlZCBmb3JtYXRzIGFyZSBhcyBmb2xsb3dzOgotICAgICAqICAgIHhzOmRhdGVUaW1lIChDQ1lZLU1NLUREVGhoOm1tOnNzKQotICAgICAqICAgIHhzOmRhdGUgKENDWVktTU0tREQpCi0gICAgICogICAgeHM6Z1llYXJNb250aCAoQ0NZWS1NTSkKLSAgICAgKiAgICB4czpnTW9udGggKC0tTU0tLSkKLSAgICAgKiAgICB4czpnTW9udGhEYXkgKC0tTU0tREQpCi0gICAgICogSWYgdGhlIGRhdGUvdGltZSBzdHJpbmcgaXMgbm90IGluIG9uZSBvZiB0aGVzZSBmb3JtYXRzLCB0aGVuIE5hTiBpcyByZXR1cm5lZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGRvdWJsZSBtb250aEluWWVhcihTdHJpbmcgZGF0ZXRpbWVJbikKLSAgICAgIHRocm93cyBQYXJzZUV4Y2VwdGlvbgotICAgIHsKLSAgICAgIFN0cmluZ1tdIGVkeiA9IGdldEVyYURhdGV0aW1lWm9uZShkYXRldGltZUluKTsKLSAgICAgIFN0cmluZyBkYXRldGltZSA9IGVkelsxXTsKLSAgICAgIGlmIChkYXRldGltZSA9PSBudWxsKQotICAgICAgICByZXR1cm4gRG91YmxlLk5hTjsKLQotICAgICAgU3RyaW5nW10gZm9ybWF0cyA9IHtkdCwgZCwgZ3ltLCBnbSwgZ21kfTsKLSAgICAgIHJldHVybiBnZXROdW1iZXIoZGF0ZXRpbWUsIGZvcm1hdHMsIENhbGVuZGFyLk1PTlRIKSArIDE7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2VlIGFib3ZlLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZG91YmxlIG1vbnRoSW5ZZWFyKCkKLSAgICB7Ci0gICAgICBDYWxlbmRhciBjYWwgPSBDYWxlbmRhci5nZXRJbnN0YW5jZSgpOwotICAgICAgcmV0dXJuIGNhbC5nZXQoQ2FsZW5kYXIuTU9OVEgpICsgMTsKLSAgIH0KLQotICAgIC8qKgotICAgICAqIFRoZSBkYXRlOndlZWstaW4teWVhciBmdW5jdGlvbiByZXR1cm5zIHRoZSB3ZWVrIG9mIHRoZSB5ZWFyIGFzIGEgbnVtYmVyLiBJZiBubyBhcmd1bWVudAotICAgICAqIGlzIGdpdmVuLCB0aGVuIHRoZSBjdXJyZW50IGxvY2FsIGRhdGUvdGltZSwgYXMgcmV0dXJuZWQgYnkgZGF0ZTpkYXRlLXRpbWUgaXMgdXNlZCBhcyB0aGUKLSAgICAgKiBkZWZhdWx0IGFyZ3VtZW50LiBGb3IgdGhlIHB1cnBvc2VzIG9mIG51bWJlcmluZywgY291bnRpbmcgZm9sbG93cyBJU08gODYwMTogd2VlayAxIGluIGEgeWVhcgotICAgICAqIGlzIHRoZSB3ZWVrIGNvbnRhaW5pbmcgdGhlIGZpcnN0IFRodXJzZGF5IG9mIHRoZSB5ZWFyLCB3aXRoIG5ldyB3ZWVrcyBiZWdpbm5pbmcgb24gYSBNb25kYXkuCi0gICAgICogVGhlIGRhdGUvdGltZSBzdHJpbmcgc3BlY2lmaWVkIGFzIHRoZSBhcmd1bWVudCBpcyBhIHJpZ2h0LXRydW5jYXRlZCBzdHJpbmcgaW4gdGhlIGZvcm1hdAotICAgICAqIGRlZmluZWQgYXMgdGhlIGxleGljYWwgcmVwcmVzZW50YXRpb24gb2YgeHM6ZGF0ZVRpbWUgaW4gb25lIG9mIHRoZSBmb3JtYXRzIGRlZmluZWQgaW4KLSAgICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94bWxzY2hlbWEtMi8iPltYTUwgU2NoZW1hIFBhcnQgMjogRGF0YXR5cGVzXTwvYT4uIFRoZQotICAgICAqIHBlcm1pdHRlZCBmb3JtYXRzIGFyZSBhcyBmb2xsb3dzOgotICAgICAqICAgIHhzOmRhdGVUaW1lIChDQ1lZLU1NLUREVGhoOm1tOnNzKQotICAgICAqICAgIHhzOmRhdGUgKENDWVktTU0tREQpCi0gICAgICogSWYgdGhlIGRhdGUvdGltZSBzdHJpbmcgaXMgbm90IGluIG9uZSBvZiB0aGVzZSBmb3JtYXRzLCB0aGVuIE5hTiBpcyByZXR1cm5lZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGRvdWJsZSB3ZWVrSW5ZZWFyKFN0cmluZyBkYXRldGltZUluKQotICAgICAgdGhyb3dzIFBhcnNlRXhjZXB0aW9uCi0gICAgewotICAgICAgU3RyaW5nW10gZWR6ID0gZ2V0RXJhRGF0ZXRpbWVab25lKGRhdGV0aW1lSW4pOwotICAgICAgU3RyaW5nIGRhdGV0aW1lID0gZWR6WzFdOwotICAgICAgaWYgKGRhdGV0aW1lID09IG51bGwpCi0gICAgICAgIHJldHVybiBEb3VibGUuTmFOOwotCi0gICAgICBTdHJpbmdbXSBmb3JtYXRzID0ge2R0LCBkfTsKLSAgICAgIHJldHVybiBnZXROdW1iZXIoZGF0ZXRpbWUsIGZvcm1hdHMsIENhbGVuZGFyLldFRUtfT0ZfWUVBUik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2VlIGFib3ZlLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZG91YmxlIHdlZWtJblllYXIoKQotICAgIHsKLSAgICAgICBDYWxlbmRhciBjYWwgPSBDYWxlbmRhci5nZXRJbnN0YW5jZSgpOwotICAgICAgcmV0dXJuIGNhbC5nZXQoQ2FsZW5kYXIuV0VFS19PRl9ZRUFSKTsKLSAgIH0KLQotICAgIC8qKgotICAgICAqIFRoZSBkYXRlOmRheS1pbi15ZWFyIGZ1bmN0aW9uIHJldHVybnMgdGhlIGRheSBvZiBhIGRhdGUgaW4gYSB5ZWFyCi0gICAgICogYXMgYSBudW1iZXIuIElmIG5vIGFyZ3VtZW50IGlzIGdpdmVuLCB0aGVuIHRoZSBjdXJyZW50IGxvY2FsCi0gICAgICogZGF0ZS90aW1lLCBhcyByZXR1cm5lZCBieSBkYXRlOmRhdGUtdGltZSBpcyB1c2VkIHRoZSBkZWZhdWx0IGFyZ3VtZW50LgotICAgICAqIFRoZSBkYXRlL3RpbWUgc3RyaW5nIHNwZWNpZmllZCBhcyB0aGUgYXJndW1lbnQgaXMgYSByaWdodC10cnVuY2F0ZWQKLSAgICAgKiBzdHJpbmcgaW4gdGhlIGZvcm1hdCBkZWZpbmVkIGFzIHRoZSBsZXhpY2FsIHJlcHJlc2VudGF0aW9uIG9mIHhzOmRhdGVUaW1lCi0gICAgICogaW4gb25lIG9mIHRoZSBmb3JtYXRzIGRlZmluZWQgaW4KLSAgICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94bWxzY2hlbWEtMi8iPltYTUwgU2NoZW1hIFBhcnQgMjogRGF0YXR5cGVzXTwvYT4uCi0gICAgICogVGhlIHBlcm1pdHRlZCBmb3JtYXRzIGFyZSBhcyBmb2xsb3dzOgotICAgICAqICAgICB4czpkYXRlVGltZSAoQ0NZWS1NTS1ERFRoaDptbTpzcykKLSAgICAgKiAgICAgeHM6ZGF0ZSAoQ0NZWS1NTS1ERCkKLSAgICAgKiBJZiB0aGUgZGF0ZS90aW1lIHN0cmluZyBpcyBub3QgaW4gb25lIG9mIHRoZXNlIGZvcm1hdHMsIHRoZW4gTmFOIGlzIHJldHVybmVkLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZG91YmxlIGRheUluWWVhcihTdHJpbmcgZGF0ZXRpbWVJbikKLSAgICAgIHRocm93cyBQYXJzZUV4Y2VwdGlvbgotICAgIHsKLSAgICAgIFN0cmluZ1tdIGVkeiA9IGdldEVyYURhdGV0aW1lWm9uZShkYXRldGltZUluKTsKLSAgICAgIFN0cmluZyBkYXRldGltZSA9IGVkelsxXTsKLSAgICAgIGlmIChkYXRldGltZSA9PSBudWxsKQotICAgICAgICByZXR1cm4gRG91YmxlLk5hTjsKLQotICAgICAgU3RyaW5nW10gZm9ybWF0cyA9IHtkdCwgZH07Ci0gICAgICByZXR1cm4gZ2V0TnVtYmVyKGRhdGV0aW1lLCBmb3JtYXRzLCBDYWxlbmRhci5EQVlfT0ZfWUVBUik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2VlIGFib3ZlLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZG91YmxlIGRheUluWWVhcigpCi0gICAgewotICAgICAgIENhbGVuZGFyIGNhbCA9IENhbGVuZGFyLmdldEluc3RhbmNlKCk7Ci0gICAgICByZXR1cm4gY2FsLmdldChDYWxlbmRhci5EQVlfT0ZfWUVBUik7Ci0gICB9Ci0KLQotICAgIC8qKgotICAgICAqIFRoZSBkYXRlOmRheS1pbi1tb250aCBmdW5jdGlvbiByZXR1cm5zIHRoZSBkYXkgb2YgYSBkYXRlIGFzIGEgbnVtYmVyLgotICAgICAqIElmIG5vIGFyZ3VtZW50IGlzIGdpdmVuLCB0aGVuIHRoZSBjdXJyZW50IGxvY2FsIGRhdGUvdGltZSwgYXMgcmV0dXJuZWQKLSAgICAgKiBieSBkYXRlOmRhdGUtdGltZSBpcyB1c2VkIHRoZSBkZWZhdWx0IGFyZ3VtZW50LgotICAgICAqIFRoZSBkYXRlL3RpbWUgc3RyaW5nIHNwZWNpZmllZCBhcyB0aGUgYXJndW1lbnQgaXMgYSBsZWZ0IG9yIHJpZ2h0LXRydW5jYXRlZAotICAgICAqIHN0cmluZyBpbiB0aGUgZm9ybWF0IGRlZmluZWQgYXMgdGhlIGxleGljYWwgcmVwcmVzZW50YXRpb24gb2YgeHM6ZGF0ZVRpbWUKLSAgICAgKiBpbiBvbmUgb2YgdGhlIGZvcm1hdHMgZGVmaW5lZCBpbgotICAgICAqIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3htbHNjaGVtYS0yLyI+W1hNTCBTY2hlbWEgUGFydCAyOiBEYXRhdHlwZXNdPC9hPi4KLSAgICAgKiBUaGUgcGVybWl0dGVkIGZvcm1hdHMgYXJlIGFzIGZvbGxvd3M6Ci0gICAgICogICAgICB4czpkYXRlVGltZSAoQ0NZWS1NTS1ERFRoaDptbTpzcykKLSAgICAgKiAgICAgIHhzOmRhdGUgKENDWVktTU0tREQpCi0gICAgICogICAgICB4czpnTW9udGhEYXkgKC0tTU0tREQpCi0gICAgICogICAgICB4czpnRGF5ICgtLS1ERCkKLSAgICAgKiBJZiB0aGUgZGF0ZS90aW1lIHN0cmluZyBpcyBub3QgaW4gb25lIG9mIHRoZXNlIGZvcm1hdHMsIHRoZW4gTmFOIGlzIHJldHVybmVkLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZG91YmxlIGRheUluTW9udGgoU3RyaW5nIGRhdGV0aW1lSW4pCi0gICAgICB0aHJvd3MgUGFyc2VFeGNlcHRpb24KLSAgICB7Ci0gICAgICBTdHJpbmdbXSBlZHogPSBnZXRFcmFEYXRldGltZVpvbmUoZGF0ZXRpbWVJbik7Ci0gICAgICBTdHJpbmcgZGF0ZXRpbWUgPSBlZHpbMV07Ci0gICAgICBTdHJpbmdbXSBmb3JtYXRzID0ge2R0LCBkLCBnbWQsIGdkfTsKLSAgICAgIGRvdWJsZSBkYXkgPSBnZXROdW1iZXIoZGF0ZXRpbWUsIGZvcm1hdHMsIENhbGVuZGFyLkRBWV9PRl9NT05USCk7Ci0gICAgICByZXR1cm4gZGF5OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNlZSBhYm92ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGRvdWJsZSBkYXlJbk1vbnRoKCkKLSAgICB7Ci0gICAgICBDYWxlbmRhciBjYWwgPSBDYWxlbmRhci5nZXRJbnN0YW5jZSgpOwotICAgICAgcmV0dXJuIGNhbC5nZXQoQ2FsZW5kYXIuREFZX09GX01PTlRIKTsKLSAgIH0KLQotICAgIC8qKgotICAgICAqIFRoZSBkYXRlOmRheS1vZi13ZWVrLWluLW1vbnRoIGZ1bmN0aW9uIHJldHVybnMgdGhlIGRheS1vZi10aGUtd2VlawotICAgICAqIGluIGEgbW9udGggb2YgYSBkYXRlIGFzIGEgbnVtYmVyIChlLmcuIDMgZm9yIHRoZSAzcmQgVHVlc2RheSBpbiBNYXkpLgotICAgICAqIElmIG5vIGFyZ3VtZW50IGlzIGdpdmVuLCB0aGVuIHRoZSBjdXJyZW50IGxvY2FsIGRhdGUvdGltZSwgYXMgcmV0dXJuZWQKLSAgICAgKiBieSBkYXRlOmRhdGUtdGltZSBpcyB1c2VkIHRoZSBkZWZhdWx0IGFyZ3VtZW50LgotICAgICAqIFRoZSBkYXRlL3RpbWUgc3RyaW5nIHNwZWNpZmllZCBhcyB0aGUgYXJndW1lbnQgaXMgYSByaWdodC10cnVuY2F0ZWQgc3RyaW5nCi0gICAgICogaW4gdGhlIGZvcm1hdCBkZWZpbmVkIGFzIHRoZSBsZXhpY2FsIHJlcHJlc2VudGF0aW9uIG9mIHhzOmRhdGVUaW1lIGluIG9uZQotICAgICAqIG9mIHRoZSBmb3JtYXRzIGRlZmluZWQgaW4KLSAgICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94bWxzY2hlbWEtMi8iPltYTUwgU2NoZW1hIFBhcnQgMjogRGF0YXR5cGVzXTwvYT4uCi0gICAgICogVGhlIHBlcm1pdHRlZCBmb3JtYXRzIGFyZSBhcyBmb2xsb3dzOgotICAgICAqICAgICAgeHM6ZGF0ZVRpbWUgKENDWVktTU0tRERUaGg6bW06c3MpCi0gICAgICogICAgICB4czpkYXRlIChDQ1lZLU1NLUREKQotICAgICAqIElmIHRoZSBkYXRlL3RpbWUgc3RyaW5nIGlzIG5vdCBpbiBvbmUgb2YgdGhlc2UgZm9ybWF0cywgdGhlbiBOYU4gaXMgcmV0dXJuZWQuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBkb3VibGUgZGF5T2ZXZWVrSW5Nb250aChTdHJpbmcgZGF0ZXRpbWVJbikKLSAgICAgIHRocm93cyBQYXJzZUV4Y2VwdGlvbgotICAgIHsKLSAgICAgIFN0cmluZ1tdIGVkeiA9IGdldEVyYURhdGV0aW1lWm9uZShkYXRldGltZUluKTsKLSAgICAgIFN0cmluZyBkYXRldGltZSA9IGVkelsxXTsKLSAgICAgIGlmIChkYXRldGltZSA9PSBudWxsKQotICAgICAgICByZXR1cm4gRG91YmxlLk5hTjsKLQotICAgICAgU3RyaW5nW10gZm9ybWF0cyA9ICB7ZHQsIGR9OwotICAgICAgcmV0dXJuIGdldE51bWJlcihkYXRldGltZSwgZm9ybWF0cywgQ2FsZW5kYXIuREFZX09GX1dFRUtfSU5fTU9OVEgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNlZSBhYm92ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGRvdWJsZSBkYXlPZldlZWtJbk1vbnRoKCkKLSAgICB7Ci0gICAgICAgQ2FsZW5kYXIgY2FsID0gQ2FsZW5kYXIuZ2V0SW5zdGFuY2UoKTsKLSAgICAgIHJldHVybiBjYWwuZ2V0KENhbGVuZGFyLkRBWV9PRl9XRUVLX0lOX01PTlRIKTsKLSAgIH0KLQotCi0gICAgLyoqCi0gICAgICogVGhlIGRhdGU6ZGF5LWluLXdlZWsgZnVuY3Rpb24gcmV0dXJucyB0aGUgZGF5IG9mIHRoZSB3ZWVrIGdpdmVuIGluIGEKLSAgICAgKiBkYXRlIGFzIGEgbnVtYmVyLiBJZiBubyBhcmd1bWVudCBpcyBnaXZlbiwgdGhlbiB0aGUgY3VycmVudCBsb2NhbCBkYXRlL3RpbWUsCi0gICAgICogYXMgcmV0dXJuZWQgYnkgZGF0ZTpkYXRlLXRpbWUgaXMgdXNlZCB0aGUgZGVmYXVsdCBhcmd1bWVudC4KLSAgICAgKiBUaGUgZGF0ZS90aW1lIHN0cmluZyBzcGVjaWZpZWQgYXMgdGhlIGFyZ3VtZW50IGlzIGEgcmlnaHQtdHJ1bmNhdGVkIHN0cmluZwotICAgICAqIGluIHRoZSBmb3JtYXQgZGVmaW5lZCBhcyB0aGUgbGV4aWNhbCByZXByZXNlbnRhdGlvbiBvZiB4czpkYXRlVGltZSBpbiBvbmUKLSAgICAgKiBvZiB0aGUgZm9ybWF0cyBkZWZpbmVkIGluCi0gICAgICogPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveG1sc2NoZW1hLTIvIj5bWE1MIFNjaGVtYSBQYXJ0IDI6IERhdGF0eXBlc108L2E+LgotICAgICAqIFRoZSBwZXJtaXR0ZWQgZm9ybWF0cyBhcmUgYXMgZm9sbG93czoKLSAgICAgKiAgICAgIHhzOmRhdGVUaW1lIChDQ1lZLU1NLUREVGhoOm1tOnNzKQotICAgICAqICAgICAgeHM6ZGF0ZSAoQ0NZWS1NTS1ERCkKLSAgICAgKiBJZiB0aGUgZGF0ZS90aW1lIHN0cmluZyBpcyBub3QgaW4gb25lIG9mIHRoZXNlIGZvcm1hdHMsIHRoZW4gTmFOIGlzIHJldHVybmVkLgotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRoZSBudW1iZXJpbmcgb2YgZGF5cyBvZiB0aGUgd2VlayBzdGFydHMgYXQgMSBmb3IgU3VuZGF5LCAyIGZvciBNb25kYXkgYW5kIHNvIG9uIHVwIHRvIDcgZm9yIFNhdHVyZGF5LgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZG91YmxlIGRheUluV2VlayhTdHJpbmcgZGF0ZXRpbWVJbikKLSAgICAgIHRocm93cyBQYXJzZUV4Y2VwdGlvbgotICAgIHsKLSAgICAgIFN0cmluZ1tdIGVkeiA9IGdldEVyYURhdGV0aW1lWm9uZShkYXRldGltZUluKTsKLSAgICAgIFN0cmluZyBkYXRldGltZSA9IGVkelsxXTsKLSAgICAgIGlmIChkYXRldGltZSA9PSBudWxsKQotICAgICAgICByZXR1cm4gRG91YmxlLk5hTjsKLQotICAgICAgU3RyaW5nW10gZm9ybWF0cyA9IHtkdCwgZH07Ci0gICAgICByZXR1cm4gZ2V0TnVtYmVyKGRhdGV0aW1lLCBmb3JtYXRzLCBDYWxlbmRhci5EQVlfT0ZfV0VFSyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2VlIGFib3ZlLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZG91YmxlIGRheUluV2VlaygpCi0gICAgewotICAgICAgIENhbGVuZGFyIGNhbCA9IENhbGVuZGFyLmdldEluc3RhbmNlKCk7Ci0gICAgICByZXR1cm4gY2FsLmdldChDYWxlbmRhci5EQVlfT0ZfV0VFSyk7Ci0gICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgZGF0ZTpob3VyLWluLWRheSBmdW5jdGlvbiByZXR1cm5zIHRoZSBob3VyIG9mIHRoZSBkYXkgYXMgYSBudW1iZXIuCi0gICAgICogSWYgbm8gYXJndW1lbnQgaXMgZ2l2ZW4sIHRoZW4gdGhlIGN1cnJlbnQgbG9jYWwgZGF0ZS90aW1lLCBhcyByZXR1cm5lZAotICAgICAqIGJ5IGRhdGU6ZGF0ZS10aW1lIGlzIHVzZWQgdGhlIGRlZmF1bHQgYXJndW1lbnQuCi0gICAgICogVGhlIGRhdGUvdGltZSBzdHJpbmcgc3BlY2lmaWVkIGFzIHRoZSBhcmd1bWVudCBpcyBhIHJpZ2h0LXRydW5jYXRlZAotICAgICAqIHN0cmluZyAgaW4gdGhlIGZvcm1hdCBkZWZpbmVkIGFzIHRoZSBsZXhpY2FsIHJlcHJlc2VudGF0aW9uIG9mIHhzOmRhdGVUaW1lCi0gICAgICogaW4gb25lIG9mIHRoZSBmb3JtYXRzIGRlZmluZWQgaW4KLSAgICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94bWxzY2hlbWEtMi8iPltYTUwgU2NoZW1hIFBhcnQgMjogRGF0YXR5cGVzXTwvYT4uCi0gICAgICogVGhlIHBlcm1pdHRlZCBmb3JtYXRzIGFyZSBhcyBmb2xsb3dzOgotICAgICAqICAgICB4czpkYXRlVGltZSAoQ0NZWS1NTS1ERFRoaDptbTpzcykKLSAgICAgKiAgICAgeHM6dGltZSAoaGg6bW06c3MpCi0gICAgICogSWYgdGhlIGRhdGUvdGltZSBzdHJpbmcgaXMgbm90IGluIG9uZSBvZiB0aGVzZSBmb3JtYXRzLCB0aGVuIE5hTiBpcyByZXR1cm5lZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGRvdWJsZSBob3VySW5EYXkoU3RyaW5nIGRhdGV0aW1lSW4pCi0gICAgICB0aHJvd3MgUGFyc2VFeGNlcHRpb24KLSAgICB7Ci0gICAgICBTdHJpbmdbXSBlZHogPSBnZXRFcmFEYXRldGltZVpvbmUoZGF0ZXRpbWVJbik7Ci0gICAgICBTdHJpbmcgZGF0ZXRpbWUgPSBlZHpbMV07Ci0gICAgICBpZiAoZGF0ZXRpbWUgPT0gbnVsbCkKLSAgICAgICAgcmV0dXJuIERvdWJsZS5OYU47Ci0KLSAgICAgIFN0cmluZ1tdIGZvcm1hdHMgPSB7ZHQsIHR9OwotICAgICAgcmV0dXJuIGdldE51bWJlcihkYXRldGltZSwgZm9ybWF0cywgQ2FsZW5kYXIuSE9VUl9PRl9EQVkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNlZSBhYm92ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGRvdWJsZSBob3VySW5EYXkoKQotICAgIHsKLSAgICAgICBDYWxlbmRhciBjYWwgPSBDYWxlbmRhci5nZXRJbnN0YW5jZSgpOwotICAgICAgcmV0dXJuIGNhbC5nZXQoQ2FsZW5kYXIuSE9VUl9PRl9EQVkpOwotICAgfQotCi0gICAgLyoqCi0gICAgICogVGhlIGRhdGU6bWludXRlLWluLWhvdXIgZnVuY3Rpb24gcmV0dXJucyB0aGUgbWludXRlIG9mIHRoZSBob3VyCi0gICAgICogYXMgYSBudW1iZXIuIElmIG5vIGFyZ3VtZW50IGlzIGdpdmVuLCB0aGVuIHRoZSBjdXJyZW50IGxvY2FsCi0gICAgICogZGF0ZS90aW1lLCBhcyByZXR1cm5lZCBieSBkYXRlOmRhdGUtdGltZSBpcyB1c2VkIHRoZSBkZWZhdWx0IGFyZ3VtZW50LgotICAgICAqIFRoZSBkYXRlL3RpbWUgc3RyaW5nIHNwZWNpZmllZCBhcyB0aGUgYXJndW1lbnQgaXMgYSByaWdodC10cnVuY2F0ZWQKLSAgICAgKiBzdHJpbmcgaW4gdGhlIGZvcm1hdCBkZWZpbmVkIGFzIHRoZSBsZXhpY2FsIHJlcHJlc2VudGF0aW9uIG9mIHhzOmRhdGVUaW1lCi0gICAgICogaW4gb25lIG9mIHRoZSBmb3JtYXRzIGRlZmluZWQgaW4KLSAgICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94bWxzY2hlbWEtMi8iPltYTUwgU2NoZW1hIFBhcnQgMjogRGF0YXR5cGVzXTwvYT4uCi0gICAgICogVGhlIHBlcm1pdHRlZCBmb3JtYXRzIGFyZSBhcyBmb2xsb3dzOgotICAgICAqICAgICAgeHM6ZGF0ZVRpbWUgKENDWVktTU0tRERUaGg6bW06c3MpCi0gICAgICogICAgICB4czp0aW1lIChoaDptbTpzcykKLSAgICAgKiBJZiB0aGUgZGF0ZS90aW1lIHN0cmluZyBpcyBub3QgaW4gb25lIG9mIHRoZXNlIGZvcm1hdHMsIHRoZW4gTmFOIGlzIHJldHVybmVkLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZG91YmxlIG1pbnV0ZUluSG91cihTdHJpbmcgZGF0ZXRpbWVJbikKLSAgICAgIHRocm93cyBQYXJzZUV4Y2VwdGlvbgotICAgIHsKLSAgICAgIFN0cmluZ1tdIGVkeiA9IGdldEVyYURhdGV0aW1lWm9uZShkYXRldGltZUluKTsKLSAgICAgIFN0cmluZyBkYXRldGltZSA9IGVkelsxXTsKLSAgICAgIGlmIChkYXRldGltZSA9PSBudWxsKQotICAgICAgICByZXR1cm4gRG91YmxlLk5hTjsKLQotICAgICAgU3RyaW5nW10gZm9ybWF0cyA9IHtkdCx0fTsKLSAgICAgIHJldHVybiBnZXROdW1iZXIoZGF0ZXRpbWUsIGZvcm1hdHMsIENhbGVuZGFyLk1JTlVURSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2VlIGFib3ZlLgotICAgICAqLwotICAgcHVibGljIHN0YXRpYyBkb3VibGUgbWludXRlSW5Ib3VyKCkKLSAgICB7Ci0gICAgICAgQ2FsZW5kYXIgY2FsID0gQ2FsZW5kYXIuZ2V0SW5zdGFuY2UoKTsKLSAgICAgIHJldHVybiBjYWwuZ2V0KENhbGVuZGFyLk1JTlVURSk7Ci0gICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgZGF0ZTpzZWNvbmQtaW4tbWludXRlIGZ1bmN0aW9uIHJldHVybnMgdGhlIHNlY29uZCBvZiB0aGUgbWludXRlCi0gICAgICogYXMgYSBudW1iZXIuIElmIG5vIGFyZ3VtZW50IGlzIGdpdmVuLCB0aGVuIHRoZSBjdXJyZW50IGxvY2FsCi0gICAgICogZGF0ZS90aW1lLCBhcyByZXR1cm5lZCBieSBkYXRlOmRhdGUtdGltZSBpcyB1c2VkIHRoZSBkZWZhdWx0IGFyZ3VtZW50LgotICAgICAqIFRoZSBkYXRlL3RpbWUgc3RyaW5nIHNwZWNpZmllZCBhcyB0aGUgYXJndW1lbnQgaXMgYSByaWdodC10cnVuY2F0ZWQKLSAgICAgKiBzdHJpbmcgaW4gdGhlIGZvcm1hdCBkZWZpbmVkIGFzIHRoZSBsZXhpY2FsIHJlcHJlc2VudGF0aW9uIG9mIHhzOmRhdGVUaW1lCi0gICAgICogaW4gb25lIG9mIHRoZSBmb3JtYXRzIGRlZmluZWQgaW4KLSAgICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94bWxzY2hlbWEtMi8iPltYTUwgU2NoZW1hIFBhcnQgMjogRGF0YXR5cGVzXTwvYT4uCi0gICAgICogVGhlIHBlcm1pdHRlZCBmb3JtYXRzIGFyZSBhcyBmb2xsb3dzOgotICAgICAqICAgICAgeHM6ZGF0ZVRpbWUgKENDWVktTU0tRERUaGg6bW06c3MpCi0gICAgICogICAgICB4czp0aW1lIChoaDptbTpzcykKLSAgICAgKiBJZiB0aGUgZGF0ZS90aW1lIHN0cmluZyBpcyBub3QgaW4gb25lIG9mIHRoZXNlIGZvcm1hdHMsIHRoZW4gTmFOIGlzIHJldHVybmVkLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZG91YmxlIHNlY29uZEluTWludXRlKFN0cmluZyBkYXRldGltZUluKQotICAgICAgdGhyb3dzIFBhcnNlRXhjZXB0aW9uCi0gICAgewotICAgICAgU3RyaW5nW10gZWR6ID0gZ2V0RXJhRGF0ZXRpbWVab25lKGRhdGV0aW1lSW4pOwotICAgICAgU3RyaW5nIGRhdGV0aW1lID0gZWR6WzFdOwotICAgICAgaWYgKGRhdGV0aW1lID09IG51bGwpCi0gICAgICAgIHJldHVybiBEb3VibGUuTmFOOwotCi0gICAgICBTdHJpbmdbXSBmb3JtYXRzID0ge2R0LCB0fTsKLSAgICAgIHJldHVybiBnZXROdW1iZXIoZGF0ZXRpbWUsIGZvcm1hdHMsIENhbGVuZGFyLlNFQ09ORCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2VlIGFib3ZlLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZG91YmxlIHNlY29uZEluTWludXRlKCkKLSAgICB7Ci0gICAgICAgQ2FsZW5kYXIgY2FsID0gQ2FsZW5kYXIuZ2V0SW5zdGFuY2UoKTsKLSAgICAgIHJldHVybiBjYWwuZ2V0KENhbGVuZGFyLlNFQ09ORCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhlIGRhdGU6bGVhcC15ZWFyIGZ1bmN0aW9uIHJldHVybnMgdHJ1ZSBpZiB0aGUgeWVhciBnaXZlbiBpbiBhIGRhdGUKLSAgICAgKiBpcyBhIGxlYXAgeWVhci4gSWYgbm8gYXJndW1lbnQgaXMgZ2l2ZW4sIHRoZW4gdGhlIGN1cnJlbnQgbG9jYWwKLSAgICAgKiBkYXRlL3RpbWUsIGFzIHJldHVybmVkIGJ5IGRhdGU6ZGF0ZS10aW1lIGlzIHVzZWQgYXMgYSBkZWZhdWx0IGFyZ3VtZW50LgotICAgICAqIFRoZSBkYXRlL3RpbWUgc3RyaW5nIHNwZWNpZmllZCBhcyB0aGUgZmlyc3QgYXJndW1lbnQgbXVzdCBiZSBhCi0gICAgICogcmlnaHQtdHJ1bmNhdGVkIHN0cmluZyBpbiB0aGUgZm9ybWF0IGRlZmluZWQgYXMgdGhlIGxleGljYWwgcmVwcmVzZW50YXRpb24KLSAgICAgKiBvZiB4czpkYXRlVGltZSBpbiBvbmUgb2YgdGhlIGZvcm1hdHMgZGVmaW5lZCBpbgotICAgICAqIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3htbHNjaGVtYS0yLyI+W1hNTCBTY2hlbWEgUGFydCAyOiBEYXRhdHlwZXNdPC9hPi4KLSAgICAgKiBUaGUgcGVybWl0dGVkIGZvcm1hdHMgYXJlIGFzIGZvbGxvd3M6Ci0gICAgICogICAgeHM6ZGF0ZVRpbWUgKENDWVktTU0tRERUaGg6bW06c3MpCi0gICAgICogICAgeHM6ZGF0ZSAoQ0NZWS1NTS1ERCkKLSAgICAgKiAgICB4czpnWWVhck1vbnRoIChDQ1lZLU1NKQotICAgICAqICAgIHhzOmdZZWFyIChDQ1lZKQotICAgICAqIElmIHRoZSBkYXRlL3RpbWUgc3RyaW5nIGlzIG5vdCBpbiBvbmUgb2YgdGhlc2UgZm9ybWF0cywgdGhlbiBOYU4gaXMgcmV0dXJuZWQuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBYT2JqZWN0IGxlYXBZZWFyKFN0cmluZyBkYXRldGltZUluKQotICAgICAgdGhyb3dzIFBhcnNlRXhjZXB0aW9uCi0gICAgewotICAgICAgU3RyaW5nW10gZWR6ID0gZ2V0RXJhRGF0ZXRpbWVab25lKGRhdGV0aW1lSW4pOwotICAgICAgU3RyaW5nIGRhdGV0aW1lID0gZWR6WzFdOwotICAgICAgaWYgKGRhdGV0aW1lID09IG51bGwpCi0gICAgICAgIHJldHVybiBuZXcgWE51bWJlcihEb3VibGUuTmFOKTsKLQotICAgICAgU3RyaW5nW10gZm9ybWF0cyA9IHtkdCwgZCwgZ3ltLCBneX07Ci0gICAgICBkb3VibGUgZGJsID0gZ2V0TnVtYmVyKGRhdGV0aW1lLCBmb3JtYXRzLCBDYWxlbmRhci5ZRUFSKTsKLSAgICAgIGlmIChkYmwgPT0gRG91YmxlLk5hTikKLSAgICAgICAgcmV0dXJuIG5ldyBYTnVtYmVyKERvdWJsZS5OYU4pOwotICAgICAgaW50IHlyID0gKGludClkYmw7Ci0gICAgICByZXR1cm4gbmV3IFhCb29sZWFuKHlyICUgNDAwID09IDAgfHwgKHlyICUgMTAwICE9IDAgJiYgeXIgJSA0ID09IDApKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZWUgYWJvdmUuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBib29sZWFuIGxlYXBZZWFyKCkKLSAgICB7Ci0gICAgICBDYWxlbmRhciBjYWwgPSBDYWxlbmRhci5nZXRJbnN0YW5jZSgpOwotICAgICAgaW50IHlyID0gKGludCljYWwuZ2V0KENhbGVuZGFyLllFQVIpOwotICAgICAgcmV0dXJuICh5ciAlIDQwMCA9PSAwIHx8ICh5ciAlIDEwMCAhPSAwICYmIHlyICUgNCA9PSAwKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhlIGRhdGU6bW9udGgtbmFtZSBmdW5jdGlvbiByZXR1cm5zIHRoZSBmdWxsIG5hbWUgb2YgdGhlIG1vbnRoIG9mIGEgZGF0ZS4KLSAgICAgKiBJZiBubyBhcmd1bWVudCBpcyBnaXZlbiwgdGhlbiB0aGUgY3VycmVudCBsb2NhbCBkYXRlL3RpbWUsIGFzIHJldHVybmVkIGJ5Ci0gICAgICogZGF0ZTpkYXRlLXRpbWUgaXMgdXNlZCB0aGUgZGVmYXVsdCBhcmd1bWVudC4KLSAgICAgKiBUaGUgZGF0ZS90aW1lIHN0cmluZyBzcGVjaWZpZWQgYXMgdGhlIGFyZ3VtZW50IGlzIGEgbGVmdCBvciByaWdodC10cnVuY2F0ZWQKLSAgICAgKiBzdHJpbmcgaW4gdGhlIGZvcm1hdCBkZWZpbmVkIGFzIHRoZSBsZXhpY2FsIHJlcHJlc2VudGF0aW9uIG9mIHhzOmRhdGVUaW1lIGluCi0gICAgICogIG9uZSBvZiB0aGUgZm9ybWF0cyBkZWZpbmVkIGluCi0gICAgICogPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveG1sc2NoZW1hLTIvIj5bWE1MIFNjaGVtYSBQYXJ0IDI6IERhdGF0eXBlc108L2E+LgotICAgICAqIFRoZSBwZXJtaXR0ZWQgZm9ybWF0cyBhcmUgYXMgZm9sbG93czoKLSAgICAgKiAgICB4czpkYXRlVGltZSAoQ0NZWS1NTS1ERFRoaDptbTpzcykKLSAgICAgKiAgICB4czpkYXRlIChDQ1lZLU1NLUREKQotICAgICAqICAgIHhzOmdZZWFyTW9udGggKENDWVktTU0pCi0gICAgICogICAgeHM6Z01vbnRoICgtLU1NLS0pCi0gICAgICogSWYgdGhlIGRhdGUvdGltZSBzdHJpbmcgaXMgbm90IGluIG9uZSBvZiB0aGVzZSBmb3JtYXRzLCB0aGVuIGFuIGVtcHR5IHN0cmluZyAoJycpCi0gICAgICogaXMgcmV0dXJuZWQuCi0gICAgICogVGhlIHJlc3VsdCBpcyBhbiBFbmdsaXNoIG1vbnRoIG5hbWU6IG9uZSBvZiAnSmFudWFyeScsICdGZWJydWFyeScsICdNYXJjaCcsCi0gICAgICogJ0FwcmlsJywgJ01heScsICdKdW5lJywgJ0p1bHknLCAnQXVndXN0JywgJ1NlcHRlbWJlcicsICdPY3RvYmVyJywgJ05vdmVtYmVyJwotICAgICAqIG9yICdEZWNlbWJlcicuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBTdHJpbmcgbW9udGhOYW1lKFN0cmluZyBkYXRldGltZUluKQotICAgICAgdGhyb3dzIFBhcnNlRXhjZXB0aW9uCi0gICAgewotICAgICAgU3RyaW5nW10gZWR6ID0gZ2V0RXJhRGF0ZXRpbWVab25lKGRhdGV0aW1lSW4pOwotICAgICAgU3RyaW5nIGRhdGV0aW1lID0gZWR6WzFdOwotICAgICAgaWYgKGRhdGV0aW1lID09IG51bGwpCi0gICAgICAgIHJldHVybiBFTVBUWV9TVFI7Ci0KLSAgICAgIFN0cmluZ1tdIGZvcm1hdHNJbiA9IHtkdCwgZCwgZ3ltLCBnbX07Ci0gICAgICBTdHJpbmcgZm9ybWF0T3V0ID0gIk1NTU0iOwotICAgICAgcmV0dXJuIGdldE5hbWVPckFiYnJldihkYXRldGltZUluLCBmb3JtYXRzSW4sIGZvcm1hdE91dCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2VlIGFib3ZlLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIG1vbnRoTmFtZSgpCi0gICAgewotICAgICAgQ2FsZW5kYXIgY2FsID0gQ2FsZW5kYXIuZ2V0SW5zdGFuY2UoKTsKLSAgICAgIFN0cmluZyBmb3JtYXQgPSAiTU1NTSI7Ci0gICAgICByZXR1cm4gZ2V0TmFtZU9yQWJicmV2KGZvcm1hdCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhlIGRhdGU6bW9udGgtYWJicmV2aWF0aW9uIGZ1bmN0aW9uIHJldHVybnMgdGhlIGFiYnJldmlhdGlvbiBvZiB0aGUgbW9udGggb2YKLSAgICAgKiBhIGRhdGUuIElmIG5vIGFyZ3VtZW50IGlzIGdpdmVuLCB0aGVuIHRoZSBjdXJyZW50IGxvY2FsIGRhdGUvdGltZSwgYXMgcmV0dXJuZWQKLSAgICAgKiBieSBkYXRlOmRhdGUtdGltZSBpcyB1c2VkIHRoZSBkZWZhdWx0IGFyZ3VtZW50LgotICAgICAqIFRoZSBkYXRlL3RpbWUgc3RyaW5nIHNwZWNpZmllZCBhcyB0aGUgYXJndW1lbnQgaXMgYSBsZWZ0IG9yIHJpZ2h0LXRydW5jYXRlZAotICAgICAqIHN0cmluZyBpbiB0aGUgZm9ybWF0IGRlZmluZWQgYXMgdGhlIGxleGljYWwgcmVwcmVzZW50YXRpb24gb2YgeHM6ZGF0ZVRpbWUgaW4KLSAgICAgKiBvbmUgb2YgdGhlIGZvcm1hdHMgZGVmaW5lZCBpbgotICAgICAqIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3htbHNjaGVtYS0yLyI+W1hNTCBTY2hlbWEgUGFydCAyOiBEYXRhdHlwZXNdPC9hPi4KLSAgICAgKiBUaGUgcGVybWl0dGVkIGZvcm1hdHMgYXJlIGFzIGZvbGxvd3M6Ci0gICAgICogICAgeHM6ZGF0ZVRpbWUgKENDWVktTU0tRERUaGg6bW06c3MpCi0gICAgICogICAgeHM6ZGF0ZSAoQ0NZWS1NTS1ERCkKLSAgICAgKiAgICB4czpnWWVhck1vbnRoIChDQ1lZLU1NKQotICAgICAqICAgIHhzOmdNb250aCAoLS1NTS0tKQotICAgICAqIElmIHRoZSBkYXRlL3RpbWUgc3RyaW5nIGlzIG5vdCBpbiBvbmUgb2YgdGhlc2UgZm9ybWF0cywgdGhlbiBhbiBlbXB0eSBzdHJpbmcgKCcnKQotICAgICAqIGlzIHJldHVybmVkLgotICAgICAqIFRoZSByZXN1bHQgaXMgYSB0aHJlZS1sZXR0ZXIgRW5nbGlzaCBtb250aCBhYmJyZXZpYXRpb246IG9uZSBvZiAnSmFuJywgJ0ZlYicsICdNYXInLAotICAgICAqICdBcHInLCAnTWF5JywgJ0p1bicsICdKdWwnLCAnQXVnJywgJ1NlcCcsICdPY3QnLCAnTm92JyBvciAnRGVjJy4KLSAgICAgKiBBbiBpbXBsZW1lbnRhdGlvbiBvZiB0aGlzIGV4dGVuc2lvbiBmdW5jdGlvbiBpbiB0aGUgRVhTTFQgZGF0ZSBuYW1lc3BhY2UgbXVzdCBjb25mb3JtCi0gICAgICogdG8gdGhlIGJlaGF2aW91ciBkZXNjcmliZWQgaW4gdGhpcyBkb2N1bWVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBtb250aEFiYnJldmlhdGlvbihTdHJpbmcgZGF0ZXRpbWVJbikKLSAgICAgIHRocm93cyBQYXJzZUV4Y2VwdGlvbgotICAgIHsKLSAgICAgIFN0cmluZ1tdIGVkeiA9IGdldEVyYURhdGV0aW1lWm9uZShkYXRldGltZUluKTsKLSAgICAgIFN0cmluZyBkYXRldGltZSA9IGVkelsxXTsKLSAgICAgIGlmIChkYXRldGltZSA9PSBudWxsKQotICAgICAgICByZXR1cm4gRU1QVFlfU1RSOwotCi0gICAgICBTdHJpbmdbXSBmb3JtYXRzSW4gPSB7ZHQsIGQsIGd5bSwgZ219OwotICAgICAgU3RyaW5nIGZvcm1hdE91dCA9ICJNTU0iOwotICAgICAgcmV0dXJuIGdldE5hbWVPckFiYnJldihkYXRldGltZUluLCBmb3JtYXRzSW4sIGZvcm1hdE91dCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2VlIGFib3ZlLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIG1vbnRoQWJicmV2aWF0aW9uKCkKLSAgICB7Ci0gICAgICBTdHJpbmcgZm9ybWF0ID0gIk1NTSI7Ci0gICAgICByZXR1cm4gZ2V0TmFtZU9yQWJicmV2KGZvcm1hdCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhlIGRhdGU6ZGF5LW5hbWUgZnVuY3Rpb24gcmV0dXJucyB0aGUgZnVsbCBuYW1lIG9mIHRoZSBkYXkgb2YgdGhlIHdlZWsKLSAgICAgKiBvZiBhIGRhdGUuICBJZiBubyBhcmd1bWVudCBpcyBnaXZlbiwgdGhlbiB0aGUgY3VycmVudCBsb2NhbCBkYXRlL3RpbWUsCi0gICAgICogYXMgcmV0dXJuZWQgYnkgZGF0ZTpkYXRlLXRpbWUgaXMgdXNlZCB0aGUgZGVmYXVsdCBhcmd1bWVudC4KLSAgICAgKiBUaGUgZGF0ZS90aW1lIHN0cmluZyBzcGVjaWZpZWQgYXMgdGhlIGFyZ3VtZW50IGlzIGEgbGVmdCBvciByaWdodC10cnVuY2F0ZWQKLSAgICAgKiBzdHJpbmcgaW4gdGhlIGZvcm1hdCBkZWZpbmVkIGFzIHRoZSBsZXhpY2FsIHJlcHJlc2VudGF0aW9uIG9mIHhzOmRhdGVUaW1lCi0gICAgICogaW4gb25lIG9mIHRoZSBmb3JtYXRzIGRlZmluZWQgaW4KLSAgICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94bWxzY2hlbWEtMi8iPltYTUwgU2NoZW1hIFBhcnQgMjogRGF0YXR5cGVzXTwvYT4uCi0gICAgICogVGhlIHBlcm1pdHRlZCBmb3JtYXRzIGFyZSBhcyBmb2xsb3dzOgotICAgICAqICAgICB4czpkYXRlVGltZSAoQ0NZWS1NTS1ERFRoaDptbTpzcykKLSAgICAgKiAgICAgeHM6ZGF0ZSAoQ0NZWS1NTS1ERCkKLSAgICAgKiBJZiB0aGUgZGF0ZS90aW1lIHN0cmluZyBpcyBub3QgaW4gb25lIG9mIHRoZXNlIGZvcm1hdHMsIHRoZW4gdGhlIGVtcHR5IHN0cmluZyAoJycpCi0gICAgICogaXMgcmV0dXJuZWQuCi0gICAgICogVGhlIHJlc3VsdCBpcyBhbiBFbmdsaXNoIGRheSBuYW1lOiBvbmUgb2YgJ1N1bmRheScsICdNb25kYXknLCAnVHVlc2RheScsICdXZWRuZXNkYXknLAotICAgICAqICdUaHVyc2RheScgb3IgJ0ZyaWRheScuCi0gICAgICogQW4gaW1wbGVtZW50YXRpb24gb2YgdGhpcyBleHRlbnNpb24gZnVuY3Rpb24gaW4gdGhlIEVYU0xUIGRhdGUgbmFtZXNwYWNlIG11c3QgY29uZm9ybQotICAgICAqIHRvIHRoZSBiZWhhdmlvdXIgZGVzY3JpYmVkIGluIHRoaXMgZG9jdW1lbnQuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZGF5TmFtZShTdHJpbmcgZGF0ZXRpbWVJbikKLSAgICAgIHRocm93cyBQYXJzZUV4Y2VwdGlvbgotICAgIHsKLSAgICAgIFN0cmluZ1tdIGVkeiA9IGdldEVyYURhdGV0aW1lWm9uZShkYXRldGltZUluKTsKLSAgICAgIFN0cmluZyBkYXRldGltZSA9IGVkelsxXTsKLSAgICAgIGlmIChkYXRldGltZSA9PSBudWxsKQotICAgICAgICByZXR1cm4gRU1QVFlfU1RSOwotCi0gICAgICBTdHJpbmdbXSBmb3JtYXRzSW4gPSB7ZHQsIGR9OwotICAgICAgU3RyaW5nIGZvcm1hdE91dCA9ICJFRUVFIjsKLSAgICAgIHJldHVybiBnZXROYW1lT3JBYmJyZXYoZGF0ZXRpbWVJbiwgZm9ybWF0c0luLCBmb3JtYXRPdXQpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNlZSBhYm92ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBkYXlOYW1lKCkKLSAgICB7Ci0gICAgICBTdHJpbmcgZm9ybWF0ID0gIkVFRUUiOwotICAgICAgcmV0dXJuIGdldE5hbWVPckFiYnJldihmb3JtYXQpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoZSBkYXRlOmRheS1hYmJyZXZpYXRpb24gZnVuY3Rpb24gcmV0dXJucyB0aGUgYWJicmV2aWF0aW9uIG9mIHRoZSBkYXkKLSAgICAgKiBvZiB0aGUgd2VlayBvZiBhIGRhdGUuIElmIG5vIGFyZ3VtZW50IGlzIGdpdmVuLCB0aGVuIHRoZSBjdXJyZW50IGxvY2FsCi0gICAgICogZGF0ZS90aW1lLCBhcyByZXR1cm5lZCAgYnkgZGF0ZTpkYXRlLXRpbWUgaXMgdXNlZCB0aGUgZGVmYXVsdCBhcmd1bWVudC4KLSAgICAgKiBUaGUgZGF0ZS90aW1lIHN0cmluZyBzcGVjaWZpZWQgYXMgdGhlIGFyZ3VtZW50IGlzIGEgbGVmdCBvciByaWdodC10cnVuY2F0ZWQKLSAgICAgKiBzdHJpbmcgaW4gdGhlIGZvcm1hdCBkZWZpbmVkIGFzIHRoZSBsZXhpY2FsIHJlcHJlc2VudGF0aW9uIG9mIHhzOmRhdGVUaW1lCi0gICAgICogaW4gb25lIG9mIHRoZSBmb3JtYXRzIGRlZmluZWQgaW4KLSAgICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94bWxzY2hlbWEtMi8iPltYTUwgU2NoZW1hIFBhcnQgMjogRGF0YXR5cGVzXTwvYT4uCi0gICAgICogVGhlIHBlcm1pdHRlZCBmb3JtYXRzIGFyZSBhcyBmb2xsb3dzOgotICAgICAqICAgICB4czpkYXRlVGltZSAoQ0NZWS1NTS1ERFRoaDptbTpzcykKLSAgICAgKiAgICAgeHM6ZGF0ZSAoQ0NZWS1NTS1ERCkKLSAgICAgKiBJZiB0aGUgZGF0ZS90aW1lIHN0cmluZyBpcyBub3QgaW4gb25lIG9mIHRoZXNlIGZvcm1hdHMsIHRoZW4gdGhlIGVtcHR5IHN0cmluZwotICAgICAqICgnJykgaXMgcmV0dXJuZWQuCi0gICAgICogVGhlIHJlc3VsdCBpcyBhIHRocmVlLWxldHRlciBFbmdsaXNoIGRheSBhYmJyZXZpYXRpb246IG9uZSBvZiAnU3VuJywgJ01vbicsICdUdWUnLAotICAgICAqICdXZWQnLCAnVGh1JyBvciAnRnJpJy4KLSAgICAgKiBBbiBpbXBsZW1lbnRhdGlvbiBvZiB0aGlzIGV4dGVuc2lvbiBmdW5jdGlvbiBpbiB0aGUgRVhTTFQgZGF0ZSBuYW1lc3BhY2UgbXVzdCBjb25mb3JtCi0gICAgICogdG8gdGhlIGJlaGF2aW91ciBkZXNjcmliZWQgaW4gdGhpcyBkb2N1bWVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBkYXlBYmJyZXZpYXRpb24oU3RyaW5nIGRhdGV0aW1lSW4pCi0gICAgICB0aHJvd3MgUGFyc2VFeGNlcHRpb24KLSAgICB7Ci0gICAgICBTdHJpbmdbXSBlZHogPSBnZXRFcmFEYXRldGltZVpvbmUoZGF0ZXRpbWVJbik7Ci0gICAgICBTdHJpbmcgZGF0ZXRpbWUgPSBlZHpbMV07Ci0gICAgICBpZiAoZGF0ZXRpbWUgPT0gbnVsbCkKLSAgICAgICAgcmV0dXJuIEVNUFRZX1NUUjsKLQotICAgICAgU3RyaW5nW10gZm9ybWF0c0luID0ge2R0LCBkfTsKLSAgICAgIFN0cmluZyBmb3JtYXRPdXQgPSAiRUVFIjsKLSAgICAgIHJldHVybiBnZXROYW1lT3JBYmJyZXYoZGF0ZXRpbWVJbiwgZm9ybWF0c0luLCBmb3JtYXRPdXQpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNlZSBhYm92ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBkYXlBYmJyZXZpYXRpb24oKQotICAgIHsKLSAgICAgIFN0cmluZyBmb3JtYXQgPSAiRUVFIjsKLSAgICAgIHJldHVybiBnZXROYW1lT3JBYmJyZXYoZm9ybWF0KTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGFuIGFycmF5IHdpdGggdGhlIDMgY29tcG9uZW50cyB0aGF0IGEgZGF0ZXRpbWUgaW5wdXQgc3RyaW5nCi0gICAgICogbWF5IGNvbnRhaW46IC0gKGZvciBCQyBlcmEpLCBkYXRldGltZSwgYW5kIHpvbmUuIElmIHRoZSB6b25lIGlzIG5vdAotICAgICAqIHZhbGlkLCByZXR1cm4gbnVsbCBmb3IgdGhhdCBjb21wb25lbnQuCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nW10gZ2V0RXJhRGF0ZXRpbWVab25lKFN0cmluZyBpbikKLSAgICB7Ci0gICAgICBTdHJpbmcgbGVhZGVyID0gIiI7Ci0gICAgICBTdHJpbmcgZGF0ZXRpbWUgPSBpbjsKLSAgICAgIFN0cmluZyB6b25lID0gIiI7Ci0gICAgICBpZiAoaW4uY2hhckF0KDApPT0nLScgJiYgIWluLnN0YXJ0c1dpdGgoIi0tIikpCi0gICAgICB7Ci0gICAgICAgIGxlYWRlciA9ICItIjsgLy8gICcrJyBpcyBpbXBsaWNpdCAsIG5vdCBhbGxvd2VkCi0gICAgICAgIGRhdGV0aW1lID0gaW4uc3Vic3RyaW5nKDEpOwotICAgICAgfQotICAgICAgaW50IHogPSBnZXRab25lU3RhcnQoZGF0ZXRpbWUpOwotICAgICAgaWYgKHogPiAwKQotICAgICAgewotICAgICAgICB6b25lID0gZGF0ZXRpbWUuc3Vic3RyaW5nKHopOwotICAgICAgICBkYXRldGltZSA9IGRhdGV0aW1lLnN1YnN0cmluZygwLCB6KTsKLSAgICAgIH0KLSAgICAgIGVsc2UgaWYgKHogPT0gLTIpCi0gICAgICAgIHpvbmUgPSBudWxsOwotICAgICAgLy9TeXN0ZW0ub3V0LnByaW50bG4oIiciICsgbGVhZGVyICsgIicgIiArIGRhdGV0aW1lICsgIiAiICsgem9uZSk7Ci0gICAgICByZXR1cm4gbmV3IFN0cmluZ1tde2xlYWRlciwgZGF0ZXRpbWUsIHpvbmV9OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgc3RhcnQgb2Ygem9uZSBpbmZvcm1hdGlvbiBpZiB0aGUgaW5wdXQgZW5kcwotICAgICAqIHdpdGggJ1onIG9yICsvLWhoOm1tLiBJZiBhIHpvbmUgc3RyaW5nIGlzIG5vdAotICAgICAqIGZvdW5kLCByZXR1cm4gLTE7IGlmIHRoZSB6b25lIHN0cmluZyBpcyBpbnZhbGlkLAotICAgICAqIHJldHVybiAtMi4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBpbnQgZ2V0Wm9uZVN0YXJ0IChTdHJpbmcgZGF0ZXRpbWUpCi0gICAgewotICAgICAgaWYgKGRhdGV0aW1lLmluZGV4T2YoIloiKSA9PSBkYXRldGltZS5sZW5ndGgoKS0xKQotICAgICAgICByZXR1cm4gZGF0ZXRpbWUubGVuZ3RoKCktMTsKLSAgICAgIGVsc2UgaWYgKGRhdGV0aW1lLmxlbmd0aCgpID49NgotICAgICAgICAgICAgICAgICYmIGRhdGV0aW1lLmNoYXJBdChkYXRldGltZS5sZW5ndGgoKS0zKSA9PSAnOicKLSAgICAgICAgICAgICAgICAmJiAoZGF0ZXRpbWUuY2hhckF0KGRhdGV0aW1lLmxlbmd0aCgpLTYpID09ICcrJwotICAgICAgICAgICAgICAgICAgICB8fCBkYXRldGltZS5jaGFyQXQoZGF0ZXRpbWUubGVuZ3RoKCktNikgPT0gJy0nKSkKLSAgICAgIHsKLSAgICAgICAgdHJ5Ci0gICAgICAgIHsKLSAgICAgICAgICBTaW1wbGVEYXRlRm9ybWF0IGRhdGVGb3JtYXQgPSBuZXcgU2ltcGxlRGF0ZUZvcm1hdCgiSEg6bW0iKTsKLSAgICAgICAgICBkYXRlRm9ybWF0LnNldExlbmllbnQoZmFsc2UpOwotICAgICAgICAgIERhdGUgZCA9IGRhdGVGb3JtYXQucGFyc2UoZGF0ZXRpbWUuc3Vic3RyaW5nKGRhdGV0aW1lLmxlbmd0aCgpIC01KSk7Ci0gICAgICAgICAgcmV0dXJuIGRhdGV0aW1lLmxlbmd0aCgpLTY7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKFBhcnNlRXhjZXB0aW9uIHBlKQotICAgICAgICB7Ci0gICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJQYXJzZUV4Y2VwdGlvbiAiICsgcGUuZ2V0RXJyb3JPZmZzZXQoKSk7Ci0gICAgICAgICAgcmV0dXJuIC0yOyAvLyBJbnZhbGlkLgotICAgICAgICB9Ci0KLSAgICAgIH0KLSAgICAgICAgcmV0dXJuIC0xOyAvLyBObyB6b25lIGluZm9ybWF0aW9uLgotICAgIH0KLQotICAgIC8qKgotICAgICAqIEF0dGVtcHQgdG8gcGFyc2UgYW4gaW5wdXQgc3RyaW5nIHdpdGggdGhlIGFsbG93ZWQgZm9ybWF0cywgcmV0dXJuaW5nCi0gICAgICogbnVsbCBpZiBub25lIG9mIHRoZSBmb3JtYXRzIHdvcmsuCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgRGF0ZSB0ZXN0Rm9ybWF0cyAoU3RyaW5nIGluLCBTdHJpbmdbXSBmb3JtYXRzKQotICAgICAgdGhyb3dzIFBhcnNlRXhjZXB0aW9uCi0gICAgewotICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPGZvcm1hdHMubGVuZ3RoOyBpKyspCi0gICAgICB7Ci0gICAgICAgIHRyeQotICAgICAgICB7Ci0gICAgICAgICAgU2ltcGxlRGF0ZUZvcm1hdCBkYXRlRm9ybWF0ID0gbmV3IFNpbXBsZURhdGVGb3JtYXQoZm9ybWF0c1tpXSk7Ci0gICAgICAgICAgZGF0ZUZvcm1hdC5zZXRMZW5pZW50KGZhbHNlKTsKLSAgICAgICAgICByZXR1cm4gZGF0ZUZvcm1hdC5wYXJzZShpbik7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKFBhcnNlRXhjZXB0aW9uIHBlKQotICAgICAgICB7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogUGFyc2UgdGhlIGlucHV0IHN0cmluZyBhbmQgcmV0dXJuIHRoZSBjb3JyZXNwb25kaW5nIGNhbGVuZGFyIGZpZWxkCi0gICAgICogbnVtYmVyLgotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIGRvdWJsZSBnZXROdW1iZXIoU3RyaW5nIGluLCBTdHJpbmdbXSBmb3JtYXRzLCBpbnQgY2FsRmllbGQpCi0gICAgICB0aHJvd3MgUGFyc2VFeGNlcHRpb24KLSAgICB7Ci0gICAgICBDYWxlbmRhciBjYWwgPSBDYWxlbmRhci5nZXRJbnN0YW5jZSgpOwotICAgICAgY2FsLnNldExlbmllbnQoZmFsc2UpOwotICAgICAgLy8gVHJ5IHRoZSBhbGxvd2VkIGZvcm1hdHMsIGZyb20gbG9uZ2VzdCB0byBzaG9ydGVzdC4KLSAgICAgIERhdGUgZGF0ZSA9IHRlc3RGb3JtYXRzKGluLCBmb3JtYXRzKTsKLSAgICAgIGlmIChkYXRlID09IG51bGwpIHJldHVybiBEb3VibGUuTmFOOwotICAgICAgY2FsLnNldFRpbWUoZGF0ZSk7Ci0gICAgICByZXR1cm4gY2FsLmdldChjYWxGaWVsZCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogIEdldCB0aGUgZnVsbCBuYW1lIG9yIGFiYnJldmlhdGlvbiBvZiB0aGUgbW9udGggb3IgZGF5LgotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBnZXROYW1lT3JBYmJyZXYoU3RyaW5nIGluLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmdbXSBmb3JtYXRzSW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBmb3JtYXRPdXQpCi0gICAgICB0aHJvd3MgUGFyc2VFeGNlcHRpb24KLSAgICB7Ci0gICAgICBmb3IgKGludCBpID0gMDsgaSA8Zm9ybWF0c0luLmxlbmd0aDsgaSsrKSAvLyBmcm9tIGxvbmdlc3QgdG8gc2hvcnRlc3QuCi0gICAgICB7Ci0gICAgICAgIHRyeQotICAgICAgICB7Ci0gICAgICAgICAgU2ltcGxlRGF0ZUZvcm1hdCBkYXRlRm9ybWF0ID0gbmV3IFNpbXBsZURhdGVGb3JtYXQoZm9ybWF0c0luW2ldLCBMb2NhbGUuRU5HTElTSCk7Ci0gICAgICAgICAgZGF0ZUZvcm1hdC5zZXRMZW5pZW50KGZhbHNlKTsKLSAgICAgICAgICBEYXRlIGR0ID0gZGF0ZUZvcm1hdC5wYXJzZShpbik7Ci0gICAgICAgICAgZGF0ZUZvcm1hdC5hcHBseVBhdHRlcm4oZm9ybWF0T3V0KTsKLSAgICAgICAgICByZXR1cm4gZGF0ZUZvcm1hdC5mb3JtYXQoZHQpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChQYXJzZUV4Y2VwdGlvbiBwZSkKLSAgICAgICAgewotICAgICAgICB9Ci0gICAgICB9Ci0gICAgICByZXR1cm4gIiI7Ci0gICAgfQotICAgIC8qKgotICAgICAqIEdldCB0aGUgZnVsbCBuYW1lIG9yIGFiYnJldmlhdGlvbiBmb3IgdGhlIGN1cnJlbnQgbW9udGggb3IgZGF5Ci0gICAgICogKG5vIGlucHV0IHN0cmluZykuCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGdldE5hbWVPckFiYnJldihTdHJpbmcgZm9ybWF0KQotICAgIHsKLSAgICAgIENhbGVuZGFyIGNhbCA9IENhbGVuZGFyLmdldEluc3RhbmNlKCk7Ci0gICAgICBTaW1wbGVEYXRlRm9ybWF0IGRhdGVGb3JtYXQgPSBuZXcgU2ltcGxlRGF0ZUZvcm1hdChmb3JtYXQsIExvY2FsZS5FTkdMSVNIKTsKLSAgICAgIHJldHVybiBkYXRlRm9ybWF0LmZvcm1hdChjYWwuZ2V0VGltZSgpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgZGF0ZTpmb3JtYXQtZGF0ZSBmdW5jdGlvbiBmb3JtYXRzIGEgZGF0ZS90aW1lIGFjY29yZGluZyB0byBhIHBhdHRlcm4uCi0gICAgICogPHA+Ci0gICAgICogVGhlIGZpcnN0IGFyZ3VtZW50IHRvIGRhdGU6Zm9ybWF0LWRhdGUgc3BlY2lmaWVzIHRoZSBkYXRlL3RpbWUgdG8gYmUKLSAgICAgKiBmb3JtYXR0ZWQuIEl0IG11c3QgYmUgcmlnaHQgb3IgbGVmdC10cnVuY2F0ZWQgZGF0ZS90aW1lIHN0cmluZ3MgaW4gb25lIG9mCi0gICAgICogdGhlIGZvcm1hdHMgZGVmaW5lZCBpbgotICAgICAqIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3htbHNjaGVtYS0yLyI+W1hNTCBTY2hlbWEgUGFydCAyOiBEYXRhdHlwZXNdPC9hPi4KLSAgICAgKiBUaGUgcGVybWl0dGVkIGZvcm1hdHMgYXJlIGFzIGZvbGxvd3M6Ci0gICAgICogPHVsPgotICAgICAqIDxsaT54czpkYXRlVGltZSAoQ0NZWS1NTS1ERFRoaDptbTpzcykKLSAgICAgKiA8bGk+eHM6ZGF0ZSAoQ0NZWS1NTS1ERCkKLSAgICAgKiA8bGk+eHM6dGltZSAoaGg6bW06c3MpCi0gICAgICogPGxpPnhzOmdZZWFyTW9udGggKENDWVktTU0pCi0gICAgICogPGxpPnhzOmdZZWFyIChDQ1lZKQotICAgICAqIDxsaT54czpnTW9udGhEYXkgKC0tTU0tREQpCi0gICAgICogPGxpPnhzOmdNb250aCAoLS1NTS0tKQotICAgICAqIDxsaT54czpnRGF5ICgtLS1ERCkKLSAgICAgKiA8L3VsPgotICAgICAqIFRoZSBzZWNvbmQgYXJndW1lbnQgaXMgYSBzdHJpbmcgdGhhdCBnaXZlcyB0aGUgZm9ybWF0IHBhdHRlcm4gdXNlZCB0bwotICAgICAqIGZvcm1hdCB0aGUgZGF0ZS4gVGhlIGZvcm1hdCBwYXR0ZXJuIG11c3QgYmUgaW4gdGhlIHN5bnRheCBzcGVjaWZpZWQgYnkKLSAgICAgKiB0aGUgSkRLIDEuMSBTaW1wbGVEYXRlRm9ybWF0IGNsYXNzLiBUaGUgZm9ybWF0IHBhdHRlcm4gc3RyaW5nIGlzCi0gICAgICogaW50ZXJwcmV0ZWQgYXMgZGVzY3JpYmVkIGZvciB0aGUgSkRLIDEuMSBTaW1wbGVEYXRlRm9ybWF0IGNsYXNzLgotICAgICAqIDxwPgotICAgICAqIElmIHRoZSBkYXRlL3RpbWUgZm9ybWF0IGlzIHJpZ2h0LXRydW5jYXRlZCAoaS5lLiBpbiBhIGZvcm1hdCBvdGhlciB0aGFuCi0gICAgICogeHM6dGltZSwgb3IgeHM6ZGF0ZVRpbWUpIHRoZW4gYW55IG1pc3NpbmcgY29tcG9uZW50cyBhcmUgYXNzdW1lZCB0byBiZSBhcwotICAgICAqIGZvbGxvd3M6IGlmIG5vIG1vbnRoIGlzIHNwZWNpZmllZCwgaXQgaXMgZ2l2ZW4gYSBtb250aCBvZiAwMTsgaWYgbm8gZGF5Ci0gICAgICogaXMgc3BlY2lmaWVkLCBpdCBpcyBnaXZlbiBhIGRheSBvZiAwMTsgaWYgbm8gdGltZSBpcyBzcGVjaWZpZWQsIGl0IGlzCi0gICAgICogZ2l2ZW4gYSB0aW1lIG9mIDAwOjAwOjAwLgotICAgICAqIDxwPgotICAgICAqIElmIHRoZSBkYXRlL3RpbWUgZm9ybWF0IGlzIGxlZnQtdHJ1bmNhdGVkIChpLmUuIHhzOnRpbWUsIHhzOmdNb250aERheSwKLSAgICAgKiB4czpnTW9udGggb3IgeHM6Z0RheSkgYW5kIHRoZSBmb3JtYXQgcGF0dGVybiBoYXMgYSB0b2tlbiB0aGF0IHVzZXMgYQotICAgICAqIGNvbXBvbmVudCB0aGF0IGlzIG1pc3NpbmcgZnJvbSB0aGUgZGF0ZS90aW1lIGZvcm1hdCB1c2VkLCB0aGVuIHRoYXQgdG9rZW4KLSAgICAgKiBpcyByZXBsYWNlZCB3aXRoIGFuIGVtcHR5IHN0cmluZyAoJycpIHdpdGhpbiB0aGUgcmVzdWx0LgotICAgICAqCi0gICAgICogVGhlIGF1dGhvciBpcyBIZWxnIEJyZWRvdyAoaGVsZy5icmVkb3dAa2FsaWRvLmNvbSkKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBmb3JtYXREYXRlKFN0cmluZyBkYXRlVGltZSwgU3RyaW5nIHBhdHRlcm4pCi0gICAgewotICAgICAgICBmaW5hbCBTdHJpbmcgeWVhclN5bWJvbHMgPSAiR3kiOwotICAgICAgICBmaW5hbCBTdHJpbmcgbW9udGhTeW1ib2xzID0gIk0iOwotICAgICAgICBmaW5hbCBTdHJpbmcgZGF5U3ltYm9scyA9ICJkREVGd1ciOwotICAgICAgICBUaW1lWm9uZSB0aW1lWm9uZTsKLSAgICAgICAgU3RyaW5nIHpvbmU7Ci0KLSAgICAgICAgLy8gR2V0IHRoZSB0aW1lem9uZSBpbmZvcm1hdGlvbiBpZiBpdCB3YXMgc3VwcGxpZWQgYW5kIG1vZGlmeSB0aGUKLSAgICAgICAgLy8gZGF0ZVRpbWUgc28gdGhhdCBTaW1wbGVEYXRlRm9ybWF0IHdpbGwgdW5kZXJzdGFuZCBpdC4KLSAgICAgICAgaWYgKGRhdGVUaW1lLmVuZHNXaXRoKCJaIikgfHwgZGF0ZVRpbWUuZW5kc1dpdGgoInoiKSkKLSAgICAgICAgewotICAgICAgICAgICAgdGltZVpvbmUgPSBUaW1lWm9uZS5nZXRUaW1lWm9uZSgiR01UIik7Ci0gICAgICAgICAgICBkYXRlVGltZSA9IGRhdGVUaW1lLnN1YnN0cmluZygwLCBkYXRlVGltZS5sZW5ndGgoKS0xKSArICJHTVQiOwotICAgICAgICAgICAgem9uZSA9ICJ6IjsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICgoZGF0ZVRpbWUubGVuZ3RoKCkgPj0gNikKLSAgICAgICAgICAgICAgICAgJiYgKGRhdGVUaW1lLmNoYXJBdChkYXRlVGltZS5sZW5ndGgoKS0zKSA9PSAnOicpCi0gICAgICAgICAgICAgICAgICYmICgoZGF0ZVRpbWUuY2hhckF0KGRhdGVUaW1lLmxlbmd0aCgpLTYpID09ICcrJykKLSAgICAgICAgICAgICAgICAgICAgfHwgKGRhdGVUaW1lLmNoYXJBdChkYXRlVGltZS5sZW5ndGgoKS02KSA9PSAnLScpKSkKLSAgICAgICAgewotICAgICAgICAgICAgU3RyaW5nIG9mZnNldCA9IGRhdGVUaW1lLnN1YnN0cmluZyhkYXRlVGltZS5sZW5ndGgoKS02KTsKLQotICAgICAgICAgICAgaWYgKCIrMDA6MDAiLmVxdWFscyhvZmZzZXQpIHx8ICItMDA6MDAiLmVxdWFscyhvZmZzZXQpKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIHRpbWVab25lID0gVGltZVpvbmUuZ2V0VGltZVpvbmUoIkdNVCIpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIHRpbWVab25lID0gVGltZVpvbmUuZ2V0VGltZVpvbmUoIkdNVCIgKyBvZmZzZXQpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgem9uZSA9ICJ6IjsKLSAgICAgICAgICAgIC8vIE5lZWQgdG8gYWRqdXN0IGl0IHNpbmNlIFNpbXBsZURhdGVGb3JtYXQgcmVxdWlyZXMgR01UK2hoOm1tIGJ1dAotICAgICAgICAgICAgLy8gd2UgaGF2ZSAraGg6bW0uCi0gICAgICAgICAgICBkYXRlVGltZSA9IGRhdGVUaW1lLnN1YnN0cmluZygwLCBkYXRlVGltZS5sZW5ndGgoKS02KSArICJHTVQiICsgb2Zmc2V0OwotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotICAgICAgICAgICAgLy8gQXNzdW1lIGxvY2FsIHRpbWUuCi0gICAgICAgICAgICB0aW1lWm9uZSA9IFRpbWVab25lLmdldERlZmF1bHQoKTsKLSAgICAgICAgICAgIHpvbmUgPSAiIjsKLSAgICAgICAgICAgIC8vIExlYXZlIG9mZiB0aGUgdGltZXpvbmUgc2luY2UgU2ltcGxlRGF0ZUZvcm1hdCB3aWxsIGFzc3VtZSBsb2NhbAotICAgICAgICAgICAgLy8gdGltZSBpZiB0aW1lIHpvbmUgaXMgbm90IGluY2x1ZGVkLgotICAgICAgICB9Ci0gICAgICAgIFN0cmluZ1tdIGZvcm1hdHMgPSB7ZHQgKyB6b25lLCBkLCBneW0sIGd5fTsKLQotICAgICAgICAvLyBUcnkgdGhlIHRpbWUgZm9ybWF0IGZpcnN0LiBXZSBuZWVkIHRvIGRvIHRoaXMgdG8gcHJldmVudAotICAgICAgICAvLyBTaW1wbGVEYXRlRm9ybWF0IGZyb20gaW50ZXJwcmV0aW5nIGEgdGltZSBhcyBhIHllYXIuIGkuZSB3ZSBqdXN0IG5lZWQKLSAgICAgICAgLy8gdG8gY2hlY2sgaWYgaXQncyBhIHRpbWUgYmVmb3JlIHdlIGNoZWNrIGl0J3MgYSB5ZWFyLgotICAgICAgICB0cnkKLSAgICAgICAgewotICAgICAgICAgICAgU2ltcGxlRGF0ZUZvcm1hdCBpbkZvcm1hdCA9IG5ldyBTaW1wbGVEYXRlRm9ybWF0KHQgKyB6b25lKTsKLSAgICAgICAgICAgIGluRm9ybWF0LnNldExlbmllbnQoZmFsc2UpOwotICAgICAgICAgICAgRGF0ZSBkPSBpbkZvcm1hdC5wYXJzZShkYXRlVGltZSk7Ci0gICAgICAgICAgICBTaW1wbGVEYXRlRm9ybWF0IG91dEZvcm1hdCA9IG5ldyBTaW1wbGVEYXRlRm9ybWF0KHN0cmlwCi0gICAgICAgICAgICAgICAgKHllYXJTeW1ib2xzICsgbW9udGhTeW1ib2xzICsgZGF5U3ltYm9scywgcGF0dGVybikpOwotICAgICAgICAgICAgb3V0Rm9ybWF0LnNldFRpbWVab25lKHRpbWVab25lKTsKLSAgICAgICAgICAgIHJldHVybiBvdXRGb3JtYXQuZm9ybWF0KGQpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChQYXJzZUV4Y2VwdGlvbiBwZSkKLSAgICAgICAgewotICAgICAgICB9Ci0KLSAgICAgICAgLy8gVHJ5IHRoZSByaWdodCB0cnVuY2F0ZWQgZm9ybWF0cy4KLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmb3JtYXRzLmxlbmd0aDsgaSsrKQotICAgICAgICB7Ci0gICAgICAgICAgICB0cnkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBTaW1wbGVEYXRlRm9ybWF0IGluRm9ybWF0ID0gbmV3IFNpbXBsZURhdGVGb3JtYXQoZm9ybWF0c1tpXSk7Ci0gICAgICAgICAgICAgICAgaW5Gb3JtYXQuc2V0TGVuaWVudChmYWxzZSk7Ci0gICAgICAgICAgICAgICAgRGF0ZSBkID0gaW5Gb3JtYXQucGFyc2UoZGF0ZVRpbWUpOwotICAgICAgICAgICAgICAgIFNpbXBsZURhdGVGb3JtYXQgb3V0Rm9ybWF0ID0gbmV3IFNpbXBsZURhdGVGb3JtYXQocGF0dGVybik7Ci0gICAgICAgICAgICAgICAgb3V0Rm9ybWF0LnNldFRpbWVab25lKHRpbWVab25lKTsKLSAgICAgICAgICAgICAgICByZXR1cm4gb3V0Rm9ybWF0LmZvcm1hdChkKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhdGNoIChQYXJzZUV4Y2VwdGlvbiBwZSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIE5vdyB0cnkgdGhlIGxlZnQgdHJ1bmNhdGVkIG9uZXMuIFRoZSBKYXZhIGZvcm1hdCgpIGZ1bmN0aW9uIGRvZXNuJ3QKLSAgICAgICAgLy8gcmV0dXJuIHRoZSBjb3JyZWN0IHN0cmluZ3MgaW4gdGhpcyBjYXNlLiBXZSBzdHJpcCBhbnkgcGF0dGVybgotICAgICAgICAvLyBzeW1ib2xzIHRoYXQgc2hvdWxkbid0IGJlIG91dHB1dCBzbyB0aGF0IHRoZXkgYXJlIG5vdCBkZWZhdWx0ZWQgdG8KLSAgICAgICAgLy8gaW5hcHByb3ByaWF0ZSB2YWx1ZXMgaW4gdGhlIG91dHB1dC4KLSAgICAgICAgdHJ5Ci0gICAgICAgIHsKLSAgICAgICAgICAgIFNpbXBsZURhdGVGb3JtYXQgaW5Gb3JtYXQgPSBuZXcgU2ltcGxlRGF0ZUZvcm1hdChnbWQpOwotICAgICAgICAgICAgaW5Gb3JtYXQuc2V0TGVuaWVudChmYWxzZSk7Ci0gICAgICAgICAgICBEYXRlIGQgPSBpbkZvcm1hdC5wYXJzZShkYXRlVGltZSk7Ci0gICAgICAgICAgICBTaW1wbGVEYXRlRm9ybWF0IG91dEZvcm1hdCA9IG5ldyBTaW1wbGVEYXRlRm9ybWF0KHN0cmlwKHllYXJTeW1ib2xzLCBwYXR0ZXJuKSk7Ci0gICAgICAgICAgICBvdXRGb3JtYXQuc2V0VGltZVpvbmUodGltZVpvbmUpOwotICAgICAgICAgICAgcmV0dXJuIG91dEZvcm1hdC5mb3JtYXQoZCk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKFBhcnNlRXhjZXB0aW9uIHBlKQotICAgICAgICB7Ci0gICAgICAgIH0KLSAgICAgICAgdHJ5Ci0gICAgICAgIHsKLSAgICAgICAgICAgIFNpbXBsZURhdGVGb3JtYXQgaW5Gb3JtYXQgPSBuZXcgU2ltcGxlRGF0ZUZvcm1hdChnbSk7Ci0gICAgICAgICAgICBpbkZvcm1hdC5zZXRMZW5pZW50KGZhbHNlKTsKLSAgICAgICAgICAgIERhdGUgZCA9IGluRm9ybWF0LnBhcnNlKGRhdGVUaW1lKTsKLSAgICAgICAgICAgIFNpbXBsZURhdGVGb3JtYXQgb3V0Rm9ybWF0ID0gbmV3IFNpbXBsZURhdGVGb3JtYXQoc3RyaXAoeWVhclN5bWJvbHMsIHBhdHRlcm4pKTsKLSAgICAgICAgICAgIG91dEZvcm1hdC5zZXRUaW1lWm9uZSh0aW1lWm9uZSk7Ci0gICAgICAgICAgICByZXR1cm4gb3V0Rm9ybWF0LmZvcm1hdChkKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoUGFyc2VFeGNlcHRpb24gcGUpCi0gICAgICAgIHsKLSAgICAgICAgfQotICAgICAgICB0cnkKLSAgICAgICAgewotICAgICAgICAgICAgU2ltcGxlRGF0ZUZvcm1hdCBpbkZvcm1hdCA9IG5ldyBTaW1wbGVEYXRlRm9ybWF0KGdkKTsKLSAgICAgICAgICAgIGluRm9ybWF0LnNldExlbmllbnQoZmFsc2UpOwotICAgICAgICAgICAgRGF0ZSBkID0gaW5Gb3JtYXQucGFyc2UoZGF0ZVRpbWUpOwotICAgICAgICAgICAgU2ltcGxlRGF0ZUZvcm1hdCBvdXRGb3JtYXQgPSBuZXcgU2ltcGxlRGF0ZUZvcm1hdChzdHJpcCh5ZWFyU3ltYm9scyArIG1vbnRoU3ltYm9scywgcGF0dGVybikpOwotICAgICAgICAgICAgb3V0Rm9ybWF0LnNldFRpbWVab25lKHRpbWVab25lKTsKLSAgICAgICAgICAgIHJldHVybiBvdXRGb3JtYXQuZm9ybWF0KGQpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChQYXJzZUV4Y2VwdGlvbiBwZSkKLSAgICAgICAgewotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBFTVBUWV9TVFI7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU3RyaXBzIG9jY3VycmVuY2VzIG9mIHRoZSBnaXZlbiBjaGFyYWN0ZXIgZnJvbSBhIGRhdGUgZm9ybWF0IHBhdHRlcm4uCi0gICAgICogQHBhcmFtIHN5bWJvbHMgbGlzdCBvZiBzeW1ib2xzIHRvIHN0cmlwLgotICAgICAqIEBwYXJhbSBwYXR0ZXJuCi0gICAgICogQHJldHVybgotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBzdHJpcChTdHJpbmcgc3ltYm9scywgU3RyaW5nIHBhdHRlcm4pCi0gICAgewotICAgICAgICBpbnQgcXVvdGVTZW1hcGhvcmUgPSAwOwotICAgICAgICBpbnQgaSA9IDA7Ci0gICAgICAgIFN0cmluZ0J1ZmZlciByZXN1bHQgPSBuZXcgU3RyaW5nQnVmZmVyKHBhdHRlcm4ubGVuZ3RoKCkpOwotCi0gICAgICAgIHdoaWxlIChpIDwgcGF0dGVybi5sZW5ndGgoKSkKLSAgICAgICAgewotICAgICAgICAgICAgY2hhciBjaCA9IHBhdHRlcm4uY2hhckF0KGkpOwotICAgICAgICAgICAgaWYgKGNoID09ICdcJycpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgLy8gQXNzdW1lIGl0J3MgYW4gb3BlbmVuaW5nIHF1b3RlIHNvIHNpbXBseSBjb3B5IHRoZSBxdW90ZWQKLSAgICAgICAgICAgICAgICAvLyB0ZXh0IHRvIHRoZSByZXN1bHQuIFRoZXJlIGlzIG5vdGhpbmcgdG8gc3RyaXAgaGVyZS4KLSAgICAgICAgICAgICAgICBpbnQgZW5kUXVvdGUgPSBwYXR0ZXJuLmluZGV4T2YoJ1wnJywgaSArIDEpOwotICAgICAgICAgICAgICAgIGlmIChlbmRRdW90ZSA9PSAtMSkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIGVuZFF1b3RlID0gcGF0dGVybi5sZW5ndGgoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChwYXR0ZXJuLnN1YnN0cmluZyhpLCBlbmRRdW90ZSkpOwotICAgICAgICAgICAgICAgIGkgPSBlbmRRdW90ZSsrOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoc3ltYm9scy5pbmRleE9mKGNoKSA+IC0xKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIC8vIFRoZSBjaGFyIG5lZWRzIHRvIGJlIHN0cmlwcGVkLgotICAgICAgICAgICAgICAgIGkrKzsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICByZXN1bHQuYXBwZW5kKGNoKTsKLSAgICAgICAgICAgICAgICBpKys7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHJlc3VsdC50b1N0cmluZygpOwotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC9saWIvRXhzbHREeW5hbWljLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL2xpYi9FeHNsdER5bmFtaWMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggN2Y1NWQ4OS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL2xpYi9FeHNsdER5bmFtaWMuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDYxNiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBFeHNsdER5bmFtaWMuamF2YSx2IDEuMS4yLjEgMjAwNS8wOC8wMSAwMjowODo1MSBqZWZmc3V0dG9yIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLmxpYjsKLQotaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlcjsKLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5OwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwuZXh0ZW5zaW9ucy5FeHByZXNzaW9uQ29udGV4dDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwucmVzLlhTTE1lc3NhZ2VzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC5yZXMuWFNMVEVycm9yUmVzb3VyY2VzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5Ob2RlU2V0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5Ob2RlU2V0RFRNOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5YUGF0aDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuWFBhdGhDb250ZXh0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhCb29sZWFuOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhOb2RlU2V0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhOdW1iZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWE9iamVjdDsKLQotaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLkVsZW1lbnQ7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlTGlzdDsKLWltcG9ydCBvcmcudzNjLmRvbS5UZXh0OwotCi1pbXBvcnQgb3JnLnhtbC5zYXguU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgY29udGFpbnMgRVhTTFQgZHluYW1pYyBleHRlbnNpb24gZnVuY3Rpb25zLgotICoKLSAqIEl0IGlzIGFjY2Vzc2VkIGJ5IHNwZWNpZnlpbmcgYSBuYW1lc3BhY2UgVVJJIGFzIGZvbGxvd3M6Ci0gKiA8cHJlPgotICogICAgeG1sbnM6ZHluPSJodHRwOi8vZXhzbHQub3JnL2R5bmFtaWMiCi0gKiA8L3ByZT4KLSAqIFRoZSBkb2N1bWVudGF0aW9uIGZvciBlYWNoIGZ1bmN0aW9uIGhhcyBiZWVuIGNvcGllZCBmcm9tIHRoZSByZWxldmFudAotICogRVhTTFQgSW1wbGVtZW50ZXIgcGFnZS4KLSAqCi0gKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cuZXhzbHQub3JnLyI+RVhTTFQ8L2E+Ci0KLSAqIEB4c2wudXNhZ2UgZ2VuZXJhbAotICovCi1wdWJsaWMgY2xhc3MgRXhzbHREeW5hbWljIGV4dGVuZHMgRXhzbHRCYXNlCi17Ci0KLSAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVYU0xfVVJJID0gImh0dHA6Ly9leHNsdC5vcmcvY29tbW9uIjsKLQotICAvKioKLSAgICogVGhlIGR5bjptYXggZnVuY3Rpb24gY2FsY3VsYXRlcyB0aGUgbWF4aW11bSB2YWx1ZSBmb3IgdGhlIG5vZGVzIHBhc3NlZCBhcwotICAgKiB0aGUgZmlyc3QgYXJndW1lbnQsIHdoZXJlIHRoZSB2YWx1ZSBvZiBlYWNoIG5vZGUgaXMgY2FsY3VsYXRlZCBkeW5hbWljYWxseQotICAgKiB1c2luZyBhbiBYUGF0aCBleHByZXNzaW9uIHBhc3NlZCBhcyBhIHN0cmluZyBhcyB0aGUgc2Vjb25kIGFyZ3VtZW50LgotICAgKiA8cD4KLSAgICogVGhlIGV4cHJlc3Npb25zIGFyZSBldmFsdWF0ZWQgcmVsYXRpdmUgdG8gdGhlIG5vZGVzIHBhc3NlZCBhcyB0aGUgZmlyc3QgYXJndW1lbnQuCi0gICAqIEluIG90aGVyIHdvcmRzLCB0aGUgdmFsdWUgZm9yIGVhY2ggbm9kZSBpcyBjYWxjdWxhdGVkIGJ5IGV2YWx1YXRpbmcgdGhlIFhQYXRoCi0gICAqIGV4cHJlc3Npb24gd2l0aCBhbGwgY29udGV4dCBpbmZvcm1hdGlvbiBiZWluZyB0aGUgc2FtZSBhcyB0aGF0IGZvciB0aGUgY2FsbCB0bwotICAgKiB0aGUgZHluOm1heCBmdW5jdGlvbiBpdHNlbGYsIGV4Y2VwdCBmb3IgdGhlIGZvbGxvd2luZzoKLSAgICogPHA+Ci0gICAqIDx1bD4KLSAgICogIDxsaT50aGUgY29udGV4dCBub2RlIGlzIHRoZSBub2RlIHdob3NlIHZhbHVlIGlzIGJlaW5nIGNhbGN1bGF0ZWQuPC9saT4KLSAgICogIDxsaT50aGUgY29udGV4dCBwb3NpdGlvbiBpcyB0aGUgcG9zaXRpb24gb2YgdGhlIG5vZGUgd2l0aGluIHRoZSBub2RlIHNldCBwYXNzZWQgYXMKLSAgICogICB0aGUgZmlyc3QgYXJndW1lbnQgdG8gdGhlIGR5bjptYXggZnVuY3Rpb24sIGFycmFuZ2VkIGluIGRvY3VtZW50IG9yZGVyLjwvbGk+Ci0gICAqICA8bGk+dGhlIGNvbnRleHQgc2l6ZSBpcyB0aGUgbnVtYmVyIG9mIG5vZGVzIHBhc3NlZCBhcyB0aGUgZmlyc3QgYXJndW1lbnQgdG8gdGhlCi0gICAqICAgZHluOm1heCBmdW5jdGlvbi48L2xpPgotICAgKiA8L3VsPgotICAgKiA8cD4KLSAgICogVGhlIGR5bjptYXggZnVuY3Rpb24gcmV0dXJucyB0aGUgbWF4aW11bSBvZiB0aGVzZSB2YWx1ZXMsIGNhbGN1bGF0ZWQgaW4gZXhhY3RseQotICAgKiB0aGUgc2FtZSB3YXkgYXMgZm9yIG1hdGg6bWF4LgotICAgKiA8cD4KLSAgICogSWYgdGhlIGV4cHJlc3Npb24gc3RyaW5nIHBhc3NlZCBhcyB0aGUgc2Vjb25kIGFyZ3VtZW50IGlzIGFuIGludmFsaWQgWFBhdGgKLSAgICogZXhwcmVzc2lvbiAoaW5jbHVkaW5nIGFuIGVtcHR5IHN0cmluZyksIHRoaXMgZnVuY3Rpb24gcmV0dXJucyBOYU4uCi0gICAqIDxwPgotICAgKiBUaGlzIGZ1bmN0aW9uIG11c3QgdGFrZSBhIHNlY29uZCBhcmd1bWVudC4gVG8gY2FsY3VsYXRlIHRoZSBtYXhpbXVtIG9mIGEgc2V0IG9mCi0gICAqIG5vZGVzIGJhc2VkIG9uIHRoZWlyIHN0cmluZyB2YWx1ZXMsIHlvdSBzaG91bGQgdXNlIHRoZSBtYXRoOm1heCBmdW5jdGlvbi4KLSAgICoKLSAgICogQHBhcmFtIG15Q29udGV4dCBUaGUgRXhwcmVzc2lvbkNvbnRleHQgcGFzc2VkIGJ5IHRoZSBleHRlbnNpb24gcHJvY2Vzc29yCi0gICAqIEBwYXJhbSBubCBUaGUgbm9kZSBzZXQKLSAgICogQHBhcmFtIGV4cHIgVGhlIGV4cHJlc3Npb24gc3RyaW5nCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIG1heGltdW0gZXZhbHVhdGlvbiB2YWx1ZQotICAgKi8KLSAgcHVibGljIHN0YXRpYyBkb3VibGUgbWF4KEV4cHJlc3Npb25Db250ZXh0IG15Q29udGV4dCwgTm9kZUxpc3QgbmwsIFN0cmluZyBleHByKQotICAgIHRocm93cyBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24KLSAgewotCi0gICAgWFBhdGhDb250ZXh0IHhjdHh0ID0gbnVsbDsKLSAgICBpZiAobXlDb250ZXh0IGluc3RhbmNlb2YgWFBhdGhDb250ZXh0LlhQYXRoRXhwcmVzc2lvbkNvbnRleHQpCi0gICAgICB4Y3R4dCA9ICgoWFBhdGhDb250ZXh0LlhQYXRoRXhwcmVzc2lvbkNvbnRleHQpIG15Q29udGV4dCkuZ2V0WFBhdGhDb250ZXh0KCk7Ci0gICAgZWxzZQotICAgICAgdGhyb3cgbmV3IFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9JTlZBTElEX0NPTlRFWFRfUEFTU0VELCBuZXcgT2JqZWN0W117bXlDb250ZXh0IH0pKTsKLQotICAgIGlmIChleHByID09IG51bGwgfHwgZXhwci5sZW5ndGgoKSA9PSAwKQotICAgICAgcmV0dXJuIERvdWJsZS5OYU47Ci0KLSAgICBOb2RlU2V0RFRNIGNvbnRleHROb2RlcyA9IG5ldyBOb2RlU2V0RFRNKG5sLCB4Y3R4dCk7Ci0gICAgeGN0eHQucHVzaENvbnRleHROb2RlTGlzdChjb250ZXh0Tm9kZXMpOwotCi0gICAgZG91YmxlIG1heFZhbHVlID0gLSBEb3VibGUuTUFYX1ZBTFVFOwotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY29udGV4dE5vZGVzLmdldExlbmd0aCgpOyBpKyspCi0gICAgewotICAgICAgaW50IGNvbnRleHROb2RlID0gY29udGV4dE5vZGVzLml0ZW0oaSk7Ci0gICAgICB4Y3R4dC5wdXNoQ3VycmVudE5vZGUoY29udGV4dE5vZGUpOwotCi0gICAgICBkb3VibGUgcmVzdWx0ID0gMDsKLSAgICAgIHRyeQotICAgICAgewotICAgICAgICBYUGF0aCBkeW5hbWljWFBhdGggPSBuZXcgWFBhdGgoZXhwciwgeGN0eHQuZ2V0U0FYTG9jYXRvcigpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeGN0eHQuZ2V0TmFtZXNwYWNlQ29udGV4dCgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWFBhdGguU0VMRUNUKTsKLSAgICAgICAgcmVzdWx0ID0gZHluYW1pY1hQYXRoLmV4ZWN1dGUoeGN0eHQsIGNvbnRleHROb2RlLCB4Y3R4dC5nZXROYW1lc3BhY2VDb250ZXh0KCkpLm51bSgpOwotICAgICAgfQotICAgICAgY2F0Y2ggKFRyYW5zZm9ybWVyRXhjZXB0aW9uIGUpCi0gICAgICB7Ci0gICAgICAgIHhjdHh0LnBvcEN1cnJlbnROb2RlKCk7Ci0gICAgICAgIHhjdHh0LnBvcENvbnRleHROb2RlTGlzdCgpOwotICAgICAgICByZXR1cm4gRG91YmxlLk5hTjsKLSAgICAgIH0KLQotICAgICAgeGN0eHQucG9wQ3VycmVudE5vZGUoKTsKLQotICAgICAgaWYgKHJlc3VsdCA+IG1heFZhbHVlKQotICAgICAgICAgIG1heFZhbHVlID0gcmVzdWx0OwotICAgIH0KLQotICAgIHhjdHh0LnBvcENvbnRleHROb2RlTGlzdCgpOwotICAgIHJldHVybiBtYXhWYWx1ZTsKLQotICB9Ci0KLSAgLyoqCi0gICAqIFRoZSBkeW46bWluIGZ1bmN0aW9uIGNhbGN1bGF0ZXMgdGhlIG1pbmltdW0gdmFsdWUgZm9yIHRoZSBub2RlcyBwYXNzZWQgYXMgdGhlCi0gICAqIGZpcnN0IGFyZ3VtZW50LCB3aGVyZSB0aGUgdmFsdWUgb2YgZWFjaCBub2RlIGlzIGNhbGN1bGF0ZWQgZHluYW1pY2FsbHkgdXNpbmcKLSAgICogYW4gWFBhdGggZXhwcmVzc2lvbiBwYXNzZWQgYXMgYSBzdHJpbmcgYXMgdGhlIHNlY29uZCBhcmd1bWVudC4KLSAgICogPHA+Ci0gICAqIFRoZSBleHByZXNzaW9ucyBhcmUgZXZhbHVhdGVkIHJlbGF0aXZlIHRvIHRoZSBub2RlcyBwYXNzZWQgYXMgdGhlIGZpcnN0IGFyZ3VtZW50LgotICAgKiBJbiBvdGhlciB3b3JkcywgdGhlIHZhbHVlIGZvciBlYWNoIG5vZGUgaXMgY2FsY3VsYXRlZCBieSBldmFsdWF0aW5nIHRoZSBYUGF0aAotICAgKiBleHByZXNzaW9uIHdpdGggYWxsIGNvbnRleHQgaW5mb3JtYXRpb24gYmVpbmcgdGhlIHNhbWUgYXMgdGhhdCBmb3IgdGhlIGNhbGwgdG8KLSAgICogdGhlIGR5bjptaW4gZnVuY3Rpb24gaXRzZWxmLCBleGNlcHQgZm9yIHRoZSBmb2xsb3dpbmc6Ci0gICAqIDxwPgotICAgKiA8dWw+Ci0gICAqICA8bGk+dGhlIGNvbnRleHQgbm9kZSBpcyB0aGUgbm9kZSB3aG9zZSB2YWx1ZSBpcyBiZWluZyBjYWxjdWxhdGVkLjwvbGk+Ci0gICAqICA8bGk+dGhlIGNvbnRleHQgcG9zaXRpb24gaXMgdGhlIHBvc2l0aW9uIG9mIHRoZSBub2RlIHdpdGhpbiB0aGUgbm9kZSBzZXQgcGFzc2VkCi0gICAqICAgIGFzIHRoZSBmaXJzdCBhcmd1bWVudCB0byB0aGUgZHluOm1pbiBmdW5jdGlvbiwgYXJyYW5nZWQgaW4gZG9jdW1lbnQgb3JkZXIuPC9saT4KLSAgICogIDxsaT50aGUgY29udGV4dCBzaXplIGlzIHRoZSBudW1iZXIgb2Ygbm9kZXMgcGFzc2VkIGFzIHRoZSBmaXJzdCBhcmd1bWVudCB0byB0aGUKLSAgICogICAgZHluOm1pbiBmdW5jdGlvbi48L2xpPgotICAgKiA8L3VsPgotICAgKiA8cD4KLSAgICogVGhlIGR5bjptaW4gZnVuY3Rpb24gcmV0dXJucyB0aGUgbWluaW11bSBvZiB0aGVzZSB2YWx1ZXMsIGNhbGN1bGF0ZWQgaW4gZXhhY3RseQotICAgKiB0aGUgc2FtZSB3YXkgYXMgZm9yIG1hdGg6bWluLgotICAgKiA8cD4KLSAgICogSWYgdGhlIGV4cHJlc3Npb24gc3RyaW5nIHBhc3NlZCBhcyB0aGUgc2Vjb25kIGFyZ3VtZW50IGlzIGFuIGludmFsaWQgWFBhdGggZXhwcmVzc2lvbgotICAgKiAoaW5jbHVkaW5nIGFuIGVtcHR5IHN0cmluZyksIHRoaXMgZnVuY3Rpb24gcmV0dXJucyBOYU4uCi0gICAqIDxwPgotICAgKiBUaGlzIGZ1bmN0aW9uIG11c3QgdGFrZSBhIHNlY29uZCBhcmd1bWVudC4gVG8gY2FsY3VsYXRlIHRoZSBtaW5pbXVtIG9mIGEgc2V0IG9mCi0gICAqIG5vZGVzIGJhc2VkIG9uIHRoZWlyIHN0cmluZyB2YWx1ZXMsIHlvdSBzaG91bGQgdXNlIHRoZSBtYXRoOm1pbiBmdW5jdGlvbi4KLSAgICoKLSAgICogQHBhcmFtIG15Q29udGV4dCBUaGUgRXhwcmVzc2lvbkNvbnRleHQgcGFzc2VkIGJ5IHRoZSBleHRlbnNpb24gcHJvY2Vzc29yCi0gICAqIEBwYXJhbSBubCBUaGUgbm9kZSBzZXQKLSAgICogQHBhcmFtIGV4cHIgVGhlIGV4cHJlc3Npb24gc3RyaW5nCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIG1pbmltdW0gZXZhbHVhdGlvbiB2YWx1ZQotICAgKi8KLSAgcHVibGljIHN0YXRpYyBkb3VibGUgbWluKEV4cHJlc3Npb25Db250ZXh0IG15Q29udGV4dCwgTm9kZUxpc3QgbmwsIFN0cmluZyBleHByKQotICAgIHRocm93cyBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24KLSAgewotCi0gICAgWFBhdGhDb250ZXh0IHhjdHh0ID0gbnVsbDsKLSAgICBpZiAobXlDb250ZXh0IGluc3RhbmNlb2YgWFBhdGhDb250ZXh0LlhQYXRoRXhwcmVzc2lvbkNvbnRleHQpCi0gICAgICB4Y3R4dCA9ICgoWFBhdGhDb250ZXh0LlhQYXRoRXhwcmVzc2lvbkNvbnRleHQpIG15Q29udGV4dCkuZ2V0WFBhdGhDb250ZXh0KCk7Ci0gICAgZWxzZQotICAgICAgdGhyb3cgbmV3IFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9JTlZBTElEX0NPTlRFWFRfUEFTU0VELCBuZXcgT2JqZWN0W117bXlDb250ZXh0IH0pKTsKLQotICAgIGlmIChleHByID09IG51bGwgfHwgZXhwci5sZW5ndGgoKSA9PSAwKQotICAgICAgcmV0dXJuIERvdWJsZS5OYU47Ci0KLSAgICBOb2RlU2V0RFRNIGNvbnRleHROb2RlcyA9IG5ldyBOb2RlU2V0RFRNKG5sLCB4Y3R4dCk7Ci0gICAgeGN0eHQucHVzaENvbnRleHROb2RlTGlzdChjb250ZXh0Tm9kZXMpOwotCi0gICAgZG91YmxlIG1pblZhbHVlID0gRG91YmxlLk1BWF9WQUxVRTsKLSAgICBmb3IgKGludCBpID0gMDsgaSA8IG5sLmdldExlbmd0aCgpOyBpKyspCi0gICAgewotICAgICAgaW50IGNvbnRleHROb2RlID0gY29udGV4dE5vZGVzLml0ZW0oaSk7Ci0gICAgICB4Y3R4dC5wdXNoQ3VycmVudE5vZGUoY29udGV4dE5vZGUpOwotCi0gICAgICBkb3VibGUgcmVzdWx0ID0gMDsKLSAgICAgIHRyeQotICAgICAgewotICAgICAgICBYUGF0aCBkeW5hbWljWFBhdGggPSBuZXcgWFBhdGgoZXhwciwgeGN0eHQuZ2V0U0FYTG9jYXRvcigpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeGN0eHQuZ2V0TmFtZXNwYWNlQ29udGV4dCgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWFBhdGguU0VMRUNUKTsKLSAgICAgICAgcmVzdWx0ID0gZHluYW1pY1hQYXRoLmV4ZWN1dGUoeGN0eHQsIGNvbnRleHROb2RlLCB4Y3R4dC5nZXROYW1lc3BhY2VDb250ZXh0KCkpLm51bSgpOwotICAgICAgfQotICAgICAgY2F0Y2ggKFRyYW5zZm9ybWVyRXhjZXB0aW9uIGUpCi0gICAgICB7Ci0gICAgICAgIHhjdHh0LnBvcEN1cnJlbnROb2RlKCk7Ci0gICAgICAgIHhjdHh0LnBvcENvbnRleHROb2RlTGlzdCgpOwotICAgICAgICByZXR1cm4gRG91YmxlLk5hTjsKLSAgICAgIH0KLQotICAgICAgeGN0eHQucG9wQ3VycmVudE5vZGUoKTsKLQotICAgICAgaWYgKHJlc3VsdCA8IG1pblZhbHVlKQotICAgICAgICAgIG1pblZhbHVlID0gcmVzdWx0OwotICAgIH0KLQotICAgIHhjdHh0LnBvcENvbnRleHROb2RlTGlzdCgpOwotICAgIHJldHVybiBtaW5WYWx1ZTsKLQotICB9Ci0KLSAgLyoqCi0gICAqIFRoZSBkeW46c3VtIGZ1bmN0aW9uIGNhbGN1bGF0ZXMgdGhlIHN1bSBmb3IgdGhlIG5vZGVzIHBhc3NlZCBhcyB0aGUgZmlyc3QgYXJndW1lbnQsCi0gICAqIHdoZXJlIHRoZSB2YWx1ZSBvZiBlYWNoIG5vZGUgaXMgY2FsY3VsYXRlZCBkeW5hbWljYWxseSB1c2luZyBhbiBYUGF0aCBleHByZXNzaW9uCi0gICAqIHBhc3NlZCBhcyBhIHN0cmluZyBhcyB0aGUgc2Vjb25kIGFyZ3VtZW50LgotICAgKiA8cD4KLSAgICogVGhlIGV4cHJlc3Npb25zIGFyZSBldmFsdWF0ZWQgcmVsYXRpdmUgdG8gdGhlIG5vZGVzIHBhc3NlZCBhcyB0aGUgZmlyc3QgYXJndW1lbnQuCi0gICAqIEluIG90aGVyIHdvcmRzLCB0aGUgdmFsdWUgZm9yIGVhY2ggbm9kZSBpcyBjYWxjdWxhdGVkIGJ5IGV2YWx1YXRpbmcgdGhlIFhQYXRoCi0gICAqIGV4cHJlc3Npb24gd2l0aCBhbGwgY29udGV4dCBpbmZvcm1hdGlvbiBiZWluZyB0aGUgc2FtZSBhcyB0aGF0IGZvciB0aGUgY2FsbCB0bwotICAgKiB0aGUgZHluOnN1bSBmdW5jdGlvbiBpdHNlbGYsIGV4Y2VwdCBmb3IgdGhlIGZvbGxvd2luZzoKLSAgICogPHA+Ci0gICAqIDx1bD4KLSAgICogIDxsaT50aGUgY29udGV4dCBub2RlIGlzIHRoZSBub2RlIHdob3NlIHZhbHVlIGlzIGJlaW5nIGNhbGN1bGF0ZWQuPC9saT4KLSAgICogIDxsaT50aGUgY29udGV4dCBwb3NpdGlvbiBpcyB0aGUgcG9zaXRpb24gb2YgdGhlIG5vZGUgd2l0aGluIHRoZSBub2RlIHNldCBwYXNzZWQgYXMKLSAgICogICAgdGhlIGZpcnN0IGFyZ3VtZW50IHRvIHRoZSBkeW46c3VtIGZ1bmN0aW9uLCBhcnJhbmdlZCBpbiBkb2N1bWVudCBvcmRlci48L2xpPgotICAgKiAgPGxpPnRoZSBjb250ZXh0IHNpemUgaXMgdGhlIG51bWJlciBvZiBub2RlcyBwYXNzZWQgYXMgdGhlIGZpcnN0IGFyZ3VtZW50IHRvIHRoZQotICAgKiAgICBkeW46c3VtIGZ1bmN0aW9uLjwvbGk+Ci0gICAqIDwvdWw+Ci0gICAqIDxwPgotICAgKiBUaGUgZHluOnN1bSBmdW5jdGlvbiByZXR1cm5zIHRoZSBzdW1pbXVtIG9mIHRoZXNlIHZhbHVlcywgY2FsY3VsYXRlZCBpbiBleGFjdGx5Ci0gICAqIHRoZSBzYW1lIHdheSBhcyBmb3Igc3VtLgotICAgKiA8cD4KLSAgICogSWYgdGhlIGV4cHJlc3Npb24gc3RyaW5nIHBhc3NlZCBhcyB0aGUgc2Vjb25kIGFyZ3VtZW50IGlzIGFuIGludmFsaWQgWFBhdGgKLSAgICogZXhwcmVzc2lvbiAoaW5jbHVkaW5nIGFuIGVtcHR5IHN0cmluZyksIHRoaXMgZnVuY3Rpb24gcmV0dXJucyBOYU4uCi0gICAqIDxwPgotICAgKiBUaGlzIGZ1bmN0aW9uIG11c3QgdGFrZSBhIHNlY29uZCBhcmd1bWVudC4gVG8gY2FsY3VsYXRlIHRoZSBzdW1pbXVtIG9mIGEgc2V0IG9mCi0gICAqIG5vZGVzIGJhc2VkIG9uIHRoZWlyIHN0cmluZyB2YWx1ZXMsIHlvdSBzaG91bGQgdXNlIHRoZSBzdW0gZnVuY3Rpb24uCi0gICAqCi0gICAqIEBwYXJhbSBteUNvbnRleHQgVGhlIEV4cHJlc3Npb25Db250ZXh0IHBhc3NlZCBieSB0aGUgZXh0ZW5zaW9uIHByb2Nlc3NvcgotICAgKiBAcGFyYW0gbmwgVGhlIG5vZGUgc2V0Ci0gICAqIEBwYXJhbSBleHByIFRoZSBleHByZXNzaW9uIHN0cmluZwotICAgKgotICAgKiBAcmV0dXJuIFRoZSBzdW0gb2YgdGhlIGV2YWx1YXRpb24gdmFsdWUgb24gZWFjaCBub2RlCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGRvdWJsZSBzdW0oRXhwcmVzc2lvbkNvbnRleHQgbXlDb250ZXh0LCBOb2RlTGlzdCBubCwgU3RyaW5nIGV4cHIpCi0gICAgdGhyb3dzIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbgotICB7Ci0gICAgWFBhdGhDb250ZXh0IHhjdHh0ID0gbnVsbDsKLSAgICBpZiAobXlDb250ZXh0IGluc3RhbmNlb2YgWFBhdGhDb250ZXh0LlhQYXRoRXhwcmVzc2lvbkNvbnRleHQpCi0gICAgICB4Y3R4dCA9ICgoWFBhdGhDb250ZXh0LlhQYXRoRXhwcmVzc2lvbkNvbnRleHQpIG15Q29udGV4dCkuZ2V0WFBhdGhDb250ZXh0KCk7Ci0gICAgZWxzZQotICAgICAgdGhyb3cgbmV3IFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9JTlZBTElEX0NPTlRFWFRfUEFTU0VELCBuZXcgT2JqZWN0W117bXlDb250ZXh0IH0pKTsKLQotICAgIGlmIChleHByID09IG51bGwgfHwgZXhwci5sZW5ndGgoKSA9PSAwKQotICAgICAgcmV0dXJuIERvdWJsZS5OYU47Ci0KLSAgICBOb2RlU2V0RFRNIGNvbnRleHROb2RlcyA9IG5ldyBOb2RlU2V0RFRNKG5sLCB4Y3R4dCk7Ci0gICAgeGN0eHQucHVzaENvbnRleHROb2RlTGlzdChjb250ZXh0Tm9kZXMpOwotCi0gICAgZG91YmxlIHN1bSA9IDA7Ci0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBubC5nZXRMZW5ndGgoKTsgaSsrKQotICAgIHsKLSAgICAgIGludCBjb250ZXh0Tm9kZSA9IGNvbnRleHROb2Rlcy5pdGVtKGkpOwotICAgICAgeGN0eHQucHVzaEN1cnJlbnROb2RlKGNvbnRleHROb2RlKTsKLQotICAgICAgZG91YmxlIHJlc3VsdCA9IDA7Ci0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgWFBhdGggZHluYW1pY1hQYXRoID0gbmV3IFhQYXRoKGV4cHIsIHhjdHh0LmdldFNBWExvY2F0b3IoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhjdHh0LmdldE5hbWVzcGFjZUNvbnRleHQoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhQYXRoLlNFTEVDVCk7Ci0gICAgICAgIHJlc3VsdCA9IGR5bmFtaWNYUGF0aC5leGVjdXRlKHhjdHh0LCBjb250ZXh0Tm9kZSwgeGN0eHQuZ2V0TmFtZXNwYWNlQ29udGV4dCgpKS5udW0oKTsKLSAgICAgIH0KLSAgICAgIGNhdGNoIChUcmFuc2Zvcm1lckV4Y2VwdGlvbiBlKQotICAgICAgewotICAgICAgICB4Y3R4dC5wb3BDdXJyZW50Tm9kZSgpOwotICAgICAgICB4Y3R4dC5wb3BDb250ZXh0Tm9kZUxpc3QoKTsKLSAgICAgICAgcmV0dXJuIERvdWJsZS5OYU47Ci0gICAgICB9Ci0KLSAgICAgIHhjdHh0LnBvcEN1cnJlbnROb2RlKCk7Ci0KLSAgICAgIHN1bSA9IHN1bSArIHJlc3VsdDsKLQotICAgIH0KLQotICAgIHhjdHh0LnBvcENvbnRleHROb2RlTGlzdCgpOwotICAgIHJldHVybiBzdW07Ci0gIH0KLQotICAvKioKLSAgICogVGhlIGR5bjptYXAgZnVuY3Rpb24gZXZhbHVhdGVzIHRoZSBleHByZXNzaW9uIHBhc3NlZCBhcyB0aGUgc2Vjb25kIGFyZ3VtZW50IGZvcgotICAgKiBlYWNoIG9mIHRoZSBub2RlcyBwYXNzZWQgYXMgdGhlIGZpcnN0IGFyZ3VtZW50LCBhbmQgcmV0dXJucyBhIG5vZGUgc2V0IG9mIHRob3NlIHZhbHVlcy4KLSAgICogPHA+Ci0gICAqIFRoZSBleHByZXNzaW9ucyBhcmUgZXZhbHVhdGVkIHJlbGF0aXZlIHRvIHRoZSBub2RlcyBwYXNzZWQgYXMgdGhlIGZpcnN0IGFyZ3VtZW50LgotICAgKiBJbiBvdGhlciB3b3JkcywgdGhlIHZhbHVlIGZvciBlYWNoIG5vZGUgaXMgY2FsY3VsYXRlZCBieSBldmFsdWF0aW5nIHRoZSBYUGF0aAotICAgKiBleHByZXNzaW9uIHdpdGggYWxsIGNvbnRleHQgaW5mb3JtYXRpb24gYmVpbmcgdGhlIHNhbWUgYXMgdGhhdCBmb3IgdGhlIGNhbGwgdG8KLSAgICogdGhlIGR5bjptYXAgZnVuY3Rpb24gaXRzZWxmLCBleGNlcHQgZm9yIHRoZSBmb2xsb3dpbmc6Ci0gICAqIDxwPgotICAgKiA8dWw+Ci0gICAqICA8bGk+VGhlIGNvbnRleHQgbm9kZSBpcyB0aGUgbm9kZSB3aG9zZSB2YWx1ZSBpcyBiZWluZyBjYWxjdWxhdGVkLjwvbGk+Ci0gICAqICA8bGk+dGhlIGNvbnRleHQgcG9zaXRpb24gaXMgdGhlIHBvc2l0aW9uIG9mIHRoZSBub2RlIHdpdGhpbiB0aGUgbm9kZSBzZXQgcGFzc2VkCi0gICAqICAgIGFzIHRoZSBmaXJzdCBhcmd1bWVudCB0byB0aGUgZHluOm1hcCBmdW5jdGlvbiwgYXJyYW5nZWQgaW4gZG9jdW1lbnQgb3JkZXIuPC9saT4KLSAgICogIDxsaT50aGUgY29udGV4dCBzaXplIGlzIHRoZSBudW1iZXIgb2Ygbm9kZXMgcGFzc2VkIGFzIHRoZSBmaXJzdCBhcmd1bWVudCB0byB0aGUKLSAgICogICAgZHluOm1hcCBmdW5jdGlvbi48L2xpPgotICAgKiA8L3VsPgotICAgKiA8cD4KLSAgICogSWYgdGhlIGV4cHJlc3Npb24gc3RyaW5nIHBhc3NlZCBhcyB0aGUgc2Vjb25kIGFyZ3VtZW50IGlzIGFuIGludmFsaWQgWFBhdGgKLSAgICogZXhwcmVzc2lvbiAoaW5jbHVkaW5nIGFuIGVtcHR5IHN0cmluZyksIHRoaXMgZnVuY3Rpb24gcmV0dXJucyBhbiBlbXB0eSBub2RlIHNldC4KLSAgICogPHA+Ci0gICAqIElmIHRoZSBYUGF0aCBleHByZXNzaW9uIGV2YWx1YXRlcyBhcyBhIG5vZGUgc2V0LCB0aGUgZHluOm1hcCBmdW5jdGlvbiByZXR1cm5zCi0gICAqIHRoZSB1bmlvbiBvZiB0aGUgbm9kZSBzZXRzIHJldHVybmVkIGJ5IGV2YWx1YXRpbmcgdGhlIGV4cHJlc3Npb24gZm9yIGVhY2ggb2YgdGhlCi0gICAqIG5vZGVzIGluIHRoZSBmaXJzdCBhcmd1bWVudC4gTm90ZSB0aGF0IHRoaXMgbWF5IG1lYW4gdGhhdCB0aGUgbm9kZSBzZXQgcmVzdWx0aW5nCi0gICAqIGZyb20gdGhlIGNhbGwgdG8gdGhlIGR5bjptYXAgZnVuY3Rpb24gY29udGFpbnMgYSBkaWZmZXJlbnQgbnVtYmVyIG9mIG5vZGVzIGZyb20KLSAgICogdGhlIG51bWJlciBpbiB0aGUgbm9kZSBzZXQgcGFzc2VkIGFzIHRoZSBmaXJzdCBhcmd1bWVudCB0byB0aGUgZnVuY3Rpb24uCi0gICAqIDxwPgotICAgKiBJZiB0aGUgWFBhdGggZXhwcmVzc2lvbiBldmFsdWF0ZXMgYXMgYSBudW1iZXIsIHRoZSBkeW46bWFwIGZ1bmN0aW9uIHJldHVybnMgYQotICAgKiBub2RlIHNldCBjb250YWluaW5nIG9uZSBleHNsOm51bWJlciBlbGVtZW50IChuYW1lc3BhY2UgaHR0cDovL2V4c2x0Lm9yZy9jb21tb24pCi0gICAqIGZvciBlYWNoIG5vZGUgaW4gdGhlIG5vZGUgc2V0IHBhc3NlZCBhcyB0aGUgZmlyc3QgYXJndW1lbnQgdG8gdGhlIGR5bjptYXAgZnVuY3Rpb24sCi0gICAqIGluIGRvY3VtZW50IG9yZGVyLiBUaGUgc3RyaW5nIHZhbHVlIG9mIGVhY2ggZXhzbDpudW1iZXIgZWxlbWVudCBpcyB0aGUgc2FtZSBhcwotICAgKiB0aGUgcmVzdWx0IG9mIGNvbnZlcnRpbmcgdGhlIG51bWJlciByZXN1bHRpbmcgZnJvbSBldmFsdWF0aW5nIHRoZSBleHByZXNzaW9uIHRvCi0gICAqIGEgc3RyaW5nIGFzIHdpdGggdGhlIG51bWJlciBmdW5jdGlvbiwgd2l0aCB0aGUgZXhjZXB0aW9uIHRoYXQgSW5maW5pdHkgcmVzdWx0cwotICAgKiBpbiBhbiBleHNsOm51bWJlciBob2xkaW5nIHRoZSBoaWdoZXN0IG51bWJlciB0aGUgaW1wbGVtZW50YXRpb24gY2FuIHN0b3JlLCBhbmQKLSAgICogLUluZmluaXR5IHJlc3VsdHMgaW4gYW4gZXhzbDpudW1iZXIgaG9sZGluZyB0aGUgbG93ZXN0IG51bWJlciB0aGUgaW1wbGVtZW50YXRpb24KLSAgICogY2FuIHN0b3JlLgotICAgKiA8cD4KLSAgICogSWYgdGhlIFhQYXRoIGV4cHJlc3Npb24gZXZhbHVhdGVzIGFzIGEgYm9vbGVhbiwgdGhlIGR5bjptYXAgZnVuY3Rpb24gcmV0dXJucyBhCi0gICAqIG5vZGUgc2V0IGNvbnRhaW5pbmcgb25lIGV4c2w6Ym9vbGVhbiBlbGVtZW50IChuYW1lc3BhY2UgaHR0cDovL2V4c2x0Lm9yZy9jb21tb24pCi0gICAqIGZvciBlYWNoIG5vZGUgaW4gdGhlIG5vZGUgc2V0IHBhc3NlZCBhcyB0aGUgZmlyc3QgYXJndW1lbnQgdG8gdGhlIGR5bjptYXAgZnVuY3Rpb24sCi0gICAqIGluIGRvY3VtZW50IG9yZGVyLiBUaGUgc3RyaW5nIHZhbHVlIG9mIGVhY2ggZXhzbDpib29sZWFuIGVsZW1lbnQgaXMgJ3RydWUnIGlmIHRoZQotICAgKiBleHByZXNzaW9uIGV2YWx1YXRlcyBhcyB0cnVlIGZvciB0aGUgbm9kZSwgYW5kICcnIGlmIHRoZSBleHByZXNzaW9uIGV2YWx1YXRlcyBhcwotICAgKiBmYWxzZS4KLSAgICogPHA+Ci0gICAqIE90aGVyd2lzZSwgdGhlIGR5bjptYXAgZnVuY3Rpb24gcmV0dXJucyBhIG5vZGUgc2V0IGNvbnRhaW5pbmcgb25lIGV4c2w6c3RyaW5nCi0gICAqIGVsZW1lbnQgKG5hbWVzcGFjZSBodHRwOi8vZXhzbHQub3JnL2NvbW1vbikgZm9yIGVhY2ggbm9kZSBpbiB0aGUgbm9kZSBzZXQgcGFzc2VkCi0gICAqIGFzIHRoZSBmaXJzdCBhcmd1bWVudCB0byB0aGUgZHluOm1hcCBmdW5jdGlvbiwgaW4gZG9jdW1lbnQgb3JkZXIuIFRoZSBzdHJpbmcKLSAgICogdmFsdWUgb2YgZWFjaCBleHNsOnN0cmluZyBlbGVtZW50IGlzIHRoZSBzYW1lIGFzIHRoZSByZXN1bHQgb2YgY29udmVydGluZyB0aGUKLSAgICogcmVzdWx0IG9mIGV2YWx1YXRpbmcgdGhlIGV4cHJlc3Npb24gZm9yIHRoZSByZWxldmFudCBub2RlIHRvIGEgc3RyaW5nIGFzIHdpdGgKLSAgICogdGhlIHN0cmluZyBmdW5jdGlvbi4KLSAgICoKLSAgICogQHBhcmFtIG15Q29udGV4dCBUaGUgRXhwcmVzc2lvbkNvbnRleHQgcGFzc2VkIGJ5IHRoZSBleHRlbnNpb24gcHJvY2Vzc29yCi0gICAqIEBwYXJhbSBubCBUaGUgbm9kZSBzZXQKLSAgICogQHBhcmFtIGV4cHIgVGhlIGV4cHJlc3Npb24gc3RyaW5nCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIG5vZGUgc2V0IGFmdGVyIGV2YWx1YXRpb24KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgTm9kZUxpc3QgbWFwKEV4cHJlc3Npb25Db250ZXh0IG15Q29udGV4dCwgTm9kZUxpc3QgbmwsIFN0cmluZyBleHByKQotICAgIHRocm93cyBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24KLSAgewotICAgIFhQYXRoQ29udGV4dCB4Y3R4dCA9IG51bGw7Ci0gICAgRG9jdW1lbnQgbERvYyA9IG51bGw7Ci0KLSAgICBpZiAobXlDb250ZXh0IGluc3RhbmNlb2YgWFBhdGhDb250ZXh0LlhQYXRoRXhwcmVzc2lvbkNvbnRleHQpCi0gICAgICB4Y3R4dCA9ICgoWFBhdGhDb250ZXh0LlhQYXRoRXhwcmVzc2lvbkNvbnRleHQpIG15Q29udGV4dCkuZ2V0WFBhdGhDb250ZXh0KCk7Ci0gICAgZWxzZQotICAgICAgdGhyb3cgbmV3IFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9JTlZBTElEX0NPTlRFWFRfUEFTU0VELCBuZXcgT2JqZWN0W117bXlDb250ZXh0IH0pKTsKLQotICAgIGlmIChleHByID09IG51bGwgfHwgZXhwci5sZW5ndGgoKSA9PSAwKQotICAgICAgcmV0dXJuIG5ldyBOb2RlU2V0KCk7Ci0KLSAgICBOb2RlU2V0RFRNIGNvbnRleHROb2RlcyA9IG5ldyBOb2RlU2V0RFRNKG5sLCB4Y3R4dCk7Ci0gICAgeGN0eHQucHVzaENvbnRleHROb2RlTGlzdChjb250ZXh0Tm9kZXMpOwotCi0gICAgTm9kZVNldCByZXN1bHRTZXQgPSBuZXcgTm9kZVNldCgpOwotICAgIHJlc3VsdFNldC5zZXRTaG91bGRDYWNoZU5vZGVzKHRydWUpOwotCi0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBubC5nZXRMZW5ndGgoKTsgaSsrKQotICAgIHsKLSAgICAgIGludCBjb250ZXh0Tm9kZSA9IGNvbnRleHROb2Rlcy5pdGVtKGkpOwotICAgICAgeGN0eHQucHVzaEN1cnJlbnROb2RlKGNvbnRleHROb2RlKTsKLQotICAgICAgWE9iamVjdCBvYmplY3QgPSBudWxsOwotICAgICAgdHJ5Ci0gICAgICB7Ci0gICAgICAgIFhQYXRoIGR5bmFtaWNYUGF0aCA9IG5ldyBYUGF0aChleHByLCB4Y3R4dC5nZXRTQVhMb2NhdG9yKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4Y3R4dC5nZXROYW1lc3BhY2VDb250ZXh0KCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYUGF0aC5TRUxFQ1QpOwotICAgICAgICBvYmplY3QgPSBkeW5hbWljWFBhdGguZXhlY3V0ZSh4Y3R4dCwgY29udGV4dE5vZGUsIHhjdHh0LmdldE5hbWVzcGFjZUNvbnRleHQoKSk7Ci0KLSAgICAgICAgaWYgKG9iamVjdCBpbnN0YW5jZW9mIFhOb2RlU2V0KQotICAgICAgICB7Ci0gICAgICAgICAgTm9kZUxpc3Qgbm9kZWxpc3QgPSBudWxsOwotICAgICAgICAgIG5vZGVsaXN0ID0gKChYTm9kZVNldClvYmplY3QpLm5vZGVsaXN0KCk7Ci0KLSAgICAgICAgICBmb3IgKGludCBrID0gMDsgayA8IG5vZGVsaXN0LmdldExlbmd0aCgpOyBrKyspCi0gICAgICAgICAgewotICAgICAgICAgICAgTm9kZSBuID0gbm9kZWxpc3QuaXRlbShrKTsKLSAgICAgICAgICAgIGlmICghcmVzdWx0U2V0LmNvbnRhaW5zKG4pKQotICAgICAgICAgICAgICByZXN1bHRTZXQuYWRkTm9kZShuKTsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICB7Ci0gICAgICAgICAgaWYgKGxEb2MgPT0gbnVsbCkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGRiZiA9IERvY3VtZW50QnVpbGRlckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKLSAgICAgICAgICAgIGRiZi5zZXROYW1lc3BhY2VBd2FyZSh0cnVlKTsKLSAgICAgICAgICAgIERvY3VtZW50QnVpbGRlciBkYiA9IGRiZi5uZXdEb2N1bWVudEJ1aWxkZXIoKTsKLSAgICAgICAgICAgIGxEb2MgPSBkYi5uZXdEb2N1bWVudCgpOwotICAgICAgICAgIH0KLQotICAgICAgICAgIEVsZW1lbnQgZWxlbWVudCA9IG51bGw7Ci0gICAgICAgICAgaWYgKG9iamVjdCBpbnN0YW5jZW9mIFhOdW1iZXIpCi0gICAgICAgICAgICBlbGVtZW50ID0gbERvYy5jcmVhdGVFbGVtZW50TlMoRVhTTF9VUkksICJleHNsOm51bWJlciIpOwotICAgICAgICAgIGVsc2UgaWYgKG9iamVjdCBpbnN0YW5jZW9mIFhCb29sZWFuKQotICAgICAgICAgICAgZWxlbWVudCA9IGxEb2MuY3JlYXRlRWxlbWVudE5TKEVYU0xfVVJJLCAiZXhzbDpib29sZWFuIik7Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgICAgZWxlbWVudCA9IGxEb2MuY3JlYXRlRWxlbWVudE5TKEVYU0xfVVJJLCAiZXhzbDpzdHJpbmciKTsKLQotICAgICAgICAgIFRleHQgdGV4dE5vZGUgPSBsRG9jLmNyZWF0ZVRleHROb2RlKG9iamVjdC5zdHIoKSk7Ci0gICAgICAgICAgZWxlbWVudC5hcHBlbmRDaGlsZCh0ZXh0Tm9kZSk7Ci0gICAgICAgICAgcmVzdWx0U2V0LmFkZE5vZGUoZWxlbWVudCk7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICAgIGNhdGNoIChFeGNlcHRpb24gZSkKLSAgICAgIHsKLSAgICAgICAgeGN0eHQucG9wQ3VycmVudE5vZGUoKTsKLSAgICAgICAgeGN0eHQucG9wQ29udGV4dE5vZGVMaXN0KCk7Ci0gICAgICAgIHJldHVybiBuZXcgTm9kZVNldCgpOwotICAgICAgfQotCi0gICAgICB4Y3R4dC5wb3BDdXJyZW50Tm9kZSgpOwotCi0gICAgfQotCi0gICAgeGN0eHQucG9wQ29udGV4dE5vZGVMaXN0KCk7Ci0gICAgcmV0dXJuIHJlc3VsdFNldDsKLSAgfQotCi0gIC8qKgotICAgKiBUaGUgZHluOmV2YWx1YXRlIGZ1bmN0aW9uIGV2YWx1YXRlcyBhIHN0cmluZyBhcyBhbiBYUGF0aCBleHByZXNzaW9uIGFuZCByZXR1cm5zCi0gICAqIHRoZSByZXN1bHRpbmcgdmFsdWUsIHdoaWNoIG1pZ2h0IGJlIGEgYm9vbGVhbiwgbnVtYmVyLCBzdHJpbmcsIG5vZGUgc2V0LCByZXN1bHQKLSAgICogdHJlZSBmcmFnbWVudCBvciBleHRlcm5hbCBvYmplY3QuIFRoZSBzb2xlIGFyZ3VtZW50IGlzIHRoZSBzdHJpbmcgdG8gYmUgZXZhbHVhdGVkLgotICAgKiA8cD4KLSAgICogSWYgdGhlIGV4cHJlc3Npb24gc3RyaW5nIHBhc3NlZCBhcyB0aGUgc2Vjb25kIGFyZ3VtZW50IGlzIGFuIGludmFsaWQgWFBhdGgKLSAgICogZXhwcmVzc2lvbiAoaW5jbHVkaW5nIGFuIGVtcHR5IHN0cmluZyksIHRoaXMgZnVuY3Rpb24gcmV0dXJucyBhbiBlbXB0eSBub2RlIHNldC4KLSAgICogPHA+Ci0gICAqIFlvdSBzaG91bGQgb25seSB1c2UgdGhpcyBmdW5jdGlvbiBpZiB0aGUgZXhwcmVzc2lvbiBtdXN0IGJlIGNvbnN0cnVjdGVkIGR5bmFtaWNhbGx5LAotICAgKiBvdGhlcndpc2UgaXQgaXMgbXVjaCBtb3JlIGVmZmljaWVudCB0byB1c2UgdGhlIGV4cHJlc3Npb24gbGl0ZXJhbGx5LgotICAgKgotICAgKiBAcGFyYW0gbXlDb250ZXh0IFRoZSBFeHByZXNzaW9uQ29udGV4dCBwYXNzZWQgYnkgdGhlIGV4dGVuc2lvbiBwcm9jZXNzb3IKLSAgICogQHBhcmFtIHhwYXRoRXhwciBUaGUgWFBhdGggZXhwcmVzc2lvbiBzdHJpbmcKLSAgICoKLSAgICogQHJldHVybiBUaGUgZXZhbHVhdGlvbiByZXN1bHQKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgWE9iamVjdCBldmFsdWF0ZShFeHByZXNzaW9uQ29udGV4dCBteUNvbnRleHQsIFN0cmluZyB4cGF0aEV4cHIpCi0gICAgdGhyb3dzIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbgotICB7Ci0gICAgaWYgKG15Q29udGV4dCBpbnN0YW5jZW9mIFhQYXRoQ29udGV4dC5YUGF0aEV4cHJlc3Npb25Db250ZXh0KQotICAgIHsKLSAgICAgIFhQYXRoQ29udGV4dCB4Y3R4dCA9IG51bGw7Ci0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgeGN0eHQgPSAoKFhQYXRoQ29udGV4dC5YUGF0aEV4cHJlc3Npb25Db250ZXh0KSBteUNvbnRleHQpLmdldFhQYXRoQ29udGV4dCgpOwotICAgICAgICBYUGF0aCBkeW5hbWljWFBhdGggPSBuZXcgWFBhdGgoeHBhdGhFeHByLCB4Y3R4dC5nZXRTQVhMb2NhdG9yKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4Y3R4dC5nZXROYW1lc3BhY2VDb250ZXh0KCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYUGF0aC5TRUxFQ1QpOwotCi0gICAgICAgIHJldHVybiBkeW5hbWljWFBhdGguZXhlY3V0ZSh4Y3R4dCwgbXlDb250ZXh0LmdldENvbnRleHROb2RlKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4Y3R4dC5nZXROYW1lc3BhY2VDb250ZXh0KCkpOwotICAgICAgfQotICAgICAgY2F0Y2ggKFRyYW5zZm9ybWVyRXhjZXB0aW9uIGUpCi0gICAgICB7Ci0gICAgICAgIHJldHVybiBuZXcgWE5vZGVTZXQoeGN0eHQuZ2V0RFRNTWFuYWdlcigpKTsKLSAgICAgIH0KLSAgICB9Ci0gICAgZWxzZQotICAgICAgdGhyb3cgbmV3IFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9JTlZBTElEX0NPTlRFWFRfUEFTU0VELCBuZXcgT2JqZWN0W117bXlDb250ZXh0IH0pKTsgLy8iSW52YWxpZCBjb250ZXh0IHBhc3NlZCB0byBldmFsdWF0ZSAiCi0gIH0KLQotICAvKioKLSAgICogVGhlIGR5bjpjbG9zdXJlIGZ1bmN0aW9uIGNyZWF0ZXMgYSBub2RlIHNldCByZXN1bHRpbmcgZnJvbSB0cmFuc2l0aXZlIGNsb3N1cmUgb2YKLSAgICogZXZhbHVhdGluZyB0aGUgZXhwcmVzc2lvbiBwYXNzZWQgYXMgdGhlIHNlY29uZCBhcmd1bWVudCBvbiBlYWNoIG9mIHRoZSBub2RlcyBwYXNzZWQKLSAgICogYXMgdGhlIGZpcnN0IGFyZ3VtZW50LCB0aGVuIG9uIHRoZSBub2RlIHNldCByZXN1bHRpbmcgZnJvbSB0aGF0IGFuZCBzbyBvbiB1bnRpbCBubwotICAgKiBtb3JlIG5vZGVzIGFyZSBmb3VuZC4gRm9yIGV4YW1wbGU6Ci0gICAqIDxwcmU+Ci0gICAqICBkeW46Y2xvc3VyZSguLCAnKicpCi0gICAqIDwvcHJlPgotICAgKiByZXR1cm5zIGFsbCB0aGUgZGVzY2VuZGFudCBlbGVtZW50cyBvZiB0aGUgbm9kZSAoaXRzIGVsZW1lbnQgY2hpbGRyZW4sIHRoZWlyCi0gICAqIGNoaWxkcmVuLCB0aGVpciBjaGlsZHJlbidzIGNoaWxkcmVuIGFuZCBzbyBvbikuCi0gICAqIDxwPgotICAgKiBUaGUgZXhwcmVzc2lvbiBpcyB0aHVzIGV2YWx1YXRlZCBzZXZlcmFsIHRpbWVzLCBlYWNoIHdpdGggYSBkaWZmZXJlbnQgbm9kZSBzZXQKLSAgICogYWN0aW5nIGFzIHRoZSBjb250ZXh0IG9mIHRoZSBleHByZXNzaW9uLiBUaGUgZmlyc3QgdGltZSB0aGUgZXhwcmVzc2lvbiBpcwotICAgKiBldmFsdWF0ZWQsIHRoZSBjb250ZXh0IG5vZGUgc2V0IGlzIHRoZSBmaXJzdCBhcmd1bWVudCBwYXNzZWQgdG8gdGhlIGR5bjpjbG9zdXJlCi0gICAqIGZ1bmN0aW9uLiBJbiBvdGhlciB3b3JkcywgdGhlIG5vZGUgc2V0IGZvciBlYWNoIG5vZGUgaXMgY2FsY3VsYXRlZCBieSBldmFsdWF0aW5nCi0gICAqIHRoZSBYUGF0aCBleHByZXNzaW9uIHdpdGggYWxsIGNvbnRleHQgaW5mb3JtYXRpb24gYmVpbmcgdGhlIHNhbWUgYXMgdGhhdCBmb3IKLSAgICogdGhlIGNhbGwgdG8gdGhlIGR5bjpjbG9zdXJlIGZ1bmN0aW9uIGl0c2VsZiwgZXhjZXB0IGZvciB0aGUgZm9sbG93aW5nOgotICAgKiA8cD4KLSAgICogPHVsPgotICAgKiAgPGxpPnRoZSBjb250ZXh0IG5vZGUgaXMgdGhlIG5vZGUgd2hvc2UgdmFsdWUgaXMgYmVpbmcgY2FsY3VsYXRlZC48L2xpPgotICAgKiAgPGxpPnRoZSBjb250ZXh0IHBvc2l0aW9uIGlzIHRoZSBwb3NpdGlvbiBvZiB0aGUgbm9kZSB3aXRoaW4gdGhlIG5vZGUgc2V0IHBhc3NlZAotICAgKiAgICBhcyB0aGUgZmlyc3QgYXJndW1lbnQgdG8gdGhlIGR5bjpjbG9zdXJlIGZ1bmN0aW9uLCBhcnJhbmdlZCBpbiBkb2N1bWVudCBvcmRlci48L2xpPgotICAgKiAgPGxpPnRoZSBjb250ZXh0IHNpemUgaXMgdGhlIG51bWJlciBvZiBub2RlcyBwYXNzZWQgYXMgdGhlIGZpcnN0IGFyZ3VtZW50IHRvIHRoZQotICAgKiAgICBkeW46Y2xvc3VyZSBmdW5jdGlvbi48L2xpPgotICAgKiAgPGxpPnRoZSBjdXJyZW50IG5vZGUgaXMgdGhlIG5vZGUgd2hvc2UgdmFsdWUgaXMgYmVpbmcgY2FsY3VsYXRlZC48L2xpPgotICAgKiA8L3VsPgotICAgKiA8cD4KLSAgICogVGhlIHJlc3VsdCBmb3IgYSBwYXJ0aWN1bGFyIGl0ZXJhdGlvbiBpcyB0aGUgdW5pb24gb2YgdGhlIG5vZGUgc2V0cyByZXN1bHRpbmcKLSAgICogZnJvbSBldmFsdXRpbmcgdGhlIGV4cHJlc3Npb24gZm9yIGVhY2ggb2YgdGhlIG5vZGVzIGluIHRoZSBzb3VyY2Ugbm9kZSBzZXQgZm9yCi0gICAqIHRoYXQgaXRlcmF0aW9uLiBUaGlzIHJlc3VsdCBpcyB0aGVuIHVzZWQgYXMgdGhlIHNvdXJjZSBub2RlIHNldCBmb3IgdGhlIG5leHQKLSAgICogaXRlcmF0aW9uLCBhbmQgc28gb24uIFRoZSByZXN1bHQgb2YgdGhlIGZ1bmN0aW9uIGFzIGEgd2hvbGUgaXMgdGhlIHVuaW9uIG9mCi0gICAqIHRoZSBub2RlIHNldHMgZ2VuZXJhdGVkIGJ5IGVhY2ggaXRlcmF0aW9uLgotICAgKiA8cD4KLSAgICogSWYgdGhlIGV4cHJlc3Npb24gc3RyaW5nIHBhc3NlZCBhcyB0aGUgc2Vjb25kIGFyZ3VtZW50IGlzIGFuIGludmFsaWQgWFBhdGgKLSAgICogZXhwcmVzc2lvbiAoaW5jbHVkaW5nIGFuIGVtcHR5IHN0cmluZykgb3IgYW4gZXhwcmVzc2lvbiB0aGF0IGRvZXMgbm90IHJldHVybiBhCi0gICAqIG5vZGUgc2V0LCB0aGlzIGZ1bmN0aW9uIHJldHVybnMgYW4gZW1wdHkgbm9kZSBzZXQuCi0gICAqCi0gICAqIEBwYXJhbSBteUNvbnRleHQgVGhlIEV4cHJlc3Npb25Db250ZXh0IHBhc3NlZCBieSB0aGUgZXh0ZW5zaW9uIHByb2Nlc3NvcgotICAgKiBAcGFyYW0gbmwgVGhlIG5vZGUgc2V0Ci0gICAqIEBwYXJhbSBleHByIFRoZSBleHByZXNzaW9uIHN0cmluZwotICAgKgotICAgKiBAcmV0dXJuIFRoZSBub2RlIHNldCBhZnRlciBldmFsdWF0aW9uCi0gICAqLwotICBwdWJsaWMgc3RhdGljIE5vZGVMaXN0IGNsb3N1cmUoRXhwcmVzc2lvbkNvbnRleHQgbXlDb250ZXh0LCBOb2RlTGlzdCBubCwgU3RyaW5nIGV4cHIpCi0gICAgdGhyb3dzIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbgotICB7Ci0gICAgWFBhdGhDb250ZXh0IHhjdHh0ID0gbnVsbDsKLSAgICBpZiAobXlDb250ZXh0IGluc3RhbmNlb2YgWFBhdGhDb250ZXh0LlhQYXRoRXhwcmVzc2lvbkNvbnRleHQpCi0gICAgICB4Y3R4dCA9ICgoWFBhdGhDb250ZXh0LlhQYXRoRXhwcmVzc2lvbkNvbnRleHQpIG15Q29udGV4dCkuZ2V0WFBhdGhDb250ZXh0KCk7Ci0gICAgZWxzZQotICAgICAgdGhyb3cgbmV3IFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9JTlZBTElEX0NPTlRFWFRfUEFTU0VELCBuZXcgT2JqZWN0W117bXlDb250ZXh0IH0pKTsKLQotICAgIGlmIChleHByID09IG51bGwgfHwgZXhwci5sZW5ndGgoKSA9PSAwKQotICAgICAgcmV0dXJuIG5ldyBOb2RlU2V0KCk7Ci0KLSAgICBOb2RlU2V0IGNsb3N1cmVTZXQgPSBuZXcgTm9kZVNldCgpOwotICAgIGNsb3N1cmVTZXQuc2V0U2hvdWxkQ2FjaGVOb2Rlcyh0cnVlKTsKLQotICAgIE5vZGVMaXN0IGl0ZXJhdGlvbkxpc3QgPSBubDsKLSAgICBkbwotICAgIHsKLQotICAgICAgTm9kZVNldCBpdGVyYXRpb25TZXQgPSBuZXcgTm9kZVNldCgpOwotCi0gICAgICBOb2RlU2V0RFRNIGNvbnRleHROb2RlcyA9IG5ldyBOb2RlU2V0RFRNKGl0ZXJhdGlvbkxpc3QsIHhjdHh0KTsKLSAgICAgIHhjdHh0LnB1c2hDb250ZXh0Tm9kZUxpc3QoY29udGV4dE5vZGVzKTsKLQotICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBpdGVyYXRpb25MaXN0LmdldExlbmd0aCgpOyBpKyspCi0gICAgICB7Ci0gICAgICAgIGludCBjb250ZXh0Tm9kZSA9IGNvbnRleHROb2Rlcy5pdGVtKGkpOwotICAgICAgICB4Y3R4dC5wdXNoQ3VycmVudE5vZGUoY29udGV4dE5vZGUpOwotCi0gICAgICAgIFhPYmplY3Qgb2JqZWN0ID0gbnVsbDsKLSAgICAgICAgdHJ5Ci0gICAgICAgIHsKLSAgICAgICAgICBYUGF0aCBkeW5hbWljWFBhdGggPSBuZXcgWFBhdGgoZXhwciwgeGN0eHQuZ2V0U0FYTG9jYXRvcigpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4Y3R4dC5nZXROYW1lc3BhY2VDb250ZXh0KCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhQYXRoLlNFTEVDVCk7Ci0gICAgICAgICAgb2JqZWN0ID0gZHluYW1pY1hQYXRoLmV4ZWN1dGUoeGN0eHQsIGNvbnRleHROb2RlLCB4Y3R4dC5nZXROYW1lc3BhY2VDb250ZXh0KCkpOwotCi0gICAgICAgICAgaWYgKG9iamVjdCBpbnN0YW5jZW9mIFhOb2RlU2V0KQotICAgICAgICAgIHsKLSAgICAgICAgICAgIE5vZGVMaXN0IG5vZGVsaXN0ID0gbnVsbDsKLSAgICAgICAgICAgIG5vZGVsaXN0ID0gKChYTm9kZVNldClvYmplY3QpLm5vZGVsaXN0KCk7Ci0KLSAgICAgICAgICAgIGZvciAoaW50IGsgPSAwOyBrIDwgbm9kZWxpc3QuZ2V0TGVuZ3RoKCk7IGsrKykKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgTm9kZSBuID0gbm9kZWxpc3QuaXRlbShrKTsKLSAgICAgICAgICAgICAgaWYgKCFpdGVyYXRpb25TZXQuY29udGFpbnMobikpCi0gICAgICAgICAgICAgICAgaXRlcmF0aW9uU2V0LmFkZE5vZGUobik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UKLSAgICAgICAgICB7Ci0gICAgICAgICAgICB4Y3R4dC5wb3BDdXJyZW50Tm9kZSgpOwotICAgICAgICAgICAgeGN0eHQucG9wQ29udGV4dE5vZGVMaXN0KCk7Ci0gICAgICAgICAgICByZXR1cm4gbmV3IE5vZGVTZXQoKTsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKFRyYW5zZm9ybWVyRXhjZXB0aW9uIGUpCi0gICAgICAgIHsKLSAgICAgICAgICB4Y3R4dC5wb3BDdXJyZW50Tm9kZSgpOwotICAgICAgICAgIHhjdHh0LnBvcENvbnRleHROb2RlTGlzdCgpOwotICAgICAgICAgIHJldHVybiBuZXcgTm9kZVNldCgpOwotICAgICAgICB9Ci0KLSAgICAgICAgeGN0eHQucG9wQ3VycmVudE5vZGUoKTsKLQotICAgICAgfQotCi0gICAgICB4Y3R4dC5wb3BDb250ZXh0Tm9kZUxpc3QoKTsKLQotICAgICAgaXRlcmF0aW9uTGlzdCA9IGl0ZXJhdGlvblNldDsKLQotICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBpdGVyYXRpb25MaXN0LmdldExlbmd0aCgpOyBpKyspCi0gICAgICB7Ci0gICAgICAgIE5vZGUgbiA9IGl0ZXJhdGlvbkxpc3QuaXRlbShpKTsKLSAgICAgICAgaWYgKCFjbG9zdXJlU2V0LmNvbnRhaW5zKG4pKQotICAgICAgICAgIGNsb3N1cmVTZXQuYWRkTm9kZShuKTsKLSAgICAgIH0KLQotICAgIH0gd2hpbGUoaXRlcmF0aW9uTGlzdC5nZXRMZW5ndGgoKSA+IDApOwotCi0gICAgcmV0dXJuIGNsb3N1cmVTZXQ7Ci0KLSAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL2xpYi9FeHNsdE1hdGguamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwvbGliL0V4c2x0TWF0aC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2MDY2ODMyLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwvbGliL0V4c2x0TWF0aC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzkxICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IEV4c2x0TWF0aC5qYXZhLHYgMS4xLjIuMSAyMDA1LzA4LzAxIDAyOjA4OjUwIGplZmZzdXR0b3IgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwubGliOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLk5vZGVTZXQ7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGVMaXN0OwotCi0vKioKLSAqIFRoaXMgY2xhc3MgY29udGFpbnMgRVhTTFQgbWF0aCBleHRlbnNpb24gZnVuY3Rpb25zLgotICogSXQgaXMgYWNjZXNzZWQgYnkgc3BlY2lmeWluZyBhIG5hbWVzcGFjZSBVUkkgYXMgZm9sbG93czoKLSAqIDxwcmU+Ci0gKiAgICB4bWxuczptYXRoPSJodHRwOi8vZXhzbHQub3JnL21hdGgiCi0gKiA8L3ByZT4KLSAqCi0gKiBUaGUgZG9jdW1lbnRhdGlvbiBmb3IgZWFjaCBmdW5jdGlvbiBoYXMgYmVlbiBjb3BpZWQgZnJvbSB0aGUgcmVsZXZhbnQKLSAqIEVYU0xUIEltcGxlbWVudGVyIHBhZ2UuCi0gKgotICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LmV4c2x0Lm9yZy8iPkVYU0xUPC9hPgotCi0gKiBAeHNsLnVzYWdlIGdlbmVyYWwKLSAqLwotcHVibGljIGNsYXNzIEV4c2x0TWF0aCBleHRlbmRzIEV4c2x0QmFzZQotewotICAvLyBDb25zdGFudHMKLSAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIFBJID0gIjMuMTQxNTkyNjUzNTg5NzkzMjM4NDYyNjQzMzgzMjc5NTAyODg0MTk3MTY5Mzk5Mzc1MSI7Ci0gIHByaXZhdGUgc3RhdGljIFN0cmluZyBFICA9ICIyLjcxODI4MTgyODQ1OTA0NTIzNTM2MDI4NzQ3MTM1MjY2MjQ5Nzc1NzI0NzA5MzY5OTk2IjsKLSAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIFNRUlJUMiA9ICIxLjQxNDIxMzU2MjM3MzA5NTA0ODgwMTY4ODcyNDIwOTY5ODA3ODU2OTY3MTg3NTM3Njk0IjsKLSAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIExOMiA9ICIwLjY5MzE0NzE4MDU1OTk0NTMwOTQxNzIzMjEyMTQ1ODE3NjU2ODA3NTUwMDEzNDM2MDI1IjsKLSAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIExOMTAgPSAiMi4zMDI1ODUwOTI5OTQwNDYiOwotICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgTE9HMkUgPSAiMS40NDI2OTUwNDA4ODg5NjMzIjsKLSAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIFNRUlQxXzIgPSAiMC43MDcxMDY3ODExODY1NDc2IjsKLQotICAvKioKLSAgICogVGhlIG1hdGg6bWF4IGZ1bmN0aW9uIHJldHVybnMgdGhlIG1heGltdW0gdmFsdWUgb2YgdGhlIG5vZGVzIHBhc3NlZCBhcyB0aGUgYXJndW1lbnQuCi0gICAqIFRoZSBtYXhpbXVtIHZhbHVlIGlzIGRlZmluZWQgYXMgZm9sbG93cy4gVGhlIG5vZGUgc2V0IHBhc3NlZCBhcyBhbiBhcmd1bWVudCBpcyBzb3J0ZWQKLSAgICogaW4gZGVzY2VuZGluZyBvcmRlciBhcyBpdCB3b3VsZCBiZSBieSB4c2w6c29ydCB3aXRoIGEgZGF0YSB0eXBlIG9mIG51bWJlci4gVGhlIG1heGltdW0KLSAgICogaXMgdGhlIHJlc3VsdCBvZiBjb252ZXJ0aW5nIHRoZSBzdHJpbmcgdmFsdWUgb2YgdGhlIGZpcnN0IG5vZGUgaW4gdGhpcyBzb3J0ZWQgbGlzdCB0bwotICAgKiBhIG51bWJlciB1c2luZyB0aGUgbnVtYmVyIGZ1bmN0aW9uLgotICAgKiA8cD4KLSAgICogSWYgdGhlIG5vZGUgc2V0IGlzIGVtcHR5LCBvciBpZiB0aGUgcmVzdWx0IG9mIGNvbnZlcnRpbmcgdGhlIHN0cmluZyB2YWx1ZXMgb2YgYW55IG9mIHRoZQotICAgKiBub2RlcyB0byBhIG51bWJlciBpcyBOYU4sIHRoZW4gTmFOIGlzIHJldHVybmVkLgotICAgKgotICAgKiBAcGFyYW0gbmwgVGhlIE5vZGVMaXN0IGZvciB0aGUgbm9kZS1zZXQgdG8gYmUgZXZhbHVhdGVkLgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBtYXhpbXVtIHZhbHVlIGZvdW5kLCBOYU4gaWYgYW55IG5vZGUgY2Fubm90IGJlIGNvbnZlcnRlZCB0byBhIG51bWJlci4KLSAgICoKLSAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LmV4c2x0Lm9yZy8iPkVYU0xUPC9hPgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBkb3VibGUgbWF4IChOb2RlTGlzdCBubCkKLSAgewotICAgIGlmIChubCA9PSBudWxsIHx8IG5sLmdldExlbmd0aCgpID09IDApCi0gICAgICByZXR1cm4gRG91YmxlLk5hTjsKLQotICAgIGRvdWJsZSBtID0gLSBEb3VibGUuTUFYX1ZBTFVFOwotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbmwuZ2V0TGVuZ3RoKCk7IGkrKykKLSAgICB7Ci0gICAgICBOb2RlIG4gPSBubC5pdGVtKGkpOwotICAgICAgZG91YmxlIGQgPSB0b051bWJlcihuKTsKLSAgICAgIGlmIChEb3VibGUuaXNOYU4oZCkpCi0gICAgICAgIHJldHVybiBEb3VibGUuTmFOOwotICAgICAgZWxzZSBpZiAoZCA+IG0pCi0gICAgICAgIG0gPSBkOwotICAgIH0KLQotICAgIHJldHVybiBtOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoZSBtYXRoOm1pbiBmdW5jdGlvbiByZXR1cm5zIHRoZSBtaW5pbXVtIHZhbHVlIG9mIHRoZSBub2RlcyBwYXNzZWQgYXMgdGhlIGFyZ3VtZW50LgotICAgKiBUaGUgbWluaW11bSB2YWx1ZSBpcyBkZWZpbmVkIGFzIGZvbGxvd3MuIFRoZSBub2RlIHNldCBwYXNzZWQgYXMgYW4gYXJndW1lbnQgaXMgc29ydGVkCi0gICAqIGluIGFzY2VuZGluZyBvcmRlciBhcyBpdCB3b3VsZCBiZSBieSB4c2w6c29ydCB3aXRoIGEgZGF0YSB0eXBlIG9mIG51bWJlci4gVGhlIG1pbmltdW0KLSAgICogaXMgdGhlIHJlc3VsdCBvZiBjb252ZXJ0aW5nIHRoZSBzdHJpbmcgdmFsdWUgb2YgdGhlIGZpcnN0IG5vZGUgaW4gdGhpcyBzb3J0ZWQgbGlzdCB0bwotICAgKiBhIG51bWJlciB1c2luZyB0aGUgbnVtYmVyIGZ1bmN0aW9uLgotICAgKiA8cD4KLSAgICogSWYgdGhlIG5vZGUgc2V0IGlzIGVtcHR5LCBvciBpZiB0aGUgcmVzdWx0IG9mIGNvbnZlcnRpbmcgdGhlIHN0cmluZyB2YWx1ZXMgb2YgYW55IG9mCi0gICAqIHRoZSBub2RlcyB0byBhIG51bWJlciBpcyBOYU4sIHRoZW4gTmFOIGlzIHJldHVybmVkLgotICAgKgotICAgKiBAcGFyYW0gbmwgVGhlIE5vZGVMaXN0IGZvciB0aGUgbm9kZS1zZXQgdG8gYmUgZXZhbHVhdGVkLgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBtaW5pbXVtIHZhbHVlIGZvdW5kLCBOYU4gaWYgYW55IG5vZGUgY2Fubm90IGJlIGNvbnZlcnRlZCB0byBhIG51bWJlci4KLSAgICoKLSAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LmV4c2x0Lm9yZy8iPkVYU0xUPC9hPgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBkb3VibGUgbWluIChOb2RlTGlzdCBubCkKLSAgewotICAgIGlmIChubCA9PSBudWxsIHx8IG5sLmdldExlbmd0aCgpID09IDApCi0gICAgICByZXR1cm4gRG91YmxlLk5hTjsKLQotICAgIGRvdWJsZSBtID0gRG91YmxlLk1BWF9WQUxVRTsKLSAgICBmb3IgKGludCBpID0gMDsgaSA8IG5sLmdldExlbmd0aCgpOyBpKyspCi0gICAgewotICAgICAgTm9kZSBuID0gbmwuaXRlbShpKTsKLSAgICAgIGRvdWJsZSBkID0gdG9OdW1iZXIobik7Ci0gICAgICBpZiAoRG91YmxlLmlzTmFOKGQpKQotICAgICAgICByZXR1cm4gRG91YmxlLk5hTjsKLSAgICAgIGVsc2UgaWYgKGQgPCBtKQotICAgICAgICBtID0gZDsKLSAgICB9Ci0KLSAgICByZXR1cm4gbTsKLSAgfQotCi0gIC8qKgotICAgKiBUaGUgbWF0aDpoaWdoZXN0IGZ1bmN0aW9uIHJldHVybnMgdGhlIG5vZGVzIGluIHRoZSBub2RlIHNldCB3aG9zZSB2YWx1ZSBpcyB0aGUgbWF4aW11bQotICAgKiB2YWx1ZSBmb3IgdGhlIG5vZGUgc2V0LiBUaGUgbWF4aW11bSB2YWx1ZSBmb3IgdGhlIG5vZGUgc2V0IGlzIHRoZSBzYW1lIGFzIHRoZSB2YWx1ZSBhcwotICAgKiBjYWxjdWxhdGVkIGJ5IG1hdGg6bWF4LiBBIG5vZGUgaGFzIHRoaXMgbWF4aW11bSB2YWx1ZSBpZiB0aGUgcmVzdWx0IG9mIGNvbnZlcnRpbmcgaXRzCi0gICAqIHN0cmluZyB2YWx1ZSB0byBhIG51bWJlciBhcyBpZiBieSB0aGUgbnVtYmVyIGZ1bmN0aW9uIGlzIGVxdWFsIHRvIHRoZSBtYXhpbXVtIHZhbHVlLAotICAgKiB3aGVyZSB0aGUgZXF1YWxpdHkgY29tcGFyaXNvbiBpcyBkZWZpbmVkIGFzIGEgbnVtZXJpY2FsIGNvbXBhcmlzb24gdXNpbmcgdGhlID0gb3BlcmF0b3IuCi0gICAqIDxwPgotICAgKiBJZiBhbnkgb2YgdGhlIG5vZGVzIGluIHRoZSBub2RlIHNldCBoYXMgYSBub24tbnVtZXJpYyB2YWx1ZSwgdGhlIG1hdGg6bWF4IGZ1bmN0aW9uIHdpbGwKLSAgICogcmV0dXJuIE5hTi4gVGhlIGRlZmluaXRpb24gbnVtZXJpYyBjb21wYXJpc29ucyBlbnRhaWxzIHRoYXQgTmFOICE9IE5hTi4gVGhlcmVmb3JlIGlmIGFueQotICAgKiBvZiB0aGUgbm9kZXMgaW4gdGhlIG5vZGUgc2V0IGhhcyBhIG5vbi1udW1lcmljIHZhbHVlLCBtYXRoOmhpZ2hlc3Qgd2lsbCByZXR1cm4gYW4gZW1wdHkKLSAgICogbm9kZSBzZXQuCi0gICAqCi0gICAqIEBwYXJhbSBubCBUaGUgTm9kZUxpc3QgZm9yIHRoZSBub2RlLXNldCB0byBiZSBldmFsdWF0ZWQuCi0gICAqCi0gICAqIEByZXR1cm4gbm9kZS1zZXQgd2l0aCBub2RlcyBjb250YWluaW5nIHRoZSBtYXhpbXVtIHZhbHVlIGZvdW5kLCBhbiBlbXB0eSBub2RlLXNldAotICAgKiBpZiBhbnkgbm9kZSBjYW5ub3QgYmUgY29udmVydGVkIHRvIGEgbnVtYmVyLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBOb2RlTGlzdCBoaWdoZXN0IChOb2RlTGlzdCBubCkKLSAgewotICAgIGRvdWJsZSBtYXhWYWx1ZSA9IG1heChubCk7Ci0KLSAgICBOb2RlU2V0IGhpZ2hOb2RlcyA9IG5ldyBOb2RlU2V0KCk7Ci0gICAgaGlnaE5vZGVzLnNldFNob3VsZENhY2hlTm9kZXModHJ1ZSk7Ci0KLSAgICBpZiAoRG91YmxlLmlzTmFOKG1heFZhbHVlKSkKLSAgICAgIHJldHVybiBoaWdoTm9kZXM7ICAvLyBlbXB0eSBOb2Rlc2V0Ci0KLSAgICBmb3IgKGludCBpID0gMDsgaSA8IG5sLmdldExlbmd0aCgpOyBpKyspCi0gICAgewotICAgICAgTm9kZSBuID0gbmwuaXRlbShpKTsKLSAgICAgIGRvdWJsZSBkID0gdG9OdW1iZXIobik7Ci0gICAgICBpZiAoZCA9PSBtYXhWYWx1ZSkKLSAgICAgICAgaGlnaE5vZGVzLmFkZEVsZW1lbnQobik7Ci0gICAgfQotICAgIHJldHVybiBoaWdoTm9kZXM7Ci0gIH0KLQotICAvKioKLSAgICogVGhlIG1hdGg6bG93ZXN0IGZ1bmN0aW9uIHJldHVybnMgdGhlIG5vZGVzIGluIHRoZSBub2RlIHNldCB3aG9zZSB2YWx1ZSBpcyB0aGUgbWluaW11bSB2YWx1ZQotICAgKiBmb3IgdGhlIG5vZGUgc2V0LiBUaGUgbWluaW11bSB2YWx1ZSBmb3IgdGhlIG5vZGUgc2V0IGlzIHRoZSBzYW1lIGFzIHRoZSB2YWx1ZSBhcyBjYWxjdWxhdGVkCi0gICAqIGJ5IG1hdGg6bWluLiBBIG5vZGUgaGFzIHRoaXMgbWluaW11bSB2YWx1ZSBpZiB0aGUgcmVzdWx0IG9mIGNvbnZlcnRpbmcgaXRzIHN0cmluZyB2YWx1ZSB0bwotICAgKiBhIG51bWJlciBhcyBpZiBieSB0aGUgbnVtYmVyIGZ1bmN0aW9uIGlzIGVxdWFsIHRvIHRoZSBtaW5pbXVtIHZhbHVlLCB3aGVyZSB0aGUgZXF1YWxpdHkKLSAgICogY29tcGFyaXNvbiBpcyBkZWZpbmVkIGFzIGEgbnVtZXJpY2FsIGNvbXBhcmlzb24gdXNpbmcgdGhlID0gb3BlcmF0b3IuCi0gICAqIDxwPgotICAgKiBJZiBhbnkgb2YgdGhlIG5vZGVzIGluIHRoZSBub2RlIHNldCBoYXMgYSBub24tbnVtZXJpYyB2YWx1ZSwgdGhlIG1hdGg6bWluIGZ1bmN0aW9uIHdpbGwgcmV0dXJuCi0gICAqIE5hTi4gVGhlIGRlZmluaXRpb24gbnVtZXJpYyBjb21wYXJpc29ucyBlbnRhaWxzIHRoYXQgTmFOICE9IE5hTi4gVGhlcmVmb3JlIGlmIGFueSBvZiB0aGUgbm9kZXMKLSAgICogaW4gdGhlIG5vZGUgc2V0IGhhcyBhIG5vbi1udW1lcmljIHZhbHVlLCBtYXRoOmxvd2VzdCB3aWxsIHJldHVybiBhbiBlbXB0eSBub2RlIHNldC4KLSAgICoKLSAgICogQHBhcmFtIG5sIFRoZSBOb2RlTGlzdCBmb3IgdGhlIG5vZGUtc2V0IHRvIGJlIGV2YWx1YXRlZC4KLSAgICoKLSAgICogQHJldHVybiBub2RlLXNldCB3aXRoIG5vZGVzIGNvbnRhaW5pbmcgdGhlIG1pbmltdW0gdmFsdWUgZm91bmQsIGFuIGVtcHR5IG5vZGUtc2V0Ci0gICAqIGlmIGFueSBub2RlIGNhbm5vdCBiZSBjb252ZXJ0ZWQgdG8gYSBudW1iZXIuCi0gICAqCi0gICAqLwotICBwdWJsaWMgc3RhdGljIE5vZGVMaXN0IGxvd2VzdCAoTm9kZUxpc3QgbmwpCi0gIHsKLSAgICBkb3VibGUgbWluVmFsdWUgPSBtaW4obmwpOwotCi0gICAgTm9kZVNldCBsb3dOb2RlcyA9IG5ldyBOb2RlU2V0KCk7Ci0gICAgbG93Tm9kZXMuc2V0U2hvdWxkQ2FjaGVOb2Rlcyh0cnVlKTsKLQotICAgIGlmIChEb3VibGUuaXNOYU4obWluVmFsdWUpKQotICAgICAgcmV0dXJuIGxvd05vZGVzOyAgLy8gZW1wdHkgTm9kZXNldAotCi0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBubC5nZXRMZW5ndGgoKTsgaSsrKQotICAgIHsKLSAgICAgIE5vZGUgbiA9IG5sLml0ZW0oaSk7Ci0gICAgICBkb3VibGUgZCA9IHRvTnVtYmVyKG4pOwotICAgICAgaWYgKGQgPT0gbWluVmFsdWUpCi0gICAgICAgIGxvd05vZGVzLmFkZEVsZW1lbnQobik7Ci0gICAgfQotICAgIHJldHVybiBsb3dOb2RlczsKLSAgfQotCi0gIC8qKgotICAgKiBUaGUgbWF0aDphYnMgZnVuY3Rpb24gcmV0dXJucyB0aGUgYWJzb2x1dGUgdmFsdWUgb2YgYSBudW1iZXIuCi0gICAqCi0gICAqIEBwYXJhbSBudW0gQSBudW1iZXIKLSAgICogQHJldHVybiBUaGUgYWJzb2x1dGUgdmFsdWUgb2YgdGhlIG51bWJlcgotICAgKi8KLSAgIHB1YmxpYyBzdGF0aWMgZG91YmxlIGFicyhkb3VibGUgbnVtKQotICAgewotICAgICByZXR1cm4gTWF0aC5hYnMobnVtKTsKLSAgIH0KLQotICAvKioKLSAgICogVGhlIG1hdGg6YWNvcyBmdW5jdGlvbiByZXR1cm5zIHRoZSBhcmNjb3NpbmUgdmFsdWUgb2YgYSBudW1iZXIuCi0gICAqCi0gICAqIEBwYXJhbSBudW0gQSBudW1iZXIKLSAgICogQHJldHVybiBUaGUgYXJjY29zaW5lIHZhbHVlIG9mIHRoZSBudW1iZXIKLSAgICovCi0gICBwdWJsaWMgc3RhdGljIGRvdWJsZSBhY29zKGRvdWJsZSBudW0pCi0gICB7Ci0gICAgIHJldHVybiBNYXRoLmFjb3MobnVtKTsKLSAgIH0KLQotICAvKioKLSAgICogVGhlIG1hdGg6YXNpbiBmdW5jdGlvbiByZXR1cm5zIHRoZSBhcmNzaW5lIHZhbHVlIG9mIGEgbnVtYmVyLgotICAgKgotICAgKiBAcGFyYW0gbnVtIEEgbnVtYmVyCi0gICAqIEByZXR1cm4gVGhlIGFyY3NpbmUgdmFsdWUgb2YgdGhlIG51bWJlcgotICAgKi8KLSAgIHB1YmxpYyBzdGF0aWMgZG91YmxlIGFzaW4oZG91YmxlIG51bSkKLSAgIHsKLSAgICAgcmV0dXJuIE1hdGguYXNpbihudW0pOwotICAgfQotCi0gIC8qKgotICAgKiBUaGUgbWF0aDphdGFuIGZ1bmN0aW9uIHJldHVybnMgdGhlIGFyY3RhbmdlbnQgdmFsdWUgb2YgYSBudW1iZXIuCi0gICAqCi0gICAqIEBwYXJhbSBudW0gQSBudW1iZXIKLSAgICogQHJldHVybiBUaGUgYXJjdGFuZ2VudCB2YWx1ZSBvZiB0aGUgbnVtYmVyCi0gICAqLwotICAgcHVibGljIHN0YXRpYyBkb3VibGUgYXRhbihkb3VibGUgbnVtKQotICAgewotICAgICByZXR1cm4gTWF0aC5hdGFuKG51bSk7Ci0gICB9Ci0KLSAgLyoqCi0gICAqIFRoZSBtYXRoOmF0YW4yIGZ1bmN0aW9uIHJldHVybnMgdGhlIGFuZ2xlICggaW4gcmFkaWFucyApIGZyb20gdGhlIFggYXhpcyB0byBhIHBvaW50ICh5LHgpLgotICAgKgotICAgKiBAcGFyYW0gbnVtMSBUaGUgWCBheGlzIHZhbHVlCi0gICAqIEBwYXJhbSBudW0yIFRoZSBZIGF4aXMgdmFsdWUKLSAgICogQHJldHVybiBUaGUgYW5nbGUgKGluIHJhZGlhbnMpIGZyb20gdGhlIFggYXhpcyB0byBhIHBvaW50ICh5LHgpCi0gICAqLwotICAgcHVibGljIHN0YXRpYyBkb3VibGUgYXRhbjIoZG91YmxlIG51bTEsIGRvdWJsZSBudW0yKQotICAgewotICAgICByZXR1cm4gTWF0aC5hdGFuMihudW0xLCBudW0yKTsKLSAgIH0KLQotICAvKioKLSAgICogVGhlIG1hdGg6Y29zIGZ1bmN0aW9uIHJldHVybnMgY29zaW5lIG9mIHRoZSBwYXNzZWQgYXJndW1lbnQuCi0gICAqCi0gICAqIEBwYXJhbSBudW0gQSBudW1iZXIKLSAgICogQHJldHVybiBUaGUgY29zaW5lIHZhbHVlIG9mIHRoZSBudW1iZXIKLSAgICovCi0gICBwdWJsaWMgc3RhdGljIGRvdWJsZSBjb3MoZG91YmxlIG51bSkKLSAgIHsKLSAgICAgcmV0dXJuIE1hdGguY29zKG51bSk7Ci0gICB9Ci0KLSAgLyoqCi0gICAqIFRoZSBtYXRoOmV4cCBmdW5jdGlvbiByZXR1cm5zIGUgKHRoZSBiYXNlIG9mIG5hdHVyYWwgbG9nYXJpdGhtcykgcmFpc2VkIHRvIGEgcG93ZXIuCi0gICAqCi0gICAqIEBwYXJhbSBudW0gQSBudW1iZXIKLSAgICogQHJldHVybiBUaGUgdmFsdWUgb2YgZSByYWlzZWQgdG8gdGhlIGdpdmVuIHBvd2VyCi0gICAqLwotICAgcHVibGljIHN0YXRpYyBkb3VibGUgZXhwKGRvdWJsZSBudW0pCi0gICB7Ci0gICAgIHJldHVybiBNYXRoLmV4cChudW0pOwotICAgfQotCi0gIC8qKgotICAgKiBUaGUgbWF0aDpsb2cgZnVuY3Rpb24gcmV0dXJucyB0aGUgbmF0dXJhbCBsb2dhcml0aG0gb2YgYSBudW1iZXIuCi0gICAqCi0gICAqIEBwYXJhbSBudW0gQSBudW1iZXIKLSAgICogQHJldHVybiBUaGUgbmF0dXJhbCBsb2dhcml0aG0gb2YgdGhlIG51bWJlcgotICAgKi8KLSAgIHB1YmxpYyBzdGF0aWMgZG91YmxlIGxvZyhkb3VibGUgbnVtKQotICAgewotICAgICByZXR1cm4gTWF0aC5sb2cobnVtKTsKLSAgIH0KLQotICAvKioKLSAgICogVGhlIG1hdGg6cG93ZXIgZnVuY3Rpb24gcmV0dXJucyB0aGUgdmFsdWUgb2YgYSBiYXNlIGV4cHJlc3Npb24gdGFrZW4gdG8gYSBzcGVjaWZpZWQgcG93ZXIuCi0gICAqCi0gICAqIEBwYXJhbSBudW0xIFRoZSBiYXNlCi0gICAqIEBwYXJhbSBudW0yIFRoZSBwb3dlcgotICAgKiBAcmV0dXJuIFRoZSB2YWx1ZSBvZiB0aGUgYmFzZSBleHByZXNzaW9uIHRha2VuIHRvIHRoZSBzcGVjaWZpZWQgcG93ZXIKLSAgICovCi0gICBwdWJsaWMgc3RhdGljIGRvdWJsZSBwb3dlcihkb3VibGUgbnVtMSwgZG91YmxlIG51bTIpCi0gICB7Ci0gICAgIHJldHVybiBNYXRoLnBvdyhudW0xLCBudW0yKTsKLSAgIH0KLQotICAvKioKLSAgICogVGhlIG1hdGg6cmFuZG9tIGZ1bmN0aW9uIHJldHVybnMgYSByYW5kb20gbnVtYmVyIGZyb20gMCB0byAxLgotICAgKgotICAgKiBAcmV0dXJuIEEgcmFuZG9tIGRvdWJsZSBmcm9tIDAgdG8gMQotICAgKi8KLSAgIHB1YmxpYyBzdGF0aWMgZG91YmxlIHJhbmRvbSgpCi0gICB7Ci0gICAgIHJldHVybiBNYXRoLnJhbmRvbSgpOwotICAgfQotCi0gIC8qKgotICAgKiBUaGUgbWF0aDpzaW4gZnVuY3Rpb24gcmV0dXJucyB0aGUgc2luZSBvZiB0aGUgbnVtYmVyLgotICAgKgotICAgKiBAcGFyYW0gbnVtIEEgbnVtYmVyCi0gICAqIEByZXR1cm4gVGhlIHNpbmUgdmFsdWUgb2YgdGhlIG51bWJlcgotICAgKi8KLSAgIHB1YmxpYyBzdGF0aWMgZG91YmxlIHNpbihkb3VibGUgbnVtKQotICAgewotICAgICByZXR1cm4gTWF0aC5zaW4obnVtKTsKLSAgIH0KLQotICAvKioKLSAgICogVGhlIG1hdGg6c3FydCBmdW5jdGlvbiByZXR1cm5zIHRoZSBzcXVhcmUgcm9vdCBvZiBhIG51bWJlci4KLSAgICoKLSAgICogQHBhcmFtIG51bSBBIG51bWJlcgotICAgKiBAcmV0dXJuIFRoZSBzcXVhcmUgcm9vdCBvZiB0aGUgbnVtYmVyCi0gICAqLwotICAgcHVibGljIHN0YXRpYyBkb3VibGUgc3FydChkb3VibGUgbnVtKQotICAgewotICAgICByZXR1cm4gTWF0aC5zcXJ0KG51bSk7Ci0gICB9Ci0KLSAgLyoqCi0gICAqIFRoZSBtYXRoOnRhbiBmdW5jdGlvbiByZXR1cm5zIHRoZSB0YW5nZW50IG9mIHRoZSBudW1iZXIgcGFzc2VkIGFzIGFuIGFyZ3VtZW50LgotICAgKgotICAgKiBAcGFyYW0gbnVtIEEgbnVtYmVyCi0gICAqIEByZXR1cm4gVGhlIHRhbmdlbnQgdmFsdWUgb2YgdGhlIG51bWJlcgotICAgKi8KLSAgIHB1YmxpYyBzdGF0aWMgZG91YmxlIHRhbihkb3VibGUgbnVtKQotICAgewotICAgICByZXR1cm4gTWF0aC50YW4obnVtKTsKLSAgIH0KLQotICAvKioKLSAgICogVGhlIG1hdGg6Y29uc3RhbnQgZnVuY3Rpb24gcmV0dXJucyB0aGUgc3BlY2lmaWVkIGNvbnN0YW50IHRvIGEgc2V0IHByZWNpc2lvbi4KLSAgICogVGhlIHBvc3NpYmxlIGNvbnN0YW50cyBhcmU6Ci0gICAqIDxwcmU+Ci0gICAqICBQSQotICAgKiAgRQotICAgKiAgU1FSUlQyCi0gICAqICBMTjIKLSAgICogIExOMTAKLSAgICogIExPRzJFCi0gICAqICBTUVJUMV8yCi0gICAqIDwvcHJlPgotICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgY29uc3RhbnQKLSAgICogQHBhcmFtIHByZWNpc2lvbiBUaGUgcHJlY2lzaW9uCi0gICAqIEByZXR1cm4gVGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgY29uc3RhbnQgdG8gdGhlIGdpdmVuIHByZWNpc2lvbgotICAgKi8KLSAgIHB1YmxpYyBzdGF0aWMgZG91YmxlIGNvbnN0YW50KFN0cmluZyBuYW1lLCBkb3VibGUgcHJlY2lzaW9uKQotICAgewotICAgICBTdHJpbmcgdmFsdWUgPSBudWxsOwotICAgICBpZiAobmFtZS5lcXVhbHMoIlBJIikpCi0gICAgICAgdmFsdWUgPSBQSTsKLSAgICAgZWxzZSBpZiAobmFtZS5lcXVhbHMoIkUiKSkKLSAgICAgICB2YWx1ZSA9IEU7Ci0gICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzKCJTUVJSVDIiKSkKLSAgICAgICB2YWx1ZSA9IFNRUlJUMjsKLSAgICAgZWxzZSBpZiAobmFtZS5lcXVhbHMoIkxOMiIpKQotICAgICAgIHZhbHVlID0gTE4yOwotICAgICBlbHNlIGlmIChuYW1lLmVxdWFscygiTE4xMCIpKQotICAgICAgIHZhbHVlID0gTE4xMDsKLSAgICAgZWxzZSBpZiAobmFtZS5lcXVhbHMoIkxPRzJFIikpCi0gICAgICAgdmFsdWUgPSBMT0cyRTsKLSAgICAgZWxzZSBpZiAobmFtZS5lcXVhbHMoIlNRUlQxXzIiKSkKLSAgICAgICB2YWx1ZSA9IFNRUlQxXzI7Ci0KLSAgICAgaWYgKHZhbHVlICE9IG51bGwpCi0gICAgIHsKLSAgICAgICBpbnQgYml0cyA9IG5ldyBEb3VibGUocHJlY2lzaW9uKS5pbnRWYWx1ZSgpOwotCi0gICAgICAgaWYgKGJpdHMgPD0gdmFsdWUubGVuZ3RoKCkpCi0gICAgICAgICB2YWx1ZSA9IHZhbHVlLnN1YnN0cmluZygwLCBiaXRzKTsKLQotICAgICAgIHJldHVybiBEb3VibGUucGFyc2VEb3VibGUodmFsdWUpOwotICAgICB9Ci0gICAgIGVsc2UKLSAgICAgICByZXR1cm4gRG91YmxlLk5hTjsKLQotICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL2xpYi9FeHNsdFNldHMuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwvbGliL0V4c2x0U2V0cy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0NmQ1ZGYxLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwvbGliL0V4c2x0U2V0cy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjQxICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKi8KLS8qCi0gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKLSAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAotICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgotICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKLSAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCi0gKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRXhzbHRTZXRzLmphdmEsdiAxLjEuMi4xIDIwMDUvMDgvMDEgMDI6MDg6NTAgamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC5saWI7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLkRPTUhlbHBlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuTm9kZVNldDsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKLWltcG9ydCBqYXZhLnV0aWwuTWFwOwotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZUxpc3Q7Ci0KLS8qKgotICogVGhpcyBjbGFzcyBjb250YWlucyBFWFNMVCBzZXQgZXh0ZW5zaW9uIGZ1bmN0aW9ucy4KLSAqIEl0IGlzIGFjY2Vzc2VkIGJ5IHNwZWNpZnlpbmcgYSBuYW1lc3BhY2UgVVJJIGFzIGZvbGxvd3M6Ci0gKiA8cHJlPgotICogICAgeG1sbnM6c2V0PSJodHRwOi8vZXhzbHQub3JnL3NldHMiCi0gKiA8L3ByZT4KLSAqCi0gKiBUaGUgZG9jdW1lbnRhdGlvbiBmb3IgZWFjaCBmdW5jdGlvbiBoYXMgYmVlbiBjb3BpZWQgZnJvbSB0aGUgcmVsZXZhbnQKLSAqIEVYU0xUIEltcGxlbWVudGVyIHBhZ2UuCi0gKgotICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LmV4c2x0Lm9yZy8iPkVYU0xUPC9hPgotICogQHhzbC51c2FnZSBnZW5lcmFsCi0gKi8KLXB1YmxpYyBjbGFzcyBFeHNsdFNldHMgZXh0ZW5kcyBFeHNsdEJhc2UKLXsKLSAgLyoqCi0gICAqIFRoZSBzZXQ6bGVhZGluZyBmdW5jdGlvbiByZXR1cm5zIHRoZSBub2RlcyBpbiB0aGUgbm9kZSBzZXQgcGFzc2VkIGFzIHRoZSBmaXJzdCBhcmd1bWVudCB0aGF0Ci0gICAqIHByZWNlZGUsIGluIGRvY3VtZW50IG9yZGVyLCB0aGUgZmlyc3Qgbm9kZSBpbiB0aGUgbm9kZSBzZXQgcGFzc2VkIGFzIHRoZSBzZWNvbmQgYXJndW1lbnQuIElmCi0gICAqIHRoZSBmaXJzdCBub2RlIGluIHRoZSBzZWNvbmQgbm9kZSBzZXQgaXMgbm90IGNvbnRhaW5lZCBpbiB0aGUgZmlyc3Qgbm9kZSBzZXQsIHRoZW4gYW4gZW1wdHkKLSAgICogbm9kZSBzZXQgaXMgcmV0dXJuZWQuIElmIHRoZSBzZWNvbmQgbm9kZSBzZXQgaXMgZW1wdHksIHRoZW4gdGhlIGZpcnN0IG5vZGUgc2V0IGlzIHJldHVybmVkLgotICAgKgotICAgKiBAcGFyYW0gbmwxIE5vZGVMaXN0IGZvciBmaXJzdCBub2RlLXNldC4KLSAgICogQHBhcmFtIG5sMiBOb2RlTGlzdCBmb3Igc2Vjb25kIG5vZGUtc2V0LgotICAgKiBAcmV0dXJuIGEgTm9kZUxpc3QgY29udGFpbmluZyB0aGUgbm9kZXMgaW4gbmwxIHRoYXQgcHJlY2VkZSBpbiBkb2N1bWVudCBvcmRlciB0aGUgZmlyc3QKLSAgICogbm9kZSBpbiBubDI7IGFuIGVtcHR5IG5vZGUtc2V0IGlmIHRoZSBmaXJzdCBub2RlIGluIG5sMiBpcyBub3QgaW4gbmwxOyBhbGwgb2YgbmwxIGlmIG5sMgotICAgKiBpcyBlbXB0eS4KLSAgICoKLSAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LmV4c2x0Lm9yZy8iPkVYU0xUPC9hPgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBOb2RlTGlzdCBsZWFkaW5nIChOb2RlTGlzdCBubDEsIE5vZGVMaXN0IG5sMikKLSAgewotICAgIGlmIChubDIuZ2V0TGVuZ3RoKCkgPT0gMCkKLSAgICAgIHJldHVybiBubDE7Ci0KLSAgICBOb2RlU2V0IG5zMSA9IG5ldyBOb2RlU2V0KG5sMSk7Ci0gICAgTm9kZVNldCBsZWFkTm9kZXMgPSBuZXcgTm9kZVNldCgpOwotICAgIE5vZGUgZW5kTm9kZSA9IG5sMi5pdGVtKDApOwotICAgIGlmICghbnMxLmNvbnRhaW5zKGVuZE5vZGUpKQotICAgICAgcmV0dXJuIGxlYWROb2RlczsgLy8gZW1wdHkgTm9kZVNldAotCi0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBubDEuZ2V0TGVuZ3RoKCk7IGkrKykKLSAgICB7Ci0gICAgICBOb2RlIHRlc3ROb2RlID0gbmwxLml0ZW0oaSk7Ci0gICAgICBpZiAoRE9NSGVscGVyLmlzTm9kZUFmdGVyKHRlc3ROb2RlLCBlbmROb2RlKQotICAgICAgICAgICYmICFET01IZWxwZXIuaXNOb2RlVGhlU2FtZSh0ZXN0Tm9kZSwgZW5kTm9kZSkpCi0gICAgICAgIGxlYWROb2Rlcy5hZGRFbGVtZW50KHRlc3ROb2RlKTsKLSAgICB9Ci0gICAgcmV0dXJuIGxlYWROb2RlczsKLSAgfQotCi0gIC8qKgotICAgKiBUaGUgc2V0OnRyYWlsaW5nIGZ1bmN0aW9uIHJldHVybnMgdGhlIG5vZGVzIGluIHRoZSBub2RlIHNldCBwYXNzZWQgYXMgdGhlIGZpcnN0IGFyZ3VtZW50IHRoYXQKLSAgICogZm9sbG93LCBpbiBkb2N1bWVudCBvcmRlciwgdGhlIGZpcnN0IG5vZGUgaW4gdGhlIG5vZGUgc2V0IHBhc3NlZCBhcyB0aGUgc2Vjb25kIGFyZ3VtZW50LiBJZgotICAgKiB0aGUgZmlyc3Qgbm9kZSBpbiB0aGUgc2Vjb25kIG5vZGUgc2V0IGlzIG5vdCBjb250YWluZWQgaW4gdGhlIGZpcnN0IG5vZGUgc2V0LCB0aGVuIGFuIGVtcHR5Ci0gICAqIG5vZGUgc2V0IGlzIHJldHVybmVkLiBJZiB0aGUgc2Vjb25kIG5vZGUgc2V0IGlzIGVtcHR5LCB0aGVuIHRoZSBmaXJzdCBub2RlIHNldCBpcyByZXR1cm5lZC4KLSAgICoKLSAgICogQHBhcmFtIG5sMSBOb2RlTGlzdCBmb3IgZmlyc3Qgbm9kZS1zZXQuCi0gICAqIEBwYXJhbSBubDIgTm9kZUxpc3QgZm9yIHNlY29uZCBub2RlLXNldC4KLSAgICogQHJldHVybiBhIE5vZGVMaXN0IGNvbnRhaW5pbmcgdGhlIG5vZGVzIGluIG5sMSB0aGF0IGZvbGxvdyBpbiBkb2N1bWVudCBvcmRlciB0aGUgZmlyc3QKLSAgICogbm9kZSBpbiBubDI7IGFuIGVtcHR5IG5vZGUtc2V0IGlmIHRoZSBmaXJzdCBub2RlIGluIG5sMiBpcyBub3QgaW4gbmwxOyBhbGwgb2YgbmwxIGlmIG5sMgotICAgKiBpcyBlbXB0eS4KLSAgICoKLSAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LmV4c2x0Lm9yZy8iPkVYU0xUPC9hPgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBOb2RlTGlzdCB0cmFpbGluZyAoTm9kZUxpc3QgbmwxLCBOb2RlTGlzdCBubDIpCi0gIHsKLSAgICBpZiAobmwyLmdldExlbmd0aCgpID09IDApCi0gICAgICByZXR1cm4gbmwxOwotCi0gICAgTm9kZVNldCBuczEgPSBuZXcgTm9kZVNldChubDEpOwotICAgIE5vZGVTZXQgdHJhaWxOb2RlcyA9IG5ldyBOb2RlU2V0KCk7Ci0gICAgTm9kZSBzdGFydE5vZGUgPSBubDIuaXRlbSgwKTsKLSAgICBpZiAoIW5zMS5jb250YWlucyhzdGFydE5vZGUpKQotICAgICAgcmV0dXJuIHRyYWlsTm9kZXM7IC8vIGVtcHR5IE5vZGVTZXQKLQotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbmwxLmdldExlbmd0aCgpOyBpKyspCi0gICAgewotICAgICAgTm9kZSB0ZXN0Tm9kZSA9IG5sMS5pdGVtKGkpOwotICAgICAgaWYgKERPTUhlbHBlci5pc05vZGVBZnRlcihzdGFydE5vZGUsIHRlc3ROb2RlKQotICAgICAgICAgICYmICFET01IZWxwZXIuaXNOb2RlVGhlU2FtZShzdGFydE5vZGUsIHRlc3ROb2RlKSkKLSAgICAgICAgdHJhaWxOb2Rlcy5hZGRFbGVtZW50KHRlc3ROb2RlKTsKLSAgICB9Ci0gICAgcmV0dXJuIHRyYWlsTm9kZXM7Ci0gIH0KLQotICAvKioKLSAgICogVGhlIHNldDppbnRlcnNlY3Rpb24gZnVuY3Rpb24gcmV0dXJucyBhIG5vZGUgc2V0IGNvbXByaXNpbmcgdGhlIG5vZGVzIHRoYXQgYXJlIHdpdGhpbgotICAgKiBib3RoIHRoZSBub2RlIHNldHMgcGFzc2VkIGFzIGFyZ3VtZW50cyB0byBpdC4KLSAgICoKLSAgICogQHBhcmFtIG5sMSBOb2RlTGlzdCBmb3IgZmlyc3Qgbm9kZS1zZXQuCi0gICAqIEBwYXJhbSBubDIgTm9kZUxpc3QgZm9yIHNlY29uZCBub2RlLXNldC4KLSAgICogQHJldHVybiBhIE5vZGVMaXN0IGNvbnRhaW5pbmcgdGhlIG5vZGVzIGluIG5sMSB0aGF0IGFyZSBhbHNvCi0gICAqIGluIG5sMi4KLSAgICoKLSAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LmV4c2x0Lm9yZy8iPkVYU0xUPC9hPgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBOb2RlTGlzdCBpbnRlcnNlY3Rpb24oTm9kZUxpc3QgbmwxLCBOb2RlTGlzdCBubDIpCi0gIHsKLSAgICBOb2RlU2V0IG5zMSA9IG5ldyBOb2RlU2V0KG5sMSk7Ci0gICAgTm9kZVNldCBuczIgPSBuZXcgTm9kZVNldChubDIpOwotICAgIE5vZGVTZXQgaW50ZXIgPSBuZXcgTm9kZVNldCgpOwotCi0gICAgaW50ZXIuc2V0U2hvdWxkQ2FjaGVOb2Rlcyh0cnVlKTsKLQotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnMxLmdldExlbmd0aCgpOyBpKyspCi0gICAgewotICAgICAgTm9kZSBuID0gbnMxLmVsZW1lbnRBdChpKTsKLQotICAgICAgaWYgKG5zMi5jb250YWlucyhuKSkKLSAgICAgICAgaW50ZXIuYWRkRWxlbWVudChuKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gaW50ZXI7Ci0gIH0KLQotICAvKioKLSAgICogVGhlIHNldDpkaWZmZXJlbmNlIGZ1bmN0aW9uIHJldHVybnMgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0d28gbm9kZSBzZXRzIC0gdGhvc2Ugbm9kZXMgdGhhdAotICAgKiBhcmUgaW4gdGhlIG5vZGUgc2V0IHBhc3NlZCBhcyB0aGUgZmlyc3QgYXJndW1lbnQgdGhhdCBhcmUgbm90IGluIHRoZSBub2RlIHNldCBwYXNzZWQgYXMgdGhlCi0gICAqIHNlY29uZCBhcmd1bWVudC4KLSAgICoKLSAgICogQHBhcmFtIG5sMSBOb2RlTGlzdCBmb3IgZmlyc3Qgbm9kZS1zZXQuCi0gICAqIEBwYXJhbSBubDIgTm9kZUxpc3QgZm9yIHNlY29uZCBub2RlLXNldC4KLSAgICogQHJldHVybiBhIE5vZGVMaXN0IGNvbnRhaW5pbmcgdGhlIG5vZGVzIGluIG5sMSB0aGF0IGFyZSBub3QgaW4gbmwyLgotICAgKgotICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cuZXhzbHQub3JnLyI+RVhTTFQ8L2E+Ci0gICAqLwotICBwdWJsaWMgc3RhdGljIE5vZGVMaXN0IGRpZmZlcmVuY2UoTm9kZUxpc3QgbmwxLCBOb2RlTGlzdCBubDIpCi0gIHsKLSAgICBOb2RlU2V0IG5zMSA9IG5ldyBOb2RlU2V0KG5sMSk7Ci0gICAgTm9kZVNldCBuczIgPSBuZXcgTm9kZVNldChubDIpOwotCi0gICAgTm9kZVNldCBkaWZmID0gbmV3IE5vZGVTZXQoKTsKLQotICAgIGRpZmYuc2V0U2hvdWxkQ2FjaGVOb2Rlcyh0cnVlKTsKLQotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnMxLmdldExlbmd0aCgpOyBpKyspCi0gICAgewotICAgICAgTm9kZSBuID0gbnMxLmVsZW1lbnRBdChpKTsKLQotICAgICAgaWYgKCFuczIuY29udGFpbnMobikpCi0gICAgICAgIGRpZmYuYWRkRWxlbWVudChuKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gZGlmZjsKLSAgfQotCi0gIC8qKgotICAgKiBUaGUgc2V0OmRpc3RpbmN0IGZ1bmN0aW9uIHJldHVybnMgYSBzdWJzZXQgb2YgdGhlIG5vZGVzIGNvbnRhaW5lZCBpbiB0aGUgbm9kZS1zZXQgTlMgcGFzc2VkCi0gICAqIGFzIHRoZSBmaXJzdCBhcmd1bWVudC4gU3BlY2lmaWNhbGx5LCBpdCBzZWxlY3RzIGEgbm9kZSBOIGlmIHRoZXJlIGlzIG5vIG5vZGUgaW4gTlMgdGhhdCBoYXMKLSAgICogdGhlIHNhbWUgc3RyaW5nIHZhbHVlIGFzIE4sIGFuZCB0aGF0IHByZWNlZGVzIE4gaW4gZG9jdW1lbnQgb3JkZXIuCi0gICAqCi0gICAqIEBwYXJhbSBubCBOb2RlTGlzdCBmb3IgdGhlIG5vZGUtc2V0LgotICAgKiBAcmV0dXJuIGEgTm9kZUxpc3Qgd2l0aCBub2RlcyBmcm9tIG5sIGNvbnRhaW5pbmcgZGlzdGluY3Qgc3RyaW5nIHZhbHVlcy4KLSAgICogSW4gb3RoZXIgd29yZHMsIGlmIG1vcmUgdGhhbiBvbmUgbm9kZSBpbiBubCBjb250YWlucyB0aGUgc2FtZSBzdHJpbmcgdmFsdWUsCi0gICAqIG9ubHkgaW5jbHVkZSB0aGUgZmlyc3Qgc3VjaCBub2RlIGZvdW5kLgotICAgKgotICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cuZXhzbHQub3JnLyI+RVhTTFQ8L2E+Ci0gICAqLwotICBwdWJsaWMgc3RhdGljIE5vZGVMaXN0IGRpc3RpbmN0KE5vZGVMaXN0IG5sKQotICB7Ci0gICAgTm9kZVNldCBkaXN0ID0gbmV3IE5vZGVTZXQoKTsKLSAgICBkaXN0LnNldFNob3VsZENhY2hlTm9kZXModHJ1ZSk7Ci0KLSAgICBNYXA8U3RyaW5nLCBOb2RlPiBzdHJpbmdUYWJsZSA9IG5ldyBIYXNoTWFwPD4oKTsKLQotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbmwuZ2V0TGVuZ3RoKCk7IGkrKykKLSAgICB7Ci0gICAgICBOb2RlIGN1cnJOb2RlID0gbmwuaXRlbShpKTsKLSAgICAgIFN0cmluZyBrZXkgPSB0b1N0cmluZyhjdXJyTm9kZSk7Ci0KLSAgICAgIGlmIChrZXkgPT0gbnVsbCkKLSAgICAgICAgZGlzdC5hZGRFbGVtZW50KGN1cnJOb2RlKTsKLSAgICAgIGVsc2UgaWYgKCFzdHJpbmdUYWJsZS5jb250YWluc0tleShrZXkpKQotICAgICAgewotICAgICAgICBzdHJpbmdUYWJsZS5wdXQoa2V5LCBjdXJyTm9kZSk7Ci0gICAgICAgIGRpc3QuYWRkRWxlbWVudChjdXJyTm9kZSk7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgcmV0dXJuIGRpc3Q7Ci0gIH0KLQotICAvKioKLSAgICogVGhlIHNldDpoYXMtc2FtZS1ub2RlIGZ1bmN0aW9uIHJldHVybnMgdHJ1ZSBpZiB0aGUgbm9kZSBzZXQgcGFzc2VkIGFzIHRoZSBmaXJzdCBhcmd1bWVudCBzaGFyZXMKLSAgICogYW55IG5vZGVzIHdpdGggdGhlIG5vZGUgc2V0IHBhc3NlZCBhcyB0aGUgc2Vjb25kIGFyZ3VtZW50LiBJZiB0aGVyZSBhcmUgbm8gbm9kZXMgdGhhdCBhcmUgaW4gYm90aAotICAgKiBub2RlIHNldHMsIHRoZW4gaXQgcmV0dXJucyBmYWxzZS4KLSAgICoKLSAgICogVGhlIFhhbGFuIGV4dGVuc2lvbnMgTWV0aG9kUmVzb2x2ZXIgY29udmVydHMgJ2hhcy1zYW1lLW5vZGUnIHRvICdoYXNTYW1lTm9kZScuCi0gICAqCi0gICAqIE5vdGU6IE5vdCB0byBiZSBjb25mdXNlZCB3aXRoIGhhc1NhbWVOb2RlcyBpbiB0aGUgWGFsYW4gbmFtZXNwYWNlLCB3aGljaCByZXR1cm5zIHRydWUgaWYKLSAgICogdGhlIHR3byBub2RlIHNldHMgY29udGFpbiB0aGUgZXhhY3RseSB0aGUgc2FtZSBub2RlcyAocGVyaGFwcyBpbiBhIGRpZmZlcmVudCBvcmRlciksCi0gICAqIG90aGVyd2lzZSBmYWxzZS4KLSAgICoKLSAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LmV4c2x0Lm9yZy8iPkVYU0xUPC9hPgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBib29sZWFuIGhhc1NhbWVOb2RlKE5vZGVMaXN0IG5sMSwgTm9kZUxpc3QgbmwyKQotICB7Ci0KLSAgICBOb2RlU2V0IG5zMSA9IG5ldyBOb2RlU2V0KG5sMSk7Ci0gICAgTm9kZVNldCBuczIgPSBuZXcgTm9kZVNldChubDIpOwotCi0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuczEuZ2V0TGVuZ3RoKCk7IGkrKykKLSAgICB7Ci0gICAgICBpZiAobnMyLmNvbnRhaW5zKG5zMS5lbGVtZW50QXQoaSkpKQotICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICB9Ci0gICAgcmV0dXJuIGZhbHNlOwotICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwvbGliL0V4c2x0U3RyaW5ncy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC9saWIvRXhzbHRTdHJpbmdzLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGFhOGJlYTUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC9saWIvRXhzbHRTdHJpbmdzLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzNTEgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRXhzbHRTdHJpbmdzLmphdmEsdiAxLjEuMi4xIDIwMDUvMDgvMDEgMDI6MDg6NDggamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC5saWI7Ci0KLWltcG9ydCBqYXZhLnV0aWwuU3RyaW5nVG9rZW5pemVyOwotCi1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy5GYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yOwotaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLlBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuTm9kZVNldDsKLQotaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLkVsZW1lbnQ7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlTGlzdDsKLWltcG9ydCBvcmcudzNjLmRvbS5UZXh0OwotCi0vKioKLSAqIFRoaXMgY2xhc3MgY29udGFpbnMgRVhTTFQgc3RyaW5ncyBleHRlbnNpb24gZnVuY3Rpb25zLgotICoKLSAqIEl0IGlzIGFjY2Vzc2VkIGJ5IHNwZWNpZnlpbmcgYSBuYW1lc3BhY2UgVVJJIGFzIGZvbGxvd3M6Ci0gKiA8cHJlPgotICogICAgeG1sbnM6c3RyPSJodHRwOi8vZXhzbHQub3JnL3N0cmluZ3MiCi0gKiA8L3ByZT4KLSAqIFRoZSBkb2N1bWVudGF0aW9uIGZvciBlYWNoIGZ1bmN0aW9uIGhhcyBiZWVuIGNvcGllZCBmcm9tIHRoZSByZWxldmFudAotICogRVhTTFQgSW1wbGVtZW50ZXIgcGFnZS4KLSAqCi0gKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cuZXhzbHQub3JnLyI+RVhTTFQ8L2E+Ci0KLSAqIEB4c2wudXNhZ2UgZ2VuZXJhbAotICovCi1wdWJsaWMgY2xhc3MgRXhzbHRTdHJpbmdzIGV4dGVuZHMgRXhzbHRCYXNlCi17Ci0gICBzdGF0aWMgZmluYWwgU3RyaW5nIEpES19ERUZBVUxUX0RPTSA9ICJjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmpheHAuRG9jdW1lbnRCdWlsZGVyRmFjdG9yeUltcGwiOwotCi0gIC8qKgotICAgKiBUaGUgc3RyOmFsaWduIGZ1bmN0aW9uIGFsaWducyBhIHN0cmluZyB3aXRoaW4gYW5vdGhlciBzdHJpbmcuCi0gICAqIDxwPgotICAgKiBUaGUgZmlyc3QgYXJndW1lbnQgZ2l2ZXMgdGhlIHRhcmdldCBzdHJpbmcgdG8gYmUgYWxpZ25lZC4gVGhlIHNlY29uZCBhcmd1bWVudCBnaXZlcwotICAgKiB0aGUgcGFkZGluZyBzdHJpbmcgd2l0aGluIHdoaWNoIGl0IGlzIHRvIGJlIGFsaWduZWQuCi0gICAqIDxwPgotICAgKiBJZiB0aGUgdGFyZ2V0IHN0cmluZyBpcyBzaG9ydGVyIHRoYW4gdGhlIHBhZGRpbmcgc3RyaW5nIHRoZW4gYSByYW5nZSBvZiBjaGFyYWN0ZXJzCi0gICAqIGluIHRoZSBwYWRkaW5nIHN0cmluZyBhcmUgcmVwYWNlZCB3aXRoIHRob3NlIGluIHRoZSB0YXJnZXQgc3RyaW5nLiBXaGljaCBjaGFyYWN0ZXJzCi0gICAqIGFyZSByZXBsYWNlZCBkZXBlbmRzIG9uIHRoZSB2YWx1ZSBvZiB0aGUgdGhpcmQgYXJndW1lbnQsIHdoaWNoIGdpdmVzIHRoZSB0eXBlIG9mCi0gICAqIGFsaWdubWVudC4gSXQgY2FuIGJlIG9uZSBvZiAnbGVmdCcsICdyaWdodCcgb3IgJ2NlbnRlcicuIElmIG5vIHRoaXJkIGFyZ3VtZW50IGlzCi0gICAqIGdpdmVuIG9yIGlmIGl0IGlzIG5vdCBvbmUgb2YgdGhlc2UgdmFsdWVzLCB0aGVuIGl0IGRlZmF1bHRzIHRvIGxlZnQgYWxpZ25tZW50LgotICAgKiA8cD4KLSAgICogV2l0aCBsZWZ0IGFsaWdubWVudCwgdGhlIHJhbmdlIG9mIGNoYXJhY3RlcnMgcmVwbGFjZWQgYnkgdGhlIHRhcmdldCBzdHJpbmcgYmVnaW5zCi0gICAqIHdpdGggdGhlIGZpcnN0IGNoYXJhY3RlciBpbiB0aGUgcGFkZGluZyBzdHJpbmcuIFdpdGggcmlnaHQgYWxpZ25tZW50LCB0aGUgcmFuZ2Ugb2YKLSAgICogY2hhcmFjdGVycyByZXBsYWNlZCBieSB0aGUgdGFyZ2V0IHN0cmluZyBlbmRzIHdpdGggdGhlIGxhc3QgY2hhcmFjdGVyIGluIHRoZSBwYWRkaW5nCi0gICAqIHN0cmluZy4gV2l0aCBjZW50ZXIgYWxpZ25tZW50LCB0aGUgcmFuZ2Ugb2YgY2hhcmFjdGVycyByZXBsYWNlZCBieSB0aGUgdGFyZ2V0IHN0cmluZwotICAgKiBpcyBpbiB0aGUgbWlkZGxlIG9mIHRoZSBwYWRkaW5nIHN0cmluZywgc3VjaCB0aGF0IGVpdGhlciB0aGUgbnVtYmVyIG9mIHVucmVwbGFjZWQKLSAgICogY2hhcmFjdGVycyBvbiBlaXRoZXIgc2lkZSBvZiB0aGUgcmFuZ2UgaXMgdGhlIHNhbWUgb3IgdGhlcmUgaXMgb25lIGxlc3Mgb24gdGhlIGxlZnQKLSAgICogdGhhbiB0aGVyZSBpcyBvbiB0aGUgcmlnaHQuCi0gICAqIDxwPgotICAgKiBJZiB0aGUgdGFyZ2V0IHN0cmluZyBpcyBsb25nZXIgdGhhbiB0aGUgcGFkZGluZyBzdHJpbmcsIHRoZW4gaXQgaXMgdHJ1bmNhdGVkIHRvIGJlCi0gICAqIHRoZSBzYW1lIGxlbmd0aCBhcyB0aGUgcGFkZGluZyBzdHJpbmcgYW5kIHJldHVybmVkLgotICAgKgotICAgKiBAcGFyYW0gdGFyZ2V0U3RyIFRoZSB0YXJnZXQgc3RyaW5nCi0gICAqIEBwYXJhbSBwYWRkaW5nU3RyIFRoZSBwYWRkaW5nIHN0cmluZwotICAgKiBAcGFyYW0gdHlwZSBUaGUgdHlwZSBvZiBhbGlnbm1lbnQKLSAgICoKLSAgICogQHJldHVybiBUaGUgc3RyaW5nIGFmdGVyIGFsaWdubWVudAotICAgKi8KLSAgcHVibGljIHN0YXRpYyBTdHJpbmcgYWxpZ24oU3RyaW5nIHRhcmdldFN0ciwgU3RyaW5nIHBhZGRpbmdTdHIsIFN0cmluZyB0eXBlKQotICB7Ci0gICAgaWYgKHRhcmdldFN0ci5sZW5ndGgoKSA+PSBwYWRkaW5nU3RyLmxlbmd0aCgpKQotICAgICAgcmV0dXJuIHRhcmdldFN0ci5zdWJzdHJpbmcoMCwgcGFkZGluZ1N0ci5sZW5ndGgoKSk7Ci0KLSAgICBpZiAodHlwZS5lcXVhbHMoInJpZ2h0IikpCi0gICAgewotICAgICAgcmV0dXJuIHBhZGRpbmdTdHIuc3Vic3RyaW5nKDAsIHBhZGRpbmdTdHIubGVuZ3RoKCkgLSB0YXJnZXRTdHIubGVuZ3RoKCkpICsgdGFyZ2V0U3RyOwotICAgIH0KLSAgICBlbHNlIGlmICh0eXBlLmVxdWFscygiY2VudGVyIikpCi0gICAgewotICAgICAgaW50IHN0YXJ0SW5kZXggPSAocGFkZGluZ1N0ci5sZW5ndGgoKSAtIHRhcmdldFN0ci5sZW5ndGgoKSkgLyAyOwotICAgICAgcmV0dXJuIHBhZGRpbmdTdHIuc3Vic3RyaW5nKDAsIHN0YXJ0SW5kZXgpICsgdGFyZ2V0U3RyICsgcGFkZGluZ1N0ci5zdWJzdHJpbmcoc3RhcnRJbmRleCArIHRhcmdldFN0ci5sZW5ndGgoKSk7Ci0gICAgfQotICAgIC8vIERlZmF1bHQgaXMgbGVmdAotICAgIGVsc2UKLSAgICB7Ci0gICAgICByZXR1cm4gdGFyZ2V0U3RyICsgcGFkZGluZ1N0ci5zdWJzdHJpbmcodGFyZ2V0U3RyLmxlbmd0aCgpKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogU2VlIGFib3ZlCi0gICAqLwotICBwdWJsaWMgc3RhdGljIFN0cmluZyBhbGlnbihTdHJpbmcgdGFyZ2V0U3RyLCBTdHJpbmcgcGFkZGluZ1N0cikKLSAgewotICAgIHJldHVybiBhbGlnbih0YXJnZXRTdHIsIHBhZGRpbmdTdHIsICJsZWZ0Iik7Ci0gIH0KLQotICAvKioKLSAgICogVGhlIHN0cjpjb25jYXQgZnVuY3Rpb24gdGFrZXMgYSBub2RlIHNldCBhbmQgcmV0dXJucyB0aGUgY29uY2F0ZW5hdGlvbiBvZiB0aGUKLSAgICogc3RyaW5nIHZhbHVlcyBvZiB0aGUgbm9kZXMgaW4gdGhhdCBub2RlIHNldC4gSWYgdGhlIG5vZGUgc2V0IGlzIGVtcHR5LCBpdCByZXR1cm5zCi0gICAqIGFuIGVtcHR5IHN0cmluZy4KLSAgICoKLSAgICogQHBhcmFtIG5sIEEgbm9kZSBzZXQKLSAgICogQHJldHVybiBUaGUgY29uY2F0ZW5hdGlvbiBvZiB0aGUgc3RyaW5nIHZhbHVlcyBvZiB0aGUgbm9kZXMgaW4gdGhhdCBub2RlIHNldAotICAgKi8KLSAgcHVibGljIHN0YXRpYyBTdHJpbmcgY29uY2F0KE5vZGVMaXN0IG5sKQotICB7Ci0gICAgU3RyaW5nQnVmZmVyIHNiID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbmwuZ2V0TGVuZ3RoKCk7IGkrKykKLSAgICB7Ci0gICAgICBOb2RlIG5vZGUgPSBubC5pdGVtKGkpOwotICAgICAgU3RyaW5nIHZhbHVlID0gdG9TdHJpbmcobm9kZSk7Ci0KLSAgICAgIGlmICh2YWx1ZSAhPSBudWxsICYmIHZhbHVlLmxlbmd0aCgpID4gMCkKLSAgICAgICAgc2IuYXBwZW5kKHZhbHVlKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKLSAgfQotCi0gIC8qKgotICAgKiBUaGUgc3RyOnBhZGRpbmcgZnVuY3Rpb24gY3JlYXRlcyBhIHBhZGRpbmcgc3RyaW5nIG9mIGEgY2VydGFpbiBsZW5ndGguCi0gICAqIFRoZSBmaXJzdCBhcmd1bWVudCBnaXZlcyB0aGUgbGVuZ3RoIG9mIHRoZSBwYWRkaW5nIHN0cmluZyB0byBiZSBjcmVhdGVkLgotICAgKiBUaGUgc2Vjb25kIGFyZ3VtZW50IGdpdmVzIGEgc3RyaW5nIHRvIGJlIHVzZWQgdG8gY3JlYXRlIHRoZSBwYWRkaW5nLiBUaGlzCi0gICAqIHN0cmluZyBpcyByZXBlYXRlZCBhcyBtYW55IHRpbWVzIGFzIGlzIG5lY2Vzc2FyeSB0byBjcmVhdGUgYSBzdHJpbmcgb2YgdGhlCi0gICAqIGxlbmd0aCBzcGVjaWZpZWQgYnkgdGhlIGZpcnN0IGFyZ3VtZW50OyBpZiB0aGUgc3RyaW5nIGlzIG1vcmUgdGhhbiBhIGNoYXJhY3RlcgotICAgKiBsb25nLCBpdCBtYXkgaGF2ZSB0byBiZSB0cnVuY2F0ZWQgdG8gcHJvZHVjZSB0aGUgcmVxdWlyZWQgbGVuZ3RoLiBJZiBubyBzZWNvbmQKLSAgICogYXJndW1lbnQgaXMgc3BlY2lmaWVkLCBpdCBkZWZhdWx0cyB0byBhIHNwYWNlICgnICcpLiBJZiB0aGUgc2Vjb25kIGFyZ3VtZW50IGlzCi0gICAqIGFuIGVtcHR5IHN0cmluZywgc3RyOnBhZGRpbmcgcmV0dXJucyBhbiBlbXB0eSBzdHJpbmcuCi0gICAqCi0gICAqIEBwYXJhbSBsZW5ndGggVGhlIGxlbmd0aCBvZiB0aGUgcGFkZGluZyBzdHJpbmcgdG8gYmUgY3JlYXRlZAotICAgKiBAcGFyYW0gcGF0dGVybiBUaGUgc3RyaW5nIHRvIGJlIHVzZWQgYXMgcGF0dGVybgotICAgKgotICAgKiBAcmV0dXJuIEEgcGFkZGluZyBzdHJpbmcgb2YgdGhlIGdpdmVuIGxlbmd0aAotICAgKi8KLSAgcHVibGljIHN0YXRpYyBTdHJpbmcgcGFkZGluZyhkb3VibGUgbGVuZ3RoLCBTdHJpbmcgcGF0dGVybikKLSAgewotICAgIGlmIChwYXR0ZXJuID09IG51bGwgfHwgcGF0dGVybi5sZW5ndGgoKSA9PSAwKQotICAgICAgcmV0dXJuICIiOwotCi0gICAgU3RyaW5nQnVmZmVyIHNiID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotICAgIGludCBsZW4gPSAoaW50KWxlbmd0aDsKLSAgICBpbnQgbnVtQWRkZWQgPSAwOwotICAgIGludCBpbmRleCA9IDA7Ci0gICAgd2hpbGUgKG51bUFkZGVkIDwgbGVuKQotICAgIHsKLSAgICAgIGlmIChpbmRleCA9PSBwYXR0ZXJuLmxlbmd0aCgpKQotICAgICAgICBpbmRleCA9IDA7Ci0KLSAgICAgIHNiLmFwcGVuZChwYXR0ZXJuLmNoYXJBdChpbmRleCkpOwotICAgICAgaW5kZXgrKzsKLSAgICAgIG51bUFkZGVkKys7Ci0gICAgfQotCi0gICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7Ci0gIH0KLQotICAvKioKLSAgICogU2VlIGFib3ZlCi0gICAqLwotICBwdWJsaWMgc3RhdGljIFN0cmluZyBwYWRkaW5nKGRvdWJsZSBsZW5ndGgpCi0gIHsKLSAgICByZXR1cm4gcGFkZGluZyhsZW5ndGgsICIgIik7Ci0gIH0KLQotICAvKioKLSAgICogVGhlIHN0cjpzcGxpdCBmdW5jdGlvbiBzcGxpdHMgdXAgYSBzdHJpbmcgYW5kIHJldHVybnMgYSBub2RlIHNldCBvZiB0b2tlbgotICAgKiBlbGVtZW50cywgZWFjaCBjb250YWluaW5nIG9uZSB0b2tlbiBmcm9tIHRoZSBzdHJpbmcuCi0gICAqIDxwPgotICAgKiBUaGUgZmlyc3QgYXJndW1lbnQgaXMgdGhlIHN0cmluZyB0byBiZSBzcGxpdC4gVGhlIHNlY29uZCBhcmd1bWVudCBpcyBhIHBhdHRlcm4KLSAgICogc3RyaW5nLiBUaGUgc3RyaW5nIGdpdmVuIGJ5IHRoZSBmaXJzdCBhcmd1bWVudCBpcyBzcGxpdCBhdCBhbnkgb2NjdXJyZW5jZSBvZgotICAgKiB0aGlzIHBhdHRlcm4uIEZvciBleGFtcGxlOgotICAgKiA8cHJlPgotICAgKiBzdHI6c3BsaXQoJ2EsIHNpbXBsZSwgbGlzdCcsICcsICcpIGdpdmVzIHRoZSBub2RlIHNldCBjb25zaXN0aW5nIG9mOgotICAgKgotICAgKiA8dG9rZW4+YTwvdG9rZW4+Ci0gICAqIDx0b2tlbj5zaW1wbGU8L3Rva2VuPgotICAgKiA8dG9rZW4+bGlzdDwvdG9rZW4+Ci0gICAqIDwvcHJlPgotICAgKiBJZiB0aGUgc2Vjb25kIGFyZ3VtZW50IGlzIG9taXR0ZWQsIHRoZSBkZWZhdWx0IGlzIHRoZSBzdHJpbmcgJyYjeDIwOycgKGkuZS4gYSBzcGFjZSkuCi0gICAqCi0gICAqIEBwYXJhbSBzdHIgVGhlIHN0cmluZyB0byBiZSBzcGxpdAotICAgKiBAcGFyYW0gcGF0dGVybiBUaGUgcGF0dGVybgotICAgKgotICAgKiBAcmV0dXJuIEEgbm9kZSBzZXQgb2Ygc3BsaXQgdG9rZW5zCi0gICAqLwotICBwdWJsaWMgc3RhdGljIE5vZGVMaXN0IHNwbGl0KFN0cmluZyBzdHIsIFN0cmluZyBwYXR0ZXJuKQotICB7Ci0KLQotICAgIE5vZGVTZXQgcmVzdWx0U2V0ID0gbmV3IE5vZGVTZXQoKTsKLSAgICByZXN1bHRTZXQuc2V0U2hvdWxkQ2FjaGVOb2Rlcyh0cnVlKTsKLQotICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwotICAgIGludCBmcm9tSW5kZXggPSAwOwotICAgIGludCBtYXRjaEluZGV4ID0gMDsKLSAgICBTdHJpbmcgdG9rZW4gPSBudWxsOwotCi0gICAgd2hpbGUgKCFkb25lICYmIGZyb21JbmRleCA8IHN0ci5sZW5ndGgoKSkKLSAgICB7Ci0gICAgICBtYXRjaEluZGV4ID0gc3RyLmluZGV4T2YocGF0dGVybiwgZnJvbUluZGV4KTsKLSAgICAgIGlmIChtYXRjaEluZGV4ID49IDApCi0gICAgICB7Ci0gICAgICAgIHRva2VuID0gc3RyLnN1YnN0cmluZyhmcm9tSW5kZXgsIG1hdGNoSW5kZXgpOwotICAgICAgICBmcm9tSW5kZXggPSBtYXRjaEluZGV4ICsgcGF0dGVybi5sZW5ndGgoKTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgZG9uZSA9IHRydWU7Ci0gICAgICAgIHRva2VuID0gc3RyLnN1YnN0cmluZyhmcm9tSW5kZXgpOwotICAgICAgfQotCi0gICAgICBEb2N1bWVudCBkb2MgPSBnZXREb2N1bWVudCgpOwotICAgICAgc3luY2hyb25pemVkIChkb2MpCi0gICAgICB7Ci0gICAgICAgIEVsZW1lbnQgZWxlbWVudCA9IGRvYy5jcmVhdGVFbGVtZW50KCJ0b2tlbiIpOwotICAgICAgICBUZXh0IHRleHQgPSBkb2MuY3JlYXRlVGV4dE5vZGUodG9rZW4pOwotICAgICAgICBlbGVtZW50LmFwcGVuZENoaWxkKHRleHQpOwotICAgICAgICByZXN1bHRTZXQuYWRkTm9kZShlbGVtZW50KTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gcmVzdWx0U2V0OwotICB9Ci0KLSAgLyoqCi0gICAqIFNlZSBhYm92ZQotICAgKi8KLSAgcHVibGljIHN0YXRpYyBOb2RlTGlzdCBzcGxpdChTdHJpbmcgc3RyKQotICB7Ci0gICAgcmV0dXJuIHNwbGl0KHN0ciwgIiAiKTsKLSAgfQotCi0gIC8qKgotICAgKiBUaGUgc3RyOnRva2VuaXplIGZ1bmN0aW9uIHNwbGl0cyB1cCBhIHN0cmluZyBhbmQgcmV0dXJucyBhIG5vZGUgc2V0IG9mIHRva2VuCi0gICAqIGVsZW1lbnRzLCBlYWNoIGNvbnRhaW5pbmcgb25lIHRva2VuIGZyb20gdGhlIHN0cmluZy4KLSAgICogPHA+Ci0gICAqIFRoZSBmaXJzdCBhcmd1bWVudCBpcyB0aGUgc3RyaW5nIHRvIGJlIHRva2VuaXplZC4gVGhlIHNlY29uZCBhcmd1bWVudCBpcyBhCi0gICAqIHN0cmluZyBjb25zaXN0aW5nIG9mIGEgbnVtYmVyIG9mIGNoYXJhY3RlcnMuIEVhY2ggY2hhcmFjdGVyIGluIHRoaXMgc3RyaW5nIGlzCi0gICAqIHRha2VuIGFzIGEgZGVsaW1pdGluZyBjaGFyYWN0ZXIuIFRoZSBzdHJpbmcgZ2l2ZW4gYnkgdGhlIGZpcnN0IGFyZ3VtZW50IGlzIHNwbGl0Ci0gICAqIGF0IGFueSBvY2N1cnJlbmNlIG9mIGFueSBvZiB0aGVzZSBjaGFyYWN0ZXJzLiBGb3IgZXhhbXBsZToKLSAgICogPHByZT4KLSAgICogc3RyOnRva2VuaXplKCcyMDAxLTA2LTAzVDExOjQwOjIzJywgJy1UOicpIGdpdmVzIHRoZSBub2RlIHNldCBjb25zaXN0aW5nIG9mOgotICAgKgotICAgKiA8dG9rZW4+MjAwMTwvdG9rZW4+Ci0gICAqIDx0b2tlbj4wNjwvdG9rZW4+Ci0gICAqIDx0b2tlbj4wMzwvdG9rZW4+Ci0gICAqIDx0b2tlbj4xMTwvdG9rZW4+Ci0gICAqIDx0b2tlbj40MDwvdG9rZW4+Ci0gICAqIDx0b2tlbj4yMzwvdG9rZW4+Ci0gICAqIDwvcHJlPgotICAgKiBJZiB0aGUgc2Vjb25kIGFyZ3VtZW50IGlzIG9taXR0ZWQsIHRoZSBkZWZhdWx0IGlzIHRoZSBzdHJpbmcgJyYjeDk7JiN4QTsmI3hEOyYjeDIwOycKLSAgICogKGkuZS4gd2hpdGVzcGFjZSBjaGFyYWN0ZXJzKS4KLSAgICogPHA+Ci0gICAqIElmIHRoZSBzZWNvbmQgYXJndW1lbnQgaXMgYW4gZW1wdHkgc3RyaW5nLCB0aGUgZnVuY3Rpb24gcmV0dXJucyBhIHNldCBvZiB0b2tlbgotICAgKiBlbGVtZW50cywgZWFjaCBvZiB3aGljaCBob2xkcyBhIHNpbmdsZSBjaGFyYWN0ZXIuCi0gICAqIDxwPgotICAgKiBOb3RlOiBUaGlzIG9uZSBpcyBkaWZmZXJlbnQgZnJvbSB0aGUgdG9rZW5pemUgZXh0ZW5zaW9uIGZ1bmN0aW9uIGluIHRoZSBYYWxhbgotICAgKiBuYW1lc3BhY2UuIFRoZSBvbmUgaW4gWGFsYW4gcmV0dXJucyBhIHNldCBvZiBUZXh0IG5vZGVzLCB3aGlsZSB0aGlzIG9uZSB3cmFwcwotICAgKiB0aGUgVGV4dCBub2RlcyBpbnNpZGUgdGhlIHRva2VuIEVsZW1lbnQgbm9kZXMuCi0gICAqCi0gICAqIEBwYXJhbSB0b1Rva2VuaXplIFRoZSBzdHJpbmcgdG8gYmUgdG9rZW5pemVkCi0gICAqIEBwYXJhbSBkZWxpbXMgVGhlIGRlbGltaXRlciBzdHJpbmcKLSAgICoKLSAgICogQHJldHVybiBBIG5vZGUgc2V0IG9mIHNwbGl0IHRva2VuIGVsZW1lbnRzCi0gICAqLwotICBwdWJsaWMgc3RhdGljIE5vZGVMaXN0IHRva2VuaXplKFN0cmluZyB0b1Rva2VuaXplLCBTdHJpbmcgZGVsaW1zKQotICB7Ci0KLQotICAgIE5vZGVTZXQgcmVzdWx0U2V0ID0gbmV3IE5vZGVTZXQoKTsKLQotICAgIGlmIChkZWxpbXMgIT0gbnVsbCAmJiBkZWxpbXMubGVuZ3RoKCkgPiAwKQotICAgIHsKLSAgICAgIFN0cmluZ1Rva2VuaXplciBsVG9rZW5pemVyID0gbmV3IFN0cmluZ1Rva2VuaXplcih0b1Rva2VuaXplLCBkZWxpbXMpOwotCi0gICAgICBEb2N1bWVudCBkb2MgPSBnZXREb2N1bWVudCgpOwotICAgICAgc3luY2hyb25pemVkIChkb2MpCi0gICAgICB7Ci0gICAgICAgIHdoaWxlIChsVG9rZW5pemVyLmhhc01vcmVUb2tlbnMoKSkKLSAgICAgICAgewotICAgICAgICAgIEVsZW1lbnQgZWxlbWVudCA9IGRvYy5jcmVhdGVFbGVtZW50KCJ0b2tlbiIpOwotICAgICAgICAgIGVsZW1lbnQuYXBwZW5kQ2hpbGQoZG9jLmNyZWF0ZVRleHROb2RlKGxUb2tlbml6ZXIubmV4dFRva2VuKCkpKTsKLSAgICAgICAgICByZXN1bHRTZXQuYWRkTm9kZShlbGVtZW50KTsKLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLSAgICAvLyBJZiB0aGUgZGVsaW1pdGVyIGlzIGFuIGVtcHR5IHN0cmluZywgY3JlYXRlIG9uZSB0b2tlbiBFbGVtZW50IGZvcgotICAgIC8vIGV2ZXJ5IHNpbmdsZSBjaGFyYWN0ZXIuCi0gICAgZWxzZQotICAgIHsKLQotICAgICAgRG9jdW1lbnQgZG9jID0gZ2V0RG9jdW1lbnQoKTsKLSAgICAgIHN5bmNocm9uaXplZCAoZG9jKQotICAgICAgewotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHRvVG9rZW5pemUubGVuZ3RoKCk7IGkrKykKLSAgICAgICAgewotICAgICAgICAgIEVsZW1lbnQgZWxlbWVudCA9IGRvYy5jcmVhdGVFbGVtZW50KCJ0b2tlbiIpOwotICAgICAgICAgIGVsZW1lbnQuYXBwZW5kQ2hpbGQoZG9jLmNyZWF0ZVRleHROb2RlKHRvVG9rZW5pemUuc3Vic3RyaW5nKGksIGkrMSkpKTsKLSAgICAgICAgICByZXN1bHRTZXQuYWRkTm9kZShlbGVtZW50KTsKLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiByZXN1bHRTZXQ7Ci0gIH0KLQotICAvKioKLSAgICogU2VlIGFib3ZlCi0gICAqLwotICBwdWJsaWMgc3RhdGljIE5vZGVMaXN0IHRva2VuaXplKFN0cmluZyB0b1Rva2VuaXplKQotICB7Ci0gICAgcmV0dXJuIHRva2VuaXplKHRvVG9rZW5pemUsICIgXHRcblxyIik7Ci0gIH0KLQotICAgIC8qKgotICAgKiBAcmV0dXJuIGFuIGluc3RhbmNlIG9mIERPTSBEb2N1bWVudAotICAgICAqLwotICAgcHJpdmF0ZSBzdGF0aWMgRG9jdW1lbnQgZ2V0RG9jdW1lbnQoKQotICAgewotICAgICAgICB0cnkKLSAgICAgICAgewotICAgICAgICAgICAgaWYgKFN5c3RlbS5nZXRTZWN1cml0eU1hbmFnZXIoKSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIERvY3VtZW50QnVpbGRlckZhY3RvcnkubmV3SW5zdGFuY2UoKS5uZXdEb2N1bWVudEJ1aWxkZXIoKS5uZXdEb2N1bWVudCgpOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gRG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5uZXdJbnN0YW5jZShKREtfREVGQVVMVF9ET00sIG51bGwpLm5ld0RvY3VtZW50QnVpbGRlcigpLm5ld0RvY3VtZW50KCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2goUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBwY2UpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLldyYXBwZWRSdW50aW1lRXhjZXB0aW9uKHBjZSk7Ci0gICAgICAgIH0KLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL2xpYi9FeHRlbnNpb25zLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL2xpYi9FeHRlbnNpb25zLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGU5MTQ3MDkuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC9saWIvRXh0ZW5zaW9ucy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzg4ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKi8KLS8qCi0gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKLSAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAotICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgotICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKLSAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCi0gKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRXh0ZW5zaW9ucy5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzEwIDE4OjUzOjMyIGplZmZzdXR0b3IgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwubGliOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLmV4dGVuc2lvbnMuRXhwcmVzc2lvbkNvbnRleHQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnV0aWxzLk9iamVjdEZhY3Rvcnk7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHQuRW52aXJvbm1lbnRDaGVjazsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuTm9kZVNldDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YQm9vbGVhbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YTnVtYmVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhPYmplY3Q7Ci1pbXBvcnQgamF2YS51dGlsLkhhc2h0YWJsZTsKLWltcG9ydCBqYXZhLnV0aWwuTWFwOwotaW1wb3J0IGphdmEudXRpbC5TdHJpbmdUb2tlbml6ZXI7Ci1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy5QYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uOwotaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50RnJhZ21lbnQ7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlTGlzdDsKLWltcG9ydCBvcmcudzNjLmRvbS5UZXh0OwotaW1wb3J0IG9yZy53M2MuZG9tLnRyYXZlcnNhbC5Ob2RlSXRlcmF0b3I7Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgY29udGFpbnMgbWFueSBvZiB0aGUgWGFsYW4tc3VwcGxpZWQgZXh0ZW5zaW9ucy4KLSAqIEl0IGlzIGFjY2Vzc2VkIGJ5IHNwZWNpZnlpbmcgYSBuYW1lc3BhY2UgVVJJIGFzIGZvbGxvd3M6Ci0gKiA8cHJlPgotICogICAgeG1sbnM6eGFsYW49Imh0dHA6Ly94bWwuYXBhY2hlLm9yZy94YWxhbiIKLSAqIDwvcHJlPgotICogQHhzbC51c2FnZSBnZW5lcmFsCi0gKi8KLXB1YmxpYyBjbGFzcyBFeHRlbnNpb25zCi17Ci0gICAgc3RhdGljIGZpbmFsIFN0cmluZyBKREtfREVGQVVMVF9ET00gPSAiY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5qYXhwLkRvY3VtZW50QnVpbGRlckZhY3RvcnlJbXBsIjsKLSAgLyoqCi0gICAqIENvbnN0cnVjdG9yIEV4dGVuc2lvbnMKLSAgICoKLSAgICovCi0gIHByaXZhdGUgRXh0ZW5zaW9ucygpe30gIC8vIE1ha2Ugc3VyZSBjbGFzcyBjYW5ub3QgYmUgaW5zdGFudGlhdGVkCi0KLSAgLyoqCi0gICAqIFRoaXMgbWV0aG9kIGlzIGFuIGV4dGVuc2lvbiB0aGF0IGltcGxlbWVudHMgYXMgYSBYYWxhbiBleHRlbnNpb24KLSAgICogdGhlIG5vZGUtc2V0IGZ1bmN0aW9uIGFsc28gZm91bmQgaW4geHQgYW5kIHNheG9uLgotICAgKiBJZiB0aGUgYXJndW1lbnQgaXMgYSBSZXN1bHQgVHJlZSBGcmFnbWVudCwgdGhlbiA8Y29kZT5ub2Rlc2V0PC9jb2RlPgotICAgKiByZXR1cm5zIGEgbm9kZS1zZXQgY29uc2lzdGluZyBvZiBhIHNpbmdsZSByb290IG5vZGUgYXMgZGVzY3JpYmVkIGluCi0gICAqIHNlY3Rpb24gMTEuMSBvZiB0aGUgWFNMVCAxLjAgUmVjb21tZW5kYXRpb24uICBJZiB0aGUgYXJndW1lbnQgaXMgYQotICAgKiBub2RlLXNldCwgPGNvZGU+bm9kZXNldDwvY29kZT4gcmV0dXJucyBhIG5vZGUtc2V0LiAgSWYgdGhlIGFyZ3VtZW50Ci0gICAqIGlzIGEgc3RyaW5nLCBudW1iZXIsIG9yIGJvb2xlYW4sIHRoZW4gPGNvZGU+bm9kZXNldDwvY29kZT4gcmV0dXJucwotICAgKiBhIG5vZGUtc2V0IGNvbnNpc3Rpbmcgb2YgYSBzaW5nbGUgcm9vdCBub2RlIHdpdGggYSBzaW5nbGUgdGV4dCBub2RlCi0gICAqIGNoaWxkIHRoYXQgaXMgdGhlIHJlc3VsdCBvZiBjYWxsaW5nIHRoZSBYUGF0aCBzdHJpbmcoKSBmdW5jdGlvbiBvbiB0aGUKLSAgICogcGFzc2VkIHBhcmFtZXRlci4gIElmIHRoZSBhcmd1bWVudCBpcyBhbnl0aGluZyBlbHNlLCB0aGVuIGEgbm9kZS1zZXQKLSAgICogaXMgcmV0dXJuZWQgY29uc2lzdGluZyBvZiBhIHNpbmdsZSByb290IG5vZGUgd2l0aCBhIHNpbmdsZSB0ZXh0IG5vZGUKLSAgICogY2hpbGQgdGhhdCBpcyB0aGUgcmVzdWx0IG9mIGNhbGxpbmcgdGhlIGphdmEgPGNvZGU+dG9TdHJpbmcoKTwvY29kZT4KLSAgICogbWV0aG9kIG9uIHRoZSBwYXNzZWQgYXJndW1lbnQuCi0gICAqIE1vc3Qgb2YgdGhlCi0gICAqIGFjdHVhbCB3b3JrIGhlcmUgaXMgZG9uZSBpbiA8Y29kZT5NZXRob2RSZXNvbHZlcjwvY29kZT4gYW5kCi0gICAqIDxjb2RlPlhSVHJlZUZyYWc8L2NvZGU+LgotICAgKiBAcGFyYW0gbXlQcm9jZXNzb3IgQ29udGV4dCBwYXNzZWQgYnkgdGhlIGV4dGVuc2lvbiBwcm9jZXNzb3IKLSAgICogQHBhcmFtIHJ0ZiBBcmd1bWVudCBpbiB0aGUgc3R5bGVzaGVldCB0byB0aGUgbm9kZXNldCBleHRlbnNpb24gZnVuY3Rpb24KLSAgICoKLSAgICogTkVFRFNET0MgKCRvYmplY3ROYW1lJCkgQHJldHVybgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBOb2RlU2V0IG5vZGVzZXQoRXhwcmVzc2lvbkNvbnRleHQgbXlQcm9jZXNzb3IsIE9iamVjdCBydGYpCi0gIHsKLQotICAgIFN0cmluZyB0ZXh0Tm9kZVZhbHVlOwotCi0gICAgaWYgKHJ0ZiBpbnN0YW5jZW9mIE5vZGVJdGVyYXRvcikKLSAgICB7Ci0gICAgICByZXR1cm4gbmV3IE5vZGVTZXQoKE5vZGVJdGVyYXRvcikgcnRmKTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIGlmIChydGYgaW5zdGFuY2VvZiBTdHJpbmcpCi0gICAgICB7Ci0gICAgICAgIHRleHROb2RlVmFsdWUgPSAoU3RyaW5nKSBydGY7Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmIChydGYgaW5zdGFuY2VvZiBCb29sZWFuKQotICAgICAgewotICAgICAgICB0ZXh0Tm9kZVZhbHVlID0gbmV3IFhCb29sZWFuKCgoQm9vbGVhbikgcnRmKS5ib29sZWFuVmFsdWUoKSkuc3RyKCk7Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmIChydGYgaW5zdGFuY2VvZiBEb3VibGUpCi0gICAgICB7Ci0gICAgICAgIHRleHROb2RlVmFsdWUgPSBuZXcgWE51bWJlcigoKERvdWJsZSkgcnRmKS5kb3VibGVWYWx1ZSgpKS5zdHIoKTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgdGV4dE5vZGVWYWx1ZSA9IHJ0Zi50b1N0cmluZygpOwotICAgICAgfQotCi0gICAgICAvLyBUaGlzIG5vIGxvbmdlciB3aWxsIHdvcmsgcmlnaHQgc2luY2UgdGhlIERUTS4KLSAgICAgIC8vIERvY3VtZW50IG15RG9jID0gbXlQcm9jZXNzb3IuZ2V0Q29udGV4dE5vZGUoKS5nZXRPd25lckRvY3VtZW50KCk7Ci0gICAgICBEb2N1bWVudCBteURvYyA9IGdldERvY3VtZW50KCk7Ci0KLSAgICAgICAgVGV4dCB0ZXh0Tm9kZSA9IG15RG9jLmNyZWF0ZVRleHROb2RlKHRleHROb2RlVmFsdWUpOwotICAgICAgICBEb2N1bWVudEZyYWdtZW50IGRvY0ZyYWcgPSBteURvYy5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7Ci0KLSAgICAgICAgZG9jRnJhZy5hcHBlbmRDaGlsZCh0ZXh0Tm9kZSk7Ci0KLSAgICAgIHJldHVybiBuZXcgTm9kZVNldChkb2NGcmFnKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgaW50ZXJzZWN0aW9uIG9mIHR3byBub2RlLXNldHMuCi0gICAqCi0gICAqIEBwYXJhbSBubDEgTm9kZUxpc3QgZm9yIGZpcnN0IG5vZGUtc2V0Ci0gICAqIEBwYXJhbSBubDIgTm9kZUxpc3QgZm9yIHNlY29uZCBub2RlLXNldAotICAgKiBAcmV0dXJuIGEgTm9kZUxpc3QgY29udGFpbmluZyB0aGUgbm9kZXMgaW4gbmwxIHRoYXQgYXJlIGFsc28gaW4gbmwyCi0gICAqCi0gICAqIE5vdGU6IFRoZSB1c2FnZSBvZiB0aGlzIGV4dGVuc2lvbiBmdW5jdGlvbiBpbiB0aGUgeGFsYW4gbmFtZXNwYWNlCi0gICAqIGlzIGRlcHJlY2F0ZWQuIFBsZWFzZSB1c2UgdGhlIHNhbWUgZnVuY3Rpb24gaW4gdGhlIEVYU0xUIHNldHMgZXh0ZW5zaW9uCi0gICAqIChodHRwOi8vZXhzbHQub3JnL3NldHMpLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBOb2RlTGlzdCBpbnRlcnNlY3Rpb24oTm9kZUxpc3QgbmwxLCBOb2RlTGlzdCBubDIpCi0gIHsKLSAgICByZXR1cm4gRXhzbHRTZXRzLmludGVyc2VjdGlvbihubDEsIG5sMik7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHR3byBub2RlLXNldHMuCi0gICAqCi0gICAqIEBwYXJhbSBubDEgTm9kZUxpc3QgZm9yIGZpcnN0IG5vZGUtc2V0Ci0gICAqIEBwYXJhbSBubDIgTm9kZUxpc3QgZm9yIHNlY29uZCBub2RlLXNldAotICAgKiBAcmV0dXJuIGEgTm9kZUxpc3QgY29udGFpbmluZyB0aGUgbm9kZXMgaW4gbmwxIHRoYXQgYXJlIG5vdCBpbiBubDIKLSAgICoKLSAgICogTm90ZTogVGhlIHVzYWdlIG9mIHRoaXMgZXh0ZW5zaW9uIGZ1bmN0aW9uIGluIHRoZSB4YWxhbiBuYW1lc3BhY2UKLSAgICogaXMgZGVwcmVjYXRlZC4gUGxlYXNlIHVzZSB0aGUgc2FtZSBmdW5jdGlvbiBpbiB0aGUgRVhTTFQgc2V0cyBleHRlbnNpb24KLSAgICogKGh0dHA6Ly9leHNsdC5vcmcvc2V0cykuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIE5vZGVMaXN0IGRpZmZlcmVuY2UoTm9kZUxpc3QgbmwxLCBOb2RlTGlzdCBubDIpCi0gIHsKLSAgICByZXR1cm4gRXhzbHRTZXRzLmRpZmZlcmVuY2UobmwxLCBubDIpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgbm9kZS1zZXQgY29udGFpbmluZyBkaXN0aW5jdCBzdHJpbmcgdmFsdWVzLgotICAgKgotICAgKiBAcGFyYW0gbmwgTm9kZUxpc3QgZm9yIG5vZGUtc2V0Ci0gICAqIEByZXR1cm4gYSBOb2RlTGlzdCB3aXRoIG5vZGVzIGZyb20gbmwgY29udGFpbmluZyBkaXN0aW5jdCBzdHJpbmcgdmFsdWVzLgotICAgKiBJbiBvdGhlciB3b3JkcywgaWYgbW9yZSB0aGFuIG9uZSBub2RlIGluIG5sIGNvbnRhaW5zIHRoZSBzYW1lIHN0cmluZyB2YWx1ZSwKLSAgICogb25seSBpbmNsdWRlIHRoZSBmaXJzdCBzdWNoIG5vZGUgZm91bmQuCi0gICAqCi0gICAqIE5vdGU6IFRoZSB1c2FnZSBvZiB0aGlzIGV4dGVuc2lvbiBmdW5jdGlvbiBpbiB0aGUgeGFsYW4gbmFtZXNwYWNlCi0gICAqIGlzIGRlcHJlY2F0ZWQuIFBsZWFzZSB1c2UgdGhlIHNhbWUgZnVuY3Rpb24gaW4gdGhlIEVYU0xUIHNldHMgZXh0ZW5zaW9uCi0gICAqIChodHRwOi8vZXhzbHQub3JnL3NldHMpLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBOb2RlTGlzdCBkaXN0aW5jdChOb2RlTGlzdCBubCkKLSAgewotICAgIHJldHVybiBFeHNsdFNldHMuZGlzdGluY3QobmwpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdHJ1ZSBpZiBib3RoIG5vZGUtc2V0cyBjb250YWluIHRoZSBzYW1lIHNldCBvZiBub2Rlcy4KLSAgICoKLSAgICogQHBhcmFtIG5sMSBOb2RlTGlzdCBmb3IgZmlyc3Qgbm9kZS1zZXQKLSAgICogQHBhcmFtIG5sMiBOb2RlTGlzdCBmb3Igc2Vjb25kIG5vZGUtc2V0Ci0gICAqIEByZXR1cm4gdHJ1ZSBpZiBubDEgYW5kIG5sMiBjb250YWluIGV4YWN0bHkgdGhlIHNhbWUgc2V0IG9mIG5vZGVzLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBib29sZWFuIGhhc1NhbWVOb2RlcyhOb2RlTGlzdCBubDEsIE5vZGVMaXN0IG5sMikKLSAgewotCi0gICAgTm9kZVNldCBuczEgPSBuZXcgTm9kZVNldChubDEpOwotICAgIE5vZGVTZXQgbnMyID0gbmV3IE5vZGVTZXQobmwyKTsKLQotICAgIGlmIChuczEuZ2V0TGVuZ3RoKCkgIT0gbnMyLmdldExlbmd0aCgpKQotICAgICAgcmV0dXJuIGZhbHNlOwotCi0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuczEuZ2V0TGVuZ3RoKCk7IGkrKykKLSAgICB7Ci0gICAgICBOb2RlIG4gPSBuczEuZWxlbWVudEF0KGkpOwotCi0gICAgICBpZiAoIW5zMi5jb250YWlucyhuKSkKLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIHJldHVybiB0cnVlOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIHJlc3VsdCBvZiBldmFsdWF0aW5nIHRoZSBhcmd1bWVudCBhcyBhIHN0cmluZyBjb250YWluaW5nCi0gICAqIGFuIFhQYXRoIGV4cHJlc3Npb24uICBVc2VkIHdoZXJlIHRoZSBYUGF0aCBleHByZXNzaW9uIGlzIG5vdCBrbm93biB1bnRpbAotICAgKiBydW4tdGltZS4gIFRoZSBleHByZXNzaW9uIGlzIGV2YWx1YXRlZCBhcyBpZiB0aGUgcnVuLXRpbWUgdmFsdWUgb2YgdGhlCi0gICAqIGFyZ3VtZW50IGFwcGVhcmVkIGluIHBsYWNlIG9mIHRoZSBldmFsdWF0ZSBmdW5jdGlvbiBjYWxsIGF0IGNvbXBpbGUgdGltZS4KLSAgICoKLSAgICogQHBhcmFtIG15Q29udGV4dCBhbiA8Y29kZT5FeHByZXNzaW9uQ29udGV4dDwvY29kZT4gcGFzc2VkIGluIGJ5IHRoZQotICAgKiAgICAgICAgICAgICAgICAgIGV4dGVuc2lvbiBtZWNoYW5pc20uICBUaGlzIG11c3QgYmUgYW4gWFBhdGhDb250ZXh0LgotICAgKiBAcGFyYW0geHBhdGhFeHByIFRoZSBYUGF0aCBleHByZXNzaW9uIHRvIGJlIGV2YWx1YXRlZC4KLSAgICogQHJldHVybiB0aGUgWE9iamVjdCByZXN1bHRpbmcgZnJvbSBldmFsdWF0aW5nIHRoZSBYUGF0aAotICAgKgotICAgKiBAdGhyb3dzIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbgotICAgKgotICAgKiBOb3RlOiBUaGUgdXNhZ2Ugb2YgdGhpcyBleHRlbnNpb24gZnVuY3Rpb24gaW4gdGhlIHhhbGFuIG5hbWVzcGFjZQotICAgKiBpcyBkZXByZWNhdGVkLiBQbGVhc2UgdXNlIHRoZSBzYW1lIGZ1bmN0aW9uIGluIHRoZSBFWFNMVCBkeW5hbWljIGV4dGVuc2lvbgotICAgKiAoaHR0cDovL2V4c2x0Lm9yZy9keW5hbWljKS4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgWE9iamVjdCBldmFsdWF0ZShFeHByZXNzaW9uQ29udGV4dCBteUNvbnRleHQsIFN0cmluZyB4cGF0aEV4cHIpCi0gICAgICAgICB0aHJvd3MgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gRXhzbHREeW5hbWljLmV2YWx1YXRlKG15Q29udGV4dCwgeHBhdGhFeHByKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIGEgTm9kZVNldCBjb250YWluaW5nIG9uZSB0ZXh0IG5vZGUgZm9yIGVhY2ggdG9rZW4gaW4gdGhlIGZpcnN0IGFyZ3VtZW50LgotICAgKiBEZWxpbWl0ZXJzIGFyZSBzcGVjaWZpZWQgaW4gdGhlIHNlY29uZCBhcmd1bWVudC4KLSAgICogVG9rZW5zIGFyZSBkZXRlcm1pbmVkIGJ5IGEgY2FsbCB0byA8Y29kZT5TdHJpbmdUb2tlbml6ZXI8L2NvZGU+LgotICAgKiBJZiB0aGUgZmlyc3QgYXJndW1lbnQgaXMgYW4gZW1wdHkgc3RyaW5nIG9yIGNvbnRhaW5zIG9ubHkgZGVsaW1pdGVycywgdGhlIHJlc3VsdAotICAgKiB3aWxsIGJlIGFuIGVtcHR5IE5vZGVTZXQuCi0gICAqCi0gICAqIENvbnRyaWJ1dGVkIHRvIFhhbGFuSjEgYnkgPGEgaHJlZj0ibWFpbHRvOmJlbm9pdC5jZXJyaW5hQHdyaXRlbWUuY29tIj5CZW5vaXQgQ2VycmluYTwvYT4uCi0gICAqCi0gICAqIEBwYXJhbSB0b1Rva2VuaXplIFRoZSBzdHJpbmcgdG8gYmUgc3BsaXQgaW50byB0ZXh0IHRva2Vucy4KLSAgICogQHBhcmFtIGRlbGltcyBUaGUgZGVsaW1pdGVycyB0byB1c2UuCi0gICAqIEByZXR1cm4gYSBOb2RlU2V0IGFzIGRlc2NyaWJlZCBhYm92ZS4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgTm9kZUxpc3QgdG9rZW5pemUoU3RyaW5nIHRvVG9rZW5pemUsIFN0cmluZyBkZWxpbXMpCi0gIHsKLQotICAgIERvY3VtZW50IGRvYyA9IGdldERvY3VtZW50KCk7Ci0KLSAgICBTdHJpbmdUb2tlbml6ZXIgbFRva2VuaXplciA9IG5ldyBTdHJpbmdUb2tlbml6ZXIodG9Ub2tlbml6ZSwgZGVsaW1zKTsKLSAgICBOb2RlU2V0IHJlc3VsdFNldCA9IG5ldyBOb2RlU2V0KCk7Ci0KLSAgICBzeW5jaHJvbml6ZWQgKGRvYykKLSAgICB7Ci0gICAgICB3aGlsZSAobFRva2VuaXplci5oYXNNb3JlVG9rZW5zKCkpCi0gICAgICB7Ci0gICAgICAgIHJlc3VsdFNldC5hZGROb2RlKGRvYy5jcmVhdGVUZXh0Tm9kZShsVG9rZW5pemVyLm5leHRUb2tlbigpKSk7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgcmV0dXJuIHJlc3VsdFNldDsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIGEgTm9kZVNldCBjb250YWluaW5nIG9uZSB0ZXh0IG5vZGUgZm9yIGVhY2ggdG9rZW4gaW4gdGhlIGZpcnN0IGFyZ3VtZW50LgotICAgKiBEZWxpbWl0ZXJzIGFyZSB3aGl0ZXNwYWNlLiAgVGhhdCBpcywgdGhlIGRlbGltaXRlcnMgdGhhdCBhcmUgdXNlZCBhcmUgdGFiICgmI3gwOSksCi0gICAqIGxpbmVmZWVkICgmI3gwQSksIHJldHVybiAoJiN4MEQpLCBhbmQgc3BhY2UgKCYjeDIwKS4KLSAgICogVG9rZW5zIGFyZSBkZXRlcm1pbmVkIGJ5IGEgY2FsbCB0byA8Y29kZT5TdHJpbmdUb2tlbml6ZXI8L2NvZGU+LgotICAgKiBJZiB0aGUgZmlyc3QgYXJndW1lbnQgaXMgYW4gZW1wdHkgc3RyaW5nIG9yIGNvbnRhaW5zIG9ubHkgZGVsaW1pdGVycywgdGhlIHJlc3VsdAotICAgKiB3aWxsIGJlIGFuIGVtcHR5IE5vZGVTZXQuCi0gICAqCi0gICAqIENvbnRyaWJ1dGVkIHRvIFhhbGFuSjEgYnkgPGEgaHJlZj0ibWFpbHRvOmJlbm9pdC5jZXJyaW5hQHdyaXRlbWUuY29tIj5CZW5vaXQgQ2VycmluYTwvYT4uCi0gICAqCi0gICAqIEBwYXJhbSB0b1Rva2VuaXplIFRoZSBzdHJpbmcgdG8gYmUgc3BsaXQgaW50byB0ZXh0IHRva2Vucy4KLSAgICogQHJldHVybiBhIE5vZGVTZXQgYXMgZGVzY3JpYmVkIGFib3ZlLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBOb2RlTGlzdCB0b2tlbml6ZShTdHJpbmcgdG9Ub2tlbml6ZSkKLSAgewotICAgIHJldHVybiB0b2tlbml6ZSh0b1Rva2VuaXplLCAiIFx0XG5cciIpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiBhIE5vZGUgb2YgYmFzaWMgZGVidWdnaW5nIGluZm9ybWF0aW9uIGZyb20gdGhlCi0gICAqIEVudmlyb25tZW50Q2hlY2sgdXRpbGl0eSBhYm91dCB0aGUgSmF2YSBlbnZpcm9ubWVudC4KLSAgICoKLSAgICogPHA+U2ltcGx5IGNhbGxzIHRoZSB7QGxpbmsgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHQuRW52aXJvbm1lbnRDaGVja30KLSAgICogdXRpbGl0eSB0byBncmFiIGluZm8gYWJvdXQgdGhlIEphdmEgZW52aXJvbm1lbnQgYW5kIENMQVNTUEFUSCwKLSAgICogZXRjLiwgYW5kIHRoZW4gcmV0dXJucyB0aGUgcmVzdWx0aW5nIE5vZGUuICBTdHlsZXNoZWV0cyBjYW4KLSAgICogdGhlbiBtYW5pdXBsYXRlIHRoaXMgZGF0YSBvciBzaW1wbHkgeHNsOmNvcHktb2YgdGhlIE5vZGUuICBOb3RlCi0gICAqIHRoYXQgd2UgZmlyc3QgYXR0ZW1wdCB0byBsb2FkIHRoZSBtb3JlIGFkdmFuY2VkCi0gICAqIG9yZy5hcGFjaGUuZW52LldoaWNoIHV0aWxpdHkgYnkgcmVmbGVjdGlvbjsgb25seSBpZiB0aGF0IGZhaWxzCi0gICAqIHRvIHdlIHN0aWxsIHVzZSB0aGUgaW50ZXJuYWwgdmVyc2lvbi4gIFdoaWNoIGlzIGF2YWlsYWJsZSBmcm9tCi0gICAqIDxhIGhyZWY9Imh0dHA6Ly94bWwuYXBhY2hlLm9yZy9jb21tb25zLyI+aHR0cDovL3htbC5hcGFjaGUub3JnL2NvbW1vbnMvPC9hPi48L3A+Ci0gICAqCi0gICAqIDxwPldlIHRocm93IGEgV3JhcHBlZFJ1bnRpbWVFeGNlcHRpb24gaW4gdGhlIHVubGlrZWx5IGNhc2UKLSAgICogdGhhdCByZWFkaW5nIGluZm9ybWF0aW9uIGZyb20gdGhlIGVudmlyb25tZW50IHRocm93cyB1cyBhbgotICAgKiBleGNlcHRpb24uIChJcyB0aGlzIHJlYWxseSB0aGUgYmVzdCB0aGluZyB0byBkbz8pPC9wPgotICAgKgotICAgKiBAcGFyYW0gbXlDb250ZXh0IGFuIDxjb2RlPkV4cHJlc3Npb25Db250ZXh0PC9jb2RlPiBwYXNzZWQgaW4gYnkgdGhlCi0gICAqICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uIG1lY2hhbmlzbS4gIFRoaXMgbXVzdCBiZSBhbiBYUGF0aENvbnRleHQuCi0gICAqIEByZXR1cm4gYSBOb2RlIGFzIGRlc2NyaWJlZCBhYm92ZS4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgTm9kZSBjaGVja0Vudmlyb25tZW50KEV4cHJlc3Npb25Db250ZXh0IG15Q29udGV4dCkKLSAgewotCi0gICAgRG9jdW1lbnQgZmFjdG9yeURvY3VtZW50ID0gZ2V0RG9jdW1lbnQoKTsKLQotICAgIE5vZGUgcmVzdWx0Tm9kZSA9IG51bGw7Ci0gICAgdHJ5Ci0gICAgewotICAgICAgLy8gRmlyc3QgdXNlIHJlZmxlY3Rpb24gdG8gdHJ5IHRvIGxvYWQgV2hpY2gsIHdoaWNoIGlzIGEKLSAgICAgIC8vICBiZXR0ZXIgdmVyc2lvbiBvZiBFbnZpcm9ubWVudENoZWNrCi0gICAgICByZXN1bHROb2RlID0gY2hlY2tFbnZpcm9ubWVudFVzaW5nV2hpY2gobXlDb250ZXh0LCBmYWN0b3J5RG9jdW1lbnQpOwotCi0gICAgICBpZiAobnVsbCAhPSByZXN1bHROb2RlKQotICAgICAgICByZXR1cm4gcmVzdWx0Tm9kZTsKLQotICAgICAgLy8gSWYgcmVmbGVjdGlvbiBmYWlsZWQsIGZhbGxiYWNrIHRvIG91ciBpbnRlcm5hbCBFbnZpcm9ubWVudENoZWNrCi0gICAgICBFbnZpcm9ubWVudENoZWNrIGVudkNoZWNrZXIgPSBuZXcgRW52aXJvbm1lbnRDaGVjaygpOwotICAgICAgTWFwPFN0cmluZywgT2JqZWN0PiBoID0gZW52Q2hlY2tlci5nZXRFbnZpcm9ubWVudEhhc2goKTsKLSAgICAgIHJlc3VsdE5vZGUgPSBmYWN0b3J5RG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiY2hlY2tFbnZpcm9ubWVudEV4dGVuc2lvbiIpOwotICAgICAgZW52Q2hlY2tlci5hcHBlbmRFbnZpcm9ubWVudFJlcG9ydChyZXN1bHROb2RlLCBmYWN0b3J5RG9jdW1lbnQsIGgpOwotICAgICAgZW52Q2hlY2tlciA9IG51bGw7Ci0gICAgfQotICAgIGNhdGNoKEV4Y2VwdGlvbiBlKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLldyYXBwZWRSdW50aW1lRXhjZXB0aW9uKGUpOwotICAgIH0KLQotICAgIHJldHVybiByZXN1bHROb2RlOwotICB9Ci0KLSAgLyoqCi0gICAqIFByaXZhdGUgd29ya2VyIG1ldGhvZCB0byBhdHRlbXB0IHRvIHVzZSBvcmcuYXBhY2hlLmVudi5XaGljaC4KLSAgICoKLSAgICogQHBhcmFtIG15Q29udGV4dCBhbiA8Y29kZT5FeHByZXNzaW9uQ29udGV4dDwvY29kZT4gcGFzc2VkIGluIGJ5IHRoZQotICAgKiAgICAgICAgICAgICAgICAgIGV4dGVuc2lvbiBtZWNoYW5pc20uICBUaGlzIG11c3QgYmUgYW4gWFBhdGhDb250ZXh0LgotICAgKiBAcGFyYW0gZmFjdG9yeURvY3VtZW50IHByb3ZpZGluZyBjcmVhdGVFbGVtZW50IHNlcnZpY2VzLCBldGMuCi0gICAqIEByZXR1cm4gYSBOb2RlIHdpdGggZW52aXJvbm1lbnQgaW5mbzsgbnVsbCBpZiBhbnkgZXJyb3IKLSAgICovCi0gIHByaXZhdGUgc3RhdGljIE5vZGUgY2hlY2tFbnZpcm9ubWVudFVzaW5nV2hpY2goRXhwcmVzc2lvbkNvbnRleHQgbXlDb250ZXh0LAotICAgICAgICBEb2N1bWVudCBmYWN0b3J5RG9jdW1lbnQpCi0gIHsKLSAgICBmaW5hbCBTdHJpbmcgV0hJQ0hfQ0xBU1NOQU1FID0gIm9yZy5hcGFjaGUuZW52LldoaWNoIjsKLSAgICBmaW5hbCBTdHJpbmcgV0hJQ0hfTUVUSE9ETkFNRSA9ICJ3aGljaCI7Ci0gICAgZmluYWwgQ2xhc3MgV0hJQ0hfTUVUSE9EX0FSR1NbXSA9IHsgamF2YS51dGlsLkhhc2h0YWJsZS5jbGFzcywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLmNsYXNzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcuY2xhc3MgfTsKLSAgICB0cnkKLSAgICB7Ci0gICAgICAvLyBVc2UgcmVmbGVjdGlvbiB0byB0cnkgdG8gZmluZCB4bWwtY29tbW9ucyB1dGlsaXR5ICdXaGljaCcKLSAgICAgIENsYXNzIGNsYXp6ID0gT2JqZWN0RmFjdG9yeS5maW5kUHJvdmlkZXJDbGFzcyhXSElDSF9DTEFTU05BTUUsIHRydWUpOwotICAgICAgaWYgKG51bGwgPT0gY2xhenopCi0gICAgICAgIHJldHVybiBudWxsOwotCi0gICAgICAvLyBGdWxseSBxdWFsaWZ5IG5hbWVzIHNpbmNlIHRoaXMgaXMgdGhlIG9ubHkgbWV0aG9kIHRoZXkncmUgdXNlZCBpbgotICAgICAgamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kIG1ldGhvZCA9IGNsYXp6LmdldE1ldGhvZChXSElDSF9NRVRIT0ROQU1FLCBXSElDSF9NRVRIT0RfQVJHUyk7Ci0gICAgICBIYXNodGFibGUgcmVwb3J0ID0gbmV3IEhhc2h0YWJsZSgpOwotCi0gICAgICAvLyBDYWxsIHRoZSBtZXRob2Qgd2l0aCBvdXIgSGFzaHRhYmxlLCBjb21tb24gb3B0aW9ucywgYW5kIGlnbm9yZSByZXR1cm4gdmFsdWUKLSAgICAgIE9iamVjdFtdIG1ldGhvZEFyZ3MgPSB7IHJlcG9ydCwgIlhtbENvbW1vbnM7WGFsYW47WGVyY2VzO0NyaW1zb247QW50IiwgIiIgfTsKLSAgICAgIE9iamVjdCByZXR1cm5WYWx1ZSA9IG1ldGhvZC5pbnZva2UobnVsbCwgbWV0aG9kQXJncyk7Ci0KLSAgICAgIC8vIENyZWF0ZSBhIHBhcmVudCB0byBob2xkIHRoZSByZXBvcnQgYW5kIGFwcGVuZCBoYXNoIHRvIGl0Ci0gICAgICBOb2RlIHJlc3VsdE5vZGUgPSBmYWN0b3J5RG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiY2hlY2tFbnZpcm9ubWVudEV4dGVuc2lvbiIpOwotICAgICAgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5IYXNodHJlZTJOb2RlLmFwcGVuZEhhc2hUb05vZGUocmVwb3J0LCAid2hpY2hSZXBvcnQiLAotICAgICAgICAgICAgcmVzdWx0Tm9kZSwgZmFjdG9yeURvY3VtZW50KTsKLQotICAgICAgcmV0dXJuIHJlc3VsdE5vZGU7Ci0gICAgfQotICAgIGNhdGNoIChUaHJvd2FibGUgdCkKLSAgICB7Ci0gICAgICAvLyBTaW1wbHkgcmV0dXJuIG51bGw7IG5vIG5lZWQgdG8gcmVwb3J0IGVycm9yCi0gICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0gIH0KLQotICAgIC8qKgotICAgKiBAcmV0dXJuIGFuIGluc3RhbmNlIG9mIERPTSBEb2N1bWVudAotICAgICAqLwotICAgcHJpdmF0ZSBzdGF0aWMgRG9jdW1lbnQgZ2V0RG9jdW1lbnQoKQotICAgewotICAgICAgICB0cnkKLSAgICAgICAgewotICAgICAgICAgICAgaWYgKFN5c3RlbS5nZXRTZWN1cml0eU1hbmFnZXIoKSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIERvY3VtZW50QnVpbGRlckZhY3RvcnkubmV3SW5zdGFuY2UoKS5uZXdEb2N1bWVudEJ1aWxkZXIoKS5uZXdEb2N1bWVudCgpOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gRG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5uZXdJbnN0YW5jZShKREtfREVGQVVMVF9ET00sIG51bGwpLm5ld0RvY3VtZW50QnVpbGRlcigpLm5ld0RvY3VtZW50KCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2goUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBwY2UpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLldyYXBwZWRSdW50aW1lRXhjZXB0aW9uKHBjZSk7Ci0gICAgICAgIH0KLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL2xpYi9Ob2RlSW5mby5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC9saWIvTm9kZUluZm8uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDVjYWEwMC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL2xpYi9Ob2RlSW5mby5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjUwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IE5vZGVJbmZvLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTAgMTg6NTQ6MzcgamVmZnN1dHRvciBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLmxpYjsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uU291cmNlTG9jYXRvcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC5leHRlbnNpb25zLkV4cHJlc3Npb25Db250ZXh0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLnJlZi5EVE1Ob2RlUHJveHk7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGVMaXN0OwotCi0vKioKLSAqIDxjb2RlPk5vZGVJbmZvPC9jb2RlPiBkZWZpbmVzIGEgc2V0IG9mIFhTTFQgZXh0ZW5zaW9uIGZ1bmN0aW9ucyB0byBiZQotICogdXNlZCBmcm9tIHN0eWxlc2hlZXRzLgotICoKLSAqIEBhdXRob3IgPGEgaHJlZj0ibWFpbHRvOm92aWRpdUBjdXAuaHAuY29tIj5PdmlkaXUgUHJlZGVzY3U8L2E+Ci0gKiBAc2luY2UgTWF5IDI0LCAyMDAxCi0gKi8KLXB1YmxpYyBjbGFzcyBOb2RlSW5mbwotewotICAvKioKLSAgICogPGNvZGU+c3lzdGVtSWQ8L2NvZGU+IHJldHVybnMgdGhlIHN5c3RlbSBpZCBvZiB0aGUgY3VycmVudAotICAgKiBjb250ZXh0IG5vZGUuCi0gICAqCi0gICAqIEBwYXJhbSBjb250ZXh0IGFuIDxjb2RlPkV4cHJlc3Npb25Db250ZXh0PC9jb2RlPiB2YWx1ZQotICAgKiBAcmV0dXJuIGEgPGNvZGU+U3RyaW5nPC9jb2RlPiB2YWx1ZQotICAgKi8KLSAgcHVibGljIHN0YXRpYyBTdHJpbmcgc3lzdGVtSWQoRXhwcmVzc2lvbkNvbnRleHQgY29udGV4dCkKLSAgewotICAgIE5vZGUgY29udGV4dE5vZGUgPSBjb250ZXh0LmdldENvbnRleHROb2RlKCk7Ci0gICAgaW50IG5vZGVIYW5kbGVyID0gKChEVE1Ob2RlUHJveHkpY29udGV4dE5vZGUpLmdldERUTU5vZGVOdW1iZXIoKTsKLSAgICBTb3VyY2VMb2NhdG9yIGxvY2F0b3IgPSAoKERUTU5vZGVQcm94eSljb250ZXh0Tm9kZSkuZ2V0RFRNKCkKLSAgICAgIC5nZXRTb3VyY2VMb2NhdG9yRm9yKG5vZGVIYW5kbGVyKTsKLQotICAgIGlmIChsb2NhdG9yICE9IG51bGwpCi0gICAgICByZXR1cm4gbG9jYXRvci5nZXRTeXN0ZW1JZCgpOwotICAgIGVsc2UKLSAgICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIDxjb2RlPnN5c3RlbUlkPC9jb2RlPiByZXR1cm5zIHRoZSBzeXN0ZW0gaWQgb2YgdGhlIG5vZGUgcGFzc2VkIGFzCi0gICAqIGFyZ3VtZW50LiBJZiBhIG5vZGUgc2V0IGlzIHBhc3NlZCBhcyBhcmd1bWVudCwgdGhlIHN5c3RlbSBpZCBvZgotICAgKiB0aGUgZmlyc3Qgbm9kZSBpbiB0aGUgc2V0IGlzIHJldHVybmVkLgotICAgKgotICAgKiBAcGFyYW0gbm9kZUxpc3QgYSA8Y29kZT5Ob2RlTGlzdDwvY29kZT4gdmFsdWUKLSAgICogQHJldHVybiBhIDxjb2RlPlN0cmluZzwvY29kZT4gdmFsdWUKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHN5c3RlbUlkKE5vZGVMaXN0IG5vZGVMaXN0KQotICB7Ci0gICAgaWYgKG5vZGVMaXN0ID09IG51bGwgfHwgbm9kZUxpc3QuZ2V0TGVuZ3RoKCkgPT0gMCkKLSAgICAgIHJldHVybiBudWxsOwotCi0gICAgTm9kZSBub2RlID0gbm9kZUxpc3QuaXRlbSgwKTsKLSAgICBpbnQgbm9kZUhhbmRsZXIgPSAoKERUTU5vZGVQcm94eSlub2RlKS5nZXREVE1Ob2RlTnVtYmVyKCk7Ci0gICAgU291cmNlTG9jYXRvciBsb2NhdG9yID0gKChEVE1Ob2RlUHJveHkpbm9kZSkuZ2V0RFRNKCkKLSAgICAgIC5nZXRTb3VyY2VMb2NhdG9yRm9yKG5vZGVIYW5kbGVyKTsKLQotICAgIGlmIChsb2NhdG9yICE9IG51bGwpCi0gICAgICByZXR1cm4gbG9jYXRvci5nZXRTeXN0ZW1JZCgpOwotICAgIGVsc2UKLSAgICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIDxjb2RlPnB1YmxpY0lkPC9jb2RlPiByZXR1cm5zIHRoZSBwdWJsaWMgaWRlbnRpZmllciBvZiB0aGUgY3VycmVudAotICAgKiBjb250ZXh0IG5vZGUuCi0gICAqCi0gICAqIFhhbGFuIGRvZXMgbm90IGN1cnJlbnRseSByZWNvcmQgdGhpcyB2YWx1ZSwgYW5kIHdpbGwgcmV0dXJuIG51bGwuCi0gICAqCi0gICAqIEBwYXJhbSBjb250ZXh0IGFuIDxjb2RlPkV4cHJlc3Npb25Db250ZXh0PC9jb2RlPiB2YWx1ZQotICAgKiBAcmV0dXJuIGEgPGNvZGU+U3RyaW5nPC9jb2RlPiB2YWx1ZQotICAgKi8KLSAgcHVibGljIHN0YXRpYyBTdHJpbmcgcHVibGljSWQoRXhwcmVzc2lvbkNvbnRleHQgY29udGV4dCkKLSAgewotICAgIE5vZGUgY29udGV4dE5vZGUgPSBjb250ZXh0LmdldENvbnRleHROb2RlKCk7Ci0gICAgaW50IG5vZGVIYW5kbGVyID0gKChEVE1Ob2RlUHJveHkpY29udGV4dE5vZGUpLmdldERUTU5vZGVOdW1iZXIoKTsKLSAgICBTb3VyY2VMb2NhdG9yIGxvY2F0b3IgPSAoKERUTU5vZGVQcm94eSljb250ZXh0Tm9kZSkuZ2V0RFRNKCkKLSAgICAgIC5nZXRTb3VyY2VMb2NhdG9yRm9yKG5vZGVIYW5kbGVyKTsKLQotICAgIGlmIChsb2NhdG9yICE9IG51bGwpCi0gICAgICByZXR1cm4gbG9jYXRvci5nZXRQdWJsaWNJZCgpOwotICAgIGVsc2UKLSAgICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIDxjb2RlPnB1YmxpY0lkPC9jb2RlPiByZXR1cm5zIHRoZSBwdWJsaWMgaWRlbnRpZmllciBvZiB0aGUgbm9kZSBwYXNzZWQgYXMKLSAgICogYXJndW1lbnQuIElmIGEgbm9kZSBzZXQgaXMgcGFzc2VkIGFzIGFyZ3VtZW50LCB0aGUgcHVibGljIGlkZW50aWZpZXIgb2YKLSAgICogdGhlIGZpcnN0IG5vZGUgaW4gdGhlIHNldCBpcyByZXR1cm5lZC4KLSAgICoKLSAgICogWGFsYW4gZG9lcyBub3QgY3VycmVudGx5IHJlY29yZCB0aGlzIHZhbHVlLCBhbmQgd2lsbCByZXR1cm4gbnVsbC4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVMaXN0IGEgPGNvZGU+Tm9kZUxpc3Q8L2NvZGU+IHZhbHVlCi0gICAqIEByZXR1cm4gYSA8Y29kZT5TdHJpbmc8L2NvZGU+IHZhbHVlCi0gICAqLwotICBwdWJsaWMgc3RhdGljIFN0cmluZyBwdWJsaWNJZChOb2RlTGlzdCBub2RlTGlzdCkKLSAgewotICAgIGlmIChub2RlTGlzdCA9PSBudWxsIHx8IG5vZGVMaXN0LmdldExlbmd0aCgpID09IDApCi0gICAgICByZXR1cm4gbnVsbDsKLQotICAgIE5vZGUgbm9kZSA9IG5vZGVMaXN0Lml0ZW0oMCk7Ci0gICAgaW50IG5vZGVIYW5kbGVyID0gKChEVE1Ob2RlUHJveHkpbm9kZSkuZ2V0RFRNTm9kZU51bWJlcigpOwotICAgIFNvdXJjZUxvY2F0b3IgbG9jYXRvciA9ICgoRFRNTm9kZVByb3h5KW5vZGUpLmdldERUTSgpCi0gICAgICAuZ2V0U291cmNlTG9jYXRvckZvcihub2RlSGFuZGxlcik7Ci0KLSAgICBpZiAobG9jYXRvciAhPSBudWxsKQotICAgICAgcmV0dXJuIGxvY2F0b3IuZ2V0UHVibGljSWQoKTsKLSAgICBlbHNlCi0gICAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiA8Y29kZT5saW5lTnVtYmVyPC9jb2RlPiByZXR1cm5zIHRoZSBsaW5lIG51bWJlciBvZiB0aGUgY3VycmVudAotICAgKiBjb250ZXh0IG5vZGUuCi0gICAqCi0gICAqIE5PVEU6IFhhbGFuIGRvZXMgbm90IG5vcm1hbGx5IHJlY29yZCBsb2NhdGlvbiBpbmZvcm1hdGlvbiBmb3IgZWFjaCBub2RlLgotICAgKiBUbyBvYnRhaW4gaXQsIHlvdSBtdXN0IHNldCB0aGUgY3VzdG9tIFRyQVggYXR0cmlidXRlCi0gICAqICJodHRwOi8veG1sLmFwYWNoZS5vcmcveGFsYW4vZmVhdHVyZXMvc291cmNlX2xvY2F0aW9uIgotICAgKiB0cnVlIGluIHRoZSBUcmFuc2Zvcm1lckZhY3RvcnkgYmVmb3JlIGdlbmVyYXRpbmcgdGhlIFRyYW5zZm9ybWVyIGFuZCBleGVjdXRpbmcKLSAgICogdGhlIHN0eWxlc2hlZXQuIFN0b3JhZ2UgY29zdCBwZXIgbm9kZSB3aWxsIGJlIG5vdGljYWJseSBpbmNyZWFzZWQgaW4gdGhpcyBtb2RlLgotICAgKgotICAgKiBAcGFyYW0gY29udGV4dCBhbiA8Y29kZT5FeHByZXNzaW9uQ29udGV4dDwvY29kZT4gdmFsdWUKLSAgICogQHJldHVybiBhbiA8Y29kZT5pbnQ8L2NvZGU+IHZhbHVlLiBUaGlzIG1heSBiZSAtMSB0byBpbmRpY2F0ZSB0aGF0IHRoZQotICAgKiBsaW5lIG51bWJlciBpcyBub3Qga25vd24uCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGludCBsaW5lTnVtYmVyKEV4cHJlc3Npb25Db250ZXh0IGNvbnRleHQpCi0gIHsKLSAgICBOb2RlIGNvbnRleHROb2RlID0gY29udGV4dC5nZXRDb250ZXh0Tm9kZSgpOwotICAgIGludCBub2RlSGFuZGxlciA9ICgoRFRNTm9kZVByb3h5KWNvbnRleHROb2RlKS5nZXREVE1Ob2RlTnVtYmVyKCk7Ci0gICAgU291cmNlTG9jYXRvciBsb2NhdG9yID0gKChEVE1Ob2RlUHJveHkpY29udGV4dE5vZGUpLmdldERUTSgpCi0gICAgICAuZ2V0U291cmNlTG9jYXRvckZvcihub2RlSGFuZGxlcik7Ci0KLSAgICBpZiAobG9jYXRvciAhPSBudWxsKQotICAgICAgcmV0dXJuIGxvY2F0b3IuZ2V0TGluZU51bWJlcigpOwotICAgIGVsc2UKLSAgICAgIHJldHVybiAtMTsKLSAgfQotCi0gIC8qKgotICAgKiA8Y29kZT5saW5lTnVtYmVyPC9jb2RlPiByZXR1cm5zIHRoZSBsaW5lIG51bWJlciBvZiB0aGUgbm9kZQotICAgKiBwYXNzZWQgYXMgYXJndW1lbnQuIElmIGEgbm9kZSBzZXQgaXMgcGFzc2VkIGFzIGFyZ3VtZW50LCB0aGUgbGluZQotICAgKiBudW1iZXIgb2YgdGhlIGZpcnN0IG5vZGUgaW4gdGhlIHNldCBpcyByZXR1cm5lZC4KLSAgICoKLSAgICogTk9URTogWGFsYW4gZG9lcyBub3Qgbm9ybWFsbHkgcmVjb3JkIGxvY2F0aW9uIGluZm9ybWF0aW9uIGZvciBlYWNoIG5vZGUuCi0gICAqIFRvIG9idGFpbiBpdCwgeW91IG11c3Qgc2V0IHRoZSBjdXN0b20gVHJBWCBhdHRyaWJ1dGUKLSAgICogImh0dHA6Ly94bWwuYXBhY2hlLm9yZy94YWxhbi9mZWF0dXJlcy9zb3VyY2VfbG9jYXRpb24iCi0gICAqIHRydWUgaW4gdGhlIFRyYW5zZm9ybWVyRmFjdG9yeSBiZWZvcmUgZ2VuZXJhdGluZyB0aGUgVHJhbnNmb3JtZXIgYW5kIGV4ZWN1dGluZwotICAgKiB0aGUgc3R5bGVzaGVldC4gU3RvcmFnZSBjb3N0IHBlciBub2RlIHdpbGwgYmUgbm90aWNhYmx5IGluY3JlYXNlZCBpbiB0aGlzIG1vZGUuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlTGlzdCBhIDxjb2RlPk5vZGVMaXN0PC9jb2RlPiB2YWx1ZQotICAgKiBAcmV0dXJuIGFuIDxjb2RlPmludDwvY29kZT4gdmFsdWUuIFRoaXMgbWF5IGJlIC0xIHRvIGluZGljYXRlIHRoYXQgdGhlCi0gICAqIGxpbmUgbnVtYmVyIGlzIG5vdCBrbm93bi4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgaW50IGxpbmVOdW1iZXIoTm9kZUxpc3Qgbm9kZUxpc3QpCi0gIHsKLSAgICBpZiAobm9kZUxpc3QgPT0gbnVsbCB8fCBub2RlTGlzdC5nZXRMZW5ndGgoKSA9PSAwKQotICAgICAgcmV0dXJuIC0xOwotCi0gICAgTm9kZSBub2RlID0gbm9kZUxpc3QuaXRlbSgwKTsKLSAgICBpbnQgbm9kZUhhbmRsZXIgPSAoKERUTU5vZGVQcm94eSlub2RlKS5nZXREVE1Ob2RlTnVtYmVyKCk7Ci0gICAgU291cmNlTG9jYXRvciBsb2NhdG9yID0gKChEVE1Ob2RlUHJveHkpbm9kZSkuZ2V0RFRNKCkKLSAgICAgIC5nZXRTb3VyY2VMb2NhdG9yRm9yKG5vZGVIYW5kbGVyKTsKLQotICAgIGlmIChsb2NhdG9yICE9IG51bGwpCi0gICAgICByZXR1cm4gbG9jYXRvci5nZXRMaW5lTnVtYmVyKCk7Ci0gICAgZWxzZQotICAgICAgcmV0dXJuIC0xOwotICB9Ci0KLSAgLyoqCi0gICAqIDxjb2RlPmNvbHVtbk51bWJlcjwvY29kZT4gcmV0dXJucyB0aGUgY29sdW1uIG51bWJlciBvZiB0aGUKLSAgICogY3VycmVudCBjb250ZXh0IG5vZGUuCi0gICAqCi0gICAqIE5PVEU6IFhhbGFuIGRvZXMgbm90IG5vcm1hbGx5IHJlY29yZCBsb2NhdGlvbiBpbmZvcm1hdGlvbiBmb3IgZWFjaCBub2RlLgotICAgKiBUbyBvYnRhaW4gaXQsIHlvdSBtdXN0IHNldCB0aGUgY3VzdG9tIFRyQVggYXR0cmlidXRlCi0gICAqICJodHRwOi8veG1sLmFwYWNoZS5vcmcveGFsYW4vZmVhdHVyZXMvc291cmNlX2xvY2F0aW9uIgotICAgKiB0cnVlIGluIHRoZSBUcmFuc2Zvcm1lckZhY3RvcnkgYmVmb3JlIGdlbmVyYXRpbmcgdGhlIFRyYW5zZm9ybWVyIGFuZCBleGVjdXRpbmcKLSAgICogdGhlIHN0eWxlc2hlZXQuIFN0b3JhZ2UgY29zdCBwZXIgbm9kZSB3aWxsIGJlIG5vdGljYWJseSBpbmNyZWFzZWQgaW4gdGhpcyBtb2RlLgotICAgKgotICAgKiBAcGFyYW0gY29udGV4dCBhbiA8Y29kZT5FeHByZXNzaW9uQ29udGV4dDwvY29kZT4gdmFsdWUKLSAgICogQHJldHVybiBhbiA8Y29kZT5pbnQ8L2NvZGU+IHZhbHVlLiBUaGlzIG1heSBiZSAtMSB0byBpbmRpY2F0ZSB0aGF0IHRoZQotICAgKiBjb2x1bW4gbnVtYmVyIGlzIG5vdCBrbm93bi4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgaW50IGNvbHVtbk51bWJlcihFeHByZXNzaW9uQ29udGV4dCBjb250ZXh0KQotICB7Ci0gICAgTm9kZSBjb250ZXh0Tm9kZSA9IGNvbnRleHQuZ2V0Q29udGV4dE5vZGUoKTsKLSAgICBpbnQgbm9kZUhhbmRsZXIgPSAoKERUTU5vZGVQcm94eSljb250ZXh0Tm9kZSkuZ2V0RFRNTm9kZU51bWJlcigpOwotICAgIFNvdXJjZUxvY2F0b3IgbG9jYXRvciA9ICgoRFRNTm9kZVByb3h5KWNvbnRleHROb2RlKS5nZXREVE0oKQotICAgICAgLmdldFNvdXJjZUxvY2F0b3JGb3Iobm9kZUhhbmRsZXIpOwotCi0gICAgaWYgKGxvY2F0b3IgIT0gbnVsbCkKLSAgICAgIHJldHVybiBsb2NhdG9yLmdldENvbHVtbk51bWJlcigpOwotICAgIGVsc2UKLSAgICAgIHJldHVybiAtMTsKLSAgfQotCi0gIC8qKgotICAgKiA8Y29kZT5jb2x1bW5OdW1iZXI8L2NvZGU+IHJldHVybnMgdGhlIGNvbHVtbiBudW1iZXIgb2YgdGhlIG5vZGUKLSAgICogcGFzc2VkIGFzIGFyZ3VtZW50LiBJZiBhIG5vZGUgc2V0IGlzIHBhc3NlZCBhcyBhcmd1bWVudCwgdGhlIGxpbmUKLSAgICogbnVtYmVyIG9mIHRoZSBmaXJzdCBub2RlIGluIHRoZSBzZXQgaXMgcmV0dXJuZWQuCi0gICAqCi0gICAqIE5PVEU6IFhhbGFuIGRvZXMgbm90IG5vcm1hbGx5IHJlY29yZCBsb2NhdGlvbiBpbmZvcm1hdGlvbiBmb3IgZWFjaCBub2RlLgotICAgKiBUbyBvYnRhaW4gaXQsIHlvdSBtdXN0IHNldCB0aGUgY3VzdG9tIFRyQVggYXR0cmlidXRlCi0gICAqICJodHRwOi8veG1sLmFwYWNoZS5vcmcveGFsYW4vZmVhdHVyZXMvc291cmNlX2xvY2F0aW9uIgotICAgKiB0cnVlIGluIHRoZSBUcmFuc2Zvcm1lckZhY3RvcnkgYmVmb3JlIGdlbmVyYXRpbmcgdGhlIFRyYW5zZm9ybWVyIGFuZCBleGVjdXRpbmcKLSAgICogdGhlIHN0eWxlc2hlZXQuIFN0b3JhZ2UgY29zdCBwZXIgbm9kZSB3aWxsIGJlIG5vdGljYWJseSBpbmNyZWFzZWQgaW4gdGhpcyBtb2RlLgotICAgKgotICAgKiBAcGFyYW0gbm9kZUxpc3QgYSA8Y29kZT5Ob2RlTGlzdDwvY29kZT4gdmFsdWUKLSAgICogQHJldHVybiBhbiA8Y29kZT5pbnQ8L2NvZGU+IHZhbHVlLiBUaGlzIG1heSBiZSAtMSB0byBpbmRpY2F0ZSB0aGF0IHRoZQotICAgKiBjb2x1bW4gbnVtYmVyIGlzIG5vdCBrbm93bi4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgaW50IGNvbHVtbk51bWJlcihOb2RlTGlzdCBub2RlTGlzdCkKLSAgewotICAgIGlmIChub2RlTGlzdCA9PSBudWxsIHx8IG5vZGVMaXN0LmdldExlbmd0aCgpID09IDApCi0gICAgICByZXR1cm4gLTE7Ci0KLSAgICBOb2RlIG5vZGUgPSBub2RlTGlzdC5pdGVtKDApOwotICAgIGludCBub2RlSGFuZGxlciA9ICgoRFRNTm9kZVByb3h5KW5vZGUpLmdldERUTU5vZGVOdW1iZXIoKTsKLSAgICBTb3VyY2VMb2NhdG9yIGxvY2F0b3IgPSAoKERUTU5vZGVQcm94eSlub2RlKS5nZXREVE0oKQotICAgICAgLmdldFNvdXJjZUxvY2F0b3JGb3Iobm9kZUhhbmRsZXIpOwotCi0gICAgaWYgKGxvY2F0b3IgIT0gbnVsbCkKLSAgICAgIHJldHVybiBsb2NhdG9yLmdldENvbHVtbk51bWJlcigpOwotICAgIGVsc2UKLSAgICAgIHJldHVybiAtMTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC9saWIvcGFja2FnZS5odG1sIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC9saWIvcGFja2FnZS5odG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiNjIxMTY4Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwvbGliL3BhY2thZ2UuaHRtbAorKysgL2Rldi9udWxsCkBAIC0xLDI5ICswLDAgQEAKLTwhLS0KLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0tLT4KLTwhLS0KLSAqIENvcHlyaWdodCAyMDAwLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotLS0+Ci08IS0tICRJZDogcGFja2FnZS5odG1sLHYgMS4xLjIuMSAyMDA1LzA4LzAxIDAyOjA4OjUwIGplZmZzdXR0b3IgRXhwICQgLS0+Ci08aHRtbD4KLSAgPHRpdGxlPlhhbGFuIGFuZCBFWFNMVCBFeHRlbnNpb25zLjwvdGl0bGU+Ci0gIDxib2R5PgotICAgPHA+RXh0ZW5zaW9uIGVsZW1lbnRzIGFuZCBmdW5jdGlvbnMgc2hpcHBlZCB3aXRoIFhhbGFuLUphdmEsIGluY2x1ZGluZyBFWFNMVCBmdW5jdGlvbnMuPC9wPgotICAgPHA+V2UgYXJlIGFkZGluZyBleHRlbnNpb25zIHRvIHRoaXMgcGFja2FnZS48cD4KLSAgPC9ib2R5PgotPC9odG1sPgotCi0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwvcmVzL1hTTE1lc3NhZ2VzLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3Jlcy9YU0xNZXNzYWdlcy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMGQxMWU5Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwvcmVzL1hTTE1lc3NhZ2VzLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5MyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBYU0xNZXNzYWdlcy5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzA5IDA3OjQxOjEwIHB2ZWR1bGEgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwucmVzOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnV0aWxzLlNlY3VyaXR5U3VwcG9ydDsKLWltcG9ydCBqYXZhLnV0aWwuTGlzdFJlc291cmNlQnVuZGxlOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLnJlcy5YUEFUSE1lc3NhZ2VzOwotCi0vKioKLSAqIFNldHMgdGhpbmdzIHVwIGZvciBpc3N1aW5nIGVycm9yIG1lc3NhZ2VzLiBUaGlzIGNsYXNzIGlzIG1pc25hbWVkLCBhbmQgc2hvdWxkCi0gKiBiZSBjYWxsZWQgWGFsYW5NZXNzYWdlcywgb3Igc29tZSBzdWNoLgotICoKLSAqIEB4c2wudXNhZ2UgaW50ZXJuYWwKLSAqLwotcHVibGljIGNsYXNzIFhTTE1lc3NhZ2VzIGV4dGVuZHMgWFBBVEhNZXNzYWdlcyB7Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgbGFuZ3VhZ2Ugc3BlY2lmaWMgcmVzb3VyY2Ugb2JqZWN0IGZvciBYYWxhbiBtZXNzYWdlcy4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBMaXN0UmVzb3VyY2VCdW5kbGUgWFNMVEJ1bmRsZSA9IG51bGw7Ci0gICAgLyoqCi0gICAgICogVGhlIGNsYXNzIG5hbWUgb2YgdGhlIFhhbGFuIGVycm9yIG1lc3NhZ2Ugc3RyaW5nIHRhYmxlLgotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBYU0xUX0VSUk9SX1JFU09VUkNFUyA9Ci0gICAgICAgICAgICAiY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnJlcy5YU0xURXJyb3JSZXNvdXJjZXMiOwotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlcyBhIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIGtleSBhbmQgcmVwbGFjZW1lbnQgYXJndW1lbnRzLAotICAgICAqIGxvY2FsaXplZCB0byB0aGUgZ2l2ZW4gbG9jYWxlLgotICAgICAqCi0gICAgICogQHBhcmFtIG1zZ0tleSBUaGUga2V5IGZvciB0aGUgbWVzc2FnZSB0ZXh0LgotICAgICAqIEBwYXJhbSBhcmdzIFRoZSBhcmd1bWVudHMgdG8gYmUgdXNlZCBhcyByZXBsYWNlbWVudCB0ZXh0IGluIHRoZSBtZXNzYWdlCi0gICAgICogY3JlYXRlZC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIGZvcm1hdHRlZCBtZXNzYWdlIHN0cmluZy4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBjcmVhdGVNZXNzYWdlKFN0cmluZyBtc2dLZXksIE9iamVjdCBhcmdzW10pIC8vdGhyb3dzIEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaWYgKFhTTFRCdW5kbGUgPT0gbnVsbCkgewotICAgICAgICAgICAgWFNMVEJ1bmRsZSA9IFNlY3VyaXR5U3VwcG9ydC5nZXRSZXNvdXJjZUJ1bmRsZShYU0xUX0VSUk9SX1JFU09VUkNFUyk7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoWFNMVEJ1bmRsZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gY3JlYXRlTXNnKFhTTFRCdW5kbGUsIG1zZ0tleSwgYXJncyk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gIkNvdWxkIG5vdCBsb2FkIGFueSByZXNvdXJjZSBidW5kbGVzLiI7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGVzIGEgbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQga2V5IGFuZCByZXBsYWNlbWVudCBhcmd1bWVudHMsCi0gICAgICogbG9jYWxpemVkIHRvIHRoZSBnaXZlbiBsb2NhbGUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbXNnS2V5IFRoZSBrZXkgZm9yIHRoZSBtZXNzYWdlIHRleHQuCi0gICAgICogQHBhcmFtIGFyZ3MgVGhlIGFyZ3VtZW50cyB0byBiZSB1c2VkIGFzIHJlcGxhY2VtZW50IHRleHQgaW4gdGhlIG1lc3NhZ2UKLSAgICAgKiBjcmVhdGVkLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgZm9ybWF0dGVkIHdhcm5pbmcgc3RyaW5nLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGNyZWF0ZVdhcm5pbmcoU3RyaW5nIG1zZ0tleSwgT2JqZWN0IGFyZ3NbXSkgLy90aHJvd3MgRXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAoWFNMVEJ1bmRsZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBYU0xUQnVuZGxlID0gU2VjdXJpdHlTdXBwb3J0LmdldFJlc291cmNlQnVuZGxlKFhTTFRfRVJST1JfUkVTT1VSQ0VTKTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChYU0xUQnVuZGxlICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBjcmVhdGVNc2coWFNMVEJ1bmRsZSwgbXNnS2V5LCBhcmdzKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiAiQ291bGQgbm90IGxvYWQgYW55IHJlc291cmNlIGJ1bmRsZXMuIjsKLSAgICAgICAgfQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwvcmVzL1hTTFRFcnJvclJlc291cmNlcy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC9yZXMvWFNMVEVycm9yUmVzb3VyY2VzLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDVlZjM3NGYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC9yZXMvWFNMVEVycm9yUmVzb3VyY2VzLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNDQ3ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnJlczsKLQotaW1wb3J0IGphdmEudXRpbC5MaXN0UmVzb3VyY2VCdW5kbGU7Ci1pbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKLWltcG9ydCBqYXZhLnV0aWwuTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uOwotaW1wb3J0IGphdmEudXRpbC5SZXNvdXJjZUJ1bmRsZTsKLQotLyoqCi0gKiBTZXQgdXAgZXJyb3IgbWVzc2FnZXMuCi0gKiBXZSBidWlsZCBhIHR3byBkaW1lbnNpb25hbCBhcnJheSBvZiBtZXNzYWdlIGtleXMgYW5kCi0gKiBtZXNzYWdlIHN0cmluZ3MuIEluIG9yZGVyIHRvIGFkZCBhIG5ldyBtZXNzYWdlIGhlcmUsCi0gKiB5b3UgbmVlZCB0byBmaXJzdCBhZGQgYSBTdHJpbmcgY29uc3RhbnQuIEFuZAotICogIHlvdSBuZWVkIHRvIGVudGVyIGtleSAsIHZhbHVlIHBhaXIgYXMgcGFydCBvZiBjb250ZW50cwotICogQXJyYXkuIFlvdSBhbHNvIG5lZWQgdG8gdXBkYXRlIE1BWF9DT0RFIGZvciBlcnJvciBzdHJpbmdzCi0gKiBhbmQgTUFYX1dBUk5JTkcgZm9yIHdhcm5pbmdzICggTmVlZGVkIGZvciBvbmx5IGluZm9ybWF0aW9uCi0gKiBwdXJwb3NlICkKLSAqLwotcHVibGljIGNsYXNzIFhTTFRFcnJvclJlc291cmNlcyBleHRlbmRzIExpc3RSZXNvdXJjZUJ1bmRsZQotewotCi0vKgotICogVGhpcyBmaWxlIGNvbnRhaW5zIGVycm9yIGFuZCB3YXJuaW5nIG1lc3NhZ2VzIHJlbGF0ZWQgdG8gWGFsYW4gRXJyb3IKLSAqIEhhbmRsaW5nLgotICoKLSAqICBHZW5lcmFsIG5vdGVzIHRvIHRyYW5zbGF0b3JzOgotICoKLSAqICAxKSBYYWxhbiAob3IgbW9yZSBwcm9wZXJseSwgWGFsYW4taW50ZXJwcmV0aXZlKSBhbmQgWFNMVEMgYXJlIG5hbWVzIG9mCi0gKiAgICAgY29tcG9uZW50cy4KLSAqICAgICBYU0xUIGlzIGFuIGFjcm9ueW0gZm9yICJYTUwgU3R5bGVzaGVldCBMYW5ndWFnZTogVHJhbnNmb3JtYXRpb25zIi4KLSAqICAgICBYU0xUQyBpcyBhbiBhY3JvbnltIGZvciBYU0xUIENvbXBpbGVyLgotICoKLSAqICAyKSBBIHN0eWxlc2hlZXQgaXMgYSBkZXNjcmlwdGlvbiBvZiBob3cgdG8gdHJhbnNmb3JtIGFuIGlucHV0IFhNTCBkb2N1bWVudAotICogICAgIGludG8gYSByZXN1bHRhbnQgWE1MIGRvY3VtZW50IChvciBIVE1MIGRvY3VtZW50IG9yIHRleHQpLiAgVGhlCi0gKiAgICAgc3R5bGVzaGVldCBpdHNlbGYgaXMgZGVzY3JpYmVkIGluIHRoZSBmb3JtIG9mIGFuIFhNTCBkb2N1bWVudC4KLSAqCi0gKiAgMykgQSB0ZW1wbGF0ZSBpcyBhIGNvbXBvbmVudCBvZiBhIHN0eWxlc2hlZXQgdGhhdCBpcyB1c2VkIHRvIG1hdGNoIGEKLSAqICAgICBwYXJ0aWN1bGFyIHBvcnRpb24gb2YgYW4gaW5wdXQgZG9jdW1lbnQgYW5kIHNwZWNpZmllcyB0aGUgZm9ybSBvZiB0aGUKLSAqICAgICBjb3JyZXNwb25kaW5nIHBvcnRpb24gb2YgdGhlIG91dHB1dCBkb2N1bWVudC4KLSAqCi0gKiAgNCkgQW4gZWxlbWVudCBpcyBhIG1hcmstdXAgdGFnIGluIGFuIFhNTCBkb2N1bWVudDsgYW4gYXR0cmlidXRlIGlzIGEKLSAqICAgICBtb2RpZmllciBvbiB0aGUgdGFnLiAgRm9yIGV4YW1wbGUsIGluIDxlbGVtIGF0dHI9J3ZhbCcgYXR0cjI9J3ZhbDInPgotICogICAgICJlbGVtIiBpcyBhbiBlbGVtZW50IG5hbWUsICJhdHRyIiBhbmQgImF0dHIyIiBhcmUgYXR0cmlidXRlIG5hbWVzIHdpdGgKLSAqICAgICB0aGUgdmFsdWVzICJ2YWwiIGFuZCAidmFsMiIsIHJlc3BlY3RpdmVseS4KLSAqCi0gKiAgNSkgQSBuYW1lc3BhY2UgZGVjbGFyYXRpb24gaXMgYSBzcGVjaWFsIGF0dHJpYnV0ZSB0aGF0IGlzIHVzZWQgdG8gYXNzb2NpYXRlCi0gKiAgICAgYSBwcmVmaXggd2l0aCBhIFVSSSAodGhlIG5hbWVzcGFjZSkuICBUaGUgbWVhbmluZ3Mgb2YgZWxlbWVudCBuYW1lcyBhbmQKLSAqICAgICBhdHRyaWJ1dGUgbmFtZXMgdGhhdCB1c2UgdGhhdCBwcmVmaXggYXJlIGRlZmluZWQgd2l0aCByZXNwZWN0IHRvIHRoYXQKLSAqICAgICBuYW1lc3BhY2UuCi0gKgotICogIDYpICJUcmFuc2xldCIgaXMgYW4gaW52ZW50ZWQgdGVybSB0aGF0IGRlc2NyaWJlcyB0aGUgY2xhc3MgZmlsZSB0aGF0Ci0gKiAgICAgcmVzdWx0cyBmcm9tIGNvbXBpbGluZyBhbiBYTUwgc3R5bGVzaGVldCBpbnRvIGEgSmF2YSBjbGFzcy4KLSAqCi0gKiAgNykgWFBhdGggaXMgYSBzcGVjaWZpY2F0aW9uIHRoYXQgZGVzY3JpYmVzIGEgbm90YXRpb24gZm9yIGlkZW50aWZ5aW5nCi0gKiAgICAgbm9kZXMgaW4gYSB0cmVlLXN0cnVjdHVyZWQgcmVwcmVzZW50YXRpb24gb2YgYW4gWE1MIGRvY3VtZW50LiAgQW4KLSAqICAgICBpbnN0YW5jZSBvZiB0aGF0IG5vdGF0aW9uIGlzIHJlZmVycmVkIHRvIGFzIGFuIFhQYXRoIGV4cHJlc3Npb24uCi0gKgotICovCi0KLSAgLyoKLSAgICogU3RhdGljIHZhcmlhYmxlcwotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9OQU1FU1BBQ0VfVVJJX1ZBTFVFX0ZPUl9SRVNVTFRfUFJFRklYID0KLSAgICAgICAgIkVSX0lOVkFMSURfU0VUX05BTUVTUEFDRV9VUklfVkFMVUVfRk9SX1JFU1VMVF9QUkVGSVgiOwotCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfTkFNRVNQQUNFX1VSSV9WQUxVRV9GT1JfUkVTVUxUX1BSRUZJWF9GT1JfREVGQVVMVCA9Ci0gICAgICAgICJFUl9JTlZBTElEX05BTUVTUEFDRV9VUklfVkFMVUVfRk9SX1JFU1VMVF9QUkVGSVhfRk9SX0RFRkFVTFQiOwotCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX0NVUkxZQlJBQ0UgPSAiRVJfTk9fQ1VSTFlCUkFDRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQgPSAiRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lMTEVHQUxfQVRUUklCVVRFID0gIkVSX0lMTEVHQUxfQVRUUklCVVRFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTlVMTF9TT1VSQ0VOT0RFX0FQUExZSU1QT1JUUyA9ICJFUl9OVUxMX1NPVVJDRU5PREVfQVBQTFlJTVBPUlRTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX0FERCA9ICJFUl9DQU5OT1RfQUREIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTlVMTF9TT1VSQ0VOT0RFX0hBTkRMRUFQUExZVEVNUExBVEVTPSJFUl9OVUxMX1NPVVJDRU5PREVfSEFORExFQVBQTFlURU1QTEFURVMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19OQU1FX0FUVFJJQiA9ICJFUl9OT19OQU1FX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1RFTVBMQVRFX05PVF9GT1VORCA9ICJFUl9URU1QTEFURV9OT1RfRk9VTkQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX1JFU09MVkVfTkFNRV9BVlQgPSAiRVJfQ0FOVF9SRVNPTFZFX05BTUVfQVZUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUkVRVUlSRVNfQVRUUklCID0gIkVSX1JFUVVJUkVTX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01VU1RfSEFWRV9URVNUX0FUVFJJQiA9ICJFUl9NVVNUX0hBVkVfVEVTVF9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9CQURfVkFMX09OX0xFVkVMX0FUVFJJQiA9Ci0gICAgICAgICAiRVJfQkFEX1ZBTF9PTl9MRVZFTF9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUk9DRVNTSU5HSU5TVFJVQ1RJT05fTkFNRV9DQU5UX0JFX1hNTCA9Ci0gICAgICAgICAiRVJfUFJPQ0VTU0lOR0lOU1RSVUNUSU9OX05BTUVfQ0FOVF9CRV9YTUwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUk9DRVNTSU5HSU5TVFJVQ1RJT05fTk9UVkFMSURfTkNOQU1FID0KLSAgICAgICAgICJFUl9QUk9DRVNTSU5HSU5TVFJVQ1RJT05fTk9UVkFMSURfTkNOQU1FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTkVFRF9NQVRDSF9BVFRSSUIgPSAiRVJfTkVFRF9NQVRDSF9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9ORUVEX05BTUVfT1JfTUFUQ0hfQVRUUklCID0KLSAgICAgICAgICJFUl9ORUVEX05BTUVfT1JfTUFUQ0hfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9SRVNPTFZFX05TUFJFRklYID0KLSAgICAgICAgICJFUl9DQU5UX1JFU09MVkVfTlNQUkVGSVgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTExFR0FMX1ZBTFVFID0gIkVSX0lMTEVHQUxfVkFMVUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19PV05FUkRPQyA9ICJFUl9OT19PV05FUkRPQyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VMRU1URU1QTEFURUVMRU1fRVJSID0iRVJfRUxFTVRFTVBMQVRFRUxFTV9FUlIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OVUxMX0NISUxEID0gIkVSX05VTExfQ0hJTEQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9ORUVEX1NFTEVDVF9BVFRSSUIgPSAiRVJfTkVFRF9TRUxFQ1RfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTkVFRF9URVNUX0FUVFJJQiA9ICJFUl9ORUVEX1RFU1RfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTkVFRF9OQU1FX0FUVFJJQiA9ICJFUl9ORUVEX05BTUVfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fQ09OVEVYVF9PV05FUkRPQyA9ICJFUl9OT19DT05URVhUX09XTkVSRE9DIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTERfTk9UX0NSRUFURV9YTUxfUFJPQ19MSUFJU09OID0KLSAgICAgICAgICJFUl9DT1VMRF9OT1RfQ1JFQVRFX1hNTF9QUk9DX0xJQUlTT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUk9DRVNTX05PVF9TVUNDRVNTRlVMID0KLSAgICAgICAgICJFUl9QUk9DRVNTX05PVF9TVUNDRVNTRlVMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9UX1NVQ0NFU1NGVUwgPSAiRVJfTk9UX1NVQ0NFU1NGVUwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FTkNPRElOR19OT1RfU1VQUE9SVEVEID0KLSAgICAgICAgICJFUl9FTkNPRElOR19OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTERfTk9UX0NSRUFURV9UUkFDRUxJU1RFTkVSID0KLSAgICAgICAgICJFUl9DT1VMRF9OT1RfQ1JFQVRFX1RSQUNFTElTVEVORVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9LRVlfUkVRVUlSRVNfTkFNRV9BVFRSSUIgPQotICAgICAgICAgIkVSX0tFWV9SRVFVSVJFU19OQU1FX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0tFWV9SRVFVSVJFU19NQVRDSF9BVFRSSUIgPQotICAgICAgICAgIkVSX0tFWV9SRVFVSVJFU19NQVRDSF9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9LRVlfUkVRVUlSRVNfVVNFX0FUVFJJQiA9Ci0gICAgICAgICAiRVJfS0VZX1JFUVVJUkVTX1VTRV9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SRVFVSVJFU19FTEVNRU5UU19BVFRSSUIgPQotICAgICAgICAgIkVSX1JFUVVJUkVTX0VMRU1FTlRTX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01JU1NJTkdfUFJFRklYX0FUVFJJQiA9Ci0gICAgICAgICAiRVJfTUlTU0lOR19QUkVGSVhfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQkFEX1NUWUxFU0hFRVRfVVJMID0gIkVSX0JBRF9TVFlMRVNIRUVUX1VSTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZJTEVfTk9UX0ZPVU5EID0gIkVSX0ZJTEVfTk9UX0ZPVU5EIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU9FWENFUFRJT04gPSAiRVJfSU9FWENFUFRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19IUkVGX0FUVFJJQiA9ICJFUl9OT19IUkVGX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NUWUxFU0hFRVRfSU5DTFVERVNfSVRTRUxGID0KLSAgICAgICAgICJFUl9TVFlMRVNIRUVUX0lOQ0xVREVTX0lUU0VMRiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BST0NFU1NJTkNMVURFX0VSUk9SID0iRVJfUFJPQ0VTU0lOQ0xVREVfRVJST1IiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9NSVNTSU5HX0xBTkdfQVRUUklCID0gIkVSX01JU1NJTkdfTEFOR19BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9NSVNTSU5HX0NPTlRBSU5FUl9FTEVNRU5UX0NPTVBPTkVOVCA9Ci0gICAgICAgICAiRVJfTUlTU0lOR19DT05UQUlORVJfRUxFTUVOVF9DT01QT05FTlQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5fT05MWV9PVVRQVVRfVE9fRUxFTUVOVCA9Ci0gICAgICAgICAiRVJfQ0FOX09OTFlfT1VUUFVUX1RPX0VMRU1FTlQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUk9DRVNTX0VSUk9SID0gIkVSX1BST0NFU1NfRVJST1IiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTklNUExOT0RFX0VSUk9SID0gIkVSX1VOSU1QTE5PREVfRVJST1IiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19TRUxFQ1RfRVhQUkVTU0lPTiA9IkVSX05PX1NFTEVDVF9FWFBSRVNTSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX1NFUklBTElaRV9YU0xQUk9DRVNTT1IgPQotICAgICAgICAgIkVSX0NBTk5PVF9TRVJJQUxJWkVfWFNMUFJPQ0VTU09SIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fSU5QVVRfU1RZTEVTSEVFVCA9ICJFUl9OT19JTlBVVF9TVFlMRVNIRUVUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRkFJTEVEX1BST0NFU1NfU1RZTEVTSEVFVCA9Ci0gICAgICAgICAiRVJfRkFJTEVEX1BST0NFU1NfU1RZTEVTSEVFVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxETlRfUEFSU0VfRE9DID0gIkVSX0NPVUxETlRfUEFSU0VfRE9DIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTEROVF9GSU5EX0ZSQUdNRU5UID0KLSAgICAgICAgICJFUl9DT1VMRE5UX0ZJTkRfRlJBR01FTlQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT0RFX05PVF9FTEVNRU5UID0gIkVSX05PREVfTk9UX0VMRU1FTlQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GT1JFQUNIX05FRURfTUFUQ0hfT1JfTkFNRV9BVFRSSUIgPQotICAgICAgICAgIkVSX0ZPUkVBQ0hfTkVFRF9NQVRDSF9PUl9OQU1FX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1RFTVBMQVRFU19ORUVEX01BVENIX09SX05BTUVfQVRUUklCID0KLSAgICAgICAgICJFUl9URU1QTEFURVNfTkVFRF9NQVRDSF9PUl9OQU1FX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX0NMT05FX09GX0RPQ1VNRU5UX0ZSQUcgPQotICAgICAgICAgIkVSX05PX0NMT05FX09GX0RPQ1VNRU5UX0ZSQUciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX0NSRUFURV9JVEVNID0gIkVSX0NBTlRfQ1JFQVRFX0lURU0iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YTUxTUEFDRV9JTExFR0FMX1ZBTFVFID0KLSAgICAgICAgICJFUl9YTUxTUEFDRV9JTExFR0FMX1ZBTFVFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fWFNMS0VZX0RFQ0xBUkFUSU9OID0KLSAgICAgICAgICJFUl9OT19YU0xLRVlfREVDTEFSQVRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX0NSRUFURV9VUkwgPSAiRVJfQ0FOVF9DUkVBVEVfVVJMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWFNMRlVOQ1RJT05TX1VOU1VQUE9SVEVEID0KLSAgICAgICAgICJFUl9YU0xGVU5DVElPTlNfVU5TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUk9DRVNTT1JfRVJST1IgPSAiRVJfUFJPQ0VTU09SX0VSUk9SIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9UX0FMTE9XRURfSU5TSURFX1NUWUxFU0hFRVQgPQotICAgICAgICAgIkVSX05PVF9BTExPV0VEX0lOU0lERV9TVFlMRVNIRUVUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUkVTVUxUTlNfTk9UX1NVUFBPUlRFRCA9Ci0gICAgICAgICAiRVJfUkVTVUxUTlNfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0RFRkFVTFRTUEFDRV9OT1RfU1VQUE9SVEVEID0KLSAgICAgICAgICJFUl9ERUZBVUxUU1BBQ0VfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOREVOVFJFU1VMVF9OT1RfU1VQUE9SVEVEID0KLSAgICAgICAgICJFUl9JTkRFTlRSRVNVTFRfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lMTEVHQUxfQVRUUklCID0gIkVSX0lMTEVHQUxfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5LTk9XTl9YU0xfRUxFTSA9ICJFUl9VTktOT1dOX1hTTF9FTEVNIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQkFEX1hTTFNPUlRfVVNFID0gIkVSX0JBRF9YU0xTT1JUX1VTRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01JU1BMQUNFRF9YU0xXSEVOID0gIkVSX01JU1BMQUNFRF9YU0xXSEVOIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWFNMV0hFTl9OT1RfUEFSRU5URURfQllfWFNMQ0hPT1NFID0KLSAgICAgICAgICJFUl9YU0xXSEVOX05PVF9QQVJFTlRFRF9CWV9YU0xDSE9PU0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9NSVNQTEFDRURfWFNMT1RIRVJXSVNFID0KLSAgICAgICAgICJFUl9NSVNQTEFDRURfWFNMT1RIRVJXSVNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWFNMT1RIRVJXSVNFX05PVF9QQVJFTlRFRF9CWV9YU0xDSE9PU0UgPQotICAgICAgICAgIkVSX1hTTE9USEVSV0lTRV9OT1RfUEFSRU5URURfQllfWFNMQ0hPT1NFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9UX0FMTE9XRURfSU5TSURFX1RFTVBMQVRFID0KLSAgICAgICAgICJFUl9OT1RfQUxMT1dFRF9JTlNJREVfVEVNUExBVEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTktOT1dOX0VYVF9OU19QUkVGSVggPQotICAgICAgICAgIkVSX1VOS05PV05fRVhUX05TX1BSRUZJWCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lNUE9SVFNfQVNfRklSU1RfRUxFTSA9Ci0gICAgICAgICAiRVJfSU1QT1JUU19BU19GSVJTVF9FTEVNIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU1QT1JUSU5HX0lUU0VMRiA9ICJFUl9JTVBPUlRJTkdfSVRTRUxGIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWE1MU1BBQ0VfSUxMRUdBTF9WQUwgPSJFUl9YTUxTUEFDRV9JTExFR0FMX1ZBTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BST0NFU1NTVFlMRVNIRUVUX05PVF9TVUNDRVNTRlVMID0KLSAgICAgICAgICJFUl9QUk9DRVNTU1RZTEVTSEVFVF9OT1RfU1VDQ0VTU0ZVTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NBWF9FWENFUFRJT04gPSAiRVJfU0FYX0VYQ0VQVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hTTFRfRVJST1IgPSAiRVJfWFNMVF9FUlJPUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NVUlJFTkNZX1NJR05fSUxMRUdBTD0KLSAgICAgICAgICJFUl9DVVJSRU5DWV9TSUdOX0lMTEVHQUwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9ET0NVTUVOVF9GVU5DVElPTl9JTlZBTElEX0lOX1NUWUxFU0hFRVRfRE9NID0KLSAgICAgICAgICJFUl9ET0NVTUVOVF9GVU5DVElPTl9JTlZBTElEX0lOX1NUWUxFU0hFRVRfRE9NIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9SRVNPTFZFX1BSRUZJWF9PRl9OT05fUFJFRklYX1JFU09MVkVSID0KLSAgICAgICAgICJFUl9DQU5UX1JFU09MVkVfUFJFRklYX09GX05PTl9QUkVGSVhfUkVTT0xWRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SRURJUkVDVF9DT1VMRE5UX0dFVF9GSUxFTkFNRSA9Ci0gICAgICAgICAiRVJfUkVESVJFQ1RfQ09VTEROVF9HRVRfRklMRU5BTUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfQlVJTERfRk9STUFUVEVSTElTVEVORVJfSU5fUkVESVJFQ1QgPQotICAgICAgICAgIkVSX0NBTk5PVF9CVUlMRF9GT1JNQVRURVJMSVNURU5FUl9JTl9SRURJUkVDVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfUFJFRklYX0lOX0VYQ0xVREVSRVNVTFRQUkVGSVggPQotICAgICAgICAgIkVSX0lOVkFMSURfUFJFRklYX0lOX0VYQ0xVREVSRVNVTFRQUkVGSVgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9NSVNTSU5HX05TX1VSSSA9ICJFUl9NSVNTSU5HX05TX1VSSSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01JU1NJTkdfQVJHX0ZPUl9PUFRJT04gPQotICAgICAgICAgIkVSX01JU1NJTkdfQVJHX0ZPUl9PUFRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX09QVElPTiA9ICJFUl9JTlZBTElEX09QVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01BTEZPUk1FRF9GT1JNQVRfU1RSSU5HID0KLSAgICAgICAgICJFUl9NQUxGT1JNRURfRk9STUFUX1NUUklORyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NUWUxFU0hFRVRfUkVRVUlSRVNfVkVSU0lPTl9BVFRSSUIgPQotICAgICAgICAgIkVSX1NUWUxFU0hFRVRfUkVRVUlSRVNfVkVSU0lPTl9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTExFR0FMX0FUVFJJQlVURV9WQUxVRSA9Ci0gICAgICAgICAiRVJfSUxMRUdBTF9BVFRSSUJVVEVfVkFMVUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DSE9PU0VfUkVRVUlSRVNfV0hFTiA9IkVSX0NIT09TRV9SRVFVSVJFU19XSEVOIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fQVBQTFlfSU1QT1JUX0lOX0ZPUl9FQUNIID0KLSAgICAgICAgICJFUl9OT19BUFBMWV9JTVBPUlRfSU5fRk9SX0VBQ0giOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX1VTRV9EVE1fRk9SX09VVFBVVCA9Ci0gICAgICAgICAiRVJfQ0FOVF9VU0VfRFRNX0ZPUl9PVVRQVVQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX1VTRV9EVE1fRk9SX0lOUFVUID0KLSAgICAgICAgICJFUl9DQU5UX1VTRV9EVE1fRk9SX0lOUFVUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FMTF9UT19FWFRfRkFJTEVEID0gIkVSX0NBTExfVE9fRVhUX0ZBSUxFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BSRUZJWF9NVVNUX1JFU09MVkUgPSAiRVJfUFJFRklYX01VU1RfUkVTT0xWRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfVVRGMTZfU1VSUk9HQVRFID0KLSAgICAgICAgICJFUl9JTlZBTElEX1VURjE2X1NVUlJPR0FURSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hTTEFUVFJTRVRfVVNFRF9JVFNFTEYgPQotICAgICAgICAgIkVSX1hTTEFUVFJTRVRfVVNFRF9JVFNFTEYiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfTUlYX1hFUkNFU0RPTSA9IkVSX0NBTk5PVF9NSVhfWEVSQ0VTRE9NIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVE9PX01BTllfTElTVEVORVJTID0gIkVSX1RPT19NQU5ZX0xJU1RFTkVSUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOX0VMRU1URU1QTEFURUVMRU1fUkVBRE9CSkVDVCA9Ci0gICAgICAgICAiRVJfSU5fRUxFTVRFTVBMQVRFRUxFTV9SRUFET0JKRUNUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRFVQTElDQVRFX05BTUVEX1RFTVBMQVRFID0KLSAgICAgICAgICJFUl9EVVBMSUNBVEVfTkFNRURfVEVNUExBVEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX0tFWV9DQUxMID0gIkVSX0lOVkFMSURfS0VZX0NBTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SRUZFUkVOQ0lOR19JVFNFTEYgPSAiRVJfUkVGRVJFTkNJTkdfSVRTRUxGIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSUxMRUdBTF9ET01TT1VSQ0VfSU5QVVQgPQotICAgICAgICAgIkVSX0lMTEVHQUxfRE9NU09VUkNFX0lOUFVUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0xBU1NfTk9UX0ZPVU5EX0ZPUl9PUFRJT04gPQotICAgICAgICAgIkVSX0NMQVNTX05PVF9GT1VORF9GT1JfT1BUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUkVRVUlSRURfRUxFTV9OT1RfRk9VTkQgPQotICAgICAgICAgIkVSX1JFUVVJUkVEX0VMRU1fTk9UX0ZPVU5EIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5QVVRfQ0FOTk9UX0JFX05VTEwgPSJFUl9JTlBVVF9DQU5OT1RfQkVfTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1VSSV9DQU5OT1RfQkVfTlVMTCA9ICJFUl9VUklfQ0FOTk9UX0JFX05VTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GSUxFX0NBTk5PVF9CRV9OVUxMID0gIkVSX0ZJTEVfQ0FOTk9UX0JFX05VTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TT1VSQ0VfQ0FOTk9UX0JFX05VTEwgPQotICAgICAgICAgIkVSX1NPVVJDRV9DQU5OT1RfQkVfTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9JTklUX0JTRk1HUiA9ICJFUl9DQU5OT1RfSU5JVF9CU0ZNR1IiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfQ01QTF9FWFRFTlNOID0gIkVSX0NBTk5PVF9DTVBMX0VYVEVOU04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfQ1JFQVRFX0VYVEVOU04gPQotICAgICAgICAgIkVSX0NBTk5PVF9DUkVBVEVfRVhURU5TTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOU1RBTkNFX01USERfQ0FMTF9SRVFVSVJFUyA9Ci0gICAgICAgICAiRVJfSU5TVEFOQ0VfTVRIRF9DQUxMX1JFUVVJUkVTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9FTEVNRU5UX05BTUUgPSJFUl9JTlZBTElEX0VMRU1FTlRfTkFNRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VMRU1FTlRfTkFNRV9NRVRIT0RfU1RBVElDID0KLSAgICAgICAgICJFUl9FTEVNRU5UX05BTUVfTUVUSE9EX1NUQVRJQyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYVEVOU0lPTl9GVU5DX1VOS05PV04gPQotICAgICAgICAgIkVSX0VYVEVOU0lPTl9GVU5DX1VOS05PV04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9NT1JFX01BVENIX0NPTlNUUlVDVE9SID0KLSAgICAgICAgICJFUl9NT1JFX01BVENIX0NPTlNUUlVDVE9SIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTU9SRV9NQVRDSF9NRVRIT0QgPSAiRVJfTU9SRV9NQVRDSF9NRVRIT0QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9NT1JFX01BVENIX0VMRU1FTlQgPSAiRVJfTU9SRV9NQVRDSF9FTEVNRU5UIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9DT05URVhUX1BBU1NFRCA9Ci0gICAgICAgICAiRVJfSU5WQUxJRF9DT05URVhUX1BBU1NFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BPT0xfRVhJU1RTID0gIkVSX1BPT0xfRVhJU1RTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fRFJJVkVSX05BTUUgPSAiRVJfTk9fRFJJVkVSX05BTUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19VUkwgPSAiRVJfTk9fVVJMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUE9PTF9TSVpFX0xFU1NUSEFOX09ORSA9Ci0gICAgICAgICAiRVJfUE9PTF9TSVpFX0xFU1NUSEFOX09ORSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfRFJJVkVSID0gIkVSX0lOVkFMSURfRFJJVkVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fU1RZTEVTSEVFVFJPT1QgPSAiRVJfTk9fU1RZTEVTSEVFVFJPT1QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTExFR0FMX1hNTFNQQUNFX1ZBTFVFID0KLSAgICAgICAgICJFUl9JTExFR0FMX1hNTFNQQUNFX1ZBTFVFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJPQ0VTU0ZST01OT0RFX0ZBSUxFRCA9Ci0gICAgICAgICAiRVJfUFJPQ0VTU0ZST01OT0RFX0ZBSUxFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1JFU09VUkNFX0NPVUxEX05PVF9MT0FEID0KLSAgICAgICAgICJFUl9SRVNPVVJDRV9DT1VMRF9OT1RfTE9BRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0JVRkZFUl9TSVpFX0xFU1NUSEFOX1pFUk8gPQotICAgICAgICAgIkVSX0JVRkZFUl9TSVpFX0xFU1NUSEFOX1pFUk8iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTktOT1dOX0VSUk9SX0NBTExJTkdfRVhURU5TSU9OID0KLSAgICAgICAgICJFUl9VTktOT1dOX0VSUk9SX0NBTExJTkdfRVhURU5TSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fTkFNRVNQQUNFX0RFQ0wgPSAiRVJfTk9fTkFNRVNQQUNFX0RFQ0wiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FTEVNX0NPTlRFTlRfTk9UX0FMTE9XRUQgPQotICAgICAgICAgIkVSX0VMRU1fQ09OVEVOVF9OT1RfQUxMT1dFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NUWUxFU0hFRVRfRElSRUNURURfVEVSTUlOQVRJT04gPQotICAgICAgICAgIkVSX1NUWUxFU0hFRVRfRElSRUNURURfVEVSTUlOQVRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9PTkVfT1JfVFdPID0gIkVSX09ORV9PUl9UV08iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9UV09fT1JfVEhSRUUgPSAiRVJfVFdPX09SX1RIUkVFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTERfTk9UX0xPQURfUkVTT1VSQ0UgPQotICAgICAgICAgIkVSX0NPVUxEX05PVF9MT0FEX1JFU09VUkNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX0lOSVRfREVGQVVMVF9URU1QTEFURVMgPQotICAgICAgICAgIkVSX0NBTk5PVF9JTklUX0RFRkFVTFRfVEVNUExBVEVTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUkVTVUxUX05VTEwgPSAiRVJfUkVTVUxUX05VTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SRVNVTFRfQ09VTERfTk9UX0JFX1NFVCA9Ci0gICAgICAgICAiRVJfUkVTVUxUX0NPVUxEX05PVF9CRV9TRVQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19PVVRQVVRfU1BFQ0lGSUVEID0gIkVSX05PX09VVFBVVF9TUEVDSUZJRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfVFJBTlNGT1JNX1RPX1JFU1VMVF9UWVBFID0KLSAgICAgICAgICJFUl9DQU5OT1RfVFJBTlNGT1JNX1RPX1JFU1VMVF9UWVBFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX1RSQU5TRk9STV9TT1VSQ0VfVFlQRSA9Ci0gICAgICAgICAiRVJfQ0FOTk9UX1RSQU5TRk9STV9TT1VSQ0VfVFlQRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05VTExfQ09OVEVOVF9IQU5ETEVSID0iRVJfTlVMTF9DT05URU5UX0hBTkRMRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OVUxMX0VSUk9SX0hBTkRMRVIgPSAiRVJfTlVMTF9FUlJPUl9IQU5ETEVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX0NBTExfUEFSU0UgPSAiRVJfQ0FOTk9UX0NBTExfUEFSU0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19QQVJFTlRfRk9SX0ZJTFRFUiA9IkVSX05PX1BBUkVOVF9GT1JfRklMVEVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fU1RZTEVTSEVFVF9JTl9NRURJQSA9Ci0gICAgICAgICAiRVJfTk9fU1RZTEVTSEVFVF9JTl9NRURJQSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1NUWUxFU0hFRVRfUEkgPSAiRVJfTk9fU1RZTEVTSEVFVF9QSSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PVF9TVVBQT1JURUQgPSAiRVJfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BST1BFUlRZX1ZBTFVFX0JPT0xFQU4gPQotICAgICAgICAgIkVSX1BST1BFUlRZX1ZBTFVFX0JPT0xFQU4iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRF9OT1RfRklORF9FWFRFUk5fU0NSSVBUID0KLSAgICAgICAgICJFUl9DT1VMRF9OT1RfRklORF9FWFRFUk5fU0NSSVBUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUkVTT1VSQ0VfQ09VTERfTk9UX0ZJTkQgPQotICAgICAgICAgIkVSX1JFU09VUkNFX0NPVUxEX05PVF9GSU5EIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfT1VUUFVUX1BST1BFUlRZX05PVF9SRUNPR05JWkVEID0KLSAgICAgICAgICJFUl9PVVRQVVRfUFJPUEVSVFlfTk9UX1JFQ09HTklaRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GQUlMRURfQ1JFQVRJTkdfRUxFTUxJVFJTTFQgPQotICAgICAgICAgIkVSX0ZBSUxFRF9DUkVBVElOR19FTEVNTElUUlNMVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1ZBTFVFX1NIT1VMRF9CRV9OVU1CRVIgPQotICAgICAgICAgIkVSX1ZBTFVFX1NIT1VMRF9CRV9OVU1CRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9WQUxVRV9TSE9VTERfRVFVQUwgPSAiRVJfVkFMVUVfU0hPVUxEX0VRVUFMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRkFJTEVEX0NBTExJTkdfTUVUSE9EID0KLSAgICAgICAgICJFUl9GQUlMRURfQ0FMTElOR19NRVRIT0QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GQUlMRURfQ1JFQVRJTkdfRUxFTVRNUEwgPQotICAgICAgICAgIkVSX0ZBSUxFRF9DUkVBVElOR19FTEVNVE1QTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NIQVJTX05PVF9BTExPV0VEID0gIkVSX0NIQVJTX05PVF9BTExPV0VEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQVRUUl9OT1RfQUxMT1dFRCA9ICJFUl9BVFRSX05PVF9BTExPV0VEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQkFEX1ZBTFVFID0gIkVSX0JBRF9WQUxVRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FUVFJJQl9WQUxVRV9OT1RfRk9VTkQgPQotICAgICAgICAgIkVSX0FUVFJJQl9WQUxVRV9OT1RfRk9VTkQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9BVFRSSUJfVkFMVUVfTk9UX1JFQ09HTklaRUQgPQotICAgICAgICAgIkVSX0FUVFJJQl9WQUxVRV9OT1RfUkVDT0dOSVpFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05VTExfVVJJX05BTUVTUEFDRSA9ICJFUl9OVUxMX1VSSV9OQU1FU1BBQ0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OVU1CRVJfVE9PX0JJRyA9ICJFUl9OVU1CRVJfVE9PX0JJRyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nICBFUl9DQU5OT1RfRklORF9TQVgxX0RSSVZFUiA9Ci0gICAgICAgICAiRVJfQ0FOTk9UX0ZJTkRfU0FYMV9EUklWRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyAgRVJfU0FYMV9EUklWRVJfTk9UX0xPQURFRCA9Ci0gICAgICAgICAiRVJfU0FYMV9EUklWRVJfTk9UX0xPQURFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nICBFUl9TQVgxX0RSSVZFUl9OT1RfSU5TVEFOVElBVEVEID0KLSAgICAgICAgICJFUl9TQVgxX0RSSVZFUl9OT1RfSU5TVEFOVElBVEVEIiA7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NBWDFfRFJJVkVSX05PVF9JTVBMRU1FTlRfUEFSU0VSID0KLSAgICAgICAgICJFUl9TQVgxX0RSSVZFUl9OT1RfSU1QTEVNRU5UX1BBUlNFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nICBFUl9QQVJTRVJfUFJPUEVSVFlfTk9UX1NQRUNJRklFRCA9Ci0gICAgICAgICAiRVJfUEFSU0VSX1BST1BFUlRZX05PVF9TUEVDSUZJRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyAgRVJfUEFSU0VSX0FSR19DQU5OT1RfQkVfTlVMTCA9Ci0gICAgICAgICAiRVJfUEFSU0VSX0FSR19DQU5OT1RfQkVfTlVMTCIgOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyAgRVJfRkVBVFVSRSA9ICJFUl9GRUFUVVJFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJPUEVSVFkgPSAiRVJfUFJPUEVSVFkiIDsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTlVMTF9FTlRJVFlfUkVTT0xWRVIgPSJFUl9OVUxMX0VOVElUWV9SRVNPTFZFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nICBFUl9OVUxMX0RURF9IQU5ETEVSID0gIkVSX05VTExfRFREX0hBTkRMRVIiIDsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fRFJJVkVSX05BTUVfU1BFQ0lGSUVEID0KLSAgICAgICAgICJFUl9OT19EUklWRVJfTkFNRV9TUEVDSUZJRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19VUkxfU1BFQ0lGSUVEID0gIkVSX05PX1VSTF9TUEVDSUZJRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QT09MU0laRV9MRVNTX1RIQU5fT05FID0KLSAgICAgICAgICJFUl9QT09MU0laRV9MRVNTX1RIQU5fT05FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9EUklWRVJfTkFNRSA9ICJFUl9JTlZBTElEX0RSSVZFUl9OQU1FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVJST1JMSVNURU5FUiA9ICJFUl9FUlJPUkxJU1RFTkVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQVNTRVJUX05PX1RFTVBMQVRFX1BBUkVOVCA9Ci0gICAgICAgICAiRVJfQVNTRVJUX05PX1RFTVBMQVRFX1BBUkVOVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FTU0VSVF9SRURVTkRFTlRfRVhQUl9FTElNSU5BVE9SID0KLSAgICAgICAgICJFUl9BU1NFUlRfUkVEVU5ERU5UX0VYUFJfRUxJTUlOQVRPUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PVF9BTExPV0VEX0lOX1BPU0lUSU9OID0KLSAgICAgICAgICJFUl9OT1RfQUxMT1dFRF9JTl9QT1NJVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PTldISVRFU1BBQ0VfTk9UX0FMTE9XRURfSU5fUE9TSVRJT04gPQotICAgICAgICAgIkVSX05PTldISVRFU1BBQ0VfTk9UX0FMTE9XRURfSU5fUE9TSVRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OQU1FU1BBQ0VfQ09OVEVYVF9OVUxMX05BTUVTUEFDRSA9Ci0gICAgICAgICAiRVJfTkFNRVNQQUNFX0NPTlRFWFRfTlVMTF9OQU1FU1BBQ0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OQU1FU1BBQ0VfQ09OVEVYVF9OVUxMX1BSRUZJWCA9Ci0gICAgICAgICAiRVJfTkFNRVNQQUNFX0NPTlRFWFRfTlVMTF9QUkVGSVgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YUEFUSF9SRVNPTFZFUl9OVUxMX1FOQU1FID0KLSAgICAgICAgICJFUl9YUEFUSF9SRVNPTFZFUl9OVUxMX1FOQU1FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWFBBVEhfUkVTT0xWRVJfTkVHQVRJVkVfQVJJVFkgPQotICAgICAgICAgIkVSX1hQQVRIX1JFU09MVkVSX05FR0FUSVZFX0FSSVRZIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSU5WQUxJRF9UQ0hBUiA9ICJJTlZBTElEX1RDSEFSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSU5WQUxJRF9RTkFNRSA9ICJJTlZBTElEX1FOQU1FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSU5WQUxJRF9FTlVNID0gIklOVkFMSURfRU5VTSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIElOVkFMSURfTk1UT0tFTiA9ICJJTlZBTElEX05NVE9LRU4iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBJTlZBTElEX05DTkFNRSA9ICJJTlZBTElEX05DTkFNRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIElOVkFMSURfQk9PTEVBTiA9ICJJTlZBTElEX0JPT0xFQU4iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBJTlZBTElEX05VTUJFUiA9ICJJTlZBTElEX05VTUJFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FSR19MSVRFUkFMID0gIkVSX0FSR19MSVRFUkFMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRFVQTElDQVRFX0dMT0JBTF9WQVIgPSJFUl9EVVBMSUNBVEVfR0xPQkFMX1ZBUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0RVUExJQ0FURV9WQVIgPSAiRVJfRFVQTElDQVRFX1ZBUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1RFTVBMQVRFX05BTUVfTUFUQ0ggPSAiRVJfVEVNUExBVEVfTkFNRV9NQVRDSCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfUFJFRklYID0gIkVSX0lOVkFMSURfUFJFRklYIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fQVRUUklCX1NFVCA9ICJFUl9OT19BVFRSSUJfU0VUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRlVOQ1RJT05fTk9UX0ZPVU5EID0KLSAgICAgICAgICJFUl9GVU5DVElPTl9OT1RfRk9VTkQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX0hBVkVfQ09OVEVOVF9BTkRfU0VMRUNUID0KLSAgICAgIkVSX0NBTlRfSEFWRV9DT05URU5UX0FORF9TRUxFQ1QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX1NFVF9QQVJBTV9WQUxVRSA9ICJFUl9JTlZBTElEX1NFVF9QQVJBTV9WQUxVRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NFVF9GRUFUVVJFX05VTExfTkFNRSA9Ci0gICAgICAgICJFUl9TRVRfRkVBVFVSRV9OVUxMX05BTUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9HRVRfRkVBVFVSRV9OVUxMX05BTUUgPQotICAgICAgICAiRVJfR0VUX0ZFQVRVUkVfTlVMTF9OQU1FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5TVVBQT1JURURfRkVBVFVSRSA9Ci0gICAgICAgICJFUl9VTlNVUFBPUlRFRF9GRUFUVVJFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhURU5TSU9OX0VMRU1FTlRfTk9UX0FMTE9XRURfSU5fU0VDVVJFX1BST0NFU1NJTkcgPQotICAgICAgICAiRVJfRVhURU5TSU9OX0VMRU1FTlRfTk9UX0FMTE9XRURfSU5fU0VDVVJFX1BST0NFU1NJTkciOwotCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0ZPVU5EX0NVUkxZQlJBQ0UgPSAiV0dfRk9VTkRfQ1VSTFlCUkFDRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0NPVU5UX0FUVFJJQl9NQVRDSEVTX05PX0FOQ0VTVE9SID0KLSAgICAgICAgICJXR19DT1VOVF9BVFRSSUJfTUFUQ0hFU19OT19BTkNFU1RPUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0VYUFJfQVRUUklCX0NIQU5HRURfVE9fU0VMRUNUID0KLSAgICAgICAgICJXR19FWFBSX0FUVFJJQl9DSEFOR0VEX1RPX1NFTEVDVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX05PX0xPQ0FMRV9JTl9GT1JNQVROVU1CRVIgPQotICAgICAgICAgIldHX05PX0xPQ0FMRV9JTl9GT1JNQVROVU1CRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19MT0NBTEVfTk9UX0ZPVU5EID0gIldHX0xPQ0FMRV9OT1RfRk9VTkQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19DQU5OT1RfTUFLRV9VUkxfRlJPTSA9IldHX0NBTk5PVF9NQUtFX1VSTF9GUk9NIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfQ0FOTk9UX0xPQURfUkVRVUVTVEVEX0RPQyA9Ci0gICAgICAgICAiV0dfQ0FOTk9UX0xPQURfUkVRVUVTVEVEX0RPQyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0NBTk5PVF9GSU5EX0NPTExBVE9SID0iV0dfQ0FOTk9UX0ZJTkRfQ09MTEFUT1IiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19GVU5DVElPTlNfU0hPVUxEX1VTRV9VUkwgPQotICAgICAgICAgIldHX0ZVTkNUSU9OU19TSE9VTERfVVNFX1VSTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0VOQ09ESU5HX05PVF9TVVBQT1JURURfVVNJTkdfVVRGOCA9Ci0gICAgICAgICAiV0dfRU5DT0RJTkdfTk9UX1NVUFBPUlRFRF9VU0lOR19VVEY4IjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfRU5DT0RJTkdfTk9UX1NVUFBPUlRFRF9VU0lOR19KQVZBID0KLSAgICAgICAgICJXR19FTkNPRElOR19OT1RfU1VQUE9SVEVEX1VTSU5HX0pBVkEiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19TUEVDSUZJQ0lUWV9DT05GTElDVFMgPQotICAgICAgICAgIldHX1NQRUNJRklDSVRZX0NPTkZMSUNUUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX1BBUlNJTkdfQU5EX1BSRVBBUklORyA9Ci0gICAgICAgICAiV0dfUEFSU0lOR19BTkRfUFJFUEFSSU5HIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfQVRUUl9URU1QTEFURSA9ICJXR19BVFRSX1RFTVBMQVRFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfQ09ORkxJQ1RfQkVUV0VFTl9YU0xTVFJJUFNQQUNFX0FORF9YU0xQUkVTRVJWRVNQQUNFID0gIldHX0NPTkZMSUNUX0JFVFdFRU5fWFNMU1RSSVBTUEFDRV9BTkRfWFNMUFJFU0VSVkVTUCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0FUVFJJQl9OT1RfSEFORExFRCA9ICJXR19BVFRSSUJfTk9UX0hBTkRMRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19OT19ERUNJTUFMRk9STUFUX0RFQ0xBUkFUSU9OID0KLSAgICAgICAgICJXR19OT19ERUNJTUFMRk9STUFUX0RFQ0xBUkFUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfT0xEX1hTTFRfTlMgPSAiV0dfT0xEX1hTTFRfTlMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19PTkVfREVGQVVMVF9YU0xERUNJTUFMRk9STUFUX0FMTE9XRUQgPQotICAgICAgICAgIldHX09ORV9ERUZBVUxUX1hTTERFQ0lNQUxGT1JNQVRfQUxMT1dFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX1hTTERFQ0lNQUxGT1JNQVRfTkFNRVNfTVVTVF9CRV9VTklRVUUgPQotICAgICAgICAgIldHX1hTTERFQ0lNQUxGT1JNQVRfTkFNRVNfTVVTVF9CRV9VTklRVUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19JTExFR0FMX0FUVFJJQlVURSA9ICJXR19JTExFR0FMX0FUVFJJQlVURSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0NPVUxEX05PVF9SRVNPTFZFX1BSRUZJWCA9Ci0gICAgICAgICAiV0dfQ09VTERfTk9UX1JFU09MVkVfUFJFRklYIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfU1RZTEVTSEVFVF9SRVFVSVJFU19WRVJTSU9OX0FUVFJJQiA9Ci0gICAgICAgICAiV0dfU1RZTEVTSEVFVF9SRVFVSVJFU19WRVJTSU9OX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0lMTEVHQUxfQVRUUklCVVRFX05BTUUgPQotICAgICAgICAgIldHX0lMTEVHQUxfQVRUUklCVVRFX05BTUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19JTExFR0FMX0FUVFJJQlVURV9WQUxVRSA9Ci0gICAgICAgICAiV0dfSUxMRUdBTF9BVFRSSUJVVEVfVkFMVUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19FTVBUWV9TRUNPTkRfQVJHID0gIldHX0VNUFRZX1NFQ09ORF9BUkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19QUk9DRVNTSU5HSU5TVFJVQ1RJT05fTkFNRV9DQU5UX0JFX1hNTCA9Ci0gICAgICAgICAiV0dfUFJPQ0VTU0lOR0lOU1RSVUNUSU9OX05BTUVfQ0FOVF9CRV9YTUwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19QUk9DRVNTSU5HSU5TVFJVQ1RJT05fTk9UVkFMSURfTkNOQU1FID0KLSAgICAgICAgICJXR19QUk9DRVNTSU5HSU5TVFJVQ1RJT05fTk9UVkFMSURfTkNOQU1FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfSUxMRUdBTF9BVFRSSUJVVEVfUE9TSVRJT04gPQotICAgICAgICAgIldHX0lMTEVHQUxfQVRUUklCVVRFX1BPU0lUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSID0KLSAgICAgICAgICJOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIiOwotCi0gIC8qCi0gICAqIE5vdyBmaWxsIGluIHRoZSBtZXNzYWdlIHRleHQuCi0gICAqIFRoZW4gZmlsbCBpbiB0aGUgbWVzc2FnZSB0ZXh0IGZvciB0aGF0IG1lc3NhZ2UgY29kZSBpbiB0aGUKLSAgICogYXJyYXkuIFVzZSB0aGUgbmV3IGVycm9yIGNvZGUgYXMgdGhlIGluZGV4IGludG8gdGhlIGFycmF5LgotICAgKi8KLQotICAvLyBFcnJvciBtZXNzYWdlcy4uLgotCi0gIC8qKiBHZXQgdGhlIGxvb2t1cCB0YWJsZSBmb3IgZXJyb3IgbWVzc2FnZXMuCi0gICAgKgotICAgICogQHJldHVybiBUaGUgbWVzc2FnZSBsb29rdXAgdGFibGUuCi0gICAgKi8KLSAgcHVibGljIE9iamVjdFtdW10gZ2V0Q29udGVudHMoKQotICB7Ci0gICAgICByZXR1cm4gbmV3IE9iamVjdFtdW10gewotCi0gIC8qKiBFcnJvciBtZXNzYWdlIElEIHRoYXQgaGFzIGEgbnVsbCBtZXNzYWdlLCBidXQgdGFrZXMgaW4gYSBzaW5nbGUgb2JqZWN0LiAgICAqLwotICB7IkVSMDAwMCIgLCAiezB9IiB9LAotCi0gICAgeyBFUl9OT19DVVJMWUJSQUNFLAotICAgICAgIkVycm9yOiBDYW4gbm90IGhhdmUgJ3snIHdpdGhpbiBleHByZXNzaW9uIn0sCi0KLSAgICB7IEVSX0lMTEVHQUxfQVRUUklCVVRFICwKLSAgICAgInswfSBoYXMgYW4gaWxsZWdhbCBhdHRyaWJ1dGU6IHsxfSJ9LAotCi0gIHtFUl9OVUxMX1NPVVJDRU5PREVfQVBQTFlJTVBPUlRTICwKLSAgICAgICJzb3VyY2VOb2RlIGlzIG51bGwgaW4geHNsOmFwcGx5LWltcG9ydHMhIn0sCi0KLSAge0VSX0NBTk5PVF9BREQsCi0gICAgICAiQ2FuIG5vdCBhZGQgezB9IHRvIHsxfSJ9LAotCi0gICAgeyBFUl9OVUxMX1NPVVJDRU5PREVfSEFORExFQVBQTFlURU1QTEFURVMsCi0gICAgICAic291cmNlTm9kZSBpcyBudWxsIGluIGhhbmRsZUFwcGx5VGVtcGxhdGVzSW5zdHJ1Y3Rpb24hIn0sCi0KLSAgICB7IEVSX05PX05BTUVfQVRUUklCLAotICAgICAiezB9IG11c3QgaGF2ZSBhIG5hbWUgYXR0cmlidXRlLiJ9LAotCi0gICAge0VSX1RFTVBMQVRFX05PVF9GT1VORCwKLSAgICAgIkNvdWxkIG5vdCBmaW5kIHRlbXBsYXRlIG5hbWVkOiB7MH0ifSwKLQotICAgIHtFUl9DQU5UX1JFU09MVkVfTkFNRV9BVlQsCi0gICAgICAiQ291bGQgbm90IHJlc29sdmUgbmFtZSBBVlQgaW4geHNsOmNhbGwtdGVtcGxhdGUuIn0sCi0KLSAgICB7RVJfUkVRVUlSRVNfQVRUUklCLAotICAgICAiezB9IHJlcXVpcmVzIGF0dHJpYnV0ZTogezF9In0sCi0KLSAgICB7IEVSX01VU1RfSEFWRV9URVNUX0FUVFJJQiwKLSAgICAgICJ7MH0gbXVzdCBoYXZlIGEgJyd0ZXN0JycgYXR0cmlidXRlLiJ9LAotCi0gICAge0VSX0JBRF9WQUxfT05fTEVWRUxfQVRUUklCLAotICAgICAgIkJhZCB2YWx1ZSBvbiBsZXZlbCBhdHRyaWJ1dGU6IHswfSJ9LAotCi0gICAge0VSX1BST0NFU1NJTkdJTlNUUlVDVElPTl9OQU1FX0NBTlRfQkVfWE1MLAotICAgICAgInByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24gbmFtZSBjYW4gbm90IGJlICd4bWwnIn0sCi0KLSAgICB7IEVSX1BST0NFU1NJTkdJTlNUUlVDVElPTl9OT1RWQUxJRF9OQ05BTUUsCi0gICAgICAicHJvY2Vzc2luZy1pbnN0cnVjdGlvbiBuYW1lIG11c3QgYmUgYSB2YWxpZCBOQ05hbWU6IHswfSJ9LAotCi0gICAgeyBFUl9ORUVEX01BVENIX0FUVFJJQiwKLSAgICAgICJ7MH0gbXVzdCBoYXZlIGEgbWF0Y2ggYXR0cmlidXRlIGlmIGl0IGhhcyBhIG1vZGUuIn0sCi0KLSAgICB7IEVSX05FRURfTkFNRV9PUl9NQVRDSF9BVFRSSUIsCi0gICAgICAiezB9IHJlcXVpcmVzIGVpdGhlciBhIG5hbWUgb3IgYSBtYXRjaCBhdHRyaWJ1dGUuIn0sCi0KLSAgICB7RVJfQ0FOVF9SRVNPTFZFX05TUFJFRklYLAotICAgICAgIkNhbiBub3QgcmVzb2x2ZSBuYW1lc3BhY2UgcHJlZml4OiB7MH0ifSwKLQotICAgIHsgRVJfSUxMRUdBTF9WQUxVRSwKLSAgICAgInhtbDpzcGFjZSBoYXMgYW4gaWxsZWdhbCB2YWx1ZTogezB9In0sCi0KLSAgICB7IEVSX05PX09XTkVSRE9DLAotICAgICAgIkNoaWxkIG5vZGUgZG9lcyBub3QgaGF2ZSBhbiBvd25lciBkb2N1bWVudCEifSwKLQotICAgIHsgRVJfRUxFTVRFTVBMQVRFRUxFTV9FUlIsCi0gICAgICJFbGVtVGVtcGxhdGVFbGVtZW50IGVycm9yOiB7MH0ifSwKLQotICAgIHsgRVJfTlVMTF9DSElMRCwKLSAgICAgIlRyeWluZyB0byBhZGQgYSBudWxsIGNoaWxkISJ9LAotCi0gICAgeyBFUl9ORUVEX1NFTEVDVF9BVFRSSUIsCi0gICAgICJ7MH0gcmVxdWlyZXMgYSBzZWxlY3QgYXR0cmlidXRlLiJ9LAotCi0gICAgeyBFUl9ORUVEX1RFU1RfQVRUUklCICwKLSAgICAgICJ4c2w6d2hlbiBtdXN0IGhhdmUgYSAndGVzdCcgYXR0cmlidXRlLiJ9LAotCi0gICAgeyBFUl9ORUVEX05BTUVfQVRUUklCLAotICAgICAgInhzbDp3aXRoLXBhcmFtIG11c3QgaGF2ZSBhICduYW1lJyBhdHRyaWJ1dGUuIn0sCi0KLSAgICB7IEVSX05PX0NPTlRFWFRfT1dORVJET0MsCi0gICAgICAiY29udGV4dCBkb2VzIG5vdCBoYXZlIGFuIG93bmVyIGRvY3VtZW50ISJ9LAotCi0gICAge0VSX0NPVUxEX05PVF9DUkVBVEVfWE1MX1BST0NfTElBSVNPTiwKLSAgICAgICJDb3VsZCBub3QgY3JlYXRlIFhNTCBUcmFuc2Zvcm1lckZhY3RvcnkgTGlhaXNvbjogezB9In0sCi0KLSAgICB7RVJfUFJPQ0VTU19OT1RfU1VDQ0VTU0ZVTCwKLSAgICAgICJYYWxhbjogUHJvY2VzcyB3YXMgbm90IHN1Y2Nlc3NmdWwuIn0sCi0KLSAgICB7IEVSX05PVF9TVUNDRVNTRlVMLAotICAgICAiWGFsYW46IHdhcyBub3Qgc3VjY2Vzc2Z1bC4ifSwKLQotICAgIHsgRVJfRU5DT0RJTkdfTk9UX1NVUFBPUlRFRCwKLSAgICAgIkVuY29kaW5nIG5vdCBzdXBwb3J0ZWQ6IHswfSJ9LAotCi0gICAge0VSX0NPVUxEX05PVF9DUkVBVEVfVFJBQ0VMSVNURU5FUiwKLSAgICAgICJDb3VsZCBub3QgY3JlYXRlIFRyYWNlTGlzdGVuZXI6IHswfSJ9LAotCi0gICAge0VSX0tFWV9SRVFVSVJFU19OQU1FX0FUVFJJQiwKLSAgICAgICJ4c2w6a2V5IHJlcXVpcmVzIGEgJ25hbWUnIGF0dHJpYnV0ZSEifSwKLQotICAgIHsgRVJfS0VZX1JFUVVJUkVTX01BVENIX0FUVFJJQiwKLSAgICAgICJ4c2w6a2V5IHJlcXVpcmVzIGEgJ21hdGNoJyBhdHRyaWJ1dGUhIn0sCi0KLSAgICB7IEVSX0tFWV9SRVFVSVJFU19VU0VfQVRUUklCLAotICAgICAgInhzbDprZXkgcmVxdWlyZXMgYSAndXNlJyBhdHRyaWJ1dGUhIn0sCi0KLSAgICB7IEVSX1JFUVVJUkVTX0VMRU1FTlRTX0FUVFJJQiwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIHswfSByZXF1aXJlcyBhbiAnJ2VsZW1lbnRzJycgYXR0cmlidXRlISJ9LAotCi0gICAgeyBFUl9NSVNTSU5HX1BSRUZJWF9BVFRSSUIsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSB7MH0gYXR0cmlidXRlICcncHJlZml4JycgaXMgbWlzc2luZyJ9LAotCi0gICAgeyBFUl9CQURfU1RZTEVTSEVFVF9VUkwsCi0gICAgICJTdHlsZXNoZWV0IFVSTCBpcyBiYWQ6IHswfSJ9LAotCi0gICAgeyBFUl9GSUxFX05PVF9GT1VORCwKLSAgICAgIlN0eWxlc2hlZXQgZmlsZSB3YXMgbm90IGZvdW5kOiB7MH0ifSwKLQotICAgIHsgRVJfSU9FWENFUFRJT04sCi0gICAgICAiSGFkIElPIEV4Y2VwdGlvbiB3aXRoIHN0eWxlc2hlZXQgZmlsZTogezB9In0sCi0KLSAgICB7IEVSX05PX0hSRUZfQVRUUklCLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgQ291bGQgbm90IGZpbmQgaHJlZiBhdHRyaWJ1dGUgZm9yIHswfSJ9LAotCi0gICAgeyBFUl9TVFlMRVNIRUVUX0lOQ0xVREVTX0lUU0VMRiwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIHswfSBpcyBkaXJlY3RseSBvciBpbmRpcmVjdGx5IGluY2x1ZGluZyBpdHNlbGYhIn0sCi0KLSAgICB7IEVSX1BST0NFU1NJTkNMVURFX0VSUk9SLAotICAgICAgIlN0eWxlc2hlZXRIYW5kbGVyLnByb2Nlc3NJbmNsdWRlIGVycm9yLCB7MH0ifSwKLQotICAgIHsgRVJfTUlTU0lOR19MQU5HX0FUVFJJQiwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIHswfSBhdHRyaWJ1dGUgJydsYW5nJycgaXMgbWlzc2luZyJ9LAotCi0gICAgeyBFUl9NSVNTSU5HX0NPTlRBSU5FUl9FTEVNRU5UX0NPTVBPTkVOVCwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIG1pc3BsYWNlZCB7MH0gZWxlbWVudD8/IE1pc3NpbmcgY29udGFpbmVyIGVsZW1lbnQgJydjb21wb25lbnQnJyJ9LAotCi0gICAgeyBFUl9DQU5fT05MWV9PVVRQVVRfVE9fRUxFTUVOVCwKLSAgICAgICJDYW4gb25seSBvdXRwdXQgdG8gYW4gRWxlbWVudCwgRG9jdW1lbnRGcmFnbWVudCwgRG9jdW1lbnQsIG9yIFByaW50V3JpdGVyLiJ9LAotCi0gICAgeyBFUl9QUk9DRVNTX0VSUk9SLAotICAgICAiU3R5bGVzaGVldFJvb3QucHJvY2VzcyBlcnJvciJ9LAotCi0gICAgeyBFUl9VTklNUExOT0RFX0VSUk9SLAotICAgICAiVW5JbXBsTm9kZSBlcnJvcjogezB9In0sCi0KLSAgICB7IEVSX05PX1NFTEVDVF9FWFBSRVNTSU9OLAotICAgICAgIkVycm9yISBEaWQgbm90IGZpbmQgeHBhdGggc2VsZWN0IGV4cHJlc3Npb24gKC1zZWxlY3QpLiJ9LAotCi0gICAgeyBFUl9DQU5OT1RfU0VSSUFMSVpFX1hTTFBST0NFU1NPUiwKLSAgICAgICJDYW4gbm90IHNlcmlhbGl6ZSBhbiBYU0xQcm9jZXNzb3IhIn0sCi0KLSAgICB7IEVSX05PX0lOUFVUX1NUWUxFU0hFRVQsCi0gICAgICAiU3R5bGVzaGVldCBpbnB1dCB3YXMgbm90IHNwZWNpZmllZCEifSwKLQotICAgIHsgRVJfRkFJTEVEX1BST0NFU1NfU1RZTEVTSEVFVCwKLSAgICAgICJGYWlsZWQgdG8gcHJvY2VzcyBzdHlsZXNoZWV0ISJ9LAotCi0gICAgeyBFUl9DT1VMRE5UX1BBUlNFX0RPQywKLSAgICAgIkNvdWxkIG5vdCBwYXJzZSB7MH0gZG9jdW1lbnQhIn0sCi0KLSAgICB7IEVSX0NPVUxETlRfRklORF9GUkFHTUVOVCwKLSAgICAgIkNvdWxkIG5vdCBmaW5kIGZyYWdtZW50OiB7MH0ifSwKLQotICAgIHsgRVJfTk9ERV9OT1RfRUxFTUVOVCwKLSAgICAgICJOb2RlIHBvaW50ZWQgdG8gYnkgZnJhZ21lbnQgaWRlbnRpZmllciB3YXMgbm90IGFuIGVsZW1lbnQ6IHswfSJ9LAotCi0gICAgeyBFUl9GT1JFQUNIX05FRURfTUFUQ0hfT1JfTkFNRV9BVFRSSUIsCi0gICAgICAiZm9yLWVhY2ggbXVzdCBoYXZlIGVpdGhlciBhIG1hdGNoIG9yIG5hbWUgYXR0cmlidXRlIn0sCi0KLSAgICB7IEVSX1RFTVBMQVRFU19ORUVEX01BVENIX09SX05BTUVfQVRUUklCLAotICAgICAgInRlbXBsYXRlcyBtdXN0IGhhdmUgZWl0aGVyIGEgbWF0Y2ggb3IgbmFtZSBhdHRyaWJ1dGUifSwKLQotICAgIHsgRVJfTk9fQ0xPTkVfT0ZfRE9DVU1FTlRfRlJBRywKLSAgICAgICJObyBjbG9uZSBvZiBhIGRvY3VtZW50IGZyYWdtZW50ISJ9LAotCi0gICAgeyBFUl9DQU5UX0NSRUFURV9JVEVNLAotICAgICAgIkNhbiBub3QgY3JlYXRlIGl0ZW0gaW4gcmVzdWx0IHRyZWU6IHswfSJ9LAotCi0gICAgeyBFUl9YTUxTUEFDRV9JTExFR0FMX1ZBTFVFLAotICAgICAgInhtbDpzcGFjZSBpbiB0aGUgc291cmNlIFhNTCBoYXMgYW4gaWxsZWdhbCB2YWx1ZTogezB9In0sCi0KLSAgICB7IEVSX05PX1hTTEtFWV9ERUNMQVJBVElPTiwKLSAgICAgICJUaGVyZSBpcyBubyB4c2w6a2V5IGRlY2xhcmF0aW9uIGZvciB7MH0hIn0sCi0KLSAgICB7IEVSX0NBTlRfQ1JFQVRFX1VSTCwKLSAgICAgIkVycm9yISBDYW5ub3QgY3JlYXRlIHVybCBmb3I6IHswfSJ9LAotCi0gICAgeyBFUl9YU0xGVU5DVElPTlNfVU5TVVBQT1JURUQsCi0gICAgICJ4c2w6ZnVuY3Rpb25zIGlzIHVuc3VwcG9ydGVkIn0sCi0KLSAgICB7IEVSX1BST0NFU1NPUl9FUlJPUiwKLSAgICAgIlhTTFQgVHJhbnNmb3JtZXJGYWN0b3J5IEVycm9yIn0sCi0KLSAgICB7IEVSX05PVF9BTExPV0VEX0lOU0lERV9TVFlMRVNIRUVULAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgezB9IG5vdCBhbGxvd2VkIGluc2lkZSBhIHN0eWxlc2hlZXQhIn0sCi0KLSAgICB7IEVSX1JFU1VMVE5TX05PVF9TVVBQT1JURUQsCi0gICAgICAicmVzdWx0LW5zIG5vIGxvbmdlciBzdXBwb3J0ZWQhICBVc2UgeHNsOm91dHB1dCBpbnN0ZWFkLiJ9LAotCi0gICAgeyBFUl9ERUZBVUxUU1BBQ0VfTk9UX1NVUFBPUlRFRCwKLSAgICAgICJkZWZhdWx0LXNwYWNlIG5vIGxvbmdlciBzdXBwb3J0ZWQhICBVc2UgeHNsOnN0cmlwLXNwYWNlIG9yIHhzbDpwcmVzZXJ2ZS1zcGFjZSBpbnN0ZWFkLiJ9LAotCi0gICAgeyBFUl9JTkRFTlRSRVNVTFRfTk9UX1NVUFBPUlRFRCwKLSAgICAgICJpbmRlbnQtcmVzdWx0IG5vIGxvbmdlciBzdXBwb3J0ZWQhICBVc2UgeHNsOm91dHB1dCBpbnN0ZWFkLiJ9LAotCi0gICAgeyBFUl9JTExFR0FMX0FUVFJJQiwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIHswfSBoYXMgYW4gaWxsZWdhbCBhdHRyaWJ1dGU6IHsxfSJ9LAotCi0gICAgeyBFUl9VTktOT1dOX1hTTF9FTEVNLAotICAgICAiVW5rbm93biBYU0wgZWxlbWVudDogezB9In0sCi0KLSAgICB7IEVSX0JBRF9YU0xTT1JUX1VTRSwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIHhzbDpzb3J0IGNhbiBvbmx5IGJlIHVzZWQgd2l0aCB4c2w6YXBwbHktdGVtcGxhdGVzIG9yIHhzbDpmb3ItZWFjaC4ifSwKLQotICAgIHsgRVJfTUlTUExBQ0VEX1hTTFdIRU4sCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSBtaXNwbGFjZWQgeHNsOndoZW4hIn0sCi0KLSAgICB7IEVSX1hTTFdIRU5fTk9UX1BBUkVOVEVEX0JZX1hTTENIT09TRSwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIHhzbDp3aGVuIG5vdCBwYXJlbnRlZCBieSB4c2w6Y2hvb3NlISJ9LAotCi0gICAgeyBFUl9NSVNQTEFDRURfWFNMT1RIRVJXSVNFLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgbWlzcGxhY2VkIHhzbDpvdGhlcndpc2UhIn0sCi0KLSAgICB7IEVSX1hTTE9USEVSV0lTRV9OT1RfUEFSRU5URURfQllfWFNMQ0hPT1NFLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgeHNsOm90aGVyd2lzZSBub3QgcGFyZW50ZWQgYnkgeHNsOmNob29zZSEifSwKLQotICAgIHsgRVJfTk9UX0FMTE9XRURfSU5TSURFX1RFTVBMQVRFLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgezB9IGlzIG5vdCBhbGxvd2VkIGluc2lkZSBhIHRlbXBsYXRlISJ9LAotCi0gICAgeyBFUl9VTktOT1dOX0VYVF9OU19QUkVGSVgsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSB7MH0gZXh0ZW5zaW9uIG5hbWVzcGFjZSBwcmVmaXggezF9IHVua25vd24ifSwKLQotICAgIHsgRVJfSU1QT1JUU19BU19GSVJTVF9FTEVNLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgSW1wb3J0cyBjYW4gb25seSBvY2N1ciBhcyB0aGUgZmlyc3QgZWxlbWVudHMgaW4gdGhlIHN0eWxlc2hlZXQhIn0sCi0KLSAgICB7IEVSX0lNUE9SVElOR19JVFNFTEYsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSB7MH0gaXMgZGlyZWN0bHkgb3IgaW5kaXJlY3RseSBpbXBvcnRpbmcgaXRzZWxmISJ9LAotCi0gICAgeyBFUl9YTUxTUEFDRV9JTExFR0FMX1ZBTCwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpICIgKyAieG1sOnNwYWNlIGhhcyBhbiBpbGxlZ2FsIHZhbHVlOiB7MH0ifSwKLQotICAgIHsgRVJfUFJPQ0VTU1NUWUxFU0hFRVRfTk9UX1NVQ0NFU1NGVUwsCi0gICAgICAicHJvY2Vzc1N0eWxlc2hlZXQgbm90IHN1Y2Nlc2Z1bGwhIn0sCi0KLSAgICB7IEVSX1NBWF9FWENFUFRJT04sCi0gICAgICJTQVggRXhjZXB0aW9uIn0sCi0KLS8vICBhZGQgdGhpcyBtZXNzYWdlIHRvIGZpeCBidWcgMjE0NzgKLSAgICB7IEVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQsCi0gICAgICJGdW5jdGlvbiBub3Qgc3VwcG9ydGVkISJ9LAotCi0gICAgeyBFUl9YU0xUX0VSUk9SLAotICAgICAiWFNMVCBFcnJvciJ9LAotCi0gICAgeyBFUl9DVVJSRU5DWV9TSUdOX0lMTEVHQUwsCi0gICAgICAiY3VycmVuY3kgc2lnbiBpcyBub3QgYWxsb3dlZCBpbiBmb3JtYXQgcGF0dGVybiBzdHJpbmcifSwKLQotICAgIHsgRVJfRE9DVU1FTlRfRlVOQ1RJT05fSU5WQUxJRF9JTl9TVFlMRVNIRUVUX0RPTSwKLSAgICAgICJEb2N1bWVudCBmdW5jdGlvbiBub3Qgc3VwcG9ydGVkIGluIFN0eWxlc2hlZXQgRE9NISJ9LAotCi0gICAgeyBFUl9DQU5UX1JFU09MVkVfUFJFRklYX09GX05PTl9QUkVGSVhfUkVTT0xWRVIsCi0gICAgICAiQ2FuJ3QgcmVzb2x2ZSBwcmVmaXggb2Ygbm9uLVByZWZpeCByZXNvbHZlciEifSwKLQotICAgIHsgRVJfUkVESVJFQ1RfQ09VTEROVF9HRVRfRklMRU5BTUUsCi0gICAgICAiUmVkaXJlY3QgZXh0ZW5zaW9uOiBDb3VsZCBub3QgZ2V0IGZpbGVuYW1lIC0gZmlsZSBvciBzZWxlY3QgYXR0cmlidXRlIG11c3QgcmV0dXJuIHZhbGQgc3RyaW5nLiJ9LAotCi0gICAgeyBFUl9DQU5OT1RfQlVJTERfRk9STUFUVEVSTElTVEVORVJfSU5fUkVESVJFQ1QsCi0gICAgICAiQ2FuIG5vdCBidWlsZCBGb3JtYXR0ZXJMaXN0ZW5lciBpbiBSZWRpcmVjdCBleHRlbnNpb24hIn0sCi0KLSAgICB7IEVSX0lOVkFMSURfUFJFRklYX0lOX0VYQ0xVREVSRVNVTFRQUkVGSVgsCi0gICAgICAiUHJlZml4IGluIGV4Y2x1ZGUtcmVzdWx0LXByZWZpeGVzIGlzIG5vdCB2YWxpZDogezB9In0sCi0KLSAgICB7IEVSX01JU1NJTkdfTlNfVVJJLAotICAgICAgIk1pc3NpbmcgbmFtZXNwYWNlIFVSSSBmb3Igc3BlY2lmaWVkIHByZWZpeCJ9LAotCi0gICAgeyBFUl9NSVNTSU5HX0FSR19GT1JfT1BUSU9OLAotICAgICAgIk1pc3NpbmcgYXJndW1lbnQgZm9yIG9wdGlvbjogezB9In0sCi0KLSAgICB7IEVSX0lOVkFMSURfT1BUSU9OLAotICAgICAiSW52YWxpZCBvcHRpb246IHswfSJ9LAotCi0gICAgeyBFUl9NQUxGT1JNRURfRk9STUFUX1NUUklORywKLSAgICAgIk1hbGZvcm1lZCBmb3JtYXQgc3RyaW5nOiB7MH0ifSwKLQotICAgIHsgRVJfU1RZTEVTSEVFVF9SRVFVSVJFU19WRVJTSU9OX0FUVFJJQiwKLSAgICAgICJ4c2w6c3R5bGVzaGVldCByZXF1aXJlcyBhICd2ZXJzaW9uJyBhdHRyaWJ1dGUhIn0sCi0KLSAgICB7IEVSX0lMTEVHQUxfQVRUUklCVVRFX1ZBTFVFLAotICAgICAgIkF0dHJpYnV0ZTogezB9IGhhcyBhbiBpbGxlZ2FsIHZhbHVlOiB7MX0ifSwKLQotICAgIHsgRVJfQ0hPT1NFX1JFUVVJUkVTX1dIRU4sCi0gICAgICJ4c2w6Y2hvb3NlIHJlcXVpcmVzIGFuIHhzbDp3aGVuIn0sCi0KLSAgICB7IEVSX05PX0FQUExZX0lNUE9SVF9JTl9GT1JfRUFDSCwKLSAgICAgICJ4c2w6YXBwbHktaW1wb3J0cyBub3QgYWxsb3dlZCBpbiBhIHhzbDpmb3ItZWFjaCJ9LAotCi0gICAgeyBFUl9DQU5UX1VTRV9EVE1fRk9SX09VVFBVVCwKLSAgICAgICJDYW5ub3QgdXNlIGEgRFRNTGlhaXNvbiBmb3IgYW4gb3V0cHV0IERPTSBub2RlLi4uIHBhc3MgYSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuRE9NMkhlbHBlciBpbnN0ZWFkISJ9LAotCi0gICAgeyBFUl9DQU5UX1VTRV9EVE1fRk9SX0lOUFVULAotICAgICAgIkNhbm5vdCB1c2UgYSBEVE1MaWFpc29uIGZvciBhIGlucHV0IERPTSBub2RlLi4uIHBhc3MgYSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuRE9NMkhlbHBlciBpbnN0ZWFkISJ9LAotCi0gICAgeyBFUl9DQUxMX1RPX0VYVF9GQUlMRUQsCi0gICAgICAiQ2FsbCB0byBleHRlbnNpb24gZWxlbWVudCBmYWlsZWQ6IHswfSJ9LAotCi0gICAgeyBFUl9QUkVGSVhfTVVTVF9SRVNPTFZFLAotICAgICAgIlByZWZpeCBtdXN0IHJlc29sdmUgdG8gYSBuYW1lc3BhY2U6IHswfSJ9LAotCi0gICAgeyBFUl9JTlZBTElEX1VURjE2X1NVUlJPR0FURSwKLSAgICAgICJJbnZhbGlkIFVURi0xNiBzdXJyb2dhdGUgZGV0ZWN0ZWQ6IHswfSA/In0sCi0KLSAgICB7IEVSX1hTTEFUVFJTRVRfVVNFRF9JVFNFTEYsCi0gICAgICAieHNsOmF0dHJpYnV0ZS1zZXQgezB9IHVzZWQgaXRzZWxmLCB3aGljaCB3aWxsIGNhdXNlIGFuIGluZmluaXRlIGxvb3AuIn0sCi0KLSAgICB7IEVSX0NBTk5PVF9NSVhfWEVSQ0VTRE9NLAotICAgICAgIkNhbiBub3QgbWl4IG5vbiBYZXJjZXMtRE9NIGlucHV0IHdpdGggWGVyY2VzLURPTSBvdXRwdXQhIn0sCi0KLSAgICB7IEVSX1RPT19NQU5ZX0xJU1RFTkVSUywKLSAgICAgICJhZGRUcmFjZUxpc3RlbmVyc1RvU3R5bGVzaGVldCAtIFRvb01hbnlMaXN0ZW5lcnNFeGNlcHRpb24ifSwKLQotICAgIHsgRVJfSU5fRUxFTVRFTVBMQVRFRUxFTV9SRUFET0JKRUNULAotICAgICAgIkluIEVsZW1UZW1wbGF0ZUVsZW1lbnQucmVhZE9iamVjdDogezB9In0sCi0KLSAgICB7IEVSX0RVUExJQ0FURV9OQU1FRF9URU1QTEFURSwKLSAgICAgICJGb3VuZCBtb3JlIHRoYW4gb25lIHRlbXBsYXRlIG5hbWVkOiB7MH0ifSwKLQotICAgIHsgRVJfSU5WQUxJRF9LRVlfQ0FMTCwKLSAgICAgICJJbnZhbGlkIGZ1bmN0aW9uIGNhbGw6IHJlY3Vyc2l2ZSBrZXkoKSBjYWxscyBhcmUgbm90IGFsbG93ZWQifSwKLQotICAgIHsgRVJfUkVGRVJFTkNJTkdfSVRTRUxGLAotICAgICAgIlZhcmlhYmxlIHswfSBpcyBkaXJlY3RseSBvciBpbmRpcmVjdGx5IHJlZmVyZW5jaW5nIGl0c2VsZiEifSwKLQotICAgIHsgRVJfSUxMRUdBTF9ET01TT1VSQ0VfSU5QVVQsCi0gICAgICAiVGhlIGlucHV0IG5vZGUgY2FuIG5vdCBiZSBudWxsIGZvciBhIERPTVNvdXJjZSBmb3IgbmV3VGVtcGxhdGVzISJ9LAotCi0gICAgeyBFUl9DTEFTU19OT1RfRk9VTkRfRk9SX09QVElPTiwKLSAgICAgICAgIkNsYXNzIGZpbGUgbm90IGZvdW5kIGZvciBvcHRpb24gezB9In0sCi0KLSAgICB7IEVSX1JFUVVJUkVEX0VMRU1fTk9UX0ZPVU5ELAotICAgICAgICAiUmVxdWlyZWQgRWxlbWVudCBub3QgZm91bmQ6IHswfSJ9LAotCi0gICAgeyBFUl9JTlBVVF9DQU5OT1RfQkVfTlVMTCwKLSAgICAgICAgIklucHV0U3RyZWFtIGNhbm5vdCBiZSBudWxsIn0sCi0KLSAgICB7IEVSX1VSSV9DQU5OT1RfQkVfTlVMTCwKLSAgICAgICAgIlVSSSBjYW5ub3QgYmUgbnVsbCJ9LAotCi0gICAgeyBFUl9GSUxFX0NBTk5PVF9CRV9OVUxMLAotICAgICAgICAiRmlsZSBjYW5ub3QgYmUgbnVsbCJ9LAotCi0gICAgeyBFUl9TT1VSQ0VfQ0FOTk9UX0JFX05VTEwsCi0gICAgICAgICAgICAgICAgIklucHV0U291cmNlIGNhbm5vdCBiZSBudWxsIn0sCi0KLSAgICB7IEVSX0NBTk5PVF9JTklUX0JTRk1HUiwKLSAgICAgICAgICAgICAgICAiQ291bGQgbm90IGluaXRpYWxpemUgQlNGIE1hbmFnZXIifSwKLQotICAgIHsgRVJfQ0FOTk9UX0NNUExfRVhURU5TTiwKLSAgICAgICAgICAgICAgICAiQ291bGQgbm90IGNvbXBpbGUgZXh0ZW5zaW9uIn0sCi0KLSAgICB7IEVSX0NBTk5PVF9DUkVBVEVfRVhURU5TTiwKLSAgICAgICJDb3VsZCBub3QgY3JlYXRlIGV4dGVuc2lvbjogezB9IGJlY2F1c2Ugb2Y6IHsxfSJ9LAotCi0gICAgeyBFUl9JTlNUQU5DRV9NVEhEX0NBTExfUkVRVUlSRVMsCi0gICAgICAiSW5zdGFuY2UgbWV0aG9kIGNhbGwgdG8gbWV0aG9kIHswfSByZXF1aXJlcyBhbiBPYmplY3QgaW5zdGFuY2UgYXMgZmlyc3QgYXJndW1lbnQifSwKLQotICAgIHsgRVJfSU5WQUxJRF9FTEVNRU5UX05BTUUsCi0gICAgICAiSW52YWxpZCBlbGVtZW50IG5hbWUgc3BlY2lmaWVkIHswfSJ9LAotCi0gICAgeyBFUl9FTEVNRU5UX05BTUVfTUVUSE9EX1NUQVRJQywKLSAgICAgICJFbGVtZW50IG5hbWUgbWV0aG9kIG11c3QgYmUgc3RhdGljIHswfSJ9LAotCi0gICAgeyBFUl9FWFRFTlNJT05fRlVOQ19VTktOT1dOLAotICAgICAgICAgICAgICJFeHRlbnNpb24gZnVuY3Rpb24gezB9IDogezF9IGlzIHVua25vd24ifSwKLQotICAgIHsgRVJfTU9SRV9NQVRDSF9DT05TVFJVQ1RPUiwKLSAgICAgICAgICAgICAiTW9yZSB0aGFuIG9uZSBiZXN0IG1hdGNoIGZvciBjb25zdHJ1Y3RvciBmb3IgezB9In0sCi0KLSAgICB7IEVSX01PUkVfTUFUQ0hfTUVUSE9ELAotICAgICAgICAgICAgICJNb3JlIHRoYW4gb25lIGJlc3QgbWF0Y2ggZm9yIG1ldGhvZCB7MH0ifSwKLQotICAgIHsgRVJfTU9SRV9NQVRDSF9FTEVNRU5ULAotICAgICAgICAgICAgICJNb3JlIHRoYW4gb25lIGJlc3QgbWF0Y2ggZm9yIGVsZW1lbnQgbWV0aG9kIHswfSJ9LAotCi0gICAgeyBFUl9JTlZBTElEX0NPTlRFWFRfUEFTU0VELAotICAgICAgICAgICAgICJJbnZhbGlkIGNvbnRleHQgcGFzc2VkIHRvIGV2YWx1YXRlIHswfSJ9LAotCi0gICAgeyBFUl9QT09MX0VYSVNUUywKLSAgICAgICAgICAgICAiUG9vbCBhbHJlYWR5IGV4aXN0cyJ9LAotCi0gICAgeyBFUl9OT19EUklWRVJfTkFNRSwKLSAgICAgICAgICAgICAiTm8gZHJpdmVyIE5hbWUgc3BlY2lmaWVkIn0sCi0KLSAgICB7IEVSX05PX1VSTCwKLSAgICAgICAgICAgICAiTm8gVVJMIHNwZWNpZmllZCJ9LAotCi0gICAgeyBFUl9QT09MX1NJWkVfTEVTU1RIQU5fT05FLAotICAgICAgICAgICAgICJQb29sIHNpemUgaXMgbGVzcyB0aGFuIG9uZSEifSwKLQotICAgIHsgRVJfSU5WQUxJRF9EUklWRVIsCi0gICAgICAgICAgICAgIkludmFsaWQgZHJpdmVyIG5hbWUgc3BlY2lmaWVkISJ9LAotCi0gICAgeyBFUl9OT19TVFlMRVNIRUVUUk9PVCwKLSAgICAgICAgICAgICAiRGlkIG5vdCBmaW5kIHRoZSBzdHlsZXNoZWV0IHJvb3QhIn0sCi0KLSAgICB7IEVSX0lMTEVHQUxfWE1MU1BBQ0VfVkFMVUUsCi0gICAgICAgICAiSWxsZWdhbCB2YWx1ZSBmb3IgeG1sOnNwYWNlIn0sCi0KLSAgICB7IEVSX1BST0NFU1NGUk9NTk9ERV9GQUlMRUQsCi0gICAgICAgICAicHJvY2Vzc0Zyb21Ob2RlIGZhaWxlZCJ9LAotCi0gICAgeyBFUl9SRVNPVVJDRV9DT1VMRF9OT1RfTE9BRCwKLSAgICAgICAgIlRoZSByZXNvdXJjZSBbIHswfSBdIGNvdWxkIG5vdCBsb2FkOiB7MX0gXG4gezJ9IFx0IHszfSJ9LAotCi0gICAgeyBFUl9CVUZGRVJfU0laRV9MRVNTVEhBTl9aRVJPLAotICAgICAgICAiQnVmZmVyIHNpemUgPD0wIn0sCi0KLSAgICB7IEVSX1VOS05PV05fRVJST1JfQ0FMTElOR19FWFRFTlNJT04sCi0gICAgICAgICJVbmtub3duIGVycm9yIHdoZW4gY2FsbGluZyBleHRlbnNpb24ifSwKLQotICAgIHsgRVJfTk9fTkFNRVNQQUNFX0RFQ0wsCi0gICAgICAgICJQcmVmaXggezB9IGRvZXMgbm90IGhhdmUgYSBjb3JyZXNwb25kaW5nIG5hbWVzcGFjZSBkZWNsYXJhdGlvbiJ9LAotCi0gICAgeyBFUl9FTEVNX0NPTlRFTlRfTk9UX0FMTE9XRUQsCi0gICAgICAgICJFbGVtZW50IGNvbnRlbnQgbm90IGFsbG93ZWQgZm9yIGxhbmc9amF2YWNsYXNzIHswfSJ9LAotCi0gICAgeyBFUl9TVFlMRVNIRUVUX0RJUkVDVEVEX1RFUk1JTkFUSU9OLAotICAgICAgICAiU3R5bGVzaGVldCBkaXJlY3RlZCB0ZXJtaW5hdGlvbiJ9LAotCi0gICAgeyBFUl9PTkVfT1JfVFdPLAotICAgICAgICAiMSBvciAyIn0sCi0KLSAgICB7IEVSX1RXT19PUl9USFJFRSwKLSAgICAgICAgIjIgb3IgMyJ9LAotCi0gICAgeyBFUl9DT1VMRF9OT1RfTE9BRF9SRVNPVVJDRSwKLSAgICAgICAgIkNvdWxkIG5vdCBsb2FkIHswfSAoY2hlY2sgQ0xBU1NQQVRIKSwgbm93IHVzaW5nIGp1c3QgdGhlIGRlZmF1bHRzIn0sCi0KLSAgICB7IEVSX0NBTk5PVF9JTklUX0RFRkFVTFRfVEVNUExBVEVTLAotICAgICAgICAiQ2Fubm90IGluaXRpYWxpemUgZGVmYXVsdCB0ZW1wbGF0ZXMifSwKLQotICAgIHsgRVJfUkVTVUxUX05VTEwsCi0gICAgICAgICJSZXN1bHQgc2hvdWxkIG5vdCBiZSBudWxsIn0sCi0KLSAgICB7IEVSX1JFU1VMVF9DT1VMRF9OT1RfQkVfU0VULAotICAgICAgICAiUmVzdWx0IGNvdWxkIG5vdCBiZSBzZXQifSwKLQotICAgIHsgRVJfTk9fT1VUUFVUX1NQRUNJRklFRCwKLSAgICAgICAgIk5vIG91dHB1dCBzcGVjaWZpZWQifSwKLQotICAgIHsgRVJfQ0FOTk9UX1RSQU5TRk9STV9UT19SRVNVTFRfVFlQRSwKLSAgICAgICAgIkNhbicndCB0cmFuc2Zvcm0gdG8gYSBSZXN1bHQgb2YgdHlwZSB7MH0ifSwKLQotICAgIHsgRVJfQ0FOTk9UX1RSQU5TRk9STV9TT1VSQ0VfVFlQRSwKLSAgICAgICAgIkNhbicndCB0cmFuc2Zvcm0gYSBTb3VyY2Ugb2YgdHlwZSB7MH0ifSwKLQotICAgIHsgRVJfTlVMTF9DT05URU5UX0hBTkRMRVIsCi0gICAgICAgICJOdWxsIGNvbnRlbnQgaGFuZGxlciJ9LAotCi0gICAgeyBFUl9OVUxMX0VSUk9SX0hBTkRMRVIsCi0gICAgICAgICJOdWxsIGVycm9yIGhhbmRsZXIifSwKLQotICAgIHsgRVJfQ0FOTk9UX0NBTExfUEFSU0UsCi0gICAgICAgICJwYXJzZSBjYW4gbm90IGJlIGNhbGxlZCBpZiB0aGUgQ29udGVudEhhbmRsZXIgaGFzIG5vdCBiZWVuIHNldCJ9LAotCi0gICAgeyBFUl9OT19QQVJFTlRfRk9SX0ZJTFRFUiwKLSAgICAgICAgIk5vIHBhcmVudCBmb3IgZmlsdGVyIn0sCi0KLSAgICB7IEVSX05PX1NUWUxFU0hFRVRfSU5fTUVESUEsCi0gICAgICAgICAiTm8gc3R5bGVzaGVldCBmb3VuZCBpbjogezB9LCBtZWRpYT0gezF9In0sCi0KLSAgICB7IEVSX05PX1NUWUxFU0hFRVRfUEksCi0gICAgICAgICAiTm8geG1sLXN0eWxlc2hlZXQgUEkgZm91bmQgaW46IHswfSJ9LAotCi0gICAgeyBFUl9OT1RfU1VQUE9SVEVELAotICAgICAgICJOb3Qgc3VwcG9ydGVkOiB7MH0ifSwKLQotICAgIHsgRVJfUFJPUEVSVFlfVkFMVUVfQk9PTEVBTiwKLSAgICAgICAiVmFsdWUgZm9yIHByb3BlcnR5IHswfSBzaG91bGQgYmUgYSBCb29sZWFuIGluc3RhbmNlIn0sCi0KLSAgICB7IEVSX0NPVUxEX05PVF9GSU5EX0VYVEVSTl9TQ1JJUFQsCi0gICAgICAgICAiQ291bGQgbm90IGdldCB0byBleHRlcm5hbCBzY3JpcHQgYXQgezB9In0sCi0KLSAgICB7IEVSX1JFU09VUkNFX0NPVUxEX05PVF9GSU5ELAotICAgICAgICAiVGhlIHJlc291cmNlIFsgezB9IF0gY291bGQgbm90IGJlIGZvdW5kLlxuIHsxfSJ9LAotCi0gICAgeyBFUl9PVVRQVVRfUFJPUEVSVFlfTk9UX1JFQ09HTklaRUQsCi0gICAgICAgICJPdXRwdXQgcHJvcGVydHkgbm90IHJlY29nbml6ZWQ6IHswfSJ9LAotCi0gICAgeyBFUl9GQUlMRURfQ1JFQVRJTkdfRUxFTUxJVFJTTFQsCi0gICAgICAgICJGYWlsZWQgY3JlYXRpbmcgRWxlbUxpdGVyYWxSZXN1bHQgaW5zdGFuY2UifSwKLQotICAvL0VhcmxpZXIgKEpESyAxLjQgWEFMQU4gMi4yLUQxMSkgYXQga2V5IGNvZGUgJzIwNCcgdGhlIGtleSBuYW1lIHdhcyBFUl9QUklPUklUWV9OT1RfUEFSU0FCTEUKLSAgLy8gSW4gbGF0ZXN0IFhhbGFuIGNvZGUgYmFzZSBrZXkgbmFtZSBpcyAgRVJfVkFMVUVfU0hPVUxEX0JFX05VTUJFUi4gVGhpcyBzaG91bGQgYWxzbyBiZSB0YWtlbiBjYXJlCi0gIC8vaW4gbG9jYWxlIHNwZWNpZmljIGZpbGVzIGxpa2UgWFNMVEVycm9yUmVzb3VyY2VzX2RlLmphdmEsIFhTTFRFcnJvclJlc291cmNlc19mci5qYXZhIGV0Yy4KLSAgLy9OT1RFOiBOb3Qgb25seSB0aGUga2V5IG5hbWUgYnV0IG1lc3NhZ2UgaGFzIGFsc28gYmVlbiBjaGFuZ2VkLgotICAgIHsgRVJfVkFMVUVfU0hPVUxEX0JFX05VTUJFUiwKLSAgICAgICAgIlZhbHVlIGZvciB7MH0gc2hvdWxkIGNvbnRhaW4gYSBwYXJzYWJsZSBudW1iZXIifSwKLQotICAgIHsgRVJfVkFMVUVfU0hPVUxEX0VRVUFMLAotICAgICAgICAiVmFsdWUgZm9yIHswfSBzaG91bGQgZXF1YWwgeWVzIG9yIG5vIn0sCi0KLSAgICB7IEVSX0ZBSUxFRF9DQUxMSU5HX01FVEhPRCwKLSAgICAgICAgIkZhaWxlZCBjYWxsaW5nIHswfSBtZXRob2QifSwKLQotICAgIHsgRVJfRkFJTEVEX0NSRUFUSU5HX0VMRU1UTVBMLAotICAgICAgICAiRmFpbGVkIGNyZWF0aW5nIEVsZW1UZW1wbGF0ZUVsZW1lbnQgaW5zdGFuY2UifSwKLQotICAgIHsgRVJfQ0hBUlNfTk9UX0FMTE9XRUQsCi0gICAgICAgICJDaGFyYWN0ZXJzIGFyZSBub3QgYWxsb3dlZCBhdCB0aGlzIHBvaW50IGluIHRoZSBkb2N1bWVudCJ9LAotCi0gICAgeyBFUl9BVFRSX05PVF9BTExPV0VELAotICAgICAgICAiXCJ7MH1cIiBhdHRyaWJ1dGUgaXMgbm90IGFsbG93ZWQgb24gdGhlIHsxfSBlbGVtZW50ISJ9LAotCi0gICAgeyBFUl9CQURfVkFMVUUsCi0gICAgICJ7MH0gYmFkIHZhbHVlIHsxfSAifSwKLQotICAgIHsgRVJfQVRUUklCX1ZBTFVFX05PVF9GT1VORCwKLSAgICAgInswfSBhdHRyaWJ1dGUgdmFsdWUgbm90IGZvdW5kICJ9LAotCi0gICAgeyBFUl9BVFRSSUJfVkFMVUVfTk9UX1JFQ09HTklaRUQsCi0gICAgICJ7MH0gYXR0cmlidXRlIHZhbHVlIG5vdCByZWNvZ25pemVkICJ9LAotCi0gICAgeyBFUl9OVUxMX1VSSV9OQU1FU1BBQ0UsCi0gICAgICJBdHRlbXB0aW5nIHRvIGdlbmVyYXRlIGEgbmFtZXNwYWNlIHByZWZpeCB3aXRoIGEgbnVsbCBVUkkifSwKLQotICAgIHsgRVJfTlVNQkVSX1RPT19CSUcsCi0gICAgICJBdHRlbXB0aW5nIHRvIGZvcm1hdCBhIG51bWJlciBiaWdnZXIgdGhhbiB0aGUgbGFyZ2VzdCBMb25nIGludGVnZXIifSwKLQotICAgIHsgRVJfQ0FOTk9UX0ZJTkRfU0FYMV9EUklWRVIsCi0gICAgICJDYW5ub3QgZmluZCBTQVgxIGRyaXZlciBjbGFzcyB7MH0ifSwKLQotICAgIHsgRVJfU0FYMV9EUklWRVJfTk9UX0xPQURFRCwKLSAgICAgIlNBWDEgZHJpdmVyIGNsYXNzIHswfSBmb3VuZCBidXQgY2Fubm90IGJlIGxvYWRlZCJ9LAotCi0gICAgeyBFUl9TQVgxX0RSSVZFUl9OT1RfSU5TVEFOVElBVEVELAotICAgICAiU0FYMSBkcml2ZXIgY2xhc3MgezB9IGxvYWRlZCBidXQgY2Fubm90IGJlIGluc3RhbnRpYXRlZCJ9LAotCi0gICAgeyBFUl9TQVgxX0RSSVZFUl9OT1RfSU1QTEVNRU5UX1BBUlNFUiwKLSAgICAgIlNBWDEgZHJpdmVyIGNsYXNzIHswfSBkb2VzIG5vdCBpbXBsZW1lbnQgb3JnLnhtbC5zYXguUGFyc2VyIn0sCi0KLSAgICB7IEVSX1BBUlNFUl9QUk9QRVJUWV9OT1RfU1BFQ0lGSUVELAotICAgICAiU3lzdGVtIHByb3BlcnR5IG9yZy54bWwuc2F4LnBhcnNlciBub3Qgc3BlY2lmaWVkIn0sCi0KLSAgICB7IEVSX1BBUlNFUl9BUkdfQ0FOTk9UX0JFX05VTEwsCi0gICAgICJQYXJzZXIgYXJndW1lbnQgbXVzdCBub3QgYmUgbnVsbCJ9LAotCi0gICAgeyBFUl9GRUFUVVJFLAotICAgICAiRmVhdHVyZTogezB9In0sCi0KLSAgICB7IEVSX1BST1BFUlRZLAotICAgICAiUHJvcGVydHk6IHswfSJ9LAotCi0gICAgeyBFUl9OVUxMX0VOVElUWV9SRVNPTFZFUiwKLSAgICAgIk51bGwgZW50aXR5IHJlc29sdmVyIn0sCi0KLSAgICB7IEVSX05VTExfRFREX0hBTkRMRVIsCi0gICAgICJOdWxsIERURCBoYW5kbGVyIn0sCi0KLSAgICB7IEVSX05PX0RSSVZFUl9OQU1FX1NQRUNJRklFRCwKLSAgICAgIk5vIERyaXZlciBOYW1lIFNwZWNpZmllZCEifSwKLQotICAgIHsgRVJfTk9fVVJMX1NQRUNJRklFRCwKLSAgICAgIk5vIFVSTCBTcGVjaWZpZWQhIn0sCi0KLSAgICB7IEVSX1BPT0xTSVpFX0xFU1NfVEhBTl9PTkUsCi0gICAgICJQb29sIHNpemUgaXMgbGVzcyB0aGFuIDEhIn0sCi0KLSAgICB7IEVSX0lOVkFMSURfRFJJVkVSX05BTUUsCi0gICAgICJJbnZhbGlkIERyaXZlciBOYW1lIFNwZWNpZmllZCEifSwKLQotICAgIHsgRVJfRVJST1JMSVNURU5FUiwKLSAgICAgIkVycm9yTGlzdGVuZXIifSwKLQotCi0vLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIHNob3VsZCBub3Qgbm9ybWFsbHkgYmUgZGlzcGxheWVkCi0vLyAgIHRvIHVzZXJzLiAgSXQgZGVzY3JpYmVzIGEgc2l0dWF0aW9uIGluIHdoaWNoIHRoZSBwcm9jZXNzb3IgaGFzIGRldGVjdGVkCi0vLyAgIGFuIGludGVybmFsIGNvbnNpc3RlbmN5IHByb2JsZW0gaW4gaXRzZWxmLCBhbmQgaXQgcHJvdmlkZXMgdGhpcyBtZXNzYWdlCi0vLyAgIGZvciB0aGUgZGV2ZWxvcGVyIHRvIGhlbHAgZGlhZ25vc2UgdGhlIHByb2JsZW0uICBUaGUgbmFtZQotLy8gICAnRWxlbVRlbXBsYXRlRWxlbWVudCcgaXMgdGhlIG5hbWUgb2YgYSBjbGFzcywgYW5kIHNob3VsZCBub3QgYmUKLS8vICAgdHJhbnNsYXRlZC4KLSAgICB7IEVSX0FTU0VSVF9OT19URU1QTEFURV9QQVJFTlQsCi0gICAgICJQcm9ncmFtbWVyJ3MgZXJyb3IhIFRoZSBleHByZXNzaW9uIGhhcyBubyBFbGVtVGVtcGxhdGVFbGVtZW50IHBhcmVudCEifSwKLQotCi0vLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIHNob3VsZCBub3Qgbm9ybWFsbHkgYmUgZGlzcGxheWVkCi0vLyAgIHRvIHVzZXJzLiAgSXQgZGVzY3JpYmVzIGEgc2l0dWF0aW9uIGluIHdoaWNoIHRoZSBwcm9jZXNzb3IgaGFzIGRldGVjdGVkCi0vLyAgIGFuIGludGVybmFsIGNvbnNpc3RlbmN5IHByb2JsZW0gaW4gaXRzZWxmLCBhbmQgaXQgcHJvdmlkZXMgdGhpcyBtZXNzYWdlCi0vLyAgIGZvciB0aGUgZGV2ZWxvcGVyIHRvIGhlbHAgZGlhZ25vc2UgdGhlIHByb2JsZW0uICBUaGUgc3Vic3RpdHV0aW9uIHRleHQKLS8vICAgcHJvdmlkZXMgZnVydGhlciBpbmZvcm1hdGlvbiBpbiBvcmRlciB0byBkaWFnbm9zZSB0aGUgcHJvYmxlbS4gIFRoZSBuYW1lCi0vLyAgICdSZWR1bmRlbnRFeHByRWxpbWluYXRvcicgaXMgdGhlIG5hbWUgb2YgYSBjbGFzcywgYW5kIHNob3VsZCBub3QgYmUKLS8vICAgdHJhbnNsYXRlZC4KLSAgICB7IEVSX0FTU0VSVF9SRURVTkRFTlRfRVhQUl9FTElNSU5BVE9SLAotICAgICAiUHJvZ3JhbW1lcicncyBhc3NlcnRpb24gaW4gUmVkdW5kZW50RXhwckVsaW1pbmF0b3I6IHswfSJ9LAotCi0gICAgeyBFUl9OT1RfQUxMT1dFRF9JTl9QT1NJVElPTiwKLSAgICAgInswfSBpcyBub3QgYWxsb3dlZCBpbiB0aGlzIHBvc2l0aW9uIGluIHRoZSBzdHlsZXNoZWV0ISJ9LAotCi0gICAgeyBFUl9OT05XSElURVNQQUNFX05PVF9BTExPV0VEX0lOX1BPU0lUSU9OLAotICAgICAiTm9uLXdoaXRlc3BhY2UgdGV4dCBpcyBub3QgYWxsb3dlZCBpbiB0aGlzIHBvc2l0aW9uIGluIHRoZSBzdHlsZXNoZWV0ISJ9LAotCi0gIC8vIFRoaXMgY29kZSBpcyBzaGFyZWQgd2l0aCB3YXJuaW5nIGNvZGVzLgotICAvLyBTeXN0ZW1JZCBVbmtub3duCi0gICAgeyBJTlZBTElEX1RDSEFSLAotICAgICAiSWxsZWdhbCB2YWx1ZTogezF9IHVzZWQgZm9yIENIQVIgYXR0cmlidXRlOiB7MH0uICBBbiBhdHRyaWJ1dGUgb2YgdHlwZSBDSEFSIG11c3QgYmUgb25seSAxIGNoYXJhY3RlciEifSwKLQotICAgIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgaXMgdXNlZCBpZiB0aGUgdmFsdWUgb2YKLSAgICAvLyBhbiBhdHRyaWJ1dGUgaW4gYSBzdHlsZXNoZWV0IGlzIGludmFsaWQuICAiUU5BTUUiIGlzIHRoZSBYTUwgZGF0YS10eXBlIG9mCi0gICAgLy8gdGhlIGF0dHJpYnV0ZSwgYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCB7MX0gaXMKLSAgICAvLyB0aGUgYXR0cmlidXRlIHZhbHVlIGFuZCB7MH0gaXMgdGhlIGF0dHJpYnV0ZSBuYW1lLgotICAvL1RoZSBmb2xsb3dpbmcgY29kZXMgYXJlIHNoYXJlZCB3aXRoIHRoZSB3YXJuaW5nIGNvZGVzLi4uCi0gICAgeyBJTlZBTElEX1FOQU1FLAotICAgICAiSWxsZWdhbCB2YWx1ZTogezF9IHVzZWQgZm9yIFFOQU1FIGF0dHJpYnV0ZTogezB9In0sCi0KLSAgICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIGlzIHVzZWQgaWYgdGhlIHZhbHVlIG9mCi0gICAgLy8gYW4gYXR0cmlidXRlIGluIGEgc3R5bGVzaGVldCBpcyBpbnZhbGlkLiAgIkVOVU0iIGlzIHRoZSBYTUwgZGF0YS10eXBlIG9mCi0gICAgLy8gdGhlIGF0dHJpYnV0ZSwgYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCB7MX0gaXMKLSAgICAvLyB0aGUgYXR0cmlidXRlIHZhbHVlLCB7MH0gaXMgdGhlIGF0dHJpYnV0ZSBuYW1lLCBhbmQgezJ9IGlzIGEgbGlzdCBvZiB2YWxpZAotICAgIC8vIHZhbHVlcy4KLSAgICB7IElOVkFMSURfRU5VTSwKLSAgICAgIklsbGVnYWwgdmFsdWU6IHsxfSB1c2VkIGZvciBFTlVNIGF0dHJpYnV0ZTogezB9LiAgVmFsaWQgdmFsdWVzIGFyZTogezJ9LiJ9LAotCi0vLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIGlzIHVzZWQgaWYgdGhlIHZhbHVlIG9mCi0vLyBhbiBhdHRyaWJ1dGUgaW4gYSBzdHlsZXNoZWV0IGlzIGludmFsaWQuICAiTk1UT0tFTiIgaXMgdGhlIFhNTCBkYXRhLXR5cGUKLS8vIG9mIHRoZSBhdHRyaWJ1dGUsIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgezF9IGlzCi0vLyB0aGUgYXR0cmlidXRlIHZhbHVlIGFuZCB7MH0gaXMgdGhlIGF0dHJpYnV0ZSBuYW1lLgotICAgIHsgSU5WQUxJRF9OTVRPS0VOLAotICAgICAiSWxsZWdhbCB2YWx1ZTogezF9IHVzZWQgZm9yIE5NVE9LRU4gYXR0cmlidXRlOiB7MH0gIn0sCi0KLS8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgaXMgdXNlZCBpZiB0aGUgdmFsdWUgb2YKLS8vIGFuIGF0dHJpYnV0ZSBpbiBhIHN0eWxlc2hlZXQgaXMgaW52YWxpZC4gICJOQ05BTUUiIGlzIHRoZSBYTUwgZGF0YS10eXBlCi0vLyBvZiB0aGUgYXR0cmlidXRlLCBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHsxfSBpcwotLy8gdGhlIGF0dHJpYnV0ZSB2YWx1ZSBhbmQgezB9IGlzIHRoZSBhdHRyaWJ1dGUgbmFtZS4KLSAgICB7IElOVkFMSURfTkNOQU1FLAotICAgICAiSWxsZWdhbCB2YWx1ZTogezF9IHVzZWQgZm9yIE5DTkFNRSBhdHRyaWJ1dGU6IHswfSAifSwKLQotLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBpcyB1c2VkIGlmIHRoZSB2YWx1ZSBvZgotLy8gYW4gYXR0cmlidXRlIGluIGEgc3R5bGVzaGVldCBpcyBpbnZhbGlkLiAgImJvb2xlYW4iIGlzIHRoZSBYU0xUIGRhdGEtdHlwZQotLy8gb2YgdGhlIGF0dHJpYnV0ZSwgYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCB7MX0gaXMKLS8vIHRoZSBhdHRyaWJ1dGUgdmFsdWUgYW5kIHswfSBpcyB0aGUgYXR0cmlidXRlIG5hbWUuCi0gICAgeyBJTlZBTElEX0JPT0xFQU4sCi0gICAgICJJbGxlZ2FsIHZhbHVlOiB7MX0gdXNlZCBmb3IgYm9vbGVhbiBhdHRyaWJ1dGU6IHswfSAifSwKLQotLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBpcyB1c2VkIGlmIHRoZSB2YWx1ZSBvZgotLy8gYW4gYXR0cmlidXRlIGluIGEgc3R5bGVzaGVldCBpcyBpbnZhbGlkLiAgIm51bWJlciIgaXMgdGhlIFhTTFQgZGF0YS10eXBlCi0vLyBvZiB0aGUgYXR0cmlidXRlLCBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHsxfSBpcwotLy8gdGhlIGF0dHJpYnV0ZSB2YWx1ZSBhbmQgezB9IGlzIHRoZSBhdHRyaWJ1dGUgbmFtZS4KLSAgICAgeyBJTlZBTElEX05VTUJFUiwKLSAgICAgIklsbGVnYWwgdmFsdWU6IHsxfSB1c2VkIGZvciBudW1iZXIgYXR0cmlidXRlOiB7MH0gIn0sCi0KLQotICAvLyBFbmQgb2Ygc2hhcmVkIGNvZGVzLi4uCi0KLS8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBICJtYXRjaCBwYXR0ZXJuIiBpcyBhIHNwZWNpYWwgZm9ybSBvZiBYUGF0aCBleHByZXNzaW9uCi0vLyB0aGF0IGlzIHVzZWQgZm9yIG1hdGNoaW5nIHBhdHRlcm5zLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mCi0vLyBhIGZ1bmN0aW9uLiAgVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgd2hlbiB0aGlzIGZ1bmN0aW9uIGlzIHJlZmVyZW5jZWQgaW4KLS8vIGEgbWF0Y2ggcGF0dGVybiwgaXRzIGFyZ3VtZW50IG11c3QgYmUgYSBzdHJpbmcgbGl0ZXJhbCAob3IgY29uc3RhbnQuKQotLy8gRVJfQVJHX0xJVEVSQUwgLSBuZXcgZXJyb3IgbWVzc2FnZSBmb3IgYnVnemlsbGEgLy81MjAyCi0gICAgeyBFUl9BUkdfTElURVJBTCwKLSAgICAgIkFyZ3VtZW50IHRvIHswfSBpbiBtYXRjaCBwYXR0ZXJuIG11c3QgYmUgYSBsaXRlcmFsLiJ9LAotCi0vLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHR3byBkZWZpbml0aW9ucyBvZgotLy8gYSB2YXJpYWJsZS4gIEEgImdsb2JhbCB2YXJpYWJsZSIgaXMgYSB2YXJpYWJsZSB0aGF0IGlzIGFjY2Vzc2libGUgZXZlcnl3aGVyCi0vLyBpbiB0aGUgc3R5bGVzaGVldC4KLS8vIEVSX0RVUExJQ0FURV9HTE9CQUxfVkFSIC0gbmV3IGVycm9yIG1lc3NhZ2UgZm9yIGJ1Z3ppbGxhICM3OTAKLSAgICB7IEVSX0RVUExJQ0FURV9HTE9CQUxfVkFSLAotICAgICAiRHVwbGljYXRlIGdsb2JhbCB2YXJpYWJsZSBkZWNsYXJhdGlvbi4ifSwKLQotCi0vLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHR3byBkZWZpbml0aW9ucyBvZgotLy8gYSB2YXJpYWJsZSB3ZXJlIGVuY291bnRlcmVkLgotLy8gRVJfRFVQTElDQVRFX1ZBUiAtIG5ldyBlcnJvciBtZXNzYWdlIGZvciBidWd6aWxsYSAjNzkwCi0gICAgeyBFUl9EVVBMSUNBVEVfVkFSLAotICAgICAiRHVwbGljYXRlIHZhcmlhYmxlIGRlY2xhcmF0aW9uLiJ9LAotCi0gICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogICJ4c2w6dGVtcGxhdGUsICJuYW1lIiBhbmQgIm1hdGNoIiBhcmUgWFNMVCBrZXl3b3JkcwotICAgIC8vIHdoaWNoIG11c3Qgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgLy8gRVJfVEVNUExBVEVfTkFNRV9NQVRDSCAtIG5ldyBlcnJvciBtZXNzYWdlIGZvciBidWd6aWxsYSAjNzg5Ci0gICAgeyBFUl9URU1QTEFURV9OQU1FX01BVENILAotICAgICAieHNsOnRlbXBsYXRlIG11c3QgaGF2ZSBhIG5hbWUgb3IgbWF0Y2ggYXR0cmlidXRlIChvciBib3RoKSJ9LAotCi0gICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogICJleGNsdWRlLXJlc3VsdC1wcmVmaXhlcyIgaXMgYW4gWFNMVCBrZXl3b3JkIHdoaWNoCi0gICAgLy8gc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgYSBuYW1lc3BhY2UgcHJlZml4Ci0gICAgLy8gZW5jb3VudGVyZWQgYXMgcGFydCBvZiB0aGUgdmFsdWUgb2YgdGhlIGV4Y2x1ZGUtcmVzdWx0LXByZWZpeGVzIGF0dHJpYnV0ZQotICAgIC8vIHdhcyBpbiBlcnJvci4KLSAgICAvLyBFUl9JTlZBTElEX1BSRUZJWCAtIG5ldyBlcnJvciBtZXNzYWdlIGZvciBidWd6aWxsYSAjNzg4Ci0gICAgeyBFUl9JTlZBTElEX1BSRUZJWCwKLSAgICAgIlByZWZpeCBpbiBleGNsdWRlLXJlc3VsdC1wcmVmaXhlcyBpcyBub3QgdmFsaWQ6IHswfSJ9LAotCi0gICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIEFuICJhdHRyaWJ1dGUgc2V0IiBpcyBhIHNldCBvZiBhdHRyaWJ1dGVzIHRoYXQgY2FuCi0gICAgLy8gYmUgYWRkZWQgdG8gYW4gZWxlbWVudCBpbiB0aGUgb3V0cHV0IGRvY3VtZW50IGFzIGEgZ3JvdXAuICBUaGUgbWVzc2FnZQotICAgIC8vIGluZGljYXRlcyB0aGF0IHRoZXJlIHdhcyBhIHJlZmVyZW5jZSB0byBhbiBhdHRyaWJ1dGUgc2V0IG5hbWVkIHswfSB0aGF0Ci0gICAgLy8gd2FzIG5ldmVyIGRlZmluZWQuCi0gICAgLy8gRVJfTk9fQVRUUklCX1NFVCAtIG5ldyBlcnJvciBtZXNzYWdlIGZvciBidWd6aWxsYSAjNzgyCi0gICAgeyBFUl9OT19BVFRSSUJfU0VULAotICAgICAiYXR0cmlidXRlLXNldCBuYW1lZCB7MH0gZG9lcyBub3QgZXhpc3QifSwKLQotICAgIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhlcmUgd2FzIGEgcmVmZXJlbmNlCi0gICAgLy8gdG8gYSBmdW5jdGlvbiBuYW1lZCB7MH0gZm9yIHdoaWNoIG5vIGZ1bmN0aW9uIGRlZmluaXRpb24gY291bGQgYmUgZm91bmQuCi0gICAgeyBFUl9GVU5DVElPTl9OT1RfRk9VTkQsCi0gICAgICJUaGUgZnVuY3Rpb24gbmFtZWQgezB9IGRvZXMgbm90IGV4aXN0In0sCi0KLSAgICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoZSBYU0xUIGluc3RydWN0aW9uCi0gICAgLy8gdGhhdCBpcyBuYW1lZCBieSB0aGUgc3Vic3RpdHV0aW9uIHRleHQgezB9IG11c3Qgbm90IGNvbnRhaW4gb3RoZXIgWFNMVAotICAgIC8vIGluc3RydWN0aW9ucyAoY29udGVudCkgb3IgYSAic2VsZWN0IiBhdHRyaWJ1dGUuICBUaGUgd29yZCAic2VsZWN0IiBpcwotICAgIC8vIGFuIFhTTFQga2V5d29yZCBpbiB0aGlzIGNhc2UgYW5kIG11c3Qgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgeyBFUl9DQU5UX0hBVkVfQ09OVEVOVF9BTkRfU0VMRUNULAotICAgICAiVGhlIHswfSBlbGVtZW50IG11c3Qgbm90IGhhdmUgYm90aCBjb250ZW50IGFuZCBhIHNlbGVjdCBhdHRyaWJ1dGUuIn0sCi0KLSAgICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoZSB2YWx1ZSBhcmd1bWVudAotICAgIC8vIG9mIHNldFBhcmFtZXRlciBtdXN0IGJlIGEgdmFsaWQgSmF2YSBPYmplY3QuCi0gICAgeyBFUl9JTlZBTElEX1NFVF9QQVJBTV9WQUxVRSwKLSAgICAgIlRoZSB2YWx1ZSBvZiBwYXJhbSB7MH0gbXVzdCBiZSBhIHZhbGlkIEphdmEgT2JqZWN0In0sCi0KLSAgICB7IEVSX0lOVkFMSURfTkFNRVNQQUNFX1VSSV9WQUxVRV9GT1JfUkVTVUxUX1BSRUZJWF9GT1JfREVGQVVMVCwKLSAgICAgICJUaGUgcmVzdWx0LXByZWZpeCBhdHRyaWJ1dGUgb2YgYW4geHNsOm5hbWVzcGFjZS1hbGlhcyBlbGVtZW50IGhhcyB0aGUgdmFsdWUgJyNkZWZhdWx0JywgYnV0IHRoZXJlIGlzIG5vIGRlY2xhcmF0aW9uIG9mIHRoZSBkZWZhdWx0IG5hbWVzcGFjZSBpbiBzY29wZSBmb3IgdGhlIGVsZW1lbnQifSwKLQotICAgIHsgRVJfSU5WQUxJRF9OQU1FU1BBQ0VfVVJJX1ZBTFVFX0ZPUl9SRVNVTFRfUFJFRklYLAotICAgICAgIlRoZSByZXN1bHQtcHJlZml4IGF0dHJpYnV0ZSBvZiBhbiB4c2w6bmFtZXNwYWNlLWFsaWFzIGVsZW1lbnQgaGFzIHRoZSB2YWx1ZSAnJ3swfScnLCBidXQgdGhlcmUgaXMgbm8gbmFtZXNwYWNlIGRlY2xhcmF0aW9uIGZvciB0aGUgcHJlZml4ICcnezB9JycgaW4gc2NvcGUgZm9yIHRoZSBlbGVtZW50LiJ9LAotCi0gICAgeyBFUl9TRVRfRkVBVFVSRV9OVUxMX05BTUUsCi0gICAgICAiVGhlIGZlYXR1cmUgbmFtZSBjYW5ub3QgYmUgbnVsbCBpbiBUcmFuc2Zvcm1lckZhY3Rvcnkuc2V0RmVhdHVyZShTdHJpbmcgbmFtZSwgYm9vbGVhbiB2YWx1ZSkuIn0sCi0KLSAgICB7IEVSX0dFVF9GRUFUVVJFX05VTExfTkFNRSwKLSAgICAgICJUaGUgZmVhdHVyZSBuYW1lIGNhbm5vdCBiZSBudWxsIGluIFRyYW5zZm9ybWVyRmFjdG9yeS5nZXRGZWF0dXJlKFN0cmluZyBuYW1lKS4ifSwKLQotICAgIHsgRVJfVU5TVVBQT1JURURfRkVBVFVSRSwKLSAgICAgICJDYW5ub3Qgc2V0IHRoZSBmZWF0dXJlICcnezB9Jycgb24gdGhpcyBUcmFuc2Zvcm1lckZhY3RvcnkuIn0sCi0KLSAgICB7IEVSX0VYVEVOU0lPTl9FTEVNRU5UX05PVF9BTExPV0VEX0lOX1NFQ1VSRV9QUk9DRVNTSU5HLAotICAgICAgICAgICJVc2Ugb2YgdGhlIGV4dGVuc2lvbiBlbGVtZW50ICcnezB9JycgaXMgbm90IGFsbG93ZWQgd2hlbiB0aGUgc2VjdXJlIHByb2Nlc3NpbmcgZmVhdHVyZSBpcyBzZXQgdG8gdHJ1ZS4ifSwKLQotICAgIHsgRVJfTkFNRVNQQUNFX0NPTlRFWFRfTlVMTF9OQU1FU1BBQ0UsCi0gICAgICAiQ2Fubm90IGdldCB0aGUgcHJlZml4IGZvciBhIG51bGwgbmFtZXNwYWNlIHVyaS4ifSwKLQotICAgIHsgRVJfTkFNRVNQQUNFX0NPTlRFWFRfTlVMTF9QUkVGSVgsCi0gICAgICAiQ2Fubm90IGdldCB0aGUgbmFtZXNwYWNlIHVyaSBmb3IgbnVsbCBwcmVmaXguIn0sCi0KLSAgICB7IEVSX1hQQVRIX1JFU09MVkVSX05VTExfUU5BTUUsCi0gICAgICAiVGhlIGZ1bmN0aW9uIG5hbWUgY2Fubm90IGJlIG51bGwuIn0sCi0KLSAgICB7IEVSX1hQQVRIX1JFU09MVkVSX05FR0FUSVZFX0FSSVRZLAotICAgICAgIlRoZSBhcml0eSBjYW5ub3QgYmUgbmVnYXRpdmUuIn0sCi0gIC8vIFdhcm5pbmdzLi4uCi0KLSAgICB7IFdHX0ZPVU5EX0NVUkxZQlJBQ0UsCi0gICAgICAiRm91bmQgJ30nIGJ1dCBubyBhdHRyaWJ1dGUgdGVtcGxhdGUgb3BlbiEifSwKLQotICAgIHsgV0dfQ09VTlRfQVRUUklCX01BVENIRVNfTk9fQU5DRVNUT1IsCi0gICAgICAiV2FybmluZzogY291bnQgYXR0cmlidXRlIGRvZXMgbm90IG1hdGNoIGFuIGFuY2VzdG9yIGluIHhzbDpudW1iZXIhIFRhcmdldCA9IHswfSJ9LAotCi0gICAgeyBXR19FWFBSX0FUVFJJQl9DSEFOR0VEX1RPX1NFTEVDVCwKLSAgICAgICJPbGQgc3ludGF4OiBUaGUgbmFtZSBvZiB0aGUgJ2V4cHInIGF0dHJpYnV0ZSBoYXMgYmVlbiBjaGFuZ2VkIHRvICdzZWxlY3QnLiJ9LAotCi0gICAgeyBXR19OT19MT0NBTEVfSU5fRk9STUFUTlVNQkVSLAotICAgICAgIlhhbGFuIGRvZXNuJ3QgeWV0IGhhbmRsZSB0aGUgbG9jYWxlIG5hbWUgaW4gdGhlIGZvcm1hdC1udW1iZXIgZnVuY3Rpb24uIn0sCi0KLSAgICB7IFdHX0xPQ0FMRV9OT1RfRk9VTkQsCi0gICAgICAiV2FybmluZzogQ291bGQgbm90IGZpbmQgbG9jYWxlIGZvciB4bWw6bGFuZz17MH0ifSwKLQotICAgIHsgV0dfQ0FOTk9UX01BS0VfVVJMX0ZST00sCi0gICAgICAiQ2FuIG5vdCBtYWtlIFVSTCBmcm9tOiB7MH0ifSwKLQotICAgIHsgV0dfQ0FOTk9UX0xPQURfUkVRVUVTVEVEX0RPQywKLSAgICAgICJDYW4gbm90IGxvYWQgcmVxdWVzdGVkIGRvYzogezB9In0sCi0KLSAgICB7IFdHX0NBTk5PVF9GSU5EX0NPTExBVE9SLAotICAgICAgIkNvdWxkIG5vdCBmaW5kIENvbGxhdG9yIGZvciA8c29ydCB4bWw6bGFuZz17MH0ifSwKLQotICAgIHsgV0dfRlVOQ1RJT05TX1NIT1VMRF9VU0VfVVJMLAotICAgICAgIk9sZCBzeW50YXg6IHRoZSBmdW5jdGlvbnMgaW5zdHJ1Y3Rpb24gc2hvdWxkIHVzZSBhIHVybCBvZiB7MH0ifSwKLQotICAgIHsgV0dfRU5DT0RJTkdfTk9UX1NVUFBPUlRFRF9VU0lOR19VVEY4LAotICAgICAgImVuY29kaW5nIG5vdCBzdXBwb3J0ZWQ6IHswfSwgdXNpbmcgVVRGLTgifSwKLQotICAgIHsgV0dfRU5DT0RJTkdfTk9UX1NVUFBPUlRFRF9VU0lOR19KQVZBLAotICAgICAgImVuY29kaW5nIG5vdCBzdXBwb3J0ZWQ6IHswfSwgdXNpbmcgSmF2YSB7MX0ifSwKLQotICAgIHsgV0dfU1BFQ0lGSUNJVFlfQ09ORkxJQ1RTLAotICAgICAgIlNwZWNpZmljaXR5IGNvbmZsaWN0cyBmb3VuZDogezB9IExhc3QgZm91bmQgaW4gc3R5bGVzaGVldCB3aWxsIGJlIHVzZWQuIn0sCi0KLSAgICB7IFdHX1BBUlNJTkdfQU5EX1BSRVBBUklORywKLSAgICAgICI9PT09PT09PT0gUGFyc2luZyBhbmQgcHJlcGFyaW5nIHswfSA9PT09PT09PT09In0sCi0KLSAgICB7IFdHX0FUVFJfVEVNUExBVEUsCi0gICAgICJBdHRyIFRlbXBsYXRlLCB7MH0ifSwKLQotICAgIHsgV0dfQ09ORkxJQ1RfQkVUV0VFTl9YU0xTVFJJUFNQQUNFX0FORF9YU0xQUkVTRVJWRVNQQUNFLAotICAgICAgIk1hdGNoIGNvbmZsaWN0IGJldHdlZW4geHNsOnN0cmlwLXNwYWNlIGFuZCB4c2w6cHJlc2VydmUtc3BhY2UifSwKLQotICAgIHsgV0dfQVRUUklCX05PVF9IQU5ETEVELAotICAgICAgIlhhbGFuIGRvZXMgbm90IHlldCBoYW5kbGUgdGhlIHswfSBhdHRyaWJ1dGUhIn0sCi0KLSAgICB7IFdHX05PX0RFQ0lNQUxGT1JNQVRfREVDTEFSQVRJT04sCi0gICAgICAiTm8gZGVjbGFyYXRpb24gZm91bmQgZm9yIGRlY2ltYWwgZm9ybWF0OiB7MH0ifSwKLQotICAgIHsgV0dfT0xEX1hTTFRfTlMsCi0gICAgICJNaXNzaW5nIG9yIGluY29ycmVjdCBYU0xUIE5hbWVzcGFjZS4gIn0sCi0KLSAgICB7IFdHX09ORV9ERUZBVUxUX1hTTERFQ0lNQUxGT1JNQVRfQUxMT1dFRCwKLSAgICAgICJPbmx5IG9uZSBkZWZhdWx0IHhzbDpkZWNpbWFsLWZvcm1hdCBkZWNsYXJhdGlvbiBpcyBhbGxvd2VkLiJ9LAotCi0gICAgeyBXR19YU0xERUNJTUFMRk9STUFUX05BTUVTX01VU1RfQkVfVU5JUVVFLAotICAgICAgInhzbDpkZWNpbWFsLWZvcm1hdCBuYW1lcyBtdXN0IGJlIHVuaXF1ZS4gTmFtZSBcInswfVwiIGhhcyBiZWVuIGR1cGxpY2F0ZWQuIn0sCi0KLSAgICB7IFdHX0lMTEVHQUxfQVRUUklCVVRFLAotICAgICAgInswfSBoYXMgYW4gaWxsZWdhbCBhdHRyaWJ1dGU6IHsxfSJ9LAotCi0gICAgeyBXR19DT1VMRF9OT1RfUkVTT0xWRV9QUkVGSVgsCi0gICAgICAiQ291bGQgbm90IHJlc29sdmUgbmFtZXNwYWNlIHByZWZpeDogezB9LiBUaGUgbm9kZSB3aWxsIGJlIGlnbm9yZWQuIn0sCi0KLSAgICB7IFdHX1NUWUxFU0hFRVRfUkVRVUlSRVNfVkVSU0lPTl9BVFRSSUIsCi0gICAgICAieHNsOnN0eWxlc2hlZXQgcmVxdWlyZXMgYSAndmVyc2lvbicgYXR0cmlidXRlISJ9LAotCi0gICAgeyBXR19JTExFR0FMX0FUVFJJQlVURV9OQU1FLAotICAgICAgIklsbGVnYWwgYXR0cmlidXRlIG5hbWU6IHswfSJ9LAotCi0gICAgeyBXR19JTExFR0FMX0FUVFJJQlVURV9WQUxVRSwKLSAgICAgICJJbGxlZ2FsIHZhbHVlIHVzZWQgZm9yIGF0dHJpYnV0ZSB7MH06IHsxfSJ9LAotCi0gICAgeyBXR19FTVBUWV9TRUNPTkRfQVJHLAotICAgICAgIlJlc3VsdGluZyBub2Rlc2V0IGZyb20gc2Vjb25kIGFyZ3VtZW50IG9mIGRvY3VtZW50IGZ1bmN0aW9uIGlzIGVtcHR5LiBSZXR1cm4gYW4gZW1wdHkgbm9kZS1zZXQuIn0sCi0KLSAgLy9Gb2xsb3dpbmcgYXJlIHRoZSBuZXcgV0FSTklORyBrZXlzIGFkZGVkIGluIFhBTEFOIGNvZGUgYmFzZSBhZnRlciBKZGsgMS40IChYYWxhbiAyLjItRDExKQotCi0gICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogICJuYW1lIiBhbmQgInhzbDpwcm9jZXNzaW5nLWluc3RydWN0aW9uIiBhcmUga2V5d29yZHMKLSAgICAvLyBhbmQgbXVzdCBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICB7IFdHX1BST0NFU1NJTkdJTlNUUlVDVElPTl9OQU1FX0NBTlRfQkVfWE1MLAotICAgICAgIlRoZSB2YWx1ZSBvZiB0aGUgJ25hbWUnIGF0dHJpYnV0ZSBvZiB4c2w6cHJvY2Vzc2luZy1pbnN0cnVjdGlvbiBuYW1lIG11c3Qgbm90IGJlICd4bWwnIn0sCi0KLSAgICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIm5hbWUiIGFuZCAieHNsOnByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24iIGFyZSBrZXl3b3JkcwotICAgIC8vIGFuZCBtdXN0IG5vdCBiZSB0cmFuc2xhdGVkLiAgIk5DTmFtZSIgaXMgYW4gWE1MIGRhdGEtdHlwZSBhbmQgbXVzdCBub3QgYmUKLSAgICAvLyB0cmFuc2xhdGVkLgotICAgIHsgV0dfUFJPQ0VTU0lOR0lOU1RSVUNUSU9OX05PVFZBTElEX05DTkFNRSwKLSAgICAgICJUaGUgdmFsdWUgb2YgdGhlICcnbmFtZScnIGF0dHJpYnV0ZSBvZiB4c2w6cHJvY2Vzc2luZy1pbnN0cnVjdGlvbiBtdXN0IGJlIGEgdmFsaWQgTkNOYW1lOiB7MH0ifSwKLQotICAgIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgcmVwb3J0ZWQgaWYgdGhlIHN0eWxlc2hlZXQgdGhhdCBpcwotICAgIC8vIGJlaW5nIHByb2Nlc3NlZCBhdHRlbXB0ZWQgdG8gY29uc3RydWN0IGFuIFhNTCBkb2N1bWVudCB3aXRoIGFuIGF0dHJpYnV0ZSBpbiBhCi0gICAgLy8gcGxhY2Ugb3RoZXIgdGhhbiBvbiBhbiBlbGVtZW50LiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHNwZWNpZmllcyB0aGUgbmFtZSBvZgotICAgIC8vIHRoZSBhdHRyaWJ1dGUuCi0gICAgeyBXR19JTExFR0FMX0FUVFJJQlVURV9QT1NJVElPTiwKLSAgICAgICJDYW5ub3QgYWRkIGF0dHJpYnV0ZSB7MH0gYWZ0ZXIgY2hpbGQgbm9kZXMgb3IgYmVmb3JlIGFuIGVsZW1lbnQgaXMgcHJvZHVjZWQuICBBdHRyaWJ1dGUgd2lsbCBiZSBpZ25vcmVkLiJ9LAotCi0gICAgeyBOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIsCi0gICAgICAiQW4gYXR0ZW1wdCBpcyBtYWRlIHRvIG1vZGlmeSBhbiBvYmplY3Qgd2hlcmUgbW9kaWZpY2F0aW9ucyBhcmUgbm90IGFsbG93ZWQuIgotICAgIH0sCi0KLSAgICAvL0NoZWNrOiBXSFkgVEhFUkUgSVMgQSBHQVAgQi9XIE5VTUJFUlMgaW4gdGhlIFhTTFRFcnJvclJlc291cmNlcyBwcm9wZXJ0aWVzIGZpbGU/Ci0KLSAgLy8gT3RoZXIgbWlzY2VsbGFuZW91cyB0ZXh0IHVzZWQgaW5zaWRlIHRoZSBjb2RlLi4uCi0gIHsgInVpX2xhbmd1YWdlIiwgImVuIn0sCi0gIHsgICJoZWxwX2xhbmd1YWdlIiwgICJlbiIgfSwKLSAgeyAgImxhbmd1YWdlIiwgICJlbiIgfSwKLSAgeyAiQkFEX0NPREUiLCAiUGFyYW1ldGVyIHRvIGNyZWF0ZU1lc3NhZ2Ugd2FzIG91dCBvZiBib3VuZHMifSwKLSAgeyAgIkZPUk1BVF9GQUlMRUQiLCAiRXhjZXB0aW9uIHRocm93biBkdXJpbmcgbWVzc2FnZUZvcm1hdCBjYWxsIn0sCi0gIHsgICJ2ZXJzaW9uIiwgIj4+Pj4+Pj4gWGFsYW4gVmVyc2lvbiAifSwKLSAgeyAgInZlcnNpb24yIiwgICI8PDw8PDw8In0sCi0gIHsgICJ5ZXMiLCAieWVzIn0sCi0gIHsgImxpbmUiLCAiTGluZSAjIn0sCi0gIHsgImNvbHVtbiIsIkNvbHVtbiAjIn0sCi0gIHsgInhzbGRvbmUiLCAiWFNMUHJvY2Vzc29yOiBkb25lIn0sCi0KLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlcyBwcm92aWRlIHVzYWdlIGluZm9ybWF0aW9uCi0gIC8vIGZvciB0aGUgWGFsYW4gUHJvY2VzcyBjb21tYW5kIGxpbmUuICAiUHJvY2VzcyIgaXMgdGhlIG5hbWUgb2YgYSBKYXZhIGNsYXNzLAotICAvLyBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLgotICB7ICJ4c2xQcm9jX29wdGlvbiIsICJYYWxhbi1KIGNvbW1hbmQgbGluZSBQcm9jZXNzIGNsYXNzIG9wdGlvbnM6In0sCi0gIHsgInhzbFByb2Nfb3B0aW9uIiwgIlhhbGFuLUogY29tbWFuZCBsaW5lIFByb2Nlc3MgY2xhc3Mgb3B0aW9uc1x1MDAzYSJ9LAotICB7ICJ4c2xQcm9jX2ludmFsaWRfeHNsdGNfb3B0aW9uIiwgIlRoZSBvcHRpb24gezB9IGlzIG5vdCBzdXBwb3J0ZWQgaW4gWFNMVEMgbW9kZS4ifSwKLSAgeyAieHNsUHJvY19pbnZhbGlkX3hhbGFuX29wdGlvbiIsICJUaGUgb3B0aW9uIHswfSBjYW4gb25seSBiZSB1c2VkIHdpdGggLVhTTFRDLiJ9LAotICB7ICJ4c2xQcm9jX25vX2lucHV0IiwgIkVycm9yOiBObyBzdHlsZXNoZWV0IG9yIGlucHV0IHhtbCBpcyBzcGVjaWZpZWQuIFJ1biB0aGlzIGNvbW1hbmQgd2l0aG91dCBhbnkgb3B0aW9uIGZvciB1c2FnZSBpbnN0cnVjdGlvbnMuIn0sCi0gIHsgInhzbFByb2NfY29tbW9uX29wdGlvbnMiLCAiLUNvbW1vbiBPcHRpb25zLSJ9LAotICB7ICJ4c2xQcm9jX3hhbGFuX29wdGlvbnMiLCAiLU9wdGlvbnMgZm9yIFhhbGFuLSJ9LAotICB7ICJ4c2xQcm9jX3hzbHRjX29wdGlvbnMiLCAiLU9wdGlvbnMgZm9yIFhTTFRDLSJ9LAotICB7ICJ4c2xQcm9jX3JldHVybl90b19jb250aW51ZSIsICIocHJlc3MgPHJldHVybj4gdG8gY29udGludWUpIn0sCi0KLSAgIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6IFRoZSBvcHRpb24gbmFtZSBhbmQgdGhlIHBhcmFtZXRlciBuYW1lIGRvIG5vdCBuZWVkIHRvCi0gICAvLyBiZSB0cmFuc2xhdGVkLiBPbmx5IHRyYW5zbGF0ZSB0aGUgbWVzc2FnZXMgaW4gcGFyZW50aGVzZXMuICBOb3RlIGFsc28gdGhhdAotICAgLy8gbGVhZGluZyB3aGl0ZXNwYWNlIGluIHRoZSBtZXNzYWdlcyBpcyB1c2VkIHRvIGluZGVudCB0aGUgdXNhZ2UgaW5mb3JtYXRpb24KLSAgIC8vIGZvciBlYWNoIG9wdGlvbiBpbiB0aGUgRW5nbGlzaCBtZXNzYWdlcy4KLSAgIC8vIERvIG5vdCB0cmFuc2xhdGUgdGhlIGtleXdvcmRzOiBYU0xUQywgU0FYLCBET00gYW5kIERUTS4KLSAgeyAib3B0aW9uWFNMVEMiLCAiICAgWy1YU0xUQyAodXNlIFhTTFRDIGZvciB0cmFuc2Zvcm1hdGlvbildIn0sCi0gIHsgIm9wdGlvbklOIiwgIiAgIFstSU4gaW5wdXRYTUxVUkxdIn0sCi0gIHsgIm9wdGlvblhTTCIsICIgICBbLVhTTCBYU0xUcmFuc2Zvcm1hdGlvblVSTF0ifSwKLSAgeyAib3B0aW9uT1VUIiwgICIgICBbLU9VVCBvdXRwdXRGaWxlTmFtZV0ifSwKLSAgeyAib3B0aW9uTFhDSU4iLCAiICAgWy1MWENJTiBjb21waWxlZFN0eWxlc2hlZXRGaWxlTmFtZUluXSJ9LAotICB7ICJvcHRpb25MWENPVVQiLCAiICAgWy1MWENPVVQgY29tcGlsZWRTdHlsZXNoZWV0RmlsZU5hbWVPdXRPdXRdIn0sCi0gIHsgIm9wdGlvblBBUlNFUiIsICIgICBbLVBBUlNFUiBmdWxseSBxdWFsaWZpZWQgY2xhc3MgbmFtZSBvZiBwYXJzZXIgbGlhaXNvbl0ifSwKLSAgeyAgIm9wdGlvbkUiLCAiICAgWy1FIChEbyBub3QgZXhwYW5kIGVudGl0eSByZWZzKV0ifSwKLSAgeyAgIm9wdGlvblYiLCAgIiAgIFstRSAoRG8gbm90IGV4cGFuZCBlbnRpdHkgcmVmcyldIn0sCi0gIHsgICJvcHRpb25RQyIsICIgICBbLVFDIChRdWlldCBQYXR0ZXJuIENvbmZsaWN0cyBXYXJuaW5ncyldIn0sCi0gIHsgICJvcHRpb25RIiwgIiAgIFstUSAgKFF1aWV0IE1vZGUpXSJ9LAotICB7ICAib3B0aW9uTEYiLCAiICAgWy1MRiAoVXNlIGxpbmVmZWVkcyBvbmx5IG9uIG91dHB1dCB7ZGVmYXVsdCBpcyBDUi9MRn0pXSJ9LAotICB7ICAib3B0aW9uQ1IiLCAiICAgWy1DUiAoVXNlIGNhcnJpYWdlIHJldHVybnMgb25seSBvbiBvdXRwdXQge2RlZmF1bHQgaXMgQ1IvTEZ9KV0ifSwKLSAgeyAib3B0aW9uRVNDQVBFIiwgIiAgIFstRVNDQVBFIChXaGljaCBjaGFyYWN0ZXJzIHRvIGVzY2FwZSB7ZGVmYXVsdCBpcyA8PiZcIlwnXFxyXFxufV0ifSwKLSAgeyAib3B0aW9uSU5ERU5UIiwgIiAgIFstSU5ERU5UIChDb250cm9sIGhvdyBtYW55IHNwYWNlcyB0byBpbmRlbnQge2RlZmF1bHQgaXMgMH0pXSJ9LAotICB7ICJvcHRpb25UVCIsICIgICBbLVRUIChUcmFjZSB0aGUgdGVtcGxhdGVzIGFzIHRoZXkgYXJlIGJlaW5nIGNhbGxlZC4pXSJ9LAotICB7ICJvcHRpb25URyIsICIgICBbLVRHIChUcmFjZSBlYWNoIGdlbmVyYXRpb24gZXZlbnQuKV0ifSwKLSAgeyAib3B0aW9uVFMiLCAiICAgWy1UUyAoVHJhY2UgZWFjaCBzZWxlY3Rpb24gZXZlbnQuKV0ifSwKLSAgeyAgIm9wdGlvblRUQyIsICIgICBbLVRUQyAoVHJhY2UgdGhlIHRlbXBsYXRlIGNoaWxkcmVuIGFzIHRoZXkgYXJlIGJlaW5nIHByb2Nlc3NlZC4pXSJ9LAotICB7ICJvcHRpb25UQ0xBU1MiLCAiICAgWy1UQ0xBU1MgKFRyYWNlTGlzdGVuZXIgY2xhc3MgZm9yIHRyYWNlIGV4dGVuc2lvbnMuKV0ifSwKLSAgeyAib3B0aW9uVkFMSURBVEUiLCAiICAgWy1WQUxJREFURSAoU2V0IHdoZXRoZXIgdmFsaWRhdGlvbiBvY2N1cnMuICBWYWxpZGF0aW9uIGlzIG9mZiBieSBkZWZhdWx0LildIn0sCi0gIHsgIm9wdGlvbkVEVU1QIiwgIiAgIFstRURVTVAge29wdGlvbmFsIGZpbGVuYW1lfSAoRG8gc3RhY2tkdW1wIG9uIGVycm9yLildIn0sCi0gIHsgICJvcHRpb25YTUwiLCAiICAgWy1YTUwgKFVzZSBYTUwgZm9ybWF0dGVyIGFuZCBhZGQgWE1MIGhlYWRlci4pXSJ9LAotICB7ICAib3B0aW9uVEVYVCIsICIgICBbLVRFWFQgKFVzZSBzaW1wbGUgVGV4dCBmb3JtYXR0ZXIuKV0ifSwKLSAgeyAgIm9wdGlvbkhUTUwiLCAiICAgWy1IVE1MIChVc2UgSFRNTCBmb3JtYXR0ZXIuKV0ifSwKLSAgeyAgIm9wdGlvblBBUkFNIiwgIiAgIFstUEFSQU0gbmFtZSBleHByZXNzaW9uIChTZXQgYSBzdHlsZXNoZWV0IHBhcmFtZXRlcildIn0sCi0gIHsgICJub1BhcnNlcm1zZzEiLCAiWFNMIFByb2Nlc3Mgd2FzIG5vdCBzdWNjZXNzZnVsLiJ9LAotICB7ICAibm9QYXJzZXJtc2cyIiwgIioqIENvdWxkIG5vdCBmaW5kIHBhcnNlciAqKiJ9LAotICB7ICJub1BhcnNlcm1zZzMiLCAgIlBsZWFzZSBjaGVjayB5b3VyIGNsYXNzcGF0aC4ifSwKLSAgeyAibm9QYXJzZXJtc2c0IiwgIklmIHlvdSBkb24ndCBoYXZlIElCTSdzIFhNTCBQYXJzZXIgZm9yIEphdmEsIHlvdSBjYW4gZG93bmxvYWQgaXQgZnJvbSJ9LAotICB7ICJub1BhcnNlcm1zZzUiLCAiSUJNJ3MgQWxwaGFXb3JrczogaHR0cDovL3d3dy5hbHBoYXdvcmtzLmlibS5jb20vZm9ybXVsYS94bWwifSwKLSAgeyAib3B0aW9uVVJJUkVTT0xWRVIiLCAiICAgWy1VUklSRVNPTFZFUiBmdWxsIGNsYXNzIG5hbWUgKFVSSVJlc29sdmVyIHRvIGJlIHVzZWQgdG8gcmVzb2x2ZSBVUklzKV0ifSwKLSAgeyAib3B0aW9uRU5USVRZUkVTT0xWRVIiLCAgIiAgIFstRU5USVRZUkVTT0xWRVIgZnVsbCBjbGFzcyBuYW1lIChFbnRpdHlSZXNvbHZlciB0byBiZSB1c2VkIHRvIHJlc29sdmUgZW50aXRpZXMpXSJ9LAotICB7ICJvcHRpb25DT05URU5USEFORExFUiIsICAiICAgWy1DT05URU5USEFORExFUiBmdWxsIGNsYXNzIG5hbWUgKENvbnRlbnRIYW5kbGVyIHRvIGJlIHVzZWQgdG8gc2VyaWFsaXplIG91dHB1dCldIn0sCi0gIHsgICJvcHRpb25MSU5FTlVNQkVSUyIsICAiICAgWy1MIHVzZSBsaW5lIG51bWJlcnMgZm9yIHNvdXJjZSBkb2N1bWVudF0ifSwKLSAgeyAib3B0aW9uU0VDVVJFUFJPQ0VTU0lORyIsICIgICBbLVNFQ1VSRSAoc2V0IHRoZSBzZWN1cmUgcHJvY2Vzc2luZyBmZWF0dXJlIHRvIHRydWUuKV0ifSwKLQotICAgIC8vIEZvbGxvd2luZyBhcmUgdGhlIG5ldyBvcHRpb25zIGFkZGVkIGluIFhTTFRFcnJvclJlc291cmNlcy5wcm9wZXJ0aWVzIGZpbGVzIGFmdGVyIEpkayAxLjQgKFhhbGFuIDIuMi1EMTEpCi0KLQotICB7ICAib3B0aW9uTUVESUEiLCAgIiAgIFstTUVESUEgbWVkaWFUeXBlICh1c2UgbWVkaWEgYXR0cmlidXRlIHRvIGZpbmQgc3R5bGVzaGVldCBhc3NvY2lhdGVkIHdpdGggYSBkb2N1bWVudC4pXSJ9LAotICB7ICAib3B0aW9uRkxBVk9SIiwgICIgICBbLUZMQVZPUiBmbGF2b3JOYW1lIChFeHBsaWNpdGx5IHVzZSBzMnM9U0FYIG9yIGQyZD1ET00gdG8gZG8gdHJhbnNmb3JtLildICJ9LCAvLyBBZGRlZCBieSBzYm9hZy9zY3VyY3VydTsgZXhwZXJpbWVudGFsCi0gIHsgIm9wdGlvbkRJQUciLCAiICAgWy1ESUFHIChQcmludCBvdmVyYWxsIG1pbGxpc2Vjb25kcyB0cmFuc2Zvcm0gdG9vay4pXSJ9LAotICB7ICJvcHRpb25JTkNSRU1FTlRBTCIsICAiICAgWy1JTkNSRU1FTlRBTCAocmVxdWVzdCBpbmNyZW1lbnRhbCBEVE0gY29uc3RydWN0aW9uIGJ5IHNldHRpbmcgaHR0cDovL3htbC5hcGFjaGUub3JnL3hhbGFuL2ZlYXR1cmVzL2luY3JlbWVudGFsIHRydWUuKV0ifSwKLSAgeyAgIm9wdGlvbk5PT1BUSU1JTUlaRSIsICAiICAgWy1OT09QVElNSU1JWkUgKHJlcXVlc3Qgbm8gc3R5bGVzaGVldCBvcHRpbWl6YXRpb24gcHJvY2Vzc2luZyBieSBzZXR0aW5nIGh0dHA6Ly94bWwuYXBhY2hlLm9yZy94YWxhbi9mZWF0dXJlcy9vcHRpbWl6ZSBmYWxzZS4pXSJ9LAotICB7ICJvcHRpb25STCIsICAiICAgWy1STCByZWN1cnNpb25saW1pdCAoYXNzZXJ0IG51bWVyaWMgbGltaXQgb24gc3R5bGVzaGVldCByZWN1cnNpb24gZGVwdGguKV0ifSwKLSAgeyAgICJvcHRpb25YTyIsICAiICAgWy1YTyBbdHJhbnNsZXROYW1lXSAoYXNzaWduIHRoZSBuYW1lIHRvIHRoZSBnZW5lcmF0ZWQgdHJhbnNsZXQpXSJ9LAotICB7ICAib3B0aW9uWEQiLCAiICAgWy1YRCBkZXN0aW5hdGlvbkRpcmVjdG9yeSAoc3BlY2lmeSBhIGRlc3RpbmF0aW9uIGRpcmVjdG9yeSBmb3IgdHJhbnNsZXQpXSJ9LAotICB7ICAib3B0aW9uWEoiLCAgIiAgIFstWEogamFyZmlsZSAocGFja2FnZXMgdHJhbnNsZXQgY2xhc3NlcyBpbnRvIGEgamFyIGZpbGUgb2YgbmFtZSA8amFyZmlsZT4pXSJ9LAotICB7ICAgIm9wdGlvblhQIiwgICIgICBbLVhQIHBhY2thZ2UgKHNwZWNpZmllcyBhIHBhY2thZ2UgbmFtZSBwcmVmaXggZm9yIGFsbCBnZW5lcmF0ZWQgdHJhbnNsZXQgY2xhc3NlcyldIn0sCi0KLSAgLy9BZGRJVElPTkFMICBTVFJJTkdTIHRoYXQgbmVlZCBMMTBuCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgZGVzY3JpYmVzIHVzYWdlIG9mIGEgcGFydGljdWxhcgotICAvLyBjb21tYW5kLWxpbmUgb3B0aW9uIHRoYXQgaXMgdXNlZCB0byBlbmFibGUgdGhlICJ0ZW1wbGF0ZSBpbmxpbmluZyIKLSAgLy8gb3B0aW1pemF0aW9uLiAgVGhlIG9wdGltaXphdGlvbiBpbnZvbHZlcyBtYWtpbmcgYSBjb3B5IG9mIHRoZSBjb2RlCi0gIC8vIGdlbmVyYXRlZCBmb3IgYSB0ZW1wbGF0ZSBpbiBhbm90aGVyIHRlbXBsYXRlIHRoYXQgcmVmZXJzIHRvIGl0LgotICB7ICJvcHRpb25YTiIsICAiICAgWy1YTiAoZW5hYmxlcyB0ZW1wbGF0ZSBpbmxpbmluZyldIiB9LAotICB7ICJvcHRpb25YWCIsICAiICAgWy1YWCAodHVybnMgb24gYWRkaXRpb25hbCBkZWJ1Z2dpbmcgbWVzc2FnZSBvdXRwdXQpXSJ9LAotICB7ICJvcHRpb25YVCIgLCAiICAgWy1YVCAodXNlIHRyYW5zbGV0IHRvIHRyYW5zZm9ybSBpZiBwb3NzaWJsZSldIn0sCi0gIHsgImRpYWdUaW1pbmciLCIgLS0tLS0tLS0tIFRyYW5zZm9ybSBvZiB7MH0gdmlhIHsxfSB0b29rIHsyfSBtcyIgfSwKLSAgeyAicmVjdXJzaW9uVG9vRGVlcCIsIlRlbXBsYXRlIG5lc3RpbmcgdG9vIGRlZXAuIG5lc3RpbmcgPSB7MH0sIHRlbXBsYXRlIHsxfSB7Mn0iIH0sCi0gIHsgIm5hbWVJcyIsICJuYW1lIGlzIiB9LAotICB7ICJtYXRjaFBhdHRlcm5JcyIsICJtYXRjaCBwYXR0ZXJuIGlzIiB9Ci0KLSAgfTsKLQotICB9Ci0gIC8vID09PT09PT09PT09PT09PT09IElORlJBU1RSVUNUVVJFID09PT09PT09PT09PT09PT09PT09PT0KLQotICAvKiogU3RyaW5nIGZvciB1c2Ugd2hlbiBhIGJhZCBlcnJvciBjb2RlIHdhcyBlbmNvdW50ZXJlZC4gICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQkFEX0NPREUgPSAiQkFEX0NPREUiOwotCi0gIC8qKiBTdHJpbmcgZm9yIHVzZSB3aGVuIGZvcm1hdHRpbmcgb2YgdGhlIGVycm9yIHN0cmluZyBmYWlsZWQuICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRk9STUFUX0ZBSUxFRCA9ICJGT1JNQVRfRkFJTEVEIjsKLQotICAvKiogR2VuZXJhbCBlcnJvciBzdHJpbmcuICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJST1JfU1RSSU5HID0gIiNlcnJvciI7Ci0KLSAgLyoqIFN0cmluZyB0byBwcmVwZW5kIHRvIGVycm9yIG1lc3NhZ2VzLiAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJST1JfSEVBREVSID0gIkVycm9yOiAiOwotCi0gIC8qKiBTdHJpbmcgdG8gcHJlcGVuZCB0byB3YXJuaW5nIG1lc3NhZ2VzLiAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXQVJOSU5HX0hFQURFUiA9ICJXYXJuaW5nOiAiOwotCi0gIC8qKiBTdHJpbmcgdG8gc3BlY2lmeSB0aGUgWFNMVCBtb2R1bGUuICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBYU0xfSEVBREVSID0gIlhTTFQgIjsKLQotICAvKiogU3RyaW5nIHRvIHNwZWNpZnkgdGhlIFhNTCBwYXJzZXIgbW9kdWxlLiAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MX0hFQURFUiA9ICJYTUwgIjsKLQotICAvKiogSSBkb24ndCB0aGluayB0aGlzIGlzIHVzZWQgYW55IG1vcmUuCi0gICAqIEBkZXByZWNhdGVkICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBRVUVSWV9IRUFERVIgPSAiUEFUVEVSTiAiOwotCi0KLSAgICB9CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3Jlcy9YU0xURXJyb3JSZXNvdXJjZXNfZGUuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwvcmVzL1hTTFRFcnJvclJlc291cmNlc19kZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkMWE0MDhmLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwvcmVzL1hTTFRFcnJvclJlc291cmNlc19kZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTQ0NyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC5yZXM7Ci0KLWltcG9ydCBqYXZhLnV0aWwuTGlzdFJlc291cmNlQnVuZGxlOwotaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7Ci1pbXBvcnQgamF2YS51dGlsLk1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuUmVzb3VyY2VCdW5kbGU7Ci0KLS8qKgotICogU2V0IHVwIGVycm9yIG1lc3NhZ2VzLgotICogV2UgYnVpbGQgYSB0d28gZGltZW5zaW9uYWwgYXJyYXkgb2YgbWVzc2FnZSBrZXlzIGFuZAotICogbWVzc2FnZSBzdHJpbmdzLiBJbiBvcmRlciB0byBhZGQgYSBuZXcgbWVzc2FnZSBoZXJlLAotICogeW91IG5lZWQgdG8gZmlyc3QgYWRkIGEgU3RyaW5nIGNvbnN0YW50LiBBbmQKLSAqICB5b3UgbmVlZCB0byBlbnRlciBrZXkgLCB2YWx1ZSBwYWlyIGFzIHBhcnQgb2YgY29udGVudHMKLSAqIEFycmF5LiBZb3UgYWxzbyBuZWVkIHRvIHVwZGF0ZSBNQVhfQ09ERSBmb3IgZXJyb3Igc3RyaW5ncwotICogYW5kIE1BWF9XQVJOSU5HIGZvciB3YXJuaW5ncyAoIE5lZWRlZCBmb3Igb25seSBpbmZvcm1hdGlvbgotICogcHVycG9zZSApCi0gKi8KLXB1YmxpYyBjbGFzcyBYU0xURXJyb3JSZXNvdXJjZXNfZGUgZXh0ZW5kcyBMaXN0UmVzb3VyY2VCdW5kbGUKLXsKLQotLyoKLSAqIFRoaXMgZmlsZSBjb250YWlucyBlcnJvciBhbmQgd2FybmluZyBtZXNzYWdlcyByZWxhdGVkIHRvIFhhbGFuIEVycm9yCi0gKiBIYW5kbGluZy4KLSAqCi0gKiAgR2VuZXJhbCBub3RlcyB0byB0cmFuc2xhdG9yczoKLSAqCi0gKiAgMSkgWGFsYW4gKG9yIG1vcmUgcHJvcGVybHksIFhhbGFuLWludGVycHJldGl2ZSkgYW5kIFhTTFRDIGFyZSBuYW1lcyBvZgotICogICAgIGNvbXBvbmVudHMuCi0gKiAgICAgWFNMVCBpcyBhbiBhY3JvbnltIGZvciAiWE1MIFN0eWxlc2hlZXQgTGFuZ3VhZ2U6IFRyYW5zZm9ybWF0aW9ucyIuCi0gKiAgICAgWFNMVEMgaXMgYW4gYWNyb255bSBmb3IgWFNMVCBDb21waWxlci4KLSAqCi0gKiAgMikgQSBzdHlsZXNoZWV0IGlzIGEgZGVzY3JpcHRpb24gb2YgaG93IHRvIHRyYW5zZm9ybSBhbiBpbnB1dCBYTUwgZG9jdW1lbnQKLSAqICAgICBpbnRvIGEgcmVzdWx0YW50IFhNTCBkb2N1bWVudCAob3IgSFRNTCBkb2N1bWVudCBvciB0ZXh0KS4gIFRoZQotICogICAgIHN0eWxlc2hlZXQgaXRzZWxmIGlzIGRlc2NyaWJlZCBpbiB0aGUgZm9ybSBvZiBhbiBYTUwgZG9jdW1lbnQuCi0gKgotICogIDMpIEEgdGVtcGxhdGUgaXMgYSBjb21wb25lbnQgb2YgYSBzdHlsZXNoZWV0IHRoYXQgaXMgdXNlZCB0byBtYXRjaCBhCi0gKiAgICAgcGFydGljdWxhciBwb3J0aW9uIG9mIGFuIGlucHV0IGRvY3VtZW50IGFuZCBzcGVjaWZpZXMgdGhlIGZvcm0gb2YgdGhlCi0gKiAgICAgY29ycmVzcG9uZGluZyBwb3J0aW9uIG9mIHRoZSBvdXRwdXQgZG9jdW1lbnQuCi0gKgotICogIDQpIEFuIGVsZW1lbnQgaXMgYSBtYXJrLXVwIHRhZyBpbiBhbiBYTUwgZG9jdW1lbnQ7IGFuIGF0dHJpYnV0ZSBpcyBhCi0gKiAgICAgbW9kaWZpZXIgb24gdGhlIHRhZy4gIEZvciBleGFtcGxlLCBpbiA8ZWxlbSBhdHRyPSd2YWwnIGF0dHIyPSd2YWwyJz4KLSAqICAgICAiZWxlbSIgaXMgYW4gZWxlbWVudCBuYW1lLCAiYXR0ciIgYW5kICJhdHRyMiIgYXJlIGF0dHJpYnV0ZSBuYW1lcyB3aXRoCi0gKiAgICAgdGhlIHZhbHVlcyAidmFsIiBhbmQgInZhbDIiLCByZXNwZWN0aXZlbHkuCi0gKgotICogIDUpIEEgbmFtZXNwYWNlIGRlY2xhcmF0aW9uIGlzIGEgc3BlY2lhbCBhdHRyaWJ1dGUgdGhhdCBpcyB1c2VkIHRvIGFzc29jaWF0ZQotICogICAgIGEgcHJlZml4IHdpdGggYSBVUkkgKHRoZSBuYW1lc3BhY2UpLiAgVGhlIG1lYW5pbmdzIG9mIGVsZW1lbnQgbmFtZXMgYW5kCi0gKiAgICAgYXR0cmlidXRlIG5hbWVzIHRoYXQgdXNlIHRoYXQgcHJlZml4IGFyZSBkZWZpbmVkIHdpdGggcmVzcGVjdCB0byB0aGF0Ci0gKiAgICAgbmFtZXNwYWNlLgotICoKLSAqICA2KSAiVHJhbnNsZXQiIGlzIGFuIGludmVudGVkIHRlcm0gdGhhdCBkZXNjcmliZXMgdGhlIGNsYXNzIGZpbGUgdGhhdAotICogICAgIHJlc3VsdHMgZnJvbSBjb21waWxpbmcgYW4gWE1MIHN0eWxlc2hlZXQgaW50byBhIEphdmEgY2xhc3MuCi0gKgotICogIDcpIFhQYXRoIGlzIGEgc3BlY2lmaWNhdGlvbiB0aGF0IGRlc2NyaWJlcyBhIG5vdGF0aW9uIGZvciBpZGVudGlmeWluZwotICogICAgIG5vZGVzIGluIGEgdHJlZS1zdHJ1Y3R1cmVkIHJlcHJlc2VudGF0aW9uIG9mIGFuIFhNTCBkb2N1bWVudC4gIEFuCi0gKiAgICAgaW5zdGFuY2Ugb2YgdGhhdCBub3RhdGlvbiBpcyByZWZlcnJlZCB0byBhcyBhbiBYUGF0aCBleHByZXNzaW9uLgotICoKLSAqLwotCi0gIC8qCi0gICAqIFN0YXRpYyB2YXJpYWJsZXMKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfTkFNRVNQQUNFX1VSSV9WQUxVRV9GT1JfUkVTVUxUX1BSRUZJWCA9Ci0gICAgICAgICJFUl9JTlZBTElEX1NFVF9OQU1FU1BBQ0VfVVJJX1ZBTFVFX0ZPUl9SRVNVTFRfUFJFRklYIjsKLQotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX05BTUVTUEFDRV9VUklfVkFMVUVfRk9SX1JFU1VMVF9QUkVGSVhfRk9SX0RFRkFVTFQgPQotICAgICAgICAiRVJfSU5WQUxJRF9OQU1FU1BBQ0VfVVJJX1ZBTFVFX0ZPUl9SRVNVTFRfUFJFRklYX0ZPUl9ERUZBVUxUIjsKLQotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19DVVJMWUJSQUNFID0gIkVSX05PX0NVUkxZQlJBQ0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEID0gIkVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTExFR0FMX0FUVFJJQlVURSA9ICJFUl9JTExFR0FMX0FUVFJJQlVURSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05VTExfU09VUkNFTk9ERV9BUFBMWUlNUE9SVFMgPSAiRVJfTlVMTF9TT1VSQ0VOT0RFX0FQUExZSU1QT1JUUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9BREQgPSAiRVJfQ0FOTk9UX0FERCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05VTExfU09VUkNFTk9ERV9IQU5ETEVBUFBMWVRFTVBMQVRFUz0iRVJfTlVMTF9TT1VSQ0VOT0RFX0hBTkRMRUFQUExZVEVNUExBVEVTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fTkFNRV9BVFRSSUIgPSAiRVJfTk9fTkFNRV9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9URU1QTEFURV9OT1RfRk9VTkQgPSAiRVJfVEVNUExBVEVfTk9UX0ZPVU5EIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9SRVNPTFZFX05BTUVfQVZUID0gIkVSX0NBTlRfUkVTT0xWRV9OQU1FX0FWVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1JFUVVJUkVTX0FUVFJJQiA9ICJFUl9SRVFVSVJFU19BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9NVVNUX0hBVkVfVEVTVF9BVFRSSUIgPSAiRVJfTVVTVF9IQVZFX1RFU1RfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQkFEX1ZBTF9PTl9MRVZFTF9BVFRSSUIgPQotICAgICAgICAgIkVSX0JBRF9WQUxfT05fTEVWRUxfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJPQ0VTU0lOR0lOU1RSVUNUSU9OX05BTUVfQ0FOVF9CRV9YTUwgPQotICAgICAgICAgIkVSX1BST0NFU1NJTkdJTlNUUlVDVElPTl9OQU1FX0NBTlRfQkVfWE1MIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJPQ0VTU0lOR0lOU1RSVUNUSU9OX05PVFZBTElEX05DTkFNRSA9Ci0gICAgICAgICAiRVJfUFJPQ0VTU0lOR0lOU1RSVUNUSU9OX05PVFZBTElEX05DTkFNRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05FRURfTUFUQ0hfQVRUUklCID0gIkVSX05FRURfTUFUQ0hfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTkVFRF9OQU1FX09SX01BVENIX0FUVFJJQiA9Ci0gICAgICAgICAiRVJfTkVFRF9OQU1FX09SX01BVENIX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfUkVTT0xWRV9OU1BSRUZJWCA9Ci0gICAgICAgICAiRVJfQ0FOVF9SRVNPTFZFX05TUFJFRklYIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSUxMRUdBTF9WQUxVRSA9ICJFUl9JTExFR0FMX1ZBTFVFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fT1dORVJET0MgPSAiRVJfTk9fT1dORVJET0MiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FTEVNVEVNUExBVEVFTEVNX0VSUiA9IkVSX0VMRU1URU1QTEFURUVMRU1fRVJSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTlVMTF9DSElMRCA9ICJFUl9OVUxMX0NISUxEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTkVFRF9TRUxFQ1RfQVRUUklCID0gIkVSX05FRURfU0VMRUNUX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05FRURfVEVTVF9BVFRSSUIgPSAiRVJfTkVFRF9URVNUX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05FRURfTkFNRV9BVFRSSUIgPSAiRVJfTkVFRF9OQU1FX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX0NPTlRFWFRfT1dORVJET0MgPSAiRVJfTk9fQ09OVEVYVF9PV05FUkRPQyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxEX05PVF9DUkVBVEVfWE1MX1BST0NfTElBSVNPTiA9Ci0gICAgICAgICAiRVJfQ09VTERfTk9UX0NSRUFURV9YTUxfUFJPQ19MSUFJU09OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJPQ0VTU19OT1RfU1VDQ0VTU0ZVTCA9Ci0gICAgICAgICAiRVJfUFJPQ0VTU19OT1RfU1VDQ0VTU0ZVTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PVF9TVUNDRVNTRlVMID0gIkVSX05PVF9TVUNDRVNTRlVMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRU5DT0RJTkdfTk9UX1NVUFBPUlRFRCA9Ci0gICAgICAgICAiRVJfRU5DT0RJTkdfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxEX05PVF9DUkVBVEVfVFJBQ0VMSVNURU5FUiA9Ci0gICAgICAgICAiRVJfQ09VTERfTk9UX0NSRUFURV9UUkFDRUxJU1RFTkVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfS0VZX1JFUVVJUkVTX05BTUVfQVRUUklCID0KLSAgICAgICAgICJFUl9LRVlfUkVRVUlSRVNfTkFNRV9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9LRVlfUkVRVUlSRVNfTUFUQ0hfQVRUUklCID0KLSAgICAgICAgICJFUl9LRVlfUkVRVUlSRVNfTUFUQ0hfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfS0VZX1JFUVVJUkVTX1VTRV9BVFRSSUIgPQotICAgICAgICAgIkVSX0tFWV9SRVFVSVJFU19VU0VfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUkVRVUlSRVNfRUxFTUVOVFNfQVRUUklCID0KLSAgICAgICAgICJFUl9SRVFVSVJFU19FTEVNRU5UU19BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9NSVNTSU5HX1BSRUZJWF9BVFRSSUIgPQotICAgICAgICAgIkVSX01JU1NJTkdfUFJFRklYX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0JBRF9TVFlMRVNIRUVUX1VSTCA9ICJFUl9CQURfU1RZTEVTSEVFVF9VUkwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GSUxFX05PVF9GT1VORCA9ICJFUl9GSUxFX05PVF9GT1VORCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lPRVhDRVBUSU9OID0gIkVSX0lPRVhDRVBUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fSFJFRl9BVFRSSUIgPSAiRVJfTk9fSFJFRl9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TVFlMRVNIRUVUX0lOQ0xVREVTX0lUU0VMRiA9Ci0gICAgICAgICAiRVJfU1RZTEVTSEVFVF9JTkNMVURFU19JVFNFTEYiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUk9DRVNTSU5DTFVERV9FUlJPUiA9IkVSX1BST0NFU1NJTkNMVURFX0VSUk9SIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTUlTU0lOR19MQU5HX0FUVFJJQiA9ICJFUl9NSVNTSU5HX0xBTkdfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTUlTU0lOR19DT05UQUlORVJfRUxFTUVOVF9DT01QT05FTlQgPQotICAgICAgICAgIkVSX01JU1NJTkdfQ09OVEFJTkVSX0VMRU1FTlRfQ09NUE9ORU5UIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOX09OTFlfT1VUUFVUX1RPX0VMRU1FTlQgPQotICAgICAgICAgIkVSX0NBTl9PTkxZX09VVFBVVF9UT19FTEVNRU5UIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJPQ0VTU19FUlJPUiA9ICJFUl9QUk9DRVNTX0VSUk9SIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5JTVBMTk9ERV9FUlJPUiA9ICJFUl9VTklNUExOT0RFX0VSUk9SIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fU0VMRUNUX0VYUFJFU1NJT04gPSJFUl9OT19TRUxFQ1RfRVhQUkVTU0lPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9TRVJJQUxJWkVfWFNMUFJPQ0VTU09SID0KLSAgICAgICAgICJFUl9DQU5OT1RfU0VSSUFMSVpFX1hTTFBST0NFU1NPUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX0lOUFVUX1NUWUxFU0hFRVQgPSAiRVJfTk9fSU5QVVRfU1RZTEVTSEVFVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZBSUxFRF9QUk9DRVNTX1NUWUxFU0hFRVQgPQotICAgICAgICAgIkVSX0ZBSUxFRF9QUk9DRVNTX1NUWUxFU0hFRVQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRE5UX1BBUlNFX0RPQyA9ICJFUl9DT1VMRE5UX1BBUlNFX0RPQyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxETlRfRklORF9GUkFHTUVOVCA9Ci0gICAgICAgICAiRVJfQ09VTEROVF9GSU5EX0ZSQUdNRU5UIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9ERV9OT1RfRUxFTUVOVCA9ICJFUl9OT0RFX05PVF9FTEVNRU5UIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRk9SRUFDSF9ORUVEX01BVENIX09SX05BTUVfQVRUUklCID0KLSAgICAgICAgICJFUl9GT1JFQUNIX05FRURfTUFUQ0hfT1JfTkFNRV9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9URU1QTEFURVNfTkVFRF9NQVRDSF9PUl9OQU1FX0FUVFJJQiA9Ci0gICAgICAgICAiRVJfVEVNUExBVEVTX05FRURfTUFUQ0hfT1JfTkFNRV9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19DTE9ORV9PRl9ET0NVTUVOVF9GUkFHID0KLSAgICAgICAgICJFUl9OT19DTE9ORV9PRl9ET0NVTUVOVF9GUkFHIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9DUkVBVEVfSVRFTSA9ICJFUl9DQU5UX0NSRUFURV9JVEVNIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWE1MU1BBQ0VfSUxMRUdBTF9WQUxVRSA9Ci0gICAgICAgICAiRVJfWE1MU1BBQ0VfSUxMRUdBTF9WQUxVRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1hTTEtFWV9ERUNMQVJBVElPTiA9Ci0gICAgICAgICAiRVJfTk9fWFNMS0VZX0RFQ0xBUkFUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9DUkVBVEVfVVJMID0gIkVSX0NBTlRfQ1JFQVRFX1VSTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hTTEZVTkNUSU9OU19VTlNVUFBPUlRFRCA9Ci0gICAgICAgICAiRVJfWFNMRlVOQ1RJT05TX1VOU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJPQ0VTU09SX0VSUk9SID0gIkVSX1BST0NFU1NPUl9FUlJPUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PVF9BTExPV0VEX0lOU0lERV9TVFlMRVNIRUVUID0KLSAgICAgICAgICJFUl9OT1RfQUxMT1dFRF9JTlNJREVfU1RZTEVTSEVFVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1JFU1VMVE5TX05PVF9TVVBQT1JURUQgPQotICAgICAgICAgIkVSX1JFU1VMVE5TX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9ERUZBVUxUU1BBQ0VfTk9UX1NVUFBPUlRFRCA9Ci0gICAgICAgICAiRVJfREVGQVVMVFNQQUNFX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTkRFTlRSRVNVTFRfTk9UX1NVUFBPUlRFRCA9Ci0gICAgICAgICAiRVJfSU5ERU5UUkVTVUxUX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTExFR0FMX0FUVFJJQiA9ICJFUl9JTExFR0FMX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1VOS05PV05fWFNMX0VMRU0gPSAiRVJfVU5LTk9XTl9YU0xfRUxFTSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0JBRF9YU0xTT1JUX1VTRSA9ICJFUl9CQURfWFNMU09SVF9VU0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9NSVNQTEFDRURfWFNMV0hFTiA9ICJFUl9NSVNQTEFDRURfWFNMV0hFTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hTTFdIRU5fTk9UX1BBUkVOVEVEX0JZX1hTTENIT09TRSA9Ci0gICAgICAgICAiRVJfWFNMV0hFTl9OT1RfUEFSRU5URURfQllfWFNMQ0hPT1NFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTUlTUExBQ0VEX1hTTE9USEVSV0lTRSA9Ci0gICAgICAgICAiRVJfTUlTUExBQ0VEX1hTTE9USEVSV0lTRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hTTE9USEVSV0lTRV9OT1RfUEFSRU5URURfQllfWFNMQ0hPT1NFID0KLSAgICAgICAgICJFUl9YU0xPVEhFUldJU0VfTk9UX1BBUkVOVEVEX0JZX1hTTENIT09TRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PVF9BTExPV0VEX0lOU0lERV9URU1QTEFURSA9Ci0gICAgICAgICAiRVJfTk9UX0FMTE9XRURfSU5TSURFX1RFTVBMQVRFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5LTk9XTl9FWFRfTlNfUFJFRklYID0KLSAgICAgICAgICJFUl9VTktOT1dOX0VYVF9OU19QUkVGSVgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTVBPUlRTX0FTX0ZJUlNUX0VMRU0gPQotICAgICAgICAgIkVSX0lNUE9SVFNfQVNfRklSU1RfRUxFTSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lNUE9SVElOR19JVFNFTEYgPSAiRVJfSU1QT1JUSU5HX0lUU0VMRiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hNTFNQQUNFX0lMTEVHQUxfVkFMID0iRVJfWE1MU1BBQ0VfSUxMRUdBTF9WQUwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUk9DRVNTU1RZTEVTSEVFVF9OT1RfU1VDQ0VTU0ZVTCA9Ci0gICAgICAgICAiRVJfUFJPQ0VTU1NUWUxFU0hFRVRfTk9UX1NVQ0NFU1NGVUwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TQVhfRVhDRVBUSU9OID0gIkVSX1NBWF9FWENFUFRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YU0xUX0VSUk9SID0gIkVSX1hTTFRfRVJST1IiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DVVJSRU5DWV9TSUdOX0lMTEVHQUw9Ci0gICAgICAgICAiRVJfQ1VSUkVOQ1lfU0lHTl9JTExFR0FMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRE9DVU1FTlRfRlVOQ1RJT05fSU5WQUxJRF9JTl9TVFlMRVNIRUVUX0RPTSA9Ci0gICAgICAgICAiRVJfRE9DVU1FTlRfRlVOQ1RJT05fSU5WQUxJRF9JTl9TVFlMRVNIRUVUX0RPTSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfUkVTT0xWRV9QUkVGSVhfT0ZfTk9OX1BSRUZJWF9SRVNPTFZFUiA9Ci0gICAgICAgICAiRVJfQ0FOVF9SRVNPTFZFX1BSRUZJWF9PRl9OT05fUFJFRklYX1JFU09MVkVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUkVESVJFQ1RfQ09VTEROVF9HRVRfRklMRU5BTUUgPQotICAgICAgICAgIkVSX1JFRElSRUNUX0NPVUxETlRfR0VUX0ZJTEVOQU1FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX0JVSUxEX0ZPUk1BVFRFUkxJU1RFTkVSX0lOX1JFRElSRUNUID0KLSAgICAgICAgICJFUl9DQU5OT1RfQlVJTERfRk9STUFUVEVSTElTVEVORVJfSU5fUkVESVJFQ1QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX1BSRUZJWF9JTl9FWENMVURFUkVTVUxUUFJFRklYID0KLSAgICAgICAgICJFUl9JTlZBTElEX1BSRUZJWF9JTl9FWENMVURFUkVTVUxUUFJFRklYIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTUlTU0lOR19OU19VUkkgPSAiRVJfTUlTU0lOR19OU19VUkkiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9NSVNTSU5HX0FSR19GT1JfT1BUSU9OID0KLSAgICAgICAgICJFUl9NSVNTSU5HX0FSR19GT1JfT1BUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9PUFRJT04gPSAiRVJfSU5WQUxJRF9PUFRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9NQUxGT1JNRURfRk9STUFUX1NUUklORyA9Ci0gICAgICAgICAiRVJfTUFMRk9STUVEX0ZPUk1BVF9TVFJJTkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TVFlMRVNIRUVUX1JFUVVJUkVTX1ZFUlNJT05fQVRUUklCID0KLSAgICAgICAgICJFUl9TVFlMRVNIRUVUX1JFUVVJUkVTX1ZFUlNJT05fQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSUxMRUdBTF9BVFRSSUJVVEVfVkFMVUUgPQotICAgICAgICAgIkVSX0lMTEVHQUxfQVRUUklCVVRFX1ZBTFVFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0hPT1NFX1JFUVVJUkVTX1dIRU4gPSJFUl9DSE9PU0VfUkVRVUlSRVNfV0hFTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX0FQUExZX0lNUE9SVF9JTl9GT1JfRUFDSCA9Ci0gICAgICAgICAiRVJfTk9fQVBQTFlfSU1QT1JUX0lOX0ZPUl9FQUNIIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9VU0VfRFRNX0ZPUl9PVVRQVVQgPQotICAgICAgICAgIkVSX0NBTlRfVVNFX0RUTV9GT1JfT1VUUFVUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9VU0VfRFRNX0ZPUl9JTlBVVCA9Ci0gICAgICAgICAiRVJfQ0FOVF9VU0VfRFRNX0ZPUl9JTlBVVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTExfVE9fRVhUX0ZBSUxFRCA9ICJFUl9DQUxMX1RPX0VYVF9GQUlMRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUkVGSVhfTVVTVF9SRVNPTFZFID0gIkVSX1BSRUZJWF9NVVNUX1JFU09MVkUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX1VURjE2X1NVUlJPR0FURSA9Ci0gICAgICAgICAiRVJfSU5WQUxJRF9VVEYxNl9TVVJST0dBVEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YU0xBVFRSU0VUX1VTRURfSVRTRUxGID0KLSAgICAgICAgICJFUl9YU0xBVFRSU0VUX1VTRURfSVRTRUxGIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX01JWF9YRVJDRVNET00gPSJFUl9DQU5OT1RfTUlYX1hFUkNFU0RPTSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1RPT19NQU5ZX0xJU1RFTkVSUyA9ICJFUl9UT09fTUFOWV9MSVNURU5FUlMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTl9FTEVNVEVNUExBVEVFTEVNX1JFQURPQkpFQ1QgPQotICAgICAgICAgIkVSX0lOX0VMRU1URU1QTEFURUVMRU1fUkVBRE9CSkVDVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0RVUExJQ0FURV9OQU1FRF9URU1QTEFURSA9Ci0gICAgICAgICAiRVJfRFVQTElDQVRFX05BTUVEX1RFTVBMQVRFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9LRVlfQ0FMTCA9ICJFUl9JTlZBTElEX0tFWV9DQUxMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUkVGRVJFTkNJTkdfSVRTRUxGID0gIkVSX1JFRkVSRU5DSU5HX0lUU0VMRiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lMTEVHQUxfRE9NU09VUkNFX0lOUFVUID0KLSAgICAgICAgICJFUl9JTExFR0FMX0RPTVNPVVJDRV9JTlBVVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NMQVNTX05PVF9GT1VORF9GT1JfT1BUSU9OID0KLSAgICAgICAgICJFUl9DTEFTU19OT1RfRk9VTkRfRk9SX09QVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1JFUVVJUkVEX0VMRU1fTk9UX0ZPVU5EID0KLSAgICAgICAgICJFUl9SRVFVSVJFRF9FTEVNX05PVF9GT1VORCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOUFVUX0NBTk5PVF9CRV9OVUxMID0iRVJfSU5QVVRfQ0FOTk9UX0JFX05VTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VUklfQ0FOTk9UX0JFX05VTEwgPSAiRVJfVVJJX0NBTk5PVF9CRV9OVUxMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRklMRV9DQU5OT1RfQkVfTlVMTCA9ICJFUl9GSUxFX0NBTk5PVF9CRV9OVUxMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU09VUkNFX0NBTk5PVF9CRV9OVUxMID0KLSAgICAgICAgICJFUl9TT1VSQ0VfQ0FOTk9UX0JFX05VTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfSU5JVF9CU0ZNR1IgPSAiRVJfQ0FOTk9UX0lOSVRfQlNGTUdSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX0NNUExfRVhURU5TTiA9ICJFUl9DQU5OT1RfQ01QTF9FWFRFTlNOIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX0NSRUFURV9FWFRFTlNOID0KLSAgICAgICAgICJFUl9DQU5OT1RfQ1JFQVRFX0VYVEVOU04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlNUQU5DRV9NVEhEX0NBTExfUkVRVUlSRVMgPQotICAgICAgICAgIkVSX0lOU1RBTkNFX01USERfQ0FMTF9SRVFVSVJFUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfRUxFTUVOVF9OQU1FID0iRVJfSU5WQUxJRF9FTEVNRU5UX05BTUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FTEVNRU5UX05BTUVfTUVUSE9EX1NUQVRJQyA9Ci0gICAgICAgICAiRVJfRUxFTUVOVF9OQU1FX01FVEhPRF9TVEFUSUMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FWFRFTlNJT05fRlVOQ19VTktOT1dOID0KLSAgICAgICAgICJFUl9FWFRFTlNJT05fRlVOQ19VTktOT1dOIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTU9SRV9NQVRDSF9DT05TVFJVQ1RPUiA9Ci0gICAgICAgICAiRVJfTU9SRV9NQVRDSF9DT05TVFJVQ1RPUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01PUkVfTUFUQ0hfTUVUSE9EID0gIkVSX01PUkVfTUFUQ0hfTUVUSE9EIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTU9SRV9NQVRDSF9FTEVNRU5UID0gIkVSX01PUkVfTUFUQ0hfRUxFTUVOVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfQ09OVEVYVF9QQVNTRUQgPQotICAgICAgICAgIkVSX0lOVkFMSURfQ09OVEVYVF9QQVNTRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QT09MX0VYSVNUUyA9ICJFUl9QT09MX0VYSVNUUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX0RSSVZFUl9OQU1FID0gIkVSX05PX0RSSVZFUl9OQU1FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fVVJMID0gIkVSX05PX1VSTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BPT0xfU0laRV9MRVNTVEhBTl9PTkUgPQotICAgICAgICAgIkVSX1BPT0xfU0laRV9MRVNTVEhBTl9PTkUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX0RSSVZFUiA9ICJFUl9JTlZBTElEX0RSSVZFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1NUWUxFU0hFRVRST09UID0gIkVSX05PX1NUWUxFU0hFRVRST09UIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSUxMRUdBTF9YTUxTUEFDRV9WQUxVRSA9Ci0gICAgICAgICAiRVJfSUxMRUdBTF9YTUxTUEFDRV9WQUxVRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BST0NFU1NGUk9NTk9ERV9GQUlMRUQgPQotICAgICAgICAgIkVSX1BST0NFU1NGUk9NTk9ERV9GQUlMRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SRVNPVVJDRV9DT1VMRF9OT1RfTE9BRCA9Ci0gICAgICAgICAiRVJfUkVTT1VSQ0VfQ09VTERfTk9UX0xPQUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9CVUZGRVJfU0laRV9MRVNTVEhBTl9aRVJPID0KLSAgICAgICAgICJFUl9CVUZGRVJfU0laRV9MRVNTVEhBTl9aRVJPIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5LTk9XTl9FUlJPUl9DQUxMSU5HX0VYVEVOU0lPTiA9Ci0gICAgICAgICAiRVJfVU5LTk9XTl9FUlJPUl9DQUxMSU5HX0VYVEVOU0lPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX05BTUVTUEFDRV9ERUNMID0gIkVSX05PX05BTUVTUEFDRV9ERUNMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRUxFTV9DT05URU5UX05PVF9BTExPV0VEID0KLSAgICAgICAgICJFUl9FTEVNX0NPTlRFTlRfTk9UX0FMTE9XRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TVFlMRVNIRUVUX0RJUkVDVEVEX1RFUk1JTkFUSU9OID0KLSAgICAgICAgICJFUl9TVFlMRVNIRUVUX0RJUkVDVEVEX1RFUk1JTkFUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfT05FX09SX1RXTyA9ICJFUl9PTkVfT1JfVFdPIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVFdPX09SX1RIUkVFID0gIkVSX1RXT19PUl9USFJFRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxEX05PVF9MT0FEX1JFU09VUkNFID0KLSAgICAgICAgICJFUl9DT1VMRF9OT1RfTE9BRF9SRVNPVVJDRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9JTklUX0RFRkFVTFRfVEVNUExBVEVTID0KLSAgICAgICAgICJFUl9DQU5OT1RfSU5JVF9ERUZBVUxUX1RFTVBMQVRFUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1JFU1VMVF9OVUxMID0gIkVSX1JFU1VMVF9OVUxMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUkVTVUxUX0NPVUxEX05PVF9CRV9TRVQgPQotICAgICAgICAgIkVSX1JFU1VMVF9DT1VMRF9OT1RfQkVfU0VUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fT1VUUFVUX1NQRUNJRklFRCA9ICJFUl9OT19PVVRQVVRfU1BFQ0lGSUVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX1RSQU5TRk9STV9UT19SRVNVTFRfVFlQRSA9Ci0gICAgICAgICAiRVJfQ0FOTk9UX1RSQU5TRk9STV9UT19SRVNVTFRfVFlQRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9UUkFOU0ZPUk1fU09VUkNFX1RZUEUgPQotICAgICAgICAgIkVSX0NBTk5PVF9UUkFOU0ZPUk1fU09VUkNFX1RZUEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OVUxMX0NPTlRFTlRfSEFORExFUiA9IkVSX05VTExfQ09OVEVOVF9IQU5ETEVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTlVMTF9FUlJPUl9IQU5ETEVSID0gIkVSX05VTExfRVJST1JfSEFORExFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9DQUxMX1BBUlNFID0gIkVSX0NBTk5PVF9DQUxMX1BBUlNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fUEFSRU5UX0ZPUl9GSUxURVIgPSJFUl9OT19QQVJFTlRfRk9SX0ZJTFRFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1NUWUxFU0hFRVRfSU5fTUVESUEgPQotICAgICAgICAgIkVSX05PX1NUWUxFU0hFRVRfSU5fTUVESUEiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19TVFlMRVNIRUVUX1BJID0gIkVSX05PX1NUWUxFU0hFRVRfUEkiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT1RfU1VQUE9SVEVEID0gIkVSX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUk9QRVJUWV9WQUxVRV9CT09MRUFOID0KLSAgICAgICAgICJFUl9QUk9QRVJUWV9WQUxVRV9CT09MRUFOIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTERfTk9UX0ZJTkRfRVhURVJOX1NDUklQVCA9Ci0gICAgICAgICAiRVJfQ09VTERfTk9UX0ZJTkRfRVhURVJOX1NDUklQVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1JFU09VUkNFX0NPVUxEX05PVF9GSU5EID0KLSAgICAgICAgICJFUl9SRVNPVVJDRV9DT1VMRF9OT1RfRklORCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX09VVFBVVF9QUk9QRVJUWV9OT1RfUkVDT0dOSVpFRCA9Ci0gICAgICAgICAiRVJfT1VUUFVUX1BST1BFUlRZX05PVF9SRUNPR05JWkVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRkFJTEVEX0NSRUFUSU5HX0VMRU1MSVRSU0xUID0KLSAgICAgICAgICJFUl9GQUlMRURfQ1JFQVRJTkdfRUxFTUxJVFJTTFQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9WQUxVRV9TSE9VTERfQkVfTlVNQkVSID0KLSAgICAgICAgICJFUl9WQUxVRV9TSE9VTERfQkVfTlVNQkVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVkFMVUVfU0hPVUxEX0VRVUFMID0gIkVSX1ZBTFVFX1NIT1VMRF9FUVVBTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZBSUxFRF9DQUxMSU5HX01FVEhPRCA9Ci0gICAgICAgICAiRVJfRkFJTEVEX0NBTExJTkdfTUVUSE9EIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRkFJTEVEX0NSRUFUSU5HX0VMRU1UTVBMID0KLSAgICAgICAgICJFUl9GQUlMRURfQ1JFQVRJTkdfRUxFTVRNUEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DSEFSU19OT1RfQUxMT1dFRCA9ICJFUl9DSEFSU19OT1RfQUxMT1dFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FUVFJfTk9UX0FMTE9XRUQgPSAiRVJfQVRUUl9OT1RfQUxMT1dFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0JBRF9WQUxVRSA9ICJFUl9CQURfVkFMVUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9BVFRSSUJfVkFMVUVfTk9UX0ZPVU5EID0KLSAgICAgICAgICJFUl9BVFRSSUJfVkFMVUVfTk9UX0ZPVU5EIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQVRUUklCX1ZBTFVFX05PVF9SRUNPR05JWkVEID0KLSAgICAgICAgICJFUl9BVFRSSUJfVkFMVUVfTk9UX1JFQ09HTklaRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OVUxMX1VSSV9OQU1FU1BBQ0UgPSAiRVJfTlVMTF9VUklfTkFNRVNQQUNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTlVNQkVSX1RPT19CSUcgPSAiRVJfTlVNQkVSX1RPT19CSUciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyAgRVJfQ0FOTk9UX0ZJTkRfU0FYMV9EUklWRVIgPQotICAgICAgICAgIkVSX0NBTk5PVF9GSU5EX1NBWDFfRFJJVkVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgIEVSX1NBWDFfRFJJVkVSX05PVF9MT0FERUQgPQotICAgICAgICAgIkVSX1NBWDFfRFJJVkVSX05PVF9MT0FERUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyAgRVJfU0FYMV9EUklWRVJfTk9UX0lOU1RBTlRJQVRFRCA9Ci0gICAgICAgICAiRVJfU0FYMV9EUklWRVJfTk9UX0lOU1RBTlRJQVRFRCIgOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TQVgxX0RSSVZFUl9OT1RfSU1QTEVNRU5UX1BBUlNFUiA9Ci0gICAgICAgICAiRVJfU0FYMV9EUklWRVJfTk9UX0lNUExFTUVOVF9QQVJTRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyAgRVJfUEFSU0VSX1BST1BFUlRZX05PVF9TUEVDSUZJRUQgPQotICAgICAgICAgIkVSX1BBUlNFUl9QUk9QRVJUWV9OT1RfU1BFQ0lGSUVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgIEVSX1BBUlNFUl9BUkdfQ0FOTk9UX0JFX05VTEwgPQotICAgICAgICAgIkVSX1BBUlNFUl9BUkdfQ0FOTk9UX0JFX05VTEwiIDsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgIEVSX0ZFQVRVUkUgPSAiRVJfRkVBVFVSRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BST1BFUlRZID0gIkVSX1BST1BFUlRZIiA7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05VTExfRU5USVRZX1JFU09MVkVSID0iRVJfTlVMTF9FTlRJVFlfUkVTT0xWRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyAgRVJfTlVMTF9EVERfSEFORExFUiA9ICJFUl9OVUxMX0RURF9IQU5ETEVSIiA7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX0RSSVZFUl9OQU1FX1NQRUNJRklFRCA9Ci0gICAgICAgICAiRVJfTk9fRFJJVkVSX05BTUVfU1BFQ0lGSUVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fVVJMX1NQRUNJRklFRCA9ICJFUl9OT19VUkxfU1BFQ0lGSUVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUE9PTFNJWkVfTEVTU19USEFOX09ORSA9Ci0gICAgICAgICAiRVJfUE9PTFNJWkVfTEVTU19USEFOX09ORSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfRFJJVkVSX05BTUUgPSAiRVJfSU5WQUxJRF9EUklWRVJfTkFNRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VSUk9STElTVEVORVIgPSAiRVJfRVJST1JMSVNURU5FUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FTU0VSVF9OT19URU1QTEFURV9QQVJFTlQgPQotICAgICAgICAgIkVSX0FTU0VSVF9OT19URU1QTEFURV9QQVJFTlQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9BU1NFUlRfUkVEVU5ERU5UX0VYUFJfRUxJTUlOQVRPUiA9Ci0gICAgICAgICAiRVJfQVNTRVJUX1JFRFVOREVOVF9FWFBSX0VMSU1JTkFUT1IiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT1RfQUxMT1dFRF9JTl9QT1NJVElPTiA9Ci0gICAgICAgICAiRVJfTk9UX0FMTE9XRURfSU5fUE9TSVRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT05XSElURVNQQUNFX05PVF9BTExPV0VEX0lOX1BPU0lUSU9OID0KLSAgICAgICAgICJFUl9OT05XSElURVNQQUNFX05PVF9BTExPV0VEX0lOX1BPU0lUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTkFNRVNQQUNFX0NPTlRFWFRfTlVMTF9OQU1FU1BBQ0UgPQotICAgICAgICAgIkVSX05BTUVTUEFDRV9DT05URVhUX05VTExfTkFNRVNQQUNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTkFNRVNQQUNFX0NPTlRFWFRfTlVMTF9QUkVGSVggPQotICAgICAgICAgIkVSX05BTUVTUEFDRV9DT05URVhUX05VTExfUFJFRklYIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWFBBVEhfUkVTT0xWRVJfTlVMTF9RTkFNRSA9Ci0gICAgICAgICAiRVJfWFBBVEhfUkVTT0xWRVJfTlVMTF9RTkFNRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hQQVRIX1JFU09MVkVSX05FR0FUSVZFX0FSSVRZID0KLSAgICAgICAgICJFUl9YUEFUSF9SRVNPTFZFUl9ORUdBVElWRV9BUklUWSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIElOVkFMSURfVENIQVIgPSAiSU5WQUxJRF9UQ0hBUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIElOVkFMSURfUU5BTUUgPSAiSU5WQUxJRF9RTkFNRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIElOVkFMSURfRU5VTSA9ICJJTlZBTElEX0VOVU0iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBJTlZBTElEX05NVE9LRU4gPSAiSU5WQUxJRF9OTVRPS0VOIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSU5WQUxJRF9OQ05BTUUgPSAiSU5WQUxJRF9OQ05BTUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBJTlZBTElEX0JPT0xFQU4gPSAiSU5WQUxJRF9CT09MRUFOIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSU5WQUxJRF9OVU1CRVIgPSAiSU5WQUxJRF9OVU1CRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9BUkdfTElURVJBTCA9ICJFUl9BUkdfTElURVJBTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0RVUExJQ0FURV9HTE9CQUxfVkFSID0iRVJfRFVQTElDQVRFX0dMT0JBTF9WQVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9EVVBMSUNBVEVfVkFSID0gIkVSX0RVUExJQ0FURV9WQVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9URU1QTEFURV9OQU1FX01BVENIID0gIkVSX1RFTVBMQVRFX05BTUVfTUFUQ0giOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX1BSRUZJWCA9ICJFUl9JTlZBTElEX1BSRUZJWCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX0FUVFJJQl9TRVQgPSAiRVJfTk9fQVRUUklCX1NFVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZVTkNUSU9OX05PVF9GT1VORCA9Ci0gICAgICAgICAiRVJfRlVOQ1RJT05fTk9UX0ZPVU5EIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9IQVZFX0NPTlRFTlRfQU5EX1NFTEVDVCA9Ci0gICAgICJFUl9DQU5UX0hBVkVfQ09OVEVOVF9BTkRfU0VMRUNUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9TRVRfUEFSQU1fVkFMVUUgPSAiRVJfSU5WQUxJRF9TRVRfUEFSQU1fVkFMVUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TRVRfRkVBVFVSRV9OVUxMX05BTUUgPQotICAgICAgICAiRVJfU0VUX0ZFQVRVUkVfTlVMTF9OQU1FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfR0VUX0ZFQVRVUkVfTlVMTF9OQU1FID0KLSAgICAgICAgIkVSX0dFVF9GRUFUVVJFX05VTExfTkFNRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1VOU1VQUE9SVEVEX0ZFQVRVUkUgPQotICAgICAgICAiRVJfVU5TVVBQT1JURURfRkVBVFVSRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYVEVOU0lPTl9FTEVNRU5UX05PVF9BTExPV0VEX0lOX1NFQ1VSRV9QUk9DRVNTSU5HID0KLSAgICAgICAgIkVSX0VYVEVOU0lPTl9FTEVNRU5UX05PVF9BTExPV0VEX0lOX1NFQ1VSRV9QUk9DRVNTSU5HIjsKLQotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19GT1VORF9DVVJMWUJSQUNFID0gIldHX0ZPVU5EX0NVUkxZQlJBQ0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19DT1VOVF9BVFRSSUJfTUFUQ0hFU19OT19BTkNFU1RPUiA9Ci0gICAgICAgICAiV0dfQ09VTlRfQVRUUklCX01BVENIRVNfTk9fQU5DRVNUT1IiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19FWFBSX0FUVFJJQl9DSEFOR0VEX1RPX1NFTEVDVCA9Ci0gICAgICAgICAiV0dfRVhQUl9BVFRSSUJfQ0hBTkdFRF9UT19TRUxFQ1QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19OT19MT0NBTEVfSU5fRk9STUFUTlVNQkVSID0KLSAgICAgICAgICJXR19OT19MT0NBTEVfSU5fRk9STUFUTlVNQkVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfTE9DQUxFX05PVF9GT1VORCA9ICJXR19MT0NBTEVfTk9UX0ZPVU5EIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfQ0FOTk9UX01BS0VfVVJMX0ZST00gPSJXR19DQU5OT1RfTUFLRV9VUkxfRlJPTSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0NBTk5PVF9MT0FEX1JFUVVFU1RFRF9ET0MgPQotICAgICAgICAgIldHX0NBTk5PVF9MT0FEX1JFUVVFU1RFRF9ET0MiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19DQU5OT1RfRklORF9DT0xMQVRPUiA9IldHX0NBTk5PVF9GSU5EX0NPTExBVE9SIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfRlVOQ1RJT05TX1NIT1VMRF9VU0VfVVJMID0KLSAgICAgICAgICJXR19GVU5DVElPTlNfU0hPVUxEX1VTRV9VUkwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19FTkNPRElOR19OT1RfU1VQUE9SVEVEX1VTSU5HX1VURjggPQotICAgICAgICAgIldHX0VOQ09ESU5HX05PVF9TVVBQT1JURURfVVNJTkdfVVRGOCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0VOQ09ESU5HX05PVF9TVVBQT1JURURfVVNJTkdfSkFWQSA9Ci0gICAgICAgICAiV0dfRU5DT0RJTkdfTk9UX1NVUFBPUlRFRF9VU0lOR19KQVZBIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfU1BFQ0lGSUNJVFlfQ09ORkxJQ1RTID0KLSAgICAgICAgICJXR19TUEVDSUZJQ0lUWV9DT05GTElDVFMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19QQVJTSU5HX0FORF9QUkVQQVJJTkcgPQotICAgICAgICAgIldHX1BBUlNJTkdfQU5EX1BSRVBBUklORyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0FUVFJfVEVNUExBVEUgPSAiV0dfQVRUUl9URU1QTEFURSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0NPTkZMSUNUX0JFVFdFRU5fWFNMU1RSSVBTUEFDRV9BTkRfWFNMUFJFU0VSVkVTUEFDRSA9ICJXR19DT05GTElDVF9CRVRXRUVOX1hTTFNUUklQU1BBQ0VfQU5EX1hTTFBSRVNFUlZFU1AiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19BVFRSSUJfTk9UX0hBTkRMRUQgPSAiV0dfQVRUUklCX05PVF9IQU5ETEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfTk9fREVDSU1BTEZPUk1BVF9ERUNMQVJBVElPTiA9Ci0gICAgICAgICAiV0dfTk9fREVDSU1BTEZPUk1BVF9ERUNMQVJBVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX09MRF9YU0xUX05TID0gIldHX09MRF9YU0xUX05TIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfT05FX0RFRkFVTFRfWFNMREVDSU1BTEZPUk1BVF9BTExPV0VEID0KLSAgICAgICAgICJXR19PTkVfREVGQVVMVF9YU0xERUNJTUFMRk9STUFUX0FMTE9XRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19YU0xERUNJTUFMRk9STUFUX05BTUVTX01VU1RfQkVfVU5JUVVFID0KLSAgICAgICAgICJXR19YU0xERUNJTUFMRk9STUFUX05BTUVTX01VU1RfQkVfVU5JUVVFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfSUxMRUdBTF9BVFRSSUJVVEUgPSAiV0dfSUxMRUdBTF9BVFRSSUJVVEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19DT1VMRF9OT1RfUkVTT0xWRV9QUkVGSVggPQotICAgICAgICAgIldHX0NPVUxEX05PVF9SRVNPTFZFX1BSRUZJWCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX1NUWUxFU0hFRVRfUkVRVUlSRVNfVkVSU0lPTl9BVFRSSUIgPQotICAgICAgICAgIldHX1NUWUxFU0hFRVRfUkVRVUlSRVNfVkVSU0lPTl9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19JTExFR0FMX0FUVFJJQlVURV9OQU1FID0KLSAgICAgICAgICJXR19JTExFR0FMX0FUVFJJQlVURV9OQU1FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfSUxMRUdBTF9BVFRSSUJVVEVfVkFMVUUgPQotICAgICAgICAgIldHX0lMTEVHQUxfQVRUUklCVVRFX1ZBTFVFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfRU1QVFlfU0VDT05EX0FSRyA9ICJXR19FTVBUWV9TRUNPTkRfQVJHIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfUFJPQ0VTU0lOR0lOU1RSVUNUSU9OX05BTUVfQ0FOVF9CRV9YTUwgPQotICAgICAgICAgIldHX1BST0NFU1NJTkdJTlNUUlVDVElPTl9OQU1FX0NBTlRfQkVfWE1MIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfUFJPQ0VTU0lOR0lOU1RSVUNUSU9OX05PVFZBTElEX05DTkFNRSA9Ci0gICAgICAgICAiV0dfUFJPQ0VTU0lOR0lOU1RSVUNUSU9OX05PVFZBTElEX05DTkFNRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0lMTEVHQUxfQVRUUklCVVRFX1BPU0lUSU9OID0KLSAgICAgICAgICJXR19JTExFR0FMX0FUVFJJQlVURV9QT1NJVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiA9Ci0gICAgICAgICAiTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIjsKLQotICAvKgotICAgKiBOb3cgZmlsbCBpbiB0aGUgbWVzc2FnZSB0ZXh0LgotICAgKiBUaGVuIGZpbGwgaW4gdGhlIG1lc3NhZ2UgdGV4dCBmb3IgdGhhdCBtZXNzYWdlIGNvZGUgaW4gdGhlCi0gICAqIGFycmF5LiBVc2UgdGhlIG5ldyBlcnJvciBjb2RlIGFzIHRoZSBpbmRleCBpbnRvIHRoZSBhcnJheS4KLSAgICovCi0KLSAgLy8gRXJyb3IgbWVzc2FnZXMuLi4KLQotICAvKiogR2V0IHRoZSBsb29rdXAgdGFibGUgZm9yIGVycm9yIG1lc3NhZ2VzLgotICAgICoKLSAgICAqIEByZXR1cm4gVGhlIG1lc3NhZ2UgbG9va3VwIHRhYmxlLgotICAgICovCi0gIHB1YmxpYyBPYmplY3RbXVtdIGdldENvbnRlbnRzKCkKLSAgewotICAgICAgcmV0dXJuIG5ldyBPYmplY3RbXVtdIHsKLQotICAvKiogRXJyb3IgbWVzc2FnZSBJRCB0aGF0IGhhcyBhIG51bGwgbWVzc2FnZSwgYnV0IHRha2VzIGluIGEgc2luZ2xlIG9iamVjdC4gICAgKi8KLSAgeyJFUjAwMDAiICwgInswfSIgfSwKLQotICAgIHsgRVJfTk9fQ1VSTFlCUkFDRSwKLSAgICAgICJGZWhsZXI6IFwie1wiIGRhcmYgbmljaHQgaW0gQXVzZHJ1Y2sgZW50aGFsdGVuIHNlaW4ifSwKLQotICAgIHsgRVJfSUxMRUdBTF9BVFRSSUJVVEUgLAotICAgICAiezB9IGhhdCBlaW4gdW5nXHUwMEZDbHRpZ2VzIEF0dHJpYnV0OiB7MX0ifSwKLQotICB7RVJfTlVMTF9TT1VSQ0VOT0RFX0FQUExZSU1QT1JUUyAsCi0gICAgICAic291cmNlTm9kZSBpc3QgbnVsbCBpbiB4c2w6YXBwbHktaW1wb3J0cy4ifSwKLQotICB7RVJfQ0FOTk9UX0FERCwKLSAgICAgICJ7MH0ga2FubiBuaWNodCB6dSB7MX0gaGluenVnZWZcdTAwRkNndCB3ZXJkZW4ifSwKLQotICAgIHsgRVJfTlVMTF9TT1VSQ0VOT0RFX0hBTkRMRUFQUExZVEVNUExBVEVTLAotICAgICAgInNvdXJjZU5vZGUgaXN0IG51bGwgaW4gaGFuZGxlQXBwbHlUZW1wbGF0ZXNJbnN0cnVjdGlvbi4ifSwKLQotICAgIHsgRVJfTk9fTkFNRV9BVFRSSUIsCi0gICAgICJ7MH0gbXVzcyBcdTAwRkNiZXIgZWluIFwibmFtZVwiLUF0dHJpYnV0IHZlcmZcdTAwRkNnZW4uIn0sCi0KLSAgICB7RVJfVEVNUExBVEVfTk9UX0ZPVU5ELAotICAgICAiVm9ybGFnZSBtaXQgTmFtZW4gezB9IGtvbm50ZSBuaWNodCBnZWZ1bmRlbiB3ZXJkZW4ifSwKLQotICAgIHtFUl9DQU5UX1JFU09MVkVfTkFNRV9BVlQsCi0gICAgICAiTmFtZW5zLUFWVCBpbiB4c2w6Y2FsbC10ZW1wbGF0ZSBrb25udGUgbmljaHQgYXVmZ2VsXHUwMEY2c3Qgd2VyZGVuLiJ9LAotCi0gICAge0VSX1JFUVVJUkVTX0FUVFJJQiwKLSAgICAgInswfSBlcmZvcmRlcnQgQXR0cmlidXQ6IHsxfSJ9LAotCi0gICAgeyBFUl9NVVNUX0hBVkVfVEVTVF9BVFRSSUIsCi0gICAgICAiezB9IG11c3MgXHUwMEZDYmVyIGVpbiBcInRlc3RcIi1BdHRyaWJ1dCB2ZXJmXHUwMEZDZ2VuLiJ9LAotCi0gICAge0VSX0JBRF9WQUxfT05fTEVWRUxfQVRUUklCLAotICAgICAgIlVuZ1x1MDBGQ2x0aWdlciBXZXJ0IGJlaSBFYmVuZW5hdHRyaWJ1dDogezB9In0sCi0KLSAgICB7RVJfUFJPQ0VTU0lOR0lOU1RSVUNUSU9OX05BTUVfQ0FOVF9CRV9YTUwsCi0gICAgICAicHJvY2Vzc2luZy1pbnN0cnVjdGlvbi1OYW1lIGRhcmYgbmljaHQgXCJ4bWxcIiBsYXV0ZW4ifSwKLQotICAgIHsgRVJfUFJPQ0VTU0lOR0lOU1RSVUNUSU9OX05PVFZBTElEX05DTkFNRSwKLSAgICAgICJwcm9jZXNzaW5nLWluc3RydWN0aW9uLU5hbWUgbXVzcyBlaW4gZ1x1MDBGQ2x0aWdlciBOQ05hbWUgc2VpbjogezB9In0sCi0KLSAgICB7IEVSX05FRURfTUFUQ0hfQVRUUklCLAotICAgICAgInswfSBtdXNzIFx1MDBGQ2JlciBlaW4gXCJtYXRjaFwiLUF0dHJpYnV0IHZlcmZcdTAwRkNnZW4sIHdlbm4gZWluIE1vZHVzIHZvcmhhbmRlbiBpc3QuIn0sCi0KLSAgICB7IEVSX05FRURfTkFNRV9PUl9NQVRDSF9BVFRSSUIsCi0gICAgICAiezB9IGVyZm9yZGVydCBlbnR3ZWRlciBlaW4gXCJuYW1lXCItIG9kZXIgZWluIFwibWF0Y2hcIi1BdHRyaWJ1dC4ifSwKLQotICAgIHtFUl9DQU5UX1JFU09MVkVfTlNQUkVGSVgsCi0gICAgICAiTmFtZXNwYWNlLVByXHUwMEU0Zml4IGthbm4gbmljaHQgYXVmZ2VsXHUwMEY2c3Qgd2VyZGVuOiB7MH0ifSwKLQotICAgIHsgRVJfSUxMRUdBTF9WQUxVRSwKLSAgICAgInhtbDpzcGFjZSBoYXQgZWluZW4gdW5nXHUwMEZDbHRpZ2VuIFdlcnQ6IHswfSJ9LAotCi0gICAgeyBFUl9OT19PV05FUkRPQywKLSAgICAgICJEZXIgdW50ZXJnZW9yZG5ldGUgS25vdGVuIGhhdCBrZWluIEVpZ2VudFx1MDBGQ21lcmRva3VtZW50LiJ9LAotCi0gICAgeyBFUl9FTEVNVEVNUExBVEVFTEVNX0VSUiwKLSAgICAgIkVsZW1UZW1wbGF0ZUVsZW1lbnQtRmVobGVyOiB7MH0ifSwKLQotICAgIHsgRVJfTlVMTF9DSElMRCwKLSAgICAgIkVzIHdpcmQgdmVyc3VjaHQsIGVpbiBsZWVyZXMgdW50ZXJnZW9yZG5ldGVzIEVsZW1lbnQgaGluenV6dWZcdTAwRkNnZW4uIn0sCi0KLSAgICB7IEVSX05FRURfU0VMRUNUX0FUVFJJQiwKLSAgICAgInswfSBlcmZvcmRlcnQgZWluIFwic2VsZWN0XCItQXR0cmlidXQuIn0sCi0KLSAgICB7IEVSX05FRURfVEVTVF9BVFRSSUIgLAotICAgICAgInhzbDp3aGVuIG11c3MgXHUwMEZDYmVyIGVpbiBcInRlc3RcIi1BdHRyaWJ1dCB2ZXJmXHUwMEZDZ2VuLiJ9LAotCi0gICAgeyBFUl9ORUVEX05BTUVfQVRUUklCLAotICAgICAgInhzbDp3aXRoLXBhcmFtIG11c3MgXHUwMEZDYmVyIGVpbiBcIm5hbWVcIi1BdHRyaWJ1dCB2ZXJmXHUwMEZDZ2VuLiJ9LAotCi0gICAgeyBFUl9OT19DT05URVhUX09XTkVSRE9DLAotICAgICAgIktvbnRleHQgaGF0IGtlaW4gRWlnZW50XHUwMEZDbWVyZG9rdW1lbnQuIn0sCi0KLSAgICB7RVJfQ09VTERfTk9UX0NSRUFURV9YTUxfUFJPQ19MSUFJU09OLAotICAgICAgIlhNTC1UcmFuc2Zvcm1lckZhY3RvcnktTGlhaXNvbiBrb25udGUgbmljaHQgZXJzdGVsbHQgd2VyZGVuOiB7MH0ifSwKLQotICAgIHtFUl9QUk9DRVNTX05PVF9TVUNDRVNTRlVMLAotICAgICAgIlhhbGFuOiBQcm96ZXNzIHdhciBuaWNodCBlcmZvbGdyZWljaC4ifSwKLQotICAgIHsgRVJfTk9UX1NVQ0NFU1NGVUwsCi0gICAgICJYYWxhbjogV2FyIG5pY2h0IGVyZm9sZ3JlaWNoLiJ9LAotCi0gICAgeyBFUl9FTkNPRElOR19OT1RfU1VQUE9SVEVELAotICAgICAiQ29kaWVydW5nIG5pY2h0IHVudGVyc3RcdTAwRkN0enQ6IHswfSJ9LAotCi0gICAge0VSX0NPVUxEX05PVF9DUkVBVEVfVFJBQ0VMSVNURU5FUiwKLSAgICAgICJUcmFjZUxpc3RlbmVyIGtvbm50ZSBuaWNodCBlcnN0ZWxsdCB3ZXJkZW46IHswfSJ9LAotCi0gICAge0VSX0tFWV9SRVFVSVJFU19OQU1FX0FUVFJJQiwKLSAgICAgICJ4c2w6a2V5IGVyZm9yZGVydCBlaW4gXCJuYW1lXCItQXR0cmlidXQuIn0sCi0KLSAgICB7IEVSX0tFWV9SRVFVSVJFU19NQVRDSF9BVFRSSUIsCi0gICAgICAieHNsOmtleSBlcmZvcmRlcnQgZWluIFwibWF0Y2hcIi1BdHRyaWJ1dC4ifSwKLQotICAgIHsgRVJfS0VZX1JFUVVJUkVTX1VTRV9BVFRSSUIsCi0gICAgICAieHNsOmtleSBlcmZvcmRlcnQgZWluIFwidXNlXCItQXR0cmlidXQuIn0sCi0KLSAgICB7IEVSX1JFUVVJUkVTX0VMRU1FTlRTX0FUVFJJQiwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIHswfSBlcmZvcmRlcnQgZWluIFwiZWxlbWVudHNcIi1BdHRyaWJ1dC4ifSwKLQotICAgIHsgRVJfTUlTU0lOR19QUkVGSVhfQVRUUklCLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgezB9IEF0dHJpYnV0IFwicHJlZml4XCIgZmVobHQifSwKLQotICAgIHsgRVJfQkFEX1NUWUxFU0hFRVRfVVJMLAotICAgICAiU3R5bGVzaGVldC1VUkwgaXN0IHVuZ1x1MDBGQ2x0aWc6IHswfSJ9LAotCi0gICAgeyBFUl9GSUxFX05PVF9GT1VORCwKLSAgICAgIlN0eWxlc2hlZXQtRGF0ZWkgd3VyZGUgbmljaHQgZ2VmdW5kZW46IHswfSJ9LAotCi0gICAgeyBFUl9JT0VYQ0VQVElPTiwKLSAgICAgICJJTy1BdXNuYWhtZSBiZWkgU3R5bGVzaGVldC1EYXRlaTogezB9In0sCi0KLSAgICB7IEVSX05PX0hSRUZfQVRUUklCLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgXCJocmVmXCItQXR0cmlidXQgZlx1MDBGQ3IgezB9IGtvbm50ZSBuaWNodCBnZWZ1bmRlbiB3ZXJkZW4ifSwKLQotICAgIHsgRVJfU1RZTEVTSEVFVF9JTkNMVURFU19JVFNFTEYsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSB7MH0gc2NobGllXHUwMERGdCBzaWNoIGRpcmVrdCBvZGVyIGluZGlyZWt0IHNlbGJzdCBtaXQgZWluLiJ9LAotCi0gICAgeyBFUl9QUk9DRVNTSU5DTFVERV9FUlJPUiwKLSAgICAgICJTdHlsZXNoZWV0SGFuZGxlci5wcm9jZXNzSW5jbHVkZS1GZWhsZXIsIHswfSJ9LAotCi0gICAgeyBFUl9NSVNTSU5HX0xBTkdfQVRUUklCLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgezB9OiBEYXMgQXR0cmlidXQgXCJsYW5nXCIgZmVobHQifSwKLQotICAgIHsgRVJfTUlTU0lOR19DT05UQUlORVJfRUxFTUVOVF9DT01QT05FTlQsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSBFbGVtZW50IHswfSBhbiBmYWxzY2hlciBQb3NpdGlvbj8/IEZlaGxlbmRlcyBDb250YWluZXJlbGVtZW50ICcnY29tcG9uZW50JycifSwKLQotICAgIHsgRVJfQ0FOX09OTFlfT1VUUFVUX1RPX0VMRU1FTlQsCi0gICAgICAiQXVzZ2FiZSBrYW5uIG51ciBhbiBlaW4gRWxlbWVudCwgRG9jdW1lbnRGcmFnbWVudCwgRG9rdW1lbnQgb2RlciBQcmludFdyaXRlciBlcmZvbGdlbi4ifSwKLQotICAgIHsgRVJfUFJPQ0VTU19FUlJPUiwKLSAgICAgIlN0eWxlc2hlZXRSb290LnByb2Nlc3MtRmVobGVyIn0sCi0KLSAgICB7IEVSX1VOSU1QTE5PREVfRVJST1IsCi0gICAgICJVbkltcGxOb2RlLUZlaGxlcjogezB9In0sCi0KLSAgICB7IEVSX05PX1NFTEVDVF9FWFBSRVNTSU9OLAotICAgICAgIkZlaGxlci4geHBhdGgtQXVzd2FobGF1c2RydWNrICgtc2VsZWN0KSBuaWNodCBnZWZ1bmRlbi4ifSwKLQotICAgIHsgRVJfQ0FOTk9UX1NFUklBTElaRV9YU0xQUk9DRVNTT1IsCi0gICAgICAiWFNMUHJvY2Vzc29yIGthbm4gbmljaHQgc2VyaWFsaXNpZXJ0IHdlcmRlbi4ifSwKLQotICAgIHsgRVJfTk9fSU5QVVRfU1RZTEVTSEVFVCwKLSAgICAgICJTdHlsZXNoZWV0LUVpbmdhYmUgd3VyZGUgbmljaHQgYW5nZWdlYmVuLiJ9LAotCi0gICAgeyBFUl9GQUlMRURfUFJPQ0VTU19TVFlMRVNIRUVULAotICAgICAgIlZlcmFyYmVpdHVuZyBkZXMgU3R5bGVzaGVldCBuaWNodCBlcmZvbGdyZWljaC4ifSwKLQotICAgIHsgRVJfQ09VTEROVF9QQVJTRV9ET0MsCi0gICAgICJ7MH0tRG9rdW1lbnQga29ubnRlIG5pY2h0IGdlcGFyc3Qgd2VyZGVuLiJ9LAotCi0gICAgeyBFUl9DT1VMRE5UX0ZJTkRfRlJBR01FTlQsCi0gICAgICJGcmFnbWVudCBrb25udGUgbmljaHQgZ2VmdW5kZW4gd2VyZGVuOiB7MH0ifSwKLQotICAgIHsgRVJfTk9ERV9OT1RfRUxFTUVOVCwKLSAgICAgICJGcmFnbWVudC1JRCB2ZXJ3aWVzIGF1ZiBlaW5lbiBLbm90ZW4sIGRlciBrZWluIEVsZW1lbnQgd2FyOiB7MH0ifSwKLQotICAgIHsgRVJfRk9SRUFDSF9ORUVEX01BVENIX09SX05BTUVfQVRUUklCLAotICAgICAgImZvci1lYWNoIG11c3MgZW50d2VkZXIgZWluIFwibWF0Y2hcIi0gb2RlciBlaW4gXCJuYW1lXCItQXR0cmlidXQgaGFiZW4ifSwKLQotICAgIHsgRVJfVEVNUExBVEVTX05FRURfTUFUQ0hfT1JfTkFNRV9BVFRSSUIsCi0gICAgICAiVm9ybGFnZW4gbVx1MDBGQ3NzZW4gZW50d2VkZXIgZWluIFwibWF0Y2hcIi0gb2RlciBlaW4gXCJuYW1lXCItQXR0cmlidXQgaGFiZW4ifSwKLQotICAgIHsgRVJfTk9fQ0xPTkVfT0ZfRE9DVU1FTlRfRlJBRywKLSAgICAgICJLZWluIENsb25lIGVpbmVzIERva3VtZW50ZnJhZ21lbnRzLiJ9LAotCi0gICAgeyBFUl9DQU5UX0NSRUFURV9JVEVNLAotICAgICAgIkVsZW1lbnQgaW4gRXJnZWJuaXNiYXVtIGthbm4gbmljaHQgZXJzdGVsbHQgd2VyZGVuOiB7MH0ifSwKLQotICAgIHsgRVJfWE1MU1BBQ0VfSUxMRUdBTF9WQUxVRSwKLSAgICAgICJ4bWw6c3BhY2UgaW4gUXVlbGwtWE1MIGhhdCBlaW5lbiB1bmdcdTAwRkNsdGlnZW4gV2VydDogezB9In0sCi0KLSAgICB7IEVSX05PX1hTTEtFWV9ERUNMQVJBVElPTiwKLSAgICAgICJLZWluZSB4c2w6a2V5LURla2xhcmF0aW9uIGZcdTAwRkNyIHswfSB2b3JoYW5kZW4uIn0sCi0KLSAgICB7IEVSX0NBTlRfQ1JFQVRFX1VSTCwKLSAgICAgIkZlaGxlci4gVVJMIGZcdTAwRkNyIHswfSBrYW5uIG5pY2h0IGVyc3RlbGx0IHdlcmRlbiJ9LAotCi0gICAgeyBFUl9YU0xGVU5DVElPTlNfVU5TVVBQT1JURUQsCi0gICAgICJ4c2w6ZnVuY3Rpb25zIG5pY2h0IHVudGVyc3RcdTAwRkN0enQifSwKLQotICAgIHsgRVJfUFJPQ0VTU09SX0VSUk9SLAotICAgICAiWFNMVC1UcmFuc2Zvcm1lckZhY3RvcnktRmVobGVyIn0sCi0KLSAgICB7IEVSX05PVF9BTExPV0VEX0lOU0lERV9TVFlMRVNIRUVULAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgezB9IG5pY2h0IHp1bFx1MDBFNHNzaWcgaW4gZWluZW0gU3R5bGVzaGVldC4ifSwKLQotICAgIHsgRVJfUkVTVUxUTlNfTk9UX1NVUFBPUlRFRCwKLSAgICAgICJyZXN1bHQtbnMgd2lyZCBuaWNodCBtZWhyIHVudGVyc3RcdTAwRkN0enQuIFZlcndlbmRlbiBTaWUgc3RhdHRkZXNzZW4geHNsOm91dHB1dC4ifSwKLQotICAgIHsgRVJfREVGQVVMVFNQQUNFX05PVF9TVVBQT1JURUQsCi0gICAgICAiZGVmYXVsdC1zcGFjZSB3aXJkIG5pY2h0IG1laHIgdW50ZXJzdFx1MDBGQ3R6dC4gVmVyd2VuZGVuIFNpZSBzdGF0dGRlc3NlbiB4c2w6c3RyaXAtc3BhY2Ugb2RlciB4c2w6cHJlc2VydmUtc3BhY2UuIn0sCi0KLSAgICB7IEVSX0lOREVOVFJFU1VMVF9OT1RfU1VQUE9SVEVELAotICAgICAgImluZGVudC1yZXN1bHQgd2lyZCBuaWNodCBtZWhyIHVudGVyc3RcdTAwRkN0enQuIFZlcndlbmRlbiBTaWUgc3RhdHRkZXNzZW4geHNsOm91dHB1dC4ifSwKLQotICAgIHsgRVJfSUxMRUdBTF9BVFRSSUIsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSB7MH0gaGF0IGVpbiB1bmdcdTAwRkNsdGlnZXMgQXR0cmlidXQ6IHsxfSJ9LAotCi0gICAgeyBFUl9VTktOT1dOX1hTTF9FTEVNLAotICAgICAiVW5iZWthbm50ZXMgWFNMLUVsZW1lbnQ6IHswfSJ9LAotCi0gICAgeyBFUl9CQURfWFNMU09SVF9VU0UsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSB4c2w6c29ydCBrYW5uIG51ciBtaXQgeHNsOmFwcGx5LXRlbXBsYXRlcyBvZGVyIHhzbDpmb3ItZWFjaCB2ZXJ3ZW5kZXQgd2VyZGVuLiJ9LAotCi0gICAgeyBFUl9NSVNQTEFDRURfWFNMV0hFTiwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIHhzbDp3aGVuIHN0ZWh0IGFuIGRlciBmYWxzY2hlbiBQb3NpdGlvbi4ifSwKLQotICAgIHsgRVJfWFNMV0hFTl9OT1RfUEFSRU5URURfQllfWFNMQ0hPT1NFLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgeHNsOndoZW4gaGF0IG5pY2h0IGRhcyBcdTAwRkNiZXJnZW9yZG5ldGUgRWxlbWVudCB4c2w6Y2hvb3NlLiJ9LAotCi0gICAgeyBFUl9NSVNQTEFDRURfWFNMT1RIRVJXSVNFLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgeHNsOm90aGVyd2lzZSBzdGVodCBhbiBkZXIgZmFsc2NoZW4gUG9zaXRpb24uIn0sCi0KLSAgICB7IEVSX1hTTE9USEVSV0lTRV9OT1RfUEFSRU5URURfQllfWFNMQ0hPT1NFLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgeHNsOm90aGVyd2lzZSBoYXQgbmljaHQgZGFzIFx1MDBGQ2Jlcmdlb3JkbmV0ZSBFbGVtZW50IHhzbDpjaG9vc2UuIn0sCi0KLSAgICB7IEVSX05PVF9BTExPV0VEX0lOU0lERV9URU1QTEFURSwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIHswfSBuaWNodCB6dWxcdTAwRTRzc2lnIGluIGVpbmVyIFZvcmxhZ2UuIn0sCi0KLSAgICB7IEVSX1VOS05PV05fRVhUX05TX1BSRUZJWCwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIHswfTogRXJ3ZWl0ZXJ1bmcgZGVzIE5hbWVzcGFjZS1Qclx1MDBFNGZpeGVzIHsxfSBpc3QgdW5iZWthbm50In0sCi0KLSAgICB7IEVSX0lNUE9SVFNfQVNfRklSU1RfRUxFTSwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIEltcG9ydGUga1x1MDBGNm5uZW4gbnVyIGFscyBlcnN0ZSBFbGVtZW50ZSBpbiBlaW5lbSBTdHlsZXNoZWV0IGF1ZnRyZXRlbi4ifSwKLQotICAgIHsgRVJfSU1QT1JUSU5HX0lUU0VMRiwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIHswfSBpbXBvcnRpZXJ0IHNpY2ggZGlyZWt0IG9kZXIgaW5kaXJla3Qgc2VsYnN0LiJ9LAotCi0gICAgeyBFUl9YTUxTUEFDRV9JTExFR0FMX1ZBTCwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIHhtbDpzcGFjZSBoYXQgZWluZW4gdW5nXHUwMEZDbHRpZ2VuIFdlcnQ6IHswfSJ9LAotCi0gICAgeyBFUl9QUk9DRVNTU1RZTEVTSEVFVF9OT1RfU1VDQ0VTU0ZVTCwKLSAgICAgICJwcm9jZXNzU3R5bGVzaGVldCBuaWNodCBlcmZvbGdyZWljaC4ifSwKLQotICAgIHsgRVJfU0FYX0VYQ0VQVElPTiwKLSAgICAgIlNBWC1BdXNuYWhtZSJ9LAotCi0vLyAgYWRkIHRoaXMgbWVzc2FnZSB0byBmaXggYnVnIDIxNDc4Ci0gICAgeyBFUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVELAotICAgICAiRnVua3Rpb24gbmljaHQgdW50ZXJzdFx1MDBGQ3R6dC4ifSwKLQotICAgIHsgRVJfWFNMVF9FUlJPUiwKLSAgICAgIlhTTFQtRmVobGVyIn0sCi0KLSAgICB7IEVSX0NVUlJFTkNZX1NJR05fSUxMRUdBTCwKLSAgICAgICJXXHUwMEU0aHJ1bmdzc3ltYm9sIG5pY2h0IHp1bFx1MDBFNHNzaWcgaW4gRm9ybWF0bXVzdGVyLVplaWNoZW5mb2xnZSJ9LAotCi0gICAgeyBFUl9ET0NVTUVOVF9GVU5DVElPTl9JTlZBTElEX0lOX1NUWUxFU0hFRVRfRE9NLAotICAgICAgIkRva3VtZW50ZnVua3Rpb24gbmljaHQgdW50ZXJzdFx1MDBGQ3R6dCBpbiBET00tU3R5bGVzaGVldC4ifSwKLQotICAgIHsgRVJfQ0FOVF9SRVNPTFZFX1BSRUZJWF9PRl9OT05fUFJFRklYX1JFU09MVkVSLAotICAgICAgIlByXHUwMEU0Zml4IGVpbmVzIE5vbi1Qclx1MDBFNGZpeC1SZXNvbHZlciBrYW5uIG5pY2h0IGF1ZmdlbFx1MDBGNnN0IHdlcmRlbi4ifSwKLQotICAgIHsgRVJfUkVESVJFQ1RfQ09VTEROVF9HRVRfRklMRU5BTUUsCi0gICAgICAiVW1sZWl0dW5nc2Vyd2VpdGVydW5nOiBEYXRlaW5hbWUga29ubnRlIG5pY2h0IGFiZ2VydWZlbiB3ZXJkZW4uIFwiZmlsZVwiLSBvZGVyIFwic2VsZWN0XCItQXR0cmlidXQgbXVzcyBlaW5lIGdcdTAwRkNsdGlnZSBaZWljaGVuZm9sZ2UgenVyXHUwMEZDY2tnZWJlbi4ifSwKLQotICAgIHsgRVJfQ0FOTk9UX0JVSUxEX0ZPUk1BVFRFUkxJU1RFTkVSX0lOX1JFRElSRUNULAotICAgICAgIkZvcm1hdHRlckxpc3RlbmVyIGthbm4gbmljaHQgaW4gVW1sZWl0dW5nc2Vyd2VpdGVydW5nIGVyc3RlbGx0IHdlcmRlbi4ifSwKLQotICAgIHsgRVJfSU5WQUxJRF9QUkVGSVhfSU5fRVhDTFVERVJFU1VMVFBSRUZJWCwKLSAgICAgICJQclx1MDBFNGZpeCBpbiBleGNsdWRlLXJlc3VsdC1wcmVmaXhlcyBpc3QgbmljaHQgZ1x1MDBGQ2x0aWc6IHswfSJ9LAotCi0gICAgeyBFUl9NSVNTSU5HX05TX1VSSSwKLSAgICAgICJGZWhsZW5kZXIgTmFtZXNwYWNlLVVSSSBmXHUwMEZDciBhbmdlZ2ViZW5lcyBQclx1MDBFNGZpeCJ9LAotCi0gICAgeyBFUl9NSVNTSU5HX0FSR19GT1JfT1BUSU9OLAotICAgICAgIkZlaGxlbmRlcyBBcmd1bWVudCBmXHUwMEZDciBPcHRpb246IHswfSJ9LAotCi0gICAgeyBFUl9JTlZBTElEX09QVElPTiwKLSAgICAgIlVuZ1x1MDBGQ2x0aWdlIE9wdGlvbjogezB9In0sCi0KLSAgICB7IEVSX01BTEZPUk1FRF9GT1JNQVRfU1RSSU5HLAotICAgICAiRmVobGVyaGFmdGUgRm9ybWF0emVpY2hlbmZvbGdlOiB7MH0ifSwKLQotICAgIHsgRVJfU1RZTEVTSEVFVF9SRVFVSVJFU19WRVJTSU9OX0FUVFJJQiwKLSAgICAgICJ4c2w6c3R5bGVzaGVldCBlcmZvcmRlcnQgZWluIFwidmVyc2lvblwiLUF0dHJpYnV0LiJ9LAotCi0gICAgeyBFUl9JTExFR0FMX0FUVFJJQlVURV9WQUxVRSwKLSAgICAgICJBdHRyaWJ1dCB7MH0gaGF0IGVpbmVuIHVuZ1x1MDBGQ2x0aWdlbiBXZXJ0OiB7MX0ifSwKLQotICAgIHsgRVJfQ0hPT1NFX1JFUVVJUkVTX1dIRU4sCi0gICAgICJ4c2w6Y2hvb3NlIGVyZm9yZGVydCB4c2w6d2hlbiJ9LAotCi0gICAgeyBFUl9OT19BUFBMWV9JTVBPUlRfSU5fRk9SX0VBQ0gsCi0gICAgICAieHNsOmFwcGx5LWltcG9ydHMgbmljaHQgenVsXHUwMEU0c3NpZyBpbiB4c2w6Zm9yLWVhY2gifSwKLQotICAgIHsgRVJfQ0FOVF9VU0VfRFRNX0ZPUl9PVVRQVVQsCi0gICAgICAiRFRNTGlhaXNvbiBrYW5uIG5pY2h0IGZcdTAwRkNyIGVpbmVuIEF1c2dhYmUtRE9NLUtub3RlbiB2ZXJ3ZW5kZXQgd2VyZGVuLiBcdTAwRENiZXJnZWJlbiBTaWUgc3RhdHRkZXNzZW4gZWluZW4gY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLkRPTTJIZWxwZXIuIn0sCi0KLSAgICB7IEVSX0NBTlRfVVNFX0RUTV9GT1JfSU5QVVQsCi0gICAgICAiRFRNTGlhaXNvbiBrYW5uIG5pY2h0IGZcdTAwRkNyIGVpbmVuIEVpbmdhYmUtRE9NLUtub3RlbiB2ZXJ3ZW5kZXQgd2VyZGVuLiBcdTAwRENiZXJnZWJlbiBTaWUgc3RhdHRkZXNzZW4gZWluZW4gY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLkRPTTJIZWxwZXIuIn0sCi0KLSAgICB7IEVSX0NBTExfVE9fRVhUX0ZBSUxFRCwKLSAgICAgICJBdWZydWYgdm9uIEVyd2VpdGVydW5nc2VsZW1lbnQgbmljaHQgZXJmb2xncmVpY2g6IHswfSJ9LAotCi0gICAgeyBFUl9QUkVGSVhfTVVTVF9SRVNPTFZFLAotICAgICAgIlByXHUwMEU0Zml4IG11c3MgaW4gZWluZW4gTmFtZXNwYWNlIGF1ZmdlbFx1MDBGNnN0IHdlcmRlbjogezB9In0sCi0KLSAgICB7IEVSX0lOVkFMSURfVVRGMTZfU1VSUk9HQVRFLAotICAgICAgIlVuZ1x1MDBGQ2x0aWdlIFVURi0xNi1FcnNldHp1bmcgZmVzdGdlc3RlbGx0OiB7MH0/In0sCi0KLSAgICB7IEVSX1hTTEFUVFJTRVRfVVNFRF9JVFNFTEYsCi0gICAgICAieHNsOmF0dHJpYnV0ZS1zZXQgezB9IGhhdCBzaWNoIHNlbGJzdCB2ZXJ3ZW5kZXQuIERpZXMgZlx1MDBGQ2hydCB6dSBlaW5lciBFbmRsb3NzY2hsZWlmZS4ifSwKLQotICAgIHsgRVJfQ0FOTk9UX01JWF9YRVJDRVNET00sCi0gICAgICAiTmljaHQtWGVyY2VzLURPTS1FaW5nYWJlIGthbm4gbmljaHQgbWl0IFhlcmNlcy1ET00tQXVzZ2FiZSBnZW1pc2NodCB3ZXJkZW4uIn0sCi0KLSAgICB7IEVSX1RPT19NQU5ZX0xJU1RFTkVSUywKLSAgICAgICJhZGRUcmFjZUxpc3RlbmVyc1RvU3R5bGVzaGVldCAtIFRvb01hbnlMaXN0ZW5lcnNFeGNlcHRpb24ifSwKLQotICAgIHsgRVJfSU5fRUxFTVRFTVBMQVRFRUxFTV9SRUFET0JKRUNULAotICAgICAgIkluIEVsZW1UZW1wbGF0ZUVsZW1lbnQucmVhZE9iamVjdDogezB9In0sCi0KLSAgICB7IEVSX0RVUExJQ0FURV9OQU1FRF9URU1QTEFURSwKLSAgICAgICJNZWhyZXJlIFZvcmxhZ2VuIG1pdCBkZW4gTmFtZW4gezB9IGdlZnVuZGVuIn0sCi0KLSAgICB7IEVSX0lOVkFMSURfS0VZX0NBTEwsCi0gICAgICAiVW5nXHUwMEZDbHRpZ2VyIEZ1bmt0aW9uc2F1ZnJ1ZjogUmVrdXJzaXZlIGtleSgpLUF1ZnJ1ZmUgc2luZCBuaWNodCB6dWxcdTAwRTRzc2lnIn0sCi0KLSAgICB7IEVSX1JFRkVSRU5DSU5HX0lUU0VMRiwKLSAgICAgICJWYXJpYWJsZSB7MH0gdmVyd2Vpc3QgZGlyZWt0IG9kZXIgaW5kaXJla3QgYXVmIHNpY2ggc2VsYnN0LiJ9LAotCi0gICAgeyBFUl9JTExFR0FMX0RPTVNPVVJDRV9JTlBVVCwKLSAgICAgICJEZXIgRWluZ2FiZWtub3RlbiBkYXJmIG5pY2h0IG51bGwgc2VpbiBmXHUwMEZDciBlaW5lIERPTVNvdXJjZSBmXHUwMEZDciBuZXdUZW1wbGF0ZXMuIn0sCi0KLSAgICB7IEVSX0NMQVNTX05PVF9GT1VORF9GT1JfT1BUSU9OLAotICAgICAgICAiS2xhc3NlbmRhdGVpIG5pY2h0IGdlZnVuZGVuIGZcdTAwRkNyIE9wdGlvbiB7MH0ifSwKLQotICAgIHsgRVJfUkVRVUlSRURfRUxFTV9OT1RfRk9VTkQsCi0gICAgICAgICJFcmZvcmRlcmxpY2hlcyBFbGVtZW50IG5pY2h0IGdlZnVuZGVuOiB7MH0ifSwKLQotICAgIHsgRVJfSU5QVVRfQ0FOTk9UX0JFX05VTEwsCi0gICAgICAgICJJbnB1dFN0cmVhbSBkYXJmIG5pY2h0IG51bGwgc2VpbiJ9LAotCi0gICAgeyBFUl9VUklfQ0FOTk9UX0JFX05VTEwsCi0gICAgICAgICJVUkkgZGFyZiBuaWNodCBudWxsIHNlaW4ifSwKLQotICAgIHsgRVJfRklMRV9DQU5OT1RfQkVfTlVMTCwKLSAgICAgICAgIkRhdGVpIGRhcmYgbmljaHQgbnVsbCBzZWluIn0sCi0KLSAgICB7IEVSX1NPVVJDRV9DQU5OT1RfQkVfTlVMTCwKLSAgICAgICAgICAgICAgICAiSW5wdXRTb3VyY2UgZGFyZiBuaWNodCBudWxsIHNlaW4ifSwKLQotICAgIHsgRVJfQ0FOTk9UX0lOSVRfQlNGTUdSLAotICAgICAgICAgICAgICAgICJCU0YtTWFuYWdlciBrb25udGUgbmljaHQgaW5pdGlhbGlzaWVydCB3ZXJkZW4ifSwKLQotICAgIHsgRVJfQ0FOTk9UX0NNUExfRVhURU5TTiwKLSAgICAgICAgICAgICAgICAiRXJ3ZWl0ZXJ1bmcga29ubnRlIG5pY2h0IGtvbXBpbGllcnQgd2VyZGVuIn0sCi0KLSAgICB7IEVSX0NBTk5PVF9DUkVBVEVfRVhURU5TTiwKLSAgICAgICJFcndlaXRlcnVuZyB7MH0ga29ubnRlIG5pY2h0IGVyc3RlbGx0IHdlcmRlbjsgR3J1bmQ6IHsxfSJ9LAotCi0gICAgeyBFUl9JTlNUQU5DRV9NVEhEX0NBTExfUkVRVUlSRVMsCi0gICAgICAiRGVyIEF1ZnJ1ZiBlaW5lciBJbnN0YW56bWV0aG9kZSB2b24gTWV0aG9kZSB7MH0gZXJmb3JkZXJ0IGVpbmUgT2JqZWt0aW5zdGFueiBhbHMgZXJzdGVzIEFyZ3VtZW50In0sCi0KLSAgICB7IEVSX0lOVkFMSURfRUxFTUVOVF9OQU1FLAotICAgICAgIlVuZ1x1MDBGQ2x0aWdlciBFbGVtZW50bmFtZSBhbmdlZ2ViZW4gezB9In0sCi0KLSAgICB7IEVSX0VMRU1FTlRfTkFNRV9NRVRIT0RfU1RBVElDLAotICAgICAgIkVsZW1lbnRuYW1lbm1ldGhvZGUgbXVzcyBzdGF0aXNjaCBzZWluIHswfSJ9LAotCi0gICAgeyBFUl9FWFRFTlNJT05fRlVOQ19VTktOT1dOLAotICAgICAgICAgICAgICJFcndlaXRlcnVuZ3NmdW5rdGlvbiB7MH0gOiB7MX0gaXN0IHVuYmVrYW5udCJ9LAotCi0gICAgeyBFUl9NT1JFX01BVENIX0NPTlNUUlVDVE9SLAotICAgICAgICAgICAgICJNZWhyZXJlIHBhc3NlbmRlIFx1MDBEQ2JlcmVpbnN0aW1tdW5nZW4gZlx1MDBGQ3IgQ29uc3RydWN0b3IgZlx1MDBGQ3IgezB9In0sCi0KLSAgICB7IEVSX01PUkVfTUFUQ0hfTUVUSE9ELAotICAgICAgICAgICAgICJNZWhyZXJlIHBhc3NlbmRlIFx1MDBEQ2JlcmVpbnN0aW1tdW5nZW4gZlx1MDBGQ3IgTWV0aG9kZSB7MH0ifSwKLQotICAgIHsgRVJfTU9SRV9NQVRDSF9FTEVNRU5ULAotICAgICAgICAgICAgICJNZWhyZXJlIHBhc3NlbmRlIFx1MDBEQ2JlcmVpbnN0aW1tdW5nZW4gZlx1MDBGQ3IgRWxlbWVudG1ldGhvZGUgezB9In0sCi0KLSAgICB7IEVSX0lOVkFMSURfQ09OVEVYVF9QQVNTRUQsCi0gICAgICAgICAgICAgIlVuZ1x1MDBGQ2x0aWdlciBLb250ZXh0IHp1ciBBdXN3ZXJ0dW5nIHZvbiB7MH0gXHUwMEZDYmVyZ2ViZW4ifSwKLQotICAgIHsgRVJfUE9PTF9FWElTVFMsCi0gICAgICAgICAgICAgIlBvb2wgaXN0IGJlcmVpdHMgdm9yaGFuZGVuIn0sCi0KLSAgICB7IEVSX05PX0RSSVZFUl9OQU1FLAotICAgICAgICAgICAgICJLZWluIFRyZWliZXJuYW1lIGFuZ2VnZWJlbiJ9LAotCi0gICAgeyBFUl9OT19VUkwsCi0gICAgICAgICAgICAgIktlaW5lIFVSTCBhbmdlZ2ViZW4ifSwKLQotICAgIHsgRVJfUE9PTF9TSVpFX0xFU1NUSEFOX09ORSwKLSAgICAgICAgICAgICAiUG9vbGdyXHUwMEY2XHUwMERGZSBpc3Qga2xlaW5lciBhbHMgZWlucy4ifSwKLQotICAgIHsgRVJfSU5WQUxJRF9EUklWRVIsCi0gICAgICAgICAgICAgIlVuZ1x1MDBGQ2x0aWdlciBUcmVpYmVybmFtZSBhbmdlZ2ViZW4uIn0sCi0KLSAgICB7IEVSX05PX1NUWUxFU0hFRVRST09ULAotICAgICAgICAgICAgICJTdHlsZXNoZWV0LVJvb3Qgd3VyZGUgbmljaHQgZ2VmdW5kZW4uIn0sCi0KLSAgICB7IEVSX0lMTEVHQUxfWE1MU1BBQ0VfVkFMVUUsCi0gICAgICAgICAiVW5nXHUwMEZDbHRpZ2VyIFdlcnQgZlx1MDBGQ3IgeG1sOnNwYWNlIn0sCi0KLSAgICB7IEVSX1BST0NFU1NGUk9NTk9ERV9GQUlMRUQsCi0gICAgICAgICAicHJvY2Vzc0Zyb21Ob2RlIG5pY2h0IGVyZm9sZ3JlaWNoIn0sCi0KLSAgICB7IEVSX1JFU09VUkNFX0NPVUxEX05PVF9MT0FELAotICAgICAgICAiUmVzc291cmNlIFsgezB9IF0ga29ubnRlIG5pY2h0IGdlbGFkZW4gd2VyZGVuOiB7MX0gXG4gezJ9IFx0IHszfSJ9LAotCi0gICAgeyBFUl9CVUZGRVJfU0laRV9MRVNTVEhBTl9aRVJPLAotICAgICAgICAiUHVmZmVyZ3JcdTAwRjZcdTAwREZlIDw9MCJ9LAotCi0gICAgeyBFUl9VTktOT1dOX0VSUk9SX0NBTExJTkdfRVhURU5TSU9OLAotICAgICAgICAiVW5iZWthbm50ZXIgRmVobGVyIGJlaSBBdWZydWYgdm9uIEVyd2VpdGVydW5nIn0sCi0KLSAgICB7IEVSX05PX05BTUVTUEFDRV9ERUNMLAotICAgICAgICAiUHJcdTAwRTRmaXggezB9IGhhdCBrZWluZSBlbnRzcHJlY2hlbmRlIE5hbWVzcGFjZS1EZWtsYXJhdGlvbiJ9LAotCi0gICAgeyBFUl9FTEVNX0NPTlRFTlRfTk9UX0FMTE9XRUQsCi0gICAgICAgICJFbGVtZW50LUNvbnRlbnQgbmljaHQgenVsXHUwMEU0c3NpZyBmXHUwMEZDciBsYW5nPWphdmFjbGFzcyB7MH0ifSwKLQotICAgIHsgRVJfU1RZTEVTSEVFVF9ESVJFQ1RFRF9URVJNSU5BVElPTiwKLSAgICAgICAgIlN0eWxlc2hlZXQgZlx1MDBGQ2hydGUgenUgQWJicnVjaCJ9LAotCi0gICAgeyBFUl9PTkVfT1JfVFdPLAotICAgICAgICAiMSBvZGVyIDIifSwKLQotICAgIHsgRVJfVFdPX09SX1RIUkVFLAotICAgICAgICAiMiBvZGVyIDMifSwKLQotICAgIHsgRVJfQ09VTERfTk9UX0xPQURfUkVTT1VSQ0UsCi0gICAgICAgICJ7MH0ga29ubnRlIG5pY2h0IGdlbGFkZW4gd2VyZGVuIChDTEFTU1BBVEggcHJcdTAwRkNmZW4pOyBkaWUgU3RhbmRhcmR3ZXJ0ZSB3ZXJkZW4gdmVyd2VuZGV0In0sCi0KLSAgICB7IEVSX0NBTk5PVF9JTklUX0RFRkFVTFRfVEVNUExBVEVTLAotICAgICAgICAiU3RhbmRhcmR2b3JsYWdlbiBrXHUwMEY2bm5lbiBuaWNodCBpbml0aWFsaXNpZXJ0IHdlcmRlbiJ9LAotCi0gICAgeyBFUl9SRVNVTFRfTlVMTCwKLSAgICAgICAgIkVyZ2VibmlzIGRhcmYgbmljaHQgbnVsbCBzZWluIn0sCi0KLSAgICB7IEVSX1JFU1VMVF9DT1VMRF9OT1RfQkVfU0VULAotICAgICAgICAiRXJnZWJuaXMga29ubnRlIG5pY2h0IGZlc3RnZWxlZ3Qgd2VyZGVuIn0sCi0KLSAgICB7IEVSX05PX09VVFBVVF9TUEVDSUZJRUQsCi0gICAgICAgICJLZWluZSBBdXNnYWJlIGFuZ2VnZWJlbiJ9LAotCi0gICAgeyBFUl9DQU5OT1RfVFJBTlNGT1JNX1RPX1JFU1VMVF9UWVBFLAotICAgICAgICAiVHJhbnNmb3JtYXRpb24gaW4gZWluIEVyZ2VibmlzIG1pdCBUeXAgezB9IG5pY2h0IG1cdTAwRjZnbGljaCJ9LAotCi0gICAgeyBFUl9DQU5OT1RfVFJBTlNGT1JNX1NPVVJDRV9UWVBFLAotICAgICAgICAiVHJhbnNmb3JtYXRpb24gZWluZXIgUXVlbGxlIG1pdCBUeXAgezB9IG5pY2h0IG1cdTAwRjZnbGljaCJ9LAotCi0gICAgeyBFUl9OVUxMX0NPTlRFTlRfSEFORExFUiwKLSAgICAgICAgIk51bGwtQ29udGVudC1IYW5kbGVyIn0sCi0KLSAgICB7IEVSX05VTExfRVJST1JfSEFORExFUiwKLSAgICAgICAgIk51bGwtRXJyb3IgSGFuZGxlciJ9LAotCi0gICAgeyBFUl9DQU5OT1RfQ0FMTF9QQVJTRSwKLSAgICAgICAgIlBhcnNlbiBrYW5uIG5pY2h0IGF1ZmdlcnVmZW4gd2VyZGVuLCB3ZW5uIGRlciBDb250ZW50SGFuZGxlciBuaWNodCBmZXN0Z2VsZWd0IHd1cmRlIn0sCi0KLSAgICB7IEVSX05PX1BBUkVOVF9GT1JfRklMVEVSLAotICAgICAgICAiS2VpbiBcdTAwRkNiZXJnZW9yZG5ldGVzIE9iamVrdCBmXHUwMEZDciBGaWx0ZXIifSwKLQotICAgIHsgRVJfTk9fU1RZTEVTSEVFVF9JTl9NRURJQSwKLSAgICAgICAgICJLZWluIFN0eWxlc2hlZXQgZ2VmdW5kZW4gaW46IHswfSwgRGF0ZW50clx1MDBFNGdlciA9IHsxfSJ9LAotCi0gICAgeyBFUl9OT19TVFlMRVNIRUVUX1BJLAotICAgICAgICAgIktlaW5lIFZlcmFyYmVpdHVuZ3NhbndlaXN1bmcgZlx1MDBGQ3IgeG1sLXN0eWxlc2hlZXQgZ2VmdW5kZW4gaW46IHswfSJ9LAotCi0gICAgeyBFUl9OT1RfU1VQUE9SVEVELAotICAgICAgICJOaWNodCB1bnRlcnN0XHUwMEZDdHp0OiB7MH0ifSwKLQotICAgIHsgRVJfUFJPUEVSVFlfVkFMVUVfQk9PTEVBTiwKLSAgICAgICAiV2VydCBmXHUwMEZDciBFaWdlbnNjaGFmdCB7MH0gbXVzcyBlaW5lIGJvb2xlc2NoZSBJbnN0YW56IHNlaW4ifSwKLQotICAgIHsgRVJfQ09VTERfTk9UX0ZJTkRfRVhURVJOX1NDUklQVCwKLSAgICAgICAgICJFeHRlcm5lcyBTa3JpcHQgYmVpIHswfSBrb25udGUgbmljaHQgYWJnZXJ1ZmVuIHdlcmRlbiJ9LAotCi0gICAgeyBFUl9SRVNPVVJDRV9DT1VMRF9OT1RfRklORCwKLSAgICAgICAgIlJlc3NvdXJjZSBbIHswfSBdIGtvbm50ZSBuaWNodCBnZWZ1bmRlbiB3ZXJkZW4uXG4gezF9In0sCi0KLSAgICB7IEVSX09VVFBVVF9QUk9QRVJUWV9OT1RfUkVDT0dOSVpFRCwKLSAgICAgICAgIkF1c2dhYmVlaWdlbnNjaGFmdCBuaWNodCBlcmthbm50OiB7MH0ifSwKLQotICAgIHsgRVJfRkFJTEVEX0NSRUFUSU5HX0VMRU1MSVRSU0xULAotICAgICAgICAiRWxlbUxpdGVyYWxSZXN1bHQtSW5zdGFueiBrb25udGUgbmljaHQgZXJzdGVsbHQgd2VyZGVuIn0sCi0KLSAgLy9FYXJsaWVyIChKREsgMS40IFhBTEFOIDIuMi1EMTEpIGF0IGtleSBjb2RlICcyMDQnIHRoZSBrZXkgbmFtZSB3YXMgRVJfUFJJT1JJVFlfTk9UX1BBUlNBQkxFCi0gIC8vIEluIGxhdGVzdCBYYWxhbiBjb2RlIGJhc2Uga2V5IG5hbWUgaXMgIEVSX1ZBTFVFX1NIT1VMRF9CRV9OVU1CRVIuIFRoaXMgc2hvdWxkIGFsc28gYmUgdGFrZW4gY2FyZQotICAvL2luIGxvY2FsZSBzcGVjaWZpYyBmaWxlcyBsaWtlIFhTTFRFcnJvclJlc291cmNlc19kZS5qYXZhLCBYU0xURXJyb3JSZXNvdXJjZXNfZnIuamF2YSBldGMuCi0gIC8vTk9URTogTm90IG9ubHkgdGhlIGtleSBuYW1lIGJ1dCBtZXNzYWdlIGhhcyBhbHNvIGJlZW4gY2hhbmdlZC4KLSAgICB7IEVSX1ZBTFVFX1NIT1VMRF9CRV9OVU1CRVIsCi0gICAgICAgICJXZXJ0IGZcdTAwRkNyIHswfSBzb2xsdGUgZWluZSBwYXJzZWZcdTAwRTRoaWdlIFphaGwgZW50aGFsdGVuIn0sCi0KLSAgICB7IEVSX1ZBTFVFX1NIT1VMRF9FUVVBTCwKLSAgICAgICAgIldlcnQgZlx1MDBGQ3IgezB9IG11c3MgXCJKYVwiIG9kZXIgXCJOZWluXCIgZW50c3ByZWNoZW4ifSwKLQotICAgIHsgRVJfRkFJTEVEX0NBTExJTkdfTUVUSE9ELAotICAgICAgICAiezB9LU1ldGhvZGUga29ubnRlIG5pY2h0IGF1ZmdlcnVmZW4gd2VyZGVuIn0sCi0KLSAgICB7IEVSX0ZBSUxFRF9DUkVBVElOR19FTEVNVE1QTCwKLSAgICAgICAgIkVsZW1UZW1wbGF0ZUVsZW1lbnQtSW5zdGFueiBrb25udGUgbmljaHQgZXJzdGVsbHQgd2VyZGVuIn0sCi0KLSAgICB7IEVSX0NIQVJTX05PVF9BTExPV0VELAotICAgICAgICAiQW4gZGllc2VyIFN0ZWxsZSBpbSBEb2t1bWVudCBzaW5kIGtlaW5lIFplaWNoZW4genVsXHUwMEU0c3NpZyJ9LAotCi0gICAgeyBFUl9BVFRSX05PVF9BTExPV0VELAotICAgICAgICAiXCJ7MH1cIi1BdHRyaWJ1dCBpc3QgbmljaHQgenVsXHUwMEU0c3NpZyBiZWltIHsxfS1FbGVtZW50LiJ9LAotCi0gICAgeyBFUl9CQURfVkFMVUUsCi0gICAgICJ7MH0gdW5nXHUwMEZDbHRpZ2VyIFdlcnQgezF9ICJ9LAotCi0gICAgeyBFUl9BVFRSSUJfVkFMVUVfTk9UX0ZPVU5ELAotICAgICAiezB9LUF0dHJpYnV0d2VydCBuaWNodCBnZWZ1bmRlbiAifSwKLQotICAgIHsgRVJfQVRUUklCX1ZBTFVFX05PVF9SRUNPR05JWkVELAotICAgICAiezB9LUF0dHJpYnV0d2VydCBuaWNodCBlcmthbm50ICJ9LAotCi0gICAgeyBFUl9OVUxMX1VSSV9OQU1FU1BBQ0UsCi0gICAgICJWZXJzdWNoLCBlaW4gTmFtZXNwYWNlLVByXHUwMEU0Zml4IG1pdCBlaW5lbSBOdWxsLVVSSSB6dSBnZW5lcmllcmVuIn0sCi0KLSAgICB7IEVSX05VTUJFUl9UT09fQklHLAotICAgICAiVmVyc3VjaCwgZWluZSBaYWhsIHp1IGZvcm1hdGllcmVuLCBkaWUgZ3JcdTAwRjZcdTAwREZlciBhbHMgZGllIGdyXHUwMEY2XHUwMERGdGUgTG9uZy1HYW56emFobCBpc3QifSwKLQotICAgIHsgRVJfQ0FOTk9UX0ZJTkRfU0FYMV9EUklWRVIsCi0gICAgICJTQVgxLVRyZWliZXJrbGFzc2UgezB9IGthbm4gbmljaHQgZ2VmdW5kZW4gd2VyZGVuIn0sCi0KLSAgICB7IEVSX1NBWDFfRFJJVkVSX05PVF9MT0FERUQsCi0gICAgICJTQVgxLVRyZWliZXJrbGFzc2UgezB9IGdlZnVuZGVuLCBrYW5uIGFiZXIgbmljaHQgZ2VsYWRlbiB3ZXJkZW4ifSwKLQotICAgIHsgRVJfU0FYMV9EUklWRVJfTk9UX0lOU1RBTlRJQVRFRCwKLSAgICAgIlNBWDEtVHJlaWJlcmtsYXNzZSB7MH0gZ2VsYWRlbiwga2FubiBhYmVyIG5pY2h0IGluc3RhbnppaWVydCB3ZXJkZW4ifSwKLQotICAgIHsgRVJfU0FYMV9EUklWRVJfTk9UX0lNUExFTUVOVF9QQVJTRVIsCi0gICAgICJTQVgxLVRyZWliZXJrbGFzc2UgezB9IGltcGxlbWVudGllcnQgb3JnLnhtbC5zYXguUGFyc2VyIG5pY2h0In0sCi0KLSAgICB7IEVSX1BBUlNFUl9QUk9QRVJUWV9OT1RfU1BFQ0lGSUVELAotICAgICAiU3lzdGVtZWlnZW5zY2hhZnQgXCJvcmcueG1sLnNheC5wYXJzZXJcIiBuaWNodCBhbmdlZ2ViZW4ifSwKLQotICAgIHsgRVJfUEFSU0VSX0FSR19DQU5OT1RfQkVfTlVMTCwKLSAgICAgIlBhcnNlcmFyZ3VtZW50IGRhcmYgbmljaHQgbnVsbCBzZWluIn0sCi0KLSAgICB7IEVSX0ZFQVRVUkUsCi0gICAgICJGZWF0dXJlOiB7MH0ifSwKLQotICAgIHsgRVJfUFJPUEVSVFksCi0gICAgICJFaWdlbnNjaGFmdDogezB9In0sCi0KLSAgICB7IEVSX05VTExfRU5USVRZX1JFU09MVkVSLAotICAgICAiTnVsbC1FbnRpdHktUmVzb2x2ZXIifSwKLQotICAgIHsgRVJfTlVMTF9EVERfSEFORExFUiwKLSAgICAgIk51bGwtRFRELUhhbmRsZXIifSwKLQotICAgIHsgRVJfTk9fRFJJVkVSX05BTUVfU1BFQ0lGSUVELAotICAgICAiS2VpbiBUcmVpYmVybmFtZSBhbmdlZ2ViZW4uIn0sCi0KLSAgICB7IEVSX05PX1VSTF9TUEVDSUZJRUQsCi0gICAgICJLZWluZSBVUkwgYW5nZWdlYmVuLiJ9LAotCi0gICAgeyBFUl9QT09MU0laRV9MRVNTX1RIQU5fT05FLAotICAgICAiUG9vbGdyXHUwMEY2XHUwMERGZSBpc3Qga2xlaW5lciBhbHMgMS4ifSwKLQotICAgIHsgRVJfSU5WQUxJRF9EUklWRVJfTkFNRSwKLSAgICAgIlVuZ1x1MDBGQ2x0aWdlciBUcmVpYmVybmFtZSBhbmdlZ2ViZW4uIn0sCi0KLSAgICB7IEVSX0VSUk9STElTVEVORVIsCi0gICAgICJFcnJvckxpc3RlbmVyIn0sCi0KLQotLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBzaG91bGQgbm90IG5vcm1hbGx5IGJlIGRpc3BsYXllZAotLy8gICB0byB1c2Vycy4gIEl0IGRlc2NyaWJlcyBhIHNpdHVhdGlvbiBpbiB3aGljaCB0aGUgcHJvY2Vzc29yIGhhcyBkZXRlY3RlZAotLy8gICBhbiBpbnRlcm5hbCBjb25zaXN0ZW5jeSBwcm9ibGVtIGluIGl0c2VsZiwgYW5kIGl0IHByb3ZpZGVzIHRoaXMgbWVzc2FnZQotLy8gICBmb3IgdGhlIGRldmVsb3BlciB0byBoZWxwIGRpYWdub3NlIHRoZSBwcm9ibGVtLiAgVGhlIG5hbWUKLS8vICAgJ0VsZW1UZW1wbGF0ZUVsZW1lbnQnIGlzIHRoZSBuYW1lIG9mIGEgY2xhc3MsIGFuZCBzaG91bGQgbm90IGJlCi0vLyAgIHRyYW5zbGF0ZWQuCi0gICAgeyBFUl9BU1NFUlRfTk9fVEVNUExBVEVfUEFSRU5ULAotICAgICAiUHJvZ3JhbW1pZXJlcmZlaGxlci4gRGVyIEF1c2RydWNrIGhhdCBrZWluIFx1MDBGQ2Jlcmdlb3JkbmV0ZXMgRWxlbVRlbXBsYXRlRWxlbWVudC1PYmpla3QuIn0sCi0KLQotLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBzaG91bGQgbm90IG5vcm1hbGx5IGJlIGRpc3BsYXllZAotLy8gICB0byB1c2Vycy4gIEl0IGRlc2NyaWJlcyBhIHNpdHVhdGlvbiBpbiB3aGljaCB0aGUgcHJvY2Vzc29yIGhhcyBkZXRlY3RlZAotLy8gICBhbiBpbnRlcm5hbCBjb25zaXN0ZW5jeSBwcm9ibGVtIGluIGl0c2VsZiwgYW5kIGl0IHByb3ZpZGVzIHRoaXMgbWVzc2FnZQotLy8gICBmb3IgdGhlIGRldmVsb3BlciB0byBoZWxwIGRpYWdub3NlIHRoZSBwcm9ibGVtLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0vLyAgIHByb3ZpZGVzIGZ1cnRoZXIgaW5mb3JtYXRpb24gaW4gb3JkZXIgdG8gZGlhZ25vc2UgdGhlIHByb2JsZW0uICBUaGUgbmFtZQotLy8gICAnUmVkdW5kZW50RXhwckVsaW1pbmF0b3InIGlzIHRoZSBuYW1lIG9mIGEgY2xhc3MsIGFuZCBzaG91bGQgbm90IGJlCi0vLyAgIHRyYW5zbGF0ZWQuCi0gICAgeyBFUl9BU1NFUlRfUkVEVU5ERU5UX0VYUFJfRUxJTUlOQVRPUiwKLSAgICAgIlByb2dyYW1taWVyZXItQXNzZXJ0aW9uIGluIFJlZHVuZGVudEV4cHJFbGltaW5hdG9yOiB7MH0ifSwKLQotICAgIHsgRVJfTk9UX0FMTE9XRURfSU5fUE9TSVRJT04sCi0gICAgICJ7MH0gaXN0IGFuIGRpZXNlciBQb3NpdGlvbiBpbSBTdHlsZXNoZWV0IG5pY2h0IHp1bFx1MDBFNHNzaWcuIn0sCi0KLSAgICB7IEVSX05PTldISVRFU1BBQ0VfTk9UX0FMTE9XRURfSU5fUE9TSVRJT04sCi0gICAgICJBbmRlcmVyIFRleHQgYWxzIExlZXJzdGVsbGVuIGlzdCBhbiBkaWVzZXIgUG9zaXRpb24gaW0gU3R5bGVzaGVldCBuaWNodCB6dWxcdTAwRTRzc2lnLiJ9LAotCi0gIC8vIFRoaXMgY29kZSBpcyBzaGFyZWQgd2l0aCB3YXJuaW5nIGNvZGVzLgotICAvLyBTeXN0ZW1JZCBVbmtub3duCi0gICAgeyBJTlZBTElEX1RDSEFSLAotICAgICAiVW5nXHUwMEZDbHRpZ2VyIFdlcnQgezF9IGZcdTAwRkNyIENIQVItQXR0cmlidXQgezB9IHZlcndlbmRldC4gRWluIEF0dHJpYnV0IGRlcyBUeXBzIENIQVIgZGFyZiBudXIgMSBaZWljaGVuIGVudGhhbHRlbi4ifSwKLQotICAgIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgaXMgdXNlZCBpZiB0aGUgdmFsdWUgb2YKLSAgICAvLyBhbiBhdHRyaWJ1dGUgaW4gYSBzdHlsZXNoZWV0IGlzIGludmFsaWQuICAiUU5BTUUiIGlzIHRoZSBYTUwgZGF0YS10eXBlIG9mCi0gICAgLy8gdGhlIGF0dHJpYnV0ZSwgYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCB7MX0gaXMKLSAgICAvLyB0aGUgYXR0cmlidXRlIHZhbHVlIGFuZCB7MH0gaXMgdGhlIGF0dHJpYnV0ZSBuYW1lLgotICAvL1RoZSBmb2xsb3dpbmcgY29kZXMgYXJlIHNoYXJlZCB3aXRoIHRoZSB3YXJuaW5nIGNvZGVzLi4uCi0gICAgeyBJTlZBTElEX1FOQU1FLAotICAgICAiVW5nXHUwMEZDbHRpZ2VyIFdlcnQgezF9IGZcdTAwRkNyIFFOQU1FLUF0dHJpYnV0IHswfSB2ZXJ3ZW5kZXQifSwKLQotICAgIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgaXMgdXNlZCBpZiB0aGUgdmFsdWUgb2YKLSAgICAvLyBhbiBhdHRyaWJ1dGUgaW4gYSBzdHlsZXNoZWV0IGlzIGludmFsaWQuICAiRU5VTSIgaXMgdGhlIFhNTCBkYXRhLXR5cGUgb2YKLSAgICAvLyB0aGUgYXR0cmlidXRlLCBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHsxfSBpcwotICAgIC8vIHRoZSBhdHRyaWJ1dGUgdmFsdWUsIHswfSBpcyB0aGUgYXR0cmlidXRlIG5hbWUsIGFuZCB7Mn0gaXMgYSBsaXN0IG9mIHZhbGlkCi0gICAgLy8gdmFsdWVzLgotICAgIHsgSU5WQUxJRF9FTlVNLAotICAgICAiVW5nXHUwMEZDbHRpZ2VyIFdlcnQgezF9IGZcdTAwRkNyIEVOVU0tQXR0cmlidXQgezB9IHZlcndlbmRldC4gR1x1MDBGQ2x0aWdlIFdlcnRlIHNpbmQ6IHsyfS4ifSwKLQotLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBpcyB1c2VkIGlmIHRoZSB2YWx1ZSBvZgotLy8gYW4gYXR0cmlidXRlIGluIGEgc3R5bGVzaGVldCBpcyBpbnZhbGlkLiAgIk5NVE9LRU4iIGlzIHRoZSBYTUwgZGF0YS10eXBlCi0vLyBvZiB0aGUgYXR0cmlidXRlLCBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHsxfSBpcwotLy8gdGhlIGF0dHJpYnV0ZSB2YWx1ZSBhbmQgezB9IGlzIHRoZSBhdHRyaWJ1dGUgbmFtZS4KLSAgICB7IElOVkFMSURfTk1UT0tFTiwKLSAgICAgIlVuZ1x1MDBGQ2x0aWdlciBXZXJ0IHsxfSBmXHUwMEZDciBOTVRPS0VOLUF0dHJpYnV0IHswfSB2ZXJ3ZW5kZXQgIn0sCi0KLS8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgaXMgdXNlZCBpZiB0aGUgdmFsdWUgb2YKLS8vIGFuIGF0dHJpYnV0ZSBpbiBhIHN0eWxlc2hlZXQgaXMgaW52YWxpZC4gICJOQ05BTUUiIGlzIHRoZSBYTUwgZGF0YS10eXBlCi0vLyBvZiB0aGUgYXR0cmlidXRlLCBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHsxfSBpcwotLy8gdGhlIGF0dHJpYnV0ZSB2YWx1ZSBhbmQgezB9IGlzIHRoZSBhdHRyaWJ1dGUgbmFtZS4KLSAgICB7IElOVkFMSURfTkNOQU1FLAotICAgICAiVW5nXHUwMEZDbHRpZ2VyIFdlcnQgezF9IGZcdTAwRkNyIE5DTkFNRS1BdHRyaWJ1dCB7MH0gdmVyd2VuZGV0ICJ9LAotCi0vLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIGlzIHVzZWQgaWYgdGhlIHZhbHVlIG9mCi0vLyBhbiBhdHRyaWJ1dGUgaW4gYSBzdHlsZXNoZWV0IGlzIGludmFsaWQuICAiYm9vbGVhbiIgaXMgdGhlIFhTTFQgZGF0YS10eXBlCi0vLyBvZiB0aGUgYXR0cmlidXRlLCBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHsxfSBpcwotLy8gdGhlIGF0dHJpYnV0ZSB2YWx1ZSBhbmQgezB9IGlzIHRoZSBhdHRyaWJ1dGUgbmFtZS4KLSAgICB7IElOVkFMSURfQk9PTEVBTiwKLSAgICAgIlVuZ1x1MDBGQ2x0aWdlciBXZXJ0IHsxfSBmXHUwMEZDciBcIkJvb2xlYW5cIi1BdHRyaWJ1dCB7MH0gdmVyd2VuZGV0ICJ9LAotCi0vLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIGlzIHVzZWQgaWYgdGhlIHZhbHVlIG9mCi0vLyBhbiBhdHRyaWJ1dGUgaW4gYSBzdHlsZXNoZWV0IGlzIGludmFsaWQuICAibnVtYmVyIiBpcyB0aGUgWFNMVCBkYXRhLXR5cGUKLS8vIG9mIHRoZSBhdHRyaWJ1dGUsIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgezF9IGlzCi0vLyB0aGUgYXR0cmlidXRlIHZhbHVlIGFuZCB7MH0gaXMgdGhlIGF0dHJpYnV0ZSBuYW1lLgotICAgICB7IElOVkFMSURfTlVNQkVSLAotICAgICAiVW5nXHUwMEZDbHRpZ2VyIFdlcnQgezF9IGZcdTAwRkNyIFwiTnVtYmVyXCItQXR0cmlidXQgezB9IHZlcndlbmRldCAifSwKLQotCi0gIC8vIEVuZCBvZiBzaGFyZWQgY29kZXMuLi4KLQotLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIEEgIm1hdGNoIHBhdHRlcm4iIGlzIGEgc3BlY2lhbCBmb3JtIG9mIFhQYXRoIGV4cHJlc3Npb24KLS8vIHRoYXQgaXMgdXNlZCBmb3IgbWF0Y2hpbmcgcGF0dGVybnMuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YKLS8vIGEgZnVuY3Rpb24uICBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB3aGVuIHRoaXMgZnVuY3Rpb24gaXMgcmVmZXJlbmNlZCBpbgotLy8gYSBtYXRjaCBwYXR0ZXJuLCBpdHMgYXJndW1lbnQgbXVzdCBiZSBhIHN0cmluZyBsaXRlcmFsIChvciBjb25zdGFudC4pCi0vLyBFUl9BUkdfTElURVJBTCAtIG5ldyBlcnJvciBtZXNzYWdlIGZvciBidWd6aWxsYSAvLzUyMDIKLSAgICB7IEVSX0FSR19MSVRFUkFMLAotICAgICAiQXJndW1lbnQgZlx1MDBGQ3IgezB9IGluIFZlcmdsZWljaHNtdXN0ZXIgbXVzcyBlaW4gTGl0ZXJhbCBzZWluLiJ9LAotCi0vLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHR3byBkZWZpbml0aW9ucyBvZgotLy8gYSB2YXJpYWJsZS4gIEEgImdsb2JhbCB2YXJpYWJsZSIgaXMgYSB2YXJpYWJsZSB0aGF0IGlzIGFjY2Vzc2libGUgZXZlcnl3aGVyCi0vLyBpbiB0aGUgc3R5bGVzaGVldC4KLS8vIEVSX0RVUExJQ0FURV9HTE9CQUxfVkFSIC0gbmV3IGVycm9yIG1lc3NhZ2UgZm9yIGJ1Z3ppbGxhICM3OTAKLSAgICB7IEVSX0RVUExJQ0FURV9HTE9CQUxfVkFSLAotICAgICAiRG9wcGVsdGUgRGVrbGFyYXRpb24gZWluZXIgZ2xvYmFsZW4gVmFyaWFibGUuIn0sCi0KLQotLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0d28gZGVmaW5pdGlvbnMgb2YKLS8vIGEgdmFyaWFibGUgd2VyZSBlbmNvdW50ZXJlZC4KLS8vIEVSX0RVUExJQ0FURV9WQVIgLSBuZXcgZXJyb3IgbWVzc2FnZSBmb3IgYnVnemlsbGEgIzc5MAotICAgIHsgRVJfRFVQTElDQVRFX1ZBUiwKLSAgICAgIkRvcHBlbHRlIFZhcmlhYmxlbmRla2xhcmF0aW9uLiJ9LAotCi0gICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogICJ4c2w6dGVtcGxhdGUsICJuYW1lIiBhbmQgIm1hdGNoIiBhcmUgWFNMVCBrZXl3b3JkcwotICAgIC8vIHdoaWNoIG11c3Qgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgLy8gRVJfVEVNUExBVEVfTkFNRV9NQVRDSCAtIG5ldyBlcnJvciBtZXNzYWdlIGZvciBidWd6aWxsYSAjNzg5Ci0gICAgeyBFUl9URU1QTEFURV9OQU1FX01BVENILAotICAgICAieHNsOnRlbXBsYXRlIG11c3MgZWluIFwibmFtZVwiLSBvZGVyIFwibWF0Y2hcIi1BdHRyaWJ1dCAob2RlciBiZWlkZXMpIGhhYmVuIn0sCi0KLSAgICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgImV4Y2x1ZGUtcmVzdWx0LXByZWZpeGVzIiBpcyBhbiBYU0xUIGtleXdvcmQgd2hpY2gKLSAgICAvLyBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCBhIG5hbWVzcGFjZSBwcmVmaXgKLSAgICAvLyBlbmNvdW50ZXJlZCBhcyBwYXJ0IG9mIHRoZSB2YWx1ZSBvZiB0aGUgZXhjbHVkZS1yZXN1bHQtcHJlZml4ZXMgYXR0cmlidXRlCi0gICAgLy8gd2FzIGluIGVycm9yLgotICAgIC8vIEVSX0lOVkFMSURfUFJFRklYIC0gbmV3IGVycm9yIG1lc3NhZ2UgZm9yIGJ1Z3ppbGxhICM3ODgKLSAgICB7IEVSX0lOVkFMSURfUFJFRklYLAotICAgICAiUHJcdTAwRTRmaXggaW4gZXhjbHVkZS1yZXN1bHQtcHJlZml4ZXMgaXN0IG5pY2h0IGdcdTAwRkNsdGlnOiB7MH0ifSwKLQotICAgIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBbiAiYXR0cmlidXRlIHNldCIgaXMgYSBzZXQgb2YgYXR0cmlidXRlcyB0aGF0IGNhbgotICAgIC8vIGJlIGFkZGVkIHRvIGFuIGVsZW1lbnQgaW4gdGhlIG91dHB1dCBkb2N1bWVudCBhcyBhIGdyb3VwLiAgVGhlIG1lc3NhZ2UKLSAgICAvLyBpbmRpY2F0ZXMgdGhhdCB0aGVyZSB3YXMgYSByZWZlcmVuY2UgdG8gYW4gYXR0cmlidXRlIHNldCBuYW1lZCB7MH0gdGhhdAotICAgIC8vIHdhcyBuZXZlciBkZWZpbmVkLgotICAgIC8vIEVSX05PX0FUVFJJQl9TRVQgLSBuZXcgZXJyb3IgbWVzc2FnZSBmb3IgYnVnemlsbGEgIzc4MgotICAgIHsgRVJfTk9fQVRUUklCX1NFVCwKLSAgICAgImF0dHJpYnV0ZS1zZXQgbWl0IE5hbWVuIHswfSBpc3QgbmljaHQgdm9yaGFuZGVuIn0sCi0KLSAgICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoZXJlIHdhcyBhIHJlZmVyZW5jZQotICAgIC8vIHRvIGEgZnVuY3Rpb24gbmFtZWQgezB9IGZvciB3aGljaCBubyBmdW5jdGlvbiBkZWZpbml0aW9uIGNvdWxkIGJlIGZvdW5kLgotICAgIHsgRVJfRlVOQ1RJT05fTk9UX0ZPVU5ELAotICAgICAiRnVua3Rpb24gbWl0IE5hbWVuIHswfSBpc3QgbmljaHQgdm9yaGFuZGVuIn0sCi0KLSAgICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoZSBYU0xUIGluc3RydWN0aW9uCi0gICAgLy8gdGhhdCBpcyBuYW1lZCBieSB0aGUgc3Vic3RpdHV0aW9uIHRleHQgezB9IG11c3Qgbm90IGNvbnRhaW4gb3RoZXIgWFNMVAotICAgIC8vIGluc3RydWN0aW9ucyAoY29udGVudCkgb3IgYSAic2VsZWN0IiBhdHRyaWJ1dGUuICBUaGUgd29yZCAic2VsZWN0IiBpcwotICAgIC8vIGFuIFhTTFQga2V5d29yZCBpbiB0aGlzIGNhc2UgYW5kIG11c3Qgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgeyBFUl9DQU5UX0hBVkVfQ09OVEVOVF9BTkRfU0VMRUNULAotICAgICAiezB9LUVsZW1lbnQgZGFyZiB3ZWRlciBDb250ZW50IG5vY2ggZWluIFwic2VsZWN0XCItQXR0cmlidXQgZW50aGFsdGVuLiJ9LAotCi0gICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUgdmFsdWUgYXJndW1lbnQKLSAgICAvLyBvZiBzZXRQYXJhbWV0ZXIgbXVzdCBiZSBhIHZhbGlkIEphdmEgT2JqZWN0LgotICAgIHsgRVJfSU5WQUxJRF9TRVRfUEFSQU1fVkFMVUUsCi0gICAgICJXZXJ0IHZvbiBQYXJhbWV0ZXIgezB9IG11c3MgZWluIGdcdTAwRkNsdGlnZXMgSmF2YS1PYmpla3Qgc2VpbiJ9LAotCi0gICAgeyBFUl9JTlZBTElEX05BTUVTUEFDRV9VUklfVkFMVUVfRk9SX1JFU1VMVF9QUkVGSVhfRk9SX0RFRkFVTFQsCi0gICAgICAiRGFzIHJlc3VsdC1wcmVmaXgtQXR0cmlidXQgZWluZXMgeHNsOm5hbWVzcGFjZS1hbGlhcy1FbGVtZW50cyBoYXQgZGVuIFdlcnQgXCIjZGVmYXVsdFwiLCBlcyBpc3QgYWJlciBrZWluZSBEZWtsYXJhdGlvbiBkZXMgU3RhbmRhcmQtTmFtZXNwYWNlIGltIEdcdTAwRkNsdGlna2VpdHNiZXJlaWNoIGZcdTAwRkNyIGRhcyBFbGVtZW50IHZvcmhhbmRlbiJ9LAotCi0gICAgeyBFUl9JTlZBTElEX05BTUVTUEFDRV9VUklfVkFMVUVfRk9SX1JFU1VMVF9QUkVGSVgsCi0gICAgICAiRGFzIHJlc3VsdC1wcmVmaXgtQXR0cmlidXQgZWluZXMgeHNsOm5hbWVzcGFjZS1hbGlhcy1FbGVtZW50cyBoYXQgZGVuIFdlcnQgXCJ7MH1cIiwgZXMgaXN0IGFiZXIga2VpbmUgTmFtZXNwYWNlLURla2xhcmF0aW9uIGZcdTAwRkNyIGRhcyBQclx1MDBFNGZpeCBcInswfVwiIGltIEdcdTAwRkNsdGlna2VpdHNiZXJlaWNoIGZcdTAwRkNyIGRhcyBFbGVtZW50IHZvcmhhbmRlbi4ifSwKLQotICAgIHsgRVJfU0VUX0ZFQVRVUkVfTlVMTF9OQU1FLAotICAgICAgIkRlciBGZWF0dXJlbmFtZSBkYXJmIG5pY2h0IG51bGwgaW4gVHJhbnNmb3JtZXJGYWN0b3J5LnNldEZlYXR1cmUoWmVpY2hlbmZvbGdlbm5hbWUsIGJvb2xlc2NoZXIgV2VydCkgc2Vpbi4ifSwKLQotICAgIHsgRVJfR0VUX0ZFQVRVUkVfTlVMTF9OQU1FLAotICAgICAgIkRlciBGZWF0dXJlbmFtZSBkYXJmIG5pY2h0IG51bGwgaW4gVHJhbnNmb3JtZXJGYWN0b3J5LmdldEZlYXR1cmUoWmVpY2hlbmZvbGdlbm5hbWUpIHNlaW4uIn0sCi0KLSAgICB7IEVSX1VOU1VQUE9SVEVEX0ZFQVRVUkUsCi0gICAgICAiRGFzIEZlYXR1cmUgXCJ7MH1cIiBrYW5uIG5pY2h0IGZcdTAwRkNyIGRpZXNlIFRyYW5zZm9ybWVyRmFjdG9yeSBmZXN0Z2VsZWd0IHdlcmRlbi4ifSwKLQotICAgIHsgRVJfRVhURU5TSU9OX0VMRU1FTlRfTk9UX0FMTE9XRURfSU5fU0VDVVJFX1BST0NFU1NJTkcsCi0gICAgICAgICAgIlZlcndlbmR1bmcgZGVzIEVyd2VpdGVydW5nc2VsZW1lbnRzIFwiezB9XCIgaXN0IG5pY2h0IHp1bFx1MDBFNHNzaWcsIHdlbm4gZGFzIEZlYXR1cmUgZlx1MDBGQ3IgZGllIHNpY2hlcmUgVmVyYXJiZWl0dW5nIGF1ZiBcInRydWVcIiBnZXNldHp0IGlzdC4ifSwKLQotICAgIHsgRVJfTkFNRVNQQUNFX0NPTlRFWFRfTlVMTF9OQU1FU1BBQ0UsCi0gICAgICAiUHJcdTAwRTRmaXggZlx1MDBGQ3IgTnVsbC1OYW1lc3BhY2UtVVJJIGthbm4gbmljaHQgYWJnZXJ1ZmVuIHdlcmRlbi4ifSwKLQotICAgIHsgRVJfTkFNRVNQQUNFX0NPTlRFWFRfTlVMTF9QUkVGSVgsCi0gICAgICAiTmFtZXNwYWNlLVVSSSBmXHUwMEZDciBOdWxscHJcdTAwRTRmaXgga2FubiBuaWNodCBhYmdlcnVmZW4gd2VyZGVuLiJ9LAotCi0gICAgeyBFUl9YUEFUSF9SRVNPTFZFUl9OVUxMX1FOQU1FLAotICAgICAgIkZ1bmt0aW9uc25hbWUgZGFyZiBuaWNodCBudWxsIHNlaW4uIn0sCi0KLSAgICB7IEVSX1hQQVRIX1JFU09MVkVSX05FR0FUSVZFX0FSSVRZLAotICAgICAgIkFyZ3VtZW50YW56YWhsIGRhcmYgbmljaHQgbmVnYXRpdiBzZWluLiJ9LAotICAvLyBXYXJuaW5ncy4uLgotCi0gICAgeyBXR19GT1VORF9DVVJMWUJSQUNFLAotICAgICAgIlwifVwiIGdlZnVuZGVuLCBhYmVyIGtlaW5lIEF0dHJpYnV0dm9ybGFnZSBpc3QgZ2VcdTAwRjZmZm5ldC4ifSwKLQotICAgIHsgV0dfQ09VTlRfQVRUUklCX01BVENIRVNfTk9fQU5DRVNUT1IsCi0gICAgICAiV2FybnVuZzogXCJjb3VudFwiLUF0dHJpYnV0IGVudHNwcmljaHQga2VpbmVtIFZvcmdcdTAwRTRuZ2VyIGluIHhzbDpudW1iZXIuIFppZWwgPSB7MH0ifSwKLQotICAgIHsgV0dfRVhQUl9BVFRSSUJfQ0hBTkdFRF9UT19TRUxFQ1QsCi0gICAgICAiQWx0ZSBTeW50YXg6IERlciBOYW1lIGRlcyBcImV4cHJcIi1BdHRyaWJ1dHMgd3VyZGUgaW4gXCJzZWxlY3RcIiBnZVx1MDBFNG5kZXJ0LiJ9LAotCi0gICAgeyBXR19OT19MT0NBTEVfSU5fRk9STUFUTlVNQkVSLAotICAgICAgIlhhbGFuIHZlcmFyYmVpdGV0IG5vY2ggbmljaHQgZGVuIEdlYmlldHNzY2hlbWFuYW1lbiBpbiBkZXIgZm9ybWF0LW51bWJlci1GdW5rdGlvbi4ifSwKLQotICAgIHsgV0dfTE9DQUxFX05PVF9GT1VORCwKLSAgICAgICJXYXJudW5nOiBHZWJpZXRzc2NoZW1hIGZcdTAwRkNyIHhtbDpsYW5nPXswfSBrb25udGUgbmljaHQgZ2VmdW5kZW4gd2VyZGVuIn0sCi0KLSAgICB7IFdHX0NBTk5PVF9NQUtFX1VSTF9GUk9NLAotICAgICAgIlVSTCBrYW5uIG5pY2h0IGVyc3RlbGx0IHdlcmRlbiBhdXM6IHswfSJ9LAotCi0gICAgeyBXR19DQU5OT1RfTE9BRF9SRVFVRVNURURfRE9DLAotICAgICAgIkFuZ2Vmb3JkZXJ0ZXMgRG9rdW1lbnQga2FubiBuaWNodCBnZWxhZGVuIHdlcmRlbjogezB9In0sCi0KLSAgICB7IFdHX0NBTk5PVF9GSU5EX0NPTExBVE9SLAotICAgICAgIkNvbGxhdG9yIGZcdTAwRkNyIDxzb3J0IHhtbDpsYW5nPXswfSBrb25udGUgbmljaHQgZ2VmdW5kZW4gd2VyZGVuIn0sCi0KLSAgICB7IFdHX0ZVTkNUSU9OU19TSE9VTERfVVNFX1VSTCwKLSAgICAgICJBbHRlIFN5bnRheDogRGllIEZ1bmt0aW9uc2Fud2Vpc3VuZyBtdXNzIGVpbmUgVVJMIHZvbiB7MH0gc2VpbiJ9LAotCi0gICAgeyBXR19FTkNPRElOR19OT1RfU1VQUE9SVEVEX1VTSU5HX1VURjgsCi0gICAgICAiQ29kaWVydW5nIG5pY2h0IHVudGVyc3RcdTAwRkN0enQ6IHswfS4gVVRGLTggd2lyZCB2ZXJ3ZW5kZXQifSwKLQotICAgIHsgV0dfRU5DT0RJTkdfTk9UX1NVUFBPUlRFRF9VU0lOR19KQVZBLAotICAgICAgIkNvZGllcnVuZyBuaWNodCB1bnRlcnN0XHUwMEZDdHp0OiB7MH0uIEphdmEgezF9IHdpcmQgdmVyd2VuZGV0In0sCi0KLSAgICB7IFdHX1NQRUNJRklDSVRZX0NPTkZMSUNUUywKLSAgICAgICJHZW5hdWlna2VpdHNrb25mbGlrdGUgZ2VmdW5kZW46IHswfSBMZXR6dGUgaW4gU3R5bGVzaGVldCBnZWZ1bmRlbmUgQW5nYWJlIHdpcmQgdmVyd2VuZGV0LiJ9LAotCi0gICAgeyBXR19QQVJTSU5HX0FORF9QUkVQQVJJTkcsCi0gICAgICAiPT09PT09PT09IHswfSB3aXJkIGdlcGFyc3QgdW5kIHZvcmJlcmVpdGV0ID09PT09PT09PT0ifSwKLQotICAgIHsgV0dfQVRUUl9URU1QTEFURSwKLSAgICAgIkF0dHJpYnV0dm9ybGFnZSB7MH0ifSwKLQotICAgIHsgV0dfQ09ORkxJQ1RfQkVUV0VFTl9YU0xTVFJJUFNQQUNFX0FORF9YU0xQUkVTRVJWRVNQQUNFLAotICAgICAgIlx1MDBEQ2JlcmVpbnN0aW1tdW5nc2tvbmZsaWt0IHp3aXNjaGVuIHhzbDpzdHJpcC1zcGFjZSB1bmQgeHNsOnByZXNlcnZlLXNwYWNlIn0sCi0KLSAgICB7IFdHX0FUVFJJQl9OT1RfSEFORExFRCwKLSAgICAgICJYYWxhbiB2ZXJhcmJlaXRldCBub2NoIG5pY2h0IGRhcyB7MH0tQXR0cmlidXQuIn0sCi0KLSAgICB7IFdHX05PX0RFQ0lNQUxGT1JNQVRfREVDTEFSQVRJT04sCi0gICAgICAiS2VpbmUgRGVrbGFyYXRpb24gZlx1MDBGQ3IgRGV6aW1hbGZvcm1hdCBnZWZ1bmRlbjogezB9In0sCi0KLSAgICB7IFdHX09MRF9YU0xUX05TLAotICAgICAiRmVobGVuZGVyIG9kZXIgZmFsc2NoZXIgWFNMVC1OYW1lc3BhY2UuICJ9LAotCi0gICAgeyBXR19PTkVfREVGQVVMVF9YU0xERUNJTUFMRk9STUFUX0FMTE9XRUQsCi0gICAgICAiTnVyIGVpbmUgU3RhbmRhcmQteHNsOmRlY2ltYWwtZm9ybWF0LURla2xhcmF0aW9uIGlzdCB6dWxcdTAwRTRzc2lnLiJ9LAotCi0gICAgeyBXR19YU0xERUNJTUFMRk9STUFUX05BTUVTX01VU1RfQkVfVU5JUVVFLAotICAgICAgInhzbDpkZWNpbWFsLWZvcm1hdC1OYW1lbiBtXHUwMEZDc3NlbiBlaW5kZXV0aWcgc2Vpbi4gTmFtZSBcInswfVwiIHd1cmRlIGR1cGxpemllcnQuIn0sCi0KLSAgICB7IFdHX0lMTEVHQUxfQVRUUklCVVRFLAotICAgICAgInswfSBoYXQgZWluIHVuZ1x1MDBGQ2x0aWdlcyBBdHRyaWJ1dDogezF9In0sCi0KLSAgICB7IFdHX0NPVUxEX05PVF9SRVNPTFZFX1BSRUZJWCwKLSAgICAgICJOYW1lc3BhY2UtUHJcdTAwRTRmaXgga29ubnRlIG5pY2h0IGF1ZmdlbFx1MDBGNnN0IHdlcmRlbjogezB9LiBEZXIgS25vdGVuIHdpcmQgaWdub3JpZXJ0LiJ9LAotCi0gICAgeyBXR19TVFlMRVNIRUVUX1JFUVVJUkVTX1ZFUlNJT05fQVRUUklCLAotICAgICAgInhzbDpzdHlsZXNoZWV0IGVyZm9yZGVydCBlaW4gXCJ2ZXJzaW9uXCItQXR0cmlidXQuIn0sCi0KLSAgICB7IFdHX0lMTEVHQUxfQVRUUklCVVRFX05BTUUsCi0gICAgICAiVW5nXHUwMEZDbHRpZ2VyIEF0dHJpYnV0bmFtZTogezB9In0sCi0KLSAgICB7IFdHX0lMTEVHQUxfQVRUUklCVVRFX1ZBTFVFLAotICAgICAgIlVuZ1x1MDBGQ2x0aWdlciBXZXJ0IGZcdTAwRkNyIEF0dHJpYnV0IHswfTogezF9In0sCi0KLSAgICB7IFdHX0VNUFRZX1NFQ09ORF9BUkcsCi0gICAgICAiUmVzdWx0aWVyZW5kZXMgTm9kZVNldCBhdXMgendlaXRlbSBBcmd1bWVudCB2b24gRG9rdW1lbnRmdW5rdGlvbiBpc3QgbGVlci4gR2ViZW4gU2llIGVpbiBsZWVyZXMgTm9kZVNldCB6dXJcdTAwRkNjay4ifSwKLQotICAvL0ZvbGxvd2luZyBhcmUgdGhlIG5ldyBXQVJOSU5HIGtleXMgYWRkZWQgaW4gWEFMQU4gY29kZSBiYXNlIGFmdGVyIEpkayAxLjQgKFhhbGFuIDIuMi1EMTEpCi0KLSAgICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIm5hbWUiIGFuZCAieHNsOnByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24iIGFyZSBrZXl3b3JkcwotICAgIC8vIGFuZCBtdXN0IG5vdCBiZSB0cmFuc2xhdGVkLgotICAgIHsgV0dfUFJPQ0VTU0lOR0lOU1RSVUNUSU9OX05BTUVfQ0FOVF9CRV9YTUwsCi0gICAgICAiRGVyIFdlcnQgZGVzIFwibmFtZVwiLUF0dHJpYnV0cyBkZXMgeHNsOnByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24tTmFtZW5zIGRhcmYgbmljaHQgXCJ4bWxcIiBzZWluIn0sCi0KLSAgICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIm5hbWUiIGFuZCAieHNsOnByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24iIGFyZSBrZXl3b3JkcwotICAgIC8vIGFuZCBtdXN0IG5vdCBiZSB0cmFuc2xhdGVkLiAgIk5DTmFtZSIgaXMgYW4gWE1MIGRhdGEtdHlwZSBhbmQgbXVzdCBub3QgYmUKLSAgICAvLyB0cmFuc2xhdGVkLgotICAgIHsgV0dfUFJPQ0VTU0lOR0lOU1RSVUNUSU9OX05PVFZBTElEX05DTkFNRSwKLSAgICAgICJEZXIgV2VydCBkZXMgXCJuYW1lXCItQXR0cmlidXRzIHZvbiB4c2w6cHJvY2Vzc2luZy1pbnN0cnVjdGlvbiBtdXNzIGVpbiBnXHUwMEZDbHRpZ2VyIE5DTmFtZSBzZWluOiB7MH0ifSwKLQotICAgIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgcmVwb3J0ZWQgaWYgdGhlIHN0eWxlc2hlZXQgdGhhdCBpcwotICAgIC8vIGJlaW5nIHByb2Nlc3NlZCBhdHRlbXB0ZWQgdG8gY29uc3RydWN0IGFuIFhNTCBkb2N1bWVudCB3aXRoIGFuIGF0dHJpYnV0ZSBpbiBhCi0gICAgLy8gcGxhY2Ugb3RoZXIgdGhhbiBvbiBhbiBlbGVtZW50LiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHNwZWNpZmllcyB0aGUgbmFtZSBvZgotICAgIC8vIHRoZSBhdHRyaWJ1dGUuCi0gICAgeyBXR19JTExFR0FMX0FUVFJJQlVURV9QT1NJVElPTiwKLSAgICAgICJBdHRyaWJ1dCB7MH0ga2FubiBuaWNodCBuYWNoIHVudGVyZ2VvcmRuZXRlbiBLbm90ZW4gb2RlciB2b3IgZGVtIEVyc3RlbGxlbiBlaW5lcyBFbGVtZW50cyBoaW56dWdlZlx1MDBGQ2d0IHdlcmRlbi4gQXR0cmlidXQgd2lyZCBpZ25vcmllcnQuIn0sCi0KLSAgICB7IE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiwKLSAgICAgICJFcyB3dXJkZSB2ZXJzdWNodCwgZWluIE9iamVrdCB6dSBcdTAwRTRuZGVybiwgYmVpIGRlbSBcdTAwQzRuZGVydW5nZW4gbmljaHQgenVsXHUwMEU0c3NpZyBzaW5kLiIKLSAgICB9LAotCi0gICAgLy9DaGVjazogV0hZIFRIRVJFIElTIEEgR0FQIEIvVyBOVU1CRVJTIGluIHRoZSBYU0xURXJyb3JSZXNvdXJjZXMgcHJvcGVydGllcyBmaWxlPwotCi0gIC8vIE90aGVyIG1pc2NlbGxhbmVvdXMgdGV4dCB1c2VkIGluc2lkZSB0aGUgY29kZS4uLgotICB7ICJ1aV9sYW5ndWFnZSIsICJkZSJ9LAotICB7ICAiaGVscF9sYW5ndWFnZSIsICAiZGUiIH0sCi0gIHsgICJsYW5ndWFnZSIsICAiZGUiIH0sCi0gIHsgIkJBRF9DT0RFIiwgIlBhcmFtZXRlciBmXHUwMEZDciBjcmVhdGVNZXNzYWdlIHdhciBhdVx1MDBERmVyaGFsYiBkZXMgZ1x1MDBGQ2x0aWdlbiBCZXJlaWNocyJ9LAotICB7ICAiRk9STUFUX0ZBSUxFRCIsICJBdXNuYWhtZSBiZWkgbWVzc2FnZUZvcm1hdC1BdWZydWYgYXVzZ2VsXHUwMEY2c3QifSwKLSAgeyAgInZlcnNpb24iLCAiPj4+Pj4+PiBYYWxhbi1WZXJzaW9uICJ9LAotICB7ICAidmVyc2lvbjIiLCAgIjw8PDw8PDwifSwKLSAgeyAgInllcyIsICJKYSJ9LAotICB7ICJsaW5lIiwgIlplaWxlbm51bW1lciJ9LAotICB7ICJjb2x1bW4iLCJTcGFsdGVubnVtbWVyIn0sCi0gIHsgInhzbGRvbmUiLCAiWFNMUHJvY2Vzc29yOiBGZXJ0aWcifSwKLQotCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2VzIHByb3ZpZGUgdXNhZ2UgaW5mb3JtYXRpb24KLSAgLy8gZm9yIHRoZSBYYWxhbiBQcm9jZXNzIGNvbW1hbmQgbGluZS4gICJQcm9jZXNzIiBpcyB0aGUgbmFtZSBvZiBhIEphdmEgY2xhc3MsCi0gIC8vIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuCi0gIHsgInhzbFByb2Nfb3B0aW9uIiwgIlhhbGFuLUotQmVmZWhsc3plaWxlIC0gXCJQcm9jZXNzXCItS2xhc3Nlbm9wdGlvbmVuOiJ9LAotICB7ICJ4c2xQcm9jX29wdGlvbiIsICJYYWxhbi1KLUJlZmVobHN6ZWlsZSAtIFwiUHJvY2Vzc1wiLUtsYXNzZW5vcHRpb25lbjoifSwKLSAgeyAieHNsUHJvY19pbnZhbGlkX3hzbHRjX29wdGlvbiIsICJPcHRpb24gezB9IHdpcmQgaW0gWFNMVEMtTW9kdXMgbmljaHQgdW50ZXJzdFx1MDBGQ3R6dC4ifSwKLSAgeyAieHNsUHJvY19pbnZhbGlkX3hhbGFuX29wdGlvbiIsICJPcHRpb24gezB9IGthbm4gbnVyIG1pdCAtWFNMVEMgdmVyd2VuZGV0IHdlcmRlbi4ifSwKLSAgeyAieHNsUHJvY19ub19pbnB1dCIsICJGZWhsZXI6IEtlaW4gU3R5bGVzaGVldCB1bmQga2VpbmUgRWluZ2FiZS1YTUwgYW5nZWdlYmVuLiBGXHUwMEZDaHJlbiBTaWUgZGllc2VuIEJlZmVobCBvaG5lIE9wdGlvbmVuIGZcdTAwRkNyIFZlcndlbmR1bmdzYW53ZWlzdW5nZW4gYXVzLiJ9LAotICB7ICJ4c2xQcm9jX2NvbW1vbl9vcHRpb25zIiwgIi1BbGxnZW1laW5lIE9wdGlvbmVuLSJ9LAotICB7ICJ4c2xQcm9jX3hhbGFuX29wdGlvbnMiLCAiLU9wdGlvbmVuIGZcdTAwRkNyIFhhbGFuLSJ9LAotICB7ICJ4c2xQcm9jX3hzbHRjX29wdGlvbnMiLCAiLU9wdGlvbmVuIGZcdTAwRkNyIFhTTFRDLSJ9LAotICB7ICJ4c2xQcm9jX3JldHVybl90b19jb250aW51ZSIsICIoZHJcdTAwRkNja2VuIFNpZSBkaWUgPEVpbmdhYmV0YXN0ZT4sIHVtIGZvcnR6dWZhaHJlbikifSwKLQotICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogVGhlIG9wdGlvbiBuYW1lIGFuZCB0aGUgcGFyYW1ldGVyIG5hbWUgZG8gbm90IG5lZWQgdG8KLSAgIC8vIGJlIHRyYW5zbGF0ZWQuIE9ubHkgdHJhbnNsYXRlIHRoZSBtZXNzYWdlcyBpbiBwYXJlbnRoZXNlcy4gIE5vdGUgYWxzbyB0aGF0Ci0gICAvLyBsZWFkaW5nIHdoaXRlc3BhY2UgaW4gdGhlIG1lc3NhZ2VzIGlzIHVzZWQgdG8gaW5kZW50IHRoZSB1c2FnZSBpbmZvcm1hdGlvbgotICAgLy8gZm9yIGVhY2ggb3B0aW9uIGluIHRoZSBFbmdsaXNoIG1lc3NhZ2VzLgotICAgLy8gRG8gbm90IHRyYW5zbGF0ZSB0aGUga2V5d29yZHM6IFhTTFRDLCBTQVgsIERPTSBhbmQgRFRNLgotICB7ICJvcHRpb25YU0xUQyIsICIgICBbLVhTTFRDIChYU0xUQyBmXHUwMEZDciBUcmFuc2Zvcm1hdGlvbiB2ZXJ3ZW5kZW4pXSJ9LAotICB7ICJvcHRpb25JTiIsICIgICBbLUlOIGlucHV0WE1MVVJMXSJ9LAotICB7ICJvcHRpb25YU0wiLCAiICAgWy1YU0wgWFNMVHJhbnNmb3JtYXRpb25VUkxdIn0sCi0gIHsgIm9wdGlvbk9VVCIsICAiICAgWy1PVVQgb3V0cHV0RmlsZU5hbWVdIn0sCi0gIHsgIm9wdGlvbkxYQ0lOIiwgIiAgIFstTFhDSU4gY29tcGlsZWRTdHlsZXNoZWV0RmlsZU5hbWVJbl0ifSwKLSAgeyAib3B0aW9uTFhDT1VUIiwgIiAgIFstTFhDT1VUIGNvbXBpbGVkU3R5bGVzaGVldEZpbGVOYW1lT3V0T3V0XSJ9LAotICB7ICJvcHRpb25QQVJTRVIiLCAiICAgWy1QQVJTRVIgZnVsbHkgcXVhbGlmaWVkIGNsYXNzIG5hbWUgb2YgcGFyc2VyIGxpYWlzb25dIn0sCi0gIHsgICJvcHRpb25FIiwgIiAgIFstRSAoRW50aXR5cmVmZXJlbnplbiBuaWNodCBlaW5ibGVuZGVuKV0ifSwKLSAgeyAgIm9wdGlvblYiLCAgIiAgIFstRSAoRW50aXR5cmVmZXJlbnplbiBuaWNodCBlaW5ibGVuZGVuKV0ifSwKLSAgeyAgIm9wdGlvblFDIiwgIiAgIFstUUMgKFN0aWxsZSBNdXN0ZXJrb25mbGlrdHdhcm51bmdlbildIn0sCi0gIHsgICJvcHRpb25RIiwgIiAgIFstUSAgKFNpbGVudC1Nb2R1cyldIn0sCi0gIHsgICJvcHRpb25MRiIsICIgICBbLUxGIChOdXIgWmVpbGVudm9yc2NoXHUwMEZDYmUgYmVpIEF1c2dhYmUgdmVyd2VuZGVuIHtTdGFuZGFyZCBpc3QgQ1IvTEZ9KV0ifSwKLSAgeyAgIm9wdGlvbkNSIiwgIiAgIFstQ1IgKE51ciBaZWlsZW5zY2hhbHR1bmdlbiBiZWkgQXVzZ2FiZSB2ZXJ3ZW5kZW4ge1N0YW5kYXJkIGlzdCBDUi9MRn0pXSJ9LAotICB7ICJvcHRpb25FU0NBUEUiLCAiICAgWy1FU0NBUEUgKEVzY2FwZXplaWNoZW4ge1N0YW5kYXJkIGlzdCA8PiZcIidcclxufV0ifSwKLSAgeyAib3B0aW9uSU5ERU5UIiwgIiAgIFstSU5ERU5UIChTdGV1ZXJuLCB3aWUgdmllbGUgTGVlcnplaWNoZW4gZGVyIEVpbnp1ZyBlbnRoYWx0ZW4gc29sbCB7U3RhbmRhcmQgaXN0IDB9KV0ifSwKLSAgeyAib3B0aW9uVFQiLCAiICAgWy1UVCAoVm9ybGFnZW4gdmVyZm9sZ2VuLCB3ZW5uIGRpZXNlIGF1ZmdlcnVmZW4gd2VyZGVuLildIn0sCi0gIHsgIm9wdGlvblRHIiwgIiAgIFstVEcgKEplZGVzIEdlbmVyaWVydW5nc2VyZWlnbmlzIHZlcmZvbGdlbi4pXSJ9LAotICB7ICJvcHRpb25UUyIsICIgICBbLVRTIChKZWRlcyBBdXN3YWhsZXJlaWduaXMgdmVyZm9sZ2VuLildIn0sCi0gIHsgICJvcHRpb25UVEMiLCAiICAgWy1UVEMgKFVudGVyZ2VvcmRuZXRlIFZvcmxhZ2VuIHZlcmZvbGdlbiwgd2VubiBkaWVzZSB2ZXJhcmJlaXRldCB3ZXJkZW4uKV0ifSwKLSAgeyAib3B0aW9uVENMQVNTIiwgIiAgIFstVENMQVNTIChUcmFjZUxpc3RlbmVyLUtsYXNzZSBmXHUwMEZDciBUcmFjZWVyd2VpdGVydW5nZW4uKV0ifSwKLSAgeyAib3B0aW9uVkFMSURBVEUiLCAiICAgWy1WQUxJREFURSAoRmVzdGxlZ2VuLCBvYiBkaWUgVmFsaWRpZXJ1bmcgYXVzZ2VmXHUwMEZDaHJ0IHdpcmQuIFZhbGlkaWVydW5nIGlzdCBzdGFuZGFyZG1cdTAwRTRcdTAwREZpZyBhdXNnZXNjaGFsdGV0LildIn0sCi0gIHsgIm9wdGlvbkVEVU1QIiwgIiAgIFstRURVTVAge29wdGlvbmFsZXIgRGF0ZWluYW1lfSAoU3RhY2sgRHVtcCBiZWkgRmVobGVyIHZvcm5laG1lbi4pXSJ9LAotICB7ICAib3B0aW9uWE1MIiwgIiAgIFstWE1MIChYTUwtRm9ybWF0dGVyIHZlcndlbmRlbiB1bmQgWE1MLUhlYWRlciBoaW56dWZcdTAwRkNnZW4uKV0ifSwKLSAgeyAgIm9wdGlvblRFWFQiLCAiICAgWy1URVhUIChFaW5mYWNoZW4gVGV4dC1Gb3JtYXR0ZXIgdmVyd2VuZGVuLildIn0sCi0gIHsgICJvcHRpb25IVE1MIiwgIiAgIFstSFRNTCAoSFRNTC1Gb3JtYXR0ZXIgdmVyd2VuZGVuLildIn0sCi0gIHsgICJvcHRpb25QQVJBTSIsICIgICBbLVBBUkFNIG5hbWUgZXhwcmVzc2lvbiAoU3R5bGVzaGVldC1QYXJhbWV0ZXIgZmVzdGxlZ2VuKV0ifSwKLSAgeyAgIm5vUGFyc2VybXNnMSIsICJYU0wtUHJvemVzcyB3YXIgbmljaHQgZXJmb2xncmVpY2guIn0sCi0gIHsgICJub1BhcnNlcm1zZzIiLCAiKiogUGFyc2VyIGtvbm50ZSBuaWNodCBnZWZ1bmRlbiB3ZXJkZW4gKioifSwKLSAgeyAibm9QYXJzZXJtc2czIiwgICJQclx1MDBGQ2ZlbiBTaWUgZGVuIENsYXNzcGF0aC4ifSwKLSAgeyAibm9QYXJzZXJtc2c0IiwgIldlbm4gU2llIG5pY2h0IFx1MDBGQ2JlciBkZW4gWE1MLVBhcnNlciBmXHUwMEZDciBKYXZhIHZvbiBJQk0gdmVyZlx1MDBGQ2dlbiwga1x1MDBGNm5uZW4gU2llIGlobiBoaWVyIGhlcnVudGVybGFkZW46In0sCi0gIHsgIm5vUGFyc2VybXNnNSIsICJJQk1zIEFscGhhV29ya3M6IGh0dHA6Ly93d3cuYWxwaGF3b3Jrcy5pYm0uY29tL2Zvcm11bGEveG1sIn0sCi0gIHsgIm9wdGlvblVSSVJFU09MVkVSIiwgIiAgIFstVVJJUkVTT0xWRVIgZnVsbCBjbGFzcyBuYW1lIChVUklSZXNvbHZlciBmXHUwMEZDciBkaWUgQXVmbFx1MDBGNnN1bmcgdm9uIFVSSXMpXSJ9LAotICB7ICJvcHRpb25FTlRJVFlSRVNPTFZFUiIsICAiICAgWy1FTlRJVFlSRVNPTFZFUiBmdWxsIGNsYXNzIG5hbWUgKEVudGl0eVJlc29sdmVyIGZcdTAwRkNyIGRpZSBBdWZsXHUwMEY2c3VuZyB2b24gRW50aXR5cyldIn0sCi0gIHsgIm9wdGlvbkNPTlRFTlRIQU5ETEVSIiwgICIgICBbLUNPTlRFTlRIQU5ETEVSIGZ1bGwgY2xhc3MgbmFtZSAoQ29udGVudEhhbmRsZXIgZlx1MDBGQ3IgZGllIFNlcmlhbGlzaWVydW5nIGRlciBBdXNnYWJlKV0ifSwKLSAgeyAgIm9wdGlvbkxJTkVOVU1CRVJTIiwgICIgICBbLUwgdXNlIGxpbmUgbnVtYmVycyBmb3Igc291cmNlIGRvY3VtZW50XSJ9LAotICB7ICJvcHRpb25TRUNVUkVQUk9DRVNTSU5HIiwgIiAgIFstU0VDVVJFIChGZWF0dXJlIGZcdTAwRkNyIGRpZSBzaWNoZXJlIFZlcmFyYmVpdHVuZyBhdWYgXCJ0cnVlXCIgc2V0emVuLildIn0sCi0KLSAgICAvLyBGb2xsb3dpbmcgYXJlIHRoZSBuZXcgb3B0aW9ucyBhZGRlZCBpbiBYU0xURXJyb3JSZXNvdXJjZXMucHJvcGVydGllcyBmaWxlcyBhZnRlciBKZGsgMS40IChYYWxhbiAyLjItRDExKQotCi0KLSAgeyAgIm9wdGlvbk1FRElBIiwgICIgICBbLU1FRElBIG1lZGlhVHlwZSAoXCJtZWRpYVwiLUF0dHJpYnV0IHZlcndlbmRlbiwgdW0gbWl0IGVpbmVtIERva3VtZW50IHZlcmtuXHUwMEZDcGZ0ZXMgU3R5bGVzaGVldCB6dSBmaW5kZW4uKV0ifSwKLSAgeyAgIm9wdGlvbkZMQVZPUiIsICAiICAgWy1GTEFWT1IgZmxhdm9yTmFtZSAoczJzPVNBWCBvZGVyIGQyZD1ET00gZXhwbGl6aXQgZlx1MDBGQ3IgVHJhbnNmb3JtYXRpb24gdmVyd2VuZGVuLildICJ9LCAvLyBBZGRlZCBieSBzYm9hZy9zY3VyY3VydTsgZXhwZXJpbWVudGFsCi0gIHsgIm9wdGlvbkRJQUciLCAiICAgWy1ESUFHIChHZXNhbXRkYXVlciBkZXIgVHJhbnNmb3JtYXRpb24gaW4gTWlsbGlzZWt1bmRlbiBkcnVja2VuLildIn0sCi0gIHsgIm9wdGlvbklOQ1JFTUVOVEFMIiwgICIgICBbLUlOQ1JFTUVOVEFMIChpbmtyZW1lbnRlbGxlIERUTS1Lb25zdHJ1a3Rpb24gYW5mb3JkZXJuLCBpbmRlbSBodHRwOi8veG1sLmFwYWNoZS5vcmcveGFsYW4vZmVhdHVyZXMvaW5jcmVtZW50YWwgYXVmIFwidHJ1ZVwiIGdlc2V0enQgd2lyZC4pXSJ9LAotICB7ICAib3B0aW9uTk9PUFRJTUlNSVpFIiwgICIgICBbLU5PT1BUSU1JTUlaRSAoa2VpbmUgU3R5bGVzaGVldC1PcHRpbWllcnVuZ3N2ZXJhcmJlaXR1bmcgYW5mb3JkZXJuLCBpbmRlbSBodHRwOi8veG1sLmFwYWNoZS5vcmcveGFsYW4vZmVhdHVyZXMvb3B0aW1pemUgYXVmIFwiZmFsc2VcIiBnZXNldHp0IHdpcmQuKV0ifSwKLSAgeyAib3B0aW9uUkwiLCAgIiAgIFstUkwgcmVjdXJzaW9ubGltaXQgKG51bWVyaXNjaGVuIEdyZW56d2VydCBmXHUwMEZDciBTdHlsZXNoZWV0LVJla3Vyc2lvbnN0aWVmZSBiZWthbm50IG1hY2hlbi4pXSJ9LAotICB7ICAgIm9wdGlvblhPIiwgICIgICBbLVhPIFt0cmFuc2xldE5hbWVdIChOYW1lIGRlbSBnZW5lcmllcnRlbiBUcmFuc2xldCB6dXdlaXNlbildIn0sCi0gIHsgICJvcHRpb25YRCIsICIgICBbLVhEIGRlc3RpbmF0aW9uRGlyZWN0b3J5IChaaWVsdmVyemVpY2huaXMgZlx1MDBGQ3IgVHJhbnNsZXQgYW5nZWJlbildIn0sCi0gIHsgICJvcHRpb25YSiIsICAiICAgWy1YSiBqYXJmaWxlICh2ZXJwYWNrdCBUcmFuc2xldC1LbGFzc2VuIGluIGVpbmVyIEpBUi1EYXRlaSBtaXQgZGVtIE5hbWVuIDxqYXJmaWxlPildIn0sCi0gIHsgICAib3B0aW9uWFAiLCAgIiAgIFstWFAgcGFja2FnZSAoZ2lidCBlaW4gUGFja2FnZW5hbWVuc3ByXHUwMEU0Zml4IGZcdTAwRkNyIGFsbGUgZ2VuZXJpZXJ0ZW4gVHJhbnNsZXQtS2xhc3NlbiBhbildIn0sCi0KLSAgLy9BZGRJVElPTkFMICBTVFJJTkdTIHRoYXQgbmVlZCBMMTBuCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgZGVzY3JpYmVzIHVzYWdlIG9mIGEgcGFydGljdWxhcgotICAvLyBjb21tYW5kLWxpbmUgb3B0aW9uIHRoYXQgaXMgdXNlZCB0byBlbmFibGUgdGhlICJ0ZW1wbGF0ZSBpbmxpbmluZyIKLSAgLy8gb3B0aW1pemF0aW9uLiAgVGhlIG9wdGltaXphdGlvbiBpbnZvbHZlcyBtYWtpbmcgYSBjb3B5IG9mIHRoZSBjb2RlCi0gIC8vIGdlbmVyYXRlZCBmb3IgYSB0ZW1wbGF0ZSBpbiBhbm90aGVyIHRlbXBsYXRlIHRoYXQgcmVmZXJzIHRvIGl0LgotICB7ICJvcHRpb25YTiIsICAiICAgWy1YTiAoYWt0aXZpZXJ0IFZvcmxhZ2VuLUlubGluaW5nKV0iIH0sCi0gIHsgIm9wdGlvblhYIiwgICIgICBbLVhYIChzY2hhbHRldCBkaWUgenVzXHUwMEU0dHpsaWNoZSBEZWJ1Z2dpbmctTWVsZHVuZ3NhdXNnYWJlIGVpbildIn0sCi0gIHsgIm9wdGlvblhUIiAsICIgICBbLVhUICh3ZW5uIG1cdTAwRjZnbGljaCwgVHJhbnNsZXQgZlx1MDBGQ3IgVHJhbnNmb3JtYXRpb24gdmVyd2VuZGVuKV0ifSwKLSAgeyAiZGlhZ1RpbWluZyIsIiAtLS0tLS0tLS0gVHJhbnNmb3JtYXRpb24gdm9uIHswfSBcdTAwRkNiZXIgezF9IGRhdWVydGUgezJ9IG1zIiB9LAotICB7ICJyZWN1cnNpb25Ub29EZWVwIiwiVm9ybGFnZW52ZXJzY2hhY2h0ZWx1bmcgenUgdGllZi4gVmVyc2NoYWNodGVsdW5nID0gezB9LCBWb3JsYWdlIHsxfSB7Mn0iIH0sCi0gIHsgIm5hbWVJcyIsICJOYW1lIGlzdCIgfSwKLSAgeyAibWF0Y2hQYXR0ZXJuSXMiLCAiVmVyZ2xlaWNoc211c3RlciBpc3QiIH0KLQotICB9OwotCi0gIH0KLSAgLy8gPT09PT09PT09PT09PT09PT0gSU5GUkFTVFJVQ1RVUkUgPT09PT09PT09PT09PT09PT09PT09PQotCi0gIC8qKiBTdHJpbmcgZm9yIHVzZSB3aGVuIGEgYmFkIGVycm9yIGNvZGUgd2FzIGVuY291bnRlcmVkLiAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBCQURfQ09ERSA9ICJCQURfQ09ERSI7Ci0KLSAgLyoqIFN0cmluZyBmb3IgdXNlIHdoZW4gZm9ybWF0dGluZyBvZiB0aGUgZXJyb3Igc3RyaW5nIGZhaWxlZC4gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBGT1JNQVRfRkFJTEVEID0gIkZPUk1BVF9GQUlMRUQiOwotCi0gIC8qKiBHZW5lcmFsIGVycm9yIHN0cmluZy4gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJPUl9TVFJJTkcgPSAiI2Vycm9yIjsKLQotICAvKiogU3RyaW5nIHRvIHByZXBlbmQgdG8gZXJyb3IgbWVzc2FnZXMuICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJPUl9IRUFERVIgPSAiRXJyb3I6ICI7Ci0KLSAgLyoqIFN0cmluZyB0byBwcmVwZW5kIHRvIHdhcm5pbmcgbWVzc2FnZXMuICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdBUk5JTkdfSEVBREVSID0gIldhcm5pbmc6ICI7Ci0KLSAgLyoqIFN0cmluZyB0byBzcGVjaWZ5IHRoZSBYU0xUIG1vZHVsZS4gICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFhTTF9IRUFERVIgPSAiWFNMVCAiOwotCi0gIC8qKiBTdHJpbmcgdG8gc3BlY2lmeSB0aGUgWE1MIHBhcnNlciBtb2R1bGUuICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxfSEVBREVSID0gIlhNTCAiOwotCi0gIC8qKiBJIGRvbid0IHRoaW5rIHRoaXMgaXMgdXNlZCBhbnkgbW9yZS4KLSAgICogQGRlcHJlY2F0ZWQgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFFVRVJZX0hFQURFUiA9ICJQQVRURVJOICI7Ci0KLQotICAgIH0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwvcmVzL1hTTFRFcnJvclJlc291cmNlc19lbi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC9yZXMvWFNMVEVycm9yUmVzb3VyY2VzX2VuLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGZiNTM0OGIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC9yZXMvWFNMVEVycm9yUmVzb3VyY2VzX2VuLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzMyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBYU0xURXJyb3JSZXNvdXJjZXNfZW4uamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xMyAxMDoxODozMCBwdmVkdWxhIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnJlczsKLQotCi0vKioKLSAqIERlZmF1bHQgaW1wbGVtZW50YXRpb24gb2YgWFNMVEVycm9yUmVzb3VyY2VzLiAgVGhpcyBpcyBqdXN0Ci0gKiBhbiBlbXB0eSBjbGFzcy4KLSAqIEB4c2wudXNhZ2UgYWR2YW5jZWQKLSAqLwotcHVibGljIGNsYXNzIFhTTFRFcnJvclJlc291cmNlc19lbiBleHRlbmRzIFhTTFRFcnJvclJlc291cmNlcwotewotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC9yZXMvWFNMVEVycm9yUmVzb3VyY2VzX2VzLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3Jlcy9YU0xURXJyb3JSZXNvdXJjZXNfZXMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZWYwYjBmNi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3Jlcy9YU0xURXJyb3JSZXNvdXJjZXNfZXMuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE0NDcgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwucmVzOwotCi1pbXBvcnQgamF2YS51dGlsLkxpc3RSZXNvdXJjZUJ1bmRsZTsKLWltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwotaW1wb3J0IGphdmEudXRpbC5NaXNzaW5nUmVzb3VyY2VFeGNlcHRpb247Ci1pbXBvcnQgamF2YS51dGlsLlJlc291cmNlQnVuZGxlOwotCi0vKioKLSAqIFNldCB1cCBlcnJvciBtZXNzYWdlcy4KLSAqIFdlIGJ1aWxkIGEgdHdvIGRpbWVuc2lvbmFsIGFycmF5IG9mIG1lc3NhZ2Uga2V5cyBhbmQKLSAqIG1lc3NhZ2Ugc3RyaW5ncy4gSW4gb3JkZXIgdG8gYWRkIGEgbmV3IG1lc3NhZ2UgaGVyZSwKLSAqIHlvdSBuZWVkIHRvIGZpcnN0IGFkZCBhIFN0cmluZyBjb25zdGFudC4gQW5kCi0gKiAgeW91IG5lZWQgdG8gZW50ZXIga2V5ICwgdmFsdWUgcGFpciBhcyBwYXJ0IG9mIGNvbnRlbnRzCi0gKiBBcnJheS4gWW91IGFsc28gbmVlZCB0byB1cGRhdGUgTUFYX0NPREUgZm9yIGVycm9yIHN0cmluZ3MKLSAqIGFuZCBNQVhfV0FSTklORyBmb3Igd2FybmluZ3MgKCBOZWVkZWQgZm9yIG9ubHkgaW5mb3JtYXRpb24KLSAqIHB1cnBvc2UgKQotICovCi1wdWJsaWMgY2xhc3MgWFNMVEVycm9yUmVzb3VyY2VzX2VzIGV4dGVuZHMgTGlzdFJlc291cmNlQnVuZGxlCi17Ci0KLS8qCi0gKiBUaGlzIGZpbGUgY29udGFpbnMgZXJyb3IgYW5kIHdhcm5pbmcgbWVzc2FnZXMgcmVsYXRlZCB0byBYYWxhbiBFcnJvcgotICogSGFuZGxpbmcuCi0gKgotICogIEdlbmVyYWwgbm90ZXMgdG8gdHJhbnNsYXRvcnM6Ci0gKgotICogIDEpIFhhbGFuIChvciBtb3JlIHByb3Blcmx5LCBYYWxhbi1pbnRlcnByZXRpdmUpIGFuZCBYU0xUQyBhcmUgbmFtZXMgb2YKLSAqICAgICBjb21wb25lbnRzLgotICogICAgIFhTTFQgaXMgYW4gYWNyb255bSBmb3IgIlhNTCBTdHlsZXNoZWV0IExhbmd1YWdlOiBUcmFuc2Zvcm1hdGlvbnMiLgotICogICAgIFhTTFRDIGlzIGFuIGFjcm9ueW0gZm9yIFhTTFQgQ29tcGlsZXIuCi0gKgotICogIDIpIEEgc3R5bGVzaGVldCBpcyBhIGRlc2NyaXB0aW9uIG9mIGhvdyB0byB0cmFuc2Zvcm0gYW4gaW5wdXQgWE1MIGRvY3VtZW50Ci0gKiAgICAgaW50byBhIHJlc3VsdGFudCBYTUwgZG9jdW1lbnQgKG9yIEhUTUwgZG9jdW1lbnQgb3IgdGV4dCkuICBUaGUKLSAqICAgICBzdHlsZXNoZWV0IGl0c2VsZiBpcyBkZXNjcmliZWQgaW4gdGhlIGZvcm0gb2YgYW4gWE1MIGRvY3VtZW50LgotICoKLSAqICAzKSBBIHRlbXBsYXRlIGlzIGEgY29tcG9uZW50IG9mIGEgc3R5bGVzaGVldCB0aGF0IGlzIHVzZWQgdG8gbWF0Y2ggYQotICogICAgIHBhcnRpY3VsYXIgcG9ydGlvbiBvZiBhbiBpbnB1dCBkb2N1bWVudCBhbmQgc3BlY2lmaWVzIHRoZSBmb3JtIG9mIHRoZQotICogICAgIGNvcnJlc3BvbmRpbmcgcG9ydGlvbiBvZiB0aGUgb3V0cHV0IGRvY3VtZW50LgotICoKLSAqICA0KSBBbiBlbGVtZW50IGlzIGEgbWFyay11cCB0YWcgaW4gYW4gWE1MIGRvY3VtZW50OyBhbiBhdHRyaWJ1dGUgaXMgYQotICogICAgIG1vZGlmaWVyIG9uIHRoZSB0YWcuICBGb3IgZXhhbXBsZSwgaW4gPGVsZW0gYXR0cj0ndmFsJyBhdHRyMj0ndmFsMic+Ci0gKiAgICAgImVsZW0iIGlzIGFuIGVsZW1lbnQgbmFtZSwgImF0dHIiIGFuZCAiYXR0cjIiIGFyZSBhdHRyaWJ1dGUgbmFtZXMgd2l0aAotICogICAgIHRoZSB2YWx1ZXMgInZhbCIgYW5kICJ2YWwyIiwgcmVzcGVjdGl2ZWx5LgotICoKLSAqICA1KSBBIG5hbWVzcGFjZSBkZWNsYXJhdGlvbiBpcyBhIHNwZWNpYWwgYXR0cmlidXRlIHRoYXQgaXMgdXNlZCB0byBhc3NvY2lhdGUKLSAqICAgICBhIHByZWZpeCB3aXRoIGEgVVJJICh0aGUgbmFtZXNwYWNlKS4gIFRoZSBtZWFuaW5ncyBvZiBlbGVtZW50IG5hbWVzIGFuZAotICogICAgIGF0dHJpYnV0ZSBuYW1lcyB0aGF0IHVzZSB0aGF0IHByZWZpeCBhcmUgZGVmaW5lZCB3aXRoIHJlc3BlY3QgdG8gdGhhdAotICogICAgIG5hbWVzcGFjZS4KLSAqCi0gKiAgNikgIlRyYW5zbGV0IiBpcyBhbiBpbnZlbnRlZCB0ZXJtIHRoYXQgZGVzY3JpYmVzIHRoZSBjbGFzcyBmaWxlIHRoYXQKLSAqICAgICByZXN1bHRzIGZyb20gY29tcGlsaW5nIGFuIFhNTCBzdHlsZXNoZWV0IGludG8gYSBKYXZhIGNsYXNzLgotICoKLSAqICA3KSBYUGF0aCBpcyBhIHNwZWNpZmljYXRpb24gdGhhdCBkZXNjcmliZXMgYSBub3RhdGlvbiBmb3IgaWRlbnRpZnlpbmcKLSAqICAgICBub2RlcyBpbiBhIHRyZWUtc3RydWN0dXJlZCByZXByZXNlbnRhdGlvbiBvZiBhbiBYTUwgZG9jdW1lbnQuICBBbgotICogICAgIGluc3RhbmNlIG9mIHRoYXQgbm90YXRpb24gaXMgcmVmZXJyZWQgdG8gYXMgYW4gWFBhdGggZXhwcmVzc2lvbi4KLSAqCi0gKi8KLQotICAvKgotICAgKiBTdGF0aWMgdmFyaWFibGVzCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX05BTUVTUEFDRV9VUklfVkFMVUVfRk9SX1JFU1VMVF9QUkVGSVggPQotICAgICAgICAiRVJfSU5WQUxJRF9TRVRfTkFNRVNQQUNFX1VSSV9WQUxVRV9GT1JfUkVTVUxUX1BSRUZJWCI7Ci0KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9OQU1FU1BBQ0VfVVJJX1ZBTFVFX0ZPUl9SRVNVTFRfUFJFRklYX0ZPUl9ERUZBVUxUID0KLSAgICAgICAgIkVSX0lOVkFMSURfTkFNRVNQQUNFX1VSSV9WQUxVRV9GT1JfUkVTVUxUX1BSRUZJWF9GT1JfREVGQVVMVCI7Ci0KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fQ1VSTFlCUkFDRSA9ICJFUl9OT19DVVJMWUJSQUNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCA9ICJFUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSUxMRUdBTF9BVFRSSUJVVEUgPSAiRVJfSUxMRUdBTF9BVFRSSUJVVEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OVUxMX1NPVVJDRU5PREVfQVBQTFlJTVBPUlRTID0gIkVSX05VTExfU09VUkNFTk9ERV9BUFBMWUlNUE9SVFMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfQUREID0gIkVSX0NBTk5PVF9BREQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OVUxMX1NPVVJDRU5PREVfSEFORExFQVBQTFlURU1QTEFURVM9IkVSX05VTExfU09VUkNFTk9ERV9IQU5ETEVBUFBMWVRFTVBMQVRFUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX05BTUVfQVRUUklCID0gIkVSX05PX05BTUVfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVEVNUExBVEVfTk9UX0ZPVU5EID0gIkVSX1RFTVBMQVRFX05PVF9GT1VORCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfUkVTT0xWRV9OQU1FX0FWVCA9ICJFUl9DQU5UX1JFU09MVkVfTkFNRV9BVlQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SRVFVSVJFU19BVFRSSUIgPSAiRVJfUkVRVUlSRVNfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTVVTVF9IQVZFX1RFU1RfQVRUUklCID0gIkVSX01VU1RfSEFWRV9URVNUX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0JBRF9WQUxfT05fTEVWRUxfQVRUUklCID0KLSAgICAgICAgICJFUl9CQURfVkFMX09OX0xFVkVMX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BST0NFU1NJTkdJTlNUUlVDVElPTl9OQU1FX0NBTlRfQkVfWE1MID0KLSAgICAgICAgICJFUl9QUk9DRVNTSU5HSU5TVFJVQ1RJT05fTkFNRV9DQU5UX0JFX1hNTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BST0NFU1NJTkdJTlNUUlVDVElPTl9OT1RWQUxJRF9OQ05BTUUgPQotICAgICAgICAgIkVSX1BST0NFU1NJTkdJTlNUUlVDVElPTl9OT1RWQUxJRF9OQ05BTUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9ORUVEX01BVENIX0FUVFJJQiA9ICJFUl9ORUVEX01BVENIX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05FRURfTkFNRV9PUl9NQVRDSF9BVFRSSUIgPQotICAgICAgICAgIkVSX05FRURfTkFNRV9PUl9NQVRDSF9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX1JFU09MVkVfTlNQUkVGSVggPQotICAgICAgICAgIkVSX0NBTlRfUkVTT0xWRV9OU1BSRUZJWCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lMTEVHQUxfVkFMVUUgPSAiRVJfSUxMRUdBTF9WQUxVRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX09XTkVSRE9DID0gIkVSX05PX09XTkVSRE9DIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRUxFTVRFTVBMQVRFRUxFTV9FUlIgPSJFUl9FTEVNVEVNUExBVEVFTEVNX0VSUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05VTExfQ0hJTEQgPSAiRVJfTlVMTF9DSElMRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05FRURfU0VMRUNUX0FUVFJJQiA9ICJFUl9ORUVEX1NFTEVDVF9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9ORUVEX1RFU1RfQVRUUklCID0gIkVSX05FRURfVEVTVF9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9ORUVEX05BTUVfQVRUUklCID0gIkVSX05FRURfTkFNRV9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19DT05URVhUX09XTkVSRE9DID0gIkVSX05PX0NPTlRFWFRfT1dORVJET0MiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRF9OT1RfQ1JFQVRFX1hNTF9QUk9DX0xJQUlTT04gPQotICAgICAgICAgIkVSX0NPVUxEX05PVF9DUkVBVEVfWE1MX1BST0NfTElBSVNPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BST0NFU1NfTk9UX1NVQ0NFU1NGVUwgPQotICAgICAgICAgIkVSX1BST0NFU1NfTk9UX1NVQ0NFU1NGVUwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT1RfU1VDQ0VTU0ZVTCA9ICJFUl9OT1RfU1VDQ0VTU0ZVTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VOQ09ESU5HX05PVF9TVVBQT1JURUQgPQotICAgICAgICAgIkVSX0VOQ09ESU5HX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRF9OT1RfQ1JFQVRFX1RSQUNFTElTVEVORVIgPQotICAgICAgICAgIkVSX0NPVUxEX05PVF9DUkVBVEVfVFJBQ0VMSVNURU5FUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0tFWV9SRVFVSVJFU19OQU1FX0FUVFJJQiA9Ci0gICAgICAgICAiRVJfS0VZX1JFUVVJUkVTX05BTUVfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfS0VZX1JFUVVJUkVTX01BVENIX0FUVFJJQiA9Ci0gICAgICAgICAiRVJfS0VZX1JFUVVJUkVTX01BVENIX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0tFWV9SRVFVSVJFU19VU0VfQVRUUklCID0KLSAgICAgICAgICJFUl9LRVlfUkVRVUlSRVNfVVNFX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1JFUVVJUkVTX0VMRU1FTlRTX0FUVFJJQiA9Ci0gICAgICAgICAiRVJfUkVRVUlSRVNfRUxFTUVOVFNfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTUlTU0lOR19QUkVGSVhfQVRUUklCID0KLSAgICAgICAgICJFUl9NSVNTSU5HX1BSRUZJWF9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9CQURfU1RZTEVTSEVFVF9VUkwgPSAiRVJfQkFEX1NUWUxFU0hFRVRfVVJMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRklMRV9OT1RfRk9VTkQgPSAiRVJfRklMRV9OT1RfRk9VTkQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JT0VYQ0VQVElPTiA9ICJFUl9JT0VYQ0VQVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX0hSRUZfQVRUUklCID0gIkVSX05PX0hSRUZfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU1RZTEVTSEVFVF9JTkNMVURFU19JVFNFTEYgPQotICAgICAgICAgIkVSX1NUWUxFU0hFRVRfSU5DTFVERVNfSVRTRUxGIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJPQ0VTU0lOQ0xVREVfRVJST1IgPSJFUl9QUk9DRVNTSU5DTFVERV9FUlJPUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01JU1NJTkdfTEFOR19BVFRSSUIgPSAiRVJfTUlTU0lOR19MQU5HX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01JU1NJTkdfQ09OVEFJTkVSX0VMRU1FTlRfQ09NUE9ORU5UID0KLSAgICAgICAgICJFUl9NSVNTSU5HX0NPTlRBSU5FUl9FTEVNRU5UX0NPTVBPTkVOVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTl9PTkxZX09VVFBVVF9UT19FTEVNRU5UID0KLSAgICAgICAgICJFUl9DQU5fT05MWV9PVVRQVVRfVE9fRUxFTUVOVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BST0NFU1NfRVJST1IgPSAiRVJfUFJPQ0VTU19FUlJPUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1VOSU1QTE5PREVfRVJST1IgPSAiRVJfVU5JTVBMTk9ERV9FUlJPUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1NFTEVDVF9FWFBSRVNTSU9OID0iRVJfTk9fU0VMRUNUX0VYUFJFU1NJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfU0VSSUFMSVpFX1hTTFBST0NFU1NPUiA9Ci0gICAgICAgICAiRVJfQ0FOTk9UX1NFUklBTElaRV9YU0xQUk9DRVNTT1IiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19JTlBVVF9TVFlMRVNIRUVUID0gIkVSX05PX0lOUFVUX1NUWUxFU0hFRVQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GQUlMRURfUFJPQ0VTU19TVFlMRVNIRUVUID0KLSAgICAgICAgICJFUl9GQUlMRURfUFJPQ0VTU19TVFlMRVNIRUVUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTEROVF9QQVJTRV9ET0MgPSAiRVJfQ09VTEROVF9QQVJTRV9ET0MiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRE5UX0ZJTkRfRlJBR01FTlQgPQotICAgICAgICAgIkVSX0NPVUxETlRfRklORF9GUkFHTUVOVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PREVfTk9UX0VMRU1FTlQgPSAiRVJfTk9ERV9OT1RfRUxFTUVOVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZPUkVBQ0hfTkVFRF9NQVRDSF9PUl9OQU1FX0FUVFJJQiA9Ci0gICAgICAgICAiRVJfRk9SRUFDSF9ORUVEX01BVENIX09SX05BTUVfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVEVNUExBVEVTX05FRURfTUFUQ0hfT1JfTkFNRV9BVFRSSUIgPQotICAgICAgICAgIkVSX1RFTVBMQVRFU19ORUVEX01BVENIX09SX05BTUVfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fQ0xPTkVfT0ZfRE9DVU1FTlRfRlJBRyA9Ci0gICAgICAgICAiRVJfTk9fQ0xPTkVfT0ZfRE9DVU1FTlRfRlJBRyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfQ1JFQVRFX0lURU0gPSAiRVJfQ0FOVF9DUkVBVEVfSVRFTSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hNTFNQQUNFX0lMTEVHQUxfVkFMVUUgPQotICAgICAgICAgIkVSX1hNTFNQQUNFX0lMTEVHQUxfVkFMVUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19YU0xLRVlfREVDTEFSQVRJT04gPQotICAgICAgICAgIkVSX05PX1hTTEtFWV9ERUNMQVJBVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfQ1JFQVRFX1VSTCA9ICJFUl9DQU5UX0NSRUFURV9VUkwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YU0xGVU5DVElPTlNfVU5TVVBQT1JURUQgPQotICAgICAgICAgIkVSX1hTTEZVTkNUSU9OU19VTlNVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BST0NFU1NPUl9FUlJPUiA9ICJFUl9QUk9DRVNTT1JfRVJST1IiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT1RfQUxMT1dFRF9JTlNJREVfU1RZTEVTSEVFVCA9Ci0gICAgICAgICAiRVJfTk9UX0FMTE9XRURfSU5TSURFX1NUWUxFU0hFRVQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SRVNVTFROU19OT1RfU1VQUE9SVEVEID0KLSAgICAgICAgICJFUl9SRVNVTFROU19OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfREVGQVVMVFNQQUNFX05PVF9TVVBQT1JURUQgPQotICAgICAgICAgIkVSX0RFRkFVTFRTUEFDRV9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5ERU5UUkVTVUxUX05PVF9TVVBQT1JURUQgPQotICAgICAgICAgIkVSX0lOREVOVFJFU1VMVF9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSUxMRUdBTF9BVFRSSUIgPSAiRVJfSUxMRUdBTF9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTktOT1dOX1hTTF9FTEVNID0gIkVSX1VOS05PV05fWFNMX0VMRU0iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9CQURfWFNMU09SVF9VU0UgPSAiRVJfQkFEX1hTTFNPUlRfVVNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTUlTUExBQ0VEX1hTTFdIRU4gPSAiRVJfTUlTUExBQ0VEX1hTTFdIRU4iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YU0xXSEVOX05PVF9QQVJFTlRFRF9CWV9YU0xDSE9PU0UgPQotICAgICAgICAgIkVSX1hTTFdIRU5fTk9UX1BBUkVOVEVEX0JZX1hTTENIT09TRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01JU1BMQUNFRF9YU0xPVEhFUldJU0UgPQotICAgICAgICAgIkVSX01JU1BMQUNFRF9YU0xPVEhFUldJU0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YU0xPVEhFUldJU0VfTk9UX1BBUkVOVEVEX0JZX1hTTENIT09TRSA9Ci0gICAgICAgICAiRVJfWFNMT1RIRVJXSVNFX05PVF9QQVJFTlRFRF9CWV9YU0xDSE9PU0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT1RfQUxMT1dFRF9JTlNJREVfVEVNUExBVEUgPQotICAgICAgICAgIkVSX05PVF9BTExPV0VEX0lOU0lERV9URU1QTEFURSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1VOS05PV05fRVhUX05TX1BSRUZJWCA9Ci0gICAgICAgICAiRVJfVU5LTk9XTl9FWFRfTlNfUFJFRklYIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU1QT1JUU19BU19GSVJTVF9FTEVNID0KLSAgICAgICAgICJFUl9JTVBPUlRTX0FTX0ZJUlNUX0VMRU0iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTVBPUlRJTkdfSVRTRUxGID0gIkVSX0lNUE9SVElOR19JVFNFTEYiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YTUxTUEFDRV9JTExFR0FMX1ZBTCA9IkVSX1hNTFNQQUNFX0lMTEVHQUxfVkFMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJPQ0VTU1NUWUxFU0hFRVRfTk9UX1NVQ0NFU1NGVUwgPQotICAgICAgICAgIkVSX1BST0NFU1NTVFlMRVNIRUVUX05PVF9TVUNDRVNTRlVMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU0FYX0VYQ0VQVElPTiA9ICJFUl9TQVhfRVhDRVBUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWFNMVF9FUlJPUiA9ICJFUl9YU0xUX0VSUk9SIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ1VSUkVOQ1lfU0lHTl9JTExFR0FMPQotICAgICAgICAgIkVSX0NVUlJFTkNZX1NJR05fSUxMRUdBTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0RPQ1VNRU5UX0ZVTkNUSU9OX0lOVkFMSURfSU5fU1RZTEVTSEVFVF9ET00gPQotICAgICAgICAgIkVSX0RPQ1VNRU5UX0ZVTkNUSU9OX0lOVkFMSURfSU5fU1RZTEVTSEVFVF9ET00iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX1JFU09MVkVfUFJFRklYX09GX05PTl9QUkVGSVhfUkVTT0xWRVIgPQotICAgICAgICAgIkVSX0NBTlRfUkVTT0xWRV9QUkVGSVhfT0ZfTk9OX1BSRUZJWF9SRVNPTFZFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1JFRElSRUNUX0NPVUxETlRfR0VUX0ZJTEVOQU1FID0KLSAgICAgICAgICJFUl9SRURJUkVDVF9DT1VMRE5UX0dFVF9GSUxFTkFNRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9CVUlMRF9GT1JNQVRURVJMSVNURU5FUl9JTl9SRURJUkVDVCA9Ci0gICAgICAgICAiRVJfQ0FOTk9UX0JVSUxEX0ZPUk1BVFRFUkxJU1RFTkVSX0lOX1JFRElSRUNUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9QUkVGSVhfSU5fRVhDTFVERVJFU1VMVFBSRUZJWCA9Ci0gICAgICAgICAiRVJfSU5WQUxJRF9QUkVGSVhfSU5fRVhDTFVERVJFU1VMVFBSRUZJWCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01JU1NJTkdfTlNfVVJJID0gIkVSX01JU1NJTkdfTlNfVVJJIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTUlTU0lOR19BUkdfRk9SX09QVElPTiA9Ci0gICAgICAgICAiRVJfTUlTU0lOR19BUkdfRk9SX09QVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfT1BUSU9OID0gIkVSX0lOVkFMSURfT1BUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTUFMRk9STUVEX0ZPUk1BVF9TVFJJTkcgPQotICAgICAgICAgIkVSX01BTEZPUk1FRF9GT1JNQVRfU1RSSU5HIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU1RZTEVTSEVFVF9SRVFVSVJFU19WRVJTSU9OX0FUVFJJQiA9Ci0gICAgICAgICAiRVJfU1RZTEVTSEVFVF9SRVFVSVJFU19WRVJTSU9OX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lMTEVHQUxfQVRUUklCVVRFX1ZBTFVFID0KLSAgICAgICAgICJFUl9JTExFR0FMX0FUVFJJQlVURV9WQUxVRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NIT09TRV9SRVFVSVJFU19XSEVOID0iRVJfQ0hPT1NFX1JFUVVJUkVTX1dIRU4iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19BUFBMWV9JTVBPUlRfSU5fRk9SX0VBQ0ggPQotICAgICAgICAgIkVSX05PX0FQUExZX0lNUE9SVF9JTl9GT1JfRUFDSCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfVVNFX0RUTV9GT1JfT1VUUFVUID0KLSAgICAgICAgICJFUl9DQU5UX1VTRV9EVE1fRk9SX09VVFBVVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfVVNFX0RUTV9GT1JfSU5QVVQgPQotICAgICAgICAgIkVSX0NBTlRfVVNFX0RUTV9GT1JfSU5QVVQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQUxMX1RPX0VYVF9GQUlMRUQgPSAiRVJfQ0FMTF9UT19FWFRfRkFJTEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJFRklYX01VU1RfUkVTT0xWRSA9ICJFUl9QUkVGSVhfTVVTVF9SRVNPTFZFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9VVEYxNl9TVVJST0dBVEUgPQotICAgICAgICAgIkVSX0lOVkFMSURfVVRGMTZfU1VSUk9HQVRFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWFNMQVRUUlNFVF9VU0VEX0lUU0VMRiA9Ci0gICAgICAgICAiRVJfWFNMQVRUUlNFVF9VU0VEX0lUU0VMRiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9NSVhfWEVSQ0VTRE9NID0iRVJfQ0FOTk9UX01JWF9YRVJDRVNET00iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9UT09fTUFOWV9MSVNURU5FUlMgPSAiRVJfVE9PX01BTllfTElTVEVORVJTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5fRUxFTVRFTVBMQVRFRUxFTV9SRUFET0JKRUNUID0KLSAgICAgICAgICJFUl9JTl9FTEVNVEVNUExBVEVFTEVNX1JFQURPQkpFQ1QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9EVVBMSUNBVEVfTkFNRURfVEVNUExBVEUgPQotICAgICAgICAgIkVSX0RVUExJQ0FURV9OQU1FRF9URU1QTEFURSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfS0VZX0NBTEwgPSAiRVJfSU5WQUxJRF9LRVlfQ0FMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1JFRkVSRU5DSU5HX0lUU0VMRiA9ICJFUl9SRUZFUkVOQ0lOR19JVFNFTEYiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTExFR0FMX0RPTVNPVVJDRV9JTlBVVCA9Ci0gICAgICAgICAiRVJfSUxMRUdBTF9ET01TT1VSQ0VfSU5QVVQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DTEFTU19OT1RfRk9VTkRfRk9SX09QVElPTiA9Ci0gICAgICAgICAiRVJfQ0xBU1NfTk9UX0ZPVU5EX0ZPUl9PUFRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SRVFVSVJFRF9FTEVNX05PVF9GT1VORCA9Ci0gICAgICAgICAiRVJfUkVRVUlSRURfRUxFTV9OT1RfRk9VTkQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlBVVF9DQU5OT1RfQkVfTlVMTCA9IkVSX0lOUFVUX0NBTk5PVF9CRV9OVUxMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVVJJX0NBTk5PVF9CRV9OVUxMID0gIkVSX1VSSV9DQU5OT1RfQkVfTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZJTEVfQ0FOTk9UX0JFX05VTEwgPSAiRVJfRklMRV9DQU5OT1RfQkVfTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NPVVJDRV9DQU5OT1RfQkVfTlVMTCA9Ci0gICAgICAgICAiRVJfU09VUkNFX0NBTk5PVF9CRV9OVUxMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX0lOSVRfQlNGTUdSID0gIkVSX0NBTk5PVF9JTklUX0JTRk1HUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9DTVBMX0VYVEVOU04gPSAiRVJfQ0FOTk9UX0NNUExfRVhURU5TTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9DUkVBVEVfRVhURU5TTiA9Ci0gICAgICAgICAiRVJfQ0FOTk9UX0NSRUFURV9FWFRFTlNOIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5TVEFOQ0VfTVRIRF9DQUxMX1JFUVVJUkVTID0KLSAgICAgICAgICJFUl9JTlNUQU5DRV9NVEhEX0NBTExfUkVRVUlSRVMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX0VMRU1FTlRfTkFNRSA9IkVSX0lOVkFMSURfRUxFTUVOVF9OQU1FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRUxFTUVOVF9OQU1FX01FVEhPRF9TVEFUSUMgPQotICAgICAgICAgIkVSX0VMRU1FTlRfTkFNRV9NRVRIT0RfU1RBVElDIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhURU5TSU9OX0ZVTkNfVU5LTk9XTiA9Ci0gICAgICAgICAiRVJfRVhURU5TSU9OX0ZVTkNfVU5LTk9XTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01PUkVfTUFUQ0hfQ09OU1RSVUNUT1IgPQotICAgICAgICAgIkVSX01PUkVfTUFUQ0hfQ09OU1RSVUNUT1IiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9NT1JFX01BVENIX01FVEhPRCA9ICJFUl9NT1JFX01BVENIX01FVEhPRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01PUkVfTUFUQ0hfRUxFTUVOVCA9ICJFUl9NT1JFX01BVENIX0VMRU1FTlQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX0NPTlRFWFRfUEFTU0VEID0KLSAgICAgICAgICJFUl9JTlZBTElEX0NPTlRFWFRfUEFTU0VEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUE9PTF9FWElTVFMgPSAiRVJfUE9PTF9FWElTVFMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19EUklWRVJfTkFNRSA9ICJFUl9OT19EUklWRVJfTkFNRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1VSTCA9ICJFUl9OT19VUkwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QT09MX1NJWkVfTEVTU1RIQU5fT05FID0KLSAgICAgICAgICJFUl9QT09MX1NJWkVfTEVTU1RIQU5fT05FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9EUklWRVIgPSAiRVJfSU5WQUxJRF9EUklWRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19TVFlMRVNIRUVUUk9PVCA9ICJFUl9OT19TVFlMRVNIRUVUUk9PVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lMTEVHQUxfWE1MU1BBQ0VfVkFMVUUgPQotICAgICAgICAgIkVSX0lMTEVHQUxfWE1MU1BBQ0VfVkFMVUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUk9DRVNTRlJPTU5PREVfRkFJTEVEID0KLSAgICAgICAgICJFUl9QUk9DRVNTRlJPTU5PREVfRkFJTEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUkVTT1VSQ0VfQ09VTERfTk9UX0xPQUQgPQotICAgICAgICAgIkVSX1JFU09VUkNFX0NPVUxEX05PVF9MT0FEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQlVGRkVSX1NJWkVfTEVTU1RIQU5fWkVSTyA9Ci0gICAgICAgICAiRVJfQlVGRkVSX1NJWkVfTEVTU1RIQU5fWkVSTyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1VOS05PV05fRVJST1JfQ0FMTElOR19FWFRFTlNJT04gPQotICAgICAgICAgIkVSX1VOS05PV05fRVJST1JfQ0FMTElOR19FWFRFTlNJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19OQU1FU1BBQ0VfREVDTCA9ICJFUl9OT19OQU1FU1BBQ0VfREVDTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VMRU1fQ09OVEVOVF9OT1RfQUxMT1dFRCA9Ci0gICAgICAgICAiRVJfRUxFTV9DT05URU5UX05PVF9BTExPV0VEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU1RZTEVTSEVFVF9ESVJFQ1RFRF9URVJNSU5BVElPTiA9Ci0gICAgICAgICAiRVJfU1RZTEVTSEVFVF9ESVJFQ1RFRF9URVJNSU5BVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX09ORV9PUl9UV08gPSAiRVJfT05FX09SX1RXTyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1RXT19PUl9USFJFRSA9ICJFUl9UV09fT1JfVEhSRUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRF9OT1RfTE9BRF9SRVNPVVJDRSA9Ci0gICAgICAgICAiRVJfQ09VTERfTk9UX0xPQURfUkVTT1VSQ0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfSU5JVF9ERUZBVUxUX1RFTVBMQVRFUyA9Ci0gICAgICAgICAiRVJfQ0FOTk9UX0lOSVRfREVGQVVMVF9URU1QTEFURVMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SRVNVTFRfTlVMTCA9ICJFUl9SRVNVTFRfTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1JFU1VMVF9DT1VMRF9OT1RfQkVfU0VUID0KLSAgICAgICAgICJFUl9SRVNVTFRfQ09VTERfTk9UX0JFX1NFVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX09VVFBVVF9TUEVDSUZJRUQgPSAiRVJfTk9fT1VUUFVUX1NQRUNJRklFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9UUkFOU0ZPUk1fVE9fUkVTVUxUX1RZUEUgPQotICAgICAgICAgIkVSX0NBTk5PVF9UUkFOU0ZPUk1fVE9fUkVTVUxUX1RZUEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfVFJBTlNGT1JNX1NPVVJDRV9UWVBFID0KLSAgICAgICAgICJFUl9DQU5OT1RfVFJBTlNGT1JNX1NPVVJDRV9UWVBFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTlVMTF9DT05URU5UX0hBTkRMRVIgPSJFUl9OVUxMX0NPTlRFTlRfSEFORExFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05VTExfRVJST1JfSEFORExFUiA9ICJFUl9OVUxMX0VSUk9SX0hBTkRMRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfQ0FMTF9QQVJTRSA9ICJFUl9DQU5OT1RfQ0FMTF9QQVJTRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1BBUkVOVF9GT1JfRklMVEVSID0iRVJfTk9fUEFSRU5UX0ZPUl9GSUxURVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19TVFlMRVNIRUVUX0lOX01FRElBID0KLSAgICAgICAgICJFUl9OT19TVFlMRVNIRUVUX0lOX01FRElBIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fU1RZTEVTSEVFVF9QSSA9ICJFUl9OT19TVFlMRVNIRUVUX1BJIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9UX1NVUFBPUlRFRCA9ICJFUl9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJPUEVSVFlfVkFMVUVfQk9PTEVBTiA9Ci0gICAgICAgICAiRVJfUFJPUEVSVFlfVkFMVUVfQk9PTEVBTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxEX05PVF9GSU5EX0VYVEVSTl9TQ1JJUFQgPQotICAgICAgICAgIkVSX0NPVUxEX05PVF9GSU5EX0VYVEVSTl9TQ1JJUFQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SRVNPVVJDRV9DT1VMRF9OT1RfRklORCA9Ci0gICAgICAgICAiRVJfUkVTT1VSQ0VfQ09VTERfTk9UX0ZJTkQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9PVVRQVVRfUFJPUEVSVFlfTk9UX1JFQ09HTklaRUQgPQotICAgICAgICAgIkVSX09VVFBVVF9QUk9QRVJUWV9OT1RfUkVDT0dOSVpFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZBSUxFRF9DUkVBVElOR19FTEVNTElUUlNMVCA9Ci0gICAgICAgICAiRVJfRkFJTEVEX0NSRUFUSU5HX0VMRU1MSVRSU0xUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVkFMVUVfU0hPVUxEX0JFX05VTUJFUiA9Ci0gICAgICAgICAiRVJfVkFMVUVfU0hPVUxEX0JFX05VTUJFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1ZBTFVFX1NIT1VMRF9FUVVBTCA9ICJFUl9WQUxVRV9TSE9VTERfRVFVQUwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GQUlMRURfQ0FMTElOR19NRVRIT0QgPQotICAgICAgICAgIkVSX0ZBSUxFRF9DQUxMSU5HX01FVEhPRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZBSUxFRF9DUkVBVElOR19FTEVNVE1QTCA9Ci0gICAgICAgICAiRVJfRkFJTEVEX0NSRUFUSU5HX0VMRU1UTVBMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0hBUlNfTk9UX0FMTE9XRUQgPSAiRVJfQ0hBUlNfTk9UX0FMTE9XRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9BVFRSX05PVF9BTExPV0VEID0gIkVSX0FUVFJfTk9UX0FMTE9XRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9CQURfVkFMVUUgPSAiRVJfQkFEX1ZBTFVFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQVRUUklCX1ZBTFVFX05PVF9GT1VORCA9Ci0gICAgICAgICAiRVJfQVRUUklCX1ZBTFVFX05PVF9GT1VORCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FUVFJJQl9WQUxVRV9OT1RfUkVDT0dOSVpFRCA9Ci0gICAgICAgICAiRVJfQVRUUklCX1ZBTFVFX05PVF9SRUNPR05JWkVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTlVMTF9VUklfTkFNRVNQQUNFID0gIkVSX05VTExfVVJJX05BTUVTUEFDRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05VTUJFUl9UT09fQklHID0gIkVSX05VTUJFUl9UT09fQklHIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgIEVSX0NBTk5PVF9GSU5EX1NBWDFfRFJJVkVSID0KLSAgICAgICAgICJFUl9DQU5OT1RfRklORF9TQVgxX0RSSVZFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nICBFUl9TQVgxX0RSSVZFUl9OT1RfTE9BREVEID0KLSAgICAgICAgICJFUl9TQVgxX0RSSVZFUl9OT1RfTE9BREVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgIEVSX1NBWDFfRFJJVkVSX05PVF9JTlNUQU5USUFURUQgPQotICAgICAgICAgIkVSX1NBWDFfRFJJVkVSX05PVF9JTlNUQU5USUFURUQiIDsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU0FYMV9EUklWRVJfTk9UX0lNUExFTUVOVF9QQVJTRVIgPQotICAgICAgICAgIkVSX1NBWDFfRFJJVkVSX05PVF9JTVBMRU1FTlRfUEFSU0VSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgIEVSX1BBUlNFUl9QUk9QRVJUWV9OT1RfU1BFQ0lGSUVEID0KLSAgICAgICAgICJFUl9QQVJTRVJfUFJPUEVSVFlfTk9UX1NQRUNJRklFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nICBFUl9QQVJTRVJfQVJHX0NBTk5PVF9CRV9OVUxMID0KLSAgICAgICAgICJFUl9QQVJTRVJfQVJHX0NBTk5PVF9CRV9OVUxMIiA7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nICBFUl9GRUFUVVJFID0gIkVSX0ZFQVRVUkUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUk9QRVJUWSA9ICJFUl9QUk9QRVJUWSIgOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OVUxMX0VOVElUWV9SRVNPTFZFUiA9IkVSX05VTExfRU5USVRZX1JFU09MVkVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgIEVSX05VTExfRFREX0hBTkRMRVIgPSAiRVJfTlVMTF9EVERfSEFORExFUiIgOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19EUklWRVJfTkFNRV9TUEVDSUZJRUQgPQotICAgICAgICAgIkVSX05PX0RSSVZFUl9OQU1FX1NQRUNJRklFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1VSTF9TUEVDSUZJRUQgPSAiRVJfTk9fVVJMX1NQRUNJRklFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BPT0xTSVpFX0xFU1NfVEhBTl9PTkUgPQotICAgICAgICAgIkVSX1BPT0xTSVpFX0xFU1NfVEhBTl9PTkUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX0RSSVZFUl9OQU1FID0gIkVSX0lOVkFMSURfRFJJVkVSX05BTUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FUlJPUkxJU1RFTkVSID0gIkVSX0VSUk9STElTVEVORVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9BU1NFUlRfTk9fVEVNUExBVEVfUEFSRU5UID0KLSAgICAgICAgICJFUl9BU1NFUlRfTk9fVEVNUExBVEVfUEFSRU5UIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQVNTRVJUX1JFRFVOREVOVF9FWFBSX0VMSU1JTkFUT1IgPQotICAgICAgICAgIkVSX0FTU0VSVF9SRURVTkRFTlRfRVhQUl9FTElNSU5BVE9SIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9UX0FMTE9XRURfSU5fUE9TSVRJT04gPQotICAgICAgICAgIkVSX05PVF9BTExPV0VEX0lOX1BPU0lUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9OV0hJVEVTUEFDRV9OT1RfQUxMT1dFRF9JTl9QT1NJVElPTiA9Ci0gICAgICAgICAiRVJfTk9OV0hJVEVTUEFDRV9OT1RfQUxMT1dFRF9JTl9QT1NJVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05BTUVTUEFDRV9DT05URVhUX05VTExfTkFNRVNQQUNFID0KLSAgICAgICAgICJFUl9OQU1FU1BBQ0VfQ09OVEVYVF9OVUxMX05BTUVTUEFDRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05BTUVTUEFDRV9DT05URVhUX05VTExfUFJFRklYID0KLSAgICAgICAgICJFUl9OQU1FU1BBQ0VfQ09OVEVYVF9OVUxMX1BSRUZJWCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hQQVRIX1JFU09MVkVSX05VTExfUU5BTUUgPQotICAgICAgICAgIkVSX1hQQVRIX1JFU09MVkVSX05VTExfUU5BTUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YUEFUSF9SRVNPTFZFUl9ORUdBVElWRV9BUklUWSA9Ci0gICAgICAgICAiRVJfWFBBVEhfUkVTT0xWRVJfTkVHQVRJVkVfQVJJVFkiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBJTlZBTElEX1RDSEFSID0gIklOVkFMSURfVENIQVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBJTlZBTElEX1FOQU1FID0gIklOVkFMSURfUU5BTUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBJTlZBTElEX0VOVU0gPSAiSU5WQUxJRF9FTlVNIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSU5WQUxJRF9OTVRPS0VOID0gIklOVkFMSURfTk1UT0tFTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIElOVkFMSURfTkNOQU1FID0gIklOVkFMSURfTkNOQU1FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSU5WQUxJRF9CT09MRUFOID0gIklOVkFMSURfQk9PTEVBTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIElOVkFMSURfTlVNQkVSID0gIklOVkFMSURfTlVNQkVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQVJHX0xJVEVSQUwgPSAiRVJfQVJHX0xJVEVSQUwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9EVVBMSUNBVEVfR0xPQkFMX1ZBUiA9IkVSX0RVUExJQ0FURV9HTE9CQUxfVkFSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRFVQTElDQVRFX1ZBUiA9ICJFUl9EVVBMSUNBVEVfVkFSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVEVNUExBVEVfTkFNRV9NQVRDSCA9ICJFUl9URU1QTEFURV9OQU1FX01BVENIIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9QUkVGSVggPSAiRVJfSU5WQUxJRF9QUkVGSVgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19BVFRSSUJfU0VUID0gIkVSX05PX0FUVFJJQl9TRVQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GVU5DVElPTl9OT1RfRk9VTkQgPQotICAgICAgICAgIkVSX0ZVTkNUSU9OX05PVF9GT1VORCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfSEFWRV9DT05URU5UX0FORF9TRUxFQ1QgPQotICAgICAiRVJfQ0FOVF9IQVZFX0NPTlRFTlRfQU5EX1NFTEVDVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfU0VUX1BBUkFNX1ZBTFVFID0gIkVSX0lOVkFMSURfU0VUX1BBUkFNX1ZBTFVFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU0VUX0ZFQVRVUkVfTlVMTF9OQU1FID0KLSAgICAgICAgIkVSX1NFVF9GRUFUVVJFX05VTExfTkFNRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0dFVF9GRUFUVVJFX05VTExfTkFNRSA9Ci0gICAgICAgICJFUl9HRVRfRkVBVFVSRV9OVUxMX05BTUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTlNVUFBPUlRFRF9GRUFUVVJFID0KLSAgICAgICAgIkVSX1VOU1VQUE9SVEVEX0ZFQVRVUkUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FWFRFTlNJT05fRUxFTUVOVF9OT1RfQUxMT1dFRF9JTl9TRUNVUkVfUFJPQ0VTU0lORyA9Ci0gICAgICAgICJFUl9FWFRFTlNJT05fRUxFTUVOVF9OT1RfQUxMT1dFRF9JTl9TRUNVUkVfUFJPQ0VTU0lORyI7Ci0KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfRk9VTkRfQ1VSTFlCUkFDRSA9ICJXR19GT1VORF9DVVJMWUJSQUNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfQ09VTlRfQVRUUklCX01BVENIRVNfTk9fQU5DRVNUT1IgPQotICAgICAgICAgIldHX0NPVU5UX0FUVFJJQl9NQVRDSEVTX05PX0FOQ0VTVE9SIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfRVhQUl9BVFRSSUJfQ0hBTkdFRF9UT19TRUxFQ1QgPQotICAgICAgICAgIldHX0VYUFJfQVRUUklCX0NIQU5HRURfVE9fU0VMRUNUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfTk9fTE9DQUxFX0lOX0ZPUk1BVE5VTUJFUiA9Ci0gICAgICAgICAiV0dfTk9fTE9DQUxFX0lOX0ZPUk1BVE5VTUJFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0xPQ0FMRV9OT1RfRk9VTkQgPSAiV0dfTE9DQUxFX05PVF9GT1VORCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0NBTk5PVF9NQUtFX1VSTF9GUk9NID0iV0dfQ0FOTk9UX01BS0VfVVJMX0ZST00iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19DQU5OT1RfTE9BRF9SRVFVRVNURURfRE9DID0KLSAgICAgICAgICJXR19DQU5OT1RfTE9BRF9SRVFVRVNURURfRE9DIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfQ0FOTk9UX0ZJTkRfQ09MTEFUT1IgPSJXR19DQU5OT1RfRklORF9DT0xMQVRPUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0ZVTkNUSU9OU19TSE9VTERfVVNFX1VSTCA9Ci0gICAgICAgICAiV0dfRlVOQ1RJT05TX1NIT1VMRF9VU0VfVVJMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfRU5DT0RJTkdfTk9UX1NVUFBPUlRFRF9VU0lOR19VVEY4ID0KLSAgICAgICAgICJXR19FTkNPRElOR19OT1RfU1VQUE9SVEVEX1VTSU5HX1VURjgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19FTkNPRElOR19OT1RfU1VQUE9SVEVEX1VTSU5HX0pBVkEgPQotICAgICAgICAgIldHX0VOQ09ESU5HX05PVF9TVVBQT1JURURfVVNJTkdfSkFWQSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX1NQRUNJRklDSVRZX0NPTkZMSUNUUyA9Ci0gICAgICAgICAiV0dfU1BFQ0lGSUNJVFlfQ09ORkxJQ1RTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfUEFSU0lOR19BTkRfUFJFUEFSSU5HID0KLSAgICAgICAgICJXR19QQVJTSU5HX0FORF9QUkVQQVJJTkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19BVFRSX1RFTVBMQVRFID0gIldHX0FUVFJfVEVNUExBVEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19DT05GTElDVF9CRVRXRUVOX1hTTFNUUklQU1BBQ0VfQU5EX1hTTFBSRVNFUlZFU1BBQ0UgPSAiV0dfQ09ORkxJQ1RfQkVUV0VFTl9YU0xTVFJJUFNQQUNFX0FORF9YU0xQUkVTRVJWRVNQIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfQVRUUklCX05PVF9IQU5ETEVEID0gIldHX0FUVFJJQl9OT1RfSEFORExFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX05PX0RFQ0lNQUxGT1JNQVRfREVDTEFSQVRJT04gPQotICAgICAgICAgIldHX05PX0RFQ0lNQUxGT1JNQVRfREVDTEFSQVRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19PTERfWFNMVF9OUyA9ICJXR19PTERfWFNMVF9OUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX09ORV9ERUZBVUxUX1hTTERFQ0lNQUxGT1JNQVRfQUxMT1dFRCA9Ci0gICAgICAgICAiV0dfT05FX0RFRkFVTFRfWFNMREVDSU1BTEZPUk1BVF9BTExPV0VEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfWFNMREVDSU1BTEZPUk1BVF9OQU1FU19NVVNUX0JFX1VOSVFVRSA9Ci0gICAgICAgICAiV0dfWFNMREVDSU1BTEZPUk1BVF9OQU1FU19NVVNUX0JFX1VOSVFVRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0lMTEVHQUxfQVRUUklCVVRFID0gIldHX0lMTEVHQUxfQVRUUklCVVRFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfQ09VTERfTk9UX1JFU09MVkVfUFJFRklYID0KLSAgICAgICAgICJXR19DT1VMRF9OT1RfUkVTT0xWRV9QUkVGSVgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19TVFlMRVNIRUVUX1JFUVVJUkVTX1ZFUlNJT05fQVRUUklCID0KLSAgICAgICAgICJXR19TVFlMRVNIRUVUX1JFUVVJUkVTX1ZFUlNJT05fQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfSUxMRUdBTF9BVFRSSUJVVEVfTkFNRSA9Ci0gICAgICAgICAiV0dfSUxMRUdBTF9BVFRSSUJVVEVfTkFNRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0lMTEVHQUxfQVRUUklCVVRFX1ZBTFVFID0KLSAgICAgICAgICJXR19JTExFR0FMX0FUVFJJQlVURV9WQUxVRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0VNUFRZX1NFQ09ORF9BUkcgPSAiV0dfRU1QVFlfU0VDT05EX0FSRyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX1BST0NFU1NJTkdJTlNUUlVDVElPTl9OQU1FX0NBTlRfQkVfWE1MID0KLSAgICAgICAgICJXR19QUk9DRVNTSU5HSU5TVFJVQ1RJT05fTkFNRV9DQU5UX0JFX1hNTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX1BST0NFU1NJTkdJTlNUUlVDVElPTl9OT1RWQUxJRF9OQ05BTUUgPQotICAgICAgICAgIldHX1BST0NFU1NJTkdJTlNUUlVDVElPTl9OT1RWQUxJRF9OQ05BTUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19JTExFR0FMX0FUVFJJQlVURV9QT1NJVElPTiA9Ci0gICAgICAgICAiV0dfSUxMRUdBTF9BVFRSSUJVVEVfUE9TSVRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIgPQotICAgICAgICAgIk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiI7Ci0KLSAgLyoKLSAgICogTm93IGZpbGwgaW4gdGhlIG1lc3NhZ2UgdGV4dC4KLSAgICogVGhlbiBmaWxsIGluIHRoZSBtZXNzYWdlIHRleHQgZm9yIHRoYXQgbWVzc2FnZSBjb2RlIGluIHRoZQotICAgKiBhcnJheS4gVXNlIHRoZSBuZXcgZXJyb3IgY29kZSBhcyB0aGUgaW5kZXggaW50byB0aGUgYXJyYXkuCi0gICAqLwotCi0gIC8vIEVycm9yIG1lc3NhZ2VzLi4uCi0KLSAgLyoqIEdldCB0aGUgbG9va3VwIHRhYmxlIGZvciBlcnJvciBtZXNzYWdlcy4KLSAgICAqCi0gICAgKiBAcmV0dXJuIFRoZSBtZXNzYWdlIGxvb2t1cCB0YWJsZS4KLSAgICAqLwotICBwdWJsaWMgT2JqZWN0W11bXSBnZXRDb250ZW50cygpCi0gIHsKLSAgICAgIHJldHVybiBuZXcgT2JqZWN0W11bXSB7Ci0KLSAgLyoqIEVycm9yIG1lc3NhZ2UgSUQgdGhhdCBoYXMgYSBudWxsIG1lc3NhZ2UsIGJ1dCB0YWtlcyBpbiBhIHNpbmdsZSBvYmplY3QuICAgICovCi0gIHsiRVIwMDAwIiAsICJ7MH0iIH0sCi0KLSAgICB7IEVSX05PX0NVUkxZQlJBQ0UsCi0gICAgICAiRXJyb3I6IG5vIHB1ZWRlIGhhYmVyJ3snIGVuIGxhIGV4cHJlc2lcdTAwRjNuIn0sCi0KLSAgICB7IEVSX0lMTEVHQUxfQVRUUklCVVRFICwKLSAgICAgInswfSB0aWVuZSB1biBhdHJpYnV0byBubyBwZXJtaXRpZG86IHsxfSJ9LAotCi0gIHtFUl9OVUxMX1NPVVJDRU5PREVfQVBQTFlJTVBPUlRTICwKLSAgICAgICJzb3VyY2VOb2RlIGVzIG51bG8gZW4geHNsOmFwcGx5LWltcG9ydHMuIn0sCi0KLSAge0VSX0NBTk5PVF9BREQsCi0gICAgICAiTm8gc2UgcHVlZGUgYWdyZWdhciB7MH0gYSB7MX0ifSwKLQotICAgIHsgRVJfTlVMTF9TT1VSQ0VOT0RFX0hBTkRMRUFQUExZVEVNUExBVEVTLAotICAgICAgInNvdXJjZU5vZGUgZXMgbnVsbyBlbiBoYW5kbGVBcHBseVRlbXBsYXRlc0luc3RydWN0aW9uIn0sCi0KLSAgICB7IEVSX05PX05BTUVfQVRUUklCLAotICAgICAiezB9IGRlYmUgdGVuZXIgdW4gYXRyaWJ1dG8gbmFtZS4ifSwKLQotICAgIHtFUl9URU1QTEFURV9OT1RfRk9VTkQsCi0gICAgICJObyBzZSBoYSBlbmNvbnRyYWRvIGxhIHBsYW50aWxsYSBsbGFtYWRhOiB7MH0ifSwKLQotICAgIHtFUl9DQU5UX1JFU09MVkVfTkFNRV9BVlQsCi0gICAgICAiTm8gc2UgaGEgcG9kaWRvIHJlc29sdmVyIGVsIEFWVCBkZWwgbm9tYnJlIGVuIHhzbDpjYWxsLXRlbXBsYXRlLiJ9LAotCi0gICAge0VSX1JFUVVJUkVTX0FUVFJJQiwKLSAgICAgInswfSBuZWNlc2l0YSBlbCBhdHJpYnV0bzogezF9In0sCi0KLSAgICB7IEVSX01VU1RfSEFWRV9URVNUX0FUVFJJQiwKLSAgICAgICJ7MH0gZGViZSB0ZW5lciB1biBhdHJpYnV0byAnJ3Rlc3QnJy4ifSwKLQotICAgIHtFUl9CQURfVkFMX09OX0xFVkVMX0FUVFJJQiwKLSAgICAgICJWYWxvciBlcnJcdTAwRjNuZW8gZW4gZWwgYXRyaWJ1dG8gbGV2ZWw6IHswfSJ9LAotCi0gICAge0VSX1BST0NFU1NJTkdJTlNUUlVDVElPTl9OQU1FX0NBTlRfQkVfWE1MLAotICAgICAgImVsIG5vbWJyZSBkZSBpbnN0cnVjY2lcdTAwRjNuIGRlIHByb2Nlc2FtaWVudG8gbm8gcHVlZGUgc2VyICd4bWwnIn0sCi0KLSAgICB7IEVSX1BST0NFU1NJTkdJTlNUUlVDVElPTl9OT1RWQUxJRF9OQ05BTUUsCi0gICAgICAiZWwgbm9tYnJlIGRlIGluc3RydWNjaVx1MDBGM24gZGUgcHJvY2VzYW1pZW50byBkZWJlIHNlciB1biBOQ05hbWUgdlx1MDBFMWxpZG86IHswfSJ9LAotCi0gICAgeyBFUl9ORUVEX01BVENIX0FUVFJJQiwKLSAgICAgICJ7MH0gZGViZSB0ZW5lciB1biBhdHJpYnV0byBtYXRjaCBzaSB0aWVuZSB1biBtb2RvLiJ9LAotCi0gICAgeyBFUl9ORUVEX05BTUVfT1JfTUFUQ0hfQVRUUklCLAotICAgICAgInswfSBuZWNlc2l0YSB1biBhdHJpYnV0byBuYW1lIG8gbWF0Y2guIn0sCi0KLSAgICB7RVJfQ0FOVF9SRVNPTFZFX05TUFJFRklYLAotICAgICAgIk5vIHNlIHB1ZWRlIHJlc29sdmVyIGVsIHByZWZpam8gZGUgZXNwYWNpbyBkZSBub21icmVzOiB7MH0ifSwKLQotICAgIHsgRVJfSUxMRUdBTF9WQUxVRSwKLSAgICAgInhtbDpzcGFjZSB0aWVuZSB1biB2YWxvciBubyBwZXJtaXRpZG86IHswfSJ9LAotCi0gICAgeyBFUl9OT19PV05FUkRPQywKLSAgICAgICJFbCBub2RvIHNlY3VuZGFyaW8gbm8gdGllbmUgdW4gZG9jdW1lbnRvIGRlIHByb3BpZXRhcmlvLiJ9LAotCi0gICAgeyBFUl9FTEVNVEVNUExBVEVFTEVNX0VSUiwKLSAgICAgIkVycm9yIGRlIEVsZW1UZW1wbGF0ZUVsZW1lbnQ6IHswfSJ9LAotCi0gICAgeyBFUl9OVUxMX0NISUxELAotICAgICAiSW50ZW50YW5kbyBhZ3JlZ2FyIHVuIHNlY3VuZGFyaW8gbnVsby4ifSwKLQotICAgIHsgRVJfTkVFRF9TRUxFQ1RfQVRUUklCLAotICAgICAiezB9IG5lY2VzaXRhIHVuIGF0cmlidXRvIHNlbGVjdC4ifSwKLQotICAgIHsgRVJfTkVFRF9URVNUX0FUVFJJQiAsCi0gICAgICAieHNsOndoZW4gZGViZSB0ZW5lciB1biBhdHJpYnV0byAndGVzdCcuIn0sCi0KLSAgICB7IEVSX05FRURfTkFNRV9BVFRSSUIsCi0gICAgICAieHNsOndpdGgtcGFyYW0gZGViZSB0ZW5lciB1biBhdHJpYnV0byAnbmFtZScuIn0sCi0KLSAgICB7IEVSX05PX0NPTlRFWFRfT1dORVJET0MsCi0gICAgICAiRWwgY29udGV4dG8gbm8gdGllbmUgdW4gZG9jdW1lbnRvIGRlIHByb3BpZXRhcmlvLiJ9LAotCi0gICAge0VSX0NPVUxEX05PVF9DUkVBVEVfWE1MX1BST0NfTElBSVNPTiwKLSAgICAgICJObyBzZSBoYSBwb2RpZG8gY3JlYXIgZWwgZW5sYWNlIFRyYW5zZm9ybWVyRmFjdG9yeSBYTUw6IHswfSJ9LAotCi0gICAge0VSX1BST0NFU1NfTk9UX1NVQ0NFU1NGVUwsCi0gICAgICAiWGFsYW46IGVsIHByb2Nlc28gbm8gc2UgaGEgcmVhbGl6YWRvIGNvcnJlY3RhbWVudGUuIn0sCi0KLSAgICB7IEVSX05PVF9TVUNDRVNTRlVMLAotICAgICAiWGFsYW46IG5vIHNlIGhhIHJlYWxpemFkbyBjb3JyZWN0YW1lbnRlLiJ9LAotCi0gICAgeyBFUl9FTkNPRElOR19OT1RfU1VQUE9SVEVELAotICAgICAiQ29kaWZpY2FjaVx1MDBGM24gbm8gc29wb3J0YWRhOiB7MH0ifSwKLQotICAgIHtFUl9DT1VMRF9OT1RfQ1JFQVRFX1RSQUNFTElTVEVORVIsCi0gICAgICAiTm8gc2UgaGEgcG9kaWRvIGNyZWFyIFRyYWNlTGlzdGVuZXI6IHswfSJ9LAotCi0gICAge0VSX0tFWV9SRVFVSVJFU19OQU1FX0FUVFJJQiwKLSAgICAgICJ4c2w6a2V5IG5lY2VzaXRhIHVuIGF0cmlidXRvICduYW1lJy4ifSwKLQotICAgIHsgRVJfS0VZX1JFUVVJUkVTX01BVENIX0FUVFJJQiwKLSAgICAgICJ4c2w6a2V5IG5lY2VzaXRhIHVuIGF0cmlidXRvICdtYXRjaCcuIn0sCi0KLSAgICB7IEVSX0tFWV9SRVFVSVJFU19VU0VfQVRUUklCLAotICAgICAgInhzbDprZXkgbmVjZXNpdGEgdW4gYXRyaWJ1dG8gJ3VzZScuIn0sCi0KLSAgICB7IEVSX1JFUVVJUkVTX0VMRU1FTlRTX0FUVFJJQiwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIHswfSBuZWNlc2l0YSB1biBhdHJpYnV0byAnJ2VsZW1lbnRzJycuIn0sCi0KLSAgICB7IEVSX01JU1NJTkdfUFJFRklYX0FUVFJJQiwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIEZhbHRhIGVsIHZhbG9yIGRlICcncHJlZml4JycgZGVsIGF0cmlidXRvIHswfSJ9LAotCi0gICAgeyBFUl9CQURfU1RZTEVTSEVFVF9VUkwsCi0gICAgICJMYSBVUkwgZGUgaG9qYSBkZSBlc3RpbG8gbm8gZXMgdlx1MDBFMWxpZGE6IHswfSJ9LAotCi0gICAgeyBFUl9GSUxFX05PVF9GT1VORCwKLSAgICAgIk5vIHNlIGhhIGVuY29udHJhZG8gZWwgYXJjaGl2byBkZSBob2phIGRlIGVzdGlsbzogezB9In0sCi0KLSAgICB7IEVSX0lPRVhDRVBUSU9OLAotICAgICAgIlRlblx1MDBFRGEgdW5hIGV4Y2VwY2lcdTAwRjNuIGRlIEUvUyBjb24gZWwgYXJjaGl2byBkZSBob2phIGRlIGVzdGlsbzogezB9In0sCi0KLSAgICB7IEVSX05PX0hSRUZfQVRUUklCLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgTm8gc2UgaGEgZW5jb250cmFkbyBlbCBhdHJpYnV0byBocmVmIHBhcmEgezB9In0sCi0KLSAgICB7IEVSX1NUWUxFU0hFRVRfSU5DTFVERVNfSVRTRUxGLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgezB9IHNlIGluY2x1eWUgZGlyZWN0YSBvIGluZGlyZWN0YW1lbnRlLiJ9LAotCi0gICAgeyBFUl9QUk9DRVNTSU5DTFVERV9FUlJPUiwKLSAgICAgICJFcnJvciBkZSBTdHlsZXNoZWV0SGFuZGxlci5wcm9jZXNzSW5jbHVkZSwgezB9In0sCi0KLSAgICB7IEVSX01JU1NJTkdfTEFOR19BVFRSSUIsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSBGYWx0YSBlbCBhdHJpYnV0byAnJ2xhbmcnJyB7MH0ifSwKLQotICAgIHsgRVJfTUlTU0lOR19DT05UQUlORVJfRUxFTUVOVF9DT01QT05FTlQsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSBcdTAwQkZFbGVtZW50byB7MH0gbWFsIGNvbG9jYWRvPyBGYWx0YSBlbCBlbGVtZW50byBjb250ZW5lZG9yICcnY29tcG9uZW50JycifSwKLQotICAgIHsgRVJfQ0FOX09OTFlfT1VUUFVUX1RPX0VMRU1FTlQsCi0gICAgICAiTGEgc2FsaWRhIHNcdTAwRjNsbyBwdWVkZSByZWFsaXphcnNlIGVuIEVsZW1lbnQsIERvY3VtZW50RnJhZ21lbnQsIERvY3VtZW50IG8gUHJpbnRXcml0ZXIuIn0sCi0KLSAgICB7IEVSX1BST0NFU1NfRVJST1IsCi0gICAgICJFcnJvciBkZSBTdHlsZXNoZWV0Um9vdC5wcm9jZXNzIn0sCi0KLSAgICB7IEVSX1VOSU1QTE5PREVfRVJST1IsCi0gICAgICJFcnJvciBkZSBVbkltcGxOb2RlOiB7MH0ifSwKLQotICAgIHsgRVJfTk9fU0VMRUNUX0VYUFJFU1NJT04sCi0gICAgICAiXHUwMEExRXJyb3IhIE5vIHNlIGhhIGVuY29udHJhZG8gbGEgZXhwcmVzaVx1MDBGM24gZGUgc2VsZWNjaVx1MDBGM24geHBhdGggKC1zZWxlY3QpLiJ9LAotCi0gICAgeyBFUl9DQU5OT1RfU0VSSUFMSVpFX1hTTFBST0NFU1NPUiwKLSAgICAgICJObyBzZSBwdWVkZSBzZXJpYWxpemFyIHVuIHByb2Nlc2Fkb3IgWFNMLiJ9LAotCi0gICAgeyBFUl9OT19JTlBVVF9TVFlMRVNIRUVULAotICAgICAgIk5vIHNlIGhhIGVzcGVjaWZpY2FkbyBsYSBlbnRyYWRhIGRlIGhvamEgZGUgZXN0aWxvLiJ9LAotCi0gICAgeyBFUl9GQUlMRURfUFJPQ0VTU19TVFlMRVNIRUVULAotICAgICAgIkZhbGxvIGFsIHByb2Nlc2FyIGxhIGhvamEgZGUgZXN0aWxvLiJ9LAotCi0gICAgeyBFUl9DT1VMRE5UX1BBUlNFX0RPQywKLSAgICAgIk5vIHNlIGhhIHBvZGlkbyBhbmFsaXphciBlbCBkb2N1bWVudG8gezB9LiJ9LAotCi0gICAgeyBFUl9DT1VMRE5UX0ZJTkRfRlJBR01FTlQsCi0gICAgICJObyBzZSBoYSBlbmNvbnRyYWRvIGVsIGZyYWdtZW50bzogezB9In0sCi0KLSAgICB7IEVSX05PREVfTk9UX0VMRU1FTlQsCi0gICAgICAiRWwgbm9kbyBhcHVudGFkbyBwb3IgZWwgaWRlbnRpZmljYWRvciBkZSBmcmFnbWVudG8gbm8gZXJhIHVuIGVsZW1lbnRvOiB7MH0ifSwKLQotICAgIHsgRVJfRk9SRUFDSF9ORUVEX01BVENIX09SX05BTUVfQVRUUklCLAotICAgICAgImZvci1lYWNoIGRlYmUgdGVuZXIgdW4gYXRyaWJ1dG8gbmFtZSBvIG1hdGNoLiJ9LAotCi0gICAgeyBFUl9URU1QTEFURVNfTkVFRF9NQVRDSF9PUl9OQU1FX0FUVFJJQiwKLSAgICAgICJsYXMgcGxhbnRpbGxhcyBkZWJlbiB0ZW5lciB1biBhdHJpYnV0byBuYW1lIG8gbWF0Y2guIn0sCi0KLSAgICB7IEVSX05PX0NMT05FX09GX0RPQ1VNRU5UX0ZSQUcsCi0gICAgICAiTm8gaGF5IG5pbmd1bmEgY2xvbmFjaVx1MDBGM24gZGUgdW4gZnJhZ21lbnRvIGRlIGRvY3VtZW50by4ifSwKLQotICAgIHsgRVJfQ0FOVF9DUkVBVEVfSVRFTSwKLSAgICAgICJObyBzZSBwdWVkZSBjcmVhciBlbCBlbGVtZW50byBlbiBlbCBcdTAwRTFyYm9sIGRlIHJlc3VsdGFkb3M6IHswfSJ9LAotCi0gICAgeyBFUl9YTUxTUEFDRV9JTExFR0FMX1ZBTFVFLAotICAgICAgInhtbDpzcGFjZSBlbiBlbCBYTUwgZGUgb3JpZ2VuIHRpZW5lIHVuIHZhbG9yIG5vIHZcdTAwRTFsaWRvOiB7MH0ifSwKLQotICAgIHsgRVJfTk9fWFNMS0VZX0RFQ0xBUkFUSU9OLAotICAgICAgIk5vIGhheSBuaW5ndW5hIGRlY2xhcmFjaVx1MDBGM24geHNsOmtleSBwYXJhIHswfS4ifSwKLQotICAgIHsgRVJfQ0FOVF9DUkVBVEVfVVJMLAotICAgICAiRXJyb3IuIE5vIHNlIHB1ZWRlIGNyZWFyIGxhIFVSTCBwYXJhOiB7MH0ifSwKLQotICAgIHsgRVJfWFNMRlVOQ1RJT05TX1VOU1VQUE9SVEVELAotICAgICAieHNsOmZ1bmN0aW9ucyBubyBlc3RcdTAwRTEgc29wb3J0YWRvIn0sCi0KLSAgICB7IEVSX1BST0NFU1NPUl9FUlJPUiwKLSAgICAgIkVycm9yIGRlIFRyYW5zZm9ybWVyRmFjdG9yeSBkZSBYU0xUIn0sCi0KLSAgICB7IEVSX05PVF9BTExPV0VEX0lOU0lERV9TVFlMRVNIRUVULAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgezB9IG5vIHBlcm1pdGlkbyBlbiB1bmEgaG9qYSBkZSBlc3RpbG8uIn0sCi0KLSAgICB7IEVSX1JFU1VMVE5TX05PVF9TVVBQT1JURUQsCi0gICAgICAicmVzdWx0LW5zIHlhIG5vIGVzdFx1MDBFMSBzb3BvcnRhZG8uIFV0aWxpY2UgeHNsOm91dHB1dCBlbiBzdSBsdWdhci4ifSwKLQotICAgIHsgRVJfREVGQVVMVFNQQUNFX05PVF9TVVBQT1JURUQsCi0gICAgICAiZGVmYXVsdC1zcGFjZSB5YSBubyBlc3RcdTAwRTEgc29wb3J0YWRvLiBVdGlsaWNlIHhzbDpzdHJpcC1zcGFjZSBvIHhzbDpwcmVzZXJ2ZS1zcGFjZSBlbiBzdSBsdWdhci4ifSwKLQotICAgIHsgRVJfSU5ERU5UUkVTVUxUX05PVF9TVVBQT1JURUQsCi0gICAgICAiaW5kZW50LXJlc3VsdCB5YSBubyBlc3RcdTAwRTEgc29wb3J0YWRvLiBVdGlsaWNlIHhzbDpvdXRwdXQgZW4gc3UgbHVnYXIuIn0sCi0KLSAgICB7IEVSX0lMTEVHQUxfQVRUUklCLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgezB9IHRpZW5lIHVuIGF0cmlidXRvIG5vIHBlcm1pdGlkbzogezF9In0sCi0KLSAgICB7IEVSX1VOS05PV05fWFNMX0VMRU0sCi0gICAgICJFbGVtZW50byBYU0wgZGVzY29ub2NpZG86IHswfSJ9LAotCi0gICAgeyBFUl9CQURfWFNMU09SVF9VU0UsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSB4c2w6c29ydCBzXHUwMEYzbG8gc2UgcHVlZGUgdXRpbGl6YXIgY29uIHhzbDphcHBseS10ZW1wbGF0ZXMgbyB4c2w6Zm9yLWVhY2guIn0sCi0KLSAgICB7IEVSX01JU1BMQUNFRF9YU0xXSEVOLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgaGEgY29sb2NhZG8geHNsOndoZW4gaW5jb3JyZWN0YW1lbnRlLiJ9LAotCi0gICAgeyBFUl9YU0xXSEVOX05PVF9QQVJFTlRFRF9CWV9YU0xDSE9PU0UsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSB4c2w6d2hlbiBzaW4gcHJpbmNpcGFsIGRlIHhzbDpjaG9vc2UuIn0sCi0KLSAgICB7IEVSX01JU1BMQUNFRF9YU0xPVEhFUldJU0UsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSBoYSBjb2xvY2FkbyB4c2w6b3RoZXJ3aXNlIGRlIGZvcm1hIGluY29ycmVjdGEuIn0sCi0KLSAgICB7IEVSX1hTTE9USEVSV0lTRV9OT1RfUEFSRU5URURfQllfWFNMQ0hPT1NFLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgeHNsOm90aGVyd2lzZSBzaW4gcHJpbmNpcGFsIGRlIHhzbDpjaG9vc2UuIn0sCi0KLSAgICB7IEVSX05PVF9BTExPV0VEX0lOU0lERV9URU1QTEFURSwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIHswfSBubyBlc3RcdTAwRTEgcGVybWl0aWRvIGVuIHVuYSBwbGFudGlsbGEuIn0sCi0KLSAgICB7IEVSX1VOS05PV05fRVhUX05TX1BSRUZJWCwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIHByZWZpam8gezF9IGRlIGVzcGFjaW8gZGUgbm9tYnJlcyBkZSBleHRlbnNpXHUwMEYzbiB7MH0gZGVzY29ub2NpZG8ifSwKLQotICAgIHsgRVJfSU1QT1JUU19BU19GSVJTVF9FTEVNLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgTGFzIGltcG9ydGFjaW9uZXMgc1x1MDBGM2xvIHNlIHB1ZWRlbiByZWFsaXphciBjb21vIGxvcyBwcmltZXJvcyBlbGVtZW50b3MgZW4gbGEgaG9qYSBkZSBlc3RpbG8uIn0sCi0KLSAgICB7IEVSX0lNUE9SVElOR19JVFNFTEYsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSB7MH0gc2UgZXN0XHUwMEUxIGltcG9ydGFuZG8gZGlyZWN0YSBvIGluZGlyZWN0YW1lbnRlLiJ9LAotCi0gICAgeyBFUl9YTUxTUEFDRV9JTExFR0FMX1ZBTCwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIHhtbDpzcGFjZSB0aWVuZSB1biB2YWxvciBubyBwZXJtaXRpZG86IHswfSJ9LAotCi0gICAgeyBFUl9QUk9DRVNTU1RZTEVTSEVFVF9OT1RfU1VDQ0VTU0ZVTCwKLSAgICAgICJwcm9jZXNzU3R5bGVzaGVldCBubyBzZSBoYSByZWFsaXphZG8gY29ycmVjdGFtZW50ZS4ifSwKLQotICAgIHsgRVJfU0FYX0VYQ0VQVElPTiwKLSAgICAgIkV4Y2VwY2lcdTAwRjNuIFNBWCJ9LAotCi0vLyAgYWRkIHRoaXMgbWVzc2FnZSB0byBmaXggYnVnIDIxNDc4Ci0gICAgeyBFUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVELAotICAgICAiRnVuY2lcdTAwRjNuIG5vIHNvcG9ydGFkYS4ifSwKLQotICAgIHsgRVJfWFNMVF9FUlJPUiwKLSAgICAgIkVycm9yIGRlIFhTTFQifSwKLQotICAgIHsgRVJfQ1VSUkVOQ1lfU0lHTl9JTExFR0FMLAotICAgICAgImVsIHNcdTAwRURtYm9sbyBkZSBtb25lZGEgbm8gZXN0XHUwMEUxIHBlcm1pdGlkbyBlbiBsYSBjYWRlbmEgZGUgcGF0clx1MDBGM24gZGUgZm9ybWF0byJ9LAotCi0gICAgeyBFUl9ET0NVTUVOVF9GVU5DVElPTl9JTlZBTElEX0lOX1NUWUxFU0hFRVRfRE9NLAotICAgICAgIkxhIGZ1bmNpXHUwMEYzbiBkZSBkb2N1bWVudG8gbm8gZXN0XHUwMEUxIHNvcG9ydGFkYSBlbiBET00gZGUgbGEgaG9qYSBkZSBlc3RpbG8uIn0sCi0KLSAgICB7IEVSX0NBTlRfUkVTT0xWRV9QUkVGSVhfT0ZfTk9OX1BSRUZJWF9SRVNPTFZFUiwKLSAgICAgICJObyBzZSBwdWVkZSByZXNvbHZlciBlbCBwcmVmaWpvIGRlbCBzaXN0ZW1hIGRlIHJlc29sdWNpXHUwMEYzbiBzaW4gcHJlZmlqby4ifSwKLQotICAgIHsgRVJfUkVESVJFQ1RfQ09VTEROVF9HRVRfRklMRU5BTUUsCi0gICAgICAiRXh0ZW5zaVx1MDBGM24gZGUgcmVkaXJlY2Npb25hbWllbnRvOiBubyBzZSBoYSBwb2RpZG8gb2J0ZW5lciBlbCBub21icmUgZGUgYXJjaGl2byAtIGVsIGF0cmlidXRvIGZpbGUgbyBzZWxlY3QgZGViZSBkZXZvbHZlciB1bmEgY2FkZW5hIHZcdTAwRTFsaWRhLiJ9LAotCi0gICAgeyBFUl9DQU5OT1RfQlVJTERfRk9STUFUVEVSTElTVEVORVJfSU5fUkVESVJFQ1QsCi0gICAgICAiTm8gc2UgcHVlZGUgY3JlYXIgRm9ybWF0dGVyTGlzdGVuZXIgZW4gbGEgZXh0ZW5zaVx1MDBGM24gZGUgcmVkaXJlY2Npb25hbWllbnRvLiJ9LAotCi0gICAgeyBFUl9JTlZBTElEX1BSRUZJWF9JTl9FWENMVURFUkVTVUxUUFJFRklYLAotICAgICAgIkVsIHByZWZpam8gZW4gZXhjbHVkZS1yZXN1bHQtcHJlZml4ZXMgbm8gZXMgdlx1MDBFMWxpZG86IHswfSJ9LAotCi0gICAgeyBFUl9NSVNTSU5HX05TX1VSSSwKLSAgICAgICJGYWx0YSBlbCBVUkkgZGVsIGVzcGFjaW8gZGUgbm9tYnJlcyBwYXJhIGVsIHByZWZpam8gZXNwZWNpZmljYWRvIn0sCi0KLSAgICB7IEVSX01JU1NJTkdfQVJHX0ZPUl9PUFRJT04sCi0gICAgICAiRmFsdGEgdW4gYXJndW1lbnRvIHBhcmEgbGEgb3BjaVx1MDBGM246IHswfSJ9LAotCi0gICAgeyBFUl9JTlZBTElEX09QVElPTiwKLSAgICAgIk9wY2lcdTAwRjNuIG5vIHZcdTAwRTFsaWRhOiB7MH0ifSwKLQotICAgIHsgRVJfTUFMRk9STUVEX0ZPUk1BVF9TVFJJTkcsCi0gICAgICJDYWRlbmEgY29uIGZvcm1hdG8gaW5jb3JyZWN0bzogezB9In0sCi0KLSAgICB7IEVSX1NUWUxFU0hFRVRfUkVRVUlSRVNfVkVSU0lPTl9BVFRSSUIsCi0gICAgICAieHNsOnN0eWxlc2hlZXQgbmVjZXNpdGEgdW4gYXRyaWJ1dG8gJ3ZlcnNpb24nLiJ9LAotCi0gICAgeyBFUl9JTExFR0FMX0FUVFJJQlVURV9WQUxVRSwKLSAgICAgICJFbCBhdHJpYnV0bzogezB9IHRpZW5lIHVuIHZhbG9yIG5vIHBlcm1pdGlkbzogezF9In0sCi0KLSAgICB7IEVSX0NIT09TRV9SRVFVSVJFU19XSEVOLAotICAgICAieHNsOmNob29zZSBuZWNlc2l0YSB1biB4c2w6d2hlbiJ9LAotCi0gICAgeyBFUl9OT19BUFBMWV9JTVBPUlRfSU5fRk9SX0VBQ0gsCi0gICAgICAieHNsOmFwcGx5LWltcG9ydHMgbm8gcGVybWl0aWRvIGVuIHVuIHhzbDpmb3ItZWFjaCJ9LAotCi0gICAgeyBFUl9DQU5UX1VTRV9EVE1fRk9SX09VVFBVVCwKLSAgICAgICJObyBzZSBwdWVkZSB1dGlsaXphciB1biBEVE1MaWFpc29uIHBhcmEgdW4gbm9kbyBET00gZGUgc2FsaWRhLi4uIHRyYW5zZmllcmEgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLkRPTTJIZWxwZXIgZW4gc3UgbHVnYXIsIn0sCi0KLSAgICB7IEVSX0NBTlRfVVNFX0RUTV9GT1JfSU5QVVQsCi0gICAgICAiTm8gc2UgcHVlZGUgdXRpbGl6YXIgdW4gRFRNTGlhaXNvbiBwYXJhIHVuIG5vZG8gRE9NIGRlIGVudHJhZGEuLi4gdHJhbnNmaWVyYSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuRE9NMkhlbHBlciBlbiBzdSBsdWdhciwifSwKLQotICAgIHsgRVJfQ0FMTF9UT19FWFRfRkFJTEVELAotICAgICAgIkZhbGxvIGRlIGxhIGxsYW1hZGEgYWwgZWxlbWVudG8gZGUgZXh0ZW5zaVx1MDBGM246IHswfSJ9LAotCi0gICAgeyBFUl9QUkVGSVhfTVVTVF9SRVNPTFZFLAotICAgICAgIkVsIHByZWZpam8gc2UgZGViZSByZXNvbHZlciBlbiB1biBlc3BhY2lvIGRlIG5vbWJyZXM6IHswfSJ9LAotCi0gICAgeyBFUl9JTlZBTElEX1VURjE2X1NVUlJPR0FURSwKLSAgICAgICJcdTAwQkZTZSBoYSBkZXRlY3RhZG8gdW4gc3VzdGl0dXRvIFVURi0xNiBubyB2XHUwMEUxbGlkbzogezB9PyJ9LAotCi0gICAgeyBFUl9YU0xBVFRSU0VUX1VTRURfSVRTRUxGLAotICAgICAgInhzbDphdHRyaWJ1dGUtc2V0IHswfSBzZSB1dGlsaXphIGEgc1x1MDBFRCBtaXNtbywgbG8gcXVlIGNhdXNhclx1MDBFMSB1biBidWNsZSBpbmZpbml0by4ifSwKLQotICAgIHsgRVJfQ0FOTk9UX01JWF9YRVJDRVNET00sCi0gICAgICAiTm8gc2UgcHVlZGUgbWV6Y2xhciB1bmEgZW50cmFkYSBET00gcXVlIG5vIGVzIGRlIFhlcmNlcyBjb24gdW5hIHNhbGlkYSBET00gZGUgWGVyY2VzLiJ9LAotCi0gICAgeyBFUl9UT09fTUFOWV9MSVNURU5FUlMsCi0gICAgICAiYWRkVHJhY2VMaXN0ZW5lcnNUb1N0eWxlc2hlZXQgLSBUb29NYW55TGlzdGVuZXJzRXhjZXB0aW9uIn0sCi0KLSAgICB7IEVSX0lOX0VMRU1URU1QTEFURUVMRU1fUkVBRE9CSkVDVCwKLSAgICAgICJFbiBFbGVtVGVtcGxhdGVFbGVtZW50LnJlYWRPYmplY3Q6IHswfSJ9LAotCi0gICAgeyBFUl9EVVBMSUNBVEVfTkFNRURfVEVNUExBVEUsCi0gICAgICAiU2UgaGEgZW5jb250cmFkbyBtXHUwMEUxcyBkZSB1bmEgcGxhbnRpbGxhIGNvbiBlbCBub21icmU6IHswfSJ9LAotCi0gICAgeyBFUl9JTlZBTElEX0tFWV9DQUxMLAotICAgICAgIkxsYW1hZGEgZGUgZnVuY2lcdTAwRjNuIG5vIHZcdTAwRTFsaWRhOiBsYXMgbGxhbWFkYXMgcmVjdXJzaXZlIGtleSgpIG5vIGVzdFx1MDBFMW4gcGVybWl0aWRhcyJ9LAotCi0gICAgeyBFUl9SRUZFUkVOQ0lOR19JVFNFTEYsCi0gICAgICAiTGEgdmFyaWFibGUgezB9IGhhY2UgcmVmZXJlbmNpYSBhIHNcdTAwRUQgbWlzbWEgZGUgZm9ybWEgZGlyZWN0YSBvIGluZGlyZWN0YS4ifSwKLQotICAgIHsgRVJfSUxMRUdBTF9ET01TT1VSQ0VfSU5QVVQsCi0gICAgICAiRWwgbm9kbyBkZSBlbnRyYWRhIG5vIHB1ZWRlIHNlciBudWxvIHBhcmEgdW4gRE9NU291cmNlIGRlIG51ZXZhcyBwbGFudGlsbGFzLiJ9LAotCi0gICAgeyBFUl9DTEFTU19OT1RfRk9VTkRfRk9SX09QVElPTiwKLSAgICAgICAgIk5vIHNlIGhhIGVuY29udHJhZG8gZWwgYXJjaGl2byBkZSBjbGFzZSBwYXJhIGxhIG9wY2lcdTAwRjNuIHswfSJ9LAotCi0gICAgeyBFUl9SRVFVSVJFRF9FTEVNX05PVF9GT1VORCwKLSAgICAgICAgIk5vIHNlIGhhIGVuY29udHJhZG8gZWwgZWxlbWVudG8gbmVjZXNhcmlvOiB7MH0ifSwKLQotICAgIHsgRVJfSU5QVVRfQ0FOTk9UX0JFX05VTEwsCi0gICAgICAgICJJbnB1dFN0cmVhbSBubyBwdWVkZSBzZXIgbnVsbyJ9LAotCi0gICAgeyBFUl9VUklfQ0FOTk9UX0JFX05VTEwsCi0gICAgICAgICJFbCBVUkkgbm8gcHVlZGUgc2VyIG51bG8ifSwKLQotICAgIHsgRVJfRklMRV9DQU5OT1RfQkVfTlVMTCwKLSAgICAgICAgIkVsIGFyY2hpdm8gbm8gcHVlZGUgc2VyIG51bG8ifSwKLQotICAgIHsgRVJfU09VUkNFX0NBTk5PVF9CRV9OVUxMLAotICAgICAgICAgICAgICAgICJJbnB1dFNvdXJjZSBubyBwdWVkZSBzZXIgbnVsbyJ9LAotCi0gICAgeyBFUl9DQU5OT1RfSU5JVF9CU0ZNR1IsCi0gICAgICAgICAgICAgICAgIk5vIHNlIGhhIHBvZGlkbyBpbmljaWFsaXphciBlbCBnZXN0b3IgZGUgQlNGIn0sCi0KLSAgICB7IEVSX0NBTk5PVF9DTVBMX0VYVEVOU04sCi0gICAgICAgICAgICAgICAgIk5vIHNlIGhhIHBvZGlkbyBjb21waWxhciBsYSBleHRlbnNpXHUwMEYzbiJ9LAotCi0gICAgeyBFUl9DQU5OT1RfQ1JFQVRFX0VYVEVOU04sCi0gICAgICAiTm8gc2UgaGEgcG9kaWRvIGNyZWFyIGxhIGV4dGVuc2lcdTAwRjNuOiB7MH0gZGViaWRvIGE6IHsxfSJ9LAotCi0gICAgeyBFUl9JTlNUQU5DRV9NVEhEX0NBTExfUkVRVUlSRVMsCi0gICAgICAiTGEgbGxhbWFkYSBkZWwgbVx1MDBFOXRvZG8gZGUgaW5zdGFuY2lhIGFsIG1cdTAwRTl0b2RvIHswfSBuZWNlc2l0YSB1bmEgaW5zdGFuY2lhIGRlIG9iamV0byBjb21vIHByaW1lciBhcmd1bWVudG8ifSwKLQotICAgIHsgRVJfSU5WQUxJRF9FTEVNRU5UX05BTUUsCi0gICAgICAiU2UgaGEgZXNwZWNpZmljYWRvIHVuIG5vbWJyZSBkZSBlbGVtZW50byBubyB2XHUwMEUxbGlkbyB7MH0ifSwKLQotICAgIHsgRVJfRUxFTUVOVF9OQU1FX01FVEhPRF9TVEFUSUMsCi0gICAgICAiRWwgbVx1MDBFOXRvZG8gZGVsIG5vbWJyZSBkZWwgZWxlbWVudG8gZGViZSBzZXIgZXN0XHUwMEUxdGljbyB7MH0ifSwKLQotICAgIHsgRVJfRVhURU5TSU9OX0ZVTkNfVU5LTk9XTiwKLSAgICAgICAgICAgICAiTGEgZnVuY2lcdTAwRjNuIGRlIGV4dGVuc2lcdTAwRjNuIHswfSA6IHsxfSBlcyBkZXNjb25vY2lkYSJ9LAotCi0gICAgeyBFUl9NT1JFX01BVENIX0NPTlNUUlVDVE9SLAotICAgICAgICAgICAgICJIYXkgbVx1MDBFMXMgZGUgdW5hIG1lam9yIGNvaW5jaWRlbmNpYSBwYXJhIGVsIGNvbnN0cnVjdG9yIGRlIHswfSJ9LAotCi0gICAgeyBFUl9NT1JFX01BVENIX01FVEhPRCwKLSAgICAgICAgICAgICAiSGF5IG1cdTAwRTFzIGRlIHVuYSBtZWpvciBjb2luY2lkZW5jaWEgcGFyYSBlbCBtXHUwMEU5dG9kbyB7MH0ifSwKLQotICAgIHsgRVJfTU9SRV9NQVRDSF9FTEVNRU5ULAotICAgICAgICAgICAgICJIYXkgbVx1MDBFMXMgZGUgdW5hIG1lam9yIGNvaW5jaWRlbmNpYSBwYXJhIGVsIG1cdTAwRTl0b2RvIGRlIGVsZW1lbnRvIHswfSJ9LAotCi0gICAgeyBFUl9JTlZBTElEX0NPTlRFWFRfUEFTU0VELAotICAgICAgICAgICAgICJTZSBoYSB0cmFuc2ZlcmlkbyB1biBjb250ZXh0byBubyB2XHUwMEUxbGlkbyBwYXJhIGV2YWx1YXIgezB9In0sCi0KLSAgICB7IEVSX1BPT0xfRVhJU1RTLAotICAgICAgICAgICAgICJFbCBwb29sIHlhIGV4aXN0ZSJ9LAotCi0gICAgeyBFUl9OT19EUklWRVJfTkFNRSwKLSAgICAgICAgICAgICAiTm8gc2UgaGEgZXNwZWNpZmljYWRvIG5pbmdcdTAwRkFuIG5vbWJyZSBkZSBjb250cm9sYWRvciJ9LAotCi0gICAgeyBFUl9OT19VUkwsCi0gICAgICAgICAgICAgIk5vIHNlIGhhIGVzcGVjaWZpY2FkbyBuaW5ndW5hIFVSTCJ9LAotCi0gICAgeyBFUl9QT09MX1NJWkVfTEVTU1RIQU5fT05FLAotICAgICAgICAgICAgICJFbCB0YW1hXHUwMEYxbyBkZWwgcG9vbCBlcyBpbmZlcmlvciBhIHVuby4ifSwKLQotICAgIHsgRVJfSU5WQUxJRF9EUklWRVIsCi0gICAgICAgICAgICAgIlNlIGhhIGVzcGVjaWZpY2FkbyB1biBub21icmUgZGUgY29udHJvbGFkb3Igbm8gdlx1MDBFMWxpZG8uIn0sCi0KLSAgICB7IEVSX05PX1NUWUxFU0hFRVRST09ULAotICAgICAgICAgICAgICJObyBzZSBoYSBlbmNvbnRyYWRvIGxhIHJhXHUwMEVEeiBkZSBsYSBob2phIGRlIGVzdGlsby4ifSwKLQotICAgIHsgRVJfSUxMRUdBTF9YTUxTUEFDRV9WQUxVRSwKLSAgICAgICAgICJWYWxvciBubyBwZXJtaXRpZG8gcGFyYSB4bWw6c3BhY2UifSwKLQotICAgIHsgRVJfUFJPQ0VTU0ZST01OT0RFX0ZBSUxFRCwKLSAgICAgICAgICJGYWxsbyBkZSBwcm9jZXNzRnJvbU5vZGUifSwKLQotICAgIHsgRVJfUkVTT1VSQ0VfQ09VTERfTk9UX0xPQUQsCi0gICAgICAgICJObyBzZSBoYSBwb2RpZG8gY2FyZ2FyIGVsIHJlY3Vyc28gWyB7MH0gXTogezF9IFxuIHsyfSBcdCB7M30ifSwKLQotICAgIHsgRVJfQlVGRkVSX1NJWkVfTEVTU1RIQU5fWkVSTywKLSAgICAgICAgIlRhbWFcdTAwRjFvIGRlIGJ1ZmZlciBtZW5vciBvIGlndWFsIHF1ZSAwIn0sCi0KLSAgICB7IEVSX1VOS05PV05fRVJST1JfQ0FMTElOR19FWFRFTlNJT04sCi0gICAgICAgICJFcnJvciBkZXNjb25vY2lkbyBhbCBsbGFtYXIgYSBsYSBleHRlbnNpXHUwMEYzbiJ9LAotCi0gICAgeyBFUl9OT19OQU1FU1BBQ0VfREVDTCwKLSAgICAgICAgIkVsIHByZWZpam8gezB9IG5vIHRpZW5lIHVuYSBkZWNsYXJhY2lcdTAwRjNuIGRlIGVzcGFjaW8gZGUgbm9tYnJlcyBjb3JyZXNwb25kaWVudGUifSwKLQotICAgIHsgRVJfRUxFTV9DT05URU5UX05PVF9BTExPV0VELAotICAgICAgICAiQ29udGVuaWRvIGRlIGVsZW1lbnRvIG5vIHBlcm1pdGlkbyBwYXJhIGxhbmc9amF2YWNsYXNzIHswfSJ9LAotCi0gICAgeyBFUl9TVFlMRVNIRUVUX0RJUkVDVEVEX1RFUk1JTkFUSU9OLAotICAgICAgICAiVGVybWluYWNpXHUwMEYzbiBkaXJpZ2lkYSBkZSBob2phIGRlIGVzdGlsbyJ9LAotCi0gICAgeyBFUl9PTkVfT1JfVFdPLAotICAgICAgICAiMSBvIDIifSwKLQotICAgIHsgRVJfVFdPX09SX1RIUkVFLAotICAgICAgICAiMiBvIDMifSwKLQotICAgIHsgRVJfQ09VTERfTk9UX0xPQURfUkVTT1VSQ0UsCi0gICAgICAgICJObyBzZSBoYSBwb2RpZG8gY2FyZ2FyIHswfSAobWFyY2FyIENMQVNTUEFUSCksIGFjdHVhbG1lbnRlIHNcdTAwRjNsbyBzZSB1dGlsaXphbiBsb3MgdmFsb3JlcyBwb3IgZGVmZWN0byJ9LAotCi0gICAgeyBFUl9DQU5OT1RfSU5JVF9ERUZBVUxUX1RFTVBMQVRFUywKLSAgICAgICAgIk5vIHNlIHB1ZWRlbiBpbmljaWFsaXphciBsYXMgcGxhbnRpbGxhcyBwb3IgZGVmZWN0byJ9LAotCi0gICAgeyBFUl9SRVNVTFRfTlVMTCwKLSAgICAgICAgIkVsIHJlc3VsdGFkbyBubyBkZWJlIHNlciBudWxvIn0sCi0KLSAgICB7IEVSX1JFU1VMVF9DT1VMRF9OT1RfQkVfU0VULAotICAgICAgICAiTm8gc2UgaGEgcG9kaWRvIGRlZmluaXIgZWwgcmVzdWx0YWRvIn0sCi0KLSAgICB7IEVSX05PX09VVFBVVF9TUEVDSUZJRUQsCi0gICAgICAgICJObyBzZSBoYSBlc3BlY2lmaWNhZG8gbmluZ3VuYSBzYWxpZGEifSwKLQotICAgIHsgRVJfQ0FOTk9UX1RSQU5TRk9STV9UT19SRVNVTFRfVFlQRSwKLSAgICAgICAgIk5vIHNlIHB1ZWRlIHRyYW5zZm9ybWFyIGVuIHVuIHJlc3VsdGFkbyBkZSB0aXBvIHswfSJ9LAotCi0gICAgeyBFUl9DQU5OT1RfVFJBTlNGT1JNX1NPVVJDRV9UWVBFLAotICAgICAgICAiTm8gc2UgcHVlZGUgdHJhbnNmb3JtYXIgZW4gdW4gb3JpZ2VuIGRlIHRpcG8gezB9In0sCi0KLSAgICB7IEVSX05VTExfQ09OVEVOVF9IQU5ETEVSLAotICAgICAgICAiTWFuZWphZG9yIGRlIGNvbnRlbmlkbyBudWxvIn0sCi0KLSAgICB7IEVSX05VTExfRVJST1JfSEFORExFUiwKLSAgICAgICAgIk1hbmVqYWRvciBkZSBlcnJvcmVzIG51bG8ifSwKLQotICAgIHsgRVJfQ0FOTk9UX0NBTExfUEFSU0UsCi0gICAgICAgICJubyBzZSBwdWVkZSByZWFsaXphciBlbCBhblx1MDBFMWxpc2lzIHNpIG5vIHNlIGhhIGRlZmluaWRvIGVsIG1hbmVqYWRvciBkZSBjb250ZW5pZG8ifSwKLQotICAgIHsgRVJfTk9fUEFSRU5UX0ZPUl9GSUxURVIsCi0gICAgICAgICJOaW5nXHUwMEZBbiBwcmluY2lwYWwgcGFyYSBlbCBmaWx0cm8ifSwKLQotICAgIHsgRVJfTk9fU1RZTEVTSEVFVF9JTl9NRURJQSwKLSAgICAgICAgICJObyBzZSBoYSBlbmNvbnRyYWRvIG5pbmd1bmEgaG9qYSBkZSBlc3RpbG8gZW46IHswfSwgc29wb3J0ZT0gezF9In0sCi0KLSAgICB7IEVSX05PX1NUWUxFU0hFRVRfUEksCi0gICAgICAgICAiTm8gc2UgaGEgZW5jb250cmFkbyBuaW5nXHUwMEZBbiBQSSBkZSBob2phIGRlIGVzdGlsbyBYTUwgZW46IHswfSJ9LAotCi0gICAgeyBFUl9OT1RfU1VQUE9SVEVELAotICAgICAgICJObyBzb3BvcnRhZG86IHswfSJ9LAotCi0gICAgeyBFUl9QUk9QRVJUWV9WQUxVRV9CT09MRUFOLAotICAgICAgICJFbCB2YWxvciBwYXJhIGxhIHByb3BpZWRhZCB7MH0gZGViZSBzZXIgdW5hIGluc3RhbmNpYSBib29sZWFuYSJ9LAotCi0gICAgeyBFUl9DT1VMRF9OT1RfRklORF9FWFRFUk5fU0NSSVBULAotICAgICAgICAgIk5vIHNlIGhhIHBvZGlkbyBvYnRlbmVyIHVuIHNjcmlwdCBleHRlcm5vIGVuIHswfSJ9LAotCi0gICAgeyBFUl9SRVNPVVJDRV9DT1VMRF9OT1RfRklORCwKLSAgICAgICAgIk5vIHNlIGhhIGVuY29udHJhZG8gZWwgcmVjdXJzbyBbIHswfSBdLlxuezF9In0sCi0KLSAgICB7IEVSX09VVFBVVF9QUk9QRVJUWV9OT1RfUkVDT0dOSVpFRCwKLSAgICAgICAgIlByb3BpZWRhZCBkZSBzYWxpZGEgbm8gcmVjb25vY2lkYTogezB9In0sCi0KLSAgICB7IEVSX0ZBSUxFRF9DUkVBVElOR19FTEVNTElUUlNMVCwKLSAgICAgICAgIkZhbGxvIGFsIGNyZWFyIGxhIGluc3RhbmNpYSBFbGVtTGl0ZXJhbFJlc3VsdCJ9LAotCi0gIC8vRWFybGllciAoSkRLIDEuNCBYQUxBTiAyLjItRDExKSBhdCBrZXkgY29kZSAnMjA0JyB0aGUga2V5IG5hbWUgd2FzIEVSX1BSSU9SSVRZX05PVF9QQVJTQUJMRQotICAvLyBJbiBsYXRlc3QgWGFsYW4gY29kZSBiYXNlIGtleSBuYW1lIGlzICBFUl9WQUxVRV9TSE9VTERfQkVfTlVNQkVSLiBUaGlzIHNob3VsZCBhbHNvIGJlIHRha2VuIGNhcmUKLSAgLy9pbiBsb2NhbGUgc3BlY2lmaWMgZmlsZXMgbGlrZSBYU0xURXJyb3JSZXNvdXJjZXNfZGUuamF2YSwgWFNMVEVycm9yUmVzb3VyY2VzX2ZyLmphdmEgZXRjLgotICAvL05PVEU6IE5vdCBvbmx5IHRoZSBrZXkgbmFtZSBidXQgbWVzc2FnZSBoYXMgYWxzbyBiZWVuIGNoYW5nZWQuCi0gICAgeyBFUl9WQUxVRV9TSE9VTERfQkVfTlVNQkVSLAotICAgICAgICAiRWwgdmFsb3IgcGFyYSB7MH0gbm8gZGViZSBjb250ZW5lciB1biBuXHUwMEZBbWVybyBxdWUgcHVlZGEgYW5hbGl6YXJzZSJ9LAotCi0gICAgeyBFUl9WQUxVRV9TSE9VTERfRVFVQUwsCi0gICAgICAgICJFbCB2YWxvciBwYXJhIHswfSBkZWJlIHNlciBpZ3VhbCBhIHNcdTAwRUQgbyBuby4ifSwKLQotICAgIHsgRVJfRkFJTEVEX0NBTExJTkdfTUVUSE9ELAotICAgICAgICAiRmFsbG8gYWwgbGxhbWFyIGFsIG1cdTAwRTl0b2RvIHswfSJ9LAotCi0gICAgeyBFUl9GQUlMRURfQ1JFQVRJTkdfRUxFTVRNUEwsCi0gICAgICAgICJGYWxsbyBhbCBjcmVhciBsYSBpbnN0YW5jaWEgRWxlbVRlbXBsYXRlRWxlbWVudCJ9LAotCi0gICAgeyBFUl9DSEFSU19OT1RfQUxMT1dFRCwKLSAgICAgICAgIkVuIGVzdGUgbW9tZW50bywgbm8gc2UgcGVybWl0ZSBlbCB1c28gZGUgY2FyYWN0ZXJlcyBlbiBlbCBkb2N1bWVudG8ifSwKLQotICAgIHsgRVJfQVRUUl9OT1RfQUxMT1dFRCwKLSAgICAgICAgIkVsIGF0cmlidXRvIFwiezB9XCIgbm8gZXN0XHUwMEUxIHBlcm1pdGlkbyBlbiBlbCBlbGVtZW50byB7MX0uIn0sCi0KLSAgICB7IEVSX0JBRF9WQUxVRSwKLSAgICAgInswfSB2YWxvciBpbmNvcnJlY3RvIHsxfSAifSwKLQotICAgIHsgRVJfQVRUUklCX1ZBTFVFX05PVF9GT1VORCwKLSAgICAgIk5vIHNlIGhhIGVuY29udHJhZG8gZWwgdmFsb3IgZGVsIGF0cmlidXRvIHswfSAifSwKLQotICAgIHsgRVJfQVRUUklCX1ZBTFVFX05PVF9SRUNPR05JWkVELAotICAgICAiRWwgdmFsb3IgZGVsIGF0cmlidXRvIHswfSBubyBzZSBoYSByZWNvbm9jaWRvICJ9LAotCi0gICAgeyBFUl9OVUxMX1VSSV9OQU1FU1BBQ0UsCi0gICAgICJTZSBlc3RcdTAwRTEgaW50ZW50YW5kbyBnZW5lcmFyIHVuIHByZWZpam8gZGUgZXNwYWNpbyBkZSBub21icmVzIGNvbiB1biBVUkkgbnVsbyJ9LAotCi0gICAgeyBFUl9OVU1CRVJfVE9PX0JJRywKLSAgICAgIlNlIGVzdFx1MDBFMSBpbnRlbnRhbmRvIGZvcm1hdGVhciB1biBuXHUwMEZBbWVybyBzdXBlcmlvciBhbCBlbnRlcm8gbGFyZ28gbVx1MDBFMXMgZ3JhbmRlIn0sCi0KLSAgICB7IEVSX0NBTk5PVF9GSU5EX1NBWDFfRFJJVkVSLAotICAgICAiTm8gc2UgaGEgZW5jb250cmFkbyBsYSBjbGFzZSBkZSBjb250cm9sYWRvciBTQVgxIHswfSJ9LAotCi0gICAgeyBFUl9TQVgxX0RSSVZFUl9OT1RfTE9BREVELAotICAgICAiU2UgaGEgZW5jb250cmFkbyBsYSBjbGFzZSBkZSBjb250cm9sYWRvciBTQVgxIHswfSBwZXJvIG5vIHNlIHB1ZWRlIGNhcmdhciJ9LAotCi0gICAgeyBFUl9TQVgxX0RSSVZFUl9OT1RfSU5TVEFOVElBVEVELAotICAgICAiU2UgaGEgY2FyZ2FkbyBsYSBjbGFzZSBkZSBjb250cm9sYWRvciBTQVgxIHswfSBwZXJvIG5vIHNlIHB1ZWRlIGluc3RhbmNpYXIifSwKLQotICAgIHsgRVJfU0FYMV9EUklWRVJfTk9UX0lNUExFTUVOVF9QQVJTRVIsCi0gICAgICJMYSBjbGFzZSBkZSBjb250cm9sYWRvciBTQVgxIHswfSBubyBpbXBsYW50YSBvcmcueG1sLnNheC5QYXJzZXIifSwKLQotICAgIHsgRVJfUEFSU0VSX1BST1BFUlRZX05PVF9TUEVDSUZJRUQsCi0gICAgICJObyBzZSBoYSBlc3BlY2lmaWNhZG8gbGEgcHJvcGllZGFkIGRlbCBzaXN0ZW1hIG9yZy54bWwuc2F4LnBhcnNlciJ9LAotCi0gICAgeyBFUl9QQVJTRVJfQVJHX0NBTk5PVF9CRV9OVUxMLAotICAgICAiRWwgYXJndW1lbnRvIGRlbCBhbmFsaXphZG9yIG5vIGRlYmUgc2VyIG51bG8ifSwKLQotICAgIHsgRVJfRkVBVFVSRSwKLSAgICAgIkZ1bmNpXHUwMEYzbjogezB9In0sCi0KLSAgICB7IEVSX1BST1BFUlRZLAotICAgICAiUHJvcGllZGFkOiB7MH0ifSwKLQotICAgIHsgRVJfTlVMTF9FTlRJVFlfUkVTT0xWRVIsCi0gICAgICJTaXN0ZW1hIGRlIHJlc29sdWNpXHUwMEYzbiBkZSBlbnRpZGFkZXMgbnVsbyJ9LAotCi0gICAgeyBFUl9OVUxMX0RURF9IQU5ETEVSLAotICAgICAiTWFuZWphZG9yIERURCBudWxvIn0sCi0KLSAgICB7IEVSX05PX0RSSVZFUl9OQU1FX1NQRUNJRklFRCwKLSAgICAgIk5vIHNlIGhhIGVzcGVjaWZpY2FkbyBuaW5nXHUwMEZBbiBub21icmUgZGUgY29udHJvbGFkb3IifSwKLQotICAgIHsgRVJfTk9fVVJMX1NQRUNJRklFRCwKLSAgICAgIk5vIHNlIGhhIGVzcGVjaWZpY2FkbyBuaW5ndW5hIFVSTCJ9LAotCi0gICAgeyBFUl9QT09MU0laRV9MRVNTX1RIQU5fT05FLAotICAgICAiRWwgdGFtYVx1MDBGMW8gZGVsIHBvb2wgZXMgaW5mZXJpb3IgYSAxLiJ9LAotCi0gICAgeyBFUl9JTlZBTElEX0RSSVZFUl9OQU1FLAotICAgICAiU2UgaGEgZXNwZWNpZmljYWRvIHVuIG5vbWJyZSBkZSBjb250cm9sYWRvciBubyB2XHUwMEUxbGlkby4ifSwKLQotICAgIHsgRVJfRVJST1JMSVNURU5FUiwKLSAgICAgIkVycm9yTGlzdGVuZXIifSwKLQotCi0vLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIHNob3VsZCBub3Qgbm9ybWFsbHkgYmUgZGlzcGxheWVkCi0vLyAgIHRvIHVzZXJzLiAgSXQgZGVzY3JpYmVzIGEgc2l0dWF0aW9uIGluIHdoaWNoIHRoZSBwcm9jZXNzb3IgaGFzIGRldGVjdGVkCi0vLyAgIGFuIGludGVybmFsIGNvbnNpc3RlbmN5IHByb2JsZW0gaW4gaXRzZWxmLCBhbmQgaXQgcHJvdmlkZXMgdGhpcyBtZXNzYWdlCi0vLyAgIGZvciB0aGUgZGV2ZWxvcGVyIHRvIGhlbHAgZGlhZ25vc2UgdGhlIHByb2JsZW0uICBUaGUgbmFtZQotLy8gICAnRWxlbVRlbXBsYXRlRWxlbWVudCcgaXMgdGhlIG5hbWUgb2YgYSBjbGFzcywgYW5kIHNob3VsZCBub3QgYmUKLS8vICAgdHJhbnNsYXRlZC4KLSAgICB7IEVSX0FTU0VSVF9OT19URU1QTEFURV9QQVJFTlQsCi0gICAgICJFcnJvciBkZWwgcHJvZ3JhbWFkb3IuIExhIGV4cHJlc2lcdTAwRjNuIG5vIHRpZW5lIGVsIHByaW5jaXBhbCBFbGVtVGVtcGxhdGVFbGVtZW50LiJ9LAotCi0KLS8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2Ugc2hvdWxkIG5vdCBub3JtYWxseSBiZSBkaXNwbGF5ZWQKLS8vICAgdG8gdXNlcnMuICBJdCBkZXNjcmliZXMgYSBzaXR1YXRpb24gaW4gd2hpY2ggdGhlIHByb2Nlc3NvciBoYXMgZGV0ZWN0ZWQKLS8vICAgYW4gaW50ZXJuYWwgY29uc2lzdGVuY3kgcHJvYmxlbSBpbiBpdHNlbGYsIGFuZCBpdCBwcm92aWRlcyB0aGlzIG1lc3NhZ2UKLS8vICAgZm9yIHRoZSBkZXZlbG9wZXIgdG8gaGVscCBkaWFnbm9zZSB0aGUgcHJvYmxlbS4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dAotLy8gICBwcm92aWRlcyBmdXJ0aGVyIGluZm9ybWF0aW9uIGluIG9yZGVyIHRvIGRpYWdub3NlIHRoZSBwcm9ibGVtLiAgVGhlIG5hbWUKLS8vICAgJ1JlZHVuZGVudEV4cHJFbGltaW5hdG9yJyBpcyB0aGUgbmFtZSBvZiBhIGNsYXNzLCBhbmQgc2hvdWxkIG5vdCBiZQotLy8gICB0cmFuc2xhdGVkLgotICAgIHsgRVJfQVNTRVJUX1JFRFVOREVOVF9FWFBSX0VMSU1JTkFUT1IsCi0gICAgICJBZmlybWFjaVx1MDBGM24gZGVsIHByb2dyYW1hZG9yIGVuIFJlZHVuZGVudEV4cHJFbGltaW5hdG9yOiB7MH0ifSwKLQotICAgIHsgRVJfTk9UX0FMTE9XRURfSU5fUE9TSVRJT04sCi0gICAgICJ7MH0gbm8gZXN0XHUwMEUxIHBlcm1pdGlkbyBlbiBlc3RhIHBvc2ljaVx1MDBGM24gZGUgbGEgaG9qYSBkZSBlc3RpbG8uIn0sCi0KLSAgICB7IEVSX05PTldISVRFU1BBQ0VfTk9UX0FMTE9XRURfSU5fUE9TSVRJT04sCi0gICAgICJFbCB0ZXh0byBkaXN0aW50byBkZSB1biBlc3BhY2lvIGVuIGJsYW5jbyBubyBlc3RcdTAwRTEgcGVybWl0aWRvIGVuIGVzdGEgcG9zaWNpXHUwMEYzbiBkZSBsYSBob2phIGRlIGVzdGlsby4ifSwKLQotICAvLyBUaGlzIGNvZGUgaXMgc2hhcmVkIHdpdGggd2FybmluZyBjb2Rlcy4KLSAgLy8gU3lzdGVtSWQgVW5rbm93bgotICAgIHsgSU5WQUxJRF9UQ0hBUiwKLSAgICAgIlZhbG9yIG5vIHBlcm1pdGlkbzogezF9IHV0aWxpemFkbyBwYXJhIGVsIGF0cmlidXRvIENIQVI6IHswfS4gVW4gYXRyaWJ1dG8gZGVsIHRpcG8gQ0hBUiBkZWJlIHRlbmVyIHNcdTAwRjNsbyAxIGNhclx1MDBFMWN0ZXIuIn0sCi0KLSAgICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIGlzIHVzZWQgaWYgdGhlIHZhbHVlIG9mCi0gICAgLy8gYW4gYXR0cmlidXRlIGluIGEgc3R5bGVzaGVldCBpcyBpbnZhbGlkLiAgIlFOQU1FIiBpcyB0aGUgWE1MIGRhdGEtdHlwZSBvZgotICAgIC8vIHRoZSBhdHRyaWJ1dGUsIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgezF9IGlzCi0gICAgLy8gdGhlIGF0dHJpYnV0ZSB2YWx1ZSBhbmQgezB9IGlzIHRoZSBhdHRyaWJ1dGUgbmFtZS4KLSAgLy9UaGUgZm9sbG93aW5nIGNvZGVzIGFyZSBzaGFyZWQgd2l0aCB0aGUgd2FybmluZyBjb2Rlcy4uLgotICAgIHsgSU5WQUxJRF9RTkFNRSwKLSAgICAgIlZhbG9yIG5vIHBlcm1pdGlkbzogezF9IHV0aWxpemFkbyBwYXJhIGVsIGF0cmlidXRvIFFOQU1FOiB7MH0ifSwKLQotICAgIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgaXMgdXNlZCBpZiB0aGUgdmFsdWUgb2YKLSAgICAvLyBhbiBhdHRyaWJ1dGUgaW4gYSBzdHlsZXNoZWV0IGlzIGludmFsaWQuICAiRU5VTSIgaXMgdGhlIFhNTCBkYXRhLXR5cGUgb2YKLSAgICAvLyB0aGUgYXR0cmlidXRlLCBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHsxfSBpcwotICAgIC8vIHRoZSBhdHRyaWJ1dGUgdmFsdWUsIHswfSBpcyB0aGUgYXR0cmlidXRlIG5hbWUsIGFuZCB7Mn0gaXMgYSBsaXN0IG9mIHZhbGlkCi0gICAgLy8gdmFsdWVzLgotICAgIHsgSU5WQUxJRF9FTlVNLAotICAgICAiVmFsb3Igbm8gcGVybWl0aWRvOiB7MX0gdXRpbGl6YWRvIHBhcmEgZWwgYXRyaWJ1dG8gRU5VTTogezB9LiBMb3MgdmFsb3JlcyB2XHUwMEUxbGlkb3Mgc29uOiB7Mn0uIn0sCi0KLS8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgaXMgdXNlZCBpZiB0aGUgdmFsdWUgb2YKLS8vIGFuIGF0dHJpYnV0ZSBpbiBhIHN0eWxlc2hlZXQgaXMgaW52YWxpZC4gICJOTVRPS0VOIiBpcyB0aGUgWE1MIGRhdGEtdHlwZQotLy8gb2YgdGhlIGF0dHJpYnV0ZSwgYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCB7MX0gaXMKLS8vIHRoZSBhdHRyaWJ1dGUgdmFsdWUgYW5kIHswfSBpcyB0aGUgYXR0cmlidXRlIG5hbWUuCi0gICAgeyBJTlZBTElEX05NVE9LRU4sCi0gICAgICJWYWxvciBubyBwZXJtaXRpZG86IHsxfSB1dGlsaXphZG8gcGFyYSBlbCBhdHJpYnV0byBOTVRPS0VOOiB7MH0gIn0sCi0KLS8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgaXMgdXNlZCBpZiB0aGUgdmFsdWUgb2YKLS8vIGFuIGF0dHJpYnV0ZSBpbiBhIHN0eWxlc2hlZXQgaXMgaW52YWxpZC4gICJOQ05BTUUiIGlzIHRoZSBYTUwgZGF0YS10eXBlCi0vLyBvZiB0aGUgYXR0cmlidXRlLCBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHsxfSBpcwotLy8gdGhlIGF0dHJpYnV0ZSB2YWx1ZSBhbmQgezB9IGlzIHRoZSBhdHRyaWJ1dGUgbmFtZS4KLSAgICB7IElOVkFMSURfTkNOQU1FLAotICAgICAiVmFsb3Igbm8gcGVybWl0aWRvOiB7MX0gdXRpbGl6YWRvIHBhcmEgZWwgYXRyaWJ1dG8gTkNOQU1FOiB7MH0gIn0sCi0KLS8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgaXMgdXNlZCBpZiB0aGUgdmFsdWUgb2YKLS8vIGFuIGF0dHJpYnV0ZSBpbiBhIHN0eWxlc2hlZXQgaXMgaW52YWxpZC4gICJib29sZWFuIiBpcyB0aGUgWFNMVCBkYXRhLXR5cGUKLS8vIG9mIHRoZSBhdHRyaWJ1dGUsIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgezF9IGlzCi0vLyB0aGUgYXR0cmlidXRlIHZhbHVlIGFuZCB7MH0gaXMgdGhlIGF0dHJpYnV0ZSBuYW1lLgotICAgIHsgSU5WQUxJRF9CT09MRUFOLAotICAgICAiVmFsb3Igbm8gcGVybWl0aWRvOiB7MX0gdXRpbGl6YWRvIHBhcmEgZWwgYXRyaWJ1dG8gYm9vbGVhbjogezB9ICJ9LAotCi0vLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIGlzIHVzZWQgaWYgdGhlIHZhbHVlIG9mCi0vLyBhbiBhdHRyaWJ1dGUgaW4gYSBzdHlsZXNoZWV0IGlzIGludmFsaWQuICAibnVtYmVyIiBpcyB0aGUgWFNMVCBkYXRhLXR5cGUKLS8vIG9mIHRoZSBhdHRyaWJ1dGUsIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgezF9IGlzCi0vLyB0aGUgYXR0cmlidXRlIHZhbHVlIGFuZCB7MH0gaXMgdGhlIGF0dHJpYnV0ZSBuYW1lLgotICAgICB7IElOVkFMSURfTlVNQkVSLAotICAgICAiVmFsb3Igbm8gcGVybWl0aWRvOiB7MX0gdXRpbGl6YWRvIHBhcmEgZWwgYXRyaWJ1dG8gbnVtYmVyOiB7MH0gIn0sCi0KLQotICAvLyBFbmQgb2Ygc2hhcmVkIGNvZGVzLi4uCi0KLS8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBICJtYXRjaCBwYXR0ZXJuIiBpcyBhIHNwZWNpYWwgZm9ybSBvZiBYUGF0aCBleHByZXNzaW9uCi0vLyB0aGF0IGlzIHVzZWQgZm9yIG1hdGNoaW5nIHBhdHRlcm5zLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mCi0vLyBhIGZ1bmN0aW9uLiAgVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgd2hlbiB0aGlzIGZ1bmN0aW9uIGlzIHJlZmVyZW5jZWQgaW4KLS8vIGEgbWF0Y2ggcGF0dGVybiwgaXRzIGFyZ3VtZW50IG11c3QgYmUgYSBzdHJpbmcgbGl0ZXJhbCAob3IgY29uc3RhbnQuKQotLy8gRVJfQVJHX0xJVEVSQUwgLSBuZXcgZXJyb3IgbWVzc2FnZSBmb3IgYnVnemlsbGEgLy81MjAyCi0gICAgeyBFUl9BUkdfTElURVJBTCwKLSAgICAgIkVsIGFyZ3VtZW50byBwYXJhIHswfSBlbiBlbCBwYXRyXHUwMEYzbiBkZSBjb2luY2lkZW5jaWEgbm8gZGViZSBzZXIgdW4gdmFsb3IgbGl0ZXJhbC4ifSwKLQotLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0d28gZGVmaW5pdGlvbnMgb2YKLS8vIGEgdmFyaWFibGUuICBBICJnbG9iYWwgdmFyaWFibGUiIGlzIGEgdmFyaWFibGUgdGhhdCBpcyBhY2Nlc3NpYmxlIGV2ZXJ5d2hlcgotLy8gaW4gdGhlIHN0eWxlc2hlZXQuCi0vLyBFUl9EVVBMSUNBVEVfR0xPQkFMX1ZBUiAtIG5ldyBlcnJvciBtZXNzYWdlIGZvciBidWd6aWxsYSAjNzkwCi0gICAgeyBFUl9EVVBMSUNBVEVfR0xPQkFMX1ZBUiwKLSAgICAgIkR1cGxpY2FyIGRlY2xhcmFjaVx1MDBGM24gZGUgdmFyaWFibGUgZ2xvYmFsLiJ9LAotCi0KLS8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdHdvIGRlZmluaXRpb25zIG9mCi0vLyBhIHZhcmlhYmxlIHdlcmUgZW5jb3VudGVyZWQuCi0vLyBFUl9EVVBMSUNBVEVfVkFSIC0gbmV3IGVycm9yIG1lc3NhZ2UgZm9yIGJ1Z3ppbGxhICM3OTAKLSAgICB7IEVSX0RVUExJQ0FURV9WQVIsCi0gICAgICJEdXBsaWNhciBkZWNsYXJhY2lcdTAwRjNuIGRlIHZhcmlhYmxlLiJ9LAotCi0gICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogICJ4c2w6dGVtcGxhdGUsICJuYW1lIiBhbmQgIm1hdGNoIiBhcmUgWFNMVCBrZXl3b3JkcwotICAgIC8vIHdoaWNoIG11c3Qgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgLy8gRVJfVEVNUExBVEVfTkFNRV9NQVRDSCAtIG5ldyBlcnJvciBtZXNzYWdlIGZvciBidWd6aWxsYSAjNzg5Ci0gICAgeyBFUl9URU1QTEFURV9OQU1FX01BVENILAotICAgICAieHNsOnRlbXBsYXRlIGRlYmUgdGVuZXIgdW4gYXRyaWJ1dG8gbmFtZSBvIG1hdGNoIChvIGFtYm9zKSJ9LAotCi0gICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogICJleGNsdWRlLXJlc3VsdC1wcmVmaXhlcyIgaXMgYW4gWFNMVCBrZXl3b3JkIHdoaWNoCi0gICAgLy8gc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgYSBuYW1lc3BhY2UgcHJlZml4Ci0gICAgLy8gZW5jb3VudGVyZWQgYXMgcGFydCBvZiB0aGUgdmFsdWUgb2YgdGhlIGV4Y2x1ZGUtcmVzdWx0LXByZWZpeGVzIGF0dHJpYnV0ZQotICAgIC8vIHdhcyBpbiBlcnJvci4KLSAgICAvLyBFUl9JTlZBTElEX1BSRUZJWCAtIG5ldyBlcnJvciBtZXNzYWdlIGZvciBidWd6aWxsYSAjNzg4Ci0gICAgeyBFUl9JTlZBTElEX1BSRUZJWCwKLSAgICAgIkVsIHByZWZpam8gZW4gZXhjbHVkZS1yZXN1bHQtcHJlZml4ZXMgbm8gZXMgdlx1MDBFMWxpZG86IHswfSJ9LAotCi0gICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIEFuICJhdHRyaWJ1dGUgc2V0IiBpcyBhIHNldCBvZiBhdHRyaWJ1dGVzIHRoYXQgY2FuCi0gICAgLy8gYmUgYWRkZWQgdG8gYW4gZWxlbWVudCBpbiB0aGUgb3V0cHV0IGRvY3VtZW50IGFzIGEgZ3JvdXAuICBUaGUgbWVzc2FnZQotICAgIC8vIGluZGljYXRlcyB0aGF0IHRoZXJlIHdhcyBhIHJlZmVyZW5jZSB0byBhbiBhdHRyaWJ1dGUgc2V0IG5hbWVkIHswfSB0aGF0Ci0gICAgLy8gd2FzIG5ldmVyIGRlZmluZWQuCi0gICAgLy8gRVJfTk9fQVRUUklCX1NFVCAtIG5ldyBlcnJvciBtZXNzYWdlIGZvciBidWd6aWxsYSAjNzgyCi0gICAgeyBFUl9OT19BVFRSSUJfU0VULAotICAgICAiRWwganVlZ28gZGUgYXRyaWJ1dG9zIGNvbiBlbCBub21icmUgezB9IG5vIGV4aXN0ZSJ9LAotCi0gICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGVyZSB3YXMgYSByZWZlcmVuY2UKLSAgICAvLyB0byBhIGZ1bmN0aW9uIG5hbWVkIHswfSBmb3Igd2hpY2ggbm8gZnVuY3Rpb24gZGVmaW5pdGlvbiBjb3VsZCBiZSBmb3VuZC4KLSAgICB7IEVSX0ZVTkNUSU9OX05PVF9GT1VORCwKLSAgICAgIkxhIGZ1bmNpXHUwMEYzbiBjb24gZWwgbm9tYnJlIHswfSBubyBleGlzdGUifSwKLQotICAgIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhlIFhTTFQgaW5zdHJ1Y3Rpb24KLSAgICAvLyB0aGF0IGlzIG5hbWVkIGJ5IHRoZSBzdWJzdGl0dXRpb24gdGV4dCB7MH0gbXVzdCBub3QgY29udGFpbiBvdGhlciBYU0xUCi0gICAgLy8gaW5zdHJ1Y3Rpb25zIChjb250ZW50KSBvciBhICJzZWxlY3QiIGF0dHJpYnV0ZS4gIFRoZSB3b3JkICJzZWxlY3QiIGlzCi0gICAgLy8gYW4gWFNMVCBrZXl3b3JkIGluIHRoaXMgY2FzZSBhbmQgbXVzdCBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICB7IEVSX0NBTlRfSEFWRV9DT05URU5UX0FORF9TRUxFQ1QsCi0gICAgICJFbCBlbGVtZW50byB7MH0gbm8gZGViZSB0ZW5lciBjb250ZW5pZG8gbmkgdW4gYXRyaWJ1dG8gc2VsZWN0LiJ9LAotCi0gICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUgdmFsdWUgYXJndW1lbnQKLSAgICAvLyBvZiBzZXRQYXJhbWV0ZXIgbXVzdCBiZSBhIHZhbGlkIEphdmEgT2JqZWN0LgotICAgIHsgRVJfSU5WQUxJRF9TRVRfUEFSQU1fVkFMVUUsCi0gICAgICJFbCB2YWxvciBkZWwgcGFyXHUwMEUxbWV0cm8gezB9IGRlYmUgdGVuZXIgdW4gb2JqZXRvIEphdmEgdlx1MDBFMWxpZG8ifSwKLQotICAgIHsgRVJfSU5WQUxJRF9OQU1FU1BBQ0VfVVJJX1ZBTFVFX0ZPUl9SRVNVTFRfUFJFRklYX0ZPUl9ERUZBVUxULAotICAgICAgIkVsIGF0cmlidXRvIHJlc3VsdC1wcmVmaXggZGUgdW4gZWxlbWVudG8geHNsOm5hbWVzcGFjZS1hbGlhcyB0aWVuZSBlbCB2YWxvciAnJyNkZWZhdWx0JywgcGVybyBubyBoYXkgbmluZ3VuYSBkZWNsYXJhY2lcdTAwRjNuIGRlbCBlc3BhY2lvIGRlIG5vbWJyZXMgcG9yIGRlZmVjdG8gZW4gZWwgXHUwMEUxbWJpdG8gcGFyYSBlbCBlbGVtZW50byJ9LAotCi0gICAgeyBFUl9JTlZBTElEX05BTUVTUEFDRV9VUklfVkFMVUVfRk9SX1JFU1VMVF9QUkVGSVgsCi0gICAgICAiRWwgYXRyaWJ1dG8gcmVzdWx0LXByZWZpeCBkZSB1biBlbGVtZW50byB4c2w6bmFtZXNwYWNlLWFsaWFzIHRpZW5lIGVsIHZhbG9yICcnezB9JycsIHBlcm8gbm8gaGF5IG5pbmd1bmEgZGVjbGFyYWNpXHUwMEYzbiBkZWwgZXNwYWNpbyBkZSBub21icmVzIHBhcmEgZWwgcHJlZmlqbyAnJ3swfScnIGVuIGVsIFx1MDBFMW1iaXRvIHBhcmEgZWwgZWxlbWVudG8uIn0sCi0KLSAgICB7IEVSX1NFVF9GRUFUVVJFX05VTExfTkFNRSwKLSAgICAgICJFbCBub21icmUgZGUgZnVuY2lcdTAwRjNuIG5vIHB1ZWRlIHNlciBudWxvIGVuIFRyYW5zZm9ybWVyRmFjdG9yeS5zZXRGZWF0dXJlIChub21icmUgZGUgY2FkZW5hLCB2YWxvciBib29sZWFubykuIn0sCi0KLSAgICB7IEVSX0dFVF9GRUFUVVJFX05VTExfTkFNRSwKLSAgICAgICJFbCBub21icmUgZGUgZnVuY2lcdTAwRjNuIG5vIHB1ZWRlIHNlciBudWxvIGVuIFRyYW5zZm9ybWVyRmFjdG9yeS5nZXRGZWF0dXJlIChub21icmUgZGUgY2FkZW5hKS4ifSwKLQotICAgIHsgRVJfVU5TVVBQT1JURURfRkVBVFVSRSwKLSAgICAgICJObyBzZSBwdWVkZSBkZWZpbmlyIGxhIGZ1bmNpXHUwMEYzbiAnJ3swfScnZW4gZXN0YSBmXHUwMEUxYnJpY2EgZGVsIHRyYW5zZm9ybWFkb3IuIn0sCi0KLSAgICB7IEVSX0VYVEVOU0lPTl9FTEVNRU5UX05PVF9BTExPV0VEX0lOX1NFQ1VSRV9QUk9DRVNTSU5HLAotICAgICAgICAgICJMYSB1dGlsaXphY2lcdTAwRjNuIGRlbCBlbGVtZW50byBkZSBleHRlbnNpXHUwMEYzbiAnJ3swfScnIG5vIGVzdFx1MDBFMSBwZXJtaXRpZGEgY3VhbmRvIGxhIGZ1bmNpXHUwMEYzbiBkZSBwcm9jZXNhbWllbnRvIHNlZ3VybyBzZSBoYSBkZWZpbmlkbyBlbiB0cnVlLiJ9LAotCi0gICAgeyBFUl9OQU1FU1BBQ0VfQ09OVEVYVF9OVUxMX05BTUVTUEFDRSwKLSAgICAgICJObyBzZSBwdWVkZSBvYnRlbmVyIGVsIHByZWZpam8gcGFyYSB1biBVUkkgZGUgZXNwYWNpbyBkZSBub21icmVzIG51bG8uIn0sCi0KLSAgICB7IEVSX05BTUVTUEFDRV9DT05URVhUX05VTExfUFJFRklYLAotICAgICAgIk5vIHNlIHB1ZWRlIG9idGVuZXIgZWwgVVJJIGRlIGVzcGFjaW8gZGUgbm9tYnJlcyBwYXJhIHVuIHByZWZpam8gbnVsby4ifSwKLQotICAgIHsgRVJfWFBBVEhfUkVTT0xWRVJfTlVMTF9RTkFNRSwKLSAgICAgICJFbCBub21icmUgZGUgbGEgZnVuY2lcdTAwRjNuIG5vIHB1ZWRlIHNlciBudWxvLiJ9LAotCi0gICAgeyBFUl9YUEFUSF9SRVNPTFZFUl9ORUdBVElWRV9BUklUWSwKLSAgICAgICJFbCBuXHUwMEZBbWVybyBkZSBhcmd1bWVudG9zIG5vIHB1ZWRlIHNlciBuZWdhdGl2by4ifSwKLSAgLy8gV2FybmluZ3MuLi4KLQotICAgIHsgV0dfRk9VTkRfQ1VSTFlCUkFDRSwKLSAgICAgICJTZSBoYW4gZW5jb250cmFkbyAnfScgcGVybyBubyBoYXkgbmluZ3VuYSBwbGFudGlsbGEgZGUgYXRyaWJ1dG9zIGFiaWVydGEuIn0sCi0KLSAgICB7IFdHX0NPVU5UX0FUVFJJQl9NQVRDSEVTX05PX0FOQ0VTVE9SLAotICAgICAgIkFkdmVydGVuY2lhOiBlbCBhdHJpYnV0byBjb3VudCBubyBjb2luY2lkZSBjb24gdW4gYXNjZW5kaWVudGUgZW4gZWwgZGVzdGlubyB4c2w6bnVtYmVyISA9IHswfSJ9LAotCi0gICAgeyBXR19FWFBSX0FUVFJJQl9DSEFOR0VEX1RPX1NFTEVDVCwKLSAgICAgICJTaW50YXhpcyBhbnRlcmlvcjogZWwgbm9tYnJlIGRlbCBhdHJpYnV0byAnZXhwcicgc2UgaGEgY2FtYmlhZG8gcG9yIGVsIGRlICdzZWxlY3QnLiJ9LAotCi0gICAgeyBXR19OT19MT0NBTEVfSU5fRk9STUFUTlVNQkVSLAotICAgICAgIlhhbGFuIG5vIG1hbmVqYSBhXHUwMEZBbiBlbCBub21icmUgZGUgY29uZmlndXJhY2lcdTAwRjNuIHJlZ2lvbmFsIGVuIGxhIGZ1bmNpXHUwMEYzbiBmb3JtYXQtbnVtYmVyLiJ9LAotCi0gICAgeyBXR19MT0NBTEVfTk9UX0ZPVU5ELAotICAgICAgIkFkdmVydGVuY2lhOiBubyBzZSBoYSBlbmNvbnRyYWRvIGxhIGNvbmZpZ3VyYWNpXHUwMEYzbiByZWdpb25hbCBwYXJhIHhtbDpsYW5nPXswfSJ9LAotCi0gICAgeyBXR19DQU5OT1RfTUFLRV9VUkxfRlJPTSwKLSAgICAgICJObyBzZSBwdWVkZSBjcmVhciBsYSBVUkwgZGVzZGU6IHswfSJ9LAotCi0gICAgeyBXR19DQU5OT1RfTE9BRF9SRVFVRVNURURfRE9DLAotICAgICAgIk5vIHNlIHB1ZWRlIGNhcmdhciBlbCBkb2N1bWVudG8gc29saWNpdGFkbzogezB9In0sCi0KLSAgICB7IFdHX0NBTk5PVF9GSU5EX0NPTExBVE9SLAotICAgICAgIk5vIHNlIGhhIGVuY29udHJhZG8gZWwgaW50ZXJjYWxhZG9yIHBhcmEgPHNvcnQgeG1sOmxhbmc9ezB9In0sCi0KLSAgICB7IFdHX0ZVTkNUSU9OU19TSE9VTERfVVNFX1VSTCwKLSAgICAgICJTaW50YXhpcyBhbnRlcmlvcjogbGEgaW5zdHJ1Y2NpXHUwMEYzbiBkZSBsYXMgZnVuY2lvbmVzIGRlYmUgdXRpbGl6YXIgdW5hIFVSTCBkZSB7MH0ifSwKLQotICAgIHsgV0dfRU5DT0RJTkdfTk9UX1NVUFBPUlRFRF9VU0lOR19VVEY4LAotICAgICAgImNvZGlmaWNhY2lcdTAwRjNuIG5vIHNvcG9ydGFkYTogezB9LCB1dGlsaXphbmRvIFVURi04In0sCi0KLSAgICB7IFdHX0VOQ09ESU5HX05PVF9TVVBQT1JURURfVVNJTkdfSkFWQSwKLSAgICAgICJjb2RpZmljYWNpXHUwMEYzbiBubyBzb3BvcnRhZGE6IHswfSwgdXRpbGl6YW5kbyBKYXZhIHsxfSJ9LAotCi0gICAgeyBXR19TUEVDSUZJQ0lUWV9DT05GTElDVFMsCi0gICAgICAiU2UgaGFuIGVuY29udHJhZG8gY29uZmxpY3RvcyBkZSBwcmVjaXNpXHUwMEYzbjogezB9IFNlIHV0aWxpemFyXHUwMEUxIGxhIFx1MDBGQWx0aW1hIGVuY29udHJhZGEgZW4gbGEgaG9qYSBkZSBlc3RpbG8uIn0sCi0KLSAgICB7IFdHX1BBUlNJTkdfQU5EX1BSRVBBUklORywKLSAgICAgICI9PT09PT09PT0gQW5hbGl6YW5kbyB5IHByZXBhcmFuZG8gezB9ID09PT09PT09PT0ifSwKLQotICAgIHsgV0dfQVRUUl9URU1QTEFURSwKLSAgICAgIlBsYW50aWxsYSBkZSBhdHJpYnV0b3MsIHswfSJ9LAotCi0gICAgeyBXR19DT05GTElDVF9CRVRXRUVOX1hTTFNUUklQU1BBQ0VfQU5EX1hTTFBSRVNFUlZFU1BBQ0UsCi0gICAgICAiQ29uZmxpY3RvIGRlIGNvaW5jaWRlbmNpYSBlbnRyZSB4c2w6c3RyaXAtc3BhY2UgeSB4c2w6cHJlc2VydmUtc3BhY2UifSwKLQotICAgIHsgV0dfQVRUUklCX05PVF9IQU5ETEVELAotICAgICAgIlhhbGFuIG5vIG1hbmVqYSBhXHUwMEZBbiBlbCBhdHJpYnV0byB7MH0uIn0sCi0KLSAgICB7IFdHX05PX0RFQ0lNQUxGT1JNQVRfREVDTEFSQVRJT04sCi0gICAgICAiTm8gc2UgaGEgZW5jb250cmFkbyBuaW5ndW5hIGRlY2xhcmFjaVx1MDBGM24gcGFyYSBlbCBmb3JtYXRvIGRlY2ltYWw6IHswfSJ9LAotCi0gICAgeyBXR19PTERfWFNMVF9OUywKLSAgICAgIkZhbHRhIGVsIGVzcGFjaW8gZGUgbm9tYnJlcyBYU0xUIG8gZXMgaW5jb3JyZWN0by4gIn0sCi0KLSAgICB7IFdHX09ORV9ERUZBVUxUX1hTTERFQ0lNQUxGT1JNQVRfQUxMT1dFRCwKLSAgICAgICJTXHUwMEYzbG8gc2UgcGVybWl0ZSB1bmEgZGVjbGFyYWNpXHUwMEYzbiB4c2w6ZGVjaW1hbC1mb3JtYXQgcG9yIGRlZmVjdG8uIn0sCi0KLSAgICB7IFdHX1hTTERFQ0lNQUxGT1JNQVRfTkFNRVNfTVVTVF9CRV9VTklRVUUsCi0gICAgICAiTG9zIG5vbWJyZXMgZGUgeHNsOmRlY2ltYWwtZm9ybWF0IGRlYmVuIHNlciBcdTAwRkFuaWNvcy4gRWwgbm9tYnJlIFwiezB9XCIgc2UgaGEgZHVwbGljYWRvLiJ9LAotCi0gICAgeyBXR19JTExFR0FMX0FUVFJJQlVURSwKLSAgICAgICJ7MH0gdGllbmUgdW4gYXRyaWJ1dG8gbm8gcGVybWl0aWRvOiB7MX0ifSwKLQotICAgIHsgV0dfQ09VTERfTk9UX1JFU09MVkVfUFJFRklYLAotICAgICAgIk5vIHNlIGhhIHBvZGlkbyByZXNvbHZlciBlbCBwcmVmaWpvIGRlIGVzcGFjaW8gZGUgbm9tYnJlczogezB9LiBFbCBub2RvIHNlIGlnbm9yYXJcdTAwRTEuIn0sCi0KLSAgICB7IFdHX1NUWUxFU0hFRVRfUkVRVUlSRVNfVkVSU0lPTl9BVFRSSUIsCi0gICAgICAieHNsOnN0eWxlc2hlZXQgbmVjZXNpdGEgdW4gYXRyaWJ1dG8gJ3ZlcnNpb24nLiJ9LAotCi0gICAgeyBXR19JTExFR0FMX0FUVFJJQlVURV9OQU1FLAotICAgICAgIk5vbWJyZSBkZSBhdHJpYnV0byBubyBwZXJtaXRpZG86IHswfSJ9LAotCi0gICAgeyBXR19JTExFR0FMX0FUVFJJQlVURV9WQUxVRSwKLSAgICAgICJTZSBoYSB1dGlsaXphZG8gdW4gdmFsb3Igbm8gcGVybWl0aWRvIHBhcmEgZWwgYXRyaWJ1dG8gezB9OiB7MX0ifSwKLQotICAgIHsgV0dfRU1QVFlfU0VDT05EX0FSRywKLSAgICAgICJFbCBqdWVnbyBkZSBub2RvcyByZXN1bHRhbnRlIGRlbCBzZWd1bmRvIGFyZ3VtZW50byBkZSBsYSBmdW5jaVx1MDBGM24gZGVsIGRvY3VtZW50byBlc3RcdTAwRTEgdmFjXHUwMEVEby4gU2UgaGEgZGV2dWVsdG8gdW4ganVlZ28gZGUgbm9kb3MgdmFjXHUwMEVEby4ifSwKLQotICAvL0ZvbGxvd2luZyBhcmUgdGhlIG5ldyBXQVJOSU5HIGtleXMgYWRkZWQgaW4gWEFMQU4gY29kZSBiYXNlIGFmdGVyIEpkayAxLjQgKFhhbGFuIDIuMi1EMTEpCi0KLSAgICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIm5hbWUiIGFuZCAieHNsOnByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24iIGFyZSBrZXl3b3JkcwotICAgIC8vIGFuZCBtdXN0IG5vdCBiZSB0cmFuc2xhdGVkLgotICAgIHsgV0dfUFJPQ0VTU0lOR0lOU1RSVUNUSU9OX05BTUVfQ0FOVF9CRV9YTUwsCi0gICAgICAiRWwgdmFsb3IgZGVsIGF0cmlidXRvICduYW1lJyBkZWwgbm9tYnJlIGRlIHhzbDpwcm9jZXNzaW5nLWluc3RydWN0aW9uIG5vIGRlYmUgc2VyICd4bWwnIn0sCi0KLSAgICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIm5hbWUiIGFuZCAieHNsOnByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24iIGFyZSBrZXl3b3JkcwotICAgIC8vIGFuZCBtdXN0IG5vdCBiZSB0cmFuc2xhdGVkLiAgIk5DTmFtZSIgaXMgYW4gWE1MIGRhdGEtdHlwZSBhbmQgbXVzdCBub3QgYmUKLSAgICAvLyB0cmFuc2xhdGVkLgotICAgIHsgV0dfUFJPQ0VTU0lOR0lOU1RSVUNUSU9OX05PVFZBTElEX05DTkFNRSwKLSAgICAgICJFbCB2YWxvciBkZWwgYXRyaWJ1dG8gJyduYW1lJycgZGUgeHNsOnByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24gZGViZSBzZXIgdW4gTkNOYW1lIHZcdTAwRTFsaWRvOiB7MH0ifSwKLQotICAgIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgcmVwb3J0ZWQgaWYgdGhlIHN0eWxlc2hlZXQgdGhhdCBpcwotICAgIC8vIGJlaW5nIHByb2Nlc3NlZCBhdHRlbXB0ZWQgdG8gY29uc3RydWN0IGFuIFhNTCBkb2N1bWVudCB3aXRoIGFuIGF0dHJpYnV0ZSBpbiBhCi0gICAgLy8gcGxhY2Ugb3RoZXIgdGhhbiBvbiBhbiBlbGVtZW50LiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHNwZWNpZmllcyB0aGUgbmFtZSBvZgotICAgIC8vIHRoZSBhdHRyaWJ1dGUuCi0gICAgeyBXR19JTExFR0FMX0FUVFJJQlVURV9QT1NJVElPTiwKLSAgICAgICJObyBzZSBwdWVkZSBhZ3JlZ2FyIGVsIGF0cmlidXRvIHswfSBkZXNwdVx1MDBFOXMgZGUgbm9kb3Mgc2VjdW5kYXJpb3MgbyBhbnRlcyBkZSBxdWUgc2UgcHJvZHV6Y2EgdW4gZWxlbWVudG8uIFNlIGlnbm9yYXJcdTAwRTEgZWwgYXRyaWJ1dG8uIn0sCi0KLSAgICB7IE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiwKLSAgICAgICJTZSBoYSByZWFsaXphZG8gdW4gaW50ZW50byBkZSBtb2RpZmljYXIgdW4gb2JqZXRvIGVuIGVsIHF1ZSBubyBlc3RcdTAwRTFuIHBlcm1pdGlkYXMgbGFzIG1vZGlmaWNhY2lvbmVzLiIKLSAgICB9LAotCi0gICAgLy9DaGVjazogV0hZIFRIRVJFIElTIEEgR0FQIEIvVyBOVU1CRVJTIGluIHRoZSBYU0xURXJyb3JSZXNvdXJjZXMgcHJvcGVydGllcyBmaWxlPwotCi0gIC8vIE90aGVyIG1pc2NlbGxhbmVvdXMgdGV4dCB1c2VkIGluc2lkZSB0aGUgY29kZS4uLgotICB7ICJ1aV9sYW5ndWFnZSIsICJlcyJ9LAotICB7ICAiaGVscF9sYW5ndWFnZSIsICAiZXMiIH0sCi0gIHsgICJsYW5ndWFnZSIsICAiZXMiIH0sCi0gIHsgIkJBRF9DT0RFIiwgIkVsIHBhclx1MDBFMW1ldHJvIHBhcmEgY3JlYXIgdW4gbWVuc2FqZSBlc3RcdTAwRTEgZnVlcmEgZGUgbG9zIGxcdTAwRURtaXRlcyJ9LAotICB7ICAiRk9STUFUX0ZBSUxFRCIsICJTZSBoYSBlbWl0aWRvIHVuYSBleGNlcGNpXHUwMEYzbiBkdXJhbnRlIGxhIGxsYW1hZGEgYSBtZXNzYWdlRm9ybWF0In0sCi0gIHsgICJ2ZXJzaW9uIiwgIj4+Pj4+Pj4gVmVyc2lcdTAwRjNuIFhhbGFuICJ9LAotICB7ICAidmVyc2lvbjIiLCAgIjw8PDw8PDwifSwKLSAgeyAgInllcyIsICJzXHUwMEVEIn0sCi0gIHsgImxpbmUiLCAiTlx1MDBCQSBkZSBMXHUwMEVEbmVhIn0sCi0gIHsgImNvbHVtbiIsIk5cdTAwQkEgZGUgQ29sdW1uYSJ9LAotICB7ICJ4c2xkb25lIiwgIlhTTFByb2Nlc3NvcjogbGlzdG8ifSwKLQotCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2VzIHByb3ZpZGUgdXNhZ2UgaW5mb3JtYXRpb24KLSAgLy8gZm9yIHRoZSBYYWxhbiBQcm9jZXNzIGNvbW1hbmQgbGluZS4gICJQcm9jZXNzIiBpcyB0aGUgbmFtZSBvZiBhIEphdmEgY2xhc3MsCi0gIC8vIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuCi0gIHsgInhzbFByb2Nfb3B0aW9uIiwgIk9wY2lvbmVzIGRlIGxhIGNsYXNlIFByb2Nlc3MgZGUgbGEgbFx1MDBFRG5lYSBkZSBjb21hbmRvcyBYYWxhbi1KIDoifSwKLSAgeyAieHNsUHJvY19vcHRpb24iLCAiT3BjaW9uZXMgZGUgbGEgY2xhc2UgUHJvY2VzcyBkZSBsYSBsXHUwMEVEbmVhIGRlIGNvbWFuZG9zIFhhbGFuLUogOiJ9LAotICB7ICJ4c2xQcm9jX2ludmFsaWRfeHNsdGNfb3B0aW9uIiwgIkxhIG9wY2lcdTAwRjNuIHswfSBubyBlc3RcdTAwRTEgc29wb3J0YWRhIGVuIGVsIG1vZG8gWFNMVEMuIn0sCi0gIHsgInhzbFByb2NfaW52YWxpZF94YWxhbl9vcHRpb24iLCAiTGEgb3BjaVx1MDBGM24gezB9IHNcdTAwRjNsbyBwdWVkZSB1dGlsaXphcnNlIGNvbiAtWFNMVEMuIn0sCi0gIHsgInhzbFByb2Nfbm9faW5wdXQiLCAiRXJyb3I6IG5vIHNlIGhhIGVzcGVjaWZpY2FkbyBuaW5ndW5hIGhvamEgZGUgZXN0aWxvIG8gWE1MIGRlIGVudHJhZGEuIEVqZWN1dGUgZXN0ZSBjb21hbmRvIHNpbiBuaW5ndW5hIG9wY2lcdTAwRjNuIHBhcmEgbGFzIGluc3RydWNjaW9uZXMgZGUgdXNvLiJ9LAotICB7ICJ4c2xQcm9jX2NvbW1vbl9vcHRpb25zIiwgIi1PcGNpb25lcyBDb211bmVzLSJ9LAotICB7ICJ4c2xQcm9jX3hhbGFuX29wdGlvbnMiLCAiLU9wY2lvbmVzIHBhcmEgWGFsYW4tIn0sCi0gIHsgInhzbFByb2NfeHNsdGNfb3B0aW9ucyIsICItT3BjaW9uZXMgcGFyYSBYU0xUQy0ifSwKLSAgeyAieHNsUHJvY19yZXR1cm5fdG9fY29udGludWUiLCAiKHB1bHNlIDxpbnRybz4gcGFyYSBjb250aW51YXIpIn0sCi0KLSAgIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6IFRoZSBvcHRpb24gbmFtZSBhbmQgdGhlIHBhcmFtZXRlciBuYW1lIGRvIG5vdCBuZWVkIHRvCi0gICAvLyBiZSB0cmFuc2xhdGVkLiBPbmx5IHRyYW5zbGF0ZSB0aGUgbWVzc2FnZXMgaW4gcGFyZW50aGVzZXMuICBOb3RlIGFsc28gdGhhdAotICAgLy8gbGVhZGluZyB3aGl0ZXNwYWNlIGluIHRoZSBtZXNzYWdlcyBpcyB1c2VkIHRvIGluZGVudCB0aGUgdXNhZ2UgaW5mb3JtYXRpb24KLSAgIC8vIGZvciBlYWNoIG9wdGlvbiBpbiB0aGUgRW5nbGlzaCBtZXNzYWdlcy4KLSAgIC8vIERvIG5vdCB0cmFuc2xhdGUgdGhlIGtleXdvcmRzOiBYU0xUQywgU0FYLCBET00gYW5kIERUTS4KLSAgeyAib3B0aW9uWFNMVEMiLCAiICAgWy1YU0xUQyAodXRpbGl6YXIgWFNMVEMgcGFyYSBsYSB0cmFuc2Zvcm1hY2lcdTAwRjNuKV0ifSwKLSAgeyAib3B0aW9uSU4iLCAiICAgWy1JTiBpbnB1dFhNTFVSTF0ifSwKLSAgeyAib3B0aW9uWFNMIiwgIiAgIFstWFNMIFhTTFRyYW5zZm9ybWF0aW9uVVJMXSJ9LAotICB7ICJvcHRpb25PVVQiLCAgIiAgIFstT1VUIG91dHB1dEZpbGVOYW1lXSJ9LAotICB7ICJvcHRpb25MWENJTiIsICIgICBbLUxYQ0lOIGNvbXBpbGVkU3R5bGVzaGVldEZpbGVOYW1lSW5dIn0sCi0gIHsgIm9wdGlvbkxYQ09VVCIsICIgICBbLUxYQ09VVCBjb21waWxlZFN0eWxlc2hlZXRGaWxlTmFtZU91dE91dF0ifSwKLSAgeyAib3B0aW9uUEFSU0VSIiwgIiAgIFstUEFSU0VSIG5vbWJyZSBkZSBjbGFzZSB0b3RhbG1lbnRlIGN1YWxpZmljYWRvIGRlIGVubGFjZSBkZSBhbmFsaXphZG9yXSJ9LAotICB7ICAib3B0aW9uRSIsICIgICBbLUUgKE5vIGFtcGxpYXIgcmVmZXJlbmNpYXMgZGUgZW50aWRhZCldIn0sCi0gIHsgICJvcHRpb25WIiwgICIgICBbLUUgKE5vIGFtcGxpYXIgcmVmZXJlbmNpYXMgZGUgZW50aWRhZCldIn0sCi0gIHsgICJvcHRpb25RQyIsICIgICBbLVFDIChBZHZlcnRlbmNpYXMgZGUgQ29uZmxpY3RvcyBkZSBQYXRyXHUwMEYzbiBTaWxlbmNpb3NvKV0ifSwKLSAgeyAgIm9wdGlvblEiLCAiICAgWy1RICAoTW9kbyBTaWxlbmNpb3NvKV0ifSwKLSAgeyAgIm9wdGlvbkxGIiwgIiAgIFstTEYgKFV0aWxpemFyIHNhbHRvcyBkZSBsXHUwMEVEbmVhIHNcdTAwRjNsbyBlbiBsYSBzYWxpZGEge2VsIHZhbG9yIHBvciBkZWZlY3RvIGVzIENSL0xGfSldIn0sCi0gIHsgICJvcHRpb25DUiIsICIgICBbLUNSIChVdGlsaXphciByZXRvcm5vcyBkZSBjYXJybyBzXHUwMEYzbG8gZW4gbGEgc2FsaWRhIHtlbCB2YWxvciBwb3IgZGVmZWN0byBlcyBDUi9MRn0pXSJ9LAotICB7ICJvcHRpb25FU0NBUEUiLCAiICAgWy1FU0NBUEUgKENhcmFjdGVyZXMgcGFyYSBpbnRyb2R1Y2lyIGVzY2FwZSB7ZWwgdmFsb3IgcG9yIGRlZmVjdG8gZXMgPD4mXCInXFxyXFxufV0ifSwKLSAgeyAib3B0aW9uSU5ERU5UIiwgIiAgIFstSU5ERU5UIChDb250cm9sIGRlbCBuXHUwMEZBbWVybyBkZSBlc3BhY2lvcyBwYXJhIGVsIHNhbmdyYWRvIHtlbCB2YWxvciBwb3IgZGVmZWN0byBlcyAwfSldIn0sCi0gIHsgIm9wdGlvblRUIiwgIiAgIFstVFQgKFJhc3RyZWFyIGxhcyBwbGFudGlsbGFzIGNvbW8gc2kgc2UgZXN0dXZpZXNlbiBsbGFtYW5kby4pXSJ9LAotICB7ICJvcHRpb25URyIsICIgICBbLVRHIChSYXN0cmVhciBjYWRhIGV2ZW50byBkZSBnZW5lcmFjaVx1MDBGM24uKV0ifSwKLSAgeyAib3B0aW9uVFMiLCAiICAgWy1UUyAoUmFzdHJlYXIgY2FkYSBldmVudG8gZGUgc2VsZWNjaVx1MDBGM24uKV0ifSwKLSAgeyAgIm9wdGlvblRUQyIsICIgICBbLVRUQyAoUmFzdHJlYXIgbG9zIHNlY3VuZGFyaW9zIGRlIHBsYW50aWxsYSBjb21vIHNpIHNlIGVzdHV2aWVzZW4gcHJvY2VzYW5kby4pXSJ9LAotICB7ICJvcHRpb25UQ0xBU1MiLCAiICAgWy1UQ0xBU1MgKENsYXNlIFRyYWNlTGlzdGVuZXIgcGFyYSBsYXMgZXh0ZW5zaW9uZXMgZGUgcmFzdHJlby4pXSJ9LAotICB7ICJvcHRpb25WQUxJREFURSIsICIgICBbLVZBTElEQVRFIChEZXRlcm1pbmFyIHNpIHNlIHByb2R1Y2UgbGEgdmFsaWRhY2lcdTAwRjNuLiBMYSB2YWxpZGFjaVx1MDBGM24gZXN0XHUwMEUxIGRlc2FjdGl2YWRhIHBvciBkZWZlY3RvLildIn0sCi0gIHsgIm9wdGlvbkVEVU1QIiwgIiAgIFstRURVTVAge25vbWJyZSBkZSBhcmNoaXZvIG9wY2lvbmFsfSAoUmVhbGl6YXIgdm9sY2FkbyBkZSBwaWxhIHNpIHNlIHByb2R1Y2UgZWwgZXJyb3IuKV0ifSwKLSAgeyAgIm9wdGlvblhNTCIsICIgICBbLVhNTCAoVXRpbGl6YXIgZWwgZm9ybWF0ZWFkb3IgWE1MIHkgYWdyZWdhciB1bmEgY2FiZWNlcmEgWE1MLildIn0sCi0gIHsgICJvcHRpb25URVhUIiwgIiAgIFstVEVYVCAoVXRpbGl6YXIgZWwgZm9ybWF0ZWFkb3IgZGUgdGV4dG8gc2ltcGxlLildIn0sCi0gIHsgICJvcHRpb25IVE1MIiwgIiAgIFstSFRNTCAoVXRpbGl6YXIgZWwgZm9ybWF0ZWFkb3IgSFRNTC4pXSJ9LAotICB7ICAib3B0aW9uUEFSQU0iLCAiICAgWy1QQVJBTSBleHByZXNpXHUwMEYzbiBkZSBub21icmUgKERlZmluaXIgdW4gcGFyXHUwMEUxbWV0cm8gZGUgaG9qYSBkZSBlc3RpbG8pXSJ9LAotICB7ICAibm9QYXJzZXJtc2cxIiwgIkVsIHByb2Nlc28gWFNMIG5vIHNlIGhhIHJlYWxpemFkbyBjb3JyZWN0YW1lbnRlLiJ9LAotICB7ICAibm9QYXJzZXJtc2cyIiwgIioqIE5vIHNlIGhhIGVuY29udHJhZG8gZWwgYW5hbGl6YWRvciAqKiJ9LAotICB7ICJub1BhcnNlcm1zZzMiLCAgIkNvbXBydWViZSBsYSBjbGFzc3BhdGguIn0sCi0gIHsgIm5vUGFyc2VybXNnNCIsICJTaSBubyB0aWVuZSB1biBhbmFsaXphZG9yIFhNTCBkZSBJQk0gcGFyYSBKYXZhLCBwdWVkZSBkZXNjYXJnYXJsbyBkZSJ9LAotICB7ICJub1BhcnNlcm1zZzUiLCAiQWxwaGFXb3JrcyBkZSBJQk06IGh0dHA6Ly93d3cuYWxwaGF3b3Jrcy5pYm0uY29tL2Zvcm11bGEveG1sIn0sCi0gIHsgIm9wdGlvblVSSVJFU09MVkVSIiwgIiAgIFstVVJJUkVTT0xWRVIgbm9tYnJlIGRlIGNsYXNlIGNvbXBsZXRvIChVUklSZXNvbHZlciBzZSBwdWVkZSB1dGlsaXphciBwYXJhIHJlc29sdmVyIGxvcyBVUkkpXSJ9LAotICB7ICJvcHRpb25FTlRJVFlSRVNPTFZFUiIsICAiICAgWy1FTlRJVFlSRVNPTFZFUiBub21icmUgZGUgY2xhc2UgY29tcGxldG8gKEVudGl0eVJlc29sdmVyIHV0aWxpemFkbyBwYXJhIHJlc29sdmVyIGVudGlkYWRlcyldIn0sCi0gIHsgIm9wdGlvbkNPTlRFTlRIQU5ETEVSIiwgICIgICBbLUNPTlRFTlRIQU5ETEVSIG5vbWJyZSBkZSBjbGFzZSBjb21wbGV0byAoQ29udGVudEhhbmRsZXIgdXRpbGl6YWRvIHBhcmEgc2VyaWFsaXphciBsYSBzYWxpZGEpXSJ9LAotICB7ICAib3B0aW9uTElORU5VTUJFUlMiLCAgIiAgIFstTCB1dGlsaXphciBuXHUwMEZBbWVyb3MgZGUgbFx1MDBFRG5lYSBwYXJhIGVsIGRvY3VtZW50byBkZSBvcmlnZW5dIn0sCi0gIHsgIm9wdGlvblNFQ1VSRVBST0NFU1NJTkciLCAiICAgWy1TRUNVUkUgKGRlZmluaXIgbGEgZnVuY2lcdTAwRjNuIGRlIHByb2Nlc2FtaWVudG8gc2VndXJvIGVuIHRydWUuKV0ifSwKLQotICAgIC8vIEZvbGxvd2luZyBhcmUgdGhlIG5ldyBvcHRpb25zIGFkZGVkIGluIFhTTFRFcnJvclJlc291cmNlcy5wcm9wZXJ0aWVzIGZpbGVzIGFmdGVyIEpkayAxLjQgKFhhbGFuIDIuMi1EMTEpCi0KLQotICB7ICAib3B0aW9uTUVESUEiLCAgIiAgIFstTUVESUEgbWVkaWFUeXBlICh1dGlsaWNlIGVsIGF0cmlidXRvIG1lZGlhIHBhcmEgYnVzY2FyIGxhIGhvamEgZGUgZXN0aWxvIGFzb2NpYWRhIGEgdW4gZG9jdW1lbnRvLildIn0sCi0gIHsgICJvcHRpb25GTEFWT1IiLCAgIiAgIFstRkxBVk9SIGZsYXZvck5hbWUgKFV0aWxpemFyIGV4cGxcdTAwRURjaXRhbWVudGUgczJzPVNBWCBvIGQyZD1ET00gcGFyYSByZWFsaXphciBsYSB0cmFuc2Zvcm1hY2lcdTAwRjNuLildICJ9LCAvLyBBZGRlZCBieSBzYm9hZy9zY3VyY3VydTsgZXhwZXJpbWVudGFsCi0gIHsgIm9wdGlvbkRJQUciLCAiICAgWy1ESUFHIChJbXByaW1pciB0aWVtcG8gdG90YWwgZW4gbWlsaXNlZ3VuZG9zIHBhcmEgbGEgdHJhbnNmb3JtYWNpXHUwMEYzbi4pXSJ9LAotICB7ICJvcHRpb25JTkNSRU1FTlRBTCIsICAiICAgWy1JTkNSRU1FTlRBTCAocGFyYSBzb2xpY2l0YXIgbGEgY29uc3RydWNjaVx1MDBGM24gRFRNIGluY3JlbWVudGFsLCBkZWZpbmEgaHR0cDovL3htbC5hcGFjaGUub3JnL3hhbGFuL2ZlYXR1cmVzL2luY3JlbWVudGFsIGVuIHRydWUuKV0ifSwKLSAgeyAgIm9wdGlvbk5PT1BUSU1JTUlaRSIsICAiICAgWy1OT09QVElNSU1JWkUgKHBhcmEgc29saWNpdGFyIHF1ZSBubyBzZSBwcm9kdXpjYSBuaW5nXHUwMEZBbiBwcm9jZXNhbWllbnRvIGRlIG9wdGltaXphY2lcdTAwRjNuIGRlIGhvamEgZGUgZXN0aWxvLCBkZWZpbmEgaHR0cDovL3htbC5hcGFjaGUub3JnL3hhbGFuL2ZlYXR1cmVzL29wdGltaXplIGVuIGZhbHNlLildIn0sCi0gIHsgIm9wdGlvblJMIiwgICIgICBbLVJMIHJlY3Vyc2lvbmxpbWl0IChhZmlybWFyIGxcdTAwRURtaXRlIG51bVx1MDBFOXJpY28gZW4gbGEgcHJvZnVuZGlkYWQgZGUgcmVjdXJzaVx1MDBGM24gZGUgbGEgaG9qYSBkZSBlc3RpbG8uKV0ifSwKLSAgeyAgICJvcHRpb25YTyIsICAiICAgWy1YTyBbdHJhbnNsZXROYW1lXSAoYXNpZ25hciBlbCBub21icmUgYWwgdHJhbnNsZXQgZ2VuZXJhZG8pXSJ9LAotICB7ICAib3B0aW9uWEQiLCAiICAgWy1YRCBkZXN0aW5hdGlvbkRpcmVjdG9yeSAoZXNwZWNpZmljYXIgdW4gZGlyZWN0b3JpbyBkZSBkZXN0aW5vIHBhcmEgdHJhbnNsZXQpXSJ9LAotICB7ICAib3B0aW9uWEoiLCAgIiAgIFstWEogamFyZmlsZSAoZW1wYXF1ZXRhIGxhcyBjbGFzZXMgZGUgdHJhbnNsZXQgZW4gdW4gYXJjaGl2byBqYXIgbGxhbWFkbyA8YXJjaGl2byBqYXI+KV0ifSwKLSAgeyAgICJvcHRpb25YUCIsICAiICAgWy1YUCBwYWNrYWdlIChlc3BlY2lmaWNhIHVuIHByZWZpam8gZGUgbm9tYnJlIGRlIHBhcXVldGUgcGFyYSB0b2RhcyBsYXMgY2xhc2VzIGRlIHRyYW5zbGV0IGdlbmVyYWRhcyldIn0sCi0KLSAgLy9BZGRJVElPTkFMICBTVFJJTkdTIHRoYXQgbmVlZCBMMTBuCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgZGVzY3JpYmVzIHVzYWdlIG9mIGEgcGFydGljdWxhcgotICAvLyBjb21tYW5kLWxpbmUgb3B0aW9uIHRoYXQgaXMgdXNlZCB0byBlbmFibGUgdGhlICJ0ZW1wbGF0ZSBpbmxpbmluZyIKLSAgLy8gb3B0aW1pemF0aW9uLiAgVGhlIG9wdGltaXphdGlvbiBpbnZvbHZlcyBtYWtpbmcgYSBjb3B5IG9mIHRoZSBjb2RlCi0gIC8vIGdlbmVyYXRlZCBmb3IgYSB0ZW1wbGF0ZSBpbiBhbm90aGVyIHRlbXBsYXRlIHRoYXQgcmVmZXJzIHRvIGl0LgotICB7ICJvcHRpb25YTiIsICAiICAgWy1YTiAocGVybWl0ZSBwb25lciBlbiBsXHUwMEVEbmVhIGxhIHBsYW50aWxsYSldIiB9LAotICB7ICJvcHRpb25YWCIsICAiICAgWy1YWCAoYWN0aXZhIHVuYSBzYWxpZGEgZGUgbWVuc2FqZSBkZSBkZXB1cmFjaVx1MDBGM24gYWRpY2lvbmFsKV0ifSwKLSAgeyAib3B0aW9uWFQiICwgIiAgIFstWFQgKHV0aWxpemFyIHRyYW5zbGV0IHBhcmEgbGEgdHJhbnNmb3JtYWNpXHUwMEYzbiBzaSBlcyBwb3NpYmxlKV0ifSwKLSAgeyAiZGlhZ1RpbWluZyIsIiAtLS0tLS0tLS0gTGEgdHJhbnNmb3JtYWNpXHUwMEYzbiBkZSB7MH0gbWVkaWFudGUgezF9IGhhIHRhcmRhZG8gezJ9IG1zIiB9LAotICB7ICJyZWN1cnNpb25Ub29EZWVwIiwiRWwgYW5pZGFtaWVudG8gZGUgcGxhbnRpbGxhIGVzIGRlbWFzaWFkbyBwcm9mdW5kby4gQW5pZGFtaWVudG8gPSB7MH0sIHBsYW50aWxsYSB7MX0gezJ9IiB9LAotICB7ICJuYW1lSXMiLCAiZWwgbm9tYnJlIGVzIiB9LAotICB7ICJtYXRjaFBhdHRlcm5JcyIsICJlbCBwYXRyXHUwMEYzbiBkZSBjb2luY2lkZW5jaWEgZXMiIH0KLQotICB9OwotCi0gIH0KLSAgLy8gPT09PT09PT09PT09PT09PT0gSU5GUkFTVFJVQ1RVUkUgPT09PT09PT09PT09PT09PT09PT09PQotCi0gIC8qKiBTdHJpbmcgZm9yIHVzZSB3aGVuIGEgYmFkIGVycm9yIGNvZGUgd2FzIGVuY291bnRlcmVkLiAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBCQURfQ09ERSA9ICJCQURfQ09ERSI7Ci0KLSAgLyoqIFN0cmluZyBmb3IgdXNlIHdoZW4gZm9ybWF0dGluZyBvZiB0aGUgZXJyb3Igc3RyaW5nIGZhaWxlZC4gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBGT1JNQVRfRkFJTEVEID0gIkZPUk1BVF9GQUlMRUQiOwotCi0gIC8qKiBHZW5lcmFsIGVycm9yIHN0cmluZy4gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJPUl9TVFJJTkcgPSAiI2Vycm9yIjsKLQotICAvKiogU3RyaW5nIHRvIHByZXBlbmQgdG8gZXJyb3IgbWVzc2FnZXMuICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJPUl9IRUFERVIgPSAiRXJyb3I6ICI7Ci0KLSAgLyoqIFN0cmluZyB0byBwcmVwZW5kIHRvIHdhcm5pbmcgbWVzc2FnZXMuICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdBUk5JTkdfSEVBREVSID0gIldhcm5pbmc6ICI7Ci0KLSAgLyoqIFN0cmluZyB0byBzcGVjaWZ5IHRoZSBYU0xUIG1vZHVsZS4gICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFhTTF9IRUFERVIgPSAiWFNMVCAiOwotCi0gIC8qKiBTdHJpbmcgdG8gc3BlY2lmeSB0aGUgWE1MIHBhcnNlciBtb2R1bGUuICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxfSEVBREVSID0gIlhNTCAiOwotCi0gIC8qKiBJIGRvbid0IHRoaW5rIHRoaXMgaXMgdXNlZCBhbnkgbW9yZS4KLSAgICogQGRlcHJlY2F0ZWQgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFFVRVJZX0hFQURFUiA9ICJQQVRURVJOICI7Ci0KLQotICAgIH0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwvcmVzL1hTTFRFcnJvclJlc291cmNlc19mci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC9yZXMvWFNMVEVycm9yUmVzb3VyY2VzX2ZyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDJmZmJiYmEuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC9yZXMvWFNMVEVycm9yUmVzb3VyY2VzX2ZyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNDQ3ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnJlczsKLQotaW1wb3J0IGphdmEudXRpbC5MaXN0UmVzb3VyY2VCdW5kbGU7Ci1pbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKLWltcG9ydCBqYXZhLnV0aWwuTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uOwotaW1wb3J0IGphdmEudXRpbC5SZXNvdXJjZUJ1bmRsZTsKLQotLyoqCi0gKiBTZXQgdXAgZXJyb3IgbWVzc2FnZXMuCi0gKiBXZSBidWlsZCBhIHR3byBkaW1lbnNpb25hbCBhcnJheSBvZiBtZXNzYWdlIGtleXMgYW5kCi0gKiBtZXNzYWdlIHN0cmluZ3MuIEluIG9yZGVyIHRvIGFkZCBhIG5ldyBtZXNzYWdlIGhlcmUsCi0gKiB5b3UgbmVlZCB0byBmaXJzdCBhZGQgYSBTdHJpbmcgY29uc3RhbnQuIEFuZAotICogIHlvdSBuZWVkIHRvIGVudGVyIGtleSAsIHZhbHVlIHBhaXIgYXMgcGFydCBvZiBjb250ZW50cwotICogQXJyYXkuIFlvdSBhbHNvIG5lZWQgdG8gdXBkYXRlIE1BWF9DT0RFIGZvciBlcnJvciBzdHJpbmdzCi0gKiBhbmQgTUFYX1dBUk5JTkcgZm9yIHdhcm5pbmdzICggTmVlZGVkIGZvciBvbmx5IGluZm9ybWF0aW9uCi0gKiBwdXJwb3NlICkKLSAqLwotcHVibGljIGNsYXNzIFhTTFRFcnJvclJlc291cmNlc19mciBleHRlbmRzIExpc3RSZXNvdXJjZUJ1bmRsZQotewotCi0vKgotICogVGhpcyBmaWxlIGNvbnRhaW5zIGVycm9yIGFuZCB3YXJuaW5nIG1lc3NhZ2VzIHJlbGF0ZWQgdG8gWGFsYW4gRXJyb3IKLSAqIEhhbmRsaW5nLgotICoKLSAqICBHZW5lcmFsIG5vdGVzIHRvIHRyYW5zbGF0b3JzOgotICoKLSAqICAxKSBYYWxhbiAob3IgbW9yZSBwcm9wZXJseSwgWGFsYW4taW50ZXJwcmV0aXZlKSBhbmQgWFNMVEMgYXJlIG5hbWVzIG9mCi0gKiAgICAgY29tcG9uZW50cy4KLSAqICAgICBYU0xUIGlzIGFuIGFjcm9ueW0gZm9yICJYTUwgU3R5bGVzaGVldCBMYW5ndWFnZTogVHJhbnNmb3JtYXRpb25zIi4KLSAqICAgICBYU0xUQyBpcyBhbiBhY3JvbnltIGZvciBYU0xUIENvbXBpbGVyLgotICoKLSAqICAyKSBBIHN0eWxlc2hlZXQgaXMgYSBkZXNjcmlwdGlvbiBvZiBob3cgdG8gdHJhbnNmb3JtIGFuIGlucHV0IFhNTCBkb2N1bWVudAotICogICAgIGludG8gYSByZXN1bHRhbnQgWE1MIGRvY3VtZW50IChvciBIVE1MIGRvY3VtZW50IG9yIHRleHQpLiAgVGhlCi0gKiAgICAgc3R5bGVzaGVldCBpdHNlbGYgaXMgZGVzY3JpYmVkIGluIHRoZSBmb3JtIG9mIGFuIFhNTCBkb2N1bWVudC4KLSAqCi0gKiAgMykgQSB0ZW1wbGF0ZSBpcyBhIGNvbXBvbmVudCBvZiBhIHN0eWxlc2hlZXQgdGhhdCBpcyB1c2VkIHRvIG1hdGNoIGEKLSAqICAgICBwYXJ0aWN1bGFyIHBvcnRpb24gb2YgYW4gaW5wdXQgZG9jdW1lbnQgYW5kIHNwZWNpZmllcyB0aGUgZm9ybSBvZiB0aGUKLSAqICAgICBjb3JyZXNwb25kaW5nIHBvcnRpb24gb2YgdGhlIG91dHB1dCBkb2N1bWVudC4KLSAqCi0gKiAgNCkgQW4gZWxlbWVudCBpcyBhIG1hcmstdXAgdGFnIGluIGFuIFhNTCBkb2N1bWVudDsgYW4gYXR0cmlidXRlIGlzIGEKLSAqICAgICBtb2RpZmllciBvbiB0aGUgdGFnLiAgRm9yIGV4YW1wbGUsIGluIDxlbGVtIGF0dHI9J3ZhbCcgYXR0cjI9J3ZhbDInPgotICogICAgICJlbGVtIiBpcyBhbiBlbGVtZW50IG5hbWUsICJhdHRyIiBhbmQgImF0dHIyIiBhcmUgYXR0cmlidXRlIG5hbWVzIHdpdGgKLSAqICAgICB0aGUgdmFsdWVzICJ2YWwiIGFuZCAidmFsMiIsIHJlc3BlY3RpdmVseS4KLSAqCi0gKiAgNSkgQSBuYW1lc3BhY2UgZGVjbGFyYXRpb24gaXMgYSBzcGVjaWFsIGF0dHJpYnV0ZSB0aGF0IGlzIHVzZWQgdG8gYXNzb2NpYXRlCi0gKiAgICAgYSBwcmVmaXggd2l0aCBhIFVSSSAodGhlIG5hbWVzcGFjZSkuICBUaGUgbWVhbmluZ3Mgb2YgZWxlbWVudCBuYW1lcyBhbmQKLSAqICAgICBhdHRyaWJ1dGUgbmFtZXMgdGhhdCB1c2UgdGhhdCBwcmVmaXggYXJlIGRlZmluZWQgd2l0aCByZXNwZWN0IHRvIHRoYXQKLSAqICAgICBuYW1lc3BhY2UuCi0gKgotICogIDYpICJUcmFuc2xldCIgaXMgYW4gaW52ZW50ZWQgdGVybSB0aGF0IGRlc2NyaWJlcyB0aGUgY2xhc3MgZmlsZSB0aGF0Ci0gKiAgICAgcmVzdWx0cyBmcm9tIGNvbXBpbGluZyBhbiBYTUwgc3R5bGVzaGVldCBpbnRvIGEgSmF2YSBjbGFzcy4KLSAqCi0gKiAgNykgWFBhdGggaXMgYSBzcGVjaWZpY2F0aW9uIHRoYXQgZGVzY3JpYmVzIGEgbm90YXRpb24gZm9yIGlkZW50aWZ5aW5nCi0gKiAgICAgbm9kZXMgaW4gYSB0cmVlLXN0cnVjdHVyZWQgcmVwcmVzZW50YXRpb24gb2YgYW4gWE1MIGRvY3VtZW50LiAgQW4KLSAqICAgICBpbnN0YW5jZSBvZiB0aGF0IG5vdGF0aW9uIGlzIHJlZmVycmVkIHRvIGFzIGFuIFhQYXRoIGV4cHJlc3Npb24uCi0gKgotICovCi0KLSAgLyoKLSAgICogU3RhdGljIHZhcmlhYmxlcwotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9OQU1FU1BBQ0VfVVJJX1ZBTFVFX0ZPUl9SRVNVTFRfUFJFRklYID0KLSAgICAgICAgIkVSX0lOVkFMSURfU0VUX05BTUVTUEFDRV9VUklfVkFMVUVfRk9SX1JFU1VMVF9QUkVGSVgiOwotCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfTkFNRVNQQUNFX1VSSV9WQUxVRV9GT1JfUkVTVUxUX1BSRUZJWF9GT1JfREVGQVVMVCA9Ci0gICAgICAgICJFUl9JTlZBTElEX05BTUVTUEFDRV9VUklfVkFMVUVfRk9SX1JFU1VMVF9QUkVGSVhfRk9SX0RFRkFVTFQiOwotCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX0NVUkxZQlJBQ0UgPSAiRVJfTk9fQ1VSTFlCUkFDRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQgPSAiRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lMTEVHQUxfQVRUUklCVVRFID0gIkVSX0lMTEVHQUxfQVRUUklCVVRFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTlVMTF9TT1VSQ0VOT0RFX0FQUExZSU1QT1JUUyA9ICJFUl9OVUxMX1NPVVJDRU5PREVfQVBQTFlJTVBPUlRTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX0FERCA9ICJFUl9DQU5OT1RfQUREIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTlVMTF9TT1VSQ0VOT0RFX0hBTkRMRUFQUExZVEVNUExBVEVTPSJFUl9OVUxMX1NPVVJDRU5PREVfSEFORExFQVBQTFlURU1QTEFURVMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19OQU1FX0FUVFJJQiA9ICJFUl9OT19OQU1FX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1RFTVBMQVRFX05PVF9GT1VORCA9ICJFUl9URU1QTEFURV9OT1RfRk9VTkQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX1JFU09MVkVfTkFNRV9BVlQgPSAiRVJfQ0FOVF9SRVNPTFZFX05BTUVfQVZUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUkVRVUlSRVNfQVRUUklCID0gIkVSX1JFUVVJUkVTX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01VU1RfSEFWRV9URVNUX0FUVFJJQiA9ICJFUl9NVVNUX0hBVkVfVEVTVF9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9CQURfVkFMX09OX0xFVkVMX0FUVFJJQiA9Ci0gICAgICAgICAiRVJfQkFEX1ZBTF9PTl9MRVZFTF9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUk9DRVNTSU5HSU5TVFJVQ1RJT05fTkFNRV9DQU5UX0JFX1hNTCA9Ci0gICAgICAgICAiRVJfUFJPQ0VTU0lOR0lOU1RSVUNUSU9OX05BTUVfQ0FOVF9CRV9YTUwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUk9DRVNTSU5HSU5TVFJVQ1RJT05fTk9UVkFMSURfTkNOQU1FID0KLSAgICAgICAgICJFUl9QUk9DRVNTSU5HSU5TVFJVQ1RJT05fTk9UVkFMSURfTkNOQU1FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTkVFRF9NQVRDSF9BVFRSSUIgPSAiRVJfTkVFRF9NQVRDSF9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9ORUVEX05BTUVfT1JfTUFUQ0hfQVRUUklCID0KLSAgICAgICAgICJFUl9ORUVEX05BTUVfT1JfTUFUQ0hfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9SRVNPTFZFX05TUFJFRklYID0KLSAgICAgICAgICJFUl9DQU5UX1JFU09MVkVfTlNQUkVGSVgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTExFR0FMX1ZBTFVFID0gIkVSX0lMTEVHQUxfVkFMVUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19PV05FUkRPQyA9ICJFUl9OT19PV05FUkRPQyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VMRU1URU1QTEFURUVMRU1fRVJSID0iRVJfRUxFTVRFTVBMQVRFRUxFTV9FUlIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OVUxMX0NISUxEID0gIkVSX05VTExfQ0hJTEQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9ORUVEX1NFTEVDVF9BVFRSSUIgPSAiRVJfTkVFRF9TRUxFQ1RfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTkVFRF9URVNUX0FUVFJJQiA9ICJFUl9ORUVEX1RFU1RfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTkVFRF9OQU1FX0FUVFJJQiA9ICJFUl9ORUVEX05BTUVfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fQ09OVEVYVF9PV05FUkRPQyA9ICJFUl9OT19DT05URVhUX09XTkVSRE9DIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTERfTk9UX0NSRUFURV9YTUxfUFJPQ19MSUFJU09OID0KLSAgICAgICAgICJFUl9DT1VMRF9OT1RfQ1JFQVRFX1hNTF9QUk9DX0xJQUlTT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUk9DRVNTX05PVF9TVUNDRVNTRlVMID0KLSAgICAgICAgICJFUl9QUk9DRVNTX05PVF9TVUNDRVNTRlVMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9UX1NVQ0NFU1NGVUwgPSAiRVJfTk9UX1NVQ0NFU1NGVUwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FTkNPRElOR19OT1RfU1VQUE9SVEVEID0KLSAgICAgICAgICJFUl9FTkNPRElOR19OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTERfTk9UX0NSRUFURV9UUkFDRUxJU1RFTkVSID0KLSAgICAgICAgICJFUl9DT1VMRF9OT1RfQ1JFQVRFX1RSQUNFTElTVEVORVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9LRVlfUkVRVUlSRVNfTkFNRV9BVFRSSUIgPQotICAgICAgICAgIkVSX0tFWV9SRVFVSVJFU19OQU1FX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0tFWV9SRVFVSVJFU19NQVRDSF9BVFRSSUIgPQotICAgICAgICAgIkVSX0tFWV9SRVFVSVJFU19NQVRDSF9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9LRVlfUkVRVUlSRVNfVVNFX0FUVFJJQiA9Ci0gICAgICAgICAiRVJfS0VZX1JFUVVJUkVTX1VTRV9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SRVFVSVJFU19FTEVNRU5UU19BVFRSSUIgPQotICAgICAgICAgIkVSX1JFUVVJUkVTX0VMRU1FTlRTX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01JU1NJTkdfUFJFRklYX0FUVFJJQiA9Ci0gICAgICAgICAiRVJfTUlTU0lOR19QUkVGSVhfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQkFEX1NUWUxFU0hFRVRfVVJMID0gIkVSX0JBRF9TVFlMRVNIRUVUX1VSTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZJTEVfTk9UX0ZPVU5EID0gIkVSX0ZJTEVfTk9UX0ZPVU5EIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU9FWENFUFRJT04gPSAiRVJfSU9FWENFUFRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19IUkVGX0FUVFJJQiA9ICJFUl9OT19IUkVGX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NUWUxFU0hFRVRfSU5DTFVERVNfSVRTRUxGID0KLSAgICAgICAgICJFUl9TVFlMRVNIRUVUX0lOQ0xVREVTX0lUU0VMRiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BST0NFU1NJTkNMVURFX0VSUk9SID0iRVJfUFJPQ0VTU0lOQ0xVREVfRVJST1IiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9NSVNTSU5HX0xBTkdfQVRUUklCID0gIkVSX01JU1NJTkdfTEFOR19BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9NSVNTSU5HX0NPTlRBSU5FUl9FTEVNRU5UX0NPTVBPTkVOVCA9Ci0gICAgICAgICAiRVJfTUlTU0lOR19DT05UQUlORVJfRUxFTUVOVF9DT01QT05FTlQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5fT05MWV9PVVRQVVRfVE9fRUxFTUVOVCA9Ci0gICAgICAgICAiRVJfQ0FOX09OTFlfT1VUUFVUX1RPX0VMRU1FTlQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUk9DRVNTX0VSUk9SID0gIkVSX1BST0NFU1NfRVJST1IiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTklNUExOT0RFX0VSUk9SID0gIkVSX1VOSU1QTE5PREVfRVJST1IiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19TRUxFQ1RfRVhQUkVTU0lPTiA9IkVSX05PX1NFTEVDVF9FWFBSRVNTSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX1NFUklBTElaRV9YU0xQUk9DRVNTT1IgPQotICAgICAgICAgIkVSX0NBTk5PVF9TRVJJQUxJWkVfWFNMUFJPQ0VTU09SIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fSU5QVVRfU1RZTEVTSEVFVCA9ICJFUl9OT19JTlBVVF9TVFlMRVNIRUVUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRkFJTEVEX1BST0NFU1NfU1RZTEVTSEVFVCA9Ci0gICAgICAgICAiRVJfRkFJTEVEX1BST0NFU1NfU1RZTEVTSEVFVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxETlRfUEFSU0VfRE9DID0gIkVSX0NPVUxETlRfUEFSU0VfRE9DIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTEROVF9GSU5EX0ZSQUdNRU5UID0KLSAgICAgICAgICJFUl9DT1VMRE5UX0ZJTkRfRlJBR01FTlQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT0RFX05PVF9FTEVNRU5UID0gIkVSX05PREVfTk9UX0VMRU1FTlQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GT1JFQUNIX05FRURfTUFUQ0hfT1JfTkFNRV9BVFRSSUIgPQotICAgICAgICAgIkVSX0ZPUkVBQ0hfTkVFRF9NQVRDSF9PUl9OQU1FX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1RFTVBMQVRFU19ORUVEX01BVENIX09SX05BTUVfQVRUUklCID0KLSAgICAgICAgICJFUl9URU1QTEFURVNfTkVFRF9NQVRDSF9PUl9OQU1FX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX0NMT05FX09GX0RPQ1VNRU5UX0ZSQUcgPQotICAgICAgICAgIkVSX05PX0NMT05FX09GX0RPQ1VNRU5UX0ZSQUciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX0NSRUFURV9JVEVNID0gIkVSX0NBTlRfQ1JFQVRFX0lURU0iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YTUxTUEFDRV9JTExFR0FMX1ZBTFVFID0KLSAgICAgICAgICJFUl9YTUxTUEFDRV9JTExFR0FMX1ZBTFVFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fWFNMS0VZX0RFQ0xBUkFUSU9OID0KLSAgICAgICAgICJFUl9OT19YU0xLRVlfREVDTEFSQVRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX0NSRUFURV9VUkwgPSAiRVJfQ0FOVF9DUkVBVEVfVVJMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWFNMRlVOQ1RJT05TX1VOU1VQUE9SVEVEID0KLSAgICAgICAgICJFUl9YU0xGVU5DVElPTlNfVU5TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUk9DRVNTT1JfRVJST1IgPSAiRVJfUFJPQ0VTU09SX0VSUk9SIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9UX0FMTE9XRURfSU5TSURFX1NUWUxFU0hFRVQgPQotICAgICAgICAgIkVSX05PVF9BTExPV0VEX0lOU0lERV9TVFlMRVNIRUVUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUkVTVUxUTlNfTk9UX1NVUFBPUlRFRCA9Ci0gICAgICAgICAiRVJfUkVTVUxUTlNfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0RFRkFVTFRTUEFDRV9OT1RfU1VQUE9SVEVEID0KLSAgICAgICAgICJFUl9ERUZBVUxUU1BBQ0VfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOREVOVFJFU1VMVF9OT1RfU1VQUE9SVEVEID0KLSAgICAgICAgICJFUl9JTkRFTlRSRVNVTFRfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lMTEVHQUxfQVRUUklCID0gIkVSX0lMTEVHQUxfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5LTk9XTl9YU0xfRUxFTSA9ICJFUl9VTktOT1dOX1hTTF9FTEVNIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQkFEX1hTTFNPUlRfVVNFID0gIkVSX0JBRF9YU0xTT1JUX1VTRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01JU1BMQUNFRF9YU0xXSEVOID0gIkVSX01JU1BMQUNFRF9YU0xXSEVOIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWFNMV0hFTl9OT1RfUEFSRU5URURfQllfWFNMQ0hPT1NFID0KLSAgICAgICAgICJFUl9YU0xXSEVOX05PVF9QQVJFTlRFRF9CWV9YU0xDSE9PU0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9NSVNQTEFDRURfWFNMT1RIRVJXSVNFID0KLSAgICAgICAgICJFUl9NSVNQTEFDRURfWFNMT1RIRVJXSVNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWFNMT1RIRVJXSVNFX05PVF9QQVJFTlRFRF9CWV9YU0xDSE9PU0UgPQotICAgICAgICAgIkVSX1hTTE9USEVSV0lTRV9OT1RfUEFSRU5URURfQllfWFNMQ0hPT1NFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9UX0FMTE9XRURfSU5TSURFX1RFTVBMQVRFID0KLSAgICAgICAgICJFUl9OT1RfQUxMT1dFRF9JTlNJREVfVEVNUExBVEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTktOT1dOX0VYVF9OU19QUkVGSVggPQotICAgICAgICAgIkVSX1VOS05PV05fRVhUX05TX1BSRUZJWCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lNUE9SVFNfQVNfRklSU1RfRUxFTSA9Ci0gICAgICAgICAiRVJfSU1QT1JUU19BU19GSVJTVF9FTEVNIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU1QT1JUSU5HX0lUU0VMRiA9ICJFUl9JTVBPUlRJTkdfSVRTRUxGIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWE1MU1BBQ0VfSUxMRUdBTF9WQUwgPSJFUl9YTUxTUEFDRV9JTExFR0FMX1ZBTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BST0NFU1NTVFlMRVNIRUVUX05PVF9TVUNDRVNTRlVMID0KLSAgICAgICAgICJFUl9QUk9DRVNTU1RZTEVTSEVFVF9OT1RfU1VDQ0VTU0ZVTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NBWF9FWENFUFRJT04gPSAiRVJfU0FYX0VYQ0VQVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hTTFRfRVJST1IgPSAiRVJfWFNMVF9FUlJPUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NVUlJFTkNZX1NJR05fSUxMRUdBTD0KLSAgICAgICAgICJFUl9DVVJSRU5DWV9TSUdOX0lMTEVHQUwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9ET0NVTUVOVF9GVU5DVElPTl9JTlZBTElEX0lOX1NUWUxFU0hFRVRfRE9NID0KLSAgICAgICAgICJFUl9ET0NVTUVOVF9GVU5DVElPTl9JTlZBTElEX0lOX1NUWUxFU0hFRVRfRE9NIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9SRVNPTFZFX1BSRUZJWF9PRl9OT05fUFJFRklYX1JFU09MVkVSID0KLSAgICAgICAgICJFUl9DQU5UX1JFU09MVkVfUFJFRklYX09GX05PTl9QUkVGSVhfUkVTT0xWRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SRURJUkVDVF9DT1VMRE5UX0dFVF9GSUxFTkFNRSA9Ci0gICAgICAgICAiRVJfUkVESVJFQ1RfQ09VTEROVF9HRVRfRklMRU5BTUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfQlVJTERfRk9STUFUVEVSTElTVEVORVJfSU5fUkVESVJFQ1QgPQotICAgICAgICAgIkVSX0NBTk5PVF9CVUlMRF9GT1JNQVRURVJMSVNURU5FUl9JTl9SRURJUkVDVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfUFJFRklYX0lOX0VYQ0xVREVSRVNVTFRQUkVGSVggPQotICAgICAgICAgIkVSX0lOVkFMSURfUFJFRklYX0lOX0VYQ0xVREVSRVNVTFRQUkVGSVgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9NSVNTSU5HX05TX1VSSSA9ICJFUl9NSVNTSU5HX05TX1VSSSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01JU1NJTkdfQVJHX0ZPUl9PUFRJT04gPQotICAgICAgICAgIkVSX01JU1NJTkdfQVJHX0ZPUl9PUFRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX09QVElPTiA9ICJFUl9JTlZBTElEX09QVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01BTEZPUk1FRF9GT1JNQVRfU1RSSU5HID0KLSAgICAgICAgICJFUl9NQUxGT1JNRURfRk9STUFUX1NUUklORyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NUWUxFU0hFRVRfUkVRVUlSRVNfVkVSU0lPTl9BVFRSSUIgPQotICAgICAgICAgIkVSX1NUWUxFU0hFRVRfUkVRVUlSRVNfVkVSU0lPTl9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTExFR0FMX0FUVFJJQlVURV9WQUxVRSA9Ci0gICAgICAgICAiRVJfSUxMRUdBTF9BVFRSSUJVVEVfVkFMVUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DSE9PU0VfUkVRVUlSRVNfV0hFTiA9IkVSX0NIT09TRV9SRVFVSVJFU19XSEVOIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fQVBQTFlfSU1QT1JUX0lOX0ZPUl9FQUNIID0KLSAgICAgICAgICJFUl9OT19BUFBMWV9JTVBPUlRfSU5fRk9SX0VBQ0giOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX1VTRV9EVE1fRk9SX09VVFBVVCA9Ci0gICAgICAgICAiRVJfQ0FOVF9VU0VfRFRNX0ZPUl9PVVRQVVQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX1VTRV9EVE1fRk9SX0lOUFVUID0KLSAgICAgICAgICJFUl9DQU5UX1VTRV9EVE1fRk9SX0lOUFVUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FMTF9UT19FWFRfRkFJTEVEID0gIkVSX0NBTExfVE9fRVhUX0ZBSUxFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BSRUZJWF9NVVNUX1JFU09MVkUgPSAiRVJfUFJFRklYX01VU1RfUkVTT0xWRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfVVRGMTZfU1VSUk9HQVRFID0KLSAgICAgICAgICJFUl9JTlZBTElEX1VURjE2X1NVUlJPR0FURSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hTTEFUVFJTRVRfVVNFRF9JVFNFTEYgPQotICAgICAgICAgIkVSX1hTTEFUVFJTRVRfVVNFRF9JVFNFTEYiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfTUlYX1hFUkNFU0RPTSA9IkVSX0NBTk5PVF9NSVhfWEVSQ0VTRE9NIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVE9PX01BTllfTElTVEVORVJTID0gIkVSX1RPT19NQU5ZX0xJU1RFTkVSUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOX0VMRU1URU1QTEFURUVMRU1fUkVBRE9CSkVDVCA9Ci0gICAgICAgICAiRVJfSU5fRUxFTVRFTVBMQVRFRUxFTV9SRUFET0JKRUNUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRFVQTElDQVRFX05BTUVEX1RFTVBMQVRFID0KLSAgICAgICAgICJFUl9EVVBMSUNBVEVfTkFNRURfVEVNUExBVEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX0tFWV9DQUxMID0gIkVSX0lOVkFMSURfS0VZX0NBTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SRUZFUkVOQ0lOR19JVFNFTEYgPSAiRVJfUkVGRVJFTkNJTkdfSVRTRUxGIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSUxMRUdBTF9ET01TT1VSQ0VfSU5QVVQgPQotICAgICAgICAgIkVSX0lMTEVHQUxfRE9NU09VUkNFX0lOUFVUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0xBU1NfTk9UX0ZPVU5EX0ZPUl9PUFRJT04gPQotICAgICAgICAgIkVSX0NMQVNTX05PVF9GT1VORF9GT1JfT1BUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUkVRVUlSRURfRUxFTV9OT1RfRk9VTkQgPQotICAgICAgICAgIkVSX1JFUVVJUkVEX0VMRU1fTk9UX0ZPVU5EIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5QVVRfQ0FOTk9UX0JFX05VTEwgPSJFUl9JTlBVVF9DQU5OT1RfQkVfTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1VSSV9DQU5OT1RfQkVfTlVMTCA9ICJFUl9VUklfQ0FOTk9UX0JFX05VTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GSUxFX0NBTk5PVF9CRV9OVUxMID0gIkVSX0ZJTEVfQ0FOTk9UX0JFX05VTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TT1VSQ0VfQ0FOTk9UX0JFX05VTEwgPQotICAgICAgICAgIkVSX1NPVVJDRV9DQU5OT1RfQkVfTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9JTklUX0JTRk1HUiA9ICJFUl9DQU5OT1RfSU5JVF9CU0ZNR1IiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfQ01QTF9FWFRFTlNOID0gIkVSX0NBTk5PVF9DTVBMX0VYVEVOU04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfQ1JFQVRFX0VYVEVOU04gPQotICAgICAgICAgIkVSX0NBTk5PVF9DUkVBVEVfRVhURU5TTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOU1RBTkNFX01USERfQ0FMTF9SRVFVSVJFUyA9Ci0gICAgICAgICAiRVJfSU5TVEFOQ0VfTVRIRF9DQUxMX1JFUVVJUkVTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9FTEVNRU5UX05BTUUgPSJFUl9JTlZBTElEX0VMRU1FTlRfTkFNRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VMRU1FTlRfTkFNRV9NRVRIT0RfU1RBVElDID0KLSAgICAgICAgICJFUl9FTEVNRU5UX05BTUVfTUVUSE9EX1NUQVRJQyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYVEVOU0lPTl9GVU5DX1VOS05PV04gPQotICAgICAgICAgIkVSX0VYVEVOU0lPTl9GVU5DX1VOS05PV04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9NT1JFX01BVENIX0NPTlNUUlVDVE9SID0KLSAgICAgICAgICJFUl9NT1JFX01BVENIX0NPTlNUUlVDVE9SIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTU9SRV9NQVRDSF9NRVRIT0QgPSAiRVJfTU9SRV9NQVRDSF9NRVRIT0QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9NT1JFX01BVENIX0VMRU1FTlQgPSAiRVJfTU9SRV9NQVRDSF9FTEVNRU5UIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9DT05URVhUX1BBU1NFRCA9Ci0gICAgICAgICAiRVJfSU5WQUxJRF9DT05URVhUX1BBU1NFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BPT0xfRVhJU1RTID0gIkVSX1BPT0xfRVhJU1RTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fRFJJVkVSX05BTUUgPSAiRVJfTk9fRFJJVkVSX05BTUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19VUkwgPSAiRVJfTk9fVVJMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUE9PTF9TSVpFX0xFU1NUSEFOX09ORSA9Ci0gICAgICAgICAiRVJfUE9PTF9TSVpFX0xFU1NUSEFOX09ORSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfRFJJVkVSID0gIkVSX0lOVkFMSURfRFJJVkVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fU1RZTEVTSEVFVFJPT1QgPSAiRVJfTk9fU1RZTEVTSEVFVFJPT1QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTExFR0FMX1hNTFNQQUNFX1ZBTFVFID0KLSAgICAgICAgICJFUl9JTExFR0FMX1hNTFNQQUNFX1ZBTFVFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJPQ0VTU0ZST01OT0RFX0ZBSUxFRCA9Ci0gICAgICAgICAiRVJfUFJPQ0VTU0ZST01OT0RFX0ZBSUxFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1JFU09VUkNFX0NPVUxEX05PVF9MT0FEID0KLSAgICAgICAgICJFUl9SRVNPVVJDRV9DT1VMRF9OT1RfTE9BRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0JVRkZFUl9TSVpFX0xFU1NUSEFOX1pFUk8gPQotICAgICAgICAgIkVSX0JVRkZFUl9TSVpFX0xFU1NUSEFOX1pFUk8iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTktOT1dOX0VSUk9SX0NBTExJTkdfRVhURU5TSU9OID0KLSAgICAgICAgICJFUl9VTktOT1dOX0VSUk9SX0NBTExJTkdfRVhURU5TSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fTkFNRVNQQUNFX0RFQ0wgPSAiRVJfTk9fTkFNRVNQQUNFX0RFQ0wiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FTEVNX0NPTlRFTlRfTk9UX0FMTE9XRUQgPQotICAgICAgICAgIkVSX0VMRU1fQ09OVEVOVF9OT1RfQUxMT1dFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NUWUxFU0hFRVRfRElSRUNURURfVEVSTUlOQVRJT04gPQotICAgICAgICAgIkVSX1NUWUxFU0hFRVRfRElSRUNURURfVEVSTUlOQVRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9PTkVfT1JfVFdPID0gIkVSX09ORV9PUl9UV08iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9UV09fT1JfVEhSRUUgPSAiRVJfVFdPX09SX1RIUkVFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTERfTk9UX0xPQURfUkVTT1VSQ0UgPQotICAgICAgICAgIkVSX0NPVUxEX05PVF9MT0FEX1JFU09VUkNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX0lOSVRfREVGQVVMVF9URU1QTEFURVMgPQotICAgICAgICAgIkVSX0NBTk5PVF9JTklUX0RFRkFVTFRfVEVNUExBVEVTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUkVTVUxUX05VTEwgPSAiRVJfUkVTVUxUX05VTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SRVNVTFRfQ09VTERfTk9UX0JFX1NFVCA9Ci0gICAgICAgICAiRVJfUkVTVUxUX0NPVUxEX05PVF9CRV9TRVQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19PVVRQVVRfU1BFQ0lGSUVEID0gIkVSX05PX09VVFBVVF9TUEVDSUZJRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfVFJBTlNGT1JNX1RPX1JFU1VMVF9UWVBFID0KLSAgICAgICAgICJFUl9DQU5OT1RfVFJBTlNGT1JNX1RPX1JFU1VMVF9UWVBFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX1RSQU5TRk9STV9TT1VSQ0VfVFlQRSA9Ci0gICAgICAgICAiRVJfQ0FOTk9UX1RSQU5TRk9STV9TT1VSQ0VfVFlQRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05VTExfQ09OVEVOVF9IQU5ETEVSID0iRVJfTlVMTF9DT05URU5UX0hBTkRMRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OVUxMX0VSUk9SX0hBTkRMRVIgPSAiRVJfTlVMTF9FUlJPUl9IQU5ETEVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX0NBTExfUEFSU0UgPSAiRVJfQ0FOTk9UX0NBTExfUEFSU0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19QQVJFTlRfRk9SX0ZJTFRFUiA9IkVSX05PX1BBUkVOVF9GT1JfRklMVEVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fU1RZTEVTSEVFVF9JTl9NRURJQSA9Ci0gICAgICAgICAiRVJfTk9fU1RZTEVTSEVFVF9JTl9NRURJQSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1NUWUxFU0hFRVRfUEkgPSAiRVJfTk9fU1RZTEVTSEVFVF9QSSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PVF9TVVBQT1JURUQgPSAiRVJfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BST1BFUlRZX1ZBTFVFX0JPT0xFQU4gPQotICAgICAgICAgIkVSX1BST1BFUlRZX1ZBTFVFX0JPT0xFQU4iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRF9OT1RfRklORF9FWFRFUk5fU0NSSVBUID0KLSAgICAgICAgICJFUl9DT1VMRF9OT1RfRklORF9FWFRFUk5fU0NSSVBUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUkVTT1VSQ0VfQ09VTERfTk9UX0ZJTkQgPQotICAgICAgICAgIkVSX1JFU09VUkNFX0NPVUxEX05PVF9GSU5EIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfT1VUUFVUX1BST1BFUlRZX05PVF9SRUNPR05JWkVEID0KLSAgICAgICAgICJFUl9PVVRQVVRfUFJPUEVSVFlfTk9UX1JFQ09HTklaRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GQUlMRURfQ1JFQVRJTkdfRUxFTUxJVFJTTFQgPQotICAgICAgICAgIkVSX0ZBSUxFRF9DUkVBVElOR19FTEVNTElUUlNMVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1ZBTFVFX1NIT1VMRF9CRV9OVU1CRVIgPQotICAgICAgICAgIkVSX1ZBTFVFX1NIT1VMRF9CRV9OVU1CRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9WQUxVRV9TSE9VTERfRVFVQUwgPSAiRVJfVkFMVUVfU0hPVUxEX0VRVUFMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRkFJTEVEX0NBTExJTkdfTUVUSE9EID0KLSAgICAgICAgICJFUl9GQUlMRURfQ0FMTElOR19NRVRIT0QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GQUlMRURfQ1JFQVRJTkdfRUxFTVRNUEwgPQotICAgICAgICAgIkVSX0ZBSUxFRF9DUkVBVElOR19FTEVNVE1QTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NIQVJTX05PVF9BTExPV0VEID0gIkVSX0NIQVJTX05PVF9BTExPV0VEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQVRUUl9OT1RfQUxMT1dFRCA9ICJFUl9BVFRSX05PVF9BTExPV0VEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQkFEX1ZBTFVFID0gIkVSX0JBRF9WQUxVRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FUVFJJQl9WQUxVRV9OT1RfRk9VTkQgPQotICAgICAgICAgIkVSX0FUVFJJQl9WQUxVRV9OT1RfRk9VTkQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9BVFRSSUJfVkFMVUVfTk9UX1JFQ09HTklaRUQgPQotICAgICAgICAgIkVSX0FUVFJJQl9WQUxVRV9OT1RfUkVDT0dOSVpFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05VTExfVVJJX05BTUVTUEFDRSA9ICJFUl9OVUxMX1VSSV9OQU1FU1BBQ0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OVU1CRVJfVE9PX0JJRyA9ICJFUl9OVU1CRVJfVE9PX0JJRyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nICBFUl9DQU5OT1RfRklORF9TQVgxX0RSSVZFUiA9Ci0gICAgICAgICAiRVJfQ0FOTk9UX0ZJTkRfU0FYMV9EUklWRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyAgRVJfU0FYMV9EUklWRVJfTk9UX0xPQURFRCA9Ci0gICAgICAgICAiRVJfU0FYMV9EUklWRVJfTk9UX0xPQURFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nICBFUl9TQVgxX0RSSVZFUl9OT1RfSU5TVEFOVElBVEVEID0KLSAgICAgICAgICJFUl9TQVgxX0RSSVZFUl9OT1RfSU5TVEFOVElBVEVEIiA7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NBWDFfRFJJVkVSX05PVF9JTVBMRU1FTlRfUEFSU0VSID0KLSAgICAgICAgICJFUl9TQVgxX0RSSVZFUl9OT1RfSU1QTEVNRU5UX1BBUlNFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nICBFUl9QQVJTRVJfUFJPUEVSVFlfTk9UX1NQRUNJRklFRCA9Ci0gICAgICAgICAiRVJfUEFSU0VSX1BST1BFUlRZX05PVF9TUEVDSUZJRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyAgRVJfUEFSU0VSX0FSR19DQU5OT1RfQkVfTlVMTCA9Ci0gICAgICAgICAiRVJfUEFSU0VSX0FSR19DQU5OT1RfQkVfTlVMTCIgOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyAgRVJfRkVBVFVSRSA9ICJFUl9GRUFUVVJFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJPUEVSVFkgPSAiRVJfUFJPUEVSVFkiIDsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTlVMTF9FTlRJVFlfUkVTT0xWRVIgPSJFUl9OVUxMX0VOVElUWV9SRVNPTFZFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nICBFUl9OVUxMX0RURF9IQU5ETEVSID0gIkVSX05VTExfRFREX0hBTkRMRVIiIDsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fRFJJVkVSX05BTUVfU1BFQ0lGSUVEID0KLSAgICAgICAgICJFUl9OT19EUklWRVJfTkFNRV9TUEVDSUZJRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19VUkxfU1BFQ0lGSUVEID0gIkVSX05PX1VSTF9TUEVDSUZJRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QT09MU0laRV9MRVNTX1RIQU5fT05FID0KLSAgICAgICAgICJFUl9QT09MU0laRV9MRVNTX1RIQU5fT05FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9EUklWRVJfTkFNRSA9ICJFUl9JTlZBTElEX0RSSVZFUl9OQU1FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVJST1JMSVNURU5FUiA9ICJFUl9FUlJPUkxJU1RFTkVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQVNTRVJUX05PX1RFTVBMQVRFX1BBUkVOVCA9Ci0gICAgICAgICAiRVJfQVNTRVJUX05PX1RFTVBMQVRFX1BBUkVOVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FTU0VSVF9SRURVTkRFTlRfRVhQUl9FTElNSU5BVE9SID0KLSAgICAgICAgICJFUl9BU1NFUlRfUkVEVU5ERU5UX0VYUFJfRUxJTUlOQVRPUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PVF9BTExPV0VEX0lOX1BPU0lUSU9OID0KLSAgICAgICAgICJFUl9OT1RfQUxMT1dFRF9JTl9QT1NJVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PTldISVRFU1BBQ0VfTk9UX0FMTE9XRURfSU5fUE9TSVRJT04gPQotICAgICAgICAgIkVSX05PTldISVRFU1BBQ0VfTk9UX0FMTE9XRURfSU5fUE9TSVRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OQU1FU1BBQ0VfQ09OVEVYVF9OVUxMX05BTUVTUEFDRSA9Ci0gICAgICAgICAiRVJfTkFNRVNQQUNFX0NPTlRFWFRfTlVMTF9OQU1FU1BBQ0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OQU1FU1BBQ0VfQ09OVEVYVF9OVUxMX1BSRUZJWCA9Ci0gICAgICAgICAiRVJfTkFNRVNQQUNFX0NPTlRFWFRfTlVMTF9QUkVGSVgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YUEFUSF9SRVNPTFZFUl9OVUxMX1FOQU1FID0KLSAgICAgICAgICJFUl9YUEFUSF9SRVNPTFZFUl9OVUxMX1FOQU1FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWFBBVEhfUkVTT0xWRVJfTkVHQVRJVkVfQVJJVFkgPQotICAgICAgICAgIkVSX1hQQVRIX1JFU09MVkVSX05FR0FUSVZFX0FSSVRZIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSU5WQUxJRF9UQ0hBUiA9ICJJTlZBTElEX1RDSEFSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSU5WQUxJRF9RTkFNRSA9ICJJTlZBTElEX1FOQU1FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSU5WQUxJRF9FTlVNID0gIklOVkFMSURfRU5VTSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIElOVkFMSURfTk1UT0tFTiA9ICJJTlZBTElEX05NVE9LRU4iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBJTlZBTElEX05DTkFNRSA9ICJJTlZBTElEX05DTkFNRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIElOVkFMSURfQk9PTEVBTiA9ICJJTlZBTElEX0JPT0xFQU4iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBJTlZBTElEX05VTUJFUiA9ICJJTlZBTElEX05VTUJFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FSR19MSVRFUkFMID0gIkVSX0FSR19MSVRFUkFMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRFVQTElDQVRFX0dMT0JBTF9WQVIgPSJFUl9EVVBMSUNBVEVfR0xPQkFMX1ZBUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0RVUExJQ0FURV9WQVIgPSAiRVJfRFVQTElDQVRFX1ZBUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1RFTVBMQVRFX05BTUVfTUFUQ0ggPSAiRVJfVEVNUExBVEVfTkFNRV9NQVRDSCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfUFJFRklYID0gIkVSX0lOVkFMSURfUFJFRklYIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fQVRUUklCX1NFVCA9ICJFUl9OT19BVFRSSUJfU0VUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRlVOQ1RJT05fTk9UX0ZPVU5EID0KLSAgICAgICAgICJFUl9GVU5DVElPTl9OT1RfRk9VTkQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX0hBVkVfQ09OVEVOVF9BTkRfU0VMRUNUID0KLSAgICAgIkVSX0NBTlRfSEFWRV9DT05URU5UX0FORF9TRUxFQ1QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX1NFVF9QQVJBTV9WQUxVRSA9ICJFUl9JTlZBTElEX1NFVF9QQVJBTV9WQUxVRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NFVF9GRUFUVVJFX05VTExfTkFNRSA9Ci0gICAgICAgICJFUl9TRVRfRkVBVFVSRV9OVUxMX05BTUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9HRVRfRkVBVFVSRV9OVUxMX05BTUUgPQotICAgICAgICAiRVJfR0VUX0ZFQVRVUkVfTlVMTF9OQU1FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5TVVBQT1JURURfRkVBVFVSRSA9Ci0gICAgICAgICJFUl9VTlNVUFBPUlRFRF9GRUFUVVJFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhURU5TSU9OX0VMRU1FTlRfTk9UX0FMTE9XRURfSU5fU0VDVVJFX1BST0NFU1NJTkcgPQotICAgICAgICAiRVJfRVhURU5TSU9OX0VMRU1FTlRfTk9UX0FMTE9XRURfSU5fU0VDVVJFX1BST0NFU1NJTkciOwotCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0ZPVU5EX0NVUkxZQlJBQ0UgPSAiV0dfRk9VTkRfQ1VSTFlCUkFDRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0NPVU5UX0FUVFJJQl9NQVRDSEVTX05PX0FOQ0VTVE9SID0KLSAgICAgICAgICJXR19DT1VOVF9BVFRSSUJfTUFUQ0hFU19OT19BTkNFU1RPUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0VYUFJfQVRUUklCX0NIQU5HRURfVE9fU0VMRUNUID0KLSAgICAgICAgICJXR19FWFBSX0FUVFJJQl9DSEFOR0VEX1RPX1NFTEVDVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX05PX0xPQ0FMRV9JTl9GT1JNQVROVU1CRVIgPQotICAgICAgICAgIldHX05PX0xPQ0FMRV9JTl9GT1JNQVROVU1CRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19MT0NBTEVfTk9UX0ZPVU5EID0gIldHX0xPQ0FMRV9OT1RfRk9VTkQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19DQU5OT1RfTUFLRV9VUkxfRlJPTSA9IldHX0NBTk5PVF9NQUtFX1VSTF9GUk9NIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfQ0FOTk9UX0xPQURfUkVRVUVTVEVEX0RPQyA9Ci0gICAgICAgICAiV0dfQ0FOTk9UX0xPQURfUkVRVUVTVEVEX0RPQyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0NBTk5PVF9GSU5EX0NPTExBVE9SID0iV0dfQ0FOTk9UX0ZJTkRfQ09MTEFUT1IiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19GVU5DVElPTlNfU0hPVUxEX1VTRV9VUkwgPQotICAgICAgICAgIldHX0ZVTkNUSU9OU19TSE9VTERfVVNFX1VSTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0VOQ09ESU5HX05PVF9TVVBQT1JURURfVVNJTkdfVVRGOCA9Ci0gICAgICAgICAiV0dfRU5DT0RJTkdfTk9UX1NVUFBPUlRFRF9VU0lOR19VVEY4IjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfRU5DT0RJTkdfTk9UX1NVUFBPUlRFRF9VU0lOR19KQVZBID0KLSAgICAgICAgICJXR19FTkNPRElOR19OT1RfU1VQUE9SVEVEX1VTSU5HX0pBVkEiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19TUEVDSUZJQ0lUWV9DT05GTElDVFMgPQotICAgICAgICAgIldHX1NQRUNJRklDSVRZX0NPTkZMSUNUUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX1BBUlNJTkdfQU5EX1BSRVBBUklORyA9Ci0gICAgICAgICAiV0dfUEFSU0lOR19BTkRfUFJFUEFSSU5HIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfQVRUUl9URU1QTEFURSA9ICJXR19BVFRSX1RFTVBMQVRFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfQ09ORkxJQ1RfQkVUV0VFTl9YU0xTVFJJUFNQQUNFX0FORF9YU0xQUkVTRVJWRVNQQUNFID0gIldHX0NPTkZMSUNUX0JFVFdFRU5fWFNMU1RSSVBTUEFDRV9BTkRfWFNMUFJFU0VSVkVTUCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0FUVFJJQl9OT1RfSEFORExFRCA9ICJXR19BVFRSSUJfTk9UX0hBTkRMRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19OT19ERUNJTUFMRk9STUFUX0RFQ0xBUkFUSU9OID0KLSAgICAgICAgICJXR19OT19ERUNJTUFMRk9STUFUX0RFQ0xBUkFUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfT0xEX1hTTFRfTlMgPSAiV0dfT0xEX1hTTFRfTlMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19PTkVfREVGQVVMVF9YU0xERUNJTUFMRk9STUFUX0FMTE9XRUQgPQotICAgICAgICAgIldHX09ORV9ERUZBVUxUX1hTTERFQ0lNQUxGT1JNQVRfQUxMT1dFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX1hTTERFQ0lNQUxGT1JNQVRfTkFNRVNfTVVTVF9CRV9VTklRVUUgPQotICAgICAgICAgIldHX1hTTERFQ0lNQUxGT1JNQVRfTkFNRVNfTVVTVF9CRV9VTklRVUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19JTExFR0FMX0FUVFJJQlVURSA9ICJXR19JTExFR0FMX0FUVFJJQlVURSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0NPVUxEX05PVF9SRVNPTFZFX1BSRUZJWCA9Ci0gICAgICAgICAiV0dfQ09VTERfTk9UX1JFU09MVkVfUFJFRklYIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfU1RZTEVTSEVFVF9SRVFVSVJFU19WRVJTSU9OX0FUVFJJQiA9Ci0gICAgICAgICAiV0dfU1RZTEVTSEVFVF9SRVFVSVJFU19WRVJTSU9OX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0lMTEVHQUxfQVRUUklCVVRFX05BTUUgPQotICAgICAgICAgIldHX0lMTEVHQUxfQVRUUklCVVRFX05BTUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19JTExFR0FMX0FUVFJJQlVURV9WQUxVRSA9Ci0gICAgICAgICAiV0dfSUxMRUdBTF9BVFRSSUJVVEVfVkFMVUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19FTVBUWV9TRUNPTkRfQVJHID0gIldHX0VNUFRZX1NFQ09ORF9BUkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19QUk9DRVNTSU5HSU5TVFJVQ1RJT05fTkFNRV9DQU5UX0JFX1hNTCA9Ci0gICAgICAgICAiV0dfUFJPQ0VTU0lOR0lOU1RSVUNUSU9OX05BTUVfQ0FOVF9CRV9YTUwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19QUk9DRVNTSU5HSU5TVFJVQ1RJT05fTk9UVkFMSURfTkNOQU1FID0KLSAgICAgICAgICJXR19QUk9DRVNTSU5HSU5TVFJVQ1RJT05fTk9UVkFMSURfTkNOQU1FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfSUxMRUdBTF9BVFRSSUJVVEVfUE9TSVRJT04gPQotICAgICAgICAgIldHX0lMTEVHQUxfQVRUUklCVVRFX1BPU0lUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSID0KLSAgICAgICAgICJOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIiOwotCi0gIC8qCi0gICAqIE5vdyBmaWxsIGluIHRoZSBtZXNzYWdlIHRleHQuCi0gICAqIFRoZW4gZmlsbCBpbiB0aGUgbWVzc2FnZSB0ZXh0IGZvciB0aGF0IG1lc3NhZ2UgY29kZSBpbiB0aGUKLSAgICogYXJyYXkuIFVzZSB0aGUgbmV3IGVycm9yIGNvZGUgYXMgdGhlIGluZGV4IGludG8gdGhlIGFycmF5LgotICAgKi8KLQotICAvLyBFcnJvciBtZXNzYWdlcy4uLgotCi0gIC8qKiBHZXQgdGhlIGxvb2t1cCB0YWJsZSBmb3IgZXJyb3IgbWVzc2FnZXMuCi0gICAgKgotICAgICogQHJldHVybiBUaGUgbWVzc2FnZSBsb29rdXAgdGFibGUuCi0gICAgKi8KLSAgcHVibGljIE9iamVjdFtdW10gZ2V0Q29udGVudHMoKQotICB7Ci0gICAgICByZXR1cm4gbmV3IE9iamVjdFtdW10gewotCi0gIC8qKiBFcnJvciBtZXNzYWdlIElEIHRoYXQgaGFzIGEgbnVsbCBtZXNzYWdlLCBidXQgdGFrZXMgaW4gYSBzaW5nbGUgb2JqZWN0LiAgICAqLwotICB7IkVSMDAwMCIgLCAiezB9IiB9LAotCi0gICAgeyBFUl9OT19DVVJMWUJSQUNFLAotICAgICAgIkVycmV1ciA6IGwnZXhwcmVzc2lvbiBuZSBwZXV0IHBhcyBjb250ZW5pciBsZSBjYXJhY3RcdTAwRThyZSAneycifSwKLQotICAgIHsgRVJfSUxMRUdBTF9BVFRSSUJVVEUgLAotICAgICAiezB9IGEgdW4gYXR0cmlidXQgbm9uIGFkbWlzIDogezF9In0sCi0KLSAge0VSX05VTExfU09VUkNFTk9ERV9BUFBMWUlNUE9SVFMgLAotICAgICAgIkxhIHZhbGV1ciBkZSBzb3VyY2VOb2RlIGVzdCBOVUxMIGRhbnMgeHNsOmFwcGx5LWltcG9ydHMuIn0sCi0KLSAge0VSX0NBTk5PVF9BREQsCi0gICAgICAiSW1wb3NzaWJsZSBkJydham91dGVyIHswfSBcdTAwRTAgezF9In0sCi0KLSAgICB7IEVSX05VTExfU09VUkNFTk9ERV9IQU5ETEVBUFBMWVRFTVBMQVRFUywKLSAgICAgICJMYSB2YWxldXIgZGUgc291cmNlTm9kZSBlc3QgTlVMTCBkYW5zIGhhbmRsZUFwcGx5VGVtcGxhdGVzSW5zdHJ1Y3Rpb24uIn0sCi0KLSAgICB7IEVSX05PX05BTUVfQVRUUklCLAotICAgICAiezB9IGRvaXQgYXZvaXIgdW4gYXR0cmlidXQgJyduYW1lJycuIn0sCi0KLSAgICB7RVJfVEVNUExBVEVfTk9UX0ZPVU5ELAotICAgICAiTW9kXHUwMEU4bGUgbm9tbVx1MDBFOSB7MH0gaW50cm91dmFibGUifSwKLQotICAgIHtFUl9DQU5UX1JFU09MVkVfTkFNRV9BVlQsCi0gICAgICAiSW1wb3NzaWJsZSBkZSByXHUwMEU5c291ZHJlIGxlIG5vbSBBVlQgZGFucyB4c2w6Y2FsbC10ZW1wbGF0ZS4ifSwKLQotICAgIHtFUl9SRVFVSVJFU19BVFRSSUIsCi0gICAgICJ7MH0gZXhpZ2UgbCcnYXR0cmlidXQgOiB7MX0ifSwKLQotICAgIHsgRVJfTVVTVF9IQVZFX1RFU1RfQVRUUklCLAotICAgICAgInswfSBkb2l0IGF2b2lyIHVuIGF0dHJpYnV0ICcndGVzdCcnLiJ9LAotCi0gICAge0VSX0JBRF9WQUxfT05fTEVWRUxfQVRUUklCLAotICAgICAgIlZhbGV1ciBpbmNvcnJlY3RlIHN1ciBsJydhdHRyaWJ1dCBkZSBuaXZlYXUgOiB7MH0ifSwKLQotICAgIHtFUl9QUk9DRVNTSU5HSU5TVFJVQ1RJT05fTkFNRV9DQU5UX0JFX1hNTCwKLSAgICAgICJMZSBub20gZGUgcHJvY2Vzc2luZy1pbnN0cnVjdGlvbiBuZSBwZXV0IHBhcyBcdTAwRUF0cmUgJ3htbCcifSwKLQotICAgIHsgRVJfUFJPQ0VTU0lOR0lOU1RSVUNUSU9OX05PVFZBTElEX05DTkFNRSwKLSAgICAgICJMZSBub20gZGUgcHJvY2Vzc2luZy1pbnN0cnVjdGlvbiBkb2l0IFx1MDBFQXRyZSB1biBOQ05hbWUgdmFsaWRlIDogezB9In0sCi0KLSAgICB7IEVSX05FRURfTUFUQ0hfQVRUUklCLAotICAgICAgInswfSBkb2l0IGF2b2lyIHVuIGF0dHJpYnV0IGRlIGNvcnJlc3BvbmRhbmNlIHMnJ2lsIGEgdW4gbW9kZS4ifSwKLQotICAgIHsgRVJfTkVFRF9OQU1FX09SX01BVENIX0FUVFJJQiwKLSAgICAgICJ7MH0gZXhpZ2UgdW4gbm9tIG91IHVuIGF0dHJpYnV0IGRlIGNvcnJlc3BvbmRhbmNlLiJ9LAotCi0gICAge0VSX0NBTlRfUkVTT0xWRV9OU1BSRUZJWCwKLSAgICAgICJJbXBvc3NpYmxlIGRlIHJcdTAwRTlzb3VkcmUgbGUgcHJcdTAwRTlmaXhlIGRlIGwnJ2VzcGFjZSBkZSBub21zIDogezB9In0sCi0KLSAgICB7IEVSX0lMTEVHQUxfVkFMVUUsCi0gICAgICJ4bWw6c3BhY2UgYSB1bmUgdmFsZXVyIG5vbiBhZG1pc2UgOiB7MH0ifSwKLQotICAgIHsgRVJfTk9fT1dORVJET0MsCi0gICAgICAiTGUgbm9ldWQgZW5mYW50IG5lIHBvc3NcdTAwRThkZSBwYXMgZGUgZG9jdW1lbnQgcHJvcHJpXHUwMEU5dGFpcmUuIn0sCi0KLSAgICB7IEVSX0VMRU1URU1QTEFURUVMRU1fRVJSLAotICAgICAiRXJyZXVyIEVsZW1UZW1wbGF0ZUVsZW1lbnQgOiB7MH0ifSwKLQotICAgIHsgRVJfTlVMTF9DSElMRCwKLSAgICAgIlRlbnRhdGl2ZSBkJ2Fqb3V0IGQndW4gZW5mYW50IE5VTEwuIn0sCi0KLSAgICB7IEVSX05FRURfU0VMRUNUX0FUVFJJQiwKLSAgICAgInswfSBleGlnZSB1biBhdHRyaWJ1dCBcInNlbGVjdFwiLiJ9LAotCi0gICAgeyBFUl9ORUVEX1RFU1RfQVRUUklCICwKLSAgICAgICJ4c2w6d2hlbiBkb2l0IGF2b2lyIHVuIGF0dHJpYnV0IFwidGVzdFwiLiJ9LAotCi0gICAgeyBFUl9ORUVEX05BTUVfQVRUUklCLAotICAgICAgInhzbDp3aXRoLXBhcmFtIGRvaXQgYXZvaXIgdW4gYXR0cmlidXQgXCJuYW1lXCIuIn0sCi0KLSAgICB7IEVSX05PX0NPTlRFWFRfT1dORVJET0MsCi0gICAgICAibGUgY29udGV4dGUgbmUgcG9zc1x1MDBFOGRlIHBhcyBkZSBkb2N1bWVudCBwcm9wcmlcdTAwRTl0YWlyZS4ifSwKLQotICAgIHtFUl9DT1VMRF9OT1RfQ1JFQVRFX1hNTF9QUk9DX0xJQUlTT04sCi0gICAgICAiSW1wb3NzaWJsZSBkZSBjclx1MDBFOWVyIGxhIGxpYWlzb24gWE1MPz8gVHJhbnNmb3JtZXJGYWN0b3J5IDogezB9In0sCi0KLSAgICB7RVJfUFJPQ0VTU19OT1RfU1VDQ0VTU0ZVTCwKLSAgICAgICJYYWxhbiA6IGxlIHByb2Nlc3N1cyBhIFx1MDBFOWNob3VcdTAwRTkuIn0sCi0KLSAgICB7IEVSX05PVF9TVUNDRVNTRlVMLAotICAgICAiWGFsYW4gOiBcdTAwRTljaGVjLiJ9LAotCi0gICAgeyBFUl9FTkNPRElOR19OT1RfU1VQUE9SVEVELAotICAgICAiRW5jb2RhZ2Ugbm9uIHByaXMgZW4gY2hhcmdlIDogezB9In0sCi0KLSAgICB7RVJfQ09VTERfTk9UX0NSRUFURV9UUkFDRUxJU1RFTkVSLAotICAgICAgIkltcG9zc2libGUgZGUgY3JcdTAwRTllciBUcmFjZUxpc3RlbmVyIDogezB9In0sCi0KLSAgICB7RVJfS0VZX1JFUVVJUkVTX05BTUVfQVRUUklCLAotICAgICAgInhzbDprZXkgZXhpZ2UgdW4gYXR0cmlidXQgXCJuYW1lXCIuIn0sCi0KLSAgICB7IEVSX0tFWV9SRVFVSVJFU19NQVRDSF9BVFRSSUIsCi0gICAgICAieHNsOmtleSBleGlnZSB1biBhdHRyaWJ1dCBcIm1hdGNoXCIuIn0sCi0KLSAgICB7IEVSX0tFWV9SRVFVSVJFU19VU0VfQVRUUklCLAotICAgICAgInhzbDprZXkgZXhpZ2UgdW4gYXR0cmlidXQgXCJ1c2VcIi4ifSwKLQotICAgIHsgRVJfUkVRVUlSRVNfRUxFTUVOVFNfQVRUUklCLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgezB9IGV4aWdlIHVuIGF0dHJpYnV0ICcnZWxlbWVudHMnJy4ifSwKLQotICAgIHsgRVJfTUlTU0lOR19QUkVGSVhfQVRUUklCLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgTCcnYXR0cmlidXQgJydwcmVmaXgnJyB7MH0gZXN0IG1hbnF1YW50In0sCi0KLSAgICB7IEVSX0JBRF9TVFlMRVNIRUVUX1VSTCwKLSAgICAgIkwnJ1VSTCBkZSBmZXVpbGxlIGRlIHN0eWxlIGVzdCBpbmNvcnJlY3RlIDogezB9In0sCi0KLSAgICB7IEVSX0ZJTEVfTk9UX0ZPVU5ELAotICAgICAiRmljaGllciBkZSBmZXVpbGxlIGRlIHN0eWxlIGludHJvdXZhYmxlIDogezB9In0sCi0KLSAgICB7IEVSX0lPRVhDRVBUSU9OLAotICAgICAgIkV4Y2VwdGlvbiBkJydFL1MgYXZlYyBsZSBmaWNoaWVyIGRlIGZldWlsbGUgZGUgc3R5bGUgOiB7MH0ifSwKLQotICAgIHsgRVJfTk9fSFJFRl9BVFRSSUIsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSBBdHRyaWJ1dCBocmVmIGludHJvdXZhYmxlIHBvdXIgezB9In0sCi0KLSAgICB7IEVSX1NUWUxFU0hFRVRfSU5DTFVERVNfSVRTRUxGLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgezB9IHMnJ2luY2x1dCBkaXJlY3RlbWVudCBvdSBpbmRpcmVjdGVtZW50IGx1aS1tXHUwMEVBbWUuIn0sCi0KLSAgICB7IEVSX1BST0NFU1NJTkNMVURFX0VSUk9SLAotICAgICAgIkVycmV1ciBTdHlsZXNoZWV0SGFuZGxlci5wcm9jZXNzSW5jbHVkZSwgezB9In0sCi0KLSAgICB7IEVSX01JU1NJTkdfTEFOR19BVFRSSUIsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSBMJydhdHRyaWJ1dCBcImxhbmdcIiB7MH0gZXN0IG1hbnF1YW50In0sCi0KLSAgICB7IEVSX01JU1NJTkdfQ09OVEFJTkVSX0VMRU1FTlRfQ09NUE9ORU5ULAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgbCcnXHUwMEU5bFx1MDBFOW1lbnQgezB9IGVzdC1pbCBtYWwgcGxhY1x1MDBFOT8gRWxcdTAwRTltZW50ICcnY29tcG9uZW50JycgZHUgY29udGVuZXVyIG1hbnF1YW50In0sCi0KLSAgICB7IEVSX0NBTl9PTkxZX09VVFBVVF9UT19FTEVNRU5ULAotICAgICAgIlNvcnRpZSB1bmlxdWUgdmVycyBFbGVtZW50LCBEb2N1bWVudEZyYWdtZW50LCBEb2N1bWVudCBvdSBQcmludFdyaXRlci4ifSwKLQotICAgIHsgRVJfUFJPQ0VTU19FUlJPUiwKLSAgICAgIkVycmV1ciBTdHlsZXNoZWV0Um9vdC5wcm9jZXNzIn0sCi0KLSAgICB7IEVSX1VOSU1QTE5PREVfRVJST1IsCi0gICAgICJFcnJldXIgVW5JbXBsTm9kZSA6IHswfSJ9LAotCi0gICAgeyBFUl9OT19TRUxFQ1RfRVhQUkVTU0lPTiwKLSAgICAgICJFcnJldXIgOiBleHByZXNzaW9uIGRlIHNcdTAwRTlsZWN0aW9uIFhwYXRoIGludHJvdXZhYmxlICgtc2VsZWN0KS4ifSwKLQotICAgIHsgRVJfQ0FOTk9UX1NFUklBTElaRV9YU0xQUk9DRVNTT1IsCi0gICAgICAiSW1wb3NzaWJsZSBkZSBzXHUwMEU5cmlhbGlzZXIgdW4gcHJvY2Vzc2V1ciBYU0wuIn0sCi0KLSAgICB7IEVSX05PX0lOUFVUX1NUWUxFU0hFRVQsCi0gICAgICAiTCdlbnRyXHUwMEU5ZSBkZSBmZXVpbGxlIGRlIHN0eWxlIG4nYSBwYXMgXHUwMEU5dFx1MDBFOSBzcFx1MDBFOWNpZmlcdTAwRTllLiJ9LAotCi0gICAgeyBFUl9GQUlMRURfUFJPQ0VTU19TVFlMRVNIRUVULAotICAgICAgIkVjaGVjIGR1IHRyYWl0ZW1lbnQgZGUgbGEgZmV1aWxsZSBkZSBzdHlsZS4ifSwKLQotICAgIHsgRVJfQ09VTEROVF9QQVJTRV9ET0MsCi0gICAgICJJbXBvc3NpYmxlIGQnJ2FuYWx5c2VyIGxlIGRvY3VtZW50IHswfS4ifSwKLQotICAgIHsgRVJfQ09VTEROVF9GSU5EX0ZSQUdNRU5ULAotICAgICAiRnJhZ21lbnQgaW50cm91dmFibGUgOiB7MH0ifSwKLQotICAgIHsgRVJfTk9ERV9OT1RfRUxFTUVOVCwKLSAgICAgICJMZSBub2V1ZCBzdXIgbGVxdWVsIHBvaW50ZSBsJydpZGVudGlmaWNhdGV1ciBkZSBmcmFnbWVudCBuJydcdTAwRTl0YWl0IHBhcyB1biBcdTAwRTlsXHUwMEU5bWVudCA6IHswfSJ9LAotCi0gICAgeyBFUl9GT1JFQUNIX05FRURfTUFUQ0hfT1JfTkFNRV9BVFRSSUIsCi0gICAgICAibCdcdTAwRTlsXHUwMEU5bWVudCBmb3ItZWFjaCBkb2l0IGF2b2lyIHVuIGF0dHJpYnV0IGRlIG5vbSBvdSBkZSBjb3JyZXNwb25kYW5jZSJ9LAotCi0gICAgeyBFUl9URU1QTEFURVNfTkVFRF9NQVRDSF9PUl9OQU1FX0FUVFJJQiwKLSAgICAgICJsZXMgbW9kXHUwMEU4bGVzIGRvaXZlbnQgYXZvaXIgdW4gYXR0cmlidXQgZGUgbm9tIG91IGRlIGNvcnJlc3BvbmRhbmNlIn0sCi0KLSAgICB7IEVSX05PX0NMT05FX09GX0RPQ1VNRU5UX0ZSQUcsCi0gICAgICAiQXVjdW4gY2xvbmUgZCd1biBmcmFnbWVudCBkZSBkb2N1bWVudC4ifSwKLQotICAgIHsgRVJfQ0FOVF9DUkVBVEVfSVRFTSwKLSAgICAgICJJbXBvc3NpYmxlIGRlIGNyXHUwMEU5ZXIgbCcnXHUwMEU5bFx1MDBFOW1lbnQgZGFucyBsJydhcmJvcmVzY2VuY2UgZGUgclx1MDBFOXN1bHRhdHMgOiB7MH0ifSwKLQotICAgIHsgRVJfWE1MU1BBQ0VfSUxMRUdBTF9WQUxVRSwKLSAgICAgICJ4bWw6c3BhY2UgZGFucyBsZSBmaWNoaWVyIFhNTCBzb3VyY2UgYSB1bmUgdmFsZXVyIG5vbiBhZG1pc2UgOiB7MH0ifSwKLQotICAgIHsgRVJfTk9fWFNMS0VZX0RFQ0xBUkFUSU9OLAotICAgICAgIklsIG4nJ2V4aXN0ZSBhdWN1bmUgZFx1MDBFOWNsYXJhdGlvbiB4c2w6a2V5IHBvdXIgezB9LiJ9LAotCi0gICAgeyBFUl9DQU5UX0NSRUFURV9VUkwsCi0gICAgICJFcnJldXIgOiBpbXBvc3NpYmxlIGRlIGNyXHUwMEU5ZXIgbCcnVVJMIHBvdXIgOiB7MH0ifSwKLQotICAgIHsgRVJfWFNMRlVOQ1RJT05TX1VOU1VQUE9SVEVELAotICAgICAieHNsOmZ1bmN0aW9ucyBuJ2VzdCBwYXMgcHJpcyBlbiBjaGFyZ2UifSwKLQotICAgIHsgRVJfUFJPQ0VTU09SX0VSUk9SLAotICAgICAiRXJyZXVyIFRyYW5zZm9ybWVyRmFjdG9yeSBYU0xUIn0sCi0KLSAgICB7IEVSX05PVF9BTExPV0VEX0lOU0lERV9TVFlMRVNIRUVULAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgezB9IG5vbiBhdXRvcmlzXHUwMEU5IGRhbnMgdW5lIGZldWlsbGUgZGUgc3R5bGUuIn0sCi0KLSAgICB7IEVSX1JFU1VMVE5TX05PVF9TVVBQT1JURUQsCi0gICAgICAiXHUwMEU5bFx1MDBFOW1lbnQgcmVzdWx0LW5zIHBsdXMgcHJpcyBlbiBjaGFyZ2UuIFV0aWxpc2V6IHBsdXRcdTAwRjR0IHhzbDpvdXRwdXQuIn0sCi0KLSAgICB7IEVSX0RFRkFVTFRTUEFDRV9OT1RfU1VQUE9SVEVELAotICAgICAgIlx1MDBFOWxcdTAwRTltZW50IGRlZmF1bHQtc3BhY2UgcGx1cyBwcmlzIGVuIGNoYXJnZS4gVXRpbGlzZXogcGx1dFx1MDBGNHQgeHNsOnN0cmlwLXNwYWNlIG91IHhzbDpwcmVzZXJ2ZS1zcGFjZS4ifSwKLQotICAgIHsgRVJfSU5ERU5UUkVTVUxUX05PVF9TVVBQT1JURUQsCi0gICAgICAiXHUwMEU5bFx1MDBFOW1lbnQgaW5kZW50LXJlc3VsdCBwbHVzIHByaXMgZW4gY2hhcmdlLiBVdGlsaXNleiBwbHV0XHUwMEY0dCB4c2w6b3V0cHV0LiJ9LAotCi0gICAgeyBFUl9JTExFR0FMX0FUVFJJQiwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIHswfSBhIHVuIGF0dHJpYnV0IG5vbiBhZG1pcyA6IHsxfSJ9LAotCi0gICAgeyBFUl9VTktOT1dOX1hTTF9FTEVNLAotICAgICAiRWxcdTAwRTltZW50IFhTTCBpbmNvbm51IDogezB9In0sCi0KLSAgICB7IEVSX0JBRF9YU0xTT1JUX1VTRSwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIHhzbDpzb3J0IG5lIHBldXQgXHUwMEVBdHJlIHV0aWxpc1x1MDBFOSBxdSdhdmVjIHhzbDphcHBseS10ZW1wbGF0ZXMgb3UgeHNsOmZvci1lYWNoLiJ9LAotCi0gICAgeyBFUl9NSVNQTEFDRURfWFNMV0hFTiwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIHhzbDp3aGVuIG1hbCBwbGFjXHUwMEU5LiJ9LAotCi0gICAgeyBFUl9YU0xXSEVOX05PVF9QQVJFTlRFRF9CWV9YU0xDSE9PU0UsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSB4c2w6Y2hvb3NlIG4nYSBhZmZlY3RcdTAwRTkgYXVjdW4gcGFyZW50IFx1MDBFMCB4c2w6d2hlbi4ifSwKLQotICAgIHsgRVJfTUlTUExBQ0VEX1hTTE9USEVSV0lTRSwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIHhzbDpvdGhlcndpc2UgbWFsIHBsYWNcdTAwRTkuIn0sCi0KLSAgICB7IEVSX1hTTE9USEVSV0lTRV9OT1RfUEFSRU5URURfQllfWFNMQ0hPT1NFLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgeHNsOmNob29zZSBuJ2EgYWZmZWN0XHUwMEU5IGF1Y3VuIHBhcmVudCBcdTAwRTAgeHNsOm90aGVyd2lzZS4ifSwKLQotICAgIHsgRVJfTk9UX0FMTE9XRURfSU5TSURFX1RFTVBMQVRFLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgezB9IG4nJ2VzdCBwYXMgYXV0b3Jpc1x1MDBFOSBkYW5zIHVuIG1vZFx1MDBFOGxlLiJ9LAotCi0gICAgeyBFUl9VTktOT1dOX0VYVF9OU19QUkVGSVgsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSBQclx1MDBFOWZpeGUgezF9IGRlIGwnJ2VzcGFjZSBkZSBub21zIGRlIGwnJ2V4dGVuc2lvbiB7MH0gaW5jb25udSJ9LAotCi0gICAgeyBFUl9JTVBPUlRTX0FTX0ZJUlNUX0VMRU0sCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSBMZXMgaW1wb3J0cyBuZSBwZXV2ZW50IHMnYXBwbGlxdWVyIHF1ZSBzdXIgbGVzIHByZW1pZXJzIFx1MDBFOWxcdTAwRTltZW50cyBkZSBsYSBmZXVpbGxlIGRlIHN0eWxlLiJ9LAotCi0gICAgeyBFUl9JTVBPUlRJTkdfSVRTRUxGLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgezB9IHMnJ2ltcG9ydGUgZGlyZWN0ZW1lbnQgb3UgaW5kaXJlY3RlbWVudCBsdWktbVx1MDBFQW1lLiJ9LAotCi0gICAgeyBFUl9YTUxTUEFDRV9JTExFR0FMX1ZBTCwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIHhtbDpzcGFjZSBhIHVuZSB2YWxldXIgbm9uIGFkbWlzZSA6IHswfSJ9LAotCi0gICAgeyBFUl9QUk9DRVNTU1RZTEVTSEVFVF9OT1RfU1VDQ0VTU0ZVTCwKLSAgICAgICJFY2hlYyBkZSBwcm9jZXNzU3R5bGVzaGVldC4ifSwKLQotICAgIHsgRVJfU0FYX0VYQ0VQVElPTiwKLSAgICAgIkV4Y2VwdGlvbiBTQVgifSwKLQotLy8gIGFkZCB0aGlzIG1lc3NhZ2UgdG8gZml4IGJ1ZyAyMTQ3OAotICAgIHsgRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCwKLSAgICAgIkZvbmN0aW9uIG5vbiBwcmlzZSBlbiBjaGFyZ2UuIn0sCi0KLSAgICB7IEVSX1hTTFRfRVJST1IsCi0gICAgICJFcnJldXIgWFNMVCJ9LAotCi0gICAgeyBFUl9DVVJSRU5DWV9TSUdOX0lMTEVHQUwsCi0gICAgICAibGUgc3ltYm9sZSBkZSBkZXZpc2Ugbidlc3QgcGFzIGF1dG9yaXNcdTAwRTkgZGFucyBsYSBjaGFcdTAwRUVuZSBkdSBtb2RcdTAwRThsZSBkZSBmb3JtYXQifSwKLQotICAgIHsgRVJfRE9DVU1FTlRfRlVOQ1RJT05fSU5WQUxJRF9JTl9TVFlMRVNIRUVUX0RPTSwKLSAgICAgICJGb25jdGlvbiBkZSBkb2N1bWVudCBub24gcHJpc2UgZW4gY2hhcmdlIGRhbnMgbCdvYmpldCBET00gZGUgbGEgZmV1aWxsZSBkZSBzdHlsZS4ifSwKLQotICAgIHsgRVJfQ0FOVF9SRVNPTFZFX1BSRUZJWF9PRl9OT05fUFJFRklYX1JFU09MVkVSLAotICAgICAgIkltcG9zc2libGUgZGUgclx1MDBFOXNvdWRyZSBsZSBwclx1MDBFOWZpeGUgZHUgclx1MDBFOXNvbHZldXIgbm9uLVByZWZpeC4ifSwKLQotICAgIHsgRVJfUkVESVJFQ1RfQ09VTEROVF9HRVRfRklMRU5BTUUsCi0gICAgICAiRXh0ZW5zaW9uIFJlZGlyZWN0IDogaW1wb3NzaWJsZSBkJ29idGVuaXIgbGUgbm9tIGRlIGZpY2hpZXIuIEwnYXR0cmlidXQgXCJmaWxlXCIgb3UgXCJzZWxlY3RcIiBkb2l0IHJlbnZveWVyIHVuZSBjaGFcdTAwRUVuZSB2YWxpZGUuIn0sCi0KLSAgICB7IEVSX0NBTk5PVF9CVUlMRF9GT1JNQVRURVJMSVNURU5FUl9JTl9SRURJUkVDVCwKLSAgICAgICJJbXBvc3NpYmxlIGRlIGNyXHUwMEU5ZXIgRm9ybWF0dGVyTGlzdGVuZXIgZGFucyBsJ2V4dGVuc2lvbiBSZWRpcmVjdC4ifSwKLQotICAgIHsgRVJfSU5WQUxJRF9QUkVGSVhfSU5fRVhDTFVERVJFU1VMVFBSRUZJWCwKLSAgICAgICJMZSBwclx1MDBFOWZpeGUgZGUgbCcnXHUwMEU5bFx1MDBFOW1lbnQgZXhjbHVkZS1yZXN1bHQtcHJlZml4ZXMgbicnZXN0IHBhcyB2YWxpZGUgOiB7MH0ifSwKLQotICAgIHsgRVJfTUlTU0lOR19OU19VUkksCi0gICAgICAiVVJJIGQnZXNwYWNlIGRlIG5vbXMgbWFucXVhbnQgcG91ciBsZSBwclx1MDBFOWZpeGUgc3BcdTAwRTljaWZpXHUwMEU5In0sCi0KLSAgICB7IEVSX01JU1NJTkdfQVJHX0ZPUl9PUFRJT04sCi0gICAgICAiQXJndW1lbnQgbWFucXVhbnQgcG91ciBsJydvcHRpb24gOiB7MH0ifSwKLQotICAgIHsgRVJfSU5WQUxJRF9PUFRJT04sCi0gICAgICJPcHRpb24gbm9uIHZhbGlkZSA6IHswfSJ9LAotCi0gICAgeyBFUl9NQUxGT1JNRURfRk9STUFUX1NUUklORywKLSAgICAgIkZvcm1hdCBkZSBjaGFcdTAwRUVuZSBpbmNvcnJlY3QgOiB7MH0ifSwKLQotICAgIHsgRVJfU1RZTEVTSEVFVF9SRVFVSVJFU19WRVJTSU9OX0FUVFJJQiwKLSAgICAgICJ4c2w6c3R5bGVzaGVldCBleGlnZSB1biBhdHRyaWJ1dCAgZGUgdmVyc2lvbi4ifSwKLQotICAgIHsgRVJfSUxMRUdBTF9BVFRSSUJVVEVfVkFMVUUsCi0gICAgICAiTCcnYXR0cmlidXQgezB9IGEgdW5lIHZhbGV1ciBub24gYWRtaXNlIDogezF9In0sCi0KLSAgICB7IEVSX0NIT09TRV9SRVFVSVJFU19XSEVOLAotICAgICAieHNsOmNob29zZSBleGlnZSB1biBcdTAwRTlsXHUwMEU5bWVudCB4c2w6d2hlbiJ9LAotCi0gICAgeyBFUl9OT19BUFBMWV9JTVBPUlRfSU5fRk9SX0VBQ0gsCi0gICAgICAieHNsOmFwcGx5LWltcG9ydHMgbm9uIGF1dG9yaXNcdTAwRTkgZGFucyB1biBcdTAwRTlsXHUwMEU5bWVudCB4c2w6Zm9yLWVhY2gifSwKLQotICAgIHsgRVJfQ0FOVF9VU0VfRFRNX0ZPUl9PVVRQVVQsCi0gICAgICAiSW1wb3NzaWJsZSBkJ3V0aWxpc2VyIHVuIFx1MDBFOWxcdTAwRTltZW50IERUTUxpYWlzb24gcG91ciB1biBub2V1ZCBET00gZGUgc29ydGllLi4uIFRyYW5zbWV0dGV6IHBsdXRcdTAwRjR0IHVuIFx1MDBFOWxcdTAwRTltZW50IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5ET00ySGVscGVyLiJ9LAotCi0gICAgeyBFUl9DQU5UX1VTRV9EVE1fRk9SX0lOUFVULAotICAgICAgIkltcG9zc2libGUgZCd1dGlsaXNlciB1biBcdTAwRTlsXHUwMEU5bWVudCBEVE1MaWFpc29uIHBvdXIgdW4gbm9ldWQgRE9NIGQnZW50clx1MDBFOWUuLi4gVHJhbnNtZXR0ZXogcGx1dFx1MDBGNHQgdW4gXHUwMEU5bFx1MDBFOW1lbnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLkRPTTJIZWxwZXIuIn0sCi0KLSAgICB7IEVSX0NBTExfVE9fRVhUX0ZBSUxFRCwKLSAgICAgICJFY2hlYyBkZSBsJydhcHBlbCBkZSBsJydcdTAwRTlsXHUwMEU5bWVudCBkJydleHRlbnNpb24gOiB7MH0ifSwKLQotICAgIHsgRVJfUFJFRklYX01VU1RfUkVTT0xWRSwKLSAgICAgICJMZSBwclx1MDBFOWZpeGUgZG9pdCBcdTAwRUF0cmUgclx1MDBFOXNvbHUgZW4gZXNwYWNlIGRlIG5vbXMgOiB7MH0ifSwKLQotICAgIHsgRVJfSU5WQUxJRF9VVEYxNl9TVVJST0dBVEUsCi0gICAgICAiU3Vic3RpdHV0IFVURi0xNiBub24gdmFsaWRlIGRcdTAwRTl0ZWN0XHUwMEU5IDogezB9ID8ifSwKLQotICAgIHsgRVJfWFNMQVRUUlNFVF9VU0VEX0lUU0VMRiwKLSAgICAgICJ4c2w6YXR0cmlidXRlLXNldCB7MH0gcycnZXN0IHV0aWxpc1x1MDBFOSBsdWktbVx1MDBFQW1lLCBjZSBxdWkgZ1x1MDBFOW5cdTAwRThyZSB1bmUgYm91Y2xlIHNhbnMgZmluLiJ9LAotCi0gICAgeyBFUl9DQU5OT1RfTUlYX1hFUkNFU0RPTSwKLSAgICAgICJJbXBvc3NpYmxlIGRlIGNvbWJpbmVyIHVuZSBlbnRyXHUwMEU5ZSBub24gWGVyY2VzLURPTSBldCB1bmUgc29ydGllIFhlcmNlcy1ET00uIn0sCi0KLSAgICB7IEVSX1RPT19NQU5ZX0xJU1RFTkVSUywKLSAgICAgICJhZGRUcmFjZUxpc3RlbmVyc1RvU3R5bGVzaGVldCAtIFRvb01hbnlMaXN0ZW5lcnNFeGNlcHRpb24ifSwKLQotICAgIHsgRVJfSU5fRUxFTVRFTVBMQVRFRUxFTV9SRUFET0JKRUNULAotICAgICAgIkRhbnMgRWxlbVRlbXBsYXRlRWxlbWVudC5yZWFkT2JqZWN0IDogezB9In0sCi0KLSAgICB7IEVSX0RVUExJQ0FURV9OQU1FRF9URU1QTEFURSwKLSAgICAgICJQbHVzaWV1cnMgbW9kXHUwMEU4bGVzIG5vbW1cdTAwRTlzIHswfSBvbnQgXHUwMEU5dFx1MDBFOSB0cm91dlx1MDBFOXMifSwKLQotICAgIHsgRVJfSU5WQUxJRF9LRVlfQ0FMTCwKLSAgICAgICJBcHBlbCBkZSBmb25jdGlvbiBub24gdmFsaWRlIDogbGVzIGFwcGVscyBkZSB0b3VjaGUgclx1MDBFOWN1cnNpdmUgKCkgbmUgc29udCBwYXMgYXV0b3Jpc1x1MDBFOXMifSwKLQotICAgIHsgRVJfUkVGRVJFTkNJTkdfSVRTRUxGLAotICAgICAgIkxhIHZhcmlhYmxlIHswfSBmYWl0IGRpcmVjdGVtZW50IG91IGluZGlyZWN0ZW1lbnQgclx1MDBFOWZcdTAwRTlyZW5jZSBcdTAwRTAgZWxsZS1tXHUwMEVBbWUuIn0sCi0KLSAgICB7IEVSX0lMTEVHQUxfRE9NU09VUkNFX0lOUFVULAotICAgICAgIkxlIG5vZXVkIGQnZW50clx1MDBFOWUgbmUgcGV1dCBwYXMgXHUwMEVBdHJlIE5VTEwgcG91ciB1biBcdTAwRTlsXHUwMEU5bWVudCBET01Tb3VyY2UgZGUgbmV3VGVtcGxhdGVzLiJ9LAotCi0gICAgeyBFUl9DTEFTU19OT1RfRk9VTkRfRk9SX09QVElPTiwKLSAgICAgICAgIkZpY2hpZXIgZGUgY2xhc3NlIGludHJvdXZhYmxlIHBvdXIgbCcnb3B0aW9uIHswfSJ9LAotCi0gICAgeyBFUl9SRVFVSVJFRF9FTEVNX05PVF9GT1VORCwKLSAgICAgICAgIkVsXHUwMEU5bWVudCBvYmxpZ2F0b2lyZSBpbnRyb3V2YWJsZSA6IHswfSJ9LAotCi0gICAgeyBFUl9JTlBVVF9DQU5OT1RfQkVfTlVMTCwKLSAgICAgICAgIklucHV0U3RyZWFtIG5lIHBldXQgcGFzIFx1MDBFQXRyZSBOVUxMIn0sCi0KLSAgICB7IEVSX1VSSV9DQU5OT1RfQkVfTlVMTCwKLSAgICAgICAgIkwnVVJJIG5lIHBldXQgcGFzIFx1MDBFQXRyZSBOVUxMIn0sCi0KLSAgICB7IEVSX0ZJTEVfQ0FOTk9UX0JFX05VTEwsCi0gICAgICAgICJMZSBmaWNoaWVyIG5lIHBldXQgcGFzIFx1MDBFQXRyZSBOVUxMIn0sCi0KLSAgICB7IEVSX1NPVVJDRV9DQU5OT1RfQkVfTlVMTCwKLSAgICAgICAgICAgICAgICAiSW5wdXRTb3VyY2UgbmUgcGV1dCBwYXMgXHUwMEVBdHJlIE5VTEwifSwKLQotICAgIHsgRVJfQ0FOTk9UX0lOSVRfQlNGTUdSLAotICAgICAgICAgICAgICAgICJJbXBvc3NpYmxlIGQnaW5pdGlhbGlzZXIgbGUgZ2VzdGlvbm5haXJlIEJTRiJ9LAotCi0gICAgeyBFUl9DQU5OT1RfQ01QTF9FWFRFTlNOLAotICAgICAgICAgICAgICAgICJJbXBvc3NpYmxlIGRlIGNvbXBpbGVyIGwnZXh0ZW5zaW9uIn0sCi0KLSAgICB7IEVSX0NBTk5PVF9DUkVBVEVfRVhURU5TTiwKLSAgICAgICJJbXBvc3NpYmxlIGRlIGNyXHUwMEU5ZXIgbCcnZXh0ZW5zaW9uIHswfS4gQ2F1c2UgOiB7MX0ifSwKLQotICAgIHsgRVJfSU5TVEFOQ0VfTVRIRF9DQUxMX1JFUVVJUkVTLAotICAgICAgIkwnJ2FwcGVsIGRlIGxhIG1cdTAwRTl0aG9kZSBkJydpbnN0YW5jZSB7MH0gZXhpZ2UgdW5lIGluc3RhbmNlIGQnJ29iamV0IGNvbW1lIHByZW1pZXIgYXJndW1lbnQifSwKLQotICAgIHsgRVJfSU5WQUxJRF9FTEVNRU5UX05BTUUsCi0gICAgICAiTm9tIGQnJ1x1MDBFOWxcdTAwRTltZW50IHNwXHUwMEU5Y2lmaVx1MDBFOSB7MH0gbm9uIHZhbGlkZSJ9LAotCi0gICAgeyBFUl9FTEVNRU5UX05BTUVfTUVUSE9EX1NUQVRJQywKLSAgICAgICJMYSBtXHUwMEU5dGhvZGUgZHUgbm9tIGQnJ1x1MDBFOWxcdTAwRTltZW50IGRvaXQgXHUwMEVBdHJlIHN0YXRpcXVlIHswfSJ9LAotCi0gICAgeyBFUl9FWFRFTlNJT05fRlVOQ19VTktOT1dOLAotICAgICAgICAgICAgICJMYSBmb25jdGlvbiBkJydleHRlbnNpb24gezB9IDogezF9IGVzdCBpbmNvbm51ZSJ9LAotCi0gICAgeyBFUl9NT1JFX01BVENIX0NPTlNUUlVDVE9SLAotICAgICAgICAgICAgICJQbHVzaWV1cnMgbWVpbGxldXJlcyBjb25jb3JkYW5jZXMgZHUgY29uc3RydWN0ZXVyIHBvdXIgezB9In0sCi0KLSAgICB7IEVSX01PUkVfTUFUQ0hfTUVUSE9ELAotICAgICAgICAgICAgICJQbHVzaWV1cnMgbWVpbGxldXJlcyBjb25jb3JkYW5jZXMgcG91ciBsYSBtXHUwMEU5dGhvZGUgezB9In0sCi0KLSAgICB7IEVSX01PUkVfTUFUQ0hfRUxFTUVOVCwKLSAgICAgICAgICAgICAiUGx1c2lldXJzIG1laWxsZXVyZXMgY29uY29yZGFuY2VzIHBvdXIgbGEgbVx1MDBFOXRob2RlIGQnJ1x1MDBFOWxcdTAwRTltZW50IHswfSJ9LAotCi0gICAgeyBFUl9JTlZBTElEX0NPTlRFWFRfUEFTU0VELAotICAgICAgICAgICAgICJDb250ZXh0ZSB0cmFuc21pcyBwb3VyIFx1MDBFOXZhbHVhdGlvbiB7MH0gbm9uIHZhbGlkZSJ9LAotCi0gICAgeyBFUl9QT09MX0VYSVNUUywKLSAgICAgICAgICAgICAiTGUgcG9vbCBleGlzdGUgZFx1MDBFOWpcdTAwRTAifSwKLQotICAgIHsgRVJfTk9fRFJJVkVSX05BTUUsCi0gICAgICAgICAgICAgIkF1Y3VuIG5vbSBkZSBwaWxvdGUgaW5kaXF1XHUwMEU5In0sCi0KLSAgICB7IEVSX05PX1VSTCwKLSAgICAgICAgICAgICAiQXVjdW5lIFVSTCBpbmRpcXVcdTAwRTllIn0sCi0KLSAgICB7IEVSX1BPT0xfU0laRV9MRVNTVEhBTl9PTkUsCi0gICAgICAgICAgICAgIkxhIHRhaWxsZSBkZSBwb29sIGVzdCBpbmZcdTAwRTlyaWV1cmUgXHUwMEUwIDEuIn0sCi0KLSAgICB7IEVSX0lOVkFMSURfRFJJVkVSLAotICAgICAgICAgICAgICJOb20gZGUgcGlsb3RlIGluZGlxdVx1MDBFOSBub24gdmFsaWRlLiJ9LAotCi0gICAgeyBFUl9OT19TVFlMRVNIRUVUUk9PVCwKLSAgICAgICAgICAgICAiUmFjaW5lIGRlIGxhIGZldWlsbGUgZGUgc3R5bGUgaW50cm91dmFibGUuIn0sCi0KLSAgICB7IEVSX0lMTEVHQUxfWE1MU1BBQ0VfVkFMVUUsCi0gICAgICAgICAiVmFsZXVyIG5vbiBhZG1pc2UgcG91ciB4bWw6c3BhY2UifSwKLQotICAgIHsgRVJfUFJPQ0VTU0ZST01OT0RFX0ZBSUxFRCwKLSAgICAgICAgICJFY2hlYyBkZSBwcm9jZXNzRnJvbU5vZGUifSwKLQotICAgIHsgRVJfUkVTT1VSQ0VfQ09VTERfTk9UX0xPQUQsCi0gICAgICAgICJMYSByZXNzb3VyY2UgWyB7MH0gXSBuJydhIHBhcyBwdSBjaGFyZ2VyIDogezF9IFxuIHsyfSBcdCB7M30ifSwKLQotICAgIHsgRVJfQlVGRkVSX1NJWkVfTEVTU1RIQU5fWkVSTywKLSAgICAgICAgIlRhaWxsZSBkdSB0YW1wb24gPD0wIn0sCi0KLSAgICB7IEVSX1VOS05PV05fRVJST1JfQ0FMTElOR19FWFRFTlNJT04sCi0gICAgICAgICJFcnJldXIgaW5jb25udWUgbG9ycyBkZSBsJ2FwcGVsIGRlIGwnZXh0ZW5zaW9uIn0sCi0KLSAgICB7IEVSX05PX05BTUVTUEFDRV9ERUNMLAotICAgICAgICAiTGUgcHJcdTAwRTlmaXhlIHswfSBuJydhIHBhcyBkZSBkXHUwMEU5Y2xhcmF0aW9uIGQnJ2VzcGFjZSBkZSBub21zIGNvcnJlc3BvbmRhbnRlIn0sCi0KLSAgICB7IEVSX0VMRU1fQ09OVEVOVF9OT1RfQUxMT1dFRCwKLSAgICAgICAgIkNvbnRlbnUgZCcnXHUwMEU5bFx1MDBFOW1lbnQgbm9uIGF1dG9yaXNcdTAwRTkgcG91ciBsYW5nPWphdmFjbGFzcyB7MH0ifSwKLQotICAgIHsgRVJfU1RZTEVTSEVFVF9ESVJFQ1RFRF9URVJNSU5BVElPTiwKLSAgICAgICAgIkZpbiBkdSByXHUwMEU5YWNoZW1pbmVtZW50IGRlIGxhIGZldWlsbGUgZGUgc3R5bGUifSwKLQotICAgIHsgRVJfT05FX09SX1RXTywKLSAgICAgICAgIjEgb3UgMiJ9LAotCi0gICAgeyBFUl9UV09fT1JfVEhSRUUsCi0gICAgICAgICIyIG91IDMifSwKLQotICAgIHsgRVJfQ09VTERfTk9UX0xPQURfUkVTT1VSQ0UsCi0gICAgICAgICJJbXBvc3NpYmxlIGRlIGNoYXJnZXIgezB9ICh2XHUwMEU5cmlmaWVyIENMQVNTUEFUSCksIGxlcyB2YWxldXJzIHBhciBkXHUwMEU5ZmF1dCBzb250IGRvbmMgZW1wbG95XHUwMEU5ZXMifSwKLQotICAgIHsgRVJfQ0FOTk9UX0lOSVRfREVGQVVMVF9URU1QTEFURVMsCi0gICAgICAgICJJbXBvc3NpYmxlIGQnaW5pdGlhbGlzZXIgbGVzIG1vZFx1MDBFOGxlcyBkZWZhdWx0In0sCi0KLSAgICB7IEVSX1JFU1VMVF9OVUxMLAotICAgICAgICAiTGUgclx1MDBFOXN1bHRhdCBuZSBkb2l0IHBhcyBcdTAwRUF0cmUgTlVMTCJ9LAotCi0gICAgeyBFUl9SRVNVTFRfQ09VTERfTk9UX0JFX1NFVCwKLSAgICAgICAgIkxlIHJcdTAwRTlzdWx0YXQgbidhIHBhcyBwdSBcdTAwRUF0cmUgZFx1MDBFOWZpbmkifSwKLQotICAgIHsgRVJfTk9fT1VUUFVUX1NQRUNJRklFRCwKLSAgICAgICAgIkF1Y3VuZSBzb3J0aWUgc3BcdTAwRTljaWZpXHUwMEU5ZSJ9LAotCi0gICAgeyBFUl9DQU5OT1RfVFJBTlNGT1JNX1RPX1JFU1VMVF9UWVBFLAotICAgICAgICAiSW1wb3NzaWJsZSBkZSB0cmFuc2Zvcm1lciBsZSByXHUwMEU5c3VsdGF0IGVuIHJcdTAwRTlzdWx0YXQgZGUgdHlwZSB7MH0ifSwKLQotICAgIHsgRVJfQ0FOTk9UX1RSQU5TRk9STV9TT1VSQ0VfVFlQRSwKLSAgICAgICAgIkltcG9zc2libGUgZGUgdHJhbnNmb3JtZXIgdW5lIHNvdXJjZSBkZSB0eXBlIHswfSJ9LAotCi0gICAgeyBFUl9OVUxMX0NPTlRFTlRfSEFORExFUiwKLSAgICAgICAgIkdlc3Rpb25uYWlyZSBkZSBjb250ZW51IE5VTEwifSwKLQotICAgIHsgRVJfTlVMTF9FUlJPUl9IQU5ETEVSLAotICAgICAgICAiR2VzdGlvbm5haXJlIGQnZXJyZXVycyBOVUxMIn0sCi0KLSAgICB7IEVSX0NBTk5PVF9DQUxMX1BBUlNFLAotICAgICAgICAiaW1wb3NzaWJsZSBkJ2FwcGVsZXIgbCdhbmFseXNlIHNpIGxlIGdlc3Rpb25uYWlyZSBkZSBjb250ZW51IG4nZXN0IHBhcyBkXHUwMEU5ZmluaSJ9LAotCi0gICAgeyBFUl9OT19QQVJFTlRfRk9SX0ZJTFRFUiwKLSAgICAgICAgIkF1Y3VuIHBhcmVudCBwb3VyIGxlIGZpbHRyZSJ9LAotCi0gICAgeyBFUl9OT19TVFlMRVNIRUVUX0lOX01FRElBLAotICAgICAgICAgIkF1Y3VuZSBmZXVpbGxlIGRlIHN0eWxlIHRyb3V2XHUwMEU5ZSBkYW5zIDogezB9LCBzdXBwb3J0ID0gezF9In0sCi0KLSAgICB7IEVSX05PX1NUWUxFU0hFRVRfUEksCi0gICAgICAgICAiQXVjdW5lIGluc3RydWN0aW9uIGRlIHRyYWl0ZW1lbnQgKFBJKSB4bWwtc3R5bGVzaGVldCB0cm91dlx1MDBFOWUgZGFucyA6IHswfSJ9LAotCi0gICAgeyBFUl9OT1RfU1VQUE9SVEVELAotICAgICAgICJOb24gcHJpcyBlbiBjaGFyZ2UgOiB7MH0ifSwKLQotICAgIHsgRVJfUFJPUEVSVFlfVkFMVUVfQk9PTEVBTiwKLSAgICAgICAiTGEgdmFsZXVyIGRlIGxhIHByb3ByaVx1MDBFOXRcdTAwRTkgezB9IGRvaXQgXHUwMEVBdHJlIHVuZSBpbnN0YW5jZSBCb29sZWFuIn0sCi0KLSAgICB7IEVSX0NPVUxEX05PVF9GSU5EX0VYVEVSTl9TQ1JJUFQsCi0gICAgICAgICAiSW1wb3NzaWJsZSBkJydhY2NcdTAwRTlkZXIgYXUgc2NyaXB0IGV4dGVybmUgXHUwMEUwIHswfSJ9LAotCi0gICAgeyBFUl9SRVNPVVJDRV9DT1VMRF9OT1RfRklORCwKLSAgICAgICAgIkxhIHJlc3NvdXJjZSBbIHswfSBdIGVzdCBpbnRyb3V2YWJsZS5cbiB7MX0ifSwKLQotICAgIHsgRVJfT1VUUFVUX1BST1BFUlRZX05PVF9SRUNPR05JWkVELAotICAgICAgICAiUHJvcHJpXHUwMEU5dFx1MDBFOSBkZSBzb3J0aWUgbm9uIHJlY29ubnVlIDogezB9In0sCi0KLSAgICB7IEVSX0ZBSUxFRF9DUkVBVElOR19FTEVNTElUUlNMVCwKLSAgICAgICAgIkVjaGVjIGRlIGxhIGNyXHUwMEU5YXRpb24gZGUgbCdpbnN0YW5jZSBFbGVtTGl0ZXJhbFJlc3VsdCJ9LAotCi0gIC8vRWFybGllciAoSkRLIDEuNCBYQUxBTiAyLjItRDExKSBhdCBrZXkgY29kZSAnMjA0JyB0aGUga2V5IG5hbWUgd2FzIEVSX1BSSU9SSVRZX05PVF9QQVJTQUJMRQotICAvLyBJbiBsYXRlc3QgWGFsYW4gY29kZSBiYXNlIGtleSBuYW1lIGlzICBFUl9WQUxVRV9TSE9VTERfQkVfTlVNQkVSLiBUaGlzIHNob3VsZCBhbHNvIGJlIHRha2VuIGNhcmUKLSAgLy9pbiBsb2NhbGUgc3BlY2lmaWMgZmlsZXMgbGlrZSBYU0xURXJyb3JSZXNvdXJjZXNfZGUuamF2YSwgWFNMVEVycm9yUmVzb3VyY2VzX2ZyLmphdmEgZXRjLgotICAvL05PVEU6IE5vdCBvbmx5IHRoZSBrZXkgbmFtZSBidXQgbWVzc2FnZSBoYXMgYWxzbyBiZWVuIGNoYW5nZWQuCi0gICAgeyBFUl9WQUxVRV9TSE9VTERfQkVfTlVNQkVSLAotICAgICAgICAiTGEgdmFsZXVyIGRlIHswfSBkb2l0IGNvbnRlbmlyIHVuIG5vbWJyZSBwb3V2YW50IFx1MDBFQXRyZSBhbmFseXNcdTAwRTkifSwKLQotICAgIHsgRVJfVkFMVUVfU0hPVUxEX0VRVUFMLAotICAgICAgICAiTGEgdmFsZXVyIGRlIHswfSBkb2l0IFx1MDBFQXRyZSBcdTAwRTlnYWxlIFx1MDBFMCBvdWkgb3Ugbm9uIn0sCi0KLSAgICB7IEVSX0ZBSUxFRF9DQUxMSU5HX01FVEhPRCwKLSAgICAgICAgIkVjaGVjIGRlIGwnJ2FwcGVsIGRlIGxhIG1cdTAwRTl0aG9kZSB7MH0ifSwKLQotICAgIHsgRVJfRkFJTEVEX0NSRUFUSU5HX0VMRU1UTVBMLAotICAgICAgICAiRWNoZWMgZGUgbGEgY3JcdTAwRTlhdGlvbiBkZSBsJ2luc3RhbmNlIEVsZW1UZW1wbGF0ZUVsZW1lbnQifSwKLQotICAgIHsgRVJfQ0hBUlNfTk9UX0FMTE9XRUQsCi0gICAgICAgICJMZXMgY2FyYWN0XHUwMEU4cmVzIG5lIHNvbnQgcGFzIGF1dG9yaXNcdTAwRTlzIFx1MDBFMCBjZSBwb2ludCBkdSBkb2N1bWVudCJ9LAotCi0gICAgeyBFUl9BVFRSX05PVF9BTExPV0VELAotICAgICAgICAiTCcnYXR0cmlidXQgXCJ7MH1cIiBuJydlc3QgcGFzIGF1dG9yaXNcdTAwRTkgc3VyIGwnJ1x1MDBFOWxcdTAwRTltZW50IHsxfS4ifSwKLQotICAgIHsgRVJfQkFEX1ZBTFVFLAotICAgICAiVmFsZXVyIGluY29ycmVjdGUgZGUgezB9IDogezF9ICJ9LAotCi0gICAgeyBFUl9BVFRSSUJfVkFMVUVfTk9UX0ZPVU5ELAotICAgICAiVmFsZXVyIGQnJ2F0dHJpYnV0IHswfSBpbnRyb3V2YWJsZSAifSwKLQotICAgIHsgRVJfQVRUUklCX1ZBTFVFX05PVF9SRUNPR05JWkVELAotICAgICAiVmFsZXVyIGQnJ2F0dHJpYnV0IHswfSBub24gcmVjb25udWUgIn0sCi0KLSAgICB7IEVSX05VTExfVVJJX05BTUVTUEFDRSwKLSAgICAgIlRlbnRhdGl2ZSBkZSBnXHUwMEU5blx1MDBFOXJhdGlvbiBkJ3VuIHByXHUwMEU5Zml4ZSBkJ2VzcGFjZSBkZSBub21zIGF2ZWMgdW4gVVJJIE5VTEwifSwKLQotICAgIHsgRVJfTlVNQkVSX1RPT19CSUcsCi0gICAgICJUZW50YXRpdmUgZGUgZm9ybWF0YWdlIGQndW4gbm9tYnJlIHN1cFx1MDBFOXJpZXVyIFx1MDBFMCBsJ2VudGllciBkZSB0eXBlIExvbmcgbGUgcGx1cyBncmFuZCJ9LAotCi0gICAgeyBFUl9DQU5OT1RfRklORF9TQVgxX0RSSVZFUiwKLSAgICAgIkNsYXNzZSBkZSBwaWxvdGUgU0FYMSB7MH0gaW50cm91dmFibGUifSwKLQotICAgIHsgRVJfU0FYMV9EUklWRVJfTk9UX0xPQURFRCwKLSAgICAgIkNsYXNzZSBkZSBwaWxvdGUgU0FYMSB7MH0gdHJvdXZcdTAwRTllIG1haXMgcGFzIGNoYXJnXHUwMEU5ZSJ9LAotCi0gICAgeyBFUl9TQVgxX0RSSVZFUl9OT1RfSU5TVEFOVElBVEVELAotICAgICAiQ2xhc3NlIGRlIHBpbG90ZSBTQVgxIHswfSBjaGFyZ1x1MDBFOWUgbWFpcyBwYXMgaW5zdGFuY2lcdTAwRTllIn0sCi0KLSAgICB7IEVSX1NBWDFfRFJJVkVSX05PVF9JTVBMRU1FTlRfUEFSU0VSLAotICAgICAiTGEgY2xhc3NlIGRlIHBpbG90ZSBTQVgxIHswfSBuJydpbXBsXHUwMEU5bWVudGUgcGFzIG9yZy54bWwuc2F4LlBhcnNlciJ9LAotCi0gICAgeyBFUl9QQVJTRVJfUFJPUEVSVFlfTk9UX1NQRUNJRklFRCwKLSAgICAgIlByb3ByaVx1MDBFOXRcdTAwRTkgc3lzdFx1MDBFOG1lIG9yZy54bWwuc2F4LnBhcnNlciBub24gaW5kaXF1XHUwMEU5ZSJ9LAotCi0gICAgeyBFUl9QQVJTRVJfQVJHX0NBTk5PVF9CRV9OVUxMLAotICAgICAiTCdhcmd1bWVudCBkJ2FuYWx5c2V1ciBuZSBkb2l0IHBhcyBcdTAwRUF0cmUgTlVMTCJ9LAotCi0gICAgeyBFUl9GRUFUVVJFLAotICAgICAiRm9uY3Rpb25uYWxpdFx1MDBFOSA6IHswfSJ9LAotCi0gICAgeyBFUl9QUk9QRVJUWSwKLSAgICAgIlByb3ByaVx1MDBFOXRcdTAwRTkgOiB7MH0ifSwKLQotICAgIHsgRVJfTlVMTF9FTlRJVFlfUkVTT0xWRVIsCi0gICAgICJSXHUwMEU5c29sdmV1ciBkJ2VudGl0XHUwMEU5IE5VTEwifSwKLQotICAgIHsgRVJfTlVMTF9EVERfSEFORExFUiwKLSAgICAgIkdlc3Rpb25uYWlyZSBEVEQgTlVMTCJ9LAotCi0gICAgeyBFUl9OT19EUklWRVJfTkFNRV9TUEVDSUZJRUQsCi0gICAgICJBdWN1biBub20gZGUgcGlsb3RlIGluZGlxdVx1MDBFOS4ifSwKLQotICAgIHsgRVJfTk9fVVJMX1NQRUNJRklFRCwKLSAgICAgIkF1Y3VuZSBVUkwgaW5kaXF1XHUwMEU5ZS4ifSwKLQotICAgIHsgRVJfUE9PTFNJWkVfTEVTU19USEFOX09ORSwKLSAgICAgIkxhIHRhaWxsZSBkZSBwb29sIGVzdCBpbmZcdTAwRTlyaWV1cmUgXHUwMEUwIDEuIn0sCi0KLSAgICB7IEVSX0lOVkFMSURfRFJJVkVSX05BTUUsCi0gICAgICJOb20gZGUgcGlsb3RlIGluZGlxdVx1MDBFOSBub24gdmFsaWRlLiJ9LAotCi0gICAgeyBFUl9FUlJPUkxJU1RFTkVSLAotICAgICAiRXJyb3JMaXN0ZW5lciJ9LAotCi0KLS8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2Ugc2hvdWxkIG5vdCBub3JtYWxseSBiZSBkaXNwbGF5ZWQKLS8vICAgdG8gdXNlcnMuICBJdCBkZXNjcmliZXMgYSBzaXR1YXRpb24gaW4gd2hpY2ggdGhlIHByb2Nlc3NvciBoYXMgZGV0ZWN0ZWQKLS8vICAgYW4gaW50ZXJuYWwgY29uc2lzdGVuY3kgcHJvYmxlbSBpbiBpdHNlbGYsIGFuZCBpdCBwcm92aWRlcyB0aGlzIG1lc3NhZ2UKLS8vICAgZm9yIHRoZSBkZXZlbG9wZXIgdG8gaGVscCBkaWFnbm9zZSB0aGUgcHJvYmxlbS4gIFRoZSBuYW1lCi0vLyAgICdFbGVtVGVtcGxhdGVFbGVtZW50JyBpcyB0aGUgbmFtZSBvZiBhIGNsYXNzLCBhbmQgc2hvdWxkIG5vdCBiZQotLy8gICB0cmFuc2xhdGVkLgotICAgIHsgRVJfQVNTRVJUX05PX1RFTVBMQVRFX1BBUkVOVCwKLSAgICAgIkVycmV1ciBkdSBwcm9ncmFtbWV1ci4gTCdleHByZXNzaW9uIG4nYSBwYXMgZGUgcGFyZW50IEVsZW1UZW1wbGF0ZUVsZW1lbnQuIn0sCi0KLQotLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBzaG91bGQgbm90IG5vcm1hbGx5IGJlIGRpc3BsYXllZAotLy8gICB0byB1c2Vycy4gIEl0IGRlc2NyaWJlcyBhIHNpdHVhdGlvbiBpbiB3aGljaCB0aGUgcHJvY2Vzc29yIGhhcyBkZXRlY3RlZAotLy8gICBhbiBpbnRlcm5hbCBjb25zaXN0ZW5jeSBwcm9ibGVtIGluIGl0c2VsZiwgYW5kIGl0IHByb3ZpZGVzIHRoaXMgbWVzc2FnZQotLy8gICBmb3IgdGhlIGRldmVsb3BlciB0byBoZWxwIGRpYWdub3NlIHRoZSBwcm9ibGVtLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0vLyAgIHByb3ZpZGVzIGZ1cnRoZXIgaW5mb3JtYXRpb24gaW4gb3JkZXIgdG8gZGlhZ25vc2UgdGhlIHByb2JsZW0uICBUaGUgbmFtZQotLy8gICAnUmVkdW5kZW50RXhwckVsaW1pbmF0b3InIGlzIHRoZSBuYW1lIG9mIGEgY2xhc3MsIGFuZCBzaG91bGQgbm90IGJlCi0vLyAgIHRyYW5zbGF0ZWQuCi0gICAgeyBFUl9BU1NFUlRfUkVEVU5ERU5UX0VYUFJfRUxJTUlOQVRPUiwKLSAgICAgIkFzc2VydGlvbiBkdSBwcm9ncmFtbWV1ciBkYW5zIFJlZHVuZGVudEV4cHJFbGltaW5hdG9yIDogezB9In0sCi0KLSAgICB7IEVSX05PVF9BTExPV0VEX0lOX1BPU0lUSU9OLAotICAgICAiezB9IG4nJ2VzdCBwYXMgYXV0b3Jpc1x1MDBFOSBcdTAwRTAgY2V0IGVtcGxhY2VtZW50IGRlIGxhIGZldWlsbGUgZGUgc3R5bGUuIn0sCi0KLSAgICB7IEVSX05PTldISVRFU1BBQ0VfTk9UX0FMTE9XRURfSU5fUE9TSVRJT04sCi0gICAgICJMZSB0ZXh0ZSBpbXByaW1hYmxlIG4nZXN0IHBhcyBhdXRvcmlzXHUwMEU5IFx1MDBFMCBjZXQgZW1wbGFjZW1lbnQgZGUgbGEgZmV1aWxsZSBkZSBzdHlsZS4ifSwKLQotICAvLyBUaGlzIGNvZGUgaXMgc2hhcmVkIHdpdGggd2FybmluZyBjb2Rlcy4KLSAgLy8gU3lzdGVtSWQgVW5rbm93bgotICAgIHsgSU5WQUxJRF9UQ0hBUiwKLSAgICAgIlZhbGV1ciBub24gYWRtaXNlIHsxfSB1dGlsaXNcdTAwRTllIHBvdXIgbCcnYXR0cmlidXQgQ0hBUiA6IHswfS4gVW4gYXR0cmlidXQgZGUgdHlwZSBDSEFSIG5lIGRvaXQgXHUwMEVBdHJlIGNvbXBvc1x1MDBFOSBxdWUgZCcndW4gY2FyYWN0XHUwMEU4cmUuIn0sCi0KLSAgICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIGlzIHVzZWQgaWYgdGhlIHZhbHVlIG9mCi0gICAgLy8gYW4gYXR0cmlidXRlIGluIGEgc3R5bGVzaGVldCBpcyBpbnZhbGlkLiAgIlFOQU1FIiBpcyB0aGUgWE1MIGRhdGEtdHlwZSBvZgotICAgIC8vIHRoZSBhdHRyaWJ1dGUsIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgezF9IGlzCi0gICAgLy8gdGhlIGF0dHJpYnV0ZSB2YWx1ZSBhbmQgezB9IGlzIHRoZSBhdHRyaWJ1dGUgbmFtZS4KLSAgLy9UaGUgZm9sbG93aW5nIGNvZGVzIGFyZSBzaGFyZWQgd2l0aCB0aGUgd2FybmluZyBjb2Rlcy4uLgotICAgIHsgSU5WQUxJRF9RTkFNRSwKLSAgICAgIlZhbGV1ciBub24gYWRtaXNlIHsxfSB1dGlsaXNcdTAwRTllIHBvdXIgbCcnYXR0cmlidXQgUU5BTUUgOiB7MH0ifSwKLQotICAgIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgaXMgdXNlZCBpZiB0aGUgdmFsdWUgb2YKLSAgICAvLyBhbiBhdHRyaWJ1dGUgaW4gYSBzdHlsZXNoZWV0IGlzIGludmFsaWQuICAiRU5VTSIgaXMgdGhlIFhNTCBkYXRhLXR5cGUgb2YKLSAgICAvLyB0aGUgYXR0cmlidXRlLCBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHsxfSBpcwotICAgIC8vIHRoZSBhdHRyaWJ1dGUgdmFsdWUsIHswfSBpcyB0aGUgYXR0cmlidXRlIG5hbWUsIGFuZCB7Mn0gaXMgYSBsaXN0IG9mIHZhbGlkCi0gICAgLy8gdmFsdWVzLgotICAgIHsgSU5WQUxJRF9FTlVNLAotICAgICAiVmFsZXVyIG5vbiBhZG1pc2UgezF9IHV0aWxpc1x1MDBFOWUgcG91ciBsJydhdHRyaWJ1dCBFTlVNIDogezB9LiBMZXMgdmFsZXVycyB2YWxpZGVzIHNvbnQgbGVzIHN1aXZhbnRlcyA6IHsyfS4ifSwKLQotLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBpcyB1c2VkIGlmIHRoZSB2YWx1ZSBvZgotLy8gYW4gYXR0cmlidXRlIGluIGEgc3R5bGVzaGVldCBpcyBpbnZhbGlkLiAgIk5NVE9LRU4iIGlzIHRoZSBYTUwgZGF0YS10eXBlCi0vLyBvZiB0aGUgYXR0cmlidXRlLCBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHsxfSBpcwotLy8gdGhlIGF0dHJpYnV0ZSB2YWx1ZSBhbmQgezB9IGlzIHRoZSBhdHRyaWJ1dGUgbmFtZS4KLSAgICB7IElOVkFMSURfTk1UT0tFTiwKLSAgICAgIlZhbGV1ciBub24gYWRtaXNlIHsxfSB1dGlsaXNcdTAwRTllIHBvdXIgbCcnYXR0cmlidXQgTk1UT0tFTiA6IHswfSAifSwKLQotLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBpcyB1c2VkIGlmIHRoZSB2YWx1ZSBvZgotLy8gYW4gYXR0cmlidXRlIGluIGEgc3R5bGVzaGVldCBpcyBpbnZhbGlkLiAgIk5DTkFNRSIgaXMgdGhlIFhNTCBkYXRhLXR5cGUKLS8vIG9mIHRoZSBhdHRyaWJ1dGUsIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgezF9IGlzCi0vLyB0aGUgYXR0cmlidXRlIHZhbHVlIGFuZCB7MH0gaXMgdGhlIGF0dHJpYnV0ZSBuYW1lLgotICAgIHsgSU5WQUxJRF9OQ05BTUUsCi0gICAgICJWYWxldXIgbm9uIGFkbWlzZSB7MX0gdXRpbGlzXHUwMEU5ZSBwb3VyIGwnJ2F0dHJpYnV0IE5DTkFNRSA6IHswfSAifSwKLQotLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBpcyB1c2VkIGlmIHRoZSB2YWx1ZSBvZgotLy8gYW4gYXR0cmlidXRlIGluIGEgc3R5bGVzaGVldCBpcyBpbnZhbGlkLiAgImJvb2xlYW4iIGlzIHRoZSBYU0xUIGRhdGEtdHlwZQotLy8gb2YgdGhlIGF0dHJpYnV0ZSwgYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCB7MX0gaXMKLS8vIHRoZSBhdHRyaWJ1dGUgdmFsdWUgYW5kIHswfSBpcyB0aGUgYXR0cmlidXRlIG5hbWUuCi0gICAgeyBJTlZBTElEX0JPT0xFQU4sCi0gICAgICJWYWxldXIgbm9uIGFkbWlzZSB7MX0gdXRpbGlzXHUwMEU5ZSBwb3VyIGwnJ2F0dHJpYnV0IFwiYm9vbGVhblwiIDogezB9ICJ9LAotCi0vLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIGlzIHVzZWQgaWYgdGhlIHZhbHVlIG9mCi0vLyBhbiBhdHRyaWJ1dGUgaW4gYSBzdHlsZXNoZWV0IGlzIGludmFsaWQuICAibnVtYmVyIiBpcyB0aGUgWFNMVCBkYXRhLXR5cGUKLS8vIG9mIHRoZSBhdHRyaWJ1dGUsIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgezF9IGlzCi0vLyB0aGUgYXR0cmlidXRlIHZhbHVlIGFuZCB7MH0gaXMgdGhlIGF0dHJpYnV0ZSBuYW1lLgotICAgICB7IElOVkFMSURfTlVNQkVSLAotICAgICAiVmFsZXVyIG5vbiBhZG1pc2UgezF9IHV0aWxpc1x1MDBFOWUgcG91ciBsJydhdHRyaWJ1dCBcIm51bWJlclwiIDogezB9ICJ9LAotCi0KLSAgLy8gRW5kIG9mIHNoYXJlZCBjb2Rlcy4uLgotCi0vLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQSAibWF0Y2ggcGF0dGVybiIgaXMgYSBzcGVjaWFsIGZvcm0gb2YgWFBhdGggZXhwcmVzc2lvbgotLy8gdGhhdCBpcyB1c2VkIGZvciBtYXRjaGluZyBwYXR0ZXJucy4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZgotLy8gYSBmdW5jdGlvbi4gIFRoZSBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHdoZW4gdGhpcyBmdW5jdGlvbiBpcyByZWZlcmVuY2VkIGluCi0vLyBhIG1hdGNoIHBhdHRlcm4sIGl0cyBhcmd1bWVudCBtdXN0IGJlIGEgc3RyaW5nIGxpdGVyYWwgKG9yIGNvbnN0YW50LikKLS8vIEVSX0FSR19MSVRFUkFMIC0gbmV3IGVycm9yIG1lc3NhZ2UgZm9yIGJ1Z3ppbGxhIC8vNTIwMgotICAgIHsgRVJfQVJHX0xJVEVSQUwsCi0gICAgICJMJydhcmd1bWVudCBwb3VyIHswfSBkYW5zIGxlIG1vZFx1MDBFOGxlIGRlIHJlY2hlcmNoZSBkb2l0IFx1MDBFQXRyZSB1biBsaXR0XHUwMEU5cmFsLiJ9LAotCi0vLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHR3byBkZWZpbml0aW9ucyBvZgotLy8gYSB2YXJpYWJsZS4gIEEgImdsb2JhbCB2YXJpYWJsZSIgaXMgYSB2YXJpYWJsZSB0aGF0IGlzIGFjY2Vzc2libGUgZXZlcnl3aGVyCi0vLyBpbiB0aGUgc3R5bGVzaGVldC4KLS8vIEVSX0RVUExJQ0FURV9HTE9CQUxfVkFSIC0gbmV3IGVycm9yIG1lc3NhZ2UgZm9yIGJ1Z3ppbGxhICM3OTAKLSAgICB7IEVSX0RVUExJQ0FURV9HTE9CQUxfVkFSLAotICAgICAiRFx1MDBFOWNsYXJhdGlvbiBkZSB2YXJpYWJsZSBnbG9iYWxlIGVuIGRvdWJsZS4ifSwKLQotCi0vLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHR3byBkZWZpbml0aW9ucyBvZgotLy8gYSB2YXJpYWJsZSB3ZXJlIGVuY291bnRlcmVkLgotLy8gRVJfRFVQTElDQVRFX1ZBUiAtIG5ldyBlcnJvciBtZXNzYWdlIGZvciBidWd6aWxsYSAjNzkwCi0gICAgeyBFUl9EVVBMSUNBVEVfVkFSLAotICAgICAiRFx1MDBFOWNsYXJhdGlvbiBkZSB2YXJpYWJsZSBlbiBkb3VibGUuIn0sCi0KLSAgICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgInhzbDp0ZW1wbGF0ZSwgIm5hbWUiIGFuZCAibWF0Y2giIGFyZSBYU0xUIGtleXdvcmRzCi0gICAgLy8gd2hpY2ggbXVzdCBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICAvLyBFUl9URU1QTEFURV9OQU1FX01BVENIIC0gbmV3IGVycm9yIG1lc3NhZ2UgZm9yIGJ1Z3ppbGxhICM3ODkKLSAgICB7IEVSX1RFTVBMQVRFX05BTUVfTUFUQ0gsCi0gICAgICJ4c2w6dGVtcGxhdGUgZG9pdCBhdm9pciB1biBhdHRyaWJ1dCBcIm5hbWVcIiBvdSBcIm1hdGNoXCIgKG91IGxlcyBkZXV4KSJ9LAotCi0gICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogICJleGNsdWRlLXJlc3VsdC1wcmVmaXhlcyIgaXMgYW4gWFNMVCBrZXl3b3JkIHdoaWNoCi0gICAgLy8gc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgYSBuYW1lc3BhY2UgcHJlZml4Ci0gICAgLy8gZW5jb3VudGVyZWQgYXMgcGFydCBvZiB0aGUgdmFsdWUgb2YgdGhlIGV4Y2x1ZGUtcmVzdWx0LXByZWZpeGVzIGF0dHJpYnV0ZQotICAgIC8vIHdhcyBpbiBlcnJvci4KLSAgICAvLyBFUl9JTlZBTElEX1BSRUZJWCAtIG5ldyBlcnJvciBtZXNzYWdlIGZvciBidWd6aWxsYSAjNzg4Ci0gICAgeyBFUl9JTlZBTElEX1BSRUZJWCwKLSAgICAgIkxlIHByXHUwMEU5Zml4ZSBkZSBsJydcdTAwRTlsXHUwMEU5bWVudCBleGNsdWRlLXJlc3VsdC1wcmVmaXhlcyBuJydlc3QgcGFzIHZhbGlkZSA6IHswfSJ9LAotCi0gICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIEFuICJhdHRyaWJ1dGUgc2V0IiBpcyBhIHNldCBvZiBhdHRyaWJ1dGVzIHRoYXQgY2FuCi0gICAgLy8gYmUgYWRkZWQgdG8gYW4gZWxlbWVudCBpbiB0aGUgb3V0cHV0IGRvY3VtZW50IGFzIGEgZ3JvdXAuICBUaGUgbWVzc2FnZQotICAgIC8vIGluZGljYXRlcyB0aGF0IHRoZXJlIHdhcyBhIHJlZmVyZW5jZSB0byBhbiBhdHRyaWJ1dGUgc2V0IG5hbWVkIHswfSB0aGF0Ci0gICAgLy8gd2FzIG5ldmVyIGRlZmluZWQuCi0gICAgLy8gRVJfTk9fQVRUUklCX1NFVCAtIG5ldyBlcnJvciBtZXNzYWdlIGZvciBidWd6aWxsYSAjNzgyCi0gICAgeyBFUl9OT19BVFRSSUJfU0VULAotICAgICAiTCcnZW5zZW1ibGUgZCcnYXR0cmlidXRzIG5vbW1cdTAwRTkgezB9IG4nJ2V4aXN0ZSBwYXMifSwKLQotICAgIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhlcmUgd2FzIGEgcmVmZXJlbmNlCi0gICAgLy8gdG8gYSBmdW5jdGlvbiBuYW1lZCB7MH0gZm9yIHdoaWNoIG5vIGZ1bmN0aW9uIGRlZmluaXRpb24gY291bGQgYmUgZm91bmQuCi0gICAgeyBFUl9GVU5DVElPTl9OT1RfRk9VTkQsCi0gICAgICJMYSBmb25jdGlvbiBub21tXHUwMEU5ZSB7MH0gbicnZXhpc3RlIHBhcyJ9LAotCi0gICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUgWFNMVCBpbnN0cnVjdGlvbgotICAgIC8vIHRoYXQgaXMgbmFtZWQgYnkgdGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHswfSBtdXN0IG5vdCBjb250YWluIG90aGVyIFhTTFQKLSAgICAvLyBpbnN0cnVjdGlvbnMgKGNvbnRlbnQpIG9yIGEgInNlbGVjdCIgYXR0cmlidXRlLiAgVGhlIHdvcmQgInNlbGVjdCIgaXMKLSAgICAvLyBhbiBYU0xUIGtleXdvcmQgaW4gdGhpcyBjYXNlIGFuZCBtdXN0IG5vdCBiZSB0cmFuc2xhdGVkLgotICAgIHsgRVJfQ0FOVF9IQVZFX0NPTlRFTlRfQU5EX1NFTEVDVCwKLSAgICAgIkwnJ1x1MDBFOWxcdTAwRTltZW50IHswfSBuZSBkb2l0IHBhcyBhdm9pciBcdTAwRTAgbGEgZm9pcyB1biBhdHRyaWJ1dCBcInNlbGVjdFwiIGV0IHVuIGF0dHJpYnV0IGRlIGNvbnRlbnUuIn0sCi0KLSAgICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoZSB2YWx1ZSBhcmd1bWVudAotICAgIC8vIG9mIHNldFBhcmFtZXRlciBtdXN0IGJlIGEgdmFsaWQgSmF2YSBPYmplY3QuCi0gICAgeyBFUl9JTlZBTElEX1NFVF9QQVJBTV9WQUxVRSwKLSAgICAgIkxhIHZhbGV1ciBkdSBwYXJhbVx1MDBFOHRyZSB7MH0gZG9pdCBcdTAwRUF0cmUgdW4gb2JqZXQgSmF2YSB2YWxpZGUifSwKLQotICAgIHsgRVJfSU5WQUxJRF9OQU1FU1BBQ0VfVVJJX1ZBTFVFX0ZPUl9SRVNVTFRfUFJFRklYX0ZPUl9ERUZBVUxULAotICAgICAgIkwnYXR0cmlidXQgcmVzdWx0LXByZWZpeCBkJ3VuIFx1MDBFOWxcdTAwRTltZW50IHhzbDpuYW1lc3BhY2UtYWxpYXMgYSBsYSB2YWxldXIgXCIjZGVmYXVsdFwiLCBtYWlzIGlsIG4nZXhpc3RlIGF1Y3VuZSBkXHUwMEU5Y2xhcmF0aW9uIGRlIGwnZXNwYWNlIGRlIG5vbXMgcGFyIGRcdTAwRTlmYXV0IGRhbnMgbGEgcG9ydFx1MDBFOWUgcG91ciBsJ1x1MDBFOWxcdTAwRTltZW50In0sCi0KLSAgICB7IEVSX0lOVkFMSURfTkFNRVNQQUNFX1VSSV9WQUxVRV9GT1JfUkVTVUxUX1BSRUZJWCwKLSAgICAgICJMJydhdHRyaWJ1dCByZXN1bHQtcHJlZml4IGQnJ3VuIFx1MDBFOWxcdTAwRTltZW50IHhzbDpuYW1lc3BhY2UtYWxpYXMgYSBsYSB2YWxldXIgJyd7MH0nJywgbWFpcyBpbCBuJydleGlzdGUgYXVjdW5lIGRcdTAwRTljbGFyYXRpb24gZCcnZXNwYWNlIGRlIG5vbXMgcG91ciBsZSBwclx1MDBFOWZpeGUgJyd7MH0nJyBkYW5zIGxhIHBvcnRcdTAwRTllIHBvdXIgbCcnXHUwMEU5bFx1MDBFOW1lbnQuIn0sCi0KLSAgICB7IEVSX1NFVF9GRUFUVVJFX05VTExfTkFNRSwKLSAgICAgICJMZSBub20gZGUgbGEgZm9uY3Rpb25uYWxpdFx1MDBFOSBuZSBwZXV0IHBhcyBcdTAwRUF0cmUgTlVMTCBkYW5zIFRyYW5zZm9ybWVyRmFjdG9yeS5zZXRGZWF0dXJlIChjaGFcdTAwRUVuZSBwb3VyIGxlIG5vbSwgdmFsZXVyIGJvb2xcdTAwRTllbm5lKS4ifSwKLQotICAgIHsgRVJfR0VUX0ZFQVRVUkVfTlVMTF9OQU1FLAotICAgICAgIkxlIG5vbSBkZSBsYSBmb25jdGlvbm5hbGl0XHUwMEU5IG5lIHBldXQgcGFzIFx1MDBFQXRyZSBOVUxMIGRhbnMgVHJhbnNmb3JtZXJGYWN0b3J5LmdldEZlYXR1cmUgKGNoYVx1MDBFRW5lIHBvdXIgbGUgbm9tKS4ifSwKLQotICAgIHsgRVJfVU5TVVBQT1JURURfRkVBVFVSRSwKLSAgICAgICJJbXBvc3NpYmxlIGRlIGRcdTAwRTlmaW5pciBsYSBmb25jdGlvbm5hbGl0XHUwMEU5ICcnezB9Jycgc3VyIGNldHRlIHByb3ByaVx1MDBFOXRcdTAwRTkgVHJhbnNmb3JtZXJGYWN0b3J5LiJ9LAotCi0gICAgeyBFUl9FWFRFTlNJT05fRUxFTUVOVF9OT1RfQUxMT1dFRF9JTl9TRUNVUkVfUFJPQ0VTU0lORywKLSAgICAgICAgICAiTCcndXRpbGlzYXRpb24gZGUgbCcnXHUwMEU5bFx1MDBFOW1lbnQgZCcnZXh0ZW5zaW9uICcnezB9JycgbicnZXN0IHBhcyBhdXRvcmlzXHUwMEU5ZSBsb3JzcXVlIGxhIGZvbmN0aW9ubmFsaXRcdTAwRTkgZGUgdHJhaXRlbWVudCBzXHUwMEU5Y3VyaXNcdTAwRTkgZXN0IGRcdTAwRTlmaW5pZSBzdXIgVHJ1ZS4ifSwKLQotICAgIHsgRVJfTkFNRVNQQUNFX0NPTlRFWFRfTlVMTF9OQU1FU1BBQ0UsCi0gICAgICAiSW1wb3NzaWJsZSBkJ29idGVuaXIgbGUgcHJcdTAwRTlmaXhlIHBvdXIgdW4gVVJJIGQnZXNwYWNlIGRlIG5vbXMgTlVMTC4ifSwKLQotICAgIHsgRVJfTkFNRVNQQUNFX0NPTlRFWFRfTlVMTF9QUkVGSVgsCi0gICAgICAiSW1wb3NzaWJsZSBkJ29idGVuaXIgbCdVUkkgZCdlc3BhY2UgZGUgbm9tcyBwb3VyIGxlIHByXHUwMEU5Zml4ZSBOVUxMLiJ9LAotCi0gICAgeyBFUl9YUEFUSF9SRVNPTFZFUl9OVUxMX1FOQU1FLAotICAgICAgIkxlIG5vbSBkZSBmb25jdGlvbiBuZSBwZXV0IHBhcyBcdTAwRUF0cmUgTlVMTC4ifSwKLQotICAgIHsgRVJfWFBBVEhfUkVTT0xWRVJfTkVHQVRJVkVfQVJJVFksCi0gICAgICAiTCdhcml0XHUwMEU5IG5lIHBldXQgcGFzIFx1MDBFQXRyZSBuXHUwMEU5Z2F0aXZlLiJ9LAotICAvLyBXYXJuaW5ncy4uLgotCi0gICAgeyBXR19GT1VORF9DVVJMWUJSQUNFLAotICAgICAgIid9JyB0cm91dlx1MDBFOSBtYWlzIGF1Y3VuIG1vZFx1MDBFOGxlIGQnYXR0cmlidXQgb3V2ZXJ0LiJ9LAotCi0gICAgeyBXR19DT1VOVF9BVFRSSUJfTUFUQ0hFU19OT19BTkNFU1RPUiwKLSAgICAgICJBdmVydGlzc2VtZW50IDogbCcnYXR0cmlidXQgXCJjb3VudFwiIG5lIGNvcnJlc3BvbmQgcGFzIFx1MDBFMCB1biBhbmNcdTAwRUF0cmUgZGFucyB4c2w6bnVtYmVyICEgQ2libGUgPSB7MH0ifSwKLQotICAgIHsgV0dfRVhQUl9BVFRSSUJfQ0hBTkdFRF9UT19TRUxFQ1QsCi0gICAgICAiQW5jaWVubmUgc3ludGF4ZSA6IGxlIG5vbSBkZSBsJ2F0dHJpYnV0IFwiZXhwclwiIGEgXHUwMEU5dFx1MDBFOSBtb2RpZmlcdTAwRTkgZW4gXCJzZWxlY3RcIi4ifSwKLQotICAgIHsgV0dfTk9fTE9DQUxFX0lOX0ZPUk1BVE5VTUJFUiwKLSAgICAgICJYYWxhbiBuZSBnXHUwMEU4cmUgcGFzIGVuY29yZSBsZSBub20gZGUgbCdlbnZpcm9ubmVtZW50IGxvY2FsIGRhbnMgbGEgZm9uY3Rpb24gZm9ybWF0LW51bWJlci4ifSwKLQotICAgIHsgV0dfTE9DQUxFX05PVF9GT1VORCwKLSAgICAgICJBdmVydGlzc2VtZW50IDogZW52aXJvbm5lbWVudCBsb2NhbCBpbnRyb3V2YWJsZSBwb3VyIHhtbDpsYW5nPXswfSJ9LAotCi0gICAgeyBXR19DQU5OT1RfTUFLRV9VUkxfRlJPTSwKLSAgICAgICJJbXBvc3NpYmxlIGRlIGNyXHUwMEU5ZXIgdW5lIFVSTCBcdTAwRTAgcGFydGlyIGRlIDogezB9In0sCi0KLSAgICB7IFdHX0NBTk5PVF9MT0FEX1JFUVVFU1RFRF9ET0MsCi0gICAgICAiSW1wb3NzaWJsZSBkZSBjaGFyZ2VyIGxlIGRvY3VtZW50IGRlbWFuZFx1MDBFOSA6IHswfSJ9LAotCi0gICAgeyBXR19DQU5OT1RfRklORF9DT0xMQVRPUiwKLSAgICAgICJDb2xsYXRvciBpbnRyb3V2YWJsZSBwb3VyIDxzb3J0IHhtbDpsYW5nPXswfSJ9LAotCi0gICAgeyBXR19GVU5DVElPTlNfU0hPVUxEX1VTRV9VUkwsCi0gICAgICAiQW5jaWVubmUgc3ludGF4ZSA6IGwnJ2luc3RydWN0aW9uIGRlIGxhIGZvbmN0aW9uIGRvaXQgdXRpbGlzZXIgdW5lIFVSTCBkZSB7MH0ifSwKLQotICAgIHsgV0dfRU5DT0RJTkdfTk9UX1NVUFBPUlRFRF9VU0lOR19VVEY4LAotICAgICAgImVuY29kYWdlIG5vbiBwcmlzIGVuIGNoYXJnZSA6IHswfSwgYXZlYyBVVEYtOCJ9LAotCi0gICAgeyBXR19FTkNPRElOR19OT1RfU1VQUE9SVEVEX1VTSU5HX0pBVkEsCi0gICAgICAiZW5jb2RhZ2Ugbm9uIHByaXMgZW4gY2hhcmdlIDogezB9LCBhdmVjIEphdmEgezF9In0sCi0KLSAgICB7IFdHX1NQRUNJRklDSVRZX0NPTkZMSUNUUywKLSAgICAgICJDb25mbGl0cyBkZSBzcFx1MDBFOWNpZmljaXRcdTAwRTkgZFx1MDBFOXRlY3RcdTAwRTlzIDogezB9IExlcyBkZXJuaWVycyBcdTAwRTlsXHUwMEU5bWVudHMgdHJvdXZcdTAwRTlzIGRhbnMgbGEgZmV1aWxsZSBkZSBzdHlsZSBzZXJvbnQgdXRpbGlzXHUwMEU5cy4ifSwKLQotICAgIHsgV0dfUEFSU0lOR19BTkRfUFJFUEFSSU5HLAotICAgICAgIj09PT09PT09PSBBbmFseXNlIGV0IHByXHUwMEU5cGFyYXRpb24gZGUgezB9ID09PT09PT09PT0ifSwKLQotICAgIHsgV0dfQVRUUl9URU1QTEFURSwKLSAgICAgIk1vZFx1MDBFOGxlIGF0dHIsIHswfSJ9LAotCi0gICAgeyBXR19DT05GTElDVF9CRVRXRUVOX1hTTFNUUklQU1BBQ0VfQU5EX1hTTFBSRVNFUlZFU1BBQ0UsCi0gICAgICAiQ29uZmxpdCBkZSBjb3JyZXNwb25kYW5jZSBlbnRyZSB4c2w6c3RyaXAtc3BhY2UgZXQgeHNsOnByZXNlcnZlLXNwYWNlIn0sCi0KLSAgICB7IFdHX0FUVFJJQl9OT1RfSEFORExFRCwKLSAgICAgICJYYWxhbiBuZSBnXHUwMEU4cmUgcGFzIGVuY29yZSBsJydhdHRyaWJ1dCB7MH0uIn0sCi0KLSAgICB7IFdHX05PX0RFQ0lNQUxGT1JNQVRfREVDTEFSQVRJT04sCi0gICAgICAiQXVjdW5lIGRcdTAwRTljbGFyYXRpb24gdHJvdXZcdTAwRTllIHBvdXIgbGUgZm9ybWF0IGRcdTAwRTljaW1hbCA6IHswfSJ9LAotCi0gICAgeyBXR19PTERfWFNMVF9OUywKLSAgICAgIkVzcGFjZSBkZSBub21zIFhTTFQgaW5jb3JyZWN0IG91IG1hbnF1YW50LiAifSwKLQotICAgIHsgV0dfT05FX0RFRkFVTFRfWFNMREVDSU1BTEZPUk1BVF9BTExPV0VELAotICAgICAgIlVuZSBzZXVsZSBkXHUwMEU5Y2xhcmF0aW9uIHhzbDpkZWNpbWFsLWZvcm1hdCBwYXIgZFx1MDBFOWZhdXQgZXN0IGF1dG9yaXNcdTAwRTllLiJ9LAotCi0gICAgeyBXR19YU0xERUNJTUFMRk9STUFUX05BTUVTX01VU1RfQkVfVU5JUVVFLAotICAgICAgIkxlcyBub21zIHhzbDpkZWNpbWFsLWZvcm1hdCBkb2l2ZW50IFx1MDBFQXRyZSB1bmlxdWVzLiBMZSBub20gXCJ7MH1cIiBhIFx1MDBFOXRcdTAwRTkgZHVwbGlxdVx1MDBFOS4ifSwKLQotICAgIHsgV0dfSUxMRUdBTF9BVFRSSUJVVEUsCi0gICAgICAiezB9IGEgdW4gYXR0cmlidXQgbm9uIGFkbWlzIDogezF9In0sCi0KLSAgICB7IFdHX0NPVUxEX05PVF9SRVNPTFZFX1BSRUZJWCwKLSAgICAgICJJbXBvc3NpYmxlIGRlIHJcdTAwRTlzb3VkcmUgbGUgcHJcdTAwRTlmaXhlIGQnJ2VzcGFjZSBkZSBub21zIDogezB9LiBMZSBub2V1ZCBuZSBzZXJhIHBhcyBwcmlzIGVuIGNvbXB0ZS4ifSwKLQotICAgIHsgV0dfU1RZTEVTSEVFVF9SRVFVSVJFU19WRVJTSU9OX0FUVFJJQiwKLSAgICAgICJ4c2w6c3R5bGVzaGVldCBleGlnZSB1biBhdHRyaWJ1dCBkZSB2ZXJzaW9uLiJ9LAotCi0gICAgeyBXR19JTExFR0FMX0FUVFJJQlVURV9OQU1FLAotICAgICAgIk5vbSBkJydhdHRyaWJ1dCBub24gYWRtaXMgOiB7MH0ifSwKLQotICAgIHsgV0dfSUxMRUdBTF9BVFRSSUJVVEVfVkFMVUUsCi0gICAgICAiVmFsZXVyIG5vbiBhZG1pc2UgdXRpbGlzXHUwMEU5ZSBwb3VyIGwnJ2F0dHJpYnV0IHswfSA6IHsxfSJ9LAotCi0gICAgeyBXR19FTVBUWV9TRUNPTkRfQVJHLAotICAgICAgIkxlIGpldSBkZSBub2V1ZHMgclx1MDBFOXN1bHRhbnQgZHUgZGV1eGlcdTAwRThtZSBhcmd1bWVudCBkZSBsYSBmb25jdGlvbiBkZSBkb2N1bWVudCBlc3QgdmlkZS4gUmVudm95ZXogdW4gamV1IGRlIG5vZXVkcyB2aWRlLiJ9LAotCi0gIC8vRm9sbG93aW5nIGFyZSB0aGUgbmV3IFdBUk5JTkcga2V5cyBhZGRlZCBpbiBYQUxBTiBjb2RlIGJhc2UgYWZ0ZXIgSmRrIDEuNCAoWGFsYW4gMi4yLUQxMSkKLQotICAgIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAibmFtZSIgYW5kICJ4c2w6cHJvY2Vzc2luZy1pbnN0cnVjdGlvbiIgYXJlIGtleXdvcmRzCi0gICAgLy8gYW5kIG11c3Qgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgeyBXR19QUk9DRVNTSU5HSU5TVFJVQ1RJT05fTkFNRV9DQU5UX0JFX1hNTCwKLSAgICAgICJMYSB2YWxldXIgZGUgbCdhdHRyaWJ1dCBcIm5hbWVcIiBkdSBub20geHNsOnByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24gbmUgZG9pdCBwYXMgXHUwMEVBdHJlIFwieG1sXCIifSwKLQotICAgIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAibmFtZSIgYW5kICJ4c2w6cHJvY2Vzc2luZy1pbnN0cnVjdGlvbiIgYXJlIGtleXdvcmRzCi0gICAgLy8gYW5kIG11c3Qgbm90IGJlIHRyYW5zbGF0ZWQuICAiTkNOYW1lIiBpcyBhbiBYTUwgZGF0YS10eXBlIGFuZCBtdXN0IG5vdCBiZQotICAgIC8vIHRyYW5zbGF0ZWQuCi0gICAgeyBXR19QUk9DRVNTSU5HSU5TVFJVQ1RJT05fTk9UVkFMSURfTkNOQU1FLAotICAgICAgIkxhIHZhbGV1ciBkZSBsJydhdHRyaWJ1dCAnJ25hbWUnJyBkZSB4c2w6cHJvY2Vzc2luZy1pbnN0cnVjdGlvbiBkb2l0IFx1MDBFQXRyZSB1biBOQ05hbWUgdmFsaWRlIDogezB9In0sCi0KLSAgICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIHJlcG9ydGVkIGlmIHRoZSBzdHlsZXNoZWV0IHRoYXQgaXMKLSAgICAvLyBiZWluZyBwcm9jZXNzZWQgYXR0ZW1wdGVkIHRvIGNvbnN0cnVjdCBhbiBYTUwgZG9jdW1lbnQgd2l0aCBhbiBhdHRyaWJ1dGUgaW4gYQotICAgIC8vIHBsYWNlIG90aGVyIHRoYW4gb24gYW4gZWxlbWVudC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBzcGVjaWZpZXMgdGhlIG5hbWUgb2YKLSAgICAvLyB0aGUgYXR0cmlidXRlLgotICAgIHsgV0dfSUxMRUdBTF9BVFRSSUJVVEVfUE9TSVRJT04sCi0gICAgICAiSW1wb3NzaWJsZSBkJydham91dGVyIGwnJ2F0dHJpYnV0IHswfSBhcHJcdTAwRThzIGRlcyBub2V1ZHMgZW5mYW50IG91IGF2YW50IGxhIHByb2R1Y3Rpb24gZCcndW4gXHUwMEU5bFx1MDBFOW1lbnQuIEwnJ2F0dHJpYnV0IGVzdCBpZ25vclx1MDBFOS4ifSwKLQotICAgIHsgTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSLAotICAgICAgIlVuZSB0ZW50YXRpdmUgZGUgbW9kaWZpY2F0aW9uIGQndW4gb2JqZXQgYSBcdTAwRTl0XHUwMEU5IGVmZmVjdHVcdTAwRTllIGFsb3JzIHF1ZSBsZXMgbW9kaWZpY2F0aW9ucyBuZSBzb250IHBhcyBhdXRvcmlzXHUwMEU5ZXMuIgotICAgIH0sCi0KLSAgICAvL0NoZWNrOiBXSFkgVEhFUkUgSVMgQSBHQVAgQi9XIE5VTUJFUlMgaW4gdGhlIFhTTFRFcnJvclJlc291cmNlcyBwcm9wZXJ0aWVzIGZpbGU/Ci0KLSAgLy8gT3RoZXIgbWlzY2VsbGFuZW91cyB0ZXh0IHVzZWQgaW5zaWRlIHRoZSBjb2RlLi4uCi0gIHsgInVpX2xhbmd1YWdlIiwgImZyIn0sCi0gIHsgICJoZWxwX2xhbmd1YWdlIiwgICJmciIgfSwKLSAgeyAgImxhbmd1YWdlIiwgICJmciIgfSwKLSAgeyAiQkFEX0NPREUiLCAiTGUgcGFyYW1cdTAwRTh0cmUgY3JlYXRlTWVzc2FnZSBcdTAwRTl0YWl0IGhvcnMgbGltaXRlcyJ9LAotICB7ICAiRk9STUFUX0ZBSUxFRCIsICJFeGNlcHRpb24gZ1x1MDBFOW5cdTAwRTlyXHUwMEU5ZSBwZW5kYW50IGwnYXBwZWwgbWVzc2FnZUZvcm1hdCJ9LAotICB7ICAidmVyc2lvbiIsICI+Pj4+Pj4+IFZlcnNpb24gWGFsYW4gIn0sCi0gIHsgICJ2ZXJzaW9uMiIsICAiPDw8PDw8PCJ9LAotICB7ICAieWVzIiwgIm91aSJ9LAotICB7ICJsaW5lIiwgIkxpZ25lIG5cdTAwQjAifSwKLSAgeyAiY29sdW1uIiwiQ29sb25uZSBuXHUwMEIwIn0sCi0gIHsgInhzbGRvbmUiLCAiWFNMUHJvY2Vzc29yIDogdGVybWluXHUwMEU5In0sCi0KLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlcyBwcm92aWRlIHVzYWdlIGluZm9ybWF0aW9uCi0gIC8vIGZvciB0aGUgWGFsYW4gUHJvY2VzcyBjb21tYW5kIGxpbmUuICAiUHJvY2VzcyIgaXMgdGhlIG5hbWUgb2YgYSBKYXZhIGNsYXNzLAotICAvLyBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLgotICB7ICJ4c2xQcm9jX29wdGlvbiIsICJPcHRpb25zIGRlIGNsYXNzZSBcIlByb2Nlc3NcIiBkZSBsaWduZSBkZSBjb21tYW5kZSBYYWxhbi1KIDoifSwKLSAgeyAieHNsUHJvY19vcHRpb24iLCAiT3B0aW9ucyBkZSBjbGFzc2UgXCJQcm9jZXNzXCIgZGUgbGlnbmUgZGUgY29tbWFuZGUgWGFsYW4tSiA6In0sCi0gIHsgInhzbFByb2NfaW52YWxpZF94c2x0Y19vcHRpb24iLCAiTCcnb3B0aW9uIHswfSBuJydlc3QgcGFzIHByaXNlIGVuIGNoYXJnZSBkYW5zIGxlIG1vZGUgWFNMVEMuIn0sCi0gIHsgInhzbFByb2NfaW52YWxpZF94YWxhbl9vcHRpb24iLCAiTCcnb3B0aW9uIHswfSBuZSBwZXV0IFx1MDBFQXRyZSB1dGlsaXNcdTAwRTllIHF1JydhdmVjIC1YU0xUQy4ifSwKLSAgeyAieHNsUHJvY19ub19pbnB1dCIsICJFcnJldXIgOiBhdWN1bmUgZmV1aWxsZSBkZSBzdHlsZSBvdSBhdWN1biBmaWNoaWVyIFhNTCBkJ2VudHJcdTAwRTllIG4nZXN0IHNwXHUwMEU5Y2lmaVx1MDBFOS4gRXhcdTAwRTljdXRleiBjZXR0ZSBjb21tYW5kZSBzYW5zIG9wdGlvbiBjb25jZXJuYW50IGxlcyBpbnN0cnVjdGlvbnMgZCd1dGlsaXNhdGlvbi4ifSwKLSAgeyAieHNsUHJvY19jb21tb25fb3B0aW9ucyIsICItT3B0aW9ucyBjb21tdW5lcy0ifSwKLSAgeyAieHNsUHJvY194YWxhbl9vcHRpb25zIiwgIi1PcHRpb25zIHBvdXIgWGFsYW4tIn0sCi0gIHsgInhzbFByb2NfeHNsdGNfb3B0aW9ucyIsICItT3B0aW9ucyBwb3VyIFhTTFRDLSJ9LAotICB7ICJ4c2xQcm9jX3JldHVybl90b19jb250aW51ZSIsICIoYXBwdXlleiBzdXIgbGEgdG91Y2hlIDxFbnRyXHUwMEU5ZT4gcG91ciBjb250aW51ZXIpIn0sCi0KLSAgIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6IFRoZSBvcHRpb24gbmFtZSBhbmQgdGhlIHBhcmFtZXRlciBuYW1lIGRvIG5vdCBuZWVkIHRvCi0gICAvLyBiZSB0cmFuc2xhdGVkLiBPbmx5IHRyYW5zbGF0ZSB0aGUgbWVzc2FnZXMgaW4gcGFyZW50aGVzZXMuICBOb3RlIGFsc28gdGhhdAotICAgLy8gbGVhZGluZyB3aGl0ZXNwYWNlIGluIHRoZSBtZXNzYWdlcyBpcyB1c2VkIHRvIGluZGVudCB0aGUgdXNhZ2UgaW5mb3JtYXRpb24KLSAgIC8vIGZvciBlYWNoIG9wdGlvbiBpbiB0aGUgRW5nbGlzaCBtZXNzYWdlcy4KLSAgIC8vIERvIG5vdCB0cmFuc2xhdGUgdGhlIGtleXdvcmRzOiBYU0xUQywgU0FYLCBET00gYW5kIERUTS4KLSAgeyAib3B0aW9uWFNMVEMiLCAiICAgWy1YU0xUQyAodXRpbGlzZXIgWFNMVEMgcG91ciBsYSB0cmFuc2Zvcm1hdGlvbildIn0sCi0gIHsgIm9wdGlvbklOIiwgIiAgIFstSU4gaW5wdXRYTUxVUkxdIn0sCi0gIHsgIm9wdGlvblhTTCIsICIgICBbLVhTTCBYU0xUcmFuc2Zvcm1hdGlvblVSTF0ifSwKLSAgeyAib3B0aW9uT1VUIiwgICIgICBbLU9VVCBvdXRwdXRGaWxlTmFtZV0ifSwKLSAgeyAib3B0aW9uTFhDSU4iLCAiICAgWy1MWENJTiBjb21waWxlZFN0eWxlc2hlZXRGaWxlTmFtZUluXSJ9LAotICB7ICJvcHRpb25MWENPVVQiLCAiICAgWy1MWENPVVQgY29tcGlsZWRTdHlsZXNoZWV0RmlsZU5hbWVPdXRPdXRdIn0sCi0gIHsgIm9wdGlvblBBUlNFUiIsICIgICBbTm9tIGRlIGNsYXNzZSBxdWFsaWZpXHUwMEU5IGNvbXBsZXQgLVBBUlNFUiBkZSBsaWFpc29uIGQnYW5hbHlzZXVyXSJ9LAotICB7ICAib3B0aW9uRSIsICIgICBbLUUgKE5lIHBhcyBkXHUwMEU5dmVsb3BwZXIgbGVzIHJcdTAwRTlmXHUwMEU5cmVuY2VzIGQnZW50aXRcdTAwRTkpXSJ9LAotICB7ICAib3B0aW9uViIsICAiICAgWy1FIChOZSBwYXMgZFx1MDBFOXZlbG9wcGVyIGxlcyByXHUwMEU5Zlx1MDBFOXJlbmNlcyBkJ2VudGl0XHUwMEU5KV0ifSwKLSAgeyAgIm9wdGlvblFDIiwgIiAgIFstUUMgKEF2ZXJ0aXNzZW1lbnRzIGRlIGNvbmZsaXRzIGRlIG1vZFx1MDBFOGxlcyBlbiBtb2RlIHNpbGVuY2lldXgpXSJ9LAotICB7ICAib3B0aW9uUSIsICIgICBbLVEgIChNb2RlIHNpbGVuY2lldXgpXSJ9LAotICB7ICAib3B0aW9uTEYiLCAiICAgWy1MRiAoVXRpbGlzZXIgbGVzIHJldG91cnMgXHUwMEUwIGxhIGxpZ25lIHVuaXF1ZW1lbnQgZW4gc29ydGllIHt2YWxldXIgcGFyIGRcdTAwRTlmYXV0IDogQ1IvTEZ9KV0ifSwKLSAgeyAgIm9wdGlvbkNSIiwgIiAgIFstQ1IgKFV0aWxpc2VyIGxlcyByZXRvdXJzIGNoYXJpb3QgdW5pcXVlbWVudCBlbiBzb3J0aWUge3ZhbGV1ciBwYXIgZFx1MDBFOWZhdXQgOiBDUi9MRn0pXSJ9LAotICB7ICJvcHRpb25FU0NBUEUiLCAiICAgWy1FU0NBUEUgKEF2ZWMgY2FyYWN0XHUwMEU4cmVzIGQnZXNwYWNlbWVudCB7dmFsZXVyIHBhciBkXHUwMEU5ZmF1dCA6IDw+JlwiJ1xcclxcbn1dIn0sCi0gIHsgIm9wdGlvbklOREVOVCIsICIgICBbLUlOREVOVCAoQ29udHJcdTAwRjRsZXIgbGUgbm9tYnJlIGQnZXNwYWNlcyBcdTAwRTAgbWV0dHJlIGVuIHJldHJhaXQge3ZhbGV1ciBwYXIgZFx1MDBFOWZhdXQgOiAwfSldIn0sCi0gIHsgIm9wdGlvblRUIiwgIiAgIFstVFQgKEdcdTAwRTluXHUwMEU5cmVyIHVuZSB0cmFjZSBkZXMgbW9kXHUwMEU4bGVzIHBlbmRhbnQgcXUnaWxzIHNvbnQgYXBwZWxcdTAwRTlzLildIn0sCi0gIHsgIm9wdGlvblRHIiwgIiAgIFstVEcgKEdcdTAwRTluXHUwMEU5cmVyIHVuZSB0cmFjZSBkZSBjaGFxdWUgXHUwMEU5dlx1MDBFOW5lbWVudCBkZSBnXHUwMEU5blx1MDBFOXJhdGlvbi4pXSJ9LAotICB7ICJvcHRpb25UUyIsICIgICBbLVRTIChHXHUwMEU5blx1MDBFOXJlciB1bmUgdHJhY2UgZGUgY2hhcXVlIFx1MDBFOXZcdTAwRTluZW1lbnQgZGUgc1x1MDBFOWxlY3Rpb24uKV0ifSwKLSAgeyAgIm9wdGlvblRUQyIsICIgICBbLVRUQyAoR1x1MDBFOW5cdTAwRTlyZXIgdW5lIHRyYWNlIGRlcyBlbmZhbnRzIGRlIG1vZFx1MDBFOGxlIHBlbmRhbnQgcXUnaWxzIHNvbnQgdHJhaXRcdTAwRTlzLildIn0sCi0gIHsgIm9wdGlvblRDTEFTUyIsICIgICBbLVRDTEFTUyAoQ2xhc3NlIFRyYWNlTGlzdGVuZXIgcG91ciBsZXMgZXh0ZW5zaW9ucyBkZSB0cmFjZS4pXSJ9LAotICB7ICJvcHRpb25WQUxJREFURSIsICIgICBbLVZBTElEQVRFIChEXHUwMEU5ZmluaXIgc2kgbGEgdmFsaWRhdGlvbiBlc3QgZWZmZWN0dVx1MDBFOWUuIFBhciBkXHUwMEU5ZmF1dCwgbGEgdmFsaWRhdGlvbiBlc3QgZFx1MDBFOXNhY3Rpdlx1MDBFOWUuKV0ifSwKLSAgeyAib3B0aW9uRURVTVAiLCAiICAgWy1FRFVNUCB7bm9tIGRlIGZpY2hpZXIgZmFjdWx0YXRpZn0gKEVmZmVjdHVlciBsZSB2aWRhZ2UgZGUgbGEgcGlsZSBzdXIgbCdlcnJldXIuKV0ifSwKLSAgeyAgIm9wdGlvblhNTCIsICIgICBbLVhNTCAoVXRpbGlzZXIgbGUgcHJvZ3JhbW1lIGRlIGZvcm1hdGFnZSBYTUwgZXQgYWpvdXRlciB1biBlbi10XHUwMEVBdGUgWE1MLildIn0sCi0gIHsgICJvcHRpb25URVhUIiwgIiAgIFstVEVYVCAoVXRpbGlzZXIgbGUgZm9ybWF0YWdlIGRlIHRleHRlIHNpbXBsZS4pXSJ9LAotICB7ICAib3B0aW9uSFRNTCIsICIgICBbLUhUTUwgKFV0aWxpc2VyIGxlIGZvcm1hdGFnZSBIVE1MLildIn0sCi0gIHsgICJvcHRpb25QQVJBTSIsICIgICBbLVBBUkFNIEV4cHJlc3Npb24gZGUgbm9tIChEXHUwMEU5ZmluaXIgdW4gcGFyYW1cdTAwRTh0cmUgZGUgZmV1aWxsZSBkZSBzdHlsZSldIn0sCi0gIHsgICJub1BhcnNlcm1zZzEiLCAiRWNoZWMgZHUgcHJvY2Vzc3VzIFhTTC4ifSwKLSAgeyAgIm5vUGFyc2VybXNnMiIsICIqKiBBbmFseXNldXIgaW50cm91dmFibGUgKioifSwKLSAgeyAibm9QYXJzZXJtc2czIiwgICJWXHUwMEU5cmlmaWV6IHZvdHJlIHZhcmlhYmxlIGQnZW52aXJvbm5lbWVudCBDTEFTU1BBVEguIn0sCi0gIHsgIm5vUGFyc2VybXNnNCIsICJTaSB2b3VzIG5lIGRpc3Bvc2V6IHBhcyBkZSBsJ2FuYWx5c2V1ciBYTUwgcG91ciBKYXZhIGQnSUJNLCB2b3VzIHBvdXZleiBsZSB0XHUwMEU5bFx1MDBFOWNoYXJnZXIgc3VyIGxlIHNpdGUifSwKLSAgeyAibm9QYXJzZXJtc2c1IiwgIkFscGhhV29ya3MgZCdJQk0gOiBodHRwOi8vd3d3LmFscGhhd29ya3MuaWJtLmNvbS9mb3JtdWxhL3htbCJ9LAotICB7ICJvcHRpb25VUklSRVNPTFZFUiIsICIgICBbLVVSSVJFU09MVkVSIE5vbSBkZSBjbGFzc2UgY29tcGxldCAoVVJJUmVzb2x2ZXIgXHUwMEUwIHV0aWxpc2VyIHBvdXIgclx1MDBFOXNvdWRyZSBsZXMgVVJJKV0ifSwKLSAgeyAib3B0aW9uRU5USVRZUkVTT0xWRVIiLCAgIiAgIFstRU5USVRZUkVTT0xWRVIgTm9tIGRlIGNsYXNzZSBjb21wbGV0IChFbnRpdHlSZXNvbHZlciBcdTAwRTAgdXRpbGlzZXIgcG91ciByXHUwMEU5c291ZHJlIGxlcyBlbnRpdFx1MDBFOXMpXSJ9LAotICB7ICJvcHRpb25DT05URU5USEFORExFUiIsICAiICAgWy1DT05URU5USEFORExFUiBOb20gZGUgY2xhc3NlIGNvbXBsZXQgKENvbnRlbnRIYW5kbGVyIFx1MDBFMCB1dGlsaXNlciBwb3VyIHNcdTAwRTlyaWFsaXNlciBsYSBzb3J0aWUpXSJ9LAotICB7ICAib3B0aW9uTElORU5VTUJFUlMiLCAgIiAgIFstTCBVdGlsaXNlciBsZXMgbnVtXHUwMEU5cm9zIGRlIGxpZ25lIHBvdXIgbGUgZG9jdW1lbnQgc291cmNlXSJ9LAotICB7ICJvcHRpb25TRUNVUkVQUk9DRVNTSU5HIiwgIiAgIFstU0VDVVJFIChEXHUwMEU5ZmluaXIgbGEgZm9uY3Rpb25uYWxpdFx1MDBFOSBkZSB0cmFpdGVtZW50IHNcdTAwRTljdXJpc1x1MDBFOSBzdXIgVHJ1ZSldIn0sCi0KLSAgICAvLyBGb2xsb3dpbmcgYXJlIHRoZSBuZXcgb3B0aW9ucyBhZGRlZCBpbiBYU0xURXJyb3JSZXNvdXJjZXMucHJvcGVydGllcyBmaWxlcyBhZnRlciBKZGsgMS40IChYYWxhbiAyLjItRDExKQotCi0KLSAgeyAgIm9wdGlvbk1FRElBIiwgICIgICBbLU1FRElBIG1lZGlhVHlwZSAoVXRpbGlzZXIgbCdhdHRyaWJ1dCBkZSBzdXBwb3J0IHBvdXIgdHJvdXZlciBsYSBmZXVpbGxlIGRlIHN0eWxlIGFzc29jaVx1MDBFOWUgXHUwMEUwIHVuIGRvY3VtZW50KV0ifSwKLSAgeyAgIm9wdGlvbkZMQVZPUiIsICAiICAgWy1GTEFWT1IgZmxhdm9yTmFtZSAoVXRpbGlzZXIgZXhwbGljaXRlbWVudCBzMnM9U0FYIG91IGQyZD1ET00gcG91ciBlZmZlY3R1ZXIgbGEgdHJhbnNmb3JtYXRpb24pXSAifSwgLy8gQWRkZWQgYnkgc2JvYWcvc2N1cmN1cnU7IGV4cGVyaW1lbnRhbAotICB7ICJvcHRpb25ESUFHIiwgIiAgIFstRElBRyAoQWZmaWNoZXIgbGEgZHVyXHUwMEU5ZSB0b3RhbGUgZGUgbGEgdHJhbnNmb3JtYXRpb24sIGVuIG1pbGxpc2Vjb25kZXMpXSJ9LAotICB7ICJvcHRpb25JTkNSRU1FTlRBTCIsICAiICAgWy1JTkNSRU1FTlRBTCAoRGVtYW5kZXIgbGEgY29uc3RydWN0aW9uIERUTSBpbmNyXHUwMEU5bWVudGllbGxlIGVuIGRcdTAwRTlmaW5pc3NhbnQgaHR0cDovL3htbC5hcGFjaGUub3JnL3hhbGFuL2ZlYXR1cmVzL2luY3JlbWVudGFsIHRydWUpXSJ9LAotICB7ICAib3B0aW9uTk9PUFRJTUlNSVpFIiwgICIgICBbLU5PT1BUSU1JTUlaRSAoTmUgZGVtYW5kZXIgYXVjdW5lIG9wdGltaXNhdGlvbiBkZSBsYSBmZXVpbGxlIGRlIHN0eWxlIGVuIGRcdTAwRTlmaW5pc3NhbnQgaHR0cDovL3htbC5hcGFjaGUub3JnL3hhbGFuL2ZlYXR1cmVzL29wdGltaXplIGZhbHNlKV0ifSwKLSAgeyAib3B0aW9uUkwiLCAgIiAgIFstUkwgcmVjdXJzaW9ubGltaXQgKEFzc2VydGlvbiBkJ3VuZSBsaW1pdGUgbnVtXHUwMEU5cmlxdWUgc3VyIGxhIHByb2ZvbmRldXIgZGUgclx1MDBFOWN1cnNpdml0XHUwMEU5IGRlIGxhIGZldWlsbGUgZGUgc3R5bGUpXSJ9LAotICB7ICAgIm9wdGlvblhPIiwgICIgICBbLVhPIFt0cmFuc2xldE5hbWVdIChBZmZlY3RlciBsZSBub20gYXUgdHJhbnNsZXQgZ1x1MDBFOW5cdTAwRTlyXHUwMEU5KV0ifSwKLSAgeyAgIm9wdGlvblhEIiwgIiAgIFstWEQgZGVzdGluYXRpb25EaXJlY3RvcnkgKEluZGlxdWVyIHVuIHJcdTAwRTlwZXJ0b2lyZSBkZSBkZXN0aW5hdGlvbiBwb3VyIGxlIHRyYW5zbGV0KV0ifSwKLSAgeyAgIm9wdGlvblhKIiwgICIgICBbLVhKIGphcmZpbGUgKFBhY2thZ2VyIGxlcyBjbGFzc2VzIGRlIHRyYW5zbGV0IGRhbnMgdW4gZmljaGllciBKQVIgbm9tbVx1MDBFOSA8amFyZmlsZT4pXSJ9LAotICB7ICAgIm9wdGlvblhQIiwgICIgICBbLVhQIHBhY2thZ2UgKEluZGlxdWUgdW4gcHJcdTAwRTlmaXhlIGRlIG5vbSBkZSBwYWNrYWdlIHBvdXIgdG91dGVzIGxlcyBjbGFzc2VzIGRlIHRyYW5zbGV0IGdcdTAwRTluXHUwMEU5clx1MDBFOWVzKV0ifSwKLQotICAvL0FkZElUSU9OQUwgIFNUUklOR1MgdGhhdCBuZWVkIEwxMG4KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBkZXNjcmliZXMgdXNhZ2Ugb2YgYSBwYXJ0aWN1bGFyCi0gIC8vIGNvbW1hbmQtbGluZSBvcHRpb24gdGhhdCBpcyB1c2VkIHRvIGVuYWJsZSB0aGUgInRlbXBsYXRlIGlubGluaW5nIgotICAvLyBvcHRpbWl6YXRpb24uICBUaGUgb3B0aW1pemF0aW9uIGludm9sdmVzIG1ha2luZyBhIGNvcHkgb2YgdGhlIGNvZGUKLSAgLy8gZ2VuZXJhdGVkIGZvciBhIHRlbXBsYXRlIGluIGFub3RoZXIgdGVtcGxhdGUgdGhhdCByZWZlcnMgdG8gaXQuCi0gIHsgIm9wdGlvblhOIiwgICIgICBbLVhOIChBY3RpdmVyIGF1dG9tYXRpcXVlbWVudCBsJ2ltYWdlIFwiaW5saW5lXCIgZHUgbW9kXHUwMEU4bGUpXSIgfSwKLSAgeyAib3B0aW9uWFgiLCAgIiAgIFstWFggKEFjdGl2ZXIgbGEgc29ydGllIGRlIG1lc3NhZ2VzIGRlIGRcdTAwRTlib2dhZ2Ugc3VwcGxcdTAwRTltZW50YWlyZXMpXSJ9LAotICB7ICJvcHRpb25YVCIgLCAiICAgWy1YVCAoVXRpbGlzZXIgbGUgdHJhbnNsZXQgcG91ciBsYSB0cmFuc2Zvcm1hdGlvbiBzaSBwb3NzaWJsZSldIn0sCi0gIHsgImRpYWdUaW1pbmciLCIgLS0tLS0tLS0tIExhIHRyYW5zZm9ybWF0aW9uIGRlIHswfSB2aWEgezF9IGEgcHJpcyB7Mn0gbXMiIH0sCi0gIHsgInJlY3Vyc2lvblRvb0RlZXAiLCJJbWJyaWNhdGlvbiBkZSBtb2RcdTAwRThsZSB0cm9wIHByb2ZvbmRlLiBJbWJyaWNhdGlvbiA9IHswfSwgbW9kXHUwMEU4bGUgezF9IHsyfSIgfSwKLSAgeyAibmFtZUlzIiwgImxlIG5vbSBlc3QiIH0sCi0gIHsgIm1hdGNoUGF0dGVybklzIiwgImxlIG1vZFx1MDBFOGxlIGRlIHJlY2hlcmNoZSBlc3QiIH0KLQotICB9OwotCi0gIH0KLSAgLy8gPT09PT09PT09PT09PT09PT0gSU5GUkFTVFJVQ1RVUkUgPT09PT09PT09PT09PT09PT09PT09PQotCi0gIC8qKiBTdHJpbmcgZm9yIHVzZSB3aGVuIGEgYmFkIGVycm9yIGNvZGUgd2FzIGVuY291bnRlcmVkLiAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBCQURfQ09ERSA9ICJCQURfQ09ERSI7Ci0KLSAgLyoqIFN0cmluZyBmb3IgdXNlIHdoZW4gZm9ybWF0dGluZyBvZiB0aGUgZXJyb3Igc3RyaW5nIGZhaWxlZC4gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBGT1JNQVRfRkFJTEVEID0gIkZPUk1BVF9GQUlMRUQiOwotCi0gIC8qKiBHZW5lcmFsIGVycm9yIHN0cmluZy4gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJPUl9TVFJJTkcgPSAiI2Vycm9yIjsKLQotICAvKiogU3RyaW5nIHRvIHByZXBlbmQgdG8gZXJyb3IgbWVzc2FnZXMuICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJPUl9IRUFERVIgPSAiRXJyb3I6ICI7Ci0KLSAgLyoqIFN0cmluZyB0byBwcmVwZW5kIHRvIHdhcm5pbmcgbWVzc2FnZXMuICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdBUk5JTkdfSEVBREVSID0gIldhcm5pbmc6ICI7Ci0KLSAgLyoqIFN0cmluZyB0byBzcGVjaWZ5IHRoZSBYU0xUIG1vZHVsZS4gICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFhTTF9IRUFERVIgPSAiWFNMVCAiOwotCi0gIC8qKiBTdHJpbmcgdG8gc3BlY2lmeSB0aGUgWE1MIHBhcnNlciBtb2R1bGUuICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxfSEVBREVSID0gIlhNTCAiOwotCi0gIC8qKiBJIGRvbid0IHRoaW5rIHRoaXMgaXMgdXNlZCBhbnkgbW9yZS4KLSAgICogQGRlcHJlY2F0ZWQgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFFVRVJZX0hFQURFUiA9ICJQQVRURVJOICI7Ci0KLQotICAgIH0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwvcmVzL1hTTFRFcnJvclJlc291cmNlc19pdC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC9yZXMvWFNMVEVycm9yUmVzb3VyY2VzX2l0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGFhZTNjMzYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC9yZXMvWFNMVEVycm9yUmVzb3VyY2VzX2l0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNDQ3ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnJlczsKLQotaW1wb3J0IGphdmEudXRpbC5MaXN0UmVzb3VyY2VCdW5kbGU7Ci1pbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKLWltcG9ydCBqYXZhLnV0aWwuTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uOwotaW1wb3J0IGphdmEudXRpbC5SZXNvdXJjZUJ1bmRsZTsKLQotLyoqCi0gKiBTZXQgdXAgZXJyb3IgbWVzc2FnZXMuCi0gKiBXZSBidWlsZCBhIHR3byBkaW1lbnNpb25hbCBhcnJheSBvZiBtZXNzYWdlIGtleXMgYW5kCi0gKiBtZXNzYWdlIHN0cmluZ3MuIEluIG9yZGVyIHRvIGFkZCBhIG5ldyBtZXNzYWdlIGhlcmUsCi0gKiB5b3UgbmVlZCB0byBmaXJzdCBhZGQgYSBTdHJpbmcgY29uc3RhbnQuIEFuZAotICogIHlvdSBuZWVkIHRvIGVudGVyIGtleSAsIHZhbHVlIHBhaXIgYXMgcGFydCBvZiBjb250ZW50cwotICogQXJyYXkuIFlvdSBhbHNvIG5lZWQgdG8gdXBkYXRlIE1BWF9DT0RFIGZvciBlcnJvciBzdHJpbmdzCi0gKiBhbmQgTUFYX1dBUk5JTkcgZm9yIHdhcm5pbmdzICggTmVlZGVkIGZvciBvbmx5IGluZm9ybWF0aW9uCi0gKiBwdXJwb3NlICkKLSAqLwotcHVibGljIGNsYXNzIFhTTFRFcnJvclJlc291cmNlc19pdCBleHRlbmRzIExpc3RSZXNvdXJjZUJ1bmRsZQotewotCi0vKgotICogVGhpcyBmaWxlIGNvbnRhaW5zIGVycm9yIGFuZCB3YXJuaW5nIG1lc3NhZ2VzIHJlbGF0ZWQgdG8gWGFsYW4gRXJyb3IKLSAqIEhhbmRsaW5nLgotICoKLSAqICBHZW5lcmFsIG5vdGVzIHRvIHRyYW5zbGF0b3JzOgotICoKLSAqICAxKSBYYWxhbiAob3IgbW9yZSBwcm9wZXJseSwgWGFsYW4taW50ZXJwcmV0aXZlKSBhbmQgWFNMVEMgYXJlIG5hbWVzIG9mCi0gKiAgICAgY29tcG9uZW50cy4KLSAqICAgICBYU0xUIGlzIGFuIGFjcm9ueW0gZm9yICJYTUwgU3R5bGVzaGVldCBMYW5ndWFnZTogVHJhbnNmb3JtYXRpb25zIi4KLSAqICAgICBYU0xUQyBpcyBhbiBhY3JvbnltIGZvciBYU0xUIENvbXBpbGVyLgotICoKLSAqICAyKSBBIHN0eWxlc2hlZXQgaXMgYSBkZXNjcmlwdGlvbiBvZiBob3cgdG8gdHJhbnNmb3JtIGFuIGlucHV0IFhNTCBkb2N1bWVudAotICogICAgIGludG8gYSByZXN1bHRhbnQgWE1MIGRvY3VtZW50IChvciBIVE1MIGRvY3VtZW50IG9yIHRleHQpLiAgVGhlCi0gKiAgICAgc3R5bGVzaGVldCBpdHNlbGYgaXMgZGVzY3JpYmVkIGluIHRoZSBmb3JtIG9mIGFuIFhNTCBkb2N1bWVudC4KLSAqCi0gKiAgMykgQSB0ZW1wbGF0ZSBpcyBhIGNvbXBvbmVudCBvZiBhIHN0eWxlc2hlZXQgdGhhdCBpcyB1c2VkIHRvIG1hdGNoIGEKLSAqICAgICBwYXJ0aWN1bGFyIHBvcnRpb24gb2YgYW4gaW5wdXQgZG9jdW1lbnQgYW5kIHNwZWNpZmllcyB0aGUgZm9ybSBvZiB0aGUKLSAqICAgICBjb3JyZXNwb25kaW5nIHBvcnRpb24gb2YgdGhlIG91dHB1dCBkb2N1bWVudC4KLSAqCi0gKiAgNCkgQW4gZWxlbWVudCBpcyBhIG1hcmstdXAgdGFnIGluIGFuIFhNTCBkb2N1bWVudDsgYW4gYXR0cmlidXRlIGlzIGEKLSAqICAgICBtb2RpZmllciBvbiB0aGUgdGFnLiAgRm9yIGV4YW1wbGUsIGluIDxlbGVtIGF0dHI9J3ZhbCcgYXR0cjI9J3ZhbDInPgotICogICAgICJlbGVtIiBpcyBhbiBlbGVtZW50IG5hbWUsICJhdHRyIiBhbmQgImF0dHIyIiBhcmUgYXR0cmlidXRlIG5hbWVzIHdpdGgKLSAqICAgICB0aGUgdmFsdWVzICJ2YWwiIGFuZCAidmFsMiIsIHJlc3BlY3RpdmVseS4KLSAqCi0gKiAgNSkgQSBuYW1lc3BhY2UgZGVjbGFyYXRpb24gaXMgYSBzcGVjaWFsIGF0dHJpYnV0ZSB0aGF0IGlzIHVzZWQgdG8gYXNzb2NpYXRlCi0gKiAgICAgYSBwcmVmaXggd2l0aCBhIFVSSSAodGhlIG5hbWVzcGFjZSkuICBUaGUgbWVhbmluZ3Mgb2YgZWxlbWVudCBuYW1lcyBhbmQKLSAqICAgICBhdHRyaWJ1dGUgbmFtZXMgdGhhdCB1c2UgdGhhdCBwcmVmaXggYXJlIGRlZmluZWQgd2l0aCByZXNwZWN0IHRvIHRoYXQKLSAqICAgICBuYW1lc3BhY2UuCi0gKgotICogIDYpICJUcmFuc2xldCIgaXMgYW4gaW52ZW50ZWQgdGVybSB0aGF0IGRlc2NyaWJlcyB0aGUgY2xhc3MgZmlsZSB0aGF0Ci0gKiAgICAgcmVzdWx0cyBmcm9tIGNvbXBpbGluZyBhbiBYTUwgc3R5bGVzaGVldCBpbnRvIGEgSmF2YSBjbGFzcy4KLSAqCi0gKiAgNykgWFBhdGggaXMgYSBzcGVjaWZpY2F0aW9uIHRoYXQgZGVzY3JpYmVzIGEgbm90YXRpb24gZm9yIGlkZW50aWZ5aW5nCi0gKiAgICAgbm9kZXMgaW4gYSB0cmVlLXN0cnVjdHVyZWQgcmVwcmVzZW50YXRpb24gb2YgYW4gWE1MIGRvY3VtZW50LiAgQW4KLSAqICAgICBpbnN0YW5jZSBvZiB0aGF0IG5vdGF0aW9uIGlzIHJlZmVycmVkIHRvIGFzIGFuIFhQYXRoIGV4cHJlc3Npb24uCi0gKgotICovCi0KLSAgLyoKLSAgICogU3RhdGljIHZhcmlhYmxlcwotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9OQU1FU1BBQ0VfVVJJX1ZBTFVFX0ZPUl9SRVNVTFRfUFJFRklYID0KLSAgICAgICAgIkVSX0lOVkFMSURfU0VUX05BTUVTUEFDRV9VUklfVkFMVUVfRk9SX1JFU1VMVF9QUkVGSVgiOwotCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfTkFNRVNQQUNFX1VSSV9WQUxVRV9GT1JfUkVTVUxUX1BSRUZJWF9GT1JfREVGQVVMVCA9Ci0gICAgICAgICJFUl9JTlZBTElEX05BTUVTUEFDRV9VUklfVkFMVUVfRk9SX1JFU1VMVF9QUkVGSVhfRk9SX0RFRkFVTFQiOwotCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX0NVUkxZQlJBQ0UgPSAiRVJfTk9fQ1VSTFlCUkFDRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQgPSAiRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lMTEVHQUxfQVRUUklCVVRFID0gIkVSX0lMTEVHQUxfQVRUUklCVVRFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTlVMTF9TT1VSQ0VOT0RFX0FQUExZSU1QT1JUUyA9ICJFUl9OVUxMX1NPVVJDRU5PREVfQVBQTFlJTVBPUlRTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX0FERCA9ICJFUl9DQU5OT1RfQUREIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTlVMTF9TT1VSQ0VOT0RFX0hBTkRMRUFQUExZVEVNUExBVEVTPSJFUl9OVUxMX1NPVVJDRU5PREVfSEFORExFQVBQTFlURU1QTEFURVMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19OQU1FX0FUVFJJQiA9ICJFUl9OT19OQU1FX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1RFTVBMQVRFX05PVF9GT1VORCA9ICJFUl9URU1QTEFURV9OT1RfRk9VTkQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX1JFU09MVkVfTkFNRV9BVlQgPSAiRVJfQ0FOVF9SRVNPTFZFX05BTUVfQVZUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUkVRVUlSRVNfQVRUUklCID0gIkVSX1JFUVVJUkVTX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01VU1RfSEFWRV9URVNUX0FUVFJJQiA9ICJFUl9NVVNUX0hBVkVfVEVTVF9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9CQURfVkFMX09OX0xFVkVMX0FUVFJJQiA9Ci0gICAgICAgICAiRVJfQkFEX1ZBTF9PTl9MRVZFTF9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUk9DRVNTSU5HSU5TVFJVQ1RJT05fTkFNRV9DQU5UX0JFX1hNTCA9Ci0gICAgICAgICAiRVJfUFJPQ0VTU0lOR0lOU1RSVUNUSU9OX05BTUVfQ0FOVF9CRV9YTUwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUk9DRVNTSU5HSU5TVFJVQ1RJT05fTk9UVkFMSURfTkNOQU1FID0KLSAgICAgICAgICJFUl9QUk9DRVNTSU5HSU5TVFJVQ1RJT05fTk9UVkFMSURfTkNOQU1FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTkVFRF9NQVRDSF9BVFRSSUIgPSAiRVJfTkVFRF9NQVRDSF9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9ORUVEX05BTUVfT1JfTUFUQ0hfQVRUUklCID0KLSAgICAgICAgICJFUl9ORUVEX05BTUVfT1JfTUFUQ0hfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9SRVNPTFZFX05TUFJFRklYID0KLSAgICAgICAgICJFUl9DQU5UX1JFU09MVkVfTlNQUkVGSVgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTExFR0FMX1ZBTFVFID0gIkVSX0lMTEVHQUxfVkFMVUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19PV05FUkRPQyA9ICJFUl9OT19PV05FUkRPQyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VMRU1URU1QTEFURUVMRU1fRVJSID0iRVJfRUxFTVRFTVBMQVRFRUxFTV9FUlIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OVUxMX0NISUxEID0gIkVSX05VTExfQ0hJTEQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9ORUVEX1NFTEVDVF9BVFRSSUIgPSAiRVJfTkVFRF9TRUxFQ1RfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTkVFRF9URVNUX0FUVFJJQiA9ICJFUl9ORUVEX1RFU1RfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTkVFRF9OQU1FX0FUVFJJQiA9ICJFUl9ORUVEX05BTUVfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fQ09OVEVYVF9PV05FUkRPQyA9ICJFUl9OT19DT05URVhUX09XTkVSRE9DIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTERfTk9UX0NSRUFURV9YTUxfUFJPQ19MSUFJU09OID0KLSAgICAgICAgICJFUl9DT1VMRF9OT1RfQ1JFQVRFX1hNTF9QUk9DX0xJQUlTT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUk9DRVNTX05PVF9TVUNDRVNTRlVMID0KLSAgICAgICAgICJFUl9QUk9DRVNTX05PVF9TVUNDRVNTRlVMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9UX1NVQ0NFU1NGVUwgPSAiRVJfTk9UX1NVQ0NFU1NGVUwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FTkNPRElOR19OT1RfU1VQUE9SVEVEID0KLSAgICAgICAgICJFUl9FTkNPRElOR19OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTERfTk9UX0NSRUFURV9UUkFDRUxJU1RFTkVSID0KLSAgICAgICAgICJFUl9DT1VMRF9OT1RfQ1JFQVRFX1RSQUNFTElTVEVORVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9LRVlfUkVRVUlSRVNfTkFNRV9BVFRSSUIgPQotICAgICAgICAgIkVSX0tFWV9SRVFVSVJFU19OQU1FX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0tFWV9SRVFVSVJFU19NQVRDSF9BVFRSSUIgPQotICAgICAgICAgIkVSX0tFWV9SRVFVSVJFU19NQVRDSF9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9LRVlfUkVRVUlSRVNfVVNFX0FUVFJJQiA9Ci0gICAgICAgICAiRVJfS0VZX1JFUVVJUkVTX1VTRV9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SRVFVSVJFU19FTEVNRU5UU19BVFRSSUIgPQotICAgICAgICAgIkVSX1JFUVVJUkVTX0VMRU1FTlRTX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01JU1NJTkdfUFJFRklYX0FUVFJJQiA9Ci0gICAgICAgICAiRVJfTUlTU0lOR19QUkVGSVhfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQkFEX1NUWUxFU0hFRVRfVVJMID0gIkVSX0JBRF9TVFlMRVNIRUVUX1VSTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZJTEVfTk9UX0ZPVU5EID0gIkVSX0ZJTEVfTk9UX0ZPVU5EIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU9FWENFUFRJT04gPSAiRVJfSU9FWENFUFRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19IUkVGX0FUVFJJQiA9ICJFUl9OT19IUkVGX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NUWUxFU0hFRVRfSU5DTFVERVNfSVRTRUxGID0KLSAgICAgICAgICJFUl9TVFlMRVNIRUVUX0lOQ0xVREVTX0lUU0VMRiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BST0NFU1NJTkNMVURFX0VSUk9SID0iRVJfUFJPQ0VTU0lOQ0xVREVfRVJST1IiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9NSVNTSU5HX0xBTkdfQVRUUklCID0gIkVSX01JU1NJTkdfTEFOR19BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9NSVNTSU5HX0NPTlRBSU5FUl9FTEVNRU5UX0NPTVBPTkVOVCA9Ci0gICAgICAgICAiRVJfTUlTU0lOR19DT05UQUlORVJfRUxFTUVOVF9DT01QT05FTlQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5fT05MWV9PVVRQVVRfVE9fRUxFTUVOVCA9Ci0gICAgICAgICAiRVJfQ0FOX09OTFlfT1VUUFVUX1RPX0VMRU1FTlQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUk9DRVNTX0VSUk9SID0gIkVSX1BST0NFU1NfRVJST1IiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTklNUExOT0RFX0VSUk9SID0gIkVSX1VOSU1QTE5PREVfRVJST1IiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19TRUxFQ1RfRVhQUkVTU0lPTiA9IkVSX05PX1NFTEVDVF9FWFBSRVNTSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX1NFUklBTElaRV9YU0xQUk9DRVNTT1IgPQotICAgICAgICAgIkVSX0NBTk5PVF9TRVJJQUxJWkVfWFNMUFJPQ0VTU09SIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fSU5QVVRfU1RZTEVTSEVFVCA9ICJFUl9OT19JTlBVVF9TVFlMRVNIRUVUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRkFJTEVEX1BST0NFU1NfU1RZTEVTSEVFVCA9Ci0gICAgICAgICAiRVJfRkFJTEVEX1BST0NFU1NfU1RZTEVTSEVFVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxETlRfUEFSU0VfRE9DID0gIkVSX0NPVUxETlRfUEFSU0VfRE9DIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTEROVF9GSU5EX0ZSQUdNRU5UID0KLSAgICAgICAgICJFUl9DT1VMRE5UX0ZJTkRfRlJBR01FTlQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT0RFX05PVF9FTEVNRU5UID0gIkVSX05PREVfTk9UX0VMRU1FTlQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GT1JFQUNIX05FRURfTUFUQ0hfT1JfTkFNRV9BVFRSSUIgPQotICAgICAgICAgIkVSX0ZPUkVBQ0hfTkVFRF9NQVRDSF9PUl9OQU1FX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1RFTVBMQVRFU19ORUVEX01BVENIX09SX05BTUVfQVRUUklCID0KLSAgICAgICAgICJFUl9URU1QTEFURVNfTkVFRF9NQVRDSF9PUl9OQU1FX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX0NMT05FX09GX0RPQ1VNRU5UX0ZSQUcgPQotICAgICAgICAgIkVSX05PX0NMT05FX09GX0RPQ1VNRU5UX0ZSQUciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX0NSRUFURV9JVEVNID0gIkVSX0NBTlRfQ1JFQVRFX0lURU0iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YTUxTUEFDRV9JTExFR0FMX1ZBTFVFID0KLSAgICAgICAgICJFUl9YTUxTUEFDRV9JTExFR0FMX1ZBTFVFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fWFNMS0VZX0RFQ0xBUkFUSU9OID0KLSAgICAgICAgICJFUl9OT19YU0xLRVlfREVDTEFSQVRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX0NSRUFURV9VUkwgPSAiRVJfQ0FOVF9DUkVBVEVfVVJMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWFNMRlVOQ1RJT05TX1VOU1VQUE9SVEVEID0KLSAgICAgICAgICJFUl9YU0xGVU5DVElPTlNfVU5TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUk9DRVNTT1JfRVJST1IgPSAiRVJfUFJPQ0VTU09SX0VSUk9SIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9UX0FMTE9XRURfSU5TSURFX1NUWUxFU0hFRVQgPQotICAgICAgICAgIkVSX05PVF9BTExPV0VEX0lOU0lERV9TVFlMRVNIRUVUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUkVTVUxUTlNfTk9UX1NVUFBPUlRFRCA9Ci0gICAgICAgICAiRVJfUkVTVUxUTlNfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0RFRkFVTFRTUEFDRV9OT1RfU1VQUE9SVEVEID0KLSAgICAgICAgICJFUl9ERUZBVUxUU1BBQ0VfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOREVOVFJFU1VMVF9OT1RfU1VQUE9SVEVEID0KLSAgICAgICAgICJFUl9JTkRFTlRSRVNVTFRfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lMTEVHQUxfQVRUUklCID0gIkVSX0lMTEVHQUxfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5LTk9XTl9YU0xfRUxFTSA9ICJFUl9VTktOT1dOX1hTTF9FTEVNIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQkFEX1hTTFNPUlRfVVNFID0gIkVSX0JBRF9YU0xTT1JUX1VTRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01JU1BMQUNFRF9YU0xXSEVOID0gIkVSX01JU1BMQUNFRF9YU0xXSEVOIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWFNMV0hFTl9OT1RfUEFSRU5URURfQllfWFNMQ0hPT1NFID0KLSAgICAgICAgICJFUl9YU0xXSEVOX05PVF9QQVJFTlRFRF9CWV9YU0xDSE9PU0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9NSVNQTEFDRURfWFNMT1RIRVJXSVNFID0KLSAgICAgICAgICJFUl9NSVNQTEFDRURfWFNMT1RIRVJXSVNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWFNMT1RIRVJXSVNFX05PVF9QQVJFTlRFRF9CWV9YU0xDSE9PU0UgPQotICAgICAgICAgIkVSX1hTTE9USEVSV0lTRV9OT1RfUEFSRU5URURfQllfWFNMQ0hPT1NFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9UX0FMTE9XRURfSU5TSURFX1RFTVBMQVRFID0KLSAgICAgICAgICJFUl9OT1RfQUxMT1dFRF9JTlNJREVfVEVNUExBVEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTktOT1dOX0VYVF9OU19QUkVGSVggPQotICAgICAgICAgIkVSX1VOS05PV05fRVhUX05TX1BSRUZJWCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lNUE9SVFNfQVNfRklSU1RfRUxFTSA9Ci0gICAgICAgICAiRVJfSU1QT1JUU19BU19GSVJTVF9FTEVNIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU1QT1JUSU5HX0lUU0VMRiA9ICJFUl9JTVBPUlRJTkdfSVRTRUxGIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWE1MU1BBQ0VfSUxMRUdBTF9WQUwgPSJFUl9YTUxTUEFDRV9JTExFR0FMX1ZBTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BST0NFU1NTVFlMRVNIRUVUX05PVF9TVUNDRVNTRlVMID0KLSAgICAgICAgICJFUl9QUk9DRVNTU1RZTEVTSEVFVF9OT1RfU1VDQ0VTU0ZVTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NBWF9FWENFUFRJT04gPSAiRVJfU0FYX0VYQ0VQVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hTTFRfRVJST1IgPSAiRVJfWFNMVF9FUlJPUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NVUlJFTkNZX1NJR05fSUxMRUdBTD0KLSAgICAgICAgICJFUl9DVVJSRU5DWV9TSUdOX0lMTEVHQUwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9ET0NVTUVOVF9GVU5DVElPTl9JTlZBTElEX0lOX1NUWUxFU0hFRVRfRE9NID0KLSAgICAgICAgICJFUl9ET0NVTUVOVF9GVU5DVElPTl9JTlZBTElEX0lOX1NUWUxFU0hFRVRfRE9NIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9SRVNPTFZFX1BSRUZJWF9PRl9OT05fUFJFRklYX1JFU09MVkVSID0KLSAgICAgICAgICJFUl9DQU5UX1JFU09MVkVfUFJFRklYX09GX05PTl9QUkVGSVhfUkVTT0xWRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SRURJUkVDVF9DT1VMRE5UX0dFVF9GSUxFTkFNRSA9Ci0gICAgICAgICAiRVJfUkVESVJFQ1RfQ09VTEROVF9HRVRfRklMRU5BTUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfQlVJTERfRk9STUFUVEVSTElTVEVORVJfSU5fUkVESVJFQ1QgPQotICAgICAgICAgIkVSX0NBTk5PVF9CVUlMRF9GT1JNQVRURVJMSVNURU5FUl9JTl9SRURJUkVDVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfUFJFRklYX0lOX0VYQ0xVREVSRVNVTFRQUkVGSVggPQotICAgICAgICAgIkVSX0lOVkFMSURfUFJFRklYX0lOX0VYQ0xVREVSRVNVTFRQUkVGSVgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9NSVNTSU5HX05TX1VSSSA9ICJFUl9NSVNTSU5HX05TX1VSSSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01JU1NJTkdfQVJHX0ZPUl9PUFRJT04gPQotICAgICAgICAgIkVSX01JU1NJTkdfQVJHX0ZPUl9PUFRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX09QVElPTiA9ICJFUl9JTlZBTElEX09QVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01BTEZPUk1FRF9GT1JNQVRfU1RSSU5HID0KLSAgICAgICAgICJFUl9NQUxGT1JNRURfRk9STUFUX1NUUklORyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NUWUxFU0hFRVRfUkVRVUlSRVNfVkVSU0lPTl9BVFRSSUIgPQotICAgICAgICAgIkVSX1NUWUxFU0hFRVRfUkVRVUlSRVNfVkVSU0lPTl9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTExFR0FMX0FUVFJJQlVURV9WQUxVRSA9Ci0gICAgICAgICAiRVJfSUxMRUdBTF9BVFRSSUJVVEVfVkFMVUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DSE9PU0VfUkVRVUlSRVNfV0hFTiA9IkVSX0NIT09TRV9SRVFVSVJFU19XSEVOIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fQVBQTFlfSU1QT1JUX0lOX0ZPUl9FQUNIID0KLSAgICAgICAgICJFUl9OT19BUFBMWV9JTVBPUlRfSU5fRk9SX0VBQ0giOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX1VTRV9EVE1fRk9SX09VVFBVVCA9Ci0gICAgICAgICAiRVJfQ0FOVF9VU0VfRFRNX0ZPUl9PVVRQVVQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX1VTRV9EVE1fRk9SX0lOUFVUID0KLSAgICAgICAgICJFUl9DQU5UX1VTRV9EVE1fRk9SX0lOUFVUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FMTF9UT19FWFRfRkFJTEVEID0gIkVSX0NBTExfVE9fRVhUX0ZBSUxFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BSRUZJWF9NVVNUX1JFU09MVkUgPSAiRVJfUFJFRklYX01VU1RfUkVTT0xWRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfVVRGMTZfU1VSUk9HQVRFID0KLSAgICAgICAgICJFUl9JTlZBTElEX1VURjE2X1NVUlJPR0FURSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hTTEFUVFJTRVRfVVNFRF9JVFNFTEYgPQotICAgICAgICAgIkVSX1hTTEFUVFJTRVRfVVNFRF9JVFNFTEYiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfTUlYX1hFUkNFU0RPTSA9IkVSX0NBTk5PVF9NSVhfWEVSQ0VTRE9NIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVE9PX01BTllfTElTVEVORVJTID0gIkVSX1RPT19NQU5ZX0xJU1RFTkVSUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOX0VMRU1URU1QTEFURUVMRU1fUkVBRE9CSkVDVCA9Ci0gICAgICAgICAiRVJfSU5fRUxFTVRFTVBMQVRFRUxFTV9SRUFET0JKRUNUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRFVQTElDQVRFX05BTUVEX1RFTVBMQVRFID0KLSAgICAgICAgICJFUl9EVVBMSUNBVEVfTkFNRURfVEVNUExBVEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX0tFWV9DQUxMID0gIkVSX0lOVkFMSURfS0VZX0NBTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SRUZFUkVOQ0lOR19JVFNFTEYgPSAiRVJfUkVGRVJFTkNJTkdfSVRTRUxGIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSUxMRUdBTF9ET01TT1VSQ0VfSU5QVVQgPQotICAgICAgICAgIkVSX0lMTEVHQUxfRE9NU09VUkNFX0lOUFVUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0xBU1NfTk9UX0ZPVU5EX0ZPUl9PUFRJT04gPQotICAgICAgICAgIkVSX0NMQVNTX05PVF9GT1VORF9GT1JfT1BUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUkVRVUlSRURfRUxFTV9OT1RfRk9VTkQgPQotICAgICAgICAgIkVSX1JFUVVJUkVEX0VMRU1fTk9UX0ZPVU5EIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5QVVRfQ0FOTk9UX0JFX05VTEwgPSJFUl9JTlBVVF9DQU5OT1RfQkVfTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1VSSV9DQU5OT1RfQkVfTlVMTCA9ICJFUl9VUklfQ0FOTk9UX0JFX05VTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GSUxFX0NBTk5PVF9CRV9OVUxMID0gIkVSX0ZJTEVfQ0FOTk9UX0JFX05VTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TT1VSQ0VfQ0FOTk9UX0JFX05VTEwgPQotICAgICAgICAgIkVSX1NPVVJDRV9DQU5OT1RfQkVfTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9JTklUX0JTRk1HUiA9ICJFUl9DQU5OT1RfSU5JVF9CU0ZNR1IiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfQ01QTF9FWFRFTlNOID0gIkVSX0NBTk5PVF9DTVBMX0VYVEVOU04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfQ1JFQVRFX0VYVEVOU04gPQotICAgICAgICAgIkVSX0NBTk5PVF9DUkVBVEVfRVhURU5TTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOU1RBTkNFX01USERfQ0FMTF9SRVFVSVJFUyA9Ci0gICAgICAgICAiRVJfSU5TVEFOQ0VfTVRIRF9DQUxMX1JFUVVJUkVTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9FTEVNRU5UX05BTUUgPSJFUl9JTlZBTElEX0VMRU1FTlRfTkFNRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VMRU1FTlRfTkFNRV9NRVRIT0RfU1RBVElDID0KLSAgICAgICAgICJFUl9FTEVNRU5UX05BTUVfTUVUSE9EX1NUQVRJQyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYVEVOU0lPTl9GVU5DX1VOS05PV04gPQotICAgICAgICAgIkVSX0VYVEVOU0lPTl9GVU5DX1VOS05PV04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9NT1JFX01BVENIX0NPTlNUUlVDVE9SID0KLSAgICAgICAgICJFUl9NT1JFX01BVENIX0NPTlNUUlVDVE9SIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTU9SRV9NQVRDSF9NRVRIT0QgPSAiRVJfTU9SRV9NQVRDSF9NRVRIT0QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9NT1JFX01BVENIX0VMRU1FTlQgPSAiRVJfTU9SRV9NQVRDSF9FTEVNRU5UIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9DT05URVhUX1BBU1NFRCA9Ci0gICAgICAgICAiRVJfSU5WQUxJRF9DT05URVhUX1BBU1NFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BPT0xfRVhJU1RTID0gIkVSX1BPT0xfRVhJU1RTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fRFJJVkVSX05BTUUgPSAiRVJfTk9fRFJJVkVSX05BTUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19VUkwgPSAiRVJfTk9fVVJMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUE9PTF9TSVpFX0xFU1NUSEFOX09ORSA9Ci0gICAgICAgICAiRVJfUE9PTF9TSVpFX0xFU1NUSEFOX09ORSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfRFJJVkVSID0gIkVSX0lOVkFMSURfRFJJVkVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fU1RZTEVTSEVFVFJPT1QgPSAiRVJfTk9fU1RZTEVTSEVFVFJPT1QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTExFR0FMX1hNTFNQQUNFX1ZBTFVFID0KLSAgICAgICAgICJFUl9JTExFR0FMX1hNTFNQQUNFX1ZBTFVFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJPQ0VTU0ZST01OT0RFX0ZBSUxFRCA9Ci0gICAgICAgICAiRVJfUFJPQ0VTU0ZST01OT0RFX0ZBSUxFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1JFU09VUkNFX0NPVUxEX05PVF9MT0FEID0KLSAgICAgICAgICJFUl9SRVNPVVJDRV9DT1VMRF9OT1RfTE9BRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0JVRkZFUl9TSVpFX0xFU1NUSEFOX1pFUk8gPQotICAgICAgICAgIkVSX0JVRkZFUl9TSVpFX0xFU1NUSEFOX1pFUk8iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTktOT1dOX0VSUk9SX0NBTExJTkdfRVhURU5TSU9OID0KLSAgICAgICAgICJFUl9VTktOT1dOX0VSUk9SX0NBTExJTkdfRVhURU5TSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fTkFNRVNQQUNFX0RFQ0wgPSAiRVJfTk9fTkFNRVNQQUNFX0RFQ0wiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FTEVNX0NPTlRFTlRfTk9UX0FMTE9XRUQgPQotICAgICAgICAgIkVSX0VMRU1fQ09OVEVOVF9OT1RfQUxMT1dFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NUWUxFU0hFRVRfRElSRUNURURfVEVSTUlOQVRJT04gPQotICAgICAgICAgIkVSX1NUWUxFU0hFRVRfRElSRUNURURfVEVSTUlOQVRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9PTkVfT1JfVFdPID0gIkVSX09ORV9PUl9UV08iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9UV09fT1JfVEhSRUUgPSAiRVJfVFdPX09SX1RIUkVFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTERfTk9UX0xPQURfUkVTT1VSQ0UgPQotICAgICAgICAgIkVSX0NPVUxEX05PVF9MT0FEX1JFU09VUkNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX0lOSVRfREVGQVVMVF9URU1QTEFURVMgPQotICAgICAgICAgIkVSX0NBTk5PVF9JTklUX0RFRkFVTFRfVEVNUExBVEVTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUkVTVUxUX05VTEwgPSAiRVJfUkVTVUxUX05VTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SRVNVTFRfQ09VTERfTk9UX0JFX1NFVCA9Ci0gICAgICAgICAiRVJfUkVTVUxUX0NPVUxEX05PVF9CRV9TRVQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19PVVRQVVRfU1BFQ0lGSUVEID0gIkVSX05PX09VVFBVVF9TUEVDSUZJRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfVFJBTlNGT1JNX1RPX1JFU1VMVF9UWVBFID0KLSAgICAgICAgICJFUl9DQU5OT1RfVFJBTlNGT1JNX1RPX1JFU1VMVF9UWVBFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX1RSQU5TRk9STV9TT1VSQ0VfVFlQRSA9Ci0gICAgICAgICAiRVJfQ0FOTk9UX1RSQU5TRk9STV9TT1VSQ0VfVFlQRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05VTExfQ09OVEVOVF9IQU5ETEVSID0iRVJfTlVMTF9DT05URU5UX0hBTkRMRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OVUxMX0VSUk9SX0hBTkRMRVIgPSAiRVJfTlVMTF9FUlJPUl9IQU5ETEVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX0NBTExfUEFSU0UgPSAiRVJfQ0FOTk9UX0NBTExfUEFSU0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19QQVJFTlRfRk9SX0ZJTFRFUiA9IkVSX05PX1BBUkVOVF9GT1JfRklMVEVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fU1RZTEVTSEVFVF9JTl9NRURJQSA9Ci0gICAgICAgICAiRVJfTk9fU1RZTEVTSEVFVF9JTl9NRURJQSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1NUWUxFU0hFRVRfUEkgPSAiRVJfTk9fU1RZTEVTSEVFVF9QSSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PVF9TVVBQT1JURUQgPSAiRVJfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BST1BFUlRZX1ZBTFVFX0JPT0xFQU4gPQotICAgICAgICAgIkVSX1BST1BFUlRZX1ZBTFVFX0JPT0xFQU4iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRF9OT1RfRklORF9FWFRFUk5fU0NSSVBUID0KLSAgICAgICAgICJFUl9DT1VMRF9OT1RfRklORF9FWFRFUk5fU0NSSVBUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUkVTT1VSQ0VfQ09VTERfTk9UX0ZJTkQgPQotICAgICAgICAgIkVSX1JFU09VUkNFX0NPVUxEX05PVF9GSU5EIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfT1VUUFVUX1BST1BFUlRZX05PVF9SRUNPR05JWkVEID0KLSAgICAgICAgICJFUl9PVVRQVVRfUFJPUEVSVFlfTk9UX1JFQ09HTklaRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GQUlMRURfQ1JFQVRJTkdfRUxFTUxJVFJTTFQgPQotICAgICAgICAgIkVSX0ZBSUxFRF9DUkVBVElOR19FTEVNTElUUlNMVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1ZBTFVFX1NIT1VMRF9CRV9OVU1CRVIgPQotICAgICAgICAgIkVSX1ZBTFVFX1NIT1VMRF9CRV9OVU1CRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9WQUxVRV9TSE9VTERfRVFVQUwgPSAiRVJfVkFMVUVfU0hPVUxEX0VRVUFMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRkFJTEVEX0NBTExJTkdfTUVUSE9EID0KLSAgICAgICAgICJFUl9GQUlMRURfQ0FMTElOR19NRVRIT0QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GQUlMRURfQ1JFQVRJTkdfRUxFTVRNUEwgPQotICAgICAgICAgIkVSX0ZBSUxFRF9DUkVBVElOR19FTEVNVE1QTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NIQVJTX05PVF9BTExPV0VEID0gIkVSX0NIQVJTX05PVF9BTExPV0VEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQVRUUl9OT1RfQUxMT1dFRCA9ICJFUl9BVFRSX05PVF9BTExPV0VEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQkFEX1ZBTFVFID0gIkVSX0JBRF9WQUxVRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FUVFJJQl9WQUxVRV9OT1RfRk9VTkQgPQotICAgICAgICAgIkVSX0FUVFJJQl9WQUxVRV9OT1RfRk9VTkQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9BVFRSSUJfVkFMVUVfTk9UX1JFQ09HTklaRUQgPQotICAgICAgICAgIkVSX0FUVFJJQl9WQUxVRV9OT1RfUkVDT0dOSVpFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05VTExfVVJJX05BTUVTUEFDRSA9ICJFUl9OVUxMX1VSSV9OQU1FU1BBQ0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OVU1CRVJfVE9PX0JJRyA9ICJFUl9OVU1CRVJfVE9PX0JJRyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nICBFUl9DQU5OT1RfRklORF9TQVgxX0RSSVZFUiA9Ci0gICAgICAgICAiRVJfQ0FOTk9UX0ZJTkRfU0FYMV9EUklWRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyAgRVJfU0FYMV9EUklWRVJfTk9UX0xPQURFRCA9Ci0gICAgICAgICAiRVJfU0FYMV9EUklWRVJfTk9UX0xPQURFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nICBFUl9TQVgxX0RSSVZFUl9OT1RfSU5TVEFOVElBVEVEID0KLSAgICAgICAgICJFUl9TQVgxX0RSSVZFUl9OT1RfSU5TVEFOVElBVEVEIiA7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NBWDFfRFJJVkVSX05PVF9JTVBMRU1FTlRfUEFSU0VSID0KLSAgICAgICAgICJFUl9TQVgxX0RSSVZFUl9OT1RfSU1QTEVNRU5UX1BBUlNFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nICBFUl9QQVJTRVJfUFJPUEVSVFlfTk9UX1NQRUNJRklFRCA9Ci0gICAgICAgICAiRVJfUEFSU0VSX1BST1BFUlRZX05PVF9TUEVDSUZJRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyAgRVJfUEFSU0VSX0FSR19DQU5OT1RfQkVfTlVMTCA9Ci0gICAgICAgICAiRVJfUEFSU0VSX0FSR19DQU5OT1RfQkVfTlVMTCIgOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyAgRVJfRkVBVFVSRSA9ICJFUl9GRUFUVVJFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJPUEVSVFkgPSAiRVJfUFJPUEVSVFkiIDsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTlVMTF9FTlRJVFlfUkVTT0xWRVIgPSJFUl9OVUxMX0VOVElUWV9SRVNPTFZFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nICBFUl9OVUxMX0RURF9IQU5ETEVSID0gIkVSX05VTExfRFREX0hBTkRMRVIiIDsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fRFJJVkVSX05BTUVfU1BFQ0lGSUVEID0KLSAgICAgICAgICJFUl9OT19EUklWRVJfTkFNRV9TUEVDSUZJRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19VUkxfU1BFQ0lGSUVEID0gIkVSX05PX1VSTF9TUEVDSUZJRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QT09MU0laRV9MRVNTX1RIQU5fT05FID0KLSAgICAgICAgICJFUl9QT09MU0laRV9MRVNTX1RIQU5fT05FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9EUklWRVJfTkFNRSA9ICJFUl9JTlZBTElEX0RSSVZFUl9OQU1FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVJST1JMSVNURU5FUiA9ICJFUl9FUlJPUkxJU1RFTkVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQVNTRVJUX05PX1RFTVBMQVRFX1BBUkVOVCA9Ci0gICAgICAgICAiRVJfQVNTRVJUX05PX1RFTVBMQVRFX1BBUkVOVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FTU0VSVF9SRURVTkRFTlRfRVhQUl9FTElNSU5BVE9SID0KLSAgICAgICAgICJFUl9BU1NFUlRfUkVEVU5ERU5UX0VYUFJfRUxJTUlOQVRPUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PVF9BTExPV0VEX0lOX1BPU0lUSU9OID0KLSAgICAgICAgICJFUl9OT1RfQUxMT1dFRF9JTl9QT1NJVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PTldISVRFU1BBQ0VfTk9UX0FMTE9XRURfSU5fUE9TSVRJT04gPQotICAgICAgICAgIkVSX05PTldISVRFU1BBQ0VfTk9UX0FMTE9XRURfSU5fUE9TSVRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OQU1FU1BBQ0VfQ09OVEVYVF9OVUxMX05BTUVTUEFDRSA9Ci0gICAgICAgICAiRVJfTkFNRVNQQUNFX0NPTlRFWFRfTlVMTF9OQU1FU1BBQ0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OQU1FU1BBQ0VfQ09OVEVYVF9OVUxMX1BSRUZJWCA9Ci0gICAgICAgICAiRVJfTkFNRVNQQUNFX0NPTlRFWFRfTlVMTF9QUkVGSVgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YUEFUSF9SRVNPTFZFUl9OVUxMX1FOQU1FID0KLSAgICAgICAgICJFUl9YUEFUSF9SRVNPTFZFUl9OVUxMX1FOQU1FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWFBBVEhfUkVTT0xWRVJfTkVHQVRJVkVfQVJJVFkgPQotICAgICAgICAgIkVSX1hQQVRIX1JFU09MVkVSX05FR0FUSVZFX0FSSVRZIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSU5WQUxJRF9UQ0hBUiA9ICJJTlZBTElEX1RDSEFSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSU5WQUxJRF9RTkFNRSA9ICJJTlZBTElEX1FOQU1FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSU5WQUxJRF9FTlVNID0gIklOVkFMSURfRU5VTSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIElOVkFMSURfTk1UT0tFTiA9ICJJTlZBTElEX05NVE9LRU4iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBJTlZBTElEX05DTkFNRSA9ICJJTlZBTElEX05DTkFNRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIElOVkFMSURfQk9PTEVBTiA9ICJJTlZBTElEX0JPT0xFQU4iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBJTlZBTElEX05VTUJFUiA9ICJJTlZBTElEX05VTUJFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FSR19MSVRFUkFMID0gIkVSX0FSR19MSVRFUkFMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRFVQTElDQVRFX0dMT0JBTF9WQVIgPSJFUl9EVVBMSUNBVEVfR0xPQkFMX1ZBUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0RVUExJQ0FURV9WQVIgPSAiRVJfRFVQTElDQVRFX1ZBUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1RFTVBMQVRFX05BTUVfTUFUQ0ggPSAiRVJfVEVNUExBVEVfTkFNRV9NQVRDSCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfUFJFRklYID0gIkVSX0lOVkFMSURfUFJFRklYIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fQVRUUklCX1NFVCA9ICJFUl9OT19BVFRSSUJfU0VUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRlVOQ1RJT05fTk9UX0ZPVU5EID0KLSAgICAgICAgICJFUl9GVU5DVElPTl9OT1RfRk9VTkQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX0hBVkVfQ09OVEVOVF9BTkRfU0VMRUNUID0KLSAgICAgIkVSX0NBTlRfSEFWRV9DT05URU5UX0FORF9TRUxFQ1QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX1NFVF9QQVJBTV9WQUxVRSA9ICJFUl9JTlZBTElEX1NFVF9QQVJBTV9WQUxVRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NFVF9GRUFUVVJFX05VTExfTkFNRSA9Ci0gICAgICAgICJFUl9TRVRfRkVBVFVSRV9OVUxMX05BTUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9HRVRfRkVBVFVSRV9OVUxMX05BTUUgPQotICAgICAgICAiRVJfR0VUX0ZFQVRVUkVfTlVMTF9OQU1FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5TVVBQT1JURURfRkVBVFVSRSA9Ci0gICAgICAgICJFUl9VTlNVUFBPUlRFRF9GRUFUVVJFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhURU5TSU9OX0VMRU1FTlRfTk9UX0FMTE9XRURfSU5fU0VDVVJFX1BST0NFU1NJTkcgPQotICAgICAgICAiRVJfRVhURU5TSU9OX0VMRU1FTlRfTk9UX0FMTE9XRURfSU5fU0VDVVJFX1BST0NFU1NJTkciOwotCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0ZPVU5EX0NVUkxZQlJBQ0UgPSAiV0dfRk9VTkRfQ1VSTFlCUkFDRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0NPVU5UX0FUVFJJQl9NQVRDSEVTX05PX0FOQ0VTVE9SID0KLSAgICAgICAgICJXR19DT1VOVF9BVFRSSUJfTUFUQ0hFU19OT19BTkNFU1RPUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0VYUFJfQVRUUklCX0NIQU5HRURfVE9fU0VMRUNUID0KLSAgICAgICAgICJXR19FWFBSX0FUVFJJQl9DSEFOR0VEX1RPX1NFTEVDVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX05PX0xPQ0FMRV9JTl9GT1JNQVROVU1CRVIgPQotICAgICAgICAgIldHX05PX0xPQ0FMRV9JTl9GT1JNQVROVU1CRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19MT0NBTEVfTk9UX0ZPVU5EID0gIldHX0xPQ0FMRV9OT1RfRk9VTkQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19DQU5OT1RfTUFLRV9VUkxfRlJPTSA9IldHX0NBTk5PVF9NQUtFX1VSTF9GUk9NIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfQ0FOTk9UX0xPQURfUkVRVUVTVEVEX0RPQyA9Ci0gICAgICAgICAiV0dfQ0FOTk9UX0xPQURfUkVRVUVTVEVEX0RPQyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0NBTk5PVF9GSU5EX0NPTExBVE9SID0iV0dfQ0FOTk9UX0ZJTkRfQ09MTEFUT1IiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19GVU5DVElPTlNfU0hPVUxEX1VTRV9VUkwgPQotICAgICAgICAgIldHX0ZVTkNUSU9OU19TSE9VTERfVVNFX1VSTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0VOQ09ESU5HX05PVF9TVVBQT1JURURfVVNJTkdfVVRGOCA9Ci0gICAgICAgICAiV0dfRU5DT0RJTkdfTk9UX1NVUFBPUlRFRF9VU0lOR19VVEY4IjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfRU5DT0RJTkdfTk9UX1NVUFBPUlRFRF9VU0lOR19KQVZBID0KLSAgICAgICAgICJXR19FTkNPRElOR19OT1RfU1VQUE9SVEVEX1VTSU5HX0pBVkEiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19TUEVDSUZJQ0lUWV9DT05GTElDVFMgPQotICAgICAgICAgIldHX1NQRUNJRklDSVRZX0NPTkZMSUNUUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX1BBUlNJTkdfQU5EX1BSRVBBUklORyA9Ci0gICAgICAgICAiV0dfUEFSU0lOR19BTkRfUFJFUEFSSU5HIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfQVRUUl9URU1QTEFURSA9ICJXR19BVFRSX1RFTVBMQVRFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfQ09ORkxJQ1RfQkVUV0VFTl9YU0xTVFJJUFNQQUNFX0FORF9YU0xQUkVTRVJWRVNQQUNFID0gIldHX0NPTkZMSUNUX0JFVFdFRU5fWFNMU1RSSVBTUEFDRV9BTkRfWFNMUFJFU0VSVkVTUCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0FUVFJJQl9OT1RfSEFORExFRCA9ICJXR19BVFRSSUJfTk9UX0hBTkRMRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19OT19ERUNJTUFMRk9STUFUX0RFQ0xBUkFUSU9OID0KLSAgICAgICAgICJXR19OT19ERUNJTUFMRk9STUFUX0RFQ0xBUkFUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfT0xEX1hTTFRfTlMgPSAiV0dfT0xEX1hTTFRfTlMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19PTkVfREVGQVVMVF9YU0xERUNJTUFMRk9STUFUX0FMTE9XRUQgPQotICAgICAgICAgIldHX09ORV9ERUZBVUxUX1hTTERFQ0lNQUxGT1JNQVRfQUxMT1dFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX1hTTERFQ0lNQUxGT1JNQVRfTkFNRVNfTVVTVF9CRV9VTklRVUUgPQotICAgICAgICAgIldHX1hTTERFQ0lNQUxGT1JNQVRfTkFNRVNfTVVTVF9CRV9VTklRVUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19JTExFR0FMX0FUVFJJQlVURSA9ICJXR19JTExFR0FMX0FUVFJJQlVURSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0NPVUxEX05PVF9SRVNPTFZFX1BSRUZJWCA9Ci0gICAgICAgICAiV0dfQ09VTERfTk9UX1JFU09MVkVfUFJFRklYIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfU1RZTEVTSEVFVF9SRVFVSVJFU19WRVJTSU9OX0FUVFJJQiA9Ci0gICAgICAgICAiV0dfU1RZTEVTSEVFVF9SRVFVSVJFU19WRVJTSU9OX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0lMTEVHQUxfQVRUUklCVVRFX05BTUUgPQotICAgICAgICAgIldHX0lMTEVHQUxfQVRUUklCVVRFX05BTUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19JTExFR0FMX0FUVFJJQlVURV9WQUxVRSA9Ci0gICAgICAgICAiV0dfSUxMRUdBTF9BVFRSSUJVVEVfVkFMVUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19FTVBUWV9TRUNPTkRfQVJHID0gIldHX0VNUFRZX1NFQ09ORF9BUkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19QUk9DRVNTSU5HSU5TVFJVQ1RJT05fTkFNRV9DQU5UX0JFX1hNTCA9Ci0gICAgICAgICAiV0dfUFJPQ0VTU0lOR0lOU1RSVUNUSU9OX05BTUVfQ0FOVF9CRV9YTUwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19QUk9DRVNTSU5HSU5TVFJVQ1RJT05fTk9UVkFMSURfTkNOQU1FID0KLSAgICAgICAgICJXR19QUk9DRVNTSU5HSU5TVFJVQ1RJT05fTk9UVkFMSURfTkNOQU1FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfSUxMRUdBTF9BVFRSSUJVVEVfUE9TSVRJT04gPQotICAgICAgICAgIldHX0lMTEVHQUxfQVRUUklCVVRFX1BPU0lUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSID0KLSAgICAgICAgICJOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIiOwotCi0gIC8qCi0gICAqIE5vdyBmaWxsIGluIHRoZSBtZXNzYWdlIHRleHQuCi0gICAqIFRoZW4gZmlsbCBpbiB0aGUgbWVzc2FnZSB0ZXh0IGZvciB0aGF0IG1lc3NhZ2UgY29kZSBpbiB0aGUKLSAgICogYXJyYXkuIFVzZSB0aGUgbmV3IGVycm9yIGNvZGUgYXMgdGhlIGluZGV4IGludG8gdGhlIGFycmF5LgotICAgKi8KLQotICAvLyBFcnJvciBtZXNzYWdlcy4uLgotCi0gIC8qKiBHZXQgdGhlIGxvb2t1cCB0YWJsZSBmb3IgZXJyb3IgbWVzc2FnZXMuCi0gICAgKgotICAgICogQHJldHVybiBUaGUgbWVzc2FnZSBsb29rdXAgdGFibGUuCi0gICAgKi8KLSAgcHVibGljIE9iamVjdFtdW10gZ2V0Q29udGVudHMoKQotICB7Ci0gICAgICByZXR1cm4gbmV3IE9iamVjdFtdW10gewotCi0gIC8qKiBFcnJvciBtZXNzYWdlIElEIHRoYXQgaGFzIGEgbnVsbCBtZXNzYWdlLCBidXQgdGFrZXMgaW4gYSBzaW5nbGUgb2JqZWN0LiAgICAqLwotICB7IkVSMDAwMCIgLCAiezB9IiB9LAotCi0gICAgeyBFUl9OT19DVVJMWUJSQUNFLAotICAgICAgIkVycm9yZTogJ3snIG5vbiBwdVx1MDBGMiBlc2lzdGVyZSBuZWxsJ2VzcHJlc3Npb25lIn0sCi0KLSAgICB7IEVSX0lMTEVHQUxfQVRUUklCVVRFICwKLSAgICAgInswfSBoYSB1biBhdHRyaWJ1dG8gbm9uIHZhbGlkbzogezF9In0sCi0KLSAge0VSX05VTExfU09VUkNFTk9ERV9BUFBMWUlNUE9SVFMgLAotICAgICAgInNvdXJjZU5vZGUgbnVsbG8gaW4geHNsOmFwcGx5LWltcG9ydHMuIn0sCi0KLSAge0VSX0NBTk5PVF9BREQsCi0gICAgICAiSW1wb3NzaWJpbGUgYWdnaXVuZ2VyZSB7MH0gYSB7MX0ifSwKLQotICAgIHsgRVJfTlVMTF9TT1VSQ0VOT0RFX0hBTkRMRUFQUExZVEVNUExBVEVTLAotICAgICAgInNvdXJjZU5vZGUgbnVsbG8gaW4gaGFuZGxlQXBwbHlUZW1wbGF0ZXNJbnN0cnVjdGlvbi4ifSwKLQotICAgIHsgRVJfTk9fTkFNRV9BVFRSSUIsCi0gICAgICJ7MH0gZGV2ZSBhdmVyZSB1biBhdHRyaWJ1dG8gbmFtZS4ifSwKLQotICAgIHtFUl9URU1QTEFURV9OT1RfRk9VTkQsCi0gICAgICJJbXBvc3NpYmlsZSB0cm92YXJlIGlsIG1vZGVsbG8gZGVub21pbmF0byB7MH0ifSwKLQotICAgIHtFUl9DQU5UX1JFU09MVkVfTkFNRV9BVlQsCi0gICAgICAiSW1wb3NzaWJpbGUgcmlzb2x2ZXJlIGwnQVZUIGRlbCBub21lIGluIHhzbDpjYWxsLXRlbXBsYXRlLiJ9LAotCi0gICAge0VSX1JFUVVJUkVTX0FUVFJJQiwKLSAgICAgInswfSByaWNoaWVkZSBsJydhdHRyaWJ1dG86IHsxfSJ9LAotCi0gICAgeyBFUl9NVVNUX0hBVkVfVEVTVF9BVFRSSUIsCi0gICAgICAiezB9IGRldmUgYXZlcmUgdW4gYXR0cmlidXRvIFwidGVzdFwiLiJ9LAotCi0gICAge0VSX0JBRF9WQUxfT05fTEVWRUxfQVRUUklCLAotICAgICAgIlZhbG9yZSBub24gdmFsaWRvIHBlciBsJydhdHRyaWJ1dG8gbGV2ZWw6IHswfSJ9LAotCi0gICAge0VSX1BST0NFU1NJTkdJTlNUUlVDVElPTl9OQU1FX0NBTlRfQkVfWE1MLAotICAgICAgImlsIG5vbWUgcHJvY2Vzc2luZy1pbnN0cnVjdGlvbiBub24gcHVcdTAwRjIgZXNzZXJlICd4bWwnIn0sCi0KLSAgICB7IEVSX1BST0NFU1NJTkdJTlNUUlVDVElPTl9OT1RWQUxJRF9OQ05BTUUsCi0gICAgICAiaWwgbm9tZSBwcm9jZXNzaW5nLWluc3RydWN0aW9uIGRldmUgZXNzZXJlIHVuIE5DTmFtZSB2YWxpZG86IHswfSJ9LAotCi0gICAgeyBFUl9ORUVEX01BVENIX0FUVFJJQiwKLSAgICAgICJ7MH0gZGV2ZSBhdmVyZSB1biBhdHRyaWJ1dG8gbWF0Y2ggc2UgZGlzcG9uZSBkaSB1bmEgbW9kYWxpdFx1MDBFMC4ifSwKLQotICAgIHsgRVJfTkVFRF9OQU1FX09SX01BVENIX0FUVFJJQiwKLSAgICAgICJ7MH0gcmljaGllZGUgdW4gbm9tZSBvIHVuIGF0dHJpYnV0byBtYXRjaC4ifSwKLQotICAgIHtFUl9DQU5UX1JFU09MVkVfTlNQUkVGSVgsCi0gICAgICAiSW1wb3NzaWJpbGUgcmlzb2x2ZXJlIGlsIHByZWZpc3NvIHNwYXppbyBkaSBub21pIHswfSJ9LAotCi0gICAgeyBFUl9JTExFR0FMX1ZBTFVFLAotICAgICAieG1sOnNwYWNlIGhhIHVuIHZhbG9yZSBub24gdmFsaWRvIHswfSJ9LAotCi0gICAgeyBFUl9OT19PV05FUkRPQywKLSAgICAgICJJbCBub2RvIGZpZ2xpbyBub24gZGlzcG9uZSBkaSB1biBkb2N1bWVudG8gcHJvcHJpZXRhcmlvLiJ9LAotCi0gICAgeyBFUl9FTEVNVEVNUExBVEVFTEVNX0VSUiwKLSAgICAgIkVycm9yZSBkaSBFbGVtVGVtcGxhdGVFbGVtZW50OiB7MH0ifSwKLQotICAgIHsgRVJfTlVMTF9DSElMRCwKLSAgICAgIlRlbnRhdGl2byBkaSBhZ2dpdW5nZXJlIHVuIGVsZW1lbnRvIGZpZ2xpbyBudWxsby4ifSwKLQotICAgIHsgRVJfTkVFRF9TRUxFQ1RfQVRUUklCLAotICAgICAiezB9IHJpY2hpZWRlIHVuIGF0dHJpYnV0byBzZWxlY3QuIn0sCi0KLSAgICB7IEVSX05FRURfVEVTVF9BVFRSSUIgLAotICAgICAgInhzbDp3aGVuIGRldmUgYXZlcmUgdW4gYXR0cmlidXRvICd0ZXN0Jy4ifSwKLQotICAgIHsgRVJfTkVFRF9OQU1FX0FUVFJJQiwKLSAgICAgICJ4c2w6d2l0aC1wYXJhbSBkZXZlIGF2ZXJlIHVuIGF0dHJpYnV0byAnbmFtZScuIn0sCi0KLSAgICB7IEVSX05PX0NPTlRFWFRfT1dORVJET0MsCi0gICAgICAiaWwgY29udGVzdG8gbm9uIGRpc3BvbmUgZGkgdW4gZG9jdW1lbnRvIHByb3ByaWV0YXJpby4ifSwKLQotICAgIHtFUl9DT1VMRF9OT1RfQ1JFQVRFX1hNTF9QUk9DX0xJQUlTT04sCi0gICAgICAiSW1wb3NzaWJpbGUgY3JlYXJlIGxhIHJlbGF6aW9uZSBUcmFuc2Zvcm1lckZhY3RvcnkgWE1MIHswfSJ9LAotCi0gICAge0VSX1BST0NFU1NfTk9UX1NVQ0NFU1NGVUwsCi0gICAgICAiWGFsYW46IHByb2Nlc3NvIG5vbiByaXVzY2l0by4ifSwKLQotICAgIHsgRVJfTk9UX1NVQ0NFU1NGVUwsCi0gICAgICJYYWxhbjogb3BlcmF6aW9uZSBub24gcml1c2NpdGEuIn0sCi0KLSAgICB7IEVSX0VOQ09ESU5HX05PVF9TVVBQT1JURUQsCi0gICAgICJDb2RpZmljYSBub24gc3VwcG9ydGF0YTogezB9In0sCi0KLSAgICB7RVJfQ09VTERfTk9UX0NSRUFURV9UUkFDRUxJU1RFTkVSLAotICAgICAgIkltcG9zc2liaWxlIGNyZWFyZSBUcmFjZUxpc3RlbmVyIHswfSJ9LAotCi0gICAge0VSX0tFWV9SRVFVSVJFU19OQU1FX0FUVFJJQiwKLSAgICAgICJ4c2w6a2V5IHJpY2hpZWRlIHVuIGF0dHJpYnV0byAnbmFtZScuIn0sCi0KLSAgICB7IEVSX0tFWV9SRVFVSVJFU19NQVRDSF9BVFRSSUIsCi0gICAgICAieHNsOmtleSByaWNoaWVkZSB1biBhdHRyaWJ1dG8gJ21hdGNoJy4ifSwKLQotICAgIHsgRVJfS0VZX1JFUVVJUkVTX1VTRV9BVFRSSUIsCi0gICAgICAieHNsOmtleSByaWNoaWVkZSB1biBhdHRyaWJ1dG8gJ3VzZScuIn0sCi0KLSAgICB7IEVSX1JFUVVJUkVTX0VMRU1FTlRTX0FUVFJJQiwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIHswfSByaWNoaWVkZSB1biBhdHRyaWJ1dG8gJydlbGVtZW50cycnLiJ9LAotCi0gICAgeyBFUl9NSVNTSU5HX1BSRUZJWF9BVFRSSUIsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSB7MH0gYXR0cmlidXRvICcncHJlZml4JycgbWFuY2FudGUifSwKLQotICAgIHsgRVJfQkFEX1NUWUxFU0hFRVRfVVJMLAotICAgICAiVVJMIGRlbCBmb2dsaW8gZGkgc3RpbGUgbm9uIHZhbGlkbzogezB9In0sCi0KLSAgICB7IEVSX0ZJTEVfTk9UX0ZPVU5ELAotICAgICAiRmlsZSBkZWwgZm9nbGlvIGRpIHN0aWxlIG5vbiB0cm92YXRvOiB7MH0ifSwKLQotICAgIHsgRVJfSU9FWENFUFRJT04sCi0gICAgICAiRWNjZXppb25lIElPIGNvbiBpbCBmaWxlIGZvZ2xpbyBkaSBzdGlsZTogezB9In0sCi0KLSAgICB7IEVSX05PX0hSRUZfQVRUUklCLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgSW1wb3NzaWJpbGUgdHJvdmFyZSBsJydhdHRyaWJ1dG8gaHJlZiBwZXIgezB9In0sCi0KLSAgICB7IEVSX1NUWUxFU0hFRVRfSU5DTFVERVNfSVRTRUxGLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgezB9IGluY2x1ZGUgc1x1MDBFOSBzdGVzc28gZGlyZXR0YW1lbnRlIG8gaW5kaXJldHRhbWVudGUuIn0sCi0KLSAgICB7IEVSX1BST0NFU1NJTkNMVURFX0VSUk9SLAotICAgICAgIkVycm9yZSBkaSBTdHlsZXNoZWV0SGFuZGxlci5wcm9jZXNzSW5jbHVkZTogezB9In0sCi0KLSAgICB7IEVSX01JU1NJTkdfTEFOR19BVFRSSUIsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSB7MH0gYXR0cmlidXRvICcnbGFuZycnIG1hbmNhbnRlIn0sCi0KLSAgICB7IEVSX01JU1NJTkdfQ09OVEFJTkVSX0VMRU1FTlRfQ09NUE9ORU5ULAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgcG9zaXppb25lIGVycmF0YSBkZWxsJydlbGVtZW50byB7MH0uIEVsZW1lbnRvICcnY29tcG9uZW50JycgZGVsIGNvbnRlbml0b3JlIG1hbmNhbnRlLiJ9LAotCi0gICAgeyBFUl9DQU5fT05MWV9PVVRQVVRfVE9fRUxFTUVOVCwKLSAgICAgICJMJ291dHB1dCBwdVx1MDBGMiBlc3NlcmUgZXNlZ3VpdG8gc29sbyBzdSBFbGVtZW50LCBEb2N1bWVudEZyYWdtZW50LCBEb2N1bWVudCBvIFByaW50V3JpdGVyLiJ9LAotCi0gICAgeyBFUl9QUk9DRVNTX0VSUk9SLAotICAgICAiRXJyb3JlIGRpIFN0eWxlc2hlZXRSb290LnByb2Nlc3MifSwKLQotICAgIHsgRVJfVU5JTVBMTk9ERV9FUlJPUiwKLSAgICAgIkVycm9yZSBkaSBVbkltcGxOb2RlOiB7MH0ifSwKLQotICAgIHsgRVJfTk9fU0VMRUNUX0VYUFJFU1NJT04sCi0gICAgICAiRXJyb3JlLiBMJ2VzcHJlc3Npb25lIGRpIHNlbGV6aW9uZSBkZWxsJ3hwYXRoICgtc2VsZWN0KSBub24gXHUwMEU4IHN0YXRhIHRyb3ZhdGEuIn0sCi0KLSAgICB7IEVSX0NBTk5PVF9TRVJJQUxJWkVfWFNMUFJPQ0VTU09SLAotICAgICAgIkltcG9zc2liaWxlIHNlcmlhbGl6emFyZSB1biBYU0xQcm9jZXNzb3IuIn0sCi0KLSAgICB7IEVSX05PX0lOUFVUX1NUWUxFU0hFRVQsCi0gICAgICAiSW5wdXQgZGVsIGZvZ2xpbyBkaSBzdGlsZSBub24gc3BlY2lmaWNhdG8uIn0sCi0KLSAgICB7IEVSX0ZBSUxFRF9QUk9DRVNTX1NUWUxFU0hFRVQsCi0gICAgICAiRWxhYm9yYXppb25lIGRlbCBmb2dsaW8gZGkgc3RpbGUgbm9uIHJpdXNjaXRhLiJ9LAotCi0gICAgeyBFUl9DT1VMRE5UX1BBUlNFX0RPQywKLSAgICAgIkltcG9zc2liaWxlIGFuYWxpenphcmUgaWwgZG9jdW1lbnRvIHswfSJ9LAotCi0gICAgeyBFUl9DT1VMRE5UX0ZJTkRfRlJBR01FTlQsCi0gICAgICJJbXBvc3NpYmlsZSB0cm92YXJlIGlsIGZyYW1tZW50byB7MH0ifSwKLQotICAgIHsgRVJfTk9ERV9OT1RfRUxFTUVOVCwKLSAgICAgICJJbCBub2RvIGEgY3VpIHB1bnRhIGwnJ2lkZW50aWZpY2F0aXZvIGRpIGZyYW1tZW50byBub24gXHUwMEU4IHVuIGVsZW1lbnRvOiB7MH0ifSwKLQotICAgIHsgRVJfRk9SRUFDSF9ORUVEX01BVENIX09SX05BTUVfQVRUUklCLAotICAgICAgImZvci1lYWNoIGRldmUgYXZlcmUgdW4gYXR0cmlidXRvIG1hdGNoIG8gbmFtZSJ9LAotCi0gICAgeyBFUl9URU1QTEFURVNfTkVFRF9NQVRDSF9PUl9OQU1FX0FUVFJJQiwKLSAgICAgICJ0ZW1wbGF0ZXMgZGV2ZSBhdmVyZSB1biBhdHRyaWJ1dG8gbWF0Y2ggbyBuYW1lIn0sCi0KLSAgICB7IEVSX05PX0NMT05FX09GX0RPQ1VNRU5UX0ZSQUcsCi0gICAgICAiTmVzc3VuIGR1cGxpY2F0byBkaSB1biBmcmFtbWVudG8gZGkgZG9jdW1lbnRvLiJ9LAotCi0gICAgeyBFUl9DQU5UX0NSRUFURV9JVEVNLAotICAgICAgIkltcG9zc2liaWxlIGNyZWFyZSB1bmEgdm9jZSBuZWxsYSBzdHJ1dHR1cmEgZGVpIHJpc3VsdGF0aTogezB9In0sCi0KLSAgICB7IEVSX1hNTFNQQUNFX0lMTEVHQUxfVkFMVUUsCi0gICAgICAieG1sOnNwYWNlIG5lbGwnJ1hNTCBkaSBvcmlnaW5lIGhhIHVuIHZhbG9yZSBub24gdmFsaWRvIHswfSJ9LAotCi0gICAgeyBFUl9OT19YU0xLRVlfREVDTEFSQVRJT04sCi0gICAgICAiTmVzc3VuYSBkaWNoaWFyYXppb25lIHhzbDprZXkgcGVyIHswfS4ifSwKLQotICAgIHsgRVJfQ0FOVF9DUkVBVEVfVVJMLAotICAgICAiRXJyb3JlLiBJbXBvc3NpYmlsZSBjcmVhcmUgbCcnVVJMIHBlciB7MH0ifSwKLQotICAgIHsgRVJfWFNMRlVOQ1RJT05TX1VOU1VQUE9SVEVELAotICAgICAieHNsOmZ1bmN0aW9ucyBub24gc3VwcG9ydGF0byJ9LAotCi0gICAgeyBFUl9QUk9DRVNTT1JfRVJST1IsCi0gICAgICJFcnJvcmUgZGkgVHJhbnNmb3JtZXJGYWN0b3J5IFhTTFQifSwKLQotICAgIHsgRVJfTk9UX0FMTE9XRURfSU5TSURFX1NUWUxFU0hFRVQsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSB7MH0gbm9uIGNvbnNlbnRpdG8gaW4gdW4gZm9nbGlvIGRpIHN0aWxlLiJ9LAotCi0gICAgeyBFUl9SRVNVTFROU19OT1RfU1VQUE9SVEVELAotICAgICAgInJlc3VsdC1ucyBub24gcGlcdTAwRjkgc3VwcG9ydGF0by4gVXRpbGl6emFyZSB4c2w6b3V0cHV0LiJ9LAotCi0gICAgeyBFUl9ERUZBVUxUU1BBQ0VfTk9UX1NVUFBPUlRFRCwKLSAgICAgICJkZWZhdWx0LXNwYWNlIG5vbiBwaVx1MDBGOSBzdXBwb3J0YXRvLiBVdGlsaXp6YXJlIHhzbDpzdHJpcC1zcGFjZSBvIHhzbDpwcmVzZXJ2ZS1zcGFjZS4ifSwKLQotICAgIHsgRVJfSU5ERU5UUkVTVUxUX05PVF9TVVBQT1JURUQsCi0gICAgICAiaW5kZW50LXJlc3VsdCBub24gcGlcdTAwRjkgc3VwcG9ydGF0by4gVXRpbGl6emFyZSB4c2w6b3V0cHV0LiJ9LAotCi0gICAgeyBFUl9JTExFR0FMX0FUVFJJQiwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIHswfSBoYSB1biBhdHRyaWJ1dG8gbm9uIHZhbGlkbzogezF9In0sCi0KLSAgICB7IEVSX1VOS05PV05fWFNMX0VMRU0sCi0gICAgICJFbGVtZW50byBYU0wgc2Nvbm9zY2l1dG86IHswfSJ9LAotCi0gICAgeyBFUl9CQURfWFNMU09SVF9VU0UsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSB4c2w6c29ydCBwdVx1MDBGMiBlc3NlcmUgdXRpbGl6emF0byBzb2xvIGNvbiB4c2w6YXBwbHktdGVtcGxhdGVzIG8geHNsOmZvci1lYWNoLiJ9LAotCi0gICAgeyBFUl9NSVNQTEFDRURfWFNMV0hFTiwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIHBvc2l6aW9uZSBlcnJhdGEgZGkgeHNsOndoZW4uIn0sCi0KLSAgICB7IEVSX1hTTFdIRU5fTk9UX1BBUkVOVEVEX0JZX1hTTENIT09TRSwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIHhzbDp3aGVuIG5vbiBhc3NvY2lhdG8gZGEgeHNsOmNob29zZS4ifSwKLQotICAgIHsgRVJfTUlTUExBQ0VEX1hTTE9USEVSV0lTRSwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIHBvc2l6aW9uZSBlcnJhdGEgZGkgeHNsOm90aGVyd2lzZS4ifSwKLQotICAgIHsgRVJfWFNMT1RIRVJXSVNFX05PVF9QQVJFTlRFRF9CWV9YU0xDSE9PU0UsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSB4c2w6b3RoZXJ3aXNlIG5vbiBhc3NvY2lhdG8gZGEgeHNsOmNob29zZS4ifSwKLQotICAgIHsgRVJfTk9UX0FMTE9XRURfSU5TSURFX1RFTVBMQVRFLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgezB9IG5vbiBjb25zZW50aXRvIGluIHVuIG1vZGVsbG8uIn0sCi0KLSAgICB7IEVSX1VOS05PV05fRVhUX05TX1BSRUZJWCwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIHswfSBwcmVmaXNzbyBzcGF6aW8gZGkgbm9taSBlc3RlbnNpb25lIHsxfSBzY29ub3NjaXV0byJ9LAotCi0gICAgeyBFUl9JTVBPUlRTX0FTX0ZJUlNUX0VMRU0sCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSBMZSBpbXBvcnRhemlvbmkgcG9zc29ubyBlc3NlcmUgZXNlZ3VpdGUgc29sbyBjb21lIHByaW1pIGVsZW1lbnRpIG5lbCBmb2dsaW8gZGkgc3RpbGUuIn0sCi0KLSAgICB7IEVSX0lNUE9SVElOR19JVFNFTEYsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSB7MH0gaW1wb3J0YSBzXHUwMEU5IHN0ZXNzbyBkaXJldHRhbWVudGUgbyBpbmRpcmV0dGFtZW50ZS4ifSwKLQotICAgIHsgRVJfWE1MU1BBQ0VfSUxMRUdBTF9WQUwsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSB4bWw6c3BhY2UgaGEgdW4gdmFsb3JlIG5vbiB2YWxpZG8gezB9In0sCi0KLSAgICB7IEVSX1BST0NFU1NTVFlMRVNIRUVUX05PVF9TVUNDRVNTRlVMLAotICAgICAgInByb2Nlc3NTdHlsZXNoZWV0IG5vbiByaXVzY2l0by4ifSwKLQotICAgIHsgRVJfU0FYX0VYQ0VQVElPTiwKLSAgICAgIkVjY2V6aW9uZSBTQVgifSwKLQotLy8gIGFkZCB0aGlzIG1lc3NhZ2UgdG8gZml4IGJ1ZyAyMTQ3OAotICAgIHsgRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCwKLSAgICAgIkZ1bnppb25lIG5vbiBzdXBwb3J0YXRhLiJ9LAotCi0gICAgeyBFUl9YU0xUX0VSUk9SLAotICAgICAiRXJyb3JlIFhTTFQifSwKLQotICAgIHsgRVJfQ1VSUkVOQ1lfU0lHTl9JTExFR0FMLAotICAgICAgImlsIHNpbWJvbG8gZGVsbGEgdmFsdXRhIG5vbiBcdTAwRTggY29uc2VudGl0byBpbiB1bmEgc3RyaW5nYSBkaSBwYXR0ZXJuIGRpIGZvcm1hdG8ifSwKLQotICAgIHsgRVJfRE9DVU1FTlRfRlVOQ1RJT05fSU5WQUxJRF9JTl9TVFlMRVNIRUVUX0RPTSwKLSAgICAgICJGdW56aW9uZSBkZWwgZG9jdW1lbnRvIG5vbiBzdXBwb3J0YXRhIG5lbCBET00gZGVsIGZvZ2xpbyBkaSBzdGlsZS4ifSwKLQotICAgIHsgRVJfQ0FOVF9SRVNPTFZFX1BSRUZJWF9PRl9OT05fUFJFRklYX1JFU09MVkVSLAotICAgICAgIkltcG9zc2liaWxlIHJpc29sdmVyZSBpbCBwcmVmaXNzbyBkaSB1biByZXNvbHZlciBzZW56YSBwcmVmaXNzaS4ifSwKLQotICAgIHsgRVJfUkVESVJFQ1RfQ09VTEROVF9HRVRfRklMRU5BTUUsCi0gICAgICAiRXN0ZW5zaW9uZSBkaSByZWluZGlyaXp6YW1lbnRvOiBpbXBvc3NpYmlsZSB0cm92YXJlIGlsIG5vbWUgZmlsZS4gTCdhdHRyaWJ1dG8gZmlsZSBvIHNlbGVjdCBkZXZlIHJlc3RpdHVpcmUgdW5hIHN0cmluZ2EgdmFsaWRhLiJ9LAotCi0gICAgeyBFUl9DQU5OT1RfQlVJTERfRk9STUFUVEVSTElTVEVORVJfSU5fUkVESVJFQ1QsCi0gICAgICAiSW1wb3NzaWJpbGUgY3JlYXJlIEZvcm1hdHRlckxpc3RlbmVyIG5lbGwnZXN0ZW5zaW9uZSBkaSByZWluZGlyaXp6YW1lbnRvLiJ9LAotCi0gICAgeyBFUl9JTlZBTElEX1BSRUZJWF9JTl9FWENMVURFUkVTVUxUUFJFRklYLAotICAgICAgIklsIHByZWZpc3NvIGluIGV4Y2x1ZGUtcmVzdWx0LXByZWZpeGVzIG5vbiBcdTAwRTggdmFsaWRvOiB7MH0ifSwKLQotICAgIHsgRVJfTUlTU0lOR19OU19VUkksCi0gICAgICAiVVJJIGRlbGxvIHNwYXppbyBkaSBub21pIG1hbmNhbnRlIHBlciBpbCBwcmVmaXNzbyBzcGVjaWZpY2F0byJ9LAotCi0gICAgeyBFUl9NSVNTSU5HX0FSR19GT1JfT1BUSU9OLAotICAgICAgIkFyZ29tZW50byBtYW5jYW50ZSBwZXIgbCcnb3B6aW9uZTogezB9In0sCi0KLSAgICB7IEVSX0lOVkFMSURfT1BUSU9OLAotICAgICAiT3B6aW9uZSBub24gdmFsaWRhOiB7MH0ifSwKLQotICAgIHsgRVJfTUFMRk9STUVEX0ZPUk1BVF9TVFJJTkcsCi0gICAgICJTdHJpbmdhIGNvbiBmb3JtYXRvIGVycmF0bzogezB9In0sCi0KLSAgICB7IEVSX1NUWUxFU0hFRVRfUkVRVUlSRVNfVkVSU0lPTl9BVFRSSUIsCi0gICAgICAieHNsOnN0eWxlc2hlZXQgcmljaGllZGUgdW4gYXR0cmlidXRvICd2ZXJzaW9uJy4ifSwKLQotICAgIHsgRVJfSUxMRUdBTF9BVFRSSUJVVEVfVkFMVUUsCi0gICAgICAiTCcnYXR0cmlidXRvIHswfSBoYSB1biB2YWxvcmUgbm9uIHZhbGlkbyB7MX0ifSwKLQotICAgIHsgRVJfQ0hPT1NFX1JFUVVJUkVTX1dIRU4sCi0gICAgICJ4c2w6Y2hvb3NlIHJpY2hpZWRlIHhzbDp3aGVuIn0sCi0KLSAgICB7IEVSX05PX0FQUExZX0lNUE9SVF9JTl9GT1JfRUFDSCwKLSAgICAgICJ4c2w6YXBwbHktaW1wb3J0cyBub24gY29uc2VudGl0byBpbiB4c2w6Zm9yLWVhY2gifSwKLQotICAgIHsgRVJfQ0FOVF9VU0VfRFRNX0ZPUl9PVVRQVVQsCi0gICAgICAiSW1wb3NzaWJpbGUgdXRpbGl6emFyZSBEVE1MaWFpc29uIHBlciB1biBub2RvIERPTSBkaSBvdXRwdXQuLi4gUGFzc2FyZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuRE9NMkhlbHBlci4ifSwKLQotICAgIHsgRVJfQ0FOVF9VU0VfRFRNX0ZPUl9JTlBVVCwKLSAgICAgICJJbXBvc3NpYmlsZSB1dGlsaXp6YXJlIERUTUxpYWlzb24gcGVyIHVuIG5vZG8gRE9NIGRpIGlucHV0Li4uIFBhc3NhcmUgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLkRPTTJIZWxwZXIuIn0sCi0KLSAgICB7IEVSX0NBTExfVE9fRVhUX0ZBSUxFRCwKLSAgICAgICJDaGlhbWF0YSBhbGwnJ2VsZW1lbnRvIGRpIGVzdGVuc2lvbmUgbm9uIHJpdXNjaXRhOiB7MH0ifSwKLQotICAgIHsgRVJfUFJFRklYX01VU1RfUkVTT0xWRSwKLSAgICAgICJJbCBwcmVmaXNzbyBkZXZlIGVzc2VyZSByaXNvbHRvIGluIHVubyBzcGF6aW8gZGkgbm9taTogezB9In0sCi0KLSAgICB7IEVSX0lOVkFMSURfVVRGMTZfU1VSUk9HQVRFLAotICAgICAgIlJpbGV2YXRvIHN1cnJvZ2F0byBVVEYtMTYgbm9uIHZhbGlkbzogezB9PyJ9LAotCi0gICAgeyBFUl9YU0xBVFRSU0VUX1VTRURfSVRTRUxGLAotICAgICAgInhzbDphdHRyaWJ1dGUtc2V0IHswfSB1dGlsaXp6YSBzXHUwMEU5IHN0ZXNzbywgaWwgY2hlIHB1XHUwMEYyIGNhdXNhcmUgdW4gbG9vcCBpbmZpbml0by4ifSwKLQotICAgIHsgRVJfQ0FOTk9UX01JWF9YRVJDRVNET00sCi0gICAgICAiSW1wb3NzaWJpbGUgdW5pcmUgaW5wdXQgbm9uIFhlcmNlcy1ET00gY29uIG91dHB1dCBYZXJjZXMtRE9NLiJ9LAotCi0gICAgeyBFUl9UT09fTUFOWV9MSVNURU5FUlMsCi0gICAgICAiYWRkVHJhY2VMaXN0ZW5lcnNUb1N0eWxlc2hlZXQgLSBUb29NYW55TGlzdGVuZXJzRXhjZXB0aW9uIn0sCi0KLSAgICB7IEVSX0lOX0VMRU1URU1QTEFURUVMRU1fUkVBRE9CSkVDVCwKLSAgICAgICJJbiBFbGVtVGVtcGxhdGVFbGVtZW50LnJlYWRPYmplY3Q6IHswfSJ9LAotCi0gICAgeyBFUl9EVVBMSUNBVEVfTkFNRURfVEVNUExBVEUsCi0gICAgICAiU29ubyBzdGF0aSB0cm92YXRpIHBpXHUwMEY5IG1vZGVsbGkgZGVub21pbmF0aSB7MH0ifSwKLQotICAgIHsgRVJfSU5WQUxJRF9LRVlfQ0FMTCwKLSAgICAgICJDaGlhbWF0YSBkaSBmdW56aW9uZSBub24gdmFsaWRhOiBub24gc29ubyBjb25zZW50aXRlIGNoaWFtYXRlIHJlY3Vyc2l2ZSBrZXkoKSJ9LAotCi0gICAgeyBFUl9SRUZFUkVOQ0lOR19JVFNFTEYsCi0gICAgICAiTGEgdmFyaWFiaWxlIHswfSBmYSByaWZlcmltZW50byBhIHNcdTAwRTkgc3Rlc3NhIGRpcmV0dGFtZW50ZSBvIGluZGlyZXR0YW1lbnRlLiJ9LAotCi0gICAgeyBFUl9JTExFR0FMX0RPTVNPVVJDRV9JTlBVVCwKLSAgICAgICJJbCBub2RvIGRpIGlucHV0IG5vbiBwdVx1MDBGMiBlc3NlcmUgbnVsbG8gcGVyIHVuIERPTVNvdXJjZSBwZXIgbmV3VGVtcGxhdGVzLiJ9LAotCi0gICAgeyBFUl9DTEFTU19OT1RfRk9VTkRfRk9SX09QVElPTiwKLSAgICAgICAgIkZpbGUgZGkgY2xhc3NlIG5vbiB0cm92YXRvIHBlciBsJydvcHppb25lIHswfSJ9LAotCi0gICAgeyBFUl9SRVFVSVJFRF9FTEVNX05PVF9GT1VORCwKLSAgICAgICAgIkVsZW1lbnRvIHJpY2hpZXN0byBub24gdHJvdmF0bzogezB9In0sCi0KLSAgICB7IEVSX0lOUFVUX0NBTk5PVF9CRV9OVUxMLAotICAgICAgICAiSW5wdXRTdHJlYW0gbm9uIHB1XHUwMEYyIGVzc2VyZSBudWxsbyJ9LAotCi0gICAgeyBFUl9VUklfQ0FOTk9UX0JFX05VTEwsCi0gICAgICAgICJMJ1VSSSBub24gcHVcdTAwRjIgZXNzZXJlIG51bGxvIn0sCi0KLSAgICB7IEVSX0ZJTEVfQ0FOTk9UX0JFX05VTEwsCi0gICAgICAgICJJbCBmaWxlIG5vbiBwdVx1MDBGMiBlc3NlcmUgbnVsbG8ifSwKLQotICAgIHsgRVJfU09VUkNFX0NBTk5PVF9CRV9OVUxMLAotICAgICAgICAgICAgICAgICJJbnB1dFNvdXJjZSBub24gcHVcdTAwRjIgZXNzZXJlIG51bGxvIn0sCi0KLSAgICB7IEVSX0NBTk5PVF9JTklUX0JTRk1HUiwKLSAgICAgICAgICAgICAgICAiSW1wb3NzaWJpbGUgaW5pemlhbGl6emFyZSBCU0YgTWFuYWdlciJ9LAotCi0gICAgeyBFUl9DQU5OT1RfQ01QTF9FWFRFTlNOLAotICAgICAgICAgICAgICAgICJJbXBvc3NpYmlsZSBjb21waWxhcmUgbCdlc3RlbnNpb25lIn0sCi0KLSAgICB7IEVSX0NBTk5PVF9DUkVBVEVfRVhURU5TTiwKLSAgICAgICJJbXBvc3NpYmlsZSBjcmVhcmUgbCcnZXN0ZW5zaW9uZSB7MH0uIE1vdGl2bzogezF9In0sCi0KLSAgICB7IEVSX0lOU1RBTkNFX01USERfQ0FMTF9SRVFVSVJFUywKLSAgICAgICJMYSBjaGlhbWF0YSBkZWwgbWV0b2RvIGRpIGlzdGFuemEgezB9IHJpY2hpZWRlIHVuJydpc3RhbnphIGRpIG9nZ2V0dG8gY29tZSBwcmltbyBhcmdvbWVudG8ifSwKLQotICAgIHsgRVJfSU5WQUxJRF9FTEVNRU5UX05BTUUsCi0gICAgICAiU3BlY2lmaWNhdG8gbm9tZSBlbGVtZW50byB7MH0gbm9uIHZhbGlkbyJ9LAotCi0gICAgeyBFUl9FTEVNRU5UX05BTUVfTUVUSE9EX1NUQVRJQywKLSAgICAgICJJbCBtZXRvZG8gZGkgbm9tZSBlbGVtZW50byBkZXZlIGVzc2VyZSBzdGF0aWNvIHswfSJ9LAotCi0gICAgeyBFUl9FWFRFTlNJT05fRlVOQ19VTktOT1dOLAotICAgICAgICAgICAgICJGdW56aW9uZSBkaSBlc3RlbnNpb25lIHswfSA6IHsxfSBzY29ub3NjaXV0YSJ9LAotCi0gICAgeyBFUl9NT1JFX01BVENIX0NPTlNUUlVDVE9SLAotICAgICAgICAgICAgICJFc2lzdG9ubyBwaVx1MDBGOSBjb3JyaXNwb25kZW56ZSBtaWdsaW9yaSBwZXIgaWwgY29zdHJ1dHRvcmUgZGkgezB9In0sCi0KLSAgICB7IEVSX01PUkVfTUFUQ0hfTUVUSE9ELAotICAgICAgICAgICAgICJFc2lzdG9ubyBwaVx1MDBGOSBjb3JyaXNwb25kZW56ZSBtaWdsaW9yaSBwZXIgaWwgbWV0b2RvIHswfSJ9LAotCi0gICAgeyBFUl9NT1JFX01BVENIX0VMRU1FTlQsCi0gICAgICAgICAgICAgIkVzaXN0b25vIHBpXHUwMEY5IGNvcnJpc3BvbmRlbnplIG1pZ2xpb3JpIHBlciBpbCBtZXRvZG8gZGkgZWxlbWVudG8gezB9In0sCi0KLSAgICB7IEVSX0lOVkFMSURfQ09OVEVYVF9QQVNTRUQsCi0gICAgICAgICAgICAgIlBhc3NhdG8gY29udGVzdG8gbm9uIHZhbGlkbyBwZXIgdmFsdXRhcmUgezB9In0sCi0KLSAgICB7IEVSX1BPT0xfRVhJU1RTLAotICAgICAgICAgICAgICJJbCBwb29sIGVzaXN0ZSBnaVx1MDBFMCJ9LAotCi0gICAgeyBFUl9OT19EUklWRVJfTkFNRSwKLSAgICAgICAgICAgICAiTmVzc3VuIG5vbWUgZHJpdmVyIHNwZWNpZmljYXRvIn0sCi0KLSAgICB7IEVSX05PX1VSTCwKLSAgICAgICAgICAgICAiTmVzc3VuIFVSTCBzcGVjaWZpY2F0byJ9LAotCi0gICAgeyBFUl9QT09MX1NJWkVfTEVTU1RIQU5fT05FLAotICAgICAgICAgICAgICJMYSBkaW1lbnNpb25lIGRlbCBwb29sIFx1MDBFOCBtaW5vcmUgZGkgdW5vLiJ9LAotCi0gICAgeyBFUl9JTlZBTElEX0RSSVZFUiwKLSAgICAgICAgICAgICAiU3BlY2lmaWNhdG8gbm9tZSBkcml2ZXIgbm9uIHZhbGlkby4ifSwKLQotICAgIHsgRVJfTk9fU1RZTEVTSEVFVFJPT1QsCi0gICAgICAgICAgICAgIlJhZGljZSBkZWwgZm9nbGlvIGRpIHN0aWxlIG5vbiB0cm92YXRhLiJ9LAotCi0gICAgeyBFUl9JTExFR0FMX1hNTFNQQUNFX1ZBTFVFLAotICAgICAgICAgIlZhbG9yZSBub24gdmFsaWRvIHBlciB4bWw6c3BhY2UifSwKLQotICAgIHsgRVJfUFJPQ0VTU0ZST01OT0RFX0ZBSUxFRCwKLSAgICAgICAgICJwcm9jZXNzRnJvbU5vZGUgbm9uIHJpdXNjaXRvIn0sCi0KLSAgICB7IEVSX1JFU09VUkNFX0NPVUxEX05PVF9MT0FELAotICAgICAgICAiSW1wb3NzaWJpbGUgY2FyaWNhcmUgbGEgcmlzb3JzYSBbIHswfSBdOiB7MX0gXG4gezJ9IFx0IHszfSJ9LAotCi0gICAgeyBFUl9CVUZGRVJfU0laRV9MRVNTVEhBTl9aRVJPLAotICAgICAgICAiRGltZW5zaW9uZSBidWZmZXIgPD0wIn0sCi0KLSAgICB7IEVSX1VOS05PV05fRVJST1JfQ0FMTElOR19FWFRFTlNJT04sCi0gICAgICAgICJFcnJvcmUgc2Nvbm9zY2l1dG8gZHVyYW50ZSBsYSBjaGlhbWF0YSBkZWxsJ2VzdGVuc2lvbmUifSwKLQotICAgIHsgRVJfTk9fTkFNRVNQQUNFX0RFQ0wsCi0gICAgICAgICJJbCBwcmVmaXNzbyB7MH0gbm9uIGhhIHVuYSBkaWNoaWFyYXppb25lIGRpIHNwYXppbyBkaSBub21pIGNvcnJpc3BvbmRlbnRlIn0sCi0KLSAgICB7IEVSX0VMRU1fQ09OVEVOVF9OT1RfQUxMT1dFRCwKLSAgICAgICAgIkNvbnRlbnV0byBkaSBlbGVtZW50byBub24gY29uc2VudGl0byBwZXIgbGFuZz1qYXZhY2xhc3MgezB9In0sCi0KLSAgICB7IEVSX1NUWUxFU0hFRVRfRElSRUNURURfVEVSTUlOQVRJT04sCi0gICAgICAgICJJbCBmb2dsaW8gZGkgc3RpbGUgaGEgY2F1c2F0byBsJ2ludGVycnV6aW9uZSJ9LAotCi0gICAgeyBFUl9PTkVfT1JfVFdPLAotICAgICAgICAiMSBvIDIifSwKLQotICAgIHsgRVJfVFdPX09SX1RIUkVFLAotICAgICAgICAiMiBvIDMifSwKLQotICAgIHsgRVJfQ09VTERfTk9UX0xPQURfUkVTT1VSQ0UsCi0gICAgICAgICJJbXBvc3NpYmlsZSBjYXJpY2FyZSB7MH0gKHZlcmlmaWNhcmUgQ0xBU1NQQVRIKTsgdmVycmFubm8gdXRpbGl6emF0aSBpIHZhbG9yaSBwcmVkZWZpbml0aSJ9LAotCi0gICAgeyBFUl9DQU5OT1RfSU5JVF9ERUZBVUxUX1RFTVBMQVRFUywKLSAgICAgICAgIkltcG9zc2liaWxlIGluaXppYWxpenphcmUgaSBtb2RlbGxpIHByZWRlZmluaXRpIn0sCi0KLSAgICB7IEVSX1JFU1VMVF9OVUxMLAotICAgICAgICAiSWwgcmlzdWx0YXRvIG5vbiBkZXZlIGVzc2VyZSBudWxsbyJ9LAotCi0gICAgeyBFUl9SRVNVTFRfQ09VTERfTk9UX0JFX1NFVCwKLSAgICAgICAgIkltcG9zc2liaWxlIGltcG9zdGFyZSBpbCByaXN1bHRhdG8ifSwKLQotICAgIHsgRVJfTk9fT1VUUFVUX1NQRUNJRklFRCwKLSAgICAgICAgIk5lc3N1biBvdXRwdXQgc3BlY2lmaWNhdG8ifSwKLQotICAgIHsgRVJfQ0FOTk9UX1RSQU5TRk9STV9UT19SRVNVTFRfVFlQRSwKLSAgICAgICAgIkltcG9zc2liaWxlIGVzZWd1aXJlIGxhIHRyYXNmb3JtYXppb25lIGluIHVuIHJpc3VsdGF0byBkaSB0aXBvIHswfSJ9LAotCi0gICAgeyBFUl9DQU5OT1RfVFJBTlNGT1JNX1NPVVJDRV9UWVBFLAotICAgICAgICAiSW1wb3NzaWJpbGUgZXNlZ3VpcmUgbGEgdHJhc2Zvcm1hemlvbmUgaW4gdW4nJ29yaWdpbmUgZGkgdGlwbyB7MH0ifSwKLQotICAgIHsgRVJfTlVMTF9DT05URU5UX0hBTkRMRVIsCi0gICAgICAgICJIYW5kbGVyIGRlaSBjb250ZW51dGkgbnVsbG8ifSwKLQotICAgIHsgRVJfTlVMTF9FUlJPUl9IQU5ETEVSLAotICAgICAgICAiSGFuZGxlciBkZWdsaSBlcnJvcmkgbnVsbG8ifSwKLQotICAgIHsgRVJfQ0FOTk9UX0NBTExfUEFSU0UsCi0gICAgICAgICJpbXBvc3NpYmlsZSByaWNoaWFtYXJlIHBhcnNlIHNlIG5vbiBcdTAwRTggc3RhdG8gaW1wb3N0YXRvIENvbnRlbnRIYW5kbGVyIn0sCi0KLSAgICB7IEVSX05PX1BBUkVOVF9GT1JfRklMVEVSLAotICAgICAgICAiTmVzc3VuIGVsZW1lbnRvIHBhZHJlIHBlciBpbCBmaWx0cm8ifSwKLQotICAgIHsgRVJfTk9fU1RZTEVTSEVFVF9JTl9NRURJQSwKLSAgICAgICAgICJOZXNzdW4gZm9nbGlvIGRpIHN0aWxlIHRyb3ZhdG8gaW4gezB9LCBtZWRpYT0gezF9LiJ9LAotCi0gICAgeyBFUl9OT19TVFlMRVNIRUVUX1BJLAotICAgICAgICAgIk5lc3N1biBQSSB4bWwtc3R5bGVzaGVldCB0cm92YXRvIGluIHswfSJ9LAotCi0gICAgeyBFUl9OT1RfU1VQUE9SVEVELAotICAgICAgICJOb24gc3VwcG9ydGF0bzogezB9In0sCi0KLSAgICB7IEVSX1BST1BFUlRZX1ZBTFVFX0JPT0xFQU4sCi0gICAgICAgIklsIHZhbG9yZSBkZWxsYSBwcm9wcmlldFx1MDBFMCB7MH0gZGV2ZSBlc3NlcmUgdW4nJ2lzdGFuemEgYm9vbGVhbmEifSwKLQotICAgIHsgRVJfQ09VTERfTk9UX0ZJTkRfRVhURVJOX1NDUklQVCwKLSAgICAgICAgICJJbXBvc3NpYmlsZSByZWN1cGVyYXJlIGxvIHNjcmlwdCBlc3Rlcm5vIGluIHswfSJ9LAotCi0gICAgeyBFUl9SRVNPVVJDRV9DT1VMRF9OT1RfRklORCwKLSAgICAgICAgIlJpc29yc2EgWyB7MH0gXSBub24gdHJvdmF0YS5cbiB7MX0ifSwKLQotICAgIHsgRVJfT1VUUFVUX1BST1BFUlRZX05PVF9SRUNPR05JWkVELAotICAgICAgICAiUHJvcHJpZXRcdTAwRTAgZGkgb3V0cHV0IG5vbiByaWNvbm9zY2l1dGE6IHswfSJ9LAotCi0gICAgeyBFUl9GQUlMRURfQ1JFQVRJTkdfRUxFTUxJVFJTTFQsCi0gICAgICAgICJDcmVhemlvbmUgZGVsbCdpc3RhbnphIEVsZW1MaXRlcmFsUmVzdWx0IG5vbiByaXVzY2l0YSJ9LAotCi0gIC8vRWFybGllciAoSkRLIDEuNCBYQUxBTiAyLjItRDExKSBhdCBrZXkgY29kZSAnMjA0JyB0aGUga2V5IG5hbWUgd2FzIEVSX1BSSU9SSVRZX05PVF9QQVJTQUJMRQotICAvLyBJbiBsYXRlc3QgWGFsYW4gY29kZSBiYXNlIGtleSBuYW1lIGlzICBFUl9WQUxVRV9TSE9VTERfQkVfTlVNQkVSLiBUaGlzIHNob3VsZCBhbHNvIGJlIHRha2VuIGNhcmUKLSAgLy9pbiBsb2NhbGUgc3BlY2lmaWMgZmlsZXMgbGlrZSBYU0xURXJyb3JSZXNvdXJjZXNfZGUuamF2YSwgWFNMVEVycm9yUmVzb3VyY2VzX2ZyLmphdmEgZXRjLgotICAvL05PVEU6IE5vdCBvbmx5IHRoZSBrZXkgbmFtZSBidXQgbWVzc2FnZSBoYXMgYWxzbyBiZWVuIGNoYW5nZWQuCi0gICAgeyBFUl9WQUxVRV9TSE9VTERfQkVfTlVNQkVSLAotICAgICAgICAiSWwgdmFsb3JlIHBlciB7MH0gZGV2ZSBjb250ZW5lcmUgdW4gbnVtZXJvIGFuYWxpenphYmlsZSJ9LAotCi0gICAgeyBFUl9WQUxVRV9TSE9VTERfRVFVQUwsCi0gICAgICAgICJJbCB2YWxvcmUgcGVyIHswfSBkZXZlIGNvcnJpc3BvbmRlcmUgYSB5ZXMgbyBubyJ9LAotCi0gICAgeyBFUl9GQUlMRURfQ0FMTElOR19NRVRIT0QsCi0gICAgICAgICJSaWNoaWFtbyBkZWwgbWV0b2RvIHswfSBub24gcml1c2NpdG8ifSwKLQotICAgIHsgRVJfRkFJTEVEX0NSRUFUSU5HX0VMRU1UTVBMLAotICAgICAgICAiQ3JlYXppb25lIGRlbGwnaXN0YW56YSBFbGVtVGVtcGxhdGVFbGVtZW50IG5vbiByaXVzY2l0YSJ9LAotCi0gICAgeyBFUl9DSEFSU19OT1RfQUxMT1dFRCwKLSAgICAgICAgIk5vbiBzb25vIGNvbnNlbnRpdGkgY2FyYXR0ZXJpIGluIHF1ZXN0byBwdW50byBkZWwgZG9jdW1lbnRvIn0sCi0KLSAgICB7IEVSX0FUVFJfTk9UX0FMTE9XRUQsCi0gICAgICAgICJMJydhdHRyaWJ1dG8gXCJ7MH1cIiBub24gXHUwMEU4IGNvbnNlbnRpdG8gbmVsbCcnZWxlbWVudG8gezF9LiJ9LAotCi0gICAgeyBFUl9CQURfVkFMVUUsCi0gICAgICJ7MH0gdmFsb3JlIG5vbiB2YWxpZG8gezF9ICJ9LAotCi0gICAgeyBFUl9BVFRSSUJfVkFMVUVfTk9UX0ZPVU5ELAotICAgICAiezB9IHZhbG9yZSBkaSBhdHRyaWJ1dG8gbm9uIHRyb3ZhdG8gIn0sCi0KLSAgICB7IEVSX0FUVFJJQl9WQUxVRV9OT1RfUkVDT0dOSVpFRCwKLSAgICAgInswfSB2YWxvcmUgZGkgYXR0cmlidXRvIG5vbiByaWNvbm9zY2l1dG8gIn0sCi0KLSAgICB7IEVSX05VTExfVVJJX05BTUVTUEFDRSwKLSAgICAgIlRlbnRhdGl2byBkaSBnZW5lcmFyZSB1biBwcmVmaXNzbyBzcGF6aW8gZGkgbm9taSBjb24gVVJJIG51bGxvIn0sCi0KLSAgICB7IEVSX05VTUJFUl9UT09fQklHLAotICAgICAiVGVudGF0aXZvIGRpIGZvcm1hdHRhcmUgdW4gbnVtZXJvIHN1cGVyaW9yZSBhIHF1ZWxsbyBkZWwgbnVtZXJvIGludGVybyBkaSB0aXBvIExvbmcgcGlcdTAwRjkgZ3JhbmRlIn0sCi0KLSAgICB7IEVSX0NBTk5PVF9GSU5EX1NBWDFfRFJJVkVSLAotICAgICAiSW1wb3NzaWJpbGUgdHJvdmFyZSBsYSBjbGFzc2UgZGkgZHJpdmVyIFNBWDEgezB9In0sCi0KLSAgICB7IEVSX1NBWDFfRFJJVkVSX05PVF9MT0FERUQsCi0gICAgICJMYSBjbGFzc2UgZGkgZHJpdmVyIFNBWDEgezB9IFx1MDBFOCBzdGF0YSB0cm92YXRhLCBtYSBub24gcHVcdTAwRjIgZXNzZXJlIGNhcmljYXRhLiJ9LAotCi0gICAgeyBFUl9TQVgxX0RSSVZFUl9OT1RfSU5TVEFOVElBVEVELAotICAgICAiTGEgY2xhc3NlIGRpIGRyaXZlciBTQVgxIHswfSBcdTAwRTggc3RhdGEgY2FyaWNhdGEsIG1hIG5vbiBcdTAwRTggcG9zc2liaWxlIGNyZWFyZSB1bicnaXN0YW56YS4ifSwKLQotICAgIHsgRVJfU0FYMV9EUklWRVJfTk9UX0lNUExFTUVOVF9QQVJTRVIsCi0gICAgICJMYSBjbGFzc2UgZGkgZHJpdmVyIFNBWDEgezB9IG5vbiBpbXBsZW1lbnRhIG9yZy54bWwuc2F4LlBhcnNlciJ9LAotCi0gICAgeyBFUl9QQVJTRVJfUFJPUEVSVFlfTk9UX1NQRUNJRklFRCwKLSAgICAgIlByb3ByaWV0XHUwMEUwIGRpIHNpc3RlbWEgb3JnLnhtbC5zYXgucGFyc2VyIG5vbiBzcGVjaWZpY2F0YSJ9LAotCi0gICAgeyBFUl9QQVJTRVJfQVJHX0NBTk5PVF9CRV9OVUxMLAotICAgICAiTCcnYXJnb21lbnRvIGRlbCBwYXJzZXIgbm9uIGRldmUgZXNzZXJlIG51bGxvIn0sCi0KLSAgICB7IEVSX0ZFQVRVUkUsCi0gICAgICJGdW56aW9uZTogezB9In0sCi0KLSAgICB7IEVSX1BST1BFUlRZLAotICAgICAiUHJvcHJpZXRcdTAwRTA6IHswfSJ9LAotCi0gICAgeyBFUl9OVUxMX0VOVElUWV9SRVNPTFZFUiwKLSAgICAgIlJlc29sdmVyIGRpIGVudGl0XHUwMEUwIG51bGxvIn0sCi0KLSAgICB7IEVSX05VTExfRFREX0hBTkRMRVIsCi0gICAgICJIYW5kbGVyIERURCBudWxsbyJ9LAotCi0gICAgeyBFUl9OT19EUklWRVJfTkFNRV9TUEVDSUZJRUQsCi0gICAgICJOZXNzdW4gbm9tZSBkcml2ZXIgc3BlY2lmaWNhdG8uIn0sCi0KLSAgICB7IEVSX05PX1VSTF9TUEVDSUZJRUQsCi0gICAgICJOZXNzdW4gVVJMIHNwZWNpZmljYXRvLiJ9LAotCi0gICAgeyBFUl9QT09MU0laRV9MRVNTX1RIQU5fT05FLAotICAgICAiTGEgZGltZW5zaW9uZSBkZWwgcG9vbCBcdTAwRTggbWlub3JlIGRpIHVuby4ifSwKLQotICAgIHsgRVJfSU5WQUxJRF9EUklWRVJfTkFNRSwKLSAgICAgIlNwZWNpZmljYXRvIG5vbWUgZHJpdmVyIG5vbiB2YWxpZG8uIn0sCi0KLSAgICB7IEVSX0VSUk9STElTVEVORVIsCi0gICAgICJFcnJvckxpc3RlbmVyIn0sCi0KLQotLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBzaG91bGQgbm90IG5vcm1hbGx5IGJlIGRpc3BsYXllZAotLy8gICB0byB1c2Vycy4gIEl0IGRlc2NyaWJlcyBhIHNpdHVhdGlvbiBpbiB3aGljaCB0aGUgcHJvY2Vzc29yIGhhcyBkZXRlY3RlZAotLy8gICBhbiBpbnRlcm5hbCBjb25zaXN0ZW5jeSBwcm9ibGVtIGluIGl0c2VsZiwgYW5kIGl0IHByb3ZpZGVzIHRoaXMgbWVzc2FnZQotLy8gICBmb3IgdGhlIGRldmVsb3BlciB0byBoZWxwIGRpYWdub3NlIHRoZSBwcm9ibGVtLiAgVGhlIG5hbWUKLS8vICAgJ0VsZW1UZW1wbGF0ZUVsZW1lbnQnIGlzIHRoZSBuYW1lIG9mIGEgY2xhc3MsIGFuZCBzaG91bGQgbm90IGJlCi0vLyAgIHRyYW5zbGF0ZWQuCi0gICAgeyBFUl9BU1NFUlRfTk9fVEVNUExBVEVfUEFSRU5ULAotICAgICAiRXJyb3JlIGRlbCBwcm9ncmFtbWF0b3JlLiBMJ2VzcHJlc3Npb25lIG5vbiBoYSB1biBlbGVtZW50byBwYWRyZSBFbGVtVGVtcGxhdGVFbGVtZW50LiJ9LAotCi0KLS8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2Ugc2hvdWxkIG5vdCBub3JtYWxseSBiZSBkaXNwbGF5ZWQKLS8vICAgdG8gdXNlcnMuICBJdCBkZXNjcmliZXMgYSBzaXR1YXRpb24gaW4gd2hpY2ggdGhlIHByb2Nlc3NvciBoYXMgZGV0ZWN0ZWQKLS8vICAgYW4gaW50ZXJuYWwgY29uc2lzdGVuY3kgcHJvYmxlbSBpbiBpdHNlbGYsIGFuZCBpdCBwcm92aWRlcyB0aGlzIG1lc3NhZ2UKLS8vICAgZm9yIHRoZSBkZXZlbG9wZXIgdG8gaGVscCBkaWFnbm9zZSB0aGUgcHJvYmxlbS4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dAotLy8gICBwcm92aWRlcyBmdXJ0aGVyIGluZm9ybWF0aW9uIGluIG9yZGVyIHRvIGRpYWdub3NlIHRoZSBwcm9ibGVtLiAgVGhlIG5hbWUKLS8vICAgJ1JlZHVuZGVudEV4cHJFbGltaW5hdG9yJyBpcyB0aGUgbmFtZSBvZiBhIGNsYXNzLCBhbmQgc2hvdWxkIG5vdCBiZQotLy8gICB0cmFuc2xhdGVkLgotICAgIHsgRVJfQVNTRVJUX1JFRFVOREVOVF9FWFBSX0VMSU1JTkFUT1IsCi0gICAgICJBc3Nlcnppb25lIGRlbCBwcm9ncmFtbWF0b3JlIGluIFJlZHVuZGVudEV4cHJFbGltaW5hdG9yOiB7MH0ifSwKLQotICAgIHsgRVJfTk9UX0FMTE9XRURfSU5fUE9TSVRJT04sCi0gICAgICJ7MH0gbm9uIGNvbnNlbnRpdG8gaW4gcXVlc3RhIHBvc2l6aW9uZSBuZWwgZmlnbGlvIGRpIHN0aWxlLiJ9LAotCi0gICAgeyBFUl9OT05XSElURVNQQUNFX05PVF9BTExPV0VEX0lOX1BPU0lUSU9OLAotICAgICAiVGVzdG8gc2VuemEgc3Bhemkgbm9uIGNvbnNlbnRpdG8gaW4gcXVlc3RhIHBvc2l6aW9uZSBuZWwgZmlnbGlvIGRpIHN0aWxlLiJ9LAotCi0gIC8vIFRoaXMgY29kZSBpcyBzaGFyZWQgd2l0aCB3YXJuaW5nIGNvZGVzLgotICAvLyBTeXN0ZW1JZCBVbmtub3duCi0gICAgeyBJTlZBTElEX1RDSEFSLAotICAgICAiVmFsb3JlIG5vbiB2YWxpZG8gezF9IHV0aWxpenphdG8gcGVyIGwnJ2F0dHJpYnV0byBDSEFSIHswfS4gVW4gYXR0cmlidXRvIGRpIHRpcG8gQ0hBUiBkZXZlIGF2ZXJlIHVuIHNvbG8gY2FyYXR0ZXJlLiJ9LAotCi0gICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBpcyB1c2VkIGlmIHRoZSB2YWx1ZSBvZgotICAgIC8vIGFuIGF0dHJpYnV0ZSBpbiBhIHN0eWxlc2hlZXQgaXMgaW52YWxpZC4gICJRTkFNRSIgaXMgdGhlIFhNTCBkYXRhLXR5cGUgb2YKLSAgICAvLyB0aGUgYXR0cmlidXRlLCBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHsxfSBpcwotICAgIC8vIHRoZSBhdHRyaWJ1dGUgdmFsdWUgYW5kIHswfSBpcyB0aGUgYXR0cmlidXRlIG5hbWUuCi0gIC8vVGhlIGZvbGxvd2luZyBjb2RlcyBhcmUgc2hhcmVkIHdpdGggdGhlIHdhcm5pbmcgY29kZXMuLi4KLSAgICB7IElOVkFMSURfUU5BTUUsCi0gICAgICJWYWxvcmUgbm9uIHZhbGlkbyB7MX0gdXRpbGl6emF0byBwZXIgbCcnYXR0cmlidXRvIFFOQU1FIHswfSJ9LAotCi0gICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBpcyB1c2VkIGlmIHRoZSB2YWx1ZSBvZgotICAgIC8vIGFuIGF0dHJpYnV0ZSBpbiBhIHN0eWxlc2hlZXQgaXMgaW52YWxpZC4gICJFTlVNIiBpcyB0aGUgWE1MIGRhdGEtdHlwZSBvZgotICAgIC8vIHRoZSBhdHRyaWJ1dGUsIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgezF9IGlzCi0gICAgLy8gdGhlIGF0dHJpYnV0ZSB2YWx1ZSwgezB9IGlzIHRoZSBhdHRyaWJ1dGUgbmFtZSwgYW5kIHsyfSBpcyBhIGxpc3Qgb2YgdmFsaWQKLSAgICAvLyB2YWx1ZXMuCi0gICAgeyBJTlZBTElEX0VOVU0sCi0gICAgICJWYWxvcmUgbm9uIHZhbGlkbyB7MX0gdXRpbGl6emF0byBwZXIgbCcnYXR0cmlidXRvIEVOVU0gezB9LiBWYWxvcmkgdmFsaWRpOiB7Mn0uIn0sCi0KLS8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgaXMgdXNlZCBpZiB0aGUgdmFsdWUgb2YKLS8vIGFuIGF0dHJpYnV0ZSBpbiBhIHN0eWxlc2hlZXQgaXMgaW52YWxpZC4gICJOTVRPS0VOIiBpcyB0aGUgWE1MIGRhdGEtdHlwZQotLy8gb2YgdGhlIGF0dHJpYnV0ZSwgYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCB7MX0gaXMKLS8vIHRoZSBhdHRyaWJ1dGUgdmFsdWUgYW5kIHswfSBpcyB0aGUgYXR0cmlidXRlIG5hbWUuCi0gICAgeyBJTlZBTElEX05NVE9LRU4sCi0gICAgICJWYWxvcmUgbm9uIHZhbGlkbyB7MX0gdXRpbGl6emF0byBwZXIgbCcnYXR0cmlidXRvIE5NVE9LRU4gezB9ICJ9LAotCi0vLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIGlzIHVzZWQgaWYgdGhlIHZhbHVlIG9mCi0vLyBhbiBhdHRyaWJ1dGUgaW4gYSBzdHlsZXNoZWV0IGlzIGludmFsaWQuICAiTkNOQU1FIiBpcyB0aGUgWE1MIGRhdGEtdHlwZQotLy8gb2YgdGhlIGF0dHJpYnV0ZSwgYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCB7MX0gaXMKLS8vIHRoZSBhdHRyaWJ1dGUgdmFsdWUgYW5kIHswfSBpcyB0aGUgYXR0cmlidXRlIG5hbWUuCi0gICAgeyBJTlZBTElEX05DTkFNRSwKLSAgICAgIlZhbG9yZSBub24gdmFsaWRvIHsxfSB1dGlsaXp6YXRvIHBlciBsJydhdHRyaWJ1dG8gTkNOQU1FIHswfSAifSwKLQotLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBpcyB1c2VkIGlmIHRoZSB2YWx1ZSBvZgotLy8gYW4gYXR0cmlidXRlIGluIGEgc3R5bGVzaGVldCBpcyBpbnZhbGlkLiAgImJvb2xlYW4iIGlzIHRoZSBYU0xUIGRhdGEtdHlwZQotLy8gb2YgdGhlIGF0dHJpYnV0ZSwgYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCB7MX0gaXMKLS8vIHRoZSBhdHRyaWJ1dGUgdmFsdWUgYW5kIHswfSBpcyB0aGUgYXR0cmlidXRlIG5hbWUuCi0gICAgeyBJTlZBTElEX0JPT0xFQU4sCi0gICAgICJWYWxvcmUgbm9uIHZhbGlkbyB7MX0gdXRpbGl6emF0byBwZXIgbCcnYXR0cmlidXRvIGJvb2xlYW5vIHswfSAifSwKLQotLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBpcyB1c2VkIGlmIHRoZSB2YWx1ZSBvZgotLy8gYW4gYXR0cmlidXRlIGluIGEgc3R5bGVzaGVldCBpcyBpbnZhbGlkLiAgIm51bWJlciIgaXMgdGhlIFhTTFQgZGF0YS10eXBlCi0vLyBvZiB0aGUgYXR0cmlidXRlLCBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHsxfSBpcwotLy8gdGhlIGF0dHJpYnV0ZSB2YWx1ZSBhbmQgezB9IGlzIHRoZSBhdHRyaWJ1dGUgbmFtZS4KLSAgICAgeyBJTlZBTElEX05VTUJFUiwKLSAgICAgIlZhbG9yZSBub24gdmFsaWRvIHsxfSB1dGlsaXp6YXRvIHBlciBsJydhdHRyaWJ1dG8gbnVtZXJpY28gezB9ICJ9LAotCi0KLSAgLy8gRW5kIG9mIHNoYXJlZCBjb2Rlcy4uLgotCi0vLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQSAibWF0Y2ggcGF0dGVybiIgaXMgYSBzcGVjaWFsIGZvcm0gb2YgWFBhdGggZXhwcmVzc2lvbgotLy8gdGhhdCBpcyB1c2VkIGZvciBtYXRjaGluZyBwYXR0ZXJucy4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZgotLy8gYSBmdW5jdGlvbi4gIFRoZSBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHdoZW4gdGhpcyBmdW5jdGlvbiBpcyByZWZlcmVuY2VkIGluCi0vLyBhIG1hdGNoIHBhdHRlcm4sIGl0cyBhcmd1bWVudCBtdXN0IGJlIGEgc3RyaW5nIGxpdGVyYWwgKG9yIGNvbnN0YW50LikKLS8vIEVSX0FSR19MSVRFUkFMIC0gbmV3IGVycm9yIG1lc3NhZ2UgZm9yIGJ1Z3ppbGxhIC8vNTIwMgotICAgIHsgRVJfQVJHX0xJVEVSQUwsCi0gICAgICJMJydhcmdvbWVudG8gcGVyIHswfSBuZWwgcGF0dGVybiBkaSBjb3JyaXNwb25kZW56YSBkZXZlIGVzc2VyZSB1biB2YWxvcmUuIn0sCi0KLS8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdHdvIGRlZmluaXRpb25zIG9mCi0vLyBhIHZhcmlhYmxlLiAgQSAiZ2xvYmFsIHZhcmlhYmxlIiBpcyBhIHZhcmlhYmxlIHRoYXQgaXMgYWNjZXNzaWJsZSBldmVyeXdoZXIKLS8vIGluIHRoZSBzdHlsZXNoZWV0LgotLy8gRVJfRFVQTElDQVRFX0dMT0JBTF9WQVIgLSBuZXcgZXJyb3IgbWVzc2FnZSBmb3IgYnVnemlsbGEgIzc5MAotICAgIHsgRVJfRFVQTElDQVRFX0dMT0JBTF9WQVIsCi0gICAgICJEaWNoaWFyYXppb25lIGRpIHZhcmlhYmlsaSBnbG9iYWxpIGR1cGxpY2F0ZS4ifSwKLQotCi0vLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHR3byBkZWZpbml0aW9ucyBvZgotLy8gYSB2YXJpYWJsZSB3ZXJlIGVuY291bnRlcmVkLgotLy8gRVJfRFVQTElDQVRFX1ZBUiAtIG5ldyBlcnJvciBtZXNzYWdlIGZvciBidWd6aWxsYSAjNzkwCi0gICAgeyBFUl9EVVBMSUNBVEVfVkFSLAotICAgICAiRGljaGlhcmF6aW9uZSBkaSB2YXJpYWJpbGkgZHVwbGljYXRlLiJ9LAotCi0gICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogICJ4c2w6dGVtcGxhdGUsICJuYW1lIiBhbmQgIm1hdGNoIiBhcmUgWFNMVCBrZXl3b3JkcwotICAgIC8vIHdoaWNoIG11c3Qgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgLy8gRVJfVEVNUExBVEVfTkFNRV9NQVRDSCAtIG5ldyBlcnJvciBtZXNzYWdlIGZvciBidWd6aWxsYSAjNzg5Ci0gICAgeyBFUl9URU1QTEFURV9OQU1FX01BVENILAotICAgICAieHNsOnRlbXBsYXRlIGRldmUgYXZlcmUgdW4gYXR0cmlidXRvIG5hbWUgbyBtYXRjaCBvIGVudHJhbWJpIn0sCi0KLSAgICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgImV4Y2x1ZGUtcmVzdWx0LXByZWZpeGVzIiBpcyBhbiBYU0xUIGtleXdvcmQgd2hpY2gKLSAgICAvLyBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCBhIG5hbWVzcGFjZSBwcmVmaXgKLSAgICAvLyBlbmNvdW50ZXJlZCBhcyBwYXJ0IG9mIHRoZSB2YWx1ZSBvZiB0aGUgZXhjbHVkZS1yZXN1bHQtcHJlZml4ZXMgYXR0cmlidXRlCi0gICAgLy8gd2FzIGluIGVycm9yLgotICAgIC8vIEVSX0lOVkFMSURfUFJFRklYIC0gbmV3IGVycm9yIG1lc3NhZ2UgZm9yIGJ1Z3ppbGxhICM3ODgKLSAgICB7IEVSX0lOVkFMSURfUFJFRklYLAotICAgICAiSWwgcHJlZmlzc28gaW4gZXhjbHVkZS1yZXN1bHQtcHJlZml4ZXMgbm9uIFx1MDBFOCB2YWxpZG86IHswfSJ9LAotCi0gICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIEFuICJhdHRyaWJ1dGUgc2V0IiBpcyBhIHNldCBvZiBhdHRyaWJ1dGVzIHRoYXQgY2FuCi0gICAgLy8gYmUgYWRkZWQgdG8gYW4gZWxlbWVudCBpbiB0aGUgb3V0cHV0IGRvY3VtZW50IGFzIGEgZ3JvdXAuICBUaGUgbWVzc2FnZQotICAgIC8vIGluZGljYXRlcyB0aGF0IHRoZXJlIHdhcyBhIHJlZmVyZW5jZSB0byBhbiBhdHRyaWJ1dGUgc2V0IG5hbWVkIHswfSB0aGF0Ci0gICAgLy8gd2FzIG5ldmVyIGRlZmluZWQuCi0gICAgLy8gRVJfTk9fQVRUUklCX1NFVCAtIG5ldyBlcnJvciBtZXNzYWdlIGZvciBidWd6aWxsYSAjNzgyCi0gICAgeyBFUl9OT19BVFRSSUJfU0VULAotICAgICAiaWwgc2V0IGRpIGF0dHJpYnV0aSBkZW5vbWluYXRvIHswfSBub24gZXNpc3RlIn0sCi0KLSAgICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoZXJlIHdhcyBhIHJlZmVyZW5jZQotICAgIC8vIHRvIGEgZnVuY3Rpb24gbmFtZWQgezB9IGZvciB3aGljaCBubyBmdW5jdGlvbiBkZWZpbml0aW9uIGNvdWxkIGJlIGZvdW5kLgotICAgIHsgRVJfRlVOQ1RJT05fTk9UX0ZPVU5ELAotICAgICAiTGEgZnVuemlvbmUgZGVub21pbmF0YSB7MH0gbm9uIGVzaXN0ZSJ9LAotCi0gICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUgWFNMVCBpbnN0cnVjdGlvbgotICAgIC8vIHRoYXQgaXMgbmFtZWQgYnkgdGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHswfSBtdXN0IG5vdCBjb250YWluIG90aGVyIFhTTFQKLSAgICAvLyBpbnN0cnVjdGlvbnMgKGNvbnRlbnQpIG9yIGEgInNlbGVjdCIgYXR0cmlidXRlLiAgVGhlIHdvcmQgInNlbGVjdCIgaXMKLSAgICAvLyBhbiBYU0xUIGtleXdvcmQgaW4gdGhpcyBjYXNlIGFuZCBtdXN0IG5vdCBiZSB0cmFuc2xhdGVkLgotICAgIHsgRVJfQ0FOVF9IQVZFX0NPTlRFTlRfQU5EX1NFTEVDVCwKLSAgICAgIkwnJ2VsZW1lbnRvIHswfSBub24gZGV2ZSBhdmVyZSBlbnRyYW1iaSBnbGkgYXR0cmlidXRpIGNvbnRlbnQgZSBzZWxlY3QuIn0sCi0KLSAgICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoZSB2YWx1ZSBhcmd1bWVudAotICAgIC8vIG9mIHNldFBhcmFtZXRlciBtdXN0IGJlIGEgdmFsaWQgSmF2YSBPYmplY3QuCi0gICAgeyBFUl9JTlZBTElEX1NFVF9QQVJBTV9WQUxVRSwKLSAgICAgIklsIHZhbG9yZSBkZWwgcGFyYW1ldHJvIHswfSBkZXZlIGVzc2VyZSB1biBvZ2dldHRvIEphdmEgdmFsaWRvIn0sCi0KLSAgICB7IEVSX0lOVkFMSURfTkFNRVNQQUNFX1VSSV9WQUxVRV9GT1JfUkVTVUxUX1BSRUZJWF9GT1JfREVGQVVMVCwKLSAgICAgICJMJ2F0dHJpYnV0byByZXN1bHQtcHJlZml4IGRpIHVuIGVsZW1lbnRvIHhzbDpuYW1lc3BhY2UtYWxpYXMgaGEgaWwgdmFsb3JlICcjZGVmYXVsdCcsIG1hIG5vbiBlc2lzdGUgYWxjdW5hIGRpY2hpYXJhemlvbmUgZGVsbG8gc3BhemlvIGRpIG5vbWkgcHJlZGVmaW5pdG8gbmVsbCdhbWJpdG8gcGVyIGwnZWxlbWVudG8uIn0sCi0KLSAgICB7IEVSX0lOVkFMSURfTkFNRVNQQUNFX1VSSV9WQUxVRV9GT1JfUkVTVUxUX1BSRUZJWCwKLSAgICAgICJMJydhdHRyaWJ1dG8gcmVzdWx0LXByZWZpeCBkaSB1biBlbGVtZW50byB4c2w6bmFtZXNwYWNlLWFsaWFzIGhhIGlsIHZhbG9yZSAnJ3swfScnLCBtYSBub24gZXNpc3RlIGFsY3VuYSBkaWNoaWFyYXppb25lIGRlbGxvIHNwYXppbyBkaSBub21pIHBlciBpbCBwcmVmaXNzbyAnJ3swfScnIG5lbGwnJ2FtYml0byBwZXIgbCcnZWxlbWVudG8uIn0sCi0KLSAgICB7IEVSX1NFVF9GRUFUVVJFX05VTExfTkFNRSwKLSAgICAgICJJbCBub21lIGZ1bnppb25lIG5vbiBwdVx1MDBGMiBlc3NlcmUgbnVsbG8gaW4gVHJhbnNmb3JtZXJGYWN0b3J5LnNldEZlYXR1cmUgKG5vbWUgc3RyaW5nYSwgdmFsb3JlIGJvb2xlYW5vKS4ifSwKLQotICAgIHsgRVJfR0VUX0ZFQVRVUkVfTlVMTF9OQU1FLAotICAgICAgIklsIG5vbWUgZnVuemlvbmUgbm9uIHB1XHUwMEYyIGVzc2VyZSBudWxsbyBpbiBUcmFuc2Zvcm1lckZhY3RvcnkuZ2V0RmVhdHVyZSAobm9tZSBzdHJpbmdhKS4ifSwKLQotICAgIHsgRVJfVU5TVVBQT1JURURfRkVBVFVSRSwKLSAgICAgICJJbXBvc3NpYmlsZSBpbXBvc3RhcmUgbGEgZnVuemlvbmUgJyd7MH0nJyBpbiBxdWVzdG8gVHJhbnNmb3JtZXJGYWN0b3J5LiJ9LAotCi0gICAgeyBFUl9FWFRFTlNJT05fRUxFTUVOVF9OT1RfQUxMT1dFRF9JTl9TRUNVUkVfUFJPQ0VTU0lORywKLSAgICAgICAgICAiTm9uIFx1MDBFOCBjb25zZW50aXRvIHV0aWxpenphcmUgbCcnZWxlbWVudG8gZGkgZXN0ZW5zaW9uZSAnJ3swfScnIHNlIGxhIGZ1bnppb25lIGRpIGVsYWJvcmF6aW9uZSBzaWN1cmEgXHUwMEU4IGltcG9zdGF0YSBzdSB0cnVlLiJ9LAotCi0gICAgeyBFUl9OQU1FU1BBQ0VfQ09OVEVYVF9OVUxMX05BTUVTUEFDRSwKLSAgICAgICJJbXBvc3NpYmlsZSByZWN1cGVyYXJlIGlsIHByZWZpc3NvIHBlciB1biBVUkkgZGkgc3BhemlvIGRpIG5vbWkgbnVsbG8uIn0sCi0KLSAgICB7IEVSX05BTUVTUEFDRV9DT05URVhUX05VTExfUFJFRklYLAotICAgICAgIkltcG9zc2liaWxlIHJlY3VwZXJhcmUgbCdVUkkgZGkgc3BhemlvIGRpIG5vbWkgcGVyIHVuIHByZWZpc3NvIG51bGxvLiJ9LAotCi0gICAgeyBFUl9YUEFUSF9SRVNPTFZFUl9OVUxMX1FOQU1FLAotICAgICAgIklsIG5vbWUgZnVuemlvbmUgbm9uIHB1XHUwMEYyIGVzc2VyZSBudWxsby4ifSwKLQotICAgIHsgRVJfWFBBVEhfUkVTT0xWRVJfTkVHQVRJVkVfQVJJVFksCi0gICAgICAiTCdhcml0eSBub24gcHVcdTAwRjIgZXNzZXJlIG5lZ2F0aXZhLiJ9LAotICAvLyBXYXJuaW5ncy4uLgotCi0gICAgeyBXR19GT1VORF9DVVJMWUJSQUNFLAotICAgICAgIlRyb3ZhdG8gJ30nLCBtYSBub24gZXNpc3Rvbm8gbW9kZWxsaSBkaSBhdHRyaWJ1dG8gYXBlcnRpLiJ9LAotCi0gICAgeyBXR19DT1VOVF9BVFRSSUJfTUFUQ0hFU19OT19BTkNFU1RPUiwKLSAgICAgICJBdnZlcnRlbnphOiBsJydhdHRyaWJ1dG8gY291bnQgbm9uIGNvcnJpc3BvbmRlIGEgdW4gcHJlZGVjZXNzb3JlIGluIHhzbDpudW1iZXIuIERlc3RpbmF6aW9uZSA9IHswfSJ9LAotCi0gICAgeyBXR19FWFBSX0FUVFJJQl9DSEFOR0VEX1RPX1NFTEVDVCwKLSAgICAgICJTaW50YXNzaSBvYnNvbGV0YTogaWwgbm9tZSBkZWxsJ2F0dHJpYnV0byAnZXhwcicgXHUwMEU4IHN0YXRvIGNhbWJpYXRvIGluICdzZWxlY3QnLiJ9LAotCi0gICAgeyBXR19OT19MT0NBTEVfSU5fRk9STUFUTlVNQkVSLAotICAgICAgIlhhbGFuIG5vbiBnZXN0aXNjZSBhbmNvcmEgaWwgbm9tZSBkaSBpbXBvc3RhemlvbmkgbmF6aW9uYWxpIG5lbGxhIGZ1bnppb25lIGZvcm1hdC1udW1iZXIuIn0sCi0KLSAgICB7IFdHX0xPQ0FMRV9OT1RfRk9VTkQsCi0gICAgICAiQXZ2ZXJ0ZW56YTogaW1wb3NzaWJpbGUgdHJvdmFyZSBsZSBpbXBvc3RhemlvbmkgbmF6aW9uYWxpIHBlciB4bWw6bGFuZz17MH0ifSwKLQotICAgIHsgV0dfQ0FOTk9UX01BS0VfVVJMX0ZST00sCi0gICAgICAiSW1wb3NzaWJpbGUgY3JlYXJlIHVuIFVSTCBkYSB7MH0ifSwKLQotICAgIHsgV0dfQ0FOTk9UX0xPQURfUkVRVUVTVEVEX0RPQywKLSAgICAgICJJbXBvc3NpYmlsZSBjYXJpY2FyZSBpbCBkb2N1bWVudG8gcmljaGllc3RvOiB7MH0ifSwKLQotICAgIHsgV0dfQ0FOTk9UX0ZJTkRfQ09MTEFUT1IsCi0gICAgICAiSW1wb3NzaWJpbGUgdHJvdmFyZSBDb2xsYXRvciBwZXIgPHNvcnQgeG1sOmxhbmc9ezB9In0sCi0KLSAgICB7IFdHX0ZVTkNUSU9OU19TSE9VTERfVVNFX1VSTCwKLSAgICAgICJTaW50YXNzaSBvYnNvbGV0YTogbGUgaXN0cnV6aW9uaSBkZWxsZSBmdW56aW9uaSBkZXZvbm8gdXRpbGl6emFyZSB1biBVUkwgezB9In0sCi0KLSAgICB7IFdHX0VOQ09ESU5HX05PVF9TVVBQT1JURURfVVNJTkdfVVRGOCwKLSAgICAgICJDb2RpZmljYSB7MH0gbm9uIHN1cHBvcnRhdGEuIFZlcnJcdTAwRTAgdXRpbGl6emF0YSBsYSBjb2RpZmljYSBVVEYtOC4ifSwKLQotICAgIHsgV0dfRU5DT0RJTkdfTk9UX1NVUFBPUlRFRF9VU0lOR19KQVZBLAotICAgICAgIkNvZGlmaWNhIHswfSBub24gc3VwcG9ydGF0YS4gVmVyclx1MDBFMCB1dGlsaXp6YXRhIGxhIGNvZGlmaWNhIEphdmEgezF9LiJ9LAotCi0gICAgeyBXR19TUEVDSUZJQ0lUWV9DT05GTElDVFMsCi0gICAgICAiU29ubyBzdGF0aSB0cm92YXRpIGNvbmZsaXR0aSBkaSBzcGVjaWZpY2l0XHUwMEUwOiB7MH0uIFZlcnJcdTAwRTAgdXRpbGl6emF0byBsJyd1bHRpbW8gdHJvdmF0byBuZWwgZm9nbGlvIGRpIHN0aWxlLiJ9LAotCi0gICAgeyBXR19QQVJTSU5HX0FORF9QUkVQQVJJTkcsCi0gICAgICAiPT09PT09PT09IEFuYWxpc2kgZSBwcmVwYXJhemlvbmUgZGkgezB9IGluIGNvcnNvID09PT09PT09PT0ifSwKLQotICAgIHsgV0dfQVRUUl9URU1QTEFURSwKLSAgICAgIk1vZGVsbG8gYXR0cmlidXRpIHswfSJ9LAotCi0gICAgeyBXR19DT05GTElDVF9CRVRXRUVOX1hTTFNUUklQU1BBQ0VfQU5EX1hTTFBSRVNFUlZFU1BBQ0UsCi0gICAgICAiQ29uZmxpdHRvIGRpIGNvcnJpc3BvbmRlbnphIHRyYSB4c2w6c3RyaXAtc3BhY2UgZSB4c2w6cHJlc2VydmUtc3BhY2UifSwKLQotICAgIHsgV0dfQVRUUklCX05PVF9IQU5ETEVELAotICAgICAgIlhhbGFuIG5vbiBnZXN0aXNjZSBhbmNvcmEgbCcnYXR0cmlidXRvIHswfS4ifSwKLQotICAgIHsgV0dfTk9fREVDSU1BTEZPUk1BVF9ERUNMQVJBVElPTiwKLSAgICAgICJOZXNzdW5hIGRpY2hpYXJhemlvbmUgdHJvdmF0YSBwZXIgaWwgZm9ybWF0byBkZWNpbWFsZTogezB9In0sCi0KLSAgICB7IFdHX09MRF9YU0xUX05TLAotICAgICAiU3BhemlvIGRpIG5vbWkgWFNMVCBtYW5jYW50ZSBvIGVycmF0by4gIn0sCi0KLSAgICB7IFdHX09ORV9ERUZBVUxUX1hTTERFQ0lNQUxGT1JNQVRfQUxMT1dFRCwKLSAgICAgICJcdTAwQzggY29uc2VudGl0YSB1bmEgc29sYSBkaWNoaWFyYXppb25lIHhzbDpkZWNpbWFsLWZvcm1hdCBwcmVkZWZpbml0YS4ifSwKLQotICAgIHsgV0dfWFNMREVDSU1BTEZPUk1BVF9OQU1FU19NVVNUX0JFX1VOSVFVRSwKLSAgICAgICJJIG5vbWkgeHNsOmRlY2ltYWwtZm9ybWF0IGRldm9ubyBlc3NlcmUgdW5pdm9jaS4gSWwgbm9tZSBcInswfVwiIFx1MDBFOCBzdGF0byBkdXBsaWNhdG8uIn0sCi0KLSAgICB7IFdHX0lMTEVHQUxfQVRUUklCVVRFLAotICAgICAgInswfSBoYSB1biBhdHRyaWJ1dG8gbm9uIHZhbGlkbzogezF9In0sCi0KLSAgICB7IFdHX0NPVUxEX05PVF9SRVNPTFZFX1BSRUZJWCwKLSAgICAgICJJbXBvc3NpYmlsZSByaXNvbHZlcmUgaWwgcHJlZmlzc28gc3BhemlvIGRpIG5vbWkgezB9LiBJbCBub2RvIHZlcnJcdTAwRTAgaWdub3JhdG8uIn0sCi0KLSAgICB7IFdHX1NUWUxFU0hFRVRfUkVRVUlSRVNfVkVSU0lPTl9BVFRSSUIsCi0gICAgICAieHNsOnN0eWxlc2hlZXQgcmljaGllZGUgdW4gYXR0cmlidXRvICd2ZXJzaW9uJy4ifSwKLQotICAgIHsgV0dfSUxMRUdBTF9BVFRSSUJVVEVfTkFNRSwKLSAgICAgICJOb21lIGF0dHJpYnV0byBub24gdmFsaWRvOiB7MH0ifSwKLQotICAgIHsgV0dfSUxMRUdBTF9BVFRSSUJVVEVfVkFMVUUsCi0gICAgICAiVmFsb3JlIG5vbiB2YWxpZG8gdXRpbGl6emF0byBwZXIgbCcnYXR0cmlidXRvIHswfTogezF9In0sCi0KLSAgICB7IFdHX0VNUFRZX1NFQ09ORF9BUkcsCi0gICAgICAiSWwgc2V0IGRpIG5vZGkgcmlzdWx0YW50ZSBkYWwgc2Vjb25kbyBhcmdvbWVudG8gZGVsbGEgZnVuemlvbmUgZGkgZG9jdW1lbnRvIFx1MDBFOCB2dW90by4gVmVyclx1MDBFMCByZXN0aXR1aXRvIHVuIHNldCBkaSBub2RpIHZ1b3RvLiJ9LAotCi0gIC8vRm9sbG93aW5nIGFyZSB0aGUgbmV3IFdBUk5JTkcga2V5cyBhZGRlZCBpbiBYQUxBTiBjb2RlIGJhc2UgYWZ0ZXIgSmRrIDEuNCAoWGFsYW4gMi4yLUQxMSkKLQotICAgIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAibmFtZSIgYW5kICJ4c2w6cHJvY2Vzc2luZy1pbnN0cnVjdGlvbiIgYXJlIGtleXdvcmRzCi0gICAgLy8gYW5kIG11c3Qgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgeyBXR19QUk9DRVNTSU5HSU5TVFJVQ1RJT05fTkFNRV9DQU5UX0JFX1hNTCwKLSAgICAgICJJbCB2YWxvcmUgZGVsbCdhdHRyaWJ1dG8gJ25hbWUnIGRlbCBub21lIHhzbDpwcm9jZXNzaW5nLWluc3RydWN0aW9uIG5vbiBkZXZlIGVzc2VyZSAneG1sJyJ9LAotCi0gICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogICJuYW1lIiBhbmQgInhzbDpwcm9jZXNzaW5nLWluc3RydWN0aW9uIiBhcmUga2V5d29yZHMKLSAgICAvLyBhbmQgbXVzdCBub3QgYmUgdHJhbnNsYXRlZC4gICJOQ05hbWUiIGlzIGFuIFhNTCBkYXRhLXR5cGUgYW5kIG11c3Qgbm90IGJlCi0gICAgLy8gdHJhbnNsYXRlZC4KLSAgICB7IFdHX1BST0NFU1NJTkdJTlNUUlVDVElPTl9OT1RWQUxJRF9OQ05BTUUsCi0gICAgICAiSWwgdmFsb3JlIGRlbGwnJ2F0dHJpYnV0byAnJ25hbWUnJyBkaSB4c2w6cHJvY2Vzc2luZy1pbnN0cnVjdGlvbiBkZXZlIGVzc2VyZSB1biBOQ05hbWUgdmFsaWRvOiB7MH0ifSwKLQotICAgIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgcmVwb3J0ZWQgaWYgdGhlIHN0eWxlc2hlZXQgdGhhdCBpcwotICAgIC8vIGJlaW5nIHByb2Nlc3NlZCBhdHRlbXB0ZWQgdG8gY29uc3RydWN0IGFuIFhNTCBkb2N1bWVudCB3aXRoIGFuIGF0dHJpYnV0ZSBpbiBhCi0gICAgLy8gcGxhY2Ugb3RoZXIgdGhhbiBvbiBhbiBlbGVtZW50LiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHNwZWNpZmllcyB0aGUgbmFtZSBvZgotICAgIC8vIHRoZSBhdHRyaWJ1dGUuCi0gICAgeyBXR19JTExFR0FMX0FUVFJJQlVURV9QT1NJVElPTiwKLSAgICAgICJJbXBvc3NpYmlsZSBhZ2dpdW5nZXJlIGwnJ2F0dHJpYnV0byB7MH0gZG9wbyBpIG5vZGkgZmlnbGlvIG8gcHJpbWEgY2hlIHNpYSBwcm9kb3R0byB1biBlbGVtZW50by4gTCcnYXR0cmlidXRvIHZlcnJcdTAwRTAgaWdub3JhdG8uIn0sCi0KLSAgICB7IE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiwKLSAgICAgICJTaSBcdTAwRTggdGVudGF0byBkaSBtb2RpZmljYXJlIHVuIG9nZ2V0dG8gbm9uIG1vZGlmaWNhYmlsZS4iCi0gICAgfSwKLQotICAgIC8vQ2hlY2s6IFdIWSBUSEVSRSBJUyBBIEdBUCBCL1cgTlVNQkVSUyBpbiB0aGUgWFNMVEVycm9yUmVzb3VyY2VzIHByb3BlcnRpZXMgZmlsZT8KLQotICAvLyBPdGhlciBtaXNjZWxsYW5lb3VzIHRleHQgdXNlZCBpbnNpZGUgdGhlIGNvZGUuLi4KLSAgeyAidWlfbGFuZ3VhZ2UiLCAiaXQifSwKLSAgeyAgImhlbHBfbGFuZ3VhZ2UiLCAgIml0IiB9LAotICB7ICAibGFuZ3VhZ2UiLCAgIml0IiB9LAotICB7ICJCQURfQ09ERSIsICJQYXJhbWV0cm8gcGVyIGNyZWF0ZU1lc3NhZ2UgZnVvcmkgbGltaXRlIn0sCi0gIHsgICJGT1JNQVRfRkFJTEVEIiwgIkVjY2V6aW9uZSBkdXJhbnRlIGxhIGNoaWFtYXRhIG1lc3NhZ2VGb3JtYXQifSwKLSAgeyAgInZlcnNpb24iLCAiPj4+Pj4+PiBWZXJzaW9uZSBYYWxhbiAifSwKLSAgeyAgInZlcnNpb24yIiwgICI8PDw8PDw8In0sCi0gIHsgICJ5ZXMiLCAic1x1MDBFQyJ9LAotICB7ICJsaW5lIiwgIk4uIHJpZ2EifSwKLSAgeyAiY29sdW1uIiwiTi4gY29sb25uYSJ9LAotICB7ICJ4c2xkb25lIiwgIlhTTFByb2Nlc3Nvcjogb3BlcmF6aW9uZSBjb21wbGV0YXRhIn0sCi0KLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlcyBwcm92aWRlIHVzYWdlIGluZm9ybWF0aW9uCi0gIC8vIGZvciB0aGUgWGFsYW4gUHJvY2VzcyBjb21tYW5kIGxpbmUuICAiUHJvY2VzcyIgaXMgdGhlIG5hbWUgb2YgYSBKYXZhIGNsYXNzLAotICAvLyBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLgotICB7ICJ4c2xQcm9jX29wdGlvbiIsICJPcHppb25pIGNsYXNzZSBkaSBwcm9jZXNzbyBwZXIgcmlnYSBkaSBjb21hbmRvIFhhbGFuLUo6In0sCi0gIHsgInhzbFByb2Nfb3B0aW9uIiwgIk9wemlvbmkgY2xhc3NlIGRpIHByb2Nlc3NvIHBlciByaWdhIGRpIGNvbWFuZG8gWGFsYW4tSjoifSwKLSAgeyAieHNsUHJvY19pbnZhbGlkX3hzbHRjX29wdGlvbiIsICJPcHppb25lIHswfSBub24gc3VwcG9ydGF0YSBpbiBtb2RhbGl0XHUwMEUwIFhTTFRDLiJ9LAotICB7ICJ4c2xQcm9jX2ludmFsaWRfeGFsYW5fb3B0aW9uIiwgIkwnJ29wemlvbmUgezB9IHB1XHUwMEYyIGVzc2VyZSB1dGlsaXp6YXRhIHNvbG8gY29uIC1YU0xUQy4ifSwKLSAgeyAieHNsUHJvY19ub19pbnB1dCIsICJFcnJvcmU6IG5vbiBcdTAwRTggc3RhdG8gc3BlY2lmaWNhdG8gYWxjdW4gZm9nbGlvIGRpIHN0aWxlIG8gWE1MIGRpIGlucHV0LiBFc2VndWlyZSBxdWVzdG8gY29tYW5kbyBzZW56YSBvcHppb25pIHBlciB2aXN1YWxpenphcmUgbGUgaXN0cnV6aW9uaSBzdWxsJ3Vzby4ifSwKLSAgeyAieHNsUHJvY19jb21tb25fb3B0aW9ucyIsICItT3B6aW9uaSBjb211bmktIn0sCi0gIHsgInhzbFByb2NfeGFsYW5fb3B0aW9ucyIsICItT3B6aW9uaSBwZXIgWGFsYW4tIn0sCi0gIHsgInhzbFByb2NfeHNsdGNfb3B0aW9ucyIsICItT3B6aW9uaSBwZXIgWFNMVEMtIn0sCi0gIHsgInhzbFByb2NfcmV0dXJuX3RvX2NvbnRpbnVlIiwgIihwcmVtZXJlIDxpbnZpbz4gcGVyIGNvbnRpbnVhcmUpIn0sCi0KLSAgIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6IFRoZSBvcHRpb24gbmFtZSBhbmQgdGhlIHBhcmFtZXRlciBuYW1lIGRvIG5vdCBuZWVkIHRvCi0gICAvLyBiZSB0cmFuc2xhdGVkLiBPbmx5IHRyYW5zbGF0ZSB0aGUgbWVzc2FnZXMgaW4gcGFyZW50aGVzZXMuICBOb3RlIGFsc28gdGhhdAotICAgLy8gbGVhZGluZyB3aGl0ZXNwYWNlIGluIHRoZSBtZXNzYWdlcyBpcyB1c2VkIHRvIGluZGVudCB0aGUgdXNhZ2UgaW5mb3JtYXRpb24KLSAgIC8vIGZvciBlYWNoIG9wdGlvbiBpbiB0aGUgRW5nbGlzaCBtZXNzYWdlcy4KLSAgIC8vIERvIG5vdCB0cmFuc2xhdGUgdGhlIGtleXdvcmRzOiBYU0xUQywgU0FYLCBET00gYW5kIERUTS4KLSAgeyAib3B0aW9uWFNMVEMiLCAiICAgWy1YU0xUQyAodXNhIFhTTFRDIHBlciBsYSB0cmFzZm9ybWF6aW9uZSldIn0sCi0gIHsgIm9wdGlvbklOIiwgIiAgIFstSU4gaW5wdXRYTUxVUkxdIn0sCi0gIHsgIm9wdGlvblhTTCIsICIgICBbLVhTTCBYU0xUcmFuc2Zvcm1hdGlvblVSTF0ifSwKLSAgeyAib3B0aW9uT1VUIiwgICIgICBbLU9VVCBvdXRwdXRGaWxlTmFtZV0ifSwKLSAgeyAib3B0aW9uTFhDSU4iLCAiICAgWy1MWENJTiBjb21waWxlZFN0eWxlc2hlZXRGaWxlTmFtZUluXSJ9LAotICB7ICJvcHRpb25MWENPVVQiLCAiICAgWy1MWENPVVQgY29tcGlsZWRTdHlsZXNoZWV0RmlsZU5hbWVPdXRPdXRdIn0sCi0gIHsgIm9wdGlvblBBUlNFUiIsICIgICBbLVBBUlNFUiBub21lIGNsYXNzZSBjb21wbGV0YW1lbnRlIHF1YWxpZmljYXRvIHBlciBsYSByZWxhemlvbmUgZGVsIHBhcnNlcl0ifSwKLSAgeyAgIm9wdGlvbkUiLCAiICAgWy1FIChub24gZXNwYW5kZSBpIHJpZmVyaW1lbnRpIGFsbGUgZW50aXRcdTAwRTApXSJ9LAotICB7ICAib3B0aW9uViIsICAiICAgWy1FIChub24gZXNwYW5kZSBpIHJpZmVyaW1lbnRpIGFsbGUgZW50aXRcdTAwRTApXSJ9LAotICB7ICAib3B0aW9uUUMiLCAiICAgWy1RQyAoYXZ2ZXJ0ZW56ZSBzaWxlbnppb3NlIHBlciBpIGNvbmZsaXR0aSBkaSBwYXR0ZXJuKV0ifSwKLSAgeyAgIm9wdGlvblEiLCAiICAgWy1RICAobW9kYWxpdFx1MDBFMCBzaWxlbnppb3NhKV0ifSwKLSAgeyAgIm9wdGlvbkxGIiwgIiAgIFstTEYgKHVzYSBhdmFuemFtZW50aSByaWdhIHNvbG8gbmVsbCdvdXRwdXQge2lsIHZhbG9yZSBwcmVkZWZpbml0byBcdTAwRTggQ1IvTEZ9KV0ifSwKLSAgeyAgIm9wdGlvbkNSIiwgIiAgIFstQ1IgKHVzYSByaXRvcm5pIGEgY2FwbyBzb2xvIG5lbGwnb3V0cHV0IHtpbCB2YWxvcmUgcHJlZGVmaW5pdG8gXHUwMEU4IENSL0xGfSldIn0sCi0gIHsgIm9wdGlvbkVTQ0FQRSIsICIgICBbLUVTQ0FQRSAoY2FyYXR0ZXJpIGRhIHNvdHRvcG9ycmUgYSBlc2NhcGUge2lsIHZhbG9yZSBwcmVkZWZpbml0byBcdTAwRTggPD4mXCInXFxyXFxufV0ifSwKLSAgeyAib3B0aW9uSU5ERU5UIiwgIiAgIFstSU5ERU5UIChkZXRlcm1pbmEgaWwgbnVtZXJvIGRpIHNwYXppIGRhIGluZGVudGFyZSB7aWwgdmFsb3JlIHByZWRlZmluaXRvIFx1MDBFOCAwfSldIn0sCi0gIHsgIm9wdGlvblRUIiwgIiAgIFstVFQgKHRpZW5lIHRyYWNjaWEgZGVpIG1vZGVsbGkgbWVudHJlIHZlbmdvbm8gcmljaGlhbWF0aS4pXSJ9LAotICB7ICJvcHRpb25URyIsICIgICBbLVRHICh0aWVuZSB0cmFjY2lhIGRpIG9nbmkgZXZlbnRvIGRpIGdlbmVyYXppb25lLildIn0sCi0gIHsgIm9wdGlvblRTIiwgIiAgIFstVFMgKHRpZW5lIHRyYWNjaWEgZGkgb2duaSBldmVudG8gZGkgc2VsZXppb25lLildIn0sCi0gIHsgICJvcHRpb25UVEMiLCAiICAgWy1UVEMgKHRpZW5lIHRyYWNjaWEgZGVnbGkgZWxlbWVudGkgc2Vjb25kYXJpIGRpIG1vZGVsbG8gbWVudHJlIHZlbmdvbm8gZWxhYm9yYXRpLildIn0sCi0gIHsgIm9wdGlvblRDTEFTUyIsICIgICBbLVRDTEFTUyAoY2xhc3NlIFRyYWNlTGlzdGVuZXIgcGVyIHRlbmVyZSB0cmFjY2lhIGRlbGxlIGVzdGVuc2lvbmkuKV0ifSwKLSAgeyAib3B0aW9uVkFMSURBVEUiLCAiICAgWy1WQUxJREFURSAoaW1wb3N0YSBzZSB2aWVuZSBlc2VndWl0YSBsYSBjb252YWxpZGEgY2hlLCBwZXIgaW1wb3N0YXppb25lIHByZWRlZmluaXRhLCBcdTAwRTggZGlzYXR0aXZhdGEuKV0ifSwKLSAgeyAib3B0aW9uRURVTVAiLCAiICAgWy1FRFVNUCB7bm9tZSBmaWxlIGZhY29sdGF0aXZvfSAoZXNlZ3VlIHN0YWNrZHVtcCBpbiBjYXNvIGRpIGVycm9yZS4pXSJ9LAotICB7ICAib3B0aW9uWE1MIiwgIiAgIFstWE1MICh1c2EgaWwgZm9ybWF0dGVyIFhNTCBlIGFnZ2l1bmdlIGwnaW50ZXN0YXppb25lIFhNTC4pXSJ9LAotICB7ICAib3B0aW9uVEVYVCIsICIgICBbLVRFWFQgKHVzYSBpbCBmb3JtYXR0ZXIgZGkgdGVzdG8gc2VtcGxpY2UuKV0ifSwKLSAgeyAgIm9wdGlvbkhUTUwiLCAiICAgWy1IVE1MICh1c2EgaWwgZm9ybWF0dGVyIEhUTUwuKV0ifSwKLSAgeyAgIm9wdGlvblBBUkFNIiwgIiAgIFstUEFSQU0gZXNwcmVzc2lvbmUgbm9tZSAoaW1wb3N0YSB1biBwYXJhbWV0cm8gZGkgZm9nbGlvIGRpIHN0aWxlKV0ifSwKLSAgeyAgIm5vUGFyc2VybXNnMSIsICJQcm9jZXNzbyBYU0wgbm9uIHJpdXNjaXRvLiJ9LAotICB7ICAibm9QYXJzZXJtc2cyIiwgIioqIEltcG9zc2liaWxlIHRyb3ZhcmUgaWwgcGFyc2VyICoqIn0sCi0gIHsgIm5vUGFyc2VybXNnMyIsICAiQ29udHJvbGxhcmUgaWwgY2xhc3NwYXRoLiJ9LAotICB7ICJub1BhcnNlcm1zZzQiLCAiU2Ugbm9uIFx1MDBFOCBkaXNwb25pYmlsZSB1biBwYXJzZXIgWE1MIGRpIElCTSBwZXIgSmF2YSwgXHUwMEU4IHBvc3NpYmlsZSBzY2FyaWNhcmxvIGRhIn0sCi0gIHsgIm5vUGFyc2VybXNnNSIsICJBbHBoYVdvcmtzIGRpIElCTTogaHR0cDovL3d3dy5hbHBoYXdvcmtzLmlibS5jb20vZm9ybXVsYS94bWwifSwKLSAgeyAib3B0aW9uVVJJUkVTT0xWRVIiLCAiICAgWy1VUklSRVNPTFZFUiBub21lIGNsYXNzZSBjb21wbGV0byAoVVJJUmVzb2x2ZXIgZGEgdXRpbGl6emFyZSBwZXIgcmlzb2x2ZXJlIGdsaSBVUkkpXSJ9LAotICB7ICJvcHRpb25FTlRJVFlSRVNPTFZFUiIsICAiICAgWy1FTlRJVFlSRVNPTFZFUiBub21lIGNsYXNzZSBjb21wbGV0byAoRW50aXR5UmVzb2x2ZXIgZGEgdXRpbGl6emFyZSBwZXIgcmlzb2x2ZXJlIGxlIGVudGl0XHUwMEUwKV0ifSwKLSAgeyAib3B0aW9uQ09OVEVOVEhBTkRMRVIiLCAgIiAgIFstQ09OVEVOVEhBTkRMRVIgbm9tZSBjbGFzc2UgY29tcGxldG8gKENvbnRlbnRIYW5kbGVyIGRhIHV0aWxpenphcmUgcGVyIHNlcmlhbGl6emFyZSBsJ291dHB1dCldIn0sCi0gIHsgICJvcHRpb25MSU5FTlVNQkVSUyIsICAiICAgWy1MIHV0aWxpenphIGkgbnVtZXJpIGRpIHJpZ2EgcGVyIGlsIGRvY3VtZW50byBkaSBvcmlnaW5lXSJ9LAotICB7ICJvcHRpb25TRUNVUkVQUk9DRVNTSU5HIiwgIiAgIFstU0VDVVJFIChpbXBvc3RhIGxhIGZ1bnppb25lIGRpIGVsYWJvcmF6aW9uZSBzaWN1cmEgc3UgdHJ1ZS4pXSJ9LAotCi0gICAgLy8gRm9sbG93aW5nIGFyZSB0aGUgbmV3IG9wdGlvbnMgYWRkZWQgaW4gWFNMVEVycm9yUmVzb3VyY2VzLnByb3BlcnRpZXMgZmlsZXMgYWZ0ZXIgSmRrIDEuNCAoWGFsYW4gMi4yLUQxMSkKLQotCi0gIHsgICJvcHRpb25NRURJQSIsICAiICAgWy1NRURJQSBtZWRpYVR5cGUgKHV0aWxpenphIGwnYXR0cmlidXRvIG1lZGlhIHBlciB0cm92YXJlIGlsIGZvZ2xpbyBkaSBzdGlsZSBhc3NvY2lhdG8gYSB1biBkb2N1bWVudG8uKV0ifSwKLSAgeyAgIm9wdGlvbkZMQVZPUiIsICAiICAgWy1GTEFWT1IgZmxhdm9yTmFtZSAodXRpbGl6emEgZXNwbGljaXRhbWVudGUgczJzPVNBWCBvIGQyZD1ET00gcGVyIGVzZWd1aXJlIGxhIHRyYXNmb3JtYXppb25lLildICJ9LCAvLyBBZGRlZCBieSBzYm9hZy9zY3VyY3VydTsgZXhwZXJpbWVudGFsCi0gIHsgIm9wdGlvbkRJQUciLCAiICAgWy1ESUFHICh2aXN1YWxpenphIGkgbWlsbGlzZWNvbmRpIHRvdGFsaSByaWNoaWVzdGkgcGVyIGxhIHRyYXNmb3JtYXppb25lLildIn0sCi0gIHsgIm9wdGlvbklOQ1JFTUVOVEFMIiwgICIgICBbLUlOQ1JFTUVOVEFMIChyaWNoaWVkZSBsYSBjcmVhemlvbmUgaW5jcmVtZW50YWxlIGRpIERUTSBpbXBvc3RhbmRvIGh0dHA6Ly94bWwuYXBhY2hlLm9yZy94YWxhbi9mZWF0dXJlcy9pbmNyZW1lbnRhbCBzdSB0cnVlLildIn0sCi0gIHsgICJvcHRpb25OT09QVElNSU1JWkUiLCAgIiAgIFstTk9PUFRJTUlNSVpFIChyaWNoaWVkZSBjaGUgbm9uIHZlbmdhIGVsYWJvcmF0YSBsJ290dGltaXp6YXppb25lIGRlaSBmb2dsaSBkaSBzdGlsZSBpbXBvc3RhbmRvIGh0dHA6Ly94bWwuYXBhY2hlLm9yZy94YWxhbi9mZWF0dXJlcy9vcHRpbWl6ZSBzdSBmYWxzZS4pXSJ9LAotICB7ICJvcHRpb25STCIsICAiICAgWy1STCByZWN1cnNpb25saW1pdCAoc3RhYmlsaXNjZSB1biBsaW1pdGUgbnVtZXJpY28gc3VsbGEgcHJvZm9uZGl0XHUwMEUwIHJpY29yc2l2YSBkZWkgZm9nbGkgZGkgc3RpbGUuKV0ifSwKLSAgeyAgICJvcHRpb25YTyIsICAiICAgWy1YTyBbdHJhbnNsZXROYW1lXSAoYXNzZWduYSB1biBub21lIGFsIHRyYW5zbGV0IGNyZWF0byldIn0sCi0gIHsgICJvcHRpb25YRCIsICIgICBbLVhEIGRlc3RpbmF0aW9uRGlyZWN0b3J5IChzcGVjaWZpY2EgdW5hIGRpcmVjdG9yeSBkaSBkZXN0aW5hemlvbmUgcGVyIGlsIHRyYW5zbGV0KV0ifSwKLSAgeyAgIm9wdGlvblhKIiwgICIgICBbLVhKIGphcmZpbGUgKGNyZWEgdW4gcGFja2FnZSBkaSBjbGFzc2kgZGkgdHJhbnNsZXQgaW4gdW4gZmlsZSBqYXIgZGVub21pbmF0byA8amFyZmlsZT4pXSJ9LAotICB7ICAgIm9wdGlvblhQIiwgICIgICBbLVhQIHBhY2thZ2UgKHNwZWNpZmljYSB1biBwcmVmaXNzbyBub21lIHBhY2thZ2UgcGVyIHR1dHRlIGxlIGNsYXNzaSBkaSB0cmFuc2xldCBnZW5lcmF0ZSldIn0sCi0KLSAgLy9BZGRJVElPTkFMICBTVFJJTkdTIHRoYXQgbmVlZCBMMTBuCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgZGVzY3JpYmVzIHVzYWdlIG9mIGEgcGFydGljdWxhcgotICAvLyBjb21tYW5kLWxpbmUgb3B0aW9uIHRoYXQgaXMgdXNlZCB0byBlbmFibGUgdGhlICJ0ZW1wbGF0ZSBpbmxpbmluZyIKLSAgLy8gb3B0aW1pemF0aW9uLiAgVGhlIG9wdGltaXphdGlvbiBpbnZvbHZlcyBtYWtpbmcgYSBjb3B5IG9mIHRoZSBjb2RlCi0gIC8vIGdlbmVyYXRlZCBmb3IgYSB0ZW1wbGF0ZSBpbiBhbm90aGVyIHRlbXBsYXRlIHRoYXQgcmVmZXJzIHRvIGl0LgotICB7ICJvcHRpb25YTiIsICAiICAgWy1YTiAoYWJpbGl0YSBsJ2luc2VyaW1lbnRvIGluIGxpbmVhIGRlaSBtb2RlbGxpKV0iIH0sCi0gIHsgIm9wdGlvblhYIiwgICIgICBbLVhYIChhdHRpdmEgbCdvdXRwdXQgZGkgYWx0cmkgbWVzc2FnZ2kgZGkgZGVidWcpXSJ9LAotICB7ICJvcHRpb25YVCIgLCAiICAgWy1YVCAodXRpbGl6emEgaWwgdHJhbnNsZXQgcGVyIGVzZWd1aXJlIGxhIHRyYXNmb3JtYXppb25lLCBzZSBwb3NzaWJpbGUuKV0ifSwKLSAgeyAiZGlhZ1RpbWluZyIsIiAtLS0tLS0tLS0gTGEgdHJhc2Zvcm1hemlvbmUgZGkgezB9IG1lZGlhbnRlIHsxfSBoYSByaWNoaWVzdG8gezJ9IG1zIiB9LAotICB7ICJyZWN1cnNpb25Ub29EZWVwIiwiTmlkaWZpY2F6aW9uZSBkZWkgbW9kZWxsaSB0cm9wcG8gcHJvZm9uZGEuIE5pZGlmaWNhemlvbmUgPSB7MH0sIG1vZGVsbG8gezF9IHsyfS4iIH0sCi0gIHsgIm5hbWVJcyIsICJpbCBub21lIFx1MDBFOCIgfSwKLSAgeyAibWF0Y2hQYXR0ZXJuSXMiLCAiaWwgcGF0dGVybiBkaSBjb3JyaXNwb25kZW56YSBcdTAwRTgiIH0KLQotICB9OwotCi0gIH0KLSAgLy8gPT09PT09PT09PT09PT09PT0gSU5GUkFTVFJVQ1RVUkUgPT09PT09PT09PT09PT09PT09PT09PQotCi0gIC8qKiBTdHJpbmcgZm9yIHVzZSB3aGVuIGEgYmFkIGVycm9yIGNvZGUgd2FzIGVuY291bnRlcmVkLiAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBCQURfQ09ERSA9ICJCQURfQ09ERSI7Ci0KLSAgLyoqIFN0cmluZyBmb3IgdXNlIHdoZW4gZm9ybWF0dGluZyBvZiB0aGUgZXJyb3Igc3RyaW5nIGZhaWxlZC4gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBGT1JNQVRfRkFJTEVEID0gIkZPUk1BVF9GQUlMRUQiOwotCi0gIC8qKiBHZW5lcmFsIGVycm9yIHN0cmluZy4gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJPUl9TVFJJTkcgPSAiI2Vycm9yIjsKLQotICAvKiogU3RyaW5nIHRvIHByZXBlbmQgdG8gZXJyb3IgbWVzc2FnZXMuICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJPUl9IRUFERVIgPSAiRXJyb3I6ICI7Ci0KLSAgLyoqIFN0cmluZyB0byBwcmVwZW5kIHRvIHdhcm5pbmcgbWVzc2FnZXMuICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdBUk5JTkdfSEVBREVSID0gIldhcm5pbmc6ICI7Ci0KLSAgLyoqIFN0cmluZyB0byBzcGVjaWZ5IHRoZSBYU0xUIG1vZHVsZS4gICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFhTTF9IRUFERVIgPSAiWFNMVCAiOwotCi0gIC8qKiBTdHJpbmcgdG8gc3BlY2lmeSB0aGUgWE1MIHBhcnNlciBtb2R1bGUuICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxfSEVBREVSID0gIlhNTCAiOwotCi0gIC8qKiBJIGRvbid0IHRoaW5rIHRoaXMgaXMgdXNlZCBhbnkgbW9yZS4KLSAgICogQGRlcHJlY2F0ZWQgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFFVRVJZX0hFQURFUiA9ICJQQVRURVJOICI7Ci0KLQotICAgIH0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwvcmVzL1hTTFRFcnJvclJlc291cmNlc19qYS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC9yZXMvWFNMVEVycm9yUmVzb3VyY2VzX2phLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDc0NjBkM2UuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC9yZXMvWFNMVEVycm9yUmVzb3VyY2VzX2phLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNDQ3ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnJlczsKLQotaW1wb3J0IGphdmEudXRpbC5MaXN0UmVzb3VyY2VCdW5kbGU7Ci1pbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKLWltcG9ydCBqYXZhLnV0aWwuTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uOwotaW1wb3J0IGphdmEudXRpbC5SZXNvdXJjZUJ1bmRsZTsKLQotLyoqCi0gKiBTZXQgdXAgZXJyb3IgbWVzc2FnZXMuCi0gKiBXZSBidWlsZCBhIHR3byBkaW1lbnNpb25hbCBhcnJheSBvZiBtZXNzYWdlIGtleXMgYW5kCi0gKiBtZXNzYWdlIHN0cmluZ3MuIEluIG9yZGVyIHRvIGFkZCBhIG5ldyBtZXNzYWdlIGhlcmUsCi0gKiB5b3UgbmVlZCB0byBmaXJzdCBhZGQgYSBTdHJpbmcgY29uc3RhbnQuIEFuZAotICogIHlvdSBuZWVkIHRvIGVudGVyIGtleSAsIHZhbHVlIHBhaXIgYXMgcGFydCBvZiBjb250ZW50cwotICogQXJyYXkuIFlvdSBhbHNvIG5lZWQgdG8gdXBkYXRlIE1BWF9DT0RFIGZvciBlcnJvciBzdHJpbmdzCi0gKiBhbmQgTUFYX1dBUk5JTkcgZm9yIHdhcm5pbmdzICggTmVlZGVkIGZvciBvbmx5IGluZm9ybWF0aW9uCi0gKiBwdXJwb3NlICkKLSAqLwotcHVibGljIGNsYXNzIFhTTFRFcnJvclJlc291cmNlc19qYSBleHRlbmRzIExpc3RSZXNvdXJjZUJ1bmRsZQotewotCi0vKgotICogVGhpcyBmaWxlIGNvbnRhaW5zIGVycm9yIGFuZCB3YXJuaW5nIG1lc3NhZ2VzIHJlbGF0ZWQgdG8gWGFsYW4gRXJyb3IKLSAqIEhhbmRsaW5nLgotICoKLSAqICBHZW5lcmFsIG5vdGVzIHRvIHRyYW5zbGF0b3JzOgotICoKLSAqICAxKSBYYWxhbiAob3IgbW9yZSBwcm9wZXJseSwgWGFsYW4taW50ZXJwcmV0aXZlKSBhbmQgWFNMVEMgYXJlIG5hbWVzIG9mCi0gKiAgICAgY29tcG9uZW50cy4KLSAqICAgICBYU0xUIGlzIGFuIGFjcm9ueW0gZm9yICJYTUwgU3R5bGVzaGVldCBMYW5ndWFnZTogVHJhbnNmb3JtYXRpb25zIi4KLSAqICAgICBYU0xUQyBpcyBhbiBhY3JvbnltIGZvciBYU0xUIENvbXBpbGVyLgotICoKLSAqICAyKSBBIHN0eWxlc2hlZXQgaXMgYSBkZXNjcmlwdGlvbiBvZiBob3cgdG8gdHJhbnNmb3JtIGFuIGlucHV0IFhNTCBkb2N1bWVudAotICogICAgIGludG8gYSByZXN1bHRhbnQgWE1MIGRvY3VtZW50IChvciBIVE1MIGRvY3VtZW50IG9yIHRleHQpLiAgVGhlCi0gKiAgICAgc3R5bGVzaGVldCBpdHNlbGYgaXMgZGVzY3JpYmVkIGluIHRoZSBmb3JtIG9mIGFuIFhNTCBkb2N1bWVudC4KLSAqCi0gKiAgMykgQSB0ZW1wbGF0ZSBpcyBhIGNvbXBvbmVudCBvZiBhIHN0eWxlc2hlZXQgdGhhdCBpcyB1c2VkIHRvIG1hdGNoIGEKLSAqICAgICBwYXJ0aWN1bGFyIHBvcnRpb24gb2YgYW4gaW5wdXQgZG9jdW1lbnQgYW5kIHNwZWNpZmllcyB0aGUgZm9ybSBvZiB0aGUKLSAqICAgICBjb3JyZXNwb25kaW5nIHBvcnRpb24gb2YgdGhlIG91dHB1dCBkb2N1bWVudC4KLSAqCi0gKiAgNCkgQW4gZWxlbWVudCBpcyBhIG1hcmstdXAgdGFnIGluIGFuIFhNTCBkb2N1bWVudDsgYW4gYXR0cmlidXRlIGlzIGEKLSAqICAgICBtb2RpZmllciBvbiB0aGUgdGFnLiAgRm9yIGV4YW1wbGUsIGluIDxlbGVtIGF0dHI9J3ZhbCcgYXR0cjI9J3ZhbDInPgotICogICAgICJlbGVtIiBpcyBhbiBlbGVtZW50IG5hbWUsICJhdHRyIiBhbmQgImF0dHIyIiBhcmUgYXR0cmlidXRlIG5hbWVzIHdpdGgKLSAqICAgICB0aGUgdmFsdWVzICJ2YWwiIGFuZCAidmFsMiIsIHJlc3BlY3RpdmVseS4KLSAqCi0gKiAgNSkgQSBuYW1lc3BhY2UgZGVjbGFyYXRpb24gaXMgYSBzcGVjaWFsIGF0dHJpYnV0ZSB0aGF0IGlzIHVzZWQgdG8gYXNzb2NpYXRlCi0gKiAgICAgYSBwcmVmaXggd2l0aCBhIFVSSSAodGhlIG5hbWVzcGFjZSkuICBUaGUgbWVhbmluZ3Mgb2YgZWxlbWVudCBuYW1lcyBhbmQKLSAqICAgICBhdHRyaWJ1dGUgbmFtZXMgdGhhdCB1c2UgdGhhdCBwcmVmaXggYXJlIGRlZmluZWQgd2l0aCByZXNwZWN0IHRvIHRoYXQKLSAqICAgICBuYW1lc3BhY2UuCi0gKgotICogIDYpICJUcmFuc2xldCIgaXMgYW4gaW52ZW50ZWQgdGVybSB0aGF0IGRlc2NyaWJlcyB0aGUgY2xhc3MgZmlsZSB0aGF0Ci0gKiAgICAgcmVzdWx0cyBmcm9tIGNvbXBpbGluZyBhbiBYTUwgc3R5bGVzaGVldCBpbnRvIGEgSmF2YSBjbGFzcy4KLSAqCi0gKiAgNykgWFBhdGggaXMgYSBzcGVjaWZpY2F0aW9uIHRoYXQgZGVzY3JpYmVzIGEgbm90YXRpb24gZm9yIGlkZW50aWZ5aW5nCi0gKiAgICAgbm9kZXMgaW4gYSB0cmVlLXN0cnVjdHVyZWQgcmVwcmVzZW50YXRpb24gb2YgYW4gWE1MIGRvY3VtZW50LiAgQW4KLSAqICAgICBpbnN0YW5jZSBvZiB0aGF0IG5vdGF0aW9uIGlzIHJlZmVycmVkIHRvIGFzIGFuIFhQYXRoIGV4cHJlc3Npb24uCi0gKgotICovCi0KLSAgLyoKLSAgICogU3RhdGljIHZhcmlhYmxlcwotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9OQU1FU1BBQ0VfVVJJX1ZBTFVFX0ZPUl9SRVNVTFRfUFJFRklYID0KLSAgICAgICAgIkVSX0lOVkFMSURfU0VUX05BTUVTUEFDRV9VUklfVkFMVUVfRk9SX1JFU1VMVF9QUkVGSVgiOwotCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfTkFNRVNQQUNFX1VSSV9WQUxVRV9GT1JfUkVTVUxUX1BSRUZJWF9GT1JfREVGQVVMVCA9Ci0gICAgICAgICJFUl9JTlZBTElEX05BTUVTUEFDRV9VUklfVkFMVUVfRk9SX1JFU1VMVF9QUkVGSVhfRk9SX0RFRkFVTFQiOwotCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX0NVUkxZQlJBQ0UgPSAiRVJfTk9fQ1VSTFlCUkFDRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQgPSAiRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lMTEVHQUxfQVRUUklCVVRFID0gIkVSX0lMTEVHQUxfQVRUUklCVVRFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTlVMTF9TT1VSQ0VOT0RFX0FQUExZSU1QT1JUUyA9ICJFUl9OVUxMX1NPVVJDRU5PREVfQVBQTFlJTVBPUlRTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX0FERCA9ICJFUl9DQU5OT1RfQUREIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTlVMTF9TT1VSQ0VOT0RFX0hBTkRMRUFQUExZVEVNUExBVEVTPSJFUl9OVUxMX1NPVVJDRU5PREVfSEFORExFQVBQTFlURU1QTEFURVMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19OQU1FX0FUVFJJQiA9ICJFUl9OT19OQU1FX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1RFTVBMQVRFX05PVF9GT1VORCA9ICJFUl9URU1QTEFURV9OT1RfRk9VTkQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX1JFU09MVkVfTkFNRV9BVlQgPSAiRVJfQ0FOVF9SRVNPTFZFX05BTUVfQVZUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUkVRVUlSRVNfQVRUUklCID0gIkVSX1JFUVVJUkVTX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01VU1RfSEFWRV9URVNUX0FUVFJJQiA9ICJFUl9NVVNUX0hBVkVfVEVTVF9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9CQURfVkFMX09OX0xFVkVMX0FUVFJJQiA9Ci0gICAgICAgICAiRVJfQkFEX1ZBTF9PTl9MRVZFTF9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUk9DRVNTSU5HSU5TVFJVQ1RJT05fTkFNRV9DQU5UX0JFX1hNTCA9Ci0gICAgICAgICAiRVJfUFJPQ0VTU0lOR0lOU1RSVUNUSU9OX05BTUVfQ0FOVF9CRV9YTUwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUk9DRVNTSU5HSU5TVFJVQ1RJT05fTk9UVkFMSURfTkNOQU1FID0KLSAgICAgICAgICJFUl9QUk9DRVNTSU5HSU5TVFJVQ1RJT05fTk9UVkFMSURfTkNOQU1FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTkVFRF9NQVRDSF9BVFRSSUIgPSAiRVJfTkVFRF9NQVRDSF9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9ORUVEX05BTUVfT1JfTUFUQ0hfQVRUUklCID0KLSAgICAgICAgICJFUl9ORUVEX05BTUVfT1JfTUFUQ0hfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9SRVNPTFZFX05TUFJFRklYID0KLSAgICAgICAgICJFUl9DQU5UX1JFU09MVkVfTlNQUkVGSVgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTExFR0FMX1ZBTFVFID0gIkVSX0lMTEVHQUxfVkFMVUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19PV05FUkRPQyA9ICJFUl9OT19PV05FUkRPQyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VMRU1URU1QTEFURUVMRU1fRVJSID0iRVJfRUxFTVRFTVBMQVRFRUxFTV9FUlIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OVUxMX0NISUxEID0gIkVSX05VTExfQ0hJTEQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9ORUVEX1NFTEVDVF9BVFRSSUIgPSAiRVJfTkVFRF9TRUxFQ1RfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTkVFRF9URVNUX0FUVFJJQiA9ICJFUl9ORUVEX1RFU1RfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTkVFRF9OQU1FX0FUVFJJQiA9ICJFUl9ORUVEX05BTUVfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fQ09OVEVYVF9PV05FUkRPQyA9ICJFUl9OT19DT05URVhUX09XTkVSRE9DIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTERfTk9UX0NSRUFURV9YTUxfUFJPQ19MSUFJU09OID0KLSAgICAgICAgICJFUl9DT1VMRF9OT1RfQ1JFQVRFX1hNTF9QUk9DX0xJQUlTT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUk9DRVNTX05PVF9TVUNDRVNTRlVMID0KLSAgICAgICAgICJFUl9QUk9DRVNTX05PVF9TVUNDRVNTRlVMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9UX1NVQ0NFU1NGVUwgPSAiRVJfTk9UX1NVQ0NFU1NGVUwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FTkNPRElOR19OT1RfU1VQUE9SVEVEID0KLSAgICAgICAgICJFUl9FTkNPRElOR19OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTERfTk9UX0NSRUFURV9UUkFDRUxJU1RFTkVSID0KLSAgICAgICAgICJFUl9DT1VMRF9OT1RfQ1JFQVRFX1RSQUNFTElTVEVORVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9LRVlfUkVRVUlSRVNfTkFNRV9BVFRSSUIgPQotICAgICAgICAgIkVSX0tFWV9SRVFVSVJFU19OQU1FX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0tFWV9SRVFVSVJFU19NQVRDSF9BVFRSSUIgPQotICAgICAgICAgIkVSX0tFWV9SRVFVSVJFU19NQVRDSF9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9LRVlfUkVRVUlSRVNfVVNFX0FUVFJJQiA9Ci0gICAgICAgICAiRVJfS0VZX1JFUVVJUkVTX1VTRV9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SRVFVSVJFU19FTEVNRU5UU19BVFRSSUIgPQotICAgICAgICAgIkVSX1JFUVVJUkVTX0VMRU1FTlRTX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01JU1NJTkdfUFJFRklYX0FUVFJJQiA9Ci0gICAgICAgICAiRVJfTUlTU0lOR19QUkVGSVhfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQkFEX1NUWUxFU0hFRVRfVVJMID0gIkVSX0JBRF9TVFlMRVNIRUVUX1VSTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZJTEVfTk9UX0ZPVU5EID0gIkVSX0ZJTEVfTk9UX0ZPVU5EIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU9FWENFUFRJT04gPSAiRVJfSU9FWENFUFRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19IUkVGX0FUVFJJQiA9ICJFUl9OT19IUkVGX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NUWUxFU0hFRVRfSU5DTFVERVNfSVRTRUxGID0KLSAgICAgICAgICJFUl9TVFlMRVNIRUVUX0lOQ0xVREVTX0lUU0VMRiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BST0NFU1NJTkNMVURFX0VSUk9SID0iRVJfUFJPQ0VTU0lOQ0xVREVfRVJST1IiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9NSVNTSU5HX0xBTkdfQVRUUklCID0gIkVSX01JU1NJTkdfTEFOR19BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9NSVNTSU5HX0NPTlRBSU5FUl9FTEVNRU5UX0NPTVBPTkVOVCA9Ci0gICAgICAgICAiRVJfTUlTU0lOR19DT05UQUlORVJfRUxFTUVOVF9DT01QT05FTlQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5fT05MWV9PVVRQVVRfVE9fRUxFTUVOVCA9Ci0gICAgICAgICAiRVJfQ0FOX09OTFlfT1VUUFVUX1RPX0VMRU1FTlQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUk9DRVNTX0VSUk9SID0gIkVSX1BST0NFU1NfRVJST1IiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTklNUExOT0RFX0VSUk9SID0gIkVSX1VOSU1QTE5PREVfRVJST1IiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19TRUxFQ1RfRVhQUkVTU0lPTiA9IkVSX05PX1NFTEVDVF9FWFBSRVNTSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX1NFUklBTElaRV9YU0xQUk9DRVNTT1IgPQotICAgICAgICAgIkVSX0NBTk5PVF9TRVJJQUxJWkVfWFNMUFJPQ0VTU09SIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fSU5QVVRfU1RZTEVTSEVFVCA9ICJFUl9OT19JTlBVVF9TVFlMRVNIRUVUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRkFJTEVEX1BST0NFU1NfU1RZTEVTSEVFVCA9Ci0gICAgICAgICAiRVJfRkFJTEVEX1BST0NFU1NfU1RZTEVTSEVFVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxETlRfUEFSU0VfRE9DID0gIkVSX0NPVUxETlRfUEFSU0VfRE9DIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTEROVF9GSU5EX0ZSQUdNRU5UID0KLSAgICAgICAgICJFUl9DT1VMRE5UX0ZJTkRfRlJBR01FTlQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT0RFX05PVF9FTEVNRU5UID0gIkVSX05PREVfTk9UX0VMRU1FTlQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GT1JFQUNIX05FRURfTUFUQ0hfT1JfTkFNRV9BVFRSSUIgPQotICAgICAgICAgIkVSX0ZPUkVBQ0hfTkVFRF9NQVRDSF9PUl9OQU1FX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1RFTVBMQVRFU19ORUVEX01BVENIX09SX05BTUVfQVRUUklCID0KLSAgICAgICAgICJFUl9URU1QTEFURVNfTkVFRF9NQVRDSF9PUl9OQU1FX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX0NMT05FX09GX0RPQ1VNRU5UX0ZSQUcgPQotICAgICAgICAgIkVSX05PX0NMT05FX09GX0RPQ1VNRU5UX0ZSQUciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX0NSRUFURV9JVEVNID0gIkVSX0NBTlRfQ1JFQVRFX0lURU0iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YTUxTUEFDRV9JTExFR0FMX1ZBTFVFID0KLSAgICAgICAgICJFUl9YTUxTUEFDRV9JTExFR0FMX1ZBTFVFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fWFNMS0VZX0RFQ0xBUkFUSU9OID0KLSAgICAgICAgICJFUl9OT19YU0xLRVlfREVDTEFSQVRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX0NSRUFURV9VUkwgPSAiRVJfQ0FOVF9DUkVBVEVfVVJMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWFNMRlVOQ1RJT05TX1VOU1VQUE9SVEVEID0KLSAgICAgICAgICJFUl9YU0xGVU5DVElPTlNfVU5TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUk9DRVNTT1JfRVJST1IgPSAiRVJfUFJPQ0VTU09SX0VSUk9SIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9UX0FMTE9XRURfSU5TSURFX1NUWUxFU0hFRVQgPQotICAgICAgICAgIkVSX05PVF9BTExPV0VEX0lOU0lERV9TVFlMRVNIRUVUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUkVTVUxUTlNfTk9UX1NVUFBPUlRFRCA9Ci0gICAgICAgICAiRVJfUkVTVUxUTlNfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0RFRkFVTFRTUEFDRV9OT1RfU1VQUE9SVEVEID0KLSAgICAgICAgICJFUl9ERUZBVUxUU1BBQ0VfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOREVOVFJFU1VMVF9OT1RfU1VQUE9SVEVEID0KLSAgICAgICAgICJFUl9JTkRFTlRSRVNVTFRfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lMTEVHQUxfQVRUUklCID0gIkVSX0lMTEVHQUxfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5LTk9XTl9YU0xfRUxFTSA9ICJFUl9VTktOT1dOX1hTTF9FTEVNIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQkFEX1hTTFNPUlRfVVNFID0gIkVSX0JBRF9YU0xTT1JUX1VTRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01JU1BMQUNFRF9YU0xXSEVOID0gIkVSX01JU1BMQUNFRF9YU0xXSEVOIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWFNMV0hFTl9OT1RfUEFSRU5URURfQllfWFNMQ0hPT1NFID0KLSAgICAgICAgICJFUl9YU0xXSEVOX05PVF9QQVJFTlRFRF9CWV9YU0xDSE9PU0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9NSVNQTEFDRURfWFNMT1RIRVJXSVNFID0KLSAgICAgICAgICJFUl9NSVNQTEFDRURfWFNMT1RIRVJXSVNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWFNMT1RIRVJXSVNFX05PVF9QQVJFTlRFRF9CWV9YU0xDSE9PU0UgPQotICAgICAgICAgIkVSX1hTTE9USEVSV0lTRV9OT1RfUEFSRU5URURfQllfWFNMQ0hPT1NFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9UX0FMTE9XRURfSU5TSURFX1RFTVBMQVRFID0KLSAgICAgICAgICJFUl9OT1RfQUxMT1dFRF9JTlNJREVfVEVNUExBVEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTktOT1dOX0VYVF9OU19QUkVGSVggPQotICAgICAgICAgIkVSX1VOS05PV05fRVhUX05TX1BSRUZJWCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lNUE9SVFNfQVNfRklSU1RfRUxFTSA9Ci0gICAgICAgICAiRVJfSU1QT1JUU19BU19GSVJTVF9FTEVNIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU1QT1JUSU5HX0lUU0VMRiA9ICJFUl9JTVBPUlRJTkdfSVRTRUxGIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWE1MU1BBQ0VfSUxMRUdBTF9WQUwgPSJFUl9YTUxTUEFDRV9JTExFR0FMX1ZBTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BST0NFU1NTVFlMRVNIRUVUX05PVF9TVUNDRVNTRlVMID0KLSAgICAgICAgICJFUl9QUk9DRVNTU1RZTEVTSEVFVF9OT1RfU1VDQ0VTU0ZVTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NBWF9FWENFUFRJT04gPSAiRVJfU0FYX0VYQ0VQVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hTTFRfRVJST1IgPSAiRVJfWFNMVF9FUlJPUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NVUlJFTkNZX1NJR05fSUxMRUdBTD0KLSAgICAgICAgICJFUl9DVVJSRU5DWV9TSUdOX0lMTEVHQUwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9ET0NVTUVOVF9GVU5DVElPTl9JTlZBTElEX0lOX1NUWUxFU0hFRVRfRE9NID0KLSAgICAgICAgICJFUl9ET0NVTUVOVF9GVU5DVElPTl9JTlZBTElEX0lOX1NUWUxFU0hFRVRfRE9NIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9SRVNPTFZFX1BSRUZJWF9PRl9OT05fUFJFRklYX1JFU09MVkVSID0KLSAgICAgICAgICJFUl9DQU5UX1JFU09MVkVfUFJFRklYX09GX05PTl9QUkVGSVhfUkVTT0xWRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SRURJUkVDVF9DT1VMRE5UX0dFVF9GSUxFTkFNRSA9Ci0gICAgICAgICAiRVJfUkVESVJFQ1RfQ09VTEROVF9HRVRfRklMRU5BTUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfQlVJTERfRk9STUFUVEVSTElTVEVORVJfSU5fUkVESVJFQ1QgPQotICAgICAgICAgIkVSX0NBTk5PVF9CVUlMRF9GT1JNQVRURVJMSVNURU5FUl9JTl9SRURJUkVDVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfUFJFRklYX0lOX0VYQ0xVREVSRVNVTFRQUkVGSVggPQotICAgICAgICAgIkVSX0lOVkFMSURfUFJFRklYX0lOX0VYQ0xVREVSRVNVTFRQUkVGSVgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9NSVNTSU5HX05TX1VSSSA9ICJFUl9NSVNTSU5HX05TX1VSSSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01JU1NJTkdfQVJHX0ZPUl9PUFRJT04gPQotICAgICAgICAgIkVSX01JU1NJTkdfQVJHX0ZPUl9PUFRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX09QVElPTiA9ICJFUl9JTlZBTElEX09QVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01BTEZPUk1FRF9GT1JNQVRfU1RSSU5HID0KLSAgICAgICAgICJFUl9NQUxGT1JNRURfRk9STUFUX1NUUklORyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NUWUxFU0hFRVRfUkVRVUlSRVNfVkVSU0lPTl9BVFRSSUIgPQotICAgICAgICAgIkVSX1NUWUxFU0hFRVRfUkVRVUlSRVNfVkVSU0lPTl9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTExFR0FMX0FUVFJJQlVURV9WQUxVRSA9Ci0gICAgICAgICAiRVJfSUxMRUdBTF9BVFRSSUJVVEVfVkFMVUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DSE9PU0VfUkVRVUlSRVNfV0hFTiA9IkVSX0NIT09TRV9SRVFVSVJFU19XSEVOIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fQVBQTFlfSU1QT1JUX0lOX0ZPUl9FQUNIID0KLSAgICAgICAgICJFUl9OT19BUFBMWV9JTVBPUlRfSU5fRk9SX0VBQ0giOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX1VTRV9EVE1fRk9SX09VVFBVVCA9Ci0gICAgICAgICAiRVJfQ0FOVF9VU0VfRFRNX0ZPUl9PVVRQVVQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX1VTRV9EVE1fRk9SX0lOUFVUID0KLSAgICAgICAgICJFUl9DQU5UX1VTRV9EVE1fRk9SX0lOUFVUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FMTF9UT19FWFRfRkFJTEVEID0gIkVSX0NBTExfVE9fRVhUX0ZBSUxFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BSRUZJWF9NVVNUX1JFU09MVkUgPSAiRVJfUFJFRklYX01VU1RfUkVTT0xWRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfVVRGMTZfU1VSUk9HQVRFID0KLSAgICAgICAgICJFUl9JTlZBTElEX1VURjE2X1NVUlJPR0FURSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hTTEFUVFJTRVRfVVNFRF9JVFNFTEYgPQotICAgICAgICAgIkVSX1hTTEFUVFJTRVRfVVNFRF9JVFNFTEYiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfTUlYX1hFUkNFU0RPTSA9IkVSX0NBTk5PVF9NSVhfWEVSQ0VTRE9NIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVE9PX01BTllfTElTVEVORVJTID0gIkVSX1RPT19NQU5ZX0xJU1RFTkVSUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOX0VMRU1URU1QTEFURUVMRU1fUkVBRE9CSkVDVCA9Ci0gICAgICAgICAiRVJfSU5fRUxFTVRFTVBMQVRFRUxFTV9SRUFET0JKRUNUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRFVQTElDQVRFX05BTUVEX1RFTVBMQVRFID0KLSAgICAgICAgICJFUl9EVVBMSUNBVEVfTkFNRURfVEVNUExBVEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX0tFWV9DQUxMID0gIkVSX0lOVkFMSURfS0VZX0NBTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SRUZFUkVOQ0lOR19JVFNFTEYgPSAiRVJfUkVGRVJFTkNJTkdfSVRTRUxGIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSUxMRUdBTF9ET01TT1VSQ0VfSU5QVVQgPQotICAgICAgICAgIkVSX0lMTEVHQUxfRE9NU09VUkNFX0lOUFVUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0xBU1NfTk9UX0ZPVU5EX0ZPUl9PUFRJT04gPQotICAgICAgICAgIkVSX0NMQVNTX05PVF9GT1VORF9GT1JfT1BUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUkVRVUlSRURfRUxFTV9OT1RfRk9VTkQgPQotICAgICAgICAgIkVSX1JFUVVJUkVEX0VMRU1fTk9UX0ZPVU5EIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5QVVRfQ0FOTk9UX0JFX05VTEwgPSJFUl9JTlBVVF9DQU5OT1RfQkVfTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1VSSV9DQU5OT1RfQkVfTlVMTCA9ICJFUl9VUklfQ0FOTk9UX0JFX05VTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GSUxFX0NBTk5PVF9CRV9OVUxMID0gIkVSX0ZJTEVfQ0FOTk9UX0JFX05VTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TT1VSQ0VfQ0FOTk9UX0JFX05VTEwgPQotICAgICAgICAgIkVSX1NPVVJDRV9DQU5OT1RfQkVfTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9JTklUX0JTRk1HUiA9ICJFUl9DQU5OT1RfSU5JVF9CU0ZNR1IiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfQ01QTF9FWFRFTlNOID0gIkVSX0NBTk5PVF9DTVBMX0VYVEVOU04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfQ1JFQVRFX0VYVEVOU04gPQotICAgICAgICAgIkVSX0NBTk5PVF9DUkVBVEVfRVhURU5TTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOU1RBTkNFX01USERfQ0FMTF9SRVFVSVJFUyA9Ci0gICAgICAgICAiRVJfSU5TVEFOQ0VfTVRIRF9DQUxMX1JFUVVJUkVTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9FTEVNRU5UX05BTUUgPSJFUl9JTlZBTElEX0VMRU1FTlRfTkFNRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VMRU1FTlRfTkFNRV9NRVRIT0RfU1RBVElDID0KLSAgICAgICAgICJFUl9FTEVNRU5UX05BTUVfTUVUSE9EX1NUQVRJQyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYVEVOU0lPTl9GVU5DX1VOS05PV04gPQotICAgICAgICAgIkVSX0VYVEVOU0lPTl9GVU5DX1VOS05PV04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9NT1JFX01BVENIX0NPTlNUUlVDVE9SID0KLSAgICAgICAgICJFUl9NT1JFX01BVENIX0NPTlNUUlVDVE9SIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTU9SRV9NQVRDSF9NRVRIT0QgPSAiRVJfTU9SRV9NQVRDSF9NRVRIT0QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9NT1JFX01BVENIX0VMRU1FTlQgPSAiRVJfTU9SRV9NQVRDSF9FTEVNRU5UIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9DT05URVhUX1BBU1NFRCA9Ci0gICAgICAgICAiRVJfSU5WQUxJRF9DT05URVhUX1BBU1NFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BPT0xfRVhJU1RTID0gIkVSX1BPT0xfRVhJU1RTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fRFJJVkVSX05BTUUgPSAiRVJfTk9fRFJJVkVSX05BTUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19VUkwgPSAiRVJfTk9fVVJMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUE9PTF9TSVpFX0xFU1NUSEFOX09ORSA9Ci0gICAgICAgICAiRVJfUE9PTF9TSVpFX0xFU1NUSEFOX09ORSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfRFJJVkVSID0gIkVSX0lOVkFMSURfRFJJVkVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fU1RZTEVTSEVFVFJPT1QgPSAiRVJfTk9fU1RZTEVTSEVFVFJPT1QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTExFR0FMX1hNTFNQQUNFX1ZBTFVFID0KLSAgICAgICAgICJFUl9JTExFR0FMX1hNTFNQQUNFX1ZBTFVFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJPQ0VTU0ZST01OT0RFX0ZBSUxFRCA9Ci0gICAgICAgICAiRVJfUFJPQ0VTU0ZST01OT0RFX0ZBSUxFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1JFU09VUkNFX0NPVUxEX05PVF9MT0FEID0KLSAgICAgICAgICJFUl9SRVNPVVJDRV9DT1VMRF9OT1RfTE9BRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0JVRkZFUl9TSVpFX0xFU1NUSEFOX1pFUk8gPQotICAgICAgICAgIkVSX0JVRkZFUl9TSVpFX0xFU1NUSEFOX1pFUk8iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTktOT1dOX0VSUk9SX0NBTExJTkdfRVhURU5TSU9OID0KLSAgICAgICAgICJFUl9VTktOT1dOX0VSUk9SX0NBTExJTkdfRVhURU5TSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fTkFNRVNQQUNFX0RFQ0wgPSAiRVJfTk9fTkFNRVNQQUNFX0RFQ0wiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FTEVNX0NPTlRFTlRfTk9UX0FMTE9XRUQgPQotICAgICAgICAgIkVSX0VMRU1fQ09OVEVOVF9OT1RfQUxMT1dFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NUWUxFU0hFRVRfRElSRUNURURfVEVSTUlOQVRJT04gPQotICAgICAgICAgIkVSX1NUWUxFU0hFRVRfRElSRUNURURfVEVSTUlOQVRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9PTkVfT1JfVFdPID0gIkVSX09ORV9PUl9UV08iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9UV09fT1JfVEhSRUUgPSAiRVJfVFdPX09SX1RIUkVFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTERfTk9UX0xPQURfUkVTT1VSQ0UgPQotICAgICAgICAgIkVSX0NPVUxEX05PVF9MT0FEX1JFU09VUkNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX0lOSVRfREVGQVVMVF9URU1QTEFURVMgPQotICAgICAgICAgIkVSX0NBTk5PVF9JTklUX0RFRkFVTFRfVEVNUExBVEVTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUkVTVUxUX05VTEwgPSAiRVJfUkVTVUxUX05VTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SRVNVTFRfQ09VTERfTk9UX0JFX1NFVCA9Ci0gICAgICAgICAiRVJfUkVTVUxUX0NPVUxEX05PVF9CRV9TRVQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19PVVRQVVRfU1BFQ0lGSUVEID0gIkVSX05PX09VVFBVVF9TUEVDSUZJRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfVFJBTlNGT1JNX1RPX1JFU1VMVF9UWVBFID0KLSAgICAgICAgICJFUl9DQU5OT1RfVFJBTlNGT1JNX1RPX1JFU1VMVF9UWVBFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX1RSQU5TRk9STV9TT1VSQ0VfVFlQRSA9Ci0gICAgICAgICAiRVJfQ0FOTk9UX1RSQU5TRk9STV9TT1VSQ0VfVFlQRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05VTExfQ09OVEVOVF9IQU5ETEVSID0iRVJfTlVMTF9DT05URU5UX0hBTkRMRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OVUxMX0VSUk9SX0hBTkRMRVIgPSAiRVJfTlVMTF9FUlJPUl9IQU5ETEVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX0NBTExfUEFSU0UgPSAiRVJfQ0FOTk9UX0NBTExfUEFSU0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19QQVJFTlRfRk9SX0ZJTFRFUiA9IkVSX05PX1BBUkVOVF9GT1JfRklMVEVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fU1RZTEVTSEVFVF9JTl9NRURJQSA9Ci0gICAgICAgICAiRVJfTk9fU1RZTEVTSEVFVF9JTl9NRURJQSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1NUWUxFU0hFRVRfUEkgPSAiRVJfTk9fU1RZTEVTSEVFVF9QSSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PVF9TVVBQT1JURUQgPSAiRVJfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BST1BFUlRZX1ZBTFVFX0JPT0xFQU4gPQotICAgICAgICAgIkVSX1BST1BFUlRZX1ZBTFVFX0JPT0xFQU4iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRF9OT1RfRklORF9FWFRFUk5fU0NSSVBUID0KLSAgICAgICAgICJFUl9DT1VMRF9OT1RfRklORF9FWFRFUk5fU0NSSVBUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUkVTT1VSQ0VfQ09VTERfTk9UX0ZJTkQgPQotICAgICAgICAgIkVSX1JFU09VUkNFX0NPVUxEX05PVF9GSU5EIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfT1VUUFVUX1BST1BFUlRZX05PVF9SRUNPR05JWkVEID0KLSAgICAgICAgICJFUl9PVVRQVVRfUFJPUEVSVFlfTk9UX1JFQ09HTklaRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GQUlMRURfQ1JFQVRJTkdfRUxFTUxJVFJTTFQgPQotICAgICAgICAgIkVSX0ZBSUxFRF9DUkVBVElOR19FTEVNTElUUlNMVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1ZBTFVFX1NIT1VMRF9CRV9OVU1CRVIgPQotICAgICAgICAgIkVSX1ZBTFVFX1NIT1VMRF9CRV9OVU1CRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9WQUxVRV9TSE9VTERfRVFVQUwgPSAiRVJfVkFMVUVfU0hPVUxEX0VRVUFMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRkFJTEVEX0NBTExJTkdfTUVUSE9EID0KLSAgICAgICAgICJFUl9GQUlMRURfQ0FMTElOR19NRVRIT0QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GQUlMRURfQ1JFQVRJTkdfRUxFTVRNUEwgPQotICAgICAgICAgIkVSX0ZBSUxFRF9DUkVBVElOR19FTEVNVE1QTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NIQVJTX05PVF9BTExPV0VEID0gIkVSX0NIQVJTX05PVF9BTExPV0VEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQVRUUl9OT1RfQUxMT1dFRCA9ICJFUl9BVFRSX05PVF9BTExPV0VEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQkFEX1ZBTFVFID0gIkVSX0JBRF9WQUxVRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FUVFJJQl9WQUxVRV9OT1RfRk9VTkQgPQotICAgICAgICAgIkVSX0FUVFJJQl9WQUxVRV9OT1RfRk9VTkQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9BVFRSSUJfVkFMVUVfTk9UX1JFQ09HTklaRUQgPQotICAgICAgICAgIkVSX0FUVFJJQl9WQUxVRV9OT1RfUkVDT0dOSVpFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05VTExfVVJJX05BTUVTUEFDRSA9ICJFUl9OVUxMX1VSSV9OQU1FU1BBQ0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OVU1CRVJfVE9PX0JJRyA9ICJFUl9OVU1CRVJfVE9PX0JJRyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nICBFUl9DQU5OT1RfRklORF9TQVgxX0RSSVZFUiA9Ci0gICAgICAgICAiRVJfQ0FOTk9UX0ZJTkRfU0FYMV9EUklWRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyAgRVJfU0FYMV9EUklWRVJfTk9UX0xPQURFRCA9Ci0gICAgICAgICAiRVJfU0FYMV9EUklWRVJfTk9UX0xPQURFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nICBFUl9TQVgxX0RSSVZFUl9OT1RfSU5TVEFOVElBVEVEID0KLSAgICAgICAgICJFUl9TQVgxX0RSSVZFUl9OT1RfSU5TVEFOVElBVEVEIiA7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NBWDFfRFJJVkVSX05PVF9JTVBMRU1FTlRfUEFSU0VSID0KLSAgICAgICAgICJFUl9TQVgxX0RSSVZFUl9OT1RfSU1QTEVNRU5UX1BBUlNFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nICBFUl9QQVJTRVJfUFJPUEVSVFlfTk9UX1NQRUNJRklFRCA9Ci0gICAgICAgICAiRVJfUEFSU0VSX1BST1BFUlRZX05PVF9TUEVDSUZJRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyAgRVJfUEFSU0VSX0FSR19DQU5OT1RfQkVfTlVMTCA9Ci0gICAgICAgICAiRVJfUEFSU0VSX0FSR19DQU5OT1RfQkVfTlVMTCIgOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyAgRVJfRkVBVFVSRSA9ICJFUl9GRUFUVVJFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJPUEVSVFkgPSAiRVJfUFJPUEVSVFkiIDsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTlVMTF9FTlRJVFlfUkVTT0xWRVIgPSJFUl9OVUxMX0VOVElUWV9SRVNPTFZFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nICBFUl9OVUxMX0RURF9IQU5ETEVSID0gIkVSX05VTExfRFREX0hBTkRMRVIiIDsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fRFJJVkVSX05BTUVfU1BFQ0lGSUVEID0KLSAgICAgICAgICJFUl9OT19EUklWRVJfTkFNRV9TUEVDSUZJRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19VUkxfU1BFQ0lGSUVEID0gIkVSX05PX1VSTF9TUEVDSUZJRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QT09MU0laRV9MRVNTX1RIQU5fT05FID0KLSAgICAgICAgICJFUl9QT09MU0laRV9MRVNTX1RIQU5fT05FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9EUklWRVJfTkFNRSA9ICJFUl9JTlZBTElEX0RSSVZFUl9OQU1FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVJST1JMSVNURU5FUiA9ICJFUl9FUlJPUkxJU1RFTkVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQVNTRVJUX05PX1RFTVBMQVRFX1BBUkVOVCA9Ci0gICAgICAgICAiRVJfQVNTRVJUX05PX1RFTVBMQVRFX1BBUkVOVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FTU0VSVF9SRURVTkRFTlRfRVhQUl9FTElNSU5BVE9SID0KLSAgICAgICAgICJFUl9BU1NFUlRfUkVEVU5ERU5UX0VYUFJfRUxJTUlOQVRPUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PVF9BTExPV0VEX0lOX1BPU0lUSU9OID0KLSAgICAgICAgICJFUl9OT1RfQUxMT1dFRF9JTl9QT1NJVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PTldISVRFU1BBQ0VfTk9UX0FMTE9XRURfSU5fUE9TSVRJT04gPQotICAgICAgICAgIkVSX05PTldISVRFU1BBQ0VfTk9UX0FMTE9XRURfSU5fUE9TSVRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OQU1FU1BBQ0VfQ09OVEVYVF9OVUxMX05BTUVTUEFDRSA9Ci0gICAgICAgICAiRVJfTkFNRVNQQUNFX0NPTlRFWFRfTlVMTF9OQU1FU1BBQ0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OQU1FU1BBQ0VfQ09OVEVYVF9OVUxMX1BSRUZJWCA9Ci0gICAgICAgICAiRVJfTkFNRVNQQUNFX0NPTlRFWFRfTlVMTF9QUkVGSVgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YUEFUSF9SRVNPTFZFUl9OVUxMX1FOQU1FID0KLSAgICAgICAgICJFUl9YUEFUSF9SRVNPTFZFUl9OVUxMX1FOQU1FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWFBBVEhfUkVTT0xWRVJfTkVHQVRJVkVfQVJJVFkgPQotICAgICAgICAgIkVSX1hQQVRIX1JFU09MVkVSX05FR0FUSVZFX0FSSVRZIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSU5WQUxJRF9UQ0hBUiA9ICJJTlZBTElEX1RDSEFSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSU5WQUxJRF9RTkFNRSA9ICJJTlZBTElEX1FOQU1FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSU5WQUxJRF9FTlVNID0gIklOVkFMSURfRU5VTSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIElOVkFMSURfTk1UT0tFTiA9ICJJTlZBTElEX05NVE9LRU4iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBJTlZBTElEX05DTkFNRSA9ICJJTlZBTElEX05DTkFNRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIElOVkFMSURfQk9PTEVBTiA9ICJJTlZBTElEX0JPT0xFQU4iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBJTlZBTElEX05VTUJFUiA9ICJJTlZBTElEX05VTUJFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FSR19MSVRFUkFMID0gIkVSX0FSR19MSVRFUkFMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRFVQTElDQVRFX0dMT0JBTF9WQVIgPSJFUl9EVVBMSUNBVEVfR0xPQkFMX1ZBUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0RVUExJQ0FURV9WQVIgPSAiRVJfRFVQTElDQVRFX1ZBUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1RFTVBMQVRFX05BTUVfTUFUQ0ggPSAiRVJfVEVNUExBVEVfTkFNRV9NQVRDSCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfUFJFRklYID0gIkVSX0lOVkFMSURfUFJFRklYIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fQVRUUklCX1NFVCA9ICJFUl9OT19BVFRSSUJfU0VUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRlVOQ1RJT05fTk9UX0ZPVU5EID0KLSAgICAgICAgICJFUl9GVU5DVElPTl9OT1RfRk9VTkQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX0hBVkVfQ09OVEVOVF9BTkRfU0VMRUNUID0KLSAgICAgIkVSX0NBTlRfSEFWRV9DT05URU5UX0FORF9TRUxFQ1QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX1NFVF9QQVJBTV9WQUxVRSA9ICJFUl9JTlZBTElEX1NFVF9QQVJBTV9WQUxVRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NFVF9GRUFUVVJFX05VTExfTkFNRSA9Ci0gICAgICAgICJFUl9TRVRfRkVBVFVSRV9OVUxMX05BTUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9HRVRfRkVBVFVSRV9OVUxMX05BTUUgPQotICAgICAgICAiRVJfR0VUX0ZFQVRVUkVfTlVMTF9OQU1FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5TVVBQT1JURURfRkVBVFVSRSA9Ci0gICAgICAgICJFUl9VTlNVUFBPUlRFRF9GRUFUVVJFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhURU5TSU9OX0VMRU1FTlRfTk9UX0FMTE9XRURfSU5fU0VDVVJFX1BST0NFU1NJTkcgPQotICAgICAgICAiRVJfRVhURU5TSU9OX0VMRU1FTlRfTk9UX0FMTE9XRURfSU5fU0VDVVJFX1BST0NFU1NJTkciOwotCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0ZPVU5EX0NVUkxZQlJBQ0UgPSAiV0dfRk9VTkRfQ1VSTFlCUkFDRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0NPVU5UX0FUVFJJQl9NQVRDSEVTX05PX0FOQ0VTVE9SID0KLSAgICAgICAgICJXR19DT1VOVF9BVFRSSUJfTUFUQ0hFU19OT19BTkNFU1RPUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0VYUFJfQVRUUklCX0NIQU5HRURfVE9fU0VMRUNUID0KLSAgICAgICAgICJXR19FWFBSX0FUVFJJQl9DSEFOR0VEX1RPX1NFTEVDVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX05PX0xPQ0FMRV9JTl9GT1JNQVROVU1CRVIgPQotICAgICAgICAgIldHX05PX0xPQ0FMRV9JTl9GT1JNQVROVU1CRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19MT0NBTEVfTk9UX0ZPVU5EID0gIldHX0xPQ0FMRV9OT1RfRk9VTkQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19DQU5OT1RfTUFLRV9VUkxfRlJPTSA9IldHX0NBTk5PVF9NQUtFX1VSTF9GUk9NIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfQ0FOTk9UX0xPQURfUkVRVUVTVEVEX0RPQyA9Ci0gICAgICAgICAiV0dfQ0FOTk9UX0xPQURfUkVRVUVTVEVEX0RPQyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0NBTk5PVF9GSU5EX0NPTExBVE9SID0iV0dfQ0FOTk9UX0ZJTkRfQ09MTEFUT1IiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19GVU5DVElPTlNfU0hPVUxEX1VTRV9VUkwgPQotICAgICAgICAgIldHX0ZVTkNUSU9OU19TSE9VTERfVVNFX1VSTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0VOQ09ESU5HX05PVF9TVVBQT1JURURfVVNJTkdfVVRGOCA9Ci0gICAgICAgICAiV0dfRU5DT0RJTkdfTk9UX1NVUFBPUlRFRF9VU0lOR19VVEY4IjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfRU5DT0RJTkdfTk9UX1NVUFBPUlRFRF9VU0lOR19KQVZBID0KLSAgICAgICAgICJXR19FTkNPRElOR19OT1RfU1VQUE9SVEVEX1VTSU5HX0pBVkEiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19TUEVDSUZJQ0lUWV9DT05GTElDVFMgPQotICAgICAgICAgIldHX1NQRUNJRklDSVRZX0NPTkZMSUNUUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX1BBUlNJTkdfQU5EX1BSRVBBUklORyA9Ci0gICAgICAgICAiV0dfUEFSU0lOR19BTkRfUFJFUEFSSU5HIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfQVRUUl9URU1QTEFURSA9ICJXR19BVFRSX1RFTVBMQVRFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfQ09ORkxJQ1RfQkVUV0VFTl9YU0xTVFJJUFNQQUNFX0FORF9YU0xQUkVTRVJWRVNQQUNFID0gIldHX0NPTkZMSUNUX0JFVFdFRU5fWFNMU1RSSVBTUEFDRV9BTkRfWFNMUFJFU0VSVkVTUCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0FUVFJJQl9OT1RfSEFORExFRCA9ICJXR19BVFRSSUJfTk9UX0hBTkRMRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19OT19ERUNJTUFMRk9STUFUX0RFQ0xBUkFUSU9OID0KLSAgICAgICAgICJXR19OT19ERUNJTUFMRk9STUFUX0RFQ0xBUkFUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfT0xEX1hTTFRfTlMgPSAiV0dfT0xEX1hTTFRfTlMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19PTkVfREVGQVVMVF9YU0xERUNJTUFMRk9STUFUX0FMTE9XRUQgPQotICAgICAgICAgIldHX09ORV9ERUZBVUxUX1hTTERFQ0lNQUxGT1JNQVRfQUxMT1dFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX1hTTERFQ0lNQUxGT1JNQVRfTkFNRVNfTVVTVF9CRV9VTklRVUUgPQotICAgICAgICAgIldHX1hTTERFQ0lNQUxGT1JNQVRfTkFNRVNfTVVTVF9CRV9VTklRVUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19JTExFR0FMX0FUVFJJQlVURSA9ICJXR19JTExFR0FMX0FUVFJJQlVURSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0NPVUxEX05PVF9SRVNPTFZFX1BSRUZJWCA9Ci0gICAgICAgICAiV0dfQ09VTERfTk9UX1JFU09MVkVfUFJFRklYIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfU1RZTEVTSEVFVF9SRVFVSVJFU19WRVJTSU9OX0FUVFJJQiA9Ci0gICAgICAgICAiV0dfU1RZTEVTSEVFVF9SRVFVSVJFU19WRVJTSU9OX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0lMTEVHQUxfQVRUUklCVVRFX05BTUUgPQotICAgICAgICAgIldHX0lMTEVHQUxfQVRUUklCVVRFX05BTUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19JTExFR0FMX0FUVFJJQlVURV9WQUxVRSA9Ci0gICAgICAgICAiV0dfSUxMRUdBTF9BVFRSSUJVVEVfVkFMVUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19FTVBUWV9TRUNPTkRfQVJHID0gIldHX0VNUFRZX1NFQ09ORF9BUkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19QUk9DRVNTSU5HSU5TVFJVQ1RJT05fTkFNRV9DQU5UX0JFX1hNTCA9Ci0gICAgICAgICAiV0dfUFJPQ0VTU0lOR0lOU1RSVUNUSU9OX05BTUVfQ0FOVF9CRV9YTUwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19QUk9DRVNTSU5HSU5TVFJVQ1RJT05fTk9UVkFMSURfTkNOQU1FID0KLSAgICAgICAgICJXR19QUk9DRVNTSU5HSU5TVFJVQ1RJT05fTk9UVkFMSURfTkNOQU1FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfSUxMRUdBTF9BVFRSSUJVVEVfUE9TSVRJT04gPQotICAgICAgICAgIldHX0lMTEVHQUxfQVRUUklCVVRFX1BPU0lUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSID0KLSAgICAgICAgICJOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIiOwotCi0gIC8qCi0gICAqIE5vdyBmaWxsIGluIHRoZSBtZXNzYWdlIHRleHQuCi0gICAqIFRoZW4gZmlsbCBpbiB0aGUgbWVzc2FnZSB0ZXh0IGZvciB0aGF0IG1lc3NhZ2UgY29kZSBpbiB0aGUKLSAgICogYXJyYXkuIFVzZSB0aGUgbmV3IGVycm9yIGNvZGUgYXMgdGhlIGluZGV4IGludG8gdGhlIGFycmF5LgotICAgKi8KLQotICAvLyBFcnJvciBtZXNzYWdlcy4uLgotCi0gIC8qKiBHZXQgdGhlIGxvb2t1cCB0YWJsZSBmb3IgZXJyb3IgbWVzc2FnZXMuCi0gICAgKgotICAgICogQHJldHVybiBUaGUgbWVzc2FnZSBsb29rdXAgdGFibGUuCi0gICAgKi8KLSAgcHVibGljIE9iamVjdFtdW10gZ2V0Q29udGVudHMoKQotICB7Ci0gICAgICByZXR1cm4gbmV3IE9iamVjdFtdW10gewotCi0gIC8qKiBFcnJvciBtZXNzYWdlIElEIHRoYXQgaGFzIGEgbnVsbCBtZXNzYWdlLCBidXQgdGFrZXMgaW4gYSBzaW5nbGUgb2JqZWN0LiAgICAqLwotICB7IkVSMDAwMCIgLCAiezB9IiB9LAotCi0gICAgeyBFUl9OT19DVVJMWUJSQUNFLAotICAgICAgIlx1MzBBOFx1MzBFOVx1MzBGQzogXHU1RjBGXHU1MTg1XHUzMDZCJ3snXHUzMDkyXHU2MzAxXHUzMDY0XHUzMDUzXHUzMDY4XHUzMDZGXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzIn0sCi0KLSAgICB7IEVSX0lMTEVHQUxfQVRUUklCVVRFICwKLSAgICAgInswfVx1MzA2Qlx1NEUwRFx1NkI2M1x1MzA2QVx1NUM1RVx1NjAyN1x1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OTogezF9In0sCi0KLSAge0VSX05VTExfU09VUkNFTk9ERV9BUFBMWUlNUE9SVFMgLAotICAgICAgInNvdXJjZU5vZGVcdTMwNkZ4c2w6YXBwbHktaW1wb3J0c1x1NTE4NVx1MzA2N251bGxcdTMwNjdcdTMwNTlcdTMwMDIifSwKLQotICB7RVJfQ0FOTk9UX0FERCwKLSAgICAgICJ7MH1cdTMwOTJ7MX1cdTMwNkJcdThGRkRcdTUyQTBcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTMifSwKLQotICAgIHsgRVJfTlVMTF9TT1VSQ0VOT0RFX0hBTkRMRUFQUExZVEVNUExBVEVTLAotICAgICAgInNvdXJjZU5vZGVcdTMwNkZoYW5kbGVBcHBseVRlbXBsYXRlc0luc3RydWN0aW9uXHU1MTg1XHUzMDY3bnVsbFx1MzA2N1x1MzA1OVx1MzAwMiJ9LAotCi0gICAgeyBFUl9OT19OQU1FX0FUVFJJQiwKLSAgICAgInswfVx1MzA2Qlx1MzA2Rm5hbWVcdTVDNUVcdTYwMjdcdTMwNENcdTVGQzVcdTg5ODFcdTMwNjdcdTMwNTlcdTMwMDIifSwKLQotICAgIHtFUl9URU1QTEFURV9OT1RfRk9VTkQsCi0gICAgICJcdTU0MERcdTUyNER7MH1cdTMwNkVcdTMwQzZcdTMwRjNcdTMwRDdcdTMwRUNcdTMwRkNcdTMwQzhcdTMwNENcdTg5OEJcdTMwNjRcdTMwNEJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwNjdcdTMwNTdcdTMwNUYifSwKLQotICAgIHtFUl9DQU5UX1JFU09MVkVfTkFNRV9BVlQsCi0gICAgICAieHNsOmNhbGwtdGVtcGxhdGVcdTMwNkVcdTU0MERcdTUyNERBVlRcdTMwOTJcdTg5RTNcdTZDN0FcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwNjdcdTMwNTdcdTMwNUZcdTMwMDIifSwKLQotICAgIHtFUl9SRVFVSVJFU19BVFRSSUIsCi0gICAgICJ7MH1cdTMwNkZcdTVDNUVcdTYwMjd7MX1cdTMwNENcdTVGQzVcdTg5ODFcdTMwNjdcdTMwNTkifSwKLQotICAgIHsgRVJfTVVTVF9IQVZFX1RFU1RfQVRUUklCLAotICAgICAgInswfVx1MzA2RicndGVzdCcnXHU1QzVFXHU2MDI3XHUzMDkyXHU2MzAxXHUzMDY0XHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyIn0sCi0KLSAgICB7RVJfQkFEX1ZBTF9PTl9MRVZFTF9BVFRSSUIsCi0gICAgICAibGV2ZWxcdTVDNUVcdTYwMjdcdTMwNkVcdTUwMjRcdTMwNENcdTRFMERcdTZCNjNcdTMwNjdcdTMwNTk6IHswfSJ9LAotCi0gICAge0VSX1BST0NFU1NJTkdJTlNUUlVDVElPTl9OQU1FX0NBTlRfQkVfWE1MLAotICAgICAgInByb2Nlc3NpbmctaW5zdHJ1Y3Rpb25cdTU0MERcdTMwNkYneG1sJ1x1MzA2Qlx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MyJ9LAotCi0gICAgeyBFUl9QUk9DRVNTSU5HSU5TVFJVQ1RJT05fTk9UVkFMSURfTkNOQU1FLAotICAgICAgInByb2Nlc3NpbmctaW5zdHJ1Y3Rpb25cdTU0MERcdTMwNkZcdTY3MDlcdTUyQjlcdTMwNkFOQ05hbWVcdTMwNjdcdTMwNDJcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTk6IHswfSJ9LAotCi0gICAgeyBFUl9ORUVEX01BVENIX0FUVFJJQiwKLSAgICAgICJcdTMwRTJcdTMwRkNcdTMwQzlcdTMwNENcdTMwNDJcdTMwOEJcdTU4MzRcdTU0MDhcdTMwMDF7MH1cdTMwNkJcdTMwNkZtYXRjaFx1NUM1RVx1NjAyN1x1MzA0Q1x1NUZDNVx1ODk4MVx1MzA2N1x1MzA1OVx1MzAwMiJ9LAotCi0gICAgeyBFUl9ORUVEX05BTUVfT1JfTUFUQ0hfQVRUUklCLAotICAgICAgInswfVx1MzA2Qlx1MzA2Rm5hbWVcdTMwN0VcdTMwNUZcdTMwNkZtYXRjaFx1NUM1RVx1NjAyN1x1MzA0Q1x1NUZDNVx1ODk4MVx1MzA2N1x1MzA1OVx1MzAwMiJ9LAotCi0gICAge0VSX0NBTlRfUkVTT0xWRV9OU1BSRUZJWCwKLSAgICAgICJcdTMwQ0RcdTMwRkNcdTMwRTBcdTMwQjlcdTMwREFcdTMwRkNcdTMwQjlcdTMwNkVcdTYzQTVcdTk4MkRcdThGOUVcdTMwOTJcdTg5RTNcdTZDN0FcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTM6IHswfSJ9LAotCi0gICAgeyBFUl9JTExFR0FMX1ZBTFVFLAotICAgICAieG1sOnNwYWNlXHUzMDZFXHU1MDI0XHUzMDRDXHU0RTBEXHU2QjYzXHUzMDY3XHUzMDU5OiB7MH0ifSwKLQotICAgIHsgRVJfTk9fT1dORVJET0MsCi0gICAgICAiXHU1QjUwXHUzMENFXHUzMEZDXHUzMEM5XHUzMDZCXHU2MjQwXHU2NzA5XHU4MDA1XHUzMEM5XHUzMEFEXHUzMEU1XHUzMEUxXHUzMEYzXHUzMEM4XHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyIn0sCi0KLSAgICB7IEVSX0VMRU1URU1QTEFURUVMRU1fRVJSLAotICAgICAiRWxlbVRlbXBsYXRlRWxlbWVudFx1MzBBOFx1MzBFOVx1MzBGQzogezB9In0sCi0KLSAgICB7IEVSX05VTExfQ0hJTEQsCi0gICAgICJudWxsXHUzMDZFXHU1QjUwXHUzMDkyXHU4RkZEXHU1MkEwXHUzMDU3XHUzMDg4XHUzMDQ2XHUzMDY4XHUzMDU3XHUzMDdFXHUzMDU3XHUzMDVGXHUzMDAyIn0sCi0KLSAgICB7IEVSX05FRURfU0VMRUNUX0FUVFJJQiwKLSAgICAgInswfVx1MzA2Qlx1MzA2RnNlbGVjdFx1NUM1RVx1NjAyN1x1MzA0Q1x1NUZDNVx1ODk4MVx1MzA2N1x1MzA1OVx1MzAwMiJ9LAotCi0gICAgeyBFUl9ORUVEX1RFU1RfQVRUUklCICwKLSAgICAgICJ4c2w6d2hlblx1MzA2Qlx1MzA2Rid0ZXN0J1x1NUM1RVx1NjAyN1x1MzA0Q1x1NUZDNVx1ODk4MVx1MzA2N1x1MzA1OVx1MzAwMiJ9LAotCi0gICAgeyBFUl9ORUVEX05BTUVfQVRUUklCLAotICAgICAgInhzbDp3aXRoLXBhcmFtXHUzMDZCXHUzMDZGJ25hbWUnXHU1QzVFXHU2MDI3XHUzMDRDXHU1RkM1XHU4OTgxXHUzMDY3XHUzMDU5XHUzMDAyIn0sCi0KLSAgICB7IEVSX05PX0NPTlRFWFRfT1dORVJET0MsCi0gICAgICAiXHUzMEIzXHUzMEYzXHUzMEM2XHUzMEFEXHUzMEI5XHUzMEM4XHUzMDZCXHU2MjQwXHU2NzA5XHU4MDA1XHUzMEM5XHUzMEFEXHUzMEU1XHUzMEUxXHUzMEYzXHUzMEM4XHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyIn0sCi0KLSAgICB7RVJfQ09VTERfTk9UX0NSRUFURV9YTUxfUFJPQ19MSUFJU09OLAotICAgICAgIlhNTCBUcmFuc2Zvcm1lckZhY3RvcnkgTGlhaXNvblx1MzA5Mlx1NEY1Q1x1NjIxMFx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzA2N1x1MzA1N1x1MzA1RjogezB9In0sCi0KLSAgICB7RVJfUFJPQ0VTU19OT1RfU1VDQ0VTU0ZVTCwKLSAgICAgICJYYWxhbjogXHUzMEQ3XHUzMEVEXHUzMEJCXHUzMEI5XHUzMDZGXHU2MjEwXHU1MjlGXHUzMDU3XHUzMDdFXHUzMDVCXHUzMDkzXHUzMDY3XHUzMDU3XHUzMDVGXHUzMDAyIn0sCi0KLSAgICB7IEVSX05PVF9TVUNDRVNTRlVMLAotICAgICAiWGFsYW46IFx1MzA2Rlx1NjIxMFx1NTI5Rlx1MzA1N1x1MzA3RVx1MzA1Qlx1MzA5M1x1MzA2N1x1MzA1N1x1MzA1Rlx1MzAwMiJ9LAotCi0gICAgeyBFUl9FTkNPRElOR19OT1RfU1VQUE9SVEVELAotICAgICAiXHUzMEE4XHUzMEYzXHUzMEIzXHUzMEZDXHUzMEM3XHUzMEEzXHUzMEYzXHUzMEIwezB9XHUzMDZGXHUzMEI1XHUzMEREXHUzMEZDXHUzMEM4XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzIn0sCi0KLSAgICB7RVJfQ09VTERfTk9UX0NSRUFURV9UUkFDRUxJU1RFTkVSLAotICAgICAgIlRyYWNlTGlzdGVuZXJcdTMwOTJcdTRGNUNcdTYyMTBcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwNjdcdTMwNTdcdTMwNUY6IHswfSJ9LAotCi0gICAge0VSX0tFWV9SRVFVSVJFU19OQU1FX0FUVFJJQiwKLSAgICAgICJ4c2w6a2V5XHUzMDZCXHUzMDZGJ25hbWUnXHU1QzVFXHU2MDI3XHUzMDRDXHU1RkM1XHU4OTgxXHUzMDY3XHUzMDU5XHUzMDAyIn0sCi0KLSAgICB7IEVSX0tFWV9SRVFVSVJFU19NQVRDSF9BVFRSSUIsCi0gICAgICAieHNsOmtleVx1MzA2Qlx1MzA2RidtYXRjaCdcdTVDNUVcdTYwMjdcdTMwNENcdTVGQzVcdTg5ODFcdTMwNjdcdTMwNTlcdTMwMDIifSwKLQotICAgIHsgRVJfS0VZX1JFUVVJUkVTX1VTRV9BVFRSSUIsCi0gICAgICAieHNsOmtleVx1MzA2Qlx1MzA2Rid1c2UnXHU1QzVFXHU2MDI3XHUzMDRDXHU1RkM1XHU4OTgxXHUzMDY3XHUzMDU5XHUzMDAyIn0sCi0KLSAgICB7IEVSX1JFUVVJUkVTX0VMRU1FTlRTX0FUVFJJQiwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIHswfVx1MzA2Qlx1MzA2RicnZWxlbWVudHMnJ1x1NUM1RVx1NjAyN1x1MzA0Q1x1NUZDNVx1ODk4MVx1MzA2N1x1MzA1OVx1MzAwMiJ9LAotCi0gICAgeyBFUl9NSVNTSU5HX1BSRUZJWF9BVFRSSUIsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSB7MH1cdTVDNUVcdTYwMjcnJ3ByZWZpeCcnXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzIn0sCi0KLSAgICB7IEVSX0JBRF9TVFlMRVNIRUVUX1VSTCwKLSAgICAgIlx1MzBCOVx1MzBCRlx1MzBBNFx1MzBFQlx1MzBCN1x1MzBGQ1x1MzBDOFVSTFx1MzA0Q1x1NEUwRFx1NkI2M1x1MzA2N1x1MzA1OTogezB9In0sCi0KLSAgICB7IEVSX0ZJTEVfTk9UX0ZPVU5ELAotICAgICAiXHUzMEI5XHUzMEJGXHUzMEE0XHUzMEVCXHUzMEI3XHUzMEZDXHUzMEM4XHUzMEZCXHUzMEQ1XHUzMEExXHUzMEE0XHUzMEVCXHUzMDRDXHU4OThCXHUzMDY0XHUzMDRCXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDY3XHUzMDU3XHUzMDVGOiB7MH0ifSwKLQotICAgIHsgRVJfSU9FWENFUFRJT04sCi0gICAgICAiXHUzMEI5XHUzMEJGXHUzMEE0XHUzMEVCXHUzMEI3XHUzMEZDXHUzMEM4XHUzMEZCXHUzMEQ1XHUzMEExXHUzMEE0XHUzMEVCXHUzMDZCXHU1MTY1XHU1MUZBXHU1MjlCXHU0RjhCXHU1OTE2XHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5OiB7MH0ifSwKLQotICAgIHsgRVJfTk9fSFJFRl9BVFRSSUIsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSB7MH1cdTMwNkVocmVmXHU1QzVFXHU2MDI3XHUzMDRDXHU4OThCXHUzMDY0XHUzMDRCXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDY3XHUzMDU3XHUzMDVGIn0sCi0KLSAgICB7IEVSX1NUWUxFU0hFRVRfSU5DTFVERVNfSVRTRUxGLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgezB9XHUzMDZGXHUzMDVEXHUzMDhDXHU4MUVBXHU0RjUzXHUzMDkyXHU3NkY0XHU2M0E1XHU3Njg0XHUzMDdFXHUzMDVGXHUzMDZGXHU5NTkzXHU2M0E1XHU3Njg0XHUzMDZCXHU1NDJCXHUzMDkzXHUzMDY3XHUzMDQ0XHUzMDdFXHUzMDU5XHUzMDAyIn0sCi0KLSAgICB7IEVSX1BST0NFU1NJTkNMVURFX0VSUk9SLAotICAgICAgIlN0eWxlc2hlZXRIYW5kbGVyLnByb2Nlc3NJbmNsdWRlXHUzMEE4XHUzMEU5XHUzMEZDXHUzMDAxezB9In0sCi0KLSAgICB7IEVSX01JU1NJTkdfTEFOR19BVFRSSUIsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSB7MH1cdTVDNUVcdTYwMjcnJ2xhbmcnJ1x1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5MyJ9LAotCi0gICAgeyBFUl9NSVNTSU5HX0NPTlRBSU5FUl9FTEVNRU5UX0NPTVBPTkVOVCwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIHswfVx1ODk4MVx1N0QyMFx1MzA2RVx1OTE0RFx1N0Y2RVx1MzA0Q1x1NEUwRFx1NkI2M1x1MzA2N1x1MzA1OVx1MzAwMlx1MzBCM1x1MzBGM1x1MzBDNlx1MzBDQVx1ODk4MVx1N0QyMCcnY29tcG9uZW50JydcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTMifSwKLQotICAgIHsgRVJfQ0FOX09OTFlfT1VUUFVUX1RPX0VMRU1FTlQsCi0gICAgICAiRWxlbWVudFx1MzAwMURvY3VtZW50RnJhZ21lbnRcdTMwMDFEb2N1bWVudFx1MzA3RVx1MzA1Rlx1MzA2RlByaW50V3JpdGVyXHUzMDZCXHUzMDZFXHUzMDdGXHU1MUZBXHU1MjlCXHUzMDY3XHUzMDREXHUzMDdFXHUzMDU5XHUzMDAyIn0sCi0KLSAgICB7IEVSX1BST0NFU1NfRVJST1IsCi0gICAgICJTdHlsZXNoZWV0Um9vdC5wcm9jZXNzXHUzMEE4XHUzMEU5XHUzMEZDIn0sCi0KLSAgICB7IEVSX1VOSU1QTE5PREVfRVJST1IsCi0gICAgICJVbkltcGxOb2RlXHUzMEE4XHUzMEU5XHUzMEZDOiB7MH0ifSwKLQotICAgIHsgRVJfTk9fU0VMRUNUX0VYUFJFU1NJT04sCi0gICAgICAiXHUzMEE4XHUzMEU5XHUzMEZDXHUzMDAyeHBhdGhcdTkwNzhcdTYyOUVcdTVGMEYoLXNlbGVjdClcdTMwNENcdTg5OEJcdTMwNjRcdTMwNEJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwNjdcdTMwNTdcdTMwNUZcdTMwMDIifSwKLQotICAgIHsgRVJfQ0FOTk9UX1NFUklBTElaRV9YU0xQUk9DRVNTT1IsCi0gICAgICAiWFNMUHJvY2Vzc29yXHUzMDkyXHUzMEI3XHUzMEVBXHUzMEEyXHUzMEU5XHUzMEE0XHUzMEJBXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyIn0sCi0KLSAgICB7IEVSX05PX0lOUFVUX1NUWUxFU0hFRVQsCi0gICAgICAiXHUzMEI5XHUzMEJGXHUzMEE0XHUzMEVCXHUzMEI3XHUzMEZDXHUzMEM4XHU1MTY1XHU1MjlCXHUzMDRDXHU2MzA3XHU1QjlBXHUzMDU1XHUzMDhDXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDY3XHUzMDU3XHUzMDVGXHUzMDAyIn0sCi0KLSAgICB7IEVSX0ZBSUxFRF9QUk9DRVNTX1NUWUxFU0hFRVQsCi0gICAgICAiXHUzMEI5XHUzMEJGXHUzMEE0XHUzMEVCXHUzMEI3XHUzMEZDXHUzMEM4XHUzMDZFXHU1MUU2XHU3NDA2XHUzMDZCXHU1OTMxXHU2NTU3XHUzMDU3XHUzMDdFXHUzMDU3XHUzMDVGXHUzMDAyIn0sCi0KLSAgICB7IEVSX0NPVUxETlRfUEFSU0VfRE9DLAotICAgICAiezB9XHUzMEM5XHUzMEFEXHUzMEU1XHUzMEUxXHUzMEYzXHUzMEM4XHUzMDkyXHU4OUUzXHU2NzkwXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDY3XHUzMDU3XHUzMDVGXHUzMDAyIn0sCi0KLSAgICB7IEVSX0NPVUxETlRfRklORF9GUkFHTUVOVCwKLSAgICAgIlx1MzBENVx1MzBFOVx1MzBCMFx1MzBFMVx1MzBGM1x1MzBDOFx1MzA0Q1x1ODk4Qlx1MzA2NFx1MzA0Qlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5M1x1MzA2N1x1MzA1N1x1MzA1RjogezB9In0sCi0KLSAgICB7IEVSX05PREVfTk9UX0VMRU1FTlQsCi0gICAgICAiXHUzMEQ1XHUzMEU5XHUzMEIwXHUzMEUxXHUzMEYzXHUzMEM4XHU4QjU4XHU1MjI1XHU1QjUwXHUzMDZCXHUzMDg4XHUzMDYzXHUzMDY2XHU2MzA3XHU3OTNBXHUzMDU1XHUzMDhDXHUzMDVGXHUzMENFXHUzMEZDXHUzMEM5XHUzMDZGXHU4OTgxXHU3RDIwXHUzMDY3XHUzMDZGXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDY3XHUzMDU3XHUzMDVGOiB7MH0ifSwKLQotICAgIHsgRVJfRk9SRUFDSF9ORUVEX01BVENIX09SX05BTUVfQVRUUklCLAotICAgICAgImZvci1lYWNoXHUzMDZGbWF0Y2hcdTMwN0VcdTMwNUZcdTMwNkZuYW1lXHU1QzVFXHU2MDI3XHUzMDkyXHU2MzAxXHUzMDY0XHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5In0sCi0KLSAgICB7IEVSX1RFTVBMQVRFU19ORUVEX01BVENIX09SX05BTUVfQVRUUklCLAotICAgICAgIlx1MzBDNlx1MzBGM1x1MzBEN1x1MzBFQ1x1MzBGQ1x1MzBDOFx1MzA2Rm1hdGNoXHUzMDdFXHUzMDVGXHUzMDZGbmFtZVx1NUM1RVx1NjAyN1x1MzA5Mlx1NjMwMVx1MzA2NFx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OSJ9LAotCi0gICAgeyBFUl9OT19DTE9ORV9PRl9ET0NVTUVOVF9GUkFHLAotICAgICAgIlx1MzBDOVx1MzBBRFx1MzBFNVx1MzBFMVx1MzBGM1x1MzBDOFx1MzBGQlx1MzBENVx1MzBFOVx1MzBCMFx1MzBFMVx1MzBGM1x1MzBDOFx1MzA2RVx1MzBBRlx1MzBFRFx1MzBGQ1x1MzBGM1x1MzA5Mlx1NEY1Q1x1NjIxMFx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMiJ9LAotCi0gICAgeyBFUl9DQU5UX0NSRUFURV9JVEVNLAotICAgICAgIlx1N0Q1MFx1Njc5Q1x1MzBDNFx1MzBFQVx1MzBGQ1x1MzA2Qlx1OTgwNVx1NzZFRVx1MzA5Mlx1NEY1Q1x1NjIxMFx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MzogezB9In0sCi0KLSAgICB7IEVSX1hNTFNQQUNFX0lMTEVHQUxfVkFMVUUsCi0gICAgICAiXHUzMEJEXHUzMEZDXHUzMEI5WE1MXHUzMDZFeG1sOnNwYWNlXHUzMDZFXHU1MDI0XHUzMDRDXHU0RTBEXHU2QjYzXHUzMDY3XHUzMDU5OiB7MH0ifSwKLQotICAgIHsgRVJfTk9fWFNMS0VZX0RFQ0xBUkFUSU9OLAotICAgICAgInswfVx1MzA2RXhzbDprZXlcdTVCQTNcdThBMDBcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIifSwKLQotICAgIHsgRVJfQ0FOVF9DUkVBVEVfVVJMLAotICAgICAiXHUzMEE4XHUzMEU5XHUzMEZDXHUzMDAyezB9XHUzMDZFVVJMXHUzMDkyXHU0RjVDXHU2MjEwXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzIn0sCi0KLSAgICB7IEVSX1hTTEZVTkNUSU9OU19VTlNVUFBPUlRFRCwKLSAgICAgInhzbDpmdW5jdGlvbnNcdTMwNkZcdTMwQjVcdTMwRERcdTMwRkNcdTMwQzhcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTMifSwKLQotICAgIHsgRVJfUFJPQ0VTU09SX0VSUk9SLAotICAgICAiWFNMVCBUcmFuc2Zvcm1lckZhY3RvcnlcdTMwQThcdTMwRTlcdTMwRkMifSwKLQotICAgIHsgRVJfTk9UX0FMTE9XRURfSU5TSURFX1NUWUxFU0hFRVQsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSB7MH1cdTMwNkZcdTMwQjlcdTMwQkZcdTMwQTRcdTMwRUJcdTMwQjdcdTMwRkNcdTMwQzhcdTUxODVcdTMwNjdcdThBMzFcdTUzRUZcdTMwNTVcdTMwOENcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIifSwKLQotICAgIHsgRVJfUkVTVUxUTlNfTk9UX1NVUFBPUlRFRCwKLSAgICAgICJyZXN1bHQtbnNcdTMwNkZcdTczRkVcdTU3MjhcdTMwNkZcdTMwQjVcdTMwRERcdTMwRkNcdTMwQzhcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDJcdTMwNEJcdTMwOEZcdTMwOEFcdTMwNkJ4c2w6b3V0cHV0XHUzMDkyXHU0RjdGXHU3NTI4XHUzMDU3XHUzMDY2XHUzMDRGXHUzMDYwXHUzMDU1XHUzMDQ0XHUzMDAyIn0sCi0KLSAgICB7IEVSX0RFRkFVTFRTUEFDRV9OT1RfU1VQUE9SVEVELAotICAgICAgImRlZmF1bHQtc3BhY2VcdTMwNkZcdTczRkVcdTU3MjhcdTMwNkZcdTMwQjVcdTMwRERcdTMwRkNcdTMwQzhcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDJcdTMwNEJcdTMwOEZcdTMwOEFcdTMwNkJ4c2w6c3RyaXAtc3BhY2VcdTMwN0VcdTMwNUZcdTMwNkZ4c2w6cHJlc2VydmUtc3BhY2VcdTMwOTJcdTRGN0ZcdTc1MjhcdTMwNTdcdTMwNjZcdTMwNEZcdTMwNjBcdTMwNTVcdTMwNDRcdTMwMDIifSwKLQotICAgIHsgRVJfSU5ERU5UUkVTVUxUX05PVF9TVVBQT1JURUQsCi0gICAgICAiaW5kZW50LXJlc3VsdFx1MzA2Rlx1NzNGRVx1NTcyOFx1MzA2Rlx1MzBCNVx1MzBERFx1MzBGQ1x1MzBDOFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMlx1MzA0Qlx1MzA4Rlx1MzA4QVx1MzA2QnhzbDpvdXRwdXRcdTMwOTJcdTRGN0ZcdTc1MjhcdTMwNTdcdTMwNjZcdTMwNEZcdTMwNjBcdTMwNTVcdTMwNDRcdTMwMDIifSwKLQotICAgIHsgRVJfSUxMRUdBTF9BVFRSSUIsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSB7MH1cdTMwNkJcdTMwNkZcdTRFMERcdTZCNjNcdTMwNkFcdTVDNUVcdTYwMjdcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTk6IHsxfSJ9LAotCi0gICAgeyBFUl9VTktOT1dOX1hTTF9FTEVNLAotICAgICAiXHU0RTBEXHU2NjBFXHUzMDZBWFNMXHU4OTgxXHU3RDIwOiB7MH0ifSwKLQotICAgIHsgRVJfQkFEX1hTTFNPUlRfVVNFLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgeHNsOnNvcnRcdTMwNkZcdTMwMDF4c2w6YXBwbHktdGVtcGxhdGVzXHUzMDdFXHUzMDVGXHUzMDZGeHNsOmZvci1lYWNoXHUzMDY4XHUzMDY4XHUzMDgyXHUzMDZCXHUzMDZFXHUzMDdGXHU0RjdGXHU3NTI4XHUzMDY3XHUzMDREXHUzMDdFXHUzMDU5XHUzMDAyIn0sCi0KLSAgICB7IEVSX01JU1BMQUNFRF9YU0xXSEVOLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgeHNsOndoZW5cdTMwNkVcdTkxNERcdTdGNkVcdTMwNENcdTRFMERcdTZCNjNcdTMwNjdcdTMwNTlcdTMwMDIifSwKLQotICAgIHsgRVJfWFNMV0hFTl9OT1RfUEFSRU5URURfQllfWFNMQ0hPT1NFLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgeHNsOndoZW5cdTMwNkVcdTg5QUFcdTMwNEN4c2w6Y2hvb3NlXHUzMDY3XHUzMDZGXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyIn0sCi0KLSAgICB7IEVSX01JU1BMQUNFRF9YU0xPVEhFUldJU0UsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSB4c2w6b3RoZXJ3aXNlXHUzMDZFXHU5MTREXHU3RjZFXHUzMDRDXHU0RTBEXHU2QjYzXHUzMDY3XHUzMDU5XHUzMDAyIn0sCi0KLSAgICB7IEVSX1hTTE9USEVSV0lTRV9OT1RfUEFSRU5URURfQllfWFNMQ0hPT1NFLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgeHNsOm90aGVyd2lzZVx1MzA2RVx1ODlBQVx1MzA0Q3hzbDpjaG9vc2VcdTMwNjdcdTMwNkZcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIifSwKLQotICAgIHsgRVJfTk9UX0FMTE9XRURfSU5TSURFX1RFTVBMQVRFLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgezB9XHUzMDZGXHUzMEM2XHUzMEYzXHUzMEQ3XHUzMEVDXHUzMEZDXHUzMEM4XHU1MTg1XHUzMDY3XHU4QTMxXHU1M0VGXHUzMDU1XHUzMDhDXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyIn0sCi0KLSAgICB7IEVSX1VOS05PV05fRVhUX05TX1BSRUZJWCwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIFx1NEUwRFx1NjYwRVx1MzA2QXswfVx1NjJFMVx1NUYzNVx1MzBDRFx1MzBGQ1x1MzBFMFx1MzBCOVx1MzBEQVx1MzBGQ1x1MzBCOVx1MzA2RVx1NjNBNVx1OTgyRFx1OEY5RXsxfVx1MzA2N1x1MzA1OSJ9LAotCi0gICAgeyBFUl9JTVBPUlRTX0FTX0ZJUlNUX0VMRU0sCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSBcdTMwQTRcdTMwRjNcdTMwRERcdTMwRkNcdTMwQzhcdTMwNkZcdTMwQjlcdTMwQkZcdTMwQTRcdTMwRUJcdTMwQjdcdTMwRkNcdTMwQzhcdTMwNkVcdTY3MDBcdTUyMURcdTMwNkVcdTg5ODFcdTdEMjBcdTMwNjhcdTMwNTdcdTMwNjZcdTMwNkVcdTMwN0ZcdTRGN0ZcdTc1MjhcdTMwNjdcdTMwNERcdTMwN0VcdTMwNTlcdTMwMDIifSwKLQotICAgIHsgRVJfSU1QT1JUSU5HX0lUU0VMRiwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIHswfVx1MzA2Rlx1MzA1RFx1MzA4Q1x1ODFFQVx1NEY1M1x1MzA5Mlx1NzZGNFx1NjNBNVx1MzA3RVx1MzA1Rlx1MzA2Rlx1OTU5M1x1NjNBNVx1NzY4NFx1MzA2Qlx1MzBBNFx1MzBGM1x1MzBERFx1MzBGQ1x1MzBDOFx1MzA1N1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OVx1MzAwMiJ9LAotCi0gICAgeyBFUl9YTUxTUEFDRV9JTExFR0FMX1ZBTCwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIHhtbDpzcGFjZVx1MzA2RVx1NTAyNFx1MzA0Q1x1NEUwRFx1NkI2M1x1MzA2N1x1MzA1OTogezB9In0sCi0KLSAgICB7IEVSX1BST0NFU1NTVFlMRVNIRUVUX05PVF9TVUNDRVNTRlVMLAotICAgICAgInByb2Nlc3NTdHlsZXNoZWV0XHUzMDZGXHU1OTMxXHU2NTU3XHUzMDU3XHUzMDdFXHUzMDU3XHUzMDVGXHUzMDAyIn0sCi0KLSAgICB7IEVSX1NBWF9FWENFUFRJT04sCi0gICAgICJTQVhcdTRGOEJcdTU5MTYifSwKLQotLy8gIGFkZCB0aGlzIG1lc3NhZ2UgdG8gZml4IGJ1ZyAyMTQ3OAotICAgIHsgRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCwKLSAgICAgIlx1OTVBMlx1NjU3MFx1MzA0Q1x1MzBCNVx1MzBERFx1MzBGQ1x1MzBDOFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMiJ9LAotCi0gICAgeyBFUl9YU0xUX0VSUk9SLAotICAgICAiWFNMVFx1MzBBOFx1MzBFOVx1MzBGQyJ9LAotCi0gICAgeyBFUl9DVVJSRU5DWV9TSUdOX0lMTEVHQUwsCi0gICAgICAiXHU5MDFBXHU4Q0E4XHU4QTE4XHU1M0Y3XHUzMDZGXHUzMEQ1XHUzMEE5XHUzMEZDXHUzMERFXHUzMEMzXHUzMEM4XHUzMEZCXHUzMEQxXHUzMEJGXHUzMEZDXHUzMEYzXHU2NTg3XHU1QjU3XHU1MjE3XHU1MTg1XHUzMDY3XHU4QTMxXHU1M0VGXHUzMDU1XHUzMDhDXHUzMDdFXHUzMDVCXHUzMDkzIn0sCi0KLSAgICB7IEVSX0RPQ1VNRU5UX0ZVTkNUSU9OX0lOVkFMSURfSU5fU1RZTEVTSEVFVF9ET00sCi0gICAgICAiXHUzMEM5XHUzMEFEXHUzMEU1XHUzMEUxXHUzMEYzXHUzMEM4XHU5NUEyXHU2NTcwXHUzMDZGXHUzMEI5XHUzMEJGXHUzMEE0XHUzMEVCXHUzMEI3XHUzMEZDXHUzMEM4RE9NXHUzMDY3XHUzMEI1XHUzMEREXHUzMEZDXHUzMEM4XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyIn0sCi0KLSAgICB7IEVSX0NBTlRfUkVTT0xWRV9QUkVGSVhfT0ZfTk9OX1BSRUZJWF9SRVNPTFZFUiwKLSAgICAgICJcdTk3NUVcdTYzQTVcdTk4MkRcdThGOUVcdTMwRUFcdTMwQkVcdTMwRUJcdTMwRDBcdTMwNkVcdTYzQTVcdTk4MkRcdThGOUVcdTMwOTJcdTg5RTNcdTZDN0FcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIifSwKLQotICAgIHsgRVJfUkVESVJFQ1RfQ09VTEROVF9HRVRfRklMRU5BTUUsCi0gICAgICAiXHUzMEVBXHUzMEMwXHUzMEE0XHUzMEVDXHUzMEFGXHUzMEM4XHU2MkUxXHU1RjM1OiBcdTMwRDVcdTMwQTFcdTMwQTRcdTMwRUJcdTU0MERcdTMwOTJcdTUzRDZcdTVGOTdcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwNjdcdTMwNTdcdTMwNUYgLSBmaWxlXHUzMDdFXHUzMDVGXHUzMDZGc2VsZWN0XHU1QzVFXHU2MDI3XHUzMDRDXHU2NzA5XHU1MkI5XHUzMDZBXHU2NTg3XHU1QjU3XHU1MjE3XHUzMDkyXHU4RkQ0XHUzMDU5XHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyIn0sCi0KLSAgICB7IEVSX0NBTk5PVF9CVUlMRF9GT1JNQVRURVJMSVNURU5FUl9JTl9SRURJUkVDVCwKLSAgICAgICJcdTMwRUFcdTMwQzBcdTMwQTRcdTMwRUNcdTMwQUZcdTMwQzhcdTYyRTFcdTVGMzVcdTMwNjdGb3JtYXR0ZXJMaXN0ZW5lclx1MzA5Mlx1NEY1Q1x1NjIxMFx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMiJ9LAotCi0gICAgeyBFUl9JTlZBTElEX1BSRUZJWF9JTl9FWENMVURFUkVTVUxUUFJFRklYLAotICAgICAgImV4Y2x1ZGUtcmVzdWx0LXByZWZpeGVzXHUzMDZFXHU2M0E1XHU5ODJEXHU4RjlFXHUzMDRDXHU3MTIxXHU1MkI5XHUzMDY3XHUzMDU5OiB7MH0ifSwKLQotICAgIHsgRVJfTUlTU0lOR19OU19VUkksCi0gICAgICAiXHU2MzA3XHU1QjlBXHUzMDU3XHUzMDVGXHU2M0E1XHU5ODJEXHU4RjlFXHUzMDZFXHUzMENEXHUzMEZDXHUzMEUwXHUzMEI5XHUzMERBXHUzMEZDXHUzMEI5VVJJXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzIn0sCi0KLSAgICB7IEVSX01JU1NJTkdfQVJHX0ZPUl9PUFRJT04sCi0gICAgICAiXHUzMEFBXHUzMEQ3XHUzMEI3XHUzMEU3XHUzMEYzezB9XHUzMDZFXHU1RjE1XHU2NTcwXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzIn0sCi0KLSAgICB7IEVSX0lOVkFMSURfT1BUSU9OLAotICAgICAiXHU3MTIxXHU1MkI5XHUzMDZBXHUzMEFBXHUzMEQ3XHUzMEI3XHUzMEU3XHUzMEYzOiB7MH0ifSwKLQotICAgIHsgRVJfTUFMRk9STUVEX0ZPUk1BVF9TVFJJTkcsCi0gICAgICJcdTRFMERcdTZCNjNcdTMwNkFcdTMwRDVcdTMwQTlcdTMwRkNcdTMwREVcdTMwQzNcdTMwQzhcdTMwNkVcdTY1ODdcdTVCNTdcdTUyMTdcdTMwNjdcdTMwNTk6IHswfSJ9LAotCi0gICAgeyBFUl9TVFlMRVNIRUVUX1JFUVVJUkVTX1ZFUlNJT05fQVRUUklCLAotICAgICAgInhzbDpzdHlsZXNoZWV0XHUzMDZGJ3ZlcnNpb24nXHU1QzVFXHU2MDI3XHUzMDRDXHU1RkM1XHU4OTgxXHUzMDY3XHUzMDU5XHUzMDAyIn0sCi0KLSAgICB7IEVSX0lMTEVHQUxfQVRUUklCVVRFX1ZBTFVFLAotICAgICAgIlx1NUM1RVx1NjAyN3swfVx1MzA2RVx1NTAyNFx1MzA0Q1x1NEUwRFx1NkI2M1x1MzA2N1x1MzA1OTogezF9In0sCi0KLSAgICB7IEVSX0NIT09TRV9SRVFVSVJFU19XSEVOLAotICAgICAieHNsOmNob29zZVx1MzA2RnhzbDp3aGVuXHUzMDRDXHU1RkM1XHU4OTgxXHUzMDY3XHUzMDU5In0sCi0KLSAgICB7IEVSX05PX0FQUExZX0lNUE9SVF9JTl9GT1JfRUFDSCwKLSAgICAgICJ4c2w6YXBwbHktaW1wb3J0c1x1MzA2RnhzbDpmb3ItZWFjaFx1NTE4NVx1MzA2N1x1OEEzMVx1NTNFRlx1MzA1NVx1MzA4Q1x1MzA3RVx1MzA1Qlx1MzA5MyJ9LAotCi0gICAgeyBFUl9DQU5UX1VTRV9EVE1fRk9SX09VVFBVVCwKLSAgICAgICJcdTUxRkFcdTUyOUJET01cdTMwQ0VcdTMwRkNcdTMwQzlcdTMwNkJEVE1MaWFpc29uXHUzMDkyXHU0RjdGXHU3NTI4XHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzLi4uXHUzMDRCXHUzMDhGXHUzMDhBXHUzMDZCY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLkRPTTJIZWxwZXJcdTMwOTJcdTZFMjFcdTMwNTdcdTMwNjZcdTMwNEZcdTMwNjBcdTMwNTVcdTMwNDRcdTMwMDIifSwKLQotICAgIHsgRVJfQ0FOVF9VU0VfRFRNX0ZPUl9JTlBVVCwKLSAgICAgICJcdTUxNjVcdTUyOUJET01cdTMwQ0VcdTMwRkNcdTMwQzlcdTMwNkJEVE1MaWFpc29uXHUzMDkyXHU0RjdGXHU3NTI4XHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzLi4uXHUzMDRCXHUzMDhGXHUzMDhBXHUzMDZCY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLkRPTTJIZWxwZXJcdTMwOTJcdTZFMjFcdTMwNTdcdTMwNjZcdTMwNEZcdTMwNjBcdTMwNTVcdTMwNDRcdTMwMDIifSwKLQotICAgIHsgRVJfQ0FMTF9UT19FWFRfRkFJTEVELAotICAgICAgIlx1NjJFMVx1NUYzNVx1ODk4MVx1N0QyMFx1MzA2RVx1NTQ3Q1x1NTFGQVx1MzA1N1x1MzA0Q1x1NTkzMVx1NjU1N1x1MzA1N1x1MzA3RVx1MzA1N1x1MzA1RjogezB9In0sCi0KLSAgICB7IEVSX1BSRUZJWF9NVVNUX1JFU09MVkUsCi0gICAgICAiXHU2M0E1XHU5ODJEXHU4RjlFXHUzMDZGXHUzMENEXHUzMEZDXHUzMEUwXHUzMEI5XHUzMERBXHUzMEZDXHUzMEI5XHUzMDZCXHU4OUUzXHU2QzdBXHUzMDU1XHUzMDhDXHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5OiB7MH0ifSwKLQotICAgIHsgRVJfSU5WQUxJRF9VVEYxNl9TVVJST0dBVEUsCi0gICAgICAiXHU3MTIxXHU1MkI5XHUzMDZBVVRGLTE2XHUzMEI1XHUzMEVEXHUzMEIyXHUzMEZDXHUzMEM4XHUzMDRDXHU2OTFDXHU1MUZBXHUzMDU1XHUzMDhDXHUzMDdFXHUzMDU3XHUzMDVGOiB7MH1cdTMwMDIifSwKLQotICAgIHsgRVJfWFNMQVRUUlNFVF9VU0VEX0lUU0VMRiwKLSAgICAgICJ4c2w6YXR0cmlidXRlLXNldCB7MH1cdTMwNENcdTMwNURcdTMwOENcdTgxRUFcdTRGNTNcdTMwOTJcdTRGN0ZcdTc1MjhcdTMwNTdcdTMwMDFcdTcxMjFcdTk2NTBcdTMwRUJcdTMwRkNcdTMwRDdcdTMwNENcdTc2N0FcdTc1MUZcdTMwNTdcdTMwN0VcdTMwNTlcdTMwMDIifSwKLQotICAgIHsgRVJfQ0FOTk9UX01JWF9YRVJDRVNET00sCi0gICAgICAiXHU5NzVFWGVyY2VzLURPTVx1NTE2NVx1NTI5Qlx1MzA2OFhlcmNlcy1ET01cdTUxRkFcdTUyOUJcdTMwOTJcdTU0MENcdTY2NDJcdTMwNkJcdTRGN0ZcdTc1MjhcdTMwNTlcdTMwOEJcdTMwNTNcdTMwNjhcdTMwNkZcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIifSwKLQotICAgIHsgRVJfVE9PX01BTllfTElTVEVORVJTLAotICAgICAgImFkZFRyYWNlTGlzdGVuZXJzVG9TdHlsZXNoZWV0IC0gVG9vTWFueUxpc3RlbmVyc0V4Y2VwdGlvbiJ9LAotCi0gICAgeyBFUl9JTl9FTEVNVEVNUExBVEVFTEVNX1JFQURPQkpFQ1QsCi0gICAgICAiRWxlbVRlbXBsYXRlRWxlbWVudC5yZWFkT2JqZWN0XHU1MTg1OiB7MH0ifSwKLQotICAgIHsgRVJfRFVQTElDQVRFX05BTUVEX1RFTVBMQVRFLAotICAgICAgIlx1NTQwRFx1NTI0RHswfVx1MzA2RVx1MzBDNlx1MzBGM1x1MzBEN1x1MzBFQ1x1MzBGQ1x1MzBDOFx1MzA0Q1x1ODkwN1x1NjU3MFx1ODk4Qlx1MzA2NFx1MzA0Qlx1MzA4QVx1MzA3RVx1MzA1N1x1MzA1RiJ9LAotCi0gICAgeyBFUl9JTlZBTElEX0tFWV9DQUxMLAotICAgICAgIlx1NzEyMVx1NTJCOVx1MzA2QVx1OTVBMlx1NjU3MFx1NTQ3Q1x1NTFGQVx1MzA1NzogXHU1MThEXHU1RTMwXHU3Njg0XHUzMDZBa2V5KClcdTMwNkVcdTU0N0NcdTUxRkFcdTMwNTdcdTMwNkZcdThBMzFcdTUzRUZcdTMwNTVcdTMwOENcdTMwN0VcdTMwNUJcdTMwOTMifSwKLQotICAgIHsgRVJfUkVGRVJFTkNJTkdfSVRTRUxGLAotICAgICAgIlx1NTkwOVx1NjU3MHswfVx1MzA2Rlx1MzA1RFx1MzA4Q1x1ODFFQVx1NEY1M1x1MzA5Mlx1NzZGNFx1NjNBNVx1MzA3RVx1MzA1Rlx1MzA2Rlx1OTU5M1x1NjNBNVx1NzY4NFx1MzA2Qlx1NTNDMlx1NzE2N1x1MzA1N1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OVx1MzAwMiJ9LAotCi0gICAgeyBFUl9JTExFR0FMX0RPTVNPVVJDRV9JTlBVVCwKLSAgICAgICJuZXdUZW1wbGF0ZXNcdTMwNkVET01Tb3VyY2VcdTMwNkJcdTMwNjRcdTMwNDRcdTMwNjZcdTUxNjVcdTUyOUJcdTMwQ0VcdTMwRkNcdTMwQzlcdTMwOTJudWxsXHUzMDZCXHUzMDU5XHUzMDhCXHUzMDUzXHUzMDY4XHUzMDZGXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyIn0sCi0KLSAgICB7IEVSX0NMQVNTX05PVF9GT1VORF9GT1JfT1BUSU9OLAotICAgICAgICAiXHUzMEFBXHUzMEQ3XHUzMEI3XHUzMEU3XHUzMEYzezB9XHUzMDZCXHUzMDY0XHUzMDQ0XHUzMDY2XHUzMEFGXHUzMEU5XHUzMEI5XHUzMEZCXHUzMEQ1XHUzMEExXHUzMEE0XHUzMEVCXHUzMDRDXHU4OThCXHUzMDY0XHUzMDRCXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzIn0sCi0KLSAgICB7IEVSX1JFUVVJUkVEX0VMRU1fTk9UX0ZPVU5ELAotICAgICAgICAiXHU1RkM1XHU5ODA4XHU4OTgxXHU3RDIwXHUzMDRDXHU4OThCXHUzMDY0XHUzMDRCXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzOiB7MH0ifSwKLQotICAgIHsgRVJfSU5QVVRfQ0FOTk9UX0JFX05VTEwsCi0gICAgICAgICJJbnB1dFN0cmVhbVx1MzA5Mm51bGxcdTMwNkJcdTMwNTlcdTMwOEJcdTMwNTNcdTMwNjhcdTMwNkZcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTMifSwKLQotICAgIHsgRVJfVVJJX0NBTk5PVF9CRV9OVUxMLAotICAgICAgICAiVVJJXHUzMDkybnVsbFx1MzA2Qlx1MzA1OVx1MzA4Qlx1MzA1M1x1MzA2OFx1MzA2Rlx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MyJ9LAotCi0gICAgeyBFUl9GSUxFX0NBTk5PVF9CRV9OVUxMLAotICAgICAgICAiXHUzMEQ1XHUzMEExXHUzMEE0XHUzMEVCXHUzMDkybnVsbFx1MzA2Qlx1MzA1OVx1MzA4Qlx1MzA1M1x1MzA2OFx1MzA2Rlx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MyJ9LAotCi0gICAgeyBFUl9TT1VSQ0VfQ0FOTk9UX0JFX05VTEwsCi0gICAgICAgICAgICAgICAgIklucHV0U291cmNlXHUzMDkybnVsbFx1MzA2Qlx1MzA1OVx1MzA4Qlx1MzA1M1x1MzA2OFx1MzA2Rlx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MyJ9LAotCi0gICAgeyBFUl9DQU5OT1RfSU5JVF9CU0ZNR1IsCi0gICAgICAgICAgICAgICAgIkJTRlx1MzBERVx1MzBDRFx1MzBGQ1x1MzBCOFx1MzBFM1x1MzA5Mlx1NTIxRFx1NjcxRlx1NTMxNlx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzA2N1x1MzA1N1x1MzA1RiJ9LAotCi0gICAgeyBFUl9DQU5OT1RfQ01QTF9FWFRFTlNOLAotICAgICAgICAgICAgICAgICJcdTYyRTFcdTVGMzVcdTMwOTJcdTMwQjNcdTMwRjNcdTMwRDFcdTMwQTRcdTMwRUJcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwNjdcdTMwNTdcdTMwNUYifSwKLQotICAgIHsgRVJfQ0FOTk9UX0NSRUFURV9FWFRFTlNOLAotICAgICAgInsxfVx1MzA0Q1x1NTM5Rlx1NTZFMFx1MzA2N1x1NjJFMVx1NUYzNXswfVx1MzA5Mlx1NEY1Q1x1NjIxMFx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzA2N1x1MzA1N1x1MzA1RiJ9LAotCi0gICAgeyBFUl9JTlNUQU5DRV9NVEhEX0NBTExfUkVRVUlSRVMsCi0gICAgICAiXHUzMEUxXHUzMEJEXHUzMEMzXHUzMEM5ezB9XHUzMDZFXHUzMEE0XHUzMEYzXHUzMEI5XHUzMEJGXHUzMEYzXHUzMEI5XHUzMEZCXHUzMEUxXHUzMEJEXHUzMEMzXHUzMEM5XHU1NDdDXHU1MUZBXHUzMDU3XHUzMDY3XHUzMDZGXHUzMDAxXHU2NzAwXHU1MjFEXHUzMDZFXHU1RjE1XHU2NTcwXHUzMDY4XHUzMDU3XHUzMDY2XHUzMEFBXHUzMEQ2XHUzMEI4XHUzMEE3XHUzMEFGXHUzMEM4XHUzMEZCXHUzMEE0XHUzMEYzXHUzMEI5XHUzMEJGXHUzMEYzXHUzMEI5XHUzMDRDXHU1RkM1XHU4OTgxXHUzMDY3XHUzMDU5In0sCi0KLSAgICB7IEVSX0lOVkFMSURfRUxFTUVOVF9OQU1FLAotICAgICAgIlx1NzEyMVx1NTJCOVx1MzA2QVx1ODk4MVx1N0QyMFx1NTQwRFx1MzA0Q1x1NjMwN1x1NUI5QVx1MzA1NVx1MzA4Q1x1MzA3RVx1MzA1N1x1MzA1RnswfSJ9LAotCi0gICAgeyBFUl9FTEVNRU5UX05BTUVfTUVUSE9EX1NUQVRJQywKLSAgICAgICJcdTg5ODFcdTdEMjBcdTU0MERcdTMwRTFcdTMwQkRcdTMwQzNcdTMwQzlcdTMwNkZzdGF0aWMgezB9XHUzMDY3XHUzMDQyXHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5In0sCi0KLSAgICB7IEVSX0VYVEVOU0lPTl9GVU5DX1VOS05PV04sCi0gICAgICAgICAgICAgIlx1NjJFMVx1NUYzNVx1OTVBMlx1NjU3MHswfSA6IHsxfVx1MzA0Q1x1NEUwRFx1NjYwRVx1MzA2N1x1MzA1OSJ9LAotCi0gICAgeyBFUl9NT1JFX01BVENIX0NPTlNUUlVDVE9SLAotICAgICAgICAgICAgICJ7MH1cdTMwNkVcdTMwQjNcdTMwRjNcdTMwQjlcdTMwQzhcdTMwRTlcdTMwQUZcdTMwQkZcdTMwNkJcdTg5MDdcdTY1NzBcdTMwNkVcdTY3MDBcdTkwNjlcdTRFMDBcdTgxRjRcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTkifSwKLQotICAgIHsgRVJfTU9SRV9NQVRDSF9NRVRIT0QsCi0gICAgICAgICAgICAgIlx1MzBFMVx1MzBCRFx1MzBDM1x1MzBDOXswfVx1MzA2Qlx1ODkwN1x1NjU3MFx1MzA2RVx1NjcwMFx1OTA2OVx1NEUwMFx1ODFGNFx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OSJ9LAotCi0gICAgeyBFUl9NT1JFX01BVENIX0VMRU1FTlQsCi0gICAgICAgICAgICAgIlx1ODk4MVx1N0QyMFx1MzBFMVx1MzBCRFx1MzBDM1x1MzBDOXswfVx1MzA2Qlx1ODkwN1x1NjU3MFx1MzA2RVx1NjcwMFx1OTA2OVx1NEUwMFx1ODFGNFx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OSJ9LAotCi0gICAgeyBFUl9JTlZBTElEX0NPTlRFWFRfUEFTU0VELAotICAgICAgICAgICAgICJ7MH1cdTMwOTJcdThBNTVcdTRGQTFcdTMwNTlcdTMwOEJcdTMwNUZcdTMwODFcdTMwNkJcdTcxMjFcdTUyQjlcdTMwNkFcdTMwQjNcdTMwRjNcdTMwQzZcdTMwQURcdTMwQjlcdTMwQzhcdTMwNENcdTZFMjFcdTMwNTVcdTMwOENcdTMwN0VcdTMwNTdcdTMwNUYifSwKLQotICAgIHsgRVJfUE9PTF9FWElTVFMsCi0gICAgICAgICAgICAgIlx1MzBEN1x1MzBGQ1x1MzBFQlx1MzA2Rlx1MzA1OVx1MzA2N1x1MzA2Qlx1NUI1OFx1NTcyOFx1MzA1N1x1MzA3RVx1MzA1OSJ9LAotCi0gICAgeyBFUl9OT19EUklWRVJfTkFNRSwKLSAgICAgICAgICAgICAiXHUzMEM5XHUzMEU5XHUzMEE0XHUzMEQwXHU1NDBEXHUzMDRDXHU2MzA3XHU1QjlBXHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzIn0sCi0KLSAgICB7IEVSX05PX1VSTCwKLSAgICAgICAgICAgICAiVVJMXHUzMDRDXHU2MzA3XHU1QjlBXHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzIn0sCi0KLSAgICB7IEVSX1BPT0xfU0laRV9MRVNTVEhBTl9PTkUsCi0gICAgICAgICAgICAgIlx1MzBEN1x1MzBGQ1x1MzBFQlx1MzBGQlx1MzBCNVx1MzBBNFx1MzBCQVx1MzA0QzFcdTMwODhcdTMwOEFcdTVDMEZcdTMwNTVcdTMwNDRcdTMwNjdcdTMwNTlcdTMwMDIifSwKLQotICAgIHsgRVJfSU5WQUxJRF9EUklWRVIsCi0gICAgICAgICAgICAgIlx1NzEyMVx1NTJCOVx1MzA2QVx1MzBDOVx1MzBFOVx1MzBBNFx1MzBEMFx1NTQwRFx1MzA0Q1x1NjMwN1x1NUI5QVx1MzA1NVx1MzA4Q1x1MzA3RVx1MzA1N1x1MzA1Rlx1MzAwMiJ9LAotCi0gICAgeyBFUl9OT19TVFlMRVNIRUVUUk9PVCwKLSAgICAgICAgICAgICAiXHUzMEI5XHUzMEJGXHUzMEE0XHUzMEVCXHUzMEI3XHUzMEZDXHUzMEM4XHUzMEZCXHUzMEVCXHUzMEZDXHUzMEM4XHUzMDRDXHU4OThCXHUzMDY0XHUzMDRCXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDY3XHUzMDU3XHUzMDVGXHUzMDAyIn0sCi0KLSAgICB7IEVSX0lMTEVHQUxfWE1MU1BBQ0VfVkFMVUUsCi0gICAgICAgICAieG1sOnNwYWNlXHUzMDZFXHU1MDI0XHUzMDRDXHU0RTBEXHU2QjYzXHUzMDY3XHUzMDU5In0sCi0KLSAgICB7IEVSX1BST0NFU1NGUk9NTk9ERV9GQUlMRUQsCi0gICAgICAgICAicHJvY2Vzc0Zyb21Ob2RlXHUzMDRDXHU1OTMxXHU2NTU3XHUzMDU3XHUzMDdFXHUzMDU3XHUzMDVGIn0sCi0KLSAgICB7IEVSX1JFU09VUkNFX0NPVUxEX05PVF9MT0FELAotICAgICAgICAiXHUzMEVBXHUzMEJEXHUzMEZDXHUzMEI5WyB7MH0gXVx1MzA5Mlx1MzBFRFx1MzBGQ1x1MzBDOVx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzA2N1x1MzA1N1x1MzA1RjogezF9IFxuIHsyfSBcdCB7M30ifSwKLQotICAgIHsgRVJfQlVGRkVSX1NJWkVfTEVTU1RIQU5fWkVSTywKLSAgICAgICAgIlx1MzBEMFx1MzBDM1x1MzBENVx1MzBBMVx1MzBGQlx1MzBCNVx1MzBBNFx1MzBCQTw9MCJ9LAotCi0gICAgeyBFUl9VTktOT1dOX0VSUk9SX0NBTExJTkdfRVhURU5TSU9OLAotICAgICAgICAiXHU2MkUxXHU1RjM1XHUzMDkyXHU1NDdDXHUzMDczXHU1MUZBXHUzMDU5XHUzMDY4XHUzMDREXHUzMDZCXHU0RTBEXHU2NjBFXHUzMDZBXHUzMEE4XHUzMEU5XHUzMEZDXHUzMDRDXHU3NjdBXHU3NTFGXHUzMDU3XHUzMDdFXHUzMDU3XHUzMDVGIn0sCi0KLSAgICB7IEVSX05PX05BTUVTUEFDRV9ERUNMLAotICAgICAgICAiXHU2M0E1XHU5ODJEXHU4RjlFezB9XHUzMDZCXHUzMDZGXHUzMDAxXHU1QkZFXHU1RkRDXHUzMDU5XHUzMDhCXHUzMENEXHUzMEZDXHUzMEUwXHUzMEI5XHUzMERBXHUzMEZDXHUzMEI5XHU1QkEzXHU4QTAwXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzIn0sCi0KLSAgICB7IEVSX0VMRU1fQ09OVEVOVF9OT1RfQUxMT1dFRCwKLSAgICAgICAgIlx1ODk4MVx1N0QyMFx1MzA2RVx1NTE4NVx1NUJCOVx1MzA2Rmxhbmc9amF2YWNsYXNzIHswfVx1MzA2Qlx1MzA2NFx1MzA0NFx1MzA2Nlx1OEEzMVx1NTNFRlx1MzA1NVx1MzA4Q1x1MzA3RVx1MzA1Qlx1MzA5MyJ9LAotCi0gICAgeyBFUl9TVFlMRVNIRUVUX0RJUkVDVEVEX1RFUk1JTkFUSU9OLAotICAgICAgICAiXHUzMEI5XHUzMEJGXHUzMEE0XHUzMEVCXHUzMEI3XHUzMEZDXHUzMEM4XHUzMDZCXHUzMDg4XHUzMDhBXHU3RDQyXHU0RTg2XHUzMDRDXHU2MzA3XHU3OTNBXHUzMDU1XHUzMDhDXHUzMDdFXHUzMDU3XHUzMDVGIn0sCi0KLSAgICB7IEVSX09ORV9PUl9UV08sCi0gICAgICAgICIxXHUzMDdFXHUzMDVGXHUzMDZGMiJ9LAotCi0gICAgeyBFUl9UV09fT1JfVEhSRUUsCi0gICAgICAgICIyXHUzMDdFXHUzMDVGXHUzMDZGMyJ9LAotCi0gICAgeyBFUl9DT1VMRF9OT1RfTE9BRF9SRVNPVVJDRSwKLSAgICAgICAgInswfVx1MzA5Mlx1MzBFRFx1MzBGQ1x1MzBDOVx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzA2N1x1MzA1N1x1MzA1RihDTEFTU1BBVEhcdTMwOTJcdTc4QkFcdThBOERcdTMwNTdcdTMwNjZcdTMwNEZcdTMwNjBcdTMwNTVcdTMwNDQpXHUzMDAyXHU3M0ZFXHU1NzI4XHUzMDZGXHU1MzU4XHUzMDZCXHUzMEM3XHUzMEQ1XHUzMEE5XHUzMEVCXHUzMEM4XHUzMDkyXHU0RjdGXHU3NTI4XHUzMDU3XHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5In0sCi0KLSAgICB7IEVSX0NBTk5PVF9JTklUX0RFRkFVTFRfVEVNUExBVEVTLAotICAgICAgICAiXHUzMEM3XHUzMEQ1XHUzMEE5XHUzMEVCXHUzMEM4XHUzMEZCXHUzMEM2XHUzMEYzXHUzMEQ3XHUzMEVDXHUzMEZDXHUzMEM4XHUzMDkyXHU1MjFEXHU2NzFGXHU1MzE2XHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzIn0sCi0KLSAgICB7IEVSX1JFU1VMVF9OVUxMLAotICAgICAgICAiXHU3RDUwXHU2NzlDXHUzMDZGbnVsbFx1MzA2Qlx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MyJ9LAotCi0gICAgeyBFUl9SRVNVTFRfQ09VTERfTk9UX0JFX1NFVCwKLSAgICAgICAgIlx1N0Q1MFx1Njc5Q1x1MzA5Mlx1OEEyRFx1NUI5QVx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzA2N1x1MzA1N1x1MzA1RiJ9LAotCi0gICAgeyBFUl9OT19PVVRQVVRfU1BFQ0lGSUVELAotICAgICAgICAiXHU1MUZBXHU1MjlCXHUzMDRDXHU2MzA3XHU1QjlBXHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzIn0sCi0KLSAgICB7IEVSX0NBTk5PVF9UUkFOU0ZPUk1fVE9fUkVTVUxUX1RZUEUsCi0gICAgICAgICJcdTMwQkZcdTMwQTRcdTMwRDd7MH1cdTMwNkVcdTdENTBcdTY3OUNcdTMwNkJcdTU5MDlcdTYzREJcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTMifSwKLQotICAgIHsgRVJfQ0FOTk9UX1RSQU5TRk9STV9TT1VSQ0VfVFlQRSwKLSAgICAgICAgIlx1MzBCRlx1MzBBNFx1MzBEN3swfVx1MzA2RVx1MzBCRFx1MzBGQ1x1MzBCOVx1MzA2Qlx1NTkwOVx1NjNEQlx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MyJ9LAotCi0gICAgeyBFUl9OVUxMX0NPTlRFTlRfSEFORExFUiwKLSAgICAgICAgIk51bGxcdTMwNkVcdTMwQjNcdTMwRjNcdTMwQzZcdTMwRjNcdTMwQzRcdTMwRkJcdTMwQ0ZcdTMwRjNcdTMwQzlcdTMwRTkifSwKLQotICAgIHsgRVJfTlVMTF9FUlJPUl9IQU5ETEVSLAotICAgICAgICAiTnVsbFx1MzA2RVx1MzBBOFx1MzBFOVx1MzBGQ1x1MzBGQlx1MzBDRlx1MzBGM1x1MzBDOVx1MzBFOSJ9LAotCi0gICAgeyBFUl9DQU5OT1RfQ0FMTF9QQVJTRSwKLSAgICAgICAgIkNvbnRlbnRIYW5kbGVyXHUzMDRDXHU4QTJEXHU1QjlBXHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDZBXHUzMDQ0XHU1ODM0XHU1NDA4XHUzMDAxXHU4OUUzXHU2NzkwXHUzMDkyXHU1NDdDXHUzMDczXHU1MUZBXHUzMDU5XHUzMDUzXHUzMDY4XHUzMDRDXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzIn0sCi0KLSAgICB7IEVSX05PX1BBUkVOVF9GT1JfRklMVEVSLAotICAgICAgICAiXHUzMEQ1XHUzMEEzXHUzMEVCXHUzMEJGXHUzMDZFXHU4OUFBXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzIn0sCi0KLSAgICB7IEVSX05PX1NUWUxFU0hFRVRfSU5fTUVESUEsCi0gICAgICAgICAiXHUzMEI5XHUzMEJGXHUzMEE0XHUzMEVCXHUzMEI3XHUzMEZDXHUzMEM4XHUzMDRDezB9XHUzMDZCXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyXHUzMEUxXHUzMEM3XHUzMEEzXHUzMEEyPSB7MX0ifSwKLQotICAgIHsgRVJfTk9fU1RZTEVTSEVFVF9QSSwKLSAgICAgICAgICJ4bWwtc3R5bGVzaGVldCBQSVx1MzA0Q3swfVx1MzA2Qlx1ODk4Qlx1MzA2NFx1MzA0Qlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5MyJ9LAotCi0gICAgeyBFUl9OT1RfU1VQUE9SVEVELAotICAgICAgICJcdTMwQjVcdTMwRERcdTMwRkNcdTMwQzhcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTM6IHswfSJ9LAotCi0gICAgeyBFUl9QUk9QRVJUWV9WQUxVRV9CT09MRUFOLAotICAgICAgICJcdTMwRDdcdTMwRURcdTMwRDFcdTMwQzZcdTMwQTN7MH1cdTMwNkVcdTUwMjRcdTMwNkZCb29sZWFuXHUzMEE0XHUzMEYzXHUzMEI5XHUzMEJGXHUzMEYzXHUzMEI5XHUzMDY3XHUzMDQyXHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5In0sCi0KLSAgICB7IEVSX0NPVUxEX05PVF9GSU5EX0VYVEVSTl9TQ1JJUFQsCi0gICAgICAgICAiezB9XHUzMDZFXHU1OTE2XHU5MEU4XHUzMEI5XHUzMEFGXHUzMEVBXHUzMEQ3XHUzMEM4XHUzMDZCXHU1MjMwXHU5MDU0XHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDY3XHUzMDU3XHUzMDVGIn0sCi0KLSAgICB7IEVSX1JFU09VUkNFX0NPVUxEX05PVF9GSU5ELAotICAgICAgICAiXHUzMEVBXHUzMEJEXHUzMEZDXHUzMEI5WyB7MH0gXVx1MzA2Rlx1ODk4Qlx1MzA2NFx1MzA0Qlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5M1x1MzA2N1x1MzA1N1x1MzA1Rlx1MzAwMlxuIHsxfSJ9LAotCi0gICAgeyBFUl9PVVRQVVRfUFJPUEVSVFlfTk9UX1JFQ09HTklaRUQsCi0gICAgICAgICJcdTUxRkFcdTUyOUJcdTMwRDdcdTMwRURcdTMwRDFcdTMwQzZcdTMwQTNcdTMwNENcdThBOERcdThCNThcdTMwNTVcdTMwOENcdTMwN0VcdTMwNUJcdTMwOTM6IHswfSJ9LAotCi0gICAgeyBFUl9GQUlMRURfQ1JFQVRJTkdfRUxFTUxJVFJTTFQsCi0gICAgICAgICJFbGVtTGl0ZXJhbFJlc3VsdFx1MzBBNFx1MzBGM1x1MzBCOVx1MzBCRlx1MzBGM1x1MzBCOVx1MzA2RVx1NEY1Q1x1NjIxMFx1MzA2Qlx1NTkzMVx1NjU1N1x1MzA1N1x1MzA3RVx1MzA1N1x1MzA1RiJ9LAotCi0gIC8vRWFybGllciAoSkRLIDEuNCBYQUxBTiAyLjItRDExKSBhdCBrZXkgY29kZSAnMjA0JyB0aGUga2V5IG5hbWUgd2FzIEVSX1BSSU9SSVRZX05PVF9QQVJTQUJMRQotICAvLyBJbiBsYXRlc3QgWGFsYW4gY29kZSBiYXNlIGtleSBuYW1lIGlzICBFUl9WQUxVRV9TSE9VTERfQkVfTlVNQkVSLiBUaGlzIHNob3VsZCBhbHNvIGJlIHRha2VuIGNhcmUKLSAgLy9pbiBsb2NhbGUgc3BlY2lmaWMgZmlsZXMgbGlrZSBYU0xURXJyb3JSZXNvdXJjZXNfZGUuamF2YSwgWFNMVEVycm9yUmVzb3VyY2VzX2ZyLmphdmEgZXRjLgotICAvL05PVEU6IE5vdCBvbmx5IHRoZSBrZXkgbmFtZSBidXQgbWVzc2FnZSBoYXMgYWxzbyBiZWVuIGNoYW5nZWQuCi0gICAgeyBFUl9WQUxVRV9TSE9VTERfQkVfTlVNQkVSLAotICAgICAgICAiezB9XHUzMDZFXHU1MDI0XHUzMDZCXHUzMDZGXHU4OUUzXHU2NzkwXHU1M0VGXHU4MEZEXHUzMDZBXHU2NTcwXHU1MDI0XHUzMDRDXHU1NDJCXHUzMDdFXHUzMDhDXHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5In0sCi0KLSAgICB7IEVSX1ZBTFVFX1NIT1VMRF9FUVVBTCwKLSAgICAgICAgInswfVx1MzA2RVx1NTAyNFx1MzA2Rnllc1x1MzA3RVx1MzA1Rlx1MzA2Rm5vXHUzMDZCXHU3QjQ5XHUzMDU3XHUzMDQ0XHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5In0sCi0KLSAgICB7IEVSX0ZBSUxFRF9DQUxMSU5HX01FVEhPRCwKLSAgICAgICAgInswfVx1MzBFMVx1MzBCRFx1MzBDM1x1MzBDOVx1MzA2RVx1NTQ3Q1x1NTFGQVx1MzA1N1x1MzA2Qlx1NTkzMVx1NjU1N1x1MzA1N1x1MzA3RVx1MzA1N1x1MzA1RiJ9LAotCi0gICAgeyBFUl9GQUlMRURfQ1JFQVRJTkdfRUxFTVRNUEwsCi0gICAgICAgICJFbGVtVGVtcGxhdGVFbGVtZW50XHUzMEE0XHUzMEYzXHUzMEI5XHUzMEJGXHUzMEYzXHUzMEI5XHUzMDZFXHU0RjVDXHU2MjEwXHUzMDZCXHU1OTMxXHU2NTU3XHUzMDU3XHUzMDdFXHUzMDU3XHUzMDVGIn0sCi0KLSAgICB7IEVSX0NIQVJTX05PVF9BTExPV0VELAotICAgICAgICAiXHU2NTg3XHU1QjU3XHUzMDZGXHUzMEM5XHUzMEFEXHUzMEU1XHUzMEUxXHUzMEYzXHUzMEM4XHUzMDZFXHUzMDUzXHUzMDZFXHUzMEREXHUzMEE0XHUzMEYzXHUzMEM4XHUzMDY3XHUzMDZGXHU4QTMxXHU1M0VGXHUzMDU1XHUzMDhDXHUzMDdFXHUzMDVCXHUzMDkzIn0sCi0KLSAgICB7IEVSX0FUVFJfTk9UX0FMTE9XRUQsCi0gICAgICAgICJcInswfVwiXHU1QzVFXHU2MDI3XHUzMDZGezF9XHU4OTgxXHU3RDIwXHUzMDY3XHUzMDZGXHU4QTMxXHU1M0VGXHUzMDU1XHUzMDhDXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyIn0sCi0KLSAgICB7IEVSX0JBRF9WQUxVRSwKLSAgICAgInswfVx1MzA2RVx1NEUwRFx1NkI2M1x1MzA2QVx1NTAyNHsxfSAifSwKLQotICAgIHsgRVJfQVRUUklCX1ZBTFVFX05PVF9GT1VORCwKLSAgICAgInswfVx1NUM1RVx1NjAyN1x1NTAyNFx1MzA0Q1x1ODk4Qlx1MzA2NFx1MzA0Qlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5MyAifSwKLQotICAgIHsgRVJfQVRUUklCX1ZBTFVFX05PVF9SRUNPR05JWkVELAotICAgICAiezB9XHU1QzVFXHU2MDI3XHU1MDI0XHUzMDRDXHU4QThEXHU4QjU4XHUzMDU1XHUzMDhDXHUzMDdFXHUzMDVCXHUzMDkzICJ9LAotCi0gICAgeyBFUl9OVUxMX1VSSV9OQU1FU1BBQ0UsCi0gICAgICJudWxsXHUzMDZFVVJJXHUzMDkyXHU2MzAxXHUzMDY0XHUzMENEXHUzMEZDXHUzMEUwXHUzMEI5XHUzMERBXHUzMEZDXHUzMEI5XHUzMDZFXHU2M0E1XHU5ODJEXHU4RjlFXHUzMDkyXHU3NTFGXHU2MjEwXHUzMDU3XHUzMDg4XHUzMDQ2XHUzMDY4XHUzMDU3XHUzMDdFXHUzMDU3XHUzMDVGIn0sCi0KLSAgICB7IEVSX05VTUJFUl9UT09fQklHLAotICAgICAiXHU2NzAwXHU1OTI3XHUzMDZFTG9uZ1x1NjU3NFx1NjU3MFx1MzA4OFx1MzA4QVx1MzA4Mlx1NTkyN1x1MzA0RFx1MzA0NFx1NjU3MFx1NTAyNFx1MzA5Mlx1MzBENVx1MzBBOVx1MzBGQ1x1MzBERVx1MzBDM1x1MzBDOFx1MzA1N1x1MzA4OFx1MzA0Nlx1MzA2OFx1MzA1N1x1MzA3RVx1MzA1N1x1MzA1RiJ9LAotCi0gICAgeyBFUl9DQU5OT1RfRklORF9TQVgxX0RSSVZFUiwKLSAgICAgIlNBWDFcdTMwQzlcdTMwRTlcdTMwQTRcdTMwRDBcdTMwRkJcdTMwQUZcdTMwRTlcdTMwQjl7MH1cdTMwNENcdTg5OEJcdTMwNjRcdTMwNEJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTMifSwKLQotICAgIHsgRVJfU0FYMV9EUklWRVJfTk9UX0xPQURFRCwKLSAgICAgIlNBWDFcdTMwQzlcdTMwRTlcdTMwQTRcdTMwRDBcdTMwRkJcdTMwQUZcdTMwRTlcdTMwQjl7MH1cdTMwNENcdTg5OEJcdTMwNjRcdTMwNEJcdTMwOEFcdTMwN0VcdTMwNTdcdTMwNUZcdTMwNENcdTMwRURcdTMwRkNcdTMwQzlcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTMifSwKLQotICAgIHsgRVJfU0FYMV9EUklWRVJfTk9UX0lOU1RBTlRJQVRFRCwKLSAgICAgIlNBWDFcdTMwQzlcdTMwRTlcdTMwQTRcdTMwRDBcdTMwRkJcdTMwQUZcdTMwRTlcdTMwQjl7MH1cdTMwNENcdTMwRURcdTMwRkNcdTMwQzlcdTMwNTVcdTMwOENcdTMwN0VcdTMwNTdcdTMwNUZcdTMwNENcdTMwQTRcdTMwRjNcdTMwQjlcdTMwQkZcdTMwRjNcdTMwQjlcdTUzMTZcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTMifSwKLQotICAgIHsgRVJfU0FYMV9EUklWRVJfTk9UX0lNUExFTUVOVF9QQVJTRVIsCi0gICAgICJTQVgxXHUzMEM5XHUzMEU5XHUzMEE0XHUzMEQwXHUzMEZCXHUzMEFGXHUzMEU5XHUzMEI5ezB9XHUzMDZGb3JnLnhtbC5zYXguUGFyc2VyXHUzMDkyXHU1QjlGXHU4OEM1XHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzIn0sCi0KLSAgICB7IEVSX1BBUlNFUl9QUk9QRVJUWV9OT1RfU1BFQ0lGSUVELAotICAgICAiXHUzMEI3XHUzMEI5XHUzMEM2XHUzMEUwXHUzMEZCXHUzMEQ3XHUzMEVEXHUzMEQxXHUzMEM2XHUzMEEzb3JnLnhtbC5zYXgucGFyc2VyXHUzMDRDXHU2MzA3XHU1QjlBXHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzIn0sCi0KLSAgICB7IEVSX1BBUlNFUl9BUkdfQ0FOTk9UX0JFX05VTEwsCi0gICAgICJcdTMwRDFcdTMwRkNcdTMwQjVcdTMwRkNcdTVGMTVcdTY1NzBcdTMwNkZudWxsXHUzMDY3XHUzMDZBXHUzMDQ0XHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5In0sCi0KLSAgICB7IEVSX0ZFQVRVUkUsCi0gICAgICJcdTZBNUZcdTgwRkQ6IHswfSJ9LAotCi0gICAgeyBFUl9QUk9QRVJUWSwKLSAgICAgIlx1MzBEN1x1MzBFRFx1MzBEMVx1MzBDNlx1MzBBMzogezB9In0sCi0KLSAgICB7IEVSX05VTExfRU5USVRZX1JFU09MVkVSLAotICAgICAiTnVsbFx1MzBBOFx1MzBGM1x1MzBDNlx1MzBBM1x1MzBDNlx1MzBBM1x1MzBGQlx1MzBFQVx1MzBCRVx1MzBFQlx1MzBEMCJ9LAotCi0gICAgeyBFUl9OVUxMX0RURF9IQU5ETEVSLAotICAgICAiTnVsbCBEVERcdTMwQ0ZcdTMwRjNcdTMwQzlcdTMwRTkifSwKLQotICAgIHsgRVJfTk9fRFJJVkVSX05BTUVfU1BFQ0lGSUVELAotICAgICAiXHUzMEM5XHUzMEU5XHUzMEE0XHUzMEQwXHU1NDBEXHUzMDRDXHU2MzA3XHU1QjlBXHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyIn0sCi0KLSAgICB7IEVSX05PX1VSTF9TUEVDSUZJRUQsCi0gICAgICJVUkxcdTMwNENcdTYzMDdcdTVCOUFcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIifSwKLQotICAgIHsgRVJfUE9PTFNJWkVfTEVTU19USEFOX09ORSwKLSAgICAgIlx1MzBEN1x1MzBGQ1x1MzBFQlx1MzBGQlx1MzBCNVx1MzBBNFx1MzBCQVx1MzA0QzFcdTMwODhcdTMwOEFcdTVDMEZcdTMwNTVcdTMwNDRcdTMwNjdcdTMwNTlcdTMwMDIifSwKLQotICAgIHsgRVJfSU5WQUxJRF9EUklWRVJfTkFNRSwKLSAgICAgIlx1NzEyMVx1NTJCOVx1MzA2QVx1MzBDOVx1MzBFOVx1MzBBNFx1MzBEMFx1NTQwRFx1MzA0Q1x1NjMwN1x1NUI5QVx1MzA1NVx1MzA4Q1x1MzA3RVx1MzA1N1x1MzA1Rlx1MzAwMiJ9LAotCi0gICAgeyBFUl9FUlJPUkxJU1RFTkVSLAotICAgICAiRXJyb3JMaXN0ZW5lciJ9LAotCi0KLS8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2Ugc2hvdWxkIG5vdCBub3JtYWxseSBiZSBkaXNwbGF5ZWQKLS8vICAgdG8gdXNlcnMuICBJdCBkZXNjcmliZXMgYSBzaXR1YXRpb24gaW4gd2hpY2ggdGhlIHByb2Nlc3NvciBoYXMgZGV0ZWN0ZWQKLS8vICAgYW4gaW50ZXJuYWwgY29uc2lzdGVuY3kgcHJvYmxlbSBpbiBpdHNlbGYsIGFuZCBpdCBwcm92aWRlcyB0aGlzIG1lc3NhZ2UKLS8vICAgZm9yIHRoZSBkZXZlbG9wZXIgdG8gaGVscCBkaWFnbm9zZSB0aGUgcHJvYmxlbS4gIFRoZSBuYW1lCi0vLyAgICdFbGVtVGVtcGxhdGVFbGVtZW50JyBpcyB0aGUgbmFtZSBvZiBhIGNsYXNzLCBhbmQgc2hvdWxkIG5vdCBiZQotLy8gICB0cmFuc2xhdGVkLgotICAgIHsgRVJfQVNTRVJUX05PX1RFTVBMQVRFX1BBUkVOVCwKLSAgICAgIlx1MzBEN1x1MzBFRFx1MzBCMFx1MzBFOVx1MzBERVx1MzA2RVx1MzBBOFx1MzBFOVx1MzBGQ1x1MzAwMlx1NUYwRlx1MzA2QkVsZW1UZW1wbGF0ZUVsZW1lbnRcdTMwNkVcdTg5QUFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIifSwKLQotCi0vLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIHNob3VsZCBub3Qgbm9ybWFsbHkgYmUgZGlzcGxheWVkCi0vLyAgIHRvIHVzZXJzLiAgSXQgZGVzY3JpYmVzIGEgc2l0dWF0aW9uIGluIHdoaWNoIHRoZSBwcm9jZXNzb3IgaGFzIGRldGVjdGVkCi0vLyAgIGFuIGludGVybmFsIGNvbnNpc3RlbmN5IHByb2JsZW0gaW4gaXRzZWxmLCBhbmQgaXQgcHJvdmlkZXMgdGhpcyBtZXNzYWdlCi0vLyAgIGZvciB0aGUgZGV2ZWxvcGVyIHRvIGhlbHAgZGlhZ25vc2UgdGhlIHByb2JsZW0uICBUaGUgc3Vic3RpdHV0aW9uIHRleHQKLS8vICAgcHJvdmlkZXMgZnVydGhlciBpbmZvcm1hdGlvbiBpbiBvcmRlciB0byBkaWFnbm9zZSB0aGUgcHJvYmxlbS4gIFRoZSBuYW1lCi0vLyAgICdSZWR1bmRlbnRFeHByRWxpbWluYXRvcicgaXMgdGhlIG5hbWUgb2YgYSBjbGFzcywgYW5kIHNob3VsZCBub3QgYmUKLS8vICAgdHJhbnNsYXRlZC4KLSAgICB7IEVSX0FTU0VSVF9SRURVTkRFTlRfRVhQUl9FTElNSU5BVE9SLAotICAgICAiUmVkdW5kZW50RXhwckVsaW1pbmF0b3JcdTMwNjdcdTMwNkVcdTMwRDdcdTMwRURcdTMwQjBcdTMwRTlcdTMwREVcdTMwNkVcdTMwQTJcdTMwQjVcdTMwRkNcdTMwQjdcdTMwRTdcdTMwRjM6IHswfSJ9LAotCi0gICAgeyBFUl9OT1RfQUxMT1dFRF9JTl9QT1NJVElPTiwKLSAgICAgInswfVx1MzA2Rlx1MzBCOVx1MzBCRlx1MzBBNFx1MzBFQlx1MzBCN1x1MzBGQ1x1MzBDOFx1MzA2RVx1MzA1M1x1MzA2RVx1NEY0RFx1N0Y2RVx1MzA2N1x1MzA2Rlx1OEEzMVx1NTNFRlx1MzA1NVx1MzA4Q1x1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMiJ9LAotCi0gICAgeyBFUl9OT05XSElURVNQQUNFX05PVF9BTExPV0VEX0lOX1BPU0lUSU9OLAotICAgICAiXHU3QTdBXHU3NjdEXHU0RUU1XHU1OTE2XHUzMDZFXHUzMEM2XHUzMEFEXHUzMEI5XHUzMEM4XHUzMDZGXHUzMEI5XHUzMEJGXHUzMEE0XHUzMEVCXHUzMEI3XHUzMEZDXHUzMEM4XHUzMDZFXHUzMDUzXHUzMDZFXHU0RjREXHU3RjZFXHUzMDY3XHUzMDZGXHU4QTMxXHU1M0VGXHUzMDU1XHUzMDhDXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyIn0sCi0KLSAgLy8gVGhpcyBjb2RlIGlzIHNoYXJlZCB3aXRoIHdhcm5pbmcgY29kZXMuCi0gIC8vIFN5c3RlbUlkIFVua25vd24KLSAgICB7IElOVkFMSURfVENIQVIsCi0gICAgICJcdTRFMERcdTZCNjNcdTMwNkFcdTUwMjQ6IHsxfVx1MzA0Q0NIQVJcdTVDNUVcdTYwMjd7MH1cdTMwNkJcdTRGN0ZcdTc1MjhcdTMwNTVcdTMwOENcdTMwN0VcdTMwNTdcdTMwNUZcdTMwMDJDSEFSXHU1NzhCXHUzMDZFXHU1QzVFXHU2MDI3XHUzMDZGMVx1NjU4N1x1NUI1N1x1MzA2RVx1MzA3Rlx1MzA2N1x1MzA0Mlx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMiJ9LAotCi0gICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBpcyB1c2VkIGlmIHRoZSB2YWx1ZSBvZgotICAgIC8vIGFuIGF0dHJpYnV0ZSBpbiBhIHN0eWxlc2hlZXQgaXMgaW52YWxpZC4gICJRTkFNRSIgaXMgdGhlIFhNTCBkYXRhLXR5cGUgb2YKLSAgICAvLyB0aGUgYXR0cmlidXRlLCBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHsxfSBpcwotICAgIC8vIHRoZSBhdHRyaWJ1dGUgdmFsdWUgYW5kIHswfSBpcyB0aGUgYXR0cmlidXRlIG5hbWUuCi0gIC8vVGhlIGZvbGxvd2luZyBjb2RlcyBhcmUgc2hhcmVkIHdpdGggdGhlIHdhcm5pbmcgY29kZXMuLi4KLSAgICB7IElOVkFMSURfUU5BTUUsCi0gICAgICJcdTRFMERcdTZCNjNcdTMwNkFcdTUwMjQ6IHsxfVx1MzA0Q1FOQU1FXHU1QzVFXHU2MDI3ezB9XHUzMDZCXHU0RjdGXHU3NTI4XHUzMDU1XHUzMDhDXHUzMDdFXHUzMDU3XHUzMDVGIn0sCi0KLSAgICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIGlzIHVzZWQgaWYgdGhlIHZhbHVlIG9mCi0gICAgLy8gYW4gYXR0cmlidXRlIGluIGEgc3R5bGVzaGVldCBpcyBpbnZhbGlkLiAgIkVOVU0iIGlzIHRoZSBYTUwgZGF0YS10eXBlIG9mCi0gICAgLy8gdGhlIGF0dHJpYnV0ZSwgYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCB7MX0gaXMKLSAgICAvLyB0aGUgYXR0cmlidXRlIHZhbHVlLCB7MH0gaXMgdGhlIGF0dHJpYnV0ZSBuYW1lLCBhbmQgezJ9IGlzIGEgbGlzdCBvZiB2YWxpZAotICAgIC8vIHZhbHVlcy4KLSAgICB7IElOVkFMSURfRU5VTSwKLSAgICAgIlx1NEUwRFx1NkI2M1x1MzA2QVx1NTAyNDogezF9XHUzMDRDRU5VTVx1NUM1RVx1NjAyN3swfVx1MzA2Qlx1NEY3Rlx1NzUyOFx1MzA1NVx1MzA4Q1x1MzA3RVx1MzA1N1x1MzA1Rlx1MzAwMlx1NjcwOVx1NTJCOVx1MzA2QVx1NTAyNFx1MzA2RnsyfVx1MzA2N1x1MzA1OVx1MzAwMiJ9LAotCi0vLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIGlzIHVzZWQgaWYgdGhlIHZhbHVlIG9mCi0vLyBhbiBhdHRyaWJ1dGUgaW4gYSBzdHlsZXNoZWV0IGlzIGludmFsaWQuICAiTk1UT0tFTiIgaXMgdGhlIFhNTCBkYXRhLXR5cGUKLS8vIG9mIHRoZSBhdHRyaWJ1dGUsIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgezF9IGlzCi0vLyB0aGUgYXR0cmlidXRlIHZhbHVlIGFuZCB7MH0gaXMgdGhlIGF0dHJpYnV0ZSBuYW1lLgotICAgIHsgSU5WQUxJRF9OTVRPS0VOLAotICAgICAiXHU0RTBEXHU2QjYzXHUzMDZBXHU1MDI0OiB7MX1cdTMwNENOTVRPS0VOXHU1QzVFXHU2MDI3ezB9XHUzMDZCXHU0RjdGXHU3NTI4XHUzMDU1XHUzMDhDXHUzMDdFXHUzMDU3XHUzMDVGICJ9LAotCi0vLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIGlzIHVzZWQgaWYgdGhlIHZhbHVlIG9mCi0vLyBhbiBhdHRyaWJ1dGUgaW4gYSBzdHlsZXNoZWV0IGlzIGludmFsaWQuICAiTkNOQU1FIiBpcyB0aGUgWE1MIGRhdGEtdHlwZQotLy8gb2YgdGhlIGF0dHJpYnV0ZSwgYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCB7MX0gaXMKLS8vIHRoZSBhdHRyaWJ1dGUgdmFsdWUgYW5kIHswfSBpcyB0aGUgYXR0cmlidXRlIG5hbWUuCi0gICAgeyBJTlZBTElEX05DTkFNRSwKLSAgICAgIlx1NEUwRFx1NkI2M1x1MzA2QVx1NTAyNDogezF9XHUzMDRDTkNOQU1FXHU1QzVFXHU2MDI3ezB9XHUzMDZCXHU0RjdGXHU3NTI4XHUzMDU1XHUzMDhDXHUzMDdFXHUzMDU3XHUzMDVGICJ9LAotCi0vLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIGlzIHVzZWQgaWYgdGhlIHZhbHVlIG9mCi0vLyBhbiBhdHRyaWJ1dGUgaW4gYSBzdHlsZXNoZWV0IGlzIGludmFsaWQuICAiYm9vbGVhbiIgaXMgdGhlIFhTTFQgZGF0YS10eXBlCi0vLyBvZiB0aGUgYXR0cmlidXRlLCBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHsxfSBpcwotLy8gdGhlIGF0dHJpYnV0ZSB2YWx1ZSBhbmQgezB9IGlzIHRoZSBhdHRyaWJ1dGUgbmFtZS4KLSAgICB7IElOVkFMSURfQk9PTEVBTiwKLSAgICAgIlx1NEUwRFx1NkI2M1x1MzA2QVx1NTAyNDogezF9XHUzMDRDYm9vbGVhblx1NUM1RVx1NjAyN3swfVx1MzA2Qlx1NEY3Rlx1NzUyOFx1MzA1NVx1MzA4Q1x1MzA3RVx1MzA1N1x1MzA1RiAifSwKLQotLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBpcyB1c2VkIGlmIHRoZSB2YWx1ZSBvZgotLy8gYW4gYXR0cmlidXRlIGluIGEgc3R5bGVzaGVldCBpcyBpbnZhbGlkLiAgIm51bWJlciIgaXMgdGhlIFhTTFQgZGF0YS10eXBlCi0vLyBvZiB0aGUgYXR0cmlidXRlLCBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHsxfSBpcwotLy8gdGhlIGF0dHJpYnV0ZSB2YWx1ZSBhbmQgezB9IGlzIHRoZSBhdHRyaWJ1dGUgbmFtZS4KLSAgICAgeyBJTlZBTElEX05VTUJFUiwKLSAgICAgIlx1NEUwRFx1NkI2M1x1MzA2QVx1NTAyNDogezF9XHUzMDRDXHU2NTcwXHU1MDI0XHU1QzVFXHU2MDI3ezB9XHUzMDZCXHU0RjdGXHU3NTI4XHUzMDU1XHUzMDhDXHUzMDdFXHUzMDU3XHUzMDVGICJ9LAotCi0KLSAgLy8gRW5kIG9mIHNoYXJlZCBjb2Rlcy4uLgotCi0vLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQSAibWF0Y2ggcGF0dGVybiIgaXMgYSBzcGVjaWFsIGZvcm0gb2YgWFBhdGggZXhwcmVzc2lvbgotLy8gdGhhdCBpcyB1c2VkIGZvciBtYXRjaGluZyBwYXR0ZXJucy4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZgotLy8gYSBmdW5jdGlvbi4gIFRoZSBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHdoZW4gdGhpcyBmdW5jdGlvbiBpcyByZWZlcmVuY2VkIGluCi0vLyBhIG1hdGNoIHBhdHRlcm4sIGl0cyBhcmd1bWVudCBtdXN0IGJlIGEgc3RyaW5nIGxpdGVyYWwgKG9yIGNvbnN0YW50LikKLS8vIEVSX0FSR19MSVRFUkFMIC0gbmV3IGVycm9yIG1lc3NhZ2UgZm9yIGJ1Z3ppbGxhIC8vNTIwMgotICAgIHsgRVJfQVJHX0xJVEVSQUwsCi0gICAgICJcdTRFMDBcdTgxRjRcdTMwRDFcdTMwQkZcdTMwRkNcdTMwRjNcdTMwNkJcdTMwNEFcdTMwNTFcdTMwOEJ7MH1cdTMwNkVcdTVGMTVcdTY1NzBcdTMwNkZcdTMwRUFcdTMwQzZcdTMwRTlcdTMwRUJcdTMwNjdcdTMwNDJcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIifSwKLQotLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0d28gZGVmaW5pdGlvbnMgb2YKLS8vIGEgdmFyaWFibGUuICBBICJnbG9iYWwgdmFyaWFibGUiIGlzIGEgdmFyaWFibGUgdGhhdCBpcyBhY2Nlc3NpYmxlIGV2ZXJ5d2hlcgotLy8gaW4gdGhlIHN0eWxlc2hlZXQuCi0vLyBFUl9EVVBMSUNBVEVfR0xPQkFMX1ZBUiAtIG5ldyBlcnJvciBtZXNzYWdlIGZvciBidWd6aWxsYSAjNzkwCi0gICAgeyBFUl9EVVBMSUNBVEVfR0xPQkFMX1ZBUiwKLSAgICAgIlx1MzBCMFx1MzBFRFx1MzBGQ1x1MzBEMFx1MzBFQlx1NTkwOVx1NjU3MFx1NUJBM1x1OEEwMFx1MzA0Q1x1OTFDRFx1ODkwN1x1MzA1N1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OVx1MzAwMiJ9LAotCi0KLS8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdHdvIGRlZmluaXRpb25zIG9mCi0vLyBhIHZhcmlhYmxlIHdlcmUgZW5jb3VudGVyZWQuCi0vLyBFUl9EVVBMSUNBVEVfVkFSIC0gbmV3IGVycm9yIG1lc3NhZ2UgZm9yIGJ1Z3ppbGxhICM3OTAKLSAgICB7IEVSX0RVUExJQ0FURV9WQVIsCi0gICAgICJcdTU5MDlcdTY1NzBcdTVCQTNcdThBMDBcdTMwNENcdTkxQ0RcdTg5MDdcdTMwNTdcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTlcdTMwMDIifSwKLQotICAgIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAieHNsOnRlbXBsYXRlLCAibmFtZSIgYW5kICJtYXRjaCIgYXJlIFhTTFQga2V5d29yZHMKLSAgICAvLyB3aGljaCBtdXN0IG5vdCBiZSB0cmFuc2xhdGVkLgotICAgIC8vIEVSX1RFTVBMQVRFX05BTUVfTUFUQ0ggLSBuZXcgZXJyb3IgbWVzc2FnZSBmb3IgYnVnemlsbGEgIzc4OQotICAgIHsgRVJfVEVNUExBVEVfTkFNRV9NQVRDSCwKLSAgICAgInhzbDp0ZW1wbGF0ZVx1MzA2Qlx1MzA2Rm5hbWVcdTVDNUVcdTYwMjdcdTMwN0VcdTMwNUZcdTMwNkZtYXRjaFx1NUM1RVx1NjAyNyhcdTMwNDJcdTMwOEJcdTMwNDRcdTMwNkZcdTRFMjFcdTY1QjkpXHUzMDRDXHU1RkM1XHU4OTgxXHUzMDY3XHUzMDU5In0sCi0KLSAgICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgImV4Y2x1ZGUtcmVzdWx0LXByZWZpeGVzIiBpcyBhbiBYU0xUIGtleXdvcmQgd2hpY2gKLSAgICAvLyBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCBhIG5hbWVzcGFjZSBwcmVmaXgKLSAgICAvLyBlbmNvdW50ZXJlZCBhcyBwYXJ0IG9mIHRoZSB2YWx1ZSBvZiB0aGUgZXhjbHVkZS1yZXN1bHQtcHJlZml4ZXMgYXR0cmlidXRlCi0gICAgLy8gd2FzIGluIGVycm9yLgotICAgIC8vIEVSX0lOVkFMSURfUFJFRklYIC0gbmV3IGVycm9yIG1lc3NhZ2UgZm9yIGJ1Z3ppbGxhICM3ODgKLSAgICB7IEVSX0lOVkFMSURfUFJFRklYLAotICAgICAiZXhjbHVkZS1yZXN1bHQtcHJlZml4ZXNcdTMwNkVcdTYzQTVcdTk4MkRcdThGOUVcdTMwNENcdTcxMjFcdTUyQjlcdTMwNjdcdTMwNTk6IHswfSJ9LAotCi0gICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIEFuICJhdHRyaWJ1dGUgc2V0IiBpcyBhIHNldCBvZiBhdHRyaWJ1dGVzIHRoYXQgY2FuCi0gICAgLy8gYmUgYWRkZWQgdG8gYW4gZWxlbWVudCBpbiB0aGUgb3V0cHV0IGRvY3VtZW50IGFzIGEgZ3JvdXAuICBUaGUgbWVzc2FnZQotICAgIC8vIGluZGljYXRlcyB0aGF0IHRoZXJlIHdhcyBhIHJlZmVyZW5jZSB0byBhbiBhdHRyaWJ1dGUgc2V0IG5hbWVkIHswfSB0aGF0Ci0gICAgLy8gd2FzIG5ldmVyIGRlZmluZWQuCi0gICAgLy8gRVJfTk9fQVRUUklCX1NFVCAtIG5ldyBlcnJvciBtZXNzYWdlIGZvciBidWd6aWxsYSAjNzgyCi0gICAgeyBFUl9OT19BVFRSSUJfU0VULAotICAgICAiezB9XHUzMDY4XHUzMDQ0XHUzMDQ2XHU1NDBEXHU1MjREXHUzMDZFYXR0cmlidXRlLXNldFx1MzA2Rlx1NUI1OFx1NTcyOFx1MzA1N1x1MzA3RVx1MzA1Qlx1MzA5MyJ9LAotCi0gICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGVyZSB3YXMgYSByZWZlcmVuY2UKLSAgICAvLyB0byBhIGZ1bmN0aW9uIG5hbWVkIHswfSBmb3Igd2hpY2ggbm8gZnVuY3Rpb24gZGVmaW5pdGlvbiBjb3VsZCBiZSBmb3VuZC4KLSAgICB7IEVSX0ZVTkNUSU9OX05PVF9GT1VORCwKLSAgICAgInswfVx1MzA2OFx1MzA0NFx1MzA0Nlx1NTQwRFx1NTI0RFx1MzA2RVx1NkE1Rlx1ODBGRFx1MzA2Rlx1NUI1OFx1NTcyOFx1MzA1N1x1MzA3RVx1MzA1Qlx1MzA5MyJ9LAotCi0gICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUgWFNMVCBpbnN0cnVjdGlvbgotICAgIC8vIHRoYXQgaXMgbmFtZWQgYnkgdGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHswfSBtdXN0IG5vdCBjb250YWluIG90aGVyIFhTTFQKLSAgICAvLyBpbnN0cnVjdGlvbnMgKGNvbnRlbnQpIG9yIGEgInNlbGVjdCIgYXR0cmlidXRlLiAgVGhlIHdvcmQgInNlbGVjdCIgaXMKLSAgICAvLyBhbiBYU0xUIGtleXdvcmQgaW4gdGhpcyBjYXNlIGFuZCBtdXN0IG5vdCBiZSB0cmFuc2xhdGVkLgotICAgIHsgRVJfQ0FOVF9IQVZFX0NPTlRFTlRfQU5EX1NFTEVDVCwKLSAgICAgInswfVx1ODk4MVx1N0QyMFx1MzA2Qlx1MzA2Rlx1MzBCM1x1MzBGM1x1MzBDNlx1MzBGM1x1MzBDNFx1MzA2OHNlbGVjdFx1NUM1RVx1NjAyN1x1MzA2RVx1NEUyMVx1NjVCOVx1MzA5Mlx1NTQyQlx1MzA4MVx1MzA2QVx1MzA0NFx1MzA2N1x1MzA0Rlx1MzA2MFx1MzA1NVx1MzA0NFx1MzAwMiJ9LAotCi0gICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUgdmFsdWUgYXJndW1lbnQKLSAgICAvLyBvZiBzZXRQYXJhbWV0ZXIgbXVzdCBiZSBhIHZhbGlkIEphdmEgT2JqZWN0LgotICAgIHsgRVJfSU5WQUxJRF9TRVRfUEFSQU1fVkFMVUUsCi0gICAgICJcdTMwRDFcdTMwRTlcdTMwRTFcdTMwRkNcdTMwQkZ7MH1cdTMwNkZcdTY3MDlcdTUyQjlcdTMwNkFKYXZhXHUzMEFBXHUzMEQ2XHUzMEI4XHUzMEE3XHUzMEFGXHUzMEM4XHUzMDY3XHUzMDQyXHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5In0sCi0KLSAgICB7IEVSX0lOVkFMSURfTkFNRVNQQUNFX1VSSV9WQUxVRV9GT1JfUkVTVUxUX1BSRUZJWF9GT1JfREVGQVVMVCwKLSAgICAgICJ4c2w6bmFtZXNwYWNlLWFsaWFzXHU4OTgxXHU3RDIwXHUzMDZFcmVzdWx0LXByZWZpeFx1NUM1RVx1NjAyN1x1MzA2Qlx1NTAyNCcjZGVmYXVsdCdcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwNENcdTMwMDFcdTg5ODFcdTdEMjBcdTMwNkVcdTMwQjlcdTMwQjNcdTMwRkNcdTMwRDdcdTUxODVcdTMwNkJcdTMwQzdcdTMwRDVcdTMwQTlcdTMwRUJcdTMwQzhcdTMwNkVcdTMwQ0RcdTMwRkNcdTMwRTBcdTMwQjlcdTMwREFcdTMwRkNcdTMwQjlcdTMwNkVcdTVCQTNcdThBMDBcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTMifSwKLQotICAgIHsgRVJfSU5WQUxJRF9OQU1FU1BBQ0VfVVJJX1ZBTFVFX0ZPUl9SRVNVTFRfUFJFRklYLAotICAgICAgInhzbDpuYW1lc3BhY2UtYWxpYXNcdTg5ODFcdTdEMjBcdTMwNkVyZXN1bHQtcHJlZml4XHU1QzVFXHU2MDI3XHUzMDZCXHU1MDI0Jyd7MH0nJ1x1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzA0Q1x1MzAwMVx1ODk4MVx1N0QyMFx1MzA2RVx1MzBCOVx1MzBCM1x1MzBGQ1x1MzBEN1x1NTE4NVx1MzA2Qlx1NjNBNVx1OTgyRFx1OEY5RScnezB9JydcdTMwNkVcdTMwQ0RcdTMwRkNcdTMwRTBcdTMwQjlcdTMwREFcdTMwRkNcdTMwQjlcdTVCQTNcdThBMDBcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIifSwKLQotICAgIHsgRVJfU0VUX0ZFQVRVUkVfTlVMTF9OQU1FLAotICAgICAgIlx1NkE1Rlx1ODBGRFx1NTQwRFx1MzA2RlRyYW5zZm9ybWVyRmFjdG9yeS5zZXRGZWF0dXJlKFN0cmluZyBuYW1lLCBib29sZWFuIHZhbHVlKVx1NTE4NVx1MzA2N251bGxcdTMwNkJcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIifSwKLQotICAgIHsgRVJfR0VUX0ZFQVRVUkVfTlVMTF9OQU1FLAotICAgICAgIlx1NkE1Rlx1ODBGRFx1NTQwRFx1MzA2RlRyYW5zZm9ybWVyRmFjdG9yeS5nZXRGZWF0dXJlKFN0cmluZyBuYW1lKVx1NTE4NVx1MzA2N251bGxcdTMwNkJcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIifSwKLQotICAgIHsgRVJfVU5TVVBQT1JURURfRkVBVFVSRSwKLSAgICAgICJcdTZBNUZcdTgwRkQnJ3swfScnXHUzMDkyXHUzMDUzXHUzMDZFVHJhbnNmb3JtZXJGYWN0b3J5XHUzMDZCXHU4QTJEXHU1QjlBXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyIn0sCi0KLSAgICB7IEVSX0VYVEVOU0lPTl9FTEVNRU5UX05PVF9BTExPV0VEX0lOX1NFQ1VSRV9QUk9DRVNTSU5HLAotICAgICAgICAgICJcdTMwQkJcdTMwQURcdTMwRTVcdTMwQTJcdTUxRTZcdTc0MDZcdTZBNUZcdTgwRkRcdTMwNEN0cnVlXHUzMDZCXHU4QTJEXHU1QjlBXHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDhCXHUzMDY4XHUzMDREXHUzMDAxXHU2MkUxXHU1RjM1XHU4OTgxXHU3RDIwJyd7MH0nJ1x1MzA2RVx1NEY3Rlx1NzUyOFx1MzA2Rlx1OEEzMVx1NTNFRlx1MzA1NVx1MzA4Q1x1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMiJ9LAotCi0gICAgeyBFUl9OQU1FU1BBQ0VfQ09OVEVYVF9OVUxMX05BTUVTUEFDRSwKLSAgICAgICJudWxsXHUzMDZFXHUzMENEXHUzMEZDXHUzMEUwXHUzMEI5XHUzMERBXHUzMEZDXHUzMEI5VVJJXHUzMDZCXHUzMDY0XHUzMDQ0XHUzMDY2XHU2M0E1XHU5ODJEXHU4RjlFXHUzMDkyXHU1M0Q2XHU1Rjk3XHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyIn0sCi0KLSAgICB7IEVSX05BTUVTUEFDRV9DT05URVhUX05VTExfUFJFRklYLAotICAgICAgIm51bGxcdTMwNkVcdTYzQTVcdTk4MkRcdThGOUVcdTMwNkJcdTMwNjRcdTMwNDRcdTMwNjZcdTMwQ0RcdTMwRkNcdTMwRTBcdTMwQjlcdTMwREFcdTMwRkNcdTMwQjlVUklcdTMwOTJcdTUzRDZcdTVGOTdcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIifSwKLQotICAgIHsgRVJfWFBBVEhfUkVTT0xWRVJfTlVMTF9RTkFNRSwKLSAgICAgICJcdTZBNUZcdTgwRkRcdTU0MERcdTMwOTJudWxsXHUzMDZCXHUzMDU5XHUzMDhCXHUzMDUzXHUzMDY4XHUzMDZGXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyIn0sCi0KLSAgICB7IEVSX1hQQVRIX1JFU09MVkVSX05FR0FUSVZFX0FSSVRZLAotICAgICAgImFyaXR5XHUzMDkyXHU4Q0EwXHUzMDZCXHUzMDU5XHUzMDhCXHUzMDUzXHUzMDY4XHUzMDZGXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyIn0sCi0gIC8vIFdhcm5pbmdzLi4uCi0KLSAgICB7IFdHX0ZPVU5EX0NVUkxZQlJBQ0UsCi0gICAgICAiJ30nXHUzMDRDXHU4OThCXHUzMDY0XHUzMDRCXHUzMDhBXHUzMDdFXHUzMDU3XHUzMDVGXHUzMDRDXHU1QzVFXHU2MDI3XHUzMEM2XHUzMEYzXHUzMEQ3XHUzMEVDXHUzMEZDXHUzMEM4XHUzMDRDXHU5NThCXHUzMDQ0XHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyIn0sCi0KLSAgICB7IFdHX0NPVU5UX0FUVFJJQl9NQVRDSEVTX05PX0FOQ0VTVE9SLAotICAgICAgIlx1OEI2Nlx1NTQ0QTogY291bnRcdTVDNUVcdTYwMjdcdTMwNEN4c2w6bnVtYmVyXHU1MTg1XHUzMDZFXHU3OTU2XHU1MTQ4XHUzMDY4XHU0RTAwXHU4MUY0XHUzMDU3XHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyXHUzMEJGXHUzMEZDXHUzMEIyXHUzMEMzXHUzMEM4PSB7MH0ifSwKLQotICAgIHsgV0dfRVhQUl9BVFRSSUJfQ0hBTkdFRF9UT19TRUxFQ1QsCi0gICAgICAiXHU1M0U0XHUzMDQ0XHU2OUNCXHU2NTg3OiAnZXhwcidcdTVDNUVcdTYwMjdcdTMwNkVcdTU0MERcdTUyNERcdTMwNEMnc2VsZWN0J1x1MzA2Qlx1NTkwOVx1NjZGNFx1MzA1NVx1MzA4Q1x1MzA3RVx1MzA1N1x1MzA1Rlx1MzAwMiJ9LAotCi0gICAgeyBXR19OT19MT0NBTEVfSU5fRk9STUFUTlVNQkVSLAotICAgICAgIlhhbGFuXHUzMDZGZm9ybWF0LW51bWJlclx1OTVBMlx1NjU3MFx1NTE4NVx1MzA2RVx1MzBFRFx1MzBCMVx1MzBGQ1x1MzBFQlx1NTQwRFx1MzA5Mlx1MzA3RVx1MzA2MFx1NTFFNlx1NzQwNlx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMiJ9LAotCi0gICAgeyBXR19MT0NBTEVfTk9UX0ZPVU5ELAotICAgICAgIlx1OEI2Nlx1NTQ0QTogeG1sOmxhbmc9ezB9XHUzMDZFXHUzMEVEXHUzMEIxXHUzMEZDXHUzMEVCXHUzMDRDXHU4OThCXHUzMDY0XHUzMDRCXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDY3XHUzMDU3XHUzMDVGIn0sCi0KLSAgICB7IFdHX0NBTk5PVF9NQUtFX1VSTF9GUk9NLAotICAgICAgInswfVx1MzA0Qlx1MzA4OVVSTFx1MzA5Mlx1NEY1Q1x1NjIxMFx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MyJ9LAotCi0gICAgeyBXR19DQU5OT1RfTE9BRF9SRVFVRVNURURfRE9DLAotICAgICAgIlx1MzBFQVx1MzBBRlx1MzBBOFx1MzBCOVx1MzBDOFx1MzA1NVx1MzA4Q1x1MzA1Rlx1MzBDOVx1MzBBRFx1MzBFNVx1MzBFMVx1MzBGM1x1MzBDOHswfVx1MzA5Mlx1MzBFRFx1MzBGQ1x1MzBDOVx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MyJ9LAotCi0gICAgeyBXR19DQU5OT1RfRklORF9DT0xMQVRPUiwKLSAgICAgICI8c29ydCB4bWw6bGFuZz17MH1cdTMwNkVcdTMwQjNcdTMwRUNcdTMwRkNcdTMwQkZcdTMwNENcdTg5OEJcdTMwNjRcdTMwNEJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwNjdcdTMwNTdcdTMwNUYifSwKLQotICAgIHsgV0dfRlVOQ1RJT05TX1NIT1VMRF9VU0VfVVJMLAotICAgICAgIlx1NTNFNFx1MzA0NFx1NjlDQlx1NjU4NzogXHU5NUEyXHU2NTcwXHU1NDdEXHU0RUU0XHUzMDZGezB9XHUzMDZFVVJMXHUzMDkyXHU0RjdGXHU3NTI4XHUzMDU5XHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5In0sCi0KLSAgICB7IFdHX0VOQ09ESU5HX05PVF9TVVBQT1JURURfVVNJTkdfVVRGOCwKLSAgICAgICJcdTMwQThcdTMwRjNcdTMwQjNcdTMwRkNcdTMwQzdcdTMwQTNcdTMwRjNcdTMwQjB7MH1cdTMwNkZcdTMwQjVcdTMwRERcdTMwRkNcdTMwQzhcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDJVVEYtOFx1MzA5Mlx1NEY3Rlx1NzUyOFx1MzA1N1x1MzA3RVx1MzA1OSJ9LAotCi0gICAgeyBXR19FTkNPRElOR19OT1RfU1VQUE9SVEVEX1VTSU5HX0pBVkEsCi0gICAgICAiXHUzMEE4XHUzMEYzXHUzMEIzXHUzMEZDXHUzMEM3XHUzMEEzXHUzMEYzXHUzMEIwezB9XHUzMDZGXHUzMEI1XHUzMEREXHUzMEZDXHUzMEM4XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAySmF2YSB7MX1cdTMwOTJcdTRGN0ZcdTc1MjhcdTMwNTdcdTMwN0VcdTMwNTkifSwKLQotICAgIHsgV0dfU1BFQ0lGSUNJVFlfQ09ORkxJQ1RTLAotICAgICAgIlx1NzI3OVx1NzU3MFx1NjAyN1x1MzA2RVx1N0FGNlx1NTQwOFx1MzA0Q1x1ODk4Qlx1MzA2NFx1MzA0Qlx1MzA4QVx1MzA3RVx1MzA1N1x1MzA1RjogezB9XHUzMDAyXHUzMEI5XHUzMEJGXHUzMEE0XHUzMEVCXHUzMEI3XHUzMEZDXHUzMEM4XHU1MTg1XHUzMDY3XHU2NzAwXHU1RjhDXHUzMDZCXHU4OThCXHUzMDY0XHUzMDRCXHUzMDYzXHUzMDVGXHUzMDgyXHUzMDZFXHUzMDRDXHU0RjdGXHU3NTI4XHUzMDU1XHUzMDhDXHUzMDdFXHUzMDU5XHUzMDAyIn0sCi0KLSAgICB7IFdHX1BBUlNJTkdfQU5EX1BSRVBBUklORywKLSAgICAgICI9PT09PT09PT0gezB9XHUzMDZFXHU4OUUzXHU2NzkwXHUzMDRBXHUzMDg4XHUzMDczXHU2RTk2XHU1MDk5XHU0RTJEID09PT09PT09PT0ifSwKLQotICAgIHsgV0dfQVRUUl9URU1QTEFURSwKLSAgICAgIlx1NUM1RVx1NjAyN1x1MzBDNlx1MzBGM1x1MzBEN1x1MzBFQ1x1MzBGQ1x1MzBDOFx1MzAwMXswfSJ9LAotCi0gICAgeyBXR19DT05GTElDVF9CRVRXRUVOX1hTTFNUUklQU1BBQ0VfQU5EX1hTTFBSRVNFUlZFU1BBQ0UsCi0gICAgICAieHNsOnN0cmlwLXNwYWNlXHUzMDY4eHNsOnByZXNlcnZlLXNwYWNlXHUzMDZFXHU5NTkzXHUzMDY3XHU0RTAwXHU4MUY0XHUzMDRDXHU3QUY2XHU1NDA4XHUzMDU3XHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5In0sCi0KLSAgICB7IFdHX0FUVFJJQl9OT1RfSEFORExFRCwKLSAgICAgICJYYWxhblx1MzA2RnswfVx1NUM1RVx1NjAyN1x1MzA5Mlx1MzA3RVx1MzA2MFx1NTFFNlx1NzQwNlx1MzA1N1x1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMiJ9LAotCi0gICAgeyBXR19OT19ERUNJTUFMRk9STUFUX0RFQ0xBUkFUSU9OLAotICAgICAgIjEwXHU5MDMyXHU2NTcwXHUzMEQ1XHUzMEE5XHUzMEZDXHUzMERFXHUzMEMzXHUzMEM4ezB9XHUzMDZFXHU1QkEzXHU4QTAwXHUzMDRDXHU4OThCXHUzMDY0XHUzMDRCXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzIn0sCi0KLSAgICB7IFdHX09MRF9YU0xUX05TLAotICAgICAiWFNMVFx1MzA2RVx1MzBDRFx1MzBGQ1x1MzBFMFx1MzBCOVx1MzBEQVx1MzBGQ1x1MzBCOVx1MzA0Q1x1MzA2QVx1MzA0NFx1MzA0Qlx1NEUwRFx1NkI2M1x1MzA2N1x1MzA1OVx1MzAwMiAifSwKLQotICAgIHsgV0dfT05FX0RFRkFVTFRfWFNMREVDSU1BTEZPUk1BVF9BTExPV0VELAotICAgICAgIlx1MzBDN1x1MzBENVx1MzBBOVx1MzBFQlx1MzBDOFx1MzA2RXhzbDpkZWNpbWFsLWZvcm1hdFx1NUJBM1x1OEEwMFx1MzA2RjFcdTMwNjRcdTMwNkVcdTMwN0ZcdThBMzFcdTUzRUZcdTMwNTVcdTMwOENcdTMwN0VcdTMwNTlcdTMwMDIifSwKLQotICAgIHsgV0dfWFNMREVDSU1BTEZPUk1BVF9OQU1FU19NVVNUX0JFX1VOSVFVRSwKLSAgICAgICJ4c2w6ZGVjaW1hbC1mb3JtYXRcdTU0MERcdTMwNkZcdTU2RkFcdTY3MDlcdTMwNjdcdTMwNDJcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDJcdTU0MERcdTUyNERcInswfVwiXHUzMDZGXHU5MUNEXHU4OTA3XHUzMDU3XHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5XHUzMDAyIn0sCi0KLSAgICB7IFdHX0lMTEVHQUxfQVRUUklCVVRFLAotICAgICAgInswfVx1MzA2Qlx1NEUwRFx1NkI2M1x1MzA2QVx1NUM1RVx1NjAyN1x1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OTogezF9In0sCi0KLSAgICB7IFdHX0NPVUxEX05PVF9SRVNPTFZFX1BSRUZJWCwKLSAgICAgICJcdTMwQ0RcdTMwRkNcdTMwRTBcdTMwQjlcdTMwREFcdTMwRkNcdTMwQjlcdTMwNkVcdTYzQTVcdTk4MkRcdThGOUV7MH1cdTMwOTJcdTg5RTNcdTZDN0FcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwNjdcdTMwNTdcdTMwNUZcdTMwMDJcdTMwQ0VcdTMwRkNcdTMwQzlcdTMwNkZcdTcxMjFcdTg5OTZcdTMwNTVcdTMwOENcdTMwN0VcdTMwNTlcdTMwMDIifSwKLQotICAgIHsgV0dfU1RZTEVTSEVFVF9SRVFVSVJFU19WRVJTSU9OX0FUVFJJQiwKLSAgICAgICJ4c2w6c3R5bGVzaGVldFx1MzA2Rid2ZXJzaW9uJ1x1NUM1RVx1NjAyN1x1MzA0Q1x1NUZDNVx1ODk4MVx1MzA2N1x1MzA1OVx1MzAwMiJ9LAotCi0gICAgeyBXR19JTExFR0FMX0FUVFJJQlVURV9OQU1FLAotICAgICAgIlx1NEUwRFx1NkI2M1x1MzA2QVx1NUM1RVx1NjAyN1x1NTQwRDogezB9In0sCi0KLSAgICB7IFdHX0lMTEVHQUxfQVRUUklCVVRFX1ZBTFVFLAotICAgICAgIlx1NzEyMVx1NTJCOVx1MzA2QVx1NTAyNFx1MzA0Q1x1NUM1RVx1NjAyN3swfVx1MzA2Qlx1NEY3Rlx1NzUyOFx1MzA1NVx1MzA4Q1x1MzA3RVx1MzA1N1x1MzA1RjogezF9In0sCi0KLSAgICB7IFdHX0VNUFRZX1NFQ09ORF9BUkcsCi0gICAgICAiXHUzMEM5XHUzMEFEXHUzMEU1XHUzMEUxXHUzMEYzXHUzMEM4XHU5NUEyXHU2NTcwXHUzMDZFMlx1NzU2QVx1NzZFRVx1MzA2RVx1NUYxNVx1NjU3MFx1MzA0Qlx1MzA4OVx1MzA2RVx1N0Q1MFx1Njc5Q1x1MzBDRVx1MzBGQ1x1MzBDOVx1MzBCQlx1MzBDM1x1MzBDOFx1MzA0Q1x1N0E3QVx1MzA2N1x1MzA1OVx1MzAwMlx1N0E3QVx1MzA2RVx1MzBDRVx1MzBGQ1x1MzBDOVx1MzBCQlx1MzBDM1x1MzBDOFx1MzA5Mlx1OEZENFx1MzA1N1x1MzA3RVx1MzA1OVx1MzAwMiJ9LAotCi0gIC8vRm9sbG93aW5nIGFyZSB0aGUgbmV3IFdBUk5JTkcga2V5cyBhZGRlZCBpbiBYQUxBTiBjb2RlIGJhc2UgYWZ0ZXIgSmRrIDEuNCAoWGFsYW4gMi4yLUQxMSkKLQotICAgIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAibmFtZSIgYW5kICJ4c2w6cHJvY2Vzc2luZy1pbnN0cnVjdGlvbiIgYXJlIGtleXdvcmRzCi0gICAgLy8gYW5kIG11c3Qgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgeyBXR19QUk9DRVNTSU5HSU5TVFJVQ1RJT05fTkFNRV9DQU5UX0JFX1hNTCwKLSAgICAgICJ4c2w6cHJvY2Vzc2luZy1pbnN0cnVjdGlvblx1NTQwRFx1MzA2RSduYW1lJ1x1NUM1RVx1NjAyN1x1MzA2RVx1NTAyNFx1MzA2Rid4bWwnXHUzMDY3XHUzMDZBXHUzMDQ0XHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5In0sCi0KLSAgICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIm5hbWUiIGFuZCAieHNsOnByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24iIGFyZSBrZXl3b3JkcwotICAgIC8vIGFuZCBtdXN0IG5vdCBiZSB0cmFuc2xhdGVkLiAgIk5DTmFtZSIgaXMgYW4gWE1MIGRhdGEtdHlwZSBhbmQgbXVzdCBub3QgYmUKLSAgICAvLyB0cmFuc2xhdGVkLgotICAgIHsgV0dfUFJPQ0VTU0lOR0lOU1RSVUNUSU9OX05PVFZBTElEX05DTkFNRSwKLSAgICAgICJ4c2w6cHJvY2Vzc2luZy1pbnN0cnVjdGlvblx1MzA2RScnbmFtZScnXHU1QzVFXHU2MDI3XHUzMDZFXHU1MDI0XHUzMDZGXHU2NzA5XHU1MkI5XHUzMDZBTkNOYW1lXHUzMDY3XHUzMDQyXHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5OiB7MH0ifSwKLQotICAgIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgcmVwb3J0ZWQgaWYgdGhlIHN0eWxlc2hlZXQgdGhhdCBpcwotICAgIC8vIGJlaW5nIHByb2Nlc3NlZCBhdHRlbXB0ZWQgdG8gY29uc3RydWN0IGFuIFhNTCBkb2N1bWVudCB3aXRoIGFuIGF0dHJpYnV0ZSBpbiBhCi0gICAgLy8gcGxhY2Ugb3RoZXIgdGhhbiBvbiBhbiBlbGVtZW50LiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHNwZWNpZmllcyB0aGUgbmFtZSBvZgotICAgIC8vIHRoZSBhdHRyaWJ1dGUuCi0gICAgeyBXR19JTExFR0FMX0FUVFJJQlVURV9QT1NJVElPTiwKLSAgICAgICJcdTVCNTBcdTMwQ0VcdTMwRkNcdTMwQzlcdTMwNkVcdTVGOENcdTMwN0VcdTMwNUZcdTMwNkZcdTg5ODFcdTdEMjBcdTMwNENcdTc1MUZcdTYyMTBcdTMwNTVcdTMwOENcdTMwOEJcdTUyNERcdTMwNkJcdTVDNUVcdTYwMjd7MH1cdTMwOTJcdThGRkRcdTUyQTBcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDJcdTVDNUVcdTYwMjdcdTMwNkZcdTcxMjFcdTg5OTZcdTMwNTVcdTMwOENcdTMwN0VcdTMwNTlcdTMwMDIifSwKLQotICAgIHsgTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSLAotICAgICAgIlx1NTkwOVx1NjZGNFx1MzA0Q1x1OEEzMVx1NTNFRlx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA2QVx1MzA0NFx1MzBBQVx1MzBENlx1MzBCOFx1MzBBN1x1MzBBRlx1MzBDOFx1MzA5Mlx1NTkwOVx1NjZGNFx1MzA1N1x1MzA4OFx1MzA0Nlx1MzA2OFx1MzA1N1x1MzA3RVx1MzA1N1x1MzA1Rlx1MzAwMiIKLSAgICB9LAotCi0gICAgLy9DaGVjazogV0hZIFRIRVJFIElTIEEgR0FQIEIvVyBOVU1CRVJTIGluIHRoZSBYU0xURXJyb3JSZXNvdXJjZXMgcHJvcGVydGllcyBmaWxlPwotCi0gIC8vIE90aGVyIG1pc2NlbGxhbmVvdXMgdGV4dCB1c2VkIGluc2lkZSB0aGUgY29kZS4uLgotICB7ICJ1aV9sYW5ndWFnZSIsICJqYSJ9LAotICB7ICAiaGVscF9sYW5ndWFnZSIsICAiamEiIH0sCi0gIHsgICJsYW5ndWFnZSIsICAiamEiIH0sCi0gIHsgIkJBRF9DT0RFIiwgImNyZWF0ZU1lc3NhZ2VcdTMwNkVcdTMwRDFcdTMwRTlcdTMwRTFcdTMwRkNcdTMwQkZcdTMwNENcdTdCQzRcdTU2RjJcdTU5MTZcdTMwNjdcdTMwNTkifSwKLSAgeyAgIkZPUk1BVF9GQUlMRUQiLCAibWVzc2FnZUZvcm1hdFx1MzA2RVx1NTQ3Q1x1NTFGQVx1MzA1N1x1NEUyRFx1MzA2Qlx1NEY4Qlx1NTkxNlx1MzA0Q1x1MzBCOVx1MzBFRFx1MzBGQ1x1MzA1NVx1MzA4Q1x1MzA3RVx1MzA1N1x1MzA1RiJ9LAotICB7ICAidmVyc2lvbiIsICI+Pj4+Pj4+IFhhbGFuXHUzMEQwXHUzMEZDXHUzMEI4XHUzMEU3XHUzMEYzICJ9LAotICB7ICAidmVyc2lvbjIiLCAgIjw8PDw8PDwifSwKLSAgeyAgInllcyIsICJ5ZXMifSwKLSAgeyAibGluZSIsICJcdTg4NENcdTc1NkFcdTUzRjcifSwKLSAgeyAiY29sdW1uIiwiXHU1MjE3XHU3NTZBXHU1M0Y3In0sCi0gIHsgInhzbGRvbmUiLCAiWFNMUHJvY2Vzc29yOiBcdTVCOENcdTRFODZcdTMwNTdcdTMwN0VcdTMwNTdcdTMwNUYifSwKLQotCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2VzIHByb3ZpZGUgdXNhZ2UgaW5mb3JtYXRpb24KLSAgLy8gZm9yIHRoZSBYYWxhbiBQcm9jZXNzIGNvbW1hbmQgbGluZS4gICJQcm9jZXNzIiBpcyB0aGUgbmFtZSBvZiBhIEphdmEgY2xhc3MsCi0gIC8vIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuCi0gIHsgInhzbFByb2Nfb3B0aW9uIiwgIlhhbGFuLUpcdTMwQjNcdTMwREVcdTMwRjNcdTMwQzlcdTg4NENcdTMwRDdcdTMwRURcdTMwQkJcdTMwQjlcdTMwRkJcdTMwQUZcdTMwRTlcdTMwQjlcdTMwNkVcdTMwQUFcdTMwRDdcdTMwQjdcdTMwRTdcdTMwRjM6In0sCi0gIHsgInhzbFByb2Nfb3B0aW9uIiwgIlhhbGFuLUpcdTMwQjNcdTMwREVcdTMwRjNcdTMwQzlcdTg4NENcdTMwRDdcdTMwRURcdTMwQkJcdTMwQjlcdTMwRkJcdTMwQUZcdTMwRTlcdTMwQjlcdTMwNkVcdTMwQUFcdTMwRDdcdTMwQjdcdTMwRTdcdTMwRjM6In0sCi0gIHsgInhzbFByb2NfaW52YWxpZF94c2x0Y19vcHRpb24iLCAiXHUzMEFBXHUzMEQ3XHUzMEI3XHUzMEU3XHUzMEYzezB9XHUzMDZGWFNMVENcdTMwRTJcdTMwRkNcdTMwQzlcdTMwNjdcdTMwQjVcdTMwRERcdTMwRkNcdTMwQzhcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIifSwKLSAgeyAieHNsUHJvY19pbnZhbGlkX3hhbGFuX29wdGlvbiIsICJcdTMwQUFcdTMwRDdcdTMwQjdcdTMwRTdcdTMwRjN7MH1cdTMwNkYtWFNMVENcdTMwNjhcdTMwNjhcdTMwODJcdTMwNkJcdTMwNkVcdTMwN0ZcdTRGN0ZcdTc1MjhcdTMwNjdcdTMwNERcdTMwN0VcdTMwNTlcdTMwMDIifSwKLSAgeyAieHNsUHJvY19ub19pbnB1dCIsICJcdTMwQThcdTMwRTlcdTMwRkM6IFx1MzBCOVx1MzBCRlx1MzBBNFx1MzBFQlx1MzBCN1x1MzBGQ1x1MzBDOFx1MzA3RVx1MzA1Rlx1MzA2Rlx1NTE2NVx1NTI5QnhtbFx1MzA0Q1x1NjMwN1x1NUI5QVx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMlx1NEY3Rlx1NzUyOFx1NjVCOVx1NkNENVx1MzA2RVx1NjMwN1x1NzkzQVx1MzA2Qlx1MzA2NFx1MzA0NFx1MzA2Nlx1MzA2Rlx1MzBBQVx1MzBEN1x1MzBCN1x1MzBFN1x1MzBGM1x1MzA5Mlx1NEVEOFx1MzA1MVx1MzA1QVx1MzA2Qlx1MzA1M1x1MzA2RVx1MzBCM1x1MzBERVx1MzBGM1x1MzBDOVx1MzA5Mlx1NUI5Rlx1ODg0Q1x1MzA1N1x1MzA2Nlx1MzA0Rlx1MzA2MFx1MzA1NVx1MzA0NFx1MzAwMiJ9LAotICB7ICJ4c2xQcm9jX2NvbW1vbl9vcHRpb25zIiwgIi1cdTUxNzFcdTkwMUFcdTMwQUFcdTMwRDdcdTMwQjdcdTMwRTdcdTMwRjMtIn0sCi0gIHsgInhzbFByb2NfeGFsYW5fb3B0aW9ucyIsICItWGFsYW5cdTc1MjhcdTMwQUFcdTMwRDdcdTMwQjdcdTMwRTdcdTMwRjMtIn0sCi0gIHsgInhzbFByb2NfeHNsdGNfb3B0aW9ucyIsICItWFNMVENcdTc1MjhcdTMwQUFcdTMwRDdcdTMwQjdcdTMwRTdcdTMwRjMtIn0sCi0gIHsgInhzbFByb2NfcmV0dXJuX3RvX2NvbnRpbnVlIiwgIihcdTdEOUFcdTg4NENcdTMwNTlcdTMwOEJcdTMwNkJcdTMwNkY8cmV0dXJuPlx1MzA5Mlx1NjJCQ1x1MzA1N1x1MzA2Nlx1MzA0Rlx1MzA2MFx1MzA1NVx1MzA0NCkifSwKLQotICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogVGhlIG9wdGlvbiBuYW1lIGFuZCB0aGUgcGFyYW1ldGVyIG5hbWUgZG8gbm90IG5lZWQgdG8KLSAgIC8vIGJlIHRyYW5zbGF0ZWQuIE9ubHkgdHJhbnNsYXRlIHRoZSBtZXNzYWdlcyBpbiBwYXJlbnRoZXNlcy4gIE5vdGUgYWxzbyB0aGF0Ci0gICAvLyBsZWFkaW5nIHdoaXRlc3BhY2UgaW4gdGhlIG1lc3NhZ2VzIGlzIHVzZWQgdG8gaW5kZW50IHRoZSB1c2FnZSBpbmZvcm1hdGlvbgotICAgLy8gZm9yIGVhY2ggb3B0aW9uIGluIHRoZSBFbmdsaXNoIG1lc3NhZ2VzLgotICAgLy8gRG8gbm90IHRyYW5zbGF0ZSB0aGUga2V5d29yZHM6IFhTTFRDLCBTQVgsIERPTSBhbmQgRFRNLgotICB7ICJvcHRpb25YU0xUQyIsICIgICBbLVhTTFRDIChcdTU5MDlcdTYzREJcdTMwNkJYU0xUQ1x1MzA5Mlx1NEY3Rlx1NzUyOCldIn0sCi0gIHsgIm9wdGlvbklOIiwgIiAgIFstSU4gaW5wdXRYTUxVUkxdIn0sCi0gIHsgIm9wdGlvblhTTCIsICIgICBbLVhTTCBYU0xUcmFuc2Zvcm1hdGlvblVSTF0ifSwKLSAgeyAib3B0aW9uT1VUIiwgICIgICBbLU9VVCBvdXRwdXRGaWxlTmFtZV0ifSwKLSAgeyAib3B0aW9uTFhDSU4iLCAiICAgWy1MWENJTiBjb21waWxlZFN0eWxlc2hlZXRGaWxlTmFtZUluXSJ9LAotICB7ICJvcHRpb25MWENPVVQiLCAiICAgWy1MWENPVVQgY29tcGlsZWRTdHlsZXNoZWV0RmlsZU5hbWVPdXRPdXRdIn0sCi0gIHsgIm9wdGlvblBBUlNFUiIsICIgICBbLVBBUlNFUiBcdTMwRDFcdTMwRkNcdTMwQjVcdTMwRkNcdTMwRkJcdTMwRUFcdTMwQThcdTMwQkVcdTMwRjNcdTMwNkVcdTVCOENcdTUxNjhcdTRGRUVcdTk4RkVcdTMwQUZcdTMwRTlcdTMwQjlcdTU0MERdIn0sCi0gIHsgICJvcHRpb25FIiwgIiAgIFstRSAoXHU1QjlGXHU0RjUzXHU1M0MyXHU3MTY3XHUzMDkyXHU2MkUxXHU1RjM1XHUzMDU3XHUzMDZBXHUzMDQ0KV0ifSwKLSAgeyAgIm9wdGlvblYiLCAgIiAgIFstRSAoXHU1QjlGXHU0RjUzXHU1M0MyXHU3MTY3XHUzMDkyXHU2MkUxXHU1RjM1XHUzMDU3XHUzMDZBXHUzMDQ0KV0ifSwKLSAgeyAgIm9wdGlvblFDIiwgIiAgIFstUUMgKFx1NjI5MVx1NTIzNlx1MzBEMVx1MzBCRlx1MzBGQ1x1MzBGM1x1N0FGNlx1NTQwOFx1MzA2RVx1OEI2Nlx1NTQ0QSldIn0sCi0gIHsgICJvcHRpb25RIiwgIiAgIFstUSAgKFx1NjI5MVx1NTIzNlx1MzBFMlx1MzBGQ1x1MzBDOSldIn0sCi0gIHsgICJvcHRpb25MRiIsICIgICBbLUxGIChcdTUxRkFcdTUyOUJcdTMwNjdcdTMwNkVcdTMwN0ZcdTY1MzlcdTg4NENcdTMwOTJcdTRGN0ZcdTc1Mjh7XHUzMEM3XHUzMEQ1XHUzMEE5XHUzMEVCXHUzMEM4XHUzMDZGQ1IvTEZ9KV0ifSwKLSAgeyAgIm9wdGlvbkNSIiwgIiAgIFstQ1IgKFx1NTFGQVx1NTI5Qlx1MzA2N1x1MzA2RVx1MzA3Rlx1NjUzOVx1ODg0Q1x1MzA5Mlx1NEY3Rlx1NzUyOHtcdTMwQzdcdTMwRDVcdTMwQTlcdTMwRUJcdTMwQzhcdTMwNkZDUi9MRn0pXSJ9LAotICB7ICJvcHRpb25FU0NBUEUiLCAiICAgWy1FU0NBUEUgKFx1MzBBOFx1MzBCOVx1MzBCMVx1MzBGQ1x1MzBEN1x1MzA1OVx1MzA4Qlx1NjU4N1x1NUI1N3tcdTMwQzdcdTMwRDVcdTMwQTlcdTMwRUJcdTMwQzhcdTMwNkY8PiZcIidcXHJcXG59XSJ9LAotICB7ICJvcHRpb25JTkRFTlQiLCAiICAgWy1JTkRFTlQgKFx1MzBBNFx1MzBGM1x1MzBDN1x1MzBGM1x1MzBDOFx1MzA1OVx1MzA4Qlx1N0E3QVx1NzY3RFx1NjU4N1x1NUI1N1x1NjU3MFx1MzA5Mlx1NTIzNlx1NUZBMXtcdTMwQzdcdTMwRDVcdTMwQTlcdTMwRUJcdTMwQzhcdTMwNkYwfSldIn0sCi0gIHsgIm9wdGlvblRUIiwgIiAgIFstVFQgKFx1MzBDNlx1MzBGM1x1MzBEN1x1MzBFQ1x1MzBGQ1x1MzBDOFx1MzA0Q1x1NTQ3Q1x1MzA3M1x1NTFGQVx1MzA1NVx1MzA4Q1x1MzA1Rlx1MzA2OFx1MzA0RFx1MzA2Qlx1MzBDOFx1MzBFQ1x1MzBGQ1x1MzBCOVx1MzA1OVx1MzA4Qlx1MzAwMildIn0sCi0gIHsgIm9wdGlvblRHIiwgIiAgIFstVEcgKFx1NTQwNFx1NzUxRlx1NjIxMFx1MzBBNFx1MzBEOVx1MzBGM1x1MzBDOFx1MzA5Mlx1MzBDOFx1MzBFQ1x1MzBGQ1x1MzBCOVx1MzA1OVx1MzA4Qlx1MzAwMildIn0sCi0gIHsgIm9wdGlvblRTIiwgIiAgIFstVFMgKFx1NTQwNFx1OTA3OFx1NjI5RVx1MzBBNFx1MzBEOVx1MzBGM1x1MzBDOFx1MzA5Mlx1MzBDOFx1MzBFQ1x1MzBGQ1x1MzBCOVx1MzA1OVx1MzA4Qlx1MzAwMildIn0sCi0gIHsgICJvcHRpb25UVEMiLCAiICAgWy1UVEMgKFx1MzBDNlx1MzBGM1x1MzBEN1x1MzBFQ1x1MzBGQ1x1MzBDOFx1MzA2RVx1NUI1MFx1MzA0Q1x1NTFFNlx1NzQwNlx1MzA1NVx1MzA4Q1x1MzA4Qlx1MzA2OFx1MzA0RFx1MzA2Qlx1MzBDOFx1MzBFQ1x1MzBGQ1x1MzBCOVx1MzA1OVx1MzA4Qlx1MzAwMildIn0sCi0gIHsgIm9wdGlvblRDTEFTUyIsICIgICBbLVRDTEFTUyAoXHUzMEM4XHUzMEVDXHUzMEZDXHUzMEI5XHU2MkUxXHU1RjM1XHU3NTI4XHUzMDZFVHJhY2VMaXN0ZW5lclx1MzBBRlx1MzBFOVx1MzBCOVx1MzAwMildIn0sCi0gIHsgIm9wdGlvblZBTElEQVRFIiwgIiAgIFstVkFMSURBVEUgKFx1NjkxQ1x1OEEzQ1x1MzA5Mlx1NUI5Rlx1ODg0Q1x1MzA1OVx1MzA4Qlx1MzA0Qlx1MzA2OVx1MzA0Nlx1MzA0Qlx1MzA5Mlx1OEEyRFx1NUI5QVx1MzA1OVx1MzA4Qlx1MzAwMlx1NjkxQ1x1OEEzQ1x1MzA2Rlx1MzBDN1x1MzBENVx1MzBBOVx1MzBFQlx1MzBDOFx1MzA2N1x1MzA2Rlx1MzBBQVx1MzBENVx1MzAwMildIn0sCi0gIHsgIm9wdGlvbkVEVU1QIiwgIiAgIFstRURVTVAge29wdGlvbmFsIGZpbGVuYW1lfSAoXHUzMEE4XHUzMEU5XHUzMEZDXHU2NjQyXHUzMDZCc3RhY2tkdW1wXHUzMDkyXHU1QjlGXHU4ODRDXHUzMDU5XHUzMDhCXHUzMDAyKV0ifSwKLSAgeyAgIm9wdGlvblhNTCIsICIgICBbLVhNTCAoWE1MXHUzMEQ1XHUzMEE5XHUzMEZDXHUzMERFXHUzMEMzXHUzMEJGXHUzMDkyXHU0RjdGXHU3NTI4XHUzMDU3XHUzMDY2WE1MXHUzMEQ4XHUzMEMzXHUzMEMwXHUzMEZDXHUzMDkyXHU4RkZEXHU1MkEwXHUzMDU5XHUzMDhCXHUzMDAyKV0ifSwKLSAgeyAgIm9wdGlvblRFWFQiLCAiICAgWy1URVhUIChcdTMwQjdcdTMwRjNcdTMwRDdcdTMwRUJcdTMwRkJcdTMwQzZcdTMwQURcdTMwQjlcdTMwQzhcdTMwRkJcdTMwRDVcdTMwQTlcdTMwRkNcdTMwREVcdTMwQzNcdTMwQkZcdTMwOTJcdTRGN0ZcdTc1MjhcdTMwNTlcdTMwOEJcdTMwMDIpXSJ9LAotICB7ICAib3B0aW9uSFRNTCIsICIgICBbLUhUTUwgKEhUTUxcdTMwRDVcdTMwQTlcdTMwRkNcdTMwREVcdTMwQzNcdTMwQkZcdTMwOTJcdTRGN0ZcdTc1MjhcdTMwNTlcdTMwOEJcdTMwMDIpXSJ9LAotICB7ICAib3B0aW9uUEFSQU0iLCAiICAgWy1QQVJBTSBuYW1lIGV4cHJlc3Npb24gKFx1MzBCOVx1MzBCRlx1MzBBNFx1MzBFQlx1MzBCN1x1MzBGQ1x1MzBDOFx1MzBGQlx1MzBEMVx1MzBFOVx1MzBFMVx1MzBGQ1x1MzBCRlx1MzA5Mlx1OEEyRFx1NUI5QVx1MzA1OVx1MzA4QildIn0sCi0gIHsgICJub1BhcnNlcm1zZzEiLCAiWFNMXHUzMEQ3XHUzMEVEXHUzMEJCXHUzMEI5XHUzMDZGXHU2MjEwXHU1MjlGXHUzMDU3XHUzMDdFXHUzMDVCXHUzMDkzXHUzMDY3XHUzMDU3XHUzMDVGXHUzMDAyIn0sCi0gIHsgICJub1BhcnNlcm1zZzIiLCAiKiogXHUzMEQxXHUzMEZDXHUzMEI1XHUzMEZDXHUzMDRDXHU4OThCXHUzMDY0XHUzMDRCXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDY3XHUzMDU3XHUzMDVGICoqIn0sCi0gIHsgIm5vUGFyc2VybXNnMyIsICAiXHUzMEFGXHUzMEU5XHUzMEI5XHUzMEQxXHUzMEI5XHUzMDkyXHU3OEJBXHU4QThEXHUzMDU3XHUzMDY2XHUzMDRGXHUzMDYwXHUzMDU1XHUzMDQ0XHUzMDAyIn0sCi0gIHsgIm5vUGFyc2VybXNnNCIsICJJQk1cdTMwNkVKYXZhXHU3NTI4WE1MXHUzMEQxXHUzMEZDXHUzMEI1XHUzMEZDXHUzMDRDXHUzMDZBXHUzMDQ0XHU1ODM0XHU1NDA4XHUzMDAxXHU2QjIxXHUzMDZFXHUzMEI1XHUzMEE0XHUzMEM4XHUzMDRCXHUzMDg5XHUzMEMwXHUzMEE2XHUzMEYzXHUzMEVEXHUzMEZDXHUzMEM5XHUzMDY3XHUzMDREXHUzMDdFXHUzMDU5In0sCi0gIHsgIm5vUGFyc2VybXNnNSIsICJJQk1cdTMwNkVBbHBoYVdvcmtzOiBodHRwOi8vd3d3LmFscGhhd29ya3MuaWJtLmNvbS9mb3JtdWxhL3htbCJ9LAotICB7ICJvcHRpb25VUklSRVNPTFZFUiIsICIgICBbLVVSSVJFU09MVkVSIGZ1bGwgY2xhc3MgbmFtZSAoVVJJXHUzMDZFXHU4OUUzXHU2QzdBXHUzMDZCXHU0RjdGXHU3NTI4XHUzMDU1XHUzMDhDXHUzMDhCVVJJUmVzb2x2ZXIpXSJ9LAotICB7ICJvcHRpb25FTlRJVFlSRVNPTFZFUiIsICAiICAgWy1FTlRJVFlSRVNPTFZFUiBmdWxsIGNsYXNzIG5hbWUgKFx1MzBBOFx1MzBGM1x1MzBDNlx1MzBBM1x1MzBDNlx1MzBBM1x1MzA2RVx1ODlFM1x1NkM3QVx1MzA2Qlx1NEY3Rlx1NzUyOFx1MzA1NVx1MzA4Q1x1MzA4QkVudGl0eVJlc29sdmVyKV0ifSwKLSAgeyAib3B0aW9uQ09OVEVOVEhBTkRMRVIiLCAgIiAgIFstQ09OVEVOVEhBTkRMRVIgZnVsbCBjbGFzcyBuYW1lIChcdTUxRkFcdTUyOUJcdTMwNkVcdTMwQjdcdTMwRUFcdTMwQTJcdTMwRTlcdTMwQTRcdTMwQkFcdTMwNkJcdTRGN0ZcdTc1MjhcdTMwNTVcdTMwOENcdTMwOEJDb250ZW50SGFuZGxlcildIn0sCi0gIHsgICJvcHRpb25MSU5FTlVNQkVSUyIsICAiICAgWy1MIFx1MzBCRFx1MzBGQ1x1MzBCOVx1MzBGQlx1MzBDOVx1MzBBRFx1MzBFNVx1MzBFMVx1MzBGM1x1MzBDOFx1MzA2RVx1ODg0Q1x1NzU2QVx1NTNGN1x1MzA5Mlx1NEY3Rlx1NzUyOF0ifSwKLSAgeyAib3B0aW9uU0VDVVJFUFJPQ0VTU0lORyIsICIgICBbLVNFQ1VSRSAoXHUzMEJCXHUzMEFEXHUzMEU1XHUzMEEyXHU1MUU2XHU3NDA2XHU2QTVGXHU4MEZEXHUzMDkydHJ1ZVx1MzA2Qlx1OEEyRFx1NUI5QVx1MzA1OVx1MzA4Qlx1MzAwMildIn0sCi0KLSAgICAvLyBGb2xsb3dpbmcgYXJlIHRoZSBuZXcgb3B0aW9ucyBhZGRlZCBpbiBYU0xURXJyb3JSZXNvdXJjZXMucHJvcGVydGllcyBmaWxlcyBhZnRlciBKZGsgMS40IChYYWxhbiAyLjItRDExKQotCi0KLSAgeyAgIm9wdGlvbk1FRElBIiwgICIgICBbLU1FRElBIG1lZGlhVHlwZSAoXHUzMEM5XHUzMEFEXHUzMEU1XHUzMEUxXHUzMEYzXHUzMEM4XHUzMDZCXHU5NUEyXHU5MDIzXHU0RUQ4XHUzMDUxXHUzMDg5XHUzMDhDXHUzMDVGXHUzMEI5XHUzMEJGXHUzMEE0XHUzMEVCXHUzMEI3XHUzMEZDXHUzMEM4XHUzMDkyXHU4OThCXHUzMDY0XHUzMDUxXHUzMDhCXHUzMDVGXHUzMDgxXHUzMDZCXHUzMEUxXHUzMEM3XHUzMEEzXHUzMEEyXHU1QzVFXHU2MDI3XHUzMDkyXHU0RjdGXHU3NTI4XHUzMDU5XHUzMDhCXHUzMDAyKV0ifSwKLSAgeyAgIm9wdGlvbkZMQVZPUiIsICAiICAgWy1GTEFWT1IgZmxhdm9yTmFtZSAoXHU1OTA5XHU2M0RCXHUzMDkyXHU4ODRDXHUzMDQ2XHUzMDVGXHUzMDgxXHUzMDZCczJzPVNBWFx1MzA3RVx1MzA1Rlx1MzA2RmQyZD1ET01cdTMwOTJcdTY2MEVcdTc5M0FcdTc2ODRcdTMwNkJcdTRGN0ZcdTc1MjhcdTMwNTlcdTMwOEJcdTMwMDIpXSAifSwgLy8gQWRkZWQgYnkgc2JvYWcvc2N1cmN1cnU7IGV4cGVyaW1lbnRhbAotICB7ICJvcHRpb25ESUFHIiwgIiAgIFstRElBRyAoXHU1OTA5XHU2M0RCXHUzMDZCXHUzMDRCXHUzMDRCXHUzMDYzXHUzMDVGXHU1NDA4XHU4QTA4XHUzMERGXHUzMEVBXHU3OUQyXHU2NTcwXHUzMDkyXHU1MUZBXHU1MjlCXHUzMDU5XHUzMDhCXHUzMDAyKV0ifSwKLSAgeyAib3B0aW9uSU5DUkVNRU5UQUwiLCAgIiAgIFstSU5DUkVNRU5UQUwgKGh0dHA6Ly94bWwuYXBhY2hlLm9yZy94YWxhbi9mZWF0dXJlcy9pbmNyZW1lbnRhbFx1MzA5MnRydWVcdTMwNkJcdThBMkRcdTVCOUFcdTMwNTlcdTMwOEJcdTMwNTNcdTMwNjhcdTMwNkJcdTMwODhcdTMwNjNcdTMwNjZcdTU4OTdcdTUyMDZEVE1cdTY5Q0JcdTdCQzlcdTMwOTJcdTMwRUFcdTMwQUZcdTMwQThcdTMwQjlcdTMwQzhcdTMwNTlcdTMwOEJcdTMwMDIpXSJ9LAotICB7ICAib3B0aW9uTk9PUFRJTUlNSVpFIiwgICIgICBbLU5PT1BUSU1JTUlaRSAoaHR0cDovL3htbC5hcGFjaGUub3JnL3hhbGFuL2ZlYXR1cmVzL29wdGltaXplXHUzMDkyZmFsc2VcdTMwNkJcdThBMkRcdTVCOUFcdTMwNTlcdTMwOEJcdTMwNTNcdTMwNjhcdTMwNkJcdTMwODhcdTMwNjNcdTMwNjZcdTMwQjlcdTMwQkZcdTMwQTRcdTMwRUJcdTMwQjdcdTMwRkNcdTMwQzhcdTY3MDBcdTkwNjlcdTUzMTZcdTUxRTZcdTc0MDZcdTMwOTJcdTMwRUFcdTMwQUZcdTMwQThcdTMwQjlcdTMwQzhcdTMwNTdcdTMwNkFcdTMwNDRcdTMwMDIpXSJ9LAotICB7ICJvcHRpb25STCIsICAiICAgWy1STCByZWN1cnNpb25saW1pdCAoXHUzMEI5XHUzMEJGXHUzMEE0XHUzMEVCXHUzMEI3XHUzMEZDXHUzMEM4XHUzMDZFXHU1MThEXHU1RTMwXHUzMDZFXHU2REYxXHUzMDU1XHUzMDZCXHUzMDY0XHUzMDQ0XHUzMDY2XHU2NTcwXHU1MDI0XHU0RTBBXHUzMDZFXHU1MjM2XHU5NjUwXHUzMDkyXHUzMEEyXHUzMEI1XHUzMEZDXHUzMEM4XHUzMDU5XHUzMDhCXHUzMDAyKV0ifSwKLSAgeyAgICJvcHRpb25YTyIsICAiICAgWy1YTyBbdHJhbnNsZXROYW1lXSAoXHU3NTFGXHU2MjEwXHU2RTA4dHJhbnNsZXRcdTMwNkJcdTU0MERcdTUyNERcdTMwOTJcdTUyNzJcdTMwOEFcdTVGNTNcdTMwNjZcdTMwOEIpXSJ9LAotICB7ICAib3B0aW9uWEQiLCAiICAgWy1YRCBkZXN0aW5hdGlvbkRpcmVjdG9yeSAodHJhbnNsZXRcdTMwNkVcdTVCOUJcdTUxNDhcdTMwQzdcdTMwQTNcdTMwRUNcdTMwQUZcdTMwQzhcdTMwRUFcdTMwOTJcdTYzMDdcdTVCOUFcdTMwNTlcdTMwOEIpXSJ9LAotICB7ICAib3B0aW9uWEoiLCAgIiAgIFstWEogamFyZmlsZSAodHJhbnNsZXRcdTMwQUZcdTMwRTlcdTMwQjlcdTMwOTJcdTU0MERcdTUyNEQ8amFyZmlsZT5cdTMwNkVqYXJcdTMwRDVcdTMwQTFcdTMwQTRcdTMwRUJcdTMwNkJcdTMwRDFcdTMwQzNcdTMwQjFcdTMwRkNcdTMwQjhcdTMwNTlcdTMwOEIpXSJ9LAotICB7ICAgIm9wdGlvblhQIiwgICIgICBbLVhQIHBhY2thZ2UgKFx1MzA1OVx1MzA3OVx1MzA2Nlx1MzA2RVx1NzUxRlx1NjIxMFx1NkUwOHRyYW5zbGV0XHUzMEFGXHUzMEU5XHUzMEI5XHU3NTI4XHUzMDZCXHUzMEQxXHUzMEMzXHUzMEIxXHUzMEZDXHUzMEI4XHU1NDBEXHU2M0E1XHU5ODJEXHU4RjlFXHUzMDkyXHU2MzA3XHU1QjlBXHUzMDU5XHUzMDhCKV0ifSwKLQotICAvL0FkZElUSU9OQUwgIFNUUklOR1MgdGhhdCBuZWVkIEwxMG4KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBkZXNjcmliZXMgdXNhZ2Ugb2YgYSBwYXJ0aWN1bGFyCi0gIC8vIGNvbW1hbmQtbGluZSBvcHRpb24gdGhhdCBpcyB1c2VkIHRvIGVuYWJsZSB0aGUgInRlbXBsYXRlIGlubGluaW5nIgotICAvLyBvcHRpbWl6YXRpb24uICBUaGUgb3B0aW1pemF0aW9uIGludm9sdmVzIG1ha2luZyBhIGNvcHkgb2YgdGhlIGNvZGUKLSAgLy8gZ2VuZXJhdGVkIGZvciBhIHRlbXBsYXRlIGluIGFub3RoZXIgdGVtcGxhdGUgdGhhdCByZWZlcnMgdG8gaXQuCi0gIHsgIm9wdGlvblhOIiwgICIgICBbLVhOIChcdTMwQzZcdTMwRjNcdTMwRDdcdTMwRUNcdTMwRkNcdTMwQzhcdTMwNkVcdTMwQTRcdTMwRjNcdTMwRTlcdTMwQTRcdTMwRjNcdTUzMTZcdTMwOTJcdTY3MDlcdTUyQjlcdTMwNkJcdTMwNTlcdTMwOEIpXSIgfSwKLSAgeyAib3B0aW9uWFgiLCAgIiAgIFstWFggKFx1OEZGRFx1NTJBMFx1MzA2RVx1MzBDN1x1MzBEMFx1MzBDM1x1MzBCMFx1MzBGQlx1MzBFMVx1MzBDM1x1MzBCQlx1MzBGQ1x1MzBCOFx1NTFGQVx1NTI5Qlx1MzA5Mlx1MzBBQVx1MzBGM1x1MzA2Qlx1MzA1OVx1MzA4QildIn0sCi0gIHsgIm9wdGlvblhUIiAsICIgICBbLVhUIChcdTUzRUZcdTgwRkRcdTMwNkFcdTU4MzRcdTU0MDhcdTMwNkZcdTU5MDlcdTYzREJcdTMwNkVcdTMwNUZcdTMwODFcdTMwNkJ0cmFuc2xldFx1MzA5Mlx1NEY3Rlx1NzUyOFx1MzA1OVx1MzA4QildIn0sCi0gIHsgImRpYWdUaW1pbmciLCIgLS0tLS0tLS0tIHsxfVx1MzA2Qlx1MzA4OFx1MzA4QnswfVx1MzA2RVx1NTkwOVx1NjNEQlx1MzA2QnsyfVx1MzBERlx1MzBFQVx1NzlEMlx1MzA0Qlx1MzA0Qlx1MzA4QVx1MzA3RVx1MzA1N1x1MzA1RiIgfSwKLSAgeyAicmVjdXJzaW9uVG9vRGVlcCIsIlx1MzBDNlx1MzBGM1x1MzBEN1x1MzBFQ1x1MzBGQ1x1MzBDOFx1MzA2RVx1MzBDRFx1MzBCOVx1MzBDOFx1MzA0Q1x1NkRGMVx1MzA1OVx1MzA0RVx1MzA3RVx1MzA1OVx1MzAwMlx1MzBDRFx1MzBCOVx1MzBDOD0gezB9XHUzMDAxXHUzMEM2XHUzMEYzXHUzMEQ3XHUzMEVDXHUzMEZDXHUzMEM4ezF9IHsyfSIgfSwKLSAgeyAibmFtZUlzIiwgIlx1NTQwRFx1NTI0RDoiIH0sCi0gIHsgIm1hdGNoUGF0dGVybklzIiwgIlx1NEUwMFx1ODFGNFx1MzBEMVx1MzBCRlx1MzBGQ1x1MzBGMzoiIH0KLQotICB9OwotCi0gIH0KLSAgLy8gPT09PT09PT09PT09PT09PT0gSU5GUkFTVFJVQ1RVUkUgPT09PT09PT09PT09PT09PT09PT09PQotCi0gIC8qKiBTdHJpbmcgZm9yIHVzZSB3aGVuIGEgYmFkIGVycm9yIGNvZGUgd2FzIGVuY291bnRlcmVkLiAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBCQURfQ09ERSA9ICJCQURfQ09ERSI7Ci0KLSAgLyoqIFN0cmluZyBmb3IgdXNlIHdoZW4gZm9ybWF0dGluZyBvZiB0aGUgZXJyb3Igc3RyaW5nIGZhaWxlZC4gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBGT1JNQVRfRkFJTEVEID0gIkZPUk1BVF9GQUlMRUQiOwotCi0gIC8qKiBHZW5lcmFsIGVycm9yIHN0cmluZy4gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJPUl9TVFJJTkcgPSAiI2Vycm9yIjsKLQotICAvKiogU3RyaW5nIHRvIHByZXBlbmQgdG8gZXJyb3IgbWVzc2FnZXMuICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJPUl9IRUFERVIgPSAiRXJyb3I6ICI7Ci0KLSAgLyoqIFN0cmluZyB0byBwcmVwZW5kIHRvIHdhcm5pbmcgbWVzc2FnZXMuICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdBUk5JTkdfSEVBREVSID0gIldhcm5pbmc6ICI7Ci0KLSAgLyoqIFN0cmluZyB0byBzcGVjaWZ5IHRoZSBYU0xUIG1vZHVsZS4gICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFhTTF9IRUFERVIgPSAiWFNMVCAiOwotCi0gIC8qKiBTdHJpbmcgdG8gc3BlY2lmeSB0aGUgWE1MIHBhcnNlciBtb2R1bGUuICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxfSEVBREVSID0gIlhNTCAiOwotCi0gIC8qKiBJIGRvbid0IHRoaW5rIHRoaXMgaXMgdXNlZCBhbnkgbW9yZS4KLSAgICogQGRlcHJlY2F0ZWQgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFFVRVJZX0hFQURFUiA9ICJQQVRURVJOICI7Ci0KLQotICAgIH0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwvcmVzL1hTTFRFcnJvclJlc291cmNlc19rby5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC9yZXMvWFNMVEVycm9yUmVzb3VyY2VzX2tvLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGZlMjkyZWUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC9yZXMvWFNMVEVycm9yUmVzb3VyY2VzX2tvLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNDQ3ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnJlczsKLQotaW1wb3J0IGphdmEudXRpbC5MaXN0UmVzb3VyY2VCdW5kbGU7Ci1pbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKLWltcG9ydCBqYXZhLnV0aWwuTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uOwotaW1wb3J0IGphdmEudXRpbC5SZXNvdXJjZUJ1bmRsZTsKLQotLyoqCi0gKiBTZXQgdXAgZXJyb3IgbWVzc2FnZXMuCi0gKiBXZSBidWlsZCBhIHR3byBkaW1lbnNpb25hbCBhcnJheSBvZiBtZXNzYWdlIGtleXMgYW5kCi0gKiBtZXNzYWdlIHN0cmluZ3MuIEluIG9yZGVyIHRvIGFkZCBhIG5ldyBtZXNzYWdlIGhlcmUsCi0gKiB5b3UgbmVlZCB0byBmaXJzdCBhZGQgYSBTdHJpbmcgY29uc3RhbnQuIEFuZAotICogIHlvdSBuZWVkIHRvIGVudGVyIGtleSAsIHZhbHVlIHBhaXIgYXMgcGFydCBvZiBjb250ZW50cwotICogQXJyYXkuIFlvdSBhbHNvIG5lZWQgdG8gdXBkYXRlIE1BWF9DT0RFIGZvciBlcnJvciBzdHJpbmdzCi0gKiBhbmQgTUFYX1dBUk5JTkcgZm9yIHdhcm5pbmdzICggTmVlZGVkIGZvciBvbmx5IGluZm9ybWF0aW9uCi0gKiBwdXJwb3NlICkKLSAqLwotcHVibGljIGNsYXNzIFhTTFRFcnJvclJlc291cmNlc19rbyBleHRlbmRzIExpc3RSZXNvdXJjZUJ1bmRsZQotewotCi0vKgotICogVGhpcyBmaWxlIGNvbnRhaW5zIGVycm9yIGFuZCB3YXJuaW5nIG1lc3NhZ2VzIHJlbGF0ZWQgdG8gWGFsYW4gRXJyb3IKLSAqIEhhbmRsaW5nLgotICoKLSAqICBHZW5lcmFsIG5vdGVzIHRvIHRyYW5zbGF0b3JzOgotICoKLSAqICAxKSBYYWxhbiAob3IgbW9yZSBwcm9wZXJseSwgWGFsYW4taW50ZXJwcmV0aXZlKSBhbmQgWFNMVEMgYXJlIG5hbWVzIG9mCi0gKiAgICAgY29tcG9uZW50cy4KLSAqICAgICBYU0xUIGlzIGFuIGFjcm9ueW0gZm9yICJYTUwgU3R5bGVzaGVldCBMYW5ndWFnZTogVHJhbnNmb3JtYXRpb25zIi4KLSAqICAgICBYU0xUQyBpcyBhbiBhY3JvbnltIGZvciBYU0xUIENvbXBpbGVyLgotICoKLSAqICAyKSBBIHN0eWxlc2hlZXQgaXMgYSBkZXNjcmlwdGlvbiBvZiBob3cgdG8gdHJhbnNmb3JtIGFuIGlucHV0IFhNTCBkb2N1bWVudAotICogICAgIGludG8gYSByZXN1bHRhbnQgWE1MIGRvY3VtZW50IChvciBIVE1MIGRvY3VtZW50IG9yIHRleHQpLiAgVGhlCi0gKiAgICAgc3R5bGVzaGVldCBpdHNlbGYgaXMgZGVzY3JpYmVkIGluIHRoZSBmb3JtIG9mIGFuIFhNTCBkb2N1bWVudC4KLSAqCi0gKiAgMykgQSB0ZW1wbGF0ZSBpcyBhIGNvbXBvbmVudCBvZiBhIHN0eWxlc2hlZXQgdGhhdCBpcyB1c2VkIHRvIG1hdGNoIGEKLSAqICAgICBwYXJ0aWN1bGFyIHBvcnRpb24gb2YgYW4gaW5wdXQgZG9jdW1lbnQgYW5kIHNwZWNpZmllcyB0aGUgZm9ybSBvZiB0aGUKLSAqICAgICBjb3JyZXNwb25kaW5nIHBvcnRpb24gb2YgdGhlIG91dHB1dCBkb2N1bWVudC4KLSAqCi0gKiAgNCkgQW4gZWxlbWVudCBpcyBhIG1hcmstdXAgdGFnIGluIGFuIFhNTCBkb2N1bWVudDsgYW4gYXR0cmlidXRlIGlzIGEKLSAqICAgICBtb2RpZmllciBvbiB0aGUgdGFnLiAgRm9yIGV4YW1wbGUsIGluIDxlbGVtIGF0dHI9J3ZhbCcgYXR0cjI9J3ZhbDInPgotICogICAgICJlbGVtIiBpcyBhbiBlbGVtZW50IG5hbWUsICJhdHRyIiBhbmQgImF0dHIyIiBhcmUgYXR0cmlidXRlIG5hbWVzIHdpdGgKLSAqICAgICB0aGUgdmFsdWVzICJ2YWwiIGFuZCAidmFsMiIsIHJlc3BlY3RpdmVseS4KLSAqCi0gKiAgNSkgQSBuYW1lc3BhY2UgZGVjbGFyYXRpb24gaXMgYSBzcGVjaWFsIGF0dHJpYnV0ZSB0aGF0IGlzIHVzZWQgdG8gYXNzb2NpYXRlCi0gKiAgICAgYSBwcmVmaXggd2l0aCBhIFVSSSAodGhlIG5hbWVzcGFjZSkuICBUaGUgbWVhbmluZ3Mgb2YgZWxlbWVudCBuYW1lcyBhbmQKLSAqICAgICBhdHRyaWJ1dGUgbmFtZXMgdGhhdCB1c2UgdGhhdCBwcmVmaXggYXJlIGRlZmluZWQgd2l0aCByZXNwZWN0IHRvIHRoYXQKLSAqICAgICBuYW1lc3BhY2UuCi0gKgotICogIDYpICJUcmFuc2xldCIgaXMgYW4gaW52ZW50ZWQgdGVybSB0aGF0IGRlc2NyaWJlcyB0aGUgY2xhc3MgZmlsZSB0aGF0Ci0gKiAgICAgcmVzdWx0cyBmcm9tIGNvbXBpbGluZyBhbiBYTUwgc3R5bGVzaGVldCBpbnRvIGEgSmF2YSBjbGFzcy4KLSAqCi0gKiAgNykgWFBhdGggaXMgYSBzcGVjaWZpY2F0aW9uIHRoYXQgZGVzY3JpYmVzIGEgbm90YXRpb24gZm9yIGlkZW50aWZ5aW5nCi0gKiAgICAgbm9kZXMgaW4gYSB0cmVlLXN0cnVjdHVyZWQgcmVwcmVzZW50YXRpb24gb2YgYW4gWE1MIGRvY3VtZW50LiAgQW4KLSAqICAgICBpbnN0YW5jZSBvZiB0aGF0IG5vdGF0aW9uIGlzIHJlZmVycmVkIHRvIGFzIGFuIFhQYXRoIGV4cHJlc3Npb24uCi0gKgotICovCi0KLSAgLyoKLSAgICogU3RhdGljIHZhcmlhYmxlcwotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9OQU1FU1BBQ0VfVVJJX1ZBTFVFX0ZPUl9SRVNVTFRfUFJFRklYID0KLSAgICAgICAgIkVSX0lOVkFMSURfU0VUX05BTUVTUEFDRV9VUklfVkFMVUVfRk9SX1JFU1VMVF9QUkVGSVgiOwotCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfTkFNRVNQQUNFX1VSSV9WQUxVRV9GT1JfUkVTVUxUX1BSRUZJWF9GT1JfREVGQVVMVCA9Ci0gICAgICAgICJFUl9JTlZBTElEX05BTUVTUEFDRV9VUklfVkFMVUVfRk9SX1JFU1VMVF9QUkVGSVhfRk9SX0RFRkFVTFQiOwotCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX0NVUkxZQlJBQ0UgPSAiRVJfTk9fQ1VSTFlCUkFDRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQgPSAiRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lMTEVHQUxfQVRUUklCVVRFID0gIkVSX0lMTEVHQUxfQVRUUklCVVRFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTlVMTF9TT1VSQ0VOT0RFX0FQUExZSU1QT1JUUyA9ICJFUl9OVUxMX1NPVVJDRU5PREVfQVBQTFlJTVBPUlRTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX0FERCA9ICJFUl9DQU5OT1RfQUREIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTlVMTF9TT1VSQ0VOT0RFX0hBTkRMRUFQUExZVEVNUExBVEVTPSJFUl9OVUxMX1NPVVJDRU5PREVfSEFORExFQVBQTFlURU1QTEFURVMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19OQU1FX0FUVFJJQiA9ICJFUl9OT19OQU1FX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1RFTVBMQVRFX05PVF9GT1VORCA9ICJFUl9URU1QTEFURV9OT1RfRk9VTkQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX1JFU09MVkVfTkFNRV9BVlQgPSAiRVJfQ0FOVF9SRVNPTFZFX05BTUVfQVZUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUkVRVUlSRVNfQVRUUklCID0gIkVSX1JFUVVJUkVTX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01VU1RfSEFWRV9URVNUX0FUVFJJQiA9ICJFUl9NVVNUX0hBVkVfVEVTVF9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9CQURfVkFMX09OX0xFVkVMX0FUVFJJQiA9Ci0gICAgICAgICAiRVJfQkFEX1ZBTF9PTl9MRVZFTF9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUk9DRVNTSU5HSU5TVFJVQ1RJT05fTkFNRV9DQU5UX0JFX1hNTCA9Ci0gICAgICAgICAiRVJfUFJPQ0VTU0lOR0lOU1RSVUNUSU9OX05BTUVfQ0FOVF9CRV9YTUwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUk9DRVNTSU5HSU5TVFJVQ1RJT05fTk9UVkFMSURfTkNOQU1FID0KLSAgICAgICAgICJFUl9QUk9DRVNTSU5HSU5TVFJVQ1RJT05fTk9UVkFMSURfTkNOQU1FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTkVFRF9NQVRDSF9BVFRSSUIgPSAiRVJfTkVFRF9NQVRDSF9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9ORUVEX05BTUVfT1JfTUFUQ0hfQVRUUklCID0KLSAgICAgICAgICJFUl9ORUVEX05BTUVfT1JfTUFUQ0hfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9SRVNPTFZFX05TUFJFRklYID0KLSAgICAgICAgICJFUl9DQU5UX1JFU09MVkVfTlNQUkVGSVgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTExFR0FMX1ZBTFVFID0gIkVSX0lMTEVHQUxfVkFMVUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19PV05FUkRPQyA9ICJFUl9OT19PV05FUkRPQyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VMRU1URU1QTEFURUVMRU1fRVJSID0iRVJfRUxFTVRFTVBMQVRFRUxFTV9FUlIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OVUxMX0NISUxEID0gIkVSX05VTExfQ0hJTEQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9ORUVEX1NFTEVDVF9BVFRSSUIgPSAiRVJfTkVFRF9TRUxFQ1RfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTkVFRF9URVNUX0FUVFJJQiA9ICJFUl9ORUVEX1RFU1RfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTkVFRF9OQU1FX0FUVFJJQiA9ICJFUl9ORUVEX05BTUVfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fQ09OVEVYVF9PV05FUkRPQyA9ICJFUl9OT19DT05URVhUX09XTkVSRE9DIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTERfTk9UX0NSRUFURV9YTUxfUFJPQ19MSUFJU09OID0KLSAgICAgICAgICJFUl9DT1VMRF9OT1RfQ1JFQVRFX1hNTF9QUk9DX0xJQUlTT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUk9DRVNTX05PVF9TVUNDRVNTRlVMID0KLSAgICAgICAgICJFUl9QUk9DRVNTX05PVF9TVUNDRVNTRlVMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9UX1NVQ0NFU1NGVUwgPSAiRVJfTk9UX1NVQ0NFU1NGVUwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FTkNPRElOR19OT1RfU1VQUE9SVEVEID0KLSAgICAgICAgICJFUl9FTkNPRElOR19OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTERfTk9UX0NSRUFURV9UUkFDRUxJU1RFTkVSID0KLSAgICAgICAgICJFUl9DT1VMRF9OT1RfQ1JFQVRFX1RSQUNFTElTVEVORVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9LRVlfUkVRVUlSRVNfTkFNRV9BVFRSSUIgPQotICAgICAgICAgIkVSX0tFWV9SRVFVSVJFU19OQU1FX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0tFWV9SRVFVSVJFU19NQVRDSF9BVFRSSUIgPQotICAgICAgICAgIkVSX0tFWV9SRVFVSVJFU19NQVRDSF9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9LRVlfUkVRVUlSRVNfVVNFX0FUVFJJQiA9Ci0gICAgICAgICAiRVJfS0VZX1JFUVVJUkVTX1VTRV9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SRVFVSVJFU19FTEVNRU5UU19BVFRSSUIgPQotICAgICAgICAgIkVSX1JFUVVJUkVTX0VMRU1FTlRTX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01JU1NJTkdfUFJFRklYX0FUVFJJQiA9Ci0gICAgICAgICAiRVJfTUlTU0lOR19QUkVGSVhfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQkFEX1NUWUxFU0hFRVRfVVJMID0gIkVSX0JBRF9TVFlMRVNIRUVUX1VSTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZJTEVfTk9UX0ZPVU5EID0gIkVSX0ZJTEVfTk9UX0ZPVU5EIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU9FWENFUFRJT04gPSAiRVJfSU9FWENFUFRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19IUkVGX0FUVFJJQiA9ICJFUl9OT19IUkVGX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NUWUxFU0hFRVRfSU5DTFVERVNfSVRTRUxGID0KLSAgICAgICAgICJFUl9TVFlMRVNIRUVUX0lOQ0xVREVTX0lUU0VMRiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BST0NFU1NJTkNMVURFX0VSUk9SID0iRVJfUFJPQ0VTU0lOQ0xVREVfRVJST1IiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9NSVNTSU5HX0xBTkdfQVRUUklCID0gIkVSX01JU1NJTkdfTEFOR19BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9NSVNTSU5HX0NPTlRBSU5FUl9FTEVNRU5UX0NPTVBPTkVOVCA9Ci0gICAgICAgICAiRVJfTUlTU0lOR19DT05UQUlORVJfRUxFTUVOVF9DT01QT05FTlQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5fT05MWV9PVVRQVVRfVE9fRUxFTUVOVCA9Ci0gICAgICAgICAiRVJfQ0FOX09OTFlfT1VUUFVUX1RPX0VMRU1FTlQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUk9DRVNTX0VSUk9SID0gIkVSX1BST0NFU1NfRVJST1IiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTklNUExOT0RFX0VSUk9SID0gIkVSX1VOSU1QTE5PREVfRVJST1IiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19TRUxFQ1RfRVhQUkVTU0lPTiA9IkVSX05PX1NFTEVDVF9FWFBSRVNTSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX1NFUklBTElaRV9YU0xQUk9DRVNTT1IgPQotICAgICAgICAgIkVSX0NBTk5PVF9TRVJJQUxJWkVfWFNMUFJPQ0VTU09SIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fSU5QVVRfU1RZTEVTSEVFVCA9ICJFUl9OT19JTlBVVF9TVFlMRVNIRUVUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRkFJTEVEX1BST0NFU1NfU1RZTEVTSEVFVCA9Ci0gICAgICAgICAiRVJfRkFJTEVEX1BST0NFU1NfU1RZTEVTSEVFVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxETlRfUEFSU0VfRE9DID0gIkVSX0NPVUxETlRfUEFSU0VfRE9DIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTEROVF9GSU5EX0ZSQUdNRU5UID0KLSAgICAgICAgICJFUl9DT1VMRE5UX0ZJTkRfRlJBR01FTlQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT0RFX05PVF9FTEVNRU5UID0gIkVSX05PREVfTk9UX0VMRU1FTlQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GT1JFQUNIX05FRURfTUFUQ0hfT1JfTkFNRV9BVFRSSUIgPQotICAgICAgICAgIkVSX0ZPUkVBQ0hfTkVFRF9NQVRDSF9PUl9OQU1FX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1RFTVBMQVRFU19ORUVEX01BVENIX09SX05BTUVfQVRUUklCID0KLSAgICAgICAgICJFUl9URU1QTEFURVNfTkVFRF9NQVRDSF9PUl9OQU1FX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX0NMT05FX09GX0RPQ1VNRU5UX0ZSQUcgPQotICAgICAgICAgIkVSX05PX0NMT05FX09GX0RPQ1VNRU5UX0ZSQUciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX0NSRUFURV9JVEVNID0gIkVSX0NBTlRfQ1JFQVRFX0lURU0iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YTUxTUEFDRV9JTExFR0FMX1ZBTFVFID0KLSAgICAgICAgICJFUl9YTUxTUEFDRV9JTExFR0FMX1ZBTFVFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fWFNMS0VZX0RFQ0xBUkFUSU9OID0KLSAgICAgICAgICJFUl9OT19YU0xLRVlfREVDTEFSQVRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX0NSRUFURV9VUkwgPSAiRVJfQ0FOVF9DUkVBVEVfVVJMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWFNMRlVOQ1RJT05TX1VOU1VQUE9SVEVEID0KLSAgICAgICAgICJFUl9YU0xGVU5DVElPTlNfVU5TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUk9DRVNTT1JfRVJST1IgPSAiRVJfUFJPQ0VTU09SX0VSUk9SIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9UX0FMTE9XRURfSU5TSURFX1NUWUxFU0hFRVQgPQotICAgICAgICAgIkVSX05PVF9BTExPV0VEX0lOU0lERV9TVFlMRVNIRUVUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUkVTVUxUTlNfTk9UX1NVUFBPUlRFRCA9Ci0gICAgICAgICAiRVJfUkVTVUxUTlNfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0RFRkFVTFRTUEFDRV9OT1RfU1VQUE9SVEVEID0KLSAgICAgICAgICJFUl9ERUZBVUxUU1BBQ0VfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOREVOVFJFU1VMVF9OT1RfU1VQUE9SVEVEID0KLSAgICAgICAgICJFUl9JTkRFTlRSRVNVTFRfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lMTEVHQUxfQVRUUklCID0gIkVSX0lMTEVHQUxfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5LTk9XTl9YU0xfRUxFTSA9ICJFUl9VTktOT1dOX1hTTF9FTEVNIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQkFEX1hTTFNPUlRfVVNFID0gIkVSX0JBRF9YU0xTT1JUX1VTRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01JU1BMQUNFRF9YU0xXSEVOID0gIkVSX01JU1BMQUNFRF9YU0xXSEVOIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWFNMV0hFTl9OT1RfUEFSRU5URURfQllfWFNMQ0hPT1NFID0KLSAgICAgICAgICJFUl9YU0xXSEVOX05PVF9QQVJFTlRFRF9CWV9YU0xDSE9PU0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9NSVNQTEFDRURfWFNMT1RIRVJXSVNFID0KLSAgICAgICAgICJFUl9NSVNQTEFDRURfWFNMT1RIRVJXSVNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWFNMT1RIRVJXSVNFX05PVF9QQVJFTlRFRF9CWV9YU0xDSE9PU0UgPQotICAgICAgICAgIkVSX1hTTE9USEVSV0lTRV9OT1RfUEFSRU5URURfQllfWFNMQ0hPT1NFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9UX0FMTE9XRURfSU5TSURFX1RFTVBMQVRFID0KLSAgICAgICAgICJFUl9OT1RfQUxMT1dFRF9JTlNJREVfVEVNUExBVEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTktOT1dOX0VYVF9OU19QUkVGSVggPQotICAgICAgICAgIkVSX1VOS05PV05fRVhUX05TX1BSRUZJWCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lNUE9SVFNfQVNfRklSU1RfRUxFTSA9Ci0gICAgICAgICAiRVJfSU1QT1JUU19BU19GSVJTVF9FTEVNIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU1QT1JUSU5HX0lUU0VMRiA9ICJFUl9JTVBPUlRJTkdfSVRTRUxGIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWE1MU1BBQ0VfSUxMRUdBTF9WQUwgPSJFUl9YTUxTUEFDRV9JTExFR0FMX1ZBTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BST0NFU1NTVFlMRVNIRUVUX05PVF9TVUNDRVNTRlVMID0KLSAgICAgICAgICJFUl9QUk9DRVNTU1RZTEVTSEVFVF9OT1RfU1VDQ0VTU0ZVTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NBWF9FWENFUFRJT04gPSAiRVJfU0FYX0VYQ0VQVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hTTFRfRVJST1IgPSAiRVJfWFNMVF9FUlJPUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NVUlJFTkNZX1NJR05fSUxMRUdBTD0KLSAgICAgICAgICJFUl9DVVJSRU5DWV9TSUdOX0lMTEVHQUwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9ET0NVTUVOVF9GVU5DVElPTl9JTlZBTElEX0lOX1NUWUxFU0hFRVRfRE9NID0KLSAgICAgICAgICJFUl9ET0NVTUVOVF9GVU5DVElPTl9JTlZBTElEX0lOX1NUWUxFU0hFRVRfRE9NIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9SRVNPTFZFX1BSRUZJWF9PRl9OT05fUFJFRklYX1JFU09MVkVSID0KLSAgICAgICAgICJFUl9DQU5UX1JFU09MVkVfUFJFRklYX09GX05PTl9QUkVGSVhfUkVTT0xWRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SRURJUkVDVF9DT1VMRE5UX0dFVF9GSUxFTkFNRSA9Ci0gICAgICAgICAiRVJfUkVESVJFQ1RfQ09VTEROVF9HRVRfRklMRU5BTUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfQlVJTERfRk9STUFUVEVSTElTVEVORVJfSU5fUkVESVJFQ1QgPQotICAgICAgICAgIkVSX0NBTk5PVF9CVUlMRF9GT1JNQVRURVJMSVNURU5FUl9JTl9SRURJUkVDVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfUFJFRklYX0lOX0VYQ0xVREVSRVNVTFRQUkVGSVggPQotICAgICAgICAgIkVSX0lOVkFMSURfUFJFRklYX0lOX0VYQ0xVREVSRVNVTFRQUkVGSVgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9NSVNTSU5HX05TX1VSSSA9ICJFUl9NSVNTSU5HX05TX1VSSSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01JU1NJTkdfQVJHX0ZPUl9PUFRJT04gPQotICAgICAgICAgIkVSX01JU1NJTkdfQVJHX0ZPUl9PUFRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX09QVElPTiA9ICJFUl9JTlZBTElEX09QVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01BTEZPUk1FRF9GT1JNQVRfU1RSSU5HID0KLSAgICAgICAgICJFUl9NQUxGT1JNRURfRk9STUFUX1NUUklORyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NUWUxFU0hFRVRfUkVRVUlSRVNfVkVSU0lPTl9BVFRSSUIgPQotICAgICAgICAgIkVSX1NUWUxFU0hFRVRfUkVRVUlSRVNfVkVSU0lPTl9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTExFR0FMX0FUVFJJQlVURV9WQUxVRSA9Ci0gICAgICAgICAiRVJfSUxMRUdBTF9BVFRSSUJVVEVfVkFMVUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DSE9PU0VfUkVRVUlSRVNfV0hFTiA9IkVSX0NIT09TRV9SRVFVSVJFU19XSEVOIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fQVBQTFlfSU1QT1JUX0lOX0ZPUl9FQUNIID0KLSAgICAgICAgICJFUl9OT19BUFBMWV9JTVBPUlRfSU5fRk9SX0VBQ0giOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX1VTRV9EVE1fRk9SX09VVFBVVCA9Ci0gICAgICAgICAiRVJfQ0FOVF9VU0VfRFRNX0ZPUl9PVVRQVVQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX1VTRV9EVE1fRk9SX0lOUFVUID0KLSAgICAgICAgICJFUl9DQU5UX1VTRV9EVE1fRk9SX0lOUFVUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FMTF9UT19FWFRfRkFJTEVEID0gIkVSX0NBTExfVE9fRVhUX0ZBSUxFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BSRUZJWF9NVVNUX1JFU09MVkUgPSAiRVJfUFJFRklYX01VU1RfUkVTT0xWRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfVVRGMTZfU1VSUk9HQVRFID0KLSAgICAgICAgICJFUl9JTlZBTElEX1VURjE2X1NVUlJPR0FURSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hTTEFUVFJTRVRfVVNFRF9JVFNFTEYgPQotICAgICAgICAgIkVSX1hTTEFUVFJTRVRfVVNFRF9JVFNFTEYiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfTUlYX1hFUkNFU0RPTSA9IkVSX0NBTk5PVF9NSVhfWEVSQ0VTRE9NIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVE9PX01BTllfTElTVEVORVJTID0gIkVSX1RPT19NQU5ZX0xJU1RFTkVSUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOX0VMRU1URU1QTEFURUVMRU1fUkVBRE9CSkVDVCA9Ci0gICAgICAgICAiRVJfSU5fRUxFTVRFTVBMQVRFRUxFTV9SRUFET0JKRUNUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRFVQTElDQVRFX05BTUVEX1RFTVBMQVRFID0KLSAgICAgICAgICJFUl9EVVBMSUNBVEVfTkFNRURfVEVNUExBVEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX0tFWV9DQUxMID0gIkVSX0lOVkFMSURfS0VZX0NBTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SRUZFUkVOQ0lOR19JVFNFTEYgPSAiRVJfUkVGRVJFTkNJTkdfSVRTRUxGIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSUxMRUdBTF9ET01TT1VSQ0VfSU5QVVQgPQotICAgICAgICAgIkVSX0lMTEVHQUxfRE9NU09VUkNFX0lOUFVUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0xBU1NfTk9UX0ZPVU5EX0ZPUl9PUFRJT04gPQotICAgICAgICAgIkVSX0NMQVNTX05PVF9GT1VORF9GT1JfT1BUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUkVRVUlSRURfRUxFTV9OT1RfRk9VTkQgPQotICAgICAgICAgIkVSX1JFUVVJUkVEX0VMRU1fTk9UX0ZPVU5EIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5QVVRfQ0FOTk9UX0JFX05VTEwgPSJFUl9JTlBVVF9DQU5OT1RfQkVfTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1VSSV9DQU5OT1RfQkVfTlVMTCA9ICJFUl9VUklfQ0FOTk9UX0JFX05VTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GSUxFX0NBTk5PVF9CRV9OVUxMID0gIkVSX0ZJTEVfQ0FOTk9UX0JFX05VTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TT1VSQ0VfQ0FOTk9UX0JFX05VTEwgPQotICAgICAgICAgIkVSX1NPVVJDRV9DQU5OT1RfQkVfTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9JTklUX0JTRk1HUiA9ICJFUl9DQU5OT1RfSU5JVF9CU0ZNR1IiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfQ01QTF9FWFRFTlNOID0gIkVSX0NBTk5PVF9DTVBMX0VYVEVOU04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfQ1JFQVRFX0VYVEVOU04gPQotICAgICAgICAgIkVSX0NBTk5PVF9DUkVBVEVfRVhURU5TTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOU1RBTkNFX01USERfQ0FMTF9SRVFVSVJFUyA9Ci0gICAgICAgICAiRVJfSU5TVEFOQ0VfTVRIRF9DQUxMX1JFUVVJUkVTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9FTEVNRU5UX05BTUUgPSJFUl9JTlZBTElEX0VMRU1FTlRfTkFNRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VMRU1FTlRfTkFNRV9NRVRIT0RfU1RBVElDID0KLSAgICAgICAgICJFUl9FTEVNRU5UX05BTUVfTUVUSE9EX1NUQVRJQyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYVEVOU0lPTl9GVU5DX1VOS05PV04gPQotICAgICAgICAgIkVSX0VYVEVOU0lPTl9GVU5DX1VOS05PV04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9NT1JFX01BVENIX0NPTlNUUlVDVE9SID0KLSAgICAgICAgICJFUl9NT1JFX01BVENIX0NPTlNUUlVDVE9SIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTU9SRV9NQVRDSF9NRVRIT0QgPSAiRVJfTU9SRV9NQVRDSF9NRVRIT0QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9NT1JFX01BVENIX0VMRU1FTlQgPSAiRVJfTU9SRV9NQVRDSF9FTEVNRU5UIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9DT05URVhUX1BBU1NFRCA9Ci0gICAgICAgICAiRVJfSU5WQUxJRF9DT05URVhUX1BBU1NFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BPT0xfRVhJU1RTID0gIkVSX1BPT0xfRVhJU1RTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fRFJJVkVSX05BTUUgPSAiRVJfTk9fRFJJVkVSX05BTUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19VUkwgPSAiRVJfTk9fVVJMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUE9PTF9TSVpFX0xFU1NUSEFOX09ORSA9Ci0gICAgICAgICAiRVJfUE9PTF9TSVpFX0xFU1NUSEFOX09ORSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfRFJJVkVSID0gIkVSX0lOVkFMSURfRFJJVkVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fU1RZTEVTSEVFVFJPT1QgPSAiRVJfTk9fU1RZTEVTSEVFVFJPT1QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTExFR0FMX1hNTFNQQUNFX1ZBTFVFID0KLSAgICAgICAgICJFUl9JTExFR0FMX1hNTFNQQUNFX1ZBTFVFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJPQ0VTU0ZST01OT0RFX0ZBSUxFRCA9Ci0gICAgICAgICAiRVJfUFJPQ0VTU0ZST01OT0RFX0ZBSUxFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1JFU09VUkNFX0NPVUxEX05PVF9MT0FEID0KLSAgICAgICAgICJFUl9SRVNPVVJDRV9DT1VMRF9OT1RfTE9BRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0JVRkZFUl9TSVpFX0xFU1NUSEFOX1pFUk8gPQotICAgICAgICAgIkVSX0JVRkZFUl9TSVpFX0xFU1NUSEFOX1pFUk8iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTktOT1dOX0VSUk9SX0NBTExJTkdfRVhURU5TSU9OID0KLSAgICAgICAgICJFUl9VTktOT1dOX0VSUk9SX0NBTExJTkdfRVhURU5TSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fTkFNRVNQQUNFX0RFQ0wgPSAiRVJfTk9fTkFNRVNQQUNFX0RFQ0wiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FTEVNX0NPTlRFTlRfTk9UX0FMTE9XRUQgPQotICAgICAgICAgIkVSX0VMRU1fQ09OVEVOVF9OT1RfQUxMT1dFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NUWUxFU0hFRVRfRElSRUNURURfVEVSTUlOQVRJT04gPQotICAgICAgICAgIkVSX1NUWUxFU0hFRVRfRElSRUNURURfVEVSTUlOQVRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9PTkVfT1JfVFdPID0gIkVSX09ORV9PUl9UV08iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9UV09fT1JfVEhSRUUgPSAiRVJfVFdPX09SX1RIUkVFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTERfTk9UX0xPQURfUkVTT1VSQ0UgPQotICAgICAgICAgIkVSX0NPVUxEX05PVF9MT0FEX1JFU09VUkNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX0lOSVRfREVGQVVMVF9URU1QTEFURVMgPQotICAgICAgICAgIkVSX0NBTk5PVF9JTklUX0RFRkFVTFRfVEVNUExBVEVTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUkVTVUxUX05VTEwgPSAiRVJfUkVTVUxUX05VTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SRVNVTFRfQ09VTERfTk9UX0JFX1NFVCA9Ci0gICAgICAgICAiRVJfUkVTVUxUX0NPVUxEX05PVF9CRV9TRVQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19PVVRQVVRfU1BFQ0lGSUVEID0gIkVSX05PX09VVFBVVF9TUEVDSUZJRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfVFJBTlNGT1JNX1RPX1JFU1VMVF9UWVBFID0KLSAgICAgICAgICJFUl9DQU5OT1RfVFJBTlNGT1JNX1RPX1JFU1VMVF9UWVBFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX1RSQU5TRk9STV9TT1VSQ0VfVFlQRSA9Ci0gICAgICAgICAiRVJfQ0FOTk9UX1RSQU5TRk9STV9TT1VSQ0VfVFlQRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05VTExfQ09OVEVOVF9IQU5ETEVSID0iRVJfTlVMTF9DT05URU5UX0hBTkRMRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OVUxMX0VSUk9SX0hBTkRMRVIgPSAiRVJfTlVMTF9FUlJPUl9IQU5ETEVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX0NBTExfUEFSU0UgPSAiRVJfQ0FOTk9UX0NBTExfUEFSU0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19QQVJFTlRfRk9SX0ZJTFRFUiA9IkVSX05PX1BBUkVOVF9GT1JfRklMVEVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fU1RZTEVTSEVFVF9JTl9NRURJQSA9Ci0gICAgICAgICAiRVJfTk9fU1RZTEVTSEVFVF9JTl9NRURJQSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1NUWUxFU0hFRVRfUEkgPSAiRVJfTk9fU1RZTEVTSEVFVF9QSSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PVF9TVVBQT1JURUQgPSAiRVJfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BST1BFUlRZX1ZBTFVFX0JPT0xFQU4gPQotICAgICAgICAgIkVSX1BST1BFUlRZX1ZBTFVFX0JPT0xFQU4iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRF9OT1RfRklORF9FWFRFUk5fU0NSSVBUID0KLSAgICAgICAgICJFUl9DT1VMRF9OT1RfRklORF9FWFRFUk5fU0NSSVBUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUkVTT1VSQ0VfQ09VTERfTk9UX0ZJTkQgPQotICAgICAgICAgIkVSX1JFU09VUkNFX0NPVUxEX05PVF9GSU5EIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfT1VUUFVUX1BST1BFUlRZX05PVF9SRUNPR05JWkVEID0KLSAgICAgICAgICJFUl9PVVRQVVRfUFJPUEVSVFlfTk9UX1JFQ09HTklaRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GQUlMRURfQ1JFQVRJTkdfRUxFTUxJVFJTTFQgPQotICAgICAgICAgIkVSX0ZBSUxFRF9DUkVBVElOR19FTEVNTElUUlNMVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1ZBTFVFX1NIT1VMRF9CRV9OVU1CRVIgPQotICAgICAgICAgIkVSX1ZBTFVFX1NIT1VMRF9CRV9OVU1CRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9WQUxVRV9TSE9VTERfRVFVQUwgPSAiRVJfVkFMVUVfU0hPVUxEX0VRVUFMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRkFJTEVEX0NBTExJTkdfTUVUSE9EID0KLSAgICAgICAgICJFUl9GQUlMRURfQ0FMTElOR19NRVRIT0QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GQUlMRURfQ1JFQVRJTkdfRUxFTVRNUEwgPQotICAgICAgICAgIkVSX0ZBSUxFRF9DUkVBVElOR19FTEVNVE1QTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NIQVJTX05PVF9BTExPV0VEID0gIkVSX0NIQVJTX05PVF9BTExPV0VEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQVRUUl9OT1RfQUxMT1dFRCA9ICJFUl9BVFRSX05PVF9BTExPV0VEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQkFEX1ZBTFVFID0gIkVSX0JBRF9WQUxVRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FUVFJJQl9WQUxVRV9OT1RfRk9VTkQgPQotICAgICAgICAgIkVSX0FUVFJJQl9WQUxVRV9OT1RfRk9VTkQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9BVFRSSUJfVkFMVUVfTk9UX1JFQ09HTklaRUQgPQotICAgICAgICAgIkVSX0FUVFJJQl9WQUxVRV9OT1RfUkVDT0dOSVpFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05VTExfVVJJX05BTUVTUEFDRSA9ICJFUl9OVUxMX1VSSV9OQU1FU1BBQ0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OVU1CRVJfVE9PX0JJRyA9ICJFUl9OVU1CRVJfVE9PX0JJRyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nICBFUl9DQU5OT1RfRklORF9TQVgxX0RSSVZFUiA9Ci0gICAgICAgICAiRVJfQ0FOTk9UX0ZJTkRfU0FYMV9EUklWRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyAgRVJfU0FYMV9EUklWRVJfTk9UX0xPQURFRCA9Ci0gICAgICAgICAiRVJfU0FYMV9EUklWRVJfTk9UX0xPQURFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nICBFUl9TQVgxX0RSSVZFUl9OT1RfSU5TVEFOVElBVEVEID0KLSAgICAgICAgICJFUl9TQVgxX0RSSVZFUl9OT1RfSU5TVEFOVElBVEVEIiA7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NBWDFfRFJJVkVSX05PVF9JTVBMRU1FTlRfUEFSU0VSID0KLSAgICAgICAgICJFUl9TQVgxX0RSSVZFUl9OT1RfSU1QTEVNRU5UX1BBUlNFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nICBFUl9QQVJTRVJfUFJPUEVSVFlfTk9UX1NQRUNJRklFRCA9Ci0gICAgICAgICAiRVJfUEFSU0VSX1BST1BFUlRZX05PVF9TUEVDSUZJRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyAgRVJfUEFSU0VSX0FSR19DQU5OT1RfQkVfTlVMTCA9Ci0gICAgICAgICAiRVJfUEFSU0VSX0FSR19DQU5OT1RfQkVfTlVMTCIgOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyAgRVJfRkVBVFVSRSA9ICJFUl9GRUFUVVJFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJPUEVSVFkgPSAiRVJfUFJPUEVSVFkiIDsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTlVMTF9FTlRJVFlfUkVTT0xWRVIgPSJFUl9OVUxMX0VOVElUWV9SRVNPTFZFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nICBFUl9OVUxMX0RURF9IQU5ETEVSID0gIkVSX05VTExfRFREX0hBTkRMRVIiIDsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fRFJJVkVSX05BTUVfU1BFQ0lGSUVEID0KLSAgICAgICAgICJFUl9OT19EUklWRVJfTkFNRV9TUEVDSUZJRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19VUkxfU1BFQ0lGSUVEID0gIkVSX05PX1VSTF9TUEVDSUZJRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QT09MU0laRV9MRVNTX1RIQU5fT05FID0KLSAgICAgICAgICJFUl9QT09MU0laRV9MRVNTX1RIQU5fT05FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9EUklWRVJfTkFNRSA9ICJFUl9JTlZBTElEX0RSSVZFUl9OQU1FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVJST1JMSVNURU5FUiA9ICJFUl9FUlJPUkxJU1RFTkVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQVNTRVJUX05PX1RFTVBMQVRFX1BBUkVOVCA9Ci0gICAgICAgICAiRVJfQVNTRVJUX05PX1RFTVBMQVRFX1BBUkVOVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FTU0VSVF9SRURVTkRFTlRfRVhQUl9FTElNSU5BVE9SID0KLSAgICAgICAgICJFUl9BU1NFUlRfUkVEVU5ERU5UX0VYUFJfRUxJTUlOQVRPUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PVF9BTExPV0VEX0lOX1BPU0lUSU9OID0KLSAgICAgICAgICJFUl9OT1RfQUxMT1dFRF9JTl9QT1NJVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PTldISVRFU1BBQ0VfTk9UX0FMTE9XRURfSU5fUE9TSVRJT04gPQotICAgICAgICAgIkVSX05PTldISVRFU1BBQ0VfTk9UX0FMTE9XRURfSU5fUE9TSVRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OQU1FU1BBQ0VfQ09OVEVYVF9OVUxMX05BTUVTUEFDRSA9Ci0gICAgICAgICAiRVJfTkFNRVNQQUNFX0NPTlRFWFRfTlVMTF9OQU1FU1BBQ0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OQU1FU1BBQ0VfQ09OVEVYVF9OVUxMX1BSRUZJWCA9Ci0gICAgICAgICAiRVJfTkFNRVNQQUNFX0NPTlRFWFRfTlVMTF9QUkVGSVgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YUEFUSF9SRVNPTFZFUl9OVUxMX1FOQU1FID0KLSAgICAgICAgICJFUl9YUEFUSF9SRVNPTFZFUl9OVUxMX1FOQU1FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWFBBVEhfUkVTT0xWRVJfTkVHQVRJVkVfQVJJVFkgPQotICAgICAgICAgIkVSX1hQQVRIX1JFU09MVkVSX05FR0FUSVZFX0FSSVRZIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSU5WQUxJRF9UQ0hBUiA9ICJJTlZBTElEX1RDSEFSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSU5WQUxJRF9RTkFNRSA9ICJJTlZBTElEX1FOQU1FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSU5WQUxJRF9FTlVNID0gIklOVkFMSURfRU5VTSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIElOVkFMSURfTk1UT0tFTiA9ICJJTlZBTElEX05NVE9LRU4iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBJTlZBTElEX05DTkFNRSA9ICJJTlZBTElEX05DTkFNRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIElOVkFMSURfQk9PTEVBTiA9ICJJTlZBTElEX0JPT0xFQU4iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBJTlZBTElEX05VTUJFUiA9ICJJTlZBTElEX05VTUJFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FSR19MSVRFUkFMID0gIkVSX0FSR19MSVRFUkFMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRFVQTElDQVRFX0dMT0JBTF9WQVIgPSJFUl9EVVBMSUNBVEVfR0xPQkFMX1ZBUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0RVUExJQ0FURV9WQVIgPSAiRVJfRFVQTElDQVRFX1ZBUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1RFTVBMQVRFX05BTUVfTUFUQ0ggPSAiRVJfVEVNUExBVEVfTkFNRV9NQVRDSCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfUFJFRklYID0gIkVSX0lOVkFMSURfUFJFRklYIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fQVRUUklCX1NFVCA9ICJFUl9OT19BVFRSSUJfU0VUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRlVOQ1RJT05fTk9UX0ZPVU5EID0KLSAgICAgICAgICJFUl9GVU5DVElPTl9OT1RfRk9VTkQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX0hBVkVfQ09OVEVOVF9BTkRfU0VMRUNUID0KLSAgICAgIkVSX0NBTlRfSEFWRV9DT05URU5UX0FORF9TRUxFQ1QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX1NFVF9QQVJBTV9WQUxVRSA9ICJFUl9JTlZBTElEX1NFVF9QQVJBTV9WQUxVRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NFVF9GRUFUVVJFX05VTExfTkFNRSA9Ci0gICAgICAgICJFUl9TRVRfRkVBVFVSRV9OVUxMX05BTUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9HRVRfRkVBVFVSRV9OVUxMX05BTUUgPQotICAgICAgICAiRVJfR0VUX0ZFQVRVUkVfTlVMTF9OQU1FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5TVVBQT1JURURfRkVBVFVSRSA9Ci0gICAgICAgICJFUl9VTlNVUFBPUlRFRF9GRUFUVVJFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhURU5TSU9OX0VMRU1FTlRfTk9UX0FMTE9XRURfSU5fU0VDVVJFX1BST0NFU1NJTkcgPQotICAgICAgICAiRVJfRVhURU5TSU9OX0VMRU1FTlRfTk9UX0FMTE9XRURfSU5fU0VDVVJFX1BST0NFU1NJTkciOwotCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0ZPVU5EX0NVUkxZQlJBQ0UgPSAiV0dfRk9VTkRfQ1VSTFlCUkFDRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0NPVU5UX0FUVFJJQl9NQVRDSEVTX05PX0FOQ0VTVE9SID0KLSAgICAgICAgICJXR19DT1VOVF9BVFRSSUJfTUFUQ0hFU19OT19BTkNFU1RPUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0VYUFJfQVRUUklCX0NIQU5HRURfVE9fU0VMRUNUID0KLSAgICAgICAgICJXR19FWFBSX0FUVFJJQl9DSEFOR0VEX1RPX1NFTEVDVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX05PX0xPQ0FMRV9JTl9GT1JNQVROVU1CRVIgPQotICAgICAgICAgIldHX05PX0xPQ0FMRV9JTl9GT1JNQVROVU1CRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19MT0NBTEVfTk9UX0ZPVU5EID0gIldHX0xPQ0FMRV9OT1RfRk9VTkQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19DQU5OT1RfTUFLRV9VUkxfRlJPTSA9IldHX0NBTk5PVF9NQUtFX1VSTF9GUk9NIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfQ0FOTk9UX0xPQURfUkVRVUVTVEVEX0RPQyA9Ci0gICAgICAgICAiV0dfQ0FOTk9UX0xPQURfUkVRVUVTVEVEX0RPQyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0NBTk5PVF9GSU5EX0NPTExBVE9SID0iV0dfQ0FOTk9UX0ZJTkRfQ09MTEFUT1IiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19GVU5DVElPTlNfU0hPVUxEX1VTRV9VUkwgPQotICAgICAgICAgIldHX0ZVTkNUSU9OU19TSE9VTERfVVNFX1VSTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0VOQ09ESU5HX05PVF9TVVBQT1JURURfVVNJTkdfVVRGOCA9Ci0gICAgICAgICAiV0dfRU5DT0RJTkdfTk9UX1NVUFBPUlRFRF9VU0lOR19VVEY4IjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfRU5DT0RJTkdfTk9UX1NVUFBPUlRFRF9VU0lOR19KQVZBID0KLSAgICAgICAgICJXR19FTkNPRElOR19OT1RfU1VQUE9SVEVEX1VTSU5HX0pBVkEiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19TUEVDSUZJQ0lUWV9DT05GTElDVFMgPQotICAgICAgICAgIldHX1NQRUNJRklDSVRZX0NPTkZMSUNUUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX1BBUlNJTkdfQU5EX1BSRVBBUklORyA9Ci0gICAgICAgICAiV0dfUEFSU0lOR19BTkRfUFJFUEFSSU5HIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfQVRUUl9URU1QTEFURSA9ICJXR19BVFRSX1RFTVBMQVRFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfQ09ORkxJQ1RfQkVUV0VFTl9YU0xTVFJJUFNQQUNFX0FORF9YU0xQUkVTRVJWRVNQQUNFID0gIldHX0NPTkZMSUNUX0JFVFdFRU5fWFNMU1RSSVBTUEFDRV9BTkRfWFNMUFJFU0VSVkVTUCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0FUVFJJQl9OT1RfSEFORExFRCA9ICJXR19BVFRSSUJfTk9UX0hBTkRMRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19OT19ERUNJTUFMRk9STUFUX0RFQ0xBUkFUSU9OID0KLSAgICAgICAgICJXR19OT19ERUNJTUFMRk9STUFUX0RFQ0xBUkFUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfT0xEX1hTTFRfTlMgPSAiV0dfT0xEX1hTTFRfTlMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19PTkVfREVGQVVMVF9YU0xERUNJTUFMRk9STUFUX0FMTE9XRUQgPQotICAgICAgICAgIldHX09ORV9ERUZBVUxUX1hTTERFQ0lNQUxGT1JNQVRfQUxMT1dFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX1hTTERFQ0lNQUxGT1JNQVRfTkFNRVNfTVVTVF9CRV9VTklRVUUgPQotICAgICAgICAgIldHX1hTTERFQ0lNQUxGT1JNQVRfTkFNRVNfTVVTVF9CRV9VTklRVUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19JTExFR0FMX0FUVFJJQlVURSA9ICJXR19JTExFR0FMX0FUVFJJQlVURSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0NPVUxEX05PVF9SRVNPTFZFX1BSRUZJWCA9Ci0gICAgICAgICAiV0dfQ09VTERfTk9UX1JFU09MVkVfUFJFRklYIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfU1RZTEVTSEVFVF9SRVFVSVJFU19WRVJTSU9OX0FUVFJJQiA9Ci0gICAgICAgICAiV0dfU1RZTEVTSEVFVF9SRVFVSVJFU19WRVJTSU9OX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0lMTEVHQUxfQVRUUklCVVRFX05BTUUgPQotICAgICAgICAgIldHX0lMTEVHQUxfQVRUUklCVVRFX05BTUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19JTExFR0FMX0FUVFJJQlVURV9WQUxVRSA9Ci0gICAgICAgICAiV0dfSUxMRUdBTF9BVFRSSUJVVEVfVkFMVUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19FTVBUWV9TRUNPTkRfQVJHID0gIldHX0VNUFRZX1NFQ09ORF9BUkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19QUk9DRVNTSU5HSU5TVFJVQ1RJT05fTkFNRV9DQU5UX0JFX1hNTCA9Ci0gICAgICAgICAiV0dfUFJPQ0VTU0lOR0lOU1RSVUNUSU9OX05BTUVfQ0FOVF9CRV9YTUwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19QUk9DRVNTSU5HSU5TVFJVQ1RJT05fTk9UVkFMSURfTkNOQU1FID0KLSAgICAgICAgICJXR19QUk9DRVNTSU5HSU5TVFJVQ1RJT05fTk9UVkFMSURfTkNOQU1FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfSUxMRUdBTF9BVFRSSUJVVEVfUE9TSVRJT04gPQotICAgICAgICAgIldHX0lMTEVHQUxfQVRUUklCVVRFX1BPU0lUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSID0KLSAgICAgICAgICJOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIiOwotCi0gIC8qCi0gICAqIE5vdyBmaWxsIGluIHRoZSBtZXNzYWdlIHRleHQuCi0gICAqIFRoZW4gZmlsbCBpbiB0aGUgbWVzc2FnZSB0ZXh0IGZvciB0aGF0IG1lc3NhZ2UgY29kZSBpbiB0aGUKLSAgICogYXJyYXkuIFVzZSB0aGUgbmV3IGVycm9yIGNvZGUgYXMgdGhlIGluZGV4IGludG8gdGhlIGFycmF5LgotICAgKi8KLQotICAvLyBFcnJvciBtZXNzYWdlcy4uLgotCi0gIC8qKiBHZXQgdGhlIGxvb2t1cCB0YWJsZSBmb3IgZXJyb3IgbWVzc2FnZXMuCi0gICAgKgotICAgICogQHJldHVybiBUaGUgbWVzc2FnZSBsb29rdXAgdGFibGUuCi0gICAgKi8KLSAgcHVibGljIE9iamVjdFtdW10gZ2V0Q29udGVudHMoKQotICB7Ci0gICAgICByZXR1cm4gbmV3IE9iamVjdFtdW10gewotCi0gIC8qKiBFcnJvciBtZXNzYWdlIElEIHRoYXQgaGFzIGEgbnVsbCBtZXNzYWdlLCBidXQgdGFrZXMgaW4gYSBzaW5nbGUgb2JqZWN0LiAgICAqLwotICB7IkVSMDAwMCIgLCAiezB9IiB9LAotCi0gICAgeyBFUl9OT19DVVJMWUJSQUNFLAotICAgICAgIlx1QzYyNFx1Qjk1ODogXHVENDVDXHVENjA0XHVDMkREXHVDNUQwXHVCMjk0ICd7J1x1QUMwMCBcdUQzRUNcdUQ1NjhcdUI0MjAgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAgIHsgRVJfSUxMRUdBTF9BVFRSSUJVVEUgLAotICAgICAiezB9XHVDNUQwIFx1Qzc5OFx1QkFCQlx1QjQxQyBcdUMxOERcdUMxMzFcdUM3NzQgXHVDNzg4XHVDNzRDOiB7MX0ifSwKLQotICB7RVJfTlVMTF9TT1VSQ0VOT0RFX0FQUExZSU1QT1JUUyAsCi0gICAgICAieHNsOmFwcGx5LWltcG9ydHNcdUM3NTggc291cmNlTm9kZVx1QUMwMCBcdUIxMTBcdUM3ODVcdUIyQzhcdUIyRTQhIn0sCi0KLSAge0VSX0NBTk5PVF9BREQsCi0gICAgICAiezF9XHVDNUQwIHswfVx1Qzc0NChcdUI5N0MpIFx1Q0Q5NFx1QUMwMFx1RDU2MCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBFUl9OVUxMX1NPVVJDRU5PREVfSEFORExFQVBQTFlURU1QTEFURVMsCi0gICAgICAiaGFuZGxlQXBwbHlUZW1wbGF0ZXNJbnN0cnVjdGlvblx1Qzc1OCBzb3VyY2VOb2RlXHVBQzAwIFx1QjExMFx1Qzc4NVx1QjJDOFx1QjJFNCEifSwKLQotICAgIHsgRVJfTk9fTkFNRV9BVFRSSUIsCi0gICAgICJ7MH1cdUM1RDBcdUIyOTQgbmFtZSBcdUMxOERcdUMxMzFcdUM3NzQgXHVDNzg4XHVDNUI0XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4ifSwKLQotICAgIHtFUl9URU1QTEFURV9OT1RfRk9VTkQsCi0gICAgICJcdUJBODVcdUJBODVcdUI0MUMgXHVEMTVDXHVENTBDXHVCOUFDXHVEMkI4XHVCOTdDIFx1Q0MzRVx1Qzc0NCBcdUMyMTggXHVDNUM2XHVDNzRDOiB7MH0ifSwKLQotICAgIHtFUl9DQU5UX1JFU09MVkVfTkFNRV9BVlQsCi0gICAgICAieHNsOmNhbGwtdGVtcGxhdGVcdUM1RDBcdUMxMUMgXHVDNzc0XHVCOTg0IEFWVFx1Qjk3QyBcdUJEODRcdUMxMURcdUQ1NjAgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAgIHtFUl9SRVFVSVJFU19BVFRSSUIsCi0gICAgICJ7MH1cdUM1RDAgXHVDMThEXHVDMTMxXHVDNzc0IFx1RDU0NFx1QzY5NFx1RDU2ODogezF9In0sCi0KLSAgICB7IEVSX01VU1RfSEFWRV9URVNUX0FUVFJJQiwKLSAgICAgICJ7MH1cdUM1RDBcdUIyOTQgJyd0ZXN0JycgXHVDMThEXHVDMTMxXHVDNzc0IFx1Qzc4OFx1QzVCNFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICB7RVJfQkFEX1ZBTF9PTl9MRVZFTF9BVFRSSUIsCi0gICAgICAibGV2ZWwgXHVDMThEXHVDMTMxXHVDNUQwIFx1Qzc5OFx1QkFCQlx1QjQxQyBcdUFDMTJcdUM3NzQgXHVDNzg4XHVDNzRDOiB7MH0ifSwKLQotICAgIHtFUl9QUk9DRVNTSU5HSU5TVFJVQ1RJT05fTkFNRV9DQU5UX0JFX1hNTCwKLSAgICAgICJwcm9jZXNzaW5nLWluc3RydWN0aW9uIFx1Qzc3NFx1Qjk4NFx1Qzc0MCAneG1sJ1x1Qzc3QyBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBFUl9QUk9DRVNTSU5HSU5TVFJVQ1RJT05fTk9UVkFMSURfTkNOQU1FLAotICAgICAgInByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24gXHVDNzc0XHVCOTg0XHVDNzQwIFx1QzgwMVx1RDU2OVx1RDU1QyBOQ05hbWVcdUM3NzRcdUM1QjRcdUM1N0MgXHVENTY4OiB7MH0ifSwKLQotICAgIHsgRVJfTkVFRF9NQVRDSF9BVFRSSUIsCi0gICAgICAiezB9XHVDNUQwIFx1QkFBOFx1QjREQ1x1QUMwMCBcdUM3ODhcdUM3NDQgXHVBQ0JEXHVDNkIwIG1hdGNoIFx1QzE4RFx1QzEzMVx1Qzc3NCBcdUM3ODhcdUM1QjRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBFUl9ORUVEX05BTUVfT1JfTUFUQ0hfQVRUUklCLAotICAgICAgInswfVx1QzVEMFx1QjI5NCBuYW1lIFx1QjYxMFx1QjI5NCBtYXRjaCBcdUMxOERcdUMxMzFcdUM3NzQgXHVENTQ0XHVDNjk0XHVENTY5XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAge0VSX0NBTlRfUkVTT0xWRV9OU1BSRUZJWCwKLSAgICAgICJcdUIxMjRcdUM3ODRcdUMyQTRcdUQzOThcdUM3NzRcdUMyQTQgXHVDODExXHVCNDUwXHVDNUI0XHVCOTdDIFx1QkQ4NFx1QzExRFx1RDU2MCBcdUMyMTggXHVDNUM2XHVDNzRDOiB7MH0ifSwKLQotICAgIHsgRVJfSUxMRUdBTF9WQUxVRSwKLSAgICAgInhtbDpzcGFjZVx1QzVEMCBcdUM3OThcdUJBQkJcdUI0MUMgXHVBQzEyXHVDNzc0IFx1Qzc4OFx1Qzc0QzogezB9In0sCi0KLSAgICB7IEVSX05PX09XTkVSRE9DLAotICAgICAgIlx1RDU1OFx1QzcwNCBcdUIxNzhcdUI0RENcdUM1RDAgXHVDMThDXHVDNzIwXHVDNzkwIFx1QkIzOFx1QzExQ1x1QUMwMCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQhIn0sCi0KLSAgICB7IEVSX0VMRU1URU1QTEFURUVMRU1fRVJSLAotICAgICAiRWxlbVRlbXBsYXRlRWxlbWVudCBcdUM2MjRcdUI5NTg6IHswfSJ9LAotCi0gICAgeyBFUl9OVUxMX0NISUxELAotICAgICAiXHVCMTEwIFx1RDU1OFx1QzcwNFx1Qjk3QyBcdUNEOTRcdUFDMDBcdUQ1NThcdUI4MjRcdUFDRTAgXHVDMkRDXHVCM0M0XHVENTU4XHVCMjk0IFx1QzkxMVx1Qzc4NVx1QjJDOFx1QjJFNCEifSwKLQotICAgIHsgRVJfTkVFRF9TRUxFQ1RfQVRUUklCLAotICAgICAiezB9XHVDNUQwXHVCMjk0IHNlbGVjdCBcdUMxOERcdUMxMzFcdUM3NzQgXHVENTQ0XHVDNjk0XHVENTY5XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBFUl9ORUVEX1RFU1RfQVRUUklCICwKLSAgICAgICJ4c2w6d2hlblx1QzVEMFx1QjI5NCAndGVzdCcgXHVDMThEXHVDMTMxXHVDNzc0IFx1Qzc4OFx1QzVCNFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICB7IEVSX05FRURfTkFNRV9BVFRSSUIsCi0gICAgICAieHNsOndpdGgtcGFyYW1cdUM1RDBcdUIyOTQgJ25hbWUnIFx1QzE4RFx1QzEzMVx1Qzc3NCBcdUM3ODhcdUM1QjRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBFUl9OT19DT05URVhUX09XTkVSRE9DLAotICAgICAgIlx1Q0VFOFx1RDE0RFx1QzJBNFx1RDJCOFx1QzVEMCBcdUMxOENcdUM3MjBcdUM3OTAgXHVCQjM4XHVDMTFDXHVBQzAwIFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNCEifSwKLQotICAgIHtFUl9DT1VMRF9OT1RfQ1JFQVRFX1hNTF9QUk9DX0xJQUlTT04sCi0gICAgICAiWE1MIFRyYW5zZm9ybWVyRmFjdG9yeSBcdUM1RjBcdUFDQjBcdUM3NDQgXHVDMEREXHVDMTMxXHVENTYwIFx1QzIxOCBcdUM1QzZcdUM3NEM6IHswfSJ9LAotCi0gICAge0VSX1BST0NFU1NfTk9UX1NVQ0NFU1NGVUwsCi0gICAgICAiWGFsYW46IFx1RDUwNFx1Qjg1Q1x1QzEzOFx1QzJBNFx1Qjk3QyBcdUMyRTRcdUQzMjhcdUQ1ODhcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICB7IEVSX05PVF9TVUNDRVNTRlVMLAotICAgICAiWGFsYW46IFx1QzJFNFx1RDMyOFx1RDU4OFx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAgIHsgRVJfRU5DT0RJTkdfTk9UX1NVUFBPUlRFRCwKLSAgICAgIlx1Qzc3OFx1Q0Y1NFx1QjUyOVx1Qzc3NCBcdUM5QzBcdUM2RDBcdUI0MThcdUM5QzAgXHVDNTRBXHVDNzRDOiB7MH0ifSwKLQotICAgIHtFUl9DT1VMRF9OT1RfQ1JFQVRFX1RSQUNFTElTVEVORVIsCi0gICAgICAiVHJhY2VMaXN0ZW5lclx1Qjk3QyBcdUMwRERcdUMxMzFcdUQ1NjAgXHVDMjE4IFx1QzVDNlx1Qzc0QzogezB9In0sCi0KLSAgICB7RVJfS0VZX1JFUVVJUkVTX05BTUVfQVRUUklCLAotICAgICAgInhzbDprZXlcdUM1RDBcdUIyOTQgJ25hbWUnIFx1QzE4RFx1QzEzMVx1Qzc3NCBcdUQ1NDRcdUM2OTRcdUQ1NjlcdUIyQzhcdUIyRTQhIn0sCi0KLSAgICB7IEVSX0tFWV9SRVFVSVJFU19NQVRDSF9BVFRSSUIsCi0gICAgICAieHNsOmtleVx1QzVEMFx1QjI5NCAnbWF0Y2gnIFx1QzE4RFx1QzEzMVx1Qzc3NCBcdUQ1NDRcdUM2OTRcdUQ1NjlcdUIyQzhcdUIyRTQhIn0sCi0KLSAgICB7IEVSX0tFWV9SRVFVSVJFU19VU0VfQVRUUklCLAotICAgICAgInhzbDprZXlcdUM1RDBcdUIyOTQgJ3VzZScgXHVDMThEXHVDMTMxXHVDNzc0IFx1RDU0NFx1QzY5NFx1RDU2OVx1QjJDOFx1QjJFNCEifSwKLQotICAgIHsgRVJfUkVRVUlSRVNfRUxFTUVOVFNfQVRUUklCLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgezB9XHVDNUQwXHVCMjk0ICcnZWxlbWVudHMnJyBcdUMxOERcdUMxMzFcdUM3NzQgXHVENTQ0XHVDNjk0XHVENTY5XHVCMkM4XHVCMkU0ISJ9LAotCi0gICAgeyBFUl9NSVNTSU5HX1BSRUZJWF9BVFRSSUIsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSB7MH0gXHVDMThEXHVDMTMxICcncHJlZml4JydcdUFDMDAgXHVCMjA0XHVCNzdEXHVCNDE4XHVDNUM4XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBFUl9CQURfU1RZTEVTSEVFVF9VUkwsCi0gICAgICJcdUMyQTRcdUQwQzBcdUM3N0NcdUMyRENcdUQyQjggVVJMXHVDNzc0IFx1Qzc5OFx1QkFCQlx1QjQyODogezB9In0sCi0KLSAgICB7IEVSX0ZJTEVfTk9UX0ZPVU5ELAotICAgICAiXHVDMkE0XHVEMEMwXHVDNzdDXHVDMkRDXHVEMkI4IFx1RDMwQ1x1Qzc3Q1x1Qzc0NCBcdUNDM0VcdUM3NDQgXHVDMjE4IFx1QzVDNlx1Qzc0QzogezB9In0sCi0KLSAgICB7IEVSX0lPRVhDRVBUSU9OLAotICAgICAgIlx1QzJBNFx1RDBDMFx1Qzc3Q1x1QzJEQ1x1RDJCOCBcdUQzMENcdUM3N0NcdUM1RDAgSU8gXHVDNjA4XHVDNjc4XHVDMEFDXHVENTZEIFx1QkMxQ1x1QzBERDogezB9In0sCi0KLSAgICB7IEVSX05PX0hSRUZfQVRUUklCLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgezB9XHVDNUQwIFx1QjMwMFx1RDU1QyBocmVmIFx1QzE4RFx1QzEzMVx1Qzc0NCBcdUNDM0VcdUM3NDQgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAgIHsgRVJfU1RZTEVTSEVFVF9JTkNMVURFU19JVFNFTEYsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSB7MH1cdUM1RDAgXHVDOUMxXHVDODExIFx1QjYxMFx1QjI5NCBcdUFDMDRcdUM4MTFcdUM4MDFcdUM3M0NcdUI4NUMgXHVDNzkwXHVDMkUwXHVDNzc0IFx1RDNFQ1x1RDU2OFx1QjQxOFx1QzVCNCBcdUM3ODhcdUMyQjVcdUIyQzhcdUIyRTQhIn0sCi0KLSAgICB7IEVSX1BST0NFU1NJTkNMVURFX0VSUk9SLAotICAgICAgIlN0eWxlc2hlZXRIYW5kbGVyLnByb2Nlc3NJbmNsdWRlIFx1QzYyNFx1Qjk1OCwgezB9In0sCi0KLSAgICB7IEVSX01JU1NJTkdfTEFOR19BVFRSSUIsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSB7MH0gXHVDMThEXHVDMTMxICcnbGFuZycnXHVBQzAwIFx1QjIwNFx1Qjc3RFx1QjQxOFx1QzVDOFx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAgIHsgRVJfTUlTU0lOR19DT05UQUlORVJfRUxFTUVOVF9DT01QT05FTlQsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSB7MH0gXHVDNjk0XHVDMThDXHVDNzU4IFx1QzcwNFx1Q0U1OFx1QUMwMCBcdUM3OThcdUJBQkJcdUI0MUMgXHVBQzgzIFx1QUMxOVx1QzJCNVx1QjJDOFx1QjJFNC4gXHVDRUU4XHVEMTRDXHVDNzc0XHVCMTA4IFx1QzY5NFx1QzE4QyAnJ2NvbXBvbmVudCcnXHVBQzAwIFx1QjIwNFx1Qjc3RFx1QjQxOFx1QzVDOFx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAgIHsgRVJfQ0FOX09OTFlfT1VUUFVUX1RPX0VMRU1FTlQsCi0gICAgICAiRWxlbWVudCwgRG9jdW1lbnRGcmFnbWVudCwgRG9jdW1lbnQgXHVCNjEwXHVCMjk0IFByaW50V3JpdGVyXHVDNUQwXHVCOUNDIFx1Q0Q5Q1x1QjgyNVx1RDU2MCBcdUMyMTggXHVDNzg4XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBFUl9QUk9DRVNTX0VSUk9SLAotICAgICAiU3R5bGVzaGVldFJvb3QucHJvY2VzcyBcdUM2MjRcdUI5NTgifSwKLQotICAgIHsgRVJfVU5JTVBMTk9ERV9FUlJPUiwKLSAgICAgIlVuSW1wbE5vZGUgXHVDNjI0XHVCOTU4OiB7MH0ifSwKLQotICAgIHsgRVJfTk9fU0VMRUNUX0VYUFJFU1NJT04sCi0gICAgICAiXHVDNjI0XHVCOTU4OiB4cGF0aCBzZWxlY3QgXHVENDVDXHVENjA0XHVDMkREKC1zZWxlY3QpXHVDNzQ0IFx1Q0MzRVx1Qzc0NCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBFUl9DQU5OT1RfU0VSSUFMSVpFX1hTTFBST0NFU1NPUiwKLSAgICAgICJYU0xQcm9jZXNzb3JcdUI5N0MgXHVDOUMxXHVCODJDXHVENjU0XHVENTYwIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQhIn0sCi0KLSAgICB7IEVSX05PX0lOUFVUX1NUWUxFU0hFRVQsCi0gICAgICAiXHVDMkE0XHVEMEMwXHVDNzdDXHVDMkRDXHVEMkI4IFx1Qzc4NVx1QjgyNVx1QUMxMlx1Qzc3NCBcdUM5QzBcdUM4MTVcdUI0MThcdUM5QzAgXHVDNTRBXHVDNTU4XHVDMkI1XHVCMkM4XHVCMkU0ISJ9LAotCi0gICAgeyBFUl9GQUlMRURfUFJPQ0VTU19TVFlMRVNIRUVULAotICAgICAgIlx1QzJBNFx1RDBDMFx1Qzc3Q1x1QzJEQ1x1RDJCOCBcdUNDOThcdUI5QUNcdUI5N0MgXHVDMkU0XHVEMzI4XHVENTg4XHVDMkI1XHVCMkM4XHVCMkU0ISJ9LAotCi0gICAgeyBFUl9DT1VMRE5UX1BBUlNFX0RPQywKLSAgICAgInswfSBcdUJCMzhcdUMxMUNcdUM3NTggXHVBRDZDXHVCQjM4XHVDNzQ0IFx1QkQ4NFx1QzExRFx1RDU2MCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0ISJ9LAotCi0gICAgeyBFUl9DT1VMRE5UX0ZJTkRfRlJBR01FTlQsCi0gICAgICJcdUJEODBcdUJEODRcdUM3NDQgXHVDQzNFXHVDNzQ0IFx1QzIxOCBcdUM1QzZcdUM3NEM6IHswfSJ9LAotCi0gICAgeyBFUl9OT0RFX05PVF9FTEVNRU5ULAotICAgICAgIlx1QkQ4MFx1QkQ4NCBcdUMyRERcdUJDQzRcdUM3OTBcdUFDMDAgXHVBQzAwXHVCOUFDXHVEMEE4IFx1QjE3OFx1QjREQ1x1QjI5NCBcdUM2OTRcdUMxOENcdUFDMDAgXHVDNTQ0XHVCMkQ4OiB7MH0ifSwKLQotICAgIHsgRVJfRk9SRUFDSF9ORUVEX01BVENIX09SX05BTUVfQVRUUklCLAotICAgICAgImZvci1lYWNoXHVDNUQwXHVCMjk0IG1hdGNoIFx1QjYxMFx1QjI5NCBuYW1lIFx1QzE4RFx1QzEzMVx1Qzc3NCBcdUM3ODhcdUM1QjRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBFUl9URU1QTEFURVNfTkVFRF9NQVRDSF9PUl9OQU1FX0FUVFJJQiwKLSAgICAgICJ0ZW1wbGF0ZXNcdUM1RDBcdUIyOTQgbWF0Y2ggXHVCNjEwXHVCMjk0IG5hbWUgXHVDMThEXHVDMTMxXHVDNzc0IFx1Qzc4OFx1QzVCNFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICB7IEVSX05PX0NMT05FX09GX0RPQ1VNRU5UX0ZSQUcsCi0gICAgICAiXHVCQjM4XHVDMTFDIFx1QkQ4MFx1QkQ4NFx1Qzc1OCBcdUJDRjVcdUM4MUNcdUJDRjhcdUM3NzQgXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0ISJ9LAotCi0gICAgeyBFUl9DQU5UX0NSRUFURV9JVEVNLAotICAgICAgIlx1QUNCMFx1QUNGQyBcdUQyQjhcdUI5QUNcdUM1RDAgXHVENTZEXHVCQUE5XHVDNzQ0IFx1QzBERFx1QzEzMVx1RDU2MCBcdUMyMTggXHVDNUM2XHVDNzRDOiB7MH0ifSwKLQotICAgIHsgRVJfWE1MU1BBQ0VfSUxMRUdBTF9WQUxVRSwKLSAgICAgICJcdUMxOENcdUMyQTQgWE1MXHVDNzU4IHhtbDpzcGFjZVx1QzVEMCBcdUM3OThcdUJBQkJcdUI0MUMgXHVBQzEyXHVDNzc0IFx1Qzc4OFx1Qzc0QzogezB9In0sCi0KLSAgICB7IEVSX05PX1hTTEtFWV9ERUNMQVJBVElPTiwKLSAgICAgICJ7MH1cdUM1RDAgXHVCMzAwXHVENTVDIHhzbDprZXkgXHVDMTIwXHVDNUI4XHVDNzc0IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNCEifSwKLQotICAgIHsgRVJfQ0FOVF9DUkVBVEVfVVJMLAotICAgICAiXHVDNjI0XHVCOTU4OiB7MH1cdUM1RDAgXHVCMzAwXHVENTVDIFVSTFx1Qzc0NCBcdUMwRERcdUMxMzFcdUQ1NjAgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAgIHsgRVJfWFNMRlVOQ1RJT05TX1VOU1VQUE9SVEVELAotICAgICAieHNsOmZ1bmN0aW9uc1x1QjI5NCBcdUM5QzBcdUM2RDBcdUI0MThcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBFUl9QUk9DRVNTT1JfRVJST1IsCi0gICAgICJYU0xUIFRyYW5zZm9ybWVyRmFjdG9yeSBcdUM2MjRcdUI5NTgifSwKLQotICAgIHsgRVJfTk9UX0FMTE9XRURfSU5TSURFX1NUWUxFU0hFRVQsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSBcdUMyQTRcdUQwQzBcdUM3N0NcdUMyRENcdUQyQjhcdUM1RDBcdUMxMUNcdUIyOTQgezB9XHVDNzc0KFx1QUMwMCkgXHVENUM4XHVDNkE5XHVCNDE4XHVDOUMwIFx1QzU0QVx1QzJCNVx1QjJDOFx1QjJFNCEifSwKLQotICAgIHsgRVJfUkVTVUxUTlNfTk9UX1NVUFBPUlRFRCwKLSAgICAgICJyZXN1bHQtbnNcdUIyOTQgXHVCMzU0IFx1Qzc3NFx1QzBDMSBcdUM5QzBcdUM2RDBcdUI0MThcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0ISBcdUIzMDBcdUMyRTAgeHNsOm91dHB1dFx1Qzc0NCBcdUMwQUNcdUM2QTlcdUQ1NThcdUMyRURcdUMyRENcdUM2MjQuIn0sCi0KLSAgICB7IEVSX0RFRkFVTFRTUEFDRV9OT1RfU1VQUE9SVEVELAotICAgICAgImRlZmF1bHQtc3BhY2VcdUIyOTQgXHVCMzU0IFx1Qzc3NFx1QzBDMSBcdUM5QzBcdUM2RDBcdUI0MThcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0ISBcdUIzMDBcdUMyRTAgeHNsOnN0cmlwLXNwYWNlIFx1QjYxMFx1QjI5NCB4c2w6cHJlc2VydmUtc3BhY2VcdUI5N0MgXHVDMEFDXHVDNkE5XHVENTU4XHVDMkVEXHVDMkRDXHVDNjI0LiJ9LAotCi0gICAgeyBFUl9JTkRFTlRSRVNVTFRfTk9UX1NVUFBPUlRFRCwKLSAgICAgICJpbmRlbnQtcmVzdWx0XHVCMjk0IFx1QjM1NCBcdUM3NzRcdUMwQzEgXHVDOUMwXHVDNkQwXHVCNDE4XHVDOUMwIFx1QzU0QVx1QzJCNVx1QjJDOFx1QjJFNCEgXHVCMzAwXHVDMkUwIHhzbDpvdXRwdXRcdUM3NDQgXHVDMEFDXHVDNkE5XHVENTU4XHVDMkVEXHVDMkRDXHVDNjI0LiJ9LAotCi0gICAgeyBFUl9JTExFR0FMX0FUVFJJQiwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIHswfVx1QzVEMCBcdUM3OThcdUJBQkJcdUI0MUMgXHVDMThEXHVDMTMxXHVDNzc0IFx1Qzc4OFx1Qzc0QzogezF9In0sCi0KLSAgICB7IEVSX1VOS05PV05fWFNMX0VMRU0sCi0gICAgICJcdUM1NEMgXHVDMjE4IFx1QzVDNlx1QjI5NCBYU0wgXHVDNjk0XHVDMThDOiB7MH0ifSwKLQotICAgIHsgRVJfQkFEX1hTTFNPUlRfVVNFLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgeHNsOnNvcnRcdUIyOTQgeHNsOmFwcGx5LXRlbXBsYXRlcyBcdUI2MTBcdUIyOTQgeHNsOmZvci1lYWNoXHVDNjQwIFx1RDU2OFx1QUVEOFx1QjlDQyBcdUMwQUNcdUM2QTlcdUQ1NjAgXHVDMjE4IFx1Qzc4OFx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAgIHsgRVJfTUlTUExBQ0VEX1hTTFdIRU4sCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSB4c2w6d2hlblx1Qzc1OCBcdUM3MDRcdUNFNThcdUFDMDAgXHVDNzk4XHVCQUJCXHVCNDE4XHVDNUM4XHVDMkI1XHVCMkM4XHVCMkU0ISJ9LAotCi0gICAgeyBFUl9YU0xXSEVOX05PVF9QQVJFTlRFRF9CWV9YU0xDSE9PU0UsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSB4c2w6d2hlblx1Qzc3NCB4c2w6Y2hvb3NlXHVDNUQwIFx1Qzc1OFx1RDU3NCBcdUMwQzFcdUM3MDRcdUI4NUMgXHVDOUMwXHVDODE1XHVCNDE4XHVDOUMwIFx1QzU0QVx1QzU1OFx1QzJCNVx1QjJDOFx1QjJFNCEifSwKLQotICAgIHsgRVJfTUlTUExBQ0VEX1hTTE9USEVSV0lTRSwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIHhzbDpvdGhlcndpc2VcdUM3NTggXHVDNzA0XHVDRTU4XHVBQzAwIFx1Qzc5OFx1QkFCQlx1QjQxOFx1QzVDOFx1QzJCNVx1QjJDOFx1QjJFNCEifSwKLQotICAgIHsgRVJfWFNMT1RIRVJXSVNFX05PVF9QQVJFTlRFRF9CWV9YU0xDSE9PU0UsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSB4c2w6b3RoZXJ3aXNlXHVBQzAwIHhzbDpjaG9vc2VcdUM1RDAgXHVDNzU4XHVENTc0IFx1QzBDMVx1QzcwNFx1Qjg1QyBcdUM5QzBcdUM4MTVcdUI0MThcdUM5QzAgXHVDNTRBXHVDNTU4XHVDMkI1XHVCMkM4XHVCMkU0ISJ9LAotCi0gICAgeyBFUl9OT1RfQUxMT1dFRF9JTlNJREVfVEVNUExBVEUsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSBcdUQxNUNcdUQ1MENcdUI5QUNcdUQyQjhcdUM1RDBcdUMxMUNcdUIyOTQgezB9XHVDNzc0KFx1QUMwMCkgXHVENUM4XHVDNkE5XHVCNDE4XHVDOUMwIFx1QzU0QVx1QzJCNVx1QjJDOFx1QjJFNCEifSwKLQotICAgIHsgRVJfVU5LTk9XTl9FWFRfTlNfUFJFRklYLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgezB9IFx1RDY1NVx1QzdBNSBcdUIxMjRcdUM3ODRcdUMyQTRcdUQzOThcdUM3NzRcdUMyQTQgXHVDODExXHVCNDUwXHVDNUI0IHsxfVx1Qzc0NChcdUI5N0MpIFx1QzU0QyBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBFUl9JTVBPUlRTX0FTX0ZJUlNUX0VMRU0sCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSBcdUMyQTRcdUQwQzBcdUM3N0NcdUMyRENcdUQyQjhcdUM3NTggXHVDQ0FCXHVCQzg4XHVDOUY4IFx1QzY5NFx1QzE4Q1x1Qjg1Q1x1QjlDQyBcdUM3ODRcdUQzRUNcdUQyQjhcdUI5N0MgXHVDMjE4XHVENTg5XHVENTYwIFx1QzIxOCBcdUM3ODhcdUMyQjVcdUIyQzhcdUIyRTQhIn0sCi0KLSAgICB7IEVSX0lNUE9SVElOR19JVFNFTEYsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSB7MH1cdUM3NzQoXHVBQzAwKSBcdUM5QzFcdUM4MTEgXHVCNjEwXHVCMjk0IFx1QUMwNFx1QzgxMVx1QzgwMVx1QzczQ1x1Qjg1QyBcdUM3OTBcdUMyRTBcdUM3NDQgXHVDNzg0XHVEM0VDXHVEMkI4XHVENTU4XHVBQ0UwIFx1Qzc4OFx1QzJCNVx1QjJDOFx1QjJFNCEifSwKLQotICAgIHsgRVJfWE1MU1BBQ0VfSUxMRUdBTF9WQUwsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSB4bWw6c3BhY2VcdUM1RDAgXHVDNzk4XHVCQUJCXHVCNDFDIFx1QUMxMlx1Qzc3NCBcdUM3ODhcdUM3NEM6IHswfSJ9LAotCi0gICAgeyBFUl9QUk9DRVNTU1RZTEVTSEVFVF9OT1RfU1VDQ0VTU0ZVTCwKLSAgICAgICJwcm9jZXNzU3R5bGVzaGVldFx1Qjk3QyBcdUMyRTRcdUQzMjhcdUQ1ODhcdUMyQjVcdUIyQzhcdUIyRTQhIn0sCi0KLSAgICB7IEVSX1NBWF9FWENFUFRJT04sCi0gICAgICJTQVggXHVDNjA4XHVDNjc4XHVDMEFDXHVENTZEIn0sCi0KLS8vICBhZGQgdGhpcyBtZXNzYWdlIHRvIGZpeCBidWcgMjE0NzgKLSAgICB7IEVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQsCi0gICAgICJcdUQ1NjhcdUMyMThcdUFDMDAgXHVDOUMwXHVDNkQwXHVCNDE4XHVDOUMwIFx1QzU0QVx1QzJCNVx1QjJDOFx1QjJFNCEifSwKLQotICAgIHsgRVJfWFNMVF9FUlJPUiwKLSAgICAgIlhTTFQgXHVDNjI0XHVCOTU4In0sCi0KLSAgICB7IEVSX0NVUlJFTkNZX1NJR05fSUxMRUdBTCwKLSAgICAgICJcdUQ2MTVcdUMyREQgXHVEMzI4XHVEMTM0IFx1QkIzOFx1Qzc5MFx1QzVGNFx1QzVEMFx1QzExQ1x1QjI5NCBcdUQxQjVcdUQ2NTQgXHVBRTMwXHVENjM4XHVBQzAwIFx1RDVDOFx1QzZBOVx1QjQxOFx1QzlDMCBcdUM1NEFcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICB7IEVSX0RPQ1VNRU5UX0ZVTkNUSU9OX0lOVkFMSURfSU5fU1RZTEVTSEVFVF9ET00sCi0gICAgICAiRG9jdW1lbnQgXHVENTY4XHVDMjE4XHVCMjk0IFx1QzJBNFx1RDBDMFx1Qzc3Q1x1QzJEQ1x1RDJCOCBET01cdUM1RDBcdUMxMUMgXHVDOUMwXHVDNkQwXHVCNDE4XHVDOUMwIFx1QzU0QVx1QzJCNVx1QjJDOFx1QjJFNCEifSwKLQotICAgIHsgRVJfQ0FOVF9SRVNPTFZFX1BSRUZJWF9PRl9OT05fUFJFRklYX1JFU09MVkVSLAotICAgICAgIlx1QkU0NFx1QzgxMVx1QjQ1MFx1QzVCNCBcdUJEODRcdUMxMURcdUFFMzBcdUM3NTggXHVDODExXHVCNDUwXHVDNUI0XHVCOTdDIFx1QkQ4NFx1QzExRFx1RDU2MCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0ISJ9LAotCi0gICAgeyBFUl9SRURJUkVDVF9DT1VMRE5UX0dFVF9GSUxFTkFNRSwKLSAgICAgICJcdUM3QUNcdUM5QzBcdUM4MTUgXHVENjU1XHVDN0E1OiBcdUQzMENcdUM3N0MgXHVDNzc0XHVCOTg0XHVDNzQ0IFx1QUMwMFx1QzgzOFx1QzYyQyBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiBmaWxlIFx1QjYxMFx1QjI5NCBzZWxlY3QgXHVDMThEXHVDMTMxXHVDNzQwIFx1QzgwMVx1RDU2OVx1RDU1QyBcdUJCMzhcdUM3OTBcdUM1RjRcdUM3NDQgXHVCQzE4XHVENjU4XHVENTc0XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4ifSwKLQotICAgIHsgRVJfQ0FOTk9UX0JVSUxEX0ZPUk1BVFRFUkxJU1RFTkVSX0lOX1JFRElSRUNULAotICAgICAgIlx1QzdBQ1x1QzlDMFx1QzgxNSBcdUQ2NTVcdUM3QTVcdUM1RDAgRm9ybWF0dGVyTGlzdGVuZXJcdUI5N0MgXHVDMEREXHVDMTMxXHVENTYwIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQhIn0sCi0KLSAgICB7IEVSX0lOVkFMSURfUFJFRklYX0lOX0VYQ0xVREVSRVNVTFRQUkVGSVgsCi0gICAgICAiZXhjbHVkZS1yZXN1bHQtcHJlZml4ZXNcdUM3NTggXHVDODExXHVCNDUwXHVDNUI0XHVBQzAwIFx1QkQ4MFx1QzgwMVx1RDU2OVx1RDU2ODogezB9In0sCi0KLSAgICB7IEVSX01JU1NJTkdfTlNfVVJJLAotICAgICAgIlx1QzlDMFx1QzgxNVx1QjQxQyBcdUM4MTFcdUI0NTBcdUM1QjRcdUM1RDAgXHVCMzAwXHVENTVDIFx1QjEyNFx1Qzc4NFx1QzJBNFx1RDM5OFx1Qzc3NFx1QzJBNCBVUklcdUFDMDAgXHVCMjA0XHVCNzdEXHVCNDE4XHVDNUM4XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBFUl9NSVNTSU5HX0FSR19GT1JfT1BUSU9OLAotICAgICAgIlx1QzYzNVx1QzE1OFx1QzVEMCBcdUIzMDBcdUQ1NUMgXHVDNzc4XHVDMjE4XHVBQzAwIFx1QjIwNFx1Qjc3RFx1QjQyODogezB9In0sCi0KLSAgICB7IEVSX0lOVkFMSURfT1BUSU9OLAotICAgICAiXHVCRDgwXHVDODAxXHVENTY5XHVENTVDIFx1QzYzNVx1QzE1ODogezB9In0sCi0KLSAgICB7IEVSX01BTEZPUk1FRF9GT1JNQVRfU1RSSU5HLAotICAgICAiXHVDNzk4XHVCQUJCXHVCNDFDIFx1RDYxNVx1QzJERCBcdUJCMzhcdUM3OTBcdUM1RjQ6IHswfSJ9LAotCi0gICAgeyBFUl9TVFlMRVNIRUVUX1JFUVVJUkVTX1ZFUlNJT05fQVRUUklCLAotICAgICAgInhzbDpzdHlsZXNoZWV0XHVDNUQwXHVCMjk0ICd2ZXJzaW9uJyBcdUMxOERcdUMxMzFcdUM3NzQgXHVENTQ0XHVDNjk0XHVENTY5XHVCMkM4XHVCMkU0ISJ9LAotCi0gICAgeyBFUl9JTExFR0FMX0FUVFJJQlVURV9WQUxVRSwKLSAgICAgICJ7MH0gXHVDMThEXHVDMTMxXHVDNUQwIFx1Qzc5OFx1QkFCQlx1QjQxQyBcdUFDMTJcdUM3NzQgXHVDNzg4XHVDNzRDOiB7MX0ifSwKLQotICAgIHsgRVJfQ0hPT1NFX1JFUVVJUkVTX1dIRU4sCi0gICAgICJ4c2w6Y2hvb3NlXHVDNUQwXHVCMjk0IHhzbDp3aGVuXHVDNzc0IFx1RDU0NFx1QzY5NFx1RDU2OVx1QjJDOFx1QjJFNC4ifSwKLQotICAgIHsgRVJfTk9fQVBQTFlfSU1QT1JUX0lOX0ZPUl9FQUNILAotICAgICAgInhzbDpmb3ItZWFjaFx1QzVEMFx1QzExQ1x1QjI5NCB4c2w6YXBwbHktaW1wb3J0c1x1QUMwMCBcdUQ1QzhcdUM2QTlcdUI0MThcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBFUl9DQU5UX1VTRV9EVE1fRk9SX09VVFBVVCwKLSAgICAgICJcdUNEOUNcdUI4MjUgRE9NIFx1QjE3OFx1QjREQ1x1QzVEMCBEVE1MaWFpc29uXHVDNzQ0IFx1QzBBQ1x1QzZBOVx1RDU2MCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiBcdUIzMDBcdUMyRTAgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLkRPTTJIZWxwZXJcdUI5N0MgXHVDODA0XHVCMkVDXHVENTU4XHVDMkVEXHVDMkRDXHVDNjI0ISJ9LAotCi0gICAgeyBFUl9DQU5UX1VTRV9EVE1fRk9SX0lOUFVULAotICAgICAgIlx1Qzc4NVx1QjgyNSBET00gXHVCMTc4XHVCNERDXHVDNUQwIERUTUxpYWlzb25cdUM3NDQgXHVDMEFDXHVDNkE5XHVENTYwIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuIFx1QjMwMFx1QzJFMCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuRE9NMkhlbHBlclx1Qjk3QyBcdUM4MDRcdUIyRUNcdUQ1NThcdUMyRURcdUMyRENcdUM2MjQhIn0sCi0KLSAgICB7IEVSX0NBTExfVE9fRVhUX0ZBSUxFRCwKLSAgICAgICJcdUQ2NTVcdUM3QTUgXHVDNjk0XHVDMThDXHVDNUQwIFx1QjMwMFx1RDU1QyBcdUQ2MzhcdUNEOUMgXHVDMkU0XHVEMzI4OiB7MH0ifSwKLQotICAgIHsgRVJfUFJFRklYX01VU1RfUkVTT0xWRSwKLSAgICAgICJcdUM4MTFcdUI0NTBcdUM1QjRcdUIyOTQgXHVCMTI0XHVDNzg0XHVDMkE0XHVEMzk4XHVDNzc0XHVDMkE0XHVCODVDIFx1QkQ4NFx1QzExRFx1QjQxOFx1QzVCNFx1QzU3QyBcdUQ1Njg6IHswfSJ9LAotCi0gICAgeyBFUl9JTlZBTElEX1VURjE2X1NVUlJPR0FURSwKLSAgICAgICJcdUJEODBcdUM4MDFcdUQ1NjlcdUQ1NUMgVVRGLTE2IFx1QjMwMFx1QjlBQyBcdUM2OTRcdUMxOENcdUFDMDAgXHVBQzEwXHVDOUMwXHVCNDI4OiB7MH0ifSwKLQotICAgIHsgRVJfWFNMQVRUUlNFVF9VU0VEX0lUU0VMRiwKLSAgICAgICJ4c2w6YXR0cmlidXRlLXNldCB7MH1cdUM3NzQoXHVBQzAwKSBcdUM3OTBcdUMyRTBcdUM3NDQgXHVDMEFDXHVDNkE5XHVENTg4XHVDMkI1XHVCMkM4XHVCMkU0LiBcdUM3NzQgXHVBQ0JEXHVDNkIwIFx1QkIzNFx1RDU1QyBcdUI4RThcdUQ1MDRcdUFDMDAgXHVCQzFDXHVDMEREXHVENTY5XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBFUl9DQU5OT1RfTUlYX1hFUkNFU0RPTSwKLSAgICAgICJcdUJFNDRYZXJjZXMtRE9NIFx1Qzc4NVx1QjgyNVx1QUNGQyBYZXJjZXMtRE9NIFx1Q0Q5Q1x1QjgyNVx1Qzc0NCBcdUQ1NjhcdUFFRDggXHVDMEFDXHVDNkE5XHVENTYwIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQhIn0sCi0KLSAgICB7IEVSX1RPT19NQU5ZX0xJU1RFTkVSUywKLSAgICAgICJhZGRUcmFjZUxpc3RlbmVyc1RvU3R5bGVzaGVldCAtIFRvb01hbnlMaXN0ZW5lcnNFeGNlcHRpb24ifSwKLQotICAgIHsgRVJfSU5fRUxFTVRFTVBMQVRFRUxFTV9SRUFET0JKRUNULAotICAgICAgIkVsZW1UZW1wbGF0ZUVsZW1lbnQucmVhZE9iamVjdFx1QzVEMCBcdUM2MjRcdUI5NTggXHVCQzFDXHVDMEREOiB7MH0ifSwKLQotICAgIHsgRVJfRFVQTElDQVRFX05BTUVEX1RFTVBMQVRFLAotICAgICAgIlx1QkE4NVx1QkE4NVx1QjQxQyBcdUQxNUNcdUQ1MENcdUI5QUNcdUQyQjhcdUI5N0MgXHVCNDUwIFx1QUMxQyBcdUM3NzRcdUMwQzEgXHVDQzNFXHVDNzRDOiB7MH0ifSwKLQotICAgIHsgRVJfSU5WQUxJRF9LRVlfQ0FMTCwKLSAgICAgICJcdUJEODBcdUM4MDFcdUQ1NjlcdUQ1NUMgXHVENTY4XHVDMjE4IFx1RDYzOFx1Q0Q5QzogcmVjdXJzaXZlIGtleSgpIFx1RDYzOFx1Q0Q5Q1x1Qzc0MCBcdUQ1QzhcdUM2QTlcdUI0MThcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBFUl9SRUZFUkVOQ0lOR19JVFNFTEYsCi0gICAgICAiezB9IFx1QkNDMFx1QzIxOFx1QUMwMCBcdUM5QzFcdUM4MTEgXHVCNjEwXHVCMjk0IFx1QUMwNFx1QzgxMVx1QzgwMVx1QzczQ1x1Qjg1QyBcdUM3OTBcdUMyRTBcdUM3NDQgXHVDQzM4XHVDODcwXHVENTU4XHVBQ0UwIFx1Qzc4OFx1QzJCNVx1QjJDOFx1QjJFNCEifSwKLQotICAgIHsgRVJfSUxMRUdBTF9ET01TT1VSQ0VfSU5QVVQsCi0gICAgICAibmV3VGVtcGxhdGVzXHVDNzU4IERPTVNvdXJjZVx1QzVEMCBcdUIzMDBcdUQ1NUMgXHVDNzg1XHVCODI1IFx1QjE3OFx1QjREQ1x1QjI5NCBcdUIxMTBcdUM3N0MgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNCEifSwKLQotICAgIHsgRVJfQ0xBU1NfTk9UX0ZPVU5EX0ZPUl9PUFRJT04sCi0gICAgICAgICJ7MH0gXHVDNjM1XHVDMTU4XHVDNUQwIFx1QjMwMFx1RDU1QyBcdUQwNzRcdUI3OThcdUMyQTQgXHVEMzBDXHVDNzdDXHVDNzQ0IFx1Q0MzRVx1Qzc0NCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBFUl9SRVFVSVJFRF9FTEVNX05PVF9GT1VORCwKLSAgICAgICAgIlx1RDU0NFx1QzIxOCBcdUM2OTRcdUMxOENcdUI5N0MgXHVDQzNFXHVDNzQ0IFx1QzIxOCBcdUM1QzZcdUM3NEM6IHswfSJ9LAotCi0gICAgeyBFUl9JTlBVVF9DQU5OT1RfQkVfTlVMTCwKLSAgICAgICAgIklucHV0U3RyZWFtXHVDNzQwIFx1QjExMFx1Qzc3QyBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBFUl9VUklfQ0FOTk9UX0JFX05VTEwsCi0gICAgICAgICJVUklcdUIyOTQgXHVCMTEwXHVDNzdDIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICB7IEVSX0ZJTEVfQ0FOTk9UX0JFX05VTEwsCi0gICAgICAgICJcdUQzMENcdUM3N0NcdUM3NDAgXHVCMTEwXHVDNzdDIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICB7IEVSX1NPVVJDRV9DQU5OT1RfQkVfTlVMTCwKLSAgICAgICAgICAgICAgICAiSW5wdXRTb3VyY2VcdUIyOTQgXHVCMTEwXHVDNzdDIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICB7IEVSX0NBTk5PVF9JTklUX0JTRk1HUiwKLSAgICAgICAgICAgICAgICAiQlNGIFx1QUQwMFx1QjlBQ1x1Qzc5MFx1Qjk3QyBcdUNEMDhcdUFFMzBcdUQ2NTRcdUQ1NjAgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAgIHsgRVJfQ0FOTk9UX0NNUExfRVhURU5TTiwKLSAgICAgICAgICAgICAgICAiXHVENjU1XHVDN0E1XHVDNzQ0IFx1Q0VGNFx1RDMwQ1x1Qzc3Q1x1RDU2MCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBFUl9DQU5OT1RfQ1JFQVRFX0VYVEVOU04sCi0gICAgICAiezB9IFx1RDY1NVx1QzdBNVx1Qzc0NCBcdUMwRERcdUMxMzFcdUQ1NjAgXHVDMjE4IFx1QzVDNlx1QjI5NCBcdUM2RDBcdUM3Nzg6IHsxfSJ9LAotCi0gICAgeyBFUl9JTlNUQU5DRV9NVEhEX0NBTExfUkVRVUlSRVMsCi0gICAgICAiezB9IFx1QkE1NFx1QzE4Q1x1QjREQ1x1QzVEMCBcdUIzMDBcdUQ1NUMgXHVDNzc4XHVDMkE0XHVEMTM0XHVDMkE0IFx1QkE1NFx1QzE4Q1x1QjREQ1x1QzVEMFx1QjI5NCBcdUFDMURcdUNDQjQgXHVDNzc4XHVDMkE0XHVEMTM0XHVDMkE0XHVBQzAwIFx1Q0NBQlx1QkM4OFx1QzlGOCBcdUM3NzhcdUMyMThcdUI4NUMgXHVENTQ0XHVDNjk0XHVENTY5XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBFUl9JTlZBTElEX0VMRU1FTlRfTkFNRSwKLSAgICAgICJcdUJEODBcdUM4MDFcdUQ1NjlcdUQ1NUMgXHVDNjk0XHVDMThDIFx1Qzc3NFx1Qjk4NFx1Qzc3NCBcdUM5QzBcdUM4MTVcdUI0Mjg6IHswfSJ9LAotCi0gICAgeyBFUl9FTEVNRU5UX05BTUVfTUVUSE9EX1NUQVRJQywKLSAgICAgICJcdUM2OTRcdUMxOEMgXHVDNzc0XHVCOTg0IFx1QkE1NFx1QzE4Q1x1QjREQ1x1QjI5NCBcdUM4MTVcdUM4MDEgezB9XHVDNzc0XHVDNUI0XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4ifSwKLQotICAgIHsgRVJfRVhURU5TSU9OX0ZVTkNfVU5LTk9XTiwKLSAgICAgICAgICAgICAiXHVENjU1XHVDN0E1IFx1RDU2OFx1QzIxOCB7MH06IHsxfVx1Qzc0NChcdUI5N0MpIFx1QzU0QyBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBFUl9NT1JFX01BVENIX0NPTlNUUlVDVE9SLAotICAgICAgICAgICAgICJ7MH1cdUM1RDAgXHVCMzAwXHVENTVDIFx1QzBERFx1QzEzMVx1Qzc5MFx1QzY0MCBcdUFDMDBcdUM3QTUgXHVDNzk4IFx1Qzc3Q1x1Q0U1OFx1RDU1OFx1QjI5NCBcdUQ1NkRcdUJBQTlcdUM3NzQgXHVCNDUwIFx1QUMxQyBcdUM3NzRcdUMwQzEgXHVDNzg4XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBFUl9NT1JFX01BVENIX01FVEhPRCwKLSAgICAgICAgICAgICAiezB9IFx1QkE1NFx1QzE4Q1x1QjREQ1x1QzY0MCBcdUFDMDBcdUM3QTUgXHVDNzk4IFx1Qzc3Q1x1Q0U1OFx1RDU1OFx1QjI5NCBcdUQ1NkRcdUJBQTlcdUM3NzQgXHVCNDUwIFx1QUMxQyBcdUM3NzRcdUMwQzEgXHVDNzg4XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBFUl9NT1JFX01BVENIX0VMRU1FTlQsCi0gICAgICAgICAgICAgIlx1QzY5NFx1QzE4QyBcdUJBNTRcdUMxOENcdUI0REMgezB9XHVBQ0ZDKFx1QzY0MCkgXHVBQzAwXHVDN0E1IFx1Qzc5OCBcdUM3N0NcdUNFNThcdUQ1NThcdUIyOTQgXHVENTZEXHVCQUE5XHVDNzc0IFx1QjQ1MCBcdUFDMUMgXHVDNzc0XHVDMEMxIFx1Qzc4OFx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAgIHsgRVJfSU5WQUxJRF9DT05URVhUX1BBU1NFRCwKLSAgICAgICAgICAgICAiezB9IFx1RDNDOVx1QUMwMFx1Qjk3QyBcdUM3MDRcdUQ1NzQgXHVCRDgwXHVDODAxXHVENTY5XHVENTVDIFx1Q0VFOFx1RDE0RFx1QzJBNFx1RDJCOFx1QUMwMCBcdUM4MDRcdUIyRUNcdUI0MThcdUM1QzhcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICB7IEVSX1BPT0xfRVhJU1RTLAotICAgICAgICAgICAgICJcdUQ0ODBcdUM3NzQgXHVDODc0XHVDN0FDXHVENTY5XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBFUl9OT19EUklWRVJfTkFNRSwKLSAgICAgICAgICAgICAiXHVDOUMwXHVDODE1XHVCNDFDIFx1QjREQ1x1Qjc3Q1x1Qzc3NFx1QkM4NCBcdUM3NzRcdUI5ODRcdUM3NzQgXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBFUl9OT19VUkwsCi0gICAgICAgICAgICAgIlx1QzlDMFx1QzgxNVx1QjQxQyBVUkxcdUM3NzQgXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBFUl9QT09MX1NJWkVfTEVTU1RIQU5fT05FLAotICAgICAgICAgICAgICJcdUQ0ODAgXHVEMDZDXHVBRTMwXHVBQzAwIDFcdUJDRjRcdUIyRTQgXHVDNzkxXHVDMkI1XHVCMkM4XHVCMkU0ISJ9LAotCi0gICAgeyBFUl9JTlZBTElEX0RSSVZFUiwKLSAgICAgICAgICAgICAiXHVCRDgwXHVDODAxXHVENTY5XHVENTVDIFx1QjREQ1x1Qjc3Q1x1Qzc3NFx1QkM4NCBcdUM3NzRcdUI5ODRcdUM3NzQgXHVDOUMwXHVDODE1XHVCNDE4XHVDNUM4XHVDMkI1XHVCMkM4XHVCMkU0ISJ9LAotCi0gICAgeyBFUl9OT19TVFlMRVNIRUVUUk9PVCwKLSAgICAgICAgICAgICAiXHVDMkE0XHVEMEMwXHVDNzdDXHVDMkRDXHVEMkI4IFx1QjhFOFx1RDJCOFx1Qjk3QyBcdUNDM0VcdUM3NDQgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNCEifSwKLQotICAgIHsgRVJfSUxMRUdBTF9YTUxTUEFDRV9WQUxVRSwKLSAgICAgICAgICJ4bWw6c3BhY2VcdUM1RDAgXHVCMzAwXHVENTVDIFx1QUMxMlx1Qzc3NCBcdUM3OThcdUJBQkJcdUI0MThcdUM1QzhcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICB7IEVSX1BST0NFU1NGUk9NTk9ERV9GQUlMRUQsCi0gICAgICAgICAicHJvY2Vzc0Zyb21Ob2RlXHVCOTdDIFx1QzJFNFx1RDMyOFx1RDU4OFx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAgIHsgRVJfUkVTT1VSQ0VfQ09VTERfTk9UX0xPQUQsCi0gICAgICAgICJbezB9XSBcdUI5QUNcdUMxOENcdUMyQTRcdUFDMDAgXHVCMkU0XHVDNzRDXHVDNzQ0IFx1Qjg1Q1x1QjREQ1x1RDU2MCBcdUMyMTggXHVDNUM2XHVDNzRDOiB7MX0gXG4gezJ9IFx0IHszfSJ9LAotCi0gICAgeyBFUl9CVUZGRVJfU0laRV9MRVNTVEhBTl9aRVJPLAotICAgICAgICAiXHVCQzg0XHVEMzdDIFx1RDA2Q1x1QUUzMCA8PTAifSwKLQotICAgIHsgRVJfVU5LTk9XTl9FUlJPUl9DQUxMSU5HX0VYVEVOU0lPTiwKLSAgICAgICAgIlx1RDY1NVx1QzdBNVx1Qzc0NCBcdUQ2MzhcdUNEOUNcdUQ1NThcdUIyOTQgXHVDOTExIFx1QzU0QyBcdUMyMTggXHVDNUM2XHVCMjk0IFx1QzYyNFx1Qjk1OFx1QUMwMCBcdUJDMUNcdUMwRERcdUQ1ODhcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICB7IEVSX05PX05BTUVTUEFDRV9ERUNMLAotICAgICAgICAiezB9IFx1QzgxMVx1QjQ1MFx1QzVCNFx1QzVEMCBcdUQ1NzRcdUIyRjlcdUQ1NThcdUIyOTQgXHVCMTI0XHVDNzg0XHVDMkE0XHVEMzk4XHVDNzc0XHVDMkE0IFx1QzEyMFx1QzVCOFx1Qzc3NCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICB7IEVSX0VMRU1fQ09OVEVOVF9OT1RfQUxMT1dFRCwKLSAgICAgICAgImxhbmc9amF2YWNsYXNzIHswfVx1QzVEMCBcdUIzMDBcdUQ1NzRcdUMxMUNcdUIyOTQgXHVDNjk0XHVDMThDIFx1Q0Y1OFx1RDE1MFx1Q0UyMFx1QUMwMCBcdUQ1QzhcdUM2QTlcdUI0MThcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBFUl9TVFlMRVNIRUVUX0RJUkVDVEVEX1RFUk1JTkFUSU9OLAotICAgICAgICAiXHVDMkE0XHVEMEMwXHVDNzdDXHVDMkRDXHVEMkI4XHVBQzAwIFx1Qzg4NVx1QjhDQ1x1Qjk3QyBcdUM5QzBcdUM4MTVcdUQ1ODhcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICB7IEVSX09ORV9PUl9UV08sCi0gICAgICAgICIxIFx1QjYxMFx1QjI5NCAyIn0sCi0KLSAgICB7IEVSX1RXT19PUl9USFJFRSwKLSAgICAgICAgIjIgXHVCNjEwXHVCMjk0IDMifSwKLQotICAgIHsgRVJfQ09VTERfTk9UX0xPQURfUkVTT1VSQ0UsCi0gICAgICAgICJ7MH1cdUM3NDQoXHVCOTdDKSBcdUI4NUNcdUI0RENcdUQ1NjAgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4gQ0xBU1NQQVRIXHVCOTdDIFx1RDY1NVx1Qzc3OFx1RDU1OFx1QzJFRFx1QzJEQ1x1QzYyNC4gXHVENjA0XHVDN0FDIFx1QUUzMFx1QkNGOFx1QUMxMlx1QjlDQyBcdUMwQUNcdUM2QTlcdUQ1NThcdUIyOTQgXHVDOTExXHVDNzg1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBFUl9DQU5OT1RfSU5JVF9ERUZBVUxUX1RFTVBMQVRFUywKLSAgICAgICAgIlx1QUUzMFx1QkNGOCBcdUQxNUNcdUQ1MENcdUI5QUNcdUQyQjhcdUI5N0MgXHVDRDA4XHVBRTMwXHVENjU0XHVENTYwIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICB7IEVSX1JFU1VMVF9OVUxMLAotICAgICAgICAiXHVBQ0IwXHVBQ0ZDXHVCMjk0IFx1QjExMFx1Qzc3NCBcdUM1NDRcdUIyQzhcdUM1QjRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBFUl9SRVNVTFRfQ09VTERfTk9UX0JFX1NFVCwKLSAgICAgICAgIlx1QUNCMFx1QUNGQ1x1Qjk3QyBcdUMxMjRcdUM4MTVcdUQ1NjAgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAgIHsgRVJfTk9fT1VUUFVUX1NQRUNJRklFRCwKLSAgICAgICAgIlx1QzlDMFx1QzgxNVx1QjQxQyBcdUNEOUNcdUI4MjVcdUM3NzQgXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBFUl9DQU5OT1RfVFJBTlNGT1JNX1RPX1JFU1VMVF9UWVBFLAotICAgICAgICAiezB9IFx1QzcyMFx1RDYxNVx1Qzc1OCBcdUFDQjBcdUFDRkNcdUI4NUMgXHVCQ0MwXHVENjU4XHVENTYwIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICB7IEVSX0NBTk5PVF9UUkFOU0ZPUk1fU09VUkNFX1RZUEUsCi0gICAgICAgICJ7MH0gXHVDNzIwXHVENjE1XHVDNzU4IFx1QzE4Q1x1QzJBNFx1Qjk3QyBcdUJDQzBcdUQ2NThcdUQ1NjAgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAgIHsgRVJfTlVMTF9DT05URU5UX0hBTkRMRVIsCi0gICAgICAgICJcdUIxMTAgXHVDRjU4XHVEMTUwXHVDRTIwIFx1Q0M5OFx1QjlBQ1x1QUUzMCJ9LAotCi0gICAgeyBFUl9OVUxMX0VSUk9SX0hBTkRMRVIsCi0gICAgICAgICJcdUIxMTAgXHVDNjI0XHVCOTU4IFx1Q0M5OFx1QjlBQ1x1QUUzMCJ9LAotCi0gICAgeyBFUl9DQU5OT1RfQ0FMTF9QQVJTRSwKLSAgICAgICAgIkNvbnRlbnRIYW5kbGVyXHVBQzAwIFx1QzEyNFx1QzgxNVx1QjQxOFx1QzlDMCBcdUM1NEFcdUM3NDAgXHVBQ0JEXHVDNkIwIHBhcnNlXHVCOTdDIFx1RDYzOFx1Q0Q5Q1x1RDU2MCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBFUl9OT19QQVJFTlRfRk9SX0ZJTFRFUiwKLSAgICAgICAgIlx1RDU0NFx1RDEzMFx1QzVEMCBcdUIzMDBcdUQ1NUMgXHVDMEMxXHVDNzA0XHVBQzAwIFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAgIHsgRVJfTk9fU1RZTEVTSEVFVF9JTl9NRURJQSwKLSAgICAgICAgICJ7MH1cdUM1RDBcdUMxMUMgXHVDMkE0XHVEMEMwXHVDNzdDXHVDMkRDXHVEMkI4XHVCOTdDIFx1Q0MzRVx1Qzc0NCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiBcdUI5RTRcdUNDQjQgPSB7MX0ifSwKLQotICAgIHsgRVJfTk9fU1RZTEVTSEVFVF9QSSwKLSAgICAgICAgICJ7MH1cdUM1RDBcdUMxMUMgeG1sLXN0eWxlc2hlZXQgUElcdUI5N0MgXHVDQzNFXHVDNzQ0IFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICB7IEVSX05PVF9TVVBQT1JURUQsCi0gICAgICAgIlx1QzlDMFx1QzZEMFx1QjQxOFx1QzlDMCBcdUM1NEFcdUM3NEM6IHswfSJ9LAotCi0gICAgeyBFUl9QUk9QRVJUWV9WQUxVRV9CT09MRUFOLAotICAgICAgICJ7MH0gXHVDMThEXHVDMTMxXHVDNUQwIFx1QjMwMFx1RDU1QyBcdUFDMTJcdUM3NDAgXHVCRDgwXHVDNkI4IFx1Qzc3OFx1QzJBNFx1RDEzNFx1QzJBNFx1QzVFQ1x1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICB7IEVSX0NPVUxEX05PVF9GSU5EX0VYVEVSTl9TQ1JJUFQsCi0gICAgICAgICAiezB9XHVDNUQwIFx1Qzc4OFx1QjI5NCBcdUM2NzhcdUJEODAgXHVDMkE0XHVEMDZDXHVCOUJEXHVEMkI4XHVCODVDIFx1QUMwMFx1QzgzOFx1QzYyQyBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBFUl9SRVNPVVJDRV9DT1VMRF9OT1RfRklORCwKLSAgICAgICAgIlt7MH1dIFx1QjlBQ1x1QzE4Q1x1QzJBNFx1Qjk3QyBcdUNDM0VcdUM3NDQgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC5cbiB7MX0ifSwKLQotICAgIHsgRVJfT1VUUFVUX1BST1BFUlRZX05PVF9SRUNPR05JWkVELAotICAgICAgICAiXHVDRDlDXHVCODI1IFx1QzE4RFx1QzEzMVx1Qzc0NCBcdUM3NzhcdUMyRERcdUQ1NjAgXHVDMjE4IFx1QzVDNlx1Qzc0QzogezB9In0sCi0KLSAgICB7IEVSX0ZBSUxFRF9DUkVBVElOR19FTEVNTElUUlNMVCwKLSAgICAgICAgIkVsZW1MaXRlcmFsUmVzdWx0IFx1Qzc3OFx1QzJBNFx1RDEzNFx1QzJBNCBcdUMwRERcdUMxMzFcdUM3NDQgXHVDMkU0XHVEMzI4XHVENTg4XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gIC8vRWFybGllciAoSkRLIDEuNCBYQUxBTiAyLjItRDExKSBhdCBrZXkgY29kZSAnMjA0JyB0aGUga2V5IG5hbWUgd2FzIEVSX1BSSU9SSVRZX05PVF9QQVJTQUJMRQotICAvLyBJbiBsYXRlc3QgWGFsYW4gY29kZSBiYXNlIGtleSBuYW1lIGlzICBFUl9WQUxVRV9TSE9VTERfQkVfTlVNQkVSLiBUaGlzIHNob3VsZCBhbHNvIGJlIHRha2VuIGNhcmUKLSAgLy9pbiBsb2NhbGUgc3BlY2lmaWMgZmlsZXMgbGlrZSBYU0xURXJyb3JSZXNvdXJjZXNfZGUuamF2YSwgWFNMVEVycm9yUmVzb3VyY2VzX2ZyLmphdmEgZXRjLgotICAvL05PVEU6IE5vdCBvbmx5IHRoZSBrZXkgbmFtZSBidXQgbWVzc2FnZSBoYXMgYWxzbyBiZWVuIGNoYW5nZWQuCi0gICAgeyBFUl9WQUxVRV9TSE9VTERfQkVfTlVNQkVSLAotICAgICAgICAiezB9XHVDNUQwIFx1QjMwMFx1RDU1QyBcdUFDMTJcdUM1RDBcdUIyOTQgXHVBRDZDXHVCQjM4XHVDNzQ0IFx1QkQ4NFx1QzExRFx1RDU2MCBcdUMyMTggXHVDNzg4XHVCMjk0IFx1QzIyQlx1Qzc5MFx1QUMwMCBcdUQzRUNcdUQ1NjhcdUI0MThcdUM1QjRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBFUl9WQUxVRV9TSE9VTERfRVFVQUwsCi0gICAgICAgICJ7MH1cdUM1RDAgXHVCMzAwXHVENTVDIFx1QUMxMlx1Qzc0MCB5ZXMgXHVCNjEwXHVCMjk0IG5vXHVDNUVDXHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4ifSwKLQotICAgIHsgRVJfRkFJTEVEX0NBTExJTkdfTUVUSE9ELAotICAgICAgICAiezB9IFx1QkE1NFx1QzE4Q1x1QjREQyBcdUQ2MzhcdUNEOUNcdUM3NDQgXHVDMkU0XHVEMzI4XHVENTg4XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBFUl9GQUlMRURfQ1JFQVRJTkdfRUxFTVRNUEwsCi0gICAgICAgICJFbGVtVGVtcGxhdGVFbGVtZW50IFx1Qzc3OFx1QzJBNFx1RDEzNFx1QzJBNCBcdUMwRERcdUMxMzFcdUM3NDQgXHVDMkU0XHVEMzI4XHVENTg4XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBFUl9DSEFSU19OT1RfQUxMT1dFRCwKLSAgICAgICAgIlx1QkIzOFx1QzExQ1x1Qzc1OCBcdUM3NzQgXHVDOUMwXHVDODEwXHVDNUQwXHVDMTFDXHVCMjk0IFx1QkIzOFx1Qzc5MFx1QUMwMCBcdUQ1QzhcdUM2QTlcdUI0MThcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBFUl9BVFRSX05PVF9BTExPV0VELAotICAgICAgICAiezF9IFx1QzY5NFx1QzE4Q1x1QzVEMFx1QzExQ1x1QjI5NCBcInswfVwiIFx1QzE4RFx1QzEzMVx1Qzc3NCBcdUQ1QzhcdUM2QTlcdUI0MThcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0ISJ9LAotCi0gICAgeyBFUl9CQURfVkFMVUUsCi0gICAgICJ7MH06IFx1Qzc5OFx1QkFCQlx1QjQxQyBcdUFDMTIgezF9ICJ9LAotCi0gICAgeyBFUl9BVFRSSUJfVkFMVUVfTk9UX0ZPVU5ELAotICAgICAiezB9IFx1QzE4RFx1QzEzMVx1QUMxMlx1Qzc0NCBcdUNDM0VcdUM3NDQgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4gIn0sCi0KLSAgICB7IEVSX0FUVFJJQl9WQUxVRV9OT1RfUkVDT0dOSVpFRCwKLSAgICAgInswfSBcdUMxOERcdUMxMzFcdUFDMTJcdUM3NDQgXHVDNzc4XHVDMkREXHVENTYwIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuICJ9LAotCi0gICAgeyBFUl9OVUxMX1VSSV9OQU1FU1BBQ0UsCi0gICAgICJcdUIxMTAgVVJJXHVCOTdDIFx1QzBBQ1x1QzZBOVx1RDU1OFx1QzVFQyBcdUIxMjRcdUM3ODRcdUMyQTRcdUQzOThcdUM3NzRcdUMyQTQgXHVDODExXHVCNDUwXHVDNUI0XHVCOTdDIFx1QzBERFx1QzEzMVx1RDU1OFx1QjgyNFx1QUNFMCBcdUMyRENcdUIzQzRcdUQ1NThcdUIyOTQgXHVDOTExIn0sCi0KLSAgICB7IEVSX05VTUJFUl9UT09fQklHLAotICAgICAiXHVBQzAwXHVDN0E1IFx1RDA3MCBMb25nIFx1QzgxNVx1QzIxOFx1QkNGNFx1QjJFNCBcdUQwNzAgXHVDMjJCXHVDNzkwXHVDNzU4IFx1RDYxNVx1QzJERFx1Qzc0NCBcdUM5QzBcdUM4MTVcdUQ1NThcdUI4MjRcdUFDRTAgXHVDMkRDXHVCM0M0XHVENTU4XHVCMjk0IFx1QzkxMSJ9LAotCi0gICAgeyBFUl9DQU5OT1RfRklORF9TQVgxX0RSSVZFUiwKLSAgICAgIlNBWDEgXHVCNERDXHVCNzdDXHVDNzc0XHVCQzg0IFx1RDA3NFx1Qjc5OFx1QzJBNCB7MH1cdUM3NDQoXHVCOTdDKSBcdUNDM0VcdUM3NDQgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAgIHsgRVJfU0FYMV9EUklWRVJfTk9UX0xPQURFRCwKLSAgICAgIlNBWDEgXHVCNERDXHVCNzdDXHVDNzc0XHVCQzg0IFx1RDA3NFx1Qjc5OFx1QzJBNCB7MH1cdUM3NzQoXHVBQzAwKSBcdUJDMUNcdUFDQUNcdUI0MThcdUM1QzhcdUM5QzBcdUI5Q0MgXHVENTc0XHVCMkY5IFx1RDA3NFx1Qjc5OFx1QzJBNFx1Qjk3QyBcdUI4NUNcdUI0RENcdUQ1NjAgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAgIHsgRVJfU0FYMV9EUklWRVJfTk9UX0lOU1RBTlRJQVRFRCwKLSAgICAgIlNBWDEgXHVCNERDXHVCNzdDXHVDNzc0XHVCQzg0IFx1RDA3NFx1Qjc5OFx1QzJBNCB7MH1cdUM3NzQoXHVBQzAwKSBcdUI4NUNcdUI0RENcdUI0MThcdUM1QzhcdUM5QzBcdUI5Q0MgXHVENTc0XHVCMkY5IFx1RDA3NFx1Qjc5OFx1QzJBNFx1Qjk3QyBcdUM3NzhcdUMyQTRcdUQxMzRcdUMyQTRcdUQ2NTRcdUQ1NjAgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAgIHsgRVJfU0FYMV9EUklWRVJfTk9UX0lNUExFTUVOVF9QQVJTRVIsCi0gICAgICJTQVgxIFx1QjREQ1x1Qjc3Q1x1Qzc3NFx1QkM4NCBcdUQwNzRcdUI3OThcdUMyQTQgezB9XHVDNzc0KFx1QUMwMCkgb3JnLnhtbC5zYXguUGFyc2VyXHVCOTdDIFx1QUQ2Q1x1RDYwNFx1RDU1OFx1QzlDMCBcdUM1NEFcdUM1NThcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICB7IEVSX1BBUlNFUl9QUk9QRVJUWV9OT1RfU1BFQ0lGSUVELAotICAgICAiXHVDMkRDXHVDMkE0XHVEMTVDIFx1QzE4RFx1QzEzMSBvcmcueG1sLnNheC5wYXJzZXJcdUFDMDAgXHVDOUMwXHVDODE1XHVCNDE4XHVDOUMwIFx1QzU0QVx1QzU1OFx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAgIHsgRVJfUEFSU0VSX0FSR19DQU5OT1RfQkVfTlVMTCwKLSAgICAgIlx1QUQ2Q1x1QkIzOCBcdUJEODRcdUMxMURcdUFFMzAgXHVDNzc4XHVDMjE4XHVCMjk0IFx1QjExMFx1Qzc3NCBcdUM1NDRcdUIyQzhcdUM1QjRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBFUl9GRUFUVVJFLAotICAgICAiXHVBRTMwXHVCMkE1OiB7MH0ifSwKLQotICAgIHsgRVJfUFJPUEVSVFksCi0gICAgICJcdUMxOERcdUMxMzE6IHswfSJ9LAotCi0gICAgeyBFUl9OVUxMX0VOVElUWV9SRVNPTFZFUiwKLSAgICAgIlx1QjExMCBcdUM1RDRcdUQyRjBcdUQyRjAgXHVCRDg0XHVDMTFEXHVBRTMwIn0sCi0KLSAgICB7IEVSX05VTExfRFREX0hBTkRMRVIsCi0gICAgICJcdUIxMTAgRFREIFx1Q0M5OFx1QjlBQ1x1QUUzMCJ9LAotCi0gICAgeyBFUl9OT19EUklWRVJfTkFNRV9TUEVDSUZJRUQsCi0gICAgICJcdUM5QzBcdUM4MTVcdUI0MUMgXHVCNERDXHVCNzdDXHVDNzc0XHVCQzg0IFx1Qzc3NFx1Qjk4NFx1Qzc3NCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQhIn0sCi0KLSAgICB7IEVSX05PX1VSTF9TUEVDSUZJRUQsCi0gICAgICJcdUM5QzBcdUM4MTVcdUI0MUMgVVJMXHVDNzc0IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNCEifSwKLQotICAgIHsgRVJfUE9PTFNJWkVfTEVTU19USEFOX09ORSwKLSAgICAgIlx1RDQ4MCBcdUQwNkNcdUFFMzBcdUFDMDAgMSBcdUJCRjhcdUI5Q0NcdUM3ODVcdUIyQzhcdUIyRTQhIn0sCi0KLSAgICB7IEVSX0lOVkFMSURfRFJJVkVSX05BTUUsCi0gICAgICJcdUJEODBcdUM4MDFcdUQ1NjlcdUQ1NUMgXHVCNERDXHVCNzdDXHVDNzc0XHVCQzg0IFx1Qzc3NFx1Qjk4NFx1Qzc3NCBcdUM5QzBcdUM4MTVcdUI0MThcdUM1QzhcdUMyQjVcdUIyQzhcdUIyRTQhIn0sCi0KLSAgICB7IEVSX0VSUk9STElTVEVORVIsCi0gICAgICJFcnJvckxpc3RlbmVyIn0sCi0KLQotLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBzaG91bGQgbm90IG5vcm1hbGx5IGJlIGRpc3BsYXllZAotLy8gICB0byB1c2Vycy4gIEl0IGRlc2NyaWJlcyBhIHNpdHVhdGlvbiBpbiB3aGljaCB0aGUgcHJvY2Vzc29yIGhhcyBkZXRlY3RlZAotLy8gICBhbiBpbnRlcm5hbCBjb25zaXN0ZW5jeSBwcm9ibGVtIGluIGl0c2VsZiwgYW5kIGl0IHByb3ZpZGVzIHRoaXMgbWVzc2FnZQotLy8gICBmb3IgdGhlIGRldmVsb3BlciB0byBoZWxwIGRpYWdub3NlIHRoZSBwcm9ibGVtLiAgVGhlIG5hbWUKLS8vICAgJ0VsZW1UZW1wbGF0ZUVsZW1lbnQnIGlzIHRoZSBuYW1lIG9mIGEgY2xhc3MsIGFuZCBzaG91bGQgbm90IGJlCi0vLyAgIHRyYW5zbGF0ZWQuCi0gICAgeyBFUl9BU1NFUlRfTk9fVEVNUExBVEVfUEFSRU5ULAotICAgICAiXHVENTA0XHVCODVDXHVBREY4XHVCNzk4XHVCQTM4IFx1QzYyNFx1Qjk1OFx1Qzc4NVx1QjJDOFx1QjJFNCEgXHVENDVDXHVENjA0XHVDMkREXHVDNUQwIEVsZW1UZW1wbGF0ZUVsZW1lbnQgXHVDMEMxXHVDNzA0XHVBQzAwIFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNCEifSwKLQotCi0vLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIHNob3VsZCBub3Qgbm9ybWFsbHkgYmUgZGlzcGxheWVkCi0vLyAgIHRvIHVzZXJzLiAgSXQgZGVzY3JpYmVzIGEgc2l0dWF0aW9uIGluIHdoaWNoIHRoZSBwcm9jZXNzb3IgaGFzIGRldGVjdGVkCi0vLyAgIGFuIGludGVybmFsIGNvbnNpc3RlbmN5IHByb2JsZW0gaW4gaXRzZWxmLCBhbmQgaXQgcHJvdmlkZXMgdGhpcyBtZXNzYWdlCi0vLyAgIGZvciB0aGUgZGV2ZWxvcGVyIHRvIGhlbHAgZGlhZ25vc2UgdGhlIHByb2JsZW0uICBUaGUgc3Vic3RpdHV0aW9uIHRleHQKLS8vICAgcHJvdmlkZXMgZnVydGhlciBpbmZvcm1hdGlvbiBpbiBvcmRlciB0byBkaWFnbm9zZSB0aGUgcHJvYmxlbS4gIFRoZSBuYW1lCi0vLyAgICdSZWR1bmRlbnRFeHByRWxpbWluYXRvcicgaXMgdGhlIG5hbWUgb2YgYSBjbGFzcywgYW5kIHNob3VsZCBub3QgYmUKLS8vICAgdHJhbnNsYXRlZC4KLSAgICB7IEVSX0FTU0VSVF9SRURVTkRFTlRfRVhQUl9FTElNSU5BVE9SLAotICAgICAiUmVkdW5kZW50RXhwckVsaW1pbmF0b3JcdUM1RDAgXHVENTA0XHVCODVDXHVBREY4XHVCNzk4XHVCQTM4IFx1QUM4MFx1Qzk5RFx1Qzc3NCBcdUM3ODhcdUM3NEM6IHswfSJ9LAotCi0gICAgeyBFUl9OT1RfQUxMT1dFRF9JTl9QT1NJVElPTiwKLSAgICAgIlx1QzJBNFx1RDBDMFx1Qzc3Q1x1QzJEQ1x1RDJCOFx1Qzc1OCBcdUM3NzQgXHVDNzA0XHVDRTU4XHVDNUQwXHVCMjk0IHswfVx1Qzc3NChcdUFDMDApIFx1RDVDOFx1QzZBOVx1QjQxOFx1QzlDMCBcdUM1NEFcdUMyQjVcdUIyQzhcdUIyRTQhIn0sCi0KLSAgICB7IEVSX05PTldISVRFU1BBQ0VfTk9UX0FMTE9XRURfSU5fUE9TSVRJT04sCi0gICAgICJcdUMyQTRcdUQwQzBcdUM3N0NcdUMyRENcdUQyQjhcdUM3NTggXHVDNzc0IFx1QzcwNFx1Q0U1OFx1QzVEMFx1QjI5NCBcdUFDRjVcdUJDMzFcdUM3NzQgXHVDNTQ0XHVCMkNDIFx1RDE0RFx1QzJBNFx1RDJCOFx1QjI5NCBcdUQ1QzhcdUM2QTlcdUI0MThcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0ISJ9LAotCi0gIC8vIFRoaXMgY29kZSBpcyBzaGFyZWQgd2l0aCB3YXJuaW5nIGNvZGVzLgotICAvLyBTeXN0ZW1JZCBVbmtub3duCi0gICAgeyBJTlZBTElEX1RDSEFSLAotICAgICAiXHVDNzk4XHVCQUJCXHVCNDFDIFx1QUMxMjogezF9XHVDNzc0KFx1QUMwMCkgQ0hBUiBcdUMxOERcdUMxMzFcdUM1RDAgXHVDMEFDXHVDNkE5XHVCNDI4OiB7MH0uIENIQVIgXHVDNzIwXHVENjE1XHVDNzU4IFx1QzE4RFx1QzEzMVx1Qzc0MCAxXHVDNzkwXHVDNUVDXHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNCEifSwKLQotICAgIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgaXMgdXNlZCBpZiB0aGUgdmFsdWUgb2YKLSAgICAvLyBhbiBhdHRyaWJ1dGUgaW4gYSBzdHlsZXNoZWV0IGlzIGludmFsaWQuICAiUU5BTUUiIGlzIHRoZSBYTUwgZGF0YS10eXBlIG9mCi0gICAgLy8gdGhlIGF0dHJpYnV0ZSwgYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCB7MX0gaXMKLSAgICAvLyB0aGUgYXR0cmlidXRlIHZhbHVlIGFuZCB7MH0gaXMgdGhlIGF0dHJpYnV0ZSBuYW1lLgotICAvL1RoZSBmb2xsb3dpbmcgY29kZXMgYXJlIHNoYXJlZCB3aXRoIHRoZSB3YXJuaW5nIGNvZGVzLi4uCi0gICAgeyBJTlZBTElEX1FOQU1FLAotICAgICAiXHVDNzk4XHVCQUJCXHVCNDFDIFx1QUMxMjogezF9XHVDNzc0KFx1QUMwMCkgUU5BTUUgXHVDMThEXHVDMTMxXHVDNUQwIFx1QzBBQ1x1QzZBOVx1QjQyODogezB9In0sCi0KLSAgICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIGlzIHVzZWQgaWYgdGhlIHZhbHVlIG9mCi0gICAgLy8gYW4gYXR0cmlidXRlIGluIGEgc3R5bGVzaGVldCBpcyBpbnZhbGlkLiAgIkVOVU0iIGlzIHRoZSBYTUwgZGF0YS10eXBlIG9mCi0gICAgLy8gdGhlIGF0dHJpYnV0ZSwgYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCB7MX0gaXMKLSAgICAvLyB0aGUgYXR0cmlidXRlIHZhbHVlLCB7MH0gaXMgdGhlIGF0dHJpYnV0ZSBuYW1lLCBhbmQgezJ9IGlzIGEgbGlzdCBvZiB2YWxpZAotICAgIC8vIHZhbHVlcy4KLSAgICB7IElOVkFMSURfRU5VTSwKLSAgICAgIlx1Qzc5OFx1QkFCQlx1QjQxQyBcdUFDMTI6IHsxfVx1Qzc3NChcdUFDMDApIEVOVU0gXHVDMThEXHVDMTMxXHVDNUQwIFx1QzBBQ1x1QzZBOVx1QjQyODogezB9LiBcdUM4MDFcdUQ1NjlcdUQ1NUMgXHVBQzEyOiB7Mn0uIn0sCi0KLS8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgaXMgdXNlZCBpZiB0aGUgdmFsdWUgb2YKLS8vIGFuIGF0dHJpYnV0ZSBpbiBhIHN0eWxlc2hlZXQgaXMgaW52YWxpZC4gICJOTVRPS0VOIiBpcyB0aGUgWE1MIGRhdGEtdHlwZQotLy8gb2YgdGhlIGF0dHJpYnV0ZSwgYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCB7MX0gaXMKLS8vIHRoZSBhdHRyaWJ1dGUgdmFsdWUgYW5kIHswfSBpcyB0aGUgYXR0cmlidXRlIG5hbWUuCi0gICAgeyBJTlZBTElEX05NVE9LRU4sCi0gICAgICJcdUM3OThcdUJBQkJcdUI0MUMgXHVBQzEyOiB7MX1cdUM3NzQoXHVBQzAwKSBOTVRPS0VOIFx1QzE4RFx1QzEzMVx1QzVEMCBcdUMwQUNcdUM2QTlcdUI0Mjg6IHswfSAifSwKLQotLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBpcyB1c2VkIGlmIHRoZSB2YWx1ZSBvZgotLy8gYW4gYXR0cmlidXRlIGluIGEgc3R5bGVzaGVldCBpcyBpbnZhbGlkLiAgIk5DTkFNRSIgaXMgdGhlIFhNTCBkYXRhLXR5cGUKLS8vIG9mIHRoZSBhdHRyaWJ1dGUsIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgezF9IGlzCi0vLyB0aGUgYXR0cmlidXRlIHZhbHVlIGFuZCB7MH0gaXMgdGhlIGF0dHJpYnV0ZSBuYW1lLgotICAgIHsgSU5WQUxJRF9OQ05BTUUsCi0gICAgICJcdUM3OThcdUJBQkJcdUI0MUMgXHVBQzEyOiB7MX1cdUM3NzQoXHVBQzAwKSBOQ05BTUUgXHVDMThEXHVDMTMxXHVDNUQwIFx1QzBBQ1x1QzZBOVx1QjQyODogezB9ICJ9LAotCi0vLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIGlzIHVzZWQgaWYgdGhlIHZhbHVlIG9mCi0vLyBhbiBhdHRyaWJ1dGUgaW4gYSBzdHlsZXNoZWV0IGlzIGludmFsaWQuICAiYm9vbGVhbiIgaXMgdGhlIFhTTFQgZGF0YS10eXBlCi0vLyBvZiB0aGUgYXR0cmlidXRlLCBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHsxfSBpcwotLy8gdGhlIGF0dHJpYnV0ZSB2YWx1ZSBhbmQgezB9IGlzIHRoZSBhdHRyaWJ1dGUgbmFtZS4KLSAgICB7IElOVkFMSURfQk9PTEVBTiwKLSAgICAgIlx1Qzc5OFx1QkFCQlx1QjQxQyBcdUFDMTI6IHsxfVx1Qzc3NChcdUFDMDApIGJvb2xlYW4gXHVDMThEXHVDMTMxXHVDNUQwIFx1QzBBQ1x1QzZBOVx1QjQyODogezB9ICJ9LAotCi0vLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIGlzIHVzZWQgaWYgdGhlIHZhbHVlIG9mCi0vLyBhbiBhdHRyaWJ1dGUgaW4gYSBzdHlsZXNoZWV0IGlzIGludmFsaWQuICAibnVtYmVyIiBpcyB0aGUgWFNMVCBkYXRhLXR5cGUKLS8vIG9mIHRoZSBhdHRyaWJ1dGUsIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgezF9IGlzCi0vLyB0aGUgYXR0cmlidXRlIHZhbHVlIGFuZCB7MH0gaXMgdGhlIGF0dHJpYnV0ZSBuYW1lLgotICAgICB7IElOVkFMSURfTlVNQkVSLAotICAgICAiXHVDNzk4XHVCQUJCXHVCNDFDIFx1QUMxMjogezF9XHVDNzc0KFx1QUMwMCkgbnVtYmVyIFx1QzE4RFx1QzEzMVx1QzVEMCBcdUMwQUNcdUM2QTlcdUI0Mjg6IHswfSAifSwKLQotCi0gIC8vIEVuZCBvZiBzaGFyZWQgY29kZXMuLi4KLQotLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIEEgIm1hdGNoIHBhdHRlcm4iIGlzIGEgc3BlY2lhbCBmb3JtIG9mIFhQYXRoIGV4cHJlc3Npb24KLS8vIHRoYXQgaXMgdXNlZCBmb3IgbWF0Y2hpbmcgcGF0dGVybnMuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YKLS8vIGEgZnVuY3Rpb24uICBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB3aGVuIHRoaXMgZnVuY3Rpb24gaXMgcmVmZXJlbmNlZCBpbgotLy8gYSBtYXRjaCBwYXR0ZXJuLCBpdHMgYXJndW1lbnQgbXVzdCBiZSBhIHN0cmluZyBsaXRlcmFsIChvciBjb25zdGFudC4pCi0vLyBFUl9BUkdfTElURVJBTCAtIG5ldyBlcnJvciBtZXNzYWdlIGZvciBidWd6aWxsYSAvLzUyMDIKLSAgICB7IEVSX0FSR19MSVRFUkFMLAotICAgICAiXHVDNzdDXHVDRTU4IFx1RDMyOFx1RDEzNFx1Qzc1OCB7MH1cdUM1RDAgXHVCMzAwXHVENTVDIFx1Qzc3OFx1QzIxOFx1QjI5NCBcdUI5QUNcdUQxMzBcdUI3RjRcdUM3NzRcdUM1QjRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LiJ9LAotCi0vLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHR3byBkZWZpbml0aW9ucyBvZgotLy8gYSB2YXJpYWJsZS4gIEEgImdsb2JhbCB2YXJpYWJsZSIgaXMgYSB2YXJpYWJsZSB0aGF0IGlzIGFjY2Vzc2libGUgZXZlcnl3aGVyCi0vLyBpbiB0aGUgc3R5bGVzaGVldC4KLS8vIEVSX0RVUExJQ0FURV9HTE9CQUxfVkFSIC0gbmV3IGVycm9yIG1lc3NhZ2UgZm9yIGJ1Z3ppbGxhICM3OTAKLSAgICB7IEVSX0RVUExJQ0FURV9HTE9CQUxfVkFSLAotICAgICAiXHVDODA0XHVDNUVEIFx1QkNDMFx1QzIxOCBcdUMxMjBcdUM1QjhcdUM3NzQgXHVDOTExXHVCQ0Y1XHVCNDI5XHVCMkM4XHVCMkU0LiJ9LAotCi0KLS8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdHdvIGRlZmluaXRpb25zIG9mCi0vLyBhIHZhcmlhYmxlIHdlcmUgZW5jb3VudGVyZWQuCi0vLyBFUl9EVVBMSUNBVEVfVkFSIC0gbmV3IGVycm9yIG1lc3NhZ2UgZm9yIGJ1Z3ppbGxhICM3OTAKLSAgICB7IEVSX0RVUExJQ0FURV9WQVIsCi0gICAgICJcdUJDQzBcdUMyMTggXHVDMTIwXHVDNUI4XHVDNzc0IFx1QzkxMVx1QkNGNVx1QjQyOVx1QjJDOFx1QjJFNC4ifSwKLQotICAgIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAieHNsOnRlbXBsYXRlLCAibmFtZSIgYW5kICJtYXRjaCIgYXJlIFhTTFQga2V5d29yZHMKLSAgICAvLyB3aGljaCBtdXN0IG5vdCBiZSB0cmFuc2xhdGVkLgotICAgIC8vIEVSX1RFTVBMQVRFX05BTUVfTUFUQ0ggLSBuZXcgZXJyb3IgbWVzc2FnZSBmb3IgYnVnemlsbGEgIzc4OQotICAgIHsgRVJfVEVNUExBVEVfTkFNRV9NQVRDSCwKLSAgICAgInhzbDp0ZW1wbGF0ZVx1QzVEMFx1QjI5NCBuYW1lIFx1QjYxMFx1QjI5NCBtYXRjaCBcdUMxOERcdUMxMzEgXHVDOTExIFx1RDU1OFx1QjA5OFx1QUMwMCBcdUM3ODhcdUFDNzBcdUIwOTggXHVCQUE4XHVCNDUwIFx1Qzc4OFx1QzVCNFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgImV4Y2x1ZGUtcmVzdWx0LXByZWZpeGVzIiBpcyBhbiBYU0xUIGtleXdvcmQgd2hpY2gKLSAgICAvLyBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCBhIG5hbWVzcGFjZSBwcmVmaXgKLSAgICAvLyBlbmNvdW50ZXJlZCBhcyBwYXJ0IG9mIHRoZSB2YWx1ZSBvZiB0aGUgZXhjbHVkZS1yZXN1bHQtcHJlZml4ZXMgYXR0cmlidXRlCi0gICAgLy8gd2FzIGluIGVycm9yLgotICAgIC8vIEVSX0lOVkFMSURfUFJFRklYIC0gbmV3IGVycm9yIG1lc3NhZ2UgZm9yIGJ1Z3ppbGxhICM3ODgKLSAgICB7IEVSX0lOVkFMSURfUFJFRklYLAotICAgICAiZXhjbHVkZS1yZXN1bHQtcHJlZml4ZXNcdUM3NTggXHVDODExXHVCNDUwXHVDNUI0XHVBQzAwIFx1QkQ4MFx1QzgwMVx1RDU2OVx1RDU2ODogezB9In0sCi0KLSAgICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQW4gImF0dHJpYnV0ZSBzZXQiIGlzIGEgc2V0IG9mIGF0dHJpYnV0ZXMgdGhhdCBjYW4KLSAgICAvLyBiZSBhZGRlZCB0byBhbiBlbGVtZW50IGluIHRoZSBvdXRwdXQgZG9jdW1lbnQgYXMgYSBncm91cC4gIFRoZSBtZXNzYWdlCi0gICAgLy8gaW5kaWNhdGVzIHRoYXQgdGhlcmUgd2FzIGEgcmVmZXJlbmNlIHRvIGFuIGF0dHJpYnV0ZSBzZXQgbmFtZWQgezB9IHRoYXQKLSAgICAvLyB3YXMgbmV2ZXIgZGVmaW5lZC4KLSAgICAvLyBFUl9OT19BVFRSSUJfU0VUIC0gbmV3IGVycm9yIG1lc3NhZ2UgZm9yIGJ1Z3ppbGxhICM3ODIKLSAgICB7IEVSX05PX0FUVFJJQl9TRVQsCi0gICAgICJcdUM3NzRcdUI5ODRcdUM3NzQgezB9XHVDNzc4IGF0dHJpYnV0ZS1zZXRcdUFDMDAgXHVDODc0XHVDN0FDXHVENTU4XHVDOUMwIFx1QzU0QVx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAgIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhlcmUgd2FzIGEgcmVmZXJlbmNlCi0gICAgLy8gdG8gYSBmdW5jdGlvbiBuYW1lZCB7MH0gZm9yIHdoaWNoIG5vIGZ1bmN0aW9uIGRlZmluaXRpb24gY291bGQgYmUgZm91bmQuCi0gICAgeyBFUl9GVU5DVElPTl9OT1RfRk9VTkQsCi0gICAgICJcdUM3NzRcdUI5ODRcdUM3NzQgezB9XHVDNzc4IFx1RDU2OFx1QzIxOFx1QUMwMCBcdUM4NzRcdUM3QUNcdUQ1NThcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUgWFNMVCBpbnN0cnVjdGlvbgotICAgIC8vIHRoYXQgaXMgbmFtZWQgYnkgdGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHswfSBtdXN0IG5vdCBjb250YWluIG90aGVyIFhTTFQKLSAgICAvLyBpbnN0cnVjdGlvbnMgKGNvbnRlbnQpIG9yIGEgInNlbGVjdCIgYXR0cmlidXRlLiAgVGhlIHdvcmQgInNlbGVjdCIgaXMKLSAgICAvLyBhbiBYU0xUIGtleXdvcmQgaW4gdGhpcyBjYXNlIGFuZCBtdXN0IG5vdCBiZSB0cmFuc2xhdGVkLgotICAgIHsgRVJfQ0FOVF9IQVZFX0NPTlRFTlRfQU5EX1NFTEVDVCwKLSAgICAgInswfSBcdUM2OTRcdUMxOENcdUM1RDBcdUIyOTQgY29udGVudCBcdUMxOERcdUMxMzFcdUFDRkMgc2VsZWN0IFx1QzE4RFx1QzEzMVx1Qzc3NCBcdUQ1NjhcdUFFRDggXHVEM0VDXHVENTY4XHVCNDE4XHVDOUMwIFx1QzU0QVx1QzU0NFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoZSB2YWx1ZSBhcmd1bWVudAotICAgIC8vIG9mIHNldFBhcmFtZXRlciBtdXN0IGJlIGEgdmFsaWQgSmF2YSBPYmplY3QuCi0gICAgeyBFUl9JTlZBTElEX1NFVF9QQVJBTV9WQUxVRSwKLSAgICAgInswfSBcdUI5RTRcdUFDMUNcdUJDQzBcdUMyMThcdUM3NTggXHVBQzEyXHVDNzQwIFx1QzgwMVx1RDU2OVx1RDU1QyBKYXZhIFx1QUMxRFx1Q0NCNFx1QzVFQ1x1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICB7IEVSX0lOVkFMSURfTkFNRVNQQUNFX1VSSV9WQUxVRV9GT1JfUkVTVUxUX1BSRUZJWF9GT1JfREVGQVVMVCwKLSAgICAgICJ4c2w6bmFtZXNwYWNlLWFsaWFzIFx1QzY5NFx1QzE4Q1x1Qzc1OCByZXN1bHQtcHJlZml4IFx1QzE4RFx1QzEzMVx1QzVEMCBcdUIzMDBcdUQ1NUMgXHVBQzEyXHVDNzQwICcjZGVmYXVsdCdcdUM3NzRcdUM5QzBcdUI5Q0MgXHVDNjk0XHVDMThDXHVDNUQwIFx1QjMwMFx1RDU1QyBcdUJDOTRcdUM3MDRcdUM1RDBcdUMxMUMgXHVBRTMwXHVCQ0Y4IFx1QjEyNFx1Qzc4NFx1QzJBNFx1RDM5OFx1Qzc3NFx1QzJBNFx1QUMwMCBcdUMxMjBcdUM1QjhcdUI0MThcdUM5QzAgXHVDNTRBXHVDNTU4XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBFUl9JTlZBTElEX05BTUVTUEFDRV9VUklfVkFMVUVfRk9SX1JFU1VMVF9QUkVGSVgsCi0gICAgICAieHNsOm5hbWVzcGFjZS1hbGlhcyBcdUM2OTRcdUMxOENcdUM3NTggcmVzdWx0LXByZWZpeCBcdUMxOERcdUMxMzFcdUM1RDAgXHVCMzAwXHVENTVDIFx1QUMxMlx1Qzc0MCAnJ3swfScnXHVDNzc0XHVDOUMwXHVCOUNDIFx1QzY5NFx1QzE4Q1x1QzVEMCBcdUIzMDBcdUQ1NUMgXHVCQzk0XHVDNzA0XHVDNUQwXHVDMTFDICcnezB9JycgXHVDODExXHVCNDUwXHVDNUI0XHVDNzU4IFx1QjEyNFx1Qzc4NFx1QzJBNFx1RDM5OFx1Qzc3NFx1QzJBNFx1QUMwMCBcdUMxMjBcdUM1QjhcdUI0MThcdUM5QzAgXHVDNTRBXHVDNTU4XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBFUl9TRVRfRkVBVFVSRV9OVUxMX05BTUUsCi0gICAgICAiXHVBRTMwXHVCMkE1IFx1Qzc3NFx1Qjk4NFx1Qzc0MCBUcmFuc2Zvcm1lckZhY3Rvcnkuc2V0RmVhdHVyZShcdUJCMzhcdUM3OTBcdUM1RjQgXHVDNzc0XHVCOTg0LCBcdUJEODBcdUM2QjggXHVBQzEyKVx1QzVEMFx1QzExQyBcdUIxMTBcdUM3N0MgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAgIHsgRVJfR0VUX0ZFQVRVUkVfTlVMTF9OQU1FLAotICAgICAgIlx1QUUzMFx1QjJBNSBcdUM3NzRcdUI5ODRcdUM3NDAgVHJhbnNmb3JtZXJGYWN0b3J5LmdldEZlYXR1cmUoXHVCQjM4XHVDNzkwXHVDNUY0IFx1Qzc3NFx1Qjk4NClcdUM1RDBcdUMxMUMgXHVCMTEwXHVDNzdDIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICB7IEVSX1VOU1VQUE9SVEVEX0ZFQVRVUkUsCi0gICAgICAiXHVDNzc0IFRyYW5zZm9ybWVyRmFjdG9yeVx1QzVEMFx1QzExQyAnJ3swfScnIFx1QUUzMFx1QjJBNVx1Qzc0NCBcdUMxMjRcdUM4MTVcdUQ1NjAgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAgIHsgRVJfRVhURU5TSU9OX0VMRU1FTlRfTk9UX0FMTE9XRURfSU5fU0VDVVJFX1BST0NFU1NJTkcsCi0gICAgICAgICAgIlx1QkNGNFx1QzU0OCBcdUNDOThcdUI5QUMgXHVBRTMwXHVCMkE1XHVDNzc0IHRydWVcdUI4NUMgXHVDMTI0XHVDODE1XHVCNDFDIFx1QUNCRFx1QzZCMCBcdUQ2NTVcdUM3QTUgXHVDNjk0XHVDMThDICcnezB9JydcdUM3NDQoXHVCOTdDKSBcdUMwQUNcdUM2QTlcdUQ1NjAgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAgIHsgRVJfTkFNRVNQQUNFX0NPTlRFWFRfTlVMTF9OQU1FU1BBQ0UsCi0gICAgICAiXHVCMTEwIFx1QjEyNFx1Qzc4NFx1QzJBNFx1RDM5OFx1Qzc3NFx1QzJBNCBVUklcdUM1RDAgXHVCMzAwXHVENTVDIFx1QzgxMVx1QjQ1MFx1QzVCNFx1Qjk3QyBcdUFDMDBcdUM4MzhcdUM2MkMgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAgIHsgRVJfTkFNRVNQQUNFX0NPTlRFWFRfTlVMTF9QUkVGSVgsCi0gICAgICAiXHVCMTEwIFx1QzgxMVx1QjQ1MFx1QzVCNFx1QzVEMCBcdUIzMDBcdUQ1NUMgXHVCMTI0XHVDNzg0XHVDMkE0XHVEMzk4XHVDNzc0XHVDMkE0IFVSSVx1Qjk3QyBcdUFDMDBcdUM4MzhcdUM2MkMgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAgIHsgRVJfWFBBVEhfUkVTT0xWRVJfTlVMTF9RTkFNRSwKLSAgICAgICJcdUQ1NjhcdUMyMTggXHVDNzc0XHVCOTg0XHVDNzQwIFx1QjExMFx1Qzc3QyBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBFUl9YUEFUSF9SRVNPTFZFUl9ORUdBVElWRV9BUklUWSwKLSAgICAgICJcdUM3NzhcdUM3OTAgXHVDMjE4XHVCMjk0IFx1Qzc0Q1x1QzIxOFx1Qzc3QyBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotICAvLyBXYXJuaW5ncy4uLgotCi0gICAgeyBXR19GT1VORF9DVVJMWUJSQUNFLAotICAgICAgIid9J1x1Qjk3QyBcdUNDM0VcdUM1NThcdUM5QzBcdUI5Q0MgXHVDNUY0XHVCODI0IFx1Qzc4OFx1QjI5NCBcdUMxOERcdUMxMzEgXHVEMTVDXHVENTBDXHVCOUFDXHVEMkI4XHVBQzAwIFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNCEifSwKLQotICAgIHsgV0dfQ09VTlRfQVRUUklCX01BVENIRVNfTk9fQU5DRVNUT1IsCi0gICAgICAiXHVBQ0JEXHVBQ0UwOiBjb3VudCBcdUMxOERcdUMxMzFcdUM3NzQgeHNsOm51bWJlclx1Qzc1OCBcdUM4NzBcdUMwQzFcdUFDRkMgXHVDNzdDXHVDRTU4XHVENTU4XHVDOUMwIFx1QzU0QVx1QzJCNVx1QjJDOFx1QjJFNCEgXHVCMzAwXHVDMEMxID0gezB9In0sCi0KLSAgICB7IFdHX0VYUFJfQVRUUklCX0NIQU5HRURfVE9fU0VMRUNULAotICAgICAgIlx1Qzc3NFx1QzgwNCBcdUFENkNcdUJCMzg6ICdleHByJyBcdUMxOERcdUMxMzFcdUM3NTggXHVDNzc0XHVCOTg0XHVDNzc0ICdzZWxlY3QnXHVCODVDIFx1QkNDMFx1QUNCRFx1QjQxOFx1QzVDOFx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAgIHsgV0dfTk9fTE9DQUxFX0lOX0ZPUk1BVE5VTUJFUiwKLSAgICAgICJYYWxhblx1Qzc3NCBmb3JtYXQtbnVtYmVyIFx1RDU2OFx1QzIxOFx1QzVEMFx1QzExQyBcdUI4NUNcdUNGMDBcdUM3N0MgXHVDNzc0XHVCOTg0XHVDNzQ0IFx1QzU0NFx1QzlDMSBcdUNDOThcdUI5QUNcdUQ1NThcdUM5QzAgXHVDNTRBXHVDNTU4XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBXR19MT0NBTEVfTk9UX0ZPVU5ELAotICAgICAgIlx1QUNCRFx1QUNFMDogeG1sOmxhbmc9ezB9XHVDNUQwIFx1QjMwMFx1RDU1QyBcdUI4NUNcdUNGMDBcdUM3N0NcdUM3NDQgXHVDQzNFXHVDNzQ0IFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICB7IFdHX0NBTk5PVF9NQUtFX1VSTF9GUk9NLAotICAgICAgInswfVx1QzVEMFx1QzExQyBVUkxcdUM3NDQgXHVDMEREXHVDMTMxXHVENTYwIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICB7IFdHX0NBTk5PVF9MT0FEX1JFUVVFU1RFRF9ET0MsCi0gICAgICAiXHVDNjk0XHVDQ0FEXHVCNDFDIFx1QkIzOFx1QzExQ1x1Qjk3QyBcdUI4NUNcdUI0RENcdUQ1NjAgXHVDMjE4IFx1QzVDNlx1Qzc0QzogezB9In0sCi0KLSAgICB7IFdHX0NBTk5PVF9GSU5EX0NPTExBVE9SLAotICAgICAgIjxzb3J0IHhtbDpsYW5nPXswfVx1QzVEMCBcdUIzMDBcdUQ1NUMgXHVCQ0QxXHVENTY5XHVBRTMwXHVCOTdDIFx1Q0MzRVx1Qzc0NCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBXR19GVU5DVElPTlNfU0hPVUxEX1VTRV9VUkwsCi0gICAgICAiXHVDNzc0XHVDODA0IFx1QUQ2Q1x1QkIzODogXHVENTY4XHVDMjE4IFx1QkE4NVx1QjgzOVx1QzVEMCB7MH0gVVJMXHVDNzc0IFx1QzBBQ1x1QzZBOVx1QjQxOFx1QzVCNFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICB7IFdHX0VOQ09ESU5HX05PVF9TVVBQT1JURURfVVNJTkdfVVRGOCwKLSAgICAgICJcdUM3NzhcdUNGNTRcdUI1MjlcdUM3NzQgXHVDOUMwXHVDNkQwXHVCNDE4XHVDOUMwIFx1QzU0QVx1Qzc0QzogezB9LiBVVEYtOFx1Qzc0NCBcdUMwQUNcdUM2QTlcdUQ1NThcdUIyOTQgXHVDOTExXHVDNzg1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBXR19FTkNPRElOR19OT1RfU1VQUE9SVEVEX1VTSU5HX0pBVkEsCi0gICAgICAiXHVDNzc4XHVDRjU0XHVCNTI5XHVDNzc0IFx1QzlDMFx1QzZEMFx1QjQxOFx1QzlDMCBcdUM1NEFcdUM3NEM6IHswfS4gSmF2YSB7MX1cdUM3NDQoXHVCOTdDKSBcdUMwQUNcdUM2QTlcdUQ1NThcdUIyOTQgXHVDOTExXHVDNzg1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBXR19TUEVDSUZJQ0lUWV9DT05GTElDVFMsCi0gICAgICAiXHVEMkI5XHVDMjE4IFx1Q0RBOVx1QjNDQ1x1Qzc3NCBcdUJDMUNcdUFDQUNcdUI0Mjg6IHswfS4gXHVDMkE0XHVEMEMwXHVDNzdDXHVDMkRDXHVEMkI4XHVDNUQwXHVDMTFDIFx1QkMxQ1x1QUNBQ1x1QjQxQyBcdUI5QzhcdUM5QzBcdUI5QzkgXHVENTZEXHVCQUE5XHVDNzc0IFx1QzBBQ1x1QzZBOVx1QjQyOVx1QjJDOFx1QjJFNC4ifSwKLQotICAgIHsgV0dfUEFSU0lOR19BTkRfUFJFUEFSSU5HLAotICAgICAgIj09PT09PT09PSBcdUFENkNcdUJCMzggXHVCRDg0XHVDMTFEIFx1RDZDNCB7MH0gXHVDOTAwXHVCRTQ0IFx1QzkxMSA9PT09PT09PT09In0sCi0KLSAgICB7IFdHX0FUVFJfVEVNUExBVEUsCi0gICAgICJcdUMxOERcdUMxMzEgXHVEMTVDXHVENTBDXHVCOUFDXHVEMkI4LCB7MH0ifSwKLQotICAgIHsgV0dfQ09ORkxJQ1RfQkVUV0VFTl9YU0xTVFJJUFNQQUNFX0FORF9YU0xQUkVTRVJWRVNQQUNFLAotICAgICAgInhzbDpzdHJpcC1zcGFjZVx1QzY0MCB4c2w6cHJlc2VydmUtc3BhY2UgXHVBQzA0XHVDNzU4IFx1Qzc3Q1x1Q0U1OCBcdUNEQTlcdUIzQ0MifSwKLQotICAgIHsgV0dfQVRUUklCX05PVF9IQU5ETEVELAotICAgICAgIlhhbGFuXHVDNzc0IHswfSBcdUMxOERcdUMxMzFcdUM3NDQgXHVDNTQ0XHVDOUMxIFx1Q0M5OFx1QjlBQ1x1RDU1OFx1QzlDMCBcdUM1NEFcdUM1NThcdUMyQjVcdUIyQzhcdUIyRTQhIn0sCi0KLSAgICB7IFdHX05PX0RFQ0lNQUxGT1JNQVRfREVDTEFSQVRJT04sCi0gICAgICAiXHVDMkVEXHVDOUM0XHVDMjE4IFx1RDYxNVx1QzJERFx1QzVEMCBcdUIzMDBcdUQ1NUMgXHVDMTIwXHVDNUI4XHVDNzQ0IFx1Q0MzRVx1Qzc0NCBcdUMyMTggXHVDNUM2XHVDNzRDOiB7MH0ifSwKLQotICAgIHsgV0dfT0xEX1hTTFRfTlMsCi0gICAgICJYU0xUIFx1QjEyNFx1Qzc4NFx1QzJBNFx1RDM5OFx1Qzc3NFx1QzJBNFx1QUMwMCBcdUIyMDRcdUI3N0RcdUI0MThcdUFDNzBcdUIwOTggXHVDNjJDXHVCQzE0XHVCOTc0XHVDOUMwIFx1QzU0QVx1QzJCNVx1QjJDOFx1QjJFNC4gIn0sCi0KLSAgICB7IFdHX09ORV9ERUZBVUxUX1hTTERFQ0lNQUxGT1JNQVRfQUxMT1dFRCwKLSAgICAgICJcdUFFMzBcdUJDRjggeHNsOmRlY2ltYWwtZm9ybWF0IFx1QzEyMFx1QzVCOFx1Qzc0MCBcdUQ1NThcdUIwOThcdUI5Q0MgXHVENUM4XHVDNkE5XHVCNDI5XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBXR19YU0xERUNJTUFMRk9STUFUX05BTUVTX01VU1RfQkVfVU5JUVVFLAotICAgICAgInhzbDpkZWNpbWFsLWZvcm1hdCBcdUM3NzRcdUI5ODRcdUM3NDAgXHVBQ0UwXHVDNzIwXHVENTc0XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4gXCJ7MH1cIiBcdUM3NzRcdUI5ODRcdUM3NzQgXHVDOTExXHVCQ0Y1XHVCNDE4XHVDNUM4XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBXR19JTExFR0FMX0FUVFJJQlVURSwKLSAgICAgICJ7MH1cdUM1RDAgXHVDNzk4XHVCQUJCXHVCNDFDIFx1QzE4RFx1QzEzMVx1Qzc3NCBcdUM3ODhcdUM3NEM6IHsxfSJ9LAotCi0gICAgeyBXR19DT1VMRF9OT1RfUkVTT0xWRV9QUkVGSVgsCi0gICAgICAiXHVCMTI0XHVDNzg0XHVDMkE0XHVEMzk4XHVDNzc0XHVDMkE0IFx1QzgxMVx1QjQ1MFx1QzVCNFx1Qjk3QyBcdUJEODRcdUMxMURcdUQ1NjAgXHVDMjE4IFx1QzVDNlx1Qzc0QzogezB9LiBcdUIxNzhcdUI0RENcdUFDMDAgXHVCQjM0XHVDMkRDXHVCNDI5XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBXR19TVFlMRVNIRUVUX1JFUVVJUkVTX1ZFUlNJT05fQVRUUklCLAotICAgICAgInhzbDpzdHlsZXNoZWV0XHVDNUQwXHVCMjk0ICd2ZXJzaW9uJyBcdUMxOERcdUMxMzFcdUM3NzQgXHVENTQ0XHVDNjk0XHVENTY5XHVCMkM4XHVCMkU0ISJ9LAotCi0gICAgeyBXR19JTExFR0FMX0FUVFJJQlVURV9OQU1FLAotICAgICAgIlx1Qzc5OFx1QkFCQlx1QjQxQyBcdUMxOERcdUMxMzEgXHVDNzc0XHVCOTg0OiB7MH0ifSwKLQotICAgIHsgV0dfSUxMRUdBTF9BVFRSSUJVVEVfVkFMVUUsCi0gICAgICAiezB9IFx1QzE4RFx1QzEzMVx1QzVEMCBcdUM3OThcdUJBQkJcdUI0MUMgXHVBQzEyXHVDNzc0IFx1QzBBQ1x1QzZBOVx1QjQyODogezF9In0sCi0KLSAgICB7IFdHX0VNUFRZX1NFQ09ORF9BUkcsCi0gICAgICAiZG9jdW1lbnQgXHVENTY4XHVDMjE4XHVDNzU4IFx1QjQ1MFx1QkM4OFx1QzlGOCBcdUM3NzhcdUMyMThcdUM1RDBcdUMxMUMgXHVBQ0IwXHVBQ0ZDXHVCODVDIFx1QjA5OFx1RDBDMFx1QjA5QyBub2Rlc2V0XHVBQzAwIFx1QkU0NFx1QzVCNCBcdUM3ODhcdUMyQjVcdUIyQzhcdUIyRTQuIFx1QkU0OCBub2RlLXNldFx1QUMwMCBcdUJDMThcdUQ2NThcdUI0MjlcdUIyQzhcdUIyRTQuIn0sCi0KLSAgLy9Gb2xsb3dpbmcgYXJlIHRoZSBuZXcgV0FSTklORyBrZXlzIGFkZGVkIGluIFhBTEFOIGNvZGUgYmFzZSBhZnRlciBKZGsgMS40IChYYWxhbiAyLjItRDExKQotCi0gICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogICJuYW1lIiBhbmQgInhzbDpwcm9jZXNzaW5nLWluc3RydWN0aW9uIiBhcmUga2V5d29yZHMKLSAgICAvLyBhbmQgbXVzdCBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICB7IFdHX1BST0NFU1NJTkdJTlNUUlVDVElPTl9OQU1FX0NBTlRfQkVfWE1MLAotICAgICAgInhzbDpwcm9jZXNzaW5nLWluc3RydWN0aW9uIFx1Qzc3NFx1Qjk4NFx1Qzc1OCAnbmFtZScgXHVDMThEXHVDMTMxXHVBQzEyXHVDNzQwICd4bWwnXHVDNzc0IFx1QzU0NFx1QjJDOFx1QzVCNFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIm5hbWUiIGFuZCAieHNsOnByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24iIGFyZSBrZXl3b3JkcwotICAgIC8vIGFuZCBtdXN0IG5vdCBiZSB0cmFuc2xhdGVkLiAgIk5DTmFtZSIgaXMgYW4gWE1MIGRhdGEtdHlwZSBhbmQgbXVzdCBub3QgYmUKLSAgICAvLyB0cmFuc2xhdGVkLgotICAgIHsgV0dfUFJPQ0VTU0lOR0lOU1RSVUNUSU9OX05PVFZBTElEX05DTkFNRSwKLSAgICAgICJ4c2w6cHJvY2Vzc2luZy1pbnN0cnVjdGlvblx1Qzc1OCAnJ25hbWUnJyBcdUMxOERcdUMxMzFcdUFDMTJcdUM3NDAgXHVDODAxXHVENTY5XHVENTVDIE5DTmFtZVx1Qzc3NFx1QzVCNFx1QzU3QyBcdUQ1Njg6IHswfSJ9LAotCi0gICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyByZXBvcnRlZCBpZiB0aGUgc3R5bGVzaGVldCB0aGF0IGlzCi0gICAgLy8gYmVpbmcgcHJvY2Vzc2VkIGF0dGVtcHRlZCB0byBjb25zdHJ1Y3QgYW4gWE1MIGRvY3VtZW50IHdpdGggYW4gYXR0cmlidXRlIGluIGEKLSAgICAvLyBwbGFjZSBvdGhlciB0aGFuIG9uIGFuIGVsZW1lbnQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgc3BlY2lmaWVzIHRoZSBuYW1lIG9mCi0gICAgLy8gdGhlIGF0dHJpYnV0ZS4KLSAgICB7IFdHX0lMTEVHQUxfQVRUUklCVVRFX1BPU0lUSU9OLAotICAgICAgIlx1RDU1OFx1QzcwNCBcdUIxNzhcdUI0RENcdUFDMDAgXHVDMEREXHVDMTMxXHVCNDFDIFx1RDZDNCBcdUI2MTBcdUIyOTQgXHVDNjk0XHVDMThDXHVBQzAwIFx1QzBERFx1QzEzMVx1QjQxOFx1QUUzMCBcdUM4MDRcdUM1RDAgezB9IFx1QzE4RFx1QzEzMVx1Qzc0NCBcdUNEOTRcdUFDMDBcdUQ1NjAgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4gXHVDMThEXHVDMTMxXHVDNzc0IFx1QkIzNFx1QzJEQ1x1QjQyOVx1QjJDOFx1QjJFNC4ifSwKLQotICAgIHsgTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSLAotICAgICAgIlx1QzIxOFx1QzgxNVx1Qzc3NCBcdUQ1QzhcdUM2QTlcdUI0MThcdUM5QzAgXHVDNTRBXHVCMjk0IFx1QUMxRFx1Q0NCNFx1Qjk3QyBcdUMyMThcdUM4MTVcdUQ1NThcdUI4MjRcdUFDRTAgXHVDMkRDXHVCM0M0XHVENTg4XHVDMkI1XHVCMkM4XHVCMkU0LiIKLSAgICB9LAotCi0gICAgLy9DaGVjazogV0hZIFRIRVJFIElTIEEgR0FQIEIvVyBOVU1CRVJTIGluIHRoZSBYU0xURXJyb3JSZXNvdXJjZXMgcHJvcGVydGllcyBmaWxlPwotCi0gIC8vIE90aGVyIG1pc2NlbGxhbmVvdXMgdGV4dCB1c2VkIGluc2lkZSB0aGUgY29kZS4uLgotICB7ICJ1aV9sYW5ndWFnZSIsICJrbyJ9LAotICB7ICAiaGVscF9sYW5ndWFnZSIsICAia28iIH0sCi0gIHsgICJsYW5ndWFnZSIsICAia28iIH0sCi0gIHsgIkJBRF9DT0RFIiwgImNyZWF0ZU1lc3NhZ2VcdUM1RDAgXHVCMzAwXHVENTVDIFx1QjlFNFx1QUMxQ1x1QkNDMFx1QzIxOFx1QUMwMCBcdUJDOTRcdUM3MDRcdUI5N0MgXHVCQzk3XHVDNUI0XHVCMEFDXHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotICB7ICAiRk9STUFUX0ZBSUxFRCIsICJtZXNzYWdlRm9ybWF0IFx1RDYzOFx1Q0Q5QyBcdUM5MTEgXHVDNjA4XHVDNjc4XHVDMEFDXHVENTZEXHVDNzc0IFx1QkMxQ1x1QzBERFx1RDU4OFx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLSAgeyAgInZlcnNpb24iLCAiPj4+Pj4+PiBYYWxhbiBcdUJDODRcdUM4MDQgIn0sCi0gIHsgICJ2ZXJzaW9uMiIsICAiPDw8PDw8PCJ9LAotICB7ICAieWVzIiwgIlx1QzYwOCJ9LAotICB7ICJsaW5lIiwgIlx1RDU4OSBcdUJDODhcdUQ2MzgifSwKLSAgeyAiY29sdW1uIiwiXHVDNUY0IFx1QkM4OFx1RDYzOCJ9LAotICB7ICJ4c2xkb25lIiwgIlhTTFByb2Nlc3NvcjogXHVDNjQ0XHVCOENDIn0sCi0KLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlcyBwcm92aWRlIHVzYWdlIGluZm9ybWF0aW9uCi0gIC8vIGZvciB0aGUgWGFsYW4gUHJvY2VzcyBjb21tYW5kIGxpbmUuICAiUHJvY2VzcyIgaXMgdGhlIG5hbWUgb2YgYSBKYXZhIGNsYXNzLAotICAvLyBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLgotICB7ICJ4c2xQcm9jX29wdGlvbiIsICJYYWxhbi1KIFx1QkE4NVx1QjgzOVx1RDU4OSBQcm9jZXNzIFx1RDA3NFx1Qjc5OFx1QzJBNCBcdUM2MzVcdUMxNTg6In0sCi0gIHsgInhzbFByb2Nfb3B0aW9uIiwgIlhhbGFuLUogXHVCQTg1XHVCODM5XHVENTg5IFByb2Nlc3MgXHVEMDc0XHVCNzk4XHVDMkE0IFx1QzYzNVx1QzE1ODoifSwKLSAgeyAieHNsUHJvY19pbnZhbGlkX3hzbHRjX29wdGlvbiIsICJYU0xUQyBcdUJBQThcdUI0RENcdUM1RDBcdUMxMUNcdUIyOTQgezB9IFx1QzYzNVx1QzE1OFx1Qzc3NCBcdUM5QzBcdUM2RDBcdUI0MThcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotICB7ICJ4c2xQcm9jX2ludmFsaWRfeGFsYW5fb3B0aW9uIiwgInswfSBcdUM2MzVcdUMxNThcdUM3NDAgLVhTTFRDXHVDNUQwXHVCOUNDIFx1QzBBQ1x1QzZBOVx1RDU2MCBcdUMyMTggXHVDNzg4XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotICB7ICJ4c2xQcm9jX25vX2lucHV0IiwgIlx1QzYyNFx1Qjk1ODogXHVDOUMwXHVDODE1XHVCNDFDIFx1QzJBNFx1RDBDMFx1Qzc3Q1x1QzJEQ1x1RDJCOCBcdUI2MTBcdUIyOTQgXHVDNzg1XHVCODI1IHhtbFx1Qzc3NCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuIFx1QzBBQ1x1QzZBOVx1QkM5NSBcdUM5QzBcdUNFNjhcdUM1RDAgXHVCMzAwXHVENTVDIFx1QzYzNVx1QzE1OCBcdUM1QzZcdUM3NzQgXHVDNzc0IFx1QkE4NVx1QjgzOVx1Qzc0NCBcdUMyRTRcdUQ1ODlcdUQ1NThcdUMyRURcdUMyRENcdUM2MjQuIn0sCi0gIHsgInhzbFByb2NfY29tbW9uX29wdGlvbnMiLCAiLVx1Qzc3Q1x1QkMxOCBcdUM2MzVcdUMxNTgtIn0sCi0gIHsgInhzbFByb2NfeGFsYW5fb3B0aW9ucyIsICItWGFsYW4gXHVDNjM1XHVDMTU4LSJ9LAotICB7ICJ4c2xQcm9jX3hzbHRjX29wdGlvbnMiLCAiLVhTTFRDIFx1QzYzNVx1QzE1OC0ifSwKLSAgeyAieHNsUHJvY19yZXR1cm5fdG9fY29udGludWUiLCAiKFx1QUNDNFx1QzE4RFx1RDU1OFx1QjgyNFx1QkE3NCA8UmV0dXJuPiBcdUQwQTRcdUI5N0MgXHVCMjA0XHVCOTc0XHVDMkVEXHVDMkRDXHVDNjI0LikifSwKLQotICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogVGhlIG9wdGlvbiBuYW1lIGFuZCB0aGUgcGFyYW1ldGVyIG5hbWUgZG8gbm90IG5lZWQgdG8KLSAgIC8vIGJlIHRyYW5zbGF0ZWQuIE9ubHkgdHJhbnNsYXRlIHRoZSBtZXNzYWdlcyBpbiBwYXJlbnRoZXNlcy4gIE5vdGUgYWxzbyB0aGF0Ci0gICAvLyBsZWFkaW5nIHdoaXRlc3BhY2UgaW4gdGhlIG1lc3NhZ2VzIGlzIHVzZWQgdG8gaW5kZW50IHRoZSB1c2FnZSBpbmZvcm1hdGlvbgotICAgLy8gZm9yIGVhY2ggb3B0aW9uIGluIHRoZSBFbmdsaXNoIG1lc3NhZ2VzLgotICAgLy8gRG8gbm90IHRyYW5zbGF0ZSB0aGUga2V5d29yZHM6IFhTTFRDLCBTQVgsIERPTSBhbmQgRFRNLgotICB7ICJvcHRpb25YU0xUQyIsICIgICBbLVhTTFRDKFx1QkNDMFx1RDY1OFx1QzVEMCBYU0xUQyBcdUMwQUNcdUM2QTkpXSJ9LAotICB7ICJvcHRpb25JTiIsICIgICBbLUlOIGlucHV0WE1MVVJMXSJ9LAotICB7ICJvcHRpb25YU0wiLCAiICAgWy1YU0wgWFNMVHJhbnNmb3JtYXRpb25VUkxdIn0sCi0gIHsgIm9wdGlvbk9VVCIsICAiICAgWy1PVVQgb3V0cHV0RmlsZU5hbWVdIn0sCi0gIHsgIm9wdGlvbkxYQ0lOIiwgIiAgIFstTFhDSU4gY29tcGlsZWRTdHlsZXNoZWV0RmlsZU5hbWVJbl0ifSwKLSAgeyAib3B0aW9uTFhDT1VUIiwgIiAgIFstTFhDT1VUIGNvbXBpbGVkU3R5bGVzaGVldEZpbGVOYW1lT3V0T3V0XSJ9LAotICB7ICJvcHRpb25QQVJTRVIiLCAiICAgWy1QQVJTRVIgXHVBRDZDXHVCQjM4IFx1QkQ4NFx1QzExRFx1QUUzMCBcdUM1RjBcdUFDQjBcdUM3NTggXHVDODA0XHVDQ0I0IFx1RDA3NFx1Qjc5OFx1QzJBNCBcdUM3NzRcdUI5ODRdIn0sCi0gIHsgICJvcHRpb25FIiwgIiAgIFstRShcdUM1RDRcdUQyRjBcdUQyRjAgXHVDQzM4XHVDODcwIFx1RDY1NVx1QzdBNSBcdUM1NDhcdUQ1NjgpXSJ9LAotICB7ICAib3B0aW9uViIsICAiICAgWy1FKFx1QzVENFx1RDJGMFx1RDJGMCBcdUNDMzhcdUM4NzAgXHVENjU1XHVDN0E1IFx1QzU0OFx1RDU2OCldIn0sCi0gIHsgICJvcHRpb25RQyIsICIgICBbLVFDKFx1Qzc5MFx1QjNEOSBcdUQzMjhcdUQxMzQgXHVDREE5XHVCM0NDIFx1QUNCRFx1QUNFMCldIn0sCi0gIHsgICJvcHRpb25RIiwgIiAgIFstUShcdUM3OTBcdUIzRDkgXHVCQUE4XHVCNERDKV0ifSwKLSAgeyAgIm9wdGlvbkxGIiwgIiAgIFstTEYoXHVDRDlDXHVCODI1XHVDNUQwXHVCOUNDIFx1QzkwNCBcdUJDMTRcdUFGQzggXHVDMEFDXHVDNkE5IHtcdUFFMzBcdUJDRjhcdUFDMTI6IENSL0xGfSldIn0sCi0gIHsgICJvcHRpb25DUiIsICIgICBbLUNSKFx1Q0Q5Q1x1QjgyNVx1QzVEMFx1QjlDQyBcdUNFOTBcdUI5QUNcdUM5QzAgXHVCOUFDXHVEMTM0IFx1QzBBQ1x1QzZBOSB7XHVBRTMwXHVCQ0Y4XHVBQzEyOiBDUi9MRn0pXSJ9LAotICB7ICJvcHRpb25FU0NBUEUiLCAiICAgWy1FU0NBUEUoXHVDNzc0XHVDMkE0XHVDRjAwXHVDNzc0XHVENTA0IFx1QkIzOFx1Qzc5MCB7XHVBRTMwXHVCQ0Y4XHVBQzEyOiA8PiZcIidcXHJcXG59XSJ9LAotICB7ICJvcHRpb25JTkRFTlQiLCAiICAgWy1JTkRFTlQoXHVCNEU0XHVDNUVDIFx1QzRGOCBcdUFDRjVcdUJDMzEgXHVDMjE4IFx1QzgxQ1x1QzVCNCB7XHVBRTMwXHVCQ0Y4XHVBQzEyOiAwfSldIn0sCi0gIHsgIm9wdGlvblRUIiwgIiAgIFstVFQoXHVEMTVDXHVENTBDXHVCOUFDXHVEMkI4IFx1RDYzOFx1Q0Q5QyBcdUMyREMgXHVDRDk0XHVDODAxKV0ifSwKLSAgeyAib3B0aW9uVEciLCAiICAgWy1URyhcdUFDMDEgXHVDMEREXHVDMTMxIFx1Qzc3NFx1QkNBNFx1RDJCOCBcdUNEOTRcdUM4MDEpXSJ9LAotICB7ICJvcHRpb25UUyIsICIgICBbLVRTKFx1QUMwMSBcdUMxMjBcdUQwREQgXHVDNzc0XHVCQ0E0XHVEMkI4IFx1Q0Q5NFx1QzgwMSldIn0sCi0gIHsgICJvcHRpb25UVEMiLCAiICAgWy1UVEMoXHVEMTVDXHVENTBDXHVCOUFDXHVEMkI4IFx1RDU1OFx1QzcwNCBcdUQ1NkRcdUJBQTkgXHVDQzk4XHVCOUFDIFx1QzJEQyBcdUNEOTRcdUM4MDEpXSJ9LAotICB7ICJvcHRpb25UQ0xBU1MiLCAiICAgWy1UQ0xBU1MoXHVDRDk0XHVDODAxIFx1RDY1NVx1QzdBNVx1QzVEMCBcdUIzMDBcdUQ1NUMgVHJhY2VMaXN0ZW5lciBcdUQwNzRcdUI3OThcdUMyQTQpXSJ9LAotICB7ICJvcHRpb25WQUxJREFURSIsICIgICBbLVZBTElEQVRFKFx1QUM4MFx1Qzk5RCBcdUM1RUNcdUJEODAgXHVDMTI0XHVDODE1LiBcdUFFMzBcdUJDRjhcdUM4MDFcdUM3M0NcdUI4NUMgXHVBQzgwXHVDOTlEXHVDNzQwIFx1RDU3NFx1QzgxQ1x1QjQxOFx1QzVCNCBcdUM3ODhcdUM3NEMpXSJ9LAotICB7ICJvcHRpb25FRFVNUCIsICIgICBbLUVEVU1QIHtcdUMxMjBcdUQwRERcdUM4MDEgXHVEMzBDXHVDNzdDIFx1Qzc3NFx1Qjk4NH0oXHVDNjI0XHVCOTU4IFx1QkMxQ1x1QzBERCBcdUMyREMgXHVDMkE0XHVEMEREIFx1QjM2NFx1RDUwNCldIn0sCi0gIHsgICJvcHRpb25YTUwiLCAiICAgWy1YTUwoWE1MIFx1RDNFQ1x1QjlGN1x1RDEzMCBcdUMwQUNcdUM2QTkgXHVCQzBGIFhNTCBcdUQ1RTRcdUIzNTQgXHVDRDk0XHVBQzAwKV0ifSwKLSAgeyAgIm9wdGlvblRFWFQiLCAiICAgWy1URVhUKFx1QUMwNFx1QjJFOFx1RDU1QyBcdUQxNERcdUMyQTRcdUQyQjggXHVEM0VDXHVCOUY3XHVEMTMwIFx1QzBBQ1x1QzZBOSldIn0sCi0gIHsgICJvcHRpb25IVE1MIiwgIiAgIFstSFRNTChIVE1MIFx1RDNFQ1x1QjlGN1x1RDEzMCBcdUMwQUNcdUM2QTkpXSJ9LAotICB7ICAib3B0aW9uUEFSQU0iLCAiICAgWy1QQVJBTSBcdUM3NzRcdUI5ODQgXHVENDVDXHVENjA0XHVDMkREKFx1QzJBNFx1RDBDMFx1Qzc3Q1x1QzJEQ1x1RDJCOCBcdUI5RTRcdUFDMUNcdUJDQzBcdUMyMTggXHVDMTI0XHVDODE1KV0ifSwKLSAgeyAgIm5vUGFyc2VybXNnMSIsICJYU0wgXHVENTA0XHVCODVDXHVDMTM4XHVDMkE0XHVCOTdDIFx1QzJFNFx1RDMyOFx1RDU4OFx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLSAgeyAgIm5vUGFyc2VybXNnMiIsICIqKiBcdUFENkNcdUJCMzggXHVCRDg0XHVDMTFEXHVBRTMwXHVCOTdDIFx1Q0MzRVx1Qzc0NCBcdUMyMTggXHVDNUM2XHVDNzRDICoqIn0sCi0gIHsgIm5vUGFyc2VybXNnMyIsICAiXHVEMDc0XHVCNzk4XHVDMkE0IFx1QUNCRFx1Qjg1Q1x1Qjk3QyBcdUQ2NTVcdUM3NzhcdUQ1NThcdUMyRURcdUMyRENcdUM2MjQuIn0sCi0gIHsgIm5vUGFyc2VybXNnNCIsICJJQk1cdUM3NTggSmF2YVx1QzZBOSBYTUwgXHVBRDZDXHVCQjM4IFx1QkQ4NFx1QzExRFx1QUUzMFx1QUMwMCBcdUM1QzZcdUM3NDQgXHVBQ0JEXHVDNkIwIFx1QjJFNFx1Qzc0QyBcdUM3MDRcdUNFNThcdUM1RDBcdUMxMUMgXHVCMkU0XHVDNkI0XHVCODVDXHVCNERDXHVENTYwIFx1QzIxOCBcdUM3ODhcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0gIHsgIm5vUGFyc2VybXNnNSIsICJJQk0gQWxwaGFXb3JrczogaHR0cDovL3d3dy5hbHBoYXdvcmtzLmlibS5jb20vZm9ybXVsYS94bWwifSwKLSAgeyAib3B0aW9uVVJJUkVTT0xWRVIiLCAiICAgWy1VUklSRVNPTFZFUiBcdUM4MDRcdUNDQjQgXHVEMDc0XHVCNzk4XHVDMkE0IFx1Qzc3NFx1Qjk4NChVUkkgXHVCRDg0XHVDMTFEXHVDNUQwIFx1QzBBQ1x1QzZBOVx1RDU2MCBVUklSZXNvbHZlcildIn0sCi0gIHsgIm9wdGlvbkVOVElUWVJFU09MVkVSIiwgICIgICBbLUVOVElUWVJFU09MVkVSIFx1QzgwNFx1Q0NCNCBcdUQwNzRcdUI3OThcdUMyQTQgXHVDNzc0XHVCOTg0KFx1QzVENFx1RDJGMFx1RDJGMCBcdUJEODRcdUMxMURcdUM1RDAgXHVDMEFDXHVDNkE5XHVENTYwIEVudGl0eVJlc29sdmVyKV0ifSwKLSAgeyAib3B0aW9uQ09OVEVOVEhBTkRMRVIiLCAgIiAgIFstQ09OVEVOVEhBTkRMRVIgXHVDODA0XHVDQ0I0IFx1RDA3NFx1Qjc5OFx1QzJBNCBcdUM3NzRcdUI5ODQoXHVDRDlDXHVCODI1IFx1QzlDMVx1QjgyQ1x1RDY1NFx1QzVEMCBcdUMwQUNcdUM2QTlcdUQ1NjAgQ29udGVudEhhbmRsZXIpXSJ9LAotICB7ICAib3B0aW9uTElORU5VTUJFUlMiLCAgIiAgIFstTChcdUMxOENcdUMyQTQgXHVCQjM4XHVDMTFDXHVDNUQwIFx1RDU4OSBcdUJDODhcdUQ2MzggXHVDMEFDXHVDNkE5KV0ifSwKLSAgeyAib3B0aW9uU0VDVVJFUFJPQ0VTU0lORyIsICIgICBbLVNFQ1VSRShcdUJDRjRcdUM1NDggXHVDQzk4XHVCOUFDIFx1QUUzMFx1QjJBNVx1Qzc0NCB0cnVlXHVCODVDIFx1QzEyNFx1QzgxNSldIn0sCi0KLSAgICAvLyBGb2xsb3dpbmcgYXJlIHRoZSBuZXcgb3B0aW9ucyBhZGRlZCBpbiBYU0xURXJyb3JSZXNvdXJjZXMucHJvcGVydGllcyBmaWxlcyBhZnRlciBKZGsgMS40IChYYWxhbiAyLjItRDExKQotCi0KLSAgeyAgIm9wdGlvbk1FRElBIiwgICIgICBbLU1FRElBIG1lZGlhVHlwZShtZWRpYSBcdUMxOERcdUMxMzFcdUM3NDQgXHVDMEFDXHVDNkE5XHVENTU4XHVDNUVDIFx1QkIzOFx1QzExQ1x1QzY0MCBcdUM1RjBcdUFEMDBcdUI0MUMgXHVDMkE0XHVEMEMwXHVDNzdDXHVDMkRDXHVEMkI4IFx1Q0MzRVx1QUUzMCldIn0sCi0gIHsgICJvcHRpb25GTEFWT1IiLCAgIiAgIFstRkxBVk9SIGZsYXZvck5hbWUoXHVCQ0MwXHVENjU4XHVDNUQwIFx1QkE4NVx1QzJEQ1x1QzgwMVx1QzczQ1x1Qjg1QyBzMnM9U0FYIFx1QjYxMFx1QjI5NCBkMmQ9RE9NIFx1QzBBQ1x1QzZBOSldICJ9LCAvLyBBZGRlZCBieSBzYm9hZy9zY3VyY3VydTsgZXhwZXJpbWVudGFsCi0gIHsgIm9wdGlvbkRJQUciLCAiICAgWy1ESUFHKFx1QkNDMFx1RDY1OFx1QzVEMCBcdUFDNzhcdUI5QjAgXHVDRDFEIFx1QzJEQ1x1QUMwNChcdUJDMDBcdUI5QUNcdUNEMDgpIFx1Qzc3OFx1QzFDNCldIn0sCi0gIHsgIm9wdGlvbklOQ1JFTUVOVEFMIiwgICIgICBbLUlOQ1JFTUVOVEFMKGh0dHA6Ly94bWwuYXBhY2hlLm9yZy94YWxhbi9mZWF0dXJlcy9pbmNyZW1lbnRhbFx1Qzc0NCB0cnVlXHVCODVDIFx1QzEyNFx1QzgxNVx1RDU1OFx1QzVFQyBcdUM5OURcdUJEODRcdUM4MDEgRFRNIFx1QzBERFx1QzEzMSBcdUM2OTRcdUNDQUQpXSJ9LAotICB7ICAib3B0aW9uTk9PUFRJTUlNSVpFIiwgICIgICBbLU5PT1BUSU1JTUlaRShodHRwOi8veG1sLmFwYWNoZS5vcmcveGFsYW4vZmVhdHVyZXMvb3B0aW1pemVcdUI5N0MgZmFsc2VcdUI4NUMgXHVDMTI0XHVDODE1XHVENTU4XHVDNUVDIFx1QzJBNFx1RDBDMFx1Qzc3Q1x1QzJEQ1x1RDJCOCBcdUNENUNcdUM4MDFcdUQ2NTQgXHVDQzk4XHVCOUFDIFx1QzU0OFx1RDU2OCBcdUM2OTRcdUNDQUQpXSJ9LAotICB7ICJvcHRpb25STCIsICAiICAgWy1STCByZWN1cnNpb25saW1pdChcdUMyQTRcdUQwQzBcdUM3N0NcdUMyRENcdUQyQjggXHVDMjFDXHVENjU4IFx1QUU0QVx1Qzc3NFx1QzVEMCBcdUIzMDBcdUQ1NUMgXHVDMjJCXHVDNzkwIFx1QzgxQ1x1RDU1QyBcdUFDODBcdUM5OUQpXSJ9LAotICB7ICAgIm9wdGlvblhPIiwgICIgICBbLVhPIFt0cmFuc2xldE5hbWVdKFx1QzBERFx1QzEzMVx1QjQxQyB0cmFuc2xldFx1QzVEMCBcdUM3NzRcdUI5ODQgXHVDOUMwXHVDODE1KV0ifSwKLSAgeyAgIm9wdGlvblhEIiwgIiAgIFstWEQgZGVzdGluYXRpb25EaXJlY3RvcnkodHJhbnNsZXRcdUM1RDAgXHVCMzAwXHVENTVDIFx1QjMwMFx1QzBDMSBcdUI1MTRcdUI4MDlcdUQxQTBcdUI5QUMgXHVDOUMwXHVDODE1KV0ifSwKLSAgeyAgIm9wdGlvblhKIiwgICIgICBbLVhKIGphcmZpbGUodHJhbnNsZXQgXHVEMDc0XHVCNzk4XHVDMkE0XHVCOTdDIDxqYXJmaWxlPiBcdUM3NzRcdUI5ODRcdUM3NTggamFyIFx1RDMwQ1x1Qzc3Q1x1Qjg1QyBcdUQzMjhcdUQwQTRcdUM5QzBcdUQ2NTQpXSJ9LAotICB7ICAgIm9wdGlvblhQIiwgICIgICBbLVhQIHBhY2thZ2UoXHVDMEREXHVDMTMxXHVCNDFDIFx1QkFBOFx1QjRFMCB0cmFuc2xldCBcdUQwNzRcdUI3OThcdUMyQTRcdUM1RDAgXHVCMzAwXHVENTVDIFx1RDMyOFx1RDBBNFx1QzlDMCBcdUM3NzRcdUI5ODQgXHVDODExXHVCNDUwXHVDNUI0IFx1QzlDMFx1QzgxNSldIn0sCi0KLSAgLy9BZGRJVElPTkFMICBTVFJJTkdTIHRoYXQgbmVlZCBMMTBuCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgZGVzY3JpYmVzIHVzYWdlIG9mIGEgcGFydGljdWxhcgotICAvLyBjb21tYW5kLWxpbmUgb3B0aW9uIHRoYXQgaXMgdXNlZCB0byBlbmFibGUgdGhlICJ0ZW1wbGF0ZSBpbmxpbmluZyIKLSAgLy8gb3B0aW1pemF0aW9uLiAgVGhlIG9wdGltaXphdGlvbiBpbnZvbHZlcyBtYWtpbmcgYSBjb3B5IG9mIHRoZSBjb2RlCi0gIC8vIGdlbmVyYXRlZCBmb3IgYSB0ZW1wbGF0ZSBpbiBhbm90aGVyIHRlbXBsYXRlIHRoYXQgcmVmZXJzIHRvIGl0LgotICB7ICJvcHRpb25YTiIsICAiICAgWy1YTihcdUQxNUNcdUQ1MENcdUI5QUNcdUQyQjggXHVDNzc4XHVCNzdDXHVDNzc4XHVDNzQ0IFx1QzBBQ1x1QzZBOVx1QzczQ1x1Qjg1QyBcdUMxMjRcdUM4MTUpXSIgfSwKLSAgeyAib3B0aW9uWFgiLCAgIiAgIFstWFgoXHVDRDk0XHVBQzAwIFx1QjUxNFx1QkM4NFx1QUU0NSBcdUJBNTRcdUMyRENcdUM5QzAgXHVDRDlDXHVCODI1IFx1QzEyNFx1QzgxNSldIn0sCi0gIHsgIm9wdGlvblhUIiAsICIgICBbLVhUKFx1QUMwMFx1QjJBNVx1RDU1QyBcdUFDQkRcdUM2QjAgXHVCQ0MwXHVENjU4XHVDNUQwIHRyYW5zbGV0IFx1QzBBQ1x1QzZBOSldIn0sCi0gIHsgImRpYWdUaW1pbmciLCIgLS0tLS0tLS0tIHsxfVx1Qzc0NChcdUI5N0MpIFx1RDFCNVx1RDU1QyB7MH0gXHVCQ0MwXHVENjU4XHVDNUQwIHsyfVx1QkMwMFx1QjlBQ1x1Q0QwOFx1QUMwMCBcdUFDNzhcdUI4MzhcdUMyQjVcdUIyQzhcdUIyRTQuIiB9LAotICB7ICJyZWN1cnNpb25Ub29EZWVwIiwiXHVEMTVDXHVENTBDXHVCOUFDXHVEMkI4XHVBQzAwIFx1QjEwOFx1QkIzNCBcdUFFNEFcdUFDOEMgXHVDOTExXHVDQ0E5XHVCNDE4XHVDNUM4XHVDMkI1XHVCMkM4XHVCMkU0LiBcdUM5MTFcdUNDQTkgPSB7MH0sIFx1RDE1Q1x1RDUwQ1x1QjlBQ1x1RDJCODogezF9IHsyfSIgfSwKLSAgeyAibmFtZUlzIiwgIlx1Qzc3NFx1Qjk4NDoiIH0sCi0gIHsgIm1hdGNoUGF0dGVybklzIiwgIlx1Qzc3Q1x1Q0U1OCBcdUQzMjhcdUQxMzQ6IiB9Ci0KLSAgfTsKLQotICB9Ci0gIC8vID09PT09PT09PT09PT09PT09IElORlJBU1RSVUNUVVJFID09PT09PT09PT09PT09PT09PT09PT0KLQotICAvKiogU3RyaW5nIGZvciB1c2Ugd2hlbiBhIGJhZCBlcnJvciBjb2RlIHdhcyBlbmNvdW50ZXJlZC4gICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQkFEX0NPREUgPSAiQkFEX0NPREUiOwotCi0gIC8qKiBTdHJpbmcgZm9yIHVzZSB3aGVuIGZvcm1hdHRpbmcgb2YgdGhlIGVycm9yIHN0cmluZyBmYWlsZWQuICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRk9STUFUX0ZBSUxFRCA9ICJGT1JNQVRfRkFJTEVEIjsKLQotICAvKiogR2VuZXJhbCBlcnJvciBzdHJpbmcuICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJST1JfU1RSSU5HID0gIiNlcnJvciI7Ci0KLSAgLyoqIFN0cmluZyB0byBwcmVwZW5kIHRvIGVycm9yIG1lc3NhZ2VzLiAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJST1JfSEVBREVSID0gIkVycm9yOiAiOwotCi0gIC8qKiBTdHJpbmcgdG8gcHJlcGVuZCB0byB3YXJuaW5nIG1lc3NhZ2VzLiAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXQVJOSU5HX0hFQURFUiA9ICJXYXJuaW5nOiAiOwotCi0gIC8qKiBTdHJpbmcgdG8gc3BlY2lmeSB0aGUgWFNMVCBtb2R1bGUuICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBYU0xfSEVBREVSID0gIlhTTFQgIjsKLQotICAvKiogU3RyaW5nIHRvIHNwZWNpZnkgdGhlIFhNTCBwYXJzZXIgbW9kdWxlLiAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MX0hFQURFUiA9ICJYTUwgIjsKLQotICAvKiogSSBkb24ndCB0aGluayB0aGlzIGlzIHVzZWQgYW55IG1vcmUuCi0gICAqIEBkZXByZWNhdGVkICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBRVUVSWV9IRUFERVIgPSAiUEFUVEVSTiAiOwotCi0KLSAgICB9CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3Jlcy9YU0xURXJyb3JSZXNvdXJjZXNfcHRfQlIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwvcmVzL1hTTFRFcnJvclJlc291cmNlc19wdF9CUi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3ZWVkZWI4Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwvcmVzL1hTTFRFcnJvclJlc291cmNlc19wdF9CUi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTQ0NyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC5yZXM7Ci0KLWltcG9ydCBqYXZhLnV0aWwuTGlzdFJlc291cmNlQnVuZGxlOwotaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7Ci1pbXBvcnQgamF2YS51dGlsLk1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuUmVzb3VyY2VCdW5kbGU7Ci0KLS8qKgotICogU2V0IHVwIGVycm9yIG1lc3NhZ2VzLgotICogV2UgYnVpbGQgYSB0d28gZGltZW5zaW9uYWwgYXJyYXkgb2YgbWVzc2FnZSBrZXlzIGFuZAotICogbWVzc2FnZSBzdHJpbmdzLiBJbiBvcmRlciB0byBhZGQgYSBuZXcgbWVzc2FnZSBoZXJlLAotICogeW91IG5lZWQgdG8gZmlyc3QgYWRkIGEgU3RyaW5nIGNvbnN0YW50LiBBbmQKLSAqICB5b3UgbmVlZCB0byBlbnRlciBrZXkgLCB2YWx1ZSBwYWlyIGFzIHBhcnQgb2YgY29udGVudHMKLSAqIEFycmF5LiBZb3UgYWxzbyBuZWVkIHRvIHVwZGF0ZSBNQVhfQ09ERSBmb3IgZXJyb3Igc3RyaW5ncwotICogYW5kIE1BWF9XQVJOSU5HIGZvciB3YXJuaW5ncyAoIE5lZWRlZCBmb3Igb25seSBpbmZvcm1hdGlvbgotICogcHVycG9zZSApCi0gKi8KLXB1YmxpYyBjbGFzcyBYU0xURXJyb3JSZXNvdXJjZXNfcHRfQlIgZXh0ZW5kcyBMaXN0UmVzb3VyY2VCdW5kbGUKLXsKLQotLyoKLSAqIFRoaXMgZmlsZSBjb250YWlucyBlcnJvciBhbmQgd2FybmluZyBtZXNzYWdlcyByZWxhdGVkIHRvIFhhbGFuIEVycm9yCi0gKiBIYW5kbGluZy4KLSAqCi0gKiAgR2VuZXJhbCBub3RlcyB0byB0cmFuc2xhdG9yczoKLSAqCi0gKiAgMSkgWGFsYW4gKG9yIG1vcmUgcHJvcGVybHksIFhhbGFuLWludGVycHJldGl2ZSkgYW5kIFhTTFRDIGFyZSBuYW1lcyBvZgotICogICAgIGNvbXBvbmVudHMuCi0gKiAgICAgWFNMVCBpcyBhbiBhY3JvbnltIGZvciAiWE1MIFN0eWxlc2hlZXQgTGFuZ3VhZ2U6IFRyYW5zZm9ybWF0aW9ucyIuCi0gKiAgICAgWFNMVEMgaXMgYW4gYWNyb255bSBmb3IgWFNMVCBDb21waWxlci4KLSAqCi0gKiAgMikgQSBzdHlsZXNoZWV0IGlzIGEgZGVzY3JpcHRpb24gb2YgaG93IHRvIHRyYW5zZm9ybSBhbiBpbnB1dCBYTUwgZG9jdW1lbnQKLSAqICAgICBpbnRvIGEgcmVzdWx0YW50IFhNTCBkb2N1bWVudCAob3IgSFRNTCBkb2N1bWVudCBvciB0ZXh0KS4gIFRoZQotICogICAgIHN0eWxlc2hlZXQgaXRzZWxmIGlzIGRlc2NyaWJlZCBpbiB0aGUgZm9ybSBvZiBhbiBYTUwgZG9jdW1lbnQuCi0gKgotICogIDMpIEEgdGVtcGxhdGUgaXMgYSBjb21wb25lbnQgb2YgYSBzdHlsZXNoZWV0IHRoYXQgaXMgdXNlZCB0byBtYXRjaCBhCi0gKiAgICAgcGFydGljdWxhciBwb3J0aW9uIG9mIGFuIGlucHV0IGRvY3VtZW50IGFuZCBzcGVjaWZpZXMgdGhlIGZvcm0gb2YgdGhlCi0gKiAgICAgY29ycmVzcG9uZGluZyBwb3J0aW9uIG9mIHRoZSBvdXRwdXQgZG9jdW1lbnQuCi0gKgotICogIDQpIEFuIGVsZW1lbnQgaXMgYSBtYXJrLXVwIHRhZyBpbiBhbiBYTUwgZG9jdW1lbnQ7IGFuIGF0dHJpYnV0ZSBpcyBhCi0gKiAgICAgbW9kaWZpZXIgb24gdGhlIHRhZy4gIEZvciBleGFtcGxlLCBpbiA8ZWxlbSBhdHRyPSd2YWwnIGF0dHIyPSd2YWwyJz4KLSAqICAgICAiZWxlbSIgaXMgYW4gZWxlbWVudCBuYW1lLCAiYXR0ciIgYW5kICJhdHRyMiIgYXJlIGF0dHJpYnV0ZSBuYW1lcyB3aXRoCi0gKiAgICAgdGhlIHZhbHVlcyAidmFsIiBhbmQgInZhbDIiLCByZXNwZWN0aXZlbHkuCi0gKgotICogIDUpIEEgbmFtZXNwYWNlIGRlY2xhcmF0aW9uIGlzIGEgc3BlY2lhbCBhdHRyaWJ1dGUgdGhhdCBpcyB1c2VkIHRvIGFzc29jaWF0ZQotICogICAgIGEgcHJlZml4IHdpdGggYSBVUkkgKHRoZSBuYW1lc3BhY2UpLiAgVGhlIG1lYW5pbmdzIG9mIGVsZW1lbnQgbmFtZXMgYW5kCi0gKiAgICAgYXR0cmlidXRlIG5hbWVzIHRoYXQgdXNlIHRoYXQgcHJlZml4IGFyZSBkZWZpbmVkIHdpdGggcmVzcGVjdCB0byB0aGF0Ci0gKiAgICAgbmFtZXNwYWNlLgotICoKLSAqICA2KSAiVHJhbnNsZXQiIGlzIGFuIGludmVudGVkIHRlcm0gdGhhdCBkZXNjcmliZXMgdGhlIGNsYXNzIGZpbGUgdGhhdAotICogICAgIHJlc3VsdHMgZnJvbSBjb21waWxpbmcgYW4gWE1MIHN0eWxlc2hlZXQgaW50byBhIEphdmEgY2xhc3MuCi0gKgotICogIDcpIFhQYXRoIGlzIGEgc3BlY2lmaWNhdGlvbiB0aGF0IGRlc2NyaWJlcyBhIG5vdGF0aW9uIGZvciBpZGVudGlmeWluZwotICogICAgIG5vZGVzIGluIGEgdHJlZS1zdHJ1Y3R1cmVkIHJlcHJlc2VudGF0aW9uIG9mIGFuIFhNTCBkb2N1bWVudC4gIEFuCi0gKiAgICAgaW5zdGFuY2Ugb2YgdGhhdCBub3RhdGlvbiBpcyByZWZlcnJlZCB0byBhcyBhbiBYUGF0aCBleHByZXNzaW9uLgotICoKLSAqLwotCi0gIC8qCi0gICAqIFN0YXRpYyB2YXJpYWJsZXMKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfTkFNRVNQQUNFX1VSSV9WQUxVRV9GT1JfUkVTVUxUX1BSRUZJWCA9Ci0gICAgICAgICJFUl9JTlZBTElEX1NFVF9OQU1FU1BBQ0VfVVJJX1ZBTFVFX0ZPUl9SRVNVTFRfUFJFRklYIjsKLQotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX05BTUVTUEFDRV9VUklfVkFMVUVfRk9SX1JFU1VMVF9QUkVGSVhfRk9SX0RFRkFVTFQgPQotICAgICAgICAiRVJfSU5WQUxJRF9OQU1FU1BBQ0VfVVJJX1ZBTFVFX0ZPUl9SRVNVTFRfUFJFRklYX0ZPUl9ERUZBVUxUIjsKLQotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19DVVJMWUJSQUNFID0gIkVSX05PX0NVUkxZQlJBQ0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEID0gIkVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTExFR0FMX0FUVFJJQlVURSA9ICJFUl9JTExFR0FMX0FUVFJJQlVURSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05VTExfU09VUkNFTk9ERV9BUFBMWUlNUE9SVFMgPSAiRVJfTlVMTF9TT1VSQ0VOT0RFX0FQUExZSU1QT1JUUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9BREQgPSAiRVJfQ0FOTk9UX0FERCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05VTExfU09VUkNFTk9ERV9IQU5ETEVBUFBMWVRFTVBMQVRFUz0iRVJfTlVMTF9TT1VSQ0VOT0RFX0hBTkRMRUFQUExZVEVNUExBVEVTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fTkFNRV9BVFRSSUIgPSAiRVJfTk9fTkFNRV9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9URU1QTEFURV9OT1RfRk9VTkQgPSAiRVJfVEVNUExBVEVfTk9UX0ZPVU5EIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9SRVNPTFZFX05BTUVfQVZUID0gIkVSX0NBTlRfUkVTT0xWRV9OQU1FX0FWVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1JFUVVJUkVTX0FUVFJJQiA9ICJFUl9SRVFVSVJFU19BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9NVVNUX0hBVkVfVEVTVF9BVFRSSUIgPSAiRVJfTVVTVF9IQVZFX1RFU1RfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQkFEX1ZBTF9PTl9MRVZFTF9BVFRSSUIgPQotICAgICAgICAgIkVSX0JBRF9WQUxfT05fTEVWRUxfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJPQ0VTU0lOR0lOU1RSVUNUSU9OX05BTUVfQ0FOVF9CRV9YTUwgPQotICAgICAgICAgIkVSX1BST0NFU1NJTkdJTlNUUlVDVElPTl9OQU1FX0NBTlRfQkVfWE1MIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJPQ0VTU0lOR0lOU1RSVUNUSU9OX05PVFZBTElEX05DTkFNRSA9Ci0gICAgICAgICAiRVJfUFJPQ0VTU0lOR0lOU1RSVUNUSU9OX05PVFZBTElEX05DTkFNRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05FRURfTUFUQ0hfQVRUUklCID0gIkVSX05FRURfTUFUQ0hfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTkVFRF9OQU1FX09SX01BVENIX0FUVFJJQiA9Ci0gICAgICAgICAiRVJfTkVFRF9OQU1FX09SX01BVENIX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfUkVTT0xWRV9OU1BSRUZJWCA9Ci0gICAgICAgICAiRVJfQ0FOVF9SRVNPTFZFX05TUFJFRklYIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSUxMRUdBTF9WQUxVRSA9ICJFUl9JTExFR0FMX1ZBTFVFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fT1dORVJET0MgPSAiRVJfTk9fT1dORVJET0MiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FTEVNVEVNUExBVEVFTEVNX0VSUiA9IkVSX0VMRU1URU1QTEFURUVMRU1fRVJSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTlVMTF9DSElMRCA9ICJFUl9OVUxMX0NISUxEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTkVFRF9TRUxFQ1RfQVRUUklCID0gIkVSX05FRURfU0VMRUNUX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05FRURfVEVTVF9BVFRSSUIgPSAiRVJfTkVFRF9URVNUX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05FRURfTkFNRV9BVFRSSUIgPSAiRVJfTkVFRF9OQU1FX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX0NPTlRFWFRfT1dORVJET0MgPSAiRVJfTk9fQ09OVEVYVF9PV05FUkRPQyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxEX05PVF9DUkVBVEVfWE1MX1BST0NfTElBSVNPTiA9Ci0gICAgICAgICAiRVJfQ09VTERfTk9UX0NSRUFURV9YTUxfUFJPQ19MSUFJU09OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJPQ0VTU19OT1RfU1VDQ0VTU0ZVTCA9Ci0gICAgICAgICAiRVJfUFJPQ0VTU19OT1RfU1VDQ0VTU0ZVTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PVF9TVUNDRVNTRlVMID0gIkVSX05PVF9TVUNDRVNTRlVMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRU5DT0RJTkdfTk9UX1NVUFBPUlRFRCA9Ci0gICAgICAgICAiRVJfRU5DT0RJTkdfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxEX05PVF9DUkVBVEVfVFJBQ0VMSVNURU5FUiA9Ci0gICAgICAgICAiRVJfQ09VTERfTk9UX0NSRUFURV9UUkFDRUxJU1RFTkVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfS0VZX1JFUVVJUkVTX05BTUVfQVRUUklCID0KLSAgICAgICAgICJFUl9LRVlfUkVRVUlSRVNfTkFNRV9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9LRVlfUkVRVUlSRVNfTUFUQ0hfQVRUUklCID0KLSAgICAgICAgICJFUl9LRVlfUkVRVUlSRVNfTUFUQ0hfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfS0VZX1JFUVVJUkVTX1VTRV9BVFRSSUIgPQotICAgICAgICAgIkVSX0tFWV9SRVFVSVJFU19VU0VfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUkVRVUlSRVNfRUxFTUVOVFNfQVRUUklCID0KLSAgICAgICAgICJFUl9SRVFVSVJFU19FTEVNRU5UU19BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9NSVNTSU5HX1BSRUZJWF9BVFRSSUIgPQotICAgICAgICAgIkVSX01JU1NJTkdfUFJFRklYX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0JBRF9TVFlMRVNIRUVUX1VSTCA9ICJFUl9CQURfU1RZTEVTSEVFVF9VUkwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GSUxFX05PVF9GT1VORCA9ICJFUl9GSUxFX05PVF9GT1VORCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lPRVhDRVBUSU9OID0gIkVSX0lPRVhDRVBUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fSFJFRl9BVFRSSUIgPSAiRVJfTk9fSFJFRl9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TVFlMRVNIRUVUX0lOQ0xVREVTX0lUU0VMRiA9Ci0gICAgICAgICAiRVJfU1RZTEVTSEVFVF9JTkNMVURFU19JVFNFTEYiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUk9DRVNTSU5DTFVERV9FUlJPUiA9IkVSX1BST0NFU1NJTkNMVURFX0VSUk9SIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTUlTU0lOR19MQU5HX0FUVFJJQiA9ICJFUl9NSVNTSU5HX0xBTkdfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTUlTU0lOR19DT05UQUlORVJfRUxFTUVOVF9DT01QT05FTlQgPQotICAgICAgICAgIkVSX01JU1NJTkdfQ09OVEFJTkVSX0VMRU1FTlRfQ09NUE9ORU5UIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOX09OTFlfT1VUUFVUX1RPX0VMRU1FTlQgPQotICAgICAgICAgIkVSX0NBTl9PTkxZX09VVFBVVF9UT19FTEVNRU5UIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJPQ0VTU19FUlJPUiA9ICJFUl9QUk9DRVNTX0VSUk9SIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5JTVBMTk9ERV9FUlJPUiA9ICJFUl9VTklNUExOT0RFX0VSUk9SIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fU0VMRUNUX0VYUFJFU1NJT04gPSJFUl9OT19TRUxFQ1RfRVhQUkVTU0lPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9TRVJJQUxJWkVfWFNMUFJPQ0VTU09SID0KLSAgICAgICAgICJFUl9DQU5OT1RfU0VSSUFMSVpFX1hTTFBST0NFU1NPUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX0lOUFVUX1NUWUxFU0hFRVQgPSAiRVJfTk9fSU5QVVRfU1RZTEVTSEVFVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZBSUxFRF9QUk9DRVNTX1NUWUxFU0hFRVQgPQotICAgICAgICAgIkVSX0ZBSUxFRF9QUk9DRVNTX1NUWUxFU0hFRVQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRE5UX1BBUlNFX0RPQyA9ICJFUl9DT1VMRE5UX1BBUlNFX0RPQyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxETlRfRklORF9GUkFHTUVOVCA9Ci0gICAgICAgICAiRVJfQ09VTEROVF9GSU5EX0ZSQUdNRU5UIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9ERV9OT1RfRUxFTUVOVCA9ICJFUl9OT0RFX05PVF9FTEVNRU5UIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRk9SRUFDSF9ORUVEX01BVENIX09SX05BTUVfQVRUUklCID0KLSAgICAgICAgICJFUl9GT1JFQUNIX05FRURfTUFUQ0hfT1JfTkFNRV9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9URU1QTEFURVNfTkVFRF9NQVRDSF9PUl9OQU1FX0FUVFJJQiA9Ci0gICAgICAgICAiRVJfVEVNUExBVEVTX05FRURfTUFUQ0hfT1JfTkFNRV9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19DTE9ORV9PRl9ET0NVTUVOVF9GUkFHID0KLSAgICAgICAgICJFUl9OT19DTE9ORV9PRl9ET0NVTUVOVF9GUkFHIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9DUkVBVEVfSVRFTSA9ICJFUl9DQU5UX0NSRUFURV9JVEVNIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWE1MU1BBQ0VfSUxMRUdBTF9WQUxVRSA9Ci0gICAgICAgICAiRVJfWE1MU1BBQ0VfSUxMRUdBTF9WQUxVRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1hTTEtFWV9ERUNMQVJBVElPTiA9Ci0gICAgICAgICAiRVJfTk9fWFNMS0VZX0RFQ0xBUkFUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9DUkVBVEVfVVJMID0gIkVSX0NBTlRfQ1JFQVRFX1VSTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hTTEZVTkNUSU9OU19VTlNVUFBPUlRFRCA9Ci0gICAgICAgICAiRVJfWFNMRlVOQ1RJT05TX1VOU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJPQ0VTU09SX0VSUk9SID0gIkVSX1BST0NFU1NPUl9FUlJPUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PVF9BTExPV0VEX0lOU0lERV9TVFlMRVNIRUVUID0KLSAgICAgICAgICJFUl9OT1RfQUxMT1dFRF9JTlNJREVfU1RZTEVTSEVFVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1JFU1VMVE5TX05PVF9TVVBQT1JURUQgPQotICAgICAgICAgIkVSX1JFU1VMVE5TX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9ERUZBVUxUU1BBQ0VfTk9UX1NVUFBPUlRFRCA9Ci0gICAgICAgICAiRVJfREVGQVVMVFNQQUNFX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTkRFTlRSRVNVTFRfTk9UX1NVUFBPUlRFRCA9Ci0gICAgICAgICAiRVJfSU5ERU5UUkVTVUxUX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTExFR0FMX0FUVFJJQiA9ICJFUl9JTExFR0FMX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1VOS05PV05fWFNMX0VMRU0gPSAiRVJfVU5LTk9XTl9YU0xfRUxFTSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0JBRF9YU0xTT1JUX1VTRSA9ICJFUl9CQURfWFNMU09SVF9VU0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9NSVNQTEFDRURfWFNMV0hFTiA9ICJFUl9NSVNQTEFDRURfWFNMV0hFTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hTTFdIRU5fTk9UX1BBUkVOVEVEX0JZX1hTTENIT09TRSA9Ci0gICAgICAgICAiRVJfWFNMV0hFTl9OT1RfUEFSRU5URURfQllfWFNMQ0hPT1NFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTUlTUExBQ0VEX1hTTE9USEVSV0lTRSA9Ci0gICAgICAgICAiRVJfTUlTUExBQ0VEX1hTTE9USEVSV0lTRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hTTE9USEVSV0lTRV9OT1RfUEFSRU5URURfQllfWFNMQ0hPT1NFID0KLSAgICAgICAgICJFUl9YU0xPVEhFUldJU0VfTk9UX1BBUkVOVEVEX0JZX1hTTENIT09TRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PVF9BTExPV0VEX0lOU0lERV9URU1QTEFURSA9Ci0gICAgICAgICAiRVJfTk9UX0FMTE9XRURfSU5TSURFX1RFTVBMQVRFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5LTk9XTl9FWFRfTlNfUFJFRklYID0KLSAgICAgICAgICJFUl9VTktOT1dOX0VYVF9OU19QUkVGSVgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTVBPUlRTX0FTX0ZJUlNUX0VMRU0gPQotICAgICAgICAgIkVSX0lNUE9SVFNfQVNfRklSU1RfRUxFTSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lNUE9SVElOR19JVFNFTEYgPSAiRVJfSU1QT1JUSU5HX0lUU0VMRiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hNTFNQQUNFX0lMTEVHQUxfVkFMID0iRVJfWE1MU1BBQ0VfSUxMRUdBTF9WQUwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUk9DRVNTU1RZTEVTSEVFVF9OT1RfU1VDQ0VTU0ZVTCA9Ci0gICAgICAgICAiRVJfUFJPQ0VTU1NUWUxFU0hFRVRfTk9UX1NVQ0NFU1NGVUwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TQVhfRVhDRVBUSU9OID0gIkVSX1NBWF9FWENFUFRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YU0xUX0VSUk9SID0gIkVSX1hTTFRfRVJST1IiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DVVJSRU5DWV9TSUdOX0lMTEVHQUw9Ci0gICAgICAgICAiRVJfQ1VSUkVOQ1lfU0lHTl9JTExFR0FMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRE9DVU1FTlRfRlVOQ1RJT05fSU5WQUxJRF9JTl9TVFlMRVNIRUVUX0RPTSA9Ci0gICAgICAgICAiRVJfRE9DVU1FTlRfRlVOQ1RJT05fSU5WQUxJRF9JTl9TVFlMRVNIRUVUX0RPTSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfUkVTT0xWRV9QUkVGSVhfT0ZfTk9OX1BSRUZJWF9SRVNPTFZFUiA9Ci0gICAgICAgICAiRVJfQ0FOVF9SRVNPTFZFX1BSRUZJWF9PRl9OT05fUFJFRklYX1JFU09MVkVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUkVESVJFQ1RfQ09VTEROVF9HRVRfRklMRU5BTUUgPQotICAgICAgICAgIkVSX1JFRElSRUNUX0NPVUxETlRfR0VUX0ZJTEVOQU1FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX0JVSUxEX0ZPUk1BVFRFUkxJU1RFTkVSX0lOX1JFRElSRUNUID0KLSAgICAgICAgICJFUl9DQU5OT1RfQlVJTERfRk9STUFUVEVSTElTVEVORVJfSU5fUkVESVJFQ1QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX1BSRUZJWF9JTl9FWENMVURFUkVTVUxUUFJFRklYID0KLSAgICAgICAgICJFUl9JTlZBTElEX1BSRUZJWF9JTl9FWENMVURFUkVTVUxUUFJFRklYIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTUlTU0lOR19OU19VUkkgPSAiRVJfTUlTU0lOR19OU19VUkkiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9NSVNTSU5HX0FSR19GT1JfT1BUSU9OID0KLSAgICAgICAgICJFUl9NSVNTSU5HX0FSR19GT1JfT1BUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9PUFRJT04gPSAiRVJfSU5WQUxJRF9PUFRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9NQUxGT1JNRURfRk9STUFUX1NUUklORyA9Ci0gICAgICAgICAiRVJfTUFMRk9STUVEX0ZPUk1BVF9TVFJJTkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TVFlMRVNIRUVUX1JFUVVJUkVTX1ZFUlNJT05fQVRUUklCID0KLSAgICAgICAgICJFUl9TVFlMRVNIRUVUX1JFUVVJUkVTX1ZFUlNJT05fQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSUxMRUdBTF9BVFRSSUJVVEVfVkFMVUUgPQotICAgICAgICAgIkVSX0lMTEVHQUxfQVRUUklCVVRFX1ZBTFVFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0hPT1NFX1JFUVVJUkVTX1dIRU4gPSJFUl9DSE9PU0VfUkVRVUlSRVNfV0hFTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX0FQUExZX0lNUE9SVF9JTl9GT1JfRUFDSCA9Ci0gICAgICAgICAiRVJfTk9fQVBQTFlfSU1QT1JUX0lOX0ZPUl9FQUNIIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9VU0VfRFRNX0ZPUl9PVVRQVVQgPQotICAgICAgICAgIkVSX0NBTlRfVVNFX0RUTV9GT1JfT1VUUFVUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9VU0VfRFRNX0ZPUl9JTlBVVCA9Ci0gICAgICAgICAiRVJfQ0FOVF9VU0VfRFRNX0ZPUl9JTlBVVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTExfVE9fRVhUX0ZBSUxFRCA9ICJFUl9DQUxMX1RPX0VYVF9GQUlMRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUkVGSVhfTVVTVF9SRVNPTFZFID0gIkVSX1BSRUZJWF9NVVNUX1JFU09MVkUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX1VURjE2X1NVUlJPR0FURSA9Ci0gICAgICAgICAiRVJfSU5WQUxJRF9VVEYxNl9TVVJST0dBVEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YU0xBVFRSU0VUX1VTRURfSVRTRUxGID0KLSAgICAgICAgICJFUl9YU0xBVFRSU0VUX1VTRURfSVRTRUxGIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX01JWF9YRVJDRVNET00gPSJFUl9DQU5OT1RfTUlYX1hFUkNFU0RPTSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1RPT19NQU5ZX0xJU1RFTkVSUyA9ICJFUl9UT09fTUFOWV9MSVNURU5FUlMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTl9FTEVNVEVNUExBVEVFTEVNX1JFQURPQkpFQ1QgPQotICAgICAgICAgIkVSX0lOX0VMRU1URU1QTEFURUVMRU1fUkVBRE9CSkVDVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0RVUExJQ0FURV9OQU1FRF9URU1QTEFURSA9Ci0gICAgICAgICAiRVJfRFVQTElDQVRFX05BTUVEX1RFTVBMQVRFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9LRVlfQ0FMTCA9ICJFUl9JTlZBTElEX0tFWV9DQUxMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUkVGRVJFTkNJTkdfSVRTRUxGID0gIkVSX1JFRkVSRU5DSU5HX0lUU0VMRiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lMTEVHQUxfRE9NU09VUkNFX0lOUFVUID0KLSAgICAgICAgICJFUl9JTExFR0FMX0RPTVNPVVJDRV9JTlBVVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NMQVNTX05PVF9GT1VORF9GT1JfT1BUSU9OID0KLSAgICAgICAgICJFUl9DTEFTU19OT1RfRk9VTkRfRk9SX09QVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1JFUVVJUkVEX0VMRU1fTk9UX0ZPVU5EID0KLSAgICAgICAgICJFUl9SRVFVSVJFRF9FTEVNX05PVF9GT1VORCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOUFVUX0NBTk5PVF9CRV9OVUxMID0iRVJfSU5QVVRfQ0FOTk9UX0JFX05VTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VUklfQ0FOTk9UX0JFX05VTEwgPSAiRVJfVVJJX0NBTk5PVF9CRV9OVUxMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRklMRV9DQU5OT1RfQkVfTlVMTCA9ICJFUl9GSUxFX0NBTk5PVF9CRV9OVUxMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU09VUkNFX0NBTk5PVF9CRV9OVUxMID0KLSAgICAgICAgICJFUl9TT1VSQ0VfQ0FOTk9UX0JFX05VTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfSU5JVF9CU0ZNR1IgPSAiRVJfQ0FOTk9UX0lOSVRfQlNGTUdSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX0NNUExfRVhURU5TTiA9ICJFUl9DQU5OT1RfQ01QTF9FWFRFTlNOIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX0NSRUFURV9FWFRFTlNOID0KLSAgICAgICAgICJFUl9DQU5OT1RfQ1JFQVRFX0VYVEVOU04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlNUQU5DRV9NVEhEX0NBTExfUkVRVUlSRVMgPQotICAgICAgICAgIkVSX0lOU1RBTkNFX01USERfQ0FMTF9SRVFVSVJFUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfRUxFTUVOVF9OQU1FID0iRVJfSU5WQUxJRF9FTEVNRU5UX05BTUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FTEVNRU5UX05BTUVfTUVUSE9EX1NUQVRJQyA9Ci0gICAgICAgICAiRVJfRUxFTUVOVF9OQU1FX01FVEhPRF9TVEFUSUMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FWFRFTlNJT05fRlVOQ19VTktOT1dOID0KLSAgICAgICAgICJFUl9FWFRFTlNJT05fRlVOQ19VTktOT1dOIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTU9SRV9NQVRDSF9DT05TVFJVQ1RPUiA9Ci0gICAgICAgICAiRVJfTU9SRV9NQVRDSF9DT05TVFJVQ1RPUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01PUkVfTUFUQ0hfTUVUSE9EID0gIkVSX01PUkVfTUFUQ0hfTUVUSE9EIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTU9SRV9NQVRDSF9FTEVNRU5UID0gIkVSX01PUkVfTUFUQ0hfRUxFTUVOVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfQ09OVEVYVF9QQVNTRUQgPQotICAgICAgICAgIkVSX0lOVkFMSURfQ09OVEVYVF9QQVNTRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QT09MX0VYSVNUUyA9ICJFUl9QT09MX0VYSVNUUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX0RSSVZFUl9OQU1FID0gIkVSX05PX0RSSVZFUl9OQU1FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fVVJMID0gIkVSX05PX1VSTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BPT0xfU0laRV9MRVNTVEhBTl9PTkUgPQotICAgICAgICAgIkVSX1BPT0xfU0laRV9MRVNTVEhBTl9PTkUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX0RSSVZFUiA9ICJFUl9JTlZBTElEX0RSSVZFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1NUWUxFU0hFRVRST09UID0gIkVSX05PX1NUWUxFU0hFRVRST09UIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSUxMRUdBTF9YTUxTUEFDRV9WQUxVRSA9Ci0gICAgICAgICAiRVJfSUxMRUdBTF9YTUxTUEFDRV9WQUxVRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BST0NFU1NGUk9NTk9ERV9GQUlMRUQgPQotICAgICAgICAgIkVSX1BST0NFU1NGUk9NTk9ERV9GQUlMRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SRVNPVVJDRV9DT1VMRF9OT1RfTE9BRCA9Ci0gICAgICAgICAiRVJfUkVTT1VSQ0VfQ09VTERfTk9UX0xPQUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9CVUZGRVJfU0laRV9MRVNTVEhBTl9aRVJPID0KLSAgICAgICAgICJFUl9CVUZGRVJfU0laRV9MRVNTVEhBTl9aRVJPIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5LTk9XTl9FUlJPUl9DQUxMSU5HX0VYVEVOU0lPTiA9Ci0gICAgICAgICAiRVJfVU5LTk9XTl9FUlJPUl9DQUxMSU5HX0VYVEVOU0lPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX05BTUVTUEFDRV9ERUNMID0gIkVSX05PX05BTUVTUEFDRV9ERUNMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRUxFTV9DT05URU5UX05PVF9BTExPV0VEID0KLSAgICAgICAgICJFUl9FTEVNX0NPTlRFTlRfTk9UX0FMTE9XRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TVFlMRVNIRUVUX0RJUkVDVEVEX1RFUk1JTkFUSU9OID0KLSAgICAgICAgICJFUl9TVFlMRVNIRUVUX0RJUkVDVEVEX1RFUk1JTkFUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfT05FX09SX1RXTyA9ICJFUl9PTkVfT1JfVFdPIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVFdPX09SX1RIUkVFID0gIkVSX1RXT19PUl9USFJFRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxEX05PVF9MT0FEX1JFU09VUkNFID0KLSAgICAgICAgICJFUl9DT1VMRF9OT1RfTE9BRF9SRVNPVVJDRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9JTklUX0RFRkFVTFRfVEVNUExBVEVTID0KLSAgICAgICAgICJFUl9DQU5OT1RfSU5JVF9ERUZBVUxUX1RFTVBMQVRFUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1JFU1VMVF9OVUxMID0gIkVSX1JFU1VMVF9OVUxMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUkVTVUxUX0NPVUxEX05PVF9CRV9TRVQgPQotICAgICAgICAgIkVSX1JFU1VMVF9DT1VMRF9OT1RfQkVfU0VUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fT1VUUFVUX1NQRUNJRklFRCA9ICJFUl9OT19PVVRQVVRfU1BFQ0lGSUVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX1RSQU5TRk9STV9UT19SRVNVTFRfVFlQRSA9Ci0gICAgICAgICAiRVJfQ0FOTk9UX1RSQU5TRk9STV9UT19SRVNVTFRfVFlQRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9UUkFOU0ZPUk1fU09VUkNFX1RZUEUgPQotICAgICAgICAgIkVSX0NBTk5PVF9UUkFOU0ZPUk1fU09VUkNFX1RZUEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OVUxMX0NPTlRFTlRfSEFORExFUiA9IkVSX05VTExfQ09OVEVOVF9IQU5ETEVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTlVMTF9FUlJPUl9IQU5ETEVSID0gIkVSX05VTExfRVJST1JfSEFORExFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9DQUxMX1BBUlNFID0gIkVSX0NBTk5PVF9DQUxMX1BBUlNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fUEFSRU5UX0ZPUl9GSUxURVIgPSJFUl9OT19QQVJFTlRfRk9SX0ZJTFRFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1NUWUxFU0hFRVRfSU5fTUVESUEgPQotICAgICAgICAgIkVSX05PX1NUWUxFU0hFRVRfSU5fTUVESUEiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19TVFlMRVNIRUVUX1BJID0gIkVSX05PX1NUWUxFU0hFRVRfUEkiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT1RfU1VQUE9SVEVEID0gIkVSX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUk9QRVJUWV9WQUxVRV9CT09MRUFOID0KLSAgICAgICAgICJFUl9QUk9QRVJUWV9WQUxVRV9CT09MRUFOIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTERfTk9UX0ZJTkRfRVhURVJOX1NDUklQVCA9Ci0gICAgICAgICAiRVJfQ09VTERfTk9UX0ZJTkRfRVhURVJOX1NDUklQVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1JFU09VUkNFX0NPVUxEX05PVF9GSU5EID0KLSAgICAgICAgICJFUl9SRVNPVVJDRV9DT1VMRF9OT1RfRklORCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX09VVFBVVF9QUk9QRVJUWV9OT1RfUkVDT0dOSVpFRCA9Ci0gICAgICAgICAiRVJfT1VUUFVUX1BST1BFUlRZX05PVF9SRUNPR05JWkVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRkFJTEVEX0NSRUFUSU5HX0VMRU1MSVRSU0xUID0KLSAgICAgICAgICJFUl9GQUlMRURfQ1JFQVRJTkdfRUxFTUxJVFJTTFQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9WQUxVRV9TSE9VTERfQkVfTlVNQkVSID0KLSAgICAgICAgICJFUl9WQUxVRV9TSE9VTERfQkVfTlVNQkVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVkFMVUVfU0hPVUxEX0VRVUFMID0gIkVSX1ZBTFVFX1NIT1VMRF9FUVVBTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZBSUxFRF9DQUxMSU5HX01FVEhPRCA9Ci0gICAgICAgICAiRVJfRkFJTEVEX0NBTExJTkdfTUVUSE9EIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRkFJTEVEX0NSRUFUSU5HX0VMRU1UTVBMID0KLSAgICAgICAgICJFUl9GQUlMRURfQ1JFQVRJTkdfRUxFTVRNUEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DSEFSU19OT1RfQUxMT1dFRCA9ICJFUl9DSEFSU19OT1RfQUxMT1dFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FUVFJfTk9UX0FMTE9XRUQgPSAiRVJfQVRUUl9OT1RfQUxMT1dFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0JBRF9WQUxVRSA9ICJFUl9CQURfVkFMVUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9BVFRSSUJfVkFMVUVfTk9UX0ZPVU5EID0KLSAgICAgICAgICJFUl9BVFRSSUJfVkFMVUVfTk9UX0ZPVU5EIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQVRUUklCX1ZBTFVFX05PVF9SRUNPR05JWkVEID0KLSAgICAgICAgICJFUl9BVFRSSUJfVkFMVUVfTk9UX1JFQ09HTklaRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OVUxMX1VSSV9OQU1FU1BBQ0UgPSAiRVJfTlVMTF9VUklfTkFNRVNQQUNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTlVNQkVSX1RPT19CSUcgPSAiRVJfTlVNQkVSX1RPT19CSUciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyAgRVJfQ0FOTk9UX0ZJTkRfU0FYMV9EUklWRVIgPQotICAgICAgICAgIkVSX0NBTk5PVF9GSU5EX1NBWDFfRFJJVkVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgIEVSX1NBWDFfRFJJVkVSX05PVF9MT0FERUQgPQotICAgICAgICAgIkVSX1NBWDFfRFJJVkVSX05PVF9MT0FERUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyAgRVJfU0FYMV9EUklWRVJfTk9UX0lOU1RBTlRJQVRFRCA9Ci0gICAgICAgICAiRVJfU0FYMV9EUklWRVJfTk9UX0lOU1RBTlRJQVRFRCIgOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TQVgxX0RSSVZFUl9OT1RfSU1QTEVNRU5UX1BBUlNFUiA9Ci0gICAgICAgICAiRVJfU0FYMV9EUklWRVJfTk9UX0lNUExFTUVOVF9QQVJTRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyAgRVJfUEFSU0VSX1BST1BFUlRZX05PVF9TUEVDSUZJRUQgPQotICAgICAgICAgIkVSX1BBUlNFUl9QUk9QRVJUWV9OT1RfU1BFQ0lGSUVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgIEVSX1BBUlNFUl9BUkdfQ0FOTk9UX0JFX05VTEwgPQotICAgICAgICAgIkVSX1BBUlNFUl9BUkdfQ0FOTk9UX0JFX05VTEwiIDsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgIEVSX0ZFQVRVUkUgPSAiRVJfRkVBVFVSRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BST1BFUlRZID0gIkVSX1BST1BFUlRZIiA7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05VTExfRU5USVRZX1JFU09MVkVSID0iRVJfTlVMTF9FTlRJVFlfUkVTT0xWRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyAgRVJfTlVMTF9EVERfSEFORExFUiA9ICJFUl9OVUxMX0RURF9IQU5ETEVSIiA7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX0RSSVZFUl9OQU1FX1NQRUNJRklFRCA9Ci0gICAgICAgICAiRVJfTk9fRFJJVkVSX05BTUVfU1BFQ0lGSUVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fVVJMX1NQRUNJRklFRCA9ICJFUl9OT19VUkxfU1BFQ0lGSUVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUE9PTFNJWkVfTEVTU19USEFOX09ORSA9Ci0gICAgICAgICAiRVJfUE9PTFNJWkVfTEVTU19USEFOX09ORSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfRFJJVkVSX05BTUUgPSAiRVJfSU5WQUxJRF9EUklWRVJfTkFNRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VSUk9STElTVEVORVIgPSAiRVJfRVJST1JMSVNURU5FUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FTU0VSVF9OT19URU1QTEFURV9QQVJFTlQgPQotICAgICAgICAgIkVSX0FTU0VSVF9OT19URU1QTEFURV9QQVJFTlQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9BU1NFUlRfUkVEVU5ERU5UX0VYUFJfRUxJTUlOQVRPUiA9Ci0gICAgICAgICAiRVJfQVNTRVJUX1JFRFVOREVOVF9FWFBSX0VMSU1JTkFUT1IiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT1RfQUxMT1dFRF9JTl9QT1NJVElPTiA9Ci0gICAgICAgICAiRVJfTk9UX0FMTE9XRURfSU5fUE9TSVRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT05XSElURVNQQUNFX05PVF9BTExPV0VEX0lOX1BPU0lUSU9OID0KLSAgICAgICAgICJFUl9OT05XSElURVNQQUNFX05PVF9BTExPV0VEX0lOX1BPU0lUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTkFNRVNQQUNFX0NPTlRFWFRfTlVMTF9OQU1FU1BBQ0UgPQotICAgICAgICAgIkVSX05BTUVTUEFDRV9DT05URVhUX05VTExfTkFNRVNQQUNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTkFNRVNQQUNFX0NPTlRFWFRfTlVMTF9QUkVGSVggPQotICAgICAgICAgIkVSX05BTUVTUEFDRV9DT05URVhUX05VTExfUFJFRklYIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWFBBVEhfUkVTT0xWRVJfTlVMTF9RTkFNRSA9Ci0gICAgICAgICAiRVJfWFBBVEhfUkVTT0xWRVJfTlVMTF9RTkFNRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hQQVRIX1JFU09MVkVSX05FR0FUSVZFX0FSSVRZID0KLSAgICAgICAgICJFUl9YUEFUSF9SRVNPTFZFUl9ORUdBVElWRV9BUklUWSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIElOVkFMSURfVENIQVIgPSAiSU5WQUxJRF9UQ0hBUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIElOVkFMSURfUU5BTUUgPSAiSU5WQUxJRF9RTkFNRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIElOVkFMSURfRU5VTSA9ICJJTlZBTElEX0VOVU0iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBJTlZBTElEX05NVE9LRU4gPSAiSU5WQUxJRF9OTVRPS0VOIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSU5WQUxJRF9OQ05BTUUgPSAiSU5WQUxJRF9OQ05BTUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBJTlZBTElEX0JPT0xFQU4gPSAiSU5WQUxJRF9CT09MRUFOIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSU5WQUxJRF9OVU1CRVIgPSAiSU5WQUxJRF9OVU1CRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9BUkdfTElURVJBTCA9ICJFUl9BUkdfTElURVJBTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0RVUExJQ0FURV9HTE9CQUxfVkFSID0iRVJfRFVQTElDQVRFX0dMT0JBTF9WQVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9EVVBMSUNBVEVfVkFSID0gIkVSX0RVUExJQ0FURV9WQVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9URU1QTEFURV9OQU1FX01BVENIID0gIkVSX1RFTVBMQVRFX05BTUVfTUFUQ0giOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX1BSRUZJWCA9ICJFUl9JTlZBTElEX1BSRUZJWCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX0FUVFJJQl9TRVQgPSAiRVJfTk9fQVRUUklCX1NFVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZVTkNUSU9OX05PVF9GT1VORCA9Ci0gICAgICAgICAiRVJfRlVOQ1RJT05fTk9UX0ZPVU5EIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9IQVZFX0NPTlRFTlRfQU5EX1NFTEVDVCA9Ci0gICAgICJFUl9DQU5UX0hBVkVfQ09OVEVOVF9BTkRfU0VMRUNUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9TRVRfUEFSQU1fVkFMVUUgPSAiRVJfSU5WQUxJRF9TRVRfUEFSQU1fVkFMVUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TRVRfRkVBVFVSRV9OVUxMX05BTUUgPQotICAgICAgICAiRVJfU0VUX0ZFQVRVUkVfTlVMTF9OQU1FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfR0VUX0ZFQVRVUkVfTlVMTF9OQU1FID0KLSAgICAgICAgIkVSX0dFVF9GRUFUVVJFX05VTExfTkFNRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1VOU1VQUE9SVEVEX0ZFQVRVUkUgPQotICAgICAgICAiRVJfVU5TVVBQT1JURURfRkVBVFVSRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYVEVOU0lPTl9FTEVNRU5UX05PVF9BTExPV0VEX0lOX1NFQ1VSRV9QUk9DRVNTSU5HID0KLSAgICAgICAgIkVSX0VYVEVOU0lPTl9FTEVNRU5UX05PVF9BTExPV0VEX0lOX1NFQ1VSRV9QUk9DRVNTSU5HIjsKLQotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19GT1VORF9DVVJMWUJSQUNFID0gIldHX0ZPVU5EX0NVUkxZQlJBQ0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19DT1VOVF9BVFRSSUJfTUFUQ0hFU19OT19BTkNFU1RPUiA9Ci0gICAgICAgICAiV0dfQ09VTlRfQVRUUklCX01BVENIRVNfTk9fQU5DRVNUT1IiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19FWFBSX0FUVFJJQl9DSEFOR0VEX1RPX1NFTEVDVCA9Ci0gICAgICAgICAiV0dfRVhQUl9BVFRSSUJfQ0hBTkdFRF9UT19TRUxFQ1QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19OT19MT0NBTEVfSU5fRk9STUFUTlVNQkVSID0KLSAgICAgICAgICJXR19OT19MT0NBTEVfSU5fRk9STUFUTlVNQkVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfTE9DQUxFX05PVF9GT1VORCA9ICJXR19MT0NBTEVfTk9UX0ZPVU5EIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfQ0FOTk9UX01BS0VfVVJMX0ZST00gPSJXR19DQU5OT1RfTUFLRV9VUkxfRlJPTSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0NBTk5PVF9MT0FEX1JFUVVFU1RFRF9ET0MgPQotICAgICAgICAgIldHX0NBTk5PVF9MT0FEX1JFUVVFU1RFRF9ET0MiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19DQU5OT1RfRklORF9DT0xMQVRPUiA9IldHX0NBTk5PVF9GSU5EX0NPTExBVE9SIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfRlVOQ1RJT05TX1NIT1VMRF9VU0VfVVJMID0KLSAgICAgICAgICJXR19GVU5DVElPTlNfU0hPVUxEX1VTRV9VUkwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19FTkNPRElOR19OT1RfU1VQUE9SVEVEX1VTSU5HX1VURjggPQotICAgICAgICAgIldHX0VOQ09ESU5HX05PVF9TVVBQT1JURURfVVNJTkdfVVRGOCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0VOQ09ESU5HX05PVF9TVVBQT1JURURfVVNJTkdfSkFWQSA9Ci0gICAgICAgICAiV0dfRU5DT0RJTkdfTk9UX1NVUFBPUlRFRF9VU0lOR19KQVZBIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfU1BFQ0lGSUNJVFlfQ09ORkxJQ1RTID0KLSAgICAgICAgICJXR19TUEVDSUZJQ0lUWV9DT05GTElDVFMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19QQVJTSU5HX0FORF9QUkVQQVJJTkcgPQotICAgICAgICAgIldHX1BBUlNJTkdfQU5EX1BSRVBBUklORyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0FUVFJfVEVNUExBVEUgPSAiV0dfQVRUUl9URU1QTEFURSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0NPTkZMSUNUX0JFVFdFRU5fWFNMU1RSSVBTUEFDRV9BTkRfWFNMUFJFU0VSVkVTUEFDRSA9ICJXR19DT05GTElDVF9CRVRXRUVOX1hTTFNUUklQU1BBQ0VfQU5EX1hTTFBSRVNFUlZFU1AiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19BVFRSSUJfTk9UX0hBTkRMRUQgPSAiV0dfQVRUUklCX05PVF9IQU5ETEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfTk9fREVDSU1BTEZPUk1BVF9ERUNMQVJBVElPTiA9Ci0gICAgICAgICAiV0dfTk9fREVDSU1BTEZPUk1BVF9ERUNMQVJBVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX09MRF9YU0xUX05TID0gIldHX09MRF9YU0xUX05TIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfT05FX0RFRkFVTFRfWFNMREVDSU1BTEZPUk1BVF9BTExPV0VEID0KLSAgICAgICAgICJXR19PTkVfREVGQVVMVF9YU0xERUNJTUFMRk9STUFUX0FMTE9XRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19YU0xERUNJTUFMRk9STUFUX05BTUVTX01VU1RfQkVfVU5JUVVFID0KLSAgICAgICAgICJXR19YU0xERUNJTUFMRk9STUFUX05BTUVTX01VU1RfQkVfVU5JUVVFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfSUxMRUdBTF9BVFRSSUJVVEUgPSAiV0dfSUxMRUdBTF9BVFRSSUJVVEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19DT1VMRF9OT1RfUkVTT0xWRV9QUkVGSVggPQotICAgICAgICAgIldHX0NPVUxEX05PVF9SRVNPTFZFX1BSRUZJWCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX1NUWUxFU0hFRVRfUkVRVUlSRVNfVkVSU0lPTl9BVFRSSUIgPQotICAgICAgICAgIldHX1NUWUxFU0hFRVRfUkVRVUlSRVNfVkVSU0lPTl9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19JTExFR0FMX0FUVFJJQlVURV9OQU1FID0KLSAgICAgICAgICJXR19JTExFR0FMX0FUVFJJQlVURV9OQU1FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfSUxMRUdBTF9BVFRSSUJVVEVfVkFMVUUgPQotICAgICAgICAgIldHX0lMTEVHQUxfQVRUUklCVVRFX1ZBTFVFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfRU1QVFlfU0VDT05EX0FSRyA9ICJXR19FTVBUWV9TRUNPTkRfQVJHIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfUFJPQ0VTU0lOR0lOU1RSVUNUSU9OX05BTUVfQ0FOVF9CRV9YTUwgPQotICAgICAgICAgIldHX1BST0NFU1NJTkdJTlNUUlVDVElPTl9OQU1FX0NBTlRfQkVfWE1MIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfUFJPQ0VTU0lOR0lOU1RSVUNUSU9OX05PVFZBTElEX05DTkFNRSA9Ci0gICAgICAgICAiV0dfUFJPQ0VTU0lOR0lOU1RSVUNUSU9OX05PVFZBTElEX05DTkFNRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0lMTEVHQUxfQVRUUklCVVRFX1BPU0lUSU9OID0KLSAgICAgICAgICJXR19JTExFR0FMX0FUVFJJQlVURV9QT1NJVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiA9Ci0gICAgICAgICAiTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIjsKLQotICAvKgotICAgKiBOb3cgZmlsbCBpbiB0aGUgbWVzc2FnZSB0ZXh0LgotICAgKiBUaGVuIGZpbGwgaW4gdGhlIG1lc3NhZ2UgdGV4dCBmb3IgdGhhdCBtZXNzYWdlIGNvZGUgaW4gdGhlCi0gICAqIGFycmF5LiBVc2UgdGhlIG5ldyBlcnJvciBjb2RlIGFzIHRoZSBpbmRleCBpbnRvIHRoZSBhcnJheS4KLSAgICovCi0KLSAgLy8gRXJyb3IgbWVzc2FnZXMuLi4KLQotICAvKiogR2V0IHRoZSBsb29rdXAgdGFibGUgZm9yIGVycm9yIG1lc3NhZ2VzLgotICAgICoKLSAgICAqIEByZXR1cm4gVGhlIG1lc3NhZ2UgbG9va3VwIHRhYmxlLgotICAgICovCi0gIHB1YmxpYyBPYmplY3RbXVtdIGdldENvbnRlbnRzKCkKLSAgewotICAgICAgcmV0dXJuIG5ldyBPYmplY3RbXVtdIHsKLQotICAvKiogRXJyb3IgbWVzc2FnZSBJRCB0aGF0IGhhcyBhIG51bGwgbWVzc2FnZSwgYnV0IHRha2VzIGluIGEgc2luZ2xlIG9iamVjdC4gICAgKi8KLSAgeyJFUjAwMDAiICwgInswfSIgfSwKLQotICAgIHsgRVJfTk9fQ1VSTFlCUkFDRSwKLSAgICAgICJFcnJvOiBOXHUwMEUzbyBcdTAwRTkgcG9zc1x1MDBFRHZlbCB1dGlsaXphciAnJ3snJyBuYSBleHByZXNzXHUwMEUzbyJ9LAotCi0gICAgeyBFUl9JTExFR0FMX0FUVFJJQlVURSAsCi0gICAgICJ7MH0gdGVtIHVtIGF0cmlidXRvIGludlx1MDBFMWxpZG86IHsxfSJ9LAotCi0gIHtFUl9OVUxMX1NPVVJDRU5PREVfQVBQTFlJTVBPUlRTICwKLSAgICAgICJzb3VyY2VOb2RlIFx1MDBFOSBudWxvIGVtIHhzbDphcHBseS1pbXBvcnRzISJ9LAotCi0gIHtFUl9DQU5OT1RfQURELAotICAgICAgIk5cdTAwRTNvIFx1MDBFOSBwb3NzXHUwMEVEdmVsIGFkaWNpb25hciB7MH0gYSB7MX0ifSwKLQotICAgIHsgRVJfTlVMTF9TT1VSQ0VOT0RFX0hBTkRMRUFQUExZVEVNUExBVEVTLAotICAgICAgInNvdXJjZU5vZGUgXHUwMEU5IG51bG8gZW0gaGFuZGxlQXBwbHlUZW1wbGF0ZXNJbnN0cnVjdGlvbiEifSwKLQotICAgIHsgRVJfTk9fTkFNRV9BVFRSSUIsCi0gICAgICJ7MH0gZGV2ZSB0ZXIgdW0gYXRyaWJ1dG8gZGUgbm9tZS4ifSwKLQotICAgIHtFUl9URU1QTEFURV9OT1RfRk9VTkQsCi0gICAgICJOXHUwMEUzbyBmb2kgcG9zc1x1MDBFRHZlbCBsb2NhbGl6YXIgbyBtb2RlbG8gY29tIG8gbm9tZTogezB9In0sCi0KLSAgICB7RVJfQ0FOVF9SRVNPTFZFX05BTUVfQVZULAotICAgICAgIk5cdTAwRTNvIGZvaSBwb3NzXHUwMEVEdmVsIHJlc29sdmVyIG8gbm9tZSBBVlQgZW0geHNsOmNhbGwtdGVtcGxhdGUuIn0sCi0KLSAgICB7RVJfUkVRVUlSRVNfQVRUUklCLAotICAgICAiezB9IHJlcXVlciBvIGF0cmlidXRvOiB7MX0ifSwKLQotICAgIHsgRVJfTVVTVF9IQVZFX1RFU1RfQVRUUklCLAotICAgICAgInswfSBkZXZlIHRlciB1bSBhdHJpYnV0byAnJ3Rlc3QnJy4ifSwKLQotICAgIHtFUl9CQURfVkFMX09OX0xFVkVMX0FUVFJJQiwKLSAgICAgICJWYWxvciBpbnZcdTAwRTFsaWRvIG5vIGF0cmlidXRvIGRlIG5cdTAwRUR2ZWw6IHswfSJ9LAotCi0gICAge0VSX1BST0NFU1NJTkdJTlNUUlVDVElPTl9OQU1FX0NBTlRfQkVfWE1MLAotICAgICAgIm8gbm9tZSBkYSBpbnN0cnVcdTAwRTdcdTAwRTNvIGRlIHByb2Nlc3NhbWVudG8gblx1MDBFM28gcG9kZSBzZXIgJ3htbCcifSwKLQotICAgIHsgRVJfUFJPQ0VTU0lOR0lOU1RSVUNUSU9OX05PVFZBTElEX05DTkFNRSwKLSAgICAgICJvIG5vbWUgZGEgaW5zdHJ1XHUwMEU3XHUwMEUzbyBkZSBwcm9jZXNzYW1lbnRvIGRldmUgc2VyIHVtIE5DTmFtZSB2XHUwMEUxbGlkbzogezB9In0sCi0KLSAgICB7IEVSX05FRURfTUFUQ0hfQVRUUklCLAotICAgICAgInswfSBkZXZlIHRlciB1bSBhdHJpYnV0byBkZSBjb3JyZXNwb25kXHUwMEVBbmNpYSBzZSB0aXZlciB1bSBtb2RvLiJ9LAotCi0gICAgeyBFUl9ORUVEX05BTUVfT1JfTUFUQ0hfQVRUUklCLAotICAgICAgInswfSByZXF1ZXIgdW0gYXRyaWJ1dG8gZGUgbm9tZSBvdSBkZSBjb3JyZXNwb25kXHUwMEVBbmNpYS4ifSwKLQotICAgIHtFUl9DQU5UX1JFU09MVkVfTlNQUkVGSVgsCi0gICAgICAiTlx1MDBFM28gXHUwMEU5IHBvc3NcdTAwRUR2ZWwgcmVzb2x2ZXIgbyBwcmVmaXhvIGRvIG5hbWVzcGFjZTogezB9In0sCi0KLSAgICB7IEVSX0lMTEVHQUxfVkFMVUUsCi0gICAgICJ4bWw6c3BhY2UgdGVtIHVtIHZhbG9yIGludlx1MDBFMWxpZG86IHswfSJ9LAotCi0gICAgeyBFUl9OT19PV05FUkRPQywKLSAgICAgICJPIG5cdTAwRjMgZmlsaG8gblx1MDBFM28gdGVtIHVtIGRvY3VtZW50byBkZSBwcm9wcmlldFx1MDBFMXJpbyEifSwKLQotICAgIHsgRVJfRUxFTVRFTVBMQVRFRUxFTV9FUlIsCi0gICAgICJFcnJvIGRlIEVsZW1UZW1wbGF0ZUVsZW1lbnQ6IHswfSJ9LAotCi0gICAgeyBFUl9OVUxMX0NISUxELAotICAgICAiVGVudGF0aXZhIGRlIGFkaWNpb25hciB1bSBmaWxobyBudWxvISJ9LAotCi0gICAgeyBFUl9ORUVEX1NFTEVDVF9BVFRSSUIsCi0gICAgICJ7MH0gcmVxdWVyIHVtIGF0cmlidXRvIGRlIHNlbGVcdTAwRTdcdTAwRTNvLiJ9LAotCi0gICAgeyBFUl9ORUVEX1RFU1RfQVRUUklCICwKLSAgICAgICJ4c2w6d2hlbiBkZXZlIHRlciB1bSBhdHJpYnV0byAndGVzdCcuIn0sCi0KLSAgICB7IEVSX05FRURfTkFNRV9BVFRSSUIsCi0gICAgICAieHNsOndpdGgtcGFyYW0gZGV2ZSB0ZXIgdW0gYXRyaWJ1dG8gJ25hbWUnLiJ9LAotCi0gICAgeyBFUl9OT19DT05URVhUX09XTkVSRE9DLAotICAgICAgIm8gY29udGV4dG8gblx1MDBFM28gdGVtIHVtIGRvY3VtZW50byBkZSBwcm9wcmlldFx1MDBFMXJpbyEifSwKLQotICAgIHtFUl9DT1VMRF9OT1RfQ1JFQVRFX1hNTF9QUk9DX0xJQUlTT04sCi0gICAgICAiTlx1MDBFM28gZm9pIHBvc3NcdTAwRUR2ZWwgY3JpYXIgYSBMaWdhXHUwMEU3XHUwMEUzbyBUcmFuc2Zvcm1lckZhY3RvcnkgWE1MOiB7MH0ifSwKLQotICAgIHtFUl9QUk9DRVNTX05PVF9TVUNDRVNTRlVMLAotICAgICAgIlhhbGFuOiBPIHByb2Nlc3NvIG5cdTAwRTNvIGZvaSBiZW0tc3VjZWRpZG8uIn0sCi0KLSAgICB7IEVSX05PVF9TVUNDRVNTRlVMLAotICAgICAiWGFsYW46IE5cdTAwRTNvIGZvaSBiZW0tc3VjZWRpZG8uIn0sCi0KLSAgICB7IEVSX0VOQ09ESU5HX05PVF9TVVBQT1JURUQsCi0gICAgICJDb2RpZmljYVx1MDBFN1x1MDBFM28gblx1MDBFM28gc3Vwb3J0YWRhOiB7MH0ifSwKLQotICAgIHtFUl9DT1VMRF9OT1RfQ1JFQVRFX1RSQUNFTElTVEVORVIsCi0gICAgICAiTlx1MDBFM28gZm9pIHBvc3NcdTAwRUR2ZWwgY3JpYXIgVHJhY2VMaXN0ZW5lcjogezB9In0sCi0KLSAgICB7RVJfS0VZX1JFUVVJUkVTX05BTUVfQVRUUklCLAotICAgICAgInhzbDprZXkgcmVxdWVyIHVtIGF0cmlidXRvICduYW1lJyEifSwKLQotICAgIHsgRVJfS0VZX1JFUVVJUkVTX01BVENIX0FUVFJJQiwKLSAgICAgICJ4c2w6a2V5IHJlcXVlciB1bSBhdHJpYnV0byAnbWF0Y2gnISJ9LAotCi0gICAgeyBFUl9LRVlfUkVRVUlSRVNfVVNFX0FUVFJJQiwKLSAgICAgICJ4c2w6a2V5IHJlcXVlciB1bSBhdHJpYnV0byAndXNlJyEifSwKLQotICAgIHsgRVJfUkVRVUlSRVNfRUxFTUVOVFNfQVRUUklCLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgezB9IHJlcXVlciB1bSBhdHJpYnV0byAnJ2VsZW1lbnRzJychIn0sCi0KLSAgICB7IEVSX01JU1NJTkdfUFJFRklYX0FUVFJJQiwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIG8gYXRyaWJ1dG8gJydwcmVmaXgnJyBkZSB7MH0gblx1MDBFM28gZm9pIGVuY29udHJhZG8ifSwKLQotICAgIHsgRVJfQkFEX1NUWUxFU0hFRVRfVVJMLAotICAgICAiTyBVUkwgZGEgRm9saGEgZGUgRXN0aWxvcyBlc3RcdTAwRTEgaW5jb3JyZXRvOiB7MH0ifSwKLQotICAgIHsgRVJfRklMRV9OT1RfRk9VTkQsCi0gICAgICJPIGFycXVpdm8gZGEgZm9saGEgZGUgZXN0aWxvcyBuXHUwMEUzbyBmb2kgZW5jb250cmFkbzogezB9In0sCi0KLSAgICB7IEVSX0lPRVhDRVBUSU9OLAotICAgICAgIkV4Y2VcdTAwRTdcdTAwRTNvIGRlIEUvUyBjb20gbyBhcnF1aXZvIGRlIGZvbGhhIGRlIGVzdGlsb3M6IHswfSJ9LAotCi0gICAgeyBFUl9OT19IUkVGX0FUVFJJQiwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIE5cdTAwRTNvIGZvaSBwb3NzXHUwMEVEdmVsIGVuY29udHJhciBvIGF0cmlidXRvIGhyZWYgcGFyYSB7MH0ifSwKLQotICAgIHsgRVJfU1RZTEVTSEVFVF9JTkNMVURFU19JVFNFTEYsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSBBIGZvbGhhIGRlIGVzdGlsb3MgezB9IGVzdFx1MDBFMSBpbmNsdWluZG8gYSBzaSBtZXNtYSBkaXJldGEgb3UgaW5kaXJldGFtZW50ZSEifSwKLQotICAgIHsgRVJfUFJPQ0VTU0lOQ0xVREVfRVJST1IsCi0gICAgICAiRXJybyBkZSBTdHlsZXNoZWV0SGFuZGxlci5wcm9jZXNzSW5jbHVkZTogezB9In0sCi0KLSAgICB7IEVSX01JU1NJTkdfTEFOR19BVFRSSUIsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSBPIGF0cmlidXRvICcnbGFuZycnIGRlIHswfSBuXHUwMEUzbyBmb2kgZW5jb250cmFkbyJ9LAotCi0gICAgeyBFUl9NSVNTSU5HX0NPTlRBSU5FUl9FTEVNRU5UX0NPTVBPTkVOVCwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIGVsZW1lbnRvIHswfSBpbmNvcnJldGFtZW50ZSBwb3NpY2lvbmFkbz8/IEVsZW1lbnRvICcnY29tcG9uZW50JycgZG8gY29udGFpbmVyIG5cdTAwRTNvIGVuY29udHJhZG8ifSwKLQotICAgIHsgRVJfQ0FOX09OTFlfT1VUUFVUX1RPX0VMRU1FTlQsCi0gICAgICAiU2FcdTAwRURkYSBwZXJtaXRpZGEgc29tZW50ZSBwYXJhIEVsZW1lbnQsIERvY3VtZW50RnJhZ21lbnQsIERvY3VtZW50IG91IFByaW50V3JpdGVyLiJ9LAotCi0gICAgeyBFUl9QUk9DRVNTX0VSUk9SLAotICAgICAiRXJybyBkZSBTdHlsZXNoZWV0Um9vdC5wcm9jZXNzIn0sCi0KLSAgICB7IEVSX1VOSU1QTE5PREVfRVJST1IsCi0gICAgICJFcnJvIGRlIFVuSW1wbE5vZGU6IHswfSJ9LAotCi0gICAgeyBFUl9OT19TRUxFQ1RfRVhQUkVTU0lPTiwKLSAgICAgICJFcnJvISBOXHUwMEUzbyBmb2kgcG9zc1x1MDBFRHZlbCBsb2NhbGl6YXIgYSBleHByZXNzXHUwMEUzbyBkZSBzZWxlXHUwMEU3XHUwMEUzbyB4cGF0aCAoLXNlbGVjdCkuIn0sCi0KLSAgICB7IEVSX0NBTk5PVF9TRVJJQUxJWkVfWFNMUFJPQ0VTU09SLAotICAgICAgIk5cdTAwRTNvIFx1MDBFOSBwb3NzXHUwMEVEdmVsIHNlcmlhbGl6YXIgdW0gWFNMUHJvY2Vzc29yISJ9LAotCi0gICAgeyBFUl9OT19JTlBVVF9TVFlMRVNIRUVULAotICAgICAgIkEgZW50cmFkYSBkYSBmb2xoYSBkZSBlc3RpbG9zIG5cdTAwRTNvIGZvaSBlc3BlY2lmaWNhZGEhIn0sCi0KLSAgICB7IEVSX0ZBSUxFRF9QUk9DRVNTX1NUWUxFU0hFRVQsCi0gICAgICAiRmFsaGEgYW8gcHJvY2Vzc2FyIGEgZm9saGEgZGUgZXN0aWxvcyEifSwKLQotICAgIHsgRVJfQ09VTEROVF9QQVJTRV9ET0MsCi0gICAgICJOXHUwMEUzbyBmb2kgcG9zc1x1MDBFRHZlbCBmYXplciBwYXJzaW5nIGRvIGRvY3VtZW50byB7MH0hIn0sCi0KLSAgICB7IEVSX0NPVUxETlRfRklORF9GUkFHTUVOVCwKLSAgICAgIk5cdTAwRTNvIGZvaSBwb3NzXHUwMEVEdmVsIGxvY2FsaXphciBvIGZyYWdtZW50bzogezB9In0sCi0KLSAgICB7IEVSX05PREVfTk9UX0VMRU1FTlQsCi0gICAgICAiTyBuXHUwMEYzIGluZGljYWRvIHBlbG8gaWRlbnRpZmljYWRvciBkZSBmcmFnbWVudG8gblx1MDBFM28gZXJhIHVtIGVsZW1lbnRvOiB7MH0ifSwKLQotICAgIHsgRVJfRk9SRUFDSF9ORUVEX01BVENIX09SX05BTUVfQVRUUklCLAotICAgICAgImZvci1lYWNoIGRldmUgdGVyIHVtIGF0cmlidXRvIGRlIGNvcnJlc3BvbmRcdTAwRUFuY2lhIG91IGRlIG5vbWUifSwKLQotICAgIHsgRVJfVEVNUExBVEVTX05FRURfTUFUQ0hfT1JfTkFNRV9BVFRSSUIsCi0gICAgICAib3MgbW9kZWxvcyBkZXZlbSB0ZXIgdW0gYXRyaWJ1dG8gZGUgY29ycmVzcG9uZFx1MDBFQW5jaWEgb3UgZGUgbm9tZSJ9LAotCi0gICAgeyBFUl9OT19DTE9ORV9PRl9ET0NVTUVOVF9GUkFHLAotICAgICAgIk5cdTAwRTNvIGhcdTAwRTEgY2xvbmUgZGUgdW0gZnJhZ21lbnRvIGRlIGRvY3VtZW50byEifSwKLQotICAgIHsgRVJfQ0FOVF9DUkVBVEVfSVRFTSwKLSAgICAgICJOXHUwMEUzbyBcdTAwRTkgcG9zc1x1MDBFRHZlbCBjcmlhciB1bSBpdGVtIGVtIHVtYSBcdTAwRTFydm9yZSBkZSByZXN1bHRhZG9zOiB7MH0ifSwKLQotICAgIHsgRVJfWE1MU1BBQ0VfSUxMRUdBTF9WQUxVRSwKLSAgICAgICJ4bWw6c3BhY2Ugbm8gWE1MIGRlIG9yaWdlbSB0ZW0gdW0gdmFsb3IgaW52XHUwMEUxbGlkbzogezB9In0sCi0KLSAgICB7IEVSX05PX1hTTEtFWV9ERUNMQVJBVElPTiwKLSAgICAgICJOXHUwMEUzbyBoXHUwMEUxIHVtYSBkZWNsYXJhXHUwMEU3XHUwMEUzbyBkZSB4c2w6a2V5IHBhcmEgezB9ISJ9LAotCi0gICAgeyBFUl9DQU5UX0NSRUFURV9VUkwsCi0gICAgICJFcnJvISBOXHUwMEUzbyBcdTAwRTkgcG9zc1x1MDBFRHZlbCBjcmlhciBvIHVybCBwYXJhOiB7MH0ifSwKLQotICAgIHsgRVJfWFNMRlVOQ1RJT05TX1VOU1VQUE9SVEVELAotICAgICAieHNsOmZ1bmN0aW9ucyBuXHUwMEUzbyBcdTAwRTkgc3Vwb3J0YWRvIn0sCi0KLSAgICB7IEVSX1BST0NFU1NPUl9FUlJPUiwKLSAgICAgIkVycm8gZGUgVHJhbnNmb3JtZXJGYWN0b3J5IFhTTFQifSwKLQotICAgIHsgRVJfTk9UX0FMTE9XRURfSU5TSURFX1NUWUxFU0hFRVQsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSB7MH0gblx1MDBFM28gXHUwMEU5IHBlcm1pdGlkbyBlbSB1bWEgZm9saGEgZGUgZXN0aWxvcyEifSwKLQotICAgIHsgRVJfUkVTVUxUTlNfTk9UX1NVUFBPUlRFRCwKLSAgICAgICJyZXN1bHQtbnMgblx1MDBFM28gXHUwMEU5IG1haXMgc3Vwb3J0YWRvISBFbSB2ZXogZGlzc28sIHVzZSB4c2w6b3V0cHV0LiJ9LAotCi0gICAgeyBFUl9ERUZBVUxUU1BBQ0VfTk9UX1NVUFBPUlRFRCwKLSAgICAgICJwYWRyXHUwMEUzby1zcGFjZSBuXHUwMEUzbyBcdTAwRTkgbWFpcyBzdXBvcnRhZG8hIEVtIHZleiBkaXNzbywgdXNlIHhzbDpzdHJpcC1zcGFjZSBvdSB4c2w6cHJlc2VydmUtc3BhY2UuIn0sCi0KLSAgICB7IEVSX0lOREVOVFJFU1VMVF9OT1RfU1VQUE9SVEVELAotICAgICAgImluZGVudC1yZXN1bHQgblx1MDBFM28gXHUwMEU5IG1haXMgc3Vwb3J0YWRvISBFbSB2ZXogZGlzc28sIHVzZSB4c2w6b3V0cHV0LiJ9LAotCi0gICAgeyBFUl9JTExFR0FMX0FUVFJJQiwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIHswfSB0ZW0gdW0gYXRyaWJ1dG8gaW52XHUwMEUxbGlkbzogezF9In0sCi0KLSAgICB7IEVSX1VOS05PV05fWFNMX0VMRU0sCi0gICAgICJFbGVtZW50byBYU0wgZGVzY29uaGVjaWRvOiB7MH0ifSwKLQotICAgIHsgRVJfQkFEX1hTTFNPUlRfVVNFLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgeHNsOnNvcnQgc1x1MDBGMyBwb2RlIHNlciB1c2FkbyBjb20geHNsOmFwcGx5LXRlbXBsYXRlcyBvdSB4c2w6Zm9yLWVhY2guIn0sCi0KLSAgICB7IEVSX01JU1BMQUNFRF9YU0xXSEVOLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgeHNsOndoZW4gcG9zaWNpb25hZG8gaW5jb3JyZXRhbWVudGUhIn0sCi0KLSAgICB7IEVSX1hTTFdIRU5fTk9UX1BBUkVOVEVEX0JZX1hTTENIT09TRSwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIHhzbDp3aGVuIG5cdTAwRTNvIHJlbGFjaW9uYWRvIGEgeHNsOmNob29zZSEifSwKLQotICAgIHsgRVJfTUlTUExBQ0VEX1hTTE9USEVSV0lTRSwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIHhzbDpvdGhlcndpc2UgcG9zaWNpb25hZG8gaW5jb3JyZXRhbWVudGUhIn0sCi0KLSAgICB7IEVSX1hTTE9USEVSV0lTRV9OT1RfUEFSRU5URURfQllfWFNMQ0hPT1NFLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgeHNsOm90aGVyd2lzZSBuXHUwMEUzbyByZWxhY2lvbmFkbyBhIHhzbDpjaG9vc2UhIn0sCi0KLSAgICB7IEVSX05PVF9BTExPV0VEX0lOU0lERV9URU1QTEFURSwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIHswfSBuXHUwMEUzbyBcdTAwRTkgcGVybWl0aWRvIGVtIHVtIG1vZGVsbyEifSwKLQotICAgIHsgRVJfVU5LTk9XTl9FWFRfTlNfUFJFRklYLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgcHJlZml4byB7MX0gZGUgbmFtZXNwYWNlIGRhIGV4dGVuc1x1MDBFM28gZGUgezB9IGRlc2NvbmhlY2lkbyJ9LAotCi0gICAgeyBFUl9JTVBPUlRTX0FTX0ZJUlNUX0VMRU0sCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSBBcyBpbXBvcnRhXHUwMEU3XHUwMEY1ZXMgc1x1MDBGMyBwb2RlbSBvY29ycmVyIGNvbW8gb3MgcHJpbWVpcm9zIGVsZW1lbnRvcyBuYSBmb2xoYSBkZSBlc3RpbG9zISJ9LAotCi0gICAgeyBFUl9JTVBPUlRJTkdfSVRTRUxGLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgQSBmb2xoYSBkZSBlc3RpbG9zIHswfSBlc3RcdTAwRTEgaW1wb3J0YW5kbyBhIHNpIG1lc21vKGEpIGRpcmV0YSBvdSBpbmRpcmV0YW1lbnRlISJ9LAotCi0gICAgeyBFUl9YTUxTUEFDRV9JTExFR0FMX1ZBTCwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIHhtbDpzcGFjZSB0ZW0gdW0gdmFsb3IgaW52XHUwMEUxbGlkbzogezB9In0sCi0KLSAgICB7IEVSX1BST0NFU1NTVFlMRVNIRUVUX05PVF9TVUNDRVNTRlVMLAotICAgICAgInByb2Nlc3NTdHlsZXNoZWV0IG1hbHN1Y2VkaWRvISJ9LAotCi0gICAgeyBFUl9TQVhfRVhDRVBUSU9OLAotICAgICAiRXhjZVx1MDBFN1x1MDBFM28gZGUgU0FYIn0sCi0KLS8vICBhZGQgdGhpcyBtZXNzYWdlIHRvIGZpeCBidWcgMjE0NzgKLSAgICB7IEVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQsCi0gICAgICJGdW5cdTAwRTdcdTAwRTNvIG5cdTAwRTNvIHN1cG9ydGFkYSEifSwKLQotICAgIHsgRVJfWFNMVF9FUlJPUiwKLSAgICAgIkVycm8gZGUgWFNMVCJ9LAotCi0gICAgeyBFUl9DVVJSRU5DWV9TSUdOX0lMTEVHQUwsCi0gICAgICAic2luYWwgZGUgbW9lZGEgblx1MDBFM28gcGVybWl0aWRvIG5hIHN0cmluZyBkZSBwYWRyXHUwMEUzbyBkZSBmb3JtYXRvIn0sCi0KLSAgICB7IEVSX0RPQ1VNRU5UX0ZVTkNUSU9OX0lOVkFMSURfSU5fU1RZTEVTSEVFVF9ET00sCi0gICAgICAiRnVuXHUwMEU3XHUwMEUzbyBkbyBkb2N1bWVudG8gblx1MDBFM28gc3Vwb3J0YWRhIG5vIERPTSBkYSBGb2xoYSBkZSBlc3RpbG9zISJ9LAotCi0gICAgeyBFUl9DQU5UX1JFU09MVkVfUFJFRklYX09GX05PTl9QUkVGSVhfUkVTT0xWRVIsCi0gICAgICAiTlx1MDBFM28gXHUwMEU5IHBvc3NcdTAwRUR2ZWwgcmVzb2x2ZXIgbyBwcmVmaXhvIGRlIHVtIHJlc29sdmVkb3Igc2VtIFByZWZpeG8hIn0sCi0KLSAgICB7IEVSX1JFRElSRUNUX0NPVUxETlRfR0VUX0ZJTEVOQU1FLAotICAgICAgIlJlZGlyZWNpb25hciBleHRlbnNcdTAwRTNvOiBOXHUwMEUzbyBmb2kgcG9zc1x1MDBFRHZlbCBvYnRlciBvIG5vbWUgZG8gYXJxdWl2byAtIG8gYXJxdWl2byBvdSBvIGF0cmlidXRvIGRlIHNlbGVcdTAwRTdcdTAwRTNvIGRldmUgcmV0b3JuYXIgdW1hIHN0cmluZyB2XHUwMEUxbGlkYS4ifSwKLQotICAgIHsgRVJfQ0FOTk9UX0JVSUxEX0ZPUk1BVFRFUkxJU1RFTkVSX0lOX1JFRElSRUNULAotICAgICAgIk5cdTAwRTNvIFx1MDBFOSBwb3NzXHUwMEVEdmVsIGNyaWFyIEZvcm1hdHRlckxpc3RlbmVyIG5hIGV4dGVuc1x1MDBFM28gZGUgUmVkaXJlY2lvbmFtZW50byEifSwKLQotICAgIHsgRVJfSU5WQUxJRF9QUkVGSVhfSU5fRVhDTFVERVJFU1VMVFBSRUZJWCwKLSAgICAgICJPIHByZWZpeG8gZW0gZXhjbHVkZS1yZXN1bHQtcHJlZml4ZXMgblx1MDBFM28gXHUwMEU5IHZcdTAwRTFsaWRvOiB7MH0ifSwKLQotICAgIHsgRVJfTUlTU0lOR19OU19VUkksCi0gICAgICAiVVJJIGRvIG5hbWVzcGFjZSBuXHUwMEUzbyBlbmNvbnRyYWRvIHBhcmEgbyBwcmVmaXhvIGVzcGVjaWZpY2FkbyJ9LAotCi0gICAgeyBFUl9NSVNTSU5HX0FSR19GT1JfT1BUSU9OLAotICAgICAgIkFyZ3VtZW50byBuXHUwMEUzbyBlbmNvbnRyYWRvIHBhcmEgYSBvcFx1MDBFN1x1MDBFM286IHswfSJ9LAotCi0gICAgeyBFUl9JTlZBTElEX09QVElPTiwKLSAgICAgIk9wXHUwMEU3XHUwMEUzbyBpbnZcdTAwRTFsaWRhOiB7MH0ifSwKLQotICAgIHsgRVJfTUFMRk9STUVEX0ZPUk1BVF9TVFJJTkcsCi0gICAgICJTdHJpbmcgZGUgZm9ybWF0byBpbmNvcnJldGE6IHswfSJ9LAotCi0gICAgeyBFUl9TVFlMRVNIRUVUX1JFUVVJUkVTX1ZFUlNJT05fQVRUUklCLAotICAgICAgInhzbDpzdHlsZXNoZWV0IHJlcXVlciB1bSBhdHJpYnV0byAndmVyc2lvbichIn0sCi0KLSAgICB7IEVSX0lMTEVHQUxfQVRUUklCVVRFX1ZBTFVFLAotICAgICAgIkF0cmlidXRvOiB7MH0gdGVtIHVtIHZhbG9yIGludlx1MDBFMWxpZG86IHsxfSJ9LAotCi0gICAgeyBFUl9DSE9PU0VfUkVRVUlSRVNfV0hFTiwKLSAgICAgInhzbDpjaG9vc2UgcmVxdWVyIHVtIHhzbDp3aGVuIn0sCi0KLSAgICB7IEVSX05PX0FQUExZX0lNUE9SVF9JTl9GT1JfRUFDSCwKLSAgICAgICJ4c2w6YXBwbHktaW1wb3J0cyBuXHUwMEUzbyBwZXJtaXRpZG8gZW0gdW0geHNsOmZvci1lYWNoIn0sCi0KLSAgICB7IEVSX0NBTlRfVVNFX0RUTV9GT1JfT1VUUFVULAotICAgICAgIk5cdTAwRTNvIFx1MDBFOSBwb3NzXHUwMEVEdmVsIHVzYXIgdW0gRFRNTGlhaXNvbiBwYXJhIHVtIG5cdTAwRjMgRE9NIGRlIHNhXHUwMEVEZGEuLi4gZW0gdmV6IGRpc3NvLCBlc3BlY2lmaXF1ZSB1bSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuRE9NMkhlbHBlciEifSwKLQotICAgIHsgRVJfQ0FOVF9VU0VfRFRNX0ZPUl9JTlBVVCwKLSAgICAgICJOXHUwMEUzbyBcdTAwRTkgcG9zc1x1MDBFRHZlbCB1c2FyIHVtIERUTUxpYWlzb24gcGFyYSB1bSBuXHUwMEYzIERPTSBkZSBlbnRyYWRhLi4uIGVtIHZleiBkaXNzbywgZXNwZWNpZmlxdWUgdW0gY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLkRPTTJIZWxwZXIhIn0sCi0KLSAgICB7IEVSX0NBTExfVE9fRVhUX0ZBSUxFRCwKLSAgICAgICJGYWxoYSBhbyBjaGFtYXIgbyBlbGVtZW50byBkYSBleHRlbnNcdTAwRTNvOiB7MH0ifSwKLQotICAgIHsgRVJfUFJFRklYX01VU1RfUkVTT0xWRSwKLSAgICAgICJPIHByZWZpeG8gZGV2ZSBzZXIgcmVzb2x2aWRvIHBhcmEgdW0gbmFtZXNwYWNlOiB7MH0ifSwKLQotICAgIHsgRVJfSU5WQUxJRF9VVEYxNl9TVVJST0dBVEUsCi0gICAgICAiRm9pIGRldGVjdGFkbyB1bSBzdWJzdGl0dXRvIGRlIFVURi0xNiBpbnZcdTAwRTFsaWRvOiB7MH0gPyJ9LAotCi0gICAgeyBFUl9YU0xBVFRSU0VUX1VTRURfSVRTRUxGLAotICAgICAgInhzbDphdHRyaWJ1dGUtc2V0IHswfSB1c291IGVsZSBtZXNtbywgbyBxdWUgY2F1c2FyXHUwMEUxIHVtIGxvb3AgaW5maW5pdG8uIn0sCi0KLSAgICB7IEVSX0NBTk5PVF9NSVhfWEVSQ0VTRE9NLAotICAgICAgIk5cdTAwRTNvIFx1MDBFOSBwb3NzXHUwMEVEdmVsIG1pc3R1cmFyIGVudHJhZGEgblx1MDBFM28gWGVyY2VzLURPTSBjb20gc2FcdTAwRURkYSBYZXJjZXMtRE9NISJ9LAotCi0gICAgeyBFUl9UT09fTUFOWV9MSVNURU5FUlMsCi0gICAgICAiYWRkVHJhY2VMaXN0ZW5lcnNUb1N0eWxlc2hlZXQgLSBUb29NYW55TGlzdGVuZXJzRXhjZXB0aW9uIn0sCi0KLSAgICB7IEVSX0lOX0VMRU1URU1QTEFURUVMRU1fUkVBRE9CSkVDVCwKLSAgICAgICJObyBFbGVtVGVtcGxhdGVFbGVtZW50LnJlYWRPYmplY3Q6IHswfSJ9LAotCi0gICAgeyBFUl9EVVBMSUNBVEVfTkFNRURfVEVNUExBVEUsCi0gICAgICAiRm9pIGVuY29udHJhZG8gbWFpcyBkZSB1bSBtb2RlbG8gY29tIG8gbm9tZTogezB9In0sCi0KLSAgICB7IEVSX0lOVkFMSURfS0VZX0NBTEwsCi0gICAgICAiQ2hhbWFkYSBkZSBmdW5cdTAwRTdcdTAwRTNvIGludlx1MDBFMWxpZGE6IGNoYW1hZGFzIHJlY3Vyc2l2YXMgZGUga2V5KCkgblx1MDBFM28gc1x1MDBFM28gcGVybWl0aWRhcyJ9LAotCi0gICAgeyBFUl9SRUZFUkVOQ0lOR19JVFNFTEYsCi0gICAgICAiQSB2YXJpXHUwMEUxdmVsIHswfSBlc3RcdTAwRTEgaW1wb3J0YW5kbyBlbGEgbWVzbWEgZGUgZm9ybWEgZGlyZXRhIG91IGluZGlyZXRhISJ9LAotCi0gICAgeyBFUl9JTExFR0FMX0RPTVNPVVJDRV9JTlBVVCwKLSAgICAgICJPIG5cdTAwRjMgZGUgZW50cmFkYSBuXHUwMEUzbyBwb2RlIHNlciBudWxvIHBhcmEgdW0gRE9NU291cmNlIHBhcmEgbmV3VGVtcGxhdGVzISJ9LAotCi0gICAgeyBFUl9DTEFTU19OT1RfRk9VTkRfRk9SX09QVElPTiwKLSAgICAgICAgIk8gYXJxdWl2byBkZSBjbGFzc2Ugblx1MDBFM28gZm9pIGVuY29udHJhZG8gcGFyYSBhIG9wXHUwMEU3XHUwMEUzbyB7MH0ifSwKLQotICAgIHsgRVJfUkVRVUlSRURfRUxFTV9OT1RfRk9VTkQsCi0gICAgICAgICJFbGVtZW50byBPYnJpZ2F0XHUwMEYzcmlvIG5cdTAwRTNvIGVuY29udHJhZG86IHswfSJ9LAotCi0gICAgeyBFUl9JTlBVVF9DQU5OT1RfQkVfTlVMTCwKLSAgICAgICAgIklucHV0U3RyZWFtIG5cdTAwRTNvIHBvZGUgc2VyIG51bG8ifSwKLQotICAgIHsgRVJfVVJJX0NBTk5PVF9CRV9OVUxMLAotICAgICAgICAiTyBVUkkgblx1MDBFM28gcG9kZSBzZXIgbnVsbyJ9LAotCi0gICAgeyBFUl9GSUxFX0NBTk5PVF9CRV9OVUxMLAotICAgICAgICAiTyBhcnF1aXZvIG5cdTAwRTNvIHBvZGUgc2VyIG51bG8ifSwKLQotICAgIHsgRVJfU09VUkNFX0NBTk5PVF9CRV9OVUxMLAotICAgICAgICAgICAgICAgICJJbnB1dFNvdXJjZSBuXHUwMEUzbyBwb2RlIHNlciBudWxvIn0sCi0KLSAgICB7IEVSX0NBTk5PVF9JTklUX0JTRk1HUiwKLSAgICAgICAgICAgICAgICAiTlx1MDBFM28gZm9pIHBvc3NcdTAwRUR2ZWwgaW5pY2lhbGl6YXIgbyBHZXJlbmNpYWRvciBkZSBCU0YifSwKLQotICAgIHsgRVJfQ0FOTk9UX0NNUExfRVhURU5TTiwKLSAgICAgICAgICAgICAgICAiTlx1MDBFM28gZm9pIHBvc3NcdTAwRUR2ZWwgY29tcGlsYXIgYSBleHRlbnNcdTAwRTNvIn0sCi0KLSAgICB7IEVSX0NBTk5PVF9DUkVBVEVfRVhURU5TTiwKLSAgICAgICJOXHUwMEUzbyBmb2kgcG9zc1x1MDBFRHZlbCBjcmlhciBhIGV4dGVuc1x1MDBFM286IHswfSBlbSBkZWNvcnJcdTAwRUFuY2lhIGRlOiB7MX0ifSwKLQotICAgIHsgRVJfSU5TVEFOQ0VfTVRIRF9DQUxMX1JFUVVJUkVTLAotICAgICAgIkEgY2hhbWFkYSBkbyBtXHUwMEU5dG9kbyBkYSBpbnN0XHUwMEUybmNpYSBwYXJhIG8gbVx1MDBFOXRvZG8gezB9IGV4aWdlIHVtYSBpbnN0XHUwMEUybmNpYSBkbyBPYmpldG8gY29tbyBwcmltZWlybyBhcmd1bWVudG8ifSwKLQotICAgIHsgRVJfSU5WQUxJRF9FTEVNRU5UX05BTUUsCi0gICAgICAiTm9tZSBkZSBlbGVtZW50byBpbnZcdTAwRTFsaWRvIGVzcGVjaWZpY2FkbyB7MH0ifSwKLQotICAgIHsgRVJfRUxFTUVOVF9OQU1FX01FVEhPRF9TVEFUSUMsCi0gICAgICAiTyBtXHUwMEU5dG9kbyBkbyBub21lIGRvIGVsZW1lbnRvIGRldmUgc2VyIGVzdFx1MDBFMXRpY28gezB9In0sCi0KLSAgICB7IEVSX0VYVEVOU0lPTl9GVU5DX1VOS05PV04sCi0gICAgICAgICAgICAgIkZ1blx1MDBFN1x1MDBFM28gZGEgZXh0ZW5zXHUwMEUzbyB7MH0gOiB7MX0gZGVzY29uaGVjaWRvIn0sCi0KLSAgICB7IEVSX01PUkVfTUFUQ0hfQ09OU1RSVUNUT1IsCi0gICAgICAgICAgICAgIkhcdTAwRTEgbWFpcyBkZSB1bWEgbWVsaG9yIGNvcnJlc3BvbmRcdTAwRUFuY2lhIHBhcmEgbyBjb25zdHJ1dG9yIGVtIHJlbGFcdTAwRTdcdTAwRTNvIGEgezB9In0sCi0KLSAgICB7IEVSX01PUkVfTUFUQ0hfTUVUSE9ELAotICAgICAgICAgICAgICJIXHUwMEUxIG1haXMgZGUgdW1hIG1lbGhvciBjb3JyZXNwb25kXHUwMEVBbmNpYSBwYXJhIG8gbVx1MDBFOXRvZG8gezB9In0sCi0KLSAgICB7IEVSX01PUkVfTUFUQ0hfRUxFTUVOVCwKLSAgICAgICAgICAgICAiSFx1MDBFMSBtYWlzIGRlIHVtYSBtZWxob3IgY29ycmVzcG9uZFx1MDBFQW5jaWEgcGFyYSBvIG1cdTAwRTl0b2RvIGRvIGVsZW1lbnRvIHswfSJ9LAotCi0gICAgeyBFUl9JTlZBTElEX0NPTlRFWFRfUEFTU0VELAotICAgICAgICAgICAgICJDb250ZXh0byBpbnZcdTAwRTFsaWRvIGVzcGVjaWZpY2FkbyBwYXJhIGF2YWxpYXIgezB9In0sCi0KLSAgICB7IEVSX1BPT0xfRVhJU1RTLAotICAgICAgICAgICAgICJPIHBvb2wgalx1MDBFMSBleGlzdGUifSwKLQotICAgIHsgRVJfTk9fRFJJVkVSX05BTUUsCi0gICAgICAgICAgICAgIk5lbmh1bSBOb21lIGRvIGRyaXZlciBlc3BlY2lmaWNhZG8ifSwKLQotICAgIHsgRVJfTk9fVVJMLAotICAgICAgICAgICAgICJOZW5odW0gVVJMIGVzcGVjaWZpY2FkbyJ9LAotCi0gICAgeyBFUl9QT09MX1NJWkVfTEVTU1RIQU5fT05FLAotICAgICAgICAgICAgICJPIHRhbWFuaG8gZG8gcG9vbCBcdTAwRTkgbWVub3IgcXVlIHVtISJ9LAotCi0gICAgeyBFUl9JTlZBTElEX0RSSVZFUiwKLSAgICAgICAgICAgICAiTm9tZSBkbyBkcml2ZXIgaW52XHUwMEUxbGlkbyBlc3BlY2lmaWNhZG8hIn0sCi0KLSAgICB7IEVSX05PX1NUWUxFU0hFRVRST09ULAotICAgICAgICAgICAgICJBIHJhaXogZGEgZm9saGEgZGUgZXN0aWxvcyBuXHUwMEUzbyBmb2kgZW5jb250cmFkYSEifSwKLQotICAgIHsgRVJfSUxMRUdBTF9YTUxTUEFDRV9WQUxVRSwKLSAgICAgICAgICJWYWxvciBpbnZcdTAwRTFsaWRvIHBhcmEgeG1sOnNwYWNlIn0sCi0KLSAgICB7IEVSX1BST0NFU1NGUk9NTk9ERV9GQUlMRUQsCi0gICAgICAgICAiRmFsaGEgZW0gcHJvY2Vzc0Zyb21Ob2RlIn0sCi0KLSAgICB7IEVSX1JFU09VUkNFX0NPVUxEX05PVF9MT0FELAotICAgICAgICAiTyByZWN1cnNvIFsgezB9IF0gblx1MDBFM28gZm9pIGNhcnJlZ2FkbzogezF9IFxuIHsyfSBcdCB7M30ifSwKLQotICAgIHsgRVJfQlVGRkVSX1NJWkVfTEVTU1RIQU5fWkVSTywKLSAgICAgICAgIlRhbWFuaG8gZG8gYnVmZmVyIDw9MCJ9LAotCi0gICAgeyBFUl9VTktOT1dOX0VSUk9SX0NBTExJTkdfRVhURU5TSU9OLAotICAgICAgICAiRXJybyBkZXNjb25oZWNpZG8gYW8gY2hhbWFyIGEgZXh0ZW5zXHUwMEUzbyJ9LAotCi0gICAgeyBFUl9OT19OQU1FU1BBQ0VfREVDTCwKLSAgICAgICAgIk8gcHJlZml4byB7MH0gblx1MDBFM28gdGVtIHVtYSBkZWNsYXJhXHUwMEU3XHUwMEUzbyBkZSBuYW1lc3BhY2UgY29ycmVzcG9uZGVudGUifSwKLQotICAgIHsgRVJfRUxFTV9DT05URU5UX05PVF9BTExPV0VELAotICAgICAgICAiQ29udGVcdTAwRkFkbyBkbyBlbGVtZW50byBuXHUwMEUzbyBwZXJtaXRpZG8gcGFyYSBsYW5nPWphdmFjbGFzcyB7MH0ifSwKLQotICAgIHsgRVJfU1RZTEVTSEVFVF9ESVJFQ1RFRF9URVJNSU5BVElPTiwKLSAgICAgICAgIlRcdTAwRTlybWlubyBkaXJlY2lvbmFkbyBkYSBmb2xoYSBkZSBlc3RpbG9zIn0sCi0KLSAgICB7IEVSX09ORV9PUl9UV08sCi0gICAgICAgICIxIG91IDIifSwKLQotICAgIHsgRVJfVFdPX09SX1RIUkVFLAotICAgICAgICAiMiBvdSAzIn0sCi0KLSAgICB7IEVSX0NPVUxEX05PVF9MT0FEX1JFU09VUkNFLAotICAgICAgICAiTlx1MDBFM28gZm9pIHBvc3NcdTAwRUR2ZWwgY2FycmVnYXIgezB9ICh2ZXJpZmljYXIgQ0xBU1NQQVRIKTsgdXNhbmRvIGFnb3JhIGFwZW5hcyBvcyBwYWRyXHUwMEY1ZXMifSwKLQotICAgIHsgRVJfQ0FOTk9UX0lOSVRfREVGQVVMVF9URU1QTEFURVMsCi0gICAgICAgICJOXHUwMEUzbyBcdTAwRTkgcG9zc1x1MDBFRHZlbCBpbmljaWFsaXphciBvcyBtb2RlbG9zIHBhZHJcdTAwRTNvIn0sCi0KLSAgICB7IEVSX1JFU1VMVF9OVUxMLAotICAgICAgICAiTyByZXN1bHRhZG8gblx1MDBFM28gZGV2ZSBzZXIgbnVsbyJ9LAotCi0gICAgeyBFUl9SRVNVTFRfQ09VTERfTk9UX0JFX1NFVCwKLSAgICAgICAgIk5cdTAwRTNvIGZvaSBwb3NzXHUwMEVEdmVsIGRlZmluaXIgbyByZXN1bHRhZG8ifSwKLQotICAgIHsgRVJfTk9fT1VUUFVUX1NQRUNJRklFRCwKLSAgICAgICAgIk5lbmh1bWEgc2FcdTAwRURkYSBlc3BlY2lmaWNhZGEifSwKLQotICAgIHsgRVJfQ0FOTk9UX1RSQU5TRk9STV9UT19SRVNVTFRfVFlQRSwKLSAgICAgICAgIk5cdTAwRTNvIFx1MDBFOSBwb3NzXHUwMEVEdmVsIHRyYW5zZm9ybWFyIHVtIFJlc3VsdGFkbyBkbyB0aXBvIHswfSJ9LAotCi0gICAgeyBFUl9DQU5OT1RfVFJBTlNGT1JNX1NPVVJDRV9UWVBFLAotICAgICAgICAiTlx1MDBFM28gXHUwMEU5IHBvc3NcdTAwRUR2ZWwgdHJhbnNmb3JtYXIgdW1hIE9yaWdlbSBkbyB0aXBvIHswfSJ9LAotCi0gICAgeyBFUl9OVUxMX0NPTlRFTlRfSEFORExFUiwKLSAgICAgICAgIkhhbmRsZXIgZGUgY29udGVcdTAwRkFkbyBudWxvIn0sCi0KLSAgICB7IEVSX05VTExfRVJST1JfSEFORExFUiwKLSAgICAgICAgIkhhbmRsZXIgZGUgZXJybyBudWxvIn0sCi0KLSAgICB7IEVSX0NBTk5PVF9DQUxMX1BBUlNFLAotICAgICAgICAibyBwYXJzaW5nIG5cdTAwRTNvIHBvZGVyXHUwMEUxIHNlciBjaGFtYWRvIHNlIG8gQ29udGVudEhhbmRsZXIgblx1MDBFM28gdGl2ZXIgc2lkbyBkZWZpbmlkbyJ9LAotCi0gICAgeyBFUl9OT19QQVJFTlRfRk9SX0ZJTFRFUiwKLSAgICAgICAgIk5lbmh1bSBwYWkgcGFyYSBvIGZpbHRybyJ9LAotCi0gICAgeyBFUl9OT19TVFlMRVNIRUVUX0lOX01FRElBLAotICAgICAgICAgIk5lbmh1bWEgZm9saGEgZGUgZXN0aWxvcyBlbmNvbnRyYWRhIGVtOiB7MH0sIG1cdTAwRURkaWE9IHsxfSJ9LAotCi0gICAgeyBFUl9OT19TVFlMRVNIRUVUX1BJLAotICAgICAgICAgIk5lbmh1bSBQSSBkZSB4bWwtc3R5bGVzaGVldCBlbmNvbnRyYWRvIGVtOiB7MH0ifSwKLQotICAgIHsgRVJfTk9UX1NVUFBPUlRFRCwKLSAgICAgICAiTlx1MDBFM28gc3Vwb3J0YWRvOiB7MH0ifSwKLQotICAgIHsgRVJfUFJPUEVSVFlfVkFMVUVfQk9PTEVBTiwKLSAgICAgICAiTyB2YWxvciBkYSBwcm9wcmllZGFkZSB7MH0gZGV2ZSBzZXIgdW1hIGluc3RcdTAwRTJuY2lhIEJvb2xpYW5hIn0sCi0KLSAgICB7IEVSX0NPVUxEX05PVF9GSU5EX0VYVEVSTl9TQ1JJUFQsCi0gICAgICAgICAiTlx1MDBFM28gZm9pIHBvc3NcdTAwRUR2ZWwgb2J0ZXIgdW0gc2NyaXB0IGV4dGVybm8gZW0gezB9In0sCi0KLSAgICB7IEVSX1JFU09VUkNFX0NPVUxEX05PVF9GSU5ELAotICAgICAgICAiTlx1MDBFM28gZm9pIHBvc3NcdTAwRUR2ZWwgZW5jb250cmFyIG8gcmVjdXJzbyBbIHswfSBdLlxuIHsxfSJ9LAotCi0gICAgeyBFUl9PVVRQVVRfUFJPUEVSVFlfTk9UX1JFQ09HTklaRUQsCi0gICAgICAgICJQcm9wcmllZGFkZSBkZSBzYVx1MDBFRGRhIG5cdTAwRTNvIHJlY29uaGVjaWRhOiB7MH0ifSwKLQotICAgIHsgRVJfRkFJTEVEX0NSRUFUSU5HX0VMRU1MSVRSU0xULAotICAgICAgICAiRmFsaGEgYW8gY3JpYXIgYSBpbnN0XHUwMEUybmNpYSBFbGVtTGl0ZXJhbFJlc3VsdCJ9LAotCi0gIC8vRWFybGllciAoSkRLIDEuNCBYQUxBTiAyLjItRDExKSBhdCBrZXkgY29kZSAnMjA0JyB0aGUga2V5IG5hbWUgd2FzIEVSX1BSSU9SSVRZX05PVF9QQVJTQUJMRQotICAvLyBJbiBsYXRlc3QgWGFsYW4gY29kZSBiYXNlIGtleSBuYW1lIGlzICBFUl9WQUxVRV9TSE9VTERfQkVfTlVNQkVSLiBUaGlzIHNob3VsZCBhbHNvIGJlIHRha2VuIGNhcmUKLSAgLy9pbiBsb2NhbGUgc3BlY2lmaWMgZmlsZXMgbGlrZSBYU0xURXJyb3JSZXNvdXJjZXNfZGUuamF2YSwgWFNMVEVycm9yUmVzb3VyY2VzX2ZyLmphdmEgZXRjLgotICAvL05PVEU6IE5vdCBvbmx5IHRoZSBrZXkgbmFtZSBidXQgbWVzc2FnZSBoYXMgYWxzbyBiZWVuIGNoYW5nZWQuCi0gICAgeyBFUl9WQUxVRV9TSE9VTERfQkVfTlVNQkVSLAotICAgICAgICAiTyB2YWxvciBwYXJhIHswfSBkZXZlIGNvbnRlciB1bSBuXHUwMEZBbWVybyBwYXNzXHUwMEVEdmVsIGRlIHBhcnNpbmcifSwKLQotICAgIHsgRVJfVkFMVUVfU0hPVUxEX0VRVUFMLAotICAgICAgICAiTyB2YWxvciBwYXJhIHswfSBkZXZlIHNlciBpZ3VhbCBhIHNpbSBvdSBuXHUwMEUzbyJ9LAotCi0gICAgeyBFUl9GQUlMRURfQ0FMTElOR19NRVRIT0QsCi0gICAgICAgICJGYWxoYSBhbyBjaGFtYXIgbyBtXHUwMEU5dG9kbyB7MH0ifSwKLQotICAgIHsgRVJfRkFJTEVEX0NSRUFUSU5HX0VMRU1UTVBMLAotICAgICAgICAiRmFsaGEgYW8gY3JpYXIgYSBpbnN0XHUwMEUybmNpYSBFbGVtVGVtcGxhdGVFbGVtZW50In0sCi0KLSAgICB7IEVSX0NIQVJTX05PVF9BTExPV0VELAotICAgICAgICAiT3MgY2FyYWN0ZXJlcyBuXHUwMEUzbyBzXHUwMEUzbyBwZXJtaXRpZG9zIG5lc3RlIHBvbnRvIGRvIGRvY3VtZW50byJ9LAotCi0gICAgeyBFUl9BVFRSX05PVF9BTExPV0VELAotICAgICAgICAiTyBhdHJpYnV0byBcInswfVwiIG5cdTAwRTNvIFx1MDBFOSBwZXJtaXRpZG8gbm8gZWxlbWVudG8gezF9ISJ9LAotCi0gICAgeyBFUl9CQURfVkFMVUUsCi0gICAgICJ7MH0gdmFsb3IgaW5jb3JyZXRvIHsxfSAifSwKLQotICAgIHsgRVJfQVRUUklCX1ZBTFVFX05PVF9GT1VORCwKLSAgICAgInZhbG9yIGRvIGF0cmlidXRvIHswfSBuXHUwMEUzbyBlbmNvbnRyYWRvICJ9LAotCi0gICAgeyBFUl9BVFRSSUJfVkFMVUVfTk9UX1JFQ09HTklaRUQsCi0gICAgICJWYWxvciBkbyBhdHJpYnV0byB7MH0gblx1MDBFM28gcmVjb25oZWNpZG8gIn0sCi0KLSAgICB7IEVSX05VTExfVVJJX05BTUVTUEFDRSwKLSAgICAgIlRlbnRhdGl2YSBkZSBnZXJhciB1bSBwcmVmaXhvIGRvIG5hbWVzcGFjZSBjb20gdW0gVVJJIG51bG8ifSwKLQotICAgIHsgRVJfTlVNQkVSX1RPT19CSUcsCi0gICAgICJUZW50YXRpdmEgZGUgZm9ybWF0YXIgdW0gblx1MDBGQW1lcm8gbWFpb3IgcXVlIG8gblx1MDBGQW1lcm8gaW50ZWlybyBMb25nbyBtYWlvciJ9LAotCi0gICAgeyBFUl9DQU5OT1RfRklORF9TQVgxX0RSSVZFUiwKLSAgICAgIk5cdTAwRTNvIFx1MDBFOSBwb3NzXHUwMEVEdmVsIGxvY2FsaXphciBhIGNsYXNzZSBkbyBkcml2ZXIgU0FYMSB7MH0ifSwKLQotICAgIHsgRVJfU0FYMV9EUklWRVJfTk9UX0xPQURFRCwKLSAgICAgIkEgY2xhc3NlIGRvIGRyaXZlciBTQVgxIHswfSBmb2kgZW5jb250cmFkYSwgbWFzIG5cdTAwRTNvIHBvZGUgc2VyIGNhcnJlZ2FkYSJ9LAotCi0gICAgeyBFUl9TQVgxX0RSSVZFUl9OT1RfSU5TVEFOVElBVEVELAotICAgICAiQSBjbGFzc2UgZG8gZHJpdmVyIFNBWDEgezB9IGZvaSBjYXJyZWdhZGEsIG1hcyBuXHUwMEUzbyBwb2RlIHNlciBpbnN0YW5jaWFkYSJ9LAotCi0gICAgeyBFUl9TQVgxX0RSSVZFUl9OT1RfSU1QTEVNRU5UX1BBUlNFUiwKLSAgICAgIkEgY2xhc3NlIGRvIGRyaXZlciBTQVgxIHswfSBuXHUwMEUzbyBpbXBsZW1lbnRhIG9yZy54bWwuc2F4LlBhcnNlciJ9LAotCi0gICAgeyBFUl9QQVJTRVJfUFJPUEVSVFlfTk9UX1NQRUNJRklFRCwKLSAgICAgIkEgcHJvcHJpZWRhZGUgZG8gc2lzdGVtYSBvcmcueG1sLnNheC5wYXJzZXIgblx1MDBFM28gZm9pIGVzcGVjaWZpY2FkYSJ9LAotCi0gICAgeyBFUl9QQVJTRVJfQVJHX0NBTk5PVF9CRV9OVUxMLAotICAgICAiTyBhcmd1bWVudG8gZGUgcGFyc2VyIG5cdTAwRTNvIHBvZGUgc2VyIG51bG8ifSwKLQotICAgIHsgRVJfRkVBVFVSRSwKLSAgICAgIlJlY3Vyc286IHswfSJ9LAotCi0gICAgeyBFUl9QUk9QRVJUWSwKLSAgICAgIlByb3ByaWVkYWRlOiB7MH0ifSwKLQotICAgIHsgRVJfTlVMTF9FTlRJVFlfUkVTT0xWRVIsCi0gICAgICJSZXNvbHZlZG9yIGRhIGVudGlkYWRlIG51bG8ifSwKLQotICAgIHsgRVJfTlVMTF9EVERfSEFORExFUiwKLSAgICAgIkhhbmRsZXIgZGUgRFREIG51bG8ifSwKLQotICAgIHsgRVJfTk9fRFJJVkVSX05BTUVfU1BFQ0lGSUVELAotICAgICAiTmVuaHVtIE5vbWUgZG8gRHJpdmVyIEVzcGVjaWZpY2FkbyEifSwKLQotICAgIHsgRVJfTk9fVVJMX1NQRUNJRklFRCwKLSAgICAgIk5lbmh1bSBVUkwgRXNwZWNpZmljYWRvISJ9LAotCi0gICAgeyBFUl9QT09MU0laRV9MRVNTX1RIQU5fT05FLAotICAgICAiTyB0YW1hbmhvIGRvIHBvb2wgXHUwMEU5IG1lbm9yIHF1ZSAxISJ9LAotCi0gICAgeyBFUl9JTlZBTElEX0RSSVZFUl9OQU1FLAotICAgICAiTm9tZSBkbyBEcml2ZXIgRXNwZWNpZmljYWRvIEludlx1MDBFMWxpZG8hIn0sCi0KLSAgICB7IEVSX0VSUk9STElTVEVORVIsCi0gICAgICJFcnJvckxpc3RlbmVyIn0sCi0KLQotLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBzaG91bGQgbm90IG5vcm1hbGx5IGJlIGRpc3BsYXllZAotLy8gICB0byB1c2Vycy4gIEl0IGRlc2NyaWJlcyBhIHNpdHVhdGlvbiBpbiB3aGljaCB0aGUgcHJvY2Vzc29yIGhhcyBkZXRlY3RlZAotLy8gICBhbiBpbnRlcm5hbCBjb25zaXN0ZW5jeSBwcm9ibGVtIGluIGl0c2VsZiwgYW5kIGl0IHByb3ZpZGVzIHRoaXMgbWVzc2FnZQotLy8gICBmb3IgdGhlIGRldmVsb3BlciB0byBoZWxwIGRpYWdub3NlIHRoZSBwcm9ibGVtLiAgVGhlIG5hbWUKLS8vICAgJ0VsZW1UZW1wbGF0ZUVsZW1lbnQnIGlzIHRoZSBuYW1lIG9mIGEgY2xhc3MsIGFuZCBzaG91bGQgbm90IGJlCi0vLyAgIHRyYW5zbGF0ZWQuCi0gICAgeyBFUl9BU1NFUlRfTk9fVEVNUExBVEVfUEFSRU5ULAotICAgICAiRXJybyBkbyBwcm9ncmFtYWRvciEgQSBleHByZXNzXHUwMEUzbyBuXHUwMEUzbyB0ZW0gRWxlbVRlbXBsYXRlRWxlbWVudCBwYWkhIn0sCi0KLQotLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBzaG91bGQgbm90IG5vcm1hbGx5IGJlIGRpc3BsYXllZAotLy8gICB0byB1c2Vycy4gIEl0IGRlc2NyaWJlcyBhIHNpdHVhdGlvbiBpbiB3aGljaCB0aGUgcHJvY2Vzc29yIGhhcyBkZXRlY3RlZAotLy8gICBhbiBpbnRlcm5hbCBjb25zaXN0ZW5jeSBwcm9ibGVtIGluIGl0c2VsZiwgYW5kIGl0IHByb3ZpZGVzIHRoaXMgbWVzc2FnZQotLy8gICBmb3IgdGhlIGRldmVsb3BlciB0byBoZWxwIGRpYWdub3NlIHRoZSBwcm9ibGVtLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0vLyAgIHByb3ZpZGVzIGZ1cnRoZXIgaW5mb3JtYXRpb24gaW4gb3JkZXIgdG8gZGlhZ25vc2UgdGhlIHByb2JsZW0uICBUaGUgbmFtZQotLy8gICAnUmVkdW5kZW50RXhwckVsaW1pbmF0b3InIGlzIHRoZSBuYW1lIG9mIGEgY2xhc3MsIGFuZCBzaG91bGQgbm90IGJlCi0vLyAgIHRyYW5zbGF0ZWQuCi0gICAgeyBFUl9BU1NFUlRfUkVEVU5ERU5UX0VYUFJfRUxJTUlOQVRPUiwKLSAgICAgIkFzc2VyXHUwMEU3XHUwMEUzbyBkbyBQcm9ncmFtYWRvciBubyBSZWR1bmRlbnRFeHByRWxpbWluYXRvcjogezB9In0sCi0KLSAgICB7IEVSX05PVF9BTExPV0VEX0lOX1BPU0lUSU9OLAotICAgICAiezB9IG5cdTAwRTNvIFx1MDBFOSBwZXJtaXRpZG8oYSkgbmVzdGEgcG9zaVx1MDBFN1x1MDBFM28gbmEgZm9saGEgZGUgZXN0aWxvcyEifSwKLQotICAgIHsgRVJfTk9OV0hJVEVTUEFDRV9OT1RfQUxMT1dFRF9JTl9QT1NJVElPTiwKLSAgICAgIlRleHRvIHNlbSBlc3BhXHUwMEU3byBlbSBicmFuY28gblx1MDBFM28gcGVybWl0aWRvIG5lc3RhIHBvc2lcdTAwRTdcdTAwRTNvIG5hIGZvbGhhIGRlIGVzdGlsb3MhIn0sCi0KLSAgLy8gVGhpcyBjb2RlIGlzIHNoYXJlZCB3aXRoIHdhcm5pbmcgY29kZXMuCi0gIC8vIFN5c3RlbUlkIFVua25vd24KLSAgICB7IElOVkFMSURfVENIQVIsCi0gICAgICJWYWxvciBpbnZcdTAwRTFsaWRvOiB7MX0gdXNhZG8gcGFyYSBvIGF0cmlidXRvIENIQVI6IHswfS4gVW0gYXRyaWJ1dG8gZG8gdGlwbyBDSEFSIGRldmUgdGVyIHNvbWVudGUgMSBjYXJhY3RlcmUhIn0sCi0KLSAgICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIGlzIHVzZWQgaWYgdGhlIHZhbHVlIG9mCi0gICAgLy8gYW4gYXR0cmlidXRlIGluIGEgc3R5bGVzaGVldCBpcyBpbnZhbGlkLiAgIlFOQU1FIiBpcyB0aGUgWE1MIGRhdGEtdHlwZSBvZgotICAgIC8vIHRoZSBhdHRyaWJ1dGUsIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgezF9IGlzCi0gICAgLy8gdGhlIGF0dHJpYnV0ZSB2YWx1ZSBhbmQgezB9IGlzIHRoZSBhdHRyaWJ1dGUgbmFtZS4KLSAgLy9UaGUgZm9sbG93aW5nIGNvZGVzIGFyZSBzaGFyZWQgd2l0aCB0aGUgd2FybmluZyBjb2Rlcy4uLgotICAgIHsgSU5WQUxJRF9RTkFNRSwKLSAgICAgIlZhbG9yIGludlx1MDBFMWxpZG86IHsxfSB1c2FkbyBwYXJhIG8gYXRyaWJ1dG8gUU5BTUU6IHswfSJ9LAotCi0gICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBpcyB1c2VkIGlmIHRoZSB2YWx1ZSBvZgotICAgIC8vIGFuIGF0dHJpYnV0ZSBpbiBhIHN0eWxlc2hlZXQgaXMgaW52YWxpZC4gICJFTlVNIiBpcyB0aGUgWE1MIGRhdGEtdHlwZSBvZgotICAgIC8vIHRoZSBhdHRyaWJ1dGUsIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgezF9IGlzCi0gICAgLy8gdGhlIGF0dHJpYnV0ZSB2YWx1ZSwgezB9IGlzIHRoZSBhdHRyaWJ1dGUgbmFtZSwgYW5kIHsyfSBpcyBhIGxpc3Qgb2YgdmFsaWQKLSAgICAvLyB2YWx1ZXMuCi0gICAgeyBJTlZBTElEX0VOVU0sCi0gICAgICJWYWxvciBpbnZcdTAwRTFsaWRvOiB7MX0gdXNhZG8gcGFyYSBvIGF0cmlidXRvIEVOVU06IHswfS4gT3MgdmFsb3JlcyB2XHUwMEUxbGlkb3Mgc1x1MDBFM286IHsyfS4ifSwKLQotLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBpcyB1c2VkIGlmIHRoZSB2YWx1ZSBvZgotLy8gYW4gYXR0cmlidXRlIGluIGEgc3R5bGVzaGVldCBpcyBpbnZhbGlkLiAgIk5NVE9LRU4iIGlzIHRoZSBYTUwgZGF0YS10eXBlCi0vLyBvZiB0aGUgYXR0cmlidXRlLCBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHsxfSBpcwotLy8gdGhlIGF0dHJpYnV0ZSB2YWx1ZSBhbmQgezB9IGlzIHRoZSBhdHRyaWJ1dGUgbmFtZS4KLSAgICB7IElOVkFMSURfTk1UT0tFTiwKLSAgICAgIlZhbG9yIGludlx1MDBFMWxpZG86IHsxfSB1c2FkbyBwYXJhIG8gYXRyaWJ1dG8gTk1UT0tFTjogezB9ICJ9LAotCi0vLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIGlzIHVzZWQgaWYgdGhlIHZhbHVlIG9mCi0vLyBhbiBhdHRyaWJ1dGUgaW4gYSBzdHlsZXNoZWV0IGlzIGludmFsaWQuICAiTkNOQU1FIiBpcyB0aGUgWE1MIGRhdGEtdHlwZQotLy8gb2YgdGhlIGF0dHJpYnV0ZSwgYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCB7MX0gaXMKLS8vIHRoZSBhdHRyaWJ1dGUgdmFsdWUgYW5kIHswfSBpcyB0aGUgYXR0cmlidXRlIG5hbWUuCi0gICAgeyBJTlZBTElEX05DTkFNRSwKLSAgICAgIlZhbG9yIGludlx1MDBFMWxpZG86IHsxfSB1c2FkbyBwYXJhIG8gYXRyaWJ1dG8gTkNOQU1FOiB7MH0gIn0sCi0KLS8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgaXMgdXNlZCBpZiB0aGUgdmFsdWUgb2YKLS8vIGFuIGF0dHJpYnV0ZSBpbiBhIHN0eWxlc2hlZXQgaXMgaW52YWxpZC4gICJib29sZWFuIiBpcyB0aGUgWFNMVCBkYXRhLXR5cGUKLS8vIG9mIHRoZSBhdHRyaWJ1dGUsIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgezF9IGlzCi0vLyB0aGUgYXR0cmlidXRlIHZhbHVlIGFuZCB7MH0gaXMgdGhlIGF0dHJpYnV0ZSBuYW1lLgotICAgIHsgSU5WQUxJRF9CT09MRUFOLAotICAgICAiVmFsb3IgaW52XHUwMEUxbGlkbzogezF9IHVzYWRvIHBhcmEgbyBhdHJpYnV0byBib29sZWFuOiB7MH0gIn0sCi0KLS8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgaXMgdXNlZCBpZiB0aGUgdmFsdWUgb2YKLS8vIGFuIGF0dHJpYnV0ZSBpbiBhIHN0eWxlc2hlZXQgaXMgaW52YWxpZC4gICJudW1iZXIiIGlzIHRoZSBYU0xUIGRhdGEtdHlwZQotLy8gb2YgdGhlIGF0dHJpYnV0ZSwgYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCB7MX0gaXMKLS8vIHRoZSBhdHRyaWJ1dGUgdmFsdWUgYW5kIHswfSBpcyB0aGUgYXR0cmlidXRlIG5hbWUuCi0gICAgIHsgSU5WQUxJRF9OVU1CRVIsCi0gICAgICJWYWxvciBpbnZcdTAwRTFsaWRvOiB7MX0gdXNhZG8gcGFyYSBvIGF0cmlidXRvIGRvIG5cdTAwRkFtZXJvOiB7MH0gIn0sCi0KLQotICAvLyBFbmQgb2Ygc2hhcmVkIGNvZGVzLi4uCi0KLS8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBICJtYXRjaCBwYXR0ZXJuIiBpcyBhIHNwZWNpYWwgZm9ybSBvZiBYUGF0aCBleHByZXNzaW9uCi0vLyB0aGF0IGlzIHVzZWQgZm9yIG1hdGNoaW5nIHBhdHRlcm5zLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mCi0vLyBhIGZ1bmN0aW9uLiAgVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgd2hlbiB0aGlzIGZ1bmN0aW9uIGlzIHJlZmVyZW5jZWQgaW4KLS8vIGEgbWF0Y2ggcGF0dGVybiwgaXRzIGFyZ3VtZW50IG11c3QgYmUgYSBzdHJpbmcgbGl0ZXJhbCAob3IgY29uc3RhbnQuKQotLy8gRVJfQVJHX0xJVEVSQUwgLSBuZXcgZXJyb3IgbWVzc2FnZSBmb3IgYnVnemlsbGEgLy81MjAyCi0gICAgeyBFUl9BUkdfTElURVJBTCwKLSAgICAgIk8gYXJndW1lbnRvIHBhcmEgezB9IG5vIHBhZHJcdTAwRTNvIGRlIGNvcnJlc3BvbmRcdTAwRUFuY2lhIGRldmUgc2VyIHVtIGxpdGVyYWwuIn0sCi0KLS8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdHdvIGRlZmluaXRpb25zIG9mCi0vLyBhIHZhcmlhYmxlLiAgQSAiZ2xvYmFsIHZhcmlhYmxlIiBpcyBhIHZhcmlhYmxlIHRoYXQgaXMgYWNjZXNzaWJsZSBldmVyeXdoZXIKLS8vIGluIHRoZSBzdHlsZXNoZWV0LgotLy8gRVJfRFVQTElDQVRFX0dMT0JBTF9WQVIgLSBuZXcgZXJyb3IgbWVzc2FnZSBmb3IgYnVnemlsbGEgIzc5MAotICAgIHsgRVJfRFVQTElDQVRFX0dMT0JBTF9WQVIsCi0gICAgICJEZWNsYXJhXHUwMEU3XHUwMEUzbyBkZSB2YXJpXHUwMEUxdmVsIGdsb2JhbCBkdXBsaWNhZGEuIn0sCi0KLQotLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0d28gZGVmaW5pdGlvbnMgb2YKLS8vIGEgdmFyaWFibGUgd2VyZSBlbmNvdW50ZXJlZC4KLS8vIEVSX0RVUExJQ0FURV9WQVIgLSBuZXcgZXJyb3IgbWVzc2FnZSBmb3IgYnVnemlsbGEgIzc5MAotICAgIHsgRVJfRFVQTElDQVRFX1ZBUiwKLSAgICAgIkRlY2xhcmFcdTAwRTdcdTAwRTNvIGRlIHZhcmlcdTAwRTF2ZWwgZHVwbGljYWRhLiJ9LAotCi0gICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogICJ4c2w6dGVtcGxhdGUsICJuYW1lIiBhbmQgIm1hdGNoIiBhcmUgWFNMVCBrZXl3b3JkcwotICAgIC8vIHdoaWNoIG11c3Qgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgLy8gRVJfVEVNUExBVEVfTkFNRV9NQVRDSCAtIG5ldyBlcnJvciBtZXNzYWdlIGZvciBidWd6aWxsYSAjNzg5Ci0gICAgeyBFUl9URU1QTEFURV9OQU1FX01BVENILAotICAgICAieHNsOnRlbXBsYXRlIGRldmUgdGVyIHVtIGF0cmlidXRvIG5hbWUgb3UgbWF0Y2ggKG91IGFtYm9zKSJ9LAotCi0gICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogICJleGNsdWRlLXJlc3VsdC1wcmVmaXhlcyIgaXMgYW4gWFNMVCBrZXl3b3JkIHdoaWNoCi0gICAgLy8gc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgYSBuYW1lc3BhY2UgcHJlZml4Ci0gICAgLy8gZW5jb3VudGVyZWQgYXMgcGFydCBvZiB0aGUgdmFsdWUgb2YgdGhlIGV4Y2x1ZGUtcmVzdWx0LXByZWZpeGVzIGF0dHJpYnV0ZQotICAgIC8vIHdhcyBpbiBlcnJvci4KLSAgICAvLyBFUl9JTlZBTElEX1BSRUZJWCAtIG5ldyBlcnJvciBtZXNzYWdlIGZvciBidWd6aWxsYSAjNzg4Ci0gICAgeyBFUl9JTlZBTElEX1BSRUZJWCwKLSAgICAgIk8gcHJlZml4byBlbSBleGNsdWRlLXJlc3VsdC1wcmVmaXhlcyBuXHUwMEUzbyBcdTAwRTkgdlx1MDBFMWxpZG86IHswfSJ9LAotCi0gICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIEFuICJhdHRyaWJ1dGUgc2V0IiBpcyBhIHNldCBvZiBhdHRyaWJ1dGVzIHRoYXQgY2FuCi0gICAgLy8gYmUgYWRkZWQgdG8gYW4gZWxlbWVudCBpbiB0aGUgb3V0cHV0IGRvY3VtZW50IGFzIGEgZ3JvdXAuICBUaGUgbWVzc2FnZQotICAgIC8vIGluZGljYXRlcyB0aGF0IHRoZXJlIHdhcyBhIHJlZmVyZW5jZSB0byBhbiBhdHRyaWJ1dGUgc2V0IG5hbWVkIHswfSB0aGF0Ci0gICAgLy8gd2FzIG5ldmVyIGRlZmluZWQuCi0gICAgLy8gRVJfTk9fQVRUUklCX1NFVCAtIG5ldyBlcnJvciBtZXNzYWdlIGZvciBidWd6aWxsYSAjNzgyCi0gICAgeyBFUl9OT19BVFRSSUJfU0VULAotICAgICAibyBjb25qdW50byBkZSBhdHJpYnV0b3MgY29tIG8gbm9tZSB7MH0gblx1MDBFM28gZXhpc3RlIn0sCi0KLSAgICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoZXJlIHdhcyBhIHJlZmVyZW5jZQotICAgIC8vIHRvIGEgZnVuY3Rpb24gbmFtZWQgezB9IGZvciB3aGljaCBubyBmdW5jdGlvbiBkZWZpbml0aW9uIGNvdWxkIGJlIGZvdW5kLgotICAgIHsgRVJfRlVOQ1RJT05fTk9UX0ZPVU5ELAotICAgICAiQSBmdW5cdTAwRTdcdTAwRTNvIGNvbSBvIG5vbWUgezB9IG5cdTAwRTNvIGV4aXN0ZSJ9LAotCi0gICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUgWFNMVCBpbnN0cnVjdGlvbgotICAgIC8vIHRoYXQgaXMgbmFtZWQgYnkgdGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHswfSBtdXN0IG5vdCBjb250YWluIG90aGVyIFhTTFQKLSAgICAvLyBpbnN0cnVjdGlvbnMgKGNvbnRlbnQpIG9yIGEgInNlbGVjdCIgYXR0cmlidXRlLiAgVGhlIHdvcmQgInNlbGVjdCIgaXMKLSAgICAvLyBhbiBYU0xUIGtleXdvcmQgaW4gdGhpcyBjYXNlIGFuZCBtdXN0IG5vdCBiZSB0cmFuc2xhdGVkLgotICAgIHsgRVJfQ0FOVF9IQVZFX0NPTlRFTlRfQU5EX1NFTEVDVCwKLSAgICAgIk8gZWxlbWVudG8gezB9IG5cdTAwRTNvIGRldmUgdGVyIHVtIGNvbnRlXHUwMEZBZG8gZSB1bSBhdHJpYnV0byBzZWxlY3QuIn0sCi0KLSAgICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoZSB2YWx1ZSBhcmd1bWVudAotICAgIC8vIG9mIHNldFBhcmFtZXRlciBtdXN0IGJlIGEgdmFsaWQgSmF2YSBPYmplY3QuCi0gICAgeyBFUl9JTlZBTElEX1NFVF9QQVJBTV9WQUxVRSwKLSAgICAgIk8gdmFsb3IgZG8gcGFyXHUwMEUybWV0cm8gezB9IGRldmUgc2VyIHVtIE9iamV0byBKYXZhIHZcdTAwRTFsaWRvIn0sCi0KLSAgICB7IEVSX0lOVkFMSURfTkFNRVNQQUNFX1VSSV9WQUxVRV9GT1JfUkVTVUxUX1BSRUZJWF9GT1JfREVGQVVMVCwKLSAgICAgICJPIGF0cmlidXRvIHJlc3VsdC1wcmVmaXggZGUgdW0gZWxlbWVudG8geHNsOm5hbWVzcGFjZS1hbGlhcyB0ZW0gbyB2YWxvciAnI3BhZHJcdTAwRTNvJywgbWFzIG5cdTAwRTNvIGhcdTAwRTEgZGVjbGFyYVx1MDBFN1x1MDBFM28gZG8gbmFtZXNwYWNlIHBhZHJcdTAwRTNvIG5vIGVzY29wbyBkbyBlbGVtZW50byJ9LAotCi0gICAgeyBFUl9JTlZBTElEX05BTUVTUEFDRV9VUklfVkFMVUVfRk9SX1JFU1VMVF9QUkVGSVgsCi0gICAgICAiTyBhdHJpYnV0byByZXN1bHQtcHJlZml4IGRlIHVtIGVsZW1lbnRvIHhzbDpuYW1lc3BhY2UtYWxpYXMgdGVtIG8gdmFsb3IgJyd7MH0nJywgbWFzIG5cdTAwRTNvIGhcdTAwRTEgZGVjbGFyYVx1MDBFN1x1MDBFM28gZGUgbmFtZXNwYWNlIHBhcmEgbyBwcmVmaXhvICcnezB9Jycgbm8gZXNjb3BvIGRvIGVsZW1lbnRvLiJ9LAotCi0gICAgeyBFUl9TRVRfRkVBVFVSRV9OVUxMX05BTUUsCi0gICAgICAiTyBub21lIGRvIHJlY3Vyc28gblx1MDBFM28gcG9kZSBzZXIgbnVsbyBlbSBUcmFuc2Zvcm1lckZhY3Rvcnkuc2V0RmVhdHVyZShOb21lIGRhIHN0cmluZywgdmFsb3IgYm9vbGlhbm8pLiJ9LAotCi0gICAgeyBFUl9HRVRfRkVBVFVSRV9OVUxMX05BTUUsCi0gICAgICAiTyBub21lIGRvIHJlY3Vyc28gblx1MDBFM28gcG9kZSBzZXIgbnVsbyBlbSBUcmFuc2Zvcm1lckZhY3RvcnkuZ2V0RmVhdHVyZShOb21lIGRhIHN0cmluZykuIn0sCi0KLSAgICB7IEVSX1VOU1VQUE9SVEVEX0ZFQVRVUkUsCi0gICAgICAiTlx1MDBFM28gXHUwMEU5IHBvc3NcdTAwRUR2ZWwgZGVmaW5pciBvIHJlY3Vyc28gJyd7MH0nJyBuZXN0YSBUcmFuc2Zvcm1lckZhY3RvcnkuIn0sCi0KLSAgICB7IEVSX0VYVEVOU0lPTl9FTEVNRU5UX05PVF9BTExPV0VEX0lOX1NFQ1VSRV9QUk9DRVNTSU5HLAotICAgICAgICAgICJPIHVzbyBkbyBlbGVtZW50byBkYSBleHRlbnNcdTAwRTNvICcnezB9Jycgblx1MDBFM28gc2VyXHUwMEUxIHBlcm1pdGlkbyBxdWFuZG8gbyByZWN1cnNvIGRlIHByb2Nlc3NhbWVudG8gc2VndXJvIGZvciBkZWZpbmlkbyBjb21vIHZlcmRhZGVpcm8uIn0sCi0KLSAgICB7IEVSX05BTUVTUEFDRV9DT05URVhUX05VTExfTkFNRVNQQUNFLAotICAgICAgIk5cdTAwRTNvIFx1MDBFOSBwb3NzXHUwMEVEdmVsIG9idGVyIG8gcHJlZml4byBkZSB1bSB1cmkgZGUgbmFtZXNwYWNlIG51bG8uIn0sCi0KLSAgICB7IEVSX05BTUVTUEFDRV9DT05URVhUX05VTExfUFJFRklYLAotICAgICAgIk5cdTAwRTNvIFx1MDBFOSBwb3NzXHUwMEVEdmVsIG9idGVyIG8gdXJpIGRvIG5hbWVzcGFjZSBkbyBwcmVmaXhvIG51bG8uIn0sCi0KLSAgICB7IEVSX1hQQVRIX1JFU09MVkVSX05VTExfUU5BTUUsCi0gICAgICAiTyBub21lIGRhIGZ1blx1MDBFN1x1MDBFM28gblx1MDBFM28gcG9kZSBzZXIgbnVsby4ifSwKLQotICAgIHsgRVJfWFBBVEhfUkVTT0xWRVJfTkVHQVRJVkVfQVJJVFksCi0gICAgICAiQSBhcmlkYWRlIG5cdTAwRTNvIHBvZGUgc2VyIG5lZ2F0aXZhLiJ9LAotICAvLyBXYXJuaW5ncy4uLgotCi0gICAgeyBXR19GT1VORF9DVVJMWUJSQUNFLAotICAgICAgIkVuY29udHJvdSAnfScsIG1hcyBuZW5odW0gbW9kZWxvIGRvIGF0cmlidXRvIGVzdGF2YSBhYmVydG8hIn0sCi0KLSAgICB7IFdHX0NPVU5UX0FUVFJJQl9NQVRDSEVTX05PX0FOQ0VTVE9SLAotICAgICAgIkFkdmVydFx1MDBFQW5jaWE6IG8gYXRyaWJ1dG8gZGUgY29udGFnZW0gblx1MDBFM28gY29ycmVzcG9uZGUgYSB1bSBhbmNlc3RyYWwgbm8geHNsOm51bWJlciEgQWx2byA9IHswfSJ9LAotCi0gICAgeyBXR19FWFBSX0FUVFJJQl9DSEFOR0VEX1RPX1NFTEVDVCwKLSAgICAgICJTaW50YXhlIGFudGlnYTogTyBub21lIGRvIGF0cmlidXRvICdleHByJyBmb2kgYWx0ZXJhZG8gcGFyYSAnc2VsZWN0Jy4ifSwKLQotICAgIHsgV0dfTk9fTE9DQUxFX0lOX0ZPUk1BVE5VTUJFUiwKLSAgICAgICJPIFhhbGFuIGFpbmRhIG5cdTAwRTNvIHRyYXRhIG8gbm9tZSBkYXMgY29uZmlndXJhXHUwMEU3XHUwMEY1ZXMgcmVnaW9uYWlzIG5hIGZ1blx1MDBFN1x1MDBFM28gZm9ybWF0LW51bWJlci4ifSwKLQotICAgIHsgV0dfTE9DQUxFX05PVF9GT1VORCwKLSAgICAgICJBZHZlcnRcdTAwRUFuY2lhOiBOXHUwMEUzbyBmb2kgcG9zc1x1MDBFRHZlbCBlbmNvbnRyYXIgbyBub21lIGRhcyBjb25maWd1cmFcdTAwRTdcdTAwRjVlcyByZWdpb25haXMgZGUgeG1sOmxhbmc9ezB9In0sCi0KLSAgICB7IFdHX0NBTk5PVF9NQUtFX1VSTF9GUk9NLAotICAgICAgIk5cdTAwRTNvIFx1MDBFOSBwb3NzXHUwMEVEdmVsIGNyaWFyIG8gVVJMIGRlOiB7MH0ifSwKLQotICAgIHsgV0dfQ0FOTk9UX0xPQURfUkVRVUVTVEVEX0RPQywKLSAgICAgICJOXHUwMEUzbyBcdTAwRTkgcG9zc1x1MDBFRHZlbCBjYXJyZWdhciBvIGRvYyBzb2xpY2l0YWRvOiB7MH0ifSwKLQotICAgIHsgV0dfQ0FOTk9UX0ZJTkRfQ09MTEFUT1IsCi0gICAgICAiTlx1MDBFM28gZm9pIHBvc3NcdTAwRUR2ZWwgbG9jYWxpemFyIG8gQWdydXBhZG9yIHBhcmEgPHNvcnQgeG1sOmxhbmc9ezB9In0sCi0KLSAgICB7IFdHX0ZVTkNUSU9OU19TSE9VTERfVVNFX1VSTCwKLSAgICAgICJTaW50YXhlIGFudGlnYTogYSBpbnN0cnVcdTAwRTdcdTAwRTNvIGRhcyBmdW5cdTAwRTdcdTAwRjVlcyBkZXZlIHVzYXIgdW0gdXJsIGRlIHswfSJ9LAotCi0gICAgeyBXR19FTkNPRElOR19OT1RfU1VQUE9SVEVEX1VTSU5HX1VURjgsCi0gICAgICAiY29kaWZpY2FcdTAwRTdcdTAwRTNvIG5cdTAwRTNvIHN1cG9ydGFkYTogezB9LCB1c2FuZG8gVVRGLTgifSwKLQotICAgIHsgV0dfRU5DT0RJTkdfTk9UX1NVUFBPUlRFRF9VU0lOR19KQVZBLAotICAgICAgImNvZGlmaWNhXHUwMEU3XHUwMEUzbyBuXHUwMEUzbyBzdXBvcnRhZGE6IHswfSwgdXNhbmRvIEphdmEgezF9In0sCi0KLSAgICB7IFdHX1NQRUNJRklDSVRZX0NPTkZMSUNUUywKLSAgICAgICJDb25mbGl0b3MgZGUgZXNwZWNpZmljaWRhZGUgZW5jb250cmFkb3M6IHswfSBTZXJcdTAwRTEgdXNhZG8gbyBcdTAwRkFsdGltbyBlbmNvbnRyYWRvIG5hIGZvbGhhIGRlIGVzdGlsb3MuIn0sCi0KLSAgICB7IFdHX1BBUlNJTkdfQU5EX1BSRVBBUklORywKLSAgICAgICI9PT09PT09PT0gRmF6ZW5kbyBwYXJzaW5nIGUgcHJlcGFyYW5kbyB7MH0gPT09PT09PT09PSJ9LAotCi0gICAgeyBXR19BVFRSX1RFTVBMQVRFLAotICAgICAiTW9kZWxvIGRvIEF0cmlidXRvLCB7MH0ifSwKLQotICAgIHsgV0dfQ09ORkxJQ1RfQkVUV0VFTl9YU0xTVFJJUFNQQUNFX0FORF9YU0xQUkVTRVJWRVNQQUNFLAotICAgICAgIkNvbmZsaXRvIGNvcnJlc3BvbmRlbnRlIGVudHJlIHhzbDpzdHJpcC1zcGFjZSBlIHhzbDpwcmVzZXJ2ZS1zcGFjZSJ9LAotCi0gICAgeyBXR19BVFRSSUJfTk9UX0hBTkRMRUQsCi0gICAgICAiTyBYYWxhbiBhaW5kYSBuXHUwMEUzbyB0cmF0YSBvIGF0cmlidXRvIHswfSEifSwKLQotICAgIHsgV0dfTk9fREVDSU1BTEZPUk1BVF9ERUNMQVJBVElPTiwKLSAgICAgICJOZW5odW1hIGRlY2xhcmFcdTAwRTdcdTAwRTNvIGVuY29udHJhZGEgcGFyYSBvIGZvcm1hdG8gZGVjaW1hbDogezB9In0sCi0KLSAgICB7IFdHX09MRF9YU0xUX05TLAotICAgICAiTmFtZXNwYWNlIGRlIFhTTFQgblx1MDBFM28gZW5jb250cmFkbyBvdSBpbmNvcnJldG8uICJ9LAotCi0gICAgeyBXR19PTkVfREVGQVVMVF9YU0xERUNJTUFMRk9STUFUX0FMTE9XRUQsCi0gICAgICAiXHUwMEM5IHBlcm1pdGlkYSBzb21lbnRlIHVtYSBkZWNsYXJhXHUwMEU3XHUwMEUzbyBkZSB4c2w6ZGVjaW1hbC1mb3JtYXQgcGFkclx1MDBFM28uIn0sCi0KLSAgICB7IFdHX1hTTERFQ0lNQUxGT1JNQVRfTkFNRVNfTVVTVF9CRV9VTklRVUUsCi0gICAgICAib3Mgbm9tZXMgZGUgeHNsOmRlY2ltYWwtZm9ybWF0IGRldmVtIHNlciBleGNsdXNpdm9zLiBPIG5vbWUgXCJ7MH1cIiBmb2kgZHVwbGljYWRvLiJ9LAotCi0gICAgeyBXR19JTExFR0FMX0FUVFJJQlVURSwKLSAgICAgICJ7MH0gdGVtIHVtIGF0cmlidXRvIGludlx1MDBFMWxpZG86IHsxfSJ9LAotCi0gICAgeyBXR19DT1VMRF9OT1RfUkVTT0xWRV9QUkVGSVgsCi0gICAgICAiTlx1MDBFM28gZm9pIHBvc3NcdTAwRUR2ZWwgcmVzb2x2ZXIgbyBwcmVmaXhvIGRvIG5hbWVzcGFjZTogezB9LiBPIG5cdTAwRjMgc2VyXHUwMEUxIGlnbm9yYWRvLiJ9LAotCi0gICAgeyBXR19TVFlMRVNIRUVUX1JFUVVJUkVTX1ZFUlNJT05fQVRUUklCLAotICAgICAgInhzbDpzdHlsZXNoZWV0IHJlcXVlciB1bSBhdHJpYnV0byAndmVyc2lvbichIn0sCi0KLSAgICB7IFdHX0lMTEVHQUxfQVRUUklCVVRFX05BTUUsCi0gICAgICAiTm9tZSBkbyBhdHJpYnV0byBpbnZcdTAwRTFsaWRvOiB7MH0ifSwKLQotICAgIHsgV0dfSUxMRUdBTF9BVFRSSUJVVEVfVkFMVUUsCi0gICAgICAiVmFsb3IgaW52XHUwMEUxbGlkbyB1c2FkbyBwYXJhIG8gYXRyaWJ1dG8gezB9OiB7MX0ifSwKLQotICAgIHsgV0dfRU1QVFlfU0VDT05EX0FSRywKLSAgICAgICJPIGNvbmp1bnRvIGRlIG5cdTAwRjNzIHJlc3VsdGFudGUgZG8gc2VndW5kbyBhcmd1bWVudG8gZGEgZnVuXHUwMEU3XHUwMEUzbyBkbyBkb2N1bWVudG8gZXN0XHUwMEUxIHZhemlvLiBSZXRvcm5lIHVtIGNvbmp1bnRvIGRlIG5cdTAwRjNzIHZhemlvLiJ9LAotCi0gIC8vRm9sbG93aW5nIGFyZSB0aGUgbmV3IFdBUk5JTkcga2V5cyBhZGRlZCBpbiBYQUxBTiBjb2RlIGJhc2UgYWZ0ZXIgSmRrIDEuNCAoWGFsYW4gMi4yLUQxMSkKLQotICAgIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAibmFtZSIgYW5kICJ4c2w6cHJvY2Vzc2luZy1pbnN0cnVjdGlvbiIgYXJlIGtleXdvcmRzCi0gICAgLy8gYW5kIG11c3Qgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgeyBXR19QUk9DRVNTSU5HSU5TVFJVQ1RJT05fTkFNRV9DQU5UX0JFX1hNTCwKLSAgICAgICJPIHZhbG9yIGRvIGF0cmlidXRvICduYW1lJyBkbyBub21lIGRlIHhzbDpwcm9jZXNzaW5nLWluc3RydWN0aW9uIG5cdTAwRTNvIGRldmUgc2VyICd4bWwnIn0sCi0KLSAgICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIm5hbWUiIGFuZCAieHNsOnByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24iIGFyZSBrZXl3b3JkcwotICAgIC8vIGFuZCBtdXN0IG5vdCBiZSB0cmFuc2xhdGVkLiAgIk5DTmFtZSIgaXMgYW4gWE1MIGRhdGEtdHlwZSBhbmQgbXVzdCBub3QgYmUKLSAgICAvLyB0cmFuc2xhdGVkLgotICAgIHsgV0dfUFJPQ0VTU0lOR0lOU1RSVUNUSU9OX05PVFZBTElEX05DTkFNRSwKLSAgICAgICJPIHZhbG9yIGRvIGF0cmlidXRvICcnbmFtZScnIGRlIHhzbDpwcm9jZXNzaW5nLWluc3RydWN0aW9uIGRldmUgc2VyIHVtIE5DTmFtZSB2XHUwMEUxbGlkbzogezB9In0sCi0KLSAgICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIHJlcG9ydGVkIGlmIHRoZSBzdHlsZXNoZWV0IHRoYXQgaXMKLSAgICAvLyBiZWluZyBwcm9jZXNzZWQgYXR0ZW1wdGVkIHRvIGNvbnN0cnVjdCBhbiBYTUwgZG9jdW1lbnQgd2l0aCBhbiBhdHRyaWJ1dGUgaW4gYQotICAgIC8vIHBsYWNlIG90aGVyIHRoYW4gb24gYW4gZWxlbWVudC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBzcGVjaWZpZXMgdGhlIG5hbWUgb2YKLSAgICAvLyB0aGUgYXR0cmlidXRlLgotICAgIHsgV0dfSUxMRUdBTF9BVFRSSUJVVEVfUE9TSVRJT04sCi0gICAgICAiTlx1MDBFM28gXHUwMEU5IHBvc3NcdTAwRUR2ZWwgYWRpY2lvbmFyIG8gYXRyaWJ1dG8gezB9IGRlcG9pcyBkb3Mgblx1MDBGM3MgZmlsaG9zIG91IGFudGVzIHF1ZSB1bSBlbGVtZW50byBzZWphIHByb2R1emlkby4gTyBhdHJpYnV0byBzZXJcdTAwRTEgaWdub3JhZG8uIn0sCi0KLSAgICB7IE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiwKLSAgICAgICJGb2kgZmVpdGEgdW1hIHRlbnRhdGl2YSBkZSBtb2RpZmljYXIgdW0gb2JqZXRvIG5vIHF1YWwgblx1MDBFM28gc1x1MDBFM28gcGVybWl0aWRhcyBtb2RpZmljYVx1MDBFN1x1MDBGNWVzLiIKLSAgICB9LAotCi0gICAgLy9DaGVjazogV0hZIFRIRVJFIElTIEEgR0FQIEIvVyBOVU1CRVJTIGluIHRoZSBYU0xURXJyb3JSZXNvdXJjZXMgcHJvcGVydGllcyBmaWxlPwotCi0gIC8vIE90aGVyIG1pc2NlbGxhbmVvdXMgdGV4dCB1c2VkIGluc2lkZSB0aGUgY29kZS4uLgotICB7ICJ1aV9sYW5ndWFnZSIsICJwdC1CUiJ9LAotICB7ICAiaGVscF9sYW5ndWFnZSIsICAicHQtQlIiIH0sCi0gIHsgICJsYW5ndWFnZSIsICAicHQtQlIiIH0sCi0gIHsgIkJBRF9DT0RFIiwgIk8gcGFyXHUwMEUybWV0cm8gcGFyYSBjcmVhdGVNZXNzYWdlIGVzdGF2YSBmb3JhIGRvcyBsaW1pdGVzIn0sCi0gIHsgICJGT1JNQVRfRkFJTEVEIiwgIkV4Y2VcdTAwRTdcdTAwRTNvIGdlcmFkYSBkdXJhbnRlIGEgY2hhbWFkYSBtZXNzYWdlRm9ybWF0In0sCi0gIHsgICJ2ZXJzaW9uIiwgIj4+Pj4+Pj4gVmVyc1x1MDBFM28gZG8gWGFsYW4gIn0sCi0gIHsgICJ2ZXJzaW9uMiIsICAiPDw8PDw8PCJ9LAotICB7ICAieWVzIiwgInNpbSJ9LAotICB7ICJsaW5lIiwgIk5cdTAwQjAgZGEgTGluaGEifSwKLSAgeyAiY29sdW1uIiwiTlx1MDBCMCBkYSBDb2x1bmEifSwKLSAgeyAieHNsZG9uZSIsICJYU0xQcm9jZXNzb3I6IGNvbmNsdVx1MDBFRGRvIn0sCi0KLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlcyBwcm92aWRlIHVzYWdlIGluZm9ybWF0aW9uCi0gIC8vIGZvciB0aGUgWGFsYW4gUHJvY2VzcyBjb21tYW5kIGxpbmUuICAiUHJvY2VzcyIgaXMgdGhlIG5hbWUgb2YgYSBKYXZhIGNsYXNzLAotICAvLyBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLgotICB7ICJ4c2xQcm9jX29wdGlvbiIsICJPcFx1MDBFN1x1MDBGNWVzIGRhIGNsYXNzZSBQcm9jZXNzIGRhIGxpbmhhIGRlIGNvbWFuZG9zIGRvIFhhbGFuLUo6In0sCi0gIHsgInhzbFByb2Nfb3B0aW9uIiwgIk9wXHUwMEU3XHUwMEY1ZXMgZGEgY2xhc3NlIFByb2Nlc3MgZGEgbGluaGEgZGUgY29tYW5kb3MgZG8gWGFsYW4tSjoifSwKLSAgeyAieHNsUHJvY19pbnZhbGlkX3hzbHRjX29wdGlvbiIsICJBIG9wXHUwMEU3XHUwMEUzbyB7MH0gblx1MDBFM28gXHUwMEU5IHN1cG9ydGFkYSBubyBtb2RvIFhTTFRDLiJ9LAotICB7ICJ4c2xQcm9jX2ludmFsaWRfeGFsYW5fb3B0aW9uIiwgIkEgb3BcdTAwRTdcdTAwRTNvIHswfSBzXHUwMEYzIHBvZGUgc2VyIHVzYWRhIGNvbSAtWFNMVEMuIn0sCi0gIHsgInhzbFByb2Nfbm9faW5wdXQiLCAiRXJybzogTlx1MDBFM28gZm9pIGVzcGVjaWZpY2FkYSB1bWEgZm9saGEgZGUgZXN0aWxvcyBvdSB1bSB4bWwgZGUgZW50cmFkYSAuIEV4ZWN1dGUgZXN0ZSBjb21hbmRvIHNlbSBuZW5odW1hIG9wXHUwMEU3XHUwMEUzbyBwYXJhIGluc3RydVx1MDBFN1x1MDBGNWVzIGRlIHVzby4ifSwKLSAgeyAieHNsUHJvY19jb21tb25fb3B0aW9ucyIsICItT3BcdTAwRTdcdTAwRjVlcyBDb211bnMtIn0sCi0gIHsgInhzbFByb2NfeGFsYW5fb3B0aW9ucyIsICItT3BcdTAwRTdcdTAwRjVlcyBwYXJhIFhhbGFuLSJ9LAotICB7ICJ4c2xQcm9jX3hzbHRjX29wdGlvbnMiLCAiLU9wXHUwMEU3XHUwMEY1ZXMgcGFyYSBYU0xUQy0ifSwKLSAgeyAieHNsUHJvY19yZXR1cm5fdG9fY29udGludWUiLCAiKHByZXNzaW9uZSA8cmV0dXJuPiBwYXJhIGNvbnRpbnVhcikifSwKLQotICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogVGhlIG9wdGlvbiBuYW1lIGFuZCB0aGUgcGFyYW1ldGVyIG5hbWUgZG8gbm90IG5lZWQgdG8KLSAgIC8vIGJlIHRyYW5zbGF0ZWQuIE9ubHkgdHJhbnNsYXRlIHRoZSBtZXNzYWdlcyBpbiBwYXJlbnRoZXNlcy4gIE5vdGUgYWxzbyB0aGF0Ci0gICAvLyBsZWFkaW5nIHdoaXRlc3BhY2UgaW4gdGhlIG1lc3NhZ2VzIGlzIHVzZWQgdG8gaW5kZW50IHRoZSB1c2FnZSBpbmZvcm1hdGlvbgotICAgLy8gZm9yIGVhY2ggb3B0aW9uIGluIHRoZSBFbmdsaXNoIG1lc3NhZ2VzLgotICAgLy8gRG8gbm90IHRyYW5zbGF0ZSB0aGUga2V5d29yZHM6IFhTTFRDLCBTQVgsIERPTSBhbmQgRFRNLgotICB7ICJvcHRpb25YU0xUQyIsICIgICBbLVhTTFRDICh1c2UgWFNMVEMgcGFyYSB0cmFuc2Zvcm1hXHUwMEU3XHUwMEUzbyldIn0sCi0gIHsgIm9wdGlvbklOIiwgIiAgIFstSU4gaW5wdXRYTUxVUkxdIn0sCi0gIHsgIm9wdGlvblhTTCIsICIgICBbLVhTTCBYU0xUcmFuc2Zvcm1hdGlvblVSTF0ifSwKLSAgeyAib3B0aW9uT1VUIiwgICIgICBbLU9VVCBvdXRwdXRGaWxlTmFtZV0ifSwKLSAgeyAib3B0aW9uTFhDSU4iLCAiICAgWy1MWENJTiBjb21waWxlZFN0eWxlc2hlZXRGaWxlTmFtZUluXSJ9LAotICB7ICJvcHRpb25MWENPVVQiLCAiICAgWy1MWENPVVQgY29tcGlsZWRTdHlsZXNoZWV0RmlsZU5hbWVPdXRPdXRdIn0sCi0gIHsgIm9wdGlvblBBUlNFUiIsICIgICBbLVBBUlNFUiBub21lIGRhIGNsYXNzZSB0b3RhbG1lbnRlIHF1YWxpZmljYWRvIGRlIGxpYWlzb24gZGUgcGFyc2VyXSJ9LAotICB7ICAib3B0aW9uRSIsICIgICBbLUUgKE5cdTAwRTNvIGV4cGFuZGlyIHJlZmVyXHUwMEVBbmNpYXMgZGEgZW50aWRhZGUpXSJ9LAotICB7ICAib3B0aW9uViIsICAiICAgWy1FIChOXHUwMEUzbyBleHBhbmRpciByZWZlclx1MDBFQW5jaWFzIGRhIGVudGlkYWRlKV0ifSwKLSAgeyAgIm9wdGlvblFDIiwgIiAgIFstUUMgKEFkdmVydFx1MDBFQW5jaWFzIGRlIENvbmZsaXRvcyBkbyBQYWRyXHUwMEUzbyBTaWxlbmNpb3NvKV0ifSwKLSAgeyAgIm9wdGlvblEiLCAiICAgWy1RICAoTW9kbyBTaWxlbmNpb3NvKV0ifSwKLSAgeyAgIm9wdGlvbkxGIiwgIiAgIFstTEYgKFVzYXIgYWxpbWVudGFcdTAwRTdcdTAwRjVlcyBkZSBsaW5oYSBzb21lbnRlIG5hIHNhXHUwMEVEZGEge28gcGFkclx1MDBFM28gXHUwMEU5IENSL0xGfSldIn0sCi0gIHsgICJvcHRpb25DUiIsICIgICBbLUNSIChVc2UgcmV0b3Jub3MgZGUgY2Fycm8gc29tZW50ZSBuYSBzYVx1MDBFRGRhIHtvIHBhZHJcdTAwRTNvIFx1MDBFOSBDUi9MRn0pXSJ9LAotICB7ICJvcHRpb25FU0NBUEUiLCAiICAgWy1FU0NBUEUgKFF1YWlzIGNhcmFjdGVyZXMgZGV2ZW0gc2VyIGlkZW50aWZpY2Fkb3MgY29tbyBlc2NhcGUge28gcGFkclx1MDBFM28gXHUwMEU5IDw+JlwiJ1xcclxcbn1dIn0sCi0gIHsgIm9wdGlvbklOREVOVCIsICIgICBbLUlOREVOVCAoQ29udHJvbGEgcXVhbnRvcyBlc3BhXHUwMEU3b3MgZGV2ZW0gc2VyIHJlY3VhZG9zIHtvIHBhZHJcdTAwRTNvIFx1MDBFOSAwfSldIn0sCi0gIHsgIm9wdGlvblRUIiwgIiAgIFstVFQgKFJhc3RyZWlhIG9zIG1vZGVsb3MgXHUwMEUwIG1lZGlkYSBxdWUgc1x1MDBFM28gY2hhbWFkb3MuKV0ifSwKLSAgeyAib3B0aW9uVEciLCAiICAgWy1URyAoUmFzdHJlaWEgY2FkYSBldmVudG8gZGUgZ2VyYVx1MDBFN1x1MDBFM28uKV0ifSwKLSAgeyAib3B0aW9uVFMiLCAiICAgWy1UUyAoUmFzdHJlaWEgY2FkYSBldmVudG8gZGUgc2VsZVx1MDBFN1x1MDBFM28uKV0ifSwKLSAgeyAgIm9wdGlvblRUQyIsICIgICBbLVRUQyAoUmFzdHJlaWEgb3MgZmlsaG9zIGRvIG1vZGVsbyBcdTAwRTAgbWVkaWRhIHF1ZSBzXHUwMEUzbyBwcm9jZXNzYWRvcy4pXSJ9LAotICB7ICJvcHRpb25UQ0xBU1MiLCAiICAgWy1UQ0xBU1MgKENsYXNzZSBUcmFjZUxpc3RlbmVyIHBhcmEgZXh0ZW5zXHUwMEY1ZXMgZGUgcmFzdHJlYW1lbnRvLildIn0sCi0gIHsgIm9wdGlvblZBTElEQVRFIiwgIiAgIFstVkFMSURBVEUgKERlZmluZSBzZSBvY29ycmUgdmFsaWRhXHUwMEU3XHUwMEUzby4gUG9yIHBhZHJcdTAwRTNvLCBhIHZhbGlkYVx1MDBFN1x1MDBFM28gZmljYSBkZXNhdGl2YWRhLildIn0sCi0gIHsgIm9wdGlvbkVEVU1QIiwgIiAgIFstRURVTVAge25vbWUgZG8gYXJxdWl2byBvcGNpb25hbH0gKEV4ZWN1dGUgdW0gZHVtcCBkZSBwaWxoYSBlbSBjYXNvIGRlIGVycm8uKV0ifSwKLSAgeyAgIm9wdGlvblhNTCIsICIgICBbLVhNTCAoVXNlIG8gZm9ybWF0YWRvciBYTUwgZSBhZGljaW9uZSBvIGNhYmVcdTAwRTdhbGhvIFhNTC4pXSJ9LAotICB7ICAib3B0aW9uVEVYVCIsICIgICBbLVRFWFQgKFVzZSBvIGZvcm1hdGFkb3IgZGUgVGV4dG8gc2ltcGxlcy4pXSJ9LAotICB7ICAib3B0aW9uSFRNTCIsICIgICBbLUhUTUwgKFVzZSBvIGZvcm1hdGFkb3IgSFRNTC4pXSJ9LAotICB7ICAib3B0aW9uUEFSQU0iLCAiICAgWy1QQVJBTSBleHByZXNzXHUwMEUzbyBkbyBub21lIChEZWZpbmEgdW0gcGFyXHUwMEUybWV0cm8gZGEgZm9saGEgZGUgZXN0aWxvcyldIn0sCi0gIHsgICJub1BhcnNlcm1zZzEiLCAiUHJvY2Vzc28gWFNMIG1hbHN1Y2VkaWRvLiJ9LAotICB7ICAibm9QYXJzZXJtc2cyIiwgIioqIE5cdTAwRTNvIGZvaSBwb3NzXHUwMEVEdmVsIGxvY2FsaXphciBvIHBhcnNlciAqKiJ9LAotICB7ICJub1BhcnNlcm1zZzMiLCAgIlZlcmlmaXF1ZSBzZXUgY2xhc3NwYXRoLiJ9LAotICB7ICJub1BhcnNlcm1zZzQiLCAiU2Ugdm9jXHUwMEVBIG5cdTAwRTNvIHRpdmVyIHVtIFBhcnNlciBYTUwgZGEgSUJNIHBhcmEgSmF2YSwgcG9kZXJcdTAwRTEgZmF6ZXIgZG93bmxvYWQgZGVsZSBlbSJ9LAotICB7ICJub1BhcnNlcm1zZzUiLCAiQWxwaGFXb3JrcyBkYSBJQk06IGh0dHA6Ly93d3cuYWxwaGF3b3Jrcy5pYm0uY29tL2Zvcm11bGEveG1sIn0sCi0gIHsgIm9wdGlvblVSSVJFU09MVkVSIiwgIiAgIFstVVJJUkVTT0xWRVIgbm9tZSBjb21wbGV0byBkYSBjbGFzc2UgKFVSSVJlc29sdmVyIGEgc2VyIHVzYWRvIHBhcmEgcmVzb2x2ZXIgVVJJcyldIn0sCi0gIHsgIm9wdGlvbkVOVElUWVJFU09MVkVSIiwgICIgICBbLUVOVElUWVJFU09MVkVSIG5vbWUgY29tcGxldG8gZGEgY2xhc3NlIChFbnRpdHlSZXNvbHZlciBhIHNlciB1c2FkbyBwYXJhIHJlc29sdmVyIGVudGlkYWRlcyldIn0sCi0gIHsgIm9wdGlvbkNPTlRFTlRIQU5ETEVSIiwgICIgICBbLUNPTlRFTlRIQU5ETEVSIG5vbWUgY29tcGxldG8gZGEgY2xhc3NlIChDb250ZW50SGFuZGxlciBhIHNlciB1c2FkbyBwYXJhIHNlcmlhbGl6YXIgYSBzYVx1MDBFRGRhKV0ifSwKLSAgeyAgIm9wdGlvbkxJTkVOVU1CRVJTIiwgICIgICBbLUwgdXNhIG9zIG5cdTAwRkFtZXJvcyBkZSBsaW5oYSBkb3MgZG9jdW1lbnRvcyBkZSBvcmlnZW1dIn0sCi0gIHsgIm9wdGlvblNFQ1VSRVBST0NFU1NJTkciLCAiICAgWy1TRUNVUkUgKGRlZmluZSBvIHJlY3Vyc28gZGUgcHJvY2Vzc2FtZW50byBzZWd1cm8gY29tbyB2ZXJkYWRlaXJvLildIn0sCi0KLSAgICAvLyBGb2xsb3dpbmcgYXJlIHRoZSBuZXcgb3B0aW9ucyBhZGRlZCBpbiBYU0xURXJyb3JSZXNvdXJjZXMucHJvcGVydGllcyBmaWxlcyBhZnRlciBKZGsgMS40IChYYWxhbiAyLjItRDExKQotCi0KLSAgeyAgIm9wdGlvbk1FRElBIiwgICIgICBbLU1FRElBIG1lZGlhVHlwZSAodXNlIG8gYXRyaWJ1dG8gZGUgbVx1MDBFRGRpYSBwYXJhIGxvY2FsaXphciBhIGZvbGhhIGRlIGVzdGlsb3MgYXNzb2NpYWRhIGEgdW0gZG9jdW1lbnRvLildIn0sCi0gIHsgICJvcHRpb25GTEFWT1IiLCAgIiAgIFstRkxBVk9SIGZsYXZvck5hbWUgKFVzZSBleHBsaWNpdGFtZW50ZSBzMnM9U0FYIG91IGQyZD1ET00gcGFyYSBmYXplciBhIHRyYW5zZm9ybWFcdTAwRTdcdTAwRTNvLildICJ9LCAvLyBBZGRlZCBieSBzYm9hZy9zY3VyY3VydTsgZXhwZXJpbWVudGFsCi0gIHsgIm9wdGlvbkRJQUciLCAiICAgWy1ESUFHIChJbXByaW1pciB0cmFuc2Zvcm1hXHUwMEU3XHUwMEUzbyBnZXJhbCBkZSBtaWxpc3NlZ3VuZG9zIGRldGVjdGFkYS4pXSJ9LAotICB7ICJvcHRpb25JTkNSRU1FTlRBTCIsICAiICAgWy1JTkNSRU1FTlRBTCAoc29saWNpdGFyIGEgY29uc3RydVx1MDBFN1x1MDBFM28gZGUgRFRNIGluY3JlbWVudGFsLCBkZWZpbmluZG8gaHR0cDovL3htbC5hcGFjaGUub3JnL3hhbGFuL2ZlYXR1cmVzL2luY3JlbWVudGFsIGNvbW8gdmVyZGFkZWlyby4pXSJ9LAotICB7ICAib3B0aW9uTk9PUFRJTUlNSVpFIiwgICIgICBbLU5PT1BUSU1JTUlaRSAoc29saWNpdGUgbyBuXHUwMEUzbyBwcm9jZXNzYW1lbnRvIGRlIG90aW1pemFcdTAwRTdcdTAwRTNvIGRhIGZvbGhhIGRlIGVzdGlsb3MgZGVmaW5pbmRvIGh0dHA6Ly94bWwuYXBhY2hlLm9yZy94YWxhbi9mZWF0dXJlcy9vcHRpbWl6ZSBjb21vIGZhbHNvLildIn0sCi0gIHsgIm9wdGlvblJMIiwgICIgICBbLVJMIHJlY3Vyc2lvbmxpbWl0IChsaW1pdGUgbnVtXHUwMEU5cmljbyBkZSBhc3Nlclx1MDBFN1x1MDBFM28gbmEgcHJvZnVuZGlkYWRlIGRlIHJlY3Vyc1x1MDBFM28gZGEgZm9saGEgZGUgZXN0aWxvcy4pXSJ9LAotICB7ICAgIm9wdGlvblhPIiwgICIgICBbLVhPIFt0cmFuc2xldE5hbWVdIChhdHJpYnVpIG8gbm9tZSBhbyB0cmFuc2xldCBnZXJhZG8pXSJ9LAotICB7ICAib3B0aW9uWEQiLCAiICAgWy1YRCBkZXN0aW5hdGlvbkRpcmVjdG9yeSAoZXNwZWNpZmljYXIgdW0gZGlyZXRcdTAwRjNyaW8gZGUgZGVzdGlubyBwYXJhIHRyYW5zbGV0KV0ifSwKLSAgeyAgIm9wdGlvblhKIiwgICIgICBbLVhKIGphcmZpbGUgKGVtcGFjb3RhciBjbGFzc2VzIGRvIHRyYW5zbGV0IGVtIHVtIGFycXVpdm8gamFyIGNvbSBvIG5vbWUgPGphcmZpbGU+KV0ifSwKLSAgeyAgICJvcHRpb25YUCIsICAiICAgWy1YUCBwYWNvdGUgKGVzcGVjaWZpY2EgdW0gcHJlZml4byBkZSBub21lIGRvIHBhY290ZSBwYXJhIHRvZGFzIGFzIGNsYXNzZXMgdHJhbnNsZXQgZ2VyYWRhcyldIn0sCi0KLSAgLy9BZGRJVElPTkFMICBTVFJJTkdTIHRoYXQgbmVlZCBMMTBuCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgZGVzY3JpYmVzIHVzYWdlIG9mIGEgcGFydGljdWxhcgotICAvLyBjb21tYW5kLWxpbmUgb3B0aW9uIHRoYXQgaXMgdXNlZCB0byBlbmFibGUgdGhlICJ0ZW1wbGF0ZSBpbmxpbmluZyIKLSAgLy8gb3B0aW1pemF0aW9uLiAgVGhlIG9wdGltaXphdGlvbiBpbnZvbHZlcyBtYWtpbmcgYSBjb3B5IG9mIHRoZSBjb2RlCi0gIC8vIGdlbmVyYXRlZCBmb3IgYSB0ZW1wbGF0ZSBpbiBhbm90aGVyIHRlbXBsYXRlIHRoYXQgcmVmZXJzIHRvIGl0LgotICB7ICJvcHRpb25YTiIsICAiICAgWy1YTiAoYXRpdmEgYSBpbnNlclx1MDBFN1x1MDBFM28gZG8gbW9kZWxvKV0iIH0sCi0gIHsgIm9wdGlvblhYIiwgICIgICBbLVhYIChhdGl2YSBhIHNhXHUwMEVEZGEgZGEgbWVuc2FnZW0gZGUgZGVwdXJhXHUwMEU3XHUwMEUzbyBhZGljaW9uYWwpXSJ9LAotICB7ICJvcHRpb25YVCIgLCAiICAgWy1YVCAodXNhciBvIHRyYW5zbGV0IHBhcmEgdHJhbnNmb3JtYXIsIHNlIHBvc3NcdTAwRUR2ZWwpXSJ9LAotICB7ICJkaWFnVGltaW5nIiwiIC0tLS0tLS0tLSBBIHRyYW5zZm9ybWFcdTAwRTdcdTAwRTNvIGRlIHswfSBwb3IgbWVpbyBkZSB7MX0gbGV2b3UgezJ9IG1zIiB9LAotICB7ICJyZWN1cnNpb25Ub29EZWVwIiwiQW5pbmhhbWVudG8gZG8gbW9kZWxvIG11aXRvIHByb2Z1bmRvLiBhbmluaGFtZW50byA9IHswfSwgbW9kZWxvIHsxfSB7Mn0iIH0sCi0gIHsgIm5hbWVJcyIsICJvIG5vbWUgXHUwMEU5IiB9LAotICB7ICJtYXRjaFBhdHRlcm5JcyIsICJvIHBhZHJcdTAwRTNvIGRlIGNvcnJlc3BvbmRcdTAwRUFuY2lhIFx1MDBFOSIgfQotCi0gIH07Ci0KLSAgfQotICAvLyA9PT09PT09PT09PT09PT09PSBJTkZSQVNUUlVDVFVSRSA9PT09PT09PT09PT09PT09PT09PT09Ci0KLSAgLyoqIFN0cmluZyBmb3IgdXNlIHdoZW4gYSBiYWQgZXJyb3IgY29kZSB3YXMgZW5jb3VudGVyZWQuICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEJBRF9DT0RFID0gIkJBRF9DT0RFIjsKLQotICAvKiogU3RyaW5nIGZvciB1c2Ugd2hlbiBmb3JtYXR0aW5nIG9mIHRoZSBlcnJvciBzdHJpbmcgZmFpbGVkLiAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEZPUk1BVF9GQUlMRUQgPSAiRk9STUFUX0ZBSUxFRCI7Ci0KLSAgLyoqIEdlbmVyYWwgZXJyb3Igc3RyaW5nLiAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUk9SX1NUUklORyA9ICIjZXJyb3IiOwotCi0gIC8qKiBTdHJpbmcgdG8gcHJlcGVuZCB0byBlcnJvciBtZXNzYWdlcy4gICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUk9SX0hFQURFUiA9ICJFcnJvcjogIjsKLQotICAvKiogU3RyaW5nIHRvIHByZXBlbmQgdG8gd2FybmluZyBtZXNzYWdlcy4gICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0FSTklOR19IRUFERVIgPSAiV2FybmluZzogIjsKLQotICAvKiogU3RyaW5nIHRvIHNwZWNpZnkgdGhlIFhTTFQgbW9kdWxlLiAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgWFNMX0hFQURFUiA9ICJYU0xUICI7Ci0KLSAgLyoqIFN0cmluZyB0byBzcGVjaWZ5IHRoZSBYTUwgcGFyc2VyIG1vZHVsZS4gICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFhNTF9IRUFERVIgPSAiWE1MICI7Ci0KLSAgLyoqIEkgZG9uJ3QgdGhpbmsgdGhpcyBpcyB1c2VkIGFueSBtb3JlLgotICAgKiBAZGVwcmVjYXRlZCAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgUVVFUllfSEVBREVSID0gIlBBVFRFUk4gIjsKLQotCi0gICAgfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC9yZXMvWFNMVEVycm9yUmVzb3VyY2VzX3N2LmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3Jlcy9YU0xURXJyb3JSZXNvdXJjZXNfc3YuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMTgzNjk3Yi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3Jlcy9YU0xURXJyb3JSZXNvdXJjZXNfc3YuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE0NDcgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwucmVzOwotCi1pbXBvcnQgamF2YS51dGlsLkxpc3RSZXNvdXJjZUJ1bmRsZTsKLWltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwotaW1wb3J0IGphdmEudXRpbC5NaXNzaW5nUmVzb3VyY2VFeGNlcHRpb247Ci1pbXBvcnQgamF2YS51dGlsLlJlc291cmNlQnVuZGxlOwotCi0vKioKLSAqIFNldCB1cCBlcnJvciBtZXNzYWdlcy4KLSAqIFdlIGJ1aWxkIGEgdHdvIGRpbWVuc2lvbmFsIGFycmF5IG9mIG1lc3NhZ2Uga2V5cyBhbmQKLSAqIG1lc3NhZ2Ugc3RyaW5ncy4gSW4gb3JkZXIgdG8gYWRkIGEgbmV3IG1lc3NhZ2UgaGVyZSwKLSAqIHlvdSBuZWVkIHRvIGZpcnN0IGFkZCBhIFN0cmluZyBjb25zdGFudC4gQW5kCi0gKiAgeW91IG5lZWQgdG8gZW50ZXIga2V5ICwgdmFsdWUgcGFpciBhcyBwYXJ0IG9mIGNvbnRlbnRzCi0gKiBBcnJheS4gWW91IGFsc28gbmVlZCB0byB1cGRhdGUgTUFYX0NPREUgZm9yIGVycm9yIHN0cmluZ3MKLSAqIGFuZCBNQVhfV0FSTklORyBmb3Igd2FybmluZ3MgKCBOZWVkZWQgZm9yIG9ubHkgaW5mb3JtYXRpb24KLSAqIHB1cnBvc2UgKQotICovCi1wdWJsaWMgY2xhc3MgWFNMVEVycm9yUmVzb3VyY2VzX3N2IGV4dGVuZHMgTGlzdFJlc291cmNlQnVuZGxlCi17Ci0KLS8qCi0gKiBUaGlzIGZpbGUgY29udGFpbnMgZXJyb3IgYW5kIHdhcm5pbmcgbWVzc2FnZXMgcmVsYXRlZCB0byBYYWxhbiBFcnJvcgotICogSGFuZGxpbmcuCi0gKgotICogIEdlbmVyYWwgbm90ZXMgdG8gdHJhbnNsYXRvcnM6Ci0gKgotICogIDEpIFhhbGFuIChvciBtb3JlIHByb3Blcmx5LCBYYWxhbi1pbnRlcnByZXRpdmUpIGFuZCBYU0xUQyBhcmUgbmFtZXMgb2YKLSAqICAgICBjb21wb25lbnRzLgotICogICAgIFhTTFQgaXMgYW4gYWNyb255bSBmb3IgIlhNTCBTdHlsZXNoZWV0IExhbmd1YWdlOiBUcmFuc2Zvcm1hdGlvbnMiLgotICogICAgIFhTTFRDIGlzIGFuIGFjcm9ueW0gZm9yIFhTTFQgQ29tcGlsZXIuCi0gKgotICogIDIpIEEgc3R5bGVzaGVldCBpcyBhIGRlc2NyaXB0aW9uIG9mIGhvdyB0byB0cmFuc2Zvcm0gYW4gaW5wdXQgWE1MIGRvY3VtZW50Ci0gKiAgICAgaW50byBhIHJlc3VsdGFudCBYTUwgZG9jdW1lbnQgKG9yIEhUTUwgZG9jdW1lbnQgb3IgdGV4dCkuICBUaGUKLSAqICAgICBzdHlsZXNoZWV0IGl0c2VsZiBpcyBkZXNjcmliZWQgaW4gdGhlIGZvcm0gb2YgYW4gWE1MIGRvY3VtZW50LgotICoKLSAqICAzKSBBIHRlbXBsYXRlIGlzIGEgY29tcG9uZW50IG9mIGEgc3R5bGVzaGVldCB0aGF0IGlzIHVzZWQgdG8gbWF0Y2ggYQotICogICAgIHBhcnRpY3VsYXIgcG9ydGlvbiBvZiBhbiBpbnB1dCBkb2N1bWVudCBhbmQgc3BlY2lmaWVzIHRoZSBmb3JtIG9mIHRoZQotICogICAgIGNvcnJlc3BvbmRpbmcgcG9ydGlvbiBvZiB0aGUgb3V0cHV0IGRvY3VtZW50LgotICoKLSAqICA0KSBBbiBlbGVtZW50IGlzIGEgbWFyay11cCB0YWcgaW4gYW4gWE1MIGRvY3VtZW50OyBhbiBhdHRyaWJ1dGUgaXMgYQotICogICAgIG1vZGlmaWVyIG9uIHRoZSB0YWcuICBGb3IgZXhhbXBsZSwgaW4gPGVsZW0gYXR0cj0ndmFsJyBhdHRyMj0ndmFsMic+Ci0gKiAgICAgImVsZW0iIGlzIGFuIGVsZW1lbnQgbmFtZSwgImF0dHIiIGFuZCAiYXR0cjIiIGFyZSBhdHRyaWJ1dGUgbmFtZXMgd2l0aAotICogICAgIHRoZSB2YWx1ZXMgInZhbCIgYW5kICJ2YWwyIiwgcmVzcGVjdGl2ZWx5LgotICoKLSAqICA1KSBBIG5hbWVzcGFjZSBkZWNsYXJhdGlvbiBpcyBhIHNwZWNpYWwgYXR0cmlidXRlIHRoYXQgaXMgdXNlZCB0byBhc3NvY2lhdGUKLSAqICAgICBhIHByZWZpeCB3aXRoIGEgVVJJICh0aGUgbmFtZXNwYWNlKS4gIFRoZSBtZWFuaW5ncyBvZiBlbGVtZW50IG5hbWVzIGFuZAotICogICAgIGF0dHJpYnV0ZSBuYW1lcyB0aGF0IHVzZSB0aGF0IHByZWZpeCBhcmUgZGVmaW5lZCB3aXRoIHJlc3BlY3QgdG8gdGhhdAotICogICAgIG5hbWVzcGFjZS4KLSAqCi0gKiAgNikgIlRyYW5zbGV0IiBpcyBhbiBpbnZlbnRlZCB0ZXJtIHRoYXQgZGVzY3JpYmVzIHRoZSBjbGFzcyBmaWxlIHRoYXQKLSAqICAgICByZXN1bHRzIGZyb20gY29tcGlsaW5nIGFuIFhNTCBzdHlsZXNoZWV0IGludG8gYSBKYXZhIGNsYXNzLgotICoKLSAqICA3KSBYUGF0aCBpcyBhIHNwZWNpZmljYXRpb24gdGhhdCBkZXNjcmliZXMgYSBub3RhdGlvbiBmb3IgaWRlbnRpZnlpbmcKLSAqICAgICBub2RlcyBpbiBhIHRyZWUtc3RydWN0dXJlZCByZXByZXNlbnRhdGlvbiBvZiBhbiBYTUwgZG9jdW1lbnQuICBBbgotICogICAgIGluc3RhbmNlIG9mIHRoYXQgbm90YXRpb24gaXMgcmVmZXJyZWQgdG8gYXMgYW4gWFBhdGggZXhwcmVzc2lvbi4KLSAqCi0gKi8KLQotICAvKgotICAgKiBTdGF0aWMgdmFyaWFibGVzCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX05BTUVTUEFDRV9VUklfVkFMVUVfRk9SX1JFU1VMVF9QUkVGSVggPQotICAgICAgICAiRVJfSU5WQUxJRF9TRVRfTkFNRVNQQUNFX1VSSV9WQUxVRV9GT1JfUkVTVUxUX1BSRUZJWCI7Ci0KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9OQU1FU1BBQ0VfVVJJX1ZBTFVFX0ZPUl9SRVNVTFRfUFJFRklYX0ZPUl9ERUZBVUxUID0KLSAgICAgICAgIkVSX0lOVkFMSURfTkFNRVNQQUNFX1VSSV9WQUxVRV9GT1JfUkVTVUxUX1BSRUZJWF9GT1JfREVGQVVMVCI7Ci0KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fQ1VSTFlCUkFDRSA9ICJFUl9OT19DVVJMWUJSQUNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCA9ICJFUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSUxMRUdBTF9BVFRSSUJVVEUgPSAiRVJfSUxMRUdBTF9BVFRSSUJVVEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OVUxMX1NPVVJDRU5PREVfQVBQTFlJTVBPUlRTID0gIkVSX05VTExfU09VUkNFTk9ERV9BUFBMWUlNUE9SVFMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfQUREID0gIkVSX0NBTk5PVF9BREQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OVUxMX1NPVVJDRU5PREVfSEFORExFQVBQTFlURU1QTEFURVM9IkVSX05VTExfU09VUkNFTk9ERV9IQU5ETEVBUFBMWVRFTVBMQVRFUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX05BTUVfQVRUUklCID0gIkVSX05PX05BTUVfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVEVNUExBVEVfTk9UX0ZPVU5EID0gIkVSX1RFTVBMQVRFX05PVF9GT1VORCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfUkVTT0xWRV9OQU1FX0FWVCA9ICJFUl9DQU5UX1JFU09MVkVfTkFNRV9BVlQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SRVFVSVJFU19BVFRSSUIgPSAiRVJfUkVRVUlSRVNfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTVVTVF9IQVZFX1RFU1RfQVRUUklCID0gIkVSX01VU1RfSEFWRV9URVNUX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0JBRF9WQUxfT05fTEVWRUxfQVRUUklCID0KLSAgICAgICAgICJFUl9CQURfVkFMX09OX0xFVkVMX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BST0NFU1NJTkdJTlNUUlVDVElPTl9OQU1FX0NBTlRfQkVfWE1MID0KLSAgICAgICAgICJFUl9QUk9DRVNTSU5HSU5TVFJVQ1RJT05fTkFNRV9DQU5UX0JFX1hNTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BST0NFU1NJTkdJTlNUUlVDVElPTl9OT1RWQUxJRF9OQ05BTUUgPQotICAgICAgICAgIkVSX1BST0NFU1NJTkdJTlNUUlVDVElPTl9OT1RWQUxJRF9OQ05BTUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9ORUVEX01BVENIX0FUVFJJQiA9ICJFUl9ORUVEX01BVENIX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05FRURfTkFNRV9PUl9NQVRDSF9BVFRSSUIgPQotICAgICAgICAgIkVSX05FRURfTkFNRV9PUl9NQVRDSF9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX1JFU09MVkVfTlNQUkVGSVggPQotICAgICAgICAgIkVSX0NBTlRfUkVTT0xWRV9OU1BSRUZJWCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lMTEVHQUxfVkFMVUUgPSAiRVJfSUxMRUdBTF9WQUxVRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX09XTkVSRE9DID0gIkVSX05PX09XTkVSRE9DIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRUxFTVRFTVBMQVRFRUxFTV9FUlIgPSJFUl9FTEVNVEVNUExBVEVFTEVNX0VSUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05VTExfQ0hJTEQgPSAiRVJfTlVMTF9DSElMRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05FRURfU0VMRUNUX0FUVFJJQiA9ICJFUl9ORUVEX1NFTEVDVF9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9ORUVEX1RFU1RfQVRUUklCID0gIkVSX05FRURfVEVTVF9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9ORUVEX05BTUVfQVRUUklCID0gIkVSX05FRURfTkFNRV9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19DT05URVhUX09XTkVSRE9DID0gIkVSX05PX0NPTlRFWFRfT1dORVJET0MiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRF9OT1RfQ1JFQVRFX1hNTF9QUk9DX0xJQUlTT04gPQotICAgICAgICAgIkVSX0NPVUxEX05PVF9DUkVBVEVfWE1MX1BST0NfTElBSVNPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BST0NFU1NfTk9UX1NVQ0NFU1NGVUwgPQotICAgICAgICAgIkVSX1BST0NFU1NfTk9UX1NVQ0NFU1NGVUwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT1RfU1VDQ0VTU0ZVTCA9ICJFUl9OT1RfU1VDQ0VTU0ZVTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VOQ09ESU5HX05PVF9TVVBQT1JURUQgPQotICAgICAgICAgIkVSX0VOQ09ESU5HX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRF9OT1RfQ1JFQVRFX1RSQUNFTElTVEVORVIgPQotICAgICAgICAgIkVSX0NPVUxEX05PVF9DUkVBVEVfVFJBQ0VMSVNURU5FUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0tFWV9SRVFVSVJFU19OQU1FX0FUVFJJQiA9Ci0gICAgICAgICAiRVJfS0VZX1JFUVVJUkVTX05BTUVfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfS0VZX1JFUVVJUkVTX01BVENIX0FUVFJJQiA9Ci0gICAgICAgICAiRVJfS0VZX1JFUVVJUkVTX01BVENIX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0tFWV9SRVFVSVJFU19VU0VfQVRUUklCID0KLSAgICAgICAgICJFUl9LRVlfUkVRVUlSRVNfVVNFX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1JFUVVJUkVTX0VMRU1FTlRTX0FUVFJJQiA9Ci0gICAgICAgICAiRVJfUkVRVUlSRVNfRUxFTUVOVFNfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTUlTU0lOR19QUkVGSVhfQVRUUklCID0KLSAgICAgICAgICJFUl9NSVNTSU5HX1BSRUZJWF9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9CQURfU1RZTEVTSEVFVF9VUkwgPSAiRVJfQkFEX1NUWUxFU0hFRVRfVVJMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRklMRV9OT1RfRk9VTkQgPSAiRVJfRklMRV9OT1RfRk9VTkQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JT0VYQ0VQVElPTiA9ICJFUl9JT0VYQ0VQVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX0hSRUZfQVRUUklCID0gIkVSX05PX0hSRUZfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU1RZTEVTSEVFVF9JTkNMVURFU19JVFNFTEYgPQotICAgICAgICAgIkVSX1NUWUxFU0hFRVRfSU5DTFVERVNfSVRTRUxGIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJPQ0VTU0lOQ0xVREVfRVJST1IgPSJFUl9QUk9DRVNTSU5DTFVERV9FUlJPUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01JU1NJTkdfTEFOR19BVFRSSUIgPSAiRVJfTUlTU0lOR19MQU5HX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01JU1NJTkdfQ09OVEFJTkVSX0VMRU1FTlRfQ09NUE9ORU5UID0KLSAgICAgICAgICJFUl9NSVNTSU5HX0NPTlRBSU5FUl9FTEVNRU5UX0NPTVBPTkVOVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTl9PTkxZX09VVFBVVF9UT19FTEVNRU5UID0KLSAgICAgICAgICJFUl9DQU5fT05MWV9PVVRQVVRfVE9fRUxFTUVOVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BST0NFU1NfRVJST1IgPSAiRVJfUFJPQ0VTU19FUlJPUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1VOSU1QTE5PREVfRVJST1IgPSAiRVJfVU5JTVBMTk9ERV9FUlJPUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1NFTEVDVF9FWFBSRVNTSU9OID0iRVJfTk9fU0VMRUNUX0VYUFJFU1NJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfU0VSSUFMSVpFX1hTTFBST0NFU1NPUiA9Ci0gICAgICAgICAiRVJfQ0FOTk9UX1NFUklBTElaRV9YU0xQUk9DRVNTT1IiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19JTlBVVF9TVFlMRVNIRUVUID0gIkVSX05PX0lOUFVUX1NUWUxFU0hFRVQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GQUlMRURfUFJPQ0VTU19TVFlMRVNIRUVUID0KLSAgICAgICAgICJFUl9GQUlMRURfUFJPQ0VTU19TVFlMRVNIRUVUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTEROVF9QQVJTRV9ET0MgPSAiRVJfQ09VTEROVF9QQVJTRV9ET0MiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRE5UX0ZJTkRfRlJBR01FTlQgPQotICAgICAgICAgIkVSX0NPVUxETlRfRklORF9GUkFHTUVOVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PREVfTk9UX0VMRU1FTlQgPSAiRVJfTk9ERV9OT1RfRUxFTUVOVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZPUkVBQ0hfTkVFRF9NQVRDSF9PUl9OQU1FX0FUVFJJQiA9Ci0gICAgICAgICAiRVJfRk9SRUFDSF9ORUVEX01BVENIX09SX05BTUVfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVEVNUExBVEVTX05FRURfTUFUQ0hfT1JfTkFNRV9BVFRSSUIgPQotICAgICAgICAgIkVSX1RFTVBMQVRFU19ORUVEX01BVENIX09SX05BTUVfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fQ0xPTkVfT0ZfRE9DVU1FTlRfRlJBRyA9Ci0gICAgICAgICAiRVJfTk9fQ0xPTkVfT0ZfRE9DVU1FTlRfRlJBRyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfQ1JFQVRFX0lURU0gPSAiRVJfQ0FOVF9DUkVBVEVfSVRFTSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hNTFNQQUNFX0lMTEVHQUxfVkFMVUUgPQotICAgICAgICAgIkVSX1hNTFNQQUNFX0lMTEVHQUxfVkFMVUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19YU0xLRVlfREVDTEFSQVRJT04gPQotICAgICAgICAgIkVSX05PX1hTTEtFWV9ERUNMQVJBVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfQ1JFQVRFX1VSTCA9ICJFUl9DQU5UX0NSRUFURV9VUkwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YU0xGVU5DVElPTlNfVU5TVVBQT1JURUQgPQotICAgICAgICAgIkVSX1hTTEZVTkNUSU9OU19VTlNVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BST0NFU1NPUl9FUlJPUiA9ICJFUl9QUk9DRVNTT1JfRVJST1IiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT1RfQUxMT1dFRF9JTlNJREVfU1RZTEVTSEVFVCA9Ci0gICAgICAgICAiRVJfTk9UX0FMTE9XRURfSU5TSURFX1NUWUxFU0hFRVQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SRVNVTFROU19OT1RfU1VQUE9SVEVEID0KLSAgICAgICAgICJFUl9SRVNVTFROU19OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfREVGQVVMVFNQQUNFX05PVF9TVVBQT1JURUQgPQotICAgICAgICAgIkVSX0RFRkFVTFRTUEFDRV9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5ERU5UUkVTVUxUX05PVF9TVVBQT1JURUQgPQotICAgICAgICAgIkVSX0lOREVOVFJFU1VMVF9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSUxMRUdBTF9BVFRSSUIgPSAiRVJfSUxMRUdBTF9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTktOT1dOX1hTTF9FTEVNID0gIkVSX1VOS05PV05fWFNMX0VMRU0iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9CQURfWFNMU09SVF9VU0UgPSAiRVJfQkFEX1hTTFNPUlRfVVNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTUlTUExBQ0VEX1hTTFdIRU4gPSAiRVJfTUlTUExBQ0VEX1hTTFdIRU4iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YU0xXSEVOX05PVF9QQVJFTlRFRF9CWV9YU0xDSE9PU0UgPQotICAgICAgICAgIkVSX1hTTFdIRU5fTk9UX1BBUkVOVEVEX0JZX1hTTENIT09TRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01JU1BMQUNFRF9YU0xPVEhFUldJU0UgPQotICAgICAgICAgIkVSX01JU1BMQUNFRF9YU0xPVEhFUldJU0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YU0xPVEhFUldJU0VfTk9UX1BBUkVOVEVEX0JZX1hTTENIT09TRSA9Ci0gICAgICAgICAiRVJfWFNMT1RIRVJXSVNFX05PVF9QQVJFTlRFRF9CWV9YU0xDSE9PU0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT1RfQUxMT1dFRF9JTlNJREVfVEVNUExBVEUgPQotICAgICAgICAgIkVSX05PVF9BTExPV0VEX0lOU0lERV9URU1QTEFURSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1VOS05PV05fRVhUX05TX1BSRUZJWCA9Ci0gICAgICAgICAiRVJfVU5LTk9XTl9FWFRfTlNfUFJFRklYIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU1QT1JUU19BU19GSVJTVF9FTEVNID0KLSAgICAgICAgICJFUl9JTVBPUlRTX0FTX0ZJUlNUX0VMRU0iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTVBPUlRJTkdfSVRTRUxGID0gIkVSX0lNUE9SVElOR19JVFNFTEYiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YTUxTUEFDRV9JTExFR0FMX1ZBTCA9IkVSX1hNTFNQQUNFX0lMTEVHQUxfVkFMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJPQ0VTU1NUWUxFU0hFRVRfTk9UX1NVQ0NFU1NGVUwgPQotICAgICAgICAgIkVSX1BST0NFU1NTVFlMRVNIRUVUX05PVF9TVUNDRVNTRlVMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU0FYX0VYQ0VQVElPTiA9ICJFUl9TQVhfRVhDRVBUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWFNMVF9FUlJPUiA9ICJFUl9YU0xUX0VSUk9SIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ1VSUkVOQ1lfU0lHTl9JTExFR0FMPQotICAgICAgICAgIkVSX0NVUlJFTkNZX1NJR05fSUxMRUdBTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0RPQ1VNRU5UX0ZVTkNUSU9OX0lOVkFMSURfSU5fU1RZTEVTSEVFVF9ET00gPQotICAgICAgICAgIkVSX0RPQ1VNRU5UX0ZVTkNUSU9OX0lOVkFMSURfSU5fU1RZTEVTSEVFVF9ET00iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX1JFU09MVkVfUFJFRklYX09GX05PTl9QUkVGSVhfUkVTT0xWRVIgPQotICAgICAgICAgIkVSX0NBTlRfUkVTT0xWRV9QUkVGSVhfT0ZfTk9OX1BSRUZJWF9SRVNPTFZFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1JFRElSRUNUX0NPVUxETlRfR0VUX0ZJTEVOQU1FID0KLSAgICAgICAgICJFUl9SRURJUkVDVF9DT1VMRE5UX0dFVF9GSUxFTkFNRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9CVUlMRF9GT1JNQVRURVJMSVNURU5FUl9JTl9SRURJUkVDVCA9Ci0gICAgICAgICAiRVJfQ0FOTk9UX0JVSUxEX0ZPUk1BVFRFUkxJU1RFTkVSX0lOX1JFRElSRUNUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9QUkVGSVhfSU5fRVhDTFVERVJFU1VMVFBSRUZJWCA9Ci0gICAgICAgICAiRVJfSU5WQUxJRF9QUkVGSVhfSU5fRVhDTFVERVJFU1VMVFBSRUZJWCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01JU1NJTkdfTlNfVVJJID0gIkVSX01JU1NJTkdfTlNfVVJJIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTUlTU0lOR19BUkdfRk9SX09QVElPTiA9Ci0gICAgICAgICAiRVJfTUlTU0lOR19BUkdfRk9SX09QVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfT1BUSU9OID0gIkVSX0lOVkFMSURfT1BUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTUFMRk9STUVEX0ZPUk1BVF9TVFJJTkcgPQotICAgICAgICAgIkVSX01BTEZPUk1FRF9GT1JNQVRfU1RSSU5HIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU1RZTEVTSEVFVF9SRVFVSVJFU19WRVJTSU9OX0FUVFJJQiA9Ci0gICAgICAgICAiRVJfU1RZTEVTSEVFVF9SRVFVSVJFU19WRVJTSU9OX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lMTEVHQUxfQVRUUklCVVRFX1ZBTFVFID0KLSAgICAgICAgICJFUl9JTExFR0FMX0FUVFJJQlVURV9WQUxVRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NIT09TRV9SRVFVSVJFU19XSEVOID0iRVJfQ0hPT1NFX1JFUVVJUkVTX1dIRU4iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19BUFBMWV9JTVBPUlRfSU5fRk9SX0VBQ0ggPQotICAgICAgICAgIkVSX05PX0FQUExZX0lNUE9SVF9JTl9GT1JfRUFDSCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfVVNFX0RUTV9GT1JfT1VUUFVUID0KLSAgICAgICAgICJFUl9DQU5UX1VTRV9EVE1fRk9SX09VVFBVVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfVVNFX0RUTV9GT1JfSU5QVVQgPQotICAgICAgICAgIkVSX0NBTlRfVVNFX0RUTV9GT1JfSU5QVVQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQUxMX1RPX0VYVF9GQUlMRUQgPSAiRVJfQ0FMTF9UT19FWFRfRkFJTEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJFRklYX01VU1RfUkVTT0xWRSA9ICJFUl9QUkVGSVhfTVVTVF9SRVNPTFZFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9VVEYxNl9TVVJST0dBVEUgPQotICAgICAgICAgIkVSX0lOVkFMSURfVVRGMTZfU1VSUk9HQVRFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWFNMQVRUUlNFVF9VU0VEX0lUU0VMRiA9Ci0gICAgICAgICAiRVJfWFNMQVRUUlNFVF9VU0VEX0lUU0VMRiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9NSVhfWEVSQ0VTRE9NID0iRVJfQ0FOTk9UX01JWF9YRVJDRVNET00iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9UT09fTUFOWV9MSVNURU5FUlMgPSAiRVJfVE9PX01BTllfTElTVEVORVJTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5fRUxFTVRFTVBMQVRFRUxFTV9SRUFET0JKRUNUID0KLSAgICAgICAgICJFUl9JTl9FTEVNVEVNUExBVEVFTEVNX1JFQURPQkpFQ1QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9EVVBMSUNBVEVfTkFNRURfVEVNUExBVEUgPQotICAgICAgICAgIkVSX0RVUExJQ0FURV9OQU1FRF9URU1QTEFURSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfS0VZX0NBTEwgPSAiRVJfSU5WQUxJRF9LRVlfQ0FMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1JFRkVSRU5DSU5HX0lUU0VMRiA9ICJFUl9SRUZFUkVOQ0lOR19JVFNFTEYiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTExFR0FMX0RPTVNPVVJDRV9JTlBVVCA9Ci0gICAgICAgICAiRVJfSUxMRUdBTF9ET01TT1VSQ0VfSU5QVVQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DTEFTU19OT1RfRk9VTkRfRk9SX09QVElPTiA9Ci0gICAgICAgICAiRVJfQ0xBU1NfTk9UX0ZPVU5EX0ZPUl9PUFRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SRVFVSVJFRF9FTEVNX05PVF9GT1VORCA9Ci0gICAgICAgICAiRVJfUkVRVUlSRURfRUxFTV9OT1RfRk9VTkQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlBVVF9DQU5OT1RfQkVfTlVMTCA9IkVSX0lOUFVUX0NBTk5PVF9CRV9OVUxMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVVJJX0NBTk5PVF9CRV9OVUxMID0gIkVSX1VSSV9DQU5OT1RfQkVfTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZJTEVfQ0FOTk9UX0JFX05VTEwgPSAiRVJfRklMRV9DQU5OT1RfQkVfTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NPVVJDRV9DQU5OT1RfQkVfTlVMTCA9Ci0gICAgICAgICAiRVJfU09VUkNFX0NBTk5PVF9CRV9OVUxMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX0lOSVRfQlNGTUdSID0gIkVSX0NBTk5PVF9JTklUX0JTRk1HUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9DTVBMX0VYVEVOU04gPSAiRVJfQ0FOTk9UX0NNUExfRVhURU5TTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9DUkVBVEVfRVhURU5TTiA9Ci0gICAgICAgICAiRVJfQ0FOTk9UX0NSRUFURV9FWFRFTlNOIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5TVEFOQ0VfTVRIRF9DQUxMX1JFUVVJUkVTID0KLSAgICAgICAgICJFUl9JTlNUQU5DRV9NVEhEX0NBTExfUkVRVUlSRVMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX0VMRU1FTlRfTkFNRSA9IkVSX0lOVkFMSURfRUxFTUVOVF9OQU1FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRUxFTUVOVF9OQU1FX01FVEhPRF9TVEFUSUMgPQotICAgICAgICAgIkVSX0VMRU1FTlRfTkFNRV9NRVRIT0RfU1RBVElDIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhURU5TSU9OX0ZVTkNfVU5LTk9XTiA9Ci0gICAgICAgICAiRVJfRVhURU5TSU9OX0ZVTkNfVU5LTk9XTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01PUkVfTUFUQ0hfQ09OU1RSVUNUT1IgPQotICAgICAgICAgIkVSX01PUkVfTUFUQ0hfQ09OU1RSVUNUT1IiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9NT1JFX01BVENIX01FVEhPRCA9ICJFUl9NT1JFX01BVENIX01FVEhPRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01PUkVfTUFUQ0hfRUxFTUVOVCA9ICJFUl9NT1JFX01BVENIX0VMRU1FTlQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX0NPTlRFWFRfUEFTU0VEID0KLSAgICAgICAgICJFUl9JTlZBTElEX0NPTlRFWFRfUEFTU0VEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUE9PTF9FWElTVFMgPSAiRVJfUE9PTF9FWElTVFMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19EUklWRVJfTkFNRSA9ICJFUl9OT19EUklWRVJfTkFNRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1VSTCA9ICJFUl9OT19VUkwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QT09MX1NJWkVfTEVTU1RIQU5fT05FID0KLSAgICAgICAgICJFUl9QT09MX1NJWkVfTEVTU1RIQU5fT05FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9EUklWRVIgPSAiRVJfSU5WQUxJRF9EUklWRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19TVFlMRVNIRUVUUk9PVCA9ICJFUl9OT19TVFlMRVNIRUVUUk9PVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lMTEVHQUxfWE1MU1BBQ0VfVkFMVUUgPQotICAgICAgICAgIkVSX0lMTEVHQUxfWE1MU1BBQ0VfVkFMVUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUk9DRVNTRlJPTU5PREVfRkFJTEVEID0KLSAgICAgICAgICJFUl9QUk9DRVNTRlJPTU5PREVfRkFJTEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUkVTT1VSQ0VfQ09VTERfTk9UX0xPQUQgPQotICAgICAgICAgIkVSX1JFU09VUkNFX0NPVUxEX05PVF9MT0FEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQlVGRkVSX1NJWkVfTEVTU1RIQU5fWkVSTyA9Ci0gICAgICAgICAiRVJfQlVGRkVSX1NJWkVfTEVTU1RIQU5fWkVSTyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1VOS05PV05fRVJST1JfQ0FMTElOR19FWFRFTlNJT04gPQotICAgICAgICAgIkVSX1VOS05PV05fRVJST1JfQ0FMTElOR19FWFRFTlNJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19OQU1FU1BBQ0VfREVDTCA9ICJFUl9OT19OQU1FU1BBQ0VfREVDTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VMRU1fQ09OVEVOVF9OT1RfQUxMT1dFRCA9Ci0gICAgICAgICAiRVJfRUxFTV9DT05URU5UX05PVF9BTExPV0VEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU1RZTEVTSEVFVF9ESVJFQ1RFRF9URVJNSU5BVElPTiA9Ci0gICAgICAgICAiRVJfU1RZTEVTSEVFVF9ESVJFQ1RFRF9URVJNSU5BVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX09ORV9PUl9UV08gPSAiRVJfT05FX09SX1RXTyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1RXT19PUl9USFJFRSA9ICJFUl9UV09fT1JfVEhSRUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRF9OT1RfTE9BRF9SRVNPVVJDRSA9Ci0gICAgICAgICAiRVJfQ09VTERfTk9UX0xPQURfUkVTT1VSQ0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfSU5JVF9ERUZBVUxUX1RFTVBMQVRFUyA9Ci0gICAgICAgICAiRVJfQ0FOTk9UX0lOSVRfREVGQVVMVF9URU1QTEFURVMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SRVNVTFRfTlVMTCA9ICJFUl9SRVNVTFRfTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1JFU1VMVF9DT1VMRF9OT1RfQkVfU0VUID0KLSAgICAgICAgICJFUl9SRVNVTFRfQ09VTERfTk9UX0JFX1NFVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX09VVFBVVF9TUEVDSUZJRUQgPSAiRVJfTk9fT1VUUFVUX1NQRUNJRklFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9UUkFOU0ZPUk1fVE9fUkVTVUxUX1RZUEUgPQotICAgICAgICAgIkVSX0NBTk5PVF9UUkFOU0ZPUk1fVE9fUkVTVUxUX1RZUEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfVFJBTlNGT1JNX1NPVVJDRV9UWVBFID0KLSAgICAgICAgICJFUl9DQU5OT1RfVFJBTlNGT1JNX1NPVVJDRV9UWVBFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTlVMTF9DT05URU5UX0hBTkRMRVIgPSJFUl9OVUxMX0NPTlRFTlRfSEFORExFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05VTExfRVJST1JfSEFORExFUiA9ICJFUl9OVUxMX0VSUk9SX0hBTkRMRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfQ0FMTF9QQVJTRSA9ICJFUl9DQU5OT1RfQ0FMTF9QQVJTRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1BBUkVOVF9GT1JfRklMVEVSID0iRVJfTk9fUEFSRU5UX0ZPUl9GSUxURVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19TVFlMRVNIRUVUX0lOX01FRElBID0KLSAgICAgICAgICJFUl9OT19TVFlMRVNIRUVUX0lOX01FRElBIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fU1RZTEVTSEVFVF9QSSA9ICJFUl9OT19TVFlMRVNIRUVUX1BJIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9UX1NVUFBPUlRFRCA9ICJFUl9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJPUEVSVFlfVkFMVUVfQk9PTEVBTiA9Ci0gICAgICAgICAiRVJfUFJPUEVSVFlfVkFMVUVfQk9PTEVBTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxEX05PVF9GSU5EX0VYVEVSTl9TQ1JJUFQgPQotICAgICAgICAgIkVSX0NPVUxEX05PVF9GSU5EX0VYVEVSTl9TQ1JJUFQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SRVNPVVJDRV9DT1VMRF9OT1RfRklORCA9Ci0gICAgICAgICAiRVJfUkVTT1VSQ0VfQ09VTERfTk9UX0ZJTkQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9PVVRQVVRfUFJPUEVSVFlfTk9UX1JFQ09HTklaRUQgPQotICAgICAgICAgIkVSX09VVFBVVF9QUk9QRVJUWV9OT1RfUkVDT0dOSVpFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZBSUxFRF9DUkVBVElOR19FTEVNTElUUlNMVCA9Ci0gICAgICAgICAiRVJfRkFJTEVEX0NSRUFUSU5HX0VMRU1MSVRSU0xUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVkFMVUVfU0hPVUxEX0JFX05VTUJFUiA9Ci0gICAgICAgICAiRVJfVkFMVUVfU0hPVUxEX0JFX05VTUJFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1ZBTFVFX1NIT1VMRF9FUVVBTCA9ICJFUl9WQUxVRV9TSE9VTERfRVFVQUwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GQUlMRURfQ0FMTElOR19NRVRIT0QgPQotICAgICAgICAgIkVSX0ZBSUxFRF9DQUxMSU5HX01FVEhPRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZBSUxFRF9DUkVBVElOR19FTEVNVE1QTCA9Ci0gICAgICAgICAiRVJfRkFJTEVEX0NSRUFUSU5HX0VMRU1UTVBMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0hBUlNfTk9UX0FMTE9XRUQgPSAiRVJfQ0hBUlNfTk9UX0FMTE9XRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9BVFRSX05PVF9BTExPV0VEID0gIkVSX0FUVFJfTk9UX0FMTE9XRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9CQURfVkFMVUUgPSAiRVJfQkFEX1ZBTFVFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQVRUUklCX1ZBTFVFX05PVF9GT1VORCA9Ci0gICAgICAgICAiRVJfQVRUUklCX1ZBTFVFX05PVF9GT1VORCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FUVFJJQl9WQUxVRV9OT1RfUkVDT0dOSVpFRCA9Ci0gICAgICAgICAiRVJfQVRUUklCX1ZBTFVFX05PVF9SRUNPR05JWkVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTlVMTF9VUklfTkFNRVNQQUNFID0gIkVSX05VTExfVVJJX05BTUVTUEFDRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05VTUJFUl9UT09fQklHID0gIkVSX05VTUJFUl9UT09fQklHIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgIEVSX0NBTk5PVF9GSU5EX1NBWDFfRFJJVkVSID0KLSAgICAgICAgICJFUl9DQU5OT1RfRklORF9TQVgxX0RSSVZFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nICBFUl9TQVgxX0RSSVZFUl9OT1RfTE9BREVEID0KLSAgICAgICAgICJFUl9TQVgxX0RSSVZFUl9OT1RfTE9BREVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgIEVSX1NBWDFfRFJJVkVSX05PVF9JTlNUQU5USUFURUQgPQotICAgICAgICAgIkVSX1NBWDFfRFJJVkVSX05PVF9JTlNUQU5USUFURUQiIDsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU0FYMV9EUklWRVJfTk9UX0lNUExFTUVOVF9QQVJTRVIgPQotICAgICAgICAgIkVSX1NBWDFfRFJJVkVSX05PVF9JTVBMRU1FTlRfUEFSU0VSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgIEVSX1BBUlNFUl9QUk9QRVJUWV9OT1RfU1BFQ0lGSUVEID0KLSAgICAgICAgICJFUl9QQVJTRVJfUFJPUEVSVFlfTk9UX1NQRUNJRklFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nICBFUl9QQVJTRVJfQVJHX0NBTk5PVF9CRV9OVUxMID0KLSAgICAgICAgICJFUl9QQVJTRVJfQVJHX0NBTk5PVF9CRV9OVUxMIiA7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nICBFUl9GRUFUVVJFID0gIkVSX0ZFQVRVUkUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUk9QRVJUWSA9ICJFUl9QUk9QRVJUWSIgOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OVUxMX0VOVElUWV9SRVNPTFZFUiA9IkVSX05VTExfRU5USVRZX1JFU09MVkVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgIEVSX05VTExfRFREX0hBTkRMRVIgPSAiRVJfTlVMTF9EVERfSEFORExFUiIgOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19EUklWRVJfTkFNRV9TUEVDSUZJRUQgPQotICAgICAgICAgIkVSX05PX0RSSVZFUl9OQU1FX1NQRUNJRklFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1VSTF9TUEVDSUZJRUQgPSAiRVJfTk9fVVJMX1NQRUNJRklFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BPT0xTSVpFX0xFU1NfVEhBTl9PTkUgPQotICAgICAgICAgIkVSX1BPT0xTSVpFX0xFU1NfVEhBTl9PTkUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX0RSSVZFUl9OQU1FID0gIkVSX0lOVkFMSURfRFJJVkVSX05BTUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FUlJPUkxJU1RFTkVSID0gIkVSX0VSUk9STElTVEVORVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9BU1NFUlRfTk9fVEVNUExBVEVfUEFSRU5UID0KLSAgICAgICAgICJFUl9BU1NFUlRfTk9fVEVNUExBVEVfUEFSRU5UIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQVNTRVJUX1JFRFVOREVOVF9FWFBSX0VMSU1JTkFUT1IgPQotICAgICAgICAgIkVSX0FTU0VSVF9SRURVTkRFTlRfRVhQUl9FTElNSU5BVE9SIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9UX0FMTE9XRURfSU5fUE9TSVRJT04gPQotICAgICAgICAgIkVSX05PVF9BTExPV0VEX0lOX1BPU0lUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9OV0hJVEVTUEFDRV9OT1RfQUxMT1dFRF9JTl9QT1NJVElPTiA9Ci0gICAgICAgICAiRVJfTk9OV0hJVEVTUEFDRV9OT1RfQUxMT1dFRF9JTl9QT1NJVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05BTUVTUEFDRV9DT05URVhUX05VTExfTkFNRVNQQUNFID0KLSAgICAgICAgICJFUl9OQU1FU1BBQ0VfQ09OVEVYVF9OVUxMX05BTUVTUEFDRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05BTUVTUEFDRV9DT05URVhUX05VTExfUFJFRklYID0KLSAgICAgICAgICJFUl9OQU1FU1BBQ0VfQ09OVEVYVF9OVUxMX1BSRUZJWCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hQQVRIX1JFU09MVkVSX05VTExfUU5BTUUgPQotICAgICAgICAgIkVSX1hQQVRIX1JFU09MVkVSX05VTExfUU5BTUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YUEFUSF9SRVNPTFZFUl9ORUdBVElWRV9BUklUWSA9Ci0gICAgICAgICAiRVJfWFBBVEhfUkVTT0xWRVJfTkVHQVRJVkVfQVJJVFkiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBJTlZBTElEX1RDSEFSID0gIklOVkFMSURfVENIQVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBJTlZBTElEX1FOQU1FID0gIklOVkFMSURfUU5BTUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBJTlZBTElEX0VOVU0gPSAiSU5WQUxJRF9FTlVNIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSU5WQUxJRF9OTVRPS0VOID0gIklOVkFMSURfTk1UT0tFTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIElOVkFMSURfTkNOQU1FID0gIklOVkFMSURfTkNOQU1FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSU5WQUxJRF9CT09MRUFOID0gIklOVkFMSURfQk9PTEVBTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIElOVkFMSURfTlVNQkVSID0gIklOVkFMSURfTlVNQkVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQVJHX0xJVEVSQUwgPSAiRVJfQVJHX0xJVEVSQUwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9EVVBMSUNBVEVfR0xPQkFMX1ZBUiA9IkVSX0RVUExJQ0FURV9HTE9CQUxfVkFSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRFVQTElDQVRFX1ZBUiA9ICJFUl9EVVBMSUNBVEVfVkFSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVEVNUExBVEVfTkFNRV9NQVRDSCA9ICJFUl9URU1QTEFURV9OQU1FX01BVENIIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9QUkVGSVggPSAiRVJfSU5WQUxJRF9QUkVGSVgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19BVFRSSUJfU0VUID0gIkVSX05PX0FUVFJJQl9TRVQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GVU5DVElPTl9OT1RfRk9VTkQgPQotICAgICAgICAgIkVSX0ZVTkNUSU9OX05PVF9GT1VORCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfSEFWRV9DT05URU5UX0FORF9TRUxFQ1QgPQotICAgICAiRVJfQ0FOVF9IQVZFX0NPTlRFTlRfQU5EX1NFTEVDVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfU0VUX1BBUkFNX1ZBTFVFID0gIkVSX0lOVkFMSURfU0VUX1BBUkFNX1ZBTFVFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU0VUX0ZFQVRVUkVfTlVMTF9OQU1FID0KLSAgICAgICAgIkVSX1NFVF9GRUFUVVJFX05VTExfTkFNRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0dFVF9GRUFUVVJFX05VTExfTkFNRSA9Ci0gICAgICAgICJFUl9HRVRfRkVBVFVSRV9OVUxMX05BTUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTlNVUFBPUlRFRF9GRUFUVVJFID0KLSAgICAgICAgIkVSX1VOU1VQUE9SVEVEX0ZFQVRVUkUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FWFRFTlNJT05fRUxFTUVOVF9OT1RfQUxMT1dFRF9JTl9TRUNVUkVfUFJPQ0VTU0lORyA9Ci0gICAgICAgICJFUl9FWFRFTlNJT05fRUxFTUVOVF9OT1RfQUxMT1dFRF9JTl9TRUNVUkVfUFJPQ0VTU0lORyI7Ci0KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfRk9VTkRfQ1VSTFlCUkFDRSA9ICJXR19GT1VORF9DVVJMWUJSQUNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfQ09VTlRfQVRUUklCX01BVENIRVNfTk9fQU5DRVNUT1IgPQotICAgICAgICAgIldHX0NPVU5UX0FUVFJJQl9NQVRDSEVTX05PX0FOQ0VTVE9SIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfRVhQUl9BVFRSSUJfQ0hBTkdFRF9UT19TRUxFQ1QgPQotICAgICAgICAgIldHX0VYUFJfQVRUUklCX0NIQU5HRURfVE9fU0VMRUNUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfTk9fTE9DQUxFX0lOX0ZPUk1BVE5VTUJFUiA9Ci0gICAgICAgICAiV0dfTk9fTE9DQUxFX0lOX0ZPUk1BVE5VTUJFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0xPQ0FMRV9OT1RfRk9VTkQgPSAiV0dfTE9DQUxFX05PVF9GT1VORCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0NBTk5PVF9NQUtFX1VSTF9GUk9NID0iV0dfQ0FOTk9UX01BS0VfVVJMX0ZST00iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19DQU5OT1RfTE9BRF9SRVFVRVNURURfRE9DID0KLSAgICAgICAgICJXR19DQU5OT1RfTE9BRF9SRVFVRVNURURfRE9DIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfQ0FOTk9UX0ZJTkRfQ09MTEFUT1IgPSJXR19DQU5OT1RfRklORF9DT0xMQVRPUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0ZVTkNUSU9OU19TSE9VTERfVVNFX1VSTCA9Ci0gICAgICAgICAiV0dfRlVOQ1RJT05TX1NIT1VMRF9VU0VfVVJMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfRU5DT0RJTkdfTk9UX1NVUFBPUlRFRF9VU0lOR19VVEY4ID0KLSAgICAgICAgICJXR19FTkNPRElOR19OT1RfU1VQUE9SVEVEX1VTSU5HX1VURjgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19FTkNPRElOR19OT1RfU1VQUE9SVEVEX1VTSU5HX0pBVkEgPQotICAgICAgICAgIldHX0VOQ09ESU5HX05PVF9TVVBQT1JURURfVVNJTkdfSkFWQSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX1NQRUNJRklDSVRZX0NPTkZMSUNUUyA9Ci0gICAgICAgICAiV0dfU1BFQ0lGSUNJVFlfQ09ORkxJQ1RTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfUEFSU0lOR19BTkRfUFJFUEFSSU5HID0KLSAgICAgICAgICJXR19QQVJTSU5HX0FORF9QUkVQQVJJTkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19BVFRSX1RFTVBMQVRFID0gIldHX0FUVFJfVEVNUExBVEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19DT05GTElDVF9CRVRXRUVOX1hTTFNUUklQU1BBQ0VfQU5EX1hTTFBSRVNFUlZFU1BBQ0UgPSAiV0dfQ09ORkxJQ1RfQkVUV0VFTl9YU0xTVFJJUFNQQUNFX0FORF9YU0xQUkVTRVJWRVNQIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfQVRUUklCX05PVF9IQU5ETEVEID0gIldHX0FUVFJJQl9OT1RfSEFORExFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX05PX0RFQ0lNQUxGT1JNQVRfREVDTEFSQVRJT04gPQotICAgICAgICAgIldHX05PX0RFQ0lNQUxGT1JNQVRfREVDTEFSQVRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19PTERfWFNMVF9OUyA9ICJXR19PTERfWFNMVF9OUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX09ORV9ERUZBVUxUX1hTTERFQ0lNQUxGT1JNQVRfQUxMT1dFRCA9Ci0gICAgICAgICAiV0dfT05FX0RFRkFVTFRfWFNMREVDSU1BTEZPUk1BVF9BTExPV0VEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfWFNMREVDSU1BTEZPUk1BVF9OQU1FU19NVVNUX0JFX1VOSVFVRSA9Ci0gICAgICAgICAiV0dfWFNMREVDSU1BTEZPUk1BVF9OQU1FU19NVVNUX0JFX1VOSVFVRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0lMTEVHQUxfQVRUUklCVVRFID0gIldHX0lMTEVHQUxfQVRUUklCVVRFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfQ09VTERfTk9UX1JFU09MVkVfUFJFRklYID0KLSAgICAgICAgICJXR19DT1VMRF9OT1RfUkVTT0xWRV9QUkVGSVgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19TVFlMRVNIRUVUX1JFUVVJUkVTX1ZFUlNJT05fQVRUUklCID0KLSAgICAgICAgICJXR19TVFlMRVNIRUVUX1JFUVVJUkVTX1ZFUlNJT05fQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfSUxMRUdBTF9BVFRSSUJVVEVfTkFNRSA9Ci0gICAgICAgICAiV0dfSUxMRUdBTF9BVFRSSUJVVEVfTkFNRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0lMTEVHQUxfQVRUUklCVVRFX1ZBTFVFID0KLSAgICAgICAgICJXR19JTExFR0FMX0FUVFJJQlVURV9WQUxVRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0VNUFRZX1NFQ09ORF9BUkcgPSAiV0dfRU1QVFlfU0VDT05EX0FSRyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX1BST0NFU1NJTkdJTlNUUlVDVElPTl9OQU1FX0NBTlRfQkVfWE1MID0KLSAgICAgICAgICJXR19QUk9DRVNTSU5HSU5TVFJVQ1RJT05fTkFNRV9DQU5UX0JFX1hNTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX1BST0NFU1NJTkdJTlNUUlVDVElPTl9OT1RWQUxJRF9OQ05BTUUgPQotICAgICAgICAgIldHX1BST0NFU1NJTkdJTlNUUlVDVElPTl9OT1RWQUxJRF9OQ05BTUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19JTExFR0FMX0FUVFJJQlVURV9QT1NJVElPTiA9Ci0gICAgICAgICAiV0dfSUxMRUdBTF9BVFRSSUJVVEVfUE9TSVRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIgPQotICAgICAgICAgIk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiI7Ci0KLSAgLyoKLSAgICogTm93IGZpbGwgaW4gdGhlIG1lc3NhZ2UgdGV4dC4KLSAgICogVGhlbiBmaWxsIGluIHRoZSBtZXNzYWdlIHRleHQgZm9yIHRoYXQgbWVzc2FnZSBjb2RlIGluIHRoZQotICAgKiBhcnJheS4gVXNlIHRoZSBuZXcgZXJyb3IgY29kZSBhcyB0aGUgaW5kZXggaW50byB0aGUgYXJyYXkuCi0gICAqLwotCi0gIC8vIEVycm9yIG1lc3NhZ2VzLi4uCi0KLSAgLyoqIEdldCB0aGUgbG9va3VwIHRhYmxlIGZvciBlcnJvciBtZXNzYWdlcy4KLSAgICAqCi0gICAgKiBAcmV0dXJuIFRoZSBtZXNzYWdlIGxvb2t1cCB0YWJsZS4KLSAgICAqLwotICBwdWJsaWMgT2JqZWN0W11bXSBnZXRDb250ZW50cygpCi0gIHsKLSAgICAgIHJldHVybiBuZXcgT2JqZWN0W11bXSB7Ci0KLSAgLyoqIEVycm9yIG1lc3NhZ2UgSUQgdGhhdCBoYXMgYSBudWxsIG1lc3NhZ2UsIGJ1dCB0YWtlcyBpbiBhIHNpbmdsZSBvYmplY3QuICAgICovCi0gIHsiRVIwMDAwIiAsICJ7MH0iIH0sCi0KLSAgICB7IEVSX05PX0NVUkxZQlJBQ0UsCi0gICAgICAiRmVsOiBVdHRyeWNrIGthbiBpbnRlIGlubmVoXHUwMEU1bGxhICd7JyJ9LAotCi0gICAgeyBFUl9JTExFR0FMX0FUVFJJQlVURSAsCi0gICAgICJ7MH0gaGFyIGV0dCBvdGlsbFx1MDBFNXRldCBhdHRyaWJ1dDogezF9In0sCi0KLSAge0VSX05VTExfU09VUkNFTk9ERV9BUFBMWUlNUE9SVFMgLAotICAgICAgInNvdXJjZU5vZGUgXHUwMEU0ciBudWxsIGkgeHNsOmFwcGx5LWltcG9ydHMhIn0sCi0KLSAge0VSX0NBTk5PVF9BREQsCi0gICAgICAiS2FuIGludGUgYWRkZXJhIHswfSB0aWxsIHsxfSJ9LAotCi0gICAgeyBFUl9OVUxMX1NPVVJDRU5PREVfSEFORExFQVBQTFlURU1QTEFURVMsCi0gICAgICAic291cmNlTm9kZSBcdTAwRTRyIG51bGwgaSBoYW5kbGVBcHBseVRlbXBsYXRlc0luc3RydWN0aW9uISJ9LAotCi0gICAgeyBFUl9OT19OQU1FX0FUVFJJQiwKLSAgICAgInswfSBtXHUwMEU1c3RlIGhhIGV0dCBuYW1uYXR0cmlidXQuIn0sCi0KLSAgICB7RVJfVEVNUExBVEVfTk9UX0ZPVU5ELAotICAgICAiSGl0dGFkZSBpbnRlIG1hbGxlbiBtZWQgbmFtbmV0OiB7MH0ifSwKLQotICAgIHtFUl9DQU5UX1JFU09MVkVfTkFNRV9BVlQsCi0gICAgICAiS3VuZGUgaW50ZSBtYXRjaGEgbmFtbi1BVlQgaSB4c2w6Y2FsbC10ZW1wbGF0ZS4ifSwKLQotICAgIHtFUl9SRVFVSVJFU19BVFRSSUIsCi0gICAgICJ7MH0ga3JcdTAwRTR2ZXIgYXR0cmlidXQ6IHsxfSJ9LAotCi0gICAgeyBFUl9NVVNUX0hBVkVfVEVTVF9BVFRSSUIsCi0gICAgICAiezB9IG1cdTAwRTVzdGUgaGEgZXR0ICcndGVzdCcnLWF0dHJpYnV0LiJ9LAotCi0gICAge0VSX0JBRF9WQUxfT05fTEVWRUxfQVRUUklCLAotICAgICAgIkZlbGFrdGlndCB2XHUwMEU0cmRlIGkgbml2XHUwMEU1YXR0cmlidXQ6IHswfSJ9LAotCi0gICAge0VSX1BST0NFU1NJTkdJTlNUUlVDVElPTl9OQU1FX0NBTlRfQkVfWE1MLAotICAgICAgIk5hbW4gcFx1MDBFNSBiZWFyYmV0bmluZ3NpbnN0cnVrdGlvbiBrYW4gaW50ZSB2YXJhICd4bWwnIn0sCi0KLSAgICB7IEVSX1BST0NFU1NJTkdJTlNUUlVDVElPTl9OT1RWQUxJRF9OQ05BTUUsCi0gICAgICAiTmFtbiBwXHUwMEU1IGJlYXJiZXRuaW5nc2luc3RydWt0aW9uIG1cdTAwRTVzdGUgdmFyYSBldHQgZ2lsdGlndCBOQ05hbWU6IHswfSJ9LAotCi0gICAgeyBFUl9ORUVEX01BVENIX0FUVFJJQiwKLSAgICAgICJ7MH0gbVx1MDBFNXN0ZSBoYSBldHQgbWF0Y2huaW5nc2F0dHJpYnV0IG5cdTAwRTRyIGRldCBhbmdlciBldHQgbFx1MDBFNGdlLiJ9LAotCi0gICAgeyBFUl9ORUVEX05BTUVfT1JfTUFUQ0hfQVRUUklCLAotICAgICAgInswfSBrclx1MDBFNHZlciBhbnRpbmdlbiBldHQgbmFtbiBlbGxlciBldHQgbWF0Y2huaW5nc2F0dHJpYnV0LiJ9LAotCi0gICAge0VSX0NBTlRfUkVTT0xWRV9OU1BSRUZJWCwKLSAgICAgICJLYW4gaW50ZSBtYXRjaGEgcHJlZml4IGZcdTAwRjZyIG5hbW5yeW1kOiB7MH0ifSwKLQotICAgIHsgRVJfSUxMRUdBTF9WQUxVRSwKLSAgICAgInhtbDpzcGFjZSBoYXIgZXR0IG90aWxsXHUwMEU1dGV0IHZcdTAwRTRyZGU6IHswfSJ9LAotCi0gICAgeyBFUl9OT19PV05FUkRPQywKLSAgICAgICJVbmRlcm9yZG5hZCBub2QgaGFyIGluZ2V0IFx1MDBFNGdhcmRva3VtZW50ISJ9LAotCi0gICAgeyBFUl9FTEVNVEVNUExBVEVFTEVNX0VSUiwKLSAgICAgIkVsZW1UZW1wbGF0ZUVsZW1lbnQtZmVsOiB7MH0ifSwKLQotICAgIHsgRVJfTlVMTF9DSElMRCwKLSAgICAgIkZcdTAwRjZyc1x1MDBGNmtlciBsXHUwMEU0Z2dhIHRpbGwgZW4gbnVsbC11bmRlcm9yZG5hZCEifSwKLQotICAgIHsgRVJfTkVFRF9TRUxFQ1RfQVRUUklCLAotICAgICAiezB9IGtyXHUwMEU0dmVyIGV0dCBzZWxlY3QtYXR0cmlidXQuIn0sCi0KLSAgICB7IEVSX05FRURfVEVTVF9BVFRSSUIgLAotICAgICAgInhzbDp3aGVuIG1cdTAwRTVzdGUgaGEgZXR0ICd0ZXN0Jy1hdHRyaWJ1dC4ifSwKLQotICAgIHsgRVJfTkVFRF9OQU1FX0FUVFJJQiwKLSAgICAgICJ4c2w6d2l0aC1wYXJhbWV0ZXJuIG1cdTAwRTVzdGUgaGEgZXR0ICduYW1uJy1hdHRyaWJ1dC4ifSwKLQotICAgIHsgRVJfTk9fQ09OVEVYVF9PV05FUkRPQywKLSAgICAgICJjb250ZXh0IGhhciBpbmdldCBcdTAwRTRnYXJkb2t1bWVudCEifSwKLQotICAgIHtFUl9DT1VMRF9OT1RfQ1JFQVRFX1hNTF9QUk9DX0xJQUlTT04sCi0gICAgICAiS3VuZGUgaW50ZSBza2FwYSBYTUwgVHJhbnNmb3JtZXJGYWN0b3J5IExpYWlzb246IHswfSJ9LAotCi0gICAge0VSX1BST0NFU1NfTk9UX1NVQ0NFU1NGVUwsCi0gICAgICAiWGFsYW46IFByb2Nlc3NlbiB1dGZcdTAwRjZyZGVzIGludGUuIn0sCi0KLSAgICB7IEVSX05PVF9TVUNDRVNTRlVMLAotICAgICAiWGFsYW46IHV0Zlx1MDBGNnJkZXMgaW50ZS4ifSwKLQotICAgIHsgRVJfRU5DT0RJTkdfTk9UX1NVUFBPUlRFRCwKLSAgICAgIktvZG5pbmdlbiBzdFx1MDBGNmRzIGludGU6IHswfSJ9LAotCi0gICAge0VSX0NPVUxEX05PVF9DUkVBVEVfVFJBQ0VMSVNURU5FUiwKLSAgICAgICJLdW5kZSBpbnRlIFRyYWNlTGlzdGVuZXI6IHswfSJ9LAotCi0gICAge0VSX0tFWV9SRVFVSVJFU19OQU1FX0FUVFJJQiwKLSAgICAgICJ4c2w6a2V5IGtyXHUwMEU0dmVyIGV0dCAnbmFtbictYXR0cmlidXQhIn0sCi0KLSAgICB7IEVSX0tFWV9SRVFVSVJFU19NQVRDSF9BVFRSSUIsCi0gICAgICAieHNsOmtleSBrclx1MDBFNHZlciBldHQgJ21hdGNobmluZyctYXR0cmlidXQhIn0sCi0KLSAgICB7IEVSX0tFWV9SRVFVSVJFU19VU0VfQVRUUklCLAotICAgICAgInhzbDprZXkga3JcdTAwRTR2ZXIgZXR0ICdhbnZcdTAwRTRuZCctYXR0cmlidXQhIn0sCi0KLSAgICB7IEVSX1JFUVVJUkVTX0VMRU1FTlRTX0FUVFJJQiwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIHswfSBrclx1MDBFNHZlciBldHQgJydlbGVtZW50JyctYXR0cmlidXQhIn0sCi0KLSAgICB7IEVSX01JU1NJTkdfUFJFRklYX0FUVFJJQiwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpICcncHJlZml4JycgZlx1MDBGNnIgezB9LWF0dHJpYnV0IHNha25hcyJ9LAotCi0gICAgeyBFUl9CQURfU1RZTEVTSEVFVF9VUkwsCi0gICAgICJGb3JtYXRtYWxsLVVSTCBcdTAwRTRyIGZlbGFrdGlnOiB7MH0ifSwKLQotICAgIHsgRVJfRklMRV9OT1RfRk9VTkQsCi0gICAgICJGb3JtYXRtYWxsZmlsIGt1bmRlIGludGUgaGl0dGFzOiB7MH0ifSwKLQotICAgIHsgRVJfSU9FWENFUFRJT04sCi0gICAgICAiRmljayBJTy11bmRhbnRhZyBtZWQgZm9ybWF0bWFsbGZpbDogezB9In0sCi0KLSAgICB7IEVSX05PX0hSRUZfQVRUUklCLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgSGl0dGFkZSBpbnRlIGhyZWYtYXR0cmlidXQgZlx1MDBGNnIgezB9In0sCi0KLSAgICB7IEVSX1NUWUxFU0hFRVRfSU5DTFVERVNfSVRTRUxGLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgezB9IGlua2x1ZGVyYXIsIGRpcmVrdCBlbGxlciBpbmRpcmVrdCwgc2lnIHNqXHUwMEU0bHYhIn0sCi0KLSAgICB7IEVSX1BST0NFU1NJTkNMVURFX0VSUk9SLAotICAgICAgIlN0eWxlc2hlZXRIYW5kbGVyLnByb2Nlc3NJbmNsdWRlLWZlbCwgezB9In0sCi0KLSAgICB7IEVSX01JU1NJTkdfTEFOR19BVFRSSUIsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSAnJ2xhbmcnJyBmXHUwMEY2ciB7MH0tYXR0cmlidXQgc2FrbmFzIn0sCi0KLSAgICB7IEVSX01JU1NJTkdfQ09OVEFJTkVSX0VMRU1FTlRfQ09NUE9ORU5ULAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgezB9LWVsZW1lbnQ/PyBcdTAwRTRyIGZlbHBsYWNlcmF0IENvbnRhaW5lci1lbGVtZW50ZXQgJydjb21wb25lbnQnJyBzYWtuYXMifSwKLQotICAgIHsgRVJfQ0FOX09OTFlfT1VUUFVUX1RPX0VMRU1FTlQsCi0gICAgICAiS2FuIGVuZGFzdCBza2lja2EgdXRkYXRhIHRpbGwgZXR0IEVsZW1lbnQsIGV0dCBEb2N1bWVudEZyYWdtZW50LCBldHQgRG9jdW1lbnQgZWxsZXIgZW4gUHJpbnRXcml0ZXIuIn0sCi0KLSAgICB7IEVSX1BST0NFU1NfRVJST1IsCi0gICAgICJTdHlsZXNoZWV0Um9vdC5wcm9jZXNzLWZlbCJ9LAotCi0gICAgeyBFUl9VTklNUExOT0RFX0VSUk9SLAotICAgICAiVW5JbXBsTm9kZS1mZWw6IHswfSJ9LAotCi0gICAgeyBFUl9OT19TRUxFQ1RfRVhQUkVTU0lPTiwKLSAgICAgICJGZWwhIEhpdHRhZGUgaW50ZSB4cGF0aCBzZWxlY3QtdXR0cnljayAoLXNlbGVjdCkuIn0sCi0KLSAgICB7IEVSX0NBTk5PVF9TRVJJQUxJWkVfWFNMUFJPQ0VTU09SLAotICAgICAgIkthbiBpbnRlIHNlcmlhbGlzZXJhIGVuIFhTTFByb2Nlc3NvciEifSwKLQotICAgIHsgRVJfTk9fSU5QVVRfU1RZTEVTSEVFVCwKLSAgICAgICJGb3JtYXRtYWxsaW5kYXRhIGVqIGFuZ2l2ZW4hIn0sCi0KLSAgICB7IEVSX0ZBSUxFRF9QUk9DRVNTX1NUWUxFU0hFRVQsCi0gICAgICAiS3VuZGUgaW50ZSBiZWhhbmRsYSBmb3JtYXRtYWxsISJ9LAotCi0gICAgeyBFUl9DT1VMRE5UX1BBUlNFX0RPQywKLSAgICAgIkt1bmRlIGludGUgdG9sa2EgZG9rdW1lbnRldCB7MH0hIn0sCi0KLSAgICB7IEVSX0NPVUxETlRfRklORF9GUkFHTUVOVCwKLSAgICAgIkhpdHRhZGUgaW50ZSBmcmFnbWVudDogezB9In0sCi0KLSAgICB7IEVSX05PREVfTk9UX0VMRU1FTlQsCi0gICAgICAiTm9kIHNvbSBwZWthZGVzIHBcdTAwRTUgYXYgZnJhZ21lbnQtaWRlbnRpZmllcmFyZSB2YXIgaW50ZSBldHQgZWxlbWVudDogezB9In0sCi0KLSAgICB7IEVSX0ZPUkVBQ0hfTkVFRF9NQVRDSF9PUl9OQU1FX0FUVFJJQiwKLSAgICAgICJmb3ItZWFjaCBrclx1MDBFNHZlciBhbnRpbmdlbiBlbiBtYXRjaG5pbmcgZWxsZXIgZXR0IG5hbW5hdHRyaWJ1dCJ9LAotCi0gICAgeyBFUl9URU1QTEFURVNfTkVFRF9NQVRDSF9PUl9OQU1FX0FUVFJJQiwKLSAgICAgICJ0ZW1wbGF0ZXMga3JcdTAwRTR2ZXIgYW50aW5nZW4gZW4gbWF0Y2huaW5nIGVsbGVyIGV0dCBuYW1uYXR0cmlidXQifSwKLQotICAgIHsgRVJfTk9fQ0xPTkVfT0ZfRE9DVU1FTlRfRlJBRywKLSAgICAgICJJbmdlbiBrbG9uIGF2IGV0dCBkb2t1bWVudGZyYWdtZW50ISJ9LAotCi0gICAgeyBFUl9DQU5UX0NSRUFURV9JVEVNLAotICAgICAgIkthbiBpbnRlIHNrYXBhIGVsZW1lbnQgaSByZXN1bHRhdHRyXHUwMEU0ZDogezB9In0sCi0KLSAgICB7IEVSX1hNTFNQQUNFX0lMTEVHQUxfVkFMVUUsCi0gICAgICAieG1sOnNwYWNlIGkga1x1MDBFNGxsLVhNTCBoYXIgZXR0IG90aWxsXHUwMEU1dGV0IHZcdTAwRTRyZGU6IHswfSJ9LAotCi0gICAgeyBFUl9OT19YU0xLRVlfREVDTEFSQVRJT04sCi0gICAgICAiRGV0IGZpbm5zIGluZ2VuIHhzbDprZXktZGVrbGFyYXRpb24gZlx1MDBGNnIgezB9ISJ9LAotCi0gICAgeyBFUl9DQU5UX0NSRUFURV9VUkwsCi0gICAgICJGZWwhIEthbiBpbnRlIHNrYXBhIFVSTCBmXHUwMEY2cjogezB9In0sCi0KLSAgICB7IEVSX1hTTEZVTkNUSU9OU19VTlNVUFBPUlRFRCwKLSAgICAgInhzbDpmdW5jdGlvbnMgc3RcdTAwRjZkcyBpbnRlIn0sCi0KLSAgICB7IEVSX1BST0NFU1NPUl9FUlJPUiwKLSAgICAgIlhTTFQgVHJhbnNmb3JtZXJGYWN0b3J5LWZlbCJ9LAotCi0gICAgeyBFUl9OT1RfQUxMT1dFRF9JTlNJREVfU1RZTEVTSEVFVCwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIHswfSBcdTAwRTRyIGludGUgdGlsbFx1MDBFNXRlbiBpbm5lIGkgZW4gZm9ybWF0bWFsbCEifSwKLQotICAgIHsgRVJfUkVTVUxUTlNfTk9UX1NVUFBPUlRFRCwKLSAgICAgICJyZXN1bHQtbnMgc3RcdTAwRjZkcyBpbnRlIGxcdTAwRTRuZ3JlISBBbnZcdTAwRTRuZCB4c2w6b3V0cHV0IGlzdFx1MDBFNGxsZXQuIn0sCi0KLSAgICB7IEVSX0RFRkFVTFRTUEFDRV9OT1RfU1VQUE9SVEVELAotICAgICAgImRlZmF1bHQtc3BhY2Ugc3RcdTAwRjZkcyBpbnRlIGxcdTAwRTRuZ3JlISBBbnZcdTAwRTRuZCB4c2w6c3RyaXAtc3BhY2UgZWxsZXIgeHNsOnByZXNlcnZlLXNwYWNlIGlzdFx1MDBFNGxsZXQuIn0sCi0KLSAgICB7IEVSX0lOREVOVFJFU1VMVF9OT1RfU1VQUE9SVEVELAotICAgICAgImluZGVudC1yZXN1bHQgc3RcdTAwRjZkcyBpbnRlIGxcdTAwRTRuZ3JlISBBbnZcdTAwRTRuZCB4c2w6b3V0cHV0IGlzdFx1MDBFNGxsZXQuIn0sCi0KLSAgICB7IEVSX0lMTEVHQUxfQVRUUklCLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgezB9IGhhciBldHQgb3RpbGxcdTAwRTV0ZXQgYXR0cmlidXQ6IHsxfSJ9LAotCi0gICAgeyBFUl9VTktOT1dOX1hTTF9FTEVNLAotICAgICAiT2tcdTAwRTRudCBYU0wtZWxlbWVudDogezB9In0sCi0KLSAgICB7IEVSX0JBRF9YU0xTT1JUX1VTRSwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIHhzbDpzb3J0IGthbiBlbmRhc3QgYW52XHUwMEU0bmRhcyBtZWQgeHNsOmFwcGx5LXRlbXBsYXRlcyBlbGxlciB4c2w6Zm9yLWVhY2guIn0sCi0KLSAgICB7IEVSX01JU1BMQUNFRF9YU0xXSEVOLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgZmVscGxhY2VyYWRlIHhzbDp3aGVuISJ9LAotCi0gICAgeyBFUl9YU0xXSEVOX05PVF9QQVJFTlRFRF9CWV9YU0xDSE9PU0UsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSB4c2w6d2hlbiBoXHUwMEU0cnN0YW1tYXIgaW50ZSBmclx1MDBFNW4geHNsOmNob29zZSEifSwKLQotICAgIHsgRVJfTUlTUExBQ0VEX1hTTE9USEVSV0lTRSwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIGZlbHBsYWNlcmFkZSB4c2w6b3RoZXJ3aXNlISJ9LAotCi0gICAgeyBFUl9YU0xPVEhFUldJU0VfTk9UX1BBUkVOVEVEX0JZX1hTTENIT09TRSwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIHhzbDpvdGhlcndpc2UgaFx1MDBFNHJzdGFtbWFyIGludGUgZnJcdTAwRTVuIHhzbDpjaG9vc2UhIn0sCi0KLSAgICB7IEVSX05PVF9BTExPV0VEX0lOU0lERV9URU1QTEFURSwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIHswfSBcdTAwRTRyIGludGUgdGlsbFx1MDBFNXRlbiBpbm5lIGkgZW4gbWFsbCEifSwKLQotICAgIHsgRVJfVU5LTk9XTl9FWFRfTlNfUFJFRklYLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgb2tcdTAwRTRudCBuYW1ucnltZHNwcmVmaXggezF9IGZcdTAwRjZyIHRpbGxcdTAwRTRnZyB7MH0ifSwKLQotICAgIHsgRVJfSU1QT1JUU19BU19GSVJTVF9FTEVNLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgSW1wb3J0cyBrYW4gZW5kYXN0IGZcdTAwRjZyZWtvbW1hIHNvbSBkZSBmXHUwMEY2cnN0YSBlbGVtZW50ZW4gaSBmb3JtYXRtYWxsZW4hIn0sCi0KLSAgICB7IEVSX0lNUE9SVElOR19JVFNFTEYsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSB7MH0gaW1wb3J0ZXJhciwgZGlyZWt0IGVsbGVyIGluZGlyZWt0LCBzaWcgc2pcdTAwRTRsdiEifSwKLQotICAgIHsgRVJfWE1MU1BBQ0VfSUxMRUdBTF9WQUwsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSB4bWw6c3BhY2UgaGFyIGV0dCBvdGlsbFx1MDBFNXRldCB2XHUwMEU0cmRlOiB7MH0ifSwKLQotICAgIHsgRVJfUFJPQ0VTU1NUWUxFU0hFRVRfTk9UX1NVQ0NFU1NGVUwsCi0gICAgICAicHJvY2Vzc1N0eWxlc2hlZXQgdXRmXHUwMEY2cmRlcyBpbnRlISJ9LAotCi0gICAgeyBFUl9TQVhfRVhDRVBUSU9OLAotICAgICAiU0FYLXVuZGFudGFnIn0sCi0KLS8vICBhZGQgdGhpcyBtZXNzYWdlIHRvIGZpeCBidWcgMjE0NzgKLSAgICB7IEVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQsCi0gICAgICJGdW5rdGlvbmVuIHN0XHUwMEY2ZHMgaW50ZSEifSwKLQotICAgIHsgRVJfWFNMVF9FUlJPUiwKLSAgICAgIlhTTFQtZmVsIn0sCi0KLSAgICB7IEVSX0NVUlJFTkNZX1NJR05fSUxMRUdBTCwKLSAgICAgICJ2YWx1dGF0ZWNrZW4gXHUwMEU0ciBpbnRlIHRpbGxcdTAwRTV0ZXQgaSBmb3JtYXRtXHUwMEY2bnN0ZXJzdHJcdTAwRTRuZyJ9LAotCi0gICAgeyBFUl9ET0NVTUVOVF9GVU5DVElPTl9JTlZBTElEX0lOX1NUWUxFU0hFRVRfRE9NLAotICAgICAgIkRva3VtZW50ZnVua3Rpb24gc3RcdTAwRjZkcyBpbnRlIGkgU3R5bGVzaGVldCBET00hIn0sCi0KLSAgICB7IEVSX0NBTlRfUkVTT0xWRV9QUkVGSVhfT0ZfTk9OX1BSRUZJWF9SRVNPTFZFUiwKLSAgICAgICJLYW4gaW50ZSBtYXRjaGEgcHJlZml4IG1lZCBtYXRjaG5pbmcgc29tIHNha25hciBwcmVmaXghIn0sCi0KLSAgICB7IEVSX1JFRElSRUNUX0NPVUxETlRfR0VUX0ZJTEVOQU1FLAotICAgICAgIlJlZGlyZWN0LXRpbGxcdTAwRTRnZzogSGl0dGFkZSBpbnRlIGZpbG5hbW4gLSBmaWwgZWxsZXIgdmFsYXR0cmlidXQgbVx1MDBFNXN0ZSByZXR1cm5lcmEgZ2lsdGlnIHN0clx1MDBFNG5nLiJ9LAotCi0gICAgeyBFUl9DQU5OT1RfQlVJTERfRk9STUFUVEVSTElTVEVORVJfSU5fUkVESVJFQ1QsCi0gICAgICAiS2FuIGludGUgYnlnZ2EgRm9ybWF0dGVyTGlzdGVuZXIgaSBSZWRpcmVjdC10aWxsXHUwMEU0Z2chIn0sCi0KLSAgICB7IEVSX0lOVkFMSURfUFJFRklYX0lOX0VYQ0xVREVSRVNVTFRQUkVGSVgsCi0gICAgICAiUHJlZml4IGkgZXhjbHVkZS1yZXN1bHQtcHJlZml4ZXMgXHUwMEU0ciBpbnRlIGdpbHRpZ3Q6IHswfSJ9LAotCi0gICAgeyBFUl9NSVNTSU5HX05TX1VSSSwKLSAgICAgICJOYW1ucnltZHMtVVJJIHNha25hcyBmXHUwMEY2ciBhbmdpdm5hIHByZWZpeCJ9LAotCi0gICAgeyBFUl9NSVNTSU5HX0FSR19GT1JfT1BUSU9OLAotICAgICAgIkFyZ3VtZW50IHNha25hcyBmXHUwMEY2ciBhbHRlcm5hdGl2ZXQ6IHswfSJ9LAotCi0gICAgeyBFUl9JTlZBTElEX09QVElPTiwKLSAgICAgIk9naWx0aWd0IGFsdGVybmF0aXY6IHswfSJ9LAotCi0gICAgeyBFUl9NQUxGT1JNRURfRk9STUFUX1NUUklORywKLSAgICAgIkZlbGFrdGlndCB1dGZvcm1hZCBmb3JtYXRzdHJcdTAwRTRuZzogezB9In0sCi0KLSAgICB7IEVSX1NUWUxFU0hFRVRfUkVRVUlSRVNfVkVSU0lPTl9BVFRSSUIsCi0gICAgICAieHNsOnN0eWxlc2hlZXQga3JcdTAwRTR2ZXIgZXR0ICd2ZXJzaW9uJy1hdHRyaWJ1dCEifSwKLQotICAgIHsgRVJfSUxMRUdBTF9BVFRSSUJVVEVfVkFMVUUsCi0gICAgICAiQXR0cmlidXQ6IHswfSBoYXIgZXR0IG90aWxsXHUwMEU1dGV0IHZcdTAwRTRyZGU6IHsxfSJ9LAotCi0gICAgeyBFUl9DSE9PU0VfUkVRVUlSRVNfV0hFTiwKLSAgICAgInhzbDpjaG9vc2Uga3JcdTAwRTR2ZXIgeHNsOndoZW4ifSwKLQotICAgIHsgRVJfTk9fQVBQTFlfSU1QT1JUX0lOX0ZPUl9FQUNILAotICAgICAgInhzbDphcHBseS1pbXBvcnRzIGludGUgdGlsbFx1MDBFNXRldCBpIHhzbDpmb3ItZWFjaCJ9LAotCi0gICAgeyBFUl9DQU5UX1VTRV9EVE1fRk9SX09VVFBVVCwKLSAgICAgICJLYW4gaW50ZSBhbnZcdTAwRTRuZGEgRFRNTGlhaXNvbiB0aWxsIGVuIERPTSB1dGRhdGFub2QuLi4gc2tpY2thIGVuIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5ET00ySGVscGVyIGlzdFx1MDBFNGxsZXQhIn0sCi0KLSAgICB7IEVSX0NBTlRfVVNFX0RUTV9GT1JfSU5QVVQsCi0gICAgICAiS2FuIGludGUgYW52XHUwMEU0bmRhIERUTUxpYWlzb24gdGlsbCBlbiBET00gaW5kYXRhbm9kLi4uIHNraWNrYSBlbiBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuRE9NMkhlbHBlciBpc3RcdTAwRTRsbGV0ISJ9LAotCi0gICAgeyBFUl9DQUxMX1RPX0VYVF9GQUlMRUQsCi0gICAgICAiQW5yb3AgdGlsbCB0aWxsXHUwMEU0Z2dzZWxlbWVudCB1dGZcdTAwRjZyZGVzIGludGU6IHswfSJ9LAotCi0gICAgeyBFUl9QUkVGSVhfTVVTVF9SRVNPTFZFLAotICAgICAgIlByZWZpeCBtXHUwMEU1c3RlIG1hdGNoYXMgdGlsbCBlbiBuYW1ucnltZDogezB9In0sCi0KLSAgICB7IEVSX0lOVkFMSURfVVRGMTZfU1VSUk9HQVRFLAotICAgICAgIk9naWx0aWd0IFVURi0xNi1zdXJyb2dhdCB1cHB0XHUwMEU0Y2t0OiB7MH0gPyJ9LAotCi0gICAgeyBFUl9YU0xBVFRSU0VUX1VTRURfSVRTRUxGLAotICAgICAgInhzbDphdHRyaWJ1dGUtc2V0IHswfSBhbnZcdTAwRTRuZGUgc2lnIHNqXHUwMEU0bHZ0LCB2aWxrZXQga29tbWVyIGF0dCBvcnNha2EgZW4gb1x1MDBFNG5kbGlnIHNsaW5nYS4ifSwKLQotICAgIHsgRVJfQ0FOTk9UX01JWF9YRVJDRVNET00sCi0gICAgICAiS2FuIGludGUgYmxhbmRhIGlja2UtWGVyY2VzLURPTS1pbmRhdGEgbWVkIFhlcmNlcy1ET00tdXRkYXRhISJ9LAotCi0gICAgeyBFUl9UT09fTUFOWV9MSVNURU5FUlMsCi0gICAgICAiYWRkVHJhY2VMaXN0ZW5lcnNUb1N0eWxlc2hlZXQgLSBUb29NYW55TGlzdGVuZXJzRXhjZXB0aW9uIn0sCi0KLSAgICB7IEVSX0lOX0VMRU1URU1QTEFURUVMRU1fUkVBRE9CSkVDVCwKLSAgICAgICJJIEVsZW1UZW1wbGF0ZUVsZW1lbnQucmVhZE9iamVjdDogezB9In0sCi0KLSAgICB7IEVSX0RVUExJQ0FURV9OQU1FRF9URU1QTEFURSwKLSAgICAgICJIaXR0YWRlIGZsZXIgXHUwMEU0biBlbiBtYWxsIG1lZCBuYW1uZXQ6IHswfSJ9LAotCi0gICAgeyBFUl9JTlZBTElEX0tFWV9DQUxMLAotICAgICAgIk9naWx0aWd0IGZ1bmt0aW9uc2Fucm9wOiByZWt1cnNpdmEga2V5KCktYW5yb3AgXHUwMEU0ciBpbnRlIHRpbGxcdTAwRTV0bmEifSwKLQotICAgIHsgRVJfUkVGRVJFTkNJTkdfSVRTRUxGLAotICAgICAgIlZhcmlhYmVsbiB7MH0gcmVmZXJlcmFyLCBkaXJla3QgZWxsZXIgaW5kaXJla3QsIHRpbGwgc2lnIHNqXHUwMEU0bHYhIn0sCi0KLSAgICB7IEVSX0lMTEVHQUxfRE9NU09VUkNFX0lOUFVULAotICAgICAgIkluZGF0YW5vZGVuIHRpbGwgZW4gRE9NU291cmNlIGZcdTAwRjZyIG5ld1RlbXBsYXRlcyBmXHUwMEU1ciBpbnRlIHZhcmEgbnVsbCEifSwKLQotICAgIHsgRVJfQ0xBU1NfTk9UX0ZPVU5EX0ZPUl9PUFRJT04sCi0gICAgICAgICJLbGFzc2ZpbCBmXHUwMEY2ciBhbHRlcm5hdGl2IHswfSBzYWtuYXMifSwKLQotICAgIHsgRVJfUkVRVUlSRURfRUxFTV9OT1RfRk9VTkQsCi0gICAgICAgICJPYmxpZ2F0b3Jpc2thIGVsZW1lbnQgaGl0dGFkZXMgaW50ZTogezB9In0sCi0KLSAgICB7IEVSX0lOUFVUX0NBTk5PVF9CRV9OVUxMLAotICAgICAgICAiSW5wdXRTdHJlYW0ga2FuIGludGUgdmFyYSBudWxsIn0sCi0KLSAgICB7IEVSX1VSSV9DQU5OT1RfQkVfTlVMTCwKLSAgICAgICAgIlVSSSBrYW4gaW50ZSB2YXJhIG51bGwifSwKLQotICAgIHsgRVJfRklMRV9DQU5OT1RfQkVfTlVMTCwKLSAgICAgICAgIkZpbCBrYW4gaW50ZSB2YXJhIG51bGwifSwKLQotICAgIHsgRVJfU09VUkNFX0NBTk5PVF9CRV9OVUxMLAotICAgICAgICAgICAgICAgICJJbnB1dFNvdXJjZSBrYW4gaW50ZSB2YXJhIG51bGwifSwKLQotICAgIHsgRVJfQ0FOTk9UX0lOSVRfQlNGTUdSLAotICAgICAgICAgICAgICAgICJLdW5kZSBpbnRlIGluaXRpZXJhIEJTRiBNYW5hZ2VyIn0sCi0KLSAgICB7IEVSX0NBTk5PVF9DTVBMX0VYVEVOU04sCi0gICAgICAgICAgICAgICAgIkt1bmRlIGludGUga29tcGlsZXJhIHRpbGxcdTAwRTRnZyJ9LAotCi0gICAgeyBFUl9DQU5OT1RfQ1JFQVRFX0VYVEVOU04sCi0gICAgICAiS3VuZGUgaW50ZSBza2FwYSB0aWxsXHUwMEU0Z2c6IHswfSBwXHUwMEU1IGdydW5kIGF2OiB7MX0ifSwKLQotICAgIHsgRVJfSU5TVEFOQ0VfTVRIRF9DQUxMX1JFUVVJUkVTLAotICAgICAgIkluc3RhbnNtZXRvZGFucm9wIHRpbGwgbWV0b2QgezB9IGtyXHUwMEU0dmVyIGVuIG9iamVrdGluc3RhbnMgc29tIGZcdTAwRjZyc3RhIGFyZ3VtZW50In0sCi0KLSAgICB7IEVSX0lOVkFMSURfRUxFTUVOVF9OQU1FLAotICAgICAgIk9naWx0aWd0IGVsZW1lbnRuYW1uIGFuZ2l2ZXQgezB9In0sCi0KLSAgICB7IEVSX0VMRU1FTlRfTkFNRV9NRVRIT0RfU1RBVElDLAotICAgICAgIkVsZW1lbnRuYW1ubWV0b2QgbVx1MDBFNXN0ZSB2YXJhIHN0YXRpc2sgezB9In0sCi0KLSAgICB7IEVSX0VYVEVOU0lPTl9GVU5DX1VOS05PV04sCi0gICAgICAgICAgICAgIlRpbGxcdTAwRTRnZ3NmdW5rdGlvbiB7MH0gOiB7MX0gXHUwMEU0ciBva1x1MDBFNG5kIn0sCi0KLSAgICB7IEVSX01PUkVfTUFUQ0hfQ09OU1RSVUNUT1IsCi0gICAgICAgICAgICAgIkZsZXIgXHUwMEU0biBlbiBiXHUwMEU0c3RhIG1hdGNobmluZyBmXHUwMEY2ciBrb25zdHJ1a3RvciBmXHUwMEY2ciB7MH0ifSwKLQotICAgIHsgRVJfTU9SRV9NQVRDSF9NRVRIT0QsCi0gICAgICAgICAgICAgIkZsZXIgXHUwMEU0biBlbiBiXHUwMEU0c3RhIG1hdGNobmluZyBmXHUwMEY2ciBtZXRvZCB7MH0ifSwKLQotICAgIHsgRVJfTU9SRV9NQVRDSF9FTEVNRU5ULAotICAgICAgICAgICAgICJGbGVyIFx1MDBFNG4gZW4gYlx1MDBFNHN0YSBtYXRjaG5pbmcgZlx1MDBGNnIgZWxlbWVudG1ldG9kIHswfSJ9LAotCi0gICAgeyBFUl9JTlZBTElEX0NPTlRFWFRfUEFTU0VELAotICAgICAgICAgICAgICJPZ2lsdGlnIGtvbnRleHQgc2tpY2thZCBmXHUwMEY2ciBhdHQgdXR2XHUwMEU0cmRlcmEgezB9In0sCi0KLSAgICB7IEVSX1BPT0xfRVhJU1RTLAotICAgICAgICAgICAgICJQb29sIGZpbm5zIHJlZGFuIn0sCi0KLSAgICB7IEVSX05PX0RSSVZFUl9OQU1FLAotICAgICAgICAgICAgICJJbmdldCBkcml2cnV0aW5zbmFtbiBhbmdpdmV0In0sCi0KLSAgICB7IEVSX05PX1VSTCwKLSAgICAgICAgICAgICAiSW5nZW4gVVJMIGFuZ2l2ZW4ifSwKLQotICAgIHsgRVJfUE9PTF9TSVpFX0xFU1NUSEFOX09ORSwKLSAgICAgICAgICAgICAiUG9vbHN0b3JsZWsgXHUwMEU0ciBtaW5kcmUgXHUwMEU0biBldHQhIn0sCi0KLSAgICB7IEVSX0lOVkFMSURfRFJJVkVSLAotICAgICAgICAgICAgICJPZ2lsdGlndCBkcml2cnV0aW5zbmFtbiBhbmdpdmV0ISJ9LAotCi0gICAgeyBFUl9OT19TVFlMRVNIRUVUUk9PVCwKLSAgICAgICAgICAgICAiSGl0dGFkZSBpbnRlIGZvcm1hdG1hbGxlbiByb3RlbiEifSwKLQotICAgIHsgRVJfSUxMRUdBTF9YTUxTUEFDRV9WQUxVRSwKLSAgICAgICAgICJPdGlsbFx1MDBFNXRldCB2XHUwMEU0cmRlIGZcdTAwRjZyIHhtbDpzcGFjZSJ9LAotCi0gICAgeyBFUl9QUk9DRVNTRlJPTU5PREVfRkFJTEVELAotICAgICAgICAgInByb2Nlc3NGcm9tTm9kZSB1dGZcdTAwRjZyZGVzIGludGUifSwKLQotICAgIHsgRVJfUkVTT1VSQ0VfQ09VTERfTk9UX0xPQUQsCi0gICAgICAgICJSZXN1cnNlbiBbIHswfSBdIGt1bmRlIGludGUgbGFkZGFzOiB7MX0gXG4gezJ9IFx0IHszfSJ9LAotCi0gICAgeyBFUl9CVUZGRVJfU0laRV9MRVNTVEhBTl9aRVJPLAotICAgICAgICAiQnVmZmVydHN0b3JsZWsgPD0wIn0sCi0KLSAgICB7IEVSX1VOS05PV05fRVJST1JfQ0FMTElOR19FWFRFTlNJT04sCi0gICAgICAgICJPa1x1MDBFNG50IGZlbCB2aWQgYW5yb3AgYXYgdGlsbFx1MDBFNGdnIn0sCi0KLSAgICB7IEVSX05PX05BTUVTUEFDRV9ERUNMLAotICAgICAgICAiUHJlZml4IHswfSBoYXIgaW5nZW4gbW90c3ZhcmFuZGUgbmFtbnJ5bWRzZGVrbGFyYXRpb24ifSwKLQotICAgIHsgRVJfRUxFTV9DT05URU5UX05PVF9BTExPV0VELAotICAgICAgICAiRWxlbWVudGlubmVoXHUwMEU1bGwgaW50ZSB0aWxsXHUwMEU1dGV0IGZcdTAwRjZyIGxhbmc9amF2YWNsYXNzIHswfSJ9LAotCi0gICAgeyBFUl9TVFlMRVNIRUVUX0RJUkVDVEVEX1RFUk1JTkFUSU9OLAotICAgICAgICAiQXZzbHV0bmluZyB2aWEgZm9ybWF0bWFsbCJ9LAotCi0gICAgeyBFUl9PTkVfT1JfVFdPLAotICAgICAgICAiMSBlbGxlciAyIn0sCi0KLSAgICB7IEVSX1RXT19PUl9USFJFRSwKLSAgICAgICAgIjIgZWxsZXIgMyJ9LAotCi0gICAgeyBFUl9DT1VMRF9OT1RfTE9BRF9SRVNPVVJDRSwKLSAgICAgICAgIkt1bmRlIGludGUgbGFkZGEgezB9IChrb250cm9sbGVyYSBDTEFTU1BBVEgpLCBhbnZcdTAwRTRuZGVyIG51IGVuYmFydCBzdGFuZGFyZHZcdTAwRTRyZGVuIn0sCi0KLSAgICB7IEVSX0NBTk5PVF9JTklUX0RFRkFVTFRfVEVNUExBVEVTLAotICAgICAgICAiS2FuIGludGUgaW5pdGllcmEgc3RhbmRhcmRtYWxsYXIifSwKLQotICAgIHsgRVJfUkVTVUxUX05VTEwsCi0gICAgICAgICJSZXN1bHQgYm9yZGUgaW50ZSB2YXJhIG51bGwifSwKLQotICAgIHsgRVJfUkVTVUxUX0NPVUxEX05PVF9CRV9TRVQsCi0gICAgICAgICJSZXN1bHQga3VuZGUgaW50ZSBzdFx1MDBFNGxsYXMgaW4ifSwKLQotICAgIHsgRVJfTk9fT1VUUFVUX1NQRUNJRklFRCwKLSAgICAgICAgIkluZ2VuIHV0ZGF0YSBhbmdpdmVuIn0sCi0KLSAgICB7IEVSX0NBTk5PVF9UUkFOU0ZPUk1fVE9fUkVTVUxUX1RZUEUsCi0gICAgICAgICJLYW4gaW50ZSBvbXZhbmRsYSB0aWxsIFJlc3VsdCBhdiB0eXAgezB9In0sCi0KLSAgICB7IEVSX0NBTk5PVF9UUkFOU0ZPUk1fU09VUkNFX1RZUEUsCi0gICAgICAgICJLYW4gaW50ZSBvbXZhbmRsYSBTb3VyY2UgYXYgdHlwIHswfSJ9LAotCi0gICAgeyBFUl9OVUxMX0NPTlRFTlRfSEFORExFUiwKLSAgICAgICAgIklubmVoXHUwMEU1bGxzaGFudGVyYXJlIG1lZCB2XHUwMEU0cmRlIG51bGwifSwKLQotICAgIHsgRVJfTlVMTF9FUlJPUl9IQU5ETEVSLAotICAgICAgICAiRmVsaGFudGVyYXJlIG1lZCB2XHUwMEU0cmRlIG51bGwifSwKLQotICAgIHsgRVJfQ0FOTk9UX0NBTExfUEFSU0UsCi0gICAgICAgICJwYXJzZSBrYW4gaW50ZSBhbnJvcGFzIG9tIENvbnRlbnRIYW5kbGVyIGludGUgaGFyIHNhdHRzIn0sCi0KLSAgICB7IEVSX05PX1BBUkVOVF9GT1JfRklMVEVSLAotICAgICAgICAiSW5nZW4gXHUwMEY2dmVyb3JkbmFkIGZcdTAwRjZyIGZpbHRlciJ9LAotCi0gICAgeyBFUl9OT19TVFlMRVNIRUVUX0lOX01FRElBLAotICAgICAgICAgIkZvcm1hdG1hbGwgc2FrbmFzIGk6IHswfSwgbWVkaWE9IHsxfSJ9LAotCi0gICAgeyBFUl9OT19TVFlMRVNIRUVUX1BJLAotICAgICAgICAgIlBJIGZcdTAwRjZyIHhtbC1mb3JtYXRtYWxsIHNha25hcyBpOiB7MH0ifSwKLQotICAgIHsgRVJfTk9UX1NVUFBPUlRFRCwKLSAgICAgICAiVW5kZXJzdFx1MDBGNmRzIGludGU6IHswfSJ9LAotCi0gICAgeyBFUl9QUk9QRVJUWV9WQUxVRV9CT09MRUFOLAotICAgICAgICJWXHUwMEU0cmRlIGZcdTAwRjZyIGVnZW5za2FwIHswfSBiXHUwMEY2ciB2YXJhIGVuIGJvb2xlc2sgaW5zdGFucyJ9LAotCi0gICAgeyBFUl9DT1VMRF9OT1RfRklORF9FWFRFUk5fU0NSSVBULAotICAgICAgICAgIkt1bmRlIGludGUgaFx1MDBFNG10YSBleHRlcm50IHNrcmlwdCBmclx1MDBFNW4gezB9In0sCi0KLSAgICB7IEVSX1JFU09VUkNFX0NPVUxEX05PVF9GSU5ELAotICAgICAgICAiUmVzdXJzZW4gWyB7MH0gXSBrdW5kZSBpbnRlIGhcdTAwRTRtdGFzLlxuIHsxfSJ9LAotCi0gICAgeyBFUl9PVVRQVVRfUFJPUEVSVFlfTk9UX1JFQ09HTklaRUQsCi0gICAgICAgICJVdGRhdGFlZ2Vuc2thcCBrYW4gaW50ZSBpZGVudGlmaWVyYXM6IHswfSJ9LAotCi0gICAgeyBFUl9GQUlMRURfQ1JFQVRJTkdfRUxFTUxJVFJTTFQsCi0gICAgICAgICJLdW5kZSBpbnRlIHNrYXBhIGluc3RhbnMgYXYgRWxlbUxpdGVyYWxSZXN1bHQifSwKLQotICAvL0VhcmxpZXIgKEpESyAxLjQgWEFMQU4gMi4yLUQxMSkgYXQga2V5IGNvZGUgJzIwNCcgdGhlIGtleSBuYW1lIHdhcyBFUl9QUklPUklUWV9OT1RfUEFSU0FCTEUKLSAgLy8gSW4gbGF0ZXN0IFhhbGFuIGNvZGUgYmFzZSBrZXkgbmFtZSBpcyAgRVJfVkFMVUVfU0hPVUxEX0JFX05VTUJFUi4gVGhpcyBzaG91bGQgYWxzbyBiZSB0YWtlbiBjYXJlCi0gIC8vaW4gbG9jYWxlIHNwZWNpZmljIGZpbGVzIGxpa2UgWFNMVEVycm9yUmVzb3VyY2VzX2RlLmphdmEsIFhTTFRFcnJvclJlc291cmNlc19mci5qYXZhIGV0Yy4KLSAgLy9OT1RFOiBOb3Qgb25seSB0aGUga2V5IG5hbWUgYnV0IG1lc3NhZ2UgaGFzIGFsc28gYmVlbiBjaGFuZ2VkLgotICAgIHsgRVJfVkFMVUVfU0hPVUxEX0JFX05VTUJFUiwKLSAgICAgICAgIlZcdTAwRTRyZGV0IGZcdTAwRjZyIHswfSBiXHUwMEY2ciBpbm5laFx1MDBFNWxsYSBldHQgdGFsIHNvbSBrYW4gdG9sa2FzIn0sCi0KLSAgICB7IEVSX1ZBTFVFX1NIT1VMRF9FUVVBTCwKLSAgICAgICAgIlZcdTAwRTRyZGV0IGZcdTAwRjZyIHswfSBiXHUwMEY2ciB2YXJhIGphIGVsbGVyIG5laiJ9LAotCi0gICAgeyBFUl9GQUlMRURfQ0FMTElOR19NRVRIT0QsCi0gICAgICAgICJLdW5kZSBpbnRlIGFucm9wYSBtZXRvZGVuIHswfSJ9LAotCi0gICAgeyBFUl9GQUlMRURfQ1JFQVRJTkdfRUxFTVRNUEwsCi0gICAgICAgICJLdW5kZSBpbnRlIHNrYXBhIGluc3RhbnMgYXYgRWxlbVRlbXBsYXRlRWxlbWVudCJ9LAotCi0gICAgeyBFUl9DSEFSU19OT1RfQUxMT1dFRCwKLSAgICAgICAgIlRlY2tlbiBcdTAwRTRyIGludGUgdGlsbFx1MDBFNXRuYSBpIGRva3VtZW50ZXQgaSBkZXQgaFx1MDBFNHIgc2tlZGV0In0sCi0KLSAgICB7IEVSX0FUVFJfTk9UX0FMTE9XRUQsCi0gICAgICAgICJBdHRyaWJ1dGV0IFwiezB9XCIgXHUwMEU0ciBpbnRlIHRpbGxcdTAwRTV0ZXQgaSBlbGVtZW50ZXQgezF9ISJ9LAotCi0gICAgeyBFUl9CQURfVkFMVUUsCi0gICAgICJ7MH0gZmVsYWt0aWd0IHZcdTAwRTRyZGUgezF9ICJ9LAotCi0gICAgeyBFUl9BVFRSSUJfVkFMVUVfTk9UX0ZPVU5ELAotICAgICAiQXR0cmlidXRldCB7MH0gc2FrbmFzICJ9LAotCi0gICAgeyBFUl9BVFRSSUJfVkFMVUVfTk9UX1JFQ09HTklaRUQsCi0gICAgICJBdHRyaWJ1dHZcdTAwRTRyZGV0IHswfSBrYW4gaW50ZSBpZGVudGlmaWVyYXMgIn0sCi0KLSAgICB7IEVSX05VTExfVVJJX05BTUVTUEFDRSwKLSAgICAgIkZcdTAwRjZyc1x1MDBGNmtlciBnZW5lcmVyYSBldHQgbmFtbnJ5bWRzcHJlZml4IG1lZCBlbiBudWxsLVVSSSJ9LAotCi0gICAgeyBFUl9OVU1CRVJfVE9PX0JJRywKLSAgICAgIkZcdTAwRjZyc1x1MDBGNmtlciBmb3JtYXRlcmEgZXR0IHRhbCBzb20gXHUwMEU0ciBzdFx1MDBGNnJyZSBcdTAwRTRuIGRldCBzdFx1MDBGNnJzdGEgbFx1MDBFNW5nYSBoZWx0YWxldCJ9LAotCi0gICAgeyBFUl9DQU5OT1RfRklORF9TQVgxX0RSSVZFUiwKLSAgICAgIkhpdHRhciBpbnRlIFNBWDEtZHJpdnJ1dGluZW4ga2xhc3MgezB9In0sCi0KLSAgICB7IEVSX1NBWDFfRFJJVkVSX05PVF9MT0FERUQsCi0gICAgICJTQVgxLWRyaXZydXRpbmVuIGtsYXNzIHswfSBoaXR0YWRlcywgbWVuIGthbiBpbnRlIGxhZGRhcyJ9LAotCi0gICAgeyBFUl9TQVgxX0RSSVZFUl9OT1RfSU5TVEFOVElBVEVELAotICAgICAiU0FYMS1kcml2cnV0aW5lbiBrbGFzcyB7MH0gbGFkZGFkZXMsIG1lbiBrYW4gaW50ZSBpbnN0YW5zaWVyYXMifSwKLQotICAgIHsgRVJfU0FYMV9EUklWRVJfTk9UX0lNUExFTUVOVF9QQVJTRVIsCi0gICAgICJTQVgxLWRyaXZydXRpbmVuIGtsYXNzIHswfSBpbXBsZW1lbnRlcmFyIGludGUgb3JnLnhtbC5zYXguUGFyc2VyIn0sCi0KLSAgICB7IEVSX1BBUlNFUl9QUk9QRVJUWV9OT1RfU1BFQ0lGSUVELAotICAgICAiU3lzdGVtZWdlbnNrYXBlbiBvcmcueG1sLnNheC5wYXJzZXIgXHUwMEU0ciBpbnRlIGFuZ2l2ZW4ifSwKLQotICAgIHsgRVJfUEFSU0VSX0FSR19DQU5OT1RfQkVfTlVMTCwKLSAgICAgIlBhcnNlcmFyZ3VtZW50IG1cdTAwRTVzdGUgdmFyYSBudWxsIn0sCi0KLSAgICB7IEVSX0ZFQVRVUkUsCi0gICAgICJGdW5rdGlvbjogezB9In0sCi0KLSAgICB7IEVSX1BST1BFUlRZLAotICAgICAiRWdlbnNrYXA6IHswfSJ9LAotCi0gICAgeyBFUl9OVUxMX0VOVElUWV9SRVNPTFZFUiwKLSAgICAgIkVuaGV0c21hdGNobmluZyBtZWQgdlx1MDBFNHJkZSBudWxsIn0sCi0KLSAgICB7IEVSX05VTExfRFREX0hBTkRMRVIsCi0gICAgICJEVEQtaGFudGVyYXJlIG1lZCB2XHUwMEU0cmRlIG51bGwifSwKLQotICAgIHsgRVJfTk9fRFJJVkVSX05BTUVfU1BFQ0lGSUVELAotICAgICAiSW5nZXQgYW5naXZldCBkcml2cnV0aW5zbmFtbiEifSwKLQotICAgIHsgRVJfTk9fVVJMX1NQRUNJRklFRCwKLSAgICAgIkluZ2VuIFVSTCBhbmdpdmVuISJ9LAotCi0gICAgeyBFUl9QT09MU0laRV9MRVNTX1RIQU5fT05FLAotICAgICAiUG9vbHN0b3JsZWsgXHUwMEU0ciBtaW5kcmUgXHUwMEU0biBldHQhIn0sCi0KLSAgICB7IEVSX0lOVkFMSURfRFJJVkVSX05BTUUsCi0gICAgICJPZ2lsdGlndCBkcml2cnV0aW5zbmFtbiBhbmdpdmV0ISJ9LAotCi0gICAgeyBFUl9FUlJPUkxJU1RFTkVSLAotICAgICAiRXJyb3JMaXN0ZW5lciJ9LAotCi0KLS8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2Ugc2hvdWxkIG5vdCBub3JtYWxseSBiZSBkaXNwbGF5ZWQKLS8vICAgdG8gdXNlcnMuICBJdCBkZXNjcmliZXMgYSBzaXR1YXRpb24gaW4gd2hpY2ggdGhlIHByb2Nlc3NvciBoYXMgZGV0ZWN0ZWQKLS8vICAgYW4gaW50ZXJuYWwgY29uc2lzdGVuY3kgcHJvYmxlbSBpbiBpdHNlbGYsIGFuZCBpdCBwcm92aWRlcyB0aGlzIG1lc3NhZ2UKLS8vICAgZm9yIHRoZSBkZXZlbG9wZXIgdG8gaGVscCBkaWFnbm9zZSB0aGUgcHJvYmxlbS4gIFRoZSBuYW1lCi0vLyAgICdFbGVtVGVtcGxhdGVFbGVtZW50JyBpcyB0aGUgbmFtZSBvZiBhIGNsYXNzLCBhbmQgc2hvdWxkIG5vdCBiZQotLy8gICB0cmFuc2xhdGVkLgotICAgIHsgRVJfQVNTRVJUX05PX1RFTVBMQVRFX1BBUkVOVCwKLSAgICAgIlByb2dyYW1tZXJhcmZlbCEgVXR0cnlja2V0IGhhciBpbmdlbiBcdTAwRjZ2ZXJvcmRuYWQgRWxlbVRlbXBsYXRlRWxlbWVudCEifSwKLQotCi0vLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIHNob3VsZCBub3Qgbm9ybWFsbHkgYmUgZGlzcGxheWVkCi0vLyAgIHRvIHVzZXJzLiAgSXQgZGVzY3JpYmVzIGEgc2l0dWF0aW9uIGluIHdoaWNoIHRoZSBwcm9jZXNzb3IgaGFzIGRldGVjdGVkCi0vLyAgIGFuIGludGVybmFsIGNvbnNpc3RlbmN5IHByb2JsZW0gaW4gaXRzZWxmLCBhbmQgaXQgcHJvdmlkZXMgdGhpcyBtZXNzYWdlCi0vLyAgIGZvciB0aGUgZGV2ZWxvcGVyIHRvIGhlbHAgZGlhZ25vc2UgdGhlIHByb2JsZW0uICBUaGUgc3Vic3RpdHV0aW9uIHRleHQKLS8vICAgcHJvdmlkZXMgZnVydGhlciBpbmZvcm1hdGlvbiBpbiBvcmRlciB0byBkaWFnbm9zZSB0aGUgcHJvYmxlbS4gIFRoZSBuYW1lCi0vLyAgICdSZWR1bmRlbnRFeHByRWxpbWluYXRvcicgaXMgdGhlIG5hbWUgb2YgYSBjbGFzcywgYW5kIHNob3VsZCBub3QgYmUKLS8vICAgdHJhbnNsYXRlZC4KLSAgICB7IEVSX0FTU0VSVF9SRURVTkRFTlRfRVhQUl9FTElNSU5BVE9SLAotICAgICAiUHJvZ3JhbW1lcmFyZW5zIHV0c2FnYSBpIFJlZHVuZGVudEV4cHJFbGltaW5hdG9yOiB7MH0ifSwKLQotICAgIHsgRVJfTk9UX0FMTE9XRURfSU5fUE9TSVRJT04sCi0gICAgICJ7MH0gXHUwMEU0ciBpbnRlIHRpbGxcdTAwRTV0ZW4gaSBkZW5uYSBwb3NpdGlvbiBpIGZvcm1hdG1hbGxlbiEifSwKLQotICAgIHsgRVJfTk9OV0hJVEVTUEFDRV9OT1RfQUxMT1dFRF9JTl9QT1NJVElPTiwKLSAgICAgIlRleHQgdXRhbiBibGFua3RlY2tlbiBcdTAwRTRyIGludGUgdGlsbFx1MDBFNXRlbiBpIGRlbm5hIHBvc2l0aW9uIGkgZm9ybWF0bWFsbGVuISJ9LAotCi0gIC8vIFRoaXMgY29kZSBpcyBzaGFyZWQgd2l0aCB3YXJuaW5nIGNvZGVzLgotICAvLyBTeXN0ZW1JZCBVbmtub3duCi0gICAgeyBJTlZBTElEX1RDSEFSLAotICAgICAiT3RpbGxcdTAwRTV0ZXQgdlx1MDBFNHJkZTogezF9IGFudlx1MDBFNG5kcyBmXHUwMEY2ciBDSEFSLWF0dHJpYnV0ZXQ6IHswfS4gRXR0IGF0dHJpYnV0IGF2IENIQVItdHlwIGZcdTAwRTVyIGJhcmEgaGEgMSB0ZWNrZW4hIn0sCi0KLSAgICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIGlzIHVzZWQgaWYgdGhlIHZhbHVlIG9mCi0gICAgLy8gYW4gYXR0cmlidXRlIGluIGEgc3R5bGVzaGVldCBpcyBpbnZhbGlkLiAgIlFOQU1FIiBpcyB0aGUgWE1MIGRhdGEtdHlwZSBvZgotICAgIC8vIHRoZSBhdHRyaWJ1dGUsIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgezF9IGlzCi0gICAgLy8gdGhlIGF0dHJpYnV0ZSB2YWx1ZSBhbmQgezB9IGlzIHRoZSBhdHRyaWJ1dGUgbmFtZS4KLSAgLy9UaGUgZm9sbG93aW5nIGNvZGVzIGFyZSBzaGFyZWQgd2l0aCB0aGUgd2FybmluZyBjb2Rlcy4uLgotICAgIHsgSU5WQUxJRF9RTkFNRSwKLSAgICAgIk90aWxsXHUwMEU1dGV0IHZcdTAwRTRyZGU6IHsxfSBhbnZcdTAwRTRuZHMgZlx1MDBGNnIgUU5BTUUtYXR0cmlidXRldDogezB9In0sCi0KLSAgICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIGlzIHVzZWQgaWYgdGhlIHZhbHVlIG9mCi0gICAgLy8gYW4gYXR0cmlidXRlIGluIGEgc3R5bGVzaGVldCBpcyBpbnZhbGlkLiAgIkVOVU0iIGlzIHRoZSBYTUwgZGF0YS10eXBlIG9mCi0gICAgLy8gdGhlIGF0dHJpYnV0ZSwgYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCB7MX0gaXMKLSAgICAvLyB0aGUgYXR0cmlidXRlIHZhbHVlLCB7MH0gaXMgdGhlIGF0dHJpYnV0ZSBuYW1lLCBhbmQgezJ9IGlzIGEgbGlzdCBvZiB2YWxpZAotICAgIC8vIHZhbHVlcy4KLSAgICB7IElOVkFMSURfRU5VTSwKLSAgICAgIk90aWxsXHUwMEU1dGV0IHZcdTAwRTRyZGU6IHsxfSBhbnZcdTAwRTRuZHMgZlx1MDBGNnIgRU5VTS1hdHRyaWJ1dGV0OiB7MH0uIEdpbHRpZ2Egdlx1MDBFNHJkZW4gXHUwMEU0cjogezJ9LiJ9LAotCi0vLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIGlzIHVzZWQgaWYgdGhlIHZhbHVlIG9mCi0vLyBhbiBhdHRyaWJ1dGUgaW4gYSBzdHlsZXNoZWV0IGlzIGludmFsaWQuICAiTk1UT0tFTiIgaXMgdGhlIFhNTCBkYXRhLXR5cGUKLS8vIG9mIHRoZSBhdHRyaWJ1dGUsIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgezF9IGlzCi0vLyB0aGUgYXR0cmlidXRlIHZhbHVlIGFuZCB7MH0gaXMgdGhlIGF0dHJpYnV0ZSBuYW1lLgotICAgIHsgSU5WQUxJRF9OTVRPS0VOLAotICAgICAiT3RpbGxcdTAwRTV0ZXQgdlx1MDBFNHJkZTogezF9IGFudlx1MDBFNG5kcyBmXHUwMEY2ciBOTVRPS0VOLWF0dHJpYnV0ZXQ6IHswfSAifSwKLQotLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBpcyB1c2VkIGlmIHRoZSB2YWx1ZSBvZgotLy8gYW4gYXR0cmlidXRlIGluIGEgc3R5bGVzaGVldCBpcyBpbnZhbGlkLiAgIk5DTkFNRSIgaXMgdGhlIFhNTCBkYXRhLXR5cGUKLS8vIG9mIHRoZSBhdHRyaWJ1dGUsIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgezF9IGlzCi0vLyB0aGUgYXR0cmlidXRlIHZhbHVlIGFuZCB7MH0gaXMgdGhlIGF0dHJpYnV0ZSBuYW1lLgotICAgIHsgSU5WQUxJRF9OQ05BTUUsCi0gICAgICJPdGlsbFx1MDBFNXRldCB2XHUwMEU0cmRlOiB7MX0gYW52XHUwMEU0bmRzIGZcdTAwRjZyIE5DTkFNRS1hdHRyaWJ1dGV0OiB7MH0gIn0sCi0KLS8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgaXMgdXNlZCBpZiB0aGUgdmFsdWUgb2YKLS8vIGFuIGF0dHJpYnV0ZSBpbiBhIHN0eWxlc2hlZXQgaXMgaW52YWxpZC4gICJib29sZWFuIiBpcyB0aGUgWFNMVCBkYXRhLXR5cGUKLS8vIG9mIHRoZSBhdHRyaWJ1dGUsIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgezF9IGlzCi0vLyB0aGUgYXR0cmlidXRlIHZhbHVlIGFuZCB7MH0gaXMgdGhlIGF0dHJpYnV0ZSBuYW1lLgotICAgIHsgSU5WQUxJRF9CT09MRUFOLAotICAgICAiT3RpbGxcdTAwRTV0ZXQgdlx1MDBFNHJkZTogezF9IGFudlx1MDBFNG5kcyBmXHUwMEY2ciBib29sZWFuLWF0dHJpYnV0ZXQ6IHswfSAifSwKLQotLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBpcyB1c2VkIGlmIHRoZSB2YWx1ZSBvZgotLy8gYW4gYXR0cmlidXRlIGluIGEgc3R5bGVzaGVldCBpcyBpbnZhbGlkLiAgIm51bWJlciIgaXMgdGhlIFhTTFQgZGF0YS10eXBlCi0vLyBvZiB0aGUgYXR0cmlidXRlLCBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHsxfSBpcwotLy8gdGhlIGF0dHJpYnV0ZSB2YWx1ZSBhbmQgezB9IGlzIHRoZSBhdHRyaWJ1dGUgbmFtZS4KLSAgICAgeyBJTlZBTElEX05VTUJFUiwKLSAgICAgIk90aWxsXHUwMEU1dGV0IHZcdTAwRTRyZGU6IHsxfSBhbnZcdTAwRTRuZHMgZlx1MDBGNnIgbnVtYmVyLWF0dHJpYnV0ZXQ6IHswfSAifSwKLQotCi0gIC8vIEVuZCBvZiBzaGFyZWQgY29kZXMuLi4KLQotLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIEEgIm1hdGNoIHBhdHRlcm4iIGlzIGEgc3BlY2lhbCBmb3JtIG9mIFhQYXRoIGV4cHJlc3Npb24KLS8vIHRoYXQgaXMgdXNlZCBmb3IgbWF0Y2hpbmcgcGF0dGVybnMuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YKLS8vIGEgZnVuY3Rpb24uICBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB3aGVuIHRoaXMgZnVuY3Rpb24gaXMgcmVmZXJlbmNlZCBpbgotLy8gYSBtYXRjaCBwYXR0ZXJuLCBpdHMgYXJndW1lbnQgbXVzdCBiZSBhIHN0cmluZyBsaXRlcmFsIChvciBjb25zdGFudC4pCi0vLyBFUl9BUkdfTElURVJBTCAtIG5ldyBlcnJvciBtZXNzYWdlIGZvciBidWd6aWxsYSAvLzUyMDIKLSAgICB7IEVSX0FSR19MSVRFUkFMLAotICAgICAiQXJndW1lbnQgZlx1MDBGNnIgezB9IGkgbWF0Y2huaW5nc21cdTAwRjZuc3RyZXQgbVx1MDBFNXN0ZSB2YXJhIGxpdHRlcmFsLiJ9LAotCi0vLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHR3byBkZWZpbml0aW9ucyBvZgotLy8gYSB2YXJpYWJsZS4gIEEgImdsb2JhbCB2YXJpYWJsZSIgaXMgYSB2YXJpYWJsZSB0aGF0IGlzIGFjY2Vzc2libGUgZXZlcnl3aGVyCi0vLyBpbiB0aGUgc3R5bGVzaGVldC4KLS8vIEVSX0RVUExJQ0FURV9HTE9CQUxfVkFSIC0gbmV3IGVycm9yIG1lc3NhZ2UgZm9yIGJ1Z3ppbGxhICM3OTAKLSAgICB7IEVSX0RVUExJQ0FURV9HTE9CQUxfVkFSLAotICAgICAiRHViYmVsIGRla2xhcmF0aW9uIGF2IGdsb2JhbCB2YXJpYWJlbC4ifSwKLQotCi0vLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHR3byBkZWZpbml0aW9ucyBvZgotLy8gYSB2YXJpYWJsZSB3ZXJlIGVuY291bnRlcmVkLgotLy8gRVJfRFVQTElDQVRFX1ZBUiAtIG5ldyBlcnJvciBtZXNzYWdlIGZvciBidWd6aWxsYSAjNzkwCi0gICAgeyBFUl9EVVBMSUNBVEVfVkFSLAotICAgICAiRHViYmVsIGRla2xhcmF0aW9uIGF2IHZhcmlhYmVsLiJ9LAotCi0gICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogICJ4c2w6dGVtcGxhdGUsICJuYW1lIiBhbmQgIm1hdGNoIiBhcmUgWFNMVCBrZXl3b3JkcwotICAgIC8vIHdoaWNoIG11c3Qgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgLy8gRVJfVEVNUExBVEVfTkFNRV9NQVRDSCAtIG5ldyBlcnJvciBtZXNzYWdlIGZvciBidWd6aWxsYSAjNzg5Ci0gICAgeyBFUl9URU1QTEFURV9OQU1FX01BVENILAotICAgICAieHNsOnRlbXBsYXRlIG1cdTAwRTVzdGUgaGEgbmFtZS0gb2NoL2VsbGVyIG1hdGNoLWF0dHJpYnV0In0sCi0KLSAgICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgImV4Y2x1ZGUtcmVzdWx0LXByZWZpeGVzIiBpcyBhbiBYU0xUIGtleXdvcmQgd2hpY2gKLSAgICAvLyBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCBhIG5hbWVzcGFjZSBwcmVmaXgKLSAgICAvLyBlbmNvdW50ZXJlZCBhcyBwYXJ0IG9mIHRoZSB2YWx1ZSBvZiB0aGUgZXhjbHVkZS1yZXN1bHQtcHJlZml4ZXMgYXR0cmlidXRlCi0gICAgLy8gd2FzIGluIGVycm9yLgotICAgIC8vIEVSX0lOVkFMSURfUFJFRklYIC0gbmV3IGVycm9yIG1lc3NhZ2UgZm9yIGJ1Z3ppbGxhICM3ODgKLSAgICB7IEVSX0lOVkFMSURfUFJFRklYLAotICAgICAiUHJlZml4IGkgZXhjbHVkZS1yZXN1bHQtcHJlZml4ZXMgXHUwMEU0ciBpbnRlIGdpbHRpZ3Q6IHswfSJ9LAotCi0gICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIEFuICJhdHRyaWJ1dGUgc2V0IiBpcyBhIHNldCBvZiBhdHRyaWJ1dGVzIHRoYXQgY2FuCi0gICAgLy8gYmUgYWRkZWQgdG8gYW4gZWxlbWVudCBpbiB0aGUgb3V0cHV0IGRvY3VtZW50IGFzIGEgZ3JvdXAuICBUaGUgbWVzc2FnZQotICAgIC8vIGluZGljYXRlcyB0aGF0IHRoZXJlIHdhcyBhIHJlZmVyZW5jZSB0byBhbiBhdHRyaWJ1dGUgc2V0IG5hbWVkIHswfSB0aGF0Ci0gICAgLy8gd2FzIG5ldmVyIGRlZmluZWQuCi0gICAgLy8gRVJfTk9fQVRUUklCX1NFVCAtIG5ldyBlcnJvciBtZXNzYWdlIGZvciBidWd6aWxsYSAjNzgyCi0gICAgeyBFUl9OT19BVFRSSUJfU0VULAotICAgICAiYXR0cmlidXRzZXJpZW4gezB9IGZpbm5zIGludGUifSwKLQotICAgIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhlcmUgd2FzIGEgcmVmZXJlbmNlCi0gICAgLy8gdG8gYSBmdW5jdGlvbiBuYW1lZCB7MH0gZm9yIHdoaWNoIG5vIGZ1bmN0aW9uIGRlZmluaXRpb24gY291bGQgYmUgZm91bmQuCi0gICAgeyBFUl9GVU5DVElPTl9OT1RfRk9VTkQsCi0gICAgICJEZXQgZmlubnMgaW5nZW4gZnVua3Rpb24gbWVkIG5hbW5ldCB7MH0ifSwKLQotICAgIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhlIFhTTFQgaW5zdHJ1Y3Rpb24KLSAgICAvLyB0aGF0IGlzIG5hbWVkIGJ5IHRoZSBzdWJzdGl0dXRpb24gdGV4dCB7MH0gbXVzdCBub3QgY29udGFpbiBvdGhlciBYU0xUCi0gICAgLy8gaW5zdHJ1Y3Rpb25zIChjb250ZW50KSBvciBhICJzZWxlY3QiIGF0dHJpYnV0ZS4gIFRoZSB3b3JkICJzZWxlY3QiIGlzCi0gICAgLy8gYW4gWFNMVCBrZXl3b3JkIGluIHRoaXMgY2FzZSBhbmQgbXVzdCBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICB7IEVSX0NBTlRfSEFWRV9DT05URU5UX0FORF9TRUxFQ1QsCi0gICAgICJFbGVtZW50ZXQgezB9IGthbiBpbnRlIGhhIGJcdTAwRTVkZSBpbm5laFx1MDBFNWxsIG9jaCBzZWxlY3QtYXR0cmlidXQuIn0sCi0KLSAgICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoZSB2YWx1ZSBhcmd1bWVudAotICAgIC8vIG9mIHNldFBhcmFtZXRlciBtdXN0IGJlIGEgdmFsaWQgSmF2YSBPYmplY3QuCi0gICAgeyBFUl9JTlZBTElEX1NFVF9QQVJBTV9WQUxVRSwKLSAgICAgIlBhcmFtZXRlcnZcdTAwRTRyZGV0IGZcdTAwRjZyIHswfSBtXHUwMEU1c3RlIHZhcmEgZ2lsdGlndCBKYXZhLW9iamVrdCJ9LAotCi0gICAgeyBFUl9JTlZBTElEX05BTUVTUEFDRV9VUklfVkFMVUVfRk9SX1JFU1VMVF9QUkVGSVhfRk9SX0RFRkFVTFQsCi0gICAgICAicmVzdWx0LXByZWZpeC1hdHRyaWJ1dGV0IGkgeHNsOm5hbWVzcGFjZS1hbGlhcy1lbGVtZW50IGhhciB2XHUwMEU0cmRldCAnI2RlZmF1bHQnLCBtZW4gZGV0IGZpbm5zIGluZ2VuIGRla2xhcmF0aW9uIGF2IHN0YW5kYXJkbmFtbnJ5bWQgaW5vbSBvbWZhdHRuaW5nZW4gYXYgZWxlbWVudGV0In0sCi0KLSAgICB7IEVSX0lOVkFMSURfTkFNRVNQQUNFX1VSSV9WQUxVRV9GT1JfUkVTVUxUX1BSRUZJWCwKLSAgICAgICJyZXN1bHQtcHJlZml4LWF0dHJpYnV0ZXQgaSB4c2w6bmFtZXNwYWNlLWFsaWFzLWVsZW1lbnQgaGFyIHZcdTAwRTRyZGV0ICcnezB9JycsIG1lbiBkZXQgZmlubnMgaW5nZW4gZGVrbGFyYXRpb24gYXYgbmFtbnJ5bWQgZlx1MDBGNnIgcHJlZml4ZXQgJyd7MH0nJyBpbm9tIG9tZmF0dG5pbmdlbiBhdiBlbGVtZW50ZXQuIn0sCi0KLSAgICB7IEVSX1NFVF9GRUFUVVJFX05VTExfTkFNRSwKLSAgICAgICJGdW5rdGlvbnNuYW1uZXQga2FuIGludGUgdmFyYSBudWxsIGkgVHJhbnNmb3JtZXJGYWN0b3J5LnNldEZlYXR1cmUobmFtbiBwXHUwMEU1IHN0clx1MDBFNG5nLCBib29sZXNrdCB2XHUwMEU0cmRlKS4ifSwKLQotICAgIHsgRVJfR0VUX0ZFQVRVUkVfTlVMTF9OQU1FLAotICAgICAgIkZ1bmt0aW9uc25hbW5ldCBrYW4gaW50ZSB2YXJhIG51bGwgaSBUcmFuc2Zvcm1lckZhY3RvcnkuZ2V0RmVhdHVyZShuYW1uIHBcdTAwRTUgc3RyXHUwMEU0bmcpLiJ9LAotCi0gICAgeyBFUl9VTlNVUFBPUlRFRF9GRUFUVVJFLAotICAgICAgIkthbiBpbnRlIHN0XHUwMEU0bGxhIGluIGZ1bmt0aW9uZW4gJyd7MH0nJyBpIGRlbm5hIFRyYW5zZm9ybWVyRmFjdG9yeS4ifSwKLQotICAgIHsgRVJfRVhURU5TSU9OX0VMRU1FTlRfTk9UX0FMTE9XRURfSU5fU0VDVVJFX1BST0NFU1NJTkcsCi0gICAgICAgICAgIkFudlx1MDBFNG5kbmluZyBhdiB0aWxsXHUwMEU0Z2dzZWxlbWVudGV0ICcnezB9JycgXHUwMEU0ciBpbnRlIHRpbGxcdTAwRTV0ZXQgblx1MDBFNHIgc1x1MDBFNGtlciBiZWFyYmV0bmluZyB0aWxsXHUwMEU0bXBhcy4ifSwKLQotICAgIHsgRVJfTkFNRVNQQUNFX0NPTlRFWFRfTlVMTF9OQU1FU1BBQ0UsCi0gICAgICAiS2FuIGludGUgaFx1MDBFNG10YSBwcmVmaXggZlx1MDBGNnIgbmFtbnJ5bWRzLXVyaSBzb20gXHUwMEU0ciBudWxsLiJ9LAotCi0gICAgeyBFUl9OQU1FU1BBQ0VfQ09OVEVYVF9OVUxMX1BSRUZJWCwKLSAgICAgICJLYW4gaW50ZSBoXHUwMEU0bXRhIG5hbW5yeW1kcy11cmkgZlx1MDBGNnIgcHJlZml4IHNvbSBcdTAwRTRyIG51bGwuIn0sCi0KLSAgICB7IEVSX1hQQVRIX1JFU09MVkVSX05VTExfUU5BTUUsCi0gICAgICAiRnVua3Rpb25zbmFtbiBmXHUwMEU1ciBpbnRlIHZhcmEgbnVsbC4ifSwKLQotICAgIHsgRVJfWFBBVEhfUkVTT0xWRVJfTkVHQVRJVkVfQVJJVFksCi0gICAgICAiQXJpdGV0ZW4ga2FuIGludGUgdmFyYSBuZWdhdGl2LiJ9LAotICAvLyBXYXJuaW5ncy4uLgotCi0gICAgeyBXR19GT1VORF9DVVJMWUJSQUNFLAotICAgICAgIkhpdHRhZGUgJ30nIG1lbiBkZXQgZmlubnMgaW5nZW4gXHUwMEY2cHBlbiBhdHRyaWJ1dG1hbGwhIn0sCi0KLSAgICB7IFdHX0NPVU5UX0FUVFJJQl9NQVRDSEVTX05PX0FOQ0VTVE9SLAotICAgICAgIlZhcm5pbmc6IHJcdTAwRTRrbmFyYXR0cmlidXQgbWF0Y2hhciBpbnRlIFx1MDBGNnZlcm9yZG5hZCBpIHhzbDpudW1iZXIhIFRhcmdldCA9IHswfSJ9LAotCi0gICAgeyBXR19FWFBSX0FUVFJJQl9DSEFOR0VEX1RPX1NFTEVDVCwKLSAgICAgICJHYW1tYWwgc3ludGF4OiBOYW1uZXQgcFx1MDBFNSAnZXhwcictYXR0cmlidXRldCBoYXIgXHUwMEU0bmRyYXRzIHRpbGwgJ3NlbGVjdCcuIn0sCi0KLSAgICB7IFdHX05PX0xPQ0FMRV9JTl9GT1JNQVROVU1CRVIsCi0gICAgICAiWGFsYW4gaGFudGVyYXIgXHUwMEU0bm51IGludGUgc3ByXHUwMEU1a2tvbnZlbnRpb25lbiBpIGZ1bmt0aW9uZW4gZm9ybWF0LW51bWJlci4ifSwKLQotICAgIHsgV0dfTE9DQUxFX05PVF9GT1VORCwKLSAgICAgICJWYXJuaW5nOiBIaXR0YWRlIGludGUgc3ByXHUwMEU1a2tvbnZlbnRpb24gZlx1MDBGNnIgeG1sOmxhbmc9ezB9In0sCi0KLSAgICB7IFdHX0NBTk5PVF9NQUtFX1VSTF9GUk9NLAotICAgICAgIkthbiBpbnRlIHNrYXBhIFVSTCBmclx1MDBFNW46IHswfSJ9LAotCi0gICAgeyBXR19DQU5OT1RfTE9BRF9SRVFVRVNURURfRE9DLAotICAgICAgIkthbiBpbnRlIGxhZGRhIGJlZ1x1MDBFNHJ0IGRva3VtZW50OiB7MH0ifSwKLQotICAgIHsgV0dfQ0FOTk9UX0ZJTkRfQ09MTEFUT1IsCi0gICAgICAiSGl0dGFkZSBpbnRlIGtvbGxhdGlvbmVyaW5nIGZcdTAwRjZyIDxzb3J0IHhtbDpsYW5nPXswfSJ9LAotCi0gICAgeyBXR19GVU5DVElPTlNfU0hPVUxEX1VTRV9VUkwsCi0gICAgICAiR2FtbWFsIHN5bnRheDogZnVua3Rpb25zaW5zdHJ1a3Rpb25lbiBiXHUwMEY2ciBhbnZcdTAwRTRuZGEgdXJsOmVuIHswfSJ9LAotCi0gICAgeyBXR19FTkNPRElOR19OT1RfU1VQUE9SVEVEX1VTSU5HX1VURjgsCi0gICAgICAia29kbmluZyB1bmRlcnN0XHUwMEY2ZHMgaW50ZTogezB9LCBhbnZcdTAwRTRuZGVyIFVURi04In0sCi0KLSAgICB7IFdHX0VOQ09ESU5HX05PVF9TVVBQT1JURURfVVNJTkdfSkFWQSwKLSAgICAgICJrb2RuaW5nIHVuZGVyc3RcdTAwRjZkcyBpbnRlOiB7MH0sIGFudlx1MDBFNG5kZXIgSmF2YSB7MX0ifSwKLQotICAgIHsgV0dfU1BFQ0lGSUNJVFlfQ09ORkxJQ1RTLAotICAgICAgIlNwZWNpZmlrYSBrb25mbGlrdGVyIGhpdHRhZGVzOiB7MH0gU2VuYXN0IGhpdHRhZGUgaSBmb3JtYXRtYWxsIGtvbW1lciBhdHQgYW52XHUwMEU0bmRhcy4ifSwKLQotICAgIHsgV0dfUEFSU0lOR19BTkRfUFJFUEFSSU5HLAotICAgICAgIj09PT09PT09PSBUb2xrYXIgb2NoIGZcdTAwRjZyYmVyZWRlciB7MH0gPT09PT09PT09PSJ9LAotCi0gICAgeyBXR19BVFRSX1RFTVBMQVRFLAotICAgICAiQXR0cmlidXRtYWxsLCB7MH0ifSwKLQotICAgIHsgV0dfQ09ORkxJQ1RfQkVUV0VFTl9YU0xTVFJJUFNQQUNFX0FORF9YU0xQUkVTRVJWRVNQQUNFLAotICAgICAgIk1hdGNobmluZ3Nrb25mbGlrdCBtZWxsYW4geHNsOnN0cmlwLXNwYWNlIG9jaCB4c2w6cHJlc2VydmUtc3BhY2UifSwKLQotICAgIHsgV0dfQVRUUklCX05PVF9IQU5ETEVELAotICAgICAgIlhhbGFuIGhhbnRlcmFyIFx1MDBFNG5udSBpbnRlIGF0dHJpYnV0ZXQgezB9ISJ9LAotCi0gICAgeyBXR19OT19ERUNJTUFMRk9STUFUX0RFQ0xBUkFUSU9OLAotICAgICAgIkhpdHRhZGUgaW5nZW4gZGVrbGFyYXRpb24gZlx1MDBGNnIgZGVjaW1hbGZvcm1hdGV0OiB7MH0ifSwKLQotICAgIHsgV0dfT0xEX1hTTFRfTlMsCi0gICAgICJYU0xULW5hbW5yeW1kIHNha25hcyBlbGxlciBcdTAwRTRyIGlua29ycmVrdC4gIn0sCi0KLSAgICB7IFdHX09ORV9ERUZBVUxUX1hTTERFQ0lNQUxGT1JNQVRfQUxMT1dFRCwKLSAgICAgICJFbmRhc3QgZW4gc3RhbmRhcmRkZWtsYXJhdGlvbiBhdiB4c2w6ZGVjaW1hbC1mb3JtYXQgXHUwMEU0ciB0aWxsXHUwMEU1dGVuLiJ9LAotCi0gICAgeyBXR19YU0xERUNJTUFMRk9STUFUX05BTUVTX01VU1RfQkVfVU5JUVVFLAotICAgICAgIk5hbW4gcFx1MDBFNSB4c2w6ZGVjaW1hbC1mb3JtYXQgbVx1MDBFNXN0ZSB2YXJhIHVuaWthLiBOYW1uZXQgXCJ7MH1cIiBoYXIgYmxpdml0IGR1cGxpY2VyYXQuIn0sCi0KLSAgICB7IFdHX0lMTEVHQUxfQVRUUklCVVRFLAotICAgICAgInswfSBoYXIgZXR0IG90aWxsXHUwMEU1dGV0IGF0dHJpYnV0OiB7MX0ifSwKLQotICAgIHsgV0dfQ09VTERfTk9UX1JFU09MVkVfUFJFRklYLAotICAgICAgIkt1bmRlIGludGUgbWF0Y2hhIG5hbW5yeW1kc3ByZWZpeDogezB9LiBOb2RlbiBpZ25vcmVyYXMuIn0sCi0KLSAgICB7IFdHX1NUWUxFU0hFRVRfUkVRVUlSRVNfVkVSU0lPTl9BVFRSSUIsCi0gICAgICAieHNsOnN0eWxlc2hlZXQga3JcdTAwRTR2ZXIgZXR0ICd2ZXJzaW9uJy1hdHRyaWJ1dCEifSwKLQotICAgIHsgV0dfSUxMRUdBTF9BVFRSSUJVVEVfTkFNRSwKLSAgICAgICJPdGlsbFx1MDBFNXRldCBhdHRyaWJ1dG5hbW46IHswfSJ9LAotCi0gICAgeyBXR19JTExFR0FMX0FUVFJJQlVURV9WQUxVRSwKLSAgICAgICJPdGlsbFx1MDBFNXRldCB2XHUwMEU0cmRlIGFudlx1MDBFNG5kcyBmXHUwMEY2ciBhdHRyaWJ1dGV0IHswfTogezF9In0sCi0KLSAgICB7IFdHX0VNUFRZX1NFQ09ORF9BUkcsCi0gICAgICAiUmVzdWx0ZXJhbmRlIG5vZHVwcHNcdTAwRTR0dG5pbmcgZnJcdTAwRTVuIGRva3VtZW50ZnVua3Rpb25lbnMgYW5kcmEgYXJndW1lbnRldCBcdTAwRTRyIHRvbXQuIEVuIHRvbSBub2R1cHBzXHUwMEU0dHRuaW5nIGFudlx1MDBFNG5kcy4ifSwKLQotICAvL0ZvbGxvd2luZyBhcmUgdGhlIG5ldyBXQVJOSU5HIGtleXMgYWRkZWQgaW4gWEFMQU4gY29kZSBiYXNlIGFmdGVyIEpkayAxLjQgKFhhbGFuIDIuMi1EMTEpCi0KLSAgICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIm5hbWUiIGFuZCAieHNsOnByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24iIGFyZSBrZXl3b3JkcwotICAgIC8vIGFuZCBtdXN0IG5vdCBiZSB0cmFuc2xhdGVkLgotICAgIHsgV0dfUFJPQ0VTU0lOR0lOU1RSVUNUSU9OX05BTUVfQ0FOVF9CRV9YTUwsCi0gICAgICAiJ25hbWUnLWF0dHJpYnV0ZXRzIHZcdTAwRTRyZGUgZlx1MDBGNnIgeHNsOnByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24ga2FuIGludGUgdmFyYSAneG1sJyJ9LAotCi0gICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogICJuYW1lIiBhbmQgInhzbDpwcm9jZXNzaW5nLWluc3RydWN0aW9uIiBhcmUga2V5d29yZHMKLSAgICAvLyBhbmQgbXVzdCBub3QgYmUgdHJhbnNsYXRlZC4gICJOQ05hbWUiIGlzIGFuIFhNTCBkYXRhLXR5cGUgYW5kIG11c3Qgbm90IGJlCi0gICAgLy8gdHJhbnNsYXRlZC4KLSAgICB7IFdHX1BST0NFU1NJTkdJTlNUUlVDVElPTl9OT1RWQUxJRF9OQ05BTUUsCi0gICAgICAiJyduYW1lJyctYXR0cmlidXRldHMgdlx1MDBFNHJkZSBmXHUwMEY2ciB4c2w6cHJvY2Vzc2luZy1pbnN0cnVjdGlvbiBtXHUwMEU1c3RlIHZhcmEgZ2lsdGlndCBOQ05hbWU6IHswfSJ9LAotCi0gICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyByZXBvcnRlZCBpZiB0aGUgc3R5bGVzaGVldCB0aGF0IGlzCi0gICAgLy8gYmVpbmcgcHJvY2Vzc2VkIGF0dGVtcHRlZCB0byBjb25zdHJ1Y3QgYW4gWE1MIGRvY3VtZW50IHdpdGggYW4gYXR0cmlidXRlIGluIGEKLSAgICAvLyBwbGFjZSBvdGhlciB0aGFuIG9uIGFuIGVsZW1lbnQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgc3BlY2lmaWVzIHRoZSBuYW1lIG9mCi0gICAgLy8gdGhlIGF0dHJpYnV0ZS4KLSAgICB7IFdHX0lMTEVHQUxfQVRUUklCVVRFX1BPU0lUSU9OLAotICAgICAgIkthbiBpbnRlIGxcdTAwRTRnZ2EgdGlsbCBhdHRyaWJ1dGV0IHswfSBlZnRlciB1bmRlcm9yZG5hZGUgbm9kZXIgZWxsZXIgaW5uYW4gZXR0IGVsZW1lbnQgaGFyIHNrYXBhdHMuIEF0dHJpYnV0ZXQgaWdub3JlcmFzLiJ9LAotCi0gICAgeyBOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIsCi0gICAgICAiRlx1MDBGNnJzXHUwMEY2a2VyIFx1MDBFNG5kcmEgZXR0IG9iamVrdCBkXHUwMEU0ciBcdTAwRTRuZHJpbmdhciBpbnRlIFx1MDBFNHIgdGlsbFx1MDBFNXRuYS4iCi0gICAgfSwKLQotICAgIC8vQ2hlY2s6IFdIWSBUSEVSRSBJUyBBIEdBUCBCL1cgTlVNQkVSUyBpbiB0aGUgWFNMVEVycm9yUmVzb3VyY2VzIHByb3BlcnRpZXMgZmlsZT8KLQotICAvLyBPdGhlciBtaXNjZWxsYW5lb3VzIHRleHQgdXNlZCBpbnNpZGUgdGhlIGNvZGUuLi4KLSAgeyAidWlfbGFuZ3VhZ2UiLCAiZW4ifSwKLSAgeyAgImhlbHBfbGFuZ3VhZ2UiLCAgImVuIiB9LAotICB7ICAibGFuZ3VhZ2UiLCAgImVuIiB9LAotICB7ICJCQURfQ09ERSIsICJQYXJhbWV0ZXIgZlx1MDBGNnIgY3JlYXRlTWVzc2FnZSBsaWdnZXIgdXRhbmZcdTAwRjZyIGdyXHUwMEU0bnN2XHUwMEU0cmRldCJ9LAotICB7ICAiRk9STUFUX0ZBSUxFRCIsICJVbmRhbnRhZyB1dGxcdTAwRjZzdCB2aWQgbWVzc2FnZUZvcm1hdC1hbnJvcCJ9LAotICB7ICAidmVyc2lvbiIsICI+Pj4+Pj4+IFhhbGFuIHZlcnNpb24gIn0sCi0gIHsgICJ2ZXJzaW9uMiIsICAiPDw8PDw8PCJ9LAotICB7ICAieWVzIiwgImphIn0sCi0gIHsgImxpbmUiLCAiUmFkIG5yIn0sCi0gIHsgImNvbHVtbiIsIktvbHVtbiBuciJ9LAotICB7ICJ4c2xkb25lIiwgIlhTTFByb2Nlc3NvcjogdXRmXHUwMEY2cmQifSwKLQotCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2VzIHByb3ZpZGUgdXNhZ2UgaW5mb3JtYXRpb24KLSAgLy8gZm9yIHRoZSBYYWxhbiBQcm9jZXNzIGNvbW1hbmQgbGluZS4gICJQcm9jZXNzIiBpcyB0aGUgbmFtZSBvZiBhIEphdmEgY2xhc3MsCi0gIC8vIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuCi0gIHsgInhzbFByb2Nfb3B0aW9uIiwgIlByb2Nlc3Mta2xhc3NhbHRlcm5hdGl2IGZcdTAwRjZyIFhhbGFuLUota29tbWFuZG9yYWQ6In0sCi0gIHsgInhzbFByb2Nfb3B0aW9uIiwgIlByb2Nlc3Mta2xhc3NhbHRlcm5hdGl2IGZcdTAwRjZyIFhhbGFuLUota29tbWFuZG9yYWQ6In0sCi0gIHsgInhzbFByb2NfaW52YWxpZF94c2x0Y19vcHRpb24iLCAiQWx0ZXJuYXRpdmV0IHswfSB1bmRlcnN0XHUwMEY2ZHMgaW50ZSBpIFhTTFRDLWxcdTAwRTRnZS4ifSwKLSAgeyAieHNsUHJvY19pbnZhbGlkX3hhbGFuX29wdGlvbiIsICJBbHRlcm5hdGl2ZXQgezB9IGthbiBhbnZcdTAwRTRuZGFzIGVuZGFzdCBtZWQgLVhTTFRDLiJ9LAotICB7ICJ4c2xQcm9jX25vX2lucHV0IiwgIkZlbDogSW5nZW4gZm9ybWF0bWFsbCBlbGxlciBpbmRhdGEteG1sIGhhciBhbmdldHRzLiBLXHUwMEY2ciBrb21tYW5kb3QgdXRhbiBuXHUwMEU1Z290IGFsdGVybmF0aXYgZlx1MDBGNnIgYXR0IHZpc2Egc3ludGF4LiJ9LAotICB7ICJ4c2xQcm9jX2NvbW1vbl9vcHRpb25zIiwgIi1BbGxtXHUwMEU0bm5hIGFsdGVybmF0aXYtIn0sCi0gIHsgInhzbFByb2NfeGFsYW5fb3B0aW9ucyIsICItQWx0ZXJuYXRpdiBmXHUwMEY2ciBYYWxhbi0ifSwKLSAgeyAieHNsUHJvY194c2x0Y19vcHRpb25zIiwgIi1BbHRlcm5hdGl2IGZcdTAwRjZyIFhTTFRDLSJ9LAotICB7ICJ4c2xQcm9jX3JldHVybl90b19jb250aW51ZSIsICIodHJ5Y2sgcFx1MDBFNSBFbnRlciBmXHUwMEY2ciBhdHQgZm9ydHNcdTAwRTR0dGEpIn0sCi0KLSAgIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6IFRoZSBvcHRpb24gbmFtZSBhbmQgdGhlIHBhcmFtZXRlciBuYW1lIGRvIG5vdCBuZWVkIHRvCi0gICAvLyBiZSB0cmFuc2xhdGVkLiBPbmx5IHRyYW5zbGF0ZSB0aGUgbWVzc2FnZXMgaW4gcGFyZW50aGVzZXMuICBOb3RlIGFsc28gdGhhdAotICAgLy8gbGVhZGluZyB3aGl0ZXNwYWNlIGluIHRoZSBtZXNzYWdlcyBpcyB1c2VkIHRvIGluZGVudCB0aGUgdXNhZ2UgaW5mb3JtYXRpb24KLSAgIC8vIGZvciBlYWNoIG9wdGlvbiBpbiB0aGUgRW5nbGlzaCBtZXNzYWdlcy4KLSAgIC8vIERvIG5vdCB0cmFuc2xhdGUgdGhlIGtleXdvcmRzOiBYU0xUQywgU0FYLCBET00gYW5kIERUTS4KLSAgeyAib3B0aW9uWFNMVEMiLCAiICAgWy1YU0xUQyAoYW52XHUwMEU0bmQgWFNMVEMgZlx1MDBGNnIgdHJhbnNmb3JtZXJpbmcpXSJ9LAotICB7ICJvcHRpb25JTiIsICIgICBbLUlOIGlucHV0WE1MVVJMXSJ9LAotICB7ICJvcHRpb25YU0wiLCAiICAgWy1YU0wgWFNMVHJhbnNmb3JtYXRpb25VUkxdIn0sCi0gIHsgIm9wdGlvbk9VVCIsICAiICAgWy1PVVQgb3V0cHV0RmlsZU5hbWVdIn0sCi0gIHsgIm9wdGlvbkxYQ0lOIiwgIiAgIFstTFhDSU4gY29tcGlsZWRTdHlsZXNoZWV0RmlsZU5hbWVJbl0ifSwKLSAgeyAib3B0aW9uTFhDT1VUIiwgIiAgIFstTFhDT1VUIGNvbXBpbGVkU3R5bGVzaGVldEZpbGVOYW1lT3V0T3V0XSJ9LAotICB7ICJvcHRpb25QQVJTRVIiLCAiICAgWy1QQVJTRVIgZnVsbHQga3ZhbGlmaWNlcmF0IGtsYXNzbmFtbiBwXHUwMEU1IHBhcnNlcmZcdTAwRjZyYmluZGVsc2VdIn0sCi0gIHsgICJvcHRpb25FIiwgIiAgIFstRSAoVXRcdTAwRjZrYSBpbnRlIGVuaGV0c3JlZmVyZW5zZXIpXSJ9LAotICB7ICAib3B0aW9uViIsICAiICAgWy1FIChVdFx1MDBGNmthIGludGUgZW5oZXRzcmVmZXJlbnNlcildIn0sCi0gIHsgICJvcHRpb25RQyIsICIgICBbLVFDIChUeXN0YSBtXHUwMEY2bnN0ZXJrb25mbGlrdHZhcm5pbmdhcildIn0sCi0gIHsgICJvcHRpb25RIiwgIiAgIFstUSAgKFR5c3QgbFx1MDBFNGdlKV0ifSwKLSAgeyAgIm9wdGlvbkxGIiwgIiAgIFstTEYgKEFudlx1MDBFNG5kIHJhZG1hdG5pbmdhciBlbmRhc3QgZlx1MDBGNnIgdXRkYXRhIHtzdGFuZGFyZCBcdTAwRTRyIENSL0xGfSldIn0sCi0gIHsgICJvcHRpb25DUiIsICIgICBbLUNSIChBbnZcdTAwRTRuZCByYWRtYXRuaW5nYXIgZW5kYXN0IGZcdTAwRjZyIHV0ZGF0YSB7c3RhbmRhcmQgXHUwMEU0ciBDUi9MRn0pXSJ9LAotICB7ICJvcHRpb25FU0NBUEUiLCAiICAgWy1FU0NBUEUgKFZpbGthIHRlY2tlbiBcdTAwRTRyIHNraWZ0bmluZ3N0ZWNrZW4ge3N0YW5kYXJkIFx1MDBFNHIgPD4mXCInXFxyXFxufV0ifSwKLSAgeyAib3B0aW9uSU5ERU5UIiwgIiAgIFstSU5ERU5UIChCZXN0XHUwMEU0bSBhbnRhbCBibGFua3N0ZWcgZlx1MDBGNnIgaW5kcmFnIHtzdGFuZGFyZCBcdTAwRTRyIDB9KV0ifSwKLSAgeyAib3B0aW9uVFQiLCAiICAgWy1UVCAoU3BcdTAwRTVyYSBtYWxsYXIgdmlkIGFucm9wLildIn0sCi0gIHsgIm9wdGlvblRHIiwgIiAgIFstVEcgKFNwXHUwMEU1cmEgdmFyamUgZ2VuZXJhdGlvbnNoXHUwMEU0bmRlbHNlLildIn0sCi0gIHsgIm9wdGlvblRTIiwgIiAgIFstVFMgKFNwXHUwMEU1cmEgdmFyamUgdXJ2YWxzaFx1MDBFNG5kZWxzZS4pXSJ9LAotICB7ICAib3B0aW9uVFRDIiwgIiAgIFstVFRDIChTcFx1MDBFNXJhIG1hbGx1bmRlcm9yZG5hZGUgblx1MDBFNHIgZGUgYmVhcmJldGFzLildIn0sCi0gIHsgIm9wdGlvblRDTEFTUyIsICIgICBbLVRDTEFTUyAoVHJhY2VMaXN0ZW5lci1rbGFzcyBmXHUwMEY2ciBzcFx1MDBFNXJuaW5nc3RpbGxcdTAwRTRnZy4pXSJ9LAotICB7ICJvcHRpb25WQUxJREFURSIsICIgICBbLVZBTElEQVRFIChTdFx1MDBFNGxsIGluIG9tIHZhbGlkZXJpbmcgdXRmXHUwMEY2cnMuIFN0YW5kYXJkIFx1MDBFNHIgYXR0IHZhbGlkZXJpbmcgXHUwMEU0ciBhdnN0XHUwMEU0bmdkLildIn0sCi0gIHsgIm9wdGlvbkVEVU1QIiwgIiAgIFstRURVTVAge3ZhbGZyaXR0IGZpbG5hbW59IChHXHUwMEY2ciBzdGFja2R1bXAgdmlkIGZlbC4pXSJ9LAotICB7ICAib3B0aW9uWE1MIiwgIiAgIFstWE1MIChBbnZcdTAwRTRuZCBYTUwtZm9ybWF0ZXJhcmUgb2NoIGxcdTAwRTRnZyB0aWxsIFhNTC1odXZ1ZC4pXSJ9LAotICB7ICAib3B0aW9uVEVYVCIsICIgICBbLVRFWFQgKEFudlx1MDBFNG5kIGVua2VsIHRleHRmb3JtYXRlcmFyZS4pXSJ9LAotICB7ICAib3B0aW9uSFRNTCIsICIgICBbLUhUTUwgKEFudlx1MDBFNG5kIEhUTUwtZm9ybWF0ZXJhcmUuKV0ifSwKLSAgeyAgIm9wdGlvblBBUkFNIiwgIiAgIFstUEFSQU0tbmFtbnV0dHJ5Y2sgKFN0XHUwMEU0bGwgaW4gcGFyYW1ldGVyIGZcdTAwRjZyIGZvcm1hdG1hbGwpXSJ9LAotICB7ICAibm9QYXJzZXJtc2cxIiwgIlhTTC1wcm9jZXNzZW4gdXRmXHUwMEY2cmRlcyBpbnRlLiJ9LAotICB7ICAibm9QYXJzZXJtc2cyIiwgIioqIEhpdHRhZGUgaW50ZSBwYXJzZXIgKioifSwKLSAgeyAibm9QYXJzZXJtc2czIiwgICJLb250cm9sbGVyYSBrbGFzc1x1MDBGNmt2XHUwMEU0Z2VuLiJ9LAotICB7ICJub1BhcnNlcm1zZzQiLCAiT20gZHUgaW50ZSBoYXIgSUJNcyBYTUwgUGFyc2VyIGZcdTAwRjZyIEphdmEga2FuIGR1IGxhZGRhIG5lZCBkZW4gZnJcdTAwRTVuIn0sCi0gIHsgIm5vUGFyc2VybXNnNSIsICJJQk1zIEFscGhhV29ya3M6IGh0dHA6Ly93d3cuYWxwaGF3b3Jrcy5pYm0uY29tL2Zvcm11bGEveG1sIn0sCi0gIHsgIm9wdGlvblVSSVJFU09MVkVSIiwgIiAgIFstVVJJUkVTT0xWRVIgZnVsbHN0XHUwMEU0bmRpZ3Qga2xhc3NuYW1uIChVUklSZXNvbHZlciBzb20gYW52XHUwMEU0bmRzIHZpZCBtYXRjaG5pbmcgYXYgVVJJLWVyKV0ifSwKLSAgeyAib3B0aW9uRU5USVRZUkVTT0xWRVIiLCAgIiAgIFstRU5USVRZUkVTT0xWRVIgZnVsbHN0XHUwMEU0bmRpZ3Qga2xhc3NuYW1uIChFbnRpdHlSZXNvbHZlciBzb20gYW52XHUwMEU0bmRzIHZpZCBtYXRjaG5pbmcgYXYgZW5oZXRlcildIn0sCi0gIHsgIm9wdGlvbkNPTlRFTlRIQU5ETEVSIiwgICIgICBbLUNPTlRFTlRIQU5ETEVSIGZ1bGxzdFx1MDBFNG5kaWd0IGtsYXNzbmFtbiAoQ29udGVudEhhbmRsZXIgc29tIGFudlx1MDBFNG5kcyB2aWQgc2VyaWFsaXNlcmluZyBhdiB1dGRhdGEpXSJ9LAotICB7ICAib3B0aW9uTElORU5VTUJFUlMiLCAgIiAgIFstTCBhbnZcdTAwRTRuZCByYWRudW1tZXIgaSBrXHUwMEU0bGxkb2t1bWVudF0ifSwKLSAgeyAib3B0aW9uU0VDVVJFUFJPQ0VTU0lORyIsICIgICBbLVNFQ1VSRSAoYW5nZSBhdHQgc1x1MDBFNGtlciBiZWFyYmV0bmluZyBza2EgdGlsbFx1MDBFNG1wYXMuKV0ifSwKLQotICAgIC8vIEZvbGxvd2luZyBhcmUgdGhlIG5ldyBvcHRpb25zIGFkZGVkIGluIFhTTFRFcnJvclJlc291cmNlcy5wcm9wZXJ0aWVzIGZpbGVzIGFmdGVyIEpkayAxLjQgKFhhbGFuIDIuMi1EMTEpCi0KLQotICB7ICAib3B0aW9uTUVESUEiLCAgIiAgIFstTUVESUEgbWVkaWFUeXBlIChhbnZcdTAwRTRuZCBtZWRpZWF0dHJpYnV0IGZcdTAwRjZyIGF0dCBoaXR0YSBmb3JtYXRtYWxsIHNvbSBoXHUwMEY2ciBpaG9wIG1lZCBkb2t1bWVudC4pXSJ9LAotICB7ICAib3B0aW9uRkxBVk9SIiwgICIgICBbLUZMQVZPUiBmbGF2b3JOYW1lIChBbnZcdTAwRTRuZCBzMnM9U0FYIGVsbGVyIGQyZD1ET00gdmlkIHRyYW5zZm9ybWVyaW5nLildICJ9LCAvLyBBZGRlZCBieSBzYm9hZy9zY3VyY3VydTsgZXhwZXJpbWVudGFsCi0gIHsgIm9wdGlvbkRJQUciLCAiICAgWy1ESUFHIChTa3JpdiB1dCB0aWQgZlx1MDBGNnIgdHJhbnNmb3JtZXJpbmcgaSBtaWxsaXNla3VuZGVyLildIn0sCi0gIHsgIm9wdGlvbklOQ1JFTUVOVEFMIiwgICIgICBbLUlOQ1JFTUVOVEFMIChiZWdcdTAwRTRyIGlua3JlbWVudGVsbCBEVE0ta29uc3RydWt0aW9uIGdlbm9tIGF0dCBhbmdlIGh0dHA6Ly94bWwuYXBhY2hlLm9yZy94YWxhbi9mZWF0dXJlcy9pbmNyZW1lbnRhbCB0cnVlLildIn0sCi0gIHsgICJvcHRpb25OT09QVElNSU1JWkUiLCAgIiAgIFstTk9PUFRJTUlNSVpFIChiZWdcdTAwRTRyIGF0dCBpbmdlbiBmb3JtYXRtYWxsc29wdGltZXJpbmcgdXRmXHUwMEY2cnMgZ2Vub20gYXR0IGFuZ2UgaHR0cDovL3htbC5hcGFjaGUub3JnL3hhbGFuL2ZlYXR1cmVzL29wdGltaXplIGZhbHNlLildIn0sCi0gIHsgIm9wdGlvblJMIiwgICIgICBbLVJMIHJla3Vyc2lvbnNnclx1MDBFNG5zICh2ZXJpZmllcmEgbnVtZXJpc2t0IGdyXHUwMEU0bnN2XHUwMEU0cmRlIGZcdTAwRjZyIGZvcm1hdG1hbGxlbnMgcmVrdXJzaW9uc2RqdXAuKV0ifSwKLSAgeyAgICJvcHRpb25YTyIsICAiICAgWy1YTyBbdHJhbnNsZXROYW1lXSAodGlsbGRlbGEgbmFtbmV0IHRpbGwgZ2VuZXJlcmFkIHRyYW5zbGV0KV0ifSwKLSAgeyAgIm9wdGlvblhEIiwgIiAgIFstWEQgZGVzdGluYXRpb25EaXJlY3RvcnkgKGFuZ2UgZGVzdGluYXRpb25za2F0YWxvZyBmXHUwMEY2ciB0cmFuc2xldCldIn0sCi0gIHsgICJvcHRpb25YSiIsICAiICAgWy1YSiBqYXJmaWxlIChwYWtldGVyYXIgdHJhbnNsZXRrbGFzc2VybmEgaSBlbiBqYXItZmlsIG1lZCBuYW1uZXQgPGphcmZpbGU+KV0ifSwKLSAgeyAgICJvcHRpb25YUCIsICAiICAgWy1YUCBwYWNrYWdlIChhbmdlciBwYWtldG5hbW5zcHJlZml4IGZcdTAwRjZyIGFsbGEgZ2VuZXJlcmFkZSB0cmFuc2xldGtsYXNzZXIpXSJ9LAotCi0gIC8vQWRkSVRJT05BTCAgU1RSSU5HUyB0aGF0IG5lZWQgTDEwbgotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIGRlc2NyaWJlcyB1c2FnZSBvZiBhIHBhcnRpY3VsYXIKLSAgLy8gY29tbWFuZC1saW5lIG9wdGlvbiB0aGF0IGlzIHVzZWQgdG8gZW5hYmxlIHRoZSAidGVtcGxhdGUgaW5saW5pbmciCi0gIC8vIG9wdGltaXphdGlvbi4gIFRoZSBvcHRpbWl6YXRpb24gaW52b2x2ZXMgbWFraW5nIGEgY29weSBvZiB0aGUgY29kZQotICAvLyBnZW5lcmF0ZWQgZm9yIGEgdGVtcGxhdGUgaW4gYW5vdGhlciB0ZW1wbGF0ZSB0aGF0IHJlZmVycyB0byBpdC4KLSAgeyAib3B0aW9uWE4iLCAgIiAgIFstWE4gKGFrdGl2ZXJhciBtYWxsaW5mb2duaW5nKV0iIH0sCi0gIHsgIm9wdGlvblhYIiwgICIgICBbLVhYIChha3RpdmVyYXIgeXR0ZXJsaWdhcmUgZmVsc1x1MDBGNmtuaW5nc21lZGRlbGFuZGVuKV0ifSwKLSAgeyAib3B0aW9uWFQiICwgIiAgIFstWFQgKGFudlx1MDBFNG5kZXIgdHJhbnNsZXQgdmlkIHRyYW5zZm9ybWVyaW5nIG9tIG1cdTAwRjZqbGlndCldIn0sCi0gIHsgImRpYWdUaW1pbmciLCIgLS0tLS0tLS0tIFRyYW5zZm9ybWVyaW5nIGF2IHswfSB2aWEgezF9IHRvZyB7Mn0gbXMiIH0sCi0gIHsgInJlY3Vyc2lvblRvb0RlZXAiLCJNYWxsa2Fwc2xpbmdlbiBcdTAwRTRyIGZcdTAwRjZyIGRqdXAuIGthcHNsaW5nID0gezB9LCBtYWxsIHsxfSB7Mn0iIH0sCi0gIHsgIm5hbWVJcyIsICJuYW1uZXQgXHUwMEU0ciIgfSwKLSAgeyAibWF0Y2hQYXR0ZXJuSXMiLCAibWF0Y2huaW5nc21cdTAwRjZuc3RyZXQgXHUwMEU0ciIgfQotCi0gIH07Ci0KLSAgfQotICAvLyA9PT09PT09PT09PT09PT09PSBJTkZSQVNUUlVDVFVSRSA9PT09PT09PT09PT09PT09PT09PT09Ci0KLSAgLyoqIFN0cmluZyBmb3IgdXNlIHdoZW4gYSBiYWQgZXJyb3IgY29kZSB3YXMgZW5jb3VudGVyZWQuICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEJBRF9DT0RFID0gIkJBRF9DT0RFIjsKLQotICAvKiogU3RyaW5nIGZvciB1c2Ugd2hlbiBmb3JtYXR0aW5nIG9mIHRoZSBlcnJvciBzdHJpbmcgZmFpbGVkLiAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEZPUk1BVF9GQUlMRUQgPSAiRk9STUFUX0ZBSUxFRCI7Ci0KLSAgLyoqIEdlbmVyYWwgZXJyb3Igc3RyaW5nLiAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUk9SX1NUUklORyA9ICIjZXJyb3IiOwotCi0gIC8qKiBTdHJpbmcgdG8gcHJlcGVuZCB0byBlcnJvciBtZXNzYWdlcy4gICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUk9SX0hFQURFUiA9ICJFcnJvcjogIjsKLQotICAvKiogU3RyaW5nIHRvIHByZXBlbmQgdG8gd2FybmluZyBtZXNzYWdlcy4gICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0FSTklOR19IRUFERVIgPSAiV2FybmluZzogIjsKLQotICAvKiogU3RyaW5nIHRvIHNwZWNpZnkgdGhlIFhTTFQgbW9kdWxlLiAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgWFNMX0hFQURFUiA9ICJYU0xUICI7Ci0KLSAgLyoqIFN0cmluZyB0byBzcGVjaWZ5IHRoZSBYTUwgcGFyc2VyIG1vZHVsZS4gICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFhNTF9IRUFERVIgPSAiWE1MICI7Ci0KLSAgLyoqIEkgZG9uJ3QgdGhpbmsgdGhpcyBpcyB1c2VkIGFueSBtb3JlLgotICAgKiBAZGVwcmVjYXRlZCAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgUVVFUllfSEVBREVSID0gIlBBVFRFUk4gIjsKLQotCi0gICAgfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC9yZXMvWFNMVEVycm9yUmVzb3VyY2VzX3poX0NOLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3Jlcy9YU0xURXJyb3JSZXNvdXJjZXNfemhfQ04uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYmQ4ZjlhNS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3Jlcy9YU0xURXJyb3JSZXNvdXJjZXNfemhfQ04uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE0NDcgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwucmVzOwotCi1pbXBvcnQgamF2YS51dGlsLkxpc3RSZXNvdXJjZUJ1bmRsZTsKLWltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwotaW1wb3J0IGphdmEudXRpbC5NaXNzaW5nUmVzb3VyY2VFeGNlcHRpb247Ci1pbXBvcnQgamF2YS51dGlsLlJlc291cmNlQnVuZGxlOwotCi0vKioKLSAqIFNldCB1cCBlcnJvciBtZXNzYWdlcy4KLSAqIFdlIGJ1aWxkIGEgdHdvIGRpbWVuc2lvbmFsIGFycmF5IG9mIG1lc3NhZ2Uga2V5cyBhbmQKLSAqIG1lc3NhZ2Ugc3RyaW5ncy4gSW4gb3JkZXIgdG8gYWRkIGEgbmV3IG1lc3NhZ2UgaGVyZSwKLSAqIHlvdSBuZWVkIHRvIGZpcnN0IGFkZCBhIFN0cmluZyBjb25zdGFudC4gQW5kCi0gKiAgeW91IG5lZWQgdG8gZW50ZXIga2V5ICwgdmFsdWUgcGFpciBhcyBwYXJ0IG9mIGNvbnRlbnRzCi0gKiBBcnJheS4gWW91IGFsc28gbmVlZCB0byB1cGRhdGUgTUFYX0NPREUgZm9yIGVycm9yIHN0cmluZ3MKLSAqIGFuZCBNQVhfV0FSTklORyBmb3Igd2FybmluZ3MgKCBOZWVkZWQgZm9yIG9ubHkgaW5mb3JtYXRpb24KLSAqIHB1cnBvc2UgKQotICovCi1wdWJsaWMgY2xhc3MgWFNMVEVycm9yUmVzb3VyY2VzX3poX0NOIGV4dGVuZHMgTGlzdFJlc291cmNlQnVuZGxlCi17Ci0KLS8qCi0gKiBUaGlzIGZpbGUgY29udGFpbnMgZXJyb3IgYW5kIHdhcm5pbmcgbWVzc2FnZXMgcmVsYXRlZCB0byBYYWxhbiBFcnJvcgotICogSGFuZGxpbmcuCi0gKgotICogIEdlbmVyYWwgbm90ZXMgdG8gdHJhbnNsYXRvcnM6Ci0gKgotICogIDEpIFhhbGFuIChvciBtb3JlIHByb3Blcmx5LCBYYWxhbi1pbnRlcnByZXRpdmUpIGFuZCBYU0xUQyBhcmUgbmFtZXMgb2YKLSAqICAgICBjb21wb25lbnRzLgotICogICAgIFhTTFQgaXMgYW4gYWNyb255bSBmb3IgIlhNTCBTdHlsZXNoZWV0IExhbmd1YWdlOiBUcmFuc2Zvcm1hdGlvbnMiLgotICogICAgIFhTTFRDIGlzIGFuIGFjcm9ueW0gZm9yIFhTTFQgQ29tcGlsZXIuCi0gKgotICogIDIpIEEgc3R5bGVzaGVldCBpcyBhIGRlc2NyaXB0aW9uIG9mIGhvdyB0byB0cmFuc2Zvcm0gYW4gaW5wdXQgWE1MIGRvY3VtZW50Ci0gKiAgICAgaW50byBhIHJlc3VsdGFudCBYTUwgZG9jdW1lbnQgKG9yIEhUTUwgZG9jdW1lbnQgb3IgdGV4dCkuICBUaGUKLSAqICAgICBzdHlsZXNoZWV0IGl0c2VsZiBpcyBkZXNjcmliZWQgaW4gdGhlIGZvcm0gb2YgYW4gWE1MIGRvY3VtZW50LgotICoKLSAqICAzKSBBIHRlbXBsYXRlIGlzIGEgY29tcG9uZW50IG9mIGEgc3R5bGVzaGVldCB0aGF0IGlzIHVzZWQgdG8gbWF0Y2ggYQotICogICAgIHBhcnRpY3VsYXIgcG9ydGlvbiBvZiBhbiBpbnB1dCBkb2N1bWVudCBhbmQgc3BlY2lmaWVzIHRoZSBmb3JtIG9mIHRoZQotICogICAgIGNvcnJlc3BvbmRpbmcgcG9ydGlvbiBvZiB0aGUgb3V0cHV0IGRvY3VtZW50LgotICoKLSAqICA0KSBBbiBlbGVtZW50IGlzIGEgbWFyay11cCB0YWcgaW4gYW4gWE1MIGRvY3VtZW50OyBhbiBhdHRyaWJ1dGUgaXMgYQotICogICAgIG1vZGlmaWVyIG9uIHRoZSB0YWcuICBGb3IgZXhhbXBsZSwgaW4gPGVsZW0gYXR0cj0ndmFsJyBhdHRyMj0ndmFsMic+Ci0gKiAgICAgImVsZW0iIGlzIGFuIGVsZW1lbnQgbmFtZSwgImF0dHIiIGFuZCAiYXR0cjIiIGFyZSBhdHRyaWJ1dGUgbmFtZXMgd2l0aAotICogICAgIHRoZSB2YWx1ZXMgInZhbCIgYW5kICJ2YWwyIiwgcmVzcGVjdGl2ZWx5LgotICoKLSAqICA1KSBBIG5hbWVzcGFjZSBkZWNsYXJhdGlvbiBpcyBhIHNwZWNpYWwgYXR0cmlidXRlIHRoYXQgaXMgdXNlZCB0byBhc3NvY2lhdGUKLSAqICAgICBhIHByZWZpeCB3aXRoIGEgVVJJICh0aGUgbmFtZXNwYWNlKS4gIFRoZSBtZWFuaW5ncyBvZiBlbGVtZW50IG5hbWVzIGFuZAotICogICAgIGF0dHJpYnV0ZSBuYW1lcyB0aGF0IHVzZSB0aGF0IHByZWZpeCBhcmUgZGVmaW5lZCB3aXRoIHJlc3BlY3QgdG8gdGhhdAotICogICAgIG5hbWVzcGFjZS4KLSAqCi0gKiAgNikgIlRyYW5zbGV0IiBpcyBhbiBpbnZlbnRlZCB0ZXJtIHRoYXQgZGVzY3JpYmVzIHRoZSBjbGFzcyBmaWxlIHRoYXQKLSAqICAgICByZXN1bHRzIGZyb20gY29tcGlsaW5nIGFuIFhNTCBzdHlsZXNoZWV0IGludG8gYSBKYXZhIGNsYXNzLgotICoKLSAqICA3KSBYUGF0aCBpcyBhIHNwZWNpZmljYXRpb24gdGhhdCBkZXNjcmliZXMgYSBub3RhdGlvbiBmb3IgaWRlbnRpZnlpbmcKLSAqICAgICBub2RlcyBpbiBhIHRyZWUtc3RydWN0dXJlZCByZXByZXNlbnRhdGlvbiBvZiBhbiBYTUwgZG9jdW1lbnQuICBBbgotICogICAgIGluc3RhbmNlIG9mIHRoYXQgbm90YXRpb24gaXMgcmVmZXJyZWQgdG8gYXMgYW4gWFBhdGggZXhwcmVzc2lvbi4KLSAqCi0gKi8KLQotICAvKgotICAgKiBTdGF0aWMgdmFyaWFibGVzCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX05BTUVTUEFDRV9VUklfVkFMVUVfRk9SX1JFU1VMVF9QUkVGSVggPQotICAgICAgICAiRVJfSU5WQUxJRF9TRVRfTkFNRVNQQUNFX1VSSV9WQUxVRV9GT1JfUkVTVUxUX1BSRUZJWCI7Ci0KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9OQU1FU1BBQ0VfVVJJX1ZBTFVFX0ZPUl9SRVNVTFRfUFJFRklYX0ZPUl9ERUZBVUxUID0KLSAgICAgICAgIkVSX0lOVkFMSURfTkFNRVNQQUNFX1VSSV9WQUxVRV9GT1JfUkVTVUxUX1BSRUZJWF9GT1JfREVGQVVMVCI7Ci0KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fQ1VSTFlCUkFDRSA9ICJFUl9OT19DVVJMWUJSQUNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCA9ICJFUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSUxMRUdBTF9BVFRSSUJVVEUgPSAiRVJfSUxMRUdBTF9BVFRSSUJVVEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OVUxMX1NPVVJDRU5PREVfQVBQTFlJTVBPUlRTID0gIkVSX05VTExfU09VUkNFTk9ERV9BUFBMWUlNUE9SVFMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfQUREID0gIkVSX0NBTk5PVF9BREQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OVUxMX1NPVVJDRU5PREVfSEFORExFQVBQTFlURU1QTEFURVM9IkVSX05VTExfU09VUkNFTk9ERV9IQU5ETEVBUFBMWVRFTVBMQVRFUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX05BTUVfQVRUUklCID0gIkVSX05PX05BTUVfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVEVNUExBVEVfTk9UX0ZPVU5EID0gIkVSX1RFTVBMQVRFX05PVF9GT1VORCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfUkVTT0xWRV9OQU1FX0FWVCA9ICJFUl9DQU5UX1JFU09MVkVfTkFNRV9BVlQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SRVFVSVJFU19BVFRSSUIgPSAiRVJfUkVRVUlSRVNfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTVVTVF9IQVZFX1RFU1RfQVRUUklCID0gIkVSX01VU1RfSEFWRV9URVNUX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0JBRF9WQUxfT05fTEVWRUxfQVRUUklCID0KLSAgICAgICAgICJFUl9CQURfVkFMX09OX0xFVkVMX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BST0NFU1NJTkdJTlNUUlVDVElPTl9OQU1FX0NBTlRfQkVfWE1MID0KLSAgICAgICAgICJFUl9QUk9DRVNTSU5HSU5TVFJVQ1RJT05fTkFNRV9DQU5UX0JFX1hNTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BST0NFU1NJTkdJTlNUUlVDVElPTl9OT1RWQUxJRF9OQ05BTUUgPQotICAgICAgICAgIkVSX1BST0NFU1NJTkdJTlNUUlVDVElPTl9OT1RWQUxJRF9OQ05BTUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9ORUVEX01BVENIX0FUVFJJQiA9ICJFUl9ORUVEX01BVENIX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05FRURfTkFNRV9PUl9NQVRDSF9BVFRSSUIgPQotICAgICAgICAgIkVSX05FRURfTkFNRV9PUl9NQVRDSF9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX1JFU09MVkVfTlNQUkVGSVggPQotICAgICAgICAgIkVSX0NBTlRfUkVTT0xWRV9OU1BSRUZJWCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lMTEVHQUxfVkFMVUUgPSAiRVJfSUxMRUdBTF9WQUxVRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX09XTkVSRE9DID0gIkVSX05PX09XTkVSRE9DIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRUxFTVRFTVBMQVRFRUxFTV9FUlIgPSJFUl9FTEVNVEVNUExBVEVFTEVNX0VSUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05VTExfQ0hJTEQgPSAiRVJfTlVMTF9DSElMRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05FRURfU0VMRUNUX0FUVFJJQiA9ICJFUl9ORUVEX1NFTEVDVF9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9ORUVEX1RFU1RfQVRUUklCID0gIkVSX05FRURfVEVTVF9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9ORUVEX05BTUVfQVRUUklCID0gIkVSX05FRURfTkFNRV9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19DT05URVhUX09XTkVSRE9DID0gIkVSX05PX0NPTlRFWFRfT1dORVJET0MiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRF9OT1RfQ1JFQVRFX1hNTF9QUk9DX0xJQUlTT04gPQotICAgICAgICAgIkVSX0NPVUxEX05PVF9DUkVBVEVfWE1MX1BST0NfTElBSVNPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BST0NFU1NfTk9UX1NVQ0NFU1NGVUwgPQotICAgICAgICAgIkVSX1BST0NFU1NfTk9UX1NVQ0NFU1NGVUwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT1RfU1VDQ0VTU0ZVTCA9ICJFUl9OT1RfU1VDQ0VTU0ZVTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VOQ09ESU5HX05PVF9TVVBQT1JURUQgPQotICAgICAgICAgIkVSX0VOQ09ESU5HX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRF9OT1RfQ1JFQVRFX1RSQUNFTElTVEVORVIgPQotICAgICAgICAgIkVSX0NPVUxEX05PVF9DUkVBVEVfVFJBQ0VMSVNURU5FUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0tFWV9SRVFVSVJFU19OQU1FX0FUVFJJQiA9Ci0gICAgICAgICAiRVJfS0VZX1JFUVVJUkVTX05BTUVfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfS0VZX1JFUVVJUkVTX01BVENIX0FUVFJJQiA9Ci0gICAgICAgICAiRVJfS0VZX1JFUVVJUkVTX01BVENIX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0tFWV9SRVFVSVJFU19VU0VfQVRUUklCID0KLSAgICAgICAgICJFUl9LRVlfUkVRVUlSRVNfVVNFX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1JFUVVJUkVTX0VMRU1FTlRTX0FUVFJJQiA9Ci0gICAgICAgICAiRVJfUkVRVUlSRVNfRUxFTUVOVFNfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTUlTU0lOR19QUkVGSVhfQVRUUklCID0KLSAgICAgICAgICJFUl9NSVNTSU5HX1BSRUZJWF9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9CQURfU1RZTEVTSEVFVF9VUkwgPSAiRVJfQkFEX1NUWUxFU0hFRVRfVVJMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRklMRV9OT1RfRk9VTkQgPSAiRVJfRklMRV9OT1RfRk9VTkQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JT0VYQ0VQVElPTiA9ICJFUl9JT0VYQ0VQVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX0hSRUZfQVRUUklCID0gIkVSX05PX0hSRUZfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU1RZTEVTSEVFVF9JTkNMVURFU19JVFNFTEYgPQotICAgICAgICAgIkVSX1NUWUxFU0hFRVRfSU5DTFVERVNfSVRTRUxGIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJPQ0VTU0lOQ0xVREVfRVJST1IgPSJFUl9QUk9DRVNTSU5DTFVERV9FUlJPUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01JU1NJTkdfTEFOR19BVFRSSUIgPSAiRVJfTUlTU0lOR19MQU5HX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01JU1NJTkdfQ09OVEFJTkVSX0VMRU1FTlRfQ09NUE9ORU5UID0KLSAgICAgICAgICJFUl9NSVNTSU5HX0NPTlRBSU5FUl9FTEVNRU5UX0NPTVBPTkVOVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTl9PTkxZX09VVFBVVF9UT19FTEVNRU5UID0KLSAgICAgICAgICJFUl9DQU5fT05MWV9PVVRQVVRfVE9fRUxFTUVOVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BST0NFU1NfRVJST1IgPSAiRVJfUFJPQ0VTU19FUlJPUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1VOSU1QTE5PREVfRVJST1IgPSAiRVJfVU5JTVBMTk9ERV9FUlJPUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1NFTEVDVF9FWFBSRVNTSU9OID0iRVJfTk9fU0VMRUNUX0VYUFJFU1NJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfU0VSSUFMSVpFX1hTTFBST0NFU1NPUiA9Ci0gICAgICAgICAiRVJfQ0FOTk9UX1NFUklBTElaRV9YU0xQUk9DRVNTT1IiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19JTlBVVF9TVFlMRVNIRUVUID0gIkVSX05PX0lOUFVUX1NUWUxFU0hFRVQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GQUlMRURfUFJPQ0VTU19TVFlMRVNIRUVUID0KLSAgICAgICAgICJFUl9GQUlMRURfUFJPQ0VTU19TVFlMRVNIRUVUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTEROVF9QQVJTRV9ET0MgPSAiRVJfQ09VTEROVF9QQVJTRV9ET0MiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRE5UX0ZJTkRfRlJBR01FTlQgPQotICAgICAgICAgIkVSX0NPVUxETlRfRklORF9GUkFHTUVOVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PREVfTk9UX0VMRU1FTlQgPSAiRVJfTk9ERV9OT1RfRUxFTUVOVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZPUkVBQ0hfTkVFRF9NQVRDSF9PUl9OQU1FX0FUVFJJQiA9Ci0gICAgICAgICAiRVJfRk9SRUFDSF9ORUVEX01BVENIX09SX05BTUVfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVEVNUExBVEVTX05FRURfTUFUQ0hfT1JfTkFNRV9BVFRSSUIgPQotICAgICAgICAgIkVSX1RFTVBMQVRFU19ORUVEX01BVENIX09SX05BTUVfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fQ0xPTkVfT0ZfRE9DVU1FTlRfRlJBRyA9Ci0gICAgICAgICAiRVJfTk9fQ0xPTkVfT0ZfRE9DVU1FTlRfRlJBRyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfQ1JFQVRFX0lURU0gPSAiRVJfQ0FOVF9DUkVBVEVfSVRFTSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hNTFNQQUNFX0lMTEVHQUxfVkFMVUUgPQotICAgICAgICAgIkVSX1hNTFNQQUNFX0lMTEVHQUxfVkFMVUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19YU0xLRVlfREVDTEFSQVRJT04gPQotICAgICAgICAgIkVSX05PX1hTTEtFWV9ERUNMQVJBVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfQ1JFQVRFX1VSTCA9ICJFUl9DQU5UX0NSRUFURV9VUkwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YU0xGVU5DVElPTlNfVU5TVVBQT1JURUQgPQotICAgICAgICAgIkVSX1hTTEZVTkNUSU9OU19VTlNVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BST0NFU1NPUl9FUlJPUiA9ICJFUl9QUk9DRVNTT1JfRVJST1IiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT1RfQUxMT1dFRF9JTlNJREVfU1RZTEVTSEVFVCA9Ci0gICAgICAgICAiRVJfTk9UX0FMTE9XRURfSU5TSURFX1NUWUxFU0hFRVQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SRVNVTFROU19OT1RfU1VQUE9SVEVEID0KLSAgICAgICAgICJFUl9SRVNVTFROU19OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfREVGQVVMVFNQQUNFX05PVF9TVVBQT1JURUQgPQotICAgICAgICAgIkVSX0RFRkFVTFRTUEFDRV9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5ERU5UUkVTVUxUX05PVF9TVVBQT1JURUQgPQotICAgICAgICAgIkVSX0lOREVOVFJFU1VMVF9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSUxMRUdBTF9BVFRSSUIgPSAiRVJfSUxMRUdBTF9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTktOT1dOX1hTTF9FTEVNID0gIkVSX1VOS05PV05fWFNMX0VMRU0iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9CQURfWFNMU09SVF9VU0UgPSAiRVJfQkFEX1hTTFNPUlRfVVNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTUlTUExBQ0VEX1hTTFdIRU4gPSAiRVJfTUlTUExBQ0VEX1hTTFdIRU4iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YU0xXSEVOX05PVF9QQVJFTlRFRF9CWV9YU0xDSE9PU0UgPQotICAgICAgICAgIkVSX1hTTFdIRU5fTk9UX1BBUkVOVEVEX0JZX1hTTENIT09TRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01JU1BMQUNFRF9YU0xPVEhFUldJU0UgPQotICAgICAgICAgIkVSX01JU1BMQUNFRF9YU0xPVEhFUldJU0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YU0xPVEhFUldJU0VfTk9UX1BBUkVOVEVEX0JZX1hTTENIT09TRSA9Ci0gICAgICAgICAiRVJfWFNMT1RIRVJXSVNFX05PVF9QQVJFTlRFRF9CWV9YU0xDSE9PU0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT1RfQUxMT1dFRF9JTlNJREVfVEVNUExBVEUgPQotICAgICAgICAgIkVSX05PVF9BTExPV0VEX0lOU0lERV9URU1QTEFURSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1VOS05PV05fRVhUX05TX1BSRUZJWCA9Ci0gICAgICAgICAiRVJfVU5LTk9XTl9FWFRfTlNfUFJFRklYIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU1QT1JUU19BU19GSVJTVF9FTEVNID0KLSAgICAgICAgICJFUl9JTVBPUlRTX0FTX0ZJUlNUX0VMRU0iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTVBPUlRJTkdfSVRTRUxGID0gIkVSX0lNUE9SVElOR19JVFNFTEYiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YTUxTUEFDRV9JTExFR0FMX1ZBTCA9IkVSX1hNTFNQQUNFX0lMTEVHQUxfVkFMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJPQ0VTU1NUWUxFU0hFRVRfTk9UX1NVQ0NFU1NGVUwgPQotICAgICAgICAgIkVSX1BST0NFU1NTVFlMRVNIRUVUX05PVF9TVUNDRVNTRlVMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU0FYX0VYQ0VQVElPTiA9ICJFUl9TQVhfRVhDRVBUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWFNMVF9FUlJPUiA9ICJFUl9YU0xUX0VSUk9SIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ1VSUkVOQ1lfU0lHTl9JTExFR0FMPQotICAgICAgICAgIkVSX0NVUlJFTkNZX1NJR05fSUxMRUdBTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0RPQ1VNRU5UX0ZVTkNUSU9OX0lOVkFMSURfSU5fU1RZTEVTSEVFVF9ET00gPQotICAgICAgICAgIkVSX0RPQ1VNRU5UX0ZVTkNUSU9OX0lOVkFMSURfSU5fU1RZTEVTSEVFVF9ET00iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX1JFU09MVkVfUFJFRklYX09GX05PTl9QUkVGSVhfUkVTT0xWRVIgPQotICAgICAgICAgIkVSX0NBTlRfUkVTT0xWRV9QUkVGSVhfT0ZfTk9OX1BSRUZJWF9SRVNPTFZFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1JFRElSRUNUX0NPVUxETlRfR0VUX0ZJTEVOQU1FID0KLSAgICAgICAgICJFUl9SRURJUkVDVF9DT1VMRE5UX0dFVF9GSUxFTkFNRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9CVUlMRF9GT1JNQVRURVJMSVNURU5FUl9JTl9SRURJUkVDVCA9Ci0gICAgICAgICAiRVJfQ0FOTk9UX0JVSUxEX0ZPUk1BVFRFUkxJU1RFTkVSX0lOX1JFRElSRUNUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9QUkVGSVhfSU5fRVhDTFVERVJFU1VMVFBSRUZJWCA9Ci0gICAgICAgICAiRVJfSU5WQUxJRF9QUkVGSVhfSU5fRVhDTFVERVJFU1VMVFBSRUZJWCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01JU1NJTkdfTlNfVVJJID0gIkVSX01JU1NJTkdfTlNfVVJJIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTUlTU0lOR19BUkdfRk9SX09QVElPTiA9Ci0gICAgICAgICAiRVJfTUlTU0lOR19BUkdfRk9SX09QVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfT1BUSU9OID0gIkVSX0lOVkFMSURfT1BUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTUFMRk9STUVEX0ZPUk1BVF9TVFJJTkcgPQotICAgICAgICAgIkVSX01BTEZPUk1FRF9GT1JNQVRfU1RSSU5HIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU1RZTEVTSEVFVF9SRVFVSVJFU19WRVJTSU9OX0FUVFJJQiA9Ci0gICAgICAgICAiRVJfU1RZTEVTSEVFVF9SRVFVSVJFU19WRVJTSU9OX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lMTEVHQUxfQVRUUklCVVRFX1ZBTFVFID0KLSAgICAgICAgICJFUl9JTExFR0FMX0FUVFJJQlVURV9WQUxVRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NIT09TRV9SRVFVSVJFU19XSEVOID0iRVJfQ0hPT1NFX1JFUVVJUkVTX1dIRU4iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19BUFBMWV9JTVBPUlRfSU5fRk9SX0VBQ0ggPQotICAgICAgICAgIkVSX05PX0FQUExZX0lNUE9SVF9JTl9GT1JfRUFDSCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfVVNFX0RUTV9GT1JfT1VUUFVUID0KLSAgICAgICAgICJFUl9DQU5UX1VTRV9EVE1fRk9SX09VVFBVVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfVVNFX0RUTV9GT1JfSU5QVVQgPQotICAgICAgICAgIkVSX0NBTlRfVVNFX0RUTV9GT1JfSU5QVVQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQUxMX1RPX0VYVF9GQUlMRUQgPSAiRVJfQ0FMTF9UT19FWFRfRkFJTEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJFRklYX01VU1RfUkVTT0xWRSA9ICJFUl9QUkVGSVhfTVVTVF9SRVNPTFZFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9VVEYxNl9TVVJST0dBVEUgPQotICAgICAgICAgIkVSX0lOVkFMSURfVVRGMTZfU1VSUk9HQVRFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWFNMQVRUUlNFVF9VU0VEX0lUU0VMRiA9Ci0gICAgICAgICAiRVJfWFNMQVRUUlNFVF9VU0VEX0lUU0VMRiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9NSVhfWEVSQ0VTRE9NID0iRVJfQ0FOTk9UX01JWF9YRVJDRVNET00iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9UT09fTUFOWV9MSVNURU5FUlMgPSAiRVJfVE9PX01BTllfTElTVEVORVJTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5fRUxFTVRFTVBMQVRFRUxFTV9SRUFET0JKRUNUID0KLSAgICAgICAgICJFUl9JTl9FTEVNVEVNUExBVEVFTEVNX1JFQURPQkpFQ1QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9EVVBMSUNBVEVfTkFNRURfVEVNUExBVEUgPQotICAgICAgICAgIkVSX0RVUExJQ0FURV9OQU1FRF9URU1QTEFURSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfS0VZX0NBTEwgPSAiRVJfSU5WQUxJRF9LRVlfQ0FMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1JFRkVSRU5DSU5HX0lUU0VMRiA9ICJFUl9SRUZFUkVOQ0lOR19JVFNFTEYiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTExFR0FMX0RPTVNPVVJDRV9JTlBVVCA9Ci0gICAgICAgICAiRVJfSUxMRUdBTF9ET01TT1VSQ0VfSU5QVVQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DTEFTU19OT1RfRk9VTkRfRk9SX09QVElPTiA9Ci0gICAgICAgICAiRVJfQ0xBU1NfTk9UX0ZPVU5EX0ZPUl9PUFRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SRVFVSVJFRF9FTEVNX05PVF9GT1VORCA9Ci0gICAgICAgICAiRVJfUkVRVUlSRURfRUxFTV9OT1RfRk9VTkQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlBVVF9DQU5OT1RfQkVfTlVMTCA9IkVSX0lOUFVUX0NBTk5PVF9CRV9OVUxMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVVJJX0NBTk5PVF9CRV9OVUxMID0gIkVSX1VSSV9DQU5OT1RfQkVfTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZJTEVfQ0FOTk9UX0JFX05VTEwgPSAiRVJfRklMRV9DQU5OT1RfQkVfTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NPVVJDRV9DQU5OT1RfQkVfTlVMTCA9Ci0gICAgICAgICAiRVJfU09VUkNFX0NBTk5PVF9CRV9OVUxMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX0lOSVRfQlNGTUdSID0gIkVSX0NBTk5PVF9JTklUX0JTRk1HUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9DTVBMX0VYVEVOU04gPSAiRVJfQ0FOTk9UX0NNUExfRVhURU5TTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9DUkVBVEVfRVhURU5TTiA9Ci0gICAgICAgICAiRVJfQ0FOTk9UX0NSRUFURV9FWFRFTlNOIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5TVEFOQ0VfTVRIRF9DQUxMX1JFUVVJUkVTID0KLSAgICAgICAgICJFUl9JTlNUQU5DRV9NVEhEX0NBTExfUkVRVUlSRVMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX0VMRU1FTlRfTkFNRSA9IkVSX0lOVkFMSURfRUxFTUVOVF9OQU1FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRUxFTUVOVF9OQU1FX01FVEhPRF9TVEFUSUMgPQotICAgICAgICAgIkVSX0VMRU1FTlRfTkFNRV9NRVRIT0RfU1RBVElDIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhURU5TSU9OX0ZVTkNfVU5LTk9XTiA9Ci0gICAgICAgICAiRVJfRVhURU5TSU9OX0ZVTkNfVU5LTk9XTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01PUkVfTUFUQ0hfQ09OU1RSVUNUT1IgPQotICAgICAgICAgIkVSX01PUkVfTUFUQ0hfQ09OU1RSVUNUT1IiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9NT1JFX01BVENIX01FVEhPRCA9ICJFUl9NT1JFX01BVENIX01FVEhPRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01PUkVfTUFUQ0hfRUxFTUVOVCA9ICJFUl9NT1JFX01BVENIX0VMRU1FTlQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX0NPTlRFWFRfUEFTU0VEID0KLSAgICAgICAgICJFUl9JTlZBTElEX0NPTlRFWFRfUEFTU0VEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUE9PTF9FWElTVFMgPSAiRVJfUE9PTF9FWElTVFMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19EUklWRVJfTkFNRSA9ICJFUl9OT19EUklWRVJfTkFNRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1VSTCA9ICJFUl9OT19VUkwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QT09MX1NJWkVfTEVTU1RIQU5fT05FID0KLSAgICAgICAgICJFUl9QT09MX1NJWkVfTEVTU1RIQU5fT05FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9EUklWRVIgPSAiRVJfSU5WQUxJRF9EUklWRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19TVFlMRVNIRUVUUk9PVCA9ICJFUl9OT19TVFlMRVNIRUVUUk9PVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lMTEVHQUxfWE1MU1BBQ0VfVkFMVUUgPQotICAgICAgICAgIkVSX0lMTEVHQUxfWE1MU1BBQ0VfVkFMVUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUk9DRVNTRlJPTU5PREVfRkFJTEVEID0KLSAgICAgICAgICJFUl9QUk9DRVNTRlJPTU5PREVfRkFJTEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUkVTT1VSQ0VfQ09VTERfTk9UX0xPQUQgPQotICAgICAgICAgIkVSX1JFU09VUkNFX0NPVUxEX05PVF9MT0FEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQlVGRkVSX1NJWkVfTEVTU1RIQU5fWkVSTyA9Ci0gICAgICAgICAiRVJfQlVGRkVSX1NJWkVfTEVTU1RIQU5fWkVSTyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1VOS05PV05fRVJST1JfQ0FMTElOR19FWFRFTlNJT04gPQotICAgICAgICAgIkVSX1VOS05PV05fRVJST1JfQ0FMTElOR19FWFRFTlNJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19OQU1FU1BBQ0VfREVDTCA9ICJFUl9OT19OQU1FU1BBQ0VfREVDTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VMRU1fQ09OVEVOVF9OT1RfQUxMT1dFRCA9Ci0gICAgICAgICAiRVJfRUxFTV9DT05URU5UX05PVF9BTExPV0VEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU1RZTEVTSEVFVF9ESVJFQ1RFRF9URVJNSU5BVElPTiA9Ci0gICAgICAgICAiRVJfU1RZTEVTSEVFVF9ESVJFQ1RFRF9URVJNSU5BVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX09ORV9PUl9UV08gPSAiRVJfT05FX09SX1RXTyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1RXT19PUl9USFJFRSA9ICJFUl9UV09fT1JfVEhSRUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRF9OT1RfTE9BRF9SRVNPVVJDRSA9Ci0gICAgICAgICAiRVJfQ09VTERfTk9UX0xPQURfUkVTT1VSQ0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfSU5JVF9ERUZBVUxUX1RFTVBMQVRFUyA9Ci0gICAgICAgICAiRVJfQ0FOTk9UX0lOSVRfREVGQVVMVF9URU1QTEFURVMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SRVNVTFRfTlVMTCA9ICJFUl9SRVNVTFRfTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1JFU1VMVF9DT1VMRF9OT1RfQkVfU0VUID0KLSAgICAgICAgICJFUl9SRVNVTFRfQ09VTERfTk9UX0JFX1NFVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX09VVFBVVF9TUEVDSUZJRUQgPSAiRVJfTk9fT1VUUFVUX1NQRUNJRklFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9UUkFOU0ZPUk1fVE9fUkVTVUxUX1RZUEUgPQotICAgICAgICAgIkVSX0NBTk5PVF9UUkFOU0ZPUk1fVE9fUkVTVUxUX1RZUEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfVFJBTlNGT1JNX1NPVVJDRV9UWVBFID0KLSAgICAgICAgICJFUl9DQU5OT1RfVFJBTlNGT1JNX1NPVVJDRV9UWVBFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTlVMTF9DT05URU5UX0hBTkRMRVIgPSJFUl9OVUxMX0NPTlRFTlRfSEFORExFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05VTExfRVJST1JfSEFORExFUiA9ICJFUl9OVUxMX0VSUk9SX0hBTkRMRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfQ0FMTF9QQVJTRSA9ICJFUl9DQU5OT1RfQ0FMTF9QQVJTRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1BBUkVOVF9GT1JfRklMVEVSID0iRVJfTk9fUEFSRU5UX0ZPUl9GSUxURVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19TVFlMRVNIRUVUX0lOX01FRElBID0KLSAgICAgICAgICJFUl9OT19TVFlMRVNIRUVUX0lOX01FRElBIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fU1RZTEVTSEVFVF9QSSA9ICJFUl9OT19TVFlMRVNIRUVUX1BJIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9UX1NVUFBPUlRFRCA9ICJFUl9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJPUEVSVFlfVkFMVUVfQk9PTEVBTiA9Ci0gICAgICAgICAiRVJfUFJPUEVSVFlfVkFMVUVfQk9PTEVBTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxEX05PVF9GSU5EX0VYVEVSTl9TQ1JJUFQgPQotICAgICAgICAgIkVSX0NPVUxEX05PVF9GSU5EX0VYVEVSTl9TQ1JJUFQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SRVNPVVJDRV9DT1VMRF9OT1RfRklORCA9Ci0gICAgICAgICAiRVJfUkVTT1VSQ0VfQ09VTERfTk9UX0ZJTkQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9PVVRQVVRfUFJPUEVSVFlfTk9UX1JFQ09HTklaRUQgPQotICAgICAgICAgIkVSX09VVFBVVF9QUk9QRVJUWV9OT1RfUkVDT0dOSVpFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZBSUxFRF9DUkVBVElOR19FTEVNTElUUlNMVCA9Ci0gICAgICAgICAiRVJfRkFJTEVEX0NSRUFUSU5HX0VMRU1MSVRSU0xUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVkFMVUVfU0hPVUxEX0JFX05VTUJFUiA9Ci0gICAgICAgICAiRVJfVkFMVUVfU0hPVUxEX0JFX05VTUJFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1ZBTFVFX1NIT1VMRF9FUVVBTCA9ICJFUl9WQUxVRV9TSE9VTERfRVFVQUwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GQUlMRURfQ0FMTElOR19NRVRIT0QgPQotICAgICAgICAgIkVSX0ZBSUxFRF9DQUxMSU5HX01FVEhPRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZBSUxFRF9DUkVBVElOR19FTEVNVE1QTCA9Ci0gICAgICAgICAiRVJfRkFJTEVEX0NSRUFUSU5HX0VMRU1UTVBMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0hBUlNfTk9UX0FMTE9XRUQgPSAiRVJfQ0hBUlNfTk9UX0FMTE9XRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9BVFRSX05PVF9BTExPV0VEID0gIkVSX0FUVFJfTk9UX0FMTE9XRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9CQURfVkFMVUUgPSAiRVJfQkFEX1ZBTFVFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQVRUUklCX1ZBTFVFX05PVF9GT1VORCA9Ci0gICAgICAgICAiRVJfQVRUUklCX1ZBTFVFX05PVF9GT1VORCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FUVFJJQl9WQUxVRV9OT1RfUkVDT0dOSVpFRCA9Ci0gICAgICAgICAiRVJfQVRUUklCX1ZBTFVFX05PVF9SRUNPR05JWkVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTlVMTF9VUklfTkFNRVNQQUNFID0gIkVSX05VTExfVVJJX05BTUVTUEFDRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05VTUJFUl9UT09fQklHID0gIkVSX05VTUJFUl9UT09fQklHIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgIEVSX0NBTk5PVF9GSU5EX1NBWDFfRFJJVkVSID0KLSAgICAgICAgICJFUl9DQU5OT1RfRklORF9TQVgxX0RSSVZFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nICBFUl9TQVgxX0RSSVZFUl9OT1RfTE9BREVEID0KLSAgICAgICAgICJFUl9TQVgxX0RSSVZFUl9OT1RfTE9BREVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgIEVSX1NBWDFfRFJJVkVSX05PVF9JTlNUQU5USUFURUQgPQotICAgICAgICAgIkVSX1NBWDFfRFJJVkVSX05PVF9JTlNUQU5USUFURUQiIDsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU0FYMV9EUklWRVJfTk9UX0lNUExFTUVOVF9QQVJTRVIgPQotICAgICAgICAgIkVSX1NBWDFfRFJJVkVSX05PVF9JTVBMRU1FTlRfUEFSU0VSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgIEVSX1BBUlNFUl9QUk9QRVJUWV9OT1RfU1BFQ0lGSUVEID0KLSAgICAgICAgICJFUl9QQVJTRVJfUFJPUEVSVFlfTk9UX1NQRUNJRklFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nICBFUl9QQVJTRVJfQVJHX0NBTk5PVF9CRV9OVUxMID0KLSAgICAgICAgICJFUl9QQVJTRVJfQVJHX0NBTk5PVF9CRV9OVUxMIiA7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nICBFUl9GRUFUVVJFID0gIkVSX0ZFQVRVUkUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUk9QRVJUWSA9ICJFUl9QUk9QRVJUWSIgOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OVUxMX0VOVElUWV9SRVNPTFZFUiA9IkVSX05VTExfRU5USVRZX1JFU09MVkVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgIEVSX05VTExfRFREX0hBTkRMRVIgPSAiRVJfTlVMTF9EVERfSEFORExFUiIgOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19EUklWRVJfTkFNRV9TUEVDSUZJRUQgPQotICAgICAgICAgIkVSX05PX0RSSVZFUl9OQU1FX1NQRUNJRklFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1VSTF9TUEVDSUZJRUQgPSAiRVJfTk9fVVJMX1NQRUNJRklFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BPT0xTSVpFX0xFU1NfVEhBTl9PTkUgPQotICAgICAgICAgIkVSX1BPT0xTSVpFX0xFU1NfVEhBTl9PTkUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX0RSSVZFUl9OQU1FID0gIkVSX0lOVkFMSURfRFJJVkVSX05BTUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FUlJPUkxJU1RFTkVSID0gIkVSX0VSUk9STElTVEVORVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9BU1NFUlRfTk9fVEVNUExBVEVfUEFSRU5UID0KLSAgICAgICAgICJFUl9BU1NFUlRfTk9fVEVNUExBVEVfUEFSRU5UIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQVNTRVJUX1JFRFVOREVOVF9FWFBSX0VMSU1JTkFUT1IgPQotICAgICAgICAgIkVSX0FTU0VSVF9SRURVTkRFTlRfRVhQUl9FTElNSU5BVE9SIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9UX0FMTE9XRURfSU5fUE9TSVRJT04gPQotICAgICAgICAgIkVSX05PVF9BTExPV0VEX0lOX1BPU0lUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9OV0hJVEVTUEFDRV9OT1RfQUxMT1dFRF9JTl9QT1NJVElPTiA9Ci0gICAgICAgICAiRVJfTk9OV0hJVEVTUEFDRV9OT1RfQUxMT1dFRF9JTl9QT1NJVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05BTUVTUEFDRV9DT05URVhUX05VTExfTkFNRVNQQUNFID0KLSAgICAgICAgICJFUl9OQU1FU1BBQ0VfQ09OVEVYVF9OVUxMX05BTUVTUEFDRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05BTUVTUEFDRV9DT05URVhUX05VTExfUFJFRklYID0KLSAgICAgICAgICJFUl9OQU1FU1BBQ0VfQ09OVEVYVF9OVUxMX1BSRUZJWCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hQQVRIX1JFU09MVkVSX05VTExfUU5BTUUgPQotICAgICAgICAgIkVSX1hQQVRIX1JFU09MVkVSX05VTExfUU5BTUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YUEFUSF9SRVNPTFZFUl9ORUdBVElWRV9BUklUWSA9Ci0gICAgICAgICAiRVJfWFBBVEhfUkVTT0xWRVJfTkVHQVRJVkVfQVJJVFkiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBJTlZBTElEX1RDSEFSID0gIklOVkFMSURfVENIQVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBJTlZBTElEX1FOQU1FID0gIklOVkFMSURfUU5BTUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBJTlZBTElEX0VOVU0gPSAiSU5WQUxJRF9FTlVNIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSU5WQUxJRF9OTVRPS0VOID0gIklOVkFMSURfTk1UT0tFTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIElOVkFMSURfTkNOQU1FID0gIklOVkFMSURfTkNOQU1FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSU5WQUxJRF9CT09MRUFOID0gIklOVkFMSURfQk9PTEVBTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIElOVkFMSURfTlVNQkVSID0gIklOVkFMSURfTlVNQkVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQVJHX0xJVEVSQUwgPSAiRVJfQVJHX0xJVEVSQUwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9EVVBMSUNBVEVfR0xPQkFMX1ZBUiA9IkVSX0RVUExJQ0FURV9HTE9CQUxfVkFSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRFVQTElDQVRFX1ZBUiA9ICJFUl9EVVBMSUNBVEVfVkFSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVEVNUExBVEVfTkFNRV9NQVRDSCA9ICJFUl9URU1QTEFURV9OQU1FX01BVENIIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9QUkVGSVggPSAiRVJfSU5WQUxJRF9QUkVGSVgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19BVFRSSUJfU0VUID0gIkVSX05PX0FUVFJJQl9TRVQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GVU5DVElPTl9OT1RfRk9VTkQgPQotICAgICAgICAgIkVSX0ZVTkNUSU9OX05PVF9GT1VORCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfSEFWRV9DT05URU5UX0FORF9TRUxFQ1QgPQotICAgICAiRVJfQ0FOVF9IQVZFX0NPTlRFTlRfQU5EX1NFTEVDVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfU0VUX1BBUkFNX1ZBTFVFID0gIkVSX0lOVkFMSURfU0VUX1BBUkFNX1ZBTFVFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU0VUX0ZFQVRVUkVfTlVMTF9OQU1FID0KLSAgICAgICAgIkVSX1NFVF9GRUFUVVJFX05VTExfTkFNRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0dFVF9GRUFUVVJFX05VTExfTkFNRSA9Ci0gICAgICAgICJFUl9HRVRfRkVBVFVSRV9OVUxMX05BTUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTlNVUFBPUlRFRF9GRUFUVVJFID0KLSAgICAgICAgIkVSX1VOU1VQUE9SVEVEX0ZFQVRVUkUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FWFRFTlNJT05fRUxFTUVOVF9OT1RfQUxMT1dFRF9JTl9TRUNVUkVfUFJPQ0VTU0lORyA9Ci0gICAgICAgICJFUl9FWFRFTlNJT05fRUxFTUVOVF9OT1RfQUxMT1dFRF9JTl9TRUNVUkVfUFJPQ0VTU0lORyI7Ci0KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfRk9VTkRfQ1VSTFlCUkFDRSA9ICJXR19GT1VORF9DVVJMWUJSQUNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfQ09VTlRfQVRUUklCX01BVENIRVNfTk9fQU5DRVNUT1IgPQotICAgICAgICAgIldHX0NPVU5UX0FUVFJJQl9NQVRDSEVTX05PX0FOQ0VTVE9SIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfRVhQUl9BVFRSSUJfQ0hBTkdFRF9UT19TRUxFQ1QgPQotICAgICAgICAgIldHX0VYUFJfQVRUUklCX0NIQU5HRURfVE9fU0VMRUNUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfTk9fTE9DQUxFX0lOX0ZPUk1BVE5VTUJFUiA9Ci0gICAgICAgICAiV0dfTk9fTE9DQUxFX0lOX0ZPUk1BVE5VTUJFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0xPQ0FMRV9OT1RfRk9VTkQgPSAiV0dfTE9DQUxFX05PVF9GT1VORCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0NBTk5PVF9NQUtFX1VSTF9GUk9NID0iV0dfQ0FOTk9UX01BS0VfVVJMX0ZST00iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19DQU5OT1RfTE9BRF9SRVFVRVNURURfRE9DID0KLSAgICAgICAgICJXR19DQU5OT1RfTE9BRF9SRVFVRVNURURfRE9DIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfQ0FOTk9UX0ZJTkRfQ09MTEFUT1IgPSJXR19DQU5OT1RfRklORF9DT0xMQVRPUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0ZVTkNUSU9OU19TSE9VTERfVVNFX1VSTCA9Ci0gICAgICAgICAiV0dfRlVOQ1RJT05TX1NIT1VMRF9VU0VfVVJMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfRU5DT0RJTkdfTk9UX1NVUFBPUlRFRF9VU0lOR19VVEY4ID0KLSAgICAgICAgICJXR19FTkNPRElOR19OT1RfU1VQUE9SVEVEX1VTSU5HX1VURjgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19FTkNPRElOR19OT1RfU1VQUE9SVEVEX1VTSU5HX0pBVkEgPQotICAgICAgICAgIldHX0VOQ09ESU5HX05PVF9TVVBQT1JURURfVVNJTkdfSkFWQSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX1NQRUNJRklDSVRZX0NPTkZMSUNUUyA9Ci0gICAgICAgICAiV0dfU1BFQ0lGSUNJVFlfQ09ORkxJQ1RTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfUEFSU0lOR19BTkRfUFJFUEFSSU5HID0KLSAgICAgICAgICJXR19QQVJTSU5HX0FORF9QUkVQQVJJTkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19BVFRSX1RFTVBMQVRFID0gIldHX0FUVFJfVEVNUExBVEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19DT05GTElDVF9CRVRXRUVOX1hTTFNUUklQU1BBQ0VfQU5EX1hTTFBSRVNFUlZFU1BBQ0UgPSAiV0dfQ09ORkxJQ1RfQkVUV0VFTl9YU0xTVFJJUFNQQUNFX0FORF9YU0xQUkVTRVJWRVNQIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfQVRUUklCX05PVF9IQU5ETEVEID0gIldHX0FUVFJJQl9OT1RfSEFORExFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX05PX0RFQ0lNQUxGT1JNQVRfREVDTEFSQVRJT04gPQotICAgICAgICAgIldHX05PX0RFQ0lNQUxGT1JNQVRfREVDTEFSQVRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19PTERfWFNMVF9OUyA9ICJXR19PTERfWFNMVF9OUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX09ORV9ERUZBVUxUX1hTTERFQ0lNQUxGT1JNQVRfQUxMT1dFRCA9Ci0gICAgICAgICAiV0dfT05FX0RFRkFVTFRfWFNMREVDSU1BTEZPUk1BVF9BTExPV0VEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfWFNMREVDSU1BTEZPUk1BVF9OQU1FU19NVVNUX0JFX1VOSVFVRSA9Ci0gICAgICAgICAiV0dfWFNMREVDSU1BTEZPUk1BVF9OQU1FU19NVVNUX0JFX1VOSVFVRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0lMTEVHQUxfQVRUUklCVVRFID0gIldHX0lMTEVHQUxfQVRUUklCVVRFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfQ09VTERfTk9UX1JFU09MVkVfUFJFRklYID0KLSAgICAgICAgICJXR19DT1VMRF9OT1RfUkVTT0xWRV9QUkVGSVgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19TVFlMRVNIRUVUX1JFUVVJUkVTX1ZFUlNJT05fQVRUUklCID0KLSAgICAgICAgICJXR19TVFlMRVNIRUVUX1JFUVVJUkVTX1ZFUlNJT05fQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfSUxMRUdBTF9BVFRSSUJVVEVfTkFNRSA9Ci0gICAgICAgICAiV0dfSUxMRUdBTF9BVFRSSUJVVEVfTkFNRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0lMTEVHQUxfQVRUUklCVVRFX1ZBTFVFID0KLSAgICAgICAgICJXR19JTExFR0FMX0FUVFJJQlVURV9WQUxVRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0VNUFRZX1NFQ09ORF9BUkcgPSAiV0dfRU1QVFlfU0VDT05EX0FSRyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX1BST0NFU1NJTkdJTlNUUlVDVElPTl9OQU1FX0NBTlRfQkVfWE1MID0KLSAgICAgICAgICJXR19QUk9DRVNTSU5HSU5TVFJVQ1RJT05fTkFNRV9DQU5UX0JFX1hNTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX1BST0NFU1NJTkdJTlNUUlVDVElPTl9OT1RWQUxJRF9OQ05BTUUgPQotICAgICAgICAgIldHX1BST0NFU1NJTkdJTlNUUlVDVElPTl9OT1RWQUxJRF9OQ05BTUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19JTExFR0FMX0FUVFJJQlVURV9QT1NJVElPTiA9Ci0gICAgICAgICAiV0dfSUxMRUdBTF9BVFRSSUJVVEVfUE9TSVRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIgPQotICAgICAgICAgIk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiI7Ci0KLSAgLyoKLSAgICogTm93IGZpbGwgaW4gdGhlIG1lc3NhZ2UgdGV4dC4KLSAgICogVGhlbiBmaWxsIGluIHRoZSBtZXNzYWdlIHRleHQgZm9yIHRoYXQgbWVzc2FnZSBjb2RlIGluIHRoZQotICAgKiBhcnJheS4gVXNlIHRoZSBuZXcgZXJyb3IgY29kZSBhcyB0aGUgaW5kZXggaW50byB0aGUgYXJyYXkuCi0gICAqLwotCi0gIC8vIEVycm9yIG1lc3NhZ2VzLi4uCi0KLSAgLyoqIEdldCB0aGUgbG9va3VwIHRhYmxlIGZvciBlcnJvciBtZXNzYWdlcy4KLSAgICAqCi0gICAgKiBAcmV0dXJuIFRoZSBtZXNzYWdlIGxvb2t1cCB0YWJsZS4KLSAgICAqLwotICBwdWJsaWMgT2JqZWN0W11bXSBnZXRDb250ZW50cygpCi0gIHsKLSAgICAgIHJldHVybiBuZXcgT2JqZWN0W11bXSB7Ci0KLSAgLyoqIEVycm9yIG1lc3NhZ2UgSUQgdGhhdCBoYXMgYSBudWxsIG1lc3NhZ2UsIGJ1dCB0YWtlcyBpbiBhIHNpbmdsZSBvYmplY3QuICAgICovCi0gIHsiRVIwMDAwIiAsICJ7MH0iIH0sCi0KLSAgICB7IEVSX05PX0NVUkxZQlJBQ0UsCi0gICAgICAiXHU5NTE5XHU4QkVGOiBcdTg4NjhcdThGQkVcdTVGMEZcdTRFMkRcdTRFMERcdTgwRkRcdTUzMDVcdTU0MkIgJ3snIn0sCi0KLSAgICB7IEVSX0lMTEVHQUxfQVRUUklCVVRFICwKLSAgICAgInswfVx1NTE3N1x1NjcwOVx1OTc1RVx1NkNENVx1NUM1RVx1NjAyNzogezF9In0sCi0KLSAge0VSX05VTExfU09VUkNFTk9ERV9BUFBMWUlNUE9SVFMgLAotICAgICAgInNvdXJjZU5vZGUgXHU1NzI4IHhzbDphcHBseS1pbXBvcnRzIFx1NEUyRFx1NEUzQVx1N0E3QVx1NTAzQyEifSwKLQotICB7RVJfQ0FOTk9UX0FERCwKLSAgICAgICJcdTY1RTBcdTZDRDVcdTU0MTF7MX1cdTZERkJcdTUyQTB7MH0ifSwKLQotICAgIHsgRVJfTlVMTF9TT1VSQ0VOT0RFX0hBTkRMRUFQUExZVEVNUExBVEVTLAotICAgICAgInNvdXJjZU5vZGUgXHU1NzI4IGhhbmRsZUFwcGx5VGVtcGxhdGVzSW5zdHJ1Y3Rpb24gXHU0RTJEXHU0RTNBXHU3QTdBXHU1MDNDISJ9LAotCi0gICAgeyBFUl9OT19OQU1FX0FUVFJJQiwKLSAgICAgInswfVx1NUZDNVx1OTg3Qlx1NTE3N1x1NjcwOSBuYW1lIFx1NUM1RVx1NjAyN1x1MzAwMiJ9LAotCi0gICAge0VSX1RFTVBMQVRFX05PVF9GT1VORCwKLSAgICAgIlx1NjI3RVx1NEUwRFx1NTIzMFx1NTQwRFx1NEUzQXswfVx1NzY4NFx1NkEyMVx1Njc3RiJ9LAotCi0gICAge0VSX0NBTlRfUkVTT0xWRV9OQU1FX0FWVCwKLSAgICAgICJcdTY1RTBcdTZDRDVcdTg5RTNcdTY3OTAgeHNsOmNhbGwtdGVtcGxhdGUgXHU0RTJEXHU3Njg0XHU1NDBEXHU3OUYwIEFWVFx1MzAwMiJ9LAotCi0gICAge0VSX1JFUVVJUkVTX0FUVFJJQiwKLSAgICAgInswfVx1OTcwMFx1ODk4MVx1NUM1RVx1NjAyNzogezF9In0sCi0KLSAgICB7IEVSX01VU1RfSEFWRV9URVNUX0FUVFJJQiwKLSAgICAgICJ7MH1cdTVGQzVcdTk4N0JcdTUxNzdcdTY3MDkgJyd0ZXN0JycgXHU1QzVFXHU2MDI3XHUzMDAyIn0sCi0KLSAgICB7RVJfQkFEX1ZBTF9PTl9MRVZFTF9BVFRSSUIsCi0gICAgICAibGV2ZWwgXHU1QzVFXHU2MDI3XHU3Njg0XHU1MDNDXHU5NTE5XHU4QkVGOiB7MH0ifSwKLQotICAgIHtFUl9QUk9DRVNTSU5HSU5TVFJVQ1RJT05fTkFNRV9DQU5UX0JFX1hNTCwKLSAgICAgICJwcm9jZXNzaW5nLWluc3RydWN0aW9uIFx1NTQwRFx1NzlGMFx1NEUwRFx1ODBGRFx1NEUzQSAneG1sJyJ9LAotCi0gICAgeyBFUl9QUk9DRVNTSU5HSU5TVFJVQ1RJT05fTk9UVkFMSURfTkNOQU1FLAotICAgICAgInByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24gXHU1NDBEXHU3OUYwXHU1RkM1XHU5ODdCXHU2NjJGXHU2NzA5XHU2NTQ4XHU3Njg0IE5DTmFtZTogezB9In0sCi0KLSAgICB7IEVSX05FRURfTUFUQ0hfQVRUUklCLAotICAgICAgIlx1NTk4Mlx1Njc5Q3swfVx1NTE3N1x1NjcwOVx1NjdEMFx1NzlDRFx1NkEyMVx1NUYwRiwgXHU1MjE5XHU1RkM1XHU5ODdCXHU1MTc3XHU2NzA5IG1hdGNoIFx1NUM1RVx1NjAyN1x1MzAwMiJ9LAotCi0gICAgeyBFUl9ORUVEX05BTUVfT1JfTUFUQ0hfQVRUUklCLAotICAgICAgInswfVx1OTcwMFx1ODk4MSBuYW1lIFx1NjIxNiBtYXRjaCBcdTVDNUVcdTYwMjdcdTMwMDIifSwKLQotICAgIHtFUl9DQU5UX1JFU09MVkVfTlNQUkVGSVgsCi0gICAgICAiXHU2NUUwXHU2Q0Q1XHU4OUUzXHU2NzkwXHU1NDBEXHU3OUYwXHU3QTdBXHU5NUY0XHU1MjREXHU3RjAwOiB7MH0ifSwKLQotICAgIHsgRVJfSUxMRUdBTF9WQUxVRSwKLSAgICAgInhtbDpzcGFjZSBcdTUxNzdcdTY3MDlcdTk3NUVcdTZDRDVcdTUwM0M6IHswfSJ9LAotCi0gICAgeyBFUl9OT19PV05FUkRPQywKLSAgICAgICJcdTVCNTBcdTgyODJcdTcwQjlcdTZDQTFcdTY3MDlcdTYyNDBcdTY3MDlcdTgwMDVcdTY1ODdcdTY4NjMhIn0sCi0KLSAgICB7IEVSX0VMRU1URU1QTEFURUVMRU1fRVJSLAotICAgICAiRWxlbVRlbXBsYXRlRWxlbWVudCBcdTk1MTlcdThCRUY6IHswfSJ9LAotCi0gICAgeyBFUl9OVUxMX0NISUxELAotICAgICAiXHU2QjYzXHU1NzI4XHU1QzFEXHU4QkQ1XHU2REZCXHU1MkEwXHU3QTdBXHU1QjUwXHU3RUE3ISJ9LAotCi0gICAgeyBFUl9ORUVEX1NFTEVDVF9BVFRSSUIsCi0gICAgICJ7MH1cdTk3MDBcdTg5ODEgc2VsZWN0IFx1NUM1RVx1NjAyN1x1MzAwMiJ9LAotCi0gICAgeyBFUl9ORUVEX1RFU1RfQVRUUklCICwKLSAgICAgICJ4c2w6d2hlbiBcdTVGQzVcdTk4N0JcdTUxNzdcdTY3MDkgJ3Rlc3QnIFx1NUM1RVx1NjAyN1x1MzAwMiJ9LAotCi0gICAgeyBFUl9ORUVEX05BTUVfQVRUUklCLAotICAgICAgInhzbDp3aXRoLXBhcmFtIFx1NUZDNVx1OTg3Qlx1NTE3N1x1NjcwOSAnbmFtZScgXHU1QzVFXHU2MDI3XHUzMDAyIn0sCi0KLSAgICB7IEVSX05PX0NPTlRFWFRfT1dORVJET0MsCi0gICAgICAiXHU0RTBBXHU0RTBCXHU2NTg3XHU2Q0ExXHU2NzA5XHU2MjQwXHU2NzA5XHU4MDA1XHU2NTg3XHU2ODYzISJ9LAotCi0gICAge0VSX0NPVUxEX05PVF9DUkVBVEVfWE1MX1BST0NfTElBSVNPTiwKLSAgICAgICJcdTY1RTBcdTZDRDVcdTUyMUJcdTVFRkEgWE1MIFRyYW5zZm9ybWVyRmFjdG9yeSBMaWFpc29uOiB7MH0ifSwKLQotICAgIHtFUl9QUk9DRVNTX05PVF9TVUNDRVNTRlVMLAotICAgICAgIlhhbGFuOiBcdThGREJcdTdBMEJcdTY3MkFcdTYyMTBcdTUyOUZcdTMwMDIifSwKLQotICAgIHsgRVJfTk9UX1NVQ0NFU1NGVUwsCi0gICAgICJYYWxhbjogXHU2NzJBXHU2MjEwXHU1MjlGXHUzMDAyIn0sCi0KLSAgICB7IEVSX0VOQ09ESU5HX05PVF9TVVBQT1JURUQsCi0gICAgICJcdTRFMERcdTY1MkZcdTYzMDFcdTdGMTZcdTc4MDE6IHswfSJ9LAotCi0gICAge0VSX0NPVUxEX05PVF9DUkVBVEVfVFJBQ0VMSVNURU5FUiwKLSAgICAgICJcdTY1RTBcdTZDRDVcdTUyMUJcdTVFRkEgVHJhY2VMaXN0ZW5lcjogezB9In0sCi0KLSAgICB7RVJfS0VZX1JFUVVJUkVTX05BTUVfQVRUUklCLAotICAgICAgInhzbDprZXkgXHU5NzAwXHU4OTgxICduYW1lJyBcdTVDNUVcdTYwMjchIn0sCi0KLSAgICB7IEVSX0tFWV9SRVFVSVJFU19NQVRDSF9BVFRSSUIsCi0gICAgICAieHNsOmtleSBcdTk3MDBcdTg5ODEgJ21hdGNoJyBcdTVDNUVcdTYwMjchIn0sCi0KLSAgICB7IEVSX0tFWV9SRVFVSVJFU19VU0VfQVRUUklCLAotICAgICAgInhzbDprZXkgXHU5NzAwXHU4OTgxICd1c2UnIFx1NUM1RVx1NjAyNyEifSwKLQotICAgIHsgRVJfUkVRVUlSRVNfRUxFTUVOVFNfQVRUUklCLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgezB9XHU5NzAwXHU4OTgxICcnZWxlbWVudHMnJyBcdTVDNUVcdTYwMjchIn0sCi0KLSAgICB7IEVSX01JU1NJTkdfUFJFRklYX0FUVFJJQiwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIFx1N0YzQVx1NUMxMXswfVx1NUM1RVx1NjAyNyAnJ3ByZWZpeCcnIn0sCi0KLSAgICB7IEVSX0JBRF9TVFlMRVNIRUVUX1VSTCwKLSAgICAgIlx1NjgzN1x1NUYwRlx1ODg2OCBVUkwgXHU5NTE5XHU4QkVGOiB7MH0ifSwKLQotICAgIHsgRVJfRklMRV9OT1RfRk9VTkQsCi0gICAgICJcdTYyN0VcdTRFMERcdTUyMzBcdTY4MzdcdTVGMEZcdTg4NjhcdTY1ODdcdTRFRjY6IHswfSJ9LAotCi0gICAgeyBFUl9JT0VYQ0VQVElPTiwKLSAgICAgICJcdTY4MzdcdTVGMEZcdTg4NjhcdTY1ODdcdTRFRjZcdTUxRkFcdTczQjAgSU8gXHU1RjAyXHU1RTM4XHU5NTE5XHU4QkVGOiB7MH0ifSwKLQotICAgIHsgRVJfTk9fSFJFRl9BVFRSSUIsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSBcdTYyN0VcdTRFMERcdTUyMzB7MH1cdTc2ODQgaHJlZiBcdTVDNUVcdTYwMjcifSwKLQotICAgIHsgRVJfU1RZTEVTSEVFVF9JTkNMVURFU19JVFNFTEYsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSB7MH1cdTc2RjRcdTYzQTVcdTYyMTZcdTk1RjRcdTYzQTVcdTUzMDVcdTU0MkJcdTUxNzZcdTgxRUFcdThFQUIhIn0sCi0KLSAgICB7IEVSX1BST0NFU1NJTkNMVURFX0VSUk9SLAotICAgICAgIlN0eWxlc2hlZXRIYW5kbGVyLnByb2Nlc3NJbmNsdWRlIFx1OTUxOVx1OEJFRiwgezB9In0sCi0KLSAgICB7IEVSX01JU1NJTkdfTEFOR19BVFRSSUIsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSBcdTdGM0FcdTVDMTF7MH1cdTVDNUVcdTYwMjcgJydsYW5nJycifSwKLQotICAgIHsgRVJfTUlTU0lOR19DT05UQUlORVJfRUxFTUVOVF9DT01QT05FTlQsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSB7MH1cdTUxNDNcdTdEMjBcdTc2ODRcdTY1M0VcdTdGNkVcdTRGNERcdTdGNkVcdTY2MkZcdTU0MjZcdTk1MTlcdThCRUY/PyBcdTdGM0FcdTVDMTFcdTVCQjlcdTU2NjhcdTUxNDNcdTdEMjAgJydjb21wb25lbnQnJyJ9LAotCi0gICAgeyBFUl9DQU5fT05MWV9PVVRQVVRfVE9fRUxFTUVOVCwKLSAgICAgICJcdTUzRUFcdTgwRkRcdThGOTNcdTUxRkFcdTUyMzAgRWxlbWVudCwgRG9jdW1lbnRGcmFnbWVudCwgRG9jdW1lbnQgXHU2MjE2IFByaW50V3JpdGVyXHUzMDAyIn0sCi0KLSAgICB7IEVSX1BST0NFU1NfRVJST1IsCi0gICAgICJTdHlsZXNoZWV0Um9vdC5wcm9jZXNzIFx1OTUxOVx1OEJFRiJ9LAotCi0gICAgeyBFUl9VTklNUExOT0RFX0VSUk9SLAotICAgICAiVW5JbXBsTm9kZSBcdTk1MTlcdThCRUY6IHswfSJ9LAotCi0gICAgeyBFUl9OT19TRUxFQ1RfRVhQUkVTU0lPTiwKLSAgICAgICJcdTk1MTlcdThCRUYhIFx1NjI3RVx1NEUwRFx1NTIzMCB4cGF0aCBcdTkwMDlcdTYyRTlcdTg4NjhcdThGQkVcdTVGMEYgKC1zZWxlY3QpXHUzMDAyIn0sCi0KLSAgICB7IEVSX0NBTk5PVF9TRVJJQUxJWkVfWFNMUFJPQ0VTU09SLAotICAgICAgIlx1NjVFMFx1NkNENVx1NUU4Rlx1NTIxN1x1NTMxNiBYU0xQcm9jZXNzb3IhIn0sCi0KLSAgICB7IEVSX05PX0lOUFVUX1NUWUxFU0hFRVQsCi0gICAgICAiXHU2NzJBXHU2MzA3XHU1QjlBXHU2ODM3XHU1RjBGXHU4ODY4XHU4RjkzXHU1MTY1ISJ9LAotCi0gICAgeyBFUl9GQUlMRURfUFJPQ0VTU19TVFlMRVNIRUVULAotICAgICAgIlx1NjVFMFx1NkNENVx1NTkwNFx1NzQwNlx1NjgzN1x1NUYwRlx1ODg2OCEifSwKLQotICAgIHsgRVJfQ09VTEROVF9QQVJTRV9ET0MsCi0gICAgICJcdTY1RTBcdTZDRDVcdTg5RTNcdTY3OTB7MH1cdTY1ODdcdTY4NjMhIn0sCi0KLSAgICB7IEVSX0NPVUxETlRfRklORF9GUkFHTUVOVCwKLSAgICAgIlx1NjI3RVx1NEUwRFx1NTIzMFx1NzI0N1x1NkJCNTogezB9In0sCi0KLSAgICB7IEVSX05PREVfTk9UX0VMRU1FTlQsCi0gICAgICAiXHU3MjQ3XHU2QkI1XHU2ODA3XHU4QkM2XHU3QjI2XHU2MzA3XHU1NDExXHU3Njg0XHU4MjgyXHU3MEI5XHU0RTBEXHU2NjJGXHU1MTQzXHU3RDIwOiB7MH0ifSwKLQotICAgIHsgRVJfRk9SRUFDSF9ORUVEX01BVENIX09SX05BTUVfQVRUUklCLAotICAgICAgImZvci1lYWNoIFx1NUZDNVx1OTg3Qlx1NTE3N1x1NjcwOSBtYXRjaCBcdTYyMTYgbmFtZSBcdTVDNUVcdTYwMjcifSwKLQotICAgIHsgRVJfVEVNUExBVEVTX05FRURfTUFUQ0hfT1JfTkFNRV9BVFRSSUIsCi0gICAgICAidGVtcGxhdGVzIFx1NUZDNVx1OTg3Qlx1NTE3N1x1NjcwOSBtYXRjaCBcdTYyMTYgbmFtZSBcdTVDNUVcdTYwMjcifSwKLQotICAgIHsgRVJfTk9fQ0xPTkVfT0ZfRE9DVU1FTlRfRlJBRywKLSAgICAgICJcdTRFMERcdTgwRkRcdTUxNEJcdTk2ODZcdTY1ODdcdTY4NjNcdTcyNDdcdTZCQjUhIn0sCi0KLSAgICB7IEVSX0NBTlRfQ1JFQVRFX0lURU0sCi0gICAgICAiXHU2NUUwXHU2Q0Q1XHU1NzI4XHU3RUQzXHU2NzlDXHU2ODExXHU0RTJEXHU1MjFCXHU1RUZBXHU5ODc5OiB7MH0ifSwKLQotICAgIHsgRVJfWE1MU1BBQ0VfSUxMRUdBTF9WQUxVRSwKLSAgICAgICJcdTZFOTAgWE1MIFx1NEUyRFx1NzY4NCB4bWw6c3BhY2UgXHU1MTc3XHU2NzA5XHU5NzVFXHU2Q0Q1XHU1MDNDOiB7MH0ifSwKLQotICAgIHsgRVJfTk9fWFNMS0VZX0RFQ0xBUkFUSU9OLAotICAgICAgInswfVx1NkNBMVx1NjcwOSB4c2w6a2V5IFx1NThGMFx1NjYwRSEifSwKLQotICAgIHsgRVJfQ0FOVF9DUkVBVEVfVVJMLAotICAgICAiXHU5NTE5XHU4QkVGISBcdTY1RTBcdTZDRDVcdTRFM0F7MH1cdTUyMUJcdTVFRkEgdXJsIn0sCi0KLSAgICB7IEVSX1hTTEZVTkNUSU9OU19VTlNVUFBPUlRFRCwKLSAgICAgIlx1NEUwRFx1NjUyRlx1NjMwMSB4c2w6ZnVuY3Rpb25zIn0sCi0KLSAgICB7IEVSX1BST0NFU1NPUl9FUlJPUiwKLSAgICAgIlhTTFQgVHJhbnNmb3JtZXJGYWN0b3J5IFx1OTUxOVx1OEJFRiJ9LAotCi0gICAgeyBFUl9OT1RfQUxMT1dFRF9JTlNJREVfU1RZTEVTSEVFVCwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIFx1NjgzN1x1NUYwRlx1ODg2OFx1NEUyRFx1NEUwRFx1NTE0MVx1OEJCOFx1NEY3Rlx1NzUyOHswfSEifSwKLQotICAgIHsgRVJfUkVTVUxUTlNfTk9UX1NVUFBPUlRFRCwKLSAgICAgICJcdTRFMERcdTUxOERcdTY1MkZcdTYzMDEgcmVzdWx0LW5zISBcdThCRjdcdTY1MzlcdTc1MjggeHNsOm91dHB1dFx1MzAwMiJ9LAotCi0gICAgeyBFUl9ERUZBVUxUU1BBQ0VfTk9UX1NVUFBPUlRFRCwKLSAgICAgICJcdTRFMERcdTUxOERcdTY1MkZcdTYzMDEgZGVmYXVsdC1zcGFjZSEgXHU4QkY3XHU2NTM5XHU3NTI4IHhzbDpzdHJpcC1zcGFjZSBcdTYyMTYgeHNsOnByZXNlcnZlLXNwYWNlXHUzMDAyIn0sCi0KLSAgICB7IEVSX0lOREVOVFJFU1VMVF9OT1RfU1VQUE9SVEVELAotICAgICAgIlx1NEUwRFx1NTE4RFx1NjUyRlx1NjMwMSBpbmRlbnQtcmVzdWx0ISBcdThCRjdcdTY1MzlcdTc1MjggeHNsOm91dHB1dFx1MzAwMiJ9LAotCi0gICAgeyBFUl9JTExFR0FMX0FUVFJJQiwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIHswfVx1NTE3N1x1NjcwOVx1OTc1RVx1NkNENVx1NUM1RVx1NjAyNzogezF9In0sCi0KLSAgICB7IEVSX1VOS05PV05fWFNMX0VMRU0sCi0gICAgICJcdTY3MkFcdTc3RTUgWFNMIFx1NTE0M1x1N0QyMDogezB9In0sCi0KLSAgICB7IEVSX0JBRF9YU0xTT1JUX1VTRSwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIHhzbDpzb3J0IFx1NTNFQVx1ODBGRFx1NEUwRSB4c2w6YXBwbHktdGVtcGxhdGVzIFx1NjIxNiB4c2w6Zm9yLWVhY2ggXHU0RTAwXHU4RDc3XHU0RjdGXHU3NTI4XHUzMDAyIn0sCi0KLSAgICB7IEVSX01JU1BMQUNFRF9YU0xXSEVOLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgeHNsOndoZW4gXHU3Njg0XHU2NTNFXHU3RjZFXHU0RjREXHU3RjZFXHU5NTE5XHU4QkVGISJ9LAotCi0gICAgeyBFUl9YU0xXSEVOX05PVF9QQVJFTlRFRF9CWV9YU0xDSE9PU0UsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSB4c2w6d2hlbiBcdTc2ODRcdTcyMzZcdTdFQTdcdTRFMERcdTY2MkYgeHNsOmNob29zZSEifSwKLQotICAgIHsgRVJfTUlTUExBQ0VEX1hTTE9USEVSV0lTRSwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIHhzbDpvdGhlcndpc2UgXHU3Njg0XHU2NTNFXHU3RjZFXHU0RjREXHU3RjZFXHU5NTE5XHU4QkVGISJ9LAotCi0gICAgeyBFUl9YU0xPVEhFUldJU0VfTk9UX1BBUkVOVEVEX0JZX1hTTENIT09TRSwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIHhzbDpvdGhlcndpc2UgXHU3Njg0XHU3MjM2XHU3RUE3XHU0RTBEXHU2NjJGIHhzbDpjaG9vc2UhIn0sCi0KLSAgICB7IEVSX05PVF9BTExPV0VEX0lOU0lERV9URU1QTEFURSwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIFx1NkEyMVx1Njc3Rlx1NEUyRFx1NEUwRFx1NTE0MVx1OEJCOFx1NEY3Rlx1NzUyOHswfSEifSwKLQotICAgIHsgRVJfVU5LTk9XTl9FWFRfTlNfUFJFRklYLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgezB9XHU2MjY5XHU1QzU1XHU1NDBEXHU3OUYwXHU3QTdBXHU5NUY0XHU1MjREXHU3RjAwIHsxfSBcdTY3MkFcdTc3RTUifSwKLQotICAgIHsgRVJfSU1QT1JUU19BU19GSVJTVF9FTEVNLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgXHU1M0VBXHU4MEZEXHU0RjVDXHU0RTNBXHU2ODM3XHU1RjBGXHU4ODY4XHU0RTJEXHU3Njg0XHU3QjJDXHU0RTAwXHU0RTJBXHU1MTQzXHU3RDIwXHU1QkZDXHU1MTY1ISJ9LAotCi0gICAgeyBFUl9JTVBPUlRJTkdfSVRTRUxGLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgezB9XHU3NkY0XHU2M0E1XHU2MjE2XHU5NUY0XHU2M0E1XHU1QkZDXHU1MTY1XHU1MTc2XHU4MUVBXHU4RUFCISJ9LAotCi0gICAgeyBFUl9YTUxTUEFDRV9JTExFR0FMX1ZBTCwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIHhtbDpzcGFjZSBcdTUxNzdcdTY3MDlcdTk3NUVcdTZDRDVcdTUwM0M6IHswfSJ9LAotCi0gICAgeyBFUl9QUk9DRVNTU1RZTEVTSEVFVF9OT1RfU1VDQ0VTU0ZVTCwKLSAgICAgICJwcm9jZXNzU3R5bGVzaGVldCBcdTU5MzFcdThEMjUhIn0sCi0KLSAgICB7IEVSX1NBWF9FWENFUFRJT04sCi0gICAgICJTQVggXHU1RjAyXHU1RTM4XHU5NTE5XHU4QkVGIn0sCi0KLS8vICBhZGQgdGhpcyBtZXNzYWdlIHRvIGZpeCBidWcgMjE0NzgKLSAgICB7IEVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQsCi0gICAgICJcdTRFMERcdTY1MkZcdTYzMDFcdThCRTVcdTUxRkRcdTY1NzAhIn0sCi0KLSAgICB7IEVSX1hTTFRfRVJST1IsCi0gICAgICJYU0xUIFx1OTUxOVx1OEJFRiJ9LAotCi0gICAgeyBFUl9DVVJSRU5DWV9TSUdOX0lMTEVHQUwsCi0gICAgICAiXHU2ODNDXHU1RjBGXHU2QTIxXHU1RjBGXHU1QjU3XHU3QjI2XHU0RTMyXHU0RTJEXHU0RTBEXHU1MTQxXHU4QkI4XHU0RjdGXHU3NTI4XHU4RDI3XHU1RTAxXHU3QjI2XHU1M0Y3In0sCi0KLSAgICB7IEVSX0RPQ1VNRU5UX0ZVTkNUSU9OX0lOVkFMSURfSU5fU1RZTEVTSEVFVF9ET00sCi0gICAgICAiXHU2ODM3XHU1RjBGXHU4ODY4IERPTSBcdTRFMkRcdTRFMERcdTY1MkZcdTYzMDEgRG9jdW1lbnQgXHU1MUZEXHU2NTcwISJ9LAotCi0gICAgeyBFUl9DQU5UX1JFU09MVkVfUFJFRklYX09GX05PTl9QUkVGSVhfUkVTT0xWRVIsCi0gICAgICAiXHU2NUUwXHU2Q0Q1XHU4OUUzXHU2NzkwXHU5NzVFXHU1MjREXHU3RjAwXHU4OUUzXHU2NzkwXHU1NjY4XHU3Njg0XHU1MjREXHU3RjAwISJ9LAotCi0gICAgeyBFUl9SRURJUkVDVF9DT1VMRE5UX0dFVF9GSUxFTkFNRSwKLSAgICAgICJcdTkxQ0RcdTVCOUFcdTU0MTFcdTYyNjlcdTVDNTU6IFx1NjVFMFx1NkNENVx1ODNCN1x1NTNENlx1NjU4N1x1NEVGNlx1NTQwRCAtIGZpbGUgXHU2MjE2IHNlbGVjdCBcdTVDNUVcdTYwMjdcdTVGQzVcdTk4N0JcdThGRDRcdTU2REVcdTY3MDlcdTY1NDhcdTVCNTdcdTdCMjZcdTRFMzJcdTMwMDIifSwKLQotICAgIHsgRVJfQ0FOTk9UX0JVSUxEX0ZPUk1BVFRFUkxJU1RFTkVSX0lOX1JFRElSRUNULAotICAgICAgIlx1NjVFMFx1NkNENVx1NTcyOFx1OTFDRFx1NUI5QVx1NTQxMVx1NjI2OVx1NUM1NVx1NEUyRFx1Njc4NFx1NUVGQSBGb3JtYXR0ZXJMaXN0ZW5lciEifSwKLQotICAgIHsgRVJfSU5WQUxJRF9QUkVGSVhfSU5fRVhDTFVERVJFU1VMVFBSRUZJWCwKLSAgICAgICJleGNsdWRlLXJlc3VsdC1wcmVmaXhlcyBcdTRFMkRcdTc2ODRcdTUyNERcdTdGMDBcdTY1RTBcdTY1NDg6IHswfSJ9LAotCi0gICAgeyBFUl9NSVNTSU5HX05TX1VSSSwKLSAgICAgICJcdTYzMDdcdTVCOUFcdTUyNERcdTdGMDBcdTdGM0FcdTVDMTFcdTU0MERcdTc5RjBcdTdBN0FcdTk1RjQgVVJJIn0sCi0KLSAgICB7IEVSX01JU1NJTkdfQVJHX0ZPUl9PUFRJT04sCi0gICAgICAiXHU5MDA5XHU5ODc5XHU3RjNBXHU1QzExXHU1M0MyXHU2NTcwOiB7MH0ifSwKLQotICAgIHsgRVJfSU5WQUxJRF9PUFRJT04sCi0gICAgICJcdTkwMDlcdTk4NzlcdTY1RTBcdTY1NDg6IHswfSJ9LAotCi0gICAgeyBFUl9NQUxGT1JNRURfRk9STUFUX1NUUklORywKLSAgICAgIlx1NjgzQ1x1NUYwRlx1NUI1N1x1N0IyNlx1NEUzMlx1NzY4NFx1NjgzQ1x1NUYwRlx1OTUxOVx1OEJFRjogezB9In0sCi0KLSAgICB7IEVSX1NUWUxFU0hFRVRfUkVRVUlSRVNfVkVSU0lPTl9BVFRSSUIsCi0gICAgICAieHNsOnN0eWxlc2hlZXQgXHU5NzAwXHU4OTgxICd2ZXJzaW9uJyBcdTVDNUVcdTYwMjchIn0sCi0KLSAgICB7IEVSX0lMTEVHQUxfQVRUUklCVVRFX1ZBTFVFLAotICAgICAgIlx1NUM1RVx1NjAyN3swfVx1NTE3N1x1NjcwOVx1OTc1RVx1NkNENVx1NTAzQzogezF9In0sCi0KLSAgICB7IEVSX0NIT09TRV9SRVFVSVJFU19XSEVOLAotICAgICAieHNsOmNob29zZSBcdTk3MDBcdTg5ODEgeHNsOndoZW4ifSwKLQotICAgIHsgRVJfTk9fQVBQTFlfSU1QT1JUX0lOX0ZPUl9FQUNILAotICAgICAgInhzbDpmb3ItZWFjaCBcdTRFMkRcdTRFMERcdTUxNDFcdThCQjhcdTRGN0ZcdTc1MjggeHNsOmFwcGx5LWltcG9ydHMifSwKLQotICAgIHsgRVJfQ0FOVF9VU0VfRFRNX0ZPUl9PVVRQVVQsCi0gICAgICAiXHU2NUUwXHU2Q0Q1XHU1QzA2IERUTUxpYWlzb24gXHU3NTI4XHU0RThFXHU4RjkzXHU1MUZBIERPTSBcdTgyODJcdTcwQjkuLi4gXHU4QkY3XHU2NTM5XHU0RTNBXHU0RjIwXHU5MDEyIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5ET00ySGVscGVyISJ9LAotCi0gICAgeyBFUl9DQU5UX1VTRV9EVE1fRk9SX0lOUFVULAotICAgICAgIlx1NjVFMFx1NkNENVx1NUMwNiBEVE1MaWFpc29uIFx1NzUyOFx1NEU4RVx1OEY5M1x1NTE2NSBET00gXHU4MjgyXHU3MEI5Li4uIFx1OEJGN1x1NjUzOVx1NEUzQVx1NEYyMFx1OTAxMiBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuRE9NMkhlbHBlciEifSwKLQotICAgIHsgRVJfQ0FMTF9UT19FWFRfRkFJTEVELAotICAgICAgIlx1NjcyQVx1ODBGRFx1OEMwM1x1NzUyOFx1NjI2OVx1NUM1NVx1NTE0M1x1N0QyMDogezB9In0sCi0KLSAgICB7IEVSX1BSRUZJWF9NVVNUX1JFU09MVkUsCi0gICAgICAiXHU1MjREXHU3RjAwXHU1RkM1XHU5ODdCXHU4OUUzXHU2NzkwXHU0RTNBXHU1NDBEXHU3OUYwXHU3QTdBXHU5NUY0OiB7MH0ifSwKLQotICAgIHsgRVJfSU5WQUxJRF9VVEYxNl9TVVJST0dBVEUsCi0gICAgICAiXHU2OEMwXHU2RDRCXHU1MjMwXHU2NUUwXHU2NTQ4XHU3Njg0IFVURi0xNiBcdTRFRTNcdTc0MDY6IHswfT8ifSwKLQotICAgIHsgRVJfWFNMQVRUUlNFVF9VU0VEX0lUU0VMRiwKLSAgICAgICJ4c2w6YXR0cmlidXRlLXNldCB7MH0gXHU0RjdGXHU3NTI4XHU1MTc2XHU4MUVBXHU4RUFCLCBcdThGRDlcdTVDMDZcdTVCRkNcdTgxRjRcdTY1RTBcdTk2NTBcdTVGQUFcdTczQUZcdTMwMDIifSwKLQotICAgIHsgRVJfQ0FOTk9UX01JWF9YRVJDRVNET00sCi0gICAgICAiXHU2NUUwXHU2Q0Q1XHU2REY3XHU1NDA4XHU5NzVFIFhlcmNlcy1ET00gXHU4RjkzXHU1MTY1XHU1NDhDIFhlcmNlcy1ET00gXHU4RjkzXHU1MUZBISJ9LAotCi0gICAgeyBFUl9UT09fTUFOWV9MSVNURU5FUlMsCi0gICAgICAiYWRkVHJhY2VMaXN0ZW5lcnNUb1N0eWxlc2hlZXQgLSBUb29NYW55TGlzdGVuZXJzRXhjZXB0aW9uIn0sCi0KLSAgICB7IEVSX0lOX0VMRU1URU1QTEFURUVMRU1fUkVBRE9CSkVDVCwKLSAgICAgICJcdTU3MjggRWxlbVRlbXBsYXRlRWxlbWVudC5yZWFkT2JqZWN0IFx1NEUyRDogezB9In0sCi0KLSAgICB7IEVSX0RVUExJQ0FURV9OQU1FRF9URU1QTEFURSwKLSAgICAgICJcdTYyN0VcdTUyMzBcdTU5MUFcdTRFMkFcdTU0MERcdTRFM0F7MH1cdTc2ODRcdTZBMjFcdTY3N0YifSwKLQotICAgIHsgRVJfSU5WQUxJRF9LRVlfQ0FMTCwKLSAgICAgICJcdTUxRkRcdTY1NzBcdThDMDNcdTc1MjhcdTY1RTBcdTY1NDg6IFx1NEUwRFx1NTE0MVx1OEJCOFx1OTAxMlx1NUY1MiBrZXkoKSBcdThDMDNcdTc1MjgifSwKLQotICAgIHsgRVJfUkVGRVJFTkNJTkdfSVRTRUxGLAotICAgICAgIlx1NTNEOFx1OTFDRiB7MH0gXHU3NkY0XHU2M0E1XHU2MjE2XHU5NUY0XHU2M0E1XHU1RjE1XHU3NTI4XHU1MTc2XHU4MUVBXHU4RUFCISJ9LAotCi0gICAgeyBFUl9JTExFR0FMX0RPTVNPVVJDRV9JTlBVVCwKLSAgICAgICJcdTVCRjlcdTRFOEUgbmV3VGVtcGxhdGVzIFx1NzY4NCBET01Tb3VyY2UsIFx1OEY5M1x1NTE2NVx1ODI4Mlx1NzBCOVx1NEUwRFx1ODBGRFx1NEUzQVx1N0E3QVx1NTAzQyEifSwKLQotICAgIHsgRVJfQ0xBU1NfTk9UX0ZPVU5EX0ZPUl9PUFRJT04sCi0gICAgICAgICJcdTYyN0VcdTRFMERcdTUyMzBcdTkwMDlcdTk4Nzl7MH1cdTc2ODRcdTdDN0JcdTY1ODdcdTRFRjYifSwKLQotICAgIHsgRVJfUkVRVUlSRURfRUxFTV9OT1RfRk9VTkQsCi0gICAgICAgICJcdTYyN0VcdTRFMERcdTUyMzBcdTYyNDBcdTk3MDBcdTUxNDNcdTdEMjA6IHswfSJ9LAotCi0gICAgeyBFUl9JTlBVVF9DQU5OT1RfQkVfTlVMTCwKLSAgICAgICAgIklucHV0U3RyZWFtIFx1NEUwRFx1ODBGRFx1NEUzQVx1N0E3QVx1NTAzQyJ9LAotCi0gICAgeyBFUl9VUklfQ0FOTk9UX0JFX05VTEwsCi0gICAgICAgICJVUkkgXHU0RTBEXHU4MEZEXHU0RTNBXHU3QTdBXHU1MDNDIn0sCi0KLSAgICB7IEVSX0ZJTEVfQ0FOTk9UX0JFX05VTEwsCi0gICAgICAgICJGaWxlIFx1NEUwRFx1ODBGRFx1NEUzQVx1N0E3QVx1NTAzQyJ9LAotCi0gICAgeyBFUl9TT1VSQ0VfQ0FOTk9UX0JFX05VTEwsCi0gICAgICAgICAgICAgICAgIklucHV0U291cmNlIFx1NEUwRFx1ODBGRFx1NEUzQVx1N0E3QVx1NTAzQyJ9LAotCi0gICAgeyBFUl9DQU5OT1RfSU5JVF9CU0ZNR1IsCi0gICAgICAgICAgICAgICAgIlx1NjVFMFx1NkNENVx1NTIxRFx1NTlDQlx1NTMxNiBCU0YgXHU3QkExXHU3NDA2XHU1NjY4In0sCi0KLSAgICB7IEVSX0NBTk5PVF9DTVBMX0VYVEVOU04sCi0gICAgICAgICAgICAgICAgIlx1NjVFMFx1NkNENVx1N0YxNlx1OEJEMVx1NjI2OVx1NUM1NSJ9LAotCi0gICAgeyBFUl9DQU5OT1RfQ1JFQVRFX0VYVEVOU04sCi0gICAgICAiXHU2NUUwXHU2Q0Q1XHU1MjFCXHU1RUZBXHU2MjY5XHU1QzU1OiB7MH0sIFx1NTM5Rlx1NTZFMDogezF9In0sCi0KLSAgICB7IEVSX0lOU1RBTkNFX01USERfQ0FMTF9SRVFVSVJFUywKLSAgICAgICJcdTVCRjlcdTY1QjlcdTZDRDV7MH1cdTc2ODRcdTVCOUVcdTRGOEJcdTY1QjlcdTZDRDVcdThDMDNcdTc1MjhcdTk3MDBcdTg5ODFcdTVDMDYgT2JqZWN0IFx1NUI5RVx1NEY4Qlx1NEY1Q1x1NEUzQVx1N0IyQ1x1NEUwMFx1NEUyQVx1NTNDMlx1NjU3MCJ9LAotCi0gICAgeyBFUl9JTlZBTElEX0VMRU1FTlRfTkFNRSwKLSAgICAgICJcdTYzMDdcdTVCOUFcdTc2ODRcdTUxNDNcdTdEMjBcdTU0MERcdTc5RjB7MH1cdTY1RTBcdTY1NDgifSwKLQotICAgIHsgRVJfRUxFTUVOVF9OQU1FX01FVEhPRF9TVEFUSUMsCi0gICAgICAiXHU1MTQzXHU3RDIwXHU1NDBEXHU3OUYwXHU2NUI5XHU2Q0Q1XHU1RkM1XHU5ODdCXHU2NjJGIHN0YXRpYyB7MH0ifSwKLQotICAgIHsgRVJfRVhURU5TSU9OX0ZVTkNfVU5LTk9XTiwKLSAgICAgICAgICAgICAiXHU2MjY5XHU1QzU1XHU1MUZEXHU2NTcwIHswfTogezF9IFx1NjcyQVx1NzdFNSJ9LAotCi0gICAgeyBFUl9NT1JFX01BVENIX0NPTlNUUlVDVE9SLAotICAgICAgICAgICAgICJ7MH1cdTc2ODRcdTY3ODRcdTkwMjBcdTU2NjhcdTUxNzdcdTY3MDlcdTU5MUFcdTRFMkFcdTY3MDBcdTRGNzNcdTUzMzlcdTkxNEQifSwKLQotICAgIHsgRVJfTU9SRV9NQVRDSF9NRVRIT0QsCi0gICAgICAgICAgICAgIlx1NjVCOVx1NkNENXswfVx1NTE3N1x1NjcwOVx1NTkxQVx1NEUyQVx1NjcwMFx1NEY3M1x1NTMzOVx1OTE0RCJ9LAotCi0gICAgeyBFUl9NT1JFX01BVENIX0VMRU1FTlQsCi0gICAgICAgICAgICAgIlx1NTE0M1x1N0QyMFx1NjVCOVx1NkNENXswfVx1NTE3N1x1NjcwOVx1NTkxQVx1NEUyQVx1NjcwMFx1NEY3M1x1NTMzOVx1OTE0RCJ9LAotCi0gICAgeyBFUl9JTlZBTElEX0NPTlRFWFRfUEFTU0VELAotICAgICAgICAgICAgICJcdTRGMjBcdTkwMTJcdTc2ODRcdTc1MjhcdTRFOEVcdTVCRjl7MH1cdTZDNDJcdTUwM0NcdTc2ODRcdTRFMEFcdTRFMEJcdTY1ODdcdTY1RTBcdTY1NDgifSwKLQotICAgIHsgRVJfUE9PTF9FWElTVFMsCi0gICAgICAgICAgICAgIlx1NkM2MFx1NURGMlx1NUI1OFx1NTcyOCJ9LAotCi0gICAgeyBFUl9OT19EUklWRVJfTkFNRSwKLSAgICAgICAgICAgICAiXHU2NzJBXHU2MzA3XHU1QjlBXHU5QTcxXHU1MkE4XHU3QTBCXHU1RThGXHU1NDBEXHU3OUYwIn0sCi0KLSAgICB7IEVSX05PX1VSTCwKLSAgICAgICAgICAgICAiXHU2NzJBXHU2MzA3XHU1QjlBIFVSTCJ9LAotCi0gICAgeyBFUl9QT09MX1NJWkVfTEVTU1RIQU5fT05FLAotICAgICAgICAgICAgICJcdTZDNjBcdTU5MjdcdTVDMEZcdTVDMEZcdTRFOEUgMSEifSwKLQotICAgIHsgRVJfSU5WQUxJRF9EUklWRVIsCi0gICAgICAgICAgICAgIlx1NjMwN1x1NUI5QVx1NzY4NFx1OUE3MVx1NTJBOFx1N0EwQlx1NUU4Rlx1NTQwRFx1NzlGMFx1NjVFMFx1NjU0OCEifSwKLQotICAgIHsgRVJfTk9fU1RZTEVTSEVFVFJPT1QsCi0gICAgICAgICAgICAgIlx1NjI3RVx1NEUwRFx1NTIzMFx1NjgzN1x1NUYwRlx1ODg2OFx1NjgzOSEifSwKLQotICAgIHsgRVJfSUxMRUdBTF9YTUxTUEFDRV9WQUxVRSwKLSAgICAgICAgICJ4bWw6c3BhY2UgXHU3Njg0XHU1MDNDXHU5NzVFXHU2Q0Q1In0sCi0KLSAgICB7IEVSX1BST0NFU1NGUk9NTk9ERV9GQUlMRUQsCi0gICAgICAgICAicHJvY2Vzc0Zyb21Ob2RlIFx1NTkzMVx1OEQyNSJ9LAotCi0gICAgeyBFUl9SRVNPVVJDRV9DT1VMRF9OT1RfTE9BRCwKLSAgICAgICAgIlx1OEQ0NFx1NkU5MCBbIHswfSBdIFx1NjVFMFx1NkNENVx1NTJBMFx1OEY3RDogezF9IFxuIHsyfSBcdCB7M30ifSwKLQotICAgIHsgRVJfQlVGRkVSX1NJWkVfTEVTU1RIQU5fWkVSTywKLSAgICAgICAgIlx1N0YxM1x1NTFCMlx1NTMzQVx1NTkyN1x1NUMwRiA8PTAifSwKLQotICAgIHsgRVJfVU5LTk9XTl9FUlJPUl9DQUxMSU5HX0VYVEVOU0lPTiwKLSAgICAgICAgIlx1OEMwM1x1NzUyOFx1NjI2OVx1NUM1NVx1NjVGNlx1NTFGQVx1NzNCMFx1NjcyQVx1NzdFNVx1OTUxOVx1OEJFRiJ9LAotCi0gICAgeyBFUl9OT19OQU1FU1BBQ0VfREVDTCwKLSAgICAgICAgIlx1NTI0RFx1N0YwMCB7MH0gXHU2Q0ExXHU2NzA5XHU1QkY5XHU1RTk0XHU3Njg0XHU1NDBEXHU3OUYwXHU3QTdBXHU5NUY0XHU1OEYwXHU2NjBFIn0sCi0KLSAgICB7IEVSX0VMRU1fQ09OVEVOVF9OT1RfQUxMT1dFRCwKLSAgICAgICAgImxhbmc9amF2YWNsYXNzIHswfVx1NEUwRFx1NTE0MVx1OEJCOFx1NEY3Rlx1NzUyOFx1NTE0M1x1N0QyMFx1NTE4NVx1NUJCOSJ9LAotCi0gICAgeyBFUl9TVFlMRVNIRUVUX0RJUkVDVEVEX1RFUk1JTkFUSU9OLAotICAgICAgICAiXHU2ODM3XHU1RjBGXHU4ODY4XHU2MzA3XHU1NDExXHU3RUM4XHU2QjYyIn0sCi0KLSAgICB7IEVSX09ORV9PUl9UV08sCi0gICAgICAgICIxIFx1NjIxNiAyIn0sCi0KLSAgICB7IEVSX1RXT19PUl9USFJFRSwKLSAgICAgICAgIjIgXHU2MjE2IDMifSwKLQotICAgIHsgRVJfQ09VTERfTk9UX0xPQURfUkVTT1VSQ0UsCi0gICAgICAgICJcdTY1RTBcdTZDRDVcdTUyQTBcdThGN0R7MH0gKFx1NjhDMFx1NjdFNSBDTEFTU1BBVEgpLCBcdTczQjBcdTU3MjhcdTUzRUFcdTRGN0ZcdTc1MjhcdTlFRDhcdThCQTRcdTUwM0MifSwKLQotICAgIHsgRVJfQ0FOTk9UX0lOSVRfREVGQVVMVF9URU1QTEFURVMsCi0gICAgICAgICJcdTY1RTBcdTZDRDVcdTUyMURcdTU5Q0JcdTUzMTZcdTlFRDhcdThCQTRcdTZBMjFcdTY3N0YifSwKLQotICAgIHsgRVJfUkVTVUxUX05VTEwsCi0gICAgICAgICJSZXN1bHQgXHU0RTBEXHU4MEZEXHU0RTNBXHU3QTdBXHU1MDNDIn0sCi0KLSAgICB7IEVSX1JFU1VMVF9DT1VMRF9OT1RfQkVfU0VULAotICAgICAgICAiXHU2NUUwXHU2Q0Q1XHU4QkJFXHU3RjZFIFJlc3VsdCJ9LAotCi0gICAgeyBFUl9OT19PVVRQVVRfU1BFQ0lGSUVELAotICAgICAgICAiXHU2NzJBXHU2MzA3XHU1QjlBXHU4RjkzXHU1MUZBIn0sCi0KLSAgICB7IEVSX0NBTk5PVF9UUkFOU0ZPUk1fVE9fUkVTVUxUX1RZUEUsCi0gICAgICAgICJcdTY1RTBcdTZDRDVcdThGNkNcdTYzNjJcdTRFM0FcdTdDN0JcdTU3OEJcdTRFM0F7MH1cdTc2ODQgUmVzdWx0In0sCi0KLSAgICB7IEVSX0NBTk5PVF9UUkFOU0ZPUk1fU09VUkNFX1RZUEUsCi0gICAgICAgICJcdTY1RTBcdTZDRDVcdThGNkNcdTYzNjJcdTdDN0JcdTU3OEJcdTRFM0F7MH1cdTc2ODRcdTZFOTAifSwKLQotICAgIHsgRVJfTlVMTF9DT05URU5UX0hBTkRMRVIsCi0gICAgICAgICJcdTdBN0FcdTUxODVcdTVCQjlcdTU5MDRcdTc0MDZcdTdBMEJcdTVFOEYifSwKLQotICAgIHsgRVJfTlVMTF9FUlJPUl9IQU5ETEVSLAotICAgICAgICAiXHU3QTdBXHU5NTE5XHU4QkVGXHU1OTA0XHU3NDA2XHU3QTBCXHU1RThGIn0sCi0KLSAgICB7IEVSX0NBTk5PVF9DQUxMX1BBUlNFLAotICAgICAgICAiXHU1OTgyXHU2NzlDXHU1QzFBXHU2NzJBXHU4QkJFXHU3RjZFIENvbnRlbnRIYW5kbGVyLCBcdTUyMTlcdTY1RTBcdTZDRDVcdThDMDNcdTc1MjggcGFyc2UifSwKLQotICAgIHsgRVJfTk9fUEFSRU5UX0ZPUl9GSUxURVIsCi0gICAgICAgICJcdTdCNUJcdTkwMDlcdTU2NjhcdTZDQTFcdTY3MDlcdTcyMzZcdTdFQTcifSwKLQotICAgIHsgRVJfTk9fU1RZTEVTSEVFVF9JTl9NRURJQSwKLSAgICAgICAgICJcdTU3Mjh7MH1cdTRFMkRcdTYyN0VcdTRFMERcdTUyMzBcdTY4MzdcdTVGMEZcdTg4NjgsIFx1NEVDQlx1OEQyOD0gezF9In0sCi0KLSAgICB7IEVSX05PX1NUWUxFU0hFRVRfUEksCi0gICAgICAgICAiXHU1NzI4ezB9XHU0RTJEXHU2MjdFXHU0RTBEXHU1MjMwIHhtbC1zdHlsZXNoZWV0IFBJIn0sCi0KLSAgICB7IEVSX05PVF9TVVBQT1JURUQsCi0gICAgICAgIlx1NEUwRFx1NjUyRlx1NjMwMTogezB9In0sCi0KLSAgICB7IEVSX1BST1BFUlRZX1ZBTFVFX0JPT0xFQU4sCi0gICAgICAgIlx1NUM1RVx1NjAyN3swfVx1NzY4NFx1NTAzQ1x1NUU5NFx1NEUzQSBCb29sZWFuIFx1NUI5RVx1NEY4QiJ9LAotCi0gICAgeyBFUl9DT1VMRF9OT1RfRklORF9FWFRFUk5fU0NSSVBULAotICAgICAgICAgIlx1NjVFMFx1NkNENVx1NTcyOHswfVx1NEUyRFx1ODNCN1x1NTNENlx1NTkxNlx1OTBFOFx1ODExQVx1NjcyQyJ9LAotCi0gICAgeyBFUl9SRVNPVVJDRV9DT1VMRF9OT1RfRklORCwKLSAgICAgICAgIlx1NjI3RVx1NEUwRFx1NTIzMFx1OEQ0NFx1NkU5MCBbIHswfSBdXHUzMDAyXG4gezF9In0sCi0KLSAgICB7IEVSX09VVFBVVF9QUk9QRVJUWV9OT1RfUkVDT0dOSVpFRCwKLSAgICAgICAgIlx1NjVFMFx1NkNENVx1OEJDNlx1NTIyQlx1OEY5M1x1NTFGQVx1NUM1RVx1NjAyNzogezB9In0sCi0KLSAgICB7IEVSX0ZBSUxFRF9DUkVBVElOR19FTEVNTElUUlNMVCwKLSAgICAgICAgIlx1NjcyQVx1ODBGRFx1NTIxQlx1NUVGQSBFbGVtTGl0ZXJhbFJlc3VsdCBcdTVCOUVcdTRGOEIifSwKLQotICAvL0VhcmxpZXIgKEpESyAxLjQgWEFMQU4gMi4yLUQxMSkgYXQga2V5IGNvZGUgJzIwNCcgdGhlIGtleSBuYW1lIHdhcyBFUl9QUklPUklUWV9OT1RfUEFSU0FCTEUKLSAgLy8gSW4gbGF0ZXN0IFhhbGFuIGNvZGUgYmFzZSBrZXkgbmFtZSBpcyAgRVJfVkFMVUVfU0hPVUxEX0JFX05VTUJFUi4gVGhpcyBzaG91bGQgYWxzbyBiZSB0YWtlbiBjYXJlCi0gIC8vaW4gbG9jYWxlIHNwZWNpZmljIGZpbGVzIGxpa2UgWFNMVEVycm9yUmVzb3VyY2VzX2RlLmphdmEsIFhTTFRFcnJvclJlc291cmNlc19mci5qYXZhIGV0Yy4KLSAgLy9OT1RFOiBOb3Qgb25seSB0aGUga2V5IG5hbWUgYnV0IG1lc3NhZ2UgaGFzIGFsc28gYmVlbiBjaGFuZ2VkLgotICAgIHsgRVJfVkFMVUVfU0hPVUxEX0JFX05VTUJFUiwKLSAgICAgICAgInswfVx1NzY4NFx1NTAzQ1x1NUU5NFx1NTMwNVx1NTQyQlx1NTNFRlx1ODlFM1x1Njc5MFx1NzY4NFx1NjU3MFx1NUI1NyJ9LAotCi0gICAgeyBFUl9WQUxVRV9TSE9VTERfRVFVQUwsCi0gICAgICAgICJ7MH1cdTc2ODRcdTUwM0NcdTVFOTRcdTdCNDlcdTRFOEVcdTIwMUNcdTY2MkZcdTIwMURcdTYyMTZcdTIwMUNcdTU0MjZcdTIwMUQifSwKLQotICAgIHsgRVJfRkFJTEVEX0NBTExJTkdfTUVUSE9ELAotICAgICAgICAiXHU2NzJBXHU4MEZEXHU4QzAzXHU3NTI4ezB9XHU2NUI5XHU2Q0Q1In0sCi0KLSAgICB7IEVSX0ZBSUxFRF9DUkVBVElOR19FTEVNVE1QTCwKLSAgICAgICAgIlx1NjcyQVx1ODBGRFx1NTIxQlx1NUVGQSBFbGVtVGVtcGxhdGVFbGVtZW50IFx1NUI5RVx1NEY4QiJ9LAotCi0gICAgeyBFUl9DSEFSU19OT1RfQUxMT1dFRCwKLSAgICAgICAgIlx1NEUwRFx1NTE0MVx1OEJCOFx1NTcyOFx1NjU4N1x1Njg2M1x1NEUyRFx1NzY4NFx1NkI2NFx1NEY0RFx1N0Y2RVx1NTkwNFx1NEY3Rlx1NzUyOFx1NUI1N1x1N0IyNiJ9LAotCi0gICAgeyBFUl9BVFRSX05PVF9BTExPV0VELAotICAgICAgICAiezF9XHU1MTQzXHU3RDIwXHU0RTJEXHU0RTBEXHU1MTQxXHU4QkI4XHU0RjdGXHU3NTI4IFwiezB9XCIgXHU1QzVFXHU2MDI3ISJ9LAotCi0gICAgeyBFUl9CQURfVkFMVUUsCi0gICAgICJ7MH1cdTk1MTlcdThCRUZcdTUwM0N7MX0gIn0sCi0KLSAgICB7IEVSX0FUVFJJQl9WQUxVRV9OT1RfRk9VTkQsCi0gICAgICJcdTYyN0VcdTRFMERcdTUyMzB7MH1cdTVDNUVcdTYwMjdcdTUwM0MgIn0sCi0KLSAgICB7IEVSX0FUVFJJQl9WQUxVRV9OT1RfUkVDT0dOSVpFRCwKLSAgICAgIlx1NjVFMFx1NkNENVx1OEJDNlx1NTIyQnswfVx1NUM1RVx1NjAyN1x1NTAzQyAifSwKLQotICAgIHsgRVJfTlVMTF9VUklfTkFNRVNQQUNFLAotICAgICAiXHU1QzFEXHU4QkQ1XHU0RjdGXHU3NTI4XHU3QTdBIFVSSSBcdTc1MUZcdTYyMTBcdTU0MERcdTc5RjBcdTdBN0FcdTk1RjRcdTUyNERcdTdGMDAifSwKLQotICAgIHsgRVJfTlVNQkVSX1RPT19CSUcsCi0gICAgICJcdTVDMURcdThCRDVcdThCQkVcdTdGNkVcdThEODVcdThGQzdcdTY3MDBcdTU5MjdcdTk1N0ZcdTY1NzRcdTU3OEJcdTc2ODRcdTY1NzBcdTVCNTdcdTc2ODRcdTY4M0NcdTVGMEYifSwKLQotICAgIHsgRVJfQ0FOTk9UX0ZJTkRfU0FYMV9EUklWRVIsCi0gICAgICJcdTYyN0VcdTRFMERcdTUyMzAgU0FYMSBcdTlBNzFcdTUyQThcdTdBMEJcdTVFOEZcdTdDN0J7MH0ifSwKLQotICAgIHsgRVJfU0FYMV9EUklWRVJfTk9UX0xPQURFRCwKLSAgICAgIlx1NURGMlx1NjI3RVx1NTIzMCBTQVgxIFx1OUE3MVx1NTJBOFx1N0EwQlx1NUU4Rlx1N0M3QnswfSwgXHU0RjQ2XHU2NUUwXHU2Q0Q1XHU4RkRCXHU4ODRDXHU1MkEwXHU4RjdEIn0sCi0KLSAgICB7IEVSX1NBWDFfRFJJVkVSX05PVF9JTlNUQU5USUFURUQsCi0gICAgICJcdTVERjJcdTUyQTBcdThGN0QgU0FYMSBcdTlBNzFcdTUyQThcdTdBMEJcdTVFOEZcdTdDN0J7MH0sIFx1NEY0Nlx1NjVFMFx1NkNENVx1OEZEQlx1ODg0Q1x1NUI5RVx1NEY4Qlx1NTMxNiJ9LAotCi0gICAgeyBFUl9TQVgxX0RSSVZFUl9OT1RfSU1QTEVNRU5UX1BBUlNFUiwKLSAgICAgIlNBWDEgXHU5QTcxXHU1MkE4XHU3QTBCXHU1RThGXHU3QzdCIHswfSBcdTY3MkFcdTVCOUVcdTczQjAgb3JnLnhtbC5zYXguUGFyc2VyIn0sCi0KLSAgICB7IEVSX1BBUlNFUl9QUk9QRVJUWV9OT1RfU1BFQ0lGSUVELAotICAgICAiXHU2NzJBXHU2MzA3XHU1QjlBXHU3Q0ZCXHU3RURGXHU1QzVFXHU2MDI3IG9yZy54bWwuc2F4LnBhcnNlciJ9LAotCi0gICAgeyBFUl9QQVJTRVJfQVJHX0NBTk5PVF9CRV9OVUxMLAotICAgICAiXHU4OUUzXHU2NzkwXHU1NjY4XHU1M0MyXHU2NTcwXHU0RTBEXHU4MEZEXHU0RTNBXHU3QTdBXHU1MDNDIn0sCi0KLSAgICB7IEVSX0ZFQVRVUkUsCi0gICAgICJcdTUyOUZcdTgwRkQ6IHswfSJ9LAotCi0gICAgeyBFUl9QUk9QRVJUWSwKLSAgICAgIlx1NUM1RVx1NjAyNzogezB9In0sCi0KLSAgICB7IEVSX05VTExfRU5USVRZX1JFU09MVkVSLAotICAgICAiXHU3QTdBXHU1QjlFXHU0RjUzXHU4OUUzXHU2NzkwXHU1NjY4In0sCi0KLSAgICB7IEVSX05VTExfRFREX0hBTkRMRVIsCi0gICAgICJcdTdBN0EgRFREIFx1NTkwNFx1NzQwNlx1N0EwQlx1NUU4RiJ9LAotCi0gICAgeyBFUl9OT19EUklWRVJfTkFNRV9TUEVDSUZJRUQsCi0gICAgICJcdTY3MkFcdTYzMDdcdTVCOUFcdTlBNzFcdTUyQThcdTdBMEJcdTVFOEZcdTU0MERcdTc5RjAhIn0sCi0KLSAgICB7IEVSX05PX1VSTF9TUEVDSUZJRUQsCi0gICAgICJcdTY3MkFcdTYzMDdcdTVCOUEgVVJMISJ9LAotCi0gICAgeyBFUl9QT09MU0laRV9MRVNTX1RIQU5fT05FLAotICAgICAiXHU2QzYwXHU1OTI3XHU1QzBGXHU1QzBGXHU0RThFIDEhIn0sCi0KLSAgICB7IEVSX0lOVkFMSURfRFJJVkVSX05BTUUsCi0gICAgICJcdTYzMDdcdTVCOUFcdTc2ODRcdTlBNzFcdTUyQThcdTdBMEJcdTVFOEZcdTU0MERcdTc5RjBcdTY1RTBcdTY1NDghIn0sCi0KLSAgICB7IEVSX0VSUk9STElTVEVORVIsCi0gICAgICJFcnJvckxpc3RlbmVyIn0sCi0KLQotLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBzaG91bGQgbm90IG5vcm1hbGx5IGJlIGRpc3BsYXllZAotLy8gICB0byB1c2Vycy4gIEl0IGRlc2NyaWJlcyBhIHNpdHVhdGlvbiBpbiB3aGljaCB0aGUgcHJvY2Vzc29yIGhhcyBkZXRlY3RlZAotLy8gICBhbiBpbnRlcm5hbCBjb25zaXN0ZW5jeSBwcm9ibGVtIGluIGl0c2VsZiwgYW5kIGl0IHByb3ZpZGVzIHRoaXMgbWVzc2FnZQotLy8gICBmb3IgdGhlIGRldmVsb3BlciB0byBoZWxwIGRpYWdub3NlIHRoZSBwcm9ibGVtLiAgVGhlIG5hbWUKLS8vICAgJ0VsZW1UZW1wbGF0ZUVsZW1lbnQnIGlzIHRoZSBuYW1lIG9mIGEgY2xhc3MsIGFuZCBzaG91bGQgbm90IGJlCi0vLyAgIHRyYW5zbGF0ZWQuCi0gICAgeyBFUl9BU1NFUlRfTk9fVEVNUExBVEVfUEFSRU5ULAotICAgICAiXHU3QTBCXHU1RThGXHU1NDU4XHU5NTE5XHU4QkVGISBcdTg4NjhcdThGQkVcdTVGMEZcdTZDQTFcdTY3MDkgRWxlbVRlbXBsYXRlRWxlbWVudCBcdTcyMzZcdTdFQTchIn0sCi0KLQotLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBzaG91bGQgbm90IG5vcm1hbGx5IGJlIGRpc3BsYXllZAotLy8gICB0byB1c2Vycy4gIEl0IGRlc2NyaWJlcyBhIHNpdHVhdGlvbiBpbiB3aGljaCB0aGUgcHJvY2Vzc29yIGhhcyBkZXRlY3RlZAotLy8gICBhbiBpbnRlcm5hbCBjb25zaXN0ZW5jeSBwcm9ibGVtIGluIGl0c2VsZiwgYW5kIGl0IHByb3ZpZGVzIHRoaXMgbWVzc2FnZQotLy8gICBmb3IgdGhlIGRldmVsb3BlciB0byBoZWxwIGRpYWdub3NlIHRoZSBwcm9ibGVtLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0vLyAgIHByb3ZpZGVzIGZ1cnRoZXIgaW5mb3JtYXRpb24gaW4gb3JkZXIgdG8gZGlhZ25vc2UgdGhlIHByb2JsZW0uICBUaGUgbmFtZQotLy8gICAnUmVkdW5kZW50RXhwckVsaW1pbmF0b3InIGlzIHRoZSBuYW1lIG9mIGEgY2xhc3MsIGFuZCBzaG91bGQgbm90IGJlCi0vLyAgIHRyYW5zbGF0ZWQuCi0gICAgeyBFUl9BU1NFUlRfUkVEVU5ERU5UX0VYUFJfRUxJTUlOQVRPUiwKLSAgICAgIlJlZHVuZGVudEV4cHJFbGltaW5hdG9yIFx1NEUyRFx1NzY4NFx1N0EwQlx1NUU4Rlx1NTQ1OFx1NjVBRFx1OEEwMDogezB9In0sCi0KLSAgICB7IEVSX05PVF9BTExPV0VEX0lOX1BPU0lUSU9OLAotICAgICAiXHU0RTBEXHU1MTQxXHU4QkI4XHU1NzI4XHU2ODM3XHU1RjBGXHU4ODY4XHU0RTJEXHU3Njg0XHU2QjY0XHU0RjREXHU3RjZFXHU0RjdGXHU3NTI4ezB9ISJ9LAotCi0gICAgeyBFUl9OT05XSElURVNQQUNFX05PVF9BTExPV0VEX0lOX1BPU0lUSU9OLAotICAgICAiXHU0RTBEXHU1MTQxXHU4QkI4XHU1NzI4XHU2ODM3XHU1RjBGXHU4ODY4XHU0RTJEXHU3Njg0XHU2QjY0XHU0RjREXHU3RjZFXHU0RjdGXHU3NTI4XHU5NzVFXHU3QTdBXHU3NjdEXHU2NTg3XHU2NzJDISJ9LAotCi0gIC8vIFRoaXMgY29kZSBpcyBzaGFyZWQgd2l0aCB3YXJuaW5nIGNvZGVzLgotICAvLyBTeXN0ZW1JZCBVbmtub3duCi0gICAgeyBJTlZBTElEX1RDSEFSLAotICAgICAiQ0hBUiBcdTVDNUVcdTYwMjd7MH1cdTRGN0ZcdTc1MjhcdTRFODZcdTk3NUVcdTZDRDVcdTUwM0N7MX1cdTMwMDJDSEFSIFx1N0M3Qlx1NTc4Qlx1NzY4NFx1NUM1RVx1NjAyN1x1NTNFQVx1ODBGRFx1NEUzQSAxIFx1NEUyQVx1NUI1N1x1N0IyNiEifSwKLQotICAgIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgaXMgdXNlZCBpZiB0aGUgdmFsdWUgb2YKLSAgICAvLyBhbiBhdHRyaWJ1dGUgaW4gYSBzdHlsZXNoZWV0IGlzIGludmFsaWQuICAiUU5BTUUiIGlzIHRoZSBYTUwgZGF0YS10eXBlIG9mCi0gICAgLy8gdGhlIGF0dHJpYnV0ZSwgYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCB7MX0gaXMKLSAgICAvLyB0aGUgYXR0cmlidXRlIHZhbHVlIGFuZCB7MH0gaXMgdGhlIGF0dHJpYnV0ZSBuYW1lLgotICAvL1RoZSBmb2xsb3dpbmcgY29kZXMgYXJlIHNoYXJlZCB3aXRoIHRoZSB3YXJuaW5nIGNvZGVzLi4uCi0gICAgeyBJTlZBTElEX1FOQU1FLAotICAgICAiUU5BTUUgXHU1QzVFXHU2MDI3ezB9XHU0RjdGXHU3NTI4XHU0RTg2XHU5NzVFXHU2Q0Q1XHU1MDNDezF9In0sCi0KLSAgICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIGlzIHVzZWQgaWYgdGhlIHZhbHVlIG9mCi0gICAgLy8gYW4gYXR0cmlidXRlIGluIGEgc3R5bGVzaGVldCBpcyBpbnZhbGlkLiAgIkVOVU0iIGlzIHRoZSBYTUwgZGF0YS10eXBlIG9mCi0gICAgLy8gdGhlIGF0dHJpYnV0ZSwgYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCB7MX0gaXMKLSAgICAvLyB0aGUgYXR0cmlidXRlIHZhbHVlLCB7MH0gaXMgdGhlIGF0dHJpYnV0ZSBuYW1lLCBhbmQgezJ9IGlzIGEgbGlzdCBvZiB2YWxpZAotICAgIC8vIHZhbHVlcy4KLSAgICB7IElOVkFMSURfRU5VTSwKLSAgICAgIkVOVU0gXHU1QzVFXHU2MDI3ezB9XHU0RjdGXHU3NTI4XHU0RTg2XHU5NzVFXHU2Q0Q1XHU1MDNDezF9XHUzMDAyXHU2NzA5XHU2NTQ4XHU1MDNDXHU0RTNBOiB7Mn1cdTMwMDIifSwKLQotLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBpcyB1c2VkIGlmIHRoZSB2YWx1ZSBvZgotLy8gYW4gYXR0cmlidXRlIGluIGEgc3R5bGVzaGVldCBpcyBpbnZhbGlkLiAgIk5NVE9LRU4iIGlzIHRoZSBYTUwgZGF0YS10eXBlCi0vLyBvZiB0aGUgYXR0cmlidXRlLCBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHsxfSBpcwotLy8gdGhlIGF0dHJpYnV0ZSB2YWx1ZSBhbmQgezB9IGlzIHRoZSBhdHRyaWJ1dGUgbmFtZS4KLSAgICB7IElOVkFMSURfTk1UT0tFTiwKLSAgICAgIk5NVE9LRU4gXHU1QzVFXHU2MDI3ezB9XHU0RjdGXHU3NTI4XHU0RTg2XHU5NzVFXHU2Q0Q1XHU1MDNDezF9ICJ9LAotCi0vLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIGlzIHVzZWQgaWYgdGhlIHZhbHVlIG9mCi0vLyBhbiBhdHRyaWJ1dGUgaW4gYSBzdHlsZXNoZWV0IGlzIGludmFsaWQuICAiTkNOQU1FIiBpcyB0aGUgWE1MIGRhdGEtdHlwZQotLy8gb2YgdGhlIGF0dHJpYnV0ZSwgYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCB7MX0gaXMKLS8vIHRoZSBhdHRyaWJ1dGUgdmFsdWUgYW5kIHswfSBpcyB0aGUgYXR0cmlidXRlIG5hbWUuCi0gICAgeyBJTlZBTElEX05DTkFNRSwKLSAgICAgIk5DTkFNRSBcdTVDNUVcdTYwMjd7MH1cdTRGN0ZcdTc1MjhcdTRFODZcdTk3NUVcdTZDRDVcdTUwM0N7MX0gIn0sCi0KLS8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgaXMgdXNlZCBpZiB0aGUgdmFsdWUgb2YKLS8vIGFuIGF0dHJpYnV0ZSBpbiBhIHN0eWxlc2hlZXQgaXMgaW52YWxpZC4gICJib29sZWFuIiBpcyB0aGUgWFNMVCBkYXRhLXR5cGUKLS8vIG9mIHRoZSBhdHRyaWJ1dGUsIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgezF9IGlzCi0vLyB0aGUgYXR0cmlidXRlIHZhbHVlIGFuZCB7MH0gaXMgdGhlIGF0dHJpYnV0ZSBuYW1lLgotICAgIHsgSU5WQUxJRF9CT09MRUFOLAotICAgICAiQm9vbGVhbiBcdTVDNUVcdTYwMjd7MH1cdTRGN0ZcdTc1MjhcdTRFODZcdTk3NUVcdTZDRDVcdTUwM0N7MX0gIn0sCi0KLS8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgaXMgdXNlZCBpZiB0aGUgdmFsdWUgb2YKLS8vIGFuIGF0dHJpYnV0ZSBpbiBhIHN0eWxlc2hlZXQgaXMgaW52YWxpZC4gICJudW1iZXIiIGlzIHRoZSBYU0xUIGRhdGEtdHlwZQotLy8gb2YgdGhlIGF0dHJpYnV0ZSwgYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCB7MX0gaXMKLS8vIHRoZSBhdHRyaWJ1dGUgdmFsdWUgYW5kIHswfSBpcyB0aGUgYXR0cmlidXRlIG5hbWUuCi0gICAgIHsgSU5WQUxJRF9OVU1CRVIsCi0gICAgICJOdW1iZXIgXHU1QzVFXHU2MDI3ezB9XHU0RjdGXHU3NTI4XHU0RTg2XHU5NzVFXHU2Q0Q1XHU1MDNDezF9ICJ9LAotCi0KLSAgLy8gRW5kIG9mIHNoYXJlZCBjb2Rlcy4uLgotCi0vLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQSAibWF0Y2ggcGF0dGVybiIgaXMgYSBzcGVjaWFsIGZvcm0gb2YgWFBhdGggZXhwcmVzc2lvbgotLy8gdGhhdCBpcyB1c2VkIGZvciBtYXRjaGluZyBwYXR0ZXJucy4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZgotLy8gYSBmdW5jdGlvbi4gIFRoZSBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHdoZW4gdGhpcyBmdW5jdGlvbiBpcyByZWZlcmVuY2VkIGluCi0vLyBhIG1hdGNoIHBhdHRlcm4sIGl0cyBhcmd1bWVudCBtdXN0IGJlIGEgc3RyaW5nIGxpdGVyYWwgKG9yIGNvbnN0YW50LikKLS8vIEVSX0FSR19MSVRFUkFMIC0gbmV3IGVycm9yIG1lc3NhZ2UgZm9yIGJ1Z3ppbGxhIC8vNTIwMgotICAgIHsgRVJfQVJHX0xJVEVSQUwsCi0gICAgICJcdTUzMzlcdTkxNERcdTZBMjFcdTVGMEZcdTRFMkRcdTc2ODR7MH1cdTc2ODRcdTUzQzJcdTY1NzBcdTVGQzVcdTk4N0JcdTRFM0FcdTY1ODdcdTVCNTdcdTMwMDIifSwKLQotLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0d28gZGVmaW5pdGlvbnMgb2YKLS8vIGEgdmFyaWFibGUuICBBICJnbG9iYWwgdmFyaWFibGUiIGlzIGEgdmFyaWFibGUgdGhhdCBpcyBhY2Nlc3NpYmxlIGV2ZXJ5d2hlcgotLy8gaW4gdGhlIHN0eWxlc2hlZXQuCi0vLyBFUl9EVVBMSUNBVEVfR0xPQkFMX1ZBUiAtIG5ldyBlcnJvciBtZXNzYWdlIGZvciBidWd6aWxsYSAjNzkwCi0gICAgeyBFUl9EVVBMSUNBVEVfR0xPQkFMX1ZBUiwKLSAgICAgIlx1NTE2OFx1NUM0MFx1NTNEOFx1OTFDRlx1NThGMFx1NjYwRVx1OTFDRFx1NTkwRFx1MzAwMiJ9LAotCi0KLS8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdHdvIGRlZmluaXRpb25zIG9mCi0vLyBhIHZhcmlhYmxlIHdlcmUgZW5jb3VudGVyZWQuCi0vLyBFUl9EVVBMSUNBVEVfVkFSIC0gbmV3IGVycm9yIG1lc3NhZ2UgZm9yIGJ1Z3ppbGxhICM3OTAKLSAgICB7IEVSX0RVUExJQ0FURV9WQVIsCi0gICAgICJcdTUzRDhcdTkxQ0ZcdTU4RjBcdTY2MEVcdTkxQ0RcdTU5MERcdTMwMDIifSwKLQotICAgIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAieHNsOnRlbXBsYXRlLCAibmFtZSIgYW5kICJtYXRjaCIgYXJlIFhTTFQga2V5d29yZHMKLSAgICAvLyB3aGljaCBtdXN0IG5vdCBiZSB0cmFuc2xhdGVkLgotICAgIC8vIEVSX1RFTVBMQVRFX05BTUVfTUFUQ0ggLSBuZXcgZXJyb3IgbWVzc2FnZSBmb3IgYnVnemlsbGEgIzc4OQotICAgIHsgRVJfVEVNUExBVEVfTkFNRV9NQVRDSCwKLSAgICAgInhzbDp0ZW1wbGF0ZSBcdTVGQzVcdTk4N0JcdTUxNzdcdTY3MDkgbmFtZSBcdTU0OEMvXHU2MjE2IG1hdGNoIFx1NUM1RVx1NjAyNyJ9LAotCi0gICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogICJleGNsdWRlLXJlc3VsdC1wcmVmaXhlcyIgaXMgYW4gWFNMVCBrZXl3b3JkIHdoaWNoCi0gICAgLy8gc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgYSBuYW1lc3BhY2UgcHJlZml4Ci0gICAgLy8gZW5jb3VudGVyZWQgYXMgcGFydCBvZiB0aGUgdmFsdWUgb2YgdGhlIGV4Y2x1ZGUtcmVzdWx0LXByZWZpeGVzIGF0dHJpYnV0ZQotICAgIC8vIHdhcyBpbiBlcnJvci4KLSAgICAvLyBFUl9JTlZBTElEX1BSRUZJWCAtIG5ldyBlcnJvciBtZXNzYWdlIGZvciBidWd6aWxsYSAjNzg4Ci0gICAgeyBFUl9JTlZBTElEX1BSRUZJWCwKLSAgICAgImV4Y2x1ZGUtcmVzdWx0LXByZWZpeGVzIFx1NEUyRFx1NzY4NFx1NTI0RFx1N0YwMFx1NjVFMFx1NjU0ODogezB9In0sCi0KLSAgICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQW4gImF0dHJpYnV0ZSBzZXQiIGlzIGEgc2V0IG9mIGF0dHJpYnV0ZXMgdGhhdCBjYW4KLSAgICAvLyBiZSBhZGRlZCB0byBhbiBlbGVtZW50IGluIHRoZSBvdXRwdXQgZG9jdW1lbnQgYXMgYSBncm91cC4gIFRoZSBtZXNzYWdlCi0gICAgLy8gaW5kaWNhdGVzIHRoYXQgdGhlcmUgd2FzIGEgcmVmZXJlbmNlIHRvIGFuIGF0dHJpYnV0ZSBzZXQgbmFtZWQgezB9IHRoYXQKLSAgICAvLyB3YXMgbmV2ZXIgZGVmaW5lZC4KLSAgICAvLyBFUl9OT19BVFRSSUJfU0VUIC0gbmV3IGVycm9yIG1lc3NhZ2UgZm9yIGJ1Z3ppbGxhICM3ODIKLSAgICB7IEVSX05PX0FUVFJJQl9TRVQsCi0gICAgICJcdTU0MERcdTRFM0F7MH1cdTc2ODRcdTVDNUVcdTYwMjdcdTk2QzZcdTRFMERcdTVCNThcdTU3MjgifSwKLQotICAgIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhlcmUgd2FzIGEgcmVmZXJlbmNlCi0gICAgLy8gdG8gYSBmdW5jdGlvbiBuYW1lZCB7MH0gZm9yIHdoaWNoIG5vIGZ1bmN0aW9uIGRlZmluaXRpb24gY291bGQgYmUgZm91bmQuCi0gICAgeyBFUl9GVU5DVElPTl9OT1RfRk9VTkQsCi0gICAgICJcdTU0MERcdTRFM0F7MH1cdTc2ODRcdTUxRkRcdTY1NzBcdTRFMERcdTVCNThcdTU3MjgifSwKLQotICAgIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhlIFhTTFQgaW5zdHJ1Y3Rpb24KLSAgICAvLyB0aGF0IGlzIG5hbWVkIGJ5IHRoZSBzdWJzdGl0dXRpb24gdGV4dCB7MH0gbXVzdCBub3QgY29udGFpbiBvdGhlciBYU0xUCi0gICAgLy8gaW5zdHJ1Y3Rpb25zIChjb250ZW50KSBvciBhICJzZWxlY3QiIGF0dHJpYnV0ZS4gIFRoZSB3b3JkICJzZWxlY3QiIGlzCi0gICAgLy8gYW4gWFNMVCBrZXl3b3JkIGluIHRoaXMgY2FzZSBhbmQgbXVzdCBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICB7IEVSX0NBTlRfSEFWRV9DT05URU5UX0FORF9TRUxFQ1QsCi0gICAgICJ7MH1cdTUxNDNcdTdEMjBcdTRFMERcdTgwRkRcdTU0MENcdTY1RjZcdTUxNzdcdTY3MDlcdTUxODVcdTVCQjlcdTU0OEMgc2VsZWN0IFx1NUM1RVx1NjAyN1x1MzAwMiJ9LAotCi0gICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUgdmFsdWUgYXJndW1lbnQKLSAgICAvLyBvZiBzZXRQYXJhbWV0ZXIgbXVzdCBiZSBhIHZhbGlkIEphdmEgT2JqZWN0LgotICAgIHsgRVJfSU5WQUxJRF9TRVRfUEFSQU1fVkFMVUUsCi0gICAgICJcdTUzQzJcdTY1NzAgezB9IFx1NzY4NFx1NTAzQ1x1NUZDNVx1OTg3Qlx1NjYyRlx1NjcwOVx1NjU0OCBKYXZhIFx1NUJGOVx1OEM2MSJ9LAotCi0gICAgeyBFUl9JTlZBTElEX05BTUVTUEFDRV9VUklfVkFMVUVfRk9SX1JFU1VMVF9QUkVGSVhfRk9SX0RFRkFVTFQsCi0gICAgICAieHNsOm5hbWVzcGFjZS1hbGlhcyBcdTUxNDNcdTdEMjBcdTc2ODQgcmVzdWx0LXByZWZpeCBcdTVDNUVcdTYwMjdcdTUxNzdcdTY3MDlcdTUwM0MgJyNkZWZhdWx0JywgXHU0RjQ2XHU4QkU1XHU1MTQzXHU3RDIwXHU3Njg0XHU0RjVDXHU3NTI4XHU1N0RGXHU0RTJEXHU2Q0ExXHU2NzA5XHU5RUQ4XHU4QkE0XHU1NDBEXHU3OUYwXHU3QTdBXHU5NUY0XHU3Njg0XHU1OEYwXHU2NjBFIn0sCi0KLSAgICB7IEVSX0lOVkFMSURfTkFNRVNQQUNFX1VSSV9WQUxVRV9GT1JfUkVTVUxUX1BSRUZJWCwKLSAgICAgICJ4c2w6bmFtZXNwYWNlLWFsaWFzIFx1NTE0M1x1N0QyMFx1NzY4NCByZXN1bHQtcHJlZml4IFx1NUM1RVx1NjAyN1x1NTE3N1x1NjcwOVx1NTAzQyAnJ3swfScnLCBcdTRGNDZcdThCRTVcdTUxNDNcdTdEMjBcdTc2ODRcdTRGNUNcdTc1MjhcdTU3REZcdTRFMkRcdTZDQTFcdTY3MDlcdTUyNERcdTdGMDAgJyd7MH0nJyBcdTc2ODRcdTU0MERcdTc5RjBcdTdBN0FcdTk1RjRcdTU4RjBcdTY2MEVcdTMwMDIifSwKLQotICAgIHsgRVJfU0VUX0ZFQVRVUkVfTlVMTF9OQU1FLAotICAgICAgIlRyYW5zZm9ybWVyRmFjdG9yeS5zZXRGZWF0dXJlKFN0cmluZyBuYW1lLCBib29sZWFuIHZhbHVlKSBcdTRFMkRcdTc2ODRcdTUyOUZcdTgwRkRcdTU0MERcdTc5RjBcdTRFMERcdTgwRkRcdTRFM0FcdTdBN0FcdTUwM0NcdTMwMDIifSwKLQotICAgIHsgRVJfR0VUX0ZFQVRVUkVfTlVMTF9OQU1FLAotICAgICAgIlRyYW5zZm9ybWVyRmFjdG9yeS5nZXRGZWF0dXJlKFN0cmluZyBuYW1lKSBcdTRFMkRcdTc2ODRcdTUyOUZcdTgwRkRcdTU0MERcdTc5RjBcdTRFMERcdTgwRkRcdTRFM0FcdTdBN0FcdTUwM0NcdTMwMDIifSwKLQotICAgIHsgRVJfVU5TVVBQT1JURURfRkVBVFVSRSwKLSAgICAgICJcdTY1RTBcdTZDRDVcdTVCRjlcdTZCNjQgVHJhbnNmb3JtZXJGYWN0b3J5IFx1OEJCRVx1N0Y2RVx1NTI5Rlx1ODBGRCAnJ3swfScnXHUzMDAyIn0sCi0KLSAgICB7IEVSX0VYVEVOU0lPTl9FTEVNRU5UX05PVF9BTExPV0VEX0lOX1NFQ1VSRV9QUk9DRVNTSU5HLAotICAgICAgICAgICJcdTVGNTNcdTVCODlcdTUxNjhcdTU5MDRcdTc0MDZcdTUyOUZcdTgwRkRcdThCQkVcdTdGNkVcdTRFM0FcdTIwMUNcdTc3MUZcdTIwMURcdTY1RjYsIFx1NEUwRFx1NTE0MVx1OEJCOFx1NEY3Rlx1NzUyOFx1NjI2OVx1NUM1NVx1NTE0M1x1N0QyMCAnJ3swfScnXHUzMDAyIn0sCi0KLSAgICB7IEVSX05BTUVTUEFDRV9DT05URVhUX05VTExfTkFNRVNQQUNFLAotICAgICAgIlx1NjVFMFx1NkNENVx1ODNCN1x1NTNENlx1N0E3QVx1NTQwRFx1NzlGMFx1N0E3QVx1OTVGNCB1cmkgXHU3Njg0XHU1MjREXHU3RjAwXHUzMDAyIn0sCi0KLSAgICB7IEVSX05BTUVTUEFDRV9DT05URVhUX05VTExfUFJFRklYLAotICAgICAgIlx1NjVFMFx1NkNENVx1ODNCN1x1NTNENlx1N0E3QVx1NTI0RFx1N0YwMFx1NzY4NFx1NTQwRFx1NzlGMFx1N0E3QVx1OTVGNCB1cmlcdTMwMDIifSwKLQotICAgIHsgRVJfWFBBVEhfUkVTT0xWRVJfTlVMTF9RTkFNRSwKLSAgICAgICJcdTUxRkRcdTY1NzBcdTU0MERcdTc5RjBcdTRFMERcdTgwRkRcdTRFM0FcdTdBN0FcdTUwM0NcdTMwMDIifSwKLQotICAgIHsgRVJfWFBBVEhfUkVTT0xWRVJfTkVHQVRJVkVfQVJJVFksCi0gICAgICAiXHU1MTQzXHU2NTcwXHU0RTBEXHU4MEZEXHU0RTNBXHU4RDFGXHU2NTcwXHUzMDAyIn0sCi0gIC8vIFdhcm5pbmdzLi4uCi0KLSAgICB7IFdHX0ZPVU5EX0NVUkxZQlJBQ0UsCi0gICAgICAiXHU1REYyXHU2MjdFXHU1MjMwICd9JywgXHU0RjQ2XHU2NzJBXHU2MjUzXHU1RjAwXHU1QzVFXHU2MDI3XHU2QTIxXHU2NzdGISJ9LAotCi0gICAgeyBXR19DT1VOVF9BVFRSSUJfTUFUQ0hFU19OT19BTkNFU1RPUiwKLSAgICAgICJcdThCNjZcdTU0NEE6IGNvdW50IFx1NUM1RVx1NjAyN1x1NEUwRSB4c2w6bnVtYmVyIFx1NEUyRFx1NzY4NCBhbmNlc3RvciBcdTRFMERcdTUzMzlcdTkxNEQhIFx1NzZFRVx1NjgwNyA9IHswfSJ9LAotCi0gICAgeyBXR19FWFBSX0FUVFJJQl9DSEFOR0VEX1RPX1NFTEVDVCwKLSAgICAgICJcdTY1RTdcdThCRURcdTZDRDU6ICdleHByJyBcdTVDNUVcdTYwMjdcdTc2ODRcdTU0MERcdTc5RjBcdTVERjJcdTY2RjRcdTY1MzlcdTRFM0EgJ3NlbGVjdCdcdTMwMDIifSwKLQotICAgIHsgV0dfTk9fTE9DQUxFX0lOX0ZPUk1BVE5VTUJFUiwKLSAgICAgICJYYWxhbiBcdTVDMUFcdTY3MkFcdTU5MDRcdTc0MDYgZm9ybWF0LW51bWJlciBcdTUxRkRcdTY1NzBcdTRFMkRcdTc2ODRcdTUzM0FcdTU3REZcdThCQkVcdTdGNkVcdTU0MERcdTc5RjBcdTMwMDIifSwKLQotICAgIHsgV0dfTE9DQUxFX05PVF9GT1VORCwKLSAgICAgICJcdThCNjZcdTU0NEE6IFx1NjI3RVx1NEUwRFx1NTIzMCB4bWw6bGFuZz17MH0gXHU3Njg0XHU1MzNBXHU1N0RGXHU4QkJFXHU3RjZFIn0sCi0KLSAgICB7IFdHX0NBTk5PVF9NQUtFX1VSTF9GUk9NLAotICAgICAgIlx1NjVFMFx1NkNENVx1NjgzOVx1NjM2RXswfVx1NzUxRlx1NjIxMCBVUkwifSwKLQotICAgIHsgV0dfQ0FOTk9UX0xPQURfUkVRVUVTVEVEX0RPQywKLSAgICAgICJcdTY1RTBcdTZDRDVcdTUyQTBcdThGN0RcdThCRjdcdTZDNDJcdTc2ODRcdTY1ODdcdTY4NjM6IHswfSJ9LAotCi0gICAgeyBXR19DQU5OT1RfRklORF9DT0xMQVRPUiwKLSAgICAgICJcdTYyN0VcdTRFMERcdTUyMzAgPHNvcnQgeG1sOmxhbmc9ezB9IFx1NzY4NCBDb2xsYXRvciJ9LAotCi0gICAgeyBXR19GVU5DVElPTlNfU0hPVUxEX1VTRV9VUkwsCi0gICAgICAiXHU2NUU3XHU4QkVEXHU2Q0Q1OiBcdTUxRkRcdTY1NzBcdTYzMDdcdTRFRTRcdTVFOTRcdTRGN0ZcdTc1Mjh7MH1cdTc2ODQgdXJsIn0sCi0KLSAgICB7IFdHX0VOQ09ESU5HX05PVF9TVVBQT1JURURfVVNJTkdfVVRGOCwKLSAgICAgICJcdTRFMERcdTY1MkZcdTYzMDFcdTdGMTZcdTc4MDE6IHswfSwgXHU0RjdGXHU3NTI4IFVURi04In0sCi0KLSAgICB7IFdHX0VOQ09ESU5HX05PVF9TVVBQT1JURURfVVNJTkdfSkFWQSwKLSAgICAgICJcdTRFMERcdTY1MkZcdTYzMDFcdTdGMTZcdTc4MDE6IHswfSwgXHU0RjdGXHU3NTI4IEphdmEgezF9In0sCi0KLSAgICB7IFdHX1NQRUNJRklDSVRZX0NPTkZMSUNUUywKLSAgICAgICJcdTUzRDFcdTczQjBcdTcyNzlcdTVGODFcdTUxQjJcdTdBODE6IFx1NUMwNlx1NEY3Rlx1NzUyOFx1NEUwQVx1NkIyMVx1NTcyOFx1NjgzN1x1NUYwRlx1ODg2OFx1NEUyRFx1NjI3RVx1NTIzMFx1NzY4NHswfVx1MzAwMiJ9LAotCi0gICAgeyBXR19QQVJTSU5HX0FORF9QUkVQQVJJTkcsCi0gICAgICAiPT09PT09PT09IFx1ODlFM1x1Njc5MFx1NTQ4Q1x1NTFDNlx1NTkwN3swfSA9PT09PT09PT09In0sCi0KLSAgICB7IFdHX0FUVFJfVEVNUExBVEUsCi0gICAgICJcdTVDNUVcdTYwMjdcdTZBMjFcdTY3N0Z7MH0ifSwKLQotICAgIHsgV0dfQ09ORkxJQ1RfQkVUV0VFTl9YU0xTVFJJUFNQQUNFX0FORF9YU0xQUkVTRVJWRVNQQUNFLAotICAgICAgInhzbDpzdHJpcC1zcGFjZSBcdTU0OEMgeHNsOnByZXNlcnZlLXNwYWNlIFx1NEU0Qlx1OTVGNFx1NUI1OFx1NTcyOFx1NTMzOVx1OTE0RFx1NTFCMlx1N0E4MSJ9LAotCi0gICAgeyBXR19BVFRSSUJfTk9UX0hBTkRMRUQsCi0gICAgICAiWGFsYW4gXHU1QzFBXHU2NzJBXHU1OTA0XHU3NDA2ezB9XHU1QzVFXHU2MDI3ISJ9LAotCi0gICAgeyBXR19OT19ERUNJTUFMRk9STUFUX0RFQ0xBUkFUSU9OLAotICAgICAgIlx1NjI3RVx1NEUwRFx1NTIzMFx1NTM0MVx1OEZEQlx1NTIzNlx1NjgzQ1x1NUYwRlx1NzY4NFx1NThGMFx1NjYwRTogezB9In0sCi0KLSAgICB7IFdHX09MRF9YU0xUX05TLAotICAgICAiXHU3RjNBXHU1QzExIFhTTFQgXHU1NDBEXHU3OUYwXHU3QTdBXHU5NUY0XHU2MjE2IFhTTFQgXHU1NDBEXHU3OUYwXHU3QTdBXHU5NUY0XHU5NTE5XHU4QkVGXHUzMDAyIn0sCi0KLSAgICB7IFdHX09ORV9ERUZBVUxUX1hTTERFQ0lNQUxGT1JNQVRfQUxMT1dFRCwKLSAgICAgICJcdTRFQzVcdTUxNDFcdThCQjhcdTRGN0ZcdTc1MjhcdTRFMDBcdTRFMkFcdTlFRDhcdThCQTRcdTc2ODQgeHNsOmRlY2ltYWwtZm9ybWF0IFx1NThGMFx1NjYwRVx1MzAwMiJ9LAotCi0gICAgeyBXR19YU0xERUNJTUFMRk9STUFUX05BTUVTX01VU1RfQkVfVU5JUVVFLAotICAgICAgInhzbDpkZWNpbWFsLWZvcm1hdCBcdTU0MERcdTc5RjBcdTVGQzVcdTk4N0JcdTU1MkZcdTRFMDBcdTMwMDJcdTU0MERcdTc5RjAgXCJ7MH1cIiBcdTkxQ0RcdTU5MERcdTMwMDIifSwKLQotICAgIHsgV0dfSUxMRUdBTF9BVFRSSUJVVEUsCi0gICAgICAiezB9XHU1MTc3XHU2NzA5XHU5NzVFXHU2Q0Q1XHU1QzVFXHU2MDI3OiB7MX0ifSwKLQotICAgIHsgV0dfQ09VTERfTk9UX1JFU09MVkVfUFJFRklYLAotICAgICAgIlx1NjVFMFx1NkNENVx1ODlFM1x1Njc5MFx1NTQwRFx1NzlGMFx1N0E3QVx1OTVGNFx1NTI0RFx1N0YwMDogezB9XHUzMDAyXHU1QzA2XHU1RkZEXHU3NTY1XHU4MjgyXHU3MEI5XHUzMDAyIn0sCi0KLSAgICB7IFdHX1NUWUxFU0hFRVRfUkVRVUlSRVNfVkVSU0lPTl9BVFRSSUIsCi0gICAgICAieHNsOnN0eWxlc2hlZXQgXHU5NzAwXHU4OTgxICd2ZXJzaW9uJyBcdTVDNUVcdTYwMjchIn0sCi0KLSAgICB7IFdHX0lMTEVHQUxfQVRUUklCVVRFX05BTUUsCi0gICAgICAiXHU5NzVFXHU2Q0Q1XHU1QzVFXHU2MDI3XHU1NDBEXHU3OUYwOiB7MH0ifSwKLQotICAgIHsgV0dfSUxMRUdBTF9BVFRSSUJVVEVfVkFMVUUsCi0gICAgICAiXHU1QzVFXHU2MDI3ezB9XHU0RjdGXHU3NTI4XHU0RTg2XHU5NzVFXHU2Q0Q1XHU1MDNDezF9In0sCi0KLSAgICB7IFdHX0VNUFRZX1NFQ09ORF9BUkcsCi0gICAgICAiXHU2ODM5XHU2MzZFIGRvY3VtZW50IFx1NTFGRFx1NjU3MFx1NzY4NFx1N0IyQ1x1NEU4Q1x1NEUyQVx1NTNDMlx1NjU3MFx1NUY5N1x1NTIzMFx1NzY4NFx1ODI4Mlx1NzBCOVx1OTZDNlx1NEUzQVx1N0E3QVx1MzAwMlx1OEZENFx1NTZERVx1N0E3QSBub2RlLXNldFx1MzAwMiJ9LAotCi0gIC8vRm9sbG93aW5nIGFyZSB0aGUgbmV3IFdBUk5JTkcga2V5cyBhZGRlZCBpbiBYQUxBTiBjb2RlIGJhc2UgYWZ0ZXIgSmRrIDEuNCAoWGFsYW4gMi4yLUQxMSkKLQotICAgIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAibmFtZSIgYW5kICJ4c2w6cHJvY2Vzc2luZy1pbnN0cnVjdGlvbiIgYXJlIGtleXdvcmRzCi0gICAgLy8gYW5kIG11c3Qgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgeyBXR19QUk9DRVNTSU5HSU5TVFJVQ1RJT05fTkFNRV9DQU5UX0JFX1hNTCwKLSAgICAgICJ4c2w6cHJvY2Vzc2luZy1pbnN0cnVjdGlvbiBcdTU0MERcdTc5RjBcdTc2ODQgJ25hbWUnIFx1NUM1RVx1NjAyN1x1NzY4NFx1NTAzQ1x1NEUwRFx1ODBGRFx1NEUzQSAneG1sJyJ9LAotCi0gICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogICJuYW1lIiBhbmQgInhzbDpwcm9jZXNzaW5nLWluc3RydWN0aW9uIiBhcmUga2V5d29yZHMKLSAgICAvLyBhbmQgbXVzdCBub3QgYmUgdHJhbnNsYXRlZC4gICJOQ05hbWUiIGlzIGFuIFhNTCBkYXRhLXR5cGUgYW5kIG11c3Qgbm90IGJlCi0gICAgLy8gdHJhbnNsYXRlZC4KLSAgICB7IFdHX1BST0NFU1NJTkdJTlNUUlVDVElPTl9OT1RWQUxJRF9OQ05BTUUsCi0gICAgICAieHNsOnByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24gXHU3Njg0ICcnbmFtZScnIFx1NUM1RVx1NjAyN1x1NzY4NFx1NTAzQ1x1NUZDNVx1OTg3Qlx1NjYyRlx1NjcwOVx1NjU0OFx1NzY4NCBOQ05hbWU6IHswfSJ9LAotCi0gICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyByZXBvcnRlZCBpZiB0aGUgc3R5bGVzaGVldCB0aGF0IGlzCi0gICAgLy8gYmVpbmcgcHJvY2Vzc2VkIGF0dGVtcHRlZCB0byBjb25zdHJ1Y3QgYW4gWE1MIGRvY3VtZW50IHdpdGggYW4gYXR0cmlidXRlIGluIGEKLSAgICAvLyBwbGFjZSBvdGhlciB0aGFuIG9uIGFuIGVsZW1lbnQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgc3BlY2lmaWVzIHRoZSBuYW1lIG9mCi0gICAgLy8gdGhlIGF0dHJpYnV0ZS4KLSAgICB7IFdHX0lMTEVHQUxfQVRUUklCVVRFX1BPU0lUSU9OLAotICAgICAgIlx1NTcyOFx1NzUxRlx1NjIxMFx1NUI1MFx1ODI4Mlx1NzBCOVx1NEU0Qlx1NTQwRVx1NjIxNlx1NTcyOFx1NzUxRlx1NjIxMFx1NTE0M1x1N0QyMFx1NEU0Qlx1NTI0RFx1NjVFMFx1NkNENVx1NkRGQlx1NTJBMFx1NUM1RVx1NjAyNyB7MH1cdTMwMDJcdTVDMDZcdTVGRkRcdTc1NjVcdTVDNUVcdTYwMjdcdTMwMDIifSwKLQotICAgIHsgTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSLAotICAgICAgIlx1NUMxRFx1OEJENVx1NEZFRVx1NjUzOVx1NEUwRFx1NTE0MVx1OEJCOFx1NEZFRVx1NjUzOVx1NzY4NFx1NUJGOVx1OEM2MVx1MzAwMiIKLSAgICB9LAotCi0gICAgLy9DaGVjazogV0hZIFRIRVJFIElTIEEgR0FQIEIvVyBOVU1CRVJTIGluIHRoZSBYU0xURXJyb3JSZXNvdXJjZXMgcHJvcGVydGllcyBmaWxlPwotCi0gIC8vIE90aGVyIG1pc2NlbGxhbmVvdXMgdGV4dCB1c2VkIGluc2lkZSB0aGUgY29kZS4uLgotICB7ICJ1aV9sYW5ndWFnZSIsICJlbiJ9LAotICB7ICAiaGVscF9sYW5ndWFnZSIsICAiZW4iIH0sCi0gIHsgICJsYW5ndWFnZSIsICAiZW4iIH0sCi0gIHsgIkJBRF9DT0RFIiwgImNyZWF0ZU1lc3NhZ2UgXHU3Njg0XHU1M0MyXHU2NTcwXHU4RDg1XHU1MUZBXHU4MzAzXHU1NkY0In0sCi0gIHsgICJGT1JNQVRfRkFJTEVEIiwgIlx1OEMwM1x1NzUyOCBtZXNzYWdlRm9ybWF0IFx1NjVGNlx1NjI5Qlx1NTFGQVx1NUYwMlx1NUUzOFx1OTUxOVx1OEJFRiJ9LAotICB7ICAidmVyc2lvbiIsICI+Pj4+Pj4+IFhhbGFuIFx1NzI0OFx1NjcyQyAifSwKLSAgeyAgInZlcnNpb24yIiwgICI8PDw8PDw8In0sCi0gIHsgICJ5ZXMiLCAiXHU2NjJGIn0sCi0gIHsgImxpbmUiLCAiXHU4ODRDXHU1M0Y3In0sCi0gIHsgImNvbHVtbiIsIlx1NTIxN1x1NTNGNyJ9LAotICB7ICJ4c2xkb25lIiwgIlhTTFByb2Nlc3NvcjogXHU1QjhDXHU2MjEwIn0sCi0KLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlcyBwcm92aWRlIHVzYWdlIGluZm9ybWF0aW9uCi0gIC8vIGZvciB0aGUgWGFsYW4gUHJvY2VzcyBjb21tYW5kIGxpbmUuICAiUHJvY2VzcyIgaXMgdGhlIG5hbWUgb2YgYSBKYXZhIGNsYXNzLAotICAvLyBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLgotICB7ICJ4c2xQcm9jX29wdGlvbiIsICJYYWxhbi1KIFx1NTQ3RFx1NEVFNFx1ODg0QyBQcm9jZXNzIFx1N0M3Qlx1OTAwOVx1OTg3OToifSwKLSAgeyAieHNsUHJvY19vcHRpb24iLCAiWGFsYW4tSiBcdTU0N0RcdTRFRTRcdTg4NEMgUHJvY2VzcyBcdTdDN0JcdTkwMDlcdTk4Nzk6In0sCi0gIHsgInhzbFByb2NfaW52YWxpZF94c2x0Y19vcHRpb24iLCAiWFNMVEMgXHU2QTIxXHU1RjBGXHU0RTBCXHU0RTBEXHU2NTJGXHU2MzAxXHU5MDA5XHU5ODc5ezB9XHUzMDAyIn0sCi0gIHsgInhzbFByb2NfaW52YWxpZF94YWxhbl9vcHRpb24iLCAiXHU5MDA5XHU5ODc5ezB9XHU1M0VBXHU4MEZEXHU0RTBFIC1YU0xUQyBcdTRFMDBcdThENzdcdTRGN0ZcdTc1MjhcdTMwMDIifSwKLSAgeyAieHNsUHJvY19ub19pbnB1dCIsICJcdTk1MTlcdThCRUY6IFx1NjcyQVx1NjMwN1x1NUI5QVx1NjgzN1x1NUYwRlx1ODg2OFx1NjIxNlx1OEY5M1x1NTE2NSB4bWxcdTMwMDJcdThGRDBcdTg4NENcdTZCNjRcdTU0N0RcdTRFRTRcdTY1RjYsIFx1NzUyOFx1NkNENVx1NjMwN1x1NEVFNFx1NEUwRFx1NUUyNlx1NEVGQlx1NEY1NVx1OTAwOVx1OTg3OVx1MzAwMiJ9LAotICB7ICJ4c2xQcm9jX2NvbW1vbl9vcHRpb25zIiwgIi1cdTUxNkNcdTc1MjhcdTkwMDlcdTk4NzktIn0sCi0gIHsgInhzbFByb2NfeGFsYW5fb3B0aW9ucyIsICItWGFsYW4gXHU3Njg0XHU5MDA5XHU5ODc5LSJ9LAotICB7ICJ4c2xQcm9jX3hzbHRjX29wdGlvbnMiLCAiLVhTTFRDIFx1NzY4NFx1OTAwOVx1OTg3OS0ifSwKLSAgeyAieHNsUHJvY19yZXR1cm5fdG9fY29udGludWUiLCAiKFx1NjMwOSA8cmV0dXJuPiBcdTRFRTVcdTdFRTdcdTdFRUQpIn0sCi0KLSAgIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6IFRoZSBvcHRpb24gbmFtZSBhbmQgdGhlIHBhcmFtZXRlciBuYW1lIGRvIG5vdCBuZWVkIHRvCi0gICAvLyBiZSB0cmFuc2xhdGVkLiBPbmx5IHRyYW5zbGF0ZSB0aGUgbWVzc2FnZXMgaW4gcGFyZW50aGVzZXMuICBOb3RlIGFsc28gdGhhdAotICAgLy8gbGVhZGluZyB3aGl0ZXNwYWNlIGluIHRoZSBtZXNzYWdlcyBpcyB1c2VkIHRvIGluZGVudCB0aGUgdXNhZ2UgaW5mb3JtYXRpb24KLSAgIC8vIGZvciBlYWNoIG9wdGlvbiBpbiB0aGUgRW5nbGlzaCBtZXNzYWdlcy4KLSAgIC8vIERvIG5vdCB0cmFuc2xhdGUgdGhlIGtleXdvcmRzOiBYU0xUQywgU0FYLCBET00gYW5kIERUTS4KLSAgeyAib3B0aW9uWFNMVEMiLCAiICAgWy1YU0xUQyAoXHU0RjdGXHU3NTI4IFhTTFRDIFx1OEZEQlx1ODg0Q1x1OEY2Q1x1NjM2MildIn0sCi0gIHsgIm9wdGlvbklOIiwgIiAgIFstSU4gaW5wdXRYTUxVUkxdIn0sCi0gIHsgIm9wdGlvblhTTCIsICIgICBbLVhTTCBYU0xUcmFuc2Zvcm1hdGlvblVSTF0ifSwKLSAgeyAib3B0aW9uT1VUIiwgICIgICBbLU9VVCBvdXRwdXRGaWxlTmFtZV0ifSwKLSAgeyAib3B0aW9uTFhDSU4iLCAiICAgWy1MWENJTiBjb21waWxlZFN0eWxlc2hlZXRGaWxlTmFtZUluXSJ9LAotICB7ICJvcHRpb25MWENPVVQiLCAiICAgWy1MWENPVVQgY29tcGlsZWRTdHlsZXNoZWV0RmlsZU5hbWVPdXRPdXRdIn0sCi0gIHsgIm9wdGlvblBBUlNFUiIsICIgICBbLVBBUlNFUiBmdWxseSBxdWFsaWZpZWQgY2xhc3MgbmFtZSBvZiBwYXJzZXIgbGlhaXNvbl0ifSwKLSAgeyAgIm9wdGlvbkUiLCAiICAgWy1FIChcdTRFMERcdTVDNTVcdTVGMDBcdTVCOUVcdTRGNTNcdTVGMTVcdTc1MjgpXSJ9LAotICB7ICAib3B0aW9uViIsICAiICAgWy1FIChcdTRFMERcdTVDNTVcdTVGMDBcdTVCOUVcdTRGNTNcdTVGMTVcdTc1MjgpXSJ9LAotICB7ICAib3B0aW9uUUMiLCAiICAgWy1RQyAoXHU2NUUwXHU2M0QwXHU3OTNBXHU2QTIxXHU1RjBGXHU1MUIyXHU3QTgxXHU4QjY2XHU1NDRBKV0ifSwKLSAgeyAgIm9wdGlvblEiLCAiICAgWy1RIChcdTY1RTBcdTYzRDBcdTc5M0FcdTZBMjFcdTVGMEYpXSJ9LAotICB7ICAib3B0aW9uTEYiLCAiICAgWy1MRiAoXHU0RUM1XHU1NzI4XHU4RjkzXHU1MUZBXHU2NUY2XHU0RjdGXHU3NTI4XHU2MzYyXHU4ODRDXHU3QjI2IHtcdTlFRDhcdThCQTRcdTUwM0NcdTRFM0EgQ1IvTEZ9KV0ifSwKLSAgeyAgIm9wdGlvbkNSIiwgIiAgIFstQ1IgKFx1NEVDNVx1NTcyOFx1OEY5M1x1NTFGQVx1NjVGNlx1NEY3Rlx1NzUyOFx1NTZERVx1OEY2NiB7XHU5RUQ4XHU4QkE0XHU1MDNDXHU0RTNBIENSL0xGfSldIn0sCi0gIHsgIm9wdGlvbkVTQ0FQRSIsICIgICBbLUVTQ0FQRSAoXHU4OTgxXHU4RjZDXHU3OUZCXHU3Njg0XHU1QjU3XHU3QjI2IHtcdTlFRDhcdThCQTRcdTUwM0NcdTRFM0EgPD4mXCInXFxyXFxufV0ifSwKLSAgeyAib3B0aW9uSU5ERU5UIiwgIiAgIFstSU5ERU5UIChcdTYzQTdcdTUyMzZcdTg5ODFcdTdGMjlcdThGREJcdTc2ODRcdTdBN0FcdTY4M0NcdTY1NzAge1x1OUVEOFx1OEJBNFx1NTAzQ1x1NEUzQSAwfSldIn0sCi0gIHsgIm9wdGlvblRUIiwgIiAgIFstVFQgKFx1NTcyOFx1OEMwM1x1NzUyOFx1NkEyMVx1Njc3Rlx1NjVGNlx1OERERlx1OEUyQVx1NkEyMVx1Njc3Rlx1MzAwMildIn0sCi0gIHsgIm9wdGlvblRHIiwgIiAgIFstVEcgKFx1OERERlx1OEUyQVx1NkJDRlx1NEUyQVx1NzUxRlx1NjIxMFx1NEU4Qlx1NEVGNlx1MzAwMildIn0sCi0gIHsgIm9wdGlvblRTIiwgIiAgIFstVFMgKFx1OERERlx1OEUyQVx1NkJDRlx1NEUyQVx1OTAwOVx1NjJFOVx1NEU4Qlx1NEVGNlx1MzAwMildIn0sCi0gIHsgICJvcHRpb25UVEMiLCAiICAgWy1UVEMgKFx1NTcyOFx1NTkwNFx1NzQwNlx1NkEyMVx1Njc3Rlx1NUI1MFx1N0VBN1x1NjVGNlx1OERERlx1OEUyQVx1NkEyMVx1Njc3Rlx1NUI1MFx1N0VBN1x1MzAwMildIn0sCi0gIHsgIm9wdGlvblRDTEFTUyIsICIgICBbLVRDTEFTUyAoXHU3NTI4XHU0RThFXHU4RERGXHU4RTJBXHU2MjY5XHU1QzU1XHU3Njg0IFRyYWNlTGlzdGVuZXIgXHU3QzdCXHUzMDAyKV0ifSwKLSAgeyAib3B0aW9uVkFMSURBVEUiLCAiICAgWy1WQUxJREFURSAoXHU4QkJFXHU3RjZFXHU2NjJGXHU1NDI2XHU4RkRCXHU4ODRDXHU5QThDXHU4QkMxXHUzMDAyXHU5RUQ4XHU4QkE0XHU2MEM1XHU1MUI1XHU0RTBCLCBcdTVDMDZcdTc5ODFcdTZCNjJcdTlBOENcdThCQzFcdTMwMDIpXSJ9LAotICB7ICJvcHRpb25FRFVNUCIsICIgICBbLUVEVU1QIHtvcHRpb25hbCBmaWxlbmFtZX0gKFx1NTcyOFx1NTFGQVx1OTUxOVx1NjVGNlx1NjI2N1x1ODg0Q1x1NTgwNlx1NjgwOFx1OEY2Q1x1NTBBOFx1MzAwMildIn0sCi0gIHsgICJvcHRpb25YTUwiLCAiICAgWy1YTUwgKFx1NEY3Rlx1NzUyOCBYTUwgXHU2ODNDXHU1RjBGXHU4QkJFXHU3RjZFXHU1REU1XHU1MTc3XHU1RTc2XHU2REZCXHU1MkEwIFhNTCBcdTY4MDdcdTU5MzRcdTMwMDIpXSJ9LAotICB7ICAib3B0aW9uVEVYVCIsICIgICBbLVRFWFQgKFx1NEY3Rlx1NzUyOFx1N0I4MFx1NTM1NVx1NjU4N1x1NjcyQ1x1NjgzQ1x1NUYwRlx1OEJCRVx1N0Y2RVx1NURFNVx1NTE3N1x1MzAwMildIn0sCi0gIHsgICJvcHRpb25IVE1MIiwgIiAgIFstSFRNTCAoXHU0RjdGXHU3NTI4IEhUTUwgXHU2ODNDXHU1RjBGXHU4QkJFXHU3RjZFXHU1REU1XHU1MTc3XHUzMDAyKV0ifSwKLSAgeyAgIm9wdGlvblBBUkFNIiwgIiAgIFstUEFSQU0gXHU1NDBEXHU3OUYwXHU4ODY4XHU4RkJFXHU1RjBGIChcdThCQkVcdTdGNkVcdTY4MzdcdTVGMEZcdTg4NjhcdTUzQzJcdTY1NzApXSJ9LAotICB7ICAibm9QYXJzZXJtc2cxIiwgIlhTTCBcdThGREJcdTdBMEJcdTY3MkFcdTYyMTBcdTUyOUZcdTMwMDIifSwKLSAgeyAgIm5vUGFyc2VybXNnMiIsICIqKiBcdTYyN0VcdTRFMERcdTUyMzBcdTg5RTNcdTY3OTBcdTU2NjggKioifSwKLSAgeyAibm9QYXJzZXJtc2czIiwgICJcdThCRjdcdTY4QzBcdTY3RTVcdTYwQThcdTc2ODRcdTdDN0JcdThERUZcdTVGODRcdTMwMDIifSwKLSAgeyAibm9QYXJzZXJtc2c0IiwgIlx1NTk4Mlx1Njc5Q1x1NkNBMVx1NjcwOSBJQk0gXHU2M0QwXHU0RjlCXHU3Njg0IFhNTCBQYXJzZXIgZm9yIEphdmEsIFx1NTIxOVx1NTNFRlx1NEVFNVx1NEVDRSJ9LAotICB7ICJub1BhcnNlcm1zZzUiLCAiSUJNIEFscGhhV29ya3MgXHU4RkRCXHU4ODRDXHU0RTBCXHU4RjdELCBcdTdGNTFcdTU3NDBcdTRFM0E6IGh0dHA6Ly93d3cuYWxwaGF3b3Jrcy5pYm0uY29tL2Zvcm11bGEveG1sIn0sCi0gIHsgIm9wdGlvblVSSVJFU09MVkVSIiwgIiAgIFstVVJJUkVTT0xWRVIgXHU1QjhDXHU2NTc0XHU3QzdCXHU1NDBEIChcdTRGN0ZcdTc1MjggVVJJUmVzb2x2ZXIgXHU4OUUzXHU2NzkwIFVSSSldIn0sCi0gIHsgIm9wdGlvbkVOVElUWVJFU09MVkVSIiwgICIgICBbLUVOVElUWVJFU09MVkVSIFx1NUI4Q1x1NjU3NFx1N0M3Qlx1NTQwRCAoXHU0RjdGXHU3NTI4IEVudGl0eVJlc29sdmVyIFx1ODlFM1x1Njc5MFx1NUI5RVx1NEY1MyldIn0sCi0gIHsgIm9wdGlvbkNPTlRFTlRIQU5ETEVSIiwgICIgICBbLUNPTlRFTlRIQU5ETEVSIFx1NUI4Q1x1NjU3NFx1N0M3Qlx1NTQwRCAoXHU0RjdGXHU3NTI4IENvbnRlbnRIYW5kbGVyIFx1NUU4Rlx1NTIxN1x1NTMxNlx1OEY5M1x1NTFGQSldIn0sCi0gIHsgICJvcHRpb25MSU5FTlVNQkVSUyIsICAiICAgWy1MIFx1NEY3Rlx1NzUyOFx1NkU5MFx1NjU4N1x1Njg2M1x1NzY4NFx1ODg0Q1x1NTNGN10ifSwKLSAgeyAib3B0aW9uU0VDVVJFUFJPQ0VTU0lORyIsICIgICBbLVNFQ1VSRSAoXHU1QzA2XHU1Qjg5XHU1MTY4XHU1OTA0XHU3NDA2XHU1MjlGXHU4MEZEXHU4QkJFXHU3RjZFXHU0RTNBXHUyMDFDXHU3NzFGXHUyMDFEXHUzMDAyKV0ifSwKLQotICAgIC8vIEZvbGxvd2luZyBhcmUgdGhlIG5ldyBvcHRpb25zIGFkZGVkIGluIFhTTFRFcnJvclJlc291cmNlcy5wcm9wZXJ0aWVzIGZpbGVzIGFmdGVyIEpkayAxLjQgKFhhbGFuIDIuMi1EMTEpCi0KLQotICB7ICAib3B0aW9uTUVESUEiLCAgIiAgIFstTUVESUEgbWVkaWFUeXBlIChcdTRGN0ZcdTc1MjggbWVkaWEgXHU1QzVFXHU2MDI3XHU2N0U1XHU2MjdFXHU0RTBFXHU2NTg3XHU2ODYzXHU1MTczXHU4MDU0XHU3Njg0XHU2ODM3XHU1RjBGXHU4ODY4XHUzMDAyKV0ifSwKLSAgeyAgIm9wdGlvbkZMQVZPUiIsICAiICAgWy1GTEFWT1IgZmxhdm9yTmFtZSAoXHU2NjBFXHU3ODZFXHU0RjdGXHU3NTI4IHMycz1TQVggXHU2MjE2IGQyZD1ET00gXHU2MjY3XHU4ODRDXHU4RjZDXHU2MzYyXHUzMDAyKV0gIn0sIC8vIEFkZGVkIGJ5IHNib2FnL3NjdXJjdXJ1OyBleHBlcmltZW50YWwKLSAgeyAib3B0aW9uRElBRyIsICIgICBbLURJQUcgKFx1OEY5M1x1NTFGQVx1NTE2OFx1OTBFOFx1OEY2Q1x1NjM2Mlx1NjVGNlx1OTVGNCAoXHU2QkVCXHU3OUQyKVx1MzAwMildIn0sCi0gIHsgIm9wdGlvbklOQ1JFTUVOVEFMIiwgICIgICBbLUlOQ1JFTUVOVEFMIChcdTkwMUFcdThGQzdcdTVDMDYgaHR0cDovL3htbC5hcGFjaGUub3JnL3hhbGFuL2ZlYXR1cmVzL2luY3JlbWVudGFsIFx1OEJCRVx1N0Y2RVx1NEUzQVx1MjAxQ1x1NzcxRlx1MjAxRFx1Njc2NVx1OEJGN1x1NkM0Mlx1NTg5RVx1OTFDRiBEVE0gXHU2Nzg0XHU1RUZBXHUzMDAyKV0ifSwKLSAgeyAgIm9wdGlvbk5PT1BUSU1JTUlaRSIsICAiICAgWy1OT09QVElNSU1JWkUgKFx1OTAxQVx1OEZDN1x1NUMwNiBodHRwOi8veG1sLmFwYWNoZS5vcmcveGFsYW4vZmVhdHVyZXMvb3B0aW1pemUgXHU4QkJFXHU3RjZFXHU0RTNBXHUyMDFDXHU1MDQ3XHUyMDFEXHU2NzY1XHU4QkY3XHU2QzQyXHU0RTBEXHU2MjY3XHU4ODRDXHU2ODM3XHU1RjBGXHU4ODY4XHU0RjE4XHU1MzE2XHU1OTA0XHU3NDA2XHUzMDAyKV0ifSwKLSAgeyAib3B0aW9uUkwiLCAgIiAgIFstUkwgcmVjdXJzaW9ubGltaXQgKFx1NThGMFx1NjYwRVx1NjgzN1x1NUYwRlx1ODg2OFx1OTAxMlx1NUY1Mlx1NkRGMVx1NUVBNlx1NzY4NFx1NjU3MFx1NUI1N1x1OTY1MFx1NTIzNlx1MzAwMildIn0sCi0gIHsgICAib3B0aW9uWE8iLCAgIiAgIFstWE8gW3RyYW5zbGV0TmFtZV0gKFx1NEUzQVx1NzUxRlx1NjIxMFx1NzY4NCB0cmFuc2xldCBcdTUyMDZcdTkxNERcdTU0MERcdTc5RjApXSJ9LAotICB7ICAib3B0aW9uWEQiLCAiICAgWy1YRCBkZXN0aW5hdGlvbkRpcmVjdG9yeSAoXHU2MzA3XHU1QjlBIHRyYW5zbGV0IFx1NzY4NFx1NzZFRVx1NjgwN1x1NzZFRVx1NUY1NSldIn0sCi0gIHsgICJvcHRpb25YSiIsICAiICAgWy1YSiBqYXJmaWxlIChcdTVDMDYgdHJhbnNsZXQgXHU3QzdCXHU2MjUzXHU1MzA1XHU1MjMwXHU1NDBEXHU0RTNBIDxqYXJmaWxlPiBcdTc2ODQgamFyIFx1NjU4N1x1NEVGNlx1NEUyRCldIn0sCi0gIHsgICAib3B0aW9uWFAiLCAgIiAgIFstWFAgcGFja2FnZSAoXHU0RTNBXHU3NTFGXHU2MjEwXHU3Njg0XHU2MjQwXHU2NzA5IHRyYW5zbGV0IFx1N0M3Qlx1NjMwN1x1NUI5QVx1N0EwQlx1NUU4Rlx1NTMwNVx1NTQwRFx1NzlGMFx1NTI0RFx1N0YwMCldIn0sCi0KLSAgLy9BZGRJVElPTkFMICBTVFJJTkdTIHRoYXQgbmVlZCBMMTBuCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgZGVzY3JpYmVzIHVzYWdlIG9mIGEgcGFydGljdWxhcgotICAvLyBjb21tYW5kLWxpbmUgb3B0aW9uIHRoYXQgaXMgdXNlZCB0byBlbmFibGUgdGhlICJ0ZW1wbGF0ZSBpbmxpbmluZyIKLSAgLy8gb3B0aW1pemF0aW9uLiAgVGhlIG9wdGltaXphdGlvbiBpbnZvbHZlcyBtYWtpbmcgYSBjb3B5IG9mIHRoZSBjb2RlCi0gIC8vIGdlbmVyYXRlZCBmb3IgYSB0ZW1wbGF0ZSBpbiBhbm90aGVyIHRlbXBsYXRlIHRoYXQgcmVmZXJzIHRvIGl0LgotICB7ICJvcHRpb25YTiIsICAiICAgWy1YTiAoXHU1NDJGXHU3NTI4XHU2QTIxXHU2NzdGXHU1MTg1XHU1RDRDKV0iIH0sCi0gIHsgIm9wdGlvblhYIiwgICIgICBbLVhYIChcdTU0MkZcdTc1MjhcdTk2NDRcdTUyQTBcdThDMDNcdThCRDVcdTZEODhcdTYwNkZcdThGOTNcdTUxRkEpXSJ9LAotICB7ICJvcHRpb25YVCIgLCAiICAgWy1YVCAoXHU1OTgyXHU2NzlDXHU1M0VGXHU4MEZELCBcdTRGN0ZcdTc1MjggdHJhbnNsZXQgXHU4RkRCXHU4ODRDXHU4RjZDXHU2MzYyKV0ifSwKLSAgeyAiZGlhZ1RpbWluZyIsIiAtLS0tLS0tLS0gXHU5MDFBXHU4RkM3ezF9XHU4RjZDXHU2MzYyezB9XHU4MkIxXHU4RDM5XHU0RTg2IHsyfSBcdTZCRUJcdTc5RDJcdTc2ODRcdTY1RjZcdTk1RjQiIH0sCi0gIHsgInJlY3Vyc2lvblRvb0RlZXAiLCJcdTZBMjFcdTY3N0ZcdTVENENcdTU5NTdcdTU5MkFcdTZERjFcdTMwMDJcdTVENENcdTU5NTcgPSB7MH0sIFx1NkEyMVx1Njc3RnsxfSB7Mn0iIH0sCi0gIHsgIm5hbWVJcyIsICJcdTU0MERcdTc5RjBcdTRFM0EiIH0sCi0gIHsgIm1hdGNoUGF0dGVybklzIiwgIlx1NTMzOVx1OTE0RFx1NkEyMVx1NUYwRlx1NEUzQSIgfQotCi0gIH07Ci0KLSAgfQotICAvLyA9PT09PT09PT09PT09PT09PSBJTkZSQVNUUlVDVFVSRSA9PT09PT09PT09PT09PT09PT09PT09Ci0KLSAgLyoqIFN0cmluZyBmb3IgdXNlIHdoZW4gYSBiYWQgZXJyb3IgY29kZSB3YXMgZW5jb3VudGVyZWQuICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEJBRF9DT0RFID0gIkJBRF9DT0RFIjsKLQotICAvKiogU3RyaW5nIGZvciB1c2Ugd2hlbiBmb3JtYXR0aW5nIG9mIHRoZSBlcnJvciBzdHJpbmcgZmFpbGVkLiAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEZPUk1BVF9GQUlMRUQgPSAiRk9STUFUX0ZBSUxFRCI7Ci0KLSAgLyoqIEdlbmVyYWwgZXJyb3Igc3RyaW5nLiAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUk9SX1NUUklORyA9ICIjZXJyb3IiOwotCi0gIC8qKiBTdHJpbmcgdG8gcHJlcGVuZCB0byBlcnJvciBtZXNzYWdlcy4gICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUk9SX0hFQURFUiA9ICJFcnJvcjogIjsKLQotICAvKiogU3RyaW5nIHRvIHByZXBlbmQgdG8gd2FybmluZyBtZXNzYWdlcy4gICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0FSTklOR19IRUFERVIgPSAiV2FybmluZzogIjsKLQotICAvKiogU3RyaW5nIHRvIHNwZWNpZnkgdGhlIFhTTFQgbW9kdWxlLiAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgWFNMX0hFQURFUiA9ICJYU0xUICI7Ci0KLSAgLyoqIFN0cmluZyB0byBzcGVjaWZ5IHRoZSBYTUwgcGFyc2VyIG1vZHVsZS4gICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFhNTF9IRUFERVIgPSAiWE1MICI7Ci0KLSAgLyoqIEkgZG9uJ3QgdGhpbmsgdGhpcyBpcyB1c2VkIGFueSBtb3JlLgotICAgKiBAZGVwcmVjYXRlZCAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgUVVFUllfSEVBREVSID0gIlBBVFRFUk4gIjsKLQotCi0gICAgfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC9yZXMvWFNMVEVycm9yUmVzb3VyY2VzX3poX1RXLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3Jlcy9YU0xURXJyb3JSZXNvdXJjZXNfemhfVFcuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZWU4YTExYi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3Jlcy9YU0xURXJyb3JSZXNvdXJjZXNfemhfVFcuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE0NDcgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwucmVzOwotCi1pbXBvcnQgamF2YS51dGlsLkxpc3RSZXNvdXJjZUJ1bmRsZTsKLWltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwotaW1wb3J0IGphdmEudXRpbC5NaXNzaW5nUmVzb3VyY2VFeGNlcHRpb247Ci1pbXBvcnQgamF2YS51dGlsLlJlc291cmNlQnVuZGxlOwotCi0vKioKLSAqIFNldCB1cCBlcnJvciBtZXNzYWdlcy4KLSAqIFdlIGJ1aWxkIGEgdHdvIGRpbWVuc2lvbmFsIGFycmF5IG9mIG1lc3NhZ2Uga2V5cyBhbmQKLSAqIG1lc3NhZ2Ugc3RyaW5ncy4gSW4gb3JkZXIgdG8gYWRkIGEgbmV3IG1lc3NhZ2UgaGVyZSwKLSAqIHlvdSBuZWVkIHRvIGZpcnN0IGFkZCBhIFN0cmluZyBjb25zdGFudC4gQW5kCi0gKiAgeW91IG5lZWQgdG8gZW50ZXIga2V5ICwgdmFsdWUgcGFpciBhcyBwYXJ0IG9mIGNvbnRlbnRzCi0gKiBBcnJheS4gWW91IGFsc28gbmVlZCB0byB1cGRhdGUgTUFYX0NPREUgZm9yIGVycm9yIHN0cmluZ3MKLSAqIGFuZCBNQVhfV0FSTklORyBmb3Igd2FybmluZ3MgKCBOZWVkZWQgZm9yIG9ubHkgaW5mb3JtYXRpb24KLSAqIHB1cnBvc2UgKQotICovCi1wdWJsaWMgY2xhc3MgWFNMVEVycm9yUmVzb3VyY2VzX3poX1RXIGV4dGVuZHMgTGlzdFJlc291cmNlQnVuZGxlCi17Ci0KLS8qCi0gKiBUaGlzIGZpbGUgY29udGFpbnMgZXJyb3IgYW5kIHdhcm5pbmcgbWVzc2FnZXMgcmVsYXRlZCB0byBYYWxhbiBFcnJvcgotICogSGFuZGxpbmcuCi0gKgotICogIEdlbmVyYWwgbm90ZXMgdG8gdHJhbnNsYXRvcnM6Ci0gKgotICogIDEpIFhhbGFuIChvciBtb3JlIHByb3Blcmx5LCBYYWxhbi1pbnRlcnByZXRpdmUpIGFuZCBYU0xUQyBhcmUgbmFtZXMgb2YKLSAqICAgICBjb21wb25lbnRzLgotICogICAgIFhTTFQgaXMgYW4gYWNyb255bSBmb3IgIlhNTCBTdHlsZXNoZWV0IExhbmd1YWdlOiBUcmFuc2Zvcm1hdGlvbnMiLgotICogICAgIFhTTFRDIGlzIGFuIGFjcm9ueW0gZm9yIFhTTFQgQ29tcGlsZXIuCi0gKgotICogIDIpIEEgc3R5bGVzaGVldCBpcyBhIGRlc2NyaXB0aW9uIG9mIGhvdyB0byB0cmFuc2Zvcm0gYW4gaW5wdXQgWE1MIGRvY3VtZW50Ci0gKiAgICAgaW50byBhIHJlc3VsdGFudCBYTUwgZG9jdW1lbnQgKG9yIEhUTUwgZG9jdW1lbnQgb3IgdGV4dCkuICBUaGUKLSAqICAgICBzdHlsZXNoZWV0IGl0c2VsZiBpcyBkZXNjcmliZWQgaW4gdGhlIGZvcm0gb2YgYW4gWE1MIGRvY3VtZW50LgotICoKLSAqICAzKSBBIHRlbXBsYXRlIGlzIGEgY29tcG9uZW50IG9mIGEgc3R5bGVzaGVldCB0aGF0IGlzIHVzZWQgdG8gbWF0Y2ggYQotICogICAgIHBhcnRpY3VsYXIgcG9ydGlvbiBvZiBhbiBpbnB1dCBkb2N1bWVudCBhbmQgc3BlY2lmaWVzIHRoZSBmb3JtIG9mIHRoZQotICogICAgIGNvcnJlc3BvbmRpbmcgcG9ydGlvbiBvZiB0aGUgb3V0cHV0IGRvY3VtZW50LgotICoKLSAqICA0KSBBbiBlbGVtZW50IGlzIGEgbWFyay11cCB0YWcgaW4gYW4gWE1MIGRvY3VtZW50OyBhbiBhdHRyaWJ1dGUgaXMgYQotICogICAgIG1vZGlmaWVyIG9uIHRoZSB0YWcuICBGb3IgZXhhbXBsZSwgaW4gPGVsZW0gYXR0cj0ndmFsJyBhdHRyMj0ndmFsMic+Ci0gKiAgICAgImVsZW0iIGlzIGFuIGVsZW1lbnQgbmFtZSwgImF0dHIiIGFuZCAiYXR0cjIiIGFyZSBhdHRyaWJ1dGUgbmFtZXMgd2l0aAotICogICAgIHRoZSB2YWx1ZXMgInZhbCIgYW5kICJ2YWwyIiwgcmVzcGVjdGl2ZWx5LgotICoKLSAqICA1KSBBIG5hbWVzcGFjZSBkZWNsYXJhdGlvbiBpcyBhIHNwZWNpYWwgYXR0cmlidXRlIHRoYXQgaXMgdXNlZCB0byBhc3NvY2lhdGUKLSAqICAgICBhIHByZWZpeCB3aXRoIGEgVVJJICh0aGUgbmFtZXNwYWNlKS4gIFRoZSBtZWFuaW5ncyBvZiBlbGVtZW50IG5hbWVzIGFuZAotICogICAgIGF0dHJpYnV0ZSBuYW1lcyB0aGF0IHVzZSB0aGF0IHByZWZpeCBhcmUgZGVmaW5lZCB3aXRoIHJlc3BlY3QgdG8gdGhhdAotICogICAgIG5hbWVzcGFjZS4KLSAqCi0gKiAgNikgIlRyYW5zbGV0IiBpcyBhbiBpbnZlbnRlZCB0ZXJtIHRoYXQgZGVzY3JpYmVzIHRoZSBjbGFzcyBmaWxlIHRoYXQKLSAqICAgICByZXN1bHRzIGZyb20gY29tcGlsaW5nIGFuIFhNTCBzdHlsZXNoZWV0IGludG8gYSBKYXZhIGNsYXNzLgotICoKLSAqICA3KSBYUGF0aCBpcyBhIHNwZWNpZmljYXRpb24gdGhhdCBkZXNjcmliZXMgYSBub3RhdGlvbiBmb3IgaWRlbnRpZnlpbmcKLSAqICAgICBub2RlcyBpbiBhIHRyZWUtc3RydWN0dXJlZCByZXByZXNlbnRhdGlvbiBvZiBhbiBYTUwgZG9jdW1lbnQuICBBbgotICogICAgIGluc3RhbmNlIG9mIHRoYXQgbm90YXRpb24gaXMgcmVmZXJyZWQgdG8gYXMgYW4gWFBhdGggZXhwcmVzc2lvbi4KLSAqCi0gKi8KLQotICAvKgotICAgKiBTdGF0aWMgdmFyaWFibGVzCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX05BTUVTUEFDRV9VUklfVkFMVUVfRk9SX1JFU1VMVF9QUkVGSVggPQotICAgICAgICAiRVJfSU5WQUxJRF9TRVRfTkFNRVNQQUNFX1VSSV9WQUxVRV9GT1JfUkVTVUxUX1BSRUZJWCI7Ci0KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9OQU1FU1BBQ0VfVVJJX1ZBTFVFX0ZPUl9SRVNVTFRfUFJFRklYX0ZPUl9ERUZBVUxUID0KLSAgICAgICAgIkVSX0lOVkFMSURfTkFNRVNQQUNFX1VSSV9WQUxVRV9GT1JfUkVTVUxUX1BSRUZJWF9GT1JfREVGQVVMVCI7Ci0KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fQ1VSTFlCUkFDRSA9ICJFUl9OT19DVVJMWUJSQUNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCA9ICJFUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSUxMRUdBTF9BVFRSSUJVVEUgPSAiRVJfSUxMRUdBTF9BVFRSSUJVVEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OVUxMX1NPVVJDRU5PREVfQVBQTFlJTVBPUlRTID0gIkVSX05VTExfU09VUkNFTk9ERV9BUFBMWUlNUE9SVFMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfQUREID0gIkVSX0NBTk5PVF9BREQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OVUxMX1NPVVJDRU5PREVfSEFORExFQVBQTFlURU1QTEFURVM9IkVSX05VTExfU09VUkNFTk9ERV9IQU5ETEVBUFBMWVRFTVBMQVRFUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX05BTUVfQVRUUklCID0gIkVSX05PX05BTUVfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVEVNUExBVEVfTk9UX0ZPVU5EID0gIkVSX1RFTVBMQVRFX05PVF9GT1VORCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfUkVTT0xWRV9OQU1FX0FWVCA9ICJFUl9DQU5UX1JFU09MVkVfTkFNRV9BVlQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SRVFVSVJFU19BVFRSSUIgPSAiRVJfUkVRVUlSRVNfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTVVTVF9IQVZFX1RFU1RfQVRUUklCID0gIkVSX01VU1RfSEFWRV9URVNUX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0JBRF9WQUxfT05fTEVWRUxfQVRUUklCID0KLSAgICAgICAgICJFUl9CQURfVkFMX09OX0xFVkVMX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BST0NFU1NJTkdJTlNUUlVDVElPTl9OQU1FX0NBTlRfQkVfWE1MID0KLSAgICAgICAgICJFUl9QUk9DRVNTSU5HSU5TVFJVQ1RJT05fTkFNRV9DQU5UX0JFX1hNTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BST0NFU1NJTkdJTlNUUlVDVElPTl9OT1RWQUxJRF9OQ05BTUUgPQotICAgICAgICAgIkVSX1BST0NFU1NJTkdJTlNUUlVDVElPTl9OT1RWQUxJRF9OQ05BTUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9ORUVEX01BVENIX0FUVFJJQiA9ICJFUl9ORUVEX01BVENIX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05FRURfTkFNRV9PUl9NQVRDSF9BVFRSSUIgPQotICAgICAgICAgIkVSX05FRURfTkFNRV9PUl9NQVRDSF9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX1JFU09MVkVfTlNQUkVGSVggPQotICAgICAgICAgIkVSX0NBTlRfUkVTT0xWRV9OU1BSRUZJWCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lMTEVHQUxfVkFMVUUgPSAiRVJfSUxMRUdBTF9WQUxVRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX09XTkVSRE9DID0gIkVSX05PX09XTkVSRE9DIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRUxFTVRFTVBMQVRFRUxFTV9FUlIgPSJFUl9FTEVNVEVNUExBVEVFTEVNX0VSUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05VTExfQ0hJTEQgPSAiRVJfTlVMTF9DSElMRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05FRURfU0VMRUNUX0FUVFJJQiA9ICJFUl9ORUVEX1NFTEVDVF9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9ORUVEX1RFU1RfQVRUUklCID0gIkVSX05FRURfVEVTVF9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9ORUVEX05BTUVfQVRUUklCID0gIkVSX05FRURfTkFNRV9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19DT05URVhUX09XTkVSRE9DID0gIkVSX05PX0NPTlRFWFRfT1dORVJET0MiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRF9OT1RfQ1JFQVRFX1hNTF9QUk9DX0xJQUlTT04gPQotICAgICAgICAgIkVSX0NPVUxEX05PVF9DUkVBVEVfWE1MX1BST0NfTElBSVNPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BST0NFU1NfTk9UX1NVQ0NFU1NGVUwgPQotICAgICAgICAgIkVSX1BST0NFU1NfTk9UX1NVQ0NFU1NGVUwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT1RfU1VDQ0VTU0ZVTCA9ICJFUl9OT1RfU1VDQ0VTU0ZVTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VOQ09ESU5HX05PVF9TVVBQT1JURUQgPQotICAgICAgICAgIkVSX0VOQ09ESU5HX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRF9OT1RfQ1JFQVRFX1RSQUNFTElTVEVORVIgPQotICAgICAgICAgIkVSX0NPVUxEX05PVF9DUkVBVEVfVFJBQ0VMSVNURU5FUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0tFWV9SRVFVSVJFU19OQU1FX0FUVFJJQiA9Ci0gICAgICAgICAiRVJfS0VZX1JFUVVJUkVTX05BTUVfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfS0VZX1JFUVVJUkVTX01BVENIX0FUVFJJQiA9Ci0gICAgICAgICAiRVJfS0VZX1JFUVVJUkVTX01BVENIX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0tFWV9SRVFVSVJFU19VU0VfQVRUUklCID0KLSAgICAgICAgICJFUl9LRVlfUkVRVUlSRVNfVVNFX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1JFUVVJUkVTX0VMRU1FTlRTX0FUVFJJQiA9Ci0gICAgICAgICAiRVJfUkVRVUlSRVNfRUxFTUVOVFNfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTUlTU0lOR19QUkVGSVhfQVRUUklCID0KLSAgICAgICAgICJFUl9NSVNTSU5HX1BSRUZJWF9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9CQURfU1RZTEVTSEVFVF9VUkwgPSAiRVJfQkFEX1NUWUxFU0hFRVRfVVJMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRklMRV9OT1RfRk9VTkQgPSAiRVJfRklMRV9OT1RfRk9VTkQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JT0VYQ0VQVElPTiA9ICJFUl9JT0VYQ0VQVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX0hSRUZfQVRUUklCID0gIkVSX05PX0hSRUZfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU1RZTEVTSEVFVF9JTkNMVURFU19JVFNFTEYgPQotICAgICAgICAgIkVSX1NUWUxFU0hFRVRfSU5DTFVERVNfSVRTRUxGIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJPQ0VTU0lOQ0xVREVfRVJST1IgPSJFUl9QUk9DRVNTSU5DTFVERV9FUlJPUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01JU1NJTkdfTEFOR19BVFRSSUIgPSAiRVJfTUlTU0lOR19MQU5HX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01JU1NJTkdfQ09OVEFJTkVSX0VMRU1FTlRfQ09NUE9ORU5UID0KLSAgICAgICAgICJFUl9NSVNTSU5HX0NPTlRBSU5FUl9FTEVNRU5UX0NPTVBPTkVOVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTl9PTkxZX09VVFBVVF9UT19FTEVNRU5UID0KLSAgICAgICAgICJFUl9DQU5fT05MWV9PVVRQVVRfVE9fRUxFTUVOVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BST0NFU1NfRVJST1IgPSAiRVJfUFJPQ0VTU19FUlJPUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1VOSU1QTE5PREVfRVJST1IgPSAiRVJfVU5JTVBMTk9ERV9FUlJPUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1NFTEVDVF9FWFBSRVNTSU9OID0iRVJfTk9fU0VMRUNUX0VYUFJFU1NJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfU0VSSUFMSVpFX1hTTFBST0NFU1NPUiA9Ci0gICAgICAgICAiRVJfQ0FOTk9UX1NFUklBTElaRV9YU0xQUk9DRVNTT1IiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19JTlBVVF9TVFlMRVNIRUVUID0gIkVSX05PX0lOUFVUX1NUWUxFU0hFRVQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GQUlMRURfUFJPQ0VTU19TVFlMRVNIRUVUID0KLSAgICAgICAgICJFUl9GQUlMRURfUFJPQ0VTU19TVFlMRVNIRUVUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTEROVF9QQVJTRV9ET0MgPSAiRVJfQ09VTEROVF9QQVJTRV9ET0MiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRE5UX0ZJTkRfRlJBR01FTlQgPQotICAgICAgICAgIkVSX0NPVUxETlRfRklORF9GUkFHTUVOVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PREVfTk9UX0VMRU1FTlQgPSAiRVJfTk9ERV9OT1RfRUxFTUVOVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZPUkVBQ0hfTkVFRF9NQVRDSF9PUl9OQU1FX0FUVFJJQiA9Ci0gICAgICAgICAiRVJfRk9SRUFDSF9ORUVEX01BVENIX09SX05BTUVfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVEVNUExBVEVTX05FRURfTUFUQ0hfT1JfTkFNRV9BVFRSSUIgPQotICAgICAgICAgIkVSX1RFTVBMQVRFU19ORUVEX01BVENIX09SX05BTUVfQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fQ0xPTkVfT0ZfRE9DVU1FTlRfRlJBRyA9Ci0gICAgICAgICAiRVJfTk9fQ0xPTkVfT0ZfRE9DVU1FTlRfRlJBRyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfQ1JFQVRFX0lURU0gPSAiRVJfQ0FOVF9DUkVBVEVfSVRFTSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hNTFNQQUNFX0lMTEVHQUxfVkFMVUUgPQotICAgICAgICAgIkVSX1hNTFNQQUNFX0lMTEVHQUxfVkFMVUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19YU0xLRVlfREVDTEFSQVRJT04gPQotICAgICAgICAgIkVSX05PX1hTTEtFWV9ERUNMQVJBVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfQ1JFQVRFX1VSTCA9ICJFUl9DQU5UX0NSRUFURV9VUkwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YU0xGVU5DVElPTlNfVU5TVVBQT1JURUQgPQotICAgICAgICAgIkVSX1hTTEZVTkNUSU9OU19VTlNVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BST0NFU1NPUl9FUlJPUiA9ICJFUl9QUk9DRVNTT1JfRVJST1IiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT1RfQUxMT1dFRF9JTlNJREVfU1RZTEVTSEVFVCA9Ci0gICAgICAgICAiRVJfTk9UX0FMTE9XRURfSU5TSURFX1NUWUxFU0hFRVQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SRVNVTFROU19OT1RfU1VQUE9SVEVEID0KLSAgICAgICAgICJFUl9SRVNVTFROU19OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfREVGQVVMVFNQQUNFX05PVF9TVVBQT1JURUQgPQotICAgICAgICAgIkVSX0RFRkFVTFRTUEFDRV9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5ERU5UUkVTVUxUX05PVF9TVVBQT1JURUQgPQotICAgICAgICAgIkVSX0lOREVOVFJFU1VMVF9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSUxMRUdBTF9BVFRSSUIgPSAiRVJfSUxMRUdBTF9BVFRSSUIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTktOT1dOX1hTTF9FTEVNID0gIkVSX1VOS05PV05fWFNMX0VMRU0iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9CQURfWFNMU09SVF9VU0UgPSAiRVJfQkFEX1hTTFNPUlRfVVNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTUlTUExBQ0VEX1hTTFdIRU4gPSAiRVJfTUlTUExBQ0VEX1hTTFdIRU4iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YU0xXSEVOX05PVF9QQVJFTlRFRF9CWV9YU0xDSE9PU0UgPQotICAgICAgICAgIkVSX1hTTFdIRU5fTk9UX1BBUkVOVEVEX0JZX1hTTENIT09TRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01JU1BMQUNFRF9YU0xPVEhFUldJU0UgPQotICAgICAgICAgIkVSX01JU1BMQUNFRF9YU0xPVEhFUldJU0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YU0xPVEhFUldJU0VfTk9UX1BBUkVOVEVEX0JZX1hTTENIT09TRSA9Ci0gICAgICAgICAiRVJfWFNMT1RIRVJXSVNFX05PVF9QQVJFTlRFRF9CWV9YU0xDSE9PU0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT1RfQUxMT1dFRF9JTlNJREVfVEVNUExBVEUgPQotICAgICAgICAgIkVSX05PVF9BTExPV0VEX0lOU0lERV9URU1QTEFURSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1VOS05PV05fRVhUX05TX1BSRUZJWCA9Ci0gICAgICAgICAiRVJfVU5LTk9XTl9FWFRfTlNfUFJFRklYIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU1QT1JUU19BU19GSVJTVF9FTEVNID0KLSAgICAgICAgICJFUl9JTVBPUlRTX0FTX0ZJUlNUX0VMRU0iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTVBPUlRJTkdfSVRTRUxGID0gIkVSX0lNUE9SVElOR19JVFNFTEYiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YTUxTUEFDRV9JTExFR0FMX1ZBTCA9IkVSX1hNTFNQQUNFX0lMTEVHQUxfVkFMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJPQ0VTU1NUWUxFU0hFRVRfTk9UX1NVQ0NFU1NGVUwgPQotICAgICAgICAgIkVSX1BST0NFU1NTVFlMRVNIRUVUX05PVF9TVUNDRVNTRlVMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU0FYX0VYQ0VQVElPTiA9ICJFUl9TQVhfRVhDRVBUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWFNMVF9FUlJPUiA9ICJFUl9YU0xUX0VSUk9SIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ1VSUkVOQ1lfU0lHTl9JTExFR0FMPQotICAgICAgICAgIkVSX0NVUlJFTkNZX1NJR05fSUxMRUdBTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0RPQ1VNRU5UX0ZVTkNUSU9OX0lOVkFMSURfSU5fU1RZTEVTSEVFVF9ET00gPQotICAgICAgICAgIkVSX0RPQ1VNRU5UX0ZVTkNUSU9OX0lOVkFMSURfSU5fU1RZTEVTSEVFVF9ET00iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX1JFU09MVkVfUFJFRklYX09GX05PTl9QUkVGSVhfUkVTT0xWRVIgPQotICAgICAgICAgIkVSX0NBTlRfUkVTT0xWRV9QUkVGSVhfT0ZfTk9OX1BSRUZJWF9SRVNPTFZFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1JFRElSRUNUX0NPVUxETlRfR0VUX0ZJTEVOQU1FID0KLSAgICAgICAgICJFUl9SRURJUkVDVF9DT1VMRE5UX0dFVF9GSUxFTkFNRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9CVUlMRF9GT1JNQVRURVJMSVNURU5FUl9JTl9SRURJUkVDVCA9Ci0gICAgICAgICAiRVJfQ0FOTk9UX0JVSUxEX0ZPUk1BVFRFUkxJU1RFTkVSX0lOX1JFRElSRUNUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9QUkVGSVhfSU5fRVhDTFVERVJFU1VMVFBSRUZJWCA9Ci0gICAgICAgICAiRVJfSU5WQUxJRF9QUkVGSVhfSU5fRVhDTFVERVJFU1VMVFBSRUZJWCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01JU1NJTkdfTlNfVVJJID0gIkVSX01JU1NJTkdfTlNfVVJJIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTUlTU0lOR19BUkdfRk9SX09QVElPTiA9Ci0gICAgICAgICAiRVJfTUlTU0lOR19BUkdfRk9SX09QVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfT1BUSU9OID0gIkVSX0lOVkFMSURfT1BUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTUFMRk9STUVEX0ZPUk1BVF9TVFJJTkcgPQotICAgICAgICAgIkVSX01BTEZPUk1FRF9GT1JNQVRfU1RSSU5HIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU1RZTEVTSEVFVF9SRVFVSVJFU19WRVJTSU9OX0FUVFJJQiA9Ci0gICAgICAgICAiRVJfU1RZTEVTSEVFVF9SRVFVSVJFU19WRVJTSU9OX0FUVFJJQiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lMTEVHQUxfQVRUUklCVVRFX1ZBTFVFID0KLSAgICAgICAgICJFUl9JTExFR0FMX0FUVFJJQlVURV9WQUxVRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NIT09TRV9SRVFVSVJFU19XSEVOID0iRVJfQ0hPT1NFX1JFUVVJUkVTX1dIRU4iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19BUFBMWV9JTVBPUlRfSU5fRk9SX0VBQ0ggPQotICAgICAgICAgIkVSX05PX0FQUExZX0lNUE9SVF9JTl9GT1JfRUFDSCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfVVNFX0RUTV9GT1JfT1VUUFVUID0KLSAgICAgICAgICJFUl9DQU5UX1VTRV9EVE1fRk9SX09VVFBVVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfVVNFX0RUTV9GT1JfSU5QVVQgPQotICAgICAgICAgIkVSX0NBTlRfVVNFX0RUTV9GT1JfSU5QVVQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQUxMX1RPX0VYVF9GQUlMRUQgPSAiRVJfQ0FMTF9UT19FWFRfRkFJTEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJFRklYX01VU1RfUkVTT0xWRSA9ICJFUl9QUkVGSVhfTVVTVF9SRVNPTFZFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9VVEYxNl9TVVJST0dBVEUgPQotICAgICAgICAgIkVSX0lOVkFMSURfVVRGMTZfU1VSUk9HQVRFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWFNMQVRUUlNFVF9VU0VEX0lUU0VMRiA9Ci0gICAgICAgICAiRVJfWFNMQVRUUlNFVF9VU0VEX0lUU0VMRiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9NSVhfWEVSQ0VTRE9NID0iRVJfQ0FOTk9UX01JWF9YRVJDRVNET00iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9UT09fTUFOWV9MSVNURU5FUlMgPSAiRVJfVE9PX01BTllfTElTVEVORVJTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5fRUxFTVRFTVBMQVRFRUxFTV9SRUFET0JKRUNUID0KLSAgICAgICAgICJFUl9JTl9FTEVNVEVNUExBVEVFTEVNX1JFQURPQkpFQ1QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9EVVBMSUNBVEVfTkFNRURfVEVNUExBVEUgPQotICAgICAgICAgIkVSX0RVUExJQ0FURV9OQU1FRF9URU1QTEFURSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfS0VZX0NBTEwgPSAiRVJfSU5WQUxJRF9LRVlfQ0FMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1JFRkVSRU5DSU5HX0lUU0VMRiA9ICJFUl9SRUZFUkVOQ0lOR19JVFNFTEYiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTExFR0FMX0RPTVNPVVJDRV9JTlBVVCA9Ci0gICAgICAgICAiRVJfSUxMRUdBTF9ET01TT1VSQ0VfSU5QVVQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DTEFTU19OT1RfRk9VTkRfRk9SX09QVElPTiA9Ci0gICAgICAgICAiRVJfQ0xBU1NfTk9UX0ZPVU5EX0ZPUl9PUFRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SRVFVSVJFRF9FTEVNX05PVF9GT1VORCA9Ci0gICAgICAgICAiRVJfUkVRVUlSRURfRUxFTV9OT1RfRk9VTkQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlBVVF9DQU5OT1RfQkVfTlVMTCA9IkVSX0lOUFVUX0NBTk5PVF9CRV9OVUxMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVVJJX0NBTk5PVF9CRV9OVUxMID0gIkVSX1VSSV9DQU5OT1RfQkVfTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZJTEVfQ0FOTk9UX0JFX05VTEwgPSAiRVJfRklMRV9DQU5OT1RfQkVfTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NPVVJDRV9DQU5OT1RfQkVfTlVMTCA9Ci0gICAgICAgICAiRVJfU09VUkNFX0NBTk5PVF9CRV9OVUxMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX0lOSVRfQlNGTUdSID0gIkVSX0NBTk5PVF9JTklUX0JTRk1HUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9DTVBMX0VYVEVOU04gPSAiRVJfQ0FOTk9UX0NNUExfRVhURU5TTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9DUkVBVEVfRVhURU5TTiA9Ci0gICAgICAgICAiRVJfQ0FOTk9UX0NSRUFURV9FWFRFTlNOIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5TVEFOQ0VfTVRIRF9DQUxMX1JFUVVJUkVTID0KLSAgICAgICAgICJFUl9JTlNUQU5DRV9NVEhEX0NBTExfUkVRVUlSRVMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX0VMRU1FTlRfTkFNRSA9IkVSX0lOVkFMSURfRUxFTUVOVF9OQU1FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRUxFTUVOVF9OQU1FX01FVEhPRF9TVEFUSUMgPQotICAgICAgICAgIkVSX0VMRU1FTlRfTkFNRV9NRVRIT0RfU1RBVElDIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhURU5TSU9OX0ZVTkNfVU5LTk9XTiA9Ci0gICAgICAgICAiRVJfRVhURU5TSU9OX0ZVTkNfVU5LTk9XTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01PUkVfTUFUQ0hfQ09OU1RSVUNUT1IgPQotICAgICAgICAgIkVSX01PUkVfTUFUQ0hfQ09OU1RSVUNUT1IiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9NT1JFX01BVENIX01FVEhPRCA9ICJFUl9NT1JFX01BVENIX01FVEhPRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01PUkVfTUFUQ0hfRUxFTUVOVCA9ICJFUl9NT1JFX01BVENIX0VMRU1FTlQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX0NPTlRFWFRfUEFTU0VEID0KLSAgICAgICAgICJFUl9JTlZBTElEX0NPTlRFWFRfUEFTU0VEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUE9PTF9FWElTVFMgPSAiRVJfUE9PTF9FWElTVFMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19EUklWRVJfTkFNRSA9ICJFUl9OT19EUklWRVJfTkFNRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1VSTCA9ICJFUl9OT19VUkwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QT09MX1NJWkVfTEVTU1RIQU5fT05FID0KLSAgICAgICAgICJFUl9QT09MX1NJWkVfTEVTU1RIQU5fT05FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9EUklWRVIgPSAiRVJfSU5WQUxJRF9EUklWRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19TVFlMRVNIRUVUUk9PVCA9ICJFUl9OT19TVFlMRVNIRUVUUk9PVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lMTEVHQUxfWE1MU1BBQ0VfVkFMVUUgPQotICAgICAgICAgIkVSX0lMTEVHQUxfWE1MU1BBQ0VfVkFMVUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUk9DRVNTRlJPTU5PREVfRkFJTEVEID0KLSAgICAgICAgICJFUl9QUk9DRVNTRlJPTU5PREVfRkFJTEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUkVTT1VSQ0VfQ09VTERfTk9UX0xPQUQgPQotICAgICAgICAgIkVSX1JFU09VUkNFX0NPVUxEX05PVF9MT0FEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQlVGRkVSX1NJWkVfTEVTU1RIQU5fWkVSTyA9Ci0gICAgICAgICAiRVJfQlVGRkVSX1NJWkVfTEVTU1RIQU5fWkVSTyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1VOS05PV05fRVJST1JfQ0FMTElOR19FWFRFTlNJT04gPQotICAgICAgICAgIkVSX1VOS05PV05fRVJST1JfQ0FMTElOR19FWFRFTlNJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19OQU1FU1BBQ0VfREVDTCA9ICJFUl9OT19OQU1FU1BBQ0VfREVDTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VMRU1fQ09OVEVOVF9OT1RfQUxMT1dFRCA9Ci0gICAgICAgICAiRVJfRUxFTV9DT05URU5UX05PVF9BTExPV0VEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU1RZTEVTSEVFVF9ESVJFQ1RFRF9URVJNSU5BVElPTiA9Ci0gICAgICAgICAiRVJfU1RZTEVTSEVFVF9ESVJFQ1RFRF9URVJNSU5BVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX09ORV9PUl9UV08gPSAiRVJfT05FX09SX1RXTyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1RXT19PUl9USFJFRSA9ICJFUl9UV09fT1JfVEhSRUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRF9OT1RfTE9BRF9SRVNPVVJDRSA9Ci0gICAgICAgICAiRVJfQ09VTERfTk9UX0xPQURfUkVTT1VSQ0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfSU5JVF9ERUZBVUxUX1RFTVBMQVRFUyA9Ci0gICAgICAgICAiRVJfQ0FOTk9UX0lOSVRfREVGQVVMVF9URU1QTEFURVMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SRVNVTFRfTlVMTCA9ICJFUl9SRVNVTFRfTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1JFU1VMVF9DT1VMRF9OT1RfQkVfU0VUID0KLSAgICAgICAgICJFUl9SRVNVTFRfQ09VTERfTk9UX0JFX1NFVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX09VVFBVVF9TUEVDSUZJRUQgPSAiRVJfTk9fT1VUUFVUX1NQRUNJRklFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9UUkFOU0ZPUk1fVE9fUkVTVUxUX1RZUEUgPQotICAgICAgICAgIkVSX0NBTk5PVF9UUkFOU0ZPUk1fVE9fUkVTVUxUX1RZUEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfVFJBTlNGT1JNX1NPVVJDRV9UWVBFID0KLSAgICAgICAgICJFUl9DQU5OT1RfVFJBTlNGT1JNX1NPVVJDRV9UWVBFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTlVMTF9DT05URU5UX0hBTkRMRVIgPSJFUl9OVUxMX0NPTlRFTlRfSEFORExFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05VTExfRVJST1JfSEFORExFUiA9ICJFUl9OVUxMX0VSUk9SX0hBTkRMRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfQ0FMTF9QQVJTRSA9ICJFUl9DQU5OT1RfQ0FMTF9QQVJTRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1BBUkVOVF9GT1JfRklMVEVSID0iRVJfTk9fUEFSRU5UX0ZPUl9GSUxURVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19TVFlMRVNIRUVUX0lOX01FRElBID0KLSAgICAgICAgICJFUl9OT19TVFlMRVNIRUVUX0lOX01FRElBIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fU1RZTEVTSEVFVF9QSSA9ICJFUl9OT19TVFlMRVNIRUVUX1BJIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9UX1NVUFBPUlRFRCA9ICJFUl9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJPUEVSVFlfVkFMVUVfQk9PTEVBTiA9Ci0gICAgICAgICAiRVJfUFJPUEVSVFlfVkFMVUVfQk9PTEVBTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxEX05PVF9GSU5EX0VYVEVSTl9TQ1JJUFQgPQotICAgICAgICAgIkVSX0NPVUxEX05PVF9GSU5EX0VYVEVSTl9TQ1JJUFQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SRVNPVVJDRV9DT1VMRF9OT1RfRklORCA9Ci0gICAgICAgICAiRVJfUkVTT1VSQ0VfQ09VTERfTk9UX0ZJTkQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9PVVRQVVRfUFJPUEVSVFlfTk9UX1JFQ09HTklaRUQgPQotICAgICAgICAgIkVSX09VVFBVVF9QUk9QRVJUWV9OT1RfUkVDT0dOSVpFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZBSUxFRF9DUkVBVElOR19FTEVNTElUUlNMVCA9Ci0gICAgICAgICAiRVJfRkFJTEVEX0NSRUFUSU5HX0VMRU1MSVRSU0xUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVkFMVUVfU0hPVUxEX0JFX05VTUJFUiA9Ci0gICAgICAgICAiRVJfVkFMVUVfU0hPVUxEX0JFX05VTUJFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1ZBTFVFX1NIT1VMRF9FUVVBTCA9ICJFUl9WQUxVRV9TSE9VTERfRVFVQUwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GQUlMRURfQ0FMTElOR19NRVRIT0QgPQotICAgICAgICAgIkVSX0ZBSUxFRF9DQUxMSU5HX01FVEhPRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZBSUxFRF9DUkVBVElOR19FTEVNVE1QTCA9Ci0gICAgICAgICAiRVJfRkFJTEVEX0NSRUFUSU5HX0VMRU1UTVBMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0hBUlNfTk9UX0FMTE9XRUQgPSAiRVJfQ0hBUlNfTk9UX0FMTE9XRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9BVFRSX05PVF9BTExPV0VEID0gIkVSX0FUVFJfTk9UX0FMTE9XRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9CQURfVkFMVUUgPSAiRVJfQkFEX1ZBTFVFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQVRUUklCX1ZBTFVFX05PVF9GT1VORCA9Ci0gICAgICAgICAiRVJfQVRUUklCX1ZBTFVFX05PVF9GT1VORCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FUVFJJQl9WQUxVRV9OT1RfUkVDT0dOSVpFRCA9Ci0gICAgICAgICAiRVJfQVRUUklCX1ZBTFVFX05PVF9SRUNPR05JWkVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTlVMTF9VUklfTkFNRVNQQUNFID0gIkVSX05VTExfVVJJX05BTUVTUEFDRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05VTUJFUl9UT09fQklHID0gIkVSX05VTUJFUl9UT09fQklHIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgIEVSX0NBTk5PVF9GSU5EX1NBWDFfRFJJVkVSID0KLSAgICAgICAgICJFUl9DQU5OT1RfRklORF9TQVgxX0RSSVZFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nICBFUl9TQVgxX0RSSVZFUl9OT1RfTE9BREVEID0KLSAgICAgICAgICJFUl9TQVgxX0RSSVZFUl9OT1RfTE9BREVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgIEVSX1NBWDFfRFJJVkVSX05PVF9JTlNUQU5USUFURUQgPQotICAgICAgICAgIkVSX1NBWDFfRFJJVkVSX05PVF9JTlNUQU5USUFURUQiIDsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU0FYMV9EUklWRVJfTk9UX0lNUExFTUVOVF9QQVJTRVIgPQotICAgICAgICAgIkVSX1NBWDFfRFJJVkVSX05PVF9JTVBMRU1FTlRfUEFSU0VSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgIEVSX1BBUlNFUl9QUk9QRVJUWV9OT1RfU1BFQ0lGSUVEID0KLSAgICAgICAgICJFUl9QQVJTRVJfUFJPUEVSVFlfTk9UX1NQRUNJRklFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nICBFUl9QQVJTRVJfQVJHX0NBTk5PVF9CRV9OVUxMID0KLSAgICAgICAgICJFUl9QQVJTRVJfQVJHX0NBTk5PVF9CRV9OVUxMIiA7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nICBFUl9GRUFUVVJFID0gIkVSX0ZFQVRVUkUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUk9QRVJUWSA9ICJFUl9QUk9QRVJUWSIgOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OVUxMX0VOVElUWV9SRVNPTFZFUiA9IkVSX05VTExfRU5USVRZX1JFU09MVkVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgIEVSX05VTExfRFREX0hBTkRMRVIgPSAiRVJfTlVMTF9EVERfSEFORExFUiIgOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19EUklWRVJfTkFNRV9TUEVDSUZJRUQgPQotICAgICAgICAgIkVSX05PX0RSSVZFUl9OQU1FX1NQRUNJRklFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1VSTF9TUEVDSUZJRUQgPSAiRVJfTk9fVVJMX1NQRUNJRklFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BPT0xTSVpFX0xFU1NfVEhBTl9PTkUgPQotICAgICAgICAgIkVSX1BPT0xTSVpFX0xFU1NfVEhBTl9PTkUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX0RSSVZFUl9OQU1FID0gIkVSX0lOVkFMSURfRFJJVkVSX05BTUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FUlJPUkxJU1RFTkVSID0gIkVSX0VSUk9STElTVEVORVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9BU1NFUlRfTk9fVEVNUExBVEVfUEFSRU5UID0KLSAgICAgICAgICJFUl9BU1NFUlRfTk9fVEVNUExBVEVfUEFSRU5UIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQVNTRVJUX1JFRFVOREVOVF9FWFBSX0VMSU1JTkFUT1IgPQotICAgICAgICAgIkVSX0FTU0VSVF9SRURVTkRFTlRfRVhQUl9FTElNSU5BVE9SIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9UX0FMTE9XRURfSU5fUE9TSVRJT04gPQotICAgICAgICAgIkVSX05PVF9BTExPV0VEX0lOX1BPU0lUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9OV0hJVEVTUEFDRV9OT1RfQUxMT1dFRF9JTl9QT1NJVElPTiA9Ci0gICAgICAgICAiRVJfTk9OV0hJVEVTUEFDRV9OT1RfQUxMT1dFRF9JTl9QT1NJVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05BTUVTUEFDRV9DT05URVhUX05VTExfTkFNRVNQQUNFID0KLSAgICAgICAgICJFUl9OQU1FU1BBQ0VfQ09OVEVYVF9OVUxMX05BTUVTUEFDRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05BTUVTUEFDRV9DT05URVhUX05VTExfUFJFRklYID0KLSAgICAgICAgICJFUl9OQU1FU1BBQ0VfQ09OVEVYVF9OVUxMX1BSRUZJWCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hQQVRIX1JFU09MVkVSX05VTExfUU5BTUUgPQotICAgICAgICAgIkVSX1hQQVRIX1JFU09MVkVSX05VTExfUU5BTUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YUEFUSF9SRVNPTFZFUl9ORUdBVElWRV9BUklUWSA9Ci0gICAgICAgICAiRVJfWFBBVEhfUkVTT0xWRVJfTkVHQVRJVkVfQVJJVFkiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBJTlZBTElEX1RDSEFSID0gIklOVkFMSURfVENIQVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBJTlZBTElEX1FOQU1FID0gIklOVkFMSURfUU5BTUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBJTlZBTElEX0VOVU0gPSAiSU5WQUxJRF9FTlVNIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSU5WQUxJRF9OTVRPS0VOID0gIklOVkFMSURfTk1UT0tFTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIElOVkFMSURfTkNOQU1FID0gIklOVkFMSURfTkNOQU1FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSU5WQUxJRF9CT09MRUFOID0gIklOVkFMSURfQk9PTEVBTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIElOVkFMSURfTlVNQkVSID0gIklOVkFMSURfTlVNQkVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQVJHX0xJVEVSQUwgPSAiRVJfQVJHX0xJVEVSQUwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9EVVBMSUNBVEVfR0xPQkFMX1ZBUiA9IkVSX0RVUExJQ0FURV9HTE9CQUxfVkFSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRFVQTElDQVRFX1ZBUiA9ICJFUl9EVVBMSUNBVEVfVkFSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVEVNUExBVEVfTkFNRV9NQVRDSCA9ICJFUl9URU1QTEFURV9OQU1FX01BVENIIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9QUkVGSVggPSAiRVJfSU5WQUxJRF9QUkVGSVgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19BVFRSSUJfU0VUID0gIkVSX05PX0FUVFJJQl9TRVQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GVU5DVElPTl9OT1RfRk9VTkQgPQotICAgICAgICAgIkVSX0ZVTkNUSU9OX05PVF9GT1VORCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfSEFWRV9DT05URU5UX0FORF9TRUxFQ1QgPQotICAgICAiRVJfQ0FOVF9IQVZFX0NPTlRFTlRfQU5EX1NFTEVDVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfU0VUX1BBUkFNX1ZBTFVFID0gIkVSX0lOVkFMSURfU0VUX1BBUkFNX1ZBTFVFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU0VUX0ZFQVRVUkVfTlVMTF9OQU1FID0KLSAgICAgICAgIkVSX1NFVF9GRUFUVVJFX05VTExfTkFNRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0dFVF9GRUFUVVJFX05VTExfTkFNRSA9Ci0gICAgICAgICJFUl9HRVRfRkVBVFVSRV9OVUxMX05BTUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTlNVUFBPUlRFRF9GRUFUVVJFID0KLSAgICAgICAgIkVSX1VOU1VQUE9SVEVEX0ZFQVRVUkUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FWFRFTlNJT05fRUxFTUVOVF9OT1RfQUxMT1dFRF9JTl9TRUNVUkVfUFJPQ0VTU0lORyA9Ci0gICAgICAgICJFUl9FWFRFTlNJT05fRUxFTUVOVF9OT1RfQUxMT1dFRF9JTl9TRUNVUkVfUFJPQ0VTU0lORyI7Ci0KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfRk9VTkRfQ1VSTFlCUkFDRSA9ICJXR19GT1VORF9DVVJMWUJSQUNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfQ09VTlRfQVRUUklCX01BVENIRVNfTk9fQU5DRVNUT1IgPQotICAgICAgICAgIldHX0NPVU5UX0FUVFJJQl9NQVRDSEVTX05PX0FOQ0VTVE9SIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfRVhQUl9BVFRSSUJfQ0hBTkdFRF9UT19TRUxFQ1QgPQotICAgICAgICAgIldHX0VYUFJfQVRUUklCX0NIQU5HRURfVE9fU0VMRUNUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfTk9fTE9DQUxFX0lOX0ZPUk1BVE5VTUJFUiA9Ci0gICAgICAgICAiV0dfTk9fTE9DQUxFX0lOX0ZPUk1BVE5VTUJFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0xPQ0FMRV9OT1RfRk9VTkQgPSAiV0dfTE9DQUxFX05PVF9GT1VORCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0NBTk5PVF9NQUtFX1VSTF9GUk9NID0iV0dfQ0FOTk9UX01BS0VfVVJMX0ZST00iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19DQU5OT1RfTE9BRF9SRVFVRVNURURfRE9DID0KLSAgICAgICAgICJXR19DQU5OT1RfTE9BRF9SRVFVRVNURURfRE9DIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfQ0FOTk9UX0ZJTkRfQ09MTEFUT1IgPSJXR19DQU5OT1RfRklORF9DT0xMQVRPUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0ZVTkNUSU9OU19TSE9VTERfVVNFX1VSTCA9Ci0gICAgICAgICAiV0dfRlVOQ1RJT05TX1NIT1VMRF9VU0VfVVJMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfRU5DT0RJTkdfTk9UX1NVUFBPUlRFRF9VU0lOR19VVEY4ID0KLSAgICAgICAgICJXR19FTkNPRElOR19OT1RfU1VQUE9SVEVEX1VTSU5HX1VURjgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19FTkNPRElOR19OT1RfU1VQUE9SVEVEX1VTSU5HX0pBVkEgPQotICAgICAgICAgIldHX0VOQ09ESU5HX05PVF9TVVBQT1JURURfVVNJTkdfSkFWQSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX1NQRUNJRklDSVRZX0NPTkZMSUNUUyA9Ci0gICAgICAgICAiV0dfU1BFQ0lGSUNJVFlfQ09ORkxJQ1RTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfUEFSU0lOR19BTkRfUFJFUEFSSU5HID0KLSAgICAgICAgICJXR19QQVJTSU5HX0FORF9QUkVQQVJJTkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19BVFRSX1RFTVBMQVRFID0gIldHX0FUVFJfVEVNUExBVEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19DT05GTElDVF9CRVRXRUVOX1hTTFNUUklQU1BBQ0VfQU5EX1hTTFBSRVNFUlZFU1BBQ0UgPSAiV0dfQ09ORkxJQ1RfQkVUV0VFTl9YU0xTVFJJUFNQQUNFX0FORF9YU0xQUkVTRVJWRVNQIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfQVRUUklCX05PVF9IQU5ETEVEID0gIldHX0FUVFJJQl9OT1RfSEFORExFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX05PX0RFQ0lNQUxGT1JNQVRfREVDTEFSQVRJT04gPQotICAgICAgICAgIldHX05PX0RFQ0lNQUxGT1JNQVRfREVDTEFSQVRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19PTERfWFNMVF9OUyA9ICJXR19PTERfWFNMVF9OUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX09ORV9ERUZBVUxUX1hTTERFQ0lNQUxGT1JNQVRfQUxMT1dFRCA9Ci0gICAgICAgICAiV0dfT05FX0RFRkFVTFRfWFNMREVDSU1BTEZPUk1BVF9BTExPV0VEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfWFNMREVDSU1BTEZPUk1BVF9OQU1FU19NVVNUX0JFX1VOSVFVRSA9Ci0gICAgICAgICAiV0dfWFNMREVDSU1BTEZPUk1BVF9OQU1FU19NVVNUX0JFX1VOSVFVRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0lMTEVHQUxfQVRUUklCVVRFID0gIldHX0lMTEVHQUxfQVRUUklCVVRFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfQ09VTERfTk9UX1JFU09MVkVfUFJFRklYID0KLSAgICAgICAgICJXR19DT1VMRF9OT1RfUkVTT0xWRV9QUkVGSVgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19TVFlMRVNIRUVUX1JFUVVJUkVTX1ZFUlNJT05fQVRUUklCID0KLSAgICAgICAgICJXR19TVFlMRVNIRUVUX1JFUVVJUkVTX1ZFUlNJT05fQVRUUklCIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfSUxMRUdBTF9BVFRSSUJVVEVfTkFNRSA9Ci0gICAgICAgICAiV0dfSUxMRUdBTF9BVFRSSUJVVEVfTkFNRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0lMTEVHQUxfQVRUUklCVVRFX1ZBTFVFID0KLSAgICAgICAgICJXR19JTExFR0FMX0FUVFJJQlVURV9WQUxVRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0VNUFRZX1NFQ09ORF9BUkcgPSAiV0dfRU1QVFlfU0VDT05EX0FSRyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX1BST0NFU1NJTkdJTlNUUlVDVElPTl9OQU1FX0NBTlRfQkVfWE1MID0KLSAgICAgICAgICJXR19QUk9DRVNTSU5HSU5TVFJVQ1RJT05fTkFNRV9DQU5UX0JFX1hNTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX1BST0NFU1NJTkdJTlNUUlVDVElPTl9OT1RWQUxJRF9OQ05BTUUgPQotICAgICAgICAgIldHX1BST0NFU1NJTkdJTlNUUlVDVElPTl9OT1RWQUxJRF9OQ05BTUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19JTExFR0FMX0FUVFJJQlVURV9QT1NJVElPTiA9Ci0gICAgICAgICAiV0dfSUxMRUdBTF9BVFRSSUJVVEVfUE9TSVRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIgPQotICAgICAgICAgIk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiI7Ci0KLSAgLyoKLSAgICogTm93IGZpbGwgaW4gdGhlIG1lc3NhZ2UgdGV4dC4KLSAgICogVGhlbiBmaWxsIGluIHRoZSBtZXNzYWdlIHRleHQgZm9yIHRoYXQgbWVzc2FnZSBjb2RlIGluIHRoZQotICAgKiBhcnJheS4gVXNlIHRoZSBuZXcgZXJyb3IgY29kZSBhcyB0aGUgaW5kZXggaW50byB0aGUgYXJyYXkuCi0gICAqLwotCi0gIC8vIEVycm9yIG1lc3NhZ2VzLi4uCi0KLSAgLyoqIEdldCB0aGUgbG9va3VwIHRhYmxlIGZvciBlcnJvciBtZXNzYWdlcy4KLSAgICAqCi0gICAgKiBAcmV0dXJuIFRoZSBtZXNzYWdlIGxvb2t1cCB0YWJsZS4KLSAgICAqLwotICBwdWJsaWMgT2JqZWN0W11bXSBnZXRDb250ZW50cygpCi0gIHsKLSAgICAgIHJldHVybiBuZXcgT2JqZWN0W11bXSB7Ci0KLSAgLyoqIEVycm9yIG1lc3NhZ2UgSUQgdGhhdCBoYXMgYSBudWxsIG1lc3NhZ2UsIGJ1dCB0YWtlcyBpbiBhIHNpbmdsZSBvYmplY3QuICAgICovCi0gIHsiRVIwMDAwIiAsICJ7MH0iIH0sCi0KLSAgICB7IEVSX05PX0NVUkxZQlJBQ0UsCi0gICAgICAiXHU5MzJGXHU4QUE0OiBcdTg4NjhcdTc5M0FcdTVGMEZcdTRFMkRcdTRFMERcdTUzRUZcdTY3MDkgJ3snIn0sCi0KLSAgICB7IEVSX0lMTEVHQUxfQVRUUklCVVRFICwKLSAgICAgInswfSBcdTUxNzdcdTY3MDlcdTcxMjFcdTY1NDhcdTVDNkNcdTYwMjc6IHsxfSJ9LAotCi0gIHtFUl9OVUxMX1NPVVJDRU5PREVfQVBQTFlJTVBPUlRTICwKLSAgICAgICJzb3VyY2VOb2RlIFx1NTcyOCB4c2w6YXBwbHktaW1wb3J0cyBcdTRFMkRcdTY2MkZcdTdBN0FcdTUwM0NcdUZGMDEifSwKLQotICB7RVJfQ0FOTk9UX0FERCwKLSAgICAgICJcdTcxMjFcdTZDRDVcdTY1QjBcdTU4OUUgezB9IFx1ODFGMyB7MX0ifSwKLQotICAgIHsgRVJfTlVMTF9TT1VSQ0VOT0RFX0hBTkRMRUFQUExZVEVNUExBVEVTLAotICAgICAgInNvdXJjZU5vZGUgXHU1NzI4IGhhbmRsZUFwcGx5VGVtcGxhdGVzSW5zdHJ1Y3Rpb24gXHU0RTJEXHU2NjJGXHU3QTdBXHU1MDNDXHVGRjAxIn0sCi0KLSAgICB7IEVSX05PX05BTUVfQVRUUklCLAotICAgICAiezB9IFx1NUZDNVx1OTgwOFx1NjcwOVx1NTQwRFx1N0EzMVx1NUM2Q1x1NjAyN1x1MzAwMiJ9LAotCi0gICAge0VSX1RFTVBMQVRFX05PVF9GT1VORCwKLSAgICAgIlx1NjI3RVx1NEUwRFx1NTIzMFx1NEUwQlx1NTIxN1x1NTQwRFx1N0EzMVx1NzY4NFx1NkEyM1x1Njc3RjogezB9In0sCi0KLSAgICB7RVJfQ0FOVF9SRVNPTFZFX05BTUVfQVZULAotICAgICAgIlx1NzEyMVx1NkNENVx1ODlFM1x1Njc5MCB4c2w6Y2FsbC10ZW1wbGF0ZSBcdTRFMkRcdTc2ODRcdTU0MERcdTdBMzEgQVZUXHUzMDAyIn0sCi0KLSAgICB7RVJfUkVRVUlSRVNfQVRUUklCLAotICAgICAiezB9IFx1OTcwMFx1ODk4MVx1NUM2Q1x1NjAyNzogezF9In0sCi0KLSAgICB7IEVSX01VU1RfSEFWRV9URVNUX0FUVFJJQiwKLSAgICAgICJ7MH0gXHU1RkM1XHU5ODA4XHU2NzA5ICcndGVzdCcnIFx1NUM2Q1x1NjAyN1x1MzAwMiJ9LAotCi0gICAge0VSX0JBRF9WQUxfT05fTEVWRUxfQVRUUklCLAotICAgICAgIlx1OTMyRlx1OEFBNFx1NzY4NFx1NTAzQ1x1NEY0RFx1NjVCQ1x1NUM2NFx1NkIyMVx1NUM2Q1x1NjAyNzogezB9In0sCi0KLSAgICB7RVJfUFJPQ0VTU0lOR0lOU1RSVUNUSU9OX05BTUVfQ0FOVF9CRV9YTUwsCi0gICAgICAicHJvY2Vzc2luZy1pbnN0cnVjdGlvbiBcdTU0MERcdTdBMzFcdTRFMERcdTUzRUZcdTcwQkEgJ3htbCcifSwKLQotICAgIHsgRVJfUFJPQ0VTU0lOR0lOU1RSVUNUSU9OX05PVFZBTElEX05DTkFNRSwKLSAgICAgICJwcm9jZXNzaW5nLWluc3RydWN0aW9uIFx1NTQwRFx1N0EzMVx1NUZDNVx1OTgwOFx1NjYyRlx1NjcwOVx1NjU0OFx1NzY4NCBOQ05hbWU6IHswfSJ9LAotCi0gICAgeyBFUl9ORUVEX01BVENIX0FUVFJJQiwKLSAgICAgICJ7MH0gXHU4MkU1XHU1MTc3XHU2NzA5XHU2QTIxXHU1RjBGXHVGRjBDXHU1MjQ3XHU1RkM1XHU5ODA4XHU2NzA5XHU5MTREXHU1QzBEXHU1QzZDXHU2MDI3XHUzMDAyIn0sCi0KLSAgICB7IEVSX05FRURfTkFNRV9PUl9NQVRDSF9BVFRSSUIsCi0gICAgICAiezB9IFx1OTcwMFx1ODk4MVx1NTQwRFx1N0EzMVx1NjIxNlx1OTE0RFx1NUMwRFx1NUM2Q1x1NjAyN1x1MzAwMiJ9LAotCi0gICAge0VSX0NBTlRfUkVTT0xWRV9OU1BSRUZJWCwKLSAgICAgICJcdTcxMjFcdTZDRDVcdTg5RTNcdTY3OTBcdTU0N0RcdTU0MERcdTdBN0FcdTk1OTNcdTUyNERcdTdGNkVcdTc4QkM6IHswfSJ9LAotCi0gICAgeyBFUl9JTExFR0FMX1ZBTFVFLAotICAgICAieG1sOnNwYWNlIFx1NTE3N1x1NjcwOVx1NzEyMVx1NjU0OFx1NTAzQzogezB9In0sCi0KLSAgICB7IEVSX05PX09XTkVSRE9DLAotICAgICAgIlx1NUI1MFx1OTgwNVx1N0JDMFx1OUVERVx1NEUwRFx1NTE3N1x1NjcwOVx1NjRDMVx1NjcwOVx1ODAwNVx1NjU4N1x1NEVGNlx1RkYwMSJ9LAotCi0gICAgeyBFUl9FTEVNVEVNUExBVEVFTEVNX0VSUiwKLSAgICAgIkVsZW1UZW1wbGF0ZUVsZW1lbnQgXHU5MzJGXHU4QUE0OiB7MH0ifSwKLQotICAgIHsgRVJfTlVMTF9DSElMRCwKLSAgICAgIlx1NTYxN1x1OEE2Nlx1NjVCMFx1NTg5RVx1N0E3QVx1NTAzQ1x1NUI1MFx1OTgwNVx1RkYwMSJ9LAotCi0gICAgeyBFUl9ORUVEX1NFTEVDVF9BVFRSSUIsCi0gICAgICJ7MH0gXHU5NzAwXHU4OTgxXHU5MDc4XHU1M0Q2XHU1QzZDXHU2MDI3XHUzMDAyIn0sCi0KLSAgICB7IEVSX05FRURfVEVTVF9BVFRSSUIgLAotICAgICAgInhzbDp3aGVuIFx1NUZDNVx1OTgwOFx1NTE3N1x1NjcwOSAndGVzdCcgXHU1QzZDXHU2MDI3XHUzMDAyIn0sCi0KLSAgICB7IEVSX05FRURfTkFNRV9BVFRSSUIsCi0gICAgICAieHNsOndpdGgtcGFyYW0gXHU1RkM1XHU5ODA4XHU1MTc3XHU2NzA5ICduYW1lJyBcdTVDNkNcdTYwMjdcdTMwMDIifSwKLQotICAgIHsgRVJfTk9fQ09OVEVYVF9PV05FUkRPQywKLSAgICAgICJcdTc2RjhcdTk1RENcdThDQzdcdThBMEFcdTc0QjBcdTU4ODNcdTRFMERcdTUxNzdcdTY3MDlcdTY0QzFcdTY3MDlcdTgwMDVcdTY1ODdcdTRFRjZcdUZGMDEifSwKLQotICAgIHtFUl9DT1VMRF9OT1RfQ1JFQVRFX1hNTF9QUk9DX0xJQUlTT04sCi0gICAgICAiXHU3MTIxXHU2Q0Q1XHU1RUZBXHU3QUNCIFhNTCBUcmFuc2Zvcm1lckZhY3RvcnkgTGlhaXNvbjogezB9In0sCi0KLSAgICB7RVJfUFJPQ0VTU19OT1RfU1VDQ0VTU0ZVTCwKLSAgICAgICJYYWxhbjogXHU4NjU1XHU3NDA2XHU0RjVDXHU2OTZEXHU1OTMxXHU2NTU3XHUzMDAyIn0sCi0KLSAgICB7IEVSX05PVF9TVUNDRVNTRlVMLAotICAgICAiWGFsYW46IFx1NTkzMVx1NjU1N1x1RkYwMSJ9LAotCi0gICAgeyBFUl9FTkNPRElOR19OT1RfU1VQUE9SVEVELAotICAgICAiXHU0RTBEXHU2NTJGXHU2M0Y0XHU3REU4XHU3OEJDOiB7MH0ifSwKLQotICAgIHtFUl9DT1VMRF9OT1RfQ1JFQVRFX1RSQUNFTElTVEVORVIsCi0gICAgICAiXHU3MTIxXHU2Q0Q1XHU1RUZBXHU3QUNCIFRyYWNlTGlzdGVuZXI6IHswfSJ9LAotCi0gICAge0VSX0tFWV9SRVFVSVJFU19OQU1FX0FUVFJJQiwKLSAgICAgICJ4c2w6a2V5IFx1OTcwMFx1ODk4MSAnbmFtZScgXHU1QzZDXHU2MDI3XHVGRjAxIn0sCi0KLSAgICB7IEVSX0tFWV9SRVFVSVJFU19NQVRDSF9BVFRSSUIsCi0gICAgICAieHNsOmtleSBcdTk3MDBcdTg5ODEgJ21hdGNoJyBcdTVDNkNcdTYwMjdcdUZGMDEifSwKLQotICAgIHsgRVJfS0VZX1JFUVVJUkVTX1VTRV9BVFRSSUIsCi0gICAgICAieHNsOmtleSBcdTk3MDBcdTg5ODEgJ3VzZScgXHU1QzZDXHU2MDI3XHVGRjAxIn0sCi0KLSAgICB7IEVSX1JFUVVJUkVTX0VMRU1FTlRTX0FUVFJJQiwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIHswfSBcdTk3MDBcdTg5ODEgJydlbGVtZW50cycnIFx1NUM2Q1x1NjAyN1x1RkYwMSJ9LAotCi0gICAgeyBFUl9NSVNTSU5HX1BSRUZJWF9BVFRSSUIsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSBcdTkwN0FcdTZGMEYgezB9IFx1NUM2Q1x1NjAyNyAnJ3ByZWZpeCcnIn0sCi0KLSAgICB7IEVSX0JBRF9TVFlMRVNIRUVUX1VSTCwKLSAgICAgIlx1NkEyM1x1NUYwRlx1ODg2OCBVUkwgXHU5MzJGXHU4QUE0OiB7MH0ifSwKLQotICAgIHsgRVJfRklMRV9OT1RfRk9VTkQsCi0gICAgICJcdTYyN0VcdTRFMERcdTUyMzBcdTZBMjNcdTVGMEZcdTg4NjhcdTZBOTRcdTY4NDg6IHswfSJ9LAotCi0gICAgeyBFUl9JT0VYQ0VQVElPTiwKLSAgICAgICJcdTZBMjNcdTVGMEZcdTg4NjhcdTZBOTRcdTY4NDhcdTc2N0NcdTc1MUYgSU8gXHU3NTcwXHU1RTM4XHU3MkMwXHU2Q0MxOiB7MH0ifSwKLQotICAgIHsgRVJfTk9fSFJFRl9BVFRSSUIsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSBcdTYyN0VcdTRFMERcdTUyMzAgezB9IFx1NzY4NCBocmVmIFx1NUM2Q1x1NjAyNyJ9LAotCi0gICAgeyBFUl9TVFlMRVNIRUVUX0lOQ0xVREVTX0lUU0VMRiwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIHswfSBcdTc2RjRcdTYzQTVcdTYyMTZcdTk1OTNcdTYzQTVcdTU3MzBcdTUzMDVcdTU0MkJcdTY3MkNcdThFQUJcdUZGMDEifSwKLQotICAgIHsgRVJfUFJPQ0VTU0lOQ0xVREVfRVJST1IsCi0gICAgICAiU3R5bGVzaGVldEhhbmRsZXIucHJvY2Vzc0luY2x1ZGUgXHU5MzJGXHU4QUE0XHVGRjBDezB9In0sCi0KLSAgICB7IEVSX01JU1NJTkdfTEFOR19BVFRSSUIsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSBcdTkwN0FcdTZGMEYgezB9IFx1NUM2Q1x1NjAyNyAnJ2xhbmcnJyJ9LAotCi0gICAgeyBFUl9NSVNTSU5HX0NPTlRBSU5FUl9FTEVNRU5UX0NPTVBPTkVOVCwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIHswfSBcdTUxNDNcdTdEMjBcdTc2ODRcdTRGNERcdTdGNkVcdTkzMkZcdThBQTRcdUZGMUZcdTkwN0FcdTZGMEZcdTVCQjlcdTU2NjhcdTUxNDNcdTdEMjAgJydjb21wb25lbnQnJyJ9LAotCi0gICAgeyBFUl9DQU5fT05MWV9PVVRQVVRfVE9fRUxFTUVOVCwKLSAgICAgICJcdTUzRUFcdTgwRkRcdThGMzhcdTUxRkFcdTgxRjMgRWxlbWVudFx1MzAwMURvY3VtZW50RnJhZ21lbnRcdTMwMDFEb2N1bWVudCBcdTYyMTYgUHJpbnRXcml0ZXJcdTMwMDIifSwKLQotICAgIHsgRVJfUFJPQ0VTU19FUlJPUiwKLSAgICAgIlN0eWxlc2hlZXRSb290LnByb2Nlc3MgXHU5MzJGXHU4QUE0In0sCi0KLSAgICB7IEVSX1VOSU1QTE5PREVfRVJST1IsCi0gICAgICJVbkltcGxOb2RlIFx1OTMyRlx1OEFBNDogezB9In0sCi0KLSAgICB7IEVSX05PX1NFTEVDVF9FWFBSRVNTSU9OLAotICAgICAgIlx1OTMyRlx1OEFBNFx1RkYwMVx1NjI3RVx1NEUwRFx1NTIzMCB4cGF0aCBcdTkwNzhcdTUzRDZcdTg4NjhcdTc5M0FcdTVGMEYgKC1zZWxlY3QpXHUzMDAyIn0sCi0KLSAgICB7IEVSX0NBTk5PVF9TRVJJQUxJWkVfWFNMUFJPQ0VTU09SLAotICAgICAgIlx1NzEyMVx1NkNENVx1NUU4Rlx1NTIxN1x1NTMxNiBYU0xQcm9jZXNzb3JcdUZGMDEifSwKLQotICAgIHsgRVJfTk9fSU5QVVRfU1RZTEVTSEVFVCwKLSAgICAgICJcdTY3MkFcdTYzMDdcdTVCOUFcdTZBMjNcdTVGMEZcdTg4NjhcdThGMzhcdTUxNjVcdUZGMDEifSwKLQotICAgIHsgRVJfRkFJTEVEX1BST0NFU1NfU1RZTEVTSEVFVCwKLSAgICAgICJcdTcxMjFcdTZDRDVcdTg2NTVcdTc0MDZcdTZBMjNcdTVGMEZcdTg4NjhcdUZGMDEifSwKLQotICAgIHsgRVJfQ09VTEROVF9QQVJTRV9ET0MsCi0gICAgICJcdTcxMjFcdTZDRDVcdTUyNTZcdTY3OTAgezB9IFx1NjU4N1x1NEVGNlx1RkYwMSJ9LAotCi0gICAgeyBFUl9DT1VMRE5UX0ZJTkRfRlJBR01FTlQsCi0gICAgICJcdTYyN0VcdTRFMERcdTUyMzBcdTcyNDdcdTZCQjU6IHswfSJ9LAotCi0gICAgeyBFUl9OT0RFX05PVF9FTEVNRU5ULAotICAgICAgIlx1NzI0N1x1NkJCNSBJRCBcdTYzMDdcdTU0MTFcdTc2ODRcdTdCQzBcdTlFREVcdTRFMERcdTY2MkZcdTUxNDNcdTdEMjA6IHswfSJ9LAotCi0gICAgeyBFUl9GT1JFQUNIX05FRURfTUFUQ0hfT1JfTkFNRV9BVFRSSUIsCi0gICAgICAiZm9yLWVhY2ggXHU1RkM1XHU5ODA4XHU2NzA5XHU5MTREXHU1QzBEXHU2MjE2XHU1NDBEXHU3QTMxXHU1QzZDXHU2MDI3In0sCi0KLSAgICB7IEVSX1RFTVBMQVRFU19ORUVEX01BVENIX09SX05BTUVfQVRUUklCLAotICAgICAgIlx1NkEyM1x1Njc3Rlx1NUZDNVx1OTgwOFx1NjcwOVx1OTE0RFx1NUMwRFx1NjIxNlx1NTQwRFx1N0EzMVx1NUM2Q1x1NjAyNyJ9LAotCi0gICAgeyBFUl9OT19DTE9ORV9PRl9ET0NVTUVOVF9GUkFHLAotICAgICAgIlx1NkM5Mlx1NjcwOVx1NjU4N1x1NEVGNlx1NzI0N1x1NkJCNVx1NzY4NFx1ODkwN1x1ODhGRFx1RkYwMSJ9LAotCi0gICAgeyBFUl9DQU5UX0NSRUFURV9JVEVNLAotICAgICAgIlx1NzEyMVx1NkNENVx1NTcyOFx1N0Q1MFx1Njc5Q1x1NkEzOVx1NzJDMFx1N0Q1MFx1NjlDQlx1NEUyRFx1NUVGQVx1N0FDQlx1OTgwNVx1NzZFRTogezB9In0sCi0KLSAgICB7IEVSX1hNTFNQQUNFX0lMTEVHQUxfVkFMVUUsCi0gICAgICAiXHU0Rjg2XHU2RTkwIFhNTCBcdTRFMkRcdTc2ODQgeG1sOnNwYWNlIFx1NTE3N1x1NjcwOVx1NzEyMVx1NjU0OFx1NTAzQzogezB9In0sCi0KLSAgICB7IEVSX05PX1hTTEtFWV9ERUNMQVJBVElPTiwKLSAgICAgICJ7MH0gXHU2QzkyXHU2NzA5IHhzbDprZXkgXHU1QkEzXHU1NDRBXHVGRjAxIn0sCi0KLSAgICB7IEVSX0NBTlRfQ1JFQVRFX1VSTCwKLSAgICAgIlx1OTMyRlx1OEFBNFx1RkYwMVx1NzEyMVx1NkNENVx1NzBCQSB7MH0gXHU1RUZBXHU3QUNCIHVybCJ9LAotCi0gICAgeyBFUl9YU0xGVU5DVElPTlNfVU5TVVBQT1JURUQsCi0gICAgICJcdTRFMERcdTY1MkZcdTYzRjQgeHNsOmZ1bmN0aW9ucyJ9LAotCi0gICAgeyBFUl9QUk9DRVNTT1JfRVJST1IsCi0gICAgICJYU0xUIFRyYW5zZm9ybWVyRmFjdG9yeSBcdTkzMkZcdThBQTQifSwKLQotICAgIHsgRVJfTk9UX0FMTE9XRURfSU5TSURFX1NUWUxFU0hFRVQsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSBcdTZBMjNcdTVGMEZcdTg4NjhcdTUxNjdcdTRFMERcdTUxNDFcdThBMzEgezB9XHVGRjAxIn0sCi0KLSAgICB7IEVSX1JFU1VMVE5TX05PVF9TVVBQT1JURUQsCi0gICAgICAiXHU0RTBEXHU1MThEXHU2NTJGXHU2M0Y0IHJlc3VsdC1uc1x1RkYwMVx1OEFDQlx1NjUzOVx1NzUyOCB4c2w6b3V0cHV0XHUzMDAyIn0sCi0KLSAgICB7IEVSX0RFRkFVTFRTUEFDRV9OT1RfU1VQUE9SVEVELAotICAgICAgIlx1NEUwRFx1NTE4RFx1NjUyRlx1NjNGNCBkZWZhdWx0LXNwYWNlXHVGRjAxXHU4QUNCXHU2NTM5XHU3NTI4IHhzbDpzdHJpcC1zcGFjZSBcdTYyMTYgeHNsOnByZXNlcnZlLXNwYWNlXHUzMDAyIn0sCi0KLSAgICB7IEVSX0lOREVOVFJFU1VMVF9OT1RfU1VQUE9SVEVELAotICAgICAgIlx1NEUwRFx1NTE4RFx1NjUyRlx1NjNGNCBpbmRlbnQtcmVzdWx0XHVGRjAxXHU4QUNCXHU2NTM5XHU3NTI4IHhzbDpvdXRwdXRcdTMwMDIifSwKLQotICAgIHsgRVJfSUxMRUdBTF9BVFRSSUIsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSB7MH0gXHU1MTc3XHU2NzA5XHU3MTIxXHU2NTQ4XHU1QzZDXHU2MDI3OiB7MX0ifSwKLQotICAgIHsgRVJfVU5LTk9XTl9YU0xfRUxFTSwKLSAgICAgIlx1NEUwRFx1NjYwRVx1NzY4NCBYU0wgXHU1MTQzXHU3RDIwOiB7MH0ifSwKLQotICAgIHsgRVJfQkFEX1hTTFNPUlRfVVNFLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgeHNsOnNvcnQgXHU1M0VBXHU4MEZEXHU4MjA3IHhzbDphcHBseS10ZW1wbGF0ZXMgXHU2MjE2IHhzbDpmb3ItZWFjaCBcdTRFMDBcdThENzdcdTRGN0ZcdTc1MjhcdTMwMDIifSwKLQotICAgIHsgRVJfTUlTUExBQ0VEX1hTTFdIRU4sCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSB4c2w6d2hlbiBcdTRGNERcdTdGNkVcdTkzMkZcdThBQTRcdUZGMDEifSwKLQotICAgIHsgRVJfWFNMV0hFTl9OT1RfUEFSRU5URURfQllfWFNMQ0hPT1NFLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgeHNsOndoZW4gXHU3Njg0XHU3MjM2XHU5ODA1XHU0RTBEXHU2NjJGIHhzbDpjaG9vc2VcdUZGMDEifSwKLQotICAgIHsgRVJfTUlTUExBQ0VEX1hTTE9USEVSV0lTRSwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIHhzbDpvdGhlcndpc2UgXHU0RjREXHU3RjZFXHU5MzJGXHU4QUE0XHVGRjAxIn0sCi0KLSAgICB7IEVSX1hTTE9USEVSV0lTRV9OT1RfUEFSRU5URURfQllfWFNMQ0hPT1NFLAotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgeHNsOm90aGVyd2lzZSBcdTc2ODRcdTcyMzZcdTk4MDVcdTRFMERcdTY2MkYgeHNsOmNob29zZVx1RkYwMSJ9LAotCi0gICAgeyBFUl9OT1RfQUxMT1dFRF9JTlNJREVfVEVNUExBVEUsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSBcdTZBMjNcdTY3N0ZcdTUxNjdcdTRFMERcdTUxNDFcdThBMzEgezB9XHVGRjAxIn0sCi0KLSAgICB7IEVSX1VOS05PV05fRVhUX05TX1BSRUZJWCwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIFx1NEUwRFx1NjYwRVx1NzY4NCB7MH0gXHU2NEY0XHU1MTQ1XHU1OTU3XHU0RUY2XHU1NDdEXHU1NDBEXHU3QTdBXHU5NTkzXHU1MjREXHU3RjZFXHU3OEJDIHsxfSJ9LAotCi0gICAgeyBFUl9JTVBPUlRTX0FTX0ZJUlNUX0VMRU0sCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSBcdTUzMkZcdTUxNjVcdTUzRUFcdTgwRkRcdTc2N0NcdTc1MUZcdTY1QkNcdTZBMjNcdTVGMEZcdTg4NjhcdTRFMkRcdTc2ODRcdTdCMkNcdTRFMDBcdTUwMEJcdTUxNDNcdTdEMjBcdUZGMDEifSwKLQotICAgIHsgRVJfSU1QT1JUSU5HX0lUU0VMRiwKLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIHswfSBcdTc2RjRcdTYzQTVcdTYyMTZcdTk1OTNcdTYzQTVcdTU3MzBcdTUzMkZcdTUxNjVcdTY3MkNcdThFQUJcdUZGMDEifSwKLQotICAgIHsgRVJfWE1MU1BBQ0VfSUxMRUdBTF9WQUwsCi0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSB4bWw6c3BhY2UgXHU1MTc3XHU2NzA5XHU3MTIxXHU2NTQ4XHU1MDNDOiB7MH0ifSwKLQotICAgIHsgRVJfUFJPQ0VTU1NUWUxFU0hFRVRfTk9UX1NVQ0NFU1NGVUwsCi0gICAgICAicHJvY2Vzc1N0eWxlc2hlZXQgXHU1OTMxXHU2NTU3XHVGRjAxIn0sCi0KLSAgICB7IEVSX1NBWF9FWENFUFRJT04sCi0gICAgICJTQVggXHU3NTcwXHU1RTM4XHU3MkMwXHU2Q0MxIn0sCi0KLS8vICBhZGQgdGhpcyBtZXNzYWdlIHRvIGZpeCBidWcgMjE0NzgKLSAgICB7IEVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQsCi0gICAgICJcdTRFMERcdTY1MkZcdTYzRjRcdTUxRkRcdTY1NzhcdUZGMDEifSwKLQotICAgIHsgRVJfWFNMVF9FUlJPUiwKLSAgICAgIlhTTFQgXHU5MzJGXHU4QUE0In0sCi0KLSAgICB7IEVSX0NVUlJFTkNZX1NJR05fSUxMRUdBTCwKLSAgICAgICJcdTY4M0NcdTVGMEZcdTZBMjNcdTVGMEZcdTVCNTdcdTRFMzJcdTRFMkRcdTRFMERcdTUxNDFcdThBMzFcdThDQThcdTVFNjNcdTdCMjZcdTg2NUYifSwKLQotICAgIHsgRVJfRE9DVU1FTlRfRlVOQ1RJT05fSU5WQUxJRF9JTl9TVFlMRVNIRUVUX0RPTSwKLSAgICAgICJTdHlsZXNoZWV0IERPTSBcdTRFMkRcdTRFMERcdTY1MkZcdTYzRjRcdTY1ODdcdTRFRjZcdTUxRkRcdTY1NzhcdUZGMDEifSwKLQotICAgIHsgRVJfQ0FOVF9SRVNPTFZFX1BSRUZJWF9PRl9OT05fUFJFRklYX1JFU09MVkVSLAotICAgICAgIlx1NzEyMVx1NkNENVx1ODlFM1x1Njc5MFx1OTc1RVx1NTI0RFx1N0Y2RVx1NzhCQ1x1ODlFM1x1Njc5MFx1NTY2OFx1NzY4NFx1NTI0RFx1N0Y2RVx1NzhCQ1x1RkYwMSJ9LAotCi0gICAgeyBFUl9SRURJUkVDVF9DT1VMRE5UX0dFVF9GSUxFTkFNRSwKLSAgICAgICJcdTkxQ0RcdTVDMEVcdTY0RjRcdTUxNDVcdTU5NTdcdTRFRjY6IFx1NzEyMVx1NkNENVx1NTNENlx1NUY5N1x1NkE5NFx1Njg0OFx1NTQwRFx1N0EzMSAtIFx1NkE5NFx1Njg0OFx1NjIxNlx1OTA3OFx1NTNENlx1NUM2Q1x1NjAyN1x1NUZDNVx1OTgwOFx1NTBCM1x1NTZERVx1NjcwOVx1NjU0OFx1NUI1N1x1NEUzMlx1MzAwMiJ9LAotCi0gICAgeyBFUl9DQU5OT1RfQlVJTERfRk9STUFUVEVSTElTVEVORVJfSU5fUkVESVJFQ1QsCi0gICAgICAiXHU3MTIxXHU2Q0Q1XHU1NzI4XHU5MUNEXHU1QzBFXHU2NEY0XHU1MTQ1XHU1OTU3XHU0RUY2XHU0RTJEXHU1RUZBXHU3QUNCIEZvcm1hdHRlckxpc3RlbmVyXHVGRjAxIn0sCi0KLSAgICB7IEVSX0lOVkFMSURfUFJFRklYX0lOX0VYQ0xVREVSRVNVTFRQUkVGSVgsCi0gICAgICAiZXhjbHVkZS1yZXN1bHQtcHJlZml4ZXMgXHU0RTJEXHU3Njg0XHU1MjREXHU3RjZFXHU3OEJDXHU3MTIxXHU2NTQ4OiB7MH0ifSwKLQotICAgIHsgRVJfTUlTU0lOR19OU19VUkksCi0gICAgICAiXHU5MDdBXHU2RjBGXHU2MzA3XHU1QjlBXHU1MjREXHU3RjZFXHU3OEJDXHU3Njg0XHU1NDdEXHU1NDBEXHU3QTdBXHU5NTkzIFVSSSJ9LAotCi0gICAgeyBFUl9NSVNTSU5HX0FSR19GT1JfT1BUSU9OLAotICAgICAgIlx1OTA3QVx1NkYwRlx1OTA3OFx1OTgwNVx1NzY4NFx1NUYxNVx1NjU3ODogezB9In0sCi0KLSAgICB7IEVSX0lOVkFMSURfT1BUSU9OLAotICAgICAiXHU3MTIxXHU2NTQ4XHU3Njg0XHU5MDc4XHU5ODA1OiB7MH0ifSwKLQotICAgIHsgRVJfTUFMRk9STUVEX0ZPUk1BVF9TVFJJTkcsCi0gICAgICJcdTY4M0NcdTVGMEZcdTkzMkZcdThBQTRcdTc2ODRcdTY4M0NcdTVGMEZcdTVCNTdcdTRFMzI6IHswfSJ9LAotCi0gICAgeyBFUl9TVFlMRVNIRUVUX1JFUVVJUkVTX1ZFUlNJT05fQVRUUklCLAotICAgICAgInhzbDpzdHlsZXNoZWV0IFx1OTcwMFx1ODk4MSAndmVyc2lvbicgXHU1QzZDXHU2MDI3XHVGRjAxIn0sCi0KLSAgICB7IEVSX0lMTEVHQUxfQVRUUklCVVRFX1ZBTFVFLAotICAgICAgIlx1NUM2Q1x1NjAyNzogezB9IFx1NTE3N1x1NjcwOVx1NzEyMVx1NjU0OFx1NTAzQzogezF9In0sCi0KLSAgICB7IEVSX0NIT09TRV9SRVFVSVJFU19XSEVOLAotICAgICAieHNsOmNob29zZSBcdTk3MDBcdTg5ODEgeHNsOndoZW4ifSwKLQotICAgIHsgRVJfTk9fQVBQTFlfSU1QT1JUX0lOX0ZPUl9FQUNILAotICAgICAgInhzbDpmb3ItZWFjaCBcdTRFMkRcdTRFMERcdTUxNDFcdThBMzEgeHNsOmFwcGx5LWltcG9ydHMifSwKLQotICAgIHsgRVJfQ0FOVF9VU0VfRFRNX0ZPUl9PVVRQVVQsCi0gICAgICAiRFRNTGlhaXNvbiBcdTcxMjFcdTZDRDVcdTc1MjhcdTY1QkNcdThGMzhcdTUxRkEgRE9NIFx1N0JDMFx1OUVERVx1MzAwMlx1OEFDQlx1NjUzOVx1NzBCQVx1NTBCM1x1OTAwMSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuRE9NMkhlbHBlclx1RkYwMSJ9LAotCi0gICAgeyBFUl9DQU5UX1VTRV9EVE1fRk9SX0lOUFVULAotICAgICAgIkRUTUxpYWlzb24gXHU3MTIxXHU2Q0Q1XHU3NTI4XHU2NUJDXHU4RjM4XHU1MTY1IERPTSBcdTdCQzBcdTlFREVcdTMwMDJcdThBQ0JcdTY1MzlcdTcwQkFcdTUwQjNcdTkwMDEgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLkRPTTJIZWxwZXJcdUZGMDEifSwKLQotICAgIHsgRVJfQ0FMTF9UT19FWFRfRkFJTEVELAotICAgICAgIlx1NTQ3Q1x1NTNFQlx1NjRGNFx1NTE0NVx1NTk1N1x1NEVGNlx1NTE0M1x1N0QyMFx1NTkzMVx1NjU1NzogezB9In0sCi0KLSAgICB7IEVSX1BSRUZJWF9NVVNUX1JFU09MVkUsCi0gICAgICAiXHU1MjREXHU3RjZFXHU3OEJDXHU1RkM1XHU5ODA4XHU4OUUzXHU2NzkwXHU3MEJBXHU1NDdEXHU1NDBEXHU3QTdBXHU5NTkzOiB7MH0ifSwKLQotICAgIHsgRVJfSU5WQUxJRF9VVEYxNl9TVVJST0dBVEUsCi0gICAgICAiXHU1MDc1XHU2RTJDXHU1MjMwXHU3MTIxXHU2NTQ4XHU3Njg0IFVURi0xNiBcdTRFRTNcdTc0MDY6IHswfVx1RkYxRiJ9LAotCi0gICAgeyBFUl9YU0xBVFRSU0VUX1VTRURfSVRTRUxGLAotICAgICAgInhzbDphdHRyaWJ1dGUtc2V0IHswfSBcdTRGN0ZcdTc1MjhcdTY3MkNcdThFQUJcdUZGMENcdTU5ODJcdTZCNjRcdTVDMDdcdTkwMjBcdTYyMTBcdTcxMjFcdTk2NTBcdThGRjRcdTU3MDhcdTMwMDIifSwKLQotICAgIHsgRVJfQ0FOTk9UX01JWF9YRVJDRVNET00sCi0gICAgICAiXHU3MTIxXHU2Q0Q1XHU2REY3XHU1NDA4XHU5NzVFIFhlcmNlcy1ET00gXHU4RjM4XHU1MTY1XHU4MjA3IFhlcmNlcy1ET00gXHU4RjM4XHU1MUZBXHVGRjAxIn0sCi0KLSAgICB7IEVSX1RPT19NQU5ZX0xJU1RFTkVSUywKLSAgICAgICJhZGRUcmFjZUxpc3RlbmVyc1RvU3R5bGVzaGVldCAtIFRvb01hbnlMaXN0ZW5lcnNFeGNlcHRpb24ifSwKLQotICAgIHsgRVJfSU5fRUxFTVRFTVBMQVRFRUxFTV9SRUFET0JKRUNULAotICAgICAgIlx1NTcyOCBFbGVtVGVtcGxhdGVFbGVtZW50LnJlYWRPYmplY3QgXHU0RTJEOiB7MH0ifSwKLQotICAgIHsgRVJfRFVQTElDQVRFX05BTUVEX1RFTVBMQVRFLAotICAgICAgIlx1NjI3RVx1NTIzMFx1OEQ4NVx1OTA0RVx1NEUwMFx1NTAwQlx1NEUwQlx1NTIxN1x1NTQwRFx1N0EzMVx1NzY4NFx1NkEyM1x1Njc3RjogezB9In0sCi0KLSAgICB7IEVSX0lOVkFMSURfS0VZX0NBTEwsCi0gICAgICAiXHU3MTIxXHU2NTQ4XHU3Njg0XHU1MUZEXHU2NTc4XHU1NDdDXHU1M0VCOiBcdTRFMERcdTUxNDFcdThBMzFcdTkwNUVcdThGRjQga2V5KCkgXHU1NDdDXHU1M0VCIn0sCi0KLSAgICB7IEVSX1JFRkVSRU5DSU5HX0lUU0VMRiwKLSAgICAgICJcdThCOEFcdTY1NzggezB9IFx1NzZGNFx1NjNBNVx1NjIxNlx1OTU5M1x1NjNBNVx1NTczMFx1NTNDM1x1NzE2N1x1NjcyQ1x1OEVBQlx1RkYwMSJ9LAotCi0gICAgeyBFUl9JTExFR0FMX0RPTVNPVVJDRV9JTlBVVCwKLSAgICAgICJuZXdUZW1wbGF0ZXMgXHU0RTRCIERPTVNvdXJjZSBcdTc2ODRcdThGMzhcdTUxNjVcdTdCQzBcdTlFREVcdTRFMERcdTUzRUZcdTcwQkFcdTdBN0FcdTUwM0NcdUZGMDEifSwKLQotICAgIHsgRVJfQ0xBU1NfTk9UX0ZPVU5EX0ZPUl9PUFRJT04sCi0gICAgICAgICJcdTYyN0VcdTRFMERcdTUyMzBcdTkwNzhcdTk4MDUgezB9IFx1NzY4NFx1OTg1RVx1NTIyNVx1NkE5NFx1Njg0OCJ9LAotCi0gICAgeyBFUl9SRVFVSVJFRF9FTEVNX05PVF9GT1VORCwKLSAgICAgICAgIlx1NjI3RVx1NEUwRFx1NTIzMFx1OTcwMFx1ODk4MVx1NzY4NFx1NTE0M1x1N0QyMDogezB9In0sCi0KLSAgICB7IEVSX0lOUFVUX0NBTk5PVF9CRV9OVUxMLAotICAgICAgICAiSW5wdXRTdHJlYW0gXHU0RTBEXHU1M0VGXHU3MEJBXHU3QTdBXHU1MDNDIn0sCi0KLSAgICB7IEVSX1VSSV9DQU5OT1RfQkVfTlVMTCwKLSAgICAgICAgIlVSSSBcdTRFMERcdTUzRUZcdTcwQkFcdTdBN0FcdTUwM0MifSwKLQotICAgIHsgRVJfRklMRV9DQU5OT1RfQkVfTlVMTCwKLSAgICAgICAgIkZpbGUgXHU0RTBEXHU1M0VGXHU3MEJBXHU3QTdBXHU1MDNDIn0sCi0KLSAgICB7IEVSX1NPVVJDRV9DQU5OT1RfQkVfTlVMTCwKLSAgICAgICAgICAgICAgICAiSW5wdXRTb3VyY2UgXHU0RTBEXHU1M0VGXHU3MEJBXHU3QTdBXHU1MDNDIn0sCi0KLSAgICB7IEVSX0NBTk5PVF9JTklUX0JTRk1HUiwKLSAgICAgICAgICAgICAgICAiXHU3MTIxXHU2Q0Q1XHU4RDc3XHU1OUNCIEJTRiBcdTdCQTFcdTc0MDZcdTdBMEJcdTVGMEYifSwKLQotICAgIHsgRVJfQ0FOTk9UX0NNUExfRVhURU5TTiwKLSAgICAgICAgICAgICAgICAiXHU3MTIxXHU2Q0Q1XHU3REU4XHU4QjZGXHU2NEY0XHU1MTQ1XHU1OTU3XHU0RUY2In0sCi0KLSAgICB7IEVSX0NBTk5PVF9DUkVBVEVfRVhURU5TTiwKLSAgICAgICJcdTcxMjFcdTZDRDVcdTVFRkFcdTdBQ0JcdTY0RjRcdTUxNDVcdTU5NTdcdTRFRjY6IHswfVx1RkYwQ1x1NTZFMFx1NzBCQTogezF9In0sCi0KLSAgICB7IEVSX0lOU1RBTkNFX01USERfQ0FMTF9SRVFVSVJFUywKLSAgICAgICJcdTU3RjdcdTg4NENcdTg2NTVcdTc0MDZcdTY1QjlcdTZDRDVcdTU0N0NcdTUzRUJcdTY1QjlcdTZDRDUgezB9IFx1NjY0Mlx1RkYwQ1x1OTcwMFx1ODk4MSBPYmplY3QgXHU1N0Y3XHU4ODRDXHU4NjU1XHU3NDA2XHU0RjVDXHU3MEJBXHU3QjJDXHU0RTAwXHU1MDBCXHU1RjE1XHU2NTc4In0sCi0KLSAgICB7IEVSX0lOVkFMSURfRUxFTUVOVF9OQU1FLAotICAgICAgIlx1NjMwN1x1NUI5QVx1NEU4Nlx1NzEyMVx1NjU0OFx1NzY4NFx1NTE0M1x1N0QyMFx1NTQwRFx1N0EzMSB7MH0ifSwKLQotICAgIHsgRVJfRUxFTUVOVF9OQU1FX01FVEhPRF9TVEFUSUMsCi0gICAgICAiXHU1MTQzXHU3RDIwXHU1NDBEXHU3QTMxXHU2NUI5XHU2Q0Q1XHU1RkM1XHU5ODA4XHU2NjJGXHU5NzVDXHU2MTRCIHswfSJ9LAotCi0gICAgeyBFUl9FWFRFTlNJT05fRlVOQ19VTktOT1dOLAotICAgICAgICAgICAgICJcdTY0RjRcdTUxNDVcdTU5NTdcdTRFRjZcdTUxRkRcdTY1NzggezB9IDogezF9IFx1NEUwRFx1NjYwRSJ9LAotCi0gICAgeyBFUl9NT1JFX01BVENIX0NPTlNUUlVDVE9SLAotICAgICAgICAgICAgICJ7MH0gXHU3Njg0XHU1RUZBXHU2OUNCXHU1QjUwXHU2NzA5XHU4RDg1XHU5MDRFXHU0RTAwXHU1MDBCXHU0RUU1XHU0RTBBXHU3Njg0XHU2NzAwXHU0RjczXHU5MTREXHU1QzBEIn0sCi0KLSAgICB7IEVSX01PUkVfTUFUQ0hfTUVUSE9ELAotICAgICAgICAgICAgICJcdTY1QjlcdTZDRDUgezB9IFx1NjcwOVx1OEQ4NVx1OTA0RVx1NEUwMFx1NTAwQlx1NEVFNVx1NEUwQVx1NzY4NFx1NjcwMFx1NEY3M1x1OTE0RFx1NUMwRCJ9LAotCi0gICAgeyBFUl9NT1JFX01BVENIX0VMRU1FTlQsCi0gICAgICAgICAgICAgIlx1NTE0M1x1N0QyMFx1NjVCOVx1NkNENSB7MH0gXHU2NzA5XHU4RDg1XHU5MDRFXHU0RTAwXHU1MDBCXHU0RUU1XHU0RTBBXHU3Njg0XHU2NzAwXHU0RjczXHU5MTREXHU1QzBEIn0sCi0KLSAgICB7IEVSX0lOVkFMSURfQ09OVEVYVF9QQVNTRUQsCi0gICAgICAgICAgICAgIlx1NTBCM1x1OTAwMVx1NEU4Nlx1NzEyMVx1NjU0OFx1NzY4NFx1NzZGOFx1OTVEQ1x1OENDN1x1OEEwQVx1NzRCMFx1NTg4M1x1NEY4Nlx1OEE1NVx1NEYzMCB7MH0ifSwKLQotICAgIHsgRVJfUE9PTF9FWElTVFMsCi0gICAgICAgICAgICAgIlx1OTZDNlx1NTM0MFx1NURGMlx1N0Q5M1x1NUI1OFx1NTcyOCJ9LAotCi0gICAgeyBFUl9OT19EUklWRVJfTkFNRSwKLSAgICAgICAgICAgICAiXHU2NzJBXHU2MzA3XHU1QjlBXHU5QTQ1XHU1MkQ1XHU3QTBCXHU1RjBGXHU1NDBEXHU3QTMxIn0sCi0KLSAgICB7IEVSX05PX1VSTCwKLSAgICAgICAgICAgICAiXHU2NzJBXHU2MzA3XHU1QjlBIFVSTCJ9LAotCi0gICAgeyBFUl9QT09MX1NJWkVfTEVTU1RIQU5fT05FLAotICAgICAgICAgICAgICJcdTk2QzZcdTUzNDBcdTU5MjdcdTVDMEZcdTVDMEZcdTY1QkNcdTRFMDBcdUZGMDEifSwKLQotICAgIHsgRVJfSU5WQUxJRF9EUklWRVIsCi0gICAgICAgICAgICAgIlx1NjMwN1x1NUI5QVx1NEU4Nlx1NzEyMVx1NjU0OFx1NzY4NFx1OUE0NVx1NTJENVx1N0EwQlx1NUYwRlx1NTQwRFx1N0EzMVx1RkYwMSJ9LAotCi0gICAgeyBFUl9OT19TVFlMRVNIRUVUUk9PVCwKLSAgICAgICAgICAgICAiXHU2MjdFXHU0RTBEXHU1MjMwXHU2QTIzXHU1RjBGXHU4ODY4XHU2ODM5XHVGRjAxIn0sCi0KLSAgICB7IEVSX0lMTEVHQUxfWE1MU1BBQ0VfVkFMVUUsCi0gICAgICAgICAieG1sOnNwYWNlIFx1NzY4NFx1NTAzQ1x1NzEyMVx1NjU0OCJ9LAotCi0gICAgeyBFUl9QUk9DRVNTRlJPTU5PREVfRkFJTEVELAotICAgICAgICAgInByb2Nlc3NGcm9tTm9kZSBcdTU5MzFcdTY1NTcifSwKLQotICAgIHsgRVJfUkVTT1VSQ0VfQ09VTERfTk9UX0xPQUQsCi0gICAgICAgICJcdTcxMjFcdTZDRDVcdThGMDlcdTUxNjVcdThDQzdcdTZFOTAgWyB7MH0gXTogezF9IFxuIHsyfSBcdCB7M30ifSwKLQotICAgIHsgRVJfQlVGRkVSX1NJWkVfTEVTU1RIQU5fWkVSTywKLSAgICAgICAgIlx1N0RFOVx1ODg1RFx1NTM0MFx1NTkyN1x1NUMwRiA8PTAifSwKLQotICAgIHsgRVJfVU5LTk9XTl9FUlJPUl9DQUxMSU5HX0VYVEVOU0lPTiwKLSAgICAgICAgIlx1NTQ3Q1x1NTNFQlx1NjRGNFx1NTE0NVx1NTk1N1x1NEVGNlx1NjY0Mlx1RkYwQ1x1NzY3Q1x1NzUxRlx1NEUwRFx1NjYwRVx1NzY4NFx1OTMyRlx1OEFBNCJ9LAotCi0gICAgeyBFUl9OT19OQU1FU1BBQ0VfREVDTCwKLSAgICAgICAgIlx1NTI0RFx1N0Y2RVx1NzhCQyB7MH0gXHU2QzkyXHU2NzA5XHU1QzBEXHU2MUM5XHU3Njg0XHU1NDdEXHU1NDBEXHU3QTdBXHU5NTkzXHU1QkEzXHU1NDRBIn0sCi0KLSAgICB7IEVSX0VMRU1fQ09OVEVOVF9OT1RfQUxMT1dFRCwKLSAgICAgICAgIlx1NTE0M1x1N0QyMFx1NTE2N1x1NUJCOVx1NEUwRFx1NTE0MVx1OEEzMSBsYW5nPWphdmFjbGFzcyB7MH0ifSwKLQotICAgIHsgRVJfU1RZTEVTSEVFVF9ESVJFQ1RFRF9URVJNSU5BVElPTiwKLSAgICAgICAgIlx1NkEyM1x1NUYwRlx1ODg2OFx1NUMwRVx1NTQxMVx1NzY4NFx1N0Q0Mlx1NkI2MiJ9LAotCi0gICAgeyBFUl9PTkVfT1JfVFdPLAotICAgICAgICAiMSBcdTYyMTYgMiJ9LAotCi0gICAgeyBFUl9UV09fT1JfVEhSRUUsCi0gICAgICAgICIyIFx1NjIxNiAzIn0sCi0KLSAgICB7IEVSX0NPVUxEX05PVF9MT0FEX1JFU09VUkNFLAotICAgICAgICAiXHU3MTIxXHU2Q0Q1XHU4RjA5XHU1MTY1IHswfSAoXHU2QUEyXHU2N0U1IENMQVNTUEFUSClcdUZGMENcdTc2RUVcdTUyNERcdTUzRUFcdTRGN0ZcdTc1MjhcdTk4MTBcdThBMkRcdTUwM0MifSwKLQotICAgIHsgRVJfQ0FOTk9UX0lOSVRfREVGQVVMVF9URU1QTEFURVMsCi0gICAgICAgICJcdTcxMjFcdTZDRDVcdThENzdcdTU5Q0JcdTk4MTBcdThBMkRcdTZBMjNcdTY3N0YifSwKLQotICAgIHsgRVJfUkVTVUxUX05VTEwsCi0gICAgICAgICJcdTdENTBcdTY3OUNcdTRFMERcdTYxQzlcdTcwQkFcdTdBN0FcdTUwM0MifSwKLQotICAgIHsgRVJfUkVTVUxUX0NPVUxEX05PVF9CRV9TRVQsCi0gICAgICAgICJcdTcxMjFcdTZDRDVcdThBMkRcdTVCOUFcdTdENTBcdTY3OUMifSwKLQotICAgIHsgRVJfTk9fT1VUUFVUX1NQRUNJRklFRCwKLSAgICAgICAgIlx1NjcyQVx1NjMwN1x1NUI5QVx1OEYzOFx1NTFGQSJ9LAotCi0gICAgeyBFUl9DQU5OT1RfVFJBTlNGT1JNX1RPX1JFU1VMVF9UWVBFLAotICAgICAgICAiXHU3MTIxXHU2Q0Q1XHU4RjQ5XHU2M0RCXHU3MEJBXHU5ODVFXHU1NzhCIHswfSBcdTc2ODRcdTdENTBcdTY3OUMifSwKLQotICAgIHsgRVJfQ0FOTk9UX1RSQU5TRk9STV9TT1VSQ0VfVFlQRSwKLSAgICAgICAgIlx1NzEyMVx1NkNENVx1OEY0OVx1NjNEQlx1OTg1RVx1NTc4QiB7MH0gXHU3Njg0XHU0Rjg2XHU2RTkwIn0sCi0KLSAgICB7IEVSX05VTExfQ09OVEVOVF9IQU5ETEVSLAotICAgICAgICAiXHU3QTdBXHU1MDNDXHU1MTY3XHU1QkI5XHU4NjU1XHU3NDA2XHU3QTBCXHU1RjBGIn0sCi0KLSAgICB7IEVSX05VTExfRVJST1JfSEFORExFUiwKLSAgICAgICAgIlx1N0E3QVx1NTAzQ1x1OTMyRlx1OEFBNFx1ODY1NVx1NzQwNlx1N0EwQlx1NUYwRiJ9LAotCi0gICAgeyBFUl9DQU5OT1RfQ0FMTF9QQVJTRSwKLSAgICAgICAgIlx1ODJFNVx1NjcyQVx1OEEyRFx1NUI5QSBDb250ZW50SGFuZGxlclx1RkYwQ1x1NTI0N1x1NzEyMVx1NkNENVx1NTQ3Q1x1NTNFQlx1NTI1Nlx1Njc5MCJ9LAotCi0gICAgeyBFUl9OT19QQVJFTlRfRk9SX0ZJTFRFUiwKLSAgICAgICAgIlx1N0JFOVx1OTA3OFx1NkM5Mlx1NjcwOVx1NzIzNlx1OTgwNSJ9LAotCi0gICAgeyBFUl9OT19TVFlMRVNIRUVUX0lOX01FRElBLAotICAgICAgICAgIlx1NTcyOCB7MH0gXHU0RTJEXHU2MjdFXHU0RTBEXHU1MjMwXHU2QTIzXHU1RjBGXHU4ODY4XHVGRjBDXHU1QTkyXHU5QUQ0ID0gezF9In0sCi0KLSAgICB7IEVSX05PX1NUWUxFU0hFRVRfUEksCi0gICAgICAgICAiXHU1NzI4IHswfSBcdTRFMkRcdTYyN0VcdTRFMERcdTUyMzAgeG1sLXN0eWxlc2hlZXQgUEkifSwKLQotICAgIHsgRVJfTk9UX1NVUFBPUlRFRCwKLSAgICAgICAiXHU0RTBEXHU2NTJGXHU2M0Y0OiB7MH0ifSwKLQotICAgIHsgRVJfUFJPUEVSVFlfVkFMVUVfQk9PTEVBTiwKLSAgICAgICAiXHU1QzZDXHU2MDI3IHswfSBcdTc2ODRcdTUwM0NcdTYxQzlcdTcwQkFcdTVFMDNcdTY3OTdcdTU3RjdcdTg4NENcdTg2NTVcdTc0MDYifSwKLQotICAgIHsgRVJfQ09VTERfTk9UX0ZJTkRfRVhURVJOX1NDUklQVCwKLSAgICAgICAgICJcdTcxMjFcdTZDRDVcdTU3MjggezB9IFx1NTNENlx1NUY5N1x1NTkxNlx1OTBFOFx1NTQ3RFx1NEVFNFx1NkE5NCJ9LAotCi0gICAgeyBFUl9SRVNPVVJDRV9DT1VMRF9OT1RfRklORCwKLSAgICAgICAgIlx1NjI3RVx1NEUwRFx1NTIzMFx1OENDN1x1NkU5MCBbIHswfSBdXHUzMDAyXG57MX0ifSwKLQotICAgIHsgRVJfT1VUUFVUX1BST1BFUlRZX05PVF9SRUNPR05JWkVELAotICAgICAgICAiXHU3MTIxXHU2Q0Q1XHU4RkE4XHU4QjU4XHU3Njg0XHU4RjM4XHU1MUZBXHU1QzZDXHU2MDI3OiB7MH0ifSwKLQotICAgIHsgRVJfRkFJTEVEX0NSRUFUSU5HX0VMRU1MSVRSU0xULAotICAgICAgICAiXHU3MTIxXHU2Q0Q1XHU1RUZBXHU3QUNCIEVsZW1MaXRlcmFsUmVzdWx0IFx1NTdGN1x1ODg0Q1x1ODY1NVx1NzQwNiJ9LAotCi0gIC8vRWFybGllciAoSkRLIDEuNCBYQUxBTiAyLjItRDExKSBhdCBrZXkgY29kZSAnMjA0JyB0aGUga2V5IG5hbWUgd2FzIEVSX1BSSU9SSVRZX05PVF9QQVJTQUJMRQotICAvLyBJbiBsYXRlc3QgWGFsYW4gY29kZSBiYXNlIGtleSBuYW1lIGlzICBFUl9WQUxVRV9TSE9VTERfQkVfTlVNQkVSLiBUaGlzIHNob3VsZCBhbHNvIGJlIHRha2VuIGNhcmUKLSAgLy9pbiBsb2NhbGUgc3BlY2lmaWMgZmlsZXMgbGlrZSBYU0xURXJyb3JSZXNvdXJjZXNfZGUuamF2YSwgWFNMVEVycm9yUmVzb3VyY2VzX2ZyLmphdmEgZXRjLgotICAvL05PVEU6IE5vdCBvbmx5IHRoZSBrZXkgbmFtZSBidXQgbWVzc2FnZSBoYXMgYWxzbyBiZWVuIGNoYW5nZWQuCi0gICAgeyBFUl9WQUxVRV9TSE9VTERfQkVfTlVNQkVSLAotICAgICAgICAiezB9IFx1NzY4NFx1NTAzQ1x1NjFDOVx1NTMwNVx1NTQyQlx1NTNFRlx1NTI1Nlx1Njc5MFx1NzY4NFx1NjU3OFx1NUI1NyJ9LAotCi0gICAgeyBFUl9WQUxVRV9TSE9VTERfRVFVQUwsCi0gICAgICAgICJ7MH0gXHU3Njg0XHU1MDNDXHU2MUM5XHU3QjQ5XHU2NUJDIHllcyBcdTYyMTYgbm8ifSwKLQotICAgIHsgRVJfRkFJTEVEX0NBTExJTkdfTUVUSE9ELAotICAgICAgICAiXHU3MTIxXHU2Q0Q1XHU1NDdDXHU1M0VCIHswfSBcdTY1QjlcdTZDRDUifSwKLQotICAgIHsgRVJfRkFJTEVEX0NSRUFUSU5HX0VMRU1UTVBMLAotICAgICAgICAiXHU3MTIxXHU2Q0Q1XHU1RUZBXHU3QUNCIEVsZW1UZW1wbGF0ZUVsZW1lbnQgXHU1N0Y3XHU4ODRDXHU4NjU1XHU3NDA2In0sCi0KLSAgICB7IEVSX0NIQVJTX05PVF9BTExPV0VELAotICAgICAgICAiXHU2NTg3XHU0RUY2XHU2QjY0XHU4NjU1XHU0RTBEXHU1MTQxXHU4QTMxXHU1QjU3XHU1MTQzIn0sCi0KLSAgICB7IEVSX0FUVFJfTk9UX0FMTE9XRUQsCi0gICAgICAgICJ7MX0gXHU1MTQzXHU3RDIwXHU0RTBEXHU1MTQxXHU4QTMxIFwiezB9XCIgXHU1QzZDXHU2MDI3XHVGRjAxIn0sCi0KLSAgICB7IEVSX0JBRF9WQUxVRSwKLSAgICAgInswfSBcdTcxMjFcdTY1NDhcdTUwM0MgezF9ICJ9LAotCi0gICAgeyBFUl9BVFRSSUJfVkFMVUVfTk9UX0ZPVU5ELAotICAgICAiXHU2MjdFXHU0RTBEXHU1MjMwIHswfSBcdTVDNkNcdTYwMjdcdTUwM0MifSwKLQotICAgIHsgRVJfQVRUUklCX1ZBTFVFX05PVF9SRUNPR05JWkVELAotICAgICAiezB9IFx1NUM2Q1x1NjAyN1x1NTAzQ1x1NzEyMVx1NkNENVx1OEZBOFx1OEI1OCAifSwKLQotICAgIHsgRVJfTlVMTF9VUklfTkFNRVNQQUNFLAotICAgICAiXHU1NjE3XHU4QTY2XHU0RUU1XHU3QTdBXHU1MDNDIFVSSSBcdTc1MjJcdTc1MUZcdTU0N0RcdTU0MERcdTdBN0FcdTk1OTNcdTUyNERcdTdGNkVcdTc4QkMifSwKLQotICAgIHsgRVJfTlVNQkVSX1RPT19CSUcsCi0gICAgICJcdTU2MTdcdThBNjZcdTY4M0NcdTVGMEZcdTUzMTZcdTU5MjdcdTY1QkNcdTY3MDBcdTU5MjdcdTk1NzdcdTY1NzRcdTY1NzhcdTc2ODRcdTY1NzhcdTVCNTcifSwKLQotICAgIHsgRVJfQ0FOTk9UX0ZJTkRfU0FYMV9EUklWRVIsCi0gICAgICJcdTYyN0VcdTRFMERcdTUyMzAgU0FYMSBcdTlBNDVcdTUyRDVcdTdBMEJcdTVGMEZcdTk4NUVcdTUyMjUgezB9In0sCi0KLSAgICB7IEVSX1NBWDFfRFJJVkVSX05PVF9MT0FERUQsCi0gICAgICJcdTYyN0VcdTUyMzAgU0FYMSBcdTlBNDVcdTUyRDVcdTdBMEJcdTVGMEZcdTk4NUVcdTUyMjUgezB9XHVGRjBDXHU0RjQ2XHU3MTIxXHU2Q0Q1XHU4RjA5XHU1MTY1In0sCi0KLSAgICB7IEVSX1NBWDFfRFJJVkVSX05PVF9JTlNUQU5USUFURUQsCi0gICAgICJcdTVERjJcdThGMDlcdTUxNjUgU0FYMSBcdTlBNDVcdTUyRDVcdTdBMEJcdTVGMEZcdTk4NUVcdTUyMjUgezB9XHVGRjBDXHU0RjQ2XHU3MTIxXHU2Q0Q1XHU1RUZBXHU3QUNCIn0sCi0KLSAgICB7IEVSX1NBWDFfRFJJVkVSX05PVF9JTVBMRU1FTlRfUEFSU0VSLAotICAgICAiU0FYMSBcdTlBNDVcdTUyRDVcdTdBMEJcdTVGMEZcdTk4NUVcdTUyMjUgezB9IFx1NjcyQVx1NUJFNlx1ODg0QyBvcmcueG1sLnNheC5QYXJzZXIifSwKLQotICAgIHsgRVJfUEFSU0VSX1BST1BFUlRZX05PVF9TUEVDSUZJRUQsCi0gICAgICJcdTY3MkFcdTYzMDdcdTVCOUFcdTdDRkJcdTdENzFcdTVDNkNcdTYwMjcgb3JnLnhtbC5zYXgucGFyc2VyIn0sCi0KLSAgICB7IEVSX1BBUlNFUl9BUkdfQ0FOTk9UX0JFX05VTEwsCi0gICAgICJcdTUyNTZcdTY3OTBcdTU2NjhcdTVGMTVcdTY1NzhcdTRFMERcdTUzRUZcdTcwQkFcdTdBN0FcdTUwM0MifSwKLQotICAgIHsgRVJfRkVBVFVSRSwKLSAgICAgIlx1NTI5Rlx1ODBGRDogezB9In0sCi0KLSAgICB7IEVSX1BST1BFUlRZLAotICAgICAiXHU1QzZDXHU2MDI3OiB7MH0ifSwKLQotICAgIHsgRVJfTlVMTF9FTlRJVFlfUkVTT0xWRVIsCi0gICAgICJcdTdBN0FcdTUwM0NcdTUwMEJcdTlBRDRcdTg5RTNcdTY3OTBcdTU2NjgifSwKLQotICAgIHsgRVJfTlVMTF9EVERfSEFORExFUiwKLSAgICAgIlx1N0E3QVx1NTAzQyBEVEQgXHU4NjU1XHU3NDA2XHU3QTBCXHU1RjBGIn0sCi0KLSAgICB7IEVSX05PX0RSSVZFUl9OQU1FX1NQRUNJRklFRCwKLSAgICAgIlx1NjcyQVx1NjMwN1x1NUI5QVx1OUE0NVx1NTJENVx1N0EwQlx1NUYwRlx1NTQwRFx1N0EzMVx1RkYwMSJ9LAotCi0gICAgeyBFUl9OT19VUkxfU1BFQ0lGSUVELAotICAgICAiXHU2NzJBXHU2MzA3XHU1QjlBIFVSTFx1RkYwMSJ9LAotCi0gICAgeyBFUl9QT09MU0laRV9MRVNTX1RIQU5fT05FLAotICAgICAiXHU5NkM2XHU1MzQwXHU1OTI3XHU1QzBGXHU1QzBGXHU2NUJDIDFcdUZGMDEifSwKLQotICAgIHsgRVJfSU5WQUxJRF9EUklWRVJfTkFNRSwKLSAgICAgIlx1NjMwN1x1NUI5QVx1NEU4Nlx1NzEyMVx1NjU0OFx1NzY4NFx1OUE0NVx1NTJENVx1N0EwQlx1NUYwRlx1NTQwRFx1N0EzMVx1RkYwMSJ9LAotCi0gICAgeyBFUl9FUlJPUkxJU1RFTkVSLAotICAgICAiRXJyb3JMaXN0ZW5lciJ9LAotCi0KLS8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2Ugc2hvdWxkIG5vdCBub3JtYWxseSBiZSBkaXNwbGF5ZWQKLS8vICAgdG8gdXNlcnMuICBJdCBkZXNjcmliZXMgYSBzaXR1YXRpb24gaW4gd2hpY2ggdGhlIHByb2Nlc3NvciBoYXMgZGV0ZWN0ZWQKLS8vICAgYW4gaW50ZXJuYWwgY29uc2lzdGVuY3kgcHJvYmxlbSBpbiBpdHNlbGYsIGFuZCBpdCBwcm92aWRlcyB0aGlzIG1lc3NhZ2UKLS8vICAgZm9yIHRoZSBkZXZlbG9wZXIgdG8gaGVscCBkaWFnbm9zZSB0aGUgcHJvYmxlbS4gIFRoZSBuYW1lCi0vLyAgICdFbGVtVGVtcGxhdGVFbGVtZW50JyBpcyB0aGUgbmFtZSBvZiBhIGNsYXNzLCBhbmQgc2hvdWxkIG5vdCBiZQotLy8gICB0cmFuc2xhdGVkLgotICAgIHsgRVJfQVNTRVJUX05PX1RFTVBMQVRFX1BBUkVOVCwKLSAgICAgIlx1N0EwQlx1NUYwRlx1OEEyRFx1OEEwOFx1NEVCQVx1NTRFMVx1NzY4NFx1OTMyRlx1OEFBNFx1RkYwMVx1ODg2OFx1NzkzQVx1NUYwRlx1NkM5Mlx1NjcwOSBFbGVtVGVtcGxhdGVFbGVtZW50IFx1NzIzNlx1OTgwNVx1RkYwMSJ9LAotCi0KLS8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2Ugc2hvdWxkIG5vdCBub3JtYWxseSBiZSBkaXNwbGF5ZWQKLS8vICAgdG8gdXNlcnMuICBJdCBkZXNjcmliZXMgYSBzaXR1YXRpb24gaW4gd2hpY2ggdGhlIHByb2Nlc3NvciBoYXMgZGV0ZWN0ZWQKLS8vICAgYW4gaW50ZXJuYWwgY29uc2lzdGVuY3kgcHJvYmxlbSBpbiBpdHNlbGYsIGFuZCBpdCBwcm92aWRlcyB0aGlzIG1lc3NhZ2UKLS8vICAgZm9yIHRoZSBkZXZlbG9wZXIgdG8gaGVscCBkaWFnbm9zZSB0aGUgcHJvYmxlbS4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dAotLy8gICBwcm92aWRlcyBmdXJ0aGVyIGluZm9ybWF0aW9uIGluIG9yZGVyIHRvIGRpYWdub3NlIHRoZSBwcm9ibGVtLiAgVGhlIG5hbWUKLS8vICAgJ1JlZHVuZGVudEV4cHJFbGltaW5hdG9yJyBpcyB0aGUgbmFtZSBvZiBhIGNsYXNzLCBhbmQgc2hvdWxkIG5vdCBiZQotLy8gICB0cmFuc2xhdGVkLgotICAgIHsgRVJfQVNTRVJUX1JFRFVOREVOVF9FWFBSX0VMSU1JTkFUT1IsCi0gICAgICJcdTdBMEJcdTVGMEZcdThBMkRcdThBMDhcdTRFQkFcdTU0RTFcdTU3MjggUmVkdW5kZW50RXhwckVsaW1pbmF0b3IgXHU0RTJEXHU3Njg0XHU1QkEzXHU1NDRBOiB7MH0ifSwKLQotICAgIHsgRVJfTk9UX0FMTE9XRURfSU5fUE9TSVRJT04sCi0gICAgICJcdTZBMjNcdTVGMEZcdTg4NjhcdTZCNjRcdTRGNERcdTdGNkVcdTRFMERcdTUxNDFcdThBMzEgezB9XHVGRjAxIn0sCi0KLSAgICB7IEVSX05PTldISVRFU1BBQ0VfTk9UX0FMTE9XRURfSU5fUE9TSVRJT04sCi0gICAgICJcdTZBMjNcdTVGMEZcdTg4NjhcdTZCNjRcdTRGNERcdTdGNkVcdTRFMERcdTUxNDFcdThBMzFcdTk3NUVcdTdBN0FcdTY4M0NcdTY1ODdcdTVCNTdcdUZGMDEifSwKLQotICAvLyBUaGlzIGNvZGUgaXMgc2hhcmVkIHdpdGggd2FybmluZyBjb2Rlcy4KLSAgLy8gU3lzdGVtSWQgVW5rbm93bgotICAgIHsgSU5WQUxJRF9UQ0hBUiwKLSAgICAgIlx1NzEyMVx1NjU0OFx1NTAzQzogezF9IFx1NzUyOFx1NjVCQyBDSEFSIFx1NUM2Q1x1NjAyNzogezB9XHUzMDAyXHU5ODVFXHU1NzhCIENIQVIgXHU3Njg0XHU1QzZDXHU2MDI3XHU1RkM1XHU5ODA4XHU1MEM1XHU3MEJBIDEgXHU1MDBCXHU1QjU3XHU1MTQzXHVGRjAxIn0sCi0KLSAgICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIGlzIHVzZWQgaWYgdGhlIHZhbHVlIG9mCi0gICAgLy8gYW4gYXR0cmlidXRlIGluIGEgc3R5bGVzaGVldCBpcyBpbnZhbGlkLiAgIlFOQU1FIiBpcyB0aGUgWE1MIGRhdGEtdHlwZSBvZgotICAgIC8vIHRoZSBhdHRyaWJ1dGUsIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgezF9IGlzCi0gICAgLy8gdGhlIGF0dHJpYnV0ZSB2YWx1ZSBhbmQgezB9IGlzIHRoZSBhdHRyaWJ1dGUgbmFtZS4KLSAgLy9UaGUgZm9sbG93aW5nIGNvZGVzIGFyZSBzaGFyZWQgd2l0aCB0aGUgd2FybmluZyBjb2Rlcy4uLgotICAgIHsgSU5WQUxJRF9RTkFNRSwKLSAgICAgIlx1NzEyMVx1NjU0OFx1NTAzQzogezF9IFx1NzUyOFx1NjVCQyBRTkFNRSBcdTVDNkNcdTYwMjc6IHswfSJ9LAotCi0gICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBpcyB1c2VkIGlmIHRoZSB2YWx1ZSBvZgotICAgIC8vIGFuIGF0dHJpYnV0ZSBpbiBhIHN0eWxlc2hlZXQgaXMgaW52YWxpZC4gICJFTlVNIiBpcyB0aGUgWE1MIGRhdGEtdHlwZSBvZgotICAgIC8vIHRoZSBhdHRyaWJ1dGUsIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgezF9IGlzCi0gICAgLy8gdGhlIGF0dHJpYnV0ZSB2YWx1ZSwgezB9IGlzIHRoZSBhdHRyaWJ1dGUgbmFtZSwgYW5kIHsyfSBpcyBhIGxpc3Qgb2YgdmFsaWQKLSAgICAvLyB2YWx1ZXMuCi0gICAgeyBJTlZBTElEX0VOVU0sCi0gICAgICJcdTcxMjFcdTY1NDhcdTUwM0M6IHsxfSBcdTc1MjhcdTY1QkMgRU5VTSBcdTVDNkNcdTYwMjc6IHswfVx1MzAwMlx1NjcwOVx1NjU0OFx1NTAzQ1x1NzBCQTogezJ9XHUzMDAyIn0sCi0KLS8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgaXMgdXNlZCBpZiB0aGUgdmFsdWUgb2YKLS8vIGFuIGF0dHJpYnV0ZSBpbiBhIHN0eWxlc2hlZXQgaXMgaW52YWxpZC4gICJOTVRPS0VOIiBpcyB0aGUgWE1MIGRhdGEtdHlwZQotLy8gb2YgdGhlIGF0dHJpYnV0ZSwgYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCB7MX0gaXMKLS8vIHRoZSBhdHRyaWJ1dGUgdmFsdWUgYW5kIHswfSBpcyB0aGUgYXR0cmlidXRlIG5hbWUuCi0gICAgeyBJTlZBTElEX05NVE9LRU4sCi0gICAgICJcdTcxMjFcdTY1NDhcdTUwM0M6IHsxfSBcdTc1MjhcdTY1QkMgTk1UT0tFTiBcdTVDNkNcdTYwMjc6IHswfSJ9LAotCi0vLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIGlzIHVzZWQgaWYgdGhlIHZhbHVlIG9mCi0vLyBhbiBhdHRyaWJ1dGUgaW4gYSBzdHlsZXNoZWV0IGlzIGludmFsaWQuICAiTkNOQU1FIiBpcyB0aGUgWE1MIGRhdGEtdHlwZQotLy8gb2YgdGhlIGF0dHJpYnV0ZSwgYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCB7MX0gaXMKLS8vIHRoZSBhdHRyaWJ1dGUgdmFsdWUgYW5kIHswfSBpcyB0aGUgYXR0cmlidXRlIG5hbWUuCi0gICAgeyBJTlZBTElEX05DTkFNRSwKLSAgICAgIlx1NzEyMVx1NjU0OFx1NTAzQzogezF9IFx1NzUyOFx1NjVCQyBOQ05BTUUgXHU1QzZDXHU2MDI3OiB7MH0ifSwKLQotLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBpcyB1c2VkIGlmIHRoZSB2YWx1ZSBvZgotLy8gYW4gYXR0cmlidXRlIGluIGEgc3R5bGVzaGVldCBpcyBpbnZhbGlkLiAgImJvb2xlYW4iIGlzIHRoZSBYU0xUIGRhdGEtdHlwZQotLy8gb2YgdGhlIGF0dHJpYnV0ZSwgYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCB7MX0gaXMKLS8vIHRoZSBhdHRyaWJ1dGUgdmFsdWUgYW5kIHswfSBpcyB0aGUgYXR0cmlidXRlIG5hbWUuCi0gICAgeyBJTlZBTElEX0JPT0xFQU4sCi0gICAgICJcdTcxMjFcdTY1NDhcdTUwM0M6IHsxfSBcdTc1MjhcdTY1QkNcdTVFMDNcdTY3OTdcdTVDNkNcdTYwMjc6IHswfSJ9LAotCi0vLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIGlzIHVzZWQgaWYgdGhlIHZhbHVlIG9mCi0vLyBhbiBhdHRyaWJ1dGUgaW4gYSBzdHlsZXNoZWV0IGlzIGludmFsaWQuICAibnVtYmVyIiBpcyB0aGUgWFNMVCBkYXRhLXR5cGUKLS8vIG9mIHRoZSBhdHRyaWJ1dGUsIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgezF9IGlzCi0vLyB0aGUgYXR0cmlidXRlIHZhbHVlIGFuZCB7MH0gaXMgdGhlIGF0dHJpYnV0ZSBuYW1lLgotICAgICB7IElOVkFMSURfTlVNQkVSLAotICAgICAiXHU3MTIxXHU2NTQ4XHU1MDNDOiB7MX0gXHU3NTI4XHU2NUJDXHU2NTc4XHU1QjU3XHU1QzZDXHU2MDI3OiB7MH0ifSwKLQotCi0gIC8vIEVuZCBvZiBzaGFyZWQgY29kZXMuLi4KLQotLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIEEgIm1hdGNoIHBhdHRlcm4iIGlzIGEgc3BlY2lhbCBmb3JtIG9mIFhQYXRoIGV4cHJlc3Npb24KLS8vIHRoYXQgaXMgdXNlZCBmb3IgbWF0Y2hpbmcgcGF0dGVybnMuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YKLS8vIGEgZnVuY3Rpb24uICBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB3aGVuIHRoaXMgZnVuY3Rpb24gaXMgcmVmZXJlbmNlZCBpbgotLy8gYSBtYXRjaCBwYXR0ZXJuLCBpdHMgYXJndW1lbnQgbXVzdCBiZSBhIHN0cmluZyBsaXRlcmFsIChvciBjb25zdGFudC4pCi0vLyBFUl9BUkdfTElURVJBTCAtIG5ldyBlcnJvciBtZXNzYWdlIGZvciBidWd6aWxsYSAvLzUyMDIKLSAgICB7IEVSX0FSR19MSVRFUkFMLAotICAgICAiXHU5MTREXHU1QzBEXHU2QTIzXHU1RjBGXHU0RTJEIHswfSBcdTc2ODRcdTVGMTVcdTY1NzhcdTVGQzVcdTk4MDhcdTY2MkZcdTY1ODdcdTVCNTdcdTMwMDIifSwKLQotLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0d28gZGVmaW5pdGlvbnMgb2YKLS8vIGEgdmFyaWFibGUuICBBICJnbG9iYWwgdmFyaWFibGUiIGlzIGEgdmFyaWFibGUgdGhhdCBpcyBhY2Nlc3NpYmxlIGV2ZXJ5d2hlcgotLy8gaW4gdGhlIHN0eWxlc2hlZXQuCi0vLyBFUl9EVVBMSUNBVEVfR0xPQkFMX1ZBUiAtIG5ldyBlcnJvciBtZXNzYWdlIGZvciBidWd6aWxsYSAjNzkwCi0gICAgeyBFUl9EVVBMSUNBVEVfR0xPQkFMX1ZBUiwKLSAgICAgIlx1OTFDRFx1ODkwN1x1NzY4NFx1NTE2OFx1NTdERlx1OEI4QVx1NjU3OFx1NUJBM1x1NTQ0QVx1MzAwMiJ9LAotCi0KLS8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdHdvIGRlZmluaXRpb25zIG9mCi0vLyBhIHZhcmlhYmxlIHdlcmUgZW5jb3VudGVyZWQuCi0vLyBFUl9EVVBMSUNBVEVfVkFSIC0gbmV3IGVycm9yIG1lc3NhZ2UgZm9yIGJ1Z3ppbGxhICM3OTAKLSAgICB7IEVSX0RVUExJQ0FURV9WQVIsCi0gICAgICJcdTkxQ0RcdTg5MDdcdTc2ODRcdThCOEFcdTY1NzhcdTVCQTNcdTU0NEFcdTMwMDIifSwKLQotICAgIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAieHNsOnRlbXBsYXRlLCAibmFtZSIgYW5kICJtYXRjaCIgYXJlIFhTTFQga2V5d29yZHMKLSAgICAvLyB3aGljaCBtdXN0IG5vdCBiZSB0cmFuc2xhdGVkLgotICAgIC8vIEVSX1RFTVBMQVRFX05BTUVfTUFUQ0ggLSBuZXcgZXJyb3IgbWVzc2FnZSBmb3IgYnVnemlsbGEgIzc4OQotICAgIHsgRVJfVEVNUExBVEVfTkFNRV9NQVRDSCwKLSAgICAgInhzbDp0ZW1wbGF0ZSBcdTVGQzVcdTk4MDhcdTY3MDlcdTU0MERcdTdBMzFcdTYyMTZcdTkxNERcdTVDMERcdTVDNkNcdTYwMjcgKFx1NjIxNlx1NTE3N1x1NjcwOVx1NTE2OVx1ODAwNSkifSwKLQotICAgIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiZXhjbHVkZS1yZXN1bHQtcHJlZml4ZXMiIGlzIGFuIFhTTFQga2V5d29yZCB3aGljaAotICAgIC8vIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoZSBtZXNzYWdlIGluZGljYXRlcyB0aGF0IGEgbmFtZXNwYWNlIHByZWZpeAotICAgIC8vIGVuY291bnRlcmVkIGFzIHBhcnQgb2YgdGhlIHZhbHVlIG9mIHRoZSBleGNsdWRlLXJlc3VsdC1wcmVmaXhlcyBhdHRyaWJ1dGUKLSAgICAvLyB3YXMgaW4gZXJyb3IuCi0gICAgLy8gRVJfSU5WQUxJRF9QUkVGSVggLSBuZXcgZXJyb3IgbWVzc2FnZSBmb3IgYnVnemlsbGEgIzc4OAotICAgIHsgRVJfSU5WQUxJRF9QUkVGSVgsCi0gICAgICJleGNsdWRlLXJlc3VsdC1wcmVmaXhlcyBcdTRFMkRcdTc2ODRcdTUyNERcdTdGNkVcdTc4QkNcdTcxMjFcdTY1NDg6IHswfSJ9LAotCi0gICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIEFuICJhdHRyaWJ1dGUgc2V0IiBpcyBhIHNldCBvZiBhdHRyaWJ1dGVzIHRoYXQgY2FuCi0gICAgLy8gYmUgYWRkZWQgdG8gYW4gZWxlbWVudCBpbiB0aGUgb3V0cHV0IGRvY3VtZW50IGFzIGEgZ3JvdXAuICBUaGUgbWVzc2FnZQotICAgIC8vIGluZGljYXRlcyB0aGF0IHRoZXJlIHdhcyBhIHJlZmVyZW5jZSB0byBhbiBhdHRyaWJ1dGUgc2V0IG5hbWVkIHswfSB0aGF0Ci0gICAgLy8gd2FzIG5ldmVyIGRlZmluZWQuCi0gICAgLy8gRVJfTk9fQVRUUklCX1NFVCAtIG5ldyBlcnJvciBtZXNzYWdlIGZvciBidWd6aWxsYSAjNzgyCi0gICAgeyBFUl9OT19BVFRSSUJfU0VULAotICAgICAiXHU0RTBEXHU1QjU4XHU1NzI4XHU1NDBEXHU3QTMxXHU3MEJBIHswfSBcdTc2ODQgYXR0cmlidXRlLXNldCJ9LAotCi0gICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGVyZSB3YXMgYSByZWZlcmVuY2UKLSAgICAvLyB0byBhIGZ1bmN0aW9uIG5hbWVkIHswfSBmb3Igd2hpY2ggbm8gZnVuY3Rpb24gZGVmaW5pdGlvbiBjb3VsZCBiZSBmb3VuZC4KLSAgICB7IEVSX0ZVTkNUSU9OX05PVF9GT1VORCwKLSAgICAgIlx1NEUwRFx1NUI1OFx1NTcyOFx1NTQwRFx1N0EzMVx1NzBCQSB7MH0gXHU3Njg0XHU1MUZEXHU2NTc4In0sCi0KLSAgICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoZSBYU0xUIGluc3RydWN0aW9uCi0gICAgLy8gdGhhdCBpcyBuYW1lZCBieSB0aGUgc3Vic3RpdHV0aW9uIHRleHQgezB9IG11c3Qgbm90IGNvbnRhaW4gb3RoZXIgWFNMVAotICAgIC8vIGluc3RydWN0aW9ucyAoY29udGVudCkgb3IgYSAic2VsZWN0IiBhdHRyaWJ1dGUuICBUaGUgd29yZCAic2VsZWN0IiBpcwotICAgIC8vIGFuIFhTTFQga2V5d29yZCBpbiB0aGlzIGNhc2UgYW5kIG11c3Qgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgeyBFUl9DQU5UX0hBVkVfQ09OVEVOVF9BTkRfU0VMRUNULAotICAgICAiezB9IFx1NTE0M1x1N0QyMFx1NEUwRFx1NTNFRlx1NTQwQ1x1NjY0Mlx1NTE3N1x1NjcwOVx1NTE2N1x1NUJCOVx1ODIwN1x1OTA3OFx1NTNENlx1NUM2Q1x1NjAyN1x1MzAwMiJ9LAotCi0gICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUgdmFsdWUgYXJndW1lbnQKLSAgICAvLyBvZiBzZXRQYXJhbWV0ZXIgbXVzdCBiZSBhIHZhbGlkIEphdmEgT2JqZWN0LgotICAgIHsgRVJfSU5WQUxJRF9TRVRfUEFSQU1fVkFMVUUsCi0gICAgICJcdTUzQzNcdTY1NzggezB9IFx1NzY4NFx1NTAzQ1x1NUZDNVx1OTgwOFx1NjYyRlx1NjcwOVx1NjU0OFx1NzY4NCBKYXZhIFx1NzI2OVx1NEVGNiJ9LAotCi0gICAgeyBFUl9JTlZBTElEX05BTUVTUEFDRV9VUklfVkFMVUVfRk9SX1JFU1VMVF9QUkVGSVhfRk9SX0RFRkFVTFQsCi0gICAgICAieHNsOm5hbWVzcGFjZS1hbGlhcyBcdTUxNDNcdTdEMjBcdTc2ODQgcmVzdWx0LXByZWZpeCBcdTVDNkNcdTYwMjdcdTUxNzdcdTY3MDlcdTUwM0MgJyNkZWZhdWx0J1x1RkYwQ1x1NEY0Nlx1NjYyRlx1NTE0M1x1N0QyMFx1N0JDNFx1NTcwRFx1NEUyRFx1NkM5Mlx1NjcwOVx1OTgxMFx1OEEyRFx1NTQ3RFx1NTQwRFx1N0E3QVx1OTU5M1x1NzY4NFx1NUJBM1x1NTQ0QSJ9LAotCi0gICAgeyBFUl9JTlZBTElEX05BTUVTUEFDRV9VUklfVkFMVUVfRk9SX1JFU1VMVF9QUkVGSVgsCi0gICAgICAieHNsOm5hbWVzcGFjZS1hbGlhcyBcdTUxNDNcdTdEMjBcdTc2ODQgcmVzdWx0LXByZWZpeCBcdTVDNkNcdTYwMjdcdTUxNzdcdTY3MDlcdTUwM0MgJyd7MH0nJ1x1RkYwQ1x1NEY0Nlx1NjYyRlx1NTE0M1x1N0QyMFx1N0JDNFx1NTcwRFx1NEUyRFx1NkM5Mlx1NjcwOVx1NTI0RFx1N0Y2RVx1NzhCQyAnJ3swfScnIFx1NzY4NFx1NTQ3RFx1NTQwRFx1N0E3QVx1OTU5M1x1NUJBM1x1NTQ0QVx1MzAwMiJ9LAotCi0gICAgeyBFUl9TRVRfRkVBVFVSRV9OVUxMX05BTUUsCi0gICAgICAiVHJhbnNmb3JtZXJGYWN0b3J5LnNldEZlYXR1cmUoXHU1QjU3XHU0RTMyXHU1NDBEXHU3QTMxLCBcdTVFMDNcdTY3OTdcdTUwM0MpIFx1NEUyRFx1NzY4NFx1NTI5Rlx1ODBGRFx1NTQwRFx1N0EzMVx1NEUwRFx1NTNFRlx1NzBCQVx1N0E3QVx1NTAzQ1x1MzAwMiJ9LAotCi0gICAgeyBFUl9HRVRfRkVBVFVSRV9OVUxMX05BTUUsCi0gICAgICAiVHJhbnNmb3JtZXJGYWN0b3J5LmdldEZlYXR1cmUoXHU1QjU3XHU0RTMyXHU1NDBEXHU3QTMxKSBcdTRFMkRcdTc2ODRcdTUyOUZcdTgwRkRcdTU0MERcdTdBMzFcdTRFMERcdTUzRUZcdTcwQkFcdTdBN0FcdTUwM0NcdTMwMDIifSwKLQotICAgIHsgRVJfVU5TVVBQT1JURURfRkVBVFVSRSwKLSAgICAgICJcdTcxMjFcdTZDRDVcdTU3MjhcdTZCNjQgVHJhbnNmb3JtZXJGYWN0b3J5IFx1NEUwQVx1OEEyRFx1NUI5QVx1NTI5Rlx1ODBGRCAnJ3swfScnXHUzMDAyIn0sCi0KLSAgICB7IEVSX0VYVEVOU0lPTl9FTEVNRU5UX05PVF9BTExPV0VEX0lOX1NFQ1VSRV9QUk9DRVNTSU5HLAotICAgICAgICAgICJcdTc1NzZcdTVCODlcdTUxNjhcdTg2NTVcdTc0MDZcdTUyOUZcdTgwRkRcdThBMkRcdTcwQkFcdTc3MUZcdTY2NDJcdUZGMENcdTRFMERcdTUxNDFcdThBMzFcdTRGN0ZcdTc1MjhcdTY0RjRcdTUxNDVcdTU5NTdcdTRFRjZcdTUxNDNcdTdEMjAgJyd7MH0nJ1x1MzAwMiJ9LAotCi0gICAgeyBFUl9OQU1FU1BBQ0VfQ09OVEVYVF9OVUxMX05BTUVTUEFDRSwKLSAgICAgICJcdTcxMjFcdTZDRDVcdTUzRDZcdTVGOTdcdTdBN0FcdTUwM0NcdTU0N0RcdTU0MERcdTdBN0FcdTk1OTMgdXJpIFx1NzY4NFx1NTI0RFx1N0Y2RVx1NzhCQ1x1MzAwMiJ9LAotCi0gICAgeyBFUl9OQU1FU1BBQ0VfQ09OVEVYVF9OVUxMX1BSRUZJWCwKLSAgICAgICJcdTcxMjFcdTZDRDVcdTUzRDZcdTVGOTdcdTdBN0FcdTUwM0NcdTUyNERcdTdGNkVcdTc4QkNcdTc2ODRcdTU0N0RcdTU0MERcdTdBN0FcdTk1OTMgdXJpXHUzMDAyIn0sCi0KLSAgICB7IEVSX1hQQVRIX1JFU09MVkVSX05VTExfUU5BTUUsCi0gICAgICAiXHU1MUZEXHU2NTc4XHU1NDBEXHU3QTMxXHU0RTBEXHU1M0VGXHU3MEJBXHU3QTdBXHU1MDNDXHUzMDAyIn0sCi0KLSAgICB7IEVSX1hQQVRIX1JFU09MVkVSX05FR0FUSVZFX0FSSVRZLAotICAgICAgIkFyaXR5IFx1NEUwRFx1NTNFRlx1NzBCQVx1OENBMFx1NTAzQ1x1MzAwMiJ9LAotICAvLyBXYXJuaW5ncy4uLgotCi0gICAgeyBXR19GT1VORF9DVVJMWUJSQUNFLAotICAgICAgIlx1NjI3RVx1NTIzMCAnfSdcdUZGMENcdTRGNDZcdTZDOTJcdTY3MDlcdTk1OEJcdTU1NUZcdTc2ODRcdTVDNkNcdTYwMjdcdTZBMjNcdTY3N0ZcdUZGMDEifSwKLQotICAgIHsgV0dfQ09VTlRfQVRUUklCX01BVENIRVNfTk9fQU5DRVNUT1IsCi0gICAgICAiXHU4QjY2XHU1NDRBOiBcdThBMDhcdTY1NzhcdTVDNkNcdTYwMjdcdTRFMERcdTdCMjZcdTU0MDggeHNsOm51bWJlciBcdTRFMkRcdTc2ODRcdTc5NTZcdTdDRkJcdUZGMDFcdTc2RUVcdTZBMTkgPSB7MH0ifSwKLQotICAgIHsgV0dfRVhQUl9BVFRSSUJfQ0hBTkdFRF9UT19TRUxFQ1QsCi0gICAgICAiXHU4MjBBXHU4QTlFXHU2Q0Q1OiAnZXhwcicgXHU1QzZDXHU2MDI3XHU3Njg0XHU1NDBEXHU3QTMxXHU1REYyXHU4QjhBXHU2NkY0XHU3MEJBICdzZWxlY3QnXHUzMDAyIn0sCi0KLSAgICB7IFdHX05PX0xPQ0FMRV9JTl9GT1JNQVROVU1CRVIsCi0gICAgICAiWGFsYW4gXHU1QzFBXHU2NzJBXHU4NjU1XHU3NDA2IGZvcm1hdC1udW1iZXIgXHU1MUZEXHU2NTc4XHU0RTJEXHU3Njg0XHU1NzMwXHU1MzQwXHU4QTJEXHU1QjlBXHU1NDBEXHU3QTMxXHUzMDAyIn0sCi0KLSAgICB7IFdHX0xPQ0FMRV9OT1RfRk9VTkQsCi0gICAgICAiXHU4QjY2XHU1NDRBOiBcdTYyN0VcdTRFMERcdTUyMzAgeG1sOmxhbmc9ezB9IFx1NzY4NFx1NTczMFx1NTM0MFx1OEEyRFx1NUI5QSJ9LAotCi0gICAgeyBXR19DQU5OT1RfTUFLRV9VUkxfRlJPTSwKLSAgICAgICJcdTcxMjFcdTZDRDVcdTVGOUUgezB9IFx1NUVGQVx1N0FDQiBVUkwifSwKLQotICAgIHsgV0dfQ0FOTk9UX0xPQURfUkVRVUVTVEVEX0RPQywKLSAgICAgICJcdTcxMjFcdTZDRDVcdThGMDlcdTUxNjVcdTg5ODFcdTZDNDJcdTc2ODRcdTY1ODdcdTRFRjY6IHswfSJ9LAotCi0gICAgeyBXR19DQU5OT1RfRklORF9DT0xMQVRPUiwKLSAgICAgICJcdTYyN0VcdTRFMERcdTUyMzAgPHNvcnQgeG1sOmxhbmc9ezB9IFx1NzY4NCBDb2xsYXRvciJ9LAotCi0gICAgeyBXR19GVU5DVElPTlNfU0hPVUxEX1VTRV9VUkwsCi0gICAgICAiXHU4MjBBXHU4QTlFXHU2Q0Q1OiBcdTUxRkRcdTY1NzhcdTYzMDdcdTc5M0FcdTYxQzlcdTRGN0ZcdTc1MjggezB9IFx1NzY4NCB1cmwifSwKLQotICAgIHsgV0dfRU5DT0RJTkdfTk9UX1NVUFBPUlRFRF9VU0lOR19VVEY4LAotICAgICAgIlx1NEUwRFx1NjUyRlx1NjNGNFx1N0RFOFx1NzhCQzogezB9XHVGRjBDXHU0RjdGXHU3NTI4IFVURi04In0sCi0KLSAgICB7IFdHX0VOQ09ESU5HX05PVF9TVVBQT1JURURfVVNJTkdfSkFWQSwKLSAgICAgICJcdTRFMERcdTY1MkZcdTYzRjRcdTdERThcdTc4QkM6IHswfVx1RkYwQ1x1NEY3Rlx1NzUyOCBKYXZhIHsxfSJ9LAotCi0gICAgeyBXR19TUEVDSUZJQ0lUWV9DT05GTElDVFMsCi0gICAgICAiXHU3NjdDXHU3M0ZFXHU2MzA3XHU1QjlBXHU4ODVEXHU3QTgxOiB7MH0gXHU1QzA3XHU0RjdGXHU3NTI4XHU2QTIzXHU1RjBGXHU4ODY4XHU0RTJEXHU2NzAwXHU1RjhDXHU2MjdFXHU1MjMwXHU3Njg0XHU5ODA1XHU3NkVFXHUzMDAyIn0sCi0KLSAgICB7IFdHX1BBUlNJTkdfQU5EX1BSRVBBUklORywKLSAgICAgICI9PT09PT09PT0gXHU1MjU2XHU2NzkwXHU4MjA3XHU2RTk2XHU1MDk5IHswfSA9PT09PT09PT09In0sCi0KLSAgICB7IFdHX0FUVFJfVEVNUExBVEUsCi0gICAgICJcdTVDNkNcdTYwMjdcdTZBMjNcdTY3N0ZcdUZGMEN7MH0ifSwKLQotICAgIHsgV0dfQ09ORkxJQ1RfQkVUV0VFTl9YU0xTVFJJUFNQQUNFX0FORF9YU0xQUkVTRVJWRVNQQUNFLAotICAgICAgInhzbDpzdHJpcC1zcGFjZSBcdTgyMDcgeHNsOnByZXNlcnZlLXNwYWNlIFx1NEU0Qlx1OTU5M1x1OTE0RFx1NUMwRFx1ODg1RFx1N0E4MSJ9LAotCi0gICAgeyBXR19BVFRSSUJfTk9UX0hBTkRMRUQsCi0gICAgICAiWGFsYW4gXHU1QzFBXHU2NzJBXHU4NjU1XHU3NDA2IHswfSBcdTVDNkNcdTYwMjdcdUZGMDEifSwKLQotICAgIHsgV0dfTk9fREVDSU1BTEZPUk1BVF9ERUNMQVJBVElPTiwKLSAgICAgICJcdTYyN0VcdTRFMERcdTUyMzBcdTUzNDFcdTkwMzJcdTRGNERcdTY4M0NcdTVGMEZcdTc2ODRcdTVCQTNcdTU0NEE6IHswfSJ9LAotCi0gICAgeyBXR19PTERfWFNMVF9OUywKLSAgICAgIlx1OTA3QVx1NkYwRlx1NjIxNlx1NEUwRFx1NkI2M1x1NzhCQVx1NzY4NCBYU0xUIFx1NTQ3RFx1NTQwRFx1N0E3QVx1OTU5M1x1MzAwMiJ9LAotCi0gICAgeyBXR19PTkVfREVGQVVMVF9YU0xERUNJTUFMRk9STUFUX0FMTE9XRUQsCi0gICAgICAiXHU1M0VBXHU1MTQxXHU4QTMxXHU0RTAwXHU1MDBCXHU5ODEwXHU4QTJEXHU3Njg0IHhzbDpkZWNpbWFsLWZvcm1hdCBcdTVCQTNcdTU0NEFcdTMwMDIifSwKLQotICAgIHsgV0dfWFNMREVDSU1BTEZPUk1BVF9OQU1FU19NVVNUX0JFX1VOSVFVRSwKLSAgICAgICJ4c2w6ZGVjaW1hbC1mb3JtYXQgXHU1NDBEXHU3QTMxXHU1RkM1XHU5ODA4XHU2NjJGXHU1NTJGXHU0RTAwXHU3Njg0XHU1NDBEXHU3QTMxXHUzMDAyXHU1NDBEXHU3QTMxIFwiezB9XCIgXHU5MUNEXHU4OTA3XHUzMDAyIn0sCi0KLSAgICB7IFdHX0lMTEVHQUxfQVRUUklCVVRFLAotICAgICAgInswfSBcdTUxNzdcdTY3MDlcdTcxMjFcdTY1NDhcdTVDNkNcdTYwMjc6IHsxfSJ9LAotCi0gICAgeyBXR19DT1VMRF9OT1RfUkVTT0xWRV9QUkVGSVgsCi0gICAgICAiXHU3MTIxXHU2Q0Q1XHU4OUUzXHU2NzkwXHU1NDdEXHU1NDBEXHU3QTdBXHU5NTkzXHU1MjREXHU3RjZFXHU3OEJDOiB7MH1cdTMwMDJcdTVDMDdcdTVGRkRcdTc1NjVcdTZCNjRcdTdCQzBcdTlFREVcdTMwMDIifSwKLQotICAgIHsgV0dfU1RZTEVTSEVFVF9SRVFVSVJFU19WRVJTSU9OX0FUVFJJQiwKLSAgICAgICJ4c2w6c3R5bGVzaGVldCBcdTk3MDBcdTg5ODEgJ3ZlcnNpb24nIFx1NUM2Q1x1NjAyN1x1RkYwMSJ9LAotCi0gICAgeyBXR19JTExFR0FMX0FUVFJJQlVURV9OQU1FLAotICAgICAgIlx1NzEyMVx1NjU0OFx1NzY4NFx1NUM2Q1x1NjAyN1x1NTQwRFx1N0EzMTogezB9In0sCi0KLSAgICB7IFdHX0lMTEVHQUxfQVRUUklCVVRFX1ZBTFVFLAotICAgICAgIlx1NzUyOFx1NjVCQ1x1NUM2Q1x1NjAyNyB7MH0gXHU3Njg0XHU3MTIxXHU2NTQ4XHU1MDNDOiB7MX0ifSwKLQotICAgIHsgV0dfRU1QVFlfU0VDT05EX0FSRywKLSAgICAgICJcdTY1ODdcdTRFRjZcdTUxRkRcdTY1NzhcdTdCMkNcdTRFOENcdTUwMEJcdTVGMTVcdTY1NzhcdTc1MjJcdTc1MUZcdTc2ODRcdTdCQzBcdTlFREVcdTk2QzZcdTcwQkFcdTdBN0FcdTc2N0RcdTMwMDJcdTUwQjNcdTU2REVcdTdBN0FcdTc2N0RcdTc2ODQgbm9kZS1zZXRcdTMwMDIifSwKLQotICAvL0ZvbGxvd2luZyBhcmUgdGhlIG5ldyBXQVJOSU5HIGtleXMgYWRkZWQgaW4gWEFMQU4gY29kZSBiYXNlIGFmdGVyIEpkayAxLjQgKFhhbGFuIDIuMi1EMTEpCi0KLSAgICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIm5hbWUiIGFuZCAieHNsOnByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24iIGFyZSBrZXl3b3JkcwotICAgIC8vIGFuZCBtdXN0IG5vdCBiZSB0cmFuc2xhdGVkLgotICAgIHsgV0dfUFJPQ0VTU0lOR0lOU1RSVUNUSU9OX05BTUVfQ0FOVF9CRV9YTUwsCi0gICAgICAieHNsOnByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24gXHU1NDBEXHU3QTMxXHU3Njg0ICduYW1lJyBcdTVDNkNcdTYwMjdcdTUwM0NcdTRFMERcdTUzRUZcdTcwQkEgJ3htbCcifSwKLQotICAgIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAibmFtZSIgYW5kICJ4c2w6cHJvY2Vzc2luZy1pbnN0cnVjdGlvbiIgYXJlIGtleXdvcmRzCi0gICAgLy8gYW5kIG11c3Qgbm90IGJlIHRyYW5zbGF0ZWQuICAiTkNOYW1lIiBpcyBhbiBYTUwgZGF0YS10eXBlIGFuZCBtdXN0IG5vdCBiZQotICAgIC8vIHRyYW5zbGF0ZWQuCi0gICAgeyBXR19QUk9DRVNTSU5HSU5TVFJVQ1RJT05fTk9UVkFMSURfTkNOQU1FLAotICAgICAgInhzbDpwcm9jZXNzaW5nLWluc3RydWN0aW9uIFx1NzY4NCAnJ25hbWUnJyBcdTVDNkNcdTYwMjdcdTUwM0NcdTVGQzVcdTk4MDhcdTY2MkZcdTY3MDlcdTY1NDhcdTc2ODQgTkNOYW1lOiB7MH0ifSwKLQotICAgIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgcmVwb3J0ZWQgaWYgdGhlIHN0eWxlc2hlZXQgdGhhdCBpcwotICAgIC8vIGJlaW5nIHByb2Nlc3NlZCBhdHRlbXB0ZWQgdG8gY29uc3RydWN0IGFuIFhNTCBkb2N1bWVudCB3aXRoIGFuIGF0dHJpYnV0ZSBpbiBhCi0gICAgLy8gcGxhY2Ugb3RoZXIgdGhhbiBvbiBhbiBlbGVtZW50LiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHNwZWNpZmllcyB0aGUgbmFtZSBvZgotICAgIC8vIHRoZSBhdHRyaWJ1dGUuCi0gICAgeyBXR19JTExFR0FMX0FUVFJJQlVURV9QT1NJVElPTiwKLSAgICAgICJcdTU3MjhcdTc1MjJcdTc1MUZcdTVCNTBcdTk4MDVcdTdCQzBcdTlFREVcdTRFNEJcdTVGOENcdUZGMENcdTYyMTZcdTU3MjhcdTc1MjJcdTc1MUZcdTUxNDNcdTdEMjBcdTRFNEJcdTUyNERcdUZGMENcdTRFMERcdTUzRUZcdTY1QjBcdTU4OUVcdTVDNkNcdTYwMjcgezB9XHUzMDAyXHU1QzZDXHU2MDI3XHU2NzAzXHU4OEFCXHU1RkZEXHU3NTY1XHUzMDAyIn0sCi0KLSAgICB7IE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiwKLSAgICAgICJcdTU2MTdcdThBNjZcdTRGRUVcdTY1MzlcdTRFMERcdTUxNDFcdThBMzFcdTRGRUVcdTY1MzlcdTc2ODRcdTcyNjlcdTRFRjZcdTMwMDIiCi0gICAgfSwKLQotICAgIC8vQ2hlY2s6IFdIWSBUSEVSRSBJUyBBIEdBUCBCL1cgTlVNQkVSUyBpbiB0aGUgWFNMVEVycm9yUmVzb3VyY2VzIHByb3BlcnRpZXMgZmlsZT8KLQotICAvLyBPdGhlciBtaXNjZWxsYW5lb3VzIHRleHQgdXNlZCBpbnNpZGUgdGhlIGNvZGUuLi4KLSAgeyAidWlfbGFuZ3VhZ2UiLCAidHcifSwKLSAgeyAgImhlbHBfbGFuZ3VhZ2UiLCAgInR3IiB9LAotICB7ICAibGFuZ3VhZ2UiLCAgInR3IiB9LAotICB7ICJCQURfQ09ERSIsICJjcmVhdGVNZXNzYWdlIFx1NzY4NFx1NTNDM1x1NjU3OFx1OEQ4NVx1NTFGQVx1N0JDNFx1NTcwRCJ9LAotICB7ICAiRk9STUFUX0ZBSUxFRCIsICJtZXNzYWdlRm9ybWF0IFx1NTQ3Q1x1NTNFQlx1NjcxRlx1OTU5M1x1NzY3Q1x1NzUxRlx1NzU3MFx1NUUzOFx1NzJDMFx1NkNDMSJ9LAotICB7ICAidmVyc2lvbiIsICI+Pj4+Pj4+IFhhbGFuIFx1NzI0OFx1NjcyQyAifSwKLSAgeyAgInZlcnNpb24yIiwgICI8PDw8PDw8In0sCi0gIHsgICJ5ZXMiLCAiXHU2NjJGIn0sCi0gIHsgImxpbmUiLCAiXHU4ODRDXHU4NjVGIn0sCi0gIHsgImNvbHVtbiIsIlx1OENDN1x1NjU5OVx1NkIwNFx1N0RFOFx1ODY1RiJ9LAotICB7ICJ4c2xkb25lIiwgIlhTTFByb2Nlc3NvcjogXHU1QjhDXHU2MjEwIn0sCi0KLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlcyBwcm92aWRlIHVzYWdlIGluZm9ybWF0aW9uCi0gIC8vIGZvciB0aGUgWGFsYW4gUHJvY2VzcyBjb21tYW5kIGxpbmUuICAiUHJvY2VzcyIgaXMgdGhlIG5hbWUgb2YgYSBKYXZhIGNsYXNzLAotICAvLyBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLgotICB7ICJ4c2xQcm9jX29wdGlvbiIsICJYYWxhbi1KIFx1NTQ3RFx1NEVFNFx1ODg0Q1x1ODY1NVx1NzQwNlx1NEY1Q1x1Njk2RFx1OTg1RVx1NTIyNVx1OTA3OFx1OTgwNToifSwKLSAgeyAieHNsUHJvY19vcHRpb24iLCAiWGFsYW4tSiBcdTU0N0RcdTRFRTRcdTg4NENcdTg2NTVcdTc0MDZcdTRGNUNcdTY5NkRcdTk4NUVcdTUyMjVcdTkwNzhcdTk4MDU6In0sCi0gIHsgInhzbFByb2NfaW52YWxpZF94c2x0Y19vcHRpb24iLCAiWFNMVEMgXHU2QTIxXHU1RjBGXHU0RTJEXHU0RTBEXHU2NTJGXHU2M0Y0XHU5MDc4XHU5ODA1IHswfVx1MzAwMiJ9LAotICB7ICJ4c2xQcm9jX2ludmFsaWRfeGFsYW5fb3B0aW9uIiwgIlx1OTA3OFx1OTgwNSB7MH0gXHU1M0VBXHU4MEZEXHU4MjA3IC1YU0xUQyBcdTRFMDBcdThENzdcdTRGN0ZcdTc1MjhcdTMwMDIifSwKLSAgeyAieHNsUHJvY19ub19pbnB1dCIsICJcdTkzMkZcdThBQTQ6IFx1NjcyQVx1NjMwN1x1NUI5QVx1NkEyM1x1NUYwRlx1ODg2OFx1NjIxNlx1OEYzOFx1NTE2NSB4bWxcdTMwMDJcdTRFMERcdTRGN0ZcdTc1MjhcdTRFRkJcdTRGNTVcdTkwNzhcdTk4MDVcdTRGODZcdTU3RjdcdTg4NENcdTZCNjRcdTU0N0RcdTRFRTRcdUZGMENcdTUzRUZcdTUzRDZcdTVGOTdcdTc1MjhcdTZDRDVcdTYzMDdcdTc5M0FcdTMwMDIifSwKLSAgeyAieHNsUHJvY19jb21tb25fb3B0aW9ucyIsICItXHU0RTAwXHU4MjJDXHU5MDc4XHU5ODA1LSJ9LAotICB7ICJ4c2xQcm9jX3hhbGFuX29wdGlvbnMiLCAiLVhhbGFuIFx1NzY4NFx1OTA3OFx1OTgwNS0ifSwKLSAgeyAieHNsUHJvY194c2x0Y19vcHRpb25zIiwgIi1YU0xUQyBcdTc2ODRcdTkwNzhcdTk4MDUtIn0sCi0gIHsgInhzbFByb2NfcmV0dXJuX3RvX2NvbnRpbnVlIiwgIihcdTYzMDkgPHJldHVybj4gXHU0RUU1XHU3RTdDXHU3RThDKSJ9LAotCi0gICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiBUaGUgb3B0aW9uIG5hbWUgYW5kIHRoZSBwYXJhbWV0ZXIgbmFtZSBkbyBub3QgbmVlZCB0bwotICAgLy8gYmUgdHJhbnNsYXRlZC4gT25seSB0cmFuc2xhdGUgdGhlIG1lc3NhZ2VzIGluIHBhcmVudGhlc2VzLiAgTm90ZSBhbHNvIHRoYXQKLSAgIC8vIGxlYWRpbmcgd2hpdGVzcGFjZSBpbiB0aGUgbWVzc2FnZXMgaXMgdXNlZCB0byBpbmRlbnQgdGhlIHVzYWdlIGluZm9ybWF0aW9uCi0gICAvLyBmb3IgZWFjaCBvcHRpb24gaW4gdGhlIEVuZ2xpc2ggbWVzc2FnZXMuCi0gICAvLyBEbyBub3QgdHJhbnNsYXRlIHRoZSBrZXl3b3JkczogWFNMVEMsIFNBWCwgRE9NIGFuZCBEVE0uCi0gIHsgIm9wdGlvblhTTFRDIiwgIiAgIFstWFNMVEMgKFx1NEY3Rlx1NzUyOCBYU0xUQyBcdTkwMzJcdTg4NENcdThGNDlcdTYzREIpXSJ9LAotICB7ICJvcHRpb25JTiIsICIgICBbLUlOIGlucHV0WE1MVVJMXSJ9LAotICB7ICJvcHRpb25YU0wiLCAiICAgWy1YU0wgWFNMVHJhbnNmb3JtYXRpb25VUkxdIn0sCi0gIHsgIm9wdGlvbk9VVCIsICAiICAgWy1PVVQgb3V0cHV0RmlsZU5hbWVdIn0sCi0gIHsgIm9wdGlvbkxYQ0lOIiwgIiAgIFstTFhDSU4gY29tcGlsZWRTdHlsZXNoZWV0RmlsZU5hbWVJbl0ifSwKLSAgeyAib3B0aW9uTFhDT1VUIiwgIiAgIFstTFhDT1VUIGNvbXBpbGVkU3R5bGVzaGVldEZpbGVOYW1lT3V0T3V0XSJ9LAotICB7ICJvcHRpb25QQVJTRVIiLCAiICAgWy1QQVJTRVIgXHU1MjU2XHU2NzkwXHU1NjY4XHU4MDZGXHU3RDYxXHU3Njg0XHU1QjhDXHU2NTc0XHU5ODVFXHU1MjI1XHU1NDBEXHU3QTMxXSJ9LAotICB7ICAib3B0aW9uRSIsICIgICBbLUUgKFx1NTJGRlx1NUM1NVx1OTU4Qlx1NTAwQlx1OUFENFx1NTNDM1x1NzE2NyldIn0sCi0gIHsgICJvcHRpb25WIiwgICIgICBbLUUgKFx1NTJGRlx1NUM1NVx1OTU4Qlx1NTAwQlx1OUFENFx1NTNDM1x1NzE2NyldIn0sCi0gIHsgICJvcHRpb25RQyIsICIgICBbLVFDIChcdTk3NUNcdTk3RjNcdTZBMjNcdTVGMEZcdTg4NURcdTdBODFcdThCNjZcdTU0NEEpXSJ9LAotICB7ICAib3B0aW9uUSIsICIgICBbLVEgIChcdTk3NUNcdTk3RjNcdTZBMjFcdTVGMEYpXSJ9LAotICB7ICAib3B0aW9uTEYiLCAiICAgWy1MRiAoXHU4RjM4XHU1MUZBXHU0RTBBXHU1MEM1XHU0RjdGXHU3NTI4XHU2M0RCXHU4ODRDXHU1QjU3XHU1MTQzIHtcdTk4MTBcdThBMkRcdTcwQkEgQ1IvTEZ9KV0ifSwKLSAgeyAgIm9wdGlvbkNSIiwgIiAgIFstQ1IgKFx1OEYzOFx1NTFGQVx1NEUwQVx1NTBDNVx1NEY3Rlx1NzUyOFx1NkI3OFx1NEY0RFx1NUI1N1x1NTE0MyB7XHU5ODEwXHU4QTJEXHU3MEJBIENSL0xGfSldIn0sCi0gIHsgIm9wdGlvbkVTQ0FQRSIsICIgICBbLUVTQ0FQRSAoXHU4OTgxXHU5MDQxXHU5NkUyXHU3Njg0XHU1QjU3XHU1MTQzIHtcdTk4MTBcdThBMkRcdTcwQkEgPD4mXCInXFxyXFxufV0ifSwKLSAgeyAib3B0aW9uSU5ERU5UIiwgIiAgIFstSU5ERU5UIChcdTYzQTdcdTUyMzZcdTg5ODFcdTdFMkVcdTYzOTJcdTc2ODRcdTdBN0FcdTk1OTMge1x1OTgxMFx1OEEyRFx1NzBCQSAwfSldIn0sCi0gIHsgIm9wdGlvblRUIiwgIiAgIFstVFQgKFx1OEZGRFx1OEU2NFx1NTQ3Q1x1NTNFQlx1NzY4NFx1NkEyM1x1Njc3Rlx1MzAwMildIn0sCi0gIHsgIm9wdGlvblRHIiwgIiAgIFstVEcgKFx1OEZGRFx1OEU2NFx1NkJDRlx1NTAwQlx1NzUyMlx1NzUxRlx1NEU4Qlx1NEVGNlx1MzAwMildIn0sCi0gIHsgIm9wdGlvblRTIiwgIiAgIFstVFMgKFx1OEZGRFx1OEU2NFx1NkJDRlx1NTAwQlx1OTA3OFx1NTNENlx1NEU4Qlx1NEVGNlx1MzAwMildIn0sCi0gIHsgICJvcHRpb25UVEMiLCAiICAgWy1UVEMgKFx1OEZGRFx1OEU2NFx1ODY1NVx1NzQwNlx1NzY4NFx1NkEyM1x1Njc3Rlx1NUI1MFx1OTgwNVx1MzAwMildIn0sCi0gIHsgIm9wdGlvblRDTEFTUyIsICIgICBbLVRDTEFTUyAoXHU4RkZEXHU4RTY0XHU2NEY0XHU1MTQ1XHU1OTU3XHU0RUY2XHU3Njg0IFRyYWNlTGlzdGVuZXIgXHU5ODVFXHU1MjI1XHUzMDAyKV0ifSwKLSAgeyAib3B0aW9uVkFMSURBVEUiLCAiICAgWy1WQUxJREFURSAoXHU4QTJEXHU1QjlBXHU2NjJGXHU1NDI2XHU1N0Y3XHU4ODRDXHU5QTU3XHU4QjQ5XHUzMDAyXHU5ODEwXHU4QTJEXHU0RTBEXHU2NzAzXHU1N0Y3XHU4ODRDXHU5QTU3XHU4QjQ5XHUzMDAyKV0ifSwKLSAgeyAib3B0aW9uRURVTVAiLCAiICAgWy1FRFVNUCB7XHU5MDc4XHU2NEM3XHU2MDI3XHU2QTk0XHU2ODQ4XHU1NDBEXHU3QTMxfSAoXHU3NjdDXHU3NTFGXHU5MzJGXHU4QUE0XHU2NjQyXHU2NzAzXHU1N0Y3XHU4ODRDXHU1ODA2XHU3NThBXHU1MEJFXHU1MzcwXHUzMDAyKV0ifSwKLSAgeyAgIm9wdGlvblhNTCIsICIgICBbLVhNTCAoXHU0RjdGXHU3NTI4IFhNTCBcdTY4M0NcdTVGMEZcdTU2NjhcdTRFMjZcdTY1QjBcdTU4OUUgWE1MIFx1NkExOVx1OTgyRFx1MzAwMildIn0sCi0gIHsgICJvcHRpb25URVhUIiwgIiAgIFstVEVYVCAoXHU0RjdGXHU3NTI4XHU3QzIxXHU1NUFFIFRleHQgXHU2ODNDXHU1RjBGXHU1NjY4XHUzMDAyKV0ifSwKLSAgeyAgIm9wdGlvbkhUTUwiLCAiICAgWy1IVE1MIChcdTRGN0ZcdTc1MjggSFRNTCBcdTY4M0NcdTVGMEZcdTU2NjhcdTMwMDIpXSJ9LAotICB7ICAib3B0aW9uUEFSQU0iLCAiICAgWy1QQVJBTSBcdTU0MERcdTdBMzFcdTg4NjhcdTc5M0FcdTVGMEYgKFx1OEEyRFx1NUI5QVx1NkEyM1x1NUYwRlx1ODg2OFx1NTNDM1x1NjU3OCldIn0sCi0gIHsgICJub1BhcnNlcm1zZzEiLCAiWFNMIFx1ODY1NVx1NzQwNlx1NEY1Q1x1Njk2RFx1NTkzMVx1NjU1N1x1MzAwMiJ9LAotICB7ICAibm9QYXJzZXJtc2cyIiwgIioqIFx1NjI3RVx1NEUwRFx1NTIzMFx1NTI1Nlx1Njc5MFx1NTY2OCAqKiJ9LAotICB7ICJub1BhcnNlcm1zZzMiLCAgIlx1OEFDQlx1NkFBMlx1NjdFNVx1OTg1RVx1NTIyNVx1OERFRlx1NUY5MVx1MzAwMiJ9LAotICB7ICJub1BhcnNlcm1zZzQiLCAiXHU4MkU1XHU3MTIxIElCTSBcdTc2ODQgWE1MIFBhcnNlciBmb3IgSmF2YVx1RkYwQ1x1NTNFRlx1NEUwQlx1OEYwOVx1ODFFQSJ9LAotICB7ICJub1BhcnNlcm1zZzUiLCAiSUJNIFx1NzY4NCBBbHBoYVdvcmtzOiBodHRwOi8vd3d3LmFscGhhd29ya3MuaWJtLmNvbS9mb3JtdWxhL3htbCJ9LAotICB7ICJvcHRpb25VUklSRVNPTFZFUiIsICIgICBbLVVSSVJFU09MVkVSIFx1NUI4Q1x1NjU3NFx1OTg1RVx1NTIyNVx1NTQwRFx1N0EzMSAoXHU3NTI4XHU0Rjg2XHU4OUUzXHU2NzkwIFVSSSBcdTc2ODQgVVJJUmVzb2x2ZXIpXSJ9LAotICB7ICJvcHRpb25FTlRJVFlSRVNPTFZFUiIsICAiICAgWy1FTlRJVFlSRVNPTFZFUiBcdTVCOENcdTY1NzRcdTk4NUVcdTUyMjVcdTU0MERcdTdBMzEgKFx1NzUyOFx1NEY4Nlx1ODlFM1x1Njc5MFx1NTAwQlx1OUFENFx1NzY4NCBFbnRpdHlSZXNvbHZlciApXSJ9LAotICB7ICJvcHRpb25DT05URU5USEFORExFUiIsICAiICAgWy1DT05URU5USEFORExFUiBcdTVCOENcdTY1NzRcdTk4NUVcdTUyMjVcdTU0MERcdTdBMzEgKFx1NzUyOFx1NEY4Nlx1NUU4Rlx1NTIxN1x1NTMxNlx1OEYzOFx1NTFGQVx1NzY4NCBDb250ZW50SGFuZGxlcildIn0sCi0gIHsgICJvcHRpb25MSU5FTlVNQkVSUyIsICAiICAgWy1MIFx1NEY3Rlx1NzUyOFx1ODg0Q1x1ODY1Rlx1NjVCQ1x1NEY4Nlx1NkU5MFx1NjU4N1x1NEVGNl0ifSwKLSAgeyAib3B0aW9uU0VDVVJFUFJPQ0VTU0lORyIsICIgICBbLVNFQ1VSRSAoXHU1QzA3XHU1Qjg5XHU1MTY4XHU4NjU1XHU3NDA2XHU1MjlGXHU4MEZEXHU4QTJEXHU3MEJBXHU3NzFGXHUzMDAyKV0ifSwKLQotICAgIC8vIEZvbGxvd2luZyBhcmUgdGhlIG5ldyBvcHRpb25zIGFkZGVkIGluIFhTTFRFcnJvclJlc291cmNlcy5wcm9wZXJ0aWVzIGZpbGVzIGFmdGVyIEpkayAxLjQgKFhhbGFuIDIuMi1EMTEpCi0KLQotICB7ICAib3B0aW9uTUVESUEiLCAgIiAgIFstTUVESUEgbWVkaWFUeXBlIChcdTRGN0ZcdTc1MjhcdTVBOTJcdTlBRDRcdTVDNkNcdTYwMjdcdTRGODZcdTVDMEJcdTYyN0VcdTgyMDdcdTY1ODdcdTRFRjZcdTk1RENcdTgwNkZcdTc2ODRcdTZBMjNcdTVGMEZcdTg4NjhcdTMwMDIpXSJ9LAotICB7ICAib3B0aW9uRkxBVk9SIiwgICIgICBbLUZMQVZPUiBmbGF2b3JOYW1lIChcdTY2MEVcdTc4QkFcdTRGN0ZcdTc1MjggczJzPVNBWCBcdTYyMTYgZDJkPURPTSBcdTRGODZcdTU3RjdcdTg4NENcdThGNDlcdTYzREJcdTMwMDIpXSAifSwgLy8gQWRkZWQgYnkgc2JvYWcvc2N1cmN1cnU7IGV4cGVyaW1lbnRhbAotICB7ICJvcHRpb25ESUFHIiwgIiAgIFstRElBRyAoXHU1MjE3XHU1MzcwXHU4RjQ5XHU2M0RCXHU2MjQwXHU5NzAwXHU4OTgxXHU3Njg0XHU1MTY4XHU5MEU4XHU2QkVCXHU3OUQyXHUzMDAyKV0ifSwKLSAgeyAib3B0aW9uSU5DUkVNRU5UQUwiLCAgIiAgIFstSU5DUkVNRU5UQUwgKFx1OEEyRFx1NUI5QSBodHRwOi8veG1sLmFwYWNoZS5vcmcveGFsYW4vZmVhdHVyZXMvaW5jcmVtZW50YWwgXHU3MEJBXHU3NzFGXHVGRjBDXHU0RUU1XHU4OTgxXHU2QzQyXHU2RjM4XHU5MDMyIERUTSBcdTVFRkFcdTY5Q0JcdTMwMDIpXSJ9LAotICB7ICAib3B0aW9uTk9PUFRJTUlNSVpFIiwgICIgICBbLU5PT1BUSU1JTUlaRSAoXHU4QTJEXHU1QjlBIGh0dHA6Ly94bWwuYXBhY2hlLm9yZy94YWxhbi9mZWF0dXJlcy9vcHRpbWl6ZSBcdTcwQkFcdTUwN0RcdUZGMENcdTRFRTVcdTg5ODFcdTZDNDJcdTcxMjFcdTZBMjNcdTVGMEZcdTg4NjhcdTY3MDBcdTRGNzNcdTUzMTZcdTg2NTVcdTc0MDZcdTMwMDIpXSJ9LAotICB7ICJvcHRpb25STCIsICAiICAgWy1STCByZWN1cnNpb25saW1pdCAoXHU1QkEzXHU1NDRBXHU2QTIzXHU1RjBGXHU4ODY4XHU5MDVFXHU4RkY0XHU2REYxXHU1RUE2XHU3Njg0XHU2NTc4XHU1QjU3XHU5NjUwXHU1MjM2XHUzMDAyKV0ifSwKLSAgeyAgICJvcHRpb25YTyIsICAiICAgWy1YTyBbdHJhbnNsZXROYW1lXSAoXHU2MzA3XHU2RDNFXHU2MjQwXHU3NTIyXHU3NTFGIHRyYW5zbGV0IFx1NzY4NFx1NTQwRFx1N0EzMSldIn0sCi0gIHsgICJvcHRpb25YRCIsICIgICBbLVhEIGRlc3RpbmF0aW9uRGlyZWN0b3J5IChcdTYzMDdcdTVCOUEgdHJhbnNsZXQgXHU3Njg0XHU3NkVFXHU3Njg0XHU1NzMwXHU3NkVFXHU5MzA0KV0ifSwKLSAgeyAgIm9wdGlvblhKIiwgICIgICBbLVhKIGphcmZpbGUgKFx1NUMwMVx1ODhERCB0cmFuc2xldCBcdTk4NUVcdTUyMjVcdTYyMTBcdTcwQkFcdTU0MERcdTdBMzFcdTcwQkEgPGphcmZpbGU+IFx1NzY4NCBqYXIgXHU2QTk0XHU2ODQ4KV0ifSwKLSAgeyAgICJvcHRpb25YUCIsICAiICAgWy1YUCBcdTU5NTdcdTg4RERcdTdBMEJcdTVGMEYgKFx1NjMwN1x1NUI5QVx1NjI0MFx1NjcwOVx1NzUyMlx1NzUxRlx1NzY4NCB0cmFuc2xldCBcdTk4NUVcdTUyMjVcdTc2ODRcdTU5NTdcdTg4RERcdTdBMEJcdTVGMEZcdTU0MERcdTdBMzFcdTUyNERcdTdGNkVcdTc4QkMpXSJ9LAotCi0gIC8vQWRkSVRJT05BTCAgU1RSSU5HUyB0aGF0IG5lZWQgTDEwbgotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIGRlc2NyaWJlcyB1c2FnZSBvZiBhIHBhcnRpY3VsYXIKLSAgLy8gY29tbWFuZC1saW5lIG9wdGlvbiB0aGF0IGlzIHVzZWQgdG8gZW5hYmxlIHRoZSAidGVtcGxhdGUgaW5saW5pbmciCi0gIC8vIG9wdGltaXphdGlvbi4gIFRoZSBvcHRpbWl6YXRpb24gaW52b2x2ZXMgbWFraW5nIGEgY29weSBvZiB0aGUgY29kZQotICAvLyBnZW5lcmF0ZWQgZm9yIGEgdGVtcGxhdGUgaW4gYW5vdGhlciB0ZW1wbGF0ZSB0aGF0IHJlZmVycyB0byBpdC4KLSAgeyAib3B0aW9uWE4iLCAgIiAgIFstWE4gKFx1NTU1Rlx1NzUyOFx1NkEyM1x1Njc3Rlx1NTE2N1x1NUQ0QyldIiB9LAotICB7ICJvcHRpb25YWCIsICAiICAgWy1YWCAoXHU5NThCXHU1NTVGXHU5ODREXHU1OTE2XHU3Njg0XHU5NjY0XHU5MzJGXHU4QTBBXHU2MDZGXHU4RjM4XHU1MUZBKV0ifSwKLSAgeyAib3B0aW9uWFQiICwgIiAgIFstWFQgKFx1ODJFNVx1NjcwOVx1NTNFRlx1ODBGRFx1RkYwQ1x1NEY3Rlx1NzUyOCB0cmFuc2xldCBcdTRGODZcdThGNDlcdTYzREIpXSJ9LAotICB7ICJkaWFnVGltaW5nIiwiIC0tLS0tLS0tLSBcdTdEOTNcdTc1MzEgezF9IFx1NzY4NCB7MH0gXHU4RjQ5XHU2M0RCXHU2Qjc3XHU2NjQyIHsyfSBcdTZCRUJcdTc5RDIiIH0sCi0gIHsgInJlY3Vyc2lvblRvb0RlZXAiLCJcdTZBMjNcdTY3N0ZcdTVERTJcdTcyQzBcdTdENTBcdTY5Q0JcdTkwNEVcdTZERjFcdTMwMDJcdTVERTJcdTcyQzBcdTdENTBcdTY5Q0IgPSB7MH1cdUZGMENcdTZBMjNcdTY3N0YgezF9IHsyfSIgfSwKLSAgeyAibmFtZUlzIiwgIlx1NTQwRFx1N0EzMVx1NzBCQSIgfSwKLSAgeyAibWF0Y2hQYXR0ZXJuSXMiLCAiXHU5MTREXHU1QzBEXHU2QTIzXHU1RjBGXHU3MEJBIiB9Ci0KLSAgfTsKLQotICB9Ci0gIC8vID09PT09PT09PT09PT09PT09IElORlJBU1RSVUNUVVJFID09PT09PT09PT09PT09PT09PT09PT0KLQotICAvKiogU3RyaW5nIGZvciB1c2Ugd2hlbiBhIGJhZCBlcnJvciBjb2RlIHdhcyBlbmNvdW50ZXJlZC4gICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQkFEX0NPREUgPSAiQkFEX0NPREUiOwotCi0gIC8qKiBTdHJpbmcgZm9yIHVzZSB3aGVuIGZvcm1hdHRpbmcgb2YgdGhlIGVycm9yIHN0cmluZyBmYWlsZWQuICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRk9STUFUX0ZBSUxFRCA9ICJGT1JNQVRfRkFJTEVEIjsKLQotICAvKiogR2VuZXJhbCBlcnJvciBzdHJpbmcuICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJST1JfU1RSSU5HID0gIiNlcnJvciI7Ci0KLSAgLyoqIFN0cmluZyB0byBwcmVwZW5kIHRvIGVycm9yIG1lc3NhZ2VzLiAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJST1JfSEVBREVSID0gIkVycm9yOiAiOwotCi0gIC8qKiBTdHJpbmcgdG8gcHJlcGVuZCB0byB3YXJuaW5nIG1lc3NhZ2VzLiAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXQVJOSU5HX0hFQURFUiA9ICJXYXJuaW5nOiAiOwotCi0gIC8qKiBTdHJpbmcgdG8gc3BlY2lmeSB0aGUgWFNMVCBtb2R1bGUuICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBYU0xfSEVBREVSID0gIlhTTFQgIjsKLQotICAvKiogU3RyaW5nIHRvIHNwZWNpZnkgdGhlIFhNTCBwYXJzZXIgbW9kdWxlLiAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MX0hFQURFUiA9ICJYTUwgIjsKLQotICAvKiogSSBkb24ndCB0aGluayB0aGlzIGlzIHVzZWQgYW55IG1vcmUuCi0gICAqIEBkZXByZWNhdGVkICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBRVUVSWV9IRUFERVIgPSAiUEFUVEVSTiAiOwotCi0KLSAgICB9CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3Jlcy9YU0xUSW5mby5wcm9wZXJ0aWVzIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC9yZXMvWFNMVEluZm8ucHJvcGVydGllcwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZDQ1ZDAzMy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3Jlcy9YU0xUSW5mby5wcm9wZXJ0aWVzCisrKyAvZGV2L251bGwKQEAgLTEsMzIgKzAsMCBAQAotIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCi0jIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSMgRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwotIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCi0jIENvcHlyaWdodCAyMDAwLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotIwotIyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSMgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotIyBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSMKLSMgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotIwotIyBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0jIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0jIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotIyBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0jIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKLSMKLSMgJElkOiBYU0xUSW5mby5wcm9wZXJ0aWVzLHYgMS4xLjIuMSAyMDA1LzA4LzAxIDAyOjEwOjQ4IGplZmZzdXR0b3IgRXhwICQKLSMKLSMgIFhTTFQgUmVzb3VyY2UgRmlsZQotIwotCi12ZW5kb3I9QXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KLXZlbmRvci11cmw9aHR0cDovL3htbC5hcGFjaGUub3JnL3hhbGFuLWoKLQotIyBQcm9kdWN0IFZlcnNpb246IFhhbGFuLUphdmEgQGltcGwudmVyc2lvbkAKLQotIyBXM0MgWFNMIFRyYW5zZm9ybWF0aW9ucyAoWFNMVCkgVmVyc2lvbiAxLjAKLXZlcnNpb249MS4wCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3Jlcy9wYWNrYWdlLmh0bWwgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3Jlcy9wYWNrYWdlLmh0bWwKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGZhYzgyZDIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC9yZXMvcGFja2FnZS5odG1sCisrKyAvZGV2L251bGwKQEAgLTEsMjggKzAsMCBAQAotPCEtLQotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLS0tPgotPCEtLQotICogQ29weXJpZ2h0IDIwMDAtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0tLT4KLTwhLS0gJElkOiBwYWNrYWdlLmh0bWwsdiAxLjEuMi4xIDIwMDUvMDgvMDEgMDI6MTA6NDkgamVmZnN1dHRvciBFeHAgJCAtLT4KLTxodG1sPgotICA8dGl0bGU+WGFsYW4gcmVzb3VyY2UgUGFja2FnZS48L3RpdGxlPgotICA8Ym9keT4KLSAgICA8cD5Db250YWlucyBzdHJpbmdzIHRoYXQgcmVxdWlyZSBpbnRlcm5hdGlvbmFsaXphdGlvbi48cD4KLSA8L2JvZHk+Ci08L2h0bWw+Ci0KLQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC90ZW1wbGF0ZXMvQ29uc3RhbnRzLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3RlbXBsYXRlcy9Db25zdGFudHMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZTRjNzUzOS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3RlbXBsYXRlcy9Db25zdGFudHMuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQwMSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBDb25zdGFudHMuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xMCAxOTo1MDo1NiBqZWZmc3V0dG9yIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnRlbXBsYXRlczsKLQotCi0vKioKLSAqIFByaW1hcnkgY29uc3RhbnRzIHVzZWQgaW4gdGhlIFRyYW5zZm9ybWVySW1wbCBjbGFzc2VzLgotICogQHhzbC51c2FnZSBhZHZhbmNlZAotICovCi1wdWJsaWMgY2xhc3MgQ29uc3RhbnRzIGV4dGVuZHMgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5Db25zdGFudHMKLXsKLQotICAvKioKLSAgICogSURzIGZvciBYU0wgZWxlbWVudCB0eXBlcy4gVGhlc2UgYXJlIGFzc29jaWF0ZWQKLSAgICogd2l0aCB0aGUgc3RyaW5nIGxpdGVyYWxzIGluIHRoZSBUcmFuc2Zvcm1lckltcGwgY2xhc3MuCi0gICAqIERvbid0IGNoYW5nZSB0aGUgbnVtYmVycy4gTk9URSBUSEFUIFRIRVNFIEFSRSBOT1QgSU4KLSAgICogQUxQSEFCRVRJQ0FMIE9SREVSIQotICAgKiAoSXQncyBhIHBpdHkgSmF2YSBkb2Vzbid0IGhhdmUgYSByZWFsIEVudW1lcmF0ZWQgTW5lbW9uaWMKLSAgICogZGF0YXR5cGUuLi4gb3IgYSBDLWxpa2UgcHJlcHJvY2Vzc29yIGluIGxpZXUgdGhlcmVvZiB3aGljaAotICAgKiBjb3VsZCBiZSB1c2VkIHRvIGdlbmVyYXRlIGFuZCBtYWludGFpbiBzeW5jaCBiZXR3ZWVuIHRoZXNlIGxpc3RzLikKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVMRU1OQU1FX1VOREVGSU5FRCA9IC0xLCBFTEVNTkFNRV9XSVRIUEFSQU0gPSAyLAotICAgICAgICAgICAgICAgICAgICAgICAgICBFTEVNTkFNRV9BRERBVFRSSUJVVEUgPSA0LCBFTEVNTkFNRV9BTkNIT1IgPSAyMiwKLQotICAvLyAgRUxFTU5BTUVfQU5DSE9SX1BBVFRFUk4gPSAyMywKLSAgRUxFTU5BTUVfQVBQTFlfVEVNUExBVEVTID0gNTAsIEVMRU1OQU1FX1VTRSA9IDM0LCBFTEVNTkFNRV9DSElMRFJFTiA9IDYsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFTEVNTkFNRV9DSE9PU0UgPSAzNywgRUxFTU5BTUVfQ09NTUVOVCA9IDU5LCAgLy8gbXkgb3duCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFTEVNTkFNRV9DT05TVFJVQ1QgPSA3LCAgLy8gbXkgb3duCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFTEVNTkFNRV9DT05URU5UUyA9IDgsIEVMRU1OQU1FX0NPUFkgPSA5LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRUxFTU5BTUVfQ09QWV9PRiA9IDc0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRUxFTU5BTUVfREVDSU1BTEZPUk1BVCA9IDgzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRUxFTU5BTUVfREVGSU5FQVRUUklCVVRFU0VUID0gNDAsCi0KLSAgLy8gIEVMRU1OQU1FX0RFRklORUNPTlNUQU5UID0gMjksCi0gIC8vICBFTEVNTkFNRV9ERUZJTkVNQUNSTyA9IDEwLAotICBFTEVNTkFNRV9ERUZJTkVTQ1JJUFQgPSAxMSwgRUxFTU5BTUVfRElTUExBWUlGID0gMTIsICAvLyBteSBvd24KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVMRU1OQU1FX0VNUFRZID0gMTQsIEVMRU1OQU1FX0VWQUwgPSAxNSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVMRU1OQU1FX0VYUEVDVEVEQ0hJTERSRU4gPSAxNiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVMRU1OQU1FX0VYVEVOU0lPTiA9IDU0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRUxFTU5BTUVfRVhURU5TSU9OSEFORExFUiA9IDYzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRUxFTU5BTUVfRk9SRUFDSCA9IDI4LCBFTEVNTkFNRV9LRVkgPSAzMSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVMRU1OQU1FX0lGID0gMzYsIEVMRU1OQU1FX0lNUE9SVCA9IDI2LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRUxFTU5BTUVfSU5DTFVERSA9IDI3LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRUxFTU5BTUVfQ0FMTFRFTVBMQVRFID0gMTcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFTEVNTkFNRV9QQVJBTVZBUklBQkxFID0gNDEsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFTEVNTkFNRV9OVU1CRVIgPSAzNSwgRUxFTU5BTUVfTlNBTElBUyA9IDg0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRUxFTU5BTUVfT1RIRVJXSVNFID0gMzksIEVMRU1OQU1FX1BJID0gNTgsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFTEVNTkFNRV9QUkVTRVJWRVNQQUNFID0gMzMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFTEVNTkFNRV9SRU1PVkVBVFRSSUJVVEUgPSA1LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRUxFTU5BTUVfVEVNUExBVEUgPSAxOSwgRUxFTU5BTUVfU09SVCA9IDY0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRUxFTU5BTUVfU1RSSVBTUEFDRSA9IDMyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRUxFTU5BTUVfU1RZTEVTSEVFVCA9IDI1LCBFTEVNTkFNRV9URVhUID0gNDIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFTEVNTkFNRV9WQUxVRU9GID0gMzAsIEVMRU1OQU1FX1dIRU4gPSAzOCwKLQotICAvLyBQYXR0ZXJuIGJ5IGV4YW1wbGUgc3VwcG9ydAotICBFTEVNTkFNRV9ST09UID0gNDQsIEVMRU1OQU1FX0FOWSA9IDQ1LCBFTEVNTkFNRV9FTEVNRU5UID0gNDYsCi0gICAgICAgICAgICAgICAgICAgICAgRUxFTU5BTUVfVEFSR0VURUxFTUVOVCA9IDQ3LCBFTEVNTkFNRV9BVFRSSUJVVEUgPSA0OCwKLSAgICAgICAgICAgICAgICAgICAgICBFTEVNTkFNRV9UQVJHRVRBVFRSSUJVVEUgPSA0OSwgRUxFTU5BTUVfVVJMID0gNTIsICAvLyBteSBvd24KLSAgICAgICAgICAgICAgICAgICAgICBFTEVNTkFNRV9DQUxMID0gNTUsICAvLyBteSBvd24KLQotICAvLyAgRUxFTU5BTUVfV0lUSFBBUkFNID0gNTYsCi0gIEVMRU1OQU1FX0ZBTExCQUNLID0gNTcsICAvLyBteSBvd24KLSAgRUxFTU5BTUVfVEFSR0VUUEkgPSA2MCwgIC8vIG15IG93bgotICBFTEVNTkFNRV9UQVJHRVRDT01NRU5UID0gNjEsICAvLyBteSBvd24KLSAgRUxFTU5BTUVfVEFSR0VUVEVYVCA9IDYyLCAgLy8gbXkgb3duCi0gIEVMRU1OQU1FX0NTU1NUWUxFQ09OVkVSU0lPTiA9IDY1LCAgLy8gbXkgb3duCi0gIEVMRU1OQU1FX0NPVU5URVIgPSA2NiwgRUxFTU5BTUVfQ09VTlRFUlMgPSA2NywKLSAgRUxFTU5BTUVfQ09VTlRFUklOQ1JFTUVOVCA9IDY4LCBFTEVNTkFNRV9DT1VOVEVSUkVTRVQgPSA2OSwKLSAgRUxFTU5BTUVfQ09VTlRFUlNDT1BFID0gNzEsIEVMRU1OQU1FX0FQUExZX0lNUE9SVFMgPSA3MiwKLSAgRUxFTU5BTUVfVkFSSUFCTEUgPSA3MywgRUxFTU5BTUVfTUVTU0FHRSA9IDc1LCBFTEVNTkFNRV9MT0NBTEUgPSA3NiwKLSAgRUxFTU5BTUVfTElURVJBTFJFU1VMVCA9IDc3LCBFTEVNTkFNRV9URVhUTElURVJBTFJFU1VMVCA9IDc4LAotICBFTEVNTkFNRV9FWFRFTlNJT05DQUxMID0gNzksIEVMRU1OQU1FX0VYVEVOU0lPTkRFQ0wgPSA4NSwKLSAgRUxFTU5BTUVfRVhURU5TSU9OU0NSSVBUID0gODYsIEVMRU1OQU1FX09VVFBVVCA9IDgwLAotICBFTEVNTkFNRV9DT01QT05FTlQgPSA4MSwgRUxFTU5BTUVfU0NSSVBUID0gODI7Ci0KLSAgLy8gTmV4dCBmcmVlIG51bWJlcjogOTAgKDg4IGFuZCA4OSB1c2VkIGZvciBFWFNMVCBlbGVtZW50cyk7Ci0KLSAgLyoqCi0gICAqIExpdGVyYWxzIGZvciBYU0wgZWxlbWVudCBuYW1lcy4gIE5vdGUgdGhhdCB0aGVyZSBhcmUgbW9yZQotICAgKiBuYW1lcyB0aGFuIElEcywgYmVjYXVzZSBzb21lIG5hbWVzIG1hcCB0byB0aGUgc2FtZSBJRC4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nCi0gICAgICAgICAgRUxFTU5BTUVfQU5DSE9SX1NUUklORyA9ICJhbmNob3IiLAotICAgICAgRUxFTU5BTUVfQU5ZX1NUUklORyA9ICJhbnkiLCAgLy8gcGF0dGVybi1ieS1leGFtcGxlIHN1cHBvcnQKLSAgICAgIEVMRU1OQU1FX0FQUExZX0lNUE9SVFNfU1RSSU5HID0gImFwcGx5LWltcG9ydHMiLAotICAgICAgRUxFTU5BTUVfQVBQTFlfVEVNUExBVEVTX1NUUklORyA9ICJhcHBseS10ZW1wbGF0ZXMiLAotICAgICAgRUxFTU5BTUVfQVJHX1NUUklORyA9ICJhcmciLAotICAgICAgRUxFTU5BTUVfQVRUUklCVVRFU0VUX1NUUklORyA9ICJhdHRyaWJ1dGUtc2V0IiwKLSAgICAgIEVMRU1OQU1FX0FUVFJJQlVURV9TVFJJTkcgPSAiYXR0cmlidXRlIiwgIC8vIHBhdHRlcm4tYnktZXhhbXBsZSBzdXBwb3J0Ci0gICAgICBFTEVNTkFNRV9DQUxMVEVNUExBVEVBUkdfU1RSSU5HID0gImludm9rZS1hcmciLAotICAgICAgRUxFTU5BTUVfQ0FMTFRFTVBMQVRFX1NUUklORyA9ICJjYWxsLXRlbXBsYXRlIiwKLSAgICAgIEVMRU1OQU1FX0NBTExfU1RSSU5HID0gImNhbGwiLAotICAgICAgRUxFTU5BTUVfQ0hJTERSRU5fU1RSSU5HID0gImNoaWxkcmVuIiwKLSAgICAgIEVMRU1OQU1FX0NIT09TRV9TVFJJTkcgPSAiY2hvb3NlIiwKLSAgICAgIEVMRU1OQU1FX0NPTU1FTlRfU1RSSU5HID0gImNvbW1lbnQiLAotICAgICAgRUxFTU5BTUVfQ09NUE9ORU5UX1NUUklORyA9ICJjb21wb25lbnQiLAotICAgICAgRUxFTU5BTUVfQ09OU1RSVUNUX1NUUklORyA9ICJjb25zdHJ1Y3QiLCAgLy8gbXkgb3duCi0gICAgICBFTEVNTkFNRV9DT05URU5UU19TVFJJTkcgPSAiY29udGVudHMiLAotICAgICAgRUxFTU5BTUVfQ09QWV9PRl9TVFJJTkcgPSJjb3B5LW9mIiwKLSAgICAgIEVMRU1OQU1FX0NPUFlfU1RSSU5HID0gImNvcHkiLAotICAgICAgRUxFTU5BTUVfQ09VTlRFUklOQ1JFTUVOVF9TVFJJTkcgPSAiY291bnRlci1pbmNyZW1lbnQiLAotICAgICAgRUxFTU5BTUVfQ09VTlRFUlJFU0VUX1NUUklORyA9ICJjb3VudGVyLXJlc2V0IiwKLSAgICAgIEVMRU1OQU1FX0NPVU5URVJTQ09QRV9TVFJJTkcgPSAiY291bnRlci1zY29wZSIsCi0gICAgICBFTEVNTkFNRV9DT1VOVEVSU19TVFJJTkcgPSAiY291bnRlcnMiLAotICAgICAgRUxFTU5BTUVfQ09VTlRFUl9TVFJJTkcgPSAiY291bnRlciIsCi0gICAgICBFTEVNTkFNRV9DU1NTVFlMRUNPTlZFUlNJT05fU1RSSU5HID0gImNzcy1zdHlsZS1jb252ZXJzaW9uIiwKLSAgICAgIEVMRU1OQU1FX0RFQ0lNQUxGT1JNQVRfU1RSSU5HID0gImRlY2ltYWwtZm9ybWF0IiwKLSAgICAgIEVMRU1OQU1FX0RJU1BMQVlJRl9TVFJJTkcgPSAiZGlzcGxheS1pZiIsICAvLyBteSBvd24KLSAgICAgIEVMRU1OQU1FX0VMRU1FTlRfU1RSSU5HID0gImVsZW1lbnQiLCAgLy8gcGF0dGVybi1ieS1leGFtcGxlIHN1cHBvcnQKLSAgICAgIEVMRU1OQU1FX0VNUFRZX1NUUklORyA9ICJlbXB0eSIsCi0gICAgICBFTEVNTkFNRV9FVkFMX1NUUklORyA9ICJldmFsIiwKLSAgICAgIEVMRU1OQU1FX0VYUEVDVEVEQ0hJTERSRU5fU1RSSU5HID0gImV4cGVjdGVkY2hpbGRyZW4iLAotICAgICAgRUxFTU5BTUVfRVhURU5TSU9OSEFORExFUl9TVFJJTkcgPSAiY29kZS1kaXNwYXRjaGVyIiwKLSAgICAgIEVMRU1OQU1FX0VYVEVOU0lPTl9TVFJJTkcgPSAiZnVuY3Rpb25zIiwKLSAgICAgIEVMRU1OQU1FX0ZBTExCQUNLX1NUUklORyA9ICJmYWxsYmFjayIsCi0gICAgICBFTEVNTkFNRV9GT1JFQUNIX1NUUklORyA9ICJmb3ItZWFjaCIsCi0gICAgICBFTEVNTkFNRV9JRl9TVFJJTkcgPSAiaWYiLAotICAgICAgRUxFTU5BTUVfSU1QT1JUX1NUUklORyA9ICJpbXBvcnQiLAotICAgICAgRUxFTU5BTUVfSU5DTFVERV9TVFJJTkcgPSAiaW5jbHVkZSIsCi0gICAgICBFTEVNTkFNRV9LRVlfU1RSSU5HID0gImtleSIsCi0gICAgICBFTEVNTkFNRV9MT0NBTEVfU1RSSU5HID0gImxvY2FsZSIsCi0gICAgICBFTEVNTkFNRV9NRVNTQUdFX1NUUklORyA9ICJtZXNzYWdlIiwKLSAgICAgIEVMRU1OQU1FX05TQUxJQVNfU1RSSU5HID0gIm5hbWVzcGFjZS1hbGlhcyIsCi0gICAgICBFTEVNTkFNRV9OVU1CRVJfU1RSSU5HID0gIm51bWJlciIsCi0gICAgICBFTEVNTkFNRV9PVEhFUldJU0VfU1RSSU5HID0gIm90aGVyd2lzZSIsCi0gICAgICBFTEVNTkFNRV9PVVRQVVRfU1RSSU5HID0gIm91dHB1dCIsCi0gICAgICBFTEVNTkFNRV9QQVJBTVZBUklBQkxFX1NUUklORyA9ICJwYXJhbSIsCi0gICAgICBFTEVNTkFNRV9QSV9PTERfU1RSSU5HID0gInBpIiwKLSAgICAgIEVMRU1OQU1FX1BJX1NUUklORyA9ICJwcm9jZXNzaW5nLWluc3RydWN0aW9uIiwKLSAgICAgIEVMRU1OQU1FX1BSRVNFUlZFU1BBQ0VfU1RSSU5HID0gInByZXNlcnZlLXNwYWNlIiwKLSAgICAgIEVMRU1OQU1FX1JPT1RfU1RSSU5HID0gInJvb3QiLCAgLy8gcGF0dGVybi1ieS1leGFtcGxlIHN1cHBvcnQKLSAgICAgIEVMRU1OQU1FX1NDUklQVF9TVFJJTkcgPSAic2NyaXB0IiwKLSAgICAgIEVMRU1OQU1FX1NPUlRfU1RSSU5HID0gInNvcnQiLAotICAgICAgRUxFTU5BTUVfU1RSSVBTUEFDRV9TVFJJTkcgPSAic3RyaXAtc3BhY2UiLAotICAgICAgRUxFTU5BTUVfU1RZTEVTSEVFVF9TVFJJTkcgPSAic3R5bGVzaGVldCIsCi0gICAgICBFTEVNTkFNRV9UQVJHRVRBVFRSSUJVVEVfU1RSSU5HID0gInRhcmdldC1hdHRyaWJ1dGUiLCAgLy8gcGF0dGVybi1ieS1leGFtcGxlIHN1cHBvcnQKLSAgICAgIEVMRU1OQU1FX1RBUkdFVENPTU1FTlRfU1RSSU5HID0gInRhcmdldC1jb21tZW50IiwKLSAgICAgIEVMRU1OQU1FX1RBUkdFVEVMRU1FTlRfU1RSSU5HID0gInRhcmdldC1lbGVtZW50IiwgIC8vIHBhdHRlcm4tYnktZXhhbXBsZSBzdXBwb3J0Ci0gICAgICBFTEVNTkFNRV9UQVJHRVRQSV9TVFJJTkcgPSAidGFyZ2V0LXBpIiwKLSAgICAgIEVMRU1OQU1FX1RBUkdFVFRFWFRfU1RSSU5HID0gInRhcmdldC10ZXh0IiwKLSAgICAgIEVMRU1OQU1FX1RFTVBMQVRFX1NUUklORyA9ICJ0ZW1wbGF0ZSIsCi0gICAgICBFTEVNTkFNRV9URVhUX1NUUklORyA9ICJ0ZXh0IiwKLSAgICAgIEVMRU1OQU1FX1RSQU5TRk9STV9TVFJJTkcgPSAidHJhbnNmb3JtIiwKLSAgICAgIEVMRU1OQU1FX1VSTF9TVFJJTkcgPSAidXJpIiwgIC8vIHBhdHRlcm4tYnktZXhhbXBsZSBzdXBwb3J0Ci0gICAgICBFTEVNTkFNRV9VU0VfU1RSSU5HID0gInVzZSIsCi0gICAgICBFTEVNTkFNRV9WQUxVRU9GX1NUUklORyA9ICJ2YWx1ZS1vZiIsCi0gICAgICBFTEVNTkFNRV9WQVJJQUJMRV9TVFJJTkcgPSAidmFyaWFibGUiLAotICAgICAgRUxFTU5BTUVfV0hFTl9TVFJJTkcgPSAid2hlbiIsCi0gICAgICBFTEVNTkFNRV9XSVRIUEFSQU1fU1RSSU5HID0gIndpdGgtcGFyYW0iOwotCi0gIC8qKgotICAgKiBMaXRlcmFscyBmb3IgRVhTTFQgZnVuY3Rpb24gZWxlbWVudHMuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZwotICAgIEVYU0xUX0VMRU1OQU1FX0ZVTkNUSU9OX1NUUklORyA9ICJmdW5jdGlvbiIsCi0gICAgRVhTTFRfRUxFTU5BTUVfRlVOQ1JFU1VMVF9TVFJJTkcgPSAicmVzdWx0IjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQKLSAgICBFWFNMVF9FTEVNTkFNRV9GVU5DVElPTiA9IDg4LAotICAgIEVYU0xUX0VMRU1OQU1FX0ZVTkNSRVNVTFQgPSA4OTsKLQotCi0gIC8qKgotICAgKiBMaXRlcmFscyBmb3IgWFNMIGF0dHJpYnV0ZSBuYW1lcy4gIE5vdGUgdGhhdCB0aGVyZSBtYXkgYmUgbW9yZQotICAgKiBuYW1lcyB0aGFuIElEcywgYmVjYXVzZSBzb21lIG5hbWVzIG1heSBtYXAgdG8gdGhlIHNhbWUgSUQuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZwotICAgICAgICAgIEFUVFJOQU1FX0FNT1VOVCA9ICJhbW91bnQiLAotICAgICAgQVRUUk5BTUVfQU5DRVNUT1IgPSAiYW5jZXN0b3IiLAotICAgICAgQVRUUk5BTUVfQVJDSElWRSA9ICJhcmNoaXZlIiwKLSAgICAgIEFUVFJOQU1FX0FUVFJJQlVURSA9ICJhdHRyaWJ1dGUiLAotICAgICAgQVRUUk5BTUVfQVRUUklCVVRFX1NFVCA9ICJhdHRyaWJ1dGUtc2V0IiwKLSAgICAgIEFUVFJOQU1FX0NBU0VPUkRFUiA9ICJjYXNlLW9yZGVyIiwKLSAgICAgIEFUVFJOQU1FX0NMQVNTID0gImNsYXNzIiwKLSAgICAgIEFUVFJOQU1FX0NMQVNTSUQgPSAiY2xhc3NpZCIsCi0gICAgICBBVFRSTkFNRV9DT0RFQkFTRSA9ICJjb2RlYmFzZSIsCi0gICAgICBBVFRSTkFNRV9DT0RFVFlQRSA9ICJ0eXBlIiwKLSAgICAgIEFUVFJOQU1FX0NPTkRJVElPTiA9ICJjb25kaXRpb24iLAotICAgICAgQVRUUk5BTUVfQ09QWVRZUEUgPSAiY29weS10eXBlIiwKLSAgICAgIEFUVFJOQU1FX0NPVU5UID0gImNvdW50IiwKLSAgICAgIEFUVFJOQU1FX0RBVEFUWVBFID0gImRhdGEtdHlwZSIsCi0gICAgICBBVFRSTkFNRV9ERUNJTUFMU0VQQVJBVE9SID0gImRlY2ltYWwtc2VwYXJhdG9yIiwKLSAgICAgIEFUVFJOQU1FX0RFRkFVTFQgPSAiZGVmYXVsdCIsCi0gICAgICBBVFRSTkFNRV9ERUZBVUxUU1BBQ0UgPSAiZGVmYXVsdC1zcGFjZSIsCi0gICAgICBBVFRSTkFNRV9ERVBUSCA9ICJ3aXRoLWNoaWxkcmVuIiwKLSAgICAgIEFUVFJOQU1FX0RJR0lUID0gImRpZ2l0IiwKLSAgICAgIEFUVFJOQU1FX0RJR0lUR1JPVVBTRVAgPSAiZGlnaXQtZ3JvdXAtc2VwIiwKLSAgICAgIEFUVFJOQU1FX0RJU0FCTEVfT1VUUFVUX0VTQ0FQSU5HID0gImRpc2FibGUtb3V0cHV0LWVzY2FwaW5nIiwKLSAgICAgIEFUVFJOQU1FX0VMRU1FTlQgPSAiZWxlbWVudCIsCi0gICAgICBBVFRSTkFNRV9FTEVNRU5UUyA9ICJlbGVtZW50cyIsCi0gICAgICBBVFRSTkFNRV9FWENMVURFX1JFU1VMVF9QUkVGSVhFUyA9ImV4Y2x1ZGUtcmVzdWx0LXByZWZpeGVzIiwKLSAgICAgIEFUVFJOQU1FX0VYUFIgPSAiZXhwciIsCi0gICAgICBBVFRSTkFNRV9FWFRFTlNJT05FTEVNRU5UUFJFRklYRVMgPSAiZXh0ZW5zaW9uLWVsZW1lbnQtcHJlZml4ZXMiLAotICAgICAgQVRUUk5BTUVfRk9STUFUID0gImZvcm1hdCIsCi0gICAgICBBVFRSTkFNRV9GUk9NID0gImZyb20iLAotICAgICAgQVRUUk5BTUVfR1JPVVBJTkdTRVBBUkFUT1IgPSAiZ3JvdXBpbmctc2VwYXJhdG9yIiwKLSAgICAgIEFUVFJOQU1FX0dST1VQSU5HU0laRSA9ICJncm91cGluZy1zaXplIiwKLSAgICAgIEFUVFJOQU1FX0hSRUYgPSAiaHJlZiIsCi0gICAgICBBVFRSTkFNRV9JRCA9ICJpZCIsCi0gICAgICBBVFRSTkFNRV9JTVBPUlRBTkNFID0gImltcG9ydGFuY2UiLAotICAgICAgQVRUUk5BTUVfSU5ERU5UUkVTVUxUID0gImluZGVudC1yZXN1bHQiLAotICAgICAgQVRUUk5BTUVfSU5GSU5JVFkgPSAiaW5maW5pdHkiLAotICAgICAgQVRUUk5BTUVfTEFORyA9ICJsYW5nIiwKLSAgICAgIEFUVFJOQU1FX0xFVFRFUlZBTFVFID0gImxldHRlci12YWx1ZSIsCi0gICAgICBBVFRSTkFNRV9MRVZFTCA9ICJsZXZlbCIsCi0gICAgICBBVFRSTkFNRV9NQVRDSCA9ICJtYXRjaCIsCi0gICAgICBBVFRSTkFNRV9NRVRIT0QgPSAiY2FsbHMiLAotICAgICAgQVRUUk5BTUVfTUlOVVNTSUdOID0gIm1pbnVzLXNpZ24iLAotICAgICAgQVRUUk5BTUVfTU9ERSA9ICJtb2RlIiwKLSAgICAgIEFUVFJOQU1FX05BTUUgPSAibmFtZSIsCi0gICAgICBBVFRSTkFNRV9OQU1FU1BBQ0UgPSAibmFtZXNwYWNlIiwKLSAgICAgIEFUVFJOQU1FX05BTiA9ICJOYU4iLAotICAgICAgQVRUUk5BTUVfTkRJR0lUU1BFUkdST1VQID0gIm4tZGlnaXRzLXBlci1ncm91cCIsCi0gICAgICBBVFRSTkFNRV9OUyA9ICJucyIsCi0gICAgICBBVFRSTkFNRV9PTkxZID0gIm9ubHkiLAotICAgICAgQVRUUk5BTUVfT1JERVIgPSAib3JkZXIiLAotICAgICAgQVRUUk5BTUVfT1VUUFVUX0NEQVRBX1NFQ1RJT05fRUxFTUVOVFMgPSAiY2RhdGEtc2VjdGlvbi1lbGVtZW50cyIsCi0gICAgICBBVFRSTkFNRV9PVVRQVVRfRE9DVFlQRV9QVUJMSUMgPSAiZG9jdHlwZS1wdWJsaWMiLAotICAgICAgQVRUUk5BTUVfT1VUUFVUX0RPQ1RZUEVfU1lTVEVNID0gImRvY3R5cGUtc3lzdGVtIiwKLSAgICAgIEFUVFJOQU1FX09VVFBVVF9FTkNPRElORyA9ICJlbmNvZGluZyIsCi0gICAgICBBVFRSTkFNRV9PVVRQVVRfSU5ERU5UID0gImluZGVudCIsCi0gICAgICBBVFRSTkFNRV9PVVRQVVRfTUVESUFUWVBFID0gIm1lZGlhLXR5cGUiLAotICAgICAgQVRUUk5BTUVfT1VUUFVUX01FVEhPRCA9ICJtZXRob2QiLCAgLy8gcW5hbWUsCi0gICAgICBBVFRSTkFNRV9PVVRQVVRfT01JVFhNTERFQ0wgPSAib21pdC14bWwtZGVjbGFyYXRpb24iLAotICAgICAgQVRUUk5BTUVfT1VUUFVUX1NUQU5EQUxPTkUgPSAic3RhbmRhbG9uZSIsCi0gICAgICBBVFRSTkFNRV9PVVRQVVRfVkVSU0lPTiA9ICJ2ZXJzaW9uIiwKLSAgICAgIEFUVFJOQU1FX1BBVFRFUk5TRVBBUkFUT1IgPSAicGF0dGVybi1zZXBhcmF0b3IiLAotICAgICAgQVRUUk5BTUVfUEVSQ0VOVCA9ICJwZXJjZW50IiwKLSAgICAgIEFUVFJOQU1FX1BFUk1JTExFID0gInBlci1taWxsZSIsCi0gICAgICBBVFRSTkFNRV9QUklPUklUWSA9ICJwcmlvcml0eSIsCi0gICAgICBBVFRSTkFNRV9SRUZJRCA9ICJyZWZJRCIsCi0gICAgICBBVFRSTkFNRV9SRVNVTFROUyA9ICJyZXN1bHQtbnMiLAotICAgICAgQVRUUk5BTUVfUkVTVUxUX1BSRUZJWCA9ICJyZXN1bHQtcHJlZml4IiwKLSAgICAgIEFUVFJOQU1FX1NFTEVDVCA9ICJzZWxlY3QiLAotICAgICAgQVRUUk5BTUVfU0VRVUVOQ0VTUkMgPSAic2VxdWVuY2Utc3JjIiwKLSAgICAgIEFUVFJOQU1FX1NUWUxFID0gInN0eWxlIiwKLSAgICAgIEFUVFJOQU1FX1NUWUxFU0hFRVRfUFJFRklYID0gInN0eWxlc2hlZXQtcHJlZml4IiwKLSAgICAgIEFUVFJOQU1FX1RFUk1JTkFURSA9ICJ0ZXJtaW5hdGUiLAotICAgICAgQVRUUk5BTUVfVEVTVCA9ICJ0ZXN0IiwKLSAgICAgIEFUVFJOQU1FX1RPU1RSSU5HID0gInRvLXN0cmluZyIsCi0gICAgICBBVFRSTkFNRV9UWVBFID0gInR5cGUiLAotICAgICAgQVRUUk5BTUVfVVNFID0gInVzZSIsCi0gICAgICBBVFRSTkFNRV9VU0VBVFRSSUJVVEVTRVRTID0gInVzZS1hdHRyaWJ1dGUtc2V0cyIsCi0gICAgICBBVFRSTkFNRV9WQUxVRSA9ICJ2YWx1ZSIsCi0gICAgICBBVFRSTkFNRV9WRVJTSU9OID0gInZlcnNpb24iLAotICAgICAgQVRUUk5BTUVfWE1MTlMgPSAieG1sbnM6IiwgLy8gbmFtZXNwYWNlIGRlY2xhcmF0aW9uIHByZWZpeCAtLSBOT1QgYW4gYXR0cmlidXRlIGJ5IGl0c2VsZgotICAgICAgQVRUUk5BTUVfWE1MTlNERUYgPSAieG1sbnMiLCAvLyBkZWZhdWx0IG5hbWVzcGFjZQotICAgICAgQVRUUk5BTUVfWE1MU1BBQ0UgPSAieG1sOnNwYWNlIiwKLSAgICAgIEFUVFJOQU1FX1pFUk9ESUdJVCA9ICJ6ZXJvLWRpZ2l0IjsKLQotICAvKiogSURzIGZvciBYU0wgYXR0cmlidXRlIHR5cGVzLiBUaGVzZSBhcmUgYXNzb2NpYXRlZAotICAgKiB3aXRoIHRoZSBzdHJpbmcgbGl0ZXJhbHMgaW4gdGhlIFRyYW5zZm9ybWVySW1wbCBjbGFzcy4KLSAgICogRG9uJ3QgY2hhbmdlIHRoZSBudW1iZXJzLiBOT1RFIFRIQVQgVEhFU0UgQVJFIE5PVCBJTgotICAgKiBBTFBIQUJFVElDQUwgT1JERVIhCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUQVRUUk5BTUVfT1VUUFVUX01FVEhPRCA9IDEsIFRBVFRSTkFNRV9BTU9VTlQgPSAyLAotICAgICAgICAgICAgICAgICAgICAgICAgICBUQVRUUk5BTUVfQU5DRVNUT1IgPSAzLCBUQVRUUk5BTUVfQVJDSElWRSA9IDQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIFRBVFRSTkFNRV9BVFRSSUJVVEUgPSA1LAotICAgICAgICAgICAgICAgICAgICAgICAgICBUQVRUUk5BTUVfQVRUUklCVVRFX1NFVCA9IDYsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIFRBVFRSTkFNRV9DQVNFT1JERVIgPSA3LCBUQVRUUk5BTUVfQ0xBU1MgPSA4LAotICAgICAgICAgICAgICAgICAgICAgICAgICBUQVRUUk5BTUVfQ0xBU1NJRCA9IDksIFRBVFRSTkFNRV9DT0RFQkFTRSA9IDEwLAotICAgICAgICAgICAgICAgICAgICAgICAgICBUQVRUUk5BTUVfQ09ERVRZUEUgPSAxMSwgVEFUVFJOQU1FX0NPTkRJVElPTiA9IDEyLAotICAgICAgICAgICAgICAgICAgICAgICAgICBUQVRUUk5BTUVfQ09QWVRZUEUgPSAxMywgVEFUVFJOQU1FX0NPVU5UID0gMTQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIFRBVFRSTkFNRV9EQVRBVFlQRSA9IDE1LCBUQVRUUk5BTUVfREVGQVVMVCA9IDE2LAotICAgICAgICAgICAgICAgICAgICAgICAgICBUQVRUUk5BTUVfREVGQVVMVFNQQUNFID0gMTcsIFRBVFRSTkFNRV9ERVBUSCA9IDE4LAotICAgICAgICAgICAgICAgICAgICAgICAgICBUQVRUUk5BTUVfRElHSVRHUk9VUFNFUCA9IDE5LAotICAgICAgICAgICAgICAgICAgICAgICAgICBUQVRUUk5BTUVfRElTQUJMRV9PVVRQVVRfRVNDQVBJTkcgPSAyMCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgVEFUVFJOQU1FX0VMRU1FTlQgPSAyMSwgVEFUVFJOQU1FX0VMRU1FTlRTID0gMjIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIFRBVFRSTkFNRV9FWFBSID0gMjMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIFRBVFRSTkFNRV9FWFRFTlNJT05FTEVNRU5UUFJFRklYRVMgPSAyNCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgVEFUVFJOQU1FX0ZPUk1BVCA9IDI1LCBUQVRUUk5BTUVfRlJPTSA9IDI2LAotICAgICAgICAgICAgICAgICAgICAgICAgICBUQVRUUk5BTUVfR1JPVVBJTkdTRVBBUkFUT1IgPSAyNywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgVEFUVFJOQU1FX0dST1VQSU5HU0laRSA9IDI4LCBUQVRUUk5BTUVfSFJFRiA9IDI5LAotICAgICAgICAgICAgICAgICAgICAgICAgICBUQVRUUk5BTUVfSUQgPSAzMCwgVEFUVFJOQU1FX0lNUE9SVEFOQ0UgPSAzMSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgVEFUVFJOQU1FX0lOREVOVFJFU1VMVCA9IDMyLCBUQVRUUk5BTUVfTEFORyA9IDMzLAotICAgICAgICAgICAgICAgICAgICAgICAgICBUQVRUUk5BTUVfTEVUVEVSVkFMVUUgPSAzNCwgVEFUVFJOQU1FX0xFVkVMID0gMzUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIFRBVFRSTkFNRV9NQVRDSCA9IDM2LCBUQVRUUk5BTUVfTUVUSE9EID0gMzcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIFRBVFRSTkFNRV9NT0RFID0gMzgsIFRBVFRSTkFNRV9OQU1FID0gMzksCi0gICAgICAgICAgICAgICAgICAgICAgICAgIFRBVFRSTkFNRV9OQU1FU1BBQ0UgPSA0MCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgVEFUVFJOQU1FX05ESUdJVFNQRVJHUk9VUCA9IDQxLCBUQVRUUk5BTUVfTlMgPSA0MiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgVEFUVFJOQU1FX09OTFkgPSA0MywgVEFUVFJOQU1FX09SREVSID0gNDQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIFRBVFRSTkFNRV9PVVRQVVRfQ0RBVEFfU0VDVElPTl9FTEVNRU5UUyA9IDQ1LAotICAgICAgICAgICAgICAgICAgICAgICAgICBUQVRUUk5BTUVfT1VUUFVUX0RPQ1RZUEVfUFVCTElDID0gNDYsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIFRBVFRSTkFNRV9PVVRQVVRfRE9DVFlQRV9TWVNURU0gPSA0NywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgVEFUVFJOQU1FX09VVFBVVF9FTkNPRElORyA9IDQ4LAotICAgICAgICAgICAgICAgICAgICAgICAgICBUQVRUUk5BTUVfT1VUUFVUX0lOREVOVCA9IDQ5LAotICAgICAgICAgICAgICAgICAgICAgICAgICBUQVRUUk5BTUVfT1VUUFVUX01FRElBVFlQRSA9IDUwLAotICAgICAgICAgICAgICAgICAgICAgICAgICBUQVRUUk5BTUVfT1VUUFVUX1NUQU5EQUxPTkUgPSA1MSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgVEFUVFJOQU1FX09VVFBVVF9WRVJTSU9OID0gNTIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIFRBVFRSTkFNRV9PVVRQVVRfT01JVFhNTERFQ0wgPSA1MywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgVEFUVFJOQU1FX1BSSU9SSVRZID0gNTQsIFRBVFRSTkFNRV9SRUZJRCA9IDU1LAotICAgICAgICAgICAgICAgICAgICAgICAgICBUQVRUUk5BTUVfUkVTVUxUTlMgPSA1NiwgVEFUVFJOQU1FX1NFTEVDVCA9IDU3LAotICAgICAgICAgICAgICAgICAgICAgICAgICBUQVRUUk5BTUVfU0VRVUVOQ0VTUkMgPSA1OCwgVEFUVFJOQU1FX1NUWUxFID0gNTksCi0gICAgICAgICAgICAgICAgICAgICAgICAgIFRBVFRSTkFNRV9URVNUID0gNjAsIFRBVFRSTkFNRV9UT1NUUklORyA9IDYxLAotICAgICAgICAgICAgICAgICAgICAgICAgICBUQVRUUk5BTUVfVFlQRSA9IDYyLCBUQVRUUk5BTUVfVVNFID0gNjMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIFRBVFRSTkFNRV9VU0VBVFRSSUJVVEVTRVRTID0gNjQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIFRBVFRSTkFNRV9WQUxVRSA9IDY1LCBUQVRUUk5BTUVfWE1MTlNERUYgPSA2NiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgVEFUVFJOQU1FX1hNTE5TID0gNjcsIFRBVFRSTkFNRV9YTUxTUEFDRSA9IDY4LAotICAgICAgICAgICAgICAgICAgICAgICAgICBUQVRUUk5BTUVfRVhDTFVERV9SRVNVTFRfUFJFRklYRVMgPSA2OTsKLQotICAvKiogTW5lbW9uaWNzIGZvciB0aGUgcG9zc2libGUgdmFsdWVzIG9mIHRoZSB4c2w6b3V0cHV0IGVsZW1lbnQncwotICAgKiBtZXRob2Q9IGF0dHJpYnV0ZToKLSAgICogPHVsPgotICAgKiA8bGk+QVRUUlZBTF9PVVRQVVRfTUVUSE9EX1hNTCA9IFVzZSBhbiBYTUwgZm9ybWF0dGVyIHRvCi0gICAqIHByb2R1Y2UgdGhlIG91dHB1dCBkb2N1bWVudCAoYmFzaWMgWFNMVCBvcGVyYXRpb24pLjwvbGk+Ci0gICAqIDxsaT5BVFRSVkFMX09VVFBVVF9NRVRIT0RfSFRNTDogVXNlIGFuIEhUTUwgZm9ybWF0dGVyIHRvCi0gICAqIHByb2R1Y2UgdGhlIG91dHB1dCBkb2N1bWVudC4gV2hlbiBnZW5lcmF0aW5nIEhUTUwgZG9jdW1lbnRzLAotICAgKiB0aGlzIG1heSB5aWVsZCBiZXR0ZXIgcmVzdWx0czsgaXQgZG9lcyB0aGluZ3MgbGlrZSBlc2NhcGluZwotICAgKiBjaGFyYWN0ZXJzIGluIGhyZWYgYXR0cmlidXRlcy48L2xpPgotICAgKiA8L2xpPkFUVFJWQUxfT1VUUFVUX01FVEhPRF9URVhUOiAgVXNlIGEgVGV4dCBmb3JtYXR0ZXIgdG8KLSAgICogcHJvZHVjZSB0aGUgb3V0cHV0IGRvY3VtZW50LiBHZW5lcmFsbHkgdGhlIHJpZ2h0IGNob2ljZSBpZiB5b3VyCi0gICAqIHN0eWxlc2hlZXQgd2FudHMgdG8gdGFrZSBvdmVyIF9hbGxfIHRoZSBkZXRhaWxzIG9mIGZvcm1hdHRpbmcsCi0gICAqIG1vc3Qgb2Z0ZW4gd2hlbiBwcm9kdWNpbmcgc29tZXRoaW5nIHRoYXQgaXNuJ3QgYW4gWE1MIG9yIEhUTUwKLSAgICogZG9jdW1lbnQuPC9saT4KLSAgICogPC91bD4KLSAgICogKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUUlZBTF9PVVRQVVRfTUVUSE9EX0hUTUwgPSAiaHRtbCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFUVFJWQUxfT1VUUFVUX01FVEhPRF9YTUwgPSAieG1sIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVRUUlZBTF9PVVRQVVRfTUVUSE9EX1RFWFQgPSAidGV4dCI7Ci0KLQotICAvKiBGb3Igc3BhY2UtYXR0Ki8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQVRUUlZBTF9QUkVTRVJWRSA9IDEsIEFUVFJWQUxfU1RSSVAgPSAyOwotCi0KLSAgLyoqIEZvciBpbmRlbnQtcmVzdWx0ICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgYm9vbGVhbiBBVFRSVkFMX1lFUyA9IHRydWUsIEFUVFJWQUxfTk8gPSBmYWxzZTsKLQotCi0gIC8qKiBGb3IgbGV0dGVyLXZhbHVlIGF0dHJpYnV0ZSAocGFydCBvZiBjb252ZXJzaW9uIGF0dHJpYnV0ZXMpLiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRSVkFMX0FMUEhBQkVUSUMgPSAiYWxwaGFiZXRpYyIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFUVFJWQUxfT1RIRVIgPSAib3RoZXIiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBVFRSVkFMX1RSQURJVElPTkFMID0gInRyYWRpdGlvbmFsIjsKLQotCi0gIC8qKiBGb3IgbGV2ZWwgYXR0cmlidXRlIGluIHhzbDpudW1iZXIuICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEFUVFJWQUxfU0lOR0xFID0gInNpbmdsZSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFUVFJWQUxfTVVMVEkgPSAibXVsdGlwbGUiLCBBVFRSVkFMX0FOWSA9ICJhbnkiOwotCi0KLSAgLyoqIEZvciBTdHlsZXNoZWV0LXByZWZpeCBhbmQgcmVzdWx0LXByZWZpeCBpbiB4c2w6bmFtZXNwYWNlLWFsaWFzICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEFUVFJWQUxfREVGQVVMVF9QUkVGSVggPSAiI2RlZmF1bHQiOwotCi0gLyoqIEludGVnZXIgZXF1aXZhbGVudHMgZm9yIGFib3ZlICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBOVU1CRVJMRVRURVJfQUxQSEFCRVRJQyA9IDEsIE5VTUJFUkxFVFRFUl9UUkFESVRJT05BTCA9IDI7Ci0KLSAgLyoqIEludGVnZXIgZXF1aXZlbGVudHMgZm9yIGFib3ZlICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBOVU1CRVJMRVZFTF9TSU5HTEUgPSAxLCBOVU1CRVJMRVZFTF9NVUxUSSA9IDIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIE5VTUJFUkxFVkVMX0FOWSA9IDMsIE1BWF9NVUxUSV9DT1VOVElOR19ERVBUSCA9IDMyOwotCi0KLSAgLyoqIHNvbWUgc3R1ZmYgZm9yIG15IHBhdHRlcm5zLWJ5LWV4YW1wbGUgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRSVkFMX1RISVMgPSAiLiIsIEFUVFJWQUxfUEFSRU5UID0gIi4uIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVRUUlZBTF9BTkNFU1RPUiA9ICJhbmNlc3RvciIsIEFUVFJWQUxfSUQgPSAiaWQiOwotCi0KLSAgLyoqIFN0dWZmIGZvciBzb3J0aW5nICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUUlZBTF9EQVRBVFlQRV9URVhUID0gInRleHQiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBVFRSVkFMX0RBVEFUWVBFX05VTUJFUiA9ICJudW1iZXIiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBVFRSVkFMX09SREVSX0FTQ0VORElORyA9ICJhc2NlbmRpbmciLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBVFRSVkFMX09SREVSX0RFU0NFTkRJTkcgPSAiZGVzY2VuZGluZyIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFUVFJWQUxfQ0FTRU9SREVSX1VQUEVSID0gInVwcGVyLWZpcnN0IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVRUUlZBTF9DQVNFT1JERVJfTE9XRVIgPSAibG93ZXItZmlyc3QiOwotCi0gLyoqIEludGVnZXIgZXF1aXZlbGVudHMgZm9yIERBVEFUWVBFIGF0dHJpYnV0ZSAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTT1JUREFUQVRZUEVfVEVYVCA9IDEsIFNPUlREQVRBVFlQRV9OVU1CRVIgPSAyOwotCi0gIC8qKiBJbnRlZ2VyIGVxdWl2ZWxlbnRzIGZvciBPUkRFUiBhdHRyaWJ1dGUgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU09SVE9SREVSX0FTQ0VORElORyA9IDEsIFNPUlRPUkRFUl9ERVNDRU5ESU5HID0gMjsKLQotICAvKiogSW50ZWdlciBlcXVpdmVsZW50cyBmb3IgQ0FTRS1PUkRFUiBhdHRyaWJ1dGUgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU09SVENBU0VPUkRFUl9VUFBFUkZJUlNUID0gMSwgU09SVENBU0VPUkRFUl9MT1dFUkZJUlNUID0gMjsKLQotICAvKiogc29tZSBzdHVmZiBmb3IgRGVjaW1hbC1mb3JtYXQgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUUlZBTF9JTkZJTklUWSA9ICJJbmZpbml0eSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFUVFJWQUxfTkFOID0gIk5hTiIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIERFRkFVTFRfREVDSU1BTF9GT1JNQVQgPSAiI2RlZmF1bHQiOwotCi0KLSAgLyoqIHRlbXAgZHVtbXkgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRSTkFNRV9YWFhYID0gIlhYWFgiOwotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC90ZW1wbGF0ZXMvcGFja2FnZS5odG1sIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC90ZW1wbGF0ZXMvcGFja2FnZS5odG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkNzJiOWE3Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwvdGVtcGxhdGVzL3BhY2thZ2UuaHRtbAorKysgL2Rldi9udWxsCkBAIC0xLDE1ICswLDAgQEAKLTxodG1sPgotPGhlYWQ+Ci0gIDx0aXRsZT5YYWxhbiBUZW1wbGF0ZXMgUGFja2FnZS48L3RpdGxlPgotPCEtLQotCi0gIEAoIylwYWNrYWdlLmh0bWwJMS4zICAgMDMvMTIvMTQKLQotLS0+Ci08L2hlYWQ+Ci08Ym9keSBiZ2NvbG9yPSJ3aGl0ZSI+Ci0gICAgPHA+IFRoaXMgcGFja2FnZSBub3cgb25seSBjb250YWluIHRoZSBjbGFzc2VzIHVzZWQgYnkgWFNMVEMuIEluIEoyU0UgMS41IG9ubHkgWFNMVEMgaXMgYnVuZGxlZCBhcyBUcmFuc2Zvcm1lciBmb3Igc3VwcG9ydGluZyBKQVhQICA8L1A+Ci0gPC9ib2R5PgotPC9odG1sPgotCi0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwvdXRpbHMvQ29uZmlndXJhdGlvbkVycm9yLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3V0aWxzL0NvbmZpZ3VyYXRpb25FcnJvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1ODMyZjgyLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwvdXRpbHMvQ29uZmlndXJhdGlvbkVycm9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw2MSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBPYmplY3RGYWN0b3J5LmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTUgMDI6Mzk6NTQgamVmZnN1dHRvciBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnV0aWxzOwotCi0vKioKLSAqIEEgY29uZmlndXJhdGlvbiBlcnJvci4gVGhpcyB3YXMgYW4gaW50ZXJuYWwgY2xhc3MgaW4gT2JqZWN0RmFjdG9yeSBwcmV2aW91c2x5Ci0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBDb25maWd1cmF0aW9uRXJyb3IKLSAgICBleHRlbmRzIEVycm9yIHsKLQotICAgIC8vCi0gICAgLy8gRGF0YQotICAgIC8vCi0KLSAgICAvKiogRXhjZXB0aW9uLiAqLwotICAgIHByaXZhdGUgRXhjZXB0aW9uIGV4Y2VwdGlvbjsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdCBhIG5ldyBpbnN0YW5jZSB3aXRoIHRoZSBzcGVjaWZpZWQgZGV0YWlsIHN0cmluZyBhbmQKLSAgICAgKiBleGNlcHRpb24uCi0gICAgICovCi0gICAgQ29uZmlndXJhdGlvbkVycm9yKFN0cmluZyBtc2csIEV4Y2VwdGlvbiB4KSB7Ci0gICAgICAgIHN1cGVyKG1zZyk7Ci0gICAgICAgIHRoaXMuZXhjZXB0aW9uID0geDsKLSAgICB9IC8vIDxpbml0PihTdHJpbmcsRXhjZXB0aW9uKQotCi0gICAgLy8KLSAgICAvLyBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKiBSZXR1cm5zIHRoZSBleGNlcHRpb24gYXNzb2NpYXRlZCB0byB0aGlzIGVycm9yLiAqLwotICAgIHB1YmxpYyBFeGNlcHRpb24gZ2V0RXhjZXB0aW9uKCkgewotICAgICAgICByZXR1cm4gZXhjZXB0aW9uOwotICAgIH0gLy8gZ2V0RXhjZXB0aW9uKCk6RXhjZXB0aW9uCi0KLX0gLy8gY2xhc3MgQ29uZmlndXJhdGlvbkVycm9yCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3V0aWxzL0ZhY3RvcnlJbXBsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3V0aWxzL0ZhY3RvcnlJbXBsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDk3M2E3ZmQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC91dGlscy9GYWN0b3J5SW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTcgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAxMSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwudXRpbHM7Ci0KLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5OwotaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLlNBWFBhcnNlckZhY3Rvcnk7Ci0KLS8qKgotICoKLSAqIEBhdXRob3IgaHVpemhlIHdhbmcKLSAqLwotcHVibGljIGNsYXNzIEZhY3RvcnlJbXBsIHsKLQotICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgREJGID0gImNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuamF4cC5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5SW1wbCI7Ci0gICAgc3RhdGljIGZpbmFsIFN0cmluZyBTRiA9ICJjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmpheHAuU0FYUGFyc2VyRmFjdG9yeUltcGwiOwotCi0gICAgc3RhdGljIHB1YmxpYyBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGdldERPTUZhY3RvcnkoYm9vbGVhbiB1c2VTZXJ2aWNlc01lY2hhbmlzbSkgewotICAgICAgICBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGRiZiA9Ci0gICAgICAgICAgICB1c2VTZXJ2aWNlc01lY2hhbmlzbSA/Ci0gICAgICAgICAgICBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCkgOgotICAgICAgICAgICAgRG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5uZXdJbnN0YW5jZSggREJGLAotICAgICAgICAgICAgICAgIEZhY3RvcnlJbXBsLmNsYXNzLmdldENsYXNzTG9hZGVyKCkpOwotCi0gICAgICAgIHJldHVybiBkYmY7Ci0gICAgfQotICAgIHN0YXRpYyBwdWJsaWMgU0FYUGFyc2VyRmFjdG9yeSBnZXRTQVhGYWN0b3J5KGJvb2xlYW4gdXNlU2VydmljZXNNZWNoYW5pc20pIHsKLSAgICAgICAgICAgICAgICBTQVhQYXJzZXJGYWN0b3J5IGZhY3RvcnkgPQotICAgICAgICAgICAgICAgICAgICB1c2VTZXJ2aWNlc01lY2hhbmlzbSA/Ci0gICAgICAgICAgICAgICAgICAgIFNBWFBhcnNlckZhY3RvcnkubmV3SW5zdGFuY2UoKSA6Ci0gICAgICAgICAgICAgICAgICAgIFNBWFBhcnNlckZhY3RvcnkubmV3SW5zdGFuY2UoU0YsCi0gICAgICAgICAgICAgICAgICAgICAgICBGYWN0b3J5SW1wbC5jbGFzcy5nZXRDbGFzc0xvYWRlcigpKTsKLSAgICAgICAgICAgICAgICByZXR1cm4gZmFjdG9yeTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3V0aWxzL0ZlYXR1cmVNYW5hZ2VyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3V0aWxzL0ZlYXR1cmVNYW5hZ2VyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDhiNzdkNTAuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC91dGlscy9GZWF0dXJlTWFuYWdlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTI0ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMTEsIDIwMTMsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnV0aWxzOwotCi0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwuWGFsYW5Db25zdGFudHM7Ci0KLS8qKgotICogVGhpcyBjbGFzcyBtYW5hZ2VzIHNlY3VyaXR5IHJlbGF0ZWQgcHJvcGVydGllcwotICoKLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIEZlYXR1cmVNYW5hZ2VyIGV4dGVuZHMgRmVhdHVyZVByb3BlcnR5QmFzZSB7Ci0KLSAgICAvKioKLSAgICAgKiBTdGF0ZXMgb2YgdGhlIHNldHRpbmdzIG9mIGEgcHJvcGVydHksIGluIHRoZSBvcmRlcjogZGVmYXVsdCB2YWx1ZSwgdmFsdWUKLSAgICAgKiBzZXQgYnkgRkVBVFVSRV9TRUNVUkVfUFJPQ0VTU0lORywgamF4cC5wcm9wZXJ0aWVzIGZpbGUsIGpheHAgc3lzdGVtCi0gICAgICogcHJvcGVydGllcywgYW5kIGpheHAgYXBpIHByb3BlcnRpZXMKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGVudW0gU3RhdGUgewotICAgICAgICAvL3RoaXMgb3JkZXIgcmVmbGVjdHMgdGhlIG92ZXJyaWRpbmcgb3JkZXIKLSAgICAgICAgREVGQVVMVCwgRlNQLCBKQVhQRE9UUFJPUEVSVElFUywgU1lTVEVNUFJPUEVSVFksIEFQSVBST1BFUlRZCi0gICAgfQotCi0gICAgLyoqCi0gICAgICogWGFsYW4gRmVhdHVyZXMKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGVudW0gRmVhdHVyZSB7Ci0gICAgICAgIE9SQUNMRV9FTkFCTEVfRVhURU5TSU9OX0ZVTkNUSU9OKFhhbGFuQ29uc3RhbnRzLk9SQUNMRV9FTkFCTEVfRVhURU5TSU9OX0ZVTkNUSU9OLAotICAgICAgICAgICAgICAgICJ0cnVlIik7Ci0KLSAgICAgICAgZmluYWwgU3RyaW5nIG5hbWU7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBkZWZhdWx0VmFsdWU7Ci0KLSAgICAgICAgRmVhdHVyZShTdHJpbmcgbmFtZSwgU3RyaW5nIHZhbHVlKSB7Ci0gICAgICAgICAgICB0aGlzLm5hbWUgPSBuYW1lOwotICAgICAgICAgICAgdGhpcy5kZWZhdWx0VmFsdWUgPSB2YWx1ZTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFsc05hbWUoU3RyaW5nIHByb3BlcnR5TmFtZSkgewotICAgICAgICAgICAgcmV0dXJuIChwcm9wZXJ0eU5hbWUgPT0gbnVsbCkgPyBmYWxzZSA6IG5hbWUuZXF1YWxzKHByb3BlcnR5TmFtZSk7Ci0gICAgICAgIH0KLQotICAgICAgICBTdHJpbmcgZGVmYXVsdFZhbHVlKCkgewotICAgICAgICAgICAgcmV0dXJuIGRlZmF1bHRWYWx1ZTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIERlZmF1bHQgY29uc3RydWN0b3IuIEVzdGFibGlzaGVzIGRlZmF1bHQgdmFsdWVzCi0gICAgICovCi0gICAgcHVibGljIEZlYXR1cmVNYW5hZ2VyKCkgewotICAgICAgICB2YWx1ZXMgPSBuZXcgU3RyaW5nW0ZlYXR1cmUudmFsdWVzKCkubGVuZ3RoXTsKLSAgICAgICAgZm9yIChGZWF0dXJlIGZlYXR1cmUgOiBGZWF0dXJlLnZhbHVlcygpKSB7Ci0gICAgICAgICAgICB2YWx1ZXNbZmVhdHVyZS5vcmRpbmFsKCldID0gZmVhdHVyZS5kZWZhdWx0VmFsdWUoKTsKLSAgICAgICAgfQotICAgICAgICAvL3JlYWQgc3lzdGVtIHByb3BlcnRpZXMgb3IgamF4cC5wcm9wZXJ0aWVzCi0gICAgICAgIHJlYWRTeXN0ZW1Qcm9wZXJ0aWVzKCk7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBDaGVjayBpZiB0aGUgZmVhdHVyZSBpcyBlbmFibGVkCi0gICAgICogQHBhcmFtIGZlYXR1cmUgbmFtZSBvZiB0aGUgZmVhdHVyZQotICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBlbmFibGVkLCBmYWxzZSBvdGhlcndpc2UKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0ZlYXR1cmVFbmFibGVkKEZlYXR1cmUgZmVhdHVyZSkgewotICAgICAgICByZXR1cm4gQm9vbGVhbi5wYXJzZUJvb2xlYW4odmFsdWVzW2ZlYXR1cmUub3JkaW5hbCgpXSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ2hlY2sgaWYgdGhlIGZlYXR1cmUgaXMgZW5hYmxlZAotICAgICAqIEBwYXJhbSBwcm9wZXJ0eU5hbWUgbmFtZSBvZiB0aGUgZmVhdHVyZQotICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBlbmFibGVkLCBmYWxzZSBvdGhlcndpc2UKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0ZlYXR1cmVFbmFibGVkKFN0cmluZyBwcm9wZXJ0eU5hbWUpIHsKLSAgICAgICAgcmV0dXJuIEJvb2xlYW4ucGFyc2VCb29sZWFuKHZhbHVlc1tnZXRJbmRleChwcm9wZXJ0eU5hbWUpXSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBpbmRleCBieSBwcm9wZXJ0eSBuYW1lCi0gICAgICogQHBhcmFtIHByb3BlcnR5TmFtZSBwcm9wZXJ0eSBuYW1lCi0gICAgICogQHJldHVybiB0aGUgaW5kZXggb2YgdGhlIHByb3BlcnR5IGlmIGZvdW5kOyByZXR1cm4gLTEgaWYgbm90Ci0gICAgICovCi0gICAgcHVibGljIGludCBnZXRJbmRleChTdHJpbmcgcHJvcGVydHlOYW1lKXsKLSAgICAgICAgZm9yIChGZWF0dXJlIGZlYXR1cmUgOiBGZWF0dXJlLnZhbHVlcygpKSB7Ci0gICAgICAgICAgICBpZiAoZmVhdHVyZS5lcXVhbHNOYW1lKHByb3BlcnR5TmFtZSkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZmVhdHVyZS5vcmRpbmFsKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIC0xOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJlYWQgZnJvbSBzeXN0ZW0gcHJvcGVydGllcywgb3IgdGhvc2UgaW4gamF4cC5wcm9wZXJ0aWVzCi0gICAgICovCi0gICAgcHJpdmF0ZSB2b2lkIHJlYWRTeXN0ZW1Qcm9wZXJ0aWVzKCkgewotICAgICAgICBnZXRTeXN0ZW1Qcm9wZXJ0eShGZWF0dXJlLk9SQUNMRV9FTkFCTEVfRVhURU5TSU9OX0ZVTkNUSU9OLAotICAgICAgICAgICAgICAgIFhhbGFuQ29uc3RhbnRzLlNQX09SQUNMRV9FTkFCTEVfRVhURU5TSU9OX0ZVTkNUSU9OKTsKLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwvdXRpbHMvRmVhdHVyZVByb3BlcnR5QmFzZS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC91dGlscy9GZWF0dXJlUHJvcGVydHlCYXNlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDMwMTUwMjQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC91dGlscy9GZWF0dXJlUHJvcGVydHlCYXNlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMTUgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAxMSwgMjAxMywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwudXRpbHM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwuWGFsYW5Db25zdGFudHM7Ci0KLS8qKgotICogVGhpcyBpcyB0aGUgYmFzZSBjbGFzcyBmb3IgZmVhdHVyZXMgYW5kIHByb3BlcnRpZXMKLSAqCi0gKi8KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBGZWF0dXJlUHJvcGVydHlCYXNlIHsKLQotICAgIC8qKgotICAgICAqIFN0YXRlcyBvZiB0aGUgc2V0dGluZ3Mgb2YgYSBwcm9wZXJ0eSwgaW4gdGhlIG9yZGVyOiBkZWZhdWx0IHZhbHVlLCB2YWx1ZQotICAgICAqIHNldCBieSBGRUFUVVJFX1NFQ1VSRV9QUk9DRVNTSU5HLCBqYXhwLnByb3BlcnRpZXMgZmlsZSwgamF4cCBzeXN0ZW0KLSAgICAgKiBwcm9wZXJ0aWVzLCBhbmQgamF4cCBhcGkgcHJvcGVydGllcwotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZW51bSBTdGF0ZSB7Ci0gICAgICAgIC8vdGhpcyBvcmRlciByZWZsZWN0cyB0aGUgb3ZlcnJpZGluZyBvcmRlcgotICAgICAgICBERUZBVUxULCBGU1AsIEpBWFBET1RQUk9QRVJUSUVTLCBTWVNURU1QUk9QRVJUWSwgQVBJUFJPUEVSVFkKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFZhbHVlcyBvZiB0aGUgcHJvcGVydGllcyBhcyBkZWZpbmVkIGluIGVudW0gUHJvcGVydGllcwotICAgICAqLwotICAgIFN0cmluZ1tdIHZhbHVlcyA9IG51bGw7Ci0gICAgLyoqCi0gICAgICogU3RhdGVzIG9mIHRoZSBzZXR0aW5ncyBmb3IgZWFjaCBwcm9wZXJ0eSBpbiBQcm9wZXJ0aWVzIGFib3ZlCi0gICAgICovCi0gICAgU3RhdGVbXSBzdGF0ZXMgPSB7U3RhdGUuREVGQVVMVCwgU3RhdGUuREVGQVVMVH07Ci0KLQotICAgIC8qKgotICAgICAqIFNldCB0aGUgdmFsdWUgZm9yIGEgc3BlY2lmaWMgcHJvcGVydHkuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcHJvcGVydHkgdGhlIHByb3BlcnR5Ci0gICAgICogQHBhcmFtIHN0YXRlIHRoZSBzdGF0ZSBvZiB0aGUgcHJvcGVydHkKLSAgICAgKiBAcGFyYW0gdmFsdWUgdGhlIHZhbHVlIG9mIHRoZSBwcm9wZXJ0eQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFZhbHVlKEVudW0gcHJvcGVydHksIFN0YXRlIHN0YXRlLCBTdHJpbmcgdmFsdWUpIHsKLSAgICAgICAgLy9vbmx5IHVwZGF0ZSBpZiBpdCBzaGFsbCBvdmVycmlkZQotICAgICAgICBpZiAoc3RhdGUuY29tcGFyZVRvKHN0YXRlc1twcm9wZXJ0eS5vcmRpbmFsKCldKSA+PSAwKSB7Ci0gICAgICAgICAgICB2YWx1ZXNbcHJvcGVydHkub3JkaW5hbCgpXSA9IHZhbHVlOwotICAgICAgICAgICAgc3RhdGVzW3Byb3BlcnR5Lm9yZGluYWwoKV0gPSBzdGF0ZTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldCB0aGUgdmFsdWUgb2YgYSBwcm9wZXJ0eSBieSBpdHMgaW5kZXgKLSAgICAgKiBAcGFyYW0gaW5kZXggdGhlIGluZGV4IG9mIHRoZSBwcm9wZXJ0eQotICAgICAqIEBwYXJhbSBzdGF0ZSB0aGUgc3RhdGUgb2YgdGhlIHByb3BlcnR5Ci0gICAgICogQHBhcmFtIHZhbHVlIHRoZSB2YWx1ZSBvZiB0aGUgcHJvcGVydHkKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRWYWx1ZShpbnQgaW5kZXgsIFN0YXRlIHN0YXRlLCBTdHJpbmcgdmFsdWUpIHsKLSAgICAgICAgLy9vbmx5IHVwZGF0ZSBpZiBpdCBzaGFsbCBvdmVycmlkZQotICAgICAgICBpZiAoc3RhdGUuY29tcGFyZVRvKHN0YXRlc1tpbmRleF0pID49IDApIHsKLSAgICAgICAgICAgIHZhbHVlc1tpbmRleF0gPSB2YWx1ZTsKLSAgICAgICAgICAgIHN0YXRlc1tpbmRleF0gPSBzdGF0ZTsKLSAgICAgICAgfQotICAgIH0KLQotICAgICAvKioKLSAgICAgKiBTZXQgdmFsdWUgYnkgcHJvcGVydHkgbmFtZSBhbmQgc3RhdGUKLSAgICAgKiBAcGFyYW0gcHJvcGVydHlOYW1lIHByb3BlcnR5IG5hbWUKLSAgICAgKiBAcGFyYW0gc3RhdGUgdGhlIHN0YXRlIG9mIHRoZSBwcm9wZXJ0eQotICAgICAqIEBwYXJhbSB2YWx1ZSB0aGUgdmFsdWUgb2YgdGhlIHByb3BlcnR5Ci0gICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBwcm9wZXJ0eSBpcyBtYW5hZ2VkIGJ5IHRoZSBzZWN1cml0eSBwcm9wZXJ0eSBtYW5hZ2VyOwotICAgICAqICAgICAgICAgZmFsc2UgaWYgb3RoZXJ3aXNlLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIHNldFZhbHVlKFN0cmluZyBwcm9wZXJ0eU5hbWUsIFN0YXRlIHN0YXRlLCBPYmplY3QgdmFsdWUpIHsKLSAgICAgICAgaW50IGluZGV4ID0gZ2V0SW5kZXgocHJvcGVydHlOYW1lKTsKLSAgICAgICAgaWYgKGluZGV4ID4gLTEpIHsKLSAgICAgICAgICAgIHNldFZhbHVlKGluZGV4LCBzdGF0ZSwgKFN0cmluZyl2YWx1ZSk7Ci0gICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgIC8qKgotICAgICAqIFNldCB2YWx1ZSBieSBwcm9wZXJ0eSBuYW1lIGFuZCBzdGF0ZQotICAgICAqIEBwYXJhbSBwcm9wZXJ0eU5hbWUgcHJvcGVydHkgbmFtZQotICAgICAqIEBwYXJhbSBzdGF0ZSB0aGUgc3RhdGUgb2YgdGhlIHByb3BlcnR5Ci0gICAgICogQHBhcmFtIHZhbHVlIHRoZSB2YWx1ZSBvZiB0aGUgcHJvcGVydHkKLSAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHByb3BlcnR5IGlzIG1hbmFnZWQgYnkgdGhlIHNlY3VyaXR5IHByb3BlcnR5IG1hbmFnZXI7Ci0gICAgICogICAgICAgICBmYWxzZSBpZiBvdGhlcndpc2UuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gc2V0VmFsdWUoU3RyaW5nIHByb3BlcnR5TmFtZSwgU3RhdGUgc3RhdGUsIGJvb2xlYW4gdmFsdWUpIHsKLSAgICAgICAgaW50IGluZGV4ID0gZ2V0SW5kZXgocHJvcGVydHlOYW1lKTsKLSAgICAgICAgaWYgKGluZGV4ID4gLTEpIHsKLSAgICAgICAgICAgIGlmICh2YWx1ZSkgewotICAgICAgICAgICAgICAgIHNldFZhbHVlKGluZGV4LCBzdGF0ZSwgWGFsYW5Db25zdGFudHMuRkVBVFVSRV9UUlVFKTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgc2V0VmFsdWUoaW5kZXgsIHN0YXRlLCBYYWxhbkNvbnN0YW50cy5GRUFUVVJFX0ZBTFNFKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgcHJvcGVydHkKLSAgICAgKgotICAgICAqIEBwYXJhbSBwcm9wZXJ0eSB0aGUgcHJvcGVydHkKLSAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgcHJvcGVydHkKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFZhbHVlKEVudW0gcHJvcGVydHkpIHsKLSAgICAgICAgcmV0dXJuIHZhbHVlc1twcm9wZXJ0eS5vcmRpbmFsKCldOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybiB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBwcm9wZXJ0eQotICAgICAqCi0gICAgICogQHBhcmFtIHByb3BlcnR5IHRoZSBwcm9wZXJ0eQotICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBwcm9wZXJ0eQotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VmFsdWUoU3RyaW5nIHByb3BlcnR5KSB7Ci0gICAgICAgIGludCBpbmRleCA9IGdldEluZGV4KHByb3BlcnR5KTsKLSAgICAgICAgaWYgKGluZGV4ID4gLTEpIHsKLSAgICAgICAgICAgIHJldHVybiBnZXRWYWx1ZUJ5SW5kZXgoaW5kZXgpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybiB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBwcm9wZXJ0eS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBwcm9wZXJ0eU5hbWUgdGhlIHByb3BlcnR5IG5hbWUKLSAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgcHJvcGVydHkgYXMgYSBzdHJpbmcuIElmIGEgcHJvcGVydHkgaXMgbWFuYWdlZAotICAgICAqIGJ5IHRoaXMgbWFuYWdlciwgaXRzIHZhbHVlIHNoYWxsIG5vdCBiZSBudWxsLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VmFsdWVBc1N0cmluZyhTdHJpbmcgcHJvcGVydHlOYW1lKSB7Ci0gICAgICAgIGludCBpbmRleCA9IGdldEluZGV4KHByb3BlcnR5TmFtZSk7Ci0gICAgICAgIGlmIChpbmRleCA+IC0xKSB7Ci0gICAgICAgICAgICByZXR1cm4gZ2V0VmFsdWVCeUluZGV4KGluZGV4KTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybiB0aGUgdmFsdWUgb2YgYSBwcm9wZXJ0eSBieSBpdHMgb3JkaW5hbAotICAgICAqIEBwYXJhbSBpbmRleCB0aGUgaW5kZXggb2YgYSBwcm9wZXJ0eQotICAgICAqIEByZXR1cm4gdmFsdWUgb2YgYSBwcm9wZXJ0eQotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VmFsdWVCeUluZGV4KGludCBpbmRleCkgewotICAgICAgICByZXR1cm4gdmFsdWVzW2luZGV4XTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIGluZGV4IGJ5IHByb3BlcnR5IG5hbWUKLSAgICAgKiBAcGFyYW0gcHJvcGVydHlOYW1lIHByb3BlcnR5IG5hbWUKLSAgICAgKiBAcmV0dXJuIHRoZSBpbmRleCBvZiB0aGUgcHJvcGVydHkgaWYgZm91bmQ7IHJldHVybiAtMSBpZiBub3QKLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3QgaW50IGdldEluZGV4KFN0cmluZyBwcm9wZXJ0eU5hbWUpOwotCi0gICAgcHVibGljIDxFIGV4dGVuZHMgRW51bTxFPj4gaW50IGdldEluZGV4KENsYXNzPEU+IHByb3BlcnR5LCBTdHJpbmcgcHJvcGVydHlOYW1lKSB7Ci0gICAgICAgIGZvciAoRW51bTxFPiBlbnVtSXRlbSA6IHByb3BlcnR5LmdldEVudW1Db25zdGFudHMoKSkgewotICAgICAgICAgICAgaWYgKGVudW1JdGVtLnRvU3RyaW5nKCkuZXF1YWxzKHByb3BlcnR5TmFtZSkpIHsKLSAgICAgICAgICAgICAgICAvL2ludGVybmFsbHksIG9yZGluYWwgaXMgdXNlZCBhcyBpbmRleAotICAgICAgICAgICAgICAgIHJldHVybiBlbnVtSXRlbS5vcmRpbmFsKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIC0xOwotICAgIH07Ci0KLQotICAgIC8qKgotICAgICAqIFJlYWQgZnJvbSBzeXN0ZW0gcHJvcGVydGllcywgb3IgdGhvc2UgaW4gamF4cC5wcm9wZXJ0aWVzCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcHJvcGVydHkgdGhlIHByb3BlcnR5Ci0gICAgICogQHBhcmFtIHN5c3RlbVByb3BlcnR5IHRoZSBuYW1lIG9mIHRoZSBzeXN0ZW0gcHJvcGVydHkKLSAgICAgKi8KLSAgICB2b2lkIGdldFN5c3RlbVByb3BlcnR5KEVudW0gcHJvcGVydHksIFN0cmluZyBzeXN0ZW1Qcm9wZXJ0eSkgewotICAgICAgICB0cnkgewotICAgICAgICAgICAgU3RyaW5nIHZhbHVlID0gU2VjdXJpdHlTdXBwb3J0LmdldFN5c3RlbVByb3BlcnR5KHN5c3RlbVByb3BlcnR5KTsKLSAgICAgICAgICAgIGlmICh2YWx1ZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgdmFsdWVzW3Byb3BlcnR5Lm9yZGluYWwoKV0gPSB2YWx1ZTsKLSAgICAgICAgICAgICAgICBzdGF0ZXNbcHJvcGVydHkub3JkaW5hbCgpXSA9IFN0YXRlLlNZU1RFTVBST1BFUlRZOwotICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgdmFsdWUgPSBTZWN1cml0eVN1cHBvcnQucmVhZEpBWFBQcm9wZXJ0eShzeXN0ZW1Qcm9wZXJ0eSk7Ci0gICAgICAgICAgICBpZiAodmFsdWUgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHZhbHVlc1twcm9wZXJ0eS5vcmRpbmFsKCldID0gdmFsdWU7Ci0gICAgICAgICAgICAgICAgc3RhdGVzW3Byb3BlcnR5Lm9yZGluYWwoKV0gPSBTdGF0ZS5KQVhQRE9UUFJPUEVSVElFUzsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIC8vaW52YWxpZCBzZXR0aW5nIGlnbm9yZWQKLSAgICAgICAgfQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwvdXRpbHMvT2JqZWN0RmFjdG9yeS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC91dGlscy9PYmplY3RGYWN0b3J5LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDhlODI5NjkuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC91dGlscy9PYmplY3RGYWN0b3J5LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMjEgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogT2JqZWN0RmFjdG9yeS5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE1IDAyOjM5OjU0IGplZmZzdXR0b3IgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC51dGlsczsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGlzIGR1cGxpY2F0ZWQgZm9yIGVhY2ggSkFYUCBzdWJwYWNrYWdlIHNvIGtlZXAgaXQgaW4gc3luYy4KLSAqIEl0IGlzIHBhY2thZ2UgcHJpdmF0ZSBhbmQgdGhlcmVmb3JlIGlzIG5vdCBleHBvc2VkIGFzIHBhcnQgb2YgdGhlIEpBWFAKLSAqIEFQSS4KLSAqIDxwPgotICogVGhpcyBjbGFzcyB3YXMgbW92ZWQgZnJvbSB0aGUgPGNvZGU+amF2YXgueG1sLnBhcnNlcnMuT2JqZWN0RmFjdG9yeTwvY29kZT4KLSAqIGNsYXNzIGFuZCBtb2RpZmllZCB0byBiZSB1c2VkIGFzIGEgZ2VuZXJhbCB1dGlsaXR5IGZvciBjcmVhdGluZyBvYmplY3RzCi0gKiBkeW5hbWljYWxseS4KLSAqCi0gKiBAdmVyc2lvbiAkSWQ6IE9iamVjdEZhY3RvcnkuamF2YSx2IDEuMTEgMjAxMC0xMS0wMSAwNDozNDoyNSBqb2VodyBFeHAgJAotICovCi1wdWJsaWMgY2xhc3MgT2JqZWN0RmFjdG9yeSB7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0YW50cwotICAgIC8vCi0gICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBKQVhQX0lOVEVSTkFMID0gImNvbS5zdW4ub3JnLmFwYWNoZSI7Ci0gICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBTVEFYX0lOVEVSTkFMID0gImNvbS5zdW4ueG1sLmludGVybmFsIjsKLQotICAgIC8qKiBTZXQgdG8gdHJ1ZSBmb3IgZGVidWdnaW5nICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbiBERUJVRyA9IGZhbHNlOwotCi0KLSAgICAvKiogUHJpbnRzIGEgbWVzc2FnZSB0byBzdGFuZGFyZCBlcnJvciBpZiBkZWJ1Z2dpbmcgaXMgZW5hYmxlZC4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGRlYnVnUHJpbnRsbihTdHJpbmcgbXNnKSB7Ci0gICAgICAgIGlmIChERUJVRykgewotICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJKQVhQOiAiICsgbXNnKTsKLSAgICAgICAgfQotICAgIH0gLy8gZGVidWdQcmludGxuKFN0cmluZykKLQotICAgIC8qKgotICAgICAqIEZpZ3VyZSBvdXQgd2hpY2ggQ2xhc3NMb2FkZXIgdG8gdXNlLiAgRm9yIEpESyAxLjIgYW5kIGxhdGVyIHVzZQotICAgICAqIHRoZSBjb250ZXh0IENsYXNzTG9hZGVyLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgQ2xhc3NMb2FkZXIgZmluZENsYXNzTG9hZGVyKCkKLSAgICB7Ci0gICAgICAgIGlmIChTeXN0ZW0uZ2V0U2VjdXJpdHlNYW5hZ2VyKCkhPW51bGwpIHsKLSAgICAgICAgICAgIC8vdGhpcyB3aWxsIGVuc3VyZSBib290Y2xhc3Nsb2FkZXIgaXMgdXNlZAotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBGaWd1cmUgb3V0IHdoaWNoIENsYXNzTG9hZGVyIHRvIHVzZSBmb3IgbG9hZGluZyB0aGUgcHJvdmlkZXIKLSAgICAgICAgLy8gY2xhc3MuICBJZiB0aGVyZSBpcyBhIENvbnRleHQgQ2xhc3NMb2FkZXIgdGhlbiB1c2UgaXQuCi0gICAgICAgIENsYXNzTG9hZGVyIGNvbnRleHQgPSBTZWN1cml0eVN1cHBvcnQuZ2V0Q29udGV4dENsYXNzTG9hZGVyKCk7Ci0gICAgICAgIENsYXNzTG9hZGVyIHN5c3RlbSA9IFNlY3VyaXR5U3VwcG9ydC5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpOwotCi0gICAgICAgIENsYXNzTG9hZGVyIGNoYWluID0gc3lzdGVtOwotICAgICAgICB3aGlsZSAodHJ1ZSkgewotICAgICAgICAgICAgaWYgKGNvbnRleHQgPT0gY2hhaW4pIHsKLSAgICAgICAgICAgICAgICAvLyBBc3NlcnQ6IHdlIGFyZSBvbiBKREsgMS4xIG9yIHdlIGhhdmUgbm8gQ29udGV4dCBDbGFzc0xvYWRlcgotICAgICAgICAgICAgICAgIC8vIG9yIGFueSBDb250ZXh0IENsYXNzTG9hZGVyIGluIGNoYWluIG9mIHN5c3RlbSBjbGFzc2xvYWRlcgotICAgICAgICAgICAgICAgIC8vIChpbmNsdWRpbmcgZXh0ZW5zaW9uIENsYXNzTG9hZGVyKSBzbyBleHRlbmQgdG8gd2lkZXN0Ci0gICAgICAgICAgICAgICAgLy8gQ2xhc3NMb2FkZXIgKGFsd2F5cyBsb29rIGluIHN5c3RlbSBDbGFzc0xvYWRlciBpZiBYYWxhbgotICAgICAgICAgICAgICAgIC8vIGlzIGluIGJvb3QvZXh0ZW5zaW9uL3N5c3RlbSBjbGFzc3BhdGggYW5kIGluIGN1cnJlbnQKLSAgICAgICAgICAgICAgICAvLyBDbGFzc0xvYWRlciBvdGhlcndpc2UpOyBub3JtYWwgY2xhc3Nsb2FkZXJzIGRlbGVnYXRlCi0gICAgICAgICAgICAgICAgLy8gYmFjayB0byBzeXN0ZW0gQ2xhc3NMb2FkZXIgZmlyc3Qgc28gdGhpcyB3aWRlbmluZyBkb2Vzbid0Ci0gICAgICAgICAgICAgICAgLy8gY2hhbmdlIHRoZSBmYWN0IHRoYXQgY29udGV4dCBDbGFzc0xvYWRlciB3aWxsIGJlIGNvbnN1bHRlZAotICAgICAgICAgICAgICAgIENsYXNzTG9hZGVyIGN1cnJlbnQgPSBPYmplY3RGYWN0b3J5LmNsYXNzLmdldENsYXNzTG9hZGVyKCk7Ci0KLSAgICAgICAgICAgICAgICBjaGFpbiA9IHN5c3RlbTsKLSAgICAgICAgICAgICAgICB3aGlsZSAodHJ1ZSkgewotICAgICAgICAgICAgICAgICAgICBpZiAoY3VycmVudCA9PSBjaGFpbikgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gQXNzZXJ0OiBDdXJyZW50IENsYXNzTG9hZGVyIGluIGNoYWluIG9mCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBib290L2V4dGVuc2lvbi9zeXN0ZW0gQ2xhc3NMb2FkZXJzCi0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3lzdGVtOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGlmIChjaGFpbiA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBjaGFpbiA9IFNlY3VyaXR5U3VwcG9ydC5nZXRQYXJlbnRDbGFzc0xvYWRlcihjaGFpbik7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgLy8gQXNzZXJ0OiBDdXJyZW50IENsYXNzTG9hZGVyIG5vdCBpbiBjaGFpbiBvZgotICAgICAgICAgICAgICAgIC8vIGJvb3QvZXh0ZW5zaW9uL3N5c3RlbSBDbGFzc0xvYWRlcnMKLSAgICAgICAgICAgICAgICByZXR1cm4gY3VycmVudDsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKGNoYWluID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAvLyBib290IENsYXNzTG9hZGVyIHJlYWNoZWQKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gQ2hlY2sgZm9yIGFueSBleHRlbnNpb24gQ2xhc3NMb2FkZXJzIGluIGNoYWluIHVwIHRvCi0gICAgICAgICAgICAvLyBib290IENsYXNzTG9hZGVyCi0gICAgICAgICAgICBjaGFpbiA9IFNlY3VyaXR5U3VwcG9ydC5nZXRQYXJlbnRDbGFzc0xvYWRlcihjaGFpbik7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBBc3NlcnQ6IENvbnRleHQgQ2xhc3NMb2FkZXIgbm90IGluIGNoYWluIG9mCi0gICAgICAgIC8vIGJvb3QvZXh0ZW5zaW9uL3N5c3RlbSBDbGFzc0xvYWRlcnMKLSAgICAgICAgcmV0dXJuIGNvbnRleHQ7Ci0gICAgfSAvLyBmaW5kQ2xhc3NMb2FkZXIoKTpDbGFzc0xvYWRlcgotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlIGFuIGluc3RhbmNlIG9mIGEgY2xhc3MgdXNpbmcgdGhlIHNhbWUgY2xhc3MgbG9hZGVyIGZvciB0aGUgT2JqZWN0RmFjdG9yeSBieSBkZWZhdWx0Ci0gICAgICogb3IgYm9vdCBjbGFzcyBsb2FkZXIgd2hlbiBTZWN1cml0eSBNYW5hZ2VyIGlzIGluIHBsYWNlCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBPYmplY3QgbmV3SW5zdGFuY2UoU3RyaW5nIGNsYXNzTmFtZSwgYm9vbGVhbiBkb0ZhbGxiYWNrKQotICAgICAgICB0aHJvd3MgQ29uZmlndXJhdGlvbkVycm9yCi0gICAgewotICAgICAgICBpZiAoU3lzdGVtLmdldFNlY3VyaXR5TWFuYWdlcigpIT1udWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gbmV3SW5zdGFuY2UoY2xhc3NOYW1lLCBudWxsLCBkb0ZhbGxiYWNrKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiBuZXdJbnN0YW5jZShjbGFzc05hbWUsCi0gICAgICAgICAgICAgICAgZmluZENsYXNzTG9hZGVyICgpLCBkb0ZhbGxiYWNrKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIENyZWF0ZSBhbiBpbnN0YW5jZSBvZiBhIGNsYXNzIHVzaW5nIHRoZSBzcGVjaWZpZWQgQ2xhc3NMb2FkZXIKLSAgICAgKi8KLSAgICBzdGF0aWMgT2JqZWN0IG5ld0luc3RhbmNlKFN0cmluZyBjbGFzc05hbWUsIENsYXNzTG9hZGVyIGNsLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGRvRmFsbGJhY2spCi0gICAgICAgIHRocm93cyBDb25maWd1cmF0aW9uRXJyb3IKLSAgICB7Ci0gICAgICAgIC8vIGFzc2VydChjbGFzc05hbWUgIT0gbnVsbCk7Ci0gICAgICAgIHRyeXsKLSAgICAgICAgICAgIENsYXNzIHByb3ZpZGVyQ2xhc3MgPSBmaW5kUHJvdmlkZXJDbGFzcyhjbGFzc05hbWUsIGNsLCBkb0ZhbGxiYWNrKTsKLSAgICAgICAgICAgIE9iamVjdCBpbnN0YW5jZSA9IHByb3ZpZGVyQ2xhc3MubmV3SW5zdGFuY2UoKTsKLSAgICAgICAgICAgIGlmIChERUJVRykgZGVidWdQcmludGxuKCJjcmVhdGVkIG5ldyBpbnN0YW5jZSBvZiAiICsgcHJvdmlkZXJDbGFzcyArCi0gICAgICAgICAgICAgICAgICAgIiB1c2luZyBDbGFzc0xvYWRlcjogIiArIGNsKTsKLSAgICAgICAgICAgIHJldHVybiBpbnN0YW5jZTsKLSAgICAgICAgfSBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB4KSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgQ29uZmlndXJhdGlvbkVycm9yKAotICAgICAgICAgICAgICAgICJQcm92aWRlciAiICsgY2xhc3NOYW1lICsgIiBub3QgZm91bmQiLCB4KTsKLSAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIHgpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBDb25maWd1cmF0aW9uRXJyb3IoCi0gICAgICAgICAgICAgICAgIlByb3ZpZGVyICIgKyBjbGFzc05hbWUgKyAiIGNvdWxkIG5vdCBiZSBpbnN0YW50aWF0ZWQ6ICIgKyB4LAotICAgICAgICAgICAgICAgIHgpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRmluZCBhIENsYXNzIHVzaW5nIHRoZSBzYW1lIGNsYXNzIGxvYWRlciBmb3IgdGhlIE9iamVjdEZhY3RvcnkgYnkgZGVmYXVsdAotICAgICAqIG9yIGJvb3QgY2xhc3MgbG9hZGVyIHdoZW4gU2VjdXJpdHkgTWFuYWdlciBpcyBpbiBwbGFjZQotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgQ2xhc3M8Pz4gZmluZFByb3ZpZGVyQ2xhc3MoU3RyaW5nIGNsYXNzTmFtZSwgYm9vbGVhbiBkb0ZhbGxiYWNrKQotICAgICAgICB0aHJvd3MgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiwgQ29uZmlndXJhdGlvbkVycm9yCi0gICAgewotICAgICAgICByZXR1cm4gZmluZFByb3ZpZGVyQ2xhc3MgKGNsYXNzTmFtZSwKLSAgICAgICAgICAgICAgICBmaW5kQ2xhc3NMb2FkZXIgKCksIGRvRmFsbGJhY2spOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEZpbmQgYSBDbGFzcyB1c2luZyB0aGUgc3BlY2lmaWVkIENsYXNzTG9hZGVyCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgQ2xhc3M8Pz4gZmluZFByb3ZpZGVyQ2xhc3MoU3RyaW5nIGNsYXNzTmFtZSwgQ2xhc3NMb2FkZXIgY2wsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBkb0ZhbGxiYWNrKQotICAgICAgICB0aHJvd3MgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiwgQ29uZmlndXJhdGlvbkVycm9yCi0gICAgewotICAgICAgICAvL3Rocm93IHNlY3VyaXR5IGV4Y2VwdGlvbiBpZiB0aGUgY2FsbGluZyB0aHJlYWQgaXMgbm90IGFsbG93ZWQgdG8gYWNjZXNzIHRoZQotICAgICAgICAvL2NsYXNzLiBSZXN0cmljdCB0aGUgYWNjZXNzIHRvIHRoZSBwYWNrYWdlIGNsYXNzZXMgYXMgc3BlY2lmaWVkIGluIGphdmEuc2VjdXJpdHkgcG9saWN5LgotICAgICAgICBTZWN1cml0eU1hbmFnZXIgc2VjdXJpdHkgPSBTeXN0ZW0uZ2V0U2VjdXJpdHlNYW5hZ2VyKCk7Ci0gICAgICAgIHRyeXsKLSAgICAgICAgICAgIGlmIChzZWN1cml0eSAhPSBudWxsKXsKLSAgICAgICAgICAgICAgICBpZiAoY2xhc3NOYW1lLnN0YXJ0c1dpdGgoSkFYUF9JTlRFUk5BTCkgfHwKLSAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lLnN0YXJ0c1dpdGgoU1RBWF9JTlRFUk5BTCkpIHsKLSAgICAgICAgICAgICAgICAgICAgY2wgPSBudWxsOwotICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCBsYXN0RG90ID0gY2xhc3NOYW1lLmxhc3RJbmRleE9mKCIuIik7Ci0gICAgICAgICAgICAgICAgICAgIFN0cmluZyBwYWNrYWdlTmFtZSA9IGNsYXNzTmFtZTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGxhc3REb3QgIT0gLTEpIHBhY2thZ2VOYW1lID0gY2xhc3NOYW1lLnN1YnN0cmluZygwLCBsYXN0RG90KTsKLSAgICAgICAgICAgICAgICAgICAgc2VjdXJpdHkuY2hlY2tQYWNrYWdlQWNjZXNzKHBhY2thZ2VOYW1lKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgfQotICAgICAgICB9Y2F0Y2goU2VjdXJpdHlFeGNlcHRpb24gZSl7Ci0gICAgICAgICAgICB0aHJvdyBlOwotICAgICAgICB9Ci0KLSAgICAgICAgQ2xhc3M8Pz4gcHJvdmlkZXJDbGFzczsKLSAgICAgICAgaWYgKGNsID09IG51bGwpIHsKLSAgICAgICAgICAgIHByb3ZpZGVyQ2xhc3MgPSBDbGFzcy5mb3JOYW1lKGNsYXNzTmFtZSwgZmFsc2UsIE9iamVjdEZhY3RvcnkuY2xhc3MuZ2V0Q2xhc3NMb2FkZXIoKSk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIHByb3ZpZGVyQ2xhc3MgPSBjbC5sb2FkQ2xhc3MoY2xhc3NOYW1lKTsKLSAgICAgICAgICAgIH0gY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24geCkgewotICAgICAgICAgICAgICAgIGlmIChkb0ZhbGxiYWNrKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIEZhbGwgYmFjayB0byBjdXJyZW50IGNsYXNzbG9hZGVyCi0gICAgICAgICAgICAgICAgICAgIENsYXNzTG9hZGVyIGN1cnJlbnQgPSBPYmplY3RGYWN0b3J5LmNsYXNzLmdldENsYXNzTG9hZGVyKCk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChjdXJyZW50ID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHByb3ZpZGVyQ2xhc3MgPSBDbGFzcy5mb3JOYW1lKGNsYXNzTmFtZSk7Ci0gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoY2wgIT0gY3VycmVudCkgewotICAgICAgICAgICAgICAgICAgICAgICAgY2wgPSBjdXJyZW50OwotICAgICAgICAgICAgICAgICAgICAgICAgcHJvdmlkZXJDbGFzcyA9IGNsLmxvYWRDbGFzcyhjbGFzc05hbWUpOwotICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgeDsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIHRocm93IHg7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIHByb3ZpZGVyQ2xhc3M7Ci0gICAgfQotCi19IC8vIGNsYXNzIE9iamVjdEZhY3RvcnkKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwvdXRpbHMvU2VjdXJpdHlTdXBwb3J0LmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3V0aWxzL1NlY3VyaXR5U3VwcG9ydC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlNTgxZjlhLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwvdXRpbHMvU2VjdXJpdHlTdXBwb3J0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzNDUgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMi0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogU2VjdXJpdHlTdXBwb3J0LmphdmEsdiAxLjEuMi4xIDIwMDUvMDgvMDEgMDI6MDg6NDggamVmZnN1dHRvciBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnV0aWxzOwotCi1pbXBvcnQgamF2YS5pby5GaWxlOwotaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uRmlsZU5vdEZvdW5kRXhjZXB0aW9uOwotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci1pbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKLWltcG9ydCBqYXZhLm5ldC5VUkw7Ci0KLWltcG9ydCBqYXZhLnNlY3VyaXR5LkFjY2Vzc0NvbnRyb2xsZXI7Ci1pbXBvcnQgamF2YS5zZWN1cml0eS5Qcml2aWxlZ2VkQWN0aW9uOwotaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpdmlsZWdlZEFjdGlvbkV4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLnNlY3VyaXR5LlByaXZpbGVnZWRFeGNlcHRpb25BY3Rpb247Ci1pbXBvcnQgamF2YS51dGlsLkxpc3RSZXNvdXJjZUJ1bmRsZTsKLWltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwotaW1wb3J0IGphdmEudXRpbC5NaXNzaW5nUmVzb3VyY2VFeGNlcHRpb247Ci1pbXBvcnQgamF2YS51dGlsLlJlc291cmNlQnVuZGxlOwotaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0aWVzOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgaXMgZHVwbGljYXRlZCBmb3IgZWFjaCBzdWJwYWNrYWdlIHNvIGtlZXAgaXQgaW4gc3luYy4gSXQgaXMKLSAqIHBhY2thZ2UgcHJpdmF0ZSBhbmQgdGhlcmVmb3JlIGlzIG5vdCBleHBvc2VkIGFzIHBhcnQgb2YgYW55IEFQSS4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBTZWN1cml0eVN1cHBvcnQgewotCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU2VjdXJpdHlTdXBwb3J0IHNlY3VyaXR5U3VwcG9ydCA9IG5ldyBTZWN1cml0eVN1cHBvcnQoKTsKLQotICAgIC8qKgotICAgICAqIFJldHVybiBhbiBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgU2VjdXJpdHlTdXBwb3J0IGdldEluc3RhbmNlKCkgewotICAgICAgICByZXR1cm4gc2VjdXJpdHlTdXBwb3J0OwotICAgIH0KLQotICAgIHB1YmxpYyBzdGF0aWMgQ2xhc3NMb2FkZXIgZ2V0Q29udGV4dENsYXNzTG9hZGVyKCkgewotICAgICAgICByZXR1cm4gKENsYXNzTG9hZGVyKSBBY2Nlc3NDb250cm9sbGVyLmRvUHJpdmlsZWdlZChuZXcgUHJpdmlsZWdlZEFjdGlvbigpIHsKLSAgICAgICAgICAgIHB1YmxpYyBPYmplY3QgcnVuKCkgewotICAgICAgICAgICAgICAgIENsYXNzTG9hZGVyIGNsID0gbnVsbDsKLSAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICBjbCA9IFRocmVhZC5jdXJyZW50VGhyZWFkKCkuZ2V0Q29udGV4dENsYXNzTG9hZGVyKCk7Ci0gICAgICAgICAgICAgICAgfSBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gZXgpIHsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGNsOwotICAgICAgICAgICAgfQotICAgICAgICB9KTsKLSAgICB9Ci0KLSAgICBzdGF0aWMgQ2xhc3NMb2FkZXIgZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKSB7Ci0gICAgICAgIHJldHVybiAoQ2xhc3NMb2FkZXIpIEFjY2Vzc0NvbnRyb2xsZXIuZG9Qcml2aWxlZ2VkKG5ldyBQcml2aWxlZ2VkQWN0aW9uKCkgewotICAgICAgICAgICAgcHVibGljIE9iamVjdCBydW4oKSB7Ci0gICAgICAgICAgICAgICAgQ2xhc3NMb2FkZXIgY2wgPSBudWxsOwotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgIGNsID0gQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKTsKLSAgICAgICAgICAgICAgICB9IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBleCkgewotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICByZXR1cm4gY2w7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0pOwotICAgIH0KLQotICAgIHN0YXRpYyBDbGFzc0xvYWRlciBnZXRQYXJlbnRDbGFzc0xvYWRlcihmaW5hbCBDbGFzc0xvYWRlciBjbCkgewotICAgICAgICByZXR1cm4gKENsYXNzTG9hZGVyKSBBY2Nlc3NDb250cm9sbGVyLmRvUHJpdmlsZWdlZChuZXcgUHJpdmlsZWdlZEFjdGlvbigpIHsKLSAgICAgICAgICAgIHB1YmxpYyBPYmplY3QgcnVuKCkgewotICAgICAgICAgICAgICAgIENsYXNzTG9hZGVyIHBhcmVudCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgcGFyZW50ID0gY2wuZ2V0UGFyZW50KCk7Ci0gICAgICAgICAgICAgICAgfSBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gZXgpIHsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyBlbGltaW5hdGUgbG9vcHMgaW4gY2FzZSBvZiB0aGUgYm9vdAotICAgICAgICAgICAgICAgIC8vIENsYXNzTG9hZGVyIHJldHVybmluZyBpdHNlbGYgYXMgYSBwYXJlbnQKLSAgICAgICAgICAgICAgICByZXR1cm4gKHBhcmVudCA9PSBjbCkgPyBudWxsIDogcGFyZW50OwotICAgICAgICAgICAgfQotICAgICAgICB9KTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBnZXRTeXN0ZW1Qcm9wZXJ0eShmaW5hbCBTdHJpbmcgcHJvcE5hbWUpIHsKLSAgICAgICAgcmV0dXJuIChTdHJpbmcpIEFjY2Vzc0NvbnRyb2xsZXIuZG9Qcml2aWxlZ2VkKG5ldyBQcml2aWxlZ2VkQWN0aW9uKCkgewotICAgICAgICAgICAgcHVibGljIE9iamVjdCBydW4oKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIFN5c3RlbS5nZXRQcm9wZXJ0eShwcm9wTmFtZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0pOwotICAgIH0KLQotICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldFN5c3RlbVByb3BlcnR5KGZpbmFsIFN0cmluZyBwcm9wTmFtZSwgZmluYWwgU3RyaW5nIGRlZikgewotICAgICAgICByZXR1cm4gKFN0cmluZykgQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQobmV3IFByaXZpbGVnZWRBY3Rpb24oKSB7Ci0gICAgICAgICAgICBwdWJsaWMgT2JqZWN0IHJ1bigpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gU3lzdGVtLmdldFByb3BlcnR5KHByb3BOYW1lLCBkZWYpOwotICAgICAgICAgICAgfQotICAgICAgICB9KTsKLSAgICB9Ci0KLSAgICBzdGF0aWMgRmlsZUlucHV0U3RyZWFtIGdldEZpbGVJbnB1dFN0cmVhbShmaW5hbCBGaWxlIGZpbGUpCi0gICAgICAgICAgICB0aHJvd3MgRmlsZU5vdEZvdW5kRXhjZXB0aW9uIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIHJldHVybiAoRmlsZUlucHV0U3RyZWFtKSBBY2Nlc3NDb250cm9sbGVyLmRvUHJpdmlsZWdlZChuZXcgUHJpdmlsZWdlZEV4Y2VwdGlvbkFjdGlvbigpIHsKLSAgICAgICAgICAgICAgICBwdWJsaWMgT2JqZWN0IHJ1bigpIHRocm93cyBGaWxlTm90Rm91bmRFeGNlcHRpb24gewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEZpbGVJbnB1dFN0cmVhbShmaWxlKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9KTsKLSAgICAgICAgfSBjYXRjaCAoUHJpdmlsZWdlZEFjdGlvbkV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICB0aHJvdyAoRmlsZU5vdEZvdW5kRXhjZXB0aW9uKWUuZ2V0RXhjZXB0aW9uKCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gcmVzb3VyY2UgdXNpbmcgdGhlIHNhbWUgY2xhc3Nsb2FkZXIgZm9yIHRoZSBPYmplY3RGYWN0b3J5IGJ5Ci0gICAgICogZGVmYXVsdCBvciBib290Y2xhc3Nsb2FkZXIgd2hlbiBTZWN1cml0eSBNYW5hZ2VyIGlzIGluIHBsYWNlCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBJbnB1dFN0cmVhbSBnZXRSZXNvdXJjZUFzU3RyZWFtKGZpbmFsIFN0cmluZyBuYW1lKSB7Ci0gICAgICAgIGlmIChTeXN0ZW0uZ2V0U2VjdXJpdHlNYW5hZ2VyKCkhPW51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBnZXRSZXNvdXJjZUFzU3RyZWFtKG51bGwsIG5hbWUpOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIGdldFJlc291cmNlQXNTdHJlYW0oT2JqZWN0RmFjdG9yeS5maW5kQ2xhc3NMb2FkZXIoKSwgbmFtZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgc3RhdGljIElucHV0U3RyZWFtIGdldFJlc291cmNlQXNTdHJlYW0oZmluYWwgQ2xhc3NMb2FkZXIgY2wsCi0gICAgICAgICAgICBmaW5hbCBTdHJpbmcgbmFtZSkgewotICAgICAgICByZXR1cm4gKElucHV0U3RyZWFtKSBBY2Nlc3NDb250cm9sbGVyLmRvUHJpdmlsZWdlZChuZXcgUHJpdmlsZWdlZEFjdGlvbigpIHsKLSAgICAgICAgICAgIHB1YmxpYyBPYmplY3QgcnVuKCkgewotICAgICAgICAgICAgICAgIElucHV0U3RyZWFtIHJpczsKLSAgICAgICAgICAgICAgICBpZiAoY2wgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICByaXMgPSBPYmplY3QuY2xhc3MuZ2V0UmVzb3VyY2VBc1N0cmVhbSgiLyIrbmFtZSk7Ci0gICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgcmlzID0gY2wuZ2V0UmVzb3VyY2VBc1N0cmVhbShuYW1lKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHJpczsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0cyBhIHJlc291cmNlIGJ1bmRsZSB1c2luZyB0aGUgc3BlY2lmaWVkIGJhc2UgbmFtZSwgdGhlIGRlZmF1bHQgbG9jYWxlLCBhbmQgdGhlIGNhbGxlcidzIGNsYXNzIGxvYWRlci4KLSAgICAgKiBAcGFyYW0gYnVuZGxlIHRoZSBiYXNlIG5hbWUgb2YgdGhlIHJlc291cmNlIGJ1bmRsZSwgYSBmdWxseSBxdWFsaWZpZWQgY2xhc3MgbmFtZQotICAgICAqIEByZXR1cm4gYSByZXNvdXJjZSBidW5kbGUgZm9yIHRoZSBnaXZlbiBiYXNlIG5hbWUgYW5kIHRoZSBkZWZhdWx0IGxvY2FsZQotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgTGlzdFJlc291cmNlQnVuZGxlIGdldFJlc291cmNlQnVuZGxlKFN0cmluZyBidW5kbGUpIHsKLSAgICAgICAgcmV0dXJuIGdldFJlc291cmNlQnVuZGxlKGJ1bmRsZSwgTG9jYWxlLmdldERlZmF1bHQoKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0cyBhIHJlc291cmNlIGJ1bmRsZSB1c2luZyB0aGUgc3BlY2lmaWVkIGJhc2UgbmFtZSBhbmQgbG9jYWxlLCBhbmQgdGhlIGNhbGxlcidzIGNsYXNzIGxvYWRlci4KLSAgICAgKiBAcGFyYW0gYnVuZGxlIHRoZSBiYXNlIG5hbWUgb2YgdGhlIHJlc291cmNlIGJ1bmRsZSwgYSBmdWxseSBxdWFsaWZpZWQgY2xhc3MgbmFtZQotICAgICAqIEBwYXJhbSBsb2NhbGUgdGhlIGxvY2FsZSBmb3Igd2hpY2ggYSByZXNvdXJjZSBidW5kbGUgaXMgZGVzaXJlZAotICAgICAqIEByZXR1cm4gYSByZXNvdXJjZSBidW5kbGUgZm9yIHRoZSBnaXZlbiBiYXNlIG5hbWUgYW5kIGxvY2FsZQotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgTGlzdFJlc291cmNlQnVuZGxlIGdldFJlc291cmNlQnVuZGxlKGZpbmFsIFN0cmluZyBidW5kbGUsIGZpbmFsIExvY2FsZSBsb2NhbGUpIHsKLSAgICAgICAgcmV0dXJuIEFjY2Vzc0NvbnRyb2xsZXIuZG9Qcml2aWxlZ2VkKG5ldyBQcml2aWxlZ2VkQWN0aW9uPExpc3RSZXNvdXJjZUJ1bmRsZT4oKSB7Ci0gICAgICAgICAgICBwdWJsaWMgTGlzdFJlc291cmNlQnVuZGxlIHJ1bigpIHsKLSAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gKExpc3RSZXNvdXJjZUJ1bmRsZSlSZXNvdXJjZUJ1bmRsZS5nZXRCdW5kbGUoYnVuZGxlLCBsb2NhbGUpOwotICAgICAgICAgICAgICAgIH0gY2F0Y2ggKE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKExpc3RSZXNvdXJjZUJ1bmRsZSlSZXNvdXJjZUJ1bmRsZS5nZXRCdW5kbGUoYnVuZGxlLCBuZXcgTG9jYWxlKCJlbiIsICJVUyIpKTsKLSAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uIGUyKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ291bGQgbm90IGxvYWQgYW55IHJlc291cmNlIGJ1bmRsZSBieSAiICsgYnVuZGxlLCBidW5kbGUsICIiKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfSk7Ci0gICAgfQotCi0gICAgcHVibGljIHN0YXRpYyBib29sZWFuIGdldEZpbGVFeGlzdHMoZmluYWwgRmlsZSBmKSB7Ci0gICAgICAgIHJldHVybiAoKEJvb2xlYW4pIEFjY2Vzc0NvbnRyb2xsZXIuZG9Qcml2aWxlZ2VkKG5ldyBQcml2aWxlZ2VkQWN0aW9uKCkgewotICAgICAgICAgICAgICAgICAgICBwdWJsaWMgT2JqZWN0IHJ1bigpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmLmV4aXN0cygpID8gQm9vbGVhbi5UUlVFIDogQm9vbGVhbi5GQUxTRTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0pKS5ib29sZWFuVmFsdWUoKTsKLSAgICB9Ci0KLSAgICBzdGF0aWMgbG9uZyBnZXRMYXN0TW9kaWZpZWQoZmluYWwgRmlsZSBmKSB7Ci0gICAgICAgIHJldHVybiAoKExvbmcpIEFjY2Vzc0NvbnRyb2xsZXIuZG9Qcml2aWxlZ2VkKG5ldyBQcml2aWxlZ2VkQWN0aW9uKCkgewotICAgICAgICAgICAgICAgICAgICBwdWJsaWMgT2JqZWN0IHJ1bigpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgTG9uZyhmLmxhc3RNb2RpZmllZCgpKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0pKS5sb25nVmFsdWUoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTdHJpcCBvZmYgcGF0aCBmcm9tIGFuIFVSSQotICAgICAqCi0gICAgICogQHBhcmFtIHVyaSBhbiBVUkkgd2l0aCBmdWxsIHBhdGgKLSAgICAgKiBAcmV0dXJuIHRoZSBmaWxlIG5hbWUgb25seQotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHNhbml0aXplUGF0aChTdHJpbmcgdXJpKSB7Ci0gICAgICAgIGlmICh1cmkgPT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuICIiOwotICAgICAgICB9Ci0gICAgICAgIGludCBpID0gdXJpLmxhc3RJbmRleE9mKCIvIik7Ci0gICAgICAgIGlmIChpID4gMCkgewotICAgICAgICAgICAgcmV0dXJuIHVyaS5zdWJzdHJpbmcoaSsxLCB1cmkubGVuZ3RoKCkpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiAiIjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDaGVjayB0aGUgcHJvdG9jb2wgdXNlZCBpbiB0aGUgc3lzdGVtSWQgYWdhaW5zdCBhbGxvd2VkIHByb3RvY29scwotICAgICAqCi0gICAgICogQHBhcmFtIHN5c3RlbUlkIHRoZSBJZCBvZiB0aGUgVVJJCi0gICAgICogQHBhcmFtIGFsbG93ZWRQcm90b2NvbHMgYSBsaXN0IG9mIGFsbG93ZWQgcHJvdG9jb2xzIHNlcGFyYXRlZCBieSBjb21tYQotICAgICAqIEBwYXJhbSBhY2Nlc3NBbnkga2V5d29yZCB0byBpbmRpY2F0ZSBhbGxvd2luZyBhbnkgcHJvdG9jb2wKLSAgICAgKiBAcmV0dXJuIHRoZSBuYW1lIG9mIHRoZSBwcm90b2NvbCBpZiByZWplY3RlZCwgbnVsbCBvdGhlcndpc2UKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBjaGVja0FjY2VzcyhTdHJpbmcgc3lzdGVtSWQsIFN0cmluZyBhbGxvd2VkUHJvdG9jb2xzLCBTdHJpbmcgYWNjZXNzQW55KSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgICAgICBpZiAoc3lzdGVtSWQgPT0gbnVsbCB8fCAoYWxsb3dlZFByb3RvY29scyAhPSBudWxsICYmCi0gICAgICAgICAgICAgICAgYWxsb3dlZFByb3RvY29scy5lcXVhbHNJZ25vcmVDYXNlKGFjY2Vzc0FueSkpKSB7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotCi0gICAgICAgIFN0cmluZyBwcm90b2NvbDsKLSAgICAgICAgaWYgKHN5c3RlbUlkLmluZGV4T2YoIjoiKT09LTEpIHsKLSAgICAgICAgICAgIHByb3RvY29sID0gImZpbGUiOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgVVJMIHVybCA9IG5ldyBVUkwoc3lzdGVtSWQpOwotICAgICAgICAgICAgcHJvdG9jb2wgPSB1cmwuZ2V0UHJvdG9jb2woKTsKLSAgICAgICAgICAgIGlmIChwcm90b2NvbC5lcXVhbHNJZ25vcmVDYXNlKCJqYXIiKSkgewotICAgICAgICAgICAgICAgIFN0cmluZyBwYXRoID0gdXJsLmdldFBhdGgoKTsKLSAgICAgICAgICAgICAgICBwcm90b2NvbCA9IHBhdGguc3Vic3RyaW5nKDAsIHBhdGguaW5kZXhPZigiOiIpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGlmIChpc1Byb3RvY29sQWxsb3dlZChwcm90b2NvbCwgYWxsb3dlZFByb3RvY29scykpIHsKLSAgICAgICAgICAgIC8vYWNjZXNzIGFsbG93ZWQKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIHByb3RvY29sOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ2hlY2sgaWYgdGhlIHByb3RvY29sIGlzIGluIHRoZSBhbGxvd2VkIGxpc3Qgb2YgcHJvdG9jb2xzLiBUaGUgY2hlY2sKLSAgICAgKiBpcyBjYXNlLWluc2Vuc2l0aXZlIHdoaWxlIGlnbm9yaW5nIHdoaXRlc3BhY2VzLgotICAgICAqCi0gICAgICogQHBhcmFtIHByb3RvY29sIGEgcHJvdG9jb2wKLSAgICAgKiBAcGFyYW0gYWxsb3dlZFByb3RvY29scyBhIGxpc3Qgb2YgYWxsb3dlZCBwcm90b2NvbHMKLSAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHByb3RvY29sIGlzIGluIHRoZSBsaXN0Ci0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBpc1Byb3RvY29sQWxsb3dlZChTdHJpbmcgcHJvdG9jb2wsIFN0cmluZyBhbGxvd2VkUHJvdG9jb2xzKSB7Ci0gICAgICAgICBpZiAoYWxsb3dlZFByb3RvY29scyA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgfQotICAgICAgICAgU3RyaW5nIHRlbXBbXSA9IGFsbG93ZWRQcm90b2NvbHMuc3BsaXQoIiwiKTsKLSAgICAgICAgIGZvciAoU3RyaW5nIHQgOiB0ZW1wKSB7Ci0gICAgICAgICAgICAgdCA9IHQudHJpbSgpOwotICAgICAgICAgICAgIGlmICh0LmVxdWFsc0lnbm9yZUNhc2UocHJvdG9jb2wpKSB7Ci0gICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgIH0KLSAgICAgICAgIH0KLSAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgfQotCi0gICAgLyoqCi0gICAgICogUmVhZCBKQVhQIHN5c3RlbSBwcm9wZXJ0eSBpbiB0aGlzIG9yZGVyOiBzeXN0ZW0gcHJvcGVydHksCi0gICAgICogJGphdmEuaG9tZS9saWIvamF4cC5wcm9wZXJ0aWVzIGlmIHRoZSBzeXN0ZW0gcHJvcGVydHkgaXMgbm90IHNwZWNpZmllZAotICAgICAqCi0gICAgICogQHBhcmFtIHByb3BlcnR5SWQgdGhlIElkIG9mIHRoZSBwcm9wZXJ0eQotICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBwcm9wZXJ0eQotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldEpBWFBTeXN0ZW1Qcm9wZXJ0eShTdHJpbmcgc3lzUHJvcGVydHlJZCkgewotICAgICAgICBTdHJpbmcgYWNjZXNzRXh0ZXJuYWwgPSBnZXRTeXN0ZW1Qcm9wZXJ0eShzeXNQcm9wZXJ0eUlkKTsKLSAgICAgICAgaWYgKGFjY2Vzc0V4dGVybmFsID09IG51bGwpIHsKLSAgICAgICAgICAgIGFjY2Vzc0V4dGVybmFsID0gcmVhZEpBWFBQcm9wZXJ0eShzeXNQcm9wZXJ0eUlkKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gYWNjZXNzRXh0ZXJuYWw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmVhZCBmcm9tICRqYXZhLmhvbWUvbGliL2pheHAucHJvcGVydGllcyBmb3IgdGhlIHNwZWNpZmllZCBwcm9wZXJ0eQotICAgICAqIFRoZSBwcm9ncmFtCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcHJvcGVydHlJZCB0aGUgSWQgb2YgdGhlIHByb3BlcnR5Ci0gICAgICogQHJldHVybiB0aGUgdmFsdWUgb2YgdGhlIHByb3BlcnR5Ci0gICAgICovCi0gICAgc3RhdGljIFN0cmluZyByZWFkSkFYUFByb3BlcnR5KFN0cmluZyBwcm9wZXJ0eUlkKSB7Ci0gICAgICAgIFN0cmluZyB2YWx1ZSA9IG51bGw7Ci0gICAgICAgIElucHV0U3RyZWFtIGlzID0gbnVsbDsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGlmIChmaXJzdFRpbWUpIHsKLSAgICAgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKGNhY2hlUHJvcHMpIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGZpcnN0VGltZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGNvbmZpZ0ZpbGUgPSBnZXRTeXN0ZW1Qcm9wZXJ0eSgiamF2YS5ob21lIikgKyBGaWxlLnNlcGFyYXRvciArCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgImxpYiIgKyBGaWxlLnNlcGFyYXRvciArICJqYXhwLnByb3BlcnRpZXMiOwotICAgICAgICAgICAgICAgICAgICAgICAgRmlsZSBmID0gbmV3IEZpbGUoY29uZmlnRmlsZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZ2V0RmlsZUV4aXN0cyhmKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzID0gZ2V0RmlsZUlucHV0U3RyZWFtKGYpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhY2hlUHJvcHMubG9hZChpcyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBmaXJzdFRpbWUgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHZhbHVlID0gY2FjaGVQcm9wcy5nZXRQcm9wZXJ0eShwcm9wZXJ0eUlkKTsKLQotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpIHt9Ci0gICAgICAgIGZpbmFsbHkgewotICAgICAgICAgICAgaWYgKGlzICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICBpcy5jbG9zZSgpOwotICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7fQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIHZhbHVlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENhY2hlIGZvciBwcm9wZXJ0aWVzIGluIGphdmEuaG9tZS9saWIvamF4cC5wcm9wZXJ0aWVzCi0gICAgICovCi0gICAgc3RhdGljIGZpbmFsIFByb3BlcnRpZXMgY2FjaGVQcm9wcyA9IG5ldyBQcm9wZXJ0aWVzKCk7Ci0KLSAgICAvKioKLSAgICAgKiBGbGFnIGluZGljYXRpbmcgaWYgdGhlIHByb2dyYW0gaGFzIHRyaWVkIHJlYWRpbmcgamF2YS5ob21lL2xpYi9qYXhwLnByb3BlcnRpZXMKLSAgICAgKi8KLSAgICBzdGF0aWMgdm9sYXRpbGUgYm9vbGVhbiBmaXJzdFRpbWUgPSB0cnVlOwotCi0gICAgcHJpdmF0ZSBTZWN1cml0eVN1cHBvcnQgKCkge30KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwvdXRpbHMvWE1MU2VjdXJpdHlNYW5hZ2VyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3V0aWxzL1hNTFNlY3VyaXR5TWFuYWdlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA5NmJiNDZjLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwvdXRpbHMvWE1MU2VjdXJpdHlNYW5hZ2VyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0NjYgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAxMywgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwudXRpbHM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwuWGFsYW5Db25zdGFudHM7Ci1pbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuQ29weU9uV3JpdGVBcnJheUxpc3Q7Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotCi0KLS8qKgotICogVGhpcyBjbGFzcyBpcyBub3QgdGhlIHNhbWUgYXMgdGhhdCBpbiBYZXJjZXMuIEl0IGlzIHVzZWQgdG8gbWFuYWdlIHRoZQotICogc3RhdGUgb2YgY29ycmVzcG9uZGluZyBYZXJjZXMgcHJvcGVydGllcyBhbmQgcGFzcyB0aGUgdmFsdWVzIG92ZXIgdG8KLSAqIHRoZSBYZXJjZXMgU2VjdXJpdHkgTWFuYWdlci4KLSAqCi0gKiBAYXV0aG9yIEpvZSBXYW5nIE9yYWNsZSBDb3JwLgotICoKLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIFhNTFNlY3VyaXR5TWFuYWdlciB7Ci0KLSAgICAvKioKLSAgICAgKiBTdGF0ZXMgb2YgdGhlIHNldHRpbmdzIG9mIGEgcHJvcGVydHksIGluIHRoZSBvcmRlcjogZGVmYXVsdCB2YWx1ZSwgdmFsdWUKLSAgICAgKiBzZXQgYnkgRkVBVFVSRV9TRUNVUkVfUFJPQ0VTU0lORywgamF4cC5wcm9wZXJ0aWVzIGZpbGUsIGpheHAgc3lzdGVtCi0gICAgICogcHJvcGVydGllcywgYW5kIGpheHAgYXBpIHByb3BlcnRpZXMKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGVudW0gU3RhdGUgewotICAgICAgICAvL3RoaXMgb3JkZXIgcmVmbGVjdHMgdGhlIG92ZXJyaWRpbmcgb3JkZXIKLQotICAgICAgICBERUZBVUxUKCJkZWZhdWx0IiksIEZTUCgiRkVBVFVSRV9TRUNVUkVfUFJPQ0VTU0lORyIpLAotICAgICAgICBKQVhQRE9UUFJPUEVSVElFUygiamF4cC5wcm9wZXJ0aWVzIiksIFNZU1RFTVBST1BFUlRZKCJzeXN0ZW0gcHJvcGVydHkiKSwKLSAgICAgICAgQVBJUFJPUEVSVFkoInByb3BlcnR5Iik7Ci0KLSAgICAgICAgZmluYWwgU3RyaW5nIGxpdGVyYWw7Ci0gICAgICAgIFN0YXRlKFN0cmluZyBsaXRlcmFsKSB7Ci0gICAgICAgICAgICB0aGlzLmxpdGVyYWwgPSBsaXRlcmFsOwotICAgICAgICB9Ci0KLSAgICAgICAgU3RyaW5nIGxpdGVyYWwoKSB7Ci0gICAgICAgICAgICByZXR1cm4gbGl0ZXJhbDsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIExpbWl0cyBtYW5hZ2VkIGJ5IHRoZSBzZWN1cml0eSBtYW5hZ2VyCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBlbnVtIExpbWl0IHsKLQotICAgICAgICBFTlRJVFlfRVhQQU5TSU9OX0xJTUlUKCJFbnRpdHlFeHBhbnNpb25MaW1pdCIsIFhhbGFuQ29uc3RhbnRzLkpES19FTlRJVFlfRVhQQU5TSU9OX0xJTUlULAotICAgICAgICAgICAgICAgIFhhbGFuQ29uc3RhbnRzLlNQX0VOVElUWV9FWFBBTlNJT05fTElNSVQsIDAsIDY0MDAwKSwKLSAgICAgICAgTUFYX09DQ1VSX05PREVfTElNSVQoIk1heE9jY3VyTGltaXQiLCBYYWxhbkNvbnN0YW50cy5KREtfTUFYX09DQ1VSX0xJTUlULAotICAgICAgICAgICAgICAgIFhhbGFuQ29uc3RhbnRzLlNQX01BWF9PQ0NVUl9MSU1JVCwgMCwgNTAwMCksCi0gICAgICAgIEVMRU1FTlRfQVRUUklCVVRFX0xJTUlUKCJFbGVtZW50QXR0cmlidXRlTGltaXQiLCBYYWxhbkNvbnN0YW50cy5KREtfRUxFTUVOVF9BVFRSSUJVVEVfTElNSVQsCi0gICAgICAgICAgICAgICAgWGFsYW5Db25zdGFudHMuU1BfRUxFTUVOVF9BVFRSSUJVVEVfTElNSVQsIDAsIDEwMDAwKSwKLSAgICAgICAgVE9UQUxfRU5USVRZX1NJWkVfTElNSVQoIlRvdGFsRW50aXR5U2l6ZUxpbWl0IiwgWGFsYW5Db25zdGFudHMuSkRLX1RPVEFMX0VOVElUWV9TSVpFX0xJTUlULAotICAgICAgICAgICAgICAgIFhhbGFuQ29uc3RhbnRzLlNQX1RPVEFMX0VOVElUWV9TSVpFX0xJTUlULCAwLCA1MDAwMDAwMCksCi0gICAgICAgIEdFTkVSQUxfRU5USVRZX1NJWkVfTElNSVQoIk1heEVudGl0eVNpemVMaW1pdCIsIFhhbGFuQ29uc3RhbnRzLkpES19HRU5FUkFMX0VOVElUWV9TSVpFX0xJTUlULAotICAgICAgICAgICAgICAgIFhhbGFuQ29uc3RhbnRzLlNQX0dFTkVSQUxfRU5USVRZX1NJWkVfTElNSVQsIDAsIDApLAotICAgICAgICBQQVJBTUVURVJfRU5USVRZX1NJWkVfTElNSVQoIk1heEVudGl0eVNpemVMaW1pdCIsIFhhbGFuQ29uc3RhbnRzLkpES19QQVJBTUVURVJfRU5USVRZX1NJWkVfTElNSVQsCi0gICAgICAgICAgICAgICAgWGFsYW5Db25zdGFudHMuU1BfUEFSQU1FVEVSX0VOVElUWV9TSVpFX0xJTUlULCAwLCAxMDAwMDAwKSwKLSAgICAgICAgTUFYX0VMRU1FTlRfREVQVEhfTElNSVQoIk1heEVsZW1lbnREZXB0aExpbWl0IiwgWGFsYW5Db25zdGFudHMuSkRLX01BWF9FTEVNRU5UX0RFUFRILAotICAgICAgICAgICAgICAgIFhhbGFuQ29uc3RhbnRzLlNQX01BWF9FTEVNRU5UX0RFUFRILCAwLCAwKSwKLSAgICAgICAgTUFYX05BTUVfTElNSVQoIk1heFhNTE5hbWVMaW1pdCIsIFhhbGFuQ29uc3RhbnRzLkpES19YTUxfTkFNRV9MSU1JVCwKLSAgICAgICAgICAgICAgICBYYWxhbkNvbnN0YW50cy5TUF9YTUxfTkFNRV9MSU1JVCwgMTAwMCwgMTAwMCksCi0gICAgICAgIEVOVElUWV9SRVBMQUNFTUVOVF9MSU1JVCgiRW50aXR5UmVwbGFjZW1lbnRMaW1pdCIsIFhhbGFuQ29uc3RhbnRzLkpES19FTlRJVFlfUkVQTEFDRU1FTlRfTElNSVQsCi0gICAgICAgICAgICAgICAgWGFsYW5Db25zdGFudHMuU1BfRU5USVRZX1JFUExBQ0VNRU5UX0xJTUlULCAwLCAzMDAwMDAwKTsKLQotICAgICAgICBmaW5hbCBTdHJpbmcga2V5OwotICAgICAgICBmaW5hbCBTdHJpbmcgYXBpUHJvcGVydHk7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBzeXN0ZW1Qcm9wZXJ0eTsKLSAgICAgICAgZmluYWwgaW50IGRlZmF1bHRWYWx1ZTsKLSAgICAgICAgZmluYWwgaW50IHNlY3VyZVZhbHVlOwotCi0gICAgICAgIExpbWl0KFN0cmluZyBrZXksIFN0cmluZyBhcGlQcm9wZXJ0eSwgU3RyaW5nIHN5c3RlbVByb3BlcnR5LCBpbnQgdmFsdWUsIGludCBzZWN1cmVWYWx1ZSkgewotICAgICAgICAgICAgdGhpcy5rZXkgPSBrZXk7Ci0gICAgICAgICAgICB0aGlzLmFwaVByb3BlcnR5ID0gYXBpUHJvcGVydHk7Ci0gICAgICAgICAgICB0aGlzLnN5c3RlbVByb3BlcnR5ID0gc3lzdGVtUHJvcGVydHk7Ci0gICAgICAgICAgICB0aGlzLmRlZmF1bHRWYWx1ZSA9IHZhbHVlOwotICAgICAgICAgICAgdGhpcy5zZWN1cmVWYWx1ZSA9IHNlY3VyZVZhbHVlOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzQVBJUHJvcGVydHlOYW1lKFN0cmluZyBwcm9wZXJ0eU5hbWUpIHsKLSAgICAgICAgICAgIHJldHVybiAocHJvcGVydHlOYW1lID09IG51bGwpID8gZmFsc2UgOiBhcGlQcm9wZXJ0eS5lcXVhbHMocHJvcGVydHlOYW1lKTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFsc1N5c3RlbVByb3BlcnR5TmFtZShTdHJpbmcgcHJvcGVydHlOYW1lKSB7Ci0gICAgICAgICAgICByZXR1cm4gKHByb3BlcnR5TmFtZSA9PSBudWxsKSA/IGZhbHNlIDogc3lzdGVtUHJvcGVydHkuZXF1YWxzKHByb3BlcnR5TmFtZSk7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgU3RyaW5nIGtleSgpIHsKLSAgICAgICAgICAgIHJldHVybiBrZXk7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgU3RyaW5nIGFwaVByb3BlcnR5KCkgewotICAgICAgICAgICAgcmV0dXJuIGFwaVByb3BlcnR5OwotICAgICAgICB9Ci0KLSAgICAgICAgU3RyaW5nIHN5c3RlbVByb3BlcnR5KCkgewotICAgICAgICAgICAgcmV0dXJuIHN5c3RlbVByb3BlcnR5OwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIGludCBkZWZhdWx0VmFsdWUoKSB7Ci0gICAgICAgICAgICByZXR1cm4gZGVmYXVsdFZhbHVlOwotICAgICAgICB9Ci0KLSAgICAgICAgaW50IHNlY3VyZVZhbHVlKCkgewotICAgICAgICAgICAgcmV0dXJuIHNlY3VyZVZhbHVlOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogTWFwIG9sZCBwcm9wZXJ0eSBuYW1lcyB3aXRoIHRoZSBuZXcgb25lcwotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZW51bSBOYW1lTWFwIHsKLQotICAgICAgICBFTlRJVFlfRVhQQU5TSU9OX0xJTUlUKFhhbGFuQ29uc3RhbnRzLlNQX0VOVElUWV9FWFBBTlNJT05fTElNSVQsCi0gICAgICAgICAgICAgICAgWGFsYW5Db25zdGFudHMuRU5USVRZX0VYUEFOU0lPTl9MSU1JVCksCi0gICAgICAgIE1BWF9PQ0NVUl9OT0RFX0xJTUlUKFhhbGFuQ29uc3RhbnRzLlNQX01BWF9PQ0NVUl9MSU1JVCwKLSAgICAgICAgICAgICAgICBYYWxhbkNvbnN0YW50cy5NQVhfT0NDVVJfTElNSVQpLAotICAgICAgICBFTEVNRU5UX0FUVFJJQlVURV9MSU1JVChYYWxhbkNvbnN0YW50cy5TUF9FTEVNRU5UX0FUVFJJQlVURV9MSU1JVCwKLSAgICAgICAgICAgICAgICBYYWxhbkNvbnN0YW50cy5FTEVNRU5UX0FUVFJJQlVURV9MSU1JVCk7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBuZXdOYW1lOwotICAgICAgICBmaW5hbCBTdHJpbmcgb2xkTmFtZTsKLQotICAgICAgICBOYW1lTWFwKFN0cmluZyBuZXdOYW1lLCBTdHJpbmcgb2xkTmFtZSkgewotICAgICAgICAgICAgdGhpcy5uZXdOYW1lID0gbmV3TmFtZTsKLSAgICAgICAgICAgIHRoaXMub2xkTmFtZSA9IG9sZE5hbWU7Ci0gICAgICAgIH0KLQotICAgICAgICBTdHJpbmcgZ2V0T2xkTmFtZShTdHJpbmcgbmV3TmFtZSkgewotICAgICAgICAgICAgaWYgKG5ld05hbWUuZXF1YWxzKHRoaXMubmV3TmFtZSkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gb2xkTmFtZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgfQotICAgIC8qKgotICAgICAqIFZhbHVlcyBvZiB0aGUgcHJvcGVydGllcwotICAgICAqLwotICAgIHByaXZhdGUgZmluYWwgaW50W10gdmFsdWVzOwotICAgIC8qKgotICAgICAqIFN0YXRlcyBvZiB0aGUgc2V0dGluZ3MgZm9yIGVhY2ggcHJvcGVydHkKLSAgICAgKi8KLSAgICBwcml2YXRlIFN0YXRlW10gc3RhdGVzOwotICAgIC8qKgotICAgICAqIFN0YXRlcyB0aGF0IGRldGVybWluZSBpZiBwcm9wZXJ0aWVzIGFyZSBzZXQgZXhwbGljaXRseQotICAgICAqLwotICAgIHByaXZhdGUgYm9vbGVhbltdIGlzU2V0OwotCi0KLSAgICAvKioKLSAgICAgKiBJbmRleCBvZiB0aGUgc3BlY2lhbCBlbnRpdHlDb3VudEluZm8gcHJvcGVydHkKLSAgICAgKi8KLSAgICBwcml2YXRlIGZpbmFsIGludCBpbmRleEVudGl0eUNvdW50SW5mbyA9IDEwMDAwOwotICAgIHByaXZhdGUgU3RyaW5nIHByaW50RW50aXR5Q291bnRJbmZvID0gIiI7Ci0KLSAgICAvKioKLSAgICAgKiBEZWZhdWx0IGNvbnN0cnVjdG9yLiBFc3RhYmxpc2hlcyBkZWZhdWx0IHZhbHVlcyBmb3Iga25vd24gc2VjdXJpdHkKLSAgICAgKiB2dWxuZXJhYmlsaXRpZXMuCi0gICAgICovCi0gICAgcHVibGljIFhNTFNlY3VyaXR5TWFuYWdlcigpIHsKLSAgICAgICAgdGhpcyhmYWxzZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSW5zdGFudGlhdGUgU2VjdXJpdHkgTWFuYWdlciBpbiBhY2NvcmRhbmNlIHdpdGggdGhlIHN0YXR1cyBvZgotICAgICAqIHNlY3VyZSBwcm9jZXNzaW5nCi0gICAgICogQHBhcmFtIHNlY3VyZVByb2Nlc3NpbmcKLSAgICAgKi8KLSAgICBwdWJsaWMgWE1MU2VjdXJpdHlNYW5hZ2VyKGJvb2xlYW4gc2VjdXJlUHJvY2Vzc2luZykgewotICAgICAgICB2YWx1ZXMgPSBuZXcgaW50W0xpbWl0LnZhbHVlcygpLmxlbmd0aF07Ci0gICAgICAgIHN0YXRlcyA9IG5ldyBTdGF0ZVtMaW1pdC52YWx1ZXMoKS5sZW5ndGhdOwotICAgICAgICBpc1NldCA9IG5ldyBib29sZWFuW0xpbWl0LnZhbHVlcygpLmxlbmd0aF07Ci0gICAgICAgIGZvciAoTGltaXQgbGltaXQgOiBMaW1pdC52YWx1ZXMoKSkgewotICAgICAgICAgICAgaWYgKHNlY3VyZVByb2Nlc3NpbmcpIHsKLSAgICAgICAgICAgICAgICB2YWx1ZXNbbGltaXQub3JkaW5hbCgpXSA9IGxpbWl0LnNlY3VyZVZhbHVlKCk7Ci0gICAgICAgICAgICAgICAgc3RhdGVzW2xpbWl0Lm9yZGluYWwoKV0gPSBTdGF0ZS5GU1A7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIHZhbHVlc1tsaW1pdC5vcmRpbmFsKCldID0gbGltaXQuZGVmYXVsdFZhbHVlKCk7Ci0gICAgICAgICAgICAgICAgc3RhdGVzW2xpbWl0Lm9yZGluYWwoKV0gPSBTdGF0ZS5ERUZBVUxUOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIC8vcmVhZCBzeXN0ZW0gcHJvcGVydGllcyBvciBqYXhwLnByb3BlcnRpZXMKLSAgICAgICAgcmVhZFN5c3RlbVByb3BlcnRpZXMoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXR0aW5nIEZFQVRVUkVfU0VDVVJFX1BST0NFU1NJTkcgZXhwbGljaXRseQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFNlY3VyZVByb2Nlc3NpbmcoYm9vbGVhbiBzZWN1cmUpIHsKLSAgICAgICAgZm9yIChMaW1pdCBsaW1pdCA6IExpbWl0LnZhbHVlcygpKSB7Ci0gICAgICAgICAgICBpZiAoc2VjdXJlKSB7Ci0gICAgICAgICAgICAgICAgc2V0TGltaXQobGltaXQub3JkaW5hbCgpLCBTdGF0ZS5GU1AsIGxpbWl0LnNlY3VyZVZhbHVlKCkpOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBzZXRMaW1pdChsaW1pdC5vcmRpbmFsKCksIFN0YXRlLkZTUCwgbGltaXQuZGVmYXVsdFZhbHVlKCkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0IGxpbWl0IGJ5IHByb3BlcnR5IG5hbWUgYW5kIHN0YXRlCi0gICAgICogQHBhcmFtIHByb3BlcnR5TmFtZSBwcm9wZXJ0eSBuYW1lCi0gICAgICogQHBhcmFtIHN0YXRlIHRoZSBzdGF0ZSBvZiB0aGUgcHJvcGVydHkKLSAgICAgKiBAcGFyYW0gdmFsdWUgdGhlIHZhbHVlIG9mIHRoZSBwcm9wZXJ0eQotICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgcHJvcGVydHkgaXMgbWFuYWdlZCBieSB0aGUgc2VjdXJpdHkgbWFuYWdlcjsgZmFsc2UKLSAgICAgKiAgICAgICAgICAgICAgaWYgb3RoZXJ3aXNlLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIHNldExpbWl0KFN0cmluZyBwcm9wZXJ0eU5hbWUsIFN0YXRlIHN0YXRlLCBPYmplY3QgdmFsdWUpIHsKLSAgICAgICAgaW50IGluZGV4ID0gZ2V0SW5kZXgocHJvcGVydHlOYW1lKTsKLSAgICAgICAgaWYgKGluZGV4ID4gLTEpIHsKLSAgICAgICAgICAgIHNldExpbWl0KGluZGV4LCBzdGF0ZSwgdmFsdWUpOwotICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldCB0aGUgdmFsdWUgZm9yIGEgc3BlY2lmaWMgbGltaXQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbGltaXQgdGhlIGxpbWl0Ci0gICAgICogQHBhcmFtIHN0YXRlIHRoZSBzdGF0ZSBvZiB0aGUgcHJvcGVydHkKLSAgICAgKiBAcGFyYW0gdmFsdWUgdGhlIHZhbHVlIG9mIHRoZSBwcm9wZXJ0eQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldExpbWl0KExpbWl0IGxpbWl0LCBTdGF0ZSBzdGF0ZSwgaW50IHZhbHVlKSB7Ci0gICAgICAgIHNldExpbWl0KGxpbWl0Lm9yZGluYWwoKSwgc3RhdGUsIHZhbHVlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIHZhbHVlIG9mIGEgcHJvcGVydHkgYnkgaXRzIGluZGV4Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gaW5kZXggdGhlIGluZGV4IG9mIHRoZSBwcm9wZXJ0eQotICAgICAqIEBwYXJhbSBzdGF0ZSB0aGUgc3RhdGUgb2YgdGhlIHByb3BlcnR5Ci0gICAgICogQHBhcmFtIHZhbHVlIHRoZSB2YWx1ZSBvZiB0aGUgcHJvcGVydHkKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRMaW1pdChpbnQgaW5kZXgsIFN0YXRlIHN0YXRlLCBPYmplY3QgdmFsdWUpIHsKLSAgICAgICAgaWYgKGluZGV4ID09IGluZGV4RW50aXR5Q291bnRJbmZvKSB7Ci0gICAgICAgICAgICAvL2lmIGl0J3MgZXhwbGljaXRseSBzZXQsIGl0J3MgdHJlYXRlZCBhcyB5ZXMgbm8gbWF0dGVyIHRoZSB2YWx1ZQotICAgICAgICAgICAgcHJpbnRFbnRpdHlDb3VudEluZm8gPSAoU3RyaW5nKXZhbHVlOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgaW50IHRlbXAgPSAwOwotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICB0ZW1wID0gSW50ZWdlci5wYXJzZUludCgoU3RyaW5nKSB2YWx1ZSk7Ci0gICAgICAgICAgICAgICAgaWYgKHRlbXAgPCAwKSB7Ci0gICAgICAgICAgICAgICAgICAgIHRlbXAgPSAwOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBlKSB7fQotICAgICAgICAgICAgc2V0TGltaXQoaW5kZXgsIHN0YXRlLCB0ZW1wKTsgICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIHZhbHVlIG9mIGEgcHJvcGVydHkgYnkgaXRzIGluZGV4Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gaW5kZXggdGhlIGluZGV4IG9mIHRoZSBwcm9wZXJ0eQotICAgICAqIEBwYXJhbSBzdGF0ZSB0aGUgc3RhdGUgb2YgdGhlIHByb3BlcnR5Ci0gICAgICogQHBhcmFtIHZhbHVlIHRoZSB2YWx1ZSBvZiB0aGUgcHJvcGVydHkKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRMaW1pdChpbnQgaW5kZXgsIFN0YXRlIHN0YXRlLCBpbnQgdmFsdWUpIHsKLSAgICAgICAgaWYgKGluZGV4ID09IGluZGV4RW50aXR5Q291bnRJbmZvKSB7Ci0gICAgICAgICAgICAvL2lmIGl0J3MgZXhwbGljaXRseSBzZXQsIGl0J3MgdHJlYXRlZCBhcyB5ZXMgbm8gbWF0dGVyIHRoZSB2YWx1ZQotICAgICAgICAgICAgcHJpbnRFbnRpdHlDb3VudEluZm8gPSBYYWxhbkNvbnN0YW50cy5KREtfWUVTOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgLy9vbmx5IHVwZGF0ZSBpZiBpdCBzaGFsbCBvdmVycmlkZQotICAgICAgICAgICAgaWYgKHN0YXRlLmNvbXBhcmVUbyhzdGF0ZXNbaW5kZXhdKSA+PSAwKSB7Ci0gICAgICAgICAgICAgICAgdmFsdWVzW2luZGV4XSA9IHZhbHVlOwotICAgICAgICAgICAgICAgIHN0YXRlc1tpbmRleF0gPSBzdGF0ZTsKLSAgICAgICAgICAgICAgICBpc1NldFtpbmRleF0gPSB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgcHJvcGVydHkuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcHJvcGVydHlOYW1lIHRoZSBwcm9wZXJ0eSBuYW1lCi0gICAgICogQHJldHVybiB0aGUgdmFsdWUgb2YgdGhlIHByb3BlcnR5IGFzIGEgc3RyaW5nLiBJZiBhIHByb3BlcnR5IGlzIG1hbmFnZWQKLSAgICAgKiBieSB0aGlzIG1hbmFnZXIsIGl0cyB2YWx1ZSBzaGFsbCBub3QgYmUgbnVsbC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldExpbWl0QXNTdHJpbmcoU3RyaW5nIHByb3BlcnR5TmFtZSkgewotICAgICAgICBpbnQgaW5kZXggPSBnZXRJbmRleChwcm9wZXJ0eU5hbWUpOwotICAgICAgICBpZiAoaW5kZXggPiAtMSkgewotICAgICAgICAgICAgcmV0dXJuIGdldExpbWl0VmFsdWVCeUluZGV4KGluZGV4KTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybiB0aGUgdmFsdWUgb2YgYSBwcm9wZXJ0eSBieSBpdHMgb3JkaW5hbAotICAgICAqCi0gICAgICogQHBhcmFtIGxpbWl0IHRoZSBwcm9wZXJ0eQotICAgICAqIEByZXR1cm4gdmFsdWUgb2YgYSBwcm9wZXJ0eQotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TGltaXRWYWx1ZUFzU3RyaW5nKExpbWl0IGxpbWl0KSB7Ci0gICAgICAgIHJldHVybiBJbnRlZ2VyLnRvU3RyaW5nKHZhbHVlc1tsaW1pdC5vcmRpbmFsKCldKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgcHJvcGVydHkKLSAgICAgKgotICAgICAqIEBwYXJhbSBsaW1pdCB0aGUgcHJvcGVydHkKLSAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgcHJvcGVydHkKLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldExpbWl0KExpbWl0IGxpbWl0KSB7Ci0gICAgICAgIHJldHVybiB2YWx1ZXNbbGltaXQub3JkaW5hbCgpXTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIHZhbHVlIG9mIGEgcHJvcGVydHkgYnkgaXRzIG9yZGluYWwKLSAgICAgKgotICAgICAqIEBwYXJhbSBpbmRleCB0aGUgaW5kZXggb2YgYSBwcm9wZXJ0eQotICAgICAqIEByZXR1cm4gdmFsdWUgb2YgYSBwcm9wZXJ0eQotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0TGltaXRCeUluZGV4KGludCBpbmRleCkgewotICAgICAgICByZXR1cm4gdmFsdWVzW2luZGV4XTsKLSAgICB9Ci0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSB2YWx1ZSBvZiBhIHByb3BlcnR5IGJ5IGl0cyBpbmRleAotICAgICAqCi0gICAgICogQHBhcmFtIGluZGV4IHRoZSBpbmRleCBvZiBhIHByb3BlcnR5Ci0gICAgICogQHJldHVybiBsaW1pdCBvZiBhIHByb3BlcnR5IGFzIGEgc3RyaW5nCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRMaW1pdFZhbHVlQnlJbmRleChpbnQgaW5kZXgpIHsKLSAgICAgICAgaWYgKGluZGV4ID09IGluZGV4RW50aXR5Q291bnRJbmZvKSB7Ci0gICAgICAgICAgICByZXR1cm4gcHJpbnRFbnRpdHlDb3VudEluZm87Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gSW50ZWdlci50b1N0cmluZyh2YWx1ZXNbaW5kZXhdKTsKLSAgICB9Ci0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSBzdGF0ZSBvZiB0aGUgbGltaXQgcHJvcGVydHkKLSAgICAgKgotICAgICAqIEBwYXJhbSBsaW1pdCB0aGUgbGltaXQKLSAgICAgKiBAcmV0dXJuIHRoZSBzdGF0ZSBvZiB0aGUgbGltaXQgcHJvcGVydHkKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RhdGUgZ2V0U3RhdGUoTGltaXQgbGltaXQpIHsKLSAgICAgICAgcmV0dXJuIHN0YXRlc1tsaW1pdC5vcmRpbmFsKCldOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybiB0aGUgc3RhdGUgb2YgdGhlIGxpbWl0IHByb3BlcnR5Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gbGltaXQgdGhlIGxpbWl0Ci0gICAgICogQHJldHVybiB0aGUgc3RhdGUgb2YgdGhlIGxpbWl0IHByb3BlcnR5Ci0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRTdGF0ZUxpdGVyYWwoTGltaXQgbGltaXQpIHsKLSAgICAgICAgcmV0dXJuIHN0YXRlc1tsaW1pdC5vcmRpbmFsKCldLmxpdGVyYWwoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIGluZGV4IGJ5IHByb3BlcnR5IG5hbWUKLSAgICAgKgotICAgICAqIEBwYXJhbSBwcm9wZXJ0eU5hbWUgcHJvcGVydHkgbmFtZQotICAgICAqIEByZXR1cm4gdGhlIGluZGV4IG9mIHRoZSBwcm9wZXJ0eSBpZiBmb3VuZDsgcmV0dXJuIC0xIGlmIG5vdAotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0SW5kZXgoU3RyaW5nIHByb3BlcnR5TmFtZSkgewotICAgICAgICBmb3IgKExpbWl0IGxpbWl0IDogTGltaXQudmFsdWVzKCkpIHsKLSAgICAgICAgICAgIGlmIChsaW1pdC5lcXVhbHNBUElQcm9wZXJ0eU5hbWUocHJvcGVydHlOYW1lKSkgewotICAgICAgICAgICAgICAgIC8vaW50ZXJuYWxseSwgb3JkaW5hbCBpcyB1c2VkIGFzIGluZGV4Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGxpbWl0Lm9yZGluYWwoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICAvL3NwZWNpYWwgcHJvcGVydHkgdG8gcmV0dXJuIGVudGl0eSBjb3VudCBpbmZvCi0gICAgICAgIGlmIChwcm9wZXJ0eU5hbWUuZXF1YWxzKFhhbGFuQ29uc3RhbnRzLkpES19FTlRJVFlfQ09VTlRfSU5GTykpIHsKLSAgICAgICAgICAgIHJldHVybiBpbmRleEVudGl0eUNvdW50SW5mbzsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gLTE7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSW5kaWNhdGUgaWYgYSBwcm9wZXJ0eSBpcyBzZXQgZXhwbGljaXRseQotICAgICAqIEBwYXJhbSBpbmRleAotICAgICAqIEByZXR1cm4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc1NldChpbnQgaW5kZXgpIHsKLSAgICAgICAgcmV0dXJuIGlzU2V0W2luZGV4XTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBwcmludEVudGl0eUNvdW50SW5mbygpIHsKLSAgICAgICAgcmV0dXJuIHByaW50RW50aXR5Q291bnRJbmZvLmVxdWFscyhYYWxhbkNvbnN0YW50cy5KREtfWUVTKTsKLSAgICB9Ci0gICAgLyoqCi0gICAgICogUmVhZCBmcm9tIHN5c3RlbSBwcm9wZXJ0aWVzLCBvciB0aG9zZSBpbiBqYXhwLnByb3BlcnRpZXMKLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgcmVhZFN5c3RlbVByb3BlcnRpZXMoKSB7Ci0KLSAgICAgICAgZm9yIChMaW1pdCBsaW1pdCA6IExpbWl0LnZhbHVlcygpKSB7Ci0gICAgICAgICAgICBpZiAoIWdldFN5c3RlbVByb3BlcnR5KGxpbWl0LCBsaW1pdC5zeXN0ZW1Qcm9wZXJ0eSgpKSkgewotICAgICAgICAgICAgICAgIC8vaWYgc3lzdGVtIHByb3BlcnR5IGlzIG5vdCBmb3VuZCwgdHJ5IHRoZSBvbGRlciBmb3JtIGlmIGFueQotICAgICAgICAgICAgICAgIGZvciAoTmFtZU1hcCBuYW1lTWFwIDogTmFtZU1hcC52YWx1ZXMoKSkgewotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgb2xkTmFtZSA9IG5hbWVNYXAuZ2V0T2xkTmFtZShsaW1pdC5zeXN0ZW1Qcm9wZXJ0eSgpKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKG9sZE5hbWUgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgZ2V0U3lzdGVtUHJvcGVydHkobGltaXQsIG9sZE5hbWUpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICB9Ci0KLSAgICAvLyBBcnJheSBsaXN0IHRvIHN0b3JlIHByaW50ZWQgd2FybmluZ3MgZm9yIGVhY2ggU0FYIHBhcnNlciB1c2VkCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQ29weU9uV3JpdGVBcnJheUxpc3Q8U3RyaW5nPiBwcmludGVkV2FybmluZ3MgPSBuZXcgQ29weU9uV3JpdGVBcnJheUxpc3Q8PigpOwotCi0gICAgLyoqCi0gICAgICogUHJpbnRzIG91dCB3YXJuaW5ncyBpZiBhIHBhcnNlciBkb2VzIG5vdCBzdXBwb3J0IHRoZSBzcGVjaWZpZWQgZmVhdHVyZS9wcm9wZXJ0eS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBwYXJzZXJDbGFzc05hbWUgdGhlIG5hbWUgb2YgdGhlIHBhcnNlciBjbGFzcwotICAgICAqIEBwYXJhbSBwcm9wZXJ0eU5hbWUgdGhlIHByb3BlcnR5IG5hbWUKLSAgICAgKiBAcGFyYW0gZXhjZXB0aW9uIHRoZSBleGNlcHRpb24gdGhyb3duIGJ5IHRoZSBwYXJzZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIHZvaWQgcHJpbnRXYXJuaW5nKFN0cmluZyBwYXJzZXJDbGFzc05hbWUsIFN0cmluZyBwcm9wZXJ0eU5hbWUsIFNBWEV4Y2VwdGlvbiBleGNlcHRpb24pIHsKLSAgICAgICAgU3RyaW5nIGtleSA9IHBhcnNlckNsYXNzTmFtZSsiOiIrcHJvcGVydHlOYW1lOwotICAgICAgICBpZiAocHJpbnRlZFdhcm5pbmdzLmFkZElmQWJzZW50KGtleSkpIHsKLSAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbiggIldhcm5pbmc6ICIrcGFyc2VyQ2xhc3NOYW1lKyI6ICIrZXhjZXB0aW9uLmdldE1lc3NhZ2UoKSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZWFkIGZyb20gc3lzdGVtIHByb3BlcnRpZXMsIG9yIHRob3NlIGluIGpheHAucHJvcGVydGllcwotICAgICAqCi0gICAgICogQHBhcmFtIHByb3BlcnR5IHRoZSB0eXBlIG9mIHRoZSBwcm9wZXJ0eQotICAgICAqIEBwYXJhbSBzeXNQcm9wZXJ0eU5hbWUgdGhlIG5hbWUgb2Ygc3lzdGVtIHByb3BlcnR5Ci0gICAgICovCi0gICAgcHJpdmF0ZSBib29sZWFuIGdldFN5c3RlbVByb3BlcnR5KExpbWl0IGxpbWl0LCBTdHJpbmcgc3lzUHJvcGVydHlOYW1lKSB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBTdHJpbmcgdmFsdWUgPSBTZWN1cml0eVN1cHBvcnQuZ2V0U3lzdGVtUHJvcGVydHkoc3lzUHJvcGVydHlOYW1lKTsKLSAgICAgICAgICAgIGlmICh2YWx1ZSAhPSBudWxsICYmICF2YWx1ZS5lcXVhbHMoIiIpKSB7Ci0gICAgICAgICAgICAgICAgdmFsdWVzW2xpbWl0Lm9yZGluYWwoKV0gPSBJbnRlZ2VyLnBhcnNlSW50KHZhbHVlKTsKLSAgICAgICAgICAgICAgICBzdGF0ZXNbbGltaXQub3JkaW5hbCgpXSA9IFN0YXRlLlNZU1RFTVBST1BFUlRZOwotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICB2YWx1ZSA9IFNlY3VyaXR5U3VwcG9ydC5yZWFkSkFYUFByb3BlcnR5KHN5c1Byb3BlcnR5TmFtZSk7Ci0gICAgICAgICAgICBpZiAodmFsdWUgIT0gbnVsbCAmJiAhdmFsdWUuZXF1YWxzKCIiKSkgewotICAgICAgICAgICAgICAgIHZhbHVlc1tsaW1pdC5vcmRpbmFsKCldID0gSW50ZWdlci5wYXJzZUludCh2YWx1ZSk7Ci0gICAgICAgICAgICAgICAgc3RhdGVzW2xpbWl0Lm9yZGluYWwoKV0gPSBTdGF0ZS5KQVhQRE9UUFJPUEVSVElFUzsKLSAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIC8vaW52YWxpZCBzZXR0aW5nCi0gICAgICAgICAgICB0aHJvdyBuZXcgTnVtYmVyRm9ybWF0RXhjZXB0aW9uKCJJbnZhbGlkIHNldHRpbmcgZm9yIHN5c3RlbSBwcm9wZXJ0eTogIiArIGxpbWl0LnN5c3RlbVByb3BlcnR5KCkpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3V0aWxzL1hNTFNlY3VyaXR5UHJvcGVydHlNYW5hZ2VyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3V0aWxzL1hNTFNlY3VyaXR5UHJvcGVydHlNYW5hZ2VyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDYxMTEyMGIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC91dGlscy9YTUxTZWN1cml0eVByb3BlcnR5TWFuYWdlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTAyICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMTMsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnV0aWxzOwotCi0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwuWGFsYW5Db25zdGFudHM7Ci1pbXBvcnQgamF2YXgueG1sLlhNTENvbnN0YW50czsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIG1hbmFnZXMgc2VjdXJpdHkgcmVsYXRlZCBwcm9wZXJ0aWVzCi0gKgotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgWE1MU2VjdXJpdHlQcm9wZXJ0eU1hbmFnZXIgZXh0ZW5kcyBGZWF0dXJlUHJvcGVydHlCYXNlIHsKLQotICAgIC8qKgotICAgICAqIFByb3BlcnRpZXMgbWFuYWdlZCBieSB0aGUgc2VjdXJpdHkgcHJvcGVydHkgbWFuYWdlcgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZW51bSBQcm9wZXJ0eSB7Ci0gICAgICAgIEFDQ0VTU19FWFRFUk5BTF9EVEQoWE1MQ29uc3RhbnRzLkFDQ0VTU19FWFRFUk5BTF9EVEQsCi0gICAgICAgICAgICAgICAgWGFsYW5Db25zdGFudHMuRVhURVJOQUxfQUNDRVNTX0RFRkFVTFQpLAotICAgICAgICBBQ0NFU1NfRVhURVJOQUxfU1RZTEVTSEVFVChYTUxDb25zdGFudHMuQUNDRVNTX0VYVEVSTkFMX1NUWUxFU0hFRVQsCi0gICAgICAgICAgICAgICAgWGFsYW5Db25zdGFudHMuRVhURVJOQUxfQUNDRVNTX0RFRkFVTFQpOwotCi0gICAgICAgIGZpbmFsIFN0cmluZyBuYW1lOwotICAgICAgICBmaW5hbCBTdHJpbmcgZGVmYXVsdFZhbHVlOwotCi0gICAgICAgIFByb3BlcnR5KFN0cmluZyBuYW1lLCBTdHJpbmcgdmFsdWUpIHsKLSAgICAgICAgICAgIHRoaXMubmFtZSA9IG5hbWU7Ci0gICAgICAgICAgICB0aGlzLmRlZmF1bHRWYWx1ZSA9IHZhbHVlOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzTmFtZShTdHJpbmcgcHJvcGVydHlOYW1lKSB7Ci0gICAgICAgICAgICByZXR1cm4gKHByb3BlcnR5TmFtZSA9PSBudWxsKSA/IGZhbHNlIDogbmFtZS5lcXVhbHMocHJvcGVydHlOYW1lKTsKLSAgICAgICAgfQotCi0gICAgICAgIFN0cmluZyBkZWZhdWx0VmFsdWUoKSB7Ci0gICAgICAgICAgICByZXR1cm4gZGVmYXVsdFZhbHVlOwotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBEZWZhdWx0IGNvbnN0cnVjdG9yLiBFc3RhYmxpc2hlcyBkZWZhdWx0IHZhbHVlcwotICAgICAqLwotICAgIHB1YmxpYyBYTUxTZWN1cml0eVByb3BlcnR5TWFuYWdlcigpIHsKLSAgICAgICAgdmFsdWVzID0gbmV3IFN0cmluZ1tQcm9wZXJ0eS52YWx1ZXMoKS5sZW5ndGhdOwotICAgICAgICBmb3IgKFByb3BlcnR5IHByb3BlcnR5IDogUHJvcGVydHkudmFsdWVzKCkpIHsKLSAgICAgICAgICAgIHZhbHVlc1twcm9wZXJ0eS5vcmRpbmFsKCldID0gcHJvcGVydHkuZGVmYXVsdFZhbHVlKCk7Ci0gICAgICAgIH0KLSAgICAgICAgLy9yZWFkIHN5c3RlbSBwcm9wZXJ0aWVzIG9yIGpheHAucHJvcGVydGllcwotICAgICAgICByZWFkU3lzdGVtUHJvcGVydGllcygpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgaW5kZXggYnkgcHJvcGVydHkgbmFtZQotICAgICAqIEBwYXJhbSBwcm9wZXJ0eU5hbWUgcHJvcGVydHkgbmFtZQotICAgICAqIEByZXR1cm4gdGhlIGluZGV4IG9mIHRoZSBwcm9wZXJ0eSBpZiBmb3VuZDsgcmV0dXJuIC0xIGlmIG5vdAotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0SW5kZXgoU3RyaW5nIHByb3BlcnR5TmFtZSl7Ci0gICAgICAgIGZvciAoUHJvcGVydHkgcHJvcGVydHkgOiBQcm9wZXJ0eS52YWx1ZXMoKSkgewotICAgICAgICAgICAgaWYgKHByb3BlcnR5LmVxdWFsc05hbWUocHJvcGVydHlOYW1lKSkgewotICAgICAgICAgICAgICAgIC8vaW50ZXJuYWxseSwgb3JkaW5hbCBpcyB1c2VkIGFzIGluZGV4Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHByb3BlcnR5Lm9yZGluYWwoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gLTE7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmVhZCBmcm9tIHN5c3RlbSBwcm9wZXJ0aWVzLCBvciB0aG9zZSBpbiBqYXhwLnByb3BlcnRpZXMKLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgcmVhZFN5c3RlbVByb3BlcnRpZXMoKSB7Ci0gICAgICAgIGdldFN5c3RlbVByb3BlcnR5KFByb3BlcnR5LkFDQ0VTU19FWFRFUk5BTF9EVEQsCi0gICAgICAgICAgICAgICAgWGFsYW5Db25zdGFudHMuU1BfQUNDRVNTX0VYVEVSTkFMX0RURCk7Ci0gICAgICAgIGdldFN5c3RlbVByb3BlcnR5KFByb3BlcnR5LkFDQ0VTU19FWFRFUk5BTF9TVFlMRVNIRUVULAotICAgICAgICAgICAgICAgIFhhbGFuQ29uc3RhbnRzLlNQX0FDQ0VTU19FWFRFUk5BTF9TVFlMRVNIRUVUKTsKLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdC9FbnZpcm9ubWVudENoZWNrLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHQvRW52aXJvbm1lbnRDaGVjay5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhOTMzMWYyLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdC9FbnZpcm9ubWVudENoZWNrLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMjUzICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKi8KLS8qCi0gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKLSAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAotICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgotICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKLSAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCi0gKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRW52aXJvbm1lbnRDaGVjay5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzA5IDA3OjEzOjU5IHB2ZWR1bGEgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdDsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC51dGlscy5PYmplY3RGYWN0b3J5OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC51dGlscy5TZWN1cml0eVN1cHBvcnQ7Ci1pbXBvcnQgamF2YS5pby5GaWxlOwotaW1wb3J0IGphdmEuaW8uRmlsZVdyaXRlcjsKLWltcG9ydCBqYXZhLmlvLlByaW50V3JpdGVyOwotaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkZpZWxkOwotaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lk1ldGhvZDsKLWltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwotaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKLWltcG9ydCBqYXZhLnV0aWwuTGlzdDsKLWltcG9ydCBqYXZhLnV0aWwuTWFwOwotaW1wb3J0IGphdmEudXRpbC5TdHJpbmdUb2tlbml6ZXI7Ci1pbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7Ci1pbXBvcnQgb3JnLnczYy5kb20uRWxlbWVudDsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotCi0vKioKLSAqIFV0aWxpdHkgY2xhc3MgdG8gcmVwb3J0IHNpbXBsZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgZW52aXJvbm1lbnQuCi0gKiBTaW1wbGlzdGljIHJlcG9ydGluZyBhYm91dCBjZXJ0YWluIGNsYXNzZXMgZm91bmQgaW4geW91ciBKVk0gbWF5Ci0gKiBoZWxwIGFuc3dlciBzb21lIEZBUXMgZm9yIHNpbXBsZSBwcm9ibGVtcy4KLSAqCi0gKiA8cD5Vc2FnZS1jb21tYW5kIGxpbmU6Ci0gKiA8Y29kZT4KLSAqIGphdmEgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHQuRW52aXJvbm1lbnRDaGVjayBbLW91dCBvdXRGaWxlXQotICogPC9jb2RlPjwvcD4KLSAqCi0gKiA8cD5Vc2FnZS1mcm9tIHByb2dyYW06Ci0gKiA8Y29kZT4KLSAqIGJvb2xlYW4gZW52aXJvbm1lbnRPSyA9Ci0gKiAobmV3IEVudmlyb25tZW50Q2hlY2soKSkuY2hlY2tFbnZpcm9ubWVudCh5b3VyUHJpbnRXcml0ZXIpOwotICogPC9jb2RlPjwvcD4KLSAqCi0gKiA8cD5Vc2FnZS1mcm9tIHN0eWxlc2hlZXQ6Ci0gKiA8Y29kZT48cHJlPgotICogICAgJmx0Oz94bWwgdmVyc2lvbj0iMS4wIj8mZ3Q7Ci0gKiAgICAmbHQ7eHNsOnN0eWxlc2hlZXQgeG1sbnM6eHNsPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L1hTTC9UcmFuc2Zvcm0iIHZlcnNpb249IjEuMCIKLSAqICAgICAgICB4bWxuczp4YWxhbj0iaHR0cDovL3htbC5hcGFjaGUub3JnL3hhbGFuIgotICogICAgICAgIGV4Y2x1ZGUtcmVzdWx0LXByZWZpeGVzPSJ4YWxhbiImZ3Q7Ci0gKiAgICAmbHQ7eHNsOm91dHB1dCBpbmRlbnQ9InllcyIvJmd0OwotICogICAgJmx0O3hzbDp0ZW1wbGF0ZSBtYXRjaD0iLyImZ3Q7Ci0gKiAgICAgICZsdDt4c2w6Y29weS1vZiBzZWxlY3Q9InhhbGFuOmNoZWNrRW52aXJvbm1lbnQoKSIvJmd0OwotICogICAgJmx0Oy94c2w6dGVtcGxhdGUmZ3Q7Ci0gKiAgICAmbHQ7L3hzbDpzdHlsZXNoZWV0Jmd0OwotICogPC9wcmU+PC9jb2RlPjwvcD4KLSAqCi0gKiA8cD5YYWxhbiB1c2VycyByZXBvcnRpbmcgcHJvYmxlbXMgYXJlIGVuY291cmFnZWQgdG8gdXNlIHRoaXMgY2xhc3MKLSAqIHRvIHNlZSBpZiB0aGVyZSBhcmUgcG90ZW50aWFsIHByb2JsZW1zIHdpdGggdGhlaXIgYWN0dWFsCi0gKiBKYXZhIGVudmlyb25tZW50IDxiPmJlZm9yZTwvYj4gcmVwb3J0aW5nIGEgYnVnLiAgTm90ZSB0aGF0IHlvdQotICogc2hvdWxkIGJvdGggY2hlY2sgZnJvbSB0aGUgSlZNL0pSRSdzIGNvbW1hbmQgbGluZSBhcyB3ZWxsIGFzCi0gKiB0ZW1wb3JhcmlseSBjYWxsaW5nIGNoZWNrRW52aXJvbm1lbnQoKSBkaXJlY3RseSBmcm9tIHlvdXIgY29kZSwKLSAqIHNpbmNlIHRoZSBjbGFzc3BhdGggbWF5IGRpZmZlciAoZXNwZWNpYWxseSBmb3Igc2VydmxldHMsIGV0YykuPC9wPgotICoKLSAqIDxwPkFsc28gc2VlIGh0dHA6Ly94bWwuYXBhY2hlLm9yZy94YWxhbi1qL2ZhcS5odG1sPC9wPgotICoKLSAqIDxwPk5vdGU6IFRoaXMgY2xhc3MgaXMgcHJldHR5IHNpbXBsaXN0aWM6Ci0gKiByZXN1bHRzIGFyZSBub3QgbmVjZXNzYXJpbHkgZGVmaW5pdGl2ZSBub3Igd2lsbCBpdCBmaW5kIGFsbAotICogcHJvYmxlbXMgcmVsYXRlZCB0byBlbnZpcm9ubWVudCBzZXR1cC4gIEFsc28sIHlvdSBzaG91bGQgYXZvaWQKLSAqIGNhbGxpbmcgdGhpcyBpbiBkZXBsb3llZCBwcm9kdWN0aW9uIGNvZGUsIGJvdGggYmVjYXVzZSBpdCBpcwotICogcXVpdGUgc2xvdyBhbmQgYmVjYXVzZSBpdCBmb3JjZXMgY2xhc3NlcyB0byBnZXQgbG9hZGVkLjwvcD4KLSAqCi0gKiA8cD5Ob3RlOiBUaGlzIGNsYXNzIGV4cGxpY2l0bHkgaGFzIHZlcnkgbGltaXRlZCBjb21waWxlLXRpbWUKLSAqIGRlcGVuZGVuY2llcyB0byBlbmFibGUgZWFzeSBjb21waWxhdGlvbiBhbmQgdXNhZ2UgZXZlbiB3aGVuCi0gKiBYYWxhbiwgRE9NL1NBWC9KQVhQLCBldGMuIGFyZSBub3QgcHJlc2VudC48L3A+Ci0gKgotICogPHA+Tm90ZTogZm9yIGFuIGltcHJvdmVkIHZlcnNpb24gb2YgdGhpcyB1dGlsaXR5LCBwbGVhc2Ugc2VlCi0gKiB0aGUgeG1sLWNvbW1vbnMnIHByb2plY3QgV2hpY2ggdXRpbGl0eSB3aGljaCBkb2VzIHRoZSBzYW1lIGtpbmQKLSAqIG9mIHRoaW5nIGJ1dCBpbiBhIG11Y2ggc2ltcGxlciBtYW5uZXIuPC9wPgotICoKLSAqIEBhdXRob3IgU2hhbmVfQ3VyY3VydUB1cy5pYm0uY29tCi0gKiBAdmVyc2lvbiAkSWQ6IEVudmlyb25tZW50Q2hlY2suamF2YSx2IDEuMTAgMjAxMC0xMS0wMSAwNDozNDoxMyBqb2VodyBFeHAgJAotICovCi1wdWJsaWMgY2xhc3MgRW52aXJvbm1lbnRDaGVjawotewotCi0gIC8qKgotICAgKiBDb21tYW5kIGxpbmUgcnVubmFiaWxpdHk6IGNoZWNrcyBmb3IgWy1vdXQgb3V0RmlsZW5hbWVdIGFyZy4KLSAgICogPHA+Q29tbWFuZCBsaW5lIGVudHJ5cG9pbnQ7IFNldHMgb3V0cHV0IGFuZCBjYWxscwotICAgKiB7QGxpbmsgI2NoZWNrRW52aXJvbm1lbnQoUHJpbnRXcml0ZXIpfS48L3A+Ci0gICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmdzCi0gICAqLwotICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKQotICB7Ci0gICAgLy8gRGVmYXVsdCB0byBTeXN0ZW0ub3V0LCBhdXRvZmx1c2hpbmcKLSAgICBQcmludFdyaXRlciBzZW5kT3V0cHV0VG8gPSBuZXcgUHJpbnRXcml0ZXIoU3lzdGVtLm91dCwgdHJ1ZSk7Ci0KLSAgICAvLyBSZWFkIG91ciBzaW1wbGlzdGljIGlucHV0IGFyZ3MsIGlmIHN1cHBsaWVkCi0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhcmdzLmxlbmd0aDsgaSsrKQotICAgIHsKLSAgICAgIGlmICgiLW91dCIuZXF1YWxzSWdub3JlQ2FzZShhcmdzW2ldKSkKLSAgICAgIHsKLSAgICAgICAgaSsrOwotCi0gICAgICAgIGlmIChpIDwgYXJncy5sZW5ndGgpCi0gICAgICAgIHsKLSAgICAgICAgICB0cnkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBzZW5kT3V0cHV0VG8gPSBuZXcgUHJpbnRXcml0ZXIobmV3IEZpbGVXcml0ZXIoYXJnc1tpXSwgdHJ1ZSkpOwotICAgICAgICAgIH0KLSAgICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGUpCi0gICAgICAgICAgewotICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCIjIFdBUk5JTkc6IC1vdXQgIiArIGFyZ3NbaV0gKyAiIHRocmV3ICIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGUudG9TdHJpbmcoKSk7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigKLSAgICAgICAgICAgICIjIFdBUk5JTkc6IC1vdXQgYXJndW1lbnQgc2hvdWxkIGhhdmUgYSBmaWxlbmFtZSwgb3V0cHV0IHNlbnQgdG8gY29uc29sZSIpOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotCi0gICAgRW52aXJvbm1lbnRDaGVjayBhcHAgPSBuZXcgRW52aXJvbm1lbnRDaGVjaygpOwotICAgIGFwcC5jaGVja0Vudmlyb25tZW50KHNlbmRPdXRwdXRUbyk7Ci0gIH0KLQotICAvKioKLSAgICogUHJvZ3JhbW1hdGljIGVudHJ5cG9pbnQ6IFJlcG9ydCBvbiBiYXNpYyBKYXZhIGVudmlyb25tZW50Ci0gICAqIGFuZCBDTEFTU1BBVEggc2V0dGluZ3MgdGhhdCBhZmZlY3QgWGFsYW4uCi0gICAqCi0gICAqIDxwPk5vdGUgdGhhdCB0aGlzIGNsYXNzIGlzIG5vdCBhZHZhbmNlZCBlbm91Z2ggdG8gdGVsbCB5b3UKLSAgICogZXZlcnl0aGluZyBhYm91dCB0aGUgZW52aXJvbm1lbnQgdGhhdCBhZmZlY3RzIFhhbGFuLCBhbmQKLSAgICogc29tZXRpbWVzIHJlcG9ydHMgZXJyb3JzIHRoYXQgd2lsbCBub3QgYWN0dWFsbHkgYWZmZWN0Ci0gICAqIFhhbGFuJ3MgYmVoYXZpb3IuICBDdXJyZW50bHksIGl0IHZlcnkgc2ltcGxpc3RpY2FsbHkKLSAgICogY2hlY2tzIHRoZSBKVk0ncyBlbnZpcm9ubWVudCBmb3Igc29tZSBiYXNpYyBwcm9wZXJ0aWVzIGFuZAotICAgKiBsb2dzIHRoZW0gb3V0OyBpdCB3aWxsIHJlcG9ydCBhIHByb2JsZW0gaWYgaXQgZmluZHMgYSBzZXR0aW5nCi0gICAqIG9yIC5qYXIgZmlsZSB0aGF0IGlzIDxpPmxpa2VseTwvaT4gdG8gY2F1c2UgcHJvYmxlbXMuPC9wPgotICAgKgotICAgKiA8cD5BZHZhbmNlZCB1c2VycyBjYW4gcGVydXNlIHRoZSBjb2RlIGhlcmVpbiB0byBoZWxwIHRoZW0KLSAgICogaW52ZXN0aWdhdGUgcG90ZW50aWFsIGVudmlyb25tZW50IHByb2JsZW1zIGZvdW5kOyBvdGhlciB1c2VycwotICAgKiBtYXkgc2ltcGx5IHNlbmQgdGhlIG91dHB1dCBmcm9tIHRoaXMgdG9vbCBhbG9uZyB3aXRoIGFueSBidWdzCi0gICAqIHRoZXkgc3VibWl0IHRvIGhlbHAgdXMgaW4gdGhlIGRlYnVnZ2luZyBwcm9jZXNzLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIHB3IFByaW50V3JpdGVyIHRvIHNlbmQgb3V0cHV0IHRvOyBjYW4gYmUgc2VudCB0byBhCi0gICAqIGZpbGUgdGhhdCB3aWxsIGxvb2sgc2ltaWxhciB0byBhIFByb3BlcnRpZXMgZmlsZTsgZGVmYXVsdHMKLSAgICogdG8gU3lzdGVtLm91dCBpZiBudWxsCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB5b3VyIGVudmlyb25tZW50IGFwcGVhcnMgdG8gaGF2ZSBubyBtYWpvcgotICAgKiBwcm9ibGVtczsgZmFsc2UgaWYgcG90ZW50aWFsIGVudmlyb25tZW50IHByb2JsZW1zIGZvdW5kCi0gICAqIEBzZWUgI2dldEVudmlyb25tZW50SGFzaCgpCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBjaGVja0Vudmlyb25tZW50KFByaW50V3JpdGVyIHB3KQotICB7Ci0KLSAgICAvLyBVc2UgdXNlci1zcGVjaWZpZWQgb3V0cHV0IHdyaXRlciBpZiBub24tbnVsbAotICAgIGlmIChudWxsICE9IHB3KQotICAgICAgb3V0V3JpdGVyID0gcHc7Ci0KLSAgICAvLyBTZXR1cCBhIGhhc2ggdG8gc3RvcmUgdmFyaW91cyBlbnZpcm9ubWVudCBpbmZvcm1hdGlvbiBpbgotICAgIE1hcDxTdHJpbmcsIE9iamVjdD4gaGFzaCA9IGdldEVudmlyb25tZW50SGFzaCgpOwotCi0gICAgLy8gQ2hlY2sgZm9yIEVSUk9SIGtleXMgaW4gdGhlIGhhc2h0YWJsZSwgYW5kIHByaW50IHJlcG9ydAotICAgIGJvb2xlYW4gZW52aXJvbm1lbnRIYXNFcnJvcnMgPSB3cml0ZUVudmlyb25tZW50UmVwb3J0KGhhc2gpOwotCi0gICAgaWYgKGVudmlyb25tZW50SGFzRXJyb3JzKQotICAgIHsKLSAgICAgIC8vIE5vdGU6IG1hbnkgbG9nTXNnIGNhbGxzIGhhdmUgIyBhdCB0aGUgc3RhcnQgdG8KLSAgICAgIC8vICBmYWtlIGEgcHJvcGVydHktZmlsZSBsaWtlIG91dHB1dAotICAgICAgbG9nTXNnKCIjIFdBUk5JTkc6IFBvdGVudGlhbCBwcm9ibGVtcyBmb3VuZCBpbiB5b3VyIGVudmlyb25tZW50ISIpOwotICAgICAgbG9nTXNnKCIjICAgIENoZWNrIGFueSAnRVJST1InIGl0ZW1zIGFib3ZlIGFnYWluc3QgdGhlIFhhbGFuIEZBUXMiKTsKLSAgICAgIGxvZ01zZygiIyAgICB0byBjb3JyZWN0IHBvdGVudGlhbCBwcm9ibGVtcyB3aXRoIHlvdXIgY2xhc3Nlcy9qYXJzIik7Ci0gICAgICBsb2dNc2coIiMgICAgaHR0cDovL3htbC5hcGFjaGUub3JnL3hhbGFuLWovZmFxLmh0bWwiKTsKLSAgICAgIGlmIChudWxsICE9IG91dFdyaXRlcikKLSAgICAgICAgb3V0V3JpdGVyLmZsdXNoKCk7Ci0gICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBsb2dNc2coIiMgWUFIT08hIFlvdXIgZW52aXJvbm1lbnQgc2VlbXMgdG8gYmUgT0suIik7Ci0gICAgICBpZiAobnVsbCAhPSBvdXRXcml0ZXIpCi0gICAgICAgIG91dFdyaXRlci5mbHVzaCgpOwotICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEZpbGwgYSBoYXNoIHdpdGggYmFzaWMgZW52aXJvbm1lbnQgc2V0dGluZ3MgdGhhdCBhZmZlY3QgWGFsYW4uCi0gICAqCi0gICAqIDxwPldvcmtlciBtZXRob2QgY2FsbGVkIGZyb20gdmFyaW91cyBwbGFjZXMuPC9wPgotICAgKiA8cD5WYXJpb3VzIHN5c3RlbSBhbmQgQ0xBU1NQQVRILCBldGMuIHByb3BlcnRpZXMgYXJlIHB1dCBpbnRvCi0gICAqIHRoZSBoYXNoIGFzIGtleXMgd2l0aCBhIGJyaWVmIGRlc2NyaXB0aW9uIG9mIHRoZSBjdXJyZW50IHN0YXRlCi0gICAqIG9mIHRoYXQgaXRlbSBhcyB0aGUgdmFsdWUuICBBbnkgc2VyaW91cyBwcm9ibGVtcyB3aWxsIGJlIHB1dCBpbgotICAgKiB3aXRoIGEga2V5IHRoYXQgaXMgcHJlZml4ZWQgd2l0aCB7QGxpbmsgI0VSUk9SICdFUlJPUi4nfSBzbyBpdAotICAgKiBzdGFuZHMgb3V0IGluIGFueSByZXN1bHRpbmcgcmVwb3J0OyBhbHNvIGEga2V5IHdpdGgganVzdCB0aGF0Ci0gICAqIGNvbnN0YW50IHdpbGwgYmUgc2V0IGFzIHdlbGwgZm9yIGFueSBlcnJvci48L3A+Ci0gICAqIDxwPk5vdGUgdGhhdCBzb21lIGxlZ2l0aW1hdGUgY2FzZXMgYXJlIGZsYWdlZCBhcyBwb3RlbnRpYWwKLSAgICogZXJyb3JzIC0gbmFtZWx5IHdoZW4gYSBkZXZlbG9wZXIgcmVjb21waWxlcyB4YWxhbi5qYXIgb24gdGhlaXIKLSAgICogb3duIC0gYW5kIGV2ZW4gYSBub24tZXJyb3Igc3RhdGUgZG9lc24ndCBndWFydW50ZWUgdGhhdAotICAgKiBldmVyeXRoaW5nIGluIHRoZSBlbnZpcm9ubWVudCBpcyBjb3JyZWN0LiAgQnV0IHRoaXMgd2lsbCBoZWxwCi0gICAqIHBvaW50IG91dCB0aGUgbW9zdCBjb21tb24gY2xhc3NwYXRoIGFuZCBzeXN0ZW0gcHJvcGVydHkKLSAgICogcHJvYmxlbXMgdGhhdCB3ZSd2ZSBzZWVuLjwvcD4KLSAgICoKLSAgICogQHJldHVybiBNYXAgZnVsbCBvZiB1c2VmdWwgZW52aXJvbm1lbnQgaW5mbyBhYm91dCBYYWxhbiBhbmQgcmVsYXRlZAotICAgKiBzeXN0ZW0gcHJvcGVydGllcywgZXRjLgotICAgKi8KLSAgcHVibGljIE1hcDxTdHJpbmcsIE9iamVjdD4gZ2V0RW52aXJvbm1lbnRIYXNoKCkKLSAgewotICAgIC8vIFNldHVwIGEgaGFzaCB0byBzdG9yZSB2YXJpb3VzIGVudmlyb25tZW50IGluZm9ybWF0aW9uIGluCi0gICAgTWFwPFN0cmluZywgT2JqZWN0PiBoYXNoID0gbmV3IEhhc2hNYXA8PigpOwotCi0gICAgLy8gQ2FsbCB2YXJpb3VzIHdvcmtlciBtZXRob2RzIHRvIGZpbGwgaW4gdGhlIGhhc2gKLSAgICAvLyAgVGhlc2UgYXJlIGV4cGxpY2l0bHkgc2VwYXJhdGUgZm9yIG1haW50ZW5hbmNlIGFuZCBzbwotICAgIC8vICBhZHZhbmNlZCB1c2VycyBjb3VsZCBjYWxsIHRoZW0gc3RhbmRhbG9uZQotICAgIGNoZWNrSkFYUFZlcnNpb24oaGFzaCk7Ci0gICAgY2hlY2tQcm9jZXNzb3JWZXJzaW9uKGhhc2gpOwotICAgIGNoZWNrUGFyc2VyVmVyc2lvbihoYXNoKTsKLSAgICBjaGVja0FudFZlcnNpb24oaGFzaCk7Ci0gICAgaWYgKCFjaGVja0RPTUwzKGhhc2gpKSB7Ci0gICAgY2hlY2tET01WZXJzaW9uKGhhc2gpOwotICAgIH0KLSAgICBjaGVja1NBWFZlcnNpb24oaGFzaCk7Ci0gICAgY2hlY2tTeXN0ZW1Qcm9wZXJ0aWVzKGhhc2gpOwotCi0gICAgcmV0dXJuIGhhc2g7Ci0gIH0KLQotICAvKioKLSAgICogRHVtcCBhIGJhc2ljIFhhbGFuIGVudmlyb25tZW50IHJlcG9ydCB0byBvdXRXcml0ZXIuCi0gICAqCi0gICAqIDxwPlRoaXMgZHVtcHMgYSBzaW1wbGUgaGVhZGVyIGFuZCB0aGVuIGVhY2ggb2YgdGhlIGVudHJpZXMgaW4KLSAgICogdGhlIE1hcCB0byBvdXIgUHJpbnRXcml0ZXI7IGl0IGRvZXMgc3BlY2lhbCBwcm9jZXNzaW5nCi0gICAqIGZvciBlbnRyaWVzIHRoYXQgYXJlIC5qYXJzIGZvdW5kIGluIHRoZSBjbGFzc3BhdGguPC9wPgotICAgKgotICAgKiBAcGFyYW0gaCBNYXAgb2YgaXRlbXMgdG8gcmVwb3J0IG9uOyBwcmVzdW1hYmx5Ci0gICAqIGZpbGxlZCBpbiBieSBvdXIgdmFyaW91cyBjaGVjayooKSBtZXRob2RzCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB5b3VyIGVudmlyb25tZW50IGFwcGVhcnMgdG8gaGF2ZSBubyBtYWpvcgotICAgKiBwcm9ibGVtczsgZmFsc2UgaWYgcG90ZW50aWFsIGVudmlyb25tZW50IHByb2JsZW1zIGZvdW5kCi0gICAqIEBzZWUgI2FwcGVuZEVudmlyb25tZW50UmVwb3J0KE5vZGUsIERvY3VtZW50LCBNYXApCi0gICAqIGZvciBhbiBlcXVpdmFsZW50IHRoYXQgYXBwZW5kcyB0byBhIE5vZGUgaW5zdGVhZAotICAgKi8KLSAgcHJvdGVjdGVkIGJvb2xlYW4gd3JpdGVFbnZpcm9ubWVudFJlcG9ydChNYXA8U3RyaW5nLCBPYmplY3Q+IGgpCi0gIHsKLQotICAgIGlmIChudWxsID09IGgpCi0gICAgewotICAgICAgbG9nTXNnKCIjIEVSUk9SOiB3cml0ZUVudmlyb25tZW50UmVwb3J0IGNhbGxlZCB3aXRoIG51bGwgTWFwIik7Ci0gICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgYm9vbGVhbiBlcnJvcnMgPSBmYWxzZTsKLQotICAgIGxvZ01zZygKLSAgICAgICIjLS0tLSBCRUdJTiB3cml0ZUVudmlyb25tZW50UmVwb3J0KCRSZXZpc2lvbjogMS4xMCAkKTogVXNlZnVsIHN0dWZmIGZvdW5kOiAtLS0tIik7Ci0KLSAgICAvLyBGYWtlIHRoZSBQcm9wZXJ0aWVzLWxpa2Ugb3V0cHV0Ci0gICAgZm9yIChNYXAuRW50cnk8U3RyaW5nLCBPYmplY3Q+IGVudHJ5IDogaC5lbnRyeVNldCgpKSB7Ci0gICAgICAgIFN0cmluZyBrZXlTdHIgPSBlbnRyeS5nZXRLZXkoKTsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIC8vIFNwZWNpYWwgcHJvY2Vzc2luZyBmb3IgY2xhc3NlcyBmb3VuZC4uCi0gICAgICAgICAgICBpZiAoa2V5U3RyLnN0YXJ0c1dpdGgoRk9VTkRDTEFTU0VTKSkgewotICAgICAgICAgICAgICAgIExpc3Q8TWFwPiB2ID0gKEFycmF5TGlzdDxNYXA+KWVudHJ5LmdldFZhbHVlKCk7Ci0gICAgICAgICAgICAgICAgZXJyb3JzIHw9IGxvZ0ZvdW5kSmFycyh2LCBrZXlTdHIpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gLi5ub3JtYWwgcHJvY2Vzc2luZyBmb3IgYWxsIG90aGVyIGVudHJpZXMKLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIC8vIE5vdGU6IHdlIGNvdWxkIGp1c3QgY2hlY2sgZm9yIHRoZSBFUlJPUiBrZXkgYnkgaXRzZWxmLAotICAgICAgICAgICAgICAgIC8vICAgIHNpbmNlIHdlIG5vdyBzZXQgdGhhdCwgYnV0IHNpbmNlIHdlIGhhdmUgdG8gZ28KLSAgICAgICAgICAgICAgICAvLyAgICB0aHJvdWdoIHRoZSB3aG9sZSBoYXNoIGFueXdheSwgZG8gaXQgdGhpcyB3YXksCi0gICAgICAgICAgICAgICAgLy8gICAgd2hpY2ggaXMgc2FmZXIgZm9yIG1haW50ZW5hbmNlCi0gICAgICAgICAgICAgICAgaWYgKGtleVN0ci5zdGFydHNXaXRoKEVSUk9SKSkgewotICAgICAgICAgICAgICAgICAgICBlcnJvcnMgPSB0cnVlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBsb2dNc2coa2V5U3RyICsgIj0iICsgaC5nZXQoa2V5U3RyKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICBsb2dNc2coIlJlYWRpbmctIiArIGtleVN0ciArICI9IHRocmV3OiAiICsgZS50b1N0cmluZygpKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIGxvZ01zZygKLSAgICAgICIjLS0tLS0gRU5EIHdyaXRlRW52aXJvbm1lbnRSZXBvcnQ6IFVzZWZ1bCBwcm9wZXJ0aWVzIGZvdW5kOiAtLS0tLSIpOwotCi0gICAgcmV0dXJuIGVycm9yczsKLSAgfQotCi0gIC8qKiBQcmVmaXhlZCB0byBoYXNoIGtleXMgdGhhdCBzaWduaWZ5IHNlcmlvdXMgcHJvYmxlbXMuICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJPUiA9ICJFUlJPUi4iOwotCi0gIC8qKiBBZGRlZCB0byBkZXNjcmlwdGlvbnMgdGhhdCBzaWduaWZ5IHBvdGVudGlhbCBwcm9ibGVtcy4gICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdBUk5JTkcgPSAiV0FSTklORy4iOwotCi0gIC8qKiBWYWx1ZSBmb3IgYW55IGVycm9yIGZvdW5kLiAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJST1JfRk9VTkQgPSAiQXQgbGVhc3Qgb25lIGVycm9yIHdhcyBmb3VuZCEiOwotCi0gIC8qKiBQcmVmaXhlZCB0byBoYXNoIGtleXMgdGhhdCBzaWduaWZ5IHZlcnNpb24gbnVtYmVycy4gICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFZFUlNJT04gPSAidmVyc2lvbi4iOwotCi0gIC8qKiBQcmVmaXhlZCB0byBoYXNoIGtleXMgdGhhdCBzaWduaWZ5IC5qYXJzIGZvdW5kIGluIGNsYXNzcGF0aC4gICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEZPVU5EQ0xBU1NFUyA9ICJmb3VuZGNsYXNzZXMuIjsKLQotICAvKiogTWFya2VyIHRoYXQgYSBjbGFzcyBvciAuamFyIHdhcyBmb3VuZC4gICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIENMQVNTX1BSRVNFTlQgPSAicHJlc2VudC11bmtub3duLXZlcnNpb24iOwotCi0gIC8qKiBNYXJrZXIgdGhhdCBhIGNsYXNzIG9yIC5qYXIgd2FzIG5vdCBmb3VuZC4gICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIENMQVNTX05PVFBSRVNFTlQgPSAibm90LXByZXNlbnQiOwotCi0gIC8qKiBMaXN0aW5nIG9mIGNvbW1vbiAuamFyIGZpbGVzIHRoYXQgaW5jbHVkZSBYYWxhbi1yZWxhdGVkIGNsYXNzZXMuICAqLwotICBwdWJsaWMgU3RyaW5nW10gamFyTmFtZXMgPQotICB7Ci0gICAgInhhbGFuLmphciIsICJ4YWxhbnNhbXBsZXMuamFyIiwgInhhbGFuajFjb21wYXQuamFyIiwgInhhbGFuc2VydmxldC5qYXIiLAotICAgICJzZXJpYWxpemVyLmphciIsICAgLy8gU2VyaWFsaXplciAoc2hhcmVkIGJldHdlZW4gWGFsYW4gJiBYZXJjZXMpCi0gICAgInhlcmNlcy5qYXIiLCAgICAgICAvLyBYZXJjZXMtSiAxLngKLSAgICAieGVyY2VzSW1wbC5qYXIiLCAgIC8vIFhlcmNlcy1KIDIueAotICAgICJ0ZXN0eHNsLmphciIsCi0gICAgImNyaW1zb24uamFyIiwKLSAgICAibG90dXN4c2wuamFyIiwKLSAgICAiamF4cC5qYXIiLCAicGFyc2VyLmphciIsICJkb20uamFyIiwgInNheC5qYXIiLCAieG1sLmphciIsCi0gICAgInhtbC1hcGlzLmphciIsCi0gICAgInhzbHRjLmphciIKLSAgfTsKLQotICAvKioKLSAgICogUHJpbnQgb3V0IHJlcG9ydCBvZiAuamFycyBmb3VuZCBpbiBhIGNsYXNzcGF0aC4KLSAgICoKLSAgICogVGFrZXMgdGhlIGluZm9ybWF0aW9uIGVuY29kZWQgZnJvbSBhIGNoZWNrUGF0aEZvckphcnMoKQotICAgKiBjYWxsIGFuZCBkdW1wcyBpdCBvdXQgdG8gb3VyIFByaW50V3JpdGVyLgotICAgKgotICAgKiBAcGFyYW0gdiBMaXN0IG9mIE1hcHMgb2YgLmphciBmaWxlIGluZm8KLSAgICogQHBhcmFtIGRlc2MgZGVzY3JpcHRpb24gdG8gcHJpbnQgb3V0IGluIGhlYWRlcgotICAgKgotICAgKiBAcmV0dXJuIGZhbHNlIGlmIE9LLCB0cnVlIGlmIGFueSAuamFycyB3ZXJlIHJlcG9ydGVkCi0gICAqIGFzIGhhdmluZyBlcnJvcnMKLSAgICogQHNlZSAjY2hlY2tQYXRoRm9ySmFycyhTdHJpbmcsIFN0cmluZ1tdKQotICAgKi8KLSAgcHJvdGVjdGVkIGJvb2xlYW4gbG9nRm91bmRKYXJzKExpc3Q8TWFwPiB2LCBTdHJpbmcgZGVzYykKLSAgewotCi0gICAgaWYgKChudWxsID09IHYpIHx8ICh2LnNpemUoKSA8IDEpKQotICAgICAgcmV0dXJuIGZhbHNlOwotCi0gICAgYm9vbGVhbiBlcnJvcnMgPSBmYWxzZTsKLQotICAgIGxvZ01zZygiIy0tLS0gQkVHSU4gTGlzdGluZyBYTUwtcmVsYXRlZCBqYXJzIGluOiAiICsgZGVzYyArICIgLS0tLSIpOwotCi0gICAgZm9yIChNYXA8U3RyaW5nLCBTdHJpbmc+IHYxIDogdikgewotICAgICAgICBmb3IgKE1hcC5FbnRyeTxTdHJpbmcsIFN0cmluZz4gZW50cnkgOiB2MS5lbnRyeVNldCgpKSB7Ci0gICAgICAgICAgICBTdHJpbmcga2V5U3RyID0gZW50cnkuZ2V0S2V5KCk7Ci0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIGlmIChrZXlTdHIuc3RhcnRzV2l0aChFUlJPUikpIHsKLSAgICAgICAgICAgICAgICAgICAgZXJyb3JzID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgbG9nTXNnKGtleVN0ciArICI9IiArIGVudHJ5LmdldFZhbHVlKCkpOwotCi0gICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgIGVycm9ycyA9IHRydWU7Ci0gICAgICAgICAgICAgICAgbG9nTXNnKCJSZWFkaW5nLSIgKyBrZXlTdHIgKyAiPSB0aHJldzogIiArIGUudG9TdHJpbmcoKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBsb2dNc2coIiMtLS0tLSBFTkQgTGlzdGluZyBYTUwtcmVsYXRlZCBqYXJzIGluOiAiICsgZGVzYyArICIgLS0tLS0iKTsKLQotICAgIHJldHVybiBlcnJvcnM7Ci0gIH0KLQotICAvKioKLSAgICogU3R5bGVzaGVldCBleHRlbnNpb24gZW50cnlwb2ludDogRHVtcCBhIGJhc2ljIFhhbGFuCi0gICAqIGVudmlyb25tZW50IHJlcG9ydCBmcm9tIGdldEVudmlyb25tZW50SGFzaCgpIHRvIGEgTm9kZS4KLSAgICoKLSAgICogPHA+Q29weSBvZiB3cml0ZUVudmlyb25tZW50UmVwb3J0IHRoYXQgY3JlYXRlcyBhIE5vZGUgc3VpdGFibGUKLSAgICogZm9yIG90aGVyIHByb2Nlc3NpbmcgaW5zdGVhZCBvZiBhIHByb3BlcnRpZXMtbGlrZSB0ZXh0IG91dHB1dC4KLSAgICogPC9wPgotICAgKiBAcGFyYW0gY29udGFpbmVyIE5vZGUgdG8gYXBwZW5kIG91ciByZXBvcnQgdG8KLSAgICogQHBhcmFtIGZhY3RvcnkgRG9jdW1lbnQgcHJvdmlkaW5nIGNyZWF0ZUVsZW1lbnQsIGV0Yy4gc2VydmljZXMKLSAgICogQHBhcmFtIGggSGFzaCBwcmVzdW1hYmx5IGZyb20ge0BsaW5rICNnZXRFbnZpcm9ubWVudEhhc2goKX0KLSAgICogQHNlZSAjd3JpdGVFbnZpcm9ubWVudFJlcG9ydChNYXApCi0gICAqIGZvciBhbiBlcXVpdmFsZW50IHRoYXQgd3JpdGVzIHRvIGEgUHJpbnRXcml0ZXIgaW5zdGVhZAotICAgKi8KLSAgcHVibGljIHZvaWQgYXBwZW5kRW52aXJvbm1lbnRSZXBvcnQoTm9kZSBjb250YWluZXIsIERvY3VtZW50IGZhY3RvcnksIE1hcDxTdHJpbmcsIE9iamVjdD4gaCkKLSAgewotICAgIGlmICgobnVsbCA9PSBjb250YWluZXIpIHx8IChudWxsID09IGZhY3RvcnkpKQotICAgIHsKLSAgICAgIHJldHVybjsKLSAgICB9Ci0KLSAgICB0cnkKLSAgICB7Ci0gICAgICBFbGVtZW50IGVudkNoZWNrTm9kZSA9IGZhY3RvcnkuY3JlYXRlRWxlbWVudCgiRW52aXJvbm1lbnRDaGVjayIpOwotICAgICAgZW52Q2hlY2tOb2RlLnNldEF0dHJpYnV0ZSgidmVyc2lvbiIsICIkUmV2aXNpb246IDEuMTAgJCIpOwotICAgICAgY29udGFpbmVyLmFwcGVuZENoaWxkKGVudkNoZWNrTm9kZSk7Ci0KLSAgICAgIGlmIChudWxsID09IGgpCi0gICAgICB7Ci0gICAgICAgIEVsZW1lbnQgc3RhdHVzTm9kZSA9IGZhY3RvcnkuY3JlYXRlRWxlbWVudCgic3RhdHVzIik7Ci0gICAgICAgIHN0YXR1c05vZGUuc2V0QXR0cmlidXRlKCJyZXN1bHQiLCAiRVJST1IiKTsKLSAgICAgICAgc3RhdHVzTm9kZS5hcHBlbmRDaGlsZChmYWN0b3J5LmNyZWF0ZVRleHROb2RlKCJhcHBlbmRFbnZpcm9ubWVudFJlcG9ydCBjYWxsZWQgd2l0aCBudWxsIE1hcCEiKSk7Ci0gICAgICAgIGVudkNoZWNrTm9kZS5hcHBlbmRDaGlsZChzdGF0dXNOb2RlKTsKLSAgICAgICAgcmV0dXJuOwotICAgICAgfQotCi0gICAgICBib29sZWFuIGVycm9ycyA9IGZhbHNlOwotCi0gICAgICBFbGVtZW50IGhhc2hOb2RlID0gZmFjdG9yeS5jcmVhdGVFbGVtZW50KCJlbnZpcm9ubWVudCIpOwotICAgICAgZW52Q2hlY2tOb2RlLmFwcGVuZENoaWxkKGhhc2hOb2RlKTsKLQotICAgICAgZm9yIChNYXAuRW50cnk8U3RyaW5nLCBPYmplY3Q+IGVudHJ5IDogaC5lbnRyeVNldCgpKSB7Ci0gICAgICAgICAgU3RyaW5nIGtleVN0ciA9IGVudHJ5LmdldEtleSgpOwotICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgIC8vIFNwZWNpYWwgcHJvY2Vzc2luZyBmb3IgY2xhc3NlcyBmb3VuZC4uCi0gICAgICAgICAgICAgIGlmIChrZXlTdHIuc3RhcnRzV2l0aChGT1VORENMQVNTRVMpKSB7Ci0gICAgICAgICAgICAgICAgICBMaXN0PE1hcD4gdiA9IChMaXN0PE1hcD4pZW50cnkuZ2V0VmFsdWUoKTsKLSAgICAgICAgICAgICAgICAgIC8vIGVycm9ycyB8PSBsb2dGb3VuZEphcnModiwga2V5U3RyKTsKLSAgICAgICAgICAgICAgICAgIGVycm9ycyB8PSBhcHBlbmRGb3VuZEphcnMoaGFzaE5vZGUsIGZhY3RvcnksIHYsIGtleVN0cik7Ci0gICAgICAgICAgICAgIH0gLy8gLi5ub3JtYWwgcHJvY2Vzc2luZyBmb3IgYWxsIG90aGVyIGVudHJpZXMKLSAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAvLyBOb3RlOiB3ZSBjb3VsZCBqdXN0IGNoZWNrIGZvciB0aGUgRVJST1Iga2V5IGJ5IGl0c2VsZiwKLSAgICAgICAgICAgICAgICAgIC8vICAgIHNpbmNlIHdlIG5vdyBzZXQgdGhhdCwgYnV0IHNpbmNlIHdlIGhhdmUgdG8gZ28KLSAgICAgICAgICAgICAgICAgIC8vICAgIHRocm91Z2ggdGhlIHdob2xlIGhhc2ggYW55d2F5LCBkbyBpdCB0aGlzIHdheSwKLSAgICAgICAgICAgICAgICAgIC8vICAgIHdoaWNoIGlzIHNhZmVyIGZvciBtYWludGVuYW5jZQotICAgICAgICAgICAgICAgICAgaWYgKGtleVN0ci5zdGFydHNXaXRoKEVSUk9SKSkgewotICAgICAgICAgICAgICAgICAgICAgIGVycm9ycyA9IHRydWU7Ci0gICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICBFbGVtZW50IG5vZGUgPSBmYWN0b3J5LmNyZWF0ZUVsZW1lbnQoIml0ZW0iKTsKLSAgICAgICAgICAgICAgICAgIG5vZGUuc2V0QXR0cmlidXRlKCJrZXkiLCBrZXlTdHIpOwotICAgICAgICAgICAgICAgICAgbm9kZS5hcHBlbmRDaGlsZChmYWN0b3J5LmNyZWF0ZVRleHROb2RlKChTdHJpbmcpIGguZ2V0KGtleVN0cikpKTsKLSAgICAgICAgICAgICAgICAgIGhhc2hOb2RlLmFwcGVuZENoaWxkKG5vZGUpOwotICAgICAgICAgICAgICB9Ci0gICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgZXJyb3JzID0gdHJ1ZTsKLSAgICAgICAgICAgICAgRWxlbWVudCBub2RlID0gZmFjdG9yeS5jcmVhdGVFbGVtZW50KCJpdGVtIik7Ci0gICAgICAgICAgICAgIG5vZGUuc2V0QXR0cmlidXRlKCJrZXkiLCBrZXlTdHIpOwotICAgICAgICAgICAgICBub2RlLmFwcGVuZENoaWxkKGZhY3RvcnkuY3JlYXRlVGV4dE5vZGUoRVJST1IgKyAiIFJlYWRpbmcgIiArIGtleVN0ciArICIgdGhyZXc6ICIgKyBlLnRvU3RyaW5nKCkpKTsKLSAgICAgICAgICAgICAgaGFzaE5vZGUuYXBwZW5kQ2hpbGQobm9kZSk7Ci0gICAgICAgICAgfQotICAgICAgfSAvLyBlbmQgb2YgZm9yLi4uCi0KLSAgICAgIEVsZW1lbnQgc3RhdHVzTm9kZSA9IGZhY3RvcnkuY3JlYXRlRWxlbWVudCgic3RhdHVzIik7Ci0gICAgICBzdGF0dXNOb2RlLnNldEF0dHJpYnV0ZSgicmVzdWx0IiwgKGVycm9ycyA/ICJFUlJPUiIgOiAiT0siICkpOwotICAgICAgZW52Q2hlY2tOb2RlLmFwcGVuZENoaWxkKHN0YXR1c05vZGUpOwotICAgIH0KLSAgICBjYXRjaCAoRXhjZXB0aW9uIGUyKQotICAgIHsKLSAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiYXBwZW5kRW52aXJvbm1lbnRSZXBvcnQgdGhyZXc6ICIgKyBlMi50b1N0cmluZygpKTsKLSAgICAgIGUyLnByaW50U3RhY2tUcmFjZSgpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBQcmludCBvdXQgcmVwb3J0IG9mIC5qYXJzIGZvdW5kIGluIGEgY2xhc3NwYXRoLgotICAgKgotICAgKiBUYWtlcyB0aGUgaW5mb3JtYXRpb24gZW5jb2RlZCBmcm9tIGEgY2hlY2tQYXRoRm9ySmFycygpCi0gICAqIGNhbGwgYW5kIGR1bXBzIGl0IG91dCB0byBvdXIgUHJpbnRXcml0ZXIuCi0gICAqCi0gICAqIEBwYXJhbSBjb250YWluZXIgTm9kZSB0byBhcHBlbmQgb3VyIHJlcG9ydCB0bwotICAgKiBAcGFyYW0gZmFjdG9yeSBEb2N1bWVudCBwcm92aWRpbmcgY3JlYXRlRWxlbWVudCwgZXRjLiBzZXJ2aWNlcwotICAgKiBAcGFyYW0gdiBNYXAgb2YgTWFwcyBvZiAuamFyIGZpbGUgaW5mbwotICAgKiBAcGFyYW0gZGVzYyBkZXNjcmlwdGlvbiB0byBwcmludCBvdXQgaW4gaGVhZGVyCi0gICAqCi0gICAqIEByZXR1cm4gZmFsc2UgaWYgT0ssIHRydWUgaWYgYW55IC5qYXJzIHdlcmUgcmVwb3J0ZWQKLSAgICogYXMgaGF2aW5nIGVycm9ycwotICAgKiBAc2VlICNjaGVja1BhdGhGb3JKYXJzKFN0cmluZywgU3RyaW5nW10pCi0gICAqLwotICBwcm90ZWN0ZWQgYm9vbGVhbiBhcHBlbmRGb3VuZEphcnMoTm9kZSBjb250YWluZXIsIERvY3VtZW50IGZhY3RvcnksCi0gICAgICAgIExpc3Q8TWFwPiB2LCBTdHJpbmcgZGVzYykKLSAgewotCi0gICAgaWYgKChudWxsID09IHYpIHx8ICh2LnNpemUoKSA8IDEpKQotICAgICAgcmV0dXJuIGZhbHNlOwotCi0gICAgYm9vbGVhbiBlcnJvcnMgPSBmYWxzZTsKLQotICAgIGZvciAoTWFwPFN0cmluZywgU3RyaW5nPiB2MSA6IHYpIHsKLSAgICAgICAgZm9yIChNYXAuRW50cnk8U3RyaW5nLCBTdHJpbmc+IGVudHJ5IDogdjEuZW50cnlTZXQoKSkgewotICAgICAgICAgICAgU3RyaW5nIGtleVN0ciA9IGVudHJ5LmdldEtleSgpOwotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICBpZiAoa2V5U3RyLnN0YXJ0c1dpdGgoRVJST1IpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGVycm9ycyA9IHRydWU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIEVsZW1lbnQgbm9kZSA9IGZhY3RvcnkuY3JlYXRlRWxlbWVudCgiZm91bmRKYXIiKTsKLSAgICAgICAgICAgICAgICBub2RlLnNldEF0dHJpYnV0ZSgibmFtZSIsIGtleVN0ci5zdWJzdHJpbmcoMCwga2V5U3RyLmluZGV4T2YoIi0iKSkpOwotICAgICAgICAgICAgICAgIG5vZGUuc2V0QXR0cmlidXRlKCJkZXNjIiwga2V5U3RyLnN1YnN0cmluZyhrZXlTdHIuaW5kZXhPZigiLSIpICsgMSkpOwotICAgICAgICAgICAgICAgIG5vZGUuYXBwZW5kQ2hpbGQoZmFjdG9yeS5jcmVhdGVUZXh0Tm9kZShlbnRyeS5nZXRWYWx1ZSgpKSk7Ci0gICAgICAgICAgICAgICAgY29udGFpbmVyLmFwcGVuZENoaWxkKG5vZGUpOwotICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICBlcnJvcnMgPSB0cnVlOwotICAgICAgICAgICAgICAgIEVsZW1lbnQgbm9kZSA9IGZhY3RvcnkuY3JlYXRlRWxlbWVudCgiZm91bmRKYXIiKTsKLSAgICAgICAgICAgICAgICBub2RlLmFwcGVuZENoaWxkKGZhY3RvcnkuY3JlYXRlVGV4dE5vZGUoRVJST1IgKyAiIFJlYWRpbmcgIiArIGtleVN0ciArICIgdGhyZXc6ICIgKyBlLnRvU3RyaW5nKCkpKTsKLSAgICAgICAgICAgICAgICBjb250YWluZXIuYXBwZW5kQ2hpbGQobm9kZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0gICAgcmV0dXJuIGVycm9yczsKLSAgfQotCi0gIC8qKgotICAgKiBGaWxsaW4gaGFzaCB3aXRoIGluZm8gYWJvdXQgU3lzdGVtUHJvcGVydGllcy4KLSAgICoKLSAgICogTG9ncyBqYXZhLmNsYXNzLnBhdGggYW5kIG90aGVyIGxpa2VseSBwYXRoczsgdGhlbiBhdHRlbXB0cwotICAgKiB0byBzZWFyY2ggdGhvc2UgcGF0aHMgZm9yIC5qYXIgZmlsZXMgd2l0aCBYYWxhbi1yZWxhdGVkIGNsYXNzZXMuCi0gICAqCi0gICAqIC8vQHRvZG8gTk9URTogV2UgZG9uJ3QgYWN0dWFsbHkgc2VhcmNoIGphdmEuZXh0LmRpcnMgZm9yCi0gICAqIC8vICAqLmphciBmaWxlcyB0aGVyZWluISBUaGlzIHNob3VsZCBiZSB1cGRhdGVkCi0gICAqCi0gICAqIEBwYXJhbSBoIE1hcCB0byBwdXQgaW5mb3JtYXRpb24gaW4KLSAgICogQHNlZSAjamFyTmFtZXMKLSAgICogQHNlZSAjY2hlY2tQYXRoRm9ySmFycyhTdHJpbmcsIFN0cmluZ1tdKQotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgY2hlY2tTeXN0ZW1Qcm9wZXJ0aWVzKE1hcDxTdHJpbmcsIE9iamVjdD4gaCkKLSAgewotCi0gICAgaWYgKG51bGwgPT0gaCkKLSAgICAgIGggPSBuZXcgSGFzaE1hcDw+KCk7Ci0KLSAgICAvLyBHcmFiIGphdmEgdmVyc2lvbiBmb3IgbGF0ZXIgdXNlCi0gICAgdHJ5Ci0gICAgewotICAgICAgU3RyaW5nIGphdmFWZXJzaW9uID0gU2VjdXJpdHlTdXBwb3J0LmdldFN5c3RlbVByb3BlcnR5KCJqYXZhLnZlcnNpb24iKTsKLQotICAgICAgaC5wdXQoImphdmEudmVyc2lvbiIsIGphdmFWZXJzaW9uKTsKLSAgICB9Ci0gICAgY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIHNlKQotICAgIHsKLQotICAgICAgLy8gRm9yIGFwcGxldCBjb250ZXh0LCBldGMuCi0gICAgICBoLnB1dCgKLSAgICAgICAgImphdmEudmVyc2lvbiIsCi0gICAgICAgICJXQVJOSU5HOiBTZWN1cml0eUV4Y2VwdGlvbiB0aHJvd24gYWNjZXNzaW5nIHN5c3RlbSB2ZXJzaW9uIHByb3BlcnRpZXMiKTsKLSAgICB9Ci0KLSAgICAvLyBQcmludG91dCBqYXIgZmlsZXMgb24gY2xhc3NwYXRoKHMpIHRoYXQgbWF5IGFmZmVjdCBvcGVyYXRpb24KLSAgICAvLyAgRG8gdGhpcyBpbiBvcmRlcgotICAgIHRyeQotICAgIHsKLQotICAgICAgLy8gVGhpcyBpcyBwcmVzZW50IGluIGFsbCBKVk0ncwotICAgICAgU3RyaW5nIGNwID0gU2VjdXJpdHlTdXBwb3J0LmdldFN5c3RlbVByb3BlcnR5KCJqYXZhLmNsYXNzLnBhdGgiKTsKLQotICAgICAgaC5wdXQoImphdmEuY2xhc3MucGF0aCIsIGNwKTsKLQotICAgICAgTGlzdDxNYXA+IGNsYXNzcGF0aEphcnMgPSBjaGVja1BhdGhGb3JKYXJzKGNwLCBqYXJOYW1lcyk7Ci0KLSAgICAgIGlmIChudWxsICE9IGNsYXNzcGF0aEphcnMpIHsKLSAgICAgICAgICBoLnB1dChGT1VORENMQVNTRVMgKyAiamF2YS5jbGFzcy5wYXRoIiwgY2xhc3NwYXRoSmFycyk7Ci0gICAgICB9Ci0KLSAgICAgIC8vIEFsc28gY2hlY2sgZm9yIEpESyAxLjIrIHR5cGUgY2xhc3NwYXRocwotICAgICAgU3RyaW5nIG90aGVyY3AgPSBTZWN1cml0eVN1cHBvcnQuZ2V0U3lzdGVtUHJvcGVydHkoInN1bi5ib290LmNsYXNzLnBhdGgiKTsKLQotICAgICAgaWYgKG51bGwgIT0gb3RoZXJjcCkgewotICAgICAgICAgIGgucHV0KCJzdW4uYm9vdC5jbGFzcy5wYXRoIiwgb3RoZXJjcCk7Ci0gICAgICAgICAgY2xhc3NwYXRoSmFycyA9IGNoZWNrUGF0aEZvckphcnMob3RoZXJjcCwgamFyTmFtZXMpOwotCi0gICAgICAgICAgaWYgKG51bGwgIT0gY2xhc3NwYXRoSmFycykgewotICAgICAgICAgICAgICBoLnB1dChGT1VORENMQVNTRVMgKyAic3VuLmJvb3QuY2xhc3MucGF0aCIsIGNsYXNzcGF0aEphcnMpOwotICAgICAgICAgIH0KLSAgICAgIH0KLQotICAgICAgLy9AdG9kbyBOT1RFOiBXZSBkb24ndCBhY3R1YWxseSBzZWFyY2ggamF2YS5leHQuZGlycyBmb3IKLSAgICAgIC8vICAqLmphciBmaWxlcyB0aGVyZWluISBUaGlzIHNob3VsZCBiZSB1cGRhdGVkCi0gICAgICBvdGhlcmNwID0gU2VjdXJpdHlTdXBwb3J0LmdldFN5c3RlbVByb3BlcnR5KCJqYXZhLmV4dC5kaXJzIik7Ci0KLSAgICAgIGlmIChudWxsICE9IG90aGVyY3ApCi0gICAgICB7Ci0gICAgICAgIGgucHV0KCJqYXZhLmV4dC5kaXJzIiwgb3RoZXJjcCk7Ci0KLSAgICAgICAgY2xhc3NwYXRoSmFycyA9IGNoZWNrUGF0aEZvckphcnMob3RoZXJjcCwgamFyTmFtZXMpOwotCi0gICAgICAgIGlmIChudWxsICE9IGNsYXNzcGF0aEphcnMpCi0gICAgICAgICAgaC5wdXQoRk9VTkRDTEFTU0VTICsgImphdmEuZXh0LmRpcnMiLCBjbGFzc3BhdGhKYXJzKTsKLSAgICAgIH0KLQotICAgICAgLy9AdG9kbyBhbHNvIGNoZWNrIG90aGVyIFN5c3RlbSBwcm9wZXJ0aWVzJyBwYXRocz8KLSAgICAgIC8vICB2MiA9IGNoZWNrUGF0aEZvckphcnMoU3lzdGVtLmdldFByb3BlcnR5KCJzdW4uYm9vdC5saWJyYXJ5LnBhdGgiKSwgamFyTmFtZXMpOyAgIC8vID8/IG1heSBub3QgYmUgbmVlZGVkCi0gICAgICAvLyAgdjMgPSBjaGVja1BhdGhGb3JKYXJzKFN5c3RlbS5nZXRQcm9wZXJ0eSgiamF2YS5saWJyYXJ5LnBhdGgiKSwgamFyTmFtZXMpOyAgIC8vID8/IG1heSBub3QgYmUgbmVlZGVkCi0gICAgfQotICAgIGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBzZTIpCi0gICAgewotICAgICAgLy8gRm9yIGFwcGxldCBjb250ZXh0LCBldGMuCi0gICAgICBoLnB1dCgKLSAgICAgICAgImphdmEuY2xhc3MucGF0aCIsCi0gICAgICAgICJXQVJOSU5HOiBTZWN1cml0eUV4Y2VwdGlvbiB0aHJvd24gYWNjZXNzaW5nIHN5c3RlbSBjbGFzc3BhdGggcHJvcGVydGllcyIpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBDaGVhcC1vIGxpc3Rpbmcgb2Ygc3BlY2lmaWVkIC5qYXJzIGZvdW5kIGluIHRoZSBjbGFzc3BhdGguCi0gICAqCi0gICAqIGNwIHNob3VsZCBiZSBzZXBhcmF0ZWQgYnkgdGhlIHVzdWFsIEZpbGUucGF0aFNlcGFyYXRvci4gIFdlCi0gICAqIHRoZW4gZG8gYSBzaW1wbGlzdGljIHNlYXJjaCBvZiB0aGUgcGF0aCBmb3IgYW55IHJlcXVlc3RlZAotICAgKiAuamFyIGZpbGVuYW1lcywgYW5kIHJldHVybiBhIGxpc3Rpbmcgb2YgdGhlaXIgbmFtZXMgYW5kCi0gICAqIHdoZXJlIChhcHBhcmVudGx5KSB0aGV5IGNhbWUgZnJvbS4KLSAgICoKLSAgICogQHBhcmFtIGNwIGNsYXNzcGF0aCB0byBzZWFyY2gKLSAgICogQHBhcmFtIGphcnMgYXJyYXkgb2YgLmphciBiYXNlIGZpbGVuYW1lcyB0byBsb29rIGZvcgotICAgKgotICAgKiBAcmV0dXJuIExpc3Qgb2YgTWFwcyBmaWxsZWQgd2l0aCBpbmZvIGFib3V0IGZvdW5kIC5qYXJzCi0gICAqIEBzZWUgI2phck5hbWVzCi0gICAqIEBzZWUgI2xvZ0ZvdW5kSmFycyhNYXAsIFN0cmluZykKLSAgICogQHNlZSAjYXBwZW5kRm91bmRKYXJzKE5vZGUsIERvY3VtZW50LCBNYXAsIFN0cmluZyApCi0gICAqIEBzZWUgI2dldEFwcGFyZW50VmVyc2lvbihTdHJpbmcsIGxvbmcpCi0gICAqLwotICBwcm90ZWN0ZWQgTGlzdDxNYXA+IGNoZWNrUGF0aEZvckphcnMoU3RyaW5nIGNwLCBTdHJpbmdbXSBqYXJzKQotICB7Ci0KLSAgICBpZiAoKG51bGwgPT0gY3ApIHx8IChudWxsID09IGphcnMpIHx8ICgwID09IGNwLmxlbmd0aCgpKQotICAgICAgICAgICAgfHwgKDAgPT0gamFycy5sZW5ndGgpKQotICAgICAgcmV0dXJuIG51bGw7Ci0KLSAgICBMaXN0PE1hcD4gdiA9IG5ldyBBcnJheUxpc3Q8PigpOwotICAgIFN0cmluZ1Rva2VuaXplciBzdCA9IG5ldyBTdHJpbmdUb2tlbml6ZXIoY3AsIEZpbGUucGF0aFNlcGFyYXRvcik7Ci0KLSAgICB3aGlsZSAoc3QuaGFzTW9yZVRva2VucygpKQotICAgIHsKLQotICAgICAgLy8gTG9vayBhdCBlYWNoIGNsYXNzcGF0aCBlbnRyeSBmb3IgZWFjaCBvZiBvdXIgcmVxdWVzdGVkIGphck5hbWVzCi0gICAgICBTdHJpbmcgZmlsZW5hbWUgPSBzdC5uZXh0VG9rZW4oKTsKLQotICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBqYXJzLmxlbmd0aDsgaSsrKQotICAgICAgewotICAgICAgICBpZiAoZmlsZW5hbWUuaW5kZXhPZihqYXJzW2ldKSA+IC0xKQotICAgICAgICB7Ci0gICAgICAgICAgRmlsZSBmID0gbmV3IEZpbGUoZmlsZW5hbWUpOwotCi0gICAgICAgICAgaWYgKGYuZXhpc3RzKCkpCi0gICAgICAgICAgewotCi0gICAgICAgICAgICAvLyBJZiBhbnkgcmVxdWVzdGVkIGphck5hbWUgZXhpc3RzLCByZXBvcnQgb24KLSAgICAgICAgICAgIC8vICB0aGUgZGV0YWlscyBvZiB0aGF0IC5qYXIgZmlsZQotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICBNYXA8U3RyaW5nLCBTdHJpbmc+IGggPSBuZXcgSGFzaE1hcDw+KDIpOwotICAgICAgICAgICAgICAgIC8vIE5vdGUgIi0iIGNoYXIgaXMgbG9va2VkIGZvciBpbiBhcHBlbmRGb3VuZEphcnMKLSAgICAgICAgICAgICAgICBoLnB1dChqYXJzW2ldICsgIi1wYXRoIiwgZi5nZXRBYnNvbHV0ZVBhdGgoKSk7Ci0KLSAgICAgICAgICAgICAgICAvLyBXZSB3b24ndCBib3RoZXIgcmVwb3J0aW5nIG9uIHRoZSB4YWxhbi5qYXIgYXBwYXJlbnQgdmVyc2lvbgotICAgICAgICAgICAgICAgIC8vIHNpbmNlIHRoaXMgcmVxdWlyZXMga25vd2luZyB0aGUgamFyIHNpemUgb2YgdGhlIHhhbGFuLmphcgotICAgICAgICAgICAgICAgIC8vIGJlZm9yZSB3ZSBidWlsZCBpdC4KLSAgICAgICAgICAgICAgICAvLyBGb3Igb3RoZXIgamFycywgZWcuIHhtbC1hcGlzLmphciBhbmQgeGVyY2VzSW1wbC5qYXIsIHdlCi0gICAgICAgICAgICAgICAgLy8gcmVwb3J0IHRoZSBhcHBhcmVudCB2ZXJzaW9uIG9mIHRoZSBmaWxlIHdlJ3ZlIGZvdW5kCi0gICAgICAgICAgICAgICAgaWYgKCEoInhhbGFuLmphciIuZXF1YWxzSWdub3JlQ2FzZShqYXJzW2ldKSkpIHsKLSAgICAgICAgICAgICAgICAgICAgaC5wdXQoamFyc1tpXSArICItYXBwYXJlbnQudmVyc2lvbiIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0QXBwYXJlbnRWZXJzaW9uKGphcnNbaV0sIGYubGVuZ3RoKCkpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgdi5hZGQoaCk7Ci0gICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgewotCi0gICAgICAgICAgICAgICAgLyogbm8tb3AsIGRvbid0IGFkZCBpdCAgKi8KLSAgICAgICAgICAgIH0KLSAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgTWFwPFN0cmluZywgU3RyaW5nPiBoID0gbmV3IEhhc2hNYXA8PigyKTsKLSAgICAgICAgICAgIC8vIE5vdGUgIi0iIGNoYXIgaXMgbG9va2VkIGZvciBpbiBhcHBlbmRGb3VuZEphcnMKLSAgICAgICAgICAgIGgucHV0KGphcnNbaV0gKyAiLXBhdGgiLCBXQVJOSU5HICsgIiBDbGFzc3BhdGggZW50cnk6ICIKLSAgICAgICAgICAgICAgICAgICAgKyBmaWxlbmFtZSArICIgZG9lcyBub3QgZXhpc3QiKTsKLSAgICAgICAgICAgIGgucHV0KGphcnNbaV0gKyAiLWFwcGFyZW50LnZlcnNpb24iLCBDTEFTU19OT1RQUkVTRU5UKTsKLSAgICAgICAgICAgIHYuYWRkKGgpOwotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiB2OwotICB9Ci0KLSAgLyoqCi0gICAqIENoZWFwLW8gbWV0aG9kIHRvIGRldGVybWluZSB0aGUgcHJvZHVjdCB2ZXJzaW9uIG9mIGEgLmphci4KLSAgICoKLSAgICogQ3VycmVudGx5IGRvZXMgYSBsb29rdXAgaW50byBhIGxvY2FsIHRhYmxlIG9mIHNvbWUgcmVjZW50Ci0gICAqIHNoaXBwZWQgWGFsYW4gYnVpbGRzIHRvIGRldGVybWluZSB3aGVyZSB0aGUgLmphciBwcm9iYWJseQotICAgKiBjYW1lIGZyb20uICBOb3RlIHRoYXQgaWYgeW91IHJlY29tcGlsZSBYYWxhbiBvciBYZXJjZXMKLSAgICogeW91cnNlbGYgdGhpcyB3aWxsIGxpa2VseSByZXBvcnQgYSBwb3RlbnRpYWwgZXJyb3IsIHNpbmNlCi0gICAqIHdlIGNhbid0IGNlcnRpZnkgYnVpbGRzIG90aGVyIHRoYW4gdGhlIG9uZXMgd2Ugc2hpcC4KLSAgICogT25seSByZXBvcnRzIGFnYWluc3Qgc2VsZWN0ZWQgcG9zdGVkIFhhbGFuLUogYnVpbGRzLgotICAgKgotICAgKiAvL0B0b2RvIGFjdHVhbGx5IGxvb2sgdXAgdmVyc2lvbiBpbmZvIGluIG1hbmlmZXN0cwotICAgKgotICAgKiBAcGFyYW0gamFyTmFtZSBiYXNlIGZpbGVuYW1lIG9mIHRoZSAuamFyZmlsZQotICAgKiBAcGFyYW0gamFyU2l6ZSBzaXplIG9mIHRoZSAuamFyZmlsZQotICAgKgotICAgKiBAcmV0dXJuIFN0cmluZyBkZXNjcmliaW5nIHdoZXJlIHRoZSAuamFyIGZpbGUgcHJvYmFibHkKLSAgICogY2FtZSBmcm9tCi0gICAqLwotICBwcm90ZWN0ZWQgU3RyaW5nIGdldEFwcGFyZW50VmVyc2lvbihTdHJpbmcgamFyTmFtZSwgbG9uZyBqYXJTaXplKQotICB7Ci0gICAgLy8gSWYgd2UgZm91bmQgYSBtYXRjaGluZyBzaXplIGFuZCBpdCdzIGZvciBvdXIKLSAgICAvLyAgamFyLCB0aGVuIHJldHVybiBpdCdzIGRlc2NyaXB0aW9uCi0gICAgLy8gTG9va3VwIGluIHN0YXRpYyBKQVJWRVJTSU9OUyBNYXAKLSAgICBTdHJpbmcgZm91bmRTaXplID0gSkFSVkVSU0lPTlMuZ2V0KG5ldyBMb25nKGphclNpemUpKTsKLQotICAgIGlmICgobnVsbCAhPSBmb3VuZFNpemUpICYmIChmb3VuZFNpemUuc3RhcnRzV2l0aChqYXJOYW1lKSkpCi0gICAgewotICAgICAgcmV0dXJuIGZvdW5kU2l6ZTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIGlmICgieGVyY2VzLmphciIuZXF1YWxzSWdub3JlQ2FzZShqYXJOYW1lKQotICAgICAgICAgICAgICB8fCAieGVyY2VzSW1wbC5qYXIiLmVxdWFsc0lnbm9yZUNhc2UoamFyTmFtZSkpCi0vLyAgICAgICAgICAgICAgfHwgInhhbGFuLmphciIuZXF1YWxzSWdub3JlQ2FzZShqYXJOYW1lKSkKLSAgICAgIHsKLQotICAgICAgICAvLyBGb3IgeGFsYW4uamFyIGFuZCB4ZXJjZXMuamFyL3hlcmNlc0ltcGwuamFyLCB3aGljaCB3ZSBzaGlwIHRvZ2V0aGVyOgotICAgICAgICAvLyBUaGUgamFyIGlzIG5vdCBmcm9tIGEgc2hpcHBlZCBjb3B5IG9mIHhhbGFuLWosIHNvCi0gICAgICAgIC8vICBpdCdzIHVwIHRvIHRoZSB1c2VyIHRvIGVuc3VyZSB0aGF0IGl0J3MgY29tcGF0aWJsZQotICAgICAgICByZXR1cm4gamFyTmFtZSArICIgIiArIFdBUk5JTkcgKyBDTEFTU19QUkVTRU5UOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotCi0gICAgICAgIC8vIE90aGVyd2lzZSwgaXQncyBqdXN0IGEgamFyIHdlIGRvbid0IGhhdmUgdGhlIHZlcnNpb24gaW5mbyBjYWxjdWxhdGVkIGZvcgotICAgICAgICByZXR1cm4gamFyTmFtZSArICIgIiArIENMQVNTX1BSRVNFTlQ7Ci0gICAgICB9Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFJlcG9ydCB2ZXJzaW9uIGluZm9ybWF0aW9uIGFib3V0IEpBWFAgaW50ZXJmYWNlcy4KLSAgICoKLSAgICogQ3VycmVudGx5IGRpc3Rpbmd1aXNoZXMgYmV0d2VlbiBKQVhQIDEuMC4xIGFuZCBKQVhQIDEuMSwKLSAgICogYW5kIG5vdCBmb3VuZDsgb25seSB0ZXN0cyB0aGUgaW50ZXJmYWNlcywgYW5kIGRvZXMgbm90Ci0gICAqIGNoZWNrIGZvciByZWZlcmVuY2UgaW1wbGVtZW50YXRpb24gdmVyc2lvbnMuCi0gICAqCi0gICAqIEBwYXJhbSBoIE1hcCB0byBwdXQgaW5mb3JtYXRpb24gaW4KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIGNoZWNrSkFYUFZlcnNpb24oTWFwPFN0cmluZywgT2JqZWN0PiBoKQotICB7Ci0KLSAgICBpZiAobnVsbCA9PSBoKQotICAgICAgaCA9IG5ldyBIYXNoTWFwPD4oKTsKLQotICAgIENsYXNzIGNsYXp6ID0gbnVsbDsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIGZpbmFsIFN0cmluZyBKQVhQMV9DTEFTUyA9ICJqYXZheC54bWwuc3RyZWFtLlhNTFN0cmVhbUNvbnN0YW50cyI7Ci0KLSAgICAgIGNsYXp6ID0gT2JqZWN0RmFjdG9yeS5maW5kUHJvdmlkZXJDbGFzcyhKQVhQMV9DTEFTUywgdHJ1ZSk7Ci0KLSAgICAgIC8vIElmIHdlIHN1Y2NlZWRlZCwgd2UgaGF2ZSBKQVhQIDEuNCBhdmFpbGFibGUKLSAgICAgIGgucHV0KFZFUlNJT04gKyAiSkFYUCIsICIxLjQiKTsKLSAgICB9Ci0gICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKQotICAgIHsKLSAgICAgICAgaC5wdXQoRVJST1IgKyBWRVJTSU9OICsgIkpBWFAiLCAiMS4zIik7Ci0gICAgICAgIGgucHV0KEVSUk9SLCBFUlJPUl9GT1VORCk7Ci0gICAgICB9Ci0gICAgICB9Ci0KLSAgLyoqCi0gICAqIFJlcG9ydCBwcm9kdWN0IHZlcnNpb24gaW5mb3JtYXRpb24gZnJvbSBYYWxhbi1KLgotICAgKgotICAgKiBMb29rcyBmb3IgdmVyc2lvbiBpbmZvIGluIHhhbGFuLmphciBmcm9tIFhhbGFuLUogcHJvZHVjdHMuCi0gICAqCi0gICAqIEBwYXJhbSBoIE1hcCB0byBwdXQgaW5mb3JtYXRpb24gaW4KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIGNoZWNrUHJvY2Vzc29yVmVyc2lvbihNYXA8U3RyaW5nLCBPYmplY3Q+IGgpCi0gIHsKLQotICAgIGlmIChudWxsID09IGgpCi0gICAgICBoID0gbmV3IEhhc2hNYXA8PigpOwotCi0gICAgdHJ5Ci0gICAgewotICAgICAgZmluYWwgU3RyaW5nIFhBTEFOMV9WRVJTSU9OX0NMQVNTID0KLSAgICAgICAgImNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0LlhTTFByb2Nlc3NvclZlcnNpb24iOwotCi0gICAgICBDbGFzcyBjbGF6eiA9IE9iamVjdEZhY3RvcnkuZmluZFByb3ZpZGVyQ2xhc3MoWEFMQU4xX1ZFUlNJT05fQ0xBU1MsIHRydWUpOwotCi0gICAgICAvLyBGb3VuZCBYYWxhbi1KIDEueCwgZ3JhYiBpdCdzIHZlcnNpb24gZmllbGRzCi0gICAgICBTdHJpbmdCdWZmZXIgYnVmID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotICAgICAgRmllbGQgZiA9IGNsYXp6LmdldEZpZWxkKCJQUk9EVUNUIik7Ci0KLSAgICAgIGJ1Zi5hcHBlbmQoZi5nZXQobnVsbCkpOwotICAgICAgYnVmLmFwcGVuZCgnOycpOwotCi0gICAgICBmID0gY2xhenouZ2V0RmllbGQoIkxBTkdVQUdFIik7Ci0KLSAgICAgIGJ1Zi5hcHBlbmQoZi5nZXQobnVsbCkpOwotICAgICAgYnVmLmFwcGVuZCgnOycpOwotCi0gICAgICBmID0gY2xhenouZ2V0RmllbGQoIlNfVkVSU0lPTiIpOwotCi0gICAgICBidWYuYXBwZW5kKGYuZ2V0KG51bGwpKTsKLSAgICAgIGJ1Zi5hcHBlbmQoJzsnKTsKLSAgICAgIGgucHV0KFZFUlNJT04gKyAieGFsYW4xIiwgYnVmLnRvU3RyaW5nKCkpOwotICAgIH0KLSAgICBjYXRjaCAoRXhjZXB0aW9uIGUxKQotICAgIHsKLSAgICAgIGgucHV0KFZFUlNJT04gKyAieGFsYW4xIiwgQ0xBU1NfTk9UUFJFU0VOVCk7Ci0gICAgfQotCi0gICAgdHJ5Ci0gICAgewotICAgICAgLy8gTk9URTogVGhpcyBpcyB0aGUgb2xkIFhhbGFuIDIuMCwgMi4xLCAyLjIgdmVyc2lvbiBjbGFzcywKLSAgICAgIC8vICAgIGlzIGJlaW5nIHJlcGxhY2VkIGJ5IGNsYXNzIGJlbG93Ci0gICAgICBmaW5hbCBTdHJpbmcgWEFMQU4yX1ZFUlNJT05fQ0xBU1MgPQotICAgICAgICAiY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnByb2Nlc3Nvci5YU0xQcm9jZXNzb3JWZXJzaW9uIjsKLQotICAgICAgQ2xhc3MgY2xhenogPSBPYmplY3RGYWN0b3J5LmZpbmRQcm92aWRlckNsYXNzKFhBTEFOMl9WRVJTSU9OX0NMQVNTLCB0cnVlKTsKLQotICAgICAgLy8gRm91bmQgWGFsYW4tSiAyLngsIGdyYWIgaXQncyB2ZXJzaW9uIGZpZWxkcwotICAgICAgU3RyaW5nQnVmZmVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLSAgICAgIEZpZWxkIGYgPSBjbGF6ei5nZXRGaWVsZCgiU19WRVJTSU9OIik7Ci0gICAgICBidWYuYXBwZW5kKGYuZ2V0KG51bGwpKTsKLQotICAgICAgaC5wdXQoVkVSU0lPTiArICJ4YWxhbjJ4IiwgYnVmLnRvU3RyaW5nKCkpOwotICAgIH0KLSAgICBjYXRjaCAoRXhjZXB0aW9uIGUyKQotICAgIHsKLSAgICAgIGgucHV0KFZFUlNJT04gKyAieGFsYW4yeCIsIENMQVNTX05PVFBSRVNFTlQpOwotICAgIH0KLSAgICB0cnkKLSAgICB7Ci0gICAgICAvLyBOT1RFOiBUaGlzIGlzIHRoZSBuZXcgWGFsYW4gMi4yKyB2ZXJzaW9uIGNsYXNzCi0gICAgICBmaW5hbCBTdHJpbmcgWEFMQU4yXzJfVkVSU0lPTl9DTEFTUyA9Ci0gICAgICAgICJjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwuVmVyc2lvbiI7Ci0gICAgICBmaW5hbCBTdHJpbmcgWEFMQU4yXzJfVkVSU0lPTl9NRVRIT0QgPSAiZ2V0VmVyc2lvbiI7Ci0gICAgICBmaW5hbCBDbGFzcyBub0FyZ3NbXSA9IG5ldyBDbGFzc1swXTsKLQotICAgICAgQ2xhc3MgY2xhenogPSBPYmplY3RGYWN0b3J5LmZpbmRQcm92aWRlckNsYXNzKFhBTEFOMl8yX1ZFUlNJT05fQ0xBU1MsIHRydWUpOwotCi0gICAgICBNZXRob2QgbWV0aG9kID0gY2xhenouZ2V0TWV0aG9kKFhBTEFOMl8yX1ZFUlNJT05fTUVUSE9ELCBub0FyZ3MpOwotICAgICAgT2JqZWN0IHJldHVyblZhbHVlID0gbWV0aG9kLmludm9rZShudWxsLCBuZXcgT2JqZWN0WzBdKTsKLQotICAgICAgaC5wdXQoVkVSU0lPTiArICJ4YWxhbjJfMiIsIChTdHJpbmcpcmV0dXJuVmFsdWUpOwotICAgIH0KLSAgICBjYXRjaCAoRXhjZXB0aW9uIGUyKQotICAgIHsKLSAgICAgIGgucHV0KFZFUlNJT04gKyAieGFsYW4yXzIiLCBDTEFTU19OT1RQUkVTRU5UKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogUmVwb3J0IHByb2R1Y3QgdmVyc2lvbiBpbmZvcm1hdGlvbiBmcm9tIGNvbW1vbiBwYXJzZXJzLgotICAgKgotICAgKiBMb29rcyBmb3IgdmVyc2lvbiBpbmZvIGluIHhlcmNlcy5qYXIveGVyY2VzSW1wbC5qYXIvY3JpbXNvbi5qYXIuCi0gICAqCi0gICAqIC8vQHRvZG8gYWN0dWFsbHkgbG9vayB1cCB2ZXJzaW9uIGluZm8gaW4gY3JpbXNvbiBtYW5pZmVzdAotICAgKgotICAgKiBAcGFyYW0gaCBNYXAgdG8gcHV0IGluZm9ybWF0aW9uIGluCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBjaGVja1BhcnNlclZlcnNpb24oTWFwPFN0cmluZywgT2JqZWN0PiBoKQotICB7Ci0KLSAgICBpZiAobnVsbCA9PSBoKQotICAgICAgaCA9IG5ldyBIYXNoTWFwPD4oKTsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIGZpbmFsIFN0cmluZyBYRVJDRVMxX1ZFUlNJT05fQ0xBU1MgPSAiY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5mcmFtZXdvcmsuVmVyc2lvbiI7Ci0KLSAgICAgIENsYXNzIGNsYXp6ID0gT2JqZWN0RmFjdG9yeS5maW5kUHJvdmlkZXJDbGFzcyhYRVJDRVMxX1ZFUlNJT05fQ0xBU1MsIHRydWUpOwotCi0gICAgICAvLyBGb3VuZCBYZXJjZXMtSiAxLngsIGdyYWIgaXQncyB2ZXJzaW9uIGZpZWxkcwotICAgICAgRmllbGQgZiA9IGNsYXp6LmdldEZpZWxkKCJmVmVyc2lvbiIpOwotICAgICAgU3RyaW5nIHBhcnNlclZlcnNpb24gPSAoU3RyaW5nKSBmLmdldChudWxsKTsKLQotICAgICAgaC5wdXQoVkVSU0lPTiArICJ4ZXJjZXMxIiwgcGFyc2VyVmVyc2lvbik7Ci0gICAgfQotICAgIGNhdGNoIChFeGNlcHRpb24gZSkKLSAgICB7Ci0gICAgICBoLnB1dChWRVJTSU9OICsgInhlcmNlczEiLCBDTEFTU19OT1RQUkVTRU5UKTsKLSAgICB9Ci0KLSAgICAvLyBMb29rIGZvciB4ZXJjZXMxIGFuZCB4ZXJjZXMyIHBhcnNlcnMgc2VwYXJhdGVseQotICAgIHRyeQotICAgIHsKLSAgICAgIGZpbmFsIFN0cmluZyBYRVJDRVMyX1ZFUlNJT05fQ0xBU1MgPSAiY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLlZlcnNpb24iOwotCi0gICAgICBDbGFzcyBjbGF6eiA9IE9iamVjdEZhY3RvcnkuZmluZFByb3ZpZGVyQ2xhc3MoWEVSQ0VTMl9WRVJTSU9OX0NMQVNTLCB0cnVlKTsKLQotICAgICAgLy8gRm91bmQgWGVyY2VzLUogMi54LCBncmFiIGl0J3MgdmVyc2lvbiBmaWVsZHMKLSAgICAgIEZpZWxkIGYgPSBjbGF6ei5nZXRGaWVsZCgiZlZlcnNpb24iKTsKLSAgICAgIFN0cmluZyBwYXJzZXJWZXJzaW9uID0gKFN0cmluZykgZi5nZXQobnVsbCk7Ci0KLSAgICAgIGgucHV0KFZFUlNJT04gKyAieGVyY2VzMiIsIHBhcnNlclZlcnNpb24pOwotICAgIH0KLSAgICBjYXRjaCAoRXhjZXB0aW9uIGUpCi0gICAgewotICAgICAgaC5wdXQoVkVSU0lPTiArICJ4ZXJjZXMyIiwgQ0xBU1NfTk9UUFJFU0VOVCk7Ci0gICAgfQotCi0gICAgdHJ5Ci0gICAgewotICAgICAgZmluYWwgU3RyaW5nIENSSU1TT05fQ0xBU1MgPSAib3JnLmFwYWNoZS5jcmltc29uLnBhcnNlci5QYXJzZXIyIjsKLQotICAgICAgQ2xhc3MgY2xhenogPSBPYmplY3RGYWN0b3J5LmZpbmRQcm92aWRlckNsYXNzKENSSU1TT05fQ0xBU1MsIHRydWUpOwotCi0gICAgICAvL0B0b2RvIGRldGVybWluZSBzcGVjaWZpYyBjcmltc29uIHZlcnNpb24KLSAgICAgIGgucHV0KFZFUlNJT04gKyAiY3JpbXNvbiIsIENMQVNTX1BSRVNFTlQpOwotICAgIH0KLSAgICBjYXRjaCAoRXhjZXB0aW9uIGUpCi0gICAgewotICAgICAgaC5wdXQoVkVSU0lPTiArICJjcmltc29uIiwgQ0xBU1NfTk9UUFJFU0VOVCk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFJlcG9ydCBwcm9kdWN0IHZlcnNpb24gaW5mb3JtYXRpb24gZnJvbSBBbnQuCi0gICAqCi0gICAqIEBwYXJhbSBoIE1hcCB0byBwdXQgaW5mb3JtYXRpb24gaW4KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIGNoZWNrQW50VmVyc2lvbihNYXA8U3RyaW5nLCBPYmplY3Q+IGgpCi0gIHsKLQotICAgIGlmIChudWxsID09IGgpCi0gICAgICBoID0gbmV3IEhhc2hNYXA8PigpOwotCi0gICAgdHJ5Ci0gICAgewotICAgICAgZmluYWwgU3RyaW5nIEFOVF9WRVJTSU9OX0NMQVNTID0gIm9yZy5hcGFjaGUudG9vbHMuYW50Lk1haW4iOwotICAgICAgZmluYWwgU3RyaW5nIEFOVF9WRVJTSU9OX01FVEhPRCA9ICJnZXRBbnRWZXJzaW9uIjsgLy8gbm9BcmdzCi0gICAgICBmaW5hbCBDbGFzcyBub0FyZ3NbXSA9IG5ldyBDbGFzc1swXTsKLQotICAgICAgQ2xhc3MgY2xhenogPSBPYmplY3RGYWN0b3J5LmZpbmRQcm92aWRlckNsYXNzKEFOVF9WRVJTSU9OX0NMQVNTLCB0cnVlKTsKLQotICAgICAgTWV0aG9kIG1ldGhvZCA9IGNsYXp6LmdldE1ldGhvZChBTlRfVkVSU0lPTl9NRVRIT0QsIG5vQXJncyk7Ci0gICAgICBPYmplY3QgcmV0dXJuVmFsdWUgPSBtZXRob2QuaW52b2tlKG51bGwsIG5ldyBPYmplY3RbMF0pOwotCi0gICAgICBoLnB1dChWRVJTSU9OICsgImFudCIsIChTdHJpbmcpcmV0dXJuVmFsdWUpOwotICAgIH0KLSAgICBjYXRjaCAoRXhjZXB0aW9uIGUpCi0gICAgewotICAgICAgaC5wdXQoVkVSU0lPTiArICJhbnQiLCBDTEFTU19OT1RQUkVTRU5UKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogUmVwb3J0IHZlcnNpb24gaW5mbyBmcm9tIERPTSBpbnRlcmZhY2VzLgotICAgKgotICAgKiBAcGFyYW0gaCBNYXAgdG8gcHV0IGluZm9ybWF0aW9uIGluCi0gICAqLwotICBwcm90ZWN0ZWQgYm9vbGVhbiBjaGVja0RPTUwzKE1hcDxTdHJpbmcsIE9iamVjdD4gaCkKLSAgewotCi0gICAgaWYgKG51bGwgPT0gaCkKLSAgICAgIGggPSBuZXcgSGFzaE1hcDw+KCk7Ci0KLSAgICBmaW5hbCBTdHJpbmcgRE9NX0NMQVNTID0gIm9yZy53M2MuZG9tLkRvY3VtZW50IjsKLSAgICBmaW5hbCBTdHJpbmcgRE9NX0xFVkVMM19NRVRIT0QgPSAiZ2V0RG9jdHlwZSI7ICAvLyBubyBwYXJhbWV0ZXIKLQotICAgIHRyeQotICAgIHsKLSAgICAgIENsYXNzIGNsYXp6ID0gT2JqZWN0RmFjdG9yeS5maW5kUHJvdmlkZXJDbGFzcyhET01fQ0xBU1MsIHRydWUpOwotCi0gICAgICBNZXRob2QgbWV0aG9kID0gY2xhenouZ2V0TWV0aG9kKERPTV9MRVZFTDNfTUVUSE9ELCAoQ2xhc3M8Pz5bXSludWxsKTsKLQotICAgICAgLy8gSWYgd2Ugc3VjY2VlZGVkLCB3ZSBoYXZlIGxvYWRlZCBpbnRlcmZhY2VzIGZyb20gYQotICAgICAgLy8gIGxldmVsIDMgRE9NIHNvbWV3aGVyZQotICAgICAgaC5wdXQoVkVSU0lPTiArICJET00iLCAiMy4wIik7Ci0gICAgICByZXR1cm4gdHJ1ZTsKLSAgICB9Ci0gICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKQotICAgIHsKLSAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogUmVwb3J0IHZlcnNpb24gaW5mbyBmcm9tIERPTSBpbnRlcmZhY2VzLgotICAgKgotICAgKiBDdXJyZW50bHkgZGlzdGluZ3Vpc2hlcyBiZXR3ZWVuIHByZS1ET00gbGV2ZWwgMiwgdGhlIERPTQotICAgKiBsZXZlbCAyIHdvcmtpbmcgZHJhZnQsIHRoZSBET00gbGV2ZWwgMiBmaW5hbCBkcmFmdCwKLSAgICogYW5kIG5vdCBmb3VuZC4KLSAgICoKLSAgICogQHBhcmFtIGggTWFwIHRvIHB1dCBpbmZvcm1hdGlvbiBpbgotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgY2hlY2tET01WZXJzaW9uKE1hcDxTdHJpbmcsIE9iamVjdD4gaCkKLSAgewotCi0gICAgaWYgKG51bGwgPT0gaCkKLSAgICAgIGggPSBuZXcgSGFzaE1hcDw+KCk7Ci0KLSAgICBmaW5hbCBTdHJpbmcgRE9NX0xFVkVMMl9DTEFTUyA9ICJvcmcudzNjLmRvbS5Eb2N1bWVudCI7Ci0gICAgZmluYWwgU3RyaW5nIERPTV9MRVZFTDJfTUVUSE9EID0gImNyZWF0ZUVsZW1lbnROUyI7ICAvLyBTdHJpbmcsIFN0cmluZwotICAgIGZpbmFsIFN0cmluZyBET01fTEVWRUwzX01FVEhPRCA9ICJnZXREb2N0eXBlIjsgIC8vIG5vIHBhcmFtZXRlcgotICAgIGZpbmFsIFN0cmluZyBET01fTEVWRUwyV0RfQ0xBU1MgPSAib3JnLnczYy5kb20uTm9kZSI7Ci0gICAgZmluYWwgU3RyaW5nIERPTV9MRVZFTDJXRF9NRVRIT0QgPSAic3VwcG9ydGVkIjsgIC8vIFN0cmluZywgU3RyaW5nCi0gICAgZmluYWwgU3RyaW5nIERPTV9MRVZFTDJGRF9DTEFTUyA9ICJvcmcudzNjLmRvbS5Ob2RlIjsKLSAgICBmaW5hbCBTdHJpbmcgRE9NX0xFVkVMMkZEX01FVEhPRCA9ICJpc1N1cHBvcnRlZCI7ICAvLyBTdHJpbmcsIFN0cmluZwotICAgIGZpbmFsIENsYXNzIHR3b1N0cmluZ0FyZ3NbXSA9IHsgamF2YS5sYW5nLlN0cmluZy5jbGFzcywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcuY2xhc3MgfTsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIENsYXNzIGNsYXp6ID0gT2JqZWN0RmFjdG9yeS5maW5kUHJvdmlkZXJDbGFzcyhET01fTEVWRUwyX0NMQVNTLCB0cnVlKTsKLQotICAgICAgTWV0aG9kIG1ldGhvZCA9IGNsYXp6LmdldE1ldGhvZChET01fTEVWRUwyX01FVEhPRCwgdHdvU3RyaW5nQXJncyk7Ci0KLSAgICAgIC8vIElmIHdlIHN1Y2NlZWRlZCwgd2UgaGF2ZSBsb2FkZWQgaW50ZXJmYWNlcyBmcm9tIGEKLSAgICAgIC8vICBsZXZlbCAyIERPTSBzb21ld2hlcmUKLSAgICAgIGgucHV0KFZFUlNJT04gKyAiRE9NIiwgIjIuMCIpOwotCi0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgLy8gQ2hlY2sgZm9yIHRoZSB3b3JraW5nIGRyYWZ0IHZlcnNpb24sIHdoaWNoIGlzCi0gICAgICAgIC8vICBjb21tb25seSBmb3VuZCwgYnV0IHdvbid0IHdvcmsgYW55bW9yZQotICAgICAgICBjbGF6eiA9IE9iamVjdEZhY3RvcnkuZmluZFByb3ZpZGVyQ2xhc3MoRE9NX0xFVkVMMldEX0NMQVNTLCB0cnVlKTsKLQotICAgICAgICBtZXRob2QgPSBjbGF6ei5nZXRNZXRob2QoRE9NX0xFVkVMMldEX01FVEhPRCwgdHdvU3RyaW5nQXJncyk7Ci0KLSAgICAgICAgaC5wdXQoRVJST1IgKyBWRVJTSU9OICsgIkRPTS5kcmFmdGxldmVsIiwgIjIuMHdkIik7Ci0gICAgICAgIGgucHV0KEVSUk9SLCBFUlJPUl9GT1VORCk7Ci0gICAgICB9Ci0gICAgICBjYXRjaCAoRXhjZXB0aW9uIGUyKQotICAgICAgewotICAgICAgICB0cnkKLSAgICAgICAgewotICAgICAgICAgIC8vIENoZWNrIGZvciB0aGUgZmluYWwgZHJhZnQgdmVyc2lvbiBhcyB3ZWxsCi0gICAgICAgICAgY2xhenogPSBPYmplY3RGYWN0b3J5LmZpbmRQcm92aWRlckNsYXNzKERPTV9MRVZFTDJGRF9DTEFTUywgdHJ1ZSk7Ci0KLSAgICAgICAgICBtZXRob2QgPSBjbGF6ei5nZXRNZXRob2QoRE9NX0xFVkVMMkZEX01FVEhPRCwgdHdvU3RyaW5nQXJncyk7Ci0KLSAgICAgICAgICBoLnB1dChWRVJTSU9OICsgIkRPTS5kcmFmdGxldmVsIiwgIjIuMGZkIik7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBlMykKLSAgICAgICAgewotICAgICAgICAgIGgucHV0KEVSUk9SICsgVkVSU0lPTiArICJET00uZHJhZnRsZXZlbCIsICIyLjB1bmtub3duIik7Ci0gICAgICAgICAgaC5wdXQoRVJST1IsIEVSUk9SX0ZPVU5EKTsKLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLSAgICBjYXRjaCAoRXhjZXB0aW9uIGUpCi0gICAgewotICAgICAgaC5wdXQoRVJST1IgKyBWRVJTSU9OICsgIkRPTSIsCi0gICAgICAgICAgICAiRVJST1IgYXR0ZW1wdGluZyB0byBsb2FkIERPTSBsZXZlbCAyIGNsYXNzOiAiICsgZS50b1N0cmluZygpKTsKLSAgICAgIGgucHV0KEVSUk9SLCBFUlJPUl9GT1VORCk7Ci0gICAgfQotCi0gICAgLy9AdG9kbyBsb2FkIGFuIGFjdHVhbCBET00gaW1wbG1lbWVudGF0aW9uIGFuZCBxdWVyeSBpdCBhcyB3ZWxsCi0gICAgLy9AdG9kbyBsb2FkIGFuIGFjdHVhbCBET00gaW1wbG1lbWVudGF0aW9uIGFuZCBjaGVjayBpZgotICAgIC8vICBpc05hbWVzcGFjZUF3YXJlKCkgPT0gdHJ1ZSwgd2hpY2ggaXMgbmVlZGVkIHRvIHBhcnNlCi0gICAgLy8gIHhzbCBzdHlsZXNoZWV0IGZpbGVzIGludG8gYSBET00KLSAgfQotCi0gIC8qKgotICAgKiBSZXBvcnQgdmVyc2lvbiBpbmZvIGZyb20gU0FYIGludGVyZmFjZXMuCi0gICAqCi0gICAqIEN1cnJlbnRseSBkaXN0aW5ndWlzaGVzIGJldHdlZW4gU0FYIDIsIFNBWCAyLjBiZXRhMiwKLSAgICogU0FYMSwgYW5kIG5vdCBmb3VuZC4KLSAgICoKLSAgICogQHBhcmFtIGggTWFwIHRvIHB1dCBpbmZvcm1hdGlvbiBpbgotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgY2hlY2tTQVhWZXJzaW9uKE1hcDxTdHJpbmcsIE9iamVjdD4gaCkKLSAgewotCi0gICAgaWYgKG51bGwgPT0gaCkKLSAgICAgIGggPSBuZXcgSGFzaE1hcDw+KCk7Ci0KLSAgICBmaW5hbCBTdHJpbmcgU0FYX1ZFUlNJT04xX0NMQVNTID0gIm9yZy54bWwuc2F4LlBhcnNlciI7Ci0gICAgZmluYWwgU3RyaW5nIFNBWF9WRVJTSU9OMV9NRVRIT0QgPSAicGFyc2UiOyAgLy8gU3RyaW5nCi0gICAgZmluYWwgU3RyaW5nIFNBWF9WRVJTSU9OMl9DTEFTUyA9ICJvcmcueG1sLnNheC5YTUxSZWFkZXIiOwotICAgIGZpbmFsIFN0cmluZyBTQVhfVkVSU0lPTjJfTUVUSE9EID0gInBhcnNlIjsgIC8vIFN0cmluZwotICAgIGZpbmFsIFN0cmluZyBTQVhfVkVSU0lPTjJCRVRBX0NMQVNTTkYgPSAib3JnLnhtbC5zYXguaGVscGVycy5BdHRyaWJ1dGVzSW1wbCI7Ci0gICAgZmluYWwgU3RyaW5nIFNBWF9WRVJTSU9OMkJFVEFfTUVUSE9ETkYgPSAic2V0QXR0cmlidXRlcyI7ICAvLyBBdHRyaWJ1dGVzCi0gICAgZmluYWwgQ2xhc3Mgb25lU3RyaW5nQXJnW10gPSB7IGphdmEubGFuZy5TdHJpbmcuY2xhc3MgfTsKLSAgICAvLyBOb3RlIHRoaXMgaW50cm9kdWNlcyBhIG1pbm9yIGNvbXBpbGUgZGVwZW5kZW5jeSBvbiBTQVguLi4KLSAgICBmaW5hbCBDbGFzcyBhdHRyaWJ1dGVzQXJnW10gPSB7IG9yZy54bWwuc2F4LkF0dHJpYnV0ZXMuY2xhc3MgfTsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIC8vIFRoaXMgbWV0aG9kIHdhcyBvbmx5IGFkZGVkIGluIHRoZSBmaW5hbCBTQVggMi4wIHJlbGVhc2U7Ci0gICAgICAvLyAgc2VlIGNoYW5nZXMuaHRtbCAiQ2hhbmdlcyBmcm9tIFNBWCAyLjBiZXRhMiB0byBTQVggMi4wcHJlcmVsZWFzZSIKLSAgICAgIENsYXNzIGNsYXp6ID0gT2JqZWN0RmFjdG9yeS5maW5kUHJvdmlkZXJDbGFzcyhTQVhfVkVSU0lPTjJCRVRBX0NMQVNTTkYsIHRydWUpOwotCi0gICAgICBNZXRob2QgbWV0aG9kID0gY2xhenouZ2V0TWV0aG9kKFNBWF9WRVJTSU9OMkJFVEFfTUVUSE9ETkYsIGF0dHJpYnV0ZXNBcmcpOwotCi0gICAgICAvLyBJZiB3ZSBzdWNjZWVkZWQsIHdlIGhhdmUgbG9hZGVkIGludGVyZmFjZXMgZnJvbSBhCi0gICAgICAvLyAgcmVhbCwgZmluYWwgU0FYIHZlcnNpb24gMi4wIHNvbWV3aGVyZQotICAgICAgaC5wdXQoVkVSU0lPTiArICJTQVgiLCAiMi4wIik7Ci0gICAgfQotICAgIGNhdGNoIChFeGNlcHRpb24gZSkKLSAgICB7Ci0gICAgICAvLyBJZiB3ZSBkaWRuJ3QgZmluZCB0aGUgU0FYIDIuMCBjbGFzcywgbG9vayBmb3IgYSAyLjBiZXRhMgotICAgICAgaC5wdXQoRVJST1IgKyBWRVJTSU9OICsgIlNBWCIsCi0gICAgICAgICAgICAiRVJST1IgYXR0ZW1wdGluZyB0byBsb2FkIFNBWCB2ZXJzaW9uIDIgY2xhc3M6ICIgKyBlLnRvU3RyaW5nKCkpOwotICAgICAgaC5wdXQoRVJST1IsIEVSUk9SX0ZPVU5EKTsKLQotICAgICAgdHJ5Ci0gICAgICB7Ci0gICAgICAgIENsYXNzIGNsYXp6ID0gT2JqZWN0RmFjdG9yeS5maW5kUHJvdmlkZXJDbGFzcyhTQVhfVkVSU0lPTjJfQ0xBU1MsIHRydWUpOwotCi0gICAgICAgIE1ldGhvZCBtZXRob2QgPSBjbGF6ei5nZXRNZXRob2QoU0FYX1ZFUlNJT04yX01FVEhPRCwgb25lU3RyaW5nQXJnKTsKLQotICAgICAgICAvLyBJZiB3ZSBzdWNjZWVkZWQsIHdlIGhhdmUgbG9hZGVkIGludGVyZmFjZXMgZnJvbSBhCi0gICAgICAgIC8vICBTQVggdmVyc2lvbiAyLjBiZXRhMiBvciBlYXJsaWVyOyB0aGVzZSBtaWdodCB3b3JrIGJ1dAotICAgICAgICAvLyAgeW91IHNob3VsZCByZWFsbHkgaGF2ZSB0aGUgZmluYWwgU0FYIDIuMAotICAgICAgICBoLnB1dChWRVJTSU9OICsgIlNBWC1iYWNrbGV2ZWwiLCAiMi4wYmV0YTItb3ItZWFybGllciIpOwotICAgICAgfQotICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBlMikKLSAgICAgIHsKLSAgICAgICAgLy8gSWYgd2UgZGlkbid0IGZpbmQgdGhlIFNBWCAyLjBiZXRhMiBjbGFzcywgbG9vayBmb3IgYSAxLjAgb25lCi0gICAgICAgIGgucHV0KEVSUk9SICsgVkVSU0lPTiArICJTQVgiLAotICAgICAgICAgICAgICAiRVJST1IgYXR0ZW1wdGluZyB0byBsb2FkIFNBWCB2ZXJzaW9uIDIgY2xhc3M6ICIgKyBlLnRvU3RyaW5nKCkpOwotICAgICAgICBoLnB1dChFUlJPUiwgRVJST1JfRk9VTkQpOwotCi0gICAgICAgIHRyeQotICAgICAgICB7Ci0gICAgICAgICAgQ2xhc3MgY2xhenogPSBPYmplY3RGYWN0b3J5LmZpbmRQcm92aWRlckNsYXNzKFNBWF9WRVJTSU9OMV9DTEFTUywgdHJ1ZSk7Ci0KLSAgICAgICAgICBNZXRob2QgbWV0aG9kID0gY2xhenouZ2V0TWV0aG9kKFNBWF9WRVJTSU9OMV9NRVRIT0QsIG9uZVN0cmluZ0FyZyk7Ci0KLSAgICAgICAgICAvLyBJZiB3ZSBzdWNjZWVkZWQsIHdlIGhhdmUgbG9hZGVkIGludGVyZmFjZXMgZnJvbSBhCi0gICAgICAgICAgLy8gIFNBWCB2ZXJzaW9uIDEuMCBzb21ld2hlcmU7IHdoaWNoIHdvbid0IHdvcmsgdmVyeQotICAgICAgICAgIC8vICB3ZWxsIGZvciBKQVhQIDEuMSBvciBiZXlvbmQhCi0gICAgICAgICAgaC5wdXQoVkVSU0lPTiArICJTQVgtYmFja2xldmVsIiwgIjEuMCIpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChFeGNlcHRpb24gZTMpCi0gICAgICAgIHsKLSAgICAgICAgICAvLyBJZiB3ZSBkaWRuJ3QgZmluZCB0aGUgU0FYIDIuMCBjbGFzcywgbG9vayBmb3IgYSAxLjAgb25lCi0gICAgICAgICAgLy8gTm90ZSB0aGF0IGVpdGhlciAxLjAgb3Igbm8gU0FYIGFyZSBib3RoIGVycm9ycwotICAgICAgICAgIGgucHV0KEVSUk9SICsgVkVSU0lPTiArICJTQVgtYmFja2xldmVsIiwKLSAgICAgICAgICAgICAgICAiRVJST1IgYXR0ZW1wdGluZyB0byBsb2FkIFNBWCB2ZXJzaW9uIDEgY2xhc3M6ICIgKyBlMy50b1N0cmluZygpKTsKLQotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIE1hbnVhbCB0YWJsZSBvZiBrbm93biAuamFyIHNpemVzLgotICAgKiBPbmx5IGluY2x1ZGVzIHNoaXBwZWQgdmVyc2lvbnMgb2YgY2VydGFpbiBwcm9qZWN0cy4KLSAgICoga2V5PWphcnNpemUsIHZhbHVlPWphcm5hbWUgJyBmcm9tICcgZGlzdHJvIG5hbWUKLSAgICogTm90ZSBhc3N1bXB0aW9uOiB0d28gamFycyBjYW5ub3QgaGF2ZSB0aGUgc2FtZSBzaXplIQotICAgKgotICAgKiBAc2VlICNnZXRBcHBhcmVudFZlcnNpb24oU3RyaW5nLCBsb25nKQotICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTWFwPExvbmcsIFN0cmluZz4gSkFSVkVSU0lPTlM7Ci0KLSAgLyoqCi0gICAqIFN0YXRpYyBpbml0aWFsaXplciBmb3IgSkFSVkVSU0lPTlMgdGFibGUuCi0gICAqIERvaW5nIHRoaXMganVzdCBvbmNlIHNhdmVzIHRpbWUgYW5kIHNwYWNlLgotICAgKgotICAgKiBAc2VlICNnZXRBcHBhcmVudFZlcnNpb24oU3RyaW5nLCBsb25nKQotICAgKi8KLSAgc3RhdGljCi0gIHsKLSAgICBNYXA8TG9uZywgU3RyaW5nPiBqYXJWZXJzaW9ucyA9IG5ldyBIYXNoTWFwPD4oKTsKLSAgICBqYXJWZXJzaW9ucy5wdXQobmV3IExvbmcoODU3MTkyKSwgInhhbGFuLmphciBmcm9tIHhhbGFuLWpfMV8xIik7Ci0gICAgamFyVmVyc2lvbnMucHV0KG5ldyBMb25nKDQ0MDIzNyksICJ4YWxhbi5qYXIgZnJvbSB4YWxhbi1qXzFfMiIpOwotICAgIGphclZlcnNpb25zLnB1dChuZXcgTG9uZyg0MzYwOTQpLCAieGFsYW4uamFyIGZyb20geGFsYW4tal8xXzJfMSIpOwotICAgIGphclZlcnNpb25zLnB1dChuZXcgTG9uZyg0MjYyNDkpLCAieGFsYW4uamFyIGZyb20geGFsYW4tal8xXzJfMiIpOwotICAgIGphclZlcnNpb25zLnB1dChuZXcgTG9uZyg3MDI1MzYpLCAieGFsYW4uamFyIGZyb20geGFsYW4tal8yXzBfMCIpOwotICAgIGphclZlcnNpb25zLnB1dChuZXcgTG9uZyg3MjA5MzApLCAieGFsYW4uamFyIGZyb20geGFsYW4tal8yXzBfMSIpOwotICAgIGphclZlcnNpb25zLnB1dChuZXcgTG9uZyg3MzIzMzApLCAieGFsYW4uamFyIGZyb20geGFsYW4tal8yXzFfMCIpOwotICAgIGphclZlcnNpb25zLnB1dChuZXcgTG9uZyg4NzIyNDEpLCAieGFsYW4uamFyIGZyb20geGFsYW4tal8yXzJfRDEwIik7Ci0gICAgamFyVmVyc2lvbnMucHV0KG5ldyBMb25nKDg4MjczOSksICJ4YWxhbi5qYXIgZnJvbSB4YWxhbi1qXzJfMl9EMTEiKTsKLSAgICBqYXJWZXJzaW9ucy5wdXQobmV3IExvbmcoOTIzODY2KSwgInhhbGFuLmphciBmcm9tIHhhbGFuLWpfMl8yXzAiKTsKLSAgICBqYXJWZXJzaW9ucy5wdXQobmV3IExvbmcoOTA1ODcyKSwgInhhbGFuLmphciBmcm9tIHhhbGFuLWpfMl8zX0QxIik7Ci0gICAgamFyVmVyc2lvbnMucHV0KG5ldyBMb25nKDkwNjEyMiksICJ4YWxhbi5qYXIgZnJvbSB4YWxhbi1qXzJfM18wIik7Ci0gICAgamFyVmVyc2lvbnMucHV0KG5ldyBMb25nKDkwNjI0OCksICJ4YWxhbi5qYXIgZnJvbSB4YWxhbi1qXzJfM18xIik7Ci0gICAgamFyVmVyc2lvbnMucHV0KG5ldyBMb25nKDk4MzM3NyksICJ4YWxhbi5qYXIgZnJvbSB4YWxhbi1qXzJfNF9EMSIpOwotICAgIGphclZlcnNpb25zLnB1dChuZXcgTG9uZyg5OTcyNzYpLCAieGFsYW4uamFyIGZyb20geGFsYW4tal8yXzRfMCIpOwotICAgIGphclZlcnNpb25zLnB1dChuZXcgTG9uZygxMDMxMDM2KSwgInhhbGFuLmphciBmcm9tIHhhbGFuLWpfMl80XzEiKTsKLSAgICAvLyBTdG9wIHJlY29yZGluZyB4YWxhbi5qYXIgc2l6ZXMgYXMgb2YgWGFsYW4gSmF2YSAyLjUuMAotCi0gICAgamFyVmVyc2lvbnMucHV0KG5ldyBMb25nKDU5NjU0MCksICJ4c2x0Yy5qYXIgZnJvbSB4YWxhbi1qXzJfMl8wIik7Ci0gICAgamFyVmVyc2lvbnMucHV0KG5ldyBMb25nKDU5MDI0NyksICJ4c2x0Yy5qYXIgZnJvbSB4YWxhbi1qXzJfM19EMSIpOwotICAgIGphclZlcnNpb25zLnB1dChuZXcgTG9uZyg1ODk5MTQpLCAieHNsdGMuamFyIGZyb20geGFsYW4tal8yXzNfMCIpOwotICAgIGphclZlcnNpb25zLnB1dChuZXcgTG9uZyg1ODk5MTUpLCAieHNsdGMuamFyIGZyb20geGFsYW4tal8yXzNfMSIpOwotICAgIGphclZlcnNpb25zLnB1dChuZXcgTG9uZygxMzA2NjY3KSwgInhzbHRjLmphciBmcm9tIHhhbGFuLWpfMl80X0QxIik7Ci0gICAgamFyVmVyc2lvbnMucHV0KG5ldyBMb25nKDEzMjgyMjcpLCAieHNsdGMuamFyIGZyb20geGFsYW4tal8yXzRfMCIpOwotICAgIGphclZlcnNpb25zLnB1dChuZXcgTG9uZygxMzQ0MDA5KSwgInhzbHRjLmphciBmcm9tIHhhbGFuLWpfMl80XzEiKTsKLSAgICBqYXJWZXJzaW9ucy5wdXQobmV3IExvbmcoMTM0ODM2MSksICJ4c2x0Yy5qYXIgZnJvbSB4YWxhbi1qXzJfNV9EMSIpOwotICAgIC8vIFN0b3AgcmVjb3JkaW5nIHhzbHRjLmphciBzaXplcyBhcyBvZiBYYWxhbiBKYXZhIDIuNS4wCi0KLSAgICBqYXJWZXJzaW9ucy5wdXQobmV3IExvbmcoMTI2ODYzNCksICJ4c2x0Yy5qYXItYnVuZGxlZCBmcm9tIHhhbGFuLWpfMl8zXzAiKTsKLQotICAgIGphclZlcnNpb25zLnB1dChuZXcgTG9uZygxMDAxOTYpLCAieG1sLWFwaXMuamFyIGZyb20geGFsYW4tal8yXzJfMCBvciB4YWxhbi1qXzJfM19EMSIpOwotICAgIGphclZlcnNpb25zLnB1dChuZXcgTG9uZygxMDg0ODQpLCAieG1sLWFwaXMuamFyIGZyb20geGFsYW4tal8yXzNfMCwgb3IgeGFsYW4tal8yXzNfMSBmcm9tIHhtbC1jb21tb25zLTEuMC5iMiIpOwotICAgIGphclZlcnNpb25zLnB1dChuZXcgTG9uZygxMDkwNDkpLCAieG1sLWFwaXMuamFyIGZyb20geGFsYW4tal8yXzRfMCBmcm9tIHhtbC1jb21tb25zIFJJVkVSQ09VUlQxIGJyYW5jaCIpOwotICAgIGphclZlcnNpb25zLnB1dChuZXcgTG9uZygxMTM3NDkpLCAieG1sLWFwaXMuamFyIGZyb20geGFsYW4tal8yXzRfMSBmcm9tIGZhY3RvcnlmaW5kZXItYnVpbGQgb2YgeG1sLWNvbW1vbnMgUklWRVJDT1VSVDEiKTsKLSAgICBqYXJWZXJzaW9ucy5wdXQobmV3IExvbmcoMTI0NzA0KSwgInhtbC1hcGlzLmphciBmcm9tIHRjay1qYXhwLTFfMl8wIGJyYW5jaCBvZiB4bWwtY29tbW9ucyIpOwotICAgIGphclZlcnNpb25zLnB1dChuZXcgTG9uZygxMjQ3MjQpLCAieG1sLWFwaXMuamFyIGZyb20gdGNrLWpheHAtMV8yXzAgYnJhbmNoIG9mIHhtbC1jb21tb25zLCB0YWc6IHhtbC1jb21tb25zLWV4dGVybmFsXzFfMl8wMSIpOwotICAgIGphclZlcnNpb25zLnB1dChuZXcgTG9uZygxOTQyMDUpLCAieG1sLWFwaXMuamFyIGZyb20gaGVhZCBicmFuY2ggb2YgeG1sLWNvbW1vbnMsIHRhZzogeG1sLWNvbW1vbnMtZXh0ZXJuYWxfMV8zXzAyIik7Ci0KLSAgICAvLyBJZiB0aGUgYmVsb3cgd2VyZSBtb3JlIGNvbW1vbiBJIHdvdWxkIHVwZGF0ZSBpdCB0byByZXBvcnQKLSAgICAvLyAgZXJyb3JzIGJldHRlcjsgYnV0IHRoaXMgaXMgc28gb2xkIGhhcmRseSBhbnlvbmUgaGFzIGl0Ci0gICAgamFyVmVyc2lvbnMucHV0KG5ldyBMb25nKDQyNDQ5MCksICJ4YWxhbi5qYXIgZnJvbSBYZXJjZXMgVG9vbHMgcmVsZWFzZXMgLSBFUlJPUjpETyBOT1QgVVNFISIpOwotCi0gICAgamFyVmVyc2lvbnMucHV0KG5ldyBMb25nKDE1OTE4NTUpLCAieGVyY2VzLmphciBmcm9tIHhhbGFuLWpfMV8xIGZyb20geGVyY2VzLTEuLi4iKTsKLSAgICBqYXJWZXJzaW9ucy5wdXQobmV3IExvbmcoMTQ5ODY3OSksICJ4ZXJjZXMuamFyIGZyb20geGFsYW4tal8xXzIgZnJvbSB4ZXJjZXMtMV8yXzAuYmluIik7Ci0gICAgamFyVmVyc2lvbnMucHV0KG5ldyBMb25nKDE0ODQ4OTYpLCAieGVyY2VzLmphciBmcm9tIHhhbGFuLWpfMV8yXzEgZnJvbSB4ZXJjZXMtMV8yXzEuYmluIik7Ci0gICAgamFyVmVyc2lvbnMucHV0KG5ldyBMb25nKDgwNDQ2MCksICAieGVyY2VzLmphciBmcm9tIHhhbGFuLWpfMV8yXzIgZnJvbSB4ZXJjZXMtMV8yXzIuYmluIik7Ci0gICAgamFyVmVyc2lvbnMucHV0KG5ldyBMb25nKDE0OTkyNDQpLCAieGVyY2VzLmphciBmcm9tIHhhbGFuLWpfMl8wXzAgZnJvbSB4ZXJjZXMtMV8yXzMuYmluIik7Ci0gICAgamFyVmVyc2lvbnMucHV0KG5ldyBMb25nKDE2MDUyNjYpLCAieGVyY2VzLmphciBmcm9tIHhhbGFuLWpfMl8wXzEgZnJvbSB4ZXJjZXMtMV8zXzAuYmluIik7Ci0gICAgamFyVmVyc2lvbnMucHV0KG5ldyBMb25nKDkwNDAzMCksICJ4ZXJjZXMuamFyIGZyb20geGFsYW4tal8yXzFfMCBmcm9tIHhlcmNlcy0xXzQuYmluIik7Ci0gICAgamFyVmVyc2lvbnMucHV0KG5ldyBMb25nKDkwNDAzMCksICJ4ZXJjZXMuamFyIGZyb20geGVyY2VzLTFfNF8wLmJpbiIpOwotICAgIGphclZlcnNpb25zLnB1dChuZXcgTG9uZygxODAyODg1KSwgInhlcmNlcy5qYXIgZnJvbSB4ZXJjZXMtMV80XzIuYmluIik7Ci0gICAgamFyVmVyc2lvbnMucHV0KG5ldyBMb25nKDE3MzQ1OTQpLCAieGVyY2VzLmphciBmcm9tIFhlcmNlcy1KLWJpbi4yLjAuMC5iZXRhMyIpOwotICAgIGphclZlcnNpb25zLnB1dChuZXcgTG9uZygxODA4ODgzKSwgInhlcmNlcy5qYXIgZnJvbSB4YWxhbi1qXzJfMl9EMTAsRDExLEQxMiBvciB4ZXJjZXMtMV80XzMuYmluIik7Ci0gICAgamFyVmVyc2lvbnMucHV0KG5ldyBMb25nKDE4MTIwMTkpLCAieGVyY2VzLmphciBmcm9tIHhhbGFuLWpfMl8yXzAiKTsKLSAgICBqYXJWZXJzaW9ucy5wdXQobmV3IExvbmcoMTcyMDI5MiksICJ4ZXJjZXNJbXBsLmphciBmcm9tIHhhbGFuLWpfMl8zX0QxIik7Ci0gICAgamFyVmVyc2lvbnMucHV0KG5ldyBMb25nKDE3MzAwNTMpLCAieGVyY2VzSW1wbC5qYXIgZnJvbSB4YWxhbi1qXzJfM18wIG9yIHhhbGFuLWpfMl8zXzEgZnJvbSB4ZXJjZXMtMl8wXzAiKTsKLSAgICBqYXJWZXJzaW9ucy5wdXQobmV3IExvbmcoMTcyODg2MSksICJ4ZXJjZXNJbXBsLmphciBmcm9tIHhhbGFuLWpfMl80X0QxIGZyb20geGVyY2VzLTJfMF8xIik7Ci0gICAgamFyVmVyc2lvbnMucHV0KG5ldyBMb25nKDk3MjAyNyksICJ4ZXJjZXNJbXBsLmphciBmcm9tIHhhbGFuLWpfMl80XzAgZnJvbSB4ZXJjZXMtMl8xIik7Ci0gICAgamFyVmVyc2lvbnMucHV0KG5ldyBMb25nKDgzMTU4NyksICJ4ZXJjZXNJbXBsLmphciBmcm9tIHhhbGFuLWpfMl80XzEgZnJvbSB4ZXJjZXMtMl8yIik7Ci0gICAgamFyVmVyc2lvbnMucHV0KG5ldyBMb25nKDg5MTgxNyksICJ4ZXJjZXNJbXBsLmphciBmcm9tIHhhbGFuLWpfMl81X0QxIGZyb20geGVyY2VzLTJfMyIpOwotICAgIGphclZlcnNpb25zLnB1dChuZXcgTG9uZyg4OTU5MjQpLCAieGVyY2VzSW1wbC5qYXIgZnJvbSB4ZXJjZXMtMl80Iik7Ci0gICAgamFyVmVyc2lvbnMucHV0KG5ldyBMb25nKDEwMTA4MDYpLCAieGVyY2VzSW1wbC5qYXIgZnJvbSBYZXJjZXMtSi1iaW4uMi42LjIiKTsKLSAgICBqYXJWZXJzaW9ucy5wdXQobmV3IExvbmcoMTIwMzg2MCksICJ4ZXJjZXNJbXBsLmphciBmcm9tIFhlcmNlcy1KLWJpbi4yLjcuMSIpOwotCi0gICAgamFyVmVyc2lvbnMucHV0KG5ldyBMb25nKDM3NDg1KSwgInhhbGFuajFjb21wYXQuamFyIGZyb20geGFsYW4tal8yXzBfMCIpOwotICAgIGphclZlcnNpb25zLnB1dChuZXcgTG9uZygzODEwMCksICJ4YWxhbmoxY29tcGF0LmphciBmcm9tIHhhbGFuLWpfMl8wXzEiKTsKLQotICAgIGphclZlcnNpb25zLnB1dChuZXcgTG9uZygxODc3OSksICJ4YWxhbnNlcnZsZXQuamFyIGZyb20geGFsYW4tal8yXzBfMCIpOwotICAgIGphclZlcnNpb25zLnB1dChuZXcgTG9uZygyMTQ1MyksICJ4YWxhbnNlcnZsZXQuamFyIGZyb20geGFsYW4tal8yXzBfMSIpOwotICAgIGphclZlcnNpb25zLnB1dChuZXcgTG9uZygyNDgyNiksICJ4YWxhbnNlcnZsZXQuamFyIGZyb20geGFsYW4tal8yXzNfMSBvciB4YWxhbi1qXzJfNF8xIik7Ci0gICAgamFyVmVyc2lvbnMucHV0KG5ldyBMb25nKDI0ODMxKSwgInhhbGFuc2VydmxldC5qYXIgZnJvbSB4YWxhbi1qXzJfNF8xIik7Ci0gICAgLy8gU3RvcCByZWNvcmRpbmcgeGFsYW5zZXJ2bGV0LmphciBzaXplcyBhcyBvZiBYYWxhbiBKYXZhIDIuNS4wOyBub3cgYSAud2FyIGZpbGUKLQotICAgIC8vIEZvciB0aG9zZSB3aG8ndmUgZG93bmxvYWRlZCBKQVhQIGZyb20gc3VuCi0gICAgamFyVmVyc2lvbnMucHV0KG5ldyBMb25nKDU2MTgpLCAiamF4cC5qYXIgZnJvbSBqYXhwMS4wLjEiKTsKLSAgICBqYXJWZXJzaW9ucy5wdXQobmV3IExvbmcoMTM2MTMzKSwgInBhcnNlci5qYXIgZnJvbSBqYXhwMS4wLjEiKTsKLSAgICBqYXJWZXJzaW9ucy5wdXQobmV3IExvbmcoMjg0MDQpLCAiamF4cC5qYXIgZnJvbSBqYXhwLTEuMSIpOwotICAgIGphclZlcnNpb25zLnB1dChuZXcgTG9uZygxODcxNjIpLCAiY3JpbXNvbi5qYXIgZnJvbSBqYXhwLTEuMSIpOwotICAgIGphclZlcnNpb25zLnB1dChuZXcgTG9uZyg4MDE3MTQpLCAieGFsYW4uamFyIGZyb20gamF4cC0xLjEiKTsKLSAgICBqYXJWZXJzaW9ucy5wdXQobmV3IExvbmcoMTk2Mzk5KSwgImNyaW1zb24uamFyIGZyb20gY3JpbXNvbi0xLjEuMSIpOwotICAgIGphclZlcnNpb25zLnB1dChuZXcgTG9uZygzMzMyMyksICJqYXhwLmphciBmcm9tIGNyaW1zb24tMS4xLjEgb3IgamFrYXJ0YS1hbnQtMS40LjFiMSIpOwotICAgIGphclZlcnNpb25zLnB1dChuZXcgTG9uZygxNTI3MTcpLCAiY3JpbXNvbi5qYXIgZnJvbSBjcmltc29uLTEuMS4yYmV0YTIiKTsKLSAgICBqYXJWZXJzaW9ucy5wdXQobmV3IExvbmcoODgxNDMpLCAieG1sLWFwaXMuamFyIGZyb20gY3JpbXNvbi0xLjEuMmJldGEyIik7Ci0gICAgamFyVmVyc2lvbnMucHV0KG5ldyBMb25nKDIwNjM4NCksICJjcmltc29uLmphciBmcm9tIGNyaW1zb24tMS4xLjMgb3IgamFrYXJ0YS1hbnQtMS40LjFiMSIpOwotCi0gICAgLy8gamFrYXJ0YS1hbnQ6IHNpbmNlIG1hbnkgcGVvcGxlIHVzZSBhbnQgdGhlc2UgZGF5cwotICAgIGphclZlcnNpb25zLnB1dChuZXcgTG9uZygxMzYxOTgpLCAicGFyc2VyLmphciBmcm9tIGpha2FydGEtYW50LTEuMyBvciAxLjIiKTsKLSAgICBqYXJWZXJzaW9ucy5wdXQobmV3IExvbmcoNTUzNyksICJqYXhwLmphciBmcm9tIGpha2FydGEtYW50LTEuMyBvciAxLjIiKTsKLQotICAgIEpBUlZFUlNJT05TID0gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTWFwKGphclZlcnNpb25zKTsKLSAgfQotCi0gIC8qKiBTaW1wbGUgUHJpbnRXcml0ZXIgd2Ugc2VuZCBvdXRwdXQgdG87IGRlZmF1bHRzIHRvIFN5c3RlbS5vdXQuICAqLwotICBwcm90ZWN0ZWQgUHJpbnRXcml0ZXIgb3V0V3JpdGVyID0gbmV3IFByaW50V3JpdGVyKFN5c3RlbS5vdXQsIHRydWUpOwotCi0gIC8qKgotICAgKiBCb3R0bGVuZWNrIG91dHB1dDogY2FsbHMgb3V0V3JpdGVyLnByaW50bG4ocykuCi0gICAqIEBwYXJhbSBzIFN0cmluZyB0byBwcmludAotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgbG9nTXNnKFN0cmluZyBzKQotICB7Ci0gICAgb3V0V3JpdGVyLnByaW50bG4ocyk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdC9Qcm9jZXNzLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHQvUHJvY2Vzcy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2N2FhNzA0Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdC9Qcm9jZXNzLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMjI2ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFByb2Nlc3MuamF2YSx2IDEuMi40LjIgMjAwNS8wOS8xNSAxODoyMTo1NyBqZWZmc3V0dG9yIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHQ7Ci0KLWltcG9ydCBqYXZhLmlvLkZpbGVPdXRwdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5pby5GaWxlV3JpdGVyOwotaW1wb3J0IGphdmEuaW8uUHJpbnRXcml0ZXI7Ci1pbXBvcnQgamF2YS5pby5TdHJpbmdSZWFkZXI7Ci1pbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7Ci1pbXBvcnQgamF2YS51dGlsLlJlc291cmNlQnVuZGxlOwotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLWltcG9ydCBqYXZheC54bWwuWE1MQ29uc3RhbnRzOwotaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlcjsKLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5OwotaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLlBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5PdXRwdXRLZXlzOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uU291cmNlOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVGVtcGxhdGVzOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXI7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRmFjdG9yeTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvcjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlVSSVJlc29sdmVyOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uZG9tLkRPTVJlc3VsdDsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLmRvbS5ET01Tb3VyY2U7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zYXguU0FYUmVzdWx0OwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlNBWFNvdXJjZTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnNheC5TQVhUcmFuc2Zvcm1lckZhY3Rvcnk7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zYXguVHJhbnNmb3JtZXJIYW5kbGVyOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc3RyZWFtLlN0cmVhbVJlc3VsdDsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbS5TdHJlYW1Tb3VyY2U7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwuVmVyc2lvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwucmVzLlhTTE1lc3NhZ2VzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC5yZXMuWFNMVEVycm9yUmVzb3VyY2VzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC51dGlscy5PYmplY3RGYWN0b3J5OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC51dGlscy5Db25maWd1cmF0aW9uRXJyb3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnV0aWxzLlNlY3VyaXR5U3VwcG9ydDsKLQotLy9KMlNFIGRvZXMgbm90IHN1cHBvcnQgWGFsYW4gaW50ZXJwcmV0aXZlCi0vKgotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC50cmFjZS5QcmludFRyYWNlTGlzdGVuZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnRyYWNlLlRyYWNlTWFuYWdlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwudHJhbnNmb3JtZXIuWGFsYW5Qcm9wZXJ0aWVzOwotKi8KLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuRGVmYXVsdEVycm9ySGFuZGxlcjsKLQotaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci0KLWltcG9ydCBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5FbnRpdHlSZXNvbHZlcjsKLWltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKLWltcG9ydCBvcmcueG1sLnNheC5YTUxSZWFkZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguaGVscGVycy5YTUxSZWFkZXJGYWN0b3J5OwotCi0vKioKLSAqIFRoZSBtYWluKCkgbWV0aG9kIGhhbmRsZXMgdGhlIFhhbGFuIGNvbW1hbmQtbGluZSBpbnRlcmZhY2UuCi0gKiBAeHNsLnVzYWdlIGdlbmVyYWwKLSAqLwotcHVibGljIGNsYXNzIFByb2Nlc3MKLXsKLSAgLyoqCi0gICAqIFByaW50cyBhcmd1bWVudCBvcHRpb25zLgotICAgKgotICAgKiBAcGFyYW0gcmVzYnVuZGxlIFJlc291cmNlIGJ1bmRsZQotICAgKi8KLSAgcHJvdGVjdGVkIHN0YXRpYyB2b2lkIHByaW50QXJnT3B0aW9ucyhSZXNvdXJjZUJ1bmRsZSByZXNidW5kbGUpCi0gIHsKLSAgICBTeXN0ZW0ub3V0LnByaW50bG4ocmVzYnVuZGxlLmdldFN0cmluZygieHNsUHJvY19vcHRpb24iKSk7ICAvLyJ4c2xwcm9jIG9wdGlvbnM6ICIpOwotICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXG5cdFx0XHQiICsgcmVzYnVuZGxlLmdldFN0cmluZygieHNsUHJvY19jb21tb25fb3B0aW9ucyIpICsgIlxuIik7Ci0gICAgU3lzdGVtLm91dC5wcmludGxuKHJlc2J1bmRsZS5nZXRTdHJpbmcoIm9wdGlvblhTTFRDIikpOyAgLy8iICAgIFstWFNMVEMgKHVzZSBYU0xUQyBmb3IgdHJhbnNmb3JtYXRpb24pXQotICAgIFN5c3RlbS5vdXQucHJpbnRsbihyZXNidW5kbGUuZ2V0U3RyaW5nKCJvcHRpb25JTiIpKTsgIC8vIiAgICBbLUlOIGlucHV0WE1MVVJMXSIpOwotICAgIFN5c3RlbS5vdXQucHJpbnRsbihyZXNidW5kbGUuZ2V0U3RyaW5nKCJvcHRpb25YU0wiKSk7ICAvLyIgICBbLVhTTCBYU0xUcmFuc2Zvcm1hdGlvblVSTF0iKTsKLSAgICBTeXN0ZW0ub3V0LnByaW50bG4ocmVzYnVuZGxlLmdldFN0cmluZygib3B0aW9uT1VUIikpOyAgLy8iICAgWy1PVVQgb3V0cHV0RmlsZU5hbWVdIik7Ci0KLSAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4ocmVzYnVuZGxlLmdldFN0cmluZygib3B0aW9uRSIpKTsgLy8iICAgWy1FIChEbyBub3QgZXhwYW5kIGVudGl0eSByZWZzKV0iKTsKLSAgICBTeXN0ZW0ub3V0LnByaW50bG4ocmVzYnVuZGxlLmdldFN0cmluZygib3B0aW9uViIpKTsgIC8vIiAgIFstViAoVmVyc2lvbiBpbmZvKV0iKTsKLQotICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbihyZXNidW5kbGUuZ2V0U3RyaW5nKCJvcHRpb25WQUxJREFURSIpKTsgLy8iICAgWy1WQUxJREFURSAoU2V0IHdoZXRoZXIgdmFsaWRhdGlvbiBvY2N1cnMuICBWYWxpZGF0aW9uIGlzIG9mZiBieSBkZWZhdWx0LildIik7Ci0gICAgU3lzdGVtLm91dC5wcmludGxuKHJlc2J1bmRsZS5nZXRTdHJpbmcoIm9wdGlvbkVEVU1QIikpOyAgLy8iICAgWy1FRFVNUCB7b3B0aW9uYWwgZmlsZW5hbWV9IChEbyBzdGFja2R1bXAgb24gZXJyb3IuKV0iKTsKLSAgICBTeXN0ZW0ub3V0LnByaW50bG4ocmVzYnVuZGxlLmdldFN0cmluZygib3B0aW9uWE1MIikpOyAgLy8iICAgWy1YTUwgKFVzZSBYTUwgZm9ybWF0dGVyIGFuZCBhZGQgWE1MIGhlYWRlci4pXSIpOwotICAgIFN5c3RlbS5vdXQucHJpbnRsbihyZXNidW5kbGUuZ2V0U3RyaW5nKCJvcHRpb25URVhUIikpOyAgLy8iICAgWy1URVhUIChVc2Ugc2ltcGxlIFRleHQgZm9ybWF0dGVyLildIik7Ci0gICAgU3lzdGVtLm91dC5wcmludGxuKHJlc2J1bmRsZS5nZXRTdHJpbmcoIm9wdGlvbkhUTUwiKSk7ICAvLyIgICBbLUhUTUwgKFVzZSBIVE1MIGZvcm1hdHRlci4pXSIpOwotICAgIFN5c3RlbS5vdXQucHJpbnRsbihyZXNidW5kbGUuZ2V0U3RyaW5nKCJvcHRpb25QQVJBTSIpKTsgIC8vIiAgIFstUEFSQU0gbmFtZSBleHByZXNzaW9uIChTZXQgYSBzdHlsZXNoZWV0IHBhcmFtZXRlcildIik7Ci0KLSAgICBTeXN0ZW0ub3V0LnByaW50bG4ocmVzYnVuZGxlLmdldFN0cmluZygib3B0aW9uTUVESUEiKSk7Ci0gICAgU3lzdGVtLm91dC5wcmludGxuKHJlc2J1bmRsZS5nZXRTdHJpbmcoIm9wdGlvbkZMQVZPUiIpKTsKLSAgICBTeXN0ZW0ub3V0LnByaW50bG4ocmVzYnVuZGxlLmdldFN0cmluZygib3B0aW9uRElBRyIpKTsKLSAgICBTeXN0ZW0ub3V0LnByaW50bG4ocmVzYnVuZGxlLmdldFN0cmluZygib3B0aW9uVVJJUkVTT0xWRVIiKSk7ICAvLyIgICBbLVVSSVJFU09MVkVSIGZ1bGwgY2xhc3MgbmFtZSAoVVJJUmVzb2x2ZXIgdG8gYmUgdXNlZCB0byByZXNvbHZlIFVSSXMpXSIpOwotICAgIFN5c3RlbS5vdXQucHJpbnRsbihyZXNidW5kbGUuZ2V0U3RyaW5nKCJvcHRpb25FTlRJVFlSRVNPTFZFUiIpKTsgIC8vIiAgIFstRU5USVRZUkVTT0xWRVIgZnVsbCBjbGFzcyBuYW1lIChFbnRpdHlSZXNvbHZlciB0byBiZSB1c2VkIHRvIHJlc29sdmUgZW50aXRpZXMpXSIpOwotICAgIHdhaXRGb3JSZXR1cm5LZXkocmVzYnVuZGxlKTsKLSAgICBTeXN0ZW0ub3V0LnByaW50bG4ocmVzYnVuZGxlLmdldFN0cmluZygib3B0aW9uQ09OVEVOVEhBTkRMRVIiKSk7ICAvLyIgICBbLUNPTlRFTlRIQU5ETEVSIGZ1bGwgY2xhc3MgbmFtZSAoQ29udGVudEhhbmRsZXIgdG8gYmUgdXNlZCB0byBzZXJpYWxpemUgb3V0cHV0KV0iKTsKLSAgICBTeXN0ZW0ub3V0LnByaW50bG4ocmVzYnVuZGxlLmdldFN0cmluZygib3B0aW9uU0VDVVJFUFJPQ0VTU0lORyIpKTsgLy8iICAgWy1TRUNVUkUgKHNldCB0aGUgc2VjdXJlIHByb2Nlc3NpbmcgZmVhdHVyZSB0byB0cnVlKV0iKTsKLQotICAgIC8vIEoyU0UgZG9lcyBub3Qgc3VwcG9ydCBYYWxhbiBpbnRlcnByZXRpdmUKLSAgICAvKgotICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXG5cdFx0XHQiICsgcmVzYnVuZGxlLmdldFN0cmluZygieHNsUHJvY194YWxhbl9vcHRpb25zIikgKyAiXG4iKTsKLQotICAgIFN5c3RlbS5vdXQucHJpbnRsbihyZXNidW5kbGUuZ2V0U3RyaW5nKCJvcHRpb25RQyIpKTsgIC8vIiAgIFstUUMgKFF1aWV0IFBhdHRlcm4gQ29uZmxpY3RzIFdhcm5pbmdzKV0iKTsKLQotICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbihyZXNidW5kbGUuZ2V0U3RyaW5nKCJvcHRpb25RIikpOyAgLy8iICAgWy1RICAoUXVpZXQgTW9kZSldIik7IC8vIHNjIDI4LUZlYi0wMSBjb21tZW50ZWQgb3V0Ci0gICAgU3lzdGVtLm91dC5wcmludGxuKHJlc2J1bmRsZS5nZXRTdHJpbmcoIm9wdGlvblRUIikpOyAgLy8iICAgWy1UVCAoVHJhY2UgdGhlIHRlbXBsYXRlcyBhcyB0aGV5IGFyZSBiZWluZyBjYWxsZWQuKV0iKTsKLSAgICBTeXN0ZW0ub3V0LnByaW50bG4ocmVzYnVuZGxlLmdldFN0cmluZygib3B0aW9uVEciKSk7ICAvLyIgICBbLVRHIChUcmFjZSBlYWNoIGdlbmVyYXRpb24gZXZlbnQuKV0iKTsKLSAgICBTeXN0ZW0ub3V0LnByaW50bG4ocmVzYnVuZGxlLmdldFN0cmluZygib3B0aW9uVFMiKSk7ICAvLyIgICBbLVRTIChUcmFjZSBlYWNoIHNlbGVjdGlvbiBldmVudC4pXSIpOwotICAgIFN5c3RlbS5vdXQucHJpbnRsbihyZXNidW5kbGUuZ2V0U3RyaW5nKCJvcHRpb25UVEMiKSk7ICAvLyIgICBbLVRUQyAoVHJhY2UgdGhlIHRlbXBsYXRlIGNoaWxkcmVuIGFzIHRoZXkgYXJlIGJlaW5nIHByb2Nlc3NlZC4pXSIpOwotICAgIFN5c3RlbS5vdXQucHJpbnRsbihyZXNidW5kbGUuZ2V0U3RyaW5nKCJvcHRpb25UQ0xBU1MiKSk7ICAvLyIgICBbLVRDTEFTUyAoVHJhY2VMaXN0ZW5lciBjbGFzcyBmb3IgdHJhY2UgZXh0ZW5zaW9ucy4pXSIpOwotICAgIFN5c3RlbS5vdXQucHJpbnRsbihyZXNidW5kbGUuZ2V0U3RyaW5nKCJvcHRpb25MSU5FTlVNQkVSUyIpKTsgLy8iICAgWy1MIHVzZSBsaW5lIG51bWJlcnNdIgotICAgIFN5c3RlbS5vdXQucHJpbnRsbihyZXNidW5kbGUuZ2V0U3RyaW5nKCJvcHRpb25JTkNSRU1FTlRBTCIpKTsKLSAgICBTeXN0ZW0ub3V0LnByaW50bG4ocmVzYnVuZGxlLmdldFN0cmluZygib3B0aW9uTk9PUFRJTUlNSVpFIikpOwotICAgIFN5c3RlbS5vdXQucHJpbnRsbihyZXNidW5kbGUuZ2V0U3RyaW5nKCJvcHRpb25STCIpKTsKLSAgICAqLwotCi0gICAgU3lzdGVtLm91dC5wcmludGxuKCJcblx0XHRcdCIgKyByZXNidW5kbGUuZ2V0U3RyaW5nKCJ4c2xQcm9jX3hzbHRjX29wdGlvbnMiKSArICJcbiIpOwotICAgIFN5c3RlbS5vdXQucHJpbnRsbihyZXNidW5kbGUuZ2V0U3RyaW5nKCJvcHRpb25YTyIpKTsKLSAgICB3YWl0Rm9yUmV0dXJuS2V5KHJlc2J1bmRsZSk7Ci0gICAgU3lzdGVtLm91dC5wcmludGxuKHJlc2J1bmRsZS5nZXRTdHJpbmcoIm9wdGlvblhEIikpOwotICAgIFN5c3RlbS5vdXQucHJpbnRsbihyZXNidW5kbGUuZ2V0U3RyaW5nKCJvcHRpb25YSiIpKTsKLSAgICBTeXN0ZW0ub3V0LnByaW50bG4ocmVzYnVuZGxlLmdldFN0cmluZygib3B0aW9uWFAiKSk7Ci0gICAgU3lzdGVtLm91dC5wcmludGxuKHJlc2J1bmRsZS5nZXRTdHJpbmcoIm9wdGlvblhOIikpOwotICAgIFN5c3RlbS5vdXQucHJpbnRsbihyZXNidW5kbGUuZ2V0U3RyaW5nKCJvcHRpb25YWCIpKTsKLSAgICBTeXN0ZW0ub3V0LnByaW50bG4ocmVzYnVuZGxlLmdldFN0cmluZygib3B0aW9uWFQiKSk7Ci0gIH0KLQotICAvKioKLSAgICogQ29tbWFuZCBsaW5lIGludGVyZmFjZSB0byB0cmFuc2Zvcm0gYW4gWE1MIGRvY3VtZW50IGFjY29yZGluZyB0bwotICAgKiB0aGUgaW5zdHJ1Y3Rpb25zIGZvdW5kIGluIGFuIFhTTCBzdHlsZXNoZWV0LgotICAgKiA8cD5UaGUgUHJvY2VzcyBjbGFzcyBwcm92aWRlcyBiYXNpYyBmdW5jdGlvbmFsaXR5IGZvcgotICAgKiBwZXJmb3JtaW5nIHRyYW5zZm9ybWF0aW9ucyBmcm9tIHRoZSBjb21tYW5kIGxpbmUuICBUbyBzZWUgYQotICAgKiBsaXN0IG9mIGFyZ3VtZW50cyBzdXBwb3J0ZWQsIGNhbGwgd2l0aCB6ZXJvIGFyZ3VtZW50cy48L3A+Ci0gICAqIDxwPlRvIHNldCBzdHlsZXNoZWV0IHBhcmFtZXRlcnMgZnJvbSB0aGUgY29tbWFuZCBsaW5lLCB1c2UKLSAgICogPGNvZGU+LVBBUkFNIG5hbWUgZXhwcmVzc2lvbjwvY29kZT4uIElmIHlvdSB3YW50IHRvIHNldCB0aGUKLSAgICogcGFyYW1ldGVyIHRvIGEgc3RyaW5nIHZhbHVlLCBzaW1wbHkgcGFzcyB0aGUgc3RyaW5nIHZhbHVlCi0gICAqIGFzLWlzLCBhbmQgaXQgd2lsbCBiZSBpbnRlcnByZXRlZCBhcyBhIHN0cmluZy4gIChOb3RlOiBpZgotICAgKiB0aGUgdmFsdWUgaGFzIHNwYWNlcyBpbiBpdCwgeW91IG1heSBuZWVkIHRvIHF1b3RlIGl0IGRlcGVuZGluZwotICAgKiBvbiB5b3VyIHNoZWxsIGVudmlyb25tZW50KS48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBhcmd2IElucHV0IHBhcmFtZXRlcnMgZnJvbSBjb21tYW5kIGxpbmUKLSAgICovCi0gIC8vIEoyU0UgZG9lcyBub3Qgc3VwcG9ydCBYYWxhbiBpbnRlcnByZXRpdmUKLSAgLy8gbWFpbiAtPiBfbWFpbgotICBwdWJsaWMgc3RhdGljIHZvaWQgX21haW4oU3RyaW5nIGFyZ3ZbXSkKLSAgewotCi0gICAgLy8gUnVudGltZS5nZXRSdW50aW1lKCkudHJhY2VNZXRob2RDYWxscyhmYWxzZSk7IC8vIHR1cm5zIEphdmEgdHJhY2luZyBvZmYKLSAgICBib29sZWFuIGRvU3RhY2tEdW1wT25FcnJvciA9IGZhbHNlOwotICAgIGJvb2xlYW4gc2V0UXVpZXRNb2RlID0gZmFsc2U7Ci0gICAgYm9vbGVhbiBkb0RpYWcgPSBmYWxzZTsKLSAgICBTdHJpbmcgbXNnID0gbnVsbDsKLSAgICBib29sZWFuIGlzU2VjdXJlUHJvY2Vzc2luZyA9IGZhbHNlOwotCi0gICAgLy8gUnVudGltZS5nZXRSdW50aW1lKCkudHJhY2VNZXRob2RDYWxscyhmYWxzZSk7Ci0gICAgLy8gUnVudGltZS5nZXRSdW50aW1lKCkudHJhY2VJbnN0cnVjdGlvbnMoZmFsc2UpOwotCi0gICAgLyoqCi0gICAgICogVGhlIGRlZmF1bHQgZGlhZ25vc3RpYyB3cml0ZXIuLi4KLSAgICAgKi8KLSAgICBqYXZhLmlvLlByaW50V3JpdGVyIGRpYWdub3N0aWNzV3JpdGVyID0gbmV3IFByaW50V3JpdGVyKFN5c3RlbS5lcnIsIHRydWUpOwotICAgIGphdmEuaW8uUHJpbnRXcml0ZXIgZHVtcFdyaXRlciA9IGRpYWdub3N0aWNzV3JpdGVyOwotICAgIFJlc291cmNlQnVuZGxlIHJlc2J1bmRsZSA9Ci0gICAgICAoU2VjdXJpdHlTdXBwb3J0LmdldFJlc291cmNlQnVuZGxlKAotICAgICAgICBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLnJlcy5YUmVzb3VyY2VCdW5kbGUuRVJST1JfUkVTT1VSQ0VTKSk7Ci0gICAgU3RyaW5nIGZsYXZvciA9ICJzMnMiOwotCi0gICAgaWYgKGFyZ3YubGVuZ3RoIDwgMSkKLSAgICB7Ci0gICAgICBwcmludEFyZ09wdGlvbnMocmVzYnVuZGxlKTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgICAgLy8gSjJTRSBkb2VzIG5vdCBzdXBwb3J0IFhhbGFuIGludGVycHJldGl2ZQotICAgICAgICAvLyBmYWxzZSAtPiB0cnVlCi0gICAgICAgIGJvb2xlYW4gdXNlWFNMVEMgPSB0cnVlOwotICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhcmd2Lmxlbmd0aDsgaSsrKQotICAgICAgewotICAgICAgICBpZiAoIi1YU0xUQyIuZXF1YWxzSWdub3JlQ2FzZShhcmd2W2ldKSkKLSAgICAgICAgewotICAgICAgICAgIHVzZVhTTFRDID0gdHJ1ZTsKLSAgICAgICAgfQotICAgICAgfQotCi0gICAgICBUcmFuc2Zvcm1lckZhY3RvcnkgdGZhY3Rvcnk7Ci0gICAgICBpZiAodXNlWFNMVEMpCi0gICAgICB7Ci0gICAgICAgICBTdHJpbmcga2V5ID0gImphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJGYWN0b3J5IjsKLSAgICAgICAgIFN0cmluZyB2YWx1ZSA9ICJjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMudHJheC5UcmFuc2Zvcm1lckZhY3RvcnlJbXBsIjsKLSAgICAgICAgIFByb3BlcnRpZXMgcHJvcHMgPSBTeXN0ZW0uZ2V0UHJvcGVydGllcygpOwotICAgICAgICAgcHJvcHMucHV0KGtleSwgdmFsdWUpOwotICAgICAgICAgU3lzdGVtLnNldFByb3BlcnRpZXMocHJvcHMpOwotICAgICAgfQotCi0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgdGZhY3RvcnkgPSBUcmFuc2Zvcm1lckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKLSAgICAgICAgdGZhY3Rvcnkuc2V0RXJyb3JMaXN0ZW5lcihuZXcgRGVmYXVsdEVycm9ySGFuZGxlcigpKTsKLSAgICAgIH0KLSAgICAgIGNhdGNoIChUcmFuc2Zvcm1lckZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IgcGZlKQotICAgICAgewotICAgICAgICBwZmUucHJpbnRTdGFja1RyYWNlKGR1bXBXcml0ZXIpOwotLy8gICAgICAiWFNMIFByb2Nlc3Mgd2FzIG5vdCBzdWNjZXNzZnVsLiIpOwotICAgICAgICBtc2cgPSBYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKAotICAgICAgICAgICAgWFNMVEVycm9yUmVzb3VyY2VzLkVSX05PVF9TVUNDRVNTRlVMLCBudWxsKTsKLSAgICAgICAgZGlhZ25vc3RpY3NXcml0ZXIucHJpbnRsbihtc2cpOwotCi0gICAgICAgIHRmYWN0b3J5ID0gbnVsbDsgIC8vIHNodXQgdXAgY29tcGlsZXIKLQotICAgICAgICBkb0V4aXQobXNnKTsKLSAgICAgIH0KLQotICAgICAgYm9vbGVhbiBmb3JtYXRPdXRwdXQgPSBmYWxzZTsKLSAgICAgIGJvb2xlYW4gdXNlU291cmNlTG9jYXRpb24gPSBmYWxzZTsKLSAgICAgIFN0cmluZyBpbkZpbGVOYW1lID0gbnVsbDsKLSAgICAgIFN0cmluZyBvdXRGaWxlTmFtZSA9IG51bGw7Ci0gICAgICBTdHJpbmcgZHVtcEZpbGVOYW1lID0gbnVsbDsKLSAgICAgIFN0cmluZyB4c2xGaWxlTmFtZSA9IG51bGw7Ci0gICAgICBTdHJpbmcgdHJlZWR1bXBGaWxlTmFtZSA9IG51bGw7Ci0gICAgICAvLyBKMlNFIGRvZXMgbm90IHN1cHBvcnQgWGFsYW4gaW50ZXJwcmV0aXZlCi0gICAgICAvKgotICAgICAgUHJpbnRUcmFjZUxpc3RlbmVyIHRyYWNlciA9IG51bGw7Ci0gICAgICAqLwotICAgICAgU3RyaW5nIG91dHB1dFR5cGUgPSBudWxsOwotICAgICAgU3RyaW5nIG1lZGlhID0gbnVsbDsKLSAgICAgIFZlY3RvciBwYXJhbXMgPSBuZXcgVmVjdG9yKCk7Ci0gICAgICBib29sZWFuIHF1aWV0Q29uZmxpY3RXYXJuaW5ncyA9IGZhbHNlOwotICAgICAgVVJJUmVzb2x2ZXIgdXJpUmVzb2x2ZXIgPSBudWxsOwotICAgICAgRW50aXR5UmVzb2x2ZXIgZW50aXR5UmVzb2x2ZXIgPSBudWxsOwotICAgICAgQ29udGVudEhhbmRsZXIgY29udGVudEhhbmRsZXIgPSBudWxsOwotICAgICAgaW50IHJlY3Vyc2lvbkxpbWl0PS0xOwotCi0gICAgICBmb3IgKGludCBpID0gMDsgaSA8IGFyZ3YubGVuZ3RoOyBpKyspCi0gICAgICB7Ci0gICAgICAgIGlmICgiLVhTTFRDIi5lcXVhbHNJZ25vcmVDYXNlKGFyZ3ZbaV0pKQotICAgICAgICB7Ci0gICAgICAgICAgLy8gVGhlIC1YU0xUQyBvcHRpb24gaGFzIGJlZW4gcHJvY2Vzc2VkLgotICAgICAgICB9Ci0gICAgICAgIC8vIEoyU0UgZG9lcyBub3Qgc3VwcG9ydCBYYWxhbiBpbnRlcnByZXRpdmUKLSAgICAgICAgLyoKLSAgICAgICAgZWxzZSBpZiAoIi1UVCIuZXF1YWxzSWdub3JlQ2FzZShhcmd2W2ldKSkKLSAgICAgICAgewotICAgICAgICAgIGlmICghdXNlWFNMVEMpCi0gICAgICAgICAgewotICAgICAgICAgICAgaWYgKG51bGwgPT0gdHJhY2VyKQotICAgICAgICAgICAgICB0cmFjZXIgPSBuZXcgUHJpbnRUcmFjZUxpc3RlbmVyKGRpYWdub3N0aWNzV3JpdGVyKTsKLQotICAgICAgICAgICAgdHJhY2VyLm1fdHJhY2VUZW1wbGF0ZXMgPSB0cnVlOwotICAgICAgICAgIH0KLSAgICAgICAgICBlbHNlCi0gICAgICAgICAgICBwcmludEludmFsaWRYU0xUQ09wdGlvbigiLVRUIik7Ci0KLSAgICAgICAgICAvLyB0ZmFjdG9yeS5zZXRUcmFjZVRlbXBsYXRlcyh0cnVlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICgiLVRHIi5lcXVhbHNJZ25vcmVDYXNlKGFyZ3ZbaV0pKQotICAgICAgICB7Ci0gICAgICAgICAgaWYgKCF1c2VYU0xUQykKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBpZiAobnVsbCA9PSB0cmFjZXIpCi0gICAgICAgICAgICAgIHRyYWNlciA9IG5ldyBQcmludFRyYWNlTGlzdGVuZXIoZGlhZ25vc3RpY3NXcml0ZXIpOwotCi0gICAgICAgICAgICB0cmFjZXIubV90cmFjZUdlbmVyYXRpb24gPSB0cnVlOwotICAgICAgICAgIH0KLSAgICAgICAgICBlbHNlCi0gICAgICAgICAgICBwcmludEludmFsaWRYU0xUQ09wdGlvbigiLVRHIik7Ci0KLSAgICAgICAgICAvLyB0ZmFjdG9yeS5zZXRUcmFjZVNlbGVjdCh0cnVlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICgiLVRTIi5lcXVhbHNJZ25vcmVDYXNlKGFyZ3ZbaV0pKQotICAgICAgICB7Ci0gICAgICAgICAgaWYgKCF1c2VYU0xUQykKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBpZiAobnVsbCA9PSB0cmFjZXIpCi0gICAgICAgICAgICAgIHRyYWNlciA9IG5ldyBQcmludFRyYWNlTGlzdGVuZXIoZGlhZ25vc3RpY3NXcml0ZXIpOwotCi0gICAgICAgICAgICB0cmFjZXIubV90cmFjZVNlbGVjdGlvbiA9IHRydWU7Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgIHByaW50SW52YWxpZFhTTFRDT3B0aW9uKCItVFMiKTsKLQotICAgICAgICAgIC8vIHRmYWN0b3J5LnNldFRyYWNlVGVtcGxhdGVzKHRydWUpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKCItVFRDIi5lcXVhbHNJZ25vcmVDYXNlKGFyZ3ZbaV0pKQotICAgICAgICB7Ci0gICAgICAgICAgaWYgKCF1c2VYU0xUQykKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBpZiAobnVsbCA9PSB0cmFjZXIpCi0gICAgICAgICAgICAgIHRyYWNlciA9IG5ldyBQcmludFRyYWNlTGlzdGVuZXIoZGlhZ25vc3RpY3NXcml0ZXIpOwotCi0gICAgICAgICAgICB0cmFjZXIubV90cmFjZUVsZW1lbnRzID0gdHJ1ZTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgICAgcHJpbnRJbnZhbGlkWFNMVENPcHRpb24oIi1UVEMiKTsKLQotICAgICAgICAgIC8vIHRmYWN0b3J5LnNldFRyYWNlVGVtcGxhdGVDaGlsZHJlbih0cnVlKTsKLSAgICAgICAgfQotICAgICAgICAqLwotICAgICAgICBlbHNlIGlmICgiLUlOREVOVCIuZXF1YWxzSWdub3JlQ2FzZShhcmd2W2ldKSkKLSAgICAgICAgewotICAgICAgICAgIGludCBpbmRlbnRBbW91bnQ7Ci0KLSAgICAgICAgICBpZiAoKChpICsgMSkgPCBhcmd2Lmxlbmd0aCkgJiYgKGFyZ3ZbaSArIDFdLmNoYXJBdCgwKSAhPSAnLScpKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGluZGVudEFtb3VudCA9IEludGVnZXIucGFyc2VJbnQoYXJndlsrK2ldKTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGluZGVudEFtb3VudCA9IDA7Ci0gICAgICAgICAgfQotCi0gICAgICAgICAgLy8gVEJEOgotICAgICAgICAgIC8vIHhtbFByb2Nlc3NvckxpYWlzb24uc2V0SW5kZW50KGluZGVudEFtb3VudCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoIi1JTiIuZXF1YWxzSWdub3JlQ2FzZShhcmd2W2ldKSkKLSAgICAgICAgewotICAgICAgICAgIGlmIChpICsgMSA8IGFyZ3YubGVuZ3RoICYmIGFyZ3ZbaSArIDFdLmNoYXJBdCgwKSAhPSAnLScpCi0gICAgICAgICAgICBpbkZpbGVOYW1lID0gYXJndlsrK2ldOwotICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigKLSAgICAgICAgICAgICAgWFNMTWVzc2FnZXMuY3JlYXRlTWVzc2FnZSgKLSAgICAgICAgICAgICAgICBYU0xURXJyb3JSZXNvdXJjZXMuRVJfTUlTU0lOR19BUkdfRk9SX09QVElPTiwKLSAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117ICItSU4iIH0pKTsgIC8vIk1pc3NpbmcgYXJndW1lbnQgZm9yKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICgiLU1FRElBIi5lcXVhbHNJZ25vcmVDYXNlKGFyZ3ZbaV0pKQotICAgICAgICB7Ci0gICAgICAgICAgaWYgKGkgKyAxIDwgYXJndi5sZW5ndGgpCi0gICAgICAgICAgICBtZWRpYSA9IGFyZ3ZbKytpXTsKLSAgICAgICAgICBlbHNlCi0gICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oCi0gICAgICAgICAgICAgIFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoCi0gICAgICAgICAgICAgICAgWFNMVEVycm9yUmVzb3VyY2VzLkVSX01JU1NJTkdfQVJHX0ZPUl9PUFRJT04sCi0gICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdeyAiLU1FRElBIiB9KSk7ICAvLyJNaXNzaW5nIGFyZ3VtZW50IGZvcik7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoIi1PVVQiLmVxdWFsc0lnbm9yZUNhc2UoYXJndltpXSkpCi0gICAgICAgIHsKLSAgICAgICAgICBpZiAoaSArIDEgPCBhcmd2Lmxlbmd0aCAmJiBhcmd2W2kgKyAxXS5jaGFyQXQoMCkgIT0gJy0nKQotICAgICAgICAgICAgb3V0RmlsZU5hbWUgPSBhcmd2WysraV07Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKAotICAgICAgICAgICAgICBYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKAotICAgICAgICAgICAgICAgIFhTTFRFcnJvclJlc291cmNlcy5FUl9NSVNTSU5HX0FSR19GT1JfT1BUSU9OLAotICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXsgIi1PVVQiIH0pKTsgIC8vIk1pc3NpbmcgYXJndW1lbnQgZm9yKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICgiLVhTTCIuZXF1YWxzSWdub3JlQ2FzZShhcmd2W2ldKSkKLSAgICAgICAgewotICAgICAgICAgIGlmIChpICsgMSA8IGFyZ3YubGVuZ3RoICYmIGFyZ3ZbaSArIDFdLmNoYXJBdCgwKSAhPSAnLScpCi0gICAgICAgICAgICB4c2xGaWxlTmFtZSA9IGFyZ3ZbKytpXTsKLSAgICAgICAgICBlbHNlCi0gICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oCi0gICAgICAgICAgICAgIFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoCi0gICAgICAgICAgICAgICAgWFNMVEVycm9yUmVzb3VyY2VzLkVSX01JU1NJTkdfQVJHX0ZPUl9PUFRJT04sCi0gICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdeyAiLVhTTCIgfSkpOyAgLy8iTWlzc2luZyBhcmd1bWVudCBmb3IpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKCItRkxBVk9SIi5lcXVhbHNJZ25vcmVDYXNlKGFyZ3ZbaV0pKQotICAgICAgICB7Ci0gICAgICAgICAgaWYgKGkgKyAxIDwgYXJndi5sZW5ndGgpCi0gICAgICAgICAgewotICAgICAgICAgICAgZmxhdm9yID0gYXJndlsrK2ldOwotICAgICAgICAgIH0KLSAgICAgICAgICBlbHNlCi0gICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oCi0gICAgICAgICAgICAgIFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoCi0gICAgICAgICAgICAgICAgWFNMVEVycm9yUmVzb3VyY2VzLkVSX01JU1NJTkdfQVJHX0ZPUl9PUFRJT04sCi0gICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdeyAiLUZMQVZPUiIgfSkpOyAgLy8iTWlzc2luZyBhcmd1bWVudCBmb3IpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKCItUEFSQU0iLmVxdWFsc0lnbm9yZUNhc2UoYXJndltpXSkpCi0gICAgICAgIHsKLSAgICAgICAgICBpZiAoaSArIDIgPCBhcmd2Lmxlbmd0aCkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBTdHJpbmcgbmFtZSA9IGFyZ3ZbKytpXTsKLQotICAgICAgICAgICAgcGFyYW1zLmFkZEVsZW1lbnQobmFtZSk7Ci0KLSAgICAgICAgICAgIFN0cmluZyBleHByZXNzaW9uID0gYXJndlsrK2ldOwotCi0gICAgICAgICAgICBwYXJhbXMuYWRkRWxlbWVudChleHByZXNzaW9uKTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKAotICAgICAgICAgICAgICBYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKAotICAgICAgICAgICAgICAgIFhTTFRFcnJvclJlc291cmNlcy5FUl9NSVNTSU5HX0FSR19GT1JfT1BUSU9OLAotICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXsgIi1QQVJBTSIgfSkpOyAgLy8iTWlzc2luZyBhcmd1bWVudCBmb3IpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKCItRSIuZXF1YWxzSWdub3JlQ2FzZShhcmd2W2ldKSkKLSAgICAgICAgewotCi0gICAgICAgICAgLy8gVEJEOgotICAgICAgICAgIC8vIHhtbFByb2Nlc3NvckxpYWlzb24uc2V0U2hvdWxkRXhwYW5kRW50aXR5UmVmcyhmYWxzZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoIi1WIi5lcXVhbHNJZ25vcmVDYXNlKGFyZ3ZbaV0pKQotICAgICAgICB7Ci0gICAgICAgICAgZGlhZ25vc3RpY3NXcml0ZXIucHJpbnRsbihyZXNidW5kbGUuZ2V0U3RyaW5nKCJ2ZXJzaW9uIikgIC8vIj4+Pj4+Pj4gWGFsYW4gVmVyc2lvbiAiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIFZlcnNpb24uZ2V0VmVyc2lvbigpICsgIiwgIiArCi0KLSAgICAgICAgICAvKiB4bWxQcm9jZXNzb3JMaWFpc29uLmdldFBhcnNlckRlc2NyaXB0aW9uKCkrICovCi0gICAgICAgICAgcmVzYnVuZGxlLmdldFN0cmluZygidmVyc2lvbjIiKSk7ICAvLyAiPDw8PDw8PCIpOwotICAgICAgICB9Ci0gICAgICAgIC8vIEoyU0UgZG9lcyBub3Qgc3VwcG9ydCBYYWxhbiBpbnRlcnByZXRpdmUKLSAgICAgICAgLyoKLSAgICAgICAgZWxzZSBpZiAoIi1RQyIuZXF1YWxzSWdub3JlQ2FzZShhcmd2W2ldKSkKLSAgICAgICAgewotICAgICAgICAgIGlmICghdXNlWFNMVEMpCi0gICAgICAgICAgICBxdWlldENvbmZsaWN0V2FybmluZ3MgPSB0cnVlOwotICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgIHByaW50SW52YWxpZFhTTFRDT3B0aW9uKCItUUMiKTsKLSAgICAgICAgfQotICAgICAgICAqLwotICAgICAgICBlbHNlIGlmICgiLVEiLmVxdWFsc0lnbm9yZUNhc2UoYXJndltpXSkpCi0gICAgICAgIHsKLSAgICAgICAgICBzZXRRdWlldE1vZGUgPSB0cnVlOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKCItRElBRyIuZXF1YWxzSWdub3JlQ2FzZShhcmd2W2ldKSkKLSAgICAgICAgewotICAgICAgICAgIGRvRGlhZyA9IHRydWU7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoIi1YTUwiLmVxdWFsc0lnbm9yZUNhc2UoYXJndltpXSkpCi0gICAgICAgIHsKLSAgICAgICAgICBvdXRwdXRUeXBlID0gInhtbCI7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoIi1URVhUIi5lcXVhbHNJZ25vcmVDYXNlKGFyZ3ZbaV0pKQotICAgICAgICB7Ci0gICAgICAgICAgb3V0cHV0VHlwZSA9ICJ0ZXh0IjsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICgiLUhUTUwiLmVxdWFsc0lnbm9yZUNhc2UoYXJndltpXSkpCi0gICAgICAgIHsKLSAgICAgICAgICBvdXRwdXRUeXBlID0gImh0bWwiOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKCItRURVTVAiLmVxdWFsc0lnbm9yZUNhc2UoYXJndltpXSkpCi0gICAgICAgIHsKLSAgICAgICAgICBkb1N0YWNrRHVtcE9uRXJyb3IgPSB0cnVlOwotCi0gICAgICAgICAgaWYgKCgoaSArIDEpIDwgYXJndi5sZW5ndGgpICYmIChhcmd2W2kgKyAxXS5jaGFyQXQoMCkgIT0gJy0nKSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBkdW1wRmlsZU5hbWUgPSBhcmd2WysraV07Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKCItVVJJUkVTT0xWRVIiLmVxdWFsc0lnbm9yZUNhc2UoYXJndltpXSkpCi0gICAgICAgIHsKLSAgICAgICAgICBpZiAoaSArIDEgPCBhcmd2Lmxlbmd0aCkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICB0cnkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgdXJpUmVzb2x2ZXIgPSAoVVJJUmVzb2x2ZXIpIE9iamVjdEZhY3RvcnkubmV3SW5zdGFuY2UoYXJndlsrK2ldLCB0cnVlKTsKLQotICAgICAgICAgICAgICB0ZmFjdG9yeS5zZXRVUklSZXNvbHZlcih1cmlSZXNvbHZlcik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXRjaCAoQ29uZmlndXJhdGlvbkVycm9yIGNuZmUpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgbXNnID0gWFNMTWVzc2FnZXMuY3JlYXRlTWVzc2FnZSgKLSAgICAgICAgICAgICAgICAgICAgWFNMVEVycm9yUmVzb3VyY2VzLkVSX0NMQVNTX05PVF9GT1VORF9GT1JfT1BUSU9OLAotICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117ICItVVJJUmVzb2x2ZXIiIH0pOwotICAgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4obXNnKTsKLSAgICAgICAgICAgICAgZG9FeGl0KG1zZyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBtc2cgPSBYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKAotICAgICAgICAgICAgICAgICAgICBYU0xURXJyb3JSZXNvdXJjZXMuRVJfTUlTU0lOR19BUkdfRk9SX09QVElPTiwKLSAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdeyAiLVVSSVJlc29sdmVyIiB9KTsgIC8vIk1pc3NpbmcgYXJndW1lbnQgZm9yKTsKLSAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbihtc2cpOwotICAgICAgICAgICAgZG9FeGl0KG1zZyk7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKCItRU5USVRZUkVTT0xWRVIiLmVxdWFsc0lnbm9yZUNhc2UoYXJndltpXSkpCi0gICAgICAgIHsKLSAgICAgICAgICBpZiAoaSArIDEgPCBhcmd2Lmxlbmd0aCkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICB0cnkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgZW50aXR5UmVzb2x2ZXIgPSAoRW50aXR5UmVzb2x2ZXIpIE9iamVjdEZhY3RvcnkubmV3SW5zdGFuY2UoYXJndlsrK2ldLCB0cnVlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhdGNoIChDb25maWd1cmF0aW9uRXJyb3IgY25mZSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBtc2cgPSBYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKAotICAgICAgICAgICAgICAgICAgICBYU0xURXJyb3JSZXNvdXJjZXMuRVJfQ0xBU1NfTk9UX0ZPVU5EX0ZPUl9PUFRJT04sCi0gICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXsgIi1FbnRpdHlSZXNvbHZlciIgfSk7Ci0gICAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbihtc2cpOwotICAgICAgICAgICAgICBkb0V4aXQobXNnKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICB9Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgIHsKLS8vICAgICAgICAgICAgIk1pc3NpbmcgYXJndW1lbnQgZm9yKTsKLSAgICAgICAgICAgICAgbXNnID0gWFNMTWVzc2FnZXMuY3JlYXRlTWVzc2FnZSgKLSAgICAgICAgICAgICAgICAgICAgWFNMVEVycm9yUmVzb3VyY2VzLkVSX01JU1NJTkdfQVJHX0ZPUl9PUFRJT04sCi0gICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXsgIi1FbnRpdHlSZXNvbHZlciIgfSk7Ci0gICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4obXNnKTsKLSAgICAgICAgICAgIGRvRXhpdChtc2cpOwotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICgiLUNPTlRFTlRIQU5ETEVSIi5lcXVhbHNJZ25vcmVDYXNlKGFyZ3ZbaV0pKQotICAgICAgICB7Ci0gICAgICAgICAgaWYgKGkgKyAxIDwgYXJndi5sZW5ndGgpCi0gICAgICAgICAgewotICAgICAgICAgICAgdHJ5Ci0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIGNvbnRlbnRIYW5kbGVyID0gKENvbnRlbnRIYW5kbGVyKSBPYmplY3RGYWN0b3J5Lm5ld0luc3RhbmNlKGFyZ3ZbKytpXSwgdHJ1ZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXRjaCAoQ29uZmlndXJhdGlvbkVycm9yIGNuZmUpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgbXNnID0gWFNMTWVzc2FnZXMuY3JlYXRlTWVzc2FnZSgKLSAgICAgICAgICAgICAgICAgICAgWFNMVEVycm9yUmVzb3VyY2VzLkVSX0NMQVNTX05PVF9GT1VORF9GT1JfT1BUSU9OLAotICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117ICItQ29udGVudEhhbmRsZXIiIH0pOwotICAgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4obXNnKTsKLSAgICAgICAgICAgICAgZG9FeGl0KG1zZyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UKLSAgICAgICAgICB7Ci0vLyAgICAgICAgICAgICJNaXNzaW5nIGFyZ3VtZW50IGZvcik7Ci0gICAgICAgICAgICAgIG1zZyA9IFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoCi0gICAgICAgICAgICAgICAgICAgIFhTTFRFcnJvclJlc291cmNlcy5FUl9NSVNTSU5HX0FSR19GT1JfT1BUSU9OLAotICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117ICItQ29udGVudEhhbmRsZXIiIH0pOwotICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKG1zZyk7Ci0gICAgICAgICAgICBkb0V4aXQobXNnKTsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgLy8gSjJTRSBkb2VzIG5vdCBzdXBwb3J0IFhhbGFuIGludGVycHJldGl2ZQotICAgICAgICAvKgotICAgICAgICBlbHNlIGlmICgiLUwiLmVxdWFsc0lnbm9yZUNhc2UoYXJndltpXSkpCi0gICAgICAgIHsKLSAgICAgICAgICBpZiAoIXVzZVhTTFRDKQotICAgICAgICAgICAgdGZhY3Rvcnkuc2V0QXR0cmlidXRlKFhhbGFuUHJvcGVydGllcy5TT1VSQ0VfTE9DQVRJT04sIEJvb2xlYW4uVFJVRSk7Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgICAgcHJpbnRJbnZhbGlkWFNMVENPcHRpb24oIi1MIik7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoIi1JTkNSRU1FTlRBTCIuZXF1YWxzSWdub3JlQ2FzZShhcmd2W2ldKSkKLSAgICAgICAgewotICAgICAgICAgIGlmICghdXNlWFNMVEMpCi0gICAgICAgICAgICB0ZmFjdG9yeS5zZXRBdHRyaWJ1dGUKLSAgICAgICAgICAgICAgKCJodHRwOi8veG1sLmFwYWNoZS5vcmcveGFsYW4vZmVhdHVyZXMvaW5jcmVtZW50YWwiLAotICAgICAgICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4uVFJVRSk7Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgICAgcHJpbnRJbnZhbGlkWFNMVENPcHRpb24oIi1JTkNSRU1FTlRBTCIpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKCItTk9PUFRJTUlaRSIuZXF1YWxzSWdub3JlQ2FzZShhcmd2W2ldKSkKLSAgICAgICAgewotICAgICAgICAgIC8vIERlZmF1bHQgaXMgdHJ1ZS4KLSAgICAgICAgICAvLwotICAgICAgICAgIC8vICVSRVZJRVclIFdlIHNob3VsZCBoYXZlIGEgZ2VuZXJhbGl6ZWQgc3ludGF4IGZvciBuZWdhdGl2ZQotICAgICAgICAgIC8vIHN3aXRjaGVzLi4uICBhbmQgcHJvYmFibHkgc2hvdWxkIGFjY2VwdCB0aGUgaW52ZXJzZSBldmVuCi0gICAgICAgICAgLy8gaWYgaXQgaXMgdGhlIGRlZmF1bHQuCi0gICAgICAgICAgaWYgKCF1c2VYU0xUQykKLSAgICAgICAgICAgIHRmYWN0b3J5LnNldEF0dHJpYnV0ZQotICAgICAgICAgICAgICAoImh0dHA6Ly94bWwuYXBhY2hlLm9yZy94YWxhbi9mZWF0dXJlcy9vcHRpbWl6ZSIsCi0gICAgICAgICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbi5GQUxTRSk7Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgICAgcHJpbnRJbnZhbGlkWFNMVENPcHRpb24oIi1OT09QVElNSVpFIik7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoIi1STCIuZXF1YWxzSWdub3JlQ2FzZShhcmd2W2ldKSkKLSAgICAgICAgewotICAgICAgICAgIGlmICghdXNlWFNMVEMpCi0gICAgICAgICAgewotICAgICAgICAgICAgaWYgKGkgKyAxIDwgYXJndi5sZW5ndGgpCi0gICAgICAgICAgICAgIHJlY3Vyc2lvbkxpbWl0ID0gSW50ZWdlci5wYXJzZUludChhcmd2WysraV0pOwotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oCi0gICAgICAgICAgICAgICAgWFNMTWVzc2FnZXMuY3JlYXRlTWVzc2FnZSgKLSAgICAgICAgICAgICAgICAgIFhTTFRFcnJvclJlc291cmNlcy5FUl9NSVNTSU5HX0FSR19GT1JfT1BUSU9OLAotICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdeyAiLXJsIiB9KSk7ICAvLyJNaXNzaW5nIGFyZ3VtZW50IGZvcik7Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBpZiAoaSArIDEgPCBhcmd2Lmxlbmd0aCAmJiBhcmd2W2kgKyAxXS5jaGFyQXQoMCkgIT0gJy0nKQotICAgICAgICAgICAgIGkrKzsKLQotICAgICAgICAgICAgcHJpbnRJbnZhbGlkWFNMVENPcHRpb24oIi1STCIpOwotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICAqLwotICAgICAgICAvLyBHZW5lcmF0ZSB0aGUgdHJhbnNsZXQgY2xhc3MgYW5kIG9wdGlvbmFsbHkgc3BlY2lmeSB0aGUgbmFtZQotICAgICAgICAvLyBvZiB0aGUgdHJhbnNsZXQgY2xhc3MuCi0gICAgICAgIGVsc2UgaWYgKCItWE8iLmVxdWFsc0lnbm9yZUNhc2UoYXJndltpXSkpCi0gICAgICAgIHsKLSAgICAgICAgICBpZiAodXNlWFNMVEMpCi0gICAgICAgICAgewotICAgICAgICAgICAgaWYgKGkgKyAxIDwgYXJndi5sZW5ndGggJiYgYXJndltpKzFdLmNoYXJBdCgwKSAhPSAnLScpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIHRmYWN0b3J5LnNldEF0dHJpYnV0ZSgiZ2VuZXJhdGUtdHJhbnNsZXQiLCAidHJ1ZSIpOwotICAgICAgICAgICAgICB0ZmFjdG9yeS5zZXRBdHRyaWJ1dGUoInRyYW5zbGV0LW5hbWUiLCBhcmd2WysraV0pOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICB0ZmFjdG9yeS5zZXRBdHRyaWJ1dGUoImdlbmVyYXRlLXRyYW5zbGV0IiwgInRydWUiKTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGlmIChpICsgMSA8IGFyZ3YubGVuZ3RoICYmIGFyZ3ZbaSArIDFdLmNoYXJBdCgwKSAhPSAnLScpCi0gICAgICAgICAgICAgaSsrOwotICAgICAgICAgICAgcHJpbnRJbnZhbGlkWGFsYW5PcHRpb24oIi1YTyIpOwotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICAvLyBTcGVjaWZ5IHRoZSBkZXN0aW5hdGlvbiBkaXJlY3RvcnkgZm9yIHRoZSB0cmFuc2xldCBjbGFzc2VzLgotICAgICAgICBlbHNlIGlmICgiLVhEIi5lcXVhbHNJZ25vcmVDYXNlKGFyZ3ZbaV0pKQotICAgICAgICB7Ci0gICAgICAgICAgaWYgKHVzZVhTTFRDKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGlmIChpICsgMSA8IGFyZ3YubGVuZ3RoICYmIGFyZ3ZbaSsxXS5jaGFyQXQoMCkgIT0gJy0nKQotICAgICAgICAgICAgICB0ZmFjdG9yeS5zZXRBdHRyaWJ1dGUoImRlc3RpbmF0aW9uLWRpcmVjdG9yeSIsIGFyZ3ZbKytpXSk7Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigKLSAgICAgICAgICAgICAgICBYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKAotICAgICAgICAgICAgICAgICAgWFNMVEVycm9yUmVzb3VyY2VzLkVSX01JU1NJTkdfQVJHX0ZPUl9PUFRJT04sCi0gICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117ICItWEQiIH0pKTsgIC8vIk1pc3NpbmcgYXJndW1lbnQgZm9yKTsKLQotICAgICAgICAgIH0KLSAgICAgICAgICBlbHNlCi0gICAgICAgICAgewotICAgICAgICAgICAgaWYgKGkgKyAxIDwgYXJndi5sZW5ndGggJiYgYXJndltpICsgMV0uY2hhckF0KDApICE9ICctJykKLSAgICAgICAgICAgICBpKys7Ci0KLSAgICAgICAgICAgIHByaW50SW52YWxpZFhhbGFuT3B0aW9uKCItWEQiKTsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgLy8gU3BlY2lmeSB0aGUgamFyIGZpbGUgbmFtZSB3aGljaCB0aGUgdHJhbnNsZXQgY2xhc3NlcyBhcmUgcGFja2FnZWQgaW50by4KLSAgICAgICAgZWxzZSBpZiAoIi1YSiIuZXF1YWxzSWdub3JlQ2FzZShhcmd2W2ldKSkKLSAgICAgICAgewotICAgICAgICAgIGlmICh1c2VYU0xUQykKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBpZiAoaSArIDEgPCBhcmd2Lmxlbmd0aCAmJiBhcmd2W2krMV0uY2hhckF0KDApICE9ICctJykKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgdGZhY3Rvcnkuc2V0QXR0cmlidXRlKCJnZW5lcmF0ZS10cmFuc2xldCIsICJ0cnVlIik7Ci0gICAgICAgICAgICAgIHRmYWN0b3J5LnNldEF0dHJpYnV0ZSgiamFyLW5hbWUiLCBhcmd2WysraV0pOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oCi0gICAgICAgICAgICAgICAgWFNMTWVzc2FnZXMuY3JlYXRlTWVzc2FnZSgKLSAgICAgICAgICAgICAgICAgIFhTTFRFcnJvclJlc291cmNlcy5FUl9NSVNTSU5HX0FSR19GT1JfT1BUSU9OLAotICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdeyAiLVhKIiB9KSk7ICAvLyJNaXNzaW5nIGFyZ3VtZW50IGZvcik7Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBpZiAoaSArIDEgPCBhcmd2Lmxlbmd0aCAmJiBhcmd2W2kgKyAxXS5jaGFyQXQoMCkgIT0gJy0nKQotICAgICAgICAgICAgIGkrKzsKLQotICAgICAgICAgICAgcHJpbnRJbnZhbGlkWGFsYW5PcHRpb24oIi1YSiIpOwotICAgICAgICAgIH0KLQotICAgICAgICB9Ci0gICAgICAgIC8vIFNwZWNpZnkgdGhlIHBhY2thZ2UgbmFtZSBwcmVmaXggZm9yIHRoZSBnZW5lcmF0ZWQgdHJhbnNsZXQgY2xhc3Nlcy4KLSAgICAgICAgZWxzZSBpZiAoIi1YUCIuZXF1YWxzSWdub3JlQ2FzZShhcmd2W2ldKSkKLSAgICAgICAgewotICAgICAgICAgIGlmICh1c2VYU0xUQykKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBpZiAoaSArIDEgPCBhcmd2Lmxlbmd0aCAmJiBhcmd2W2krMV0uY2hhckF0KDApICE9ICctJykKLSAgICAgICAgICAgICAgdGZhY3Rvcnkuc2V0QXR0cmlidXRlKCJwYWNrYWdlLW5hbWUiLCBhcmd2WysraV0pOwotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oCi0gICAgICAgICAgICAgICAgWFNMTWVzc2FnZXMuY3JlYXRlTWVzc2FnZSgKLSAgICAgICAgICAgICAgICAgIFhTTFRFcnJvclJlc291cmNlcy5FUl9NSVNTSU5HX0FSR19GT1JfT1BUSU9OLAotICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdeyAiLVhQIiB9KSk7ICAvLyJNaXNzaW5nIGFyZ3VtZW50IGZvcik7Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBpZiAoaSArIDEgPCBhcmd2Lmxlbmd0aCAmJiBhcmd2W2kgKyAxXS5jaGFyQXQoMCkgIT0gJy0nKQotICAgICAgICAgICAgIGkrKzsKLQotICAgICAgICAgICAgcHJpbnRJbnZhbGlkWGFsYW5PcHRpb24oIi1YUCIpOwotICAgICAgICAgIH0KLQotICAgICAgICB9Ci0gICAgICAgIC8vIEVuYWJsZSB0ZW1wbGF0ZSBpbmxpbmluZy4KLSAgICAgICAgZWxzZSBpZiAoIi1YTiIuZXF1YWxzSWdub3JlQ2FzZShhcmd2W2ldKSkKLSAgICAgICAgewotICAgICAgICAgIGlmICh1c2VYU0xUQykKLSAgICAgICAgICB7Ci0gICAgICAgICAgICB0ZmFjdG9yeS5zZXRBdHRyaWJ1dGUoImVuYWJsZS1pbmxpbmluZyIsICJ0cnVlIik7Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgIHByaW50SW52YWxpZFhhbGFuT3B0aW9uKCItWE4iKTsKLSAgICAgICAgfQotICAgICAgICAvLyBUdXJucyBvbiBhZGRpdGlvbmFsIGRlYnVnZ2luZyBtZXNzYWdlIG91dHB1dAotICAgICAgICBlbHNlIGlmICgiLVhYIi5lcXVhbHNJZ25vcmVDYXNlKGFyZ3ZbaV0pKQotICAgICAgICB7Ci0gICAgICAgICAgaWYgKHVzZVhTTFRDKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIHRmYWN0b3J5LnNldEF0dHJpYnV0ZSgiZGVidWciLCAidHJ1ZSIpOwotICAgICAgICAgIH0KLSAgICAgICAgICBlbHNlCi0gICAgICAgICAgICBwcmludEludmFsaWRYYWxhbk9wdGlvbigiLVhYIik7Ci0gICAgICAgIH0KLSAgICAgICAgLy8gQ3JlYXRlIHRoZSBUcmFuc2Zvcm1lciBmcm9tIHRoZSB0cmFuc2xldCBpZiB0aGUgdHJhbnNsZXQgY2xhc3MgaXMgbmV3ZXIKLSAgICAgICAgLy8gdGhhbiB0aGUgc3R5bGVzaGVldC4KLSAgICAgICAgZWxzZSBpZiAoIi1YVCIuZXF1YWxzSWdub3JlQ2FzZShhcmd2W2ldKSkKLSAgICAgICAgewotICAgICAgICAgIGlmICh1c2VYU0xUQykKLSAgICAgICAgICB7Ci0gICAgICAgICAgICB0ZmFjdG9yeS5zZXRBdHRyaWJ1dGUoImF1dG8tdHJhbnNsZXQiLCAidHJ1ZSIpOwotICAgICAgICAgIH0KLSAgICAgICAgICBlbHNlCi0gICAgICAgICAgICBwcmludEludmFsaWRYYWxhbk9wdGlvbigiLVhUIik7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoIi1TRUNVUkUiLmVxdWFsc0lnbm9yZUNhc2UoYXJndltpXSkpCi0gICAgICAgIHsKLSAgICAgICAgICBpc1NlY3VyZVByb2Nlc3NpbmcgPSB0cnVlOwotICAgICAgICAgIHRyeQotICAgICAgICAgIHsKLSAgICAgICAgICAgIHRmYWN0b3J5LnNldEZlYXR1cmUoWE1MQ29uc3RhbnRzLkZFQVRVUkVfU0VDVVJFX1BST0NFU1NJTkcsIHRydWUpOwotICAgICAgICAgIH0KLSAgICAgICAgICBjYXRjaCAoVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIGUpIHt9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigKLSAgICAgICAgICAgIFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoCi0gICAgICAgICAgICAgIFhTTFRFcnJvclJlc291cmNlcy5FUl9JTlZBTElEX09QVElPTiwgbmV3IE9iamVjdFtdeyBhcmd2W2ldIH0pKTsgIC8vIkludmFsaWQgYXJndW1lbnQ6KTsKLSAgICAgIH0KLQotICAgICAgLy8gUHJpbnQgdXNhZ2UgaW5zdHJ1Y3Rpb25zIGlmIG5vIHhtbCBhbmQgeHNsIGZpbGUgaXMgc3BlY2lmaWVkIGluIHRoZSBjb21tYW5kIGxpbmUKLSAgICAgIGlmIChpbkZpbGVOYW1lID09IG51bGwgJiYgeHNsRmlsZU5hbWUgPT0gbnVsbCkKLSAgICAgIHsKLSAgICAgICAgICBtc2cgPSByZXNidW5kbGUuZ2V0U3RyaW5nKCJ4c2xQcm9jX25vX2lucHV0Iik7Ci0gICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbihtc2cpOwotICAgICAgICBkb0V4aXQobXNnKTsKLSAgICAgIH0KLQotICAgICAgLy8gTm90ZSB0aGF0IHRoZXJlIGFyZSB1c2FnZSBjYXNlcyBmb3IgY2FsbGluZyB1cyB3aXRob3V0IGEgLUlOIGFyZwotICAgICAgLy8gVGhlIG1haW4gWFNMIHRyYW5zZm9ybWF0aW9uIG9jY3VycyBoZXJlIQotICAgICAgdHJ5Ci0gICAgICB7Ci0gICAgICAgIGxvbmcgc3RhcnQgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKLQotICAgICAgICBpZiAobnVsbCAhPSBkdW1wRmlsZU5hbWUpCi0gICAgICAgIHsKLSAgICAgICAgICBkdW1wV3JpdGVyID0gbmV3IFByaW50V3JpdGVyKG5ldyBGaWxlV3JpdGVyKGR1bXBGaWxlTmFtZSkpOwotICAgICAgICB9Ci0KLSAgICAgICAgVGVtcGxhdGVzIHN0eWxlc2hlZXQgPSBudWxsOwotCi0gICAgICAgIGlmIChudWxsICE9IHhzbEZpbGVOYW1lKQotICAgICAgICB7Ci0gICAgICAgICAgaWYgKGZsYXZvci5lcXVhbHMoImQyZCIpKQotICAgICAgICAgIHsKLQotICAgICAgICAgICAgLy8gUGFyc2UgaW4gdGhlIHhtbCBkYXRhIGludG8gYSBET00KLSAgICAgICAgICAgIERvY3VtZW50QnVpbGRlckZhY3RvcnkgZGZhY3RvcnkgPQotICAgICAgICAgICAgICBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCk7Ci0KLSAgICAgICAgICAgIGRmYWN0b3J5LnNldE5hbWVzcGFjZUF3YXJlKHRydWUpOwotCi0gICAgICAgICAgICBpZiAoaXNTZWN1cmVQcm9jZXNzaW5nKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICB0cnkKLSAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIGRmYWN0b3J5LnNldEZlYXR1cmUoWE1MQ29uc3RhbnRzLkZFQVRVUkVfU0VDVVJFX1BST0NFU1NJTkcsIHRydWUpOwotICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgIGNhdGNoIChQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIHBjZSkge30KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgRG9jdW1lbnRCdWlsZGVyIGRvY0J1aWxkZXIgPSBkZmFjdG9yeS5uZXdEb2N1bWVudEJ1aWxkZXIoKTsKLSAgICAgICAgICAgIE5vZGUgeHNsRE9NID0gZG9jQnVpbGRlci5wYXJzZShuZXcgSW5wdXRTb3VyY2UoeHNsRmlsZU5hbWUpKTsKLQotICAgICAgICAgICAgc3R5bGVzaGVldCA9IHRmYWN0b3J5Lm5ld1RlbXBsYXRlcyhuZXcgRE9NU291cmNlKHhzbERPTSwKLSAgICAgICAgICAgICAgICAgICAgeHNsRmlsZU5hbWUpKTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgIHsKLSAgICAgICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiQ2FsbGluZyBuZXdUZW1wbGF0ZXM6ICIreHNsRmlsZU5hbWUpOwotICAgICAgICAgICAgc3R5bGVzaGVldCA9IHRmYWN0b3J5Lm5ld1RlbXBsYXRlcyhuZXcgU3RyZWFtU291cmNlKHhzbEZpbGVOYW1lKSk7Ci0gICAgICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIkRvbmUgY2FsbGluZyBuZXdUZW1wbGF0ZXM6ICIreHNsRmlsZU5hbWUpOwotICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIFByaW50V3JpdGVyIHJlc3VsdFdyaXRlcjsKLSAgICAgICAgU3RyZWFtUmVzdWx0IHN0clJlc3VsdDsKLQotICAgICAgICBpZiAobnVsbCAhPSBvdXRGaWxlTmFtZSkKLSAgICAgICAgewotICAgICAgICAgIHN0clJlc3VsdCA9IG5ldyBTdHJlYW1SZXN1bHQobmV3IEZpbGVPdXRwdXRTdHJlYW0ob3V0RmlsZU5hbWUpKTsKLSAgICAgICAgICAvLyBPbmUgcG9zc2libGUgaW1wcm92ZW1lbnQgbWlnaHQgYmUgdG8gZW5zdXJlIHRoaXMgaXMKLSAgICAgICAgICAvLyAgYSB2YWxpZCBVUkkgYmVmb3JlIHNldHRpbmcgdGhlIHN5c3RlbUlkLCBidXQgdGhhdAotICAgICAgICAgIC8vICBtaWdodCBoYXZlIHN1YnRsZSBjaGFuZ2VzIHRoYXQgcHJlLWV4aXN0aW5nIHVzZXJzCi0gICAgICAgICAgLy8gIG1pZ2h0IG5vdGljZTsgd2UgY2FuIHRoaW5rIGFib3V0IHRoYXQgbGF0ZXIgLXNjIHIxLjQ2Ci0gICAgICAgICAgc3RyUmVzdWx0LnNldFN5c3RlbUlkKG91dEZpbGVOYW1lKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgIHsKLSAgICAgICAgICBzdHJSZXN1bHQgPSBuZXcgU3RyZWFtUmVzdWx0KFN5c3RlbS5vdXQpOwotICAgICAgICAgIC8vIFdlIHVzZWQgdG8gZGVmYXVsdCB0byBpbmNyZW1lbnRhbCBtb2RlIGluIHRoaXMgY2FzZS4KLSAgICAgICAgICAvLyBXZSd2ZSBzaW5jZSBkZWNpZGVkIHRoYXQgc2luY2UgdGhlIC1JTkNSRU1FTlRBTCBzd2l0Y2ggaXMKLSAgICAgICAgICAvLyBhdmFpbGFibGUsIHRoYXQgZGVmYXVsdCBpcyBwcm9iYWJseSBub3QgbmVjZXNzYXJ5IG5vcgotICAgICAgICAgIC8vIG5lY2Vzc2FyaWx5IGEgZ29vZCBpZGVhLgotICAgICAgICB9Ci0KLSAgICAgICAgU0FYVHJhbnNmb3JtZXJGYWN0b3J5IHN0ZiA9IChTQVhUcmFuc2Zvcm1lckZhY3RvcnkpIHRmYWN0b3J5OwotCi0gICAgICAgIC8vIEoyU0UgZG9lcyBub3Qgc3VwcG9ydCBYYWxhbiBpbnRlcnByZXRpdmUKLSAgICAgICAgLyoKLSAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIGN1cnJlbnRseSBjb250cm9sbGVkIHZpYSBUcmFuc2Zvcm1lckZhY3RvcnlJbXBsLgotICAgICAgICBpZiAoIXVzZVhTTFRDICYmIHVzZVNvdXJjZUxvY2F0aW9uKQotICAgICAgICAgICBzdGYuc2V0QXR0cmlidXRlKFhhbGFuUHJvcGVydGllcy5TT1VSQ0VfTE9DQVRJT04sIEJvb2xlYW4uVFJVRSk7Ci0gICAgICAgICovCi0KLSAgICAgICAgLy8gRGlkIHRoZXkgcGFzcyBpbiBhIHN0eWxlc2hlZXQsIG9yIHNob3VsZCB3ZSBnZXQgaXQgZnJvbSB0aGUKLSAgICAgICAgLy8gZG9jdW1lbnQ/Ci0gICAgICAgIGlmIChudWxsID09IHN0eWxlc2hlZXQpCi0gICAgICAgIHsKLSAgICAgICAgICBTb3VyY2Ugc291cmNlID0KLSAgICAgICAgICAgIHN0Zi5nZXRBc3NvY2lhdGVkU3R5bGVzaGVldChuZXcgU3RyZWFtU291cmNlKGluRmlsZU5hbWUpLCBtZWRpYSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLCBudWxsKTsKLQotICAgICAgICAgIGlmIChudWxsICE9IHNvdXJjZSkKLSAgICAgICAgICAgIHN0eWxlc2hlZXQgPSB0ZmFjdG9yeS5uZXdUZW1wbGF0ZXMoc291cmNlKTsKLSAgICAgICAgICBlbHNlCi0gICAgICAgICAgewotICAgICAgICAgICAgaWYgKG51bGwgIT0gbWVkaWEpCi0gICAgICAgICAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9OT19TVFlMRVNIRUVUX0lOX01FRElBLCBuZXcgT2JqZWN0W117aW5GaWxlTmFtZSwgbWVkaWF9KSk7IC8vIk5vIHN0eWxlc2hlZXQgZm91bmQgaW46ICIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gKyBpbkZpbGVOYW1lICsgIiwgbWVkaWE9IgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyArIG1lZGlhKTsKLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoWFNMVEVycm9yUmVzb3VyY2VzLkVSX05PX1NUWUxFU0hFRVRfUEksIG5ldyBPYmplY3RbXXtpbkZpbGVOYW1lfSkpOyAvLyJObyB4bWwtc3R5bGVzaGVldCBQSSBmb3VuZCBpbjogIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8rIGluRmlsZU5hbWUpOwotICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGlmIChudWxsICE9IHN0eWxlc2hlZXQpCi0gICAgICAgIHsKLSAgICAgICAgICBUcmFuc2Zvcm1lciB0cmFuc2Zvcm1lciA9IGZsYXZvci5lcXVhbHMoInRoIikgPyBudWxsIDogc3R5bGVzaGVldC5uZXdUcmFuc2Zvcm1lcigpOwotICAgICAgICAgIHRyYW5zZm9ybWVyLnNldEVycm9yTGlzdGVuZXIobmV3IERlZmF1bHRFcnJvckhhbmRsZXIoKSk7Ci0KLSAgICAgICAgICAvLyBPdmVycmlkZSB0aGUgb3V0cHV0IGZvcm1hdD8KLSAgICAgICAgICBpZiAobnVsbCAhPSBvdXRwdXRUeXBlKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIHRyYW5zZm9ybWVyLnNldE91dHB1dFByb3BlcnR5KE91dHB1dEtleXMuTUVUSE9ELCBvdXRwdXRUeXBlKTsKLSAgICAgICAgICB9Ci0KLSAgICAgICAgICAvLyBKMlNFIGRvZXMgbm90IHN1cHBvcnQgWGFsYW4gaW50ZXJwcmV0aXZlCi0gICAgICAgICAgLyoKLSAgICAgICAgICBpZiAodHJhbnNmb3JtZXIgaW5zdGFuY2VvZiBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwudHJhbnNmb3JtZXIuVHJhbnNmb3JtZXJJbXBsKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC50cmFuc2Zvcm1lci5UcmFuc2Zvcm1lckltcGwgaW1wbCA9IChjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwudHJhbnNmb3JtZXIuVHJhbnNmb3JtZXJJbXBsKXRyYW5zZm9ybWVyOwotICAgICAgICAgICAgVHJhY2VNYW5hZ2VyIHRtID0gaW1wbC5nZXRUcmFjZU1hbmFnZXIoKTsKLQotICAgICAgICAgICAgaWYgKG51bGwgIT0gdHJhY2VyKQotICAgICAgICAgICAgICB0bS5hZGRUcmFjZUxpc3RlbmVyKHRyYWNlcik7Ci0KLSAgICAgICAgICAgIGltcGwuc2V0UXVpZXRDb25mbGljdFdhcm5pbmdzKHF1aWV0Q29uZmxpY3RXYXJuaW5ncyk7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoaXMgaXMgY3VycmVudGx5IGNvbnRyb2xsZWQgdmlhIFRyYW5zZm9ybWVyRmFjdG9yeUltcGwuCi0gICAgICAgICAgICBpZiAodXNlU291cmNlTG9jYXRpb24pCi0gICAgICAgICAgICAgIGltcGwuc2V0UHJvcGVydHkoWGFsYW5Qcm9wZXJ0aWVzLlNPVVJDRV9MT0NBVElPTiwgQm9vbGVhbi5UUlVFKTsKLQotICAgICAgICAgICAgaWYocmVjdXJzaW9uTGltaXQ+MCkKLSAgICAgICAgICAgICAgaW1wbC5zZXRSZWN1cnNpb25MaW1pdChyZWN1cnNpb25MaW1pdCk7Ci0KLSAgICAgICAgICAgIC8vIHNjIDI4LUZlYi0wMSBpZiB3ZSByZS1pbXBsZW1lbnQgdGhpcywgcGxlYXNlIHVuY29tbWVudCBoZWxwbXNnIGluIHByaW50QXJnT3B0aW9ucwotICAgICAgICAgICAgLy8gaW1wbC5zZXREaWFnbm9zdGljc091dHB1dCggc2V0UXVpZXRNb2RlID8gbnVsbCA6IGRpYWdub3N0aWNzV3JpdGVyICk7Ci0gICAgICAgICAgfQotICAgICAgICAgICovCi0KLSAgICAgICAgICBpbnQgblBhcmFtcyA9IHBhcmFtcy5zaXplKCk7Ci0KLSAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG5QYXJhbXM7IGkgKz0gMikKLSAgICAgICAgICB7Ci0gICAgICAgICAgICB0cmFuc2Zvcm1lci5zZXRQYXJhbWV0ZXIoKFN0cmluZykgcGFyYW1zLmVsZW1lbnRBdChpKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoU3RyaW5nKSBwYXJhbXMuZWxlbWVudEF0KGkgKyAxKSk7Ci0gICAgICAgICAgfQotCi0gICAgICAgICAgaWYgKHVyaVJlc29sdmVyICE9IG51bGwpCi0gICAgICAgICAgICB0cmFuc2Zvcm1lci5zZXRVUklSZXNvbHZlcih1cmlSZXNvbHZlcik7Ci0KLSAgICAgICAgICBpZiAobnVsbCAhPSBpbkZpbGVOYW1lKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGlmIChmbGF2b3IuZXF1YWxzKCJkMmQiKSkKLSAgICAgICAgICAgIHsKLQotICAgICAgICAgICAgICAvLyBQYXJzZSBpbiB0aGUgeG1sIGRhdGEgaW50byBhIERPTQotICAgICAgICAgICAgICBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGRmYWN0b3J5ID0KLSAgICAgICAgICAgICAgICBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCk7Ci0KLSAgICAgICAgICAgICAgZGZhY3Rvcnkuc2V0Q29hbGVzY2luZyh0cnVlKTsKLSAgICAgICAgICAgICAgZGZhY3Rvcnkuc2V0TmFtZXNwYWNlQXdhcmUodHJ1ZSk7Ci0KLSAgICAgICAgICAgICAgaWYgKGlzU2VjdXJlUHJvY2Vzc2luZykKLSAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIHRyeQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgIGRmYWN0b3J5LnNldEZlYXR1cmUoWE1MQ29uc3RhbnRzLkZFQVRVUkVfU0VDVVJFX1BST0NFU1NJTkcsIHRydWUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBjYXRjaCAoUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBwY2UpIHt9Ci0gICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICBEb2N1bWVudEJ1aWxkZXIgZG9jQnVpbGRlciA9IGRmYWN0b3J5Lm5ld0RvY3VtZW50QnVpbGRlcigpOwotCi0gICAgICAgICAgICAgIGlmIChlbnRpdHlSZXNvbHZlciAhPSBudWxsKQotICAgICAgICAgICAgICAgIGRvY0J1aWxkZXIuc2V0RW50aXR5UmVzb2x2ZXIoZW50aXR5UmVzb2x2ZXIpOwotCi0gICAgICAgICAgICAgIE5vZGUgeG1sRG9jID0gZG9jQnVpbGRlci5wYXJzZShuZXcgSW5wdXRTb3VyY2UoaW5GaWxlTmFtZSkpOwotICAgICAgICAgICAgICBEb2N1bWVudCBkb2MgPSBkb2NCdWlsZGVyLm5ld0RvY3VtZW50KCk7Ci0gICAgICAgICAgICAgIG9yZy53M2MuZG9tLkRvY3VtZW50RnJhZ21lbnQgb3V0Tm9kZSA9Ci0gICAgICAgICAgICAgICAgZG9jLmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTsKLQotICAgICAgICAgICAgICB0cmFuc2Zvcm1lci50cmFuc2Zvcm0obmV3IERPTVNvdXJjZSh4bWxEb2MsIGluRmlsZU5hbWUpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IERPTVJlc3VsdChvdXROb2RlKSk7Ci0KLSAgICAgICAgICAgICAgLy8gTm93IHNlcmlhbGl6ZSBvdXRwdXQgdG8gZGlzayB3aXRoIGlkZW50aXR5IHRyYW5zZm9ybWVyCi0gICAgICAgICAgICAgIFRyYW5zZm9ybWVyIHNlcmlhbGl6ZXIgPSBzdGYubmV3VHJhbnNmb3JtZXIoKTsKLSAgICAgICAgICAgICAgc2VyaWFsaXplci5zZXRFcnJvckxpc3RlbmVyKG5ldyBEZWZhdWx0RXJyb3JIYW5kbGVyKCkpOwotCi0gICAgICAgICAgICAgIFByb3BlcnRpZXMgc2VyaWFsaXphdGlvblByb3BzID0KLSAgICAgICAgICAgICAgICBzdHlsZXNoZWV0LmdldE91dHB1dFByb3BlcnRpZXMoKTsKLQotICAgICAgICAgICAgICBzZXJpYWxpemVyLnNldE91dHB1dFByb3BlcnRpZXMoc2VyaWFsaXphdGlvblByb3BzKTsKLQotICAgICAgICAgICAgICBpZiAoY29udGVudEhhbmRsZXIgIT0gbnVsbCkKLSAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIFNBWFJlc3VsdCByZXN1bHQgPSBuZXcgU0FYUmVzdWx0KGNvbnRlbnRIYW5kbGVyKTsKLQotICAgICAgICAgICAgICAgIHNlcmlhbGl6ZXIudHJhbnNmb3JtKG5ldyBET01Tb3VyY2Uob3V0Tm9kZSksIHJlc3VsdCk7Ci0gICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIHNlcmlhbGl6ZXIudHJhbnNmb3JtKG5ldyBET01Tb3VyY2Uob3V0Tm9kZSksIHN0clJlc3VsdCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChmbGF2b3IuZXF1YWxzKCJ0aCIpKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDE7IGkrKykgLy8gTG9vcCBmb3IgZGlhZ25vc2luZyBidWdzIHdpdGggaW5jb25zaXN0ZW50IGJlaGF2aW9yCi0gICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJUZXN0aW5nIHRoZSBUcmFuc2Zvcm1lckhhbmRsZXIuLi4iKTsKLQotICAgICAgICAgICAgICBYTUxSZWFkZXIgcmVhZGVyID0gbnVsbDsKLQotICAgICAgICAgICAgICAvLyBVc2UgSkFYUDEuMSAoIGlmIHBvc3NpYmxlICkKLSAgICAgICAgICAgICAgdHJ5Ci0gICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBqYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXJGYWN0b3J5IGZhY3RvcnkgPQotICAgICAgICAgICAgICAgICAgamF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyRmFjdG9yeS5uZXdJbnN0YW5jZSgpOwotCi0gICAgICAgICAgICAgICAgZmFjdG9yeS5zZXROYW1lc3BhY2VBd2FyZSh0cnVlKTsKLQotICAgICAgICAgICAgICAgIGlmIChpc1NlY3VyZVByb2Nlc3NpbmcpCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgdHJ5Ci0gICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIGZhY3Rvcnkuc2V0RmVhdHVyZShYTUxDb25zdGFudHMuRkVBVFVSRV9TRUNVUkVfUFJPQ0VTU0lORywgdHJ1ZSk7Ci0gICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICBjYXRjaCAob3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIHNlKSB7fQotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIGphdmF4LnhtbC5wYXJzZXJzLlNBWFBhcnNlciBqYXhwUGFyc2VyID0KLSAgICAgICAgICAgICAgICAgIGZhY3RvcnkubmV3U0FYUGFyc2VyKCk7Ci0KLSAgICAgICAgICAgICAgICByZWFkZXIgPSBqYXhwUGFyc2VyLmdldFhNTFJlYWRlcigpOwotICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgIGNhdGNoIChqYXZheC54bWwucGFyc2Vycy5QYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIGV4KQotICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbihleCk7Ci0gICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgY2F0Y2ggKGphdmF4LnhtbC5wYXJzZXJzLkZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IgZXgxKQotICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbihleDEudG9TdHJpbmcoKSk7Ci0gICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgY2F0Y2ggKE5vU3VjaE1ldGhvZEVycm9yIGV4Mil7fQotICAgICAgICAgICAgICBjYXRjaCAoQWJzdHJhY3RNZXRob2RFcnJvciBhbWUpe30KLQotICAgICAgICAgICAgICBpZiAobnVsbCA9PSByZWFkZXIpCi0gICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICByZWFkZXIgPSBYTUxSZWFkZXJGYWN0b3J5LmNyZWF0ZVhNTFJlYWRlcigpOwotICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgLy8gSjJTRSBkb2VzIG5vdCBzdXBwb3J0IFhhbGFuIGludGVycHJldGl2ZQotICAgICAgICAgICAgICAvKgotICAgICAgICAgICAgICBpZiAoIXVzZVhTTFRDKQotICAgICAgICAgICAgICAgIHN0Zi5zZXRBdHRyaWJ1dGUoY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnByb2Nlc3Nvci5UcmFuc2Zvcm1lckZhY3RvcnlJbXBsLkZFQVRVUkVfSU5DUkVNRU5UQUwsCi0gICAgICAgICAgICAgICAgICAgQm9vbGVhbi5UUlVFKTsKLSAgICAgICAgICAgICAgKi8KLQotICAgICAgICAgICAgICBUcmFuc2Zvcm1lckhhbmRsZXIgdGggPSBzdGYubmV3VHJhbnNmb3JtZXJIYW5kbGVyKHN0eWxlc2hlZXQpOwotCi0gICAgICAgICAgICAgIHJlYWRlci5zZXRDb250ZW50SGFuZGxlcih0aCk7Ci0gICAgICAgICAgICAgIHJlYWRlci5zZXREVERIYW5kbGVyKHRoKTsKLQotICAgICAgICAgICAgICBpZih0aCBpbnN0YW5jZW9mIG9yZy54bWwuc2F4LkVycm9ySGFuZGxlcikKLSAgICAgICAgICAgICAgICByZWFkZXIuc2V0RXJyb3JIYW5kbGVyKChvcmcueG1sLnNheC5FcnJvckhhbmRsZXIpdGgpOwotCi0gICAgICAgICAgICAgIHRyeQotICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgcmVhZGVyLnNldFByb3BlcnR5KAotICAgICAgICAgICAgICAgICAgImh0dHA6Ly94bWwub3JnL3NheC9wcm9wZXJ0aWVzL2xleGljYWwtaGFuZGxlciIsIHRoKTsKLSAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICBjYXRjaCAob3JnLnhtbC5zYXguU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiBlKXt9Ci0gICAgICAgICAgICAgIGNhdGNoIChvcmcueG1sLnNheC5TQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gZSl7fQotICAgICAgICAgICAgICB0cnkKLSAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIHJlYWRlci5zZXRGZWF0dXJlKCJodHRwOi8veG1sLm9yZy9zYXgvZmVhdHVyZXMvbmFtZXNwYWNlLXByZWZpeGVzIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlKTsKLSAgICAgICAgICAgICAgfSBjYXRjaCAob3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIHNlKSB7fQotCi0gICAgICAgICAgICAgIHRoLnNldFJlc3VsdChzdHJSZXN1bHQpOwotCi0gICAgICAgICAgICAgIHJlYWRlci5wYXJzZShuZXcgSW5wdXRTb3VyY2UoaW5GaWxlTmFtZSkpOwotICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIGlmIChlbnRpdHlSZXNvbHZlciAhPSBudWxsKQotICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgWE1MUmVhZGVyIHJlYWRlciA9IG51bGw7Ci0KLSAgICAgICAgICAgICAgICAvLyBVc2UgSkFYUDEuMSAoIGlmIHBvc3NpYmxlICkKLSAgICAgICAgICAgICAgICB0cnkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICBqYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXJGYWN0b3J5IGZhY3RvcnkgPQotICAgICAgICAgICAgICAgICAgICBqYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCk7Ci0KLSAgICAgICAgICAgICAgICAgIGZhY3Rvcnkuc2V0TmFtZXNwYWNlQXdhcmUodHJ1ZSk7Ci0KLSAgICAgICAgICAgICAgICAgIGlmIChpc1NlY3VyZVByb2Nlc3NpbmcpCi0gICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIHRyeQotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgZmFjdG9yeS5zZXRGZWF0dXJlKFhNTENvbnN0YW50cy5GRUFUVVJFX1NFQ1VSRV9QUk9DRVNTSU5HLCB0cnVlKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBjYXRjaCAob3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIHNlKSB7fQotICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICBqYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXIgamF4cFBhcnNlciA9Ci0gICAgICAgICAgICAgICAgICAgIGZhY3RvcnkubmV3U0FYUGFyc2VyKCk7Ci0KLSAgICAgICAgICAgICAgICAgIHJlYWRlciA9IGpheHBQYXJzZXIuZ2V0WE1MUmVhZGVyKCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGNhdGNoIChqYXZheC54bWwucGFyc2Vycy5QYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIGV4KQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24oZXgpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBjYXRjaCAoamF2YXgueG1sLnBhcnNlcnMuRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvciBleDEpCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbihleDEudG9TdHJpbmcoKSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGNhdGNoIChOb1N1Y2hNZXRob2RFcnJvciBleDIpe30KLSAgICAgICAgICAgICAgICBjYXRjaCAoQWJzdHJhY3RNZXRob2RFcnJvciBhbWUpe30KLQotICAgICAgICAgICAgICAgIGlmIChudWxsID09IHJlYWRlcikKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICByZWFkZXIgPSBYTUxSZWFkZXJGYWN0b3J5LmNyZWF0ZVhNTFJlYWRlcigpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIHJlYWRlci5zZXRFbnRpdHlSZXNvbHZlcihlbnRpdHlSZXNvbHZlcik7Ci0KLSAgICAgICAgICAgICAgICBpZiAoY29udGVudEhhbmRsZXIgIT0gbnVsbCkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICBTQVhSZXN1bHQgcmVzdWx0ID0gbmV3IFNBWFJlc3VsdChjb250ZW50SGFuZGxlcik7Ci0KLSAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybWVyLnRyYW5zZm9ybSgKLSAgICAgICAgICAgICAgICAgICAgbmV3IFNBWFNvdXJjZShyZWFkZXIsIG5ldyBJbnB1dFNvdXJjZShpbkZpbGVOYW1lKSksCi0gICAgICAgICAgICAgICAgICAgIHJlc3VsdCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICB0cmFuc2Zvcm1lci50cmFuc2Zvcm0oCi0gICAgICAgICAgICAgICAgICAgIG5ldyBTQVhTb3VyY2UocmVhZGVyLCBuZXcgSW5wdXRTb3VyY2UoaW5GaWxlTmFtZSkpLAotICAgICAgICAgICAgICAgICAgICBzdHJSZXN1bHQpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICBlbHNlIGlmIChjb250ZW50SGFuZGxlciAhPSBudWxsKQotICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgU0FYUmVzdWx0IHJlc3VsdCA9IG5ldyBTQVhSZXN1bHQoY29udGVudEhhbmRsZXIpOwotCi0gICAgICAgICAgICAgICAgdHJhbnNmb3JtZXIudHJhbnNmb3JtKG5ldyBTdHJlYW1Tb3VyY2UoaW5GaWxlTmFtZSksIHJlc3VsdCk7Ci0gICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJTdGFydGluZyB0cmFuc2Zvcm0iKTsKLSAgICAgICAgICAgICAgICB0cmFuc2Zvcm1lci50cmFuc2Zvcm0obmV3IFN0cmVhbVNvdXJjZShpbkZpbGVOYW1lKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyUmVzdWx0KTsKLSAgICAgICAgICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIkRvbmUgd2l0aCB0cmFuc2Zvcm0iKTsKLSAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgIH0KLSAgICAgICAgICBlbHNlCi0gICAgICAgICAgewotICAgICAgICAgICAgU3RyaW5nUmVhZGVyIHJlYWRlciA9Ci0gICAgICAgICAgICAgIG5ldyBTdHJpbmdSZWFkZXIoIjw/eG1sIHZlcnNpb249XCIxLjBcIj8+IDxkb2MvPiIpOwotCi0gICAgICAgICAgICB0cmFuc2Zvcm1lci50cmFuc2Zvcm0obmV3IFN0cmVhbVNvdXJjZShyZWFkZXIpLCBzdHJSZXN1bHQpOwotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgIHsKLS8vICAgICAgICAgICJYU0wgUHJvY2VzcyB3YXMgbm90IHN1Y2Nlc3NmdWwuIik7Ci0gICAgICAgICAgICBtc2cgPSBYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKAotICAgICAgICAgICAgICAgIFhTTFRFcnJvclJlc291cmNlcy5FUl9OT1RfU1VDQ0VTU0ZVTCwgbnVsbCk7Ci0gICAgICAgICAgZGlhZ25vc3RpY3NXcml0ZXIucHJpbnRsbihtc2cpOwotICAgICAgICAgIGRvRXhpdChtc2cpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gY2xvc2Ugb3V0cHV0IHN0cmVhbXMKLSAgICAgICAgaWYgKG51bGwgIT0gb3V0RmlsZU5hbWUgJiYgc3RyUmVzdWx0IT1udWxsKQotICAgICAgICB7Ci0gICAgICAgICAgamF2YS5pby5PdXRwdXRTdHJlYW0gb3V0ID0gc3RyUmVzdWx0LmdldE91dHB1dFN0cmVhbSgpOwotICAgICAgICAgIGphdmEuaW8uV3JpdGVyIHdyaXRlciA9IHN0clJlc3VsdC5nZXRXcml0ZXIoKTsKLSAgICAgICAgICB0cnkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBpZiAob3V0ICE9IG51bGwpIG91dC5jbG9zZSgpOwotICAgICAgICAgICAgaWYgKHdyaXRlciAhPSBudWxsKSB3cml0ZXIuY2xvc2UoKTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgY2F0Y2goamF2YS5pby5JT0V4Y2VwdGlvbiBpZSkge30KLSAgICAgICAgfQotCi0gICAgICAgIGxvbmcgc3RvcCA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOwotICAgICAgICBsb25nIG1pbGxpc2Vjb25kc0R1cmF0aW9uID0gc3RvcCAtIHN0YXJ0OwotCi0gICAgICAgIGlmIChkb0RpYWcpCi0gICAgICAgIHsKLSAgICAgICAgICAgICAgICBPYmplY3RbXSBtc2dBcmdzID0gbmV3IE9iamVjdFtdeyBpbkZpbGVOYW1lLCB4c2xGaWxlTmFtZSwgbmV3IExvbmcobWlsbGlzZWNvbmRzRHVyYXRpb24pIH07Ci0gICAgICAgICAgICBtc2cgPSBYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKCJkaWFnVGltaW5nIiwgbXNnQXJncyk7Ci0gICAgICAgICAgICAgICAgZGlhZ25vc3RpY3NXcml0ZXIucHJpbnRsbignXG4nKTsKLSAgICAgICAgICAgICAgICBkaWFnbm9zdGljc1dyaXRlci5wcmludGxuKG1zZyk7Ci0gICAgICAgIH0KLQotICAgICAgfQotICAgICAgY2F0Y2ggKFRocm93YWJsZSB0aHJvd2FibGUpCi0gICAgICB7Ci0gICAgICAgIHdoaWxlICh0aHJvd2FibGUKLSAgICAgICAgICAgICAgIGluc3RhbmNlb2YgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5XcmFwcGVkUnVudGltZUV4Y2VwdGlvbikKLSAgICAgICAgewotICAgICAgICAgIHRocm93YWJsZSA9Ci0gICAgICAgICAgICAoKGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuV3JhcHBlZFJ1bnRpbWVFeGNlcHRpb24pIHRocm93YWJsZSkuZ2V0RXhjZXB0aW9uKCk7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoKHRocm93YWJsZSBpbnN0YW5jZW9mIE51bGxQb2ludGVyRXhjZXB0aW9uKQotICAgICAgICAgICAgICAgIHx8ICh0aHJvd2FibGUgaW5zdGFuY2VvZiBDbGFzc0Nhc3RFeGNlcHRpb24pKQotICAgICAgICAgIGRvU3RhY2tEdW1wT25FcnJvciA9IHRydWU7Ci0KLSAgICAgICAgZGlhZ25vc3RpY3NXcml0ZXIucHJpbnRsbigpOwotCi0gICAgICAgIGlmIChkb1N0YWNrRHVtcE9uRXJyb3IpCi0gICAgICAgICAgdGhyb3dhYmxlLnByaW50U3RhY2tUcmFjZShkdW1wV3JpdGVyKTsKLSAgICAgICAgZWxzZQotICAgICAgICB7Ci0gICAgICAgICAgRGVmYXVsdEVycm9ySGFuZGxlci5wcmludExvY2F0aW9uKGRpYWdub3N0aWNzV3JpdGVyLCB0aHJvd2FibGUpOwotICAgICAgICAgIGRpYWdub3N0aWNzV3JpdGVyLnByaW50bG4oCi0gICAgICAgICAgICBYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9YU0xUX0VSUk9SLCBudWxsKQotICAgICAgICAgICAgKyAiICgiICsgdGhyb3dhYmxlLmdldENsYXNzKCkuZ2V0TmFtZSgpICsgIik6ICIKLSAgICAgICAgICAgICsgdGhyb3dhYmxlLmdldE1lc3NhZ2UoKSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBkaWFnbm9zdGljc1dyaXRlci5wcmludGxuKFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoWFNMVEVycm9yUmVzb3VyY2VzLkVSX05PVF9TVUNDRVNTRlVMLCBudWxsKSk7IC8vIlhTTCBQcm9jZXNzIHdhcyBub3Qgc3VjY2Vzc2Z1bC4iKTsKLSAgICAgICAgaWYgKG51bGwgIT0gZHVtcEZpbGVOYW1lKQotICAgICAgICB7Ci0gICAgICAgICAgZHVtcFdyaXRlci5jbG9zZSgpOwotICAgICAgICB9Ci0KLSAgICAgICAgZG9FeGl0KHRocm93YWJsZS5nZXRNZXNzYWdlKCkpOwotICAgICAgfQotCi0gICAgICBpZiAobnVsbCAhPSBkdW1wRmlsZU5hbWUpCi0gICAgICB7Ci0gICAgICAgIGR1bXBXcml0ZXIuY2xvc2UoKTsKLSAgICAgIH0KLQotICAgICAgaWYgKG51bGwgIT0gZGlhZ25vc3RpY3NXcml0ZXIpCi0gICAgICB7Ci0KLSAgICAgICAgLy8gZGlhZ25vc3RpY3NXcml0ZXIuY2xvc2UoKTsKLSAgICAgIH0KLQotICAgICAgLy8gaWYoIXNldFF1aWV0TW9kZSkKLSAgICAgIC8vICBkaWFnbm9zdGljc1dyaXRlci5wcmludGxuKHJlc2J1bmRsZS5nZXRTdHJpbmcoInhzbGRvbmUiKSk7IC8vIlhhbGFuOiBkb25lIik7Ci0gICAgICAvLyBlbHNlCi0gICAgICAvLyBkaWFnbm9zdGljc1dyaXRlci5wcmludGxuKCIiKTsgIC8vIlhhbGFuOiBkb25lIik7Ci0gICAgfQotICB9Ci0KLSAgLyoqIEl0IGlzIF9tdWNoXyBlYXNpZXIgdG8gZGVidWcgdW5kZXIgVkorKyBpZiBJIGNhbiBzZXQgYSBzaW5nbGUgYnJlYWtwb2ludAotICAgKiBiZWZvcmUgdGhpcyBibG93cyBpdHNlbGYgb3V0IG9mIHRoZSB3YXRlci4uLgotICAgKiAoSSBrZWVwIGNoZWNraW5nIHRoaXMgaW4sIGl0IGtlZXBzIHZhbmlzaGluZy4gR3JyISkKLSAgICogKi8KLSAgc3RhdGljIHZvaWQgZG9FeGl0KFN0cmluZyBtc2cpCi0gIHsKLSAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihtc2cpOwotICB9Ci0KLSAgLyoqCi0gICAqIFdhaXQgZm9yIGEgcmV0dXJuIGtleSB0byBjb250aW51ZQotICAgKgotICAgKiBAcGFyYW0gcmVzYnVuZGxlIFRoZSByZXNvdXJjZSBidW5kbGUKLSAgICovCi0gIHByaXZhdGUgc3RhdGljIHZvaWQgd2FpdEZvclJldHVybktleShSZXNvdXJjZUJ1bmRsZSByZXNidW5kbGUpCi0gIHsKLSAgICBTeXN0ZW0ub3V0LnByaW50bG4ocmVzYnVuZGxlLmdldFN0cmluZygieHNsUHJvY19yZXR1cm5fdG9fY29udGludWUiKSk7Ci0gICAgdHJ5Ci0gICAgewotICAgICAgd2hpbGUgKFN5c3RlbS5pbi5yZWFkKCkgIT0gJ1xuJyk7Ci0gICAgfQotICAgIGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsgfQotICB9Ci0KLSAgLyoqCi0gICAqIFByaW50IGEgbWVzc2FnZSBpZiBhbiBvcHRpb24gY2Fubm90IGJlIHVzZWQgd2l0aCAtWFNMVEMuCi0gICAqCi0gICAqIEBwYXJhbSBvcHRpb24gVGhlIG9wdGlvbiBTdHJpbmcKLSAgICovCi0gIHByaXZhdGUgc3RhdGljIHZvaWQgcHJpbnRJbnZhbGlkWFNMVENPcHRpb24oU3RyaW5nIG9wdGlvbikKLSAgewotICAgIFN5c3RlbS5lcnIucHJpbnRsbihYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKCJ4c2xQcm9jX2ludmFsaWRfeHNsdGNfb3B0aW9uIiwgbmV3IE9iamVjdFtde29wdGlvbn0pKTsKLSAgfQotCi0gIC8qKgotICAgKiBQcmludCBhIG1lc3NhZ2UgaWYgYW4gb3B0aW9uIGNhbiBvbmx5IGJlIHVzZWQgd2l0aCAtWFNMVEMuCi0gICAqCi0gICAqIEBwYXJhbSBvcHRpb24gVGhlIG9wdGlvbiBTdHJpbmcKLSAgICovCi0gIHByaXZhdGUgc3RhdGljIHZvaWQgcHJpbnRJbnZhbGlkWGFsYW5PcHRpb24oU3RyaW5nIG9wdGlvbikKLSAgewotICAgIFN5c3RlbS5lcnIucHJpbnRsbihYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKCJ4c2xQcm9jX2ludmFsaWRfeGFsYW5fb3B0aW9uIiwgbmV3IE9iamVjdFtde29wdGlvbn0pKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0L3BhY2thZ2UuaHRtbCBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdC9wYWNrYWdlLmh0bWwKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDU5MTVlYmUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0L3BhY2thZ2UuaHRtbAorKysgL2Rldi9udWxsCkBAIC0xLDI4ICswLDAgQEAKLTwhLS0KLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0tLT4KLTwhLS0KLSAqIENvcHlyaWdodCAyMDAwLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotLS0+Ci08IS0tICRJZDogcGFja2FnZS5odG1sLHYgMS4yLjQuMSAyMDA1LzA5LzA5IDA3OjE4OjI1IHB2ZWR1bGEgRXhwICQgLS0+Ci08aHRtbD4KLSAgPHRpdGxlPlhhbGFuIGNvbW1hbmQtbGluZSBpbnRlcmZhY2UuPC90aXRsZT4KLSAgPGJvZHk+Ci0gICAgPHA+SW1wbGVtZW50YXRpb24gb2YgWGFsYW4gY29tbWFuZC1saW5lIGludGVyZmFjZS48cD4KLSA8L2JvZHk+Ci08L2h0bWw+Ci0KLQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9Db2xsYXRvckZhY3RvcnkuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvQ29sbGF0b3JGYWN0b3J5LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGE0NWMzNTMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9Db2xsYXRvckZhY3RvcnkuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDM3ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IENvbGxhdG9yRmFjdG9yeS5qYXZhLHYgMS4yLjQuMSAyMDA1LzA4LzMxIDEwOjE2OjMzIHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0YzsKLQotaW1wb3J0IGphdmEudGV4dC5Db2xsYXRvcjsKLWltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwotCi0vKioKLSAqIEBhdXRob3IgVy4gRWxpb3QgS2ltYmVyIChlbGlvdEBpc29nZW4uY29tKQotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgQ29sbGF0b3JGYWN0b3J5IHsKLQotICAgIHB1YmxpYyBDb2xsYXRvciBnZXRDb2xsYXRvcihTdHJpbmcgbGFuZywgU3RyaW5nIGNvdW50cnkpOwotICAgIHB1YmxpYyBDb2xsYXRvciBnZXRDb2xsYXRvcihMb2NhbGUgbG9jYWxlKTsKLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyNWNlMzcyLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMDMgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqLwotLyoKLSAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQotICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCi0gKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCi0gKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAotICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKLSAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNQXhpc0l0ZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplci5TZXJpYWxpemF0aW9uSGFuZGxlcjsKLWltcG9ydCBqYXZhLnV0aWwuTWFwOwotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZUxpc3Q7Ci0KLS8qKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICovCi1wdWJsaWMgaW50ZXJmYWNlIERPTSB7Ci0gICAgcHVibGljIGZpbmFsIHN0YXRpYyBpbnQgIEZJUlNUX1RZUEUgICAgICAgICAgICAgPSAwOwotCi0gICAgcHVibGljIGZpbmFsIHN0YXRpYyBpbnQgIE5PX1RZUEUgICAgICAgICAgICAgICAgPSAtMTsKLQotICAgIC8vIDAgaXMgcmVzZXJ2ZWQgZm9yIE5vZGVJdGVyYXRvci5FTkQKLSAgICBwdWJsaWMgZmluYWwgc3RhdGljIGludCBOVUxMICAgICA9IDA7Ci0KLSAgICAvLyB1c2VkIGJ5IHNvbWUgbm9kZSBpdGVyYXRvcnMgdG8ga25vdyB3aGljaCBub2RlIHRvIHJldHVybgotICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgaW50IFJFVFVSTl9DVVJSRU5UID0gMDsKLSAgICBwdWJsaWMgZmluYWwgc3RhdGljIGludCBSRVRVUk5fUEFSRU5UICA9IDE7Ci0KLSAgICAvLyBDb25zdGFudHMgdXNlZCBieSBnZXRSZXN1bHRUcmVlRnJhZyB0byBpbmRpY2F0ZSB0aGUgdHlwZXMgb2YgdGhlIFJURnMuCi0gICAgcHVibGljIGZpbmFsIHN0YXRpYyBpbnQgU0lNUExFX1JURiAgID0gMDsKLSAgICBwdWJsaWMgZmluYWwgc3RhdGljIGludCBBREFQVElWRV9SVEYgPSAxOwotICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgaW50IFRSRUVfUlRGICAgICA9IDI7Ci0KLSAgICAvKiogcmV0dXJucyBzaW5nbGV0b24gaXRlcmF0b3IgY29udGFpbmcgdGhlIGRvY3VtZW50IHJvb3QgKi8KLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIGdldEl0ZXJhdG9yKCk7Ci0gICAgcHVibGljIFN0cmluZyBnZXRTdHJpbmdWYWx1ZSgpOwotCi0gICAgcHVibGljIERUTUF4aXNJdGVyYXRvciBnZXRDaGlsZHJlbihmaW5hbCBpbnQgbm9kZSk7Ci0gICAgcHVibGljIERUTUF4aXNJdGVyYXRvciBnZXRUeXBlZENoaWxkcmVuKGZpbmFsIGludCB0eXBlKTsKLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIGdldEF4aXNJdGVyYXRvcihmaW5hbCBpbnQgYXhpcyk7Ci0gICAgcHVibGljIERUTUF4aXNJdGVyYXRvciBnZXRUeXBlZEF4aXNJdGVyYXRvcihmaW5hbCBpbnQgYXhpcywgZmluYWwgaW50IHR5cGUpOwotICAgIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3IgZ2V0TnRoRGVzY2VuZGFudChpbnQgbm9kZSwgaW50IG4sIGJvb2xlYW4gaW5jbHVkZXNlbGYpOwotICAgIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3IgZ2V0TmFtZXNwYWNlQXhpc0l0ZXJhdG9yKGZpbmFsIGludCBheGlzLCBmaW5hbCBpbnQgbnMpOwotICAgIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3IgZ2V0Tm9kZVZhbHVlSXRlcmF0b3IoRFRNQXhpc0l0ZXJhdG9yIGl0ZXIsIGludCByZXR1cm5UeXBlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHZhbHVlLCBib29sZWFuIG9wKTsKLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIG9yZGVyTm9kZXMoRFRNQXhpc0l0ZXJhdG9yIHNvdXJjZSwgaW50IG5vZGUpOwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Tm9kZU5hbWUoZmluYWwgaW50IG5vZGUpOwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Tm9kZU5hbWVYKGZpbmFsIGludCBub2RlKTsKLSAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWVzcGFjZU5hbWUoZmluYWwgaW50IG5vZGUpOwotICAgIHB1YmxpYyBpbnQgZ2V0RXhwYW5kZWRUeXBlSUQoZmluYWwgaW50IG5vZGUpOwotICAgIHB1YmxpYyBpbnQgZ2V0TmFtZXNwYWNlVHlwZShmaW5hbCBpbnQgbm9kZSk7Ci0gICAgcHVibGljIGludCBnZXRQYXJlbnQoZmluYWwgaW50IG5vZGUpOwotICAgIHB1YmxpYyBpbnQgZ2V0QXR0cmlidXRlTm9kZShmaW5hbCBpbnQgZ1R5cGUsIGZpbmFsIGludCBlbGVtZW50KTsKLSAgICBwdWJsaWMgU3RyaW5nIGdldFN0cmluZ1ZhbHVlWChmaW5hbCBpbnQgbm9kZSk7Ci0gICAgcHVibGljIHZvaWQgY29weShmaW5hbCBpbnQgbm9kZSwgU2VyaWFsaXphdGlvbkhhbmRsZXIgaGFuZGxlcikKLSAgICAgICAgdGhyb3dzIFRyYW5zbGV0RXhjZXB0aW9uOwotICAgIHB1YmxpYyB2b2lkIGNvcHkoRFRNQXhpc0l0ZXJhdG9yIG5vZGVzLCBTZXJpYWxpemF0aW9uSGFuZGxlciBoYW5kbGVyKQotICAgICAgICB0aHJvd3MgVHJhbnNsZXRFeGNlcHRpb247Ci0gICAgcHVibGljIFN0cmluZyBzaGFsbG93Q29weShmaW5hbCBpbnQgbm9kZSwgU2VyaWFsaXphdGlvbkhhbmRsZXIgaGFuZGxlcikKLSAgICAgICAgdGhyb3dzIFRyYW5zbGV0RXhjZXB0aW9uOwotICAgIHB1YmxpYyBib29sZWFuIGxlc3NUaGFuKGZpbmFsIGludCBub2RlMSwgZmluYWwgaW50IG5vZGUyKTsKLSAgICBwdWJsaWMgdm9pZCBjaGFyYWN0ZXJzKGZpbmFsIGludCB0ZXh0Tm9kZSwgU2VyaWFsaXphdGlvbkhhbmRsZXIgaGFuZGxlcikKLSAgICAgICAgdGhyb3dzIFRyYW5zbGV0RXhjZXB0aW9uOwotICAgIHB1YmxpYyBOb2RlIG1ha2VOb2RlKGludCBpbmRleCk7Ci0gICAgcHVibGljIE5vZGUgbWFrZU5vZGUoRFRNQXhpc0l0ZXJhdG9yIGl0ZXIpOwotICAgIHB1YmxpYyBOb2RlTGlzdCBtYWtlTm9kZUxpc3QoaW50IGluZGV4KTsKLSAgICBwdWJsaWMgTm9kZUxpc3QgbWFrZU5vZGVMaXN0KERUTUF4aXNJdGVyYXRvciBpdGVyKTsKLSAgICBwdWJsaWMgU3RyaW5nIGdldExhbmd1YWdlKGludCBub2RlKTsKLSAgICBwdWJsaWMgaW50IGdldFNpemUoKTsKLSAgICBwdWJsaWMgU3RyaW5nIGdldERvY3VtZW50VVJJKGludCBub2RlKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRGaWx0ZXIoU3RyaXBGaWx0ZXIgZmlsdGVyKTsKLSAgICBwdWJsaWMgdm9pZCBzZXR1cE1hcHBpbmcoU3RyaW5nW10gbmFtZXMsIFN0cmluZ1tdIHVyaXNBcnJheSwgaW50W10gdHlwZXNBcnJheSwgU3RyaW5nW10gbmFtZXNwYWNlcyk7Ci0gICAgcHVibGljIGJvb2xlYW4gaXNFbGVtZW50KGZpbmFsIGludCBub2RlKTsKLSAgICBwdWJsaWMgYm9vbGVhbiBpc0F0dHJpYnV0ZShmaW5hbCBpbnQgbm9kZSk7Ci0gICAgcHVibGljIFN0cmluZyBsb29rdXBOYW1lc3BhY2UoaW50IG5vZGUsIFN0cmluZyBwcmVmaXgpCi0gICAgICAgIHRocm93cyBUcmFuc2xldEV4Y2VwdGlvbjsKLSAgICBwdWJsaWMgaW50IGdldE5vZGVJZGVudChmaW5hbCBpbnQgbm9kZWhhbmRsZSk7Ci0gICAgcHVibGljIGludCBnZXROb2RlSGFuZGxlKGZpbmFsIGludCBub2RlSWQpOwotICAgIHB1YmxpYyBET00gZ2V0UmVzdWx0VHJlZUZyYWcoaW50IGluaXRpYWxTaXplLCBpbnQgcnRmVHlwZSk7Ci0gICAgcHVibGljIERPTSBnZXRSZXN1bHRUcmVlRnJhZyhpbnQgaW5pdGlhbFNpemUsIGludCBydGZUeXBlLCBib29sZWFuIGFkZFRvRFRNTWFuYWdlcik7Ci0gICAgcHVibGljIFNlcmlhbGl6YXRpb25IYW5kbGVyIGdldE91dHB1dERvbUJ1aWxkZXIoKTsKLSAgICBwdWJsaWMgaW50IGdldE5TVHlwZShpbnQgbm9kZSk7Ci0gICAgcHVibGljIGludCBnZXREb2N1bWVudCgpOwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VW5wYXJzZWRFbnRpdHlVUkkoU3RyaW5nIG5hbWUpOwotICAgIHB1YmxpYyBNYXA8U3RyaW5nLCBJbnRlZ2VyPiBnZXRFbGVtZW50c1dpdGhJRHMoKTsKLSAgICBwdWJsaWMgdm9pZCByZWxlYXNlKCk7Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTUNhY2hlLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTUNhY2hlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDFhOGVmYjEuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET01DYWNoZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTggKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRE9NQ2FjaGUuamF2YSx2IDEuMi40LjEgMjAwNS8wOC8zMSAxMDoyMzo1NSBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGM7Ci0KLQotLyoqCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqLwotcHVibGljIGludGVyZmFjZSBET01DYWNoZSB7Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBpcyByZXNwb25zaWJsZSBmb3I6Ci0gICAgICoKLSAgICAgKiAoMSkgYnVpbGRpbmcgdGhlIERPTUltcGwgdHJlZQotICAgICAqCi0gICAgICogICAgICBQYXJzZXIgIF9wYXJzZXIgPSBuZXcgUGFyc2VyKCk7Ci0gICAgICogICAgICBET01JbXBsIF9kb20gPSBuZXcgRE9NSW1wbCgpOwotICAgICAqICAgICAgX3BhcnNlci5zZXREb2N1bWVudEhhbmRsZXIoX2RvbS5nZXRCdWlsZGVyKCkpOwotICAgICAqICAgICAgX3BhcnNlci5zZXREVERIYW5kbGVyKF9kb20uZ2V0QnVpbGRlcigpKTsKLSAgICAgKiAgICAgIF9wYXJzZXIucGFyc2UodXJpKTsKLSAgICAgKgotICAgICAqICgyKSBnaXZpbmcgdGhlIHRyYW5zbGV0IGFuIGVhcmx5IG9wcG9ydHVuaXR5IHRvIGV4dHJhY3QgYW55dGhpbmcgZnJvbQotICAgICAqICAgICB0aGUgRE9NSW1wbCB0aGF0IGl0IHdvdWxkIGxpa2UKLSAgICAgKgotICAgICAqICAgICAgdHJhbnNsZXQuZG9jdW1lbnRQcmVwYXNzKF9kb20pOwotICAgICAqCi0gICAgICogKDMpIHNldHRpbmcgdGhlIGRvY3VtZW50IFVSSToKLSAgICAgKgotICAgICAqICAgICAgX2RvbS5zZXREb2N1bWVudFVSSSh1cmkpOwotICAgICAqCi0gICAgICogQHBhcmFtIGJhc2VVUkkgVGhlIGJhc2UgVVJJIHVzZWQgYnkgdGhlIGRvY3VtZW50IGNhbGwuCi0gICAgICogQHBhcmFtIGhyZWYgVGhlIGhyZWYgYXJndW1lbnQgcGFzc2VkIHRvIHRoZSBkb2N1bWVudCBmdW5jdGlvbi4KLSAgICAgKiBAcGFyYW0gdHJhbnNsZXQgQSByZWZlcmVuY2UgdG8gdGhlIHRyYW5zbGV0IHJlcXVlc3RpbmcgdGhlIGRvY3VtZW50Ci0gICAgICovCi0gICAgcHVibGljIERPTSByZXRyaWV2ZURvY3VtZW50KFN0cmluZyBiYXNlVVJJLCBTdHJpbmcgaHJlZiwgVHJhbnNsZXQgdHJhbnNsZXQpOwotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTUVuaGFuY2VkRm9yRFRNLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTUVuaGFuY2VkRm9yRFRNLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGY3ZTFiMzAuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET01FbmhhbmNlZEZvckRUTS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDcgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRE9NRW5oYW5jZWRGb3JEVE0uamF2YSx2IDEuMi40LjEgMjAwNS8wOC8zMSAxMDoyNToxMyBwdmVkdWxhIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjOwotCi0vKioKLSAqIEludGVyZmFjZSBmb3IgU0FYSW1wbCB3aGljaCBhZGRzIG1ldGhvZHMgdXNlZCBhdCBydW4tdGltZSwgb3ZlciBhbmQgYWJvdmUKLSAqIHRob3NlIHByb3ZpZGVkIGJ5IHRoZSBYU0xUQyBET00gaW50ZXJmYWNlLiBBbiBhdHRlbXB0IHRvIGF2b2lkIHRoZSBjdXJyZW50Ci0gKiAiSXMgdGhlIERUTSBhIERPTSwgaWYgc28gaXMgaXQgYSBTQVhJbXBsLCAuIC4gLgotICogd2hpY2ggd2FzIHByb2R1Y2luZyBzb21lIHVnbHkgcmVwbGljYXRlZCBjb2RlCi0gKiBhbmQgaW50cm9kdWNpbmcgYnVncyB3aGVyZSB0aGF0IG11bHRpcGF0aGluZyBoYWQgbm90IGJlZW4KLSAqIGRvbmUuICBUaGlzIG1ha2VzIGl0IGVhc2llciB0byBwcm92aWRlIG90aGVyIERPTS9ET01FbmhhbmNlZEZvckRUTQotICogaW1wbGVtZW50YXRpb25zLCByYXRoZXIgdGhhbiBoYXJkLXdpcmluZyBYU0xUQyB0byBTQVhJbXBsLgotICoKLSAqIEBhdXRob3IgSm9zZXBoIEtlc3NlbG1hbgotICoKLSAqLwotcHVibGljIGludGVyZmFjZSBET01FbmhhbmNlZEZvckRUTSBleHRlbmRzIERPTSB7Ci0gICAgcHVibGljIHNob3J0W10gZ2V0TWFwcGluZyhTdHJpbmdbXSBuYW1lcywgU3RyaW5nW10gdXJpcywgaW50W10gdHlwZXMpOwotICAgIHB1YmxpYyBpbnRbXSBnZXRSZXZlcnNlTWFwcGluZyhTdHJpbmdbXSBuYW1lcywgU3RyaW5nW10gdXJpcywgaW50W10gdHlwZXMpOwotICAgIHB1YmxpYyBzaG9ydFtdIGdldE5hbWVzcGFjZU1hcHBpbmcoU3RyaW5nW10gbmFtZXNwYWNlcyk7Ci0gICAgcHVibGljIHNob3J0W10gZ2V0UmV2ZXJzZU5hbWVzcGFjZU1hcHBpbmcoU3RyaW5nW10gbmFtZXNwYWNlcyk7Ci0gICAgcHVibGljIFN0cmluZyBnZXREb2N1bWVudFVSSSgpOwotICAgIHB1YmxpYyB2b2lkIHNldERvY3VtZW50VVJJKFN0cmluZyB1cmkpOwotICAgIHB1YmxpYyBpbnQgZ2V0RXhwYW5kZWRUeXBlSUQyKGludCBub2RlSGFuZGxlKTsKLSAgICBwdWJsaWMgYm9vbGVhbiBoYXNET01Tb3VyY2UoKTsKLSAgICBwdWJsaWMgaW50IGdldEVsZW1lbnRCeUlkKFN0cmluZyBpZFN0cmluZyk7Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL05vZGVJdGVyYXRvci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9Ob2RlSXRlcmF0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNjUwMzlmNC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL05vZGVJdGVyYXRvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsODYgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogTm9kZUl0ZXJhdG9yLmphdmEsdiAxLjIuNC4xIDIwMDUvMDgvMzEgMTA6MjY6MjcgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNOwotCi0vKioKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqLwotcHVibGljIGludGVyZmFjZSBOb2RlSXRlcmF0b3IgZXh0ZW5kcyBDbG9uZWFibGUgewotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVORCA9IERUTS5OVUxMOwotCi0gICAgLyoqCi0gICAgICogQ2FsbGVycyBzaG91bGQgbm90IGNhbGwgbmV4dCgpIGFmdGVyIGl0IHJldHVybnMgRU5ELgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgbmV4dCgpOwotCi0gICAgLyoqCi0gICAgICogUmVzZXRzIHRoZSBpdGVyYXRvciB0byB0aGUgbGFzdCBzdGFydCBub2RlLgotICAgICAqLwotICAgIHB1YmxpYyBOb2RlSXRlcmF0b3IgcmVzZXQoKTsKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIG51bWJlciBvZiBlbGVtZW50cyBpbiB0aGlzIGl0ZXJhdG9yLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0TGFzdCgpOwotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgcG9zaXRpb24gb2YgdGhlIGN1cnJlbnQgbm9kZSBpbiB0aGUgc2V0LgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0UG9zaXRpb24oKTsKLQotICAgIC8qKgotICAgICAqIFJlbWVtYmVycyB0aGUgY3VycmVudCBub2RlIGZvciB0aGUgbmV4dCBjYWxsIHRvIGdvdG9NYXJrKCkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0TWFyaygpOwotCi0gICAgLyoqCi0gICAgICogUmVzdG9yZXMgdGhlIGN1cnJlbnQgbm9kZSByZW1lbWJlcmVkIGJ5IHNldE1hcmsoKS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBnb3RvTWFyaygpOwotCi0gICAgLyoqCi0gICAgICogU2V0IHN0YXJ0IHRvIEVORCBzaG91bGQgJ2Nsb3NlJyB0aGUgaXRlcmF0b3IsCi0gICAgICogaS5lLiBzdWJzZXF1ZW50IGNhbGwgdG8gbmV4dCgpIHNob3VsZCByZXR1cm4gRU5ELgotICAgICAqLwotICAgIHB1YmxpYyBOb2RlSXRlcmF0b3Igc2V0U3RhcnROb2RlKGludCBub2RlKTsKLQotICAgIC8qKgotICAgICAqIFRydWUgaWYgdGhpcyBpdGVyYXRvciBoYXMgYSByZXZlcnNlZCBheGlzLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzUmV2ZXJzZSgpOwotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhIGRlZXAgY29weSBvZiB0aGlzIGl0ZXJhdG9yLgotICAgICAqLwotICAgIHB1YmxpYyBOb2RlSXRlcmF0b3IgY2xvbmVJdGVyYXRvcigpOwotCi0gICAgLyoqCi0gICAgICogUHJldmVudHMgb3IgYWxsb3dzIGl0ZXJhdG9yIHJlc3RhcnRzLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFJlc3RhcnRhYmxlKGJvb2xlYW4gaXNSZXN0YXJ0YWJsZSk7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvUHJvY2Vzc29yVmVyc2lvbi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9Qcm9jZXNzb3JWZXJzaW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGYzZDhlNGQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9Qcm9jZXNzb3JWZXJzaW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw1MSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBQcm9jZXNzb3JWZXJzaW9uLmphdmEsdiAxLjIuNC4xIDIwMDUvMDgvMzEgMTA6MzA6MzYgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjOwotCi0KLS8qKgotICogQWRtaW4gY2xhc3MgdGhhdCBhc3NpZ25zIGEgdmVyc2lvbiBudW1iZXIgdG8gdGhlIFhTTFRDIHNvZnR3YXJlLgotICogVGhlIHZlcnNpb24gbnVtYmVyIGlzIG1hZGUgdXAgZnJvbSB0aHJlZSBmaWVsZHMgYXMgaW46Ci0gKiBNQUpPUi5NSU5PUlsuREVMVEFdLiBGaWVsZHMgYXJlIGluY3JlbWVudGVkIGJhc2VkIG9uIHRoZSBmb2xsb3dpbmc6Ci0gKiBERUxUQSBmaWVsZDogY2hhbmdlcyBmb3IgZWFjaCBidWcgZml4LCBkZXZlbG9wZXIgZml4aW5nIHRoZSBidWcgc2hvdWxkCi0gKiAgICAgICAgICAgICAgaW5jcmVtZW50IHRoaXMgZmllbGQuCi0gKiBNSU5PUiBmaWVsZDogQVBJIGNoYW5nZXMgb3IgYSBtaWxlc3RvbmUgY3VsbWluYXRpbmcgZnJvbSBzZXZlcmFsCi0gKiAgICAgICAgICAgICAgYnVnIGZpeGVzLiBERUxUQSBmaWVsZCBnb2VzIHRvIHplcm8gYW5kIE1JTk9SIGlzCi0gKiAgICAgICAgICAgICAgaW5jcmVtZW50ZWQgc3VjaCBhczogezEuMCwxLjAuMSwxLjAuMiwxLjAuMywuLi4xLjAuMTgsMS4xfQotICogTUFKT1IgZmllbGQ6IG1pbGVzdG9uZSBjdWxtaW5hdGluZyBpbiBmdW5kYW1lbnRhbCBBUEkgY2hhbmdlcyBvcgotICogICAgICAgICAgICAgIGFyY2hpdGVjdHVyYWwgY2hhbmdlcy4gIE1JTk9SIGZpZWxkIGdvZXMgdG8gemVybwotICogICAgICAgICAgICAgIGFuZCBNQUpPUiBpcyBpbmNyZW1lbnRlZCBzdWNoIGFzOiB7Li4uLDEuMS4xNCwxLjIsMi4wfQotICogU3RhYmlsaXR5IG9mIGEgcmVsZWFzZSBmb2xsb3dzOiBYLjAgPiBYLlggPiBYLlguWAotICogQGF1dGhvciBHLiBUb2RkIE1pbGxlcgotICovCi1wdWJsaWMgY2xhc3MgUHJvY2Vzc29yVmVyc2lvbiB7Ci0gICAgcHJpdmF0ZSBzdGF0aWMgaW50IE1BSk9SID0gMTsKLSAgICBwcml2YXRlIHN0YXRpYyBpbnQgTUlOT1IgPSAwOwotICAgIHByaXZhdGUgc3RhdGljIGludCBERUxUQSA9IDA7Ci0KLSAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKSB7Ci0gICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiWFNMVEMgdmVyc2lvbiAiICsgTUFKT1IgKyAiLiIgKyBNSU5PUiArCi0gICAgICAgICAgICAoKERFTFRBID4gMCkgPyAoIi4iK0RFTFRBKSA6ICgiIikpKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1N0cmlwRmlsdGVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1N0cmlwRmlsdGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGVkNWI4NzguLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9TdHJpcEZpbHRlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzMgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogU3RyaXBGaWx0ZXIuamF2YSx2IDEuMi40LjEgMjAwNS8wOC8zMSAxMDo0MzozNiBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGM7Ci0KLQotLyoqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgU3RyaXBGaWx0ZXIgewotICAgIHB1YmxpYyBib29sZWFuIHN0cmlwU3BhY2UoRE9NIGRvbSwgaW50IG5vZGUsIGludCB0eXBlKTsKLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvVHJhbnNsZXQuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvVHJhbnNsZXQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggY2E2ZmY1MC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1RyYW5zbGV0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw1NyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBUcmFuc2xldC5qYXZhLHYgMS4yLjQuMSAyMDA1LzA4LzMxIDEwOjQ2OjI3IHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0YzsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTUF4aXNJdGVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXIuU2VyaWFsaXphdGlvbkhhbmRsZXI7Ci0KLS8qKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICovCi1wdWJsaWMgaW50ZXJmYWNlIFRyYW5zbGV0IHsKLQotICAgIHB1YmxpYyB2b2lkIHRyYW5zZm9ybShET00gZG9jdW1lbnQsIFNlcmlhbGl6YXRpb25IYW5kbGVyIGhhbmRsZXIpCi0gICAgICAgIHRocm93cyBUcmFuc2xldEV4Y2VwdGlvbjsKLSAgICBwdWJsaWMgdm9pZCB0cmFuc2Zvcm0oRE9NIGRvY3VtZW50LCBTZXJpYWxpemF0aW9uSGFuZGxlcltdIGhhbmRsZXJzKQotICAgICAgICB0aHJvd3MgVHJhbnNsZXRFeGNlcHRpb247Ci0gICAgcHVibGljIHZvaWQgdHJhbnNmb3JtKERPTSBkb2N1bWVudCwgRFRNQXhpc0l0ZXJhdG9yIGl0ZXJhdG9yLAotICAgICAgICAgICAgICAgICAgICAgICAgICBTZXJpYWxpemF0aW9uSGFuZGxlciBoYW5kbGVyKQotICAgICAgICB0aHJvd3MgVHJhbnNsZXRFeGNlcHRpb247Ci0KLSAgICBwdWJsaWMgT2JqZWN0IGFkZFBhcmFtZXRlcihTdHJpbmcgbmFtZSwgT2JqZWN0IHZhbHVlKTsKLQotICAgIHB1YmxpYyB2b2lkIGJ1aWxkS2V5cyhET00gZG9jdW1lbnQsIERUTUF4aXNJdGVyYXRvciBpdGVyYXRvciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgU2VyaWFsaXphdGlvbkhhbmRsZXIgaGFuZGxlciwgaW50IHJvb3QpCi0gICAgICAgIHRocm93cyBUcmFuc2xldEV4Y2VwdGlvbjsKLSAgICBwdWJsaWMgdm9pZCBhZGRBdXhpbGlhcnlDbGFzcyhDbGFzcyBhdXhDbGFzcyk7Ci0gICAgcHVibGljIENsYXNzIGdldEF1eGlsaWFyeUNsYXNzKFN0cmluZyBjbGFzc05hbWUpOwotICAgIHB1YmxpYyBTdHJpbmdbXSBnZXROYW1lc0FycmF5KCk7Ci0gICAgcHVibGljIFN0cmluZ1tdIGdldFVyaXNBcnJheSgpOwotICAgIHB1YmxpYyBpbnRbXSAgICBnZXRUeXBlc0FycmF5KCk7Ci0gICAgcHVibGljIFN0cmluZ1tdIGdldE5hbWVzcGFjZUFycmF5KCk7Ci0gICAgcHVibGljIGJvb2xlYW4gdXNlU2VydmljZXNNZWNobmlzbSgpOwotICAgIHB1YmxpYyB2b2lkIHNldFNlcnZpY2VzTWVjaG5pc20oYm9vbGVhbiBmbGFnKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9UcmFuc2xldEV4Y2VwdGlvbi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9UcmFuc2xldEV4Y2VwdGlvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxOWUxMmZlLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvVHJhbnNsZXRFeGNlcHRpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQ4ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFRyYW5zbGV0RXhjZXB0aW9uLmphdmEsdiAxLjIuNC4xIDIwMDUvMDgvMzEgMTA6NDc6NTAgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjOwotCi1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotCi0vKioKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgVHJhbnNsZXRFeGNlcHRpb24gZXh0ZW5kcyBTQVhFeGNlcHRpb24gewotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtODc4OTE2ODI5NTIxMjE3MjkzTDsKLQotICAgIHB1YmxpYyBUcmFuc2xldEV4Y2VwdGlvbigpIHsKLSAgICAgICAgc3VwZXIoIlRyYW5zbGV0IGVycm9yIik7Ci0gICAgfQotCi0gICAgcHVibGljIFRyYW5zbGV0RXhjZXB0aW9uKEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgIHN1cGVyKGUudG9TdHJpbmcoKSk7Ci0gICAgICAgIGluaXRDYXVzZShlKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgVHJhbnNsZXRFeGNlcHRpb24oU3RyaW5nIG1lc3NhZ2UpIHsKLSAgICAgICAgc3VwZXIobWVzc2FnZSk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jbWRsaW5lL0NvbXBpbGUuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY21kbGluZS9Db21waWxlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDlhYjdlMzAuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jbWRsaW5lL0NvbXBpbGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE3MSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBDb21waWxlLmphdmEsdiAxLjIuNC4xIDIwMDUvMDgvMzEgMTE6MjQ6MTMgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNtZGxpbmU7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwudXRpbHMuRmVhdHVyZU1hbmFnZXI7Ci1pbXBvcnQgamF2YS5pby5GaWxlOwotaW1wb3J0IGphdmEubmV0LlVSTDsKLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNtZGxpbmUuZ2V0b3B0LkdldE9wdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY21kbGluZS5nZXRvcHQuR2V0T3B0c0V4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIuWFNMVEM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuRXJyb3JNc2c7Ci0KLS8qKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICogQGF1dGhvciBHLiBUb2RkIE1pbGxlcgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBDb21waWxlIHsKLQotICAgIC8vIFZlcnNpb25pbmcgbnVtYmVycyAgZm9yIHRoZSBjb21waWxlciAtdiBvcHRpb24gb3V0cHV0Ci0gICAgcHJpdmF0ZSBzdGF0aWMgaW50IFZFUlNJT05fTUFKT1IgPSAxOwotICAgIHByaXZhdGUgc3RhdGljIGludCBWRVJTSU9OX01JTk9SID0gNDsKLSAgICBwcml2YXRlIHN0YXRpYyBpbnQgVkVSU0lPTl9ERUxUQSA9IDA7Ci0KLQotCi0gICAgLy8gVGhpcyB2YXJpYWJsZSBzaG91bGQgYmUgc2V0IHRvIGZhbHNlIHRvIHByZXZlbnQgYW55IG1ldGhvZHMgaW4gdGhpcwotICAgIC8vIGNsYXNzIGZyb20gY2FsbGluZyBTeXN0ZW0uZXhpdCgpLiBBcyB0aGlzIGlzIGEgY29tbWFuZC1saW5lIHRvb2wsCi0gICAgLy8gY2FsbGluZyBTeXN0ZW0uZXhpdCgpIGlzIG5vcm1hbGx5IE9LLCBidXQgd2UgYWxzbyB3YW50IHRvIGFsbG93IGZvcgotICAgIC8vIHRoaXMgY2xhc3MgYmVpbmcgdXNlZCBpbiBvdGhlciB3YXlzIGFzIHdlbGwuCi0gICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBfYWxsb3dFeGl0ID0gdHJ1ZTsKLQotCi0gICAgcHVibGljIHN0YXRpYyB2b2lkIHByaW50VXNhZ2UoKSB7Ci0gICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIlhTTFRDIHZlcnNpb24gIiArCi0gICAgICAgICAgICAgIFZFUlNJT05fTUFKT1IgKyAiLiIgKyBWRVJTSU9OX01JTk9SICsKLSAgICAgICAgICAgICAgKChWRVJTSU9OX0RFTFRBID4gMCkgPyAoIi4iICsgVkVSU0lPTl9ERUxUQSkgOiAoIiIpKSArICJcbiIgKwotICAgICAgICAgICAgICBuZXcgRXJyb3JNc2coRXJyb3JNc2cuQ09NUElMRV9VU0FHRV9TVFIpKTsKLSAgICAgICAgaWYgKF9hbGxvd0V4aXQpIFN5c3RlbS5leGl0KC0xKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBpbXBsZW1lbnRzIHRoZSBjb21tYW5kIGxpbmUgY29tcGlsZXIuIFNlZSB0aGUgVVNBR0VfU1RSSU5HCi0gICAgICogY29uc3RhbnQgZm9yIGEgZGVzY3JpcHRpb24uIEl0IG1heSBtYWtlIHNlbnNlIHRvIG1vdmUgdGhlIGNvbW1hbmQtbGluZQotICAgICAqIGhhbmRsaW5nIHRvIGEgc2VwYXJhdGUgcGFja2FnZSAoaWUuIG1ha2Ugb25lIHhzbHRjLmNtZGxpbmUuQ29tcGlsZXIKLSAgICAgKiBjbGFzcyB0aGF0IGNvbnRhaW5zIHRoaXMgbWFpbigpIG1ldGhvZCBhbmQgb25lIHhzbHRjLmNtZGxpbmUuVHJhbnNmb3JtCi0gICAgICogY2xhc3MgdGhhdCBjb250YWlucyB0aGUgRGVmYXVsdFJ1biBzdHVmZikuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nW10gYXJncykgewotICAgICAgICB0cnkgewotICAgICAgICAgICAgYm9vbGVhbiBpbnB1dElzVVJMID0gZmFsc2U7Ci0gICAgICAgICAgICBib29sZWFuIHVzZVN0ZEluID0gZmFsc2U7Ci0gICAgICAgICAgICBib29sZWFuIGNsYXNzTmFtZVNldCA9IGZhbHNlOwotICAgICAgICAgICAgZmluYWwgR2V0T3B0IGdldG9wdCA9IG5ldyBHZXRPcHQoYXJncywgIm86ZDpqOnA6dXhoc2ludiIpOwotICAgICAgICAgICAgaWYgKGFyZ3MubGVuZ3RoIDwgMSkgcHJpbnRVc2FnZSgpOwotCi0gICAgICAgICAgICBmaW5hbCBYU0xUQyB4c2x0YyA9IG5ldyBYU0xUQyh0cnVlLCBuZXcgRmVhdHVyZU1hbmFnZXIoKSk7Ci0gICAgICAgICAgICB4c2x0Yy5pbml0KCk7Ci0KLSAgICAgICAgICAgIGludCBjOwotICAgICAgICAgICAgd2hpbGUgKChjID0gZ2V0b3B0LmdldE5leHRPcHRpb24oKSkgIT0gLTEpIHsKLSAgICAgICAgICAgICAgICBzd2l0Y2goYykgewotICAgICAgICAgICAgICAgIGNhc2UgJ2knOgotICAgICAgICAgICAgICAgICAgICB1c2VTdGRJbiA9IHRydWU7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGNhc2UgJ28nOgotICAgICAgICAgICAgICAgICAgICB4c2x0Yy5zZXRDbGFzc05hbWUoZ2V0b3B0LmdldE9wdGlvbkFyZygpKTsKLSAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lU2V0ID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgY2FzZSAnZCc6Ci0gICAgICAgICAgICAgICAgICAgIHhzbHRjLnNldERlc3REaXJlY3RvcnkoZ2V0b3B0LmdldE9wdGlvbkFyZygpKTsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgY2FzZSAncCc6Ci0gICAgICAgICAgICAgICAgICAgIHhzbHRjLnNldFBhY2thZ2VOYW1lKGdldG9wdC5nZXRPcHRpb25BcmcoKSk7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGNhc2UgJ2onOgotICAgICAgICAgICAgICAgICAgICB4c2x0Yy5zZXRKYXJGaWxlTmFtZShnZXRvcHQuZ2V0T3B0aW9uQXJnKCkpOwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICBjYXNlICd4JzoKLSAgICAgICAgICAgICAgICAgICAgeHNsdGMuc2V0RGVidWcodHJ1ZSk7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGNhc2UgJ3UnOgotICAgICAgICAgICAgICAgICAgICBpbnB1dElzVVJMID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgY2FzZSAncyc6Ci0gICAgICAgICAgICAgICAgICAgIF9hbGxvd0V4aXQgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgY2FzZSAnbic6Ci0gICAgICAgICAgICAgICAgICAgIHhzbHRjLnNldFRlbXBsYXRlSW5saW5pbmcodHJ1ZSk7ICAgIC8vIHVzZWQgdG8gYmUgJ2ZhbHNlJwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICBjYXNlICd2JzoKLSAgICAgICAgICAgICAgICAgICAgLy8gZmFsbCB0aHJvdWdoIHRvIGNhc2UgaAotICAgICAgICAgICAgICAgIGNhc2UgJ2gnOgotICAgICAgICAgICAgICAgIGRlZmF1bHQ6Ci0gICAgICAgICAgICAgICAgICAgIHByaW50VXNhZ2UoKTsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBib29sZWFuIGNvbXBpbGVPSzsKLQotICAgICAgICAgICAgaWYgKHVzZVN0ZEluKSB7Ci0gICAgICAgICAgICAgICAgaWYgKCFjbGFzc05hbWVTZXQpIHsKLSAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKG5ldyBFcnJvck1zZyhFcnJvck1zZy5DT01QSUxFX1NURElOX0VSUikpOwotICAgICAgICAgICAgICAgICAgICBpZiAoX2FsbG93RXhpdCkgU3lzdGVtLmV4aXQoLTEpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBjb21waWxlT0sgPSB4c2x0Yy5jb21waWxlKFN5c3RlbS5pbiwgeHNsdGMuZ2V0Q2xhc3NOYW1lKCkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgLy8gR2VuZXJhdGUgYSB2ZWN0b3IgY29udGFpbmcgVVJMcyBmb3IgYWxsIHN0eWxlc2hlZXRzIHNwZWNpZmllZAotICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZ1tdIHN0eWxlc2hlZXROYW1lcyA9IGdldG9wdC5nZXRDbWRBcmdzKCk7Ci0gICAgICAgICAgICAgICAgZmluYWwgVmVjdG9yICAgc3R5bGVzaGVldFZlY3RvciA9IG5ldyBWZWN0b3IoKTsKLSAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHN0eWxlc2hlZXROYW1lcy5sZW5ndGg7IGkrKykgewotICAgICAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgbmFtZSA9IHN0eWxlc2hlZXROYW1lc1tpXTsKLSAgICAgICAgICAgICAgICAgICAgVVJMIHVybDsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGlucHV0SXNVUkwpCi0gICAgICAgICAgICAgICAgICAgICAgICB1cmwgPSBuZXcgVVJMKG5hbWUpOwotICAgICAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgICAgICB1cmwgPSAobmV3IEZpbGUobmFtZSkpLnRvVVJJKCkudG9VUkwoKTsKLSAgICAgICAgICAgICAgICAgICAgc3R5bGVzaGVldFZlY3Rvci5hZGRFbGVtZW50KHVybCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGNvbXBpbGVPSyA9IHhzbHRjLmNvbXBpbGUoc3R5bGVzaGVldFZlY3Rvcik7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIENvbXBpbGUgdGhlIHN0eWxlc2hlZXQgYW5kIG91dHB1dCBjbGFzcy9qYXIgZmlsZShzKQotICAgICAgICAgICAgaWYgKGNvbXBpbGVPSykgewotICAgICAgICAgICAgICAgIHhzbHRjLnByaW50V2FybmluZ3MoKTsKLSAgICAgICAgICAgICAgICBpZiAoeHNsdGMuZ2V0SmFyRmlsZU5hbWUoKSAhPSBudWxsKSB4c2x0Yy5vdXRwdXRUb0phcigpOwotICAgICAgICAgICAgICAgIGlmIChfYWxsb3dFeGl0KSBTeXN0ZW0uZXhpdCgwKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIHhzbHRjLnByaW50V2FybmluZ3MoKTsKLSAgICAgICAgICAgICAgICB4c2x0Yy5wcmludEVycm9ycygpOwotICAgICAgICAgICAgICAgIGlmIChfYWxsb3dFeGl0KSBTeXN0ZW0uZXhpdCgtMSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKEdldE9wdHNFeGNlcHRpb24gZXgpIHsKLSAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbihleCk7Ci0gICAgICAgICAgICBwcmludFVzYWdlKCk7IC8vIGV4aXRzIHdpdGggY29kZSAnLTEnCi0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgICAgICAgaWYgKF9hbGxvd0V4aXQpIFN5c3RlbS5leGl0KC0xKTsKLSAgICAgICAgfQotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jbWRsaW5lL1RyYW5zZm9ybS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jbWRsaW5lL1RyYW5zZm9ybS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhODFjZDc3Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY21kbGluZS9UcmFuc2Zvcm0uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI5MiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBUcmFuc2Zvcm0uamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xMiAwOTowNzozMyBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY21kbGluZTsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC51dGlscy5PYmplY3RGYWN0b3J5OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5ET01FbmhhbmNlZEZvckRUTTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuU3RyaXBGaWx0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLlRyYW5zbGV0RXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkVycm9yTXNnOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5kb20uRE9NV1NGaWx0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmRvbS5YU0xUQ0RUTU1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnJ1bnRpbWUuQWJzdHJhY3RUcmFuc2xldDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMucnVudGltZS5Db25zdGFudHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnJ1bnRpbWUuUGFyYW1ldGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5ydW50aW1lLm91dHB1dC5UcmFuc2xldE91dHB1dEhhbmRsZXJGYWN0b3J5OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTVdTRmlsdGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplci5TZXJpYWxpemF0aW9uSGFuZGxlcjsKLWltcG9ydCBqYXZhLmlvLkZpbGVOb3RGb3VuZEV4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLm5ldC5NYWxmb3JtZWRVUkxFeGNlcHRpb247Ci1pbXBvcnQgamF2YS5uZXQuVW5rbm93bkhvc3RFeGNlcHRpb247Ci1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXI7Ci1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyRmFjdG9yeTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnNheC5TQVhTb3VyY2U7Ci1pbXBvcnQgb3JnLnhtbC5zYXguSW5wdXRTb3VyY2U7Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LlhNTFJlYWRlcjsKLQotLyoqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKiBAYXV0aG9yIEcuIFRvZGQgTWlsbGVyCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqLwotZmluYWwgcHVibGljIGNsYXNzIFRyYW5zZm9ybSB7Ci0KLSAgICBwcml2YXRlIFNlcmlhbGl6YXRpb25IYW5kbGVyIF9oYW5kbGVyOwotCi0gICAgcHJpdmF0ZSBTdHJpbmcgIF9maWxlTmFtZTsKLSAgICBwcml2YXRlIFN0cmluZyAgX2NsYXNzTmFtZTsKLSAgICBwcml2YXRlIFN0cmluZyAgX2phckZpbGVTcmM7Ci0gICAgcHJpdmF0ZSBib29sZWFuIF9pc0phckZpbGVTcGVjaWZpZWQgPSBmYWxzZTsKLSAgICBwcml2YXRlIFZlY3RvciAgX3BhcmFtcyA9IG51bGw7Ci0gICAgcHJpdmF0ZSBib29sZWFuIF91cmksIF9kZWJ1ZzsKLSAgICBwcml2YXRlIGludCAgICAgX2l0ZXJhdGlvbnM7Ci0KLSAgICBwdWJsaWMgVHJhbnNmb3JtKFN0cmluZyBjbGFzc05hbWUsIFN0cmluZyBmaWxlTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gdXJpLCBib29sZWFuIGRlYnVnLCBpbnQgaXRlcmF0aW9ucykgewotICAgICAgICBfZmlsZU5hbWUgPSBmaWxlTmFtZTsKLSAgICAgICAgX2NsYXNzTmFtZSA9IGNsYXNzTmFtZTsKLSAgICAgICAgX3VyaSA9IHVyaTsKLSAgICAgICAgX2RlYnVnID0gZGVidWc7Ci0gICAgICAgIF9pdGVyYXRpb25zID0gaXRlcmF0aW9uczsKLSAgfQotCi0gICBwdWJsaWMgU3RyaW5nIGdldEZpbGVOYW1lKCl7cmV0dXJuIF9maWxlTmFtZTt9Ci0gICBwdWJsaWMgU3RyaW5nIGdldENsYXNzTmFtZSgpe3JldHVybiBfY2xhc3NOYW1lO30KLQotICAgIHB1YmxpYyB2b2lkIHNldFBhcmFtZXRlcnMoVmVjdG9yIHBhcmFtcykgewotICAgICAgICBfcGFyYW1zID0gcGFyYW1zOwotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBzZXRKYXJGaWxlSW5wdXRTcmMoYm9vbGVhbiBmbGFnLCAgU3RyaW5nIGphckZpbGUpIHsKLSAgICAgICAgLy8gVE9ETzogYXQgdGhpcyB0aW1lIHdlIGRvIG5vdCBkbyBhbnl0aGluZyB3aXRoIHRoaXMKLSAgICAgICAgLy8gaW5mb3JtYXRpb24sIGF0dGVtcHRzIHRvIGFkZCB0aGUgamFyZmlsZSB0byB0aGUgQ0xBU1NQQVRICi0gICAgICAgIC8vIHdlcmUgc3VjY2Vzc2Z1bCB2aWEgU3lzdGVtLnNldFByb3BlcnR5LCBidXQgdGhlIGVmZmVjdHMKLSAgICAgICAgLy8gd2VyZSBub3QgdmlzaWJsZSB0byB0aGUgcnVubmluZyBKVk0uIEZvciBub3cgd2UgYWRkIGphcmZpbGUKLSAgICAgICAgLy8gdG8gQ0xBU1NQQVRIIGluIHRoZSB3cmFwcGVyIHNjcmlwdCB0aGF0IGNhbGxzIHRoaXMgcHJvZ3JhbS4KLSAgICAgICAgX2lzSmFyRmlsZVNwZWNpZmllZCA9IGZsYWc7Ci0gICAgICAgIC8vIFRPRE8gdmVyaWZ5IGphckZpbGUgZXhpc3RzLi4uCi0gICAgICAgIF9qYXJGaWxlU3JjID0gamFyRmlsZTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgZG9UcmFuc2Zvcm0oKSB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBmaW5hbCBDbGFzcyBjbGF6eiA9IE9iamVjdEZhY3RvcnkuZmluZFByb3ZpZGVyQ2xhc3MoX2NsYXNzTmFtZSwgdHJ1ZSk7Ci0gICAgICAgICAgICBmaW5hbCBBYnN0cmFjdFRyYW5zbGV0IHRyYW5zbGV0ID0gKEFic3RyYWN0VHJhbnNsZXQpY2xhenoubmV3SW5zdGFuY2UoKTsKLSAgICAgICAgICAgIHRyYW5zbGV0LnBvc3RJbml0aWFsaXphdGlvbigpOwotCi0gICAgICAgICAgICAvLyBDcmVhdGUgYSBTQVggcGFyc2VyIGFuZCBnZXQgdGhlIFhNTFJlYWRlciBvYmplY3QgaXQgdXNlcwotICAgICAgICAgICAgZmluYWwgU0FYUGFyc2VyRmFjdG9yeSBmYWN0b3J5ID0gU0FYUGFyc2VyRmFjdG9yeS5uZXdJbnN0YW5jZSgpOwotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICBmYWN0b3J5LnNldEZlYXR1cmUoQ29uc3RhbnRzLk5BTUVTUEFDRV9GRUFUVVJFLHRydWUpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgZmFjdG9yeS5zZXROYW1lc3BhY2VBd2FyZSh0cnVlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGZpbmFsIFNBWFBhcnNlciBwYXJzZXIgPSBmYWN0b3J5Lm5ld1NBWFBhcnNlcigpOwotICAgICAgICAgICAgZmluYWwgWE1MUmVhZGVyIHJlYWRlciA9IHBhcnNlci5nZXRYTUxSZWFkZXIoKTsKLQotICAgICAgICAgICAgLy8gU2V0IHRoZSBET00ncyBET00gYnVpbGRlciBhcyB0aGUgWE1MUmVhZGVyJ3MgU0FYMiBjb250ZW50IGhhbmRsZXIKLSAgICAgICAgICAgIFhTTFRDRFRNTWFuYWdlciBkdG1NYW5hZ2VyID0KLSAgICAgICAgICAgICAgICBYU0xUQ0RUTU1hbmFnZXIuY3JlYXRlTmV3RFRNTWFuYWdlckluc3RhbmNlKCk7Ci0KLSAgICAgICAgICAgIERUTVdTRmlsdGVyIHdzZmlsdGVyOwotICAgICAgICAgICAgaWYgKHRyYW5zbGV0ICE9IG51bGwgJiYgdHJhbnNsZXQgaW5zdGFuY2VvZiBTdHJpcEZpbHRlcikgewotICAgICAgICAgICAgICAgIHdzZmlsdGVyID0gbmV3IERPTVdTRmlsdGVyKHRyYW5zbGV0KTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgd3NmaWx0ZXIgPSBudWxsOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBmaW5hbCBET01FbmhhbmNlZEZvckRUTSBkb20gPQotICAgICAgICAgICAgICAgICAgIChET01FbmhhbmNlZEZvckRUTSlkdG1NYW5hZ2VyLmdldERUTSgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgU0FYU291cmNlKHJlYWRlciwgbmV3IElucHV0U291cmNlKF9maWxlTmFtZSkpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlLCB3c2ZpbHRlciwgdHJ1ZSwgZmFsc2UsIHRyYW5zbGV0Lmhhc0lkQ2FsbCgpKTsKLQotICAgICAgICAgICAgZG9tLnNldERvY3VtZW50VVJJKF9maWxlTmFtZSk7Ci0gICAgICAgICAgICB0cmFuc2xldC5wcmVwYXNzRG9jdW1lbnQoZG9tKTsKLQotICAgICAgICAgICAgLy8gUGFzcyBnbG9iYWwgcGFyYW1ldGVycwotICAgICAgICAgICAgaW50IG4gPSBfcGFyYW1zLnNpemUoKTsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgUGFyYW1ldGVyIHBhcmFtID0gKFBhcmFtZXRlcikgX3BhcmFtcy5lbGVtZW50QXQoaSk7Ci0gICAgICAgICAgICAgICAgdHJhbnNsZXQuYWRkUGFyYW1ldGVyKHBhcmFtLl9uYW1lLCBwYXJhbS5fdmFsdWUpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBUcmFuc2Zvcm0gdGhlIGRvY3VtZW50Ci0gICAgICAgICAgICBUcmFuc2xldE91dHB1dEhhbmRsZXJGYWN0b3J5IHRvaEZhY3RvcnkgPQotICAgICAgICAgICAgICAgIFRyYW5zbGV0T3V0cHV0SGFuZGxlckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKLSAgICAgICAgICAgIHRvaEZhY3Rvcnkuc2V0T3V0cHV0VHlwZShUcmFuc2xldE91dHB1dEhhbmRsZXJGYWN0b3J5LlNUUkVBTSk7Ci0gICAgICAgICAgICB0b2hGYWN0b3J5LnNldEVuY29kaW5nKHRyYW5zbGV0Ll9lbmNvZGluZyk7Ci0gICAgICAgICAgICB0b2hGYWN0b3J5LnNldE91dHB1dE1ldGhvZCh0cmFuc2xldC5fbWV0aG9kKTsKLQotICAgICAgICAgICAgaWYgKF9pdGVyYXRpb25zID09IC0xKSB7Ci0gICAgICAgICAgICAgICAgdHJhbnNsZXQudHJhbnNmb3JtKGRvbSwgdG9oRmFjdG9yeS5nZXRTZXJpYWxpemF0aW9uSGFuZGxlcigpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKF9pdGVyYXRpb25zID4gMCkgewotICAgICAgICAgICAgICAgIGxvbmcgbW0gPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKLSAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IF9pdGVyYXRpb25zOyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgdHJhbnNsZXQudHJhbnNmb3JtKGRvbSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvaEZhY3RvcnkuZ2V0U2VyaWFsaXphdGlvbkhhbmRsZXIoKSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIG1tID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkgLSBtbTsKLQotICAgICAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiXG48IS0tIik7Ci0gICAgICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCIgIHRyYW5zZm9ybSAgPSAiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgKCgoZG91YmxlKSBtbSkgLyAoKGRvdWJsZSkgX2l0ZXJhdGlvbnMpKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgbXMiKTsKLSAgICAgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIiAgdGhyb3VnaHB1dCA9ICIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAoMTAwMC4wIC8gKCgoZG91YmxlKSBtbSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvICgoZG91YmxlKSBfaXRlcmF0aW9ucykpKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgdHBzIik7Ci0gICAgICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCItLT4iKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoVHJhbnNsZXRFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgaWYgKF9kZWJ1ZykgZS5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbihuZXcgRXJyb3JNc2coRXJyb3JNc2cuUlVOVElNRV9FUlJPUl9LRVkpKwotICAgICAgICAgICAgICAgICAgIGUuZ2V0TWVzc2FnZSgpKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICBpZiAoX2RlYnVnKSBlLnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKG5ldyBFcnJvck1zZyhFcnJvck1zZy5SVU5USU1FX0VSUk9SX0tFWSkrCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZS5nZXRNZXNzYWdlKCkpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChGaWxlTm90Rm91bmRFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgaWYgKF9kZWJ1ZykgZS5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgICAgICAgIEVycm9yTXNnIGVyciA9IG5ldyBFcnJvck1zZyhFcnJvck1zZy5GSUxFX05PVF9GT1VORF9FUlIsIF9maWxlTmFtZSk7Ci0gICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4obmV3IEVycm9yTXNnKEVycm9yTXNnLlJVTlRJTUVfRVJST1JfS0VZKSsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnIudG9TdHJpbmcoKSk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICBpZiAoX2RlYnVnKSBlLnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgICAgICAgRXJyb3JNc2cgZXJyID0gbmV3IEVycm9yTXNnKEVycm9yTXNnLklOVkFMSURfVVJJX0VSUiwgX2ZpbGVOYW1lKTsKLSAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbihuZXcgRXJyb3JNc2coRXJyb3JNc2cuUlVOVElNRV9FUlJPUl9LRVkpKwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVyci50b1N0cmluZygpKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICBpZiAoX2RlYnVnKSBlLnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgICAgICAgRXJyb3JNc2cgZXJyPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuQ0xBU1NfTk9UX0ZPVU5EX0VSUixfY2xhc3NOYW1lKTsKLSAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbihuZXcgRXJyb3JNc2coRXJyb3JNc2cuUlVOVElNRV9FUlJPUl9LRVkpKwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVyci50b1N0cmluZygpKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoVW5rbm93bkhvc3RFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgaWYgKF9kZWJ1ZykgZS5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgICAgICAgIEVycm9yTXNnIGVyciA9IG5ldyBFcnJvck1zZyhFcnJvck1zZy5JTlZBTElEX1VSSV9FUlIsIF9maWxlTmFtZSk7Ci0gICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4obmV3IEVycm9yTXNnKEVycm9yTXNnLlJVTlRJTUVfRVJST1JfS0VZKSsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnIudG9TdHJpbmcoKSk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICBFeGNlcHRpb24gZXggPSBlLmdldEV4Y2VwdGlvbigpOwotICAgICAgICAgICAgaWYgKF9kZWJ1ZykgewotICAgICAgICAgICAgICAgIGlmIChleCAhPSBudWxsKSBleC5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludChuZXcgRXJyb3JNc2coRXJyb3JNc2cuUlVOVElNRV9FUlJPUl9LRVkpKTsKLSAgICAgICAgICAgIGlmIChleCAhPSBudWxsKQotICAgICAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbihleC5nZXRNZXNzYWdlKCkpOwotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbihlLmdldE1lc3NhZ2UoKSk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICBpZiAoX2RlYnVnKSBlLnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKG5ldyBFcnJvck1zZyhFcnJvck1zZy5SVU5USU1FX0VSUk9SX0tFWSkrCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZS5nZXRNZXNzYWdlKCkpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHN0YXRpYyB2b2lkIHByaW50VXNhZ2UoKSB7Ci0gICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbihuZXcgRXJyb3JNc2coRXJyb3JNc2cuVFJBTlNGT1JNX1VTQUdFX1NUUikpOwotICAgIH0KLQotICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGlmIChhcmdzLmxlbmd0aCA+IDApIHsKLSAgICAgICAgICAgICAgICBpbnQgaTsKLSAgICAgICAgICAgICAgICBpbnQgaXRlcmF0aW9ucyA9IC0xOwotICAgICAgICAgICAgICAgIGJvb2xlYW4gdXJpID0gZmFsc2UsIGRlYnVnID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgYm9vbGVhbiBpc0phckZpbGVTcGVjaWZpZWQgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICBTdHJpbmcgIGphckZpbGUgPSBudWxsOwotCi0gICAgICAgICAgICAgICAgLy8gUGFyc2Ugb3B0aW9ucyBzdGFydGluZyB3aXRoICctJwotICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBhcmdzLmxlbmd0aCAmJiBhcmdzW2ldLmNoYXJBdCgwKSA9PSAnLSc7IGkrKykgewotICAgICAgICAgICAgICAgICAgICBpZiAoYXJnc1tpXS5lcXVhbHMoIi11IikpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHVyaSA9IHRydWU7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoYXJnc1tpXS5lcXVhbHMoIi14IikpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGRlYnVnID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChhcmdzW2ldLmVxdWFscygiLWoiKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgaXNKYXJGaWxlU3BlY2lmaWVkID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGphckZpbGUgPSBhcmdzWysraV07Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoYXJnc1tpXS5lcXVhbHMoIi1uIikpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlcmF0aW9ucyA9IEludGVnZXIucGFyc2VJbnQoYXJnc1srK2ldKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlnbm9yZQotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnRVc2FnZSgpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgLy8gRW5vdWdoIGFyZ3VtZW50cyBsZWZ0ID8KLSAgICAgICAgICAgICAgICBpZiAoYXJncy5sZW5ndGggLSBpIDwgMikgcHJpbnRVc2FnZSgpOwotCi0gICAgICAgICAgICAgICAgLy8gR2V0IGRvY3VtZW50IGZpbGUgYW5kIGNsYXNzIG5hbWUKLSAgICAgICAgICAgICAgICBUcmFuc2Zvcm0gaGFuZGxlciA9IG5ldyBUcmFuc2Zvcm0oYXJnc1tpKzFdLCBhcmdzW2ldLCB1cmksCi0gICAgICAgICAgICAgICAgICAgIGRlYnVnLCBpdGVyYXRpb25zKTsKLSAgICAgICAgICAgICAgICBoYW5kbGVyLnNldEphckZpbGVJbnB1dFNyYyhpc0phckZpbGVTcGVjaWZpZWQsICBqYXJGaWxlKTsKLQotICAgICAgICAgICAgICAgIC8vIFBhcnNlIHN0eWxlc2hlZXQgcGFyYW1ldGVycwotICAgICAgICAgICAgICAgIFZlY3RvciBwYXJhbXMgPSBuZXcgVmVjdG9yKCk7Ci0gICAgICAgICAgICAgICAgZm9yIChpICs9IDI7IGkgPCBhcmdzLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCBlcXVhbCA9IGFyZ3NbaV0uaW5kZXhPZignPScpOwotICAgICAgICAgICAgICAgICAgICBpZiAoZXF1YWwgPiAwKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgbmFtZSAgPSBhcmdzW2ldLnN1YnN0cmluZygwLCBlcXVhbCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgdmFsdWUgPSBhcmdzW2ldLnN1YnN0cmluZyhlcXVhbCsxKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtcy5hZGRFbGVtZW50KG5ldyBQYXJhbWV0ZXIobmFtZSwgdmFsdWUpKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHByaW50VXNhZ2UoKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIGlmIChpID09IGFyZ3MubGVuZ3RoKSB7Ci0gICAgICAgICAgICAgICAgICAgIGhhbmRsZXIuc2V0UGFyYW1ldGVycyhwYXJhbXMpOwotICAgICAgICAgICAgICAgICAgICBoYW5kbGVyLmRvVHJhbnNmb3JtKCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBwcmludFVzYWdlKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgICB9Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jbWRsaW5lL2dldG9wdC9HZXRPcHQuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY21kbGluZS9nZXRvcHQvR2V0T3B0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDNlNTM3YzkuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jbWRsaW5lL2dldG9wdC9HZXRPcHQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI1OCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBHZXRPcHQuamF2YSx2IDEuMi40LjEgMjAwNS8wOC8zMSAxMTo0NjowNCBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY21kbGluZS5nZXRvcHQ7Ci0KLWltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwotaW1wb3J0IGphdmEudXRpbC5MaXN0OwotaW1wb3J0IGphdmEudXRpbC5MaXN0SXRlcmF0b3I7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5FcnJvck1zZzsKLQotCi0vKioKLSogR2V0T3B0IGlzIGEgSmF2YSBlcXVpdmFsZW50IHRvIHRoZSBDIGdldG9wdCgpIGxpYnJhcnkgZnVuY3Rpb24KLSogZGlzY3Vzc2VkIGluIG1hbiBwYWdlIGdldG9wdCgzQykuIEl0IHByb3ZpZGVzIGNvbW1hbmQgbGluZQotKiBwYXJzaW5nIGZvciBKYXZhIGFwcGxpY2F0aW9ucy4gSXQgc3VwcG9ydHMgdGhlIG1vc3QgcnVsZXMgb2YgdGhlCi0qIGNvbW1hbmQgbGluZSBzdGFuZGFyZCAoc2VlIG1hbiBwYWdlIGludHJvKDEpKSBpbmNsdWRpbmcgc3RhY2tlZAotKiBvcHRpb25zIHN1Y2ggYXMgJy1zeG0nICh3aGljaCBpcyBlcXVpdmFsZW50IHRvIC1zIC14IC1tKTsgaXQKLSogaGFuZGxlcyBzcGVjaWFsICctLScgb3B0aW9uIHRoYXQgc2lnbmlmaWVzIHRoZSBlbmQgb2Ygb3B0aW9ucy4KLSogQWRkaXRpb25hbGx5IHRoaXMgaW1wbGVtZW50YXRpb24gb2YgZ2V0b3B0IHdpbGwgY2hlY2sgZm9yCi0qIG1hbmRhdG9yeSBhcmd1bWVudHMgdG8gb3B0aW9ucyBzdWNoIGFzIGluIHRoZSBjYXNlIG9mCi0qICctZCA8ZmlsZT4nIGl0IHdpbGwgdGhyb3cgYSBNaXNzaW5nT3B0QXJnRXhjZXB0aW9uIGlmIHRoZQotKiBvcHRpb24gYXJndW1lbnQgJzxmaWxlPicgaXMgbm90IGluY2x1ZGVkIG9uIHRoZSBjb21tYW5kbGluZS4KLSogZ2V0b3B0KDNDKSBkb2VzIG5vdCBjaGVjayBmb3IgdGhpcy4KLSAqIEBhdXRob3IgRyBUb2RkIE1pbGxlcgotKi8KLXB1YmxpYyBjbGFzcyBHZXRPcHR7Ci0gICAgcHVibGljIEdldE9wdChTdHJpbmdbXSBhcmdzLCBTdHJpbmcgb3B0U3RyaW5nKXsKLSAgICAgICAgdGhlT3B0aW9ucyA9IG5ldyBBcnJheUxpc3QoKTsKLSAgICAgICAgaW50IGN1cnJPcHRJbmRleCA9IDA7Ci0gICAgICAgIHRoZUNtZEFyZ3MgPSBuZXcgQXJyYXlMaXN0KCk7Ci0gICAgICAgIHRoZU9wdGlvbk1hdGNoZXIgPSBuZXcgT3B0aW9uTWF0Y2hlcihvcHRTdHJpbmcpOwotICAgICAgICAvLyBmaWxsIGluIHRoZSBvcHRpb25zIGxpc3QKLSAgICAgICAgZm9yKGludCBpPTA7IGk8YXJncy5sZW5ndGg7IGkrKyl7Ci0gICAgICAgICAgICBTdHJpbmcgdG9rZW4gPSBhcmdzW2ldOwotICAgICAgICAgICAgaW50IHRva2VuTGVuZ3RoID0gdG9rZW4ubGVuZ3RoKCk7Ci0gICAgICAgICAgICBpZih0b2tlbi5lcXVhbHMoIi0tIikpeyAgICAgICAgIC8vIGVuZCBvZiBvcHRzCi0gICAgICAgICAgICAgICAgY3Vyck9wdEluZGV4ID0gaSsxOyAgICAgICAgIC8vIHNldCBpbmRleCBvZiBmaXJzdCBvcGVyYW5kCi0gICAgICAgICAgICAgICAgYnJlYWs7ICAgICAgICAgICAgICAgICAgICAgIC8vIGVuZCBvZiBvcHRpb25zCi0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmKHRva2VuLnN0YXJ0c1dpdGgoIi0iKSAmJiB0b2tlbkxlbmd0aCA9PSAyKXsKLSAgICAgICAgICAgICAgICAvLyBzaW1wbGUgb3B0aW9uIHRva2VuIHN1Y2ggYXMgJy1zJyBmb3VuZAotICAgICAgICAgICAgICAgIHRoZU9wdGlvbnMuYWRkKG5ldyBPcHRpb24odG9rZW4uY2hhckF0KDEpKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmKHRva2VuLnN0YXJ0c1dpdGgoIi0iKSAmJiB0b2tlbkxlbmd0aCA+IDIpewotICAgICAgICAgICAgICAgIC8vIHN0YWNrZWQgb3B0aW9ucyBmb3VuZCwgc3VjaCBhcyAnLXNobScKLSAgICAgICAgICAgICAgICAvLyBpdGVyYXRlIHRocnUgdGhlIHRva2VucyBhZnRlciB0aGUgZGFzaCBhbmQKLSAgICAgICAgICAgICAgICAvLyBhZGQgdGhlbSB0byB0aGVPcHRpb25zIGxpc3QKLSAgICAgICAgICAgICAgICBmb3IoaW50IGo9MTsgajx0b2tlbkxlbmd0aDsgaisrKXsKLSAgICAgICAgICAgICAgICAgICAgdGhlT3B0aW9ucy5hZGQobmV3IE9wdGlvbih0b2tlbi5jaGFyQXQoaikpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmKCF0b2tlbi5zdGFydHNXaXRoKCItIikpewotICAgICAgICAgICAgICAgIC8vIGNhc2UgMS0gdGhlcmUgYXJlIG5vdCBvcHRpb25zIHN0b3JlZCB5ZXQgdGhlcmVmb3JlCi0gICAgICAgICAgICAgICAgLy8gdGhpcyBtdXN0IGJlIGFuIGNvbW1hbmQgYXJndW1lbnQsIG5vdCBhbiBvcHRpb24gYXJndW1lbnQKLSAgICAgICAgICAgICAgICBpZih0aGVPcHRpb25zLnNpemUoKSA9PSAwKXsKLSAgICAgICAgICAgICAgICAgICAgY3Vyck9wdEluZGV4ID0gaTsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7ICAgICAgICAgICAgICAvLyBzdG9wIHByb2Nlc3Npbmcgb3B0aW9ucwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gY2FzZSAyLQotICAgICAgICAgICAgICAgICAgICAvLyB0aGVyZSBhcmUgb3B0aW9ucyBzdG9yZWQsIGNoZWNrIHRvIHNlZSBpZgotICAgICAgICAgICAgICAgICAgICAvLyB0aGlzIGFyZyBiZWxvbmcgdG8gdGhlIGxhc3QgYXJnIHN0b3JlZAotICAgICAgICAgICAgICAgICAgICBpbnQgaW5kZXhvZmxhc3Q9MDsKLSAgICAgICAgICAgICAgICAgICAgaW5kZXhvZmxhc3QgPSB0aGVPcHRpb25zLnNpemUoKS0xOwotICAgICAgICAgICAgICAgICAgICBPcHRpb24gb3AgPSAoT3B0aW9uKXRoZU9wdGlvbnMuZ2V0KGluZGV4b2ZsYXN0KTsKLSAgICAgICAgICAgICAgICAgICAgY2hhciBvcExldHRlciA9IG9wLmdldEFyZ0xldHRlcigpOwotICAgICAgICAgICAgICAgICAgICBpZighb3AuaGFzQXJnKCkgJiYgdGhlT3B0aW9uTWF0Y2hlci5oYXNBcmcob3BMZXR0ZXIpKXsKLSAgICAgICAgICAgICAgICAgICAgICAgIG9wLnNldEFyZyh0b2tlbik7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZXsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNhc2UgMyAtCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGUgbGFzdCBvcHRpb24gc3RvcmVkIGRvZXMgbm90IHRha2UKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFuIGFyZ3VtZW50LCBzbyBhZ2FpbiwgdGhpcyBhcmd1bWVudAotICAgICAgICAgICAgICAgICAgICAgICAgLy8gbXVzdCBiZSBhIGNvbW1hbmQgYXJndW1lbnQsIG5vdAotICAgICAgICAgICAgICAgICAgICAgICAgLy8gYW4gb3B0aW9uIGFyZ3VtZW50Ci0gICAgICAgICAgICAgICAgICAgICAgICBjdXJyT3B0SW5kZXggPSBpOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7ICAgICAgICAgICAgICAgICAgLy8gZW5kIG9mIG9wdGlvbnMKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0vLyBlbmQgb3B0aW9uIGRvZXMgbm90IHN0YXJ0IHdpdGggIi0iCi0gICAgICAgIH0gLy8gZW5kIGZvciBhcmdzIGxvb3AKLQotICAgICAgICAvLyAgYXR0YWNoIGFuIGl0ZXJhdG9yIHRvIGxpc3Qgb2Ygb3B0aW9ucwotICAgICAgICB0aGVPcHRpb25zSXRlcmF0b3IgPSB0aGVPcHRpb25zLmxpc3RJdGVyYXRvcigpOwotCi0gICAgICAgIC8vIG9wdGlvbnMgYXJlIGRvbmUsIG5vdyBmaWxsIG91dCBjbWQgYXJnIGxpc3Qgd2l0aCByZW1haW5pbmcgYXJncwotICAgICAgICBmb3IoaW50IGk9Y3Vyck9wdEluZGV4OyBpPGFyZ3MubGVuZ3RoOyBpKyspewotICAgICAgICAgICAgU3RyaW5nIHRva2VuID0gYXJnc1tpXTsKLSAgICAgICAgICAgIHRoZUNtZEFyZ3MuYWRkKHRva2VuKTsKLSAgICAgICAgfQotICAgIH0KLQotCi0gICAgLyoqCi0gICAgKiBkZWJ1Z2dpbmcgcm91dGluZSB0byBwcmludCBvdXQgYWxsIG9wdGlvbnMgY29sbGVjdGVkCi0gICAgKi8KLSAgICBwdWJsaWMgdm9pZCBwcmludE9wdGlvbnMoKXsKLSAgICAgICAgZm9yKExpc3RJdGVyYXRvciBpdD10aGVPcHRpb25zLmxpc3RJdGVyYXRvcigpOyBpdC5oYXNOZXh0KCk7KXsKLSAgICAgICAgICAgIE9wdGlvbiBvcHQgPSAoT3B0aW9uKWl0Lm5leHQoKTsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIk9QVCA9IiArIG9wdC5nZXRBcmdMZXR0ZXIoKSk7Ci0gICAgICAgICAgICBTdHJpbmcgYXJnID0gb3B0LmdldEFyZ3VtZW50KCk7Ci0gICAgICAgICAgICBpZihhcmcgIT0gbnVsbCl7Ci0gICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCIgIiArIGFyZyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICogZ2V0cyB0aGUgbmV4dCBvcHRpb24gZm91bmQgaW4gdGhlIGNvbW1hbmRsaW5lLiBEaXN0aW5ndWlzaGVzCi0gICAgKiBiZXR3ZWVuIHR3byBiYWQgY2FzZXMsIG9uZSBjYXNlIGlzIHdoZW4gYW4gaWxsZWdhbCBvcHRpb24KLSAgICAqIGlzIGZvdW5kLCBhbmQgdGhlbiBvdGhlciBjYXNlIGlzIHdoZW4gYW4gb3B0aW9uIHRha2VzIGFuCi0gICAgKiBhcmd1bWVudCBidXQgbm8gYXJndW1lbnQgd2FzIGZvdW5kIGZvciB0aGF0IG9wdGlvbi4KLSAgICAqIElmIHRoZSBvcHRpb24gZm91bmQgd2FzIG5vdCBkZWNsYXJlZCBpbiB0aGUgb3B0U3RyaW5nLCB0aGVuCi0gICAgKiBhbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gd2lsbCBiZSB0aHJvd24gKGNhc2UgMSkuCi0gICAgKiBJZiB0aGUgbmV4dCBvcHRpb24gZm91bmQgaGFzIGJlZW4gZGVjbGFyZWQgdG8gdGFrZSBhbiBhcmd1bWVudCwKLSAgICAqIGFuZCBubyBzdWNoIGFyZ3VtZW50IGV4aXN0cywgdGhlbiBhIE1pc3NpbmdPcHRBcmdFeGNlcHRpb24KLSAgICAqIGlzIHRocm93biAoY2FzZSAyKS4KLSAgICAqIEBwYXJhbSBub25lCi0gICAgKiBAcmV0dXJuIGludCAtIHRoZSBuZXh0IG9wdGlvbiBmb3VuZC4KLSAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLCBNaXNzaW5nT3B0QXJnRXhjZXB0aW9uLgotICAgICovCi0gICAgcHVibGljIGludCBnZXROZXh0T3B0aW9uKCkgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiwKLSAgICAgICAgTWlzc2luZ09wdEFyZ0V4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaW50IHJldHZhbCA9IC0xOwotICAgICAgICBpZih0aGVPcHRpb25zSXRlcmF0b3IuaGFzTmV4dCgpKXsKLSAgICAgICAgICAgIHRoZUN1cnJlbnRPcHRpb24gPSAoT3B0aW9uKXRoZU9wdGlvbnNJdGVyYXRvci5uZXh0KCk7Ci0gICAgICAgICAgICBjaGFyIGMgPSB0aGVDdXJyZW50T3B0aW9uLmdldEFyZ0xldHRlcigpOwotICAgICAgICAgICAgYm9vbGVhbiBzaG91bGRIYXZlQXJnID0gdGhlT3B0aW9uTWF0Y2hlci5oYXNBcmcoYyk7Ci0gICAgICAgICAgICBTdHJpbmcgYXJnID0gdGhlQ3VycmVudE9wdGlvbi5nZXRBcmd1bWVudCgpOwotICAgICAgICAgICAgaWYoIXRoZU9wdGlvbk1hdGNoZXIubWF0Y2goYykpIHsKLSAgICAgICAgICAgICAgICBFcnJvck1zZyBtc2cgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuSUxMRUdBTF9DTURMSU5FX09QVElPTl9FUlIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBDaGFyYWN0ZXIoYykpOwotICAgICAgICAgICAgICAgIHRocm93IChuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKG1zZy50b1N0cmluZygpKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmKHNob3VsZEhhdmVBcmcgJiYgKGFyZyA9PSBudWxsKSkgewotICAgICAgICAgICAgICAgIEVycm9yTXNnIG1zZyA9IG5ldyBFcnJvck1zZyhFcnJvck1zZy5DTURMSU5FX09QVF9NSVNTSU5HX0FSR19FUlIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBDaGFyYWN0ZXIoYykpOwotICAgICAgICAgICAgICAgIHRocm93IChuZXcgTWlzc2luZ09wdEFyZ0V4Y2VwdGlvbihtc2cudG9TdHJpbmcoKSkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dmFsID0gYzsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gcmV0dmFsOwotICAgIH0KLQotICAgIC8qKgotICAgICogZ2V0cyB0aGUgYXJndW1lbnQgZm9yIHRoZSBjdXJyZW50IHBhcnNlZCBvcHRpb24uIEZvciBleGFtcGxlLAotICAgICogaW4gY2FzZSBvZiAnLWQgPGZpbGU+JywgaWYgY3VycmVudCBvcHRpb24gcGFyc2VkIGlzICdkJyB0aGVuCi0gICAgKiBnZXRPcHRpb25BcmcoKSB3b3VsZCByZXR1cm4gJzxmaWxlPicuCi0gICAgKiBAcmV0dXJuIFN0cmluZyAtIGFyZ3VtZW50IGZvciBjdXJyZW50IHBhcnNlZCBvcHRpb24uCi0gICAgKiBAcGFyYW0gbm9uZQotICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRPcHRpb25BcmcoKXsKLSAgICAgICAgU3RyaW5nIHJldHZhbCA9IG51bGw7Ci0gICAgICAgIFN0cmluZyB0bXAgPSB0aGVDdXJyZW50T3B0aW9uLmdldEFyZ3VtZW50KCk7Ci0gICAgICAgIGNoYXIgYyA9IHRoZUN1cnJlbnRPcHRpb24uZ2V0QXJnTGV0dGVyKCk7Ci0gICAgICAgIGlmKHRoZU9wdGlvbk1hdGNoZXIuaGFzQXJnKGMpKXsKLSAgICAgICAgICAgIHJldHZhbCA9IHRtcDsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gcmV0dmFsOwotICAgIH0KLQotICAgIC8qKgotICAgICogZ2V0cyBsaXN0IG9mIHRoZSBjb21tYW5kbGluZSBhcmd1bWVudHMuIEZvciBleGFtcGxlLCBpbiBjb21tYW5kCi0gICAgKiBzdWNoIGFzICdjbWQgLXMgLWQgZmlsZSBmaWxlMiBmaWxlMyBmaWxlNCcgIHdpdGggdGhlIHVzYWdlCi0gICAgKiAnY21kIFstc10gWy1kIDxmaWxlPl0gPGZpbGU+Li4uJywgZ2V0Q21kQXJncygpIHdvdWxkIHJldHVybgotICAgICogdGhlIGxpc3Qge2ZpbGUyLCBmaWxlMywgZmlsZTR9LgotICAgICogQHJldHVybiBTdHJpbmdbXSAtIGxpc3Qgb2YgY29tbWFuZCBhcmd1bWVudHMgdGhhdCBtYXkgYXBwZWFyCi0gICAgKiAgICAgICAgICAgICAgICAgICAgYWZ0ZXIgb3B0aW9ucyBhbmQgb3B0aW9uIGFyZ3VtZW50cy4KLSAgICAqIEBwYXJhbXMgbm9uZQotICAgICovCi0gICAgcHVibGljIFN0cmluZ1tdIGdldENtZEFyZ3MoKXsKLSAgICAgICAgU3RyaW5nW10gcmV0dmFsID0gbmV3IFN0cmluZ1t0aGVDbWRBcmdzLnNpemUoKV07Ci0gICAgICAgIGludCBpPTA7Ci0gICAgICAgIGZvcihMaXN0SXRlcmF0b3IgaXQ9dGhlQ21kQXJncy5saXN0SXRlcmF0b3IoKTsgaXQuaGFzTmV4dCgpOyl7Ci0gICAgICAgICAgICByZXR2YWxbaSsrXSA9IChTdHJpbmcpaXQubmV4dCgpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiByZXR2YWw7Ci0gICAgfQotCi0KLSAgICBwcml2YXRlIE9wdGlvbiB0aGVDdXJyZW50T3B0aW9uID0gbnVsbDsKLSAgICBwcml2YXRlIExpc3RJdGVyYXRvciB0aGVPcHRpb25zSXRlcmF0b3I7Ci0gICAgcHJpdmF0ZSBMaXN0IHRoZU9wdGlvbnMgPSBudWxsOwotICAgIHByaXZhdGUgTGlzdCB0aGVDbWRBcmdzID0gbnVsbDsKLSAgICBwcml2YXRlIE9wdGlvbk1hdGNoZXIgdGhlT3B0aW9uTWF0Y2hlciA9IG51bGw7Ci0KLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotICAgIC8vCi0gICAgLy8gICBJbm5lciBDbGFzc2VzCi0gICAgLy8KLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotCi0gICAgLy8gaW5uZXIgY2xhc3MgdG8gbW9kZWwgYW4gb3B0aW9uCi0gICAgY2xhc3MgT3B0aW9uewotICAgICAgICBwcml2YXRlIGNoYXIgdGhlQXJnTGV0dGVyOwotICAgICAgICBwcml2YXRlIFN0cmluZyB0aGVBcmd1bWVudCA9IG51bGw7Ci0gICAgICAgIHB1YmxpYyBPcHRpb24oY2hhciBhcmdMZXR0ZXIpIHsgdGhlQXJnTGV0dGVyID0gYXJnTGV0dGVyOyB9Ci0gICAgICAgIHB1YmxpYyB2b2lkIHNldEFyZyhTdHJpbmcgYXJnKSB7Ci0gICAgICAgICAgICB0aGVBcmd1bWVudCA9IGFyZzsKLSAgICAgICAgfQotICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNBcmcoKSB7IHJldHVybiAodGhlQXJndW1lbnQgIT0gbnVsbCk7IH0KLSAgICAgICAgcHVibGljIGNoYXIgZ2V0QXJnTGV0dGVyKCkgeyByZXR1cm4gdGhlQXJnTGV0dGVyOyB9Ci0gICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0QXJndW1lbnQoKSB7IHJldHVybiB0aGVBcmd1bWVudDsgfQotICAgIH0gLy8gZW5kIGNsYXNzIE9wdGlvbgotCi0KLSAgICAvLyBpbm5lciBjbGFzcyB0byBxdWVyeSBvcHRTdHJpbmcgZm9yIGEgcG9zc2libGUgb3B0aW9uIG1hdGNoLAotICAgIC8vIGFuZCB3aGV0aGVyIG9yIG5vdCBhIGdpdmVuIGxlZ2FsIG9wdGlvbiB0YWtlcyBhbiBhcmd1bWVudC4KLSAgICAvLwotICAgIGNsYXNzIE9wdGlvbk1hdGNoZXJ7Ci0gICAgICAgIHB1YmxpYyBPcHRpb25NYXRjaGVyKFN0cmluZyBvcHRTdHJpbmcpewotICAgICAgICAgICAgdGhlT3B0U3RyaW5nID0gb3B0U3RyaW5nOwotICAgICAgICB9Ci0gICAgICAgIHB1YmxpYyBib29sZWFuIG1hdGNoKGNoYXIgYyl7Ci0gICAgICAgICAgICBib29sZWFuIHJldHZhbCA9IGZhbHNlOwotICAgICAgICAgICAgaWYodGhlT3B0U3RyaW5nLmluZGV4T2YoYykgIT0gLTEpewotICAgICAgICAgICAgICAgIHJldHZhbCA9IHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gcmV0dmFsOwotICAgICAgICB9Ci0gICAgICAgIHB1YmxpYyBib29sZWFuIGhhc0FyZyhjaGFyIGMpewotICAgICAgICAgICAgYm9vbGVhbiByZXR2YWwgPSBmYWxzZTsKLSAgICAgICAgICAgIGludCBpbmRleCA9IHRoZU9wdFN0cmluZy5pbmRleE9mKGMpKzE7Ci0gICAgICAgICAgICBpZiAoaW5kZXggPT0gdGhlT3B0U3RyaW5nLmxlbmd0aCgpKXsKLSAgICAgICAgICAgICAgICAvLyByZWFjaGVkIGVuZCBvZiB0aGVPcHRTdHJpbmcKLSAgICAgICAgICAgICAgICByZXR2YWwgPSBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYodGhlT3B0U3RyaW5nLmNoYXJBdChpbmRleCkgPT0gJzonKXsKLSAgICAgICAgICAgICAgICByZXR2YWwgPSB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIHJldHZhbDsKLSAgICAgICAgfQotICAgICAgICBwcml2YXRlIFN0cmluZyB0aGVPcHRTdHJpbmcgPSBudWxsOwotICAgIH0gLy8gZW5kIGNsYXNzIE9wdGlvbk1hdGNoZXIKLX0vLyBlbmQgY2xhc3MgR2V0T3B0CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NtZGxpbmUvZ2V0b3B0L0dldE9wdHNFeGNlcHRpb24uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY21kbGluZS9nZXRvcHQvR2V0T3B0c0V4Y2VwdGlvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmYWM2MDg5Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY21kbGluZS9nZXRvcHQvR2V0T3B0c0V4Y2VwdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzQgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogR2V0T3B0c0V4Y2VwdGlvbi5qYXZhLHYgMS4yLjQuMSAyMDA1LzA4LzMxIDExOjQ3OjA2IHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jbWRsaW5lLmdldG9wdDsKLQotLyoqCi0gKiBAYXV0aG9yIEcgVG9kZCBNaWxsZXIKLSAqLwotcHVibGljIGNsYXNzIEdldE9wdHNFeGNlcHRpb24gZXh0ZW5kcyBFeGNlcHRpb257Ci0gICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDg3MzY4NzQ5NjcxODMwMzk4MDRMOwotICAgIHB1YmxpYyBHZXRPcHRzRXhjZXB0aW9uKFN0cmluZyBtc2cpewotICAgICAgICBzdXBlcihtc2cpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY21kbGluZS9nZXRvcHQvSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NtZGxpbmUvZ2V0b3B0L0lsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA5MzJmNjFlLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY21kbGluZS9nZXRvcHQvSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzMiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24uamF2YSx2IDEuMi40LjEgMjAwNS8wOC8zMSAxMTo0Nzo1NiBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY21kbGluZS5nZXRvcHQ7Ci0KLQotY2xhc3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4dGVuZHMgR2V0T3B0c0V4Y2VwdGlvbnsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gODY0MjEyMjQyNzI5NDc5MzY1MUw7Ci0gICAgcHVibGljIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihTdHJpbmcgbXNnKXsKLSAgICAgICAgc3VwZXIobXNnKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NtZGxpbmUvZ2V0b3B0L01pc3NpbmdPcHRBcmdFeGNlcHRpb24uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY21kbGluZS9nZXRvcHQvTWlzc2luZ09wdEFyZ0V4Y2VwdGlvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjNWU5OWI2Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY21kbGluZS9nZXRvcHQvTWlzc2luZ09wdEFyZ0V4Y2VwdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzUgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogTWlzc2luZ09wdEFyZ0V4Y2VwdGlvbi5qYXZhLHYgMS4yLjQuMSAyMDA1LzA4LzMxIDExOjQ5OjIxIHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jbWRsaW5lLmdldG9wdDsKLQotCi0vKioKLSAqIEBhdXRob3IgRyBUb2RkIE1pbGxlcgotICovCi1jbGFzcyBNaXNzaW5nT3B0QXJnRXhjZXB0aW9uIGV4dGVuZHMgR2V0T3B0c0V4Y2VwdGlvbnsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTE5NzI0NzE0NjUzOTQ1NDQ4MjJMOwotICAgIHB1YmxpYyBNaXNzaW5nT3B0QXJnRXhjZXB0aW9uKFN0cmluZyBtc2cpewotICAgICAgICBzdXBlcihtc2cpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvQWJzb2x1dGVMb2NhdGlvblBhdGguamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvQWJzb2x1dGVMb2NhdGlvblBhdGguamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOGJmZTZjYi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0Fic29sdXRlTG9jYXRpb25QYXRoLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMzAgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogQWJzb2x1dGVMb2NhdGlvblBhdGguamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xMiAwOTo0NDowMyBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkFMT0FEOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQVNUT1JFOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQ29uc3RhbnRQb29sR2VuOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFSU5URVJGQUNFOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFU1BFQ0lBTDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uTGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkxvY2FsVmFyaWFibGVHZW47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5ORVc7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuQ2xhc3NHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuTWV0aG9kR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLk5vZGVUeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZUNoZWNrRXJyb3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVXRpbDsKLQotLyoqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKi8KLWZpbmFsIGNsYXNzIEFic29sdXRlTG9jYXRpb25QYXRoIGV4dGVuZHMgRXhwcmVzc2lvbiB7Ci0gICAgcHJpdmF0ZSBFeHByZXNzaW9uIF9wYXRoOyAgIC8vIG1heSBiZSBudWxsCi0KLSAgICBwdWJsaWMgQWJzb2x1dGVMb2NhdGlvblBhdGgoKSB7Ci0gICAgICAgIF9wYXRoID0gbnVsbDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgQWJzb2x1dGVMb2NhdGlvblBhdGgoRXhwcmVzc2lvbiBwYXRoKSB7Ci0gICAgICAgIF9wYXRoID0gcGF0aDsKLSAgICAgICAgaWYgKHBhdGggIT0gbnVsbCkgewotICAgICAgICAgICAgX3BhdGguc2V0UGFyZW50KHRoaXMpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0UGFyc2VyKFBhcnNlciBwYXJzZXIpIHsKLSAgICAgICAgc3VwZXIuc2V0UGFyc2VyKHBhcnNlcik7Ci0gICAgICAgIGlmIChfcGF0aCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBfcGF0aC5zZXRQYXJzZXIocGFyc2VyKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyBFeHByZXNzaW9uIGdldFBhdGgoKSB7Ci0gICAgICAgIHJldHVybihfcGF0aCk7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKLSAgICAgICAgcmV0dXJuICJBYnNvbHV0ZUxvY2F0aW9uUGF0aCgiICsKLSAgICAgICAgICAgIChfcGF0aCAhPSBudWxsID8gX3BhdGgudG9TdHJpbmcoKSA6ICJudWxsIikgKyAnKSc7Ci0gICAgfQotCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLSAgICAgICAgaWYgKF9wYXRoICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZpbmFsIFR5cGUgcHR5cGUgPSBfcGF0aC50eXBlQ2hlY2soc3RhYmxlKTsKLSAgICAgICAgICAgIGlmIChwdHlwZSBpbnN0YW5jZW9mIE5vZGVUeXBlKSB7ICAgICAgICAgICAgLy8gcHJvbW90ZSB0byBub2RlLXNldAotICAgICAgICAgICAgICAgIF9wYXRoID0gbmV3IENhc3RFeHByKF9wYXRoLCBUeXBlLk5vZGVTZXQpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBfdHlwZSA9IFR5cGUuTm9kZVNldDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLSAgICAgICAgZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0gICAgICAgIGlmIChfcGF0aCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmaW5hbCBpbnQgaW5pdEFJID0gY3BnLmFkZE1ldGhvZHJlZihBQlNPTFVURV9JVEVSQVRPUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI8aW5pdD4iLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIigiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIE5PREVfSVRFUkFUT1JfU0lHCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIpViIpOwotCi0gICAgICAgICAgICAvLyBDb21waWxlIHJlbGF0aXZlIHBhdGggaXRlcmF0b3IocykKLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAvLyBCYWNrd2FyZHMgYnJhbmNoZXMgYXJlIHByb2hpYml0ZWQgaWYgYW4gdW5pbml0aWFsaXplZCBvYmplY3QgaXMKLSAgICAgICAgICAgIC8vIG9uIHRoZSBzdGFjayBieSBzZWN0aW9uIDQuOS40IG9mIHRoZSBKVk0gU3BlY2lmaWNhdGlvbiwgMm5kIEVkLgotICAgICAgICAgICAgLy8gV2UgZG9uJ3Qga25vdyB3aGV0aGVyIHRoaXMgY29kZSBtaWdodCBjb250YWluIGJhY2t3YXJkcyBicmFuY2hlcywKLSAgICAgICAgICAgIC8vIHNvIHdlIG11c3RuJ3QgY3JlYXRlIHRoZSBuZXcgb2JqZWN0IHVudGlsIGFmdGVyIHdlJ3ZlIGNyZWF0ZWQKLSAgICAgICAgICAgIC8vIHRoaXMgYXJndW1lbnQgdG8gaXRzIGNvbnN0cnVjdG9yLiAgSW5zdGVhZCB3ZSBjYWxjdWxhdGUgdGhlCi0gICAgICAgICAgICAvLyB2YWx1ZSBvZiB0aGUgYXJndW1lbnQgdG8gdGhlIGNvbnN0cnVjdG9yIGZpcnN0LCBzdG9yZSBpdCBpbgotICAgICAgICAgICAgLy8gYSB0ZW1wb3JhcnkgdmFyaWFibGUsIGNyZWF0ZSB0aGUgb2JqZWN0IGFuZCByZWxvYWQgdGhlIGFyZ3VtZW50Ci0gICAgICAgICAgICAvLyBmcm9tIHRoZSB0ZW1wb3JhcnkgdG8gYXZvaWQgdGhlIHByb2JsZW0uCi0gICAgICAgICAgICBfcGF0aC50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgICAgICBMb2NhbFZhcmlhYmxlR2VuIHJlbFBhdGhJdGVyYXRvcgotICAgICAgICAgICAgICAgICAgICA9IG1ldGhvZEdlbi5hZGRMb2NhbFZhcmlhYmxlKCJhYnNfbG9jYXRpb25fcGF0aF90bXAiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVXRpbC5nZXRKQ1JlZlR5cGUoTk9ERV9JVEVSQVRPUl9TSUcpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwgbnVsbCk7Ci0gICAgICAgICAgICByZWxQYXRoSXRlcmF0b3Iuc2V0U3RhcnQoCi0gICAgICAgICAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgQVNUT1JFKHJlbFBhdGhJdGVyYXRvci5nZXRJbmRleCgpKSkpOwotCi0gICAgICAgICAgICAvLyBDcmVhdGUgbmV3IEFic29sdXRlSXRlcmF0b3IKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgTkVXKGNwZy5hZGRDbGFzcyhBQlNPTFVURV9JVEVSQVRPUikpKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChEVVApOwotICAgICAgICAgICAgcmVsUGF0aEl0ZXJhdG9yLnNldEVuZCgKLSAgICAgICAgICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBBTE9BRChyZWxQYXRoSXRlcmF0b3IuZ2V0SW5kZXgoKSkpKTsKLQotICAgICAgICAgICAgLy8gSW5pdGlhbGl6ZSBBYnNvbHV0ZUl0ZXJhdG9yIHdpdGggaXRlcmF0b3IgZnJvbSB0aGUgc3RhY2sKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFU1BFQ0lBTChpbml0QUkpKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIGZpbmFsIGludCBnaXRyID0gY3BnLmFkZEludGVyZmFjZU1ldGhvZHJlZihET01fSU5URiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZ2V0SXRlcmF0b3IiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoKSIrTk9ERV9JVEVSQVRPUl9TSUcpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkRE9NKCkpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0UoZ2l0ciwgMSkpOwotICAgICAgICB9Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9BYnNvbHV0ZVBhdGhQYXR0ZXJuLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0Fic29sdXRlUGF0aFBhdHRlcm4uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYzI1YmFlNC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0Fic29sdXRlUGF0aFBhdHRlcm4uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE0MiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBBYnNvbHV0ZVBhdGhQYXR0ZXJuLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMDEgMDk6MTc6MDkgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5CcmFuY2hIYW5kbGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5Db25zdGFudFBvb2xHZW47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5HT1RPX1c7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JRl9JQ01QRVE7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JTE9BRDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklOVk9LRUlOVEVSRkFDRTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklTVE9SRTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uSGFuZGxlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW5zdHJ1Y3Rpb25MaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuTG9jYWxWYXJpYWJsZUdlbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlBVU0g7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuQ2xhc3NHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuTWV0aG9kR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZUNoZWNrRXJyb3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVXRpbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE07Ci0KLS8qKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICovCi1maW5hbCBjbGFzcyBBYnNvbHV0ZVBhdGhQYXR0ZXJuIGV4dGVuZHMgTG9jYXRpb25QYXRoUGF0dGVybiB7Ci0gICAgcHJpdmF0ZSBmaW5hbCBSZWxhdGl2ZVBhdGhQYXR0ZXJuIF9sZWZ0OyAvLyBtYXkgYmUgbnVsbAotCi0gICAgcHVibGljIEFic29sdXRlUGF0aFBhdHRlcm4oUmVsYXRpdmVQYXRoUGF0dGVybiBsZWZ0KSB7Ci0gICAgICAgIF9sZWZ0ID0gbGVmdDsKLSAgICAgICAgaWYgKGxlZnQgIT0gbnVsbCkgewotICAgICAgICAgICAgbGVmdC5zZXRQYXJlbnQodGhpcyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRQYXJzZXIoUGFyc2VyIHBhcnNlcikgewotICAgICAgICBzdXBlci5zZXRQYXJzZXIocGFyc2VyKTsKLSAgICAgICAgaWYgKF9sZWZ0ICE9IG51bGwpCi0gICAgICAgICAgICBfbGVmdC5zZXRQYXJzZXIocGFyc2VyKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgVHlwZSB0eXBlQ2hlY2soU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgewotICAgICAgICByZXR1cm4gX2xlZnQgPT0gbnVsbCA/IFR5cGUuUm9vdCA6IF9sZWZ0LnR5cGVDaGVjayhzdGFibGUpOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGlzV2lsZGNhcmQoKSB7Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RlcFBhdHRlcm4gZ2V0S2VybmVsUGF0dGVybigpIHsKLSAgICAgICAgcmV0dXJuIF9sZWZ0ICE9IG51bGwgPyBfbGVmdC5nZXRLZXJuZWxQYXR0ZXJuKCkgOiBudWxsOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHJlZHVjZUtlcm5lbFBhdHRlcm4oKSB7Ci0gICAgICAgIF9sZWZ0LnJlZHVjZUtlcm5lbFBhdHRlcm4oKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLSAgICAgICAgZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0KLSAgICAgICAgaWYgKF9sZWZ0ICE9IG51bGwpIHsKLSAgICAgICAgICAgIGlmIChfbGVmdCBpbnN0YW5jZW9mIFN0ZXBQYXR0ZXJuKSB7Ci0gICAgICAgICAgICAgICAgZmluYWwgTG9jYWxWYXJpYWJsZUdlbiBsb2NhbCA9Ci0gICAgICAgICAgICAgICAgICAgIC8vIGFic29sdXRlIHBhdGggcGF0dGVybiB0ZW1wb3JhcnkKLSAgICAgICAgICAgICAgICAgICAgbWV0aG9kR2VuLmFkZExvY2FsVmFyaWFibGUyKCJhcHB0bXAiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVXRpbC5nZXRKQ1JlZlR5cGUoTk9ERV9TSUcpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCk7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKERVUCk7Ci0gICAgICAgICAgICAgICAgbG9jYWwuc2V0U3RhcnQoaWwuYXBwZW5kKG5ldyBJU1RPUkUobG9jYWwuZ2V0SW5kZXgoKSkpKTsKLSAgICAgICAgICAgICAgICBfbGVmdC50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkRE9NKCkpOwotICAgICAgICAgICAgICAgIGxvY2FsLnNldEVuZChpbC5hcHBlbmQobmV3IElMT0FEKGxvY2FsLmdldEluZGV4KCkpKSk7Ci0gICAgICAgICAgICAgICAgbWV0aG9kR2VuLnJlbW92ZUxvY2FsVmFyaWFibGUobG9jYWwpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgX2xlZnQudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgZmluYWwgaW50IGdldFBhcmVudCA9IGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoRE9NX0lOVEYsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdFVF9QQVJFTlQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdFVF9QQVJFTlRfU0lHKTsKLSAgICAgICAgZmluYWwgaW50IGdldFR5cGUgPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKERPTV9JTlRGLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImdldEV4cGFuZGVkVHlwZUlEIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoSSlJIik7Ci0KLSAgICAgICAgSW5zdHJ1Y3Rpb25IYW5kbGUgYmVnaW4gPSBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0gICAgICAgIGlsLmFwcGVuZChTV0FQKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0UoZ2V0UGFyZW50LCAyKSk7Ci0gICAgICAgIGlmIChfbGVmdCBpbnN0YW5jZW9mIEFuY2VzdG9yUGF0dGVybikgewotICAgICAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkRE9NKCkpOwotICAgICAgICAgICAgaWwuYXBwZW5kKFNXQVApOwotICAgICAgICB9Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFSU5URVJGQUNFKGdldFR5cGUsIDIpKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgRFRNLkRPQ1VNRU5UX05PREUpKTsKLQotICAgICAgICBmaW5hbCBCcmFuY2hIYW5kbGUgc2tpcCA9IGlsLmFwcGVuZChuZXcgSUZfSUNNUEVRKG51bGwpKTsKLSAgICAgICAgX2ZhbHNlTGlzdC5hZGQoaWwuYXBwZW5kKG5ldyBHT1RPX1cobnVsbCkpKTsKLSAgICAgICAgc2tpcC5zZXRUYXJnZXQoaWwuYXBwZW5kKE5PUCkpOwotCi0gICAgICAgIGlmIChfbGVmdCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBfbGVmdC5iYWNrUGF0Y2hUcnVlTGlzdChiZWdpbik7Ci0KLSAgICAgICAgICAgIC8qCi0gICAgICAgICAgICAgKiBJZiBfbGVmdCBpcyBhbiBhbmNlc3RvciBwYXR0ZXJuLCBiYWNrcGF0Y2ggdGhpcyBwYXR0ZXJuJ3MgZmFsc2UKLSAgICAgICAgICAgICAqIGxpc3QgdG8gdGhlIGxvb3AgdGhhdCBzZWFyY2hlcyBmb3IgbW9yZSBhbmNlc3RvcnMuCi0gICAgICAgICAgICAgKi8KLSAgICAgICAgICAgIGlmIChfbGVmdCBpbnN0YW5jZW9mIEFuY2VzdG9yUGF0dGVybikgewotICAgICAgICAgICAgICAgIGZpbmFsIEFuY2VzdG9yUGF0dGVybiBhbmNlc3RvciA9IChBbmNlc3RvclBhdHRlcm4pIF9sZWZ0OwotICAgICAgICAgICAgICAgIF9mYWxzZUxpc3QuYmFja1BhdGNoKGFuY2VzdG9yLmdldExvb3BIYW5kbGUoKSk7ICAgICAgICAgLy8gY2xlYXJzIGxpc3QKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIF9mYWxzZUxpc3QuYXBwZW5kKF9sZWZ0Ll9mYWxzZUxpc3QpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKLSAgICAgICAgcmV0dXJuICJhYnNvbHV0ZVBhdGhQYXR0ZXJuKCIgKyAoX2xlZnQgIT0gbnVsbCA/IF9sZWZ0LnRvU3RyaW5nKCkgOiAiKSIpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvQWx0ZXJuYXRpdmVQYXR0ZXJuLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0FsdGVybmF0aXZlUGF0dGVybi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3YWRjYjQ4Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvQWx0ZXJuYXRpdmVQYXR0ZXJuLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMDIgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogQWx0ZXJuYXRpdmVQYXR0ZXJuLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMDEgMDk6MTg6NDYgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5HT1RPOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW5zdHJ1Y3Rpb25IYW5kbGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JbnN0cnVjdGlvbkxpc3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuQ2xhc3NHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuTWV0aG9kR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZUNoZWNrRXJyb3I7Ci0KLS8qKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICovCi1maW5hbCBjbGFzcyBBbHRlcm5hdGl2ZVBhdHRlcm4gZXh0ZW5kcyBQYXR0ZXJuIHsKLSAgICBwcml2YXRlIGZpbmFsIFBhdHRlcm4gX2xlZnQ7Ci0gICAgcHJpdmF0ZSBmaW5hbCBQYXR0ZXJuIF9yaWdodDsKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdCBhbiBhbHRlcm5hdGl2ZSBwYXR0ZXJuLiBUaGUgbWV0aG9kIDxjb2RlPnNldFBhcmVudDwvY29kZT4KLSAgICAgKiBzaG91bGQgbm90IGJlIGNhbGxlZCBpbiB0aGlzIGNhc2UuCi0gICAgICovCi0gICAgcHVibGljIEFsdGVybmF0aXZlUGF0dGVybihQYXR0ZXJuIGxlZnQsIFBhdHRlcm4gcmlnaHQpIHsKLSAgICAgICAgX2xlZnQgPSBsZWZ0OwotICAgICAgICBfcmlnaHQgPSByaWdodDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRQYXJzZXIoUGFyc2VyIHBhcnNlcikgewotICAgICAgICBzdXBlci5zZXRQYXJzZXIocGFyc2VyKTsKLSAgICAgICAgX2xlZnQuc2V0UGFyc2VyKHBhcnNlcik7Ci0gICAgICAgIF9yaWdodC5zZXRQYXJzZXIocGFyc2VyKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgUGF0dGVybiBnZXRMZWZ0KCkgewotICAgICAgICByZXR1cm4gX2xlZnQ7Ci0gICAgfQotCi0gICAgcHVibGljIFBhdHRlcm4gZ2V0UmlnaHQoKSB7Ci0gICAgICAgIHJldHVybiBfcmlnaHQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhlIHR5cGUgb2YgYW4gJ3wnIGlzIG5vdCByZWFsbHkgZGVmaW5lZCwgaGVuY2UgbnVsbCBpcyByZXR1cm5lZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgVHlwZSB0eXBlQ2hlY2soU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgewotICAgICAgICBfbGVmdC50eXBlQ2hlY2soc3RhYmxlKTsKLSAgICAgICAgX3JpZ2h0LnR5cGVDaGVjayhzdGFibGUpOwotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgZG91YmxlIGdldFByaW9yaXR5KCkgewotICAgICAgICBkb3VibGUgbGVmdCA9IF9sZWZ0LmdldFByaW9yaXR5KCk7Ci0gICAgICAgIGRvdWJsZSByaWdodCA9IF9yaWdodC5nZXRQcmlvcml0eSgpOwotCi0gICAgICAgIGlmIChsZWZ0IDwgcmlnaHQpCi0gICAgICAgICAgICByZXR1cm4obGVmdCk7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICAgIHJldHVybihyaWdodCk7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKLSAgICAgICAgcmV0dXJuICJhbHRlcm5hdGl2ZSgiICsgX2xlZnQgKyAiLCAiICsgX3JpZ2h0ICsgJyknOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0KLSAgICAgICAgX2xlZnQudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkhhbmRsZSBnb3RvdCA9IGlsLmFwcGVuZChuZXcgR09UTyhudWxsKSk7Ci0gICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZENvbnRleHROb2RlKCkpOwotICAgICAgICBfcmlnaHQudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCi0gICAgICAgIF9sZWZ0Ll90cnVlTGlzdC5iYWNrUGF0Y2goZ290b3QpOwotICAgICAgICBfbGVmdC5fZmFsc2VMaXN0LmJhY2tQYXRjaChnb3RvdC5nZXROZXh0KCkpOwotCi0gICAgICAgIF90cnVlTGlzdC5hcHBlbmQoX3JpZ2h0Ll90cnVlTGlzdC5hZGQoZ290b3QpKTsKLSAgICAgICAgX2ZhbHNlTGlzdC5hcHBlbmQoX3JpZ2h0Ll9mYWxzZUxpc3QpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvQW5jZXN0b3JQYXR0ZXJuLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0FuY2VzdG9yUGF0dGVybi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxMGJmYTdkLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvQW5jZXN0b3JQYXR0ZXJuLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxODQgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogQW5jZXN0b3JQYXR0ZXJuLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMDEgMDk6MTk6NDEgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5CcmFuY2hIYW5kbGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5Db25zdGFudFBvb2xHZW47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5HT1RPOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSUZMVDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklMT0FEOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFSU5URVJGQUNFOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSVNUT1JFOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW5zdHJ1Y3Rpb25IYW5kbGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JbnN0cnVjdGlvbkxpc3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5Mb2NhbFZhcmlhYmxlR2VuOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkNsYXNzR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLk1ldGhvZEdlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGVDaGVja0Vycm9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlV0aWw7Ci0KLS8qKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICogQGF1dGhvciBFcndpbiBCb2x3aWR0IDxlamJAa2xvbXAub3JnPgotICovCi1maW5hbCBjbGFzcyBBbmNlc3RvclBhdHRlcm4gZXh0ZW5kcyBSZWxhdGl2ZVBhdGhQYXR0ZXJuIHsKLQotICAgIHByaXZhdGUgZmluYWwgUGF0dGVybiBfbGVmdDsgICAgICAgIC8vIG1heSBiZSBudWxsCi0gICAgcHJpdmF0ZSBmaW5hbCBSZWxhdGl2ZVBhdGhQYXR0ZXJuIF9yaWdodDsKLSAgICBwcml2YXRlIEluc3RydWN0aW9uSGFuZGxlIF9sb29wOwotCi0gICAgcHVibGljIEFuY2VzdG9yUGF0dGVybihSZWxhdGl2ZVBhdGhQYXR0ZXJuIHJpZ2h0KSB7Ci0gICAgICAgIHRoaXMobnVsbCwgcmlnaHQpOwotICAgIH0KLQotICAgIHB1YmxpYyBBbmNlc3RvclBhdHRlcm4oUGF0dGVybiBsZWZ0LCBSZWxhdGl2ZVBhdGhQYXR0ZXJuIHJpZ2h0KSB7Ci0gICAgICAgIF9sZWZ0ID0gbGVmdDsKLSAgICAgICAgKF9yaWdodCA9IHJpZ2h0KS5zZXRQYXJlbnQodGhpcyk7Ci0gICAgICAgIGlmIChsZWZ0ICE9IG51bGwpIHsKLSAgICAgICAgICAgIGxlZnQuc2V0UGFyZW50KHRoaXMpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIEluc3RydWN0aW9uSGFuZGxlIGdldExvb3BIYW5kbGUoKSB7Ci0gICAgICAgIHJldHVybiBfbG9vcDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRQYXJzZXIoUGFyc2VyIHBhcnNlcikgewotICAgICAgICBzdXBlci5zZXRQYXJzZXIocGFyc2VyKTsKLSAgICAgICAgaWYgKF9sZWZ0ICE9IG51bGwpIHsKLSAgICAgICAgICAgIF9sZWZ0LnNldFBhcnNlcihwYXJzZXIpOwotICAgICAgICB9Ci0gICAgICAgIF9yaWdodC5zZXRQYXJzZXIocGFyc2VyKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBpc1dpbGRjYXJkKCkgewotICAgICAgICAvLyEhISBjYW4gYmUgd2lsZGNhcmQKLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIHB1YmxpYyBTdGVwUGF0dGVybiBnZXRLZXJuZWxQYXR0ZXJuKCkgewotICAgICAgICByZXR1cm4gX3JpZ2h0LmdldEtlcm5lbFBhdHRlcm4oKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCByZWR1Y2VLZXJuZWxQYXR0ZXJuKCkgewotICAgICAgICBfcmlnaHQucmVkdWNlS2VybmVsUGF0dGVybigpOwotICAgIH0KLQotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0gICAgICAgIGlmIChfbGVmdCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBfbGVmdC50eXBlQ2hlY2soc3RhYmxlKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gX3JpZ2h0LnR5cGVDaGVjayhzdGFibGUpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotICAgICAgICBJbnN0cnVjdGlvbkhhbmRsZSBwYXJlbnQ7Ci0gICAgICAgIGZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCi0gICAgICAgIC8qCi0gICAgICAgICAqIFRoZSBzY29wZSBvZiB0aGlzIGxvY2FsIHZhciBtdXN0IGJlIHRoZSBlbnRpcmUgbWV0aG9kIHNpbmNlCi0gICAgICAgICAqIGEgYW5vdGhlciBwYXR0ZXJuIG1heSBkZWNpZGUgdG8ganVtcCBiYWNrIGludG8gdGhlIGxvb3AKLSAgICAgICAgICovCi0gICAgICAgIGZpbmFsIExvY2FsVmFyaWFibGVHZW4gbG9jYWwgPQotICAgICAgICAgICAgbWV0aG9kR2VuLmFkZExvY2FsVmFyaWFibGUyKCJhcHAiLCBVdGlsLmdldEpDUmVmVHlwZShOT0RFX1NJRyksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWwuZ2V0RW5kKCkpOwotCi0gICAgICAgIGZpbmFsIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW5zdHJ1Y3Rpb24gbG9hZExvY2FsID0KLSAgICAgICAgICAgIG5ldyBJTE9BRChsb2NhbC5nZXRJbmRleCgpKTsKLSAgICAgICAgZmluYWwgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JbnN0cnVjdGlvbiBzdG9yZUxvY2FsID0KLSAgICAgICAgICAgIG5ldyBJU1RPUkUobG9jYWwuZ2V0SW5kZXgoKSk7Ci0KLSAgICAgICAgaWYgKF9yaWdodCBpbnN0YW5jZW9mIFN0ZXBQYXR0ZXJuKSB7Ci0gICAgICAgICAgICBpbC5hcHBlbmQoRFVQKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChzdG9yZUxvY2FsKTsKLSAgICAgICAgICAgIF9yaWdodC50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobG9hZExvY2FsKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIF9yaWdodC50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0KLSAgICAgICAgICAgIGlmIChfcmlnaHQgaW5zdGFuY2VvZiBBbmNlc3RvclBhdHRlcm4pIHsKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKFNXQVApOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKF9sZWZ0ICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZpbmFsIGludCBnZXRQYXJlbnQgPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKERPTV9JTlRGLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR0VUX1BBUkVOVCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdFVF9QQVJFTlRfU0lHKTsKLSAgICAgICAgICAgIHBhcmVudCA9IGlsLmFwcGVuZChuZXcgSU5WT0tFSU5URVJGQUNFKGdldFBhcmVudCwgMikpOwotCi0gICAgICAgICAgICBpbC5hcHBlbmQoRFVQKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChzdG9yZUxvY2FsKTsKLSAgICAgICAgICAgIF9mYWxzZUxpc3QuYWRkKGlsLmFwcGVuZChuZXcgSUZMVChudWxsKSkpOwotICAgICAgICAgICAgaWwuYXBwZW5kKGxvYWRMb2NhbCk7Ci0KLSAgICAgICAgICAgIF9sZWZ0LnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQotICAgICAgICAgICAgZmluYWwgU3ludGF4VHJlZU5vZGUgcCA9IGdldFBhcmVudCgpOwotICAgICAgICAgICAgaWYgKHAgPT0gbnVsbCB8fCBwIGluc3RhbmNlb2YgSW5zdHJ1Y3Rpb24gfHwKLSAgICAgICAgICAgICAgICBwIGluc3RhbmNlb2YgVG9wTGV2ZWxFbGVtZW50KQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIC8vIGRvIG5vdGhpbmcKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChsb2FkTG9jYWwpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBmaW5hbCBCcmFuY2hIYW5kbGUgZXhpdCA9IGlsLmFwcGVuZChuZXcgR09UTyhudWxsKSk7Ci0gICAgICAgICAgICBfbG9vcCA9IGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChsb2FkTG9jYWwpOwotICAgICAgICAgICAgbG9jYWwuc2V0RW5kKF9sb29wKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgR09UTyhwYXJlbnQpKTsKLSAgICAgICAgICAgIGV4aXQuc2V0VGFyZ2V0KGlsLmFwcGVuZChOT1ApKTsKLSAgICAgICAgICAgIF9sZWZ0LmJhY2tQYXRjaEZhbHNlTGlzdChfbG9vcCk7Ci0KLSAgICAgICAgICAgIF90cnVlTGlzdC5hcHBlbmQoX2xlZnQuX3RydWVMaXN0KTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIGlsLmFwcGVuZChQT1AyKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8qCi0gICAgICAgICAqIElmIF9yaWdodCBpcyBhbiBhbmNlc3RvciBwYXR0ZXJuLCBiYWNrcGF0Y2ggdGhpcyBwYXR0ZXJuJ3MgZmFsc2UKLSAgICAgICAgICogbGlzdCB0byB0aGUgbG9vcCB0aGF0IHNlYXJjaGVzIGZvciBtb3JlIGFuY2VzdG9ycy4KLSAgICAgICAgICovCi0gICAgICAgIGlmIChfcmlnaHQgaW5zdGFuY2VvZiBBbmNlc3RvclBhdHRlcm4pIHsKLSAgICAgICAgICAgIGZpbmFsIEFuY2VzdG9yUGF0dGVybiBhbmNlc3RvciA9IChBbmNlc3RvclBhdHRlcm4pIF9yaWdodDsKLSAgICAgICAgICAgIF9mYWxzZUxpc3QuYmFja1BhdGNoKGFuY2VzdG9yLmdldExvb3BIYW5kbGUoKSk7ICAgIC8vIGNsZWFycyBsaXN0Ci0gICAgICAgIH0KLQotICAgICAgICBfdHJ1ZUxpc3QuYXBwZW5kKF9yaWdodC5fdHJ1ZUxpc3QpOwotICAgICAgICBfZmFsc2VMaXN0LmFwcGVuZChfcmlnaHQuX2ZhbHNlTGlzdCk7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKLSAgICAgICAgcmV0dXJuICJBbmNlc3RvclBhdHRlcm4oIiArIF9sZWZ0ICsgIiwgIiArIF9yaWdodCArICcpJzsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0FwcGx5SW1wb3J0cy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9BcHBseUltcG9ydHMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggY2ViYTU2OC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0FwcGx5SW1wb3J0cy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTYxICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IEFwcGx5SW1wb3J0cy5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzEzIDEyOjIyOjAyIHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQ29uc3RhbnRQb29sR2VuOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFU1BFQ0lBTDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklOVk9LRVZJUlRVQUw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JbnN0cnVjdGlvbkxpc3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5ORVc7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuQ2xhc3NHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuTWV0aG9kR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZUNoZWNrRXJyb3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVXRpbDsKLQotZmluYWwgY2xhc3MgQXBwbHlJbXBvcnRzIGV4dGVuZHMgSW5zdHJ1Y3Rpb24gewotCi0gICAgcHJpdmF0ZSBRTmFtZSAgICAgIF9tb2RlTmFtZTsKLSAgICBwcml2YXRlIGludCAgICAgICAgX3ByZWNlZGVuY2U7Ci0KLSAgICBwdWJsaWMgdm9pZCBkaXNwbGF5KGludCBpbmRlbnQpIHsKLSAgICAgICAgaW5kZW50KGluZGVudCk7Ci0gICAgICAgIFV0aWwucHJpbnRsbigiQXBwbHlUZW1wbGF0ZXMiKTsKLSAgICAgICAgaW5kZW50KGluZGVudCArIEluZGVudEluY3JlbWVudCk7Ci0gICAgICAgIGlmIChfbW9kZU5hbWUgIT0gbnVsbCkgewotICAgICAgICAgICAgaW5kZW50KGluZGVudCArIEluZGVudEluY3JlbWVudCk7Ci0gICAgICAgICAgICBVdGlsLnByaW50bG4oIm1vZGUgIiArIF9tb2RlTmFtZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhpcyA8eHNsOmFwcGx5LWltcG9ydHMvPiBlbGVtZW50IGhhcyBwYXJhbWV0ZXJzCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaGFzV2l0aFBhcmFtcygpIHsKLSAgICAgICAgcmV0dXJuIGhhc0NvbnRlbnRzKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRGV0ZXJtaW5lIHRoZSBsb3dlc3QgaW1wb3J0IHByZWNlZGVuY2UgZm9yIGFueSBzdHlsZXNoZWV0IGltcG9ydGVkCi0gICAgICogb3IgaW5jbHVkZWQgYnkgdGhlIHN0eWxlc2hlZXQgaW4gd2hpY2ggdGhpcyA8eHNsOmFwcGx5LWltcG9ydHMvPgotICAgICAqIGVsZW1lbnQgb2NjdXJlZC4gVGhlIHRlbXBsYXRlcyB0aGF0IGFyZSBpbXBvcnRlZCBieSB0aGUgc3R5bGVzaGVldCBpbgotICAgICAqIHdoaWNoIHRoaXMgZWxlbWVudCBvY2N1cmVkIHdpbGwgYWxsIGhhdmUgaGlnaGVyIGltcG9ydCBwcmVjZWRlbmNlIHRoYW4KLSAgICAgKiB0aGUgaW50ZWdlciByZXR1cm5lZCBieSB0aGlzIG1ldGhvZC4KLSAgICAgKi8KLSAgICBwcml2YXRlIGludCBnZXRNaW5QcmVjZWRlbmNlKGludCBtYXgpIHsKLSAgICAgICAgLy8gTW92ZSB0byByb290IG9mIGluY2x1ZGUgdHJlZQotICAgICAgICBTdHlsZXNoZWV0IGluY2x1ZGVSb290ID0gZ2V0U3R5bGVzaGVldCgpOwotICAgICAgICB3aGlsZSAoaW5jbHVkZVJvb3QuX2luY2x1ZGVkRnJvbSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpbmNsdWRlUm9vdCA9IGluY2x1ZGVSb290Ll9pbmNsdWRlZEZyb207Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gaW5jbHVkZVJvb3QuZ2V0TWluaW11bURlc2NlbmRhbnRQcmVjZWRlbmNlKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUGFyc2UgdGhlIGF0dHJpYnV0ZXMgYW5kIGNvbnRlbnRzIG9mIGFuIDx4c2w6YXBwbHktaW1wb3J0cy8+IGVsZW1lbnQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcGFyc2VDb250ZW50cyhQYXJzZXIgcGFyc2VyKSB7Ci0gICAgICAgIC8vIEluZGljYXRlIHRvIHRoZSB0b3AtbGV2ZWwgc3R5bGVzaGVldCB0aGF0IGFsbCB0ZW1wbGF0ZXMgbXVzdCBiZQotICAgICAgICAvLyBjb21waWxlZCBpbnRvIHNlcGFyYXRlIG1ldGhvZHMuCi0gICAgICAgIFN0eWxlc2hlZXQgc3R5bGVzaGVldCA9IGdldFN0eWxlc2hlZXQoKTsKLSAgICAgICAgc3R5bGVzaGVldC5zZXRUZW1wbGF0ZUlubGluaW5nKGZhbHNlKTsKLQotICAgICAgICAvLyBHZXQgdGhlIG1vZGUgd2UgYXJlIGN1cnJlbnRseSBpbiAobWlnaHQgbm90IGJlIGFueSkKLSAgICAgICAgVGVtcGxhdGUgdGVtcGxhdGUgPSBnZXRUZW1wbGF0ZSgpOwotICAgICAgICBfbW9kZU5hbWUgPSB0ZW1wbGF0ZS5nZXRNb2RlTmFtZSgpOwotICAgICAgICBfcHJlY2VkZW5jZSA9IHRlbXBsYXRlLmdldEltcG9ydFByZWNlZGVuY2UoKTsKLQotICAgICAgICAvLyBHZXQgdGhlIG1ldGhvZCBuYW1lIGZvciA8eHNsOmFwcGx5LWltcG9ydHMvPiBpbiB0aGlzIG1vZGUKLSAgICAgICAgc3R5bGVzaGVldCA9IHBhcnNlci5nZXRUb3BMZXZlbFN0eWxlc2hlZXQoKTsKLQotICAgICAgICBwYXJzZUNoaWxkcmVuKHBhcnNlcik7ICAvLyB3aXRoLXBhcmFtcwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFR5cGUtY2hlY2sgdGhlIGF0dHJpYnV0ZXMvY29udGVudHMgb2YgYW4gPHhzbDphcHBseS1pbXBvcnRzLz4gZWxlbWVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgVHlwZSB0eXBlQ2hlY2soU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgewotICAgICAgICB0eXBlQ2hlY2tDb250ZW50cyhzdGFibGUpOyAgICAgICAgICAgICAgLy8gd2l0aC1wYXJhbXMKLSAgICAgICAgcmV0dXJuIFR5cGUuVm9pZDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGUgY2FsbC10ZW1wbGF0ZS4gQSBwYXJhbWV0ZXIgZnJhbWUgaXMgcHVzaGVkIG9ubHkgaWYKLSAgICAgKiBzb21lIHRlbXBsYXRlIGluIHRoZSBzdHlsZXNoZWV0IHVzZXMgcGFyYW1ldGVycy4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLSAgICAgICAgZmluYWwgU3R5bGVzaGVldCBzdHlsZXNoZWV0ID0gY2xhc3NHZW4uZ2V0U3R5bGVzaGVldCgpOwotICAgICAgICBmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLSAgICAgICAgZmluYWwgaW50IGN1cnJlbnQgPSBtZXRob2RHZW4uZ2V0TG9jYWxJbmRleCgiY3VycmVudCIpOwotCi0gICAgICAgIC8vIFB1c2ggdGhlIGFyZ3VtZW50cyB0aGF0IGFyZSBwYXNzZWQgdG8gYXBwbHlUZW1wbGF0ZXMoKQotICAgICAgICBpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpOwotICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0gICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkSXRlcmF0b3IoKSk7Ci0gICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZEhhbmRsZXIoKSk7Ci0gICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkQ3VycmVudE5vZGUoKSk7Ci0KLSAgICAgICAgLy8gUHVzaCBhIG5ldyBwYXJhbWV0ZXIgZnJhbWUgaW4gY2FzZSBpbXBvcnRlZCB0ZW1wbGF0ZSBtaWdodCBleHBlY3QKLSAgICAgICAgLy8gcGFyYW1ldGVycy4gIFRoZSBhcHBseS1pbXBvcnRzIGhhcyBub3RoaW5nIHRoYXQgaXQgY2FuIHBhc3MuCi0gICAgICAgIGlmIChzdHlsZXNoZWV0Lmhhc0xvY2FsUGFyYW1zKCkpIHsKLSAgICAgICAgICAgIGlsLmFwcGVuZChjbGFzc0dlbi5sb2FkVHJhbnNsZXQoKSk7Ci0gICAgICAgICAgICBmaW5hbCBpbnQgcHVzaEZyYW1lID0gY3BnLmFkZE1ldGhvZHJlZihUUkFOU0xFVF9DTEFTUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBVU0hfUEFSQU1fRlJBTUUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQVVNIX1BBUkFNX0ZSQU1FX1NJRyk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRVZJUlRVQUwocHVzaEZyYW1lKSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBHZXQgdGhlIFttaW4sbWF4PiBwcmVjZWRlbmNlIG9mIGFsbCB0ZW1wbGF0ZXMgaW1wb3J0ZWQgdW5kZXIgdGhlCi0gICAgICAgIC8vIGN1cnJlbnQgc3R5bGVzaGVldAotICAgICAgICBmaW5hbCBpbnQgbWF4UHJlY2VkZW5jZSA9IF9wcmVjZWRlbmNlOwotICAgICAgICBmaW5hbCBpbnQgbWluUHJlY2VkZW5jZSA9IGdldE1pblByZWNlZGVuY2UobWF4UHJlY2VkZW5jZSk7Ci0gICAgICAgIGZpbmFsIE1vZGUgbW9kZSA9IHN0eWxlc2hlZXQuZ2V0TW9kZShfbW9kZU5hbWUpOwotCi0gICAgICAgIC8vIEdldCBuYW1lIG9mIGFwcHJvcHJpYXRlIGFwcGx5LXRlbXBsYXRlcyBmdW5jdGlvbiBmb3IgdGhpcwotICAgICAgICAvLyB4c2w6YXBwbHktaW1wb3J0cyBpbnN0cnVjdGlvbgotICAgICAgICBTdHJpbmcgZnVuY3Rpb25OYW1lID0gbW9kZS5mdW5jdGlvbk5hbWUobWluUHJlY2VkZW5jZSwgbWF4UHJlY2VkZW5jZSk7Ci0KLSAgICAgICAgLy8gQ29uc3RydWN0IHRoZSB0cmFuc2xldCBjbGFzcy1uYW1lIGFuZCB0aGUgc2lnbmF0dXJlIG9mIHRoZSBtZXRob2QKLSAgICAgICAgZmluYWwgU3RyaW5nIGNsYXNzTmFtZSA9IGNsYXNzR2VuLmdldFN0eWxlc2hlZXQoKS5nZXRDbGFzc05hbWUoKTsKLSAgICAgICAgZmluYWwgU3RyaW5nIHNpZ25hdHVyZSA9IGNsYXNzR2VuLmdldEFwcGx5VGVtcGxhdGVzU2lnRm9ySW1wb3J0KCk7Ci0gICAgICAgIGZpbmFsIGludCBhcHBseVRlbXBsYXRlcyA9IGNwZy5hZGRNZXRob2RyZWYoY2xhc3NOYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaWduYXR1cmUpOwotICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRVZJUlRVQUwoYXBwbHlUZW1wbGF0ZXMpKTsKLQotICAgICAgICAvLyBQb3AgYW55IHBhcmFtZXRlciBmcmFtZSB0aGF0IHdhcyBwdXNoZWQgYWJvdmUuCi0gICAgICAgIGlmIChzdHlsZXNoZWV0Lmhhc0xvY2FsUGFyYW1zKCkpIHsKLSAgICAgICAgICAgIGlsLmFwcGVuZChjbGFzc0dlbi5sb2FkVHJhbnNsZXQoKSk7Ci0gICAgICAgICAgICBmaW5hbCBpbnQgcHVzaEZyYW1lID0gY3BnLmFkZE1ldGhvZHJlZihUUkFOU0xFVF9DTEFTUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBPUF9QQVJBTV9GUkFNRSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBPUF9QQVJBTV9GUkFNRV9TSUcpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VWSVJUVUFMKHB1c2hGcmFtZSkpOwotICAgICAgICB9Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0FwcGx5VGVtcGxhdGVzLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0FwcGx5VGVtcGxhdGVzLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGQ3YmMxY2EuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9BcHBseVRlbXBsYXRlcy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjA1ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMTUsIDIwMTYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKi8KLS8qCi0gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKLSAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAotICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgotICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKLSAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCi0gKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQ29uc3RhbnRQb29sR2VuOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFSU5URVJGQUNFOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFVklSVFVBTDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uTGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5DbGFzc0dlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5FcnJvck1zZzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5NZXRob2RHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuTm9kZVNldFR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuTm9kZVR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuUmVmZXJlbmNlVHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5SZXN1bHRUcmVlVHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGVDaGVja0Vycm9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlV0aWw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5YTUwxMUNoYXI7Ci1pbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOwotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLS8qKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICovCi1maW5hbCBjbGFzcyBBcHBseVRlbXBsYXRlcyBleHRlbmRzIEluc3RydWN0aW9uIHsKLSAgICBwcml2YXRlIEV4cHJlc3Npb24gX3NlbGVjdDsKLSAgICBwcml2YXRlIFR5cGUgICAgICAgX3R5cGUgPSBudWxsOwotICAgIHByaXZhdGUgUU5hbWUgICAgICBfbW9kZU5hbWU7Ci0gICAgcHJpdmF0ZSBTdHJpbmcgICAgIF9mdW5jdGlvbk5hbWU7Ci0KLSAgICBwdWJsaWMgdm9pZCBkaXNwbGF5KGludCBpbmRlbnQpIHsKLSAgICAgICAgaW5kZW50KGluZGVudCk7Ci0gICAgICAgIFV0aWwucHJpbnRsbigiQXBwbHlUZW1wbGF0ZXMiKTsKLSAgICAgICAgaW5kZW50KGluZGVudCArIEluZGVudEluY3JlbWVudCk7Ci0gICAgICAgIFV0aWwucHJpbnRsbigic2VsZWN0ICIgKyBfc2VsZWN0LnRvU3RyaW5nKCkpOwotICAgICAgICBpZiAoX21vZGVOYW1lICE9IG51bGwpIHsKLSAgICAgICAgICAgIGluZGVudChpbmRlbnQgKyBJbmRlbnRJbmNyZW1lbnQpOwotICAgICAgICAgICAgVXRpbC5wcmludGxuKCJtb2RlICIgKyBfbW9kZU5hbWUpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gaGFzV2l0aFBhcmFtcygpIHsKLSAgICAgICAgcmV0dXJuIGhhc0NvbnRlbnRzKCk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgcGFyc2VDb250ZW50cyhQYXJzZXIgcGFyc2VyKSB7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBzZWxlY3QgPSBnZXRBdHRyaWJ1dGUoInNlbGVjdCIpOwotICAgICAgICBmaW5hbCBTdHJpbmcgbW9kZSAgID0gZ2V0QXR0cmlidXRlKCJtb2RlIik7Ci0KLSAgICAgICAgaWYgKHNlbGVjdC5sZW5ndGgoKSA+IDApIHsKLSAgICAgICAgICAgIF9zZWxlY3QgPSBwYXJzZXIucGFyc2VFeHByZXNzaW9uKHRoaXMsICJzZWxlY3QiLCBudWxsKTsKLQotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKG1vZGUubGVuZ3RoKCkgPiAwKSB7Ci0gICAgICAgICAgICBpZiAoIVhNTDExQ2hhci5pc1hNTDExVmFsaWRRTmFtZShtb2RlKSkgewotICAgICAgICAgICAgICAgIEVycm9yTXNnIGVyciA9IG5ldyBFcnJvck1zZyhFcnJvck1zZy5JTlZBTElEX1FOQU1FX0VSUiwgbW9kZSwgdGhpcyk7Ci0gICAgICAgICAgICAgICAgcGFyc2VyLnJlcG9ydEVycm9yKENvbnN0YW50cy5FUlJPUiwgZXJyKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIF9tb2RlTmFtZSA9IHBhcnNlci5nZXRRTmFtZUlnbm9yZURlZmF1bHROcyhtb2RlKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIGluc3RhbnRpYXRlIE1vZGUgaWYgbmVlZGVkLCBjYWNoZSAoYXBwbHkgdGVtcCkgZnVuY3Rpb24gbmFtZQotICAgICAgICBfZnVuY3Rpb25OYW1lID0KLSAgICAgICAgICAgIHBhcnNlci5nZXRUb3BMZXZlbFN0eWxlc2hlZXQoKS5nZXRNb2RlKF9tb2RlTmFtZSkuZnVuY3Rpb25OYW1lKCk7Ci0gICAgICAgIHBhcnNlQ2hpbGRyZW4ocGFyc2VyKTsvLyB3aXRoLXBhcmFtcwotICAgIH0KLQotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0gICAgICAgIGlmIChfc2VsZWN0ICE9IG51bGwpIHsKLSAgICAgICAgICAgIF90eXBlID0gX3NlbGVjdC50eXBlQ2hlY2soc3RhYmxlKTsKLSAgICAgICAgICAgIGlmIChfdHlwZSBpbnN0YW5jZW9mIE5vZGVUeXBlIHx8IF90eXBlIGluc3RhbmNlb2YgUmVmZXJlbmNlVHlwZSkgewotICAgICAgICAgICAgICAgIF9zZWxlY3QgPSBuZXcgQ2FzdEV4cHIoX3NlbGVjdCwgVHlwZS5Ob2RlU2V0KTsKLSAgICAgICAgICAgICAgICBfdHlwZSA9IFR5cGUuTm9kZVNldDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChfdHlwZSBpbnN0YW5jZW9mIE5vZGVTZXRUeXBlfHxfdHlwZSBpbnN0YW5jZW9mIFJlc3VsdFRyZWVUeXBlKSB7Ci0gICAgICAgICAgICAgICAgdHlwZUNoZWNrQ29udGVudHMoc3RhYmxlKTsgLy8gd2l0aC1wYXJhbXMKLSAgICAgICAgICAgICAgICByZXR1cm4gVHlwZS5Wb2lkOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVDaGVja0Vycm9yKHRoaXMpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgdHlwZUNoZWNrQ29udGVudHMoc3RhYmxlKTsgICAgICAgICAgLy8gd2l0aC1wYXJhbXMKLSAgICAgICAgICAgIHJldHVybiBUeXBlLlZvaWQ7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGUgY2FsbC10ZW1wbGF0ZS4gQSBwYXJhbWV0ZXIgZnJhbWUgaXMgcHVzaGVkIG9ubHkgaWYKLSAgICAgKiBzb21lIHRlbXBsYXRlIGluIHRoZSBzdHlsZXNoZWV0IHVzZXMgcGFyYW1ldGVycy4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLSAgICAgICAgYm9vbGVhbiBzZXRTdGFydE5vZGVDYWxsZWQgPSBmYWxzZTsKLSAgICAgICAgZmluYWwgU3R5bGVzaGVldCBzdHlsZXNoZWV0ID0gY2xhc3NHZW4uZ2V0U3R5bGVzaGVldCgpOwotICAgICAgICBmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLSAgICAgICAgZmluYWwgaW50IGN1cnJlbnQgPSBtZXRob2RHZW4uZ2V0TG9jYWxJbmRleCgiY3VycmVudCIpOwotCi0gICAgICAgIC8vIGNoZWNrIGlmIHNvcnRpbmcgbm9kZXMgaXMgcmVxdWlyZWQKLSAgICAgICAgZmluYWwgVmVjdG9yPFNvcnQ+IHNvcnRPYmplY3RzID0gbmV3IFZlY3Rvcjw+KCk7Ci0gICAgICAgIGZvciAoZmluYWwgU3ludGF4VHJlZU5vZGUgY2hpbGQgOiBnZXRDb250ZW50cygpKSB7Ci0gICAgICAgICAgICBpZiAoY2hpbGQgaW5zdGFuY2VvZiBTb3J0KSB7Ci0gICAgICAgICAgICAgICAgc29ydE9iamVjdHMuYWRkRWxlbWVudCgoU29ydCljaGlsZCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBQdXNoIGEgbmV3IHBhcmFtZXRlciBmcmFtZQotICAgICAgICBpZiAoc3R5bGVzaGVldC5oYXNMb2NhbFBhcmFtcygpIHx8IGhhc0NvbnRlbnRzKCkpIHsKLSAgICAgICAgICAgIGlsLmFwcGVuZChjbGFzc0dlbi5sb2FkVHJhbnNsZXQoKSk7Ci0gICAgICAgICAgICBmaW5hbCBpbnQgcHVzaEZyYW1lID0gY3BnLmFkZE1ldGhvZHJlZihUUkFOU0xFVF9DTEFTUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBVU0hfUEFSQU1fRlJBTUUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQVVNIX1BBUkFNX0ZSQU1FX1NJRyk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRVZJUlRVQUwocHVzaEZyYW1lKSk7Ci0gICAgICAgICAgICAvLyB0cmFuc2xhdGUgd2l0aC1wYXJhbXMKLSAgICAgICAgICAgIHRyYW5zbGF0ZUNvbnRlbnRzKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICB9Ci0KLQotICAgICAgICBpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpOwotCi0gICAgICAgIC8vIFRoZSAnc2VsZWN0JyBleHByZXNzaW9uIGlzIGEgcmVzdWx0LXRyZWUKLSAgICAgICAgaWYgKChfdHlwZSAhPSBudWxsKSAmJiAoX3R5cGUgaW5zdGFuY2VvZiBSZXN1bHRUcmVlVHlwZSkpIHsKLSAgICAgICAgICAgIC8vIDx4c2w6c29ydD4gY2Fubm90IGJlIGFwcGxpZWQgdG8gYSByZXN1bHQgdHJlZSAtIGlzc3VlIHdhcm5pbmcKLSAgICAgICAgICAgIGlmIChzb3J0T2JqZWN0cy5zaXplKCkgPiAwKSB7Ci0gICAgICAgICAgICAgICAgRXJyb3JNc2cgZXJyID0gbmV3IEVycm9yTXNnKEVycm9yTXNnLlJFU1VMVF9UUkVFX1NPUlRfRVJSLHRoaXMpOwotICAgICAgICAgICAgICAgIGdldFBhcnNlcigpLnJlcG9ydEVycm9yKFdBUk5JTkcsIGVycik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyBQdXQgdGhlIHJlc3VsdCB0cmVlIChhIERPTSBhZGFwdGVyKSBvbiB0aGUgc3RhY2sKLSAgICAgICAgICAgIF9zZWxlY3QudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICAgICAgLy8gR2V0IGJhY2sgdGhlIERPTSBhbmQgaXRlcmF0b3IgKG5vdCBqdXN0IGl0ZXJhdG9yISEhKQotICAgICAgICAgICAgX3R5cGUudHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgVHlwZS5Ob2RlU2V0KTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLQotICAgICAgICAgICAgLy8gY29tcHV0ZSBub2RlIGl0ZXJhdG9yIGZvciBhcHBseVRlbXBsYXRlcwotICAgICAgICAgICAgaWYgKHNvcnRPYmplY3RzLnNpemUoKSA+IDApIHsKLSAgICAgICAgICAgICAgICBTb3J0LnRyYW5zbGF0ZVNvcnRJdGVyYXRvcihjbGFzc0dlbiwgbWV0aG9kR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9zZWxlY3QsIHNvcnRPYmplY3RzKTsKLSAgICAgICAgICAgICAgICBpbnQgc2V0U3RhcnROb2RlID0gY3BnLmFkZEludGVyZmFjZU1ldGhvZHJlZihOT0RFX0lURVJBVE9SLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNFVF9TVEFSVF9OT0RFLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoSSkiKwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5PREVfSVRFUkFUT1JfU0lHKTsKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRDdXJyZW50Tm9kZSgpKTsKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRUlOVEVSRkFDRShzZXRTdGFydE5vZGUsMikpOwotICAgICAgICAgICAgICAgIHNldFN0YXJ0Tm9kZUNhbGxlZCA9IHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBpZiAoX3NlbGVjdCA9PSBudWxsKQotICAgICAgICAgICAgICAgICAgICBNb2RlLmNvbXBpbGVHZXRDaGlsZHJlbihjbGFzc0dlbiwgbWV0aG9kR2VuLCBjdXJyZW50KTsKLSAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgIF9zZWxlY3QudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKF9zZWxlY3QgIT0gbnVsbCAmJiAhc2V0U3RhcnROb2RlQ2FsbGVkKSB7Ci0gICAgICAgICAgICBfc2VsZWN0LnN0YXJ0SXRlcmF0b3IoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyEhISBuZWVkIHRvIGluc3RhbnRpYXRlIGFsbCBuZWVkZWQgbW9kZXMKLSAgICAgICAgZmluYWwgU3RyaW5nIGNsYXNzTmFtZSA9IGNsYXNzR2VuLmdldFN0eWxlc2hlZXQoKS5nZXRDbGFzc05hbWUoKTsKLSAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkSGFuZGxlcigpKTsKLSAgICAgICAgZmluYWwgU3RyaW5nIGFwcGx5VGVtcGxhdGVzU2lnID0gY2xhc3NHZW4uZ2V0QXBwbHlUZW1wbGF0ZXNTaWcoKTsKLSAgICAgICAgZmluYWwgaW50IGFwcGx5VGVtcGxhdGVzID0gY3BnLmFkZE1ldGhvZHJlZihjbGFzc05hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2Z1bmN0aW9uTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcHBseVRlbXBsYXRlc1NpZyk7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChhcHBseVRlbXBsYXRlcykpOwotCi0gICAgICAgIC8vIHVubWFwIHBhcmFtZXRlcnMgdG8gcmVsZWFzZSB0ZW1wb3JhcnkgcmVzdWx0IHRyZWVzCi0gICAgICAgIGZvciAoZmluYWwgU3ludGF4VHJlZU5vZGUgY2hpbGQgOiBnZXRDb250ZW50cygpKSB7Ci0gICAgICAgICAgICBpZiAoY2hpbGQgaW5zdGFuY2VvZiBXaXRoUGFyYW0pIHsKLSAgICAgICAgICAgICAgICAoKFdpdGhQYXJhbSljaGlsZCkucmVsZWFzZVJlc3VsdFRyZWUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBQb3AgcGFyYW1ldGVyIGZyYW1lCi0gICAgICAgIGlmIChzdHlsZXNoZWV0Lmhhc0xvY2FsUGFyYW1zKCkgfHwgaGFzQ29udGVudHMoKSkgewotICAgICAgICAgICAgaWwuYXBwZW5kKGNsYXNzR2VuLmxvYWRUcmFuc2xldCgpKTsKLSAgICAgICAgICAgIGZpbmFsIGludCBwb3BGcmFtZSA9IGNwZy5hZGRNZXRob2RyZWYoVFJBTlNMRVRfQ0xBU1MsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBPUF9QQVJBTV9GUkFNRSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUE9QX1BBUkFNX0ZSQU1FX1NJRyk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRVZJUlRVQUwocG9wRnJhbWUpKTsKLSAgICAgICAgfQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvQXJndW1lbnRMaXN0LmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0FyZ3VtZW50TGlzdC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2YzE3NTdjLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvQXJndW1lbnRMaXN0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0NCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBBcmd1bWVudExpc3QuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8wMSAxMDoxODoxOSBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXI7Ci0KLS8qKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICovCi1maW5hbCBjbGFzcyBBcmd1bWVudExpc3QgewotICAgIHByaXZhdGUgZmluYWwgRXhwcmVzc2lvbiAgIF9hcmc7Ci0gICAgcHJpdmF0ZSBmaW5hbCBBcmd1bWVudExpc3QgX3Jlc3Q7Ci0KLSAgICBwdWJsaWMgQXJndW1lbnRMaXN0KEV4cHJlc3Npb24gYXJnLCBBcmd1bWVudExpc3QgcmVzdCkgewotICAgICAgICBfYXJnID0gYXJnOwotICAgICAgICBfcmVzdCA9IHJlc3Q7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKLSAgICAgICAgcmV0dXJuIF9yZXN0ID09IG51bGwKLSAgICAgICAgICAgID8gX2FyZy50b1N0cmluZygpCi0gICAgICAgICAgICA6IF9hcmcudG9TdHJpbmcoKSArICIsICIgKyBfcmVzdC50b1N0cmluZygpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvQXR0cmlidXRlLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0F0dHJpYnV0ZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyNWY2YjU2Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvQXR0cmlidXRlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0NyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBBdHRyaWJ1dGUuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8wMSAxMDoyMDo1OSBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5VdGlsOwotCi0vKioKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqLwotZmluYWwgY2xhc3MgQXR0cmlidXRlIGV4dGVuZHMgSW5zdHJ1Y3Rpb24gewotICAgIHByaXZhdGUgUU5hbWUgX25hbWU7Ci0KLSAgICBwdWJsaWMgdm9pZCBkaXNwbGF5KGludCBpbmRlbnQpIHsKLSAgICAgICAgaW5kZW50KGluZGVudCk7Ci0gICAgICAgIFV0aWwucHJpbnRsbigiQXR0cmlidXRlICIgKyBfbmFtZSk7Ci0gICAgICAgIGRpc3BsYXlDb250ZW50cyhpbmRlbnQgKyBJbmRlbnRJbmNyZW1lbnQpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHBhcnNlQ29udGVudHMoUGFyc2VyIHBhcnNlcikgewotICAgICAgICBfbmFtZSA9IHBhcnNlci5nZXRRTmFtZShnZXRBdHRyaWJ1dGUoIm5hbWUiKSk7Ci0gICAgICAgIHBhcnNlQ2hpbGRyZW4ocGFyc2VyKTsKLSAgICAgICAgLy8hISEgYWRkIHRleHQgbm9kZXMKLSAgICAgICAgLy8hISEgdGFrZSBjYXJlIG9mIHZhbHVlIHRlbXBsYXRlcwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvQXR0cmlidXRlU2V0LmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0F0dHJpYnV0ZVNldC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyYmJjYWY2Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvQXR0cmlidXRlU2V0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMDggKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAxNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqLwotLyoKLSAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQotICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCi0gKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCi0gKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAotICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKLSAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBBdHRyaWJ1dGVTZXQuamF2YSx2IDEuNSAyMDA1LzA5LzI4IDEzOjQ4OjA0IHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQ29uc3RhbnRQb29sR2VuOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFU1BFQ0lBTDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uTGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5BdHRyaWJ1dGVTZXRNZXRob2RHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuQ2xhc3NHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuRXJyb3JNc2c7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuTWV0aG9kR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZUNoZWNrRXJyb3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVXRpbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLlhNTDExQ2hhcjsKLWltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7Ci1pbXBvcnQgamF2YS51dGlsLkxpc3Q7Ci0KLS8qKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKi8KLWZpbmFsIGNsYXNzIEF0dHJpYnV0ZVNldCBleHRlbmRzIFRvcExldmVsRWxlbWVudCB7Ci0KLSAgICAvLyBUaGlzIHByZWZpeCBpcyB1c2VkIGZvciB0aGUgbWV0aG9kIG5hbWUgb2YgYXR0cmlidXRlIHNldCBtZXRob2RzCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEF0dHJpYnV0ZVNldFByZWZpeCA9ICIkYXMkIjsKLQotICAgIC8vIEVsZW1lbnQgY29udGVudHMKLSAgICBwcml2YXRlIFFOYW1lICAgICAgICAgICAgX25hbWU7Ci0gICAgcHJpdmF0ZSBVc2VBdHRyaWJ1dGVTZXRzIF91c2VTZXRzOwotICAgIHByaXZhdGUgQXR0cmlidXRlU2V0ICAgICBfbWVyZ2VTZXQ7Ci0gICAgcHJpdmF0ZSBTdHJpbmcgICAgICAgICAgIF9tZXRob2Q7Ci0gICAgcHJpdmF0ZSBib29sZWFuICAgICAgICAgIF9pZ25vcmUgPSBmYWxzZTsKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIFFOYW1lIG9mIHRoaXMgYXR0cmlidXRlIHNldAotICAgICAqLwotICAgIHB1YmxpYyBRTmFtZSBnZXROYW1lKCkgewotICAgICAgICByZXR1cm4gX25hbWU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgbWV0aG9kIG5hbWUgb2YgdGhpcyBhdHRyaWJ1dGUgc2V0LiBUaGlzIG1ldGhvZCBuYW1lIGlzCi0gICAgICogZ2VuZXJhdGVkIGJ5IHRoZSBjb21waWxlciAoWFNMVEMpCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRNZXRob2ROYW1lKCkgewotICAgICAgICByZXR1cm4gX21ldGhvZDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDYWxsIHRoaXMgbWV0aG9kIHRvIHByZXZlbnQgYSBtZXRob2QgZm9yIGJlaW5nIGNvbXBpbGVkIGZvciB0aGlzIHNldC4KLSAgICAgKiBUaGlzIGlzIHVzZWQgaW4gY2FzZSBzZXZlcmFsIDx4c2w6YXR0cmlidXRlLXNldC4uLj4gZWxlbWVudHMgY29uc3RpdHV0ZQotICAgICAqIGEgc2luZ2xlIHNldCAod2l0aCBvbmUgbmFtZSkuIFRoZSBsYXN0IGVsZW1lbnQgd2lsbCBtZXJnZSBpdHNlbGYgd2l0aAotICAgICAqIGFueSBwcmV2aW91cyBzZXQocykgd2l0aCB0aGUgc2FtZSBuYW1lIGFuZCBkaXNhYmxlIHRoZSBvdGhlciBzZXQocykuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgaWdub3JlKCkgewotICAgICAgICBfaWdub3JlID0gdHJ1ZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBQYXJzZSB0aGUgY29udGVudHMgb2YgdGhpcyBhdHRyaWJ1dGUgc2V0LiBSZWNvZ25pc2VkIGF0dHJpYnV0ZXMgYXJlCi0gICAgICogIm5hbWUiIChyZXF1aXJlZCkgYW5kICJ1c2UtYXR0cmlidXRlLXNldHMiIChvcHRpb25hbCkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcGFyc2VDb250ZW50cyhQYXJzZXIgcGFyc2VyKSB7Ci0KLSAgICAgICAgLy8gR2V0IHRoaXMgYXR0cmlidXRlIHNldCdzIG5hbWUKLSAgICAgICAgZmluYWwgU3RyaW5nIG5hbWUgPSBnZXRBdHRyaWJ1dGUoIm5hbWUiKTsKLQotICAgICAgICBpZiAoIVhNTDExQ2hhci5pc1hNTDExVmFsaWRRTmFtZShuYW1lKSkgewotICAgICAgICAgICAgRXJyb3JNc2cgZXJyID0gbmV3IEVycm9yTXNnKEVycm9yTXNnLklOVkFMSURfUU5BTUVfRVJSLCBuYW1lLCB0aGlzKTsKLSAgICAgICAgICAgIHBhcnNlci5yZXBvcnRFcnJvcihDb25zdGFudHMuRVJST1IsIGVycik7Ci0gICAgICAgIH0KLSAgICAgICAgX25hbWUgPSBwYXJzZXIuZ2V0UU5hbWVJZ25vcmVEZWZhdWx0TnMobmFtZSk7Ci0gICAgICAgIGlmICgoX25hbWUgPT0gbnVsbCkgfHwgKF9uYW1lLmVxdWFscyhFTVBUWVNUUklORykpKSB7Ci0gICAgICAgICAgICBFcnJvck1zZyBtc2cgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuVU5OQU1FRF9BVFRSSUJTRVRfRVJSLCB0aGlzKTsKLSAgICAgICAgICAgIHBhcnNlci5yZXBvcnRFcnJvcihDb25zdGFudHMuRVJST1IsIG1zZyk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBHZXQgYW55IGluY2x1ZGVkIGF0dHJpYnV0ZSBzZXRzIChzaW1pbGFyIHRvIGluaGVyaXRhbmNlLi4uKQotICAgICAgICBmaW5hbCBTdHJpbmcgdXNlU2V0cyA9IGdldEF0dHJpYnV0ZSgidXNlLWF0dHJpYnV0ZS1zZXRzIik7Ci0gICAgICAgIGlmICh1c2VTZXRzLmxlbmd0aCgpID4gMCkgewotICAgICAgICAgICAgaWYgKCFVdGlsLmlzVmFsaWRRTmFtZXModXNlU2V0cykpIHsKLSAgICAgICAgICAgICAgICBFcnJvck1zZyBlcnIgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuSU5WQUxJRF9RTkFNRV9FUlIsIHVzZVNldHMsIHRoaXMpOwotICAgICAgICAgICAgICAgIHBhcnNlci5yZXBvcnRFcnJvcihDb25zdGFudHMuRVJST1IsIGVycik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBfdXNlU2V0cyA9IG5ldyBVc2VBdHRyaWJ1dGVTZXRzKHVzZVNldHMsIHBhcnNlcik7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBQYXJzZSB0aGUgY29udGVudHMgb2YgdGhpcyBub2RlLiBBbGwgY2hpbGQgZWxlbWVudHMgbXVzdCBiZQotICAgICAgICAvLyA8eHNsOmF0dHJpYnV0ZT4gZWxlbWVudHMuIE90aGVyIGVsZW1lbnRzIGNhdXNlIGFuIGVycm9yLgotICAgICAgICBmaW5hbCBMaXN0PFN5bnRheFRyZWVOb2RlPiBjb250ZW50cyA9IGdldENvbnRlbnRzKCk7Ci0gICAgICAgIGZpbmFsIGludCBjb3VudCA9IGNvbnRlbnRzLnNpemUoKTsKLSAgICAgICAgZm9yIChpbnQgaT0wOyBpPGNvdW50OyBpKyspIHsKLSAgICAgICAgICAgIFN5bnRheFRyZWVOb2RlIGNoaWxkID0gY29udGVudHMuZ2V0KGkpOwotICAgICAgICAgICAgaWYgKGNoaWxkIGluc3RhbmNlb2YgWHNsQXR0cmlidXRlKSB7Ci0gICAgICAgICAgICAgICAgcGFyc2VyLmdldFN5bWJvbFRhYmxlKCkuc2V0Q3VycmVudE5vZGUoY2hpbGQpOwotICAgICAgICAgICAgICAgIGNoaWxkLnBhcnNlQ29udGVudHMocGFyc2VyKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKGNoaWxkIGluc3RhbmNlb2YgVGV4dCkgewotICAgICAgICAgICAgICAgIC8vIGlnbm9yZQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgRXJyb3JNc2cgbXNnID0gbmV3IEVycm9yTXNnKEVycm9yTXNnLklMTEVHQUxfQ0hJTERfRVJSLCB0aGlzKTsKLSAgICAgICAgICAgICAgICBwYXJzZXIucmVwb3J0RXJyb3IoQ29uc3RhbnRzLkVSUk9SLCBtc2cpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gUG9pbnQgdGhlIHN5bWJvbCB0YWJsZSBiYWNrIGF0IHVzLi4uCi0gICAgICAgIHBhcnNlci5nZXRTeW1ib2xUYWJsZSgpLnNldEN1cnJlbnROb2RlKHRoaXMpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFR5cGUgY2hlY2sgdGhlIGNvbnRlbnRzIG9mIHRoaXMgZWxlbWVudAotICAgICAqLwotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0KLSAgICAgICAgaWYgKF9pZ25vcmUpIHJldHVybiAoVHlwZS5Wb2lkKTsKLQotICAgICAgICAvLyBfbWVyZ2VTZXQgUG9pbnQgdG8gYW55IHByZXZpb3VzIGRlZmluaXRpb24gb2YgdGhpcyBhdHRyaWJ1dGUgc2V0Ci0gICAgICAgIF9tZXJnZVNldCA9IHN0YWJsZS5hZGRBdHRyaWJ1dGVTZXQodGhpcyk7Ci0KLSAgICAgICAgX21ldGhvZCA9IEF0dHJpYnV0ZVNldFByZWZpeCArIGdldFhTTFRDKCkubmV4dEF0dHJpYnV0ZVNldFNlcmlhbCgpOwotCi0gICAgICAgIGlmIChfdXNlU2V0cyAhPSBudWxsKSBfdXNlU2V0cy50eXBlQ2hlY2soc3RhYmxlKTsKLSAgICAgICAgdHlwZUNoZWNrQ29udGVudHMoc3RhYmxlKTsKLSAgICAgICAgcmV0dXJuIFR5cGUuVm9pZDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb21waWxlIGEgbWV0aG9kIHRoYXQgb3V0cHV0cyB0aGUgYXR0cmlidXRlcyBpbiB0aGlzIHNldAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCi0gICAgICAgIGlmIChfaWdub3JlKSByZXR1cm47Ci0KLSAgICAgICAgLy8gQ3JlYXRlIGEgbmV3IG1ldGhvZCBnZW5lcmF0b3IgZm9yIGFuIGF0dHJpYnV0ZSBzZXQgbWV0aG9kCi0gICAgICAgIG1ldGhvZEdlbiA9IG5ldyBBdHRyaWJ1dGVTZXRNZXRob2RHZW5lcmF0b3IoX21ldGhvZCwgY2xhc3NHZW4pOwotCi0gICAgICAgIC8vIEdlbmVyYXRlIGEgcmVmZXJlbmNlIHRvIHByZXZpb3VzIGF0dHJpYnV0ZS1zZXQgZGVmaW5pdGlvbnMgd2l0aCB0aGUKLSAgICAgICAgLy8gc2FtZSBuYW1lIGZpcnN0LiAgVGhvc2UgbGF0ZXIgaW4gdGhlIHN0eWxlc2hlZXQgdGFrZSBwcmVjZWRlbmNlLgotICAgICAgICBpZiAoX21lcmdlU2V0ICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLSAgICAgICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLSAgICAgICAgICAgIGZpbmFsIFN0cmluZyBtZXRob2ROYW1lID0gX21lcmdlU2V0LmdldE1ldGhvZE5hbWUoKTsKLQotICAgICAgICAgICAgaWwuYXBwZW5kKGNsYXNzR2VuLmxvYWRUcmFuc2xldCgpKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZEl0ZXJhdG9yKCkpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkSGFuZGxlcigpKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZEN1cnJlbnROb2RlKCkpOwotICAgICAgICAgICAgZmluYWwgaW50IG1ldGhvZCA9IGNwZy5hZGRNZXRob2RyZWYoY2xhc3NHZW4uZ2V0Q2xhc3NOYW1lKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRob2ROYW1lLCBBVFRSX1NFVF9TSUcpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VTUEVDSUFMKG1ldGhvZCkpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gVHJhbnNsYXRlIG90aGVyIHVzZWQgYXR0cmlidXRlIHNldHMgZmlyc3QsIGFzIGxvY2FsIGF0dHJpYnV0ZXMKLSAgICAgICAgLy8gdGFrZSBwcmVjZWRlbmNlIChsYXN0IGF0dHJpYnV0ZXMgb3ZlcnJpZGVzIGZpcnN0KQotICAgICAgICBpZiAoX3VzZVNldHMgIT0gbnVsbCkgX3VzZVNldHMudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCi0gICAgICAgIC8vIFRyYW5zbGF0ZSBhbGwgbG9jYWwgYXR0cmlidXRlcwotICAgICAgICBmaW5hbCBJdGVyYXRvcjxTeW50YXhUcmVlTm9kZT4gYXR0cmlidXRlcyA9IGVsZW1lbnRzKCk7Ci0gICAgICAgIHdoaWxlIChhdHRyaWJ1dGVzLmhhc05leHQoKSkgewotICAgICAgICAgICAgU3ludGF4VHJlZU5vZGUgZWxlbWVudCA9IGF0dHJpYnV0ZXMubmV4dCgpOwotICAgICAgICAgICAgaWYgKGVsZW1lbnQgaW5zdGFuY2VvZiBYc2xBdHRyaWJ1dGUpIHsKLSAgICAgICAgICAgICAgICBmaW5hbCBYc2xBdHRyaWJ1dGUgYXR0cmlidXRlID0gKFhzbEF0dHJpYnV0ZSllbGVtZW50OwotICAgICAgICAgICAgICAgIGF0dHJpYnV0ZS50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotICAgICAgICBpbC5hcHBlbmQoUkVUVVJOKTsKLQotICAgICAgICBjbGFzc0dlbi5hZGRNZXRob2QobWV0aG9kR2VuKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgICAgICBTdHJpbmdCdWZmZXIgYnVmID0gbmV3IFN0cmluZ0J1ZmZlcigiYXR0cmlidXRlLXNldDogIik7Ci0gICAgICAgIC8vIFRyYW5zbGF0ZSBhbGwgbG9jYWwgYXR0cmlidXRlcwotICAgICAgICBmaW5hbCBJdGVyYXRvcjxTeW50YXhUcmVlTm9kZT4gYXR0cmlidXRlcyA9IGVsZW1lbnRzKCk7Ci0gICAgICAgIHdoaWxlIChhdHRyaWJ1dGVzLmhhc05leHQoKSkgewotICAgICAgICAgICAgZmluYWwgWHNsQXR0cmlidXRlIGF0dHJpYnV0ZSA9Ci0gICAgICAgICAgICAgICAgKFhzbEF0dHJpYnV0ZSlhdHRyaWJ1dGVzLm5leHQoKTsKLSAgICAgICAgICAgIGJ1Zi5hcHBlbmQoYXR0cmlidXRlKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4oYnVmLnRvU3RyaW5nKCkpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvQXR0cmlidXRlVmFsdWUuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvQXR0cmlidXRlVmFsdWUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYmQxYTMxNy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0F0dHJpYnV0ZVZhbHVlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw1MCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBBdHRyaWJ1dGVWYWx1ZS5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzAxIDEwOjI1OjQ5IHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlcjsKLQotCi0vKioKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqLwotYWJzdHJhY3QgY2xhc3MgQXR0cmlidXRlVmFsdWUgZXh0ZW5kcyBFeHByZXNzaW9uIHsKLQotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQXR0cmlidXRlVmFsdWUgY3JlYXRlKFN5bnRheFRyZWVOb2RlIHBhcmVudCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdGV4dCwgUGFyc2VyIHBhcnNlcikgewotCi0gICAgICAgIEF0dHJpYnV0ZVZhbHVlIHJlc3VsdDsKLSAgICAgICAgaWYgKHRleHQuaW5kZXhPZigneycpICE9IC0xKSB7Ci0gICAgICAgICAgICByZXN1bHQgPSBuZXcgQXR0cmlidXRlVmFsdWVUZW1wbGF0ZSh0ZXh0LCBwYXJzZXIsIHBhcmVudCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAodGV4dC5pbmRleE9mKCd9JykgIT0gLTEpIHsKLSAgICAgICAgICAgIHJlc3VsdCA9IG5ldyBBdHRyaWJ1dGVWYWx1ZVRlbXBsYXRlKHRleHQsIHBhcnNlciwgcGFyZW50KTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHJlc3VsdCA9IG5ldyBTaW1wbGVBdHRyaWJ1dGVWYWx1ZSh0ZXh0KTsKLSAgICAgICAgICAgIHJlc3VsdC5zZXRQYXJzZXIocGFyc2VyKTsKLSAgICAgICAgICAgIHJlc3VsdC5zZXRQYXJlbnQocGFyZW50KTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gcmVzdWx0OwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvQXR0cmlidXRlVmFsdWVUZW1wbGF0ZS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9BdHRyaWJ1dGVWYWx1ZVRlbXBsYXRlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDliNTg3NTkuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9BdHRyaWJ1dGVWYWx1ZVRlbXBsYXRlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyNjIgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAxNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqLwotLyoKLSAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQotICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCi0gKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCi0gKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAotICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKLSAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBBdHRyaWJ1dGVWYWx1ZVRlbXBsYXRlLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMDEgMTA6MjY6NTcgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5Db25zdGFudFBvb2xHZW47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JTlZPS0VTUEVDSUFMOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFVklSVFVBTDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW5zdHJ1Y3Rpb25MaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuTkVXOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkNsYXNzR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkVycm9yTXNnOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLk1ldGhvZEdlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGVDaGVja0Vycm9yOwotaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKLWltcG9ydCBqYXZhLnV0aWwuTGlzdDsKLWltcG9ydCBqYXZhLnV0aWwuTm9TdWNoRWxlbWVudEV4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuU3RyaW5nVG9rZW5pemVyOwotCi0vKioKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqLwotZmluYWwgY2xhc3MgQXR0cmlidXRlVmFsdWVUZW1wbGF0ZSBleHRlbmRzIEF0dHJpYnV0ZVZhbHVlIHsKLQotICAgIGZpbmFsIHN0YXRpYyBpbnQgT1VUX0VYUFIgPSAwOwotICAgIGZpbmFsIHN0YXRpYyBpbnQgSU5fRVhQUiAgPSAxOwotICAgIGZpbmFsIHN0YXRpYyBpbnQgSU5fRVhQUl9TUVVPVEVTID0gMjsKLSAgICBmaW5hbCBzdGF0aWMgaW50IElOX0VYUFJfRFFVT1RFUyA9IDM7Ci0gICAgZmluYWwgc3RhdGljIFN0cmluZyBERUxJTUlURVIgPSAiXHVGRkZFIjsgICAgICAvLyBBIFVuaWNvZGUgbm9uY2hhcgotCi0gICAgcHVibGljIEF0dHJpYnV0ZVZhbHVlVGVtcGxhdGUoU3RyaW5nIHZhbHVlLCBQYXJzZXIgcGFyc2VyLAotICAgICAgICBTeW50YXhUcmVlTm9kZSBwYXJlbnQpCi0gICAgewotICAgICAgICBzZXRQYXJlbnQocGFyZW50KTsKLSAgICAgICAgc2V0UGFyc2VyKHBhcnNlcik7Ci0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIHBhcnNlQVZUZW1wbGF0ZSh2YWx1ZSwgcGFyc2VyKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoTm9TdWNoRWxlbWVudEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICByZXBvcnRFcnJvcihwYXJlbnQsIHBhcnNlciwKLSAgICAgICAgICAgICAgICAgICAgICAgIEVycm9yTXNnLkFUVFJfVkFMX1RFTVBMQVRFX0VSUiwgdmFsdWUpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHdvLXBhc3MgcGFyc2luZyBvZiBBVFZzLiBJbiB0aGUgZmlyc3QgcGFzcywgZG91YmxlIGN1cmx5IGJyYWNlcyBhcmUKLSAgICAgKiByZXBsYWNlZCBieSBvbmUsIGFuZCBleHByZXNzaW9ucyBhcmUgZGVsaW1pdGVkIHVzaW5nIERFTElNSVRFUi4gVGhlCi0gICAgICogc2Vjb25kIHBhc3Mgc3BsaXRzIHVwIHRoZSByZXN1bHRpbmcgYnVmZmVyIGludG8gbGl0ZXJhbCBhbmQgbm9uLWxpdGVyYWwKLSAgICAgKiBleHByZXNzaW9ucy4gRXJyb3JzIGFyZSByZXBvcnRlZCBkdXJpbmcgdGhlIGZpcnN0IHBhc3MuCi0gICAgICovCi0gICAgcHJpdmF0ZSB2b2lkIHBhcnNlQVZUZW1wbGF0ZShTdHJpbmcgdGV4dCwgUGFyc2VyIHBhcnNlcikgewotICAgICAgICBTdHJpbmdUb2tlbml6ZXIgdG9rZW5pemVyID0KLSAgICAgICAgICAgIG5ldyBTdHJpbmdUb2tlbml6ZXIodGV4dCwgInt9XCJcJyIsIHRydWUpOwotCi0gICAgICAgIC8qCi0gICAgICAgICAgKiBGaXJzdCBwYXNzOiByZXBsYWNlIGRvdWJsZSBjdXJseSBicmFjZXMgYW5kIGRlbGltaXQgZXhwcmVzc2lvbnMKLSAgICAgICAgICAqIFNpbXBsZSBhdXRvbWF0b24gdG8gcGFyc2UgQVRWcywgZGVsaW1pdCBleHByZXNzaW9ucyBhbmQgcmVwb3J0Ci0gICAgICAgICAgKiBlcnJvcnMuCi0gICAgICAgICAgKi8KLSAgICAgICAgU3RyaW5nIHQgPSBudWxsOwotICAgICAgICBTdHJpbmcgbG9va2FoZWFkID0gbnVsbDsKLSAgICAgICAgU3RyaW5nQnVmZmVyIGJ1ZmZlciA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLSAgICAgICAgaW50IHN0YXRlID0gT1VUX0VYUFI7Ci0KLSAgICAgICAgd2hpbGUgKHRva2VuaXplci5oYXNNb3JlVG9rZW5zKCkpIHsKLSAgICAgICAgICAgIC8vIFVzZSBsb29rYWhlYWQgaWYgYXZhaWxhYmxlCi0gICAgICAgICAgICBpZiAobG9va2FoZWFkICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICB0ID0gbG9va2FoZWFkOwotICAgICAgICAgICAgICAgIGxvb2thaGVhZCA9IG51bGw7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICB0ID0gdG9rZW5pemVyLm5leHRUb2tlbigpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAodC5sZW5ndGgoKSA9PSAxKSB7Ci0gICAgICAgICAgICAgICAgc3dpdGNoICh0LmNoYXJBdCgwKSkgewotICAgICAgICAgICAgICAgICAgICBjYXNlICd7JzoKLSAgICAgICAgICAgICAgICAgICAgICAgIHN3aXRjaCAoc3RhdGUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIE9VVF9FWFBSOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb29rYWhlYWQgPSB0b2tlbml6ZXIubmV4dFRva2VuKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsb29rYWhlYWQuZXF1YWxzKCJ7IikpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQobG9va2FoZWFkKTsgICAgLy8gcmVwbGFjZSB7eyBieSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb29rYWhlYWQgPSBudWxsOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZChERUxJTUlURVIpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdGUgPSBJTl9FWFBSOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgSU5fRVhQUjoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIElOX0VYUFJfU1FVT1RFUzoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIElOX0VYUFJfRFFVT1RFUzoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoZ2V0UGFyZW50KCksIHBhcnNlciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRXJyb3JNc2cuQVRUUl9WQUxfVEVNUExBVEVfRVJSLCB0ZXh0KTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgY2FzZSAnfSc6Ci0gICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKHN0YXRlKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBPVVRfRVhQUjoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9va2FoZWFkID0gdG9rZW5pemVyLm5leHRUb2tlbigpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobG9va2FoZWFkLmVxdWFscygifSIpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKGxvb2thaGVhZCk7ICAgIC8vIHJlcGxhY2UgfX0gYnkgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9va2FoZWFkID0gbnVsbDsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydEVycm9yKGdldFBhcmVudCgpLCBwYXJzZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVycm9yTXNnLkFUVFJfVkFMX1RFTVBMQVRFX0VSUiwgdGV4dCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBJTl9FWFBSOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKERFTElNSVRFUik7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlID0gT1VUX0VYUFI7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgSU5fRVhQUl9TUVVPVEVTOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgSU5fRVhQUl9EUVVPVEVTOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKHQpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICBjYXNlICdcJyc6Ci0gICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKHN0YXRlKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBJTl9FWFBSOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0ZSA9IElOX0VYUFJfU1FVT1RFUzsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBJTl9FWFBSX1NRVU9URVM6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlID0gSU5fRVhQUjsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBPVVRfRVhQUjoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIElOX0VYUFJfRFFVT1RFUzoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKHQpOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgJ1wiJzoKLSAgICAgICAgICAgICAgICAgICAgICAgIHN3aXRjaCAoc3RhdGUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIElOX0VYUFI6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlID0gSU5fRVhQUl9EUVVPVEVTOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIElOX0VYUFJfRFFVT1RFUzoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdGUgPSBJTl9FWFBSOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIE9VVF9FWFBSOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgSU5fRVhQUl9TUVVPVEVTOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQodCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKLSAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQodCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKHQpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gTXVzdCBiZSBpbiBPVVRfRVhQUiBhdCB0aGUgZW5kIG9mIHBhcnNpbmcKLSAgICAgICAgaWYgKHN0YXRlICE9IE9VVF9FWFBSKSB7Ci0gICAgICAgICAgICByZXBvcnRFcnJvcihnZXRQYXJlbnQoKSwgcGFyc2VyLAotICAgICAgICAgICAgICAgICAgICAgICAgRXJyb3JNc2cuQVRUUl9WQUxfVEVNUExBVEVfRVJSLCB0ZXh0KTsKLSAgICAgICAgfQotCi0gICAgICAgIC8qCi0gICAgICAgICAgKiBTZWNvbmQgcGFzczogc3BsaXQgdXAgYnVmZmVyIGludG8gbGl0ZXJhbCBhbmQgbm9uLWxpdGVyYWwgZXhwcmVzc2lvbnMuCi0gICAgICAgICAgKi8KLSAgICAgICAgdG9rZW5pemVyID0gbmV3IFN0cmluZ1Rva2VuaXplcihidWZmZXIudG9TdHJpbmcoKSwgREVMSU1JVEVSLCB0cnVlKTsKLQotICAgICAgICB3aGlsZSAodG9rZW5pemVyLmhhc01vcmVUb2tlbnMoKSkgewotICAgICAgICAgICAgdCA9IHRva2VuaXplci5uZXh0VG9rZW4oKTsKLQotICAgICAgICAgICAgaWYgKHQuZXF1YWxzKERFTElNSVRFUikpIHsKLSAgICAgICAgICAgICAgICBhZGRFbGVtZW50KHBhcnNlci5wYXJzZUV4cHJlc3Npb24odGhpcywgdG9rZW5pemVyLm5leHRUb2tlbigpKSk7Ci0gICAgICAgICAgICAgICAgdG9rZW5pemVyLm5leHRUb2tlbigpOyAgICAgIC8vIGNvbnN1bWUgb3RoZXIgZGVsaW1pdGVyCi0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBhZGRFbGVtZW50KG5ldyBMaXRlcmFsRXhwcih0KSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgVHlwZSB0eXBlQ2hlY2soU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgewotICAgICAgICBmaW5hbCBMaXN0PFN5bnRheFRyZWVOb2RlPiBjb250ZW50cyA9IGdldENvbnRlbnRzKCk7Ci0gICAgICAgIGZpbmFsIGludCBuID0gY29udGVudHMuc2l6ZSgpOwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykgewotICAgICAgICAgICAgZmluYWwgRXhwcmVzc2lvbiBleHAgPSAoRXhwcmVzc2lvbiljb250ZW50cy5nZXQoaSk7Ci0gICAgICAgICAgICBpZiAoIWV4cC50eXBlQ2hlY2soc3RhYmxlKS5pZGVudGljYWxUbyhUeXBlLlN0cmluZykpIHsKLSAgICAgICAgICAgICAgICBjb250ZW50cy5zZXQoaSwgbmV3IENhc3RFeHByKGV4cCwgVHlwZS5TdHJpbmcpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gX3R5cGUgPSBUeXBlLlN0cmluZzsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgICAgICBmaW5hbCBTdHJpbmdCdWZmZXIgYnVmZmVyID0gbmV3IFN0cmluZ0J1ZmZlcigiQVZUOlsiKTsKLSAgICAgICAgZmluYWwgaW50IGNvdW50ID0gZWxlbWVudENvdW50KCk7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykgewotICAgICAgICAgICAgYnVmZmVyLmFwcGVuZChlbGVtZW50QXQoaSkudG9TdHJpbmcoKSk7Ci0gICAgICAgICAgICBpZiAoaSA8IGNvdW50IC0gMSkKLSAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCcgJyk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGJ1ZmZlci5hcHBlbmQoJ10nKS50b1N0cmluZygpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotICAgICAgICBpZiAoZWxlbWVudENvdW50KCkgPT0gMSkgewotICAgICAgICAgICAgZmluYWwgRXhwcmVzc2lvbiBleHAgPSAoRXhwcmVzc2lvbillbGVtZW50QXQoMCk7Ci0gICAgICAgICAgICBleHAudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotICAgICAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotICAgICAgICAgICAgZmluYWwgaW50IGluaXRCdWZmZXIgPSBjcGcuYWRkTWV0aG9kcmVmKFNUUklOR19CVUZGRVJfQ0xBU1MsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjxpbml0PiIsICIoKVYiKTsKLSAgICAgICAgICAgIGZpbmFsIEluc3RydWN0aW9uIGFwcGVuZCA9Ci0gICAgICAgICAgICAgICAgbmV3IElOVk9LRVZJUlRVQUwoY3BnLmFkZE1ldGhvZHJlZihTVFJJTkdfQlVGRkVSX0NMQVNTLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImFwcGVuZCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKCIgKyBTVFJJTkdfU0lHICsgIikiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIFNUUklOR19CVUZGRVJfU0lHKSk7Ci0KLSAgICAgICAgICAgIGZpbmFsIGludCB0b1N0cmluZyA9IGNwZy5hZGRNZXRob2RyZWYoU1RSSU5HX0JVRkZFUl9DTEFTUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRvU3RyaW5nIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIigpIitTVFJJTkdfU0lHKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgTkVXKGNwZy5hZGRDbGFzcyhTVFJJTkdfQlVGRkVSX0NMQVNTKSkpOwotICAgICAgICAgICAgaWwuYXBwZW5kKERVUCk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRVNQRUNJQUwoaW5pdEJ1ZmZlcikpOwotICAgICAgICAgICAgLy8gU3RyaW5nQnVmZmVyIGlzIG9uIHRoZSBzdGFjawotICAgICAgICAgICAgZmluYWwgSXRlcmF0b3I8U3ludGF4VHJlZU5vZGU+IGVsZW1lbnRzID0gZWxlbWVudHMoKTsKLSAgICAgICAgICAgIHdoaWxlIChlbGVtZW50cy5oYXNOZXh0KCkpIHsKLSAgICAgICAgICAgICAgICBmaW5hbCBFeHByZXNzaW9uIGV4cCA9IChFeHByZXNzaW9uKWVsZW1lbnRzLm5leHQoKTsKLSAgICAgICAgICAgICAgICBleHAudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChhcHBlbmQpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VWSVJUVUFMKHRvU3RyaW5nKSk7Ci0gICAgICAgIH0KLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0Jpbk9wRXhwci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9CaW5PcEV4cHIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggODE4NWQxMS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0Jpbk9wRXhwci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTMyICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IEJpbk9wRXhwci5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzAxIDExOjQyOjI3IHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW5zdHJ1Y3Rpb25MaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkNsYXNzR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkVycm9yTXNnOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLk1ldGhvZEdlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5NZXRob2RUeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZUNoZWNrRXJyb3I7Ci0KLS8qKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICovCi1maW5hbCBjbGFzcyBCaW5PcEV4cHIgZXh0ZW5kcyBFeHByZXNzaW9uIHsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQTFVTICA9IDA7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUlOVVMgPSAxOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRJTUVTID0gMjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBESVYgICA9IDM7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTU9EICAgPSA0OwotCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nW10gT3BzID0gewotICAgICAgICAiKyIsICItIiwgIioiLCAiLyIsICIlIgotICAgIH07Ci0KLSAgICBwcml2YXRlIGludCBfb3A7Ci0gICAgcHJpdmF0ZSBFeHByZXNzaW9uIF9sZWZ0LCBfcmlnaHQ7Ci0KLSAgICBwdWJsaWMgQmluT3BFeHByKGludCBvcCwgRXhwcmVzc2lvbiBsZWZ0LCBFeHByZXNzaW9uIHJpZ2h0KSB7Ci0gICAgICAgIF9vcCA9IG9wOwotICAgICAgICAoX2xlZnQgPSBsZWZ0KS5zZXRQYXJlbnQodGhpcyk7Ci0gICAgICAgIChfcmlnaHQgPSByaWdodCkuc2V0UGFyZW50KHRoaXMpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGlzIGV4cHJlc3Npb25zIGNvbnRhaW5zIGEgY2FsbCB0byBwb3NpdGlvbigpLiBUaGlzIGlzCi0gICAgICogbmVlZGVkIGZvciBjb250ZXh0IGNoYW5nZXMgaW4gbm9kZSBzdGVwcyBjb250YWluaW5nIG11bHRpcGxlIHByZWRpY2F0ZXMuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaGFzUG9zaXRpb25DYWxsKCkgewotICAgICAgICBpZiAoX2xlZnQuaGFzUG9zaXRpb25DYWxsKCkpIHJldHVybiB0cnVlOwotICAgICAgICBpZiAoX3JpZ2h0Lmhhc1Bvc2l0aW9uQ2FsbCgpKSByZXR1cm4gdHJ1ZTsKLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGlzIGV4cHJlc3Npb25zIGNvbnRhaW5zIGEgY2FsbCB0byBsYXN0KCkKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBoYXNMYXN0Q2FsbCgpIHsKLSAgICAgICAgICAgIHJldHVybiAoX2xlZnQuaGFzTGFzdENhbGwoKSB8fCBfcmlnaHQuaGFzTGFzdENhbGwoKSk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0UGFyc2VyKFBhcnNlciBwYXJzZXIpIHsKLSAgICAgICAgc3VwZXIuc2V0UGFyc2VyKHBhcnNlcik7Ci0gICAgICAgIF9sZWZ0LnNldFBhcnNlcihwYXJzZXIpOwotICAgICAgICBfcmlnaHQuc2V0UGFyc2VyKHBhcnNlcik7Ci0gICAgfQotCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLSAgICAgICAgZmluYWwgVHlwZSB0bGVmdCA9IF9sZWZ0LnR5cGVDaGVjayhzdGFibGUpOwotICAgICAgICBmaW5hbCBUeXBlIHRyaWdodCA9IF9yaWdodC50eXBlQ2hlY2soc3RhYmxlKTsKLSAgICAgICAgZmluYWwgTWV0aG9kVHlwZSBwdHlwZSA9IGxvb2t1cFByaW1vcChzdGFibGUsIE9wc1tfb3BdLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBNZXRob2RUeXBlKFR5cGUuVm9pZCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0bGVmdCwgdHJpZ2h0KSk7Ci0gICAgICAgIGlmIChwdHlwZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmaW5hbCBUeXBlIGFyZzEgPSAoVHlwZSkgcHR5cGUuYXJnc1R5cGUoKS5lbGVtZW50QXQoMCk7Ci0gICAgICAgICAgICBpZiAoIWFyZzEuaWRlbnRpY2FsVG8odGxlZnQpKSB7Ci0gICAgICAgICAgICAgICAgX2xlZnQgPSBuZXcgQ2FzdEV4cHIoX2xlZnQsIGFyZzEpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZmluYWwgVHlwZSBhcmcyID0gKFR5cGUpIHB0eXBlLmFyZ3NUeXBlKCkuZWxlbWVudEF0KDEpOwotICAgICAgICAgICAgaWYgKCFhcmcyLmlkZW50aWNhbFRvKHRyaWdodCkpIHsKLSAgICAgICAgICAgICAgICBfcmlnaHQgPSBuZXcgQ2FzdEV4cHIoX3JpZ2h0LCBhcmcxKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiBfdHlwZSA9IHB0eXBlLnJlc3VsdFR5cGUoKTsKLSAgICAgICAgfQotICAgICAgICB0aHJvdyBuZXcgVHlwZUNoZWNrRXJyb3IodGhpcyk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQotICAgICAgICBfbGVmdC50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgIF9yaWdodC50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0KLSAgICAgICAgc3dpdGNoIChfb3ApIHsKLSAgICAgICAgY2FzZSBQTFVTOgotICAgICAgICAgICAgaWwuYXBwZW5kKF90eXBlLkFERCgpKTsKLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICBjYXNlIE1JTlVTOgotICAgICAgICAgICAgaWwuYXBwZW5kKF90eXBlLlNVQigpKTsKLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICBjYXNlIFRJTUVTOgotICAgICAgICAgICAgaWwuYXBwZW5kKF90eXBlLk1VTCgpKTsKLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICBjYXNlIERJVjoKLSAgICAgICAgICAgIGlsLmFwcGVuZChfdHlwZS5ESVYoKSk7Ci0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBNT0Q6Ci0gICAgICAgICAgICBpbC5hcHBlbmQoX3R5cGUuUkVNKCkpOwotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGRlZmF1bHQ6Ci0gICAgICAgICAgICBFcnJvck1zZyBtc2cgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuSUxMRUdBTF9CSU5BUllfT1BfRVJSLCB0aGlzKTsKLSAgICAgICAgICAgIGdldFBhcnNlcigpLnJlcG9ydEVycm9yKENvbnN0YW50cy5FUlJPUiwgbXNnKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0gICAgICAgIHJldHVybiBPcHNbX29wXSArICcoJyArIF9sZWZ0ICsgIiwgIiArIF9yaWdodCArICcpJzsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0Jvb2xlYW5DYWxsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0Jvb2xlYW5DYWxsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDE2ZWI2ZDQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9Cb29sZWFuQ2FsbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTkgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogQm9vbGVhbkNhbGwuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8wMSAxMTo0Mzo1MCBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuQ2xhc3NHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuTWV0aG9kR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZUNoZWNrRXJyb3I7Ci0KLS8qKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICovCi1maW5hbCBjbGFzcyBCb29sZWFuQ2FsbCBleHRlbmRzIEZ1bmN0aW9uQ2FsbCB7Ci0KLSAgICBwcml2YXRlIEV4cHJlc3Npb24gX2FyZyA9IG51bGw7Ci0KLSAgICBwdWJsaWMgQm9vbGVhbkNhbGwoUU5hbWUgZm5hbWUsIFZlY3RvciBhcmd1bWVudHMpIHsKLSAgICAgICAgc3VwZXIoZm5hbWUsIGFyZ3VtZW50cyk7Ci0gICAgICAgIF9hcmcgPSBhcmd1bWVudCgwKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgVHlwZSB0eXBlQ2hlY2soU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgewotICAgICAgICBfYXJnLnR5cGVDaGVjayhzdGFibGUpOwotICAgICAgICByZXR1cm4gX3R5cGUgPSBUeXBlLkJvb2xlYW47Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0gICAgICAgIF9hcmcudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICBmaW5hbCBUeXBlIHRhcmcgPSBfYXJnLmdldFR5cGUoKTsKLSAgICAgICAgaWYgKCF0YXJnLmlkZW50aWNhbFRvKFR5cGUuQm9vbGVhbikpIHsKLSAgICAgICAgICAgIF9hcmcuc3RhcnRJdGVyYXRvcihjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgICAgIHRhcmcudHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgVHlwZS5Cb29sZWFuKTsKLSAgICAgICAgfQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvQm9vbGVhbkV4cHIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvQm9vbGVhbkV4cHIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMjdmZTk2Ni4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0Jvb2xlYW5FeHByLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4MSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBCb29sZWFuRXhwci5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzAxIDExOjQ0OjU3IHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQ29uc3RhbnRQb29sR2VuOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuR09UTzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uTGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlBVU0g7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuQ2xhc3NHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuTWV0aG9kR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZUNoZWNrRXJyb3I7Ci0KLS8qKgotICogVGhpcyBjbGFzcyBpbXBsZW1lbnRzIGlubGluZWQgY2FsbHMgdG8gdGhlIFhTTFQgc3RhbmRhcmQgZnVuY3Rpb25zCi0gKiB0cnVlKCkgYW5kIGZhbHNlKCkuCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKi8KLWZpbmFsIGNsYXNzIEJvb2xlYW5FeHByIGV4dGVuZHMgRXhwcmVzc2lvbiB7Ci0gICAgcHJpdmF0ZSBib29sZWFuIF92YWx1ZTsKLQotICAgIHB1YmxpYyBCb29sZWFuRXhwcihib29sZWFuIHZhbHVlKSB7Ci0gICAgICAgIF92YWx1ZSA9IHZhbHVlOwotICAgIH0KLQotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0gICAgICAgIF90eXBlID0gVHlwZS5Cb29sZWFuOwotICAgICAgICByZXR1cm4gX3R5cGU7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKLSAgICAgICAgcmV0dXJuIF92YWx1ZSA/ICJ0cnVlKCkiIDogImZhbHNlKCkiOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGdldFZhbHVlKCkgewotICAgICAgICByZXR1cm4gX3ZhbHVlOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGNvbnRleHREZXBlbmRlbnQoKSB7Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLSAgICAgICAgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotICAgICAgICBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsIF92YWx1ZSkpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZURlc3ludGhlc2l6ZWQoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLSAgICAgICAgaWYgKF92YWx1ZSkgewotICAgICAgICAgICAgaWwuYXBwZW5kKE5PUCk7ICAgICAvLyB0cnVlIGxpc3QgZmFsbHMgdGhyb3VnaAotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgX2ZhbHNlTGlzdC5hZGQoaWwuYXBwZW5kKG5ldyBHT1RPKG51bGwpKSk7Ci0gICAgICAgIH0KLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0NhbGxUZW1wbGF0ZS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9DYWxsVGVtcGxhdGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMmUyY2ExNC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0NhbGxUZW1wbGF0ZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjQzICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMTYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQ29uc3RhbnRQb29sR2VuOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFVklSVFVBTDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uTGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5DbGFzc0dlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5FcnJvck1zZzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5NZXRob2RHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlQ2hlY2tFcnJvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5VdGlsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuWE1MMTFDaGFyOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotLyoqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKiBAYXV0aG9yIEVyd2luIEJvbHdpZHQgPGVqYkBrbG9tcC5vcmc+Ci0gKi8KLWZpbmFsIGNsYXNzIENhbGxUZW1wbGF0ZSBleHRlbmRzIEluc3RydWN0aW9uIHsKLQotICAgIC8qKgotICAgICAqIE5hbWUgb2YgdGVtcGxhdGUgdG8gY2FsbC4KLSAgICAgKi8KLSAgICBwcml2YXRlIFFOYW1lIF9uYW1lOwotCi0gICAgLyoqCi0gICAgICogVGhlIGFycmF5IG9mIGVmZmVjdGl2ZSBwYXJhbWV0ZXJzIGluIHRoaXMgQ2FsbFRlbXBsYXRlLiBBbiBvYmplY3QgaW4KLSAgICAgKiB0aGlzIGFycmF5IGNhbiBiZSBlaXRoZXIgYSBXaXRoUGFyYW0gb3IgYSBQYXJhbSBpZiBubyBXaXRoUGFyYW0KLSAgICAgKiBleGlzdHMgZm9yIGEgcGFydGljdWxhciBwYXJhbWV0ZXIuCi0gICAgICovCi0gICAgcHJpdmF0ZSBTeW50YXhUcmVlTm9kZVtdIF9wYXJhbWV0ZXJzID0gbnVsbDsKLQotICAgIC8qKgotICAgICAqIFRoZSBjb3JyZXNwb25kaW5nIHRlbXBsYXRlIHdoaWNoIHRoaXMgQ2FsbFRlbXBsYXRlIGNhbGxzLgotICAgICAqLwotICAgIHByaXZhdGUgVGVtcGxhdGUgX2NhbGxlZVRlbXBsYXRlID0gbnVsbDsKLQotICAgIHB1YmxpYyB2b2lkIGRpc3BsYXkoaW50IGluZGVudCkgewotICAgICAgICBpbmRlbnQoaW5kZW50KTsKLSAgICAgICAgU3lzdGVtLm91dC5wcmludCgiQ2FsbFRlbXBsYXRlIik7Ci0gICAgICAgIFV0aWwucHJpbnRsbigiIG5hbWUgIiArIF9uYW1lKTsKLSAgICAgICAgZGlzcGxheUNvbnRlbnRzKGluZGVudCArIEluZGVudEluY3JlbWVudCk7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gaGFzV2l0aFBhcmFtcygpIHsKLSAgICAgICAgcmV0dXJuIGVsZW1lbnRDb3VudCgpID4gMDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBwYXJzZUNvbnRlbnRzKFBhcnNlciBwYXJzZXIpIHsKLSAgICAgICAgZmluYWwgU3RyaW5nIG5hbWUgPSBnZXRBdHRyaWJ1dGUoIm5hbWUiKTsKLSAgICAgICAgaWYgKG5hbWUubGVuZ3RoKCkgPiAwKSB7Ci0gICAgICAgICAgICBpZiAoIVhNTDExQ2hhci5pc1hNTDExVmFsaWRRTmFtZShuYW1lKSkgewotICAgICAgICAgICAgICAgIEVycm9yTXNnIGVyciA9IG5ldyBFcnJvck1zZyhFcnJvck1zZy5JTlZBTElEX1FOQU1FX0VSUiwgbmFtZSwgdGhpcyk7Ci0gICAgICAgICAgICAgICAgcGFyc2VyLnJlcG9ydEVycm9yKENvbnN0YW50cy5FUlJPUiwgZXJyKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIF9uYW1lID0gcGFyc2VyLmdldFFOYW1lSWdub3JlRGVmYXVsdE5zKG5hbWUpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgcmVwb3J0RXJyb3IodGhpcywgcGFyc2VyLCBFcnJvck1zZy5SRVFVSVJFRF9BVFRSX0VSUiwgIm5hbWUiKTsKLSAgICAgICAgfQotICAgICAgICBwYXJzZUNoaWxkcmVuKHBhcnNlcik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVmVyaWZ5IHRoYXQgYSB0ZW1wbGF0ZSB3aXRoIHRoaXMgbmFtZSBleGlzdHMuCi0gICAgICovCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLSAgICAgICAgZmluYWwgVGVtcGxhdGUgdGVtcGxhdGUgPSBzdGFibGUubG9va3VwVGVtcGxhdGUoX25hbWUpOwotICAgICAgICBpZiAodGVtcGxhdGUgIT0gbnVsbCkgewotICAgICAgICAgICAgdHlwZUNoZWNrQ29udGVudHMoc3RhYmxlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIEVycm9yTXNnIGVyciA9IG5ldyBFcnJvck1zZyhFcnJvck1zZy5URU1QTEFURV9VTkRFRl9FUlIsX25hbWUsdGhpcyk7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUNoZWNrRXJyb3IoZXJyKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gVHlwZS5Wb2lkOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotICAgICAgICBmaW5hbCBTdHlsZXNoZWV0IHN0eWxlc2hlZXQgPSBjbGFzc0dlbi5nZXRTdHlsZXNoZWV0KCk7Ci0gICAgICAgIGZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCi0gICAgICAgIC8vIElmIHRoZXJlIGFyZSBQYXJhbXMgaW4gdGhlIHN0eWxlc2hlZXQgb3IgV2l0aFBhcmFtcyBpbiB0aGlzIGNhbGw/Ci0gICAgICAgIGlmIChzdHlsZXNoZWV0Lmhhc0xvY2FsUGFyYW1zKCkgfHwgaGFzQ29udGVudHMoKSkgewotICAgICAgICAgICAgX2NhbGxlZVRlbXBsYXRlID0gZ2V0Q2FsbGVlVGVtcGxhdGUoKTsKLQotICAgICAgICAgICAgLy8gQnVpbGQgdGhlIHBhcmFtZXRlciBsaXN0IGlmIHRoZSBjYWxsZWQgdGVtcGxhdGUgaXMgc2ltcGxlIG5hbWVkCi0gICAgICAgICAgICBpZiAoX2NhbGxlZVRlbXBsYXRlICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBidWlsZFBhcmFtZXRlckxpc3QoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIFRoaXMgaXMgb25seSBuZWVkZWQgd2hlbiB0aGUgY2FsbGVkIHRlbXBsYXRlIGlzIG5vdAotICAgICAgICAgICAgLy8gYSBzaW1wbGUgbmFtZWQgdGVtcGxhdGUuCi0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAvLyBQdXNoIHBhcmFtZXRlciBmcmFtZQotICAgICAgICAgICAgICAgIGZpbmFsIGludCBwdXNoID0gY3BnLmFkZE1ldGhvZHJlZihUUkFOU0xFVF9DTEFTUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUFVTSF9QQVJBTV9GUkFNRSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUFVTSF9QQVJBTV9GUkFNRV9TSUcpOwotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChjbGFzc0dlbi5sb2FkVHJhbnNsZXQoKSk7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VWSVJUVUFMKHB1c2gpKTsKLSAgICAgICAgICAgICAgICB0cmFuc2xhdGVDb250ZW50cyhjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIEdlbmVyYXRlIGEgdmFsaWQgSmF2YSBtZXRob2QgbmFtZQotICAgICAgICBmaW5hbCBTdHJpbmcgY2xhc3NOYW1lID0gc3R5bGVzaGVldC5nZXRDbGFzc05hbWUoKTsKLSAgICAgICAgU3RyaW5nIG1ldGhvZE5hbWUgPSBVdGlsLmVzY2FwZShfbmFtZS50b1N0cmluZygpKTsKLQotICAgICAgICAvLyBMb2FkIHN0YW5kYXJkIGFyZ3VtZW50cwotICAgICAgICBpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpOwotICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0gICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZEl0ZXJhdG9yKCkpOwotICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRIYW5kbGVyKCkpOwotICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRDdXJyZW50Tm9kZSgpKTsKLQotICAgICAgICAvLyBJbml0aWFsaXplIHByZWZpeCBvZiBtZXRob2Qgc2lnbmF0dXJlCi0gICAgICAgIFN0cmluZ0J1ZmZlciBtZXRob2RTaWcgPSBuZXcgU3RyaW5nQnVmZmVyKCIoIiArIERPTV9JTlRGX1NJRwotICAgICAgICAgICAgKyBOT0RFX0lURVJBVE9SX1NJRyArIFRSQU5TTEVUX09VVFBVVF9TSUcgKyBOT0RFX1NJRyk7Ci0KLSAgICAgICAgLy8gSWYgY2FsbGluZyBhIHNpbXBseSBuYW1lZCB0ZW1wbGF0ZSwgcHVzaCBhY3R1YWwgYXJndW1lbnRzCi0gICAgICAgIGlmIChfY2FsbGVlVGVtcGxhdGUgIT0gbnVsbCkgewotICAgICAgICAgICAgaW50IG51bVBhcmFtcyA9IF9wYXJhbWV0ZXJzLmxlbmd0aDsKLQotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW1QYXJhbXM7IGkrKykgewotICAgICAgICAgICAgICAgIFN5bnRheFRyZWVOb2RlIG5vZGUgPSBfcGFyYW1ldGVyc1tpXTsKLSAgICAgICAgICAgICAgICBtZXRob2RTaWcuYXBwZW5kKE9CSkVDVF9TSUcpOyAgIC8vIGFwcGVuZCBPYmplY3QgdG8gc2lnbmF0dXJlCi0KLSAgICAgICAgICAgICAgICAvLyBQdXNoICdudWxsJyBpZiBQYXJhbSB0byBpbmRpY2F0ZSBubyBhY3R1YWwgcGFyYW1ldGVyIHNwZWNpZmllZAotICAgICAgICAgICAgICAgIGlmIChub2RlIGluc3RhbmNlb2YgUGFyYW0pIHsKLSAgICAgICAgICAgICAgICAgICAgaWwuYXBwZW5kKEFDT05TVF9OVUxMKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSB7ICAvLyB0cmFuc2xhdGUgV2l0aFBhcmFtCi0gICAgICAgICAgICAgICAgICAgIG5vZGUudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIENvbXBsZXRlIHNpZ25hdHVyZSBhbmQgZ2VuZXJhdGUgaW52b2tldmlydHVhbCBjYWxsCi0gICAgICAgIG1ldGhvZFNpZy5hcHBlbmQoIilWIik7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChjcGcuYWRkTWV0aG9kcmVmKGNsYXNzTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kU2lnLnRvU3RyaW5nKCkpKSk7Ci0KLSAgICAgICAgLy8gcmVsZWFzZSB0ZW1wb3JhcnkgcmVzdWx0IHRyZWVzCi0gICAgICAgIGlmIChfcGFyYW1ldGVycyAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IF9wYXJhbWV0ZXJzLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgaWYgKF9wYXJhbWV0ZXJzW2ldIGluc3RhbmNlb2YgV2l0aFBhcmFtKSB7Ci0gICAgICAgICAgICAgICAgICAgICgoV2l0aFBhcmFtKV9wYXJhbWV0ZXJzW2ldKS5yZWxlYXNlUmVzdWx0VHJlZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBEbyBub3QgbmVlZCB0byBjYWxsIFRyYW5zbGV0LnBvcFBhcmFtRnJhbWUoKSBpZiB3ZSBhcmUKLSAgICAgICAgLy8gY2FsbGluZyBhIHNpbXBsZSBuYW1lZCB0ZW1wbGF0ZS4KLSAgICAgICAgaWYgKF9jYWxsZWVUZW1wbGF0ZSA9PSBudWxsICYmIChzdHlsZXNoZWV0Lmhhc0xvY2FsUGFyYW1zKCkgfHwgaGFzQ29udGVudHMoKSkpIHsKLSAgICAgICAgICAgIC8vIFBvcCBwYXJhbWV0ZXIgZnJhbWUKLSAgICAgICAgICAgIGZpbmFsIGludCBwb3AgPSBjcGcuYWRkTWV0aG9kcmVmKFRSQU5TTEVUX0NMQVNTLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUE9QX1BBUkFNX0ZSQU1FLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUE9QX1BBUkFNX0ZSQU1FX1NJRyk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VWSVJUVUFMKHBvcCkpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSBzaW1wbGUgbmFtZWQgdGVtcGxhdGUgd2hpY2ggdGhpcyBDYWxsVGVtcGxhdGUgY2FsbHMuCi0gICAgICogUmV0dXJuIGZhbHNlIGlmIHRoZXJlIGlzIG5vIG1hdGNoZWQgdGVtcGxhdGUgb3IgdGhlIG1hdGNoZWQKLSAgICAgKiB0ZW1wbGF0ZSBpcyBub3QgYSBzaW1wbGUgbmFtZWQgdGVtcGxhdGUuCi0gICAgICovCi0gICAgcHVibGljIFRlbXBsYXRlIGdldENhbGxlZVRlbXBsYXRlKCkgewotICAgICAgICBUZW1wbGF0ZSBmb3VuZFRlbXBsYXRlCi0gICAgICAgICAgICA9IGdldFhTTFRDKCkuZ2V0UGFyc2VyKCkuZ2V0U3ltYm9sVGFibGUoKS5sb29rdXBUZW1wbGF0ZShfbmFtZSk7Ci0KLSAgICAgICAgcmV0dXJuIGZvdW5kVGVtcGxhdGUuaXNTaW1wbGVOYW1lZFRlbXBsYXRlKCkgPyBmb3VuZFRlbXBsYXRlIDogbnVsbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBCdWlsZCB0aGUgbGlzdCBvZiBlZmZlY3RpdmUgcGFyYW1ldGVycyBpbiB0aGlzIENhbGxUZW1wbGF0ZS4KLSAgICAgKiBUaGUgcGFyYW1ldGVycyBvZiB0aGUgY2FsbGVkIHRlbXBsYXRlIGFyZSBwdXQgaW50byB0aGUgYXJyYXkgZmlyc3QuCi0gICAgICogVGhlbiB3ZSB2aXNpdCB0aGUgV2l0aFBhcmFtIGNoaWxkcmVuIG9mIHRoaXMgQ2FsbFRlbXBsYXRlIGFuZCByZXBsYWNlCi0gICAgICogdGhlIFBhcmFtIHdpdGggYSBjb3JyZXNwb25kaW5nIFdpdGhQYXJhbSBoYXZpbmcgdGhlIHNhbWUgbmFtZS4KLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJhbWV0ZXJMaXN0KCkgewotICAgICAgICAvLyBQdXQgdGhlIHBhcmFtZXRlcnMgZnJvbSB0aGUgY2FsbGVkIHRlbXBsYXRlIGludG8gdGhlIGFycmF5IGZpcnN0LgotICAgICAgICAvLyBUaGlzIGlzIHRvIGVuc3VyZSB0aGUgb3JkZXIgb2YgdGhlIHBhcmFtZXRlcnMuCi0gICAgICAgIFZlY3RvcjxQYXJhbT4gZGVmYXVsdFBhcmFtcyA9IF9jYWxsZWVUZW1wbGF0ZS5nZXRQYXJhbWV0ZXJzKCk7Ci0gICAgICAgIGludCBudW1QYXJhbXMgPSBkZWZhdWx0UGFyYW1zLnNpemUoKTsKLSAgICAgICAgX3BhcmFtZXRlcnMgPSBuZXcgU3ludGF4VHJlZU5vZGVbbnVtUGFyYW1zXTsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW1QYXJhbXM7IGkrKykgewotICAgICAgICAgICAgX3BhcmFtZXRlcnNbaV0gPSBkZWZhdWx0UGFyYW1zLmVsZW1lbnRBdChpKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIFJlcGxhY2UgYSBQYXJhbSB3aXRoIGEgV2l0aFBhcmFtIGlmIHRoZXkgaGF2ZSB0aGUgc2FtZSBuYW1lLgotICAgICAgICBpbnQgY291bnQgPSBlbGVtZW50Q291bnQoKTsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7Ci0gICAgICAgICAgICBPYmplY3Qgbm9kZSA9IGVsZW1lbnRBdChpKTsKLQotICAgICAgICAgICAgLy8gSWdub3JlIGlmIG5vdCBXaXRoUGFyYW0KLSAgICAgICAgICAgIGlmIChub2RlIGluc3RhbmNlb2YgV2l0aFBhcmFtKSB7Ci0gICAgICAgICAgICAgICAgV2l0aFBhcmFtIHdpdGhQYXJhbSA9IChXaXRoUGFyYW0pbm9kZTsKLSAgICAgICAgICAgICAgICBRTmFtZSBuYW1lID0gd2l0aFBhcmFtLmdldE5hbWUoKTsKLQotICAgICAgICAgICAgICAgIC8vIFNlYXJjaCBmb3IgYSBQYXJhbSB3aXRoIHRoZSBzYW1lIG5hbWUKLSAgICAgICAgICAgICAgICBmb3IgKGludCBrID0gMDsgayA8IG51bVBhcmFtczsgaysrKSB7Ci0gICAgICAgICAgICAgICAgICAgIFN5bnRheFRyZWVOb2RlIHBhcm0gPSBfcGFyYW1ldGVyc1trXTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKHBhcm0gaW5zdGFuY2VvZiBQYXJhbQotICAgICAgICAgICAgICAgICAgICAgICAgJiYgKChQYXJhbSlwYXJtKS5nZXROYW1lKCkuZXF1YWxzKG5hbWUpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICB3aXRoUGFyYW0uc2V0RG9QYXJhbWV0ZXJPcHRpbWl6YXRpb24odHJ1ZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBfcGFyYW1ldGVyc1trXSA9IHdpdGhQYXJhbTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHBhcm0gaW5zdGFuY2VvZiBXaXRoUGFyYW0KLSAgICAgICAgICAgICAgICAgICAgICAgICYmICgoV2l0aFBhcmFtKXBhcm0pLmdldE5hbWUoKS5lcXVhbHMobmFtZSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHdpdGhQYXJhbS5zZXREb1BhcmFtZXRlck9wdGltaXphdGlvbih0cnVlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIF9wYXJhbWV0ZXJzW2tdID0gd2l0aFBhcmFtOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9DYXN0Q2FsbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9DYXN0Q2FsbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjMTEzMWYzLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvQ2FzdENhbGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEwMiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBDYXN0Q2FsbC5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzAxIDExOjQ3OjU4IHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkNvbnN0YW50UG9vbEdlbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkNIRUNLQ0FTVDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uTGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5DbGFzc0dlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5NZXRob2RHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuRXJyb3JNc2c7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5PYmplY3RUeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGVDaGVja0Vycm9yOwotCi0vKioKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICovCi1maW5hbCBjbGFzcyBDYXN0Q2FsbCBleHRlbmRzIEZ1bmN0aW9uQ2FsbCB7Ci0KLSAgICAvKioKLSAgICAgKiBOYW1lIG9mIHRoZSBjbGFzcyB0aGF0IGlzIHRoZSB0YXJnZXQgb2YgdGhlIGNhc3QuIE11c3QgYmUgYQotICAgICAqIGZ1bGx5LXF1YWxpZmllZCBKYXZhIGNsYXNzIE5hbWUuCi0gICAgICovCi0gICAgcHJpdmF0ZSBTdHJpbmcgX2NsYXNzTmFtZTsKLQotICAgIC8qKgotICAgICAqIEEgcmVmZXJlbmNlIHRvIHRoZSBleHByZXNzaW9uIGJlaW5nIGNhc3RlZC4KLSAgICAgKi8KLSAgICBwcml2YXRlIEV4cHJlc3Npb24gX3JpZ2h0OwotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0b3IuCi0gICAgICovCi0gICAgcHVibGljIENhc3RDYWxsKFFOYW1lIGZuYW1lLCBWZWN0b3IgYXJndW1lbnRzKSB7Ci0gICAgICAgIHN1cGVyKGZuYW1lLCBhcmd1bWVudHMpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFR5cGUgY2hlY2sgdGhlIHR3byBwYXJhbWV0ZXJzIGZvciB0aGlzIGZ1bmN0aW9uCi0gICAgICovCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLSAgICAgICAgLy8gQ2hlY2sgdGhhdCB0aGUgZnVuY3Rpb24gd2FzIHBhc3NlZCBleGFjdGx5IHR3byBhcmd1bWVudHMKLSAgICAgICAgaWYgKGFyZ3VtZW50Q291bnQoKSAhPSAyKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUNoZWNrRXJyb3IobmV3IEVycm9yTXNnKEVycm9yTXNnLklMTEVHQUxfQVJHX0VSUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0TmFtZSgpLCB0aGlzKSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBUaGUgZmlyc3QgYXJndW1lbnQgbXVzdCBiZSBhIGxpdGVyYWwgU3RyaW5nCi0gICAgICAgIEV4cHJlc3Npb24gZXhwID0gYXJndW1lbnQoMCk7Ci0gICAgICAgIGlmIChleHAgaW5zdGFuY2VvZiBMaXRlcmFsRXhwcikgewotICAgICAgICAgICAgX2NsYXNzTmFtZSA9ICgoTGl0ZXJhbEV4cHIpIGV4cCkuZ2V0VmFsdWUoKTsKLSAgICAgICAgICAgIF90eXBlID0gVHlwZS5uZXdPYmplY3RUeXBlKF9jbGFzc05hbWUpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVDaGVja0Vycm9yKG5ldyBFcnJvck1zZyhFcnJvck1zZy5ORUVEX0xJVEVSQUxfRVJSLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXROYW1lKCksIHRoaXMpKTsKLSAgICAgICAgfQotCi0gICAgICAgICAvLyBTZWNvbmQgYXJndW1lbnQgbXVzdCBiZSBvZiB0eXBlIHJlZmVyZW5jZSBvciBvYmplY3QKLSAgICAgICAgX3JpZ2h0ID0gYXJndW1lbnQoMSk7Ci0gICAgICAgIFR5cGUgdHJpZ2h0ID0gX3JpZ2h0LnR5cGVDaGVjayhzdGFibGUpOwotICAgICAgICBpZiAodHJpZ2h0ICE9IFR5cGUuUmVmZXJlbmNlICYmCi0gICAgICAgICAgICB0cmlnaHQgaW5zdGFuY2VvZiBPYmplY3RUeXBlID09IGZhbHNlKQotICAgICAgICB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUNoZWNrRXJyb3IobmV3IEVycm9yTXNnKEVycm9yTXNnLkRBVEFfQ09OVkVSU0lPTl9FUlIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyaWdodCwgX3R5cGUsIHRoaXMpKTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBfdHlwZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLSAgICAgICAgZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0KLSAgICAgICAgX3JpZ2h0LnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBDSEVDS0NBU1QoY3BnLmFkZENsYXNzKF9jbGFzc05hbWUpKSk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9DYXN0RXhwci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9DYXN0RXhwci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlNmYwYjQ1Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvQ2FzdEV4cHIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI0MSArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDE1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICovCi0vKgotICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCi0gKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKLSAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KLSAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCi0gKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAotICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBDYXN0RXhwci5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzEyIDEwOjA2OjM1IHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQ29uc3RhbnRQb29sR2VuOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSUZfSUNNUE5FOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFSU5URVJGQUNFOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW5zdHJ1Y3Rpb25MaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuU0lQVVNIOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkJvb2xlYW5UeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkNsYXNzR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkVycm9yTXNnOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLk1ldGhvZEdlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5NdWx0aUhhc2h0YWJsZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5Ob2RlVHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5SZXN1bHRUcmVlVHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGVDaGVja0Vycm9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkF4aXM7Ci0KLS8qKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKiBAYXV0aG9yIEVyd2luIEJvbHdpZHQgPGVqYkBrbG9tcC5vcmc+Ci0gKi8KLWZpbmFsIGNsYXNzIENhc3RFeHByIGV4dGVuZHMgRXhwcmVzc2lvbiB7Ci0gICAgcHJpdmF0ZSBmaW5hbCBFeHByZXNzaW9uIF9sZWZ0OwotCi0gICAgLyoqCi0gICAgICogTGVnYWwgY29udmVyc2lvbnMgYmV0d2VlbiBpbnRlcm5hbCB0eXBlcy4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBNdWx0aUhhc2h0YWJsZTxUeXBlLCBUeXBlPiBJbnRlcm5hbFR5cGVNYXAgPSBuZXcgTXVsdGlIYXNodGFibGU8PigpOwotCi0gICAgc3RhdGljIHsKLSAgICAgICAgLy8gUG9zc2libGUgdHlwZSBjb252ZXJzaW9ucyBiZXR3ZWVuIGludGVybmFsIHR5cGVzCi0gICAgICAgIEludGVybmFsVHlwZU1hcC5wdXQoVHlwZS5Cb29sZWFuLCBUeXBlLkJvb2xlYW4pOwotICAgICAgICBJbnRlcm5hbFR5cGVNYXAucHV0KFR5cGUuQm9vbGVhbiwgVHlwZS5SZWFsKTsKLSAgICAgICAgSW50ZXJuYWxUeXBlTWFwLnB1dChUeXBlLkJvb2xlYW4sIFR5cGUuU3RyaW5nKTsKLSAgICAgICAgSW50ZXJuYWxUeXBlTWFwLnB1dChUeXBlLkJvb2xlYW4sIFR5cGUuUmVmZXJlbmNlKTsKLSAgICAgICAgSW50ZXJuYWxUeXBlTWFwLnB1dChUeXBlLkJvb2xlYW4sIFR5cGUuT2JqZWN0KTsKLQotICAgICAgICBJbnRlcm5hbFR5cGVNYXAucHV0KFR5cGUuUmVhbCwgVHlwZS5SZWFsKTsKLSAgICAgICAgSW50ZXJuYWxUeXBlTWFwLnB1dChUeXBlLlJlYWwsIFR5cGUuSW50KTsKLSAgICAgICAgSW50ZXJuYWxUeXBlTWFwLnB1dChUeXBlLlJlYWwsIFR5cGUuQm9vbGVhbik7Ci0gICAgICAgIEludGVybmFsVHlwZU1hcC5wdXQoVHlwZS5SZWFsLCBUeXBlLlN0cmluZyk7Ci0gICAgICAgIEludGVybmFsVHlwZU1hcC5wdXQoVHlwZS5SZWFsLCBUeXBlLlJlZmVyZW5jZSk7Ci0gICAgICAgIEludGVybmFsVHlwZU1hcC5wdXQoVHlwZS5SZWFsLCBUeXBlLk9iamVjdCk7Ci0KLSAgICAgICAgSW50ZXJuYWxUeXBlTWFwLnB1dChUeXBlLkludCwgVHlwZS5JbnQpOwotICAgICAgICBJbnRlcm5hbFR5cGVNYXAucHV0KFR5cGUuSW50LCBUeXBlLlJlYWwpOwotICAgICAgICBJbnRlcm5hbFR5cGVNYXAucHV0KFR5cGUuSW50LCBUeXBlLkJvb2xlYW4pOwotICAgICAgICBJbnRlcm5hbFR5cGVNYXAucHV0KFR5cGUuSW50LCBUeXBlLlN0cmluZyk7Ci0gICAgICAgIEludGVybmFsVHlwZU1hcC5wdXQoVHlwZS5JbnQsIFR5cGUuUmVmZXJlbmNlKTsKLSAgICAgICAgSW50ZXJuYWxUeXBlTWFwLnB1dChUeXBlLkludCwgVHlwZS5PYmplY3QpOwotCi0gICAgICAgIEludGVybmFsVHlwZU1hcC5wdXQoVHlwZS5TdHJpbmcsIFR5cGUuU3RyaW5nKTsKLSAgICAgICAgSW50ZXJuYWxUeXBlTWFwLnB1dChUeXBlLlN0cmluZywgVHlwZS5Cb29sZWFuKTsKLSAgICAgICAgSW50ZXJuYWxUeXBlTWFwLnB1dChUeXBlLlN0cmluZywgVHlwZS5SZWFsKTsKLSAgICAgICAgSW50ZXJuYWxUeXBlTWFwLnB1dChUeXBlLlN0cmluZywgVHlwZS5SZWZlcmVuY2UpOwotICAgICAgICBJbnRlcm5hbFR5cGVNYXAucHV0KFR5cGUuU3RyaW5nLCBUeXBlLk9iamVjdCk7Ci0KLSAgICAgICAgSW50ZXJuYWxUeXBlTWFwLnB1dChUeXBlLk5vZGVTZXQsIFR5cGUuTm9kZVNldCk7Ci0gICAgICAgIEludGVybmFsVHlwZU1hcC5wdXQoVHlwZS5Ob2RlU2V0LCBUeXBlLkJvb2xlYW4pOwotICAgICAgICBJbnRlcm5hbFR5cGVNYXAucHV0KFR5cGUuTm9kZVNldCwgVHlwZS5SZWFsKTsKLSAgICAgICAgSW50ZXJuYWxUeXBlTWFwLnB1dChUeXBlLk5vZGVTZXQsIFR5cGUuU3RyaW5nKTsKLSAgICAgICAgSW50ZXJuYWxUeXBlTWFwLnB1dChUeXBlLk5vZGVTZXQsIFR5cGUuTm9kZSk7Ci0gICAgICAgIEludGVybmFsVHlwZU1hcC5wdXQoVHlwZS5Ob2RlU2V0LCBUeXBlLlJlZmVyZW5jZSk7Ci0gICAgICAgIEludGVybmFsVHlwZU1hcC5wdXQoVHlwZS5Ob2RlU2V0LCBUeXBlLk9iamVjdCk7Ci0KLSAgICAgICAgSW50ZXJuYWxUeXBlTWFwLnB1dChUeXBlLk5vZGUsIFR5cGUuTm9kZSk7Ci0gICAgICAgIEludGVybmFsVHlwZU1hcC5wdXQoVHlwZS5Ob2RlLCBUeXBlLkJvb2xlYW4pOwotICAgICAgICBJbnRlcm5hbFR5cGVNYXAucHV0KFR5cGUuTm9kZSwgVHlwZS5SZWFsKTsKLSAgICAgICAgSW50ZXJuYWxUeXBlTWFwLnB1dChUeXBlLk5vZGUsIFR5cGUuU3RyaW5nKTsKLSAgICAgICAgSW50ZXJuYWxUeXBlTWFwLnB1dChUeXBlLk5vZGUsIFR5cGUuTm9kZVNldCk7Ci0gICAgICAgIEludGVybmFsVHlwZU1hcC5wdXQoVHlwZS5Ob2RlLCBUeXBlLlJlZmVyZW5jZSk7Ci0gICAgICAgIEludGVybmFsVHlwZU1hcC5wdXQoVHlwZS5Ob2RlLCBUeXBlLk9iamVjdCk7Ci0KLSAgICAgICAgSW50ZXJuYWxUeXBlTWFwLnB1dChUeXBlLlJlc3VsdFRyZWUsIFR5cGUuUmVzdWx0VHJlZSk7Ci0gICAgICAgIEludGVybmFsVHlwZU1hcC5wdXQoVHlwZS5SZXN1bHRUcmVlLCBUeXBlLkJvb2xlYW4pOwotICAgICAgICBJbnRlcm5hbFR5cGVNYXAucHV0KFR5cGUuUmVzdWx0VHJlZSwgVHlwZS5SZWFsKTsKLSAgICAgICAgSW50ZXJuYWxUeXBlTWFwLnB1dChUeXBlLlJlc3VsdFRyZWUsIFR5cGUuU3RyaW5nKTsKLSAgICAgICAgSW50ZXJuYWxUeXBlTWFwLnB1dChUeXBlLlJlc3VsdFRyZWUsIFR5cGUuTm9kZVNldCk7Ci0gICAgICAgIEludGVybmFsVHlwZU1hcC5wdXQoVHlwZS5SZXN1bHRUcmVlLCBUeXBlLlJlZmVyZW5jZSk7Ci0gICAgICAgIEludGVybmFsVHlwZU1hcC5wdXQoVHlwZS5SZXN1bHRUcmVlLCBUeXBlLk9iamVjdCk7Ci0KLSAgICAgICAgSW50ZXJuYWxUeXBlTWFwLnB1dChUeXBlLlJlZmVyZW5jZSwgVHlwZS5SZWZlcmVuY2UpOwotICAgICAgICBJbnRlcm5hbFR5cGVNYXAucHV0KFR5cGUuUmVmZXJlbmNlLCBUeXBlLkJvb2xlYW4pOwotICAgICAgICBJbnRlcm5hbFR5cGVNYXAucHV0KFR5cGUuUmVmZXJlbmNlLCBUeXBlLkludCk7Ci0gICAgICAgIEludGVybmFsVHlwZU1hcC5wdXQoVHlwZS5SZWZlcmVuY2UsIFR5cGUuUmVhbCk7Ci0gICAgICAgIEludGVybmFsVHlwZU1hcC5wdXQoVHlwZS5SZWZlcmVuY2UsIFR5cGUuU3RyaW5nKTsKLSAgICAgICAgSW50ZXJuYWxUeXBlTWFwLnB1dChUeXBlLlJlZmVyZW5jZSwgVHlwZS5Ob2RlKTsKLSAgICAgICAgSW50ZXJuYWxUeXBlTWFwLnB1dChUeXBlLlJlZmVyZW5jZSwgVHlwZS5Ob2RlU2V0KTsKLSAgICAgICAgSW50ZXJuYWxUeXBlTWFwLnB1dChUeXBlLlJlZmVyZW5jZSwgVHlwZS5SZXN1bHRUcmVlKTsKLSAgICAgICAgSW50ZXJuYWxUeXBlTWFwLnB1dChUeXBlLlJlZmVyZW5jZSwgVHlwZS5PYmplY3QpOwotCi0gICAgICAgIEludGVybmFsVHlwZU1hcC5wdXQoVHlwZS5PYmplY3QsIFR5cGUuU3RyaW5nKTsKLQotICAgICAgICBJbnRlcm5hbFR5cGVNYXAucHV0KFR5cGUuVm9pZCwgVHlwZS5TdHJpbmcpOwotCi0gICAgICAgIEludGVybmFsVHlwZU1hcC5tYWtlVW5tb2RpZmlhYmxlKCk7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBib29sZWFuIF90eXBlVGVzdCA9IGZhbHNlOwotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0IGEgY2FzdCBleHByZXNzaW9uIGFuZCBjaGVjayB0aGF0IHRoZSBjb252ZXJzaW9uIGlzCi0gICAgICogdmFsaWQgYnkgY2FsbGluZyB0eXBlQ2hlY2soKS4KLSAgICAgKi8KLSAgICBwdWJsaWMgQ2FzdEV4cHIoRXhwcmVzc2lvbiBsZWZ0LCBUeXBlIHR5cGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0gICAgICAgIF9sZWZ0ID0gbGVmdDsKLSAgICAgICAgX3R5cGUgPSB0eXBlOyAgICAgICAgICAgLy8gdXNlIGluaGVyaXRlZCBmaWVsZAotCi0gICAgICAgIGlmICgoX2xlZnQgaW5zdGFuY2VvZiBTdGVwKSAmJiAoX3R5cGUgPT0gVHlwZS5Cb29sZWFuKSkgewotICAgICAgICAgICAgU3RlcCBzdGVwID0gKFN0ZXApX2xlZnQ7Ci0gICAgICAgICAgICBpZiAoKHN0ZXAuZ2V0QXhpcygpID09IEF4aXMuU0VMRikgJiYgKHN0ZXAuZ2V0Tm9kZVR5cGUoKSAhPSAtMSkpCi0gICAgICAgICAgICAgICAgX3R5cGVUZXN0ID0gdHJ1ZTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIGNoZWNrIGlmIGNvbnZlcnNpb24gaXMgdmFsaWQKLSAgICAgICAgc2V0UGFyc2VyKGxlZnQuZ2V0UGFyc2VyKCkpOwotICAgICAgICBzZXRQYXJlbnQobGVmdC5nZXRQYXJlbnQoKSk7Ci0gICAgICAgIGxlZnQuc2V0UGFyZW50KHRoaXMpOwotICAgICAgICB0eXBlQ2hlY2sobGVmdC5nZXRQYXJzZXIoKS5nZXRTeW1ib2xUYWJsZSgpKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgRXhwcmVzc2lvbiBnZXRFeHByKCkgewotICAgICAgICByZXR1cm4gX2xlZnQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIGlmIHRoaXMgZXhwcmVzc2lvbnMgY29udGFpbnMgYSBjYWxsIHRvIHBvc2l0aW9uKCkuIFRoaXMgaXMKLSAgICAgKiBuZWVkZWQgZm9yIGNvbnRleHQgY2hhbmdlcyBpbiBub2RlIHN0ZXBzIGNvbnRhaW5pbmcgbXVsdGlwbGUgcHJlZGljYXRlcy4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBoYXNQb3NpdGlvbkNhbGwoKSB7Ci0gICAgICAgIHJldHVybihfbGVmdC5oYXNQb3NpdGlvbkNhbGwoKSk7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gaGFzTGFzdENhbGwoKSB7Ci0gICAgICAgIHJldHVybihfbGVmdC5oYXNMYXN0Q2FsbCgpKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgICAgICByZXR1cm4gImNhc3QoIiArIF9sZWZ0ICsgIiwgIiArIF90eXBlICsgIikiOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFR5cGUgY2hlY2tpbmcgYSBjYXN0IGV4cHJlc3Npb24gYW1vdW50cyB0byB2ZXJpZnlpbmcgdGhhdCB0aGUKLSAgICAgKiB0eXBlIGNvbnZlcnNpb24gaXMgbGVnYWwuIENhc3QgZXhwcmVzc2lvbnMgYXJlIGNyZWF0ZWQgZHVyaW5nCi0gICAgICogdHlwZSBjaGVja2luZywgYnV0IHR5cGVDaGVjaygpIGlzIHVzdWFsbHkgbm90IGNhbGxlZCBvbiB0aGVtLgotICAgICAqIEFzIGEgcmVzdWx0LCB0aGlzIG1ldGhvZCBpcyBjYWxsZWQgZnJvbSB0aGUgY29uc3RydWN0b3IuCi0gICAgICovCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLSAgICAgICAgVHlwZSB0bGVmdCA9IF9sZWZ0LmdldFR5cGUoKTsKLSAgICAgICAgaWYgKHRsZWZ0ID09IG51bGwpIHsKLSAgICAgICAgICAgIHRsZWZ0ID0gX2xlZnQudHlwZUNoZWNrKHN0YWJsZSk7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKHRsZWZ0IGluc3RhbmNlb2YgTm9kZVR5cGUpIHsKLSAgICAgICAgICAgIHRsZWZ0ID0gVHlwZS5Ob2RlOyAgLy8gbXVsdGlwbGUgaW5zdGFuY2VzCi0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAodGxlZnQgaW5zdGFuY2VvZiBSZXN1bHRUcmVlVHlwZSkgewotICAgICAgICAgICAgdGxlZnQgPSBUeXBlLlJlc3VsdFRyZWU7IC8vIG11bHRpcGxlIGluc3RhbmNlcwotICAgICAgICB9Ci0gICAgICAgIGlmIChJbnRlcm5hbFR5cGVNYXAubWFwcyh0bGVmdCwgX3R5cGUpICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBfdHlwZTsKLSAgICAgICAgfQotICAgICAgICAvLyB0aHJvdyBuZXcgVHlwZUNoZWNrRXJyb3IodGhpcyk7Ci0gICAgICAgIHRocm93IG5ldyBUeXBlQ2hlY2tFcnJvcihuZXcgRXJyb3JNc2coCi0gICAgICAgICAgICBFcnJvck1zZy5EQVRBX0NPTlZFUlNJT05fRVJSLCB0bGVmdC50b1N0cmluZygpLCBfdHlwZS50b1N0cmluZygpKSk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlRGVzeW50aGVzaXplZChDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLSAgICAgICAgRmxvd0xpc3QgZmw7Ci0gICAgICAgIGZpbmFsIFR5cGUgbHR5cGUgPSBfbGVmdC5nZXRUeXBlKCk7Ci0KLSAgICAgICAgLy8gVGhpcyBpcyBhIHNwZWNpYWwgY2FzZSBmb3IgdGhlIHNlbGY6OiBheGlzLiBJbnN0ZWFkIG9mIGxldHRpbmcKLSAgICAgICAgLy8gdGhlIFN0ZXAgb2JqZWN0IGNyZWF0ZSBhbmQgaXRlcmF0b3IgdGhhdCB3ZSBjYXN0IGJhY2sgdG8gYSBzaW5nbGUKLSAgICAgICAgLy8gbm9kZSwgd2Ugc2ltcGx5IGFzayB0aGUgRE9NIGZvciB0aGUgbm9kZSB0eXBlLgotICAgICAgICBpZiAoX3R5cGVUZXN0KSB7Ci0gICAgICAgICAgICBmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0KLSAgICAgICAgICAgIGZpbmFsIGludCBpZHggPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKERPTV9JTlRGLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImdldEV4cGFuZGVkVHlwZUlEIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoSSlJIik7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IFNJUFVTSCgoc2hvcnQpKChTdGVwKV9sZWZ0KS5nZXROb2RlVHlwZSgpKSk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRDb250ZXh0Tm9kZSgpKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFSU5URVJGQUNFKGlkeCwgMikpOwotICAgICAgICAgICAgX2ZhbHNlTGlzdC5hZGQoaWwuYXBwZW5kKG5ldyBJRl9JQ01QTkUobnVsbCkpKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLQotICAgICAgICAgICAgX2xlZnQudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICAgICAgaWYgKF90eXBlICE9IGx0eXBlKSB7Ci0gICAgICAgICAgICAgICAgX2xlZnQuc3RhcnRJdGVyYXRvcihjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgICAgICAgICBpZiAoX3R5cGUgaW5zdGFuY2VvZiBCb29sZWFuVHlwZSkgewotICAgICAgICAgICAgICAgICAgICBmbCA9IGx0eXBlLnRyYW5zbGF0ZVRvRGVzeW50aGVzaXplZChjbGFzc0dlbiwgbWV0aG9kR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdHlwZSk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChmbCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBfZmFsc2VMaXN0LmFwcGVuZChmbCk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIGx0eXBlLnRyYW5zbGF0ZVRvKGNsYXNzR2VuLCBtZXRob2RHZW4sIF90eXBlKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLSAgICAgICAgZmluYWwgVHlwZSBsdHlwZSA9IF9sZWZ0LmdldFR5cGUoKTsKLSAgICAgICAgX2xlZnQudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICBpZiAoX3R5cGUuaWRlbnRpY2FsVG8obHR5cGUpID09IGZhbHNlKSB7Ci0gICAgICAgICAgICBfbGVmdC5zdGFydEl0ZXJhdG9yKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICAgICAgbHR5cGUudHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgX3R5cGUpOwotICAgICAgICB9Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9DZWlsaW5nQ2FsbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9DZWlsaW5nQ2FsbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiMGI5ZGU5Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvQ2VpbGluZ0NhbGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDUwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IENlaWxpbmdDYWxsLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMDEgMTE6NTk6MTkgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQ29uc3RhbnRQb29sR2VuOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFU1RBVElDOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW5zdHJ1Y3Rpb25MaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkNsYXNzR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLk1ldGhvZEdlbmVyYXRvcjsKLQotLyoqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKi8KLWZpbmFsIGNsYXNzIENlaWxpbmdDYWxsIGV4dGVuZHMgRnVuY3Rpb25DYWxsIHsKLSAgICBwdWJsaWMgQ2VpbGluZ0NhbGwoUU5hbWUgZm5hbWUsIFZlY3RvciBhcmd1bWVudHMpIHsKLSAgICAgICAgc3VwZXIoZm5hbWUsIGFyZ3VtZW50cyk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0gICAgICAgIGZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotICAgICAgICBhcmd1bWVudCgwKS50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFU1RBVElDKGNwZy5hZGRNZXRob2RyZWYoTUFUSF9DTEFTUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiY2VpbCIsICIoRClEIikpKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0Nob29zZS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9DaG9vc2UuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMGUyMzgxOS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0Nob29zZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTY4ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKi8KLS8qCi0gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKLSAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAotICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgotICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKLSAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCi0gKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogQ2hvb3NlLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMDEgMTI6MDA6MTQgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5CcmFuY2hIYW5kbGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5HT1RPOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSUZFUTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uSGFuZGxlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW5zdHJ1Y3Rpb25MaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkNsYXNzR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkVycm9yTXNnOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLk1ldGhvZEdlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGVDaGVja0Vycm9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlV0aWw7Ci1pbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOwotaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi0vKioKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICovCi1maW5hbCBjbGFzcyBDaG9vc2UgZXh0ZW5kcyBJbnN0cnVjdGlvbiB7Ci0KLSAgICAvKioKLSAgICAgKiBEaXNwbGF5IHRoZSBlbGVtZW50IGNvbnRlbnRzIChhIGxvdCBvZiB3aGVuJ3MgYW5kIGFuIG90aGVyd2lzZSkKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBkaXNwbGF5KGludCBpbmRlbnQpIHsKLSAgICAgICAgaW5kZW50KGluZGVudCk7Ci0gICAgICAgIFV0aWwucHJpbnRsbigiQ2hvb3NlIik7Ci0gICAgICAgIGluZGVudChpbmRlbnQgKyBJbmRlbnRJbmNyZW1lbnQpOwotICAgICAgICBkaXNwbGF5Q29udGVudHMoaW5kZW50ICsgSW5kZW50SW5jcmVtZW50KTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGUgdGhpcyBDaG9vc2UgZWxlbWVudC4gR2VuZXJhdGUgYSB0ZXN0LWNoYWluIGZvciB0aGUgdmFyaW91cwotICAgICAqIDx4c2w6d2hlbj4gZWxlbWVudHMgYW5kIGRlZmF1bHQgdG8gdGhlIDx4c2w6b3RoZXJ3aXNlPiBpZiBwcmVzZW50LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotICAgICAgICBmaW5hbCBWZWN0b3Igd2hlbkVsZW1lbnRzID0gbmV3IFZlY3RvcigpOwotICAgICAgICBPdGhlcndpc2Ugb3RoZXJ3aXNlID0gbnVsbDsKLSAgICAgICAgSXRlcmF0b3I8U3ludGF4VHJlZU5vZGU+IGVsZW1lbnRzID0gZWxlbWVudHMoKTsKLQotICAgICAgICAvLyBUaGVzZSB0d28gYXJlIGZvciByZXBvcnRpbmcgZXJyb3JzIG9ubHkKLSAgICAgICAgRXJyb3JNc2cgZXJyb3IgPSBudWxsOwotICAgICAgICBmaW5hbCBpbnQgbGluZSA9IGdldExpbmVOdW1iZXIoKTsKLQotICAgICAgICAvLyBUcmF2ZXJzZSBhbGwgY2hpbGQgbm9kZXMgLSBtdXN0IGJlIGVpdGhlciBXaGVuIG9yIE90aGVyd2lzZQotICAgICAgICB3aGlsZSAoZWxlbWVudHMuaGFzTmV4dCgpKSB7Ci0gICAgICAgICAgICBTeW50YXhUcmVlTm9kZSBlbGVtZW50ID0gZWxlbWVudHMubmV4dCgpOwotICAgICAgICAgICAgLy8gQWRkIGEgV2hlbiBjaGlsZCBlbGVtZW50Ci0gICAgICAgICAgICBpZiAoZWxlbWVudCBpbnN0YW5jZW9mIFdoZW4pIHsKLSAgICAgICAgICAgICAgICB3aGVuRWxlbWVudHMuYWRkRWxlbWVudChlbGVtZW50KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIEFkZCBhbiBPdGhlcndpc2UgY2hpbGQgZWxlbWVudAotICAgICAgICAgICAgZWxzZSBpZiAoZWxlbWVudCBpbnN0YW5jZW9mIE90aGVyd2lzZSkgewotICAgICAgICAgICAgICAgIGlmIChvdGhlcndpc2UgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBvdGhlcndpc2UgPSAoT3RoZXJ3aXNlKWVsZW1lbnQ7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICBlcnJvciA9IG5ldyBFcnJvck1zZyhFcnJvck1zZy5NVUxUSVBMRV9PVEhFUldJU0VfRVJSLCB0aGlzKTsKLSAgICAgICAgICAgICAgICAgICAgZ2V0UGFyc2VyKCkucmVwb3J0RXJyb3IoQ29uc3RhbnRzLkVSUk9SLCBlcnJvcik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoZWxlbWVudCBpbnN0YW5jZW9mIFRleHQpIHsKLSAgICAgICAgICAgICAgICAoKFRleHQpZWxlbWVudCkuaWdub3JlKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyBJdCBpcyBhbiBlcnJvciBpZiB3ZSBmaW5kIHNvbWUgb3RoZXIgZWxlbWVudCBoZXJlCi0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBlcnJvciA9IG5ldyBFcnJvck1zZyhFcnJvck1zZy5XSEVOX0VMRU1FTlRfRVJSLCB0aGlzKTsKLSAgICAgICAgICAgICAgICBnZXRQYXJzZXIoKS5yZXBvcnRFcnJvcihDb25zdGFudHMuRVJST1IsIGVycm9yKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIE1ha2Ugc3VyZSB0aGF0IHRoZXJlIGlzIGF0IGxlYXN0IG9uZSA8eHNsOndoZW4+IGVsZW1lbnQKLSAgICAgICAgaWYgKHdoZW5FbGVtZW50cy5zaXplKCkgPT0gMCkgewotICAgICAgICAgICAgZXJyb3IgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuTUlTU0lOR19XSEVOX0VSUiwgdGhpcyk7Ci0gICAgICAgICAgICBnZXRQYXJzZXIoKS5yZXBvcnRFcnJvcihDb25zdGFudHMuRVJST1IsIGVycm9yKTsKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotCi0gICAgICAgIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQotICAgICAgICAvLyBuZXh0IGVsZW1lbnQgd2lsbCBob2xkIGEgaGFuZGxlIHRvIHRoZSBiZWdpbm5pbmcgb2YgbmV4dAotICAgICAgICAvLyBXaGVuL090aGVyd2lzZSBpZiB0ZXN0IG9uIGN1cnJlbnQgV2hlbiBmYWlscwotICAgICAgICBCcmFuY2hIYW5kbGUgbmV4dEVsZW1lbnQgPSBudWxsOwotICAgICAgICBWZWN0b3IgZXhpdEhhbmRsZXMgPSBuZXcgVmVjdG9yKCk7Ci0gICAgICAgIEluc3RydWN0aW9uSGFuZGxlIGV4aXQgPSBudWxsOwotCi0gICAgICAgIEVudW1lcmF0aW9uIHdoZW5zID0gd2hlbkVsZW1lbnRzLmVsZW1lbnRzKCk7Ci0gICAgICAgIHdoaWxlICh3aGVucy5oYXNNb3JlRWxlbWVudHMoKSkgewotICAgICAgICAgICAgZmluYWwgV2hlbiB3aGVuID0gKFdoZW4pd2hlbnMubmV4dEVsZW1lbnQoKTsKLSAgICAgICAgICAgIGZpbmFsIEV4cHJlc3Npb24gdGVzdCA9IHdoZW4uZ2V0VGVzdCgpOwotCi0gICAgICAgICAgICBJbnN0cnVjdGlvbkhhbmRsZSB0cnVlYyA9IGlsLmdldEVuZCgpOwotCi0gICAgICAgICAgICBpZiAobmV4dEVsZW1lbnQgIT0gbnVsbCkKLSAgICAgICAgICAgICAgICBuZXh0RWxlbWVudC5zZXRUYXJnZXQoaWwuYXBwZW5kKE5PUCkpOwotICAgICAgICAgICAgdGVzdC50cmFuc2xhdGVEZXN5bnRoZXNpemVkKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCi0gICAgICAgICAgICBpZiAodGVzdCBpbnN0YW5jZW9mIEZ1bmN0aW9uQ2FsbCkgewotICAgICAgICAgICAgICAgIEZ1bmN0aW9uQ2FsbCBjYWxsID0gKEZ1bmN0aW9uQ2FsbCl0ZXN0OwotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgIFR5cGUgdHlwZSA9IGNhbGwudHlwZUNoZWNrKGdldFBhcnNlcigpLmdldFN5bWJvbFRhYmxlKCkpOwotICAgICAgICAgICAgICAgICAgICBpZiAodHlwZSAhPSBUeXBlLkJvb2xlYW4pIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHRlc3QuX2ZhbHNlTGlzdC5hZGQoaWwuYXBwZW5kKG5ldyBJRkVRKG51bGwpKSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgY2F0Y2ggKFR5cGVDaGVja0Vycm9yIGUpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gaGFuZGxlZCBsYXRlciEKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyByZW1lbWJlciBlbmQgb2YgY29uZGl0aW9uCi0gICAgICAgICAgICB0cnVlYyA9IGlsLmdldEVuZCgpOwotCi0gICAgICAgICAgICAvLyBUaGUgV2hlbiBvYmplY3Qgc2hvdWxkIGJlIGlnbm9yZWQgY29tcGxldGVseSBpbiBjYXNlIGl0IHRlc3RzCi0gICAgICAgICAgICAvLyBmb3IgdGhlIHN1cHBvcnQgb2YgYSBub24tYXZhaWxhYmxlIGVsZW1lbnQKLSAgICAgICAgICAgIGlmICghd2hlbi5pZ25vcmUoKSkgd2hlbi50cmFuc2xhdGVDb250ZW50cyhjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQotICAgICAgICAgICAgLy8gZ290byBleGl0IGFmdGVyIGV4ZWN1dGluZyB0aGUgYm9keSBvZiB3aGVuCi0gICAgICAgICAgICBleGl0SGFuZGxlcy5hZGRFbGVtZW50KGlsLmFwcGVuZChuZXcgR09UTyhudWxsKSkpOwotICAgICAgICAgICAgaWYgKHdoZW5zLmhhc01vcmVFbGVtZW50cygpIHx8IG90aGVyd2lzZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgbmV4dEVsZW1lbnQgPSBpbC5hcHBlbmQobmV3IEdPVE8obnVsbCkpOwotICAgICAgICAgICAgICAgIHRlc3QuYmFja1BhdGNoRmFsc2VMaXN0KG5leHRFbGVtZW50KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICB0ZXN0LmJhY2tQYXRjaEZhbHNlTGlzdChleGl0ID0gaWwuYXBwZW5kKE5PUCkpOwotICAgICAgICAgICAgdGVzdC5iYWNrUGF0Y2hUcnVlTGlzdCh0cnVlYy5nZXROZXh0KCkpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gVHJhbnNsYXRlIGFueSA8eHNsOm90aGVyd2lzZT4gZWxlbWVudAotICAgICAgICBpZiAob3RoZXJ3aXNlICE9IG51bGwpIHsKLSAgICAgICAgICAgIG5leHRFbGVtZW50LnNldFRhcmdldChpbC5hcHBlbmQoTk9QKSk7Ci0gICAgICAgICAgICBvdGhlcndpc2UudHJhbnNsYXRlQ29udGVudHMoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgICAgICBleGl0ID0gaWwuYXBwZW5kKE5PUCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBub3cgdGhhdCBlbmQgaXMga25vd24gc2V0IHRhcmdldHMgb2YgZXhpdCBnb3RvcwotICAgICAgICBFbnVtZXJhdGlvbiBleGl0R290b3MgPSBleGl0SGFuZGxlcy5lbGVtZW50cygpOwotICAgICAgICB3aGlsZSAoZXhpdEdvdG9zLmhhc01vcmVFbGVtZW50cygpKSB7Ci0gICAgICAgICAgICBCcmFuY2hIYW5kbGUgZ290b0V4aXQgPSAoQnJhbmNoSGFuZGxlKWV4aXRHb3Rvcy5uZXh0RWxlbWVudCgpOwotICAgICAgICAgICAgZ290b0V4aXQuc2V0VGFyZ2V0KGV4aXQpOwotICAgICAgICB9Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9DbG9zdXJlLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0Nsb3N1cmUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDZkNzgwMS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0Nsb3N1cmUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDUyICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IENsb3N1cmUuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8wMSAxMjowMToyMyBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXI7Ci0KLS8qKgotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgQ2xvc3VyZSB7Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhpcyBjbG9zdXJlIGlzIGNvbXBpbGVkIGluIGFuIGlubmVyIGNsYXNzIChpLmUuCi0gICAgICogaWYgdGhpcyBpcyBhIHJlYWwgY2xvc3VyZSkuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaW5Jbm5lckNsYXNzKCk7Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGEgcmVmZXJlbmNlIHRvIGl0cyBwYXJlbnQgY2xvc3VyZSBvciBudWxsIGlmIG91dGVybW9zdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgQ2xvc3VyZSBnZXRQYXJlbnRDbG9zdXJlKCk7Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSBhdXhpbGlhcnkgY2xhc3Mgb3IgbnVsbCBpZiB0aGlzIHByZWRpY2F0ZQotICAgICAqIGlzIGNvbXBpbGVkIGluc2lkZSB0aGUgVHJhbnNsZXQuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRJbm5lckNsYXNzTmFtZSgpOwotCi0gICAgLyoqCi0gICAgICogQWRkIG5ldyB2YXJpYWJsZSB0byB0aGUgY2xvc3VyZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBhZGRWYXJpYWJsZShWYXJpYWJsZVJlZkJhc2UgdmFyaWFibGVSZWYpOwotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9Db21tZW50LmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0NvbW1lbnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMGIyNWE0NS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0NvbW1lbnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExOCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBDb21tZW50LmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMDEgMTI6MDI6MzcgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5Db25zdGFudFBvb2xHZW47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5HRVRGSUVMRDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklOVk9LRUlOVEVSRkFDRTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklOVk9LRVZJUlRVQUw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5QVVNIOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW5zdHJ1Y3Rpb25MaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkNsYXNzR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLk1ldGhvZEdlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGVDaGVja0Vycm9yOwotCi0vKioKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICovCi1maW5hbCBjbGFzcyBDb21tZW50IGV4dGVuZHMgSW5zdHJ1Y3Rpb24gewotCi0gICAgcHVibGljIHZvaWQgcGFyc2VDb250ZW50cyhQYXJzZXIgcGFyc2VyKSB7Ci0gICAgICAgIHBhcnNlQ2hpbGRyZW4ocGFyc2VyKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgVHlwZSB0eXBlQ2hlY2soU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgewotICAgICAgICB0eXBlQ2hlY2tDb250ZW50cyhzdGFibGUpOwotICAgICAgICByZXR1cm4gVHlwZS5TdHJpbmc7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0gICAgICAgIGZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCi0gICAgICAgIC8vIFNob3J0Y3V0IGZvciBsaXRlcmFsIHN0cmluZ3MKLSAgICAgICAgVGV4dCByYXdUZXh0ID0gbnVsbDsKLSAgICAgICAgaWYgKGVsZW1lbnRDb3VudCgpID09IDEpIHsKLSAgICAgICAgICAgIE9iamVjdCBjb250ZW50ID0gZWxlbWVudEF0KDApOwotICAgICAgICAgICAgaWYgKGNvbnRlbnQgaW5zdGFuY2VvZiBUZXh0KSB7Ci0gICAgICAgICAgICAgICAgcmF3VGV4dCA9IChUZXh0KSBjb250ZW50OwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gSWYgdGhlIGNvbnRlbnQgaXMgbGl0ZXJhbCB0ZXh0LCBjYWxsIGNvbW1lbnQoY2hhcltdLGludCxpbnQpIG9yCi0gICAgICAgIC8vIGNvbW1lbnQoU3RyaW5nKSwgYXMgYXBwcm9wcmlhdGUuICBPdGhlcndpc2UsIHVzZSBhCi0gICAgICAgIC8vIFN0cmluZ1ZhbHVlSGFuZGxlciB0byBnYXRoZXIgdGhlIHRleHR1YWwgY29udGVudCBvZiB0aGUgeHNsOmNvbW1lbnQKLSAgICAgICAgLy8gYW5kIGNhbGwgY29tbWVudChTdHJpbmcpIHdpdGggdGhlIHJlc3VsdC4KLSAgICAgICAgaWYgKHJhd1RleHQgIT0gbnVsbCkgewotICAgICAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkSGFuZGxlcigpKTsKLQotICAgICAgICAgICAgaWYgKHJhd1RleHQuY2FuTG9hZEFzQXJyYXlPZmZzZXRMZW5ndGgoKSkgewotICAgICAgICAgICAgICAgIHJhd1RleHQubG9hZEFzQXJyYXlPZmZzZXRMZW5ndGgoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgICAgICAgICAgZmluYWwgaW50IGNvbW1lbnQgPQotICAgICAgICAgICAgICAgICAgICAgICAgY3BnLmFkZEludGVyZmFjZU1ldGhvZHJlZihUUkFOU0xFVF9PVVRQVVRfSU5URVJGQUNFLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiY29tbWVudCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoW0NJSSlWIik7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0UoY29tbWVudCwgNCkpOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCByYXdUZXh0LmdldFRleHQoKSkpOwotICAgICAgICAgICAgICAgIGZpbmFsIGludCBjb21tZW50ID0KLSAgICAgICAgICAgICAgICAgICAgICAgIGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoVFJBTlNMRVRfT1VUUFVUX0lOVEVSRkFDRSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImNvbW1lbnQiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKCIgKyBTVFJJTkdfU0lHICsgIilWIik7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0UoY29tbWVudCwgMikpOwotICAgICAgICAgICAgfQotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgLy8gU2F2ZSB0aGUgY3VycmVudCBoYW5kbGVyIGJhc2Ugb24gdGhlIHN0YWNrCi0gICAgICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRIYW5kbGVyKCkpOwotICAgICAgICAgICAgaWwuYXBwZW5kKERVUCk7ICAgICAgICAgICAgIC8vIGZpcnN0IGFyZyB0byAiY29tbWVudCIgY2FsbAotCi0gICAgICAgICAgICAvLyBHZXQgdGhlIHRyYW5zbGV0J3MgU3RyaW5nVmFsdWVIYW5kbGVyCi0gICAgICAgICAgICBpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBHRVRGSUVMRChjcGcuYWRkRmllbGRyZWYoVFJBTlNMRVRfQ0xBU1MsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAic3RyaW5nVmFsdWVIYW5kbGVyIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNUUklOR19WQUxVRV9IQU5ETEVSX1NJRykpKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChEVVApOwotICAgICAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5zdG9yZUhhbmRsZXIoKSk7Ci0KLSAgICAgICAgICAgIC8vIHRyYW5zbGF0ZSBjb250ZW50cyB3aXRoIHN1YnN0aXR1dGVkIGhhbmRsZXIKLSAgICAgICAgICAgIHRyYW5zbGF0ZUNvbnRlbnRzKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCi0gICAgICAgICAgICAvLyBnZXQgU3RyaW5nIG91dCBvZiB0aGUgaGFuZGxlcgotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VWSVJUVUFMKGNwZy5hZGRNZXRob2RyZWYoU1RSSU5HX1ZBTFVFX0hBTkRMRVIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZ2V0VmFsdWUiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIigpIiArIFNUUklOR19TSUcpKSk7Ci0gICAgICAgICAgICAvLyBjYWxsICJjb21tZW50IgotICAgICAgICAgICAgZmluYWwgaW50IGNvbW1lbnQgPQotICAgICAgICAgICAgICAgICAgICAgICAgY3BnLmFkZEludGVyZmFjZU1ldGhvZHJlZihUUkFOU0xFVF9PVVRQVVRfSU5URVJGQUNFLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiY29tbWVudCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoIiArIFNUUklOR19TSUcgKyAiKVYiKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFSU5URVJGQUNFKGNvbW1lbnQsIDIpKTsKLSAgICAgICAgICAgIC8vIFJlc3RvcmUgb2xkIGhhbmRsZXIgYmFzZSBmcm9tIHN0YWNrCi0gICAgICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLnN0b3JlSGFuZGxlcigpKTsKLSAgICAgICAgfQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvQ29tcGlsZXJFeGNlcHRpb24uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvQ29tcGlsZXJFeGNlcHRpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYzhmNjczZS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0NvbXBpbGVyRXhjZXB0aW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw1NiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBDb21waWxlckV4Y2VwdGlvbi5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzAxIDEyOjA0OjIyIHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlcjsKLQotLyoqCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIENvbXBpbGVyRXhjZXB0aW9uIGV4dGVuZHMgRXhjZXB0aW9uIHsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMTczMjkzOTYxODU2Mjc0MjY2M0w7Ci0KLSAgICBwcml2YXRlIFN0cmluZyBfbXNnOwotCi0gICAgcHVibGljIENvbXBpbGVyRXhjZXB0aW9uKCkgewotICAgICAgICBzdXBlcigpOwotICAgIH0KLQotICAgIHB1YmxpYyBDb21waWxlckV4Y2VwdGlvbihFeGNlcHRpb24gZSkgewotICAgICAgICBzdXBlcihlLnRvU3RyaW5nKCkpOwotICAgICAgICBfbXNnID0gZS50b1N0cmluZygpOwotICAgIH0KLQotICAgIHB1YmxpYyBDb21waWxlckV4Y2VwdGlvbihTdHJpbmcgbWVzc2FnZSkgewotICAgICAgICBzdXBlcihtZXNzYWdlKTsKLSAgICAgICAgX21zZyA9IG1lc3NhZ2U7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRNZXNzYWdlKCkgewotICAgICAgICBmaW5hbCBpbnQgY29sID0gX21zZy5pbmRleE9mKCc6Jyk7Ci0KLSAgICAgICAgaWYgKGNvbCA+IC0xKQotICAgICAgICAgICAgcmV0dXJuKF9tc2cuc3Vic3RyaW5nKGNvbCkpOwotICAgICAgICBlbHNlCi0gICAgICAgICAgICByZXR1cm4oX21zZyk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9Db25jYXRDYWxsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0NvbmNhdENhbGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNGIzYWM2YS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0NvbmNhdENhbGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDk3ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IENvbmNhdENhbGwuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8wMSAxMjowNzozMSBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5Db25zdGFudFBvb2xHZW47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JTlZPS0VTUEVDSUFMOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFVklSVFVBTDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW5zdHJ1Y3Rpb25MaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuTkVXOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuUFVTSDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5DbGFzc0dlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5NZXRob2RHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlQ2hlY2tFcnJvcjsKLQotLyoqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKi8KLWZpbmFsIGNsYXNzIENvbmNhdENhbGwgZXh0ZW5kcyBGdW5jdGlvbkNhbGwgewotICAgIHB1YmxpYyBDb25jYXRDYWxsKFFOYW1lIGZuYW1lLCBWZWN0b3IgYXJndW1lbnRzKSB7Ci0gICAgICAgIHN1cGVyKGZuYW1lLCBhcmd1bWVudHMpOwotICAgIH0KLQotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYXJndW1lbnRDb3VudCgpOyBpKyspIHsKLSAgICAgICAgICAgIGZpbmFsIEV4cHJlc3Npb24gZXhwID0gYXJndW1lbnQoaSk7Ci0gICAgICAgICAgICBpZiAoIWV4cC50eXBlQ2hlY2soc3RhYmxlKS5pZGVudGljYWxUbyhUeXBlLlN0cmluZykpIHsKLSAgICAgICAgICAgICAgICBzZXRBcmd1bWVudChpLCBuZXcgQ2FzdEV4cHIoZXhwLCBUeXBlLlN0cmluZykpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBfdHlwZSA9IFR5cGUuU3RyaW5nOwotICAgIH0KLQotICAgIC8qKiB0cmFuc2xhdGUgbGVhdmVzIGEgU3RyaW5nIG9uIHRoZSBzdGFjayAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotICAgICAgICBmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLSAgICAgICAgZmluYWwgaW50IG5BcmdzID0gYXJndW1lbnRDb3VudCgpOwotCi0gICAgICAgIHN3aXRjaCAobkFyZ3MpIHsKLSAgICAgICAgY2FzZSAwOgotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgRU1QVFlTVFJJTkcpKTsKLSAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgIGNhc2UgMToKLSAgICAgICAgICAgIGFyZ3VtZW50KCkudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgZGVmYXVsdDoKLSAgICAgICAgICAgIGZpbmFsIGludCBpbml0QnVmZmVyID0gY3BnLmFkZE1ldGhvZHJlZihTVFJJTkdfQlVGRkVSX0NMQVNTLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI8aW5pdD4iLCAiKClWIik7Ci0gICAgICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbiBhcHBlbmQgPQotICAgICAgICAgICAgICAgIG5ldyBJTlZPS0VWSVJUVUFMKGNwZy5hZGRNZXRob2RyZWYoU1RSSU5HX0JVRkZFUl9DTEFTUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJhcHBlbmQiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIigiK1NUUklOR19TSUcrIikiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArU1RSSU5HX0JVRkZFUl9TSUcpKTsKLQotICAgICAgICAgICAgZmluYWwgaW50IHRvU3RyaW5nID0gY3BnLmFkZE1ldGhvZHJlZihTVFJJTkdfQlVGRkVSX0NMQVNTLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidG9TdHJpbmciLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKCkiK1NUUklOR19TSUcpOwotCi0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IE5FVyhjcGcuYWRkQ2xhc3MoU1RSSU5HX0JVRkZFUl9DTEFTUykpKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChEVVApOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VTUEVDSUFMKGluaXRCdWZmZXIpKTsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbkFyZ3M7IGkrKykgewotICAgICAgICAgICAgICAgIGFyZ3VtZW50KGkpLnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQoYXBwZW5kKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTCh0b1N0cmluZykpOwotICAgICAgICB9Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9Db25zdGFudHMuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvQ29uc3RhbnRzLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDZkZDVjMTQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9Db25zdGFudHMuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDUwOCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBDb25zdGFudHMuamF2YSx2IDEuNyAyMDA2LzA2LzE5IDE5OjQ5OjA0IHNwZXJpY2FzIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uQ29uc3RhbnRzOwotCi0vKioKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqLwotcHVibGljIGludGVyZmFjZSBDb25zdGFudHMgZXh0ZW5kcyBJbnN0cnVjdGlvbkNvbnN0YW50cyB7Ci0KLSAgICAvLyBFcnJvciBjYXRlZ29yaWVzIHVzZWQgdG8gcmVwb3J0IGVycm9ycyB0byBQYXJzZXIucmVwb3J0RXJyb3IoKQotCi0gICAgLy8gVW5leHBlY3RlZCBpbnRlcm5hbCBlcnJvcnMsIHN1Y2ggYXMgbnVsbC1wdHIgZXhjZXB0aW9ucywgZXRjLgotICAgIC8vIEltbWVkaWF0ZWx5IHRlcm1pbmF0ZXMgY29tcGlsYXRpb24sIG5vIHRyYW5zbGV0IHByb2R1Y2VkCi0gICAgcHVibGljIGZpbmFsIGludCBJTlRFUk5BTCAgICAgICAgPSAwOwotICAgIC8vIFhTTFQgZWxlbWVudHMgdGhhdCBhcmUgbm90IGltcGxlbWVudGVkIGFuZCB1bnN1cHBvcnRlZCBleHQuCi0gICAgLy8gSW1tZWRpYXRlbHkgdGVybWluYXRlcyBjb21waWxhdGlvbiwgbm8gdHJhbnNsZXQgcHJvZHVjZWQKLSAgICBwdWJsaWMgZmluYWwgaW50IFVOU1VQUE9SVEVEICAgICA9IDE7Ci0gICAgLy8gRmF0YWwgZXJyb3IgaW4gdGhlIHN0eWxlc2hlZXQgaW5wdXQgKHBhcnNpbmcgb3IgY29udGVudCkKLSAgICAvLyBJbW1lZGlhdGVseSB0ZXJtaW5hdGVzIGNvbXBpbGF0aW9uLCBubyB0cmFuc2xldCBwcm9kdWNlZAotICAgIHB1YmxpYyBmaW5hbCBpbnQgRkFUQUwgICAgICAgICAgID0gMjsKLSAgICAvLyBPdGhlciBlcnJvciBpbiB0aGUgc3R5bGVzaGVldCBpbnB1dCAocGFyc2luZyBvciBjb250ZW50KQotICAgIC8vIERvZXMgbm90IHRlcm1pbmF0ZSBjb21waWxhdGlvbiwgbm8gdHJhbnNsZXQgcHJvZHVjZWQKLSAgICBwdWJsaWMgZmluYWwgaW50IEVSUk9SICAgICAgICAgICA9IDM7Ci0gICAgLy8gT3RoZXIgZXJyb3IgaW4gdGhlIHN0eWxlc2hlZXQgaW5wdXQgKGNvbnRlbnQgZXJyb3JzIG9ubHkpCi0gICAgLy8gRG9lcyBub3QgdGVybWluYXRlIGNvbXBpbGF0aW9uLCBhIHRyYW5zbGV0IGlzIHByb2R1Y2VkCi0gICAgcHVibGljIGZpbmFsIGludCBXQVJOSU5HICAgICAgICAgPSA0OwotCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRU1QVFlTVFJJTkcgPSAiIjsKLQotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIE5BTUVTUEFDRV9GRUFUVVJFID0KLSAgICAgICAgImh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy9uYW1lc3BhY2VzIjsKLQotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFRSQU5TTEVUX0lOVEYKLSAgICAgICAgPSAiY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLlRyYW5zbGV0IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBUUkFOU0xFVF9JTlRGX1NJRwotICAgICAgICA9ICJMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1RyYW5zbGV0OyI7Ci0KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRSSUJVVEVTX1NJRwotICAgICAgICA9ICJMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvQXR0cmlidXRlczsiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIE5PREVfSVRFUkFUT1JfU0lHCi0gICAgICAgID0gIkxjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBET01fSU5URl9TSUcKLSAgICAgICAgPSAiTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBET01fSU1QTF9DTEFTUwotICAgICAgICA9ICJjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NIjsgLy8geG1sL2R0bS9yZWYvRFRNRGVmYXVsdEJhc2VJdGVyYXRvcnMiOyAvL3hhbGFuL3hzbHRjL2RvbS9ET01JbXBsIjsKLSAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU0FYX0lNUExfQ0xBU1MKLSAgICAgICAgPSAiY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTS9TQVhJbXBsIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBET01fSU1QTF9TSUcKLSAgICAgICAgPSAiTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vU0FYSW1wbDsiOyAvL3htbC9kdG0vcmVmL0RUTURlZmF1bHRCYXNlSXRlcmF0b3JzIjsgLy94YWxhbi94c2x0Yy9kb20vRE9NSW1wbDsiOwotICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBTQVhfSU1QTF9TSUcKLSAgICAgICAgPSAiTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vU0FYSW1wbDsiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIERPTV9BREFQVEVSX0NMQVNTCi0gICAgICAgID0gImNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vRE9NQWRhcHRlciI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRE9NX0FEQVBURVJfU0lHCi0gICAgICAgID0gIkxjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvZG9tL0RPTUFkYXB0ZXI7IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBNVUxUSV9ET01fQ0xBU1MKLSAgICAgICAgPSAiY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmRvbS5NdWx0aURPTSI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTVVMVElfRE9NX1NJRwotICAgICAgICA9ICJMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2RvbS9NdWx0aURPTTsiOwotCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1RSSU5HCi0gICAgICAgID0gImphdmEubGFuZy5TdHJpbmciOwotCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQUNDX1BVQkxJQwotICAgICAgICA9IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5BQ0NfUFVCTElDOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFDQ19TVVBFUgotICAgICAgICA9IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5BQ0NfU1VQRVI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQUNDX0ZJTkFMCi0gICAgICAgID0gY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkFDQ19GSU5BTDsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBQ0NfUFJJVkFURQotICAgICAgICA9IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5BQ0NfUFJJVkFURTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBQ0NfUFJPVEVDVEVECi0gICAgICAgID0gY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkFDQ19QUk9URUNURUQ7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQUNDX1NUQVRJQwotICAgICAgICA9IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50cy5BQ0NfU1RBVElDOwotCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1RSSU5HX1NJRwotICAgICAgICA9ICJMamF2YS9sYW5nL1N0cmluZzsiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFNUUklOR19CVUZGRVJfU0lHCi0gICAgICAgID0gIkxqYXZhL2xhbmcvU3RyaW5nQnVmZmVyOyI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgT0JKRUNUX1NJRwotICAgICAgICA9ICJMamF2YS9sYW5nL09iamVjdDsiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIERPVUJMRV9TSUcKLSAgICAgICAgPSAiTGphdmEvbGFuZy9Eb3VibGU7IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBJTlRFR0VSX1NJRwotICAgICAgICA9ICJMamF2YS9sYW5nL0ludGVnZXI7IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBDT0xMQVRPUl9DTEFTUwotICAgICAgICA9ICJqYXZhL3RleHQvQ29sbGF0b3IiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIENPTExBVE9SX1NJRwotICAgICAgICA9ICJMamF2YS90ZXh0L0NvbGxhdG9yOyI7Ci0KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBOT0RFCi0gICAgICAgID0gImludCI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTk9ERV9JVEVSQVRPUgotICAgICAgICA9ICJjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1BeGlzSXRlcmF0b3IiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIE5PREVfSVRFUkFUT1JfQkFTRQotICAgICAgICA9ICJjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5yZWYuRFRNQXhpc0l0ZXJhdG9yQmFzZSI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU09SVF9JVEVSQVRPUgotICAgICAgICA9ICJjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuZG9tLlNvcnRpbmdJdGVyYXRvciI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU09SVF9JVEVSQVRPUl9TSUcKLSAgICAgICAgPSAiTGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5kb20uU29ydGluZ0l0ZXJhdG9yOyI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTk9ERV9TT1JUX1JFQ09SRAotICAgICAgICA9ICJjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuZG9tLk5vZGVTb3J0UmVjb3JkIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBOT0RFX1NPUlRfRkFDVE9SWQotICAgICAgICA9ICJjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvZG9tL05vZGVTb3J0UmVjb3JkRmFjdG9yeSI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTk9ERV9TT1JUX1JFQ09SRF9TSUcKLSAgICAgICAgPSAiTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vTm9kZVNvcnRSZWNvcmQ7IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBOT0RFX1NPUlRfRkFDVE9SWV9TSUcKLSAgICAgICAgPSAiTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vTm9kZVNvcnRSZWNvcmRGYWN0b3J5OyI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTE9DQUxFX0NMQVNTCi0gICAgICAgID0gImphdmEudXRpbC5Mb2NhbGUiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIExPQ0FMRV9TSUcKLSAgICAgICAgPSAiTGphdmEvdXRpbC9Mb2NhbGU7IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBTVFJJTkdfVkFMVUVfSEFORExFUgotICAgICAgICA9ICJjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMucnVudGltZS5TdHJpbmdWYWx1ZUhhbmRsZXIiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFNUUklOR19WQUxVRV9IQU5ETEVSX1NJRwotICAgICAgICA9ICJMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvU3RyaW5nVmFsdWVIYW5kbGVyOyI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgT1VUUFVUX0hBTkRMRVIKLSAgICAgICAgPSAiY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBPVVRQVVRfSEFORExFUl9TSUcKLSAgICAgICAgPSAiTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjsiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEZJTFRFUl9JTlRFUkZBQ0UKLSAgICAgICAgPSAiY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmRvbS5GaWx0ZXIiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEZJTFRFUl9JTlRFUkZBQ0VfU0lHCi0gICAgICAgID0gIkxjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvZG9tL0ZpbHRlcjsiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFVOSU9OX0lURVJBVE9SX0NMQVNTCi0gICAgICAgID0gImNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5kb20uVW5pb25JdGVyYXRvciI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1RFUF9JVEVSQVRPUl9DTEFTUwotICAgICAgICA9ICJjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuZG9tLlN0ZXBJdGVyYXRvciI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ0FDSEVEX05PREVfTElTVF9JVEVSQVRPUl9DTEFTUwotICAgICAgICA9ICJjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuZG9tLkNhY2hlZE5vZGVMaXN0SXRlcmF0b3IiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIE5USF9JVEVSQVRPUl9DTEFTUwotICAgICAgICA9ICJjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuZG9tLk50aEl0ZXJhdG9yIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBQlNPTFVURV9JVEVSQVRPUgotICAgICAgICA9ICJjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuZG9tLkFic29sdXRlSXRlcmF0b3IiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIERVUF9GSUxURVJFRF9JVEVSQVRPUgotICAgICAgICA9ICJjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuZG9tLkR1cEZpbHRlckl0ZXJhdG9yIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBDVVJSRU5UX05PREVfTElTVF9JVEVSQVRPUgotICAgICAgICA9ICJjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuZG9tLkN1cnJlbnROb2RlTGlzdEl0ZXJhdG9yIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBDVVJSRU5UX05PREVfTElTVF9GSUxURVIKLSAgICAgICAgPSAiY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmRvbS5DdXJyZW50Tm9kZUxpc3RGaWx0ZXIiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIENVUlJFTlRfTk9ERV9MSVNUX0lURVJBVE9SX1NJRwotICAgICAgICA9ICJMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2RvbS9DdXJyZW50Tm9kZUxpc3RJdGVyYXRvcjsiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIENVUlJFTlRfTk9ERV9MSVNUX0ZJTFRFUl9TSUcKLSAgICAgICAgPSAiTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vQ3VycmVudE5vZGVMaXN0RmlsdGVyOyI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRklMVEVSX1NURVBfSVRFUkFUT1IKLSAgICAgICAgPSAiY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmRvbS5GaWx0ZXJlZFN0ZXBJdGVyYXRvciI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRklMVEVSX0lURVJBVE9SCi0gICAgICAgID0gImNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5kb20uRmlsdGVySXRlcmF0b3IiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFNJTkdMRVRPTl9JVEVSQVRPUgotICAgICAgICA9ICJjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuZG9tLlNpbmdsZXRvbkl0ZXJhdG9yIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBNQVRDSElOR19JVEVSQVRPUgotICAgICAgICA9ICJjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuZG9tLk1hdGNoaW5nSXRlcmF0b3IiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIE5PREVfU0lHCi0gICAgICAgID0gIkkiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEdFVF9QQVJFTlQKLSAgICAgICAgPSAiZ2V0UGFyZW50IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBHRVRfUEFSRU5UX1NJRwotICAgICAgICA9ICIoIiArIE5PREVfU0lHICsgIikiICsgTk9ERV9TSUc7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTkVYVF9TSUcKLSAgICAgICAgPSAiKCkiICsgTk9ERV9TSUc7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTkVYVAotICAgICAgICA9ICJuZXh0IjsKLSAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTkVYVElECi0gICAgICAgID0gIm5leHROb2RlSUQiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIE1BS0VfTk9ERQotICAgICAgICA9ICJtYWtlTm9kZSI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTUFLRV9OT0RFX0xJU1QKLSAgICAgICAgPSAibWFrZU5vZGVMaXN0IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBHRVRfVU5QQVJTRURfRU5USVRZX1VSSQotICAgICAgICA9ICJnZXRVbnBhcnNlZEVudGl0eVVSSSI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1RSSU5HX1RPX1JFQUwKLSAgICAgICAgPSAic3RyaW5nVG9SZWFsIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBTVFJJTkdfVE9fUkVBTF9TSUcKLSAgICAgICAgPSAiKCIgKyBTVFJJTkdfU0lHICsgIilEIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBTVFJJTkdfVE9fSU5UCi0gICAgICAgID0gInN0cmluZ1RvSW50IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBTVFJJTkdfVE9fSU5UX1NJRwotICAgICAgICA9ICIoIiArIFNUUklOR19TSUcgKyAiKUkiOwotCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgWFNMVF9QQUNLQUdFCi0gICAgICAgID0gImNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0YyI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ09NUElMRVJfUEFDS0FHRQotICAgICAgICA9IFhTTFRfUEFDS0FHRSArICIuY29tcGlsZXIiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFJVTlRJTUVfUEFDS0FHRQotICAgICAgICA9IFhTTFRfUEFDS0FHRSArICIucnVudGltZSI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgVFJBTlNMRVRfQ0xBU1MKLSAgICAgICAgPSBSVU5USU1FX1BBQ0tBR0UgKyAiLkFic3RyYWN0VHJhbnNsZXQiOwotCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgVFJBTlNMRVRfU0lHCi0gICAgICAgID0gIkxjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0OyI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgVU5JT05fSVRFUkFUT1JfU0lHCi0gICAgICAgID0gIkxjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvZG9tL1VuaW9uSXRlcmF0b3I7IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBUUkFOU0xFVF9PVVRQVVRfU0lHCi0gICAgICAgID0gIkxjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBNQUtFX05PREVfU0lHCi0gICAgICAgID0gIihJKUxvcmcvdzNjL2RvbS9Ob2RlOyI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTUFLRV9OT0RFX1NJRzIKLSAgICAgICAgPSAiKCIgKyBOT0RFX0lURVJBVE9SX1NJRyArICIpTG9yZy93M2MvZG9tL05vZGU7IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBNQUtFX05PREVfTElTVF9TSUcKLSAgICAgICAgPSAiKEkpTG9yZy93M2MvZG9tL05vZGVMaXN0OyI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTUFLRV9OT0RFX0xJU1RfU0lHMgotICAgICAgICA9ICIoIiArIE5PREVfSVRFUkFUT1JfU0lHICsgIilMb3JnL3czYy9kb20vTm9kZUxpc3Q7IjsKLQotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFNUUkVBTV9YTUxfT1VUUFVUCi0gICAgPSAiY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyLlRvWE1MU3RyZWFtIjsKLQotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIE9VVFBVVF9CQVNFCi0gICAgPSAiY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyLlNlcmlhbGl6ZXJCYXNlIjsKLQotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIExPQURfRE9DVU1FTlRfQ0xBU1MKLSAgICAgICAgPSAiY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmRvbS5Mb2FkRG9jdW1lbnQiOwotCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgS0VZX0lOREVYX0NMQVNTCi0gICAgICAgID0gImNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vS2V5SW5kZXgiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEtFWV9JTkRFWF9TSUcKLSAgICAgICAgPSAiTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vS2V5SW5kZXg7IjsKLQotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEtFWV9JTkRFWF9JVEVSQVRPUl9TSUcKLSAgICAgICAgPSAiTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vS2V5SW5kZXgkS2V5SW5kZXhJdGVyYXRvcjsiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIERPTV9JTlRGCi0gICAgICAgID0gImNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5ET00iOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIERPTV9JTVBMCi0gICAgICAgID0gImNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5kb20uU0FYSW1wbCI7Ci0gICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFNBWF9JTVBMCi0gICAgICAgID0gImNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5kb20uU0FYSW1wbCI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1RSSU5HX0NMQVNTCi0gICAgICAgID0gImphdmEubGFuZy5TdHJpbmciOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIE9CSkVDVF9DTEFTUwotICAgICAgICA9ICJqYXZhLmxhbmcuT2JqZWN0IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBCT09MRUFOX0NMQVNTCi0gICAgICAgID0gImphdmEubGFuZy5Cb29sZWFuIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBTVFJJTkdfQlVGRkVSX0NMQVNTCi0gICAgICAgID0gImphdmEubGFuZy5TdHJpbmdCdWZmZXIiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFNUUklOR19XUklURVIKLSAgICAgICAgPSAiamF2YS5pby5TdHJpbmdXcml0ZXIiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdSSVRFUl9TSUcKLSAgICAgICAgPSAiTGphdmEvaW8vV3JpdGVyOyI7Ci0KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBUUkFOU0xFVF9PVVRQVVRfQkFTRQotICAgICAgICA9ICJjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuVHJhbnNsZXRPdXRwdXRCYXNlIjsKLSAgICAvLyBvdXRwdXQgaW50ZXJmYWNlCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgVFJBTlNMRVRfT1VUUFVUX0lOVEVSRkFDRQotICAgICAgICA9ICJjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXIuU2VyaWFsaXphdGlvbkhhbmRsZXIiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEJBU0lTX0xJQlJBUllfQ0xBU1MKLSAgICAgICAgPSAiY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnJ1bnRpbWUuQmFzaXNMaWJyYXJ5IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRSSUJVVEVfTElTVF9JTVBMX0NMQVNTCi0gICAgICAgID0gImNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5ydW50aW1lLkF0dHJpYnV0ZUxpc3RJbXBsIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBET1VCTEVfQ0xBU1MKLSAgICAgICAgPSAiamF2YS5sYW5nLkRvdWJsZSI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSU5URUdFUl9DTEFTUwotICAgICAgICA9ICJqYXZhLmxhbmcuSW50ZWdlciI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgUlVOVElNRV9OT0RFX0NMQVNTCi0gICAgICAgID0gImNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5ydW50aW1lLk5vZGUiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIE1BVEhfQ0xBU1MKLSAgICAgICAgPSAiamF2YS5sYW5nLk1hdGgiOwotCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQk9PTEVBTl9WQUxVRQotICAgICAgICA9ICJib29sZWFuVmFsdWUiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEJPT0xFQU5fVkFMVUVfU0lHCi0gICAgICAgID0gIigpWiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSU5UX1ZBTFVFCi0gICAgICAgID0gImludFZhbHVlIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBJTlRfVkFMVUVfU0lHCi0gICAgICAgID0gIigpSSI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRE9VQkxFX1ZBTFVFCi0gICAgICAgID0gImRvdWJsZVZhbHVlIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBET1VCTEVfVkFMVUVfU0lHCi0gICAgICAgID0gIigpRCI7Ci0KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBET01fUE5BTUUKLSAgPSAiZG9tIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBOT0RFX1BOQU1FCi0gICAgICAgID0gIm5vZGUiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFRSQU5TTEVUX09VVFBVVF9QTkFNRQotICAgICAgICA9ICJoYW5kbGVyIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBJVEVSQVRPUl9QTkFNRQotICAgICAgICA9ICJpdGVyYXRvciI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRE9DVU1FTlRfUE5BTUUKLSAgICAgICAgPSAiZG9jdW1lbnQiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFRSQU5TTEVUX1BOQU1FCi0gICAgICAgID0gInRyYW5zbGV0IjsKLQotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIElOVk9LRV9NRVRIT0QKLSAgICAgICAgPSAiaW52b2tlTWV0aG9kIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBHRVRfTk9ERV9OQU1FCi0gICAgICAgID0gImdldE5vZGVOYW1lWCI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ0hBUkFDVEVSU1cKLSAgICAgICAgPSAiY2hhcmFjdGVycyI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgR0VUX0NISUxEUkVOCi0gICAgICAgID0gImdldENoaWxkcmVuIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBHRVRfVFlQRURfQ0hJTERSRU4KLSAgICAgICAgPSAiZ2V0VHlwZWRDaGlsZHJlbiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ0hBUkFDVEVSUwotICAgICAgICA9ICJjaGFyYWN0ZXJzIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBUFBMWV9URU1QTEFURVMKLSAgICAgICAgPSAiYXBwbHlUZW1wbGF0ZXMiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEdFVF9OT0RFX1RZUEUKLSAgICAgICAgPSAiZ2V0Tm9kZVR5cGUiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEdFVF9OT0RFX1ZBTFVFCi0gICAgICAgID0gImdldFN0cmluZ1ZhbHVlWCI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgR0VUX0VMRU1FTlRfVkFMVUUKLSAgICAgICAgPSAiZ2V0RWxlbWVudFZhbHVlIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBHRVRfQVRUUklCVVRFX1ZBTFVFCi0gICAgICAgID0gImdldEF0dHJpYnV0ZVZhbHVlIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBIQVNfQVRUUklCVVRFCi0gICAgICAgID0gImhhc0F0dHJpYnV0ZSI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQUREX0lURVJBVE9SCi0gICAgICAgID0gImFkZEl0ZXJhdG9yIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBTRVRfU1RBUlRfTk9ERQotICAgICAgICA9ICJzZXRTdGFydE5vZGUiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFJFU0VUCi0gICAgICAgID0gInJlc2V0IjsKLQotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEFUVFJfU0VUX1NJRwotICAgICAgICA9ICIoIiArIERPTV9JTlRGX1NJRyAgKyBOT0RFX0lURVJBVE9SX1NJRyArIFRSQU5TTEVUX09VVFBVVF9TSUcgKyAiSSlWIjsKLQotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEdFVF9OT0RFX05BTUVfU0lHCi0gICAgICAgID0gIigiICsgTk9ERV9TSUcgKyAiKSIgKyBTVFJJTkdfU0lHOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIENIQVJBQ1RFUlNXX1NJRwotICAgICAgICA9ICIoIiAgKyBTVFJJTkdfU0lHICsgVFJBTlNMRVRfT1VUUFVUX1NJRyArICIpViI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ0hBUkFDVEVSU19TSUcKLSAgICAgICAgPSAiKCIgKyBOT0RFX1NJRyArIFRSQU5TTEVUX09VVFBVVF9TSUcgKyAiKVYiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEdFVF9DSElMRFJFTl9TSUcKLSAgICAgICAgPSAiKCIgKyBOT0RFX1NJRyArIikiICsgTk9ERV9JVEVSQVRPUl9TSUc7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgR0VUX1RZUEVEX0NISUxEUkVOX1NJRwotICAgICAgICA9ICIoSSkiICsgTk9ERV9JVEVSQVRPUl9TSUc7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgR0VUX05PREVfVFlQRV9TSUcKLSAgICAgICAgPSAiKClTIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBHRVRfTk9ERV9WQUxVRV9TSUcKLSAgICAgICAgPSAiKEkpIiArIFNUUklOR19TSUc7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgR0VUX0VMRU1FTlRfVkFMVUVfU0lHCi0gICAgICAgID0gIihJKSIgKyBTVFJJTkdfU0lHOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEdFVF9BVFRSSUJVVEVfVkFMVUVfU0lHCi0gICAgICAgID0gIihJSSkiICsgU1RSSU5HX1NJRzsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBIQVNfQVRUUklCVVRFX1NJRwotICAgICAgICA9ICIoSUkpWiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgR0VUX0lURVJBVE9SX1NJRwotICAgICAgICA9ICIoKSIgKyBOT0RFX0lURVJBVE9SX1NJRzsKLQotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIE5BTUVTX0lOREVYCi0gICAgICAgID0gIm5hbWVzQXJyYXkiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIE5BTUVTX0lOREVYX1NJRwotICAgICAgICA9ICJbIiArIFNUUklOR19TSUc7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgVVJJU19JTkRFWAotICAgICAgID0gInVyaXNBcnJheSI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgVVJJU19JTkRFWF9TSUcKLSAgICAgICA9ICJbIiArIFNUUklOR19TSUc7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgVFlQRVNfSU5ERVgKLSAgICAgICA9ICJ0eXBlc0FycmF5IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBUWVBFU19JTkRFWF9TSUcKLSAgICAgICA9ICJbSSI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTkFNRVNQQUNFX0lOREVYCi0gICAgICAgID0gIm5hbWVzcGFjZUFycmF5IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBOQU1FU1BBQ0VfSU5ERVhfU0lHCi0gICAgICAgID0gIlsiICsgU1RSSU5HX1NJRzsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBIQVNJRENBTExfSU5ERVgKLSAgICAgICAgPSAiX2hhc0lkQ2FsbCI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSEFTSURDQUxMX0lOREVYX1NJRwotICAgICAgICA9ICJaIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBUUkFOU0xFVF9WRVJTSU9OX0lOREVYCi0gICAgICAgID0gInRyYW5zbGV0VmVyc2lvbiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgVFJBTlNMRVRfVkVSU0lPTl9JTkRFWF9TSUcKLSAgICAgICAgPSAiSSI7Ci0KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBET01fRklFTEQKLSAgICAgICAgPSAiX2RvbSI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1RBVElDX05BTUVTX0FSUkFZX0ZJRUxECi0gICAgICAgID0gIl9zTmFtZXNBcnJheSI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1RBVElDX1VSSVNfQVJSQVlfRklFTEQKLSAgICAgICAgPSAiX3NVcmlzQXJyYXkiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFNUQVRJQ19UWVBFU19BUlJBWV9GSUVMRAotICAgICAgICA9ICJfc1R5cGVzQXJyYXkiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFNUQVRJQ19OQU1FU1BBQ0VfQVJSQVlfRklFTEQKLSAgICAgICAgPSAiX3NOYW1lc3BhY2VBcnJheSI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1RBVElDX0NIQVJfREFUQV9GSUVMRAotICAgICAgICA9ICJfc2NoYXJEYXRhIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBTVEFUSUNfQ0hBUl9EQVRBX0ZJRUxEX1NJRwotICAgICAgICA9ICJbQyI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRk9STUFUX1NZTUJPTFNfRklFTEQKLSAgICAgICAgPSAiZm9ybWF0X3N5bWJvbHMiOwotCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSVRFUkFUT1JfRklFTERfU0lHCi0gICAgICAgID0gTk9ERV9JVEVSQVRPUl9TSUc7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTk9ERV9GSUVMRAotICAgICAgICA9ICJub2RlIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBOT0RFX0ZJRUxEX1NJRwotICAgICAgICA9ICJJIjsKLQotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVNUFRZQVRUUl9GSUVMRAotICAgICAgICA9ICJFbXB0eUF0dHJpYnV0ZXMiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEFUVFJJQlVURV9MSVNUX0ZJRUxECi0gICAgICAgID0gImF0dHJpYnV0ZUxpc3QiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIENMRUFSX0FUVFJJQlVURVMKLSAgICAgICAgPSAiY2xlYXIiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEFERF9BVFRSSUJVVEUKLSAgICAgICAgPSAiYWRkQXR0cmlidXRlIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRSSUJVVEVfTElTVF9JTVBMX1NJRwotICAgICAgICA9ICJMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvQXR0cmlidXRlTGlzdEltcGw7IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBDTEVBUl9BVFRSSUJVVEVTX1NJRwotICAgICAgICA9ICIoKSIgKyBBVFRSSUJVVEVfTElTVF9JTVBMX1NJRzsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBRERfQVRUUklCVVRFX1NJRwotICAgICAgICA9ICIoIiArIFNUUklOR19TSUcgKyBTVFJJTkdfU0lHICsgIikiICsgQVRUUklCVVRFX0xJU1RfSU1QTF9TSUc7Ci0KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBRERfSVRFUkFUT1JfU0lHCi0gICAgICAgID0gIigiICsgTk9ERV9JVEVSQVRPUl9TSUcgKyIpIiArIFVOSU9OX0lURVJBVE9SX1NJRzsKLQotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIE9SREVSX0lURVJBVE9SCi0gICAgICAgID0gIm9yZGVyTm9kZXMiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIE9SREVSX0lURVJBVE9SX1NJRwotICAgICAgICA9ICIoIitOT0RFX0lURVJBVE9SX1NJRysiSSkiK05PREVfSVRFUkFUT1JfU0lHOwotCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU0VUX1NUQVJUX05PREVfU0lHCi0gICAgICAgID0gIigiICsgTk9ERV9TSUcgKyAiKSIgKyBOT0RFX0lURVJBVE9SX1NJRzsKLQotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIE5PREVfQ09VTlRFUgotICAgICAgICA9ICJjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuZG9tLk5vZGVDb3VudGVyIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBOT0RFX0NPVU5URVJfU0lHCi0gICAgICAgID0gIkxjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvZG9tL05vZGVDb3VudGVyOyI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgREVGQVVMVF9OT0RFX0NPVU5URVIKLSAgICAgICAgPSAiY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmRvbS5EZWZhdWx0Tm9kZUNvdW50ZXIiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIERFRkFVTFRfTk9ERV9DT1VOVEVSX1NJRwotICAgICAgICA9ICJMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2RvbS9EZWZhdWx0Tm9kZUNvdW50ZXI7IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBUUkFOU0xFVF9GSUVMRAotICAgICAgICA9ICJ0cmFuc2xldCI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgVFJBTlNMRVRfRklFTERfU0lHCi0gICAgICAgID0gVFJBTlNMRVRfU0lHOwotCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgUkVTRVRfU0lHCi0gICAgICAgID0gIigpIiArIE5PREVfSVRFUkFUT1JfU0lHOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEdFVF9QQVJBTUVURVIKLSAgICAgICAgPSAiZ2V0UGFyYW1ldGVyIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBRERfUEFSQU1FVEVSCi0gICAgICAgID0gImFkZFBhcmFtZXRlciI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgUFVTSF9QQVJBTV9GUkFNRQotICAgICAgICA9ICJwdXNoUGFyYW1GcmFtZSI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgUFVTSF9QQVJBTV9GUkFNRV9TSUcKLSAgICAgICAgPSAiKClWIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBQT1BfUEFSQU1fRlJBTUUKLSAgICAgICAgPSAicG9wUGFyYW1GcmFtZSI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgUE9QX1BBUkFNX0ZSQU1FX1NJRwotICAgICAgICA9ICIoKVYiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEdFVF9QQVJBTUVURVJfU0lHCi0gICAgICAgID0gIigiICsgU1RSSU5HX1NJRyArICIpIiArIE9CSkVDVF9TSUc7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQUREX1BBUkFNRVRFUl9TSUcKLSAgICAgICAgPSAiKCIgKyBTVFJJTkdfU0lHICsgT0JKRUNUX1NJRyArICJaKSIgKyBPQkpFQ1RfU0lHOwotCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1RSSVBfU1BBQ0UKLSAgICAgICAgPSAic3RyaXBTcGFjZSI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1RSSVBfU1BBQ0VfSU5URgotICAgICAgICA9ICJjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvU3RyaXBGaWx0ZXIiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFNUUklQX1NQQUNFX1NJRwotICAgICAgICA9ICJMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1N0cmlwRmlsdGVyOyI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1RSSVBfU1BBQ0VfUEFSQU1TCi0gICAgICAgID0gIihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtJSSlaIjsKLQotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEdFVF9OT0RFX1ZBTFVFX0lURVJBVE9SCi0gICAgICAgID0gImdldE5vZGVWYWx1ZUl0ZXJhdG9yIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBHRVRfTk9ERV9WQUxVRV9JVEVSQVRPUl9TSUcKLSAgICAgICAgPSAiKCIrTk9ERV9JVEVSQVRPUl9TSUcrIkkiK1NUUklOR19TSUcrIlopIitOT0RFX0lURVJBVE9SX1NJRzsKLQotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEdFVF9VTlBBUlNFRF9FTlRJVFlfVVJJX1NJRwotICAgICAgICA9ICIoIitTVFJJTkdfU0lHKyIpIitTVFJJTkdfU0lHOwotCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUE9TSVRJT05fSU5ERVggPSAyOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExBU1RfSU5ERVggICAgID0gMzsKLQotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFhNTE5TX1BSRUZJWCA9ICJ4bWxucyI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MTlNfU1RSSU5HID0gInhtbG5zOiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MTlNfVVJJCi0gICAgICAgID0gImh0dHA6Ly93d3cudzMub3JnLzIwMDAveG1sbnMvIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBYU0xUX1VSSQotICAgICAgICA9ICJodHRwOi8vd3d3LnczLm9yZy8xOTk5L1hTTC9UcmFuc2Zvcm0iOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFhIVE1MX1VSSQotICAgICAgICA9ICJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBUUkFOU0xFVF9VUkkKLSAgICAgICAgPSAiaHR0cDovL3htbC5hcGFjaGUub3JnL3hhbGFuL3hzbHRjIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBSRURJUkVDVF9VUkkKLSAgICAgICAgPSAiaHR0cDovL3htbC5hcGFjaGUub3JnL3hhbGFuL3JlZGlyZWN0IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBGQUxMQkFDS19DTEFTUwotICAgICAgICA9ICJjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIuRmFsbGJhY2siOwotCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUlRGX0lOSVRJQUxfU0laRSA9IDMyOwotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9Db250YWluc0NhbGwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvQ29udGFpbnNDYWxsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGUwY2Q1NmMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9Db250YWluc0NhbGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEwOSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBDb250YWluc0NhbGwuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8wMSAxMjoxMjowNiBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5Db25zdGFudFBvb2xHZW47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JRkxUOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFVklSVFVBTDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uTGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5DbGFzc0dlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5FcnJvck1zZzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5NZXRob2RHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlQ2hlY2tFcnJvcjsKLQotLyoqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqLwotZmluYWwgY2xhc3MgQ29udGFpbnNDYWxsIGV4dGVuZHMgRnVuY3Rpb25DYWxsIHsKLQotICAgIHByaXZhdGUgRXhwcmVzc2lvbiBfYmFzZSA9IG51bGw7Ci0gICAgcHJpdmF0ZSBFeHByZXNzaW9uIF90b2tlbiA9IG51bGw7Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGUgYSBjb250YWlucygpIGNhbGwgLSB0d28gYXJndW1lbnRzLCBib3RoIHN0cmluZ3MKLSAgICAgKi8KLSAgICBwdWJsaWMgQ29udGFpbnNDYWxsKFFOYW1lIGZuYW1lLCBWZWN0b3IgYXJndW1lbnRzKSB7Ci0gICAgICAgIHN1cGVyKGZuYW1lLCBhcmd1bWVudHMpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgWFBhdGggZnVuY3Rpb24gcmV0dXJucyB0cnVlL2ZhbHNlIHZhbHVlcwotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzQm9vbGVhbigpIHsKLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHlwZSBjaGVjayB0aGUgdHdvIHBhcmFtZXRlcnMgZm9yIHRoaXMgZnVuY3Rpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgVHlwZSB0eXBlQ2hlY2soU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgewotCi0gICAgICAgIC8vIENoZWNrIHRoYXQgdGhlIGZ1bmN0aW9uIHdhcyBwYXNzZWQgZXhhY3RseSB0d28gYXJndW1lbnRzCi0gICAgICAgIGlmIChhcmd1bWVudENvdW50KCkgIT0gMikgewotICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVDaGVja0Vycm9yKEVycm9yTXNnLklMTEVHQUxfQVJHX0VSUiwgZ2V0TmFtZSgpLCB0aGlzKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIFRoZSBmaXJzdCBhcmd1bWVudCBtdXN0IGJlIGEgU3RyaW5nLCBvciBjYXN0IHRvIGEgU3RyaW5nCi0gICAgICAgIF9iYXNlID0gYXJndW1lbnQoMCk7Ci0gICAgICAgIFR5cGUgYmFzZVR5cGUgPSBfYmFzZS50eXBlQ2hlY2soc3RhYmxlKTsKLSAgICAgICAgaWYgKGJhc2VUeXBlICE9IFR5cGUuU3RyaW5nKQotICAgICAgICAgICAgX2Jhc2UgPSBuZXcgQ2FzdEV4cHIoX2Jhc2UsIFR5cGUuU3RyaW5nKTsKLQotICAgICAgICAvLyBUaGUgc2Vjb25kIGFyZ3VtZW50IG11c3QgYWxzbyBiZSBhIFN0cmluZywgb3IgY2FzdCB0byBhIFN0cmluZwotICAgICAgICBfdG9rZW4gPSBhcmd1bWVudCgxKTsKLSAgICAgICAgVHlwZSB0b2tlblR5cGUgPSBfdG9rZW4udHlwZUNoZWNrKHN0YWJsZSk7Ci0gICAgICAgIGlmICh0b2tlblR5cGUgIT0gVHlwZS5TdHJpbmcpCi0gICAgICAgICAgICBfdG9rZW4gPSBuZXcgQ2FzdEV4cHIoX3Rva2VuLCBUeXBlLlN0cmluZyk7Ci0KLSAgICAgICAgcmV0dXJuIF90eXBlID0gVHlwZS5Cb29sZWFuOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbXBpbGUgdGhlIGV4cHJlc3Npb24gLSBsZWF2ZSBib29sZWFuIGV4cHJlc3Npb24gb24gc3RhY2sKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLSAgICAgICAgdHJhbnNsYXRlRGVzeW50aGVzaXplZChjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgc3ludGhlc2l6ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb21waWxlIGV4cHJlc3Npb24gYW5kIHVwZGF0ZSB0cnVlL2ZhbHNlLWxpc3RzCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlRGVzeW50aGVzaXplZChDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLSAgICAgICAgZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0gICAgICAgIF9iYXNlLnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgX3Rva2VuLnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VWSVJUVUFMKGNwZy5hZGRNZXRob2RyZWYoU1RSSU5HX0NMQVNTLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiaW5kZXhPZiIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoIitTVFJJTkdfU0lHKyIpSSIpKSk7Ci0gICAgICAgIF9mYWxzZUxpc3QuYWRkKGlsLmFwcGVuZChuZXcgSUZMVChudWxsKSkpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvQ29weS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9Db3B5LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDZjOTIxYmIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9Db3B5LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNTkgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogQ29weS5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzAxIDEyOjE0OjMyIHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQUxPQUQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5BU1RPUkU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5CcmFuY2hIYW5kbGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5Db25zdGFudFBvb2xHZW47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JRkVROwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSUZOVUxMOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSUxPQUQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JTlZPS0VJTlRFUkZBQ0U7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JTlZPS0VWSVJUVUFMOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSVNUT1JFOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW5zdHJ1Y3Rpb25IYW5kbGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JbnN0cnVjdGlvbkxpc3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5Mb2NhbFZhcmlhYmxlR2VuOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkNsYXNzR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkVycm9yTXNnOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLk1ldGhvZEdlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGVDaGVja0Vycm9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlV0aWw7Ci0KLS8qKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICovCi1maW5hbCBjbGFzcyBDb3B5IGV4dGVuZHMgSW5zdHJ1Y3Rpb24gewotICAgIHByaXZhdGUgVXNlQXR0cmlidXRlU2V0cyBfdXNlU2V0czsKLQotICAgIHB1YmxpYyB2b2lkIHBhcnNlQ29udGVudHMoUGFyc2VyIHBhcnNlcikgewotICAgICAgICBmaW5hbCBTdHJpbmcgdXNlU2V0cyA9IGdldEF0dHJpYnV0ZSgidXNlLWF0dHJpYnV0ZS1zZXRzIik7Ci0gICAgICAgIGlmICh1c2VTZXRzLmxlbmd0aCgpID4gMCkgewotICAgICAgICAgICAgaWYgKCFVdGlsLmlzVmFsaWRRTmFtZXModXNlU2V0cykpIHsKLSAgICAgICAgICAgICAgICBFcnJvck1zZyBlcnIgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuSU5WQUxJRF9RTkFNRV9FUlIsIHVzZVNldHMsIHRoaXMpOwotICAgICAgICAgICAgICAgIHBhcnNlci5yZXBvcnRFcnJvcihDb25zdGFudHMuRVJST1IsIGVycik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBfdXNlU2V0cyA9IG5ldyBVc2VBdHRyaWJ1dGVTZXRzKHVzZVNldHMsIHBhcnNlcik7Ci0gICAgICAgIH0KLSAgICAgICAgcGFyc2VDaGlsZHJlbihwYXJzZXIpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGRpc3BsYXkoaW50IGluZGVudCkgewotICAgICAgICBpbmRlbnQoaW5kZW50KTsKLSAgICAgICAgVXRpbC5wcmludGxuKCJDb3B5Iik7Ci0gICAgICAgIGluZGVudChpbmRlbnQgKyBJbmRlbnRJbmNyZW1lbnQpOwotICAgICAgICBkaXNwbGF5Q29udGVudHMoaW5kZW50ICsgSW5kZW50SW5jcmVtZW50KTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgVHlwZSB0eXBlQ2hlY2soU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgewotICAgICAgICBpZiAoX3VzZVNldHMgIT0gbnVsbCkgewotICAgICAgICAgICAgX3VzZVNldHMudHlwZUNoZWNrKHN0YWJsZSk7Ci0gICAgICAgIH0KLSAgICAgICAgdHlwZUNoZWNrQ29udGVudHMoc3RhYmxlKTsKLSAgICAgICAgcmV0dXJuIFR5cGUuVm9pZDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLSAgICAgICAgZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0KLSAgICAgICAgZmluYWwgTG9jYWxWYXJpYWJsZUdlbiBuYW1lID0KLSAgICAgICAgICAgIG1ldGhvZEdlbi5hZGRMb2NhbFZhcmlhYmxlMigibmFtZSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVXRpbC5nZXRKQ1JlZlR5cGUoU1RSSU5HX1NJRyksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCk7Ci0gICAgICAgIGZpbmFsIExvY2FsVmFyaWFibGVHZW4gbGVuZ3RoID0KLSAgICAgICAgICAgIG1ldGhvZEdlbi5hZGRMb2NhbFZhcmlhYmxlMigibGVuZ3RoIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVdGlsLmdldEpDUmVmVHlwZSgiSSIpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwpOwotCi0gICAgICAgIC8vIEdldCB0aGUgbmFtZSBvZiB0aGUgbm9kZSB0byBjb3B5IGFuZCBzYXZlIGZvciBsYXRlcgotICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0gICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZEN1cnJlbnROb2RlKCkpOwotICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRIYW5kbGVyKCkpOwotICAgICAgICBmaW5hbCBpbnQgY3B5ID0gY3BnLmFkZEludGVyZmFjZU1ldGhvZHJlZihET01fSU5URiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInNoYWxsb3dDb3B5IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIigiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgTk9ERV9TSUcKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBUUkFOU0xFVF9PVVRQVVRfU0lHCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIikiICsgU1RSSU5HX1NJRyk7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFSU5URVJGQUNFKGNweSwgMykpOwotICAgICAgICBpbC5hcHBlbmQoRFVQKTsKLSAgICAgICAgbmFtZS5zZXRTdGFydChpbC5hcHBlbmQobmV3IEFTVE9SRShuYW1lLmdldEluZGV4KCkpKSk7Ci0gICAgICAgIGZpbmFsIEJyYW5jaEhhbmRsZSBpZkJsb2NrMSA9IGlsLmFwcGVuZChuZXcgSUZOVUxMKG51bGwpKTsKLQotICAgICAgICAvLyBHZXQgdGhlIGxlbmd0aCBvZiB0aGUgbm9kZSBuYW1lIGFuZCBzYXZlIGZvciBsYXRlcgotICAgICAgICBpbC5hcHBlbmQobmV3IEFMT0FEKG5hbWUuZ2V0SW5kZXgoKSkpOwotICAgICAgICBmaW5hbCBpbnQgbGVuZ3RoTWV0aG9kID0gY3BnLmFkZE1ldGhvZHJlZihTVFJJTkdfQ0xBU1MsImxlbmd0aCIsIigpSSIpOwotICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRVZJUlRVQUwobGVuZ3RoTWV0aG9kKSk7Ci0gICAgICAgIGlsLmFwcGVuZChEVVApOwotICAgICAgICBsZW5ndGguc2V0U3RhcnQoaWwuYXBwZW5kKG5ldyBJU1RPUkUobGVuZ3RoLmdldEluZGV4KCkpKSk7Ci0KLSAgICAgICAgLy8gSWdub3JlIGF0dHJpYnV0ZSBzZXRzIGlmIGN1cnJlbnQgbm9kZSBpcyBST09ULiBET00uc2hhbGxvd0NvcHkoKQotICAgICAgICAvLyByZXR1cm5zICIiIGZvciBST09ULCBzbyBza2lwIGF0dHJpYnV0ZSBzZXRzIGlmIGxlbmd0aCA9PSAwCi0gICAgICAgIGZpbmFsIEJyYW5jaEhhbmRsZSBpZkJsb2NrNCA9IGlsLmFwcGVuZChuZXcgSUZFUShudWxsKSk7Ci0KLSAgICAgICAgLy8gQ29weSBpbiBhdHRyaWJ1dGUgc2V0cyBpZiBzcGVjaWZpZWQKLSAgICAgICAgaWYgKF91c2VTZXRzICE9IG51bGwpIHsKLSAgICAgICAgICAgIC8vIElmIHRoZSBwYXJlbnQgb2YgdGhpcyBlbGVtZW50IHdpbGwgcmVzdWx0IGluIGFuIGVsZW1lbnQgYmVpbmcKLSAgICAgICAgICAgIC8vIG91dHB1dCB0aGVuIHdlIGtub3cgdGhhdCBpdCBpcyBzYWZlIHRvIGNvcHkgb3V0IHRoZSBhdHRyaWJ1dGVzCi0gICAgICAgICAgICBmaW5hbCBTeW50YXhUcmVlTm9kZSBwYXJlbnQgPSBnZXRQYXJlbnQoKTsKLSAgICAgICAgICAgIGlmICgocGFyZW50IGluc3RhbmNlb2YgTGl0ZXJhbEVsZW1lbnQpIHx8Ci0gICAgICAgICAgICAgICAgKHBhcmVudCBpbnN0YW5jZW9mIExpdGVyYWxFbGVtZW50KSkgewotICAgICAgICAgICAgICAgIF91c2VTZXRzLnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIElmIG5vdCB3ZSBoYXZlIHRvIGNoZWNrIHRvIHNlZSBpZiB0aGUgY29weSB3aWxsIHJlc3VsdCBpbiBhbgotICAgICAgICAgICAgLy8gZWxlbWVudCBiZWluZyBvdXRwdXQuCi0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAvLyBjaGVjayBpZiBlbGVtZW50OyBpZiBub3Qgc2tpcCB0byB0cmFuc2xhdGUgYm9keQotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSUxPQUQobGVuZ3RoLmdldEluZGV4KCkpKTsKLSAgICAgICAgICAgICAgICBmaW5hbCBCcmFuY2hIYW5kbGUgaWZCbG9jazIgPSBpbC5hcHBlbmQobmV3IElGRVEobnVsbCkpOwotICAgICAgICAgICAgICAgIC8vIGxlbmd0aCAhPSAwIC0+IGVsZW1lbnQgLT4gZG8gYXR0cmlidXRlIHNldHMKLSAgICAgICAgICAgICAgICBfdXNlU2V0cy50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgICAgICAgICAgLy8gbm90IGFuIGVsZW1lbnQ7IHJvb3QKLSAgICAgICAgICAgICAgICBpZkJsb2NrMi5zZXRUYXJnZXQoaWwuYXBwZW5kKE5PUCkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gSW5zdGFudGlhdGUgYm9keSBvZiB4c2w6Y29weQotICAgICAgICBpZkJsb2NrNC5zZXRUYXJnZXQoaWwuYXBwZW5kKE5PUCkpOwotICAgICAgICB0cmFuc2xhdGVDb250ZW50cyhjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQotICAgICAgICAvLyBDYWxsIHRoZSBvdXRwdXQgaGFuZGxlcidzIGVuZEVsZW1lbnQoKSBpZiB3ZSBjb3BpZWQgYW4gZWxlbWVudAotICAgICAgICAvLyAoVGhlIERPTS5zaGFsbG93Q29weSgpIG1ldGhvZCBjYWxscyBzdGFydEVsZW1lbnQoKS4pCi0gICAgICAgIGxlbmd0aC5zZXRFbmQoaWwuYXBwZW5kKG5ldyBJTE9BRChsZW5ndGguZ2V0SW5kZXgoKSkpKTsKLSAgICAgICAgZmluYWwgQnJhbmNoSGFuZGxlIGlmQmxvY2szID0gaWwuYXBwZW5kKG5ldyBJRkVRKG51bGwpKTsKLSAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkSGFuZGxlcigpKTsKLSAgICAgICAgbmFtZS5zZXRFbmQoaWwuYXBwZW5kKG5ldyBBTE9BRChuYW1lLmdldEluZGV4KCkpKSk7Ci0gICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4uZW5kRWxlbWVudCgpKTsKLQotICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkhhbmRsZSBlbmQgPSBpbC5hcHBlbmQoTk9QKTsKLSAgICAgICAgaWZCbG9jazEuc2V0VGFyZ2V0KGVuZCk7Ci0gICAgICAgIGlmQmxvY2szLnNldFRhcmdldChlbmQpOwotICAgICAgICBtZXRob2RHZW4ucmVtb3ZlTG9jYWxWYXJpYWJsZShuYW1lKTsKLSAgICAgICAgbWV0aG9kR2VuLnJlbW92ZUxvY2FsVmFyaWFibGUobGVuZ3RoKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0NvcHlPZi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9Db3B5T2YuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZWQ2MGY0Zi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0NvcHlPZi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTQzICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IENvcHlPZi5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzAxIDEyOjE2OjIyIHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQ29uc3RhbnRQb29sR2VuOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFSU5URVJGQUNFOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFU1RBVElDOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFVklSVFVBTDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uTGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5DbGFzc0dlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5FcnJvck1zZzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5NZXRob2RHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuTm9kZVNldFR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuTm9kZVR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuUmVmZXJlbmNlVHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5SZXN1bHRUcmVlVHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGVDaGVja0Vycm9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlV0aWw7Ci0KLS8qKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICovCi1maW5hbCBjbGFzcyBDb3B5T2YgZXh0ZW5kcyBJbnN0cnVjdGlvbiB7Ci0gICAgcHJpdmF0ZSBFeHByZXNzaW9uIF9zZWxlY3Q7Ci0KLSAgICBwdWJsaWMgdm9pZCBkaXNwbGF5KGludCBpbmRlbnQpIHsKLSAgICAgICAgaW5kZW50KGluZGVudCk7Ci0gICAgICAgIFV0aWwucHJpbnRsbigiQ29weU9mIik7Ci0gICAgICAgIGluZGVudChpbmRlbnQgKyBJbmRlbnRJbmNyZW1lbnQpOwotICAgICAgICBVdGlsLnByaW50bG4oInNlbGVjdCAiICsgX3NlbGVjdC50b1N0cmluZygpKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBwYXJzZUNvbnRlbnRzKFBhcnNlciBwYXJzZXIpIHsKLSAgICAgICAgX3NlbGVjdCA9IHBhcnNlci5wYXJzZUV4cHJlc3Npb24odGhpcywgInNlbGVjdCIsIG51bGwpOwotICAgICAgICAvLyBtYWtlIHN1cmUgcmVxdWlyZWQgYXR0cmlidXRlKHMpIGhhdmUgYmVlbiBzZXQKLSAgICAgICAgaWYgKF9zZWxlY3QuaXNEdW1teSgpKSB7Ci0gICAgICAgICAgICByZXBvcnRFcnJvcih0aGlzLCBwYXJzZXIsIEVycm9yTXNnLlJFUVVJUkVEX0FUVFJfRVJSLCAic2VsZWN0Iik7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgVHlwZSB0eXBlQ2hlY2soU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgewotICAgICAgICBmaW5hbCBUeXBlIHRzZWxlY3QgPSBfc2VsZWN0LnR5cGVDaGVjayhzdGFibGUpOwotICAgICAgICBpZiAodHNlbGVjdCBpbnN0YW5jZW9mIE5vZGVUeXBlIHx8Ci0gICAgICAgICAgICB0c2VsZWN0IGluc3RhbmNlb2YgTm9kZVNldFR5cGUgfHwKLSAgICAgICAgICAgIHRzZWxlY3QgaW5zdGFuY2VvZiBSZWZlcmVuY2VUeXBlIHx8Ci0gICAgICAgICAgICB0c2VsZWN0IGluc3RhbmNlb2YgUmVzdWx0VHJlZVR5cGUpIHsKLSAgICAgICAgICAgIC8vIGZhbGxzIHRocm91Z2gKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIF9zZWxlY3QgPSBuZXcgQ2FzdEV4cHIoX3NlbGVjdCwgVHlwZS5TdHJpbmcpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBUeXBlLlZvaWQ7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0gICAgICAgIGZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotICAgICAgICBmaW5hbCBUeXBlIHRzZWxlY3QgPSBfc2VsZWN0LmdldFR5cGUoKTsKLQotICAgICAgICBmaW5hbCBTdHJpbmcgQ1BZMV9TSUcgPSAiKCIrTk9ERV9JVEVSQVRPUl9TSUcrVFJBTlNMRVRfT1VUUFVUX1NJRysiKVYiOwotICAgICAgICBmaW5hbCBpbnQgY3B5MSA9IGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoRE9NX0lOVEYsICJjb3B5IiwgQ1BZMV9TSUcpOwotCi0gICAgICAgIGZpbmFsIFN0cmluZyBDUFkyX1NJRyA9ICIoIitOT0RFX1NJRytUUkFOU0xFVF9PVVRQVVRfU0lHKyIpViI7Ci0gICAgICAgIGZpbmFsIGludCBjcHkyID0gY3BnLmFkZEludGVyZmFjZU1ldGhvZHJlZihET01fSU5URiwgImNvcHkiLCBDUFkyX1NJRyk7Ci0KLSAgICAgICAgZmluYWwgU3RyaW5nIGdldERvY19TSUcgPSAiKCkiK05PREVfU0lHOwotICAgICAgICBmaW5hbCBpbnQgZ2V0RG9jID0gY3BnLmFkZEludGVyZmFjZU1ldGhvZHJlZihET01fSU5URiwgImdldERvY3VtZW50IiwgZ2V0RG9jX1NJRyk7Ci0KLQotICAgICAgICBpZiAodHNlbGVjdCBpbnN0YW5jZW9mIE5vZGVTZXRUeXBlKSB7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0KLSAgICAgICAgICAgIC8vIHB1c2ggTm9kZUl0ZXJhdG9yCi0gICAgICAgICAgICBfc2VsZWN0LnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgICAgIF9zZWxlY3Quc3RhcnRJdGVyYXRvcihjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQotICAgICAgICAgICAgLy8gY2FsbCBjb3B5IGZyb20gdGhlIERPTSAnbGlicmFyeScKLSAgICAgICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZEhhbmRsZXIoKSk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRUlOVEVSRkFDRShjcHkxLCAzKSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAodHNlbGVjdCBpbnN0YW5jZW9mIE5vZGVUeXBlKSB7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0gICAgICAgICAgICBfc2VsZWN0LnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZEhhbmRsZXIoKSk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRUlOVEVSRkFDRShjcHkyLCAzKSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAodHNlbGVjdCBpbnN0YW5jZW9mIFJlc3VsdFRyZWVUeXBlKSB7Ci0gICAgICAgICAgICBfc2VsZWN0LnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgICAgIC8vIFdlIHdhbnQgdGhlIHdob2xlIHRyZWUsIHNvIHdlIHN0YXJ0IHdpdGggdGhlIHJvb3Qgbm9kZQotICAgICAgICAgICAgaWwuYXBwZW5kKERVUCk7IC8vbmVlZCBhIHBvaW50ZXIgdG8gdGhlIERPTSA7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRUlOVEVSRkFDRShnZXREb2MsMSkpOyAvL0lDT05TVF8wKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZEhhbmRsZXIoKSk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRUlOVEVSRkFDRShjcHkyLCAzKSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAodHNlbGVjdCBpbnN0YW5jZW9mIFJlZmVyZW5jZVR5cGUpIHsKLSAgICAgICAgICAgIF9zZWxlY3QudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkSGFuZGxlcigpKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZEN1cnJlbnROb2RlKCkpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkRE9NKCkpOwotICAgICAgICAgICAgZmluYWwgaW50IGNvcHkgPSBjcGcuYWRkTWV0aG9kcmVmKEJBU0lTX0xJQlJBUllfQ0xBU1MsICJjb3B5IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKCIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIE9CSkVDVF9TSUcKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIFRSQU5TTEVUX09VVFBVVF9TSUcKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIE5PREVfU0lHCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBET01fSU5URl9TSUcKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIpViIpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VTVEFUSUMoY29weSkpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgaWwuYXBwZW5kKGNsYXNzR2VuLmxvYWRUcmFuc2xldCgpKTsKLSAgICAgICAgICAgIF9zZWxlY3QudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkSGFuZGxlcigpKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChjcGcuYWRkTWV0aG9kcmVmKFRSQU5TTEVUX0NMQVNTLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ0hBUkFDVEVSU1csCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDSEFSQUNURVJTV19TSUcpKSk7Ci0gICAgICAgIH0KLQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvQ3VycmVudENhbGwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvQ3VycmVudENhbGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggY2NhNmVhMy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0N1cnJlbnRDYWxsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0MSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBDdXJyZW50Q2FsbC5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzAxIDEyOjIzOjE2IHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkNsYXNzR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLk1ldGhvZEdlbmVyYXRvcjsKLQotLyoqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKi8KLWZpbmFsIGNsYXNzIEN1cnJlbnRDYWxsIGV4dGVuZHMgRnVuY3Rpb25DYWxsIHsKLSAgICBwdWJsaWMgQ3VycmVudENhbGwoUU5hbWUgZm5hbWUpIHsKLSAgICAgICAgc3VwZXIoZm5hbWUpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotICAgICAgICBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCkuYXBwZW5kKG1ldGhvZEdlbi5sb2FkQ3VycmVudE5vZGUoKSk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9EZWNpbWFsRm9ybWF0dGluZy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9EZWNpbWFsRm9ybWF0dGluZy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4Yzg5ZWFlLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvRGVjaW1hbEZvcm1hdHRpbmcuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI1OCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBEZWNpbWFsRm9ybWF0dGluZy5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzEyIDEwOjE0OjMyIHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQ29uc3RhbnRQb29sR2VuOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuR0VUU1RBVElDOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFU1BFQ0lBTDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklOVk9LRVZJUlRVQUw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JbnN0cnVjdGlvbkxpc3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5ORVc7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5QVVNIOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkNsYXNzR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkVycm9yTXNnOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLk1ldGhvZEdlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGVDaGVja0Vycm9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuWE1MMTFDaGFyOwotCi0vKioKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICovCi1maW5hbCBjbGFzcyBEZWNpbWFsRm9ybWF0dGluZyBleHRlbmRzIFRvcExldmVsRWxlbWVudCB7Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgREZTX0NMQVNTID0gImphdmEudGV4dC5EZWNpbWFsRm9ybWF0U3ltYm9scyI7Ci0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIERGU19TSUcgICA9ICJMamF2YS90ZXh0L0RlY2ltYWxGb3JtYXRTeW1ib2xzOyI7Ci0KLSAgICBwcml2YXRlIFFOYW1lIF9uYW1lID0gbnVsbDsKLQotICAgIC8qKgotICAgICAqIE5vIHR5cGUgY2hlY2sgbmVlZGVkIGZvciB0aGUgPHhzbDpkZWNpbWFsLWZvcm1hdHRpbmcvPiBlbGVtZW50Ci0gICAgICovCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLSAgICAgICAgcmV0dXJuIFR5cGUuVm9pZDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBQYXJzZSB0aGUgbmFtZSBvZiB0aGUgPHhzbDpkZWNpbWFsLWZvcm1hdHRpbmcvPiBlbGVtZW50Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgcGFyc2VDb250ZW50cyhQYXJzZXIgcGFyc2VyKSB7Ci0gICAgICAgIC8vIEdldCB0aGUgbmFtZSBvZiB0aGVzZSBkZWNpbWFsIGZvcm1hdHRpbmcgc3ltYm9scwotICAgICAgICBmaW5hbCBTdHJpbmcgbmFtZSA9IGdldEF0dHJpYnV0ZSgibmFtZSIpOwotICAgICAgICBpZiAobmFtZS5sZW5ndGgoKSA+IDApIHsKLSAgICAgICAgICAgIGlmICghWE1MMTFDaGFyLmlzWE1MMTFWYWxpZFFOYW1lKG5hbWUpKXsKLSAgICAgICAgICAgICAgICBFcnJvck1zZyBlcnIgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuSU5WQUxJRF9RTkFNRV9FUlIsIG5hbWUsIHRoaXMpOwotICAgICAgICAgICAgICAgIHBhcnNlci5yZXBvcnRFcnJvcihDb25zdGFudHMuRVJST1IsIGVycik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgX25hbWUgPSBwYXJzZXIuZ2V0UU5hbWVJZ25vcmVEZWZhdWx0TnMobmFtZSk7Ci0gICAgICAgIGlmIChfbmFtZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBfbmFtZSA9IHBhcnNlci5nZXRRTmFtZUlnbm9yZURlZmF1bHROcyhFTVBUWVNUUklORyk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBDaGVjayBpZiBhIHNldCBvZiBzeW1ib2xzIGhhcyBhbHJlYWR5IGJlZW4gcmVnaXN0ZXJlZCB1bmRlciB0aGlzIG5hbWUKLSAgICAgICAgU3ltYm9sVGFibGUgc3RhYmxlID0gcGFyc2VyLmdldFN5bWJvbFRhYmxlKCk7Ci0gICAgICAgIGlmIChzdGFibGUuZ2V0RGVjaW1hbEZvcm1hdHRpbmcoX25hbWUpICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJlcG9ydFdhcm5pbmcodGhpcywgcGFyc2VyLCBFcnJvck1zZy5TWU1CT0xTX1JFREVGX0VSUiwKLSAgICAgICAgICAgICAgICBfbmFtZS50b1N0cmluZygpKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHN0YWJsZS5hZGREZWNpbWFsRm9ybWF0dGluZyhfbmFtZSwgdGhpcyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgd2hlbiB0aGUgY29uc3RydWN0b3IgaXMgY29tcGlsZWQgaW4KLSAgICAgKiBTdHlsZXNoZWV0LmNvbXBpbGVDb25zdHJ1Y3RvcigpIGFuZCBub3QgYXMgdGhlIHN5bnRheCB0cmVlIGlzIHRyYXZlcnNlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLQotICAgICAgICBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgICAgIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQotICAgICAgICAvLyBEZWNpbWFsRm9ybWF0U3ltYm9scy48aW5pdD4oTG9jYWxlKTsKLSAgICAgICAgLy8geHNsOmRlY2ltYWwtZm9ybWF0IC0gZXhjZXB0IGZvciB0aGUgTmFOIGFuZCBpbmZpbml0eSBhdHRyaWJ1dGVzLgotICAgICAgICBmaW5hbCBpbnQgaW5pdCA9IGNwZy5hZGRNZXRob2RyZWYoREZTX0NMQVNTLCAiPGluaXQ+IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoIitMT0NBTEVfU0lHKyIpViIpOwotCi0gICAgICAgIC8vIFB1c2ggdGhlIGZvcm1hdCBuYW1lIG9uIHRoZSBzdGFjayBmb3IgY2FsbCB0byBhZGREZWNpbWFsRm9ybWF0KCkKLSAgICAgICAgaWwuYXBwZW5kKGNsYXNzR2VuLmxvYWRUcmFuc2xldCgpKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgX25hbWUudG9TdHJpbmcoKSkpOwotCi0gICAgICAgIC8vIE1hbnVmYWN0dXJlIGEgRGVjaW1hbEZvcm1hdFN5bWJvbHMgb24gdGhlIHN0YWNrCi0gICAgICAgIC8vIGZvciBjYWxsIHRvIGFkZERlY2ltYWxGb3JtYXQoKQotICAgICAgICAvLyBVc2UgdGhlIFVTIExvY2FsZSBhcyB0aGUgZGVmYXVsdCwgYXMgbW9zdCBvZiBpdHMgc2V0dGluZ3MKLSAgICAgICAgLy8gYXJlIGVxdWl2YWxlbnQgdG8gdGhlIGRlZmF1bHQgc2V0dGluZ3MgcmVxdWlyZWQgb2YKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBORVcoY3BnLmFkZENsYXNzKERGU19DTEFTUykpKTsKLSAgICAgICAgaWwuYXBwZW5kKERVUCk7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgR0VUU1RBVElDKGNwZy5hZGRGaWVsZHJlZihMT0NBTEVfQ0xBU1MsICJVUyIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT0NBTEVfU0lHKSkpOwotICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRVNQRUNJQUwoaW5pdCkpOwotCi0gICAgICAgIFN0cmluZyB0bXAgPSBnZXRBdHRyaWJ1dGUoIk5hTiIpOwotICAgICAgICBpZiAoKHRtcCA9PSBudWxsKSB8fCAodG1wLmVxdWFscyhFTVBUWVNUUklORykpKSB7Ci0gICAgICAgICAgICBpbnQgbmFuID0gY3BnLmFkZE1ldGhvZHJlZihERlNfQ0xBU1MsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAic2V0TmFOIiwgIihMamF2YS9sYW5nL1N0cmluZzspViIpOwotICAgICAgICAgICAgaWwuYXBwZW5kKERVUCk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCAiTmFOIikpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VWSVJUVUFMKG5hbikpOwotICAgICAgICB9Ci0KLSAgICAgICAgdG1wID0gZ2V0QXR0cmlidXRlKCJpbmZpbml0eSIpOwotICAgICAgICBpZiAoKHRtcCA9PSBudWxsKSB8fCAodG1wLmVxdWFscyhFTVBUWVNUUklORykpKSB7Ci0gICAgICAgICAgICBpbnQgaW5mID0gY3BnLmFkZE1ldGhvZHJlZihERlNfQ0xBU1MsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAic2V0SW5maW5pdHkiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIihMamF2YS9sYW5nL1N0cmluZzspViIpOwotICAgICAgICAgICAgaWwuYXBwZW5kKERVUCk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCAiSW5maW5pdHkiKSk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRVZJUlRVQUwoaW5mKSk7Ci0gICAgICAgIH0KLQotICAgICAgICBmaW5hbCBpbnQgbkF0dHJpYnV0ZXMgPSBfYXR0cmlidXRlcy5nZXRMZW5ndGgoKTsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuQXR0cmlidXRlczsgaSsrKSB7Ci0gICAgICAgICAgICBmaW5hbCBTdHJpbmcgbmFtZSA9IF9hdHRyaWJ1dGVzLmdldFFOYW1lKGkpOwotICAgICAgICAgICAgZmluYWwgU3RyaW5nIHZhbHVlID0gX2F0dHJpYnV0ZXMuZ2V0VmFsdWUoaSk7Ci0KLSAgICAgICAgICAgIGJvb2xlYW4gdmFsaWQgPSB0cnVlOwotICAgICAgICAgICAgaW50IG1ldGhvZCA9IDA7Ci0KLSAgICAgICAgICAgIGlmIChuYW1lLmVxdWFscygiZGVjaW1hbC1zZXBhcmF0b3IiKSkgewotICAgICAgICAgICAgICAgIC8vIERlY2ltYWxGb3JtYXRTeW1ib2xzLnNldERlY2ltYWxTZXBhcmF0b3IoKTsKLSAgICAgICAgICAgICAgICBtZXRob2QgPSBjcGcuYWRkTWV0aG9kcmVmKERGU19DTEFTUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJzZXREZWNpbWFsU2VwYXJhdG9yIiwgIihDKVYiKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzKCJncm91cGluZy1zZXBhcmF0b3IiKSkgewotICAgICAgICAgICAgICAgIG1ldGhvZCA9ICBjcGcuYWRkTWV0aG9kcmVmKERGU19DTEFTUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAic2V0R3JvdXBpbmdTZXBhcmF0b3IiLCAiKEMpViIpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAobmFtZS5lcXVhbHMoIm1pbnVzLXNpZ24iKSkgewotICAgICAgICAgICAgICAgIG1ldGhvZCA9IGNwZy5hZGRNZXRob2RyZWYoREZTX0NMQVNTLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInNldE1pbnVzU2lnbiIsICIoQylWIik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFscygicGVyY2VudCIpKSB7Ci0gICAgICAgICAgICAgICAgbWV0aG9kID0gY3BnLmFkZE1ldGhvZHJlZihERlNfQ0xBU1MsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAic2V0UGVyY2VudCIsICIoQylWIik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFscygicGVyLW1pbGxlIikpIHsKLSAgICAgICAgICAgICAgICBtZXRob2QgPSBjcGcuYWRkTWV0aG9kcmVmKERGU19DTEFTUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJzZXRQZXJNaWxsIiwgIihDKVYiKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzKCJ6ZXJvLWRpZ2l0IikpIHsKLSAgICAgICAgICAgICAgICBtZXRob2QgPSBjcGcuYWRkTWV0aG9kcmVmKERGU19DTEFTUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJzZXRaZXJvRGlnaXQiLCAiKEMpViIpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAobmFtZS5lcXVhbHMoImRpZ2l0IikpIHsKLSAgICAgICAgICAgICAgICBtZXRob2QgPSBjcGcuYWRkTWV0aG9kcmVmKERGU19DTEFTUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJzZXREaWdpdCIsICIoQylWIik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFscygicGF0dGVybi1zZXBhcmF0b3IiKSkgewotICAgICAgICAgICAgICAgIG1ldGhvZCA9IGNwZy5hZGRNZXRob2RyZWYoREZTX0NMQVNTLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInNldFBhdHRlcm5TZXBhcmF0b3IiLCAiKEMpViIpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAobmFtZS5lcXVhbHMoIk5hTiIpKSB7Ci0gICAgICAgICAgICAgICAgbWV0aG9kID0gY3BnLmFkZE1ldGhvZHJlZihERlNfQ0xBU1MsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAic2V0TmFOIiwgIihMamF2YS9sYW5nL1N0cmluZzspViIpOwotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChEVVApOwotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsIHZhbHVlKSk7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VWSVJUVUFMKG1ldGhvZCkpOwotICAgICAgICAgICAgICAgIHZhbGlkID0gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFscygiaW5maW5pdHkiKSkgewotICAgICAgICAgICAgICAgIG1ldGhvZCA9IGNwZy5hZGRNZXRob2RyZWYoREZTX0NMQVNTLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInNldEluZmluaXR5IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoTGphdmEvbGFuZy9TdHJpbmc7KVYiKTsKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQoRFVQKTsKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCB2YWx1ZSkpOwotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChtZXRob2QpKTsKLSAgICAgICAgICAgICAgICB2YWxpZCA9IGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgdmFsaWQgPSBmYWxzZTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKHZhbGlkKSB7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKERVUCk7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgdmFsdWUuY2hhckF0KDApKSk7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VWSVJUVUFMKG1ldGhvZCkpOwotICAgICAgICAgICAgfQotCi0gICAgICAgIH0KLQotICAgICAgICBmaW5hbCBpbnQgcHV0ID0gY3BnLmFkZE1ldGhvZHJlZihUUkFOU0xFVF9DTEFTUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImFkZERlY2ltYWxGb3JtYXQiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKCIrU1RSSU5HX1NJRytERlNfU0lHKyIpViIpOwotICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRVZJUlRVQUwocHV0KSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlcyB0aGUgZGVmYXVsdCwgbmFtZWxlc3MsIERlY2ltYWxGb3JtYXQgb2JqZWN0IGluCi0gICAgICogQWJzdHJhY3RUcmFuc2xldCdzIGZvcm1hdF9zeW1ib2xzIGhhc2h0YWJsZS4KLSAgICAgKiBUaGlzIHNob3VsZCBiZSBjYWxsZWQgZm9yIGV2ZXJ5IHN0eWxlc2hlZXQsIGFuZCB0aGUgZW50cnkKLSAgICAgKiBtYXkgYmUgb3ZlcnJpZGRlbiBieSBsYXRlciBuYW1lbGVzcyB4c2w6ZGVjaW1hbC1mb3JtYXQgaW5zdHJ1Y3Rpb25zLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgdm9pZCB0cmFuc2xhdGVEZWZhdWx0REZTKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLQotICAgICAgICBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgICAgIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLSAgICAgICAgZmluYWwgaW50IGluaXQgPSBjcGcuYWRkTWV0aG9kcmVmKERGU19DTEFTUywgIjxpbml0PiIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKCIrTE9DQUxFX1NJRysiKVYiKTsKLQotICAgICAgICAvLyBQdXNoIHRoZSBmb3JtYXQgbmFtZSwgd2hpY2ggaXMgZW1wdHksIG9uIHRoZSBzdGFjawotICAgICAgICAvLyBmb3IgY2FsbCB0byBhZGREZWNpbWFsRm9ybWF0KCkKLSAgICAgICAgaWwuYXBwZW5kKGNsYXNzR2VuLmxvYWRUcmFuc2xldCgpKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgRU1QVFlTVFJJTkcpKTsKLQotICAgICAgICAvLyBNYW51ZmFjdHVyZSBhIERlY2ltYWxGb3JtYXRTeW1ib2xzIG9uIHRoZSBzdGFjayBmb3IKLSAgICAgICAgLy8gY2FsbCB0byBhZGREZWNpbWFsRm9ybWF0KCkuICBVc2UgdGhlIFVTIExvY2FsZSBhcyB0aGUKLSAgICAgICAgLy8gZGVmYXVsdCwgYXMgbW9zdCBvZiBpdHMgc2V0dGluZ3MgYXJlIGVxdWl2YWxlbnQgdG8KLSAgICAgICAgLy8gdGhlIGRlZmF1bHQgc2V0dGluZ3MgcmVxdWlyZWQgb2YgeHNsOmRlY2ltYWwtZm9ybWF0IC0KLSAgICAgICAgLy8gZXhjZXB0IGZvciB0aGUgTmFOIGFuZCBpbmZpbml0eSBhdHRyaWJ1dGVzLgotICAgICAgICBpbC5hcHBlbmQobmV3IE5FVyhjcGcuYWRkQ2xhc3MoREZTX0NMQVNTKSkpOwotICAgICAgICBpbC5hcHBlbmQoRFVQKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBHRVRTVEFUSUMoY3BnLmFkZEZpZWxkcmVmKExPQ0FMRV9DTEFTUywgIlVTIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPQ0FMRV9TSUcpKSk7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFU1BFQ0lBTChpbml0KSk7Ci0KLSAgICAgICAgaW50IG5hbiA9IGNwZy5hZGRNZXRob2RyZWYoREZTX0NMQVNTLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAic2V0TmFOIiwgIihMamF2YS9sYW5nL1N0cmluZzspViIpOwotICAgICAgICBpbC5hcHBlbmQoRFVQKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgIk5hTiIpKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VWSVJUVUFMKG5hbikpOwotCi0gICAgICAgIGludCBpbmYgPSBjcGcuYWRkTWV0aG9kcmVmKERGU19DTEFTUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInNldEluZmluaXR5IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIihMamF2YS9sYW5nL1N0cmluZzspViIpOwotICAgICAgICBpbC5hcHBlbmQoRFVQKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgIkluZmluaXR5IikpOwotICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRVZJUlRVQUwoaW5mKSk7Ci0KLSAgICAgICAgZmluYWwgaW50IHB1dCA9IGNwZy5hZGRNZXRob2RyZWYoVFJBTlNMRVRfQ0xBU1MsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJhZGREZWNpbWFsRm9ybWF0IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIigiK1NUUklOR19TSUcrREZTX1NJRysiKVYiKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VWSVJUVUFMKHB1dCkpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvRG9jdW1lbnRDYWxsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0RvY3VtZW50Q2FsbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0NDA2M2EzLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvRG9jdW1lbnRDYWxsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNTggKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRG9jdW1lbnRDYWxsLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMDEgMTQ6MTA6MTMgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQ29uc3RhbnRQb29sR2VuOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuR0VURklFTEQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JTlZPS0VJTlRFUkZBQ0U7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JTlZPS0VTVEFUSUM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JbnN0cnVjdGlvbkxpc3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5QVVNIOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkNsYXNzR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkVycm9yTXNnOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLk1ldGhvZEdlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGVDaGVja0Vycm9yOwotCi0vKioKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqLwotZmluYWwgY2xhc3MgRG9jdW1lbnRDYWxsIGV4dGVuZHMgRnVuY3Rpb25DYWxsIHsKLQotICAgIHByaXZhdGUgRXhwcmVzc2lvbiBfYXJnMSA9IG51bGw7Ci0gICAgcHJpdmF0ZSBFeHByZXNzaW9uIF9hcmcyID0gbnVsbDsKLSAgICBwcml2YXRlIFR5cGUgICAgICAgX2FyZzFUeXBlOwotCi0gICAgLyoqCi0gICAgICogRGVmYXVsdCBmdW5jdGlvbiBjYWxsIGNvbnN0cnVjdG9yCi0gICAgICovCi0gICAgcHVibGljIERvY3VtZW50Q2FsbChRTmFtZSBmbmFtZSwgVmVjdG9yIGFyZ3VtZW50cykgewotICAgICAgICBzdXBlcihmbmFtZSwgYXJndW1lbnRzKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUeXBlIGNoZWNrcyB0aGUgYXJndW1lbnRzIHBhc3NlZCB0byB0aGUgZG9jdW1lbnQoKSBmdW5jdGlvbi4gVGhlIGZpcnN0Ci0gICAgICogYXJndW1lbnQgY2FuIGJlIGFueSB0eXBlICh3ZSBtdXN0IGNhc3QgaXQgdG8gYSBzdHJpbmcpIGFuZCBjb250YWlucyB0aGUKLSAgICAgKiBVUkkgb2YgdGhlIGRvY3VtZW50Ci0gICAgICovCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLSAgICAgICAgLy8gQXQgbGVhc3Qgb25lIGFyZ3VtZW50IC0gdHdvIGF0IG1vc3QKLSAgICAgICAgZmluYWwgaW50IGFjID0gYXJndW1lbnRDb3VudCgpOwotICAgICAgICBpZiAoKGFjIDwgMSkgfHwgKGFjID4gMikpIHsKLSAgICAgICAgICAgIEVycm9yTXNnIG1zZyA9IG5ldyBFcnJvck1zZyhFcnJvck1zZy5JTExFR0FMX0FSR19FUlIsIHRoaXMpOwotICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVDaGVja0Vycm9yKG1zZyk7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGdldFN0eWxlc2hlZXQoKSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBFcnJvck1zZyBtc2cgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuSUxMRUdBTF9BUkdfRVJSLCB0aGlzKTsKLSAgICAgICAgICAgIHRocm93IG5ldyBUeXBlQ2hlY2tFcnJvcihtc2cpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gUGFyc2UgdGhlIGZpcnN0IGFyZ3VtZW50Ci0gICAgICAgIF9hcmcxID0gYXJndW1lbnQoMCk7Ci0KLSAgICAgICAgaWYgKF9hcmcxID09IG51bGwpIHsvLyBzaG91bGQgbm90IGhhcHBlbmVkCi0gICAgICAgICAgICBFcnJvck1zZyBtc2cgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuRE9DVU1FTlRfQVJHX0VSUiwgdGhpcyk7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUNoZWNrRXJyb3IobXNnKTsKLSAgICAgICAgfQotCi0gICAgICAgIF9hcmcxVHlwZSA9IF9hcmcxLnR5cGVDaGVjayhzdGFibGUpOwotICAgICAgICBpZiAoKF9hcmcxVHlwZSAhPSBUeXBlLk5vZGVTZXQpICYmIChfYXJnMVR5cGUgIT0gVHlwZS5TdHJpbmcpKSB7Ci0gICAgICAgICAgICBfYXJnMSA9IG5ldyBDYXN0RXhwcihfYXJnMSwgVHlwZS5TdHJpbmcpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gUGFyc2UgdGhlIHNlY29uZCBhcmd1bWVudAotICAgICAgICBpZiAoYWMgPT0gMikgewotICAgICAgICAgICAgX2FyZzIgPSBhcmd1bWVudCgxKTsKLQotICAgICAgICAgICAgaWYgKF9hcmcyID09IG51bGwpIHsvLyBzaG91bGQgbm90IGhhcHBlbmVkCi0gICAgICAgICAgICAgICAgRXJyb3JNc2cgbXNnID0gbmV3IEVycm9yTXNnKEVycm9yTXNnLkRPQ1VNRU5UX0FSR19FUlIsIHRoaXMpOwotICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlQ2hlY2tFcnJvcihtc2cpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBmaW5hbCBUeXBlIGFyZzJUeXBlID0gX2FyZzIudHlwZUNoZWNrKHN0YWJsZSk7Ci0KLSAgICAgICAgICAgIGlmIChhcmcyVHlwZS5pZGVudGljYWxUbyhUeXBlLk5vZGUpKSB7Ci0gICAgICAgICAgICAgICAgX2FyZzIgPSBuZXcgQ2FzdEV4cHIoX2FyZzIsIFR5cGUuTm9kZVNldCk7Ci0gICAgICAgICAgICB9IGVsc2UgaWYgKGFyZzJUeXBlLmlkZW50aWNhbFRvKFR5cGUuTm9kZVNldCkpIHsKLSAgICAgICAgICAgICAgICAvLyBmYWxscyB0aHJvdWdoCi0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIEVycm9yTXNnIG1zZyA9IG5ldyBFcnJvck1zZyhFcnJvck1zZy5ET0NVTUVOVF9BUkdfRVJSLCB0aGlzKTsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUNoZWNrRXJyb3IobXNnKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBfdHlwZSA9IFR5cGUuTm9kZVNldDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGVzIHRoZSBkb2N1bWVudCgpIGZ1bmN0aW9uIGNhbGwgdG8gYSBjYWxsIHRvIExvYWREb2N1bWVudCgpJ3MKLSAgICAgKiBzdGF0aWMgbWV0aG9kIGRvY3VtZW50KCkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0gICAgICAgIGZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotICAgICAgICBmaW5hbCBpbnQgYWMgPSBhcmd1bWVudENvdW50KCk7Ci0KLSAgICAgICAgZmluYWwgaW50IGRvbUZpZWxkID0gY3BnLmFkZEZpZWxkcmVmKGNsYXNzR2VuLmdldENsYXNzTmFtZSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRE9NX0ZJRUxELAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRE9NX0lOVEZfU0lHKTsKLQotICAgICAgICBTdHJpbmcgZG9jUGFyYW1MaXN0ID0gbnVsbDsKLSAgICAgICAgaWYgKGFjID09IDEpIHsKLSAgICAgICAgICAgLy8gZG9jdW1lbnRGKE9iamVjdCxTdHJpbmcsQWJzdHJhY3RUcmFuc2xldCxET00pCi0gICAgICAgICAgIGRvY1BhcmFtTGlzdCA9ICIoIitPQkpFQ1RfU0lHK1NUUklOR19TSUcrVFJBTlNMRVRfU0lHK0RPTV9JTlRGX1NJRwotICAgICAgICAgICAgICAgICAgICAgICAgICsiKSIrTk9ERV9JVEVSQVRPUl9TSUc7Ci0gICAgICAgIH0gZWxzZSB7IC8vYWMgPT0gMjsgYWMgPCAxIG9yIGFzID4yICB3YXMgdGVzdGVkIGluIHR5cGVDaGVjKCkKLSAgICAgICAgICAgLy8gZG9jdW1lbnRGKE9iamVjdCxEVE1BeGlzSXRlcmF0b3IsU3RyaW5nLEFic3RyYWN0VHJhbnNsZXQsRE9NKQotICAgICAgICAgICBkb2NQYXJhbUxpc3QgPSAiKCIrT0JKRUNUX1NJRytOT0RFX0lURVJBVE9SX1NJRytTVFJJTkdfU0lHCi0gICAgICAgICAgICAgICAgICAgICAgICAgK1RSQU5TTEVUX1NJRytET01fSU5URl9TSUcrIikiK05PREVfSVRFUkFUT1JfU0lHOwotICAgICAgICB9Ci0gICAgICAgIGZpbmFsIGludCBkb2NJZHggPSBjcGcuYWRkTWV0aG9kcmVmKExPQURfRE9DVU1FTlRfQ0xBU1MsICJkb2N1bWVudEYiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2NQYXJhbUxpc3QpOwotCi0KLSAgICAgICAgLy8gVGhlIFVSSSBjYW4gYmUgZWl0aGVyIGEgbm9kZS1zZXQgb3Igc29tZXRoaW5nIGVsc2UgY2FzdCB0byBhIHN0cmluZwotICAgICAgICBfYXJnMS50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgIGlmIChfYXJnMVR5cGUgPT0gVHlwZS5Ob2RlU2V0KSB7Ci0gICAgICAgICAgICBfYXJnMS5zdGFydEl0ZXJhdG9yKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKGFjID09IDIpIHsKLSAgICAgICAgICAgIC8vX2FyZzIgPT0gbnVsbCB3YXMgdGVzdGVkIGluIHR5cGVDaGVjKCkKLSAgICAgICAgICAgIF9hcmcyLnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgICAgIF9hcmcyLnN0YXJ0SXRlcmF0b3IoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBGZWNrIHRoZSByZXN0IG9mIHRoZSBwYXJhbWV0ZXJzIG9uIHRoZSBzdGFjawotICAgICAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBnZXRTdHlsZXNoZWV0KCkuZ2V0U3lzdGVtSWQoKSkpOwotICAgICAgICBpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpOwotICAgICAgICBpbC5hcHBlbmQoRFVQKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBHRVRGSUVMRChkb21GaWVsZCkpOwotICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRVNUQVRJQyhkb2NJZHgpKTsKLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvRWxlbWVudEF2YWlsYWJsZUNhbGwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvRWxlbWVudEF2YWlsYWJsZUNhbGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNGI0OWYxYy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0VsZW1lbnRBdmFpbGFibGVDYWxsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5NSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBFbGVtZW50QXZhaWxhYmxlQ2FsbC5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzAxIDE0OjEzOjAxIHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkNvbnN0YW50UG9vbEdlbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlBVU0g7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuQ2xhc3NHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuRXJyb3JNc2c7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuTWV0aG9kR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZUNoZWNrRXJyb3I7Ci0KLS8qKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICovCi1maW5hbCBjbGFzcyBFbGVtZW50QXZhaWxhYmxlQ2FsbCBleHRlbmRzIEZ1bmN0aW9uQ2FsbCB7Ci0KLSAgICBwdWJsaWMgRWxlbWVudEF2YWlsYWJsZUNhbGwoUU5hbWUgZm5hbWUsIFZlY3RvciBhcmd1bWVudHMpIHsKLSAgICAgICAgc3VwZXIoZm5hbWUsIGFyZ3VtZW50cyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRm9yY2UgdGhlIGFyZ3VtZW50IHRvIHRoaXMgZnVuY3Rpb24gdG8gYmUgYSBsaXRlcmFsIHN0cmluZy4KLSAgICAgKi8KLSAgICBwdWJsaWMgVHlwZSB0eXBlQ2hlY2soU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgewotICAgICAgICBpZiAoYXJndW1lbnQoKSBpbnN0YW5jZW9mIExpdGVyYWxFeHByKSB7Ci0gICAgICAgICAgICByZXR1cm4gX3R5cGUgPSBUeXBlLkJvb2xlYW47Ci0gICAgICAgIH0KLSAgICAgICAgRXJyb3JNc2cgZXJyID0gbmV3IEVycm9yTXNnKEVycm9yTXNnLk5FRURfTElURVJBTF9FUlIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZWxlbWVudC1hdmFpbGFibGUiLCB0aGlzKTsKLSAgICAgICAgdGhyb3cgbmV3IFR5cGVDaGVja0Vycm9yKGVycik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhbiBvYmplY3QgcmVwcmVzZW50aW5nIHRoZSBjb21waWxlLXRpbWUgZXZhbHVhdGlvbgotICAgICAqIG9mIGFuIGV4cHJlc3Npb24uIFdlIGFyZSBvbmx5IHVzaW5nIHRoaXMgZm9yIGZ1bmN0aW9uLWF2YWlsYWJsZQotICAgICAqIGFuZCBlbGVtZW50LWF2YWlsYWJsZSBhdCB0aGlzIHRpbWUuCi0gICAgICovCi0gICAgcHVibGljIE9iamVjdCBldmFsdWF0ZUF0Q29tcGlsZVRpbWUoKSB7Ci0gICAgICAgIHJldHVybiBnZXRSZXN1bHQoKSA/IEJvb2xlYW4uVFJVRSA6IEJvb2xlYW4uRkFMU0U7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgcmVzdWx0IHRoYXQgdGhpcyBmdW5jdGlvbiB3aWxsIHJldHVybgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGdldFJlc3VsdCgpIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGZpbmFsIExpdGVyYWxFeHByIGFyZyA9IChMaXRlcmFsRXhwcikgYXJndW1lbnQoKTsKLSAgICAgICAgICAgIGZpbmFsIFN0cmluZyBxbmFtZSA9IGFyZy5nZXRWYWx1ZSgpOwotICAgICAgICAgICAgZmluYWwgaW50IGluZGV4ID0gcW5hbWUuaW5kZXhPZignOicpOwotICAgICAgICAgICAgZmluYWwgU3RyaW5nIGxvY2FsTmFtZSA9IChpbmRleCA+IDApID8KLSAgICAgICAgICAgICAgICBxbmFtZS5zdWJzdHJpbmcoaW5kZXggKyAxKSA6IHFuYW1lOwotICAgICAgICAgICAgcmV0dXJuIGdldFBhcnNlcigpLmVsZW1lbnRTdXBwb3J0ZWQoYXJnLmdldE5hbWVzcGFjZSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWxOYW1lKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIENhbGxzIHRvICdlbGVtZW50LWF2YWlsYWJsZScgYXJlIHJlc29sdmVkIGF0IGNvbXBpbGUgdGltZSBzaW5jZQotICAgICAqIHRoZSBuYW1lc3BhY2VzIGRlY2xhcmVkIGluIHRoZSBzdHlsc2hlZXQgYXJlIG5vdCBhdmFpbGFibGUgYXQgcnVuCi0gICAgICogdGltZS4gQ29uc2VxdWVudGx5LCBhcmd1bWVudHMgdG8gdGhpcyBmdW5jdGlvbiBtdXN0IGJlIGxpdGVyYWxzLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotICAgICAgICBmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgICAgIGZpbmFsIGJvb2xlYW4gcmVzdWx0ID0gZ2V0UmVzdWx0KCk7Ci0gICAgICAgIG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKS5hcHBlbmQobmV3IFBVU0goY3BnLCByZXN1bHQpKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0VxdWFsaXR5RXhwci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9FcXVhbGl0eUV4cHIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZTFkOWIwYS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0VxdWFsaXR5RXhwci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzYxICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IEVxdWFsaXR5RXhwci5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzEyIDEwOjE2OjUyIHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQnJhbmNoSGFuZGxlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQnJhbmNoSW5zdHJ1Y3Rpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5Db25zdGFudFBvb2xHZW47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5HT1RPOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSUZFUTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklGTkU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JRl9JQ01QRVE7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JRl9JQ01QTkU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JTlZPS0VTVEFUSUM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JTlZPS0VWSVJUVUFMOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW5zdHJ1Y3Rpb25MaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuUFVTSDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5Cb29sZWFuVHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5DbGFzc0dlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5JbnRUeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLk1ldGhvZEdlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5Ob2RlU2V0VHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5Ob2RlVHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5OdW1iZXJUeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlJlYWxUeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlJlZmVyZW5jZVR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuUmVzdWx0VHJlZVR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuU3RyaW5nVHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGVDaGVja0Vycm9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5ydW50aW1lLk9wZXJhdG9yczsKLQotLyoqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqIEBhdXRob3IgRXJ3aW4gQm9sd2lkdCA8ZWpiQGtsb21wLm9yZz4KLSAqLwotZmluYWwgY2xhc3MgRXF1YWxpdHlFeHByIGV4dGVuZHMgRXhwcmVzc2lvbiB7Ci0KLSAgICBwcml2YXRlIGZpbmFsIGludCBfb3A7Ci0gICAgcHJpdmF0ZSBFeHByZXNzaW9uIF9sZWZ0OwotICAgIHByaXZhdGUgRXhwcmVzc2lvbiBfcmlnaHQ7Ci0KLSAgICBwdWJsaWMgRXF1YWxpdHlFeHByKGludCBvcCwgRXhwcmVzc2lvbiBsZWZ0LCBFeHByZXNzaW9uIHJpZ2h0KSB7Ci0gICAgICAgIF9vcCA9IG9wOwotICAgICAgICAoX2xlZnQgPSBsZWZ0KS5zZXRQYXJlbnQodGhpcyk7Ci0gICAgICAgIChfcmlnaHQgPSByaWdodCkuc2V0UGFyZW50KHRoaXMpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldFBhcnNlcihQYXJzZXIgcGFyc2VyKSB7Ci0gICAgICAgIHN1cGVyLnNldFBhcnNlcihwYXJzZXIpOwotICAgICAgICBfbGVmdC5zZXRQYXJzZXIocGFyc2VyKTsKLSAgICAgICAgX3JpZ2h0LnNldFBhcnNlcihwYXJzZXIpOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0gICAgICAgIHJldHVybiBPcGVyYXRvcnMuZ2V0T3BOYW1lcyhfb3ApICsgJygnICsgX2xlZnQgKyAiLCAiICsgX3JpZ2h0ICsgJyknOwotICAgIH0KLQotICAgIHB1YmxpYyBFeHByZXNzaW9uIGdldExlZnQoKSB7Ci0gICAgICAgIHJldHVybiBfbGVmdDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgRXhwcmVzc2lvbiBnZXRSaWdodCgpIHsKLSAgICAgICAgcmV0dXJuIF9yaWdodDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXRPcCgpIHsKLSAgICAgICAgcmV0dXJuIChfb3AgIT0gT3BlcmF0b3JzLk5FKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhpcyBleHByZXNzaW9ucyBjb250YWlucyBhIGNhbGwgdG8gcG9zaXRpb24oKS4gVGhpcyBpcwotICAgICAqIG5lZWRlZCBmb3IgY29udGV4dCBjaGFuZ2VzIGluIG5vZGUgc3RlcHMgY29udGFpbmluZyBtdWx0aXBsZSBwcmVkaWNhdGVzLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGhhc1Bvc2l0aW9uQ2FsbCgpIHsKLSAgICAgICAgaWYgKF9sZWZ0Lmhhc1Bvc2l0aW9uQ2FsbCgpKSByZXR1cm4gdHJ1ZTsKLSAgICAgICAgaWYgKF9yaWdodC5oYXNQb3NpdGlvbkNhbGwoKSkgcmV0dXJuIHRydWU7Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBoYXNMYXN0Q2FsbCgpIHsKLSAgICAgICAgaWYgKF9sZWZ0Lmhhc0xhc3RDYWxsKCkpIHJldHVybiB0cnVlOwotICAgICAgICBpZiAoX3JpZ2h0Lmhhc0xhc3RDYWxsKCkpIHJldHVybiB0cnVlOwotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIHN3YXBBcmd1bWVudHMoKSB7Ci0gICAgICAgIGZpbmFsIEV4cHJlc3Npb24gdGVtcCA9IF9sZWZ0OwotICAgICAgICBfbGVmdCA9IF9yaWdodDsKLSAgICAgICAgX3JpZ2h0ID0gdGVtcDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUeXBpbmcgcnVsZXM6IHNlZSBYU0xUIFJlZmVyZW5jZSBieSBNLiBLYXkgcGFnZSAzNDUuCi0gICAgICovCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLSAgICAgICAgZmluYWwgVHlwZSB0bGVmdCA9IF9sZWZ0LnR5cGVDaGVjayhzdGFibGUpOwotICAgICAgICBmaW5hbCBUeXBlIHRyaWdodCA9IF9yaWdodC50eXBlQ2hlY2soc3RhYmxlKTsKLQotICAgICAgICBpZiAodGxlZnQuaXNTaW1wbGUoKSAmJiB0cmlnaHQuaXNTaW1wbGUoKSkgewotICAgICAgICAgICAgaWYgKHRsZWZ0ICE9IHRyaWdodCkgewotICAgICAgICAgICAgICAgIGlmICh0bGVmdCBpbnN0YW5jZW9mIEJvb2xlYW5UeXBlKSB7Ci0gICAgICAgICAgICAgICAgICAgIF9yaWdodCA9IG5ldyBDYXN0RXhwcihfcmlnaHQsIFR5cGUuQm9vbGVhbik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgaWYgKHRyaWdodCBpbnN0YW5jZW9mIEJvb2xlYW5UeXBlKSB7Ci0gICAgICAgICAgICAgICAgICAgIF9sZWZ0ID0gbmV3IENhc3RFeHByKF9sZWZ0LCBUeXBlLkJvb2xlYW4pOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIGlmICh0bGVmdCBpbnN0YW5jZW9mIE51bWJlclR5cGUgfHwKLSAgICAgICAgICAgICAgICAgICAgICAgICB0cmlnaHQgaW5zdGFuY2VvZiBOdW1iZXJUeXBlKSB7Ci0gICAgICAgICAgICAgICAgICAgIF9sZWZ0ID0gbmV3IENhc3RFeHByKF9sZWZ0LCBUeXBlLlJlYWwpOwotICAgICAgICAgICAgICAgICAgICBfcmlnaHQgPSBuZXcgQ2FzdEV4cHIoX3JpZ2h0LCBUeXBlLlJlYWwpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsgICAgICAgICAgLy8gYm90aCBjb21wYXJlZCBhcyBzdHJpbmdzCi0gICAgICAgICAgICAgICAgICAgIF9sZWZ0ID0gbmV3IENhc3RFeHByKF9sZWZ0LCAgIFR5cGUuU3RyaW5nKTsKLSAgICAgICAgICAgICAgICAgICAgX3JpZ2h0ID0gbmV3IENhc3RFeHByKF9yaWdodCwgVHlwZS5TdHJpbmcpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICh0bGVmdCBpbnN0YW5jZW9mIFJlZmVyZW5jZVR5cGUpIHsKLSAgICAgICAgICAgIF9yaWdodCA9IG5ldyBDYXN0RXhwcihfcmlnaHQsIFR5cGUuUmVmZXJlbmNlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICh0cmlnaHQgaW5zdGFuY2VvZiBSZWZlcmVuY2VUeXBlKSB7Ci0gICAgICAgICAgICBfbGVmdCA9IG5ldyBDYXN0RXhwcihfbGVmdCwgVHlwZS5SZWZlcmVuY2UpOwotICAgICAgICB9Ci0gICAgICAgIC8vIHRoZSBmb2xsb3dpbmcgMiBjYXNlcyBvcHRpbWl6ZSBAYXR0cnwufC4uID0gJ3N0cmluZycKLSAgICAgICAgZWxzZSBpZiAodGxlZnQgaW5zdGFuY2VvZiBOb2RlVHlwZSAmJiB0cmlnaHQgPT0gVHlwZS5TdHJpbmcpIHsKLSAgICAgICAgICAgIF9sZWZ0ID0gbmV3IENhc3RFeHByKF9sZWZ0LCBUeXBlLlN0cmluZyk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAodGxlZnQgPT0gVHlwZS5TdHJpbmcgJiYgdHJpZ2h0IGluc3RhbmNlb2YgTm9kZVR5cGUpIHsKLSAgICAgICAgICAgIF9yaWdodCA9IG5ldyBDYXN0RXhwcihfcmlnaHQsIFR5cGUuU3RyaW5nKTsKLSAgICAgICAgfQotICAgICAgICAvLyBvcHRpbWl6ZSBub2RlL25vZGUKLSAgICAgICAgZWxzZSBpZiAodGxlZnQgaW5zdGFuY2VvZiBOb2RlVHlwZSAmJiB0cmlnaHQgaW5zdGFuY2VvZiBOb2RlVHlwZSkgewotICAgICAgICAgICAgX2xlZnQgPSBuZXcgQ2FzdEV4cHIoX2xlZnQsIFR5cGUuU3RyaW5nKTsKLSAgICAgICAgICAgIF9yaWdodCA9IG5ldyBDYXN0RXhwcihfcmlnaHQsIFR5cGUuU3RyaW5nKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICh0bGVmdCBpbnN0YW5jZW9mIE5vZGVUeXBlICYmIHRyaWdodCBpbnN0YW5jZW9mIE5vZGVTZXRUeXBlKSB7Ci0gICAgICAgICAgICAvLyBjb21wYXJlKE5vZGUsIE5vZGVTZXQpIHdpbGwgYmUgaW52b2tlZAotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKHRsZWZ0IGluc3RhbmNlb2YgTm9kZVNldFR5cGUgJiYgdHJpZ2h0IGluc3RhbmNlb2YgTm9kZVR5cGUpIHsKLSAgICAgICAgICAgIHN3YXBBcmd1bWVudHMoKTsgICAgLy8gZm9yIGNvbXBhcmUoTm9kZSwgTm9kZVNldCkKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIC8vIEF0IGxlYXN0IG9uZSBhcmd1bWVudCBpcyBvZiB0eXBlIG5vZGUsIG5vZGUtc2V0IG9yIHJlc3VsdC10cmVlCi0KLSAgICAgICAgICAgIC8vIFByb21vdGUgYW4gZXhwcmVzc2lvbiBvZiB0eXBlIG5vZGUgdG8gbm9kZS1zZXQKLSAgICAgICAgICAgIGlmICh0bGVmdCBpbnN0YW5jZW9mIE5vZGVUeXBlKSB7Ci0gICAgICAgICAgICAgICAgX2xlZnQgPSBuZXcgQ2FzdEV4cHIoX2xlZnQsIFR5cGUuTm9kZVNldCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAodHJpZ2h0IGluc3RhbmNlb2YgTm9kZVR5cGUpIHsKLSAgICAgICAgICAgICAgICBfcmlnaHQgPSBuZXcgQ2FzdEV4cHIoX3JpZ2h0LCBUeXBlLk5vZGVTZXQpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBJZiBvbmUgYXJnIGlzIGEgbm9kZS1zZXQgdGhlbiBtYWtlIGl0IHRoZSBsZWZ0IG9uZQotICAgICAgICAgICAgaWYgKHRsZWZ0LmlzU2ltcGxlKCkgfHwKLSAgICAgICAgICAgICAgICB0bGVmdCBpbnN0YW5jZW9mIFJlc3VsdFRyZWVUeXBlICYmCi0gICAgICAgICAgICAgICAgdHJpZ2h0IGluc3RhbmNlb2YgTm9kZVNldFR5cGUpIHsKLSAgICAgICAgICAgICAgICBzd2FwQXJndW1lbnRzKCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIFByb21vdGUgaW50ZWdlcnMgdG8gZG91YmxlcyB0byBoYXZlIGZld2VyIGNvbXBhcmVzCi0gICAgICAgICAgICBpZiAoX3JpZ2h0LmdldFR5cGUoKSBpbnN0YW5jZW9mIEludFR5cGUpIHsKLSAgICAgICAgICAgICAgICBfcmlnaHQgPSBuZXcgQ2FzdEV4cHIoX3JpZ2h0LCBUeXBlLlJlYWwpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBfdHlwZSA9IFR5cGUuQm9vbGVhbjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVEZXN5bnRoZXNpemVkKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotICAgICAgICBmaW5hbCBUeXBlIHRsZWZ0ID0gX2xlZnQuZ2V0VHlwZSgpOwotICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0KLSAgICAgICAgaWYgKHRsZWZ0IGluc3RhbmNlb2YgQm9vbGVhblR5cGUpIHsKLSAgICAgICAgICAgIF9sZWZ0LnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgICAgIF9yaWdodC50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgIF9mYWxzZUxpc3QuYWRkKGlsLmFwcGVuZChfb3AgPT0gT3BlcmF0b3JzLkVRID8KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoQnJhbmNoSW5zdHJ1Y3Rpb24pbmV3IElGX0lDTVBORShudWxsKSA6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKEJyYW5jaEluc3RydWN0aW9uKW5ldyBJRl9JQ01QRVEobnVsbCkpKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICh0bGVmdCBpbnN0YW5jZW9mIE51bWJlclR5cGUpIHsKLSAgICAgICAgICAgIF9sZWZ0LnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgICAgIF9yaWdodC50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0KLSAgICAgICAgICAgIGlmICh0bGVmdCBpbnN0YW5jZW9mIFJlYWxUeXBlKSB7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKERDTVBHKTsKLSAgICAgICAgX2ZhbHNlTGlzdC5hZGQoaWwuYXBwZW5kKF9vcCA9PSBPcGVyYXRvcnMuRVEgPwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoQnJhbmNoSW5zdHJ1Y3Rpb24pbmV3IElGTkUobnVsbCkgOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoQnJhbmNoSW5zdHJ1Y3Rpb24pbmV3IElGRVEobnVsbCkpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgX2ZhbHNlTGlzdC5hZGQoaWwuYXBwZW5kKF9vcCA9PSBPcGVyYXRvcnMuRVEgPwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoQnJhbmNoSW5zdHJ1Y3Rpb24pbmV3IElGX0lDTVBORShudWxsKSA6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChCcmFuY2hJbnN0cnVjdGlvbiluZXcgSUZfSUNNUEVRKG51bGwpKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICB0cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgICAgICBkZXN5bnRoZXNpemUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLSAgICAgICAgZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0KLSAgICAgICAgZmluYWwgVHlwZSB0bGVmdCA9IF9sZWZ0LmdldFR5cGUoKTsKLSAgICAgICAgVHlwZSB0cmlnaHQgPSBfcmlnaHQuZ2V0VHlwZSgpOwotCi0gICAgICAgIGlmICh0bGVmdCBpbnN0YW5jZW9mIEJvb2xlYW5UeXBlIHx8IHRsZWZ0IGluc3RhbmNlb2YgTnVtYmVyVHlwZSkgewotICAgICAgICAgICAgdHJhbnNsYXRlRGVzeW50aGVzaXplZChjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgICAgIHN5bnRoZXNpemUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAodGxlZnQgaW5zdGFuY2VvZiBTdHJpbmdUeXBlKSB7Ci0gICAgICAgICAgICBmaW5hbCBpbnQgZXF1YWxzID0gY3BnLmFkZE1ldGhvZHJlZihTVFJJTkdfQ0xBU1MsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZXF1YWxzIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoIiArIE9CSkVDVF9TSUcgKyIpWiIpOwotICAgICAgICAgICAgX2xlZnQudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICAgICAgX3JpZ2h0LnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChlcXVhbHMpKTsKLQotICAgICAgICBpZiAoX29wID09IE9wZXJhdG9ycy5ORSkgewotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChJQ09OU1RfMSk7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKElYT1IpOyAgICAgICAgICAgICAgICAgICAgICAgIC8vIG5vdCB4IDwtPiB4IHhvciAxCi0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLQotICAgICAgICBCcmFuY2hIYW5kbGUgdHJ1ZWMsIGZhbHNlYzsKLQotICAgICAgICBpZiAodGxlZnQgaW5zdGFuY2VvZiBSZXN1bHRUcmVlVHlwZSkgewotICAgICAgICAgICAgaWYgKHRyaWdodCBpbnN0YW5jZW9mIEJvb2xlYW5UeXBlKSB7Ci0gICAgICAgICAgICAgICAgX3JpZ2h0LnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgaWYgKF9vcCA9PSBPcGVyYXRvcnMuTkUpIHsKLSAgICAgICAgICAgICAgICAgICAgaWwuYXBwZW5kKElDT05TVF8xKTsKLSAgICAgICAgICAgICAgICAgICAgaWwuYXBwZW5kKElYT1IpOyAvLyBub3QgeCA8LT4geCB4b3IgMQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmICh0cmlnaHQgaW5zdGFuY2VvZiBSZWFsVHlwZSkgewotICAgICAgICAgICAgICAgIF9sZWZ0LnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgICAgICAgICB0bGVmdC50cmFuc2xhdGVUbyhjbGFzc0dlbiwgbWV0aG9kR2VuLCBUeXBlLlJlYWwpOwotICAgICAgICAgICAgICAgIF9yaWdodC50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0KLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQoRENNUEcpOwotICAgICAgICBmYWxzZWMgPSBpbC5hcHBlbmQoX29wID09IE9wZXJhdG9ycy5FUSA/Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChCcmFuY2hJbnN0cnVjdGlvbikgbmV3IElGTkUobnVsbCkgOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoQnJhbmNoSW5zdHJ1Y3Rpb24pIG5ldyBJRkVRKG51bGwpKTsKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQoSUNPTlNUXzEpOwotICAgICAgICAgICAgICAgIHRydWVjID0gaWwuYXBwZW5kKG5ldyBHT1RPKG51bGwpKTsKLSAgICAgICAgICAgICAgICBmYWxzZWMuc2V0VGFyZ2V0KGlsLmFwcGVuZChJQ09OU1RfMCkpOwotICAgICAgICAgICAgICAgIHRydWVjLnNldFRhcmdldChpbC5hcHBlbmQoTk9QKSk7Ci0gICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBOZXh0LCByZXN1bHQtdHJlZS9zdHJpbmcgYW5kIHJlc3VsdC10cmVlL3Jlc3VsdC10cmVlIGNvbXBhcmlzb25zCi0KLSAgICAgICAgICAgIF9sZWZ0LnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgICAgIHRsZWZ0LnRyYW5zbGF0ZVRvKGNsYXNzR2VuLCBtZXRob2RHZW4sIFR5cGUuU3RyaW5nKTsKLSAgICAgICAgICAgIF9yaWdodC50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0KLSAgICAgICAgICAgIGlmICh0cmlnaHQgaW5zdGFuY2VvZiBSZXN1bHRUcmVlVHlwZSkgewotICAgICAgICAgICAgICAgIHRyaWdodC50cmFuc2xhdGVUbyhjbGFzc0dlbiwgbWV0aG9kR2VuLCBUeXBlLlN0cmluZyk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGZpbmFsIGludCBlcXVhbHMgPSBjcGcuYWRkTWV0aG9kcmVmKFNUUklOR19DTEFTUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJlcXVhbHMiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIigiICtPQkpFQ1RfU0lHKyAiKVoiKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChlcXVhbHMpKTsKLQotICAgICAgICBpZiAoX29wID09IE9wZXJhdG9ycy5ORSkgewotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChJQ09OU1RfMSk7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKElYT1IpOyAgICAgICAgICAgICAgICAgICAgICAgIC8vIG5vdCB4IDwtPiB4IHhvciAxCi0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAodGxlZnQgaW5zdGFuY2VvZiBOb2RlU2V0VHlwZSAmJiB0cmlnaHQgaW5zdGFuY2VvZiBCb29sZWFuVHlwZSkgewotICAgICAgICAgICAgX2xlZnQudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICAgICAgX2xlZnQuc3RhcnRJdGVyYXRvcihjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgICAgIFR5cGUuTm9kZVNldC50cmFuc2xhdGVUbyhjbGFzc0dlbiwgbWV0aG9kR2VuLCBUeXBlLkJvb2xlYW4pOwotICAgICAgICAgICAgX3JpZ2h0LnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQotICAgICAgICAgICAgaWwuYXBwZW5kKElYT1IpOyAvLyB4ICE9IHkgPC0+IHggeG9yIHkKLSAgICAgICAgaWYgKF9vcCA9PSBPcGVyYXRvcnMuRVEpIHsKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQoSUNPTlNUXzEpOwotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChJWE9SKTsgLy8gbm90IHggPC0+IHggeG9yIDEKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotCi0gICAgICAgIGlmICh0bGVmdCBpbnN0YW5jZW9mIE5vZGVTZXRUeXBlICYmIHRyaWdodCBpbnN0YW5jZW9mIFN0cmluZ1R5cGUpIHsKLSAgICAgICAgICAgIF9sZWZ0LnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgICAgIF9sZWZ0LnN0YXJ0SXRlcmF0b3IoY2xhc3NHZW4sIG1ldGhvZEdlbik7IC8vIG5lZWRlZCA/Ci0gICAgICAgICAgICBfcmlnaHQudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgX29wKSk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0gICAgICAgICAgICBmaW5hbCBpbnQgY21wID0gY3BnLmFkZE1ldGhvZHJlZihCQVNJU19MSUJSQVJZX0NMQVNTLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImNvbXBhcmUiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIigiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIHRsZWZ0LnRvU2lnbmF0dXJlKCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgdHJpZ2h0LnRvU2lnbmF0dXJlKCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIkkiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIERPTV9JTlRGX1NJRwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiKVoiKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFU1RBVElDKGNtcCkpOwotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gTmV4dCwgbm9kZS1zZXQvdCBmb3IgdCBpbiB7cmVhbCwgc3RyaW5nLCBub2RlLXNldCwgcmVzdWx0LXRyZWV9Ci0gICAgICAgIF9sZWZ0LnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgX2xlZnQuc3RhcnRJdGVyYXRvcihjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgX3JpZ2h0LnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgX3JpZ2h0LnN0YXJ0SXRlcmF0b3IoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0KLSAgICAgICAgLy8gQ2FzdCBhIHJlc3VsdCB0cmVlIHRvIGEgc3RyaW5nIHRvIHVzZSBhbiBleGlzdGluZyBjb21wYXJlCi0gICAgICAgIGlmICh0cmlnaHQgaW5zdGFuY2VvZiBSZXN1bHRUcmVlVHlwZSkgewotICAgICAgICAgICAgdHJpZ2h0LnRyYW5zbGF0ZVRvKGNsYXNzR2VuLCBtZXRob2RHZW4sIFR5cGUuU3RyaW5nKTsKLSAgICAgICAgICAgIHRyaWdodCA9IFR5cGUuU3RyaW5nOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gQ2FsbCB0aGUgYXBwcm9wcmlhdGUgY29tcGFyZSgpIGZyb20gdGhlIEJhc2lzTGlicmFyeQotICAgICAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBfb3ApKTsKLSAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkRE9NKCkpOwotCi0gICAgICAgIGZpbmFsIGludCBjb21wYXJlID0gY3BnLmFkZE1ldGhvZHJlZihCQVNJU19MSUJSQVJZX0NMQVNTLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImNvbXBhcmUiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIigiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIHRsZWZ0LnRvU2lnbmF0dXJlKCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgdHJpZ2h0LnRvU2lnbmF0dXJlKCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIkkiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIERPTV9JTlRGX1NJRwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiKVoiKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VTVEFUSUMoY29tcGFyZSkpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvRXhwcmVzc2lvbi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9FeHByZXNzaW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDY0ZTQ0MGQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9FeHByZXNzaW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMjQgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRXhwcmVzc2lvbi5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzAxIDE0OjE3OjUxIHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkJyYW5jaEhhbmRsZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkNvbnN0YW50UG9vbEdlbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkdPVE9fVzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklGRVE7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JbnN0cnVjdGlvbkhhbmRsZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uTGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5Cb29sZWFuVHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5DbGFzc0dlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5FcnJvck1zZzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5NZXRob2RHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuTWV0aG9kVHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5Ob2RlU2V0VHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGVDaGVja0Vycm9yOwotCi0vKioKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICogQGF1dGhvciBFcndpbiBCb2x3aWR0IDxlamJAa2xvbXAub3JnPgotICovCi1hYnN0cmFjdCBjbGFzcyBFeHByZXNzaW9uIGV4dGVuZHMgU3ludGF4VHJlZU5vZGUgewotICAgIC8qKgotICAgICAqIFRoZSB0eXBlIG9mIHRoaXMgZXhwcmVzc2lvbi4gSXQgaXMgc2V0IGFmdGVyIGNhbGxpbmcKLSAgICAgKiA8Y29kZT50eXBlQ2hlY2soKTwvY29kZT4uCi0gICAgICovCi0gICAgcHJvdGVjdGVkIFR5cGUgX3R5cGU7Ci0KLSAgICAvKioKLSAgICAgKiBJbnN0cnVjdGlvbiBoYW5kbGVzIHRoYXQgY29tcHJpc2UgdGhlIHRydWUgbGlzdC4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgRmxvd0xpc3QgX3RydWVMaXN0ID0gbmV3IEZsb3dMaXN0KCk7Ci0KLSAgICAvKioKLSAgICAgKiBJbnN0cnVjdGlvbiBoYW5kbGVzIHRoYXQgY29tcHJpc2UgdGhlIGZhbHNlIGxpc3QuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIEZsb3dMaXN0IF9mYWxzZUxpc3QgPSBuZXcgRmxvd0xpc3QoKTsKLQotICAgIHB1YmxpYyBUeXBlIGdldFR5cGUoKSB7Ci0gICAgICAgIHJldHVybiBfdHlwZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nIHRvU3RyaW5nKCk7Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBoYXNQb3NpdGlvbkNhbGwoKSB7Ci0gICAgICAgIHJldHVybiBmYWxzZTsgICAgICAgICAgIC8vIGRlZmF1bHQgc2hvdWxkIGJlICdmYWxzZScgZm9yIFN0ZXBQYXR0ZXJuCi0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gaGFzTGFzdENhbGwoKSB7Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGFuIG9iamVjdCByZXByZXNlbnRpbmcgdGhlIGNvbXBpbGUtdGltZSBldmFsdWF0aW9uCi0gICAgICogb2YgYW4gZXhwcmVzc2lvbi4gV2UgYXJlIG9ubHkgdXNpbmcgdGhpcyBmb3IgZnVuY3Rpb24tYXZhaWxhYmxlCi0gICAgICogYW5kIGVsZW1lbnQtYXZhaWxhYmxlIGF0IHRoaXMgdGltZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0IGV2YWx1YXRlQXRDb21waWxlVGltZSgpIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHlwZSBjaGVjayBhbGwgdGhlIGNoaWxkcmVuIG9mIHRoaXMgbm9kZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgVHlwZSB0eXBlQ2hlY2soU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgewotICAgICAgICByZXR1cm4gdHlwZUNoZWNrQ29udGVudHMoc3RhYmxlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGUgdGhpcyBub2RlIGludG8gSlZNIGJ5dGVjb2Rlcy4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLSAgICAgICAgRXJyb3JNc2cgbXNnID0gbmV3IEVycm9yTXNnKEVycm9yTXNnLk5PVF9JTVBMRU1FTlRFRF9FUlIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRDbGFzcygpLCB0aGlzKTsKLSAgICAgICAgZ2V0UGFyc2VyKCkucmVwb3J0RXJyb3IoRkFUQUwsIG1zZyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhbnNsYXRlIHRoaXMgbm9kZSBpbnRvIGEgZnJlc2ggaW5zdHJ1Y3Rpb24gbGlzdC4KLSAgICAgKiBUaGUgb3JpZ2luYWwgaW5zdHJ1Y3Rpb24gbGlzdCBpcyBzYXZlZCBhbmQgcmVzdG9yZWQuCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIEluc3RydWN0aW9uTGlzdCBjb21waWxlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCByZXN1bHQsIHNhdmUgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0gICAgICAgIG1ldGhvZEdlbi5zZXRJbnN0cnVjdGlvbkxpc3QocmVzdWx0ID0gbmV3IEluc3RydWN0aW9uTGlzdCgpKTsKLSAgICAgICAgdHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICBtZXRob2RHZW4uc2V0SW5zdHJ1Y3Rpb25MaXN0KHNhdmUpOwotICAgICAgICByZXR1cm4gcmVzdWx0OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJlZGVmaW5lZCBieSBleHByZXNzaW9ucyBvZiB0eXBlIGJvb2xlYW4gdGhhdCB1c2UgZmxvdyBsaXN0cy4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVEZXN5bnRoZXNpemVkKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotICAgICAgICB0cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgIGlmIChfdHlwZSBpbnN0YW5jZW9mIEJvb2xlYW5UeXBlKSB7Ci0gICAgICAgICAgICBkZXN5bnRoZXNpemUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJZiB0aGlzIGV4cHJlc3Npb24gaXMgb2YgdHlwZSBub2RlLXNldCBhbmQgaXQgaXMgbm90IGEgdmFyaWFibGUKLSAgICAgKiByZWZlcmVuY2UsIHRoZW4gY2FsbCBzZXRTdGFydE5vZGUoKSBwYXNzaW5nIHRoZSBjb250ZXh0IG5vZGUuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnRJdGVyYXRvcihDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotICAgICAgICAvLyBJZ25vcmUgaWYgdHlwZSBpcyBub3Qgbm9kZS1zZXQKLSAgICAgICAgaWYgKF90eXBlIGluc3RhbmNlb2YgTm9kZVNldFR5cGUgPT0gZmFsc2UpIHsKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIHNldFN0YXJ0Tm9kZSgpIHNob3VsZCBub3QgYmUgY2FsbGVkIGlmIGV4cHIgaXMgYSB2YXJpYWJsZSByZWYKLSAgICAgICAgRXhwcmVzc2lvbiBleHByID0gdGhpczsKLSAgICAgICAgaWYgKGV4cHIgaW5zdGFuY2VvZiBDYXN0RXhwcikgewotICAgICAgICAgICAgZXhwciA9ICgoQ2FzdEV4cHIpIGV4cHIpLmdldEV4cHIoKTsKLSAgICAgICAgfQotICAgICAgICBpZiAoZXhwciBpbnN0YW5jZW9mIFZhcmlhYmxlUmVmQmFzZSA9PSBmYWxzZSkgewotICAgICAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkQ29udGV4dE5vZGUoKSk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLnNldFN0YXJ0Tm9kZSgpKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFN5bnRoZXNpemUgYSBib29sZWFuIGV4cHJlc3Npb24sIGkuZS4sIGVpdGhlciBwdXNoIGEgMCBvciAxIG9udG8gdGhlCi0gICAgICogb3BlcmFuZCBzdGFjayBmb3IgdGhlIG5leHQgc3RhdGVtZW50IHRvIHN1Y2NlZWQuIFJldHVybnMgdGhlIGhhbmRsZQotICAgICAqIG9mIHRoZSBpbnN0cnVjdGlvbiB0byBiZSBiYWNrcGF0Y2hlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzeW50aGVzaXplKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0gICAgICAgIGZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotICAgICAgICBfdHJ1ZUxpc3QuYmFja1BhdGNoKGlsLmFwcGVuZChJQ09OU1RfMSkpOwotICAgICAgICBmaW5hbCBCcmFuY2hIYW5kbGUgdHJ1ZWMgPSBpbC5hcHBlbmQobmV3IEdPVE9fVyhudWxsKSk7Ci0gICAgICAgIF9mYWxzZUxpc3QuYmFja1BhdGNoKGlsLmFwcGVuZChJQ09OU1RfMCkpOwotICAgICAgICB0cnVlYy5zZXRUYXJnZXQoaWwuYXBwZW5kKE5PUCkpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGRlc3ludGhlc2l6ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0gICAgICAgIF9mYWxzZUxpc3QuYWRkKGlsLmFwcGVuZChuZXcgSUZFUShudWxsKSkpOwotICAgIH0KLQotICAgIHB1YmxpYyBGbG93TGlzdCBnZXRGYWxzZUxpc3QoKSB7Ci0gICAgICAgIHJldHVybiBfZmFsc2VMaXN0OwotICAgIH0KLQotICAgIHB1YmxpYyBGbG93TGlzdCBnZXRUcnVlTGlzdCgpIHsKLSAgICAgICAgcmV0dXJuIF90cnVlTGlzdDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBiYWNrUGF0Y2hGYWxzZUxpc3QoSW5zdHJ1Y3Rpb25IYW5kbGUgaWgpIHsKLSAgICAgICAgX2ZhbHNlTGlzdC5iYWNrUGF0Y2goaWgpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGJhY2tQYXRjaFRydWVMaXN0KEluc3RydWN0aW9uSGFuZGxlIGloKSB7Ci0gICAgICAgIF90cnVlTGlzdC5iYWNrUGF0Y2goaWgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNlYXJjaCBmb3IgYSBwcmltb3AgaW4gdGhlIHN5bWJvbCB0YWJsZSB0aGF0IG1hdGNoZXMgdGhlIG1ldGhvZCB0eXBlCi0gICAgICogPGNvZGU+Y3R5cGU8L2NvZGU+LiBUd28gbWV0aG9kcyBtYXRjaCBpZiB0aGV5IGhhdmUgdGhlIHNhbWUgYXJpdHkuCi0gICAgICogSWYgYSBwcmltb3AgaXMgb3ZlcmxvYWRlZCB0aGVuIHRoZSAiY2xvc2VzdCBtYXRjaCIgaXMgcmV0dXJuZWQuIFRoZQotICAgICAqIGZpcnN0IGVudHJ5IGluIHRoZSB2ZWN0b3Igb2YgcHJpbW9wcyB0aGF0IGhhcyB0aGUgcmlnaHQgYXJpdHkgaXMKLSAgICAgKiBjb25zaWRlcmVkIHRvIGJlIHRoZSBkZWZhdWx0IG9uZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgTWV0aG9kVHlwZSBsb29rdXBQcmltb3AoU3ltYm9sVGFibGUgc3RhYmxlLCBTdHJpbmcgb3AsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1ldGhvZFR5cGUgY3R5cGUpIHsKLSAgICAgICAgTWV0aG9kVHlwZSByZXN1bHQgPSBudWxsOwotICAgICAgICBmaW5hbCBWZWN0b3IgcHJpbW9wID0gc3RhYmxlLmxvb2t1cFByaW1vcChvcCk7Ci0gICAgICAgIGlmIChwcmltb3AgIT0gbnVsbCkgewotICAgICAgICAgICAgZmluYWwgaW50IG4gPSBwcmltb3Auc2l6ZSgpOwotICAgICAgICAgICAgaW50IG1pbkRpc3RhbmNlID0gSW50ZWdlci5NQVhfVkFMVUU7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykgewotICAgICAgICAgICAgICAgIGZpbmFsIE1ldGhvZFR5cGUgcHR5cGUgPSAoTWV0aG9kVHlwZSkgcHJpbW9wLmVsZW1lbnRBdChpKTsKLSAgICAgICAgICAgICAgICAvLyBTa2lwIGlmIGRpZmZlcmVudCBhcml0eQotICAgICAgICAgICAgICAgIGlmIChwdHlwZS5hcmdzQ291bnQoKSAhPSBjdHlwZS5hcmdzQ291bnQoKSkgewotICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyBUaGUgZmlyc3QgbWV0aG9kIHdpdGggdGhlIHJpZ2h0IGFyaXR5IGlzIHRoZSBkZWZhdWx0Ci0gICAgICAgICAgICAgICAgaWYgKHJlc3VsdCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IHB0eXBlOyAgICAgICAgICAgICAvLyBkZWZhdWx0IG1ldGhvZAotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIGJldHRlciB0aGFuIGxhc3Qgb25lIGZvdW5kCi0gICAgICAgICAgICAgICAgZmluYWwgaW50IGRpc3RhbmNlID0gY3R5cGUuZGlzdGFuY2VUbyhwdHlwZSk7Ci0gICAgICAgICAgICAgICAgaWYgKGRpc3RhbmNlIDwgbWluRGlzdGFuY2UpIHsKLSAgICAgICAgICAgICAgICAgICAgbWluRGlzdGFuY2UgPSBkaXN0YW5jZTsKLSAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gcHR5cGU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiByZXN1bHQ7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9GYWxsYmFjay5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9GYWxsYmFjay5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkMDRlYjlhLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvRmFsbGJhY2suamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDgxICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IEZhbGxiYWNrLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMDEgMTQ6MjI6MjUgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5Db25zdGFudFBvb2xHZW47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JbnN0cnVjdGlvbkxpc3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuQ2xhc3NHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuTWV0aG9kR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZUNoZWNrRXJyb3I7Ci0KLS8qKgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKi8KLWZpbmFsIGNsYXNzIEZhbGxiYWNrIGV4dGVuZHMgSW5zdHJ1Y3Rpb24gewotCi0gICAgcHJpdmF0ZSBib29sZWFuIF9hY3RpdmUgPSBmYWxzZTsKLQotICAgIC8qKgotICAgICAqIFRoaXMgZWxlbWVudCBuZXZlciBwcm9kdWNlcyBhbnkgZGF0YSBvbiB0aGUgc3RhY2sKLSAgICAgKi8KLSAgICBwdWJsaWMgVHlwZSB0eXBlQ2hlY2soU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgewotICAgICAgICBpZiAoX2FjdGl2ZSkgewotICAgICAgICAgICAgcmV0dXJuKHR5cGVDaGVja0NvbnRlbnRzKHN0YWJsZSkpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIFR5cGUuVm9pZDsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEFjdGl2YXRlIHRoaXMgZmFsbGJhY2sgZWxlbWVudAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGFjdGl2YXRlKCkgewotICAgICAgICBfYWN0aXZlID0gdHJ1ZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgICAgICByZXR1cm4oImZhbGxiYWNrIik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUGFyc2UgY29udGVudHMgb25seSBpZiB0aGlzIGZhbGxiYWNrIGVsZW1lbnQgaXMgcHV0IGluIHBsYWNlIG9mCi0gICAgICogc29tZSB1bnN1cHBvcnRlZCBlbGVtZW50IG9yIG5vbi1YU0xUQyBleHRlbnNpb24gZWxlbWVudAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHBhcnNlQ29udGVudHMoUGFyc2VyIHBhcnNlcikgewotICAgICAgICBpZiAoX2FjdGl2ZSkgcGFyc2VDaGlsZHJlbihwYXJzZXIpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZSBjb250ZW50cyBvbmx5IGlmIHRoaXMgZmFsbGJhY2sgZWxlbWVudCBpcyBwdXQgaW4gcGxhY2Ugb2YKLSAgICAgKiBzb21lIHVuc3VwcG9ydGVkIGVsZW1lbnQgb3Igbm9uLVhTTFRDIGV4dGVuc2lvbiBlbGVtZW50Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0gICAgICAgIGZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCi0gICAgICAgIGlmIChfYWN0aXZlKSB0cmFuc2xhdGVDb250ZW50cyhjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0ZpbHRlckV4cHIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvRmlsdGVyRXhwci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjNDg0MjgzLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvRmlsdGVyRXhwci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjU0ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IEZpbHRlckV4cHIuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xMiAxMDoyMjo1MCBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5BTE9BRDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkFTVE9SRTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkNvbnN0YW50UG9vbEdlbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklMT0FEOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFSU5URVJGQUNFOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFU1BFQ0lBTDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklOVk9LRVNUQVRJQzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uTGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklTVE9SRTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkxvY2FsVmFyaWFibGVHZW47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5ORVc7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuQ2xhc3NHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuTWV0aG9kR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLk5vZGVTZXRUeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlJlZmVyZW5jZVR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlQ2hlY2tFcnJvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5VdGlsOwotCi0vKioKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICovCi1jbGFzcyBGaWx0ZXJFeHByIGV4dGVuZHMgRXhwcmVzc2lvbiB7Ci0KLSAgICAvKioKLSAgICAgKiBQcmltYXJ5IGV4cHJlc3Npb24gb2YgdGhpcyBmaWx0ZXIuIEkuZS4sICdlJyBpbiAnKGUpW3AxXS4uLltwbl0nLgotICAgICAqLwotICAgIHByaXZhdGUgRXhwcmVzc2lvbiAgIF9wcmltYXJ5OwotCi0gICAgLyoqCi0gICAgICogQXJyYXkgb2YgcHJlZGljYXRlcyBpbiAnKGUpW3AxXS4uLltwbl0nLgotICAgICAqLwotICAgIHByaXZhdGUgZmluYWwgVmVjdG9yIF9wcmVkaWNhdGVzOwotCi0gICAgcHVibGljIEZpbHRlckV4cHIoRXhwcmVzc2lvbiBwcmltYXJ5LCBWZWN0b3IgcHJlZGljYXRlcykgewotICAgICAgICBfcHJpbWFyeSA9IHByaW1hcnk7Ci0gICAgICAgIF9wcmVkaWNhdGVzID0gcHJlZGljYXRlczsKLSAgICAgICAgcHJpbWFyeS5zZXRQYXJlbnQodGhpcyk7Ci0gICAgfQotCi0gICAgcHJvdGVjdGVkIEV4cHJlc3Npb24gZ2V0RXhwcigpIHsKLSAgICAgICAgaWYgKF9wcmltYXJ5IGluc3RhbmNlb2YgQ2FzdEV4cHIpCi0gICAgICAgICAgICByZXR1cm4gKChDYXN0RXhwcilfcHJpbWFyeSkuZ2V0RXhwcigpOwotICAgICAgICBlbHNlCi0gICAgICAgICAgICByZXR1cm4gX3ByaW1hcnk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0UGFyc2VyKFBhcnNlciBwYXJzZXIpIHsKLSAgICAgICAgc3VwZXIuc2V0UGFyc2VyKHBhcnNlcik7Ci0gICAgICAgIF9wcmltYXJ5LnNldFBhcnNlcihwYXJzZXIpOwotICAgICAgICBpZiAoX3ByZWRpY2F0ZXMgIT0gbnVsbCkgewotICAgICAgICAgICAgZmluYWwgaW50IG4gPSBfcHJlZGljYXRlcy5zaXplKCk7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykgewotICAgICAgICAgICAgICAgIGZpbmFsIEV4cHJlc3Npb24gZXhwID0gKEV4cHJlc3Npb24pX3ByZWRpY2F0ZXMuZWxlbWVudEF0KGkpOwotICAgICAgICAgICAgICAgIGV4cC5zZXRQYXJzZXIocGFyc2VyKTsKLSAgICAgICAgICAgICAgICBleHAuc2V0UGFyZW50KHRoaXMpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKLSAgICAgICAgcmV0dXJuICJmaWx0ZXItZXhwcigiICsgX3ByaW1hcnkgKyAiLCAiICsgX3ByZWRpY2F0ZXMgKyAiKSI7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHlwZSBjaGVjayBhIEZpbHRlclBhcmVudFBhdGguIElmIHRoZSBmaWx0ZXIgaXMgbm90IGEgbm9kZS1zZXQgYWRkIGEKLSAgICAgKiBjYXN0IHRvIG5vZGUtc2V0IG9ubHkgaWYgaXQgaXMgb2YgcmVmZXJlbmNlIHR5cGUuIFRoaXMgdHlwZSBjb2VyY2lvbgotICAgICAqIGlzIG5lZWRlZCBmb3IgZXhwcmVzc2lvbnMgbGlrZSAkeCB3aGVyZSAkeCBpcyBhIHBhcmFtZXRlciByZWZlcmVuY2UuCi0gICAgICogQWxsIG9wdGltaXphdGlvbnMgYXJlIHR1cm5lZCBvZmYgYmVmb3JlIHR5cGUgY2hlY2tpbmcgdW5kZXJseWluZwotICAgICAqIHByZWRpY2F0ZXMuCi0gICAgICovCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLSAgICAgICAgVHlwZSBwdHlwZSA9IF9wcmltYXJ5LnR5cGVDaGVjayhzdGFibGUpOwotICAgICAgICBib29sZWFuIGNhbk9wdGltaXplID0gX3ByaW1hcnkgaW5zdGFuY2VvZiBLZXlDYWxsOwotCi0gICAgICAgIGlmIChwdHlwZSBpbnN0YW5jZW9mIE5vZGVTZXRUeXBlID09IGZhbHNlKSB7Ci0gICAgICAgICAgICBpZiAocHR5cGUgaW5zdGFuY2VvZiBSZWZlcmVuY2VUeXBlKSAgewotICAgICAgICAgICAgICAgIF9wcmltYXJ5ID0gbmV3IENhc3RFeHByKF9wcmltYXJ5LCBUeXBlLk5vZGVTZXQpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVDaGVja0Vycm9yKHRoaXMpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gVHlwZSBjaGVjayBwcmVkaWNhdGVzIGFuZCB0dXJuIGFsbCBvcHRpbWl6YXRpb25zIG9mZiBpZiBhcHByb3ByaWF0ZQotICAgICAgICBpbnQgbiA9IF9wcmVkaWNhdGVzLnNpemUoKTsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspIHsKLSAgICAgICAgICAgIFByZWRpY2F0ZSBwcmVkID0gKFByZWRpY2F0ZSkgX3ByZWRpY2F0ZXMuZWxlbWVudEF0KGkpOwotCi0gICAgICAgICAgICBpZiAoIWNhbk9wdGltaXplKSB7Ci0gICAgICAgICAgICAgICAgcHJlZC5kb250T3B0aW1pemUoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHByZWQudHlwZUNoZWNrKHN0YWJsZSk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIF90eXBlID0gVHlwZS5Ob2RlU2V0OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZSBhIGZpbHRlciBleHByZXNzaW9uIGJ5IHB1c2hpbmcgdGhlIGFwcHJvcHJpYXRlIGl0ZXJhdG9yCi0gICAgICogb250byB0aGUgc3RhY2suCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0gICAgICAgIHRyYW5zbGF0ZUZpbHRlckV4cHIoY2xhc3NHZW4sIG1ldGhvZEdlbiwgX3ByZWRpY2F0ZXMgPT0gbnVsbCA/IC0xIDogX3ByZWRpY2F0ZXMuc2l6ZSgpIC0gMSk7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIHRyYW5zbGF0ZUZpbHRlckV4cHIoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgcHJlZGljYXRlSW5kZXgpIHsKLSAgICAgICAgaWYgKHByZWRpY2F0ZUluZGV4ID49IDApIHsKLSAgICAgICAgICAgIHRyYW5zbGF0ZVByZWRpY2F0ZXMoY2xhc3NHZW4sIG1ldGhvZEdlbiwgcHJlZGljYXRlSW5kZXgpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgX3ByaW1hcnkudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhbnNsYXRlIGEgc2VxdWVuY2Ugb2YgcHJlZGljYXRlcy4gRWFjaCBwcmVkaWNhdGUgaXMgdHJhbnNsYXRlZAotICAgICAqIGJ5IGNvbnN0cnVjdGluZyBhbiBpbnN0YW5jZSBvZiA8Y29kZT5DdXJyZW50Tm9kZUxpc3RJdGVyYXRvcjwvY29kZT4KLSAgICAgKiB3aGljaCBpcyBpbml0aWFsaXplZCBmcm9tIGFub3RoZXIgaXRlcmF0b3IgKHJlY3Vyc2l2ZSBjYWxsKSwgYQotICAgICAqIGZpbHRlciBhbmQgYSBjbG9zdXJlIChjYWxsIHRvIHRyYW5zbGF0ZSBvbiB0aGUgcHJlZGljYXRlKSBhbmQgInRoaXMiLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZVByZWRpY2F0ZXMoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHByZWRpY2F0ZUluZGV4KSB7Ci0gICAgICAgIGZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCi0gICAgICAgIC8vIElmIG5vdCBwcmVkaWNhdGVzIGxlZnQsIHRyYW5zbGF0ZSBwcmltYXJ5IGV4cHJlc3Npb24KLSAgICAgICAgaWYgKHByZWRpY2F0ZUluZGV4IDwgMCkgewotICAgICAgICAgICAgdHJhbnNsYXRlRmlsdGVyRXhwcihjbGFzc0dlbiwgbWV0aG9kR2VuLCBwcmVkaWNhdGVJbmRleCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAvLyBHZXQgdGhlIG5leHQgcHJlZGljYXRlIHRvIGJlIHRyYW5zbGF0ZWQKLSAgICAgICAgICAgIFByZWRpY2F0ZSBwcmVkaWNhdGUgPSAoUHJlZGljYXRlKSBfcHJlZGljYXRlcy5nZXQocHJlZGljYXRlSW5kZXgtLSk7Ci0KLSAgICAgICAgICAgIC8vIFRyYW5zbGF0ZSB0aGUgcmVzdCBvZiB0aGUgcHJlZGljYXRlcyBmcm9tIHJpZ2h0IHRvIGxlZnQKLSAgICAgICAgICAgIHRyYW5zbGF0ZVByZWRpY2F0ZXMoY2xhc3NHZW4sIG1ldGhvZEdlbiwgcHJlZGljYXRlSW5kZXgpOwotCi0gICAgICAgICAgICBpZiAocHJlZGljYXRlLmlzTnRoUG9zaXRpb25GaWx0ZXIoKSkgewotICAgICAgICAgICAgICAgIGludCBudGhJdGVyYXRvcklkeCA9IGNwZy5hZGRNZXRob2RyZWYoTlRIX0lURVJBVE9SX0NMQVNTLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjxpbml0PiIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKCIrTk9ERV9JVEVSQVRPUl9TSUcrIkkpViIpOwotCi0gICAgICAgICAgICAgICAgLy8gQmFja3dhcmRzIGJyYW5jaGVzIGFyZSBwcm9oaWJpdGVkIGlmIGFuIHVuaW5pdGlhbGl6ZWQgb2JqZWN0Ci0gICAgICAgICAgICAgICAgLy8gaXMgb24gdGhlIHN0YWNrIGJ5IHNlY3Rpb24gNC45LjQgb2YgdGhlIEpWTSBTcGVjaWZpY2F0aW9uLAotICAgICAgICAgICAgICAgIC8vIDJuZCBFZC4gIFdlIGRvbid0IGtub3cgd2hldGhlciB0aGlzIGNvZGUgbWlnaHQgY29udGFpbgotICAgICAgICAgICAgICAgIC8vIGJhY2t3YXJkcyBicmFuY2hlcywgc28gd2UgbXVzdG4ndCBjcmVhdGUgdGhlIG5ldyBvYmplY3QgdW50aQotCi0gICAgICAgICAgICAgICAgLy8gYWZ0ZXIgd2UndmUgY3JlYXRlZCB0aGUgc3VzcGVjdCBhcmd1bWVudHMgdG8gaXRzIGNvbnN0cnVjdG9yCi0KLSAgICAgICAgICAgICAgICAvLyBJbnN0ZWFkIHdlIGNhbGN1bGF0ZSB0aGUgdmFsdWVzIG9mIHRoZSBhcmd1bWVudHMgdG8gdGhlCi0gICAgICAgICAgICAgICAgLy8gY29uc3RydWN0b3IgZmlyc3QsIHN0b3JlIHRoZW0gaW4gdGVtcG9yYXJ5IHZhcmlhYmxlcywgY3JlYXRlCi0gICAgICAgICAgICAgICAgLy8gdGhlIG9iamVjdCBhbmQgcmVsb2FkIHRoZSBhcmd1bWVudHMgZnJvbSB0aGUgdGVtcG9yYXJpZXMgdG8KLSAgICAgICAgICAgICAgICAvLyBhdm9pZCB0aGUgcHJvYmxlbS4KLSAgICAgICAgICAgICAgICBMb2NhbFZhcmlhYmxlR2VuIGl0ZXJhdG9yVGVtcAotICAgICAgICAgICAgICAgICAgICAgICAgPSBtZXRob2RHZW4uYWRkTG9jYWxWYXJpYWJsZSgiZmlsdGVyX2V4cHJfdG1wMSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFV0aWwuZ2V0SkNSZWZUeXBlKE5PREVfSVRFUkFUT1JfU0lHKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgaXRlcmF0b3JUZW1wLnNldFN0YXJ0KAotICAgICAgICAgICAgICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBBU1RPUkUoaXRlcmF0b3JUZW1wLmdldEluZGV4KCkpKSk7Ci0KLSAgICAgICAgICAgICAgICBwcmVkaWNhdGUudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICAgICAgICAgIExvY2FsVmFyaWFibGVHZW4gcHJlZGljYXRlVmFsdWVUZW1wCi0gICAgICAgICAgICAgICAgICAgICAgICA9IG1ldGhvZEdlbi5hZGRMb2NhbFZhcmlhYmxlKCJmaWx0ZXJfZXhwcl90bXAyIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVXRpbC5nZXRKQ1JlZlR5cGUoIkkiKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgcHJlZGljYXRlVmFsdWVUZW1wLnNldFN0YXJ0KAotICAgICAgICAgICAgICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJU1RPUkUocHJlZGljYXRlVmFsdWVUZW1wLmdldEluZGV4KCkpKSk7Ci0KLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQobmV3IE5FVyhjcGcuYWRkQ2xhc3MoTlRIX0lURVJBVE9SX0NMQVNTKSkpOwotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChEVVApOwotICAgICAgICAgICAgICAgIGl0ZXJhdG9yVGVtcC5zZXRFbmQoCi0gICAgICAgICAgICAgICAgICAgICAgICBpbC5hcHBlbmQobmV3IEFMT0FEKGl0ZXJhdG9yVGVtcC5nZXRJbmRleCgpKSkpOwotICAgICAgICAgICAgICAgIHByZWRpY2F0ZVZhbHVlVGVtcC5zZXRFbmQoCi0gICAgICAgICAgICAgICAgICAgICAgICBpbC5hcHBlbmQobmV3IElMT0FEKHByZWRpY2F0ZVZhbHVlVGVtcC5nZXRJbmRleCgpKSkpOwotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFU1BFQ0lBTChudGhJdGVyYXRvcklkeCkpOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gVHJhbnNsYXRlIHByZWRpY2F0ZXMgZnJvbSByaWdodCB0byBsZWZ0Ci0gICAgICAgICAgICAgICAgZmluYWwgaW50IGluaXRDTkxJID0gY3BnLmFkZE1ldGhvZHJlZihDVVJSRU5UX05PREVfTElTVF9JVEVSQVRPUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI8aW5pdD4iLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIigiK05PREVfSVRFUkFUT1JfU0lHKyJaIisKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENVUlJFTlRfTk9ERV9MSVNUX0ZJTFRFUl9TSUcgKwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTk9ERV9TSUcrVFJBTlNMRVRfU0lHKyIpViIpOwotCi0gICAgICAgICAgICAgICAgLy8gQmFja3dhcmRzIGJyYW5jaGVzIGFyZSBwcm9oaWJpdGVkIGlmIGFuIHVuaW5pdGlhbGl6ZWQgb2JqZWN0IGlzCi0gICAgICAgICAgICAgICAgLy8gb24gdGhlIHN0YWNrIGJ5IHNlY3Rpb24gNC45LjQgb2YgdGhlIEpWTSBTcGVjaWZpY2F0aW9uLCAybmQgRWQuCi0gICAgICAgICAgICAgICAgLy8gV2UgZG9uJ3Qga25vdyB3aGV0aGVyIHRoaXMgY29kZSBtaWdodCBjb250YWluIGJhY2t3YXJkcyBicmFuY2hlcywKLSAgICAgICAgICAgICAgICAvLyBzbyB3ZSBtdXN0bid0IGNyZWF0ZSB0aGUgbmV3IG9iamVjdCB1bnRpbCBhZnRlciB3ZSd2ZSBjcmVhdGVkCi0gICAgICAgICAgICAgICAgLy8gdGhlIHN1c3BlY3QgYXJndW1lbnRzIHRvIGl0cyBjb25zdHJ1Y3Rvci4gIEluc3RlYWQgd2UgY2FsY3VsYXRlCi0gICAgICAgICAgICAgICAgLy8gdGhlIHZhbHVlcyBvZiB0aGUgYXJndW1lbnRzIHRvIHRoZSBjb25zdHJ1Y3RvciBmaXJzdCwgc3RvcmUgdGhlbQotICAgICAgICAgICAgICAgIC8vIGluIHRlbXBvcmFyeSB2YXJpYWJsZXMsIGNyZWF0ZSB0aGUgb2JqZWN0IGFuZCByZWxvYWQgdGhlCi0gICAgICAgICAgICAgICAgLy8gYXJndW1lbnRzIGZyb20gdGhlIHRlbXBvcmFyaWVzIHRvIGF2b2lkIHRoZSBwcm9ibGVtLgotCi0KLSAgICAgICAgICAgICAgICBMb2NhbFZhcmlhYmxlR2VuIG5vZGVJdGVyYXRvclRlbXAgPQotICAgICAgICAgICAgICAgICAgICBtZXRob2RHZW4uYWRkTG9jYWxWYXJpYWJsZSgiZmlsdGVyX2V4cHJfdG1wMSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFV0aWwuZ2V0SkNSZWZUeXBlKE5PREVfSVRFUkFUT1JfU0lHKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgbm9kZUl0ZXJhdG9yVGVtcC5zZXRTdGFydCgKLSAgICAgICAgICAgICAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgQVNUT1JFKG5vZGVJdGVyYXRvclRlbXAuZ2V0SW5kZXgoKSkpKTsKLQotICAgICAgICAgICAgICAgIHByZWRpY2F0ZS50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgICAgICAgICAgTG9jYWxWYXJpYWJsZUdlbiBmaWx0ZXJUZW1wID0KLSAgICAgICAgICAgICAgICAgICAgbWV0aG9kR2VuLmFkZExvY2FsVmFyaWFibGUoImZpbHRlcl9leHByX3RtcDIiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFV0aWwuZ2V0SkNSZWZUeXBlKENVUlJFTlRfTk9ERV9MSVNUX0ZJTFRFUl9TSUcpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsIG51bGwpOwotICAgICAgICAgICAgICAgIGZpbHRlclRlbXAuc2V0U3RhcnQoaWwuYXBwZW5kKG5ldyBBU1RPUkUoZmlsdGVyVGVtcC5nZXRJbmRleCgpKSkpOwotCi0gICAgICAgICAgICAgICAgLy8gQ3JlYXRlIGEgQ3VycmVudE5vZGVMaXN0SXRlcmF0b3IKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQobmV3IE5FVyhjcGcuYWRkQ2xhc3MoQ1VSUkVOVF9OT0RFX0xJU1RfSVRFUkFUT1IpKSk7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKERVUCk7Ci0KLSAgICAgICAgICAgICAgICAvLyBJbml0aWFsaXplIEN1cnJlbnROb2RlTGlzdEl0ZXJhdG9yCi0gICAgICAgICAgICAgICAgbm9kZUl0ZXJhdG9yVGVtcC5zZXRFbmQoCi0gICAgICAgICAgICAgICAgICAgICAgICBpbC5hcHBlbmQobmV3IEFMT0FEKG5vZGVJdGVyYXRvclRlbXAuZ2V0SW5kZXgoKSkpKTsKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQoSUNPTlNUXzEpOwotICAgICAgICAgICAgICAgIGZpbHRlclRlbXAuc2V0RW5kKGlsLmFwcGVuZChuZXcgQUxPQUQoZmlsdGVyVGVtcC5nZXRJbmRleCgpKSkpOwotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZEN1cnJlbnROb2RlKCkpOwotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChjbGFzc0dlbi5sb2FkVHJhbnNsZXQoKSk7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VTUEVDSUFMKGluaXRDTkxJKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0ZpbHRlclBhcmVudFBhdGguamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvRmlsdGVyUGFyZW50UGF0aC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyZDNiNzVkLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvRmlsdGVyUGFyZW50UGF0aC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTc2ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IEZpbHRlclBhcmVudFBhdGguamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xMiAxMDoyNDo1NSBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkFMT0FEOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQVNUT1JFOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQ29uc3RhbnRQb29sR2VuOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFSU5URVJGQUNFOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFU1BFQ0lBTDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklOVk9LRVZJUlRVQUw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JbnN0cnVjdGlvbkxpc3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5Mb2NhbFZhcmlhYmxlR2VuOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuTkVXOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkNsYXNzR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLk1ldGhvZEdlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5Ob2RlU2V0VHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5Ob2RlVHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5SZWZlcmVuY2VUeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZUNoZWNrRXJyb3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVXRpbDsKLQotLyoqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKi8KLWZpbmFsIGNsYXNzIEZpbHRlclBhcmVudFBhdGggZXh0ZW5kcyBFeHByZXNzaW9uIHsKLQotICAgIHByaXZhdGUgRXhwcmVzc2lvbiBfZmlsdGVyRXhwcjsKLSAgICBwcml2YXRlIEV4cHJlc3Npb24gX3BhdGg7Ci0gICAgcHJpdmF0ZSBib29sZWFuIF9oYXNEZXNjZW5kYW50QXhpcyA9IGZhbHNlOwotCi0gICAgcHVibGljIEZpbHRlclBhcmVudFBhdGgoRXhwcmVzc2lvbiBmaWx0ZXJFeHByLCBFeHByZXNzaW9uIHBhdGgpIHsKLSAgICAgICAgKF9wYXRoID0gcGF0aCkuc2V0UGFyZW50KHRoaXMpOwotICAgICAgICAoX2ZpbHRlckV4cHIgPSBmaWx0ZXJFeHByKS5zZXRQYXJlbnQodGhpcyk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0UGFyc2VyKFBhcnNlciBwYXJzZXIpIHsKLSAgICAgICAgc3VwZXIuc2V0UGFyc2VyKHBhcnNlcik7Ci0gICAgICAgIF9maWx0ZXJFeHByLnNldFBhcnNlcihwYXJzZXIpOwotICAgICAgICBfcGF0aC5zZXRQYXJzZXIocGFyc2VyKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgICAgICByZXR1cm4gIkZpbHRlclBhcmVudFBhdGgoIiArIF9maWx0ZXJFeHByICsgIiwgIiArIF9wYXRoICsgJyknOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldERlc2NlbmRhbnRBeGlzKCkgewotICAgICAgICBfaGFzRGVzY2VuZGFudEF4aXMgPSB0cnVlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFR5cGUgY2hlY2sgYSBGaWx0ZXJQYXJlbnRQYXRoLiBJZiB0aGUgZmlsdGVyIGlzIG5vdCBhIG5vZGUtc2V0IGFkZCBhCi0gICAgICogY2FzdCB0byBub2RlLXNldCBvbmx5IGlmIGl0IGlzIG9mIHJlZmVyZW5jZSB0eXBlLiBUaGlzIHR5cGUgY29lcmNpb24gaXMKLSAgICAgKiBuZWVkZWQgZm9yIGV4cHJlc3Npb25zIGxpa2UgJHgvTElORSB3aGVyZSAkeCBpcyBhIHBhcmFtZXRlciByZWZlcmVuY2UuCi0gICAgICovCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLSAgICAgICAgZmluYWwgVHlwZSBmdHlwZSA9IF9maWx0ZXJFeHByLnR5cGVDaGVjayhzdGFibGUpOwotICAgICAgICBpZiAoZnR5cGUgaW5zdGFuY2VvZiBOb2RlU2V0VHlwZSA9PSBmYWxzZSkgewotICAgICAgICAgICAgaWYgKGZ0eXBlIGluc3RhbmNlb2YgUmVmZXJlbmNlVHlwZSkgIHsKLSAgICAgICAgICAgICAgICBfZmlsdGVyRXhwciA9IG5ldyBDYXN0RXhwcihfZmlsdGVyRXhwciwgVHlwZS5Ob2RlU2V0KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8qCi0gICAgICAgICAgICBlbHNlIGlmIChmdHlwZSBpbnN0YW5jZW9mIFJlc3VsdFRyZWVUeXBlKSAgewotICAgICAgICAgICAgICAgIF9maWx0ZXJFeHByID0gbmV3IENhc3RFeHByKF9maWx0ZXJFeHByLCBUeXBlLk5vZGVTZXQpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgKi8KLSAgICAgICAgICAgIGVsc2UgaWYgKGZ0eXBlIGluc3RhbmNlb2YgTm9kZVR5cGUpICB7Ci0gICAgICAgICAgICAgICAgX2ZpbHRlckV4cHIgPSBuZXcgQ2FzdEV4cHIoX2ZpbHRlckV4cHIsIFR5cGUuTm9kZVNldCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUNoZWNrRXJyb3IodGhpcyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBXcmFwIHNpbmdsZSBub2RlIHBhdGggaW4gYSBub2RlIHNldAotICAgICAgICBmaW5hbCBUeXBlIHB0eXBlID0gX3BhdGgudHlwZUNoZWNrKHN0YWJsZSk7Ci0gICAgICAgIGlmICghKHB0eXBlIGluc3RhbmNlb2YgTm9kZVNldFR5cGUpKSB7Ci0gICAgICAgICAgICBfcGF0aCA9IG5ldyBDYXN0RXhwcihfcGF0aCwgVHlwZS5Ob2RlU2V0KTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBfdHlwZSA9IFR5cGUuTm9kZVNldDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLSAgICAgICAgZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0gICAgICAgIC8vIENyZWF0ZSBuZXcgU3RlcEl0ZXJhdG9yCi0gICAgICAgIGZpbmFsIGludCBpbml0U0kgPSBjcGcuYWRkTWV0aG9kcmVmKFNURVBfSVRFUkFUT1JfQ0xBU1MsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI8aW5pdD4iLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKCIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgK05PREVfSVRFUkFUT1JfU0lHCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICtOT0RFX0lURVJBVE9SX1NJRwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIilWIik7Ci0KLSAgICAgICAgLy8gQmFja3dhcmRzIGJyYW5jaGVzIGFyZSBwcm9oaWJpdGVkIGlmIGFuIHVuaW5pdGlhbGl6ZWQgb2JqZWN0IGlzCi0gICAgICAgIC8vIG9uIHRoZSBzdGFjayBieSBzZWN0aW9uIDQuOS40IG9mIHRoZSBKVk0gU3BlY2lmaWNhdGlvbiwgMm5kIEVkLgotICAgICAgICAvLyBXZSBkb24ndCBrbm93IHdoZXRoZXIgdGhpcyBjb2RlIG1pZ2h0IGNvbnRhaW4gYmFja3dhcmRzIGJyYW5jaGVzLAotICAgICAgICAvLyBzbyB3ZSBtdXN0bid0IGNyZWF0ZSB0aGUgbmV3IG9iamVjdCB1bnRpbCBhZnRlciB3ZSd2ZSBjcmVhdGVkCi0gICAgICAgIC8vIHRoZSBzdXNwZWN0IGFyZ3VtZW50cyB0byBpdHMgY29uc3RydWN0b3IuICBJbnN0ZWFkIHdlIGNhbGN1bGF0ZQotICAgICAgICAvLyB0aGUgdmFsdWVzIG9mIHRoZSBhcmd1bWVudHMgdG8gdGhlIGNvbnN0cnVjdG9yIGZpcnN0LCBzdG9yZSB0aGVtCi0gICAgICAgIC8vIGluIHRlbXBvcmFyeSB2YXJpYWJsZXMsIGNyZWF0ZSB0aGUgb2JqZWN0IGFuZCByZWxvYWQgdGhlCi0gICAgICAgIC8vIGFyZ3VtZW50cyBmcm9tIHRoZSB0ZW1wb3JhcmllcyB0byBhdm9pZCB0aGUgcHJvYmxlbS4KLQotICAgICAgICAvLyBSZWN1cnNpdmVseSBjb21waWxlIDIgaXRlcmF0b3JzCi0gICAgICAgIF9maWx0ZXJFeHByLnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgTG9jYWxWYXJpYWJsZUdlbiBmaWx0ZXJUZW1wID0KLSAgICAgICAgICAgICAgICBtZXRob2RHZW4uYWRkTG9jYWxWYXJpYWJsZSgiZmlsdGVyX3BhcmVudF9wYXRoX3RtcDEiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFV0aWwuZ2V0SkNSZWZUeXBlKE5PREVfSVRFUkFUT1JfU0lHKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLCBudWxsKTsKLSAgICAgICAgZmlsdGVyVGVtcC5zZXRTdGFydChpbC5hcHBlbmQobmV3IEFTVE9SRShmaWx0ZXJUZW1wLmdldEluZGV4KCkpKSk7Ci0KLSAgICAgICAgX3BhdGgudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICBMb2NhbFZhcmlhYmxlR2VuIHBhdGhUZW1wID0KLSAgICAgICAgICAgICAgICBtZXRob2RHZW4uYWRkTG9jYWxWYXJpYWJsZSgiZmlsdGVyX3BhcmVudF9wYXRoX3RtcDIiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFV0aWwuZ2V0SkNSZWZUeXBlKE5PREVfSVRFUkFUT1JfU0lHKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLCBudWxsKTsKLSAgICAgICAgcGF0aFRlbXAuc2V0U3RhcnQoaWwuYXBwZW5kKG5ldyBBU1RPUkUocGF0aFRlbXAuZ2V0SW5kZXgoKSkpKTsKLQotICAgICAgICBpbC5hcHBlbmQobmV3IE5FVyhjcGcuYWRkQ2xhc3MoU1RFUF9JVEVSQVRPUl9DTEFTUykpKTsKLSAgICAgICAgaWwuYXBwZW5kKERVUCk7Ci0gICAgICAgIGZpbHRlclRlbXAuc2V0RW5kKGlsLmFwcGVuZChuZXcgQUxPQUQoZmlsdGVyVGVtcC5nZXRJbmRleCgpKSkpOwotICAgICAgICBwYXRoVGVtcC5zZXRFbmQoaWwuYXBwZW5kKG5ldyBBTE9BRChwYXRoVGVtcC5nZXRJbmRleCgpKSkpOwotCi0gICAgICAgIC8vIEluaXRpYWxpemUgU3RlcEl0ZXJhdG9yIHdpdGggaXRlcmF0b3JzIGZyb20gdGhlIHN0YWNrCi0gICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFU1BFQ0lBTChpbml0U0kpKTsKLQotICAgICAgICAvLyBUaGlzIGlzIGEgc3BlY2lhbCBjYXNlIGZvciB0aGUgLy8qIHBhdGggd2l0aCBvciB3aXRob3V0IHByZWRpY2F0ZXMKLSAgICAgICAgaWYgKF9oYXNEZXNjZW5kYW50QXhpcykgewotICAgICAgICAgICAgZmluYWwgaW50IGluY2wgPSBjcGcuYWRkTWV0aG9kcmVmKE5PREVfSVRFUkFUT1JfQkFTRSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiaW5jbHVkZVNlbGYiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoKSIgKyBOT0RFX0lURVJBVE9SX1NJRyk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRVZJUlRVQUwoaW5jbCkpOwotICAgICAgICB9Ci0KLSAgICAgICAgU3ludGF4VHJlZU5vZGUgcGFyZW50ID0gZ2V0UGFyZW50KCk7Ci0KLSAgICAgICAgYm9vbGVhbiBwYXJlbnRBbHJlYWR5T3JkZXJlZCA9Ci0gICAgICAgICAgICAocGFyZW50IGluc3RhbmNlb2YgUmVsYXRpdmVMb2NhdGlvblBhdGgpCi0gICAgICAgICAgICAgICAgfHwgKHBhcmVudCBpbnN0YW5jZW9mIEZpbHRlclBhcmVudFBhdGgpCi0gICAgICAgICAgICAgICAgfHwgKHBhcmVudCBpbnN0YW5jZW9mIEtleUNhbGwpCi0gICAgICAgICAgICAgICAgfHwgKHBhcmVudCBpbnN0YW5jZW9mIEN1cnJlbnRDYWxsKQotICAgICAgICAgICAgICAgIHx8IChwYXJlbnQgaW5zdGFuY2VvZiBEb2N1bWVudENhbGwpOwotCi0gICAgICAgIGlmICghcGFyZW50QWxyZWFkeU9yZGVyZWQpIHsKLSAgICAgICAgICAgIGZpbmFsIGludCBvcmRlciA9IGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoRE9NX0lOVEYsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9SREVSX0lURVJBVE9SLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPUkRFUl9JVEVSQVRPUl9TSUcpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkRE9NKCkpOwotICAgICAgICAgICAgaWwuYXBwZW5kKFNXQVApOwotICAgICAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkQ29udGV4dE5vZGUoKSk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRUlOVEVSRkFDRShvcmRlciwgMykpOwotICAgICAgICB9Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9GaWx0ZXJlZEFic29sdXRlTG9jYXRpb25QYXRoLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0ZpbHRlcmVkQWJzb2x1dGVMb2NhdGlvblBhdGguamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggODIxNzRiNS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0ZpbHRlcmVkQWJzb2x1dGVMb2NhdGlvblBhdGguamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEyNyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBGaWx0ZXJlZEFic29sdXRlTG9jYXRpb25QYXRoLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTIgMTA6MjY6NTAgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5BTE9BRDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkFTVE9SRTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkNvbnN0YW50UG9vbEdlbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklOVk9LRUlOVEVSRkFDRTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklOVk9LRVNQRUNJQUw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JbnN0cnVjdGlvbkxpc3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5Mb2NhbFZhcmlhYmxlR2VuOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuTkVXOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkNsYXNzR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLk1ldGhvZEdlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5Ob2RlVHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGVDaGVja0Vycm9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlV0aWw7Ci0KLS8qKgotICogQGF1dGhvciBHLiBUb2RkIE1pbGxlcgotICovCi1maW5hbCBjbGFzcyBGaWx0ZXJlZEFic29sdXRlTG9jYXRpb25QYXRoIGV4dGVuZHMgRXhwcmVzc2lvbiB7Ci0gICAgcHJpdmF0ZSBFeHByZXNzaW9uIF9wYXRoOyAgIC8vIG1heSBiZSBudWxsCi0KLSAgICBwdWJsaWMgRmlsdGVyZWRBYnNvbHV0ZUxvY2F0aW9uUGF0aCgpIHsKLSAgICAgICAgX3BhdGggPSBudWxsOwotICAgIH0KLQotICAgIHB1YmxpYyBGaWx0ZXJlZEFic29sdXRlTG9jYXRpb25QYXRoKEV4cHJlc3Npb24gcGF0aCkgewotICAgICAgICBfcGF0aCA9IHBhdGg7Ci0gICAgICAgIGlmIChwYXRoICE9IG51bGwpIHsKLSAgICAgICAgICAgIF9wYXRoLnNldFBhcmVudCh0aGlzKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldFBhcnNlcihQYXJzZXIgcGFyc2VyKSB7Ci0gICAgICAgIHN1cGVyLnNldFBhcnNlcihwYXJzZXIpOwotICAgICAgICBpZiAoX3BhdGggIT0gbnVsbCkgewotICAgICAgICAgICAgX3BhdGguc2V0UGFyc2VyKHBhcnNlcik7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgRXhwcmVzc2lvbiBnZXRQYXRoKCkgewotICAgICAgICByZXR1cm4oX3BhdGgpOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0gICAgICAgIHJldHVybiAiRmlsdGVyZWRBYnNvbHV0ZUxvY2F0aW9uUGF0aCgiICsKLSAgICAgICAgICAgIChfcGF0aCAhPSBudWxsID8gX3BhdGgudG9TdHJpbmcoKSA6ICJudWxsIikgKyAnKSc7Ci0gICAgfQotCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLSAgICAgICAgaWYgKF9wYXRoICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZpbmFsIFR5cGUgcHR5cGUgPSBfcGF0aC50eXBlQ2hlY2soc3RhYmxlKTsKLSAgICAgICAgICAgIGlmIChwdHlwZSBpbnN0YW5jZW9mIE5vZGVUeXBlKSB7ICAgICAgICAgICAgLy8gcHJvbW90ZSB0byBub2RlLXNldAotICAgICAgICAgICAgICAgIF9wYXRoID0gbmV3IENhc3RFeHByKF9wYXRoLCBUeXBlLk5vZGVTZXQpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBfdHlwZSA9IFR5cGUuTm9kZVNldDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLSAgICAgICAgZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0gICAgICAgIGlmIChfcGF0aCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmaW5hbCBpbnQgaW5pdERGSSA9IGNwZy5hZGRNZXRob2RyZWYoRFVQX0ZJTFRFUkVEX0lURVJBVE9SLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjxpbml0PiIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKCIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgTk9ERV9JVEVSQVRPUl9TSUcKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIilWIik7Ci0KLSAgICAgICAgICAgIC8vIEJhY2t3YXJkcyBicmFuY2hlcyBhcmUgcHJvaGliaXRlZCBpZiBhbiB1bmluaXRpYWxpemVkIG9iamVjdCBpcwotICAgICAgICAgICAgLy8gb24gdGhlIHN0YWNrIGJ5IHNlY3Rpb24gNC45LjQgb2YgdGhlIEpWTSBTcGVjaWZpY2F0aW9uLCAybmQgRWQuCi0gICAgICAgICAgICAvLyBXZSBkb24ndCBrbm93IHdoZXRoZXIgdGhpcyBjb2RlIG1pZ2h0IGNvbnRhaW4gYmFja3dhcmRzIGJyYW5jaGVzLAotICAgICAgICAgICAgLy8gc28gd2UgbXVzdG4ndCBjcmVhdGUgdGhlIG5ldyBvYmplY3QgdW50aWwgYWZ0ZXIgd2UndmUgY3JlYXRlZAotICAgICAgICAgICAgLy8gdGhlIHN1c3BlY3QgYXJndW1lbnRzIHRvIGl0cyBjb25zdHJ1Y3Rvci4gIEluc3RlYWQgd2UgY2FsY3VsYXRlCi0gICAgICAgICAgICAvLyB0aGUgdmFsdWVzIG9mIHRoZSBhcmd1bWVudHMgdG8gdGhlIGNvbnN0cnVjdG9yIGZpcnN0LCBzdG9yZSB0aGVtCi0gICAgICAgICAgICAvLyBpbiB0ZW1wb3JhcnkgdmFyaWFibGVzLCBjcmVhdGUgdGhlIG9iamVjdCBhbmQgcmVsb2FkIHRoZQotICAgICAgICAgICAgLy8gYXJndW1lbnRzIGZyb20gdGhlIHRlbXBvcmFyaWVzIHRvIGF2b2lkIHRoZSBwcm9ibGVtLgotCi0gICAgICAgICAgICAvLyBDb21waWxlIHJlbGF0aXZlIHBhdGggaXRlcmF0b3IocykKLSAgICAgICAgICAgIExvY2FsVmFyaWFibGVHZW4gcGF0aFRlbXAgPQotICAgICAgICAgICAgICAgbWV0aG9kR2VuLmFkZExvY2FsVmFyaWFibGUoImZpbHRlcmVkX2Fic29sdXRlX2xvY2F0aW9uX3BhdGhfdG1wIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFV0aWwuZ2V0SkNSZWZUeXBlKE5PREVfSVRFUkFUT1JfU0lHKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsIG51bGwpOwotICAgICAgICAgICAgX3BhdGgudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICAgICAgcGF0aFRlbXAuc2V0U3RhcnQoaWwuYXBwZW5kKG5ldyBBU1RPUkUocGF0aFRlbXAuZ2V0SW5kZXgoKSkpKTsKLQotICAgICAgICAgICAgLy8gQ3JlYXRlIG5ldyBEdXAgRmlsdGVyIEl0ZXJhdG9yCi0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IE5FVyhjcGcuYWRkQ2xhc3MoRFVQX0ZJTFRFUkVEX0lURVJBVE9SKSkpOwotICAgICAgICAgICAgaWwuYXBwZW5kKERVUCk7Ci0gICAgICAgICAgICBwYXRoVGVtcC5zZXRFbmQoaWwuYXBwZW5kKG5ldyBBTE9BRChwYXRoVGVtcC5nZXRJbmRleCgpKSkpOwotCi0gICAgICAgICAgICAvLyBJbml0aWFsaXplIER1cCBGaWx0ZXIgSXRlcmF0b3Igd2l0aCBpdGVyYXRvciBmcm9tIHRoZSBzdGFjawotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VTUEVDSUFMKGluaXRERkkpKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIGZpbmFsIGludCBnaXQgPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKERPTV9JTlRGLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImdldEl0ZXJhdG9yIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoKSIrTk9ERV9JVEVSQVRPUl9TSUcpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkRE9NKCkpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0UoZ2l0LCAxKSk7Ci0gICAgICAgIH0KLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0Zsb29yQ2FsbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9GbG9vckNhbGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYmQzOTEzNi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0Zsb29yQ2FsbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDggKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRmxvb3JDYWxsLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMDEgMTU6MTY6MTUgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFU1RBVElDOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkNsYXNzR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLk1ldGhvZEdlbmVyYXRvcjsKLQotLyoqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKi8KLWZpbmFsIGNsYXNzIEZsb29yQ2FsbCBleHRlbmRzIEZ1bmN0aW9uQ2FsbCB7Ci0gICAgcHVibGljIEZsb29yQ2FsbChRTmFtZSBmbmFtZSwgVmVjdG9yIGFyZ3VtZW50cykgewotICAgICAgICBzdXBlcihmbmFtZSwgYXJndW1lbnRzKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLSAgICAgICAgYXJndW1lbnQoKS50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgIG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKQotICAgICAgICAgICAgLmFwcGVuZChuZXcgSU5WT0tFU1RBVElDKGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmFkZE1ldGhvZHJlZihNQVRIX0NMQVNTLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImZsb29yIiwgIihEKUQiKSkpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvRmxvd0xpc3QuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvRmxvd0xpc3QuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNDMyNDRiMy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0Zsb3dMaXN0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMTkgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRmxvd0xpc3QuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8wMSAxNToyMTo0MyBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7Ci1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQnJhbmNoSGFuZGxlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW5zdHJ1Y3Rpb25IYW5kbGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JbnN0cnVjdGlvbkxpc3Q7Ci0KLS8qKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgRmxvd0xpc3QgewotICAgIHByaXZhdGUgVmVjdG9yIF9lbGVtZW50czsKLQotICAgIHB1YmxpYyBGbG93TGlzdCgpIHsKLSAgICAgICAgX2VsZW1lbnRzID0gbnVsbDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgRmxvd0xpc3QoSW5zdHJ1Y3Rpb25IYW5kbGUgYmgpIHsKLSAgICAgICAgX2VsZW1lbnRzID0gbmV3IFZlY3RvcigpOwotICAgICAgICBfZWxlbWVudHMuYWRkRWxlbWVudChiaCk7Ci0gICAgfQotCi0gICAgcHVibGljIEZsb3dMaXN0KEZsb3dMaXN0IGxpc3QpIHsKLSAgICAgICAgX2VsZW1lbnRzID0gbGlzdC5fZWxlbWVudHM7Ci0gICAgfQotCi0gICAgcHVibGljIEZsb3dMaXN0IGFkZChJbnN0cnVjdGlvbkhhbmRsZSBiaCkgewotICAgICAgICBpZiAoX2VsZW1lbnRzID09IG51bGwpIHsKLSAgICAgICAgICAgIF9lbGVtZW50cyA9IG5ldyBWZWN0b3IoKTsKLSAgICAgICAgfQotICAgICAgICBfZWxlbWVudHMuYWRkRWxlbWVudChiaCk7Ci0gICAgICAgIHJldHVybiB0aGlzOwotICAgIH0KLQotICAgIHB1YmxpYyBGbG93TGlzdCBhcHBlbmQoRmxvd0xpc3QgcmlnaHQpIHsKLSAgICAgICAgaWYgKF9lbGVtZW50cyA9PSBudWxsKSB7Ci0gICAgICAgICAgICBfZWxlbWVudHMgPSByaWdodC5fZWxlbWVudHM7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBmaW5hbCBWZWN0b3IgdGVtcCA9IHJpZ2h0Ll9lbGVtZW50czsKLSAgICAgICAgICAgIGlmICh0ZW1wICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmaW5hbCBpbnQgbiA9IHRlbXAuc2l6ZSgpOwotICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgICAgIF9lbGVtZW50cy5hZGRFbGVtZW50KHRlbXAuZWxlbWVudEF0KGkpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHRoaXM7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQmFjayBwYXRjaCBhIGZsb3cgbGlzdC4gQWxsIGluc3RydWN0aW9uIGhhbmRsZXMgbXVzdCBiZSBicmFuY2ggaGFuZGxlcy4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBiYWNrUGF0Y2goSW5zdHJ1Y3Rpb25IYW5kbGUgdGFyZ2V0KSB7Ci0gICAgICAgIGlmIChfZWxlbWVudHMgIT0gbnVsbCkgewotICAgICAgICAgICAgZmluYWwgaW50IG4gPSBfZWxlbWVudHMuc2l6ZSgpOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspIHsKLSAgICAgICAgICAgICAgICBCcmFuY2hIYW5kbGUgYmggPSAoQnJhbmNoSGFuZGxlKV9lbGVtZW50cy5lbGVtZW50QXQoaSk7Ci0gICAgICAgICAgICAgICAgYmguc2V0VGFyZ2V0KHRhcmdldCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBfZWxlbWVudHMuY2xlYXIoKTsgICAgICAgICAgLy8gYXZvaWQgYmFja3BhdGNoaW5nIG1vcmUgdGhhbiBvbmNlCi0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZWRpcmVjdCB0aGUgaGFuZGxlcyBmcm9tIG9sZExpc3QgdG8gbmV3TGlzdC4gIlRoaXMiIGZsb3cgbGlzdAotICAgICAqIGlzIGFzc3VtZWQgdG8gYmUgcmVsYXRpdmUgdG8gb2xkTGlzdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgRmxvd0xpc3QgY29weUFuZFJlZGlyZWN0KEluc3RydWN0aW9uTGlzdCBvbGRMaXN0LAotICAgICAgICBJbnN0cnVjdGlvbkxpc3QgbmV3TGlzdCkKLSAgICB7Ci0gICAgICAgIGZpbmFsIEZsb3dMaXN0IHJlc3VsdCA9IG5ldyBGbG93TGlzdCgpOwotICAgICAgICBpZiAoX2VsZW1lbnRzID09IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiByZXN1bHQ7Ci0gICAgICAgIH0KLQotICAgICAgICBmaW5hbCBpbnQgbiA9IF9lbGVtZW50cy5zaXplKCk7Ci0gICAgICAgIGZpbmFsIEl0ZXJhdG9yIG9sZEl0ZXIgPSBvbGRMaXN0Lml0ZXJhdG9yKCk7Ci0gICAgICAgIGZpbmFsIEl0ZXJhdG9yIG5ld0l0ZXIgPSBuZXdMaXN0Lml0ZXJhdG9yKCk7Ci0KLSAgICAgICAgd2hpbGUgKG9sZEl0ZXIuaGFzTmV4dCgpKSB7Ci0gICAgICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkhhbmRsZSBvbGRJaCA9IChJbnN0cnVjdGlvbkhhbmRsZSkgb2xkSXRlci5uZXh0KCk7Ci0gICAgICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkhhbmRsZSBuZXdJaCA9IChJbnN0cnVjdGlvbkhhbmRsZSkgbmV3SXRlci5uZXh0KCk7Ci0KLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgaWYgKF9lbGVtZW50cy5lbGVtZW50QXQoaSkgPT0gb2xkSWgpIHsKLSAgICAgICAgICAgICAgICAgICAgcmVzdWx0LmFkZChuZXdJaCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiByZXN1bHQ7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9Gb3JFYWNoLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0ZvckVhY2guamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOWIzNTBkNy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0ZvckVhY2guamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE5NyArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDE1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICovCi0vKgotICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCi0gKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKLSAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KLSAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCi0gKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAotICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IEZvckVhY2guamF2YSx2IDEuMi40LjEgMjAwNS8wOS8wMSAxNToyMzo0NiBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkJyYW5jaEhhbmRsZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkNvbnN0YW50UG9vbEdlbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkdPVE87Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JRkdUOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW5zdHJ1Y3Rpb25IYW5kbGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JbnN0cnVjdGlvbkxpc3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuQ2xhc3NHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuRXJyb3JNc2c7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuTWV0aG9kR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLk5vZGVTZXRUeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLk5vZGVUeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlJlZmVyZW5jZVR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuUmVzdWx0VHJlZVR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlQ2hlY2tFcnJvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5VdGlsOwotaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi0vKioKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICovCi1maW5hbCBjbGFzcyBGb3JFYWNoIGV4dGVuZHMgSW5zdHJ1Y3Rpb24gewotCi0gICAgcHJpdmF0ZSBFeHByZXNzaW9uIF9zZWxlY3Q7Ci0gICAgcHJpdmF0ZSBUeXBlICAgICAgIF90eXBlOwotCi0gICAgcHVibGljIHZvaWQgZGlzcGxheShpbnQgaW5kZW50KSB7Ci0gICAgICAgIGluZGVudChpbmRlbnQpOwotICAgICAgICBVdGlsLnByaW50bG4oIkZvckVhY2giKTsKLSAgICAgICAgaW5kZW50KGluZGVudCArIEluZGVudEluY3JlbWVudCk7Ci0gICAgICAgIFV0aWwucHJpbnRsbigic2VsZWN0ICIgKyBfc2VsZWN0LnRvU3RyaW5nKCkpOwotICAgICAgICBkaXNwbGF5Q29udGVudHMoaW5kZW50ICsgSW5kZW50SW5jcmVtZW50KTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBwYXJzZUNvbnRlbnRzKFBhcnNlciBwYXJzZXIpIHsKLSAgICAgICAgX3NlbGVjdCA9IHBhcnNlci5wYXJzZUV4cHJlc3Npb24odGhpcywgInNlbGVjdCIsIG51bGwpOwotCi0gICAgICAgIHBhcnNlQ2hpbGRyZW4ocGFyc2VyKTsKLQotICAgICAgICAvLyBtYWtlIHN1cmUgcmVxdWlyZWQgYXR0cmlidXRlKHMpIGhhdmUgYmVlbiBzZXQKLSAgICAgICAgaWYgKF9zZWxlY3QuaXNEdW1teSgpKSB7Ci0gICAgICAgICAgICByZXBvcnRFcnJvcih0aGlzLCBwYXJzZXIsIEVycm9yTXNnLlJFUVVJUkVEX0FUVFJfRVJSLCAic2VsZWN0Iik7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgVHlwZSB0eXBlQ2hlY2soU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgewotICAgICAgICBfdHlwZSA9IF9zZWxlY3QudHlwZUNoZWNrKHN0YWJsZSk7Ci0KLSAgICAgICAgaWYgKF90eXBlIGluc3RhbmNlb2YgUmVmZXJlbmNlVHlwZSB8fCBfdHlwZSBpbnN0YW5jZW9mIE5vZGVUeXBlKSB7Ci0gICAgICAgICAgICBfc2VsZWN0ID0gbmV3IENhc3RFeHByKF9zZWxlY3QsIFR5cGUuTm9kZVNldCk7Ci0gICAgICAgICAgICB0eXBlQ2hlY2tDb250ZW50cyhzdGFibGUpOwotICAgICAgICAgICAgcmV0dXJuIFR5cGUuVm9pZDsKLSAgICAgICAgfQotICAgICAgICBpZiAoX3R5cGUgaW5zdGFuY2VvZiBOb2RlU2V0VHlwZXx8X3R5cGUgaW5zdGFuY2VvZiBSZXN1bHRUcmVlVHlwZSkgewotICAgICAgICAgICAgdHlwZUNoZWNrQ29udGVudHMoc3RhYmxlKTsKLSAgICAgICAgICAgIHJldHVybiBUeXBlLlZvaWQ7Ci0gICAgICAgIH0KLSAgICAgICAgdGhyb3cgbmV3IFR5cGVDaGVja0Vycm9yKHRoaXMpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotICAgICAgICBmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQotICAgICAgICAvLyBTYXZlIGN1cnJlbnQgbm9kZSBhbmQgY3VycmVudCBpdGVyYXRvciBvbiB0aGUgc3RhY2sKLSAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkQ3VycmVudE5vZGUoKSk7Ci0gICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZEl0ZXJhdG9yKCkpOwotCi0gICAgICAgIC8vIENvbGxlY3Qgc29ydCBvYmplY3RzIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGluc3RydWN0aW9uCi0gICAgICAgIGZpbmFsIFZlY3RvciBzb3J0T2JqZWN0cyA9IG5ldyBWZWN0b3IoKTsKLSAgICAgICAgSXRlcmF0b3I8U3ludGF4VHJlZU5vZGU+IGNoaWxkcmVuID0gZWxlbWVudHMoKTsKLSAgICAgICAgd2hpbGUgKGNoaWxkcmVuLmhhc05leHQoKSkgewotICAgICAgICAgICAgZmluYWwgU3ludGF4VHJlZU5vZGUgY2hpbGQgPSBjaGlsZHJlbi5uZXh0KCk7Ci0gICAgICAgICAgICBpZiAoY2hpbGQgaW5zdGFuY2VvZiBTb3J0KSB7Ci0gICAgICAgICAgICAgICAgc29ydE9iamVjdHMuYWRkRWxlbWVudChjaGlsZCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoKF90eXBlICE9IG51bGwpICYmIChfdHlwZSBpbnN0YW5jZW9mIFJlc3VsdFRyZWVUeXBlKSkgewotICAgICAgICAgICAgLy8gU3RvcmUgZXhpc3RpbmcgRE9NIG9uIHN0YWNrIC0gbXVzdCBiZSByZXN0b3JlZCB3aGVuIGxvb3AgaXMgZG9uZQotICAgICAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkRE9NKCkpOwotCi0gICAgICAgICAgICAvLyA8eHNsOnNvcnQ+IGNhbm5vdCBiZSBhcHBsaWVkIHRvIGEgcmVzdWx0IHRyZWUgLSBpc3N1ZSB3YXJuaW5nCi0gICAgICAgICAgICBpZiAoc29ydE9iamVjdHMuc2l6ZSgpID4gMCkgewotICAgICAgICAgICAgICAgIEVycm9yTXNnIG1zZyA9IG5ldyBFcnJvck1zZyhFcnJvck1zZy5SRVNVTFRfVFJFRV9TT1JUX0VSUix0aGlzKTsKLSAgICAgICAgICAgICAgICBnZXRQYXJzZXIoKS5yZXBvcnRFcnJvcihXQVJOSU5HLCBtc2cpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBQdXQgdGhlIHJlc3VsdCB0cmVlIG9uIHRoZSBzdGFjayAoRE9NKQotICAgICAgICAgICAgX3NlbGVjdC50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgICAgICAvLyBHZXQgYW4gaXRlcmF0b3IgZm9yIHRoZSB3aG9sZSBET00gLSBleGNsdWRpbmcgdGhlIHJvb3Qgbm9kZQotICAgICAgICAgICAgX3R5cGUudHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgVHlwZS5Ob2RlU2V0KTsKLSAgICAgICAgICAgIC8vIFN0b3JlIHRoZSByZXN1bHQgdHJlZSBhcyB0aGUgZGVmYXVsdCBET00KLSAgICAgICAgICAgIGlsLmFwcGVuZChTV0FQKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4uc3RvcmVET00oKSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAvLyBDb21waWxlIG5vZGUgaXRlcmF0b3IKLSAgICAgICAgICAgIGlmIChzb3J0T2JqZWN0cy5zaXplKCkgPiAwKSB7Ci0gICAgICAgICAgICAgICAgU29ydC50cmFuc2xhdGVTb3J0SXRlcmF0b3IoY2xhc3NHZW4sIG1ldGhvZEdlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfc2VsZWN0LCBzb3J0T2JqZWN0cyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBfc2VsZWN0LnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKF90eXBlIGluc3RhbmNlb2YgUmVmZXJlbmNlVHlwZSA9PSBmYWxzZSkgewotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZENvbnRleHROb2RlKCkpOwotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4uc2V0U3RhcnROb2RlKCkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLQotICAgICAgICAvLyBPdmVyd3JpdGUgY3VycmVudCBpdGVyYXRvcgotICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLnN0b3JlSXRlcmF0b3IoKSk7Ci0KLSAgICAgICAgLy8gR2l2ZSBsb2NhbCB2YXJpYWJsZXMgKGlmIGFueSkgZGVmYXVsdCB2YWx1ZXMgYmVmb3JlIHN0YXJ0aW5nIGxvb3AKLSAgICAgICAgaW5pdGlhbGl6ZVZhcmlhYmxlcyhjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQotICAgICAgICBmaW5hbCBCcmFuY2hIYW5kbGUgbmV4dE5vZGUgPSBpbC5hcHBlbmQobmV3IEdPVE8obnVsbCkpOwotICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkhhbmRsZSBsb29wID0gaWwuYXBwZW5kKE5PUCk7Ci0KLSAgICAgICAgdHJhbnNsYXRlQ29udGVudHMoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0KLSAgICAgICAgbmV4dE5vZGUuc2V0VGFyZ2V0KGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZEl0ZXJhdG9yKCkpKTsKLSAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5uZXh0Tm9kZSgpKTsKLSAgICAgICAgaWwuYXBwZW5kKERVUCk7Ci0gICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4uc3RvcmVDdXJyZW50Tm9kZSgpKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBJRkdUKGxvb3ApKTsKLQotICAgICAgICAvLyBSZXN0b3JlIGN1cnJlbnQgRE9NIChpZiByZXN1bHQgdHJlZSB3YXMgdXNlZCBpbnN0ZWFkIGZvciB0aGlzIGxvb3ApCi0gICAgICAgIGlmICgoX3R5cGUgIT0gbnVsbCkgJiYgKF90eXBlIGluc3RhbmNlb2YgUmVzdWx0VHJlZVR5cGUpKSB7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLnN0b3JlRE9NKCkpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gUmVzdG9yZSBjdXJyZW50IG5vZGUgYW5kIGN1cnJlbnQgaXRlcmF0b3IgZnJvbSB0aGUgc3RhY2sKLSAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5zdG9yZUl0ZXJhdG9yKCkpOwotICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLnN0b3JlQ3VycmVudE5vZGUoKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhlIGNvZGUgdGhhdCBpcyBnZW5lcmF0ZWQgYnkgbmVzdGVkIGZvci1lYWNoIGxvb3BzIGNhbiBhcHBlYXIgdG8gc29tZQotICAgICAqIEpWTXMgYXMgaWYgaXQgaXMgYWNjZXNzaW5nIHVuLWluaXRpYWxpemVkIHZhcmlhYmxlcy4gV2UgbXVzdCBhZGQgc29tZQotICAgICAqIGNvZGUgdGhhdCBwdXNoZXMgdGhlIGRlZmF1bHQgdmFyaWFibGUgdmFsdWUgb24gdGhlIHN0YWNrIGFuZCBwb3BzIGl0Ci0gICAgICogaW50byB0aGUgdmFyaWFibGUgc2xvdC4gVGhpcyBpcyBkb25lIGJ5IHRoZSBWYXJpYWJsZS5pbml0aWFsaXplKCkKLSAgICAgKiBtZXRob2QuIFRoZSBjb2RlIHRoYXQgd2UgY29tcGlsZSBmb3IgdGhpcyBsb29wIGxvb2tzIGxpa2UgdGhpczoKLSAgICAgKgotICAgICAqICAgICAgICAgICBpbml0aWFsaXplIGl0ZXJhdG9yCi0gICAgICogICAgICAgICAgIGluaXRpYWxpemUgdmFyaWFibGVzIDwtLSBIRVJFISEhCi0gICAgICogICAgICAgICAgIGdvdG8gICBJdGVyYXRlCi0gICAgICogIExvb3A6ICAgIDoKLSAgICAgKiAgICAgICAgICAgOiAoY29kZSBmb3IgPHhzbDpmb3ItZWFjaD4gY29udGVudHMpCi0gICAgICogICAgICAgICAgIDoKLSAgICAgKiAgSXRlcmF0ZTogbm9kZSA9IGl0ZXJhdG9yLm5leHQoKTsKLSAgICAgKiAgICAgICAgICAgaWYgKG5vZGUgIT0gRU5EKSBnb3RvIExvb3AKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBpbml0aWFsaXplVmFyaWFibGVzKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0gICAgICAgIGZpbmFsIGludCBuID0gZWxlbWVudENvdW50KCk7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKSB7Ci0gICAgICAgICAgICBmaW5hbCBTeW50YXhUcmVlTm9kZSBjaGlsZCA9IGdldENvbnRlbnRzKCkuZ2V0KGkpOwotICAgICAgICAgICAgaWYgKGNoaWxkIGluc3RhbmNlb2YgVmFyaWFibGUpIHsKLSAgICAgICAgICAgICAgICBWYXJpYWJsZSB2YXIgPSAoVmFyaWFibGUpY2hpbGQ7Ci0gICAgICAgICAgICAgICAgdmFyLmluaXRpYWxpemUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvRm9ybWF0TnVtYmVyQ2FsbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9Gb3JtYXROdW1iZXJDYWxsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDRhYTkzMTEuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9Gb3JtYXROdW1iZXJDYWxsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMTYgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRm9ybWF0TnVtYmVyQ2FsbC5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzAxIDE1OjI2OjQ2IHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkNvbnN0YW50UG9vbEdlbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklOVk9LRVNUQVRJQzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklOVk9LRVZJUlRVQUw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JbnN0cnVjdGlvbkxpc3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5QVVNIOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkNsYXNzR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLk1ldGhvZEdlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5SZWFsVHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5TdHJpbmdUeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZUNoZWNrRXJyb3I7Ci0KLS8qKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKi8KLWZpbmFsIGNsYXNzIEZvcm1hdE51bWJlckNhbGwgZXh0ZW5kcyBGdW5jdGlvbkNhbGwgewotICAgIHByaXZhdGUgRXhwcmVzc2lvbiBfdmFsdWU7Ci0gICAgcHJpdmF0ZSBFeHByZXNzaW9uIF9mb3JtYXQ7Ci0gICAgcHJpdmF0ZSBFeHByZXNzaW9uIF9uYW1lOwotICAgIHByaXZhdGUgUU5hbWUgICAgICBfcmVzb2x2ZWRRTmFtZSA9IG51bGw7Ci0KLSAgICBwdWJsaWMgRm9ybWF0TnVtYmVyQ2FsbChRTmFtZSBmbmFtZSwgVmVjdG9yIGFyZ3VtZW50cykgewotICAgICAgICBzdXBlcihmbmFtZSwgYXJndW1lbnRzKTsKLSAgICAgICAgX3ZhbHVlID0gYXJndW1lbnQoMCk7Ci0gICAgICAgIF9mb3JtYXQgPSBhcmd1bWVudCgxKTsKLSAgICAgICAgX25hbWUgPSBhcmd1bWVudENvdW50KCkgPT0gMyA/IGFyZ3VtZW50KDIpIDogbnVsbDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgVHlwZSB0eXBlQ2hlY2soU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgewotCi0gICAgICAgIC8vIEluZm9ybSBzdHlsZXNoZWV0IHRvIGluc3RhbnRpYXRlIGEgRGVjaW1hbEZvcm1hdCBvYmplY3QKLSAgICAgICAgZ2V0U3R5bGVzaGVldCgpLm51bWJlckZvcm1hdHRpbmdVc2VkKCk7Ci0KLSAgICAgICAgZmluYWwgVHlwZSB0dmFsdWUgPSBfdmFsdWUudHlwZUNoZWNrKHN0YWJsZSk7Ci0gICAgICAgIGlmICh0dmFsdWUgaW5zdGFuY2VvZiBSZWFsVHlwZSA9PSBmYWxzZSkgewotICAgICAgICAgICAgX3ZhbHVlID0gbmV3IENhc3RFeHByKF92YWx1ZSwgVHlwZS5SZWFsKTsKLSAgICAgICAgfQotICAgICAgICBmaW5hbCBUeXBlIHRmb3JtYXQgPSBfZm9ybWF0LnR5cGVDaGVjayhzdGFibGUpOwotICAgICAgICBpZiAodGZvcm1hdCBpbnN0YW5jZW9mIFN0cmluZ1R5cGUgPT0gZmFsc2UpIHsKLSAgICAgICAgICAgIF9mb3JtYXQgPSBuZXcgQ2FzdEV4cHIoX2Zvcm1hdCwgVHlwZS5TdHJpbmcpOwotICAgICAgICB9Ci0gICAgICAgIGlmIChhcmd1bWVudENvdW50KCkgPT0gMykgewotICAgICAgICAgICAgZmluYWwgVHlwZSB0bmFtZSA9IF9uYW1lLnR5cGVDaGVjayhzdGFibGUpOwotCi0gICAgICAgICAgICBpZiAoX25hbWUgaW5zdGFuY2VvZiBMaXRlcmFsRXhwcikgewotICAgICAgICAgICAgICAgIGZpbmFsIExpdGVyYWxFeHByIGxpdGVyYWwgPSAoTGl0ZXJhbEV4cHIpIF9uYW1lOwotICAgICAgICAgICAgICAgIF9yZXNvbHZlZFFOYW1lID0KLSAgICAgICAgICAgICAgICAgICAgZ2V0UGFyc2VyKCkuZ2V0UU5hbWVJZ25vcmVEZWZhdWx0TnMobGl0ZXJhbC5nZXRWYWx1ZSgpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKHRuYW1lIGluc3RhbmNlb2YgU3RyaW5nVHlwZSA9PSBmYWxzZSkgewotICAgICAgICAgICAgICAgIF9uYW1lID0gbmV3IENhc3RFeHByKF9uYW1lLCBUeXBlLlN0cmluZyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIF90eXBlID0gVHlwZS5TdHJpbmc7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0gICAgICAgIGZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCi0gICAgICAgIF92YWx1ZS50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgIF9mb3JtYXQudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCi0gICAgICAgIGZpbmFsIGludCBmbjNhcmcgPSBjcGcuYWRkTWV0aG9kcmVmKEJBU0lTX0xJQlJBUllfQ0xBU1MsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJmb3JtYXROdW1iZXIiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKERMamF2YS9sYW5nL1N0cmluZzsiKwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTGphdmEvdGV4dC9EZWNpbWFsRm9ybWF0OykiKwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTGphdmEvbGFuZy9TdHJpbmc7Iik7Ci0gICAgICAgIGZpbmFsIGludCBnZXQgPSBjcGcuYWRkTWV0aG9kcmVmKFRSQU5TTEVUX0NMQVNTLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZ2V0RGVjaW1hbEZvcm1hdCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoTGphdmEvbGFuZy9TdHJpbmc7KSIrCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJMamF2YS90ZXh0L0RlY2ltYWxGb3JtYXQ7Iik7Ci0KLSAgICAgICAgaWwuYXBwZW5kKGNsYXNzR2VuLmxvYWRUcmFuc2xldCgpKTsKLSAgICAgICAgaWYgKF9uYW1lID09IG51bGwpIHsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsIEVNUFRZU1RSSU5HKSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoX3Jlc29sdmVkUU5hbWUgIT0gbnVsbCkgewotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgX3Jlc29sdmVkUU5hbWUudG9TdHJpbmcoKSkpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgX25hbWUudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICB9Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChnZXQpKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VTVEFUSUMoZm4zYXJnKSk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9GdW5jdGlvbkF2YWlsYWJsZUNhbGwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvRnVuY3Rpb25BdmFpbGFibGVDYWxsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDhjYWQ0MjcuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9GdW5jdGlvbkF2YWlsYWJsZUNhbGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE5NiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBGdW5jdGlvbkF2YWlsYWJsZUNhbGwuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8wMSAxNTozMDoyNSBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2Q7Ci1pbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuTW9kaWZpZXI7Ci1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQ29uc3RhbnRQb29sR2VuOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuUFVTSDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5DbGFzc0dlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5FcnJvck1zZzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5NZXRob2RHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlQ2hlY2tFcnJvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5VdGlsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC51dGlscy5PYmplY3RGYWN0b3J5OwotCi0vKioKLSAqIEBhdXRob3IgRy4gVG9kZCBNaWxsZXIKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICovCi1maW5hbCBjbGFzcyBGdW5jdGlvbkF2YWlsYWJsZUNhbGwgZXh0ZW5kcyBGdW5jdGlvbkNhbGwgewotCi0gICAgcHJpdmF0ZSBFeHByZXNzaW9uIF9hcmc7Ci0gICAgcHJpdmF0ZSBTdHJpbmcgICAgIF9uYW1lT2ZGdW5jdCA9IG51bGw7Ci0gICAgcHJpdmF0ZSBTdHJpbmcgICAgIF9uYW1lc3BhY2VPZkZ1bmN0ID0gbnVsbDsKLSAgICBwcml2YXRlIGJvb2xlYW4gICAgX2lzRnVuY3Rpb25BdmFpbGFibGUgPSBmYWxzZTsKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHMgYSBGdW5jdGlvbkF2YWlsYWJsZUNhbGwgRnVuY3Rpb25DYWxsLiBUYWtlcyB0aGUKLSAgICAgKiBmdW5jdGlvbiBuYW1lIHFuYW1lLCBmb3IgZXhhbXBsZSwgJ2Z1bmN0aW9uLWF2YWlsYWJsZScsIGFuZAotICAgICAqIGEgbGlzdCBvZiBhcmd1bWVudHMgd2hlcmUgdGhlIGFyZ3VtZW50cyBtdXN0IGJlIGluc3RhbmNlcyBvZgotICAgICAqIExpdGVyYWxFeHByZXNzaW9uLgotICAgICAqLwotICAgIHB1YmxpYyBGdW5jdGlvbkF2YWlsYWJsZUNhbGwoUU5hbWUgZm5hbWUsIFZlY3RvciBhcmd1bWVudHMpIHsKLSAgICAgICAgc3VwZXIoZm5hbWUsIGFyZ3VtZW50cyk7Ci0gICAgICAgIF9hcmcgPSAoRXhwcmVzc2lvbilhcmd1bWVudHMuZWxlbWVudEF0KDApOwotICAgICAgICBfdHlwZSA9IG51bGw7Ci0KLSAgICAgICAgaWYgKF9hcmcgaW5zdGFuY2VvZiBMaXRlcmFsRXhwcikgewotICAgICAgICAgICAgTGl0ZXJhbEV4cHIgYXJnID0gKExpdGVyYWxFeHByKSBfYXJnOwotICAgICAgICAgICAgX25hbWVzcGFjZU9mRnVuY3QgPSBhcmcuZ2V0TmFtZXNwYWNlKCk7Ci0gICAgICAgICAgICBfbmFtZU9mRnVuY3QgPSBhcmcuZ2V0VmFsdWUoKTsKLQotICAgICAgICAgICAgaWYgKCFpc0ludGVybmFsTmFtZXNwYWNlKCkpIHsKLSAgICAgICAgICAgICAgX2lzRnVuY3Rpb25BdmFpbGFibGUgPSBoYXNNZXRob2RzKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBcmd1bWVudCBvZiBmdW5jdGlvbi1hdmFpbGFibGUgY2FsbCBtdXN0IGJlIGxpdGVyYWwsIHR5cGVjaGVjawotICAgICAqIHJldHVybnMgdGhlIHR5cGUgb2YgZnVuY3Rpb24tYXZhaWxhYmxlIHRvIGJlIGJvb2xlYW4uCi0gICAgICovCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLSAgICAgICAgaWYgKF90eXBlICE9IG51bGwpIHsKLSAgICAgICAgICAgcmV0dXJuIF90eXBlOwotICAgICAgICB9Ci0gICAgICAgIGlmIChfYXJnIGluc3RhbmNlb2YgTGl0ZXJhbEV4cHIpIHsKLSAgICAgICAgICAgIHJldHVybiBfdHlwZSA9IFR5cGUuQm9vbGVhbjsKLSAgICAgICAgfQotICAgICAgICBFcnJvck1zZyBlcnIgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuTkVFRF9MSVRFUkFMX0VSUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICJmdW5jdGlvbi1hdmFpbGFibGUiLCB0aGlzKTsKLSAgICAgICAgdGhyb3cgbmV3IFR5cGVDaGVja0Vycm9yKGVycik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhbiBvYmplY3QgcmVwcmVzZW50aW5nIHRoZSBjb21waWxlLXRpbWUgZXZhbHVhdGlvbgotICAgICAqIG9mIGFuIGV4cHJlc3Npb24uIFdlIGFyZSBvbmx5IHVzaW5nIHRoaXMgZm9yIGZ1bmN0aW9uLWF2YWlsYWJsZQotICAgICAqIGFuZCBlbGVtZW50LWF2YWlsYWJsZSBhdCB0aGlzIHRpbWUuCi0gICAgICovCi0gICAgcHVibGljIE9iamVjdCBldmFsdWF0ZUF0Q29tcGlsZVRpbWUoKSB7Ci0gICAgICAgIHJldHVybiBnZXRSZXN1bHQoKSA/IEJvb2xlYW4uVFJVRSA6IEJvb2xlYW4uRkFMU0U7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogZm9yIGV4dGVybmFsIGphdmEgZnVuY3Rpb25zIG9ubHk6IHJlcG9ydHMgb24gd2hldGhlciBvciBub3QKLSAgICAgKiB0aGUgc3BlY2lmaWVkIG1ldGhvZCBpcyBmb3VuZCBpbiB0aGUgc3BlY2lmZWQgY2xhc3MuCi0gICAgICovCi0gICAgcHJpdmF0ZSBib29sZWFuIGhhc01ldGhvZHMoKSB7Ci0gICAgICAgIExpdGVyYWxFeHByIGFyZyA9IChMaXRlcmFsRXhwcilfYXJnOwotCi0gICAgICAgIC8vIEdldCB0aGUgY2xhc3MgbmFtZSBmcm9tIHRoZSBuYW1lc3BhY2UgdXJpCi0gICAgICAgIFN0cmluZyBjbGFzc05hbWUgPSBnZXRDbGFzc05hbWVGcm9tVXJpKF9uYW1lc3BhY2VPZkZ1bmN0KTsKLQotICAgICAgICAvLyBHZXQgdGhlIG1ldGhvZCBuYW1lIGZyb20gdGhlIGFyZ3VtZW50IHRvIGZ1bmN0aW9uLWF2YWlsYWJsZQotICAgICAgICBTdHJpbmcgbWV0aG9kTmFtZSA9IG51bGw7Ci0gICAgICAgIGludCBjb2xvbkluZGV4ID0gX25hbWVPZkZ1bmN0LmluZGV4T2YoIjoiKTsKLSAgICAgICAgaWYgKGNvbG9uSW5kZXggPiAwKSB7Ci0gICAgICAgICAgU3RyaW5nIGZ1bmN0aW9uTmFtZSA9IF9uYW1lT2ZGdW5jdC5zdWJzdHJpbmcoY29sb25JbmRleCsxKTsKLSAgICAgICAgICBpbnQgbGFzdERvdEluZGV4ID0gZnVuY3Rpb25OYW1lLmxhc3RJbmRleE9mKCcuJyk7Ci0gICAgICAgICAgaWYgKGxhc3REb3RJbmRleCA+IDApIHsKLSAgICAgICAgICAgIG1ldGhvZE5hbWUgPSBmdW5jdGlvbk5hbWUuc3Vic3RyaW5nKGxhc3REb3RJbmRleCsxKTsKLSAgICAgICAgICAgIGlmIChjbGFzc05hbWUgIT0gbnVsbCAmJiAhY2xhc3NOYW1lLmVxdWFscygiIikpCi0gICAgICAgICAgICAgIGNsYXNzTmFtZSA9IGNsYXNzTmFtZSArICIuIiArIGZ1bmN0aW9uTmFtZS5zdWJzdHJpbmcoMCwgbGFzdERvdEluZGV4KTsKLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgY2xhc3NOYW1lID0gZnVuY3Rpb25OYW1lLnN1YnN0cmluZygwLCBsYXN0RG90SW5kZXgpOwotICAgICAgICAgIH0KLSAgICAgICAgICBlbHNlCi0gICAgICAgICAgICBtZXRob2ROYW1lID0gZnVuY3Rpb25OYW1lOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICBtZXRob2ROYW1lID0gX25hbWVPZkZ1bmN0OwotCi0gICAgICAgIGlmIChjbGFzc05hbWUgPT0gbnVsbCB8fCBtZXRob2ROYW1lID09IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIFJlcGxhY2UgdGhlICctJyBjaGFyYWN0ZXJzIGluIHRoZSBtZXRob2QgbmFtZQotICAgICAgICBpZiAobWV0aG9kTmFtZS5pbmRleE9mKCctJykgPiAwKQotICAgICAgICAgIG1ldGhvZE5hbWUgPSByZXBsYWNlRGFzaChtZXRob2ROYW1lKTsKLQotICAgICAgICB0cnkgewotICAgICAgICAgICAgZmluYWwgQ2xhc3MgY2xhenogPSBPYmplY3RGYWN0b3J5LmZpbmRQcm92aWRlckNsYXNzKGNsYXNzTmFtZSwgdHJ1ZSk7Ci0KLSAgICAgICAgICAgIGlmIChjbGF6eiA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBmaW5hbCBNZXRob2RbXSBtZXRob2RzID0gY2xhenouZ2V0TWV0aG9kcygpOwotCi0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1ldGhvZHMubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgICAgICBmaW5hbCBpbnQgbW9kcyA9IG1ldGhvZHNbaV0uZ2V0TW9kaWZpZXJzKCk7Ci0KLSAgICAgICAgICAgICAgICBpZiAoTW9kaWZpZXIuaXNQdWJsaWMobW9kcykgJiYgTW9kaWZpZXIuaXNTdGF0aWMobW9kcykKLSAgICAgICAgICAgICAgICAgICAgICAgICYmIG1ldGhvZHNbaV0uZ2V0TmFtZSgpLmVxdWFscyhtZXRob2ROYW1lKSkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXBvcnRzIG9uIHdoZXRoZXIgdGhlIGZ1bmN0aW9uIHNwZWNpZmllZCBpbiB0aGUgYXJndW1lbnQgdG8KLSAgICAgKiB4c2x0IGZ1bmN0aW9uICdmdW5jdGlvbi1hdmFpbGFibGUnIHdhcyBmb3VuZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXRSZXN1bHQoKSB7Ci0gICAgICAgIGlmIChfbmFtZU9mRnVuY3QgPT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKGlzSW50ZXJuYWxOYW1lc3BhY2UoKSkgewotICAgICAgICAgICAgZmluYWwgUGFyc2VyIHBhcnNlciA9IGdldFBhcnNlcigpOwotICAgICAgICAgICAgX2lzRnVuY3Rpb25BdmFpbGFibGUgPQotICAgICAgICAgICAgICAgIHBhcnNlci5mdW5jdGlvblN1cHBvcnRlZChVdGlsLmdldExvY2FsTmFtZShfbmFtZU9mRnVuY3QpKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gX2lzRnVuY3Rpb25BdmFpbGFibGU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRydWUgaWYgdGhlIG5hbWVzcGFjZSB1cmkgaXMgbnVsbCBvciBpdCBpcyB0aGUgWFNMVEMgdHJhbnNsZXQgdXJpLgotICAgICAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBpc0ludGVybmFsTmFtZXNwYWNlKCkgewotICAgICAgICByZXR1cm4gKF9uYW1lc3BhY2VPZkZ1bmN0ID09IG51bGwgfHwKLSAgICAgICAgICAgIF9uYW1lc3BhY2VPZkZ1bmN0LmVxdWFscyhFTVBUWVNUUklORykgfHwKLSAgICAgICAgICAgIF9uYW1lc3BhY2VPZkZ1bmN0LmVxdWFscyhUUkFOU0xFVF9VUkkpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDYWxscyB0byAnZnVuY3Rpb24tYXZhaWxhYmxlJyBhcmUgcmVzb2x2ZWQgYXQgY29tcGlsZSB0aW1lIHNpbmNlCi0gICAgICogdGhlIG5hbWVzcGFjZXMgZGVjbGFyZWQgaW4gdGhlIHN0eWxzaGVldCBhcmUgbm90IGF2YWlsYWJsZSBhdCBydW4KLSAgICAgKiB0aW1lLiBDb25zZXF1ZW50bHksIGFyZ3VtZW50cyB0byB0aGlzIGZ1bmN0aW9uIG11c3QgYmUgbGl0ZXJhbHMuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0gICAgICAgIGZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLSAgICAgICAgbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpLmFwcGVuZChuZXcgUFVTSChjcGcsIGdldFJlc3VsdCgpKSk7Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0Z1bmN0aW9uQ2FsbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9GdW5jdGlvbkNhbGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMTFiMzI0MS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0Z1bmN0aW9uQ2FsbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTE0OCArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDE1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICovCi0vKgotICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCi0gKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKLSAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KLSAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCi0gKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAotICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBGdW5jdGlvbkNhbGwuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xMiAxMDozMTozMiBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkNvbnN0YW50UG9vbEdlbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklGRVE7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JTlZPS0VJTlRFUkZBQ0U7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JTlZPS0VTUEVDSUFMOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFU1RBVElDOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFVklSVFVBTDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW5zdHJ1Y3Rpb25MaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW52b2tlSW5zdHJ1Y3Rpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5Mb2NhbFZhcmlhYmxlR2VuOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuTkVXOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuUFVTSDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwudXRpbHMuRmVhdHVyZU1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnV0aWxzLk9iamVjdEZhY3Rvcnk7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuQm9vbGVhblR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuQ2xhc3NHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuRXJyb3JNc2c7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuSW50VHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5NZXRob2RHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuTWV0aG9kVHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5NdWx0aUhhc2h0YWJsZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5PYmplY3RUeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlJlZmVyZW5jZVR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlQ2hlY2tFcnJvcjsKLWltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3RvcjsKLWltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2Q7Ci1pbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuTW9kaWZpZXI7Ci1pbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOwotaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKLWltcG9ydCBqYXZhLnV0aWwuTWFwOwotaW1wb3J0IGphdmEudXRpbC5PYmplY3RzOwotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLS8qKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKiBAYXV0aG9yIEVyd2luIEJvbHdpZHQgPGVqYkBrbG9tcC5vcmc+Ci0gKiBAYXV0aG9yIFRvZGQgTWlsbGVyCi0gKi8KLWNsYXNzIEZ1bmN0aW9uQ2FsbCBleHRlbmRzIEV4cHJlc3Npb24gewotCi0gICAgLy8gTmFtZSBvZiB0aGlzIGZ1bmN0aW9uIGNhbGwKLSAgICBwcml2YXRlIFFOYW1lICBfZm5hbWU7Ci0gICAgLy8gQXJndW1lbnRzIHRvIHRoaXMgZnVuY3Rpb24gY2FsbCAobWlnaHQgbm90IGJlIGFueSkKLSAgICBwcml2YXRlIGZpbmFsIFZlY3RvciBfYXJndW1lbnRzOwotICAgIC8vIEVtcHR5IGFyZ3VtZW50IGxpc3QsIHVzZWQgZm9yIGNlcnRhaW4gZnVuY3Rpb25zCi0gICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgVmVjdG9yIEVNUFRZX0FSR19MSVNUID0gbmV3IFZlY3RvcigwKTsKLQotICAgIC8vIFZhbGlkIG5hbWVzcGFjZXMgZm9yIEphdmEgZnVuY3Rpb24tY2FsbCBleHRlbnNpb24KLSAgICBwcm90ZWN0ZWQgZmluYWwgc3RhdGljIFN0cmluZyBFWFRfWFNMVEMgPQotICAgICAgICBUUkFOU0xFVF9VUkk7Ci0KLSAgICBwcm90ZWN0ZWQgZmluYWwgc3RhdGljIFN0cmluZyBKQVZBX0VYVF9YU0xUQyA9Ci0gICAgICAgIEVYVF9YU0xUQyArICIvamF2YSI7Ci0KLSAgICBwcm90ZWN0ZWQgZmluYWwgc3RhdGljIFN0cmluZyBFWFRfWEFMQU4gPQotICAgICAgICAiaHR0cDovL3htbC5hcGFjaGUub3JnL3hhbGFuIjsKLQotICAgIHByb3RlY3RlZCBmaW5hbCBzdGF0aWMgU3RyaW5nIEpBVkFfRVhUX1hBTEFOID0KLSAgICAgICAgImh0dHA6Ly94bWwuYXBhY2hlLm9yZy94YWxhbi9qYXZhIjsKLQotICAgIHByb3RlY3RlZCBmaW5hbCBzdGF0aWMgU3RyaW5nIEpBVkFfRVhUX1hBTEFOX09MRCA9Ci0gICAgICAgICJodHRwOi8veG1sLmFwYWNoZS5vcmcveHNsdC9qYXZhIjsKLQotICAgIHByb3RlY3RlZCBmaW5hbCBzdGF0aWMgU3RyaW5nIEVYU0xUX0NPTU1PTiA9Ci0gICAgICAgICJodHRwOi8vZXhzbHQub3JnL2NvbW1vbiI7Ci0KLSAgICBwcm90ZWN0ZWQgZmluYWwgc3RhdGljIFN0cmluZyBFWFNMVF9NQVRIID0KLSAgICAgICAgImh0dHA6Ly9leHNsdC5vcmcvbWF0aCI7Ci0KLSAgICBwcm90ZWN0ZWQgZmluYWwgc3RhdGljIFN0cmluZyBFWFNMVF9TRVRTID0KLSAgICAgICAgImh0dHA6Ly9leHNsdC5vcmcvc2V0cyI7Ci0KLSAgICBwcm90ZWN0ZWQgZmluYWwgc3RhdGljIFN0cmluZyBFWFNMVF9EQVRFVElNRSA9Ci0gICAgICAgICJodHRwOi8vZXhzbHQub3JnL2RhdGVzLWFuZC10aW1lcyI7Ci0KLSAgICBwcm90ZWN0ZWQgZmluYWwgc3RhdGljIFN0cmluZyBFWFNMVF9TVFJJTkdTID0KLSAgICAgICAgImh0dHA6Ly9leHNsdC5vcmcvc3RyaW5ncyI7Ci0KLSAgICBwcm90ZWN0ZWQgZmluYWwgc3RhdGljIFN0cmluZyBYQUxBTl9DTEFTU1BBQ0tBR0VfTkFNRVNQQUNFID0KLSAgICAgICAgInhhbGFuOi8vIjsKLQotICAgIC8vIE5hbWVzcGFjZSBmb3JtYXQgY29uc3RhbnRzCi0gICAgcHJvdGVjdGVkIGZpbmFsIHN0YXRpYyBpbnQgTkFNRVNQQUNFX0ZPUk1BVF9KQVZBID0gMDsKLSAgICBwcm90ZWN0ZWQgZmluYWwgc3RhdGljIGludCBOQU1FU1BBQ0VfRk9STUFUX0NMQVNTID0gMTsKLSAgICBwcm90ZWN0ZWQgZmluYWwgc3RhdGljIGludCBOQU1FU1BBQ0VfRk9STUFUX1BBQ0tBR0UgPSAyOwotICAgIHByb3RlY3RlZCBmaW5hbCBzdGF0aWMgaW50IE5BTUVTUEFDRV9GT1JNQVRfQ0xBU1NfT1JfUEFDS0FHRSA9IDM7Ci0KLSAgICAvLyBOYW1lc3BhY2UgZm9ybWF0Ci0gICAgcHJpdmF0ZSBpbnQgX25hbWVzcGFjZV9mb3JtYXQgPSBOQU1FU1BBQ0VfRk9STUFUX0pBVkE7Ci0KLSAgICAvKioKLSAgICAgKiBTdG9yZXMgcmVmZXJlbmNlIHRvIG9iamVjdCBmb3Igbm9uLXN0YXRpYyBKYXZhIGNhbGxzCi0gICAgICovCi0gICAgRXhwcmVzc2lvbiBfdGhpc0FyZ3VtZW50ID0gbnVsbDsKLQotICAgIC8vIEV4dGVybmFsIEphdmEgZnVuY3Rpb24ncyBjbGFzcy9tZXRob2Qvc2lnbmF0dXJlCi0gICAgcHJpdmF0ZSBTdHJpbmcgICAgICBfY2xhc3NOYW1lOwotICAgIHByaXZhdGUgQ2xhc3MgICAgICAgX2NsYXp6OwotICAgIHByaXZhdGUgTWV0aG9kICAgICAgX2Nob3Nlbk1ldGhvZDsKLSAgICBwcml2YXRlIENvbnN0cnVjdG9yIF9jaG9zZW5Db25zdHJ1Y3RvcjsKLSAgICBwcml2YXRlIE1ldGhvZFR5cGUgIF9jaG9zZW5NZXRob2RUeXBlOwotCi0gICAgLy8gRW5jYXBzdWxhdGVzIGFsbCB1bnN1cHBvcnRlZCBleHRlcm5hbCBmdW5jdGlvbiBjYWxscwotICAgIHByaXZhdGUgYm9vbGVhbiAgICB1bnJlc29sdmVkRXh0ZXJuYWw7Ci0KLSAgICAvLyBJZiBGdW5jdGlvbkNhbGwgaXMgYSBleHRlcm5hbCBqYXZhIGNvbnN0cnVjdG9yCi0gICAgcHJpdmF0ZSBib29sZWFuICAgICBfaXNFeHRDb25zdHJ1Y3RvciA9IGZhbHNlOwotCi0gICAgLy8gSWYgdGhlIGphdmEgbWV0aG9kIGlzIHN0YXRpYwotICAgIHByaXZhdGUgYm9vbGVhbiAgICAgICBfaXNTdGF0aWMgPSBmYWxzZTsKLQotICAgIC8vIExlZ2FsIGNvbnZlcnNpb25zIGJldHdlZW4gaW50ZXJuYWwgYW5kIEphdmEgdHlwZXMuCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTXVsdGlIYXNodGFibGU8VHlwZSwgSmF2YVR5cGU+IF9pbnRlcm5hbDJKYXZhID0gbmV3IE11bHRpSGFzaHRhYmxlPD4oKTsKLQotICAgIC8vIExlZ2FsIGNvbnZlcnNpb25zIGJldHdlZW4gSmF2YSBhbmQgaW50ZXJuYWwgdHlwZXMuCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTWFwPENsYXNzPD8+LCBUeXBlPiBKQVZBMklOVEVSTkFMOwotCi0gICAgLy8gVGhlIG1hcHBpbmdzIGJldHdlZW4gRVhTTFQgZXh0ZW5zaW9uIG5hbWVzcGFjZXMgYW5kIGltcGxlbWVudGF0aW9uIGNsYXNzZXMKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBNYXA8U3RyaW5nLCBTdHJpbmc+IEVYVEVOU0lPTk5BTUVTUEFDRTsKLQotICAgIC8vIEV4dGVuc2lvbiBmdW5jdGlvbnMgdGhhdCBhcmUgaW1wbGVtZW50ZWQgaW4gQmFzaXNMaWJyYXJ5Ci0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTWFwPFN0cmluZywgU3RyaW5nPiBFWFRFTlNJT05GVU5DVElPTjsKLSAgICAvKioKLSAgICAgKiBpbm5lciBjbGFzcyB0byB1c2VkIGluIGludGVybmFsMkphdmEgbWFwcGluZ3MsIGNvbnRhaW5zCi0gICAgICogdGhlIEphdmEgdHlwZSBhbmQgdGhlIGRpc3RhbmNlIGJldHdlZW4gdGhlIGludGVybmFsIHR5cGUgYW5kCi0gICAgICogdGhlIEphdmEgdHlwZS4KLSAgICAgKi8KLSAgICBzdGF0aWMgY2xhc3MgSmF2YVR5cGUgewotICAgICAgICBwdWJsaWMgQ2xhc3M8Pz4gIHR5cGU7Ci0gICAgICAgIHB1YmxpYyBpbnQgZGlzdGFuY2U7Ci0KLSAgICAgICAgcHVibGljIEphdmFUeXBlKENsYXNzIHR5cGUsIGludCBkaXN0YW5jZSl7Ci0gICAgICAgICAgICB0aGlzLnR5cGUgPSB0eXBlOwotICAgICAgICAgICAgdGhpcy5kaXN0YW5jZSA9IGRpc3RhbmNlOwotICAgICAgICB9Ci0KLSAgICAgICAgQE92ZXJyaWRlCi0gICAgICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7Ci0gICAgICAgICAgICByZXR1cm4gT2JqZWN0cy5oYXNoQ29kZSh0aGlzLnR5cGUpOwotICAgICAgICB9Ci0KLSAgICAgICAgQE92ZXJyaWRlCi0gICAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgcXVlcnkpIHsKLSAgICAgICAgICAgIGlmIChxdWVyeSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKHF1ZXJ5LmdldENsYXNzKCkuaXNBc3NpZ25hYmxlRnJvbShKYXZhVHlwZS5jbGFzcykpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gKChKYXZhVHlwZSlxdWVyeSkudHlwZS5lcXVhbHModHlwZSk7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIHJldHVybiBxdWVyeS5lcXVhbHModHlwZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBEZWZpbmVzIDIgY29udmVyc2lvbiB0YWJsZXM6Ci0gICAgICogMS4gRnJvbSBpbnRlcm5hbCB0eXBlcyB0byBKYXZhIHR5cGVzIGFuZAotICAgICAqIDIuIEZyb20gSmF2YSB0eXBlcyB0byBpbnRlcm5hbCB0eXBlcy4KLSAgICAgKiBUaGVzZSB0d28gdGFibGVzIGFyZSB1c2VkIHdoZW4gY2FsbGluZyBleHRlcm5hbCAoSmF2YSkgZnVuY3Rpb25zLgotICAgICAqLwotICAgIHN0YXRpYyB7Ci0gICAgICAgIGZpbmFsIENsYXNzPD8+IG5vZGVDbGFzcywgbm9kZUxpc3RDbGFzczsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIG5vZGVDbGFzcyAgICAgPSBDbGFzcy5mb3JOYW1lKCJvcmcudzNjLmRvbS5Ob2RlIik7Ci0gICAgICAgICAgICBub2RlTGlzdENsYXNzID0gQ2xhc3MuZm9yTmFtZSgib3JnLnczYy5kb20uTm9kZUxpc3QiKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICBFcnJvck1zZyBlcnIgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuQ0xBU1NfTk9UX0ZPVU5EX0VSUiwib3JnLnczYy5kb20uTm9kZSBvciBOb2RlTGlzdCIpOwotICAgICAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbkluSW5pdGlhbGl6ZXJFcnJvcihlcnIudG9TdHJpbmcoKSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyAtLSBJbnRlcm5hbCB0byBKYXZhIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0KLSAgICAgICAgLy8gVHlwZS5Cb29sZWFuIC0+IHsgYm9vbGVhbigwKSwgQm9vbGVhbigxKSwgT2JqZWN0KDIpIH0KLSAgICAgICAgX2ludGVybmFsMkphdmEucHV0KFR5cGUuQm9vbGVhbiwgbmV3IEphdmFUeXBlKEJvb2xlYW4uVFlQRSwgMCkpOwotICAgICAgICBfaW50ZXJuYWwySmF2YS5wdXQoVHlwZS5Cb29sZWFuLCBuZXcgSmF2YVR5cGUoQm9vbGVhbi5jbGFzcywgMSkpOwotICAgICAgICBfaW50ZXJuYWwySmF2YS5wdXQoVHlwZS5Cb29sZWFuLCBuZXcgSmF2YVR5cGUoT2JqZWN0LmNsYXNzLCAyKSk7Ci0KLSAgICAgICAgLy8gVHlwZS5SZWFsIC0+IHsgZG91YmxlKDApLCBEb3VibGUoMSksIGZsb2F0KDIpLCBsb25nKDMpLCBpbnQoNCksCi0gICAgICAgIC8vICAgICAgICAgICAgICAgIHNob3J0KDUpLCBieXRlKDYpLCBjaGFyKDcpLCBPYmplY3QoOCkgfQotICAgICAgICBfaW50ZXJuYWwySmF2YS5wdXQoVHlwZS5SZWFsLCBuZXcgSmF2YVR5cGUoRG91YmxlLlRZUEUsIDApKTsKLSAgICAgICAgX2ludGVybmFsMkphdmEucHV0KFR5cGUuUmVhbCwgbmV3IEphdmFUeXBlKERvdWJsZS5jbGFzcywgMSkpOwotICAgICAgICBfaW50ZXJuYWwySmF2YS5wdXQoVHlwZS5SZWFsLCBuZXcgSmF2YVR5cGUoRmxvYXQuVFlQRSwgMikpOwotICAgICAgICBfaW50ZXJuYWwySmF2YS5wdXQoVHlwZS5SZWFsLCBuZXcgSmF2YVR5cGUoTG9uZy5UWVBFLCAzKSk7Ci0gICAgICAgIF9pbnRlcm5hbDJKYXZhLnB1dChUeXBlLlJlYWwsIG5ldyBKYXZhVHlwZShJbnRlZ2VyLlRZUEUsIDQpKTsKLSAgICAgICAgX2ludGVybmFsMkphdmEucHV0KFR5cGUuUmVhbCwgbmV3IEphdmFUeXBlKFNob3J0LlRZUEUsIDUpKTsKLSAgICAgICAgX2ludGVybmFsMkphdmEucHV0KFR5cGUuUmVhbCwgbmV3IEphdmFUeXBlKEJ5dGUuVFlQRSwgNikpOwotICAgICAgICBfaW50ZXJuYWwySmF2YS5wdXQoVHlwZS5SZWFsLCBuZXcgSmF2YVR5cGUoQ2hhcmFjdGVyLlRZUEUsIDcpKTsKLSAgICAgICAgX2ludGVybmFsMkphdmEucHV0KFR5cGUuUmVhbCwgbmV3IEphdmFUeXBlKE9iamVjdC5jbGFzcywgOCkpOwotCi0gICAgICAgIC8vIFR5cGUuSW50IG11c3QgYmUgdGhlIHNhbWUgYXMgVHlwZS5SZWFsCi0gICAgICAgIF9pbnRlcm5hbDJKYXZhLnB1dChUeXBlLkludCwgbmV3IEphdmFUeXBlKERvdWJsZS5UWVBFLCAwKSk7Ci0gICAgICAgIF9pbnRlcm5hbDJKYXZhLnB1dChUeXBlLkludCwgbmV3IEphdmFUeXBlKERvdWJsZS5jbGFzcywgMSkpOwotICAgICAgICBfaW50ZXJuYWwySmF2YS5wdXQoVHlwZS5JbnQsIG5ldyBKYXZhVHlwZShGbG9hdC5UWVBFLCAyKSk7Ci0gICAgICAgIF9pbnRlcm5hbDJKYXZhLnB1dChUeXBlLkludCwgbmV3IEphdmFUeXBlKExvbmcuVFlQRSwgMykpOwotICAgICAgICBfaW50ZXJuYWwySmF2YS5wdXQoVHlwZS5JbnQsIG5ldyBKYXZhVHlwZShJbnRlZ2VyLlRZUEUsIDQpKTsKLSAgICAgICAgX2ludGVybmFsMkphdmEucHV0KFR5cGUuSW50LCBuZXcgSmF2YVR5cGUoU2hvcnQuVFlQRSwgNSkpOwotICAgICAgICBfaW50ZXJuYWwySmF2YS5wdXQoVHlwZS5JbnQsIG5ldyBKYXZhVHlwZShCeXRlLlRZUEUsIDYpKTsKLSAgICAgICAgX2ludGVybmFsMkphdmEucHV0KFR5cGUuSW50LCBuZXcgSmF2YVR5cGUoQ2hhcmFjdGVyLlRZUEUsIDcpKTsKLSAgICAgICAgX2ludGVybmFsMkphdmEucHV0KFR5cGUuSW50LCBuZXcgSmF2YVR5cGUoT2JqZWN0LmNsYXNzLCA4KSk7Ci0KLSAgICAgICAgLy8gVHlwZS5TdHJpbmcgLT4geyBTdHJpbmcoMCksIE9iamVjdCgxKSB9Ci0gICAgICAgIF9pbnRlcm5hbDJKYXZhLnB1dChUeXBlLlN0cmluZywgbmV3IEphdmFUeXBlKFN0cmluZy5jbGFzcywgMCkpOwotICAgICAgICBfaW50ZXJuYWwySmF2YS5wdXQoVHlwZS5TdHJpbmcsIG5ldyBKYXZhVHlwZShPYmplY3QuY2xhc3MsIDEpKTsKLQotICAgICAgICAvLyBUeXBlLk5vZGVTZXQgLT4geyBOb2RlTGlzdCgwKSwgTm9kZSgxKSwgT2JqZWN0KDIpLCBTdHJpbmcoMykgfQotICAgICAgICBfaW50ZXJuYWwySmF2YS5wdXQoVHlwZS5Ob2RlU2V0LCBuZXcgSmF2YVR5cGUobm9kZUxpc3RDbGFzcywgMCkpOwotICAgICAgICBfaW50ZXJuYWwySmF2YS5wdXQoVHlwZS5Ob2RlU2V0LCBuZXcgSmF2YVR5cGUobm9kZUNsYXNzLCAxKSk7Ci0gICAgICAgIF9pbnRlcm5hbDJKYXZhLnB1dChUeXBlLk5vZGVTZXQsIG5ldyBKYXZhVHlwZShPYmplY3QuY2xhc3MsIDIpKTsKLSAgICAgICAgX2ludGVybmFsMkphdmEucHV0KFR5cGUuTm9kZVNldCwgbmV3IEphdmFUeXBlKFN0cmluZy5jbGFzcywgMykpOwotCi0gICAgICAgIC8vIFR5cGUuTm9kZSAtPiB7IE5vZGUoMCksIE5vZGVMaXN0KDEpLCBPYmplY3QoMiksIFN0cmluZygzKSB9Ci0gICAgICAgIF9pbnRlcm5hbDJKYXZhLnB1dChUeXBlLk5vZGUsIG5ldyBKYXZhVHlwZShub2RlTGlzdENsYXNzLCAwKSk7Ci0gICAgICAgIF9pbnRlcm5hbDJKYXZhLnB1dChUeXBlLk5vZGUsIG5ldyBKYXZhVHlwZShub2RlQ2xhc3MsIDEpKTsKLSAgICAgICAgX2ludGVybmFsMkphdmEucHV0KFR5cGUuTm9kZSwgbmV3IEphdmFUeXBlKE9iamVjdC5jbGFzcywgMikpOwotICAgICAgICBfaW50ZXJuYWwySmF2YS5wdXQoVHlwZS5Ob2RlLCBuZXcgSmF2YVR5cGUoU3RyaW5nLmNsYXNzLCAzKSk7Ci0KLSAgICAgICAgLy8gVHlwZS5SZXN1bHRUcmVlIC0+IHsgTm9kZUxpc3QoMCksIE5vZGUoMSksIE9iamVjdCgyKSwgU3RyaW5nKDMpIH0KLSAgICAgICAgX2ludGVybmFsMkphdmEucHV0KFR5cGUuUmVzdWx0VHJlZSwgbmV3IEphdmFUeXBlKG5vZGVMaXN0Q2xhc3MsIDApKTsKLSAgICAgICAgX2ludGVybmFsMkphdmEucHV0KFR5cGUuUmVzdWx0VHJlZSwgbmV3IEphdmFUeXBlKG5vZGVDbGFzcywgMSkpOwotICAgICAgICBfaW50ZXJuYWwySmF2YS5wdXQoVHlwZS5SZXN1bHRUcmVlLCBuZXcgSmF2YVR5cGUoT2JqZWN0LmNsYXNzLCAyKSk7Ci0gICAgICAgIF9pbnRlcm5hbDJKYXZhLnB1dChUeXBlLlJlc3VsdFRyZWUsIG5ldyBKYXZhVHlwZShTdHJpbmcuY2xhc3MsIDMpKTsKLQotICAgICAgICBfaW50ZXJuYWwySmF2YS5wdXQoVHlwZS5SZWZlcmVuY2UsIG5ldyBKYXZhVHlwZShPYmplY3QuY2xhc3MsIDApKTsKLQotICAgICAgICBfaW50ZXJuYWwySmF2YS5tYWtlVW5tb2RpZmlhYmxlKCk7Ci0KLSAgICAgICAgTWFwPENsYXNzPD8+LCBUeXBlPiBqYXZhMkludGVybmFsID0gbmV3IEhhc2hNYXA8PigpOwotICAgICAgICBNYXA8U3RyaW5nLCBTdHJpbmc+IGV4dGVuc2lvbk5hbWVzcGFjZVRhYmxlID0gbmV3IEhhc2hNYXA8PigpOwotICAgICAgICBNYXA8U3RyaW5nLCBTdHJpbmc+IGV4dGVuc2lvbkZ1bmN0aW9uVGFibGUgPSBuZXcgSGFzaE1hcDw+KCk7Ci0KLSAgICAgICAgLy8gUG9zc2libGUgY29udmVyc2lvbnMgYmV0d2VlbiBKYXZhIGFuZCBpbnRlcm5hbCB0eXBlcwotICAgICAgICBqYXZhMkludGVybmFsLnB1dChCb29sZWFuLlRZUEUsIFR5cGUuQm9vbGVhbik7Ci0gICAgICAgIGphdmEySW50ZXJuYWwucHV0KFZvaWQuVFlQRSwgVHlwZS5Wb2lkKTsKLSAgICAgICAgamF2YTJJbnRlcm5hbC5wdXQoQ2hhcmFjdGVyLlRZUEUsIFR5cGUuUmVhbCk7Ci0gICAgICAgIGphdmEySW50ZXJuYWwucHV0KEJ5dGUuVFlQRSwgVHlwZS5SZWFsKTsKLSAgICAgICAgamF2YTJJbnRlcm5hbC5wdXQoU2hvcnQuVFlQRSwgVHlwZS5SZWFsKTsKLSAgICAgICAgamF2YTJJbnRlcm5hbC5wdXQoSW50ZWdlci5UWVBFLCBUeXBlLlJlYWwpOwotICAgICAgICBqYXZhMkludGVybmFsLnB1dChMb25nLlRZUEUsIFR5cGUuUmVhbCk7Ci0gICAgICAgIGphdmEySW50ZXJuYWwucHV0KEZsb2F0LlRZUEUsIFR5cGUuUmVhbCk7Ci0gICAgICAgIGphdmEySW50ZXJuYWwucHV0KERvdWJsZS5UWVBFLCBUeXBlLlJlYWwpOwotCi0gICAgICAgIGphdmEySW50ZXJuYWwucHV0KFN0cmluZy5jbGFzcywgVHlwZS5TdHJpbmcpOwotCi0gICAgICAgIGphdmEySW50ZXJuYWwucHV0KE9iamVjdC5jbGFzcywgVHlwZS5SZWZlcmVuY2UpOwotCi0gICAgICAgIC8vIENvbnZlcnNpb25zIGZyb20gb3JnLnczYy5kb20uTm9kZS9Ob2RlTGlzdCB0byBpbnRlcm5hbCBOb2RlU2V0Ci0gICAgICAgIGphdmEySW50ZXJuYWwucHV0KG5vZGVMaXN0Q2xhc3MsIFR5cGUuTm9kZVNldCk7Ci0gICAgICAgIGphdmEySW50ZXJuYWwucHV0KG5vZGVDbGFzcywgVHlwZS5Ob2RlU2V0KTsKLQotICAgICAgICAvLyBJbml0aWFsaXplIHRoZSBleHRlbnNpb24gbmFtZXNwYWNlIHRhYmxlCi0gICAgICAgIGV4dGVuc2lvbk5hbWVzcGFjZVRhYmxlLnB1dChFWFRfWEFMQU4sICJjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwubGliLkV4dGVuc2lvbnMiKTsKLSAgICAgICAgZXh0ZW5zaW9uTmFtZXNwYWNlVGFibGUucHV0KEVYU0xUX0NPTU1PTiwgImNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC5saWIuRXhzbHRDb21tb24iKTsKLSAgICAgICAgZXh0ZW5zaW9uTmFtZXNwYWNlVGFibGUucHV0KEVYU0xUX01BVEgsICJjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwubGliLkV4c2x0TWF0aCIpOwotICAgICAgICBleHRlbnNpb25OYW1lc3BhY2VUYWJsZS5wdXQoRVhTTFRfU0VUUywgImNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC5saWIuRXhzbHRTZXRzIik7Ci0gICAgICAgIGV4dGVuc2lvbk5hbWVzcGFjZVRhYmxlLnB1dChFWFNMVF9EQVRFVElNRSwgImNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC5saWIuRXhzbHREYXRldGltZSIpOwotICAgICAgICBleHRlbnNpb25OYW1lc3BhY2VUYWJsZS5wdXQoRVhTTFRfU1RSSU5HUywgImNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC5saWIuRXhzbHRTdHJpbmdzIik7Ci0KLSAgICAgICAgLy8gSW5pdGlhbGl6ZSB0aGUgZXh0ZW5zaW9uIGZ1bmN0aW9uIHRhYmxlCi0gICAgICAgIGV4dGVuc2lvbkZ1bmN0aW9uVGFibGUucHV0KEVYU0xUX0NPTU1PTiArICI6bm9kZVNldCIsICJub2Rlc2V0Iik7Ci0gICAgICAgIGV4dGVuc2lvbkZ1bmN0aW9uVGFibGUucHV0KEVYU0xUX0NPTU1PTiArICI6b2JqZWN0VHlwZSIsICJvYmplY3RUeXBlIik7Ci0gICAgICAgIGV4dGVuc2lvbkZ1bmN0aW9uVGFibGUucHV0KEVYVF9YQUxBTiArICI6bm9kZXNldCIsICJub2Rlc2V0Iik7Ci0KLSAgICAgICAgSkFWQTJJTlRFUk5BTCA9IENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZU1hcChqYXZhMkludGVybmFsKTsKLSAgICAgICAgRVhURU5TSU9OTkFNRVNQQUNFID0gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTWFwKGV4dGVuc2lvbk5hbWVzcGFjZVRhYmxlKTsKLSAgICAgICAgRVhURU5TSU9ORlVOQ1RJT04gPSBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVNYXAoZXh0ZW5zaW9uRnVuY3Rpb25UYWJsZSk7Ci0KLSAgICB9Ci0KLSAgICBwdWJsaWMgRnVuY3Rpb25DYWxsKFFOYW1lIGZuYW1lLCBWZWN0b3IgYXJndW1lbnRzKSB7Ci0gICAgICAgIF9mbmFtZSA9IGZuYW1lOwotICAgICAgICBfYXJndW1lbnRzID0gYXJndW1lbnRzOwotICAgICAgICBfdHlwZSA9IG51bGw7Ci0gICAgfQotCi0gICAgcHVibGljIEZ1bmN0aW9uQ2FsbChRTmFtZSBmbmFtZSkgewotICAgICAgICB0aGlzKGZuYW1lLCBFTVBUWV9BUkdfTElTVCk7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXROYW1lKCkgewotICAgICAgICByZXR1cm4oX2ZuYW1lLnRvU3RyaW5nKCkpOwotICAgIH0KLQotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyB2b2lkIHNldFBhcnNlcihQYXJzZXIgcGFyc2VyKSB7Ci0gICAgICAgIHN1cGVyLnNldFBhcnNlcihwYXJzZXIpOwotICAgICAgICBpZiAoX2FyZ3VtZW50cyAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmaW5hbCBpbnQgbiA9IF9hcmd1bWVudHMuc2l6ZSgpOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspIHsKLSAgICAgICAgICAgICAgICBmaW5hbCBFeHByZXNzaW9uIGV4cCA9IChFeHByZXNzaW9uKV9hcmd1bWVudHMuZWxlbWVudEF0KGkpOwotICAgICAgICAgICAgICAgIGV4cC5zZXRQYXJzZXIocGFyc2VyKTsKLSAgICAgICAgICAgICAgICBleHAuc2V0UGFyZW50KHRoaXMpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRDbGFzc05hbWVGcm9tVXJpKFN0cmluZyB1cmkpCi0gICAgewotICAgICAgICBTdHJpbmcgY2xhc3NOYW1lID0gRVhURU5TSU9OTkFNRVNQQUNFLmdldCh1cmkpOwotCi0gICAgICAgIGlmIChjbGFzc05hbWUgIT0gbnVsbCkKLSAgICAgICAgICAgIHJldHVybiBjbGFzc05hbWU7Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgaWYgKHVyaS5zdGFydHNXaXRoKEpBVkFfRVhUX1hTTFRDKSkgewotICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBKQVZBX0VYVF9YU0xUQy5sZW5ndGgoKSArIDE7Ci0gICAgICAgICAgICAgICAgcmV0dXJuICh1cmkubGVuZ3RoKCkgPiBsZW5ndGgpID8gdXJpLnN1YnN0cmluZyhsZW5ndGgpIDogRU1QVFlTVFJJTkc7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmICh1cmkuc3RhcnRzV2l0aChKQVZBX0VYVF9YQUxBTikpIHsKLSAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gSkFWQV9FWFRfWEFMQU4ubGVuZ3RoKCkgKyAxOwotICAgICAgICAgICAgICAgIHJldHVybiAodXJpLmxlbmd0aCgpID4gbGVuZ3RoKSA/IHVyaS5zdWJzdHJpbmcobGVuZ3RoKSA6IEVNUFRZU1RSSU5HOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAodXJpLnN0YXJ0c1dpdGgoSkFWQV9FWFRfWEFMQU5fT0xEKSkgewotICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBKQVZBX0VYVF9YQUxBTl9PTEQubGVuZ3RoKCkgKyAxOwotICAgICAgICAgICAgICAgIHJldHVybiAodXJpLmxlbmd0aCgpID4gbGVuZ3RoKSA/IHVyaS5zdWJzdHJpbmcobGVuZ3RoKSA6IEVNUFRZU1RSSU5HOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgaW50IGluZGV4ID0gdXJpLmxhc3RJbmRleE9mKCcvJyk7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIChpbmRleCA+IDApID8gdXJpLnN1YnN0cmluZyhpbmRleCsxKSA6IHVyaTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFR5cGUgY2hlY2sgYSBmdW5jdGlvbiBjYWxsLiBTaW5jZSBkaWZmZXJlbnQgdHlwZSBjb252ZXJzaW9ucyBhcHBseSwKLSAgICAgKiB0eXBlIGNoZWNraW5nIGlzIGRpZmZlcmVudCBmb3Igc3RhbmRhcmQgYW5kIGV4dGVybmFsIChKYXZhKSBmdW5jdGlvbnMuCi0gICAgICovCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkKLSAgICAgICAgdGhyb3dzIFR5cGVDaGVja0Vycm9yCi0gICAgewotICAgICAgICBpZiAoX3R5cGUgIT0gbnVsbCkgcmV0dXJuIF90eXBlOwotCi0gICAgICAgIGZpbmFsIFN0cmluZyBuYW1lc3BhY2UgPSBfZm5hbWUuZ2V0TmFtZXNwYWNlKCk7Ci0gICAgICAgIFN0cmluZyBsb2NhbCA9IF9mbmFtZS5nZXRMb2NhbFBhcnQoKTsKLQotICAgICAgICBpZiAoaXNFeHRlbnNpb24oKSkgewotICAgICAgICAgICAgX2ZuYW1lID0gbmV3IFFOYW1lKG51bGwsIG51bGwsIGxvY2FsKTsKLSAgICAgICAgICAgIHJldHVybiB0eXBlQ2hlY2tTdGFuZGFyZChzdGFibGUpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKGlzU3RhbmRhcmQoKSkgewotICAgICAgICAgICAgcmV0dXJuIHR5cGVDaGVja1N0YW5kYXJkKHN0YWJsZSk7Ci0gICAgICAgIH0KLSAgICAgICAgLy8gSGFuZGxlIGV4dGVuc2lvbiBmdW5jdGlvbnMgKHRoZXkgYWxsIGhhdmUgYSBuYW1lc3BhY2UpCi0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICBfY2xhc3NOYW1lID0gZ2V0Q2xhc3NOYW1lRnJvbVVyaShuYW1lc3BhY2UpOwotCi0gICAgICAgICAgICAgICAgZmluYWwgaW50IHBvcyA9IGxvY2FsLmxhc3RJbmRleE9mKCcuJyk7Ci0gICAgICAgICAgICAgICAgaWYgKHBvcyA+IDApIHsKLSAgICAgICAgICAgICAgICAgICAgX2lzU3RhdGljID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKF9jbGFzc05hbWUgIT0gbnVsbCAmJiBfY2xhc3NOYW1lLmxlbmd0aCgpID4gMCkgewotICAgICAgICAgICAgICAgICAgICAgICAgX25hbWVzcGFjZV9mb3JtYXQgPSBOQU1FU1BBQ0VfRk9STUFUX1BBQ0tBR0U7Ci0gICAgICAgICAgICAgICAgICAgICAgICBfY2xhc3NOYW1lID0gX2NsYXNzTmFtZSArICIuIiArIGxvY2FsLnN1YnN0cmluZygwLCBwb3MpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgX25hbWVzcGFjZV9mb3JtYXQgPSBOQU1FU1BBQ0VfRk9STUFUX0pBVkE7Ci0gICAgICAgICAgICAgICAgICAgICAgICBfY2xhc3NOYW1lID0gbG9jYWwuc3Vic3RyaW5nKDAsIHBvcyk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICBfZm5hbWUgPSBuZXcgUU5hbWUobmFtZXNwYWNlLCBudWxsLCBsb2NhbC5zdWJzdHJpbmcocG9zICsgMSkpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKF9jbGFzc05hbWUgIT0gbnVsbCAmJiBfY2xhc3NOYW1lLmxlbmd0aCgpID4gMCkgewotICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBfY2xhenogPSBPYmplY3RGYWN0b3J5LmZpbmRQcm92aWRlckNsYXNzKF9jbGFzc05hbWUsIHRydWUpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9uYW1lc3BhY2VfZm9ybWF0ID0gTkFNRVNQQUNFX0ZPUk1BVF9DTEFTUzsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGNhdGNoIChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBfbmFtZXNwYWNlX2Zvcm1hdCA9IE5BTUVTUEFDRV9GT1JNQVRfUEFDS0FHRTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgICAgICBfbmFtZXNwYWNlX2Zvcm1hdCA9IE5BTUVTUEFDRV9GT1JNQVRfSkFWQTsKLQotICAgICAgICAgICAgICAgICAgICBpZiAobG9jYWwuaW5kZXhPZignLScpID4gMCkgewotICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWwgPSByZXBsYWNlRGFzaChsb2NhbCk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgZXh0RnVuY3Rpb24gPSBFWFRFTlNJT05GVU5DVElPTi5nZXQobmFtZXNwYWNlICsgIjoiICsgbG9jYWwpOwotICAgICAgICAgICAgICAgICAgICBpZiAoZXh0RnVuY3Rpb24gIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgX2ZuYW1lID0gbmV3IFFOYW1lKG51bGwsIG51bGwsIGV4dEZ1bmN0aW9uKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0eXBlQ2hlY2tTdGFuZGFyZChzdGFibGUpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgICAgICAgIF9mbmFtZSA9IG5ldyBRTmFtZShuYW1lc3BhY2UsIG51bGwsIGxvY2FsKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICByZXR1cm4gdHlwZUNoZWNrRXh0ZXJuYWwoc3RhYmxlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhdGNoIChUeXBlQ2hlY2tFcnJvciBlKSB7Ci0gICAgICAgICAgICAgICAgRXJyb3JNc2cgZXJyb3JNc2cgPSBlLmdldEVycm9yTXNnKCk7Ci0gICAgICAgICAgICAgICAgaWYgKGVycm9yTXNnID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIG5hbWUgPSBfZm5hbWUuZ2V0TG9jYWxQYXJ0KCk7Ci0gICAgICAgICAgICAgICAgICAgIGVycm9yTXNnID0gbmV3IEVycm9yTXNnKEVycm9yTXNnLk1FVEhPRF9OT1RfRk9VTkRfRVJSLCBuYW1lKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZ2V0UGFyc2VyKCkucmVwb3J0RXJyb3IoRVJST1IsIGVycm9yTXNnKTsKLSAgICAgICAgICAgICAgICByZXR1cm4gX3R5cGUgPSBUeXBlLlZvaWQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFR5cGUgY2hlY2sgYSBjYWxsIHRvIGEgc3RhbmRhcmQgZnVuY3Rpb24uIEluc2VydCBDYXN0RXhwcnMgd2hlbiBuZWVkZWQuCi0gICAgICogSWYgYXMgYSByZXN1bHQgb2YgdGhlIGluc2VydGlvbiBvZiBhIENhc3RFeHByIGEgdHlwZSBjaGVjayBlcnJvciBpcwotICAgICAqIHRocm93biwgdGhlbiBjYXRjaCBpdCBhbmQgcmUtdGhyb3cgaXQgd2l0aCBhIG5ldyAidGhpcyIuCi0gICAgICovCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrU3RhbmRhcmQoU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgewotICAgICAgICBfZm5hbWUuY2xlYXJOYW1lc3BhY2UoKTsgICAgICAgIC8vIEhBQ0shISEKLQotICAgICAgICBmaW5hbCBpbnQgbiA9IF9hcmd1bWVudHMuc2l6ZSgpOwotICAgICAgICBmaW5hbCBWZWN0b3IgYXJnc1R5cGUgPSB0eXBlQ2hlY2tBcmdzKHN0YWJsZSk7Ci0gICAgICAgIGZpbmFsIE1ldGhvZFR5cGUgYXJncyA9IG5ldyBNZXRob2RUeXBlKFR5cGUuVm9pZCwgYXJnc1R5cGUpOwotICAgICAgICBmaW5hbCBNZXRob2RUeXBlIHB0eXBlID0KLSAgICAgICAgICAgIGxvb2t1cFByaW1vcChzdGFibGUsIF9mbmFtZS5nZXRMb2NhbFBhcnQoKSwgYXJncyk7Ci0KLSAgICAgICAgaWYgKHB0eXBlICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgZmluYWwgVHlwZSBhcmdUeXBlID0gKFR5cGUpIHB0eXBlLmFyZ3NUeXBlKCkuZWxlbWVudEF0KGkpOwotICAgICAgICAgICAgICAgIGZpbmFsIEV4cHJlc3Npb24gZXhwID0gKEV4cHJlc3Npb24pX2FyZ3VtZW50cy5lbGVtZW50QXQoaSk7Ci0gICAgICAgICAgICAgICAgaWYgKCFhcmdUeXBlLmlkZW50aWNhbFRvKGV4cC5nZXRUeXBlKCkpKSB7Ci0gICAgICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBfYXJndW1lbnRzLnNldEVsZW1lbnRBdChuZXcgQ2FzdEV4cHIoZXhwLCBhcmdUeXBlKSwgaSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgY2F0Y2ggKFR5cGVDaGVja0Vycm9yIGUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlQ2hlY2tFcnJvcih0aGlzKTsgLy8gaW52YWxpZCBjb252ZXJzaW9uCi0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBfY2hvc2VuTWV0aG9kVHlwZSA9IHB0eXBlOwotICAgICAgICAgICAgcmV0dXJuIF90eXBlID0gcHR5cGUucmVzdWx0VHlwZSgpOwotICAgICAgICB9Ci0gICAgICAgIHRocm93IG5ldyBUeXBlQ2hlY2tFcnJvcih0aGlzKTsKLSAgICB9Ci0KLQotCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrQ29uc3RydWN0b3IoU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3J7Ci0gICAgICAgIGZpbmFsIFZlY3RvciBjb25zdHJ1Y3RvcnMgPSBmaW5kQ29uc3RydWN0b3JzKCk7Ci0gICAgICAgIGlmIChjb25zdHJ1Y3RvcnMgPT0gbnVsbCkgewotICAgICAgICAgICAgLy8gQ29uc3RydWN0b3Igbm90IGZvdW5kIGluIHRoaXMgY2xhc3MKLSAgICAgICAgICAgIHRocm93IG5ldyBUeXBlQ2hlY2tFcnJvcihFcnJvck1zZy5DT05TVFJVQ1RPUl9OT1RfRk9VTkQsCi0gICAgICAgICAgICAgICAgX2NsYXNzTmFtZSk7Ci0KLSAgICAgICAgfQotCi0gICAgICAgIGZpbmFsIGludCBuQ29uc3RydWN0b3JzID0gY29uc3RydWN0b3JzLnNpemUoKTsKLSAgICAgICAgZmluYWwgaW50IG5BcmdzID0gX2FyZ3VtZW50cy5zaXplKCk7Ci0gICAgICAgIGZpbmFsIFZlY3RvciBhcmdzVHlwZSA9IHR5cGVDaGVja0FyZ3Moc3RhYmxlKTsKLQotICAgICAgICAvLyBUcnkgYWxsIGNvbnN0cnVjdG9ycwotICAgICAgICBpbnQgYmVzdENvbnN0ckRpc3RhbmNlID0gSW50ZWdlci5NQVhfVkFMVUU7Ci0gICAgICAgIF90eXBlID0gbnVsbDsgICAgICAgICAgICAgICAgICAgLy8gcmVzZXQKLSAgICAgICAgZm9yIChpbnQgaiwgaSA9IDA7IGkgPCBuQ29uc3RydWN0b3JzOyBpKyspIHsKLSAgICAgICAgICAgIC8vIENoZWNrIGlmIGFsbCBwYXJhbWV0ZXJzIHRvIHRoaXMgY29uc3RydWN0b3IgY2FuIGJlIGNvbnZlcnRlZAotICAgICAgICAgICAgZmluYWwgQ29uc3RydWN0b3IgY29uc3RydWN0b3IgPQotICAgICAgICAgICAgICAgIChDb25zdHJ1Y3Rvciljb25zdHJ1Y3RvcnMuZWxlbWVudEF0KGkpOwotICAgICAgICAgICAgZmluYWwgQ2xhc3NbXSBwYXJhbVR5cGVzID0gY29uc3RydWN0b3IuZ2V0UGFyYW1ldGVyVHlwZXMoKTsKLQotICAgICAgICAgICAgQ2xhc3M8Pz4gZXh0VHlwZTsKLSAgICAgICAgICAgIGludCBjdXJyQ29uc3RyRGlzdGFuY2UgPSAwOwotICAgICAgICAgICAgZm9yIChqID0gMDsgaiA8IG5BcmdzOyBqKyspIHsKLSAgICAgICAgICAgICAgICAvLyBDb252ZXJ0IGZyb20gaW50ZXJuYWwgKHRyYW5zbGV0KSB0eXBlIHRvIGV4dGVybmFsIChKYXZhKSB0eXBlCi0gICAgICAgICAgICAgICAgZXh0VHlwZSA9IHBhcmFtVHlwZXNbal07Ci0gICAgICAgICAgICAgICAgZmluYWwgVHlwZSBpbnRUeXBlID0gKFR5cGUpYXJnc1R5cGUuZWxlbWVudEF0KGopOwotICAgICAgICAgICAgICAgIEphdmFUeXBlIG1hdGNoID0gX2ludGVybmFsMkphdmEubWFwcyhpbnRUeXBlLCBuZXcgSmF2YVR5cGUoZXh0VHlwZSwgMCkpOwotICAgICAgICAgICAgICAgIGlmIChtYXRjaCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGN1cnJDb25zdHJEaXN0YW5jZSArPSBtYXRjaC5kaXN0YW5jZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSBpZiAoaW50VHlwZSBpbnN0YW5jZW9mIE9iamVjdFR5cGUpIHsKLSAgICAgICAgICAgICAgICAgICAgT2JqZWN0VHlwZSBvYmplY3RUeXBlID0gKE9iamVjdFR5cGUpaW50VHlwZTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKG9iamVjdFR5cGUuZ2V0SmF2YUNsYXNzKCkgPT0gZXh0VHlwZSkKLSAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChleHRUeXBlLmlzQXNzaWduYWJsZUZyb20ob2JqZWN0VHlwZS5nZXRKYXZhQ2xhc3MoKSkpCi0gICAgICAgICAgICAgICAgICAgICAgICBjdXJyQ29uc3RyRGlzdGFuY2UgKz0gMTsKLSAgICAgICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBjdXJyQ29uc3RyRGlzdGFuY2UgPSBJbnRlZ2VyLk1BWF9WQUxVRTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAvLyBubyBtYXBwaW5nIGF2YWlsYWJsZQotICAgICAgICAgICAgICAgICAgICBjdXJyQ29uc3RyRGlzdGFuY2UgPSBJbnRlZ2VyLk1BWF9WQUxVRTsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAoaiA9PSBuQXJncyAmJiBjdXJyQ29uc3RyRGlzdGFuY2UgPCBiZXN0Q29uc3RyRGlzdGFuY2UgKSB7Ci0gICAgICAgICAgICAgICAgX2Nob3NlbkNvbnN0cnVjdG9yID0gY29uc3RydWN0b3I7Ci0gICAgICAgICAgICAgICAgX2lzRXh0Q29uc3RydWN0b3IgPSB0cnVlOwotICAgICAgICAgICAgICAgIGJlc3RDb25zdHJEaXN0YW5jZSA9IGN1cnJDb25zdHJEaXN0YW5jZTsKLQotICAgICAgICAgICAgICAgIF90eXBlID0gKF9jbGF6eiAhPSBudWxsKSA/IFR5cGUubmV3T2JqZWN0VHlwZShfY2xhenopCi0gICAgICAgICAgICAgICAgICAgIDogVHlwZS5uZXdPYmplY3RUeXBlKF9jbGFzc05hbWUpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKF90eXBlICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBfdHlwZTsKLSAgICAgICAgfQotCi0gICAgICAgIHRocm93IG5ldyBUeXBlQ2hlY2tFcnJvcihFcnJvck1zZy5BUkdVTUVOVF9DT05WRVJTSU9OX0VSUiwgZ2V0TWV0aG9kU2lnbmF0dXJlKGFyZ3NUeXBlKSk7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBUeXBlIGNoZWNrIGEgY2FsbCB0byBhbiBleHRlcm5hbCAoSmF2YSkgbWV0aG9kLgotICAgICAqIFRoZSBtZXRob2QgbXVzdCBiZSBzdGF0aWMgYW4gcHVibGljLCBhbmQgYSBsZWdhbCB0eXBlIGNvbnZlcnNpb24KLSAgICAgKiBtdXN0IGV4aXN0IGZvciBhbGwgaXRzIGFyZ3VtZW50cyBhbmQgaXRzIHJldHVybiB0eXBlLgotICAgICAqIEV2ZXJ5IG1ldGhvZCBvZiBuYW1lIDxjb2RlPl9mbmFtZTwvY29kZT4gaXMgaW5zcGVjdGVkCi0gICAgICogYXMgYSBwb3NzaWJsZSBjYW5kaWRhdGUuCi0gICAgICovCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrRXh0ZXJuYWwoU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgewotICAgICAgICBpbnQgbkFyZ3MgPSBfYXJndW1lbnRzLnNpemUoKTsKLSAgICAgICAgZmluYWwgU3RyaW5nIG5hbWUgPSBfZm5hbWUuZ2V0TG9jYWxQYXJ0KCk7Ci0KLSAgICAgICAgLy8gY2hlY2sgaWYgZnVuY3Rpb24gaXMgYSBjb250cnVjdG9yICduZXcnCi0gICAgICAgIGlmIChfZm5hbWUuZ2V0TG9jYWxQYXJ0KCkuZXF1YWxzKCJuZXciKSkgewotICAgICAgICAgICAgcmV0dXJuIHR5cGVDaGVja0NvbnN0cnVjdG9yKHN0YWJsZSk7Ci0gICAgICAgIH0KLSAgICAgICAgLy8gY2hlY2sgaWYgd2UgYXJlIGNhbGxpbmcgYW4gaW5zdGFuY2UgbWV0aG9kCi0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgYm9vbGVhbiBoYXNUaGlzQXJndW1lbnQgPSBmYWxzZTsKLQotICAgICAgICAgICAgaWYgKG5BcmdzID09IDApCi0gICAgICAgICAgICAgICAgX2lzU3RhdGljID0gdHJ1ZTsKLQotICAgICAgICAgICAgaWYgKCFfaXNTdGF0aWMpIHsKLSAgICAgICAgICAgICAgICBpZiAoX25hbWVzcGFjZV9mb3JtYXQgPT0gTkFNRVNQQUNFX0ZPUk1BVF9KQVZBCi0gICAgICAgICAgICAgICAgICAgIHx8IF9uYW1lc3BhY2VfZm9ybWF0ID09IE5BTUVTUEFDRV9GT1JNQVRfUEFDS0FHRSkKLSAgICAgICAgICAgICAgICAgICAgaGFzVGhpc0FyZ3VtZW50ID0gdHJ1ZTsKLQotICAgICAgICAgICAgICAgIEV4cHJlc3Npb24gZmlyc3RBcmcgPSAoRXhwcmVzc2lvbilfYXJndW1lbnRzLmVsZW1lbnRBdCgwKTsKLSAgICAgICAgICAgICAgICBUeXBlIGZpcnN0QXJnVHlwZSA9IChUeXBlKWZpcnN0QXJnLnR5cGVDaGVjayhzdGFibGUpOwotCi0gICAgICAgICAgICAgICAgaWYgKF9uYW1lc3BhY2VfZm9ybWF0ID09IE5BTUVTUEFDRV9GT1JNQVRfQ0xBU1MKLSAgICAgICAgICAgICAgICAgICAgJiYgZmlyc3RBcmdUeXBlIGluc3RhbmNlb2YgT2JqZWN0VHlwZQotICAgICAgICAgICAgICAgICAgICAmJiBfY2xhenogIT0gbnVsbAotICAgICAgICAgICAgICAgICAgICAmJiBfY2xhenouaXNBc3NpZ25hYmxlRnJvbSgoKE9iamVjdFR5cGUpZmlyc3RBcmdUeXBlKS5nZXRKYXZhQ2xhc3MoKSkpCi0gICAgICAgICAgICAgICAgICAgIGhhc1RoaXNBcmd1bWVudCA9IHRydWU7Ci0KLSAgICAgICAgICAgICAgICBpZiAoaGFzVGhpc0FyZ3VtZW50KSB7Ci0gICAgICAgICAgICAgICAgICAgIF90aGlzQXJndW1lbnQgPSAoRXhwcmVzc2lvbikgX2FyZ3VtZW50cy5lbGVtZW50QXQoMCk7Ci0gICAgICAgICAgICAgICAgICAgIF9hcmd1bWVudHMucmVtb3ZlKDApOyBuQXJncy0tOwotICAgICAgICAgICAgICAgICAgICBpZiAoZmlyc3RBcmdUeXBlIGluc3RhbmNlb2YgT2JqZWN0VHlwZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgX2NsYXNzTmFtZSA9ICgoT2JqZWN0VHlwZSkgZmlyc3RBcmdUeXBlKS5nZXRKYXZhQ2xhc3NOYW1lKCk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVDaGVja0Vycm9yKEVycm9yTXNnLk5PX0pBVkFfRlVOQ1RfVEhJU19SRUYsIG5hbWUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKF9jbGFzc05hbWUubGVuZ3RoKCkgPT0gMCkgewotICAgICAgICAgICAgICAgIC8qCi0gICAgICAgICAgICAgICAgICogV2FybiB1c2VyIGlmIGV4dGVybmFsIGZ1bmN0aW9uIGNvdWxkIG5vdCBiZSByZXNvbHZlZC4KLSAgICAgICAgICAgICAgICAgKiBXYXJuaW5nIHdpbGwgX05PVF8gYmUgaXNzdWVkIGlzIHRoZSBjYWxsIGlzIHByb3Blcmx5Ci0gICAgICAgICAgICAgICAgICogd3JhcHBlZCBpbiBhbiA8eHNsOmlmPiBvciA8eHNsOndoZW4+IGVsZW1lbnQuIEZvciBkZXRhaWxzCi0gICAgICAgICAgICAgICAgICogc2VlIElmLnBhcnNlckNvbnRlbnRzKCkgYW5kIFdoZW4ucGFyc2VyQ29udGVudHMoKQotICAgICAgICAgICAgICAgICAqLwotICAgICAgICAgICAgICAgIGZpbmFsIFBhcnNlciBwYXJzZXIgPSBnZXRQYXJzZXIoKTsKLSAgICAgICAgICAgICAgICBpZiAocGFyc2VyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgcmVwb3J0V2FybmluZyh0aGlzLCBwYXJzZXIsIEVycm9yTXNnLkZVTkNUSU9OX1JFU09MVkVfRVJSLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9mbmFtZS50b1N0cmluZygpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgdW5yZXNvbHZlZEV4dGVybmFsID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICByZXR1cm4gX3R5cGUgPSBUeXBlLkludDsgICAgICAgIC8vIHVzZSAiSW50IiBhcyAidW5rbm93biIKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGZpbmFsIFZlY3RvciBtZXRob2RzID0gZmluZE1ldGhvZHMoKTsKLQotICAgICAgICBpZiAobWV0aG9kcyA9PSBudWxsKSB7Ci0gICAgICAgICAgICAvLyBNZXRob2Qgbm90IGZvdW5kIGluIHRoaXMgY2xhc3MKLSAgICAgICAgICAgIHRocm93IG5ldyBUeXBlQ2hlY2tFcnJvcihFcnJvck1zZy5NRVRIT0RfTk9UX0ZPVU5EX0VSUiwgX2NsYXNzTmFtZSArICIuIiArIG5hbWUpOwotICAgICAgICB9Ci0KLSAgICAgICAgQ2xhc3MgZXh0VHlwZSA9IG51bGw7Ci0gICAgICAgIGZpbmFsIGludCBuTWV0aG9kcyA9IG1ldGhvZHMuc2l6ZSgpOwotICAgICAgICBmaW5hbCBWZWN0b3IgYXJnc1R5cGUgPSB0eXBlQ2hlY2tBcmdzKHN0YWJsZSk7Ci0KLSAgICAgICAgLy8gVHJ5IGFsbCBtZXRob2RzIHRvIGlkZW50aWZ5IHRoZSBiZXN0IGZpdAotICAgICAgICBpbnQgYmVzdE1ldGhvZERpc3RhbmNlICA9IEludGVnZXIuTUFYX1ZBTFVFOwotICAgICAgICBfdHlwZSA9IG51bGw7ICAgICAgICAgICAgICAgICAgICAgICAvLyByZXNldCBpbnRlcm5hbCB0eXBlCi0gICAgICAgIGZvciAoaW50IGosIGkgPSAwOyBpIDwgbk1ldGhvZHM7IGkrKykgewotICAgICAgICAgICAgLy8gQ2hlY2sgaWYgYWxsIHBhcmFtdGV0ZXJzIHRvIHRoaXMgbWV0aG9kIGNhbiBiZSBjb252ZXJ0ZWQKLSAgICAgICAgICAgIGZpbmFsIE1ldGhvZCBtZXRob2QgPSAoTWV0aG9kKW1ldGhvZHMuZWxlbWVudEF0KGkpOwotICAgICAgICAgICAgZmluYWwgQ2xhc3NbXSBwYXJhbVR5cGVzID0gbWV0aG9kLmdldFBhcmFtZXRlclR5cGVzKCk7Ci0KLSAgICAgICAgICAgIGludCBjdXJyTWV0aG9kRGlzdGFuY2UgPSAwOwotICAgICAgICAgICAgZm9yIChqID0gMDsgaiA8IG5BcmdzOyBqKyspIHsKLSAgICAgICAgICAgICAgICAvLyBDb252ZXJ0IGZyb20gaW50ZXJuYWwgKHRyYW5zbGV0KSB0eXBlIHRvIGV4dGVybmFsIChKYXZhKSB0eXBlCi0gICAgICAgICAgICAgICAgZXh0VHlwZSA9IHBhcmFtVHlwZXNbal07Ci0gICAgICAgICAgICAgICAgZmluYWwgVHlwZSBpbnRUeXBlID0gKFR5cGUpYXJnc1R5cGUuZWxlbWVudEF0KGopOwotICAgICAgICAgICAgICAgIEphdmFUeXBlIG1hdGNoID0gX2ludGVybmFsMkphdmEubWFwcyhpbnRUeXBlLCBuZXcgSmF2YVR5cGUoZXh0VHlwZSwgMCkpOwotICAgICAgICAgICAgICAgIGlmIChtYXRjaCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGN1cnJNZXRob2REaXN0YW5jZSArPSBtYXRjaC5kaXN0YW5jZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIG5vIG1hcHBpbmcgYXZhaWxhYmxlCi0gICAgICAgICAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAgICAgICAgIC8vIEFsbG93IGEgUmVmZXJlbmNlIHR5cGUgdG8gbWF0Y2ggYW55IGV4dGVybmFsIChKYXZhKSB0eXBlIGF0Ci0gICAgICAgICAgICAgICAgICAgIC8vIHRoZSBtb21lbnQuIFRoZSByZWFsIHR5cGUgY2hlY2tpbmcgaXMgcGVyZm9ybWVkIGF0IHJ1bnRpbWUuCi0gICAgICAgICAgICAgICAgICAgIGlmIChpbnRUeXBlIGluc3RhbmNlb2YgUmVmZXJlbmNlVHlwZSkgewotICAgICAgICAgICAgICAgICAgICAgICBjdXJyTWV0aG9kRGlzdGFuY2UgKz0gMTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChpbnRUeXBlIGluc3RhbmNlb2YgT2JqZWN0VHlwZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgT2JqZWN0VHlwZSBvYmplY3QgPSAoT2JqZWN0VHlwZSlpbnRUeXBlOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGV4dFR5cGUuZ2V0TmFtZSgpLmVxdWFscyhvYmplY3QuZ2V0SmF2YUNsYXNzTmFtZSgpKSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyTWV0aG9kRGlzdGFuY2UgKz0gMDsKLSAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGV4dFR5cGUuaXNBc3NpZ25hYmxlRnJvbShvYmplY3QuZ2V0SmF2YUNsYXNzKCkpKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJNZXRob2REaXN0YW5jZSArPSAxOwotICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgY3Vyck1ldGhvZERpc3RhbmNlID0gSW50ZWdlci5NQVhfVkFMVUU7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBjdXJyTWV0aG9kRGlzdGFuY2UgPSBJbnRlZ2VyLk1BWF9WQUxVRTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAoaiA9PSBuQXJncykgewotICAgICAgICAgICAgICAgICAgLy8gQ2hlY2sgaWYgdGhlIHJldHVybiB0eXBlIGNhbiBiZSBjb252ZXJ0ZWQKLSAgICAgICAgICAgICAgICAgIGV4dFR5cGUgPSBtZXRob2QuZ2V0UmV0dXJuVHlwZSgpOwotCi0gICAgICAgICAgICAgICAgICBfdHlwZSA9IEpBVkEySU5URVJOQUwuZ2V0KGV4dFR5cGUpOwotICAgICAgICAgICAgICAgICAgaWYgKF90eXBlID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICBfdHlwZSA9IFR5cGUubmV3T2JqZWN0VHlwZShleHRUeXBlKTsKLSAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgLy8gVXNlIHRoaXMgbWV0aG9kIGlmIGFsbCBwYXJhbWV0ZXJzICYgcmV0dXJuIHR5cGUgbWF0Y2gKLSAgICAgICAgICAgICAgICAgIGlmIChfdHlwZSAhPSBudWxsICYmIGN1cnJNZXRob2REaXN0YW5jZSA8IGJlc3RNZXRob2REaXN0YW5jZSkgewotICAgICAgICAgICAgICAgICAgICAgIF9jaG9zZW5NZXRob2QgPSBtZXRob2Q7Ci0gICAgICAgICAgICAgICAgICAgICAgYmVzdE1ldGhvZERpc3RhbmNlID0gY3Vyck1ldGhvZERpc3RhbmNlOwotICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gSXQgaXMgYW4gZXJyb3IgaWYgdGhlIGNob3NlbiBtZXRob2QgaXMgYW4gaW5zdGFuY2UgbWVudGhvZCBidXQgd2UgZG9uJ3QKLSAgICAgICAgLy8gaGF2ZSBhIHRoaXMgYXJndW1lbnQuCi0gICAgICAgIGlmIChfY2hvc2VuTWV0aG9kICE9IG51bGwgJiYgX3RoaXNBcmd1bWVudCA9PSBudWxsICYmCi0gICAgICAgICAgICAhTW9kaWZpZXIuaXNTdGF0aWMoX2Nob3Nlbk1ldGhvZC5nZXRNb2RpZmllcnMoKSkpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBUeXBlQ2hlY2tFcnJvcihFcnJvck1zZy5OT19KQVZBX0ZVTkNUX1RISVNfUkVGLCBnZXRNZXRob2RTaWduYXR1cmUoYXJnc1R5cGUpKTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChfdHlwZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAoX3R5cGUgPT0gVHlwZS5Ob2RlU2V0KSB7Ci0gICAgICAgICAgICAgICAgZ2V0WFNMVEMoKS5zZXRNdWx0aURvY3VtZW50KHRydWUpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIF90eXBlOwotICAgICAgICB9Ci0KLSAgICAgICAgdGhyb3cgbmV3IFR5cGVDaGVja0Vycm9yKEVycm9yTXNnLkFSR1VNRU5UX0NPTlZFUlNJT05fRVJSLCBnZXRNZXRob2RTaWduYXR1cmUoYXJnc1R5cGUpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUeXBlIGNoZWNrIHRoZSBhY3R1YWwgYXJndW1lbnRzIG9mIHRoaXMgZnVuY3Rpb24gY2FsbC4KLSAgICAgKi8KLSAgICBwdWJsaWMgVmVjdG9yIHR5cGVDaGVja0FyZ3MoU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgewotICAgICAgICBmaW5hbCBWZWN0b3IgcmVzdWx0ID0gbmV3IFZlY3RvcigpOwotICAgICAgICBmaW5hbCBFbnVtZXJhdGlvbiBlID0gX2FyZ3VtZW50cy5lbGVtZW50cygpOwotICAgICAgICB3aGlsZSAoZS5oYXNNb3JlRWxlbWVudHMoKSkgewotICAgICAgICAgICAgZmluYWwgRXhwcmVzc2lvbiBleHAgPSAoRXhwcmVzc2lvbillLm5leHRFbGVtZW50KCk7Ci0gICAgICAgICAgICByZXN1bHQuYWRkRWxlbWVudChleHAudHlwZUNoZWNrKHN0YWJsZSkpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiByZXN1bHQ7Ci0gICAgfQotCi0gICAgcHJvdGVjdGVkIGZpbmFsIEV4cHJlc3Npb24gYXJndW1lbnQoaW50IGkpIHsKLSAgICAgICAgcmV0dXJuIChFeHByZXNzaW9uKV9hcmd1bWVudHMuZWxlbWVudEF0KGkpOwotICAgIH0KLQotICAgIHByb3RlY3RlZCBmaW5hbCBFeHByZXNzaW9uIGFyZ3VtZW50KCkgewotICAgICAgICByZXR1cm4gYXJndW1lbnQoMCk7Ci0gICAgfQotCi0gICAgcHJvdGVjdGVkIGZpbmFsIGludCBhcmd1bWVudENvdW50KCkgewotICAgICAgICByZXR1cm4gX2FyZ3VtZW50cy5zaXplKCk7Ci0gICAgfQotCi0gICAgcHJvdGVjdGVkIGZpbmFsIHZvaWQgc2V0QXJndW1lbnQoaW50IGksIEV4cHJlc3Npb24gZXhwKSB7Ci0gICAgICAgIF9hcmd1bWVudHMuc2V0RWxlbWVudEF0KGV4cCwgaSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29tcGlsZSB0aGUgZnVuY3Rpb24gY2FsbCBhbmQgdHJlYXQgYXMgYW4gZXhwcmVzc2lvbgotICAgICAqIFVwZGF0ZSB0cnVlL2ZhbHNlLWxpc3RzLgotICAgICAqLwotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZURlc3ludGhlc2l6ZWQoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKQotICAgIHsKLSAgICAgICAgVHlwZSB0eXBlID0gVHlwZS5Cb29sZWFuOwotICAgICAgICBpZiAoX2Nob3Nlbk1ldGhvZFR5cGUgIT0gbnVsbCkKLSAgICAgICAgICAgIHR5cGUgPSBfY2hvc2VuTWV0aG9kVHlwZS5yZXN1bHRUeXBlKCk7Ci0KLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotICAgICAgICB0cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0KLSAgICAgICAgaWYgKCh0eXBlIGluc3RhbmNlb2YgQm9vbGVhblR5cGUpIHx8ICh0eXBlIGluc3RhbmNlb2YgSW50VHlwZSkpIHsKLSAgICAgICAgICAgIF9mYWxzZUxpc3QuYWRkKGlsLmFwcGVuZChuZXcgSUZFUShudWxsKSkpOwotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGUgYSBmdW5jdGlvbiBjYWxsLiBUaGUgY29tcGlsZWQgY29kZSB3aWxsIGxlYXZlIHRoZSBmdW5jdGlvbidzCi0gICAgICogcmV0dXJuIHZhbHVlIG9uIHRoZSBKVk0ncyBzdGFjay4KLSAgICAgKi8KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLSAgICAgICAgZmluYWwgaW50IG4gPSBhcmd1bWVudENvdW50KCk7Ci0gICAgICAgIGZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotICAgICAgICBmaW5hbCBib29sZWFuIGlzU2VjdXJlUHJvY2Vzc2luZyA9IGNsYXNzR2VuLmdldFBhcnNlcigpLmdldFhTTFRDKCkuaXNTZWN1cmVQcm9jZXNzaW5nKCk7Ci0gICAgICAgIGZpbmFsIGJvb2xlYW4gaXNFeHRlbnNpb25GdW5jdGlvbkVuYWJsZWQgPSBjbGFzc0dlbi5nZXRQYXJzZXIoKS5nZXRYU0xUQygpCi0gICAgICAgICAgICAgICAgLmdldEZlYXR1cmUoRmVhdHVyZU1hbmFnZXIuRmVhdHVyZS5PUkFDTEVfRU5BQkxFX0VYVEVOU0lPTl9GVU5DVElPTik7Ci0gICAgICAgIGludCBpbmRleDsKLQotICAgICAgICAvLyBUcmFuc2xhdGUgY2FsbHMgdG8gbWV0aG9kcyBpbiB0aGUgQmFzaXNMaWJyYXJ5Ci0gICAgICAgIGlmIChpc1N0YW5kYXJkKCkgfHwgaXNFeHRlbnNpb24oKSkgewotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspIHsKLSAgICAgICAgICAgICAgICBmaW5hbCBFeHByZXNzaW9uIGV4cCA9IGFyZ3VtZW50KGkpOwotICAgICAgICAgICAgICAgIGV4cC50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgICAgICAgICAgZXhwLnN0YXJ0SXRlcmF0b3IoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIGFwcGVuZCAiRiIgdG8gdGhlIGZ1bmN0aW9uJ3MgbmFtZQotICAgICAgICAgICAgZmluYWwgU3RyaW5nIG5hbWUgPSBfZm5hbWUudG9TdHJpbmcoKS5yZXBsYWNlKCctJywgJ18nKSArICJGIjsKLSAgICAgICAgICAgIFN0cmluZyBhcmdzID0gQ29uc3RhbnRzLkVNUFRZU1RSSU5HOwotCi0gICAgICAgICAgICAvLyBTcGVjaWFsIHByZWNhdXRpb25zIGZvciBzb21lIG1ldGhvZCBjYWxscwotICAgICAgICAgICAgaWYgKG5hbWUuZXF1YWxzKCJzdW1GIikpIHsKLSAgICAgICAgICAgICAgICBhcmdzID0gRE9NX0lOVEZfU0lHOwotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzKCJub3JtYWxpemVfc3BhY2VGIikpIHsKLSAgICAgICAgICAgICAgICBpZiAoX2Nob3Nlbk1ldGhvZFR5cGUudG9TaWduYXR1cmUoYXJncykuCi0gICAgICAgICAgICAgICAgICAgIGVxdWFscygiKClMamF2YS9sYW5nL1N0cmluZzsiKSkgewotICAgICAgICAgICAgICAgICAgICBhcmdzID0gIkkiK0RPTV9JTlRGX1NJRzsKLSAgICAgICAgICAgICAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkQ29udGV4dE5vZGUoKSk7Ci0gICAgICAgICAgICAgICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIEludm9rZSB0aGUgbWV0aG9kIGluIHRoZSBiYXNpcyBsaWJyYXJ5Ci0gICAgICAgICAgICBpbmRleCA9IGNwZy5hZGRNZXRob2RyZWYoQkFTSVNfTElCUkFSWV9DTEFTUywgbmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfY2hvc2VuTWV0aG9kVHlwZS50b1NpZ25hdHVyZShhcmdzKSk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRVNUQVRJQyhpbmRleCkpOwotICAgICAgICB9Ci0gICAgICAgIC8vIEFkZCBjYWxsIHRvIEJhc2lzTGlicmFyeS51bnJlc29sdmVkX2V4dGVybmFsRigpIHRvIGdlbmVyYXRlCi0gICAgICAgIC8vIHJ1bi10aW1lIGVycm9yIG1lc3NhZ2UgZm9yIHVuc3VwcG9ydGVkIGV4dGVybmFsIGZ1bmN0aW9ucwotICAgICAgICBlbHNlIGlmICh1bnJlc29sdmVkRXh0ZXJuYWwpIHsKLSAgICAgICAgICAgIGluZGV4ID0gY3BnLmFkZE1ldGhvZHJlZihCQVNJU19MSUJSQVJZX0NMQVNTLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ1bnJlc29sdmVkX2V4dGVybmFsRiIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIihMamF2YS9sYW5nL1N0cmluZzspViIpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgX2ZuYW1lLnRvU3RyaW5nKCkpKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFU1RBVElDKGluZGV4KSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoX2lzRXh0Q29uc3RydWN0b3IpIHsKLSAgICAgICAgICAgIGlmIChpc1NlY3VyZVByb2Nlc3NpbmcgJiYgIWlzRXh0ZW5zaW9uRnVuY3Rpb25FbmFibGVkKQotICAgICAgICAgICAgICAgIHRyYW5zbGF0ZVVuYWxsb3dlZEV4dGVuc2lvbihjcGcsIGlsKTsKLQotICAgICAgICAgICAgZmluYWwgU3RyaW5nIGNsYXp6ID0KLSAgICAgICAgICAgICAgICBfY2hvc2VuQ29uc3RydWN0b3IuZ2V0RGVjbGFyaW5nQ2xhc3MoKS5nZXROYW1lKCk7Ci0gICAgICAgICAgICBDbGFzc1tdIHBhcmFtVHlwZXMgPSBfY2hvc2VuQ29uc3RydWN0b3IuZ2V0UGFyYW1ldGVyVHlwZXMoKTsKLSAgICAgICAgICAgIExvY2FsVmFyaWFibGVHZW5bXSBwYXJhbVRlbXAgPSBuZXcgTG9jYWxWYXJpYWJsZUdlbltuXTsKLQotICAgICAgICAgICAgLy8gQmFja3dhcmRzIGJyYW5jaGVzIGFyZSBwcm9oaWJpdGVkIGlmIGFuIHVuaW5pdGlhbGl6ZWQgb2JqZWN0IGlzCi0gICAgICAgICAgICAvLyBvbiB0aGUgc3RhY2sgYnkgc2VjdGlvbiA0LjkuNCBvZiB0aGUgSlZNIFNwZWNpZmljYXRpb24sIDJuZCBFZC4KLSAgICAgICAgICAgIC8vIFdlIGRvbid0IGtub3cgd2hldGhlciB0aGlzIGNvZGUgbWlnaHQgY29udGFpbiBiYWNrd2FyZHMgYnJhbmNoZXMKLSAgICAgICAgICAgIC8vIHNvIHdlIG11c3RuJ3QgY3JlYXRlIHRoZSBuZXcgb2JqZWN0IHVudGlsIGFmdGVyIHdlJ3ZlIGNyZWF0ZWQKLSAgICAgICAgICAgIC8vIHRoZSBzdXNwZWN0IGFyZ3VtZW50cyB0byBpdHMgY29uc3RydWN0b3IuICBJbnN0ZWFkIHdlIGNhbGN1bGF0ZQotICAgICAgICAgICAgLy8gdGhlIHZhbHVlcyBvZiB0aGUgYXJndW1lbnRzIHRvIHRoZSBjb25zdHJ1Y3RvciBmaXJzdCwgc3RvcmUgdGhlbQotICAgICAgICAgICAgLy8gaW4gdGVtcG9yYXJ5IHZhcmlhYmxlcywgY3JlYXRlIHRoZSBvYmplY3QgYW5kIHJlbG9hZCB0aGUKLSAgICAgICAgICAgIC8vIGFyZ3VtZW50cyBmcm9tIHRoZSB0ZW1wb3JhcmllcyB0byBhdm9pZCB0aGUgcHJvYmxlbS4KLQotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspIHsKLSAgICAgICAgICAgICAgICBmaW5hbCBFeHByZXNzaW9uIGV4cCA9IGFyZ3VtZW50KGkpOwotICAgICAgICAgICAgICAgIFR5cGUgZXhwVHlwZSA9IGV4cC5nZXRUeXBlKCk7Ci0gICAgICAgICAgICAgICAgZXhwLnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgICAgICAgICAvLyBDb252ZXJ0IHRoZSBhcmd1bWVudCB0byBpdHMgSmF2YSB0eXBlCi0gICAgICAgICAgICAgICAgZXhwLnN0YXJ0SXRlcmF0b3IoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgICAgICAgICAgZXhwVHlwZS50cmFuc2xhdGVUbyhjbGFzc0dlbiwgbWV0aG9kR2VuLCBwYXJhbVR5cGVzW2ldKTsKLSAgICAgICAgICAgICAgICBwYXJhbVRlbXBbaV0gPQotICAgICAgICAgICAgICAgICAgICBtZXRob2RHZW4uYWRkTG9jYWxWYXJpYWJsZSgiZnVuY3Rpb25fY2FsbF90bXAiK2ksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cFR5cGUudG9KQ1R5cGUoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgcGFyYW1UZW1wW2ldLnNldFN0YXJ0KAotICAgICAgICAgICAgICAgICAgICAgICAgaWwuYXBwZW5kKGV4cFR5cGUuU1RPUkUocGFyYW1UZW1wW2ldLmdldEluZGV4KCkpKSk7Ci0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBORVcoY3BnLmFkZENsYXNzKF9jbGFzc05hbWUpKSk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQoSW5zdHJ1Y3Rpb25Db25zdGFudHMuRFVQKTsKLQotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspIHsKLSAgICAgICAgICAgICAgICBmaW5hbCBFeHByZXNzaW9uIGFyZyA9IGFyZ3VtZW50KGkpOwotICAgICAgICAgICAgICAgIHBhcmFtVGVtcFtpXS5zZXRFbmQoCi0gICAgICAgICAgICAgICAgICAgICAgICBpbC5hcHBlbmQoYXJnLmdldFR5cGUoKS5MT0FEKHBhcmFtVGVtcFtpXS5nZXRJbmRleCgpKSkpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBmaW5hbCBTdHJpbmdCdWZmZXIgYnVmZmVyID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgnKCcpOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYXJhbVR5cGVzLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZChnZXRTaWduYXR1cmUocGFyYW1UeXBlc1tpXSkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgnKScpOwotICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgiViIpOwotCi0gICAgICAgICAgICBpbmRleCA9IGNwZy5hZGRNZXRob2RyZWYoY2xhenosCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjxpbml0PiIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnVmZmVyLnRvU3RyaW5nKCkpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VTUEVDSUFMKGluZGV4KSk7Ci0KLSAgICAgICAgICAgIC8vIENvbnZlcnQgdGhlIHJldHVybiB0eXBlIGJhY2sgdG8gb3VyIGludGVybmFsIHR5cGUKLSAgICAgICAgICAgIChUeXBlLk9iamVjdCkudHJhbnNsYXRlRnJvbShjbGFzc0dlbiwgbWV0aG9kR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfY2hvc2VuQ29uc3RydWN0b3IuZ2V0RGVjbGFyaW5nQ2xhc3MoKSk7Ci0KLSAgICAgICAgfQotICAgICAgICAvLyBJbnZva2UgZnVuY3Rpb24gY2FsbHMgdGhhdCBhcmUgaGFuZGxlZCBpbiBzZXBhcmF0ZSBjbGFzc2VzCi0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgaWYgKGlzU2VjdXJlUHJvY2Vzc2luZyAmJiAhaXNFeHRlbnNpb25GdW5jdGlvbkVuYWJsZWQpCi0gICAgICAgICAgICAgICAgdHJhbnNsYXRlVW5hbGxvd2VkRXh0ZW5zaW9uKGNwZywgaWwpOwotCi0gICAgICAgICAgICBmaW5hbCBTdHJpbmcgY2xhenogPSBfY2hvc2VuTWV0aG9kLmdldERlY2xhcmluZ0NsYXNzKCkuZ2V0TmFtZSgpOwotICAgICAgICAgICAgQ2xhc3NbXSBwYXJhbVR5cGVzID0gX2Nob3Nlbk1ldGhvZC5nZXRQYXJhbWV0ZXJUeXBlcygpOwotCi0gICAgICAgICAgICAvLyBQdXNoICJ0aGlzIiBpZiBpdCBpcyBhbiBpbnN0YW5jZSBtZXRob2QKLSAgICAgICAgICAgIGlmIChfdGhpc0FyZ3VtZW50ICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBfdGhpc0FyZ3VtZW50LnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspIHsKLSAgICAgICAgICAgICAgICBmaW5hbCBFeHByZXNzaW9uIGV4cCA9IGFyZ3VtZW50KGkpOwotICAgICAgICAgICAgICAgIGV4cC50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgICAgICAgICAgLy8gQ29udmVydCB0aGUgYXJndW1lbnQgdG8gaXRzIEphdmEgdHlwZQotICAgICAgICAgICAgICAgIGV4cC5zdGFydEl0ZXJhdG9yKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICAgICAgICAgIGV4cC5nZXRUeXBlKCkudHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgcGFyYW1UeXBlc1tpXSk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGZpbmFsIFN0cmluZ0J1ZmZlciBidWZmZXIgPSBuZXcgU3RyaW5nQnVmZmVyKCk7Ci0gICAgICAgICAgICBidWZmZXIuYXBwZW5kKCcoJyk7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhcmFtVHlwZXMubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKGdldFNpZ25hdHVyZShwYXJhbVR5cGVzW2ldKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBidWZmZXIuYXBwZW5kKCcpJyk7Ci0gICAgICAgICAgICBidWZmZXIuYXBwZW5kKGdldFNpZ25hdHVyZShfY2hvc2VuTWV0aG9kLmdldFJldHVyblR5cGUoKSkpOwotCi0gICAgICAgICAgICBpZiAoX3RoaXNBcmd1bWVudCAhPSBudWxsICYmIF9jbGF6ei5pc0ludGVyZmFjZSgpKSB7Ci0gICAgICAgICAgICAgICAgaW5kZXggPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKGNsYXp6LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9mbmFtZS5nZXRMb2NhbFBhcnQoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBidWZmZXIudG9TdHJpbmcoKSk7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0UoaW5kZXgsIG4rMSkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgaW5kZXggPSBjcGcuYWRkTWV0aG9kcmVmKGNsYXp6LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9mbmFtZS5nZXRMb2NhbFBhcnQoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBidWZmZXIudG9TdHJpbmcoKSk7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKF90aGlzQXJndW1lbnQgIT0gbnVsbCA/IChJbnZva2VJbnN0cnVjdGlvbikgbmV3IElOVk9LRVZJUlRVQUwoaW5kZXgpIDoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgKEludm9rZUluc3RydWN0aW9uKSBuZXcgSU5WT0tFU1RBVElDKGluZGV4KSk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIENvbnZlcnQgdGhlIHJldHVybiB0eXBlIGJhY2sgdG8gb3VyIGludGVybmFsIHR5cGUKLSAgICAgICAgICAgIF90eXBlLnRyYW5zbGF0ZUZyb20oY2xhc3NHZW4sIG1ldGhvZEdlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2Nob3Nlbk1ldGhvZC5nZXRSZXR1cm5UeXBlKCkpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKLSAgICAgICAgcmV0dXJuICJmdW5jYWxsKCIgKyBfZm5hbWUgKyAiLCAiICsgX2FyZ3VtZW50cyArICcpJzsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBpc1N0YW5kYXJkKCkgewotICAgICAgICBmaW5hbCBTdHJpbmcgbmFtZXNwYWNlID0gX2ZuYW1lLmdldE5hbWVzcGFjZSgpOwotICAgICAgICByZXR1cm4gKG5hbWVzcGFjZSA9PSBudWxsKSB8fCAobmFtZXNwYWNlLmVxdWFscyhDb25zdGFudHMuRU1QVFlTVFJJTkcpKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0V4dGVuc2lvbigpIHsKLSAgICAgICAgZmluYWwgU3RyaW5nIG5hbWVzcGFjZSA9IF9mbmFtZS5nZXROYW1lc3BhY2UoKTsKLSAgICAgICAgcmV0dXJuIChuYW1lc3BhY2UgIT0gbnVsbCkgJiYgKG5hbWVzcGFjZS5lcXVhbHMoRVhUX1hTTFRDKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhIHZlY3RvciB3aXRoIGFsbCBtZXRob2RzIG5hbWVkIDxjb2RlPl9mbmFtZTwvY29kZT4KLSAgICAgKiBhZnRlciBzdHJpcHBpbmcgaXRzIG5hbWVzcGFjZSBvciA8Y29kZT5udWxsPC9jb2RlPgotICAgICAqIGlmIG5vIHN1Y2ggbWV0aG9kcyBleGlzdC4KLSAgICAgKi8KLSAgICBwcml2YXRlIFZlY3RvciBmaW5kTWV0aG9kcygpIHsKLQotICAgICAgICAgIFZlY3RvciByZXN1bHQgPSBudWxsOwotICAgICAgICAgIGZpbmFsIFN0cmluZyBuYW1lc3BhY2UgPSBfZm5hbWUuZ2V0TmFtZXNwYWNlKCk7Ci0KLSAgICAgICAgICBpZiAoX2NsYXNzTmFtZSAhPSBudWxsICYmIF9jbGFzc05hbWUubGVuZ3RoKCkgPiAwKSB7Ci0gICAgICAgICAgICBmaW5hbCBpbnQgbkFyZ3MgPSBfYXJndW1lbnRzLnNpemUoKTsKLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgaWYgKF9jbGF6eiA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZpbmFsIGJvb2xlYW4gaXNTZWN1cmVQcm9jZXNzaW5nID0gZ2V0WFNMVEMoKS5pc1NlY3VyZVByb2Nlc3NpbmcoKTsKLSAgICAgICAgICAgICAgICAgICAgZmluYWwgYm9vbGVhbiBpc0V4dGVuc2lvbkZ1bmN0aW9uRW5hYmxlZCA9IGdldFhTTFRDKCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0RmVhdHVyZShGZWF0dXJlTWFuYWdlci5GZWF0dXJlLk9SQUNMRV9FTkFCTEVfRVhURU5TSU9OX0ZVTkNUSU9OKTsKLQotICAgICAgICAgICAgICAgICAgICAvL0NoZWNrIGlmIEZTUCBhbmQgU00gLSBvbmx5IHRoZW4gcHJvY2VlZCB3aXRoIGxvYWRpbmcKLSAgICAgICAgICAgICAgICAgICAgaWYgKG5hbWVzcGFjZSAhPSBudWxsICYmIGlzU2VjdXJlUHJvY2Vzc2luZwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmIGlzRXh0ZW5zaW9uRnVuY3Rpb25FbmFibGVkCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgKG5hbWVzcGFjZS5zdGFydHNXaXRoKEpBVkFfRVhUX1hBTEFOKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IG5hbWVzcGFjZS5zdGFydHNXaXRoKEpBVkFfRVhUX1hTTFRDKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IG5hbWVzcGFjZS5zdGFydHNXaXRoKEpBVkFfRVhUX1hBTEFOX09MRCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCBuYW1lc3BhY2Uuc3RhcnRzV2l0aChYQUxBTl9DTEFTU1BBQ0tBR0VfTkFNRVNQQUNFKSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIF9jbGF6eiA9IGdldFhTTFRDKCkubG9hZEV4dGVybmFsRnVuY3Rpb24oX2NsYXNzTmFtZSk7Ci0gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBfY2xhenogPSBPYmplY3RGYWN0b3J5LmZpbmRQcm92aWRlckNsYXNzKF9jbGFzc05hbWUsIHRydWUpOwotICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBpZiAoX2NsYXp6ID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgIGZpbmFsIEVycm9yTXNnIG1zZyA9Ci0gICAgICAgICAgICAgICAgICAgICAgICBuZXcgRXJyb3JNc2coRXJyb3JNc2cuQ0xBU1NfTk9UX0ZPVU5EX0VSUiwgX2NsYXNzTmFtZSk7Ci0gICAgICAgICAgICAgICAgICBnZXRQYXJzZXIoKS5yZXBvcnRFcnJvcihDb25zdGFudHMuRVJST1IsIG1zZyk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIG1ldGhvZE5hbWUgPSBfZm5hbWUuZ2V0TG9jYWxQYXJ0KCk7Ci0gICAgICAgICAgICAgIGZpbmFsIE1ldGhvZFtdIG1ldGhvZHMgPSBfY2xhenouZ2V0TWV0aG9kcygpOwotCi0gICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbWV0aG9kcy5sZW5ndGg7IGkrKykgewotICAgICAgICAgICAgICAgIGZpbmFsIGludCBtb2RzID0gbWV0aG9kc1tpXS5nZXRNb2RpZmllcnMoKTsKLSAgICAgICAgICAgICAgICAvLyBJcyBpdCBwdWJsaWMgYW5kIHNhbWUgbnVtYmVyIG9mIGFyZ3MgPwotICAgICAgICAgICAgICAgIGlmIChNb2RpZmllci5pc1B1YmxpYyhtb2RzKQotICAgICAgICAgICAgICAgICAgICAmJiBtZXRob2RzW2ldLmdldE5hbWUoKS5lcXVhbHMobWV0aG9kTmFtZSkKLSAgICAgICAgICAgICAgICAgICAgJiYgbWV0aG9kc1tpXS5nZXRQYXJhbWV0ZXJUeXBlcygpLmxlbmd0aCA9PSBuQXJncykKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICBpZiAocmVzdWx0ID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gbmV3IFZlY3RvcigpOwotICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgcmVzdWx0LmFkZEVsZW1lbnQobWV0aG9kc1tpXSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgICBmaW5hbCBFcnJvck1zZyBtc2cgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuQ0xBU1NfTk9UX0ZPVU5EX0VSUiwgX2NsYXNzTmFtZSk7Ci0gICAgICAgICAgICAgICAgICBnZXRQYXJzZXIoKS5yZXBvcnRFcnJvcihDb25zdGFudHMuRVJST1IsIG1zZyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgfQotICAgICAgICAgIHJldHVybiByZXN1bHQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhIHZlY3RvciB3aXRoIGFsbCBjb25zdHJ1Y3RvcnMgbmFtZWQgPGNvZGU+X2ZuYW1lPC9jb2RlPgotICAgICAqIGFmdGVyIHN0cmlwcGluZyBpdHMgbmFtZXNwYWNlIG9yIDxjb2RlPm51bGw8L2NvZGU+Ci0gICAgICogaWYgbm8gc3VjaCBtZXRob2RzIGV4aXN0LgotICAgICAqLwotICAgIHByaXZhdGUgVmVjdG9yIGZpbmRDb25zdHJ1Y3RvcnMoKSB7Ci0gICAgICAgIFZlY3RvciByZXN1bHQgPSBudWxsOwotICAgICAgICBmaW5hbCBTdHJpbmcgbmFtZXNwYWNlID0gX2ZuYW1lLmdldE5hbWVzcGFjZSgpOwotCi0gICAgICAgIGZpbmFsIGludCBuQXJncyA9IF9hcmd1bWVudHMuc2l6ZSgpOwotICAgICAgICB0cnkgewotICAgICAgICAgIGlmIChfY2xhenogPT0gbnVsbCkgewotICAgICAgICAgICAgX2NsYXp6ID0gT2JqZWN0RmFjdG9yeS5maW5kUHJvdmlkZXJDbGFzcyhfY2xhc3NOYW1lLCB0cnVlKTsKLQotICAgICAgICAgICAgaWYgKF9jbGF6eiA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgIGZpbmFsIEVycm9yTXNnIG1zZyA9IG5ldyBFcnJvck1zZyhFcnJvck1zZy5DTEFTU19OT1RfRk9VTkRfRVJSLCBfY2xhc3NOYW1lKTsKLSAgICAgICAgICAgICAgZ2V0UGFyc2VyKCkucmVwb3J0RXJyb3IoQ29uc3RhbnRzLkVSUk9SLCBtc2cpOwotICAgICAgICAgICAgfQotICAgICAgICAgIH0KLQotICAgICAgICAgIGZpbmFsIENvbnN0cnVjdG9yW10gY29uc3RydWN0b3JzID0gX2NsYXp6LmdldENvbnN0cnVjdG9ycygpOwotCi0gICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb25zdHJ1Y3RvcnMubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgICAgZmluYWwgaW50IG1vZHMgPSBjb25zdHJ1Y3RvcnNbaV0uZ2V0TW9kaWZpZXJzKCk7Ci0gICAgICAgICAgICAgIC8vIElzIGl0IHB1YmxpYywgc3RhdGljIGFuZCBzYW1lIG51bWJlciBvZiBhcmdzID8KLSAgICAgICAgICAgICAgaWYgKE1vZGlmaWVyLmlzUHVibGljKG1vZHMpICYmCi0gICAgICAgICAgICAgICAgICBjb25zdHJ1Y3RvcnNbaV0uZ2V0UGFyYW1ldGVyVHlwZXMoKS5sZW5ndGggPT0gbkFyZ3MpCi0gICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBpZiAocmVzdWx0ID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IG5ldyBWZWN0b3IoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgcmVzdWx0LmFkZEVsZW1lbnQoY29uc3RydWN0b3JzW2ldKTsKLSAgICAgICAgICAgICAgfQotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgZmluYWwgRXJyb3JNc2cgbXNnID0gbmV3IEVycm9yTXNnKEVycm9yTXNnLkNMQVNTX05PVF9GT1VORF9FUlIsIF9jbGFzc05hbWUpOwotICAgICAgICAgIGdldFBhcnNlcigpLnJlcG9ydEVycm9yKENvbnN0YW50cy5FUlJPUiwgbXNnKTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiByZXN1bHQ7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBDb21wdXRlIHRoZSBKVk0gc2lnbmF0dXJlIGZvciB0aGUgY2xhc3MuCi0gICAgICovCi0gICAgc3RhdGljIGZpbmFsIFN0cmluZyBnZXRTaWduYXR1cmUoQ2xhc3MgY2xhenopIHsKLSAgICAgICAgaWYgKGNsYXp6LmlzQXJyYXkoKSkgewotICAgICAgICAgICAgZmluYWwgU3RyaW5nQnVmZmVyIHNiID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotICAgICAgICAgICAgQ2xhc3MgY2wgPSBjbGF6ejsKLSAgICAgICAgICAgIHdoaWxlIChjbC5pc0FycmF5KCkpIHsKLSAgICAgICAgICAgICAgICBzYi5hcHBlbmQoIlsiKTsKLSAgICAgICAgICAgICAgICBjbCA9IGNsLmdldENvbXBvbmVudFR5cGUoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHNiLmFwcGVuZChnZXRTaWduYXR1cmUoY2wpKTsKLSAgICAgICAgICAgIHJldHVybiBzYi50b1N0cmluZygpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKGNsYXp6LmlzUHJpbWl0aXZlKCkpIHsKLSAgICAgICAgICAgIGlmIChjbGF6eiA9PSBJbnRlZ2VyLlRZUEUpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gIkkiOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoY2xhenogPT0gQnl0ZS5UWVBFKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuICJCIjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKGNsYXp6ID09IExvbmcuVFlQRSkgewotICAgICAgICAgICAgICAgIHJldHVybiAiSiI7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChjbGF6eiA9PSBGbG9hdC5UWVBFKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuICJGIjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKGNsYXp6ID09IERvdWJsZS5UWVBFKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuICJEIjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKGNsYXp6ID09IFNob3J0LlRZUEUpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gIlMiOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoY2xhenogPT0gQ2hhcmFjdGVyLlRZUEUpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gIkMiOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoY2xhenogPT0gQm9vbGVhbi5UWVBFKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuICJaIjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKGNsYXp6ID09IFZvaWQuVFlQRSkgewotICAgICAgICAgICAgICAgIHJldHVybiAiViI7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgbmFtZSA9IGNsYXp6LnRvU3RyaW5nKCk7Ci0gICAgICAgICAgICAgICAgRXJyb3JNc2cgZXJyID0gbmV3IEVycm9yTXNnKEVycm9yTXNnLlVOS05PV05fU0lHX1RZUEVfRVJSLG5hbWUpOwotICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnIudG9TdHJpbmcoKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gIkwiICsgY2xhenouZ2V0TmFtZSgpLnJlcGxhY2UoJy4nLCAnLycpICsgJzsnOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29tcHV0ZSB0aGUgSlZNIG1ldGhvZCBkZXNjcmlwdG9yIGZvciB0aGUgbWV0aG9kLgotICAgICAqLwotICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgZ2V0U2lnbmF0dXJlKE1ldGhvZCBtZXRoKSB7Ci0gICAgICAgIGZpbmFsIFN0cmluZ0J1ZmZlciBzYiA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLSAgICAgICAgc2IuYXBwZW5kKCcoJyk7Ci0gICAgICAgIGZpbmFsIENsYXNzW10gcGFyYW1zID0gbWV0aC5nZXRQYXJhbWV0ZXJUeXBlcygpOyAvLyBhdm9pZCBjbG9uZQotICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IHBhcmFtcy5sZW5ndGg7IGorKykgewotICAgICAgICAgICAgc2IuYXBwZW5kKGdldFNpZ25hdHVyZShwYXJhbXNbal0pKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gc2IuYXBwZW5kKCcpJykuYXBwZW5kKGdldFNpZ25hdHVyZShtZXRoLmdldFJldHVyblR5cGUoKSkpCi0gICAgICAgICAgICAudG9TdHJpbmcoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb21wdXRlIHRoZSBKVk0gY29uc3RydWN0b3IgZGVzY3JpcHRvciBmb3IgdGhlIGNvbnN0cnVjdG9yLgotICAgICAqLwotICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgZ2V0U2lnbmF0dXJlKENvbnN0cnVjdG9yIGNvbnMpIHsKLSAgICAgICAgZmluYWwgU3RyaW5nQnVmZmVyIHNiID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotICAgICAgICBzYi5hcHBlbmQoJygnKTsKLSAgICAgICAgZmluYWwgQ2xhc3NbXSBwYXJhbXMgPSBjb25zLmdldFBhcmFtZXRlclR5cGVzKCk7IC8vIGF2b2lkIGNsb25lCi0gICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgcGFyYW1zLmxlbmd0aDsgaisrKSB7Ci0gICAgICAgICAgICBzYi5hcHBlbmQoZ2V0U2lnbmF0dXJlKHBhcmFtc1tqXSkpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBzYi5hcHBlbmQoIilWIikudG9TdHJpbmcoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIHNpZ25hdHVyZSBvZiB0aGUgY3VycmVudCBtZXRob2QKLSAgICAgKi8KLSAgICBwcml2YXRlIFN0cmluZyBnZXRNZXRob2RTaWduYXR1cmUoVmVjdG9yIGFyZ3NUeXBlKSB7Ci0gICAgICAgIGZpbmFsIFN0cmluZ0J1ZmZlciBidWYgPSBuZXcgU3RyaW5nQnVmZmVyKF9jbGFzc05hbWUpOwotICAgICAgICBidWYuYXBwZW5kKCcuJykuYXBwZW5kKF9mbmFtZS5nZXRMb2NhbFBhcnQoKSkuYXBwZW5kKCcoJyk7Ci0KLSAgICAgICAgaW50IG5BcmdzID0gYXJnc1R5cGUuc2l6ZSgpOwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG5BcmdzOyBpKyspIHsKLSAgICAgICAgICAgIGZpbmFsIFR5cGUgaW50VHlwZSA9IChUeXBlKWFyZ3NUeXBlLmVsZW1lbnRBdChpKTsKLSAgICAgICAgICAgIGJ1Zi5hcHBlbmQoaW50VHlwZS50b1N0cmluZygpKTsKLSAgICAgICAgICAgIGlmIChpIDwgbkFyZ3MgLSAxKSBidWYuYXBwZW5kKCIsICIpOwotICAgICAgICB9Ci0KLSAgICAgICAgYnVmLmFwcGVuZCgnKScpOwotICAgICAgICByZXR1cm4gYnVmLnRvU3RyaW5nKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVG8gc3VwcG9ydCBFWFNMVCBleHRlbnNpb25zLCBjb252ZXJ0IG5hbWVzIHdpdGggZGFzaCB0byBhbGxvd2FibGUgSmF2YSBuYW1lczoKLSAgICAgKiBlLmcuLCBjb252ZXJ0IGFiYy14eXogdG8gYWJjWHl6LgotICAgICAqIE5vdGU6IGRhc2hlcyBvbmx5IGFwcGVhciBpbiBtaWRkbGUgb2YgYW4gRVhTTFQgZnVuY3Rpb24gb3IgZWxlbWVudCBuYW1lLgotICAgICAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgU3RyaW5nIHJlcGxhY2VEYXNoKFN0cmluZyBuYW1lKQotICAgIHsKLSAgICAgICAgY2hhciBkYXNoID0gJy0nOwotICAgICAgICBmaW5hbCBTdHJpbmdCdWlsZGVyIGJ1ZmYgPSBuZXcgU3RyaW5nQnVpbGRlcigiIik7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbmFtZS5sZW5ndGgoKTsgaSsrKSB7Ci0gICAgICAgIGlmIChpID4gMCAmJiBuYW1lLmNoYXJBdChpLTEpID09IGRhc2gpCi0gICAgICAgICAgICBidWZmLmFwcGVuZChDaGFyYWN0ZXIudG9VcHBlckNhc2UobmFtZS5jaGFyQXQoaSkpKTsKLSAgICAgICAgZWxzZSBpZiAobmFtZS5jaGFyQXQoaSkgIT0gZGFzaCkKLSAgICAgICAgICAgIGJ1ZmYuYXBwZW5kKG5hbWUuY2hhckF0KGkpKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gYnVmZi50b1N0cmluZygpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZSBjb2RlIHRvIGNhbGwgdGhlIEJhc2lzTGlicmFyeS51bmFsbG93ZWRfZXh0ZW5zaW9uRihTdHJpbmcpCi0gICAgICogbWV0aG9kLgotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCB0cmFuc2xhdGVVbmFsbG93ZWRFeHRlbnNpb24oQ29uc3RhbnRQb29sR2VuIGNwZywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluc3RydWN0aW9uTGlzdCBpbCkgewotICAgICAgICBpbnQgaW5kZXggPSBjcGcuYWRkTWV0aG9kcmVmKEJBU0lTX0xJQlJBUllfQ0xBU1MsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInVuYWxsb3dlZF9leHRlbnNpb25fZnVuY3Rpb25GIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKExqYXZhL2xhbmcvU3RyaW5nOylWIik7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsIF9mbmFtZS50b1N0cmluZygpKSk7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFU1RBVElDKGluZGV4KSk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9HZW5lcmF0ZUlkQ2FsbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9HZW5lcmF0ZUlkQ2FsbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA5ZmZhZTQxLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvR2VuZXJhdGVJZENhbGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDU3ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IEdlbmVyYXRlSWRDYWxsLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMDEgMTU6MzM6MTcgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQ29uc3RhbnRQb29sR2VuOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFU1RBVElDOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW5zdHJ1Y3Rpb25MaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkNsYXNzR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLk1ldGhvZEdlbmVyYXRvcjsKLQotLyoqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKi8KLWZpbmFsIGNsYXNzIEdlbmVyYXRlSWRDYWxsIGV4dGVuZHMgRnVuY3Rpb25DYWxsIHsKLSAgICBwdWJsaWMgR2VuZXJhdGVJZENhbGwoUU5hbWUgZm5hbWUsIFZlY3RvciBhcmd1bWVudHMpIHsKLSAgICAgICAgc3VwZXIoZm5hbWUsIGFyZ3VtZW50cyk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLSAgICAgICAgaWYgKGFyZ3VtZW50Q291bnQoKSA9PSAwKSB7Ci0gICAgICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZENvbnRleHROb2RlKCkpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgeyAgICAgICAgICAgICAgICAgIC8vIG9uZSBhcmd1bWVudAotICAgICAgICAgICAgYXJndW1lbnQoKS50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgIH0KLSAgICAgICAgZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRVNUQVRJQyhjcGcuYWRkTWV0aG9kcmVmKEJBU0lTX0xJQlJBUllfQ0xBU1MsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImdlbmVyYXRlX2lkRiIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcmV1c2Ugc2lnbmF0dXJlCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR0VUX05PREVfTkFNRV9TSUcpKSk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9JZEtleVBhdHRlcm4uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvSWRLZXlQYXR0ZXJuLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDg0NTExN2QuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9JZEtleVBhdHRlcm4uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEyOSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBJZEtleVBhdHRlcm4uamF2YSx2IDEuNSAyMDA1LzA5LzI4IDEzOjQ4OjEwIHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQ29uc3RhbnRQb29sR2VuOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuR09UTzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklGTkU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JTlZPS0VJTlRFUkZBQ0U7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JTlZPS0VWSVJUVUFMOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW5zdHJ1Y3Rpb25MaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuUFVTSDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5DbGFzc0dlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5NZXRob2RHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlQ2hlY2tFcnJvcjsKLQotLyoqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKi8KLWFic3RyYWN0IGNsYXNzIElkS2V5UGF0dGVybiBleHRlbmRzIExvY2F0aW9uUGF0aFBhdHRlcm4gewotCi0gICAgcHJvdGVjdGVkIFJlbGF0aXZlUGF0aFBhdHRlcm4gX2xlZnQgPSBudWxsOzsKLSAgICBwcml2YXRlIFN0cmluZyBfaW5kZXggPSBudWxsOwotICAgIHByaXZhdGUgU3RyaW5nIF92YWx1ZSA9IG51bGw7OwotCi0gICAgcHVibGljIElkS2V5UGF0dGVybihTdHJpbmcgaW5kZXgsIFN0cmluZyB2YWx1ZSkgewotICAgICAgICBfaW5kZXggPSBpbmRleDsKLSAgICAgICAgX3ZhbHVlID0gdmFsdWU7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRJbmRleE5hbWUoKSB7Ci0gICAgICAgIHJldHVybihfaW5kZXgpOwotICAgIH0KLQotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0gICAgICAgIHJldHVybiBUeXBlLk5vZGVTZXQ7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gaXNXaWxkY2FyZCgpIHsKLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldExlZnQoUmVsYXRpdmVQYXRoUGF0dGVybiBsZWZ0KSB7Ci0gICAgICAgIF9sZWZ0ID0gbGVmdDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RlcFBhdHRlcm4gZ2V0S2VybmVsUGF0dGVybigpIHsKLSAgICAgICAgcmV0dXJuKG51bGwpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHJlZHVjZUtlcm5lbFBhdHRlcm4oKSB7IH0KLQotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0gICAgICAgIHJldHVybiAiaWQva2V5UGF0dGVybigiICsgX2luZGV4ICsgIiwgIiArIF92YWx1ZSArICcpJzsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgd2hlbiB0aGUgY29uc3RydWN0b3IgaXMgY29tcGlsZWQgaW4KLSAgICAgKiBTdHlsZXNoZWV0LmNvbXBpbGVDb25zdHJ1Y3RvcigpIGFuZCBub3QgYXMgdGhlIHN5bnRheCB0cmVlIGlzIHRyYXZlcnNlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLQotICAgICAgICBmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQotICAgICAgICAvLyBSZXR1cm5zIHRoZSBLZXlJbmRleCBvYmplY3Qgb2YgYSBnaXZlbiBuYW1lCi0gICAgICAgIGZpbmFsIGludCBnZXRLZXlJbmRleCA9IGNwZy5hZGRNZXRob2RyZWYoVFJBTlNMRVRfQ0xBU1MsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImdldEtleUluZGV4IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKExqYXZhL2xhbmcvU3RyaW5nOykiKwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEtFWV9JTkRFWF9TSUcpOwotCi0gICAgICAgIC8vIEluaXRpYWxpc2VzIGEgS2V5SW5kZXggdG8gcmV0dXJuIG5vZGVzIHdpdGggc3BlY2lmaWMgdmFsdWVzCi0gICAgICAgIGZpbmFsIGludCBsb29rdXBJZCA9IGNwZy5hZGRNZXRob2RyZWYoS0VZX0lOREVYX0NMQVNTLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJjb250YWluc0lEIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKElMamF2YS9sYW5nL09iamVjdDspSSIpOwotICAgICAgICBmaW5hbCBpbnQgbG9va3VwS2V5ID0gY3BnLmFkZE1ldGhvZHJlZihLRVlfSU5ERVhfQ0xBU1MsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJjb250YWluc0tleSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoSUxqYXZhL2xhbmcvT2JqZWN0OylJIik7Ci0gICAgICAgIGZpbmFsIGludCBnZXROb2RlSWRlbnQgPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKERPTV9JTlRGLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZ2V0Tm9kZUlkZW50IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIihJKSIrTk9ERV9TSUcpOwotCi0gICAgICAgIC8vIENhbGwgZ2V0S2V5SW5kZXggaW4gQWJzdHJhY3RUcmFuc2xldCB3aXRoIHRoZSBuYW1lIG9mIHRoZSBrZXkKLSAgICAgICAgLy8gdG8gZ2V0IHRoZSBpbmRleCBmb3IgdGhpcyBrZXkgKHdoaWNoIGlzIGFsc28gYSBub2RlIGl0ZXJhdG9yKS4KLSAgICAgICAgaWwuYXBwZW5kKGNsYXNzR2VuLmxvYWRUcmFuc2xldCgpKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZyxfaW5kZXgpKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VWSVJUVUFMKGdldEtleUluZGV4KSk7Ci0KLSAgICAgICAgLy8gTm93IHVzZSB0aGUgdmFsdWUgaW4gdGhlIHNlY29uZCBhcmd1bWVudCB0byBkZXRlcm1pbmUgd2hhdCBub2RlcwotICAgICAgICAvLyB0aGUgaXRlcmF0b3Igc2hvdWxkIHJldHVybi4KLSAgICAgICAgaWwuYXBwZW5kKFNXQVApOwotICAgICAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLF92YWx1ZSkpOwotICAgICAgICBpZiAodGhpcyBpbnN0YW5jZW9mIElkUGF0dGVybikKLSAgICAgICAgewotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VWSVJUVUFMKGxvb2t1cElkKSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICB7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRVZJUlRVQUwobG9va3VwS2V5KSk7Ci0gICAgICAgIH0KLQotICAgICAgICBfdHJ1ZUxpc3QuYWRkKGlsLmFwcGVuZChuZXcgSUZORShudWxsKSkpOwotICAgICAgICBfZmFsc2VMaXN0LmFkZChpbC5hcHBlbmQobmV3IEdPVE8obnVsbCkpKTsKLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvSWRQYXR0ZXJuLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0lkUGF0dGVybi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlZjMzNjJjLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvSWRQYXR0ZXJuLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzNyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBJZFBhdHRlcm4uamF2YSx2IDEuMi40LjEgMjAwNS8wOS8wMSAxNTozNzozMyBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXI7Ci0KLQotLyoqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKi8KLWZpbmFsIGNsYXNzIElkUGF0dGVybiBleHRlbmRzIElkS2V5UGF0dGVybiB7Ci0KLSAgICBwdWJsaWMgSWRQYXR0ZXJuKFN0cmluZyBpZCkgewotICAgICAgICBzdXBlcigiIyNpZCIsaWQpOwotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9JZi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9JZi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhOTJhNmEwLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvSWYuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExMiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBJZi5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzAxIDE1OjM5OjQ3IHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW5zdHJ1Y3Rpb25IYW5kbGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JbnN0cnVjdGlvbkxpc3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuQm9vbGVhblR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuQ2xhc3NHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuRXJyb3JNc2c7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuTWV0aG9kR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZUNoZWNrRXJyb3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVXRpbDsKLQotLyoqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqLwotZmluYWwgY2xhc3MgSWYgZXh0ZW5kcyBJbnN0cnVjdGlvbiB7Ci0KLSAgICBwcml2YXRlIEV4cHJlc3Npb24gX3Rlc3Q7Ci0gICAgcHJpdmF0ZSBib29sZWFuICAgIF9pZ25vcmUgPSBmYWxzZTsKLQotICAgIC8qKgotICAgICAqIERpc3BsYXkgdGhlIGNvbnRlbnRzIG9mIHRoaXMgZWxlbWVudAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGRpc3BsYXkoaW50IGluZGVudCkgewotICAgICAgICBpbmRlbnQoaW5kZW50KTsKLSAgICAgICAgVXRpbC5wcmludGxuKCJJZiIpOwotICAgICAgICBpbmRlbnQoaW5kZW50ICsgSW5kZW50SW5jcmVtZW50KTsKLSAgICAgICAgU3lzdGVtLm91dC5wcmludCgidGVzdCAiKTsKLSAgICAgICAgVXRpbC5wcmludGxuKF90ZXN0LnRvU3RyaW5nKCkpOwotICAgICAgICBkaXNwbGF5Q29udGVudHMoaW5kZW50ICsgSW5kZW50SW5jcmVtZW50KTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBQYXJzZSB0aGUgInRlc3QiIGV4cHJlc3Npb24gYW5kIGNvbnRlbnRzIG9mIHRoaXMgZWxlbWVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBwYXJzZUNvbnRlbnRzKFBhcnNlciBwYXJzZXIpIHsKLSAgICAgICAgLy8gUGFyc2UgdGhlICJ0ZXN0IiBleHByZXNzaW9uCi0gICAgICAgIF90ZXN0ID0gcGFyc2VyLnBhcnNlRXhwcmVzc2lvbih0aGlzLCAidGVzdCIsIG51bGwpOwotCi0gICAgICAgIC8vIE1ha2Ugc3VyZSByZXF1aXJlZCBhdHRyaWJ1dGUocykgaGF2ZSBiZWVuIHNldAotICAgICAgICBpZiAoX3Rlc3QuaXNEdW1teSgpKSB7Ci0gICAgICAgICAgICByZXBvcnRFcnJvcih0aGlzLCBwYXJzZXIsIEVycm9yTXNnLlJFUVVJUkVEX0FUVFJfRVJSLCAidGVzdCIpOwotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gSWdub3JlIHhzbDppZiB3aGVuIHRlc3QgaXMgZmFsc2UgKGZ1bmN0aW9uLWF2YWlsYWJsZSgpIGFuZAotICAgICAgICAvLyBlbGVtZW50LWF2YWlsYWJsZSgpKQotICAgICAgICBPYmplY3QgcmVzdWx0ID0gX3Rlc3QuZXZhbHVhdGVBdENvbXBpbGVUaW1lKCk7Ci0gICAgICAgIGlmIChyZXN1bHQgIT0gbnVsbCAmJiByZXN1bHQgaW5zdGFuY2VvZiBCb29sZWFuKSB7Ci0gICAgICAgICAgICBfaWdub3JlID0gISgoQm9vbGVhbikgcmVzdWx0KS5ib29sZWFuVmFsdWUoKTsKLSAgICAgICAgfQotCi0gICAgICAgIHBhcnNlQ2hpbGRyZW4ocGFyc2VyKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUeXBlLWNoZWNrIHRoZSAidGVzdCIgZXhwcmVzc2lvbiBhbmQgY29udGVudHMgb2YgdGhpcyBlbGVtZW50LgotICAgICAqIFRoZSBjb250ZW50cyB3aWxsIGJlIGlnbm9yZWQgaWYgd2Uga25vdyB0aGUgdGVzdCB3aWxsIGFsd2F5cyBmYWlsLgotICAgICAqLwotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0gICAgICAgIC8vIFR5cGUtY2hlY2sgdGhlICJ0ZXN0IiBleHByZXNzaW9uCi0gICAgICAgIGlmIChfdGVzdC50eXBlQ2hlY2soc3RhYmxlKSBpbnN0YW5jZW9mIEJvb2xlYW5UeXBlID09IGZhbHNlKSB7Ci0gICAgICAgICAgICBfdGVzdCA9IG5ldyBDYXN0RXhwcihfdGVzdCwgVHlwZS5Cb29sZWFuKTsKLSAgICAgICAgfQotICAgICAgICAvLyBUeXBlIGNoZWNrIHRoZSBlbGVtZW50IGNvbnRlbnRzCi0gICAgICAgIGlmICghX2lnbm9yZSkgewotICAgICAgICAgICAgdHlwZUNoZWNrQ29udGVudHMoc3RhYmxlKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gVHlwZS5Wb2lkOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZSB0aGUgInRlc3QiIGV4cHJlc3Npb24gYW5kIGNvbnRlbnRzIG9mIHRoaXMgZWxlbWVudC4KLSAgICAgKiBUaGUgY29udGVudHMgd2lsbCBiZSBpZ25vcmVkIGlmIHdlIGtub3cgdGhlIHRlc3Qgd2lsbCBhbHdheXMgZmFpbC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotICAgICAgICBfdGVzdC50cmFuc2xhdGVEZXN5bnRoZXNpemVkKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICAvLyByZW1lbWJlciBlbmQgb2YgY29uZGl0aW9uCi0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uSGFuZGxlIHRydWVjID0gaWwuZ2V0RW5kKCk7Ci0gICAgICAgIGlmICghX2lnbm9yZSkgewotICAgICAgICAgICAgdHJhbnNsYXRlQ29udGVudHMoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgIH0KLSAgICAgICAgX3Rlc3QuYmFja1BhdGNoRmFsc2VMaXN0KGlsLmFwcGVuZChOT1ApKTsKLSAgICAgICAgX3Rlc3QuYmFja1BhdGNoVHJ1ZUxpc3QodHJ1ZWMuZ2V0TmV4dCgpKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0lsbGVnYWxDaGFyRXhjZXB0aW9uLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0lsbGVnYWxDaGFyRXhjZXB0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDYyMjcxYjIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9JbGxlZ2FsQ2hhckV4Y2VwdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzUgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogSWxsZWdhbENoYXJFeGNlcHRpb24uamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xMyAxMjozOToxNSBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXI7Ci0KLS8qKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICovCi1jbGFzcyBJbGxlZ2FsQ2hhckV4Y2VwdGlvbiBleHRlbmRzIEV4Y2VwdGlvbiB7Ci0gICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC02NjcyMzY2NzY3MDYyMjYyNjZMOwotICAgIHB1YmxpYyBJbGxlZ2FsQ2hhckV4Y2VwdGlvbihTdHJpbmcgcykgewotICAgICAgICBzdXBlcihzKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0ltcG9ydC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9JbXBvcnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNTIwN2YzOC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0ltcG9ydC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTY1ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDcsIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKi8KLS8qCi0gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKLSAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAotICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgotICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKLSAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCi0gKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogSW1wb3J0LmphdmEsdiAxLjggMjAwNy8wNC8wOSAyMTozMDo0MCBqb2VodyBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLlhhbGFuQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC51dGlscy5TZWN1cml0eVN1cHBvcnQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuQ2xhc3NHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuRXJyb3JNc2c7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuTWV0aG9kR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZUNoZWNrRXJyb3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5TeXN0ZW1JRFJlc29sdmVyOwotaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKLWltcG9ydCBqYXZheC54bWwuWE1MQ29uc3RhbnRzOwotaW1wb3J0IG9yZy54bWwuc2F4LklucHV0U291cmNlOwotaW1wb3J0IG9yZy54bWwuc2F4LlhNTFJlYWRlcjsKLQotLyoqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKiBAYXV0aG9yIEVyd2luIEJvbHdpZHQgPGVqYkBrbG9tcC5vcmc+Ci0gKiBAYXV0aG9yIEd1bm5sYXVndXIgQnJpZW0gPGd0aGJAZGltb24uaXM+Ci0gKi8KLWZpbmFsIGNsYXNzIEltcG9ydCBleHRlbmRzIFRvcExldmVsRWxlbWVudCB7Ci0KLSAgICBwcml2YXRlIFN0eWxlc2hlZXQgX2ltcG9ydGVkID0gbnVsbDsKLQotICAgIHB1YmxpYyBTdHlsZXNoZWV0IGdldEltcG9ydGVkU3R5bGVzaGVldCgpIHsKLSAgICAgICAgcmV0dXJuIF9pbXBvcnRlZDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBwYXJzZUNvbnRlbnRzKGZpbmFsIFBhcnNlciBwYXJzZXIpIHsKLSAgICAgICAgZmluYWwgWFNMVEMgeHNsdGMgPSBwYXJzZXIuZ2V0WFNMVEMoKTsKLSAgICAgICAgZmluYWwgU3R5bGVzaGVldCBjb250ZXh0ID0gcGFyc2VyLmdldEN1cnJlbnRTdHlsZXNoZWV0KCk7Ci0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIFN0cmluZyBkb2NUb0xvYWQgPSBnZXRBdHRyaWJ1dGUoImhyZWYiKTsKLSAgICAgICAgICAgIGlmIChjb250ZXh0LmNoZWNrRm9yTG9vcChkb2NUb0xvYWQpKSB7Ci0gICAgICAgICAgICAgICAgZmluYWwgRXJyb3JNc2cgbXNnID0gbmV3IEVycm9yTXNnKEVycm9yTXNnLkNJUkNVTEFSX0lOQ0xVREVfRVJSLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2NUb0xvYWQsIHRoaXMpOwotICAgICAgICAgICAgICAgIHBhcnNlci5yZXBvcnRFcnJvcihDb25zdGFudHMuRkFUQUwsIG1zZyk7Ci0gICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBJbnB1dFNvdXJjZSBpbnB1dCA9IG51bGw7Ci0gICAgICAgICAgICBYTUxSZWFkZXIgcmVhZGVyID0gbnVsbDsKLSAgICAgICAgICAgIFN0cmluZyBjdXJyTG9hZGVkRG9jID0gY29udGV4dC5nZXRTeXN0ZW1JZCgpOwotICAgICAgICAgICAgU291cmNlTG9hZGVyIGxvYWRlciA9IGNvbnRleHQuZ2V0U291cmNlTG9hZGVyKCk7Ci0KLSAgICAgICAgICAgIC8vIFVzZSBTb3VyY2VMb2FkZXIgaWYgYXZhaWxhYmxlCi0gICAgICAgICAgICBpZiAobG9hZGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBpbnB1dCA9IGxvYWRlci5sb2FkU291cmNlKGRvY1RvTG9hZCwgY3VyckxvYWRlZERvYywgeHNsdGMpOwotICAgICAgICAgICAgICAgIGlmIChpbnB1dCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGRvY1RvTG9hZCA9IGlucHV0LmdldFN5c3RlbUlkKCk7Ci0gICAgICAgICAgICAgICAgICAgIHJlYWRlciA9IHhzbHRjLmdldFhNTFJlYWRlcigpOwotICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocGFyc2VyLmVycm9yc0ZvdW5kKCkpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gTm8gU291cmNlTG9hZGVyIG9yIG5vdCByZXNvbHZlZCBieSBTb3VyY2VMb2FkZXIKLSAgICAgICAgICAgIGlmIChpbnB1dCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZG9jVG9Mb2FkID0gU3lzdGVtSURSZXNvbHZlci5nZXRBYnNvbHV0ZVVSSShkb2NUb0xvYWQsIGN1cnJMb2FkZWREb2MpOwotICAgICAgICAgICAgICAgIFN0cmluZyBhY2Nlc3NFcnJvciA9IFNlY3VyaXR5U3VwcG9ydC5jaGVja0FjY2Vzcyhkb2NUb0xvYWQsCi0gICAgICAgICAgICAgICAgICAgICAgICAoU3RyaW5nKXhzbHRjLmdldFByb3BlcnR5KFhNTENvbnN0YW50cy5BQ0NFU1NfRVhURVJOQUxfU1RZTEVTSEVFVCksCi0gICAgICAgICAgICAgICAgICAgICAgICBYYWxhbkNvbnN0YW50cy5BQ0NFU1NfRVhURVJOQUxfQUxMKTsKLQotICAgICAgICAgICAgICAgIGlmIChhY2Nlc3NFcnJvciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZpbmFsIEVycm9yTXNnIG1zZyA9IG5ldyBFcnJvck1zZyhFcnJvck1zZy5BQ0NFU1NJTkdfWFNMVF9UQVJHRVRfRVJSLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNlY3VyaXR5U3VwcG9ydC5zYW5pdGl6ZVBhdGgoZG9jVG9Mb2FkKSwgYWNjZXNzRXJyb3IsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcyk7Ci0gICAgICAgICAgICAgICAgICAgIHBhcnNlci5yZXBvcnRFcnJvcihDb25zdGFudHMuRkFUQUwsIG1zZyk7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaW5wdXQgPSBuZXcgSW5wdXRTb3VyY2UoZG9jVG9Mb2FkKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gUmV0dXJuIGlmIHdlIGNvdWxkIG5vdCByZXNvbHZlIHRoZSBVUkwKLSAgICAgICAgICAgIGlmIChpbnB1dCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZmluYWwgRXJyb3JNc2cgbXNnID0KLSAgICAgICAgICAgICAgICAgICAgbmV3IEVycm9yTXNnKEVycm9yTXNnLkZJTEVfTk9UX0ZPVU5EX0VSUiwgZG9jVG9Mb2FkLCB0aGlzKTsKLSAgICAgICAgICAgICAgICBwYXJzZXIucmVwb3J0RXJyb3IoQ29uc3RhbnRzLkZBVEFMLCBtc2cpOwotICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgZmluYWwgU3ludGF4VHJlZU5vZGUgcm9vdDsKLSAgICAgICAgICAgIGlmIChyZWFkZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJvb3QgPSBwYXJzZXIucGFyc2UocmVhZGVyLGlucHV0KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIHJvb3QgPSBwYXJzZXIucGFyc2UoaW5wdXQpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAocm9vdCA9PSBudWxsKSByZXR1cm47Ci0gICAgICAgICAgICBfaW1wb3J0ZWQgPSBwYXJzZXIubWFrZVN0eWxlc2hlZXQocm9vdCk7Ci0gICAgICAgICAgICBpZiAoX2ltcG9ydGVkID09IG51bGwpIHJldHVybjsKLQotICAgICAgICAgICAgX2ltcG9ydGVkLnNldFNvdXJjZUxvYWRlcihsb2FkZXIpOwotICAgICAgICAgICAgX2ltcG9ydGVkLnNldFN5c3RlbUlkKGRvY1RvTG9hZCk7Ci0gICAgICAgICAgICBfaW1wb3J0ZWQuc2V0UGFyZW50U3R5bGVzaGVldChjb250ZXh0KTsKLSAgICAgICAgICAgIF9pbXBvcnRlZC5zZXRJbXBvcnRpbmdTdHlsZXNoZWV0KGNvbnRleHQpOwotICAgICAgICBfaW1wb3J0ZWQuc2V0VGVtcGxhdGVJbmxpbmluZyhjb250ZXh0LmdldFRlbXBsYXRlSW5saW5pbmcoKSk7Ci0KLSAgICAgICAgICAgIC8vIHByZWNlZGVuY2UgZm9yIHRoZSBpbmNsdWRpbmcgc3R5bGVzaGVldAotICAgICAgICAgICAgZmluYWwgaW50IGN1cnJQcmVjZWRlbmNlID0gcGFyc2VyLmdldEN1cnJlbnRJbXBvcnRQcmVjZWRlbmNlKCk7Ci0gICAgICAgICAgICBmaW5hbCBpbnQgbmV4dFByZWNlZGVuY2UgPSBwYXJzZXIuZ2V0TmV4dEltcG9ydFByZWNlZGVuY2UoKTsKLSAgICAgICAgICAgIF9pbXBvcnRlZC5zZXRJbXBvcnRQcmVjZWRlbmNlKGN1cnJQcmVjZWRlbmNlKTsKLSAgICAgICAgICAgIGNvbnRleHQuc2V0SW1wb3J0UHJlY2VkZW5jZShuZXh0UHJlY2VkZW5jZSk7Ci0gICAgICAgICAgICBwYXJzZXIuc2V0Q3VycmVudFN0eWxlc2hlZXQoX2ltcG9ydGVkKTsKLSAgICAgICAgICAgIF9pbXBvcnRlZC5wYXJzZUNvbnRlbnRzKHBhcnNlcik7Ci0KLSAgICAgICAgICAgIGZpbmFsIEl0ZXJhdG9yPFN5bnRheFRyZWVOb2RlPiBlbGVtZW50cyA9IF9pbXBvcnRlZC5lbGVtZW50cygpOwotICAgICAgICAgICAgZmluYWwgU3R5bGVzaGVldCB0b3BTdHlsZXNoZWV0ID0gcGFyc2VyLmdldFRvcExldmVsU3R5bGVzaGVldCgpOwotICAgICAgICAgICAgd2hpbGUgKGVsZW1lbnRzLmhhc05leHQoKSkgewotICAgICAgICAgICAgICAgIGZpbmFsIFN5bnRheFRyZWVOb2RlIGVsZW1lbnQgPSBlbGVtZW50cy5uZXh0KCk7Ci0gICAgICAgICAgICAgICAgaWYgKGVsZW1lbnQgaW5zdGFuY2VvZiBUb3BMZXZlbEVsZW1lbnQpIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGVsZW1lbnQgaW5zdGFuY2VvZiBWYXJpYWJsZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgdG9wU3R5bGVzaGVldC5hZGRWYXJpYWJsZSgoVmFyaWFibGUpIGVsZW1lbnQpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGVsZW1lbnQgaW5zdGFuY2VvZiBQYXJhbSkgewotICAgICAgICAgICAgICAgICAgICAgICAgdG9wU3R5bGVzaGVldC5hZGRQYXJhbSgoUGFyYW0pIGVsZW1lbnQpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgdG9wU3R5bGVzaGVldC5hZGRFbGVtZW50KChUb3BMZXZlbEVsZW1lbnQpIGVsZW1lbnQpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgICAgfQotICAgICAgICBmaW5hbGx5IHsKLSAgICAgICAgICAgIHBhcnNlci5zZXRDdXJyZW50U3R5bGVzaGVldChjb250ZXh0KTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0gICAgICAgIHJldHVybiBUeXBlLlZvaWQ7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0gICAgICAgIC8vIGRvIG5vdGhpbmcKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0luY2x1ZGUuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvSW5jbHVkZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyOWQwN2Q0Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvSW5jbHVkZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTY0ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDcsIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKi8KLS8qCi0gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKLSAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAotICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgotICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKLSAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCi0gKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogSW5jbHVkZS5qYXZhLHYgMS44IDIwMDcvMDQvMDkgMjE6MzA6NDEgam9laHcgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC5YYWxhbkNvbnN0YW50czsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwudXRpbHMuU2VjdXJpdHlTdXBwb3J0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkNsYXNzR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkVycm9yTXNnOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLk1ldGhvZEdlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGVDaGVja0Vycm9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuU3lzdGVtSURSZXNvbHZlcjsKLWltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7Ci1pbXBvcnQgamF2YXgueG1sLlhNTENvbnN0YW50czsKLWltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKLWltcG9ydCBvcmcueG1sLnNheC5YTUxSZWFkZXI7Ci0KLS8qKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICogQGF1dGhvciBFcndpbiBCb2x3aWR0IDxlamJAa2xvbXAub3JnPgotICogQGF1dGhvciBHdW5ubGF1Z3VyIEJyaWVtIDxndGhiQGRpbW9uLmlzPgotICovCi1maW5hbCBjbGFzcyBJbmNsdWRlIGV4dGVuZHMgVG9wTGV2ZWxFbGVtZW50IHsKLQotICAgIHByaXZhdGUgU3R5bGVzaGVldCBfaW5jbHVkZWQgPSBudWxsOwotCi0gICAgcHVibGljIFN0eWxlc2hlZXQgZ2V0SW5jbHVkZWRTdHlsZXNoZWV0KCkgewotICAgICAgICByZXR1cm4gX2luY2x1ZGVkOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHBhcnNlQ29udGVudHMoZmluYWwgUGFyc2VyIHBhcnNlcikgewotICAgICAgICBYU0xUQyB4c2x0YyA9IHBhcnNlci5nZXRYU0xUQygpOwotICAgICAgICBTdHlsZXNoZWV0IGNvbnRleHQgPSBwYXJzZXIuZ2V0Q3VycmVudFN0eWxlc2hlZXQoKTsKLQotICAgICAgICBTdHJpbmcgZG9jVG9Mb2FkID0gZ2V0QXR0cmlidXRlKCJocmVmIik7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBpZiAoY29udGV4dC5jaGVja0Zvckxvb3AoZG9jVG9Mb2FkKSkgewotICAgICAgICAgICAgICAgIGZpbmFsIEVycm9yTXNnIG1zZyA9IG5ldyBFcnJvck1zZyhFcnJvck1zZy5DSVJDVUxBUl9JTkNMVURFX0VSUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9jVG9Mb2FkLCB0aGlzKTsKLSAgICAgICAgICAgICAgICBwYXJzZXIucmVwb3J0RXJyb3IoQ29uc3RhbnRzLkZBVEFMLCBtc2cpOwotICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgSW5wdXRTb3VyY2UgaW5wdXQgPSBudWxsOwotICAgICAgICAgICAgWE1MUmVhZGVyIHJlYWRlciA9IG51bGw7Ci0gICAgICAgICAgICBTdHJpbmcgY3VyckxvYWRlZERvYyA9IGNvbnRleHQuZ2V0U3lzdGVtSWQoKTsKLSAgICAgICAgICAgIFNvdXJjZUxvYWRlciBsb2FkZXIgPSBjb250ZXh0LmdldFNvdXJjZUxvYWRlcigpOwotCi0gICAgICAgICAgICAvLyBVc2UgU291cmNlTG9hZGVyIGlmIGF2YWlsYWJsZQotICAgICAgICAgICAgaWYgKGxvYWRlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgaW5wdXQgPSBsb2FkZXIubG9hZFNvdXJjZShkb2NUb0xvYWQsIGN1cnJMb2FkZWREb2MsIHhzbHRjKTsKLSAgICAgICAgICAgICAgICBpZiAoaW5wdXQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBkb2NUb0xvYWQgPSBpbnB1dC5nZXRTeXN0ZW1JZCgpOwotICAgICAgICAgICAgICAgICAgICByZWFkZXIgPSB4c2x0Yy5nZXRYTUxSZWFkZXIoKTsKLSAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHBhcnNlci5lcnJvcnNGb3VuZCgpKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIE5vIFNvdXJjZUxvYWRlciBvciBub3QgcmVzb2x2ZWQgYnkgU291cmNlTG9hZGVyCi0gICAgICAgICAgICBpZiAoaW5wdXQgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGRvY1RvTG9hZCA9IFN5c3RlbUlEUmVzb2x2ZXIuZ2V0QWJzb2x1dGVVUkkoZG9jVG9Mb2FkLCBjdXJyTG9hZGVkRG9jKTsKLSAgICAgICAgICAgICAgICBTdHJpbmcgYWNjZXNzRXJyb3IgPSBTZWN1cml0eVN1cHBvcnQuY2hlY2tBY2Nlc3MoZG9jVG9Mb2FkLAotICAgICAgICAgICAgICAgICAgICAgICAgKFN0cmluZyl4c2x0Yy5nZXRQcm9wZXJ0eShYTUxDb25zdGFudHMuQUNDRVNTX0VYVEVSTkFMX1NUWUxFU0hFRVQpLAotICAgICAgICAgICAgICAgICAgICAgICAgWGFsYW5Db25zdGFudHMuQUNDRVNTX0VYVEVSTkFMX0FMTCk7Ci0KLSAgICAgICAgICAgICAgICBpZiAoYWNjZXNzRXJyb3IgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBmaW5hbCBFcnJvck1zZyBtc2cgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuQUNDRVNTSU5HX1hTTFRfVEFSR0VUX0VSUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZWN1cml0eVN1cHBvcnQuc2FuaXRpemVQYXRoKGRvY1RvTG9hZCksIGFjY2Vzc0Vycm9yLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMpOwotICAgICAgICAgICAgICAgICAgICBwYXJzZXIucmVwb3J0RXJyb3IoQ29uc3RhbnRzLkZBVEFMLCBtc2cpOwotICAgICAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGlucHV0ID0gbmV3IElucHV0U291cmNlKGRvY1RvTG9hZCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIFJldHVybiBpZiB3ZSBjb3VsZCBub3QgcmVzb2x2ZSB0aGUgVVJMCi0gICAgICAgICAgICBpZiAoaW5wdXQgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZpbmFsIEVycm9yTXNnIG1zZyA9Ci0gICAgICAgICAgICAgICAgICAgIG5ldyBFcnJvck1zZyhFcnJvck1zZy5GSUxFX05PVF9GT1VORF9FUlIsIGRvY1RvTG9hZCwgdGhpcyk7Ci0gICAgICAgICAgICAgICAgcGFyc2VyLnJlcG9ydEVycm9yKENvbnN0YW50cy5GQVRBTCwgbXNnKTsKLSAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGZpbmFsIFN5bnRheFRyZWVOb2RlIHJvb3Q7Ci0gICAgICAgICAgICBpZiAocmVhZGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICByb290ID0gcGFyc2VyLnBhcnNlKHJlYWRlcixpbnB1dCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICByb290ID0gcGFyc2VyLnBhcnNlKGlucHV0KTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKHJvb3QgPT0gbnVsbCkgcmV0dXJuOwotICAgICAgICAgICAgX2luY2x1ZGVkID0gcGFyc2VyLm1ha2VTdHlsZXNoZWV0KHJvb3QpOwotICAgICAgICAgICAgaWYgKF9pbmNsdWRlZCA9PSBudWxsKSByZXR1cm47Ci0KLSAgICAgICAgICAgIF9pbmNsdWRlZC5zZXRTb3VyY2VMb2FkZXIobG9hZGVyKTsKLSAgICAgICAgICAgIF9pbmNsdWRlZC5zZXRTeXN0ZW1JZChkb2NUb0xvYWQpOwotICAgICAgICAgICAgX2luY2x1ZGVkLnNldFBhcmVudFN0eWxlc2hlZXQoY29udGV4dCk7Ci0gICAgICAgICAgICBfaW5jbHVkZWQuc2V0SW5jbHVkaW5nU3R5bGVzaGVldChjb250ZXh0KTsKLSAgICAgICAgICAgIF9pbmNsdWRlZC5zZXRUZW1wbGF0ZUlubGluaW5nKGNvbnRleHQuZ2V0VGVtcGxhdGVJbmxpbmluZygpKTsKLQotICAgICAgICAgICAgLy8gQW4gaW5jbHVkZWQgc3R5bGVzaGVldCBnZXRzIHRoZSBzYW1lIGltcG9ydCBwcmVjZWRlbmNlCi0gICAgICAgICAgICAvLyBhcyB0aGUgc3R5bGVzaGVldCB0aGF0IGluY2x1ZGVkIGl0LgotICAgICAgICAgICAgZmluYWwgaW50IHByZWNlZGVuY2UgPSBjb250ZXh0LmdldEltcG9ydFByZWNlZGVuY2UoKTsKLSAgICAgICAgICAgIF9pbmNsdWRlZC5zZXRJbXBvcnRQcmVjZWRlbmNlKHByZWNlZGVuY2UpOwotICAgICAgICAgICAgcGFyc2VyLnNldEN1cnJlbnRTdHlsZXNoZWV0KF9pbmNsdWRlZCk7Ci0gICAgICAgICAgICBfaW5jbHVkZWQucGFyc2VDb250ZW50cyhwYXJzZXIpOwotCi0gICAgICAgICAgICBmaW5hbCBJdGVyYXRvcjxTeW50YXhUcmVlTm9kZT4gZWxlbWVudHMgPSBfaW5jbHVkZWQuZWxlbWVudHMoKTsKLSAgICAgICAgICAgIGZpbmFsIFN0eWxlc2hlZXQgdG9wU3R5bGVzaGVldCA9IHBhcnNlci5nZXRUb3BMZXZlbFN0eWxlc2hlZXQoKTsKLSAgICAgICAgICAgIHdoaWxlIChlbGVtZW50cy5oYXNOZXh0KCkpIHsKLSAgICAgICAgICAgICAgICBmaW5hbCBTeW50YXhUcmVlTm9kZSBlbGVtZW50ID0gZWxlbWVudHMubmV4dCgpOwotICAgICAgICAgICAgICAgIGlmIChlbGVtZW50IGluc3RhbmNlb2YgVG9wTGV2ZWxFbGVtZW50KSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChlbGVtZW50IGluc3RhbmNlb2YgVmFyaWFibGUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHRvcFN0eWxlc2hlZXQuYWRkVmFyaWFibGUoKFZhcmlhYmxlKSBlbGVtZW50KTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChlbGVtZW50IGluc3RhbmNlb2YgUGFyYW0pIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHRvcFN0eWxlc2hlZXQuYWRkUGFyYW0oKFBhcmFtKSBlbGVtZW50KTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHRvcFN0eWxlc2hlZXQuYWRkRWxlbWVudCgoVG9wTGV2ZWxFbGVtZW50KSBlbGVtZW50KTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgIH0KLSAgICAgICAgZmluYWxseSB7Ci0gICAgICAgICAgICBwYXJzZXIuc2V0Q3VycmVudFN0eWxlc2hlZXQoY29udGV4dCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgVHlwZSB0eXBlQ2hlY2soU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgewotICAgICAgICByZXR1cm4gVHlwZS5Wb2lkOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotICAgICAgICAvLyBkbyBub3RoaW5nCi0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9JbnN0cnVjdGlvbi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9JbnN0cnVjdGlvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1MDYyNGNmLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvSW5zdHJ1Y3Rpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDUyICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IEluc3RydWN0aW9uLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMDEgMTU6NDU6MTEgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuQ2xhc3NHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuRXJyb3JNc2c7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuTWV0aG9kR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZUNoZWNrRXJyb3I7Ci0KLS8qKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICovCi1hYnN0cmFjdCBjbGFzcyBJbnN0cnVjdGlvbiBleHRlbmRzIFN5bnRheFRyZWVOb2RlIHsKLSAgICAvKioKLSAgICAgKiBUeXBlIGNoZWNrIGFsbCB0aGUgY2hpbGRyZW4gb2YgdGhpcyBub2RlLgotICAgICAqLwotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0gICAgICAgIHJldHVybiB0eXBlQ2hlY2tDb250ZW50cyhzdGFibGUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZSB0aGlzIG5vZGUgaW50byBKVk0gYnl0ZWNvZGVzLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotICAgICAgICBFcnJvck1zZyBtc2cgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuTk9UX0lNUExFTUVOVEVEX0VSUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldENsYXNzKCksIHRoaXMpOwotICAgICAgICBnZXRQYXJzZXIoKS5yZXBvcnRFcnJvcihGQVRBTCwgbXNnKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0ludEV4cHIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvSW50RXhwci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwNmE1ODFjLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvSW50RXhwci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTggKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogSW50RXhwci5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzAxIDE1OjQ2OjMyIHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQ29uc3RhbnRQb29sR2VuOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW5zdHJ1Y3Rpb25MaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuUFVTSDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5DbGFzc0dlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5NZXRob2RHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlQ2hlY2tFcnJvcjsKLQotLyoqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKi8KLWZpbmFsIGNsYXNzIEludEV4cHIgZXh0ZW5kcyBFeHByZXNzaW9uIHsKLSAgICBwcml2YXRlIGZpbmFsIGludCBfdmFsdWU7Ci0KLSAgICBwdWJsaWMgSW50RXhwcihpbnQgdmFsdWUpIHsKLSAgICAgICAgX3ZhbHVlID0gdmFsdWU7Ci0gICAgfQotCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLSAgICAgICAgcmV0dXJuIF90eXBlID0gVHlwZS5JbnQ7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKLSAgICAgICAgcmV0dXJuICJpbnQtZXhwcigiICsgX3ZhbHVlICsgJyknOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotICAgICAgICBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgICAgIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgX3ZhbHVlKSk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9LZXkuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvS2V5LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGZiZWRjYzMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9LZXkuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDMwMSArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDE1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICovCi0vKgotICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCi0gKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKLSAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KLSAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCi0gKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAotICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBLZXkuamF2YSx2IDEuNiAyMDA2LzA0LzI1IDAyOjI1OjA4IGplZmZzdXR0b3IgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQnJhbmNoSGFuZGxlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQ29uc3RhbnRQb29sR2VuOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuR09UTzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklGRVE7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JRkdFOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSUZHVDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklMT0FEOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFSU5URVJGQUNFOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFVklSVFVBTDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklTVE9SRTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uSGFuZGxlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW5zdHJ1Y3Rpb25MaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuTG9jYWxWYXJpYWJsZUdlbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlBVU0g7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuQ2xhc3NHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuRXJyb3JNc2c7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuTWV0aG9kR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLk5vZGVTZXRUeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlN0cmluZ1R5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlQ2hlY2tFcnJvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5VdGlsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkF4aXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5YTUwxMUNoYXI7Ci0KLS8qKgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqLwotZmluYWwgY2xhc3MgS2V5IGV4dGVuZHMgVG9wTGV2ZWxFbGVtZW50IHsKLQotICAgIC8qKgotICAgICAqIFRoZSBuYW1lIG9mIHRoaXMga2V5IGFzIGRlZmluZWQgaW4geHNsOmtleS4KLSAgICAgKi8KLSAgICBwcml2YXRlIFFOYW1lIF9uYW1lOwotCi0gICAgLyoqCi0gICAgICogVGhlIHBhdHRlcm4gdG8gbWF0Y2ggc3RhcnRpbmcgYXQgdGhlIHJvb3Qgbm9kZS4KLSAgICAgKi8KLSAgICBwcml2YXRlIFBhdHRlcm4gX21hdGNoOwotCi0gICAgLyoqCi0gICAgICogVGhlIGV4cHJlc3Npb24gdGhhdCBnZW5lcmF0ZXMgdGhlIHZhbHVlcyBmb3IgdGhpcyBrZXkuCi0gICAgICovCi0gICAgcHJpdmF0ZSBFeHByZXNzaW9uIF91c2U7Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgdHlwZSBvZiB0aGUgX3VzZSBleHByZXNzaW9uLgotICAgICAqLwotICAgIHByaXZhdGUgVHlwZSBfdXNlVHlwZTsKLQotICAgIC8qKgotICAgICAqIFBhcnNlIHRoZSA8eHNsOmtleT4gZWxlbWVudCBhbmQgYXR0cmlidXRlcwotICAgICAqIEBwYXJhbSBwYXJzZXIgQSByZWZlcmVuY2UgdG8gdGhlIHN0eWxlc2hlZXQgcGFyc2VyCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcGFyc2VDb250ZW50cyhQYXJzZXIgcGFyc2VyKSB7Ci0KLSAgICAgICAgLy8gR2V0IHRoZSByZXF1aXJlZCBhdHRyaWJ1dGVzIGFuZCBwYXJzZXIgWFBhdGggZXhwcmVzc2lvbnMKLSAgICAgICAgZmluYWwgU3RyaW5nIG5hbWUgPSBnZXRBdHRyaWJ1dGUoIm5hbWUiKTsKLSAgICAgICAgaWYgKCFYTUwxMUNoYXIuaXNYTUwxMVZhbGlkUU5hbWUobmFtZSkpewotICAgICAgICAgICAgRXJyb3JNc2cgZXJyID0gbmV3IEVycm9yTXNnKEVycm9yTXNnLklOVkFMSURfUU5BTUVfRVJSLCBuYW1lLCB0aGlzKTsKLSAgICAgICAgICAgIHBhcnNlci5yZXBvcnRFcnJvcihDb25zdGFudHMuRVJST1IsIGVycik7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBQYXJzZSBrZXkgbmFtZSBhbmQgYWRkIHRvIHN5bWJvbCB0YWJsZQotICAgICAgICBfbmFtZSA9IHBhcnNlci5nZXRRTmFtZUlnbm9yZURlZmF1bHROcyhuYW1lKTsKLSAgICAgICAgZ2V0U3ltYm9sVGFibGUoKS5hZGRLZXkoX25hbWUsIHRoaXMpOwotCi0gICAgICAgIF9tYXRjaCA9IHBhcnNlci5wYXJzZVBhdHRlcm4odGhpcywgIm1hdGNoIiwgbnVsbCk7Ci0gICAgICAgIF91c2UgPSBwYXJzZXIucGFyc2VFeHByZXNzaW9uKHRoaXMsICJ1c2UiLCBudWxsKTsKLQotICAgICAgICAvLyBNYWtlIHN1cmUgcmVxdWlyZWQgYXR0cmlidXRlKHMpIGhhdmUgYmVlbiBzZXQKLSAgICAgICAgaWYgKF9uYW1lID09IG51bGwpIHsKLSAgICAgICAgICAgIHJlcG9ydEVycm9yKHRoaXMsIHBhcnNlciwgRXJyb3JNc2cuUkVRVUlSRURfQVRUUl9FUlIsICJuYW1lIik7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKF9tYXRjaC5pc0R1bW15KCkpIHsKLSAgICAgICAgICAgIHJlcG9ydEVycm9yKHRoaXMsIHBhcnNlciwgRXJyb3JNc2cuUkVRVUlSRURfQVRUUl9FUlIsICJtYXRjaCIpOwotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0gICAgICAgIGlmIChfdXNlLmlzRHVtbXkoKSkgewotICAgICAgICAgICAgcmVwb3J0RXJyb3IodGhpcywgcGFyc2VyLCBFcnJvck1zZy5SRVFVSVJFRF9BVFRSX0VSUiwgInVzZSIpOwotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhIFN0cmluZy1yZXByZXNlbnRhdGlvbiBvZiB0aGlzIGtleSdzIG5hbWUKLSAgICAgKiBAcmV0dXJuIFRoZSBrZXkncyBuYW1lIChmcm9tIHRoZSA8eHNsOmtleT4gZWxlbWVudHMgJ25hbWUnIGF0dHJpYnV0ZSkuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXROYW1lKCkgewotICAgICAgICByZXR1cm4gX25hbWUudG9TdHJpbmcoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgVHlwZSB0eXBlQ2hlY2soU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgewotICAgICAgICAvLyBUeXBlIGNoZWNrIG1hdGNoIHBhdHRlcm4KLSAgICAgICAgX21hdGNoLnR5cGVDaGVjayhzdGFibGUpOwotCi0gICAgICAgIC8vIENhc3Qgbm9kZSB2YWx1ZXMgdG8gc3RyaW5nIHZhbHVlcyAoZXhjZXB0IGZvciBub2Rlc2V0cykKLSAgICAgICAgX3VzZVR5cGUgPSBfdXNlLnR5cGVDaGVjayhzdGFibGUpOwotICAgICAgICBpZiAoX3VzZVR5cGUgaW5zdGFuY2VvZiBTdHJpbmdUeXBlID09IGZhbHNlICYmCi0gICAgICAgICAgICBfdXNlVHlwZSBpbnN0YW5jZW9mIE5vZGVTZXRUeXBlID09IGZhbHNlKQotICAgICAgICB7Ci0gICAgICAgICAgICBfdXNlID0gbmV3IENhc3RFeHByKF91c2UsIFR5cGUuU3RyaW5nKTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBUeXBlLlZvaWQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGlmIHRoZSAidXNlIiBhdHRyaWJ1dGUgb2YgdGhlIGtleSBjb250YWlucyBhCi0gICAgICogbm9kZSBzZXQuIEluIHRoaXMgY2FzZSB3ZSBtdXN0IHRyYXZlcnNlIGFsbCBub2RlcyBpbiB0aGUgc2V0IGFuZAotICAgICAqIGNyZWF0ZSBvbmUgZW50cnkgaW4gdGhpcyBrZXkncyBpbmRleCBmb3IgZWFjaCBub2RlIGluIHRoZSBzZXQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhdmVyc2VOb2RlU2V0KENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgYnVpbGRLZXlJbmRleCkgewotICAgICAgICBmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQotICAgICAgICAvLyBET00uZ2V0U3RyaW5nVmFsdWVYKG5vZGVJbmRleCkgPT4gU3RyaW5nCi0gICAgICAgIGZpbmFsIGludCBnZXROb2RlVmFsdWUgPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKERPTV9JTlRGLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHRVRfTk9ERV9WQUxVRSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIihJKSIrU1RSSU5HX1NJRyk7Ci0KLSAgICAgICAgZmluYWwgaW50IGdldE5vZGVJZGVudCA9IGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoRE9NX0lOVEYsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJnZXROb2RlSWRlbnQiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKEkpIitOT0RFX1NJRyk7Ci0KLSAgICAgICAgLy8gQWJzdHJhY3RUcmFuc2xldC5TZXRLZXlJbmRleERvbShuYW1lLCBEb20pID0+IHZvaWQKLSAgICAgICAgZmluYWwgaW50IGtleURvbSA9IGNwZy5hZGRNZXRob2RyZWYoVFJBTlNMRVRfQ0xBU1MsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJzZXRLZXlJbmRleERvbSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoIitTVFJJTkdfU0lHK0RPTV9JTlRGX1NJRysiKVYiKTsKLQotCi0gICAgICAgIC8vIFRoaXMgdmFyaWFibGUgaG9sZHMgdGhlIGlkIG9mIHRoZSBub2RlIHdlIGZvdW5kIHdpdGggdGhlICJtYXRjaCIKLSAgICAgICAgLy8gYXR0cmlidXRlIG9mIHhzbDprZXkuIFRoaXMgaXMgdGhlIGlkIHdlIHN0b3JlLCB3aXRoIHRoZSB2YWx1ZSB3ZQotICAgICAgICAvLyBnZXQgZnJvbSB0aGUgbm9kZXMgd2UgZmluZCBoZXJlLCBpbiB0aGUgaW5kZXggZm9yIHRoaXMga2V5LgotICAgICAgICBmaW5hbCBMb2NhbFZhcmlhYmxlR2VuIHBhcmVudE5vZGUgPQotICAgICAgICAgICAgbWV0aG9kR2VuLmFkZExvY2FsVmFyaWFibGUoInBhcmVudE5vZGUiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVXRpbC5nZXRKQ1JlZlR5cGUoIkkiKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsIG51bGwpOwotCi0gICAgICAgIC8vIEdldCB0aGUgJ3BhcmFtZXRlcicgZnJvbSB0aGUgc3RhY2sgYW5kIHN0b3JlIGl0IGluIGEgbG9jYWwgdmFyLgotICAgICAgICBwYXJlbnROb2RlLnNldFN0YXJ0KGlsLmFwcGVuZChuZXcgSVNUT1JFKHBhcmVudE5vZGUuZ2V0SW5kZXgoKSkpKTsKLQotICAgICAgICAvLyBTYXZlIGN1cnJlbnQgbm9kZSBhbmQgY3VycmVudCBpdGVyYXRvciBvbiB0aGUgc3RhY2sKLSAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkQ3VycmVudE5vZGUoKSk7Ci0gICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZEl0ZXJhdG9yKCkpOwotCi0gICAgICAgIC8vIE92ZXJ3cml0ZSBjdXJyZW50IGl0ZXJhdG9yIHdpdGggb25lIHRoYXQgZ2l2ZXMgdXMgb25seSB3aGF0IHdlIHdhbnQKLSAgICAgICAgX3VzZS50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgIF91c2Uuc3RhcnRJdGVyYXRvcihjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5zdG9yZUl0ZXJhdG9yKCkpOwotCi0gICAgICAgIGZpbmFsIEJyYW5jaEhhbmRsZSBuZXh0Tm9kZSA9IGlsLmFwcGVuZChuZXcgR09UTyhudWxsKSk7Ci0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uSGFuZGxlIGxvb3AgPSBpbC5hcHBlbmQoTk9QKTsKLQotICAgICAgICAvLyBQcmVwYXJlIHRvIGNhbGwgYnVpbGRLZXlJbmRleChTdHJpbmcgbmFtZSwgaW50IG5vZGUsIFN0cmluZyB2YWx1ZSk7Ci0gICAgICAgIGlsLmFwcGVuZChjbGFzc0dlbi5sb2FkVHJhbnNsZXQoKSk7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsIF9uYW1lLnRvU3RyaW5nKCkpKTsKLSAgICAgICAgcGFyZW50Tm9kZS5zZXRFbmQoaWwuYXBwZW5kKG5ldyBJTE9BRChwYXJlbnROb2RlLmdldEluZGV4KCkpKSk7Ci0KLSAgICAgICAgLy8gTm93IGdldCB0aGUgbm9kZSB2YWx1ZSBhbmQgcHVzaCBpdCBvbiB0aGUgcGFyYW1ldGVyIHN0YWNrCi0gICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLSAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkQ3VycmVudE5vZGUoKSk7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFSU5URVJGQUNFKGdldE5vZGVWYWx1ZSwgMikpOwotCi0gICAgICAgIC8vIEZpbmFsbHkgZG8gdGhlIGNhbGwgdG8gYWRkIGFuIGVudHJ5IGluIHRoZSBpbmRleCBmb3IgdGhpcyBrZXkuCi0gICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChidWlsZEtleUluZGV4KSk7Ci0KLSAgICAgICAgaWwuYXBwZW5kKGNsYXNzR2VuLmxvYWRUcmFuc2xldCgpKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgZ2V0TmFtZSgpKSk7Ci0gICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VWSVJUVUFMKGtleURvbSkpOwotCi0gICAgICAgIG5leHROb2RlLnNldFRhcmdldChpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRJdGVyYXRvcigpKSk7Ci0gICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubmV4dE5vZGUoKSk7Ci0KLSAgICAgICAgaWwuYXBwZW5kKERVUCk7Ci0gICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4uc3RvcmVDdXJyZW50Tm9kZSgpKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBJRkdFKGxvb3ApKTsgLy8gR28gb24gdG8gbmV4dCBtYXRjaGluZyBub2RlLi4uLgotCi0gICAgICAgIC8vIFJlc3RvcmUgY3VycmVudCBub2RlIGFuZCBjdXJyZW50IGl0ZXJhdG9yIGZyb20gdGhlIHN0YWNrCi0gICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4uc3RvcmVJdGVyYXRvcigpKTsKLSAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5zdG9yZUN1cnJlbnROb2RlKCkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdhdGhlciBhbGwgbm9kZXMgdGhhdCBtYXRjaCB0aGUgZXhwcmVzc2lvbiBpbiB0aGUgYXR0cmlidXRlICJtYXRjaCIKLSAgICAgKiBhbmQgYWRkIG9uZSAob3IgbW9yZSkgZW50cmllcyBpbiB0aGlzIGtleSdzIGluZGV4LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCi0gICAgICAgIGZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotICAgICAgICBmaW5hbCBpbnQgY3VycmVudCA9IG1ldGhvZEdlbi5nZXRMb2NhbEluZGV4KCJjdXJyZW50Iik7Ci0KLSAgICAgICAgLy8gQWJzdHJhY3RUcmFuc2xldC5idWlsZEtleUluZGV4KG5hbWUsbm9kZV9pZCx2YWx1ZSkgPT4gdm9pZAotICAgICAgICBmaW5hbCBpbnQga2V5ID0gY3BnLmFkZE1ldGhvZHJlZihUUkFOU0xFVF9DTEFTUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImJ1aWxkS2V5SW5kZXgiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKCIrU1RSSU5HX1NJRysiSSIrU1RSSU5HX1NJRysiKVYiKTsKLQotICAgICAgICAvLyBBYnN0cmFjdFRyYW5zbGV0LlNldEtleUluZGV4RG9tKG5hbWUsIERvbSkgPT4gdm9pZAotICAgICAgICBmaW5hbCBpbnQga2V5RG9tID0gY3BnLmFkZE1ldGhvZHJlZihUUkFOU0xFVF9DTEFTUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInNldEtleUluZGV4RG9tIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIigiK1NUUklOR19TSUcrRE9NX0lOVEZfU0lHKyIpViIpOwotCi0gICAgICAgIGZpbmFsIGludCBnZXROb2RlSWRlbnQgPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKERPTV9JTlRGLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZ2V0Tm9kZUlkZW50IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIihJKSIrTk9ERV9TSUcpOwotCi0gICAgICAgIC8vIERPTS5nZXRBeGlzSXRlcmF0b3Iocm9vdCkgPT4gTm9kZUl0ZXJhdG9yCi0gICAgICAgIGZpbmFsIGludCBnaXQgPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKERPTV9JTlRGLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZ2V0QXhpc0l0ZXJhdG9yIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIihJKSIrTk9ERV9JVEVSQVRPUl9TSUcpOwotCi0gICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZEN1cnJlbnROb2RlKCkpOwotICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRJdGVyYXRvcigpKTsKLQotICAgICAgICAvLyBHZXQgYW4gaXRlcmF0b3IgZm9yIGFsbCBub2RlcyBpbiB0aGUgRE9NCi0gICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZyxBeGlzLkRFU0NFTkRBTlQpKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0UoZ2l0LCAyKSk7Ci0KLSAgICAgICAgLy8gUmVzZXQgdGhlIGl0ZXJhdG9yIHRvIHN0YXJ0IHdpdGggdGhlIHJvb3Qgbm9kZQotICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRDdXJyZW50Tm9kZSgpKTsKLSAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5zZXRTdGFydE5vZGUoKSk7Ci0gICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4uc3RvcmVJdGVyYXRvcigpKTsKLQotICAgICAgICAvLyBMb29wIGZvciB0cmF2ZXJzaW5nIGFsbCBub2RlcyBpbiB0aGUgRE9NCi0gICAgICAgIGZpbmFsIEJyYW5jaEhhbmRsZSBuZXh0Tm9kZSA9IGlsLmFwcGVuZChuZXcgR09UTyhudWxsKSk7Ci0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uSGFuZGxlIGxvb3AgPSBpbC5hcHBlbmQoTk9QKTsKLQotICAgICAgICAvLyBDaGVjayBpZiB0aGUgY3VycmVudCBub2RlIG1hdGNoZXMgdGhlIHBhdHRlcm4gaW4gIm1hdGNoIgotICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRDdXJyZW50Tm9kZSgpKTsKLSAgICAgICAgX21hdGNoLnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgX21hdGNoLnN5bnRoZXNpemUoY2xhc3NHZW4sIG1ldGhvZEdlbik7IC8vIExlYXZlcyAwIG9yIDEgb24gc3RhY2sKLSAgICAgICAgZmluYWwgQnJhbmNoSGFuZGxlIHNraXBOb2RlID0gaWwuYXBwZW5kKG5ldyBJRkVRKG51bGwpKTsKLQotICAgICAgICAvLyBJZiB0aGlzIGlzIGEgbm9kZS1zZXQgd2UgbXVzdCBnbyB0aHJvdWdoIGVhY2ggbm9kZSBpbiB0aGUgc2V0Ci0gICAgICAgIGlmIChfdXNlVHlwZSBpbnN0YW5jZW9mIE5vZGVTZXRUeXBlKSB7Ci0gICAgICAgICAgICAvLyBQYXNzIGN1cnJlbnQgbm9kZSBhcyBwYXJhbWV0ZXIgKHdlJ3JlIGluZGV4aW5nIG9uIHRoYXQgbm9kZSkKLSAgICAgICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZEN1cnJlbnROb2RlKCkpOwotICAgICAgICAgICAgdHJhdmVyc2VOb2RlU2V0KGNsYXNzR2VuLCBtZXRob2RHZW4sIGtleSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpOwotICAgICAgICAgICAgaWwuYXBwZW5kKERVUCk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBfbmFtZS50b1N0cmluZygpKSk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQoRFVQX1gxKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZEN1cnJlbnROb2RlKCkpOwotICAgICAgICAgICAgX3VzZS50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRVZJUlRVQUwoa2V5KSk7Ci0KLSAgICAgICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChrZXlEb20pKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIEdldCB0aGUgbmV4dCBub2RlIGZyb20gdGhlIGl0ZXJhdG9yIGFuZCBkbyBsb29wIGFnYWluLi4uCi0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uSGFuZGxlIHNraXAgPSBpbC5hcHBlbmQoTk9QKTsKLQotICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRJdGVyYXRvcigpKTsKLSAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5uZXh0Tm9kZSgpKTsKLSAgICAgICAgaWwuYXBwZW5kKERVUCk7Ci0gICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4uc3RvcmVDdXJyZW50Tm9kZSgpKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBJRkdUKGxvb3ApKTsKLQotICAgICAgICAvLyBSZXN0b3JlIGN1cnJlbnQgbm9kZSBhbmQgY3VycmVudCBpdGVyYXRvciBmcm9tIHRoZSBzdGFjawotICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLnN0b3JlSXRlcmF0b3IoKSk7Ci0gICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4uc3RvcmVDdXJyZW50Tm9kZSgpKTsKLQotICAgICAgICBuZXh0Tm9kZS5zZXRUYXJnZXQoc2tpcCk7Ci0gICAgICAgIHNraXBOb2RlLnNldFRhcmdldChza2lwKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0tleUNhbGwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvS2V5Q2FsbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlODVjOGVkLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvS2V5Q2FsbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjM4ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNiBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IEtleUNhbGwuamF2YSx2IDEuNyAyMDA2LzA2LzE5IDE5OjQ5OjA0IHNwZXJpY2FzIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5BTE9BRDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkFTVE9SRTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkJyYW5jaEhhbmRsZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkNvbnN0YW50UG9vbEdlbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkdPVE87Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JRkdUOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFSU5URVJGQUNFOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFU1BFQ0lBTDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklOVk9LRVZJUlRVQUw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JbnN0cnVjdGlvbkhhbmRsZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uTGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkxvY2FsVmFyaWFibGVHZW47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5ORVc7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5QVVNIOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkNsYXNzR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLk1ldGhvZEdlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5TdHJpbmdUeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZUNoZWNrRXJyb3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVXRpbDsKLQotLyoqCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICovCi1maW5hbCBjbGFzcyBLZXlDYWxsIGV4dGVuZHMgRnVuY3Rpb25DYWxsIHsKLQotICAgIC8qKgotICAgICAqIFRoZSBuYW1lIG9mIHRoZSBrZXkuCi0gICAgICovCi0gICAgcHJpdmF0ZSBFeHByZXNzaW9uIF9uYW1lOwotCi0gICAgLyoqCi0gICAgICogVGhlIHZhbHVlIHRvIGxvb2sgdXAgaW4gdGhlIGtleS9pbmRleC4KLSAgICAgKi8KLSAgICBwcml2YXRlIEV4cHJlc3Npb24gX3ZhbHVlOwotCi0gICAgLyoqCi0gICAgICogVGhlIHZhbHVlJ3MgZGF0YSB0eXBlLgotICAgICAqLwotICAgIHByaXZhdGUgVHlwZSBfdmFsdWVUeXBlOyAvLyBUaGUgdmFsdWUncyBkYXRhIHR5cGUKLQotICAgIC8qKgotICAgICAqIEV4cGFuZGVkIHFuYW1lIHdoZW4gbmFtZSBpcyBsaXRlcmFsLgotICAgICAqLwotICAgIHByaXZhdGUgUU5hbWUgX3Jlc29sdmVkUU5hbWUgPSBudWxsOwotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBwYXJhbWV0ZXJzIHBhc3NlZCB0byBmdW5jdGlvbjoKLSAgICAgKiAgIGtleShTdHJpbmcgbmFtZSwgU3RyaW5nIHZhbHVlKQotICAgICAqICAga2V5KFN0cmluZyBuYW1lLCBOb2RlU2V0IHZhbHVlKQotICAgICAqIFRoZSAnYXJndW1lbnRzJyB2ZWN0b3Igc2hvdWxkIGNvbnRhaW4gdHdvIHBhcmFtZXRlcnMgZm9yIGtleSgpIGNhbGxzLAotICAgICAqIG9uZSBob2xkaW5nIHRoZSBrZXkgbmFtZSBhbmQgb25lIGhvbGRpbmcgdGhlIHZhbHVlKHMpIHRvIGxvb2sgdXAuIFRoZQotICAgICAqIHZlY3RvciBoYXMgb25seSBvbmUgcGFyYW1ldGVyIGZvciBpZCgpIGNhbGxzICh0aGUga2V5IG5hbWUgaXMgYWx3YXlzCi0gICAgICogIiMjaWQiIGZvciBpZCgpIGNhbGxzKS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBmbmFtZSBUaGUgZnVuY3Rpb24gbmFtZSAoc2hvdWxkIGJlICdrZXknIG9yICdpZCcpCi0gICAgICogQHBhcmFtIGFyZ3VtZW50cyBBIHZlY3RvciBjb250YWluaW5nIHRoZSBhcmd1bWVudHMgdGhlIHRoZSBmdW5jdGlvbgotICAgICAqLwotICAgIHB1YmxpYyBLZXlDYWxsKFFOYW1lIGZuYW1lLCBWZWN0b3IgYXJndW1lbnRzKSB7Ci0gICAgICAgIHN1cGVyKGZuYW1lLCBhcmd1bWVudHMpOwotICAgICAgICBzd2l0Y2goYXJndW1lbnRDb3VudCgpKSB7Ci0gICAgICAgIGNhc2UgMToKLSAgICAgICAgICAgIF9uYW1lID0gbnVsbDsKLSAgICAgICAgICAgIF92YWx1ZSA9IGFyZ3VtZW50KDApOwotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgMjoKLSAgICAgICAgICAgIF9uYW1lID0gYXJndW1lbnQoMCk7Ci0gICAgICAgICAgICBfdmFsdWUgPSBhcmd1bWVudCgxKTsKLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICBkZWZhdWx0OgotICAgICAgICAgICAgX25hbWUgPSBfdmFsdWUgPSBudWxsOwotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAgLyoqCi0gICAgICogSWYgdGhpcyBjYWxsIHRvIGtleSgpIGlzIGluIGEgdG9wLWxldmVsIGVsZW1lbnQgbGlrZSAgYW5vdGhlciB2YXJpYWJsZQotICAgICAqIG9yIHBhcmFtLCBhZGQgYSBkZXBlbmRlbmN5IGJldHdlZW4gdGhhdCB0b3AtbGV2ZWwgZWxlbWVudCBhbmQgdGhlCi0gICAgICogcmVmZXJlbmNlZCBrZXkuIEZvciBleGFtcGxlLAotICAgICAqCi0gICAgICogICA8eHNsOmtleSBuYW1lPSJ4IiAuLi4vPgotICAgICAqICAgPHhzbDp2YXJpYWJsZSBuYW1lPSJ5IiBzZWxlY3Q9ImtleSgneCcsIDEpIi8+Ci0gICAgICoKLSAgICAgKiBhbmQgYXNzdW1pbmcgdGhpcyBjbGFzcyByZXByZXNlbnRzICJrZXkoJ3gnLCAxKSIsIGFkZCBhIHJlZmVyZW5jZQotICAgICAqIGJldHdlZW4gdmFyaWFibGUgeSBhbmQga2V5IHguIE5vdGUgdGhhdCBpZiAneCcgaXMgdW5rbm93biBzdGF0aWNhbGx5Ci0gICAgICogaW4ga2V5KCd4JywgMSksIHRoZXJlJ3Mgbm90aGluZyB3ZSBjYW4gZG8gYXQgdGhpcyBwb2ludC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBhZGRQYXJlbnREZXBlbmRlbmN5KCkgewotICAgICAgICAvLyBJZiBuYW1lIHVua25vd24gc3RhdGljYWxseSwgdGhlcmUncyBub3RoaW5nIHdlIGNhbiBkbwotICAgICAgICBpZiAoX3Jlc29sdmVkUU5hbWUgPT0gbnVsbCkgcmV0dXJuOwotCi0gICAgICAgIFN5bnRheFRyZWVOb2RlIG5vZGUgPSB0aGlzOwotICAgICAgICB3aGlsZSAobm9kZSAhPSBudWxsICYmIG5vZGUgaW5zdGFuY2VvZiBUb3BMZXZlbEVsZW1lbnQgPT0gZmFsc2UpIHsKLSAgICAgICAgICAgIG5vZGUgPSBub2RlLmdldFBhcmVudCgpOwotICAgICAgICB9Ci0KLSAgICAgICAgVG9wTGV2ZWxFbGVtZW50IHBhcmVudCA9IChUb3BMZXZlbEVsZW1lbnQpIG5vZGU7Ci0gICAgICAgIGlmIChwYXJlbnQgIT0gbnVsbCkgewotICAgICAgICAgICAgcGFyZW50LmFkZERlcGVuZGVuY3koZ2V0U3ltYm9sVGFibGUoKS5nZXRLZXkoX3Jlc29sdmVkUU5hbWUpKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgLyoqCi0gICAgICogVHlwZSBjaGVjayB0aGUgcGFyYW1ldGVycyBmb3IgdGhlIGlkKCkgb3Iga2V5KCkgZnVuY3Rpb24uCi0gICAgICogVGhlIGluZGV4IG5hbWUgKGZvciBrZXkoKSBjYWxsIG9ubHkpIG11c3QgYmUgYSBzdHJpbmcgb3IgY29udmVydGFibGUKLSAgICAgKiB0byBhIHN0cmluZywgYW5kIHRoZSBsb29rdXAtdmFsdWUgbXVzdCBiZSBhIHN0cmluZyBvciBhIG5vZGUtc2V0LgotICAgICAqIEBwYXJhbSBzdGFibGUgVGhlIHBhcnNlcidzIHN5bWJvbCB0YWJsZQotICAgICAqIEB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgV2hlbiB0aGUgcGFyYW1ldGVycyBoYXZlIGlsbGVnYWwgdHlwZQotICAgICAqLwotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0gICAgICAgIGZpbmFsIFR5cGUgcmV0dXJuVHlwZSA9IHN1cGVyLnR5cGVDaGVjayhzdGFibGUpOwotCi0gICAgICAgIC8vIFJ1biB0eXBlIGNoZWNrIG9uIHRoZSBrZXkgbmFtZSAoZmlyc3QgYXJndW1lbnQpIC0gbXVzdCBiZSBhIHN0cmluZywKLSAgICAgICAgLy8gYW5kIGlmIGl0IGlzIG5vdCBpdCBtdXN0IGJlIGNvbnZlcnRlZCB0byBvbmUgdXNpbmcgc3RyaW5nKCkgcnVsZXMuCi0gICAgICAgIGlmIChfbmFtZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmaW5hbCBUeXBlIG5hbWVUeXBlID0gX25hbWUudHlwZUNoZWNrKHN0YWJsZSk7Ci0KLSAgICAgICAgICAgIGlmIChfbmFtZSBpbnN0YW5jZW9mIExpdGVyYWxFeHByKSB7Ci0gICAgICAgICAgICAgICAgZmluYWwgTGl0ZXJhbEV4cHIgbGl0ZXJhbCA9IChMaXRlcmFsRXhwcikgX25hbWU7Ci0gICAgICAgICAgICAgICAgX3Jlc29sdmVkUU5hbWUgPQotICAgICAgICAgICAgICAgICAgICBnZXRQYXJzZXIoKS5nZXRRTmFtZUlnbm9yZURlZmF1bHROcyhsaXRlcmFsLmdldFZhbHVlKCkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAobmFtZVR5cGUgaW5zdGFuY2VvZiBTdHJpbmdUeXBlID09IGZhbHNlKSB7Ci0gICAgICAgICAgICAgICAgX25hbWUgPSBuZXcgQ2FzdEV4cHIoX25hbWUsIFR5cGUuU3RyaW5nKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIFJ1biB0eXBlIGNoZWNrIG9uIHRoZSB2YWx1ZSBmb3IgdGhpcyBrZXkuIFRoaXMgdmFsdWUgY2FuIGJlIG9mCi0gICAgICAgIC8vIGFueSBkYXRhIHR5cGUsIHNvIHRoaXMgc2hvdWxkIG5ldmVyIGNhdXNlIGFueSB0eXBlLWNoZWNrIGVycm9ycy4KLSAgICAgICAgLy8gSWYgdGhlIHZhbHVlIGlzIGEgcmVmZXJlbmNlLCB0aGVuIHdlIGhhdmUgdG8gZGVmZXIgdGhlIGRlY2lzaW9uCi0gICAgICAgIC8vIG9mIGhvdyB0byBwcm9jZXNzIGl0IHVudGlsIHJ1bi10aW1lLgotICAgICAgICAvLyBJZiB0aGUgdmFsdWUgaXMga25vd24gbm90IHRvIGJlIGEgbm9kZS1zZXQsIHRoZW4gaXQgc2hvdWxkIGJlCi0gICAgICAgIC8vIGNvbnZlcnRlZCB0byBhIHN0cmluZyBiZWZvcmUgdGhlIGxvb2t1cCBpcyBkb25lLiBJZiB0aGUgdmFsdWUgaXMKLSAgICAgICAgLy8ga25vd24gdG8gYmUgYSBub2RlLXNldCB0aGVuIHRoaXMgcHJvY2VzcyAoY29udmVydCB0byBzdHJpbmcsIHRoZW4KLSAgICAgICAgLy8gZG8gbG9va3VwKSBzaG91bGQgYmUgYXBwbGllZCB0byBldmVyeSBub2RlIGluIHRoZSBzZXQsIGFuZCB0aGUKLSAgICAgICAgLy8gcmVzdWx0IGZyb20gYWxsIGxvb2t1cHMgc2hvdWxkIGJlIGFkZGVkIHRvIHRoZSByZXN1bHRpbmcgbm9kZS1zZXQuCi0gICAgICAgIF92YWx1ZVR5cGUgPSBfdmFsdWUudHlwZUNoZWNrKHN0YWJsZSk7Ci0KLSAgICAgICAgaWYgKF92YWx1ZVR5cGUgIT0gVHlwZS5Ob2RlU2V0Ci0gICAgICAgICAgICAgICAgJiYgX3ZhbHVlVHlwZSAhPSBUeXBlLlJlZmVyZW5jZQotICAgICAgICAgICAgICAgICYmIF92YWx1ZVR5cGUgIT0gVHlwZS5TdHJpbmcpIHsKLSAgICAgICAgICAgIF92YWx1ZSA9IG5ldyBDYXN0RXhwcihfdmFsdWUsIFR5cGUuU3RyaW5nKTsKLSAgICAgICAgICAgIF92YWx1ZVR5cGUgPSBfdmFsdWUudHlwZUNoZWNrKHN0YWJsZSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBJZiBpbiBhIHRvcC1sZXZlbCBlbGVtZW50LCBjcmVhdGUgZGVwZW5kZW5jeSB0byB0aGUgcmVmZXJlbmNlZCBrZXkKLSAgICAgICAgYWRkUGFyZW50RGVwZW5kZW5jeSgpOwotCi0gICAgICAgIHJldHVybiByZXR1cm5UeXBlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCB3aGVuIHRoZSBjb25zdHJ1Y3RvciBpcyBjb21waWxlZCBpbgotICAgICAqIFN0eWxlc2hlZXQuY29tcGlsZUNvbnN0cnVjdG9yKCkgYW5kIG5vdCBhcyB0aGUgc3ludGF4IHRyZWUgaXMgdHJhdmVyc2VkLgotICAgICAqIDxwPlRoaXMgbWV0aG9kIHdpbGwgZ2VuZXJhdGUgYnl0ZSBjb2RlIHRoYXQgcHJvZHVjZXMgYW4gaXRlcmF0b3IKLSAgICAgKiBmb3IgdGhlIG5vZGVzIGluIHRoZSBub2RlIHNldCBmb3IgdGhlIGtleSBvciBpZCBmdW5jdGlvbiBjYWxsLgotICAgICAqIEBwYXJhbSBjbGFzc0dlbiBUaGUgSmF2YSBjbGFzcyBnZW5lcmF0b3IKLSAgICAgKiBAcGFyYW0gbWV0aG9kR2VuIFRoZSBtZXRob2QgZ2VuZXJhdG9yCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0gICAgICAgIGZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCi0gICAgICAgIC8vIFJldHVybnMgdGhlIEtleUluZGV4IG9iamVjdCBvZiBhIGdpdmVuIG5hbWUKLSAgICAgICAgZmluYWwgaW50IGdldEtleUluZGV4ID0gY3BnLmFkZE1ldGhvZHJlZihUUkFOU0xFVF9DTEFTUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZ2V0S2V5SW5kZXgiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoTGphdmEvbGFuZy9TdHJpbmc7KSIrCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgS0VZX0lOREVYX1NJRyk7Ci0KLSAgICAgICAgLy8gS2V5SW5kZXguc2V0RG9tKERvbSwgbm9kZSkgPT4gdm9pZAotICAgICAgICBmaW5hbCBpbnQga2V5RG9tID0gY3BnLmFkZE1ldGhvZHJlZihLRVlfSU5ERVhfQ0xBU1MsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJzZXREb20iLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKCIgKyBET01fSU5URl9TSUcgKyAiSSlWIik7Ci0KLSAgICAgICAgLy8gSW5pdGlhbGlzZXMgYSBLZXlJbmRleCB0byByZXR1cm4gbm9kZXMgd2l0aCBzcGVjaWZpYyB2YWx1ZXMKLSAgICAgICAgZmluYWwgaW50IGdldEtleUl0ZXJhdG9yID0KLSAgICAgICAgICAgICAgICAgICAgICAgIGNwZy5hZGRNZXRob2RyZWYoS0VZX0lOREVYX0NMQVNTLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZ2V0S2V5SW5kZXhJdGVyYXRvciIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoIiArIF92YWx1ZVR5cGUudG9TaWduYXR1cmUoKSArICJaKSIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgS0VZX0lOREVYX0lURVJBVE9SX1NJRyk7Ci0KLSAgICAgICAgLy8gSW5pdGlhbGlzZSB0aGUgaW5kZXggc3BlY2lmaWVkIGluIHRoZSBmaXJzdCBwYXJhbWV0ZXIgb2Yga2V5KCkKLSAgICAgICAgaWwuYXBwZW5kKGNsYXNzR2VuLmxvYWRUcmFuc2xldCgpKTsKLSAgICAgICAgaWYgKF9uYW1lID09IG51bGwpIHsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsIiMjaWQiKSk7Ci0gICAgICAgIH0gZWxzZSBpZiAoX3Jlc29sdmVkUU5hbWUgIT0gbnVsbCkgewotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgX3Jlc29sdmVkUU5hbWUudG9TdHJpbmcoKSkpOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgX25hbWUudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gR2VuZXJhdGUgZm9sbG93aW5nIGJ5dGUgY29kZToKLSAgICAgICAgLy8KLSAgICAgICAgLy8gICBLZXlJbmRleCBraSA9IHRyYW5zbGV0LmdldEtleUluZGV4KF9uYW1lKQotICAgICAgICAvLyAgIGtpLnNldERvbSh0cmFuc2xldC5kb20pOwotICAgICAgICAvLyAgIGtpLmdldEtleUluZGV4SXRlcmF0b3IoX3ZhbHVlLCB0cnVlKSAgLSBmb3Iga2V5KCkKLSAgICAgICAgLy8gICAgICAgIE9SCi0gICAgICAgIC8vICAga2kuZ2V0S2V5SW5kZXhJdGVyYXRvcihfdmFsdWUsIGZhbHNlKSAgLSBmb3IgaWQoKQotICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRVZJUlRVQUwoZ2V0S2V5SW5kZXgpKTsKLSAgICAgICAgaWwuYXBwZW5kKERVUCk7Ci0gICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLSAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkQ3VycmVudE5vZGUoKSk7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChrZXlEb20pKTsKLQotICAgICAgICBfdmFsdWUudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICBpbC5hcHBlbmQoKF9uYW1lICE9IG51bGwpID8gSUNPTlNUXzE6IElDT05TVF8wKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VWSVJUVUFMKGdldEtleUl0ZXJhdG9yKSk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9LZXlQYXR0ZXJuLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0tleVBhdHRlcm4uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNWE4YWJkYi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0tleVBhdHRlcm4uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDM2ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IEtleVBhdHRlcm4uamF2YSx2IDEuMi40LjEgMjAwNS8wOS8wMSAxNTo1MDoxNCBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXI7Ci0KLS8qKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICovCi1maW5hbCBjbGFzcyBLZXlQYXR0ZXJuIGV4dGVuZHMgSWRLZXlQYXR0ZXJuIHsKLQotICAgIHB1YmxpYyBLZXlQYXR0ZXJuKFN0cmluZyBpbmRleCwgU3RyaW5nIHZhbHVlKSB7Ci0gICAgICAgIHN1cGVyKGluZGV4LHZhbHVlKTsKLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvTGFuZ0NhbGwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvTGFuZ0NhbGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggY2ViNmJiZi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0xhbmdDYWxsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5MyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBMYW5nQ2FsbC5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzAxIDE1OjU0OjI1IHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkNvbnN0YW50UG9vbEdlbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklMT0FEOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFU1RBVElDOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW5zdHJ1Y3Rpb25MaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkNsYXNzR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkZpbHRlckdlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5NZXRob2RHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuU3RyaW5nVHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGVDaGVja0Vycm9yOwotCi0vKioKLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICovCi1maW5hbCBjbGFzcyBMYW5nQ2FsbCBleHRlbmRzIEZ1bmN0aW9uQ2FsbCB7Ci0gICAgcHJpdmF0ZSBFeHByZXNzaW9uIF9sYW5nOwotICAgIHByaXZhdGUgVHlwZSBfbGFuZ1R5cGU7Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIHBhcmFtZXRlcnMgcGFzc2VkIHRvIGZ1bmN0aW9uOgotICAgICAqICAgbGFuZyhzdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIExhbmdDYWxsKFFOYW1lIGZuYW1lLCBWZWN0b3IgYXJndW1lbnRzKSB7Ci0gICAgICAgIHN1cGVyKGZuYW1lLCBhcmd1bWVudHMpOwotICAgICAgICBfbGFuZyA9IGFyZ3VtZW50KDApOwotICAgIH0KLQotICAgIC8qKgotICAgICAqCi0gICAgICovCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLSAgICAgICAgX2xhbmdUeXBlID0gX2xhbmcudHlwZUNoZWNrKHN0YWJsZSk7Ci0gICAgICAgIGlmICghKF9sYW5nVHlwZSBpbnN0YW5jZW9mIFN0cmluZ1R5cGUpKSB7Ci0gICAgICAgICAgICBfbGFuZyA9IG5ldyBDYXN0RXhwcihfbGFuZywgVHlwZS5TdHJpbmcpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBUeXBlLkJvb2xlYW47Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICoKLSAgICAgKi8KLSAgICBwdWJsaWMgVHlwZSBnZXRUeXBlKCkgewotICAgICAgICByZXR1cm4oVHlwZS5Cb29sZWFuKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgd2hlbiB0aGUgY29uc3RydWN0b3IgaXMgY29tcGlsZWQgaW4KLSAgICAgKiBTdHlsZXNoZWV0LmNvbXBpbGVDb25zdHJ1Y3RvcigpIGFuZCBub3QgYXMgdGhlIHN5bnRheCB0cmVlIGlzIHRyYXZlcnNlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLSAgICAgICAgZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0KLSAgICAgICAgZmluYWwgaW50IHRzdCA9IGNwZy5hZGRNZXRob2RyZWYoQkFTSVNfTElCUkFSWV9DTEFTUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRlc3RMYW5ndWFnZSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoIitTVFJJTkdfU0lHK0RPTV9JTlRGX1NJRysiSSlaIik7Ci0gICAgICAgIF9sYW5nLnRyYW5zbGF0ZShjbGFzc0dlbixtZXRob2RHZW4pOwotICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0gICAgICAgIGlmIChjbGFzc0dlbiBpbnN0YW5jZW9mIEZpbHRlckdlbmVyYXRvcikKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSUxPQUQoMSkpOwotICAgICAgICBlbHNlCi0gICAgICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRDb250ZXh0Tm9kZSgpKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VTVEFUSUModHN0KSk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9MYXN0Q2FsbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9MYXN0Q2FsbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3MTU5ZWNlLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvTGFzdENhbGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDcxICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IExhc3RDYWxsLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMDEgMTU6NTU6MzQgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5Db25zdGFudFBvb2xHZW47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JTE9BRDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklOVk9LRUlOVEVSRkFDRTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uTGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5DbGFzc0dlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5Db21wYXJlR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLk1ldGhvZEdlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UZXN0R2VuZXJhdG9yOwotCi0vKioKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqLwotZmluYWwgY2xhc3MgTGFzdENhbGwgZXh0ZW5kcyBGdW5jdGlvbkNhbGwgewotCi0gICAgcHVibGljIExhc3RDYWxsKFFOYW1lIGZuYW1lKSB7Ci0gICAgICAgIHN1cGVyKGZuYW1lKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBoYXNQb3NpdGlvbkNhbGwoKSB7Ci0gICAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGhhc0xhc3RDYWxsKCkgewotICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCi0gICAgICAgIGlmIChtZXRob2RHZW4gaW5zdGFuY2VvZiBDb21wYXJlR2VuZXJhdG9yKSB7Ci0gICAgICAgICAgICBpbC5hcHBlbmQoKChDb21wYXJlR2VuZXJhdG9yKW1ldGhvZEdlbikubG9hZExhc3ROb2RlKCkpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKG1ldGhvZEdlbiBpbnN0YW5jZW9mIFRlc3RHZW5lcmF0b3IpIHsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSUxPQUQoTEFTVF9JTkRFWCkpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotICAgICAgICAgICAgZmluYWwgaW50IGdldExhc3QgPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKE5PREVfSVRFUkFUT1IsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImdldExhc3QiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoKUkiKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZEl0ZXJhdG9yKCkpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0UoZ2V0TGFzdCwgMSkpOwotICAgICAgICB9Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9MaXRlcmFsQXR0cmlidXRlLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0xpdGVyYWxBdHRyaWJ1dGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZGM5OWE4ZC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0xpdGVyYWxBdHRyaWJ1dGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE1OSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBMaXRlcmFsQXR0cmlidXRlLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTIgMTA6Mzg6MDMgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5Db25zdGFudFBvb2xHZW47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JbnN0cnVjdGlvbkxpc3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5QVVNIOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkNsYXNzR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLk1ldGhvZEdlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGVDaGVja0Vycm9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlV0aWw7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXIuRWxlbURlc2M7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyLlNlcmlhbGl6YXRpb25IYW5kbGVyOwotCi0vKioKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICovCi1maW5hbCBjbGFzcyBMaXRlcmFsQXR0cmlidXRlIGV4dGVuZHMgSW5zdHJ1Y3Rpb24gewotCi0gICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgIF9uYW1lOyAgICAgICAgIC8vIEF0dHJpYnV0ZSBuYW1lIChpbmNsLiBwcmVmaXgpCi0gICAgcHJpdmF0ZSBmaW5hbCBBdHRyaWJ1dGVWYWx1ZSBfdmFsdWU7IC8vIEF0dHJpYnV0ZSB2YWx1ZQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlcyBhIG5ldyBsaXRlcmFsIGF0dHJpYnV0ZSAoYnV0IGRvZXMgbm90IGluc2VydCBpdCBpbnRvIHRoZSBBU1QpLgotICAgICAqIEBwYXJhbSBuYW1lIHRoZSBhdHRyaWJ1dGUgbmFtZSAoaW5jbC4gcHJlZml4KSBhcyBhIFN0cmluZy4KLSAgICAgKiBAcGFyYW0gdmFsdWUgdGhlIGF0dHJpYnV0ZSB2YWx1ZS4KLSAgICAgKiBAcGFyYW0gcGFyc2VyIHRoZSBYU0xUIHBhcnNlciAod3JhcHMgWFBhdGggcGFyc2VyKS4KLSAgICAgKi8KLSAgICBwdWJsaWMgTGl0ZXJhbEF0dHJpYnV0ZShTdHJpbmcgbmFtZSwgU3RyaW5nIHZhbHVlLCBQYXJzZXIgcGFyc2VyLAotICAgICAgICBTeW50YXhUcmVlTm9kZSBwYXJlbnQpCi0gICAgewotICAgICAgICBfbmFtZSA9IG5hbWU7Ci0gICAgICAgIHNldFBhcmVudChwYXJlbnQpOwotICAgICAgICBfdmFsdWUgPSBBdHRyaWJ1dGVWYWx1ZS5jcmVhdGUodGhpcywgdmFsdWUsIHBhcnNlcik7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgZGlzcGxheShpbnQgaW5kZW50KSB7Ci0gICAgICAgIGluZGVudChpbmRlbnQpOwotICAgICAgICBVdGlsLnByaW50bG4oIkxpdGVyYWxBdHRyaWJ1dGUgbmFtZT0iICsgX25hbWUgKyAiIHZhbHVlPSIgKyBfdmFsdWUpOwotICAgIH0KLQotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0gICAgICAgIF92YWx1ZS50eXBlQ2hlY2soc3RhYmxlKTsKLSAgICAgICAgdHlwZUNoZWNrQ29udGVudHMoc3RhYmxlKTsKLSAgICAgICAgcmV0dXJuIFR5cGUuVm9pZDsKLSAgICB9Ci0KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBjb250ZXh0RGVwZW5kZW50KCkgewotICAgICAgICByZXR1cm4gX3ZhbHVlLmNvbnRleHREZXBlbmRlbnQoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLSAgICAgICAgZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0KLSAgICAgICAgLy8gcHVzaCBoYW5kbGVyCi0gICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZEhhbmRsZXIoKSk7Ci0gICAgICAgIC8vIHB1c2ggYXR0cmlidXRlIG5hbWUgLSBuYW1lc3BhY2UgcHJlZml4IHNldCBieSBwYXJlbnQgbm9kZQotICAgICAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBfbmFtZSkpOwotICAgICAgICAvLyBwdXNoIGF0dHJpYnV0ZSB2YWx1ZQotICAgICAgICBfdmFsdWUudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCi0gICAgICAgIC8vIEdlbmVyYXRlIGNvZGUgdGhhdCBjYWxscyBTZXJpYWxpemF0aW9uSGFuZGxlci5hZGRVbmlxdWVBdHRyaWJ1dGUoKQotICAgICAgICAvLyBpZiBhbGwgYXR0cmlidXRlcyBhcmUgdW5pcXVlLgotICAgICAgICBTeW50YXhUcmVlTm9kZSBwYXJlbnQgPSBnZXRQYXJlbnQoKTsKLSAgICAgICAgaWYgKHBhcmVudCBpbnN0YW5jZW9mIExpdGVyYWxFbGVtZW50Ci0gICAgICAgICAgICAmJiAoKExpdGVyYWxFbGVtZW50KXBhcmVudCkuYWxsQXR0cmlidXRlc1VuaXF1ZSgpKSB7Ci0KLSAgICAgICAgICAgIGludCBmbGFncyA9IDA7Ci0gICAgICAgICAgICBib29sZWFuIGlzSFRNTEF0dHJFbXB0eSA9IGZhbHNlOwotICAgICAgICAgICAgRWxlbURlc2MgZWxlbURlc2MgPSAoKExpdGVyYWxFbGVtZW50KXBhcmVudCkuZ2V0RWxlbURlc2MoKTsKLQotICAgICAgICAgICAgLy8gU2V0IHRoZSBIVE1MIGZsYWdzCi0gICAgICAgICAgICBpZiAoZWxlbURlc2MgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGlmIChlbGVtRGVzYy5pc0F0dHJGbGFnU2V0KF9uYW1lLCBFbGVtRGVzYy5BVFRSRU1QVFkpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZsYWdzID0gZmxhZ3MgfCBTZXJpYWxpemF0aW9uSGFuZGxlci5IVE1MX0FUVFJFTVBUWTsKLSAgICAgICAgICAgICAgICAgICAgaXNIVE1MQXR0ckVtcHR5ID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSBpZiAoZWxlbURlc2MuaXNBdHRyRmxhZ1NldChfbmFtZSwgRWxlbURlc2MuQVRUUlVSTCkpIHsKLSAgICAgICAgICAgICAgICAgICAgZmxhZ3MgPSBmbGFncyB8IFNlcmlhbGl6YXRpb25IYW5kbGVyLkhUTUxfQVRUUlVSTDsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmIChfdmFsdWUgaW5zdGFuY2VvZiBTaW1wbGVBdHRyaWJ1dGVWYWx1ZSkgewotICAgICAgICAgICAgICAgIFN0cmluZyBhdHRyVmFsdWUgPSAoKFNpbXBsZUF0dHJpYnV0ZVZhbHVlKV92YWx1ZSkudG9TdHJpbmcoKTsKLQotICAgICAgICAgICAgICAgIGlmICghaGFzQmFkQ2hhcnMoYXR0clZhbHVlKSAmJiAhaXNIVE1MQXR0ckVtcHR5KSB7Ci0gICAgICAgICAgICAgICAgICAgIGZsYWdzID0gZmxhZ3MgfCBTZXJpYWxpemF0aW9uSGFuZGxlci5OT19CQURfQ0hBUlM7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBmbGFncykpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi51bmlxdWVBdHRyaWJ1dGUoKSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAvLyBjYWxsIGF0dHJpYnV0ZQotICAgICAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5hdHRyaWJ1dGUoKSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdHJ1ZSBpZiBhdCBsZWFzdCBvbmUgY2hhcmFjdGVyIGluIHRoZSBTdHJpbmcgaXMgY29uc2lkZXJlZCB0bwotICAgICAqIGJlIGEgImJhZCIgY2hhcmFjdGVyLiBBIGJhZCBjaGFyYWN0ZXIgaXMgb25lIHdob3NlIGNvZGUgaXM6Ci0gICAgICogbGVzcyB0aGFuIDMyIChhIHNwYWNlKSwKLSAgICAgKiBvciBncmVhdGVyIHRoYW4gMTI2LAotICAgICAqIG9yIGl0IGlzIG9uZSBvZiAnPCcsICc+JywgJyYnIG9yICdcIicuCi0gICAgICogVGhpcyBoZWxwcyB0aGUgc2VyaWFsaXplciB0byBkZWNpZGUgd2hldGhlciB0aGUgU3RyaW5nIG5lZWRzIHRvIGJlIGVzY2FwZWQuCi0gICAgICovCi0gICAgcHJpdmF0ZSBib29sZWFuIGhhc0JhZENoYXJzKFN0cmluZyB2YWx1ZSkgewotICAgICAgICBjaGFyW10gY2hhcnMgPSB2YWx1ZS50b0NoYXJBcnJheSgpOwotICAgICAgICBpbnQgc2l6ZSA9IGNoYXJzLmxlbmd0aDsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKLSAgICAgICAgICAgIGNoYXIgY2ggPSBjaGFyc1tpXTsKLSAgICAgICAgICAgIGlmIChjaCA8IDMyIHx8IDEyNiA8IGNoIHx8IGNoID09ICc8JyB8fCBjaCA9PSAnPicgfHwgY2ggPT0gJyYnIHx8IGNoID09ICdcIicpCi0gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybiB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXROYW1lKCkgewotICAgICAgICByZXR1cm4gX25hbWU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgYXR0cmlidXRlCi0gICAgICovCi0gICAgcHVibGljIEF0dHJpYnV0ZVZhbHVlIGdldFZhbHVlKCkgewotICAgICAgICByZXR1cm4gX3ZhbHVlOwotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9MaXRlcmFsRWxlbWVudC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9MaXRlcmFsRWxlbWVudC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjMzkyY2JlLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvTGl0ZXJhbEVsZW1lbnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDUwOCArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDE1LCAyMDE2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICovCi0vKgotICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCi0gKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKLSAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KLSAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCi0gKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAotICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkNvbnN0YW50UG9vbEdlbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uTGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlBVU0g7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuQ2xhc3NHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuRXJyb3JNc2c7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuTWV0aG9kR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZUNoZWNrRXJyb3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVXRpbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXIuRWxlbURlc2M7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyLlRvSFRNTFN0cmVhbTsKLWltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwotaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwotaW1wb3J0IGphdmEudXRpbC5IYXNodGFibGU7Ci1pbXBvcnQgamF2YS51dGlsLkxpc3Q7Ci1pbXBvcnQgamF2YS51dGlsLk1hcDsKLWltcG9ydCBqYXZhLnV0aWwuU2V0OwotCi0vKioKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICovCi1maW5hbCBjbGFzcyBMaXRlcmFsRWxlbWVudCBleHRlbmRzIEluc3RydWN0aW9uIHsKLQotICAgIHByaXZhdGUgU3RyaW5nIF9uYW1lOwotICAgIHByaXZhdGUgTGl0ZXJhbEVsZW1lbnQgX2xpdGVyYWxFbGVtUGFyZW50ID0gbnVsbDsKLSAgICBwcml2YXRlIExpc3Q8U3ludGF4VHJlZU5vZGU+IF9hdHRyaWJ1dGVFbGVtZW50cyA9IG51bGw7Ci0gICAgcHJpdmF0ZSBNYXA8U3RyaW5nLCBTdHJpbmc+IF9hY2Nlc3NlZFByZWZpeGVzID0gbnVsbDsKLQotICAgIC8vIFRydWUgaWYgYWxsIGF0dHJpYnV0ZXMgb2YgdGhpcyBMUkUgYXJlIHVuaXF1ZSwgaS5lLiB0aGV5IGFsbCBoYXZlCi0gICAgLy8gZGlmZmVyZW50IG5hbWVzLiBUaGlzIGZsYWcgaXMgc2V0IHRvIGZhbHNlIGlmIHNvbWUgYXR0cmlidXRlCi0gICAgLy8gbmFtZXMgYXJlIG5vdCBrbm93biBhdCBjb21waWxlIHRpbWUuCi0gICAgcHJpdmF0ZSBib29sZWFuIF9hbGxBdHRyaWJ1dGVzVW5pcXVlID0gZmFsc2U7Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBRTmFtZSBmb3IgdGhpcyBsaXRlcmFsIGVsZW1lbnQKLSAgICAgKi8KLSAgICBwdWJsaWMgUU5hbWUgZ2V0TmFtZSgpIHsKLSAgICAgICAgcmV0dXJuIF9xbmFtZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBEaXNwbGF5cyB0aGUgY29udGVudHMgb2YgdGhpcyBsaXRlcmFsIGVsZW1lbnQKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBkaXNwbGF5KGludCBpbmRlbnQpIHsKLSAgICAgICAgaW5kZW50KGluZGVudCk7Ci0gICAgICAgIFV0aWwucHJpbnRsbigiTGl0ZXJhbEVsZW1lbnQgbmFtZSA9ICIgKyBfbmFtZSk7Ci0gICAgICAgIGRpc3BsYXlDb250ZW50cyhpbmRlbnQgKyBJbmRlbnRJbmNyZW1lbnQpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIG5hbWVzcGFjZSBVUkkgZm9yIHdoaWNoIGEgcHJlZml4IGlzIHBvaW50aW5nIHRvCi0gICAgICovCi0gICAgcHJpdmF0ZSBTdHJpbmcgYWNjZXNzZWROYW1lc3BhY2UoU3RyaW5nIHByZWZpeCkgewotICAgICAgICBpZiAoX2xpdGVyYWxFbGVtUGFyZW50ICE9IG51bGwpIHsKLSAgICAgICAgICAgIFN0cmluZyByZXN1bHQgPSBfbGl0ZXJhbEVsZW1QYXJlbnQuYWNjZXNzZWROYW1lc3BhY2UocHJlZml4KTsKLSAgICAgICAgICAgIGlmIChyZXN1bHQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIF9hY2Nlc3NlZFByZWZpeGVzICE9IG51bGwgPyBfYWNjZXNzZWRQcmVmaXhlcy5nZXQocHJlZml4KSA6IG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogTWV0aG9kIHVzZWQgdG8ga2VlcCB0cmFjayBvZiB3aGF0IG5hbWVzcGFjZXMgdGhhdCBhcmUgcmVmZXJlbmNlcyBieQotICAgICAqIHRoaXMgbGl0ZXJhbCBlbGVtZW50IGFuZCBpdHMgYXR0cmlidXRlcy4gVGhlIG91dHB1dCBtdXN0IGNvbnRhaW4gYQotICAgICAqIGRlZmluaXRpb24gZm9yIGVhY2ggbmFtZXNwYWNlLCBzbyB3ZSBzdHVmZiB0aGVtIGluIGEgbWFwLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHJlZ2lzdGVyTmFtZXNwYWNlKFN0cmluZyBwcmVmaXgsIFN0cmluZyB1cmksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3ltYm9sVGFibGUgc3RhYmxlLCBib29sZWFuIGRlY2xhcmVkKSB7Ci0KLSAgICAgICAgLy8gQ2hlY2sgaWYgdGhlIHBhcmVudCBoYXMgYSBkZWNsYXJhdGlvbiBmb3IgdGhpcyBuYW1lc3BhY2UKLSAgICAgICAgaWYgKF9saXRlcmFsRWxlbVBhcmVudCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmaW5hbCBTdHJpbmcgcGFyZW50VXJpID0gX2xpdGVyYWxFbGVtUGFyZW50LmFjY2Vzc2VkTmFtZXNwYWNlKHByZWZpeCk7Ci0gICAgICAgICAgICBpZiAocGFyZW50VXJpICE9IG51bGwgJiYgcGFyZW50VXJpLmVxdWFscyh1cmkpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gQ2hlY2sgaWYgd2UgaGF2ZSBhbnkgZGVjbGFyZWQgbmFtZXNwYWNlcwotICAgICAgICBpZiAoX2FjY2Vzc2VkUHJlZml4ZXMgPT0gbnVsbCkgewotICAgICAgICAgICAgX2FjY2Vzc2VkUHJlZml4ZXMgPSBuZXcgSGFzaHRhYmxlPD4oKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIGlmICghZGVjbGFyZWQpIHsKLSAgICAgICAgICAgICAgICAvLyBDaGVjayBpZiB0aGlzIG5vZGUgaGFzIGEgZGVjbGFyYXRpb24gZm9yIHRoaXMgbmFtZXNwYWNlCi0gICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIG9sZCA9IF9hY2Nlc3NlZFByZWZpeGVzLmdldChwcmVmaXgpOwotICAgICAgICAgICAgICAgIGlmIChvbGQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBpZiAob2xkLmVxdWFscyh1cmkpKQotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgICAgICBwcmVmaXggPSBzdGFibGUuZ2VuZXJhdGVOYW1lc3BhY2VQcmVmaXgoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoIXByZWZpeC5lcXVhbHMoInhtbCIpKSB7Ci0gICAgICAgICAgICBfYWNjZXNzZWRQcmVmaXhlcy5wdXQocHJlZml4LHVyaSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGVzIHRoZSBwcmVmaXggb2YgYSBRTmFtZSBhY2NvcmRpbmcgdG8gdGhlIHJ1bGVzIHNldCBpbgotICAgICAqIHRoZSBhdHRyaWJ1dGVzIG9mIHhzbDpzdHlsZXNoZWV0LiBBbHNvIHJlZ2lzdGVycyBhIFFOYW1lIHRvIGFzc3VyZQotICAgICAqIHRoYXQgdGhlIG91dHB1dCBlbGVtZW50IGNvbnRhaW5zIHRoZSBuZWNlc3NhcnkgbmFtZXNwYWNlIGRlY2xhcmF0aW9ucy4KLSAgICAgKi8KLSAgICBwcml2YXRlIFN0cmluZyB0cmFuc2xhdGVRTmFtZShRTmFtZSBxbmFtZSwgU3ltYm9sVGFibGUgc3RhYmxlKSB7Ci0gICAgICAgIC8vIEJyZWFrIHVwIHRoZSBRTmFtZSBhbmQgZ2V0IHByZWZpeDpsb2NhbG5hbWUgc3RyaW5ncwotICAgICAgICBTdHJpbmcgbG9jYWxuYW1lID0gcW5hbWUuZ2V0TG9jYWxQYXJ0KCk7Ci0gICAgICAgIFN0cmluZyBwcmVmaXggPSBxbmFtZS5nZXRQcmVmaXgoKTsKLQotICAgICAgICAvLyBUcmVhdCBkZWZhdWx0IG5hbWVzcGFjZSBhcyAiIiBhbmQgbm90IG51bGwKLSAgICAgICAgaWYgKHByZWZpeCA9PSBudWxsKQotICAgICAgICAgICAgcHJlZml4ID0gQ29uc3RhbnRzLkVNUFRZU1RSSU5HOwotICAgICAgICBlbHNlIGlmIChwcmVmaXguZXF1YWxzKFhNTE5TX1BSRUZJWCkpCi0gICAgICAgICAgICByZXR1cm4oWE1MTlNfUFJFRklYKTsKLQotICAgICAgICAvLyBDaGVjayBpZiB3ZSBtdXN0IHRyYW5zbGF0ZSB0aGUgcHJlZml4Ci0gICAgICAgIGZpbmFsIFN0cmluZyBhbHRlcm5hdGl2ZSA9IHN0YWJsZS5sb29rdXBQcmVmaXhBbGlhcyhwcmVmaXgpOwotICAgICAgICBpZiAoYWx0ZXJuYXRpdmUgIT0gbnVsbCkgewotICAgICAgICAgICAgc3RhYmxlLmV4Y2x1ZGVOYW1lc3BhY2VzKHByZWZpeCk7Ci0gICAgICAgICAgICBwcmVmaXggPSBhbHRlcm5hdGl2ZTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIEdldCB0aGUgbmFtZXNwYWNlIHRoaXMgcHJlZml4IHJlZmVycyB0bwotICAgICAgICBTdHJpbmcgdXJpID0gbG9va3VwTmFtZXNwYWNlKHByZWZpeCk7Ci0gICAgICAgIGlmICh1cmkgPT0gbnVsbCkgcmV0dXJuKGxvY2FsbmFtZSk7Ci0KLSAgICAgICAgLy8gUmVnaXN0ZXIgdGhlIG5hbWVzcGFjZSBhcyBhY2Nlc3NlZAotICAgICAgICByZWdpc3Rlck5hbWVzcGFjZShwcmVmaXgsIHVyaSwgc3RhYmxlLCBmYWxzZSk7Ci0KLSAgICAgICAgLy8gQ29uc3RydWN0IHRoZSBuZXcgbmFtZSBmb3IgdGhlIGVsZW1lbnQgKG1heSBiZSB1bmNoYW5nZWQpCi0gICAgICAgIGlmIChwcmVmaXggIT0gQ29uc3RhbnRzLkVNUFRZU1RSSU5HKQotICAgICAgICAgICAgcmV0dXJuKHByZWZpeCsiOiIrbG9jYWxuYW1lKTsKLSAgICAgICAgZWxzZQotICAgICAgICAgICAgcmV0dXJuKGxvY2FsbmFtZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQWRkIGFuIGF0dHJpYnV0ZSB0byB0aGlzIGVsZW1lbnQKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBhZGRBdHRyaWJ1dGUoU3ludGF4VHJlZU5vZGUgYXR0cmlidXRlKSB7Ci0gICAgICAgIGlmIChfYXR0cmlidXRlRWxlbWVudHMgPT0gbnVsbCkgewotICAgICAgICAgICAgX2F0dHJpYnV0ZUVsZW1lbnRzID0gbmV3IEFycmF5TGlzdDw+KDIpOwotICAgICAgICB9Ci0gICAgICAgIF9hdHRyaWJ1dGVFbGVtZW50cy5hZGQoYXR0cmlidXRlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIGZpcnN0IGF0dHJpYnV0ZSBvZiB0aGlzIGVsZW1lbnQKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRGaXJzdEF0dHJpYnV0ZShTeW50YXhUcmVlTm9kZSBhdHRyaWJ1dGUpIHsKLSAgICAgICAgaWYgKF9hdHRyaWJ1dGVFbGVtZW50cyA9PSBudWxsKSB7Ci0gICAgICAgICAgICBfYXR0cmlidXRlRWxlbWVudHMgPSBuZXcgQXJyYXlMaXN0PD4oMik7Ci0gICAgICAgIH0KLSAgICAgICAgX2F0dHJpYnV0ZUVsZW1lbnRzLmFkZCgwLCBhdHRyaWJ1dGUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFR5cGUtY2hlY2sgdGhlIGNvbnRlbnRzIG9mIHRoaXMgZWxlbWVudC4gVGhlIGVsZW1lbnQgaXRzZWxmIGRvZXMgbm90Ci0gICAgICogbmVlZCBhbnkgdHlwZSBjaGVja2luZyBhcyBpdCBsZWF2ZXMgbm90aGlnbiBvbiB0aGUgSlZNJ3Mgc3RhY2suCi0gICAgICovCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLSAgICAgICAgLy8gVHlwZS1jaGVjayBhbGwgYXR0cmlidXRlcwotICAgICAgICBpZiAoX2F0dHJpYnV0ZUVsZW1lbnRzICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZvciAoU3ludGF4VHJlZU5vZGUgbm9kZSA6IF9hdHRyaWJ1dGVFbGVtZW50cykgewotICAgICAgICAgICAgICAgIG5vZGUudHlwZUNoZWNrKHN0YWJsZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgdHlwZUNoZWNrQ29udGVudHMoc3RhYmxlKTsKLSAgICAgICAgcmV0dXJuIFR5cGUuVm9pZDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBzdGFydHMgYXQgYSBnaXZlbiBub2RlLCB0cmF2ZXJzZXMgYWxsIG5hbWVzcGFjZSBtYXBwaW5ncywKLSAgICAgKiBhbmQgYXNzZW1ibGVzIGEgbGlzdCBvZiBhbGwgcHJlZml4ZXMgdGhhdCAoZm9yIHRoZSBnaXZlbiBub2RlKSBtYXBzCi0gICAgICogdG8gX0FOWV8gbmFtZXNwYWNlIFVSSS4gVXNlZCBieSBsaXRlcmFsIHJlc3VsdCBlbGVtZW50cyB0byBkZXRlcm1pbmUKLSAgICAgKi8KLSAgICBwdWJsaWMgU2V0PE1hcC5FbnRyeTxTdHJpbmcsIFN0cmluZz4+IGdldE5hbWVzcGFjZVNjb3BlKFN5bnRheFRyZWVOb2RlIG5vZGUpIHsKLSAgICAgICAgTWFwPFN0cmluZywgU3RyaW5nPiBhbGwgPSBuZXcgSGFzaE1hcDw+KCk7Ci0KLSAgICAgICAgd2hpbGUgKG5vZGUgIT0gbnVsbCkgewotICAgICAgICAgICAgTWFwPFN0cmluZywgU3RyaW5nPiBtYXBwaW5nID0gbm9kZS5nZXRQcmVmaXhNYXBwaW5nKCk7Ci0gICAgICAgICAgICBpZiAobWFwcGluZyAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZm9yKCBTdHJpbmcgcHJlZml4IDogbWFwcGluZy5rZXlTZXQoKSkgewotICAgICAgICAgICAgICAgICAgICBpZiAoIWFsbC5jb250YWluc0tleShwcmVmaXgpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBhbGwucHV0KHByZWZpeCwgbWFwcGluZy5nZXQocHJlZml4KSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBub2RlID0gbm9kZS5nZXRQYXJlbnQoKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gYWxsLmVudHJ5U2V0KCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRGV0ZXJtaW5lcyB0aGUgZmluYWwgUU5hbWUgZm9yIHRoZSBlbGVtZW50IGFuZCBpdHMgYXR0cmlidXRlcy4KLSAgICAgKiBSZWdpc3RlcnMgYWxsIG5hbWVzcGFjZXMgdGhhdCBhcmUgdXNlZCBieSB0aGUgZWxlbWVudC9hdHRyaWJ1dGVzCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcGFyc2VDb250ZW50cyhQYXJzZXIgcGFyc2VyKSB7Ci0gICAgICAgIGZpbmFsIFN5bWJvbFRhYmxlIHN0YWJsZSA9IHBhcnNlci5nZXRTeW1ib2xUYWJsZSgpOwotICAgICAgICBzdGFibGUuc2V0Q3VycmVudE5vZGUodGhpcyk7Ci0KLSAgICAgICAgLy8gQ2hlY2sgaWYgaW4gYSBsaXRlcmFsIGVsZW1lbnQgY29udGV4dAotICAgICAgICBTeW50YXhUcmVlTm9kZSBwYXJlbnQgPSBnZXRQYXJlbnQoKTsKLSAgICAgICAgaWYgKHBhcmVudCAhPSBudWxsICYmIHBhcmVudCBpbnN0YW5jZW9mIExpdGVyYWxFbGVtZW50KSB7Ci0gICAgICAgICAgICBfbGl0ZXJhbEVsZW1QYXJlbnQgPSAoTGl0ZXJhbEVsZW1lbnQpIHBhcmVudDsKLSAgICAgICAgfQotCi0gICAgICAgIF9uYW1lID0gdHJhbnNsYXRlUU5hbWUoX3FuYW1lLCBzdGFibGUpOwotCi0gICAgICAgIC8vIFByb2Nlc3MgYWxsIGF0dHJpYnV0ZXMgYW5kIHJlZ2lzdGVyIGFsbCBuYW1lc3BhY2VzIHRoZXkgdXNlCi0gICAgICAgIGZpbmFsIGludCBjb3VudCA9IF9hdHRyaWJ1dGVzLmdldExlbmd0aCgpOwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKLSAgICAgICAgICAgIGZpbmFsIFFOYW1lIHFuYW1lID0gcGFyc2VyLmdldFFOYW1lKF9hdHRyaWJ1dGVzLmdldFFOYW1lKGkpKTsKLSAgICAgICAgICAgIGZpbmFsIFN0cmluZyB1cmkgPSBxbmFtZS5nZXROYW1lc3BhY2UoKTsKLSAgICAgICAgICAgIGZpbmFsIFN0cmluZyB2YWwgPSBfYXR0cmlidXRlcy5nZXRWYWx1ZShpKTsKLQotICAgICAgICAgICAgLy8gSGFuZGxlIHhzbDp1c2UtYXR0cmlidXRlLXNldHMuIEF0dHJpYnV0ZSBzZXRzIGFyZSBwbGFjZWQgZmlyc3QKLSAgICAgICAgICAgIC8vIGluIHRoZSB2ZWN0b3Igb3IgYXR0cmlidXRlcyB0byBtYWtlIHN1cmUgdGhhdCBsYXRlciBsb2NhbAotICAgICAgICAgICAgLy8gYXR0cmlidXRlcyBjYW4gb3ZlcnJpZGUgYW4gYXR0cmlidXRlcyBpbiB0aGUgc2V0LgotICAgICAgICAgICAgaWYgKHFuYW1lLmVxdWFscyhwYXJzZXIuZ2V0VXNlQXR0cmlidXRlU2V0cygpKSkgewotICAgICAgICAgICAgICAgIGlmICghVXRpbC5pc1ZhbGlkUU5hbWVzKHZhbCkpIHsKLSAgICAgICAgICAgICAgICAgICAgRXJyb3JNc2cgZXJyID0gbmV3IEVycm9yTXNnKEVycm9yTXNnLklOVkFMSURfUU5BTUVfRVJSLCB2YWwsIHRoaXMpOwotICAgICAgICAgICAgICAgICAgICBwYXJzZXIucmVwb3J0RXJyb3IoQ29uc3RhbnRzLkVSUk9SLCBlcnIpOwotICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHNldEZpcnN0QXR0cmlidXRlKG5ldyBVc2VBdHRyaWJ1dGVTZXRzKHZhbCwgcGFyc2VyKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyBIYW5kbGUgeHNsOmV4dGVuc2lvbi1lbGVtZW50LXByZWZpeGVzCi0gICAgICAgICAgICBlbHNlIGlmIChxbmFtZS5lcXVhbHMocGFyc2VyLmdldEV4dGVuc2lvbkVsZW1lbnRQcmVmaXhlcygpKSkgewotICAgICAgICAgICAgICAgIHN0YWJsZS5leGNsdWRlTmFtZXNwYWNlcyh2YWwpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gSGFuZGxlIHhzbDpleGNsdWRlLXJlc3VsdC1wcmVmaXhlcwotICAgICAgICAgICAgZWxzZSBpZiAocW5hbWUuZXF1YWxzKHBhcnNlci5nZXRFeGNsdWRlUmVzdWx0UHJlZml4ZXMoKSkpIHsKLSAgICAgICAgICAgICAgICBzdGFibGUuZXhjbHVkZU5hbWVzcGFjZXModmFsKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIC8vIElnbm9yZSBzcGVjaWFsIGF0dHJpYnV0ZXMgKGUuZy4geG1sbnM6cHJlZml4IGFuZCB4bWxucykKLSAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgcHJlZml4ID0gcW5hbWUuZ2V0UHJlZml4KCk7Ci0gICAgICAgICAgICAgICAgaWYgKHByZWZpeCAhPSBudWxsICYmIHByZWZpeC5lcXVhbHMoWE1MTlNfUFJFRklYKSB8fAotICAgICAgICAgICAgICAgICAgICBwcmVmaXggPT0gbnVsbCAmJiBxbmFtZS5nZXRMb2NhbFBhcnQoKS5lcXVhbHMoWE1MTlNfUFJFRklYKSB8fAotICAgICAgICAgICAgICAgICAgICB1cmkgIT0gbnVsbCAmJiB1cmkuZXF1YWxzKFhTTFRfVVJJKSkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8vIEhhbmRsZSBhbGwgb3RoZXIgbGl0ZXJhbCBhdHRyaWJ1dGVzCi0gICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIG5hbWUgPSB0cmFuc2xhdGVRTmFtZShxbmFtZSwgc3RhYmxlKTsKLSAgICAgICAgICAgICAgICBMaXRlcmFsQXR0cmlidXRlIGF0dHIgPSBuZXcgTGl0ZXJhbEF0dHJpYnV0ZShuYW1lLCB2YWwsIHBhcnNlciwgdGhpcyk7Ci0gICAgICAgICAgICAgICAgYWRkQXR0cmlidXRlKGF0dHIpOwotICAgICAgICAgICAgICAgIGF0dHIuc2V0UGFyZW50KHRoaXMpOwotICAgICAgICAgICAgICAgIGF0dHIucGFyc2VDb250ZW50cyhwYXJzZXIpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gUmVnaXN0ZXIgYWxsIG5hbWVzcGFjZXMgdGhhdCBhcmUgaW4gc2NvcGUsIGV4Y2VwdCBmb3IgdGhvc2UgdGhhdAotICAgICAgICAvLyBhcmUgbGlzdGVkIGluIHRoZSB4c2w6c3R5bGVzaGVldCBlbGVtZW50J3MgKi1wcmVmaXhlcyBhdHRyaWJ1dGVzCi0gICAgICAgIFNldDxNYXAuRW50cnk8U3RyaW5nLCBTdHJpbmc+PiBpbmNsdWRlID0gZ2V0TmFtZXNwYWNlU2NvcGUodGhpcyk7Ci0gICAgICAgIGZvciAoTWFwLkVudHJ5PFN0cmluZywgU3RyaW5nPiBlbnRyeSA6IGluY2x1ZGUpIHsKLSAgICAgICAgICAgIGZpbmFsIFN0cmluZyBwcmVmaXggPSBlbnRyeS5nZXRLZXkoKTsKLSAgICAgICAgICAgIGlmICghcHJlZml4LmVxdWFscygieG1sIikpIHsKLSAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgdXJpID0gbG9va3VwTmFtZXNwYWNlKHByZWZpeCk7Ci0gICAgICAgICAgICAgICAgaWYgKHVyaSAhPSBudWxsICYmICFzdGFibGUuaXNFeGNsdWRlZE5hbWVzcGFjZSh1cmkpKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJlZ2lzdGVyTmFtZXNwYWNlKHByZWZpeCwgdXJpLCBzdGFibGUsIHRydWUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHBhcnNlQ2hpbGRyZW4ocGFyc2VyKTsKLQotICAgICAgICAvLyBQcm9jZXNzIGFsbCBhdHRyaWJ1dGVzIGFuZCByZWdpc3RlciBhbGwgbmFtZXNwYWNlcyB0aGV5IHVzZQotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKLSAgICAgICAgICAgIGZpbmFsIFFOYW1lIHFuYW1lID0gcGFyc2VyLmdldFFOYW1lKF9hdHRyaWJ1dGVzLmdldFFOYW1lKGkpKTsKLSAgICAgICAgICAgIGZpbmFsIFN0cmluZyB2YWwgPSBfYXR0cmlidXRlcy5nZXRWYWx1ZShpKTsKLQotICAgICAgICAgICAgLy8gSGFuZGxlIHhzbDpleHRlbnNpb24tZWxlbWVudC1wcmVmaXhlcwotICAgICAgICAgICAgaWYgKHFuYW1lLmVxdWFscyhwYXJzZXIuZ2V0RXh0ZW5zaW9uRWxlbWVudFByZWZpeGVzKCkpKSB7Ci0gICAgICAgICAgICAgICAgc3RhYmxlLnVuRXhjbHVkZU5hbWVzcGFjZXModmFsKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIEhhbmRsZSB4c2w6ZXhjbHVkZS1yZXN1bHQtcHJlZml4ZXMKLSAgICAgICAgICAgIGVsc2UgaWYgKHFuYW1lLmVxdWFscyhwYXJzZXIuZ2V0RXhjbHVkZVJlc3VsdFByZWZpeGVzKCkpKSB7Ci0gICAgICAgICAgICAgICAgc3RhYmxlLnVuRXhjbHVkZU5hbWVzcGFjZXModmFsKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIHByb3RlY3RlZCBib29sZWFuIGNvbnRleHREZXBlbmRlbnQoKSB7Ci0gICAgICAgIHJldHVybiBkZXBlbmRlbnRDb250ZW50cygpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbXBpbGVzIGNvZGUgdGhhdCBlbWl0cyB0aGUgbGl0ZXJhbCBlbGVtZW50IHRvIHRoZSBvdXRwdXQgaGFuZGxlciwKLSAgICAgKiBmaXJzdCB0aGUgc3RhcnQgdGFnLCB0aGVuIG5hbWVzcGFjZSBkZWNsYXJhdGlvbiwgdGhlbiBhdHRyaWJ1dGVzLAotICAgICAqIHRoZW4gdGhlIGVsZW1lbnQgY29udGVudHMsIGFuZCB0aGVuIHRoZSBlbGVtZW50IGVuZCB0YWcuIFNpbmNlIHRoZQotICAgICAqIHZhbHVlIG9mIGFuIGF0dHJpYnV0ZSBtYXkgZGVwZW5kIG9uIGEgdmFyaWFibGUsIHZhcmlhYmxlcyBtdXN0IGJlCi0gICAgICogY29tcGlsZWQgZmlyc3QuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0KLSAgICAgICAgZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0KLSAgICAgICAgLy8gQ2hlY2sgd2hldGhlciBhbGwgYXR0cmlidXRlcyBhcmUgdW5pcXVlLgotICAgICAgICBfYWxsQXR0cmlidXRlc1VuaXF1ZSA9IGNoZWNrQXR0cmlidXRlc1VuaXF1ZSgpOwotCi0gICAgICAgIC8vIENvbXBpbGUgY29kZSB0byBlbWl0IGVsZW1lbnQgc3RhcnQgdGFnCi0gICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZEhhbmRsZXIoKSk7Ci0KLSAgICAgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgX25hbWUpKTsKLSAgICAgICAgaWwuYXBwZW5kKERVUDIpOyAgICAgICAgICAgICAgICAvLyBkdXBsaWNhdGUgdGhlc2UgMiBhcmdzIGZvciBlbmRFbGVtZW50Ci0gICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4uc3RhcnRFbGVtZW50KCkpOwotCi0gICAgICAgIC8vIFRoZSB2YWx1ZSBvZiBhbiBhdHRyaWJ1dGUgbWF5IGRlcGVuZCBvbiBhIChzaWJsaW5nKSB2YXJpYWJsZQotICAgICAgICBpbnQgaiA9IDA7Ci0gICAgICAgIHdoaWxlIChqIDwgZWxlbWVudENvdW50KCkpICB7Ci0gICAgICAgICAgICBmaW5hbCBTeW50YXhUcmVlTm9kZSBpdGVtID0gZWxlbWVudEF0KGopOwotICAgICAgICAgICAgaWYgKGl0ZW0gaW5zdGFuY2VvZiBWYXJpYWJsZSkgewotICAgICAgICAgICAgICAgIGl0ZW0udHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaisrOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gQ29tcGlsZSBjb2RlIHRvIGVtaXQgbmFtZXNwYWNlIGF0dHJpYnV0ZXMKLSAgICAgICAgaWYgKF9hY2Nlc3NlZFByZWZpeGVzICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZvciAoTWFwLkVudHJ5PFN0cmluZywgU3RyaW5nPiBlbnRyeSA6IF9hY2Nlc3NlZFByZWZpeGVzLmVudHJ5U2V0KCkpIHsKLSAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgcHJlZml4ID0gZW50cnkuZ2V0S2V5KCk7Ci0gICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIHVyaSA9IGVudHJ5LmdldFZhbHVlKCk7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkSGFuZGxlcigpKTsKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBwcmVmaXgpKTsKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCB1cmkpKTsKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLm5hbWVzcGFjZSgpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIE91dHB1dCBhbGwgYXR0cmlidXRlcwotICAgICAgICBpZiAoX2F0dHJpYnV0ZUVsZW1lbnRzICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZvciAoU3ludGF4VHJlZU5vZGUgbm9kZSA6IF9hdHRyaWJ1dGVFbGVtZW50cykgewotICAgICAgICAgICAgICAgIGlmICghKG5vZGUgaW5zdGFuY2VvZiBYc2xBdHRyaWJ1dGUpKSB7Ci0gICAgICAgICAgICAgICAgICAgIG5vZGUudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIENvbXBpbGUgY29kZSB0byBlbWl0IGF0dHJpYnV0ZXMgYW5kIGNoaWxkIGVsZW1lbnRzCi0gICAgICAgIHRyYW5zbGF0ZUNvbnRlbnRzKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCi0gICAgICAgIC8vIENvbXBpbGUgY29kZSB0byBlbWl0IGVsZW1lbnQgZW5kIHRhZwotICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmVuZEVsZW1lbnQoKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRydWUgaWYgdGhlIG91dHB1dCBtZXRob2QgaXMgaHRtbC4KLSAgICAgKi8KLSAgICBwcml2YXRlIGJvb2xlYW4gaXNIVE1MT3V0cHV0KCkgewotICAgICAgICByZXR1cm4gZ2V0U3R5bGVzaGVldCgpLmdldE91dHB1dE1ldGhvZCgpID09IFN0eWxlc2hlZXQuSFRNTF9PVVRQVVQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSBFbGVtRGVzYyBvYmplY3QgZm9yIGFuIEhUTUwgZWxlbWVudC4KLSAgICAgKiBSZXR1cm4gbnVsbCBpZiB0aGUgb3V0cHV0IG1ldGhvZCBpcyBub3QgSFRNTCBvciB0aGlzIGlzIG5vdCBhCi0gICAgICogdmFsaWQgSFRNTCBlbGVtZW50LgotICAgICAqLwotICAgIHB1YmxpYyBFbGVtRGVzYyBnZXRFbGVtRGVzYygpIHsKLSAgICAgICAgaWYgKGlzSFRNTE91dHB1dCgpKSB7Ci0gICAgICAgICAgICByZXR1cm4gVG9IVE1MU3RyZWFtLmdldEVsZW1EZXNjKF9uYW1lKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdHJ1ZSBpZiBhbGwgYXR0cmlidXRlcyBvZiB0aGlzIExSRSBoYXZlIHVuaXF1ZSBuYW1lcy4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBhbGxBdHRyaWJ1dGVzVW5pcXVlKCkgewotICAgICAgICByZXR1cm4gX2FsbEF0dHJpYnV0ZXNVbmlxdWU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ2hlY2sgd2hldGhlciBhbGwgYXR0cmlidXRlcyBhcmUgdW5pcXVlLgotICAgICAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBjaGVja0F0dHJpYnV0ZXNVbmlxdWUoKSB7Ci0gICAgICAgICBib29sZWFuIGhhc0hpZGRlblhzbEF0dHJpYnV0ZSA9IGNhblByb2R1Y2VBdHRyaWJ1dGVOb2Rlcyh0aGlzLCB0cnVlKTsKLSAgICAgICAgIGlmIChoYXNIaWRkZW5Yc2xBdHRyaWJ1dGUpCi0gICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotCi0gICAgICAgICBpZiAoX2F0dHJpYnV0ZUVsZW1lbnRzICE9IG51bGwpIHsKLSAgICAgICAgICAgICBpbnQgbnVtQXR0cnMgPSBfYXR0cmlidXRlRWxlbWVudHMuc2l6ZSgpOwotICAgICAgICAgICAgIE1hcDxTdHJpbmcsIFN5bnRheFRyZWVOb2RlPiBhdHRyc1RhYmxlID0gbnVsbDsKLSAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bUF0dHJzOyBpKyspIHsKLSAgICAgICAgICAgICAgICAgU3ludGF4VHJlZU5vZGUgbm9kZSA9IF9hdHRyaWJ1dGVFbGVtZW50cy5nZXQoaSk7Ci0KLSAgICAgICAgICAgICAgICAgaWYgKG5vZGUgaW5zdGFuY2VvZiBVc2VBdHRyaWJ1dGVTZXRzKSB7Ci0gICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgZWxzZSBpZiAobm9kZSBpbnN0YW5jZW9mIFhzbEF0dHJpYnV0ZSkgewotICAgICAgICAgICAgICAgICAgICAgaWYgKGF0dHJzVGFibGUgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgYXR0cnNUYWJsZSA9IG5ldyBIYXNoTWFwPD4oKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBrID0gMDsgayA8IGk7IGsrKykgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTeW50YXhUcmVlTm9kZSBuID0gX2F0dHJpYnV0ZUVsZW1lbnRzLmdldChrKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG4gaW5zdGFuY2VvZiBMaXRlcmFsQXR0cmlidXRlKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXRlcmFsQXR0cmlidXRlIGxpdGVyYWxBdHRyID0gKExpdGVyYWxBdHRyaWJ1dGUpbjsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJzVGFibGUucHV0KGxpdGVyYWxBdHRyLmdldE5hbWUoKSwgbGl0ZXJhbEF0dHIpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgICBYc2xBdHRyaWJ1dGUgeHNsQXR0ciA9IChYc2xBdHRyaWJ1dGUpbm9kZTsKLSAgICAgICAgICAgICAgICAgICAgIEF0dHJpYnV0ZVZhbHVlIGF0dHJOYW1lID0geHNsQXR0ci5nZXROYW1lKCk7Ci0gICAgICAgICAgICAgICAgICAgICBpZiAoYXR0ck5hbWUgaW5zdGFuY2VvZiBBdHRyaWJ1dGVWYWx1ZVRlbXBsYXRlKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoYXR0ck5hbWUgaW5zdGFuY2VvZiBTaW1wbGVBdHRyaWJ1dGVWYWx1ZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgIFNpbXBsZUF0dHJpYnV0ZVZhbHVlIHNpbXBsZUF0dHIgPSAoU2ltcGxlQXR0cmlidXRlVmFsdWUpYXR0ck5hbWU7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG5hbWUgPSBzaW1wbGVBdHRyLnRvU3RyaW5nKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5hbWUgIT0gbnVsbCAmJiBhdHRyc1RhYmxlLmdldChuYW1lKSAhPSBudWxsKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAobmFtZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJzVGFibGUucHV0KG5hbWUsIHhzbEF0dHIpOwotICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgIH0KLSAgICAgICAgIH0KLSAgICAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybiB0cnVlIGlmIHRoZSBpbnN0cnVjdGlvbnMgdW5kZXIgdGhlIGdpdmVuIFN5bnRheFRyZWVOb2RlIGNhbiBwcm9kdWNlIGF0dHJpYnV0ZSBub2RlcwotICAgICAqIHRvIGFuIGVsZW1lbnQuIE9ubHkgcmV0dXJuIGZhbHNlIHdoZW4gd2UgYXJlIHN1cmUgdGhhdCBubyBhdHRyaWJ1dGUgbm9kZSBpcyBwcm9kdWNlZC4KLSAgICAgKiBSZXR1cm4gdHJ1ZSBpZiB3ZSBhcmUgbm90IHN1cmUuIElmIHRoZSBmbGFnIGlnbm9yZVhzbEF0dHJpYnV0ZSBpcyB0cnVlLCB0aGUgZGlyZWN0Ci0gICAgICogPHhzbDphdHRyaWJ1dGU+IGNoaWxkcmVuIG9mIHRoZSBjdXJyZW50IG5vZGUgYXJlIG5vdCBpbmNsdWRlZCBpbiB0aGUgY2hlY2suCi0gICAgICovCi0gICAgcHJpdmF0ZSBib29sZWFuIGNhblByb2R1Y2VBdHRyaWJ1dGVOb2RlcyhTeW50YXhUcmVlTm9kZSBub2RlLCBib29sZWFuIGlnbm9yZVhzbEF0dHJpYnV0ZSkgewotICAgICAgICBMaXN0PFN5bnRheFRyZWVOb2RlPiBjb250ZW50cyA9IG5vZGUuZ2V0Q29udGVudHMoKTsKLSAgICAgICAgZm9yIChTeW50YXhUcmVlTm9kZSBjaGlsZCA6IGNvbnRlbnRzKSB7Ci0gICAgICAgICAgICBpZiAoY2hpbGQgaW5zdGFuY2VvZiBUZXh0KSB7Ci0gICAgICAgICAgICAgICAgVGV4dCB0ZXh0ID0gKFRleHQpY2hpbGQ7Ci0gICAgICAgICAgICAgICAgaWYgKHRleHQuaXNJZ25vcmUoKSkKLSAgICAgICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyBDYW5ub3QgYWRkIGFuIGF0dHJpYnV0ZSB0byBhbiBlbGVtZW50IGFmdGVyIGNoaWxkcmVuIGhhdmUgYmVlbiBhZGRlZCB0byBpdC4KLSAgICAgICAgICAgIC8vIFdlIGNhbiBzYWZlbHkgcmV0dXJuIGZhbHNlIHdoZW4gdGhlIGluc3RydWN0aW9uIGNhbiBwcm9kdWNlIGFuIG91dHB1dCBub2RlLgotICAgICAgICAgICAgZWxzZSBpZiAoY2hpbGQgaW5zdGFuY2VvZiBMaXRlcmFsRWxlbWVudAotICAgICAgICAgICAgICAgIHx8IGNoaWxkIGluc3RhbmNlb2YgVmFsdWVPZgotICAgICAgICAgICAgICAgIHx8IGNoaWxkIGluc3RhbmNlb2YgWHNsRWxlbWVudAotICAgICAgICAgICAgICAgIHx8IGNoaWxkIGluc3RhbmNlb2YgQ29tbWVudAotICAgICAgICAgICAgICAgIHx8IGNoaWxkIGluc3RhbmNlb2YgTnVtYmVyCi0gICAgICAgICAgICAgICAgfHwgY2hpbGQgaW5zdGFuY2VvZiBQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24pCi0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgZWxzZSBpZiAoY2hpbGQgaW5zdGFuY2VvZiBYc2xBdHRyaWJ1dGUpIHsKLSAgICAgICAgICAgICAgICBpZiAoaWdub3JlWHNsQXR0cmlidXRlKQotICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gSW4gZ2VuZXJhbCwgdGhlcmUgaXMgbm8gd2F5IHRvIGNoZWNrIHdoZXRoZXIgPHhzbDpjYWxsLXRlbXBsYXRlPiBvcgotICAgICAgICAgICAgLy8gPHhzbDphcHBseS10ZW1wbGF0ZXM+IGNhbiBwcm9kdWNlIGF0dHJpYnV0ZSBub2Rlcy4gPHhzbDpjb3B5PiBhbmQKLSAgICAgICAgICAgIC8vIDx4c2w6Y29weS1vZj4gY2FuIGFsc28gY29weSBhdHRyaWJ1dGUgbm9kZXMgdG8gYW4gZWxlbWVudC4gUmV0dXJuCi0gICAgICAgICAgICAvLyB0cnVlIGluIHRob3NlIGNhc2VzIHRvIGJlIHNhZmUuCi0gICAgICAgICAgICBlbHNlIGlmIChjaGlsZCBpbnN0YW5jZW9mIENhbGxUZW1wbGF0ZQotICAgICAgICAgICAgICAgIHx8IGNoaWxkIGluc3RhbmNlb2YgQXBwbHlUZW1wbGF0ZXMKLSAgICAgICAgICAgICAgICB8fCBjaGlsZCBpbnN0YW5jZW9mIENvcHkKLSAgICAgICAgICAgICAgICB8fCBjaGlsZCBpbnN0YW5jZW9mIENvcHlPZikKLSAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgICAgIGVsc2UgaWYgKChjaGlsZCBpbnN0YW5jZW9mIElmCi0gICAgICAgICAgICAgICAgICAgICAgIHx8IGNoaWxkIGluc3RhbmNlb2YgRm9yRWFjaCkKLSAgICAgICAgICAgICAgICAgICAgICYmIGNhblByb2R1Y2VBdHRyaWJ1dGVOb2RlcyhjaGlsZCwgZmFsc2UpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChjaGlsZCBpbnN0YW5jZW9mIENob29zZSkgewotICAgICAgICAgICAgICAgIExpc3Q8U3ludGF4VHJlZU5vZGU+IGNob29zZUNvbnRlbnRzID0gY2hpbGQuZ2V0Q29udGVudHMoKTsKLSAgICAgICAgICAgICAgICBmb3IgKFN5bnRheFRyZWVOb2RlIGNob29zZUNoaWxkIDogY2hvb3NlQ29udGVudHMpIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGNob29zZUNoaWxkIGluc3RhbmNlb2YgV2hlbiB8fCBjaG9vc2VDaGlsZCBpbnN0YW5jZW9mIE90aGVyd2lzZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNhblByb2R1Y2VBdHRyaWJ1dGVOb2RlcyhjaG9vc2VDaGlsZCwgZmFsc2UpKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvTGl0ZXJhbEV4cHIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvTGl0ZXJhbEV4cHIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZDk3MDAxYy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL0xpdGVyYWxFeHByLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4NyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IExpdGVyYWxFeHByLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMDEgMTU6NTg6NTMgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5Db25zdGFudFBvb2xHZW47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JbnN0cnVjdGlvbkxpc3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5QVVNIOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkNsYXNzR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLk1ldGhvZEdlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGVDaGVja0Vycm9yOwotCi0vKioKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqLwotZmluYWwgY2xhc3MgTGl0ZXJhbEV4cHIgZXh0ZW5kcyBFeHByZXNzaW9uIHsKLSAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBfdmFsdWU7Ci0gICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgX25hbWVzcGFjZTsKLQotICAgIC8qKgotICAgICAqIENyZWF0ZXMgYSBuZXcgbGl0ZXJhbCBleHByZXNzaW9uIG5vZGUuCi0gICAgICogQHBhcmFtIHZhbHVlIHRoZSBsaXRlcmFsIGV4cHJlc3Npb24gY29udGVudC92YWx1ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgTGl0ZXJhbEV4cHIoU3RyaW5nIHZhbHVlKSB7Ci0gICAgICAgIF92YWx1ZSA9IHZhbHVlOwotICAgICAgICBfbmFtZXNwYWNlID0gbnVsbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGVzIGEgbmV3IGxpdGVyYWwgZXhwcmVzc2lvbiBub2RlLgotICAgICAqIEBwYXJhbSB2YWx1ZSB0aGUgbGl0ZXJhbCBleHByZXNzaW9uIGNvbnRlbnQvdmFsdWUuCi0gICAgICogQHBhcmFtIG5hbWVzcGFjZSB0aGUgbmFtZXNwYWNlIGluIHdoaWNoIHRoZSBleHByZXNzaW9uIGV4aXN0cy4KLSAgICAgKi8KLSAgICBwdWJsaWMgTGl0ZXJhbEV4cHIoU3RyaW5nIHZhbHVlLCBTdHJpbmcgbmFtZXNwYWNlKSB7Ci0gICAgICAgIF92YWx1ZSA9IHZhbHVlOwotICAgICAgICBfbmFtZXNwYWNlID0gbmFtZXNwYWNlLmVxdWFscyhDb25zdGFudHMuRU1QVFlTVFJJTkcpID8gbnVsbCA6IG5hbWVzcGFjZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgVHlwZSB0eXBlQ2hlY2soU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgewotICAgICAgICByZXR1cm4gX3R5cGUgPSBUeXBlLlN0cmluZzsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgICAgICByZXR1cm4gImxpdGVyYWwtZXhwcigiICsgX3ZhbHVlICsgJyknOwotICAgIH0KLQotICAgIHByb3RlY3RlZCBib29sZWFuIGNvbnRleHREZXBlbmRlbnQoKSB7Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICBwcm90ZWN0ZWQgU3RyaW5nIGdldFZhbHVlKCkgewotICAgICAgICByZXR1cm4gX3ZhbHVlOwotICAgIH0KLQotICAgIHByb3RlY3RlZCBTdHJpbmcgZ2V0TmFtZXNwYWNlKCkgewotICAgICAgICByZXR1cm4gX25hbWVzcGFjZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLSAgICAgICAgZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsIF92YWx1ZSkpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvTG9jYWxOYW1lQ2FsbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9Mb2NhbE5hbWVDYWxsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDhhOWZjYWUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9Mb2NhbE5hbWVDYWxsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3NiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBMb2NhbE5hbWVDYWxsLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMDEgMTY6MDA6MjEgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQ29uc3RhbnRQb29sR2VuOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFSU5URVJGQUNFOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFU1RBVElDOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW5zdHJ1Y3Rpb25MaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkNsYXNzR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLk1ldGhvZEdlbmVyYXRvcjsKLQotLyoqCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqLwotZmluYWwgY2xhc3MgTG9jYWxOYW1lQ2FsbCBleHRlbmRzIE5hbWVCYXNlIHsKLQotICAgIC8qKgotICAgICAqIEhhbmRsZXMgY2FsbHMgd2l0aCBubyBwYXJhbWV0ZXIgKGN1cnJlbnQgbm9kZSBpcyBpbXBsaWNpdCBwYXJhbWV0ZXIpLgotICAgICAqLwotICAgIHB1YmxpYyBMb2NhbE5hbWVDYWxsKFFOYW1lIGZuYW1lKSB7Ci0gICAgICAgIHN1cGVyKGZuYW1lKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBIYW5kbGVzIGNhbGxzIHdpdGggb25lIHBhcmFtZXRlciAoZWl0aGVyIG5vZGUgb3Igbm9kZS1zZXQpLgotICAgICAqLwotICAgIHB1YmxpYyBMb2NhbE5hbWVDYWxsKFFOYW1lIGZuYW1lLCBWZWN0b3IgYXJndW1lbnRzKSB7Ci0gICAgICAgIHN1cGVyKGZuYW1lLCBhcmd1bWVudHMpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCB3aGVuIHRoZSBjb25zdHJ1Y3RvciBpcyBjb21waWxlZCBpbgotICAgICAqIFN0eWxlc2hlZXQuY29tcGlsZUNvbnN0cnVjdG9yKCkgYW5kIG5vdCBhcyB0aGUgc3ludGF4IHRyZWUgaXMgdHJhdmVyc2VkLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotICAgICAgICBmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQotICAgICAgICAvLyBSZXR1cm5zIHRoZSBuYW1lIG9mIGEgbm9kZSBpbiB0aGUgRE9NCi0gICAgICAgIGZpbmFsIGludCBnZXROb2RlTmFtZSA9IGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoRE9NX0lOVEYsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImdldE5vZGVOYW1lIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKEkpIitTVFJJTkdfU0lHKTsKLQotICAgICAgICBmaW5hbCBpbnQgZ2V0TG9jYWxOYW1lID0gY3BnLmFkZE1ldGhvZHJlZihCQVNJU19MSUJSQVJZX0NMQVNTLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZ2V0TG9jYWxOYW1lIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIihMamF2YS9sYW5nL1N0cmluZzspIisKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkxqYXZhL2xhbmcvU3RyaW5nOyIpOwotICAgICAgICBzdXBlci50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFSU5URVJGQUNFKGdldE5vZGVOYW1lLCAyKSk7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFU1RBVElDKGdldExvY2FsTmFtZSkpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvTG9jYXRpb25QYXRoUGF0dGVybi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9Mb2NhdGlvblBhdGhQYXR0ZXJuLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDM5MTgwOWQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9Mb2NhdGlvblBhdGhQYXR0ZXJuLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMDkgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogTG9jYXRpb25QYXRoUGF0dGVybi5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzEyIDEwOjQyOjQyIHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkNsYXNzR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLk1ldGhvZEdlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGVDaGVja0Vycm9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkF4aXM7Ci0KLS8qKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKi8KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBMb2NhdGlvblBhdGhQYXR0ZXJuIGV4dGVuZHMgUGF0dGVybiB7Ci0gICAgcHJpdmF0ZSBUZW1wbGF0ZSBfdGVtcGxhdGU7Ci0gICAgcHJpdmF0ZSBpbnQgX2ltcG9ydFByZWNlZGVuY2U7Ci0gICAgcHJpdmF0ZSBkb3VibGUgX3ByaW9yaXR5ID0gRG91YmxlLk5hTjsKLSAgICBwcml2YXRlIGludCBfcG9zaXRpb24gPSAwOwotCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLSAgICAgICAgcmV0dXJuIFR5cGUuVm9pZDsgICAgICAgICAgICAgICAvLyBUT0RPCi0gICAgfQotCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0gICAgICAgIC8vIFRPRE86IFdoYXQgZG9lcyBpdCBtZWFuIHRvIHRyYW5zbGF0ZSBhIFBhdHRlcm4gPwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldFRlbXBsYXRlKGZpbmFsIFRlbXBsYXRlIHRlbXBsYXRlKSB7Ci0gICAgICAgIF90ZW1wbGF0ZSA9IHRlbXBsYXRlOwotICAgICAgICBfcHJpb3JpdHkgPSB0ZW1wbGF0ZS5nZXRQcmlvcml0eSgpOwotICAgICAgICBfaW1wb3J0UHJlY2VkZW5jZSA9IHRlbXBsYXRlLmdldEltcG9ydFByZWNlZGVuY2UoKTsKLSAgICAgICAgX3Bvc2l0aW9uID0gdGVtcGxhdGUuZ2V0UG9zaXRpb24oKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgVGVtcGxhdGUgZ2V0VGVtcGxhdGUoKSB7Ci0gICAgICAgIHJldHVybiBfdGVtcGxhdGU7Ci0gICAgfQotCi0gICAgcHVibGljIGZpbmFsIGRvdWJsZSBnZXRQcmlvcml0eSgpIHsKLSAgICAgICAgcmV0dXJuIERvdWJsZS5pc05hTihfcHJpb3JpdHkpID8gZ2V0RGVmYXVsdFByaW9yaXR5KCkgOiBfcHJpb3JpdHk7Ci0gICAgfQotCi0gICAgcHVibGljIGRvdWJsZSBnZXREZWZhdWx0UHJpb3JpdHkoKSB7Ci0gICAgICAgIHJldHVybiAwLjU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgaXMgdXNlZCBieSB0aGUgTW9kZSBjbGFzcyB0byBwcmlvcml0aXNlIHBhdHRlcm5zIGFuZAotICAgICAqIHRlbXBsYXRlLiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgZm9yIHRlbXBsYXRlcyB0aGF0IGFyZSBpbiB0aGUgc2FtZQotICAgICAqIG1vZGUgYW5kIHRoYXQgbWF0Y2ggb24gdGhlIHNhbWUgY29yZSBwYXR0ZXJuLiBUaGUgcnVsZXMgdXNlZCBhcmU6Ci0gICAgICogIG8pIGZpcnN0IGNoZWNrIHByZWNlZGVuY2UgLSBoaWdoZXN0IHByZWNlZGVuY2Ugd2lucwotICAgICAqICBvKSB0aGVuIGNoZWNrIHByaW9yaXR5IC0gaGlnaGVzdCBwcmlvcml0eSB3aW5zCi0gICAgICogIG8pIHRoZW4gY2hlY2sgdGhlIHBvc2l0aW9uIC0gdGhlIHRlbXBsYXRlIHRoYXQgb2NjdXJlZCBsYXN0IHdpbnMKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBub1NtYWxsZXJUaGFuKExvY2F0aW9uUGF0aFBhdHRlcm4gb3RoZXIpIHsKLSAgICAgICAgaWYgKF9pbXBvcnRQcmVjZWRlbmNlID4gb3RoZXIuX2ltcG9ydFByZWNlZGVuY2UpIHsKLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKF9pbXBvcnRQcmVjZWRlbmNlID09IG90aGVyLl9pbXBvcnRQcmVjZWRlbmNlKSB7Ci0gICAgICAgICAgICBpZiAoX3ByaW9yaXR5ID4gb3RoZXIuX3ByaW9yaXR5KSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChfcHJpb3JpdHkgPT0gb3RoZXIuX3ByaW9yaXR5KSB7Ci0gICAgICAgICAgICAgICAgaWYgKF9wb3NpdGlvbiA+IG90aGVyLl9wb3NpdGlvbikgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIHB1YmxpYyBhYnN0cmFjdCBTdGVwUGF0dGVybiBnZXRLZXJuZWxQYXR0ZXJuKCk7Ci0KLSAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCByZWR1Y2VLZXJuZWxQYXR0ZXJuKCk7Ci0KLSAgICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBpc1dpbGRjYXJkKCk7Ci0KLSAgICBwdWJsaWMgaW50IGdldEF4aXMoKSB7Ci0gICAgICAgIGZpbmFsIFN0ZXBQYXR0ZXJuIHNwID0gZ2V0S2VybmVsUGF0dGVybigpOwotICAgICAgICByZXR1cm4gKHNwICE9IG51bGwpID8gc3AuZ2V0QXhpcygpIDogQXhpcy5DSElMRDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgICAgICByZXR1cm4gInJvb3QoKSI7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9Mb2dpY2FsRXhwci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9Mb2dpY2FsRXhwci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2ZTI5NWJhLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvTG9naWNhbEV4cHIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIzNSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBMb2dpY2FsRXhwci5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzAxIDE2OjAzOjMxIHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuR09UTzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uSGFuZGxlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW5zdHJ1Y3Rpb25MaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkNsYXNzR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLk1ldGhvZEdlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5NZXRob2RUeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZUNoZWNrRXJyb3I7Ci0KLS8qKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKi8KLWZpbmFsIGNsYXNzIExvZ2ljYWxFeHByIGV4dGVuZHMgRXhwcmVzc2lvbiB7Ci0KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUiAgPSAwOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFORCA9IDE7Ci0KLSAgICBwcml2YXRlIGZpbmFsIGludCAgX29wOyAgICAgLy8gb3BlcmF0b3IKLSAgICBwcml2YXRlIEV4cHJlc3Npb24gX2xlZnQ7ICAgLy8gZmlyc3Qgb3BlcmFuZAotICAgIHByaXZhdGUgRXhwcmVzc2lvbiBfcmlnaHQ7ICAvLyBzZWNvbmQgb3BlcmFuZAotCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nW10gT3BzID0geyAib3IiLCAiYW5kIiB9OwotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlcyBhIG5ldyBsb2dpY2FsIGV4cHJlc3Npb24gLSBlaXRoZXIgT1Igb3IgQU5ELiBOb3RlIHRoYXQgdGhlCi0gICAgICogbGVmdC0gYW5kIHJpZ2h0LWhhbmQgc2lkZSBleHByZXNzaW9ucyBjYW4gYWxzbyBiZSBsb2dpY2FsIGV4cHJlc3Npb25zLAotICAgICAqIHRodXMgY3JlYXRpbmcgbG9naWNhbCB0cmVlcyByZXByZXNlbnRpbmcgc3RydWN0dXJlcyBzdWNoIGFzCi0gICAgICogKGEgYW5kIChiIG9yIGMpIGFuZCBkKSwgZXRjLi4uCi0gICAgICovCi0gICAgcHVibGljIExvZ2ljYWxFeHByKGludCBvcCwgRXhwcmVzc2lvbiBsZWZ0LCBFeHByZXNzaW9uIHJpZ2h0KSB7Ci0gICAgICAgIF9vcCA9IG9wOwotICAgICAgICAoX2xlZnQgPSBsZWZ0KS5zZXRQYXJlbnQodGhpcyk7Ci0gICAgICAgIChfcmlnaHQgPSByaWdodCkuc2V0UGFyZW50KHRoaXMpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGlzIGV4cHJlc3Npb25zIGNvbnRhaW5zIGEgY2FsbCB0byBwb3NpdGlvbigpLiBUaGlzIGlzCi0gICAgICogbmVlZGVkIGZvciBjb250ZXh0IGNoYW5nZXMgaW4gbm9kZSBzdGVwcyBjb250YWluaW5nIG11bHRpcGxlIHByZWRpY2F0ZXMuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaGFzUG9zaXRpb25DYWxsKCkgewotICAgICAgICByZXR1cm4gKF9sZWZ0Lmhhc1Bvc2l0aW9uQ2FsbCgpIHx8IF9yaWdodC5oYXNQb3NpdGlvbkNhbGwoKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIGlmIHRoaXMgZXhwcmVzc2lvbnMgY29udGFpbnMgYSBjYWxsIHRvIGxhc3QoKQotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGhhc0xhc3RDYWxsKCkgewotICAgICAgICAgICAgcmV0dXJuIChfbGVmdC5oYXNMYXN0Q2FsbCgpIHx8IF9yaWdodC5oYXNMYXN0Q2FsbCgpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGFuIG9iamVjdCByZXByZXNlbnRpbmcgdGhlIGNvbXBpbGUtdGltZSBldmFsdWF0aW9uCi0gICAgICogb2YgYW4gZXhwcmVzc2lvbi4gV2UgYXJlIG9ubHkgdXNpbmcgdGhpcyBmb3IgZnVuY3Rpb24tYXZhaWxhYmxlCi0gICAgICogYW5kIGVsZW1lbnQtYXZhaWxhYmxlIGF0IHRoaXMgdGltZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0IGV2YWx1YXRlQXRDb21waWxlVGltZSgpIHsKLSAgICAgICAgZmluYWwgT2JqZWN0IGxlZnRiID0gX2xlZnQuZXZhbHVhdGVBdENvbXBpbGVUaW1lKCk7Ci0gICAgICAgIGZpbmFsIE9iamVjdCByaWdodGIgPSBfcmlnaHQuZXZhbHVhdGVBdENvbXBpbGVUaW1lKCk7Ci0KLSAgICAgICAgLy8gUmV0dXJuIG51bGwgaWYgd2UgY2FuJ3QgZXZhbHVhdGUgYXQgY29tcGlsZSB0aW1lCi0gICAgICAgIGlmIChsZWZ0YiA9PSBudWxsIHx8IHJpZ2h0YiA9PSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChfb3AgPT0gQU5EKSB7Ci0gICAgICAgICAgICByZXR1cm4gKGxlZnRiID09IEJvb2xlYW4uVFJVRSAmJiByaWdodGIgPT0gQm9vbGVhbi5UUlVFKSA/Ci0gICAgICAgICAgICAgICAgQm9vbGVhbi5UUlVFIDogQm9vbGVhbi5GQUxTRTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiAobGVmdGIgPT0gQm9vbGVhbi5UUlVFIHx8IHJpZ2h0YiA9PSBCb29sZWFuLlRSVUUpID8KLSAgICAgICAgICAgICAgICBCb29sZWFuLlRSVUUgOiBCb29sZWFuLkZBTFNFOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGlzIGxvZ2ljYWwgZXhwcmVzc2lvbidzIG9wZXJhdG9yIC0gT1Igb3IgQU5EIHJlcHJlc2VudGVkCi0gICAgICogYnkgMCBhbmQgMSByZXNwZWN0aXZlbHkuCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRPcCgpIHsKLSAgICAgICAgcmV0dXJuKF9vcCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogT3ZlcnJpZGUgdGhlIFN5bnRheFRyZWVOb2RlLnNldFBhcnNlcigpIG1ldGhvZCB0byBtYWtlIHN1cmUgdGhhdCB0aGUKLSAgICAgKiBwYXJzZXIgaXMgc2V0IGZvciBzdWItZXhwcmVzc2lvbnMKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRQYXJzZXIoUGFyc2VyIHBhcnNlcikgewotICAgICAgICBzdXBlci5zZXRQYXJzZXIocGFyc2VyKTsKLSAgICAgICAgX2xlZnQuc2V0UGFyc2VyKHBhcnNlcik7Ci0gICAgICAgIF9yaWdodC5zZXRQYXJzZXIocGFyc2VyKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGEgc3RyaW5nIGRlc2NyaWJpbmcgdGhpcyBleHByZXNzaW9uCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKLSAgICAgICAgcmV0dXJuIE9wc1tfb3BdICsgJygnICsgX2xlZnQgKyAiLCAiICsgX3JpZ2h0ICsgJyknOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFR5cGUtY2hlY2sgdGhpcyBleHByZXNzaW9uLCBhbmQgcG9zc2libHkgY2hpbGQgZXhwcmVzc2lvbnMuCi0gICAgICovCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLSAgICAgICAgLy8gR2V0IHRoZSBsZWZ0IGFuZCByaWdodCBvcGVyYW5kIHR5cGVzCi0gICAgICAgIFR5cGUgdGxlZnQgPSBfbGVmdC50eXBlQ2hlY2soc3RhYmxlKTsKLSAgICAgICAgVHlwZSB0cmlnaHQgPSBfcmlnaHQudHlwZUNoZWNrKHN0YWJsZSk7Ci0KLSAgICAgICAgLy8gQ2hlY2sgaWYgdGhlIG9wZXJhdG9yIHN1cHBvcnRzIHRoZSB0d28gb3BlcmFuZCB0eXBlcwotICAgICAgICBNZXRob2RUeXBlIHdhbnRUeXBlID0gbmV3IE1ldGhvZFR5cGUoVHlwZS5Wb2lkLCB0bGVmdCwgdHJpZ2h0KTsKLSAgICAgICAgTWV0aG9kVHlwZSBoYXZlVHlwZSA9IGxvb2t1cFByaW1vcChzdGFibGUsIE9wc1tfb3BdLCB3YW50VHlwZSk7Ci0KLSAgICAgICAgLy8gWWVzLCB0aGUgb3BlcmF0aW9uIGlzIHN1cHBvcnRlZAotICAgICAgICBpZiAoaGF2ZVR5cGUgIT0gbnVsbCkgewotICAgICAgICAgICAgLy8gQ2hlY2sgaWYgbGVmdC1oYW5kIHNpZGUgb3BlcmFuZCBtdXN0IGJlIHR5cGUgY2FzdGVkCi0gICAgICAgICAgICBUeXBlIGFyZzEgPSAoVHlwZSloYXZlVHlwZS5hcmdzVHlwZSgpLmVsZW1lbnRBdCgwKTsKLSAgICAgICAgICAgIGlmICghYXJnMS5pZGVudGljYWxUbyh0bGVmdCkpCi0gICAgICAgICAgICAgICAgX2xlZnQgPSBuZXcgQ2FzdEV4cHIoX2xlZnQsIGFyZzEpOwotICAgICAgICAgICAgLy8gQ2hlY2sgaWYgcmlnaHQtaGFuZCBzaWRlIG9wZXJhbmQgbXVzdCBiZSB0eXBlIGNhc3RlZAotICAgICAgICAgICAgVHlwZSBhcmcyID0gKFR5cGUpIGhhdmVUeXBlLmFyZ3NUeXBlKCkuZWxlbWVudEF0KDEpOwotICAgICAgICAgICAgaWYgKCFhcmcyLmlkZW50aWNhbFRvKHRyaWdodCkpCi0gICAgICAgICAgICAgICAgX3JpZ2h0ID0gbmV3IENhc3RFeHByKF9yaWdodCwgYXJnMSk7Ci0gICAgICAgICAgICAvLyBSZXR1cm4gdGhlIHJlc3VsdCB0eXBlIGZvciB0aGUgb3BlcmF0b3Igd2Ugd2lsbCB1c2UKLSAgICAgICAgICAgIHJldHVybiBfdHlwZSA9IGhhdmVUeXBlLnJlc3VsdFR5cGUoKTsKLSAgICAgICAgfQotICAgICAgICB0aHJvdyBuZXcgVHlwZUNoZWNrRXJyb3IodGhpcyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29tcGlsZSB0aGUgZXhwcmVzc2lvbiAtIGxlYXZlIGJvb2xlYW4gZXhwcmVzc2lvbiBvbiBzdGFjawotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotICAgICAgICB0cmFuc2xhdGVEZXN5bnRoZXNpemVkKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICBzeW50aGVzaXplKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbXBpbGUgZXhwcmVzc2lvbiBhbmQgdXBkYXRlIHRydWUvZmFsc2UtbGlzdHMKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVEZXN5bnRoZXNpemVkKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCi0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLSAgICAgICAgZmluYWwgU3ludGF4VHJlZU5vZGUgcGFyZW50ID0gZ2V0UGFyZW50KCk7Ci0KLSAgICAgICAgLy8gQ29tcGlsZSBBTkQtZXhwcmVzc2lvbgotICAgICAgICBpZiAoX29wID09IEFORCkgewotCi0gICAgICAgICAgICAvLyBUcmFuc2xhdGUgbGVmdCBoYW5kIHNpZGUgLSBtdXN0IGJlIHRydWUKLSAgICAgICAgICAgIF9sZWZ0LnRyYW5zbGF0ZURlc3ludGhlc2l6ZWQoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0KLSAgICAgICAgICAgIC8vIE5lZWQgdGhpcyBmb3IgY2hhaW5pbmcgYW55IE9SLWV4cHJlc3Npb24gY2hpbGRyZW4KLSAgICAgICAgICAgIEluc3RydWN0aW9uSGFuZGxlIG1pZGRsZSA9IGlsLmFwcGVuZChOT1ApOwotCi0gICAgICAgICAgICAvLyBUcmFuc2xhdGUgbGVmdCByaWdodCBzaWRlIC0gbXVzdCBiZSB0cnVlCi0gICAgICAgICAgICBfcmlnaHQudHJhbnNsYXRlRGVzeW50aGVzaXplZChjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQotICAgICAgICAgICAgLy8gTmVlZCB0aGlzIGZvciBjaGFpbmluZyBhbnkgT1ItZXhwcmVzc2lvbiBjaGlsZHJlbgotICAgICAgICAgICAgSW5zdHJ1Y3Rpb25IYW5kbGUgYWZ0ZXIgPSBpbC5hcHBlbmQoTk9QKTsKLQotICAgICAgICAgICAgLy8gQXBwZW5kIGNoaWxkIGV4cHJlc3Npb24gZmFsc2UtbGlzdHMgdG8gb3VyIGZhbHNlLWxpc3QKLSAgICAgICAgICAgIF9mYWxzZUxpc3QuYXBwZW5kKF9yaWdodC5fZmFsc2VMaXN0LmFwcGVuZChfbGVmdC5fZmFsc2VMaXN0KSk7Ci0KLSAgICAgICAgICAgIC8vIFNwZWNpYWwgY2FzZSBmb3IgT1ItZXhwcmVzc2lvbiBhcyBhIGxlZnQgY2hpbGQgb2YgQU5ELgotICAgICAgICAgICAgLy8gVGhlIHRydWUtbGlzdCBvZiBPUiBtdXN0IHBvaW50IHRvIHNlY29uZCBjbGF1c2Ugb2YgQU5ELgotICAgICAgICAgICAgaWYgKChfbGVmdCBpbnN0YW5jZW9mIExvZ2ljYWxFeHByKSAmJgotICAgICAgICAgICAgICAgICgoKExvZ2ljYWxFeHByKV9sZWZ0KS5nZXRPcCgpID09IE9SKSkgewotICAgICAgICAgICAgICAgIF9sZWZ0LmJhY2tQYXRjaFRydWVMaXN0KG1pZGRsZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChfbGVmdCBpbnN0YW5jZW9mIE5vdENhbGwpIHsKLSAgICAgICAgICAgICAgICBfbGVmdC5iYWNrUGF0Y2hUcnVlTGlzdChtaWRkbGUpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgX3RydWVMaXN0LmFwcGVuZChfbGVmdC5fdHJ1ZUxpc3QpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBTcGVjaWFsIGNhc2UgZm9yIE9SLWV4cHJlc3Npb24gYXMgYSByaWdodCBjaGlsZCBvZiBBTkQKLSAgICAgICAgICAgIC8vIFRoZSB0cnVlLWxpc3Qgb2YgT1IgbXVzdCBwb2ludCB0byB0cnVlLWxpc3Qgb2YgQU5ELgotICAgICAgICAgICAgaWYgKChfcmlnaHQgaW5zdGFuY2VvZiBMb2dpY2FsRXhwcikgJiYKLSAgICAgICAgICAgICAgICAoKChMb2dpY2FsRXhwcilfcmlnaHQpLmdldE9wKCkgPT0gT1IpKSB7Ci0gICAgICAgICAgICAgICAgX3JpZ2h0LmJhY2tQYXRjaFRydWVMaXN0KGFmdGVyKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKF9yaWdodCBpbnN0YW5jZW9mIE5vdENhbGwpIHsKLSAgICAgICAgICAgICAgICBfcmlnaHQuYmFja1BhdGNoVHJ1ZUxpc3QoYWZ0ZXIpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgX3RydWVMaXN0LmFwcGVuZChfcmlnaHQuX3RydWVMaXN0KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICAvLyBDb21waWxlIE9SLWV4cHJlc3Npb24KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAvLyBUcmFuc2xhdGUgbGVmdC1oYW5kIHNpZGUgZXhwcmVzc2lvbiBhbmQgcHJvZHVjZSB0cnVlL2ZhbHNlIGxpc3QKLSAgICAgICAgICAgIF9sZWZ0LnRyYW5zbGF0ZURlc3ludGhlc2l6ZWQoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0KLSAgICAgICAgICAgIC8vIFRoaXMgR09UTyBpcyB1c2VkIHRvIHNraXAgb3ZlciB0aGUgY29kZSBmb3IgdGhlIGxhc3QgdGVzdAotICAgICAgICAgICAgLy8gaW4gdGhlIGNhc2Ugd2hlcmUgdGhlIHRoZSBmaXJzdCB0ZXN0IHN1Y2NlZWRzCi0gICAgICAgICAgICBJbnN0cnVjdGlvbkhhbmRsZSBpaCA9IGlsLmFwcGVuZChuZXcgR09UTyhudWxsKSk7Ci0KLSAgICAgICAgICAgIC8vIFRyYW5zbGF0ZSByaWdodC1oYW5kIHNpZGUgZXhwcmVzc2lvbiBhbmQgcHJvZHVjZSB0cnVlL2ZhbHNlIGxpc3QKLSAgICAgICAgICAgIF9yaWdodC50cmFuc2xhdGVEZXN5bnRoZXNpemVkKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCi0gICAgICAgICAgICBfbGVmdC5fdHJ1ZUxpc3QuYmFja1BhdGNoKGloKTsKLSAgICAgICAgICAgIF9sZWZ0Ll9mYWxzZUxpc3QuYmFja1BhdGNoKGloLmdldE5leHQoKSk7Ci0KLSAgICAgICAgICAgIF9mYWxzZUxpc3QuYXBwZW5kKF9yaWdodC5fZmFsc2VMaXN0KTsKLSAgICAgICAgICAgIF90cnVlTGlzdC5hZGQoaWgpLmFwcGVuZChfcmlnaHQuX3RydWVMaXN0KTsKLSAgICAgICAgfQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvTWFrZWZpbGUuaW5jIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9NYWtlZmlsZS5pbmMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDhjMWY1N2EuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9NYWtlZmlsZS5pbmMKKysrIC9kZXYvbnVsbApAQCAtMSw2MCArMCwwIEBACi0jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKLSMgcmVzZXJ2ZWQgY29tbWVudCBibG9jawotIyBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCi0jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwotIyBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSMKLSMgTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0jIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSMgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0jCi0jICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSMKLSMgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotIyBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotIyBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSMgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotIyBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCi0jCi0jICRJZDogTWFrZWZpbGUuaW5jLHYgMS4yIDIwMDQvMDIvMTcgMTY6MzI6NDkgbWluY2hhdSBFeHAgJAotIwotIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKLSMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjCi0jIE1ha2VmaWxlLmluYyBmb3IgWFNMVCBjb21waWxlciAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIwotIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMKLSMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCi0KLSMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCi0jIFVzZWZ1bCBtYWNyb3MgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIwotIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKLQotSkFWQUMgPSBqYXZhYwotI0pBVkFDX0ZMQUdTID0gLWcgLWQgJChYU0xUKS9zcmMvY2xhc3NlcwotSkFWQUNfRkxBR1MgPSAtc291cmNlcGF0aCAkKFhTTFQpL3NyYwotSkFWQUNDID0gamF2YWNjCi1KQVZBQ0NfRkxBR1MgPSAtc3RhdGljPUZBTFNFIAotSkFWQUNVUCA9IGphdmFjdXAKLUpBVkFDVVBfRkxBR1MgPQotSkFWQUxFWCA9IGpsZXgKLUpBVkFMRVhfRkxBR1MgPQotCi0jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwotIyAgRXhwbGljaXQgcnVsZXMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMKLSMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCi0KLS5TVUZGSVhFUzogLmphdmEgLmNsYXNzIC5qaiAubGV4IC5jdXAKLQotLmphdmEuY2xhc3M6Ci0JJChKQVZBQykgJChKQVZBQ19GTEFHUykgJDwKLQotLmpqLmphdmE6Ci0JJChKQVZBQ0MpICQoSkFWQUNDX0ZMQUdTKSAkPAotCi0uY3VwLmphdmE6Ci0JJChKQVZBQ1VQKSAkKEpBVkFDVVBfRkxBR1MpICQ8Ci0KLS5sZXguamF2YToKLQkkKEpBVkFMRVgpICQoSkFWQUxFWF9GTEFHUykgJDwKLQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9NZXNzYWdlLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL01lc3NhZ2UuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDM0YTI2Ny4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL01lc3NhZ2UuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE2OSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBNZXNzYWdlLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMDIgMDY6NDc6MDIgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5Db25zdGFudFBvb2xHZW47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JTlZPS0VJTlRFUkZBQ0U7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JTlZPS0VTUEVDSUFMOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFVklSVFVBTDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uTGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLk5FVzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlBVU0g7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuQ2xhc3NHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuTWV0aG9kR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZUNoZWNrRXJyb3I7Ci0KLS8qKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKi8KLWZpbmFsIGNsYXNzIE1lc3NhZ2UgZXh0ZW5kcyBJbnN0cnVjdGlvbiB7Ci0gICAgcHJpdmF0ZSBib29sZWFuIF90ZXJtaW5hdGUgPSBmYWxzZTsKLQotICAgIHB1YmxpYyB2b2lkIHBhcnNlQ29udGVudHMoUGFyc2VyIHBhcnNlcikgewotICAgICAgICBTdHJpbmcgdGVybXN0ciA9IGdldEF0dHJpYnV0ZSgidGVybWluYXRlIik7Ci0gICAgICAgIGlmICh0ZXJtc3RyICE9IG51bGwpIHsKLSAgICAgICAgICAgIF90ZXJtaW5hdGUgPSB0ZXJtc3RyLmVxdWFscygieWVzIik7Ci0gICAgICAgIH0KLSAgICAgICAgcGFyc2VDaGlsZHJlbihwYXJzZXIpOwotICAgIH0KLQotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0gICAgICAgIHR5cGVDaGVja0NvbnRlbnRzKHN0YWJsZSk7Ci0gICAgICAgIHJldHVybiBUeXBlLlZvaWQ7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0gICAgICAgIGZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCi0gICAgICAgIC8vIExvYWQgdGhlIHRyYW5zbGV0IChmb3IgY2FsbCB0byBkaXNwbGF5TWVzc2FnZSgpIGZ1bmN0aW9uKQotICAgICAgICBpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpOwotCi0gICAgICAgIHN3aXRjaCAoZWxlbWVudENvdW50KCkpIHsKLSAgICAgICAgICAgIGNhc2UgMDoKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCAiIikpOwotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICBjYXNlIDE6Ci0gICAgICAgICAgICAgICAgU3ludGF4VHJlZU5vZGUgY2hpbGQgPSAoU3ludGF4VHJlZU5vZGUpIGVsZW1lbnRBdCgwKTsKLSAgICAgICAgICAgICAgICBpZiAoY2hpbGQgaW5zdGFuY2VvZiBUZXh0KSB7Ci0gICAgICAgICAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsICgoVGV4dCkgY2hpbGQpLmdldFRleHQoKSkpOwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLy8gZmFsbHMgdGhyb3VnaAotICAgICAgICAgICAgZGVmYXVsdDoKLSAgICAgICAgICAgICAgICAvLyBQdXNoIGN1cnJlbnQgb3V0cHV0IGhhbmRsZXIgb250byB0aGUgc3RhY2sKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRIYW5kbGVyKCkpOwotCi0gICAgICAgICAgICAgICAgLy8gUmVwbGFjZSB0aGUgY3VycmVudCBvdXRwdXQgaGFuZGxlciBieSBhIFRvWE1MU3RyZWFtCi0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBORVcoY3BnLmFkZENsYXNzKFNUUkVBTV9YTUxfT1VUUFVUKSkpOwotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4uc3RvcmVIYW5kbGVyKCkpOwotCi0gICAgICAgICAgICAgICAgLy8gUHVzaCBhIHJlZmVyZW5jZSB0byBhIFN0cmluZ1dyaXRlcgotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgTkVXKGNwZy5hZGRDbGFzcyhTVFJJTkdfV1JJVEVSKSkpOwotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChEVVApOwotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChEVVApOwotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFU1BFQ0lBTCgKLSAgICAgICAgICAgICAgICAgICAgY3BnLmFkZE1ldGhvZHJlZihTVFJJTkdfV1JJVEVSLCAiPGluaXQ+IiwgIigpViIpKSk7Ci0KLSAgICAgICAgICAgICAgICAvLyBMb2FkIFRvWE1MU3RyZWFtCi0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkSGFuZGxlcigpKTsKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRVNQRUNJQUwoCi0gICAgICAgICAgICAgICAgICAgIGNwZy5hZGRNZXRob2RyZWYoU1RSRUFNX1hNTF9PVVRQVVQsICI8aW5pdD4iLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoKVYiKSkpOwotCi0gICAgICAgICAgICAgICAgLy8gSW52b2tlIG91dHB1dC5zZXRXcml0ZXIoU1RSSU5HX1dSSVRFUikKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRIYW5kbGVyKCkpOwotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChTV0FQKTsKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRUlOVEVSRkFDRSgKLSAgICAgICAgICAgICAgICAgICAgY3BnLmFkZEludGVyZmFjZU1ldGhvZHJlZihUUkFOU0xFVF9PVVRQVVRfSU5URVJGQUNFLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJzZXRXcml0ZXIiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoIitXUklURVJfU0lHKyIpViIpLCAyKSk7Ci0KLSAgICAgICAgICAgICAgICAvLyBJbnZva2Ugb3V0cHV0LnNldEVuY29kaW5nKCJVVEYtOCIpCi0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkSGFuZGxlcigpKTsKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCAiVVRGLTgiKSk7ICAgLy8gb3RoZXIgZW5jb2RpbmdzPwotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFSU5URVJGQUNFKAotICAgICAgICAgICAgICAgICAgICBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKFRSQU5TTEVUX09VVFBVVF9JTlRFUkZBQ0UsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInNldEVuY29kaW5nIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKCIrU1RSSU5HX1NJRysiKVYiKSwgMikpOwotCi0gICAgICAgICAgICAgICAgLy8gSW52b2tlIG91dHB1dC5zZXRPbWl0WE1MRGVjbGFyYXRpb24odHJ1ZSkKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRIYW5kbGVyKCkpOwotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChJQ09OU1RfMSk7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0UoCi0gICAgICAgICAgICAgICAgICAgIGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoVFJBTlNMRVRfT1VUUFVUX0lOVEVSRkFDRSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAic2V0T21pdFhNTERlY2xhcmF0aW9uIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKFopViIpLCAyKSk7Ci0KLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRIYW5kbGVyKCkpOwotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFSU5URVJGQUNFKAotICAgICAgICAgICAgICAgICAgICBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKFRSQU5TTEVUX09VVFBVVF9JTlRFUkZBQ0UsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInN0YXJ0RG9jdW1lbnQiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoKVYiKSwgMSkpOwotCi0gICAgICAgICAgICAgICAgLy8gSW5saW5lIHRyYW5zbGF0aW9uIG9mIGNvbnRlbnRzCi0gICAgICAgICAgICAgICAgdHJhbnNsYXRlQ29udGVudHMoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0KLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRIYW5kbGVyKCkpOwotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFSU5URVJGQUNFKAotICAgICAgICAgICAgICAgICAgICBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKFRSQU5TTEVUX09VVFBVVF9JTlRFUkZBQ0UsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImVuZERvY3VtZW50IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKClWIiksIDEpKTsKLQotICAgICAgICAgICAgICAgIC8vIENhbGwgdG9TdHJpbmcoKSBvbiBTdHJpbmdXcml0ZXIKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRVZJUlRVQUwoCi0gICAgICAgICAgICAgICAgICAgIGNwZy5hZGRNZXRob2RyZWYoU1RSSU5HX1dSSVRFUiwgInRvU3RyaW5nIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKCkiICsgU1RSSU5HX1NJRykpKTsKLQotICAgICAgICAgICAgICAgIC8vIFJlc3RvcmUgb2xkIG91dHB1dCBoYW5kbGVyCi0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKFNXQVApOwotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4uc3RvcmVIYW5kbGVyKCkpOwotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBTZW5kIHRoZSByZXN1bHRpbmcgc3RyaW5nIHRvIHRoZSBtZXNzYWdlIGhhbmRsaW5nIG1ldGhvZAotICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRVZJUlRVQUwoY3BnLmFkZE1ldGhvZHJlZihUUkFOU0xFVF9DTEFTUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImRpc3BsYXlNZXNzYWdlIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIigiK1NUUklOR19TSUcrIilWIikpKTsKLQotICAgICAgICAvLyBJZiAndGVybWluYXRlJyBhdHRyaWJ1dGUgaXMgc2V0IHRvICd5ZXMnOiBJbnN0YW5jaWF0ZSBhCi0gICAgICAgIC8vIFJ1blRpbWVFeGNlcHRpb24sIGJ1dCBpdCBvbiB0aGUgc3RhY2sgYW5kIHRocm93IGFuIGV4Y2VwdGlvbgotICAgICAgICBpZiAoX3Rlcm1pbmF0ZSA9PSB0cnVlKSB7Ci0gICAgICAgICAgICAvLyBDcmVhdGUgYSBuZXcgaW5zdGFuY2Ugb2YgUnVuVGltZUV4Y2VwdGlvbgotICAgICAgICAgICAgZmluYWwgaW50IGVpbml0ID0gY3BnLmFkZE1ldGhvZHJlZigiamF2YS5sYW5nLlJ1bnRpbWVFeGNlcHRpb24iLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiPGluaXQ+IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIihMamF2YS9sYW5nL1N0cmluZzspViIpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBORVcoY3BnLmFkZENsYXNzKCJqYXZhLmxhbmcuUnVudGltZUV4Y2VwdGlvbiIpKSk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQoRFVQKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsIlRlcm1pbmF0aW9uIGZvcmNlZCBieSBhbiAiICsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInhzbDptZXNzYWdlIGluc3RydWN0aW9uIikpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VTUEVDSUFMKGVpbml0KSk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQoQVRIUk9XKTsKLSAgICAgICAgfQotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9Nb2RlLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL01vZGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggN2ZiODZiZS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL01vZGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE1MTggKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAxNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqLwotLyoKLSAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQotICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCi0gKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCi0gKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAotICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKLSAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBNb2RlLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTkgMDU6MTg6MTEgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5CcmFuY2hIYW5kbGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5Db25zdGFudFBvb2xHZW47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5EVVA7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5HT1RPX1c7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JRkxUOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSUxPQUQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JTlZPS0VJTlRFUkZBQ0U7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JTlZPS0VWSVJUVUFMOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSVNUT1JFOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW5zdHJ1Y3Rpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JbnN0cnVjdGlvbkhhbmRsZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uTGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkxvY2FsVmFyaWFibGVHZW47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5TV0lUQ0g7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5UYXJnZXRMb3N0RXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLnV0aWwuSW5zdHJ1Y3Rpb25GaW5kZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLkRPTTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5DbGFzc0dlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5NZXRob2RHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuTmFtZWRNZXRob2RHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVXRpbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5BeGlzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTTsKLWltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247Ci1pbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7Ci1pbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOwotaW1wb3J0IGphdmEudXRpbC5NYXA7Ci1pbXBvcnQgamF2YS51dGlsLlNldDsKLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi0vKioKLSAqIE1vZGUgZ2F0aGVycyBhbGwgdGhlIHRlbXBsYXRlcyBiZWxvbmdpbmcgdG8gYSBnaXZlbiBtb2RlOwotICogaXQgaXMgcmVzcG9uc2libGUgZm9yIGdlbmVyYXRpbmcgYW4gYXBwcm9wcmlhdGUKLSAqIGFwcGx5VGVtcGxhdGVzICsgKG1vZGUgbmFtZSkgbWV0aG9kIGluIHRoZSB0cmFuc2xldC4KLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICogQGF1dGhvciBFcndpbiBCb2x3aWR0IDxlamJAa2xvbXAub3JnPgotICogQGF1dGhvciBHLiBUb2RkIE1pbGxlcgotICovCi1maW5hbCBjbGFzcyBNb2RlIGltcGxlbWVudHMgQ29uc3RhbnRzIHsKLQotICAgIC8qKgotICAgICAqIFRoZSBuYW1lIG9mIHRoaXMgbW9kZSBhcyBkZWZpbmVkIGluIHRoZSBzdHlsZXNoZWV0LgotICAgICAqLwotICAgIHByaXZhdGUgZmluYWwgUU5hbWUgX25hbWU7Ci0KLSAgICAvKioKLSAgICAgKiBBIHJlZmVyZW5jZSB0byB0aGUgc3R5bGVzaGVldCBvYmplY3QgdGhhdCBvd25zIHRoaXMgbW9kZS4KLSAgICAgKi8KLSAgICBwcml2YXRlIGZpbmFsIFN0eWxlc2hlZXQgX3N0eWxlc2hlZXQ7Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgbmFtZSBvZiB0aGUgbWV0aG9kIGluIHdoaWNoIHRoaXMgbW9kZSBpcyBjb21waWxlZC4KLSAgICAgKi8KLSAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBfbWV0aG9kTmFtZTsKLQotICAgIC8qKgotICAgICAqIEEgdmVjdG9yIG9mIGFsbCB0aGUgdGVtcGxhdGVzIGluIHRoaXMgbW9kZS4KLSAgICAgKi8KLSAgICBwcml2YXRlIFZlY3RvciBfdGVtcGxhdGVzOwotCi0gICAgLyoqCi0gICAgICogR3JvdXAgZm9yIHBhdHRlcm5zIHdpdGggbm9kZSgpLXR5cGUga2VybmVsIGFuZCBjaGlsZCBheGlzLgotICAgICAqLwotICAgIHByaXZhdGUgVmVjdG9yIF9jaGlsZE5vZGVHcm91cCA9IG51bGw7Ci0KLSAgICAvKioKLSAgICAgKiBUZXN0IHNlcXVlbmNlIGZvciBwYXR0ZXJucyB3aXRoIG5vZGUoKS10eXBlIGtlcm5lbCBhbmQgY2hpbGQgYXhpcy4KLSAgICAgKi8KLSAgICBwcml2YXRlIFRlc3RTZXEgX2NoaWxkTm9kZVRlc3RTZXEgPSBudWxsOwotCi0gICAgLyoqCi0gICAgICogR3JvdXAgZm9yIHBhdHRlcm5zIHdpdGggbm9kZSgpLXR5cGUga2VybmVsIGFuZCBhdHRyaWJ1dGUgYXhpcy4KLSAgICAgKi8KLSAgICBwcml2YXRlIFZlY3RvciBfYXR0cmliTm9kZUdyb3VwID0gbnVsbDsKLQotICAgIC8qKgotICAgICAqIFRlc3Qgc2VxdWVuY2UgZm9yIHBhdHRlcm5zIHdpdGggbm9kZSgpLXR5cGUga2VybmVsIGFuZCBhdHRyaWJ1dGUgYXhpcy4KLSAgICAgKi8KLSAgICBwcml2YXRlIFRlc3RTZXEgX2F0dHJpYk5vZGVUZXN0U2VxID0gbnVsbDsKLQotICAgIC8qKgotICAgICAqIEdyb3VwIGZvciBwYXR0ZXJucyB3aXRoIGlkKCkgb3Iga2V5KCktdHlwZSBrZXJuZWwuCi0gICAgICovCi0gICAgcHJpdmF0ZSBWZWN0b3IgX2lkeEdyb3VwID0gbnVsbDsKLQotICAgIC8qKgotICAgICAqIFRlc3Qgc2VxdWVuY2UgZm9yIHBhdHRlcm5zIHdpdGggaWQoKSBvciBrZXkoKS10eXBlIGtlcm5lbC4KLSAgICAgKi8KLSAgICBwcml2YXRlIFRlc3RTZXEgX2lkeFRlc3RTZXEgPSBudWxsOwotCi0gICAgLyoqCi0gICAgICogR3JvdXAgZm9yIHBhdHRlcm5zIHdpdGggYW55IG90aGVyIGtlcm5lbCB0eXBlLgotICAgICAqLwotICAgIHByaXZhdGUgVmVjdG9yW10gX3BhdHRlcm5Hcm91cHM7Ci0KLSAgICAvKioKLSAgICAgKiBUZXN0IHNlcXVlbmNlIGZvciBwYXR0ZXJucyB3aXRoIGFueSBvdGhlciBrZXJuZWwgdHlwZS4KLSAgICAgKi8KLSAgICBwcml2YXRlIFRlc3RTZXFbXSBfdGVzdFNlcTsKLQotCi0gICAgLyoqCi0gICAgICogQSBtYXBwaW5nIGJldHdlZW4gdGVtcGxhdGVzIGFuZCB0ZXN0IHNlcXVlbmNlcy4KLSAgICAgKi8KLSAgICBwcml2YXRlIE1hcDxUZW1wbGF0ZSwgT2JqZWN0PiBfbmVlZGVkVGVtcGxhdGVzID0gbmV3IEhhc2hNYXA8PigpOwotCi0gICAgLyoqCi0gICAgICogQSBtYXBwaW5nIGJldHdlZW4gbmFtZWQgdGVtcGxhdGVzIGFuZCBNb2RlIG9iamVjdHMuCi0gICAgICovCi0gICAgcHJpdmF0ZSBNYXA8VGVtcGxhdGUsIE1vZGU+IF9uYW1lZFRlbXBsYXRlcyA9IG5ldyBIYXNoTWFwPD4oKTsKLQotICAgIC8qKgotICAgICAqIEEgbWFwcGluZyBiZXR3ZWVuIHRlbXBsYXRlcyBhbmQgaW5zdHJ1Y3Rpb24gaGFuZGxlcy4KLSAgICAgKi8KLSAgICBwcml2YXRlIE1hcDxUZW1wbGF0ZSwgSW5zdHJ1Y3Rpb25IYW5kbGU+IF90ZW1wbGF0ZUlIcyA9IG5ldyBIYXNoTWFwPD4oKTsKLQotICAgIC8qKgotICAgICAqIEEgbWFwcGluZyBiZXR3ZWVuIHRlbXBsYXRlcyBhbmQgaW5zdHJ1Y3Rpb24gbGlzdHMuCi0gICAgICovCi0gICAgcHJpdmF0ZSBNYXA8VGVtcGxhdGUsIEluc3RydWN0aW9uTGlzdD4gX3RlbXBsYXRlSUxzID0gbmV3IEhhc2hNYXA8PigpOwotCi0gICAgLyoqCi0gICAgICogQSByZWZlcmVuY2UgdG8gdGhlIHBhdHRlcm4gbWF0Y2hpbmcgdGhlIHJvb3Qgbm9kZS4KLSAgICAgKi8KLSAgICBwcml2YXRlIExvY2F0aW9uUGF0aFBhdHRlcm4gX3Jvb3RQYXR0ZXJuID0gbnVsbDsKLQotICAgIC8qKgotICAgICAqIFN0b3JlcyByYW5nZXMgb2YgdGVtcGxhdGUgcHJlY2VuZGVuY2VzIGZvciB0aGUgY29tcGlsYXRpb24KLSAgICAgKiBvZiBhcHBseS1pbXBvcnRzLgotICAgICAqLwotICAgIHByaXZhdGUgTWFwPEludGVnZXIsIEludGVnZXI+IF9pbXBvcnRMZXZlbHMgPSBudWxsOwotCi0gICAgLyoqCi0gICAgICogQSBtYXBwaW5nIGJldHdlZW4ga2V5IG5hbWVzIGFuZCBrZXlzLgotICAgICAqLwotICAgIHByaXZhdGUgTWFwPFN0cmluZywgS2V5PiBfa2V5cyA9IG51bGw7Ci0KLSAgICAvKioKLSAgICAgKiBWYXJpYWJsZSBpbmRleCBmb3IgdGhlIGN1cnJlbnQgbm9kZSB1c2VkIGluIGNvZGUgZ2VuZXJhdGlvbi4KLSAgICAgKi8KLSAgICBwcml2YXRlIGludCBfY3VycmVudEluZGV4OwotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlcyBhIG5ldyBNb2RlLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgQSB0ZXh0dWFsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBtb2RlJ3MgUU5hbWUKLSAgICAgKiBAcGFyYW0gc3R5bGVzaGVldCBUaGUgU3R5bGVzaGVldCBpbiB3aGljaCB0aGUgbW9kZSBvY2N1cmVkCi0gICAgICogQHBhcmFtIHN1ZmZpeCBBIHN1ZmZpeCB0byBhcHBlbmQgdG8gdGhlIG1ldGhvZCBuYW1lIGZvciB0aGlzIG1vZGUKLSAgICAgKiAgICAgICAgICAgICAgIChub3JtYWxseSBhIHNlcXVlbmNlIG51bWJlciAtIHN0aWxsIGluIGEgU3RyaW5nKS4KLSAgICAgKi8KLSAgICBwdWJsaWMgTW9kZShRTmFtZSBuYW1lLCBTdHlsZXNoZWV0IHN0eWxlc2hlZXQsIFN0cmluZyBzdWZmaXgpIHsKLSAgICAgICAgX25hbWUgPSBuYW1lOwotICAgICAgICBfc3R5bGVzaGVldCA9IHN0eWxlc2hlZXQ7Ci0gICAgICAgIF9tZXRob2ROYW1lID0gQVBQTFlfVEVNUExBVEVTICsgc3VmZml4OwotICAgICAgICBfdGVtcGxhdGVzID0gbmV3IFZlY3RvcigpOwotICAgICAgICBfcGF0dGVybkdyb3VwcyA9IG5ldyBWZWN0b3JbMzJdOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhlIG1ldGhvZCAoX25vdF8gZnVuY3Rpb24pIHRoYXQgd2lsbCBiZQotICAgICAqIGNvbXBpbGVkIGZvciB0aGlzIG1vZGUuIE5vcm1hbGx5IHRha2VzIHRoZSBmb3JtICdhcHBseVRlbXBsYXRlcygpJwotICAgICAqIG9yICogJ2FwcGx5VGVtcGxhdGVzMigpJy4KLSAgICAgKgotICAgICAqIEByZXR1cm4gTWV0aG9kIG5hbWUgZm9yIHRoaXMgbW9kZQotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZnVuY3Rpb25OYW1lKCkgewotICAgICAgICByZXR1cm4gX21ldGhvZE5hbWU7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBmdW5jdGlvbk5hbWUoaW50IG1pbiwgaW50IG1heCkgewotICAgICAgICBpZiAoX2ltcG9ydExldmVscyA9PSBudWxsKSB7Ci0gICAgICAgICAgICBfaW1wb3J0TGV2ZWxzID0gbmV3IEhhc2hNYXA8PigpOwotICAgICAgICB9Ci0gICAgICAgIF9pbXBvcnRMZXZlbHMucHV0KG1heCwgbWluKTsKLSAgICAgICAgcmV0dXJuIF9tZXRob2ROYW1lICsgJ18nICsgbWF4OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNob3J0Y3V0IHRvIGdldCB0aGUgY2xhc3MgY29tcGlsZWQgZm9yIHRoaXMgbW9kZSAod2lsbCBiZSBpbmxpbmVkKS4KLSAgICAgKi8KLSAgICBwcml2YXRlIFN0cmluZyBnZXRDbGFzc05hbWUoKSB7Ci0gICAgICAgIHJldHVybiBfc3R5bGVzaGVldC5nZXRDbGFzc05hbWUoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3R5bGVzaGVldCBnZXRTdHlsZXNoZWV0KCkgewotICAgICAgICByZXR1cm4gX3N0eWxlc2hlZXQ7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgYWRkVGVtcGxhdGUoVGVtcGxhdGUgdGVtcGxhdGUpIHsKLSAgICAgICAgX3RlbXBsYXRlcy5hZGRFbGVtZW50KHRlbXBsYXRlKTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIFZlY3RvciBxdWlja3NvcnQoVmVjdG9yIHRlbXBsYXRlcywgaW50IHAsIGludCByKSB7Ci0gICAgICAgIGlmIChwIDwgcikgewotICAgICAgICAgICAgZmluYWwgaW50IHEgPSBwYXJ0aXRpb24odGVtcGxhdGVzLCBwLCByKTsKLSAgICAgICAgICAgIHF1aWNrc29ydCh0ZW1wbGF0ZXMsIHAsIHEpOwotICAgICAgICAgICAgcXVpY2tzb3J0KHRlbXBsYXRlcywgcSArIDEsIHIpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiB0ZW1wbGF0ZXM7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBpbnQgcGFydGl0aW9uKFZlY3RvciB0ZW1wbGF0ZXMsIGludCBwLCBpbnQgcikgewotICAgICAgICBmaW5hbCBUZW1wbGF0ZSB4ID0gKFRlbXBsYXRlKXRlbXBsYXRlcy5lbGVtZW50QXQocCk7Ci0gICAgICAgIGludCBpID0gcCAtIDE7Ci0gICAgICAgIGludCBqID0gciArIDE7Ci0gICAgICAgIHdoaWxlICh0cnVlKSB7Ci0gICAgICAgICAgICB3aGlsZSAoeC5jb21wYXJlVG8oKFRlbXBsYXRlKXRlbXBsYXRlcy5lbGVtZW50QXQoLS1qKSkgPiAwKTsKLSAgICAgICAgICAgIHdoaWxlICh4LmNvbXBhcmVUbygoVGVtcGxhdGUpdGVtcGxhdGVzLmVsZW1lbnRBdCgrK2kpKSA8IDApOwotICAgICAgICAgICAgaWYgKGkgPCBqKSB7Ci0gICAgICAgICAgICAgICAgdGVtcGxhdGVzLnNldChqLCB0ZW1wbGF0ZXMuc2V0KGksIHRlbXBsYXRlcy5lbGVtZW50QXQoaikpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIHJldHVybiBqOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUHJvY2VzcyBhbGwgdGhlIHRlc3QgcGF0dGVybnMgaW4gdGhpcyBtb2RlCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcHJvY2Vzc1BhdHRlcm5zKE1hcDxTdHJpbmcsIEtleT4ga2V5cykgewotICAgICAgICBfa2V5cyA9IGtleXM7Ci0KLS8qCi1TeXN0ZW0ub3V0LnByaW50bG4oIkJlZm9yZSBTb3J0ICIgKyBfbmFtZSk7Ci1mb3IgKGludCBpID0gMDsgaSA8IF90ZW1wbGF0ZXMuc2l6ZSgpOyBpKyspIHsKLSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIm5hbWUgPSAiICsgKChUZW1wbGF0ZSlfdGVtcGxhdGVzLmVsZW1lbnRBdChpKSkuZ2V0TmFtZSgpKTsKLSAgICBTeXN0ZW0ub3V0LnByaW50bG4oInBhdHRlcm4gPSAiICsgKChUZW1wbGF0ZSlfdGVtcGxhdGVzLmVsZW1lbnRBdChpKSkuZ2V0UGF0dGVybigpKTsKLSAgICBTeXN0ZW0ub3V0LnByaW50bG4oInByaW9yaXR5ID0gIiArICgoVGVtcGxhdGUpX3RlbXBsYXRlcy5lbGVtZW50QXQoaSkpLmdldFByaW9yaXR5KCkpOwotICAgIFN5c3RlbS5vdXQucHJpbnRsbigicG9zaXRpb24gPSAiICsgKChUZW1wbGF0ZSlfdGVtcGxhdGVzLmVsZW1lbnRBdChpKSkuZ2V0UG9zaXRpb24oKSk7Ci19Ci0qLwotCi0gICAgICAgIF90ZW1wbGF0ZXMgPSBxdWlja3NvcnQoX3RlbXBsYXRlcywgMCwgX3RlbXBsYXRlcy5zaXplKCkgLSAxKTsKLQotLyoKLVN5c3RlbS5vdXQucHJpbnRsbigiXG4gQWZ0ZXIgU29ydCAiICsgX25hbWUpOwotZm9yIChpbnQgaSA9IDA7IGkgPCBfdGVtcGxhdGVzLnNpemUoKTsgaSsrKSB7Ci0gICAgU3lzdGVtLm91dC5wcmludGxuKCJuYW1lID0gIiArICgoVGVtcGxhdGUpX3RlbXBsYXRlcy5lbGVtZW50QXQoaSkpLmdldE5hbWUoKSk7Ci0gICAgU3lzdGVtLm91dC5wcmludGxuKCJwYXR0ZXJuID0gIiArICgoVGVtcGxhdGUpX3RlbXBsYXRlcy5lbGVtZW50QXQoaSkpLmdldFBhdHRlcm4oKSk7Ci0gICAgU3lzdGVtLm91dC5wcmludGxuKCJwcmlvcml0eSA9ICIgKyAoKFRlbXBsYXRlKV90ZW1wbGF0ZXMuZWxlbWVudEF0KGkpKS5nZXRQcmlvcml0eSgpKTsKLSAgICBTeXN0ZW0ub3V0LnByaW50bG4oInBvc2l0aW9uID0gIiArICgoVGVtcGxhdGUpX3RlbXBsYXRlcy5lbGVtZW50QXQoaSkpLmdldFBvc2l0aW9uKCkpOwotfQotKi8KLQotICAgICAgICAvLyBUcmF2ZXJzZSBhbGwgdGVtcGxhdGVzCi0gICAgICAgIGZpbmFsIEVudW1lcmF0aW9uIHRlbXBsYXRlcyA9IF90ZW1wbGF0ZXMuZWxlbWVudHMoKTsKLSAgICAgICAgd2hpbGUgKHRlbXBsYXRlcy5oYXNNb3JlRWxlbWVudHMoKSkgewotICAgICAgICAgICAgLy8gR2V0IHRoZSBuZXh0IHRlbXBsYXRlCi0gICAgICAgICAgICBmaW5hbCBUZW1wbGF0ZSB0ZW1wbGF0ZSA9IChUZW1wbGF0ZSl0ZW1wbGF0ZXMubmV4dEVsZW1lbnQoKTsKLQotICAgICAgICAgICAgLyoKLSAgICAgICAgICAgICAqIEFkZCB0aGlzIHRlbXBsYXRlIHRvIGEgdGFibGUgb2YgbmFtZWQgdGVtcGxhdGVzIGlmIGl0IGhhcyBhIG5hbWUuCi0gICAgICAgICAgICAgKiBJZiB0aGVyZSBhcmUgbXVsdGlwbGUgdGVtcGxhdGVzIHdpdGggdGhlIHNhbWUgbmFtZSwgYWxsIGJ1dCBvbmUKLSAgICAgICAgICAgICAqICh0aGUgb25lIHdpdGggaGlnaGVzdCBwcmlvcml0eSkgd2lsbCBiZSBkaXNhYmxlZC4KLSAgICAgICAgICAgICAqLwotICAgICAgICAgICAgaWYgKHRlbXBsYXRlLmlzTmFtZWQoKSAmJiAhdGVtcGxhdGUuZGlzYWJsZWQoKSkgewotICAgICAgICAgICAgICAgIF9uYW1lZFRlbXBsYXRlcy5wdXQodGVtcGxhdGUsIHRoaXMpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBBZGQgdGhpcyB0ZW1wbGF0ZSB0byBhIHRlc3Qgc2VxdWVuY2UgaWYgaXQgaGFzIGEgcGF0dGVybgotICAgICAgICAgICAgZmluYWwgUGF0dGVybiBwYXR0ZXJuID0gdGVtcGxhdGUuZ2V0UGF0dGVybigpOwotICAgICAgICAgICAgaWYgKHBhdHRlcm4gIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZsYXR0ZW5BbHRlcm5hdGl2ZShwYXR0ZXJuLCB0ZW1wbGF0ZSwga2V5cyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcHJlcGFyZVRlc3RTZXF1ZW5jZXMoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCB3aWxsIGJyZWFrIHVwIGFsdGVybmF0aXZlIHBhdHRlcm5zIChpZS4gdW5pb25zIG9mIHBhdHRlcm5zLAotICAgICAqIHN1Y2ggYXMgbWF0Y2g9IkEvQiB8IEMvQiIpIGFuZCBhZGQgdGhlIGJhc2ljIHBhdHRlcm5zIHRvIHRoZWlyCi0gICAgICogcmVzcGVjdGl2ZSBwYXR0ZXJuIGdyb3Vwcy4KLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgZmxhdHRlbkFsdGVybmF0aXZlKFBhdHRlcm4gcGF0dGVybiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRlbXBsYXRlIHRlbXBsYXRlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWFwPFN0cmluZywgS2V5PiBrZXlzKSB7Ci0gICAgICAgIC8vIFBhdHRlcm5zIG9uIHR5cGUgaWQoKSBhbmQga2V5KCkgYXJlIHNwZWNpYWwgc2luY2UgdGhleSBkbyBub3QgaGF2ZQotICAgICAgICAvLyBhbnkga2VybmVsIG5vZGUgdHlwZSAoaXQgY2FuIGJlIGFueXRoaW5nIGFzIGxvbmcgYXMgdGhlIG5vZGUgaXMgaW4KLSAgICAgICAgLy8gdGhlIGlkJ3Mgb3Iga2V5J3MgaW5kZXgpLgotICAgICAgICBpZiAocGF0dGVybiBpbnN0YW5jZW9mIElkS2V5UGF0dGVybikgewotICAgICAgICAgICAgZmluYWwgSWRLZXlQYXR0ZXJuIGlka2V5ID0gKElkS2V5UGF0dGVybilwYXR0ZXJuOwotICAgICAgICAgICAgaWRrZXkuc2V0VGVtcGxhdGUodGVtcGxhdGUpOwotICAgICAgICAgICAgaWYgKF9pZHhHcm91cCA9PSBudWxsKSBfaWR4R3JvdXAgPSBuZXcgVmVjdG9yKCk7Ci0gICAgICAgICAgICBfaWR4R3JvdXAuYWRkKHBhdHRlcm4pOwotICAgICAgICB9Ci0gICAgICAgIC8vIEFsdGVybmF0aXZlIHBhdHRlcm5zIGFyZSBicm9rZW4gdXAgYW5kIHJlLXByb2Nlc3NlZCByZWN1cnNpdmVseQotICAgICAgICBlbHNlIGlmIChwYXR0ZXJuIGluc3RhbmNlb2YgQWx0ZXJuYXRpdmVQYXR0ZXJuKSB7Ci0gICAgICAgICAgICBmaW5hbCBBbHRlcm5hdGl2ZVBhdHRlcm4gYWx0ID0gKEFsdGVybmF0aXZlUGF0dGVybilwYXR0ZXJuOwotICAgICAgICAgICAgZmxhdHRlbkFsdGVybmF0aXZlKGFsdC5nZXRMZWZ0KCksIHRlbXBsYXRlLCBrZXlzKTsKLSAgICAgICAgICAgIGZsYXR0ZW5BbHRlcm5hdGl2ZShhbHQuZ2V0UmlnaHQoKSwgdGVtcGxhdGUsIGtleXMpOwotICAgICAgICB9Ci0gICAgICAgIC8vIEZpbmFsbHkgd2UgaGF2ZSBhIHBhdHRlcm4gdGhhdCBjYW4gYmUgYWRkZWQgdG8gYSB0ZXN0IHNlcXVlbmNlIQotICAgICAgICBlbHNlIGlmIChwYXR0ZXJuIGluc3RhbmNlb2YgTG9jYXRpb25QYXRoUGF0dGVybikgewotICAgICAgICAgICAgZmluYWwgTG9jYXRpb25QYXRoUGF0dGVybiBscHAgPSAoTG9jYXRpb25QYXRoUGF0dGVybilwYXR0ZXJuOwotICAgICAgICAgICAgbHBwLnNldFRlbXBsYXRlKHRlbXBsYXRlKTsKLSAgICAgICAgICAgIGFkZFBhdHRlcm5Ub0dyb3VwKGxwcCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHcm91cCBwYXR0ZXJucyBieSBOb2RlVGVzdHMgb2YgdGhlaXIgbGFzdCBTdGVwCi0gICAgICogS2VlcCB0aGVtIHNvcnRlZCBieSBwcmlvcml0eSB3aXRoaW4gZ3JvdXAKLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgYWRkUGF0dGVyblRvR3JvdXAoZmluYWwgTG9jYXRpb25QYXRoUGF0dGVybiBscHApIHsKLSAgICAgICAgLy8gaWQoKSBhbmQga2V5KCktdHlwZSBwYXR0ZXJucyBkbyBub3QgaGF2ZSBhIGtlcm5lbCB0eXBlCi0gICAgICAgIGlmIChscHAgaW5zdGFuY2VvZiBJZEtleVBhdHRlcm4pIHsKLSAgICAgICAgICAgIGFkZFBhdHRlcm4oLTEsIGxwcCk7Ci0gICAgICAgIH0KLSAgICAgICAgLy8gT3RoZXJ3aXNlIGdldCB0aGUga2VybmVsIHBhdHRlcm4gZnJvbSB0aGUgTFBQCi0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgLy8ga2VybmVsIHBhdHRlcm4gaXMgdGhlIGxhc3QgKG1heWJlIG9ubHkpIFN0ZXAKLSAgICAgICAgICAgIGZpbmFsIFN0ZXBQYXR0ZXJuIGtlcm5lbCA9IGxwcC5nZXRLZXJuZWxQYXR0ZXJuKCk7Ci0gICAgICAgICAgICBpZiAoa2VybmVsICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBhZGRQYXR0ZXJuKGtlcm5lbC5nZXROb2RlVHlwZSgpLCBscHApOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoX3Jvb3RQYXR0ZXJuID09IG51bGwgfHwKLSAgICAgICAgICAgICAgICAgICAgIGxwcC5ub1NtYWxsZXJUaGFuKF9yb290UGF0dGVybikpIHsKLSAgICAgICAgICAgICAgICBfcm9vdFBhdHRlcm4gPSBscHA7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBZGRzIGEgcGF0dGVybiB0byBhIHBhdHRlcm4gZ3JvdXAKLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgYWRkUGF0dGVybihpbnQga2VybmVsVHlwZSwgTG9jYXRpb25QYXRoUGF0dGVybiBwYXR0ZXJuKSB7Ci0gICAgICAgIC8vIE1ha2Ugc3VyZSB0aGUgYXJyYXkgb2YgcGF0dGVybiBncm91cHMgaXMgbG9uZyBlbm91Z2gKLSAgICAgICAgZmluYWwgaW50IG9sZExlbmd0aCA9IF9wYXR0ZXJuR3JvdXBzLmxlbmd0aDsKLSAgICAgICAgaWYgKGtlcm5lbFR5cGUgPj0gb2xkTGVuZ3RoKSB7Ci0gICAgICAgICAgICBWZWN0b3JbXSBuZXdHcm91cHMgPSBuZXcgVmVjdG9yW2tlcm5lbFR5cGUgKiAyXTsKLSAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoX3BhdHRlcm5Hcm91cHMsIDAsIG5ld0dyb3VwcywgMCwgb2xkTGVuZ3RoKTsKLSAgICAgICAgICAgIF9wYXR0ZXJuR3JvdXBzID0gbmV3R3JvdXBzOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gRmluZCB0aGUgdmVjdG9yIHRvIHB1dCB0aGlzIHBhdHRlcm4gaW50bwotICAgICAgICBWZWN0b3IgcGF0dGVybnM7Ci0KLSAgICAgICAgaWYgKGtlcm5lbFR5cGUgPT0gRE9NLk5PX1RZUEUpIHsKLSAgICAgICAgICAgIGlmIChwYXR0ZXJuLmdldEF4aXMoKSA9PSBBeGlzLkFUVFJJQlVURSkgewotICAgICAgICAgICAgICAgIHBhdHRlcm5zID0gKF9hdHRyaWJOb2RlR3JvdXAgPT0gbnVsbCkgPwotICAgICAgICAgICAgICAgICAgICAoX2F0dHJpYk5vZGVHcm91cCA9IG5ldyBWZWN0b3IoMikpIDogX2F0dHJpYk5vZGVHcm91cDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIHBhdHRlcm5zID0gKF9jaGlsZE5vZGVHcm91cCA9PSBudWxsKSA/Ci0gICAgICAgICAgICAgICAgICAgIChfY2hpbGROb2RlR3JvdXAgPSBuZXcgVmVjdG9yKDIpKSA6IF9jaGlsZE5vZGVHcm91cDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHBhdHRlcm5zID0gKF9wYXR0ZXJuR3JvdXBzW2tlcm5lbFR5cGVdID09IG51bGwpID8KLSAgICAgICAgICAgICAgICAoX3BhdHRlcm5Hcm91cHNba2VybmVsVHlwZV0gPSBuZXcgVmVjdG9yKDIpKSA6Ci0gICAgICAgICAgICAgICAgX3BhdHRlcm5Hcm91cHNba2VybmVsVHlwZV07Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAocGF0dGVybnMuc2l6ZSgpID09IDApIHsKLSAgICAgICAgICAgIHBhdHRlcm5zLmFkZEVsZW1lbnQocGF0dGVybik7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBib29sZWFuIGluc2VydGVkID0gZmFsc2U7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhdHRlcm5zLnNpemUoKTsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgZmluYWwgTG9jYXRpb25QYXRoUGF0dGVybiBscHBUb0NvbXBhcmUgPQotICAgICAgICAgICAgICAgICAgICAoTG9jYXRpb25QYXRoUGF0dGVybilwYXR0ZXJucy5lbGVtZW50QXQoaSk7Ci0KLSAgICAgICAgICAgICAgICBpZiAocGF0dGVybi5ub1NtYWxsZXJUaGFuKGxwcFRvQ29tcGFyZSkpIHsKLSAgICAgICAgICAgICAgICAgICAgaW5zZXJ0ZWQgPSB0cnVlOwotICAgICAgICAgICAgICAgICAgICBwYXR0ZXJucy5pbnNlcnRFbGVtZW50QXQocGF0dGVybiwgaSk7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChpbnNlcnRlZCA9PSBmYWxzZSkgewotICAgICAgICAgICAgICAgIHBhdHRlcm5zLmFkZEVsZW1lbnQocGF0dGVybik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb21wbGV0ZSB0ZXN0IHNlcXVlbmNlcyBvZiBhIGdpdmVuIHR5cGUgYnkgYWRkaW5nIGFsbCBwYXR0ZXJucwotICAgICAqIGZyb20gYSBnaXZlbiBncm91cC4KLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgY29tcGxldGVUZXN0U2VxdWVuY2VzKGludCBub2RlVHlwZSwgVmVjdG9yIHBhdHRlcm5zKSB7Ci0gICAgICAgIGlmIChwYXR0ZXJucyAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAoX3BhdHRlcm5Hcm91cHNbbm9kZVR5cGVdID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBfcGF0dGVybkdyb3Vwc1tub2RlVHlwZV0gPSBwYXR0ZXJuczsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIGZpbmFsIGludCBtID0gcGF0dGVybnMuc2l6ZSgpOwotICAgICAgICAgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgbTsgaisrKSB7Ci0gICAgICAgICAgICAgICAgICAgIGFkZFBhdHRlcm4obm9kZVR5cGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAoTG9jYXRpb25QYXRoUGF0dGVybikgcGF0dGVybnMuZWxlbWVudEF0KGopKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBCdWlsZCB0ZXN0IHNlcXVlbmNlcy4gVGhlIGZpcnN0IHN0ZXAgaXMgdG8gY29tcGxldGUgdGhlIHRlc3Qgc2VxdWVuY2VzCi0gICAgICogYnkgaW5jbHVkaW5nIHBhdHRlcm5zIG9mICIqIiBhbmQgIm5vZGUoKSIga2VybmVsIHRvIGFsbCBlbGVtZW50IHRlc3QKLSAgICAgKiBzZXF1ZW5jZXMsIGFuZCBvZiAiQCoiIHRvIGFsbCBhdHRyaWJ1dGUgdGVzdCBzZXF1ZW5jZXMuCi0gICAgICovCi0gICAgcHJpdmF0ZSB2b2lkIHByZXBhcmVUZXN0U2VxdWVuY2VzKCkgewotICAgICAgICBmaW5hbCBWZWN0b3Igc3Rhckdyb3VwID0gX3BhdHRlcm5Hcm91cHNbRFRNLkVMRU1FTlRfTk9ERV07Ci0gICAgICAgIGZpbmFsIFZlY3RvciBhdFN0YXJHcm91cCA9IF9wYXR0ZXJuR3JvdXBzW0RUTS5BVFRSSUJVVEVfTk9ERV07Ci0KLSAgICAgICAgLy8gQ29tcGxldGUgdGVzdCBzZXF1ZW5jZSBmb3IgInRleHQoKSIgd2l0aCAiY2hpbGQ6Om5vZGUoKSIKLSAgICAgICAgY29tcGxldGVUZXN0U2VxdWVuY2VzKERUTS5URVhUX05PREUsIF9jaGlsZE5vZGVHcm91cCk7Ci0KLSAgICAgICAgLy8gQ29tcGxldGUgdGVzdCBzZXF1ZW5jZSBmb3IgIioiIHdpdGggImNoaWxkOjpub2RlKCkiCi0gICAgICAgIGNvbXBsZXRlVGVzdFNlcXVlbmNlcyhEVE0uRUxFTUVOVF9OT0RFLCBfY2hpbGROb2RlR3JvdXApOwotCi0gICAgICAgIC8vIENvbXBsZXRlIHRlc3Qgc2VxdWVuY2UgZm9yICJwaSgpIiB3aXRoICJjaGlsZDo6bm9kZSgpIgotICAgICAgICBjb21wbGV0ZVRlc3RTZXF1ZW5jZXMoRFRNLlBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERSwgX2NoaWxkTm9kZUdyb3VwKTsKLQotICAgICAgICAvLyBDb21wbGV0ZSB0ZXN0IHNlcXVlbmNlIGZvciAiY29tbWVudCgpIiB3aXRoICJjaGlsZDo6bm9kZSgpIgotICAgICAgICBjb21wbGV0ZVRlc3RTZXF1ZW5jZXMoRFRNLkNPTU1FTlRfTk9ERSwgX2NoaWxkTm9kZUdyb3VwKTsKLQotICAgICAgICAvLyBDb21wbGV0ZSB0ZXN0IHNlcXVlbmNlIGZvciAiQCoiIHdpdGggImF0dHJpYnV0ZTo6bm9kZSgpIgotICAgICAgICBjb21wbGV0ZVRlc3RTZXF1ZW5jZXMoRFRNLkFUVFJJQlVURV9OT0RFLCBfYXR0cmliTm9kZUdyb3VwKTsKLQotICAgICAgICBmaW5hbCBWZWN0b3IgbmFtZXMgPSBfc3R5bGVzaGVldC5nZXRYU0xUQygpLmdldE5hbWVzSW5kZXgoKTsKLSAgICAgICAgaWYgKHN0YXJHcm91cCAhPSBudWxsIHx8IGF0U3Rhckdyb3VwICE9IG51bGwgfHwKLSAgICAgICAgICAgIF9jaGlsZE5vZGVHcm91cCAhPSBudWxsIHx8IF9hdHRyaWJOb2RlR3JvdXAgIT0gbnVsbCkKLSAgICAgICAgewotICAgICAgICAgICAgZmluYWwgaW50IG4gPSBfcGF0dGVybkdyb3Vwcy5sZW5ndGg7Ci0KLSAgICAgICAgICAgIC8vIENvbXBsZXRlIHRlc3Qgc2VxdWVuY2UgZm9yIHVzZXItZGVmaW5lZCB0eXBlcwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IERUTS5OVFlQRVM7IGkgPCBuOyBpKyspIHsKLSAgICAgICAgICAgICAgICBpZiAoX3BhdHRlcm5Hcm91cHNbaV0gPT0gbnVsbCkgY29udGludWU7Ci0KLSAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgbmFtZSA9IChTdHJpbmcpIG5hbWVzLmVsZW1lbnRBdChpIC0gRFRNLk5UWVBFUyk7Ci0KLSAgICAgICAgICAgICAgICBpZiAoaXNBdHRyaWJ1dGVOYW1lKG5hbWUpKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIElmIGFuIGF0dHJpYnV0ZSB0aGVuIGNvcHkgIkAqIiB0byBpdHMgdGVzdCBzZXF1ZW5jZQotICAgICAgICAgICAgICAgICAgICBjb21wbGV0ZVRlc3RTZXF1ZW5jZXMoaSwgYXRTdGFyR3JvdXApOwotCi0gICAgICAgICAgICAgICAgICAgIC8vIEFuZCBhbHNvIGNvcHkgImF0dHJpYnV0ZTo6bm9kZSgpIiB0byBpdHMgdGVzdCBzZXF1ZW5jZQotICAgICAgICAgICAgICAgICAgICBjb21wbGV0ZVRlc3RTZXF1ZW5jZXMoaSwgX2F0dHJpYk5vZGVHcm91cCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAvLyBJZiBhbiBlbGVtZW50IHRoZW4gY29weSAiKiIgdG8gaXRzIHRlc3Qgc2VxdWVuY2UKLSAgICAgICAgICAgICAgICAgICAgY29tcGxldGVUZXN0U2VxdWVuY2VzKGksIHN0YXJHcm91cCk7Ci0KLSAgICAgICAgICAgICAgICAgICAgLy8gQW5kIGFsc28gY29weSAiY2hpbGQ6Om5vZGUoKSIgdG8gaXRzIHRlc3Qgc2VxdWVuY2UKLSAgICAgICAgICAgICAgICAgICAgY29tcGxldGVUZXN0U2VxdWVuY2VzKGksIF9jaGlsZE5vZGVHcm91cCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgX3Rlc3RTZXEgPSBuZXcgVGVzdFNlcVtEVE0uTlRZUEVTICsgbmFtZXMuc2l6ZSgpXTsKLQotICAgICAgICBmaW5hbCBpbnQgbiA9IF9wYXR0ZXJuR3JvdXBzLmxlbmd0aDsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspIHsKLSAgICAgICAgICAgIGZpbmFsIFZlY3RvciBwYXR0ZXJucyA9IF9wYXR0ZXJuR3JvdXBzW2ldOwotICAgICAgICAgICAgaWYgKHBhdHRlcm5zICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmaW5hbCBUZXN0U2VxIHRlc3RTZXEgPSBuZXcgVGVzdFNlcShwYXR0ZXJucywgaSwgdGhpcyk7Ci0vLyBTeXN0ZW0ub3V0LnByaW50bG4oInRlc3RTZXFbIiArIGkgKyAiXSA9ICIgKyB0ZXN0U2VxKTsKLSAgICAgICAgICAgICAgICB0ZXN0U2VxLnJlZHVjZSgpOwotICAgICAgICAgICAgICAgIF90ZXN0U2VxW2ldID0gdGVzdFNlcTsKLSAgICAgICAgICAgICAgICB0ZXN0U2VxLmZpbmRUZW1wbGF0ZXMoX25lZWRlZFRlbXBsYXRlcyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoX2NoaWxkTm9kZUdyb3VwICE9IG51bGwgJiYgX2NoaWxkTm9kZUdyb3VwLnNpemUoKSA+IDApIHsKLSAgICAgICAgICAgIF9jaGlsZE5vZGVUZXN0U2VxID0gbmV3IFRlc3RTZXEoX2NoaWxkTm9kZUdyb3VwLCAtMSwgdGhpcyk7Ci0gICAgICAgICAgICBfY2hpbGROb2RlVGVzdFNlcS5yZWR1Y2UoKTsKLSAgICAgICAgICAgIF9jaGlsZE5vZGVUZXN0U2VxLmZpbmRUZW1wbGF0ZXMoX25lZWRlZFRlbXBsYXRlcyk7Ci0gICAgICAgIH0KLQotLyoKLSAgICAgICAgaWYgKF9hdHRyaWJOb2RlR3JvdXAgIT0gbnVsbCAmJiBfYXR0cmliTm9kZUdyb3VwLnNpemUoKSA+IDApIHsKLSAgICAgICAgICAgIF9hdHRyaWJOb2RlVGVzdFNlcSA9IG5ldyBUZXN0U2VxKF9hdHRyaWJOb2RlR3JvdXAsIC0xLCB0aGlzKTsKLSAgICAgICAgICAgIF9hdHRyaWJOb2RlVGVzdFNlcS5yZWR1Y2UoKTsKLSAgICAgICAgICAgIF9hdHRyaWJOb2RlVGVzdFNlcS5maW5kVGVtcGxhdGVzKF9uZWVkZWRUZW1wbGF0ZXMpOwotICAgICAgICB9Ci0qLwotCi0gICAgICAgIGlmIChfaWR4R3JvdXAgIT0gbnVsbCAmJiBfaWR4R3JvdXAuc2l6ZSgpID4gMCkgewotICAgICAgICAgICAgX2lkeFRlc3RTZXEgPSBuZXcgVGVzdFNlcShfaWR4R3JvdXAsIHRoaXMpOwotICAgICAgICAgICAgX2lkeFRlc3RTZXEucmVkdWNlKCk7Ci0gICAgICAgICAgICBfaWR4VGVzdFNlcS5maW5kVGVtcGxhdGVzKF9uZWVkZWRUZW1wbGF0ZXMpOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKF9yb290UGF0dGVybiAhPSBudWxsKSB7Ci0gICAgICAgICAgICAvLyBkb2Vzbid0IG1hdHRlciB3aGF0IGlzICdwdXQnLCBvbmx5IGtleSBtYXR0ZXJzCi0gICAgICAgICAgICBfbmVlZGVkVGVtcGxhdGVzLnB1dChfcm9vdFBhdHRlcm4uZ2V0VGVtcGxhdGUoKSwgdGhpcyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgY29tcGlsZU5hbWVkVGVtcGxhdGUoVGVtcGxhdGUgdGVtcGxhdGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuKSB7Ci0gICAgICAgIGZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbmV3IEluc3RydWN0aW9uTGlzdCgpOwotICAgICAgICBTdHJpbmcgbWV0aG9kTmFtZSA9IFV0aWwuZXNjYXBlKHRlbXBsYXRlLmdldE5hbWUoKS50b1N0cmluZygpKTsKLQotICAgICAgICBpbnQgbnVtUGFyYW1zID0gMDsKLSAgICAgICAgaWYgKHRlbXBsYXRlLmlzU2ltcGxlTmFtZWRUZW1wbGF0ZSgpKSB7Ci0gICAgICAgICAgICBWZWN0b3IgcGFyYW1ldGVycyA9IHRlbXBsYXRlLmdldFBhcmFtZXRlcnMoKTsKLSAgICAgICAgICAgIG51bVBhcmFtcyA9IHBhcmFtZXRlcnMuc2l6ZSgpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gSW5pdGlhbGl6ZSB0aGUgdHlwZXMgYW5kIG5hbWVzIGFycmF5cyBmb3IgdGhlIE5hbWVkTWV0aG9kR2VuZXJhdG9yLgotICAgICAgICBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlR5cGVbXSB0eXBlcyA9Ci0gICAgICAgICAgICBuZXcgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5UeXBlWzQgKyBudW1QYXJhbXNdOwotICAgICAgICBTdHJpbmdbXSBuYW1lcyA9IG5ldyBTdHJpbmdbNCArIG51bVBhcmFtc107Ci0gICAgICAgIHR5cGVzWzBdID0gVXRpbC5nZXRKQ1JlZlR5cGUoRE9NX0lOVEZfU0lHKTsKLSAgICAgICAgdHlwZXNbMV0gPSBVdGlsLmdldEpDUmVmVHlwZShOT0RFX0lURVJBVE9SX1NJRyk7Ci0gICAgICAgIHR5cGVzWzJdID0gVXRpbC5nZXRKQ1JlZlR5cGUoVFJBTlNMRVRfT1VUUFVUX1NJRyk7Ci0gICAgICAgIHR5cGVzWzNdID0gY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5UeXBlLklOVDsKLSAgICAgICAgbmFtZXNbMF0gPSBET0NVTUVOVF9QTkFNRTsKLSAgICAgICAgbmFtZXNbMV0gPSBJVEVSQVRPUl9QTkFNRTsKLSAgICAgICAgbmFtZXNbMl0gPSBUUkFOU0xFVF9PVVRQVVRfUE5BTUU7Ci0gICAgICAgIG5hbWVzWzNdID0gTk9ERV9QTkFNRTsKLQotICAgICAgICAvLyBGb3Igc2ltcGxlIG5hbWVkIHRlbXBsYXRlcywgdGhlIHNpZ25hdHVyZSBvZiB0aGUgZ2VuZXJhdGVkIG1ldGhvZAotICAgICAgICAvLyBpcyBub3QgZml4ZWQuIEl0IGRlcGVuZHMgb24gdGhlIG51bWJlciBvZiBwYXJhbWV0ZXJzIGRlY2xhcmVkIGluIHRoZQotICAgICAgICAvLyB0ZW1wbGF0ZS4KLSAgICAgICAgZm9yIChpbnQgaSA9IDQ7IGkgPCA0ICsgbnVtUGFyYW1zOyBpKyspIHsKLSAgICAgICAgICAgIHR5cGVzW2ldID0gVXRpbC5nZXRKQ1JlZlR5cGUoT0JKRUNUX1NJRyk7Ci0gICAgICAgICAgICBuYW1lc1tpXSA9ICJwYXJhbSIgKyBTdHJpbmcudmFsdWVPZihpLTQpOwotICAgICAgICB9Ci0KLSAgICAgICAgTmFtZWRNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuID0KLSAgICAgICAgICAgICAgICBuZXcgTmFtZWRNZXRob2RHZW5lcmF0b3IoQUNDX1BVQkxJQywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlR5cGUuVk9JRCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlcywgbmFtZXMsIG1ldGhvZE5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0Q2xhc3NOYW1lKCksIGlsLCBjcGcpOwotCi0gICAgICAgIGlsLmFwcGVuZCh0ZW1wbGF0ZS5jb21waWxlKGNsYXNzR2VuLCBtZXRob2RHZW4pKTsKLSAgICAgICAgaWwuYXBwZW5kKFJFVFVSTik7Ci0KLSAgICAgICAgY2xhc3NHZW4uYWRkTWV0aG9kKG1ldGhvZEdlbik7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIGNvbXBpbGVUZW1wbGF0ZXMoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbnN0cnVjdGlvbkhhbmRsZSBuZXh0KQotICAgIHsKLSAgICAgICAgU2V0PFRlbXBsYXRlPiB0ZW1wbGF0ZXMgPSBfbmFtZWRUZW1wbGF0ZXMua2V5U2V0KCk7Ci0gICAgICAgIGZvciAoVGVtcGxhdGUgdGVtcGxhdGUgOiB0ZW1wbGF0ZXMpIHsKLSAgICAgICAgICAgIGNvbXBpbGVOYW1lZFRlbXBsYXRlKHRlbXBsYXRlLCBjbGFzc0dlbik7Ci0gICAgICAgIH0KLQotICAgICAgICB0ZW1wbGF0ZXMgPSBfbmVlZGVkVGVtcGxhdGVzLmtleVNldCgpOwotICAgICAgICBmb3IgKFRlbXBsYXRlIHRlbXBsYXRlIDogdGVtcGxhdGVzKSB7Ci0gICAgICAgICAgICBpZiAodGVtcGxhdGUuaGFzQ29udGVudHMoKSkgewotICAgICAgICAgICAgICAgIC8vICEhISBUT0RPIHRlbXBsYXRlcyBib3RoIG5hbWVkIGFuZCBtYXRjaGVkCi0gICAgICAgICAgICAgICAgSW5zdHJ1Y3Rpb25MaXN0IHRpbCA9IHRlbXBsYXRlLmNvbXBpbGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgICAgICAgICAgdGlsLmFwcGVuZChuZXcgR09UT19XKG5leHQpKTsKLSAgICAgICAgICAgICAgICBfdGVtcGxhdGVJTHMucHV0KHRlbXBsYXRlLCB0aWwpOwotICAgICAgICAgICAgICAgIF90ZW1wbGF0ZUlIcy5wdXQodGVtcGxhdGUsIHRpbC5nZXRTdGFydCgpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIC8vIGVtcHR5IHRlbXBsYXRlCi0gICAgICAgICAgICAgICAgX3RlbXBsYXRlSUhzLnB1dCh0ZW1wbGF0ZSwgbmV4dCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgYXBwZW5kVGVtcGxhdGVDb2RlKEluc3RydWN0aW9uTGlzdCBib2R5KSB7Ci0gICAgICAgIGZvciAoVGVtcGxhdGUgdGVtcGxhdGUgOiBfbmVlZGVkVGVtcGxhdGVzLmtleVNldCgpKSB7Ci0gICAgICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaUxpc3QgPSBfdGVtcGxhdGVJTHMuZ2V0KHRlbXBsYXRlKTsKLSAgICAgICAgICAgIGlmIChpTGlzdCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgYm9keS5hcHBlbmQoaUxpc3QpOwotICAgICAgICAgICAgfQotCi0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgYXBwZW5kVGVzdFNlcXVlbmNlcyhJbnN0cnVjdGlvbkxpc3QgYm9keSkgewotICAgICAgICBmaW5hbCBpbnQgbiA9IF90ZXN0U2VxLmxlbmd0aDsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspIHsKLSAgICAgICAgICAgIGZpbmFsIFRlc3RTZXEgdGVzdFNlcSA9IF90ZXN0U2VxW2ldOwotICAgICAgICAgICAgaWYgKHRlc3RTZXEgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIEluc3RydWN0aW9uTGlzdCBpbCA9IHRlc3RTZXEuZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0gICAgICAgICAgICAgICAgaWYgKGlsICE9IG51bGwpCi0gICAgICAgICAgICAgICAgICAgIGJvZHkuYXBwZW5kKGlsKTsKLSAgICAgICAgICAgICAgICAvLyBlbHNlIHRyaXZpYWwgVGVzdFNlcQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHN0YXRpYyB2b2lkIGNvbXBpbGVHZXRDaGlsZHJlbihDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbm9kZSkgewotICAgICAgICBmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLSAgICAgICAgZmluYWwgaW50IGdpdCA9IGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoRE9NX0lOVEYsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdFVF9DSElMRFJFTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR0VUX0NISUxEUkVOX1NJRyk7Ci0gICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBJTE9BRChub2RlKSk7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFSU5URVJGQUNFKGdpdCwgMikpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbXBpbGVzIHRoZSBkZWZhdWx0IGhhbmRsaW5nIGZvciBET00gZWxlbWVudHM6IHRyYXZlcnNlIGFsbCBjaGlsZHJlbgotICAgICAqLwotICAgIHByaXZhdGUgSW5zdHJ1Y3Rpb25MaXN0IGNvbXBpbGVEZWZhdWx0UmVjdXJzaW9uKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW5zdHJ1Y3Rpb25IYW5kbGUgbmV4dCkgewotICAgICAgICBmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG5ldyBJbnN0cnVjdGlvbkxpc3QoKTsKLSAgICAgICAgZmluYWwgU3RyaW5nIGFwcGx5VGVtcGxhdGVzU2lnID0gY2xhc3NHZW4uZ2V0QXBwbHlUZW1wbGF0ZXNTaWcoKTsKLSAgICAgICAgZmluYWwgaW50IGdpdCA9IGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoRE9NX0lOVEYsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdFVF9DSElMRFJFTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR0VUX0NISUxEUkVOX1NJRyk7Ci0gICAgICAgIGZpbmFsIGludCBhcHBseVRlbXBsYXRlcyA9IGNwZy5hZGRNZXRob2RyZWYoZ2V0Q2xhc3NOYW1lKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb25OYW1lKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXBwbHlUZW1wbGF0ZXNTaWcpOwotICAgICAgICBpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpOwotICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0KLSAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkRE9NKCkpOwotICAgICAgICBpbC5hcHBlbmQobmV3IElMT0FEKF9jdXJyZW50SW5kZXgpKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0UoZ2l0LCAyKSk7Ci0gICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZEhhbmRsZXIoKSk7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChhcHBseVRlbXBsYXRlcykpOwotICAgICAgICBpbC5hcHBlbmQobmV3IEdPVE9fVyhuZXh0KSk7Ci0gICAgICAgIHJldHVybiBpbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb21waWxlcyB0aGUgZGVmYXVsdCBhY3Rpb24gZm9yIERPTSB0ZXh0IG5vZGVzIGFuZCBhdHRyaWJ1dGUgbm9kZXM6Ci0gICAgICogb3V0cHV0IHRoZSBub2RlJ3MgdGV4dCB2YWx1ZQotICAgICAqLwotICAgIHByaXZhdGUgSW5zdHJ1Y3Rpb25MaXN0IGNvbXBpbGVEZWZhdWx0VGV4dChDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW5zdHJ1Y3Rpb25IYW5kbGUgbmV4dCkgewotICAgICAgICBmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG5ldyBJbnN0cnVjdGlvbkxpc3QoKTsKLQotICAgICAgICBmaW5hbCBpbnQgY2hhcnMgPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKERPTV9JTlRGLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENIQVJBQ1RFUlMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ0hBUkFDVEVSU19TSUcpOwotICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgSUxPQUQoX2N1cnJlbnRJbmRleCkpOwotICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRIYW5kbGVyKCkpOwotICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRUlOVEVSRkFDRShjaGFycywgMykpOwotICAgICAgICBpbC5hcHBlbmQobmV3IEdPVE9fVyhuZXh0KSk7Ci0gICAgICAgIHJldHVybiBpbDsKLSAgICB9Ci0KLSAgICBwcml2YXRlIEluc3RydWN0aW9uTGlzdCBjb21waWxlTmFtZXNwYWNlcyhDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW5bXSBpc05hbWVzcGFjZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuW10gaXNBdHRyaWJ1dGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBhdHRyRmxhZywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbnN0cnVjdGlvbkhhbmRsZSBkZWZhdWx0VGFyZ2V0KSB7Ci0gICAgICAgIGZpbmFsIFhTTFRDIHhzbHRjID0gY2xhc3NHZW4uZ2V0UGFyc2VyKCkuZ2V0WFNMVEMoKTsKLSAgICAgICAgZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotCi0gICAgICAgIC8vIEFwcGVuZCBzd2l0Y2goKSBzdGF0ZW1lbnQgLSBuYW1lc3BhY2UgdGVzdCBkaXNwYXRjaCBsb29wCi0gICAgICAgIGZpbmFsIFZlY3RvciBuYW1lc3BhY2VzID0geHNsdGMuZ2V0TmFtZXNwYWNlSW5kZXgoKTsKLSAgICAgICAgZmluYWwgVmVjdG9yIG5hbWVzID0geHNsdGMuZ2V0TmFtZXNJbmRleCgpOwotICAgICAgICBmaW5hbCBpbnQgbmFtZXNwYWNlQ291bnQgPSBuYW1lc3BhY2VzLnNpemUoKSArIDE7Ci0gICAgICAgIGZpbmFsIGludCBuYW1lc0NvdW50ID0gbmFtZXMuc2l6ZSgpOwotCi0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG5ldyBJbnN0cnVjdGlvbkxpc3QoKTsKLSAgICAgICAgZmluYWwgaW50W10gdHlwZXMgPSBuZXcgaW50W25hbWVzcGFjZUNvdW50XTsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25IYW5kbGVbXSB0YXJnZXRzID0gbmV3IEluc3RydWN0aW9uSGFuZGxlW3R5cGVzLmxlbmd0aF07Ci0KLSAgICAgICAgaWYgKG5hbWVzcGFjZUNvdW50ID4gMCkgewotICAgICAgICAgICAgYm9vbGVhbiBjb21waWxlZCA9IGZhbHNlOwotCi0gICAgICAgICAgICAvLyBJbml0aWFsaXplIHRhcmdldHMgZm9yIG5hbWVzcGFjZSgpIHN3aXRjaCBzdGF0ZW1lbnQKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbmFtZXNwYWNlQ291bnQ7IGkrKykgewotICAgICAgICAgICAgICAgIHRhcmdldHNbaV0gPSBkZWZhdWx0VGFyZ2V0OwotICAgICAgICAgICAgICAgIHR5cGVzW2ldID0gaTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gQWRkIHRlc3Qgc2VxdWVuY2VzIGZvciBrbm93biBuYW1lc3BhY2UgdHlwZXMKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSBEVE0uTlRZUEVTOyBpIDwgKERUTS5OVFlQRVMrbmFtZXNDb3VudCk7IGkrKykgewotICAgICAgICAgICAgICAgIGlmICgoaXNOYW1lc3BhY2VbaV0pICYmIChpc0F0dHJpYnV0ZVtpXSA9PSBhdHRyRmxhZykpIHsKLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG5hbWUgPSAoU3RyaW5nKW5hbWVzLmVsZW1lbnRBdChpLURUTS5OVFlQRVMpOwotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbmFtZXNwYWNlID0gbmFtZS5zdWJzdHJpbmcoMCxuYW1lLmxhc3RJbmRleE9mKCc6JykpOwotICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgdHlwZSA9IHhzbHRjLnJlZ2lzdGVyTmFtZXNwYWNlKG5hbWVzcGFjZSk7Ci0KLSAgICAgICAgICAgICAgICAgICAgaWYgKChpIDwgX3Rlc3RTZXEubGVuZ3RoKSAmJgotICAgICAgICAgICAgICAgICAgICAgICAgKF90ZXN0U2VxW2ldICE9IG51bGwpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXRzW3R5cGVdID0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAoX3Rlc3RTZXFbaV0pLmNvbXBpbGUoY2xhc3NHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRUYXJnZXQpOwotICAgICAgICAgICAgICAgICAgICAgICAgY29tcGlsZWQgPSB0cnVlOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBSZXR1cm4gIm51bGwiIGlmIG5vIHRlc3Qgc2VxdWVuY2VzIHdlcmUgY29tcGlsZWQKLSAgICAgICAgICAgIGlmICghY29tcGlsZWQpIHJldHVybihudWxsKTsKLQotICAgICAgICAgICAgLy8gQXBwZW5kIGZpcnN0IGNvZGUgaW4gYXBwbHlUZW1wbGF0ZXMoKSAtIGdldCB0eXBlIG9mIGN1cnJlbnQgbm9kZQotICAgICAgICAgICAgZmluYWwgaW50IGdldE5TID0gY3BnLmFkZEludGVyZmFjZU1ldGhvZHJlZihET01fSU5URiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImdldE5hbWVzcGFjZVR5cGUiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKEkpSSIpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkRE9NKCkpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTE9BRChfY3VycmVudEluZGV4KSk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRUlOVEVSRkFDRShnZXROUywgMikpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBTV0lUQ0godHlwZXMsIHRhcmdldHMsIGRlZmF1bHRUYXJnZXQpKTsKLSAgICAgICAgICAgIHJldHVybihpbCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4obnVsbCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgIC8qKgotICAgICAqIENvbXBpbGVzIHRoZSBhcHBseVRlbXBsYXRlcygpIG1ldGhvZCBhbmQgYWRkcyBpdCB0byB0aGUgdHJhbnNsZXQuCi0gICAgICogVGhpcyBpcyB0aGUgbWFpbiBkaXNwYXRjaCBtZXRob2QuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY29tcGlsZUFwcGx5VGVtcGxhdGVzKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuKSB7Ci0gICAgICAgIGZpbmFsIFhTTFRDIHhzbHRjID0gY2xhc3NHZW4uZ2V0UGFyc2VyKCkuZ2V0WFNMVEMoKTsKLSAgICAgICAgZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotICAgICAgICBmaW5hbCBWZWN0b3IgbmFtZXMgPSB4c2x0Yy5nZXROYW1lc0luZGV4KCk7Ci0KLSAgICAgICAgLy8gQ3JlYXRlIHRoZSBhcHBseVRlbXBsYXRlcygpIG1ldGhvZAotICAgICAgICBmaW5hbCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlR5cGVbXSBhcmdUeXBlcyA9Ci0gICAgICAgICAgICBuZXcgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5UeXBlWzNdOwotICAgICAgICBhcmdUeXBlc1swXSA9IFV0aWwuZ2V0SkNSZWZUeXBlKERPTV9JTlRGX1NJRyk7Ci0gICAgICAgIGFyZ1R5cGVzWzFdID0gVXRpbC5nZXRKQ1JlZlR5cGUoTk9ERV9JVEVSQVRPUl9TSUcpOwotICAgICAgICBhcmdUeXBlc1syXSA9IFV0aWwuZ2V0SkNSZWZUeXBlKFRSQU5TTEVUX09VVFBVVF9TSUcpOwotCi0gICAgICAgIGZpbmFsIFN0cmluZ1tdIGFyZ05hbWVzID0gbmV3IFN0cmluZ1szXTsKLSAgICAgICAgYXJnTmFtZXNbMF0gPSBET0NVTUVOVF9QTkFNRTsKLSAgICAgICAgYXJnTmFtZXNbMV0gPSBJVEVSQVRPUl9QTkFNRTsKLSAgICAgICAgYXJnTmFtZXNbMl0gPSBUUkFOU0xFVF9PVVRQVVRfUE5BTUU7Ci0KLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IG1haW5JTCA9IG5ldyBJbnN0cnVjdGlvbkxpc3QoKTsKLSAgICAgICAgZmluYWwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiA9Ci0gICAgICAgICAgICBuZXcgTWV0aG9kR2VuZXJhdG9yKEFDQ19QVUJMSUMgfCBBQ0NfRklOQUwsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuVHlwZS5WT0lELAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmdUeXBlcywgYXJnTmFtZXMsIGZ1bmN0aW9uTmFtZSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRDbGFzc05hbWUoKSwgbWFpbklMLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKSk7Ci0gICAgICAgIG1ldGhvZEdlbi5hZGRFeGNlcHRpb24oImNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5UcmFuc2xldEV4Y2VwdGlvbiIpOwotICAgICAgICAvLyBJbnNlcnQgYW4gZXh0cmEgTk9QIGp1c3QgdG8ga2VlcCAiY3VycmVudCIgZnJvbSBhcHBlYXJpbmcgYXMgaWYgaXQKLSAgICAgICAgLy8gaGFzIGEgdmFsdWUgYmVmb3JlIHRoZSBzdGFydCBvZiB0aGUgbG9vcC4KLSAgICAgICAgbWFpbklMLmFwcGVuZChOT1ApOwotCi0KLSAgICAgICAgLy8gQ3JlYXRlIGEgbG9jYWwgdmFyaWFibGUgdG8gaG9sZCB0aGUgY3VycmVudCBub2RlCi0gICAgICAgIGZpbmFsIExvY2FsVmFyaWFibGVHZW4gY3VycmVudDsKLSAgICAgICAgY3VycmVudCA9IG1ldGhvZEdlbi5hZGRMb2NhbFZhcmlhYmxlMigiY3VycmVudCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5UeXBlLklOVCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsKTsKLSAgICAgICAgX2N1cnJlbnRJbmRleCA9IGN1cnJlbnQuZ2V0SW5kZXgoKTsKLQotICAgICAgICAvLyBDcmVhdGUgdGhlICJib2R5IiBpbnN0cnVjdGlvbiBsaXN0IHRoYXQgd2lsbCBldmVudHVhbGx5IGhvbGQgdGhlCi0gICAgICAgIC8vIGNvZGUgZm9yIHRoZSBlbnRpcmUgbWV0aG9kIChvdGhlciBJTHMgd2lsbCBiZSBhcHBlbmRlZCkuCi0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBib2R5ID0gbmV3IEluc3RydWN0aW9uTGlzdCgpOwotICAgICAgICBib2R5LmFwcGVuZChOT1ApOwotCi0gICAgICAgIC8vIENyZWF0ZSBhbiBpbnN0cnVjdGlvbiBsaXN0IHRoYXQgY29udGFpbnMgdGhlIGRlZmF1bHQgbmV4dC1ub2RlCi0gICAgICAgIC8vIGl0ZXJhdGlvbgotICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWxMb29wID0gbmV3IEluc3RydWN0aW9uTGlzdCgpOwotICAgICAgICBpbExvb3AuYXBwZW5kKG1ldGhvZEdlbi5sb2FkSXRlcmF0b3IoKSk7Ci0gICAgICAgIGlsTG9vcC5hcHBlbmQobWV0aG9kR2VuLm5leHROb2RlKCkpOwotICAgICAgICBpbExvb3AuYXBwZW5kKERVUCk7Ci0gICAgICAgIGlsTG9vcC5hcHBlbmQobmV3IElTVE9SRShfY3VycmVudEluZGV4KSk7Ci0KLSAgICAgICAgLy8gVGhlIGJvZHkgb2YgdGhpcyBjb2RlIGNhbiBnZXQgdmVyeSBsYXJnZSAtIGxhcmdlIHRoYW4gY2FuIGJlIGhhbmRsZWQKLSAgICAgICAgLy8gYnkgYSBzaW5nbGUgSUZORShib2R5LmdldFN0YXJ0KCkpIGluc3RydWN0aW9uIC0gbmVlZCB3b3JrYXJvdW5kOgotICAgICAgICBmaW5hbCBCcmFuY2hIYW5kbGUgaWZlcSA9IGlsTG9vcC5hcHBlbmQobmV3IElGTFQobnVsbCkpOwotICAgICAgICBmaW5hbCBCcmFuY2hIYW5kbGUgbG9vcCA9IGlsTG9vcC5hcHBlbmQobmV3IEdPVE9fVyhudWxsKSk7Ci0gICAgICAgIGlmZXEuc2V0VGFyZ2V0KGlsTG9vcC5hcHBlbmQoUkVUVVJOKSk7ICAvLyBhcHBseVRlbXBsYXRlcygpIGVuZHMgaGVyZSEKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25IYW5kbGUgaWhMb29wID0gaWxMb29wLmdldFN0YXJ0KCk7Ci0KLSAgICAgICAgY3VycmVudC5zZXRTdGFydChtYWluSUwuYXBwZW5kKG5ldyBHT1RPX1coaWhMb29wKSkpOwotCi0gICAgICAgIC8vIExpdmUgcmFuZ2Ugb2YgImN1cnJlbnQiIGVuZHMgYXQgZW5kIG9mIGxvb3AKLSAgICAgICAgY3VycmVudC5zZXRFbmQobG9vcCk7Ci0KLSAgICAgICAgLy8gQ29tcGlsZSBkZWZhdWx0IGhhbmRsaW5nIG9mIGVsZW1lbnRzICh0cmF2ZXJzZSBjaGlsZHJlbikKLSAgICAgICAgSW5zdHJ1Y3Rpb25MaXN0IGlsUmVjdXJzZSA9Ci0gICAgICAgICAgICBjb21waWxlRGVmYXVsdFJlY3Vyc2lvbihjbGFzc0dlbiwgbWV0aG9kR2VuLCBpaExvb3ApOwotICAgICAgICBJbnN0cnVjdGlvbkhhbmRsZSBpaFJlY3Vyc2UgPSBpbFJlY3Vyc2UuZ2V0U3RhcnQoKTsKLQotICAgICAgICAvLyBDb21waWxlIGRlZmF1bHQgaGFuZGxpbmcgb2YgdGV4dC9hdHRyaWJ1dGUgbm9kZXMgKG91dHB1dCB0ZXh0KQotICAgICAgICBJbnN0cnVjdGlvbkxpc3QgaWxUZXh0ID0KLSAgICAgICAgICAgIGNvbXBpbGVEZWZhdWx0VGV4dChjbGFzc0dlbiwgbWV0aG9kR2VuLCBpaExvb3ApOwotICAgICAgICBJbnN0cnVjdGlvbkhhbmRsZSBpaFRleHQgPSBpbFRleHQuZ2V0U3RhcnQoKTsKLQotICAgICAgICAvLyBEaXN0aW5ndWlzaCBhdHRyaWJ1dGUvZWxlbWVudC9uYW1lc3BhY2UgdGVzdHMgZm9yIGZ1cnRoZXIgcHJvY2Vzc2luZwotICAgICAgICBmaW5hbCBpbnRbXSB0eXBlcyA9IG5ldyBpbnRbRFRNLk5UWVBFUyArIG5hbWVzLnNpemUoKV07Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdHlwZXMubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgIHR5cGVzW2ldID0gaTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIEluaXRpYWxpemUgaXNBdHRyaWJ1dGVbXSBhbmQgaXNOYW1lc3BhY2VbXSBhcnJheXMKLSAgICAgICAgZmluYWwgYm9vbGVhbltdIGlzQXR0cmlidXRlID0gbmV3IGJvb2xlYW5bdHlwZXMubGVuZ3RoXTsKLSAgICAgICAgZmluYWwgYm9vbGVhbltdIGlzTmFtZXNwYWNlID0gbmV3IGJvb2xlYW5bdHlwZXMubGVuZ3RoXTsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuYW1lcy5zaXplKCk7IGkrKykgewotICAgICAgICAgICAgZmluYWwgU3RyaW5nIG5hbWUgPSAoU3RyaW5nKW5hbWVzLmVsZW1lbnRBdChpKTsKLSAgICAgICAgICAgIGlzQXR0cmlidXRlW2kgKyBEVE0uTlRZUEVTXSA9IGlzQXR0cmlidXRlTmFtZShuYW1lKTsKLSAgICAgICAgICAgIGlzTmFtZXNwYWNlW2kgKyBEVE0uTlRZUEVTXSA9IGlzTmFtZXNwYWNlTmFtZShuYW1lKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIENvbXBpbGUgYWxsIHRlbXBsYXRlcyAtIHJlZ2FyZGxlc3Mgb2YgcGF0dGVybiB0eXBlCi0gICAgICAgIGNvbXBpbGVUZW1wbGF0ZXMoY2xhc3NHZW4sIG1ldGhvZEdlbiwgaWhMb29wKTsKLQotICAgICAgICAvLyBIYW5kbGUgdGVtcGxhdGUgd2l0aCBleHBsaWNpdCAiKiIgcGF0dGVybgotICAgICAgICBmaW5hbCBUZXN0U2VxIGVsZW1UZXN0ID0gX3Rlc3RTZXFbRFRNLkVMRU1FTlRfTk9ERV07Ci0gICAgICAgIEluc3RydWN0aW9uSGFuZGxlIGloRWxlbSA9IGloUmVjdXJzZTsKLSAgICAgICAgaWYgKGVsZW1UZXN0ICE9IG51bGwpCi0gICAgICAgICAgICBpaEVsZW0gPSBlbGVtVGVzdC5jb21waWxlKGNsYXNzR2VuLCBtZXRob2RHZW4sIGloUmVjdXJzZSk7Ci0KLSAgICAgICAgLy8gSGFuZGxlIHRlbXBsYXRlIHdpdGggZXhwbGljaXQgIkAqIiBwYXR0ZXJuCi0gICAgICAgIGZpbmFsIFRlc3RTZXEgYXR0clRlc3QgPSBfdGVzdFNlcVtEVE0uQVRUUklCVVRFX05PREVdOwotICAgICAgICBJbnN0cnVjdGlvbkhhbmRsZSBpaEF0dHIgPSBpaFRleHQ7Ci0gICAgICAgIGlmIChhdHRyVGVzdCAhPSBudWxsKQotICAgICAgICAgICAgaWhBdHRyID0gYXR0clRlc3QuY29tcGlsZShjbGFzc0dlbiwgbWV0aG9kR2VuLCBpaEF0dHIpOwotCi0gICAgICAgIC8vIERvIHRlc3RzIGZvciBpZCgpIGFuZCBrZXkoKSBwYXR0ZXJucyBmaXJzdAotICAgICAgICBJbnN0cnVjdGlvbkxpc3QgaWxLZXkgPSBudWxsOwotICAgICAgICBpZiAoX2lkeFRlc3RTZXEgIT0gbnVsbCkgewotICAgICAgICAgICAgbG9vcC5zZXRUYXJnZXQoX2lkeFRlc3RTZXEuY29tcGlsZShjbGFzc0dlbiwgbWV0aG9kR2VuLCBib2R5LmdldFN0YXJ0KCkpKTsKLSAgICAgICAgICAgIGlsS2V5ID0gX2lkeFRlc3RTZXEuZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBsb29wLnNldFRhcmdldChib2R5LmdldFN0YXJ0KCkpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gSWYgdGhlcmUgaXMgYSBtYXRjaCBvbiBub2RlKCkgd2UgbmVlZCB0byByZXBsYWNlIGloRWxlbQotICAgICAgICAvLyBhbmQgaWhUZXh0IGlmIHRoZSBwcmlvcml0eSBvZiBub2RlKCkgaXMgaGlnaGVyCi0gICAgICAgIGlmIChfY2hpbGROb2RlVGVzdFNlcSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAvLyBDb21wYXJlIHByaW9yaXRpZXMgb2Ygbm9kZSgpIGFuZCAiKiIKLSAgICAgICAgICAgIGRvdWJsZSBub2RlUHJpbyA9IF9jaGlsZE5vZGVUZXN0U2VxLmdldFByaW9yaXR5KCk7Ci0gICAgICAgICAgICBpbnQgICAgbm9kZVBvcyAgPSBfY2hpbGROb2RlVGVzdFNlcS5nZXRQb3NpdGlvbigpOwotICAgICAgICAgICAgZG91YmxlIGVsZW1QcmlvID0gKDAgLSBEb3VibGUuTUFYX1ZBTFVFKTsKLSAgICAgICAgICAgIGludCAgICBlbGVtUG9zICA9IEludGVnZXIuTUlOX1ZBTFVFOwotCi0gICAgICAgICAgICBpZiAoZWxlbVRlc3QgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGVsZW1QcmlvID0gZWxlbVRlc3QuZ2V0UHJpb3JpdHkoKTsKLSAgICAgICAgICAgICAgICBlbGVtUG9zICA9IGVsZW1UZXN0LmdldFBvc2l0aW9uKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoZWxlbVByaW8gPT0gRG91YmxlLk5hTiB8fCBlbGVtUHJpbyA8IG5vZGVQcmlvIHx8Ci0gICAgICAgICAgICAgICAgKGVsZW1QcmlvID09IG5vZGVQcmlvICYmIGVsZW1Qb3MgPCBub2RlUG9zKSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBpaEVsZW0gPSBfY2hpbGROb2RlVGVzdFNlcS5jb21waWxlKGNsYXNzR2VuLCBtZXRob2RHZW4sIGloTG9vcCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIENvbXBhcmUgcHJpb3JpdGllcyBvZiBub2RlKCkgYW5kIHRleHQoKQotICAgICAgICAgICAgZmluYWwgVGVzdFNlcSB0ZXh0VGVzdCA9IF90ZXN0U2VxW0RUTS5URVhUX05PREVdOwotICAgICAgICAgICAgZG91YmxlIHRleHRQcmlvID0gKDAgLSBEb3VibGUuTUFYX1ZBTFVFKTsKLSAgICAgICAgICAgIGludCAgICB0ZXh0UG9zICA9IEludGVnZXIuTUlOX1ZBTFVFOwotCi0gICAgICAgICAgICBpZiAodGV4dFRlc3QgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHRleHRQcmlvID0gdGV4dFRlc3QuZ2V0UHJpb3JpdHkoKTsKLSAgICAgICAgICAgICAgICB0ZXh0UG9zICA9IHRleHRUZXN0LmdldFBvc2l0aW9uKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAodGV4dFByaW8gPT0gRG91YmxlLk5hTiB8fCB0ZXh0UHJpbyA8IG5vZGVQcmlvIHx8Ci0gICAgICAgICAgICAgICAgKHRleHRQcmlvID09IG5vZGVQcmlvICYmIHRleHRQb3MgPCBub2RlUG9zKSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBpaFRleHQgPSBfY2hpbGROb2RlVGVzdFNlcS5jb21waWxlKGNsYXNzR2VuLCBtZXRob2RHZW4sIGloTG9vcCk7Ci0gICAgICAgICAgICAgICAgX3Rlc3RTZXFbRFRNLlRFWFRfTk9ERV0gPSBfY2hpbGROb2RlVGVzdFNlcTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIEhhbmRsZSB0ZW1wbGF0ZXMgd2l0aCAibnM6KiIgcGF0dGVybgotICAgICAgICBJbnN0cnVjdGlvbkhhbmRsZSBlbGVtTmFtZXNwYWNlSGFuZGxlID0gaWhFbGVtOwotICAgICAgICBJbnN0cnVjdGlvbkxpc3QgbnNFbGVtID0gY29tcGlsZU5hbWVzcGFjZXMoY2xhc3NHZW4sIG1ldGhvZEdlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzTmFtZXNwYWNlLCBpc0F0dHJpYnV0ZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlLCBpaEVsZW0pOwotICAgICAgICBpZiAobnNFbGVtICE9IG51bGwpIGVsZW1OYW1lc3BhY2VIYW5kbGUgPSBuc0VsZW0uZ2V0U3RhcnQoKTsKLQotICAgICAgICAvLyBIYW5kbGUgdGVtcGxhdGVzIHdpdGggIm5zOkAqIiBwYXR0ZXJuCi0gICAgICAgIEluc3RydWN0aW9uSGFuZGxlIGF0dHJOYW1lc3BhY2VIYW5kbGUgPSBpaEF0dHI7Ci0gICAgICAgIEluc3RydWN0aW9uTGlzdCBuc0F0dHIgPSBjb21waWxlTmFtZXNwYWNlcyhjbGFzc0dlbiwgbWV0aG9kR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNOYW1lc3BhY2UsIGlzQXR0cmlidXRlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ1ZSwgaWhBdHRyKTsKLSAgICAgICAgaWYgKG5zQXR0ciAhPSBudWxsKSBhdHRyTmFtZXNwYWNlSGFuZGxlID0gbnNBdHRyLmdldFN0YXJ0KCk7Ci0KLSAgICAgICAgLy8gSGFuZGxlIHRlbXBsYXRlcyB3aXRoICJuczplbGVtIiBvciAibnM6QGF0dHIiIHBhdHRlcm4KLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25IYW5kbGVbXSB0YXJnZXRzID0gbmV3IEluc3RydWN0aW9uSGFuZGxlW3R5cGVzLmxlbmd0aF07Ci0gICAgICAgIGZvciAoaW50IGkgPSBEVE0uTlRZUEVTOyBpIDwgdGFyZ2V0cy5sZW5ndGg7IGkrKykgewotICAgICAgICAgICAgZmluYWwgVGVzdFNlcSB0ZXN0U2VxID0gX3Rlc3RTZXFbaV07Ci0gICAgICAgICAgICAvLyBKdW1wIHN0cmFpZ2h0IHRvIG5hbWVzcGFjZSB0ZXN0cyA/Ci0gICAgICAgICAgICBpZiAoaXNOYW1lc3BhY2VbaV0pIHsKLSAgICAgICAgICAgICAgICBpZiAoaXNBdHRyaWJ1dGVbaV0pCi0gICAgICAgICAgICAgICAgICAgIHRhcmdldHNbaV0gPSBhdHRyTmFtZXNwYWNlSGFuZGxlOwotICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgICAgdGFyZ2V0c1tpXSA9IGVsZW1OYW1lc3BhY2VIYW5kbGU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyBUZXN0IGZpcnN0LCB0aGVuIGp1bXAgdG8gbmFtZXNwYWNlIHRlc3RzCi0gICAgICAgICAgICBlbHNlIGlmICh0ZXN0U2VxICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBpZiAoaXNBdHRyaWJ1dGVbaV0pCi0gICAgICAgICAgICAgICAgICAgIHRhcmdldHNbaV0gPSB0ZXN0U2VxLmNvbXBpbGUoY2xhc3NHZW4sIG1ldGhvZEdlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyTmFtZXNwYWNlSGFuZGxlKTsKLSAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgIHRhcmdldHNbaV0gPSB0ZXN0U2VxLmNvbXBpbGUoY2xhc3NHZW4sIG1ldGhvZEdlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtTmFtZXNwYWNlSGFuZGxlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIHRhcmdldHNbaV0gPSBpaExvb3A7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotCi0gICAgICAgIC8vIEhhbmRsZSBwYXR0ZXJuIHdpdGggbWF0Y2ggb24gcm9vdCBub2RlIC0gZGVmYXVsdDogdHJhdmVyc2UgY2hpbGRyZW4KLSAgICAgICAgdGFyZ2V0c1tEVE0uUk9PVF9OT0RFXSA9IF9yb290UGF0dGVybiAhPSBudWxsCi0gICAgICAgICAgICA/IGdldFRlbXBsYXRlSW5zdHJ1Y3Rpb25IYW5kbGUoX3Jvb3RQYXR0ZXJuLmdldFRlbXBsYXRlKCkpCi0gICAgICAgICAgICA6IGloUmVjdXJzZTsKLQotICAgICAgICAvLyBIYW5kbGUgcGF0dGVybiB3aXRoIG1hdGNoIG9uIHJvb3Qgbm9kZSAtIGRlZmF1bHQ6IHRyYXZlcnNlIGNoaWxkcmVuCi0gICAgICAgIHRhcmdldHNbRFRNLkRPQ1VNRU5UX05PREVdID0gX3Jvb3RQYXR0ZXJuICE9IG51bGwKLSAgICAgICAgICAgID8gZ2V0VGVtcGxhdGVJbnN0cnVjdGlvbkhhbmRsZShfcm9vdFBhdHRlcm4uZ2V0VGVtcGxhdGUoKSkKLSAgICAgICAgICAgIDogaWhSZWN1cnNlOwotCi0gICAgICAgIC8vIEhhbmRsZSBhbnkgcGF0dGVybiB3aXRoIG1hdGNoIG9uIHRleHQgbm9kZXMgLSBkZWZhdWx0OiBvdXRwdXQgdGV4dAotICAgICAgICB0YXJnZXRzW0RUTS5URVhUX05PREVdID0gX3Rlc3RTZXFbRFRNLlRFWFRfTk9ERV0gIT0gbnVsbAotICAgICAgICAgICAgPyBfdGVzdFNlcVtEVE0uVEVYVF9OT0RFXS5jb21waWxlKGNsYXNzR2VuLCBtZXRob2RHZW4sIGloVGV4dCkKLSAgICAgICAgICAgIDogaWhUZXh0OwotCi0gICAgICAgIC8vIFRoaXMgRE9NLXR5cGUgaXMgbm90IGluIHVzZSAtIGRlZmF1bHQ6IHByb2Nlc3MgbmV4dCBub2RlCi0gICAgICAgIHRhcmdldHNbRFRNLk5BTUVTUEFDRV9OT0RFXSA9IGloTG9vcDsKLQotICAgICAgICAvLyBNYXRjaCB1bmtub3duIGVsZW1lbnQgaW4gRE9NIC0gZGVmYXVsdDogY2hlY2sgZm9yIG5hbWVzcGFjZSBtYXRjaAotICAgICAgICB0YXJnZXRzW0RUTS5FTEVNRU5UX05PREVdID0gZWxlbU5hbWVzcGFjZUhhbmRsZTsKLQotICAgICAgICAvLyBNYXRjaCB1bmtub3duIGF0dHJpYnV0ZSBpbiBET00gLSBkZWZhdWx0OiBjaGVjayBmb3IgbmFtZXNwYWNlIG1hdGNoCi0gICAgICAgIHRhcmdldHNbRFRNLkFUVFJJQlVURV9OT0RFXSA9IGF0dHJOYW1lc3BhY2VIYW5kbGU7Ci0KLSAgICAgICAgLy8gTWF0Y2ggb24gcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiAtIGRlZmF1bHQ6IHByb2Nlc3MgbmV4dCBub2RlCi0gICAgICAgIEluc3RydWN0aW9uSGFuZGxlIGloUEkgPSBpaExvb3A7Ci0gICAgICAgIGlmIChfY2hpbGROb2RlVGVzdFNlcSAhPSBudWxsKSBpaFBJID0gaWhFbGVtOwotICAgICAgICBpZiAoX3Rlc3RTZXFbRFRNLlBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERV0gIT0gbnVsbCkKLSAgICAgICAgICAgIHRhcmdldHNbRFRNLlBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERV0gPQotICAgICAgICAgICAgICAgIF90ZXN0U2VxW0RUTS5QUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREVdLgotICAgICAgICAgICAgICAgIGNvbXBpbGUoY2xhc3NHZW4sIG1ldGhvZEdlbiwgaWhQSSk7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICAgIHRhcmdldHNbRFRNLlBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERV0gPSBpaFBJOwotCi0gICAgICAgIC8vIE1hdGNoIG9uIGNvbW1lbnRzIC0gZGVmYXVsdDogcHJvY2VzcyBuZXh0IG5vZGUKLSAgICAgICAgSW5zdHJ1Y3Rpb25IYW5kbGUgaWhDb21tZW50ID0gaWhMb29wOwotICAgICAgICBpZiAoX2NoaWxkTm9kZVRlc3RTZXEgIT0gbnVsbCkgaWhDb21tZW50ID0gaWhFbGVtOwotICAgICAgICB0YXJnZXRzW0RUTS5DT01NRU5UX05PREVdID0gX3Rlc3RTZXFbRFRNLkNPTU1FTlRfTk9ERV0gIT0gbnVsbAotICAgICAgICAgICAgPyBfdGVzdFNlcVtEVE0uQ09NTUVOVF9OT0RFXS5jb21waWxlKGNsYXNzR2VuLCBtZXRob2RHZW4sIGloQ29tbWVudCkKLSAgICAgICAgICAgIDogaWhDb21tZW50OwotCi0gICAgICAgICAgICAvLyBUaGlzIERPTS10eXBlIGlzIG5vdCBpbiB1c2UgLSBkZWZhdWx0OiBwcm9jZXNzIG5leHQgbm9kZQotICAgICAgICB0YXJnZXRzW0RUTS5DREFUQV9TRUNUSU9OX05PREVdID0gaWhMb29wOwotCi0gICAgICAgIC8vIFRoaXMgRE9NLXR5cGUgaXMgbm90IGluIHVzZSAtIGRlZmF1bHQ6IHByb2Nlc3MgbmV4dCBub2RlCi0gICAgICAgIHRhcmdldHNbRFRNLkRPQ1VNRU5UX0ZSQUdNRU5UX05PREVdID0gaWhMb29wOwotCi0gICAgICAgIC8vIFRoaXMgRE9NLXR5cGUgaXMgbm90IGluIHVzZSAtIGRlZmF1bHQ6IHByb2Nlc3MgbmV4dCBub2RlCi0gICAgICAgIHRhcmdldHNbRFRNLkRPQ1VNRU5UX1RZUEVfTk9ERV0gPSBpaExvb3A7Ci0KLSAgICAgICAgLy8gVGhpcyBET00tdHlwZSBpcyBub3QgaW4gdXNlIC0gZGVmYXVsdDogcHJvY2VzcyBuZXh0IG5vZGUKLSAgICAgICAgdGFyZ2V0c1tEVE0uRU5USVRZX05PREVdID0gaWhMb29wOwotCi0gICAgICAgIC8vIFRoaXMgRE9NLXR5cGUgaXMgbm90IGluIHVzZSAtIGRlZmF1bHQ6IHByb2Nlc3MgbmV4dCBub2RlCi0gICAgICAgIHRhcmdldHNbRFRNLkVOVElUWV9SRUZFUkVOQ0VfTk9ERV0gPSBpaExvb3A7Ci0KLSAgICAgICAgLy8gVGhpcyBET00tdHlwZSBpcyBub3QgaW4gdXNlIC0gZGVmYXVsdDogcHJvY2VzcyBuZXh0IG5vZGUKLSAgICAgICAgdGFyZ2V0c1tEVE0uTk9UQVRJT05fTk9ERV0gPSBpaExvb3A7Ci0KLQotICAgICAgICAvLyBOb3cgY29tcGlsZSB0ZXN0IHNlcXVlbmNlcyBmb3IgdmFyaW91cyBtYXRjaCBwYXR0ZXJuczoKLSAgICAgICAgZm9yIChpbnQgaSA9IERUTS5OVFlQRVM7IGkgPCB0YXJnZXRzLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICBmaW5hbCBUZXN0U2VxIHRlc3RTZXEgPSBfdGVzdFNlcVtpXTsKLSAgICAgICAgICAgIC8vIEp1bXAgc3RyYWlnaHQgdG8gbmFtZXNwYWNlIHRlc3RzID8KLSAgICAgICAgICAgIGlmICgodGVzdFNlcSA9PSBudWxsKSB8fCAoaXNOYW1lc3BhY2VbaV0pKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGlzQXR0cmlidXRlW2ldKQotICAgICAgICAgICAgICAgICAgICB0YXJnZXRzW2ldID0gYXR0ck5hbWVzcGFjZUhhbmRsZTsKLSAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgIHRhcmdldHNbaV0gPSBlbGVtTmFtZXNwYWNlSGFuZGxlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gTWF0Y2ggb24gbm9kZSB0eXBlCi0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBpZiAoaXNBdHRyaWJ1dGVbaV0pCi0gICAgICAgICAgICAgICAgICAgIHRhcmdldHNbaV0gPSB0ZXN0U2VxLmNvbXBpbGUoY2xhc3NHZW4sIG1ldGhvZEdlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyTmFtZXNwYWNlSGFuZGxlKTsKLSAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgIHRhcmdldHNbaV0gPSB0ZXN0U2VxLmNvbXBpbGUoY2xhc3NHZW4sIG1ldGhvZEdlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtTmFtZXNwYWNlSGFuZGxlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGlmIChpbEtleSAhPSBudWxsKSBib2R5Lmluc2VydChpbEtleSk7Ci0KLSAgICAgICAgLy8gQXBwZW5kIGZpcnN0IGNvZGUgaW4gYXBwbHlUZW1wbGF0ZXMoKSAtIGdldCB0eXBlIG9mIGN1cnJlbnQgbm9kZQotICAgICAgICBmaW5hbCBpbnQgZ2V0VHlwZSA9IGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoRE9NX0lOVEYsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZ2V0RXhwYW5kZWRUeXBlSUQiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIihJKUkiKTsKLSAgICAgICAgYm9keS5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0gICAgICAgIGJvZHkuYXBwZW5kKG5ldyBJTE9BRChfY3VycmVudEluZGV4KSk7Ci0gICAgICAgIGJvZHkuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0UoZ2V0VHlwZSwgMikpOwotCi0gICAgICAgIC8vIEFwcGVuZCBzd2l0Y2goKSBzdGF0ZW1lbnQgLSBtYWluIGRpc3BhdGNoIGxvb3AgaW4gYXBwbHlUZW1wbGF0ZXMoKQotICAgICAgICBJbnN0cnVjdGlvbkhhbmRsZSBkaXNwID0gYm9keS5hcHBlbmQobmV3IFNXSVRDSCh0eXBlcywgdGFyZ2V0cywgaWhMb29wKSk7Ci0KLSAgICAgICAgLy8gQXBwZW5kIGFsbCB0aGUgImNhc2U6IiBzdGF0ZW1lbnRzCi0gICAgICAgIGFwcGVuZFRlc3RTZXF1ZW5jZXMoYm9keSk7Ci0gICAgICAgIC8vIEFwcGVuZCB0aGUgYWN0dWFsIHRlbXBsYXRlIGNvZGUKLSAgICAgICAgYXBwZW5kVGVtcGxhdGVDb2RlKGJvZHkpOwotCi0gICAgICAgIC8vIEFwcGVuZCBOUzoqIG5vZGUgdGVzdHMgKGlmIGFueSkKLSAgICAgICAgaWYgKG5zRWxlbSAhPSBudWxsKSBib2R5LmFwcGVuZChuc0VsZW0pOwotICAgICAgICAvLyBBcHBlbmQgTlM6QCogbm9kZSB0ZXN0cyAoaWYgYW55KQotICAgICAgICBpZiAobnNBdHRyICE9IG51bGwpIGJvZHkuYXBwZW5kKG5zQXR0cik7Ci0KLSAgICAgICAgLy8gQXBwZW5kIGRlZmF1bHQgYWN0aW9uIGZvciBlbGVtZW50IGFuZCByb290IG5vZGVzCi0gICAgICAgIGJvZHkuYXBwZW5kKGlsUmVjdXJzZSk7Ci0gICAgICAgIC8vIEFwcGVuZCBkZWZhdWx0IGFjdGlvbiBmb3IgdGV4dCBhbmQgYXR0cmlidXRlIG5vZGVzCi0gICAgICAgIGJvZHkuYXBwZW5kKGlsVGV4dCk7Ci0KLSAgICAgICAgLy8gcHV0dGluZyB0b2dldGhlciBjb25zdGl0dWVudCBpbnN0cnVjdGlvbiBsaXN0cwotICAgICAgICBtYWluSUwuYXBwZW5kKGJvZHkpOwotICAgICAgICAvLyBmYWxsIHRocm91Z2ggdG8gaWxMb29wCi0gICAgICAgIG1haW5JTC5hcHBlbmQoaWxMb29wKTsKLQotICAgICAgICBwZWVwSG9sZU9wdGltaXphdGlvbihtZXRob2RHZW4pOwotICAgICAgICBjbGFzc0dlbi5hZGRNZXRob2QobWV0aG9kR2VuKTsKLQotICAgICAgICAvLyBDb21waWxlIG1ldGhvZChzKSBmb3IgPHhzbDphcHBseS1pbXBvcnRzLz4gZm9yIHRoaXMgbW9kZQotICAgICAgICBpZiAoX2ltcG9ydExldmVscyAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmb3IgKE1hcC5FbnRyeTxJbnRlZ2VyLCBJbnRlZ2VyPiBlbnRyeSA6IF9pbXBvcnRMZXZlbHMuZW50cnlTZXQoKSkgewotICAgICAgICAgICAgICAgIGNvbXBpbGVBcHBseUltcG9ydHMoY2xhc3NHZW4sIGVudHJ5LmdldFZhbHVlKCksIGVudHJ5LmdldEtleSgpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBjb21waWxlVGVtcGxhdGVDYWxscyhDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW5zdHJ1Y3Rpb25IYW5kbGUgbmV4dCwgaW50IG1pbiwgaW50IG1heCl7Ci0gICAgICAgIGZvciAoVGVtcGxhdGUgdGVtcGxhdGUgOiBfbmVlZGVkVGVtcGxhdGVzLmtleVNldCgpKSB7Ci0gICAgICAgICAgICBmaW5hbCBpbnQgcHJlYyA9IHRlbXBsYXRlLmdldEltcG9ydFByZWNlZGVuY2UoKTsKLSAgICAgICAgICAgIGlmICgocHJlYyA+PSBtaW4pICYmIChwcmVjIDwgbWF4KSkgewotICAgICAgICAgICAgICAgIGlmICh0ZW1wbGF0ZS5oYXNDb250ZW50cygpKSB7Ci0gICAgICAgICAgICAgICAgICAgIEluc3RydWN0aW9uTGlzdCB0aWwgPSB0ZW1wbGF0ZS5jb21waWxlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICAgICAgICAgICAgICB0aWwuYXBwZW5kKG5ldyBHT1RPX1cobmV4dCkpOwotICAgICAgICAgICAgICAgICAgICBfdGVtcGxhdGVJTHMucHV0KHRlbXBsYXRlLCB0aWwpOwotICAgICAgICAgICAgICAgICAgICBfdGVtcGxhdGVJSHMucHV0KHRlbXBsYXRlLCB0aWwuZ2V0U3RhcnQoKSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAvLyBlbXB0eSB0ZW1wbGF0ZQotICAgICAgICAgICAgICAgICAgICBfdGVtcGxhdGVJSHMucHV0KHRlbXBsYXRlLCBuZXh0KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIHB1YmxpYyB2b2lkIGNvbXBpbGVBcHBseUltcG9ydHMoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIGludCBtaW4sIGludCBtYXgpIHsKLSAgICAgICAgZmluYWwgWFNMVEMgeHNsdGMgPSBjbGFzc0dlbi5nZXRQYXJzZXIoKS5nZXRYU0xUQygpOwotICAgICAgICBmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgICAgIGZpbmFsIFZlY3RvciBuYW1lcyAgICAgID0geHNsdGMuZ2V0TmFtZXNJbmRleCgpOwotCi0gICAgICAgIC8vIENsZWFyIHNvbWUgZGF0YXN0cnVjdHVyZXMKLSAgICAgICAgX25hbWVkVGVtcGxhdGVzID0gbmV3IEhhc2hNYXA8PigpOwotICAgICAgICBfbmVlZGVkVGVtcGxhdGVzID0gbmV3IEhhc2hNYXA8PigpOwotICAgICAgICBfdGVtcGxhdGVJSHMgPSBuZXcgSGFzaE1hcDw+KCk7Ci0gICAgICAgIF90ZW1wbGF0ZUlMcyA9IG5ldyBIYXNoTWFwPD4oKTsKLSAgICAgICAgX3BhdHRlcm5Hcm91cHMgPSBuZXcgVmVjdG9yWzMyXTsKLSAgICAgICAgX3Jvb3RQYXR0ZXJuID0gbnVsbDsKLQotICAgICAgICAvLyBJTVBPUlRBTlQ6IFNhdmUgb3JpZ25hbCAmIGNvbXBsZXRlIHNldCBvZiB0ZW1wbGF0ZXMhISEhCi0gICAgICAgIFZlY3RvciBvbGRUZW1wbGF0ZXMgPSBfdGVtcGxhdGVzOwotCi0gICAgICAgIC8vIEdhdGhlciB0ZW1wbGF0ZXMgdGhhdCBhcmUgd2l0aGluIHRoZSBzY29wZSBvZiB0aGlzIGltcG9ydAotICAgICAgICBfdGVtcGxhdGVzID0gbmV3IFZlY3RvcigpOwotICAgICAgICBmaW5hbCBFbnVtZXJhdGlvbiB0ZW1wbGF0ZXMgPSBvbGRUZW1wbGF0ZXMuZWxlbWVudHMoKTsKLSAgICAgICAgd2hpbGUgKHRlbXBsYXRlcy5oYXNNb3JlRWxlbWVudHMoKSkgewotICAgICAgICAgICAgZmluYWwgVGVtcGxhdGUgdGVtcGxhdGUgPSAoVGVtcGxhdGUpdGVtcGxhdGVzLm5leHRFbGVtZW50KCk7Ci0gICAgICAgICAgICBmaW5hbCBpbnQgcHJlYyA9IHRlbXBsYXRlLmdldEltcG9ydFByZWNlZGVuY2UoKTsKLSAgICAgICAgICAgIGlmICgocHJlYyA+PSBtaW4pICYmIChwcmVjIDwgbWF4KSkgYWRkVGVtcGxhdGUodGVtcGxhdGUpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gUHJvY2VzcyBhbGwgcGF0dGVybnMgZnJvbSB0aG9zZSB0ZW1wbGF0ZXMKLSAgICAgICAgcHJvY2Vzc1BhdHRlcm5zKF9rZXlzKTsKLQotICAgICAgICAvLyBDcmVhdGUgdGhlIGFwcGx5VGVtcGxhdGVzKCkgbWV0aG9kCi0gICAgICAgIGZpbmFsIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuVHlwZVtdIGFyZ1R5cGVzID0KLSAgICAgICAgICAgIG5ldyBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlR5cGVbNF07Ci0gICAgICAgIGFyZ1R5cGVzWzBdID0gVXRpbC5nZXRKQ1JlZlR5cGUoRE9NX0lOVEZfU0lHKTsKLSAgICAgICAgYXJnVHlwZXNbMV0gPSBVdGlsLmdldEpDUmVmVHlwZShOT0RFX0lURVJBVE9SX1NJRyk7Ci0gICAgICAgIGFyZ1R5cGVzWzJdID0gVXRpbC5nZXRKQ1JlZlR5cGUoVFJBTlNMRVRfT1VUUFVUX1NJRyk7Ci0gICAgICAgIGFyZ1R5cGVzWzNdID0gY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5UeXBlLklOVDsKLQotICAgICAgICBmaW5hbCBTdHJpbmdbXSBhcmdOYW1lcyA9IG5ldyBTdHJpbmdbNF07Ci0gICAgICAgIGFyZ05hbWVzWzBdID0gRE9DVU1FTlRfUE5BTUU7Ci0gICAgICAgIGFyZ05hbWVzWzFdID0gSVRFUkFUT1JfUE5BTUU7Ci0gICAgICAgIGFyZ05hbWVzWzJdID0gVFJBTlNMRVRfT1VUUFVUX1BOQU1FOwotICAgICAgICBhcmdOYW1lc1szXSA9IE5PREVfUE5BTUU7Ci0KLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IG1haW5JTCA9IG5ldyBJbnN0cnVjdGlvbkxpc3QoKTsKLSAgICAgICAgZmluYWwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiA9Ci0gICAgICAgICAgICBuZXcgTWV0aG9kR2VuZXJhdG9yKEFDQ19QVUJMSUMgfCBBQ0NfRklOQUwsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuVHlwZS5WT0lELAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmdUeXBlcywgYXJnTmFtZXMsIGZ1bmN0aW9uTmFtZSgpKydfJyttYXgsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldENsYXNzTmFtZSgpLCBtYWluSUwsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpKTsKLSAgICAgICAgbWV0aG9kR2VuLmFkZEV4Y2VwdGlvbigiY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLlRyYW5zbGV0RXhjZXB0aW9uIik7Ci0KLSAgICAgICAgLy8gQ3JlYXRlIHRoZSBsb2NhbCB2YXJpYWJsZSB0byBob2xkIHRoZSBjdXJyZW50IG5vZGUKLSAgICAgICAgZmluYWwgTG9jYWxWYXJpYWJsZUdlbiBjdXJyZW50OwotICAgICAgICBjdXJyZW50ID0gbWV0aG9kR2VuLmFkZExvY2FsVmFyaWFibGUyKCJjdXJyZW50IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlR5cGUuSU5ULAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwpOwotICAgICAgICBfY3VycmVudEluZGV4ID0gY3VycmVudC5nZXRJbmRleCgpOwotCi0gICAgICAgIG1haW5JTC5hcHBlbmQobmV3IElMT0FEKG1ldGhvZEdlbi5nZXRMb2NhbEluZGV4KE5PREVfUE5BTUUpKSk7Ci0gICAgICAgIGN1cnJlbnQuc2V0U3RhcnQobWFpbklMLmFwcGVuZChuZXcgSVNUT1JFKF9jdXJyZW50SW5kZXgpKSk7Ci0KLSAgICAgICAgLy8gQ3JlYXRlIHRoZSAiYm9keSIgaW5zdHJ1Y3Rpb24gbGlzdCB0aGF0IHdpbGwgZXZlbnR1YWxseSBob2xkIHRoZQotICAgICAgICAvLyBjb2RlIGZvciB0aGUgZW50aXJlIG1ldGhvZCAob3RoZXIgSUxzIHdpbGwgYmUgYXBwZW5kZWQpLgotICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgYm9keSA9IG5ldyBJbnN0cnVjdGlvbkxpc3QoKTsKLSAgICAgICAgYm9keS5hcHBlbmQoTk9QKTsKLQotICAgICAgICAvLyBDcmVhdGUgYW4gaW5zdHJ1Y3Rpb24gbGlzdCB0aGF0IGNvbnRhaW5zIHRoZSBkZWZhdWx0IG5leHQtbm9kZQotICAgICAgICAvLyBpdGVyYXRpb24KLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsTG9vcCA9IG5ldyBJbnN0cnVjdGlvbkxpc3QoKTsKLSAgICAgICAgaWxMb29wLmFwcGVuZChSRVRVUk4pOwotICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkhhbmRsZSBpaExvb3AgPSBpbExvb3AuZ2V0U3RhcnQoKTsKLQotICAgICAgICAvLyBDb21waWxlIGRlZmF1bHQgaGFuZGxpbmcgb2YgZWxlbWVudHMgKHRyYXZlcnNlIGNoaWxkcmVuKQotICAgICAgICBJbnN0cnVjdGlvbkxpc3QgaWxSZWN1cnNlID0KLSAgICAgICAgICAgIGNvbXBpbGVEZWZhdWx0UmVjdXJzaW9uKGNsYXNzR2VuLCBtZXRob2RHZW4sIGloTG9vcCk7Ci0gICAgICAgIEluc3RydWN0aW9uSGFuZGxlIGloUmVjdXJzZSA9IGlsUmVjdXJzZS5nZXRTdGFydCgpOwotCi0gICAgICAgIC8vIENvbXBpbGUgZGVmYXVsdCBoYW5kbGluZyBvZiB0ZXh0L2F0dHJpYnV0ZSBub2RlcyAob3V0cHV0IHRleHQpCi0gICAgICAgIEluc3RydWN0aW9uTGlzdCBpbFRleHQgPQotICAgICAgICAgICAgY29tcGlsZURlZmF1bHRUZXh0KGNsYXNzR2VuLCBtZXRob2RHZW4sIGloTG9vcCk7Ci0gICAgICAgIEluc3RydWN0aW9uSGFuZGxlIGloVGV4dCA9IGlsVGV4dC5nZXRTdGFydCgpOwotCi0gICAgICAgIC8vIERpc3Rpbmd1aXNoIGF0dHJpYnV0ZS9lbGVtZW50L25hbWVzcGFjZSB0ZXN0cyBmb3IgZnVydGhlciBwcm9jZXNzaW5nCi0gICAgICAgIGZpbmFsIGludFtdIHR5cGVzID0gbmV3IGludFtEVE0uTlRZUEVTICsgbmFtZXMuc2l6ZSgpXTsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB0eXBlcy5sZW5ndGg7IGkrKykgewotICAgICAgICAgICAgdHlwZXNbaV0gPSBpOwotICAgICAgICB9Ci0KLSAgICAgICAgZmluYWwgYm9vbGVhbltdIGlzQXR0cmlidXRlID0gbmV3IGJvb2xlYW5bdHlwZXMubGVuZ3RoXTsKLSAgICAgICAgZmluYWwgYm9vbGVhbltdIGlzTmFtZXNwYWNlID0gbmV3IGJvb2xlYW5bdHlwZXMubGVuZ3RoXTsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuYW1lcy5zaXplKCk7IGkrKykgewotICAgICAgICAgICAgZmluYWwgU3RyaW5nIG5hbWUgPSAoU3RyaW5nKW5hbWVzLmVsZW1lbnRBdChpKTsKLSAgICAgICAgICAgIGlzQXR0cmlidXRlW2krRFRNLk5UWVBFU10gPSBpc0F0dHJpYnV0ZU5hbWUobmFtZSk7Ci0gICAgICAgICAgICBpc05hbWVzcGFjZVtpK0RUTS5OVFlQRVNdID0gaXNOYW1lc3BhY2VOYW1lKG5hbWUpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gQ29tcGlsZSBhbGwgdGVtcGxhdGVzIC0gcmVnYXJkbGVzcyBvZiBwYXR0ZXJuIHR5cGUKLSAgICAgICAgY29tcGlsZVRlbXBsYXRlQ2FsbHMoY2xhc3NHZW4sIG1ldGhvZEdlbiwgaWhMb29wLCBtaW4sIG1heCk7Ci0KLSAgICAgICAgLy8gSGFuZGxlIHRlbXBsYXRlIHdpdGggZXhwbGljaXQgIioiIHBhdHRlcm4KLSAgICAgICAgZmluYWwgVGVzdFNlcSBlbGVtVGVzdCA9IF90ZXN0U2VxW0RUTS5FTEVNRU5UX05PREVdOwotICAgICAgICBJbnN0cnVjdGlvbkhhbmRsZSBpaEVsZW0gPSBpaFJlY3Vyc2U7Ci0gICAgICAgIGlmIChlbGVtVGVzdCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpaEVsZW0gPSBlbGVtVGVzdC5jb21waWxlKGNsYXNzR2VuLCBtZXRob2RHZW4sIGloTG9vcCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBIYW5kbGUgdGVtcGxhdGUgd2l0aCBleHBsaWNpdCAiQCoiIHBhdHRlcm4KLSAgICAgICAgZmluYWwgVGVzdFNlcSBhdHRyVGVzdCA9IF90ZXN0U2VxW0RUTS5BVFRSSUJVVEVfTk9ERV07Ci0gICAgICAgIEluc3RydWN0aW9uSGFuZGxlIGloQXR0ciA9IGloTG9vcDsKLSAgICAgICAgaWYgKGF0dHJUZXN0ICE9IG51bGwpIHsKLSAgICAgICAgICAgIGloQXR0ciA9IGF0dHJUZXN0LmNvbXBpbGUoY2xhc3NHZW4sIG1ldGhvZEdlbiwgaWhBdHRyKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIERvIHRlc3RzIGZvciBpZCgpIGFuZCBrZXkoKSBwYXR0ZXJucyBmaXJzdAotICAgICAgICBJbnN0cnVjdGlvbkxpc3QgaWxLZXkgPSBudWxsOwotICAgICAgICBpZiAoX2lkeFRlc3RTZXEgIT0gbnVsbCkgewotICAgICAgICAgICAgaWxLZXkgPSBfaWR4VGVzdFNlcS5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIElmIHRoZXJlIGlzIGEgbWF0Y2ggb24gbm9kZSgpIHdlIG5lZWQgdG8gcmVwbGFjZSBpaEVsZW0KLSAgICAgICAgLy8gYW5kIGloVGV4dCBpZiB0aGUgcHJpb3JpdHkgb2Ygbm9kZSgpIGlzIGhpZ2hlcgotICAgICAgICBpZiAoX2NoaWxkTm9kZVRlc3RTZXEgIT0gbnVsbCkgewotICAgICAgICAgICAgLy8gQ29tcGFyZSBwcmlvcml0aWVzIG9mIG5vZGUoKSBhbmQgIioiCi0gICAgICAgICAgICBkb3VibGUgbm9kZVByaW8gPSBfY2hpbGROb2RlVGVzdFNlcS5nZXRQcmlvcml0eSgpOwotICAgICAgICAgICAgaW50ICAgIG5vZGVQb3MgID0gX2NoaWxkTm9kZVRlc3RTZXEuZ2V0UG9zaXRpb24oKTsKLSAgICAgICAgICAgIGRvdWJsZSBlbGVtUHJpbyA9ICgwIC0gRG91YmxlLk1BWF9WQUxVRSk7Ci0gICAgICAgICAgICBpbnQgICAgZWxlbVBvcyAgPSBJbnRlZ2VyLk1JTl9WQUxVRTsKLQotICAgICAgICAgICAgaWYgKGVsZW1UZXN0ICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBlbGVtUHJpbyA9IGVsZW1UZXN0LmdldFByaW9yaXR5KCk7Ci0gICAgICAgICAgICAgICAgZWxlbVBvcyAgPSBlbGVtVGVzdC5nZXRQb3NpdGlvbigpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAoZWxlbVByaW8gPT0gRG91YmxlLk5hTiB8fCBlbGVtUHJpbyA8IG5vZGVQcmlvIHx8Ci0gICAgICAgICAgICAgICAgKGVsZW1QcmlvID09IG5vZGVQcmlvICYmIGVsZW1Qb3MgPCBub2RlUG9zKSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBpaEVsZW0gPSBfY2hpbGROb2RlVGVzdFNlcS5jb21waWxlKGNsYXNzR2VuLCBtZXRob2RHZW4sIGloTG9vcCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIENvbXBhcmUgcHJpb3JpdGllcyBvZiBub2RlKCkgYW5kIHRleHQoKQotICAgICAgICAgICAgZmluYWwgVGVzdFNlcSB0ZXh0VGVzdCA9IF90ZXN0U2VxW0RUTS5URVhUX05PREVdOwotICAgICAgICAgICAgZG91YmxlIHRleHRQcmlvID0gKDAgLSBEb3VibGUuTUFYX1ZBTFVFKTsKLSAgICAgICAgICAgIGludCAgICB0ZXh0UG9zICA9IEludGVnZXIuTUlOX1ZBTFVFOwotCi0gICAgICAgICAgICBpZiAodGV4dFRlc3QgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHRleHRQcmlvID0gdGV4dFRlc3QuZ2V0UHJpb3JpdHkoKTsKLSAgICAgICAgICAgICAgICB0ZXh0UG9zICA9IHRleHRUZXN0LmdldFBvc2l0aW9uKCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmICh0ZXh0UHJpbyA9PSBEb3VibGUuTmFOIHx8IHRleHRQcmlvIDwgbm9kZVByaW8gfHwKLSAgICAgICAgICAgICAgICAodGV4dFByaW8gPT0gbm9kZVByaW8gJiYgdGV4dFBvcyA8IG5vZGVQb3MpKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIGloVGV4dCA9IF9jaGlsZE5vZGVUZXN0U2VxLmNvbXBpbGUoY2xhc3NHZW4sIG1ldGhvZEdlbiwgaWhMb29wKTsKLSAgICAgICAgICAgICAgICBfdGVzdFNlcVtEVE0uVEVYVF9OT0RFXSA9IF9jaGlsZE5vZGVUZXN0U2VxOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gSGFuZGxlIHRlbXBsYXRlcyB3aXRoICJuczoqIiBwYXR0ZXJuCi0gICAgICAgIEluc3RydWN0aW9uSGFuZGxlIGVsZW1OYW1lc3BhY2VIYW5kbGUgPSBpaEVsZW07Ci0gICAgICAgIEluc3RydWN0aW9uTGlzdCBuc0VsZW0gPSBjb21waWxlTmFtZXNwYWNlcyhjbGFzc0dlbiwgbWV0aG9kR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNOYW1lc3BhY2UsIGlzQXR0cmlidXRlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UsIGloRWxlbSk7Ci0gICAgICAgIGlmIChuc0VsZW0gIT0gbnVsbCkgZWxlbU5hbWVzcGFjZUhhbmRsZSA9IG5zRWxlbS5nZXRTdGFydCgpOwotCi0gICAgICAgIC8vIEhhbmRsZSB0ZW1wbGF0ZXMgd2l0aCAibnM6QCoiIHBhdHRlcm4KLSAgICAgICAgSW5zdHJ1Y3Rpb25MaXN0IG5zQXR0ciA9IGNvbXBpbGVOYW1lc3BhY2VzKGNsYXNzR2VuLCBtZXRob2RHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc05hbWVzcGFjZSwgaXNBdHRyaWJ1dGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlLCBpaEF0dHIpOwotICAgICAgICBJbnN0cnVjdGlvbkhhbmRsZSBhdHRyTmFtZXNwYWNlSGFuZGxlID0gaWhBdHRyOwotICAgICAgICBpZiAobnNBdHRyICE9IG51bGwpIGF0dHJOYW1lc3BhY2VIYW5kbGUgPSBuc0F0dHIuZ2V0U3RhcnQoKTsKLQotICAgICAgICAvLyBIYW5kbGUgdGVtcGxhdGVzIHdpdGggIm5zOmVsZW0iIG9yICJuczpAYXR0ciIgcGF0dGVybgotICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkhhbmRsZVtdIHRhcmdldHMgPSBuZXcgSW5zdHJ1Y3Rpb25IYW5kbGVbdHlwZXMubGVuZ3RoXTsKLSAgICAgICAgZm9yIChpbnQgaSA9IERUTS5OVFlQRVM7IGkgPCB0YXJnZXRzLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICBmaW5hbCBUZXN0U2VxIHRlc3RTZXEgPSBfdGVzdFNlcVtpXTsKLSAgICAgICAgICAgIC8vIEp1bXAgc3RyYWlnaHQgdG8gbmFtZXNwYWNlIHRlc3RzID8KLSAgICAgICAgICAgIGlmIChpc05hbWVzcGFjZVtpXSkgewotICAgICAgICAgICAgICAgIGlmIChpc0F0dHJpYnV0ZVtpXSkKLSAgICAgICAgICAgICAgICAgICAgdGFyZ2V0c1tpXSA9IGF0dHJOYW1lc3BhY2VIYW5kbGU7Ci0gICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICB0YXJnZXRzW2ldID0gZWxlbU5hbWVzcGFjZUhhbmRsZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIFRlc3QgZmlyc3QsIHRoZW4ganVtcCB0byBuYW1lc3BhY2UgdGVzdHMKLSAgICAgICAgICAgIGVsc2UgaWYgKHRlc3RTZXEgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGlmIChpc0F0dHJpYnV0ZVtpXSkKLSAgICAgICAgICAgICAgICAgICAgdGFyZ2V0c1tpXSA9IHRlc3RTZXEuY29tcGlsZShjbGFzc0dlbiwgbWV0aG9kR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJOYW1lc3BhY2VIYW5kbGUpOwotICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgICAgdGFyZ2V0c1tpXSA9IHRlc3RTZXEuY29tcGlsZShjbGFzc0dlbiwgbWV0aG9kR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1OYW1lc3BhY2VIYW5kbGUpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgdGFyZ2V0c1tpXSA9IGloTG9vcDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIEhhbmRsZSBwYXR0ZXJuIHdpdGggbWF0Y2ggb24gcm9vdCBub2RlIC0gZGVmYXVsdDogdHJhdmVyc2UgY2hpbGRyZW4KLSAgICAgICAgdGFyZ2V0c1tEVE0uUk9PVF9OT0RFXSA9IF9yb290UGF0dGVybiAhPSBudWxsCi0gICAgICAgICAgICA/IGdldFRlbXBsYXRlSW5zdHJ1Y3Rpb25IYW5kbGUoX3Jvb3RQYXR0ZXJuLmdldFRlbXBsYXRlKCkpCi0gICAgICAgICAgICA6IGloUmVjdXJzZTsKLSAgICAgICAgLy8gSGFuZGxlIHBhdHRlcm4gd2l0aCBtYXRjaCBvbiByb290IG5vZGUgLSBkZWZhdWx0OiB0cmF2ZXJzZSBjaGlsZHJlbgotICAgICAgICB0YXJnZXRzW0RUTS5ET0NVTUVOVF9OT0RFXSA9IF9yb290UGF0dGVybiAhPSBudWxsCi0gICAgICAgICAgICA/IGdldFRlbXBsYXRlSW5zdHJ1Y3Rpb25IYW5kbGUoX3Jvb3RQYXR0ZXJuLmdldFRlbXBsYXRlKCkpCi0gICAgICAgICAgICA6IGloUmVjdXJzZTsgICAgLy8gJUhaJTogIFdhcyBpaExvb3AgaW4gWFNMVENfRFRNIGJyYW5jaAotCi0gICAgICAgIC8vIEhhbmRsZSBhbnkgcGF0dGVybiB3aXRoIG1hdGNoIG9uIHRleHQgbm9kZXMgLSBkZWZhdWx0OiBsb29wCi0gICAgICAgIHRhcmdldHNbRFRNLlRFWFRfTk9ERV0gPSBfdGVzdFNlcVtEVE0uVEVYVF9OT0RFXSAhPSBudWxsCi0gICAgICAgICAgICA/IF90ZXN0U2VxW0RUTS5URVhUX05PREVdLmNvbXBpbGUoY2xhc3NHZW4sIG1ldGhvZEdlbiwgaWhUZXh0KQotICAgICAgICAgICAgOiBpaFRleHQ7Ci0KLSAgICAgICAgLy8gVGhpcyBET00tdHlwZSBpcyBub3QgaW4gdXNlIC0gZGVmYXVsdDogcHJvY2VzcyBuZXh0IG5vZGUKLSAgICAgICAgdGFyZ2V0c1tEVE0uTkFNRVNQQUNFX05PREVdID0gaWhMb29wOwotCi0gICAgICAgIC8vIE1hdGNoIHVua25vd24gZWxlbWVudCBpbiBET00gLSBkZWZhdWx0OiBjaGVjayBmb3IgbmFtZXNwYWNlIG1hdGNoCi0gICAgICAgIHRhcmdldHNbRFRNLkVMRU1FTlRfTk9ERV0gPSBlbGVtTmFtZXNwYWNlSGFuZGxlOwotCi0gICAgICAgIC8vIE1hdGNoIHVua25vd24gYXR0cmlidXRlIGluIERPTSAtIGRlZmF1bHQ6IGNoZWNrIGZvciBuYW1lc3BhY2UgbWF0Y2gKLSAgICAgICAgdGFyZ2V0c1tEVE0uQVRUUklCVVRFX05PREVdID0gYXR0ck5hbWVzcGFjZUhhbmRsZTsKLQotICAgICAgICAvLyBNYXRjaCBvbiBwcm9jZXNzaW5nIGluc3RydWN0aW9uIC0gZGVmYXVsdDogbG9vcAotICAgICAgICBJbnN0cnVjdGlvbkhhbmRsZSBpaFBJID0gaWhMb29wOwotICAgICAgICBpZiAoX2NoaWxkTm9kZVRlc3RTZXEgIT0gbnVsbCkgaWhQSSA9IGloRWxlbTsKLSAgICAgICAgaWYgKF90ZXN0U2VxW0RUTS5QUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREVdICE9IG51bGwpIHsKLSAgICAgICAgICAgIHRhcmdldHNbRFRNLlBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERV0gPQotICAgICAgICAgICAgICAgIF90ZXN0U2VxW0RUTS5QUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREVdLgotICAgICAgICAgICAgICAgIGNvbXBpbGUoY2xhc3NHZW4sIG1ldGhvZEdlbiwgaWhQSSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICB0YXJnZXRzW0RUTS5QUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREVdID0gaWhQSTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIE1hdGNoIG9uIGNvbW1lbnRzIC0gZGVmYXVsdDogcHJvY2VzcyBuZXh0IG5vZGUKLSAgICAgICAgSW5zdHJ1Y3Rpb25IYW5kbGUgaWhDb21tZW50ID0gaWhMb29wOwotICAgICAgICBpZiAoX2NoaWxkTm9kZVRlc3RTZXEgIT0gbnVsbCkgaWhDb21tZW50ID0gaWhFbGVtOwotICAgICAgICB0YXJnZXRzW0RUTS5DT01NRU5UX05PREVdID0gX3Rlc3RTZXFbRFRNLkNPTU1FTlRfTk9ERV0gIT0gbnVsbAotICAgICAgICAgICAgPyBfdGVzdFNlcVtEVE0uQ09NTUVOVF9OT0RFXS5jb21waWxlKGNsYXNzR2VuLCBtZXRob2RHZW4sIGloQ29tbWVudCkKLSAgICAgICAgICAgIDogaWhDb21tZW50OwotCi0gICAgICAgICAgICAgICAgLy8gVGhpcyBET00tdHlwZSBpcyBub3QgaW4gdXNlIC0gZGVmYXVsdDogcHJvY2VzcyBuZXh0IG5vZGUKLSAgICAgICAgdGFyZ2V0c1tEVE0uQ0RBVEFfU0VDVElPTl9OT0RFXSA9IGloTG9vcDsKLQotICAgICAgICAvLyBUaGlzIERPTS10eXBlIGlzIG5vdCBpbiB1c2UgLSBkZWZhdWx0OiBwcm9jZXNzIG5leHQgbm9kZQotICAgICAgICB0YXJnZXRzW0RUTS5ET0NVTUVOVF9GUkFHTUVOVF9OT0RFXSA9IGloTG9vcDsKLQotICAgICAgICAvLyBUaGlzIERPTS10eXBlIGlzIG5vdCBpbiB1c2UgLSBkZWZhdWx0OiBwcm9jZXNzIG5leHQgbm9kZQotICAgICAgICB0YXJnZXRzW0RUTS5ET0NVTUVOVF9UWVBFX05PREVdID0gaWhMb29wOwotCi0gICAgICAgIC8vIFRoaXMgRE9NLXR5cGUgaXMgbm90IGluIHVzZSAtIGRlZmF1bHQ6IHByb2Nlc3MgbmV4dCBub2RlCi0gICAgICAgIHRhcmdldHNbRFRNLkVOVElUWV9OT0RFXSA9IGloTG9vcDsKLQotICAgICAgICAvLyBUaGlzIERPTS10eXBlIGlzIG5vdCBpbiB1c2UgLSBkZWZhdWx0OiBwcm9jZXNzIG5leHQgbm9kZQotICAgICAgICB0YXJnZXRzW0RUTS5FTlRJVFlfUkVGRVJFTkNFX05PREVdID0gaWhMb29wOwotCi0gICAgICAgIC8vIFRoaXMgRE9NLXR5cGUgaXMgbm90IGluIHVzZSAtIGRlZmF1bHQ6IHByb2Nlc3MgbmV4dCBub2RlCi0gICAgICAgIHRhcmdldHNbRFRNLk5PVEFUSU9OX05PREVdID0gaWhMb29wOwotCi0KLQotICAgICAgICAvLyBOb3cgY29tcGlsZSB0ZXN0IHNlcXVlbmNlcyBmb3IgdmFyaW91cyBtYXRjaCBwYXR0ZXJuczoKLSAgICAgICAgZm9yIChpbnQgaSA9IERUTS5OVFlQRVM7IGkgPCB0YXJnZXRzLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICBmaW5hbCBUZXN0U2VxIHRlc3RTZXEgPSBfdGVzdFNlcVtpXTsKLSAgICAgICAgICAgIC8vIEp1bXAgc3RyYWlnaHQgdG8gbmFtZXNwYWNlIHRlc3RzID8KLSAgICAgICAgICAgIGlmICgodGVzdFNlcSA9PSBudWxsKSB8fCAoaXNOYW1lc3BhY2VbaV0pKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGlzQXR0cmlidXRlW2ldKQotICAgICAgICAgICAgICAgICAgICB0YXJnZXRzW2ldID0gYXR0ck5hbWVzcGFjZUhhbmRsZTsKLSAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgIHRhcmdldHNbaV0gPSBlbGVtTmFtZXNwYWNlSGFuZGxlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gTWF0Y2ggb24gbm9kZSB0eXBlCi0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBpZiAoaXNBdHRyaWJ1dGVbaV0pCi0gICAgICAgICAgICAgICAgICAgIHRhcmdldHNbaV0gPSB0ZXN0U2VxLmNvbXBpbGUoY2xhc3NHZW4sIG1ldGhvZEdlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyTmFtZXNwYWNlSGFuZGxlKTsKLSAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgIHRhcmdldHNbaV0gPSB0ZXN0U2VxLmNvbXBpbGUoY2xhc3NHZW4sIG1ldGhvZEdlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtTmFtZXNwYWNlSGFuZGxlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGlmIChpbEtleSAhPSBudWxsKSBib2R5Lmluc2VydChpbEtleSk7Ci0KLSAgICAgICAgLy8gQXBwZW5kIGZpcnN0IGNvZGUgaW4gYXBwbHlUZW1wbGF0ZXMoKSAtIGdldCB0eXBlIG9mIGN1cnJlbnQgbm9kZQotICAgICAgICBmaW5hbCBpbnQgZ2V0VHlwZSA9IGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoRE9NX0lOVEYsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZ2V0RXhwYW5kZWRUeXBlSUQiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIihJKUkiKTsKLSAgICAgICAgYm9keS5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0gICAgICAgIGJvZHkuYXBwZW5kKG5ldyBJTE9BRChfY3VycmVudEluZGV4KSk7Ci0gICAgICAgIGJvZHkuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0UoZ2V0VHlwZSwgMikpOwotCi0gICAgICAgIC8vIEFwcGVuZCBzd2l0Y2goKSBzdGF0ZW1lbnQgLSBtYWluIGRpc3BhdGNoIGxvb3AgaW4gYXBwbHlUZW1wbGF0ZXMoKQotICAgICAgICBJbnN0cnVjdGlvbkhhbmRsZSBkaXNwID0gYm9keS5hcHBlbmQobmV3IFNXSVRDSCh0eXBlcyx0YXJnZXRzLGloTG9vcCkpOwotCi0gICAgICAgIC8vIEFwcGVuZCBhbGwgdGhlICJjYXNlOiIgc3RhdGVtZW50cwotICAgICAgICBhcHBlbmRUZXN0U2VxdWVuY2VzKGJvZHkpOwotICAgICAgICAvLyBBcHBlbmQgdGhlIGFjdHVhbCB0ZW1wbGF0ZSBjb2RlCi0gICAgICAgIGFwcGVuZFRlbXBsYXRlQ29kZShib2R5KTsKLQotICAgICAgICAvLyBBcHBlbmQgTlM6KiBub2RlIHRlc3RzIChpZiBhbnkpCi0gICAgICAgIGlmIChuc0VsZW0gIT0gbnVsbCkgYm9keS5hcHBlbmQobnNFbGVtKTsKLSAgICAgICAgLy8gQXBwZW5kIE5TOkAqIG5vZGUgdGVzdHMgKGlmIGFueSkKLSAgICAgICAgaWYgKG5zQXR0ciAhPSBudWxsKSBib2R5LmFwcGVuZChuc0F0dHIpOwotCi0gICAgICAgIC8vIEFwcGVuZCBkZWZhdWx0IGFjdGlvbiBmb3IgZWxlbWVudCBhbmQgcm9vdCBub2RlcwotICAgICAgICBib2R5LmFwcGVuZChpbFJlY3Vyc2UpOwotICAgICAgICAvLyBBcHBlbmQgZGVmYXVsdCBhY3Rpb24gZm9yIHRleHQgYW5kIGF0dHJpYnV0ZSBub2RlcwotICAgICAgICBib2R5LmFwcGVuZChpbFRleHQpOwotCi0gICAgICAgIC8vIHB1dHRpbmcgdG9nZXRoZXIgY29uc3RpdHVlbnQgaW5zdHJ1Y3Rpb24gbGlzdHMKLSAgICAgICAgbWFpbklMLmFwcGVuZChib2R5KTsKLQotICAgICAgICAvLyBNYXJrIHRoZSBlbmQgb2YgdGhlIGxpdmUgcmFuZ2UgZm9yIHRoZSAiY3VycmVudCIgdmFyaWFibGUKLSAgICAgICAgY3VycmVudC5zZXRFbmQoYm9keS5nZXRFbmQoKSk7Ci0KLSAgICAgICAgLy8gZmFsbCB0aHJvdWdoIHRvIGlsTG9vcAotICAgICAgICBtYWluSUwuYXBwZW5kKGlsTG9vcCk7Ci0KLSAgICAgICAgcGVlcEhvbGVPcHRpbWl6YXRpb24obWV0aG9kR2VuKTsKLSAgICAgICAgY2xhc3NHZW4uYWRkTWV0aG9kKG1ldGhvZEdlbik7Ci0KLSAgICAgICAgLy8gUmVzdG9yZSBvcmlnaW5hbCAoY29tcGxldGUpIHNldCBvZiB0ZW1wbGF0ZXMgZm9yIHRoaXMgdHJhbnNmb3JtYXRpb24KLSAgICAgICAgX3RlbXBsYXRlcyA9IG9sZFRlbXBsYXRlczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgICogUGVlcGhvbGUgb3B0aW1pemF0aW9uLgotICAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgcGVlcEhvbGVPcHRpbWl6YXRpb24oTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotICAgICAgICBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0gICAgICAgIEluc3RydWN0aW9uRmluZGVyIGZpbmQgPSBuZXcgSW5zdHJ1Y3Rpb25GaW5kZXIoaWwpOwotICAgICAgICBJbnN0cnVjdGlvbkhhbmRsZSBpaDsKLSAgICAgICAgU3RyaW5nIHBhdHRlcm47Ci0KLSAgICAgICAgLy8gTG9hZEluc3RydWN0aW9uLCBQT1AgPT4gKHJlbW92ZWQpCi0gICAgICAgIC8vIHBhdHRlcm4gPSAiTG9hZEluc3RydWN0aW9uIFBPUCI7Ci0gICAgICAgIC8vIGNoYW5nZWQgdG8gbG93ZXIgY2FzZSAtIGNoYW5naW5nIHRvIGFsbCBsb3dlciBjYXNlIGFsdGhvdWdoIG9ubHkgdGhlIGluc3RydWN0aW9uIHdpdGggY2FwaXRhbCBJCi0gICAgICAgIC8vIGlzIGNyZWF0aW5nIGEgcHJvYmxlbSBpbiB0aGUgVHVya2lzaCBsb2NhbGUKLSAgICAgICAgcGF0dGVybiA9ICJsb2FkaW5zdHJ1Y3Rpb24gcG9wIjsKLQotICAgICAgICBmb3IgKEl0ZXJhdG9yIGl0ZXIgPSBmaW5kLnNlYXJjaChwYXR0ZXJuKTsgaXRlci5oYXNOZXh0KCk7KSB7Ci0gICAgICAgICAgICBJbnN0cnVjdGlvbkhhbmRsZVtdIG1hdGNoID0gKEluc3RydWN0aW9uSGFuZGxlW10pIGl0ZXIubmV4dCgpOwotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICBpZiAoIW1hdGNoWzBdLmhhc1RhcmdldGVycygpICYmICFtYXRjaFsxXS5oYXNUYXJnZXRlcnMoKSkgewotICAgICAgICAgICAgICAgICAgICBpbC5kZWxldGUobWF0Y2hbMF0sIG1hdGNoWzFdKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXRjaCAoVGFyZ2V0TG9zdEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgLy8gVE9ETzogbW92ZSB0YXJnZXQgZG93biBpbnRvIHRoZSBsaXN0Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBJTE9BRF9OLCBJTE9BRF9OLCBTV0FQLCBJU1RPUkVfTiA9PiBJTE9BRF9OCi0gICAgICAgIC8vIHBhdHRlcm4gPSAiSUxPQUQgSUxPQUQgU1dBUCBJU1RPUkUiOwotICAgICAgICAvLyBjaGFuZ2VkIHRvIGxvd2VyIGNhc2UgLSBjaGFuZ2luZyB0byBhbGwgbG93ZXIgY2FzZSBhbHRob3VnaCBvbmx5IHRoZSBpbnN0cnVjdGlvbiB3aXRoIGNhcGl0YWwgSQotICAgICAgICAvLyBpcyBjcmVhdGluZyBhIHByb2JsZW0gaW4gdGhlIFR1cmtpc2ggbG9jYWxlCi0gICAgICAgIHBhdHRlcm4gPSAiaWxvYWQgaWxvYWQgc3dhcCBpc3RvcmUiOwotICAgICAgICBmb3IgKEl0ZXJhdG9yIGl0ZXIgPSBmaW5kLnNlYXJjaChwYXR0ZXJuKTsgaXRlci5oYXNOZXh0KCk7KSB7Ci0gICAgICAgICAgICBJbnN0cnVjdGlvbkhhbmRsZVtdIG1hdGNoID0gKEluc3RydWN0aW9uSGFuZGxlW10pIGl0ZXIubmV4dCgpOwotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklMT0FEIGlsb2FkMSA9Ci0gICAgICAgICAgICAgICAgICAgIChjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklMT0FEKSBtYXRjaFswXS5nZXRJbnN0cnVjdGlvbigpOwotICAgICAgICAgICAgICAgIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSUxPQUQgaWxvYWQyID0KLSAgICAgICAgICAgICAgICAgICAgKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSUxPQUQpIG1hdGNoWzFdLmdldEluc3RydWN0aW9uKCk7Ci0gICAgICAgICAgICAgICAgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JU1RPUkUgaXN0b3JlID0KLSAgICAgICAgICAgICAgICAgICAgKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSVNUT1JFKSBtYXRjaFszXS5nZXRJbnN0cnVjdGlvbigpOwotCi0gICAgICAgICAgICAgICAgaWYgKCFtYXRjaFsxXS5oYXNUYXJnZXRlcnMoKSAmJgotICAgICAgICAgICAgICAgICAgICAhbWF0Y2hbMl0uaGFzVGFyZ2V0ZXJzKCkgJiYKLSAgICAgICAgICAgICAgICAgICAgIW1hdGNoWzNdLmhhc1RhcmdldGVycygpICYmCi0gICAgICAgICAgICAgICAgICAgIGlsb2FkMS5nZXRJbmRleCgpID09IGlsb2FkMi5nZXRJbmRleCgpICYmCi0gICAgICAgICAgICAgICAgICAgIGlsb2FkMi5nZXRJbmRleCgpID09IGlzdG9yZS5nZXRJbmRleCgpKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgaWwuZGVsZXRlKG1hdGNoWzFdLCBtYXRjaFszXSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2F0Y2ggKFRhcmdldExvc3RFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgIC8vIFRPRE86IG1vdmUgdGFyZ2V0IGRvd24gaW50byB0aGUgbGlzdAotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gTG9hZEluc3RydWN0aW9uX04sIExvYWRJbnN0cnVjdGlvbl9NLCBTV0FQID0+IExvYWRJbnN0cnVjdGlvbl9NLCBMb2FkSW5zdHJ1Y3Rpb25fTgotICAgICAgICAvLyBwYXR0ZXJuID0gIkxvYWRJbnN0cnVjdGlvbiBMb2FkSW5zdHJ1Y3Rpb24gU1dBUCI7Ci0gICAgICAgIC8vIGNoYW5nZWQgdG8gbG93ZXIgY2FzZSAtIGNoYW5naW5nIHRvIGFsbCBsb3dlciBjYXNlIGFsdGhvdWdoIG9ubHkgdGhlIGluc3RydWN0aW9uIHdpdGggY2FwaXRhbCBJCi0gICAgICAgIC8vIGlzIGNyZWF0aW5nIGEgcHJvYmxlbSBpbiB0aGUgVHVya2lzaCBsb2NhbGUKLSAgICAgICAgcGF0dGVybiA9ICJsb2FkaW5zdHJ1Y3Rpb24gbG9hZGluc3RydWN0aW9uIHN3YXAiOwotICAgICAgICBmb3IgKEl0ZXJhdG9yIGl0ZXIgPSBmaW5kLnNlYXJjaChwYXR0ZXJuKTsgaXRlci5oYXNOZXh0KCk7KSB7Ci0gICAgICAgICAgICBJbnN0cnVjdGlvbkhhbmRsZVtdIG1hdGNoID0gKEluc3RydWN0aW9uSGFuZGxlW10paXRlci5uZXh0KCk7Ci0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIGlmICghbWF0Y2hbMF0uaGFzVGFyZ2V0ZXJzKCkgJiYKLSAgICAgICAgICAgICAgICAgICAgIW1hdGNoWzFdLmhhc1RhcmdldGVycygpICYmCi0gICAgICAgICAgICAgICAgICAgICFtYXRjaFsyXS5oYXNUYXJnZXRlcnMoKSkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIEluc3RydWN0aW9uIGxvYWRfbSA9IG1hdGNoWzFdLmdldEluc3RydWN0aW9uKCk7Ci0gICAgICAgICAgICAgICAgICAgIGlsLmluc2VydChtYXRjaFswXSwgbG9hZF9tKTsKLSAgICAgICAgICAgICAgICAgICAgaWwuZGVsZXRlKG1hdGNoWzFdLCBtYXRjaFsyXSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2F0Y2ggKFRhcmdldExvc3RFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgIC8vIFRPRE86IG1vdmUgdGFyZ2V0IGRvd24gaW50byB0aGUgbGlzdAotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gQUxPQURfTiBBTE9BRF9OID0+IEFMT0FEX04gRFVQCi0gICAgICAgIC8vIHBhdHRlcm4gPSAiQUxPQUQgQUxPQUQiOwotICAgICAgICAvLyBjaGFuZ2VkIHRvIGxvd2VyIGNhc2UgLSBjaGFuZ2luZyB0byBhbGwgbG93ZXIgY2FzZSBhbHRob3VnaCBvbmx5IHRoZSBpbnN0cnVjdGlvbiB3aXRoIGNhcGl0YWwgSQotICAgICAgICAvLyBpcyBjcmVhdGluZyBhIHByb2JsZW0gaW4gdGhlIFR1cmtpc2ggbG9jYWxlCi0gICAgICAgIHBhdHRlcm4gPSAiYWxvYWQgYWxvYWQiOwotICAgICAgICBmb3IgKEl0ZXJhdG9yIGl0ZXIgPSBmaW5kLnNlYXJjaChwYXR0ZXJuKTsgaXRlci5oYXNOZXh0KCk7KSB7Ci0gICAgICAgICAgICBJbnN0cnVjdGlvbkhhbmRsZVtdIG1hdGNoID0gKEluc3RydWN0aW9uSGFuZGxlW10paXRlci5uZXh0KCk7Ci0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIGlmICghbWF0Y2hbMV0uaGFzVGFyZ2V0ZXJzKCkpIHsKLSAgICAgICAgICAgICAgICAgICAgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5BTE9BRCBhbG9hZDEgPQotICAgICAgICAgICAgICAgICAgICAgICAgKGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQUxPQUQpIG1hdGNoWzBdLmdldEluc3RydWN0aW9uKCk7Ci0gICAgICAgICAgICAgICAgICAgIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQUxPQUQgYWxvYWQyID0KLSAgICAgICAgICAgICAgICAgICAgICAgIChjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkFMT0FEKSBtYXRjaFsxXS5nZXRJbnN0cnVjdGlvbigpOwotCi0gICAgICAgICAgICAgICAgICAgIGlmIChhbG9hZDEuZ2V0SW5kZXgoKSA9PSBhbG9hZDIuZ2V0SW5kZXgoKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgaWwuaW5zZXJ0KG1hdGNoWzFdLCBuZXcgRFVQKCkpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWwuZGVsZXRlKG1hdGNoWzFdKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhdGNoIChUYXJnZXRMb3N0RXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICAvLyBUT0RPOiBtb3ZlIHRhcmdldCBkb3duIGludG8gdGhlIGxpc3QKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyBJbnN0cnVjdGlvbkhhbmRsZSBnZXRUZW1wbGF0ZUluc3RydWN0aW9uSGFuZGxlKFRlbXBsYXRlIHRlbXBsYXRlKSB7Ci0gICAgICAgIHJldHVybiBfdGVtcGxhdGVJSHMuZ2V0KHRlbXBsYXRlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBdXhpbGlhcnkgbWV0aG9kIHRvIGRldGVybWluZSBpZiBhIHFuYW1lIGlzIGFuIGF0dHJpYnV0ZS4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGlzQXR0cmlidXRlTmFtZShTdHJpbmcgcW5hbWUpIHsKLSAgICAgICAgZmluYWwgaW50IGNvbCA9IHFuYW1lLmxhc3RJbmRleE9mKCc6JykgKyAxOwotICAgICAgICByZXR1cm4gKHFuYW1lLmNoYXJBdChjb2wpID09ICdAJyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQXV4aWxpYXJ5IG1ldGhvZCB0byBkZXRlcm1pbmUgaWYgYSBxbmFtZSBpcyBhIG5hbWVzcGFjZQotICAgICAqIHF1YWxpZmllZCAiKiIuCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBpc05hbWVzcGFjZU5hbWUoU3RyaW5nIHFuYW1lKSB7Ci0gICAgICAgIGZpbmFsIGludCBjb2wgPSBxbmFtZS5sYXN0SW5kZXhPZignOicpOwotICAgICAgICByZXR1cm4gKGNvbCA+IC0xICYmIHFuYW1lLmNoYXJBdChxbmFtZS5sZW5ndGgoKS0xKSA9PSAnKicpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvTmFtZUJhc2UuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvTmFtZUJhc2UuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZmM5NGMxNS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL05hbWVCYXNlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMzAgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogTmFtZUJhc2UuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8wMiAxMDoxNzozMSBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5Db25zdGFudFBvb2xHZW47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JTlZPS0VTVEFUSUM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JbnN0cnVjdGlvbkxpc3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuQ2xhc3NHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuTWV0aG9kR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZUNoZWNrRXJyb3I7Ci0KLS8qKgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKiBAYXV0aG9yIEVyd2luIEJvbHdpZHQgPGVqYkBrbG9tcC5vcmc+Ci0gKi8KLWNsYXNzIE5hbWVCYXNlIGV4dGVuZHMgRnVuY3Rpb25DYWxsIHsKLQotICAgIHByaXZhdGUgRXhwcmVzc2lvbiBfcGFyYW0gPSBudWxsOwotICAgIHByaXZhdGUgVHlwZSAgICAgICBfcGFyYW1UeXBlID0gVHlwZS5Ob2RlOwotCi0gICAgLyoqCi0gICAgICogSGFuZGxlcyBjYWxscyB3aXRoIG5vIHBhcmFtZXRlciAoY3VycmVudCBub2RlIGlzIGltcGxpY2l0IHBhcmFtZXRlcikuCi0gICAgICovCi0gICAgcHVibGljIE5hbWVCYXNlKFFOYW1lIGZuYW1lKSB7Ci0gICAgICAgIHN1cGVyKGZuYW1lKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBIYW5kbGVzIGNhbGxzIHdpdGggb25lIHBhcmFtZXRlciAoZWl0aGVyIG5vZGUgb3Igbm9kZS1zZXQpLgotICAgICAqLwotICAgIHB1YmxpYyBOYW1lQmFzZShRTmFtZSBmbmFtZSwgVmVjdG9yIGFyZ3VtZW50cykgewotICAgICAgICBzdXBlcihmbmFtZSwgYXJndW1lbnRzKTsKLSAgICAgICAgX3BhcmFtID0gYXJndW1lbnQoMCk7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBDaGVjayB0aGF0IHdlIGVpdGhlciBoYXZlIG5vIHBhcmFtZXRlcnMgb3Igb25lIHBhcmFtZXRlciB0aGF0IGlzCi0gICAgICogZWl0aGVyIGEgbm9kZSBvciBhIG5vZGUtc2V0LgotICAgICAqLwotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0KLSAgICAgICAgLy8gQ2hlY2sgdGhlIGFyZ3VtZW50IHR5cGUgKGlmIGFueSkKLSAgICAgICAgc3dpdGNoKGFyZ3VtZW50Q291bnQoKSkgewotICAgICAgICBjYXNlIDA6Ci0gICAgICAgICAgICBfcGFyYW1UeXBlID0gVHlwZS5Ob2RlOwotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgMToKLSAgICAgICAgICAgIF9wYXJhbVR5cGUgPSBfcGFyYW0udHlwZUNoZWNrKHN0YWJsZSk7Ci0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgZGVmYXVsdDoKLSAgICAgICAgICAgIHRocm93IG5ldyBUeXBlQ2hlY2tFcnJvcih0aGlzKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIFRoZSBhcmd1bWVudCBoYXMgdG8gYmUgYSBub2RlLCBhIG5vZGUtc2V0IG9yIGEgbm9kZSByZWZlcmVuY2UKLSAgICAgICAgaWYgKChfcGFyYW1UeXBlICE9IFR5cGUuTm9kZVNldCkgJiYKLSAgICAgICAgICAgIChfcGFyYW1UeXBlICE9IFR5cGUuTm9kZSkgJiYKLSAgICAgICAgICAgIChfcGFyYW1UeXBlICE9IFR5cGUuUmVmZXJlbmNlKSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVDaGVja0Vycm9yKHRoaXMpOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIChfdHlwZSA9IFR5cGUuU3RyaW5nKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgVHlwZSBnZXRUeXBlKCkgewotICAgICAgICByZXR1cm4gX3R5cGU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhbnNsYXRlIHRoZSBjb2RlIHJlcXVpcmVkIGZvciBnZXR0aW5nIHRoZSBub2RlIGZvciB3aGljaCB0aGUKLSAgICAgKiBRTmFtZSwgbG9jYWwtbmFtZSBvciBuYW1lc3BhY2UgVVJJIHNob3VsZCBiZSBleHRyYWN0ZWQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0gICAgICAgIGZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCi0gICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLQotICAgICAgICAvLyBGdW5jdGlvbiB3YXMgY2FsbGVkIHdpdGggbm8gcGFyYW1ldGVycwotICAgICAgICBpZiAoYXJndW1lbnRDb3VudCgpID09IDApIHsKLSAgICAgICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZENvbnRleHROb2RlKCkpOwotICAgICAgICB9Ci0gICAgICAgIC8vIEZ1bmN0aW9uIHdhcyBjYWxsZWQgd2l0aCBub2RlIHBhcmFtZXRlcgotICAgICAgICBlbHNlIGlmIChfcGFyYW1UeXBlID09IFR5cGUuTm9kZSkgewotICAgICAgICAgICAgX3BhcmFtLnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChfcGFyYW1UeXBlID09IFR5cGUuUmVmZXJlbmNlKSB7Ci0gICAgICAgICAgICBfcGFyYW0udHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VTVEFUSUMoY3BnLmFkZE1ldGhvZHJlZgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKEJBU0lTX0xJQlJBUllfQ0xBU1MsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInJlZmVyZW5jZVRvTm9kZVNldCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIigiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBPQkpFQ1RfU0lHCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiKSIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIE5PREVfSVRFUkFUT1JfU0lHKSkpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5uZXh0Tm9kZSgpKTsKLSAgICAgICAgfQotICAgICAgICAvLyBGdW5jdGlvbiB3YXMgY2FsbGVkIHdpdGggbm9kZS1zZXQgcGFyYW1ldGVyCi0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgX3BhcmFtLnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgICAgIF9wYXJhbS5zdGFydEl0ZXJhdG9yKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5uZXh0Tm9kZSgpKTsKLSAgICAgICAgfQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvTmFtZUNhbGwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvTmFtZUNhbGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggY2IxNjlkMC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL05hbWVDYWxsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw2OCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBOYW1lQ2FsbC5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzAyIDEwOjE5OjExIHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkNvbnN0YW50UG9vbEdlbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklOVk9LRUlOVEVSRkFDRTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uTGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5DbGFzc0dlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5NZXRob2RHZW5lcmF0b3I7Ci0KLS8qKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKi8KLWZpbmFsIGNsYXNzIE5hbWVDYWxsIGV4dGVuZHMgTmFtZUJhc2UgewotCi0gICAgLyoqCi0gICAgICogSGFuZGxlcyBjYWxscyB3aXRoIG5vIHBhcmFtZXRlciAoY3VycmVudCBub2RlIGlzIGltcGxpY2l0IHBhcmFtZXRlcikuCi0gICAgICovCi0gICAgcHVibGljIE5hbWVDYWxsKFFOYW1lIGZuYW1lKSB7Ci0gICAgICAgIHN1cGVyKGZuYW1lKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBIYW5kbGVzIGNhbGxzIHdpdGggb25lIHBhcmFtZXRlciAoZWl0aGVyIG5vZGUgb3Igbm9kZS1zZXQpLgotICAgICAqLwotICAgIHB1YmxpYyBOYW1lQ2FsbChRTmFtZSBmbmFtZSwgVmVjdG9yIGFyZ3VtZW50cykgewotICAgICAgICBzdXBlcihmbmFtZSwgYXJndW1lbnRzKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGUgY29kZSB0aGF0IGxlYXZlcyBhIG5vZGUncyBRTmFtZSAoYXMgYSBTdHJpbmcpIG9uIHRoZSBzdGFjawotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotICAgICAgICBmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQotICAgICAgICBmaW5hbCBpbnQgZ2V0TmFtZSA9IGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoRE9NX0lOVEYsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHRVRfTk9ERV9OQU1FLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR0VUX05PREVfTkFNRV9TSUcpOwotICAgICAgICBzdXBlci50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFSU5URVJGQUNFKGdldE5hbWUsIDIpKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL05hbWVzcGFjZUFsaWFzLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL05hbWVzcGFjZUFsaWFzLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDhkNDgwOTkuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9OYW1lc3BhY2VBbGlhcy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTcgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogTmFtZXNwYWNlQWxpYXMuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8wMiAxMDoyMDo1NSBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5DbGFzc0dlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5NZXRob2RHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlQ2hlY2tFcnJvcjsKLQotLyoqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKi8KLWZpbmFsIGNsYXNzIE5hbWVzcGFjZUFsaWFzIGV4dGVuZHMgVG9wTGV2ZWxFbGVtZW50IHsKLQotICAgIHByaXZhdGUgU3RyaW5nIHNQcmVmaXg7Ci0gICAgcHJpdmF0ZSBTdHJpbmcgclByZWZpeDsKLQotICAgIC8qCi0gICAgICogVGhlIG5hbWVzcGFjZSBhbGlhcyBkZWZpbml0aW9ucyBnaXZlbiBoZXJlIGhhdmUgYW4gaW1wYWN0IG9ubHkgb24KLSAgICAgKiBsaXRlcmFsIGVsZW1lbnRzIGFuZCBsaXRlcmFsIGF0dHJpYnV0ZXMuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcGFyc2VDb250ZW50cyhQYXJzZXIgcGFyc2VyKSB7Ci0gICAgICAgIHNQcmVmaXggPSBnZXRBdHRyaWJ1dGUoInN0eWxlc2hlZXQtcHJlZml4Iik7Ci0gICAgICAgIHJQcmVmaXggPSBnZXRBdHRyaWJ1dGUoInJlc3VsdC1wcmVmaXgiKTsKLSAgICAgICAgcGFyc2VyLmdldFN5bWJvbFRhYmxlKCkuYWRkUHJlZml4QWxpYXMoc1ByZWZpeCxyUHJlZml4KTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgVHlwZSB0eXBlQ2hlY2soU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgewotICAgICAgICByZXR1cm4gVHlwZS5Wb2lkOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotICAgICAgICAvLyBkbyBuYWRhCi0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9OYW1lc3BhY2VVcmlDYWxsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL05hbWVzcGFjZVVyaUNhbGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMmZlN2YzZi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL05hbWVzcGFjZVVyaUNhbGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDY5ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IE5hbWVzcGFjZVVyaUNhbGwuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8wMiAxMDoyNToyNiBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5Db25zdGFudFBvb2xHZW47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JTlZPS0VJTlRFUkZBQ0U7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JbnN0cnVjdGlvbkxpc3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuQ2xhc3NHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuTWV0aG9kR2VuZXJhdG9yOwotCi0vKioKLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICovCi1maW5hbCBjbGFzcyBOYW1lc3BhY2VVcmlDYWxsIGV4dGVuZHMgTmFtZUJhc2UgewotCi0gICAgLyoqCi0gICAgICogSGFuZGxlcyBjYWxscyB3aXRoIG5vIHBhcmFtZXRlciAoY3VycmVudCBub2RlIGlzIGltcGxpY2l0IHBhcmFtZXRlcikuCi0gICAgICovCi0gICAgcHVibGljIE5hbWVzcGFjZVVyaUNhbGwoUU5hbWUgZm5hbWUpIHsKLSAgICAgICAgc3VwZXIoZm5hbWUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEhhbmRsZXMgY2FsbHMgd2l0aCBvbmUgcGFyYW1ldGVyIChlaXRoZXIgbm9kZSBvciBub2RlLXNldCkuCi0gICAgICovCi0gICAgcHVibGljIE5hbWVzcGFjZVVyaUNhbGwoUU5hbWUgZm5hbWUsIFZlY3RvciBhcmd1bWVudHMpIHsKLSAgICAgICAgc3VwZXIoZm5hbWUsIGFyZ3VtZW50cyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhbnNsYXRlIGNvZGUgdGhhdCBsZWF2ZXMgYSBub2RlJ3MgbmFtZXNwYWNlIFVSSSAoYXMgYSBTdHJpbmcpCi0gICAgICogb24gdGhlIHN0YWNrCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0gICAgICAgIGZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCi0gICAgICAgIC8vIFJldHVybnMgdGhlIHN0cmluZyB2YWx1ZSBmb3IgYSBub2RlIGluIHRoZSBET00KLSAgICAgICAgZmluYWwgaW50IGdldE5hbWVzcGFjZSA9IGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoRE9NX0lOVEYsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJnZXROYW1lc3BhY2VOYW1lIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIihJKSIrU1RSSU5HX1NJRyk7Ci0gICAgICAgIHN1cGVyLnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0UoZ2V0TmFtZXNwYWNlLCAyKSk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9Ob2RlVGVzdC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9Ob2RlVGVzdC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1YWU3Yzg5Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvTm9kZVRlc3QuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQ1ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IE5vZGVUZXN0LmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMDIgMTA6MzE6MTQgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLkRPTTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE07Ci0KLS8qKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICovCi1wdWJsaWMgaW50ZXJmYWNlIE5vZGVUZXN0IHsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBURVhUICAgICAgPSBEVE0uVEVYVF9OT0RFOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENPTU1FTlQgICA9IERUTS5DT01NRU5UX05PREU7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUEkgICAgICAgID0gRFRNLlBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBST09UICAgICAgPSBEVE0uRE9DVU1FTlRfTk9ERTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTEVNRU5UICAgPSBEVE0uRUxFTUVOVF9OT0RFOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFUVFJJQlVURSA9IERUTS5BVFRSSUJVVEVfTk9ERTsKLQotICAgIC8vIGdlbmVyYWxpemVkIHR5cGUKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBHVFlQRSAgICAgPSBEVE0uTlRZUEVTOwotCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQU5PREUgICAgID0gRE9NLkZJUlNUX1RZUEUgLSAxOwotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9Ob3RDYWxsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL05vdENhbGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYmNjMjQ2My4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL05vdENhbGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDYwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IE5vdENhbGwuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8wMiAxMDozMjoxOCBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5CcmFuY2hIYW5kbGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5HT1RPOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW5zdHJ1Y3Rpb25MaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkNsYXNzR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLk1ldGhvZEdlbmVyYXRvcjsKLQotLyoqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKi8KLWZpbmFsIGNsYXNzIE5vdENhbGwgZXh0ZW5kcyBGdW5jdGlvbkNhbGwgewotICAgIHB1YmxpYyBOb3RDYWxsKFFOYW1lIGZuYW1lLCBWZWN0b3IgYXJndW1lbnRzKSB7Ci0gICAgICAgIHN1cGVyKGZuYW1lLCBhcmd1bWVudHMpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0gICAgICAgIGFyZ3VtZW50KCkudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICBpbC5hcHBlbmQoSUNPTlNUXzEpOwotICAgICAgICBpbC5hcHBlbmQoSVhPUik7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlRGVzeW50aGVzaXplZChDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotICAgICAgICBmaW5hbCBFeHByZXNzaW9uIGV4cCA9IGFyZ3VtZW50KCk7Ci0gICAgICAgIGV4cC50cmFuc2xhdGVEZXN5bnRoZXNpemVkKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICBmaW5hbCBCcmFuY2hIYW5kbGUgZ290b2ggPSBpbC5hcHBlbmQobmV3IEdPVE8obnVsbCkpOwotICAgICAgICBfdHJ1ZUxpc3QgPSBleHAuX2ZhbHNlTGlzdDsgICAgIC8vIHN3YXAgZmxvdyBsaXN0cwotICAgICAgICBfZmFsc2VMaXN0ID0gZXhwLl90cnVlTGlzdDsKLSAgICAgICAgX2ZhbHNlTGlzdC5hZGQoZ290b2gpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvTnVtYmVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL051bWJlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA5YjU4NmFjLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvTnVtYmVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw2MDAgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogTnVtYmVyLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMjEgMDk6NDA6NTEgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmNsYXNzZmlsZS5GaWVsZDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkFMT0FEOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSUxPQUQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5BU1RPUkU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5CcmFuY2hIYW5kbGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5DSEVDS0NBU1Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5Db25zdGFudFBvb2xHZW47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5HRVRGSUVMRDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkdPVE87Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JRk5PTk5VTEw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JTlZPS0VTUEVDSUFMOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFU1RBVElDOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFVklSVFVBTDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uTGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkQySTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkxvY2FsVmFyaWFibGVHZW47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5ORVc7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5QVVNIOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuUFVURklFTEQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuQ2xhc3NHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuTWF0Y2hHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuTWV0aG9kR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLk5vZGVDb3VudGVyR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlJlYWxUeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZUNoZWNrRXJyb3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVXRpbDsKLQotLyoqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKi8KLWZpbmFsIGNsYXNzIE51bWJlciBleHRlbmRzIEluc3RydWN0aW9uIGltcGxlbWVudHMgQ2xvc3VyZSB7Ci0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IExFVkVMX1NJTkdMRSAgID0gMDsKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTEVWRUxfTVVMVElQTEUgPSAxOwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBMRVZFTF9BTlkgICAgICA9IDI7Ci0KLSAgICBzdGF0aWMgZmluYWwgcHJpdmF0ZSBTdHJpbmdbXSBDbGFzc05hbWVzID0gewotICAgICAgICAiY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmRvbS5TaW5nbGVOb2RlQ291bnRlciIsICAgICAgICAgIC8vIExFVkVMX1NJTkdMRQotICAgICAgICAiY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmRvbS5NdWx0aXBsZU5vZGVDb3VudGVyIiwgLy8gTEVWRUxfTVVMVElQTEUKLSAgICAgICAgImNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5kb20uQW55Tm9kZUNvdW50ZXIiICAgICAgLy8gTEVWRUxfQU5ZCi0gICAgfTsKLQotICAgIHN0YXRpYyBmaW5hbCBwcml2YXRlIFN0cmluZ1tdIEZpZWxkTmFtZXMgPSB7Ci0gICAgICAgICJfX19zaW5nbGVfbm9kZV9jb3VudGVyIiwgICAgICAgICAgICAgICAgICAvLyBMRVZFTF9TSU5HTEUKLSAgICAgICAgIl9fX211bHRpcGxlX25vZGVfY291bnRlciIsICAgICAgICAgICAgICAgIC8vIExFVkVMX01VTFRJUExFCi0gICAgICAgICJfX19hbnlfbm9kZV9jb3VudGVyIiAgICAgICAgICAgICAgICAgICAgICAvLyBMRVZFTF9BTlkKLSAgICB9OwotCi0gICAgcHJpdmF0ZSBQYXR0ZXJuIF9mcm9tID0gbnVsbDsKLSAgICBwcml2YXRlIFBhdHRlcm4gX2NvdW50ID0gbnVsbDsKLSAgICBwcml2YXRlIEV4cHJlc3Npb24gX3ZhbHVlID0gbnVsbDsKLQotICAgIHByaXZhdGUgQXR0cmlidXRlVmFsdWVUZW1wbGF0ZSBfbGFuZyA9IG51bGw7Ci0gICAgcHJpdmF0ZSBBdHRyaWJ1dGVWYWx1ZVRlbXBsYXRlIF9mb3JtYXQgPSBudWxsOwotICAgIHByaXZhdGUgQXR0cmlidXRlVmFsdWVUZW1wbGF0ZSBfbGV0dGVyVmFsdWUgPSBudWxsOwotICAgIHByaXZhdGUgQXR0cmlidXRlVmFsdWVUZW1wbGF0ZSBfZ3JvdXBpbmdTZXBhcmF0b3IgPSBudWxsOwotICAgIHByaXZhdGUgQXR0cmlidXRlVmFsdWVUZW1wbGF0ZSBfZ3JvdXBpbmdTaXplID0gbnVsbDsKLQotICAgIHByaXZhdGUgaW50IF9sZXZlbCA9IExFVkVMX1NJTkdMRTsKLSAgICBwcml2YXRlIGJvb2xlYW4gX2Zvcm1hdE5lZWRlZCA9IGZhbHNlOwotCi0gICAgcHJpdmF0ZSBTdHJpbmcgX2NsYXNzTmFtZSA9IG51bGw7Ci0gICAgcHJpdmF0ZSBBcnJheUxpc3QgX2Nsb3N1cmVWYXJzID0gbnVsbDsKLQotICAgICAvLyAtLSBCZWdpbiBDbG9zdXJlIGludGVyZmFjZSAtLS0tLS0tLS0tLS0tLS0tLS0tLQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIGlmIHRoaXMgY2xvc3VyZSBpcyBjb21waWxlZCBpbiBhbiBpbm5lciBjbGFzcyAoaS5lLgotICAgICAqIGlmIHRoaXMgaXMgYSByZWFsIGNsb3N1cmUpLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGluSW5uZXJDbGFzcygpIHsKLSAgICAgICAgcmV0dXJuIChfY2xhc3NOYW1lICE9IG51bGwpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYSByZWZlcmVuY2UgdG8gaXRzIHBhcmVudCBjbG9zdXJlIG9yIG51bGwgaWYgb3V0ZXJtb3N0LgotICAgICAqLwotICAgIHB1YmxpYyBDbG9zdXJlIGdldFBhcmVudENsb3N1cmUoKSB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhlIGF1eGlsaWFyeSBjbGFzcyBvciBudWxsIGlmIHRoaXMgcHJlZGljYXRlCi0gICAgICogaXMgY29tcGlsZWQgaW5zaWRlIHRoZSBUcmFuc2xldC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldElubmVyQ2xhc3NOYW1lKCkgewotICAgICAgICByZXR1cm4gX2NsYXNzTmFtZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBZGQgbmV3IHZhcmlhYmxlIHRvIHRoZSBjbG9zdXJlLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGFkZFZhcmlhYmxlKFZhcmlhYmxlUmVmQmFzZSB2YXJpYWJsZVJlZikgewotICAgICAgICBpZiAoX2Nsb3N1cmVWYXJzID09IG51bGwpIHsKLSAgICAgICAgICAgIF9jbG9zdXJlVmFycyA9IG5ldyBBcnJheUxpc3QoKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIE9ubHkgb25lIHJlZmVyZW5jZSBwZXIgdmFyaWFibGUKLSAgICAgICAgaWYgKCFfY2xvc3VyZVZhcnMuY29udGFpbnModmFyaWFibGVSZWYpKSB7Ci0gICAgICAgICAgICBfY2xvc3VyZVZhcnMuYWRkKHZhcmlhYmxlUmVmKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8vIC0tIEVuZCBDbG9zdXJlIGludGVyZmFjZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0KLSAgIHB1YmxpYyB2b2lkIHBhcnNlQ29udGVudHMoUGFyc2VyIHBhcnNlcikgewotICAgICAgICBmaW5hbCBpbnQgY291bnQgPSBfYXR0cmlidXRlcy5nZXRMZW5ndGgoKTsKLQotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKLSAgICAgICAgICAgIGZpbmFsIFN0cmluZyBuYW1lID0gX2F0dHJpYnV0ZXMuZ2V0UU5hbWUoaSk7Ci0gICAgICAgICAgICBmaW5hbCBTdHJpbmcgdmFsdWUgPSBfYXR0cmlidXRlcy5nZXRWYWx1ZShpKTsKLQotICAgICAgICAgICAgaWYgKG5hbWUuZXF1YWxzKCJ2YWx1ZSIpKSB7Ci0gICAgICAgICAgICAgICAgX3ZhbHVlID0gcGFyc2VyLnBhcnNlRXhwcmVzc2lvbih0aGlzLCBuYW1lLCBudWxsKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzKCJjb3VudCIpKSB7Ci0gICAgICAgICAgICAgICAgX2NvdW50ID0gcGFyc2VyLnBhcnNlUGF0dGVybih0aGlzLCBuYW1lLCBudWxsKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzKCJmcm9tIikpIHsKLSAgICAgICAgICAgICAgICBfZnJvbSA9IHBhcnNlci5wYXJzZVBhdHRlcm4odGhpcywgbmFtZSwgbnVsbCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFscygibGV2ZWwiKSkgewotICAgICAgICAgICAgICAgIGlmICh2YWx1ZS5lcXVhbHMoInNpbmdsZSIpKSB7Ci0gICAgICAgICAgICAgICAgICAgIF9sZXZlbCA9IExFVkVMX1NJTkdMRTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSBpZiAodmFsdWUuZXF1YWxzKCJtdWx0aXBsZSIpKSB7Ci0gICAgICAgICAgICAgICAgICAgIF9sZXZlbCA9IExFVkVMX01VTFRJUExFOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIGlmICh2YWx1ZS5lcXVhbHMoImFueSIpKSB7Ci0gICAgICAgICAgICAgICAgICAgIF9sZXZlbCA9IExFVkVMX0FOWTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFscygiZm9ybWF0IikpIHsKLSAgICAgICAgICAgICAgICBfZm9ybWF0ID0gbmV3IEF0dHJpYnV0ZVZhbHVlVGVtcGxhdGUodmFsdWUsIHBhcnNlciwgdGhpcyk7Ci0gICAgICAgICAgICAgICAgX2Zvcm1hdE5lZWRlZCA9IHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFscygibGFuZyIpKSB7Ci0gICAgICAgICAgICAgICAgX2xhbmcgPSBuZXcgQXR0cmlidXRlVmFsdWVUZW1wbGF0ZSh2YWx1ZSwgcGFyc2VyLCB0aGlzKTsKLSAgICAgICAgICAgICAgICBfZm9ybWF0TmVlZGVkID0gdHJ1ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzKCJsZXR0ZXItdmFsdWUiKSkgewotICAgICAgICAgICAgICAgIF9sZXR0ZXJWYWx1ZSA9IG5ldyBBdHRyaWJ1dGVWYWx1ZVRlbXBsYXRlKHZhbHVlLCBwYXJzZXIsIHRoaXMpOwotICAgICAgICAgICAgICAgIF9mb3JtYXROZWVkZWQgPSB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAobmFtZS5lcXVhbHMoImdyb3VwaW5nLXNlcGFyYXRvciIpKSB7Ci0gICAgICAgICAgICAgICAgX2dyb3VwaW5nU2VwYXJhdG9yID0gbmV3IEF0dHJpYnV0ZVZhbHVlVGVtcGxhdGUodmFsdWUsIHBhcnNlciwgdGhpcyk7Ci0gICAgICAgICAgICAgICAgX2Zvcm1hdE5lZWRlZCA9IHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFscygiZ3JvdXBpbmctc2l6ZSIpKSB7Ci0gICAgICAgICAgICAgICAgX2dyb3VwaW5nU2l6ZSA9IG5ldyBBdHRyaWJ1dGVWYWx1ZVRlbXBsYXRlKHZhbHVlLCBwYXJzZXIsIHRoaXMpOwotICAgICAgICAgICAgICAgIF9mb3JtYXROZWVkZWQgPSB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLSAgICAgICAgaWYgKF92YWx1ZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBUeXBlIHR2YWx1ZSA9IF92YWx1ZS50eXBlQ2hlY2soc3RhYmxlKTsKLSAgICAgICAgICAgIGlmICh0dmFsdWUgaW5zdGFuY2VvZiBSZWFsVHlwZSA9PSBmYWxzZSkgewotICAgICAgICAgICAgICAgIF92YWx1ZSA9IG5ldyBDYXN0RXhwcihfdmFsdWUsIFR5cGUuUmVhbCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKF9jb3VudCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBfY291bnQudHlwZUNoZWNrKHN0YWJsZSk7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKF9mcm9tICE9IG51bGwpIHsKLSAgICAgICAgICAgIF9mcm9tLnR5cGVDaGVjayhzdGFibGUpOwotICAgICAgICB9Ci0gICAgICAgIGlmIChfZm9ybWF0ICE9IG51bGwpIHsKLSAgICAgICAgICAgIF9mb3JtYXQudHlwZUNoZWNrKHN0YWJsZSk7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKF9sYW5nICE9IG51bGwpIHsKLSAgICAgICAgICAgIF9sYW5nLnR5cGVDaGVjayhzdGFibGUpOwotICAgICAgICB9Ci0gICAgICAgIGlmIChfbGV0dGVyVmFsdWUgIT0gbnVsbCkgewotICAgICAgICAgICAgX2xldHRlclZhbHVlLnR5cGVDaGVjayhzdGFibGUpOwotICAgICAgICB9Ci0gICAgICAgIGlmIChfZ3JvdXBpbmdTZXBhcmF0b3IgIT0gbnVsbCkgewotICAgICAgICAgICAgX2dyb3VwaW5nU2VwYXJhdG9yLnR5cGVDaGVjayhzdGFibGUpOwotICAgICAgICB9Ci0gICAgICAgIGlmIChfZ3JvdXBpbmdTaXplICE9IG51bGwpIHsKLSAgICAgICAgICAgIF9ncm91cGluZ1NpemUudHlwZUNoZWNrKHN0YWJsZSk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIFR5cGUuVm9pZDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcnVlIGlmIHRoZSBoYXMgc3BlY2lmaWVkIGEgdmFsdWUgZm9yIHRoaXMgaW5zdGFuY2Ugb2YgbnVtYmVyLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGhhc1ZhbHVlKCkgewotICAgICAgICByZXR1cm4gX3ZhbHVlICE9IG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyA8dHQ+dHJ1ZTwvdHQ+IGlmIHRoaXMgaW5zdGFuY2Ugb2YgbnVtYmVyIGhhcyBuZWl0aGVyCi0gICAgICogYSBmcm9tIG5vciBhIGNvdW50IHBhdHRlcm4uCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNEZWZhdWx0KCkgewotICAgICAgICByZXR1cm4gX2Zyb20gPT0gbnVsbCAmJiBfY291bnQgPT0gbnVsbDsKLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgY29tcGlsZURlZmF1bHQoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLSAgICAgICAgaW50IGluZGV4OwotICAgICAgICBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgICAgIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQotICAgICAgICBpbnRbXSBmaWVsZEluZGV4ZXMgPSBnZXRYU0xUQygpLmdldE51bWJlckZpZWxkSW5kZXhlcygpOwotCi0gICAgICAgIGlmIChmaWVsZEluZGV4ZXNbX2xldmVsXSA9PSAtMSkgewotICAgICAgICAgICAgRmllbGQgZGVmYXVsdE5vZGUgPSBuZXcgRmllbGQoQUNDX1BSSVZBVEUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjcGcuYWRkVXRmOChGaWVsZE5hbWVzW19sZXZlbF0pLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3BnLmFkZFV0ZjgoTk9ERV9DT1VOVEVSX1NJRyksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3BnLmdldENvbnN0YW50UG9vbCgpKTsKLQotICAgICAgICAgICAgLy8gQWRkIGEgbmV3IHByaXZhdGUgZmllbGQgdG8gdGhpcyBjbGFzcwotICAgICAgICAgICAgY2xhc3NHZW4uYWRkRmllbGQoZGVmYXVsdE5vZGUpOwotCi0gICAgICAgICAgICAvLyBHZXQgYSByZWZlcmVuY2UgdG8gdGhlIG5ld2x5IGFkZGVkIGZpZWxkCi0gICAgICAgICAgICBmaWVsZEluZGV4ZXNbX2xldmVsXSA9IGNwZy5hZGRGaWVsZHJlZihjbGFzc0dlbi5nZXRDbGFzc05hbWUoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZpZWxkTmFtZXNbX2xldmVsXSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5PREVfQ09VTlRFUl9TSUcpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gQ2hlY2sgaWYgZmllbGQgaXMgaW5pdGlhbGl6ZWQgKHJ1bnRpbWUpCi0gICAgICAgIGlsLmFwcGVuZChjbGFzc0dlbi5sb2FkVHJhbnNsZXQoKSk7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgR0VURklFTEQoZmllbGRJbmRleGVzW19sZXZlbF0pKTsKLSAgICAgICAgZmluYWwgQnJhbmNoSGFuZGxlIGlmQmxvY2sxID0gaWwuYXBwZW5kKG5ldyBJRk5PTk5VTEwobnVsbCkpOwotCi0gICAgICAgIC8vIENyZWF0ZSBhbiBpbnN0YW5jZSBvZiBEZWZhdWx0Tm9kZUNvdW50ZXIKLSAgICAgICAgaW5kZXggPSBjcGcuYWRkTWV0aG9kcmVmKENsYXNzTmFtZXNbX2xldmVsXSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJnZXREZWZhdWx0Tm9kZUNvdW50ZXIiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIigiICsgVFJBTlNMRVRfSU5URl9TSUcKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgRE9NX0lOVEZfU0lHCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIE5PREVfSVRFUkFUT1JfU0lHCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIpIiArIE5PREVfQ09VTlRFUl9TSUcpOwotICAgICAgICBpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpOwotICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0gICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZEl0ZXJhdG9yKCkpOwotICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRVNUQVRJQyhpbmRleCkpOwotICAgICAgICBpbC5hcHBlbmQoRFVQKTsKLQotICAgICAgICAvLyBTdG9yZSB0aGUgbm9kZSBjb3VudGVyIGluIHRoZSBmaWVsZAotICAgICAgICBpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpOwotICAgICAgICBpbC5hcHBlbmQoU1dBUCk7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgUFVURklFTEQoZmllbGRJbmRleGVzW19sZXZlbF0pKTsKLSAgICAgICAgZmluYWwgQnJhbmNoSGFuZGxlIGlmQmxvY2syID0gaWwuYXBwZW5kKG5ldyBHT1RPKG51bGwpKTsKLQotICAgICAgICAvLyBCYWNrcGF0Y2ggY29uZGl0aW9uYWxzCi0gICAgICAgIGlmQmxvY2sxLnNldFRhcmdldChpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBHRVRGSUVMRChmaWVsZEluZGV4ZXNbX2xldmVsXSkpOwotCi0gICAgICAgIGlmQmxvY2syLnNldFRhcmdldChpbC5hcHBlbmQoTk9QKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29tcGlsZXMgYSBjb25zdHJ1Y3RvciBmb3IgdGhlIGNsYXNzIDx0dD5fY2xhc3NOYW1lPC90dD4gdGhhdAotICAgICAqIGluaGVyaXRzIGZyb20ge0FueSxTaW5nbGUsTXVsdGlwbGV9Tm9kZUNvdW50ZXIuIFRoaXMgY29uc3RydWN0b3IKLSAgICAgKiBzaW1wbHkgY2FsbHMgdGhlIHNhbWUgY29uc3RydWN0b3IgaW4gdGhlIHN1cGVyIGNsYXNzLgotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCBjb21waWxlQ29uc3RydWN0b3IoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4pIHsKLSAgICAgICAgTWV0aG9kR2VuZXJhdG9yIGNvbnM7Ci0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG5ldyBJbnN0cnVjdGlvbkxpc3QoKTsKLSAgICAgICAgZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotCi0gICAgICAgIGNvbnMgPSBuZXcgTWV0aG9kR2VuZXJhdG9yKEFDQ19QVUJMSUMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuVHlwZS5WT0lELAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5UeXBlW10gewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVXRpbC5nZXRKQ1JlZlR5cGUoVFJBTlNMRVRfSU5URl9TSUcpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVXRpbC5nZXRKQ1JlZlR5cGUoRE9NX0lOVEZfU0lHKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFV0aWwuZ2V0SkNSZWZUeXBlKE5PREVfSVRFUkFUT1JfU0lHKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuVHlwZS5CT09MRUFOCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZG9tIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0cmFuc2xldCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiaXRlcmF0b3IiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImhhc0Zyb20iCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI8aW5pdD4iLCBfY2xhc3NOYW1lLCBpbCwgY3BnKTsKLQotICAgICAgICBpbC5hcHBlbmQoQUxPQURfMCk7ICAgICAgICAgLy8gdGhpcwotICAgICAgICBpbC5hcHBlbmQoQUxPQURfMSk7ICAgICAgICAgLy8gdHJhbnNsZXQKLSAgICAgICAgaWwuYXBwZW5kKEFMT0FEXzIpOyAgICAgICAgIC8vIERPTQotICAgICAgICBpbC5hcHBlbmQobmV3IEFMT0FEKDMpKTsgICAgLy8gaXRlcmF0b3IKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBJTE9BRCg0KSk7ICAgIC8vIGhhc0Zyb20KLQotICAgICAgICBpbnQgaW5kZXggPSBjcGcuYWRkTWV0aG9kcmVmKENsYXNzTmFtZXNbX2xldmVsXSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiPGluaXQ+IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKCIgKyBUUkFOU0xFVF9JTlRGX1NJRwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgRE9NX0lOVEZfU0lHCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBOT0RFX0lURVJBVE9SX1NJRwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIlopViIpOwotICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRVNQRUNJQUwoaW5kZXgpKTsKLSAgICAgICAgaWwuYXBwZW5kKFJFVFVSTik7Ci0KLSAgICAgICAgY2xhc3NHZW4uYWRkTWV0aG9kKGNvbnMpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIGNvbXBpbGVzIGNvZGUgdGhhdCBpcyBjb21tb24gdG8gbWF0Y2hlc0Zyb20oKSBhbmQKLSAgICAgKiBtYXRjaGVzQ291bnQoKSBpbiB0aGUgYXV4aWxsYXJ5IGNsYXNzLgotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCBjb21waWxlTG9jYWxzKE5vZGVDb3VudGVyR2VuZXJhdG9yIG5vZGVDb3VudGVyR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hdGNoR2VuZXJhdG9yIG1hdGNoR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluc3RydWN0aW9uTGlzdCBpbCkKLSAgICB7Ci0gICAgICAgIGludCBmaWVsZDsKLSAgICAgICAgTG9jYWxWYXJpYWJsZUdlbiBsb2NhbDsKLSAgICAgICAgQ29uc3RhbnRQb29sR2VuIGNwZyA9IG5vZGVDb3VudGVyR2VuLmdldENvbnN0YW50UG9vbCgpOwotCi0gICAgICAgIC8vIEdldCBOb2RlQ291bnRlci5faXRlcmF0b3IgYW5kIHN0b3JlIGxvY2FsbHkKLSAgICAgICAgbG9jYWwgPSBtYXRjaEdlbi5hZGRMb2NhbFZhcmlhYmxlKCJpdGVyYXRvciIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVdGlsLmdldEpDUmVmVHlwZShOT0RFX0lURVJBVE9SX1NJRyksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLCBudWxsKTsKLSAgICAgICAgZmllbGQgPSBjcGcuYWRkRmllbGRyZWYoTk9ERV9DT1VOVEVSLCAiX2l0ZXJhdG9yIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVRFUkFUT1JfRklFTERfU0lHKTsKLSAgICAgICAgaWwuYXBwZW5kKEFMT0FEXzApOyAvLyAndGhpcycgcG9pbnRlciBvbiBzdGFjawotICAgICAgICBpbC5hcHBlbmQobmV3IEdFVEZJRUxEKGZpZWxkKSk7Ci0gICAgICAgIGxvY2FsLnNldFN0YXJ0KGlsLmFwcGVuZChuZXcgQVNUT1JFKGxvY2FsLmdldEluZGV4KCkpKSk7Ci0gICAgICAgIG1hdGNoR2VuLnNldEl0ZXJhdG9ySW5kZXgobG9jYWwuZ2V0SW5kZXgoKSk7Ci0KLSAgICAgICAgLy8gR2V0IE5vZGVDb3VudGVyLl90cmFuc2xldCBhbmQgc3RvcmUgbG9jYWxseQotICAgICAgICBsb2NhbCA9IG1hdGNoR2VuLmFkZExvY2FsVmFyaWFibGUoInRyYW5zbGV0IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVdGlsLmdldEpDUmVmVHlwZShUUkFOU0xFVF9TSUcpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsIG51bGwpOwotICAgICAgICBmaWVsZCA9IGNwZy5hZGRGaWVsZHJlZihOT0RFX0NPVU5URVIsICJfdHJhbnNsZXQiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9UcmFuc2xldDsiKTsKLSAgICAgICAgaWwuYXBwZW5kKEFMT0FEXzApOyAvLyAndGhpcycgcG9pbnRlciBvbiBzdGFjawotICAgICAgICBpbC5hcHBlbmQobmV3IEdFVEZJRUxEKGZpZWxkKSk7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgQ0hFQ0tDQVNUKGNwZy5hZGRDbGFzcyhUUkFOU0xFVF9DTEFTUykpKTsKLSAgICAgICAgbG9jYWwuc2V0U3RhcnQoaWwuYXBwZW5kKG5ldyBBU1RPUkUobG9jYWwuZ2V0SW5kZXgoKSkpKTsKLSAgICAgICAgbm9kZUNvdW50ZXJHZW4uc2V0VHJhbnNsZXRJbmRleChsb2NhbC5nZXRJbmRleCgpKTsKLQotICAgICAgICAvLyBHZXQgTm9kZUNvdW50ZXIuX2RvY3VtZW50IGFuZCBzdG9yZSBsb2NhbGx5Ci0gICAgICAgIGxvY2FsID0gbWF0Y2hHZW4uYWRkTG9jYWxWYXJpYWJsZSgiZG9jdW1lbnQiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVXRpbC5nZXRKQ1JlZlR5cGUoRE9NX0lOVEZfU0lHKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsIG51bGwpOwotICAgICAgICBmaWVsZCA9IGNwZy5hZGRGaWVsZHJlZihfY2xhc3NOYW1lLCAiX2RvY3VtZW50IiwgRE9NX0lOVEZfU0lHKTsKLSAgICAgICAgaWwuYXBwZW5kKEFMT0FEXzApOyAvLyAndGhpcycgcG9pbnRlciBvbiBzdGFjawotICAgICAgICBpbC5hcHBlbmQobmV3IEdFVEZJRUxEKGZpZWxkKSk7Ci0gICAgICAgIC8vIE1ha2Ugc3VyZSB3ZSBoYXZlIHRoZSBjb3JyZWN0IERPTSB0eXBlIG9uIHRoZSBzdGFjayEhIQotICAgICAgICBsb2NhbC5zZXRTdGFydChpbC5hcHBlbmQobmV3IEFTVE9SRShsb2NhbC5nZXRJbmRleCgpKSkpOwotICAgICAgICBtYXRjaEdlbi5zZXREb21JbmRleChsb2NhbC5nZXRJbmRleCgpKTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgY29tcGlsZVBhdHRlcm5zKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikKLSAgICB7Ci0gICAgICAgIGludCBjdXJyZW50OwotICAgICAgICBpbnQgZmllbGQ7Ci0gICAgICAgIExvY2FsVmFyaWFibGVHZW4gbG9jYWw7Ci0gICAgICAgIE1hdGNoR2VuZXJhdG9yIG1hdGNoR2VuOwotICAgICAgICBOb2RlQ291bnRlckdlbmVyYXRvciBub2RlQ291bnRlckdlbjsKLQotICAgICAgICBfY2xhc3NOYW1lID0gZ2V0WFNMVEMoKS5nZXRIZWxwZXJDbGFzc05hbWUoKTsKLSAgICAgICAgbm9kZUNvdW50ZXJHZW4gPSBuZXcgTm9kZUNvdW50ZXJHZW5lcmF0b3IoX2NsYXNzTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2xhc3NOYW1lc1tfbGV2ZWxdLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b1N0cmluZygpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBQ0NfUFVCTElDIHwgQUNDX1NVUEVSLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzc0dlbi5nZXRTdHlsZXNoZWV0KCkpOwotICAgICAgICBJbnN0cnVjdGlvbkxpc3QgaWwgPSBudWxsOwotICAgICAgICBDb25zdGFudFBvb2xHZW4gY3BnID0gbm9kZUNvdW50ZXJHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0KLSAgICAgICAgLy8gQWRkIGEgbmV3IGluc3RhbmNlIHZhcmlhYmxlIGZvciBlYWNoIHZhciBpbiBjbG9zdXJlCi0gICAgICAgIGZpbmFsIGludCBjbG9zdXJlTGVuID0gKF9jbG9zdXJlVmFycyA9PSBudWxsKSA/IDAgOgotICAgICAgICAgICAgX2Nsb3N1cmVWYXJzLnNpemUoKTsKLQotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNsb3N1cmVMZW47IGkrKykgewotICAgICAgICAgICAgVmFyaWFibGVCYXNlIHZhciA9Ci0gICAgICAgICAgICAgICAgKChWYXJpYWJsZVJlZkJhc2UpIF9jbG9zdXJlVmFycy5nZXQoaSkpLmdldFZhcmlhYmxlKCk7Ci0KLSAgICAgICAgICAgIG5vZGVDb3VudGVyR2VuLmFkZEZpZWxkKG5ldyBGaWVsZChBQ0NfUFVCTElDLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNwZy5hZGRVdGY4KHZhci5nZXRFc2NhcGVkTmFtZSgpKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjcGcuYWRkVXRmOCh2YXIuZ2V0VHlwZSgpLnRvU2lnbmF0dXJlKCkpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsIGNwZy5nZXRDb25zdGFudFBvb2woKSkpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gQWRkIGEgc2luZ2xlIGNvbnN0cnVjdG9yIHRvIHRoZSBjbGFzcwotICAgICAgICBjb21waWxlQ29uc3RydWN0b3Iobm9kZUNvdW50ZXJHZW4pOwotCi0gICAgICAgIC8qCi0gICAgICAgICAqIENvbXBpbGUgbWV0aG9kIG1hdGNoZXNGcm9tKCkKLSAgICAgICAgICovCi0gICAgICAgIGlmIChfZnJvbSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpbCA9IG5ldyBJbnN0cnVjdGlvbkxpc3QoKTsKLSAgICAgICAgICAgIG1hdGNoR2VuID0KLSAgICAgICAgICAgICAgICBuZXcgTWF0Y2hHZW5lcmF0b3IoQUNDX1BVQkxJQyB8IEFDQ19GSU5BTCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5UeXBlLkJPT0xFQU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlR5cGVbXSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlR5cGUuSU5ULAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgU3RyaW5nW10gewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm5vZGUiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibWF0Y2hlc0Zyb20iLCBfY2xhc3NOYW1lLCBpbCwgY3BnKTsKLQotICAgICAgICAgICAgY29tcGlsZUxvY2Fscyhub2RlQ291bnRlckdlbixtYXRjaEdlbixpbCk7Ci0KLSAgICAgICAgICAgIC8vIFRyYW5zbGF0ZSBQYXR0ZXJuCi0gICAgICAgICAgICBpbC5hcHBlbmQobWF0Y2hHZW4ubG9hZENvbnRleHROb2RlKCkpOwotICAgICAgICAgICAgX2Zyb20udHJhbnNsYXRlKG5vZGVDb3VudGVyR2VuLCBtYXRjaEdlbik7Ci0gICAgICAgICAgICBfZnJvbS5zeW50aGVzaXplKG5vZGVDb3VudGVyR2VuLCBtYXRjaEdlbik7Ci0gICAgICAgICAgICBpbC5hcHBlbmQoSVJFVFVSTik7Ci0KLSAgICAgICAgICAgIG5vZGVDb3VudGVyR2VuLmFkZE1ldGhvZChtYXRjaEdlbik7Ci0gICAgICAgIH0KLQotICAgICAgICAvKgotICAgICAgICAgKiBDb21waWxlIG1ldGhvZCBtYXRjaGVzQ291bnQoKQotICAgICAgICAgKi8KLSAgICAgICAgaWYgKF9jb3VudCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpbCA9IG5ldyBJbnN0cnVjdGlvbkxpc3QoKTsKLSAgICAgICAgICAgIG1hdGNoR2VuID0gbmV3IE1hdGNoR2VuZXJhdG9yKEFDQ19QVUJMSUMgfCBBQ0NfRklOQUwsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlR5cGUuQk9PTEVBTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlR5cGVbXSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5UeXBlLklOVCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgU3RyaW5nW10gewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJub2RlIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibWF0Y2hlc0NvdW50IiwgX2NsYXNzTmFtZSwgaWwsIGNwZyk7Ci0KLSAgICAgICAgICAgIGNvbXBpbGVMb2NhbHMobm9kZUNvdW50ZXJHZW4sbWF0Y2hHZW4saWwpOwotCi0gICAgICAgICAgICAvLyBUcmFuc2xhdGUgUGF0dGVybgotICAgICAgICAgICAgaWwuYXBwZW5kKG1hdGNoR2VuLmxvYWRDb250ZXh0Tm9kZSgpKTsKLSAgICAgICAgICAgIF9jb3VudC50cmFuc2xhdGUobm9kZUNvdW50ZXJHZW4sIG1hdGNoR2VuKTsKLSAgICAgICAgICAgIF9jb3VudC5zeW50aGVzaXplKG5vZGVDb3VudGVyR2VuLCBtYXRjaEdlbik7Ci0KLSAgICAgICAgICAgIGlsLmFwcGVuZChJUkVUVVJOKTsKLQotICAgICAgICAgICAgbm9kZUNvdW50ZXJHZW4uYWRkTWV0aG9kKG1hdGNoR2VuKTsKLSAgICAgICAgfQotCi0gICAgICAgIGdldFhTTFRDKCkuZHVtcENsYXNzKG5vZGVDb3VudGVyR2VuLmdldEphdmFDbGFzcygpKTsKLQotICAgICAgICAvLyBQdXNoIGFuIGluc3RhbmNlIG9mIHRoZSBuZXdseSBjcmVhdGVkIGNsYXNzCi0gICAgICAgIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotICAgICAgICBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQotICAgICAgICBmaW5hbCBpbnQgaW5kZXggPSBjcGcuYWRkTWV0aG9kcmVmKF9jbGFzc05hbWUsICI8aW5pdD4iLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoIiArIFRSQU5TTEVUX0lOVEZfU0lHCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBET01fSU5URl9TSUcKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIE5PREVfSVRFUkFUT1JfU0lHCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiWilWIik7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgTkVXKGNwZy5hZGRDbGFzcyhfY2xhc3NOYW1lKSkpOwotICAgICAgICBpbC5hcHBlbmQoRFVQKTsKLSAgICAgICAgaWwuYXBwZW5kKGNsYXNzR2VuLmxvYWRUcmFuc2xldCgpKTsKLSAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkRE9NKCkpOwotICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRJdGVyYXRvcigpKTsKLSAgICAgICAgaWwuYXBwZW5kKF9mcm9tICE9IG51bGwgPyBJQ09OU1RfMSA6IElDT05TVF8wKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VTUEVDSUFMKGluZGV4KSk7Ci0KLSAgICAgICAgLy8gSW5pdGlhbGl6ZSBjbG9zdXJlIHZhcmlhYmxlcwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNsb3N1cmVMZW47IGkrKykgewotICAgICAgICAgICAgZmluYWwgVmFyaWFibGVSZWZCYXNlIHZhclJlZiA9IChWYXJpYWJsZVJlZkJhc2UpIF9jbG9zdXJlVmFycy5nZXQoaSk7Ci0gICAgICAgICAgICBmaW5hbCBWYXJpYWJsZUJhc2UgdmFyID0gdmFyUmVmLmdldFZhcmlhYmxlKCk7Ci0gICAgICAgICAgICBmaW5hbCBUeXBlIHZhclR5cGUgPSB2YXIuZ2V0VHlwZSgpOwotCi0gICAgICAgICAgICAvLyBTdG9yZSB2YXJpYWJsZSBpbiBuZXcgY2xvc3VyZQotICAgICAgICAgICAgaWwuYXBwZW5kKERVUCk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQodmFyLmxvYWRJbnN0cnVjdGlvbigpKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgUFVURklFTEQoCi0gICAgICAgICAgICAgICAgICAgIGNwZy5hZGRGaWVsZHJlZihfY2xhc3NOYW1lLCB2YXIuZ2V0RXNjYXBlZE5hbWUoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgIHZhclR5cGUudG9TaWduYXR1cmUoKSkpKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotICAgICAgICBpbnQgaW5kZXg7Ci0gICAgICAgIGZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCi0gICAgICAgIC8vIFB1c2ggInRoaXMiIGZvciB0aGUgY2FsbCB0byBjaGFyYWN0ZXJzKCkKLSAgICAgICAgaWwuYXBwZW5kKGNsYXNzR2VuLmxvYWRUcmFuc2xldCgpKTsKLQotICAgICAgICBpZiAoaGFzVmFsdWUoKSkgewotICAgICAgICAgICAgY29tcGlsZURlZmF1bHQoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgICAgICBfdmFsdWUudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCi0gICAgICAgICAgICAvLyBVc2luZyBqYXZhLmxhbmcuTWF0aC5mbG9vcihudW1iZXIgKyAwLjUpIHRvIHJldHVybiBhIGRvdWJsZSB2YWx1ZQotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgMC41KSk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQoREFERCk7Ci0gICAgICAgICAgICBpbmRleCA9IGNwZy5hZGRNZXRob2RyZWYoTUFUSF9DTEFTUywgImZsb29yIiwgIihEKUQiKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFU1RBVElDKGluZGV4KSk7Ci0KLSAgICAgICAgICAgIC8vIENhbGwgc2V0VmFsdWUgb24gdGhlIG5vZGUgY291bnRlcgotICAgICAgICAgICAgaW5kZXggPSBjcGcuYWRkTWV0aG9kcmVmKE5PREVfQ09VTlRFUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAic2V0VmFsdWUiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoRCkiICsgTk9ERV9DT1VOVEVSX1NJRyk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRVZJUlRVQUwoaW5kZXgpKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChpc0RlZmF1bHQoKSkgewotICAgICAgICAgICAgY29tcGlsZURlZmF1bHQoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBjb21waWxlUGF0dGVybnMoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBDYWxsIHNldFN0YXJ0Tm9kZSgpCi0gICAgICAgIGlmICghaGFzVmFsdWUoKSkgewotICAgICAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkQ29udGV4dE5vZGUoKSk7Ci0gICAgICAgICAgICBpbmRleCA9IGNwZy5hZGRNZXRob2RyZWYoTk9ERV9DT1VOVEVSLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNFVF9TVEFSVF9OT0RFLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoSSkiICsgTk9ERV9DT1VOVEVSX1NJRyk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRVZJUlRVQUwoaW5kZXgpKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIENhbGwgZ2V0Q291bnRlcigpIHdpdGggb3Igd2l0aG91dCBhcmdzCi0gICAgICAgIGlmIChfZm9ybWF0TmVlZGVkKSB7Ci0gICAgICAgICAgICBpZiAoX2Zvcm1hdCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgX2Zvcm1hdC50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCAiMSIpKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKF9sYW5nICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBfbGFuZy50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCAiZW4iKSk7ICAgICAgICAgLy8gVE9ETyA/PwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAoX2xldHRlclZhbHVlICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBfbGV0dGVyVmFsdWUudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgQ29uc3RhbnRzLkVNUFRZU1RSSU5HKSk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmIChfZ3JvdXBpbmdTZXBhcmF0b3IgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIF9ncm91cGluZ1NlcGFyYXRvci50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBDb25zdGFudHMuRU1QVFlTVFJJTkcpKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKF9ncm91cGluZ1NpemUgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIF9ncm91cGluZ1NpemUudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgIjAiKSk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGluZGV4ID0gY3BnLmFkZE1ldGhvZHJlZihOT0RFX0NPVU5URVIsICJnZXRDb3VudGVyIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKCIgKyBTVFJJTkdfU0lHICsgU1RSSU5HX1NJRwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgU1RSSU5HX1NJRyArIFNUUklOR19TSUcKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIFNUUklOR19TSUcgKyAiKSIgKyBTVFJJTkdfU0lHKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChpbmRleCkpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgaW5kZXggPSBjcGcuYWRkTWV0aG9kcmVmKE5PREVfQ09VTlRFUiwgInNldERlZmF1bHRGb3JtYXR0aW5nIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKCkiICsgTk9ERV9DT1VOVEVSX1NJRyk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRVZJUlRVQUwoaW5kZXgpKTsKLQotICAgICAgICAgICAgaW5kZXggPSBjcGcuYWRkTWV0aG9kcmVmKE5PREVfQ09VTlRFUiwgImdldENvdW50ZXIiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoKSIgKyBTVFJJTkdfU0lHKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChpbmRleCkpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gT3V0cHV0IHRoZSByZXN1bHRpbmcgc3RyaW5nIHRvIHRoZSBoYW5kbGVyCi0gICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZEhhbmRsZXIoKSk7Ci0gICAgICAgIGluZGV4ID0gY3BnLmFkZE1ldGhvZHJlZihUUkFOU0xFVF9DTEFTUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENIQVJBQ1RFUlNXLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ0hBUkFDVEVSU1dfU0lHKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VWSVJUVUFMKGluZGV4KSk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9OdW1iZXJDYWxsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL051bWJlckNhbGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZDYyMWJmMi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL051bWJlckNhbGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDcwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IE51bWJlckNhbGwuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8wMiAxMDozOToxMCBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JbnN0cnVjdGlvbkxpc3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuQ2xhc3NHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuTWV0aG9kR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZUNoZWNrRXJyb3I7Ci0KLS8qKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICovCi1maW5hbCBjbGFzcyBOdW1iZXJDYWxsIGV4dGVuZHMgRnVuY3Rpb25DYWxsIHsKLQotICAgIHB1YmxpYyBOdW1iZXJDYWxsKFFOYW1lIGZuYW1lLCBWZWN0b3IgYXJndW1lbnRzKSB7Ci0gICAgICAgIHN1cGVyKGZuYW1lLCBhcmd1bWVudHMpOwotICAgIH0KLQotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0gICAgICAgIGlmIChhcmd1bWVudENvdW50KCkgPiAwKSB7Ci0gICAgICAgICAgICBhcmd1bWVudCgpLnR5cGVDaGVjayhzdGFibGUpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBfdHlwZSA9IFR5cGUuUmVhbDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotICAgICAgICBUeXBlIHRhcmc7Ci0KLSAgICAgICAgaWYgKGFyZ3VtZW50Q291bnQoKSA9PSAwKSB7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRDb250ZXh0Tm9kZSgpKTsKLSAgICAgICAgICAgIHRhcmcgPSBUeXBlLk5vZGU7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBmaW5hbCBFeHByZXNzaW9uIGFyZyA9IGFyZ3VtZW50KCk7Ci0gICAgICAgICAgICBhcmcudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICAgICAgYXJnLnN0YXJ0SXRlcmF0b3IoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgICAgICB0YXJnID0gYXJnLmdldFR5cGUoKTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmICghdGFyZy5pZGVudGljYWxUbyhUeXBlLlJlYWwpKSB7Ci0gICAgICAgICAgICB0YXJnLnRyYW5zbGF0ZVRvKGNsYXNzR2VuLCBtZXRob2RHZW4sIFR5cGUuUmVhbCk7Ci0gICAgICAgIH0KLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL090aGVyd2lzZS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9PdGhlcndpc2UuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYjEzNTg5MC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL090aGVyd2lzZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTUgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogT3RoZXJ3aXNlLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMDIgMTA6NTg6NTYgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuQ2xhc3NHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuRXJyb3JNc2c7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuTWV0aG9kR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZUNoZWNrRXJyb3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVXRpbDsKLQotLyoqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKi8KLWZpbmFsIGNsYXNzIE90aGVyd2lzZSBleHRlbmRzIEluc3RydWN0aW9uIHsKLSAgICBwdWJsaWMgdm9pZCBkaXNwbGF5KGludCBpbmRlbnQpIHsKLSAgICAgICAgaW5kZW50KGluZGVudCk7Ci0gICAgICAgIFV0aWwucHJpbnRsbigiT3RoZXJ3aXNlIik7Ci0gICAgICAgIGluZGVudChpbmRlbnQgKyBJbmRlbnRJbmNyZW1lbnQpOwotICAgICAgICBkaXNwbGF5Q29udGVudHMoaW5kZW50ICsgSW5kZW50SW5jcmVtZW50KTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgVHlwZSB0eXBlQ2hlY2soU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgewotICAgICAgICB0eXBlQ2hlY2tDb250ZW50cyhzdGFibGUpOwotICAgICAgICByZXR1cm4gVHlwZS5Wb2lkOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotICAgICAgICBmaW5hbCBQYXJzZXIgcGFyc2VyID0gZ2V0UGFyc2VyKCk7Ci0gICAgICAgIGZpbmFsIEVycm9yTXNnIGVyciA9IG5ldyBFcnJvck1zZyhFcnJvck1zZy5TVFJBWV9PVEhFUldJU0VfRVJSLCB0aGlzKTsKLSAgICAgICAgcGFyc2VyLnJlcG9ydEVycm9yKENvbnN0YW50cy5FUlJPUiwgZXJyKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL091dHB1dC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9PdXRwdXQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMGYxODNiOS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL091dHB1dC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDIxICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IE91dHB1dC5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzEyIDEwOjUzOjAwIHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtV3JpdGVyOwotaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0aWVzOwotaW1wb3J0IGphdmEudXRpbC5TdHJpbmdUb2tlbml6ZXI7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLk91dHB1dEtleXM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkNvbnN0YW50UG9vbEdlbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklOVk9LRVZJUlRVQUw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JbnN0cnVjdGlvbkxpc3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5QVVNIOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuUFVURklFTEQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuQ2xhc3NHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuRXJyb3JNc2c7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuTWV0aG9kR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlV0aWw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyLkVuY29kaW5nczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLlhNTDExQ2hhcjsKLQotLyoqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqLwotZmluYWwgY2xhc3MgT3V0cHV0IGV4dGVuZHMgVG9wTGV2ZWxFbGVtZW50IHsKLQotICAgIC8vIFRPRE86IHVzZSB0aHJlZS12YWx1ZSB2YXJpYWJsZXMgZm9yIGJvb2xlYW4gdmFsdWVzOiB0cnVlL2ZhbHNlL2RlZmF1bHQKLQotICAgIC8vIFRoZXNlIGF0dHJpYnV0ZXMgYXJlIGV4dHJhY3RlZCBmcm9tIHRoZSB4c2w6b3V0cHV0IGVsZW1lbnQuIFRoZXkgYWxzbwotICAgIC8vIGFwcGVhciBhcyBmaWVsZHMgKHdpdGggdGhlIHNhbWUgdHlwZSwgb25seSBwdWJsaWMpIGluIHRoZSB0cmFuc2xldAotICAgIHByaXZhdGUgU3RyaW5nICBfdmVyc2lvbjsKLSAgICBwcml2YXRlIFN0cmluZyAgX21ldGhvZDsKLSAgICBwcml2YXRlIFN0cmluZyAgX2VuY29kaW5nOwotICAgIHByaXZhdGUgYm9vbGVhbiBfb21pdEhlYWRlciA9IGZhbHNlOwotICAgIHByaXZhdGUgU3RyaW5nICBfc3RhbmRhbG9uZTsKLSAgICBwcml2YXRlIFN0cmluZyAgX2RvY3R5cGVQdWJsaWM7Ci0gICAgcHJpdmF0ZSBTdHJpbmcgIF9kb2N0eXBlU3lzdGVtOwotICAgIHByaXZhdGUgU3RyaW5nICBfY2RhdGE7Ci0gICAgcHJpdmF0ZSBib29sZWFuIF9pbmRlbnQgPSBmYWxzZTsKLSAgICBwcml2YXRlIFN0cmluZyAgX21lZGlhVHlwZTsKLSAgICBwcml2YXRlIFN0cmluZyBfaW5kZW50YW1vdW50OwotCi0gICAgLy8gRGlzYWJsZXMgdGhpcyBvdXRwdXQgZWxlbWVudCAod2hlbiBvdGhlciBlbGVtZW50IGhhcyBoaWdoZXIgcHJlY2VkZW5jZSkKLSAgICBwcml2YXRlIGJvb2xlYW4gX2Rpc2FibGVkID0gZmFsc2U7Ci0KLSAgICAvLyBTb21lIGdsb2JhbCBjb25zdGFudHMKLSAgICBwcml2YXRlIGZpbmFsIHN0YXRpYyBTdHJpbmcgU1RSSU5HX1NJRyA9ICJMamF2YS9sYW5nL1N0cmluZzsiOwotICAgIHByaXZhdGUgZmluYWwgc3RhdGljIFN0cmluZyBYTUxfVkVSU0lPTiA9ICIxLjAiOwotICAgIHByaXZhdGUgZmluYWwgc3RhdGljIFN0cmluZyBIVE1MX1ZFUlNJT04gPSAiNC4wIjsKLQotICAgIC8qKgotICAgICAqIERpc3BsYXlzIHRoZSBjb250ZW50cyBvZiB0aGlzIGVsZW1lbnQgKGZvciBkZWJ1Z2dpbmcpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZGlzcGxheShpbnQgaW5kZW50KSB7Ci0gICAgICAgIGluZGVudChpbmRlbnQpOwotICAgICAgICBVdGlsLnByaW50bG4oIk91dHB1dCAiICsgX21ldGhvZCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRGlzYWJsZXMgdGhpcyA8eHNsOm91dHB1dD4gZWxlbWVudCBpbiBjYXNlIHdoZXJlIHRoZXJlIGFyZSBzb21lIG90aGVyCi0gICAgICogPHhzbDpvdXRwdXQ+IGVsZW1lbnQgKGZyb20gYSBkaWZmZXJlbnQgaW1wb3J0ZWQvaW5jbHVkZWQgc3R5bGVzaGVldCkKLSAgICAgKiB3aXRoIGhpZ2hlciBwcmVjZWRlbmNlLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGRpc2FibGUoKSB7Ci0gICAgICAgIF9kaXNhYmxlZCA9IHRydWU7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gZW5hYmxlZCgpIHsKLSAgICAgICAgcmV0dXJuICFfZGlzYWJsZWQ7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRDZGF0YSgpIHsKLSAgICAgICAgcmV0dXJuIF9jZGF0YTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldE91dHB1dE1ldGhvZCgpIHsKLSAgICAgICAgcmV0dXJuIF9tZXRob2Q7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIHRyYW5zZmVyQXR0cmlidXRlKE91dHB1dCBwcmV2aW91cywgU3RyaW5nIHFuYW1lKSB7Ci0gICAgICAgIGlmICghaGFzQXR0cmlidXRlKHFuYW1lKSAmJiBwcmV2aW91cy5oYXNBdHRyaWJ1dGUocW5hbWUpKSB7Ci0gICAgICAgICAgICBhZGRBdHRyaWJ1dGUocW5hbWUsIHByZXZpb3VzLmdldEF0dHJpYnV0ZShxbmFtZSkpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgbWVyZ2VPdXRwdXQoT3V0cHV0IHByZXZpb3VzKSB7Ci0gICAgICAgIC8vIFRyYW5zZmVyIGF0dHJpYnV0ZXMgZnJvbSBwcmV2aW91cyB4c2w6b3V0cHV0Ci0gICAgICAgIHRyYW5zZmVyQXR0cmlidXRlKHByZXZpb3VzLCAidmVyc2lvbiIpOwotICAgICAgICB0cmFuc2ZlckF0dHJpYnV0ZShwcmV2aW91cywgIm1ldGhvZCIpOwotICAgICAgICB0cmFuc2ZlckF0dHJpYnV0ZShwcmV2aW91cywgImVuY29kaW5nIik7Ci0gICAgICAgIHRyYW5zZmVyQXR0cmlidXRlKHByZXZpb3VzLCAiZG9jdHlwZS1zeXN0ZW0iKTsKLSAgICAgICAgdHJhbnNmZXJBdHRyaWJ1dGUocHJldmlvdXMsICJkb2N0eXBlLXB1YmxpYyIpOwotICAgICAgICB0cmFuc2ZlckF0dHJpYnV0ZShwcmV2aW91cywgIm1lZGlhLXR5cGUiKTsKLSAgICAgICAgdHJhbnNmZXJBdHRyaWJ1dGUocHJldmlvdXMsICJpbmRlbnQiKTsKLSAgICAgICAgdHJhbnNmZXJBdHRyaWJ1dGUocHJldmlvdXMsICJvbWl0LXhtbC1kZWNsYXJhdGlvbiIpOwotICAgICAgICB0cmFuc2ZlckF0dHJpYnV0ZShwcmV2aW91cywgInN0YW5kYWxvbmUiKTsKLQotICAgICAgICAvLyBNZXJnZSBjZGF0YS1zZWN0aW9uLWVsZW1lbnRzCi0gICAgICAgIGlmIChwcmV2aW91cy5oYXNBdHRyaWJ1dGUoImNkYXRhLXNlY3Rpb24tZWxlbWVudHMiKSkgewotICAgICAgICAgICAgLy8gYWRkQXR0cmlidXRlIHdvcmtzIGFzIGEgc2V0dGVyIGlmIGl0IGFscmVhZHkgZXhpc3RzCi0gICAgICAgICAgICBhZGRBdHRyaWJ1dGUoImNkYXRhLXNlY3Rpb24tZWxlbWVudHMiLAotICAgICAgICAgICAgICAgIHByZXZpb3VzLmdldEF0dHJpYnV0ZSgiY2RhdGEtc2VjdGlvbi1lbGVtZW50cyIpICsgJyAnICsKLSAgICAgICAgICAgICAgICBnZXRBdHRyaWJ1dGUoImNkYXRhLXNlY3Rpb24tZWxlbWVudHMiKSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBUcmFuc2ZlciBub24tc3RhbmRhcmQgYXR0cmlidXRlcyBhcyB3ZWxsCi0gICAgICAgIFN0cmluZyBwcmVmaXggPSBsb29rdXBQcmVmaXgoImh0dHA6Ly94bWwuYXBhY2hlLm9yZy94YWxhbiIpOwotICAgICAgICBpZiAocHJlZml4ICE9IG51bGwpIHsKLSAgICAgICAgICAgIHRyYW5zZmVyQXR0cmlidXRlKHByZXZpb3VzLCBwcmVmaXggKyAnOicgKyAiaW5kZW50LWFtb3VudCIpOwotICAgICAgICB9Ci0gICAgICAgIHByZWZpeCA9IGxvb2t1cFByZWZpeCgiaHR0cDovL3htbC5hcGFjaGUub3JnL3hzbHQiKTsKLSAgICAgICAgaWYgKHByZWZpeCAhPSBudWxsKSB7Ci0gICAgICAgICAgICB0cmFuc2ZlckF0dHJpYnV0ZShwcmV2aW91cywgcHJlZml4ICsgJzonICsgImluZGVudC1hbW91bnQiKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNjYW5zIHRoZSBhdHRyaWJ1dGUgbGlzdCBmb3IgdGhlIHhzbDpvdXRwdXQgaW5zdHJ1Y3Rpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBwYXJzZUNvbnRlbnRzKFBhcnNlciBwYXJzZXIpIHsKLSAgICAgICAgZmluYWwgUHJvcGVydGllcyBvdXRwdXRQcm9wZXJ0aWVzID0gbmV3IFByb3BlcnRpZXMoKTsKLQotICAgICAgICAvLyBBc2sgdGhlIHBhcnNlciBpZiBpdCB3YW50cyB0aGlzIDx4c2w6b3V0cHV0PiBlbGVtZW50Ci0gICAgICAgIHBhcnNlci5zZXRPdXRwdXQodGhpcyk7Ci0KLSAgICAgICAgLy8gRG8gbm90aGluZyBpZiBvdGhlciA8eHNsOm91dHB1dD4gZWxlbWVudCBoYXMgaGlnaGVyIHByZWNlZGVuY2UKLSAgICAgICAgaWYgKF9kaXNhYmxlZCkgcmV0dXJuOwotCi0gICAgICAgIFN0cmluZyBhdHRyaWIgPSBudWxsOwotCi0gICAgICAgIC8vIEdldCB0aGUgb3V0cHV0IHZlcnNpb24KLSAgICAgICAgX3ZlcnNpb24gPSBnZXRBdHRyaWJ1dGUoInZlcnNpb24iKTsKLSAgICAgICAgaWYgKF92ZXJzaW9uLmVxdWFscyhDb25zdGFudHMuRU1QVFlTVFJJTkcpKSB7Ci0gICAgICAgICAgICBfdmVyc2lvbiA9IG51bGw7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBvdXRwdXRQcm9wZXJ0aWVzLnNldFByb3BlcnR5KE91dHB1dEtleXMuVkVSU0lPTiwgX3ZlcnNpb24pOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gR2V0IHRoZSBvdXRwdXQgbWV0aG9kIC0gInhtbCIsICJodG1sIiwgInRleHQiIG9yIDxxbmFtZT4gKGJ1dCBub3QgbmNuYW1lKQotICAgICAgICBfbWV0aG9kID0gZ2V0QXR0cmlidXRlKCJtZXRob2QiKTsKLSAgICAgICAgaWYgKF9tZXRob2QuZXF1YWxzKENvbnN0YW50cy5FTVBUWVNUUklORykpIHsKLSAgICAgICAgICAgIF9tZXRob2QgPSBudWxsOwotICAgICAgICB9Ci0gICAgICAgIGlmIChfbWV0aG9kICE9IG51bGwpIHsKLSAgICAgICAgICAgIF9tZXRob2QgPSBfbWV0aG9kLnRvTG93ZXJDYXNlKCk7Ci0gICAgICAgICAgICBpZiAoKF9tZXRob2QuZXF1YWxzKCJ4bWwiKSl8fAotICAgICAgICAgICAgICAgIChfbWV0aG9kLmVxdWFscygiaHRtbCIpKXx8Ci0gICAgICAgICAgICAgICAgKF9tZXRob2QuZXF1YWxzKCJ0ZXh0IikpfHwKLSAgICAgICAgICAgICAgICAoKFhNTDExQ2hhci5pc1hNTDExVmFsaWRRTmFtZShfbWV0aG9kKSYmKF9tZXRob2QuaW5kZXhPZigiOiIpID4gMCkpKSkgewotICAgICAgICAgICAgICAgb3V0cHV0UHJvcGVydGllcy5zZXRQcm9wZXJ0eShPdXRwdXRLZXlzLk1FVEhPRCwgX21ldGhvZCk7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIHJlcG9ydEVycm9yKHRoaXMsIHBhcnNlciwgRXJyb3JNc2cuSU5WQUxJRF9NRVRIT0RfSU5fT1VUUFVULCBfbWV0aG9kKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIEdldCB0aGUgb3V0cHV0IGVuY29kaW5nIC0gYW55IHZhbHVlIGFjY2VwdGVkIGhlcmUKLSAgICAgICAgX2VuY29kaW5nID0gZ2V0QXR0cmlidXRlKCJlbmNvZGluZyIpOwotICAgICAgICBpZiAoX2VuY29kaW5nLmVxdWFscyhDb25zdGFudHMuRU1QVFlTVFJJTkcpKSB7Ci0gICAgICAgICAgICBfZW5jb2RpbmcgPSBudWxsOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAvLyBDcmVhdGUgYSB3cml0ZSB0byB2ZXJpZnkgZW5jb2Rpbmcgc3VwcG9ydAotICAgICAgICAgICAgICAgIFN0cmluZyBjYW5vbmljYWxFbmNvZGluZzsKLSAgICAgICAgICAgICAgICBjYW5vbmljYWxFbmNvZGluZyA9IEVuY29kaW5ncy5jb252ZXJ0TWltZTJKYXZhRW5jb2RpbmcoX2VuY29kaW5nKTsKLSAgICAgICAgICAgICAgICBPdXRwdXRTdHJlYW1Xcml0ZXIgd3JpdGVyID0KLSAgICAgICAgICAgICAgICAgICAgbmV3IE91dHB1dFN0cmVhbVdyaXRlcihTeXN0ZW0ub3V0LCBjYW5vbmljYWxFbmNvZGluZyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXRjaCAoamF2YS5pby5VbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICBFcnJvck1zZyBtc2cgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuVU5TVVBQT1JURURfRU5DT0RJTkcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9lbmNvZGluZywgdGhpcyk7Ci0gICAgICAgICAgICAgICAgcGFyc2VyLnJlcG9ydEVycm9yKENvbnN0YW50cy5XQVJOSU5HLCBtc2cpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgb3V0cHV0UHJvcGVydGllcy5zZXRQcm9wZXJ0eShPdXRwdXRLZXlzLkVOQ09ESU5HLCBfZW5jb2RpbmcpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gU2hvdWxkIHRoZSBYTUwgaGVhZGVyIGJlIG9taXR0ZWQgLSB0cmFuc2xhdGUgdG8gdHJ1ZS9mYWxzZQotICAgICAgICBhdHRyaWIgPSBnZXRBdHRyaWJ1dGUoIm9taXQteG1sLWRlY2xhcmF0aW9uIik7Ci0gICAgICAgIGlmICghYXR0cmliLmVxdWFscyhDb25zdGFudHMuRU1QVFlTVFJJTkcpKSB7Ci0gICAgICAgICAgICBpZiAoYXR0cmliLmVxdWFscygieWVzIikpIHsKLSAgICAgICAgICAgICAgICBfb21pdEhlYWRlciA9IHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBvdXRwdXRQcm9wZXJ0aWVzLnNldFByb3BlcnR5KE91dHB1dEtleXMuT01JVF9YTUxfREVDTEFSQVRJT04sIGF0dHJpYik7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBBZGQgJ3N0YW5kYWxvbmUnIGRlY2FyYXRpb24gdG8gb3V0cHV0IC0gdXNlIHRleHQgYXMgaXMKLSAgICAgICAgX3N0YW5kYWxvbmUgPSBnZXRBdHRyaWJ1dGUoInN0YW5kYWxvbmUiKTsKLSAgICAgICAgaWYgKF9zdGFuZGFsb25lLmVxdWFscyhDb25zdGFudHMuRU1QVFlTVFJJTkcpKSB7Ci0gICAgICAgICAgICBfc3RhbmRhbG9uZSA9IG51bGw7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBvdXRwdXRQcm9wZXJ0aWVzLnNldFByb3BlcnR5KE91dHB1dEtleXMuU1RBTkRBTE9ORSwgX3N0YW5kYWxvbmUpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gR2V0IHN5c3RlbS9wdWJsaWMgaWRlbnRpZmllcnMgZm9yIG91dHB1dCBET0NUWVBFIGRlY2xhcmF0aW9uCi0gICAgICAgIF9kb2N0eXBlU3lzdGVtID0gZ2V0QXR0cmlidXRlKCJkb2N0eXBlLXN5c3RlbSIpOwotICAgICAgICBpZiAoX2RvY3R5cGVTeXN0ZW0uZXF1YWxzKENvbnN0YW50cy5FTVBUWVNUUklORykpIHsKLSAgICAgICAgICAgIF9kb2N0eXBlU3lzdGVtID0gbnVsbDsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIG91dHB1dFByb3BlcnRpZXMuc2V0UHJvcGVydHkoT3V0cHV0S2V5cy5ET0NUWVBFX1NZU1RFTSwgX2RvY3R5cGVTeXN0ZW0pOwotICAgICAgICB9Ci0KLQotICAgICAgICBfZG9jdHlwZVB1YmxpYyA9IGdldEF0dHJpYnV0ZSgiZG9jdHlwZS1wdWJsaWMiKTsKLSAgICAgICAgaWYgKF9kb2N0eXBlUHVibGljLmVxdWFscyhDb25zdGFudHMuRU1QVFlTVFJJTkcpKSB7Ci0gICAgICAgICAgICBfZG9jdHlwZVB1YmxpYyA9IG51bGw7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBvdXRwdXRQcm9wZXJ0aWVzLnNldFByb3BlcnR5KE91dHB1dEtleXMuRE9DVFlQRV9QVUJMSUMsIF9kb2N0eXBlUHVibGljKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIE5hbWVzIHRoZSBlbGVtZW50cyBvZiB3aG9zZSB0ZXh0IGNvbnRlbnRzIHNob3VsZCBiZSBvdXRwdXQgYXMgQ0RBVEEKLSAgICAgICAgX2NkYXRhID0gZ2V0QXR0cmlidXRlKCJjZGF0YS1zZWN0aW9uLWVsZW1lbnRzIik7Ci0gICAgICAgIGlmIChfY2RhdGEuZXF1YWxzKENvbnN0YW50cy5FTVBUWVNUUklORykpIHsKLSAgICAgICAgICAgIF9jZGF0YSA9IG51bGw7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBTdHJpbmdCdWZmZXIgZXhwYW5kZWROYW1lcyA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLSAgICAgICAgICAgIFN0cmluZ1Rva2VuaXplciB0b2tlbnMgPSBuZXcgU3RyaW5nVG9rZW5pemVyKF9jZGF0YSk7Ci0KLSAgICAgICAgICAgIC8vIE1ha2Ugc3VyZSB0byBzdG9yZSBuYW1lcyBpbiBleHBhbmRlZCBmb3JtCi0gICAgICAgICAgICB3aGlsZSAodG9rZW5zLmhhc01vcmVUb2tlbnMoKSkgewotICAgICAgICAgICAgICAgIFN0cmluZyBxbmFtZSA9IHRva2Vucy5uZXh0VG9rZW4oKTsKLSAgICAgICAgICAgICAgICBpZiAoIVhNTDExQ2hhci5pc1hNTDExVmFsaWRRTmFtZShxbmFtZSkpIHsKLSAgICAgICAgICAgICAgICAgICAgRXJyb3JNc2cgZXJyID0gbmV3IEVycm9yTXNnKEVycm9yTXNnLklOVkFMSURfUU5BTUVfRVJSLCBxbmFtZSwgdGhpcyk7Ci0gICAgICAgICAgICAgICAgICAgIHBhcnNlci5yZXBvcnRFcnJvcihDb25zdGFudHMuRVJST1IsIGVycik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGV4cGFuZGVkTmFtZXMuYXBwZW5kKAotICAgICAgICAgICAgICAgICAgIHBhcnNlci5nZXRRTmFtZShxbmFtZSkudG9TdHJpbmcoKSkuYXBwZW5kKCcgJyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBfY2RhdGEgPSBleHBhbmRlZE5hbWVzLnRvU3RyaW5nKCk7Ci0gICAgICAgICAgICBvdXRwdXRQcm9wZXJ0aWVzLnNldFByb3BlcnR5KE91dHB1dEtleXMuQ0RBVEFfU0VDVElPTl9FTEVNRU5UUywKLSAgICAgICAgICAgICAgICBfY2RhdGEpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gR2V0IHRoZSBpbmRlbnQgc2V0dGluZyAtIG9ubHkgaGFzIGVmZmVjdCBmb3IgeG1sIGFuZCBodG1sIG91dHB1dAotICAgICAgICBhdHRyaWIgPSBnZXRBdHRyaWJ1dGUoImluZGVudCIpOwotICAgICAgICBpZiAoIWF0dHJpYi5lcXVhbHMoRU1QVFlTVFJJTkcpKSB7Ci0gICAgICAgICAgICBpZiAoYXR0cmliLmVxdWFscygieWVzIikpIHsKLSAgICAgICAgICAgICAgICBfaW5kZW50ID0gdHJ1ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIG91dHB1dFByb3BlcnRpZXMuc2V0UHJvcGVydHkoT3V0cHV0S2V5cy5JTkRFTlQsIGF0dHJpYik7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoX21ldGhvZCAhPSBudWxsICYmIF9tZXRob2QuZXF1YWxzKCJodG1sIikpIHsKLSAgICAgICAgICAgIF9pbmRlbnQgPSB0cnVlOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gaW5kZW50LWFtb3VudDogZXh0ZW5zaW9uIGF0dHJpYnV0ZSBvZiB4c2w6b3V0cHV0Ci0gICAgICAgIF9pbmRlbnRhbW91bnQgPSBnZXRBdHRyaWJ1dGUoCi0gICAgICAgICAgICBsb29rdXBQcmVmaXgoImh0dHA6Ly94bWwuYXBhY2hlLm9yZy94YWxhbiIpLCAiaW5kZW50LWFtb3VudCIpOwotICAgICAgICAvLyAgSGFjayBmb3Igc3VwcG9ydGluZyBPbGQgTmFtZXNwYWNlIFVSSS4KLSAgICAgICAgaWYgKF9pbmRlbnRhbW91bnQuZXF1YWxzKEVNUFRZU1RSSU5HKSl7Ci0gICAgICAgICAgICBfaW5kZW50YW1vdW50ID0gZ2V0QXR0cmlidXRlKAotICAgICAgICAgICAgICAgIGxvb2t1cFByZWZpeCgiaHR0cDovL3htbC5hcGFjaGUub3JnL3hzbHQiKSwgImluZGVudC1hbW91bnQiKTsKLSAgICAgICAgfQotICAgICAgICBpZiAoIV9pbmRlbnRhbW91bnQuZXF1YWxzKEVNUFRZU1RSSU5HKSkgewotICAgICAgICAgICAgb3V0cHV0UHJvcGVydGllcy5zZXRQcm9wZXJ0eSgiaW5kZW50X2Ftb3VudCIsIF9pbmRlbnRhbW91bnQpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gR2V0IHRoZSBNSU1FIHR5cGUgZm9yIHRoZSBvdXRwdXQgZmlsZQotICAgICAgICBfbWVkaWFUeXBlID0gZ2V0QXR0cmlidXRlKCJtZWRpYS10eXBlIik7Ci0gICAgICAgIGlmIChfbWVkaWFUeXBlLmVxdWFscyhDb25zdGFudHMuRU1QVFlTVFJJTkcpKSB7Ci0gICAgICAgICAgICBfbWVkaWFUeXBlID0gbnVsbDsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIG91dHB1dFByb3BlcnRpZXMuc2V0UHJvcGVydHkoT3V0cHV0S2V5cy5NRURJQV9UWVBFLCBfbWVkaWFUeXBlKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIEltcGxpZWQgcHJvcGVydGllcwotICAgICAgICBpZiAoX21ldGhvZCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAoX21ldGhvZC5lcXVhbHMoImh0bWwiKSkgewotICAgICAgICAgICAgICAgIGlmIChfdmVyc2lvbiA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIF92ZXJzaW9uID0gSFRNTF9WRVJTSU9OOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpZiAoX21lZGlhVHlwZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIF9tZWRpYVR5cGUgPSAidGV4dC9odG1sIjsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChfbWV0aG9kLmVxdWFscygidGV4dCIpKSB7Ci0gICAgICAgICAgICAgICAgaWYgKF9tZWRpYVR5cGUgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBfbWVkaWFUeXBlID0gInRleHQvcGxhaW4iOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIFNldCBvdXRwdXQgcHJvcGVydGllcyBpbiBjdXJyZW50IHN0eWxlc2hlZXQKLSAgICAgICAgcGFyc2VyLmdldEN1cnJlbnRTdHlsZXNoZWV0KCkuc2V0T3V0cHV0UHJvcGVydGllcyhvdXRwdXRQcm9wZXJ0aWVzKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb21waWxlIGNvZGUgdGhhdCBwYXNzZXMgdGhlIGluZm9ybWF0aW9uIGluIHRoaXMgPHhzbDpvdXRwdXQ+IGVsZW1lbnQKLSAgICAgKiB0byB0aGUgYXBwcm9wcmlhdGUgZmllbGRzIGluIHRoZSB0cmFuc2xldAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCi0gICAgICAgIC8vIERvIG5vdGhpbmcgaWYgb3RoZXIgPHhzbDpvdXRwdXQ+IGVsZW1lbnQgaGFzIGhpZ2hlciBwcmVjZWRlbmNlCi0gICAgICAgIGlmIChfZGlzYWJsZWQpIHJldHVybjsKLQotICAgICAgICBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgICAgIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQotICAgICAgICBpbnQgZmllbGQgPSAwOwotICAgICAgICBpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpOwotCi0gICAgICAgIC8vIE9ubHkgdXBkYXRlIF92ZXJzaW9uIGZpZWxkIGlmIHNldCBhbmQgZGlmZmVyZW50IGZyb20gZGVmYXVsdAotICAgICAgICBpZiAoKF92ZXJzaW9uICE9IG51bGwpICYmICghX3ZlcnNpb24uZXF1YWxzKFhNTF9WRVJTSU9OKSkpIHsKLSAgICAgICAgICAgIGZpZWxkID0gY3BnLmFkZEZpZWxkcmVmKFRSQU5TTEVUX0NMQVNTLCAiX3ZlcnNpb24iLCBTVFJJTkdfU0lHKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChEVVApOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgX3ZlcnNpb24pKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgUFVURklFTEQoZmllbGQpKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIE9ubHkgdXBkYXRlIF9tZXRob2QgZmllbGQgaWYgIm1ldGhvZCIgYXR0cmlidXRlIHVzZWQKLSAgICAgICAgaWYgKF9tZXRob2QgIT0gbnVsbCkgewotICAgICAgICAgICAgZmllbGQgPSBjcGcuYWRkRmllbGRyZWYoVFJBTlNMRVRfQ0xBU1MsICJfbWV0aG9kIiwgU1RSSU5HX1NJRyk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQoRFVQKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsIF9tZXRob2QpKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgUFVURklFTEQoZmllbGQpKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIE9ubHkgdXBkYXRlIGlmIF9lbmNvZGluZyBmaWVsZCBpcyAiZW5jb2RpbmciIGF0dHJpYnV0ZSB1c2VkCi0gICAgICAgIGlmIChfZW5jb2RpbmcgIT0gbnVsbCkgewotICAgICAgICAgICAgZmllbGQgPSBjcGcuYWRkRmllbGRyZWYoVFJBTlNMRVRfQ0xBU1MsICJfZW5jb2RpbmciLCBTVFJJTkdfU0lHKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChEVVApOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgX2VuY29kaW5nKSk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IFBVVEZJRUxEKGZpZWxkKSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBPbmx5IHVwZGF0ZSBpZiAib21pdC14bWwtZGVjbGFyYXRpb24iIHVzZWQgYW5kIHNldCB0byAneWVzJwotICAgICAgICBpZiAoX29taXRIZWFkZXIpIHsKLSAgICAgICAgICAgIGZpZWxkID0gY3BnLmFkZEZpZWxkcmVmKFRSQU5TTEVUX0NMQVNTLCAiX29taXRIZWFkZXIiLCAiWiIpOwotICAgICAgICAgICAgaWwuYXBwZW5kKERVUCk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBfb21pdEhlYWRlcikpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBQVVRGSUVMRChmaWVsZCkpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gQWRkICdzdGFuZGFsb25lJyBkZWNhcmF0aW9uIHRvIG91dHB1dCAtIHVzZSB0ZXh0IGFzIGlzCi0gICAgICAgIGlmIChfc3RhbmRhbG9uZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmaWVsZCA9IGNwZy5hZGRGaWVsZHJlZihUUkFOU0xFVF9DTEFTUywgIl9zdGFuZGFsb25lIiwgU1RSSU5HX1NJRyk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQoRFVQKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsIF9zdGFuZGFsb25lKSk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IFBVVEZJRUxEKGZpZWxkKSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBTZXQgc3lzdGVtL3B1YmxpYyBkb2N0eXBlIG9ubHkgaWYgYm90aCBhcmUgc2V0Ci0gICAgICAgIGZpZWxkID0gY3BnLmFkZEZpZWxkcmVmKFRSQU5TTEVUX0NMQVNTLCJfZG9jdHlwZVN5c3RlbSIsU1RSSU5HX1NJRyk7Ci0gICAgICAgIGlsLmFwcGVuZChEVVApOwotICAgICAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBfZG9jdHlwZVN5c3RlbSkpOwotICAgICAgICBpbC5hcHBlbmQobmV3IFBVVEZJRUxEKGZpZWxkKSk7Ci0gICAgICAgIGZpZWxkID0gY3BnLmFkZEZpZWxkcmVmKFRSQU5TTEVUX0NMQVNTLCJfZG9jdHlwZVB1YmxpYyIsU1RSSU5HX1NJRyk7Ci0gICAgICAgIGlsLmFwcGVuZChEVVApOwotICAgICAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBfZG9jdHlwZVB1YmxpYykpOwotICAgICAgICBpbC5hcHBlbmQobmV3IFBVVEZJRUxEKGZpZWxkKSk7Ci0KLSAgICAgICAgLy8gQWRkICdtZWR5ZS10eXBlJyBkZWNhcmF0aW9uIHRvIG91dHB1dCAtIGlmIHVzZWQKLSAgICAgICAgaWYgKF9tZWRpYVR5cGUgIT0gbnVsbCkgewotICAgICAgICAgICAgZmllbGQgPSBjcGcuYWRkRmllbGRyZWYoVFJBTlNMRVRfQ0xBU1MsICJfbWVkaWFUeXBlIiwgU1RSSU5HX1NJRyk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQoRFVQKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsIF9tZWRpYVR5cGUpKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgUFVURklFTEQoZmllbGQpKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIENvbXBpbGUgY29kZSB0byBzZXQgb3V0cHV0IGluZGVudGF0aW9uIG9uL29mZgotICAgICAgICBpZiAoX2luZGVudCkgewotICAgICAgICAgICAgZmllbGQgPSBjcGcuYWRkRmllbGRyZWYoVFJBTlNMRVRfQ0xBU1MsICJfaW5kZW50IiwgIloiKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChEVVApOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgX2luZGVudCkpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBQVVRGSUVMRChmaWVsZCkpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy9Db21waWxlIGNvZGUgdG8gc2V0IGluZGVudCBhbW91bnQuCi0gICAgICAgIGlmKF9pbmRlbnRhbW91bnQgIT0gbnVsbCAmJiAhX2luZGVudGFtb3VudC5lcXVhbHMoRU1QVFlTVFJJTkcpKXsKLSAgICAgICAgICAgIGZpZWxkID0gY3BnLmFkZEZpZWxkcmVmKFRSQU5TTEVUX0NMQVNTLCAiX2luZGVudGFtb3VudCIsICJJIik7Ci0gICAgICAgICAgICBpbC5hcHBlbmQoRFVQKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsIEludGVnZXIucGFyc2VJbnQoX2luZGVudGFtb3VudCkpKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgUFVURklFTEQoZmllbGQpKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIEZvcndhcmQgdG8gdGhlIHRyYW5zbGV0IGFueSBlbGVtZW50cyB0aGF0IHNob3VsZCBiZSBvdXRwdXQgYXMgQ0RBVEEKLSAgICAgICAgaWYgKF9jZGF0YSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpbnQgaW5kZXggPSBjcGcuYWRkTWV0aG9kcmVmKFRSQU5TTEVUX0NMQVNTLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYWRkQ2RhdGFFbGVtZW50IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIihMamF2YS9sYW5nL1N0cmluZzspViIpOwotCi0gICAgICAgICAgICBTdHJpbmdUb2tlbml6ZXIgdG9rZW5zID0gbmV3IFN0cmluZ1Rva2VuaXplcihfY2RhdGEpOwotICAgICAgICAgICAgd2hpbGUgKHRva2Vucy5oYXNNb3JlVG9rZW5zKCkpIHsKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQoRFVQKTsKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCB0b2tlbnMubmV4dFRva2VuKCkpKTsKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRVZJUlRVQUwoaW5kZXgpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBpbC5hcHBlbmQoUE9QKTsgLy8gQ2xlYW51cCAtIHBvcCBsYXN0IHRyYW5zbGV0IHJlZmVyZW5jZSBvZmYgc3RhY2sKLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvUGFyYW0uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvUGFyYW0uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNDFjOGZmMy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL1BhcmFtLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyNTggKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogUGFyYW0uamF2YSx2IDEuMi40LjEgMjAwNS8wOS8wMiAxMTowMzo0MiBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5jbGFzc2ZpbGUuRmllbGQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5CcmFuY2hIYW5kbGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5DSEVDS0NBU1Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JRk5PTk5VTEw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5Db25zdGFudFBvb2xHZW47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JTlZPS0VWSVJUVUFMOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW5zdHJ1Y3Rpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JbnN0cnVjdGlvbkxpc3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5QVVNIOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuUFVURklFTEQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuQ2xhc3NHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuRXJyb3JNc2c7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuTWV0aG9kR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlJlZmVyZW5jZVR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5PYmplY3RUeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGVDaGVja0Vycm9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5ydW50aW1lLkJhc2lzTGlicmFyeTsKLQotLyoqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqIEBhdXRob3IgRXJ3aW4gQm9sd2lkdCA8ZWpiQGtsb21wLm9yZz4KLSAqIEBhdXRob3IgSm9obiBIb3dhcmQgPEpvaG5IQHNjaGVtYXNvZnQuY29tPgotICovCi1maW5hbCBjbGFzcyBQYXJhbSBleHRlbmRzIFZhcmlhYmxlQmFzZSB7Ci0KLSAgICAvKioKLSAgICAgKiBUcnVlIGlmIHRoaXMgUGFyYW0gaXMgZGVjbGFyZWQgaW4gYSBzaW1wbGUgbmFtZWQgdGVtcGxhdGUuCi0gICAgICogVGhpcyBpcyB1c2VkIHRvIG9wdGltaXplIGNvZGVnZW4gZm9yIHBhcmFtZXRlciBwYXNzaW5nCi0gICAgICogaW4gbmFtZWQgdGVtcGxhdGVzLgotICAgICAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBfaXNJblNpbXBsZU5hbWVkVGVtcGxhdGUgPSBmYWxzZTsKLQotICAgIC8qKgotICAgICAqIERpc3BsYXkgdmFyaWFibGUgYXMgc2luZ2xlIHN0cmluZwotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0gICAgICAgIHJldHVybiAicGFyYW0oIiArIF9uYW1lICsgIikiOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldCB0aGUgaW5zdHJ1Y3Rpb24gZm9yIGxvYWRpbmcgdGhlIHZhbHVlIG9mIHRoaXMgdmFyaWFibGUgb250byB0aGUKLSAgICAgKiBKVk0gc3RhY2sgYW5kIHJldHVybnMgdGhlIG9sZCBpbnN0cnVjdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb24gc2V0TG9hZEluc3RydWN0aW9uKEluc3RydWN0aW9uIGluc3RydWN0aW9uKSB7Ci0gICAgICAgIEluc3RydWN0aW9uIHRtcCA9IF9sb2FkSW5zdHJ1Y3Rpb247Ci0gICAgICAgIF9sb2FkSW5zdHJ1Y3Rpb24gPSBpbnN0cnVjdGlvbjsKLSAgICAgICAgcmV0dXJuIHRtcDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIGluc3RydWN0aW9uIGZvciBzdG9yaW5nIGEgdmFsdWUgZnJvbSB0aGUgc3RhY2sgaW50byB0aGlzCi0gICAgICogdmFyaWFibGUgYW5kIHJldHVybnMgdGhlIG9sZCBpbnN0cnVjdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb24gc2V0U3RvcmVJbnN0cnVjdGlvbihJbnN0cnVjdGlvbiBpbnN0cnVjdGlvbikgewotICAgICAgICBJbnN0cnVjdGlvbiB0bXAgPSBfc3RvcmVJbnN0cnVjdGlvbjsKLSAgICAgICAgX3N0b3JlSW5zdHJ1Y3Rpb24gPSBpbnN0cnVjdGlvbjsKLSAgICAgICAgcmV0dXJuIHRtcDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBEaXNwbGF5IHZhcmlhYmxlIGluIGEgZnVsbCBBU1QgZHVtcAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGRpc3BsYXkoaW50IGluZGVudCkgewotICAgICAgICBpbmRlbnQoaW5kZW50KTsKLSAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJwYXJhbSAiICsgX25hbWUpOwotICAgICAgICBpZiAoX3NlbGVjdCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpbmRlbnQoaW5kZW50ICsgSW5kZW50SW5jcmVtZW50KTsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigic2VsZWN0ICIgKyBfc2VsZWN0LnRvU3RyaW5nKCkpOwotICAgICAgICB9Ci0gICAgICAgIGRpc3BsYXlDb250ZW50cyhpbmRlbnQgKyBJbmRlbnRJbmNyZW1lbnQpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFBhcnNlIHRoZSBjb250ZW50cyBvZiB0aGUgPHhzbDpwYXJhbT4gZWxlbWVudC4gVGhpcyBtZXRob2QgbXVzdCByZWFkCi0gICAgICogdGhlICduYW1lJyAocmVxdWlyZWQpIGFuZCAnc2VsZWN0JyAob3B0aW9uYWwpIGF0dHJpYnV0ZXMuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcGFyc2VDb250ZW50cyhQYXJzZXIgcGFyc2VyKSB7Ci0KLSAgICAgICAgLy8gUGFyc2UgJ25hbWUnIGFuZCAnc2VsZWN0JyBhdHRyaWJ1dGVzIHBsdXMgcGFyYW1ldGVyIGNvbnRlbnRzCi0gICAgICAgIHN1cGVyLnBhcnNlQ29udGVudHMocGFyc2VyKTsKLQotICAgICAgICAvLyBBZGQgYSByZWYgdG8gdGhpcyBwYXJhbSB0byBpdHMgZW5jbG9zaW5nIGNvbnN0cnVjdAotICAgICAgICBmaW5hbCBTeW50YXhUcmVlTm9kZSBwYXJlbnQgPSBnZXRQYXJlbnQoKTsKLSAgICAgICAgaWYgKHBhcmVudCBpbnN0YW5jZW9mIFN0eWxlc2hlZXQpIHsKLSAgICAgICAgICAgIC8vIE1hcmsgdGhpcyBhcyBhIGdsb2JhbCBwYXJhbWV0ZXIKLSAgICAgICAgICAgIF9pc0xvY2FsID0gZmFsc2U7Ci0gICAgICAgICAgICAvLyBDaGVjayBpZiBhIGdsb2JhbCB2YXJpYWJsZSB3aXRoIHRoaXMgbmFtZSBhbHJlYWR5IGV4aXN0cy4uLgotICAgICAgICAgICAgUGFyYW0gcGFyYW0gPSBwYXJzZXIuZ2V0U3ltYm9sVGFibGUoKS5sb29rdXBQYXJhbShfbmFtZSk7Ci0gICAgICAgICAgICAvLyAuLi5hbmQgaWYgaXQgZG9lcyB3ZSBuZWVkIHRvIGNoZWNrIGltcG9ydCBwcmVjZWRlbmNlCi0gICAgICAgICAgICBpZiAocGFyYW0gIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZpbmFsIGludCB1cyA9IHRoaXMuZ2V0SW1wb3J0UHJlY2VkZW5jZSgpOwotICAgICAgICAgICAgICAgIGZpbmFsIGludCB0aGVtID0gcGFyYW0uZ2V0SW1wb3J0UHJlY2VkZW5jZSgpOwotICAgICAgICAgICAgICAgIC8vIEl0IGlzIGFuIGVycm9yIGlmIHRoZSB0d28gaGF2ZSB0aGUgc2FtZSBpbXBvcnQgcHJlY2VkZW5jZQotICAgICAgICAgICAgICAgIGlmICh1cyA9PSB0aGVtKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBuYW1lID0gX25hbWUudG9TdHJpbmcoKTsKLSAgICAgICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IodGhpcywgcGFyc2VyLCBFcnJvck1zZy5WQVJJQUJMRV9SRURFRl9FUlIsbmFtZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIC8vIElnbm9yZSB0aGlzIGlmIHByZXZpb3VzIGRlZmluaXRpb24gaGFzIGhpZ2hlciBwcmVjZWRlbmNlCi0gICAgICAgICAgICAgICAgZWxzZSBpZiAodGhlbSA+IHVzKSB7Ci0gICAgICAgICAgICAgICAgICAgIF9pZ25vcmUgPSB0cnVlOwotICAgICAgICAgICAgICAgICAgICBjb3B5UmVmZXJlbmNlcyhwYXJhbSk7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIHBhcmFtLmNvcHlSZWZlcmVuY2VzKHRoaXMpOwotICAgICAgICAgICAgICAgICAgICBwYXJhbS5kaXNhYmxlKCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gQWRkIHRoaXMgdmFyaWFibGUgaWYgd2UgaGF2ZSBoaWdoZXIgcHJlY2VkZW5jZQotICAgICAgICAgICAgKChTdHlsZXNoZWV0KXBhcmVudCkuYWRkUGFyYW0odGhpcyk7Ci0gICAgICAgICAgICBwYXJzZXIuZ2V0U3ltYm9sVGFibGUoKS5hZGRQYXJhbSh0aGlzKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChwYXJlbnQgaW5zdGFuY2VvZiBUZW1wbGF0ZSkgewotICAgICAgICAgICAgVGVtcGxhdGUgdGVtcGxhdGUgPSAoVGVtcGxhdGUpIHBhcmVudDsKLSAgICAgICAgICAgIF9pc0xvY2FsID0gdHJ1ZTsKLSAgICAgICAgICAgIHRlbXBsYXRlLmFkZFBhcmFtZXRlcih0aGlzKTsKLSAgICAgICAgICAgIGlmICh0ZW1wbGF0ZS5pc1NpbXBsZU5hbWVkVGVtcGxhdGUoKSkgewotICAgICAgICAgICAgICAgIF9pc0luU2ltcGxlTmFtZWRUZW1wbGF0ZSA9IHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUeXBlLWNoZWNrcyB0aGUgcGFyYW1ldGVyLiBUaGUgcGFyYW1ldGVyIHR5cGUgaXMgZGV0ZXJtaW5lZCBieSB0aGUKLSAgICAgKiAnc2VsZWN0JyBleHByZXNzaW9uIChpZiBwcmVzZW50KSBvciBpcyBhIHJlc3VsdCB0cmVlIGlmIHRoZSBwYXJhbWV0ZXIKLSAgICAgKiBlbGVtZW50IGhhcyBhIGJvZHkgYW5kIG5vICdzZWxlY3QnIGV4cHJlc3Npb24uCi0gICAgICovCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLSAgICAgICAgaWYgKF9zZWxlY3QgIT0gbnVsbCkgewotICAgICAgICAgICAgX3R5cGUgPSBfc2VsZWN0LnR5cGVDaGVjayhzdGFibGUpOwotICAgICAgICAgICAgaWYgKF90eXBlIGluc3RhbmNlb2YgUmVmZXJlbmNlVHlwZSA9PSBmYWxzZSAmJiAhKF90eXBlIGluc3RhbmNlb2YgT2JqZWN0VHlwZSkpIHsKLSAgICAgICAgICAgICAgICBfc2VsZWN0ID0gbmV3IENhc3RFeHByKF9zZWxlY3QsIFR5cGUuUmVmZXJlbmNlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChoYXNDb250ZW50cygpKSB7Ci0gICAgICAgICAgICB0eXBlQ2hlY2tDb250ZW50cyhzdGFibGUpOwotICAgICAgICB9Ci0gICAgICAgIF90eXBlID0gVHlwZS5SZWZlcmVuY2U7Ci0KLSAgICAgICAgLy8gVGhpcyBlbGVtZW50IGhhcyBubyB0eXBlICh0aGUgcGFyYW1ldGVyIGRvZXMsIGJ1dCB0aGUgcGFyYW1ldGVyCi0gICAgICAgIC8vIGVsZW1lbnQgaXRzZWxmIGRvZXMgbm90KS4KLSAgICAgICAgcmV0dXJuIFR5cGUuVm9pZDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLSAgICAgICAgZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0KLSAgICAgICAgaWYgKF9pZ25vcmUpIHJldHVybjsKLSAgICAgICAgX2lnbm9yZSA9IHRydWU7Ci0KLSAgICAgICAgLyoKLSAgICAgICAgICogVG8gZml4IGJ1ZyAyNDUxOCByZWxhdGVkIHRvIHNldHRpbmcgcGFyYW1ldGVycyBvZiB0aGUgZm9ybQotICAgICAgICAgKiB7bmFtZXNwYWNldXJpfWxvY2FsTmFtZSB3aGljaCB3aWxsIGdldCBtYXBwZWQgdG8gYW4gaW5zdGFuY2UKLSAgICAgICAgICogdmFyaWFibGUgaW4gdGhlIGNsYXNzLgotICAgICAgICAgKi8KLSAgICAgICAgZmluYWwgU3RyaW5nIG5hbWUgPSBCYXNpc0xpYnJhcnkubWFwUU5hbWVUb0phdmFOYW1lKF9uYW1lLnRvU3RyaW5nKCkpOwotICAgICAgICBmaW5hbCBTdHJpbmcgc2lnbmF0dXJlID0gX3R5cGUudG9TaWduYXR1cmUoKTsKLSAgICAgICAgZmluYWwgU3RyaW5nIGNsYXNzTmFtZSA9IF90eXBlLmdldENsYXNzTmFtZSgpOwotCi0gICAgICAgIGlmIChpc0xvY2FsKCkpIHsKLSAgICAgICAgICAgIC8qCi0gICAgICAgICAgICAgICogSWYgc2ltcGxlIG5hbWVkIHRlbXBsYXRlIHRoZW4gZ2VuZXJhdGUgYSBjb25kaXRpb25hbCBpbml0IG9mIHRoZQotICAgICAgICAgICAgICAqIHBhcmFtIHVzaW5nIGl0cyBkZWZhdWx0IHZhbHVlOgotICAgICAgICAgICAgICAqICAgICAgIGlmIChwYXJhbSA9PSBudWxsKSBwYXJhbSA9IDxkZWZhdWx0LXZhbHVlPgotICAgICAgICAgICAgICAqLwotICAgICAgICAgICAgaWYgKF9pc0luU2ltcGxlTmFtZWRUZW1wbGF0ZSkgewotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChsb2FkSW5zdHJ1Y3Rpb24oKSk7Ci0gICAgICAgICAgICAgICAgQnJhbmNoSGFuZGxlIGlmQmxvY2sgPSBpbC5hcHBlbmQobmV3IElGTk9OTlVMTChudWxsKSk7Ci0gICAgICAgICAgICAgICAgdHJhbnNsYXRlVmFsdWUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKHN0b3JlSW5zdHJ1Y3Rpb24oKSk7Ci0gICAgICAgICAgICAgICAgaWZCbG9jay5zZXRUYXJnZXQoaWwuYXBwZW5kKE5PUCkpOwotICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWwuYXBwZW5kKGNsYXNzR2VuLmxvYWRUcmFuc2xldCgpKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsIG5hbWUpKTsKLSAgICAgICAgICAgIHRyYW5zbGF0ZVZhbHVlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgdHJ1ZSkpOwotCi0gICAgICAgICAgICAvLyBDYWxsIGFkZFBhcmFtZXRlcigpIGZyb20gdGhpcyBjbGFzcwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VWSVJUVUFMKGNwZy5hZGRNZXRob2RyZWYoVFJBTlNMRVRfQ0xBU1MsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBRERfUEFSQU1FVEVSLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQUREX1BBUkFNRVRFUl9TSUcpKSk7Ci0gICAgICAgICAgICBpZiAoY2xhc3NOYW1lICE9IEVNUFRZU1RSSU5HKSB7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBDSEVDS0NBU1QoY3BnLmFkZENsYXNzKGNsYXNzTmFtZSkpKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgX3R5cGUudHJhbnNsYXRlVW5Cb3goY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0KLSAgICAgICAgICAgIGlmIChfcmVmcy5pc0VtcHR5KCkpIHsgLy8gbm9ib2R5IHVzZXMgdGhlIHZhbHVlCi0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKF90eXBlLlBPUCgpKTsKLSAgICAgICAgICAgICAgICBfbG9jYWwgPSBudWxsOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7ICAgICAgICAgICAgICAvLyBub3JtYWwgY2FzZQotICAgICAgICAgICAgICAgIF9sb2NhbCA9IG1ldGhvZEdlbi5hZGRMb2NhbFZhcmlhYmxlMihuYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdHlwZS50b0pDVHlwZSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbC5nZXRFbmQoKSk7Ci0gICAgICAgICAgICAgICAgLy8gQ2FjaGUgdGhlIHJlc3VsdCBvZiBhZGRQYXJhbWV0ZXIoKSBpbiBhIGxvY2FsIHZhcmlhYmxlCi0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKF90eXBlLlNUT1JFKF9sb2NhbC5nZXRJbmRleCgpKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBpZiAoY2xhc3NHZW4uY29udGFpbnNGaWVsZChuYW1lKSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgY2xhc3NHZW4uYWRkRmllbGQobmV3IEZpZWxkKEFDQ19QVUJMSUMsIGNwZy5hZGRVdGY4KG5hbWUpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjcGcuYWRkVXRmOChzaWduYXR1cmUpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLCBjcGcuZ2V0Q29uc3RhbnRQb29sKCkpKTsKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpOwotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChEVVApOwotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsIG5hbWUpKTsKLSAgICAgICAgICAgICAgICB0cmFuc2xhdGVWYWx1ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCB0cnVlKSk7Ci0KLSAgICAgICAgICAgICAgICAvLyBDYWxsIGFkZFBhcmFtZXRlcigpIGZyb20gdGhpcyBjbGFzcwotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChjcGcuYWRkTWV0aG9kcmVmKFRSQU5TTEVUX0NMQVNTLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBRERfUEFSQU1FVEVSLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBRERfUEFSQU1FVEVSX1NJRykpKTsKLQotICAgICAgICAgICAgICAgIF90eXBlLnRyYW5zbGF0ZVVuQm94KGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCi0gICAgICAgICAgICAgICAgLy8gQ2FjaGUgdGhlIHJlc3VsdCBvZiBhZGRQYXJhbWV0ZXIoKSBpbiBhIGZpZWxkCi0gICAgICAgICAgICAgICAgaWYgKGNsYXNzTmFtZSAhPSBFTVBUWVNUUklORykgewotICAgICAgICAgICAgICAgICAgICBpbC5hcHBlbmQobmV3IENIRUNLQ0FTVChjcGcuYWRkQ2xhc3MoY2xhc3NOYW1lKSkpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQobmV3IFBVVEZJRUxEKGNwZy5hZGRGaWVsZHJlZihjbGFzc0dlbi5nZXRDbGFzc05hbWUoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lLCBzaWduYXR1cmUpKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL1BhcmFtZXRlclJlZi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9QYXJhbWV0ZXJSZWYuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZWQwNTFmYS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL1BhcmFtZXRlclJlZi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTExICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFBhcmFtZXRlclJlZi5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzAyIDExOjA1OjA4IHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQ0hFQ0tDQVNUOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQ29uc3RhbnRQb29sR2VuOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuR0VURklFTEQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JTlZPS0VJTlRFUkZBQ0U7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JbnN0cnVjdGlvbkxpc3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuQ2xhc3NHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuTWV0aG9kR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLk5vZGVTZXRUeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5ydW50aW1lLkJhc2lzTGlicmFyeTsKLQotLyoqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqIEBhdXRob3IgRXJ3aW4gQm9sd2lkdCA8ZWpiQGtsb21wLm9yZz4KLSAqLwotZmluYWwgY2xhc3MgUGFyYW1ldGVyUmVmIGV4dGVuZHMgVmFyaWFibGVSZWZCYXNlIHsKLQotICAgIC8qKgotICAgICAqIE5hbWUgb2YgcGFyYW0gYmVpbmcgcmVmZXJlbmNlZC4KLSAgICAgKi8KLSAgICBRTmFtZSBfbmFtZSA9IG51bGw7Ci0KLSAgICBwdWJsaWMgUGFyYW1ldGVyUmVmKFBhcmFtIHBhcmFtKSB7Ci0gICAgICAgIHN1cGVyKHBhcmFtKTsKLSAgICAgICAgX25hbWUgPSBwYXJhbS5fbmFtZTsKLQotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0gICAgICAgIHJldHVybiAicGFyYW1ldGVyLXJlZigiK192YXJpYWJsZS5nZXROYW1lKCkrJy8nK192YXJpYWJsZS5nZXRUeXBlKCkrJyknOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotICAgICAgICBmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQotICAgICAgICAvKgotICAgICAgICAgKiBUbyBmaXggYnVnIDI0NTE4IHJlbGF0ZWQgdG8gc2V0dGluZyBwYXJhbWV0ZXJzIG9mIHRoZSBmb3JtCi0gICAgICAgICAqIHtuYW1lc3BhY2V1cml9bG9jYWxOYW1lLCB3aGljaCB3aWxsIGdldCBtYXBwZWQgdG8gYW4gaW5zdGFuY2UKLSAgICAgICAgICogdmFyaWFibGUgaW4gdGhlIGNsYXNzLgotICAgICAgICAgKi8KLSAgICAgICAgZmluYWwgU3RyaW5nIG5hbWUgPSBCYXNpc0xpYnJhcnkubWFwUU5hbWVUb0phdmFOYW1lIChfbmFtZS50b1N0cmluZygpKTsKLSAgICAgICAgZmluYWwgU3RyaW5nIHNpZ25hdHVyZSA9IF90eXBlLnRvU2lnbmF0dXJlKCk7Ci0KLSAgICAgICAgaWYgKF92YXJpYWJsZS5pc0xvY2FsKCkpIHsKLSAgICAgICAgICAgIGlmIChjbGFzc0dlbi5pc0V4dGVybmFsKCkpIHsKLSAgICAgICAgICAgICAgICBDbG9zdXJlIHZhcmlhYmxlQ2xvc3VyZSA9IF9jbG9zdXJlOwotICAgICAgICAgICAgICAgIHdoaWxlICh2YXJpYWJsZUNsb3N1cmUgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBpZiAodmFyaWFibGVDbG9zdXJlLmluSW5uZXJDbGFzcygpKSBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgdmFyaWFibGVDbG9zdXJlID0gdmFyaWFibGVDbG9zdXJlLmdldFBhcmVudENsb3N1cmUoKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBpZiAodmFyaWFibGVDbG9zdXJlICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgaWwuYXBwZW5kKEFMT0FEXzApOwotICAgICAgICAgICAgICAgICAgICBpbC5hcHBlbmQobmV3IEdFVEZJRUxEKAotICAgICAgICAgICAgICAgICAgICAgICAgY3BnLmFkZEZpZWxkcmVmKHZhcmlhYmxlQ2xvc3VyZS5nZXRJbm5lckNsYXNzTmFtZSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUsIHNpZ25hdHVyZSkpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIGlsLmFwcGVuZChfdmFyaWFibGUubG9hZEluc3RydWN0aW9uKCkpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChfdmFyaWFibGUubG9hZEluc3RydWN0aW9uKCkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgZmluYWwgU3RyaW5nIGNsYXNzTmFtZSA9IGNsYXNzR2VuLmdldENsYXNzTmFtZSgpOwotICAgICAgICAgICAgaWwuYXBwZW5kKGNsYXNzR2VuLmxvYWRUcmFuc2xldCgpKTsKLSAgICAgICAgICAgIGlmIChjbGFzc0dlbi5pc0V4dGVybmFsKCkpIHsKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQobmV3IENIRUNLQ0FTVChjcGcuYWRkQ2xhc3MoY2xhc3NOYW1lKSkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBHRVRGSUVMRChjcGcuYWRkRmllbGRyZWYoY2xhc3NOYW1lLG5hbWUsc2lnbmF0dXJlKSkpOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKF92YXJpYWJsZS5nZXRUeXBlKCkgaW5zdGFuY2VvZiBOb2RlU2V0VHlwZSkgewotICAgICAgICAgICAgLy8gVGhlIG1ldGhvZCBjbG9uZUl0ZXJhdG9yKCkgYWxzbyBkb2VzIHJlc2V0dGluZwotICAgICAgICAgICAgZmluYWwgaW50IGNsb25lID0gY3BnLmFkZEludGVyZmFjZU1ldGhvZHJlZihOT0RFX0lURVJBVE9SLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJjbG9uZUl0ZXJhdG9yIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKCkiICsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTk9ERV9JVEVSQVRPUl9TSUcpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0UoY2xvbmUsIDEpKTsKLSAgICAgICAgfQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvUGFyZW50TG9jYXRpb25QYXRoLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL1BhcmVudExvY2F0aW9uUGF0aC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA5ZWNkNzRhLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvUGFyZW50TG9jYXRpb25QYXRoLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyNTIgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogUGFyZW50TG9jYXRpb25QYXRoLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTIgMTA6NTY6MzAgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5BTE9BRDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkFTVE9SRTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkNvbnN0YW50UG9vbEdlbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklOVk9LRUlOVEVSRkFDRTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklOVk9LRVNQRUNJQUw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JTlZPS0VWSVJUVUFMOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW5zdHJ1Y3Rpb25MaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuTG9jYWxWYXJpYWJsZUdlbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLk5FVzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5DbGFzc0dlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5NZXRob2RHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlQ2hlY2tFcnJvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5VdGlsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkF4aXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNOwotCi0vKioKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqLwotZmluYWwgY2xhc3MgUGFyZW50TG9jYXRpb25QYXRoIGV4dGVuZHMgUmVsYXRpdmVMb2NhdGlvblBhdGggewotICAgIHByaXZhdGUgRXhwcmVzc2lvbiBfc3RlcDsKLSAgICBwcml2YXRlIGZpbmFsIFJlbGF0aXZlTG9jYXRpb25QYXRoIF9wYXRoOwotICAgIHByaXZhdGUgVHlwZSBzdHlwZTsKLSAgICBwcml2YXRlIGJvb2xlYW4gX29yZGVyTm9kZXMgPSBmYWxzZTsKLSAgICBwcml2YXRlIGJvb2xlYW4gX2F4aXNNaXNtYXRjaCA9IGZhbHNlOwotCi0gICAgcHVibGljIFBhcmVudExvY2F0aW9uUGF0aChSZWxhdGl2ZUxvY2F0aW9uUGF0aCBwYXRoLCBFeHByZXNzaW9uIHN0ZXApIHsKLSAgICAgICAgX3BhdGggPSBwYXRoOwotICAgICAgICBfc3RlcCA9IHN0ZXA7Ci0gICAgICAgIF9wYXRoLnNldFBhcmVudCh0aGlzKTsKLSAgICAgICAgX3N0ZXAuc2V0UGFyZW50KHRoaXMpOwotCi0gICAgICAgIGlmIChfc3RlcCBpbnN0YW5jZW9mIFN0ZXApIHsKLSAgICAgICAgICAgIF9heGlzTWlzbWF0Y2ggPSBjaGVja0F4aXNNaXNtYXRjaCgpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0QXhpcyhpbnQgYXhpcykgewotICAgICAgICBfcGF0aC5zZXRBeGlzKGF4aXMpOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgZ2V0QXhpcygpIHsKLSAgICAgICAgcmV0dXJuIF9wYXRoLmdldEF4aXMoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgUmVsYXRpdmVMb2NhdGlvblBhdGggZ2V0UGF0aCgpIHsKLSAgICAgICAgcmV0dXJuKF9wYXRoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgRXhwcmVzc2lvbiBnZXRTdGVwKCkgewotICAgICAgICByZXR1cm4oX3N0ZXApOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldFBhcnNlcihQYXJzZXIgcGFyc2VyKSB7Ci0gICAgICAgIHN1cGVyLnNldFBhcnNlcihwYXJzZXIpOwotICAgICAgICBfc3RlcC5zZXRQYXJzZXIocGFyc2VyKTsKLSAgICAgICAgX3BhdGguc2V0UGFyc2VyKHBhcnNlcik7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKLSAgICAgICAgcmV0dXJuICJQYXJlbnRMb2NhdGlvblBhdGgoIiArIF9wYXRoICsgIiwgIiArIF9zdGVwICsgJyknOwotICAgIH0KLQotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0gICAgICAgIHN0eXBlID0gX3N0ZXAudHlwZUNoZWNrKHN0YWJsZSk7Ci0gICAgICAgIF9wYXRoLnR5cGVDaGVjayhzdGFibGUpOwotCi0gICAgICAgIGlmIChfYXhpc01pc21hdGNoKSBlbmFibGVOb2RlT3JkZXJpbmcoKTsKLQotICAgICAgICByZXR1cm4gX3R5cGUgPSBUeXBlLk5vZGVTZXQ7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgZW5hYmxlTm9kZU9yZGVyaW5nKCkgewotICAgICAgICBTeW50YXhUcmVlTm9kZSBwYXJlbnQgPSBnZXRQYXJlbnQoKTsKLSAgICAgICAgaWYgKHBhcmVudCBpbnN0YW5jZW9mIFBhcmVudExvY2F0aW9uUGF0aCkKLSAgICAgICAgICAgICgoUGFyZW50TG9jYXRpb25QYXRoKXBhcmVudCkuZW5hYmxlTm9kZU9yZGVyaW5nKCk7Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgX29yZGVyTm9kZXMgPSB0cnVlOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgaXMgdXNlZCB0byBkZXRlcm1pbmUgaWYgdGhpcyBwYXJlbnQgbG9jYXRpb24gcGF0aCBpcyBhCi0gICAgICogY29tYmluYXRpb24gb2YgdHdvIHN0ZXAncyB3aXRoIGF4ZXMgdGhhdCB3aWxsIGNyZWF0ZSBkdXBsaWNhdGUgb3IKLSAgICAgKiB1bm9yZGVyZWQgbm9kZXMuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gY2hlY2tBeGlzTWlzbWF0Y2goKSB7Ci0KLSAgICAgICAgaW50IGxlZnQgPSBfcGF0aC5nZXRBeGlzKCk7Ci0gICAgICAgIGludCByaWdodCA9ICgoU3RlcClfc3RlcCkuZ2V0QXhpcygpOwotCi0gICAgICAgIGlmICgoKGxlZnQgPT0gQXhpcy5BTkNFU1RPUikgfHwgKGxlZnQgPT0gQXhpcy5BTkNFU1RPUk9SU0VMRikpICYmCi0gICAgICAgICAgICAoKHJpZ2h0ID09IEF4aXMuQ0hJTEQpIHx8Ci0gICAgICAgICAgICAgKHJpZ2h0ID09IEF4aXMuREVTQ0VOREFOVCkgfHwKLSAgICAgICAgICAgICAocmlnaHQgPT0gQXhpcy5ERVNDRU5EQU5UT1JTRUxGKSB8fAotICAgICAgICAgICAgIChyaWdodCA9PSBBeGlzLlBBUkVOVCkgfHwKLSAgICAgICAgICAgICAocmlnaHQgPT0gQXhpcy5QUkVDRURJTkcpIHx8Ci0gICAgICAgICAgICAgKHJpZ2h0ID09IEF4aXMuUFJFQ0VESU5HU0lCTElORykpKQotICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0KLSAgICAgICAgaWYgKChsZWZ0ID09IEF4aXMuQ0hJTEQpICYmCi0gICAgICAgICAgICAocmlnaHQgPT0gQXhpcy5BTkNFU1RPUikgfHwKLSAgICAgICAgICAgIChyaWdodCA9PSBBeGlzLkFOQ0VTVE9ST1JTRUxGKSB8fAotICAgICAgICAgICAgKHJpZ2h0ID09IEF4aXMuUEFSRU5UKSB8fAotICAgICAgICAgICAgKHJpZ2h0ID09IEF4aXMuUFJFQ0VESU5HKSkKLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotCi0gICAgICAgIGlmICgobGVmdCA9PSBBeGlzLkRFU0NFTkRBTlQpIHx8IChsZWZ0ID09IEF4aXMuREVTQ0VOREFOVE9SU0VMRikpCi0gICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLQotICAgICAgICBpZiAoKChsZWZ0ID09IEF4aXMuRk9MTE9XSU5HKSB8fCAobGVmdCA9PSBBeGlzLkZPTExPV0lOR1NJQkxJTkcpKSAmJgotICAgICAgICAgICAgKChyaWdodCA9PSBBeGlzLkZPTExPV0lORykgfHwKLSAgICAgICAgICAgICAocmlnaHQgPT0gQXhpcy5QQVJFTlQpIHx8Ci0gICAgICAgICAgICAgKHJpZ2h0ID09IEF4aXMuUFJFQ0VESU5HKSB8fAotICAgICAgICAgICAgIChyaWdodCA9PSBBeGlzLlBSRUNFRElOR1NJQkxJTkcpKSkKLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotCi0gICAgICAgIGlmICgoKGxlZnQgPT0gQXhpcy5QUkVDRURJTkcpIHx8IChsZWZ0ID09IEF4aXMuUFJFQ0VESU5HU0lCTElORykpICYmCi0gICAgICAgICAgICAoKHJpZ2h0ID09IEF4aXMuREVTQ0VOREFOVCkgfHwKLSAgICAgICAgICAgICAocmlnaHQgPT0gQXhpcy5ERVNDRU5EQU5UT1JTRUxGKSB8fAotICAgICAgICAgICAgIChyaWdodCA9PSBBeGlzLkZPTExPV0lORykgfHwKLSAgICAgICAgICAgICAocmlnaHQgPT0gQXhpcy5GT0xMT1dJTkdTSUJMSU5HKSB8fAotICAgICAgICAgICAgIChyaWdodCA9PSBBeGlzLlBBUkVOVCkgfHwKLSAgICAgICAgICAgICAocmlnaHQgPT0gQXhpcy5QUkVDRURJTkcpIHx8Ci0gICAgICAgICAgICAgKHJpZ2h0ID09IEF4aXMuUFJFQ0VESU5HU0lCTElORykpKQotICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0KLSAgICAgICAgaWYgKChyaWdodCA9PSBBeGlzLkZPTExPV0lORykgJiYgKGxlZnQgPT0gQXhpcy5DSElMRCkpIHsKLSAgICAgICAgICAgIC8vIFNwZWNpYWwgY2FzZSBmb3IgJ0AqL2ZvbGxvd2luZzo6KicgZXhwcmVzc2lvbnMuIFRoZSByZXN1bHRpbmcKLSAgICAgICAgICAgIC8vIGl0ZXJhdG9yIGlzIGluaXRpYWxpc2VkIHdpdGggdGhlIHBhcmVudCdzIGZpcnN0IGNoaWxkLCBhbmQgdGhpcwotICAgICAgICAgICAgLy8gY2FuIGNhdXNlIGR1cGxpY2F0ZXMgaW4gdGhlIG91dHB1dCBpZiB0aGUgcGFyZW50IGhhcyBtb3JlIHRoYW4KLSAgICAgICAgICAgIC8vIG9uZSBhdHRyaWJ1dGUgdGhhdCBtYXRjaGVzIHRoZSBsZWZ0IHN0ZXAuCi0gICAgICAgICAgICBpZiAoX3BhdGggaW5zdGFuY2VvZiBTdGVwKSB7Ci0gICAgICAgICAgICAgICAgaW50IHR5cGUgPSAoKFN0ZXApX3BhdGgpLmdldE5vZGVUeXBlKCk7Ci0gICAgICAgICAgICAgICAgaWYgKHR5cGUgPT0gRFRNLkFUVFJJQlVURV9OT0RFKSByZXR1cm4gdHJ1ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLQotICAgICAgICAvLyBDb21waWxlIHBhdGggaXRlcmF0b3IKLSAgICAgICAgX3BhdGgudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOyAvLyBpdGVyYXRvciBvbiBzdGFjay4uLi4KLQotICAgICAgICB0cmFuc2xhdGVTdGVwKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZVN0ZXAoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLSAgICAgICAgZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0KLSAgICAgICAgLy8gQmFja3dhcmRzIGJyYW5jaGVzIGFyZSBwcm9oaWJpdGVkIGlmIGFuIHVuaW5pdGlhbGl6ZWQgb2JqZWN0IGlzCi0gICAgICAgIC8vIG9uIHRoZSBzdGFjayBieSBzZWN0aW9uIDQuOS40IG9mIHRoZSBKVk0gU3BlY2lmaWNhdGlvbiwgMm5kIEVkLgotICAgICAgICAvLyBXZSBkb24ndCBrbm93IHdoZXRoZXIgdGhpcyBjb2RlIG1pZ2h0IGNvbnRhaW4gYmFja3dhcmRzIGJyYW5jaGVzCi0gICAgICAgIC8vIHNvIHdlIG11c3RuJ3QgY3JlYXRlIHRoZSBuZXcgb2JqZWN0IHVudGlsIGFmdGVyIHdlJ3ZlIGNyZWF0ZWQKLSAgICAgICAgLy8gdGhlIHN1c3BlY3QgYXJndW1lbnRzIHRvIGl0cyBjb25zdHJ1Y3Rvci4gIEluc3RlYWQgd2UgY2FsY3VsYXRlCi0gICAgICAgIC8vIHRoZSB2YWx1ZXMgb2YgdGhlIGFyZ3VtZW50cyB0byB0aGUgY29uc3RydWN0b3IgZmlyc3QsIHN0b3JlIHRoZW0KLSAgICAgICAgLy8gaW4gdGVtcG9yYXJ5IHZhcmlhYmxlcywgY3JlYXRlIHRoZSBvYmplY3QgYW5kIHJlbG9hZCB0aGUKLSAgICAgICAgLy8gYXJndW1lbnRzIGZyb20gdGhlIHRlbXBvcmFyaWVzIHRvIGF2b2lkIHRoZSBwcm9ibGVtLgotCi0gICAgICAgIExvY2FsVmFyaWFibGVHZW4gcGF0aFRlbXAKLSAgICAgICAgICAgICAgICA9IG1ldGhvZEdlbi5hZGRMb2NhbFZhcmlhYmxlKCJwYXJlbnRfbG9jYXRpb25fcGF0aF90bXAxIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVXRpbC5nZXRKQ1JlZlR5cGUoTk9ERV9JVEVSQVRPUl9TSUcpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLCBudWxsKTsKLSAgICAgICAgcGF0aFRlbXAuc2V0U3RhcnQoaWwuYXBwZW5kKG5ldyBBU1RPUkUocGF0aFRlbXAuZ2V0SW5kZXgoKSkpKTsKLQotICAgICAgICBfc3RlcC50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgIExvY2FsVmFyaWFibGVHZW4gc3RlcFRlbXAKLSAgICAgICAgICAgICAgICA9IG1ldGhvZEdlbi5hZGRMb2NhbFZhcmlhYmxlKCJwYXJlbnRfbG9jYXRpb25fcGF0aF90bXAyIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVXRpbC5nZXRKQ1JlZlR5cGUoTk9ERV9JVEVSQVRPUl9TSUcpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLCBudWxsKTsKLSAgICAgICAgc3RlcFRlbXAuc2V0U3RhcnQoaWwuYXBwZW5kKG5ldyBBU1RPUkUoc3RlcFRlbXAuZ2V0SW5kZXgoKSkpKTsKLQotICAgICAgICAvLyBDcmVhdGUgbmV3IFN0ZXBJdGVyYXRvcgotICAgICAgICBmaW5hbCBpbnQgaW5pdFNJID0gY3BnLmFkZE1ldGhvZHJlZihTVEVQX0lURVJBVE9SX0NMQVNTLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiPGluaXQ+IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIigiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICtOT0RFX0lURVJBVE9SX1NJRwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArTk9ERV9JVEVSQVRPUl9TSUcKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyIpViIpOwotICAgICAgICBpbC5hcHBlbmQobmV3IE5FVyhjcGcuYWRkQ2xhc3MoU1RFUF9JVEVSQVRPUl9DTEFTUykpKTsKLSAgICAgICAgaWwuYXBwZW5kKERVUCk7Ci0KLSAgICAgICAgcGF0aFRlbXAuc2V0RW5kKGlsLmFwcGVuZChuZXcgQUxPQUQocGF0aFRlbXAuZ2V0SW5kZXgoKSkpKTsKLSAgICAgICAgc3RlcFRlbXAuc2V0RW5kKGlsLmFwcGVuZChuZXcgQUxPQUQoc3RlcFRlbXAuZ2V0SW5kZXgoKSkpKTsKLQotICAgICAgICAvLyBJbml0aWFsaXplIFN0ZXBJdGVyYXRvciB3aXRoIGl0ZXJhdG9ycyBmcm9tIHRoZSBzdGFjawotICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRVNQRUNJQUwoaW5pdFNJKSk7Ci0KLSAgICAgICAgLy8gVGhpcyBpcyBhIHNwZWNpYWwgY2FzZSBmb3IgdGhlIC8vKiBwYXRoIHdpdGggb3Igd2l0aG91dCBwcmVkaWNhdGVzCi0gICAgICAgIEV4cHJlc3Npb24gc3RwID0gX3N0ZXA7Ci0gICAgICAgIGlmIChzdHAgaW5zdGFuY2VvZiBQYXJlbnRMb2NhdGlvblBhdGgpCi0gICAgICAgICAgICBzdHAgPSAoKFBhcmVudExvY2F0aW9uUGF0aClzdHApLmdldFN0ZXAoKTsKLQotICAgICAgICBpZiAoKF9wYXRoIGluc3RhbmNlb2YgU3RlcCkgJiYgKHN0cCBpbnN0YW5jZW9mIFN0ZXApKSB7Ci0gICAgICAgICAgICBmaW5hbCBpbnQgcGF0aCA9ICgoU3RlcClfcGF0aCkuZ2V0QXhpcygpOwotICAgICAgICAgICAgZmluYWwgaW50IHN0ZXAgPSAoKFN0ZXApc3RwKS5nZXRBeGlzKCk7Ci0gICAgICAgICAgICBpZiAoKHBhdGggPT0gQXhpcy5ERVNDRU5EQU5UT1JTRUxGICYmIHN0ZXAgPT0gQXhpcy5DSElMRCkgfHwKLSAgICAgICAgICAgICAgICAocGF0aCA9PSBBeGlzLlBSRUNFRElORyAgICAgICAgJiYgc3RlcCA9PSBBeGlzLlBBUkVOVCkpIHsKLSAgICAgICAgICAgICAgICBmaW5hbCBpbnQgaW5jbCA9IGNwZy5hZGRNZXRob2RyZWYoTk9ERV9JVEVSQVRPUl9CQVNFLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiaW5jbHVkZVNlbGYiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKCkiICsgTk9ERV9JVEVSQVRPUl9TSUcpOwotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChpbmNsKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvKgotICAgICAgICAgKiBJZiB0aGlzIHBhdHRlcm4gY29udGFpbnMgYSBzZXF1ZW5jZSBvZiBkZXNjZW5kYW50IGl0ZXJhdG9ycyB3ZQotICAgICAgICAgKiBydW4gdGhlIHJpc2sgb2YgcmV0dXJuaW5nIHRoZSBzYW1lIG5vZGUgc2V2ZXJhbCB0aW1lcy4gV2UgcHV0Ci0gICAgICAgICAqIGEgbmV3IGl0ZXJhdG9yIG9uIHRvcCBvZiB0aGUgZXhpc3Rpbmcgb25lIHRvIGFzc3VyZSBub2RlIG9yZGVyCi0gICAgICAgICAqIGFuZCBwcmV2ZW50IHJldHVybmluZyBhIHNpbmdsZSBub2RlIG11bHRpcGxlIHRpbWVzLgotICAgICAgICAgKi8KLSAgICAgICAgaWYgKF9vcmRlck5vZGVzKSB7Ci0gICAgICAgICAgICBmaW5hbCBpbnQgb3JkZXIgPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKERPTV9JTlRGLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPUkRFUl9JVEVSQVRPUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT1JERVJfSVRFUkFUT1JfU0lHKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChTV0FQKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZENvbnRleHROb2RlKCkpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0Uob3JkZXIsIDMpKTsKLSAgICAgICAgfQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvUGFyZW50UGF0dGVybi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9QYXJlbnRQYXR0ZXJuLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDI2YjAxYTIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9QYXJlbnRQYXR0ZXJuLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNTMgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogUGFyZW50UGF0dGVybi5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzAyIDExOjEwOjA5IHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQ29uc3RhbnRQb29sR2VuOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSUxPQUQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JTlZPS0VJTlRFUkZBQ0U7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JU1RPUkU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JbnN0cnVjdGlvbkhhbmRsZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uTGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkxvY2FsVmFyaWFibGVHZW47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuQ2xhc3NHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuTWV0aG9kR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZUNoZWNrRXJyb3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVXRpbDsKLQotLyoqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKi8KLWZpbmFsIGNsYXNzIFBhcmVudFBhdHRlcm4gZXh0ZW5kcyBSZWxhdGl2ZVBhdGhQYXR0ZXJuIHsKLSAgICBwcml2YXRlIGZpbmFsIFBhdHRlcm4gX2xlZnQ7Ci0gICAgcHJpdmF0ZSBmaW5hbCBSZWxhdGl2ZVBhdGhQYXR0ZXJuIF9yaWdodDsKLQotICAgIHB1YmxpYyBQYXJlbnRQYXR0ZXJuKFBhdHRlcm4gbGVmdCwgUmVsYXRpdmVQYXRoUGF0dGVybiByaWdodCkgewotICAgICAgICAoX2xlZnQgPSBsZWZ0KS5zZXRQYXJlbnQodGhpcyk7Ci0gICAgICAgIChfcmlnaHQgPSByaWdodCkuc2V0UGFyZW50KHRoaXMpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldFBhcnNlcihQYXJzZXIgcGFyc2VyKSB7Ci0gICAgICAgIHN1cGVyLnNldFBhcnNlcihwYXJzZXIpOwotICAgICAgICBfbGVmdC5zZXRQYXJzZXIocGFyc2VyKTsKLSAgICAgICAgX3JpZ2h0LnNldFBhcnNlcihwYXJzZXIpOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGlzV2lsZGNhcmQoKSB7Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RlcFBhdHRlcm4gZ2V0S2VybmVsUGF0dGVybigpIHsKLSAgICAgICAgcmV0dXJuIF9yaWdodC5nZXRLZXJuZWxQYXR0ZXJuKCk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgcmVkdWNlS2VybmVsUGF0dGVybigpIHsKLSAgICAgICAgX3JpZ2h0LnJlZHVjZUtlcm5lbFBhdHRlcm4oKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgVHlwZSB0eXBlQ2hlY2soU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgewotICAgICAgICBfbGVmdC50eXBlQ2hlY2soc3RhYmxlKTsKLSAgICAgICAgcmV0dXJuIF9yaWdodC50eXBlQ2hlY2soc3RhYmxlKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLSAgICAgICAgZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0gICAgICAgIGZpbmFsIExvY2FsVmFyaWFibGVHZW4gbG9jYWwgPQotICAgICAgICAgICAgbWV0aG9kR2VuLmFkZExvY2FsVmFyaWFibGUyKCJwcHQiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFV0aWwuZ2V0SkNSZWZUeXBlKE5PREVfU0lHKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsKTsKLQotICAgICAgICBmaW5hbCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uIGxvYWRMb2NhbCA9Ci0gICAgICAgICAgICBuZXcgSUxPQUQobG9jYWwuZ2V0SW5kZXgoKSk7Ci0gICAgICAgIGZpbmFsIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW5zdHJ1Y3Rpb24gc3RvcmVMb2NhbCA9Ci0gICAgICAgICAgICBuZXcgSVNUT1JFKGxvY2FsLmdldEluZGV4KCkpOwotCi0gICAgICAgIGlmIChfcmlnaHQuaXNXaWxkY2FyZCgpKSB7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQoU1dBUCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoX3JpZ2h0IGluc3RhbmNlb2YgU3RlcFBhdHRlcm4pIHsKLSAgICAgICAgICAgIGlsLmFwcGVuZChEVVApOwotICAgICAgICAgICAgbG9jYWwuc2V0U3RhcnQoaWwuYXBwZW5kKHN0b3JlTG9jYWwpKTsKLQotICAgICAgICAgICAgX3JpZ2h0LnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQotICAgICAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkRE9NKCkpOwotICAgICAgICAgICAgbG9jYWwuc2V0RW5kKGlsLmFwcGVuZChsb2FkTG9jYWwpKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIF9yaWdodC50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0KLSAgICAgICAgICAgIGlmIChfcmlnaHQgaW5zdGFuY2VvZiBBbmNlc3RvclBhdHRlcm4pIHsKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKFNXQVApOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgZmluYWwgaW50IGdldFBhcmVudCA9IGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoRE9NX0lOVEYsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdFVF9QQVJFTlQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdFVF9QQVJFTlRfU0lHKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0UoZ2V0UGFyZW50LCAyKSk7Ci0KLSAgICAgICAgZmluYWwgU3ludGF4VHJlZU5vZGUgcCA9IGdldFBhcmVudCgpOwotICAgICAgICBpZiAocCA9PSBudWxsIHx8IHAgaW5zdGFuY2VvZiBJbnN0cnVjdGlvbiB8fAotICAgICAgICAgICAgcCBpbnN0YW5jZW9mIFRvcExldmVsRWxlbWVudCkKLSAgICAgICAgewotICAgICAgICAgICAgX2xlZnQudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgaWwuYXBwZW5kKERVUCk7Ci0gICAgICAgICAgICBJbnN0cnVjdGlvbkhhbmRsZSBzdG9yZUluc3QgPSBpbC5hcHBlbmQoc3RvcmVMb2NhbCk7Ci0KLSAgICAgICAgICAgIGlmIChsb2NhbC5nZXRTdGFydCgpID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBsb2NhbC5zZXRTdGFydChzdG9yZUluc3QpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBfbGVmdC50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0KLSAgICAgICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLSAgICAgICAgICAgIGxvY2FsLnNldEVuZChpbC5hcHBlbmQobG9hZExvY2FsKSk7Ci0gICAgICAgIH0KLQotICAgICAgICBtZXRob2RHZW4ucmVtb3ZlTG9jYWxWYXJpYWJsZShsb2NhbCk7Ci0KLSAgICAgICAgLyoKLSAgICAgICAgICogSWYgX3JpZ2h0IGlzIGFuIGFuY2VzdG9yIHBhdHRlcm4sIGJhY2twYXRjaCBfbGVmdCBmYWxzZQotICAgICAgICAgKiBsaXN0IHRvIHRoZSBsb29wIHRoYXQgc2VhcmNoZXMgZm9yIG1vcmUgYW5jZXN0b3JzLgotICAgICAgICAgKi8KLSAgICAgICAgaWYgKF9yaWdodCBpbnN0YW5jZW9mIEFuY2VzdG9yUGF0dGVybikgewotICAgICAgICAgICAgZmluYWwgQW5jZXN0b3JQYXR0ZXJuIGFuY2VzdG9yID0gKEFuY2VzdG9yUGF0dGVybikgX3JpZ2h0OwotICAgICAgICAgICAgX2xlZnQuYmFja1BhdGNoRmFsc2VMaXN0KGFuY2VzdG9yLmdldExvb3BIYW5kbGUoKSk7ICAgIC8vIGNsZWFycyBsaXN0Ci0gICAgICAgIH0KLQotICAgICAgICBfdHJ1ZUxpc3QuYXBwZW5kKF9yaWdodC5fdHJ1ZUxpc3QuYXBwZW5kKF9sZWZ0Ll90cnVlTGlzdCkpOwotICAgICAgICBfZmFsc2VMaXN0LmFwcGVuZChfcmlnaHQuX2ZhbHNlTGlzdC5hcHBlbmQoX2xlZnQuX2ZhbHNlTGlzdCkpOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0gICAgICAgIHJldHVybiAiUGFyZW50KCIgKyBfbGVmdCArICIsICIgKyBfcmlnaHQgKyAnKSc7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9QYXJzZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvUGFyc2VyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDcwODg4NTAuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9QYXJzZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE0NDkgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAxNSwgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqLwotLyoKLSAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQotICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCi0gKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCi0gKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAotICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKLSAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwuWGFsYW5Db25zdGFudHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnV0aWxzLkZhY3RvcnlJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC51dGlscy5PYmplY3RGYWN0b3J5OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC51dGlscy5TZWN1cml0eVN1cHBvcnQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnV0aWxzLlhNTFNlY3VyaXR5TWFuYWdlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5FcnJvck1zZzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5NZXRob2RUeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZUNoZWNrRXJyb3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyLnV0aWxzLlN5c3RlbUlEUmVzb2x2ZXI7Ci1pbXBvcnQgamF2YS5pby5GaWxlOwotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci1pbXBvcnQgamF2YS5pby5TdHJpbmdSZWFkZXI7Ci1pbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKLWltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7Ci1pbXBvcnQgamF2YS51dGlsLkxpc3Q7Ci1pbXBvcnQgamF2YS51dGlsLk1hcDsKLWltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKLWltcG9ydCBqYXZhLnV0aWwuU3RhY2s7Ci1pbXBvcnQgamF2YS51dGlsLlN0cmluZ1Rva2VuaXplcjsKLWltcG9ydCBqYXZheC54bWwuWE1MQ29uc3RhbnRzOwotaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLlBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyOwotaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLlNBWFBhcnNlckZhY3Rvcnk7Ci1pbXBvcnQgb3JnLnhtbC5zYXguQXR0cmlidXRlczsKLWltcG9ydCBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKLWltcG9ydCBvcmcueG1sLnNheC5Mb2NhdG9yOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWFBhcnNlRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LlhNTFJlYWRlcjsKLWltcG9ydCBvcmcueG1sLnNheC5oZWxwZXJzLkF0dHJpYnV0ZXNJbXBsOwotCi0vKioKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqIEBhdXRob3IgRy4gVG9kZCBNaWxsZXIKLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICogQGF1dGhvciBFcndpbiBCb2x3aWR0IDxlamJAa2xvbXAub3JnPgotICovCi1wdWJsaWMgY2xhc3MgUGFyc2VyIGltcGxlbWVudHMgQ29uc3RhbnRzLCBDb250ZW50SGFuZGxlciB7Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgWFNMID0gInhzbCI7ICAgICAgICAgICAvLyBzdGFuZGFyZCBwcmVmaXgKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgVFJBTlNMRVQgPSAidHJhbnNsZXQiOyAvLyBleHRlbnNpb24gcHJlZml4Ci0KLSAgICBwcml2YXRlIExvY2F0b3IgX2xvY2F0b3IgPSBudWxsOwotCi0gICAgcHJpdmF0ZSBYU0xUQyBfeHNsdGM7ICAgICAgICAgICAgICAgICAgLy8gUmVmZXJlbmNlIHRvIHRoZSBjb21waWxlciBvYmplY3QuCi0gICAgcHJpdmF0ZSBYUGF0aFBhcnNlciBfeHBhdGhQYXJzZXI7ICAgICAgLy8gUmVmZXJlbmNlIHRvIHRoZSBYUGF0aCBwYXJzZXIuCi0gICAgcHJpdmF0ZSBBcnJheUxpc3Q8RXJyb3JNc2c+IF9lcnJvcnM7ICAgLy8gQ29udGFpbnMgYWxsIGNvbXBpbGF0aW9uIGVycm9ycwotICAgIHByaXZhdGUgQXJyYXlMaXN0PEVycm9yTXNnPiBfd2FybmluZ3M7IC8vIENvbnRhaW5zIGFsbCBjb21waWxhdGlvbiB3YXJuaW5ncwotCi0gICAgcHJpdmF0ZSBNYXA8U3RyaW5nLCBTdHJpbmc+ICAgX2luc3RydWN0aW9uQ2xhc3NlczsgLy8gTWFwcyBpbnN0cnVjdGlvbnMgdG8gY2xhc3NlcwotICAgIHByaXZhdGUgTWFwPFN0cmluZywgU3RyaW5nW10+IF9pbnN0cnVjdGlvbkF0dHJzOyAgLy8gcmVxZCBhbmQgb3B0IGF0dHJzCi0gICAgcHJpdmF0ZSBNYXA8U3RyaW5nLCBRTmFtZT4gICAgX3FOYW1lczsKLSAgICBwcml2YXRlIE1hcDxTdHJpbmcsIE1hcDxTdHJpbmcsIFFOYW1lPj4gX25hbWVzcGFjZXM7Ci0gICAgcHJpdmF0ZSBRTmFtZSAgICAgICBfdXNlQXR0cmlidXRlU2V0czsKLSAgICBwcml2YXRlIFFOYW1lICAgICAgIF9leGNsdWRlUmVzdWx0UHJlZml4ZXM7Ci0gICAgcHJpdmF0ZSBRTmFtZSAgICAgICBfZXh0ZW5zaW9uRWxlbWVudFByZWZpeGVzOwotICAgIHByaXZhdGUgTWFwPFN0cmluZywgT2JqZWN0PiAgIF92YXJpYWJsZVNjb3BlOwotICAgIHByaXZhdGUgU3R5bGVzaGVldCAgX2N1cnJlbnRTdHlsZXNoZWV0OwotICAgIHByaXZhdGUgU3ltYm9sVGFibGUgX3N5bWJvbFRhYmxlOyAvLyBNYXBzIFFOYW1lcyB0byBzeW50YXgtdHJlZSBub2RlcwotICAgIHByaXZhdGUgT3V0cHV0ICAgICAgX291dHB1dDsKLSAgICBwcml2YXRlIFRlbXBsYXRlICAgIF90ZW1wbGF0ZTsgICAgLy8gUmVmZXJlbmNlIHRvIHRoZSB0ZW1wbGF0ZSBiZWluZyBwYXJzZWQuCi0KLSAgICBwcml2YXRlIGJvb2xlYW4gICAgIF9yb290TmFtZXNwYWNlRGVmOyAvLyBVc2VkIGZvciB2YWxpZGl0eSBjaGVjawotCi0gICAgcHJpdmF0ZSBTeW50YXhUcmVlTm9kZSBfcm9vdDsKLQotICAgIHByaXZhdGUgU3RyaW5nIF90YXJnZXQ7Ci0KLSAgICBwcml2YXRlIGludCBfY3VycmVudEltcG9ydFByZWNlZGVuY2U7Ci0KLSAgICBwcml2YXRlIGJvb2xlYW4gX3VzZVNlcnZpY2VzTWVjaGFuaXNtID0gdHJ1ZTsKLQotICAgIHB1YmxpYyBQYXJzZXIoWFNMVEMgeHNsdGMsIGJvb2xlYW4gdXNlU2VydmljZXNNZWNoYW5pc20pIHsKLSAgICAgICAgX3hzbHRjID0geHNsdGM7Ci0gICAgICAgIF91c2VTZXJ2aWNlc01lY2hhbmlzbSA9IHVzZVNlcnZpY2VzTWVjaGFuaXNtOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGluaXQoKSB7Ci0gICAgICAgIF9xTmFtZXMgICAgICAgICAgICAgID0gbmV3IEhhc2hNYXA8Pig1MTIpOwotICAgICAgICBfbmFtZXNwYWNlcyAgICAgICAgICA9IG5ldyBIYXNoTWFwPD4oKTsKLSAgICAgICAgX2luc3RydWN0aW9uQ2xhc3NlcyAgPSBuZXcgSGFzaE1hcDw+KCk7Ci0gICAgICAgIF9pbnN0cnVjdGlvbkF0dHJzICAgID0gbmV3IEhhc2hNYXA8PigpOwotICAgICAgICBfdmFyaWFibGVTY29wZSAgICAgICA9IG5ldyBIYXNoTWFwPD4oKTsKLSAgICAgICAgX3RlbXBsYXRlICAgICAgICAgICAgPSBudWxsOwotICAgICAgICBfZXJyb3JzICAgICAgICAgICAgICA9IG5ldyBBcnJheUxpc3Q8PigpOwotICAgICAgICBfd2FybmluZ3MgICAgICAgICAgICA9IG5ldyBBcnJheUxpc3Q8PigpOwotICAgICAgICBfc3ltYm9sVGFibGUgICAgICAgICA9IG5ldyBTeW1ib2xUYWJsZSgpOwotICAgICAgICBfeHBhdGhQYXJzZXIgICAgICAgICA9IG5ldyBYUGF0aFBhcnNlcih0aGlzKTsKLSAgICAgICAgX2N1cnJlbnRTdHlsZXNoZWV0ICAgPSBudWxsOwotICAgICAgICBfb3V0cHV0ICAgICAgICAgICAgICA9IG51bGw7Ci0gICAgICAgIF9yb290ICAgICAgICAgICAgICAgID0gbnVsbDsKLSAgICAgICAgX3Jvb3ROYW1lc3BhY2VEZWYgICAgPSBmYWxzZTsKLSAgICAgICAgX2N1cnJlbnRJbXBvcnRQcmVjZWRlbmNlID0gMTsKLQotICAgICAgICBpbml0U3RkQ2xhc3NlcygpOwotICAgICAgICBpbml0SW5zdHJ1Y3Rpb25BdHRycygpOwotICAgICAgICBpbml0RXh0Q2xhc3NlcygpOwotICAgICAgICBpbml0U3ltYm9sVGFibGUoKTsKLQotICAgICAgICBfdXNlQXR0cmlidXRlU2V0cyA9Ci0gICAgICAgICAgICBnZXRRTmFtZShYU0xUX1VSSSwgWFNMLCAidXNlLWF0dHJpYnV0ZS1zZXRzIik7Ci0gICAgICAgIF9leGNsdWRlUmVzdWx0UHJlZml4ZXMgPQotICAgICAgICAgICAgZ2V0UU5hbWUoWFNMVF9VUkksIFhTTCwgImV4Y2x1ZGUtcmVzdWx0LXByZWZpeGVzIik7Ci0gICAgICAgIF9leHRlbnNpb25FbGVtZW50UHJlZml4ZXMgPQotICAgICAgICAgICAgZ2V0UU5hbWUoWFNMVF9VUkksIFhTTCwgImV4dGVuc2lvbi1lbGVtZW50LXByZWZpeGVzIik7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0T3V0cHV0KE91dHB1dCBvdXRwdXQpIHsKLSAgICAgICAgaWYgKF9vdXRwdXQgIT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKF9vdXRwdXQuZ2V0SW1wb3J0UHJlY2VkZW5jZSgpIDw9IG91dHB1dC5nZXRJbXBvcnRQcmVjZWRlbmNlKCkpIHsKLSAgICAgICAgICAgICAgICBvdXRwdXQubWVyZ2VPdXRwdXQoX291dHB1dCk7Ci0gICAgICAgICAgICAgICAgX291dHB1dC5kaXNhYmxlKCk7Ci0gICAgICAgICAgICAgICAgX291dHB1dCA9IG91dHB1dDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIG91dHB1dC5kaXNhYmxlKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBfb3V0cHV0ID0gb3V0cHV0OwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIE91dHB1dCBnZXRPdXRwdXQoKSB7Ci0gICAgICAgIHJldHVybiBfb3V0cHV0OwotICAgIH0KLQotICAgIHB1YmxpYyBQcm9wZXJ0aWVzIGdldE91dHB1dFByb3BlcnRpZXMoKSB7Ci0gICAgICAgIHJldHVybiBnZXRUb3BMZXZlbFN0eWxlc2hlZXQoKS5nZXRPdXRwdXRQcm9wZXJ0aWVzKCk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgYWRkVmFyaWFibGUoVmFyaWFibGUgdmFyKSB7Ci0gICAgICAgIGFkZFZhcmlhYmxlT3JQYXJhbSh2YXIpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGFkZFBhcmFtZXRlcihQYXJhbSBwYXJhbSkgewotICAgICAgICBhZGRWYXJpYWJsZU9yUGFyYW0ocGFyYW0pOwotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBhZGRWYXJpYWJsZU9yUGFyYW0oVmFyaWFibGVCYXNlIHZhcikgewotICAgICAgICBPYmplY3QgZXhpc3RpbmcgPSBfdmFyaWFibGVTY29wZS5nZXQodmFyLmdldE5hbWUoKS5nZXRTdHJpbmdSZXAoKSk7Ci0gICAgICAgIGlmIChleGlzdGluZyAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAoZXhpc3RpbmcgaW5zdGFuY2VvZiBTdGFjaykgewotICAgICAgICAgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQotICAgICAgICAgICAgICAgIFN0YWNrPFZhcmlhYmxlQmFzZT4gc3RhY2sgPSAoU3RhY2s8VmFyaWFibGVCYXNlPilleGlzdGluZzsKLSAgICAgICAgICAgICAgICBzdGFjay5wdXNoKHZhcik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChleGlzdGluZyBpbnN0YW5jZW9mIFZhcmlhYmxlQmFzZSkgewotICAgICAgICAgICAgICAgIFN0YWNrPFZhcmlhYmxlQmFzZT4gc3RhY2sgPSBuZXcgU3RhY2s8PigpOwotICAgICAgICAgICAgICAgIHN0YWNrLnB1c2goKFZhcmlhYmxlQmFzZSlleGlzdGluZyk7Ci0gICAgICAgICAgICAgICAgc3RhY2sucHVzaCh2YXIpOwotICAgICAgICAgICAgICAgIF92YXJpYWJsZVNjb3BlLnB1dCh2YXIuZ2V0TmFtZSgpLmdldFN0cmluZ1JlcCgpLCBzdGFjayk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBfdmFyaWFibGVTY29wZS5wdXQodmFyLmdldE5hbWUoKS5nZXRTdHJpbmdSZXAoKSwgdmFyKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHJlbW92ZVZhcmlhYmxlKFFOYW1lIG5hbWUpIHsKLSAgICAgICAgT2JqZWN0IGV4aXN0aW5nID0gX3ZhcmlhYmxlU2NvcGUuZ2V0KG5hbWUuZ2V0U3RyaW5nUmVwKCkpOwotICAgICAgICBpZiAoZXhpc3RpbmcgaW5zdGFuY2VvZiBTdGFjaykgewotICAgICAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCi0gICAgICAgICAgICBTdGFjazxWYXJpYWJsZUJhc2U+IHN0YWNrID0gKFN0YWNrPFZhcmlhYmxlQmFzZT4pZXhpc3Rpbmc7Ci0gICAgICAgICAgICBpZiAoIXN0YWNrLmlzRW1wdHkoKSkgc3RhY2sucG9wKCk7Ci0gICAgICAgICAgICBpZiAoIXN0YWNrLmlzRW1wdHkoKSkgcmV0dXJuOwotICAgICAgICB9Ci0gICAgICAgIF92YXJpYWJsZVNjb3BlLnJlbW92ZShuYW1lLmdldFN0cmluZ1JlcCgpKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgVmFyaWFibGVCYXNlIGxvb2t1cFZhcmlhYmxlKFFOYW1lIG5hbWUpIHsKLSAgICAgICAgT2JqZWN0IGV4aXN0aW5nID0gX3ZhcmlhYmxlU2NvcGUuZ2V0KG5hbWUuZ2V0U3RyaW5nUmVwKCkpOwotICAgICAgICBpZiAoZXhpc3RpbmcgaW5zdGFuY2VvZiBWYXJpYWJsZUJhc2UpIHsKLSAgICAgICAgICAgIHJldHVybiAoVmFyaWFibGVCYXNlKWV4aXN0aW5nOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKGV4aXN0aW5nIGluc3RhbmNlb2YgU3RhY2spIHsKLSAgICAgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQotICAgICAgICAgICAgU3RhY2s8VmFyaWFibGVCYXNlPiBzdGFjayA9IChTdGFjazxWYXJpYWJsZUJhc2U+KWV4aXN0aW5nOwotICAgICAgICAgICAgcmV0dXJuIHN0YWNrLnBlZWsoKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRYU0xUQyhYU0xUQyB4c2x0YykgewotICAgICAgICBfeHNsdGMgPSB4c2x0YzsKLSAgICB9Ci0KLSAgICBwdWJsaWMgWFNMVEMgZ2V0WFNMVEMoKSB7Ci0gICAgICAgIHJldHVybiBfeHNsdGM7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBnZXRDdXJyZW50SW1wb3J0UHJlY2VkZW5jZSgpIHsKLSAgICAgICAgcmV0dXJuIF9jdXJyZW50SW1wb3J0UHJlY2VkZW5jZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldE5leHRJbXBvcnRQcmVjZWRlbmNlKCkgewotICAgICAgICByZXR1cm4gKytfY3VycmVudEltcG9ydFByZWNlZGVuY2U7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0Q3VycmVudFN0eWxlc2hlZXQoU3R5bGVzaGVldCBzdHlsZXNoZWV0KSB7Ci0gICAgICAgIF9jdXJyZW50U3R5bGVzaGVldCA9IHN0eWxlc2hlZXQ7Ci0gICAgfQotCi0gICAgcHVibGljIFN0eWxlc2hlZXQgZ2V0Q3VycmVudFN0eWxlc2hlZXQoKSB7Ci0gICAgICAgIHJldHVybiBfY3VycmVudFN0eWxlc2hlZXQ7Ci0gICAgfQotCi0gICAgcHVibGljIFN0eWxlc2hlZXQgZ2V0VG9wTGV2ZWxTdHlsZXNoZWV0KCkgewotICAgICAgICByZXR1cm4gX3hzbHRjLmdldFN0eWxlc2hlZXQoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgUU5hbWUgZ2V0UU5hbWVTYWZlKGZpbmFsIFN0cmluZyBzdHJpbmdSZXApIHsKLSAgICAgICAgLy8gcGFyc2UgYW5kIHJldHJpZXZlIG5hbWVzcGFjZQotICAgICAgICBmaW5hbCBpbnQgY29sb24gPSBzdHJpbmdSZXAubGFzdEluZGV4T2YoJzonKTsKLSAgICAgICAgaWYgKGNvbG9uICE9IC0xKSB7Ci0gICAgICAgICAgICBmaW5hbCBTdHJpbmcgcHJlZml4ID0gc3RyaW5nUmVwLnN1YnN0cmluZygwLCBjb2xvbik7Ci0gICAgICAgICAgICBmaW5hbCBTdHJpbmcgbG9jYWxuYW1lID0gc3RyaW5nUmVwLnN1YnN0cmluZyhjb2xvbiArIDEpOwotICAgICAgICAgICAgU3RyaW5nIG5hbWVzcGFjZSA9IG51bGw7Ci0KLSAgICAgICAgICAgIC8vIEdldCB0aGUgbmFtZXNwYWNlIHVyaSBmcm9tIHRoZSBzeW1ib2wgdGFibGUKLSAgICAgICAgICAgIGlmIChwcmVmaXguZXF1YWxzKFhNTE5TX1BSRUZJWCkgPT0gZmFsc2UpIHsKLSAgICAgICAgICAgICAgICBuYW1lc3BhY2UgPSBfc3ltYm9sVGFibGUubG9va3VwTmFtZXNwYWNlKHByZWZpeCk7Ci0gICAgICAgICAgICAgICAgaWYgKG5hbWVzcGFjZSA9PSBudWxsKSBuYW1lc3BhY2UgPSBFTVBUWVNUUklORzsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiBnZXRRTmFtZShuYW1lc3BhY2UsIHByZWZpeCwgbG9jYWxuYW1lKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIGZpbmFsIFN0cmluZyB1cmkgPSBzdHJpbmdSZXAuZXF1YWxzKFhNTE5TX1BSRUZJWCkgPyBudWxsCi0gICAgICAgICAgICAgICAgOiBfc3ltYm9sVGFibGUubG9va3VwTmFtZXNwYWNlKEVNUFRZU1RSSU5HKTsKLSAgICAgICAgICAgIHJldHVybiBnZXRRTmFtZSh1cmksIG51bGwsIHN0cmluZ1JlcCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgUU5hbWUgZ2V0UU5hbWUoZmluYWwgU3RyaW5nIHN0cmluZ1JlcCkgewotICAgICAgICByZXR1cm4gZ2V0UU5hbWUoc3RyaW5nUmVwLCB0cnVlLCBmYWxzZSk7Ci0gICAgfQotCi0gICAgcHVibGljIFFOYW1lIGdldFFOYW1lSWdub3JlRGVmYXVsdE5zKGZpbmFsIFN0cmluZyBzdHJpbmdSZXApIHsKLSAgICAgICAgcmV0dXJuIGdldFFOYW1lKHN0cmluZ1JlcCwgdHJ1ZSwgdHJ1ZSk7Ci0gICAgfQotCi0gICAgcHVibGljIFFOYW1lIGdldFFOYW1lKGZpbmFsIFN0cmluZyBzdHJpbmdSZXAsIGJvb2xlYW4gcmVwb3J0RXJyb3IpIHsKLSAgICAgICAgcmV0dXJuIGdldFFOYW1lKHN0cmluZ1JlcCwgcmVwb3J0RXJyb3IsIGZhbHNlKTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIFFOYW1lIGdldFFOYW1lKGZpbmFsIFN0cmluZyBzdHJpbmdSZXAsIGJvb2xlYW4gcmVwb3J0RXJyb3IsCi0gICAgICAgIGJvb2xlYW4gaWdub3JlRGVmYXVsdE5zKQotICAgIHsKLSAgICAgICAgLy8gcGFyc2UgYW5kIHJldHJpZXZlIG5hbWVzcGFjZQotICAgICAgICBmaW5hbCBpbnQgY29sb24gPSBzdHJpbmdSZXAubGFzdEluZGV4T2YoJzonKTsKLSAgICAgICAgaWYgKGNvbG9uICE9IC0xKSB7Ci0gICAgICAgICAgICBmaW5hbCBTdHJpbmcgcHJlZml4ID0gc3RyaW5nUmVwLnN1YnN0cmluZygwLCBjb2xvbik7Ci0gICAgICAgICAgICBmaW5hbCBTdHJpbmcgbG9jYWxuYW1lID0gc3RyaW5nUmVwLnN1YnN0cmluZyhjb2xvbiArIDEpOwotICAgICAgICAgICAgU3RyaW5nIG5hbWVzcGFjZSA9IG51bGw7Ci0KLSAgICAgICAgICAgIC8vIEdldCB0aGUgbmFtZXNwYWNlIHVyaSBmcm9tIHRoZSBzeW1ib2wgdGFibGUKLSAgICAgICAgICAgIGlmIChwcmVmaXguZXF1YWxzKFhNTE5TX1BSRUZJWCkgPT0gZmFsc2UpIHsKLSAgICAgICAgICAgICAgICBuYW1lc3BhY2UgPSBfc3ltYm9sVGFibGUubG9va3VwTmFtZXNwYWNlKHByZWZpeCk7Ci0gICAgICAgICAgICAgICAgaWYgKG5hbWVzcGFjZSA9PSBudWxsICYmIHJlcG9ydEVycm9yKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCBsaW5lID0gZ2V0TGluZU51bWJlcigpOwotICAgICAgICAgICAgICAgICAgICBFcnJvck1zZyBlcnIgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuTkFNRVNQQUNFX1VOREVGX0VSUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmUsIHByZWZpeCk7Ci0gICAgICAgICAgICAgICAgICAgIHJlcG9ydEVycm9yKEVSUk9SLCBlcnIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiBnZXRRTmFtZShuYW1lc3BhY2UsIHByZWZpeCwgbG9jYWxuYW1lKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIGlmIChzdHJpbmdSZXAuZXF1YWxzKFhNTE5TX1BSRUZJWCkpIHsKLSAgICAgICAgICAgICAgICBpZ25vcmVEZWZhdWx0TnMgPSB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZmluYWwgU3RyaW5nIGRlZlVSSSA9IGlnbm9yZURlZmF1bHROcyA/IG51bGwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IF9zeW1ib2xUYWJsZS5sb29rdXBOYW1lc3BhY2UoRU1QVFlTVFJJTkcpOwotICAgICAgICAgICAgcmV0dXJuIGdldFFOYW1lKGRlZlVSSSwgbnVsbCwgc3RyaW5nUmVwKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyBRTmFtZSBnZXRRTmFtZShTdHJpbmcgbmFtZXNwYWNlLCBTdHJpbmcgcHJlZml4LCBTdHJpbmcgbG9jYWxuYW1lKSB7Ci0gICAgICAgIGlmIChuYW1lc3BhY2UgPT0gbnVsbCB8fCBuYW1lc3BhY2UuZXF1YWxzKEVNUFRZU1RSSU5HKSkgewotICAgICAgICAgICAgUU5hbWUgbmFtZSA9IF9xTmFtZXMuZ2V0KGxvY2FsbmFtZSk7Ci0gICAgICAgICAgICBpZiAobmFtZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgbmFtZSA9IG5ldyBRTmFtZShudWxsLCBwcmVmaXgsIGxvY2FsbmFtZSk7Ci0gICAgICAgICAgICAgICAgX3FOYW1lcy5wdXQobG9jYWxuYW1lLCBuYW1lKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiBuYW1lOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgTWFwPFN0cmluZywgUU5hbWU+IHNwYWNlID0gX25hbWVzcGFjZXMuZ2V0KG5hbWVzcGFjZSk7Ci0gICAgICAgICAgICBTdHJpbmcgbGV4aWNhbFFOYW1lID0KLSAgICAgICAgICAgICAgICAgICAgICAgKHByZWZpeCA9PSBudWxsIHx8IHByZWZpeC5sZW5ndGgoKSA9PSAwKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gbG9jYWxuYW1lCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAocHJlZml4ICsgJzonICsgbG9jYWxuYW1lKTsKLQotICAgICAgICAgICAgaWYgKHNwYWNlID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmaW5hbCBRTmFtZSBuYW1lID0gbmV3IFFOYW1lKG5hbWVzcGFjZSwgcHJlZml4LCBsb2NhbG5hbWUpOwotICAgICAgICAgICAgICAgIF9uYW1lc3BhY2VzLnB1dChuYW1lc3BhY2UsIHNwYWNlID0gbmV3IEhhc2hNYXA8PigpKTsKLSAgICAgICAgICAgICAgICBzcGFjZS5wdXQobGV4aWNhbFFOYW1lLCBuYW1lKTsKLSAgICAgICAgICAgICAgICByZXR1cm4gbmFtZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIFFOYW1lIG5hbWUgPSBzcGFjZS5nZXQobGV4aWNhbFFOYW1lKTsKLSAgICAgICAgICAgICAgICBpZiAobmFtZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIG5hbWUgPSBuZXcgUU5hbWUobmFtZXNwYWNlLCBwcmVmaXgsIGxvY2FsbmFtZSk7Ci0gICAgICAgICAgICAgICAgICAgIHNwYWNlLnB1dChsZXhpY2FsUU5hbWUsIG5hbWUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICByZXR1cm4gbmFtZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyBRTmFtZSBnZXRRTmFtZShTdHJpbmcgc2NvcGUsIFN0cmluZyBuYW1lKSB7Ci0gICAgICAgIHJldHVybiBnZXRRTmFtZShzY29wZSArIG5hbWUpOwotICAgIH0KLQotICAgIHB1YmxpYyBRTmFtZSBnZXRRTmFtZShRTmFtZSBzY29wZSwgUU5hbWUgbmFtZSkgewotICAgICAgICByZXR1cm4gZ2V0UU5hbWUoc2NvcGUudG9TdHJpbmcoKSArIG5hbWUudG9TdHJpbmcoKSk7Ci0gICAgfQotCi0gICAgcHVibGljIFFOYW1lIGdldFVzZUF0dHJpYnV0ZVNldHMoKSB7Ci0gICAgICAgIHJldHVybiBfdXNlQXR0cmlidXRlU2V0czsKLSAgICB9Ci0KLSAgICBwdWJsaWMgUU5hbWUgZ2V0RXh0ZW5zaW9uRWxlbWVudFByZWZpeGVzKCkgewotICAgICAgICByZXR1cm4gX2V4dGVuc2lvbkVsZW1lbnRQcmVmaXhlczsKLSAgICB9Ci0KLSAgICBwdWJsaWMgUU5hbWUgZ2V0RXhjbHVkZVJlc3VsdFByZWZpeGVzKCkgewotICAgICAgICByZXR1cm4gX2V4Y2x1ZGVSZXN1bHRQcmVmaXhlczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGUgYW4gaW5zdGFuY2Ugb2YgdGhlIDxjb2RlPlN0eWxlc2hlZXQ8L2NvZGU+IGNsYXNzLAotICAgICAqIGFuZCB0aGVuIHBhcnNlLCB0eXBlY2hlY2sgYW5kIGNvbXBpbGUgdGhlIGluc3RhbmNlLgotICAgICAqIE11c3QgYmUgY2FsbGVkIGFmdGVyIDxjb2RlPnBhcnNlKCk8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBTdHlsZXNoZWV0IG1ha2VTdHlsZXNoZWV0KFN5bnRheFRyZWVOb2RlIGVsZW1lbnQpCi0gICAgICAgIHRocm93cyBDb21waWxlckV4Y2VwdGlvbiB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBTdHlsZXNoZWV0IHN0eWxlc2hlZXQ7Ci0KLSAgICAgICAgICAgIGlmIChlbGVtZW50IGluc3RhbmNlb2YgU3R5bGVzaGVldCkgewotICAgICAgICAgICAgICAgIHN0eWxlc2hlZXQgPSAoU3R5bGVzaGVldCllbGVtZW50OwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgc3R5bGVzaGVldCA9IG5ldyBTdHlsZXNoZWV0KCk7Ci0gICAgICAgICAgICAgICAgc3R5bGVzaGVldC5zZXRTaW1wbGlmaWVkKCk7Ci0gICAgICAgICAgICAgICAgc3R5bGVzaGVldC5hZGRFbGVtZW50KGVsZW1lbnQpOwotICAgICAgICAgICAgICAgIHN0eWxlc2hlZXQuc2V0QXR0cmlidXRlcygoQXR0cmlidXRlc0ltcGwpIGVsZW1lbnQuZ2V0QXR0cmlidXRlcygpKTsKLQotICAgICAgICAgICAgICAgIC8vIE1hcCB0aGUgZGVmYXVsdCBOUyBpZiBub3QgYWxyZWFkeSBkZWZpbmVkCi0gICAgICAgICAgICAgICAgaWYgKGVsZW1lbnQubG9va3VwTmFtZXNwYWNlKEVNUFRZU1RSSU5HKSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuYWRkUHJlZml4TWFwcGluZyhFTVBUWVNUUklORywgRU1QVFlTVFJJTkcpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHN0eWxlc2hlZXQuc2V0UGFyc2VyKHRoaXMpOwotICAgICAgICAgICAgcmV0dXJuIHN0eWxlc2hlZXQ7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICBFcnJvck1zZyBlcnIgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuTk9UX1NUWUxFU0hFRVRfRVJSLCBlbGVtZW50KTsKLSAgICAgICAgICAgIHRocm93IG5ldyBDb21waWxlckV4Y2VwdGlvbihlcnIudG9TdHJpbmcoKSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJbnN0YW5jaWF0ZXMgYSBTQVgyIHBhcnNlciBhbmQgZ2VuZXJhdGUgdGhlIEFTVCBmcm9tIHRoZSBpbnB1dC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBjcmVhdGVBU1QoU3R5bGVzaGVldCBzdHlsZXNoZWV0KSB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBpZiAoc3R5bGVzaGVldCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgc3R5bGVzaGVldC5wYXJzZUNvbnRlbnRzKHRoaXMpOwotICAgICAgICAgICAgICAgIGZpbmFsIEl0ZXJhdG9yPFN5bnRheFRyZWVOb2RlPiBlbGVtZW50cyA9IHN0eWxlc2hlZXQuZWxlbWVudHMoKTsKLSAgICAgICAgICAgICAgICB3aGlsZSAoZWxlbWVudHMuaGFzTmV4dCgpKSB7Ci0gICAgICAgICAgICAgICAgICAgIFN5bnRheFRyZWVOb2RlIGNoaWxkID0gZWxlbWVudHMubmV4dCgpOwotICAgICAgICAgICAgICAgICAgICBpZiAoY2hpbGQgaW5zdGFuY2VvZiBUZXh0KSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgbCA9IGdldExpbmVOdW1iZXIoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIEVycm9yTXNnIGVyciA9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IEVycm9yTXNnKEVycm9yTXNnLklMTEVHQUxfVEVYVF9OT0RFX0VSUixsLG51bGwpOwotICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoRVJST1IsIGVycik7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaWYgKCFlcnJvcnNGb3VuZCgpKSB7Ci0gICAgICAgICAgICAgICAgICAgIHN0eWxlc2hlZXQudHlwZUNoZWNrKF9zeW1ib2xUYWJsZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChUeXBlQ2hlY2tFcnJvciBlKSB7Ci0gICAgICAgICAgICByZXBvcnRFcnJvcihFUlJPUiwgbmV3IEVycm9yTXNnKEVycm9yTXNnLkpBWFBfQ09NUElMRV9FUlIsIGUpKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFBhcnNlcyBhIHN0eWxlc2hlZXQgYW5kIGJ1aWxkcyB0aGUgaW50ZXJuYWwgYWJzdHJhY3Qgc3ludGF4IHRyZWUKLSAgICAgKiBAcGFyYW0gcmVhZGVyIEEgU0FYMiBTQVhSZWFkZXIgKHBhcnNlcikKLSAgICAgKiBAcGFyYW0gaW5wdXQgQSBTQVgyIElucHV0U291cmNlIGNhbiBiZSBwYXNzZWQgdG8gYSBTQVggcmVhZGVyCi0gICAgICogQHJldHVybiBUaGUgcm9vdCBvZiB0aGUgYWJzdHJhY3Qgc3ludGF4IHRyZWUKLSAgICAgKi8KLSAgICBwdWJsaWMgU3ludGF4VHJlZU5vZGUgcGFyc2UoWE1MUmVhZGVyIHJlYWRlciwgSW5wdXRTb3VyY2UgaW5wdXQpIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIC8vIFBhcnNlIHRoZSBpbnB1dCBkb2N1bWVudCBhbmQgYnVpbGQgdGhlIGFic3RyYWN0IHN5bnRheCB0cmVlCi0gICAgICAgICAgICByZWFkZXIuc2V0Q29udGVudEhhbmRsZXIodGhpcyk7Ci0gICAgICAgICAgICByZWFkZXIucGFyc2UoaW5wdXQpOwotICAgICAgICAgICAgLy8gRmluZCB0aGUgc3RhcnQgb2YgdGhlIHN0eWxlc2hlZXQgd2l0aGluIHRoZSB0cmVlCi0gICAgICAgICAgICByZXR1cm4gKFN5bnRheFRyZWVOb2RlKWdldFN0eWxlc2hlZXQoX3Jvb3QpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICBpZiAoX3hzbHRjLmRlYnVnKCkpIGUucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgICAgICByZXBvcnRFcnJvcihFUlJPUixuZXcgRXJyb3JNc2coRXJyb3JNc2cuSkFYUF9DT01QSUxFX0VSUiwgZSkpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChTQVhFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgVGhyb3dhYmxlIGV4ID0gZS5nZXRFeGNlcHRpb24oKTsKLSAgICAgICAgICAgIGlmIChfeHNsdGMuZGVidWcoKSkgewotICAgICAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgICAgICAgICAgaWYgKGV4ICE9IG51bGwpIGV4LnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmVwb3J0RXJyb3IoRVJST1IsIG5ldyBFcnJvck1zZyhFcnJvck1zZy5KQVhQX0NPTVBJTEVfRVJSLCBlKSk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKENvbXBpbGVyRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIGlmIChfeHNsdGMuZGVidWcoKSkgZS5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgICAgICAgIHJlcG9ydEVycm9yKEVSUk9SLCBuZXcgRXJyb3JNc2coRXJyb3JNc2cuSkFYUF9DT01QSUxFX0VSUiwgZSkpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgaWYgKF94c2x0Yy5kZWJ1ZygpKSBlLnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgICAgICAgcmVwb3J0RXJyb3IoRVJST1IsIG5ldyBFcnJvck1zZyhFcnJvck1zZy5KQVhQX0NPTVBJTEVfRVJSLCBlKSk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUGFyc2VzIGEgc3R5bGVzaGVldCBhbmQgYnVpbGRzIHRoZSBpbnRlcm5hbCBhYnN0cmFjdCBzeW50YXggdHJlZQotICAgICAqIEBwYXJhbSBpbnB1dCBBIFNBWDIgSW5wdXRTb3VyY2UgY2FuIGJlIHBhc3NlZCB0byBhIFNBWCByZWFkZXIKLSAgICAgKiBAcmV0dXJuIFRoZSByb290IG9mIHRoZSBhYnN0cmFjdCBzeW50YXggdHJlZQotICAgICAqLwotICAgIHB1YmxpYyBTeW50YXhUcmVlTm9kZSBwYXJzZShJbnB1dFNvdXJjZSBpbnB1dCkgewotICAgICAgICB0cnkgewotICAgICAgICAgICAgLy8gQ3JlYXRlIGEgU0FYIHBhcnNlciBhbmQgZ2V0IHRoZSBYTUxSZWFkZXIgb2JqZWN0IGl0IHVzZXMKLSAgICAgICAgICAgIGZpbmFsIFNBWFBhcnNlckZhY3RvcnkgZmFjdG9yeSA9IEZhY3RvcnlJbXBsLmdldFNBWEZhY3RvcnkoX3VzZVNlcnZpY2VzTWVjaGFuaXNtKTsKLQotICAgICAgICAgICAgaWYgKF94c2x0Yy5pc1NlY3VyZVByb2Nlc3NpbmcoKSkgewotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgIGZhY3Rvcnkuc2V0RmVhdHVyZShYTUxDb25zdGFudHMuRkVBVFVSRV9TRUNVUkVfUFJPQ0VTU0lORywgdHJ1ZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGNhdGNoIChTQVhFeGNlcHRpb24gZSkge30KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICBmYWN0b3J5LnNldEZlYXR1cmUoQ29uc3RhbnRzLk5BTUVTUEFDRV9GRUFUVVJFLHRydWUpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgZmFjdG9yeS5zZXROYW1lc3BhY2VBd2FyZSh0cnVlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGZpbmFsIFNBWFBhcnNlciBwYXJzZXIgPSBmYWN0b3J5Lm5ld1NBWFBhcnNlcigpOwotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICBwYXJzZXIuc2V0UHJvcGVydHkoWE1MQ29uc3RhbnRzLkFDQ0VTU19FWFRFUk5BTF9EVEQsCi0gICAgICAgICAgICAgICAgICAgICAgICBfeHNsdGMuZ2V0UHJvcGVydHkoWE1MQ29uc3RhbnRzLkFDQ0VTU19FWFRFUk5BTF9EVEQpKTsKLSAgICAgICAgICAgIH0gY2F0Y2ggKFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgIEVycm9yTXNnIGVyciA9IG5ldyBFcnJvck1zZyhFcnJvck1zZy5XQVJOSU5HX01TRywKLSAgICAgICAgICAgICAgICAgICAgICAgIHBhcnNlci5nZXRDbGFzcygpLmdldE5hbWUoKSArICI6ICIgKyBlLmdldE1lc3NhZ2UoKSk7Ci0gICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoV0FSTklORywgZXJyKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgZmluYWwgWE1MUmVhZGVyIHJlYWRlciA9IHBhcnNlci5nZXRYTUxSZWFkZXIoKTsKLSAgICAgICAgICAgIFN0cmluZyBsYXN0UHJvcGVydHkgPSAiIjsKLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgWE1MU2VjdXJpdHlNYW5hZ2VyIHNlY3VyaXR5TWFuYWdlciA9Ci0gICAgICAgICAgICAgICAgICAgICAgICAoWE1MU2VjdXJpdHlNYW5hZ2VyKV94c2x0Yy5nZXRQcm9wZXJ0eShYYWxhbkNvbnN0YW50cy5TRUNVUklUWV9NQU5BR0VSKTsKLSAgICAgICAgICAgICAgICBmb3IgKFhNTFNlY3VyaXR5TWFuYWdlci5MaW1pdCBsaW1pdCA6IFhNTFNlY3VyaXR5TWFuYWdlci5MaW1pdC52YWx1ZXMoKSkgewotICAgICAgICAgICAgICAgICAgICBsYXN0UHJvcGVydHkgPSBsaW1pdC5hcGlQcm9wZXJ0eSgpOwotICAgICAgICAgICAgICAgICAgICByZWFkZXIuc2V0UHJvcGVydHkobGFzdFByb3BlcnR5LCBzZWN1cml0eU1hbmFnZXIuZ2V0TGltaXRWYWx1ZUFzU3RyaW5nKGxpbWl0KSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGlmIChzZWN1cml0eU1hbmFnZXIucHJpbnRFbnRpdHlDb3VudEluZm8oKSkgewotICAgICAgICAgICAgICAgICAgICBsYXN0UHJvcGVydHkgPSBYYWxhbkNvbnN0YW50cy5KREtfRU5USVRZX0NPVU5UX0lORk87Ci0gICAgICAgICAgICAgICAgICAgIHBhcnNlci5zZXRQcm9wZXJ0eShYYWxhbkNvbnN0YW50cy5KREtfRU5USVRZX0NPVU5UX0lORk8sIFhhbGFuQ29uc3RhbnRzLkpES19ZRVMpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBzZSkgewotICAgICAgICAgICAgICAgIFhNTFNlY3VyaXR5TWFuYWdlci5wcmludFdhcm5pbmcocmVhZGVyLmdldENsYXNzKCkuZ2V0TmFtZSgpLCBsYXN0UHJvcGVydHksIHNlKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgcmV0dXJuKHBhcnNlKHJlYWRlciwgaW5wdXQpKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICBFcnJvck1zZyBlcnIgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuU0FYX1BBUlNFUl9DT05GSUdfRVJSKTsKLSAgICAgICAgICAgIHJlcG9ydEVycm9yKEVSUk9SLCBlcnIpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChTQVhQYXJzZUV4Y2VwdGlvbiBlKXsKLSAgICAgICAgICAgIHJlcG9ydEVycm9yKEVSUk9SLCBuZXcgRXJyb3JNc2coZS5nZXRNZXNzYWdlKCksZS5nZXRMaW5lTnVtYmVyKCkpKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIHJlcG9ydEVycm9yKEVSUk9SLCBuZXcgRXJyb3JNc2coZS5nZXRNZXNzYWdlKCkpKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3ludGF4VHJlZU5vZGUgZ2V0RG9jdW1lbnRSb290KCkgewotICAgICAgICByZXR1cm4gX3Jvb3Q7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBTdHJpbmcgX1BJbWVkaWEgPSBudWxsOwotICAgIHByaXZhdGUgU3RyaW5nIF9QSXRpdGxlID0gbnVsbDsKLSAgICBwcml2YXRlIFN0cmluZyBfUEljaGFyc2V0ID0gbnVsbDsKLQotICAgIC8qKgotICAgICAqIFNldCB0aGUgcGFyYW1ldGVycyB0byB1c2UgdG8gbG9jYXRlIHRoZSBjb3JyZWN0IDw/eG1sLXN0eWxlc2hlZXQgLi4uPz4KLSAgICAgKiBwcm9jZXNzaW5nIGluc3RydWN0aW9uIGluIHRoZSBjYXNlIHdoZXJlIHRoZSBpbnB1dCBkb2N1bWVudCBpcyBhbgotICAgICAqIFhNTCBkb2N1bWVudCB3aXRoIG9uZSBvciBtb3JlIHJlZmVyZW5jZXMgdG8gYSBzdHlsZXNoZWV0LgotICAgICAqIEBwYXJhbSBtZWRpYSBUaGUgbWVkaWEgYXR0cmlidXRlIHRvIGJlIG1hdGNoZWQuIE1heSBiZSBudWxsLCBpbiB3aGljaAotICAgICAqIGNhc2UgdGhlIHByZWZlcmVkIHRlbXBsYXRlcyB3aWxsIGJlIHVzZWQgKGkuZS4gYWx0ZXJuYXRlID0gbm8pLgotICAgICAqIEBwYXJhbSB0aXRsZSBUaGUgdmFsdWUgb2YgdGhlIHRpdGxlIGF0dHJpYnV0ZSB0byBtYXRjaC4gTWF5IGJlIG51bGwuCi0gICAgICogQHBhcmFtIGNoYXJzZXQgVGhlIHZhbHVlIG9mIHRoZSBjaGFyc2V0IGF0dHJpYnV0ZSB0byBtYXRjaC4gTWF5IGJlIG51bGwuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgc2V0UElQYXJhbWV0ZXJzKFN0cmluZyBtZWRpYSwgU3RyaW5nIHRpdGxlLCBTdHJpbmcgY2hhcnNldCkgewotICAgICAgICBfUEltZWRpYSA9IG1lZGlhOwotICAgICAgICBfUEl0aXRsZSA9IHRpdGxlOwotICAgICAgICBfUEljaGFyc2V0ID0gY2hhcnNldDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBFeHRyYWN0cyB0aGUgRE9NIGZvciB0aGUgc3R5bGVzaGVldC4gSW4gdGhlIGNhc2Ugb2YgYW4gZW1iZWRkZWQKLSAgICAgKiBzdHlsZXNoZWV0LCBpdCBleHRyYWN0cyB0aGUgRE9NIHN1YnRyZWUgY29ycmVzcG9uZGluZyB0byB0aGUKLSAgICAgKiBlbWJlZGRlZCBzdHlsZXNoZWV0IHRoYXQgaGFzIGFuICdpZCcgYXR0cmlidXRlIHdob3NlIHZhbHVlIGlzIHRoZQotICAgICAqIHNhbWUgYXMgdGhlIHZhbHVlIGRlY2xhcmVkIGluIHRoZSA8P3htbC1zdHlsZXNoZWV0Li4uPz4gcHJvY2Vzc2luZwotICAgICAqIGluc3RydWN0aW9uIChQLkkuKS4gSW4gdGhlIHhtbC1zdHlsZXNoZWV0IFAuSS4gdGhlIHZhbHVlIGlzIGxhYmVsZWQKLSAgICAgKiBhcyB0aGUgJ2hyZWYnIGRhdGEgb2YgdGhlIFAuSS4gVGhlIGV4dHJhY3RlZCBET00gcmVwcmVzZW50aW5nIHRoZQotICAgICAqIHN0eWxlc2hlZXQgaXMgcmV0dXJuZWQgYXMgYW4gRWxlbWVudCBvYmplY3QuCi0gICAgICovCi0gICAgcHJpdmF0ZSBTeW50YXhUcmVlTm9kZSBnZXRTdHlsZXNoZWV0KFN5bnRheFRyZWVOb2RlIHJvb3QpCi0gICAgICAgIHRocm93cyBDb21waWxlckV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy8gQXNzdW1lIHRoYXQgdGhpcyBpcyBhIHB1cmUgWFNMIHN0eWxlc2hlZXQgaWYgdGhlcmUgaXMgbm90Ci0gICAgICAgIC8vIDw/eG1sLXN0eWxlc2hlZXQgLi4uLj8+IHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24KLSAgICAgICAgaWYgKF90YXJnZXQgPT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKCFfcm9vdE5hbWVzcGFjZURlZikgewotICAgICAgICAgICAgICAgIEVycm9yTXNnIG1zZyA9IG5ldyBFcnJvck1zZyhFcnJvck1zZy5NSVNTSU5HX1hTTFRfVVJJX0VSUik7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IENvbXBpbGVyRXhjZXB0aW9uKG1zZy50b1N0cmluZygpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybihyb290KTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIEZpbmQgdGhlIHhzbDpzdHlsZXNoZWV0IG9yIHhzbDp0cmFuc2Zvcm0gd2l0aCB0aGlzIHJlZmVyZW5jZQotICAgICAgICBpZiAoX3RhcmdldC5jaGFyQXQoMCkgPT0gJyMnKSB7Ci0gICAgICAgICAgICBTeW50YXhUcmVlTm9kZSBlbGVtZW50ID0gZmluZFN0eWxlc2hlZXQocm9vdCwgX3RhcmdldC5zdWJzdHJpbmcoMSkpOwotICAgICAgICAgICAgaWYgKGVsZW1lbnQgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIEVycm9yTXNnIG1zZyA9IG5ldyBFcnJvck1zZyhFcnJvck1zZy5NSVNTSU5HX1hTTFRfVEFSR0VUX0VSUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3RhcmdldCwgcm9vdCk7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IENvbXBpbGVyRXhjZXB0aW9uKG1zZy50b1N0cmluZygpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybihlbGVtZW50KTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIHBhdGggPSBfdGFyZ2V0OwotICAgICAgICAgICAgICAgIGlmIChwYXRoLmluZGV4T2YoIjoiKT09LTEpIHsKLSAgICAgICAgICAgICAgICAgICAgcGF0aCA9ICJmaWxlOiIgKyBwYXRoOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBwYXRoID0gU3lzdGVtSURSZXNvbHZlci5nZXRBYnNvbHV0ZVVSSShwYXRoKTsKLSAgICAgICAgICAgICAgICBTdHJpbmcgYWNjZXNzRXJyb3IgPSBTZWN1cml0eVN1cHBvcnQuY2hlY2tBY2Nlc3MocGF0aCwKLSAgICAgICAgICAgICAgICAgICAgICAgIChTdHJpbmcpX3hzbHRjLmdldFByb3BlcnR5KFhNTENvbnN0YW50cy5BQ0NFU1NfRVhURVJOQUxfU1RZTEVTSEVFVCksCi0gICAgICAgICAgICAgICAgICAgICAgICBYYWxhbkNvbnN0YW50cy5BQ0NFU1NfRVhURVJOQUxfQUxMKTsKLSAgICAgICAgICAgICAgICBpZiAoYWNjZXNzRXJyb3IgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBFcnJvck1zZyBtc2cgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuQUNDRVNTSU5HX1hTTFRfVEFSR0VUX0VSUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZWN1cml0eVN1cHBvcnQuc2FuaXRpemVQYXRoKF90YXJnZXQpLCBhY2Nlc3NFcnJvciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICByb290KTsKLSAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IENvbXBpbGVyRXhjZXB0aW9uKG1zZy50b1N0cmluZygpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBDb21waWxlckV4Y2VwdGlvbihleCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIHJldHVybihsb2FkRXh0ZXJuYWxTdHlsZXNoZWV0KF90YXJnZXQpKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEZpbmQgYSBTdHlsZXNoZWV0IGVsZW1lbnQgd2l0aCBhIHNwZWNpZmljIElEIGF0dHJpYnV0ZSB2YWx1ZS4KLSAgICAgKiBUaGlzIG1ldGhvZCBpcyB1c2VkIHRvIGZpbmQgYSBTdHlsZXNoZWV0IG5vZGUgdGhhdCBpcyByZWZlcnJlZAotICAgICAqIGluIGEgPD94bWwtc3R5bGVzaGVldCAuLi4gPz4gcHJvY2Vzc2luZyBpbnN0cnVjdGlvbi4KLSAgICAgKi8KLSAgICBwcml2YXRlIFN5bnRheFRyZWVOb2RlIGZpbmRTdHlsZXNoZWV0KFN5bnRheFRyZWVOb2RlIHJvb3QsIFN0cmluZyBocmVmKSB7Ci0KLSAgICAgICAgaWYgKHJvb3QgPT0gbnVsbCkgcmV0dXJuIG51bGw7Ci0KLSAgICAgICAgaWYgKHJvb3QgaW5zdGFuY2VvZiBTdHlsZXNoZWV0KSB7Ci0gICAgICAgICAgICBTdHJpbmcgaWQgPSByb290LmdldEF0dHJpYnV0ZSgiaWQiKTsKLSAgICAgICAgICAgIGlmIChpZC5lcXVhbHMoaHJlZikpIHJldHVybiByb290OwotICAgICAgICB9Ci0gICAgICAgIExpc3Q8U3ludGF4VHJlZU5vZGU+IGNoaWxkcmVuID0gcm9vdC5nZXRDb250ZW50cygpOwotICAgICAgICBpZiAoY2hpbGRyZW4gIT0gbnVsbCkgewotICAgICAgICAgICAgZmluYWwgaW50IGNvdW50ID0gY2hpbGRyZW4uc2l6ZSgpOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgU3ludGF4VHJlZU5vZGUgY2hpbGQgPSBjaGlsZHJlbi5nZXQoaSk7Ci0gICAgICAgICAgICAgICAgU3ludGF4VHJlZU5vZGUgbm9kZSA9IGZpbmRTdHlsZXNoZWV0KGNoaWxkLCBocmVmKTsKLSAgICAgICAgICAgICAgICBpZiAobm9kZSAhPSBudWxsKSByZXR1cm4gbm9kZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBGb3IgZW1iZWRkZWQgc3R5bGVzaGVldHM6IExvYWQgYW4gZXh0ZXJuYWwgZmlsZSB3aXRoIHN0eWxlc2hlZXQKLSAgICAgKi8KLSAgICBwcml2YXRlIFN5bnRheFRyZWVOb2RlIGxvYWRFeHRlcm5hbFN0eWxlc2hlZXQoU3RyaW5nIGxvY2F0aW9uKQotICAgICAgICB0aHJvd3MgQ29tcGlsZXJFeGNlcHRpb24gewotCi0gICAgICAgIElucHV0U291cmNlIHNvdXJjZTsKLQotICAgICAgICAvLyBDaGVjayBpZiB0aGUgbG9jYXRpb24gaXMgVVJMIG9yIGEgbG9jYWwgZmlsZQotICAgICAgICBpZiAoKG5ldyBGaWxlKGxvY2F0aW9uKSkuZXhpc3RzKCkpCi0gICAgICAgICAgICBzb3VyY2UgPSBuZXcgSW5wdXRTb3VyY2UoImZpbGU6Iitsb2NhdGlvbik7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICAgIHNvdXJjZSA9IG5ldyBJbnB1dFNvdXJjZShsb2NhdGlvbik7Ci0KLSAgICAgICAgU3ludGF4VHJlZU5vZGUgZXh0ZXJuYWwgPSAoU3ludGF4VHJlZU5vZGUpcGFyc2Uoc291cmNlKTsKLSAgICAgICAgcmV0dXJuKGV4dGVybmFsKTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgaW5pdEF0dHJUYWJsZShTdHJpbmcgZWxlbWVudE5hbWUsIFN0cmluZ1tdIGF0dHJzKSB7Ci0gICAgICAgIF9pbnN0cnVjdGlvbkF0dHJzLnB1dChnZXRRTmFtZShYU0xUX1VSSSwgWFNMLCBlbGVtZW50TmFtZSkuZ2V0U3RyaW5nUmVwKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJzKTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgaW5pdEluc3RydWN0aW9uQXR0cnMoKSB7Ci0gICAgICAgIGluaXRBdHRyVGFibGUoInRlbXBsYXRlIiwKLSAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7Im1hdGNoIiwgIm5hbWUiLCAicHJpb3JpdHkiLCAibW9kZSJ9KTsKLSAgICAgICAgaW5pdEF0dHJUYWJsZSgic3R5bGVzaGVldCIsCi0gICAgICAgICAgICBuZXcgU3RyaW5nW10geyJpZCIsICJ2ZXJzaW9uIiwgImV4dGVuc2lvbi1lbGVtZW50LXByZWZpeGVzIiwKLSAgICAgICAgICAgICAgICAiZXhjbHVkZS1yZXN1bHQtcHJlZml4ZXMifSk7Ci0gICAgICAgIGluaXRBdHRyVGFibGUoInRyYW5zZm9ybSIsCi0gICAgICAgICAgICBuZXcgU3RyaW5nW10geyJpZCIsICJ2ZXJzaW9uIiwgImV4dGVuc2lvbi1lbGVtZW50LXByZWZpeGVzIiwKLSAgICAgICAgICAgICAgICAiZXhjbHVkZS1yZXN1bHQtcHJlZml4ZXMifSk7Ci0gICAgICAgIGluaXRBdHRyVGFibGUoInRleHQiLCBuZXcgU3RyaW5nW10geyJkaXNhYmxlLW91dHB1dC1lc2NhcGluZyJ9KTsKLSAgICAgICAgaW5pdEF0dHJUYWJsZSgiaWYiLCBuZXcgU3RyaW5nW10geyJ0ZXN0In0pOwotICAgICAgICBpbml0QXR0clRhYmxlKCJjaG9vc2UiLCBuZXcgU3RyaW5nW10ge30pOwotICAgICAgICBpbml0QXR0clRhYmxlKCJ3aGVuIiwgbmV3IFN0cmluZ1tdIHsidGVzdCJ9KTsKLSAgICAgICAgaW5pdEF0dHJUYWJsZSgib3RoZXJ3aXNlIiwgbmV3IFN0cmluZ1tdIHt9KTsKLSAgICAgICAgaW5pdEF0dHJUYWJsZSgiZm9yLWVhY2giLCBuZXcgU3RyaW5nW10geyJzZWxlY3QifSk7Ci0gICAgICAgIGluaXRBdHRyVGFibGUoIm1lc3NhZ2UiLCBuZXcgU3RyaW5nW10geyJ0ZXJtaW5hdGUifSk7Ci0gICAgICAgIGluaXRBdHRyVGFibGUoIm51bWJlciIsCi0gICAgICAgICAgICBuZXcgU3RyaW5nW10geyJsZXZlbCIsICJjb3VudCIsICJmcm9tIiwgInZhbHVlIiwgImZvcm1hdCIsICJsYW5nIiwKLSAgICAgICAgICAgICAgICAibGV0dGVyLXZhbHVlIiwgImdyb3VwaW5nLXNlcGFyYXRvciIsICJncm91cGluZy1zaXplIn0pOwotICAgICAgICAgICAgICAgIGluaXRBdHRyVGFibGUoImNvbW1lbnQiLCBuZXcgU3RyaW5nW10ge30pOwotICAgICAgICBpbml0QXR0clRhYmxlKCJjb3B5IiwgbmV3IFN0cmluZ1tdIHsidXNlLWF0dHJpYnV0ZS1zZXRzIn0pOwotICAgICAgICBpbml0QXR0clRhYmxlKCJjb3B5LW9mIiwgbmV3IFN0cmluZ1tdIHsic2VsZWN0In0pOwotICAgICAgICBpbml0QXR0clRhYmxlKCJwYXJhbSIsIG5ldyBTdHJpbmdbXSB7Im5hbWUiLCAic2VsZWN0In0pOwotICAgICAgICBpbml0QXR0clRhYmxlKCJ3aXRoLXBhcmFtIiwgbmV3IFN0cmluZ1tdIHsibmFtZSIsICJzZWxlY3QifSk7Ci0gICAgICAgIGluaXRBdHRyVGFibGUoInZhcmlhYmxlIiwgbmV3IFN0cmluZ1tdIHsibmFtZSIsICJzZWxlY3QifSk7Ci0gICAgICAgIGluaXRBdHRyVGFibGUoIm91dHB1dCIsCi0gICAgICAgICAgICBuZXcgU3RyaW5nW10geyJtZXRob2QiLCAidmVyc2lvbiIsICJlbmNvZGluZyIsCi0gICAgICAgICAgICAgICAgIm9taXQteG1sLWRlY2xhcmF0aW9uIiwgInN0YW5kYWxvbmUiLCAiZG9jdHlwZS1wdWJsaWMiLAotICAgICAgICAgICAgICAgICJkb2N0eXBlLXN5c3RlbSIsICJjZGF0YS1zZWN0aW9uLWVsZW1lbnRzIiwgImluZGVudCIsCi0gICAgICAgICAgICAgICAgIm1lZGlhLXR5cGUifSk7Ci0gICAgICAgIGluaXRBdHRyVGFibGUoInNvcnQiLAotICAgICAgICAgICBuZXcgU3RyaW5nW10geyJzZWxlY3QiLCAib3JkZXIiLCAiY2FzZS1vcmRlciIsICJsYW5nIiwgImRhdGEtdHlwZSJ9KTsKLSAgICAgICAgaW5pdEF0dHJUYWJsZSgia2V5IiwgbmV3IFN0cmluZ1tdIHsibmFtZSIsICJtYXRjaCIsICJ1c2UifSk7Ci0gICAgICAgIGluaXRBdHRyVGFibGUoImZhbGxiYWNrIiwgbmV3IFN0cmluZ1tdIHt9KTsKLSAgICAgICAgaW5pdEF0dHJUYWJsZSgiYXR0cmlidXRlIiwgbmV3IFN0cmluZ1tdIHsibmFtZSIsICJuYW1lc3BhY2UifSk7Ci0gICAgICAgIGluaXRBdHRyVGFibGUoImF0dHJpYnV0ZS1zZXQiLAotICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHsibmFtZSIsICJ1c2UtYXR0cmlidXRlLXNldHMifSk7Ci0gICAgICAgIGluaXRBdHRyVGFibGUoInZhbHVlLW9mIiwKLSAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7InNlbGVjdCIsICJkaXNhYmxlLW91dHB1dC1lc2NhcGluZyJ9KTsKLSAgICAgICAgaW5pdEF0dHJUYWJsZSgiZWxlbWVudCIsCi0gICAgICAgICAgICBuZXcgU3RyaW5nW10geyJuYW1lIiwgIm5hbWVzcGFjZSIsICJ1c2UtYXR0cmlidXRlLXNldHMifSk7Ci0gICAgICAgIGluaXRBdHRyVGFibGUoImNhbGwtdGVtcGxhdGUiLCBuZXcgU3RyaW5nW10geyJuYW1lIn0pOwotICAgICAgICBpbml0QXR0clRhYmxlKCJhcHBseS10ZW1wbGF0ZXMiLCBuZXcgU3RyaW5nW10geyJzZWxlY3QiLCAibW9kZSJ9KTsKLSAgICAgICAgaW5pdEF0dHJUYWJsZSgiYXBwbHktaW1wb3J0cyIsIG5ldyBTdHJpbmdbXSB7fSk7Ci0gICAgICAgIGluaXRBdHRyVGFibGUoImRlY2ltYWwtZm9ybWF0IiwKLSAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7Im5hbWUiLCAiZGVjaW1hbC1zZXBhcmF0b3IiLCAiZ3JvdXBpbmctc2VwYXJhdG9yIiwKLSAgICAgICAgICAgICAgICAiaW5maW5pdHkiLCAibWludXMtc2lnbiIsICJOYU4iLCAicGVyY2VudCIsICJwZXItbWlsbGUiLAotICAgICAgICAgICAgICAgICJ6ZXJvLWRpZ2l0IiwgImRpZ2l0IiwgInBhdHRlcm4tc2VwYXJhdG9yIn0pOwotICAgICAgICBpbml0QXR0clRhYmxlKCJpbXBvcnQiLCBuZXcgU3RyaW5nW10geyJocmVmIn0pOwotICAgICAgICBpbml0QXR0clRhYmxlKCJpbmNsdWRlIiwgbmV3IFN0cmluZ1tdIHsiaHJlZiJ9KTsKLSAgICAgICAgaW5pdEF0dHJUYWJsZSgic3RyaXAtc3BhY2UiLCBuZXcgU3RyaW5nW10geyJlbGVtZW50cyJ9KTsKLSAgICAgICAgaW5pdEF0dHJUYWJsZSgicHJlc2VydmUtc3BhY2UiLCBuZXcgU3RyaW5nW10geyJlbGVtZW50cyJ9KTsKLSAgICAgICAgaW5pdEF0dHJUYWJsZSgicHJvY2Vzc2luZy1pbnN0cnVjdGlvbiIsIG5ldyBTdHJpbmdbXSB7Im5hbWUifSk7Ci0gICAgICAgIGluaXRBdHRyVGFibGUoIm5hbWVzcGFjZS1hbGlhcyIsCi0gICAgICAgICAgIG5ldyBTdHJpbmdbXSB7InN0eWxlc2hlZXQtcHJlZml4IiwgInJlc3VsdC1wcmVmaXgifSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSW5pdGlhbGl6ZSB0aGUgX2luc3RydWN0aW9uQ2xhc3NlcyBtYXAsIHdoaWNoIG1hcHMgWFNMIGVsZW1lbnQKLSAgICAgKiBuYW1lcyB0byBKYXZhIGNsYXNzZXMgaW4gdGhpcyBwYWNrYWdlLgotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCBpbml0U3RkQ2xhc3NlcygpIHsKLSAgICAgICAgaW5pdFN0ZENsYXNzKCJ0ZW1wbGF0ZSIsICJUZW1wbGF0ZSIpOwotICAgICAgICBpbml0U3RkQ2xhc3MoInN0eWxlc2hlZXQiLCAiU3R5bGVzaGVldCIpOwotICAgICAgICBpbml0U3RkQ2xhc3MoInRyYW5zZm9ybSIsICJTdHlsZXNoZWV0Iik7Ci0gICAgICAgIGluaXRTdGRDbGFzcygidGV4dCIsICJUZXh0Iik7Ci0gICAgICAgIGluaXRTdGRDbGFzcygiaWYiLCAiSWYiKTsKLSAgICAgICAgaW5pdFN0ZENsYXNzKCJjaG9vc2UiLCAiQ2hvb3NlIik7Ci0gICAgICAgIGluaXRTdGRDbGFzcygid2hlbiIsICJXaGVuIik7Ci0gICAgICAgIGluaXRTdGRDbGFzcygib3RoZXJ3aXNlIiwgIk90aGVyd2lzZSIpOwotICAgICAgICBpbml0U3RkQ2xhc3MoImZvci1lYWNoIiwgIkZvckVhY2giKTsKLSAgICAgICAgaW5pdFN0ZENsYXNzKCJtZXNzYWdlIiwgIk1lc3NhZ2UiKTsKLSAgICAgICAgaW5pdFN0ZENsYXNzKCJudW1iZXIiLCAiTnVtYmVyIik7Ci0gICAgICAgIGluaXRTdGRDbGFzcygiY29tbWVudCIsICJDb21tZW50Iik7Ci0gICAgICAgIGluaXRTdGRDbGFzcygiY29weSIsICJDb3B5Iik7Ci0gICAgICAgIGluaXRTdGRDbGFzcygiY29weS1vZiIsICJDb3B5T2YiKTsKLSAgICAgICAgaW5pdFN0ZENsYXNzKCJwYXJhbSIsICJQYXJhbSIpOwotICAgICAgICBpbml0U3RkQ2xhc3MoIndpdGgtcGFyYW0iLCAiV2l0aFBhcmFtIik7Ci0gICAgICAgIGluaXRTdGRDbGFzcygidmFyaWFibGUiLCAiVmFyaWFibGUiKTsKLSAgICAgICAgaW5pdFN0ZENsYXNzKCJvdXRwdXQiLCAiT3V0cHV0Iik7Ci0gICAgICAgIGluaXRTdGRDbGFzcygic29ydCIsICJTb3J0Iik7Ci0gICAgICAgIGluaXRTdGRDbGFzcygia2V5IiwgIktleSIpOwotICAgICAgICBpbml0U3RkQ2xhc3MoImZhbGxiYWNrIiwgIkZhbGxiYWNrIik7Ci0gICAgICAgIGluaXRTdGRDbGFzcygiYXR0cmlidXRlIiwgIlhzbEF0dHJpYnV0ZSIpOwotICAgICAgICBpbml0U3RkQ2xhc3MoImF0dHJpYnV0ZS1zZXQiLCAiQXR0cmlidXRlU2V0Iik7Ci0gICAgICAgIGluaXRTdGRDbGFzcygidmFsdWUtb2YiLCAiVmFsdWVPZiIpOwotICAgICAgICBpbml0U3RkQ2xhc3MoImVsZW1lbnQiLCAiWHNsRWxlbWVudCIpOwotICAgICAgICBpbml0U3RkQ2xhc3MoImNhbGwtdGVtcGxhdGUiLCAiQ2FsbFRlbXBsYXRlIik7Ci0gICAgICAgIGluaXRTdGRDbGFzcygiYXBwbHktdGVtcGxhdGVzIiwgIkFwcGx5VGVtcGxhdGVzIik7Ci0gICAgICAgIGluaXRTdGRDbGFzcygiYXBwbHktaW1wb3J0cyIsICJBcHBseUltcG9ydHMiKTsKLSAgICAgICAgaW5pdFN0ZENsYXNzKCJkZWNpbWFsLWZvcm1hdCIsICJEZWNpbWFsRm9ybWF0dGluZyIpOwotICAgICAgICBpbml0U3RkQ2xhc3MoImltcG9ydCIsICJJbXBvcnQiKTsKLSAgICAgICAgaW5pdFN0ZENsYXNzKCJpbmNsdWRlIiwgIkluY2x1ZGUiKTsKLSAgICAgICAgaW5pdFN0ZENsYXNzKCJzdHJpcC1zcGFjZSIsICJXaGl0ZXNwYWNlIik7Ci0gICAgICAgIGluaXRTdGRDbGFzcygicHJlc2VydmUtc3BhY2UiLCAiV2hpdGVzcGFjZSIpOwotICAgICAgICBpbml0U3RkQ2xhc3MoInByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24iLCAiUHJvY2Vzc2luZ0luc3RydWN0aW9uIik7Ci0gICAgICAgIGluaXRTdGRDbGFzcygibmFtZXNwYWNlLWFsaWFzIiwgIk5hbWVzcGFjZUFsaWFzIik7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIGluaXRTdGRDbGFzcyhTdHJpbmcgZWxlbWVudE5hbWUsIFN0cmluZyBjbGFzc05hbWUpIHsKLSAgICAgICAgX2luc3RydWN0aW9uQ2xhc3Nlcy5wdXQoZ2V0UU5hbWUoWFNMVF9VUkksIFhTTCwgZWxlbWVudE5hbWUpLmdldFN0cmluZ1JlcCgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDT01QSUxFUl9QQUNLQUdFICsgJy4nICsgY2xhc3NOYW1lKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBlbGVtZW50U3VwcG9ydGVkKFN0cmluZyBuYW1lc3BhY2UsIFN0cmluZyBsb2NhbE5hbWUpIHsKLSAgICAgICAgcmV0dXJuKF9pbnN0cnVjdGlvbkNsYXNzZXMuZ2V0KGdldFFOYW1lKG5hbWVzcGFjZSwgWFNMLCBsb2NhbE5hbWUpLmdldFN0cmluZ1JlcCgpKSAhPSBudWxsKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBmdW5jdGlvblN1cHBvcnRlZChTdHJpbmcgZm5hbWUpIHsKLSAgICAgICAgcmV0dXJuKF9zeW1ib2xUYWJsZS5sb29rdXBQcmltb3AoZm5hbWUpICE9IG51bGwpOwotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBpbml0RXh0Q2xhc3NlcygpIHsKLSAgICAgICAgaW5pdEV4dENsYXNzKCJvdXRwdXQiLCAiVHJhbnNsZXRPdXRwdXQiKTsKLSAgICAgICAgaW5pdEV4dENsYXNzKFJFRElSRUNUX1VSSSwgIndyaXRlIiwgIlRyYW5zbGV0T3V0cHV0Iik7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIGluaXRFeHRDbGFzcyhTdHJpbmcgZWxlbWVudE5hbWUsIFN0cmluZyBjbGFzc05hbWUpIHsKLSAgICAgICAgX2luc3RydWN0aW9uQ2xhc3Nlcy5wdXQoZ2V0UU5hbWUoVFJBTlNMRVRfVVJJLCBUUkFOU0xFVCwgZWxlbWVudE5hbWUpLmdldFN0cmluZ1JlcCgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDT01QSUxFUl9QQUNLQUdFICsgJy4nICsgY2xhc3NOYW1lKTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgaW5pdEV4dENsYXNzKFN0cmluZyBuYW1lc3BhY2UsIFN0cmluZyBlbGVtZW50TmFtZSwgU3RyaW5nIGNsYXNzTmFtZSkgewotICAgICAgICBfaW5zdHJ1Y3Rpb25DbGFzc2VzLnB1dChnZXRRTmFtZShuYW1lc3BhY2UsIFRSQU5TTEVULCBlbGVtZW50TmFtZSkuZ2V0U3RyaW5nUmVwKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPTVBJTEVSX1BBQ0tBR0UgKyAnLicgKyBjbGFzc05hbWUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEFkZCBwcmltb3BzIGFuZCBiYXNlIGZ1bmN0aW9ucyB0byB0aGUgc3ltYm9sIHRhYmxlLgotICAgICAqLwotICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bnVzZWQiKQotICAgIHByaXZhdGUgdm9pZCBpbml0U3ltYm9sVGFibGUoKSB7Ci0gICAgICAgIE1ldGhvZFR5cGUgSV9WICA9IG5ldyBNZXRob2RUeXBlKFR5cGUuSW50LCBUeXBlLlZvaWQpOwotICAgICAgICBNZXRob2RUeXBlIElfUiAgPSBuZXcgTWV0aG9kVHlwZShUeXBlLkludCwgVHlwZS5SZWFsKTsKLSAgICAgICAgTWV0aG9kVHlwZSBJX1MgID0gbmV3IE1ldGhvZFR5cGUoVHlwZS5JbnQsIFR5cGUuU3RyaW5nKTsKLSAgICAgICAgTWV0aG9kVHlwZSBJX0QgID0gbmV3IE1ldGhvZFR5cGUoVHlwZS5JbnQsIFR5cGUuTm9kZVNldCk7Ci0gICAgICAgIE1ldGhvZFR5cGUgUl9JICA9IG5ldyBNZXRob2RUeXBlKFR5cGUuUmVhbCwgVHlwZS5JbnQpOwotICAgICAgICBNZXRob2RUeXBlIFJfViAgPSBuZXcgTWV0aG9kVHlwZShUeXBlLlJlYWwsIFR5cGUuVm9pZCk7Ci0gICAgICAgIE1ldGhvZFR5cGUgUl9SICA9IG5ldyBNZXRob2RUeXBlKFR5cGUuUmVhbCwgVHlwZS5SZWFsKTsKLSAgICAgICAgTWV0aG9kVHlwZSBSX0QgID0gbmV3IE1ldGhvZFR5cGUoVHlwZS5SZWFsLCBUeXBlLk5vZGVTZXQpOwotICAgICAgICBNZXRob2RUeXBlIFJfTyAgPSBuZXcgTWV0aG9kVHlwZShUeXBlLlJlYWwsIFR5cGUuUmVmZXJlbmNlKTsKLSAgICAgICAgTWV0aG9kVHlwZSBJX0kgID0gbmV3IE1ldGhvZFR5cGUoVHlwZS5JbnQsIFR5cGUuSW50KTsKLSAgICAgICAgTWV0aG9kVHlwZSBEX08gID0gbmV3IE1ldGhvZFR5cGUoVHlwZS5Ob2RlU2V0LCBUeXBlLlJlZmVyZW5jZSk7Ci0gICAgICAgIE1ldGhvZFR5cGUgRF9WICA9IG5ldyBNZXRob2RUeXBlKFR5cGUuTm9kZVNldCwgVHlwZS5Wb2lkKTsKLSAgICAgICAgTWV0aG9kVHlwZSBEX1MgID0gbmV3IE1ldGhvZFR5cGUoVHlwZS5Ob2RlU2V0LCBUeXBlLlN0cmluZyk7Ci0gICAgICAgIE1ldGhvZFR5cGUgRF9EICA9IG5ldyBNZXRob2RUeXBlKFR5cGUuTm9kZVNldCwgVHlwZS5Ob2RlU2V0KTsKLSAgICAgICAgTWV0aG9kVHlwZSBBX1YgID0gbmV3IE1ldGhvZFR5cGUoVHlwZS5Ob2RlLCBUeXBlLlZvaWQpOwotICAgICAgICBNZXRob2RUeXBlIFNfViAgPSBuZXcgTWV0aG9kVHlwZShUeXBlLlN0cmluZywgVHlwZS5Wb2lkKTsKLSAgICAgICAgTWV0aG9kVHlwZSBTX1MgID0gbmV3IE1ldGhvZFR5cGUoVHlwZS5TdHJpbmcsIFR5cGUuU3RyaW5nKTsKLSAgICAgICAgTWV0aG9kVHlwZSBTX0EgID0gbmV3IE1ldGhvZFR5cGUoVHlwZS5TdHJpbmcsIFR5cGUuTm9kZSk7Ci0gICAgICAgIE1ldGhvZFR5cGUgU19EICA9IG5ldyBNZXRob2RUeXBlKFR5cGUuU3RyaW5nLCBUeXBlLk5vZGVTZXQpOwotICAgICAgICBNZXRob2RUeXBlIFNfTyAgPSBuZXcgTWV0aG9kVHlwZShUeXBlLlN0cmluZywgVHlwZS5SZWZlcmVuY2UpOwotICAgICAgICBNZXRob2RUeXBlIEJfTyAgPSBuZXcgTWV0aG9kVHlwZShUeXBlLkJvb2xlYW4sIFR5cGUuUmVmZXJlbmNlKTsKLSAgICAgICAgTWV0aG9kVHlwZSBCX1YgID0gbmV3IE1ldGhvZFR5cGUoVHlwZS5Cb29sZWFuLCBUeXBlLlZvaWQpOwotICAgICAgICBNZXRob2RUeXBlIEJfQiAgPSBuZXcgTWV0aG9kVHlwZShUeXBlLkJvb2xlYW4sIFR5cGUuQm9vbGVhbik7Ci0gICAgICAgIE1ldGhvZFR5cGUgQl9TICA9IG5ldyBNZXRob2RUeXBlKFR5cGUuQm9vbGVhbiwgVHlwZS5TdHJpbmcpOwotICAgICAgICBNZXRob2RUeXBlIERfWCAgPSBuZXcgTWV0aG9kVHlwZShUeXBlLk5vZGVTZXQsIFR5cGUuT2JqZWN0KTsKLSAgICAgICAgTWV0aG9kVHlwZSBSX1JSID0gbmV3IE1ldGhvZFR5cGUoVHlwZS5SZWFsLCBUeXBlLlJlYWwsIFR5cGUuUmVhbCk7Ci0gICAgICAgIE1ldGhvZFR5cGUgSV9JSSA9IG5ldyBNZXRob2RUeXBlKFR5cGUuSW50LCBUeXBlLkludCwgVHlwZS5JbnQpOwotICAgICAgICBNZXRob2RUeXBlIEJfUlIgPSBuZXcgTWV0aG9kVHlwZShUeXBlLkJvb2xlYW4sIFR5cGUuUmVhbCwgVHlwZS5SZWFsKTsKLSAgICAgICAgTWV0aG9kVHlwZSBCX0lJID0gbmV3IE1ldGhvZFR5cGUoVHlwZS5Cb29sZWFuLCBUeXBlLkludCwgVHlwZS5JbnQpOwotICAgICAgICBNZXRob2RUeXBlIFNfU1MgPSBuZXcgTWV0aG9kVHlwZShUeXBlLlN0cmluZywgVHlwZS5TdHJpbmcsIFR5cGUuU3RyaW5nKTsKLSAgICAgICAgTWV0aG9kVHlwZSBTX0RTID0gbmV3IE1ldGhvZFR5cGUoVHlwZS5TdHJpbmcsIFR5cGUuUmVhbCwgVHlwZS5TdHJpbmcpOwotICAgICAgICBNZXRob2RUeXBlIFNfU1IgPSBuZXcgTWV0aG9kVHlwZShUeXBlLlN0cmluZywgVHlwZS5TdHJpbmcsIFR5cGUuUmVhbCk7Ci0gICAgICAgIE1ldGhvZFR5cGUgT19TTyA9IG5ldyBNZXRob2RUeXBlKFR5cGUuUmVmZXJlbmNlLCBUeXBlLlN0cmluZywgVHlwZS5SZWZlcmVuY2UpOwotCi0gICAgICAgIE1ldGhvZFR5cGUgRF9TUyA9Ci0gICAgICAgICAgICBuZXcgTWV0aG9kVHlwZShUeXBlLk5vZGVTZXQsIFR5cGUuU3RyaW5nLCBUeXBlLlN0cmluZyk7Ci0gICAgICAgIE1ldGhvZFR5cGUgRF9TRCA9Ci0gICAgICAgICAgICBuZXcgTWV0aG9kVHlwZShUeXBlLk5vZGVTZXQsIFR5cGUuU3RyaW5nLCBUeXBlLk5vZGVTZXQpOwotICAgICAgICBNZXRob2RUeXBlIEJfQkIgPQotICAgICAgICAgICAgbmV3IE1ldGhvZFR5cGUoVHlwZS5Cb29sZWFuLCBUeXBlLkJvb2xlYW4sIFR5cGUuQm9vbGVhbik7Ci0gICAgICAgIE1ldGhvZFR5cGUgQl9TUyA9Ci0gICAgICAgICAgICBuZXcgTWV0aG9kVHlwZShUeXBlLkJvb2xlYW4sIFR5cGUuU3RyaW5nLCBUeXBlLlN0cmluZyk7Ci0gICAgICAgIE1ldGhvZFR5cGUgU19TRCA9Ci0gICAgICAgICAgICBuZXcgTWV0aG9kVHlwZShUeXBlLlN0cmluZywgVHlwZS5TdHJpbmcsIFR5cGUuTm9kZVNldCk7Ci0gICAgICAgIE1ldGhvZFR5cGUgU19EU1MgPQotICAgICAgICAgICAgbmV3IE1ldGhvZFR5cGUoVHlwZS5TdHJpbmcsIFR5cGUuUmVhbCwgVHlwZS5TdHJpbmcsIFR5cGUuU3RyaW5nKTsKLSAgICAgICAgTWV0aG9kVHlwZSBTX1NSUiA9Ci0gICAgICAgICAgICBuZXcgTWV0aG9kVHlwZShUeXBlLlN0cmluZywgVHlwZS5TdHJpbmcsIFR5cGUuUmVhbCwgVHlwZS5SZWFsKTsKLSAgICAgICAgTWV0aG9kVHlwZSBTX1NTUyA9Ci0gICAgICAgICAgICBuZXcgTWV0aG9kVHlwZShUeXBlLlN0cmluZywgVHlwZS5TdHJpbmcsIFR5cGUuU3RyaW5nLCBUeXBlLlN0cmluZyk7Ci0KLSAgICAgICAgLyoKLSAgICAgICAgICogU3RhbmRhcmQgZnVuY3Rpb25zOiBpbXBsZW1lbnRlZCBidXQgbm90IGluIHRoaXMgdGFibGUgY29uY2F0KCkuCi0gICAgICAgICAqIFdoZW4gYWRkaW5nIGEgbmV3IGZ1bmN0aW9uIG1ha2Ugc3VyZSB0byB1bmNvbW1lbnQKLSAgICAgICAgICogdGhlIGNvcnJlc3BvbmRpbmcgbGluZSBpbiA8dHQ+RnVuY3Rpb25BdmFpbGFibGVDYWxsPC90dD4uCi0gICAgICAgICAqLwotCi0gICAgICAgIC8vIFRoZSBmb2xsb3dpbmcgZnVuY3Rpb25zIGFyZSBpbmxpbmVkCi0KLSAgICAgICAgX3N5bWJvbFRhYmxlLmFkZFByaW1vcCgiY3VycmVudCIsIEFfVik7Ci0gICAgICAgIF9zeW1ib2xUYWJsZS5hZGRQcmltb3AoImxhc3QiLCBJX1YpOwotICAgICAgICBfc3ltYm9sVGFibGUuYWRkUHJpbW9wKCJwb3NpdGlvbiIsIElfVik7Ci0gICAgICAgIF9zeW1ib2xUYWJsZS5hZGRQcmltb3AoInRydWUiLCBCX1YpOwotICAgICAgICBfc3ltYm9sVGFibGUuYWRkUHJpbW9wKCJmYWxzZSIsIEJfVik7Ci0gICAgICAgIF9zeW1ib2xUYWJsZS5hZGRQcmltb3AoIm5vdCIsIEJfQik7Ci0gICAgICAgIF9zeW1ib2xUYWJsZS5hZGRQcmltb3AoIm5hbWUiLCBTX1YpOwotICAgICAgICBfc3ltYm9sVGFibGUuYWRkUHJpbW9wKCJuYW1lIiwgU19BKTsKLSAgICAgICAgX3N5bWJvbFRhYmxlLmFkZFByaW1vcCgiZ2VuZXJhdGUtaWQiLCBTX1YpOwotICAgICAgICBfc3ltYm9sVGFibGUuYWRkUHJpbW9wKCJnZW5lcmF0ZS1pZCIsIFNfQSk7Ci0gICAgICAgIF9zeW1ib2xUYWJsZS5hZGRQcmltb3AoImNlaWxpbmciLCBSX1IpOwotICAgICAgICBfc3ltYm9sVGFibGUuYWRkUHJpbW9wKCJmbG9vciIsIFJfUik7Ci0gICAgICAgIF9zeW1ib2xUYWJsZS5hZGRQcmltb3AoInJvdW5kIiwgUl9SKTsKLSAgICAgICAgX3N5bWJvbFRhYmxlLmFkZFByaW1vcCgiY29udGFpbnMiLCBCX1NTKTsKLSAgICAgICAgX3N5bWJvbFRhYmxlLmFkZFByaW1vcCgibnVtYmVyIiwgUl9PKTsKLSAgICAgICAgX3N5bWJvbFRhYmxlLmFkZFByaW1vcCgibnVtYmVyIiwgUl9WKTsKLSAgICAgICAgX3N5bWJvbFRhYmxlLmFkZFByaW1vcCgiYm9vbGVhbiIsIEJfTyk7Ci0gICAgICAgIF9zeW1ib2xUYWJsZS5hZGRQcmltb3AoInN0cmluZyIsIFNfTyk7Ci0gICAgICAgIF9zeW1ib2xUYWJsZS5hZGRQcmltb3AoInN0cmluZyIsIFNfVik7Ci0gICAgICAgIF9zeW1ib2xUYWJsZS5hZGRQcmltb3AoInRyYW5zbGF0ZSIsIFNfU1NTKTsKLSAgICAgICAgX3N5bWJvbFRhYmxlLmFkZFByaW1vcCgic3RyaW5nLWxlbmd0aCIsIElfVik7Ci0gICAgICAgIF9zeW1ib2xUYWJsZS5hZGRQcmltb3AoInN0cmluZy1sZW5ndGgiLCBJX1MpOwotICAgICAgICBfc3ltYm9sVGFibGUuYWRkUHJpbW9wKCJzdGFydHMtd2l0aCIsIEJfU1MpOwotICAgICAgICBfc3ltYm9sVGFibGUuYWRkUHJpbW9wKCJmb3JtYXQtbnVtYmVyIiwgU19EUyk7Ci0gICAgICAgIF9zeW1ib2xUYWJsZS5hZGRQcmltb3AoImZvcm1hdC1udW1iZXIiLCBTX0RTUyk7Ci0gICAgICAgIF9zeW1ib2xUYWJsZS5hZGRQcmltb3AoInVucGFyc2VkLWVudGl0eS11cmkiLCBTX1MpOwotICAgICAgICBfc3ltYm9sVGFibGUuYWRkUHJpbW9wKCJrZXkiLCBEX1NTKTsKLSAgICAgICAgX3N5bWJvbFRhYmxlLmFkZFByaW1vcCgia2V5IiwgRF9TRCk7Ci0gICAgICAgIF9zeW1ib2xUYWJsZS5hZGRQcmltb3AoImlkIiwgRF9TKTsKLSAgICAgICAgX3N5bWJvbFRhYmxlLmFkZFByaW1vcCgiaWQiLCBEX0QpOwotICAgICAgICBfc3ltYm9sVGFibGUuYWRkUHJpbW9wKCJuYW1lc3BhY2UtdXJpIiwgU19WKTsKLSAgICAgICAgX3N5bWJvbFRhYmxlLmFkZFByaW1vcCgiZnVuY3Rpb24tYXZhaWxhYmxlIiwgQl9TKTsKLSAgICAgICAgX3N5bWJvbFRhYmxlLmFkZFByaW1vcCgiZWxlbWVudC1hdmFpbGFibGUiLCBCX1MpOwotICAgICAgICBfc3ltYm9sVGFibGUuYWRkUHJpbW9wKCJkb2N1bWVudCIsIERfUyk7Ci0gICAgICAgIF9zeW1ib2xUYWJsZS5hZGRQcmltb3AoImRvY3VtZW50IiwgRF9WKTsKLQotICAgICAgICAvLyBUaGUgZm9sbG93aW5nIGZ1bmN0aW9ucyBhcmUgaW1wbGVtZW50ZWQgaW4gdGhlIGJhc2lzIGxpYnJhcnkKLSAgICAgICAgX3N5bWJvbFRhYmxlLmFkZFByaW1vcCgiY291bnQiLCBJX0QpOwotICAgICAgICBfc3ltYm9sVGFibGUuYWRkUHJpbW9wKCJzdW0iLCBSX0QpOwotICAgICAgICBfc3ltYm9sVGFibGUuYWRkUHJpbW9wKCJsb2NhbC1uYW1lIiwgU19WKTsKLSAgICAgICAgX3N5bWJvbFRhYmxlLmFkZFByaW1vcCgibG9jYWwtbmFtZSIsIFNfRCk7Ci0gICAgICAgIF9zeW1ib2xUYWJsZS5hZGRQcmltb3AoIm5hbWVzcGFjZS11cmkiLCBTX1YpOwotICAgICAgICBfc3ltYm9sVGFibGUuYWRkUHJpbW9wKCJuYW1lc3BhY2UtdXJpIiwgU19EKTsKLSAgICAgICAgX3N5bWJvbFRhYmxlLmFkZFByaW1vcCgic3Vic3RyaW5nIiwgU19TUik7Ci0gICAgICAgIF9zeW1ib2xUYWJsZS5hZGRQcmltb3AoInN1YnN0cmluZyIsIFNfU1JSKTsKLSAgICAgICAgX3N5bWJvbFRhYmxlLmFkZFByaW1vcCgic3Vic3RyaW5nLWFmdGVyIiwgU19TUyk7Ci0gICAgICAgIF9zeW1ib2xUYWJsZS5hZGRQcmltb3AoInN1YnN0cmluZy1iZWZvcmUiLCBTX1NTKTsKLSAgICAgICAgX3N5bWJvbFRhYmxlLmFkZFByaW1vcCgibm9ybWFsaXplLXNwYWNlIiwgU19WKTsKLSAgICAgICAgX3N5bWJvbFRhYmxlLmFkZFByaW1vcCgibm9ybWFsaXplLXNwYWNlIiwgU19TKTsKLSAgICAgICAgX3N5bWJvbFRhYmxlLmFkZFByaW1vcCgic3lzdGVtLXByb3BlcnR5IiwgU19TKTsKLQotICAgICAgICAvLyBFeHRlbnNpb25zCi0gICAgICAgIF9zeW1ib2xUYWJsZS5hZGRQcmltb3AoIm5vZGVzZXQiLCBEX08pOwotICAgICAgICBfc3ltYm9sVGFibGUuYWRkUHJpbW9wKCJvYmplY3RUeXBlIiwgU19PKTsKLSAgICAgICAgX3N5bWJvbFRhYmxlLmFkZFByaW1vcCgiY2FzdCIsIE9fU08pOwotCi0gICAgICAgIC8vIE9wZXJhdG9ycyArLCAtLCAqLCAvLCAlIGRlZmluZWQgb24gcmVhbCB0eXBlcy4KLSAgICAgICAgX3N5bWJvbFRhYmxlLmFkZFByaW1vcCgiKyIsIFJfUlIpOwotICAgICAgICBfc3ltYm9sVGFibGUuYWRkUHJpbW9wKCItIiwgUl9SUik7Ci0gICAgICAgIF9zeW1ib2xUYWJsZS5hZGRQcmltb3AoIioiLCBSX1JSKTsKLSAgICAgICAgX3N5bWJvbFRhYmxlLmFkZFByaW1vcCgiLyIsIFJfUlIpOwotICAgICAgICBfc3ltYm9sVGFibGUuYWRkUHJpbW9wKCIlIiwgUl9SUik7Ci0KLSAgICAgICAgLy8gT3BlcmF0b3JzICssIC0sICogZGVmaW5lZCBvbiBpbnRlZ2VyIHR5cGVzLgotICAgICAgICAvLyBPcGVyYXRvcnMgLyBhbmQgJSBhcmUgbm90ICBkZWZpbmVkIG9uIGludGVnZXJzIChtYXkgY2F1c2UgZXhjZXB0aW9uKQotICAgICAgICBfc3ltYm9sVGFibGUuYWRkUHJpbW9wKCIrIiwgSV9JSSk7Ci0gICAgICAgIF9zeW1ib2xUYWJsZS5hZGRQcmltb3AoIi0iLCBJX0lJKTsKLSAgICAgICAgX3N5bWJvbFRhYmxlLmFkZFByaW1vcCgiKiIsIElfSUkpOwotCi0gICAgICAgICAvLyBPcGVyYXRvcnMgPCwgPD0gPiwgPj0gZGVmaW5lZCBvbiByZWFsIHR5cGVzLgotICAgICAgICBfc3ltYm9sVGFibGUuYWRkUHJpbW9wKCI8IiwgIEJfUlIpOwotICAgICAgICBfc3ltYm9sVGFibGUuYWRkUHJpbW9wKCI8PSIsIEJfUlIpOwotICAgICAgICBfc3ltYm9sVGFibGUuYWRkUHJpbW9wKCI+IiwgIEJfUlIpOwotICAgICAgICBfc3ltYm9sVGFibGUuYWRkUHJpbW9wKCI+PSIsIEJfUlIpOwotCi0gICAgICAgIC8vIE9wZXJhdG9ycyA8LCA8PSA+LCA+PSBkZWZpbmVkIG9uIGludCB0eXBlcy4KLSAgICAgICAgX3N5bWJvbFRhYmxlLmFkZFByaW1vcCgiPCIsICBCX0lJKTsKLSAgICAgICAgX3N5bWJvbFRhYmxlLmFkZFByaW1vcCgiPD0iLCBCX0lJKTsKLSAgICAgICAgX3N5bWJvbFRhYmxlLmFkZFByaW1vcCgiPiIsICBCX0lJKTsKLSAgICAgICAgX3N5bWJvbFRhYmxlLmFkZFByaW1vcCgiPj0iLCBCX0lJKTsKLQotICAgICAgICAvLyBPcGVyYXRvcnMgPCwgPD0gPiwgPj0gZGVmaW5lZCBvbiBib29sZWFuIHR5cGVzLgotICAgICAgICBfc3ltYm9sVGFibGUuYWRkUHJpbW9wKCI8IiwgIEJfQkIpOwotICAgICAgICBfc3ltYm9sVGFibGUuYWRkUHJpbW9wKCI8PSIsIEJfQkIpOwotICAgICAgICBfc3ltYm9sVGFibGUuYWRkUHJpbW9wKCI+IiwgIEJfQkIpOwotICAgICAgICBfc3ltYm9sVGFibGUuYWRkUHJpbW9wKCI+PSIsIEJfQkIpOwotCi0gICAgICAgIC8vIE9wZXJhdG9ycyAnYW5kJyBhbmQgJ29yJy4KLSAgICAgICAgX3N5bWJvbFRhYmxlLmFkZFByaW1vcCgib3IiLCBCX0JCKTsKLSAgICAgICAgX3N5bWJvbFRhYmxlLmFkZFByaW1vcCgiYW5kIiwgQl9CQik7Ci0KLSAgICAgICAgLy8gVW5hcnkgbWludXMuCi0gICAgICAgIF9zeW1ib2xUYWJsZS5hZGRQcmltb3AoInUtIiwgUl9SKTsKLSAgICAgICAgX3N5bWJvbFRhYmxlLmFkZFByaW1vcCgidS0iLCBJX0kpOwotICAgIH0KLQotICAgIHB1YmxpYyBTeW1ib2xUYWJsZSBnZXRTeW1ib2xUYWJsZSgpIHsKLSAgICAgICAgcmV0dXJuIF9zeW1ib2xUYWJsZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgVGVtcGxhdGUgZ2V0VGVtcGxhdGUoKSB7Ci0gICAgICAgIHJldHVybiBfdGVtcGxhdGU7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0VGVtcGxhdGUoVGVtcGxhdGUgdGVtcGxhdGUpIHsKLSAgICAgICAgX3RlbXBsYXRlID0gdGVtcGxhdGU7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBpbnQgX3RlbXBsYXRlSW5kZXggPSAwOwotCi0gICAgcHVibGljIGludCBnZXRUZW1wbGF0ZUluZGV4KCkgewotICAgICAgICByZXR1cm4oX3RlbXBsYXRlSW5kZXgrKyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlcyBhIG5ldyBub2RlIGluIHRoZSBhYnN0cmFjdCBzeW50YXggdHJlZS4gVGhpcyBub2RlIGNhbiBiZQotICAgICAqICBvKSBhIHN1cHBvcnRlZCBYU0xUIDEuMCBlbGVtZW50Ci0gICAgICogIG8pIGFuIHVuc3VwcG9ydGVkIFhTTFQgZWxlbWVudCAocG9zdCAxLjApCi0gICAgICogIG8pIGEgc3VwcG9ydGVkIFhTTFQgZXh0ZW5zaW9uCi0gICAgICogIG8pIGFuIHVuc3VwcG9ydGVkIFhTTFQgZXh0ZW5zaW9uCi0gICAgICogIG8pIGEgbGl0ZXJhbCByZXN1bHQgZWxlbWVudCAobm90IGFuIFhTTFQgZWxlbWVudCBhbmQgbm90IGFuIGV4dGVuc2lvbikKLSAgICAgKiBVbnN1cHBvcnRlZCBlbGVtZW50cyBkbyBub3QgZGlyZWN0bHkgZ2VuZXJhdGUgYW4gZXJyb3IuIFdlIGhhdmUgdG8gd2FpdAotICAgICAqIHVudGlsIHdlIGhhdmUgcmVjZWl2ZWQgYWxsIGNoaWxkIGVsZW1lbnRzIG9mIGFuIHVuc3VwcG9ydGVkIGVsZW1lbnQgdG8KLSAgICAgKiBzZWUgaWYgYW55IDx4c2w6ZmFsbGJhY2s+IGVsZW1lbnRzIGV4aXN0LgotICAgICAqLwotCi0gICAgcHJpdmF0ZSBib29sZWFuIHZlcnNpb25Jc09uZSA9IHRydWU7Ci0KLSAgICBwdWJsaWMgU3ludGF4VHJlZU5vZGUgbWFrZUluc3RhbmNlKFN0cmluZyB1cmksIFN0cmluZyBwcmVmaXgsCi0gICAgICAgIFN0cmluZyBsb2NhbCwgQXR0cmlidXRlcyBhdHRyaWJ1dGVzKQotICAgIHsKLSAgICAgICAgU3ludGF4VHJlZU5vZGUgbm9kZSA9IG51bGw7Ci0gICAgICAgIFFOYW1lIHFuYW1lID0gZ2V0UU5hbWUodXJpLCBwcmVmaXgsIGxvY2FsKTsKLSAgICAgICAgU3RyaW5nIGNsYXNzTmFtZSA9IF9pbnN0cnVjdGlvbkNsYXNzZXMuZ2V0KHFuYW1lLmdldFN0cmluZ1JlcCgpKTsKLQotICAgICAgICBpZiAoY2xhc3NOYW1lICE9IG51bGwpIHsKLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgZmluYWwgQ2xhc3M8Pz4gY2xhenogPSBPYmplY3RGYWN0b3J5LmZpbmRQcm92aWRlckNsYXNzKGNsYXNzTmFtZSwgdHJ1ZSk7Ci0gICAgICAgICAgICAgICAgbm9kZSA9IChTeW50YXhUcmVlTm9kZSljbGF6ei5uZXdJbnN0YW5jZSgpOwotICAgICAgICAgICAgICAgIG5vZGUuc2V0UU5hbWUocW5hbWUpOwotICAgICAgICAgICAgICAgIG5vZGUuc2V0UGFyc2VyKHRoaXMpOwotICAgICAgICAgICAgICAgIGlmIChfbG9jYXRvciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIG5vZGUuc2V0TGluZU51bWJlcihnZXRMaW5lTnVtYmVyKCkpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpZiAobm9kZSBpbnN0YW5jZW9mIFN0eWxlc2hlZXQpIHsKLSAgICAgICAgICAgICAgICAgICAgX3hzbHRjLnNldFN0eWxlc2hlZXQoKFN0eWxlc2hlZXQpbm9kZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGNoZWNrRm9yU3VwZXJmbHVvdXNBdHRyaWJ1dGVzKG5vZGUsIGF0dHJpYnV0ZXMpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgIEVycm9yTXNnIGVyciA9IG5ldyBFcnJvck1zZyhFcnJvck1zZy5DTEFTU19OT1RfRk9VTkRfRVJSLCBub2RlKTsKLSAgICAgICAgICAgICAgICByZXBvcnRFcnJvcihFUlJPUiwgZXJyKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgIEVycm9yTXNnIGVyciA9IG5ldyBFcnJvck1zZyhFcnJvck1zZy5JTlRFUk5BTF9FUlIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGUuZ2V0TWVzc2FnZSgpLCBub2RlKTsKLSAgICAgICAgICAgICAgICByZXBvcnRFcnJvcihGQVRBTCwgZXJyKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIGlmICh1cmkgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIHRoZSBlbGVtZW50IGJlbG9uZ3MgaW4gb3VyIG5hbWVzcGFjZQotICAgICAgICAgICAgICAgIGlmICh1cmkuZXF1YWxzKFhTTFRfVVJJKSkgewotICAgICAgICAgICAgICAgICAgICBub2RlID0gbmV3IFVuc3VwcG9ydGVkRWxlbWVudCh1cmksIHByZWZpeCwgbG9jYWwsIGZhbHNlKTsKLSAgICAgICAgICAgICAgICAgICAgVW5zdXBwb3J0ZWRFbGVtZW50IGVsZW1lbnQgPSAoVW5zdXBwb3J0ZWRFbGVtZW50KW5vZGU7Ci0gICAgICAgICAgICAgICAgICAgIEVycm9yTXNnIG1zZyA9IG5ldyBFcnJvck1zZyhFcnJvck1zZy5VTlNVUFBPUlRFRF9YU0xfRVJSLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0TGluZU51bWJlcigpLGxvY2FsKTsKLSAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5zZXRFcnJvck1lc3NhZ2UobXNnKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKHZlcnNpb25Jc09uZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoVU5TVVBQT1JURUQsbXNnKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvLyBDaGVjayBpZiB0aGlzIGlzIGFuIFhTTFRDIGV4dGVuc2lvbiBlbGVtZW50Ci0gICAgICAgICAgICAgICAgZWxzZSBpZiAodXJpLmVxdWFscyhUUkFOU0xFVF9VUkkpKSB7Ci0gICAgICAgICAgICAgICAgICAgIG5vZGUgPSBuZXcgVW5zdXBwb3J0ZWRFbGVtZW50KHVyaSwgcHJlZml4LCBsb2NhbCwgdHJ1ZSk7Ci0gICAgICAgICAgICAgICAgICAgIFVuc3VwcG9ydGVkRWxlbWVudCBlbGVtZW50ID0gKFVuc3VwcG9ydGVkRWxlbWVudClub2RlOwotICAgICAgICAgICAgICAgICAgICBFcnJvck1zZyBtc2cgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuVU5TVVBQT1JURURfRVhUX0VSUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldExpbmVOdW1iZXIoKSxsb2NhbCk7Ci0gICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuc2V0RXJyb3JNZXNzYWdlKG1zZyk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIHRoaXMgaXMgYW4gZXh0ZW5zaW9uIG9mIHNvbWUgb3RoZXIgWFNMVCBwcm9jZXNzb3IKLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgU3R5bGVzaGVldCBzaGVldCA9IF94c2x0Yy5nZXRTdHlsZXNoZWV0KCk7Ci0gICAgICAgICAgICAgICAgICAgIGlmICgoc2hlZXQgIT0gbnVsbCkgJiYgKHNoZWV0LmlzRXh0ZW5zaW9uKHVyaSkpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2hlZXQgIT0gX3BhcmVudFN0YWNrLnBlZWsoKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUgPSBuZXcgVW5zdXBwb3J0ZWRFbGVtZW50KHVyaSwgcHJlZml4LCBsb2NhbCwgdHJ1ZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgVW5zdXBwb3J0ZWRFbGVtZW50IGVsZW0gPSAoVW5zdXBwb3J0ZWRFbGVtZW50KW5vZGU7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgRXJyb3JNc2cgbXNnID0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IEVycm9yTXNnKEVycm9yTXNnLlVOU1VQUE9SVEVEX0VYVF9FUlIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRMaW5lTnVtYmVyKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmVmaXgrIjoiK2xvY2FsKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtLnNldEVycm9yTWVzc2FnZShtc2cpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKG5vZGUgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIG5vZGUgPSBuZXcgTGl0ZXJhbEVsZW1lbnQoKTsKLSAgICAgICAgICAgICAgICBub2RlLnNldExpbmVOdW1iZXIoZ2V0TGluZU51bWJlcigpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBpZiAoKG5vZGUgIT0gbnVsbCkgJiYgKG5vZGUgaW5zdGFuY2VvZiBMaXRlcmFsRWxlbWVudCkpIHsKLSAgICAgICAgICAgICgoTGl0ZXJhbEVsZW1lbnQpbm9kZSkuc2V0UU5hbWUocW5hbWUpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybihub2RlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBjaGVja3MgdGhlIGxpc3Qgb2YgYXR0cmlidXRlcyBhZ2FpbnN0IGEgbGlzdCBvZiBhbGxvd2VkIGF0dHJpYnV0ZXMKLSAgICAgKiBmb3IgYSBwYXJ0aWN1bGFyIGVsZW1lbnQgbm9kZS4KLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgY2hlY2tGb3JTdXBlcmZsdW91c0F0dHJpYnV0ZXMoU3ludGF4VHJlZU5vZGUgbm9kZSwKLSAgICAgICAgQXR0cmlidXRlcyBhdHRycykKLSAgICB7Ci0gICAgICAgIFFOYW1lIHFuYW1lID0gbm9kZS5nZXRRTmFtZSgpOwotICAgICAgICBib29sZWFuIGlzU3R5bGVzaGVldCA9IChub2RlIGluc3RhbmNlb2YgU3R5bGVzaGVldCk7Ci0gICAgICAgIFN0cmluZ1tdIGxlZ2FsID0gX2luc3RydWN0aW9uQXR0cnMuZ2V0KHFuYW1lLmdldFN0cmluZ1JlcCgpKTsKLSAgICAgICAgaWYgKHZlcnNpb25Jc09uZSAmJiBsZWdhbCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpbnQgajsKLSAgICAgICAgICAgIGZpbmFsIGludCBuID0gYXR0cnMuZ2V0TGVuZ3RoKCk7Ci0KLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIGF0dHJRTmFtZSA9IGF0dHJzLmdldFFOYW1lKGkpOwotCi0gICAgICAgICAgICAgICAgaWYgKGlzU3R5bGVzaGVldCAmJiBhdHRyUU5hbWUuZXF1YWxzKCJ2ZXJzaW9uIikpIHsKLSAgICAgICAgICAgICAgICAgICAgdmVyc2lvbklzT25lID0gYXR0cnMuZ2V0VmFsdWUoaSkuZXF1YWxzKCIxLjAiKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyBJZ25vcmUgaWYgc3BlY2lhbCBvciBpZiBpdCBoYXMgYSBwcmVmaXgKLSAgICAgICAgICAgICAgICBpZiAoYXR0clFOYW1lLnN0YXJ0c1dpdGgoInhtbCIpIHx8Ci0gICAgICAgICAgICAgICAgICAgIGF0dHJRTmFtZS5pbmRleE9mKCc6JykgPiAwKSBjb250aW51ZTsKLQotICAgICAgICAgICAgICAgIGZvciAoaiA9IDA7IGogPCBsZWdhbC5sZW5ndGg7IGorKykgewotICAgICAgICAgICAgICAgICAgICBpZiAoYXR0clFOYW1lLmVxdWFsc0lnbm9yZUNhc2UobGVnYWxbal0pKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpZiAoaiA9PSBsZWdhbC5sZW5ndGgpIHsKLSAgICAgICAgICAgICAgICAgICAgZmluYWwgRXJyb3JNc2cgZXJyID0KLSAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBFcnJvck1zZyhFcnJvck1zZy5JTExFR0FMX0FUVFJJQlVURV9FUlIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJRTmFtZSwgbm9kZSk7Ci0gICAgICAgICAgICAgICAgICAgIC8vIFdvcmthcm91bmQgZm9yIHRoZSBUQ0sgZmFpbHVyZSBFcnJvckxpc3RlbmVyLmVycm9yVGVzdHMuZXJyb3IwMDEuLgotICAgICAgICAgICAgICAgICAgICBlcnIuc2V0V2FybmluZ0Vycm9yKHRydWUpOwotICAgICAgICAgICAgICAgICAgICByZXBvcnRFcnJvcihXQVJOSU5HLCBlcnIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogUGFyc2UgYW4gWFBhdGggZXhwcmVzc2lvbjoKLSAgICAgKiAgQHBhcmFtIHBhcmVudCAtIFhTTCBlbGVtZW50IHdoZXJlIHRoZSBleHByZXNzaW9uIG9jY3VyZWQKLSAgICAgKiAgQHBhcmFtIGV4cCAgICAtIHRleHR1YWwgcmVwcmVzZW50YXRpb24gb2YgdGhlIGV4cHJlc3Npb24KLSAgICAgKi8KLSAgICBwdWJsaWMgRXhwcmVzc2lvbiBwYXJzZUV4cHJlc3Npb24oU3ludGF4VHJlZU5vZGUgcGFyZW50LCBTdHJpbmcgZXhwKSB7Ci0gICAgICAgIHJldHVybiAoRXhwcmVzc2lvbilwYXJzZVRvcExldmVsKHBhcmVudCwgIjxFWFBSRVNTSU9OPiIrZXhwLCBudWxsKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBQYXJzZSBhbiBYUGF0aCBleHByZXNzaW9uOgotICAgICAqICBAcGFyYW0gcGFyZW50IC0gWFNMIGVsZW1lbnQgd2hlcmUgdGhlIGV4cHJlc3Npb24gb2NjdXJlZAotICAgICAqICBAcGFyYW0gYXR0ciAgIC0gbmFtZSBvZiB0aGlzIGVsZW1lbnQncyBhdHRyaWJ1dGUgdG8gZ2V0IGV4cHJlc3Npb24gZnJvbQotICAgICAqICBAcGFyYW0gZGVmICAgIC0gZGVmYXVsdCBleHByZXNzaW9uIChpZiB0aGUgYXR0cmlidXRlIHdhcyBub3QgZm91bmQpCi0gICAgICovCi0gICAgcHVibGljIEV4cHJlc3Npb24gcGFyc2VFeHByZXNzaW9uKFN5bnRheFRyZWVOb2RlIHBhcmVudCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGF0dHIsIFN0cmluZyBkZWYpIHsKLSAgICAgICAgLy8gR2V0IHRoZSB0ZXh0dWFsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBleHByZXNzaW9uIChpZiBhbnkpCi0gICAgICAgIFN0cmluZyBleHAgPSBwYXJlbnQuZ2V0QXR0cmlidXRlKGF0dHIpOwotICAgICAgICAvLyBVc2UgdGhlIGRlZmF1bHQgZXhwcmVzc2lvbiBpZiBub25lIHdhcyBmb3VuZAotICAgICAgICBpZiAoKGV4cC5sZW5ndGgoKSA9PSAwKSAmJiAoZGVmICE9IG51bGwpKSBleHAgPSBkZWY7Ci0gICAgICAgIC8vIEludm9rZSB0aGUgWFBhdGggcGFyc2VyCi0gICAgICAgIHJldHVybiAoRXhwcmVzc2lvbilwYXJzZVRvcExldmVsKHBhcmVudCwgIjxFWFBSRVNTSU9OPiIrZXhwLCBleHApOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFBhcnNlIGFuIFhQYXRoIHBhdHRlcm46Ci0gICAgICogIEBwYXJhbSBwYXJlbnQgIC0gWFNMIGVsZW1lbnQgd2hlcmUgdGhlIHBhdHRlcm4gb2NjdXJlZAotICAgICAqICBAcGFyYW0gcGF0dGVybiAtIHRleHR1YWwgcmVwcmVzZW50YXRpb24gb2YgdGhlIHBhdHRlcm4KLSAgICAgKi8KLSAgICBwdWJsaWMgUGF0dGVybiBwYXJzZVBhdHRlcm4oU3ludGF4VHJlZU5vZGUgcGFyZW50LCBTdHJpbmcgcGF0dGVybikgewotICAgICAgICByZXR1cm4gKFBhdHRlcm4pcGFyc2VUb3BMZXZlbChwYXJlbnQsICI8UEFUVEVSTj4iK3BhdHRlcm4sIHBhdHRlcm4pOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFBhcnNlIGFuIFhQYXRoIHBhdHRlcm46Ci0gICAgICogIEBwYXJhbSBwYXJlbnQgLSBYU0wgZWxlbWVudCB3aGVyZSB0aGUgcGF0dGVybiBvY2N1cmVkCi0gICAgICogIEBwYXJhbSBhdHRyICAgLSBuYW1lIG9mIHRoaXMgZWxlbWVudCdzIGF0dHJpYnV0ZSB0byBnZXQgcGF0dGVybiBmcm9tCi0gICAgICogIEBwYXJhbSBkZWYgICAgLSBkZWZhdWx0IHBhdHRlcm4gKGlmIHRoZSBhdHRyaWJ1dGUgd2FzIG5vdCBmb3VuZCkKLSAgICAgKi8KLSAgICBwdWJsaWMgUGF0dGVybiBwYXJzZVBhdHRlcm4oU3ludGF4VHJlZU5vZGUgcGFyZW50LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgYXR0ciwgU3RyaW5nIGRlZikgewotICAgICAgICAvLyBHZXQgdGhlIHRleHR1YWwgcmVwcmVzZW50YXRpb24gb2YgdGhlIHBhdHRlcm4gKGlmIGFueSkKLSAgICAgICAgU3RyaW5nIHBhdHRlcm4gPSBwYXJlbnQuZ2V0QXR0cmlidXRlKGF0dHIpOwotICAgICAgICAvLyBVc2UgdGhlIGRlZmF1bHQgcGF0dGVybiBpZiBub25lIHdhcyBmb3VuZAotICAgICAgICBpZiAoKHBhdHRlcm4ubGVuZ3RoKCkgPT0gMCkgJiYgKGRlZiAhPSBudWxsKSkgcGF0dGVybiA9IGRlZjsKLSAgICAgICAgLy8gSW52b2tlIHRoZSBYUGF0aCBwYXJzZXIKLSAgICAgICAgcmV0dXJuIChQYXR0ZXJuKXBhcnNlVG9wTGV2ZWwocGFyZW50LCAiPFBBVFRFUk4+IitwYXR0ZXJuLCBwYXR0ZXJuKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBQYXJzZSBhbiBYUGF0aCBleHByZXNzaW9uIG9yIHBhdHRlcm4gdXNpbmcgdGhlIGdlbmVyYXRlZCBYUGF0aFBhcnNlcgotICAgICAqIFRoZSBtZXRob2Qgd2lsbCByZXR1cm4gYSBEdW1teSBub2RlIGlmIHRoZSBYUGF0aCBwYXJzZXIgZmFpbHMuCi0gICAgICovCi0gICAgcHJpdmF0ZSBTeW50YXhUcmVlTm9kZSBwYXJzZVRvcExldmVsKFN5bnRheFRyZWVOb2RlIHBhcmVudCwgU3RyaW5nIHRleHQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBleHByZXNzaW9uKSB7Ci0gICAgICAgIGludCBsaW5lID0gZ2V0TGluZU51bWJlcigpOwotCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBfeHBhdGhQYXJzZXIuc2V0U2Nhbm5lcihuZXcgWFBhdGhMZXhlcihuZXcgU3RyaW5nUmVhZGVyKHRleHQpKSk7Ci0gICAgICAgICAgICBTeW1ib2wgcmVzdWx0ID0gX3hwYXRoUGFyc2VyLnBhcnNlKGV4cHJlc3Npb24sIGxpbmUpOwotICAgICAgICAgICAgaWYgKHJlc3VsdCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZmluYWwgU3ludGF4VHJlZU5vZGUgbm9kZSA9IChTeW50YXhUcmVlTm9kZSlyZXN1bHQudmFsdWU7Ci0gICAgICAgICAgICAgICAgaWYgKG5vZGUgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBub2RlLnNldFBhcnNlcih0aGlzKTsKLSAgICAgICAgICAgICAgICAgICAgbm9kZS5zZXRQYXJlbnQocGFyZW50KTsKLSAgICAgICAgICAgICAgICAgICAgbm9kZS5zZXRMaW5lTnVtYmVyKGxpbmUpOwotICAgICAgICAgICAgICAgICAgICByZXR1cm4gbm9kZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXBvcnRFcnJvcihFUlJPUiwgbmV3IEVycm9yTXNnKEVycm9yTXNnLlhQQVRIX1BBUlNFUl9FUlIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cHJlc3Npb24sIHBhcmVudCkpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgaWYgKF94c2x0Yy5kZWJ1ZygpKSBlLnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgICAgICAgcmVwb3J0RXJyb3IoRVJST1IsIG5ldyBFcnJvck1zZyhFcnJvck1zZy5YUEFUSF9QQVJTRVJfRVJSLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHByZXNzaW9uLCBwYXJlbnQpKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIFJldHVybiBhIGR1bW15IHBhdHRlcm4gKHdoaWNoIGlzIGFuIGV4cHJlc3Npb24pCi0gICAgICAgIFN5bnRheFRyZWVOb2RlLkR1bW15LnNldFBhcnNlcih0aGlzKTsKLSAgICAgICAgcmV0dXJuIFN5bnRheFRyZWVOb2RlLkR1bW15OwotICAgIH0KLQotICAgIC8qKioqKioqKioqKioqKioqKioqKioqKiogRVJST1IgSEFORExJTkcgU0VDVElPTiAqKioqKioqKioqKioqKioqKioqKioqKiovCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlcmUgd2VyZSBhbnkgZXJyb3JzIGR1cmluZyBjb21waWxhdGlvbgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGVycm9yc0ZvdW5kKCkgewotICAgICAgICByZXR1cm4gX2Vycm9ycy5zaXplKCkgPiAwOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFByaW50cyBhbGwgY29tcGlsZS10aW1lIGVycm9ycwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHByaW50RXJyb3JzKCkgewotICAgICAgICBmaW5hbCBpbnQgc2l6ZSA9IF9lcnJvcnMuc2l6ZSgpOwotICAgICAgICBpZiAoc2l6ZSA+IDApIHsKLSAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbihuZXcgRXJyb3JNc2coRXJyb3JNc2cuQ09NUElMRVJfRVJST1JfS0VZKSk7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewotICAgICAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiICAiICsgX2Vycm9ycy5nZXQoaSkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUHJpbnRzIGFsbCBjb21waWxlLXRpbWUgd2FybmluZ3MKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBwcmludFdhcm5pbmdzKCkgewotICAgICAgICBmaW5hbCBpbnQgc2l6ZSA9IF93YXJuaW5ncy5zaXplKCk7Ci0gICAgICAgIGlmIChzaXplID4gMCkgewotICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKG5ldyBFcnJvck1zZyhFcnJvck1zZy5DT01QSUxFUl9XQVJOSU5HX0tFWSkpOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKLSAgICAgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIiAgIiArIF93YXJuaW5ncy5nZXQoaSkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29tbW9uIGVycm9yL3dhcm5pbmcgbWVzc2FnZSBoYW5kbGVyCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcmVwb3J0RXJyb3IoZmluYWwgaW50IGNhdGVnb3J5LCBmaW5hbCBFcnJvck1zZyBlcnJvcikgewotICAgICAgICBzd2l0Y2ggKGNhdGVnb3J5KSB7Ci0gICAgICAgIGNhc2UgQ29uc3RhbnRzLklOVEVSTkFMOgotICAgICAgICAgICAgLy8gVW5leHBlY3RlZCBpbnRlcm5hbCBlcnJvcnMsIHN1Y2ggYXMgbnVsbC1wdHIgZXhjZXB0aW9ucywgZXRjLgotICAgICAgICAgICAgLy8gSW1tZWRpYXRlbHkgdGVybWluYXRlcyBjb21waWxhdGlvbiwgbm8gdHJhbnNsZXQgcHJvZHVjZWQKLSAgICAgICAgICAgIF9lcnJvcnMuYWRkKGVycm9yKTsKLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICBjYXNlIENvbnN0YW50cy5VTlNVUFBPUlRFRDoKLSAgICAgICAgICAgIC8vIFhTTFQgZWxlbWVudHMgdGhhdCBhcmUgbm90IGltcGxlbWVudGVkIGFuZCB1bnN1cHBvcnRlZCBleHQuCi0gICAgICAgICAgICAvLyBJbW1lZGlhdGVseSB0ZXJtaW5hdGVzIGNvbXBpbGF0aW9uLCBubyB0cmFuc2xldCBwcm9kdWNlZAotICAgICAgICAgICAgX2Vycm9ycy5hZGQoZXJyb3IpOwotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgQ29uc3RhbnRzLkZBVEFMOgotICAgICAgICAgICAgLy8gRmF0YWwgZXJyb3IgaW4gdGhlIHN0eWxlc2hlZXQgaW5wdXQgKHBhcnNpbmcgb3IgY29udGVudCkKLSAgICAgICAgICAgIC8vIEltbWVkaWF0ZWx5IHRlcm1pbmF0ZXMgY29tcGlsYXRpb24sIG5vIHRyYW5zbGV0IHByb2R1Y2VkCi0gICAgICAgICAgICBfZXJyb3JzLmFkZChlcnJvcik7Ci0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBDb25zdGFudHMuRVJST1I6Ci0gICAgICAgICAgICAvLyBPdGhlciBlcnJvciBpbiB0aGUgc3R5bGVzaGVldCBpbnB1dCAocGFyc2luZyBvciBjb250ZW50KQotICAgICAgICAgICAgLy8gRG9lcyBub3QgdGVybWluYXRlIGNvbXBpbGF0aW9uLCBubyB0cmFuc2xldCBwcm9kdWNlZAotICAgICAgICAgICAgX2Vycm9ycy5hZGQoZXJyb3IpOwotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgQ29uc3RhbnRzLldBUk5JTkc6Ci0gICAgICAgICAgICAvLyBPdGhlciBlcnJvciBpbiB0aGUgc3R5bGVzaGVldCBpbnB1dCAoY29udGVudCBlcnJvcnMgb25seSkKLSAgICAgICAgICAgIC8vIERvZXMgbm90IHRlcm1pbmF0ZSBjb21waWxhdGlvbiwgYSB0cmFuc2xldCBpcyBwcm9kdWNlZAotICAgICAgICAgICAgX3dhcm5pbmdzLmFkZChlcnJvcik7Ci0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyBBcnJheUxpc3Q8RXJyb3JNc2c+IGdldEVycm9ycygpIHsKLSAgICAgICAgcmV0dXJuIF9lcnJvcnM7Ci0gICAgfQotCi0gICAgcHVibGljIEFycmF5TGlzdDxFcnJvck1zZz4gZ2V0V2FybmluZ3MoKSB7Ci0gICAgICAgIHJldHVybiBfd2FybmluZ3M7Ci0gICAgfQotCi0gICAgLyoqKioqKioqKioqKioqKioqKioqKioqKiBTQVgyIENvbnRlbnRIYW5kbGVyIElOVEVSRkFDRSAqKioqKioqKioqKioqKioqKi8KLQotICAgIHByaXZhdGUgU3RhY2s8U3ludGF4VHJlZU5vZGU+IF9wYXJlbnRTdGFjayA9IG51bGw7Ci0gICAgcHJpdmF0ZSBNYXA8U3RyaW5nLCBTdHJpbmc+IF9wcmVmaXhNYXBwaW5nID0gbnVsbDsKLQotICAgIC8qKgotICAgICAqIFNBWDI6IFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIHRoZSBiZWdpbm5pbmcgb2YgYSBkb2N1bWVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydERvY3VtZW50KCkgewotICAgICAgICBfcm9vdCA9IG51bGw7Ci0gICAgICAgIF90YXJnZXQgPSBudWxsOwotICAgICAgICBfcHJlZml4TWFwcGluZyA9IG51bGw7Ci0gICAgICAgIF9wYXJlbnRTdGFjayA9IG5ldyBTdGFjazw+KCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU0FYMjogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIGVuZCBvZiBhIGRvY3VtZW50LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZERvY3VtZW50KCkgeyB9Ci0KLQotICAgIC8qKgotICAgICAqIFNBWDI6IEJlZ2luIHRoZSBzY29wZSBvZiBhIHByZWZpeC1VUkkgTmFtZXNwYWNlIG1hcHBpbmcuCi0gICAgICogICAgICAgVGhpcyBoYXMgdG8gYmUgcGFzc2VkIG9uIHRvIHRoZSBzeW1ib2wgdGFibGUhCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnRQcmVmaXhNYXBwaW5nKFN0cmluZyBwcmVmaXgsIFN0cmluZyB1cmkpIHsKLSAgICAgICAgaWYgKF9wcmVmaXhNYXBwaW5nID09IG51bGwpIHsKLSAgICAgICAgICAgIF9wcmVmaXhNYXBwaW5nID0gbmV3IEhhc2hNYXA8PigpOwotICAgICAgICB9Ci0gICAgICAgIF9wcmVmaXhNYXBwaW5nLnB1dChwcmVmaXgsIHVyaSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU0FYMjogRW5kIHRoZSBzY29wZSBvZiBhIHByZWZpeC1VUkkgTmFtZXNwYWNlIG1hcHBpbmcuCi0gICAgICogICAgICAgVGhpcyBoYXMgdG8gYmUgcGFzc2VkIG9uIHRvIHRoZSBzeW1ib2wgdGFibGUhCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kUHJlZml4TWFwcGluZyhTdHJpbmcgcHJlZml4KSB7IH0KLQotICAgIC8qKgotICAgICAqIFNBWDI6IFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIHRoZSBiZWdpbm5pbmcgb2YgYW4gZWxlbWVudC4KLSAgICAgKiAgICAgICBUaGUgcGFyc2VyIG1heSByZS11c2UgdGhlIGF0dHJpYnV0ZSBsaXN0IHRoYXQgd2UncmUgcGFzc2VkIHNvCi0gICAgICogICAgICAgd2UgY2xvbmUgdGhlIGF0dHJpYnV0ZXMgaW4gb3VyIG93biBBdHRyaWJ1dGVzIGltcGxlbWVudGF0aW9uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnRFbGVtZW50KFN0cmluZyB1cmksIFN0cmluZyBsb2NhbG5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBxbmFtZSwgQXR0cmlidXRlcyBhdHRyaWJ1dGVzKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICAgICAgZmluYWwgaW50IGNvbCA9IHFuYW1lLmxhc3RJbmRleE9mKCc6Jyk7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBwcmVmaXggPSAoY29sID09IC0xKSA/IG51bGwgOiBxbmFtZS5zdWJzdHJpbmcoMCwgY29sKTsKLQotICAgICAgICBTeW50YXhUcmVlTm9kZSBlbGVtZW50ID0gbWFrZUluc3RhbmNlKHVyaSwgcHJlZml4LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2FsbmFtZSwgYXR0cmlidXRlcyk7Ci0gICAgICAgIGlmIChlbGVtZW50ID09IG51bGwpIHsKLSAgICAgICAgICAgIEVycm9yTXNnIGVyciA9IG5ldyBFcnJvck1zZyhFcnJvck1zZy5FTEVNRU5UX1BBUlNFX0VSUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmVmaXgrJzonK2xvY2FsbmFtZSk7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKGVyci50b1N0cmluZygpKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIElmIHRoaXMgaXMgdGhlIHJvb3QgZWxlbWVudCBvZiB0aGUgWE1MIGRvY3VtZW50IHdlIG5lZWQgdG8gbWFrZSBzdXJlCi0gICAgICAgIC8vIHRoYXQgaXQgY29udGFpbnMgYSBkZWZpbml0aW9uIG9mIHRoZSBYU0wgbmFtZXNwYWNlIFVSSQotICAgICAgICBpZiAoX3Jvb3QgPT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKChfcHJlZml4TWFwcGluZyA9PSBudWxsKSB8fAotICAgICAgICAgICAgICAgIChfcHJlZml4TWFwcGluZy5jb250YWluc1ZhbHVlKENvbnN0YW50cy5YU0xUX1VSSSkgPT0gZmFsc2UpKQotICAgICAgICAgICAgICAgIF9yb290TmFtZXNwYWNlRGVmID0gZmFsc2U7Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgX3Jvb3ROYW1lc3BhY2VEZWYgPSB0cnVlOwotICAgICAgICAgICAgX3Jvb3QgPSBlbGVtZW50OwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgU3ludGF4VHJlZU5vZGUgcGFyZW50ID0gX3BhcmVudFN0YWNrLnBlZWsoKTsKLSAgICAgICAgICAgIHBhcmVudC5hZGRFbGVtZW50KGVsZW1lbnQpOwotICAgICAgICAgICAgZWxlbWVudC5zZXRQYXJlbnQocGFyZW50KTsKLSAgICAgICAgfQotICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZXMobmV3IEF0dHJpYnV0ZXNJbXBsKGF0dHJpYnV0ZXMpKTsKLSAgICAgICAgZWxlbWVudC5zZXRQcmVmaXhNYXBwaW5nKF9wcmVmaXhNYXBwaW5nKTsKLQotICAgICAgICBpZiAoZWxlbWVudCBpbnN0YW5jZW9mIFN0eWxlc2hlZXQpIHsKLSAgICAgICAgICAgIC8vIEV4dGVuc2lvbiBlbGVtZW50cyBhbmQgZXhjbHVkZWQgZWxlbWVudHMgaGF2ZSB0byBiZQotICAgICAgICAgICAgLy8gaGFuZGxlZCBhdCB0aGlzIHBvaW50IGluIG9yZGVyIHRvIGNvcnJlY3RseSBnZW5lcmF0ZQotICAgICAgICAgICAgLy8gRmFsbGJhY2sgZWxlbWVudHMgZnJvbSA8eHNsOmZhbGxiYWNrPnMuCi0gICAgICAgICAgICBnZXRTeW1ib2xUYWJsZSgpLnNldEN1cnJlbnROb2RlKGVsZW1lbnQpOwotICAgICAgICAgICAgKChTdHlsZXNoZWV0KWVsZW1lbnQpLmRlY2xhcmVFeHRlbnNpb25QcmVmaXhlcyh0aGlzKTsKLSAgICAgICAgfQotCi0gICAgICAgIF9wcmVmaXhNYXBwaW5nID0gbnVsbDsKLSAgICAgICAgX3BhcmVudFN0YWNrLnB1c2goZWxlbWVudCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU0FYMjogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIGVuZCBvZiBhbiBlbGVtZW50LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZEVsZW1lbnQoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsbmFtZSwgU3RyaW5nIHFuYW1lKSB7Ci0gICAgICAgIF9wYXJlbnRTdGFjay5wb3AoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTQVgyOiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBjaGFyYWN0ZXIgZGF0YS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBjaGFyYWN0ZXJzKGNoYXJbXSBjaCwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKSB7Ci0gICAgICAgIFN0cmluZyBzdHJpbmcgPSBuZXcgU3RyaW5nKGNoLCBzdGFydCwgbGVuZ3RoKTsKLSAgICAgICAgU3ludGF4VHJlZU5vZGUgcGFyZW50ID0gX3BhcmVudFN0YWNrLnBlZWsoKTsKLQotICAgICAgICBpZiAoc3RyaW5nLmxlbmd0aCgpID09IDApIHJldHVybjsKLQotICAgICAgICAvLyBJZiB0aGlzIHRleHQgb2NjdXJzIHdpdGhpbiBhbiA8eHNsOnRleHQ+IGVsZW1lbnQgd2UgYXBwZW5kIGl0Ci0gICAgICAgIC8vIGFzLWlzIHRvIHRoZSBleGlzdGluZyB0ZXh0IGVsZW1lbnQKLSAgICAgICAgaWYgKHBhcmVudCBpbnN0YW5jZW9mIFRleHQpIHsKLSAgICAgICAgICAgICgoVGV4dClwYXJlbnQpLnNldFRleHQoc3RyaW5nKTsKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIElnbm9yZSB0ZXh0IG5vZGVzIHRoYXQgb2NjdXIgZGlyZWN0bHkgdW5kZXIgPHhzbDpzdHlsZXNoZWV0PgotICAgICAgICBpZiAocGFyZW50IGluc3RhbmNlb2YgU3R5bGVzaGVldCkgcmV0dXJuOwotCi0gICAgICAgIFN5bnRheFRyZWVOb2RlIGJybyA9IHBhcmVudC5sYXN0Q2hpbGQoKTsKLSAgICAgICAgaWYgKChicm8gIT0gbnVsbCkgJiYgKGJybyBpbnN0YW5jZW9mIFRleHQpKSB7Ci0gICAgICAgICAgICBUZXh0IHRleHQgPSAoVGV4dClicm87Ci0gICAgICAgICAgICBpZiAoIXRleHQuaXNUZXh0RWxlbWVudCgpKSB7Ci0gICAgICAgICAgICAgICAgaWYgKChsZW5ndGggPiAxKSB8fCAoICgoaW50KWNoWzBdKSA8IDB4MTAwKSkgewotICAgICAgICAgICAgICAgICAgICB0ZXh0LnNldFRleHQoc3RyaW5nKTsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIEFkZCBpdCBhcyBhIHJlZ3VsYXIgdGV4dCBub2RlIG90aGVyd2lzZQotICAgICAgICBwYXJlbnQuYWRkRWxlbWVudChuZXcgVGV4dChzdHJpbmcpKTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIFN0cmluZyBnZXRUb2tlblZhbHVlKFN0cmluZyB0b2tlbikgewotICAgICAgICBmaW5hbCBpbnQgc3RhcnQgPSB0b2tlbi5pbmRleE9mKCciJyk7Ci0gICAgICAgIGZpbmFsIGludCBzdG9wID0gdG9rZW4ubGFzdEluZGV4T2YoJyInKTsKLSAgICAgICAgcmV0dXJuIHRva2VuLnN1YnN0cmluZyhzdGFydCsxLCBzdG9wKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTQVgyOiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBhIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24uCi0gICAgICogICAgICAgVGhlc2UgcmVxdWlyZSBzcGVjaWFsIGhhbmRsaW5nIGZvciBzdHlsZXNoZWV0IFBJcy4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oU3RyaW5nIG5hbWUsIFN0cmluZyB2YWx1ZSkgewotICAgICAgICAvLyBXZSBvbmx5IGhhbmRsZSB0aGUgPD94bWwtc3R5bGVzaGVldCAuLi4/PiBQSQotICAgICAgICBpZiAoKF90YXJnZXQgPT0gbnVsbCkgJiYgKG5hbWUuZXF1YWxzKCJ4bWwtc3R5bGVzaGVldCIpKSkgewotCi0gICAgICAgICAgICBTdHJpbmcgaHJlZiA9IG51bGw7ICAgIC8vIFVSSSBvZiBzdHlsZXNoZWV0IGZvdW5kCi0gICAgICAgICAgICBTdHJpbmcgbWVkaWEgPSBudWxsOyAgIC8vIE1lZGlhIG9mIHN0eWxlc2hlZXQgZm91bmQKLSAgICAgICAgICAgIFN0cmluZyB0aXRsZSA9IG51bGw7ICAgLy8gVGl0bGUgb2Ygc3R5bGVzaGVldCBmb3VuZAotICAgICAgICAgICAgU3RyaW5nIGNoYXJzZXQgPSBudWxsOyAvLyBDaGFyc2V0IG9mIHN0eWxlc2hlZXQgZm91bmQKLQotICAgICAgICAgICAgLy8gR2V0IHRoZSBhdHRyaWJ1dGVzIGZyb20gdGhlIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24KLSAgICAgICAgICAgIFN0cmluZ1Rva2VuaXplciB0b2tlbnMgPSBuZXcgU3RyaW5nVG9rZW5pemVyKHZhbHVlKTsKLSAgICAgICAgICAgIHdoaWxlICh0b2tlbnMuaGFzTW9yZUVsZW1lbnRzKCkpIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgdG9rZW4gPSAoU3RyaW5nKXRva2Vucy5uZXh0RWxlbWVudCgpOwotICAgICAgICAgICAgICAgIGlmICh0b2tlbi5zdGFydHNXaXRoKCJocmVmIikpCi0gICAgICAgICAgICAgICAgICAgIGhyZWYgPSBnZXRUb2tlblZhbHVlKHRva2VuKTsKLSAgICAgICAgICAgICAgICBlbHNlIGlmICh0b2tlbi5zdGFydHNXaXRoKCJtZWRpYSIpKQotICAgICAgICAgICAgICAgICAgICBtZWRpYSA9IGdldFRva2VuVmFsdWUodG9rZW4pOwotICAgICAgICAgICAgICAgIGVsc2UgaWYgKHRva2VuLnN0YXJ0c1dpdGgoInRpdGxlIikpCi0gICAgICAgICAgICAgICAgICAgIHRpdGxlID0gZ2V0VG9rZW5WYWx1ZSh0b2tlbik7Ci0gICAgICAgICAgICAgICAgZWxzZSBpZiAodG9rZW4uc3RhcnRzV2l0aCgiY2hhcnNldCIpKQotICAgICAgICAgICAgICAgICAgICBjaGFyc2V0ID0gZ2V0VG9rZW5WYWx1ZSh0b2tlbik7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIFNldCB0aGUgdGFyZ2V0IHRvIHRoaXMgUEkncyBocmVmIGlmIHRoZSBwYXJhbWV0ZXJzIGFyZQotICAgICAgICAgICAgLy8gbnVsbCBvciBtYXRjaCB0aGUgY29ycmVzcG9uZGluZyBhdHRyaWJ1dGVzIG9mIHRoaXMgUEkuCi0gICAgICAgICAgICBpZiAoICgoX1BJbWVkaWEgPT0gbnVsbCkgfHwgKF9QSW1lZGlhLmVxdWFscyhtZWRpYSkpKSAmJgotICAgICAgICAgICAgICAgICAoKF9QSXRpdGxlID09IG51bGwpIHx8IChfUEltZWRpYS5lcXVhbHModGl0bGUpKSkgJiYKLSAgICAgICAgICAgICAgICAgKChfUEljaGFyc2V0ID09IG51bGwpIHx8IChfUEltZWRpYS5lcXVhbHMoY2hhcnNldCkpKSApIHsKLSAgICAgICAgICAgICAgICBfdGFyZ2V0ID0gaHJlZjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIElHTk9SRUQgLSBhbGwgaWdub3JhYmxlIHdoaXRlc3BhY2UgaXMgaWdub3JlZAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGlnbm9yYWJsZVdoaXRlc3BhY2UoY2hhcltdIGNoLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpIHsgfQotCi0gICAgLyoqCi0gICAgICogSUdOT1JFRCAtIHdlIGRvIG5vdCBoYXZlIHRvIGRvIGFueXRoaW5nIHdpdGggc2tpcHBlZCBlbnRpdGllcwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNraXBwZWRFbnRpdHkoU3RyaW5nIG5hbWUpIHsgfQotCi0gICAgLyoqCi0gICAgICogU3RvcmUgdGhlIGRvY3VtZW50IGxvY2F0b3IgdG8gbGF0ZXIgcmV0cmlldmUgbGluZSBudW1iZXJzIG9mIGFsbAotICAgICAqIGVsZW1lbnRzIGZyb20gdGhlIHN0eWxlc2hlZXQKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXREb2N1bWVudExvY2F0b3IoTG9jYXRvciBsb2NhdG9yKSB7Ci0gICAgICAgIF9sb2NhdG9yID0gbG9jYXRvcjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIGxpbmUgbnVtYmVyLCBvciB6ZXJvCi0gICAgICogaWYgdGhlcmUgaXMgbm8gX2xvY2F0b3IuCi0gICAgICovCi0gICAgcHJpdmF0ZSBpbnQgZ2V0TGluZU51bWJlcigpIHsKLSAgICAgICAgaW50IGxpbmUgPSAwOwotICAgICAgICBpZiAoX2xvY2F0b3IgIT0gbnVsbCkKLSAgICAgICAgICAgICAgICBsaW5lID0gX2xvY2F0b3IuZ2V0TGluZU51bWJlcigpOwotICAgICAgICByZXR1cm4gbGluZTsKLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvUGF0dGVybi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9QYXR0ZXJuLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDc5YjJlMGUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9QYXR0ZXJuLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw2MiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBQYXR0ZXJuLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTIgMTE6MDA6MzEgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuQ2xhc3NHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuTWV0aG9kR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZUNoZWNrRXJyb3I7Ci0KLS8qKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICovCi1wdWJsaWMgYWJzdHJhY3QgY2xhc3MgUGF0dGVybiBleHRlbmRzIEV4cHJlc3Npb24gewotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIHR5cGUgb2YgYSBwYXR0ZXJuLCB3aGljaCBpcyBhbHdheXMgYSA8Y29kZT5Ob2RlVHlwZTwvY29kZT4uCi0gICAgICogQSA8Y29kZT5Ob2RlVHlwZTwvY29kZT4gaGFzIGEgbnVtYmVyIG9mIHN1YnR5cGVzIGRlZmluZWQgYnkKLSAgICAgKiA8Y29kZT5Ob2RlVHlwZS5fdHlwZTwvY29kZT4gY29ycmVzcG9uZGluZyB0byBlYWNoIHR5cGUgb2Ygbm9kZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3QgVHlwZSB0eXBlQ2hlY2soU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3I7Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGUgdGhpcyBub2RlIGludG8gSlZNIGJ5dGVjb2Rlcy4gUGF0dGVybnMgYXJlIHRyYW5zbGF0ZWQgYXMKLSAgICAgKiBib29sZWFuIGV4cHJlc3Npb25zIHdpdGggdHJ1ZS9mYWxzZSBsaXN0cy4gQmVmb3JlIGNhbGxpbmcKLSAgICAgKiA8Y29kZT50cmFuc2xhdGU8L2NvZGU+IG9uIGEgcGF0dGVybiwgbWFrZSBzdXJlIHRoYXQgdGhlIG5vZGUgYmVpbmcKLSAgICAgKiBtYXRjaGVkIGlzIG9uIHRvcCBvZiB0aGUgc3RhY2suIEFmdGVyIGNhbGxpbmcgPGNvZGU+dHJhbnNsYXRlPC9jb2RlPiwKLSAgICAgKiBtYWtlIHN1cmUgdG8gYmFja3BhdGNoIGJvdGggdHJ1ZSBhbmQgZmFsc2UgbGlzdHMuIFRydWUgbGlzdHMgYXJlIHRoZQotICAgICAqIGRlZmF1bHQsIGluIHRoZSBzZW5zZSB0aGF0IHRoZXkgYWx3YXlzIDxlbT4iZmFsbCB0aHJvdWdoIjwvZW0+LiBJZiB0aGlzCi0gICAgICogaXMgbm90IHRoZSBpbnRlbmRlZCBzZW1hbnRpY3MgKGUuZy4sIHNlZQotICAgICAqIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIuQWx0ZXJuYXRpdmVQYXR0ZXJuI3RyYW5zbGF0ZX0pCi0gICAgICogdGhlbiBhIEdPVE8gbXVzdCBiZSBhcHBlbmRlZCB0byB0aGUgaW5zdHJ1Y3Rpb24gbGlzdCBhZnRlciBjYWxsaW5nCi0gICAgICogPGNvZGU+dHJhbnNsYXRlPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pOwotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgcHJpb3JpdHkgb2YgdGhpcyBwYXR0ZXJuIChzZWN0aW9uIDUuNSBpbiB0aGUgWFNMVCBzcGVjKS4KLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3QgZG91YmxlIGdldFByaW9yaXR5KCk7Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL1Bvc2l0aW9uQ2FsbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9Qb3NpdGlvbkNhbGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZjY1NmFlYy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL1Bvc2l0aW9uQ2FsbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNjkgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogUG9zaXRpb25DYWxsLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMDIgMTE6MTc6MTAgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5Db25zdGFudFBvb2xHZW47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JTE9BRDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklOVk9LRUlOVEVSRkFDRTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uTGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5DbGFzc0dlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5Db21wYXJlR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLk1ldGhvZEdlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UZXN0R2VuZXJhdG9yOwotCi0vKioKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICovCi1maW5hbCBjbGFzcyBQb3NpdGlvbkNhbGwgZXh0ZW5kcyBGdW5jdGlvbkNhbGwgewotCi0gICAgcHVibGljIFBvc2l0aW9uQ2FsbChRTmFtZSBmbmFtZSkgewotICAgICAgICBzdXBlcihmbmFtZSk7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gaGFzUG9zaXRpb25DYWxsKCkgewotICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCi0gICAgICAgIGlmIChtZXRob2RHZW4gaW5zdGFuY2VvZiBDb21wYXJlR2VuZXJhdG9yKSB7Ci0gICAgICAgICAgICBpbC5hcHBlbmQoKChDb21wYXJlR2VuZXJhdG9yKW1ldGhvZEdlbikubG9hZEN1cnJlbnROb2RlKCkpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKG1ldGhvZEdlbiBpbnN0YW5jZW9mIFRlc3RHZW5lcmF0b3IpIHsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSUxPQUQoUE9TSVRJT05fSU5ERVgpKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIGZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLSAgICAgICAgICAgIGZpbmFsIGludCBpbmRleCA9IGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoTk9ERV9JVEVSQVRPUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZ2V0UG9zaXRpb24iLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoKUkiKTsKLQotICAgICAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkSXRlcmF0b3IoKSk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRUlOVEVSRkFDRShpbmRleCwxKSk7Ci0gICAgICAgIH0KLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL1ByZWRpY2F0ZS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9QcmVkaWNhdGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNDMyN2YwZC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL1ByZWRpY2F0ZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNjE5ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFByZWRpY2F0ZS5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzEyIDExOjAyOjE4IHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5jbGFzc2ZpbGUuRmllbGQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5BU1RPUkU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5DSEVDS0NBU1Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5Db25zdGFudFBvb2xHZW47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5HRVRGSUVMRDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklOVk9LRVNQRUNJQUw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JbnN0cnVjdGlvbkxpc3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5Mb2NhbFZhcmlhYmxlR2VuOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuTkVXOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuUFVTSDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlBVVEZJRUxEOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkJvb2xlYW5UeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkNsYXNzR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkZpbHRlckdlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5JbnRUeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLk1ldGhvZEdlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5OdW1iZXJUeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlJlZmVyZW5jZVR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuUmVzdWx0VHJlZVR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVGVzdEdlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGVDaGVja0Vycm9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlV0aWw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnJ1bnRpbWUuT3BlcmF0b3JzOwotCi0vKioKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICovCi1maW5hbCBjbGFzcyBQcmVkaWNhdGUgZXh0ZW5kcyBFeHByZXNzaW9uIGltcGxlbWVudHMgQ2xvc3VyZSB7Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgcHJlZGljYXRlJ3MgZXhwcmVzc2lvbi4KLSAgICAgKi8KLSAgICBwcml2YXRlIEV4cHJlc3Npb24gX2V4cCA9IG51bGw7Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIGZsYWcgaW5kaWNhdGVzIGlmIG9wdGltaXphdGlvbnMgYXJlIHR1cm5lZCBvbi4gVGhlCi0gICAgICogbWV0aG9kIDxjb2RlPmRvbnRPcHRpbWl6ZSgpPC9jb2RlPiBjYW4gYmUgY2FsbGVkIHRvIHR1cm4KLSAgICAgKiBvcHRpbWl6YXRpb25zIG9mZi4KLSAgICAgKi8KLSAgICBwcml2YXRlIGJvb2xlYW4gX2Nhbk9wdGltaXplID0gdHJ1ZTsKLQotICAgIC8qKgotICAgICAqIEZsYWcgaW5kaWNhdGlnIGlmIHRoZSBudGggcG9zaXRpb24gb3B0aW1pemF0aW9uIGlzIG9uLiBJdAotICAgICAqIGlzIHNldCBpbiA8Y29kZT50eXBlQ2hlY2soKTwvY29kZT4uCi0gICAgICovCi0gICAgcHJpdmF0ZSBib29sZWFuIF9udGhQb3NpdGlvbkZpbHRlciA9IGZhbHNlOwotCi0gICAgLyoqCi0gICAgICogRmxhZyBpbmRpY2F0aWcgaWYgdGhlIG50aCBwb3NpdGlvbiBkZXNjZW5kYW50IGlzIG9uLiBJdAotICAgICAqIGlzIHNldCBpbiA8Y29kZT50eXBlQ2hlY2soKTwvY29kZT4uCi0gICAgICovCi0gICAgcHJpdmF0ZSBib29sZWFuIF9udGhEZXNjZW5kYW50ID0gZmFsc2U7Ci0KLSAgICAvKioKLSAgICAgKiBDYWNoZWQgbm9kZSB0eXBlIG9mIHRoZSBleHByZXNzaW9uIHRoYXQgb3ducyB0aGlzIHByZWRpY2F0ZS4KLSAgICAgKi8KLSAgICBpbnQgX3B0eXBlID0gLTE7Ci0KLSAgICAvKioKLSAgICAgKiBOYW1lIG9mIHRoZSBpbm5lciBjbGFzcy4KLSAgICAgKi8KLSAgICBwcml2YXRlIFN0cmluZyBfY2xhc3NOYW1lID0gbnVsbDsKLQotICAgIC8qKgotICAgICAqIExpc3Qgb2YgdmFyaWFibGVzIGluIGNsb3N1cmUuCi0gICAgICovCi0gICAgcHJpdmF0ZSBBcnJheUxpc3QgX2Nsb3N1cmVWYXJzID0gbnVsbDsKLQotICAgIC8qKgotICAgICAqIFJlZmVyZW5jZSB0byBwYXJlbnQgY2xvc3VyZS4KLSAgICAgKi8KLSAgICBwcml2YXRlIENsb3N1cmUgX3BhcmVudENsb3N1cmUgPSBudWxsOwotCi0gICAgLyoqCi0gICAgICogQ2FjaGVkIHZhbHVlIG9mIG1ldGhvZCA8Y29kZT5nZXRDb21wYXJlVmFsdWUoKTwvY29kZT4uCi0gICAgICovCi0gICAgcHJpdmF0ZSBFeHByZXNzaW9uIF92YWx1ZSA9IG51bGw7Ci0KLSAgICAvKioKLSAgICAgKiBDYWNoZWQgdmFsdWUgb2YgbWV0aG9kIDxjb2RlPmdldENvbXBhcmVWYWx1ZSgpPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwcml2YXRlIFN0ZXAgX3N0ZXAgPSBudWxsOwotCi0gICAgLyoqCi0gICAgICogSW5pdGlhbGl6ZXMgYSBwcmVkaWNhdGUuCi0gICAgICovCi0gICAgcHVibGljIFByZWRpY2F0ZShFeHByZXNzaW9uIGV4cCkgewotICAgICAgICBfZXhwID0gZXhwOwotICAgICAgICBfZXhwLnNldFBhcmVudCh0aGlzKTsKLQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldCB0aGUgcGFyc2VyIGZvciB0aGlzIGV4cHJlc3Npb24uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0UGFyc2VyKFBhcnNlciBwYXJzZXIpIHsKLSAgICAgICAgc3VwZXIuc2V0UGFyc2VyKHBhcnNlcik7Ci0gICAgICAgIF9leHAuc2V0UGFyc2VyKHBhcnNlcik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhIGJvb2xlYW4gdmFsdWUgaW5kaWNhdGluZyBpZiB0aGUgbnRoIHBvc2l0aW9uIG9wdGltaXphdGlvbgotICAgICAqIGlzIG9uLiBNdXN0IGJlIGNhbGwgYWZ0ZXIgdHlwZSBjaGVja2luZyEKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc050aFBvc2l0aW9uRmlsdGVyKCkgewotICAgICAgICByZXR1cm4gX250aFBvc2l0aW9uRmlsdGVyOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYSBib29sZWFuIHZhbHVlIGluZGljYXRpbmcgaWYgdGhlIG50aCBkZXNjZW5kYW50IG9wdGltaXphdGlvbgotICAgICAqIGlzIG9uLiBNdXN0IGJlIGNhbGwgYWZ0ZXIgdHlwZSBjaGVja2luZyEKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc050aERlc2NlbmRhbnQoKSB7Ci0gICAgICAgIHJldHVybiBfbnRoRGVzY2VuZGFudDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUdXJucyBvZmYgYWxsIG9wdGltaXphdGlvbnMgZm9yIHRoaXMgcHJlZGljYXRlLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGRvbnRPcHRpbWl6ZSgpIHsKLSAgICAgICAgX2Nhbk9wdGltaXplID0gZmFsc2U7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBleHByZXNzaW9uIGluIHRoaXMgcHJlZGljYXRlIGNvbnRhaW5zIGEgY2FsbAotICAgICAqIHRvIHBvc2l0aW9uKCkuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaGFzUG9zaXRpb25DYWxsKCkgewotICAgICAgICByZXR1cm4gX2V4cC5oYXNQb3NpdGlvbkNhbGwoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIGV4cHJlc3Npb24gaW4gdGhpcyBwcmVkaWNhdGUgY29udGFpbnMgYSBjYWxsCi0gICAgICogdG8gbGFzdCgpLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGhhc0xhc3RDYWxsKCkgewotICAgICAgICByZXR1cm4gX2V4cC5oYXNMYXN0Q2FsbCgpOwotICAgIH0KLQotICAgIC8vIC0tIEJlZ2luIENsb3N1cmUgaW50ZXJmYWNlIC0tLS0tLS0tLS0tLS0tLS0tLS0tCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhpcyBjbG9zdXJlIGlzIGNvbXBpbGVkIGluIGFuIGlubmVyIGNsYXNzIChpLmUuCi0gICAgICogaWYgdGhpcyBpcyBhIHJlYWwgY2xvc3VyZSkuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaW5Jbm5lckNsYXNzKCkgewotICAgICAgICByZXR1cm4gKF9jbGFzc05hbWUgIT0gbnVsbCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhIHJlZmVyZW5jZSB0byBpdHMgcGFyZW50IGNsb3N1cmUgb3IgbnVsbCBpZiBvdXRlcm1vc3QuCi0gICAgICovCi0gICAgcHVibGljIENsb3N1cmUgZ2V0UGFyZW50Q2xvc3VyZSgpIHsKLSAgICAgICAgaWYgKF9wYXJlbnRDbG9zdXJlID09IG51bGwpIHsKLSAgICAgICAgICAgIFN5bnRheFRyZWVOb2RlIG5vZGUgPSBnZXRQYXJlbnQoKTsKLSAgICAgICAgICAgIGRvIHsKLSAgICAgICAgICAgICAgICBpZiAobm9kZSBpbnN0YW5jZW9mIENsb3N1cmUpIHsKLSAgICAgICAgICAgICAgICAgICAgX3BhcmVudENsb3N1cmUgPSAoQ2xvc3VyZSkgbm9kZTsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGlmIChub2RlIGluc3RhbmNlb2YgVG9wTGV2ZWxFbGVtZW50KSB7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOyAgICAgIC8vIHdheSB1cCBpbiB0aGUgdHJlZQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBub2RlID0gbm9kZS5nZXRQYXJlbnQoKTsKLSAgICAgICAgICAgIH0gd2hpbGUgKG5vZGUgIT0gbnVsbCk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIF9wYXJlbnRDbG9zdXJlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhlIGF1eGlsaWFyeSBjbGFzcyBvciBudWxsIGlmIHRoaXMgcHJlZGljYXRlCi0gICAgICogaXMgY29tcGlsZWQgaW5zaWRlIHRoZSBUcmFuc2xldC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldElubmVyQ2xhc3NOYW1lKCkgewotICAgICAgICByZXR1cm4gX2NsYXNzTmFtZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBZGQgbmV3IHZhcmlhYmxlIHRvIHRoZSBjbG9zdXJlLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGFkZFZhcmlhYmxlKFZhcmlhYmxlUmVmQmFzZSB2YXJpYWJsZVJlZikgewotICAgICAgICBpZiAoX2Nsb3N1cmVWYXJzID09IG51bGwpIHsKLSAgICAgICAgICAgIF9jbG9zdXJlVmFycyA9IG5ldyBBcnJheUxpc3QoKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIE9ubHkgb25lIHJlZmVyZW5jZSBwZXIgdmFyaWFibGUKLSAgICAgICAgaWYgKCFfY2xvc3VyZVZhcnMuY29udGFpbnModmFyaWFibGVSZWYpKSB7Ci0gICAgICAgICAgICBfY2xvc3VyZVZhcnMuYWRkKHZhcmlhYmxlUmVmKTsKLQotICAgICAgICAgICAgLy8gQWRkIHZhcmlhYmxlIHRvIHBhcmVudCBjbG9zdXJlIGFzIHdlbGwKLSAgICAgICAgICAgIENsb3N1cmUgcGFyZW50Q2xvc3VyZSA9IGdldFBhcmVudENsb3N1cmUoKTsKLSAgICAgICAgICAgIGlmIChwYXJlbnRDbG9zdXJlICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBwYXJlbnRDbG9zdXJlLmFkZFZhcmlhYmxlKHZhcmlhYmxlUmVmKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIC8vIC0tIEVuZCBDbG9zdXJlIGludGVyZmFjZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBub2RlIHR5cGUgb2YgdGhlIGV4cHJlc3Npb24gb3duaW5nIHRoaXMgcHJlZGljYXRlLiBUaGUKLSAgICAgKiByZXR1cm4gdmFsdWUgaXMgY2FjaGVkIGluIDxjb2RlPl9wdHlwZTwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRQb3NUeXBlKCkgewotICAgICAgICBpZiAoX3B0eXBlID09IC0xKSB7Ci0gICAgICAgICAgICBTeW50YXhUcmVlTm9kZSBwYXJlbnQgPSBnZXRQYXJlbnQoKTsKLSAgICAgICAgICAgIGlmIChwYXJlbnQgaW5zdGFuY2VvZiBTdGVwUGF0dGVybikgewotICAgICAgICAgICAgICAgIF9wdHlwZSA9ICgoU3RlcFBhdHRlcm4pcGFyZW50KS5nZXROb2RlVHlwZSgpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAocGFyZW50IGluc3RhbmNlb2YgQWJzb2x1dGVMb2NhdGlvblBhdGgpIHsKLSAgICAgICAgICAgICAgICBBYnNvbHV0ZUxvY2F0aW9uUGF0aCBwYXRoID0gKEFic29sdXRlTG9jYXRpb25QYXRoKXBhcmVudDsKLSAgICAgICAgICAgICAgICBFeHByZXNzaW9uIGV4cCA9IHBhdGguZ2V0UGF0aCgpOwotICAgICAgICAgICAgICAgIGlmIChleHAgaW5zdGFuY2VvZiBTdGVwKSB7Ci0gICAgICAgICAgICAgICAgICAgIF9wdHlwZSA9ICgoU3RlcClleHApLmdldE5vZGVUeXBlKCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAocGFyZW50IGluc3RhbmNlb2YgVmFyaWFibGVSZWZCYXNlKSB7Ci0gICAgICAgICAgICAgICAgZmluYWwgVmFyaWFibGVSZWZCYXNlIHJlZiA9IChWYXJpYWJsZVJlZkJhc2UpcGFyZW50OwotICAgICAgICAgICAgICAgIGZpbmFsIFZhcmlhYmxlQmFzZSB2YXIgPSByZWYuZ2V0VmFyaWFibGUoKTsKLSAgICAgICAgICAgICAgICBmaW5hbCBFeHByZXNzaW9uIGV4cCA9IHZhci5nZXRFeHByZXNzaW9uKCk7Ci0gICAgICAgICAgICAgICAgaWYgKGV4cCBpbnN0YW5jZW9mIFN0ZXApIHsKLSAgICAgICAgICAgICAgICAgICAgX3B0eXBlID0gKChTdGVwKWV4cCkuZ2V0Tm9kZVR5cGUoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChwYXJlbnQgaW5zdGFuY2VvZiBTdGVwKSB7Ci0gICAgICAgICAgICAgICAgX3B0eXBlID0gKChTdGVwKXBhcmVudCkuZ2V0Tm9kZVR5cGUoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gX3B0eXBlOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIHBhcmVudElzUGF0dGVybigpIHsKLSAgICAgICAgcmV0dXJuIChnZXRQYXJlbnQoKSBpbnN0YW5jZW9mIFBhdHRlcm4pOwotICAgIH0KLQotICAgIHB1YmxpYyBFeHByZXNzaW9uIGdldEV4cHIoKSB7Ci0gICAgICAgIHJldHVybiBfZXhwOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0gICAgICAgIHJldHVybiAicHJlZCgiICsgX2V4cCArICcpJzsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUeXBlIGNoZWNrIGEgcHJlZGljYXRlIGV4cHJlc3Npb24uIElmIHRoZSB0eXBlIG9mIHRoZSBleHByZXNzaW9uIGlzCi0gICAgICogbnVtYmVyIGNvbnZlcnQgaXQgdG8gYm9vbGVhbiBieSBhZGRpbmcgYSBjb21wYXJpc29uIHdpdGggcG9zaXRpb24oKS4KLSAgICAgKiBOb3RlIHRoYXQgaWYgdGhlIGV4cHJlc3Npb24gaXMgYSBwYXJhbWV0ZXIsIHdlIGNhbm5vdCBkaXN0aW5ndWlzaAotICAgICAqIGF0IGNvbXBpbGUgdGltZSBpZiBpdHMgdHlwZSBpcyBudW1iZXIgb3Igbm90LiBIZW5jZSwgZXhwcmVzc2lvbnMgb2YKLSAgICAgKiByZWZlcmVuY2UgdHlwZSBhcmUgYWx3YXlzIGNvbnZlcnRlZCB0byBib29sZWFucy4KLSAgICAgKgotICAgICAqIFRoaXMgbWV0aG9kIG1heSBiZSBjYWxsZWQgdHdpY2UsIGJlZm9yZSBhbmQgYWZ0ZXIgY2FsbGluZwotICAgICAqIDxjb2RlPmRvbnRPcHRpbWl6ZSgpPC9jb2RlPi4gSWYgc28sIHRoZSBzZWNvbmQgdGltZSBpdCBzaG91bGQgaG9ub3IKLSAgICAgKiB0aGUgbmV3IHZhbHVlIG9mIDxjb2RlPl9jYW5PcHRpbWl6ZTwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLSAgICAgICAgVHlwZSB0ZXhwID0gX2V4cC50eXBlQ2hlY2soc3RhYmxlKTsKLQotICAgICAgICAvLyBXZSBuZWVkIGV4cGxpY2l0IHR5cGUgaW5mb3JtYXRpb24gZm9yIHJlZmVyZW5jZSB0eXBlcyAtIG5vIGdvb2QhCi0gICAgICAgIGlmICh0ZXhwIGluc3RhbmNlb2YgUmVmZXJlbmNlVHlwZSkgewotICAgICAgICAgICAgX2V4cCA9IG5ldyBDYXN0RXhwcihfZXhwLCB0ZXhwID0gVHlwZS5SZWFsKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIEEgcmVzdWx0IHRyZWUgZnJhZ21lbnQgc2hvdWxkIG5vdCBiZSBjYXN0IGRpcmVjdGx5IHRvIGEgbnVtYmVyIHR5cGUsCi0gICAgICAgIC8vIGJ1dCByYXRoZXIgdG8gYSBib29sZWFuIHZhbHVlLCBhbmQgdGhlbiB0byBhIG51bWVyICgwIG9yIDEpLgotICAgICAgICAvLyBSZWYuIHNlY3Rpb24gMTEuMiBvZiB0aGUgWFNMVCAxLjAgc3BlYwotICAgICAgICBpZiAodGV4cCBpbnN0YW5jZW9mIFJlc3VsdFRyZWVUeXBlKSB7Ci0gICAgICAgICAgICBfZXhwID0gbmV3IENhc3RFeHByKF9leHAsIFR5cGUuQm9vbGVhbik7Ci0gICAgICAgICAgICBfZXhwID0gbmV3IENhc3RFeHByKF9leHAsIFR5cGUuUmVhbCk7Ci0gICAgICAgICAgICB0ZXhwID0gX2V4cC50eXBlQ2hlY2soc3RhYmxlKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIE51bWVyaWNhbCB0eXBlcyB3aWxsIGJlIGNvbnZlcnRlZCB0byBhIHBvc2l0aW9uIGZpbHRlcgotICAgICAgICBpZiAodGV4cCBpbnN0YW5jZW9mIE51bWJlclR5cGUpIHsKLSAgICAgICAgICAgIC8vIENhc3QgYW55IG51bWVyaWNhbCB0eXBlcyB0byBhbiBpbnRlZ2VyCi0gICAgICAgICAgICBpZiAodGV4cCBpbnN0YW5jZW9mIEludFR5cGUgPT0gZmFsc2UpIHsKLSAgICAgICAgICAgICAgICBfZXhwID0gbmV3IENhc3RFeHByKF9leHAsIFR5cGUuSW50KTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKF9jYW5PcHRpbWl6ZSkgewotICAgICAgICAgICAgICAgIC8vIE50aCBwb3NpdGlvbiBvcHRpbWl6YXRpb24uIEV4cHJlc3Npb24gbXVzdCBub3QgZGVwZW5kIG9uIGNvbnRleHQKLSAgICAgICAgICAgICAgICBfbnRoUG9zaXRpb25GaWx0ZXIgPQotICAgICAgICAgICAgICAgICAgICAhX2V4cC5oYXNMYXN0Q2FsbCgpICYmICFfZXhwLmhhc1Bvc2l0aW9uQ2FsbCgpOwotCi0gICAgICAgICAgICAgICAgLy8gX250aERlc2NlbmRhbnQgb3B0aW1pemF0aW9uIC0gb25seSBpZiBfbnRoUG9zaXRpb25GaWx0ZXIgaXMgb24KLSAgICAgICAgICAgICAgICBpZiAoX250aFBvc2l0aW9uRmlsdGVyKSB7Ci0gICAgICAgICAgICAgICAgICAgIFN5bnRheFRyZWVOb2RlIHBhcmVudCA9IGdldFBhcmVudCgpOwotICAgICAgICAgICAgICAgICAgICBfbnRoRGVzY2VuZGFudCA9IChwYXJlbnQgaW5zdGFuY2VvZiBTdGVwKSAmJgotICAgICAgICAgICAgICAgICAgICAgICAgKHBhcmVudC5nZXRQYXJlbnQoKSBpbnN0YW5jZW9mIEFic29sdXRlTG9jYXRpb25QYXRoKTsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF90eXBlID0gVHlwZS5Ob2RlU2V0OwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAvLyBSZXNldCBvcHRpbWl6YXRpb24gZmxhZ3MKLSAgICAgICAgICAgIF9udGhQb3NpdGlvbkZpbHRlciA9IF9udGhEZXNjZW5kYW50ID0gZmFsc2U7Ci0KLSAgICAgICAgICAgLy8gT3RoZXJ3aXNlLCBleHBhbmQgW2VdIHRvIFtwb3NpdGlvbigpID0gZV0KLSAgICAgICAgICAgZmluYWwgUU5hbWUgcG9zaXRpb24gPQotICAgICAgICAgICAgICAgIGdldFBhcnNlcigpLmdldFFOYW1lSWdub3JlRGVmYXVsdE5zKCJwb3NpdGlvbiIpOwotICAgICAgICAgICBmaW5hbCBQb3NpdGlvbkNhbGwgcG9zaXRpb25DYWxsID0KLSAgICAgICAgICAgICAgICBuZXcgUG9zaXRpb25DYWxsKHBvc2l0aW9uKTsKLSAgICAgICAgICAgcG9zaXRpb25DYWxsLnNldFBhcnNlcihnZXRQYXJzZXIoKSk7Ci0gICAgICAgICAgIHBvc2l0aW9uQ2FsbC5zZXRQYXJlbnQodGhpcyk7Ci0KLSAgICAgICAgICAgX2V4cCA9IG5ldyBFcXVhbGl0eUV4cHIoT3BlcmF0b3JzLkVRLCBwb3NpdGlvbkNhbGwsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfZXhwKTsKLSAgICAgICAgICAgaWYgKF9leHAudHlwZUNoZWNrKHN0YWJsZSkgIT0gVHlwZS5Cb29sZWFuKSB7Ci0gICAgICAgICAgICAgICBfZXhwID0gbmV3IENhc3RFeHByKF9leHAsIFR5cGUuQm9vbGVhbik7Ci0gICAgICAgICAgIH0KLSAgICAgICAgICAgcmV0dXJuIF90eXBlID0gVHlwZS5Cb29sZWFuOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgLy8gQWxsIG90aGVyIHR5cGVzIHdpbGwgYmUgaGFuZGxlZCBhcyBib29sZWFuIHZhbHVlcwotICAgICAgICAgICAgaWYgKHRleHAgaW5zdGFuY2VvZiBCb29sZWFuVHlwZSA9PSBmYWxzZSkgewotICAgICAgICAgICAgICAgIF9leHAgPSBuZXcgQ2FzdEV4cHIoX2V4cCwgVHlwZS5Cb29sZWFuKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiBfdHlwZSA9IFR5cGUuQm9vbGVhbjsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIENyZWF0ZSBhIG5ldyAiRmlsdGVyIiBjbGFzcyBpbXBsZW1lbnRpbmcKLSAgICAgKiA8Y29kZT5DdXJyZW50Tm9kZUxpc3RGaWx0ZXI8L2NvZGU+LiBBbGxvY2F0ZSByZWdpc3RlcnMgZm9yIGxvY2FsCi0gICAgICogdmFyaWFibGVzIGFuZCBsb2NhbCBwYXJhbWV0ZXJzIHBhc3NlZCBpbiB0aGUgY2xvc3VyZSB0byB0ZXN0KCkuCi0gICAgICogTm90aWNlIHRoYXQgbG9jYWwgdmFyaWFibGVzIG5lZWQgdG8gYmUgInVuYm94ZWQiLgotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCBjb21waWxlRmlsdGVyKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLSAgICAgICAgVGVzdEdlbmVyYXRvciB0ZXN0R2VuOwotICAgICAgICBMb2NhbFZhcmlhYmxlR2VuIGxvY2FsOwotICAgICAgICBGaWx0ZXJHZW5lcmF0b3IgZmlsdGVyR2VuOwotCi0gICAgICAgIF9jbGFzc05hbWUgPSBnZXRYU0xUQygpLmdldEhlbHBlckNsYXNzTmFtZSgpOwotICAgICAgICBmaWx0ZXJHZW4gPSBuZXcgRmlsdGVyR2VuZXJhdG9yKF9jbGFzc05hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImphdmEubGFuZy5PYmplY3QiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvU3RyaW5nKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQUNDX1BVQkxJQyB8IEFDQ19TVVBFUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgU3RyaW5nW10gewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDVVJSRU5UX05PREVfTElTVF9GSUxURVIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzR2VuLmdldFN0eWxlc2hlZXQoKSk7Ci0KLSAgICAgICAgZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGZpbHRlckdlbi5nZXRDb25zdGFudFBvb2woKTsKLSAgICAgICAgZmluYWwgaW50IGxlbmd0aCA9IChfY2xvc3VyZVZhcnMgPT0gbnVsbCkgPyAwIDogX2Nsb3N1cmVWYXJzLnNpemUoKTsKLQotICAgICAgICAvLyBBZGQgYSBuZXcgaW5zdGFuY2UgdmFyaWFibGUgZm9yIGVhY2ggdmFyIGluIGNsb3N1cmUKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykgewotICAgICAgICAgICAgVmFyaWFibGVCYXNlIHZhciA9ICgoVmFyaWFibGVSZWZCYXNlKSBfY2xvc3VyZVZhcnMuZ2V0KGkpKS5nZXRWYXJpYWJsZSgpOwotCi0gICAgICAgICAgICBmaWx0ZXJHZW4uYWRkRmllbGQobmV3IEZpZWxkKEFDQ19QVUJMSUMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3BnLmFkZFV0ZjgodmFyLmdldEVzY2FwZWROYW1lKCkpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNwZy5hZGRVdGY4KHZhci5nZXRUeXBlKCkudG9TaWduYXR1cmUoKSksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwgY3BnLmdldENvbnN0YW50UG9vbCgpKSk7Ci0gICAgICAgIH0KLQotICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBuZXcgSW5zdHJ1Y3Rpb25MaXN0KCk7Ci0gICAgICAgIHRlc3RHZW4gPSBuZXcgVGVzdEdlbmVyYXRvcihBQ0NfUFVCTElDIHwgQUNDX0ZJTkFMLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5UeXBlLkJPT0xFQU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5UeXBlW10gewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuVHlwZS5JTlQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5UeXBlLklOVCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlR5cGUuSU5ULAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuVHlwZS5JTlQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVXRpbC5nZXRKQ1JlZlR5cGUoVFJBTlNMRVRfU0lHKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVdGlsLmdldEpDUmVmVHlwZShOT0RFX0lURVJBVE9SX1NJRykKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgU3RyaW5nW10gewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJub2RlIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAicG9zaXRpb24iLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJsYXN0IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiY3VycmVudCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRyYW5zbGV0IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiaXRlcmF0b3IiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRlc3QiLCBfY2xhc3NOYW1lLCBpbCwgY3BnKTsKLQotICAgICAgICAvLyBTdG9yZSB0aGUgZG9tIGluIGEgbG9jYWwgdmFyaWFibGUKLSAgICAgICAgbG9jYWwgPSB0ZXN0R2VuLmFkZExvY2FsVmFyaWFibGUoImRvY3VtZW50IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVXRpbC5nZXRKQ1JlZlR5cGUoRE9NX0lOVEZfU0lHKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwgbnVsbCk7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBjbGFzc05hbWUgPSBjbGFzc0dlbi5nZXRDbGFzc05hbWUoKTsKLSAgICAgICAgaWwuYXBwZW5kKGZpbHRlckdlbi5sb2FkVHJhbnNsZXQoKSk7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgQ0hFQ0tDQVNUKGNwZy5hZGRDbGFzcyhjbGFzc05hbWUpKSk7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgR0VURklFTEQoY3BnLmFkZEZpZWxkcmVmKGNsYXNzTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRE9NX0ZJRUxELCBET01fSU5URl9TSUcpKSk7Ci0gICAgICAgIGxvY2FsLnNldFN0YXJ0KGlsLmFwcGVuZChuZXcgQVNUT1JFKGxvY2FsLmdldEluZGV4KCkpKSk7Ci0KLSAgICAgICAgLy8gU3RvcmUgdGhlIGRvbSBpbmRleCBpbiB0aGUgdGVzdCBnZW5lcmF0b3IKLSAgICAgICAgdGVzdEdlbi5zZXREb21JbmRleChsb2NhbC5nZXRJbmRleCgpKTsKLQotICAgICAgICBfZXhwLnRyYW5zbGF0ZShmaWx0ZXJHZW4sIHRlc3RHZW4pOwotICAgICAgICBpbC5hcHBlbmQoSVJFVFVSTik7Ci0KLSAgICAgICAgZmlsdGVyR2VuLmFkZEVtcHR5Q29uc3RydWN0b3IoQUNDX1BVQkxJQyk7Ci0gICAgICAgIGZpbHRlckdlbi5hZGRNZXRob2QodGVzdEdlbik7Ci0KLSAgICAgICAgZ2V0WFNMVEMoKS5kdW1wQ2xhc3MoZmlsdGVyR2VuLmdldEphdmFDbGFzcygpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIHByZWRpY2F0ZSBpcyBhIHRlc3QgZm9yIHRoZSBleGlzdGFuY2Ugb2YgYW4KLSAgICAgKiBlbGVtZW50IG9yIGF0dHJpYnV0ZS4gQWxsIHdlIGhhdmUgdG8gZG8gaXMgdG8gZ2V0IHRoZSBmaXJzdCBub2RlCi0gICAgICogZnJvbSB0aGUgc3RlcCwgY2hlY2sgaWYgaXQgaXMgdGhlcmUsIGFuZCB0aGVuIHJldHVybiB0cnVlL2ZhbHNlLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzQm9vbGVhblRlc3QoKSB7Ci0gICAgICAgIHJldHVybiAoX2V4cCBpbnN0YW5jZW9mIEJvb2xlYW5FeHByKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBNZXRob2QgdG8gc2VlIGlmIHdlIGNhbiBvcHRpbWlzZSB0aGUgcHJlZGljYXRlIGJ5IHVzaW5nIGEgc3BlY2lhbGlzZWQKLSAgICAgKiBpdGVyYXRvciBmb3IgZXhwcmVzc2lvbnMgbGlrZSAnL2Zvby9iYXJbQGF0dHIgPSAkdmFyXScsIHdoaWNoIGFyZQotICAgICAqIHZlcnkgY29tbW9uIGluIG1hbnkgc3R5bGVzaGVldHMKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc05vZGVWYWx1ZVRlc3QoKSB7Ci0gICAgICAgIGlmICghX2Nhbk9wdGltaXplKSByZXR1cm4gZmFsc2U7Ci0gICAgICAgIHJldHVybiAoZ2V0U3RlcCgpICE9IG51bGwgJiYgZ2V0Q29tcGFyZVZhbHVlKCkgIT0gbnVsbCk7Ci0gICAgfQotCi0gICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBzdGVwIGluIGFuIGV4cHJlc3Npb24gb2YgdGhlIGZvcm0gJ3N0ZXAgPSB2YWx1ZScuCi0gICAgICogTnVsbCBpcyByZXR1cm5lZCBpZiB0aGUgZXhwcmVzc2lvbiBpcyBub3Qgb2YgdGhlIHJpZ2h0IGZvcm0uCi0gICAgICogT3B0aW1pemF0aW9uIGlmIG9mZiBpZiBudWxsIGlzIHJldHVybmVkLgotICAgICAqLwotICAgIHB1YmxpYyBTdGVwIGdldFN0ZXAoKSB7Ci0gICAgICAgIC8vIFJldHVybmVkIGNhY2hlZCB2YWx1ZSBpZiBjYWxsZWQgbW9yZSB0aGFuIG9uY2UKLSAgICAgICAgaWYgKF9zdGVwICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBfc3RlcDsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIE5vdGhpbmcgdG8gZG8gaWYgX2V4cCBpcyBudWxsCi0gICAgICAgIGlmIChfZXhwID09IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gSWdub3JlIGlmIG5vdCBlcXVhbGl0eSBleHByZXNzaW9uCi0gICAgICAgIGlmIChfZXhwIGluc3RhbmNlb2YgRXF1YWxpdHlFeHByKSB7Ci0gICAgICAgICAgICBFcXVhbGl0eUV4cHIgZXhwID0gKEVxdWFsaXR5RXhwcilfZXhwOwotICAgICAgICAgICAgRXhwcmVzc2lvbiBsZWZ0ID0gZXhwLmdldExlZnQoKTsKLSAgICAgICAgICAgIEV4cHJlc3Npb24gcmlnaHQgPSBleHAuZ2V0UmlnaHQoKTsKLQotICAgICAgICAgICAgLy8gVW53cmFwIGFuZCBzZXQgX3N0ZXAgaWYgYXBwcm9wcmlhdGUKLSAgICAgICAgICAgIGlmIChsZWZ0IGluc3RhbmNlb2YgQ2FzdEV4cHIpIHsKLSAgICAgICAgICAgICAgICBsZWZ0ID0gKChDYXN0RXhwcikgbGVmdCkuZ2V0RXhwcigpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKGxlZnQgaW5zdGFuY2VvZiBTdGVwKSB7Ci0gICAgICAgICAgICAgICAgX3N0ZXAgPSAoU3RlcCkgbGVmdDsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gVW53cmFwIGFuZCBzZXQgX3N0ZXAgaWYgYXBwcm9wcmlhdGUKLSAgICAgICAgICAgIGlmIChyaWdodCBpbnN0YW5jZW9mIENhc3RFeHByKSB7Ci0gICAgICAgICAgICAgICAgcmlnaHQgPSAoKENhc3RFeHByKXJpZ2h0KS5nZXRFeHByKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAocmlnaHQgaW5zdGFuY2VvZiBTdGVwKSB7Ci0gICAgICAgICAgICAgICAgX3N0ZXAgPSAoU3RlcClyaWdodDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gX3N0ZXA7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgdmFsdWUgaW4gYW4gZXhwcmVzc2lvbiBvZiB0aGUgZm9ybSAnc3RlcCA9IHZhbHVlJy4KLSAgICAgKiBBIHZhbHVlIG1heSBiZSBlaXRoZXIgYSBsaXRlcmFsIHN0cmluZyBvciBhIHZhcmlhYmxlIHdob3NlCi0gICAgICogdHlwZSBpcyBzdHJpbmcuIE9wdGltaXphdGlvbiBpZiBvZmYgaWYgbnVsbCBpcyByZXR1cm5lZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgRXhwcmVzc2lvbiBnZXRDb21wYXJlVmFsdWUoKSB7Ci0gICAgICAgIC8vIFJldHVybmVkIGNhY2hlZCB2YWx1ZSBpZiBjYWxsZWQgbW9yZSB0aGFuIG9uY2UKLSAgICAgICAgaWYgKF92YWx1ZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gX3ZhbHVlOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gTm90aGluZyB0byB0byBkbyBpZiBfZXhwIGlzIG51bGwKLSAgICAgICAgaWYgKF9leHAgPT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBJZ25vcmUgaWYgbm90IGFuIGVxdWFsaXR5IGV4cHJlc3Npb24KLSAgICAgICAgaWYgKF9leHAgaW5zdGFuY2VvZiBFcXVhbGl0eUV4cHIpIHsKLSAgICAgICAgICAgIEVxdWFsaXR5RXhwciBleHAgPSAoRXF1YWxpdHlFeHByKSBfZXhwOwotICAgICAgICAgICAgRXhwcmVzc2lvbiBsZWZ0ID0gZXhwLmdldExlZnQoKTsKLSAgICAgICAgICAgIEV4cHJlc3Npb24gcmlnaHQgPSBleHAuZ2V0UmlnaHQoKTsKLQotICAgICAgICAgICAgLy8gUmV0dXJuIGlmIGxlZnQgaXMgbGl0ZXJhbCBzdHJpbmcKLSAgICAgICAgICAgIGlmIChsZWZ0IGluc3RhbmNlb2YgTGl0ZXJhbEV4cHIpIHsKLSAgICAgICAgICAgICAgICBfdmFsdWUgPSBsZWZ0OwotICAgICAgICAgICAgICAgIHJldHVybiBfdmFsdWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyBSZXR1cm4gaWYgbGVmdCBpcyBhIHZhcmlhYmxlIHJlZmVyZW5jZSBvZiB0eXBlIHN0cmluZwotICAgICAgICAgICAgaWYgKGxlZnQgaW5zdGFuY2VvZiBWYXJpYWJsZVJlZkJhc2UgJiYKLSAgICAgICAgICAgICAgICBsZWZ0LmdldFR5cGUoKSA9PSBUeXBlLlN0cmluZykKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBfdmFsdWUgPSBsZWZ0OwotICAgICAgICAgICAgICAgIHJldHVybiBfdmFsdWU7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIFJldHVybiBpZiByaWdodCBpcyBsaXRlcmFsIHN0cmluZwotICAgICAgICAgICAgaWYgKHJpZ2h0IGluc3RhbmNlb2YgTGl0ZXJhbEV4cHIpIHsKLSAgICAgICAgICAgICAgICBfdmFsdWUgPSByaWdodDsKLSAgICAgICAgICAgICAgICByZXR1cm4gX3ZhbHVlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gUmV0dXJuIGlmIGxlZnQgaXMgYSB2YXJpYWJsZSByZWZlcmVuY2Ugd2hvc2UgdHlwZSBpcyBzdHJpbmcKLSAgICAgICAgICAgIGlmIChyaWdodCBpbnN0YW5jZW9mIFZhcmlhYmxlUmVmQmFzZSAmJgotICAgICAgICAgICAgICAgIHJpZ2h0LmdldFR5cGUoKSA9PSBUeXBlLlN0cmluZykKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBfdmFsdWUgPSByaWdodDsKLSAgICAgICAgICAgICAgICByZXR1cm4gX3ZhbHVlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZSBhIHByZWRpY2F0ZSBleHByZXNzaW9uLiBUaGlzIHRyYW5zbGF0aW9uIHB1c2hlcwotICAgICAqIHR3byByZWZlcmVuY2VzIG9uIHRoZSBzdGFjazogYSByZWZlcmVuY2UgdG8gYSBuZXdseSBjcmVhdGVkCi0gICAgICogZmlsdGVyIG9iamVjdCBhbmQgYSByZWZlcmVuY2UgdG8gdGhlIHByZWRpY2F0ZSdzIGNsb3N1cmUuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlRmlsdGVyKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKQotICAgIHsKLSAgICAgICAgZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0KLSAgICAgICAgLy8gQ29tcGlsZSBhdXhpbGlhcnkgY2xhc3MgZm9yIGZpbHRlcgotICAgICAgICBjb21waWxlRmlsdGVyKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCi0gICAgICAgIC8vIENyZWF0ZSBuZXcgaW5zdGFuY2Ugb2YgZmlsdGVyCi0gICAgICAgIGlsLmFwcGVuZChuZXcgTkVXKGNwZy5hZGRDbGFzcyhfY2xhc3NOYW1lKSkpOwotICAgICAgICBpbC5hcHBlbmQoRFVQKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VTUEVDSUFMKGNwZy5hZGRNZXRob2RyZWYoX2NsYXNzTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjxpbml0PiIsICIoKVYiKSkpOwotCi0gICAgICAgIC8vIEluaXRpYWxpemUgY2xvc3VyZSB2YXJpYWJsZXMKLSAgICAgICAgZmluYWwgaW50IGxlbmd0aCA9IChfY2xvc3VyZVZhcnMgPT0gbnVsbCkgPyAwIDogX2Nsb3N1cmVWYXJzLnNpemUoKTsKLQotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICBWYXJpYWJsZVJlZkJhc2UgdmFyUmVmID0gKFZhcmlhYmxlUmVmQmFzZSkgX2Nsb3N1cmVWYXJzLmdldChpKTsKLSAgICAgICAgICAgIFZhcmlhYmxlQmFzZSB2YXIgPSB2YXJSZWYuZ2V0VmFyaWFibGUoKTsKLSAgICAgICAgICAgIFR5cGUgdmFyVHlwZSA9IHZhci5nZXRUeXBlKCk7Ci0KLSAgICAgICAgICAgIGlsLmFwcGVuZChEVVApOwotCi0gICAgICAgICAgICAvLyBGaW5kIG5lYXJlc3QgY2xvc3VyZSBpbXBsZW1lbnRlZCBhcyBhbiBpbm5lciBjbGFzcwotICAgICAgICAgICAgQ2xvc3VyZSB2YXJpYWJsZUNsb3N1cmUgPSBfcGFyZW50Q2xvc3VyZTsKLSAgICAgICAgICAgIHdoaWxlICh2YXJpYWJsZUNsb3N1cmUgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGlmICh2YXJpYWJsZUNsb3N1cmUuaW5Jbm5lckNsYXNzKCkpIGJyZWFrOwotICAgICAgICAgICAgICAgIHZhcmlhYmxlQ2xvc3VyZSA9IHZhcmlhYmxlQ2xvc3VyZS5nZXRQYXJlbnRDbG9zdXJlKCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIFVzZSBnZXRmaWVsZCBpZiBpbiBhbiBpbm5lciBjbGFzcwotICAgICAgICAgICAgaWYgKHZhcmlhYmxlQ2xvc3VyZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKEFMT0FEXzApOwotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgR0VURklFTEQoCi0gICAgICAgICAgICAgICAgICAgIGNwZy5hZGRGaWVsZHJlZih2YXJpYWJsZUNsb3N1cmUuZ2V0SW5uZXJDbGFzc05hbWUoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgIHZhci5nZXRFc2NhcGVkTmFtZSgpLCB2YXJUeXBlLnRvU2lnbmF0dXJlKCkpKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAvLyBVc2UgYSBsb2FkIG9mIGluc3RydWN0aW9uIGlmIGluIHRyYW5zbGV0IGNsYXNzCi0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKHZhci5sb2FkSW5zdHJ1Y3Rpb24oKSk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIFN0b3JlIHZhcmlhYmxlIGluIG5ldyBjbG9zdXJlCi0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IFBVVEZJRUxEKAotICAgICAgICAgICAgICAgICAgICBjcGcuYWRkRmllbGRyZWYoX2NsYXNzTmFtZSwgdmFyLmdldEVzY2FwZWROYW1lKCksCi0gICAgICAgICAgICAgICAgICAgICAgICB2YXJUeXBlLnRvU2lnbmF0dXJlKCkpKSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGUgYSBwcmVkaWNhdGUgZXhwcmVzc2lvbi4gSWYgbm9uIG9mIHRoZSBvcHRpbWl6YXRpb25zIGFwcGx5Ci0gICAgICogdGhlbiB0aGlzIHRyYW5zbGF0aW9uIHB1c2hlcyB0d28gcmVmZXJlbmNlcyBvbiB0aGUgc3RhY2s6IGEgcmVmZXJlbmNlCi0gICAgICogdG8gYSBuZXdseSBjcmVhdGVkIGZpbHRlciBvYmplY3QgYW5kIGEgcmVmZXJlbmNlIHRvIHRoZSBwcmVkaWNhdGUncwotICAgICAqIGNsb3N1cmUuIFNlZSBjbGFzcyA8Y29kZT5TdGVwPC9jb2RlPiBmb3IgZnVydGhlciBkZXRhaWxzLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCi0gICAgICAgIGZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCi0gICAgICAgIGlmIChfbnRoUG9zaXRpb25GaWx0ZXIgfHwgX250aERlc2NlbmRhbnQpIHsKLSAgICAgICAgICAgIF9leHAudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKGlzTm9kZVZhbHVlVGVzdCgpICYmIChnZXRQYXJlbnQoKSBpbnN0YW5jZW9mIFN0ZXApKSB7Ci0gICAgICAgICAgICBfdmFsdWUudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBDSEVDS0NBU1QoY3BnLmFkZENsYXNzKFNUUklOR19DTEFTUykpKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsICgoRXF1YWxpdHlFeHByKV9leHApLmdldE9wKCkpKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHRyYW5zbGF0ZUZpbHRlcihjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgfQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvUHJvY2Vzc2luZ0luc3RydWN0aW9uLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL1Byb2Nlc3NpbmdJbnN0cnVjdGlvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1Mzk3MWM5Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvUHJvY2Vzc2luZ0luc3RydWN0aW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNDIgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogUHJvY2Vzc2luZ0luc3RydWN0aW9uLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTIgMTE6MDM6MDUgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5BTE9BRDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkFTVE9SRTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkNvbnN0YW50UG9vbEdlbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkdFVEZJRUxEOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFSU5URVJGQUNFOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFU1RBVElDOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFVklSVFVBTDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uTGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkxvY2FsVmFyaWFibGVHZW47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuQ2xhc3NHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuRXJyb3JNc2c7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuTWV0aG9kR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZUNoZWNrRXJyb3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVXRpbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLlhNTDExQ2hhcjsKLQotLyoqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKi8KLWZpbmFsIGNsYXNzIFByb2Nlc3NpbmdJbnN0cnVjdGlvbiBleHRlbmRzIEluc3RydWN0aW9uIHsKLQotICAgIHByaXZhdGUgQXR0cmlidXRlVmFsdWUgX25hbWU7IC8vIG5hbWUgdHJlYXRlZCBhcyBBVlQgKDcuMS4zKQotICAgIHByaXZhdGUgYm9vbGVhbiBfaXNMaXRlcmFsID0gZmFsc2U7ICAvLyBzcGVjaWZpZWQgbmFtZSBpcyBub3QgQVZUCi0KLSAgICBwdWJsaWMgdm9pZCBwYXJzZUNvbnRlbnRzKFBhcnNlciBwYXJzZXIpIHsKLSAgICAgICAgZmluYWwgU3RyaW5nIG5hbWUgID0gZ2V0QXR0cmlidXRlKCJuYW1lIik7Ci0KLSAgICAgICAgaWYgKG5hbWUubGVuZ3RoKCkgPiAwKSB7Ci0gICAgICAgICAgICBfaXNMaXRlcmFsID0gVXRpbC5pc0xpdGVyYWwobmFtZSk7Ci0gICAgICAgICAgICBpZiAoX2lzTGl0ZXJhbCkgewotICAgICAgICAgICAgICAgIGlmICghWE1MMTFDaGFyLmlzWE1MMTFWYWxpZE5DTmFtZShuYW1lKSkgewotICAgICAgICAgICAgICAgICAgICBFcnJvck1zZyBlcnIgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuSU5WQUxJRF9OQ05BTUVfRVJSLCBuYW1lLCB0aGlzKTsKLSAgICAgICAgICAgICAgICAgICAgcGFyc2VyLnJlcG9ydEVycm9yKENvbnN0YW50cy5FUlJPUiwgZXJyKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBfbmFtZSA9IEF0dHJpYnV0ZVZhbHVlLmNyZWF0ZSh0aGlzLCBuYW1lLCBwYXJzZXIpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICAgIHJlcG9ydEVycm9yKHRoaXMsIHBhcnNlciwgRXJyb3JNc2cuUkVRVUlSRURfQVRUUl9FUlIsICJuYW1lIik7Ci0KLSAgICAgICAgaWYgKG5hbWUuZXF1YWxzKCJ4bWwiKSkgewotICAgICAgICAgICAgcmVwb3J0RXJyb3IodGhpcywgcGFyc2VyLCBFcnJvck1zZy5JTExFR0FMX1BJX0VSUiwgInhtbCIpOwotICAgICAgICB9Ci0gICAgICAgIHBhcnNlQ2hpbGRyZW4ocGFyc2VyKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgVHlwZSB0eXBlQ2hlY2soU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgewotICAgICAgICBfbmFtZS50eXBlQ2hlY2soc3RhYmxlKTsKLSAgICAgICAgdHlwZUNoZWNrQ29udGVudHMoc3RhYmxlKTsKLSAgICAgICAgcmV0dXJuIFR5cGUuVm9pZDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLSAgICAgICAgZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0KLSAgICAgICAgaWYgKCFfaXNMaXRlcmFsKSB7Ci0gICAgICAgICAgICAvLyBpZiB0aGUgbmNuYW1lIGlzIGFuIEFWVCwgdGhlbiB0aGUgbmNuYW1lIGhhcyB0byBiZSBjaGVja2VkIGF0IHJ1bnRpbWUgaWYgaXQgaXMgYSB2YWxpZCBuY25hbWUKLSAgICAgICAgICAgIExvY2FsVmFyaWFibGVHZW4gbmFtZVZhbHVlID0KLSAgICAgICAgICAgICAgICAgICAgbWV0aG9kR2VuLmFkZExvY2FsVmFyaWFibGUyKCJuYW1lVmFsdWUiLAotICAgICAgICAgICAgVXRpbC5nZXRKQ1JlZlR5cGUoU1RSSU5HX1NJRyksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsKTsKLQotICAgICAgICAgICAgLy8gc3RvcmUgdGhlIG5hbWUgaW50byBhIHZhcmlhYmxlIGZpcnN0IHNvIF9uYW1lLnRyYW5zbGF0ZSBvbmx5IG5lZWRzIHRvIGJlIGNhbGxlZCBvbmNlCi0gICAgICAgICAgICBfbmFtZS50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgICAgICBuYW1lVmFsdWUuc2V0U3RhcnQoaWwuYXBwZW5kKG5ldyBBU1RPUkUobmFtZVZhbHVlLmdldEluZGV4KCkpKSk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IEFMT0FEKG5hbWVWYWx1ZS5nZXRJbmRleCgpKSk7Ci0KLSAgICAgICAgICAgIC8vIGNhbGwgY2hlY2tOQ05hbWUgaWYgdGhlIG5hbWUgaXMgYW4gQVZUCi0gICAgICAgICAgICBmaW5hbCBpbnQgY2hlY2sgPSBjcGcuYWRkTWV0aG9kcmVmKEJBU0lTX0xJQlJBUllfQ0xBU1MsICJjaGVja05DTmFtZSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArU1RSSU5HX1NJRwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIilWIik7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFU1RBVElDKGNoZWNrKSk7Ci0KLSAgICAgICAgICAgIC8vIFNhdmUgdGhlIGN1cnJlbnQgaGFuZGxlciBiYXNlIG9uIHRoZSBzdGFjawotICAgICAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkSGFuZGxlcigpKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChEVVApOyAgICAgLy8gZmlyc3QgYXJnIHRvICJhdHRyaWJ1dGVzIiBjYWxsCi0KLSAgICAgICAgICAgIC8vIGxvYWQgbmFtZSB2YWx1ZSBhZ2FpbgotICAgICAgICAgICAgbmFtZVZhbHVlLnNldEVuZChpbC5hcHBlbmQobmV3IEFMT0FEKG5hbWVWYWx1ZS5nZXRJbmRleCgpKSkpOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgLy8gU2F2ZSB0aGUgY3VycmVudCBoYW5kbGVyIGJhc2Ugb24gdGhlIHN0YWNrCi0gICAgICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRIYW5kbGVyKCkpOwotICAgICAgICAgICAgaWwuYXBwZW5kKERVUCk7ICAgICAvLyBmaXJzdCBhcmcgdG8gImF0dHJpYnV0ZXMiIGNhbGwKLQotICAgICAgICAgICAgLy8gUHVzaCBhdHRyaWJ1dGUgbmFtZQotICAgICAgICAgICAgX25hbWUudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOy8vIDJuZCBhcmcKLQotICAgICAgICB9Ci0KLSAgICAgICAgaWwuYXBwZW5kKGNsYXNzR2VuLmxvYWRUcmFuc2xldCgpKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBHRVRGSUVMRChjcGcuYWRkRmllbGRyZWYoVFJBTlNMRVRfQ0xBU1MsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJzdHJpbmdWYWx1ZUhhbmRsZXIiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTVFJJTkdfVkFMVUVfSEFORExFUl9TSUcpKSk7Ci0gICAgICAgIGlsLmFwcGVuZChEVVApOwotICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLnN0b3JlSGFuZGxlcigpKTsKLQotICAgICAgICAvLyB0cmFuc2xhdGUgY29udGVudHMgd2l0aCBzdWJzdGl0dXRlZCBoYW5kbGVyCi0gICAgICAgIHRyYW5zbGF0ZUNvbnRlbnRzKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCi0gICAgICAgIC8vIGdldCBTdHJpbmcgb3V0IG9mIHRoZSBoYW5kbGVyCi0gICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChjcGcuYWRkTWV0aG9kcmVmKFNUUklOR19WQUxVRV9IQU5ETEVSLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZ2V0VmFsdWVPZlBJIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIigpIiArIFNUUklOR19TSUcpKSk7Ci0gICAgICAgIC8vIGNhbGwgInByb2Nlc3NpbmdJbnN0cnVjdGlvbiIKLSAgICAgICAgZmluYWwgaW50IHByb2Nlc3NpbmdJbnN0cnVjdGlvbiA9Ci0gICAgICAgICAgICBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKFRSQU5TTEVUX09VVFBVVF9JTlRFUkZBQ0UsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24iLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKCIgKyBTVFJJTkdfU0lHICsgU1RSSU5HX1NJRyArICIpViIpOwotICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRUlOVEVSRkFDRShwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24sIDMpKTsKLSAgICAgICAgLy8gUmVzdG9yZSBvbGQgaGFuZGxlciBiYXNlIGZyb20gc3RhY2sKLSAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5zdG9yZUhhbmRsZXIoKSk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9Qcm9jZXNzaW5nSW5zdHJ1Y3Rpb25QYXR0ZXJuLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL1Byb2Nlc3NpbmdJbnN0cnVjdGlvblBhdHRlcm4uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOWZjZGYxYy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL1Byb2Nlc3NpbmdJbnN0cnVjdGlvblBhdHRlcm4uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE2MCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBQcm9jZXNzaW5nSW5zdHJ1Y3Rpb25QYXR0ZXJuLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTIgMTE6MDQ6MDggcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5CcmFuY2hIYW5kbGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5Db25zdGFudFBvb2xHZW47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5HT1RPOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSUZFUTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklGX0lDTVBFUTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklOVk9LRUlOVEVSRkFDRTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklOVk9LRVZJUlRVQUw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JbnN0cnVjdGlvbkhhbmRsZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uTGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlBVU0g7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuQ2xhc3NHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuTWV0aG9kR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZUNoZWNrRXJyb3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uQXhpczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE07Ci0KLS8qKgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKi8KLWZpbmFsIGNsYXNzIFByb2Nlc3NpbmdJbnN0cnVjdGlvblBhdHRlcm4gZXh0ZW5kcyBTdGVwUGF0dGVybiB7Ci0KLSAgICBwcml2YXRlIFN0cmluZyBfbmFtZSA9IG51bGw7Ci0gICAgcHJpdmF0ZSBib29sZWFuIF90eXBlQ2hlY2tlZCA9IGZhbHNlOwotCi0gICAgLyoqCi0gICAgICogSGFuZGxlcyBjYWxscyB3aXRoIG5vIHBhcmFtZXRlciAoY3VycmVudCBub2RlIGlzIGltcGxpY2l0IHBhcmFtZXRlcikuCi0gICAgICovCi0gICAgcHVibGljIFByb2Nlc3NpbmdJbnN0cnVjdGlvblBhdHRlcm4oU3RyaW5nIG5hbWUpIHsKLSAgICAgICAgc3VwZXIoQXhpcy5DSElMRCwgRFRNLlBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERSwgbnVsbCk7Ci0gICAgICAgIF9uYW1lID0gbmFtZTsKLSAgICAgICAgLy9pZiAoX25hbWUuZXF1YWxzKCIqIikpIF90eXBlQ2hlY2tlZCA9IHRydWU7IG5vIHdpbGRjYXJkIGFsbG93ZWQhCi0gICAgfQotCi0gICAgLyoqCi0gICAgICoKLSAgICAgKi8KLSAgICAgcHVibGljIGRvdWJsZSBnZXREZWZhdWx0UHJpb3JpdHkoKSB7Ci0gICAgICAgIHJldHVybiAoX25hbWUgIT0gbnVsbCkgPyAwLjAgOiAtMC41OwotICAgICB9Ci0gICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKLSAgICAgICAgaWYgKF9wcmVkaWNhdGVzID09IG51bGwpCi0gICAgICAgICAgICByZXR1cm4gInByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24oIitfbmFtZSsiKSI7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICAgIHJldHVybiAicHJvY2Vzc2luZy1pbnN0cnVjdGlvbigiK19uYW1lKyIpIitfcHJlZGljYXRlczsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCByZWR1Y2VLZXJuZWxQYXR0ZXJuKCkgewotICAgICAgICBfdHlwZUNoZWNrZWQgPSB0cnVlOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGlzV2lsZGNhcmQoKSB7Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgVHlwZSB0eXBlQ2hlY2soU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgewotICAgICAgICBpZiAoaGFzUHJlZGljYXRlcygpKSB7Ci0gICAgICAgICAgICAvLyBUeXBlIGNoZWNrIGFsbCB0aGUgcHJlZGljYXRlcyAoZSAtPiBwb3NpdGlvbigpID0gZSkKLSAgICAgICAgICAgIGZpbmFsIGludCBuID0gX3ByZWRpY2F0ZXMuc2l6ZSgpOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspIHsKLSAgICAgICAgICAgICAgICBmaW5hbCBQcmVkaWNhdGUgcHJlZCA9IChQcmVkaWNhdGUpX3ByZWRpY2F0ZXMuZWxlbWVudEF0KGkpOwotICAgICAgICAgICAgICAgIHByZWQudHlwZUNoZWNrKHN0YWJsZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIFR5cGUuTm9kZVNldDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLSAgICAgICAgZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0KLSAgICAgICAgLy8gY29udGV4dCBub2RlIGlzIG9uIHRoZSBzdGFjawotICAgICAgICBpbnQgZ25hbWUgPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKERPTV9JTlRGLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJnZXROb2RlTmFtZSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIihJKUxqYXZhL2xhbmcvU3RyaW5nOyIpOwotICAgICAgICBpbnQgY21wID0gY3BnLmFkZE1ldGhvZHJlZihTVFJJTkdfQ0xBU1MsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJlcXVhbHMiLCAiKExqYXZhL2xhbmcvT2JqZWN0OylaIik7Ci0KLSAgICAgICAgLy8gUHVzaCBjdXJyZW50IG5vZGUgb24gdGhlIHN0YWNrCi0gICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZEN1cnJlbnROb2RlKCkpOwotICAgICAgICBpbC5hcHBlbmQoU1dBUCk7Ci0KLSAgICAgICAgLy8gT3ZlcndyaXRlIGN1cnJlbnQgbm9kZSB3aXRoIG1hdGNoaW5nIG5vZGUKLSAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5zdG9yZUN1cnJlbnROb2RlKCkpOwotCi0gICAgICAgIC8vIElmIHBhdHRlcm4gbm90IHJlZHVjZWQgdGhlbiBjaGVjayBrZXJuZWwKLSAgICAgICAgaWYgKCFfdHlwZUNoZWNrZWQpIHsKLSAgICAgICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZEN1cnJlbnROb2RlKCkpOwotICAgICAgICAgICAgZmluYWwgaW50IGdldFR5cGUgPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKERPTV9JTlRGLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJnZXRFeHBhbmRlZFR5cGVJRCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIihJKUkiKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZEN1cnJlbnROb2RlKCkpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0UoZ2V0VHlwZSwgMikpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgRFRNLlBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERSkpOwotICAgICAgICAgICAgX2ZhbHNlTGlzdC5hZGQoaWwuYXBwZW5kKG5ldyBJRl9JQ01QRVEobnVsbCkpKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIExvYWQgdGhlIHJlcXVlc3RlZCBwcm9jZXNzaW5nIGluc3RydWN0aW9uIG5hbWUKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgX25hbWUpKTsKLSAgICAgICAgLy8gTG9hZCB0aGUgY3VycmVudCBwcm9jZXNzaW5nIGluc3RydWN0aW9uJ3MgbmFtZQotICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0gICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZEN1cnJlbnROb2RlKCkpOwotICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRUlOVEVSRkFDRShnbmFtZSwgMikpOwotICAgICAgICAvLyBDb21wYXJlIHRoZSB0d28gc3RyaW5ncwotICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRVZJUlRVQUwoY21wKSk7Ci0gICAgICAgIF9mYWxzZUxpc3QuYWRkKGlsLmFwcGVuZChuZXcgSUZFUShudWxsKSkpOwotCi0gICAgICAgIC8vIENvbXBpbGUgdGhlIGV4cHJlc3Npb25zIHdpdGhpbiB0aGUgcHJlZGljYXRlcwotICAgICAgICBpZiAoaGFzUHJlZGljYXRlcygpKSB7Ci0gICAgICAgICAgICBmaW5hbCBpbnQgbiA9IF9wcmVkaWNhdGVzLnNpemUoKTsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgUHJlZGljYXRlIHByZWQgPSAoUHJlZGljYXRlKV9wcmVkaWNhdGVzLmVsZW1lbnRBdChpKTsKLSAgICAgICAgICAgICAgICBFeHByZXNzaW9uIGV4cCA9IHByZWQuZ2V0RXhwcigpOwotICAgICAgICAgICAgICAgIGV4cC50cmFuc2xhdGVEZXN5bnRoZXNpemVkKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICAgICAgICAgIF90cnVlTGlzdC5hcHBlbmQoZXhwLl90cnVlTGlzdCk7Ci0gICAgICAgICAgICAgICAgX2ZhbHNlTGlzdC5hcHBlbmQoZXhwLl9mYWxzZUxpc3QpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gQmFja3BhdGNoIHRydWUgbGlzdCBhbmQgcmVzdG9yZSBjdXJyZW50IGl0ZXJhdG9yL25vZGUKLSAgICAgICAgSW5zdHJ1Y3Rpb25IYW5kbGUgcmVzdG9yZTsKLSAgICAgICAgcmVzdG9yZSA9IGlsLmFwcGVuZChtZXRob2RHZW4uc3RvcmVDdXJyZW50Tm9kZSgpKTsKLSAgICAgICAgYmFja1BhdGNoVHJ1ZUxpc3QocmVzdG9yZSk7Ci0gICAgICAgIEJyYW5jaEhhbmRsZSBza2lwRmFsc2UgPSBpbC5hcHBlbmQobmV3IEdPVE8obnVsbCkpOwotCi0gICAgICAgIC8vIEJhY2twYXRjaCBmYWxzZSBsaXN0IGFuZCByZXN0b3JlIGN1cnJlbnQgaXRlcmF0b3Ivbm9kZQotICAgICAgICByZXN0b3JlID0gaWwuYXBwZW5kKG1ldGhvZEdlbi5zdG9yZUN1cnJlbnROb2RlKCkpOwotICAgICAgICBiYWNrUGF0Y2hGYWxzZUxpc3QocmVzdG9yZSk7Ci0gICAgICAgIF9mYWxzZUxpc3QuYWRkKGlsLmFwcGVuZChuZXcgR09UTyhudWxsKSkpOwotCi0gICAgICAgIC8vIFRydWUgbGlzdCBmYWxscyB0aHJvdWdoCi0gICAgICAgIHNraXBGYWxzZS5zZXRUYXJnZXQoaWwuYXBwZW5kKE5PUCkpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvUU5hbWUuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvUU5hbWUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggODk2YjIxNi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL1FOYW1lLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4NyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBRTmFtZS5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzAyIDExOjQ1OjU2IHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlcjsKLQotLyoqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqLwotZmluYWwgY2xhc3MgUU5hbWUgewotICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIF9sb2NhbG5hbWU7Ci0gICAgcHJpdmF0ZSBTdHJpbmcgX3ByZWZpeDsKLSAgICBwcml2YXRlIFN0cmluZyBfbmFtZXNwYWNlOwotICAgIHByaXZhdGUgU3RyaW5nIF9zdHJpbmdSZXA7Ci0gICAgcHJpdmF0ZSBpbnQgICAgX2hhc2hDb2RlOwotCi0gICAgcHVibGljIFFOYW1lKFN0cmluZyBuYW1lc3BhY2UsIFN0cmluZyBwcmVmaXgsIFN0cmluZyBsb2NhbG5hbWUpIHsKLSAgICAgICAgX25hbWVzcGFjZSA9IG5hbWVzcGFjZTsKLSAgICAgICAgX3ByZWZpeCAgICA9IHByZWZpeDsKLSAgICAgICAgX2xvY2FsbmFtZSA9IGxvY2FsbmFtZTsKLQotICAgICAgICBfc3RyaW5nUmVwID0KLSAgICAgICAgICAgIChuYW1lc3BhY2UgIT0gbnVsbCAmJiAhbmFtZXNwYWNlLmVxdWFscyhDb25zdGFudHMuRU1QVFlTVFJJTkcpKSA/Ci0gICAgICAgICAgICAobmFtZXNwYWNlICsgJzonICsgbG9jYWxuYW1lKSA6IGxvY2FsbmFtZTsKLQotICAgICAgICBfaGFzaENvZGUgID0gX3N0cmluZ1JlcC5oYXNoQ29kZSgpICsgMTk7IC8vIGNhY2hlZCBmb3Igc3BlZWQKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBjbGVhck5hbWVzcGFjZSgpIHsKLSAgICAgICAgX25hbWVzcGFjZSA9IENvbnN0YW50cy5FTVBUWVNUUklORzsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgICAgICByZXR1cm4gX3N0cmluZ1JlcDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldFN0cmluZ1JlcCgpIHsKLSAgICAgICAgcmV0dXJuIF9zdHJpbmdSZXA7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvdGhlcikgewotICAgICAgICByZXR1cm4gKHRoaXMgPT0gb3RoZXIpCi0gICAgICAgICAgICAgICAgICAgfHwgKG90aGVyIGluc3RhbmNlb2YgUU5hbWUKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICYmIF9zdHJpbmdSZXAuZXF1YWxzKCgoUU5hbWUpIG90aGVyKS5nZXRTdHJpbmdSZXAoKSkpOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TG9jYWxQYXJ0KCkgewotICAgICAgICByZXR1cm4gX2xvY2FsbmFtZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWVzcGFjZSgpIHsKLSAgICAgICAgcmV0dXJuIF9uYW1lc3BhY2U7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRQcmVmaXgoKSB7Ci0gICAgICAgIHJldHVybiBfcHJlZml4OwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7Ci0gICAgICAgIHJldHVybiBfaGFzaENvZGU7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBkdW1wKCkgewotICAgICAgICByZXR1cm4gIlFOYW1lOiAiICsgX25hbWVzcGFjZSArICIoIiArIF9wcmVmaXggKyAiKToiICsgX2xvY2FsbmFtZTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL1JlYWxFeHByLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL1JlYWxFeHByLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDU0NzFmZTUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9SZWFsRXhwci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTggKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogUmVhbEV4cHIuamF2YSx2IDEuMiAyMDA1LzA4LzE2IDIyOjMwOjM1IGplZmZzdXR0b3IgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQ29uc3RhbnRQb29sR2VuOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW5zdHJ1Y3Rpb25MaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuUFVTSDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5DbGFzc0dlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5NZXRob2RHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlQ2hlY2tFcnJvcjsKLQotLyoqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKi8KLWZpbmFsIGNsYXNzIFJlYWxFeHByIGV4dGVuZHMgRXhwcmVzc2lvbiB7Ci0gICAgcHJpdmF0ZSBkb3VibGUgX3ZhbHVlOwotCi0gICAgcHVibGljIFJlYWxFeHByKGRvdWJsZSB2YWx1ZSkgewotICAgICAgICBfdmFsdWUgPSB2YWx1ZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgVHlwZSB0eXBlQ2hlY2soU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgewotICAgICAgICByZXR1cm4gX3R5cGUgPSBUeXBlLlJlYWw7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKLSAgICAgICAgcmV0dXJuICJyZWFsLWV4cHIoIiArIF92YWx1ZSArICcpJzsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLSAgICAgICAgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotICAgICAgICBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsIF92YWx1ZSkpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvUmVsYXRpb25hbEV4cHIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvUmVsYXRpb25hbEV4cHIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZmNhN2U2Ny4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL1JlbGF0aW9uYWxFeHByLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyODMgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogUmVsYXRpb25hbEV4cHIuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xMiAxMTowNTowMCBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkJyYW5jaEluc3RydWN0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQ29uc3RhbnRQb29sR2VuOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFU1RBVElDOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW5zdHJ1Y3Rpb25MaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuUFVTSDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5Cb29sZWFuVHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5DbGFzc0dlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5FcnJvck1zZzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5JbnRUeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLk1ldGhvZEdlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5NZXRob2RUeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLk5vZGVTZXRUeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLk5vZGVUeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlJlYWxUeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlJlZmVyZW5jZVR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuUmVzdWx0VHJlZVR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlQ2hlY2tFcnJvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMucnVudGltZS5PcGVyYXRvcnM7Ci0KLS8qKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICovCi1maW5hbCBjbGFzcyBSZWxhdGlvbmFsRXhwciBleHRlbmRzIEV4cHJlc3Npb24gewotCi0gICAgcHJpdmF0ZSBpbnQgX29wOwotICAgIHByaXZhdGUgRXhwcmVzc2lvbiBfbGVmdCwgX3JpZ2h0OwotCi0gICAgcHVibGljIFJlbGF0aW9uYWxFeHByKGludCBvcCwgRXhwcmVzc2lvbiBsZWZ0LCBFeHByZXNzaW9uIHJpZ2h0KSB7Ci0gICAgICAgIF9vcCA9IG9wOwotICAgICAgICAoX2xlZnQgPSBsZWZ0KS5zZXRQYXJlbnQodGhpcyk7Ci0gICAgICAgIChfcmlnaHQgPSByaWdodCkuc2V0UGFyZW50KHRoaXMpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldFBhcnNlcihQYXJzZXIgcGFyc2VyKSB7Ci0gICAgICAgIHN1cGVyLnNldFBhcnNlcihwYXJzZXIpOwotICAgICAgICBfbGVmdC5zZXRQYXJzZXIocGFyc2VyKTsKLSAgICAgICAgX3JpZ2h0LnNldFBhcnNlcihwYXJzZXIpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGlzIGV4cHJlc3Npb25zIGNvbnRhaW5zIGEgY2FsbCB0byBwb3NpdGlvbigpLiBUaGlzIGlzCi0gICAgICogbmVlZGVkIGZvciBjb250ZXh0IGNoYW5nZXMgaW4gbm9kZSBzdGVwcyBjb250YWluaW5nIG11bHRpcGxlIHByZWRpY2F0ZXMuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaGFzUG9zaXRpb25DYWxsKCkgewotICAgICAgICBpZiAoX2xlZnQuaGFzUG9zaXRpb25DYWxsKCkpIHJldHVybiB0cnVlOwotICAgICAgICBpZiAoX3JpZ2h0Lmhhc1Bvc2l0aW9uQ2FsbCgpKSByZXR1cm4gdHJ1ZTsKLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGlzIGV4cHJlc3Npb25zIGNvbnRhaW5zIGEgY2FsbCB0byBsYXN0KCkKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBoYXNMYXN0Q2FsbCgpIHsKLSAgICAgICAgICAgIHJldHVybiAoX2xlZnQuaGFzTGFzdENhbGwoKSB8fCBfcmlnaHQuaGFzTGFzdENhbGwoKSk7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gaGFzUmVmZXJlbmNlQXJncygpIHsKLSAgICAgICAgcmV0dXJuIF9sZWZ0LmdldFR5cGUoKSBpbnN0YW5jZW9mIFJlZmVyZW5jZVR5cGUgfHwKLSAgICAgICAgICAgIF9yaWdodC5nZXRUeXBlKCkgaW5zdGFuY2VvZiBSZWZlcmVuY2VUeXBlOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGhhc05vZGVBcmdzKCkgewotICAgICAgICByZXR1cm4gX2xlZnQuZ2V0VHlwZSgpIGluc3RhbmNlb2YgTm9kZVR5cGUgfHwKLSAgICAgICAgICAgIF9yaWdodC5nZXRUeXBlKCkgaW5zdGFuY2VvZiBOb2RlVHlwZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBoYXNOb2RlU2V0QXJncygpIHsKLSAgICAgICAgcmV0dXJuIF9sZWZ0LmdldFR5cGUoKSBpbnN0YW5jZW9mIE5vZGVTZXRUeXBlIHx8Ci0gICAgICAgICAgICBfcmlnaHQuZ2V0VHlwZSgpIGluc3RhbmNlb2YgTm9kZVNldFR5cGU7Ci0gICAgfQotCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLSAgICAgICAgVHlwZSB0bGVmdCA9IF9sZWZ0LnR5cGVDaGVjayhzdGFibGUpOwotICAgICAgICBUeXBlIHRyaWdodCA9IF9yaWdodC50eXBlQ2hlY2soc3RhYmxlKTsKLQotICAgICAgICAvL2J1ZyBmaXggIyAyODM4LCBjYXN0IHRvIHJlYWxzIGlmIGJvdGggYXJlIHJlc3VsdCB0cmVlIGZyYWdtZW50cwotICAgICAgICBpZiAodGxlZnQgaW5zdGFuY2VvZiBSZXN1bHRUcmVlVHlwZSAmJgotICAgICAgICAgICAgdHJpZ2h0IGluc3RhbmNlb2YgUmVzdWx0VHJlZVR5cGUgKQotICAgICAgICB7Ci0gICAgICAgICAgICBfcmlnaHQgPSBuZXcgQ2FzdEV4cHIoX3JpZ2h0LCBUeXBlLlJlYWwpOwotICAgICAgICAgICAgX2xlZnQgPSBuZXcgQ2FzdEV4cHIoX2xlZnQsIFR5cGUuUmVhbCk7Ci0gICAgICAgICAgICByZXR1cm4gX3R5cGUgPSBUeXBlLkJvb2xlYW47Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBJZiBvbmUgaXMgb2YgcmVmZXJlbmNlIHR5cGUsIHRoZW4gY29udmVydCB0aGUgb3RoZXIgdG9vCi0gICAgICAgIGlmIChoYXNSZWZlcmVuY2VBcmdzKCkpIHsKLSAgICAgICAgICAgIFR5cGUgdHlwZSA9IG51bGw7Ci0gICAgICAgICAgICBUeXBlIHR5cGVMID0gbnVsbDsKLSAgICAgICAgICAgIFR5cGUgdHlwZVIgPSBudWxsOwotICAgICAgICAgICAgaWYgKHRsZWZ0IGluc3RhbmNlb2YgUmVmZXJlbmNlVHlwZSkgewotICAgICAgICAgICAgICAgIGlmIChfbGVmdCBpbnN0YW5jZW9mIFZhcmlhYmxlUmVmQmFzZSkgewotICAgICAgICAgICAgICAgICAgICBWYXJpYWJsZVJlZkJhc2UgcmVmID0gKFZhcmlhYmxlUmVmQmFzZSlfbGVmdDsKLSAgICAgICAgICAgICAgICAgICAgVmFyaWFibGVCYXNlIHZhciA9IHJlZi5nZXRWYXJpYWJsZSgpOwotICAgICAgICAgICAgICAgICAgICB0eXBlTCA9IHZhci5nZXRUeXBlKCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKHRyaWdodCBpbnN0YW5jZW9mIFJlZmVyZW5jZVR5cGUpIHsKLSAgICAgICAgICAgICAgICBpZiAoX3JpZ2h0IGluc3RhbmNlb2YgVmFyaWFibGVSZWZCYXNlKSB7Ci0gICAgICAgICAgICAgICAgICAgIFZhcmlhYmxlUmVmQmFzZSByZWYgPSAoVmFyaWFibGVSZWZCYXNlKV9yaWdodDsKLSAgICAgICAgICAgICAgICAgICAgVmFyaWFibGVCYXNlIHZhciA9IHJlZi5nZXRWYXJpYWJsZSgpOwotICAgICAgICAgICAgICAgICAgICB0eXBlUiA9IHZhci5nZXRUeXBlKCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gYnVnIGZpeCAjIDI4MzgKLSAgICAgICAgICAgIGlmICh0eXBlTCA9PSBudWxsKQotICAgICAgICAgICAgICAgIHR5cGUgPSB0eXBlUjsKLSAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVSID09IG51bGwpCi0gICAgICAgICAgICAgICAgdHlwZSA9IHR5cGVMOwotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgdHlwZSA9IFR5cGUuUmVhbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmICh0eXBlID09IG51bGwpIHR5cGUgPSBUeXBlLlJlYWw7Ci0KLSAgICAgICAgICAgIF9yaWdodCA9IG5ldyBDYXN0RXhwcihfcmlnaHQsIHR5cGUpOwotICAgICAgICAgICAgX2xlZnQgPSBuZXcgQ2FzdEV4cHIoX2xlZnQsIHR5cGUpOwotICAgICAgICAgICAgcmV0dXJuIF90eXBlID0gVHlwZS5Cb29sZWFuOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKGhhc05vZGVTZXRBcmdzKCkpIHsKLSAgICAgICAgICAgIC8vIEVuc3VyZSB0aGF0IHRoZSBub2RlLXNldCBpcyB0aGUgbGVmdCBhcmd1bWVudAotICAgICAgICAgICAgaWYgKHRyaWdodCBpbnN0YW5jZW9mIE5vZGVTZXRUeXBlKSB7Ci0gICAgICAgICAgICAgICAgZmluYWwgRXhwcmVzc2lvbiB0ZW1wID0gX3JpZ2h0OyBfcmlnaHQgPSBfbGVmdDsgX2xlZnQgPSB0ZW1wOwotICAgICAgICBfb3AgPSAoX29wID09IE9wZXJhdG9ycy5HVCkgPyBPcGVyYXRvcnMuTFQgOgotICAgICAgICAgICAgKF9vcCA9PSBPcGVyYXRvcnMuTFQpID8gT3BlcmF0b3JzLkdUIDoKLSAgICAgICAgICAgIChfb3AgPT0gT3BlcmF0b3JzLkdFKSA/IE9wZXJhdG9ycy5MRSA6IE9wZXJhdG9ycy5HRTsKLSAgICAgICAgICAgICAgICB0cmlnaHQgPSBfcmlnaHQuZ2V0VHlwZSgpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBQcm9tb3RlIG5vZGVzIHRvIG5vZGUgc2V0cwotICAgICAgICAgICAgaWYgKHRyaWdodCBpbnN0YW5jZW9mIE5vZGVUeXBlKSB7Ci0gICAgICAgICAgICAgICAgX3JpZ2h0ID0gbmV3IENhc3RFeHByKF9yaWdodCwgVHlwZS5Ob2RlU2V0KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIFByb21vdGUgaW50ZWdlciB0byBkb3VibGVzIHRvIGhhdmUgZmV3ZXIgY29tcGFyZXMKLSAgICAgICAgICAgIGlmICh0cmlnaHQgaW5zdGFuY2VvZiBJbnRUeXBlKSB7Ci0gICAgICAgICAgICAgICAgX3JpZ2h0ID0gbmV3IENhc3RFeHByKF9yaWdodCwgVHlwZS5SZWFsKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIFByb21vdGUgcmVzdWx0LXRyZWVzIHRvIHN0cmluZ3MKLSAgICAgICAgICAgIGlmICh0cmlnaHQgaW5zdGFuY2VvZiBSZXN1bHRUcmVlVHlwZSkgewotICAgICAgICAgICAgICAgIF9yaWdodCA9IG5ldyBDYXN0RXhwcihfcmlnaHQsIFR5cGUuU3RyaW5nKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiBfdHlwZSA9IFR5cGUuQm9vbGVhbjsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIEluIHRoZSBub2RlLWJvb2xlYW4gY2FzZSwgY29udmVydCBub2RlIHRvIGJvb2xlYW4gZmlyc3QKLSAgICAgICAgaWYgKGhhc05vZGVBcmdzKCkpIHsKLSAgICAgICAgICAgIGlmICh0bGVmdCBpbnN0YW5jZW9mIEJvb2xlYW5UeXBlKSB7Ci0gICAgICAgICAgICAgICAgX3JpZ2h0ID0gbmV3IENhc3RFeHByKF9yaWdodCwgVHlwZS5Cb29sZWFuKTsKLSAgICAgICAgICAgICAgICB0cmlnaHQgPSBUeXBlLkJvb2xlYW47Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAodHJpZ2h0IGluc3RhbmNlb2YgQm9vbGVhblR5cGUpIHsKLSAgICAgICAgICAgICAgICBfbGVmdCA9IG5ldyBDYXN0RXhwcihfbGVmdCwgVHlwZS5Cb29sZWFuKTsKLSAgICAgICAgICAgICAgICB0bGVmdCA9IFR5cGUuQm9vbGVhbjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIExvb2t1cCB0aGUgdGFibGUgb2YgcHJpbW9wcyB0byBmaW5kIHRoZSBiZXN0IG1hdGNoCi0gICAgTWV0aG9kVHlwZSBwdHlwZSA9IGxvb2t1cFByaW1vcChzdGFibGUsIE9wZXJhdG9ycy5nZXRPcE5hbWVzKF9vcCksCi0gICAgICAgICAgICAgICAgbmV3IE1ldGhvZFR5cGUoVHlwZS5Wb2lkLCB0bGVmdCwgdHJpZ2h0KSk7Ci0KLSAgICAgICAgaWYgKHB0eXBlICE9IG51bGwpIHsKLSAgICAgICAgICAgIFR5cGUgYXJnMSA9IChUeXBlKSBwdHlwZS5hcmdzVHlwZSgpLmVsZW1lbnRBdCgwKTsKLSAgICAgICAgICAgIGlmICghYXJnMS5pZGVudGljYWxUbyh0bGVmdCkpIHsKLSAgICAgICAgICAgICAgICBfbGVmdCA9IG5ldyBDYXN0RXhwcihfbGVmdCwgYXJnMSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBUeXBlIGFyZzIgPSAoVHlwZSkgcHR5cGUuYXJnc1R5cGUoKS5lbGVtZW50QXQoMSk7Ci0gICAgICAgICAgICBpZiAoIWFyZzIuaWRlbnRpY2FsVG8odHJpZ2h0KSkgewotICAgICAgICAgICAgICAgIF9yaWdodCA9IG5ldyBDYXN0RXhwcihfcmlnaHQsIGFyZzEpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIF90eXBlID0gcHR5cGUucmVzdWx0VHlwZSgpOwotICAgICAgICB9Ci0gICAgICAgIHRocm93IG5ldyBUeXBlQ2hlY2tFcnJvcih0aGlzKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLSAgICAgICAgaWYgKGhhc05vZGVTZXRBcmdzKCkgfHwgaGFzUmVmZXJlbmNlQXJncygpKSB7Ci0gICAgICAgICAgICBmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0KLSAgICAgICAgICAgIC8vIENhbGwgY29tcGFyZSgpIGZyb20gdGhlIEJhc2lzTGlicmFyeQotICAgICAgICAgICAgX2xlZnQudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICAgICAgX2xlZnQuc3RhcnRJdGVyYXRvcihjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgICAgIF9yaWdodC50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgICAgICBfcmlnaHQuc3RhcnRJdGVyYXRvcihjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgX29wKSk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0KLSAgICAgICAgICAgIGludCBpbmRleCA9IGNwZy5hZGRNZXRob2RyZWYoQkFTSVNfTElCUkFSWV9DTEFTUywgImNvbXBhcmUiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKCIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBfbGVmdC5nZXRUeXBlKCkudG9TaWduYXR1cmUoKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIF9yaWdodC5nZXRUeXBlKCkudG9TaWduYXR1cmUoKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICJJIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIERPTV9JTlRGX1NJRwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIpWiIpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VTVEFUSUMoaW5kZXgpKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHRyYW5zbGF0ZURlc3ludGhlc2l6ZWQoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgICAgICBzeW50aGVzaXplKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlRGVzeW50aGVzaXplZChDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLSAgICAgICAgaWYgKGhhc05vZGVTZXRBcmdzKCkgfHwgaGFzUmVmZXJlbmNlQXJncygpKSB7Ci0gICAgICAgICAgICB0cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgICAgICBkZXN5bnRoZXNpemUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBCcmFuY2hJbnN0cnVjdGlvbiBiaSA9IG51bGw7Ci0gICAgICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0KLSAgICAgICAgICAgIF9sZWZ0LnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgICAgIF9yaWdodC50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0KLSAgICAgICAgICAgIC8vIFRPRE86IG9wdGltaXplIGlmIG9uZSBvZiB0aGUgYXJncyBpcyAwCi0KLSAgICAgICAgICAgIGJvb2xlYW4gdG96ZXJvID0gZmFsc2U7Ci0gICAgICAgICAgICBUeXBlIHRsZWZ0ID0gX2xlZnQuZ2V0VHlwZSgpOwotCi0gICAgICAgICAgICBpZiAodGxlZnQgaW5zdGFuY2VvZiBSZWFsVHlwZSkgewotICAgICAgICBpbC5hcHBlbmQodGxlZnQuQ01QKF9vcCA9PSBPcGVyYXRvcnMuTFQgfHwgX29wID09IE9wZXJhdG9ycy5MRSkpOwotICAgICAgICAgICAgICAgIHRsZWZ0ID0gVHlwZS5JbnQ7Ci0gICAgICAgICAgICAgICAgdG96ZXJvID0gdHJ1ZTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgc3dpdGNoIChfb3ApIHsKLSAgICAgICAgY2FzZSBPcGVyYXRvcnMuTFQ6Ci0gICAgICAgICAgICAgICAgYmkgPSB0bGVmdC5HRSh0b3plcm8pOwotICAgICAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgIGNhc2UgT3BlcmF0b3JzLkdUOgotICAgICAgICAgICAgICAgIGJpID0gdGxlZnQuTEUodG96ZXJvKTsKLSAgICAgICAgICAgICAgICBicmVhazsKLQotICAgICAgICBjYXNlIE9wZXJhdG9ycy5MRToKLSAgICAgICAgICAgICAgICBiaSA9IHRsZWZ0LkdUKHRvemVybyk7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgY2FzZSBPcGVyYXRvcnMuR0U6Ci0gICAgICAgICAgICAgICAgYmkgPSB0bGVmdC5MVCh0b3plcm8pOwotICAgICAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgICAgICBkZWZhdWx0OgotICAgICAgICAgICAgICAgIEVycm9yTXNnIG1zZyA9IG5ldyBFcnJvck1zZyhFcnJvck1zZy5JTExFR0FMX1JFTEFUX09QX0VSUix0aGlzKTsKLSAgICAgICAgICAgICAgICBnZXRQYXJzZXIoKS5yZXBvcnRFcnJvcihDb25zdGFudHMuRkFUQUwsIG1zZyk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIF9mYWxzZUxpc3QuYWRkKGlsLmFwcGVuZChiaSkpOyAgICAgICAgICAgICAgLy8gbXVzdCBiZSBiYWNrcGF0Y2hlZAotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKLSAgICAgICAgcmV0dXJuIE9wZXJhdG9ycy5nZXRPcE5hbWVzKF9vcCkgKyAnKCcgKyBfbGVmdCArICIsICIgKyBfcmlnaHQgKyAnKSc7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9SZWxhdGl2ZUxvY2F0aW9uUGF0aC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9SZWxhdGl2ZUxvY2F0aW9uUGF0aC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzYjY4MDA0Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvUmVsYXRpdmVMb2NhdGlvblBhdGguamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDMzICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFJlbGF0aXZlTG9jYXRpb25QYXRoLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMDIgMTE6NTk6MjIgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyOwotCi0vKioKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqLwotYWJzdHJhY3QgY2xhc3MgUmVsYXRpdmVMb2NhdGlvblBhdGggZXh0ZW5kcyBFeHByZXNzaW9uIHsKLSAgICBwdWJsaWMgYWJzdHJhY3QgaW50IGdldEF4aXMoKTsKLSAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRBeGlzKGludCBheGlzKTsKLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvUmVsYXRpdmVQYXRoUGF0dGVybi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9SZWxhdGl2ZVBhdGhQYXR0ZXJuLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDkwYmMyZDkuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9SZWxhdGl2ZVBhdGhQYXR0ZXJuLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzMCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBSZWxhdGl2ZVBhdGhQYXR0ZXJuLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMDIgMTI6MDk6MzggcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyOwotCi0vKioKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqLwotYWJzdHJhY3QgY2xhc3MgUmVsYXRpdmVQYXRoUGF0dGVybiBleHRlbmRzIExvY2F0aW9uUGF0aFBhdHRlcm4ge30KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvUm91bmRDYWxsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL1JvdW5kQ2FsbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0YTBkMWZiLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvUm91bmRDYWxsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw1MyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBSb3VuZENhbGwuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8wMiAxMjoxMjozNSBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5Db25zdGFudFBvb2xHZW47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JTlZPS0VTVEFUSUM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JbnN0cnVjdGlvbkxpc3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuQ2xhc3NHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuTWV0aG9kR2VuZXJhdG9yOwotCi0vKioKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqLwotZmluYWwgY2xhc3MgUm91bmRDYWxsIGV4dGVuZHMgRnVuY3Rpb25DYWxsIHsKLQotICAgIHB1YmxpYyBSb3VuZENhbGwoUU5hbWUgZm5hbWUsIFZlY3RvciBhcmd1bWVudHMpIHsKLSAgICAgICAgc3VwZXIoZm5hbWUsIGFyZ3VtZW50cyk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0gICAgICAgIGZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCi0gICAgICAgIC8vIEdldCB0d28gY29waWVzIG9mIHRoZSBhcmd1bWVudCBvbiB0aGUgc3RhY2sKLSAgICAgICAgYXJndW1lbnQoKS50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VTVEFUSUMoY3BnLmFkZE1ldGhvZHJlZihCQVNJU19MSUJSQVJZX0NMQVNTLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInJvdW5kRiIsICIoRClEIikpKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL1NpbXBsZUF0dHJpYnV0ZVZhbHVlLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL1NpbXBsZUF0dHJpYnV0ZVZhbHVlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDEzMWVkMzEuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9TaW1wbGVBdHRyaWJ1dGVWYWx1ZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNzcgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogU2ltcGxlQXR0cmlidXRlVmFsdWUuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8wNSAwODo1ODo0NiBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkNvbnN0YW50UG9vbEdlbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uTGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlBVU0g7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuQ2xhc3NHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuTWV0aG9kR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZUNoZWNrRXJyb3I7Ci0KLS8qKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICovCi1maW5hbCBjbGFzcyBTaW1wbGVBdHRyaWJ1dGVWYWx1ZSBleHRlbmRzIEF0dHJpYnV0ZVZhbHVlIHsKLQotICAgIHByaXZhdGUgU3RyaW5nIF92YWx1ZTsgLy8gVGhlIGF0dHJpYnV0ZXMgdmFsdWUgKGxpdGVyYXRlIHN0cmluZykuCi0KLSAgICAvKioKLSAgICAgKiBDcmVhdGVzIGEgbmV3IHNpbXBsZSBhdHRyaWJ1dGUgdmFsdWUuCi0gICAgICogQHBhcmFtIHZhbHVlIHRoZSBhdHRyaWJ1dGUgdmFsdWUuCi0gICAgICovCi0gICAgcHVibGljIFNpbXBsZUF0dHJpYnV0ZVZhbHVlKFN0cmluZyB2YWx1ZSkgewotICAgICAgICBfdmFsdWUgPSB2YWx1ZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoaXMgYXR0cmlidXRlIHZhbHVlJ3MgdHlwZSAoU3RyaW5nKS4KLSAgICAgKiBAcGFyYW0gc3RhYmxlIFRoZSBjb21waWxlci9wYXJzZXIncyBzeW1ib2wgdGFibGUKLSAgICAgKi8KLSAgICBwdWJsaWMgVHlwZSB0eXBlQ2hlY2soU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgewotICAgICAgICByZXR1cm4gX3R5cGUgPSBUeXBlLlN0cmluZzsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgICAgICByZXR1cm4gX3ZhbHVlOwotICAgIH0KLQotICAgIHByb3RlY3RlZCBib29sZWFuIGNvbnRleHREZXBlbmRlbnQoKSB7Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGUgdGhpcyBhdHRyaWJ1dGUgdmFsdWUgaW50byBKVk0gYnl0ZWNvZGVzIHRoYXQgcHVzaGVzIHRoZQotICAgICAqIGF0dHJpYnV0ZSB2YWx1ZSBvbnRvIHRoZSBKVk0ncyBzdGFjay4KLSAgICAgKiBAcGFyYW0gY2xhc3NHZW4gQkNFTCBKYXZhIGNsYXNzIGdlbmVyYXRvcgotICAgICAqIEBwYXJhbSBtZXRob2RHZW4gQkNFTCBKYXZhIG1ldGhvZCBnZW5lcmF0b3IKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLSAgICAgICAgZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsIF92YWx1ZSkpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvU29ydC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9Tb3J0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGY3MzA5ZTUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9Tb3J0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3MzQgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuY2xhc3NmaWxlLkZpZWxkOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQUxPQUQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5BTkVXQVJSQVk7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5BU1RPUkU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5DSEVDS0NBU1Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5Db25zdGFudFBvb2xHZW47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5HRVRGSUVMRDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklMT0FEOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFSU5URVJGQUNFOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFU1BFQ0lBTDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uSGFuZGxlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW5zdHJ1Y3Rpb25MaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuTG9jYWxWYXJpYWJsZUdlbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLk5FVzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLk5PUDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlBVU0g7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5QVVRGSUVMRDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlRBQkxFU1dJVENIOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkNsYXNzR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkNvbXBhcmVHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuRXJyb3JNc2c7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuSW50VHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5NZXRob2RHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuTm9kZVNvcnRSZWNvcmRGYWN0R2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLk5vZGVTb3J0UmVjb3JkR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlN0cmluZ1R5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlQ2hlY2tFcnJvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5VdGlsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkF4aXM7Ci0KLQotLyoqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqLwotZmluYWwgY2xhc3MgU29ydCBleHRlbmRzIEluc3RydWN0aW9uIGltcGxlbWVudHMgQ2xvc3VyZSB7Ci0KLSAgICBwcml2YXRlIEV4cHJlc3Npb24gICAgIF9zZWxlY3Q7Ci0gICAgcHJpdmF0ZSBBdHRyaWJ1dGVWYWx1ZSBfb3JkZXI7Ci0gICAgcHJpdmF0ZSBBdHRyaWJ1dGVWYWx1ZSBfY2FzZU9yZGVyOwotICAgIHByaXZhdGUgQXR0cmlidXRlVmFsdWUgX2RhdGFUeXBlOwotICAgIHByaXZhdGUgU3RyaW5nICAgICAgICAgX2xhbmc7IC8vIGJ1ZyEgc2VlIDI2ODY5Ci0KLSAgICBwcml2YXRlIFN0cmluZyBfY2xhc3NOYW1lID0gbnVsbDsKLSAgICBwcml2YXRlIEFycmF5TGlzdDxWYXJpYWJsZVJlZkJhc2U+IF9jbG9zdXJlVmFycyA9IG51bGw7Ci0gICAgcHJpdmF0ZSBib29sZWFuIF9uZWVkc1NvcnRSZWNvcmRGYWN0b3J5ID0gZmFsc2U7Ci0KLSAgICAvLyAtLSBCZWdpbiBDbG9zdXJlIGludGVyZmFjZSAtLS0tLS0tLS0tLS0tLS0tLS0tLQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIGlmIHRoaXMgY2xvc3VyZSBpcyBjb21waWxlZCBpbiBhbiBpbm5lciBjbGFzcyAoaS5lLgotICAgICAqIGlmIHRoaXMgaXMgYSByZWFsIGNsb3N1cmUpLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGluSW5uZXJDbGFzcygpIHsKLSAgICAgICAgcmV0dXJuIChfY2xhc3NOYW1lICE9IG51bGwpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYSByZWZlcmVuY2UgdG8gaXRzIHBhcmVudCBjbG9zdXJlIG9yIG51bGwgaWYgb3V0ZXJtb3N0LgotICAgICAqLwotICAgIHB1YmxpYyBDbG9zdXJlIGdldFBhcmVudENsb3N1cmUoKSB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhlIGF1eGlsaWFyeSBjbGFzcyBvciBudWxsIGlmIHRoaXMgcHJlZGljYXRlCi0gICAgICogaXMgY29tcGlsZWQgaW5zaWRlIHRoZSBUcmFuc2xldC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldElubmVyQ2xhc3NOYW1lKCkgewotICAgICAgICByZXR1cm4gX2NsYXNzTmFtZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBZGQgbmV3IHZhcmlhYmxlIHRvIHRoZSBjbG9zdXJlLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGFkZFZhcmlhYmxlKFZhcmlhYmxlUmVmQmFzZSB2YXJpYWJsZVJlZikgewotICAgICAgICBpZiAoX2Nsb3N1cmVWYXJzID09IG51bGwpIHsKLSAgICAgICAgICAgIF9jbG9zdXJlVmFycyA9IG5ldyBBcnJheUxpc3Q8PigpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gT25seSBvbmUgcmVmZXJlbmNlIHBlciB2YXJpYWJsZQotICAgICAgICBpZiAoIV9jbG9zdXJlVmFycy5jb250YWlucyh2YXJpYWJsZVJlZikpIHsKLSAgICAgICAgICAgIF9jbG9zdXJlVmFycy5hZGQodmFyaWFibGVSZWYpOwotICAgICAgICAgICAgX25lZWRzU29ydFJlY29yZEZhY3RvcnkgPSB0cnVlOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLy8gLS0gRW5kIENsb3N1cmUgaW50ZXJmYWNlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLQotICAgIHByaXZhdGUgdm9pZCBzZXRJbm5lckNsYXNzTmFtZShTdHJpbmcgY2xhc3NOYW1lKSB7Ci0gICAgICAgIF9jbGFzc05hbWUgPSBjbGFzc05hbWU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUGFyc2UgdGhlIGF0dHJpYnV0ZXMgb2YgdGhlIHhzbDpzb3J0IGVsZW1lbnQKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBwYXJzZUNvbnRlbnRzKFBhcnNlciBwYXJzZXIpIHsKLQotICAgICAgICBmaW5hbCBTeW50YXhUcmVlTm9kZSBwYXJlbnQgPSBnZXRQYXJlbnQoKTsKLSAgICAgICAgaWYgKCEocGFyZW50IGluc3RhbmNlb2YgQXBwbHlUZW1wbGF0ZXMpICYmCi0gICAgICAgICAgICAhKHBhcmVudCBpbnN0YW5jZW9mIEZvckVhY2gpKSB7Ci0gICAgICAgICAgICByZXBvcnRFcnJvcih0aGlzLCBwYXJzZXIsIEVycm9yTXNnLlNUUkFZX1NPUlRfRVJSLCBudWxsKTsKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIFBhcnNlIHRoZSBzZWxlY3QgZXhwcmVzc2lvbiAobm9kZSBzdHJpbmcgdmFsdWUgaWYgbm8gZXhwcmVzc2lvbikKLSAgICAgICAgX3NlbGVjdCA9IHBhcnNlci5wYXJzZUV4cHJlc3Npb24odGhpcywgInNlbGVjdCIsICJzdHJpbmcoLikiKTsKLQotICAgICAgICAvLyBHZXQgdGhlIHNvcnQgb3JkZXI7IGRlZmF1bHQgaXMgJ2FzY2VuZGluZycKLSAgICAgICAgU3RyaW5nIHZhbCA9IGdldEF0dHJpYnV0ZSgib3JkZXIiKTsKLSAgICAgICAgaWYgKHZhbC5sZW5ndGgoKSA9PSAwKSB2YWwgPSAiYXNjZW5kaW5nIjsKLSAgICAgICAgX29yZGVyID0gQXR0cmlidXRlVmFsdWUuY3JlYXRlKHRoaXMsIHZhbCwgcGFyc2VyKTsKLQotICAgICAgICAvLyBHZXQgdGhlIHNvcnQgZGF0YSB0eXBlOyBkZWZhdWx0IGlzIHRleHQKLSAgICAgICAgdmFsID0gZ2V0QXR0cmlidXRlKCJkYXRhLXR5cGUiKTsKLSAgICAgICAgaWYgKHZhbC5sZW5ndGgoKSA9PSAwKSB7Ci0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIGZpbmFsIFR5cGUgdHlwZSA9IF9zZWxlY3QudHlwZUNoZWNrKHBhcnNlci5nZXRTeW1ib2xUYWJsZSgpKTsKLSAgICAgICAgICAgICAgICBpZiAodHlwZSBpbnN0YW5jZW9mIEludFR5cGUpCi0gICAgICAgICAgICAgICAgICAgIHZhbCA9ICJudW1iZXIiOwotICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgICAgdmFsID0gInRleHQiOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2F0Y2ggKFR5cGVDaGVja0Vycm9yIGUpIHsKLSAgICAgICAgICAgICAgICB2YWwgPSAidGV4dCI7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgX2RhdGFUeXBlID0gQXR0cmlidXRlVmFsdWUuY3JlYXRlKHRoaXMsIHZhbCwgcGFyc2VyKTsKLQotICAgICAgICAgX2xhbmcgPSAgZ2V0QXR0cmlidXRlKCJsYW5nIik7IC8vIGJ1ZyEgc2VlIDI2ODY5Ci0gIC8vIHZhbCA9ICBnZXRBdHRyaWJ1dGUoImxhbmciKTsKLSAgLy8gX2xhbmcgPSBBdHRyaWJ1dGVWYWx1ZS5jcmVhdGUodGhpcywgdmFsLCBwYXJzZXIpOwotICAgICAgICAvLyBHZXQgdGhlIGNhc2Ugb3JkZXI7IGRlZmF1bHQgaXMgbGFuZ3VhZ2UgZGVwZW5kYW50Ci0gICAgdmFsID0gZ2V0QXR0cmlidXRlKCJjYXNlLW9yZGVyIik7Ci0gICAgX2Nhc2VPcmRlciA9IEF0dHJpYnV0ZVZhbHVlLmNyZWF0ZSh0aGlzLCB2YWwsIHBhcnNlcik7Ci0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSdW4gdHlwZSBjaGVja3Mgb24gdGhlIGF0dHJpYnV0ZXM7IGV4cHJlc3Npb24gbXVzdCByZXR1cm4gYSBzdHJpbmcKLSAgICAgKiB3aGljaCB3ZSB3aWxsIHVzZSBhcyBhIHNvcnQga2V5Ci0gICAgICovCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLSAgICAgICAgZmluYWwgVHlwZSB0c2VsZWN0ID0gX3NlbGVjdC50eXBlQ2hlY2soc3RhYmxlKTsKLQotICAgICAgICAvLyBJZiB0aGUgc29ydCBkYXRhLXR5cGUgaXMgbm90IHNldCB3ZSB1c2UgdGhlIG5hdHVyYWwgZGF0YS10eXBlCi0gICAgICAgIC8vIG9mIHRoZSBkYXRhIHdlIHdpbGwgc29ydAotICAgICAgICBpZiAoISh0c2VsZWN0IGluc3RhbmNlb2YgU3RyaW5nVHlwZSkpIHsKLSAgICAgICAgICAgIF9zZWxlY3QgPSBuZXcgQ2FzdEV4cHIoX3NlbGVjdCwgVHlwZS5TdHJpbmcpOwotICAgICAgICB9Ci0KLSAgICAgICAgX29yZGVyLnR5cGVDaGVjayhzdGFibGUpOwotICAgICAgICBfY2FzZU9yZGVyLnR5cGVDaGVjayhzdGFibGUpOwotICAgICAgICBfZGF0YVR5cGUudHlwZUNoZWNrKHN0YWJsZSk7Ci0gICAgICAgIHJldHVybiBUeXBlLlZvaWQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhlc2UgdHdvIG1ldGhvZHMgYXJlIG5lZWRlZCBpbiB0aGUgc3RhdGljIG1ldGhvZHMgdGhhdCBjb21waWxlIHRoZQotICAgICAqIG92ZXJsb2FkZWQgTm9kZVNvcnRSZWNvcmQuY29tcGFyZVR5cGUoKSBhbmQgTm9kZVNvcnRSZWNvcmQuc29ydE9yZGVyKCkKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVTb3J0VHlwZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0gICAgICAgIF9kYXRhVHlwZS50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlU29ydE9yZGVyKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0gICAgICAgIF9vcmRlci50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgfQotCi0gICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZUNhc2VPcmRlcihDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwKLSAgICAgICAgICAgICAgICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0gICAgX2Nhc2VPcmRlci50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlTGFuZyhDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwKLSAgICAgICAgICAgICAgICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0gICAgZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLSAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBfbGFuZykpOyAvLyBidWchIHNlZSAyNjg2OQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIGNvbXBpbGVzIGNvZGUgZm9yIHRoZSBzZWxlY3QgZXhwcmVzc2lvbiBmb3IgdGhpcwotICAgICAqIHhzbDpzb3J0IGVsZW1lbnQuIFRoZSBtZXRob2QgaXMgY2FsbGVkIGZyb20gdGhlIHN0YXRpYyBjb2RlLWdlbmVyYXRpbmcKLSAgICAgKiBtZXRob2RzIGluIHRoaXMgY2xhc3MuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlU2VsZWN0KENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0gICAgICAgIF9zZWxlY3QudHJhbnNsYXRlKGNsYXNzR2VuLG1ldGhvZEdlbik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2Qgc2hvdWxkIG5vdCBwcm9kdWNlIGFueSBjb2RlCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0gICAgICAgIC8vIGVtcHR5Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29tcGlsZXMgY29kZSB0aGF0IGluc3RhbnRpYXRlcyBhIFNvcnRpbmdJdGVyYXRvciBvYmplY3QuCi0gICAgICogVGhpcyBvYmplY3QncyBjb25zdHJ1Y3RvciBuZWVkcyByZWZlcmVuY2RlcyB0byB0aGUgY3VycmVudCBpdGVyYXRvcgotICAgICAqIGFuZCBhIG5vZGUgc29ydCByZWNvcmQgcHJvZHVjaW5nIG9iamVjdHMgYXMgaXRzIHBhcmFtZXRlcnMuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyB2b2lkIHRyYW5zbGF0ZVNvcnRJdGVyYXRvcihDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRXhwcmVzc2lvbiBub2RlU2V0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWZWN0b3I8U29ydD4gc29ydE9iamVjdHMpCi0gICAgewotICAgICAgICBmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQotICAgICAgICAvLyBTb3J0aW5nSXRlcmF0b3IuU29ydGluZ0l0ZXJhdG9yKE5vZGVJdGVyYXRvcixOb2RlU29ydFJlY29yZEZhY3RvcnkpOwotICAgICAgICBmaW5hbCBpbnQgaW5pdCA9IGNwZy5hZGRNZXRob2RyZWYoU09SVF9JVEVSQVRPUiwgIjxpbml0PiIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKCIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgTk9ERV9JVEVSQVRPUl9TSUcKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgTk9ERV9TT1JUX0ZBQ1RPUllfU0lHCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIpViIpOwotCi0gICAgICAgIC8vIEJhY2t3YXJkcyBicmFuY2hlcyBhcmUgcHJvaGliaXRlZCBpZiBhbiB1bmluaXRpYWxpemVkIG9iamVjdCBpcwotICAgICAgICAvLyBvbiB0aGUgc3RhY2sgYnkgc2VjdGlvbiA0LjkuNCBvZiB0aGUgSlZNIFNwZWNpZmljYXRpb24sIDJuZCBFZC4KLSAgICAgICAgLy8gV2UgZG9uJ3Qga25vdyB3aGV0aGVyIHRoaXMgY29kZSBtaWdodCBjb250YWluIGJhY2t3YXJkcyBicmFuY2hlcwotICAgICAgICAvLyBzbyB3ZSBtdXN0bid0IGNyZWF0ZSB0aGUgbmV3IG9iamVjdCB1bnRpbCBhZnRlciB3ZSd2ZSBjcmVhdGVkCi0gICAgICAgIC8vIHRoZSBzdXNwZWN0IGFyZ3VtZW50cyB0byBpdHMgY29uc3RydWN0b3IuICBJbnN0ZWFkIHdlIGNhbGN1bGF0ZQotICAgICAgICAvLyB0aGUgdmFsdWVzIG9mIHRoZSBhcmd1bWVudHMgdG8gdGhlIGNvbnN0cnVjdG9yIGZpcnN0LCBzdG9yZSB0aGVtCi0gICAgICAgIC8vIGluIHRlbXBvcmFyeSB2YXJpYWJsZXMsIGNyZWF0ZSB0aGUgb2JqZWN0IGFuZCByZWxvYWQgdGhlCi0gICAgICAgIC8vIGFyZ3VtZW50cyBmcm9tIHRoZSB0ZW1wb3JhcmllcyB0byBhdm9pZCB0aGUgcHJvYmxlbS4KLQotICAgICAgICBMb2NhbFZhcmlhYmxlR2VuIG5vZGVzVGVtcCA9Ci0gICAgICAgICAgICBtZXRob2RHZW4uYWRkTG9jYWxWYXJpYWJsZSgic29ydF90bXAxIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFV0aWwuZ2V0SkNSZWZUeXBlKE5PREVfSVRFUkFUT1JfU0lHKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsIG51bGwpOwotCi0gICAgICAgIExvY2FsVmFyaWFibGVHZW4gc29ydFJlY29yZEZhY3RvcnlUZW1wID0KLSAgICAgICAgICAgIG1ldGhvZEdlbi5hZGRMb2NhbFZhcmlhYmxlKCJzb3J0X3RtcDIiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVdGlsLmdldEpDUmVmVHlwZShOT0RFX1NPUlRfRkFDVE9SWV9TSUcpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLCBudWxsKTsKLQotICAgICAgICAvLyBHZXQgdGhlIGN1cnJlbnQgbm9kZSBpdGVyYXRvcgotICAgICAgICBpZiAobm9kZVNldCA9PSBudWxsKSB7ICAvLyBhcHBseS10ZW1wbGF0ZXMgZGVmYXVsdAotICAgICAgICAgICAgZmluYWwgaW50IGNoaWxkcmVuID0gY3BnLmFkZEludGVyZmFjZU1ldGhvZHJlZihET01fSU5URiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImdldEF4aXNJdGVyYXRvciIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoSSkiKwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOT0RFX0lURVJBVE9SX1NJRyk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBBeGlzLkNISUxEKSk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRUlOVEVSRkFDRShjaGlsZHJlbiwgMikpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgbm9kZVNldC50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgIH0KLQotICAgICAgICBub2Rlc1RlbXAuc2V0U3RhcnQoaWwuYXBwZW5kKG5ldyBBU1RPUkUobm9kZXNUZW1wLmdldEluZGV4KCkpKSk7Ci0KLSAgICAgICAgLy8gQ29tcGlsZSB0aGUgY29kZSBmb3IgdGhlIE5vZGVTb3J0UmVjb3JkIHByb2R1Y2luZyBjbGFzcyBhbmQgcGFzcwotICAgICAgICAvLyB0aGF0IGFzIHRoZSBsYXN0IGFyZ3VtZW50IHRvIHRoZSBTb3J0aW5nSXRlcmF0b3IgY29uc3RydWN0b3IuCi0gICAgICAgIGNvbXBpbGVTb3J0UmVjb3JkRmFjdG9yeShzb3J0T2JqZWN0cywgY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgIHNvcnRSZWNvcmRGYWN0b3J5VGVtcC5zZXRTdGFydCgKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQobmV3IEFTVE9SRShzb3J0UmVjb3JkRmFjdG9yeVRlbXAuZ2V0SW5kZXgoKSkpKTsKLQotICAgICAgICBpbC5hcHBlbmQobmV3IE5FVyhjcGcuYWRkQ2xhc3MoU09SVF9JVEVSQVRPUikpKTsKLSAgICAgICAgaWwuYXBwZW5kKERVUCk7Ci0gICAgICAgIG5vZGVzVGVtcC5zZXRFbmQoaWwuYXBwZW5kKG5ldyBBTE9BRChub2Rlc1RlbXAuZ2V0SW5kZXgoKSkpKTsKLSAgICAgICAgc29ydFJlY29yZEZhY3RvcnlUZW1wLnNldEVuZCgKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQobmV3IEFMT0FEKHNvcnRSZWNvcmRGYWN0b3J5VGVtcC5nZXRJbmRleCgpKSkpOwotICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRVNQRUNJQUwoaW5pdCkpOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogQ29tcGlsZXMgY29kZSB0aGF0IGluc3RhbnRpYXRlcyBhIE5vZGVTb3J0UmVjb3JkRmFjdG9yeSBvYmplY3Qgd2hpY2gKLSAgICAgKiB3aWxsIHByb2R1Y2UgTm9kZVNvcnRSZWNvcmQgb2JqZWN0cyBvZiBhIHNwZWNpZmljIHR5cGUuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyB2b2lkIGNvbXBpbGVTb3J0UmVjb3JkRmFjdG9yeShWZWN0b3I8U29ydD4gc29ydE9iamVjdHMsCi0gICAgICAgIENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKQotICAgIHsKLSAgICAgICAgU3RyaW5nIHNvcnRSZWNvcmRDbGFzcyA9Ci0gICAgICAgICAgICBjb21waWxlU29ydFJlY29yZChzb3J0T2JqZWN0cywgY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0KLSAgICAgICAgYm9vbGVhbiBuZWVkc1NvcnRSZWNvcmRGYWN0b3J5ID0gZmFsc2U7Ci0gICAgICAgIGZpbmFsIGludCBuc29ydHMgPSBzb3J0T2JqZWN0cy5zaXplKCk7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnNvcnRzOyBpKyspIHsKLSAgICAgICAgICAgIGZpbmFsIFNvcnQgc29ydCA9IHNvcnRPYmplY3RzLmVsZW1lbnRBdChpKTsKLSAgICAgICAgICAgIG5lZWRzU29ydFJlY29yZEZhY3RvcnkgfD0gc29ydC5fbmVlZHNTb3J0UmVjb3JkRmFjdG9yeTsKLSAgICAgICAgfQotCi0gICAgICAgIFN0cmluZyBzb3J0UmVjb3JkRmFjdG9yeUNsYXNzID0gTk9ERV9TT1JUX0ZBQ1RPUlk7Ci0gICAgICAgIGlmIChuZWVkc1NvcnRSZWNvcmRGYWN0b3J5KSB7Ci0gICAgICAgICAgICBzb3J0UmVjb3JkRmFjdG9yeUNsYXNzID0KLSAgICAgICAgICAgICAgICBjb21waWxlU29ydFJlY29yZEZhY3Rvcnkoc29ydE9iamVjdHMsIGNsYXNzR2VuLCBtZXRob2RHZW4sCi0gICAgICAgICAgICAgICAgICAgIHNvcnRSZWNvcmRDbGFzcyk7Ci0gICAgICAgIH0KLQotICAgICAgICBmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQotICAgICAgICAvLyBCYWNrd2FyZHMgYnJhbmNoZXMgYXJlIHByb2hpYml0ZWQgaWYgYW4gdW5pbml0aWFsaXplZCBvYmplY3QgaXMKLSAgICAgICAgLy8gb24gdGhlIHN0YWNrIGJ5IHNlY3Rpb24gNC45LjQgb2YgdGhlIEpWTSBTcGVjaWZpY2F0aW9uLCAybmQgRWQuCi0gICAgICAgIC8vIFdlIGRvbid0IGtub3cgd2hldGhlciB0aGlzIGNvZGUgbWlnaHQgY29udGFpbiBiYWNrd2FyZHMgYnJhbmNoZXMKLSAgICAgICAgLy8gc28gd2UgbXVzdG4ndCBjcmVhdGUgdGhlIG5ldyBvYmplY3QgdW50aWwgYWZ0ZXIgd2UndmUgY3JlYXRlZAotICAgICAgICAvLyB0aGUgc3VzcGVjdCBhcmd1bWVudHMgdG8gaXRzIGNvbnN0cnVjdG9yLiAgSW5zdGVhZCB3ZSBjYWxjdWxhdGUKLSAgICAgICAgLy8gdGhlIHZhbHVlcyBvZiB0aGUgYXJndW1lbnRzIHRvIHRoZSBjb25zdHJ1Y3RvciBmaXJzdCwgc3RvcmUgdGhlbQotICAgICAgICAvLyBpbiB0ZW1wb3JhcnkgdmFyaWFibGVzLCBjcmVhdGUgdGhlIG9iamVjdCBhbmQgcmVsb2FkIHRoZQotICAgICAgICAvLyBhcmd1bWVudHMgZnJvbSB0aGUgdGVtcG9yYXJpZXMgdG8gYXZvaWQgdGhlIHByb2JsZW0uCi0KLSAgICAgICAgLy8gQ29tcGlsZSBjb2RlIHRoYXQgaW5pdGlhbGl6ZXMgdGhlIHN0YXRpYyBfc29ydE9yZGVyCi0gICAgICAgIExvY2FsVmFyaWFibGVHZW4gc29ydE9yZGVyVGVtcAotICAgICAgICAgICAgICAgICA9IG1ldGhvZEdlbi5hZGRMb2NhbFZhcmlhYmxlKCJzb3J0X29yZGVyX3RtcCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFV0aWwuZ2V0SkNSZWZUeXBlKCJbIiArIFNUUklOR19TSUcpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLCBudWxsKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgbnNvcnRzKSk7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgQU5FV0FSUkFZKGNwZy5hZGRDbGFzcyhTVFJJTkcpKSk7Ci0gICAgICAgIGZvciAoaW50IGxldmVsID0gMDsgbGV2ZWwgPCBuc29ydHM7IGxldmVsKyspIHsKLSAgICAgICAgICAgIGZpbmFsIFNvcnQgc29ydCA9IChTb3J0KXNvcnRPYmplY3RzLmVsZW1lbnRBdChsZXZlbCk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQoRFVQKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsIGxldmVsKSk7Ci0gICAgICAgICAgICBzb3J0LnRyYW5zbGF0ZVNvcnRPcmRlcihjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChBQVNUT1JFKTsKLSAgICAgICAgfQotICAgICAgICBzb3J0T3JkZXJUZW1wLnNldFN0YXJ0KGlsLmFwcGVuZChuZXcgQVNUT1JFKHNvcnRPcmRlclRlbXAuZ2V0SW5kZXgoKSkpKTsKLQotICAgICAgICBMb2NhbFZhcmlhYmxlR2VuIHNvcnRUeXBlVGVtcAotICAgICAgICAgICAgICAgICA9IG1ldGhvZEdlbi5hZGRMb2NhbFZhcmlhYmxlKCJzb3J0X3R5cGVfdG1wIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVXRpbC5nZXRKQ1JlZlR5cGUoIlsiICsgU1RSSU5HX1NJRyksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsIG51bGwpOwotICAgICAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBuc29ydHMpKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBBTkVXQVJSQVkoY3BnLmFkZENsYXNzKFNUUklORykpKTsKLSAgICAgICAgZm9yIChpbnQgbGV2ZWwgPSAwOyBsZXZlbCA8IG5zb3J0czsgbGV2ZWwrKykgewotICAgICAgICAgICAgZmluYWwgU29ydCBzb3J0ID0gKFNvcnQpc29ydE9iamVjdHMuZWxlbWVudEF0KGxldmVsKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChEVVApOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgbGV2ZWwpKTsKLSAgICAgICAgICAgIHNvcnQudHJhbnNsYXRlU29ydFR5cGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgICAgICBpbC5hcHBlbmQoQUFTVE9SRSk7Ci0gICAgICAgIH0KLSAgICAgICAgc29ydFR5cGVUZW1wLnNldFN0YXJ0KGlsLmFwcGVuZChuZXcgQVNUT1JFKHNvcnRUeXBlVGVtcC5nZXRJbmRleCgpKSkpOwotCi0gICAgICAgIExvY2FsVmFyaWFibGVHZW4gc29ydExhbmdUZW1wCi0gICAgICAgICAgICAgICAgID0gbWV0aG9kR2VuLmFkZExvY2FsVmFyaWFibGUoInNvcnRfbGFuZ190bXAiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVdGlsLmdldEpDUmVmVHlwZSgiWyIgKyBTVFJJTkdfU0lHKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwgbnVsbCk7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsIG5zb3J0cykpOwotICAgICAgICBpbC5hcHBlbmQobmV3IEFORVdBUlJBWShjcGcuYWRkQ2xhc3MoU1RSSU5HKSkpOwotICAgICAgICBmb3IgKGludCBsZXZlbCA9IDA7IGxldmVsIDwgbnNvcnRzOyBsZXZlbCsrKSB7Ci0gICAgICAgICAgICAgIGZpbmFsIFNvcnQgc29ydCA9IChTb3J0KXNvcnRPYmplY3RzLmVsZW1lbnRBdChsZXZlbCk7Ci0gICAgICAgICAgICAgIGlsLmFwcGVuZChEVVApOwotICAgICAgICAgICAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBsZXZlbCkpOwotICAgICAgICAgICAgICBzb3J0LnRyYW5zbGF0ZUxhbmcoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgICAgICAgIGlsLmFwcGVuZChBQVNUT1JFKTsKLSAgICAgICAgfQotICAgICAgICBzb3J0TGFuZ1RlbXAuc2V0U3RhcnQoaWwuYXBwZW5kKG5ldyBBU1RPUkUoc29ydExhbmdUZW1wLmdldEluZGV4KCkpKSk7Ci0KLSAgICAgICAgTG9jYWxWYXJpYWJsZUdlbiBzb3J0Q2FzZU9yZGVyVGVtcAotICAgICAgICAgICAgICAgICA9IG1ldGhvZEdlbi5hZGRMb2NhbFZhcmlhYmxlKCJzb3J0X2Nhc2Vfb3JkZXJfdG1wIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVXRpbC5nZXRKQ1JlZlR5cGUoIlsiICsgU1RSSU5HX1NJRyksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsIG51bGwpOwotICAgICAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBuc29ydHMpKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBBTkVXQVJSQVkoY3BnLmFkZENsYXNzKFNUUklORykpKTsKLSAgICAgICAgZm9yIChpbnQgbGV2ZWwgPSAwOyBsZXZlbCA8IG5zb3J0czsgbGV2ZWwrKykgewotICAgICAgICAgICAgZmluYWwgU29ydCBzb3J0ID0gKFNvcnQpc29ydE9iamVjdHMuZWxlbWVudEF0KGxldmVsKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChEVVApOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgbGV2ZWwpKTsKLSAgICAgICAgICAgIHNvcnQudHJhbnNsYXRlQ2FzZU9yZGVyKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICAgICAgaWwuYXBwZW5kKEFBU1RPUkUpOwotICAgICAgICB9Ci0gICAgICAgIHNvcnRDYXNlT3JkZXJUZW1wLnNldFN0YXJ0KAotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgQVNUT1JFKHNvcnRDYXNlT3JkZXJUZW1wLmdldEluZGV4KCkpKSk7Ci0KLSAgICAgICAgaWwuYXBwZW5kKG5ldyBORVcoY3BnLmFkZENsYXNzKHNvcnRSZWNvcmRGYWN0b3J5Q2xhc3MpKSk7Ci0gICAgICAgIGlsLmFwcGVuZChEVVApOwotICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsIHNvcnRSZWNvcmRDbGFzcykpOwotICAgICAgICBpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpOwotCi0gICAgICAgIHNvcnRPcmRlclRlbXAuc2V0RW5kKGlsLmFwcGVuZChuZXcgQUxPQUQoc29ydE9yZGVyVGVtcC5nZXRJbmRleCgpKSkpOwotICAgICAgICBzb3J0VHlwZVRlbXAuc2V0RW5kKGlsLmFwcGVuZChuZXcgQUxPQUQoc29ydFR5cGVUZW1wLmdldEluZGV4KCkpKSk7Ci0gICAgICAgIHNvcnRMYW5nVGVtcC5zZXRFbmQoaWwuYXBwZW5kKG5ldyBBTE9BRChzb3J0TGFuZ1RlbXAuZ2V0SW5kZXgoKSkpKTsKLSAgICAgICAgc29ydENhc2VPcmRlclRlbXAuc2V0RW5kKAotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgQUxPQUQoc29ydENhc2VPcmRlclRlbXAuZ2V0SW5kZXgoKSkpKTsKLQotICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRVNQRUNJQUwoCi0gICAgICAgICAgICBjcGcuYWRkTWV0aG9kcmVmKHNvcnRSZWNvcmRGYWN0b3J5Q2xhc3MsICI8aW5pdD4iLAotICAgICAgICAgICAgICAgICIoIiArIERPTV9JTlRGX1NJRwotICAgICAgICAgICAgICAgICAgICArIFNUUklOR19TSUcKLSAgICAgICAgICAgICAgICAgICAgKyBUUkFOU0xFVF9JTlRGX1NJRwotICAgICAgICAgICAgICAgICAgICArICJbIiArIFNUUklOR19TSUcKLSAgICAgICAgICAgICAgICAgICAgKyAiWyIgKyBTVFJJTkdfU0lHCi0gICAgICAgICAgICAgICAgICAgICsgIlsiICsgU1RSSU5HX1NJRwotICAgICAgICAgICAgICAgICAgICArICJbIiArIFNUUklOR19TSUcgKyAiKVYiKSkpOwotCi0gICAgICAgIC8vIEluaXRpYWxpemUgY2xvc3VyZSB2YXJpYWJsZXMgaW4gc29ydFJlY29yZEZhY3RvcnkKLSAgICAgICAgZmluYWwgQXJyYXlMaXN0PFZhcmlhYmxlUmVmQmFzZT4gZHVwcyA9IG5ldyBBcnJheUxpc3Q8PigpOwotCi0gICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgbnNvcnRzOyBqKyspIHsKLSAgICAgICAgICAgIGZpbmFsIFNvcnQgc29ydCA9IChTb3J0KSBzb3J0T2JqZWN0cy5nZXQoaik7Ci0gICAgICAgICAgICBmaW5hbCBpbnQgbGVuZ3RoID0gKHNvcnQuX2Nsb3N1cmVWYXJzID09IG51bGwpID8gMCA6Ci0gICAgICAgICAgICAgICAgc29ydC5fY2xvc3VyZVZhcnMuc2l6ZSgpOwotCi0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgVmFyaWFibGVSZWZCYXNlIHZhclJlZiA9IHNvcnQuX2Nsb3N1cmVWYXJzLmdldChpKTsKLQotICAgICAgICAgICAgICAgIC8vIERpc2NhcmQgZHVwbGljYXRlIHZhcmlhYmxlIHJlZmVyZW5jZXMKLSAgICAgICAgICAgICAgICBpZiAoZHVwcy5jb250YWlucyh2YXJSZWYpKSBjb250aW51ZTsKLQotICAgICAgICAgICAgICAgIGZpbmFsIFZhcmlhYmxlQmFzZSB2YXIgPSB2YXJSZWYuZ2V0VmFyaWFibGUoKTsKLQotICAgICAgICAgICAgICAgIC8vIFN0b3JlIHZhcmlhYmxlIGluIG5ldyBjbG9zdXJlCi0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKERVUCk7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKHZhci5sb2FkSW5zdHJ1Y3Rpb24oKSk7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBQVVRGSUVMRCgKLSAgICAgICAgICAgICAgICAgICAgICAgIGNwZy5hZGRGaWVsZHJlZihzb3J0UmVjb3JkRmFjdG9yeUNsYXNzLCB2YXIuZ2V0RXNjYXBlZE5hbWUoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIuZ2V0VHlwZSgpLnRvU2lnbmF0dXJlKCkpKSk7Ci0gICAgICAgICAgICAgICAgZHVwcy5hZGQodmFyUmVmKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGNvbXBpbGVTb3J0UmVjb3JkRmFjdG9yeShWZWN0b3I8U29ydD4gc29ydE9iamVjdHMsCi0gICAgICAgIENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLAotICAgICAgICBTdHJpbmcgc29ydFJlY29yZENsYXNzKQotICAgIHsKLSAgICAgICAgZmluYWwgWFNMVEMgeHNsdGMgPSAoc29ydE9iamVjdHMuZmlyc3RFbGVtZW50KCkpLmdldFhTTFRDKCk7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBjbGFzc05hbWUgPSB4c2x0Yy5nZXRIZWxwZXJDbGFzc05hbWUoKTsKLQotICAgICAgICBmaW5hbCBOb2RlU29ydFJlY29yZEZhY3RHZW5lcmF0b3Igc29ydFJlY29yZEZhY3RvcnkgPQotICAgICAgICAgICAgbmV3IE5vZGVTb3J0UmVjb3JkRmFjdEdlbmVyYXRvcihjbGFzc05hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTk9ERV9TT1JUX0ZBQ1RPUlksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lICsgIi5qYXZhIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBQ0NfUFVCTElDIHwgQUNDX1NVUEVSIHwgQUNDX0ZJTkFMLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7fSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzc0dlbi5nZXRTdHlsZXNoZWV0KCkpOwotCi0gICAgICAgIENvbnN0YW50UG9vbEdlbiBjcGcgPSBzb3J0UmVjb3JkRmFjdG9yeS5nZXRDb25zdGFudFBvb2woKTsKLQotICAgICAgICAvLyBBZGQgYSBuZXcgaW5zdGFuY2UgdmFyaWFibGUgZm9yIGVhY2ggdmFyIGluIGNsb3N1cmUKLSAgICAgICAgZmluYWwgaW50IG5zb3J0cyA9IHNvcnRPYmplY3RzLnNpemUoKTsKLSAgICAgICAgZmluYWwgQXJyYXlMaXN0PFZhcmlhYmxlUmVmQmFzZT4gZHVwcyA9IG5ldyBBcnJheUxpc3Q8PigpOwotCi0gICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgbnNvcnRzOyBqKyspIHsKLSAgICAgICAgICAgIGZpbmFsIFNvcnQgc29ydCA9IHNvcnRPYmplY3RzLmdldChqKTsKLSAgICAgICAgICAgIGZpbmFsIGludCBsZW5ndGggPSAoc29ydC5fY2xvc3VyZVZhcnMgPT0gbnVsbCkgPyAwIDoKLSAgICAgICAgICAgICAgICBzb3J0Ll9jbG9zdXJlVmFycy5zaXplKCk7Ci0KLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgICAgICBmaW5hbCBWYXJpYWJsZVJlZkJhc2UgdmFyUmVmID0gc29ydC5fY2xvc3VyZVZhcnMuZ2V0KGkpOwotCi0gICAgICAgICAgICAgICAgLy8gRGlzY2FyZCBkdXBsaWNhdGUgdmFyaWFibGUgcmVmZXJlbmNlcwotICAgICAgICAgICAgICAgIGlmIChkdXBzLmNvbnRhaW5zKHZhclJlZikpIGNvbnRpbnVlOwotCi0gICAgICAgICAgICAgICAgZmluYWwgVmFyaWFibGVCYXNlIHZhciA9IHZhclJlZi5nZXRWYXJpYWJsZSgpOwotICAgICAgICAgICAgICAgIHNvcnRSZWNvcmRGYWN0b3J5LmFkZEZpZWxkKG5ldyBGaWVsZChBQ0NfUFVCTElDLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNwZy5hZGRVdGY4KHZhci5nZXRFc2NhcGVkTmFtZSgpKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjcGcuYWRkVXRmOCh2YXIuZ2V0VHlwZSgpLnRvU2lnbmF0dXJlKCkpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsIGNwZy5nZXRDb25zdGFudFBvb2woKSkpOwotICAgICAgICAgICAgICAgIGR1cHMuYWRkKHZhclJlZik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBEZWZpbmUgYSBjb25zdHJ1Y3RvciBmb3IgdGhpcyBjbGFzcwotICAgICAgICBmaW5hbCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlR5cGVbXSBhcmdUeXBlcyA9Ci0gICAgICAgICAgICBuZXcgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5UeXBlWzddOwotICAgICAgICBhcmdUeXBlc1swXSA9IFV0aWwuZ2V0SkNSZWZUeXBlKERPTV9JTlRGX1NJRyk7Ci0gICAgICAgIGFyZ1R5cGVzWzFdID0gVXRpbC5nZXRKQ1JlZlR5cGUoU1RSSU5HX1NJRyk7Ci0gICAgICAgIGFyZ1R5cGVzWzJdID0gVXRpbC5nZXRKQ1JlZlR5cGUoVFJBTlNMRVRfSU5URl9TSUcpOwotICAgICAgICBhcmdUeXBlc1szXSA9IFV0aWwuZ2V0SkNSZWZUeXBlKCJbIiArIFNUUklOR19TSUcpOwotICAgICAgICBhcmdUeXBlc1s0XSA9IFV0aWwuZ2V0SkNSZWZUeXBlKCJbIiArIFNUUklOR19TSUcpOwotICBhcmdUeXBlc1s1XSA9IFV0aWwuZ2V0SkNSZWZUeXBlKCJbIiArIFNUUklOR19TSUcpOwotICBhcmdUeXBlc1s2XSA9IFV0aWwuZ2V0SkNSZWZUeXBlKCJbIiArIFNUUklOR19TSUcpOwotCi0gICAgICAgIGZpbmFsIFN0cmluZ1tdIGFyZ05hbWVzID0gbmV3IFN0cmluZ1s3XTsKLSAgICAgICAgYXJnTmFtZXNbMF0gPSBET0NVTUVOVF9QTkFNRTsKLSAgICAgICAgYXJnTmFtZXNbMV0gPSAiY2xhc3NOYW1lIjsKLSAgICAgICAgYXJnTmFtZXNbMl0gPSBUUkFOU0xFVF9QTkFNRTsKLSAgICAgICAgYXJnTmFtZXNbM10gPSAib3JkZXIiOwotICAgICAgICBhcmdOYW1lc1s0XSA9ICJ0eXBlIjsKLSAgYXJnTmFtZXNbNV0gPSAibGFuZyI7Ci0gIGFyZ05hbWVzWzZdID0gImNhc2Vfb3JkZXIiOwotCi0KLSAgICAgICAgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbmV3IEluc3RydWN0aW9uTGlzdCgpOwotICAgICAgICBmaW5hbCBNZXRob2RHZW5lcmF0b3IgY29uc3RydWN0b3IgPQotICAgICAgICAgICAgbmV3IE1ldGhvZEdlbmVyYXRvcihBQ0NfUFVCTElDLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlR5cGUuVk9JRCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJnVHlwZXMsIGFyZ05hbWVzLCAiPGluaXQ+IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lLCBpbCwgY3BnKTsKLQotICAgICAgICAvLyBQdXNoIGFsbCBwYXJhbWV0ZXJzIG9udG8gdGhlIHN0YWNrIGFuZCBjYWxsZWQgc3VwZXIuPGluaXQ+KCkKLSAgICAgICAgaWwuYXBwZW5kKEFMT0FEXzApOwotICAgICAgICBpbC5hcHBlbmQoQUxPQURfMSk7Ci0gICAgICAgIGlsLmFwcGVuZChBTE9BRF8yKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBBTE9BRCgzKSk7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgQUxPQUQoNCkpOwotICAgICAgICBpbC5hcHBlbmQobmV3IEFMT0FEKDUpKTsKLSAgaWwuYXBwZW5kKG5ldyBBTE9BRCg2KSk7Ci0gIGlsLmFwcGVuZChuZXcgQUxPQUQoNykpOwotICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRVNQRUNJQUwoY3BnLmFkZE1ldGhvZHJlZihOT0RFX1NPUlRfRkFDVE9SWSwKLSAgICAgICAgICAgICI8aW5pdD4iLAotICAgICAgICAgICAgIigiICsgRE9NX0lOVEZfU0lHCi0gICAgICAgICAgICAgICAgKyBTVFJJTkdfU0lHCi0gICAgICAgICAgICAgICAgKyBUUkFOU0xFVF9JTlRGX1NJRwotICAgICAgICAgICAgICAgICsgIlsiICsgU1RSSU5HX1NJRwotICAgICsgIlsiICsgU1RSSU5HX1NJRwotICAgICsgIlsiICsgU1RSSU5HX1NJRwotICAgICAgICAgICAgICAgICsgIlsiICsgU1RSSU5HX1NJRyArICIpViIpKSk7Ci0gICAgICAgIGlsLmFwcGVuZChSRVRVUk4pOwotCi0gICAgICAgIC8vIE92ZXJyaWRlIHRoZSBkZWZpbml0aW9uIG9mIG1ha2VOb2RlU29ydFJlY29yZCgpCi0gICAgICAgIGlsID0gbmV3IEluc3RydWN0aW9uTGlzdCgpOwotICAgICAgICBmaW5hbCBNZXRob2RHZW5lcmF0b3IgbWFrZU5vZGVTb3J0UmVjb3JkID0KLSAgICAgICAgICAgIG5ldyBNZXRob2RHZW5lcmF0b3IoQUNDX1BVQkxJQywKLSAgICAgICAgICAgICAgICBVdGlsLmdldEpDUmVmVHlwZShOT0RFX1NPUlRfUkVDT1JEX1NJRyksCi0gICAgICAgICAgICAgICAgbmV3IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuVHlwZVtdIHsKLSAgICAgICAgICAgICAgICAgICAgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5UeXBlLklOVCwKLSAgICAgICAgICAgICAgICAgICAgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5UeXBlLklOVCB9LAotICAgICAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7ICJub2RlIiwgImxhc3QiIH0sICJtYWtlTm9kZVNvcnRSZWNvcmQiLAotICAgICAgICAgICAgICAgIGNsYXNzTmFtZSwgaWwsIGNwZyk7Ci0KLSAgICAgICAgaWwuYXBwZW5kKEFMT0FEXzApOwotICAgICAgICBpbC5hcHBlbmQoSUxPQURfMSk7Ci0gICAgICAgIGlsLmFwcGVuZChJTE9BRF8yKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VTUEVDSUFMKGNwZy5hZGRNZXRob2RyZWYoTk9ERV9TT1JUX0ZBQ1RPUlksCi0gICAgICAgICAgICAibWFrZU5vZGVTb3J0UmVjb3JkIiwgIihJSSkiICsgTk9ERV9TT1JUX1JFQ09SRF9TSUcpKSk7Ci0gICAgICAgIGlsLmFwcGVuZChEVVApOwotICAgICAgICBpbC5hcHBlbmQobmV3IENIRUNLQ0FTVChjcGcuYWRkQ2xhc3Moc29ydFJlY29yZENsYXNzKSkpOwotCi0gICAgICAgIC8vIEluaXRpYWxpemUgY2xvc3VyZSBpbiByZWNvcmQgY2xhc3MKLSAgICAgICAgZmluYWwgaW50IG5kdXBzID0gZHVwcy5zaXplKCk7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbmR1cHM7IGkrKykgewotICAgICAgICAgICAgZmluYWwgVmFyaWFibGVSZWZCYXNlIHZhclJlZiA9IChWYXJpYWJsZVJlZkJhc2UpIGR1cHMuZ2V0KGkpOwotICAgICAgICAgICAgZmluYWwgVmFyaWFibGVCYXNlIHZhciA9IHZhclJlZi5nZXRWYXJpYWJsZSgpOwotICAgICAgICAgICAgZmluYWwgVHlwZSB2YXJUeXBlID0gdmFyLmdldFR5cGUoKTsKLQotICAgICAgICAgICAgaWwuYXBwZW5kKERVUCk7Ci0KLSAgICAgICAgICAgIC8vIEdldCBmaWVsZCBmcm9tIGZhY3RvcnkgY2xhc3MKLSAgICAgICAgICAgIGlsLmFwcGVuZChBTE9BRF8wKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgR0VURklFTEQoCi0gICAgICAgICAgICAgICAgY3BnLmFkZEZpZWxkcmVmKGNsYXNzTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgdmFyLmdldEVzY2FwZWROYW1lKCksIHZhclR5cGUudG9TaWduYXR1cmUoKSkpKTsKLQotICAgICAgICAgICAgLy8gUHV0IGZpZWxkIGluIHJlY29yZCBjbGFzcwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBQVVRGSUVMRCgKLSAgICAgICAgICAgICAgICBjcGcuYWRkRmllbGRyZWYoc29ydFJlY29yZENsYXNzLAotICAgICAgICAgICAgICAgICAgICB2YXIuZ2V0RXNjYXBlZE5hbWUoKSwgdmFyVHlwZS50b1NpZ25hdHVyZSgpKSkpOwotICAgICAgICB9Ci0gICAgICAgIGlsLmFwcGVuZChQT1ApOwotICAgICAgICBpbC5hcHBlbmQoQVJFVFVSTik7Ci0KLSAgICAgICAgY29uc3RydWN0b3Iuc2V0TWF4TG9jYWxzKCk7Ci0gICAgICAgIGNvbnN0cnVjdG9yLnNldE1heFN0YWNrKCk7Ci0gICAgICAgIHNvcnRSZWNvcmRGYWN0b3J5LmFkZE1ldGhvZChjb25zdHJ1Y3Rvcik7Ci0gICAgICAgIG1ha2VOb2RlU29ydFJlY29yZC5zZXRNYXhMb2NhbHMoKTsKLSAgICAgICAgbWFrZU5vZGVTb3J0UmVjb3JkLnNldE1heFN0YWNrKCk7Ci0gICAgICAgIHNvcnRSZWNvcmRGYWN0b3J5LmFkZE1ldGhvZChtYWtlTm9kZVNvcnRSZWNvcmQpOwotICAgICAgICB4c2x0Yy5kdW1wQ2xhc3Moc29ydFJlY29yZEZhY3RvcnkuZ2V0SmF2YUNsYXNzKCkpOwotCi0gICAgICAgIHJldHVybiBjbGFzc05hbWU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlIGEgbmV3IGF1eGlsbGFyeSBjbGFzcyBleHRlbmRpbmcgTm9kZVNvcnRSZWNvcmQuCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGNvbXBpbGVTb3J0UmVjb3JkKFZlY3RvcjxTb3J0PiBzb3J0T2JqZWN0cywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLSAgICAgICAgZmluYWwgWFNMVEMgIHhzbHRjID0gc29ydE9iamVjdHMuZmlyc3RFbGVtZW50KCkuZ2V0WFNMVEMoKTsKLSAgICAgICAgZmluYWwgU3RyaW5nIGNsYXNzTmFtZSA9IHhzbHRjLmdldEhlbHBlckNsYXNzTmFtZSgpOwotCi0gICAgICAgIC8vIFRoaXMgZ2VuZXJhdGVzIGEgbmV3IGNsYXNzIGZvciBoYW5kbGluZyB0aGlzIHNwZWNpZmljIHNvcnQKLSAgICAgICAgZmluYWwgTm9kZVNvcnRSZWNvcmRHZW5lcmF0b3Igc29ydFJlY29yZCA9Ci0gICAgICAgICAgICBuZXcgTm9kZVNvcnRSZWNvcmRHZW5lcmF0b3IoY2xhc3NOYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5PREVfU09SVF9SRUNPUkQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInNvcnQkMC5qYXZhIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBQ0NfUFVCTElDIHwgQUNDX1NVUEVSIHwgQUNDX0ZJTkFMLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7fSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzc0dlbi5nZXRTdHlsZXNoZWV0KCkpOwotCi0gICAgICAgIGZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBzb3J0UmVjb3JkLmdldENvbnN0YW50UG9vbCgpOwotCi0gICAgICAgIC8vIEFkZCBhIG5ldyBpbnN0YW5jZSB2YXJpYWJsZSBmb3IgZWFjaCB2YXIgaW4gY2xvc3VyZQotICAgICAgICBmaW5hbCBpbnQgbnNvcnRzID0gc29ydE9iamVjdHMuc2l6ZSgpOwotICAgICAgICBmaW5hbCBBcnJheUxpc3Q8VmFyaWFibGVSZWZCYXNlPiBkdXBzID0gbmV3IEFycmF5TGlzdDw+KCk7Ci0KLSAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBuc29ydHM7IGorKykgewotICAgICAgICAgICAgZmluYWwgU29ydCBzb3J0ID0gc29ydE9iamVjdHMuZ2V0KGopOwotCi0gICAgICAgICAgICAvLyBTZXQgdGhlIG5hbWUgb2YgdGhlIGlubmVyIGNsYXNzIGluIHRoaXMgc29ydCBvYmplY3QKLSAgICAgICAgICAgIHNvcnQuc2V0SW5uZXJDbGFzc05hbWUoY2xhc3NOYW1lKTsKLQotICAgICAgICAgICAgZmluYWwgaW50IGxlbmd0aCA9IChzb3J0Ll9jbG9zdXJlVmFycyA9PSBudWxsKSA/IDAgOgotICAgICAgICAgICAgICAgIHNvcnQuX2Nsb3N1cmVWYXJzLnNpemUoKTsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgICAgICBmaW5hbCBWYXJpYWJsZVJlZkJhc2UgdmFyUmVmID0gKFZhcmlhYmxlUmVmQmFzZSkgc29ydC5fY2xvc3VyZVZhcnMuZ2V0KGkpOwotCi0gICAgICAgICAgICAgICAgLy8gRGlzY2FyZCBkdXBsaWNhdGUgdmFyaWFibGUgcmVmZXJlbmNlcwotICAgICAgICAgICAgICAgIGlmIChkdXBzLmNvbnRhaW5zKHZhclJlZikpIGNvbnRpbnVlOwotCi0gICAgICAgICAgICAgICAgZmluYWwgVmFyaWFibGVCYXNlIHZhciA9IHZhclJlZi5nZXRWYXJpYWJsZSgpOwotICAgICAgICAgICAgICAgIHNvcnRSZWNvcmQuYWRkRmllbGQobmV3IEZpZWxkKEFDQ19QVUJMSUMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjcGcuYWRkVXRmOCh2YXIuZ2V0RXNjYXBlZE5hbWUoKSksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjcGcuYWRkVXRmOCh2YXIuZ2V0VHlwZSgpLnRvU2lnbmF0dXJlKCkpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwgY3BnLmdldENvbnN0YW50UG9vbCgpKSk7Ci0gICAgICAgICAgICAgICAgZHVwcy5hZGQodmFyUmVmKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIE1ldGhvZEdlbmVyYXRvciBpbml0ID0gY29tcGlsZUluaXQoc29ydFJlY29yZCwgY3BnLCBjbGFzc05hbWUpOwotICAgICAgICBNZXRob2RHZW5lcmF0b3IgZXh0cmFjdCA9IGNvbXBpbGVFeHRyYWN0KHNvcnRPYmplY3RzLCBzb3J0UmVjb3JkLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNwZywgY2xhc3NOYW1lKTsKLSAgICAgICAgc29ydFJlY29yZC5hZGRNZXRob2QoaW5pdCk7Ci0gICAgICAgIHNvcnRSZWNvcmQuYWRkTWV0aG9kKGV4dHJhY3QpOwotCi0gICAgICAgIHhzbHRjLmR1bXBDbGFzcyhzb3J0UmVjb3JkLmdldEphdmFDbGFzcygpKTsKLSAgICAgICAgcmV0dXJuIGNsYXNzTmFtZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGUgYSBjb25zdHJ1Y3RvciBmb3IgdGhlIG5ldyBjbGFzcy4gVXBkYXRlcyB0aGUgcmVmZXJlbmNlIHRvIHRoZQotICAgICAqIGNvbGxhdG9yIGluIHRoZSBzdXBlciBjYWxscyBvbmx5IHdoZW4gdGhlIHN0eWxlc2hlZXQgc3BlY2lmaWVzIGEgbmV3Ci0gICAgICogbGFuZ3VhZ2UgaW4geHNsOnNvcnQuCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgTWV0aG9kR2VuZXJhdG9yIGNvbXBpbGVJbml0KE5vZGVTb3J0UmVjb3JkR2VuZXJhdG9yIHNvcnRSZWNvcmQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29uc3RhbnRQb29sR2VuIGNwZywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgY2xhc3NOYW1lKQotICAgIHsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbmV3IEluc3RydWN0aW9uTGlzdCgpOwotICAgICAgICBmaW5hbCBNZXRob2RHZW5lcmF0b3IgaW5pdCA9Ci0gICAgICAgICAgICBuZXcgTWV0aG9kR2VuZXJhdG9yKEFDQ19QVUJMSUMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuVHlwZS5WT0lELAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLCBudWxsLCAiPGluaXQ+IiwgY2xhc3NOYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbCwgY3BnKTsKLQotICAgICAgICAvLyBDYWxsIHRoZSBjb25zdHJ1Y3RvciBpbiB0aGUgTm9kZVNvcnRSZWNvcmQgc3VwZXJjbGFzcwotICAgICAgICBpbC5hcHBlbmQoQUxPQURfMCk7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFU1BFQ0lBTChjcGcuYWRkTWV0aG9kcmVmKE5PREVfU09SVF9SRUNPUkQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI8aW5pdD4iLCAiKClWIikpKTsKLQotCi0KLSAgICAgICAgaWwuYXBwZW5kKFJFVFVSTik7Ci0KLSAgICAgICAgcmV0dXJuIGluaXQ7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBDb21waWxlcyBhIG1ldGhvZCB0aGF0IG92ZXJsb2FkcyBOb2RlU29ydFJlY29yZC5leHRyYWN0VmFsdWVGcm9tRE9NKCkKLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBNZXRob2RHZW5lcmF0b3IgY29tcGlsZUV4dHJhY3QoVmVjdG9yPFNvcnQ+IHNvcnRPYmplY3RzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOb2RlU29ydFJlY29yZEdlbmVyYXRvciBzb3J0UmVjb3JkLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb25zdGFudFBvb2xHZW4gY3BnLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgY2xhc3NOYW1lKSB7Ci0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG5ldyBJbnN0cnVjdGlvbkxpc3QoKTsKLQotICAgICAgICAvLyBTdHJpbmcgTm9kZVNvcnRSZWNvcmQuZXh0cmFjdFZhbHVlRnJvbURPTShkb20sbm9kZSxsZXZlbCk7Ci0gICAgICAgIGZpbmFsIENvbXBhcmVHZW5lcmF0b3IgZXh0cmFjdE1ldGhvZCA9Ci0gICAgICAgICAgICBuZXcgQ29tcGFyZUdlbmVyYXRvcihBQ0NfUFVCTElDIHwgQUNDX0ZJTkFMLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5UeXBlLlNUUklORywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlR5cGVbXSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVXRpbC5nZXRKQ1JlZlR5cGUoRE9NX0lOVEZfU0lHKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlR5cGUuSU5ULAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuVHlwZS5JTlQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVXRpbC5nZXRKQ1JlZlR5cGUoVFJBTlNMRVRfU0lHKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlR5cGUuSU5UCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHsgImRvbSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiY3VycmVudCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibGV2ZWwiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRyYW5zbGV0IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJsYXN0IgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJleHRyYWN0VmFsdWVGcm9tRE9NIiwgY2xhc3NOYW1lLCBpbCwgY3BnKTsKLQotICAgICAgICAvLyBWYWx1ZXMgbmVlZGVkIGZvciB0aGUgc3dpdGNoIHN0YXRlbWVudAotICAgICAgICBmaW5hbCBpbnQgbGV2ZWxzID0gc29ydE9iamVjdHMuc2l6ZSgpOwotICAgICAgICBmaW5hbCBpbnQgbWF0Y2hbXSA9IG5ldyBpbnRbbGV2ZWxzXTsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25IYW5kbGUgdGFyZ2V0W10gPSBuZXcgSW5zdHJ1Y3Rpb25IYW5kbGVbbGV2ZWxzXTsKLSAgICAgICAgSW5zdHJ1Y3Rpb25IYW5kbGUgdGJsc3dpdGNoID0gbnVsbDsKLQotICAgICAgICAvLyBDb21waWxlIHN3aXRjaCBzdGF0ZW1lbnQgb25seSBpZiB0aGUga2V5IGhhcyBtdWx0aXBsZSBsZXZlbHMKLSAgICAgICAgaWYgKGxldmVscyA+IDEpIHsKLSAgICAgICAgICAgIC8vIFB1dCB0aGUgcGFyYW1ldGVyIHRvIHRoZSBzd3RpY2ggc3RhdGVtZW50IG9uIHRoZSBzdGFjawotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTE9BRChleHRyYWN0TWV0aG9kLmdldExvY2FsSW5kZXgoImxldmVsIikpKTsKLSAgICAgICAgICAgIC8vIEFwcGVuZCB0aGUgc3dpdGNoIHN0YXRlbWVudCBoZXJlIGxhdGVyIG9uCi0gICAgICAgICAgICB0Ymxzd2l0Y2ggPSBpbC5hcHBlbmQobmV3IE5PUCgpKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIEFwcGVuZCBhbGwgdGhlIGNhc2VzIGZvciB0aGUgc3dpdGNoIHN0YXRtZW50Ci0gICAgICAgIGZvciAoaW50IGxldmVsID0gMDsgbGV2ZWwgPCBsZXZlbHM7IGxldmVsKyspIHsKLSAgICAgICAgICAgIG1hdGNoW2xldmVsXSA9IGxldmVsOwotICAgICAgICAgICAgZmluYWwgU29ydCBzb3J0ID0gc29ydE9iamVjdHMuZWxlbWVudEF0KGxldmVsKTsKLSAgICAgICAgICAgIHRhcmdldFtsZXZlbF0gPSBpbC5hcHBlbmQoTk9QKTsKLSAgICAgICAgICAgIHNvcnQudHJhbnNsYXRlU2VsZWN0KHNvcnRSZWNvcmQsIGV4dHJhY3RNZXRob2QpOwotICAgICAgICAgICAgaWwuYXBwZW5kKEFSRVRVUk4pOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gQ29tcGlsZSBkZWYuIHRhcmdldCBmb3Igc3dpdGNoIHN0YXRlbWVudCBpZiBrZXkgaGFzIG11bHRpcGxlIGxldmVscwotICAgICAgICBpZiAobGV2ZWxzID4gMSkgewotICAgICAgICAgICAgLy8gQXBwZW5kIHRoZSBkZWZhdWx0IHRhcmdldCAtIGl0IHdpbGwgX05FVkVSXyBiZSByZWFjaGVkCi0gICAgICAgICAgICBJbnN0cnVjdGlvbkhhbmRsZSBkZWZhdWx0VGFyZ2V0ID0KLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBFTVBUWVNUUklORykpOwotICAgICAgICAgICAgaWwuaW5zZXJ0KHRibHN3aXRjaCxuZXcgVEFCTEVTV0lUQ0gobWF0Y2gsIHRhcmdldCwgZGVmYXVsdFRhcmdldCkpOwotICAgICAgICAgICAgaWwuYXBwZW5kKEFSRVRVUk4pOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIGV4dHJhY3RNZXRob2Q7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9Tb3VyY2VMb2FkZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvU291cmNlTG9hZGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGNjMDc3MDguLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9Tb3VyY2VMb2FkZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQ0ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFNvdXJjZUxvYWRlci5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzA1IDA5OjAyOjMwIHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IG9yZy54bWwuc2F4LklucHV0U291cmNlOwotCi0vKioKLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICovCi1wdWJsaWMgaW50ZXJmYWNlIFNvdXJjZUxvYWRlciB7Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIGludGVyZmFjZSBpcyB1c2VkIHRvIHBsdWcgZXh0ZXJuYWwgZG9jdW1lbnQgbG9hZGVycyBpbnRvIFhTTFRDCi0gICAgICogKHVzZWQgd2l0aCB0aGUgPHhzbDppbmNsdWRlPiBhbmQgPHhzbDppbXBvcnQ+IGVsZW1lbnRzLgotICAgICAqCi0gICAgICogQHBhcmFtIGhyZWYgVGhlIFVSSSBvZiB0aGUgZG9jdW1lbnQgdG8gbG9hZAotICAgICAqIEBwYXJhbSBjb250ZXh0IFRoZSBVUkkgb2YgdGhlIGN1cnJlbnRseSBsb2FkZWQgZG9jdW1lbnQKLSAgICAgKiBAcGFyYW0geHNsdGMgVGhlIGNvbXBpbGVyIHRoYXQgcmVzdWVzdHMgdGhlIGRvY3VtZW50Ci0gICAgICogQHJldHVybiBBbiBJbnB1dFNvdXJjZSB3aXRoIHRoZSBsb2FkZWQgZG9jdW1lbnQKLSAgICAgKi8KLSAgICBwdWJsaWMgSW5wdXRTb3VyY2UgbG9hZFNvdXJjZShTdHJpbmcgaHJlZiwgU3RyaW5nIGNvbnRleHQsIFhTTFRDIHhzbHRjKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9TdGFydHNXaXRoQ2FsbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9TdGFydHNXaXRoQ2FsbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1Yjk0NmM5Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvU3RhcnRzV2l0aENhbGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDkzICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFN0YXJ0c1dpdGhDYWxsLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMDUgMDk6MDU6MjggcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQ29uc3RhbnRQb29sR2VuOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFVklSVFVBTDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uTGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5DbGFzc0dlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5FcnJvck1zZzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5NZXRob2RHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlQ2hlY2tFcnJvcjsKLQotLyoqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqLwotZmluYWwgY2xhc3MgU3RhcnRzV2l0aENhbGwgZXh0ZW5kcyBGdW5jdGlvbkNhbGwgewotCi0gICAgcHJpdmF0ZSBFeHByZXNzaW9uIF9iYXNlID0gbnVsbDsKLSAgICBwcml2YXRlIEV4cHJlc3Npb24gX3Rva2VuID0gbnVsbDsKLQotICAgIC8qKgotICAgICAqIENyZWF0ZSBhIHN0YXJ0cy13aXRoKCkgY2FsbCAtIHR3byBhcmd1bWVudHMsIGJvdGggc3RyaW5ncwotICAgICAqLwotICAgIHB1YmxpYyBTdGFydHNXaXRoQ2FsbChRTmFtZSBmbmFtZSwgVmVjdG9yIGFyZ3VtZW50cykgewotICAgICAgICBzdXBlcihmbmFtZSwgYXJndW1lbnRzKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUeXBlIGNoZWNrIHRoZSB0d28gcGFyYW1ldGVycyBmb3IgdGhpcyBmdW5jdGlvbgotICAgICAqLwotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0KLSAgICAgICAgLy8gQ2hlY2sgdGhhdCB0aGUgZnVuY3Rpb24gd2FzIHBhc3NlZCBleGFjdGx5IHR3byBhcmd1bWVudHMKLSAgICAgICAgaWYgKGFyZ3VtZW50Q291bnQoKSAhPSAyKSB7Ci0gICAgICAgICAgICBFcnJvck1zZyBlcnIgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuSUxMRUdBTF9BUkdfRVJSLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldE5hbWUoKSwgdGhpcyk7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUNoZWNrRXJyb3IoZXJyKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIFRoZSBmaXJzdCBhcmd1bWVudCBtdXN0IGJlIGEgU3RyaW5nLCBvciBjYXN0IHRvIGEgU3RyaW5nCi0gICAgICAgIF9iYXNlID0gYXJndW1lbnQoMCk7Ci0gICAgICAgIFR5cGUgYmFzZVR5cGUgPSBfYmFzZS50eXBlQ2hlY2soc3RhYmxlKTsKLSAgICAgICAgaWYgKGJhc2VUeXBlICE9IFR5cGUuU3RyaW5nKQotICAgICAgICAgICAgX2Jhc2UgPSBuZXcgQ2FzdEV4cHIoX2Jhc2UsIFR5cGUuU3RyaW5nKTsKLQotICAgICAgICAvLyBUaGUgc2Vjb25kIGFyZ3VtZW50IG11c3QgYWxzbyBiZSBhIFN0cmluZywgb3IgY2FzdCB0byBhIFN0cmluZwotICAgICAgICBfdG9rZW4gPSBhcmd1bWVudCgxKTsKLSAgICAgICAgVHlwZSB0b2tlblR5cGUgPSBfdG9rZW4udHlwZUNoZWNrKHN0YWJsZSk7Ci0gICAgICAgIGlmICh0b2tlblR5cGUgIT0gVHlwZS5TdHJpbmcpCi0gICAgICAgICAgICBfdG9rZW4gPSBuZXcgQ2FzdEV4cHIoX3Rva2VuLCBUeXBlLlN0cmluZyk7Ci0KLSAgICAgICAgcmV0dXJuIF90eXBlID0gVHlwZS5Cb29sZWFuOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbXBpbGUgdGhlIGV4cHJlc3Npb24gLSBsZWF2ZSBib29sZWFuIGV4cHJlc3Npb24gb24gc3RhY2sKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLSAgICAgICAgZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0gICAgICAgIF9iYXNlLnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgX3Rva2VuLnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VWSVJUVUFMKGNwZy5hZGRNZXRob2RyZWYoU1RSSU5HX0NMQVNTLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAic3RhcnRzV2l0aCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoIitTVFJJTkdfU0lHKyIpWiIpKSk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9TdGVwLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL1N0ZXAuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggY2NhMjhmOS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL1N0ZXAuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDUzOCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBTdGVwLmphdmEsdiAxLjYgMjAwNi8wNi8wNiAyMjozNDozNCBzcGVyaWNhcyBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQUxPQUQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5BU1RPUkU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5DSEVDS0NBU1Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5Db25zdGFudFBvb2xHZW47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JQ09OU1Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JTE9BRDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklTVE9SRTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklOVk9LRUlOVEVSRkFDRTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklOVk9LRVNQRUNJQUw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JbnN0cnVjdGlvbkxpc3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5Mb2NhbFZhcmlhYmxlR2VuOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuTkVXOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuUFVTSDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuRE9NOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkNsYXNzR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLk1ldGhvZEdlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGVDaGVja0Vycm9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlV0aWw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uQXhpczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE07Ci0KLS8qKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKi8KLWZpbmFsIGNsYXNzIFN0ZXAgZXh0ZW5kcyBSZWxhdGl2ZUxvY2F0aW9uUGF0aCB7Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIHN0ZXAncyBheGlzIGFzIGRlZmluZWQgaW4gY2xhc3MgQXhpcy4KLSAgICAgKi8KLSAgICBwcml2YXRlIGludCBfYXhpczsKLQotICAgIC8qKgotICAgICAqIEEgdmVjdG9yIG9mIHByZWRpY2F0ZXMgKGZpbHRlcnMpIGRlZmluZWQgb24gdGhpcyBzdGVwIC0gbWF5IGJlIG51bGwKLSAgICAgKi8KLSAgICBwcml2YXRlIFZlY3RvciBfcHJlZGljYXRlczsKLQotICAgIC8qKgotICAgICAqIFNvbWUgc2ltcGxlIHByZWRpY2F0ZXMgY2FuIGJlIGhhbmRsZWQgYnkgdGhpcyBjbGFzcyAoYW5kIG5vdCBieSB0aGUKLSAgICAgKiBQcmVkaWNhdGUgY2xhc3MpIGFuZCB3aWxsIGJlIHJlbW92ZWQgZnJvbSB0aGUgYWJvdmUgdmVjdG9yIGFzIHRoZXkgYXJlCi0gICAgICogaGFuZGxlZC4gV2UgdXNlIHRoaXMgYm9vbGVhbiB0byByZW1lbWJlciBpZiB3ZSBkaWQgaGF2ZSBhbnkgcHJlZGljYXRlcy4KLSAgICAgKi8KLSAgICBwcml2YXRlIGJvb2xlYW4gX2hhZFByZWRpY2F0ZXMgPSBmYWxzZTsKLQotICAgIC8qKgotICAgICAqIFR5cGUgb2YgdGhlIG5vZGUgdGVzdC4KLSAgICAgKi8KLSAgICBwcml2YXRlIGludCBfbm9kZVR5cGU7Ci0KLSAgICBwdWJsaWMgU3RlcChpbnQgYXhpcywgaW50IG5vZGVUeXBlLCBWZWN0b3IgcHJlZGljYXRlcykgewotICAgICAgICBfYXhpcyA9IGF4aXM7Ci0gICAgICAgIF9ub2RlVHlwZSA9IG5vZGVUeXBlOwotICAgICAgICBfcHJlZGljYXRlcyA9IHByZWRpY2F0ZXM7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSBwYXJzZXIgZm9yIHRoaXMgZWxlbWVudCBhbmQgYWxsIGNoaWxkIHByZWRpY2F0ZXMKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRQYXJzZXIoUGFyc2VyIHBhcnNlcikgewotICAgICAgICBzdXBlci5zZXRQYXJzZXIocGFyc2VyKTsKLSAgICAgICAgaWYgKF9wcmVkaWNhdGVzICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZpbmFsIGludCBuID0gX3ByZWRpY2F0ZXMuc2l6ZSgpOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspIHsKLSAgICAgICAgICAgICAgICBmaW5hbCBQcmVkaWNhdGUgZXhwID0gKFByZWRpY2F0ZSlfcHJlZGljYXRlcy5lbGVtZW50QXQoaSk7Ci0gICAgICAgICAgICAgICAgZXhwLnNldFBhcnNlcihwYXJzZXIpOwotICAgICAgICAgICAgICAgIGV4cC5zZXRQYXJlbnQodGhpcyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBEZWZpbmUgdGhlIGF4aXMgKGRlZmluZWQgaW4gQXhpcyBjbGFzcykgZm9yIHRoaXMgc3RlcAotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0QXhpcygpIHsKLSAgICAgICAgcmV0dXJuIF9heGlzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgYXhpcyAoZGVmaW5lZCBpbiBBeGlzIGNsYXNzKSBmb3IgdGhpcyBzdGVwCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0QXhpcyhpbnQgYXhpcykgewotICAgICAgICBfYXhpcyA9IGF4aXM7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgbm9kZS10eXBlIGZvciB0aGlzIHN0ZXAKLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldE5vZGVUeXBlKCkgewotICAgICAgICByZXR1cm4gX25vZGVUeXBlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIHZlY3RvciBjb250YWluaW5nIGFsbCBwcmVkaWNhdGVzIGZvciB0aGlzIHN0ZXAuCi0gICAgICovCi0gICAgcHVibGljIFZlY3RvciBnZXRQcmVkaWNhdGVzKCkgewotICAgICAgICByZXR1cm4gX3ByZWRpY2F0ZXM7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgdmVjdG9yIGNvbnRhaW5pbmcgYWxsIHByZWRpY2F0ZXMgZm9yIHRoaXMgc3RlcC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBhZGRQcmVkaWNhdGVzKFZlY3RvciBwcmVkaWNhdGVzKSB7Ci0gICAgICAgIGlmIChfcHJlZGljYXRlcyA9PSBudWxsKSB7Ci0gICAgICAgICAgICBfcHJlZGljYXRlcyA9IHByZWRpY2F0ZXM7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBfcHJlZGljYXRlcy5hZGRBbGwocHJlZGljYXRlcyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zICd0cnVlJyBpZiB0aGlzIHN0ZXAgaGFzIGEgcGFyZW50IHBhdHRlcm4uCi0gICAgICogVGhpcyBtZXRob2Qgd2lsbCByZXR1cm4gJ2ZhbHNlJyBpZiB0aGlzIHN0ZXAgb2NjdXJzIG9uIGl0cyBvd24gdW5kZXIKLSAgICAgKiBhbiBlbGVtZW50IGxpa2UgPHhzbDpmb3ItZWFjaD4gb3IgPHhzbDphcHBseS10ZW1wbGF0ZXM+LgotICAgICAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBoYXNQYXJlbnRQYXR0ZXJuKCkgewotICAgICAgICBmaW5hbCBTeW50YXhUcmVlTm9kZSBwYXJlbnQgPSBnZXRQYXJlbnQoKTsKLSAgICAgICAgcmV0dXJuIChwYXJlbnQgaW5zdGFuY2VvZiBQYXJlbnRQYXR0ZXJuIHx8Ci0gICAgICAgICAgICAgICAgcGFyZW50IGluc3RhbmNlb2YgUGFyZW50TG9jYXRpb25QYXRoIHx8Ci0gICAgICAgICAgICAgICAgcGFyZW50IGluc3RhbmNlb2YgVW5pb25QYXRoRXhwciB8fAotICAgICAgICAgICAgICAgIHBhcmVudCBpbnN0YW5jZW9mIEZpbHRlclBhcmVudFBhdGgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgJ3RydWUnIGlmIHRoaXMgc3RlcCBoYXMgYSBwYXJlbnQgbG9jYXRpb24gcGF0aC4KLSAgICAgKi8KLSAgICBwcml2YXRlIGJvb2xlYW4gaGFzUGFyZW50TG9jYXRpb25QYXRoKCkgewotICAgICAgICByZXR1cm4gZ2V0UGFyZW50KCkgaW5zdGFuY2VvZiBQYXJlbnRMb2NhdGlvblBhdGg7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyAndHJ1ZScgaWYgdGhpcyBzdGVwIGhhcyBhbnkgcHJlZGljYXRlcwotICAgICAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBoYXNQcmVkaWNhdGVzKCkgewotICAgICAgICByZXR1cm4gX3ByZWRpY2F0ZXMgIT0gbnVsbCAmJiBfcHJlZGljYXRlcy5zaXplKCkgPiAwOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgJ3RydWUnIGlmIHRoaXMgc3RlcCBpcyB1c2VkIHdpdGhpbiBhIHByZWRpY2F0ZQotICAgICAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBpc1ByZWRpY2F0ZSgpIHsKLSAgICAgICAgU3ludGF4VHJlZU5vZGUgcGFyZW50ID0gdGhpczsKLSAgICAgICAgd2hpbGUgKHBhcmVudCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBwYXJlbnQgPSBwYXJlbnQuZ2V0UGFyZW50KCk7Ci0gICAgICAgICAgICBpZiAocGFyZW50IGluc3RhbmNlb2YgUHJlZGljYXRlKSByZXR1cm4gdHJ1ZTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJ1ZSBpZiB0aGlzIHN0ZXAgaXMgdGhlIGFiYnJldmlhdGVkIHN0ZXAgJy4nCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNBYmJyZXZpYXRlZERvdCgpIHsKLSAgICAgICAgcmV0dXJuIF9ub2RlVHlwZSA9PSBOb2RlVGVzdC5BTk9ERSAmJiBfYXhpcyA9PSBBeGlzLlNFTEY7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBUcnVlIGlmIHRoaXMgc3RlcCBpcyB0aGUgYWJicmV2aWF0ZWQgc3RlcCAnLi4nCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNBYmJyZXZpYXRlZEREb3QoKSB7Ci0gICAgICAgIHJldHVybiBfbm9kZVR5cGUgPT0gTm9kZVRlc3QuQU5PREUgJiYgX2F4aXMgPT0gQXhpcy5QQVJFTlQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHlwZSBjaGVjayB0aGlzIHN0ZXAuIFRoZSBhYmJyZXZpYXRlZCBzdGVwcyAnLicgYW5kICdAYXR0cicgYXJlCi0gICAgICogYXNzaWduZWQgdHlwZSBub2RlIGlmIHRoZXkgaGF2ZSBubyBwcmVkaWNhdGVzLiBBbGwgb3RoZXIgc3RlcHMKLSAgICAgKiBoYXZlIHR5cGUgbm9kZS1zZXQuCi0gICAgICovCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLQotICAgICAgICAvLyBTYXZlIHRoaXMgdmFsdWUgZm9yIGxhdGVyIC0gaW1wb3J0YW50IGZvciB0ZXN0aW5nIGZvciBzcGVjaWFsCi0gICAgICAgIC8vIGNvbWJpbmF0aW9ucyBvZiBzdGVwcyBhbmQgcGF0dGVybnMgdGhhbiBjYW4gYmUgb3B0aW1pc2VkCi0gICAgICAgIF9oYWRQcmVkaWNhdGVzID0gaGFzUHJlZGljYXRlcygpOwotCi0gICAgICAgIC8vIFNwZWNpYWwgY2FzZSBmb3IgJy4nCi0gICAgICAgIC8vICAgaW4gdGhlIGNhc2Ugd2hlcmUgJy4nIGhhcyBhIGNvbnRleHQgc3VjaCBhcyBib29rLy4KLSAgICAgICAgLy8gICBvciAuW2ZhbHNlKCldIHdlIGNhbiBub3Qgb3B0aW1pemUgdGhlIG5vZGVzZXQgdG8gYSBzaW5nbGUgbm9kZS4KLSAgICAgICAgaWYgKGlzQWJicmV2aWF0ZWREb3QoKSkgewotICAgICAgICAgICAgX3R5cGUgPSAoaGFzUGFyZW50UGF0dGVybigpIHx8IGhhc1ByZWRpY2F0ZXMoKSB8fCBoYXNQYXJlbnRMb2NhdGlvblBhdGgoKSkgPwotICAgICAgICAgICAgICAgIFR5cGUuTm9kZVNldCA6IFR5cGUuTm9kZTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIF90eXBlID0gVHlwZS5Ob2RlU2V0OwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gVHlwZSBjaGVjayBhbGwgcHJlZGljYXRlcyAoZXhwcmVzc2lvbnMgYXBwbGllZCB0byB0aGUgc3RlcCkKLSAgICAgICAgaWYgKF9wcmVkaWNhdGVzICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZpbmFsIGludCBuID0gX3ByZWRpY2F0ZXMuc2l6ZSgpOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspIHsKLSAgICAgICAgICAgICAgICBmaW5hbCBFeHByZXNzaW9uIHByZWQgPSAoRXhwcmVzc2lvbilfcHJlZGljYXRlcy5lbGVtZW50QXQoaSk7Ci0gICAgICAgICAgICAgICAgcHJlZC50eXBlQ2hlY2soc3RhYmxlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIFJldHVybiBlaXRoZXIgVHlwZS5Ob2RlIG9yIFR5cGUuTm9kZVNldAotICAgICAgICByZXR1cm4gX3R5cGU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhbnNsYXRlIGEgc3RlcCBieSBwdXNoaW5nIHRoZSBhcHByb3ByaWF0ZSBpdGVyYXRvciBvbnRvIHRoZSBzdGFjay4KLSAgICAgKiBUaGUgYWJicmV2aWF0ZWQgc3RlcHMgJy4nIGFuZCAnQGF0dHInIGRvIG5vdCBjcmVhdGUgbmV3IGl0ZXJhdG9ycwotICAgICAqIGlmIHRoZXkgYXJlIG5vdCBwYXJ0IG9mIGEgTG9jYXRpb25QYXRoIGFuZCBoYXZlIG5vIGZpbHRlcnMuCi0gICAgICogSW4gdGhlc2UgY2FzZXMgYSBub2RlIGluZGV4IGluc3RlYWQgb2YgYW4gaXRlcmF0b3IgaXMgcHVzaGVkCi0gICAgICogb250byB0aGUgc3RhY2suCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0gICAgICAgIHRyYW5zbGF0ZVN0ZXAoY2xhc3NHZW4sIG1ldGhvZEdlbiwgaGFzUHJlZGljYXRlcygpID8gX3ByZWRpY2F0ZXMuc2l6ZSgpIC0gMSA6IC0xKTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgdHJhbnNsYXRlU3RlcChDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBwcmVkaWNhdGVJbmRleCkgewotICAgICAgICBmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQotICAgICAgICBpZiAocHJlZGljYXRlSW5kZXggPj0gMCkgewotICAgICAgICAgICAgdHJhbnNsYXRlUHJlZGljYXRlcyhjbGFzc0dlbiwgbWV0aG9kR2VuLCBwcmVkaWNhdGVJbmRleCk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBpbnQgc3RhciA9IDA7Ci0gICAgICAgICAgICBTdHJpbmcgbmFtZSA9IG51bGw7Ci0gICAgICAgICAgICBmaW5hbCBYU0xUQyB4c2x0YyA9IGdldFBhcnNlcigpLmdldFhTTFRDKCk7Ci0KLSAgICAgICAgICAgIGlmIChfbm9kZVR5cGUgPj0gRFRNLk5UWVBFUykgewotICAgICAgICAgICAgICAgIGZpbmFsIFZlY3RvciBuaSA9IHhzbHRjLmdldE5hbWVzSW5kZXgoKTsKLQotICAgICAgICAgICAgICAgIG5hbWUgPSAoU3RyaW5nKW5pLmVsZW1lbnRBdChfbm9kZVR5cGUtRFRNLk5UWVBFUyk7Ci0gICAgICAgICAgICAgICAgc3RhciA9IG5hbWUubGFzdEluZGV4T2YoJyonKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gSWYgaXQgaXMgYW4gYXR0cmlidXRlLCBidXQgbm90ICdAKicsICdAcHJlOionIG9yICdAbm9kZSgpJywKLSAgICAgICAgICAgIC8vIGFuZCBoYXMgbm8gcGFyZW50Ci0gICAgICAgICAgICBpZiAoX2F4aXMgPT0gQXhpcy5BVFRSSUJVVEUgJiYgX25vZGVUeXBlICE9IE5vZGVUZXN0LkFUVFJJQlVURQotICAgICAgICAgICAgICAgICYmIF9ub2RlVHlwZSAhPSBOb2RlVGVzdC5BTk9ERSAmJiAhaGFzUGFyZW50UGF0dGVybigpCi0gICAgICAgICAgICAgICAgJiYgc3RhciA9PSAwKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIGludCBpdGVyID0gY3BnLmFkZEludGVyZmFjZU1ldGhvZHJlZihET01fSU5URiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImdldFR5cGVkQXhpc0l0ZXJhdG9yIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIihJSSkiK05PREVfSVRFUkFUT1JfU0lHKTsKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgQXhpcy5BVFRSSUJVVEUpKTsKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBfbm9kZVR5cGUpKTsKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRUlOVEVSRkFDRShpdGVyLCAzKSk7Ci0gICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBTeW50YXhUcmVlTm9kZSBwYXJlbnQgPSBnZXRQYXJlbnQoKTsKLSAgICAgICAgICAgIC8vIFNwZWNpYWwgY2FzZSBmb3IgJy4nCi0gICAgICAgICAgICBpZiAoaXNBYmJyZXZpYXRlZERvdCgpKSB7Ci0gICAgICAgICAgICAgICAgaWYgKF90eXBlID09IFR5cGUuTm9kZSkgewotICAgICAgICAgICAgICAgICAgICAvLyBQdXQgY29udGV4dCBub2RlIG9uIHN0YWNrIGlmIHVzaW5nIFR5cGUuTm9kZQotICAgICAgICAgICAgICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRDb250ZXh0Tm9kZSgpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChwYXJlbnQgaW5zdGFuY2VvZiBQYXJlbnRMb2NhdGlvblBhdGgpewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gV3JhcCB0aGUgY29udGV4dCBub2RlIGluIGEgc2luZ2xldG9uIGl0ZXJhdG9yIGlmIG5vdC4KLSAgICAgICAgICAgICAgICAgICAgICAgIGludCBpbml0ID0gY3BnLmFkZE1ldGhvZHJlZihTSU5HTEVUT05fSVRFUkFUT1IsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjxpbml0PiIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIigiK05PREVfU0lHKyIpViIpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBORVcoY3BnLmFkZENsYXNzKFNJTkdMRVRPTl9JVEVSQVRPUikpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlsLmFwcGVuZChEVVApOwotICAgICAgICAgICAgICAgICAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkQ29udGV4dE5vZGUoKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRVNQRUNJQUwoaW5pdCkpOwotICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gRE9NLmdldEF4aXNJdGVyYXRvcihpbnQgYXhpcyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpbnQgZ2l0ID0gY3BnLmFkZEludGVyZmFjZU1ldGhvZHJlZihET01fSU5URiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJnZXRBeGlzSXRlcmF0b3IiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIihJKSIrTk9ERV9JVEVSQVRPUl9TSUcpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkRE9NKCkpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgX2F4aXMpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFSU5URVJGQUNFKGdpdCwgMikpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gU3BlY2lhbCBjYXNlIGZvciAvZm9vLyovYmFyCi0gICAgICAgICAgICBpZiAoKHBhcmVudCBpbnN0YW5jZW9mIFBhcmVudExvY2F0aW9uUGF0aCkgJiYKLSAgICAgICAgICAgICAgICAocGFyZW50LmdldFBhcmVudCgpIGluc3RhbmNlb2YgUGFyZW50TG9jYXRpb25QYXRoKSkgewotICAgICAgICAgICAgICAgIGlmICgoX25vZGVUeXBlID09IE5vZGVUZXN0LkVMRU1FTlQpICYmICghX2hhZFByZWRpY2F0ZXMpKSB7Ci0gICAgICAgICAgICAgICAgICAgIF9ub2RlVHlwZSA9IE5vZGVUZXN0LkFOT0RFOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gIkVMRU1FTlQiIG9yICIqIiBvciAiQCoiIG9yICIuLiIgb3IgIkBhdHRyIiB3aXRoIGEgcGFyZW50LgotICAgICAgICAgICAgc3dpdGNoIChfbm9kZVR5cGUpIHsKLSAgICAgICAgICAgIGNhc2UgTm9kZVRlc3QuQVRUUklCVVRFOgotICAgICAgICAgICAgICAgIF9heGlzID0gQXhpcy5BVFRSSUJVVEU7Ci0gICAgICAgICAgICBjYXNlIE5vZGVUZXN0LkFOT0RFOgotICAgICAgICAgICAgICAgIC8vIERPTS5nZXRBeGlzSXRlcmF0b3IoaW50IGF4aXMpOwotICAgICAgICAgICAgICAgIGludCBnaXQgPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKERPTV9JTlRGLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJnZXRBeGlzSXRlcmF0b3IiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoSSkiK05PREVfSVRFUkFUT1JfU0lHKTsKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgX2F4aXMpKTsKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRUlOVEVSRkFDRShnaXQsIDIpKTsKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIGRlZmF1bHQ6Ci0gICAgICAgICAgICAgICAgaWYgKHN0YXIgPiAxKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBuYW1lc3BhY2U7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChfYXhpcyA9PSBBeGlzLkFUVFJJQlVURSkKLSAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZSA9IG5hbWUuc3Vic3RyaW5nKDAsc3Rhci0yKTsKLSAgICAgICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXNwYWNlID0gbmFtZS5zdWJzdHJpbmcoMCxzdGFyLTEpOwotCi0gICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCBuc1R5cGUgPSB4c2x0Yy5yZWdpc3Rlck5hbWVzcGFjZShuYW1lc3BhY2UpOwotICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgbnMgPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKERPTV9JTlRGLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJnZXROYW1lc3BhY2VBeGlzSXRlcmF0b3IiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoSUkpIitOT0RFX0lURVJBVE9SX1NJRyk7Ci0gICAgICAgICAgICAgICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLSAgICAgICAgICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgX2F4aXMpKTsKLSAgICAgICAgICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgbnNUeXBlKSk7Ci0gICAgICAgICAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFSU5URVJGQUNFKG5zLCAzKSk7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhc2UgTm9kZVRlc3QuRUxFTUVOVDoKLSAgICAgICAgICAgICAgICAvLyBET00uZ2V0VHlwZWRBeGlzSXRlcmF0b3IoaW50IGF4aXMsIGludCB0eXBlKTsKLSAgICAgICAgICAgICAgICBmaW5hbCBpbnQgdHkgPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKERPTV9JTlRGLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImdldFR5cGVkQXhpc0l0ZXJhdG9yIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoSUkpIitOT0RFX0lURVJBVE9SX1NJRyk7Ci0gICAgICAgICAgICAgICAgLy8gR2V0IHRoZSB0eXBlZCBpdGVyYXRvciB3ZSdyZSBhZnRlcgotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBfYXhpcykpOwotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsIF9ub2RlVHlwZSkpOwotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFSU5URVJGQUNFKHR5LCAzKSk7Ci0KLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogVHJhbnNsYXRlIGEgc2VxdWVuY2Ugb2YgcHJlZGljYXRlcy4gRWFjaCBwcmVkaWNhdGUgaXMgdHJhbnNsYXRlZAotICAgICAqIGJ5IGNvbnN0cnVjdGluZyBhbiBpbnN0YW5jZSBvZiA8Y29kZT5DdXJyZW50Tm9kZUxpc3RJdGVyYXRvcjwvY29kZT4KLSAgICAgKiB3aGljaCBpcyBpbml0aWFsaXplZCBmcm9tIGFub3RoZXIgaXRlcmF0b3IgKHJlY3Vyc2l2ZSBjYWxsKSwKLSAgICAgKiBhIGZpbHRlciBhbmQgYSBjbG9zdXJlIChjYWxsIHRvIHRyYW5zbGF0ZSBvbiB0aGUgcHJlZGljYXRlKSBhbmQgInRoaXMiLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZVByZWRpY2F0ZXMoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHByZWRpY2F0ZUluZGV4KSB7Ci0gICAgICAgIGZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCi0gICAgICAgIGludCBpZHggPSAwOwotCi0gICAgICAgIGlmIChwcmVkaWNhdGVJbmRleCA8IDApIHsKLSAgICAgICAgICAgIHRyYW5zbGF0ZVN0ZXAoY2xhc3NHZW4sIG1ldGhvZEdlbiwgcHJlZGljYXRlSW5kZXgpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgZmluYWwgUHJlZGljYXRlIHByZWRpY2F0ZSA9IChQcmVkaWNhdGUpIF9wcmVkaWNhdGVzLmdldChwcmVkaWNhdGVJbmRleC0tKTsKLQotICAgICAgICAgICAgLy8gU3BlY2lhbCBjYXNlIGZvciBwcmVkaWNhdGVzIHRoYXQgY2FuIHVzZSB0aGUgTm9kZVZhbHVlSXRlcmF0b3IKLSAgICAgICAgICAgIC8vIGluc3RlYWQgb2YgYW4gYXV4aWxpYXJ5IGNsYXNzLiBDZXJ0YWluIHBhdGgvcHJlZGljYXRlcyBwYWlycwotICAgICAgICAgICAgLy8gYXJlIHRyYW5zbGF0ZWQgaW50byBhIGJhc2UgcGF0aCwgb24gdG9wIG9mIHdoaWNoIHdlIHBsYWNlIGEKLSAgICAgICAgICAgIC8vIG5vZGUgdmFsdWUgaXRlcmF0b3IgdGhhdCB0ZXN0cyBmb3IgdGhlIGRlc2lyZWQgdmFsdWU6Ci0gICAgICAgICAgICAvLyAgIGZvb1tAYXR0ciA9ICdzdHInXSAgLT4gIGZvby9AYXR0ciArIHRlc3QodmFsdWU9J3N0cicpCi0gICAgICAgICAgICAvLyAgIGZvb1tiYXIgPSAnc3RyJ10gICAgLT4gIGZvby9iYXIgKyB0ZXN0KHZhbHVlPSdzdHInKQotICAgICAgICAgICAgLy8gICBmb28vYmFyWy4gPSAnc3RyJ10gIC0+ICBmb28vYmFyICsgdGVzdCh2YWx1ZT0nc3RyJykKLSAgICAgICAgICAgIGlmIChwcmVkaWNhdGUuaXNOb2RlVmFsdWVUZXN0KCkpIHsKLSAgICAgICAgICAgICAgICBTdGVwIHN0ZXAgPSBwcmVkaWNhdGUuZ2V0U3RlcCgpOwotCi0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkRE9NKCkpOwotICAgICAgICAgICAgICAgIC8vIElmIHRoZSBwcmVkaWNhdGUncyBTdGVwIGlzIHNpbXBseSAnLicgd2UgdHJhbnNsYXRlIHRoaXMgU3RlcAotICAgICAgICAgICAgICAgIC8vIGFuZCBwbGFjZSB0aGUgbm9kZSB0ZXN0IG9uIHRvcCBvZiB0aGUgcmVzdWx0aW5nIGl0ZXJhdG9yCi0gICAgICAgICAgICAgICAgaWYgKHN0ZXAuaXNBYmJyZXZpYXRlZERvdCgpKSB7Ci0gICAgICAgICAgICAgICAgICAgIHRyYW5zbGF0ZVN0ZXAoY2xhc3NHZW4sIG1ldGhvZEdlbiwgcHJlZGljYXRlSW5kZXgpOwotICAgICAgICAgICAgICAgICAgICBpbC5hcHBlbmQobmV3IElDT05TVChET00uUkVUVVJOX0NVUlJFTlQpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLy8gT3RoZXJ3aXNlIHdlIGNyZWF0ZSBhIHBhcmVudCBsb2NhdGlvbiBwYXRoIHdpdGggdGhpcyBTdGVwIGFuZAotICAgICAgICAgICAgICAgIC8vIHRoZSBwcmVkaWNhdGVzIFN0ZXAsIGFuZCBwbGFjZSB0aGUgbm9kZSB0ZXN0IG9uIHRvcCBvZiB0aGF0Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIFBhcmVudExvY2F0aW9uUGF0aCBwYXRoID0gbmV3IFBhcmVudExvY2F0aW9uUGF0aCh0aGlzLCBzdGVwKTsKLSAgICAgICAgICAgICAgICAgICAgX3BhcmVudCA9IHN0ZXAuX3BhcmVudCA9IHBhdGg7ICAgICAgLy8gRm9yY2UgcmUtcGFyZW50aW5nCi0KLSAgICAgICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHBhdGgudHlwZUNoZWNrKGdldFBhcnNlcigpLmdldFN5bWJvbFRhYmxlKCkpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGNhdGNoIChUeXBlQ2hlY2tFcnJvciBlKSB7IH0KLSAgICAgICAgICAgICAgICAgICAgdHJhbnNsYXRlU3RlcChjbGFzc0dlbiwgbWV0aG9kR2VuLCBwcmVkaWNhdGVJbmRleCk7Ci0gICAgICAgICAgICAgICAgICAgIHBhdGgudHJhbnNsYXRlU3RlcChjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJQ09OU1QoRE9NLlJFVFVSTl9QQVJFTlQpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgcHJlZGljYXRlLnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgICAgICAgICBpZHggPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKERPTV9JTlRGLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR0VUX05PREVfVkFMVUVfSVRFUkFUT1IsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHRVRfTk9ERV9WQUxVRV9JVEVSQVRPUl9TSUcpOwotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFSU5URVJGQUNFKGlkeCwgNSkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gSGFuZGxlICcvLypbbl0nIGV4cHJlc3Npb24KLSAgICAgICAgICAgIGVsc2UgaWYgKHByZWRpY2F0ZS5pc050aERlc2NlbmRhbnQoKSkgewotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLSAgICAgICAgICAgICAgICAvLyBpbC5hcHBlbmQobmV3IElDT05TVChOb2RlVGVzdC5FTEVNRU5UKSk7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgcHJlZGljYXRlLmdldFBvc1R5cGUoKSkpOwotICAgICAgICAgICAgICAgIHByZWRpY2F0ZS50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJQ09OU1QoMCkpOwotICAgICAgICAgICAgICAgIGlkeCA9IGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoRE9NX0lOVEYsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZ2V0TnRoRGVzY2VuZGFudCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKElJWikiK05PREVfSVRFUkFUT1JfU0lHKTsKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRUlOVEVSRkFDRShpZHgsIDQpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIEhhbmRsZSAnZWxlbVtuXScgZXhwcmVzc2lvbgotICAgICAgICAgICAgZWxzZSBpZiAocHJlZGljYXRlLmlzTnRoUG9zaXRpb25GaWx0ZXIoKSkgewotICAgICAgICAgICAgICAgIGlkeCA9IGNwZy5hZGRNZXRob2RyZWYoTlRIX0lURVJBVE9SX0NMQVNTLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjxpbml0PiIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKCIrTk9ERV9JVEVSQVRPUl9TSUcrIkkpViIpOwotCi0gICAgICAgICAgICAgICAgLy8gQmFja3dhcmRzIGJyYW5jaGVzIGFyZSBwcm9oaWJpdGVkIGlmIGFuIHVuaW5pdGlhbGl6ZWQgb2JqZWN0Ci0gICAgICAgICAgICAgICAgLy8gaXMgb24gdGhlIHN0YWNrIGJ5IHNlY3Rpb24gNC45LjQgb2YgdGhlIEpWTSBTcGVjaWZpY2F0aW9uLAotICAgICAgICAgICAgICAgIC8vIDJuZCBFZC4gIFdlIGRvbid0IGtub3cgd2hldGhlciB0aGlzIGNvZGUgbWlnaHQgY29udGFpbgotICAgICAgICAgICAgICAgIC8vIGJhY2t3YXJkcyBicmFuY2hlcywgc28gd2UgbXVzdG4ndCBjcmVhdGUgdGhlIG5ldyBvYmplY3QgdW50aWwKLSAgICAgICAgICAgICAgICAvLyBhZnRlciB3ZSd2ZSBjcmVhdGVkIHRoZSBzdXNwZWN0IGFyZ3VtZW50cyB0byBpdHMgY29uc3RydWN0b3IuCi0gICAgICAgICAgICAgICAgLy8gSW5zdGVhZCB3ZSBjYWxjdWxhdGUgdGhlIHZhbHVlcyBvZiB0aGUgYXJndW1lbnRzIHRvIHRoZQotICAgICAgICAgICAgICAgIC8vIGNvbnN0cnVjdG9yIGZpcnN0LCBzdG9yZSB0aGVtIGluIHRlbXBvcmFyeSB2YXJpYWJsZXMsIGNyZWF0ZQotICAgICAgICAgICAgICAgIC8vIHRoZSBvYmplY3QgYW5kIHJlbG9hZCB0aGUgYXJndW1lbnRzIGZyb20gdGhlIHRlbXBvcmFyaWVzIHRvCi0gICAgICAgICAgICAgICAgLy8gYXZvaWQgdGhlIHByb2JsZW0uCi0gICAgICAgICAgICAgICAgdHJhbnNsYXRlUHJlZGljYXRlcyhjbGFzc0dlbiwgbWV0aG9kR2VuLCBwcmVkaWNhdGVJbmRleCk7IC8vIHJlY3Vyc2l2ZSBjYWxsCi0gICAgICAgICAgICAgICAgTG9jYWxWYXJpYWJsZUdlbiBpdGVyYXRvclRlbXAKLSAgICAgICAgICAgICAgICAgICAgICAgID0gbWV0aG9kR2VuLmFkZExvY2FsVmFyaWFibGUoInN0ZXBfdG1wMSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFV0aWwuZ2V0SkNSZWZUeXBlKE5PREVfSVRFUkFUT1JfU0lHKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgaXRlcmF0b3JUZW1wLnNldFN0YXJ0KAotICAgICAgICAgICAgICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBBU1RPUkUoaXRlcmF0b3JUZW1wLmdldEluZGV4KCkpKSk7Ci0KLSAgICAgICAgICAgICAgICBwcmVkaWNhdGUudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICAgICAgICAgIExvY2FsVmFyaWFibGVHZW4gcHJlZGljYXRlVmFsdWVUZW1wCi0gICAgICAgICAgICAgICAgICAgICAgICA9IG1ldGhvZEdlbi5hZGRMb2NhbFZhcmlhYmxlKCJzdGVwX3RtcDIiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVdGlsLmdldEpDUmVmVHlwZSgiSSIpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLCBudWxsKTsKLSAgICAgICAgICAgICAgICBwcmVkaWNhdGVWYWx1ZVRlbXAuc2V0U3RhcnQoCi0gICAgICAgICAgICAgICAgICAgICAgICBpbC5hcHBlbmQobmV3IElTVE9SRShwcmVkaWNhdGVWYWx1ZVRlbXAuZ2V0SW5kZXgoKSkpKTsKLQotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgTkVXKGNwZy5hZGRDbGFzcyhOVEhfSVRFUkFUT1JfQ0xBU1MpKSk7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKERVUCk7Ci0gICAgICAgICAgICAgICAgaXRlcmF0b3JUZW1wLnNldEVuZCgKLSAgICAgICAgICAgICAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgQUxPQUQoaXRlcmF0b3JUZW1wLmdldEluZGV4KCkpKSk7Ci0gICAgICAgICAgICAgICAgcHJlZGljYXRlVmFsdWVUZW1wLnNldEVuZCgKLSAgICAgICAgICAgICAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSUxPQUQocHJlZGljYXRlVmFsdWVUZW1wLmdldEluZGV4KCkpKSk7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VTUEVDSUFMKGlkeCkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgaWR4ID0gY3BnLmFkZE1ldGhvZHJlZihDVVJSRU5UX05PREVfTElTVF9JVEVSQVRPUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI8aW5pdD4iLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIigiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIE5PREVfSVRFUkFUT1JfU0lHCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIENVUlJFTlRfTk9ERV9MSVNUX0ZJTFRFUl9TSUcKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgTk9ERV9TSUcKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgVFJBTlNMRVRfU0lHCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIpViIpOwotCi0gICAgICAgICAgICAgICAgLy8gQmFja3dhcmRzIGJyYW5jaGVzIGFyZSBwcm9oaWJpdGVkIGlmIGFuIHVuaW5pdGlhbGl6ZWQgb2JqZWN0Ci0gICAgICAgICAgICAgICAgLy8gaXMgb24gdGhlIHN0YWNrIGJ5IHNlY3Rpb24gNC45LjQgb2YgdGhlIEpWTSBTcGVjaWZpY2F0aW9uLAotICAgICAgICAgICAgICAgIC8vIDJuZCBFZC4gIFdlIGRvbid0IGtub3cgd2hldGhlciB0aGlzIGNvZGUgbWlnaHQgY29udGFpbgotICAgICAgICAgICAgICAgIC8vIGJhY2t3YXJkcyBicmFuY2hlcywgc28gd2UgbXVzdG4ndCBjcmVhdGUgdGhlIG5ldyBvYmplY3QgdW50aWwKLSAgICAgICAgICAgICAgICAvLyBhZnRlciB3ZSd2ZSBjcmVhdGVkIHRoZSBzdXNwZWN0IGFyZ3VtZW50cyB0byBpdHMgY29uc3RydWN0b3IuCi0gICAgICAgICAgICAgICAgLy8gSW5zdGVhZCB3ZSBjYWxjdWxhdGUgdGhlIHZhbHVlcyBvZiB0aGUgYXJndW1lbnRzIHRvIHRoZQotICAgICAgICAgICAgICAgIC8vIGNvbnN0cnVjdG9yIGZpcnN0LCBzdG9yZSB0aGVtIGluIHRlbXBvcmFyeSB2YXJpYWJsZXMsIGNyZWF0ZQotICAgICAgICAgICAgICAgIC8vIHRoZSBvYmplY3QgYW5kIHJlbG9hZCB0aGUgYXJndW1lbnRzIGZyb20gdGhlIHRlbXBvcmFyaWVzIHRvCi0gICAgICAgICAgICAgICAgLy8gYXZvaWQgdGhlIHByb2JsZW0uCi0gICAgICAgICAgICAgICAgdHJhbnNsYXRlUHJlZGljYXRlcyhjbGFzc0dlbiwgbWV0aG9kR2VuLCBwcmVkaWNhdGVJbmRleCk7IC8vIHJlY3Vyc2l2ZSBjYWxsCi0gICAgICAgICAgICAgICAgTG9jYWxWYXJpYWJsZUdlbiBpdGVyYXRvclRlbXAKLSAgICAgICAgICAgICAgICAgICAgICAgID0gbWV0aG9kR2VuLmFkZExvY2FsVmFyaWFibGUoInN0ZXBfdG1wMSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFV0aWwuZ2V0SkNSZWZUeXBlKE5PREVfSVRFUkFUT1JfU0lHKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgaXRlcmF0b3JUZW1wLnNldFN0YXJ0KAotICAgICAgICAgICAgICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBBU1RPUkUoaXRlcmF0b3JUZW1wLmdldEluZGV4KCkpKSk7Ci0KLSAgICAgICAgICAgICAgICBwcmVkaWNhdGUudHJhbnNsYXRlRmlsdGVyKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICAgICAgICAgIExvY2FsVmFyaWFibGVHZW4gZmlsdGVyVGVtcAotICAgICAgICAgICAgICAgICAgICAgICAgPSBtZXRob2RHZW4uYWRkTG9jYWxWYXJpYWJsZSgic3RlcF90bXAyIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFV0aWwuZ2V0SkNSZWZUeXBlKENVUlJFTlRfTk9ERV9MSVNUX0ZJTFRFUl9TSUcpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgZmlsdGVyVGVtcC5zZXRTdGFydCgKLSAgICAgICAgICAgICAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgQVNUT1JFKGZpbHRlclRlbXAuZ2V0SW5kZXgoKSkpKTsKLSAgICAgICAgICAgICAgICAvLyBjcmVhdGUgbmV3IEN1cnJlbnROb2RlTGlzdEl0ZXJhdG9yCi0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBORVcoY3BnLmFkZENsYXNzKENVUlJFTlRfTk9ERV9MSVNUX0lURVJBVE9SKSkpOwotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChEVVApOwotCi0gICAgICAgICAgICAgICAgaXRlcmF0b3JUZW1wLnNldEVuZCgKLSAgICAgICAgICAgICAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgQUxPQUQoaXRlcmF0b3JUZW1wLmdldEluZGV4KCkpKSk7Ci0gICAgICAgICAgICAgICAgZmlsdGVyVGVtcC5zZXRFbmQoaWwuYXBwZW5kKG5ldyBBTE9BRChmaWx0ZXJUZW1wLmdldEluZGV4KCkpKSk7Ci0KLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRDdXJyZW50Tm9kZSgpKTsKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpOwotICAgICAgICAgICAgICAgIGlmIChjbGFzc0dlbi5pc0V4dGVybmFsKCkpIHsKLSAgICAgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIGNsYXNzTmFtZSA9IGNsYXNzR2VuLmdldENsYXNzTmFtZSgpOwotICAgICAgICAgICAgICAgICAgICBpbC5hcHBlbmQobmV3IENIRUNLQ0FTVChjcGcuYWRkQ2xhc3MoY2xhc3NOYW1lKSkpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRVNQRUNJQUwoaWR4KSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgc3RlcC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgICAgICBmaW5hbCBTdHJpbmdCdWZmZXIgYnVmZmVyID0gbmV3IFN0cmluZ0J1ZmZlcigic3RlcChcIiIpOwotICAgICAgICBidWZmZXIuYXBwZW5kKEF4aXMuZ2V0TmFtZXMoX2F4aXMpKS5hcHBlbmQoIlwiLCAiKS5hcHBlbmQoX25vZGVUeXBlKTsKLSAgICAgICAgaWYgKF9wcmVkaWNhdGVzICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZpbmFsIGludCBuID0gX3ByZWRpY2F0ZXMuc2l6ZSgpOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspIHsKLSAgICAgICAgICAgICAgICBmaW5hbCBQcmVkaWNhdGUgcHJlZCA9IChQcmVkaWNhdGUpX3ByZWRpY2F0ZXMuZWxlbWVudEF0KGkpOwotICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoIiwgIikuYXBwZW5kKHByZWQudG9TdHJpbmcoKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGJ1ZmZlci5hcHBlbmQoJyknKS50b1N0cmluZygpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvU3RlcFBhdHRlcm4uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvU3RlcFBhdHRlcm4uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggODI1ODJhZS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL1N0ZXBQYXR0ZXJuLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw1MzQgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogU3RlcFBhdHRlcm4uamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xMiAxMToxMzoxOSBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuY2xhc3NmaWxlLkZpZWxkOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQUxPQUQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5BU1RPUkU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5CcmFuY2hIYW5kbGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5Db25zdGFudFBvb2xHZW47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5HRVRGSUVMRDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkdPVE87Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5HT1RPX1c7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JRkxUOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSUZORTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklGTk9OTlVMTDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklGX0lDTVBFUTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklGX0lDTVBMVDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklGX0lDTVBORTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklMT0FEOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFSU5URVJGQUNFOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFU1BFQ0lBTDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklTVE9SRTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uSGFuZGxlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW5zdHJ1Y3Rpb25MaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuTG9jYWxWYXJpYWJsZUdlbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLk5FVzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlBVU0g7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5QVVRGSUVMRDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5DbGFzc0dlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5NZXRob2RHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlQ2hlY2tFcnJvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5VdGlsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkF4aXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNOwotCi0vKioKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqIEBhdXRob3IgRXJ3aW4gQm9sd2lkdCA8ZWpiQGtsb21wLm9yZz4KLSAqLwotY2xhc3MgU3RlcFBhdHRlcm4gZXh0ZW5kcyBSZWxhdGl2ZVBhdGhQYXR0ZXJuIHsKLQotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBOT19DT05URVhUID0gMDsKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgU0lNUExFX0NPTlRFWFQgPSAxOwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBHRU5FUkFMX0NPTlRFWFQgPSAyOwotCi0gICAgcHJvdGVjdGVkIGZpbmFsIGludCBfYXhpczsKLSAgICBwcm90ZWN0ZWQgZmluYWwgaW50IF9ub2RlVHlwZTsKLSAgICBwcm90ZWN0ZWQgVmVjdG9yIF9wcmVkaWNhdGVzOwotCi0gICAgcHJpdmF0ZSBTdGVwICAgIF9zdGVwID0gbnVsbDsKLSAgICBwcml2YXRlIGJvb2xlYW4gX2lzRXBzaWxvbiA9IGZhbHNlOwotICAgIHByaXZhdGUgaW50ICAgICBfY29udGV4dENhc2U7Ci0KLSAgICBwcml2YXRlIGRvdWJsZSAgX3ByaW9yaXR5ID0gRG91YmxlLk1BWF9WQUxVRTsKLQotICAgIHB1YmxpYyBTdGVwUGF0dGVybihpbnQgYXhpcywgaW50IG5vZGVUeXBlLCBWZWN0b3IgcHJlZGljYXRlcykgewotICAgICAgICBfYXhpcyA9IGF4aXM7Ci0gICAgICAgIF9ub2RlVHlwZSA9IG5vZGVUeXBlOwotICAgICAgICBfcHJlZGljYXRlcyA9IHByZWRpY2F0ZXM7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0UGFyc2VyKFBhcnNlciBwYXJzZXIpIHsKLSAgICAgICAgc3VwZXIuc2V0UGFyc2VyKHBhcnNlcik7Ci0gICAgICAgIGlmIChfcHJlZGljYXRlcyAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmaW5hbCBpbnQgbiA9IF9wcmVkaWNhdGVzLnNpemUoKTsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgZmluYWwgUHJlZGljYXRlIGV4cCA9IChQcmVkaWNhdGUpX3ByZWRpY2F0ZXMuZWxlbWVudEF0KGkpOwotICAgICAgICAgICAgICAgIGV4cC5zZXRQYXJzZXIocGFyc2VyKTsKLSAgICAgICAgICAgICAgICBleHAuc2V0UGFyZW50KHRoaXMpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIGludCBnZXROb2RlVHlwZSgpIHsKLSAgICAgICAgcmV0dXJuIF9ub2RlVHlwZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRQcmlvcml0eShkb3VibGUgcHJpb3JpdHkpIHsKLSAgICAgICAgX3ByaW9yaXR5ID0gcHJpb3JpdHk7Ci0gICAgfQotCi0gICAgcHVibGljIFN0ZXBQYXR0ZXJuIGdldEtlcm5lbFBhdHRlcm4oKSB7Ci0gICAgICAgIHJldHVybiB0aGlzOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGlzV2lsZGNhcmQoKSB7Ci0gICAgICAgIHJldHVybiBfaXNFcHNpbG9uICYmIGhhc1ByZWRpY2F0ZXMoKSA9PSBmYWxzZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RlcFBhdHRlcm4gc2V0UHJlZGljYXRlcyhWZWN0b3IgcHJlZGljYXRlcykgewotICAgICAgICBfcHJlZGljYXRlcyA9IHByZWRpY2F0ZXM7Ci0gICAgICAgIHJldHVybih0aGlzKTsKLSAgICB9Ci0KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBoYXNQcmVkaWNhdGVzKCkgewotICAgICAgICByZXR1cm4gX3ByZWRpY2F0ZXMgIT0gbnVsbCAmJiBfcHJlZGljYXRlcy5zaXplKCkgPiAwOwotICAgIH0KLQotICAgIHB1YmxpYyBkb3VibGUgZ2V0RGVmYXVsdFByaW9yaXR5KCkgewotICAgICAgICBpZiAoX3ByaW9yaXR5ICE9IERvdWJsZS5NQVhfVkFMVUUpIHsKLSAgICAgICAgICAgIHJldHVybiBfcHJpb3JpdHk7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoaGFzUHJlZGljYXRlcygpKSB7Ci0gICAgICAgICAgICByZXR1cm4gMC41OwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgc3dpdGNoKF9ub2RlVHlwZSkgewotICAgICAgICAgICAgY2FzZSAtMToKLSAgICAgICAgICAgICAgICByZXR1cm4gLTAuNTsgICAgLy8gbm9kZSgpCi0gICAgICAgICAgICBjYXNlIDA6Ci0gICAgICAgICAgICAgICAgcmV0dXJuIDAuMDsKLSAgICAgICAgICAgIGRlZmF1bHQ6Ci0gICAgICAgICAgICAgICAgcmV0dXJuIChfbm9kZVR5cGUgPj0gTm9kZVRlc3QuR1RZUEUpID8gMC4wIDogLTAuNTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgZ2V0QXhpcygpIHsKLSAgICAgICAgcmV0dXJuIF9heGlzOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHJlZHVjZUtlcm5lbFBhdHRlcm4oKSB7Ci0gICAgICAgIF9pc0Vwc2lsb24gPSB0cnVlOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0gICAgICAgIGZpbmFsIFN0cmluZ0J1ZmZlciBidWZmZXIgPSBuZXcgU3RyaW5nQnVmZmVyKCJzdGVwUGF0dGVybihcIiIpOwotICAgIGJ1ZmZlci5hcHBlbmQoQXhpcy5nZXROYW1lcyhfYXhpcykpCi0gICAgICAgICAgICAuYXBwZW5kKCJcIiwgIikKLSAgICAgICAgICAgIC5hcHBlbmQoX2lzRXBzaWxvbiA/Ci0gICAgICAgICAgICAgICAgICAgICAgICAoImVwc2lsb257IiArIEludGVnZXIudG9TdHJpbmcoX25vZGVUeXBlKSArICJ9IikgOgotICAgICAgICAgICAgICAgICAgICAgICAgIEludGVnZXIudG9TdHJpbmcoX25vZGVUeXBlKSk7Ci0gICAgICAgIGlmIChfcHJlZGljYXRlcyAhPSBudWxsKQotICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgiLCAiKS5hcHBlbmQoX3ByZWRpY2F0ZXMudG9TdHJpbmcoKSk7Ci0gICAgICAgIHJldHVybiBidWZmZXIuYXBwZW5kKCcpJykudG9TdHJpbmcoKTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIGludCBhbmFseXplQ2FzZXMoKSB7Ci0gICAgICAgIGJvb2xlYW4gbm9Db250ZXh0ID0gdHJ1ZTsKLSAgICAgICAgZmluYWwgaW50IG4gPSBfcHJlZGljYXRlcy5zaXplKCk7Ci0KLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuICYmIG5vQ29udGV4dDsgaSsrKSB7Ci0gICAgICAgICAgICBQcmVkaWNhdGUgcHJlZCA9IChQcmVkaWNhdGUpIF9wcmVkaWNhdGVzLmVsZW1lbnRBdChpKTsKLSAgICAgICAgICAgIGlmIChwcmVkLmlzTnRoUG9zaXRpb25GaWx0ZXIoKSB8fAotICAgICAgICAgICAgICAgIHByZWQuaGFzUG9zaXRpb25DYWxsKCkgfHwKLSAgICAgICAgICAgICAgICBwcmVkLmhhc0xhc3RDYWxsKCkpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgbm9Db250ZXh0ID0gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAobm9Db250ZXh0KSB7Ci0gICAgICAgICAgICByZXR1cm4gTk9fQ09OVEVYVDsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChuID09IDEpIHsKLSAgICAgICAgICAgIHJldHVybiBTSU1QTEVfQ09OVEVYVDsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gR0VORVJBTF9DT05URVhUOwotICAgIH0KLQotICAgIHByaXZhdGUgU3RyaW5nIGdldE5leHRGaWVsZE5hbWUoKSB7Ci0gICAgICAgIHJldHVybiAgIl9fc3RlcF9wYXR0ZXJuX2l0ZXJfIiArIGdldFhTTFRDKCkubmV4dFN0ZXBQYXR0ZXJuU2VyaWFsKCk7Ci0gICAgfQotCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLSAgICAgICAgaWYgKGhhc1ByZWRpY2F0ZXMoKSkgewotICAgICAgICAgICAgLy8gVHlwZSBjaGVjayBhbGwgdGhlIHByZWRpY2F0ZXMgKGUgLT4gcG9zaXRpb24oKSA9IGUpCi0gICAgICAgICAgICBmaW5hbCBpbnQgbiA9IF9wcmVkaWNhdGVzLnNpemUoKTsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgZmluYWwgUHJlZGljYXRlIHByZWQgPSAoUHJlZGljYXRlKV9wcmVkaWNhdGVzLmVsZW1lbnRBdChpKTsKLSAgICAgICAgICAgICAgICBwcmVkLnR5cGVDaGVjayhzdGFibGUpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBBbmFseXplIGNvbnRleHQgY2FzZXMKLSAgICAgICAgICAgIF9jb250ZXh0Q2FzZSA9IGFuYWx5emVDYXNlcygpOwotCi0gICAgICAgICAgICBTdGVwIHN0ZXAgPSBudWxsOwotCi0gICAgICAgICAgICAvLyBDcmVhdGUgYW4gaW5zdGFuY2Ugb2YgU3RlcCB0byBkbyB0aGUgdHJhbnNsYXRpb24KLSAgICAgICAgICAgIGlmIChfY29udGV4dENhc2UgPT0gU0lNUExFX0NPTlRFWFQpIHsKLSAgICAgICAgICAgICAgICBQcmVkaWNhdGUgcHJlZCA9IChQcmVkaWNhdGUpX3ByZWRpY2F0ZXMuZWxlbWVudEF0KDApOwotICAgICAgICAgICAgICAgIGlmIChwcmVkLmlzTnRoUG9zaXRpb25GaWx0ZXIoKSkgewotICAgICAgICAgICAgICAgICAgICBfY29udGV4dENhc2UgPSBHRU5FUkFMX0NPTlRFWFQ7Ci0gICAgICAgICAgICAgICAgICAgIHN0ZXAgPSBuZXcgU3RlcChfYXhpcywgX25vZGVUeXBlLCBfcHJlZGljYXRlcyk7Ci0gICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgc3RlcCA9IG5ldyBTdGVwKF9heGlzLCBfbm9kZVR5cGUsIG51bGwpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0gZWxzZSBpZiAoX2NvbnRleHRDYXNlID09IEdFTkVSQUxfQ09OVEVYVCkgewotICAgICAgICAgICAgICAgIGZpbmFsIGludCBsZW4gPSBfcHJlZGljYXRlcy5zaXplKCk7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW47IGkrKykgewotICAgICAgICAgICAgICAgICAgICAoKFByZWRpY2F0ZSlfcHJlZGljYXRlcy5lbGVtZW50QXQoaSkpLmRvbnRPcHRpbWl6ZSgpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIHN0ZXAgPSBuZXcgU3RlcChfYXhpcywgX25vZGVUeXBlLCBfcHJlZGljYXRlcyk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmIChzdGVwICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBzdGVwLnNldFBhcnNlcihnZXRQYXJzZXIoKSk7Ci0gICAgICAgICAgICAgICAgc3RlcC50eXBlQ2hlY2soc3RhYmxlKTsKLSAgICAgICAgICAgICAgICBfc3RlcCA9IHN0ZXA7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIF9heGlzID09IEF4aXMuQ0hJTEQgPyBUeXBlLkVsZW1lbnQgOiBUeXBlLkF0dHJpYnV0ZTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgdHJhbnNsYXRlS2VybmVsKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotICAgICAgICBmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQotICAgICAgICBpZiAoX25vZGVUeXBlID09IERUTS5FTEVNRU5UX05PREUpIHsKLSAgICAgICAgICAgIGZpbmFsIGludCBjaGVjayA9IGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoRE9NX0lOVEYsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJpc0VsZW1lbnQiLCAiKEkpWiIpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkRE9NKCkpOwotICAgICAgICAgICAgaWwuYXBwZW5kKFNXQVApOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0UoY2hlY2ssIDIpKTsKLQotICAgICAgICAgICAgLy8gTmVlZCB0byBhbGxvdyBmb3IgbG9uZyBqdW1wcyBoZXJlCi0gICAgICAgICAgICBmaW5hbCBCcmFuY2hIYW5kbGUgaWNtcCA9IGlsLmFwcGVuZChuZXcgSUZORShudWxsKSk7Ci0gICAgICAgICAgICBfZmFsc2VMaXN0LmFkZChpbC5hcHBlbmQobmV3IEdPVE9fVyhudWxsKSkpOwotICAgICAgICAgICAgaWNtcC5zZXRUYXJnZXQoaWwuYXBwZW5kKE5PUCkpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKF9ub2RlVHlwZSA9PSBEVE0uQVRUUklCVVRFX05PREUpIHsKLSAgICAgICAgICAgIGZpbmFsIGludCBjaGVjayA9IGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoRE9NX0lOVEYsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJpc0F0dHJpYnV0ZSIsICIoSSlaIik7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQoU1dBUCk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRUlOVEVSRkFDRShjaGVjaywgMikpOwotCi0gICAgICAgICAgICAvLyBOZWVkIHRvIGFsbG93IGZvciBsb25nIGp1bXBzIGhlcmUKLSAgICAgICAgICAgIGZpbmFsIEJyYW5jaEhhbmRsZSBpY21wID0gaWwuYXBwZW5kKG5ldyBJRk5FKG51bGwpKTsKLSAgICAgICAgICAgIF9mYWxzZUxpc3QuYWRkKGlsLmFwcGVuZChuZXcgR09UT19XKG51bGwpKSk7Ci0gICAgICAgICAgICBpY21wLnNldFRhcmdldChpbC5hcHBlbmQoTk9QKSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAvLyBjb250ZXh0IG5vZGUgaXMgb24gdGhlIHN0YWNrCi0gICAgICAgICAgICBmaW5hbCBpbnQgZ2V0RVR5cGUgPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKERPTV9JTlRGLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJnZXRFeHBhbmRlZFR5cGVJRCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIihJKUkiKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChTV0FQKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFSU5URVJGQUNFKGdldEVUeXBlLCAyKSk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBfbm9kZVR5cGUpKTsKLQotICAgICAgICAgICAgLy8gTmVlZCB0byBhbGxvdyBmb3IgbG9uZyBqdW1wcyBoZXJlCi0gICAgICAgICAgICBmaW5hbCBCcmFuY2hIYW5kbGUgaWNtcCA9IGlsLmFwcGVuZChuZXcgSUZfSUNNUEVRKG51bGwpKTsKLSAgICAgICAgICAgIF9mYWxzZUxpc3QuYWRkKGlsLmFwcGVuZChuZXcgR09UT19XKG51bGwpKSk7Ci0gICAgICAgICAgICBpY21wLnNldFRhcmdldChpbC5hcHBlbmQoTk9QKSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgdHJhbnNsYXRlTm9Db250ZXh0KENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotICAgICAgICBmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQotICAgICAgICAvLyBQdXNoIGN1cnJlbnQgbm9kZSBvbiB0aGUgc3RhY2sKLSAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkQ3VycmVudE5vZGUoKSk7Ci0gICAgICAgIGlsLmFwcGVuZChTV0FQKTsKLQotICAgICAgICAvLyBPdmVyd3JpdGUgY3VycmVudCBub2RlIHdpdGggbWF0Y2hpbmcgbm9kZQotICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLnN0b3JlQ3VycmVudE5vZGUoKSk7Ci0KLSAgICAgICAgLy8gSWYgcGF0dGVybiBub3QgcmVkdWNlZCB0aGVuIGNoZWNrIGtlcm5lbAotICAgICAgICBpZiAoIV9pc0Vwc2lsb24pIHsKLSAgICAgICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZEN1cnJlbnROb2RlKCkpOwotICAgICAgICAgICAgdHJhbnNsYXRlS2VybmVsKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gQ29tcGlsZSB0aGUgZXhwcmVzc2lvbnMgd2l0aGluIHRoZSBwcmVkaWNhdGVzCi0gICAgICAgIGZpbmFsIGludCBuID0gX3ByZWRpY2F0ZXMuc2l6ZSgpOwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykgewotICAgICAgICAgICAgUHJlZGljYXRlIHByZWQgPSAoUHJlZGljYXRlKV9wcmVkaWNhdGVzLmVsZW1lbnRBdChpKTsKLSAgICAgICAgICAgIEV4cHJlc3Npb24gZXhwID0gcHJlZC5nZXRFeHByKCk7Ci0gICAgICAgICAgICBleHAudHJhbnNsYXRlRGVzeW50aGVzaXplZChjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgICAgIF90cnVlTGlzdC5hcHBlbmQoZXhwLl90cnVlTGlzdCk7Ci0gICAgICAgICAgICBfZmFsc2VMaXN0LmFwcGVuZChleHAuX2ZhbHNlTGlzdCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBCYWNrcGF0Y2ggdHJ1ZSBsaXN0IGFuZCByZXN0b3JlIGN1cnJlbnQgaXRlcmF0b3Ivbm9kZQotICAgICAgICBJbnN0cnVjdGlvbkhhbmRsZSByZXN0b3JlOwotICAgICAgICByZXN0b3JlID0gaWwuYXBwZW5kKG1ldGhvZEdlbi5zdG9yZUN1cnJlbnROb2RlKCkpOwotICAgICAgICBiYWNrUGF0Y2hUcnVlTGlzdChyZXN0b3JlKTsKLSAgICAgICAgQnJhbmNoSGFuZGxlIHNraXBGYWxzZSA9IGlsLmFwcGVuZChuZXcgR09UTyhudWxsKSk7Ci0KLSAgICAgICAgLy8gQmFja3BhdGNoIGZhbHNlIGxpc3QgYW5kIHJlc3RvcmUgY3VycmVudCBpdGVyYXRvci9ub2RlCi0gICAgICAgIHJlc3RvcmUgPSBpbC5hcHBlbmQobWV0aG9kR2VuLnN0b3JlQ3VycmVudE5vZGUoKSk7Ci0gICAgICAgIGJhY2tQYXRjaEZhbHNlTGlzdChyZXN0b3JlKTsKLSAgICAgICAgX2ZhbHNlTGlzdC5hZGQoaWwuYXBwZW5kKG5ldyBHT1RPKG51bGwpKSk7Ci0KLSAgICAgICAgLy8gVHJ1ZSBsaXN0IGZhbGxzIHRocm91Z2gKLSAgICAgICAgc2tpcEZhbHNlLnNldFRhcmdldChpbC5hcHBlbmQoTk9QKSk7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIHRyYW5zbGF0ZVNpbXBsZUNvbnRleHQoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotICAgICAgICBpbnQgaW5kZXg7Ci0gICAgICAgIGZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCi0gICAgICAgIC8vIFN0b3JlIG1hdGNoaW5nIG5vZGUgaW50byBhIGxvY2FsIHZhcmlhYmxlCi0gICAgICAgIExvY2FsVmFyaWFibGVHZW4gbWF0Y2g7Ci0gICAgICAgIG1hdGNoID0gbWV0aG9kR2VuLmFkZExvY2FsVmFyaWFibGUoInN0ZXBfcGF0dGVybl90bXAxIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVdGlsLmdldEpDUmVmVHlwZShOT0RFX1NJRyksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwgbnVsbCk7Ci0gICAgICAgIG1hdGNoLnNldFN0YXJ0KGlsLmFwcGVuZChuZXcgSVNUT1JFKG1hdGNoLmdldEluZGV4KCkpKSk7Ci0KLSAgICAgICAgLy8gSWYgcGF0dGVybiBub3QgcmVkdWNlZCB0aGVuIGNoZWNrIGtlcm5lbAotICAgICAgICBpZiAoIV9pc0Vwc2lsb24pIHsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSUxPQUQobWF0Y2guZ2V0SW5kZXgoKSkpOwotICAgICAgICAgICAgdHJhbnNsYXRlS2VybmVsKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gUHVzaCBjdXJyZW50IGl0ZXJhdG9yIGFuZCBjdXJyZW50IG5vZGUgb24gdGhlIHN0YWNrCi0gICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZEN1cnJlbnROb2RlKCkpOwotICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRJdGVyYXRvcigpKTsKLQotICAgICAgICAvLyBDcmVhdGUgYSBuZXcgbWF0Y2hpbmcgaXRlcmF0b3IgdXNpbmcgdGhlIG1hdGNoaW5nIG5vZGUKLSAgICAgICAgaW5kZXggPSBjcGcuYWRkTWV0aG9kcmVmKE1BVENISU5HX0lURVJBVE9SLCAiPGluaXQ+IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoSSIgKyBOT0RFX0lURVJBVE9SX1NJRyArICIpViIpOwotCi0gICAgICAgIC8vIEJhY2t3YXJkcyBicmFuY2hlcyBhcmUgcHJvaGliaXRlZCBpZiBhbiB1bmluaXRpYWxpemVkIG9iamVjdCBpcwotICAgICAgICAvLyBvbiB0aGUgc3RhY2sgYnkgc2VjdGlvbiA0LjkuNCBvZiB0aGUgSlZNIFNwZWNpZmljYXRpb24sIDJuZCBFZC4KLSAgICAgICAgLy8gV2UgZG9uJ3Qga25vdyB3aGV0aGVyIHRoaXMgY29kZSBtaWdodCBjb250YWluIGJhY2t3YXJkcyBicmFuY2hlcywKLSAgICAgICAgLy8gc28gd2UgbXVzdG4ndCBjcmVhdGUgdGhlIG5ldyBvYmplY3QgdW50aWwgYWZ0ZXIgd2UndmUgY3JlYXRlZAotICAgICAgICAvLyB0aGUgc3VzcGVjdCBhcmd1bWVudHMgdG8gaXRzIGNvbnN0cnVjdG9yLiAgSW5zdGVhZCB3ZSBjYWxjdWxhdGUKLSAgICAgICAgLy8gdGhlIHZhbHVlcyBvZiB0aGUgYXJndW1lbnRzIHRvIHRoZSBjb25zdHJ1Y3RvciBmaXJzdCwgc3RvcmUgdGhlbQotICAgICAgICAvLyBpbiB0ZW1wb3JhcnkgdmFyaWFibGVzLCBjcmVhdGUgdGhlIG9iamVjdCBhbmQgcmVsb2FkIHRoZQotICAgICAgICAvLyBhcmd1bWVudHMgZnJvbSB0aGUgdGVtcG9yYXJpZXMgdG8gYXZvaWQgdGhlIHByb2JsZW0uCi0KLSAgICAgICAgX3N0ZXAudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICBMb2NhbFZhcmlhYmxlR2VuIHN0ZXBJdGVyYXRvclRlbXAgPQotICAgICAgICAgICAgICAgIG1ldGhvZEdlbi5hZGRMb2NhbFZhcmlhYmxlKCJzdGVwX3BhdHRlcm5fdG1wMiIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVXRpbC5nZXRKQ1JlZlR5cGUoTk9ERV9JVEVSQVRPUl9TSUcpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsIG51bGwpOwotICAgICAgICBzdGVwSXRlcmF0b3JUZW1wLnNldFN0YXJ0KAotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgQVNUT1JFKHN0ZXBJdGVyYXRvclRlbXAuZ2V0SW5kZXgoKSkpKTsKLQotICAgICAgICBpbC5hcHBlbmQobmV3IE5FVyhjcGcuYWRkQ2xhc3MoTUFUQ0hJTkdfSVRFUkFUT1IpKSk7Ci0gICAgICAgIGlsLmFwcGVuZChEVVApOwotICAgICAgICBpbC5hcHBlbmQobmV3IElMT0FEKG1hdGNoLmdldEluZGV4KCkpKTsKLSAgICAgICAgc3RlcEl0ZXJhdG9yVGVtcC5zZXRFbmQoCi0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBBTE9BRChzdGVwSXRlcmF0b3JUZW1wLmdldEluZGV4KCkpKSk7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFU1BFQ0lBTChpbmRleCkpOwotCi0gICAgICAgIC8vIEdldCB0aGUgcGFyZW50IG9mIHRoZSBtYXRjaGluZyBub2RlCi0gICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBJTE9BRChtYXRjaC5nZXRJbmRleCgpKSk7Ci0gICAgICAgIGluZGV4ID0gY3BnLmFkZEludGVyZmFjZU1ldGhvZHJlZihET01fSU5URiwgR0VUX1BBUkVOVCwgR0VUX1BBUkVOVF9TSUcpOwotICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRUlOVEVSRkFDRShpbmRleCwgMikpOwotCi0gICAgICAgIC8vIFN0YXJ0IHRoZSBpdGVyYXRvciB3aXRoIHRoZSBwYXJlbnQKLSAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5zZXRTdGFydE5vZGUoKSk7Ci0KLSAgICAgICAgLy8gT3ZlcndyaXRlIGN1cnJlbnQgaXRlcmF0b3IgYW5kIGN1cnJlbnQgbm9kZQotICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLnN0b3JlSXRlcmF0b3IoKSk7Ci0gICAgICAgIG1hdGNoLnNldEVuZChpbC5hcHBlbmQobmV3IElMT0FEKG1hdGNoLmdldEluZGV4KCkpKSk7Ci0gICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4uc3RvcmVDdXJyZW50Tm9kZSgpKTsKLQotICAgICAgICAvLyBUcmFuc2xhdGUgdGhlIGV4cHJlc3Npb24gb2YgdGhlIHByZWRpY2F0ZQotICAgICAgICBQcmVkaWNhdGUgcHJlZCA9IChQcmVkaWNhdGUpIF9wcmVkaWNhdGVzLmVsZW1lbnRBdCgwKTsKLSAgICAgICAgRXhwcmVzc2lvbiBleHAgPSBwcmVkLmdldEV4cHIoKTsKLSAgICAgICAgZXhwLnRyYW5zbGF0ZURlc3ludGhlc2l6ZWQoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0KLSAgICAgICAgLy8gQmFja3BhdGNoIHRydWUgbGlzdCBhbmQgcmVzdG9yZSBjdXJyZW50IGl0ZXJhdG9yL25vZGUKLSAgICAgICAgSW5zdHJ1Y3Rpb25IYW5kbGUgcmVzdG9yZSA9IGlsLmFwcGVuZChtZXRob2RHZW4uc3RvcmVJdGVyYXRvcigpKTsKLSAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5zdG9yZUN1cnJlbnROb2RlKCkpOwotICAgICAgICBleHAuYmFja1BhdGNoVHJ1ZUxpc3QocmVzdG9yZSk7Ci0gICAgICAgIEJyYW5jaEhhbmRsZSBza2lwRmFsc2UgPSBpbC5hcHBlbmQobmV3IEdPVE8obnVsbCkpOwotCi0gICAgICAgIC8vIEJhY2twYXRjaCBmYWxzZSBsaXN0IGFuZCByZXN0b3JlIGN1cnJlbnQgaXRlcmF0b3Ivbm9kZQotICAgICAgICByZXN0b3JlID0gaWwuYXBwZW5kKG1ldGhvZEdlbi5zdG9yZUl0ZXJhdG9yKCkpOwotICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLnN0b3JlQ3VycmVudE5vZGUoKSk7Ci0gICAgICAgIGV4cC5iYWNrUGF0Y2hGYWxzZUxpc3QocmVzdG9yZSk7Ci0gICAgICAgIF9mYWxzZUxpc3QuYWRkKGlsLmFwcGVuZChuZXcgR09UTyhudWxsKSkpOwotCi0gICAgICAgIC8vIFRydWUgbGlzdCBmYWxscyB0aHJvdWdoCi0gICAgICAgIHNraXBGYWxzZS5zZXRUYXJnZXQoaWwuYXBwZW5kKE5PUCkpOwotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCB0cmFuc2xhdGVHZW5lcmFsQ29udGV4dChDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotICAgICAgICBmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQotICAgICAgICBpbnQgaXRlcmF0b3JJbmRleCA9IDA7Ci0gICAgICAgIEJyYW5jaEhhbmRsZSBpZkJsb2NrID0gbnVsbDsKLSAgICAgICAgTG9jYWxWYXJpYWJsZUdlbiBpdGVyLCBub2RlLCBub2RlMjsKLSAgICAgICAgZmluYWwgU3RyaW5nIGl0ZXJhdG9yTmFtZSA9IGdldE5leHRGaWVsZE5hbWUoKTsKLQotICAgICAgICAvLyBTdG9yZSBub2RlIG9uIHRoZSBzdGFjayBpbnRvIGEgbG9jYWwgdmFyaWFibGUKLSAgICAgICAgbm9kZSA9IG1ldGhvZEdlbi5hZGRMb2NhbFZhcmlhYmxlKCJzdGVwX3BhdHRlcm5fdG1wMSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVdGlsLmdldEpDUmVmVHlwZShOT0RFX1NJRyksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLCBudWxsKTsKLSAgICAgICAgbm9kZS5zZXRTdGFydChpbC5hcHBlbmQobmV3IElTVE9SRShub2RlLmdldEluZGV4KCkpKSk7Ci0KLSAgICAgICAgLy8gQ3JlYXRlIGEgbmV3IGxvY2FsIHRvIHN0b3JlIHRoZSBpdGVyYXRvcgotICAgICAgICBpdGVyID0gbWV0aG9kR2VuLmFkZExvY2FsVmFyaWFibGUoInN0ZXBfcGF0dGVybl90bXAyIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFV0aWwuZ2V0SkNSZWZUeXBlKE5PREVfSVRFUkFUT1JfU0lHKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsIG51bGwpOwotCi0gICAgICAgIC8vIEFkZCBhIG5ldyBwcml2YXRlIGZpZWxkIGlmIHRoaXMgaXMgdGhlIG1haW4gY2xhc3MKLSAgICAgICAgaWYgKCFjbGFzc0dlbi5pc0V4dGVybmFsKCkpIHsKLSAgICAgICAgICAgIGZpbmFsIEZpZWxkIGl0ZXJhdG9yID0KLSAgICAgICAgICAgICAgICBuZXcgRmllbGQoQUNDX1BSSVZBVEUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIGNwZy5hZGRVdGY4KGl0ZXJhdG9yTmFtZSksCi0gICAgICAgICAgICAgICAgICAgICAgICAgIGNwZy5hZGRVdGY4KE5PREVfSVRFUkFUT1JfU0lHKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwgY3BnLmdldENvbnN0YW50UG9vbCgpKTsKLSAgICAgICAgICAgIGNsYXNzR2VuLmFkZEZpZWxkKGl0ZXJhdG9yKTsKLSAgICAgICAgICAgIGl0ZXJhdG9ySW5kZXggPSBjcGcuYWRkRmllbGRyZWYoY2xhc3NHZW4uZ2V0Q2xhc3NOYW1lKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZXJhdG9yTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTk9ERV9JVEVSQVRPUl9TSUcpOwotCi0gICAgICAgICAgICBpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBHRVRGSUVMRChpdGVyYXRvckluZGV4KSk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQoRFVQKTsKLSAgICAgICAgICAgIGl0ZXIuc2V0U3RhcnQoaWwuYXBwZW5kKG5ldyBBU1RPUkUoaXRlci5nZXRJbmRleCgpKSkpOwotICAgICAgICAgICAgaWZCbG9jayA9IGlsLmFwcGVuZChuZXcgSUZOT05OVUxMKG51bGwpKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChjbGFzc0dlbi5sb2FkVHJhbnNsZXQoKSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBDb21waWxlIHRoZSBzdGVwIGNyZWF0ZWQgYXQgdHlwZSBjaGVja2luZyB0aW1lCi0gICAgICAgIF9zdGVwLnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgSW5zdHJ1Y3Rpb25IYW5kbGUgaXRlclN0b3JlID0gaWwuYXBwZW5kKG5ldyBBU1RPUkUoaXRlci5nZXRJbmRleCgpKSk7Ci0KLSAgICAgICAgLy8gSWYgaW4gdGhlIG1haW4gY2xhc3MgdXBkYXRlIHRoZSBmaWVsZCB0b28KLSAgICAgICAgaWYgKCFjbGFzc0dlbi5pc0V4dGVybmFsKCkpIHsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgQUxPQUQoaXRlci5nZXRJbmRleCgpKSk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IFBVVEZJRUxEKGl0ZXJhdG9ySW5kZXgpKTsKLSAgICAgICAgICAgIGlmQmxvY2suc2V0VGFyZ2V0KGlsLmFwcGVuZChOT1ApKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIC8vIElmIGNsYXNzIGlzIG5vdCBleHRlcm5hbCwgc3RhcnQgb2YgcmFuZ2UgZm9yIGl0ZXIgdmFyaWFibGUgd2FzCi0gICAgICAgICAgICAvLyBzZXQgYWJvdmUKLSAgICAgICAgICAgIGl0ZXIuc2V0U3RhcnQoaXRlclN0b3JlKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIEdldCB0aGUgcGFyZW50IG9mIHRoZSBub2RlIG9uIHRoZSBzdGFjawotICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgSUxPQUQobm9kZS5nZXRJbmRleCgpKSk7Ci0gICAgICAgIGludCBpbmRleCA9IGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoRE9NX0lOVEYsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR0VUX1BBUkVOVCwgR0VUX1BBUkVOVF9TSUcpOwotICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRUlOVEVSRkFDRShpbmRleCwgMikpOwotCi0gICAgICAgIC8vIEluaXRpYWxpemUgdGhlIGl0ZXJhdG9yIHdpdGggdGhlIHBhcmVudAotICAgICAgICBpbC5hcHBlbmQobmV3IEFMT0FEKGl0ZXIuZ2V0SW5kZXgoKSkpOwotICAgICAgICBpbC5hcHBlbmQoU1dBUCk7Ci0gICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4uc2V0U3RhcnROb2RlKCkpOwotCi0gICAgICAgIC8qCi0gICAgICAgICAqIElubGluZSBsb29wOgotICAgICAgICAgKgotICAgICAgICAgKiBpbnQgbm9kZTI7Ci0gICAgICAgICAqIHdoaWxlICgobm9kZTIgPSBpdGVyLm5leHQoKSkgIT0gTm9kZUl0ZXJhdG9yLkVORAotICAgICAgICAgKiAgICAgICAgICAgICAgICAmJiBub2RlMiA8IG5vZGUpOwotICAgICAgICAgKiByZXR1cm4gbm9kZTIgPT0gbm9kZTsKLSAgICAgICAgICovCi0gICAgICAgIEJyYW5jaEhhbmRsZSBza2lwTmV4dDsKLSAgICAgICAgSW5zdHJ1Y3Rpb25IYW5kbGUgYmVnaW4sIG5leHQ7Ci0gICAgICAgIG5vZGUyID0gbWV0aG9kR2VuLmFkZExvY2FsVmFyaWFibGUoInN0ZXBfcGF0dGVybl90bXAzIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVdGlsLmdldEpDUmVmVHlwZShOT0RFX1NJRyksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwgbnVsbCk7Ci0KLSAgICAgICAgc2tpcE5leHQgPSBpbC5hcHBlbmQobmV3IEdPVE8obnVsbCkpOwotICAgICAgICBuZXh0ID0gaWwuYXBwZW5kKG5ldyBBTE9BRChpdGVyLmdldEluZGV4KCkpKTsKLSAgICAgICAgbm9kZTIuc2V0U3RhcnQobmV4dCk7Ci0gICAgICAgIGJlZ2luID0gaWwuYXBwZW5kKG1ldGhvZEdlbi5uZXh0Tm9kZSgpKTsKLSAgICAgICAgaWwuYXBwZW5kKERVUCk7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgSVNUT1JFKG5vZGUyLmdldEluZGV4KCkpKTsKLSAgICAgICAgX2ZhbHNlTGlzdC5hZGQoaWwuYXBwZW5kKG5ldyBJRkxUKG51bGwpKSk7ICAgICAgLy8gTm9kZUl0ZXJhdG9yLkVORAotCi0gICAgICAgIGlsLmFwcGVuZChuZXcgSUxPQUQobm9kZTIuZ2V0SW5kZXgoKSkpOwotICAgICAgICBpbC5hcHBlbmQobmV3IElMT0FEKG5vZGUuZ2V0SW5kZXgoKSkpOwotICAgICAgICBpdGVyLnNldEVuZChpbC5hcHBlbmQobmV3IElGX0lDTVBMVChuZXh0KSkpOwotCi0gICAgICAgIG5vZGUyLnNldEVuZChpbC5hcHBlbmQobmV3IElMT0FEKG5vZGUyLmdldEluZGV4KCkpKSk7Ci0gICAgICAgIG5vZGUuc2V0RW5kKGlsLmFwcGVuZChuZXcgSUxPQUQobm9kZS5nZXRJbmRleCgpKSkpOwotICAgICAgICBfZmFsc2VMaXN0LmFkZChpbC5hcHBlbmQobmV3IElGX0lDTVBORShudWxsKSkpOwotCi0gICAgICAgIHNraXBOZXh0LnNldFRhcmdldChiZWdpbik7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0gICAgICAgIGZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCi0gICAgICAgIGlmIChoYXNQcmVkaWNhdGVzKCkpIHsKLSAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHRDYXNlKSB7Ci0gICAgICAgICAgICBjYXNlIE5PX0NPTlRFWFQ6Ci0gICAgICAgICAgICAgICAgdHJhbnNsYXRlTm9Db250ZXh0KGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgICAgICBjYXNlIFNJTVBMRV9DT05URVhUOgotICAgICAgICAgICAgICAgIHRyYW5zbGF0ZVNpbXBsZUNvbnRleHQoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgICAgIGRlZmF1bHQ6Ci0gICAgICAgICAgICAgICAgdHJhbnNsYXRlR2VuZXJhbENvbnRleHQoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoaXNXaWxkY2FyZCgpKSB7Ci0gICAgICAgICAgICBpbC5hcHBlbmQoUE9QKTsgICAgIC8vIHRydWUgbGlzdCBmYWxscyB0aHJvdWdoCi0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICB0cmFuc2xhdGVLZXJuZWwoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgIH0KLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL1N0cmluZ0NhbGwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvU3RyaW5nQ2FsbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjZTJkOThhLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvU3RyaW5nQ2FsbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNzYgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogU3RyaW5nQ2FsbC5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzA1IDA5OjA4OjE1IHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uTGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5DbGFzc0dlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5FcnJvck1zZzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5NZXRob2RHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlQ2hlY2tFcnJvcjsKLQotLyoqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKi8KLWZpbmFsIGNsYXNzIFN0cmluZ0NhbGwgZXh0ZW5kcyBGdW5jdGlvbkNhbGwgewotICAgIHB1YmxpYyBTdHJpbmdDYWxsKFFOYW1lIGZuYW1lLCBWZWN0b3IgYXJndW1lbnRzKSB7Ci0gICAgICAgIHN1cGVyKGZuYW1lLCBhcmd1bWVudHMpOwotICAgIH0KLQotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0gICAgICAgIGZpbmFsIGludCBhcmdjID0gYXJndW1lbnRDb3VudCgpOwotICAgICAgICBpZiAoYXJnYyA+IDEpIHsKLSAgICAgICAgICAgIEVycm9yTXNnIGVyciA9IG5ldyBFcnJvck1zZyhFcnJvck1zZy5JTExFR0FMX0FSR19FUlIsIHRoaXMpOwotICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVDaGVja0Vycm9yKGVycik7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoYXJnYyA+IDApIHsKLSAgICAgICAgICAgIGFyZ3VtZW50KCkudHlwZUNoZWNrKHN0YWJsZSk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIF90eXBlID0gVHlwZS5TdHJpbmc7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLSAgICAgICAgVHlwZSB0YXJnOwotCi0gICAgICAgIGlmIChhcmd1bWVudENvdW50KCkgPT0gMCkgewotICAgICAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkQ29udGV4dE5vZGUoKSk7Ci0gICAgICAgICAgICB0YXJnID0gVHlwZS5Ob2RlOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgZmluYWwgRXhwcmVzc2lvbiBhcmcgPSBhcmd1bWVudCgpOwotICAgICAgICAgICAgYXJnLnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgICAgIGFyZy5zdGFydEl0ZXJhdG9yKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICAgICAgdGFyZyA9IGFyZy5nZXRUeXBlKCk7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoIXRhcmcuaWRlbnRpY2FsVG8oVHlwZS5TdHJpbmcpKSB7Ci0gICAgICAgICAgICB0YXJnLnRyYW5zbGF0ZVRvKGNsYXNzR2VuLCBtZXRob2RHZW4sIFR5cGUuU3RyaW5nKTsKLSAgICAgICAgfQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvU3RyaW5nTGVuZ3RoQ2FsbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9TdHJpbmdMZW5ndGhDYWxsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDIxMmE2ZDguLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9TdHJpbmdMZW5ndGhDYWxsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw1OCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBTdHJpbmdMZW5ndGhDYWxsLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMDUgMDk6MDg6NDYgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQ29uc3RhbnRQb29sR2VuOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFU1RBVElDOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW5zdHJ1Y3Rpb25MaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkNsYXNzR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLk1ldGhvZEdlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotCi0vKioKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqLwotZmluYWwgY2xhc3MgU3RyaW5nTGVuZ3RoQ2FsbCBleHRlbmRzIEZ1bmN0aW9uQ2FsbCB7Ci0gICAgcHVibGljIFN0cmluZ0xlbmd0aENhbGwoUU5hbWUgZm5hbWUsIFZlY3RvciBhcmd1bWVudHMpIHsKLSAgICAgICAgc3VwZXIoZm5hbWUsIGFyZ3VtZW50cyk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0gICAgICAgIGZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotICAgICAgICBpZiAoYXJndW1lbnRDb3VudCgpID4gMCkgewotICAgICAgICAgICAgYXJndW1lbnQoKS50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRDb250ZXh0Tm9kZSgpKTsKLSAgICAgICAgICAgIFR5cGUuTm9kZS50cmFuc2xhdGVUbyhjbGFzc0dlbiwgbWV0aG9kR2VuLCBUeXBlLlN0cmluZyk7Ci0gICAgICAgIH0KLSAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VTVEFUSUMoY3BnLmFkZE1ldGhvZHJlZihCQVNJU19MSUJSQVJZX0NMQVNTLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZ2V0U3RyaW5nTGVuZ3RoIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIihMamF2YS9sYW5nL1N0cmluZzspSSIpKSk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9TdHlsZXNoZWV0LmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL1N0eWxlc2hlZXQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDkwNjFlYS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL1N0eWxlc2hlZXQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE0NDcgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwNywgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqLwotLyoKLSAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQotICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCi0gKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCi0gKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAotICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKLSAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogU3R5bGVzaGVldC5qYXZhLHYgMS41IDIwMDUvMDkvMjggMTM6NDg6MTYgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5BTkVXQVJSQVk7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5CYXNpY1R5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5Db25zdGFudFBvb2xHZW47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5GaWVsZEdlbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkdFVEZJRUxEOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuR0VUU1RBVElDOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFSU5URVJGQUNFOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFU1BFQ0lBTDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklOVk9LRVNUQVRJQzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklOVk9LRVZJUlRVQUw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JU1RPUkU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JbnN0cnVjdGlvbkhhbmRsZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uTGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkxvY2FsVmFyaWFibGVHZW47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5ORVc7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5ORVdBUlJBWTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlBVU0g7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5QVVRGSUVMRDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlBVVFNUQVRJQzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlRhcmdldExvc3RFeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwudXRpbC5JbnN0cnVjdGlvbkZpbmRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5DbGFzc0dlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5FcnJvck1zZzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5NZXRob2RHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlQ2hlY2tFcnJvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5VdGlsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5ydW50aW1lLkFic3RyYWN0VHJhbnNsZXQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuU3lzdGVtSURSZXNvbHZlcjsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKLWltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7Ci1pbXBvcnQgamF2YS51dGlsLkxpc3Q7Ci1pbXBvcnQgamF2YS51dGlsLk1hcDsKLWltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKLWltcG9ydCBqYXZhLnV0aWwuU3RyaW5nVG9rZW5pemVyOwotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLS8qKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBTdHlsZXNoZWV0IGV4dGVuZHMgU3ludGF4VHJlZU5vZGUgewotCi0gICAgLyoqCi0gICAgICogWFNMVCB2ZXJzaW9uIGRlZmluZWQgaW4gdGhlIHN0eWxlc2hlZXQuCi0gICAgICovCi0gICAgcHJpdmF0ZSBTdHJpbmcgX3ZlcnNpb247Ci0KLSAgICAvKioKLSAgICAgKiBJbnRlcm5hbCBuYW1lIG9mIHRoaXMgc3R5bGVzaGVldCB1c2VkIGFzIGEga2V5IGludG8gdGhlIHN5bWJvbCB0YWJsZS4KLSAgICAgKi8KLSAgICBwcml2YXRlIFFOYW1lIF9uYW1lOwotCi0gICAgLyoqCi0gICAgICogQSBVUkkgdGhhdCByZXByZXNlbnRzIHRoZSBzeXN0ZW0gSUQgZm9yIHRoaXMgc3R5bGVzaGVldC4KLSAgICAgKi8KLSAgICBwcml2YXRlIFN0cmluZyBfc3lzdGVtSWQ7Ci0KLSAgICAvKioKLSAgICAgKiBBIHJlZmVyZW5jZSB0byB0aGUgcGFyZW50IHN0eWxlc2hlZXQgb3IgbnVsbCBpZiB0b3Btb3N0LgotICAgICAqLwotICAgIHByaXZhdGUgU3R5bGVzaGVldCBfcGFyZW50U3R5bGVzaGVldDsKLQotICAgIC8qKgotICAgICAqIENvbnRhaW5zIGdsb2JhbCB2YXJpYWJsZXMgYW5kIHBhcmFtZXRlcnMgZGVmaW5lZCBpbiB0aGUgc3R5bGVzaGVldC4KLSAgICAgKi8KLSAgICBwcml2YXRlIFZlY3RvciBfZ2xvYmFscyA9IG5ldyBWZWN0b3IoKTsKLQotICAgIC8qKgotICAgICAqIFVzZWQgdG8gY2FjaGUgdGhlIHJlc3VsdCByZXR1cm5lZCBieSA8Y29kZT5oYXNMb2NhbFBhcmFtcygpPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwcml2YXRlIEJvb2xlYW4gX2hhc0xvY2FsUGFyYW1zID0gbnVsbDsKLQotICAgIC8qKgotICAgICAqIFRoZSBuYW1lIG9mIHRoZSBjbGFzcyBiZWluZyBnZW5lcmF0ZWQuCi0gICAgICovCi0gICAgcHJpdmF0ZSBTdHJpbmcgX2NsYXNzTmFtZTsKLQotICAgIC8qKgotICAgICAgKiBDb250YWlucyBhbGwgdGVtcGxhdGVzIGRlZmluZWQgaW4gdGhpcyBzdHlsZXNoZWV0Ci0gICAgICAqLwotICAgIHByaXZhdGUgZmluYWwgVmVjdG9yIF90ZW1wbGF0ZXMgPSBuZXcgVmVjdG9yKCk7Ci0KLSAgICAvKioKLSAgICAgKiBVc2VkIHRvIGNhY2hlIHJlc3VsdCBvZiA8Y29kZT5nZXRBbGxWYWxpZFRlbXBsYXRlcygpPC9jb2RlPi4gT25seQotICAgICAqIHNldCBpbiB0b3AtbGV2ZWwgc3R5bGVzaGVldHMgdGhhdCBpbmNsdWRlL2ltcG9ydCBvdGhlciBzdHlsZXNoZWV0cy4KLSAgICAgKi8KLSAgICBwcml2YXRlIFZlY3RvciBfYWxsVmFsaWRUZW1wbGF0ZXMgPSBudWxsOwotCi0gICAgLyoqCi0gICAgICogQ291bnRlciB0byBnZW5lcmF0ZSB1bmlxdWUgbW9kZSBzdWZmaXhlcy4KLSAgICAgKi8KLSAgICBwcml2YXRlIGludCBfbmV4dE1vZGVTZXJpYWwgPSAxOwotCi0gICAgLyoqCi0gICAgICogTWFwcGluZyBiZXR3ZWVuIG1vZGUgbmFtZXMgYW5kIE1vZGUgaW5zdGFuY2VzLgotICAgICAqLwotICAgIHByaXZhdGUgZmluYWwgTWFwPFN0cmluZywgTW9kZT4gX21vZGVzID0gbmV3IEhhc2hNYXA8PigpOwotCi0gICAgLyoqCi0gICAgICogQSByZWZlcmVuY2UgdG8gdGhlIGRlZmF1bHQgTW9kZSBvYmplY3QuCi0gICAgICovCi0gICAgcHJpdmF0ZSBNb2RlIF9kZWZhdWx0TW9kZTsKLQotICAgIC8qKgotICAgICAqIE1hcHBpbmcgYmV0d2VlbiBleHRlbnNpb24gVVJJcyBhbmQgdGhlaXIgcHJlZml4ZXMuCi0gICAgICovCi0gICAgcHJpdmF0ZSBmaW5hbCBNYXA8U3RyaW5nLCBTdHJpbmc+IF9leHRlbnNpb25zID0gbmV3IEhhc2hNYXA8PigpOwotCi0gICAgLyoqCi0gICAgICogUmVmZXJlbmNlIHRvIHRoZSBzdHlsZXNoZWV0IGZyb20gd2hpY2ggdGhpcyBzdHlsZXNoZWV0IHdhcwotICAgICAqIGltcG9ydGVkIChpZiBhbnkpLgotICAgICAqLwotICAgIHB1YmxpYyBTdHlsZXNoZWV0IF9pbXBvcnRlZEZyb20gPSBudWxsOwotCi0gICAgLyoqCi0gICAgICogUmVmZXJlbmNlIHRvIHRoZSBzdHlsZXNoZWV0IGZyb20gd2hpY2ggdGhpcyBzdHlsZXNoZWV0IHdhcwotICAgICAqIGluY2x1ZGVkIChpZiBhbnkpLgotICAgICAqLwotICAgIHB1YmxpYyBTdHlsZXNoZWV0IF9pbmNsdWRlZEZyb20gPSBudWxsOwotCi0gICAgLyoqCi0gICAgICogQXJyYXkgb2YgYWxsIHRoZSBzdHlsZXNoZWV0cyBpbXBvcnRlZCBvciBpbmNsdWRlZCBmcm9tIHRoaXMgb25lLgotICAgICAqLwotICAgIHByaXZhdGUgVmVjdG9yIF9pbmNsdWRlZFN0eWxlc2hlZXRzID0gbnVsbDsKLQotICAgIC8qKgotICAgICAqIEltcG9ydCBwcmVjZW5kZW5jZSBmb3IgdGhpcyBzdHlsZXNoZWV0LgotICAgICAqLwotICAgIHByaXZhdGUgaW50IF9pbXBvcnRQcmVjZWRlbmNlID0gMTsKLQotICAgIC8qKgotICAgICAqIE1pbmltdW0gcHJlY2VuZGVuY2Ugb2YgYW55IGRlc2NlbmRhbnQgc3R5bGVzaGVldCBieSBpbmNsdXNpb24gb3IKLSAgICAgKiBpbXBvcnRhdGlvbi4KLSAgICAgKi8KLSAgICBwcml2YXRlIGludCBfbWluaW11bURlc2NlbmRhbnRQcmVjZWRlbmNlID0gLTE7Ci0KLSAgICAvKioKLSAgICAgKiBNYXBwaW5nIGJldHdlZW4ga2V5IG5hbWVzIGFuZCBLZXkgb2JqZWN0cyAobmVlZGVkIGJ5IEtleS9JZFBhdHRlcm4pLgotICAgICAqLwotICAgIHByaXZhdGUgTWFwPFN0cmluZywgS2V5PiBfa2V5cyA9IG5ldyBIYXNoTWFwPD4oKTsKLQotICAgIC8qKgotICAgICAqIEEgcmVmZXJlbmNlIHRvIHRoZSBTb3VyY2VMb2FkZXIgc2V0IGJ5IHRoZSB1c2VyIChhIFVSSVJlc29sdmVyCi0gICAgICogaWYgdGhlIEpBWFAgQVBJIGlzIGJlaW5nIHVzZWQpLgotICAgICAqLwotICAgIHByaXZhdGUgU291cmNlTG9hZGVyIF9sb2FkZXIgPSBudWxsOwotCi0gICAgLyoqCi0gICAgICogRmxhZyBpbmRpY2F0aW5nIGlmIGZvcm1hdC1udW1iZXIoKSBpcyBjYWxsZWQuCi0gICAgICovCi0gICAgcHJpdmF0ZSBib29sZWFuIF9udW1iZXJGb3JtYXR0aW5nVXNlZCA9IGZhbHNlOwotCi0gICAgLyoqCi0gICAgICogRmxhZyBpbmRpY2F0aW5nIGlmIHRoaXMgaXMgYSBzaW1wbGlmaWVkIHN0eWxlc2hlZXRzLiBBIHRlbXBsYXRlCi0gICAgICogbWF0Y2hpbmcgb24gIi8iIG11c3QgYmUgYWRkZWQgaW4gdGhpcyBjYXNlLgotICAgICAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBfc2ltcGxpZmllZCA9IGZhbHNlOwotCi0gICAgLyoqCi0gICAgICogRmxhZyBpbmRpY2F0aW5nIGlmIG11bHRpLWRvY3VtZW50IHN1cHBvcnQgaXMgbmVlZGVkLgotICAgICAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBfbXVsdGlEb2N1bWVudCA9IGZhbHNlOwotCi0gICAgLyoqCi0gICAgICogRmxhZyBpbmRpY2F0aW5nIGlmIG5vZHNldCgpIGlzIGNhbGxlZC4KLSAgICAgKi8KLSAgICBwcml2YXRlIGJvb2xlYW4gX2NhbGxzTm9kZXNldCA9IGZhbHNlOwotCi0gICAgLyoqCi0gICAgICogRmxhZyBpbmRpY2F0aW5nIGlmIGlkKCkgaXMgY2FsbGVkLgotICAgICAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBfaGFzSWRDYWxsID0gZmFsc2U7Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgdG8gdHJ1ZSB0byBlbmFibGUgdGVtcGxhdGUgaW5saW5pbmcgb3B0aW1pemF0aW9uLgotICAgICAqIEBzZWUgWFNMVEMjX3RlbXBsYXRlSW5saW5pbmcKLSAgICAgKi8KLSAgICBwcml2YXRlIGJvb2xlYW4gX3RlbXBsYXRlSW5saW5pbmcgPSBmYWxzZTsKLQotICAgIC8qKgotICAgICAqIEEgcmVmZXJlbmNlIHRvIHRoZSBsYXN0IHhzbDpvdXRwdXQgb2JqZWN0IGZvdW5kIGluIHRoZSBzdHlsZXNoZXQuCi0gICAgICovCi0gICAgcHJpdmF0ZSBPdXRwdXQgIF9sYXN0T3V0cHV0RWxlbWVudCA9IG51bGw7Ci0KLSAgICAvKioKLSAgICAgKiBPdXRwdXQgcHJvcGVydGllcyBmb3IgdGhpcyBzdHlsZXNoZWV0LgotICAgICAqLwotICAgIHByaXZhdGUgUHJvcGVydGllcyBfb3V0cHV0UHJvcGVydGllcyA9IG51bGw7Ci0KLSAgICAvKioKLSAgICAgKiBPdXRwdXQgbWV0aG9kIGZvciB0aGlzIHN0eWxlc2hlZXQgKG11c3QgYmUgc2V0IHRvIG9uZSBvZgotICAgICAqIHRoZSBjb25zdGFudHMgZGVmaW5lZCBiZWxvdykuCi0gICAgICovCi0gICAgcHJpdmF0ZSBpbnQgX291dHB1dE1ldGhvZCA9IFVOS05PV05fT1VUUFVUOwotCi0gICAgLy8gT3V0cHV0IG1ldGhvZCBjb25zdGFudHMKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBVTktOT1dOX09VVFBVVCA9IDA7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgWE1MX09VVFBVVCAgICAgPSAxOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEhUTUxfT1VUUFVUICAgID0gMjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBURVhUX09VVFBVVCAgICA9IDM7Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIG91dHB1dCBtZXRob2QKLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldE91dHB1dE1ldGhvZCgpIHsKLSAgICAgICAgcmV0dXJuIF9vdXRwdXRNZXRob2Q7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ2hlY2sgYW5kIHNldCB0aGUgb3V0cHV0IG1ldGhvZAotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCBjaGVja091dHB1dE1ldGhvZCgpIHsKLSAgICAgICAgaWYgKF9sYXN0T3V0cHV0RWxlbWVudCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBTdHJpbmcgbWV0aG9kID0gX2xhc3RPdXRwdXRFbGVtZW50LmdldE91dHB1dE1ldGhvZCgpOwotICAgICAgICAgICAgaWYgKG1ldGhvZCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgaWYgKG1ldGhvZC5lcXVhbHMoInhtbCIpKQotICAgICAgICAgICAgICAgICAgICBfb3V0cHV0TWV0aG9kID0gWE1MX09VVFBVVDsKLSAgICAgICAgICAgICAgICBlbHNlIGlmIChtZXRob2QuZXF1YWxzKCJodG1sIikpCi0gICAgICAgICAgICAgICAgICAgIF9vdXRwdXRNZXRob2QgPSBIVE1MX09VVFBVVDsKLSAgICAgICAgICAgICAgICBlbHNlIGlmIChtZXRob2QuZXF1YWxzKCJ0ZXh0IikpCi0gICAgICAgICAgICAgICAgICAgIF9vdXRwdXRNZXRob2QgPSBURVhUX09VVFBVVDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGdldFRlbXBsYXRlSW5saW5pbmcoKSB7Ci0gICAgICAgIHJldHVybiBfdGVtcGxhdGVJbmxpbmluZzsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRUZW1wbGF0ZUlubGluaW5nKGJvb2xlYW4gZmxhZykgewotICAgICAgICBfdGVtcGxhdGVJbmxpbmluZyA9IGZsYWc7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gaXNTaW1wbGlmaWVkKCkgewotICAgICAgICByZXR1cm4oX3NpbXBsaWZpZWQpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldFNpbXBsaWZpZWQoKSB7Ci0gICAgICAgIF9zaW1wbGlmaWVkID0gdHJ1ZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRIYXNJZENhbGwoYm9vbGVhbiBmbGFnKSB7Ci0gICAgICAgIF9oYXNJZENhbGwgPSBmbGFnOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldE91dHB1dFByb3BlcnR5KFN0cmluZyBrZXksIFN0cmluZyB2YWx1ZSkgewotICAgICAgICBpZiAoX291dHB1dFByb3BlcnRpZXMgPT0gbnVsbCkgewotICAgICAgICAgICAgX291dHB1dFByb3BlcnRpZXMgPSBuZXcgUHJvcGVydGllcygpOwotICAgICAgICB9Ci0gICAgICAgIF9vdXRwdXRQcm9wZXJ0aWVzLnNldFByb3BlcnR5KGtleSwgdmFsdWUpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldE91dHB1dFByb3BlcnRpZXMoUHJvcGVydGllcyBwcm9wcykgewotICAgICAgICBfb3V0cHV0UHJvcGVydGllcyA9IHByb3BzOwotICAgIH0KLQotICAgIHB1YmxpYyBQcm9wZXJ0aWVzIGdldE91dHB1dFByb3BlcnRpZXMoKSB7Ci0gICAgICAgIHJldHVybiBfb3V0cHV0UHJvcGVydGllczsKLSAgICB9Ci0KLSAgICBwdWJsaWMgT3V0cHV0IGdldExhc3RPdXRwdXRFbGVtZW50KCkgewotICAgICAgICByZXR1cm4gX2xhc3RPdXRwdXRFbGVtZW50OwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldE11bHRpRG9jdW1lbnQoYm9vbGVhbiBmbGFnKSB7Ci0gICAgICAgIF9tdWx0aURvY3VtZW50ID0gZmxhZzsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBpc011bHRpRG9jdW1lbnQoKSB7Ci0gICAgICAgIHJldHVybiBfbXVsdGlEb2N1bWVudDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRDYWxsc05vZGVzZXQoYm9vbGVhbiBmbGFnKSB7Ci0gICAgICAgIGlmIChmbGFnKSBzZXRNdWx0aURvY3VtZW50KGZsYWcpOwotICAgICAgICBfY2FsbHNOb2Rlc2V0ID0gZmxhZzsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBjYWxsc05vZGVzZXQoKSB7Ci0gICAgICAgIHJldHVybiBfY2FsbHNOb2Rlc2V0OwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIG51bWJlckZvcm1hdHRpbmdVc2VkKCkgewotICAgICAgICBfbnVtYmVyRm9ybWF0dGluZ1VzZWQgPSB0cnVlOwotICAgICAgICAvKgotICAgICAgICAgKiBGaXggZm9yIGJ1ZyAyMzA0NiwgaWYgdGhlIHN0eWxlc2hlZXQgaXMgaW5jbHVkZWQsIHNldCB0aGUKLSAgICAgICAgICogbnVtYmVyRm9ybWF0dGluZ1VzZWQgZmxhZyB0byB0aGUgcGFyZW50IHN0eWxlc2hlZXQgdG9vLgotICAgICAgICAgKiBBYnN0cmFjdFRyYW5zbGV0LmFkZERlY2ltYWxGb3JtYXQoKSB3aWxsIGJlIGlubGluZWQgb25jZSBmb3IgdGhlCi0gICAgICAgICAqIG91dGVyIG1vc3Qgc3R5bGVzaGVldC4KLSAgICAgICAgICovCi0gICAgICAgIFN0eWxlc2hlZXQgcGFyZW50ID0gZ2V0UGFyZW50U3R5bGVzaGVldCgpOwotICAgICAgICBpZiAobnVsbCAhPSBwYXJlbnQpIHBhcmVudC5udW1iZXJGb3JtYXR0aW5nVXNlZCgpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldEltcG9ydFByZWNlZGVuY2UoZmluYWwgaW50IHByZWNlZGVuY2UpIHsKLSAgICAgICAgLy8gU2V0IGltcG9ydCBwcmVjZWRlbmNlIGZvciB0aGlzIHN0eWxlc2hlZXQKLSAgICAgICAgX2ltcG9ydFByZWNlZGVuY2UgPSBwcmVjZWRlbmNlOwotCi0gICAgICAgIC8vIFNldCBpbXBvcnQgcHJlY2VkZW5jZSBmb3IgYWxsIGluY2x1ZGVkIHN0eWxlc2hlZXRzCi0gICAgICAgIGZpbmFsIEl0ZXJhdG9yPFN5bnRheFRyZWVOb2RlPiBlbGVtZW50cyA9IGVsZW1lbnRzKCk7Ci0gICAgICAgIHdoaWxlIChlbGVtZW50cy5oYXNOZXh0KCkpIHsKLSAgICAgICAgICAgIFN5bnRheFRyZWVOb2RlIGNoaWxkID0gZWxlbWVudHMubmV4dCgpOwotICAgICAgICAgICAgaWYgKGNoaWxkIGluc3RhbmNlb2YgSW5jbHVkZSkgewotICAgICAgICAgICAgICAgIFN0eWxlc2hlZXQgaW5jbHVkZWQgPSAoKEluY2x1ZGUpY2hpbGQpLmdldEluY2x1ZGVkU3R5bGVzaGVldCgpOwotICAgICAgICAgICAgICAgIGlmIChpbmNsdWRlZCAhPSBudWxsICYmIGluY2x1ZGVkLl9pbmNsdWRlZEZyb20gPT0gdGhpcykgewotICAgICAgICAgICAgICAgICAgICBpbmNsdWRlZC5zZXRJbXBvcnRQcmVjZWRlbmNlKHByZWNlZGVuY2UpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIFNldCBpbXBvcnQgcHJlY2VkZW5jZSBmb3IgdGhlIHN0eWxlc2hlZXQgdGhhdCBpbXBvcnRlZCB0aGlzIG9uZQotICAgICAgICBpZiAoX2ltcG9ydGVkRnJvbSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAoX2ltcG9ydGVkRnJvbS5nZXRJbXBvcnRQcmVjZWRlbmNlKCkgPCBwcmVjZWRlbmNlKSB7Ci0gICAgICAgICAgICAgICAgZmluYWwgUGFyc2VyIHBhcnNlciA9IGdldFBhcnNlcigpOwotICAgICAgICAgICAgICAgIGZpbmFsIGludCBuZXh0UHJlY2VkZW5jZSA9IHBhcnNlci5nZXROZXh0SW1wb3J0UHJlY2VkZW5jZSgpOwotICAgICAgICAgICAgICAgIF9pbXBvcnRlZEZyb20uc2V0SW1wb3J0UHJlY2VkZW5jZShuZXh0UHJlY2VkZW5jZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgLy8gU2V0IGltcG9ydCBwcmVjZWRlbmNlIGZvciB0aGUgc3R5bGVzaGVldCB0aGF0IGluY2x1ZGVkIHRoaXMgb25lCi0gICAgICAgIGVsc2UgaWYgKF9pbmNsdWRlZEZyb20gIT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKF9pbmNsdWRlZEZyb20uZ2V0SW1wb3J0UHJlY2VkZW5jZSgpICE9IHByZWNlZGVuY2UpCi0gICAgICAgICAgICAgICAgX2luY2x1ZGVkRnJvbS5zZXRJbXBvcnRQcmVjZWRlbmNlKHByZWNlZGVuY2UpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIGludCBnZXRJbXBvcnRQcmVjZWRlbmNlKCkgewotICAgICAgICByZXR1cm4gX2ltcG9ydFByZWNlZGVuY2U7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBtaW5pbXVtIG9mIHRoZSBwcmVjZWRlbmNlIG9mIHRoaXMgc3R5bGVzaGVldCwgYW55IHN0eWxlc2hlZXQKLSAgICAgKiBpbXBvcnRlZCBieSB0aGlzIHN0eWxlc2hlZXQgYW5kIGFueSBpbmNsdWRlL2ltcG9ydCBkZXNjZW5kYW50IG9mIHRoaXMKLSAgICAgKiBzdHlsZXNoZWV0LgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0TWluaW11bURlc2NlbmRhbnRQcmVjZWRlbmNlKCkgewotICAgICAgICBpZiAoX21pbmltdW1EZXNjZW5kYW50UHJlY2VkZW5jZSA9PSAtMSkgewotICAgICAgICAgICAgLy8gU3RhcnQgd2l0aCBwcmVjZWRlbmNlIG9mIGN1cnJlbnQgc3R5bGVzaGVldCBhcyBhIGJhc2lzLgotICAgICAgICAgICAgaW50IG1pbiA9IGdldEltcG9ydFByZWNlZGVuY2UoKTsKLQotICAgICAgICAgICAgLy8gUmVjdXJzaXZlbHkgZXhhbWluZSBhbGwgaW1wb3J0ZWQvaW5jbHVkZWQgc3R5bGVzaGVldHMuCi0gICAgICAgICAgICBmaW5hbCBpbnQgaW5jbEltcENvdW50ID0gKF9pbmNsdWRlZFN0eWxlc2hlZXRzICE9IG51bGwpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IF9pbmNsdWRlZFN0eWxlc2hlZXRzLnNpemUoKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAwOwotCi0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGluY2xJbXBDb3VudDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgaW50IHByZWMgPSAoKFN0eWxlc2hlZXQpX2luY2x1ZGVkU3R5bGVzaGVldHMuZWxlbWVudEF0KGkpKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRNaW5pbXVtRGVzY2VuZGFudFByZWNlZGVuY2UoKTsKLQotICAgICAgICAgICAgICAgIGlmIChwcmVjIDwgbWluKSB7Ci0gICAgICAgICAgICAgICAgICAgIG1pbiA9IHByZWM7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBfbWluaW11bURlc2NlbmRhbnRQcmVjZWRlbmNlID0gbWluOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBfbWluaW11bURlc2NlbmRhbnRQcmVjZWRlbmNlOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGNoZWNrRm9yTG9vcChTdHJpbmcgc3lzdGVtSWQpIHsKLSAgICAgICAgLy8gUmV0dXJuIHRydWUgaWYgdGhpcyBzdHlsZXNoZWV0IGluY2x1ZGVzL2ltcG9ydHMgaXRzZWxmCi0gICAgICAgIGlmIChfc3lzdGVtSWQgIT0gbnVsbCAmJiBfc3lzdGVtSWQuZXF1YWxzKHN5c3RlbUlkKSkgewotICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgIH0KLSAgICAgICAgLy8gVGhlbiBjaGVjayB3aXRoIGFueSBzdHlsZXNoZWV0cyB0aGF0IGluY2x1ZGVkL2ltcG9ydGVkIHRoaXMgb25lCi0gICAgICAgIGlmIChfcGFyZW50U3R5bGVzaGVldCAhPSBudWxsKQotICAgICAgICAgICAgcmV0dXJuIF9wYXJlbnRTdHlsZXNoZWV0LmNoZWNrRm9yTG9vcChzeXN0ZW1JZCk7Ci0gICAgICAgIC8vIE90aGVyd2lzZSBPSwotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0UGFyc2VyKFBhcnNlciBwYXJzZXIpIHsKLSAgICAgICAgc3VwZXIuc2V0UGFyc2VyKHBhcnNlcik7Ci0gICAgICAgIF9uYW1lID0gbWFrZVN0eWxlc2hlZXROYW1lKCJfX3N0eWxlc2hlZXRfIik7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0UGFyZW50U3R5bGVzaGVldChTdHlsZXNoZWV0IHBhcmVudCkgewotICAgICAgICBfcGFyZW50U3R5bGVzaGVldCA9IHBhcmVudDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3R5bGVzaGVldCBnZXRQYXJlbnRTdHlsZXNoZWV0KCkgewotICAgICAgICByZXR1cm4gX3BhcmVudFN0eWxlc2hlZXQ7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0SW1wb3J0aW5nU3R5bGVzaGVldChTdHlsZXNoZWV0IHBhcmVudCkgewotICAgICAgICBfaW1wb3J0ZWRGcm9tID0gcGFyZW50OwotICAgICAgICBwYXJlbnQuYWRkSW5jbHVkZWRTdHlsZXNoZWV0KHRoaXMpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldEluY2x1ZGluZ1N0eWxlc2hlZXQoU3R5bGVzaGVldCBwYXJlbnQpIHsKLSAgICAgICAgX2luY2x1ZGVkRnJvbSA9IHBhcmVudDsKLSAgICAgICAgcGFyZW50LmFkZEluY2x1ZGVkU3R5bGVzaGVldCh0aGlzKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBhZGRJbmNsdWRlZFN0eWxlc2hlZXQoU3R5bGVzaGVldCBjaGlsZCkgewotICAgICAgICBpZiAoX2luY2x1ZGVkU3R5bGVzaGVldHMgPT0gbnVsbCkgewotICAgICAgICAgICAgX2luY2x1ZGVkU3R5bGVzaGVldHMgPSBuZXcgVmVjdG9yKCk7Ci0gICAgICAgIH0KLSAgICAgICAgX2luY2x1ZGVkU3R5bGVzaGVldHMuYWRkRWxlbWVudChjaGlsZCk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0U3lzdGVtSWQoU3RyaW5nIHN5c3RlbUlkKSB7Ci0gICAgICAgIGlmIChzeXN0ZW1JZCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBfc3lzdGVtSWQgPSBTeXN0ZW1JRFJlc29sdmVyLmdldEFic29sdXRlVVJJKHN5c3RlbUlkKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3lzdGVtSWQoKSB7Ci0gICAgICAgIHJldHVybiBfc3lzdGVtSWQ7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0U291cmNlTG9hZGVyKFNvdXJjZUxvYWRlciBsb2FkZXIpIHsKLSAgICAgICAgX2xvYWRlciA9IGxvYWRlcjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU291cmNlTG9hZGVyIGdldFNvdXJjZUxvYWRlcigpIHsKLSAgICAgICAgcmV0dXJuIF9sb2FkZXI7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBRTmFtZSBtYWtlU3R5bGVzaGVldE5hbWUoU3RyaW5nIHByZWZpeCkgewotICAgICAgICByZXR1cm4gZ2V0UGFyc2VyKCkuZ2V0UU5hbWUocHJlZml4K2dldFhTTFRDKCkubmV4dFN0eWxlc2hlZXRTZXJpYWwoKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIGlmIHRoaXMgc3R5bGVzaGVldCBoYXMgZ2xvYmFsIHZhcnMgb3IgcGFyYW1zLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGhhc0dsb2JhbHMoKSB7Ci0gICAgICAgIHJldHVybiBfZ2xvYmFscy5zaXplKCkgPiAwOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdHJ1ZSBpZiBhdCBsZWFzdCBvbmUgdGVtcGxhdGUgaW4gdGhlIHN0eWxlc2hlZXQgaGFzIHBhcmFtcwotICAgICAqIGRlZmluZWQuIFVzZXMgdGhlIHZhcmlhYmxlIDxjb2RlPl9oYXNMb2NhbFBhcmFtczwvY29kZT4gdG8gY2FjaGUgdGhlCi0gICAgICogcmVzdWx0LgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGhhc0xvY2FsUGFyYW1zKCkgewotICAgICAgICBpZiAoX2hhc0xvY2FsUGFyYW1zID09IG51bGwpIHsKLSAgICAgICAgICAgIFZlY3RvciB0ZW1wbGF0ZXMgPSBnZXRBbGxWYWxpZFRlbXBsYXRlcygpOwotICAgICAgICAgICAgZmluYWwgaW50IG4gPSB0ZW1wbGF0ZXMuc2l6ZSgpOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspIHsKLSAgICAgICAgICAgICAgICBmaW5hbCBUZW1wbGF0ZSB0ZW1wbGF0ZSA9IChUZW1wbGF0ZSl0ZW1wbGF0ZXMuZWxlbWVudEF0KGkpOwotICAgICAgICAgICAgICAgIGlmICh0ZW1wbGF0ZS5oYXNQYXJhbXMoKSkgewotICAgICAgICAgICAgICAgICAgICBfaGFzTG9jYWxQYXJhbXMgPSBCb29sZWFuLlRSVUU7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIF9oYXNMb2NhbFBhcmFtcyA9IEJvb2xlYW4uRkFMU0U7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gX2hhc0xvY2FsUGFyYW1zLmJvb2xlYW5WYWx1ZSgpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQWRkcyBhIHNpbmdsZSBwcmVmaXggbWFwcGluZyB0byB0aGlzIHN5bnRheCB0cmVlIG5vZGUuCi0gICAgICogQHBhcmFtIHByZWZpeCBOYW1lc3BhY2UgcHJlZml4LgotICAgICAqIEBwYXJhbSB1cmkgTmFtZXNwYWNlIFVSSS4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCBhZGRQcmVmaXhNYXBwaW5nKFN0cmluZyBwcmVmaXgsIFN0cmluZyB1cmkpIHsKLSAgICAgICAgaWYgKHByZWZpeC5lcXVhbHMoRU1QVFlTVFJJTkcpICYmIHVyaS5lcXVhbHMoWEhUTUxfVVJJKSkgcmV0dXJuOwotICAgICAgICBzdXBlci5hZGRQcmVmaXhNYXBwaW5nKHByZWZpeCwgdXJpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTdG9yZSBleHRlbnNpb24gVVJJcwotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCBleHRlbnNpb25VUkkoU3RyaW5nIHByZWZpeGVzLCBTeW1ib2xUYWJsZSBzdGFibGUpIHsKLSAgICAgICAgaWYgKHByZWZpeGVzICE9IG51bGwpIHsKLSAgICAgICAgICAgIFN0cmluZ1Rva2VuaXplciB0b2tlbnMgPSBuZXcgU3RyaW5nVG9rZW5pemVyKHByZWZpeGVzKTsKLSAgICAgICAgICAgIHdoaWxlICh0b2tlbnMuaGFzTW9yZVRva2VucygpKSB7Ci0gICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIHByZWZpeCA9IHRva2Vucy5uZXh0VG9rZW4oKTsKLSAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgdXJpID0gbG9va3VwTmFtZXNwYWNlKHByZWZpeCk7Ci0gICAgICAgICAgICAgICAgaWYgKHVyaSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIF9leHRlbnNpb25zLnB1dCh1cmksIHByZWZpeCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gaXNFeHRlbnNpb24oU3RyaW5nIHVyaSkgewotICAgICAgICByZXR1cm4gKF9leHRlbnNpb25zLmdldCh1cmkpICE9IG51bGwpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGRlY2xhcmVFeHRlbnNpb25QcmVmaXhlcyhQYXJzZXIgcGFyc2VyKSB7Ci0gICAgICAgIGZpbmFsIFN5bWJvbFRhYmxlIHN0YWJsZSA9IHBhcnNlci5nZXRTeW1ib2xUYWJsZSgpOwotICAgICAgICBmaW5hbCBTdHJpbmcgZXh0ZW5zaW9uUHJlZml4ZXMgPSBnZXRBdHRyaWJ1dGUoImV4dGVuc2lvbi1lbGVtZW50LXByZWZpeGVzIik7Ci0gICAgICAgIGV4dGVuc2lvblVSSShleHRlbnNpb25QcmVmaXhlcywgc3RhYmxlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBQYXJzZSB0aGUgdmVyc2lvbiBhbmQgdXJpIGZpZWxkcyBvZiB0aGUgc3R5bGVzaGVldCBhbmQgYWRkIGFuCi0gICAgICogZW50cnkgdG8gdGhlIHN5bWJvbCB0YWJsZSBtYXBwaW5nIHRoZSBuYW1lIDx0dD5fX3N0eWxlc2hlZXRfPC90dD4KLSAgICAgKiB0byBhbiBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHBhcnNlQ29udGVudHMoUGFyc2VyIHBhcnNlcikgewotICAgICAgICBmaW5hbCBTeW1ib2xUYWJsZSBzdGFibGUgPSBwYXJzZXIuZ2V0U3ltYm9sVGFibGUoKTsKLQotICAgICAgICAvKgotICAgICAgICAvLyBNYWtlIHN1cmUgdGhlIFhTTCB2ZXJzaW9uIHNldCBpbiB0aGlzIHN0eWxlc2hlZXQKLSAgICAgICAgaWYgKChfdmVyc2lvbiA9PSBudWxsKSB8fCAoX3ZlcnNpb24uZXF1YWxzKEVNUFRZU1RSSU5HKSkpIHsKLSAgICAgICAgICAgIHJlcG9ydEVycm9yKHRoaXMsIHBhcnNlciwgRXJyb3JNc2cuUkVRVUlSRURfQVRUUl9FUlIsInZlcnNpb24iKTsKLSAgICAgICAgfQotICAgICAgICAvLyBWZXJpZnkgdGhhdCB0aGUgdmVyc2lvbiBpcyAxLjAgYW5kIG5vdGhpbmcgZWxzZQotICAgICAgICBlbHNlIGlmICghX3ZlcnNpb24uZXF1YWxzKCIxLjAiKSkgewotICAgICAgICAgICAgcmVwb3J0RXJyb3IodGhpcywgcGFyc2VyLCBFcnJvck1zZy5YU0xfVkVSU0lPTl9FUlIsIF92ZXJzaW9uKTsKLSAgICAgICAgfQotICAgICAgICAqLwotCi0gICAgICAgIC8vIEFkZCB0aGUgaW1wbGljaXQgbWFwcGluZyBvZiAneG1sJyB0byB0aGUgWE1MIG5hbWVzcGFjZSBVUkkKLSAgICAgICAgYWRkUHJlZml4TWFwcGluZygieG1sIiwgImh0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZSIpOwotCi0gICAgICAgIC8vIFJlcG9ydCBhbmQgZXJyb3IgaWYgbW9yZSB0aGFuIG9uZSBzdHlsZXNoZWV0IGRlZmluZWQKLSAgICAgICAgZmluYWwgU3R5bGVzaGVldCBzaGVldCA9IHN0YWJsZS5hZGRTdHlsZXNoZWV0KF9uYW1lLCB0aGlzKTsKLSAgICAgICAgaWYgKHNoZWV0ICE9IG51bGwpIHsKLSAgICAgICAgICAgIC8vIEVycm9yOiBtb3JlIHRoYXQgb25lIHN0eWxlc2hlZXQgZGVmaW5lZAotICAgICAgICAgICAgRXJyb3JNc2cgZXJyID0gbmV3IEVycm9yTXNnKEVycm9yTXNnLk1VTFRJUExFX1NUWUxFU0hFRVRfRVJSLHRoaXMpOwotICAgICAgICAgICAgcGFyc2VyLnJlcG9ydEVycm9yKENvbnN0YW50cy5FUlJPUiwgZXJyKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIElmIHRoaXMgaXMgYSBzaW1wbGlmaWVkIHN0eWxlc2hlZXQgd2UgbXVzdCBjcmVhdGUgYSB0ZW1wbGF0ZSB0aGF0Ci0gICAgICAgIC8vIGdyYWJzIHRoZSByb290IG5vZGUgb2YgdGhlIGlucHV0IGRvYyAoIDx4c2w6dGVtcGxhdGUgbWF0Y2g9Ii8iLz4gKS4KLSAgICAgICAgLy8gVGhpcyB0ZW1wbGF0ZSBuZWVkcyB0aGUgY3VycmVudCBlbGVtZW50ICh0aGUgb25lIHBhc3NlZCB0byB0aGlzCi0gICAgICAgIC8vIG1ldGhvZCkgYXMgaXRzIG9ubHkgY2hpbGQsIHNvIHRoZSBUZW1wbGF0ZSBjbGFzcyBoYXMgYSBzcGVjaWFsCi0gICAgICAgIC8vIG1ldGhvZCB0aGF0IGhhbmRsZXMgdGhpcyAocGFyc2VTaW1wbGlmaWVkKCkpLgotICAgICAgICBpZiAoX3NpbXBsaWZpZWQpIHsKLSAgICAgICAgICAgIHN0YWJsZS5leGNsdWRlVVJJKFhTTFRfVVJJKTsKLSAgICAgICAgICAgIFRlbXBsYXRlIHRlbXBsYXRlID0gbmV3IFRlbXBsYXRlKCk7Ci0gICAgICAgICAgICB0ZW1wbGF0ZS5wYXJzZVNpbXBsaWZpZWQodGhpcywgcGFyc2VyKTsKLSAgICAgICAgfQotICAgICAgICAvLyBQYXJzZSB0aGUgY2hpbGRyZW4gb2YgdGhpcyBub2RlCi0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgcGFyc2VPd25DaGlsZHJlbihwYXJzZXIpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUGFyc2UgYWxsIGRpcmVjdCBjaGlsZHJlbiBvZiB0aGUgPHhzbDpzdHlsZXNoZWV0Lz4gZWxlbWVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgZmluYWwgdm9pZCBwYXJzZU93bkNoaWxkcmVuKFBhcnNlciBwYXJzZXIpIHsKLSAgICAgICAgZmluYWwgU3ltYm9sVGFibGUgc3RhYmxlID0gcGFyc2VyLmdldFN5bWJvbFRhYmxlKCk7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBleGNsdWRlUHJlZml4ZXMgPSBnZXRBdHRyaWJ1dGUoImV4Y2x1ZGUtcmVzdWx0LXByZWZpeGVzIik7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBleHRlbnNpb25QcmVmaXhlcyA9IGdldEF0dHJpYnV0ZSgiZXh0ZW5zaW9uLWVsZW1lbnQtcHJlZml4ZXMiKTsKLQotICAgICAgICAvLyBFeGNsdWRlIFhTTFQgdXJpCi0gICAgICAgIHN0YWJsZS5wdXNoRXhjbHVkZWROYW1lc3BhY2VzQ29udGV4dCgpOwotICAgICAgICBzdGFibGUuZXhjbHVkZVVSSShDb25zdGFudHMuWFNMVF9VUkkpOwotICAgICAgICBzdGFibGUuZXhjbHVkZU5hbWVzcGFjZXMoZXhjbHVkZVByZWZpeGVzKTsKLSAgICAgICAgc3RhYmxlLmV4Y2x1ZGVOYW1lc3BhY2VzKGV4dGVuc2lvblByZWZpeGVzKTsKLQotICAgICAgICBmaW5hbCBMaXN0PFN5bnRheFRyZWVOb2RlPiBjb250ZW50cyA9IGdldENvbnRlbnRzKCk7Ci0gICAgICAgIGZpbmFsIGludCBjb3VudCA9IGNvbnRlbnRzLnNpemUoKTsKLQotICAgICAgICAvLyBXZSBoYXZlIHRvIHNjYW4gdGhlIHN0eWxlc2hlZXQgZWxlbWVudCdzIHRvcC1sZXZlbCBlbGVtZW50cyBmb3IKLSAgICAgICAgLy8gdmFyaWFibGVzIGFuZC9vciBwYXJhbWV0ZXJzIGJlZm9yZSB3ZSBwYXJzZSB0aGUgb3RoZXIgZWxlbWVudHMKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7Ci0gICAgICAgICAgICBTeW50YXhUcmVlTm9kZSBjaGlsZCA9IGNvbnRlbnRzLmdldChpKTsKLSAgICAgICAgICAgIGlmICgoY2hpbGQgaW5zdGFuY2VvZiBWYXJpYWJsZUJhc2UpIHx8Ci0gICAgICAgICAgICAgICAgKGNoaWxkIGluc3RhbmNlb2YgTmFtZXNwYWNlQWxpYXMpKSB7Ci0gICAgICAgICAgICAgICAgcGFyc2VyLmdldFN5bWJvbFRhYmxlKCkuc2V0Q3VycmVudE5vZGUoY2hpbGQpOwotICAgICAgICAgICAgICAgIGNoaWxkLnBhcnNlQ29udGVudHMocGFyc2VyKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIE5vdyBnbyB0aHJvdWdoIGFsbCB0aGUgb3RoZXIgdG9wLWxldmVsIGVsZW1lbnRzLi4uCi0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykgewotICAgICAgICAgICAgU3ludGF4VHJlZU5vZGUgY2hpbGQgPSBjb250ZW50cy5nZXQoaSk7Ci0gICAgICAgICAgICBpZiAoIShjaGlsZCBpbnN0YW5jZW9mIFZhcmlhYmxlQmFzZSkgJiYKLSAgICAgICAgICAgICAgICAhKGNoaWxkIGluc3RhbmNlb2YgTmFtZXNwYWNlQWxpYXMpKSB7Ci0gICAgICAgICAgICAgICAgcGFyc2VyLmdldFN5bWJvbFRhYmxlKCkuc2V0Q3VycmVudE5vZGUoY2hpbGQpOwotICAgICAgICAgICAgICAgIGNoaWxkLnBhcnNlQ29udGVudHMocGFyc2VyKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gQWxsIHRlbXBsYXRlIGNvZGUgc2hvdWxkIGJlIGNvbXBpbGVkIGFzIG1ldGhvZHMgaWYgdGhlCi0gICAgICAgICAgICAvLyA8eHNsOmFwcGx5LWltcG9ydHMvPiBlbGVtZW50IHdhcyBldmVyIHVzZWQgaW4gdGhpcyBzdHlsZXNoZWV0Ci0gICAgICAgICAgICBpZiAoIV90ZW1wbGF0ZUlubGluaW5nICYmIChjaGlsZCBpbnN0YW5jZW9mIFRlbXBsYXRlKSkgewotICAgICAgICAgICAgICAgIFRlbXBsYXRlIHRlbXBsYXRlID0gKFRlbXBsYXRlKWNoaWxkOwotICAgICAgICAgICAgICAgIFN0cmluZyBuYW1lID0gInRlbXBsYXRlJGRvdCQiICsgdGVtcGxhdGUuZ2V0UG9zaXRpb24oKTsKLSAgICAgICAgICAgICAgICB0ZW1wbGF0ZS5zZXROYW1lKHBhcnNlci5nZXRRTmFtZShuYW1lKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBzdGFibGUucG9wRXhjbHVkZWROYW1lc3BhY2VzQ29udGV4dCgpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHByb2Nlc3NNb2RlcygpIHsKLSAgICAgICAgaWYgKF9kZWZhdWx0TW9kZSA9PSBudWxsKQotICAgICAgICAgICAgX2RlZmF1bHRNb2RlID0gbmV3IE1vZGUobnVsbCwgdGhpcywgQ29uc3RhbnRzLkVNUFRZU1RSSU5HKTsKLSAgICAgICAgX2RlZmF1bHRNb2RlLnByb2Nlc3NQYXR0ZXJucyhfa2V5cyk7Ci0gICAgICAgIGZvciAoTW9kZSBtb2RlIDogX21vZGVzLnZhbHVlcygpKSB7Ci0gICAgICAgICAgICBtb2RlLnByb2Nlc3NQYXR0ZXJucyhfa2V5cyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgY29tcGlsZU1vZGVzKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuKSB7Ci0gICAgICAgIF9kZWZhdWx0TW9kZS5jb21waWxlQXBwbHlUZW1wbGF0ZXMoY2xhc3NHZW4pOwotICAgICAgICBmb3IgKE1vZGUgbW9kZSA6IF9tb2Rlcy52YWx1ZXMoKSkgewotICAgICAgICAgICAgbW9kZS5jb21waWxlQXBwbHlUZW1wbGF0ZXMoY2xhc3NHZW4pOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIE1vZGUgZ2V0TW9kZShRTmFtZSBtb2RlTmFtZSkgewotICAgICAgICBpZiAobW9kZU5hbWUgPT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKF9kZWZhdWx0TW9kZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgX2RlZmF1bHRNb2RlID0gbmV3IE1vZGUobnVsbCwgdGhpcywgQ29uc3RhbnRzLkVNUFRZU1RSSU5HKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiBfZGVmYXVsdE1vZGU7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBNb2RlIG1vZGUgPSBfbW9kZXMuZ2V0KG1vZGVOYW1lLmdldFN0cmluZ1JlcCgpKTsKLSAgICAgICAgICAgIGlmIChtb2RlID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgc3VmZml4ID0gSW50ZWdlci50b1N0cmluZyhfbmV4dE1vZGVTZXJpYWwrKyk7Ci0gICAgICAgICAgICAgICAgX21vZGVzLnB1dChtb2RlTmFtZS5nZXRTdHJpbmdSZXAoKSwgbW9kZSA9IG5ldyBNb2RlKG1vZGVOYW1lLCB0aGlzLCBzdWZmaXgpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiBtb2RlOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHlwZSBjaGVjayBhbGwgdGhlIGNoaWxkcmVuIG9mIHRoaXMgbm9kZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgVHlwZSB0eXBlQ2hlY2soU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgewotICAgICAgICBmaW5hbCBpbnQgY291bnQgPSBfZ2xvYmFscy5zaXplKCk7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykgewotICAgICAgICAgICAgZmluYWwgVmFyaWFibGVCYXNlIHZhciA9IChWYXJpYWJsZUJhc2UpX2dsb2JhbHMuZWxlbWVudEF0KGkpOwotICAgICAgICAgICAgdmFyLnR5cGVDaGVjayhzdGFibGUpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiB0eXBlQ2hlY2tDb250ZW50cyhzdGFibGUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZSB0aGUgc3R5bGVzaGVldCBpbnRvIEpWTSBieXRlY29kZXMuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0gICAgICAgIHRyYW5zbGF0ZSgpOwotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBhZGRET01GaWVsZChDbGFzc0dlbmVyYXRvciBjbGFzc0dlbikgewotICAgICAgICBmaW5hbCBGaWVsZEdlbiBmZ2VuID0gbmV3IEZpZWxkR2VuKEFDQ19QVUJMSUMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVXRpbC5nZXRKQ1JlZlR5cGUoRE9NX0lOVEZfU0lHKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBET01fRklFTEQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCkpOwotICAgICAgICBjbGFzc0dlbi5hZGRGaWVsZChmZ2VuLmdldEZpZWxkKCkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEFkZCBhIHN0YXRpYyBmaWVsZAotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCBhZGRTdGF0aWNGaWVsZChDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgU3RyaW5nIHR5cGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBuYW1lKQotICAgIHsKLSAgICAgICAgZmluYWwgRmllbGRHZW4gZmdlbiA9IG5ldyBGaWVsZEdlbihBQ0NfUFJPVEVDVEVEfEFDQ19TVEFUSUMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVXRpbC5nZXRKQ1JlZlR5cGUodHlwZSksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKSk7Ci0gICAgICAgIGNsYXNzR2VuLmFkZEZpZWxkKGZnZW4uZ2V0RmllbGQoKSk7Ci0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGUgdGhlIHN0eWxlc2hlZXQgaW50byBKVk0gYnl0ZWNvZGVzLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZSgpIHsKLSAgICAgICAgX2NsYXNzTmFtZSA9IGdldFhTTFRDKCkuZ2V0Q2xhc3NOYW1lKCk7Ci0KLSAgICAgICAgLy8gRGVmaW5lIGEgbmV3IGNsYXNzIGJ5IGV4dGVuZGluZyBUUkFOU0xFVF9DTEFTUwotICAgICAgICBmaW5hbCBDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiA9Ci0gICAgICAgICAgICBuZXcgQ2xhc3NHZW5lcmF0b3IoX2NsYXNzTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUUkFOU0xFVF9DTEFTUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb25zdGFudHMuRU1QVFlTVFJJTkcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQUNDX1BVQkxJQyB8IEFDQ19TVVBFUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLCB0aGlzKTsKLQotICAgICAgICBhZGRET01GaWVsZChjbGFzc0dlbik7Ci0KLSAgICAgICAgLy8gQ29tcGlsZSB0cmFuc2Zvcm0oKSB0byBpbml0aWFsaXplIHBhcmFtZXRlcnMsIGdsb2JhbHMgJiBvdXRwdXQKLSAgICAgICAgLy8gYW5kIHJ1biB0aGUgdHJhbnNmb3JtYXRpb24KLSAgICAgICAgY29tcGlsZVRyYW5zZm9ybShjbGFzc0dlbik7Ci0KLSAgICAgICAgLy8gVHJhbnNsYXRlIGFsbCBub24tdGVtcGxhdGUgZWxlbWVudHMgYW5kIGZpbHRlciBvdXQgYWxsIHRlbXBsYXRlcwotICAgICAgICBmaW5hbCBJdGVyYXRvcjxTeW50YXhUcmVlTm9kZT4gZWxlbWVudHMgPSBlbGVtZW50cygpOwotICAgICAgICB3aGlsZSAoZWxlbWVudHMuaGFzTmV4dCgpKSB7Ci0gICAgICAgICAgICBTeW50YXhUcmVlTm9kZSBlbGVtZW50ID0gZWxlbWVudHMubmV4dCgpOwotICAgICAgICAgICAgLy8geHNsOnRlbXBsYXRlCi0gICAgICAgICAgICBpZiAoZWxlbWVudCBpbnN0YW5jZW9mIFRlbXBsYXRlKSB7Ci0gICAgICAgICAgICAgICAgLy8gU2VwYXJhdGUgdGVtcGxhdGVzIGJ5IG1vZGVzCi0gICAgICAgICAgICAgICAgZmluYWwgVGVtcGxhdGUgdGVtcGxhdGUgPSAoVGVtcGxhdGUpZWxlbWVudDsKLSAgICAgICAgICAgICAgICAvL190ZW1wbGF0ZXMuYWRkRWxlbWVudCh0ZW1wbGF0ZSk7Ci0gICAgICAgICAgICAgICAgZ2V0TW9kZSh0ZW1wbGF0ZS5nZXRNb2RlTmFtZSgpKS5hZGRUZW1wbGF0ZSh0ZW1wbGF0ZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyB4c2w6YXR0cmlidXRlLXNldAotICAgICAgICAgICAgZWxzZSBpZiAoZWxlbWVudCBpbnN0YW5jZW9mIEF0dHJpYnV0ZVNldCkgewotICAgICAgICAgICAgICAgICgoQXR0cmlidXRlU2V0KWVsZW1lbnQpLnRyYW5zbGF0ZShjbGFzc0dlbiwgbnVsbCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChlbGVtZW50IGluc3RhbmNlb2YgT3V0cHV0KSB7Ci0gICAgICAgICAgICAgICAgLy8gc2F2ZSB0aGUgZWxlbWVudCBmb3IgbGF0ZXIgdG8gcGFzcyB0byBjb21waWxlQ29uc3RydWN0b3IKLSAgICAgICAgICAgICAgICBPdXRwdXQgb3V0cHV0ID0gKE91dHB1dCllbGVtZW50OwotICAgICAgICAgICAgICAgIGlmIChvdXRwdXQuZW5hYmxlZCgpKSBfbGFzdE91dHB1dEVsZW1lbnQgPSBvdXRwdXQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAvLyBHbG9iYWwgdmFyaWFibGVzIGFuZCBwYXJhbWV0ZXJzIGFyZSBoYW5kbGVkIGVsc2V3aGVyZS4KLSAgICAgICAgICAgICAgICAvLyBPdGhlciB0b3AtbGV2ZWwgbm9uLXRlbXBsYXRlIGVsZW1lbnRzIGFyZSBpZ25vcmVkLiBMaXRlcmFsCi0gICAgICAgICAgICAgICAgLy8gZWxlbWVudHMgb3V0c2lkZSBvZiB0ZW1wbGF0ZXMgd2lsbCBuZXZlciBiZSBvdXRwdXQuCi0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBjaGVja091dHB1dE1ldGhvZCgpOwotICAgICAgICBwcm9jZXNzTW9kZXMoKTsKLSAgICAgICAgY29tcGlsZU1vZGVzKGNsYXNzR2VuKTsKLSAgICAgICAgY29tcGlsZVN0YXRpY0luaXRpYWxpemVyKGNsYXNzR2VuKTsKLSAgICAgICAgY29tcGlsZUNvbnN0cnVjdG9yKGNsYXNzR2VuLCBfbGFzdE91dHB1dEVsZW1lbnQpOwotCi0gICAgICAgIGlmICghZ2V0UGFyc2VyKCkuZXJyb3JzRm91bmQoKSkgewotICAgICAgICAgICAgZ2V0WFNMVEMoKS5kdW1wQ2xhc3MoY2xhc3NHZW4uZ2V0SmF2YUNsYXNzKCkpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29tcGlsZSB0aGUgbmFtZXNBcnJheSwgdXJpc0FycmF5IGFuZCB0eXBlc0FycmF5IGludG8KLSAgICAgKiB0aGUgc3RhdGljIGluaXRpYWxpemVyLiBUaGV5IGFyZSByZWFkLW9ubHkgZnJvbSB0aGUKLSAgICAgKiB0cmFuc2xldC4gQWxsIHRyYW5zbGV0IGluc3RhbmNlcyBjYW4gc2hhcmUgYSBzaW5nbGUKLSAgICAgKiBjb3B5IG9mIHRoaXMgaW5mb3JtdGlvbi4KLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgY29tcGlsZVN0YXRpY0luaXRpYWxpemVyKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuKSB7Ci0gICAgICAgIGZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbmV3IEluc3RydWN0aW9uTGlzdCgpOwotCi0gICAgICAgIGZpbmFsIE1ldGhvZEdlbmVyYXRvciBzdGF0aWNDb25zdCA9Ci0gICAgICAgICAgICBuZXcgTWV0aG9kR2VuZXJhdG9yKEFDQ19QVUJMSUN8QUNDX1NUQVRJQywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5UeXBlLlZPSUQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsIG51bGwsICI8Y2xpbml0PiIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9jbGFzc05hbWUsIGlsLCBjcGcpOwotCi0gICAgICAgIGFkZFN0YXRpY0ZpZWxkKGNsYXNzR2VuLCAiWyIgKyBTVFJJTkdfU0lHLCBTVEFUSUNfTkFNRVNfQVJSQVlfRklFTEQpOwotICAgICAgICBhZGRTdGF0aWNGaWVsZChjbGFzc0dlbiwgIlsiICsgU1RSSU5HX1NJRywgU1RBVElDX1VSSVNfQVJSQVlfRklFTEQpOwotICAgICAgICBhZGRTdGF0aWNGaWVsZChjbGFzc0dlbiwgIltJIiwgU1RBVElDX1RZUEVTX0FSUkFZX0ZJRUxEKTsKLSAgICAgICAgYWRkU3RhdGljRmllbGQoY2xhc3NHZW4sICJbIiArIFNUUklOR19TSUcsIFNUQVRJQ19OQU1FU1BBQ0VfQVJSQVlfRklFTEQpOwotICAgICAgICAvLyBDcmVhdGUgZmllbGRzIG9mIHR5cGUgY2hhcltdIHRoYXQgd2lsbCBjb250YWluIGxpdGVyYWwgdGV4dCBmcm9tCi0gICAgICAgIC8vIHRoZSBzdHlsZXNoZWV0LgotICAgICAgICBmaW5hbCBpbnQgY2hhckRhdGFGaWVsZENvdW50ID0gZ2V0WFNMVEMoKS5nZXRDaGFyYWN0ZXJEYXRhQ291bnQoKTsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjaGFyRGF0YUZpZWxkQ291bnQ7IGkrKykgewotICAgICAgICAgICAgYWRkU3RhdGljRmllbGQoY2xhc3NHZW4sIFNUQVRJQ19DSEFSX0RBVEFfRklFTERfU0lHLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgU1RBVElDX0NIQVJfREFUQV9GSUVMRCtpKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIFB1dCB0aGUgbmFtZXMgYXJyYXkgaW50byB0aGUgdHJhbnNsZXQgLSB1c2VkIGZvciBkb20vdHJhbnNsZXQgbWFwcGluZwotICAgICAgICBmaW5hbCBWZWN0b3IgbmFtZXNJbmRleCA9IGdldFhTTFRDKCkuZ2V0TmFtZXNJbmRleCgpOwotICAgICAgICBpbnQgc2l6ZSA9IG5hbWVzSW5kZXguc2l6ZSgpOwotICAgICAgICBTdHJpbmdbXSBuYW1lc0FycmF5ID0gbmV3IFN0cmluZ1tzaXplXTsKLSAgICAgICAgU3RyaW5nW10gdXJpc0FycmF5ID0gbmV3IFN0cmluZ1tzaXplXTsKLSAgICAgICAgaW50W10gdHlwZXNBcnJheSA9IG5ldyBpbnRbc2l6ZV07Ci0KLSAgICAgICAgaW50IGluZGV4OwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewotICAgICAgICAgICAgU3RyaW5nIGVuY29kZWROYW1lID0gKFN0cmluZyluYW1lc0luZGV4LmVsZW1lbnRBdChpKTsKLSAgICAgICAgICAgIGlmICgoaW5kZXggPSBlbmNvZGVkTmFtZS5sYXN0SW5kZXhPZignOicpKSA+IC0xKSB7Ci0gICAgICAgICAgICAgICAgdXJpc0FycmF5W2ldID0gZW5jb2RlZE5hbWUuc3Vic3RyaW5nKDAsIGluZGV4KTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaW5kZXggPSBpbmRleCArIDE7Ci0gICAgICAgICAgICBpZiAoZW5jb2RlZE5hbWUuY2hhckF0KGluZGV4KSA9PSAnQCcpIHsKLSAgICAgICAgICAgICAgICB0eXBlc0FycmF5W2ldID0gRFRNLkFUVFJJQlVURV9OT0RFOwotICAgICAgICAgICAgICAgIGluZGV4Kys7Ci0gICAgICAgICAgICB9IGVsc2UgaWYgKGVuY29kZWROYW1lLmNoYXJBdChpbmRleCkgPT0gJz8nKSB7Ci0gICAgICAgICAgICAgICAgdHlwZXNBcnJheVtpXSA9IERUTS5OQU1FU1BBQ0VfTk9ERTsKLSAgICAgICAgICAgICAgICBpbmRleCsrOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICB0eXBlc0FycmF5W2ldID0gRFRNLkVMRU1FTlRfTk9ERTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKGluZGV4ID09IDApIHsKLSAgICAgICAgICAgICAgICBuYW1lc0FycmF5W2ldID0gZW5jb2RlZE5hbWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBuYW1lc0FycmF5W2ldID0gZW5jb2RlZE5hbWUuc3Vic3RyaW5nKGluZGV4KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHN0YXRpY0NvbnN0Lm1hcmtDaHVua1N0YXJ0KCk7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsIHNpemUpKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBBTkVXQVJSQVkoY3BnLmFkZENsYXNzKFNUUklORykpKTsKLSAgICAgICAgaW50IG5hbWVzQXJyYXlSZWYgPSBjcGcuYWRkRmllbGRyZWYoX2NsYXNzTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU1RBVElDX05BTUVTX0FSUkFZX0ZJRUxELAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOQU1FU19JTkRFWF9TSUcpOwotICAgICAgICBpbC5hcHBlbmQobmV3IFBVVFNUQVRJQyhuYW1lc0FycmF5UmVmKSk7Ci0gICAgICAgIHN0YXRpY0NvbnN0Lm1hcmtDaHVua0VuZCgpOwotCi0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7Ci0gICAgICAgICAgICBmaW5hbCBTdHJpbmcgbmFtZSA9IG5hbWVzQXJyYXlbaV07Ci0gICAgICAgICAgICBzdGF0aWNDb25zdC5tYXJrQ2h1bmtTdGFydCgpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBHRVRTVEFUSUMobmFtZXNBcnJheVJlZikpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgaSkpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgbmFtZSkpOwotICAgICAgICAgICAgaWwuYXBwZW5kKEFBU1RPUkUpOwotICAgICAgICAgICAgc3RhdGljQ29uc3QubWFya0NodW5rRW5kKCk7Ci0gICAgICAgIH0KLQotICAgICAgICBzdGF0aWNDb25zdC5tYXJrQ2h1bmtTdGFydCgpOwotICAgICAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBzaXplKSk7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgQU5FV0FSUkFZKGNwZy5hZGRDbGFzcyhTVFJJTkcpKSk7Ci0gICAgICAgIGludCB1cmlzQXJyYXlSZWYgPSBjcGcuYWRkRmllbGRyZWYoX2NsYXNzTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTVEFUSUNfVVJJU19BUlJBWV9GSUVMRCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVUklTX0lOREVYX1NJRyk7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgUFVUU1RBVElDKHVyaXNBcnJheVJlZikpOwotICAgICAgICBzdGF0aWNDb25zdC5tYXJrQ2h1bmtFbmQoKTsKLQotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewotICAgICAgICAgICAgZmluYWwgU3RyaW5nIHVyaSA9IHVyaXNBcnJheVtpXTsKLSAgICAgICAgICAgIHN0YXRpY0NvbnN0Lm1hcmtDaHVua1N0YXJ0KCk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IEdFVFNUQVRJQyh1cmlzQXJyYXlSZWYpKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsIGkpKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsIHVyaSkpOwotICAgICAgICAgICAgaWwuYXBwZW5kKEFBU1RPUkUpOwotICAgICAgICAgICAgc3RhdGljQ29uc3QubWFya0NodW5rRW5kKCk7Ci0gICAgICAgIH0KLQotICAgICAgICBzdGF0aWNDb25zdC5tYXJrQ2h1bmtTdGFydCgpOwotICAgICAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBzaXplKSk7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgTkVXQVJSQVkoQmFzaWNUeXBlLklOVCkpOwotICAgICAgICBpbnQgdHlwZXNBcnJheVJlZiA9IGNwZy5hZGRGaWVsZHJlZihfY2xhc3NOYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTVEFUSUNfVFlQRVNfQVJSQVlfRklFTEQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRZUEVTX0lOREVYX1NJRyk7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgUFVUU1RBVElDKHR5cGVzQXJyYXlSZWYpKTsKLSAgICAgICAgc3RhdGljQ29uc3QubWFya0NodW5rRW5kKCk7Ci0KLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKLSAgICAgICAgICAgIGZpbmFsIGludCBub2RlVHlwZSA9IHR5cGVzQXJyYXlbaV07Ci0gICAgICAgICAgICBzdGF0aWNDb25zdC5tYXJrQ2h1bmtTdGFydCgpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBHRVRTVEFUSUModHlwZXNBcnJheVJlZikpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgaSkpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgbm9kZVR5cGUpKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChJQVNUT1JFKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIFB1dCB0aGUgbmFtZXNwYWNlIG5hbWVzIGFycmF5IGludG8gdGhlIHRyYW5zbGV0Ci0gICAgICAgIGZpbmFsIFZlY3RvciBuYW1lc3BhY2VzID0gZ2V0WFNMVEMoKS5nZXROYW1lc3BhY2VJbmRleCgpOwotICAgICAgICBzdGF0aWNDb25zdC5tYXJrQ2h1bmtTdGFydCgpOwotICAgICAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBuYW1lc3BhY2VzLnNpemUoKSkpOwotICAgICAgICBpbC5hcHBlbmQobmV3IEFORVdBUlJBWShjcGcuYWRkQ2xhc3MoU1RSSU5HKSkpOwotICAgICAgICBpbnQgbmFtZXNwYWNlQXJyYXlSZWYgPSBjcGcuYWRkRmllbGRyZWYoX2NsYXNzTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNUQVRJQ19OQU1FU1BBQ0VfQVJSQVlfRklFTEQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOQU1FU1BBQ0VfSU5ERVhfU0lHKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBQVVRTVEFUSUMobmFtZXNwYWNlQXJyYXlSZWYpKTsKLSAgICAgICAgc3RhdGljQ29uc3QubWFya0NodW5rRW5kKCk7Ci0KLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuYW1lc3BhY2VzLnNpemUoKTsgaSsrKSB7Ci0gICAgICAgICAgICBmaW5hbCBTdHJpbmcgbnMgPSAoU3RyaW5nKW5hbWVzcGFjZXMuZWxlbWVudEF0KGkpOwotICAgICAgICAgICAgc3RhdGljQ29uc3QubWFya0NodW5rU3RhcnQoKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgR0VUU1RBVElDKG5hbWVzcGFjZUFycmF5UmVmKSk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBpKSk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBucykpOwotICAgICAgICAgICAgaWwuYXBwZW5kKEFBU1RPUkUpOwotICAgICAgICAgICAgc3RhdGljQ29uc3QubWFya0NodW5rRW5kKCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBHcmFiIGFsbCB0aGUgbGl0ZXJhbCB0ZXh0IGluIHRoZSBzdHlsZXNoZWV0IGFuZCBwdXQgaXQgaW4gYSBjaGFyW10KLSAgICAgICAgZmluYWwgaW50IGNoYXJEYXRhQ291bnQgPSBnZXRYU0xUQygpLmdldENoYXJhY3RlckRhdGFDb3VudCgpOwotICAgICAgICBmaW5hbCBpbnQgdG9DaGFyQXJyYXkgPSBjcGcuYWRkTWV0aG9kcmVmKFNUUklORywgInRvQ2hhckFycmF5IiwgIigpW0MiKTsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjaGFyRGF0YUNvdW50OyBpKyspIHsKLSAgICAgICAgICAgIHN0YXRpY0NvbnN0Lm1hcmtDaHVua1N0YXJ0KCk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBnZXRYU0xUQygpLmdldENoYXJhY3RlckRhdGEoaSkpKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTCh0b0NoYXJBcnJheSkpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBQVVRTVEFUSUMoY3BnLmFkZEZpZWxkcmVmKF9jbGFzc05hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNUQVRJQ19DSEFSX0RBVEFfRklFTEQraSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU1RBVElDX0NIQVJfREFUQV9GSUVMRF9TSUcpKSk7Ci0gICAgICAgICAgICBzdGF0aWNDb25zdC5tYXJrQ2h1bmtFbmQoKTsKLSAgICAgICAgfQotCi0gICAgICAgIGlsLmFwcGVuZChSRVRVUk4pOwotCi0gICAgICAgIGNsYXNzR2VuLmFkZE1ldGhvZChzdGF0aWNDb25zdCk7Ci0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb21waWxlIHRoZSB0cmFuc2xldCdzIGNvbnN0cnVjdG9yCi0gICAgICovCi0gICAgcHJpdmF0ZSB2b2lkIGNvbXBpbGVDb25zdHJ1Y3RvcihDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgT3V0cHV0IG91dHB1dCkgewotCi0gICAgICAgIGZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbmV3IEluc3RydWN0aW9uTGlzdCgpOwotCi0gICAgICAgIGZpbmFsIE1ldGhvZEdlbmVyYXRvciBjb25zdHJ1Y3RvciA9Ci0gICAgICAgICAgICBuZXcgTWV0aG9kR2VuZXJhdG9yKEFDQ19QVUJMSUMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuVHlwZS5WT0lELAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLCBudWxsLCAiPGluaXQ+IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2NsYXNzTmFtZSwgaWwsIGNwZyk7Ci0KLSAgICAgICAgLy8gQ2FsbCB0aGUgY29uc3RydWN0b3IgaW4gdGhlIEFic3RyYWN0VHJhbnNsZXQgc3VwZXJjbGFzcwotICAgICAgICBpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpOwotICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRVNQRUNJQUwoY3BnLmFkZE1ldGhvZHJlZihUUkFOU0xFVF9DTEFTUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjxpbml0PiIsICIoKVYiKSkpOwotCi0gICAgICAgIGNvbnN0cnVjdG9yLm1hcmtDaHVua1N0YXJ0KCk7Ci0gICAgICAgIGlsLmFwcGVuZChjbGFzc0dlbi5sb2FkVHJhbnNsZXQoKSk7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgR0VUU1RBVElDKGNwZy5hZGRGaWVsZHJlZihfY2xhc3NOYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU1RBVElDX05BTUVTX0FSUkFZX0ZJRUxELAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkFNRVNfSU5ERVhfU0lHKSkpOwotICAgICAgICBpbC5hcHBlbmQobmV3IFBVVEZJRUxEKGNwZy5hZGRGaWVsZHJlZihUUkFOU0xFVF9DTEFTUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkFNRVNfSU5ERVgsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5BTUVTX0lOREVYX1NJRykpKTsKLQotICAgICAgICBpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpOwotICAgICAgICBpbC5hcHBlbmQobmV3IEdFVFNUQVRJQyhjcGcuYWRkRmllbGRyZWYoX2NsYXNzTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNUQVRJQ19VUklTX0FSUkFZX0ZJRUxELAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVVJJU19JTkRFWF9TSUcpKSk7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgUFVURklFTEQoY3BnLmFkZEZpZWxkcmVmKFRSQU5TTEVUX0NMQVNTLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVUklTX0lOREVYLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVUklTX0lOREVYX1NJRykpKTsKLSAgICAgICAgY29uc3RydWN0b3IubWFya0NodW5rRW5kKCk7Ci0KLSAgICAgICAgY29uc3RydWN0b3IubWFya0NodW5rU3RhcnQoKTsKLSAgICAgICAgaWwuYXBwZW5kKGNsYXNzR2VuLmxvYWRUcmFuc2xldCgpKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBHRVRTVEFUSUMoY3BnLmFkZEZpZWxkcmVmKF9jbGFzc05hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTVEFUSUNfVFlQRVNfQVJSQVlfRklFTEQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUWVBFU19JTkRFWF9TSUcpKSk7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgUFVURklFTEQoY3BnLmFkZEZpZWxkcmVmKFRSQU5TTEVUX0NMQVNTLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUWVBFU19JTkRFWCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVFlQRVNfSU5ERVhfU0lHKSkpOwotICAgICAgICBjb25zdHJ1Y3Rvci5tYXJrQ2h1bmtFbmQoKTsKLQotICAgICAgICBjb25zdHJ1Y3Rvci5tYXJrQ2h1bmtTdGFydCgpOwotICAgICAgICBpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpOwotICAgICAgICBpbC5hcHBlbmQobmV3IEdFVFNUQVRJQyhjcGcuYWRkRmllbGRyZWYoX2NsYXNzTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNUQVRJQ19OQU1FU1BBQ0VfQVJSQVlfRklFTEQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOQU1FU1BBQ0VfSU5ERVhfU0lHKSkpOwotICAgICAgICBpbC5hcHBlbmQobmV3IFBVVEZJRUxEKGNwZy5hZGRGaWVsZHJlZihUUkFOU0xFVF9DTEFTUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkFNRVNQQUNFX0lOREVYLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOQU1FU1BBQ0VfSU5ERVhfU0lHKSkpOwotICAgICAgICBjb25zdHJ1Y3Rvci5tYXJrQ2h1bmtFbmQoKTsKLQotICAgICAgICBjb25zdHJ1Y3Rvci5tYXJrQ2h1bmtTdGFydCgpOwotICAgICAgICBpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpOwotICAgICAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBBYnN0cmFjdFRyYW5zbGV0LkNVUlJFTlRfVFJBTlNMRVRfVkVSU0lPTikpOwotICAgICAgICBpbC5hcHBlbmQobmV3IFBVVEZJRUxEKGNwZy5hZGRGaWVsZHJlZihUUkFOU0xFVF9DTEFTUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJBTlNMRVRfVkVSU0lPTl9JTkRFWCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJBTlNMRVRfVkVSU0lPTl9JTkRFWF9TSUcpKSk7Ci0gICAgICAgIGNvbnN0cnVjdG9yLm1hcmtDaHVua0VuZCgpOwotCi0gICAgICAgIGlmIChfaGFzSWRDYWxsKSB7Ci0gICAgICAgICAgICBjb25zdHJ1Y3Rvci5tYXJrQ2h1bmtTdGFydCgpOwotICAgICAgICAgICAgaWwuYXBwZW5kKGNsYXNzR2VuLmxvYWRUcmFuc2xldCgpKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsIEJvb2xlYW4uVFJVRSkpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBQVVRGSUVMRChjcGcuYWRkRmllbGRyZWYoVFJBTlNMRVRfQ0xBU1MsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIQVNJRENBTExfSU5ERVgsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIQVNJRENBTExfSU5ERVhfU0lHKSkpOwotICAgICAgICAgICAgY29uc3RydWN0b3IubWFya0NodW5rRW5kKCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBDb21waWxlIGluIGNvZGUgdG8gc2V0IHRoZSBvdXRwdXQgY29uZmlndXJhdGlvbiBmcm9tIDx4c2w6b3V0cHV0PgotICAgICAgICBpZiAob3V0cHV0ICE9IG51bGwpIHsKLSAgICAgICAgICAgIC8vIFNldCBhbGwgdGhlIG91dHB1dCBzZXR0aW5ncyBmaWxlcyBpbiB0aGUgdHJhbnNsZXQKLSAgICAgICAgICAgIGNvbnN0cnVjdG9yLm1hcmtDaHVua1N0YXJ0KCk7Ci0gICAgICAgICAgICBvdXRwdXQudHJhbnNsYXRlKGNsYXNzR2VuLCBjb25zdHJ1Y3Rvcik7Ci0gICAgICAgICAgICBjb25zdHJ1Y3Rvci5tYXJrQ2h1bmtFbmQoKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIENvbXBpbGUgZGVmYXVsdCBkZWNpbWFsIGZvcm1hdHRpbmcgc3ltYm9scy4KLSAgICAgICAgLy8gVGhpcyBpcyBhbiBpbXBsaWNpdCwgbmFtZWxlc3MgeHNsOmRlY2ltYWwtZm9ybWF0IHRvcC1sZXZlbCBlbGVtZW50LgotICAgICAgICBpZiAoX251bWJlckZvcm1hdHRpbmdVc2VkKSB7Ci0gICAgICAgICAgICBjb25zdHJ1Y3Rvci5tYXJrQ2h1bmtTdGFydCgpOwotICAgICAgICAgICAgRGVjaW1hbEZvcm1hdHRpbmcudHJhbnNsYXRlRGVmYXVsdERGUyhjbGFzc0dlbiwgY29uc3RydWN0b3IpOwotICAgICAgICAgICAgY29uc3RydWN0b3IubWFya0NodW5rRW5kKCk7Ci0gICAgICAgIH0KLQotICAgICAgICBpbC5hcHBlbmQoUkVUVVJOKTsKLQotICAgICAgICBjbGFzc0dlbi5hZGRNZXRob2QoY29uc3RydWN0b3IpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbXBpbGUgYSB0b3BMZXZlbCgpIG1ldGhvZCBpbnRvIHRoZSBvdXRwdXQgY2xhc3MuIFRoaXMgbWV0aG9kIGlzCi0gICAgICogY2FsbGVkIGZyb20gdHJhbnNmb3JtKCkgdG8gaGFuZGxlIGFsbCBub24tdGVtcGxhdGUgdG9wLWxldmVsIGVsZW1lbnRzLgotICAgICAqIFJldHVybnMgdGhlIHNpZ25hdHVyZSBvZiB0aGUgdG9wTGV2ZWwoKSBtZXRob2QuCi0gICAgICoKLSAgICAgKiBHbG9iYWwgdmFyaWFibGVzL3BhcmFtcyBhbmQga2V5cyBhcmUgZmlyc3Qgc29ydGVkIHRvIHJlc29sdmUKLSAgICAgKiBkZXBlbmRlbmNpZXMgYmV0d2VlbiB0aGVtLiBUaGUgWFNMVCAxLjAgc3BlYyBkb2VzIG5vdCBhbGxvdyBhIGtleQotICAgICAqIHRvIGRlcGVuZCBvbiBhIHZhcmlhYmxlLiBIb3dldmVyLCBmb3IgY29tcGF0aWJpbGl0eSB3aXRoIFhhbGFuCi0gICAgICogaW50ZXJwcmV0aXZlLCB0aGF0IHR5cGUgb2YgZGVwZW5kZW5jeSBpcyBhbGxvd2VkLiBOb3RlIGFsc28gdGhhdAotICAgICAqIHRoZSBidWlsZEtleXMoKSBtZXRob2QgaXMgc3RpbGwgZ2VuZXJhdGVkIGFzIGl0IGlzIHVzZWQgYnkgdGhlCi0gICAgICogTG9hZERvY3VtZW50IGNsYXNzLCBidXQgaXQgbm8gbG9uZ2VyIGNhbGxlZCBmcm9tIHRyYW5zZm9ybSgpLgotICAgICAqLwotICAgIHByaXZhdGUgU3RyaW5nIGNvbXBpbGVUb3BMZXZlbChDbGFzc0dlbmVyYXRvciBjbGFzc0dlbikgewotCi0gICAgICAgIGZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQotICAgICAgICBmaW5hbCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlR5cGVbXSBhcmdUeXBlcyA9IHsKLSAgICAgICAgICAgIFV0aWwuZ2V0SkNSZWZUeXBlKERPTV9JTlRGX1NJRyksCi0gICAgICAgICAgICBVdGlsLmdldEpDUmVmVHlwZShOT0RFX0lURVJBVE9SX1NJRyksCi0gICAgICAgICAgICBVdGlsLmdldEpDUmVmVHlwZShUUkFOU0xFVF9PVVRQVVRfU0lHKQotICAgICAgICB9OwotCi0gICAgICAgIGZpbmFsIFN0cmluZ1tdIGFyZ05hbWVzID0gewotICAgICAgICAgICAgRE9DVU1FTlRfUE5BTUUsIElURVJBVE9SX1BOQU1FLCBUUkFOU0xFVF9PVVRQVVRfUE5BTUUKLSAgICAgICAgfTsKLQotICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBuZXcgSW5zdHJ1Y3Rpb25MaXN0KCk7Ci0KLSAgICAgICAgZmluYWwgTWV0aG9kR2VuZXJhdG9yIHRvcGxldmVsID0KLSAgICAgICAgICAgIG5ldyBNZXRob2RHZW5lcmF0b3IoQUNDX1BVQkxJQywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5UeXBlLlZPSUQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyZ1R5cGVzLCBhcmdOYW1lcywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRvcExldmVsIiwgX2NsYXNzTmFtZSwgaWwsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpKTsKLQotICAgICAgICB0b3BsZXZlbC5hZGRFeGNlcHRpb24oImNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5UcmFuc2xldEV4Y2VwdGlvbiIpOwotCi0gICAgICAgIC8vIERlZmluZSBhbmQgaW5pdGlhbGl6ZSAnY3VycmVudCcgdmFyaWFibGUgd2l0aCB0aGUgcm9vdCBub2RlCi0gICAgICAgIGZpbmFsIExvY2FsVmFyaWFibGVHZW4gY3VycmVudCA9Ci0gICAgICAgICAgICB0b3BsZXZlbC5hZGRMb2NhbFZhcmlhYmxlKCJjdXJyZW50IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5UeXBlLklOVCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwgbnVsbCk7Ci0KLSAgICAgICAgZmluYWwgaW50IHNldEZpbHRlciA9IGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoRE9NX0lOVEYsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInNldEZpbHRlciIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1N0cmlwRmlsdGVyOylWIik7Ci0KLSAgICAgICAgZmluYWwgaW50IGdpdHIgPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKERPTV9JTlRGLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZ2V0SXRlcmF0b3IiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKCkiK05PREVfSVRFUkFUT1JfU0lHKTsKLSAgICAgICAgaWwuYXBwZW5kKHRvcGxldmVsLmxvYWRET00oKSk7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFSU5URVJGQUNFKGdpdHIsIDEpKTsKLSAgICAgICAgaWwuYXBwZW5kKHRvcGxldmVsLm5leHROb2RlKCkpOwotICAgICAgICBjdXJyZW50LnNldFN0YXJ0KGlsLmFwcGVuZChuZXcgSVNUT1JFKGN1cnJlbnQuZ2V0SW5kZXgoKSkpKTsKLQotICAgICAgICAvLyBDcmVhdGUgYSBuZXcgbGlzdCBjb250YWluaW5nIHZhcmlhYmxlcy9wYXJhbXMgKyBrZXlzCi0gICAgICAgIFZlY3RvciB2YXJEZXBFbGVtZW50cyA9IG5ldyBWZWN0b3IoX2dsb2JhbHMpOwotICAgICAgICBJdGVyYXRvcjxTeW50YXhUcmVlTm9kZT4gZWxlbWVudHMgPSBlbGVtZW50cygpOwotICAgICAgICB3aGlsZSAoZWxlbWVudHMuaGFzTmV4dCgpKSB7Ci0gICAgICAgICAgICBTeW50YXhUcmVlTm9kZSBlbGVtZW50ID0gZWxlbWVudHMubmV4dCgpOwotICAgICAgICAgICAgaWYgKGVsZW1lbnQgaW5zdGFuY2VvZiBLZXkpIHsKLSAgICAgICAgICAgICAgICB2YXJEZXBFbGVtZW50cy5hZGQoZWxlbWVudCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBEZXRlcm1pbmUgYSBwYXJ0aWFsIG9yZGVyIGZvciB0aGUgdmFyaWFibGVzL3BhcmFtcyBhbmQga2V5cwotICAgICAgICB2YXJEZXBFbGVtZW50cyA9IHJlc29sdmVEZXBlbmRlbmNpZXModmFyRGVwRWxlbWVudHMpOwotCi0gICAgICAgIC8vIFRyYW5zbGF0ZSB2YXJzL3BhcmFtcyBhbmQga2V5cyBpbiB0aGUgcmlnaHQgb3JkZXIKLSAgICAgICAgZmluYWwgaW50IGNvdW50ID0gdmFyRGVwRWxlbWVudHMuc2l6ZSgpOwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKLSAgICAgICAgICAgIGZpbmFsIFRvcExldmVsRWxlbWVudCB0bGUgPSAoVG9wTGV2ZWxFbGVtZW50KSB2YXJEZXBFbGVtZW50cy5lbGVtZW50QXQoaSk7Ci0gICAgICAgICAgICB0bGUudHJhbnNsYXRlKGNsYXNzR2VuLCB0b3BsZXZlbCk7Ci0gICAgICAgICAgICBpZiAodGxlIGluc3RhbmNlb2YgS2V5KSB7Ci0gICAgICAgICAgICAgICAgZmluYWwgS2V5IGtleSA9IChLZXkpIHRsZTsKLSAgICAgICAgICAgICAgICBfa2V5cy5wdXQoa2V5LmdldE5hbWUoKSwga2V5KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIENvbXBpbGUgY29kZSBmb3Igb3RoZXIgdG9wLWxldmVsIGVsZW1lbnRzCi0gICAgICAgIFZlY3RvciB3aGl0ZXNwYWNlUnVsZXMgPSBuZXcgVmVjdG9yKCk7Ci0gICAgICAgIGVsZW1lbnRzID0gZWxlbWVudHMoKTsKLSAgICAgICAgd2hpbGUgKGVsZW1lbnRzLmhhc05leHQoKSkgewotICAgICAgICAgICAgU3ludGF4VHJlZU5vZGUgZWxlbWVudCA9IGVsZW1lbnRzLm5leHQoKTsKLSAgICAgICAgICAgIC8vIHhzbDpkZWNpbWFsLWZvcm1hdAotICAgICAgICAgICAgaWYgKGVsZW1lbnQgaW5zdGFuY2VvZiBEZWNpbWFsRm9ybWF0dGluZykgewotICAgICAgICAgICAgICAgICgoRGVjaW1hbEZvcm1hdHRpbmcpZWxlbWVudCkudHJhbnNsYXRlKGNsYXNzR2VuLHRvcGxldmVsKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIHhzbDpzdHJpcC9wcmVzZXJ2ZS1zcGFjZQotICAgICAgICAgICAgZWxzZSBpZiAoZWxlbWVudCBpbnN0YW5jZW9mIFdoaXRlc3BhY2UpIHsKLSAgICAgICAgICAgICAgICB3aGl0ZXNwYWNlUnVsZXMuYWRkQWxsKCgoV2hpdGVzcGFjZSllbGVtZW50KS5nZXRSdWxlcygpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIFRyYW5zbGF0ZSBhbGwgd2hpdGVzcGFjZSBzdHJpcC9wcmVzZXJ2ZSBydWxlcwotICAgICAgICBpZiAod2hpdGVzcGFjZVJ1bGVzLnNpemUoKSA+IDApIHsKLSAgICAgICAgICAgIFdoaXRlc3BhY2UudHJhbnNsYXRlUnVsZXMod2hpdGVzcGFjZVJ1bGVzLGNsYXNzR2VuKTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChjbGFzc0dlbi5jb250YWluc01ldGhvZChTVFJJUF9TUEFDRSwgU1RSSVBfU1BBQ0VfUEFSQU1TKSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpbC5hcHBlbmQodG9wbGV2ZWwubG9hZERPTSgpKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChjbGFzc0dlbi5sb2FkVHJhbnNsZXQoKSk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRUlOVEVSRkFDRShzZXRGaWx0ZXIsIDIpKTsKLSAgICAgICAgfQotCi0gICAgICAgIGlsLmFwcGVuZChSRVRVUk4pOwotCi0gICAgICAgIC8vIENvbXB1dGUgbWF4IGxvY2FscyArIHN0YWNrIGFuZCBhZGQgbWV0aG9kIHRvIGNsYXNzCi0gICAgICAgIGNsYXNzR2VuLmFkZE1ldGhvZCh0b3BsZXZlbCk7Ci0KLSAgICAgICAgcmV0dXJuKCIoIitET01fSU5URl9TSUcrTk9ERV9JVEVSQVRPUl9TSUcrVFJBTlNMRVRfT1VUUFVUX1NJRysiKVYiKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCByZXR1cm5zIGEgdmVjdG9yIHdpdGggdmFyaWFibGVzL3BhcmFtcyBhbmQga2V5cyBpbiB0aGUKLSAgICAgKiBvcmRlciBpbiB3aGljaCB0aGV5IGFyZSB0byBiZSBjb21waWxlZCBmb3IgaW5pdGlhbGl6YXRpb24uIFRoZSBvcmRlcgotICAgICAqIGlzIGRldGVybWluZWQgYnkgYW5hbHl6aW5nIHRoZSBkZXBlbmRlbmNpZXMgYmV0d2VlbiB0aGVtLiBUaGUgWFNMVCAxLjAKLSAgICAgKiBzcGVjIGRvZXMgbm90IGFsbG93IGEga2V5IHRvIGRlcGVuZCBvbiBhIHZhcmlhYmxlLiBIb3dldmVyLCBmb3IKLSAgICAgKiBjb21wYXRpYmlsaXR5IHdpdGggWGFsYW4gaW50ZXJwcmV0aXZlLCB0aGF0IHR5cGUgb2YgZGVwZW5kZW5jeSBpcwotICAgICAqIGFsbG93ZWQgYW5kLCB0aGVyZWZvcmUsIGNvbnNpZGVyIHRvIGRldGVybWluZSB0aGUgcGFydGlhbCBvcmRlci4KLSAgICAgKi8KLSAgICBwcml2YXRlIFZlY3RvciByZXNvbHZlRGVwZW5kZW5jaWVzKFZlY3RvciBpbnB1dCkgewotICAgICAgICAvKiBERUJVRyBDT0RFIC0gSU5HT1JFCi0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaW5wdXQuc2l6ZSgpOyBpKyspIHsKLSAgICAgICAgICAgIGZpbmFsIFRvcExldmVsRWxlbWVudCBlID0gKFRvcExldmVsRWxlbWVudCkgaW5wdXQuZWxlbWVudEF0KGkpOwotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJlID0gIiArIGUgKyAiIGRlcGVuZHMgb246Iik7Ci0gICAgICAgICAgICBWZWN0b3IgZGVwID0gZS5nZXREZXBlbmRlbmNpZXMoKTsKLSAgICAgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgKGRlcCAhPSBudWxsID8gZGVwLnNpemUoKSA6IDApOyBqKyspIHsKLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlx0IiArIGRlcC5lbGVtZW50QXQoaikpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Iik7Ci0gICAgICAgICovCi0KLSAgICAgICAgVmVjdG9yIHJlc3VsdCA9IG5ldyBWZWN0b3IoKTsKLSAgICAgICAgd2hpbGUgKGlucHV0LnNpemUoKSA+IDApIHsKLSAgICAgICAgICAgIGJvb2xlYW4gY2hhbmdlZCA9IGZhbHNlOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBpbnB1dC5zaXplKCk7ICkgewotICAgICAgICAgICAgICAgIGZpbmFsIFRvcExldmVsRWxlbWVudCB2ZGUgPSAoVG9wTGV2ZWxFbGVtZW50KSBpbnB1dC5lbGVtZW50QXQoaSk7Ci0gICAgICAgICAgICAgICAgZmluYWwgVmVjdG9yIGRlcCA9IHZkZS5nZXREZXBlbmRlbmNpZXMoKTsKLSAgICAgICAgICAgICAgICBpZiAoZGVwID09IG51bGwgfHwgcmVzdWx0LmNvbnRhaW5zQWxsKGRlcCkpIHsKLSAgICAgICAgICAgICAgICAgICAgcmVzdWx0LmFkZEVsZW1lbnQodmRlKTsKLSAgICAgICAgICAgICAgICAgICAgaW5wdXQucmVtb3ZlKGkpOwotICAgICAgICAgICAgICAgICAgICBjaGFuZ2VkID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIGkrKzsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIElmIG5vdGhpbmcgd2FzIGNoYW5nZWQgaW4gdGhpcyBwYXNzIHRoZW4gd2UgaGF2ZSBhIGNpcmN1bGFyIHJlZgotICAgICAgICAgICAgaWYgKCFjaGFuZ2VkKSB7Ci0gICAgICAgICAgICAgICAgRXJyb3JNc2cgZXJyID0gbmV3IEVycm9yTXNnKEVycm9yTXNnLkNJUkNVTEFSX1ZBUklBQkxFX0VSUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQudG9TdHJpbmcoKSwgdGhpcyk7Ci0gICAgICAgICAgICAgICAgZ2V0UGFyc2VyKCkucmVwb3J0RXJyb3IoQ29uc3RhbnRzLkVSUk9SLCBlcnIpOwotICAgICAgICAgICAgICAgIHJldHVybihyZXN1bHQpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLyogREVCVUcgQ09ERSAtIElOR09SRQotICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSIpOwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlc3VsdC5zaXplKCk7IGkrKykgewotICAgICAgICAgICAgZmluYWwgVG9wTGV2ZWxFbGVtZW50IGUgPSAoVG9wTGV2ZWxFbGVtZW50KSByZXN1bHQuZWxlbWVudEF0KGkpOwotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJlID0gIiArIGUpOwotICAgICAgICB9Ci0gICAgICAgICovCi0KLSAgICAgICAgcmV0dXJuIHJlc3VsdDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb21waWxlIGEgYnVpbGRLZXlzKCkgbWV0aG9kIGludG8gdGhlIG91dHB1dCBjbGFzcy4gTm90ZSB0aGF0IGtleXMKLSAgICAgKiBmb3IgdGhlIGlucHV0IGRvY3VtZW50IGFyZSBjcmVhdGVkIGluIHRvcExldmVsKCksIG5vdCBpbiB0aGlzIG1ldGhvZC4KLSAgICAgKiBIb3dldmVyLCB3ZSBzdGlsbCBuZWVkIHRoaXMgbWV0aG9kIHRvIGNyZWF0ZSBrZXlzIGZvciBkb2N1bWVudHMgbG9hZGVkCi0gICAgICogdmlhIHRoZSBYUGF0aCBkb2N1bWVudCgpIGZ1bmN0aW9uLgotICAgICAqLwotICAgIHByaXZhdGUgU3RyaW5nIGNvbXBpbGVCdWlsZEtleXMoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4pIHsKLSAgICAgICAgZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotCi0gICAgICAgIGZpbmFsIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuVHlwZVtdIGFyZ1R5cGVzID0gewotICAgICAgICAgICAgVXRpbC5nZXRKQ1JlZlR5cGUoRE9NX0lOVEZfU0lHKSwKLSAgICAgICAgICAgIFV0aWwuZ2V0SkNSZWZUeXBlKE5PREVfSVRFUkFUT1JfU0lHKSwKLSAgICAgICAgICAgIFV0aWwuZ2V0SkNSZWZUeXBlKFRSQU5TTEVUX09VVFBVVF9TSUcpLAotICAgICAgICAgICAgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5UeXBlLklOVAotICAgICAgICB9OwotCi0gICAgICAgIGZpbmFsIFN0cmluZ1tdIGFyZ05hbWVzID0gewotICAgICAgICAgICAgRE9DVU1FTlRfUE5BTUUsIElURVJBVE9SX1BOQU1FLCBUUkFOU0xFVF9PVVRQVVRfUE5BTUUsICJjdXJyZW50IgotICAgICAgICB9OwotCi0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG5ldyBJbnN0cnVjdGlvbkxpc3QoKTsKLQotICAgICAgICBmaW5hbCBNZXRob2RHZW5lcmF0b3IgYnVpbGRLZXlzID0KLSAgICAgICAgICAgIG5ldyBNZXRob2RHZW5lcmF0b3IoQUNDX1BVQkxJQywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5UeXBlLlZPSUQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyZ1R5cGVzLCBhcmdOYW1lcywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImJ1aWxkS2V5cyIsIF9jbGFzc05hbWUsIGlsLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKSk7Ci0KLSAgICAgICAgYnVpbGRLZXlzLmFkZEV4Y2VwdGlvbigiY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLlRyYW5zbGV0RXhjZXB0aW9uIik7Ci0KLSAgICAgICAgZmluYWwgSXRlcmF0b3I8U3ludGF4VHJlZU5vZGU+IGVsZW1lbnRzID0gZWxlbWVudHMoKTsKLSAgICAgICAgd2hpbGUgKGVsZW1lbnRzLmhhc05leHQoKSkgewotICAgICAgICAgICAgLy8geHNsOmtleQotICAgICAgICAgICAgZmluYWwgU3ludGF4VHJlZU5vZGUgZWxlbWVudCA9IGVsZW1lbnRzLm5leHQoKTsKLSAgICAgICAgICAgIGlmIChlbGVtZW50IGluc3RhbmNlb2YgS2V5KSB7Ci0gICAgICAgICAgICAgICAgZmluYWwgS2V5IGtleSA9IChLZXkpZWxlbWVudDsKLSAgICAgICAgICAgICAgICBrZXkudHJhbnNsYXRlKGNsYXNzR2VuLCBidWlsZEtleXMpOwotICAgICAgICAgICAgICAgIF9rZXlzLnB1dChrZXkuZ2V0TmFtZSgpLGtleSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBpbC5hcHBlbmQoUkVUVVJOKTsKLQotICAgICAgICAvLyBDb21wdXRlIG1heCBsb2NhbHMgKyBzdGFjayBhbmQgYWRkIG1ldGhvZCB0byBjbGFzcwotICAgICAgICBidWlsZEtleXMuc3RyaXBBdHRyaWJ1dGVzKHRydWUpOwotICAgICAgICBidWlsZEtleXMuc2V0TWF4TG9jYWxzKCk7Ci0gICAgICAgIGJ1aWxkS2V5cy5zZXRNYXhTdGFjaygpOwotICAgICAgICBidWlsZEtleXMucmVtb3ZlTk9QcygpOwotCi0gICAgICAgIGNsYXNzR2VuLmFkZE1ldGhvZChidWlsZEtleXMuZ2V0TWV0aG9kKCkpOwotCi0gICAgICAgIHJldHVybigiKCIrRE9NX0lOVEZfU0lHK05PREVfSVRFUkFUT1JfU0lHK1RSQU5TTEVUX09VVFBVVF9TSUcrIkkpViIpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbXBpbGUgdHJhbnNmb3JtKCkgaW50byB0aGUgb3V0cHV0IGNsYXNzLiBUaGlzIG1ldGhvZCBpcyB1c2VkIHRvCi0gICAgICogaW5pdGlhbGl6ZSBnbG9iYWwgdmFyaWFibGVzIGFuZCBnbG9iYWwgcGFyYW1ldGVycy4gVGhlIGN1cnJlbnQgbm9kZQotICAgICAqIGlzIHNldCB0byBiZSB0aGUgZG9jdW1lbnQncyByb290IG5vZGUuCi0gICAgICovCi0gICAgcHJpdmF0ZSB2b2lkIGNvbXBpbGVUcmFuc2Zvcm0oQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4pIHsKLSAgICAgICAgZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotCi0gICAgICAgIC8qCi0gICAgICAgICAqIERlZmluZSB0aGUgdGhlIG1ldGhvZCB0cmFuc2Zvcm0gd2l0aCB0aGUgZm9sbG93aW5nIHNpZ25hdHVyZToKLSAgICAgICAgICogdm9pZCB0cmFuc2Zvcm0oRE9NLCBOb2RlSXRlcmF0b3IsIEhhbmRsZXJCYXNlKQotICAgICAgICAgKi8KLSAgICAgICAgZmluYWwgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5UeXBlW10gYXJnVHlwZXMgPQotICAgICAgICAgICAgbmV3IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuVHlwZVszXTsKLSAgICAgICAgYXJnVHlwZXNbMF0gPSBVdGlsLmdldEpDUmVmVHlwZShET01fSU5URl9TSUcpOwotICAgICAgICBhcmdUeXBlc1sxXSA9IFV0aWwuZ2V0SkNSZWZUeXBlKE5PREVfSVRFUkFUT1JfU0lHKTsKLSAgICAgICAgYXJnVHlwZXNbMl0gPSBVdGlsLmdldEpDUmVmVHlwZShUUkFOU0xFVF9PVVRQVVRfU0lHKTsKLQotICAgICAgICBmaW5hbCBTdHJpbmdbXSBhcmdOYW1lcyA9IG5ldyBTdHJpbmdbM107Ci0gICAgICAgIGFyZ05hbWVzWzBdID0gRE9DVU1FTlRfUE5BTUU7Ci0gICAgICAgIGFyZ05hbWVzWzFdID0gSVRFUkFUT1JfUE5BTUU7Ci0gICAgICAgIGFyZ05hbWVzWzJdID0gVFJBTlNMRVRfT1VUUFVUX1BOQU1FOwotCi0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG5ldyBJbnN0cnVjdGlvbkxpc3QoKTsKLSAgICAgICAgZmluYWwgTWV0aG9kR2VuZXJhdG9yIHRyYW5zZiA9Ci0gICAgICAgICAgICBuZXcgTWV0aG9kR2VuZXJhdG9yKEFDQ19QVUJMSUMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuVHlwZS5WT0lELAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmdUeXBlcywgYXJnTmFtZXMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0cmFuc2Zvcm0iLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfY2xhc3NOYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCkpOwotICAgICAgICB0cmFuc2YuYWRkRXhjZXB0aW9uKCJjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuVHJhbnNsZXRFeGNlcHRpb24iKTsKLQotICAgICAgICAvLyBjYWxsIHJlc2V0UHJlZml4SW5kZXggYXQgdGhlIGJlZ2lubmluZyBvZiB0cmFuc2Zvcm0KLSAgICAgICAgZmluYWwgaW50IGNoZWNrID0gY3BnLmFkZE1ldGhvZHJlZihCQVNJU19MSUJSQVJZX0NMQVNTLCAicmVzZXRQcmVmaXhJbmRleCIsICIoKVYiKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VTVEFUSUMoY2hlY2spKTsKLQotICAgICAgICAvLyBEZWZpbmUgYW5kIGluaXRpYWxpemUgY3VycmVudCB3aXRoIHRoZSByb290IG5vZGUKLSAgICAgICAgZmluYWwgTG9jYWxWYXJpYWJsZUdlbiBjdXJyZW50ID0KLSAgICAgICAgICAgIHRyYW5zZi5hZGRMb2NhbFZhcmlhYmxlKCJjdXJyZW50IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuVHlwZS5JTlQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLCBudWxsKTsKLSAgICAgICAgZmluYWwgU3RyaW5nIGFwcGx5VGVtcGxhdGVzU2lnID0gY2xhc3NHZW4uZ2V0QXBwbHlUZW1wbGF0ZXNTaWcoKTsKLSAgICAgICAgZmluYWwgaW50IGFwcGx5VGVtcGxhdGVzID0gY3BnLmFkZE1ldGhvZHJlZihnZXRDbGFzc05hbWUoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYXBwbHlUZW1wbGF0ZXMiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcGx5VGVtcGxhdGVzU2lnKTsKLSAgICAgICAgZmluYWwgaW50IGRvbUZpZWxkID0gY3BnLmFkZEZpZWxkcmVmKGdldENsYXNzTmFtZSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRE9NX0ZJRUxELAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRE9NX0lOVEZfU0lHKTsKLQotICAgICAgICAvLyBwdXNoIHRyYW5zbGV0IGZvciBQVVRGSUVMRAotICAgICAgICBpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpOwotICAgICAgICAvLyBwcmVwYXJlIGFwcHJvcHJpYXRlIERPTSBpbXBsZW1lbnRhdGlvbgotCi0gICAgICAgIGlmIChpc011bHRpRG9jdW1lbnQoKSkgewotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBORVcoY3BnLmFkZENsYXNzKE1VTFRJX0RPTV9DTEFTUykpKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChEVVApOwotICAgICAgICB9Ci0KLSAgICAgICAgaWwuYXBwZW5kKGNsYXNzR2VuLmxvYWRUcmFuc2xldCgpKTsKLSAgICAgICAgaWwuYXBwZW5kKHRyYW5zZi5sb2FkRE9NKCkpOwotICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRVZJUlRVQUwoY3BnLmFkZE1ldGhvZHJlZihUUkFOU0xFVF9DTEFTUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm1ha2VET01BZGFwdGVyIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIigiK0RPTV9JTlRGX1NJRysiKSIrCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERPTV9BREFQVEVSX1NJRykpKTsKLSAgICAgICAgLy8gRE9NQWRhcHRlciBpcyBvbiB0aGUgc3RhY2sKLQotICAgICAgICBpZiAoaXNNdWx0aURvY3VtZW50KCkpIHsKLSAgICAgICAgICAgIGZpbmFsIGludCBpbml0ID0gY3BnLmFkZE1ldGhvZHJlZihNVUxUSV9ET01fQ0xBU1MsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjxpbml0PiIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIigiK0RPTV9JTlRGX1NJRysiKVYiKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFU1BFQ0lBTChpbml0KSk7Ci0gICAgICAgICAgICAvLyBNdWx0aURPTSBpcyBvbiB0aGUgc3RhY2sKLSAgICAgICAgfQotCi0gICAgICAgIC8vc3RvcmUgdG8gX2RvbSB2YXJpYWJsZQotICAgICAgICBpbC5hcHBlbmQobmV3IFBVVEZJRUxEKGRvbUZpZWxkKSk7Ci0KLSAgICAgICAgLy8gY29udGludWUgd2l0aCBnbG9iYWxzIGluaXRpYWxpemF0aW9uCi0gICAgICAgIGZpbmFsIGludCBnaXRyID0gY3BnLmFkZEludGVyZmFjZU1ldGhvZHJlZihET01fSU5URiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImdldEl0ZXJhdG9yIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIigpIitOT0RFX0lURVJBVE9SX1NJRyk7Ci0gICAgICAgIGlsLmFwcGVuZCh0cmFuc2YubG9hZERPTSgpKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0UoZ2l0ciwgMSkpOwotICAgICAgICBpbC5hcHBlbmQodHJhbnNmLm5leHROb2RlKCkpOwotICAgICAgICBjdXJyZW50LnNldFN0YXJ0KGlsLmFwcGVuZChuZXcgSVNUT1JFKGN1cnJlbnQuZ2V0SW5kZXgoKSkpKTsKLQotICAgICAgICAvLyBUcmFuc2ZlciB0aGUgb3V0cHV0IHNldHRpbmdzIHRvIHRoZSBvdXRwdXQgcG9zdC1wcm9jZXNzb3IKLSAgICAgICAgaWwuYXBwZW5kKGNsYXNzR2VuLmxvYWRUcmFuc2xldCgpKTsKLSAgICAgICAgaWwuYXBwZW5kKHRyYW5zZi5sb2FkSGFuZGxlcigpKTsKLSAgICAgICAgZmluYWwgaW50IGluZGV4ID0gY3BnLmFkZE1ldGhvZHJlZihUUkFOU0xFVF9DTEFTUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidHJhbnNmZXJPdXRwdXRTZXR0aW5ncyIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIigiK09VVFBVVF9IQU5ETEVSX1NJRysiKVYiKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VWSVJUVUFMKGluZGV4KSk7Ci0KLSAgICAgICAgLyoKLSAgICAgICAgICogQ29tcGlsZSBidWlsZEtleXMoKSBtZXRob2QuIE5vdGUgdGhhdCB0aGlzIG1ldGhvZCBpcyBub3QKLSAgICAgICAgICogaW52b2tlZCBoZXJlIGFzIGtleXMgZm9yIHRoZSBpbnB1dCBkb2N1bWVudCBhcmUgbm93IGNyZWF0ZWQKLSAgICAgICAgICogaW4gdG9wTGV2ZWwoKS4gSG93ZXZlciwgdGhpcyBtZXRob2QgaXMgc3RpbGwgbmVlZGVkIGJ5IHRoZQotICAgICAgICAgKiBMb2FkRG9jdW1lbnQgY2xhc3MuCi0gICAgICAgICAqLwotICAgICAgICBmaW5hbCBTdHJpbmcga2V5U2lnID0gY29tcGlsZUJ1aWxkS2V5cyhjbGFzc0dlbik7Ci0gICAgICAgIGZpbmFsIGludCBrZXlJZHggPSBjcGcuYWRkTWV0aG9kcmVmKGdldENsYXNzTmFtZSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYnVpbGRLZXlzIiwga2V5U2lnKTsKLQotICAgICAgICAvLyBMb29rIGZvciB0b3AtbGV2ZWwgZWxlbWVudHMgdGhhdCBuZWVkIGhhbmRsaW5nCi0gICAgICAgIGZpbmFsIEl0ZXJhdG9yPFN5bnRheFRyZWVOb2RlPiB0b3BsZXZlbCA9IGVsZW1lbnRzKCk7Ci0gICAgICAgIGlmIChfZ2xvYmFscy5zaXplKCkgPiAwIHx8IHRvcGxldmVsLmhhc05leHQoKSkgewotICAgICAgICAgICAgLy8gQ29tcGlsZSBtZXRob2QgZm9yIGhhbmRsaW5nIHRvcC1sZXZlbCBlbGVtZW50cwotICAgICAgICAgICAgZmluYWwgU3RyaW5nIHRvcExldmVsU2lnID0gY29tcGlsZVRvcExldmVsKGNsYXNzR2VuKTsKLSAgICAgICAgICAgIC8vIEdldCBhIHJlZmVyZW5jZSB0byB0aGF0IG1ldGhvZAotICAgICAgICAgICAgZmluYWwgaW50IHRvcExldmVsSWR4ID0gY3BnLmFkZE1ldGhvZHJlZihnZXRDbGFzc05hbWUoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRvcExldmVsIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG9wTGV2ZWxTaWcpOwotICAgICAgICAgICAgLy8gUHVzaCBhbGwgcGFyYW1ldGVycyBvbiB0aGUgc3RhY2sgYW5kIGNhbGwgdG9wTGV2ZWwoKQotICAgICAgICAgICAgaWwuYXBwZW5kKGNsYXNzR2VuLmxvYWRUcmFuc2xldCgpKTsgLy8gVGhlICd0aGlzJyBwb2ludGVyCi0gICAgICAgICAgICBpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBHRVRGSUVMRChkb21GaWVsZCkpOyAgLy8gVGhlIERPTSByZWZlcmVuY2UKLSAgICAgICAgICAgIGlsLmFwcGVuZCh0cmFuc2YubG9hZEl0ZXJhdG9yKCkpOwotICAgICAgICAgICAgaWwuYXBwZW5kKHRyYW5zZi5sb2FkSGFuZGxlcigpKTsgICAgLy8gVGhlIG91dHB1dCBoYW5kbGVyCi0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRVZJUlRVQUwodG9wTGV2ZWxJZHgpKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIHN0YXJ0IGRvY3VtZW50Ci0gICAgICAgIGlsLmFwcGVuZCh0cmFuc2YubG9hZEhhbmRsZXIoKSk7Ci0gICAgICAgIGlsLmFwcGVuZCh0cmFuc2Yuc3RhcnREb2N1bWVudCgpKTsKLQotICAgICAgICAvLyBwdXNoIGZpcnN0IGFyZyBmb3IgYXBwbHlUZW1wbGF0ZXMKLSAgICAgICAgaWwuYXBwZW5kKGNsYXNzR2VuLmxvYWRUcmFuc2xldCgpKTsKLSAgICAgICAgLy8gcHVzaCB0cmFuc2xldCBmb3IgR0VURklFTEQgdG8gZ2V0IERPTSBhcmcKLSAgICAgICAgaWwuYXBwZW5kKGNsYXNzR2VuLmxvYWRUcmFuc2xldCgpKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBHRVRGSUVMRChkb21GaWVsZCkpOwotICAgICAgICAvLyBwdXNoIHJlbWFpbmluZyAyIGFyZ3MKLSAgICAgICAgaWwuYXBwZW5kKHRyYW5zZi5sb2FkSXRlcmF0b3IoKSk7Ci0gICAgICAgIGlsLmFwcGVuZCh0cmFuc2YubG9hZEhhbmRsZXIoKSk7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChhcHBseVRlbXBsYXRlcykpOwotICAgICAgICAvLyBlbmREb2N1bWVudAotICAgICAgICBpbC5hcHBlbmQodHJhbnNmLmxvYWRIYW5kbGVyKCkpOwotICAgICAgICBpbC5hcHBlbmQodHJhbnNmLmVuZERvY3VtZW50KCkpOwotCi0gICAgICAgIGlsLmFwcGVuZChSRVRVUk4pOwotCi0gICAgICAgIC8vIENvbXB1dGUgbWF4IGxvY2FscyArIHN0YWNrIGFuZCBhZGQgbWV0aG9kIHRvIGNsYXNzCi0gICAgICAgIGNsYXNzR2VuLmFkZE1ldGhvZCh0cmFuc2YpOwotCi0gICAgfQotCi0gICAgLyoqCi0gICAgICogUGVlcGhvbGUgb3B0aW1pemF0aW9uOiBSZW1vdmUgc2VxdWVuY2VzIG9mIFtBTE9BRCwgUE9QXS4KLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgcGVlcEhvbGVPcHRpbWl6YXRpb24oTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotICAgICAgICBmaW5hbCBTdHJpbmcgcGF0dGVybiA9ICJgYWxvYWQnYHBvcCdgaW5zdHJ1Y3Rpb24nIjsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkZpbmRlciBmaW5kID0gbmV3IEluc3RydWN0aW9uRmluZGVyKGlsKTsKLSAgICAgICAgZm9yKEl0ZXJhdG9yIGl0ZXI9ZmluZC5zZWFyY2gocGF0dGVybik7IGl0ZXIuaGFzTmV4dCgpOyApIHsKLSAgICAgICAgICAgIEluc3RydWN0aW9uSGFuZGxlW10gbWF0Y2ggPSAoSW5zdHJ1Y3Rpb25IYW5kbGVbXSlpdGVyLm5leHQoKTsKLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgaWwuZGVsZXRlKG1hdGNoWzBdLCBtYXRjaFsxXSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXRjaCAoVGFyZ2V0TG9zdEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgLy8gVE9ETzogbW92ZSB0YXJnZXQgZG93biBpbnRvIHRoZSBsaXN0Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGFkZFBhcmFtKFBhcmFtIHBhcmFtKSB7Ci0gICAgICAgIF9nbG9iYWxzLmFkZEVsZW1lbnQocGFyYW0pOwotICAgICAgICByZXR1cm4gX2dsb2JhbHMuc2l6ZSgpIC0gMTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGFkZFZhcmlhYmxlKFZhcmlhYmxlIGdsb2JhbCkgewotICAgICAgICBfZ2xvYmFscy5hZGRFbGVtZW50KGdsb2JhbCk7Ci0gICAgICAgIHJldHVybiBfZ2xvYmFscy5zaXplKCkgLSAxOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGRpc3BsYXkoaW50IGluZGVudCkgewotICAgICAgICBpbmRlbnQoaW5kZW50KTsKLSAgICAgICAgVXRpbC5wcmludGxuKCJTdHlsZXNoZWV0Iik7Ci0gICAgICAgIGRpc3BsYXlDb250ZW50cyhpbmRlbnQgKyBJbmRlbnRJbmNyZW1lbnQpOwotICAgIH0KLQotICAgIC8vIGRvIHdlIG5lZWQgdGhpcyB3cmFwcGVyID8/Pz8/Ci0gICAgcHVibGljIFN0cmluZyBnZXROYW1lc3BhY2UoU3RyaW5nIHByZWZpeCkgewotICAgICAgICByZXR1cm4gbG9va3VwTmFtZXNwYWNlKHByZWZpeCk7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRDbGFzc05hbWUoKSB7Ci0gICAgICAgIHJldHVybiBfY2xhc3NOYW1lOwotICAgIH0KLQotICAgIHB1YmxpYyBWZWN0b3IgZ2V0VGVtcGxhdGVzKCkgewotICAgICAgICByZXR1cm4gX3RlbXBsYXRlczsKLSAgICB9Ci0KLSAgICBwdWJsaWMgVmVjdG9yIGdldEFsbFZhbGlkVGVtcGxhdGVzKCkgewotICAgICAgICAvLyBSZXR1cm4gdGVtcGxhdGVzIGlmIG5vIGltcG9ydGVkL2luY2x1ZGVkIHN0eWxlc2hlZXRzCi0gICAgICAgIGlmIChfaW5jbHVkZWRTdHlsZXNoZWV0cyA9PSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gX3RlbXBsYXRlczsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIElzIHJldHVybmVkIHZhbHVlIGNhY2hlZD8KLSAgICAgICAgaWYgKF9hbGxWYWxpZFRlbXBsYXRlcyA9PSBudWxsKSB7Ci0gICAgICAgICAgIFZlY3RvciB0ZW1wbGF0ZXMgPSBuZXcgVmVjdG9yKCk7Ci0gICAgICAgICAgIHRlbXBsYXRlcy5hZGRBbGwoX3RlbXBsYXRlcyk7Ci0gICAgICAgICAgICBpbnQgc2l6ZSA9IF9pbmNsdWRlZFN0eWxlc2hlZXRzLnNpemUoKTsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgU3R5bGVzaGVldCBpbmNsdWRlZCA9KFN0eWxlc2hlZXQpX2luY2x1ZGVkU3R5bGVzaGVldHMuZWxlbWVudEF0KGkpOwotICAgICAgICAgICAgICAgIHRlbXBsYXRlcy5hZGRBbGwoaW5jbHVkZWQuZ2V0QWxsVmFsaWRUZW1wbGF0ZXMoKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvL3RlbXBsYXRlcy5hZGRBbGwoX3RlbXBsYXRlcyk7Ci0KLSAgICAgICAgICAgIC8vIENhY2hlIHJlc3VsdHMgaW4gdG9wLWxldmVsIHN0eWxlc2hlZXQgb25seQotICAgICAgICAgICAgaWYgKF9wYXJlbnRTdHlsZXNoZWV0ICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gdGVtcGxhdGVzOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgX2FsbFZhbGlkVGVtcGxhdGVzID0gdGVtcGxhdGVzOwotICAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBfYWxsVmFsaWRUZW1wbGF0ZXM7Ci0gICAgfQotCi0gICAgcHJvdGVjdGVkIHZvaWQgYWRkVGVtcGxhdGUoVGVtcGxhdGUgdGVtcGxhdGUpIHsKLSAgICAgICAgX3RlbXBsYXRlcy5hZGRFbGVtZW50KHRlbXBsYXRlKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL1N5bWJvbFRhYmxlLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL1N5bWJvbFRhYmxlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGRmYjk1YjcuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9TeW1ib2xUYWJsZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjk1ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKi8KLS8qCi0gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKLSAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAotICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgotICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKLSAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCi0gKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogU3ltYm9sVGFibGUuamF2YSx2IDEuNSAyMDA1LzA5LzI4IDEzOjQ4OjE2IHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLk1ldGhvZFR5cGU7Ci1pbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7Ci1pbXBvcnQgamF2YS51dGlsLk1hcDsKLWltcG9ydCBqYXZhLnV0aWwuU3RhY2s7Ci1pbXBvcnQgamF2YS51dGlsLlN0cmluZ1Rva2VuaXplcjsKLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi0vKioKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICovCi1maW5hbCBjbGFzcyBTeW1ib2xUYWJsZSB7Ci0KLSAgICAvLyBUaGVzZSBtYXBzIGFyZSB1c2VkIGZvciBhbGwgc3R5bGVzaGVldHMKLSAgICBwcml2YXRlIGZpbmFsIE1hcDxTdHJpbmcsIFN0eWxlc2hlZXQ+IF9zdHlsZXNoZWV0cyA9IG5ldyBIYXNoTWFwPD4oKTsKLSAgICBwcml2YXRlIGZpbmFsIE1hcDxTdHJpbmcsIFZlY3Rvcj4gX3ByaW1vcHMgICAgID0gbmV3IEhhc2hNYXA8PigpOwotCi0gICAgLy8gVGhlc2UgbWFwcyBhcmUgdXNlZCBmb3Igc29tZSBzdHlsZXNoZWV0cwotICAgIHByaXZhdGUgTWFwPFN0cmluZywgVmFyaWFibGVCYXNlPiBfdmFyaWFibGVzID0gbnVsbDsKLSAgICBwcml2YXRlIE1hcDxTdHJpbmcsIFRlbXBsYXRlPiBfdGVtcGxhdGVzID0gbnVsbDsKLSAgICBwcml2YXRlIE1hcDxTdHJpbmcsIEF0dHJpYnV0ZVNldD4gX2F0dHJpYnV0ZVNldHMgPSBudWxsOwotICAgIHByaXZhdGUgTWFwPFN0cmluZywgU3RyaW5nPiBfYWxpYXNlcyA9IG51bGw7Ci0gICAgcHJpdmF0ZSBNYXA8U3RyaW5nLCBJbnRlZ2VyPiBfZXhjbHVkZWRVUkkgPSBudWxsOwotICAgIHByaXZhdGUgU3RhY2s8TWFwPFN0cmluZywgSW50ZWdlcj4+ICAgICBfZXhjbHVkZWRVUklTdGFjayA9IG51bGw7Ci0gICAgcHJpdmF0ZSBNYXA8U3RyaW5nLCBEZWNpbWFsRm9ybWF0dGluZz4gX2RlY2ltYWxGb3JtYXRzID0gbnVsbDsKLSAgICBwcml2YXRlIE1hcDxTdHJpbmcsIEtleT4gX2tleXMgPSBudWxsOwotCi0gICAgcHVibGljIERlY2ltYWxGb3JtYXR0aW5nIGdldERlY2ltYWxGb3JtYXR0aW5nKFFOYW1lIG5hbWUpIHsKLSAgICAgICAgaWYgKF9kZWNpbWFsRm9ybWF0cyA9PSBudWxsKSByZXR1cm4gbnVsbDsKLSAgICAgICAgcmV0dXJuKF9kZWNpbWFsRm9ybWF0cy5nZXQobmFtZS5nZXRTdHJpbmdSZXAoKSkpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGFkZERlY2ltYWxGb3JtYXR0aW5nKFFOYW1lIG5hbWUsIERlY2ltYWxGb3JtYXR0aW5nIHN5bWJvbHMpIHsKLSAgICAgICAgaWYgKF9kZWNpbWFsRm9ybWF0cyA9PSBudWxsKSBfZGVjaW1hbEZvcm1hdHMgPSBuZXcgSGFzaE1hcDw+KCk7Ci0gICAgICAgIF9kZWNpbWFsRm9ybWF0cy5wdXQobmFtZS5nZXRTdHJpbmdSZXAoKSwgc3ltYm9scyk7Ci0gICAgfQotCi0gICAgcHVibGljIEtleSBnZXRLZXkoUU5hbWUgbmFtZSkgewotICAgICAgICBpZiAoX2tleXMgPT0gbnVsbCkgcmV0dXJuIG51bGw7Ci0gICAgICAgIHJldHVybiBfa2V5cy5nZXQobmFtZS5nZXRTdHJpbmdSZXAoKSk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgYWRkS2V5KFFOYW1lIG5hbWUsIEtleSBrZXkpIHsKLSAgICAgICAgaWYgKF9rZXlzID09IG51bGwpIF9rZXlzID0gbmV3IEhhc2hNYXA8PigpOwotICAgICAgICBfa2V5cy5wdXQobmFtZS5nZXRTdHJpbmdSZXAoKSwga2V5KTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3R5bGVzaGVldCBhZGRTdHlsZXNoZWV0KFFOYW1lIG5hbWUsIFN0eWxlc2hlZXQgbm9kZSkgewotICAgICAgICByZXR1cm4gX3N0eWxlc2hlZXRzLnB1dChuYW1lLmdldFN0cmluZ1JlcCgpLCBub2RlKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3R5bGVzaGVldCBsb29rdXBTdHlsZXNoZWV0KFFOYW1lIG5hbWUpIHsKLSAgICAgICAgcmV0dXJuIF9zdHlsZXNoZWV0cy5nZXQobmFtZS5nZXRTdHJpbmdSZXAoKSk7Ci0gICAgfQotCi0gICAgcHVibGljIFRlbXBsYXRlIGFkZFRlbXBsYXRlKFRlbXBsYXRlIHRlbXBsYXRlKSB7Ci0gICAgICAgIGZpbmFsIFFOYW1lIG5hbWUgPSB0ZW1wbGF0ZS5nZXROYW1lKCk7Ci0gICAgICAgIGlmIChfdGVtcGxhdGVzID09IG51bGwpIF90ZW1wbGF0ZXMgPSBuZXcgSGFzaE1hcDw+KCk7Ci0gICAgICAgIHJldHVybiBfdGVtcGxhdGVzLnB1dChuYW1lLmdldFN0cmluZ1JlcCgpLCB0ZW1wbGF0ZSk7Ci0gICAgfQotCi0gICAgcHVibGljIFRlbXBsYXRlIGxvb2t1cFRlbXBsYXRlKFFOYW1lIG5hbWUpIHsKLSAgICAgICAgaWYgKF90ZW1wbGF0ZXMgPT0gbnVsbCkgcmV0dXJuIG51bGw7Ci0gICAgICAgIHJldHVybiBfdGVtcGxhdGVzLmdldChuYW1lLmdldFN0cmluZ1JlcCgpKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgVmFyaWFibGUgYWRkVmFyaWFibGUoVmFyaWFibGUgdmFyaWFibGUpIHsKLSAgICAgICAgaWYgKF92YXJpYWJsZXMgPT0gbnVsbCkgX3ZhcmlhYmxlcyA9IG5ldyBIYXNoTWFwPD4oKTsKLSAgICAgICAgZmluYWwgU3RyaW5nIG5hbWUgPSB2YXJpYWJsZS5nZXROYW1lKCkuZ2V0U3RyaW5nUmVwKCk7Ci0gICAgICAgIHJldHVybiAoVmFyaWFibGUpX3ZhcmlhYmxlcy5wdXQobmFtZSwgdmFyaWFibGUpOwotICAgIH0KLQotICAgIHB1YmxpYyBQYXJhbSBhZGRQYXJhbShQYXJhbSBwYXJhbWV0ZXIpIHsKLSAgICAgICAgaWYgKF92YXJpYWJsZXMgPT0gbnVsbCkgX3ZhcmlhYmxlcyA9IG5ldyBIYXNoTWFwPD4oKTsKLSAgICAgICAgZmluYWwgU3RyaW5nIG5hbWUgPSBwYXJhbWV0ZXIuZ2V0TmFtZSgpLmdldFN0cmluZ1JlcCgpOwotICAgICAgICByZXR1cm4gKFBhcmFtKV92YXJpYWJsZXMucHV0KG5hbWUsIHBhcmFtZXRlcik7Ci0gICAgfQotCi0gICAgcHVibGljIFZhcmlhYmxlIGxvb2t1cFZhcmlhYmxlKFFOYW1lIHFuYW1lKSB7Ci0gICAgICAgIGlmIChfdmFyaWFibGVzID09IG51bGwpIHJldHVybiBudWxsOwotICAgICAgICBmaW5hbCBTdHJpbmcgbmFtZSA9IHFuYW1lLmdldFN0cmluZ1JlcCgpOwotICAgICAgICBmaW5hbCBWYXJpYWJsZUJhc2Ugb2JqID0gX3ZhcmlhYmxlcy5nZXQobmFtZSk7Ci0gICAgICAgIHJldHVybiBvYmogaW5zdGFuY2VvZiBWYXJpYWJsZSA/IChWYXJpYWJsZSlvYmogOiBudWxsOwotICAgIH0KLQotICAgIHB1YmxpYyBQYXJhbSBsb29rdXBQYXJhbShRTmFtZSBxbmFtZSkgewotICAgICAgICBpZiAoX3ZhcmlhYmxlcyA9PSBudWxsKSByZXR1cm4gbnVsbDsKLSAgICAgICAgZmluYWwgU3RyaW5nIG5hbWUgPSBxbmFtZS5nZXRTdHJpbmdSZXAoKTsKLSAgICAgICAgZmluYWwgVmFyaWFibGVCYXNlIG9iaiA9IF92YXJpYWJsZXMuZ2V0KG5hbWUpOwotICAgICAgICByZXR1cm4gb2JqIGluc3RhbmNlb2YgUGFyYW0gPyAoUGFyYW0pb2JqIDogbnVsbDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3ludGF4VHJlZU5vZGUgbG9va3VwTmFtZShRTmFtZSBxbmFtZSkgewotICAgICAgICBpZiAoX3ZhcmlhYmxlcyA9PSBudWxsKSByZXR1cm4gbnVsbDsKLSAgICAgICAgZmluYWwgU3RyaW5nIG5hbWUgPSBxbmFtZS5nZXRTdHJpbmdSZXAoKTsKLSAgICAgICAgcmV0dXJuIChTeW50YXhUcmVlTm9kZSlfdmFyaWFibGVzLmdldChuYW1lKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgQXR0cmlidXRlU2V0IGFkZEF0dHJpYnV0ZVNldChBdHRyaWJ1dGVTZXQgYXR0cykgewotICAgICAgICBpZiAoX2F0dHJpYnV0ZVNldHMgPT0gbnVsbCkgX2F0dHJpYnV0ZVNldHMgPSBuZXcgSGFzaE1hcDw+KCk7Ci0gICAgICAgIHJldHVybiBfYXR0cmlidXRlU2V0cy5wdXQoYXR0cy5nZXROYW1lKCkuZ2V0U3RyaW5nUmVwKCksIGF0dHMpOwotICAgIH0KLQotICAgIHB1YmxpYyBBdHRyaWJ1dGVTZXQgbG9va3VwQXR0cmlidXRlU2V0KFFOYW1lIG5hbWUpIHsKLSAgICAgICAgaWYgKF9hdHRyaWJ1dGVTZXRzID09IG51bGwpIHJldHVybiBudWxsOwotICAgICAgICByZXR1cm4gX2F0dHJpYnV0ZVNldHMuZ2V0KG5hbWUuZ2V0U3RyaW5nUmVwKCkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEFkZCBhIHByaW1pdGl2ZSBvcGVyYXRvciBvciBmdW5jdGlvbiB0byB0aGUgc3ltYm9sIHRhYmxlLiBUbyBhdm9pZAotICAgICAqIG5hbWUgY2xhc2hlcyB3aXRoIHVzZXItZGVmaW5lZCBuYW1lcywgdGhlIHByZWZpeCA8dHQ+UHJpbW9wUHJlZml4PC90dD4KLSAgICAgKiBpcyBwcmVwZW5kZWQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgYWRkUHJpbW9wKFN0cmluZyBuYW1lLCBNZXRob2RUeXBlIG10eXBlKSB7Ci0gICAgICAgIFZlY3RvciBtZXRob2RzID0gX3ByaW1vcHMuZ2V0KG5hbWUpOwotICAgICAgICBpZiAobWV0aG9kcyA9PSBudWxsKSB7Ci0gICAgICAgICAgICBfcHJpbW9wcy5wdXQobmFtZSwgbWV0aG9kcyA9IG5ldyBWZWN0b3IoKSk7Ci0gICAgICAgIH0KLSAgICAgICAgbWV0aG9kcy5hZGRFbGVtZW50KG10eXBlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBMb29rdXAgYSBwcmltaXRpdmUgb3BlcmF0b3Igb3IgZnVuY3Rpb24gaW4gdGhlIHN5bWJvbCB0YWJsZSBieQotICAgICAqIHByZXBlbmRpbmcgdGhlIHByZWZpeCA8dHQ+UHJpbW9wUHJlZml4PC90dD4uCi0gICAgICovCi0gICAgcHVibGljIFZlY3RvciBsb29rdXBQcmltb3AoU3RyaW5nIG5hbWUpIHsKLSAgICAgICAgcmV0dXJuIF9wcmltb3BzLmdldChuYW1lKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIGlzIHVzZWQgZm9yIHhzbDphdHRyaWJ1dGUgZWxlbWVudHMgdGhhdCBoYXZlIGEgIm5hbWVzcGFjZSIKLSAgICAgKiBhdHRyaWJ1dGUgdGhhdCBpcyBjdXJyZW50bHkgbm90IGRlZmluZWQgdXNpbmcgeG1sbnM6Ci0gICAgICovCi0gICAgcHJpdmF0ZSBpbnQgX25zQ291bnRlciA9IDA7Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdlbmVyYXRlTmFtZXNwYWNlUHJlZml4KCkgewotICAgICAgICByZXR1cm4oIm5zIisoX25zQ291bnRlcisrKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVXNlIGEgbmFtZXNwYWNlIHByZWZpeCB0byBsb29rdXAgYSBuYW1lc3BhY2UgVVJJCi0gICAgICovCi0gICAgcHJpdmF0ZSBTeW50YXhUcmVlTm9kZSBfY3VycmVudCA9IG51bGw7Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRDdXJyZW50Tm9kZShTeW50YXhUcmVlTm9kZSBub2RlKSB7Ci0gICAgICAgIF9jdXJyZW50ID0gbm9kZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGxvb2t1cE5hbWVzcGFjZShTdHJpbmcgcHJlZml4KSB7Ci0gICAgICAgIGlmIChfY3VycmVudCA9PSBudWxsKSByZXR1cm4oQ29uc3RhbnRzLkVNUFRZU1RSSU5HKTsKLSAgICAgICAgcmV0dXJuKF9jdXJyZW50Lmxvb2t1cE5hbWVzcGFjZShwcmVmaXgpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBZGRzIGFuIGFsaWFzIGZvciBhIG5hbWVzcGFjZSBwcmVmaXgKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBhZGRQcmVmaXhBbGlhcyhTdHJpbmcgcHJlZml4LCBTdHJpbmcgYWxpYXMpIHsKLSAgICAgICAgaWYgKF9hbGlhc2VzID09IG51bGwpIF9hbGlhc2VzID0gbmV3IEhhc2hNYXA8PigpOwotICAgICAgICBfYWxpYXNlcy5wdXQocHJlZml4LGFsaWFzKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXRyaWV2ZXMgYW55IGFsaWFzIGZvciBhIGdpdmVuIG5hbWVzcGFjZSBwcmVmaXgKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGxvb2t1cFByZWZpeEFsaWFzKFN0cmluZyBwcmVmaXgpIHsKLSAgICAgICAgaWYgKF9hbGlhc2VzID09IG51bGwpIHJldHVybiBudWxsOwotICAgICAgICByZXR1cm4gX2FsaWFzZXMuZ2V0KHByZWZpeCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmVnaXN0ZXIgYSBuYW1lc3BhY2UgVVJJIHNvIHRoYXQgaXQgd2lsbCBub3QgYmUgZGVjbGFyZWQgaW4gdGhlIG91dHB1dAotICAgICAqIHVubGVzcyBpdCBpcyBhY3R1YWxseSByZWZlcmVuY2VkIGluIHRoZSBvdXRwdXQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZXhjbHVkZVVSSShTdHJpbmcgdXJpKSB7Ci0gICAgICAgIC8vIFRoZSBudWxsLW5hbWVzcGFjZSBjYW5ub3QgYmUgZXhjbHVkZWQKLSAgICAgICAgaWYgKHVyaSA9PSBudWxsKSByZXR1cm47Ci0KLSAgICAgICAgLy8gQ3JlYXRlIGEgbmV3IG1hcCBvZiBleGxjdWRlZCBVUklzIGlmIG5vbmUgZXhpc3RzCi0gICAgICAgIGlmIChfZXhjbHVkZWRVUkkgPT0gbnVsbCkgX2V4Y2x1ZGVkVVJJID0gbmV3IEhhc2hNYXA8PigpOwotCi0gICAgICAgIC8vIFJlZ2lzdGVyIHRoZSBuYW1lc3BhY2UgVVJJCi0gICAgICAgIEludGVnZXIgcmVmY250ID0gX2V4Y2x1ZGVkVVJJLmdldCh1cmkpOwotICAgICAgICBpZiAocmVmY250ID09IG51bGwpCi0gICAgICAgICAgICByZWZjbnQgPSAxOwotICAgICAgICBlbHNlCi0gICAgICAgICAgICByZWZjbnQgPSByZWZjbnQgKyAxOwotICAgICAgICBfZXhjbHVkZWRVUkkucHV0KHVyaSxyZWZjbnQpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEV4Y2x1ZGUgYSBzZXJpZXMgb2YgbmFtZXNwYWNlcyBnaXZlbiBieSBhIGxpc3Qgb2Ygd2hpdGVzcGFjZQotICAgICAqIHNlcGFyYXRlZCBuYW1lc3BhY2UgcHJlZml4ZXMuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZXhjbHVkZU5hbWVzcGFjZXMoU3RyaW5nIHByZWZpeGVzKSB7Ci0gICAgICAgIGlmIChwcmVmaXhlcyAhPSBudWxsKSB7Ci0gICAgICAgICAgICBTdHJpbmdUb2tlbml6ZXIgdG9rZW5zID0gbmV3IFN0cmluZ1Rva2VuaXplcihwcmVmaXhlcyk7Ci0gICAgICAgICAgICB3aGlsZSAodG9rZW5zLmhhc01vcmVUb2tlbnMoKSkgewotICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBwcmVmaXggPSB0b2tlbnMubmV4dFRva2VuKCk7Ci0gICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIHVyaTsKLSAgICAgICAgICAgICAgICBpZiAocHJlZml4LmVxdWFscygiI2RlZmF1bHQiKSkKLSAgICAgICAgICAgICAgICAgICAgdXJpID0gbG9va3VwTmFtZXNwYWNlKENvbnN0YW50cy5FTVBUWVNUUklORyk7Ci0gICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICB1cmkgPSBsb29rdXBOYW1lc3BhY2UocHJlZml4KTsKLSAgICAgICAgICAgICAgICBpZiAodXJpICE9IG51bGwpIGV4Y2x1ZGVVUkkodXJpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIENoZWNrIGlmIGEgbmFtZXNwYWNlIHNob3VsZCBub3QgYmUgZGVjbGFyZWQgaW4gdGhlIG91dHB1dCAodW5sZXNzIHVzZWQpCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNFeGNsdWRlZE5hbWVzcGFjZShTdHJpbmcgdXJpKSB7Ci0gICAgICAgIGlmICh1cmkgIT0gbnVsbCAmJiBfZXhjbHVkZWRVUkkgIT0gbnVsbCkgewotICAgICAgICAgICAgZmluYWwgSW50ZWdlciByZWZjbnQgPSBfZXhjbHVkZWRVUkkuZ2V0KHVyaSk7Ci0gICAgICAgICAgICByZXR1cm4gKHJlZmNudCAhPSBudWxsICYmIHJlZmNudCA+IDApOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUdXJuIG9mIG5hbWVzcGFjZSBkZWNsYXJhdGlvbiBleGNsdXNpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB1bkV4Y2x1ZGVOYW1lc3BhY2VzKFN0cmluZyBwcmVmaXhlcykgewotICAgICAgICBpZiAoX2V4Y2x1ZGVkVVJJID09IG51bGwpIHJldHVybjsKLSAgICAgICAgaWYgKHByZWZpeGVzICE9IG51bGwpIHsKLSAgICAgICAgICAgIFN0cmluZ1Rva2VuaXplciB0b2tlbnMgPSBuZXcgU3RyaW5nVG9rZW5pemVyKHByZWZpeGVzKTsKLSAgICAgICAgICAgIHdoaWxlICh0b2tlbnMuaGFzTW9yZVRva2VucygpKSB7Ci0gICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIHByZWZpeCA9IHRva2Vucy5uZXh0VG9rZW4oKTsKLSAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgdXJpOwotICAgICAgICAgICAgICAgIGlmIChwcmVmaXguZXF1YWxzKCIjZGVmYXVsdCIpKQotICAgICAgICAgICAgICAgICAgICB1cmkgPSBsb29rdXBOYW1lc3BhY2UoQ29uc3RhbnRzLkVNUFRZU1RSSU5HKTsKLSAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgIHVyaSA9IGxvb2t1cE5hbWVzcGFjZShwcmVmaXgpOwotICAgICAgICAgICAgICAgIEludGVnZXIgcmVmY250ID0gX2V4Y2x1ZGVkVVJJLmdldCh1cmkpOwotICAgICAgICAgICAgICAgIGlmIChyZWZjbnQgIT0gbnVsbCkKLSAgICAgICAgICAgICAgICAgICAgX2V4Y2x1ZGVkVVJJLnB1dCh1cmksIHJlZmNudCAtIDEpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotICAgIC8qKgotICAgICAqIEV4Y2x1c2lvbiBvZiBuYW1lc3BhY2VzIGJ5IGEgc3R5bGVzaGVldCBkb2VzIG5vdCBleHRlbmQgdG8gYW55IHN0eWxlc2hlZXQKLSAgICAgKiBpbXBvcnRlZCBvciBpbmNsdWRlZCBieSB0aGUgc3R5bGVzaGVldC4gIFVwb24gZW50ZXJpbmcgdGhlIGNvbnRleHQgb2YgYQotICAgICAqIG5ldyBzdHlsZXNoZWV0LCBhIGNhbGwgdG8gdGhpcyBtZXRob2QgaXMgbmVlZGVkIHRvIGNsZWFyIHRoZSBjdXJyZW50IHNldAotICAgICAqIG9mIGV4Y2x1ZGVkIG5hbWVzcGFjZXMgdGVtcG9yYXJpbHkuICBFdmVyeSBjYWxsIHRvIHRoaXMgbWV0aG9kIHJlcXVpcmVzCi0gICAgICogYSBjb3JyZXNwb25kaW5nIGNhbGwgdG8ge0BsaW5rICNwb3BFeGNsdWRlZE5hbWVzcGFjZXNDb250ZXh0KCl9LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHB1c2hFeGNsdWRlZE5hbWVzcGFjZXNDb250ZXh0KCkgewotICAgICAgICBpZiAoX2V4Y2x1ZGVkVVJJU3RhY2sgPT0gbnVsbCkgewotICAgICAgICAgICAgX2V4Y2x1ZGVkVVJJU3RhY2sgPSBuZXcgU3RhY2soKTsKLSAgICAgICAgfQotICAgICAgICBfZXhjbHVkZWRVUklTdGFjay5wdXNoKF9leGNsdWRlZFVSSSk7Ci0gICAgICAgIF9leGNsdWRlZFVSSSA9IG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRXhjbHVzaW9uIG9mIG5hbWVzcGFjZXMgYnkgYSBzdHlsZXNoZWV0IGRvZXMgbm90IGV4dGVuZCB0byBhbnkgc3R5bGVzaGVldAotICAgICAqIGltcG9ydGVkIG9yIGluY2x1ZGVkIGJ5IHRoZSBzdHlsZXNoZWV0LiAgVXBvbiBleGl0aW5nIHRoZSBjb250ZXh0IG9mIGEKLSAgICAgKiBzdHlsZXNoZWV0LCBhIGNhbGwgdG8gdGhpcyBtZXRob2QgaXMgbmVlZGVkIHRvIHJlc3RvcmUgdGhlIHNldCBvZgotICAgICAqIGV4Y2x1ZGVkIG5hbWVzcGFjZXMgdGhhdCB3YXMgaW4gZWZmZWN0IHByaW9yIHRvIGVudGVyaW5nIHRoZSBjb250ZXh0IG9mCi0gICAgICogdGhlIGN1cnJlbnQgc3R5bGVzaGVldC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBwb3BFeGNsdWRlZE5hbWVzcGFjZXNDb250ZXh0KCkgewotICAgICAgICBfZXhjbHVkZWRVUkkgPSBfZXhjbHVkZWRVUklTdGFjay5wb3AoKTsKLSAgICAgICAgaWYgKF9leGNsdWRlZFVSSVN0YWNrLmlzRW1wdHkoKSkgewotICAgICAgICAgICAgX2V4Y2x1ZGVkVVJJU3RhY2sgPSBudWxsOwotICAgICAgICB9Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL1N5bnRheFRyZWVOb2RlLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL1N5bnRheFRyZWVOb2RlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAxZWYzOGIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9TeW50YXhUcmVlTm9kZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTAyICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDYsIDIwMTYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKi8KLS8qCi0gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKLSAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAotICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgotICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKLSAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCi0gKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQU5FV0FSUkFZOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQmFzaWNUeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQ0hFQ0tDQVNUOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQ29uc3RhbnRQb29sR2VuOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuRFVQX1gxOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuR0VURklFTEQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JQ09OU1Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JTlZPS0VJTlRFUkZBQ0U7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JTlZPS0VTUEVDSUFMOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFVklSVFVBTDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uTGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLk5FVzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLk5FV0FSUkFZOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuUFVTSDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuRE9NOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkNsYXNzR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkVycm9yTXNnOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLk1ldGhvZEdlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGVDaGVja0Vycm9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlV0aWw7Ci1pbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKLWltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7Ci1pbXBvcnQgamF2YS51dGlsLkxpc3Q7Ci1pbXBvcnQgamF2YS51dGlsLk1hcDsKLWltcG9ydCBvcmcueG1sLnNheC5BdHRyaWJ1dGVzOwotaW1wb3J0IG9yZy54bWwuc2F4LmhlbHBlcnMuQXR0cmlidXRlc0ltcGw7Ci0KLQotLyoqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKiBAYXV0aG9yIEcuIFRvZGQgTWlsbGVyCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JlbnNlbgotICogQGF1dGhvciBFcndpbiBCb2x3aWR0IDxlamJAa2xvbXAub3JnPgotICogQGF1dGhvciBKb2huIEhvd2FyZCA8Sm9obkhAc2NoZW1hc29mdC5jb20+Ci0gKi8KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBTeW50YXhUcmVlTm9kZSBpbXBsZW1lbnRzIENvbnN0YW50cyB7Ci0KLSAgICAvLyBSZWZlcmVuY2UgdG8gdGhlIEFTVCBwYXJzZXIKLSAgICBwcml2YXRlIFBhcnNlciBfcGFyc2VyOwotCi0gICAgLy8gQVNUIG5hdmlnYXRpb24gcG9pbnRlcnMKLSAgICBwcm90ZWN0ZWQgU3ludGF4VHJlZU5vZGUgX3BhcmVudDsgICAgICAgICAgLy8gUGFyZW50IG5vZGUKLSAgICBwcml2YXRlIFN0eWxlc2hlZXQgICAgICAgX3N0eWxlc2hlZXQ7ICAgICAgLy8gU3R5bGVzaGVldCBhbmNlc3RvciBub2RlCi0gICAgcHJpdmF0ZSBUZW1wbGF0ZSAgICAgICAgIF90ZW1wbGF0ZTsgICAgICAgIC8vIFRlbXBsYXRlIGFuY2VzdG9yIG5vZGUKLSAgICBwcml2YXRlIGZpbmFsIExpc3Q8U3ludGF4VHJlZU5vZGU+IF9jb250ZW50cyA9IG5ldyBBcnJheUxpc3Q8PigyKTsgLy8gQ2hpbGQgbm9kZXMKLQotICAgIC8vIEVsZW1lbnQgZGVzY3JpcHRpb24gZGF0YQotICAgIHByb3RlY3RlZCBRTmFtZSBfcW5hbWU7ICAgICAgICAgICAgICAgICAgICAvLyBUaGUgZWxlbWVudCBRTmFtZQotICAgIHByaXZhdGUgaW50IF9saW5lOyAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTb3VyY2UgZmlsZSBsaW5lIG51bWJlcgotICAgIHByb3RlY3RlZCBBdHRyaWJ1dGVzSW1wbCBfYXR0cmlidXRlcyA9IG51bGw7ICAgLy8gQXR0cmlidXRlcyBvZiB0aGlzIGVsZW1lbnQKLSAgICBwcml2YXRlIE1hcDxTdHJpbmcsIFN0cmluZz4gX3ByZWZpeE1hcHBpbmcgPSBudWxsOyAvLyBOYW1lc3BhY2UgZGVjbGFyYXRpb25zCi0KLSAgICAvLyBTZW50aW5lbCAtIHVzZWQgdG8gZGVub3RlIHVucmVjb2duaXNlZCBzeW50YXh0IHRyZWUgbm9kZXMuCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTeW50YXhUcmVlTm9kZSBEdW1teSA9IG5ldyBBYnNvbHV0ZVBhdGhQYXR0ZXJuKG51bGwpOwotCi0gICAgLy8gVGhlc2UgdHdvIGFyZSB1c2VkIGZvciBpbmRlbnRpbmcgbm9kZXMgaW4gdGhlIEFTVCAoZGVidWcgb3V0cHV0KQotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgaW50IEluZGVudEluY3JlbWVudCA9IDQ7Ci0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2hhcltdIF9zcGFjZXMgPQotICAgICAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIudG9DaGFyQXJyYXkoKTsKLQotICAgIC8qKgotICAgICAqIENyZWF0ZXMgYSBuZXcgU3ludGF4VHJlZU5vZGUgd2l0aCBhICdudWxsJyBRTmFtZSBhbmQgbm8gc291cmNlIGZpbGUKLSAgICAgKiBsaW5lIG51bWJlciByZWZlcmVuY2UuCi0gICAgICovCi0gICAgcHVibGljIFN5bnRheFRyZWVOb2RlKCkgewotICAgICAgICBfbGluZSA9IDA7Ci0gICAgICAgIF9xbmFtZSA9IG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlcyBhIG5ldyBTeW50YXhUcmVlTm9kZSB3aXRoIGEgJ251bGwnIFFOYW1lLgotICAgICAqIEBwYXJhbSBsaW5lIFNvdXJjZSBmaWxlIGxpbmUgbnVtYmVyIHJlZmVyZW5jZQotICAgICAqLwotICAgIHB1YmxpYyBTeW50YXhUcmVlTm9kZShpbnQgbGluZSkgewotICAgICAgICBfbGluZSA9IGxpbmU7Ci0gICAgICAgIF9xbmFtZSA9IG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlcyBhIG5ldyBTeW50YXhUcmVlTm9kZSB3aXRoIG5vIHNvdXJjZSBmaWxlIGxpbmUgbnVtYmVyIHJlZmVyZW5jZS4KLSAgICAgKiBAcGFyYW0gdXJpIFRoZSBlbGVtZW50J3MgbmFtZXNwYWNlIFVSSQotICAgICAqIEBwYXJhbSBwcmVmaXggVGhlIGVsZW1lbnQncyBuYW1lc3BhY2UgcHJlZml4Ci0gICAgICogQHBhcmFtIGxvY2FsIFRoZSBlbGVtZW50J3MgbG9jYWwgbmFtZQotICAgICAqLwotICAgIHB1YmxpYyBTeW50YXhUcmVlTm9kZShTdHJpbmcgdXJpLCBTdHJpbmcgcHJlZml4LCBTdHJpbmcgbG9jYWwpIHsKLSAgICAgICAgX2xpbmUgPSAwOwotICAgICAgICBzZXRRTmFtZSh1cmksIHByZWZpeCwgbG9jYWwpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldCB0aGUgc291cmNlIGZpbGUgbGluZSBudW1iZXIgZm9yIHRoaXMgZWxlbWVudAotICAgICAqIEBwYXJhbSBsaW5lIFRoZSBzb3VyY2UgZmlsZSBsaW5lIG51bWJlci4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgZmluYWwgdm9pZCBzZXRMaW5lTnVtYmVyKGludCBsaW5lKSB7Ci0gICAgICAgIF9saW5lID0gbGluZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIHNvdXJjZSBmaWxlIGxpbmUgbnVtYmVyIGZvciB0aGlzIGVsZW1lbnQuIElmIHVuYXZhaWxhYmxlLCBsb29rdXAKLSAgICAgKiBpbiBhbmNlc3RvcnMuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBzb3VyY2UgZmlsZSBsaW5lIG51bWJlci4KLSAgICAgKi8KLSAgICBwdWJsaWMgZmluYWwgaW50IGdldExpbmVOdW1iZXIoKSB7Ci0gICAgICAgIGlmIChfbGluZSA+IDApIHJldHVybiBfbGluZTsKLSAgICAgICAgU3ludGF4VHJlZU5vZGUgcGFyZW50ID0gZ2V0UGFyZW50KCk7Ci0gICAgICAgIHJldHVybiAocGFyZW50ICE9IG51bGwpID8gcGFyZW50LmdldExpbmVOdW1iZXIoKSA6IDA7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSBRTmFtZSBmb3IgdGhlIHN5bnRheCB0cmVlIG5vZGUuCi0gICAgICogQHBhcmFtIHFuYW1lIFRoZSBRTmFtZSBmb3IgdGhlIHN5bnRheCB0cmVlIG5vZGUKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCBzZXRRTmFtZShRTmFtZSBxbmFtZSkgewotICAgICAgICBfcW5hbWUgPSBxbmFtZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIFFOYW1lIGZvciB0aGUgU3ludGF4VHJlZU5vZGUKLSAgICAgKiBAcGFyYW0gdXJpIFRoZSBlbGVtZW50J3MgbmFtZXNwYWNlIFVSSQotICAgICAqIEBwYXJhbSBwcmVmaXggVGhlIGVsZW1lbnQncyBuYW1lc3BhY2UgcHJlZml4Ci0gICAgICogQHBhcmFtIGxvY2FsIFRoZSBlbGVtZW50J3MgbG9jYWwgbmFtZQotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIHNldFFOYW1lKFN0cmluZyB1cmksIFN0cmluZyBwcmVmaXgsIFN0cmluZyBsb2NhbG5hbWUpIHsKLSAgICAgICAgX3FuYW1lID0gbmV3IFFOYW1lKHVyaSwgcHJlZml4LCBsb2NhbG5hbWUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldCB0aGUgUU5hbWUgZm9yIHRoZSBTeW50YXhUcmVlTm9kZQotICAgICAqIEBwYXJhbSBxbmFtZSBUaGUgUU5hbWUgZm9yIHRoZSBzeW50YXggdHJlZSBub2RlCi0gICAgICovCi0gICAgcHJvdGVjdGVkIFFOYW1lIGdldFFOYW1lKCkgewotICAgICAgICByZXR1cm4oX3FuYW1lKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIGF0dHJpYnV0ZXMgZm9yIHRoaXMgU3ludGF4VHJlZU5vZGUuCi0gICAgICogQHBhcmFtIGF0dHJpYnV0ZXMgQXR0cmlidXRlcyBmb3IgdGhlIGVsZW1lbnQuIE11c3QgYmUgcGFzc2VkIGluIGFzIGFuCi0gICAgICogICAgICAgICAgICAgICAgICAgaW1wbGVtZW50YXRpb24gb2Ygb3JnLnhtbC5zYXguQXR0cmlidXRlcy4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCBzZXRBdHRyaWJ1dGVzKEF0dHJpYnV0ZXNJbXBsIGF0dHJpYnV0ZXMpIHsKLSAgICAgICAgX2F0dHJpYnV0ZXMgPSBhdHRyaWJ1dGVzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYSB2YWx1ZSBmb3IgYW4gYXR0cmlidXRlIGZyb20gdGhlIHNvdXJjZSBlbGVtZW50LgotICAgICAqIEBwYXJhbSBxbmFtZSBUaGUgUU5hbWUgb2YgdGhlIGF0dHJpYnV0ZSB0byByZXR1cm4uCi0gICAgICogQHJldHVybiBUaGUgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZSBvZiBuYW1lICdxbmFtZScuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIFN0cmluZyBnZXRBdHRyaWJ1dGUoU3RyaW5nIHFuYW1lKSB7Ci0gICAgICAgIGlmIChfYXR0cmlidXRlcyA9PSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gRU1QVFlTVFJJTkc7Ci0gICAgICAgIH0KLSAgICAgICAgZmluYWwgU3RyaW5nIHZhbHVlID0gX2F0dHJpYnV0ZXMuZ2V0VmFsdWUocW5hbWUpOwotICAgICAgICByZXR1cm4gKHZhbHVlID09IG51bGwgfHwgdmFsdWUuZXF1YWxzKEVNUFRZU1RSSU5HKSkgPwotICAgICAgICAgICAgRU1QVFlTVFJJTkcgOiB2YWx1ZTsKLSAgICB9Ci0KLSAgICBwcm90ZWN0ZWQgU3RyaW5nIGdldEF0dHJpYnV0ZShTdHJpbmcgcHJlZml4LCBTdHJpbmcgbG9jYWxOYW1lKSB7Ci0gICAgICAgIHJldHVybiBnZXRBdHRyaWJ1dGUocHJlZml4ICsgJzonICsgbG9jYWxOYW1lKTsKLSAgICB9Ci0KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBoYXNBdHRyaWJ1dGUoU3RyaW5nIHFuYW1lKSB7Ci0gICAgICAgIHJldHVybiAoX2F0dHJpYnV0ZXMgIT0gbnVsbCAmJiBfYXR0cmlidXRlcy5nZXRWYWx1ZShxbmFtZSkgIT0gbnVsbCk7Ci0gICAgfQotCi0gICAgcHJvdGVjdGVkIHZvaWQgYWRkQXR0cmlidXRlKFN0cmluZyBxbmFtZSwgU3RyaW5nIHZhbHVlKSB7Ci0gICAgICAgIGludCBpbmRleCA9IF9hdHRyaWJ1dGVzLmdldEluZGV4KHFuYW1lKTsKLSAgICAgICAgaWYgKGluZGV4ICE9IC0xKSB7Ci0gICAgICAgICAgICBfYXR0cmlidXRlcy5zZXRBdHRyaWJ1dGUoaW5kZXgsICIiLCBVdGlsLmdldExvY2FsTmFtZShxbmFtZSksCi0gICAgICAgICAgICAgICAgICAgIHFuYW1lLCAiQ0RBVEEiLCB2YWx1ZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBfYXR0cmlidXRlcy5hZGRBdHRyaWJ1dGUoIiIsIFV0aWwuZ2V0TG9jYWxOYW1lKHFuYW1lKSwgcW5hbWUsCi0gICAgICAgICAgICAgICAgICAgICJDREFUQSIsIHZhbHVlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYSBsaXN0IG9mIGFsbCBhdHRyaWJ1dGVzIGRlY2xhcmVkIGZvciB0aGUgZWxlbWVudCByZXByZXNlbnRlZCBieQotICAgICAqIHRoaXMgc3ludGF4IHRyZWUgbm9kZS4KLSAgICAgKiBAcmV0dXJuIEF0dHJpYnV0ZXMgZm9yIHRoaXMgc3ludGF4IHRyZWUgbm9kZQotICAgICAqLwotICAgIHByb3RlY3RlZCBBdHRyaWJ1dGVzIGdldEF0dHJpYnV0ZXMoKSB7Ci0gICAgICAgIHJldHVybihfYXR0cmlidXRlcyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0cyB0aGUgcHJlZml4IG1hcHBpbmcgZm9yIHRoZSBuYW1lc3BhY2VzIHRoYXQgd2VyZSBkZWNsYXJlZCBpbiB0aGlzCi0gICAgICogZWxlbWVudC4gVGhpcyBkb2VzIG5vdCBpbmNsdWRlIGFsbCBwcmVmaXggbWFwcGluZ3MgaW4gc2NvcGUsIHNvIG9uZQotICAgICAqIG1heSBoYXZlIHRvIGNoZWNrIGFuY2VzdG9yIGVsZW1lbnRzIHRvIGdldCBhbGwgbWFwcGluZ3MgdGhhdCBhcmUgaW4KLSAgICAgKiBpbiBzY29wZS4gVGhlIHByZWZpeGVzIG11c3QgYmUgcGFzc2VkIGluIGFzIGEgTWFwIHRoYXQgbWFwcwotICAgICAqIG5hbWVzcGFjZSBwcmVmaXhlcyAoU3RyaW5nIG9iamVjdHMpIHRvIG5hbWVzcGFjZSBVUklzIChhbHNvIFN0cmluZykuCi0gICAgICogQHBhcmFtIG1hcHBpbmcgVGhlIE1hcCBjb250YWluaW5nIHRoZSBtYXBwaW5ncy4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCBzZXRQcmVmaXhNYXBwaW5nKE1hcDxTdHJpbmcsIFN0cmluZz4gbWFwcGluZykgewotICAgICAgICBfcHJlZml4TWFwcGluZyA9IG1hcHBpbmc7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhIE1hcCBjb250YWluaW5nIHRoZSBwcmVmaXggbWFwcGluZ3MgdGhhdCB3ZXJlIGRlY2xhcmVkCi0gICAgICogZm9yIHRoaXMgZWxlbWVudC4gVGhpcyBkb2VzIG5vdCBpbmNsdWRlIGFsbCBwcmVmaXggbWFwcGluZ3MgaW4gc2NvcGUsCi0gICAgICogc28gb25lIG1heSBoYXZlIHRvIGNoZWNrIGFuY2VzdG9yIGVsZW1lbnRzIHRvIGdldCBhbGwgbWFwcGluZ3MgdGhhdCBhcmUKLSAgICAgKiBpbiBpbiBzY29wZS4KLSAgICAgKiBAcmV0dXJuIFByZWZpeCBtYXBwaW5ncyAoZm9yIHRoaXMgZWxlbWVudCBvbmx5KS4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgTWFwPFN0cmluZywgU3RyaW5nPiBnZXRQcmVmaXhNYXBwaW5nKCkgewotICAgICAgICByZXR1cm4gX3ByZWZpeE1hcHBpbmc7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQWRkcyBhIHNpbmdsZSBwcmVmaXggbWFwcGluZyB0byB0aGlzIHN5bnRheCB0cmVlIG5vZGUuCi0gICAgICogQHBhcmFtIHByZWZpeCBOYW1lc3BhY2UgcHJlZml4LgotICAgICAqIEBwYXJhbSB1cmkgTmFtZXNwYWNlIFVSSS4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCBhZGRQcmVmaXhNYXBwaW5nKFN0cmluZyBwcmVmaXgsIFN0cmluZyB1cmkpIHsKLSAgICAgICAgaWYgKF9wcmVmaXhNYXBwaW5nID09IG51bGwpCi0gICAgICAgICAgICBfcHJlZml4TWFwcGluZyA9IG5ldyBIYXNoTWFwPD4oKTsKLSAgICAgICAgX3ByZWZpeE1hcHBpbmcucHV0KHByZWZpeCwgdXJpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGFueSBuYW1lc3BhY2UgVVJJIHRoYXQgaXMgaW4gc2NvcGUgZm9yIGEgZ2l2ZW4gcHJlZml4LiBUaGlzCi0gICAgICogbWV0aG9kIGNoZWNrcyBuYW1lc3BhY2UgbWFwcGluZ3MgZm9yIHRoaXMgZWxlbWVudCwgYW5kIGlmIG5lY2Vzc2FyeQotICAgICAqIGZvciBhbmNlc3RvciBlbGVtZW50cyBhcyB3ZWxsIChpZS4gaWYgdGhlIHByZWZpeCBtYXBzIHRvIGFuIFVSSSBpbiB0aGlzCi0gICAgICogc2NvcGUgdGhlbiB5b3UnbGwgZGVmaW5hdGVseSBnZXQgdGhlIFVSSSBmcm9tIHRoaXMgbWV0aG9kKS4KLSAgICAgKiBAcGFyYW0gcHJlZml4IE5hbWVzcGFjZSBwcmVmaXguCi0gICAgICogQHJldHVybiBOYW1lc3BhY2UgVVJJLgotICAgICAqLwotICAgIHByb3RlY3RlZCBTdHJpbmcgbG9va3VwTmFtZXNwYWNlKFN0cmluZyBwcmVmaXgpIHsKLSAgICAgICAgLy8gSW5pdGlhbGlzZSB0aGUgb3V0cHV0IChkZWZhdWx0IGlzICdudWxsJyBmb3IgdW5kZWZpbmVkKQotICAgICAgICBTdHJpbmcgdXJpID0gbnVsbDsKLQotICAgICAgICAvLyBGaXJzdCBsb29rIHVwIHRoZSBwcmVmaXgvdXJpIG1hcHBpbmcgaW4gb3VyIG93biBtYXAuLi4KLSAgICAgICAgaWYgKF9wcmVmaXhNYXBwaW5nICE9IG51bGwpCi0gICAgICAgICAgICB1cmkgPSBfcHJlZml4TWFwcGluZy5nZXQocHJlZml4KTsKLSAgICAgICAgLy8gLi4uIGJ1dCBpZiB3ZSBjYW4ndCBmaW5kIGl0IHRoZXJlIHdlIGFzayBvdXIgcGFyZW50IGZvciB0aGUgbWFwcGluZwotICAgICAgICBpZiAoKHVyaSA9PSBudWxsKSAmJiAoX3BhcmVudCAhPSBudWxsKSkgewotICAgICAgICAgICAgdXJpID0gX3BhcmVudC5sb29rdXBOYW1lc3BhY2UocHJlZml4KTsKLSAgICAgICAgICAgIGlmICgocHJlZml4ID09IENvbnN0YW50cy5FTVBUWVNUUklORykgJiYgKHVyaSA9PSBudWxsKSkKLSAgICAgICAgICAgICAgICB1cmkgPSBDb25zdGFudHMuRU1QVFlTVFJJTkc7Ci0gICAgICAgIH0KLSAgICAgICAgLy8gLi4uIGFuZCB0aGVuIHdlIHJldHVybiB3aGF0ZXZlciBVUkkgd2UndmUgZ290LgotICAgICAgICByZXR1cm4odXJpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGFueSBuYW1lc3BhY2UgcHJlZml4IHRoYXQgaXMgbWFwcGVkIHRvIGEgcHJlZml4IGluIHRoZSBjdXJyZW50Ci0gICAgICogc2NvcGUuIFRoaXMgbWV0aG9kIGNoZWNrcyBuYW1lc3BhY2UgbWFwcGluZ3MgZm9yIHRoaXMgZWxlbWVudCwgYW5kIGlmCi0gICAgICogbmVjZXNzYXJ5IGZvciBhbmNlc3RvciBlbGVtZW50cyBhcyB3ZWxsIChpZS4gaWYgdGhlIFVSSSBpcyBkZWNsYXJlZAotICAgICAqIHdpdGhpbiB0aGUgY3VycmVudCBzY29wZSB0aGVuIHlvdSdsbCBkZWZpbmF0ZWx5IGdldCB0aGUgcHJlZml4IGZyb20KLSAgICAgKiB0aGlzIG1ldGhvZCkuIE5vdGUgdGhhdCB0aGlzIGlzIGEgdmVyeSBzbG93IG1ldGhvZCBhbmQgY29uc2VxdWVudGlhbGx5Ci0gICAgICogaXQgc2hvdWxkIG9ubHkgYmUgdXNlZCBzdHJpY3RseSB3aGVuIG5lZWRlZC4KLSAgICAgKiBAcGFyYW0gdXJpIE5hbWVzcGFjZSBVUkkuCi0gICAgICogQHJldHVybiBOYW1lc3BhY2UgcHJlZml4LgotICAgICAqLwotICAgIHByb3RlY3RlZCBTdHJpbmcgbG9va3VwUHJlZml4KFN0cmluZyB1cmkpIHsKLSAgICAgICAgLy8gSW5pdGlhbGlzZSB0aGUgb3V0cHV0IChkZWZhdWx0IGlzICdudWxsJyBmb3IgdW5kZWZpbmVkKQotICAgICAgICBTdHJpbmcgcHJlZml4ID0gbnVsbDsKLQotICAgICAgICAvLyBGaXJzdCBsb29rIHVwIHRoZSBwcmVmaXgvdXJpIG1hcHBpbmcgaW4gb3VyIG93biBtYXAuLi4KLSAgICAgICAgaWYgKChfcHJlZml4TWFwcGluZyAhPSBudWxsKSAmJgotICAgICAgICAgICAgKF9wcmVmaXhNYXBwaW5nLmNvbnRhaW5zVmFsdWUodXJpKSkpIHsKLSAgICAgICAgICAgIGZvciAoTWFwLkVudHJ5PFN0cmluZywgU3RyaW5nPiBlbnRyeSA6IF9wcmVmaXhNYXBwaW5nLmVudHJ5U2V0KCkpIHsKLSAgICAgICAgICAgICAgICBwcmVmaXggPSBlbnRyeS5nZXRLZXkoKTsKLSAgICAgICAgICAgICAgICBTdHJpbmcgbWFwc1RvID0gZW50cnkuZ2V0VmFsdWUoKTsKLSAgICAgICAgICAgICAgICBpZiAobWFwc1RvLmVxdWFscyh1cmkpKSByZXR1cm4ocHJlZml4KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICAvLyAuLi4gYnV0IGlmIHdlIGNhbid0IGZpbmQgaXQgdGhlcmUgd2UgYXNrIG91ciBwYXJlbnQgZm9yIHRoZSBtYXBwaW5nCi0gICAgICAgIGVsc2UgaWYgKF9wYXJlbnQgIT0gbnVsbCkgewotICAgICAgICAgICAgcHJlZml4ID0gX3BhcmVudC5sb29rdXBQcmVmaXgodXJpKTsKLSAgICAgICAgICAgIGlmICgodXJpID09IENvbnN0YW50cy5FTVBUWVNUUklORykgJiYgKHByZWZpeCA9PSBudWxsKSkKLSAgICAgICAgICAgICAgICBwcmVmaXggPSBDb25zdGFudHMuRU1QVFlTVFJJTkc7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuKHByZWZpeCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0IHRoaXMgbm9kZSdzIHBhcnNlci4gVGhlIHBhcnNlciAodGhlIFhTTFQgcGFyc2VyKSBnaXZlcyB0aGlzCi0gICAgICogc3ludGF4IHRyZWUgbm9kZSBhY2Nlc3MgdG8gdGhlIHN5bWJvbCB0YWJsZSBhbmQgWFBhdGggcGFyc2VyLgotICAgICAqIEBwYXJhbSBwYXJzZXIgVGhlIFhTTFQgcGFyc2VyLgotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIHNldFBhcnNlcihQYXJzZXIgcGFyc2VyKSB7Ci0gICAgICAgIF9wYXJzZXIgPSBwYXJzZXI7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGlzIG5vZGUncyBYU0xUIHBhcnNlci4KLSAgICAgKiBAcmV0dXJuIFRoZSBYU0xUIHBhcnNlci4KLSAgICAgKi8KLSAgICBwdWJsaWMgZmluYWwgUGFyc2VyIGdldFBhcnNlcigpIHsKLSAgICAgICAgcmV0dXJuIF9wYXJzZXI7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0IHRoaXMgc3ludGF4IHRyZWUgbm9kZSdzIHBhcmVudCBub2RlLCBpZiB1bnNldC4gRm9yCi0gICAgICogcmUtcGFyZW50aW5nIGp1c3QgdXNlIDxjb2RlPm5vZGUuX3BhcmVudCA9IG5ld3BhcmVudDwvY29kZT4uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcGFyZW50IFRoZSBwYXJlbnQgbm9kZS4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCBzZXRQYXJlbnQoU3ludGF4VHJlZU5vZGUgcGFyZW50KSB7Ci0gICAgICAgIGlmIChfcGFyZW50ID09IG51bGwpIF9wYXJlbnQgPSBwYXJlbnQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGlzIHN5bnRheCB0cmVlIG5vZGUncyBwYXJlbnQgbm9kZS4KLSAgICAgKiBAcmV0dXJuIFRoZSBwYXJlbnQgc3ludGF4IHRyZWUgbm9kZS4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgZmluYWwgU3ludGF4VHJlZU5vZGUgZ2V0UGFyZW50KCkgewotICAgICAgICByZXR1cm4gX3BhcmVudDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zICd0cnVlJyBpZiB0aGlzIHN5bnRheCB0cmVlIG5vZGUgaXMgdGhlIFNlbnRpbmFsIG5vZGUuCi0gICAgICogQHJldHVybiAndHJ1ZScgaWYgdGhpcyBzeW50YXggdHJlZSBub2RlIGlzIHRoZSBTZW50aW5hbCBub2RlLgotICAgICAqLwotICAgIHByb3RlY3RlZCBmaW5hbCBib29sZWFuIGlzRHVtbXkoKSB7Ci0gICAgICAgIHJldHVybiB0aGlzID09IER1bW15OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgaW1wb3J0IHByZWNlZGVuY2Ugb2YgdGhpcyBlbGVtZW50LiBUaGUgaW1wb3J0IHByZWNlZGVuY2UgZXF1YWxzCi0gICAgICogdGhlIGltcG9ydCBwcmVjZWRlbmNlIG9mIHRoZSBzdHlsZXNoZWV0IGluIHdoaWNoIHRoaXMgZWxlbWVudCBvY2N1cmVkLgotICAgICAqIEByZXR1cm4gVGhlIGltcG9ydCBwcmVjZWRlbmNlIG9mIHRoaXMgc3ludGF4IHRyZWUgbm9kZS4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgaW50IGdldEltcG9ydFByZWNlZGVuY2UoKSB7Ci0gICAgICAgIFN0eWxlc2hlZXQgc3R5bGVzaGVldCA9IGdldFN0eWxlc2hlZXQoKTsKLSAgICAgICAgaWYgKHN0eWxlc2hlZXQgPT0gbnVsbCkgcmV0dXJuIEludGVnZXIuTUlOX1ZBTFVFOwotICAgICAgICByZXR1cm4gc3R5bGVzaGVldC5nZXRJbXBvcnRQcmVjZWRlbmNlKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBTdHlsZXNoZWV0IG5vZGUgdGhhdCByZXByZXNlbnRzIHRoZSA8eHNsOnN0eWxlc2hlZXQvPiBlbGVtZW50Ci0gICAgICogdGhhdCB0aGlzIG5vZGUgb2NjdXJlZCB1bmRlci4KLSAgICAgKiBAcmV0dXJuIFRoZSBTdHlsZXNoZWV0IGFuY2VzdG9yIG5vZGUgb2YgdGhpcyBub2RlLgotICAgICAqLwotICAgIHB1YmxpYyBTdHlsZXNoZWV0IGdldFN0eWxlc2hlZXQoKSB7Ci0gICAgICAgIGlmIChfc3R5bGVzaGVldCA9PSBudWxsKSB7Ci0gICAgICAgICAgICBTeW50YXhUcmVlTm9kZSBwYXJlbnQgPSB0aGlzOwotICAgICAgICAgICAgd2hpbGUgKHBhcmVudCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgaWYgKHBhcmVudCBpbnN0YW5jZW9mIFN0eWxlc2hlZXQpCi0gICAgICAgICAgICAgICAgICAgIHJldHVybigoU3R5bGVzaGVldClwYXJlbnQpOwotICAgICAgICAgICAgICAgIHBhcmVudCA9IHBhcmVudC5nZXRQYXJlbnQoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIF9zdHlsZXNoZWV0ID0gKFN0eWxlc2hlZXQpcGFyZW50OwotICAgICAgICB9Ci0gICAgICAgIHJldHVybihfc3R5bGVzaGVldCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBUZW1wbGF0ZSBub2RlIHRoYXQgcmVwcmVzZW50cyB0aGUgPHhzbDp0ZW1wbGF0ZS8+IGVsZW1lbnQKLSAgICAgKiB0aGF0IHRoaXMgbm9kZSBvY2N1cmVkIHVuZGVyLiBOb3RlIHRoYXQgdGhpcyBtZXRob2Qgd2lsbCByZXR1cm4gJ251bGwnCi0gICAgICogZm9yIG5vZGVzIHRoYXQgcmVwcmVzZW50IHRvcC1sZXZlbCBlbGVtZW50cy4KLSAgICAgKiBAcmV0dXJuIFRoZSBUZW1wbGF0ZSBhbmNlc3RvciBub2RlIG9mIHRoaXMgbm9kZSBvciAnbnVsbCcuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIFRlbXBsYXRlIGdldFRlbXBsYXRlKCkgewotICAgICAgICBpZiAoX3RlbXBsYXRlID09IG51bGwpIHsKLSAgICAgICAgICAgIFN5bnRheFRyZWVOb2RlIHBhcmVudCA9IHRoaXM7Ci0gICAgICAgICAgICB3aGlsZSAoKHBhcmVudCAhPSBudWxsKSAmJiAoIShwYXJlbnQgaW5zdGFuY2VvZiBUZW1wbGF0ZSkpKQotICAgICAgICAgICAgICAgIHBhcmVudCA9IHBhcmVudC5nZXRQYXJlbnQoKTsKLSAgICAgICAgICAgIF90ZW1wbGF0ZSA9IChUZW1wbGF0ZSlwYXJlbnQ7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuKF90ZW1wbGF0ZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhIHJlZmVyZW5jZSB0byB0aGUgWFNMVEMgKFhTTFQgY29tcGlsZXIpIGluIHVzZS4KLSAgICAgKiBAcmV0dXJuIFhTTFRDIC0gWFNMVCBjb21waWxlci4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgZmluYWwgWFNMVEMgZ2V0WFNMVEMoKSB7Ci0gICAgICAgIHJldHVybiBfcGFyc2VyLmdldFhTTFRDKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgWFNMVCBwYXJzZXIncyBzeW1ib2wgdGFibGUuCi0gICAgICogQHJldHVybiBTeW1ib2wgdGFibGUuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGZpbmFsIFN5bWJvbFRhYmxlIGdldFN5bWJvbFRhYmxlKCkgewotICAgICAgICByZXR1cm4gKF9wYXJzZXIgPT0gbnVsbCkgPyBudWxsIDogX3BhcnNlci5nZXRTeW1ib2xUYWJsZSgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFBhcnNlIHRoZSBjb250ZW50cyBvZiB0aGlzIHN5bnRheCB0cmVlIG5vZGVzIChjaGlsZCBub2RlcywgWFBhdGgKLSAgICAgKiBleHByZXNzaW9ucywgcGF0dGVybnMgYW5kIGZ1bmN0aW9ucykuIFRoZSBkZWZhdWx0IGJlaGF2aW91ciBpcyB0byBwYXJzZXIKLSAgICAgKiB0aGUgc3ludGF4IHRyZWUgbm9kZSdzIGNoaWxkcmVuIChzaW5jZSB0aGVyZSBhcmUgbm8gY29tbW9uIGV4cHJlc3Npb25zLAotICAgICAqIHBhdHRlcm5zLCBldGMuIHRoYXQgY2FuIGJlIGhhbmRsZWQgaW4gdGhpcyBiYXNlIGNsYXNzLgotICAgICAqIEBwYXJhbSBwYXJzZXIgcmVmZXJlbmNlIHRvIHRoZSBYU0xUIHBhcnNlcgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHBhcnNlQ29udGVudHMoUGFyc2VyIHBhcnNlcikgewotICAgICAgICBwYXJzZUNoaWxkcmVuKHBhcnNlcik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUGFyc2UgYWxsIGNoaWxkcmVuIG9mIHRoaXMgc3ludGF4IHRyZWUgbm9kZS4gVGhpcyBtZXRob2QgaXMgbm9ybWFsbHkKLSAgICAgKiBjYWxsZWQgYnkgdGhlIHBhcnNlQ29udGVudHMoKSBtZXRob2QuCi0gICAgICogQHBhcmFtIHBhcnNlciByZWZlcmVuY2UgdG8gdGhlIFhTTFQgcGFyc2VyCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGZpbmFsIHZvaWQgcGFyc2VDaGlsZHJlbihQYXJzZXIgcGFyc2VyKSB7Ci0KLSAgICAgICAgTGlzdDxRTmFtZT4gbG9jYWxzID0gbnVsbDsgICAvLyBvbmx5IGNyZWF0ZSB3aGVuIG5lZWRlZAotCi0gICAgICAgIGZvciAoU3ludGF4VHJlZU5vZGUgY2hpbGQgOiBfY29udGVudHMpIHsKLSAgICAgICAgICAgIHBhcnNlci5nZXRTeW1ib2xUYWJsZSgpLnNldEN1cnJlbnROb2RlKGNoaWxkKTsKLSAgICAgICAgICAgIGNoaWxkLnBhcnNlQ29udGVudHMocGFyc2VyKTsKLSAgICAgICAgICAgIC8vIGlmIHZhcmlhYmxlIG9yIHBhcmFtZXRlciwgYWRkIGl0IHRvIHNjb3BlCi0gICAgICAgICAgICBmaW5hbCBRTmFtZSB2YXJPclBhcmFtTmFtZSA9IHVwZGF0ZVNjb3BlKHBhcnNlciwgY2hpbGQpOwotICAgICAgICAgICAgaWYgKHZhck9yUGFyYW1OYW1lICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBpZiAobG9jYWxzID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgbG9jYWxzID0gbmV3IEFycmF5TGlzdDw+KDIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBsb2NhbHMuYWRkKHZhck9yUGFyYW1OYW1lKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHBhcnNlci5nZXRTeW1ib2xUYWJsZSgpLnNldEN1cnJlbnROb2RlKHRoaXMpOwotCi0gICAgICAgIC8vIGFmdGVyIHRoZSBsYXN0IGVsZW1lbnQsIHJlbW92ZSBhbnkgbG9jYWxzIGZyb20gc2NvcGUKLSAgICAgICAgaWYgKGxvY2FscyAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmb3IgKFFOYW1lIHZhck9yUGFyYW1OYW1lIDogbG9jYWxzKSB7Ci0gICAgICAgICAgICAgICAgcGFyc2VyLnJlbW92ZVZhcmlhYmxlKHZhck9yUGFyYW1OYW1lKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEFkZCBhIG5vZGUgdG8gdGhlIGN1cnJlbnQgc2NvcGUgYW5kIHJldHVybiBuYW1lIG9mIGEgdmFyaWFibGUgb3IKLSAgICAgKiBwYXJhbWV0ZXIgaWYgdGhlIG5vZGUgcmVwcmVzZW50cyBhIHZhcmlhYmxlIG9yIGEgcGFyYW1ldGVyLgotICAgICAqLwotICAgIHByb3RlY3RlZCBRTmFtZSB1cGRhdGVTY29wZShQYXJzZXIgcGFyc2VyLCBTeW50YXhUcmVlTm9kZSBub2RlKSB7Ci0gICAgICAgIGlmIChub2RlIGluc3RhbmNlb2YgVmFyaWFibGUpIHsKLSAgICAgICAgICAgIGZpbmFsIFZhcmlhYmxlIHZhciA9IChWYXJpYWJsZSlub2RlOwotICAgICAgICAgICAgcGFyc2VyLmFkZFZhcmlhYmxlKHZhcik7Ci0gICAgICAgICAgICByZXR1cm4gdmFyLmdldE5hbWUoKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChub2RlIGluc3RhbmNlb2YgUGFyYW0pIHsKLSAgICAgICAgICAgIGZpbmFsIFBhcmFtIHBhcmFtID0gKFBhcmFtKW5vZGU7Ci0gICAgICAgICAgICBwYXJzZXIuYWRkUGFyYW1ldGVyKHBhcmFtKTsKLSAgICAgICAgICAgIHJldHVybiBwYXJhbS5nZXROYW1lKCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFR5cGUgY2hlY2sgdGhlIGNoaWxkcmVuIG9mIHRoaXMgbm9kZS4gVGhlIHR5cGUgY2hlY2sgcGhhc2UgbWF5IGFkZAotICAgICAqIGNvZXJjaW9ucyAoQ2FzdEV4cHIpIHRvIHRoZSBBU1QuCi0gICAgICogQHBhcmFtIHN0YWJsZSBUaGUgY29tcGlsZXIvcGFyc2VyJ3Mgc3ltYm9sIHRhYmxlCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yOwotCi0gICAgLyoqCi0gICAgICogQ2FsbCB0eXBlQ2hlY2soKSBvbiBhbGwgY2hpbGQgc3ludGF4IHRyZWUgbm9kZXMuCi0gICAgICogQHBhcmFtIHN0YWJsZSBUaGUgY29tcGlsZXIvcGFyc2VyJ3Mgc3ltYm9sIHRhYmxlCi0gICAgICovCi0gICAgcHJvdGVjdGVkIFR5cGUgdHlwZUNoZWNrQ29udGVudHMoU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgewotICAgICAgICBmb3IgKFN5bnRheFRyZWVOb2RlIGl0ZW0gOiBfY29udGVudHMpIHsKLSAgICAgICAgICAgIGl0ZW0udHlwZUNoZWNrKHN0YWJsZSk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIFR5cGUuVm9pZDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGUgdGhpcyBhYnN0cmFjdCBzeW50YXggdHJlZSBub2RlIGludG8gSlZNIGJ5dGVjb2Rlcy4KLSAgICAgKiBAcGFyYW0gY2xhc3NHZW4gQkNFTCBKYXZhIGNsYXNzIGdlbmVyYXRvcgotICAgICAqIEBwYXJhbSBtZXRob2RHZW4gQkNFTCBKYXZhIG1ldGhvZCBnZW5lcmF0b3IKLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pOwotCi0gICAgLyoqCi0gICAgICogQ2FsbCB0cmFuc2xhdGUoKSBvbiBhbGwgY2hpbGQgc3ludGF4IHRyZWUgbm9kZXMuCi0gICAgICogQHBhcmFtIGNsYXNzR2VuIEJDRUwgSmF2YSBjbGFzcyBnZW5lcmF0b3IKLSAgICAgKiBAcGFyYW0gbWV0aG9kR2VuIEJDRUwgSmF2YSBtZXRob2QgZ2VuZXJhdG9yCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgdHJhbnNsYXRlQ29udGVudHMoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotICAgICAgICAvLyBDYWxsIHRyYW5zbGF0ZSgpIG9uIGFsbCBjaGlsZCBub2RlcwotICAgICAgICBmaW5hbCBpbnQgbiA9IGVsZW1lbnRDb3VudCgpOwotCi0gICAgICAgIGZvciAoU3ludGF4VHJlZU5vZGUgaXRlbSA6IF9jb250ZW50cykgewotICAgICAgICAgICAgbWV0aG9kR2VuLm1hcmtDaHVua1N0YXJ0KCk7Ci0gICAgICAgICAgICBpdGVtLnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgICAgIG1ldGhvZEdlbi5tYXJrQ2h1bmtFbmQoKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIEFmdGVyIHRyYW5zbGF0aW9uLCB1bm1hcCBhbnkgcmVnaXN0ZXJzIGZvciBhbnkgdmFyaWFibGVzL3BhcmFtZXRlcnMKLSAgICAgICAgLy8gdGhhdCB3ZXJlIGRlY2xhcmVkIGluIHRoaXMgc2NvcGUuIFBlcmZvcm1pbmcgdGhpcyB1bm1hcHBpbmcgaW4gdGhlCi0gICAgICAgIC8vIHNhbWUgQVNUIHNjb3BlIGFzIHRoZSBkZWNsYXJhdGlvbiBkZWFscyB3aXRoIHRoZSBwcm9ibGVtcyBvZgotICAgICAgICAvLyByZWZlcmVuY2VzIGZhbGxpbmcgb3V0LW9mLXNjb3BlIGluc2lkZSB0aGUgZm9yLWVhY2ggZWxlbWVudC4KLSAgICAgICAgLy8gKHRoZSBjYXVzZSBvZiB3aGljaCBiZWluZyAnbGF6eScgcmVnaXN0ZXIgYWxsb2NhdGlvbiBmb3IgcmVmZXJlbmNlcykKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspIHsKLSAgICAgICAgICAgIGlmICggX2NvbnRlbnRzLmdldChpKSBpbnN0YW5jZW9mIFZhcmlhYmxlQmFzZSkgewotICAgICAgICAgICAgICAgIGZpbmFsIFZhcmlhYmxlQmFzZSB2YXIgPSAoVmFyaWFibGVCYXNlKV9jb250ZW50cy5nZXQoaSk7Ci0gICAgICAgICAgICAgICAgdmFyLnVubWFwUmVnaXN0ZXIoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdHJ1ZSBpZiB0aGUgbm9kZSByZXByZXNlbnRzIGEgc2ltcGxlIFJURi4KLSAgICAgKgotICAgICAqIEEgbm9kZSBpcyBhIHNpbXBsZSBSVEYgaWYgYWxsIGNoaWxkcmVuIG9ubHkgcHJvZHVjZSBUZXh0IHZhbHVlLgotICAgICAqCi0gICAgICogQHBhcmFtIG5vZGUgQSBub2RlCi0gICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBub2RlIGNvbnRlbnQgY2FuIGJlIGNvbnNpZGVyZWQgYXMgYSBzaW1wbGUgUlRGLgotICAgICAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBpc1NpbXBsZVJURihTeW50YXhUcmVlTm9kZSBub2RlKSB7Ci0KLSAgICAgICAgTGlzdDxTeW50YXhUcmVlTm9kZT4gY29udGVudHMgPSBub2RlLmdldENvbnRlbnRzKCk7Ci0gICAgICAgIGZvciAoU3ludGF4VHJlZU5vZGUgaXRlbSA6IGNvbnRlbnRzKSB7Ci0gICAgICAgICAgICBpZiAoIWlzVGV4dEVsZW1lbnQoaXRlbSwgZmFsc2UpKQotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotICAgICAvKioKLSAgICAgKiBSZXR1cm4gdHJ1ZSBpZiB0aGUgbm9kZSByZXByZXNlbnRzIGFuIGFkYXB0aXZlIFJURi4KLSAgICAgKgotICAgICAqIEEgbm9kZSBpcyBhbiBhZGFwdGl2ZSBSVEYgaWYgZWFjaCBjaGlsZHJlbiBpcyBhIFRleHQgZWxlbWVudAotICAgICAqIG9yIGl0IGlzIDx4c2w6Y2FsbC10ZW1wbGF0ZT4gb3IgPHhzbDphcHBseS10ZW1wbGF0ZXM+LgotICAgICAqCi0gICAgICogQHBhcmFtIG5vZGUgQSBub2RlCi0gICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBub2RlIGNvbnRlbnQgY2FuIGJlIGNvbnNpZGVyZWQgYXMgYW4gYWRhcHRpdmUgUlRGLgotICAgICAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBpc0FkYXB0aXZlUlRGKFN5bnRheFRyZWVOb2RlIG5vZGUpIHsKLQotICAgICAgICBMaXN0PFN5bnRheFRyZWVOb2RlPiBjb250ZW50cyA9IG5vZGUuZ2V0Q29udGVudHMoKTsKLSAgICAgICAgZm9yIChTeW50YXhUcmVlTm9kZSBpdGVtIDogY29udGVudHMpIHsKLSAgICAgICAgICAgIGlmICghaXNUZXh0RWxlbWVudChpdGVtLCB0cnVlKSkKLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdHJ1ZSBpZiB0aGUgbm9kZSBvbmx5IHByb2R1Y2VzIFRleHQgY29udGVudC4KLSAgICAgKgotICAgICAqIEEgbm9kZSBpcyBhIFRleHQgZWxlbWVudCBpZiBpdCBpcyBUZXh0LCB4c2w6dmFsdWUtb2YsIHhzbDpudW1iZXIsCi0gICAgICogb3IgYSBjb21iaW5hdGlvbiBvZiB0aGVzZSBuZXN0ZWQgaW4gYSBjb250cm9sIGluc3RydWN0aW9uICh4c2w6aWYgb3IKLSAgICAgKiB4c2w6Y2hvb3NlKS4KLSAgICAgKgotICAgICAqIElmIHRoZSBkb0V4dGVuZGVkQ2hlY2sgZmxhZyBpcyB0cnVlLCB4c2w6Y2FsbC10ZW1wbGF0ZSBhbmQgeHNsOmFwcGx5LXRlbXBsYXRlcwotICAgICAqIGFyZSBhbHNvIGNvbnNpZGVyZWQgYXMgVGV4dCBlbGVtZW50cy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBub2RlIEEgbm9kZQotICAgICAqIEBwYXJhbSBkb0V4dGVuZGVkQ2hlY2sgSWYgdGhpcyBmbGFnIGlzIHRydWUsIDx4c2w6Y2FsbC10ZW1wbGF0ZT4gYW5kCi0gICAgICogPHhzbDphcHBseS10ZW1wbGF0ZXM+IGFyZSBhbHNvIGNvbnNpZGVyZWQgYXMgVGV4dCBlbGVtZW50cy4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgbm9kZSBvZiBUZXh0IHR5cGUKLSAgICAgKi8KLSAgICBwcml2YXRlIGJvb2xlYW4gaXNUZXh0RWxlbWVudChTeW50YXhUcmVlTm9kZSBub2RlLCBib29sZWFuIGRvRXh0ZW5kZWRDaGVjaykgewotICAgICAgICBpZiAobm9kZSBpbnN0YW5jZW9mIFZhbHVlT2YgfHwgbm9kZSBpbnN0YW5jZW9mIE51bWJlcgotICAgICAgICAgICAgfHwgbm9kZSBpbnN0YW5jZW9mIFRleHQpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKG5vZGUgaW5zdGFuY2VvZiBJZikgewotICAgICAgICAgICAgcmV0dXJuIGRvRXh0ZW5kZWRDaGVjayA/IGlzQWRhcHRpdmVSVEYobm9kZSkgOiBpc1NpbXBsZVJURihub2RlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChub2RlIGluc3RhbmNlb2YgQ2hvb3NlKSB7Ci0gICAgICAgICAgICBMaXN0PFN5bnRheFRyZWVOb2RlPiBjb250ZW50cyA9IG5vZGUuZ2V0Q29udGVudHMoKTsKLSAgICAgICAgICAgIGZvciAoU3ludGF4VHJlZU5vZGUgaXRlbSA6IGNvbnRlbnRzKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGl0ZW0gaW5zdGFuY2VvZiBUZXh0IHx8Ci0gICAgICAgICAgICAgICAgICAgICAoKGl0ZW0gaW5zdGFuY2VvZiBXaGVuIHx8IGl0ZW0gaW5zdGFuY2VvZiBPdGhlcndpc2UpCi0gICAgICAgICAgICAgICAgICAgICAmJiAoKGRvRXh0ZW5kZWRDaGVjayAmJiBpc0FkYXB0aXZlUlRGKGl0ZW0pKQotICAgICAgICAgICAgICAgICAgICAgICAgIHx8ICghZG9FeHRlbmRlZENoZWNrICYmIGlzU2ltcGxlUlRGKGl0ZW0pKSkpKQotICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKGRvRXh0ZW5kZWRDaGVjayAmJgotICAgICAgICAgICAgICAgICAgKG5vZGUgaW5zdGFuY2VvZiBDYWxsVGVtcGxhdGUKLSAgICAgICAgICAgICAgICAgICB8fCBub2RlIGluc3RhbmNlb2YgQXBwbHlUZW1wbGF0ZXMpKQotICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBVdGlsaXR5IG1ldGhvZCB1c2VkIGJ5IHBhcmFtZXRlcnMgYW5kIHZhcmlhYmxlcyB0byBzdG9yZSByZXN1bHQgdHJlZXMKLSAgICAgKiBAcGFyYW0gY2xhc3NHZW4gQkNFTCBKYXZhIGNsYXNzIGdlbmVyYXRvcgotICAgICAqIEBwYXJhbSBtZXRob2RHZW4gQkNFTCBKYXZhIG1ldGhvZCBnZW5lcmF0b3IKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCBjb21waWxlUmVzdWx0VHJlZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKQotICAgIHsKLSAgICAgICAgZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0gICAgICAgIGZpbmFsIFN0eWxlc2hlZXQgc3R5bGVzaGVldCA9IGNsYXNzR2VuLmdldFN0eWxlc2hlZXQoKTsKLQotICAgICAgICBib29sZWFuIGlzU2ltcGxlID0gaXNTaW1wbGVSVEYodGhpcyk7Ci0gICAgICAgIGJvb2xlYW4gaXNBZGFwdGl2ZSA9IGZhbHNlOwotICAgICAgICBpZiAoIWlzU2ltcGxlKSB7Ci0gICAgICAgICAgICBpc0FkYXB0aXZlID0gaXNBZGFwdGl2ZVJURih0aGlzKTsKLSAgICAgICAgfQotCi0gICAgICAgIGludCBydGZUeXBlID0gaXNTaW1wbGUgPyBET00uU0lNUExFX1JURgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogKGlzQWRhcHRpdmUgPyBET00uQURBUFRJVkVfUlRGIDogRE9NLlRSRUVfUlRGKTsKLQotICAgICAgICAvLyBTYXZlIHRoZSBjdXJyZW50IGhhbmRsZXIgYmFzZSBvbiB0aGUgc3RhY2sKLSAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkSGFuZGxlcigpKTsKLQotICAgICAgICBmaW5hbCBTdHJpbmcgRE9NX0NMQVNTID0gY2xhc3NHZW4uZ2V0RE9NQ2xhc3MoKTsKLQotICAgICAgICAvLyBDcmVhdGUgbmV3IGluc3RhbmNlIG9mIERPTSBjbGFzcyAod2l0aCBSVEZfSU5JVElBTF9TSVpFIG5vZGVzKQotICAgICAgICAvL2ludCBpbmRleCA9IGNwZy5hZGRNZXRob2RyZWYoRE9NX0lNUEwsICI8aW5pdD4iLCAiKEkpViIpOwotICAgICAgICAvL2lsLmFwcGVuZChuZXcgTkVXKGNwZy5hZGRDbGFzcyhET01fSU1QTCkpKTsKLQotICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0gICAgICAgIGludCBpbmRleCA9IGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoRE9NX0lOVEYsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZ2V0UmVzdWx0VHJlZUZyYWciLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIihJSVopIiArIERPTV9JTlRGX1NJRyk7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsIFJURl9JTklUSUFMX1NJWkUpKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgcnRmVHlwZSkpOwotICAgICAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBzdHlsZXNoZWV0LmNhbGxzTm9kZXNldCgpKSk7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFSU5URVJGQUNFKGluZGV4LDQpKTsKLQotICAgICAgICBpbC5hcHBlbmQoRFVQKTsKLQotICAgICAgICAvLyBPdmVyd3JpdGUgb2xkIGhhbmRsZXIgd2l0aCBET00gaGFuZGxlcgotICAgICAgICBpbmRleCA9IGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoRE9NX0lOVEYsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZ2V0T3V0cHV0RG9tQnVpbGRlciIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKCkiICsgVFJBTlNMRVRfT1VUUFVUX1NJRyk7Ci0KLSAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0UoaW5kZXgsMSkpOwotICAgICAgICBpbC5hcHBlbmQoRFVQKTsKLSAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5zdG9yZUhhbmRsZXIoKSk7Ci0KLSAgICAgICAgLy8gQ2FsbCBzdGFydERvY3VtZW50IG9uIHRoZSBuZXcgaGFuZGxlcgotICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLnN0YXJ0RG9jdW1lbnQoKSk7Ci0KLSAgICAgICAgLy8gSW5zdGFudGlhdGUgcmVzdWx0IHRyZWUgZnJhZ21lbnQKLSAgICAgICAgdHJhbnNsYXRlQ29udGVudHMoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0KLSAgICAgICAgLy8gQ2FsbCBlbmREb2N1bWVudCBvbiB0aGUgbmV3IGhhbmRsZXIKLSAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkSGFuZGxlcigpKTsKLSAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5lbmREb2N1bWVudCgpKTsKLQotICAgICAgICAvLyBDaGVjayBpZiB3ZSBuZWVkIHRvIHdyYXAgdGhlIERPTUltcGwgb2JqZWN0IGluIGEgRE9NQWRhcHRlciBvYmplY3QuCi0gICAgICAgIC8vIERPTUFkYXB0ZXIgaXMgbm90IG5lZWRlZCBpZiB0aGUgUlRGIGlzIGEgc2ltcGxlIFJURiBhbmQgdGhlIG5vZGVzZXQoKQotICAgICAgICAvLyBmdW5jdGlvbiBpcyBub3QgdXNlZC4KLSAgICAgICAgaWYgKHN0eWxlc2hlZXQuY2FsbHNOb2Rlc2V0KCkKLSAgICAgICAgICAgICYmICFET01fQ0xBU1MuZXF1YWxzKERPTV9JTVBMX0NMQVNTKSkgewotICAgICAgICAgICAgLy8gbmV3IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5kb20uRE9NQWRhcHRlcihET01JbXBsLFN0cmluZ1tdKTsKLSAgICAgICAgICAgIGluZGV4ID0gY3BnLmFkZE1ldGhvZHJlZihET01fQURBUFRFUl9DTEFTUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiPGluaXQ+IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKCIrRE9NX0lOVEZfU0lHKwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJbIitTVFJJTkdfU0lHKwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJbIitTVFJJTkdfU0lHKwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJbSSIrCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlsiK1NUUklOR19TSUcrIilWIik7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IE5FVyhjcGcuYWRkQ2xhc3MoRE9NX0FEQVBURVJfQ0xBU1MpKSk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IERVUF9YMSgpKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChTV0FQKTsKLQotICAgICAgICAgICAgLyoKLSAgICAgICAgICAgICAqIEdpdmUgdGhlIERPTSBhZGFwdGVyIGFuIGVtcHR5IHR5cGUgbWFwcGluZyBpZiB0aGUgbm9kZXNldAotICAgICAgICAgICAgICogZXh0ZW5zaW9uIGZ1bmN0aW9uIGlzIG5ldmVyIGNhbGxlZC4KLSAgICAgICAgICAgICAqLwotICAgICAgICAgICAgaWYgKCFzdHlsZXNoZWV0LmNhbGxzTm9kZXNldCgpKSB7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJQ09OU1QoMCkpOwotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgQU5FV0FSUkFZKGNwZy5hZGRDbGFzcyhTVFJJTkcpKSk7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKERVUCk7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKERVUCk7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJQ09OU1QoMCkpOwotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgTkVXQVJSQVkoQmFzaWNUeXBlLklOVCkpOwotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChTV0FQKTsKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRVNQRUNJQUwoaW5kZXgpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIC8vIFB1c2ggbmFtZSBhcnJheXMgb24gdGhlIHN0YWNrCi0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKEFMT0FEXzApOwotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgR0VURklFTEQoY3BnLmFkZEZpZWxkcmVmKFRSQU5TTEVUX0NMQVNTLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5BTUVTX0lOREVYLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5BTUVTX0lOREVYX1NJRykpKTsKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQoQUxPQURfMCk7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBHRVRGSUVMRChjcGcuYWRkRmllbGRyZWYoVFJBTlNMRVRfQ0xBU1MsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVVJJU19JTkRFWCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVUklTX0lOREVYX1NJRykpKTsKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQoQUxPQURfMCk7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBHRVRGSUVMRChjcGcuYWRkRmllbGRyZWYoVFJBTlNMRVRfQ0xBU1MsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVFlQRVNfSU5ERVgsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVFlQRVNfSU5ERVhfU0lHKSkpOwotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChBTE9BRF8wKTsKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQobmV3IEdFVEZJRUxEKGNwZy5hZGRGaWVsZHJlZihUUkFOU0xFVF9DTEFTUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOQU1FU1BBQ0VfSU5ERVgsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkFNRVNQQUNFX0lOREVYX1NJRykpKTsKLQotICAgICAgICAgICAgICAgIC8vIEluaXRpYWxpemVkIERPTSBhZGFwdGVyCi0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VTUEVDSUFMKGluZGV4KSk7Ci0KLSAgICAgICAgICAgICAgICAvLyBBZGQgRE9NIGFkYXB0ZXIgdG8gTXVsdGlET00gY2xhc3MgYnkgY2FsbGluZyBhZGRET01BZGFwdGVyKCkKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQoRFVQKTsKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBDSEVDS0NBU1QoY3BnLmFkZENsYXNzKGNsYXNzR2VuLmdldERPTUNsYXNzKCkpKSk7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKFNXQVApOwotICAgICAgICAgICAgICAgIGluZGV4ID0gY3BnLmFkZE1ldGhvZHJlZihNVUxUSV9ET01fQ0xBU1MsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJhZGRET01BZGFwdGVyIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIigiICsgRE9NX0FEQVBURVJfU0lHICsgIilJIik7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VWSVJUVUFMKGluZGV4KSk7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKFBPUCk7ICAgICAgICAgLy8gaWdub3JlIG1hc2sgcmV0dXJuZWQgYnkgYWRkRE9NQWRhcHRlcgotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gUmVzdG9yZSBvbGQgaGFuZGxlciBiYXNlIGZyb20gc3RhY2sKLSAgICAgICAgaWwuYXBwZW5kKFNXQVApOwotICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLnN0b3JlSGFuZGxlcigpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhpcyBleHByZXNzaW9uL2luc3RydWN0aW9uIGRlcGVuZHMgb24gdGhlIGNvbnRleHQuIEJ5Ci0gICAgICogZGVmYXVsdCwgZXZlcnkgZXhwcmVzc2lvbi9pbnN0cnVjdGlvbiBkZXBlbmRzIG9uIHRoZSBjb250ZXh0IHVubGVzcyBpdAotICAgICAqIG92ZXJyaWRlcyB0aGlzIG1ldGhvZC4gQ3VycmVudGx5IHVzZWQgdG8gZGV0ZXJtaW5lIGlmIHJlc3VsdCB0cmVlcyBhcmUKLSAgICAgKiBjb21waWxlZCB1c2luZyBwcm9jZWR1cmVzIG9yIGxpdHRsZSBET01zIChyZXN1bHQgdHJlZSBmcmFnbWVudHMpLgotICAgICAqIEByZXR1cm4gJ3RydWUnIGlmIHRoaXMgbm9kZSBkZXBlbmRzIG9uIHRoZSBjb250ZXh0LgotICAgICAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIGNvbnRleHREZXBlbmRlbnQoKSB7Ci0gICAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybiB0cnVlIGlmIGFueSBvZiB0aGUgZXhwcmVzc2lvbnMvaW5zdHJ1Y3Rpb25zIGluIHRoZSBjb250ZW50cyBvZgotICAgICAqIHRoaXMgbm9kZSBpcyBjb250ZXh0IGRlcGVuZGVudC4KLSAgICAgKiBAcmV0dXJuICd0cnVlJyBpZiB0aGUgY29udGVudHMgb2YgdGhpcyBub2RlIGlzIGNvbnRleHQgZGVwZW5kZW50LgotICAgICAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIGRlcGVuZGVudENvbnRlbnRzKCkgewotICAgICAgICBmb3IgKFN5bnRheFRyZWVOb2RlIGl0ZW0gOiBfY29udGVudHMpIHsKLSAgICAgICAgICAgIGlmIChpdGVtLmNvbnRleHREZXBlbmRlbnQoKSkgewotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBZGRzIGEgY2hpbGQgbm9kZSB0byB0aGlzIHN5bnRheCB0cmVlIG5vZGUuCi0gICAgICogQHBhcmFtIGVsZW1lbnQgaXMgdGhlIG5ldyBjaGlsZCBub2RlLgotICAgICAqLwotICAgIHByb3RlY3RlZCBmaW5hbCB2b2lkIGFkZEVsZW1lbnQoU3ludGF4VHJlZU5vZGUgZWxlbWVudCkgewotICAgICAgICBfY29udGVudHMuYWRkKGVsZW1lbnQpOwotICAgICAgICBlbGVtZW50LnNldFBhcmVudCh0aGlzKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJbnNlcnRzIHRoZSBmaXJzdCBjaGlsZCBub2RlIG9mIHRoaXMgc3ludGF4IHRyZWUgbm9kZS4gVGhlIGV4aXN0aW5nCi0gICAgICogY2hpbGRyZW4gYXJlIHNoaWZ0ZWQgYmFjayBvbmUgcG9zaXRpb24uCi0gICAgICogQHBhcmFtIGVsZW1lbnQgaXMgdGhlIG5ldyBjaGlsZCBub2RlLgotICAgICAqLwotICAgIHByb3RlY3RlZCBmaW5hbCB2b2lkIHNldEZpcnN0RWxlbWVudChTeW50YXhUcmVlTm9kZSBlbGVtZW50KSB7Ci0gICAgICAgIF9jb250ZW50cy5hZGQoMCwgZWxlbWVudCk7Ci0gICAgICAgIGVsZW1lbnQuc2V0UGFyZW50KHRoaXMpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJlbW92ZWQgYSBjaGlsZCBub2RlIG9mIHRoaXMgc3ludGF4IHRyZWUgbm9kZS4KLSAgICAgKiBAcGFyYW0gZWxlbWVudCBpcyB0aGUgY2hpbGQgbm9kZSB0byByZW1vdmUuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGZpbmFsIHZvaWQgcmVtb3ZlRWxlbWVudChTeW50YXhUcmVlTm9kZSBlbGVtZW50KSB7Ci0gICAgICAgIF9jb250ZW50cy5yZW1vdmUoZWxlbWVudCk7Ci0gICAgICAgIGVsZW1lbnQuc2V0UGFyZW50KG51bGwpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYSBMaXN0IGNvbnRhaW5pbmcgYWxsIHRoZSBjaGlsZCBub2RlcyBvZiB0aGlzIG5vZGUuCi0gICAgICogQHJldHVybiBBIExpc3QgY29udGFpbmluZyBhbGwgdGhlIGNoaWxkIG5vZGVzIG9mIHRoaXMgbm9kZS4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgZmluYWwgTGlzdDxTeW50YXhUcmVlTm9kZT4gZ2V0Q29udGVudHMoKSB7Ci0gICAgICAgIHJldHVybiBfY29udGVudHM7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGVsbHMgeW91IGlmIHRoaXMgbm9kZSBoYXMgYW55IGNoaWxkIG5vZGVzLgotICAgICAqIEByZXR1cm4gJ3RydWUnIGlmIHRoaXMgbm9kZSBoYXMgYW55IGNoaWxkcmVuLgotICAgICAqLwotICAgIHByb3RlY3RlZCBmaW5hbCBib29sZWFuIGhhc0NvbnRlbnRzKCkgewotICAgICAgICByZXR1cm4gZWxlbWVudENvdW50KCkgPiAwOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIG51bWJlciBvZiBjaGlsZHJlbiB0aGlzIG5vZGUgaGFzLgotICAgICAqIEByZXR1cm4gTnVtYmVyIG9mIGNoaWxkIG5vZGVzLgotICAgICAqLwotICAgIHByb3RlY3RlZCBmaW5hbCBpbnQgZWxlbWVudENvdW50KCkgewotICAgICAgICByZXR1cm4gX2NvbnRlbnRzLnNpemUoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGFuIEl0ZXJhdG9yIG9mIGFsbCBjaGlsZCBub2RlcyBvZiB0aGlzIG5vZGUuCi0gICAgICogQHJldHVybiBBbiBJdGVyYXRvciBvZiBhbGwgY2hpbGQgbm9kZXMgb2YgdGhpcyBub2RlLgotICAgICAqLwotICAgIHByb3RlY3RlZCBmaW5hbCBJdGVyYXRvcjxTeW50YXhUcmVlTm9kZT4gZWxlbWVudHMoKSB7Ci0gICAgICAgIHJldHVybiBfY29udGVudHMuaXRlcmF0b3IoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGEgY2hpbGQgbm9kZSBhdCBhIGdpdmVuIHBvc2l0aW9uLgotICAgICAqIEBwYXJhbSBwb3MgVGhlIGNoaWxkIG5vZGUncyBwb3NpdGlvbi4KLSAgICAgKiBAcmV0dXJuIFRoZSBjaGlsZCBub2RlLgotICAgICAqLwotICAgIHByb3RlY3RlZCBmaW5hbCBTeW50YXhUcmVlTm9kZSBlbGVtZW50QXQoaW50IHBvcykgewotICAgICAgICByZXR1cm4gX2NvbnRlbnRzLmdldChwb3MpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhpcyBlbGVtZW50J3MgbGFzdCBjaGlsZAotICAgICAqIEByZXR1cm4gVGhlIGNoaWxkIG5vZGUuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGZpbmFsIFN5bnRheFRyZWVOb2RlIGxhc3RDaGlsZCgpIHsKLSAgICAgICAgaWYgKF9jb250ZW50cy5pc0VtcHR5KCkpIHJldHVybiBudWxsOwotICAgICAgICByZXR1cm4gX2NvbnRlbnRzLmdldChfY29udGVudHMuc2l6ZSgpIC0gMSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRGlzcGxheXMgdGhlIGNvbnRlbnRzIG9mIHRoaXMgc3ludGF4IHRyZWUgbm9kZSAodG8gc3Rkb3V0KS4KLSAgICAgKiBUaGlzIG1ldGhvZCBpcyBpbnRlbmRlZCBmb3IgZGVidWdnaW5nIF9vbmx5XywgYW5kIHNob3VsZCBiZSBvdmVycmlkZGVuCi0gICAgICogYnkgYWxsIHN5bnRheCB0cmVlIG5vZGUgaW1wbGVtZW50YXRpb25zLgotICAgICAqIEBwYXJhbSBpbmRlbnQgSW5kZW50YXRpb24gbGV2ZWwgZm9yIHN5bnRheCB0cmVlIGxldmVscy4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBkaXNwbGF5KGludCBpbmRlbnQpIHsKLSAgICAgICAgZGlzcGxheUNvbnRlbnRzKGluZGVudCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRGlzcGxheXMgdGhlIGNvbnRlbnRzIG9mIHRoaXMgc3ludGF4IHRyZWUgbm9kZSAodG8gc3Rkb3V0KS4KLSAgICAgKiBUaGlzIG1ldGhvZCBpcyBpbnRlbmRlZCBmb3IgZGVidWdnaW5nIF9vbmx5XyAhISEKLSAgICAgKiBAcGFyYW0gaW5kZW50IEluZGVudGF0aW9uIGxldmVsIGZvciBzeW50YXggdHJlZSBsZXZlbHMuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgZGlzcGxheUNvbnRlbnRzKGludCBpbmRlbnQpIHsKLSAgICAgICAgZm9yIChTeW50YXhUcmVlTm9kZSBpdGVtIDogX2NvbnRlbnRzKSB7Ci0gICAgICAgICAgICBpdGVtLmRpc3BsYXkoaW5kZW50KTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldCB0aGUgaW5kZW50YXRpb24gbGV2ZWwgZm9yIGRlYnVnIG91dHB1dC4KLSAgICAgKiBAcGFyYW0gaW5kZW50IEluZGVudGF0aW9uIGxldmVsIGZvciBzeW50YXggdHJlZSBsZXZlbHMuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGZpbmFsIHZvaWQgaW5kZW50KGludCBpbmRlbnQpIHsKLSAgICAgICAgU3lzdGVtLm91dC5wcmludChuZXcgU3RyaW5nKF9zcGFjZXMsIDAsIGluZGVudCkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJlcG9ydCBhbiBlcnJvciB0byB0aGUgcGFyc2VyLgotICAgICAqIEBwYXJhbSBlbGVtZW50IFRoZSBlbGVtZW50IGluIHdoaWNoIHRoZSBlcnJvciBvY2N1cmVkIChub3JtYWxseSAndGhpcycKLSAgICAgKiBidXQgaXQgY291bGQgYWxzbyBiZSBhbiBleHByZXNzaW9uL3BhdHRlcm4vZXRjLikKLSAgICAgKiBAcGFyYW0gcGFyc2VyIFRoZSBYU0xUIHBhcnNlciB0byByZXBvcnQgdGhlIGVycm9yIHRvLgotICAgICAqIEBwYXJhbSBlcnJvciBUaGUgZXJyb3IgY29kZSAoZnJvbSB1dGlsL0Vycm9yTXNnKS4KLSAgICAgKiBAcGFyYW0gbWVzc2FnZSBBbnkgYWRkaXRpb25hbCBlcnJvciBtZXNzYWdlLgotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIHJlcG9ydEVycm9yKFN5bnRheFRyZWVOb2RlIGVsZW1lbnQsIFBhcnNlciBwYXJzZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGVycm9yQ29kZSwgU3RyaW5nIG1lc3NhZ2UpIHsKLSAgICAgICAgZmluYWwgRXJyb3JNc2cgZXJyb3IgPSBuZXcgRXJyb3JNc2coZXJyb3JDb2RlLCBtZXNzYWdlLCBlbGVtZW50KTsKLSAgICAgICAgcGFyc2VyLnJlcG9ydEVycm9yKENvbnN0YW50cy5FUlJPUiwgZXJyb3IpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJlcG9ydCBhIHJlY292ZXJhYmxlIGVycm9yIHRvIHRoZSBwYXJzZXIuCi0gICAgICogQHBhcmFtIGVsZW1lbnQgVGhlIGVsZW1lbnQgaW4gd2hpY2ggdGhlIGVycm9yIG9jY3VyZWQgKG5vcm1hbGx5ICd0aGlzJwotICAgICAqIGJ1dCBpdCBjb3VsZCBhbHNvIGJlIGFuIGV4cHJlc3Npb24vcGF0dGVybi9ldGMuKQotICAgICAqIEBwYXJhbSBwYXJzZXIgVGhlIFhTTFQgcGFyc2VyIHRvIHJlcG9ydCB0aGUgZXJyb3IgdG8uCi0gICAgICogQHBhcmFtIGVycm9yIFRoZSBlcnJvciBjb2RlIChmcm9tIHV0aWwvRXJyb3JNc2cpLgotICAgICAqIEBwYXJhbSBtZXNzYWdlIEFueSBhZGRpdGlvbmFsIGVycm9yIG1lc3NhZ2UuCi0gICAgICovCi0gICAgcHJvdGVjdGVkICB2b2lkIHJlcG9ydFdhcm5pbmcoU3ludGF4VHJlZU5vZGUgZWxlbWVudCwgUGFyc2VyIHBhcnNlciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgZXJyb3JDb2RlLCBTdHJpbmcgbWVzc2FnZSkgewotICAgICAgICBmaW5hbCBFcnJvck1zZyBlcnJvciA9IG5ldyBFcnJvck1zZyhlcnJvckNvZGUsIG1lc3NhZ2UsIGVsZW1lbnQpOwotICAgICAgICBwYXJzZXIucmVwb3J0RXJyb3IoQ29uc3RhbnRzLldBUk5JTkcsIGVycm9yKTsKLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvVGVtcGxhdGUuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvVGVtcGxhdGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYzY4Mzc0NC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL1RlbXBsYXRlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzMzkgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAxNSwgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqLwotLyoKLSAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQotICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCi0gKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCi0gKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAotICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKLSAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5Db25zdGFudFBvb2xHZW47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JTlZPS0VWSVJUVUFMOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW5zdHJ1Y3Rpb25MaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkNsYXNzR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkVycm9yTXNnOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLk1ldGhvZEdlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5OYW1lZE1ldGhvZEdlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGVDaGVja0Vycm9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlV0aWw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5YTUwxMUNoYXI7Ci1pbXBvcnQgamF2YS51dGlsLkxpc3Q7Ci1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotCi0vKioKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICogQGF1dGhvciBFcndpbiBCb2x3aWR0IDxlamJAa2xvbXAub3JnPgotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgVGVtcGxhdGUgZXh0ZW5kcyBUb3BMZXZlbEVsZW1lbnQgewotCi0gICAgcHJpdmF0ZSBRTmFtZSAgIF9uYW1lOyAgICAgLy8gVGhlIG5hbWUgb2YgdGhlIHRlbXBsYXRlIChpZiBhbnkpCi0gICAgcHJpdmF0ZSBRTmFtZSAgIF9tb2RlOyAgICAgLy8gTW9kZSBpbiB3aGljaCB0aGlzIHRlbXBsYXRlIGlzIGluc3RhbnRpYXRlZC4KLSAgICBwcml2YXRlIFBhdHRlcm4gX3BhdHRlcm47ICAvLyBNYXRjaGluZyBwYXR0ZXJuIGRlZmluZWQgZm9yIHRoaXMgdGVtcGxhdGUuCi0gICAgcHJpdmF0ZSBkb3VibGUgIF9wcmlvcml0eTsgLy8gTWF0Y2hpbmcgcHJpb3JpdHkgb2YgdGhpcyB0ZW1wbGF0ZS4KLSAgICBwcml2YXRlIGludCAgICAgX3Bvc2l0aW9uOyAvLyBQb3NpdGlvbiB3aXRoaW4gc3R5bGVzaGVldCAocHJpby4gcmVzb2x1dGlvbikKLSAgICBwcml2YXRlIGJvb2xlYW4gX2Rpc2FibGVkID0gZmFsc2U7Ci0gICAgcHJpdmF0ZSBib29sZWFuIF9jb21waWxlZCA9IGZhbHNlOy8vbWFrZSBzdXJlIGl0IGlzIGNvbXBpbGVkIG9ubHkgb25jZQotICAgIHByaXZhdGUgYm9vbGVhbiBfc2ltcGxpZmllZCA9IGZhbHNlOwotCi0gICAgLy8gVHJ1ZSBpZiB0aGlzIGlzIGEgc2ltcGxlIG5hbWVkIHRlbXBsYXRlLiBBIHNpbXBsZSBuYW1lZAotICAgIC8vIHRlbXBsYXRlIGlzIGEgdGVtcGxhdGUgd2hpY2ggb25seSBoYXMgYSBuYW1lIGJ1dCBubyBtYXRjaCBwYXR0ZXJuLgotICAgIHByaXZhdGUgYm9vbGVhbiBfaXNTaW1wbGVOYW1lZFRlbXBsYXRlID0gZmFsc2U7Ci0KLSAgICAvLyBUaGUgbGlzdCBvZiBwYXJhbWV0ZXJzIGluIHRoaXMgdGVtcGxhdGUuIFRoaXMgaXMgb25seSB1c2VkCi0gICAgLy8gZm9yIHNpbXBsZSBuYW1lZCB0ZW1wbGF0ZXMuCi0gICAgcHJpdmF0ZSBWZWN0b3I8UGFyYW0+IF9wYXJhbWV0ZXJzID0gbmV3IFZlY3Rvcjw+KCk7Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBoYXNQYXJhbXMoKSB7Ci0gICAgICAgIHJldHVybiBfcGFyYW1ldGVycy5zaXplKCkgPiAwOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGlzU2ltcGxpZmllZCgpIHsKLSAgICAgICAgcmV0dXJuKF9zaW1wbGlmaWVkKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRTaW1wbGlmaWVkKCkgewotICAgICAgICBfc2ltcGxpZmllZCA9IHRydWU7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gaXNTaW1wbGVOYW1lZFRlbXBsYXRlKCkgewotICAgICAgICByZXR1cm4gX2lzU2ltcGxlTmFtZWRUZW1wbGF0ZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBhZGRQYXJhbWV0ZXIoUGFyYW0gcGFyYW0pIHsKLSAgICAgICAgX3BhcmFtZXRlcnMuYWRkRWxlbWVudChwYXJhbSk7Ci0gICAgfQotCi0gICAgcHVibGljIFZlY3RvcjxQYXJhbT4gZ2V0UGFyYW1ldGVycygpIHsKLSAgICAgICAgcmV0dXJuIF9wYXJhbWV0ZXJzOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGRpc2FibGUoKSB7Ci0gICAgICAgIF9kaXNhYmxlZCA9IHRydWU7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gZGlzYWJsZWQoKSB7Ci0gICAgICAgIHJldHVybihfZGlzYWJsZWQpOwotICAgIH0KLQotICAgIHB1YmxpYyBkb3VibGUgZ2V0UHJpb3JpdHkoKSB7Ci0gICAgICAgIHJldHVybiBfcHJpb3JpdHk7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBnZXRQb3NpdGlvbigpIHsKLSAgICAgICAgcmV0dXJuKF9wb3NpdGlvbik7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gaXNOYW1lZCgpIHsKLSAgICAgICAgcmV0dXJuIF9uYW1lICE9IG51bGw7Ci0gICAgfQotCi0gICAgcHVibGljIFBhdHRlcm4gZ2V0UGF0dGVybigpIHsKLSAgICAgICAgcmV0dXJuIF9wYXR0ZXJuOwotICAgIH0KLQotICAgIHB1YmxpYyBRTmFtZSBnZXROYW1lKCkgewotICAgICAgICByZXR1cm4gX25hbWU7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0TmFtZShRTmFtZSBxbmFtZSkgewotICAgICAgICBpZiAoX25hbWUgPT0gbnVsbCkgX25hbWUgPSBxbmFtZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgUU5hbWUgZ2V0TW9kZU5hbWUoKSB7Ci0gICAgICAgIHJldHVybiBfbW9kZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb21wYXJlIHRoaXMgdGVtcGxhdGUgdG8gYW5vdGhlci4gRmlyc3QgY2hlY2tzIHByaW9yaXR5LCB0aGVuIHBvc2l0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgY29tcGFyZVRvKE9iamVjdCB0ZW1wbGF0ZSkgewotICAgICAgICBUZW1wbGF0ZSBvdGhlciA9IChUZW1wbGF0ZSl0ZW1wbGF0ZTsKLSAgICAgICAgaWYgKF9wcmlvcml0eSA+IG90aGVyLl9wcmlvcml0eSkKLSAgICAgICAgICAgIHJldHVybiAxOwotICAgICAgICBlbHNlIGlmIChfcHJpb3JpdHkgPCBvdGhlci5fcHJpb3JpdHkpCi0gICAgICAgICAgICByZXR1cm4gLTE7Ci0gICAgICAgIGVsc2UgaWYgKF9wb3NpdGlvbiA+IG90aGVyLl9wb3NpdGlvbikKLSAgICAgICAgICAgIHJldHVybiAxOwotICAgICAgICBlbHNlIGlmIChfcG9zaXRpb24gPCBvdGhlci5fcG9zaXRpb24pCi0gICAgICAgICAgICByZXR1cm4gLTE7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICAgIHJldHVybiAwOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGRpc3BsYXkoaW50IGluZGVudCkgewotICAgICAgICBVdGlsLnByaW50bG4oJ1xuJyk7Ci0gICAgICAgIGluZGVudChpbmRlbnQpOwotICAgICAgICBpZiAoX25hbWUgIT0gbnVsbCkgewotICAgICAgICAgICAgaW5kZW50KGluZGVudCk7Ci0gICAgICAgICAgICBVdGlsLnByaW50bG4oIm5hbWUgPSAiICsgX25hbWUpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKF9wYXR0ZXJuICE9IG51bGwpIHsKLSAgICAgICAgICAgIGluZGVudChpbmRlbnQpOwotICAgICAgICAgICAgVXRpbC5wcmludGxuKCJtYXRjaCA9ICIgKyBfcGF0dGVybi50b1N0cmluZygpKTsKLSAgICAgICAgfQotICAgICAgICBpZiAoX21vZGUgIT0gbnVsbCkgewotICAgICAgICAgICAgaW5kZW50KGluZGVudCk7Ci0gICAgICAgICAgICBVdGlsLnByaW50bG4oIm1vZGUgPSAiICsgX21vZGUpOwotICAgICAgICB9Ci0gICAgICAgIGRpc3BsYXlDb250ZW50cyhpbmRlbnQgKyBJbmRlbnRJbmNyZW1lbnQpOwotICAgIH0KLQotICAgIHByaXZhdGUgYm9vbGVhbiByZXNvbHZlTmFtZWRUZW1wbGF0ZXMoVGVtcGxhdGUgb3RoZXIsIFBhcnNlciBwYXJzZXIpIHsKLQotICAgICAgICBpZiAob3RoZXIgPT0gbnVsbCkgcmV0dXJuIHRydWU7Ci0KLSAgICAgICAgU3ltYm9sVGFibGUgc3RhYmxlID0gcGFyc2VyLmdldFN5bWJvbFRhYmxlKCk7Ci0KLSAgICAgICAgZmluYWwgaW50IHVzID0gdGhpcy5nZXRJbXBvcnRQcmVjZWRlbmNlKCk7Ci0gICAgICAgIGZpbmFsIGludCB0aGVtID0gb3RoZXIuZ2V0SW1wb3J0UHJlY2VkZW5jZSgpOwotCi0gICAgICAgIGlmICh1cyA+IHRoZW0pIHsKLSAgICAgICAgICAgIG90aGVyLmRpc2FibGUoKTsKLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKHVzIDwgdGhlbSkgewotICAgICAgICAgICAgc3RhYmxlLmFkZFRlbXBsYXRlKG90aGVyKTsKLSAgICAgICAgICAgIHRoaXMuZGlzYWJsZSgpOwotICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwcml2YXRlIFN0eWxlc2hlZXQgX3N0eWxlc2hlZXQgPSBudWxsOwotCi0gICAgcHVibGljIFN0eWxlc2hlZXQgZ2V0U3R5bGVzaGVldCgpIHsKLSAgICAgICAgcmV0dXJuIF9zdHlsZXNoZWV0OwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHBhcnNlQ29udGVudHMoUGFyc2VyIHBhcnNlcikgewotCi0gICAgICAgIGZpbmFsIFN0cmluZyBuYW1lICAgICA9IGdldEF0dHJpYnV0ZSgibmFtZSIpOwotICAgICAgICBmaW5hbCBTdHJpbmcgbW9kZSAgICAgPSBnZXRBdHRyaWJ1dGUoIm1vZGUiKTsKLSAgICAgICAgZmluYWwgU3RyaW5nIG1hdGNoICAgID0gZ2V0QXR0cmlidXRlKCJtYXRjaCIpOwotICAgICAgICBmaW5hbCBTdHJpbmcgcHJpb3JpdHkgPSBnZXRBdHRyaWJ1dGUoInByaW9yaXR5Iik7Ci0KLSAgICAgICAgX3N0eWxlc2hlZXQgPSBzdXBlci5nZXRTdHlsZXNoZWV0KCk7Ci0KLSAgICAgICAgaWYgKG5hbWUubGVuZ3RoKCkgPiAwKSB7Ci0gICAgICAgICAgICBpZiAoIVhNTDExQ2hhci5pc1hNTDExVmFsaWRRTmFtZShuYW1lKSkgewotICAgICAgICAgICAgICAgIEVycm9yTXNnIGVyciA9IG5ldyBFcnJvck1zZyhFcnJvck1zZy5JTlZBTElEX1FOQU1FX0VSUiwgbmFtZSwgdGhpcyk7Ci0gICAgICAgICAgICAgICAgcGFyc2VyLnJlcG9ydEVycm9yKENvbnN0YW50cy5FUlJPUiwgZXJyKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIF9uYW1lID0gcGFyc2VyLmdldFFOYW1lSWdub3JlRGVmYXVsdE5zKG5hbWUpOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKG1vZGUubGVuZ3RoKCkgPiAwKSB7Ci0gICAgICAgICAgICBpZiAoIVhNTDExQ2hhci5pc1hNTDExVmFsaWRRTmFtZShtb2RlKSkgewotICAgICAgICAgICAgICAgIEVycm9yTXNnIGVyciA9IG5ldyBFcnJvck1zZyhFcnJvck1zZy5JTlZBTElEX1FOQU1FX0VSUiwgbW9kZSwgdGhpcyk7Ci0gICAgICAgICAgICAgICAgcGFyc2VyLnJlcG9ydEVycm9yKENvbnN0YW50cy5FUlJPUiwgZXJyKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIF9tb2RlID0gcGFyc2VyLmdldFFOYW1lSWdub3JlRGVmYXVsdE5zKG1vZGUpOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKG1hdGNoLmxlbmd0aCgpID4gMCkgewotICAgICAgICAgICAgX3BhdHRlcm4gPSBwYXJzZXIucGFyc2VQYXR0ZXJuKHRoaXMsICJtYXRjaCIsIG51bGwpOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKHByaW9yaXR5Lmxlbmd0aCgpID4gMCkgewotICAgICAgICAgICAgX3ByaW9yaXR5ID0gRG91YmxlLnBhcnNlRG91YmxlKHByaW9yaXR5KTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIGlmIChfcGF0dGVybiAhPSBudWxsKQotICAgICAgICAgICAgICAgIF9wcmlvcml0eSA9IF9wYXR0ZXJuLmdldFByaW9yaXR5KCk7Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgX3ByaW9yaXR5ID0gRG91YmxlLk5hTjsKLSAgICAgICAgfQotCi0gICAgICAgIF9wb3NpdGlvbiA9IHBhcnNlci5nZXRUZW1wbGF0ZUluZGV4KCk7Ci0KLSAgICAgICAgLy8gQWRkIHRoZSAobmFtZWQpIHRlbXBsYXRlIHRvIHRoZSBzeW1ib2wgdGFibGUKLSAgICAgICAgaWYgKF9uYW1lICE9IG51bGwpIHsKLSAgICAgICAgICAgIFRlbXBsYXRlIG90aGVyID0gcGFyc2VyLmdldFN5bWJvbFRhYmxlKCkuYWRkVGVtcGxhdGUodGhpcyk7Ci0gICAgICAgICAgICBpZiAoIXJlc29sdmVOYW1lZFRlbXBsYXRlcyhvdGhlciwgcGFyc2VyKSkgewotICAgICAgICAgICAgICAgIEVycm9yTXNnIGVyciA9Ci0gICAgICAgICAgICAgICAgICAgIG5ldyBFcnJvck1zZyhFcnJvck1zZy5URU1QTEFURV9SRURFRl9FUlIsIF9uYW1lLCB0aGlzKTsKLSAgICAgICAgICAgICAgICBwYXJzZXIucmVwb3J0RXJyb3IoQ29uc3RhbnRzLkVSUk9SLCBlcnIpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gSXMgdGhpcyBhIHNpbXBsZSBuYW1lZCB0ZW1wbGF0ZT8KLSAgICAgICAgICAgIGlmIChfcGF0dGVybiA9PSBudWxsICYmIF9tb2RlID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBfaXNTaW1wbGVOYW1lZFRlbXBsYXRlID0gdHJ1ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGlmIChfcGFyZW50IGluc3RhbmNlb2YgU3R5bGVzaGVldCkgewotICAgICAgICAgICAgKChTdHlsZXNoZWV0KV9wYXJlbnQpLmFkZFRlbXBsYXRlKHRoaXMpOwotICAgICAgICB9Ci0KLSAgICAgICAgcGFyc2VyLnNldFRlbXBsYXRlKHRoaXMpOyAgICAgICAvLyBzZXQgY3VycmVudCB0ZW1wbGF0ZQotICAgICAgICBwYXJzZUNoaWxkcmVuKHBhcnNlcik7Ci0gICAgICAgIHBhcnNlci5zZXRUZW1wbGF0ZShudWxsKTsgICAgICAgLy8gY2xlYXIgdGVtcGxhdGUKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBXaGVuIHRoZSBwYXJzZXIgcmVhbGlzZXMgdGhhdCBpdCBpcyBkZWFsaWduIHdpdGggYSBzaW1wbGlmaWVkIHN0eWxlc2hlZXQKLSAgICAgKiBpdCB3aWxsIGNyZWF0ZSBhbiBlbXB0eSBTdHlsZXNoZWV0IG9iamVjdCB3aXRoIHRoZSByb290IGVsZW1lbnQgb2YgdGhlCi0gICAgICogc3R5bGVzaGVldCAoYSBMaXRlcmFsRWxlbWVudCBvYmplY3QpIGFzIGl0cyBvbmx5IGNoaWxkLiBUaGUgU3R5bGVzaGVldAotICAgICAqIG9iamVjdCB3aWxsIHRoZW4gY3JlYXRlIHRoaXMgVGVtcGxhdGUgb2JqZWN0IGFuZCBpbnZva2UgdGhpcyBtZXRob2QgdG8KLSAgICAgKiBmb3JjZSBzb21lIHNwZWNpZmljIGJlaGF2aW91ci4gV2hhdCB3ZSBuZWVkIHRvIGRvIGlzOgotICAgICAqICBvKSBjcmVhdGUgYSBwYXR0ZXJuIG1hdGNoaW5nIG9uIHRoZSByb290IG5vZGUKLSAgICAgKiAgbykgYWRkIHRoZSBMUkUgcm9vdCBub2RlICh0aGUgb25seSBjaGlsZCBvZiB0aGUgU3R5bGVzaGVldCkgYXMgb3VyCi0gICAgICogICAgIG9ubHkgY2hpbGQgbm9kZQotICAgICAqICBvKSBzZXQgdGhlIGVtcHR5IFN0eWxlc2hlZXQgYXMgb3VyIHBhcmVudAotICAgICAqICBvKSBzZXQgdGhpcyB0ZW1wbGF0ZSBhcyB0aGUgU3R5bGVzaGVldCdzIG9ubHkgY2hpbGQKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBwYXJzZVNpbXBsaWZpZWQoU3R5bGVzaGVldCBzdHlsZXNoZWV0LCBQYXJzZXIgcGFyc2VyKSB7Ci0KLSAgICAgICAgX3N0eWxlc2hlZXQgPSBzdHlsZXNoZWV0OwotICAgICAgICBzZXRQYXJlbnQoc3R5bGVzaGVldCk7Ci0KLSAgICAgICAgX25hbWUgPSBudWxsOwotICAgICAgICBfbW9kZSA9IG51bGw7Ci0gICAgICAgIF9wcmlvcml0eSA9IERvdWJsZS5OYU47Ci0gICAgICAgIF9wYXR0ZXJuID0gcGFyc2VyLnBhcnNlUGF0dGVybih0aGlzLCAiLyIpOwotCi0gICAgICAgIGZpbmFsIExpc3Q8U3ludGF4VHJlZU5vZGU+IGNvbnRlbnRzID0gX3N0eWxlc2hlZXQuZ2V0Q29udGVudHMoKTsKLSAgICAgICAgZmluYWwgU3ludGF4VHJlZU5vZGUgcm9vdCA9IGNvbnRlbnRzLmdldCgwKTsKLQotICAgICAgICBpZiAocm9vdCBpbnN0YW5jZW9mIExpdGVyYWxFbGVtZW50KSB7Ci0gICAgICAgICAgICBhZGRFbGVtZW50KHJvb3QpOwotICAgICAgICAgICAgcm9vdC5zZXRQYXJlbnQodGhpcyk7Ci0gICAgICAgICAgICBjb250ZW50cy5zZXQoMCwgdGhpcyk7Ci0gICAgICAgICAgICBwYXJzZXIuc2V0VGVtcGxhdGUodGhpcyk7Ci0gICAgICAgICAgICByb290LnBhcnNlQ29udGVudHMocGFyc2VyKTsKLSAgICAgICAgICAgIHBhcnNlci5zZXRUZW1wbGF0ZShudWxsKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0gICAgICAgIGlmIChfcGF0dGVybiAhPSBudWxsKSB7Ci0gICAgICAgICAgICBfcGF0dGVybi50eXBlQ2hlY2soc3RhYmxlKTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiB0eXBlQ2hlY2tDb250ZW50cyhzdGFibGUpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotICAgICAgICBmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQotICAgICAgICBpZiAoX2Rpc2FibGVkKSByZXR1cm47Ci0gICAgICAgIC8vIGJ1ZyBmaXggIzQ0MzMxMzMsIGFkZCBhIGNhbGwgdG8gbmFtZWQgdGVtcGxhdGUgZnJvbSBhcHBseVRlbXBsYXRlcwotICAgICAgICBTdHJpbmcgY2xhc3NOYW1lID0gY2xhc3NHZW4uZ2V0Q2xhc3NOYW1lKCk7Ci0KLSAgICAgICAgaWYgKF9jb21waWxlZCAmJiBpc05hbWVkKCkpewotICAgICAgICAgICAgU3RyaW5nIG1ldGhvZE5hbWUgPSBVdGlsLmVzY2FwZShfbmFtZS50b1N0cmluZygpKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChjbGFzc0dlbi5sb2FkVHJhbnNsZXQoKSk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRJdGVyYXRvcigpKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZEhhbmRsZXIoKSk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRDdXJyZW50Tm9kZSgpKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChjcGcuYWRkTWV0aG9kcmVmKGNsYXNzTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZE5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKCIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgRE9NX0lOVEZfU0lHCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIE5PREVfSVRFUkFUT1JfU0lHCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIFRSQU5TTEVUX09VVFBVVF9TSUcKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIkkpViIpKSk7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoX2NvbXBpbGVkKSByZXR1cm47Ci0gICAgICAgIF9jb21waWxlZCA9IHRydWU7Ci0KLSAgICAgICAgLy8gJU9QVCUgU3BlY2lhbCBoYW5kbGluZyBmb3Igc2ltcGxlIG5hbWVkIHRlbXBsYXRlcy4KLSAgICAgICAgaWYgKF9pc1NpbXBsZU5hbWVkVGVtcGxhdGUgJiYgbWV0aG9kR2VuIGluc3RhbmNlb2YgTmFtZWRNZXRob2RHZW5lcmF0b3IpIHsKLSAgICAgICAgICAgIGludCBudW1QYXJhbXMgPSBfcGFyYW1ldGVycy5zaXplKCk7Ci0gICAgICAgICAgICBOYW1lZE1ldGhvZEdlbmVyYXRvciBuYW1lZE1ldGhvZEdlbiA9IChOYW1lZE1ldGhvZEdlbmVyYXRvciltZXRob2RHZW47Ci0KLSAgICAgICAgICAgIC8vIFVwZGF0ZSBsb2FkL3N0b3JlIGluc3RydWN0aW9ucyB0byBhY2Nlc3MgUGFyYW1zIGZyb20gdGhlIHN0YWNrCi0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bVBhcmFtczsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgUGFyYW0gcGFyYW0gPSAoUGFyYW0pX3BhcmFtZXRlcnMuZWxlbWVudEF0KGkpOwotICAgICAgICAgICAgICAgIHBhcmFtLnNldExvYWRJbnN0cnVjdGlvbihuYW1lZE1ldGhvZEdlbi5sb2FkUGFyYW1ldGVyKGkpKTsKLSAgICAgICAgICAgICAgICBwYXJhbS5zZXRTdG9yZUluc3RydWN0aW9uKG5hbWVkTWV0aG9kR2VuLnN0b3JlUGFyYW1ldGVyKGkpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHRyYW5zbGF0ZUNvbnRlbnRzKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICBpbC5zZXRQb3NpdGlvbnModHJ1ZSk7Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL1Rlc3RTZXEuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvVGVzdFNlcS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkOGNhN2U4Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvVGVzdFNlcS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjg4ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKi8KLS8qCi0gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKLSAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAotICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgotICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKLSAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCi0gKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogVGVzdFNlcS5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzEyIDExOjMxOjM4IHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuR09UT19XOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW5zdHJ1Y3Rpb25IYW5kbGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JbnN0cnVjdGlvbkxpc3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuQ2xhc3NHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuTWV0aG9kR2VuZXJhdG9yOwotaW1wb3J0IGphdmEudXRpbC5NYXA7Ci1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotLyoqCi0gKiBBIHRlc3Qgc2VxdWVuY2UgaXMgYSBzZXF1ZW5jZSBvZiBwYXR0ZXJucyB0aGF0Ci0gKgotICogICgxKSBvY2N1cmVkIGluIHRlbXBsYXRlcyBpbiB0aGUgc2FtZSBtb2RlCi0gKiAgKDIpIHNoYXJlIHRoZSBzYW1lIGtlcm5lbCBub2RlIHR5cGUgKGUuZy4gQS9CIGFuZCBDL0MvQikKLSAqICAoMykgbWF5IGFsc28gY29udGFpbiBwYXR0ZXJucyBtYXRjaGluZyAiKiIgYW5kICJub2RlKCkiCi0gKiAgICAgIChlbGVtZW50IHNlcXVlbmNlIG9ubHkpIG9yIG1hdGNoaW5nICJAKiIgKGF0dHJpYnV0ZQotICogICAgICBzZXF1ZW5jZSBvbmx5KS4KLSAqCi0gKiBBIHRlc3Qgc2VxdWVuY2UgbWF5IGhhdmUgYSBkZWZhdWx0IHRlbXBsYXRlLCB3aGljaCB3aWxsIGJlCi0gKiBpbnN0YW50aWF0ZWQgaWYgbm9uZSBvZiB0aGUgb3RoZXIgcGF0dGVybnMgbWF0Y2guCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKiBAYXV0aG9yIEVyd2luIEJvbHdpZHQgPGVqYkBrbG9tcC5vcmc+Ci0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4gPG1vcnRlbi5qb3JnZW5zZW5Ac3VuLmNvbT4KLSAqLwotZmluYWwgY2xhc3MgVGVzdFNlcSB7Ci0KLSAgICAvKioKLSAgICAgKiBJbnRlZ2VyIGNvZGUgZm9yIHRoZSBrZXJuZWwgdHlwZSBvZiB0aGlzIHRlc3Qgc2VxdWVuY2UKLSAgICAgKi8KLSAgICBwcml2YXRlIGludCBfa2VybmVsVHlwZTsKLQotICAgIC8qKgotICAgICAqIFZlY3RvciBvZiBhbGwgcGF0dGVybnMgaW4gdGhlIHRlc3Qgc2VxdWVuY2UuIE1heSBpbmNsdWRlCi0gICAgICogcGF0dGVybnMgd2l0aCAiKiIsICJAKiIgb3IgIm5vZGUoKSIga2VybmVsLgotICAgICAqLwotICAgIHByaXZhdGUgVmVjdG9yIF9wYXR0ZXJucyA9IG51bGw7Ci0KLSAgICAvKioKLSAgICAgKiBBIHJlZmVyZW5jZSB0byB0aGUgTW9kZSBvYmplY3QuCi0gICAgICovCi0gICAgcHJpdmF0ZSBNb2RlIF9tb2RlID0gbnVsbDsKLQotICAgIC8qKgotICAgICAqIERlZmF1bHQgdGVtcGxhdGUgZm9yIHRoaXMgdGVzdCBzZXF1ZW5jZQotICAgICAqLwotICAgIHByaXZhdGUgVGVtcGxhdGUgX2RlZmF1bHQgPSBudWxsOwotCi0gICAgLyoqCi0gICAgICogSW5zdHJ1Y3Rpb24gbGlzdCByZXByZXNlbnRpbmcgdGhpcyB0ZXN0IHNlcXVlbmNlLgotICAgICAqLwotICAgIHByaXZhdGUgSW5zdHJ1Y3Rpb25MaXN0IF9pbnN0cnVjdGlvbkxpc3Q7Ci0KLSAgICAvKioKLSAgICAgKiBDYWNoZWQgaGFuZGxlIHRvIGF2b2lkIGNvbXBpbGluZyBtb3JlIHRoYW4gb25jZS4KLSAgICAgKi8KLSAgICBwcml2YXRlIEluc3RydWN0aW9uSGFuZGxlIF9zdGFydCA9IG51bGw7Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGVzIGEgbmV3IHRlc3Qgc2VxdWVuY2UgZ2l2ZW4gYSBzZXQgb2YgcGF0dGVybnMgYW5kIGEgbW9kZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgVGVzdFNlcShWZWN0b3IgcGF0dGVybnMsIE1vZGUgbW9kZSkgewotICAgICAgICB0aGlzKHBhdHRlcm5zLCAtMiwgbW9kZSk7Ci0gICAgfQotCi0gICAgcHVibGljIFRlc3RTZXEoVmVjdG9yIHBhdHRlcm5zLCBpbnQga2VybmVsVHlwZSwgTW9kZSBtb2RlKSB7Ci0gICAgICAgIF9wYXR0ZXJucyA9IHBhdHRlcm5zOwotICAgICAgICBfa2VybmVsVHlwZSA9IGtlcm5lbFR5cGU7Ci0gICAgICAgIF9tb2RlID0gbW9kZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgdGVzdCBzZXF1ZW5jZS4gTm90aWNlCi0gICAgICogdGhhdCB0ZXN0IHNlcXVlbmNlcyBhcmUgbXV0YWJsZSwgc28gdGhlIHZhbHVlIHJldHVybmVkIGJ5IHRoaXMKLSAgICAgKiBtZXRob2QgaXMgZGlmZmVyZW50IGJlZm9yZSBhbmQgYWZ0ZXIgY2FsbGluZyByZWR1Y2UoKS4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgICAgICBmaW5hbCBpbnQgY291bnQgPSBfcGF0dGVybnMuc2l6ZSgpOwotICAgICAgICBmaW5hbCBTdHJpbmdCdWZmZXIgcmVzdWx0ID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotCi0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykgewotICAgICAgICAgICAgZmluYWwgTG9jYXRpb25QYXRoUGF0dGVybiBwYXR0ZXJuID0KLSAgICAgICAgICAgICAgICAoTG9jYXRpb25QYXRoUGF0dGVybikgX3BhdHRlcm5zLmVsZW1lbnRBdChpKTsKLQotICAgICAgICAgICAgaWYgKGkgPT0gMCkgewotICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoIlRlc3RzZXEgZm9yIGtlcm5lbCAiKS5hcHBlbmQoX2tlcm5lbFR5cGUpCi0gICAgICAgICAgICAgICAgICAgICAgLmFwcGVuZCgnXG4nKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoIiAgIHBhdHRlcm4gIikuYXBwZW5kKGkpLmFwcGVuZCgiOiAiKQotICAgICAgICAgICAgICAgICAgLmFwcGVuZChwYXR0ZXJuLnRvU3RyaW5nKCkpCi0gICAgICAgICAgICAgICAgICAuYXBwZW5kKCdcbicpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiByZXN1bHQudG9TdHJpbmcoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBpbnN0cnVjdGlvbiBsaXN0IGZvciB0aGlzIHRlc3Qgc2VxdWVuY2UKLSAgICAgKi8KLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb25MaXN0IGdldEluc3RydWN0aW9uTGlzdCgpIHsKLSAgICAgICAgcmV0dXJuIF9pbnN0cnVjdGlvbkxpc3Q7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSBoaWdoZXN0IHByaW9yaXR5IGZvciBhIHBhdHRlcm4gaW4gdGhpcyB0ZXN0Ci0gICAgICogc2VxdWVuY2UuIFRoaXMgaXMgZWl0aGVyIHRoZSBwcmlvcml0eSBvZiB0aGUgZmlyc3Qgb3IKLSAgICAgKiBvZiB0aGUgZGVmYXVsdCBwYXR0ZXJuLgotICAgICAqLwotICAgIHB1YmxpYyBkb3VibGUgZ2V0UHJpb3JpdHkoKSB7Ci0gICAgICAgIGZpbmFsIFRlbXBsYXRlIHRlbXBsYXRlID0gKF9wYXR0ZXJucy5zaXplKCkgPT0gMCkgPyBfZGVmYXVsdAotICAgICAgICAgICAgOiAoKFBhdHRlcm4pIF9wYXR0ZXJucy5lbGVtZW50QXQoMCkpLmdldFRlbXBsYXRlKCk7Ci0gICAgICAgIHJldHVybiB0ZW1wbGF0ZS5nZXRQcmlvcml0eSgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIHBvc2l0aW9uIG9mIHRoZSBoaWdoZXN0IHByaW9yaXR5IHBhdHRlcm4gaW4KLSAgICAgKiB0aGlzIHRlc3Qgc2VxdWVuY2UuCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRQb3NpdGlvbigpIHsKLSAgICAgICAgZmluYWwgVGVtcGxhdGUgdGVtcGxhdGUgPSAoX3BhdHRlcm5zLnNpemUoKSA9PSAwKSA/IF9kZWZhdWx0Ci0gICAgICAgICAgICA6ICgoUGF0dGVybikgX3BhdHRlcm5zLmVsZW1lbnRBdCgwKSkuZ2V0VGVtcGxhdGUoKTsKLSAgICAgICAgcmV0dXJuIHRlbXBsYXRlLmdldFBvc2l0aW9uKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmVkdWNlIHRoZSBwYXR0ZXJucyBpbiB0aGlzIHRlc3Qgc2VxdWVuY2UuIENyZWF0ZXMgYSBuZXcKLSAgICAgKiB2ZWN0b3Igb2YgcGF0dGVybnMgYW5kIHNldHMgdGhlIGRlZmF1bHQgcGF0dGVybiBpZiBpdAotICAgICAqIGZpbmRzIGEgcGF0dGVybnMgdGhhdCBpcyBmdWxseSByZWR1Y2VkLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHJlZHVjZSgpIHsKLSAgICAgICAgZmluYWwgVmVjdG9yIG5ld1BhdHRlcm5zID0gbmV3IFZlY3RvcigpOwotCi0gICAgICAgIGZpbmFsIGludCBjb3VudCA9IF9wYXR0ZXJucy5zaXplKCk7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykgewotICAgICAgICAgICAgZmluYWwgTG9jYXRpb25QYXRoUGF0dGVybiBwYXR0ZXJuID0KLSAgICAgICAgICAgICAgICAoTG9jYXRpb25QYXRoUGF0dGVybilfcGF0dGVybnMuZWxlbWVudEF0KGkpOwotCi0gICAgICAgICAgICAvLyBSZWR1Y2UgdGhpcyBwYXR0ZXJuCi0gICAgICAgICAgICBwYXR0ZXJuLnJlZHVjZUtlcm5lbFBhdHRlcm4oKTsKLQotICAgICAgICAgICAgLy8gSXMgdGhpcyBwYXR0ZXJuIGZ1bGx5IHJlZHVjZWQ/Ci0gICAgICAgICAgICBpZiAocGF0dGVybi5pc1dpbGRjYXJkKCkpIHsKLSAgICAgICAgICAgICAgICBfZGVmYXVsdCA9IHBhdHRlcm4uZ2V0VGVtcGxhdGUoKTsKLSAgICAgICAgICAgICAgICBicmVhazsgICAgICAgICAgLy8gSWdub3JlIGZvbGxvd2luZyBwYXR0ZXJucwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgbmV3UGF0dGVybnMuYWRkRWxlbWVudChwYXR0ZXJuKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBfcGF0dGVybnMgPSBuZXdQYXR0ZXJuczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zLCBieSByZWZlcmVuY2UsIHRoZSB0ZW1wbGF0ZXMgdGhhdCBhcmUgaW5jbHVkZWQgaW4KLSAgICAgKiB0aGlzIHRlc3Qgc2VxdWVuY2UuIE5vdGUgdGhhdCBhIHNpbmdsZSB0ZW1wbGF0ZSBjYW4gb2NjdXIKLSAgICAgKiBpbiBzZXZlcmFsIHRlc3Qgc2VxdWVuY2VzIGlmIGl0cyBwYXR0ZXJuIGlzIGEgdW5pb24uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZmluZFRlbXBsYXRlcyhNYXA8VGVtcGxhdGUsIE9iamVjdD4gdGVtcGxhdGVzKSB7Ci0gICAgICAgIGlmIChfZGVmYXVsdCAhPSBudWxsKSB7Ci0gICAgICAgICAgICB0ZW1wbGF0ZXMucHV0KF9kZWZhdWx0LCB0aGlzKTsKLSAgICAgICAgfQotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IF9wYXR0ZXJucy5zaXplKCk7IGkrKykgewotICAgICAgICAgICAgZmluYWwgTG9jYXRpb25QYXRoUGF0dGVybiBwYXR0ZXJuID0KLSAgICAgICAgICAgICAgICAoTG9jYXRpb25QYXRoUGF0dGVybilfcGF0dGVybnMuZWxlbWVudEF0KGkpOwotICAgICAgICAgICAgdGVtcGxhdGVzLnB1dChwYXR0ZXJuLmdldFRlbXBsYXRlKCksIHRoaXMpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBpbnN0cnVjdGlvbiBoYW5kbGUgdG8gYSB0ZW1wbGF0ZSdzIGNvZGUuIFRoaXMgaXMKLSAgICAgKiB1c2VkIHdoZW4gYSBzaW5nbGUgdGVtcGxhdGUgb2NjdXJzIGluIHNldmVyYWwgdGVzdAotICAgICAqIHNlcXVlbmNlczsgdGhhdCBpcywgaWYgaXRzIHBhdHRlcm4gaXMgYSB1bmlvbiBvZiBwYXR0ZXJucwotICAgICAqIChlLmcuIG1hdGNoPSJBL0IgfCBBL0MiKS4KLSAgICAgKi8KLSAgICBwcml2YXRlIEluc3RydWN0aW9uSGFuZGxlIGdldFRlbXBsYXRlSGFuZGxlKFRlbXBsYXRlIHRlbXBsYXRlKSB7Ci0gICAgICAgIHJldHVybiAoSW5zdHJ1Y3Rpb25IYW5kbGUpX21vZGUuZ2V0VGVtcGxhdGVJbnN0cnVjdGlvbkhhbmRsZSh0ZW1wbGF0ZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBwYXR0ZXJuIG4gaW4gdGhpcyB0ZXN0IHNlcXVlbmNlCi0gICAgICovCi0gICAgcHJpdmF0ZSBMb2NhdGlvblBhdGhQYXR0ZXJuIGdldFBhdHRlcm4oaW50IG4pIHsKLSAgICAgICAgcmV0dXJuIChMb2NhdGlvblBhdGhQYXR0ZXJuKV9wYXR0ZXJucy5lbGVtZW50QXQobik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29tcGlsZSB0aGUgY29kZSBmb3IgdGhpcyB0ZXN0IHNlcXVlbmNlLiBDb21waWxlIHBhdHRlcm5zCi0gICAgICogZnJvbSBoaWdoZXN0IHRvIGxvd2VzdCBwcmlvcml0eS4gTm90ZSB0aGF0IHNpbmNlIHBhdHRlcm5zCi0gICAgICogY2FuIGJlIHNoYXJlIGJ5IG11bHRpcGxlIHRlc3Qgc2VxdWVuY2VzLCBpbnN0cnVjdGlvbiBsaXN0cwotICAgICAqIG11c3QgYmUgY29waWVkIGJlZm9yZSBiYWNrcGF0Y2hpbmcuCi0gICAgICovCi0gICAgcHVibGljIEluc3RydWN0aW9uSGFuZGxlIGNvbXBpbGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbnN0cnVjdGlvbkhhbmRsZSBjb250aW51YXRpb24pCi0gICAgewotICAgICAgICAvLyBSZXR1cm5lZCBjYWNoZWQgdmFsdWUgaWYgYWxyZWFkeSBjb21waWxlZAotICAgICAgICBpZiAoX3N0YXJ0ICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBfc3RhcnQ7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBJZiBub3QgcGF0dGVybnMsIHRoZW4gcmV0dXJuIGhhbmRsZSBmb3IgZGVmYXVsdCB0ZW1wbGF0ZQotICAgICAgICBmaW5hbCBpbnQgY291bnQgPSBfcGF0dGVybnMuc2l6ZSgpOwotICAgICAgICBpZiAoY291bnQgPT0gMCkgewotICAgICAgICAgICAgcmV0dXJuIChfc3RhcnQgPSBnZXRUZW1wbGF0ZUhhbmRsZShfZGVmYXVsdCkpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gSW5pdCBoYW5kbGUgdG8ganVtcCB3aGVuIGFsbCBwYXR0ZXJucyBmYWlsZWQKLSAgICAgICAgSW5zdHJ1Y3Rpb25IYW5kbGUgZmFpbCA9IChfZGVmYXVsdCA9PSBudWxsKSA/IGNvbnRpbnVhdGlvbgotICAgICAgICAgICAgOiBnZXRUZW1wbGF0ZUhhbmRsZShfZGVmYXVsdCk7Ci0KLSAgICAgICAgLy8gQ29tcGlsZSBhbGwgcGF0dGVybnMgaW4gcmV2ZXJzZSBvcmRlcgotICAgICAgICBmb3IgKGludCBuID0gY291bnQgLSAxOyBuID49IDA7IG4tLSkgewotICAgICAgICAgICAgZmluYWwgTG9jYXRpb25QYXRoUGF0dGVybiBwYXR0ZXJuID0gZ2V0UGF0dGVybihuKTsKLSAgICAgICAgICAgIGZpbmFsIFRlbXBsYXRlIHRlbXBsYXRlID0gcGF0dGVybi5nZXRUZW1wbGF0ZSgpOwotICAgICAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbmV3IEluc3RydWN0aW9uTGlzdCgpOwotCi0gICAgICAgICAgICAvLyBQYXR0ZXJucyBleHBlY3QgY3VycmVudCBub2RlIG9uIHRvcCBvZiBzdGFjawotICAgICAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkQ3VycmVudE5vZGUoKSk7Ci0KLSAgICAgICAgICAgIC8vIEFwcGx5IHRoZSB0ZXN0LWNvZGUgY29tcGlsZWQgZm9yIHRoZSBwYXR0ZXJuCi0gICAgICAgICAgICBJbnN0cnVjdGlvbkxpc3QgaWxpc3QgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KHBhdHRlcm4pOwotICAgICAgICAgICAgaWYgKGlsaXN0ID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBpbGlzdCA9IHBhdHRlcm4uY29tcGlsZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgICAgICAgICBtZXRob2RHZW4uYWRkSW5zdHJ1Y3Rpb25MaXN0KHBhdHRlcm4sIGlsaXN0KTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gTWFrZSBhIGNvcHkgb2YgdGhlIGluc3RydWN0aW9uIGxpc3QgZm9yIGJhY2twYXRjaGluZwotICAgICAgICAgICAgSW5zdHJ1Y3Rpb25MaXN0IGNvcHlPZmlsaXN0ID0gaWxpc3QuY29weSgpOwotCi0gICAgICAgICAgICBGbG93TGlzdCB0cnVlTGlzdCA9IHBhdHRlcm4uZ2V0VHJ1ZUxpc3QoKTsKLSAgICAgICAgICAgIGlmICh0cnVlTGlzdCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgdHJ1ZUxpc3QgPSB0cnVlTGlzdC5jb3B5QW5kUmVkaXJlY3QoaWxpc3QsIGNvcHlPZmlsaXN0KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIEZsb3dMaXN0IGZhbHNlTGlzdCA9IHBhdHRlcm4uZ2V0RmFsc2VMaXN0KCk7Ci0gICAgICAgICAgICBpZiAoZmFsc2VMaXN0ICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmYWxzZUxpc3QgPSBmYWxzZUxpc3QuY29weUFuZFJlZGlyZWN0KGlsaXN0LCBjb3B5T2ZpbGlzdCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlsLmFwcGVuZChjb3B5T2ZpbGlzdCk7Ci0KLSAgICAgICAgICAgIC8vIE9uIHN1Y2Nlc3MgYnJhbmNoIHRvIHRoZSB0ZW1wbGF0ZSBjb2RlCi0gICAgICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkhhbmRsZSBndG1wbCA9IGdldFRlbXBsYXRlSGFuZGxlKHRlbXBsYXRlKTsKLSAgICAgICAgICAgIGZpbmFsIEluc3RydWN0aW9uSGFuZGxlIHN1Y2Nlc3MgPSBpbC5hcHBlbmQobmV3IEdPVE9fVyhndG1wbCkpOwotCi0gICAgICAgICAgICBpZiAodHJ1ZUxpc3QgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHRydWVMaXN0LmJhY2tQYXRjaChzdWNjZXNzKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChmYWxzZUxpc3QgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZhbHNlTGlzdC5iYWNrUGF0Y2goZmFpbCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIE5leHQgcGF0dGVybidzICdmYWlsJyB0YXJnZXQgaXMgdGhpcyBwYXR0ZXJuJ3MgZmlyc3QgaW5zdHJ1Y3Rpb24KLSAgICAgICAgICAgIGZhaWwgPSBpbC5nZXRTdGFydCgpOwotCi0gICAgICAgICAgICAvLyBBcHBlbmQgZXhpc3RpbmcgaW5zdHJ1Y3Rpb24gbGlzdCB0byB0aGUgZW5kIG9mIHRoaXMgb25lCi0gICAgICAgICAgICBpZiAoX2luc3RydWN0aW9uTGlzdCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKF9pbnN0cnVjdGlvbkxpc3QpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBTZXQgY3VycmVudCBpbnN0cnVjdGlvbiBsaXN0IHRvIGJlIHRoaXMgb25lCi0gICAgICAgICAgICBfaW5zdHJ1Y3Rpb25MaXN0ID0gaWw7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIChfc3RhcnQgPSBmYWlsKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL1RleHQuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvVGV4dC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzYzYyZjJiLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvVGV4dC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjQ3ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFRleHQuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xMiAxMTozMzowOSBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkNvbnN0YW50UG9vbEdlbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkdFVFNUQVRJQzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklOVk9LRUlOVEVSRkFDRTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uTGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlBVU0g7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuQ2xhc3NHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuTWV0aG9kR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlV0aWw7Ci0KLS8qKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKi8KLWZpbmFsIGNsYXNzIFRleHQgZXh0ZW5kcyBJbnN0cnVjdGlvbiB7Ci0KLSAgICBwcml2YXRlIFN0cmluZyBfdGV4dDsKLSAgICBwcml2YXRlIGJvb2xlYW4gX2VzY2FwaW5nID0gdHJ1ZTsKLSAgICBwcml2YXRlIGJvb2xlYW4gX2lnbm9yZSA9IGZhbHNlOwotICAgIHByaXZhdGUgYm9vbGVhbiBfdGV4dEVsZW1lbnQgPSBmYWxzZTsKLQotICAgIC8qKgotICAgICAqIENyZWF0ZSBhIGJsYW5rIFRleHQgc3ludGF4IHRyZWUgbm9kZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgVGV4dCgpIHsKLSAgICAgICAgX3RleHRFbGVtZW50ID0gdHJ1ZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGUgdGV4dCBzeW50YXggdHJlZSBub2RlLgotICAgICAqIEBwYXJhbSB0ZXh0IGlzIHRoZSB0ZXh0IHRvIHB1dCBpbiB0aGUgbm9kZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgVGV4dChTdHJpbmcgdGV4dCkgewotICAgICAgICBfdGV4dCA9IHRleHQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgdGV4dCB3cmFwcGVkIGluc2lkZSB0aGlzIG5vZGUKLSAgICAgKiBAcmV0dXJuIFRoZSB0ZXh0IHdyYXBwZWQgaW5zaWRlIHRoaXMgbm9kZQotICAgICAqLwotICAgIHByb3RlY3RlZCBTdHJpbmcgZ2V0VGV4dCgpIHsKLSAgICAgICAgcmV0dXJuIF90ZXh0OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldCB0aGUgdGV4dCBmb3IgdGhpcyBub2RlLiBBcHBlbmRzIHRoZSBnaXZlbiB0ZXh0IHRvIGFueSBhbHJlYWR5Ci0gICAgICogZXhpc3RpbmcgdGV4dCAodXNpbmcgc3RyaW5nIGNvbmNhdGVuYXRpb24sIHNvIHVzZSBvbmx5IHdoZW4gbmVlZGVkKS4KLSAgICAgKiBAcGFyYW0gdGV4dCBpcyB0aGUgdGV4dCB0byB3cmFwIGluc2lkZSB0aGlzIG5vZGUuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgc2V0VGV4dChTdHJpbmcgdGV4dCkgewotICAgICAgICBpZiAoX3RleHQgPT0gbnVsbCkKLSAgICAgICAgICAgIF90ZXh0ID0gdGV4dDsKLSAgICAgICAgZWxzZQotICAgICAgICAgICAgX3RleHQgPSBfdGV4dCArIHRleHQ7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgZGlzcGxheShpbnQgaW5kZW50KSB7Ci0gICAgICAgIGluZGVudChpbmRlbnQpOwotICAgICAgICBVdGlsLnByaW50bG4oIlRleHQiKTsKLSAgICAgICAgaW5kZW50KGluZGVudCArIEluZGVudEluY3JlbWVudCk7Ci0gICAgICAgIFV0aWwucHJpbnRsbihfdGV4dCk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgcGFyc2VDb250ZW50cyhQYXJzZXIgcGFyc2VyKSB7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBzdHIgPSBnZXRBdHRyaWJ1dGUoImRpc2FibGUtb3V0cHV0LWVzY2FwaW5nIik7Ci0gICAgICAgIGlmICgoc3RyICE9IG51bGwpICYmIChzdHIuZXF1YWxzKCJ5ZXMiKSkpIF9lc2NhcGluZyA9IGZhbHNlOwotCi0gICAgICAgIHBhcnNlQ2hpbGRyZW4ocGFyc2VyKTsKLQotICAgICAgICBpZiAoX3RleHQgPT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKF90ZXh0RWxlbWVudCkgewotICAgICAgICAgICAgICAgIF90ZXh0ID0gRU1QVFlTVFJJTkc7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBfaWdub3JlID0gdHJ1ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChfdGV4dEVsZW1lbnQpIHsKLSAgICAgICAgICAgIGlmIChfdGV4dC5sZW5ndGgoKSA9PSAwKSBfaWdub3JlID0gdHJ1ZTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChnZXRQYXJlbnQoKSBpbnN0YW5jZW9mIExpdGVyYWxFbGVtZW50KSB7Ci0gICAgICAgICAgICBMaXRlcmFsRWxlbWVudCBlbGVtZW50ID0gKExpdGVyYWxFbGVtZW50KWdldFBhcmVudCgpOwotICAgICAgICAgICAgU3RyaW5nIHNwYWNlID0gZWxlbWVudC5nZXRBdHRyaWJ1dGUoInhtbDpzcGFjZSIpOwotICAgICAgICAgICAgaWYgKChzcGFjZSA9PSBudWxsKSB8fCAoIXNwYWNlLmVxdWFscygicHJlc2VydmUiKSkpCi0gICAgICAgIHsKLSAgICAgICAgICAgIGludCBpOwotICAgICAgICAgICAgZmluYWwgaW50IHRleHRMZW5ndGggPSBfdGV4dC5sZW5ndGgoKTsKLSAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCB0ZXh0TGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgICAgICBjaGFyIGMgPSBfdGV4dC5jaGFyQXQoaSk7Ci0gICAgICAgICAgICAgICAgaWYgKCFpc1doaXRlc3BhY2UoYykpCi0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKGkgPT0gdGV4dExlbmd0aCkKLSAgICAgICAgICAgICAgICBfaWdub3JlID0gdHJ1ZTsKLSAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICBpbnQgaTsKLSAgICAgICAgZmluYWwgaW50IHRleHRMZW5ndGggPSBfdGV4dC5sZW5ndGgoKTsKLSAgICAgICAgZm9yIChpID0gMDsgaSA8IHRleHRMZW5ndGg7IGkrKykKLSAgICAgICAgewotICAgICAgICAgICAgY2hhciBjID0gX3RleHQuY2hhckF0KGkpOwotICAgICAgICAgICAgaWYgKCFpc1doaXRlc3BhY2UoYykpCi0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGkgPT0gdGV4dExlbmd0aCkKLSAgICAgICAgICAgIF9pZ25vcmUgPSB0cnVlOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgaWdub3JlKCkgewotICAgICAgICBfaWdub3JlID0gdHJ1ZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0lnbm9yZSgpIHsKLSAgICAgICAgcmV0dXJuIF9pZ25vcmU7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gaXNUZXh0RWxlbWVudCgpIHsKLSAgICAgICAgcmV0dXJuIF90ZXh0RWxlbWVudDsKLSAgICB9Ci0KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBjb250ZXh0RGVwZW5kZW50KCkgewotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBpc1doaXRlc3BhY2UoY2hhciBjKQotICAgIHsKLSAgICAgICAgcmV0dXJuIChjID09IDB4MjAgfHwgYyA9PSAweDA5IHx8IGMgPT0gMHgwQSB8fCBjID09IDB4MEQpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotICAgICAgICBmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQotICAgICAgICBpZiAoIV9pZ25vcmUpIHsKLSAgICAgICAgICAgIC8vIFR1cm4gb2ZmIGNoYXJhY3RlciBlc2NhcGluZyBpZiBzbyBpcyB3YW50ZWQuCi0gICAgICAgICAgICBmaW5hbCBpbnQgZXNjID0gY3BnLmFkZEludGVyZmFjZU1ldGhvZHJlZihPVVRQVVRfSEFORExFUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJzZXRFc2NhcGluZyIsICIoWilaIik7Ci0gICAgICAgICAgICBpZiAoIV9lc2NhcGluZykgewotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZEhhbmRsZXIoKSk7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgZmFsc2UpKTsKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRUlOVEVSRkFDRShlc2MsIDIpKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkSGFuZGxlcigpKTsKLQotICAgICAgICAgICAgLy8gQ2FsbCBjaGFyYWN0ZXJzKFN0cmluZykgb3IgY2hhcmFjdGVycyhjaGFyW10saW50LGludCksIGFzCi0gICAgICAgICAgICAvLyBhcHByb3ByaWF0ZS4KLSAgICAgICAgICAgIGlmICghY2FuTG9hZEFzQXJyYXlPZmZzZXRMZW5ndGgoKSkgewotICAgICAgICAgICAgICAgIGZpbmFsIGludCBjaGFyYWN0ZXJzID0gY3BnLmFkZEludGVyZmFjZU1ldGhvZHJlZihPVVRQVVRfSEFORExFUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImNoYXJhY3RlcnMiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKCIrU1RSSU5HX1NJRysiKVYiKTsKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBfdGV4dCkpOwotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFSU5URVJGQUNFKGNoYXJhY3RlcnMsIDIpKTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgZmluYWwgaW50IGNoYXJhY3RlcnMgPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKE9VVFBVVF9IQU5ETEVSLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiY2hhcmFjdGVycyIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoW0NJSSlWIik7Ci0gICAgICAgICAgICAgICAgbG9hZEFzQXJyYXlPZmZzZXRMZW5ndGgoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0UoY2hhcmFjdGVycywgNCkpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBSZXN0b3JlIGNoYXJhY3RlciBlc2NhcGluZyBzZXR0aW5nIHRvIHdoYXRldmVyIGl0IHdhcy4KLSAgICAgICAgICAgIC8vIE5vdGU6IHNldEVzY2FwaW5nKGJvb2wpIHJldHVybnMgdGhlIG9yaWdpbmFsIChvbGQpIHZhbHVlCi0gICAgICAgICAgICBpZiAoIV9lc2NhcGluZykgewotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZEhhbmRsZXIoKSk7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKFNXQVApOwotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFSU5URVJGQUNFKGVzYywgMikpOwotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChQT1ApOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHRyYW5zbGF0ZUNvbnRlbnRzKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENoZWNrIHdoZXRoZXIgdGhpcyBUZXh0IG5vZGUgY2FuIGJlIHN0b3JlZCBpbiBhIGNoYXJbXSBpbiB0aGUgdHJhbnNsZXQuCi0gICAgICogQ2FsbGluZyB0aGlzIGlzIHByZWNvbmRpdGlvbiB0byBjYWxsaW5nIGxvYWRBc0FycmF5T2Zmc2V0TGVuZ3RoLgotICAgICAqIEBzZWUgI2xvYWRBc0FycmF5T2Zmc2V0TGVuZ3RoKENsYXNzR2VuZXJhdG9yLE1ldGhvZEdlbmVyYXRvcikKLSAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhpcyBUZXh0IG5vZGUgY2FuIGJlCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gY2FuTG9hZEFzQXJyYXlPZmZzZXRMZW5ndGgoKSB7Ci0gICAgICAgIC8vIE1hZ2ljIG51bWJlciEgIDIxODQ1KjMgPT0gNjU1MzUuICBCQ0VMIHVzZXMgYSBEYXRhT3V0cHV0U3RyZWFtIHRvCi0gICAgICAgIC8vIHNlcmlhbGl6ZSBjbGFzcyBmaWxlcy4gIFRoZSBKYXZhIHJ1bi10aW1lIHBsYWNlcyBhIGxpbWl0IG9uIHRoZSBzaXplCi0gICAgICAgIC8vIG9mIFN0cmluZyBkYXRhIHdyaXR0ZW4gdXNpbmcgYSBEYXRhT3V0cHV0U3RyZWFtIC0gaXQgY2Fubm90IHJlcXVpcmUKLSAgICAgICAgLy8gbW9yZSB0aGFuIDY0S0Igd2hlbiByZXByZXNlbnRlZCBhcyBVVEYtOC4gIFRoZSBudW1iZXIgb2YgYnl0ZXMKLSAgICAgICAgLy8gcmVxdWlyZWQgdG8gcmVwcmVzZW50IGEgSmF2YSBzdHJpbmcgYXMgVVRGLTggY2Fubm90IGJlIGdyZWF0ZXIKLSAgICAgICAgLy8gdGhhbiB0aHJlZSB0aW1lcyB0aGUgbnVtYmVyIG9mIGNoYXIncyBpbiB0aGUgc3RyaW5nLCBoZW5jZSB0aGUKLSAgICAgICAgLy8gY2hlY2sgZm9yIDIxODQ1LgotCi0gICAgICAgIHJldHVybiAoX3RleHQubGVuZ3RoKCkgPD0gMjE4NDUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdlbmVyYXRlcyBjb2RlIHRoYXQgbG9hZHMgdGhlIGFycmF5IHRoYXQgd2lsbCBjb250YWluIHRoZSBjaGFyYWN0ZXIKLSAgICAgKiBkYXRhIHJlcHJlc2VudGVkIGJ5IHRoaXMgVGV4dCBub2RlLCBmb2xsb3dlZCBieSB0aGUgb2Zmc2V0IG9mIHRoZQotICAgICAqIGRhdGEgZnJvbSB0aGUgc3RhcnQgb2YgdGhlIGFycmF5LCBhbmQgdGhlbiB0aGUgbGVuZ3RoIG9mIHRoZSBkYXRhLgotICAgICAqCi0gICAgICogVGhlIHByZS1jb25kaXRpb24gdG8gY2FsbGluZyB0aGlzIG1ldGhvZCBpcyB0aGF0Ci0gICAgICogY2FuTG9hZEFzQXJyYXlPZmZzZXRMZW5ndGgoKSByZXR1cm5zIHRydWUuCi0gICAgICogQHNlZSAjY2FuTG9hZEFycmF5T2Zmc2V0TGVuZ3RoKCkKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBsb2FkQXNBcnJheU9mZnNldExlbmd0aChDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0gICAgICAgIGZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotICAgICAgICBmaW5hbCBYU0xUQyB4c2x0YyA9IGNsYXNzR2VuLmdldFBhcnNlcigpLmdldFhTTFRDKCk7Ci0KLSAgICAgICAgLy8gVGhlIFhTTFRDIG9iamVjdCBrZWVwcyB0cmFjayBvZiBjaGFyYWN0ZXIgZGF0YQotICAgICAgICAvLyB0aGF0IGlzIHRvIGJlIHN0b3JlZCBpbiBjaGFyIGFycmF5cy4KLSAgICAgICAgZmluYWwgaW50IG9mZnNldCA9IHhzbHRjLmFkZENoYXJhY3RlckRhdGEoX3RleHQpOwotICAgICAgICBmaW5hbCBpbnQgbGVuZ3RoID0gX3RleHQubGVuZ3RoKCk7Ci0gICAgICAgIFN0cmluZyBjaGFyRGF0YUZpZWxkTmFtZSA9Ci0gICAgICAgICAgICBTVEFUSUNfQ0hBUl9EQVRBX0ZJRUxEICsgKHhzbHRjLmdldENoYXJhY3RlckRhdGFDb3VudCgpLTEpOwotCi0gICAgICAgIGlsLmFwcGVuZChuZXcgR0VUU1RBVElDKGNwZy5hZGRGaWVsZHJlZih4c2x0Yy5nZXRDbGFzc05hbWUoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYXJEYXRhRmllbGROYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU1RBVElDX0NIQVJfREFUQV9GSUVMRF9TSUcpKSk7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsIG9mZnNldCkpOwotICAgICAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBfdGV4dC5sZW5ndGgoKSkpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvVG9wTGV2ZWxFbGVtZW50LmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL1RvcExldmVsRWxlbWVudC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkMTY3Njg0Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvVG9wTGV2ZWxFbGVtZW50LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMDAgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogVG9wTGV2ZWxFbGVtZW50LmphdmEsdiAxLjUgMjAwNS8wOS8yOCAxMzo0ODoxNyBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JbnN0cnVjdGlvbkxpc3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuQ2xhc3NHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuRXJyb3JNc2c7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuTWV0aG9kR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZUNoZWNrRXJyb3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVXRpbDsKLQotY2xhc3MgVG9wTGV2ZWxFbGVtZW50IGV4dGVuZHMgU3ludGF4VHJlZU5vZGUgewotCi0gICAgLyoKLSAgICAgKiBMaXN0IG9mIGRlcGVuZGVuY2llcyB3aXRoIG90aGVyIHZhcmlhYmxlcywgcGFyYW1ldGVycyBvcgotICAgICAqIGtleXMgZGVmaW5lZCBhdCB0aGUgdG9wIGxldmVsLgotICAgICAqLwotICAgIHByb3RlY3RlZCBWZWN0b3IgX2RlcGVuZGVuY2llcyA9IG51bGw7Ci0KLSAgICAvKioKLSAgICAgKiBUeXBlIGNoZWNrIGFsbCB0aGUgY2hpbGRyZW4gb2YgdGhpcyBub2RlLgotICAgICAqLwotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0gICAgICAgIHJldHVybiB0eXBlQ2hlY2tDb250ZW50cyhzdGFibGUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZSB0aGlzIG5vZGUgaW50byBKVk0gYnl0ZWNvZGVzLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotICAgICAgICBFcnJvck1zZyBtc2cgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuTk9UX0lNUExFTUVOVEVEX0VSUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldENsYXNzKCksIHRoaXMpOwotICAgICAgICBnZXRQYXJzZXIoKS5yZXBvcnRFcnJvcihGQVRBTCwgbXNnKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGUgdGhpcyBub2RlIGludG8gYSBmcmVzaCBpbnN0cnVjdGlvbiBsaXN0LgotICAgICAqIFRoZSBvcmlnaW5hbCBpbnN0cnVjdGlvbiBsaXN0IGlzIHNhdmVkIGFuZCByZXN0b3JlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb25MaXN0IGNvbXBpbGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IHJlc3VsdCwgc2F2ZSA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLSAgICAgICAgbWV0aG9kR2VuLnNldEluc3RydWN0aW9uTGlzdChyZXN1bHQgPSBuZXcgSW5zdHJ1Y3Rpb25MaXN0KCkpOwotICAgICAgICB0cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgIG1ldGhvZEdlbi5zZXRJbnN0cnVjdGlvbkxpc3Qoc2F2ZSk7Ci0gICAgICAgIHJldHVybiByZXN1bHQ7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgZGlzcGxheShpbnQgaW5kZW50KSB7Ci0gICAgICAgIGluZGVudChpbmRlbnQpOwotICAgICAgICBVdGlsLnByaW50bG4oIlRvcExldmVsRWxlbWVudCIpOwotICAgICAgICBkaXNwbGF5Q29udGVudHMoaW5kZW50ICsgSW5kZW50SW5jcmVtZW50KTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBZGQgYSBkZXBlbmRlbmN5IHdpdGggb3RoZXIgdG9wLWxldmVsIGVsZW1lbnRzIGxpa2UKLSAgICAgKiB2YXJpYWJsZXMsIHBhcmFtZXRlcnMgb3Iga2V5cy4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBhZGREZXBlbmRlbmN5KFRvcExldmVsRWxlbWVudCBvdGhlcikgewotICAgICAgICBpZiAoX2RlcGVuZGVuY2llcyA9PSBudWxsKSB7Ci0gICAgICAgICAgICBfZGVwZW5kZW5jaWVzID0gbmV3IFZlY3RvcigpOwotICAgICAgICB9Ci0gICAgICAgIGlmICghX2RlcGVuZGVuY2llcy5jb250YWlucyhvdGhlcikpIHsKLSAgICAgICAgICAgIF9kZXBlbmRlbmNpZXMuYWRkRWxlbWVudChvdGhlcik7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIGxpc3Qgb2YgZGVwZW5kZW5jaWVzIHdpdGggb3RoZXIgdG9wLWxldmVsIGVsZW1lbnRzCi0gICAgICogbGlrZSB2YXJpYWJsZXMsIHBhcmFtZXRlcmVzIG9yIGtleXMuCi0gICAgICovCi0gICAgcHVibGljIFZlY3RvciBnZXREZXBlbmRlbmNpZXMoKSB7Ci0gICAgICAgIHJldHVybiBfZGVwZW5kZW5jaWVzOwotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9UcmFuc2xldE91dHB1dC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9UcmFuc2xldE91dHB1dC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA5OTkxMWY5Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvVHJhbnNsZXRPdXRwdXQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE0OCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBUcmFuc2xldE91dHB1dC5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzA1IDA5OjE5OjQ0IHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQ29uc3RhbnRQb29sR2VuOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFU1RBVElDOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFVklSVFVBTDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uTGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlBVU0g7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuQ2xhc3NHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuRXJyb3JNc2c7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuTWV0aG9kR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlN0cmluZ1R5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlQ2hlY2tFcnJvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5VdGlsOwotCi0vKioKLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICovCi1maW5hbCBjbGFzcyBUcmFuc2xldE91dHB1dCBleHRlbmRzIEluc3RydWN0aW9uIHsKLQotICAgIHByaXZhdGUgRXhwcmVzc2lvbiBfZmlsZW5hbWU7Ci0gICAgcHJpdmF0ZSBib29sZWFuIF9hcHBlbmQ7Ci0KLSAgICAvKioKLSAgICAgKiBEaXNwbGF5cyB0aGUgY29udGVudHMgb2YgdGhpcyA8eHNsdGM6b3V0cHV0PiBlbGVtZW50LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGRpc3BsYXkoaW50IGluZGVudCkgewotICAgICAgICBpbmRlbnQoaW5kZW50KTsKLSAgICAgICAgVXRpbC5wcmludGxuKCJUcmFuc2xldE91dHB1dDogIiArIF9maWxlbmFtZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUGFyc2UgdGhlIGNvbnRlbnRzIG9mIHRoaXMgPHhzbHRjOm91dHB1dD4gZWxlbWVudC4gVGhlIG9ubHkgYXR0cmlidXRlCi0gICAgICogd2UgcmVjb2duaXNlIGlzIHRoZSAnZmlsZScgYXR0cmlidXRlIHRoYXQgY29udGFpbnMgdGVoIG91dHB1dCBmaWxlbmFtZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBwYXJzZUNvbnRlbnRzKFBhcnNlciBwYXJzZXIpIHsKLSAgICAgICAgLy8gR2V0IHRoZSBvdXRwdXQgZmlsZW5hbWUgZnJvbSB0aGUgJ2ZpbGUnIGF0dHJpYnV0ZQotICAgICAgICBTdHJpbmcgZmlsZW5hbWUgPSBnZXRBdHRyaWJ1dGUoImZpbGUiKTsKLQotICAgICAgICAvLyBJZiB0aGUgJ2FwcGVuZCcgYXR0cmlidXRlIGlzIHNldCB0byAieWVzIiBvciAidHJ1ZSIsCi0gICAgICAgIC8vIHRoZSBvdXRwdXQgaXMgYXBwZW5kZWQgdG8gdGhlIGZpbGUuCi0gICAgICAgIFN0cmluZyBhcHBlbmQgICA9IGdldEF0dHJpYnV0ZSgiYXBwZW5kIik7Ci0KLSAgICAgICAgLy8gVmVyaWZ5IHRoYXQgdGhlIGZpbGVuYW1lIGlzIGluIGZhY3Qgc2V0Ci0gICAgICAgIGlmICgoZmlsZW5hbWUgPT0gbnVsbCkgfHwgKGZpbGVuYW1lLmVxdWFscyhFTVBUWVNUUklORykpKSB7Ci0gICAgICAgICAgICByZXBvcnRFcnJvcih0aGlzLCBwYXJzZXIsIEVycm9yTXNnLlJFUVVJUkVEX0FUVFJfRVJSLCAiZmlsZSIpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gU2F2ZSBmaWxlbmFtZSBhcyBhbiBhdHRyaWJ1dGUgdmFsdWUgdGVtcGxhdGUKLSAgICAgICAgX2ZpbGVuYW1lID0gQXR0cmlidXRlVmFsdWUuY3JlYXRlKHRoaXMsIGZpbGVuYW1lLCBwYXJzZXIpOwotCi0gICAgICAgIGlmIChhcHBlbmQgIT0gbnVsbCAmJiAoYXBwZW5kLnRvTG93ZXJDYXNlKCkuZXF1YWxzKCJ5ZXMiKSB8fAotICAgICAgICAgICAgYXBwZW5kLnRvTG93ZXJDYXNlKCkuZXF1YWxzKCJ0cnVlIikpKSB7Ci0gICAgICAgICAgX2FwcGVuZCA9IHRydWU7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICAgIF9hcHBlbmQgPSBmYWxzZTsKLQotICAgICAgICBwYXJzZUNoaWxkcmVuKHBhcnNlcik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHlwZSBjaGVja3MgdGhlICdmaWxlJyBhdHRyaWJ1dGUgKG11c3QgYmUgYWJsZSB0byBjb252ZXJ0IGl0IHRvIGEgc3RyKS4KLSAgICAgKi8KLSAgICBwdWJsaWMgVHlwZSB0eXBlQ2hlY2soU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgewotICAgICAgICBmaW5hbCBUeXBlIHR5cGUgPSBfZmlsZW5hbWUudHlwZUNoZWNrKHN0YWJsZSk7Ci0gICAgICAgIGlmICh0eXBlIGluc3RhbmNlb2YgU3RyaW5nVHlwZSA9PSBmYWxzZSkgewotICAgICAgICAgICAgX2ZpbGVuYW1lID0gbmV3IENhc3RFeHByKF9maWxlbmFtZSwgVHlwZS5TdHJpbmcpOwotICAgICAgICB9Ci0gICAgICAgIHR5cGVDaGVja0NvbnRlbnRzKHN0YWJsZSk7Ci0gICAgICAgIHJldHVybiBUeXBlLlZvaWQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29tcGlsZSBjb2RlIHRoYXQgb3BlbnMgdGhlIGdpdmUgZmlsZSBmb3Igb3V0cHV0LCBkdW1wcyB0aGUgY29udGVudHMgb2YKLSAgICAgKiB0aGUgZWxlbWVudCB0byB0aGUgZmlsZSwgdGhlbiBjbG9zZXMgdGhlIGZpbGUuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0gICAgICAgIGZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotICAgICAgICBmaW5hbCBib29sZWFuIGlzU2VjdXJlUHJvY2Vzc2luZyA9IGNsYXNzR2VuLmdldFBhcnNlcigpLmdldFhTTFRDKCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuaXNTZWN1cmVQcm9jZXNzaW5nKCk7Ci0KLSAgICAgICAgaWYgKGlzU2VjdXJlUHJvY2Vzc2luZykgewotICAgICAgICAgICAgaW50IGluZGV4ID0gY3BnLmFkZE1ldGhvZHJlZihCQVNJU19MSUJSQVJZX0NMQVNTLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidW5hbGxvd2VkX2V4dGVuc2lvbl9lbGVtZW50RiIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoTGphdmEvbGFuZy9TdHJpbmc7KVYiKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsICJyZWRpcmVjdCIpKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFU1RBVElDKGluZGV4KSk7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBTYXZlIHRoZSBjdXJyZW50IG91dHB1dCBoYW5kbGVyIG9uIHRoZSBzdGFjawotICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRIYW5kbGVyKCkpOwotCi0gICAgICAgIGZpbmFsIGludCBvcGVuID0gIGNwZy5hZGRNZXRob2RyZWYoVFJBTlNMRVRfQ0xBU1MsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm9wZW5PdXRwdXRIYW5kbGVyIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKCIgKyBTVFJJTkdfU0lHICsgIlopIiArCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJBTlNMRVRfT1VUUFVUX1NJRyk7Ci0KLSAgICAgICAgZmluYWwgaW50IGNsb3NlID0gIGNwZy5hZGRNZXRob2RyZWYoVFJBTlNMRVRfQ0xBU1MsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJjbG9zZU91dHB1dEhhbmRsZXIiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKCIrVFJBTlNMRVRfT1VUUFVUX1NJRysiKVYiKTsKLQotICAgICAgICAvLyBDcmVhdGUgdGhlIG5ldyBvdXRwdXQgaGFuZGxlciAobGVhdmUgaXQgb24gc3RhY2spCi0gICAgICAgIGlsLmFwcGVuZChjbGFzc0dlbi5sb2FkVHJhbnNsZXQoKSk7Ci0gICAgICAgIF9maWxlbmFtZS50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsIF9hcHBlbmQpKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VWSVJUVUFMKG9wZW4pKTsKLQotICAgICAgICAvLyBPdmVyd3JpdGUgY3VycmVudCBoYW5kbGVyCi0gICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4uc3RvcmVIYW5kbGVyKCkpOwotCi0gICAgICAgIC8vIFRyYW5zbGF0ZSBjb250ZW50cyB3aXRoIHN1YnN0aXR1dGVkIGhhbmRsZXIKLSAgICAgICAgdHJhbnNsYXRlQ29udGVudHMoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0KLSAgICAgICAgLy8gQ2xvc2UgdGhlIG91dHB1dCBoYW5kbGVyIChjbG9zZSBmaWxlKQotICAgICAgICBpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpOwotICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRIYW5kbGVyKCkpOwotICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRVZJUlRVQUwoY2xvc2UpKTsKLQotICAgICAgICAvLyBSZXN0b3JlIG9sZCBvdXRwdXQgaGFuZGxlciBmcm9tIHN0YWNrCi0gICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4uc3RvcmVIYW5kbGVyKCkpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvVW5hcnlPcEV4cHIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvVW5hcnlPcEV4cHIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMzY3YjEzYi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL1VuYXJ5T3BFeHByLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5MCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBVbmFyeU9wRXhwci5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzA1IDA5OjIxOjAwIHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW5zdHJ1Y3Rpb25MaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkNsYXNzR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLk1ldGhvZEdlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5NZXRob2RUeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZUNoZWNrRXJyb3I7Ci0KLS8qKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICovCi1maW5hbCBjbGFzcyBVbmFyeU9wRXhwciBleHRlbmRzIEV4cHJlc3Npb24gewotICAgIHByaXZhdGUgRXhwcmVzc2lvbiBfbGVmdDsKLQotICAgIHB1YmxpYyBVbmFyeU9wRXhwcihFeHByZXNzaW9uIGxlZnQpIHsKLSAgICAgICAgKF9sZWZ0ID0gbGVmdCkuc2V0UGFyZW50KHRoaXMpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGlzIGV4cHJlc3Npb25zIGNvbnRhaW5zIGEgY2FsbCB0byBwb3NpdGlvbigpLiBUaGlzIGlzCi0gICAgICogbmVlZGVkIGZvciBjb250ZXh0IGNoYW5nZXMgaW4gbm9kZSBzdGVwcyBjb250YWluaW5nIG11bHRpcGxlIHByZWRpY2F0ZXMuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaGFzUG9zaXRpb25DYWxsKCkgewotICAgICAgICByZXR1cm4oX2xlZnQuaGFzUG9zaXRpb25DYWxsKCkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGlzIGV4cHJlc3Npb25zIGNvbnRhaW5zIGEgY2FsbCB0byBsYXN0KCkKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBoYXNMYXN0Q2FsbCgpIHsKLSAgICAgICAgICAgIHJldHVybihfbGVmdC5oYXNMYXN0Q2FsbCgpKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRQYXJzZXIoUGFyc2VyIHBhcnNlcikgewotICAgICAgICBzdXBlci5zZXRQYXJzZXIocGFyc2VyKTsKLSAgICAgICAgX2xlZnQuc2V0UGFyc2VyKHBhcnNlcik7Ci0gICAgfQotCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLSAgICAgICAgZmluYWwgVHlwZSB0bGVmdCA9IF9sZWZ0LnR5cGVDaGVjayhzdGFibGUpOwotICAgICAgICBmaW5hbCBNZXRob2RUeXBlIHB0eXBlID0gbG9va3VwUHJpbW9wKHN0YWJsZSwgInUtIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgTWV0aG9kVHlwZShUeXBlLlZvaWQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGxlZnQpKTsKLQotICAgICAgICBpZiAocHR5cGUgIT0gbnVsbCkgewotICAgICAgICAgICAgZmluYWwgVHlwZSBhcmcxID0gKFR5cGUpIHB0eXBlLmFyZ3NUeXBlKCkuZWxlbWVudEF0KDApOwotICAgICAgICAgICAgaWYgKCFhcmcxLmlkZW50aWNhbFRvKHRsZWZ0KSkgewotICAgICAgICAgICAgICAgIF9sZWZ0ID0gbmV3IENhc3RFeHByKF9sZWZ0LCBhcmcxKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiBfdHlwZSA9IHB0eXBlLnJlc3VsdFR5cGUoKTsKLSAgICAgICAgfQotCi0gICAgICAgIHRocm93IG5ldyBUeXBlQ2hlY2tFcnJvcih0aGlzKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgICAgICByZXR1cm4gInUtIiArICcoJyArIF9sZWZ0ICsgJyknOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotICAgICAgICBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0gICAgICAgIF9sZWZ0LnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgaWwuYXBwZW5kKF90eXBlLk5FRygpKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL1VuaW9uUGF0aEV4cHIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvVW5pb25QYXRoRXhwci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1Y2IwNmJlLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvVW5pb25QYXRoRXhwci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTQ4ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFVuaW9uUGF0aEV4cHIuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xMiAxMTozNDoxNCBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5Db25zdGFudFBvb2xHZW47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JTlZPS0VJTlRFUkZBQ0U7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JTlZPS0VTUEVDSUFMOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFVklSVFVBTDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uTGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLk5FVzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5DbGFzc0dlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5NZXRob2RHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlQ2hlY2tFcnJvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5BeGlzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTTsKLQotLyoqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKi8KLWZpbmFsIGNsYXNzIFVuaW9uUGF0aEV4cHIgZXh0ZW5kcyBFeHByZXNzaW9uIHsKLQotICAgIHByaXZhdGUgZmluYWwgRXhwcmVzc2lvbiBfcGF0aEV4cHI7Ci0gICAgcHJpdmF0ZSBmaW5hbCBFeHByZXNzaW9uIF9yZXN0OwotICAgIHByaXZhdGUgYm9vbGVhbiBfcmV2ZXJzZSA9IGZhbHNlOwotCi0gICAgLy8gbGluZWFyaXphdGlvbiBmb3IgdG9wIGxldmVsIFVuaW9uUGF0aEV4cHJzCi0gICAgcHJpdmF0ZSBFeHByZXNzaW9uW10gX2NvbXBvbmVudHM7Ci0KLSAgICBwdWJsaWMgVW5pb25QYXRoRXhwcihFeHByZXNzaW9uIHBhdGhFeHByLCBFeHByZXNzaW9uIHJlc3QpIHsKLSAgICAgICAgX3BhdGhFeHByID0gcGF0aEV4cHI7Ci0gICAgICAgIF9yZXN0ICAgICA9IHJlc3Q7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0UGFyc2VyKFBhcnNlciBwYXJzZXIpIHsKLSAgICAgICAgc3VwZXIuc2V0UGFyc2VyKHBhcnNlcik7Ci0gICAgICAgIC8vIGZpbmQgYWxsIGV4cHJlc3Npb25zIGluIHRoaXMgVW5pb24KLSAgICAgICAgZmluYWwgVmVjdG9yIGNvbXBvbmVudHMgPSBuZXcgVmVjdG9yKCk7Ci0gICAgICAgIGZsYXR0ZW4oY29tcG9uZW50cyk7Ci0gICAgICAgIGZpbmFsIGludCBzaXplID0gY29tcG9uZW50cy5zaXplKCk7Ci0gICAgICAgIF9jb21wb25lbnRzID0gKEV4cHJlc3Npb25bXSljb21wb25lbnRzLnRvQXJyYXkobmV3IEV4cHJlc3Npb25bc2l6ZV0pOwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewotICAgICAgICAgICAgX2NvbXBvbmVudHNbaV0uc2V0UGFyc2VyKHBhcnNlcik7Ci0gICAgICAgICAgICBfY29tcG9uZW50c1tpXS5zZXRQYXJlbnQodGhpcyk7Ci0gICAgICAgICAgICBpZiAoX2NvbXBvbmVudHNbaV0gaW5zdGFuY2VvZiBTdGVwKSB7Ci0gICAgICAgICAgICAgICAgZmluYWwgU3RlcCBzdGVwID0gKFN0ZXApX2NvbXBvbmVudHNbaV07Ci0gICAgICAgICAgICAgICAgZmluYWwgaW50IGF4aXMgPSBzdGVwLmdldEF4aXMoKTsKLSAgICAgICAgICAgICAgICBmaW5hbCBpbnQgdHlwZSA9IHN0ZXAuZ2V0Tm9kZVR5cGUoKTsKLSAgICAgICAgICAgICAgICAvLyBQdXQgYXR0cmlidXRlIGl0ZXJhdG9ycyBmaXJzdAotICAgICAgICAgICAgICAgIGlmICgoYXhpcyA9PSBBeGlzLkFUVFJJQlVURSkgfHwgKHR5cGUgPT0gRFRNLkFUVFJJQlVURV9OT0RFKSkgewotICAgICAgICAgICAgICAgICAgICBfY29tcG9uZW50c1tpXSA9IF9jb21wb25lbnRzWzBdOwotICAgICAgICAgICAgICAgICAgICBfY29tcG9uZW50c1swXSA9IHN0ZXA7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIHRoZSB1bmlvbiBjb250YWlucyBhIHJldmVyc2UgaXRlcmF0b3IKLSAgICAgICAgaWYgKEF4aXMuaXNSZXZlcnNlKGF4aXMpKSBfcmV2ZXJzZSA9IHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgLy8gTm8gbmVlZCB0byByZXZlcnNlIGFueXRoaW5nIGlmIGFub3RoZXIgZXhwcmVzc2lvbiBsaWVzIG9uIHRvcCBvZiB0aGlzCi0gICAgICAgIGlmIChnZXRQYXJlbnQoKSBpbnN0YW5jZW9mIEV4cHJlc3Npb24pIF9yZXZlcnNlID0gZmFsc2U7Ci0gICAgfQotCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLSAgICAgICAgZmluYWwgaW50IGxlbmd0aCA9IF9jb21wb25lbnRzLmxlbmd0aDsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykgewotICAgICAgICAgICAgaWYgKF9jb21wb25lbnRzW2ldLnR5cGVDaGVjayhzdGFibGUpICE9IFR5cGUuTm9kZVNldCkgewotICAgICAgICAgICAgICAgIF9jb21wb25lbnRzW2ldID0gbmV3IENhc3RFeHByKF9jb21wb25lbnRzW2ldLCBUeXBlLk5vZGVTZXQpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBfdHlwZSA9IFR5cGUuTm9kZVNldDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgICAgICByZXR1cm4gInVuaW9uKCIgKyBfcGF0aEV4cHIgKyAiLCAiICsgX3Jlc3QgKyAnKSc7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIGZsYXR0ZW4oVmVjdG9yIGNvbXBvbmVudHMpIHsKLSAgICAgICAgY29tcG9uZW50cy5hZGRFbGVtZW50KF9wYXRoRXhwcik7Ci0gICAgICAgIGlmIChfcmVzdCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAoX3Jlc3QgaW5zdGFuY2VvZiBVbmlvblBhdGhFeHByKSB7Ci0gICAgICAgICAgICAgICAgKChVbmlvblBhdGhFeHByKV9yZXN0KS5mbGF0dGVuKGNvbXBvbmVudHMpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgY29tcG9uZW50cy5hZGRFbGVtZW50KF9yZXN0KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotICAgICAgICBmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQotICAgICAgICBmaW5hbCBpbnQgaW5pdCA9IGNwZy5hZGRNZXRob2RyZWYoVU5JT05fSVRFUkFUT1JfQ0xBU1MsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiPGluaXQ+IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoIitET01fSU5URl9TSUcrIilWIik7Ci0gICAgICAgIGZpbmFsIGludCBpdGVyID0gY3BnLmFkZE1ldGhvZHJlZihVTklPTl9JVEVSQVRPUl9DTEFTUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFERF9JVEVSQVRPUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFERF9JVEVSQVRPUl9TSUcpOwotCi0gICAgICAgIC8vIENyZWF0ZSB0aGUgVW5pb25JdGVyYXRvciBhbmQgbGVhdmUgaXQgb24gdGhlIHN0YWNrCi0gICAgICAgIGlsLmFwcGVuZChuZXcgTkVXKGNwZy5hZGRDbGFzcyhVTklPTl9JVEVSQVRPUl9DTEFTUykpKTsKLSAgICAgICAgaWwuYXBwZW5kKERVUCk7Ci0gICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VTUEVDSUFMKGluaXQpKTsKLQotICAgICAgICAvLyBBZGQgdGhlIHZhcmlvdXMgaXRlcmF0b3JzIHRvIHRoZSBVbmlvbkl0ZXJhdG9yCi0gICAgICAgIGZpbmFsIGludCBsZW5ndGggPSBfY29tcG9uZW50cy5sZW5ndGg7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgIF9jb21wb25lbnRzW2ldLnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChpdGVyKSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBPcmRlciB0aGUgaXRlcmF0b3Igb25seSBpZiBzdHJpY3RseSBuZWVkZWQKLSAgICAgICAgaWYgKF9yZXZlcnNlKSB7Ci0gICAgICAgICAgICBmaW5hbCBpbnQgb3JkZXIgPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKERPTV9JTlRGLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPUkRFUl9JVEVSQVRPUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT1JERVJfSVRFUkFUT1JfU0lHKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChTV0FQKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZENvbnRleHROb2RlKCkpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0Uob3JkZXIsIDMpKTsKLQotICAgICAgICB9Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9VbnBhcnNlZEVudGl0eVVyaUNhbGwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvVW5wYXJzZWRFbnRpdHlVcmlDYWxsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGI1NWVkY2YuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9VbnBhcnNlZEVudGl0eVVyaUNhbGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDcyICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFVucGFyc2VkRW50aXR5VXJpQ2FsbC5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzA1IDA5OjIyOjM2IHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkNvbnN0YW50UG9vbEdlbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklOVk9LRUlOVEVSRkFDRTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uTGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5DbGFzc0dlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5NZXRob2RHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuU3RyaW5nVHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGVDaGVja0Vycm9yOwotCi0vKioKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICovCi1maW5hbCBjbGFzcyBVbnBhcnNlZEVudGl0eVVyaUNhbGwgZXh0ZW5kcyBGdW5jdGlvbkNhbGwgewotICAgIHByaXZhdGUgRXhwcmVzc2lvbiBfZW50aXR5OwotCi0gICAgcHVibGljIFVucGFyc2VkRW50aXR5VXJpQ2FsbChRTmFtZSBmbmFtZSwgVmVjdG9yIGFyZ3VtZW50cykgewotICAgICAgICBzdXBlcihmbmFtZSwgYXJndW1lbnRzKTsKLSAgICAgICAgX2VudGl0eSA9IGFyZ3VtZW50KCk7Ci0gICAgfQotCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLSAgICAgICAgZmluYWwgVHlwZSBlbnRpdHkgPSBfZW50aXR5LnR5cGVDaGVjayhzdGFibGUpOwotICAgICAgICBpZiAoZW50aXR5IGluc3RhbmNlb2YgU3RyaW5nVHlwZSA9PSBmYWxzZSkgewotICAgICAgICAgICAgX2VudGl0eSA9IG5ldyBDYXN0RXhwcihfZW50aXR5LCBUeXBlLlN0cmluZyk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIF90eXBlID0gVHlwZS5TdHJpbmc7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0gICAgICAgIGZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotICAgICAgICAvLyBGZWNrIHRoZSB0aGlzIHBvaW50ZXIgb24gdGhlIHN0YWNrLi4uCi0gICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLSAgICAgICAgLy8gLi4udGhlbiB0aGUgZW50aXR5IG5hbWUuLi4KLSAgICAgICAgX2VudGl0eS50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgIC8vIC4uLnRvIGdldCB0aGUgVVJJIGZyb20gdGhlIERPTSBvYmplY3QuCi0gICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFSU5URVJGQUNFKAotICAgICAgICAgICAgICAgICAgICAgICAgIGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoRE9NX0lOVEYsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHRVRfVU5QQVJTRURfRU5USVRZX1VSSSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdFVF9VTlBBUlNFRF9FTlRJVFlfVVJJX1NJRyksCi0gICAgICAgICAgICAgICAgICAgICAgICAgMikpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvVW5yZXNvbHZlZFJlZi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9VbnJlc29sdmVkUmVmLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDk2M2UzYzguLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9VbnJlc29sdmVkUmVmLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMDQgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogVW5yZXNvbHZlZFJlZi5qYXZhLHYgMS41IDIwMDUvMDkvMjggMTM6NDg6MTcgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuQ2xhc3NHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuRXJyb3JNc2c7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuTWV0aG9kR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZUNoZWNrRXJyb3I7Ci0KLS8qKgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKi8KLWZpbmFsIGNsYXNzIFVucmVzb2x2ZWRSZWYgZXh0ZW5kcyBWYXJpYWJsZVJlZkJhc2UgewotCi0gICAgcHJpdmF0ZSBRTmFtZSBfdmFyaWFibGVOYW1lID0gbnVsbDsKLSAgICBwcml2YXRlIFZhcmlhYmxlUmVmQmFzZSBfcmVmID0gbnVsbDsKLQotICAgIHB1YmxpYyBVbnJlc29sdmVkUmVmKFFOYW1lIG5hbWUpIHsKLSAgICAgICAgc3VwZXIoKTsKLSAgICAgICAgX3ZhcmlhYmxlTmFtZSA9IG5hbWU7Ci0gICAgfQotCi0gICAgcHVibGljIFFOYW1lIGdldE5hbWUoKSB7Ci0gICAgICAgIHJldHVybihfdmFyaWFibGVOYW1lKTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIEVycm9yTXNnIHJlcG9ydEVycm9yKCkgewotICAgICAgICBFcnJvck1zZyBlcnIgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuVkFSSUFCTEVfVU5ERUZfRVJSLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3ZhcmlhYmxlTmFtZSwgdGhpcyk7Ci0gICAgICAgIGdldFBhcnNlcigpLnJlcG9ydEVycm9yKENvbnN0YW50cy5FUlJPUiwgZXJyKTsKLSAgICAgICAgcmV0dXJuKGVycik7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBWYXJpYWJsZVJlZkJhc2UgcmVzb2x2ZShQYXJzZXIgcGFyc2VyLCBTeW1ib2xUYWJsZSBzdGFibGUpIHsKLSAgICAgICAgLy8gQXQgdGhpcyBwb2ludCB0aGUgQVNUIGlzIGFscmVhZHkgYnVpbHQgYW5kIHdlIHNob3VsZCBiZSBhYmxlIHRvCi0gICAgICAgIC8vIGZpbmQgYW55IGRlY2xhcmVkIGdsb2JhbCB2YXJpYWJsZSBvciBwYXJhbWV0ZXIKLSAgICAgICAgVmFyaWFibGVCYXNlIHJlZiA9IHBhcnNlci5sb29rdXBWYXJpYWJsZShfdmFyaWFibGVOYW1lKTsKLSAgICAgICAgaWYgKHJlZiA9PSBudWxsKSB7Ci0gICAgICAgICAgICByZWYgPSAoVmFyaWFibGVCYXNlKXN0YWJsZS5sb29rdXBOYW1lKF92YXJpYWJsZU5hbWUpOwotICAgICAgICB9Ci0gICAgICAgIGlmIChyZWYgPT0gbnVsbCkgewotICAgICAgICAgICAgcmVwb3J0RXJyb3IoKTsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gSWYgaW4gYSB0b3AtbGV2ZWwgZWxlbWVudCwgY3JlYXRlIGRlcGVuZGVuY3kgdG8gdGhlIHJlZmVyZW5jZWQgdmFyCi0gICAgICAgIF92YXJpYWJsZSA9IHJlZjsKLSAgICAgICAgYWRkUGFyZW50RGVwZW5kZW5jeSgpOwotCi0gICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBWYXJpYWJsZSkgewotICAgICAgICAgICAgcmV0dXJuIG5ldyBWYXJpYWJsZVJlZigoVmFyaWFibGUpIHJlZik7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAocmVmIGluc3RhbmNlb2YgUGFyYW0pIHsKLSAgICAgICAgICAgIHJldHVybiBuZXcgUGFyYW1ldGVyUmVmKChQYXJhbSlyZWYpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0gICAgICAgIGlmIChfcmVmICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZpbmFsIFN0cmluZyBuYW1lID0gX3ZhcmlhYmxlTmFtZS50b1N0cmluZygpOwotICAgICAgICAgICAgRXJyb3JNc2cgZXJyID0gbmV3IEVycm9yTXNnKEVycm9yTXNnLkNJUkNVTEFSX1ZBUklBQkxFX0VSUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lLCB0aGlzKTsKLSAgICAgICAgfQotICAgICAgICBpZiAoKF9yZWYgPSByZXNvbHZlKGdldFBhcnNlcigpLCBzdGFibGUpKSAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gKF90eXBlID0gX3JlZi50eXBlQ2hlY2soc3RhYmxlKSk7Ci0gICAgICAgIH0KLSAgICAgICAgdGhyb3cgbmV3IFR5cGVDaGVja0Vycm9yKHJlcG9ydEVycm9yKCkpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotICAgICAgICBpZiAoX3JlZiAhPSBudWxsKQotICAgICAgICAgICAgX3JlZi50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICAgIHJlcG9ydEVycm9yKCk7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKLSAgICAgICAgcmV0dXJuICJ1bnJlc29sdmVkLXJlZigpIjsKLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvVW5zdXBwb3J0ZWRFbGVtZW50LmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL1Vuc3VwcG9ydGVkRWxlbWVudC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlNGM4ZTIxLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvVW5zdXBwb3J0ZWRFbGVtZW50LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNTEgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAxNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqLwotLyoKLSAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQotICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCi0gKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCi0gKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAotICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKLSAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBVbnN1cHBvcnRlZEVsZW1lbnQuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8wNSAwOToyNjo1MSBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkNvbnN0YW50UG9vbEdlbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklOVk9LRVNUQVRJQzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uTGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlBVU0g7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuQ2xhc3NHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuRXJyb3JNc2c7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuTWV0aG9kR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZUNoZWNrRXJyb3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVXRpbDsKLWltcG9ydCBqYXZhLnV0aWwuTGlzdDsKLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi0vKioKLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICovCi1maW5hbCBjbGFzcyBVbnN1cHBvcnRlZEVsZW1lbnQgZXh0ZW5kcyBTeW50YXhUcmVlTm9kZSB7Ci0KLSAgICBwcml2YXRlIFZlY3RvciBfZmFsbGJhY2tzID0gbnVsbDsKLSAgICBwcml2YXRlIEVycm9yTXNnIF9tZXNzYWdlID0gbnVsbDsKLSAgICBwcml2YXRlIGJvb2xlYW4gX2lzRXh0ZW5zaW9uID0gZmFsc2U7Ci0KLSAgICAvKioKLSAgICAgKiBCYXNpYyBjb25zdXRyY29yIC0gc3RvcmVzIGVsZW1lbnQgdXJpL3ByZWZpeC9sb2NhbG5hbWUKLSAgICAgKi8KLSAgICBwdWJsaWMgVW5zdXBwb3J0ZWRFbGVtZW50KFN0cmluZyB1cmksIFN0cmluZyBwcmVmaXgsIFN0cmluZyBsb2NhbCwgYm9vbGVhbiBpc0V4dGVuc2lvbikgewotICAgICAgICBzdXBlcih1cmksIHByZWZpeCwgbG9jYWwpOwotICAgICAgICBfaXNFeHRlbnNpb24gPSBpc0V4dGVuc2lvbjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGVyZSBhcmUgZGlmZmVyZW50IGNhdGVnb3JpZXMgb2YgdW5zdXBwb3J0ZWQgZWxlbWVudHMgKGJlbGlldmUgaXQKLSAgICAgKiBvciBub3QpOiB0aGVyZSBhcmUgZWxlbWVudHMgd2l0aGluIHRoZSBYU0xUIG5hbWVzcGFjZSAodGhlc2Ugd291bGQKLSAgICAgKiBiZSBlbGVtZW50cyB0aGF0IGFyZSBub3QgeWV0IGltcGxlbWVudGVkKSwgdGhlcmUgYXJlIGV4dGVuc2lvbnMgb2YKLSAgICAgKiBvdGhlciBYU0xUIHByb2Nlc3NvcnMgYW5kIHRoZXJlIGFyZSB1bnJlY29nbmlzZWQgZXh0ZW5zaW9uIGVsZW1lbnRzCi0gICAgICogb2YgdGhpcyBYU0xUIHByb2Nlc3Nvci4gVGhlIGVycm9yIG1lc3NhZ2UgcGFzc2VkIHRvIHRoaXMgbWV0aG9kCi0gICAgICogc2hvdWxkIGRlc2NyaWJlIHRoZSB1bnN1cHBvcnRlZCBlbGVtZW50IGl0c2VsZiBhbmQgd2hhdCBjYXRlZ29yeQotICAgICAqIHRoZSBlbGVtZW50IGJlbG9uZ3MgaW4uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RXJyb3JNZXNzYWdlKEVycm9yTXNnIG1lc3NhZ2UpIHsKLSAgICAgICAgX21lc3NhZ2UgPSBtZXNzYWdlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIERpc3BsYXlzIHRoZSBjb250ZW50cyBvZiB0aGlzIGVsZW1lbnQKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBkaXNwbGF5KGludCBpbmRlbnQpIHsKLSAgICAgICAgaW5kZW50KGluZGVudCk7Ci0gICAgICAgIFV0aWwucHJpbnRsbigiVW5zdXBwb3J0ZWQgZWxlbWVudCA9ICIgKyBfcW5hbWUuZ2V0TmFtZXNwYWNlKCkgKwotICAgICAgICAgICAgICAgICAgICAgIjoiICsgX3FuYW1lLmdldExvY2FsUGFydCgpKTsKLSAgICAgICAgZGlzcGxheUNvbnRlbnRzKGluZGVudCArIEluZGVudEluY3JlbWVudCk7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBTY2FuIGFuZCBwcm9jZXNzIGFsbCBmYWxsYmFjayBjaGlsZHJlbiBvZiB0aGUgdW5zdXBwb3J0ZWQgZWxlbWVudC4KLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgcHJvY2Vzc0ZhbGxiYWNrcyhQYXJzZXIgcGFyc2VyKSB7Ci0KLSAgICAgICAgTGlzdDxTeW50YXhUcmVlTm9kZT4gY2hpbGRyZW4gPSBnZXRDb250ZW50cygpOwotICAgICAgICBpZiAoY2hpbGRyZW4gIT0gbnVsbCkgewotICAgICAgICAgICAgZmluYWwgaW50IGNvdW50ID0gY2hpbGRyZW4uc2l6ZSgpOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgU3ludGF4VHJlZU5vZGUgY2hpbGQgPSBjaGlsZHJlbi5nZXQoaSk7Ci0gICAgICAgICAgICAgICAgaWYgKGNoaWxkIGluc3RhbmNlb2YgRmFsbGJhY2spIHsKLSAgICAgICAgICAgICAgICAgICAgRmFsbGJhY2sgZmFsbGJhY2sgPSAoRmFsbGJhY2spY2hpbGQ7Ci0gICAgICAgICAgICAgICAgICAgIGZhbGxiYWNrLmFjdGl2YXRlKCk7Ci0gICAgICAgICAgICAgICAgICAgIGZhbGxiYWNrLnBhcnNlQ29udGVudHMocGFyc2VyKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKF9mYWxsYmFja3MgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgX2ZhbGxiYWNrcyA9IG5ldyBWZWN0b3IoKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBfZmFsbGJhY2tzLmFkZEVsZW1lbnQoY2hpbGQpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEZpbmQgYW55IGZhbGxiYWNrIGluIHRoZSBkZXNjZW5kYW50IG5vZGVzOyB0aGVuIGFjdGl2YXRlICYgcGFyc2UgaXQKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBwYXJzZUNvbnRlbnRzKFBhcnNlciBwYXJzZXIpIHsKLSAgICAgICAgcHJvY2Vzc0ZhbGxiYWNrcyhwYXJzZXIpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJ1biB0eXBlIGNoZWNrIG9uIHRoZSBmYWxsYmFjayBlbGVtZW50IChpZiBhbnkpLgotICAgICAqLwotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0gICAgICAgIGlmIChfZmFsbGJhY2tzICE9IG51bGwpIHsKLSAgICAgICAgICAgIGludCBjb3VudCA9IF9mYWxsYmFja3Muc2l6ZSgpOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgRmFsbGJhY2sgZmFsbGJhY2sgPSAoRmFsbGJhY2spX2ZhbGxiYWNrcy5lbGVtZW50QXQoaSk7Ci0gICAgICAgICAgICAgICAgZmFsbGJhY2sudHlwZUNoZWNrKHN0YWJsZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIFR5cGUuVm9pZDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGUgdGhlIGZhbGxiYWNrIGVsZW1lbnQgKGlmIGFueSkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0gICAgICAgIGlmIChfZmFsbGJhY2tzICE9IG51bGwpIHsKLSAgICAgICAgICAgIGludCBjb3VudCA9IF9mYWxsYmFja3Muc2l6ZSgpOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgRmFsbGJhY2sgZmFsbGJhY2sgPSAoRmFsbGJhY2spX2ZhbGxiYWNrcy5lbGVtZW50QXQoaSk7Ci0gICAgICAgICAgICAgICAgZmFsbGJhY2sudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIC8vIFdlIG9ubHkgZ28gaW50byB0aGUgZWxzZSBibG9jayBpbiBmb3J3YXJkLWNvbXBhdGliaWxpdHkgbW9kZSwgd2hlbgotICAgICAgICAvLyB0aGUgdW5zdXBwb3J0ZWQgZWxlbWVudCBoYXMgbm8gZmFsbGJhY2suCi0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgLy8gSWYgdGhlIHVuc3VwcG9ydGVkIGVsZW1lbnQgZG9lcyBub3QgaGF2ZSBhbnkgZmFsbGJhY2sgY2hpbGQsIHRoZW4KLSAgICAgICAgICAgIC8vIGF0IHJ1bnRpbWUsIGEgcnVudGltZSBlcnJvciBzaG91bGQgYmUgcmFpc2VkIHdoZW4gdGhlIHVuc3VwcG9ydGVkCi0gICAgICAgICAgICAvLyBlbGVtZW50IGlzIGluc3RhbnRpYXRlZC4gT3RoZXJ3aXNlLCBubyBlcnJvciBpcyB0aHJvd24uCi0gICAgICAgICAgICBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgICAgICAgICBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0KLSAgICAgICAgICAgIGZpbmFsIGludCB1bnN1cHBvcnRlZEVsZW0gPSBjcGcuYWRkTWV0aG9kcmVmKEJBU0lTX0xJQlJBUllfQ0xBU1MsICJ1bnN1cHBvcnRlZF9FbGVtZW50RiIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKCIgKyBTVFJJTkdfU0lHICsgIlopViIpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgZ2V0UU5hbWUoKS50b1N0cmluZygpKSk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBfaXNFeHRlbnNpb24pKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFU1RBVElDKHVuc3VwcG9ydGVkRWxlbSkpOwotICAgICAgICB9Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9Vc2VBdHRyaWJ1dGVTZXRzLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL1VzZUF0dHJpYnV0ZVNldHMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMzc1MWFlMy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL1VzZUF0dHJpYnV0ZVNldHMuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExOCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBVc2VBdHRyaWJ1dGVTZXRzLmphdmEsdiAxLjUgMjAwNS8wOS8yOCAxMzo0ODoxNyBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBqYXZhLnV0aWwuU3RyaW5nVG9rZW5pemVyOwotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkNvbnN0YW50UG9vbEdlbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklOVk9LRVNQRUNJQUw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JbnN0cnVjdGlvbkxpc3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuQ2xhc3NHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuRXJyb3JNc2c7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuTWV0aG9kR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZUNoZWNrRXJyb3I7Ci0KLS8qKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKi8KLWZpbmFsIGNsYXNzIFVzZUF0dHJpYnV0ZVNldHMgZXh0ZW5kcyBJbnN0cnVjdGlvbiB7Ci0KLSAgICAvLyBPbmx5IGVycm9yIHRoYXQgY2FuIG9jY3VyOgotICAgIHByaXZhdGUgZmluYWwgc3RhdGljIFN0cmluZyBBVFRSX1NFVF9OT1RfRk9VTkQgPQotICAgICAgICAiIjsKLQotICAgIC8vIENvbnRhaW5zIHRoZSBuYW1lcyBvZiBhbGwgcmVmZXJlbmNlcyBhdHRyaWJ1dGUgc2V0cwotICAgIHByaXZhdGUgZmluYWwgVmVjdG9yIF9zZXRzID0gbmV3IFZlY3RvcigyKTsKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHVyIC0gZGVmaW5lIGluaXRpYWwgYXR0cmlidXRlIHNldHMgdG8gdXNlCi0gICAgICovCi0gICAgcHVibGljIFVzZUF0dHJpYnV0ZVNldHMoU3RyaW5nIHNldE5hbWVzLCBQYXJzZXIgcGFyc2VyKSB7Ci0gICAgICAgIHNldFBhcnNlcihwYXJzZXIpOwotICAgICAgICBhZGRBdHRyaWJ1dGVTZXRzKHNldE5hbWVzKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBpcyBtYWRlIHB1YmxpYyB0byBlbmFibGUgYW4gQXR0cmlidXRlU2V0IG9iamVjdCB0byBtZXJnZQotICAgICAqIGl0c2VsZiB3aXRoIGFub3RoZXIgQXR0cmlidXRlU2V0IChpbmNsdWRpbmcgYW55IG90aGVyIEF0dHJpYnV0ZVNldHMKLSAgICAgKiB0aGUgdHdvIG1heSBpbmhlcml0IGZyb20pLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGFkZEF0dHJpYnV0ZVNldHMoU3RyaW5nIHNldE5hbWVzKSB7Ci0gICAgICAgIGlmICgoc2V0TmFtZXMgIT0gbnVsbCkgJiYgKCFzZXROYW1lcy5lcXVhbHMoQ29uc3RhbnRzLkVNUFRZU1RSSU5HKSkpIHsKLSAgICAgICAgICAgIGZpbmFsIFN0cmluZ1Rva2VuaXplciB0b2tlbnMgPSBuZXcgU3RyaW5nVG9rZW5pemVyKHNldE5hbWVzKTsKLSAgICAgICAgICAgIHdoaWxlICh0b2tlbnMuaGFzTW9yZVRva2VucygpKSB7Ci0gICAgICAgICAgICAgICAgZmluYWwgUU5hbWUgcW5hbWUgPQotICAgICAgICAgICAgICAgICAgICBnZXRQYXJzZXIoKS5nZXRRTmFtZUlnbm9yZURlZmF1bHROcyh0b2tlbnMubmV4dFRva2VuKCkpOwotICAgICAgICAgICAgICAgIF9zZXRzLmFkZChxbmFtZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBEbyBuYWRhLgotICAgICAqLwotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0gICAgICAgIHJldHVybiBUeXBlLlZvaWQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2VuZXJhdGUgYSBjYWxsIHRvIHRoZSBtZXRob2QgY29tcGlsZWQgZm9yIHRoaXMgYXR0cmlidXRlIHNldAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCi0gICAgICAgIGZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotICAgICAgICBmaW5hbCBTeW1ib2xUYWJsZSBzeW1ib2xUYWJsZSA9IGdldFBhcnNlcigpLmdldFN5bWJvbFRhYmxlKCk7Ci0KLSAgICAgICAgLy8gR28gdGhyb3VnaCBlYWNoIGF0dHJpYnV0ZSBzZXQgYW5kIGdlbmVyYXRlIGEgbWV0aG9kIGNhbGwKLSAgICAgICAgZm9yIChpbnQgaT0wOyBpPF9zZXRzLnNpemUoKTsgaSsrKSB7Ci0gICAgICAgICAgICAvLyBHZXQgdGhlIGF0dHJpYnV0ZSBzZXQgbmFtZQotICAgICAgICAgICAgZmluYWwgUU5hbWUgbmFtZSA9IChRTmFtZSlfc2V0cy5lbGVtZW50QXQoaSk7Ci0gICAgICAgICAgICAvLyBHZXQgdGhlIEF0dHJpYnV0ZVNldCByZWZlcmVuY2UgZnJvbSB0aGUgc3ltYm9sIHRhYmxlCi0gICAgICAgICAgICBmaW5hbCBBdHRyaWJ1dGVTZXQgYXR0cnMgPSBzeW1ib2xUYWJsZS5sb29rdXBBdHRyaWJ1dGVTZXQobmFtZSk7Ci0gICAgICAgICAgICAvLyBDb21waWxlIHRoZSBjYWxsIHRvIHRoZSBzZXQncyBtZXRob2QgaWYgdGhlIHNldCBleGlzdHMKLSAgICAgICAgICAgIGlmIChhdHRycyAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIG1ldGhvZE5hbWUgPSBhdHRycy5nZXRNZXRob2ROYW1lKCk7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKGNsYXNzR2VuLmxvYWRUcmFuc2xldCgpKTsKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkSXRlcmF0b3IoKSk7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkSGFuZGxlcigpKTsKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRDdXJyZW50Tm9kZSgpKTsKLSAgICAgICAgICAgICAgICBmaW5hbCBpbnQgbWV0aG9kID0gY3BnLmFkZE1ldGhvZHJlZihjbGFzc0dlbi5nZXRDbGFzc05hbWUoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRob2ROYW1lLCBBVFRSX1NFVF9TSUcpOwotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFU1BFQ0lBTChtZXRob2QpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIEdlbmVyYXRlIGFuIGVycm9yIGlmIHRoZSBhdHRyaWJ1dGUgc2V0IGRvZXMgbm90IGV4aXN0Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBmaW5hbCBQYXJzZXIgcGFyc2VyID0gZ2V0UGFyc2VyKCk7Ci0gICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIGF0cnMgPSBuYW1lLnRvU3RyaW5nKCk7Ci0gICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IodGhpcywgcGFyc2VyLCBFcnJvck1zZy5BVFRSSUJTRVRfVU5ERUZfRVJSLCBhdHJzKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvVmFsdWVPZi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9WYWx1ZU9mLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDk4NzNlZGQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9WYWx1ZU9mLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNDAgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogVmFsdWVPZi5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzA1IDA5OjMwOjA0IHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQ29uc3RhbnRQb29sR2VuOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFSU5URVJGQUNFOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFVklSVFVBTDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uTGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlBVU0g7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuQ2xhc3NHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuRXJyb3JNc2c7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuTWV0aG9kR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZUNoZWNrRXJyb3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVXRpbDsKLQotLyoqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqLwotZmluYWwgY2xhc3MgVmFsdWVPZiBleHRlbmRzIEluc3RydWN0aW9uIHsKLSAgICBwcml2YXRlIEV4cHJlc3Npb24gX3NlbGVjdDsKLSAgICBwcml2YXRlIGJvb2xlYW4gX2VzY2FwaW5nID0gdHJ1ZTsKLSAgICBwcml2YXRlIGJvb2xlYW4gX2lzU3RyaW5nID0gZmFsc2U7Ci0KLSAgICBwdWJsaWMgdm9pZCBkaXNwbGF5KGludCBpbmRlbnQpIHsKLSAgICAgICAgaW5kZW50KGluZGVudCk7Ci0gICAgICAgIFV0aWwucHJpbnRsbigiVmFsdWVPZiIpOwotICAgICAgICBpbmRlbnQoaW5kZW50ICsgSW5kZW50SW5jcmVtZW50KTsKLSAgICAgICAgVXRpbC5wcmludGxuKCJzZWxlY3QgIiArIF9zZWxlY3QudG9TdHJpbmcoKSk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgcGFyc2VDb250ZW50cyhQYXJzZXIgcGFyc2VyKSB7Ci0gICAgICAgIF9zZWxlY3QgPSBwYXJzZXIucGFyc2VFeHByZXNzaW9uKHRoaXMsICJzZWxlY3QiLCBudWxsKTsKLQotICAgICAgICAvLyBtYWtlIHN1cmUgcmVxdWlyZWQgYXR0cmlidXRlKHMpIGhhdmUgYmVlbiBzZXQKLSAgICAgICAgaWYgKF9zZWxlY3QuaXNEdW1teSgpKSB7Ci0gICAgICAgICAgICByZXBvcnRFcnJvcih0aGlzLCBwYXJzZXIsIEVycm9yTXNnLlJFUVVJUkVEX0FUVFJfRVJSLCAic2VsZWN0Iik7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLSAgICAgICAgZmluYWwgU3RyaW5nIHN0ciA9IGdldEF0dHJpYnV0ZSgiZGlzYWJsZS1vdXRwdXQtZXNjYXBpbmciKTsKLSAgICAgICAgaWYgKChzdHIgIT0gbnVsbCkgJiYgKHN0ci5lcXVhbHMoInllcyIpKSkgX2VzY2FwaW5nID0gZmFsc2U7Ci0gICAgfQotCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLSAgICAgICAgVHlwZSB0eXBlID0gX3NlbGVjdC50eXBlQ2hlY2soc3RhYmxlKTsKLQotICAgICAgICAvLyBQcmVmZXIgdG8gaGFuZGxlIHRoZSB2YWx1ZSBhcyBhIG5vZGU7IGZhbGwgYmFjayB0byBTdHJpbmcsIG90aGVyd2lzZQotICAgICAgICBpZiAodHlwZSAhPSBudWxsICYmICF0eXBlLmlkZW50aWNhbFRvKFR5cGUuTm9kZSkpIHsKLSAgICAgICAgICAgIC8qKioKLSAgICAgICAgICAgICAqKiogJUhaJSBXb3VsZCBsaWtlIHRvIHRyZWF0IHJlc3VsdC10cmVlIGZyYWdtZW50cyBpbiB0aGUgc2FtZQotICAgICAgICAgICAgICoqKiAlSFolIHdheSBhcyBub2RlIHNldHMgZm9yIHZhbHVlLW9mLCBidXQgdGhhdCdzIHJ1bm5pbmcgaW50bwotICAgICAgICAgICAgICoqKiAlSFolIHNvbWUgc25hZ3MuICBJbnN0ZWFkLCB0aGV5J2xsIGJlIGNvbnZlcnRlZCB0byBTdHJpbmcKLSAgICAgICAgICAgIGlmICh0eXBlLmlkZW50aWNhbFRvKFR5cGUuUmVzdWx0VHJlZSkpIHsKLSAgICAgICAgICAgICAgICBfc2VsZWN0ID0gbmV3IENhc3RFeHByKG5ldyBDYXN0RXhwcihfc2VsZWN0LCBUeXBlLk5vZGVTZXQpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHlwZS5Ob2RlKTsKLSAgICAgICAgICAgIH0gZWxzZQotICAgICAgICAgICAgKioqLwotICAgICAgICAgICAgaWYgKHR5cGUuaWRlbnRpY2FsVG8oVHlwZS5Ob2RlU2V0KSkgewotICAgICAgICAgICAgICAgIF9zZWxlY3QgPSBuZXcgQ2FzdEV4cHIoX3NlbGVjdCwgVHlwZS5Ob2RlKTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgX2lzU3RyaW5nID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICBpZiAoIXR5cGUuaWRlbnRpY2FsVG8oVHlwZS5TdHJpbmcpKSB7Ci0gICAgICAgICAgICAgICAgICAgIF9zZWxlY3QgPSBuZXcgQ2FzdEV4cHIoX3NlbGVjdCwgVHlwZS5TdHJpbmcpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBfaXNTdHJpbmcgPSB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBUeXBlLlZvaWQ7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0gICAgICAgIGZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotICAgICAgICBmaW5hbCBpbnQgc2V0RXNjYXBpbmcgPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKE9VVFBVVF9IQU5ETEVSLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJzZXRFc2NhcGluZyIsIihaKVoiKTsKLQotICAgICAgICAvLyBUdXJuIG9mZiBjaGFyYWN0ZXIgZXNjYXBpbmcgaWYgc28gaXMgd2FudGVkLgotICAgICAgICBpZiAoIV9lc2NhcGluZykgewotICAgICAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkSGFuZGxlcigpKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsZmFsc2UpKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFSU5URVJGQUNFKHNldEVzY2FwaW5nLDIpKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIFRyYW5zbGF0ZSB0aGUgY29udGVudHMuICBJZiB0aGUgdmFsdWUgaXMgYSBzdHJpbmcsIHVzZSB0aGUKLSAgICAgICAgLy8gdHJhbnNsZXQuY2hhcmFjdGVycyhTdHJpbmcsIFRyYW5zbGF0T3V0cHV0SGFuZGxlcikgbWV0aG9kLgotICAgICAgICAvLyBPdGhlcndpc2UsIHRoZSB2YWx1ZSBpcyBhIG5vZGUsIGFuZCB0aGUKLSAgICAgICAgLy8gZG9tLmNoYXJhY3RlcnMoaW50IG5vZGUsIFRyYW5zbGV0T3V0cHV0SGFuZGxlcikgbWV0aG9kIGNhbiBkaXNwYXRjaAotICAgICAgICAvLyB0aGUgc3RyaW5nIHZhbHVlIG9mIHRoZSBub2RlIHRvIHRoZSBvdXRwdXQgaGFuZGxlciBtb3JlIGVmZmljaWVudGx5LgotICAgICAgICBpZiAoX2lzU3RyaW5nKSB7Ci0gICAgICAgICAgICBmaW5hbCBpbnQgY2hhcmFjdGVycyA9IGNwZy5hZGRNZXRob2RyZWYoVFJBTlNMRVRfQ0xBU1MsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ0hBUkFDVEVSU1csCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ0hBUkFDVEVSU1dfU0lHKTsKLQotICAgICAgICAgICAgaWwuYXBwZW5kKGNsYXNzR2VuLmxvYWRUcmFuc2xldCgpKTsKLSAgICAgICAgICAgIF9zZWxlY3QudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkSGFuZGxlcigpKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChjaGFyYWN0ZXJzKSk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBmaW5hbCBpbnQgY2hhcmFjdGVycyA9IGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoRE9NX0lOVEYsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ0hBUkFDVEVSUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDSEFSQUNURVJTX1NJRyk7Ci0KLSAgICAgICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLSAgICAgICAgICAgIF9zZWxlY3QudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkSGFuZGxlcigpKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFSU5URVJGQUNFKGNoYXJhY3RlcnMsIDMpKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIFJlc3RvcmUgY2hhcmFjdGVyIGVzY2FwaW5nIHNldHRpbmcgdG8gd2hhdGV2ZXIgaXQgd2FzLgotICAgICAgICBpZiAoIV9lc2NhcGluZykgewotICAgICAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkSGFuZGxlcigpKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChTV0FQKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFSU5URVJGQUNFKHNldEVzY2FwaW5nLDIpKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChQT1ApOwotICAgICAgICB9Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9WYXJpYWJsZS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9WYXJpYWJsZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzMjI2YTM2Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvVmFyaWFibGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIwNSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBWYXJpYWJsZS5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzEyIDExOjM2OjQ2IHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmNsYXNzZmlsZS5GaWVsZDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkFDT05TVF9OVUxMOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQ29uc3RhbnRQb29sR2VuOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuRENPTlNUOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSUNPTlNUOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW5zdHJ1Y3Rpb25IYW5kbGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JbnN0cnVjdGlvbkxpc3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5QVVRGSUVMRDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5Cb29sZWFuVHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5DbGFzc0dlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5FcnJvck1zZzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5JbnRUeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLk1ldGhvZEdlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5Ob2RlVHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5SZWFsVHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGVDaGVja0Vycm9yOwotCi1maW5hbCBjbGFzcyBWYXJpYWJsZSBleHRlbmRzIFZhcmlhYmxlQmFzZSB7Ci0KLSAgICBwdWJsaWMgaW50IGdldEluZGV4KCkgewotICAgICAgICByZXR1cm4gKF9sb2NhbCAhPSBudWxsKSA/IF9sb2NhbC5nZXRJbmRleCgpIDogLTE7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUGFyc2UgdGhlIGNvbnRlbnRzIG9mIHRoZSB2YXJpYWJsZQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHBhcnNlQ29udGVudHMoUGFyc2VyIHBhcnNlcikgewotICAgICAgICAvLyBQYXJzZSAnbmFtZScgYW5kICdzZWxlY3QnIGF0dHJpYnV0ZXMgcGx1cyBwYXJhbWV0ZXIgY29udGVudHMKLSAgICAgICAgc3VwZXIucGFyc2VDb250ZW50cyhwYXJzZXIpOwotCi0gICAgICAgIC8vIEFkZCBhIHJlZiB0byB0aGlzIHZhciB0byBpdHMgZW5jbG9zaW5nIGNvbnN0cnVjdAotICAgICAgICBTeW50YXhUcmVlTm9kZSBwYXJlbnQgPSBnZXRQYXJlbnQoKTsKLSAgICAgICAgaWYgKHBhcmVudCBpbnN0YW5jZW9mIFN0eWxlc2hlZXQpIHsKLSAgICAgICAgICAgIC8vIE1hcmsgdGhpcyBhcyBhIGdsb2JhbCB2YXJpYWJsZQotICAgICAgICAgICAgX2lzTG9jYWwgPSBmYWxzZTsKLSAgICAgICAgICAgIC8vIENoZWNrIGlmIGEgZ2xvYmFsIHZhcmlhYmxlIHdpdGggdGhpcyBuYW1lIGFscmVhZHkgZXhpc3RzLi4uCi0gICAgICAgICAgICBWYXJpYWJsZSB2YXIgPSBwYXJzZXIuZ2V0U3ltYm9sVGFibGUoKS5sb29rdXBWYXJpYWJsZShfbmFtZSk7Ci0gICAgICAgICAgICAvLyAuLi5hbmQgaWYgaXQgZG9lcyB3ZSBuZWVkIHRvIGNoZWNrIGltcG9ydCBwcmVjZWRlbmNlCi0gICAgICAgICAgICBpZiAodmFyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmaW5hbCBpbnQgdXMgPSB0aGlzLmdldEltcG9ydFByZWNlZGVuY2UoKTsKLSAgICAgICAgICAgICAgICBmaW5hbCBpbnQgdGhlbSA9IHZhci5nZXRJbXBvcnRQcmVjZWRlbmNlKCk7Ci0gICAgICAgICAgICAgICAgLy8gSXQgaXMgYW4gZXJyb3IgaWYgdGhlIHR3byBoYXZlIHRoZSBzYW1lIGltcG9ydCBwcmVjZWRlbmNlCi0gICAgICAgICAgICAgICAgaWYgKHVzID09IHRoZW0pIHsKLSAgICAgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIG5hbWUgPSBfbmFtZS50b1N0cmluZygpOwotICAgICAgICAgICAgICAgICAgICByZXBvcnRFcnJvcih0aGlzLCBwYXJzZXIsIEVycm9yTXNnLlZBUklBQkxFX1JFREVGX0VSUixuYW1lKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLy8gSWdub3JlIHRoaXMgaWYgcHJldmlvdXMgZGVmaW5pdGlvbiBoYXMgaGlnaGVyIHByZWNlZGVuY2UKLSAgICAgICAgICAgICAgICBlbHNlIGlmICh0aGVtID4gdXMpIHsKLSAgICAgICAgICAgICAgICAgICAgX2lnbm9yZSA9IHRydWU7Ci0gICAgICAgICAgICAgICAgICAgIGNvcHlSZWZlcmVuY2VzKHZhcik7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIHZhci5jb3B5UmVmZXJlbmNlcyh0aGlzKTsKLSAgICAgICAgICAgICAgICAgICAgdmFyLmRpc2FibGUoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLy8gQWRkIHRoaXMgdmFyaWFibGUgaWYgd2UgaGF2ZSBoaWdoZXIgcHJlY2VkZW5jZQotICAgICAgICAgICAgfQotICAgICAgICAgICAgKChTdHlsZXNoZWV0KXBhcmVudCkuYWRkVmFyaWFibGUodGhpcyk7Ci0gICAgICAgICAgICBwYXJzZXIuZ2V0U3ltYm9sVGFibGUoKS5hZGRWYXJpYWJsZSh0aGlzKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIF9pc0xvY2FsID0gdHJ1ZTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJ1bnMgYSB0eXBlIGNoZWNrIG9uIGVpdGhlciB0aGUgdmFyaWFibGUgZWxlbWVudCBib2R5IG9yIHRoZQotICAgICAqIGV4cHJlc3Npb24gaW4gdGhlICdzZWxlY3QnIGF0dHJpYnV0ZQotICAgICAqLwotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0KLSAgICAgICAgLy8gVHlwZSBjaGVjayB0aGUgJ3NlbGVjdCcgZXhwcmVzc2lvbiBpZiBwcmVzZW50Ci0gICAgICAgIGlmIChfc2VsZWN0ICE9IG51bGwpIHsKLSAgICAgICAgICAgIF90eXBlID0gX3NlbGVjdC50eXBlQ2hlY2soc3RhYmxlKTsKLSAgICAgICAgfQotICAgICAgICAvLyBUeXBlIGNoZWNrIHRoZSBlbGVtZW50IGNvbnRlbnRzIG90aGVyd2lzZQotICAgICAgICBlbHNlIGlmIChoYXNDb250ZW50cygpKSB7Ci0gICAgICAgICAgICB0eXBlQ2hlY2tDb250ZW50cyhzdGFibGUpOwotICAgICAgICAgICAgX3R5cGUgPSBUeXBlLlJlc3VsdFRyZWU7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBfdHlwZSA9IFR5cGUuUmVmZXJlbmNlOwotICAgICAgICB9Ci0gICAgICAgIC8vIFRoZSByZXR1cm4gdHlwZSBpcyB2b2lkIGFzIHRoZSB2YXJpYWJsZSBlbGVtZW50IGRvZXMgbm90IGxlYXZlCi0gICAgICAgIC8vIGFueXRoaW5nIG9uIHRoZSBKVk0ncyBzdGFjay4gVGhlICdfdHlwZScgZ2xvYmFsIHdpbGwgYmUgcmV0dXJuZWQKLSAgICAgICAgLy8gYnkgdGhlIHJlZmVyZW5jZXMgdG8gdGhpcyB2YXJpYWJsZSwgYW5kIG5vdCBieSB0aGUgdmFyaWFibGUgaXRzZWxmLgotICAgICAgICByZXR1cm4gVHlwZS5Wb2lkOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIGlzIHBhcnQgb2YgYSBsaXR0bGUgdHJpY2sgdGhhdCBpcyBuZWVkZWQgdG8gdXNlIGxvY2FsCi0gICAgICogdmFyaWFibGVzIGluc2lkZSBuZXN0ZWQgZm9yLWVhY2ggbG9vcHMuIFNlZSB0aGUgaW5pdGlhbGl6ZVZhcmlhYmxlcygpCi0gICAgICogbWV0aG9kIGluIHRoZSBGb3JFYWNoIGNsYXNzIGZvciBhbiBleHBsYW5hdGlvbgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGluaXRpYWxpemUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLSAgICAgICAgZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0KLSAgICAgICAgLy8gVGhpcyBpcyBvbmx5IGRvbmUgZm9yIGxvY2FsIHZhcmlhYmxlcyB0aGF0IGFyZSBhY3R1YWxseSB1c2VkCi0gICAgICAgIGlmIChpc0xvY2FsKCkgJiYgIV9yZWZzLmlzRW1wdHkoKSkgewotICAgICAgICAgICAgLy8gQ3JlYXRlIGEgdmFyaWFibGUgc2xvdCBpZiBub25lIGlzIGFsbG9jYXRlZAotICAgICAgICAgICAgaWYgKF9sb2NhbCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgX2xvY2FsID0gbWV0aG9kR2VuLmFkZExvY2FsVmFyaWFibGUyKGdldEVzY2FwZWROYW1lKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF90eXBlLnRvSkNUeXBlKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gUHVzaCB0aGUgZGVmYXVsdCB2YWx1ZSBvbiB0aGUgSlZNJ3Mgc3RhY2sKLSAgICAgICAgICAgIGlmICgoX3R5cGUgaW5zdGFuY2VvZiBJbnRUeXBlKSB8fAotICAgICAgICAgICAgICAgIChfdHlwZSBpbnN0YW5jZW9mIE5vZGVUeXBlKSB8fAotICAgICAgICAgICAgICAgIChfdHlwZSBpbnN0YW5jZW9mIEJvb2xlYW5UeXBlKSkKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQobmV3IElDT05TVCgwKSk7IC8vIDAgZm9yIG5vZGUtaWQsIGludGVnZXIgYW5kIGJvb2xlYW4KLSAgICAgICAgICAgIGVsc2UgaWYgKF90eXBlIGluc3RhbmNlb2YgUmVhbFR5cGUpCi0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBEQ09OU1QoMCkpOyAvLyAwLjAgZm9yIGZsb2F0aW5nIHBvaW50IG51bWJlcnMKLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQobmV3IEFDT05TVF9OVUxMKCkpOyAvLyBhbmQgJ251bGwnIGZvciBhbnl0aGluZyBlbHNlCi0KLSAgICAgICAgICAgIC8vIE1hcmsgdGhlIHN0b3JlIGFzIHRoZSBzdGFydCBvZiB0aGUgbGl2ZSByYW5nZSBvZiB0aGUgdmFyaWFibGUKLSAgICAgICAgICAgIF9sb2NhbC5zZXRTdGFydChpbC5hcHBlbmQoX3R5cGUuU1RPUkUoX2xvY2FsLmdldEluZGV4KCkpKSk7Ci0KLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotICAgICAgICBmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQotICAgICAgICAvLyBEb24ndCBnZW5lcmF0ZSBjb2RlIGZvciB1bnJlZmVyZW5jZWQgdmFyaWFibGVzCi0gICAgICAgIGlmIChfcmVmcy5pc0VtcHR5KCkpIHsKLSAgICAgICAgICAgIF9pZ25vcmUgPSB0cnVlOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gTWFrZSBzdXJlIHRoYXQgYSB2YXJpYWJsZSBpbnN0YW5jZSBpcyBvbmx5IGNvbXBpbGVkIG9uY2UKLSAgICAgICAgaWYgKF9pZ25vcmUpIHJldHVybjsKLSAgICAgICAgX2lnbm9yZSA9IHRydWU7Ci0KLSAgICAgICAgZmluYWwgU3RyaW5nIG5hbWUgPSBnZXRFc2NhcGVkTmFtZSgpOwotCi0gICAgICAgIGlmIChpc0xvY2FsKCkpIHsKLSAgICAgICAgICAgIC8vIENvbXBpbGUgdmFyaWFibGUgdmFsdWUgY29tcHV0YXRpb24KLSAgICAgICAgICAgIHRyYW5zbGF0ZVZhbHVlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCi0gICAgICAgICAgICAvLyBBZGQgYSBuZXcgbG9jYWwgdmFyaWFibGUgYW5kIHN0b3JlIHZhbHVlCi0gICAgICAgICAgICBib29sZWFuIGNyZWF0ZUxvY2FsID0gX2xvY2FsID09IG51bGw7Ci0gICAgICAgICAgICBpZiAoY3JlYXRlTG9jYWwpIHsKLSAgICAgICAgICAgICAgICBtYXBSZWdpc3RlcihtZXRob2RHZW4pOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgSW5zdHJ1Y3Rpb25IYW5kbGUgc3RvcmVJbnN0ID0KLSAgICAgICAgICAgIGlsLmFwcGVuZChfdHlwZS5TVE9SRShfbG9jYWwuZ2V0SW5kZXgoKSkpOwotCi0gICAgICAgICAgICAvLyBJZiB0aGUgbG9jYWwgaXMganVzdCBiZWluZyBjcmVhdGVkLCBtYXJrIHRoZSBzdG9yZSBhcyB0aGUgc3RhcnQKLSAgICAgICAgICAgIC8vIG9mIGl0cyBsaXZlIHJhbmdlLiAgTm90ZSB0aGF0IGl0IG1pZ2h0IGhhdmUgYmVlbiBjcmVhdGVkIGJ5Ci0gICAgICAgICAgICAvLyBpbml0aWFsaXplVmFyaWFibGVzIGFscmVhZHksIHdoaWNoIHdvdWxkIGhhdmUgc2V0IHRoZSBzdGFydCBvZgotICAgICAgICAgICAgLy8gdGhlIGxpdmUgcmFuZ2UgYWxyZWFkeS4KLSAgICAgICAgICAgIGlmIChjcmVhdGVMb2NhbCkgewotICAgICAgICAgICAgICAgIF9sb2NhbC5zZXRTdGFydChzdG9yZUluc3QpOwotICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBTdHJpbmcgc2lnbmF0dXJlID0gX3R5cGUudG9TaWduYXR1cmUoKTsKLQotICAgICAgICAgICAgLy8gR2xvYmFsIHZhcmlhYmxlcyBhcmUgc3RvcmUgaW4gY2xhc3MgZmllbGRzCi0gICAgICAgICAgICBpZiAoY2xhc3NHZW4uY29udGFpbnNGaWVsZChuYW1lKSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgY2xhc3NHZW4uYWRkRmllbGQobmV3IEZpZWxkKEFDQ19QVUJMSUMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNwZy5hZGRVdGY4KG5hbWUpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjcGcuYWRkVXRmOChzaWduYXR1cmUpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLCBjcGcuZ2V0Q29uc3RhbnRQb29sKCkpKTsKLQotICAgICAgICAgICAgICAgIC8vIFB1c2ggYSByZWZlcmVuY2UgdG8gInRoaXMiIGZvciBwdXRmaWVsZAotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChjbGFzc0dlbi5sb2FkVHJhbnNsZXQoKSk7Ci0gICAgICAgICAgICAgICAgLy8gQ29tcGlsZSB2YXJpYWJsZSB2YWx1ZSBjb21wdXRhdGlvbgotICAgICAgICAgICAgICAgIHRyYW5zbGF0ZVZhbHVlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICAgICAgICAgIC8vIFN0b3JlIHRoZSB2YXJpYWJsZSBpbiB0aGUgYWxsb2NhdGVkIGZpZWxkCi0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBQVVRGSUVMRChjcGcuYWRkRmllbGRyZWYoY2xhc3NHZW4uZ2V0Q2xhc3NOYW1lKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSwgc2lnbmF0dXJlKSkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9WYXJpYWJsZUJhc2UuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvVmFyaWFibGVCYXNlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAyZTFhNWYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9WYXJpYWJsZUJhc2UuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI5OSArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDE2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5DSEVDS0NBU1Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5Db25zdGFudFBvb2xHZW47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JbnN0cnVjdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uTGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklOVk9LRUlOVEVSRkFDRTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklOVk9LRVNQRUNJQUw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JTlZPS0VWSVJUVUFMOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuTG9jYWxWYXJpYWJsZUdlbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLk5FVzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlBVU0g7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuQ2xhc3NHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuRXJyb3JNc2c7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuTWV0aG9kR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLk5vZGVTZXRUeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlJlc3VsdFRyZWVUeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVXRpbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLlhNTDExQ2hhcjsKLQotLyoqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqIEBhdXRob3IgRXJ3aW4gQm9sd2lkdCA8ZWpiQGtsb21wLm9yZz4KLSAqIEBhdXRob3IgSm9obiBIb3dhcmQgPEpvaG5IQHNjaGVtYXNvZnQuY29tPgotICovCi1jbGFzcyBWYXJpYWJsZUJhc2UgZXh0ZW5kcyBUb3BMZXZlbEVsZW1lbnQgewotCi0gICAgcHJvdGVjdGVkIFFOYW1lICAgICAgIF9uYW1lOyAgICAgICAgICAgICAvLyBUaGUgbmFtZSBvZiB0aGUgdmFyaWFibGUuCi0gICAgcHJvdGVjdGVkIFN0cmluZyAgICAgIF9lc2NhcGVkTmFtZTsgICAgICAvLyBUaGUgZXNjYXBlZCBxbmFtZSBvZiB0aGUgdmFyaWFibGUuCi0gICAgcHJvdGVjdGVkIFR5cGUgICAgICAgIF90eXBlOyAgICAgICAgICAgICAvLyBUaGUgdHlwZSBvZiB0aGlzIHZhcmlhYmxlLgotICAgIHByb3RlY3RlZCBib29sZWFuICAgICBfaXNMb2NhbDsgICAgICAgICAgLy8gVHJ1ZSBpZiB0aGUgdmFyaWFibGUgaXMgbG9jYWwuCi0gICAgcHJvdGVjdGVkIExvY2FsVmFyaWFibGVHZW4gX2xvY2FsOyAgICAgICAvLyBSZWZlcmVuY2UgdG8gSlZNIHZhcmlhYmxlCi0gICAgcHJvdGVjdGVkIEluc3RydWN0aW9uIF9sb2FkSW5zdHJ1Y3Rpb247ICAvLyBJbnN0cnVjdGlvbiB0byBsb2FkIEpWTSB2YXJpYWJsZQotICAgIHByb3RlY3RlZCBJbnN0cnVjdGlvbiBfc3RvcmVJbnN0cnVjdGlvbjsgLy8gSW5zdHJ1Y3Rpb24gdG8gbG9hZCBKVk0gdmFyaWFibGUKLSAgICBwcm90ZWN0ZWQgRXhwcmVzc2lvbiAgX3NlbGVjdDsgICAgICAgICAgIC8vIFJlZmVyZW5jZSB0byB2YXJpYWJsZSBleHByZXNzaW9uCi0gICAgcHJvdGVjdGVkIFN0cmluZyAgICAgIHNlbGVjdDsgICAgICAgICAgICAvLyBUZXh0dWFsIHJlcHIuIG9mIHZhcmlhYmxlIGV4cHIuCi0KLSAgICAvLyBSZWZlcmVuY2VzIHRvIHRoaXMgdmFyaWFibGUgKHdoZW4gbG9jYWwpCi0gICAgcHJvdGVjdGVkIFZlY3RvcjxWYXJpYWJsZVJlZkJhc2U+IF9yZWZzID0gbmV3IFZlY3Rvcjw+KDIpOwotCi0gICAgLy8gVXNlZCB0byBtYWtlIHN1cmUgcGFyYW1ldGVyIGZpZWxkIGlzIG5vdCBhZGRlZCB0d2ljZQotICAgIHByb3RlY3RlZCBib29sZWFuICAgIF9pZ25vcmUgPSBmYWxzZTsKLQotICAgIC8qKgotICAgICAqIERpc2FibGUgdGhpcyB2YXJpYWJsZS9wYXJhbWV0ZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBkaXNhYmxlKCkgewotICAgICAgICBfaWdub3JlID0gdHJ1ZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBZGQgYSByZWZlcmVuY2UgdG8gdGhpcyB2YXJpYWJsZS4gQ2FsbGVkIGJ5IFZhcmlhYmxlUmVmIHdoZW4gYW4KLSAgICAgKiBleHByZXNzaW9uIGNvbnRhaW5zIGEgcmVmZXJlbmNlIHRvIHRoaXMgdmFyaWFibGUuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgYWRkUmVmZXJlbmNlKFZhcmlhYmxlUmVmQmFzZSB2cmVmKSB7Ci0gICAgICAgIF9yZWZzLmFkZEVsZW1lbnQodnJlZik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogV2hlbiBhIHZhcmlhYmxlIGlzIG92ZXJyaWRlbiBieSBhbm90aGVyLCBlLmcuIHZpYSB4c2w6aW1wb3J0LAotICAgICAqIGl0cyByZWZlcmVuY2VzIG5lZWQgdG8gYmUgY29waWVkIG9yIG90aGVyd2lzZSBpdCBtYXkgYmUKLSAgICAgKiBjb21waWxlZCBhd2F5IGFzIGRlYWQgY29kZS4gVGhpcyBtZXRob2QgY2FuIGJlIHVzZWQgZm9yIHRoYXQKLSAgICAgKiBwdXJwb3NlLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGNvcHlSZWZlcmVuY2VzKFZhcmlhYmxlQmFzZSB2YXIpIHsKLSAgICAgICAgZmluYWwgaW50IHNpemUgPSBfcmVmcy5zaXplKCk7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7Ci0gICAgICAgICAgICB2YXIuYWRkUmVmZXJlbmNlKF9yZWZzLmdldChpKSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBNYXAgdGhpcyB2YXJpYWJsZSB0byBhIHJlZ2lzdGVyCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgbWFwUmVnaXN0ZXIoTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotICAgICAgICBpZiAoX2xvY2FsID09IG51bGwpIHsKLSAgICAgICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLSAgICAgICAgICAgIGZpbmFsIFN0cmluZyBuYW1lID0gZ2V0RXNjYXBlZE5hbWUoKTsgLy8gVE9ETzogbmFtZXNwYWNlID8KLSAgICAgICAgICAgIGZpbmFsIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuVHlwZSB2YXJUeXBlID0gX3R5cGUudG9KQ1R5cGUoKTsKLSAgICAgICAgICAgIF9sb2NhbCA9IG1ldGhvZEdlbi5hZGRMb2NhbFZhcmlhYmxlMihuYW1lLCB2YXJUeXBlLCBpbC5nZXRFbmQoKSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZW1vdmUgdGhlIG1hcHBpbmcgb2YgdGhpcyB2YXJpYWJsZSB0byBhIHJlZ2lzdGVyLgotICAgICAqIENhbGxlZCB3aGVuIHdlIGxlYXZlIHRoZSBBU1Qgc2NvcGUgb2YgdGhlIHZhcmlhYmxlJ3MgZGVjbGFyYXRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB1bm1hcFJlZ2lzdGVyKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0gICAgICAgIGlmIChfbG9jYWwgIT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKF90eXBlIGluc3RhbmNlb2YgUmVzdWx0VHJlZVR5cGUpIHsKLSAgICAgICAgICAgICAgICBmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgICAgICAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotICAgICAgICAgICAgICAgIGlmIChjbGFzc0dlbi5nZXRTdHlsZXNoZWV0KCkuY2FsbHNOb2Rlc2V0KCkgJiYgY2xhc3NHZW4uZ2V0RE9NQ2xhc3MoKS5lcXVhbHMoTVVMVElfRE9NX0NMQVNTKSkgewotICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgcmVtb3ZlREEgPSBjcGcuYWRkTWV0aG9kcmVmKE1VTFRJX0RPTV9DTEFTUywgInJlbW92ZURPTUFkYXB0ZXIiLCAiKCIgKyBET01fQURBUFRFUl9TSUcgKyAiKVYiKTsKLSAgICAgICAgICAgICAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkRE9NKCkpOwotICAgICAgICAgICAgICAgICAgICBpbC5hcHBlbmQobmV3IENIRUNLQ0FTVChjcGcuYWRkQ2xhc3MoTVVMVElfRE9NX0NMQVNTKSkpOwotICAgICAgICAgICAgICAgICAgICBpbC5hcHBlbmQobG9hZEluc3RydWN0aW9uKCkpOwotICAgICAgICAgICAgICAgICAgICBpbC5hcHBlbmQobmV3IENIRUNLQ0FTVChjcGcuYWRkQ2xhc3MoRE9NX0FEQVBURVJfQ0xBU1MpKSk7Ci0gICAgICAgICAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChyZW1vdmVEQSkpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBmaW5hbCBpbnQgcmVsZWFzZSA9IGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoRE9NX0lNUExfQ0xBU1MsICJyZWxlYXNlIiwgIigpViIpOwotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChsb2FkSW5zdHJ1Y3Rpb24oKSk7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0UocmVsZWFzZSwgMSkpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBfbG9jYWwuc2V0RW5kKG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKS5nZXRFbmQoKSk7Ci0gICAgICAgICAgICBtZXRob2RHZW4ucmVtb3ZlTG9jYWxWYXJpYWJsZShfbG9jYWwpOwotICAgICAgICAgICAgX3JlZnMgPSBudWxsOwotICAgICAgICAgICAgX2xvY2FsID0gbnVsbDsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYW4gaW5zdHJ1Y3Rpb24gZm9yIGxvYWRpbmcgdGhlIHZhbHVlIG9mIHRoaXMgdmFyaWFibGUgb250bwotICAgICAqIHRoZSBKVk0gc3RhY2suCi0gICAgICovCi0gICAgcHVibGljIEluc3RydWN0aW9uIGxvYWRJbnN0cnVjdGlvbigpIHsKLSAgICAgICAgaWYgKF9sb2FkSW5zdHJ1Y3Rpb24gPT0gbnVsbCkgewotICAgICAgICAgICAgX2xvYWRJbnN0cnVjdGlvbiA9IF90eXBlLkxPQUQoX2xvY2FsLmdldEluZGV4KCkpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBfbG9hZEluc3RydWN0aW9uOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYW4gaW5zdHJ1Y3Rpb24gZm9yIHN0b3JpbmcgYSB2YWx1ZSBmcm9tIHRoZSBKVk0gc3RhY2sKLSAgICAgKiBpbnRvIHRoaXMgdmFyaWFibGUuCi0gICAgICovCi0gICAgcHVibGljIEluc3RydWN0aW9uIHN0b3JlSW5zdHJ1Y3Rpb24oKSB7Ci0gICAgICAgIGlmIChfc3RvcmVJbnN0cnVjdGlvbiA9PSBudWxsKSB7Ci0gICAgICAgICAgICBfc3RvcmVJbnN0cnVjdGlvbiA9IF90eXBlLlNUT1JFKF9sb2NhbC5nZXRJbmRleCgpKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gX3N0b3JlSW5zdHJ1Y3Rpb247Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgZXhwcmVzc2lvbiBmcm9tIHRoaXMgdmFyaWFibGUncyBzZWxlY3QgYXR0cmlidXRlIChpZiBhbnkpCi0gICAgICovCi0gICAgcHVibGljIEV4cHJlc3Npb24gZ2V0RXhwcmVzc2lvbigpIHsKLSAgICAgICAgcmV0dXJuKF9zZWxlY3QpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIERpc3BsYXkgdmFyaWFibGUgYXMgc2luZ2xlIHN0cmluZwotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0gICAgICAgIHJldHVybigidmFyaWFibGUoIitfbmFtZSsiKSIpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIERpc3BsYXkgdmFyaWFibGUgaW4gYSBmdWxsIEFTVCBkdW1wCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZGlzcGxheShpbnQgaW5kZW50KSB7Ci0gICAgICAgIGluZGVudChpbmRlbnQpOwotICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlZhcmlhYmxlICIgKyBfbmFtZSk7Ci0gICAgICAgIGlmIChfc2VsZWN0ICE9IG51bGwpIHsKLSAgICAgICAgICAgIGluZGVudChpbmRlbnQgKyBJbmRlbnRJbmNyZW1lbnQpOwotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJzZWxlY3QgIiArIF9zZWxlY3QudG9TdHJpbmcoKSk7Ci0gICAgICAgIH0KLSAgICAgICAgZGlzcGxheUNvbnRlbnRzKGluZGVudCArIEluZGVudEluY3JlbWVudCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgdHlwZSBvZiB0aGUgdmFyaWFibGUKLSAgICAgKi8KLSAgICBwdWJsaWMgVHlwZSBnZXRUeXBlKCkgewotICAgICAgICByZXR1cm4gX3R5cGU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGUgdmFyaWFibGUgb3IgcGFyYW1ldGVyIGFzIGl0IHdpbGwgb2NjdXIgaW4gdGhlCi0gICAgICogY29tcGlsZWQgdHJhbnNsZXQuCi0gICAgICovCi0gICAgcHVibGljIFFOYW1lIGdldE5hbWUoKSB7Ci0gICAgICAgIHJldHVybiBfbmFtZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBlc2NhcGVkIHFuYW1lIG9mIHRoZSB2YXJpYWJsZSBvciBwYXJhbWV0ZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEVzY2FwZWROYW1lKCkgewotICAgICAgICByZXR1cm4gX2VzY2FwZWROYW1lOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldCB0aGUgbmFtZSBvZiB0aGUgdmFyaWFibGUgb3IgcGFyZW1ldGVyLiBFc2NhcGUgYWxsIHNwZWNpYWwgY2hhcnMuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0TmFtZShRTmFtZSBuYW1lKSB7Ci0gICAgICAgIF9uYW1lID0gbmFtZTsKLSAgICAgICAgX2VzY2FwZWROYW1lID0gVXRpbC5lc2NhcGUobmFtZS5nZXRTdHJpbmdSZXAoKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgdHJ1ZSBpZiB0aGUgdmFyaWFibGUgaXMgbG9jYWwKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0xvY2FsKCkgewotICAgICAgICByZXR1cm4gX2lzTG9jYWw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUGFyc2UgdGhlIGNvbnRlbnRzIG9mIHRoZSA8eHNsOmRlY2ltYWwtZm9ybWF0PiBlbGVtZW50LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHBhcnNlQ29udGVudHMoUGFyc2VyIHBhcnNlcikgewotICAgICAgICAvLyBHZXQgdGhlICduYW1lIGF0dHJpYnV0ZQotICAgICAgICBTdHJpbmcgbmFtZSA9IGdldEF0dHJpYnV0ZSgibmFtZSIpOwotCi0gICAgICAgIGlmIChuYW1lLmxlbmd0aCgpID4gMCkgewotICAgICAgICAgICAgaWYgKCFYTUwxMUNoYXIuaXNYTUwxMVZhbGlkUU5hbWUobmFtZSkpIHsKLSAgICAgICAgICAgICAgICBFcnJvck1zZyBlcnIgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuSU5WQUxJRF9RTkFNRV9FUlIsIG5hbWUsIHRoaXMpOwotICAgICAgICAgICAgICAgIHBhcnNlci5yZXBvcnRFcnJvcihDb25zdGFudHMuRVJST1IsIGVycik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBzZXROYW1lKHBhcnNlci5nZXRRTmFtZUlnbm9yZURlZmF1bHROcyhuYW1lKSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICAgICAgcmVwb3J0RXJyb3IodGhpcywgcGFyc2VyLCBFcnJvck1zZy5SRVFVSVJFRF9BVFRSX0VSUiwgIm5hbWUiKTsKLQotICAgICAgICAvLyBDaGVjayB3aGV0aGVyIHZhcmlhYmxlL3BhcmFtIG9mIHRoZSBzYW1lIG5hbWUgaXMgYWxyZWFkeSBpbiBzY29wZQotICAgICAgICBWYXJpYWJsZUJhc2Ugb3RoZXIgPSBwYXJzZXIubG9va3VwVmFyaWFibGUoX25hbWUpOwotICAgICAgICBpZiAoKG90aGVyICE9IG51bGwpICYmIChvdGhlci5nZXRQYXJlbnQoKSA9PSBnZXRQYXJlbnQoKSkpIHsKLSAgICAgICAgICAgIHJlcG9ydEVycm9yKHRoaXMsIHBhcnNlciwgRXJyb3JNc2cuVkFSSUFCTEVfUkVERUZfRVJSLCBuYW1lKTsKLSAgICAgICAgfQotCi0gICAgICAgIHNlbGVjdCA9IGdldEF0dHJpYnV0ZSgic2VsZWN0Iik7Ci0gICAgICAgIGlmIChzZWxlY3QubGVuZ3RoKCkgPiAwKSB7Ci0gICAgICAgICAgICBfc2VsZWN0ID0gZ2V0UGFyc2VyKCkucGFyc2VFeHByZXNzaW9uKHRoaXMsICJzZWxlY3QiLCBudWxsKTsKLSAgICAgICAgICAgIGlmIChfc2VsZWN0LmlzRHVtbXkoKSkgewotICAgICAgICAgICAgICAgIHJlcG9ydEVycm9yKHRoaXMsIHBhcnNlciwgRXJyb3JNc2cuUkVRVUlSRURfQVRUUl9FUlIsICJzZWxlY3QiKTsKLSAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBDaGlsZHJlbiBtdXN0IGJlIHBhcnNlZCBmaXJzdCAtPiBzdGF0aWMgc2NvcGluZwotICAgICAgICBwYXJzZUNoaWxkcmVuKHBhcnNlcik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29tcGlsZSB0aGUgdmFsdWUgb2YgdGhlIHZhcmlhYmxlLCB3aGljaCBpcyBlaXRoZXIgaW4gYW4gZXhwcmVzc2lvbiBpbgotICAgICAqIGEgJ3NlbGVjdCcgYXR0cmlidXRlLCBvciBpbiB0aGUgdmFyaWFibGUgZWxlbWVudHMgYm9keQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZVZhbHVlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLSAgICAgICAgLy8gQ29tcGlsZSBleHByZXNzaW9uIGlzICdzZWxlY3QnIGF0dHJpYnV0ZSBpZiBwcmVzZW50Ci0gICAgICAgIGlmIChfc2VsZWN0ICE9IG51bGwpIHsKLSAgICAgICAgICAgIF9zZWxlY3QudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICAgICAgLy8gQ3JlYXRlIGEgQ2FjaGVkTm9kZUxpc3RJdGVyYXRvciBmb3Igc2VsZWN0IGV4cHJlc3Npb25zCi0gICAgICAgICAgICAvLyBpbiBhIHZhcmlhYmxlIG9yIHBhcmFtZXRlci4KLSAgICAgICAgICAgIGlmIChfc2VsZWN0LmdldFR5cGUoKSBpbnN0YW5jZW9mIE5vZGVTZXRUeXBlKSB7Ci0gICAgICAgICAgICAgICAgZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotICAgICAgICAgICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQotICAgICAgICAgICAgICAgIGZpbmFsIGludCBpbml0Q05JID0gY3BnLmFkZE1ldGhvZHJlZihDQUNIRURfTk9ERV9MSVNUX0lURVJBVE9SX0NMQVNTLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiPGluaXQ+IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIigiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICtOT0RFX0lURVJBVE9SX1NJRwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIilWIik7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBORVcoY3BnLmFkZENsYXNzKENBQ0hFRF9OT0RFX0xJU1RfSVRFUkFUT1JfQ0xBU1MpKSk7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKERVUF9YMSk7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKFNXQVApOwotCi0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VTUEVDSUFMKGluaXRDTkkpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIF9zZWxlY3Quc3RhcnRJdGVyYXRvcihjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgfQotICAgICAgICAvLyBJZiBub3QsIGNvbXBpbGUgcmVzdWx0IHRyZWUgZnJvbSBwYXJhbWV0ZXIgYm9keSBpZiBwcmVzZW50LgotICAgICAgICBlbHNlIGlmIChoYXNDb250ZW50cygpKSB7Ci0gICAgICAgICAgICBjb21waWxlUmVzdWx0VHJlZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgfQotICAgICAgICAvLyBJZiBuZWl0aGVyIGFyZSBwcmVzZW50IHRoZW4gc3RvcmUgZW1wdHkgc3RyaW5nIGluIHZhcmlhYmxlCi0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotICAgICAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgQ29uc3RhbnRzLkVNUFRZU1RSSU5HKSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvVmFyaWFibGVSZWYuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvVmFyaWFibGVSZWYuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZmU5MThiMC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL1ZhcmlhYmxlUmVmLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5NyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBWYXJpYWJsZVJlZi5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzA1IDA5OjMzOjUwIHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQ0hFQ0tDQVNUOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQ29uc3RhbnRQb29sR2VuOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuR0VURklFTEQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JTlZPS0VJTlRFUkZBQ0U7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JbnN0cnVjdGlvbkxpc3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuQ2xhc3NHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuTWV0aG9kR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLk5vZGVTZXRUeXBlOwotCi0vKioKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICogQGF1dGhvciBFcndpbiBCb2x3aWR0IDxlamJAa2xvbXAub3JnPgotICovCi1maW5hbCBjbGFzcyBWYXJpYWJsZVJlZiBleHRlbmRzIFZhcmlhYmxlUmVmQmFzZSB7Ci0KLSAgICBwdWJsaWMgVmFyaWFibGVSZWYoVmFyaWFibGUgdmFyaWFibGUpIHsKLSAgICAgICAgc3VwZXIodmFyaWFibGUpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotICAgICAgICBmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQotICAgICAgICAvLyBGYWxsLXRocm91Z2ggZm9yIHZhcmlhYmxlcyB0aGF0IGFyZSBpbXBsZW1lbnRlZCBhcyBtZXRob2RzCi0gICAgICAgIGlmIChfdHlwZS5pbXBsZW1lbnRlZEFzTWV0aG9kKCkpIHJldHVybjsKLQotICAgICAgICBmaW5hbCBTdHJpbmcgbmFtZSA9IF92YXJpYWJsZS5nZXRFc2NhcGVkTmFtZSgpOwotICAgICAgICBmaW5hbCBTdHJpbmcgc2lnbmF0dXJlID0gX3R5cGUudG9TaWduYXR1cmUoKTsKLQotICAgICAgICBpZiAoX3ZhcmlhYmxlLmlzTG9jYWwoKSkgewotICAgICAgICAgICAgaWYgKGNsYXNzR2VuLmlzRXh0ZXJuYWwoKSkgewotICAgICAgICAgICAgICAgIENsb3N1cmUgdmFyaWFibGVDbG9zdXJlID0gX2Nsb3N1cmU7Ci0gICAgICAgICAgICAgICAgd2hpbGUgKHZhcmlhYmxlQ2xvc3VyZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmICh2YXJpYWJsZUNsb3N1cmUuaW5Jbm5lckNsYXNzKCkpIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICB2YXJpYWJsZUNsb3N1cmUgPSB2YXJpYWJsZUNsb3N1cmUuZ2V0UGFyZW50Q2xvc3VyZSgpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIGlmICh2YXJpYWJsZUNsb3N1cmUgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBpbC5hcHBlbmQoQUxPQURfMCk7Ci0gICAgICAgICAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgR0VURklFTEQoCi0gICAgICAgICAgICAgICAgICAgICAgICBjcGcuYWRkRmllbGRyZWYodmFyaWFibGVDbG9zdXJlLmdldElubmVyQ2xhc3NOYW1lKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSwgc2lnbmF0dXJlKSkpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgaWwuYXBwZW5kKF92YXJpYWJsZS5sb2FkSW5zdHJ1Y3Rpb24oKSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKF92YXJpYWJsZS5sb2FkSW5zdHJ1Y3Rpb24oKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBmaW5hbCBTdHJpbmcgY2xhc3NOYW1lID0gY2xhc3NHZW4uZ2V0Q2xhc3NOYW1lKCk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpOwotICAgICAgICAgICAgaWYgKGNsYXNzR2VuLmlzRXh0ZXJuYWwoKSkgewotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgQ0hFQ0tDQVNUKGNwZy5hZGRDbGFzcyhjbGFzc05hbWUpKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IEdFVEZJRUxEKGNwZy5hZGRGaWVsZHJlZihjbGFzc05hbWUsbmFtZSxzaWduYXR1cmUpKSk7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoX3ZhcmlhYmxlLmdldFR5cGUoKSBpbnN0YW5jZW9mIE5vZGVTZXRUeXBlKSB7Ci0gICAgICAgICAgICAvLyBUaGUgbWV0aG9kIGNsb25lSXRlcmF0b3IoKSBhbHNvIGRvZXMgcmVzZXR0aW5nCi0gICAgICAgICAgICBmaW5hbCBpbnQgY2xvbmUgPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKE5PREVfSVRFUkFUT1IsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImNsb25lSXRlcmF0b3IiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoKSIgKwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOT0RFX0lURVJBVE9SX1NJRyk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRUlOVEVSRkFDRShjbG9uZSwgMSkpOwotICAgICAgICB9Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9WYXJpYWJsZVJlZkJhc2UuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvVmFyaWFibGVSZWZCYXNlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDc2Y2VlMDQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9WYXJpYWJsZVJlZkJhc2UuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE2NSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBWYXJpYWJsZVJlZkJhc2UuamF2YSx2IDEuNSAyMDA1LzA5LzI4IDEzOjQ4OjE4IHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZUNoZWNrRXJyb3I7Ci1pbXBvcnQgamF2YS51dGlsLk9iamVjdHM7Ci0KLS8qKgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqLwotY2xhc3MgVmFyaWFibGVSZWZCYXNlIGV4dGVuZHMgRXhwcmVzc2lvbiB7Ci0KLSAgICAvKioKLSAgICAgKiBBIHJlZmVyZW5jZSB0byB0aGUgYXNzb2NpYXRlZCB2YXJpYWJsZS4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgVmFyaWFibGVCYXNlIF92YXJpYWJsZTsKLQotICAgIC8qKgotICAgICAqIEEgcmVmZXJlbmNlIHRvIHRoZSBlbmNsb3NpbmcgZXhwcmVzc2lvbi9pbnN0cnVjdGlvbiBmb3Igd2hpY2ggYQotICAgICAqIGNsb3N1cmUgaXMgbmVlZGVkIChQcmVkaWNhdGUsIE51bWJlciBvciBTb3J0KS4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgQ2xvc3VyZSBfY2xvc3VyZSA9IG51bGw7Ci0KLSAgICBwdWJsaWMgVmFyaWFibGVSZWZCYXNlKFZhcmlhYmxlQmFzZSB2YXJpYWJsZSkgewotICAgICAgICBfdmFyaWFibGUgPSB2YXJpYWJsZTsKLSAgICAgICAgdmFyaWFibGUuYWRkUmVmZXJlbmNlKHRoaXMpOwotICAgIH0KLQotICAgIHB1YmxpYyBWYXJpYWJsZVJlZkJhc2UoKSB7Ci0gICAgICAgIF92YXJpYWJsZSA9IG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhIHJlZmVyZW5jZSB0byB0aGUgYXNzb2NpYXRlZCB2YXJpYWJsZQotICAgICAqLwotICAgIHB1YmxpYyBWYXJpYWJsZUJhc2UgZ2V0VmFyaWFibGUoKSB7Ci0gICAgICAgIHJldHVybiBfdmFyaWFibGU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSWYgdGhpcyB2YXJpYWJsZSByZWZlcmVuY2UgaXMgaW4gYSB0b3AtbGV2ZWwgZWxlbWVudCBsaWtlCi0gICAgICogYW5vdGhlciB2YXJpYWJsZSwgcGFyYW0gb3Iga2V5LCBhZGQgYSBkZXBlbmRlbmN5IGJldHdlZW4KLSAgICAgKiB0aGF0IHRvcC1sZXZlbCBlbGVtZW50IGFuZCB0aGUgcmVmZXJlbmNlZCB2YXJpYWJsZS4gRm9yCi0gICAgICogZXhhbXBsZSwKLSAgICAgKgotICAgICAqICAgPHhzbDp2YXJpYWJsZSBuYW1lPSJ4IiAuLi4vPgotICAgICAqICAgPHhzbDp2YXJpYWJsZSBuYW1lPSJ5IiBzZWxlY3Q9IiR4ICsgMSIvPgotICAgICAqCi0gICAgICogYW5kIGFzc3VtaW5nIHRoaXMgY2xhc3MgcmVwcmVzZW50cyAiJHgiLCBhZGQgYSByZWZlcmVuY2UKLSAgICAgKiBiZXR3ZWVuIHZhcmlhYmxlIHkgYW5kIHZhcmlhYmxlIHguCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgYWRkUGFyZW50RGVwZW5kZW5jeSgpIHsKLSAgICAgICAgU3ludGF4VHJlZU5vZGUgbm9kZSA9IHRoaXM7Ci0gICAgICAgIHdoaWxlIChub2RlICE9IG51bGwgJiYgbm9kZSBpbnN0YW5jZW9mIFRvcExldmVsRWxlbWVudCA9PSBmYWxzZSkgewotICAgICAgICAgICAgbm9kZSA9IG5vZGUuZ2V0UGFyZW50KCk7Ci0gICAgICAgIH0KLQotICAgICAgICBUb3BMZXZlbEVsZW1lbnQgcGFyZW50ID0gKFRvcExldmVsRWxlbWVudCkgbm9kZTsKLSAgICAgICAgaWYgKHBhcmVudCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBWYXJpYWJsZUJhc2UgdmFyID0gX3ZhcmlhYmxlOwotICAgICAgICAgICAgaWYgKF92YXJpYWJsZS5faWdub3JlKSB7Ci0gICAgICAgICAgICAgICAgaWYgKF92YXJpYWJsZSBpbnN0YW5jZW9mIFZhcmlhYmxlKSB7Ci0gICAgICAgICAgICAgICAgICAgIHZhciA9IHBhcmVudC5nZXRTeW1ib2xUYWJsZSgpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5sb29rdXBWYXJpYWJsZShfdmFyaWFibGUuX25hbWUpOwotICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoX3ZhcmlhYmxlIGluc3RhbmNlb2YgUGFyYW0pIHsKLSAgICAgICAgICAgICAgICAgICAgdmFyID0gcGFyZW50LmdldFN5bWJvbFRhYmxlKCkubG9va3VwUGFyYW0oX3ZhcmlhYmxlLl9uYW1lKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIHBhcmVudC5hZGREZXBlbmRlbmN5KHZhcik7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUd28gdmFyaWFibGUgcmVmZXJlbmNlcyBhcmUgZGVlbWVkIGVxdWFsIGlmIHRoZXkgcmVmZXIgdG8gdGhlCi0gICAgICogc2FtZSB2YXJpYWJsZS4KLSAgICAgKi8KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaikgewotICAgICAgICByZXR1cm4gb2JqID09IHRoaXMgfHwgKG9iaiBpbnN0YW5jZW9mIFZhcmlhYmxlUmVmQmFzZSkKLSAgICAgICAgICAgICYmIChfdmFyaWFibGUgPT0gKChWYXJpYWJsZVJlZkJhc2UpIG9iaikuX3ZhcmlhYmxlKTsKLSAgICB9Ci0KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewotICAgICAgICByZXR1cm4gT2JqZWN0cy5oYXNoQ29kZSh0aGlzLl92YXJpYWJsZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIHZhcmlhYmxlIHJlZmVyZW5jZSBvbiB0aGUKLSAgICAgKiBmb3JtYXQgJ3ZhcmlhYmxlLXJlZig8dmFyLW5hbWU+KScuCi0gICAgICogQHJldHVybiBWYXJpYWJsZSByZWZlcmVuY2UgZGVzY3JpcHRpb24KLSAgICAgKi8KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgICAgICByZXR1cm4gInZhcmlhYmxlLXJlZigiK192YXJpYWJsZS5nZXROYW1lKCkrJy8nK192YXJpYWJsZS5nZXRUeXBlKCkrJyknOwotICAgIH0KLQotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpCi0gICAgICAgIHRocm93cyBUeXBlQ2hlY2tFcnJvcgotICAgIHsKLSAgICAgICAgLy8gUmV0dXJuZWQgY2FjaGVkIHR5cGUgaWYgYXZhaWxhYmxlCi0gICAgICAgIGlmIChfdHlwZSAhPSBudWxsKSByZXR1cm4gX3R5cGU7Ci0KLSAgICAgICAgLy8gRmluZCBuZWFyZXN0IGNsb3N1cmUgdG8gYWRkIGEgdmFyaWFibGUgcmVmZXJlbmNlCi0gICAgICAgIGlmIChfdmFyaWFibGUuaXNMb2NhbCgpKSB7Ci0gICAgICAgICAgICBTeW50YXhUcmVlTm9kZSBub2RlID0gZ2V0UGFyZW50KCk7Ci0gICAgICAgICAgICBkbyB7Ci0gICAgICAgICAgICAgICAgaWYgKG5vZGUgaW5zdGFuY2VvZiBDbG9zdXJlKSB7Ci0gICAgICAgICAgICAgICAgICAgIF9jbG9zdXJlID0gKENsb3N1cmUpIG5vZGU7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpZiAobm9kZSBpbnN0YW5jZW9mIFRvcExldmVsRWxlbWVudCkgewotICAgICAgICAgICAgICAgICAgICBicmVhazsgICAgICAvLyB3YXkgdXAgaW4gdGhlIHRyZWUKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgbm9kZSA9IG5vZGUuZ2V0UGFyZW50KCk7Ci0gICAgICAgICAgICB9IHdoaWxlIChub2RlICE9IG51bGwpOwotCi0gICAgICAgICAgICBpZiAoX2Nsb3N1cmUgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIF9jbG9zdXJlLmFkZFZhcmlhYmxlKHRoaXMpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gQXR0ZW1wdCB0byBnZXQgdGhlIGNhY2hlZCB2YXJpYWJsZSB0eXBlCi0gICAgICAgIF90eXBlID0gX3ZhcmlhYmxlLmdldFR5cGUoKTsKLQotICAgICAgICAvLyBJZiB0aGF0IGRvZXMgbm90IHdvcmsgd2UgbXVzdCBmb3JjZSBhIHR5cGUtY2hlY2sgKHRoaXMgaXMgbm9ybWFsbHkKLSAgICAgICAgLy8gb25seSBuZWVkZWQgZm9yIGdsb2JhbHMgaW4gaW5jbHVkZWQvaW1wb3J0ZWQgc3R5bGVzaGVldHMKLSAgICAgICAgaWYgKF90eXBlID09IG51bGwpIHsKLSAgICAgICAgICAgIF92YXJpYWJsZS50eXBlQ2hlY2soc3RhYmxlKTsKLSAgICAgICAgICAgIF90eXBlID0gX3ZhcmlhYmxlLmdldFR5cGUoKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIElmIGluIGEgdG9wLWxldmVsIGVsZW1lbnQsIGNyZWF0ZSBkZXBlbmRlbmN5IHRvIHRoZSByZWZlcmVuY2VkIHZhcgotICAgICAgICBhZGRQYXJlbnREZXBlbmRlbmN5KCk7Ci0KLSAgICAgICAgLy8gUmV0dXJuIHRoZSB0eXBlIG9mIHRoZSByZWZlcmVuY2VkIHZhcmlhYmxlCi0gICAgICAgIHJldHVybiBfdHlwZTsKLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvV2hlbi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9XaGVuLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDllZmUxNDIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9XaGVuLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMDcgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogV2hlbi5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzA1IDA5OjM2OjU4IHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkJvb2xlYW5UeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkNsYXNzR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkVycm9yTXNnOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLk1ldGhvZEdlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGVDaGVja0Vycm9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlV0aWw7Ci0KLS8qKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKi8KLWZpbmFsIGNsYXNzIFdoZW4gZXh0ZW5kcyBJbnN0cnVjdGlvbiB7Ci0KLSAgICBwcml2YXRlIEV4cHJlc3Npb24gX3Rlc3Q7Ci0gICAgcHJpdmF0ZSBib29sZWFuIF9pZ25vcmUgPSBmYWxzZTsKLQotICAgIHB1YmxpYyB2b2lkIGRpc3BsYXkoaW50IGluZGVudCkgewotICAgICAgICBpbmRlbnQoaW5kZW50KTsKLSAgICAgICAgVXRpbC5wcmludGxuKCJXaGVuIik7Ci0gICAgICAgIGluZGVudChpbmRlbnQgKyBJbmRlbnRJbmNyZW1lbnQpOwotICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCJ0ZXN0ICIpOwotICAgICAgICBVdGlsLnByaW50bG4oX3Rlc3QudG9TdHJpbmcoKSk7Ci0gICAgICAgIGRpc3BsYXlDb250ZW50cyhpbmRlbnQgKyBJbmRlbnRJbmNyZW1lbnQpOwotICAgIH0KLQotICAgIHB1YmxpYyBFeHByZXNzaW9uIGdldFRlc3QoKSB7Ci0gICAgICAgIHJldHVybiBfdGVzdDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBpZ25vcmUoKSB7Ci0gICAgICAgIHJldHVybihfaWdub3JlKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBwYXJzZUNvbnRlbnRzKFBhcnNlciBwYXJzZXIpIHsKLSAgICAgICAgX3Rlc3QgPSBwYXJzZXIucGFyc2VFeHByZXNzaW9uKHRoaXMsICJ0ZXN0IiwgbnVsbCk7Ci0KLSAgICAgICAgLy8gSWdub3JlIHhzbDppZiB3aGVuIHRlc3QgaXMgZmFsc2UgKGZ1bmN0aW9uLWF2YWlsYWJsZSgpIGFuZAotICAgICAgICAvLyBlbGVtZW50LWF2YWlsYWJsZSgpKQotICAgICAgICBPYmplY3QgcmVzdWx0ID0gX3Rlc3QuZXZhbHVhdGVBdENvbXBpbGVUaW1lKCk7Ci0gICAgICAgIGlmIChyZXN1bHQgIT0gbnVsbCAmJiByZXN1bHQgaW5zdGFuY2VvZiBCb29sZWFuKSB7Ci0gICAgICAgICAgICBfaWdub3JlID0gISgoQm9vbGVhbikgcmVzdWx0KS5ib29sZWFuVmFsdWUoKTsKLSAgICAgICAgfQotCi0gICAgICAgIHBhcnNlQ2hpbGRyZW4ocGFyc2VyKTsKLQotICAgICAgICAvLyBNYWtlIHN1cmUgcmVxdWlyZWQgYXR0cmlidXRlKHMpIGhhdmUgYmVlbiBzZXQKLSAgICAgICAgaWYgKF90ZXN0LmlzRHVtbXkoKSkgewotICAgICAgICAgICAgcmVwb3J0RXJyb3IodGhpcywgcGFyc2VyLCBFcnJvck1zZy5SRVFVSVJFRF9BVFRSX0VSUiwgInRlc3QiKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFR5cGUtY2hlY2sgdGhpcyB3aGVuIGVsZW1lbnQuIFRoZSB0ZXN0IHNob3VsZCBhbHdheXMgYmUgdHlwZSBjaGVja2VkLAotICAgICAqIHdoaWxlIHdlIGRvIG5vdCBib3RoZXIgd2l0aCB0aGUgY29udGVudHMgaWYgd2Uga25vdyB0aGUgdGVzdCBmYWlscy4KLSAgICAgKiBUaGlzIGlzIGltcG9ydGFudCBpbiBjYXNlcyB3aGVyZSB0aGUgInRlc3QiIGV4cHJlc3Npb24gdGVzdHMgZm9yCi0gICAgICogdGhlIHN1cHBvcnQgb2YgYSBub24tYXZhaWxhYmxlIGVsZW1lbnQsIGFuZCB0aGUgPHhzbDp3aGVuPiBib2R5IGNvbnRhaW5zCi0gICAgICogdGhpcyBub24tYXZhaWxhYmxlIGVsZW1lbnQuCi0gICAgICovCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLSAgICAgICAgLy8gVHlwZS1jaGVjayB0aGUgdGVzdCBleHByZXNzaW9uCi0gICAgICAgIGlmIChfdGVzdC50eXBlQ2hlY2soc3RhYmxlKSBpbnN0YW5jZW9mIEJvb2xlYW5UeXBlID09IGZhbHNlKSB7Ci0gICAgICAgICAgICBfdGVzdCA9IG5ldyBDYXN0RXhwcihfdGVzdCwgVHlwZS5Cb29sZWFuKTsKLSAgICAgICAgfQotICAgICAgICAvLyBUeXBlLWNoZWNrIHRoZSBjb250ZW50cyAoaWYgbmVjZXNzYXJ5KQotICAgICAgICBpZiAoIV9pZ25vcmUpIHsKLSAgICAgICAgICAgIHR5cGVDaGVja0NvbnRlbnRzKHN0YWJsZSk7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gVHlwZS5Wb2lkOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIHNob3VsZCBuZXZlciBiZSBjYWxsZWQuIEFuIE90aGVyd2lzZSBvYmplY3Qgd2lsbCBleHBsaWNpdGx5Ci0gICAgICogdHJhbnNsYXRlIHRoZSAidGVzdCIgZXhwcmVzc2lvbiBhbmQgYW5kIGNvbnRlbnRzIG9mIHRoaXMgZWxlbWVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLSAgICAgICAgZmluYWwgRXJyb3JNc2cgbXNnID0gbmV3IEVycm9yTXNnKEVycm9yTXNnLlNUUkFZX1dIRU5fRVJSLCB0aGlzKTsKLSAgICAgICAgZ2V0UGFyc2VyKCkucmVwb3J0RXJyb3IoQ29uc3RhbnRzLkVSUk9SLCBtc2cpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvV2hpdGVzcGFjZS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9XaGl0ZXNwYWNlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGVkZmE1YTguLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9XaGl0ZXNwYWNlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw1MzIgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogV2hpdGVzcGFjZS5qYXZhLHYgMS41IDIwMDUvMDkvMjggMTM6NDg6MTggcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgamF2YS51dGlsLlN0cmluZ1Rva2VuaXplcjsKLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5BTE9BRDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkJyYW5jaEhhbmRsZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkNvbnN0YW50UG9vbEdlbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklGX0lDTVBFUTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklMT0FEOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFSU5URVJGQUNFOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFVklSVFVBTDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uSGFuZGxlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW5zdHJ1Y3Rpb25MaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuUFVTSDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5DbGFzc0dlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5FcnJvck1zZzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5NZXRob2RHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlQ2hlY2tFcnJvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5VdGlsOwotCi0vKioKLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICovCi1maW5hbCBjbGFzcyBXaGl0ZXNwYWNlIGV4dGVuZHMgVG9wTGV2ZWxFbGVtZW50IHsKLSAgICAvLyBUaHJlZSBwb3NzaWJsZSBhY3Rpb25zIGZvciB0aGUgdHJhbnNsZXQ6Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVVNFX1BSRURJQ0FURSAgPSAwOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNUUklQX1NQQUNFICAgID0gMTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQUkVTRVJWRV9TUEFDRSA9IDI7Ci0KLSAgICAvLyBUaGUgMyBkaWZmZXJlbnQgY2F0ZWdvcmllcyBvZiBzdHJpcC9wcmVzZXJ2ZSBydWxlcyAob3JkZXIgaW1wb3J0YW50KQotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJVTEVfTk9ORSAgICAgID0gMDsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSVUxFX0VMRU1FTlQgICA9IDE7IC8vIHByaW9yaXR5IDAKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSVUxFX05BTUVTUEFDRSA9IDI7IC8vIHByaW9yaXR5IC0xLzQKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSVUxFX0FMTCAgICAgICA9IDM7IC8vIHByaW9yaXR5IC0xLzIKLQotICAgIHByaXZhdGUgU3RyaW5nIF9lbGVtZW50TGlzdDsKLSAgICBwcml2YXRlIGludCAgICBfYWN0aW9uOwotICAgIHByaXZhdGUgaW50ICAgIF9pbXBvcnRQcmVjZWRlbmNlOwotCi0gICAgLyoqCi0gICAgICogQXV4aWxsYXJ5IGNsYXNzIGZvciBlbmNhcHN1bGF0aW5nIGEgc2luZ2xlIHN0cmlwL3ByZXNlcnZlIHJ1bGUKLSAgICAgKi8KLSAgICBwcml2YXRlIGZpbmFsIHN0YXRpYyBjbGFzcyBXaGl0ZXNwYWNlUnVsZSB7Ci0gICAgICAgIHByaXZhdGUgZmluYWwgaW50IF9hY3Rpb247Ci0gICAgICAgIHByaXZhdGUgU3RyaW5nIF9uYW1lc3BhY2U7IC8vIFNob3VsZCBiZSByZXBsYWNlZCBieSBOUyB0eXBlIChpbnQpCi0gICAgICAgIHByaXZhdGUgU3RyaW5nIF9lbGVtZW50OyAgIC8vIFNob3VsZCBiZSByZXBsYWNlZCBieSBub2RlIHR5cGUgKGludCkKLSAgICAgICAgcHJpdmF0ZSBpbnQgICAgX3R5cGU7Ci0gICAgICAgIHByaXZhdGUgaW50ICAgIF9wcmlvcml0eTsKLQotICAgICAgICAvKioKLSAgICAgICAgICogU3RyaXAvcHJlc2VydmUgcnVsZSBjb25zdHJ1Y3RvcgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIFdoaXRlc3BhY2VSdWxlKGludCBhY3Rpb24sIFN0cmluZyBlbGVtZW50LCBpbnQgcHJlY2VkZW5jZSkgewotICAgICAgICAgICAgLy8gRGV0ZXJtaW5lIHRoZSBhY3Rpb24gKHN0cmlwIG9yIHByZXNlcnZlKSBmb3IgdGhpcyBydWxlCi0gICAgICAgICAgICBfYWN0aW9uID0gYWN0aW9uOwotCi0gICAgICAgICAgICAvLyBHZXQgdGhlIG5hbWVzcGFjZSBhbmQgZWxlbWVudCBuYW1lIGZvciB0aGlzIHJ1bGUKLSAgICAgICAgICAgIGZpbmFsIGludCBjb2xvbiA9IGVsZW1lbnQubGFzdEluZGV4T2YoJzonKTsKLSAgICAgICAgICAgIGlmIChjb2xvbiA+PSAwKSB7Ci0gICAgICAgICAgICAgICAgX25hbWVzcGFjZSA9IGVsZW1lbnQuc3Vic3RyaW5nKDAsY29sb24pOwotICAgICAgICAgICAgICAgIF9lbGVtZW50ID0gZWxlbWVudC5zdWJzdHJpbmcoY29sb24rMSxlbGVtZW50Lmxlbmd0aCgpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIF9uYW1lc3BhY2UgPSBDb25zdGFudHMuRU1QVFlTVFJJTkc7Ci0gICAgICAgICAgICAgICAgX2VsZW1lbnQgPSBlbGVtZW50OwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBEZXRlcm1pbmUgdGhlIGluaXRpYWwgcHJpb3JpdHkgZm9yIHRoaXMgcnVsZQotICAgICAgICAgICAgX3ByaW9yaXR5ID0gcHJlY2VkZW5jZSA8PCAyOwotCi0gICAgICAgICAgICAvLyBHZXQgdGhlIHN0cmlwL3ByZXNlcnZlIHR5cGU7IGVpdGhlciAiTlM6RUwiLCAiTlM6KiIgb3IgIioiCi0gICAgICAgICAgICBpZiAoX2VsZW1lbnQuZXF1YWxzKCIqIikpIHsKLSAgICAgICAgICAgICAgICBpZiAoX25hbWVzcGFjZSA9PSBDb25zdGFudHMuRU1QVFlTVFJJTkcpIHsKLSAgICAgICAgICAgICAgICAgICAgX3R5cGUgPSBSVUxFX0FMTDsgICAgICAgLy8gU3RyaXAvcHJlc2VydmUgX2FsbF8gZWxlbWVudHMKLSAgICAgICAgICAgICAgICAgICAgX3ByaW9yaXR5ICs9IDI7ICAgICAgICAgLy8gTG93ZXN0IHByaW9yaXR5Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICBfdHlwZSA9IFJVTEVfTkFNRVNQQUNFOyAvLyBTdHJpcC9yZXNlcnZlIGVsZW1lbnRzIHdpdGhpbiBOUwotICAgICAgICAgICAgICAgICAgICBfcHJpb3JpdHkgKz0gMTsgICAgICAgICAvLyBNZWRpdW0gcHJpb3JpdHkKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBfdHlwZSA9IFJVTEVfRUxFTUVOVDsgICAgICAgLy8gU3RyaXAvcHJlc2VydmUgc2luZ2xlIGVsZW1lbnQKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBGb3Igc29ydGluZyBydWxlcyBkZXBlbmRpbmcgb24gcHJpb3JpdHkKLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBpbnQgY29tcGFyZVRvKFdoaXRlc3BhY2VSdWxlIG90aGVyKSB7Ci0gICAgICAgICAgICByZXR1cm4gX3ByaW9yaXR5IDwgb3RoZXIuX3ByaW9yaXR5Ci0gICAgICAgICAgICAgICAgPyAtMQotICAgICAgICAgICAgICAgIDogX3ByaW9yaXR5ID4gb3RoZXIuX3ByaW9yaXR5ID8gMSA6IDA7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgaW50IGdldEFjdGlvbigpIHsgcmV0dXJuIF9hY3Rpb247IH0KLSAgICAgICAgcHVibGljIGludCBnZXRTdHJlbmd0aCgpIHsgcmV0dXJuIF90eXBlOyB9Ci0gICAgICAgIHB1YmxpYyBpbnQgZ2V0UHJpb3JpdHkoKSB7IHJldHVybiBfcHJpb3JpdHk7IH0KLSAgICAgICAgcHVibGljIFN0cmluZyBnZXRFbGVtZW50KCkgeyByZXR1cm4gX2VsZW1lbnQ7IH0KLSAgICAgICAgcHVibGljIFN0cmluZyBnZXROYW1lc3BhY2UoKSB7IHJldHVybiBfbmFtZXNwYWNlOyB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUGFyc2UgdGhlIGF0dHJpYnV0ZXMgb2YgdGhlIHhzbDpzdHJpcC9wcmVzZXJ2ZS1zcGFjZSBlbGVtZW50LgotICAgICAqIFRoZSBlbGVtZW50IHNob3VsZCBoYXZlIG5vdCBjb250ZW50cyAoaWdub3JlZCBpZiBhbnkpLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHBhcnNlQ29udGVudHMoUGFyc2VyIHBhcnNlcikgewotICAgICAgICAvLyBEZXRlcm1pbmUgaWYgdGhpcyBpcyBhbiB4c2w6c3RyaXAtIG9yIHByZXNlcnZlLXNwYWNlIGVsZW1lbnQKLSAgICAgICAgX2FjdGlvbiA9IF9xbmFtZS5nZXRMb2NhbFBhcnQoKS5lbmRzV2l0aCgic3RyaXAtc3BhY2UiKQotICAgICAgICAgICAgPyBTVFJJUF9TUEFDRSA6IFBSRVNFUlZFX1NQQUNFOwotCi0gICAgICAgIC8vIERldGVybWluZSB0aGUgaW1wb3J0IHByZWNlZGVuY2UKLSAgICAgICAgX2ltcG9ydFByZWNlZGVuY2UgPSBwYXJzZXIuZ2V0Q3VycmVudEltcG9ydFByZWNlZGVuY2UoKTsKLQotICAgICAgICAvLyBHZXQgdGhlIGxpc3Qgb2YgZWxlbWVudHMgdG8gc3RyaXAvcHJlc2VydmUKLSAgICAgICAgX2VsZW1lbnRMaXN0ID0gZ2V0QXR0cmlidXRlKCJlbGVtZW50cyIpOwotICAgICAgICBpZiAoX2VsZW1lbnRMaXN0ID09IG51bGwgfHwgX2VsZW1lbnRMaXN0Lmxlbmd0aCgpID09IDApIHsKLSAgICAgICAgICAgIHJlcG9ydEVycm9yKHRoaXMsIHBhcnNlciwgRXJyb3JNc2cuUkVRVUlSRURfQVRUUl9FUlIsICJlbGVtZW50cyIpOwotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0KLSAgICAgICAgZmluYWwgU3ltYm9sVGFibGUgc3RhYmxlID0gcGFyc2VyLmdldFN5bWJvbFRhYmxlKCk7Ci0gICAgICAgIFN0cmluZ1Rva2VuaXplciBsaXN0ID0gbmV3IFN0cmluZ1Rva2VuaXplcihfZWxlbWVudExpc3QpOwotICAgICAgICBTdHJpbmdCdWZmZXIgZWxlbWVudHMgPSBuZXcgU3RyaW5nQnVmZmVyKENvbnN0YW50cy5FTVBUWVNUUklORyk7Ci0KLSAgICAgICAgd2hpbGUgKGxpc3QuaGFzTW9yZUVsZW1lbnRzKCkpIHsKLSAgICAgICAgICAgIFN0cmluZyB0b2tlbiA9IGxpc3QubmV4dFRva2VuKCk7Ci0gICAgICAgICAgICBTdHJpbmcgcHJlZml4OwotICAgICAgICAgICAgU3RyaW5nIG5hbWVzcGFjZTsKLSAgICAgICAgICAgIGludCBjb2wgPSB0b2tlbi5pbmRleE9mKCc6Jyk7Ci0KLSAgICAgICAgICAgIGlmIChjb2wgIT0gLTEpIHsKLSAgICAgICAgICAgICAgICBuYW1lc3BhY2UgPSBsb29rdXBOYW1lc3BhY2UodG9rZW4uc3Vic3RyaW5nKDAsY29sKSk7Ci0gICAgICAgICAgICAgICAgaWYgKG5hbWVzcGFjZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGVsZW1lbnRzLmFwcGVuZChuYW1lc3BhY2UpLmFwcGVuZCgnOicpLmFwcGVuZCh0b2tlbi5zdWJzdHJpbmcoY29sICsgMSkpOwotICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIGVsZW1lbnRzLmFwcGVuZCh0b2tlbik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBlbGVtZW50cy5hcHBlbmQodG9rZW4pOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAobGlzdC5oYXNNb3JlRWxlbWVudHMoKSkKLSAgICAgICAgICAgICAgICBlbGVtZW50cy5hcHBlbmQoIiAiKTsKLSAgICAgICAgfQotICAgICAgICBfZWxlbWVudExpc3QgPSBlbGVtZW50cy50b1N0cmluZygpOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogRGUtdG9rZW5pemUgdGhlIGVsZW1lbnRzIGxpc3RlZCBpbiB0aGUgJ2VsZW1lbnRzJyBhdHRyaWJ1dGUgYW5kCi0gICAgICogaW5zdGFuY2lhdGUgYSBzZXQgb2Ygc3RyaXAvcHJlc2VydmUgcnVsZXMuCi0gICAgICovCi0gICAgcHVibGljIFZlY3RvciBnZXRSdWxlcygpIHsKLSAgICAgICAgZmluYWwgVmVjdG9yIHJ1bGVzID0gbmV3IFZlY3RvcigpOwotICAgICAgICAvLyBHbyB0aHJvdWdoIGVhY2ggZWxlbWVudCBhbmQgaW5zdGFuY2lhdGUgc3RyaXAvcHJlc2VydmUtb2JqZWN0Ci0gICAgICAgIGZpbmFsIFN0cmluZ1Rva2VuaXplciBsaXN0ID0gbmV3IFN0cmluZ1Rva2VuaXplcihfZWxlbWVudExpc3QpOwotICAgICAgICB3aGlsZSAobGlzdC5oYXNNb3JlRWxlbWVudHMoKSkgewotICAgICAgICAgICAgcnVsZXMuYWRkKG5ldyBXaGl0ZXNwYWNlUnVsZShfYWN0aW9uLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaXN0Lm5leHRUb2tlbigpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfaW1wb3J0UHJlY2VkZW5jZSkpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBydWxlczsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFNjYW5zIHRocm91Z2ggdGhlIHJ1bGVzIHZlY3RvciBhbmQgbG9va3MgZm9yIGEgcnVsZSBvZiBoaWdoZXIKLSAgICAgKiBwcmlvcml0eSB0aGF0IGNvbnRyYWRpY3RzIHRoZSBjdXJyZW50IHJ1bGUuCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgV2hpdGVzcGFjZVJ1bGUgZmluZENvbnRyYWRpY3RpbmdSdWxlKFZlY3RvciBydWxlcywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV2hpdGVzcGFjZVJ1bGUgcnVsZSkgewotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJ1bGVzLnNpemUoKTsgaSsrKSB7Ci0gICAgICAgICAgICAvLyBHZXQgdGhlIG5leHQgcnVsZSBpbiB0aGUgcHJpb3JpdGl6ZWQgbGlzdAotICAgICAgICAgICAgV2hpdGVzcGFjZVJ1bGUgY3VycmVudFJ1bGUgPSAoV2hpdGVzcGFjZVJ1bGUpcnVsZXMuZWxlbWVudEF0KGkpOwotICAgICAgICAgICAgLy8gV2Ugb25seSBjb25zaWRlciBydWxlcyB3aXRoIGhpZ2hlciBwcmlvcml0eQotICAgICAgICAgICAgaWYgKGN1cnJlbnRSdWxlID09IHJ1bGUpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLyoKLSAgICAgICAgICAgICAqIFNlZSBpZiB0aGVyZSBpcyBhIGNvbnRyYWRpY3RpbmcgcnVsZSB3aXRoIGhpZ2hlciBwcmlvcml0eS4KLSAgICAgICAgICAgICAqIElmIHRoZSBydWxlcyBoYXMgdGhlIHNhbWUgYWN0aW9uIHRoZW4gdGhpcyBydWxlIGlzIHJlZHVuZGFudCwKLSAgICAgICAgICAgICAqIGlmIHRoZXkgaGF2ZSBkaWZmZXJlbnQgYWN0aW9uIHRoZW4gdGhpcyBydWxlIHdpbGwgbmV2ZXIgd2luLgotICAgICAgICAgICAgICovCi0gICAgICAgICAgICBzd2l0Y2ggKGN1cnJlbnRSdWxlLmdldFN0cmVuZ3RoKCkpIHsKLSAgICAgICAgICAgIGNhc2UgUlVMRV9BTEw6Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnRSdWxlOwotCi0gICAgICAgICAgICBjYXNlIFJVTEVfRUxFTUVOVDoKLSAgICAgICAgICAgICAgICBpZiAoIXJ1bGUuZ2V0RWxlbWVudCgpLmVxdWFscyhjdXJyZW50UnVsZS5nZXRFbGVtZW50KCkpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvLyBpbnRlbnRpb25hbCBmYWxsLXRocm91Z2gKLSAgICAgICAgICAgIGNhc2UgUlVMRV9OQU1FU1BBQ0U6Ci0gICAgICAgICAgICAgICAgaWYgKHJ1bGUuZ2V0TmFtZXNwYWNlKCkuZXF1YWxzKGN1cnJlbnRSdWxlLmdldE5hbWVzcGFjZSgpKSkgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gY3VycmVudFJ1bGU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogT3JkZXJzIGEgc2V0IG9yIHJ1bGVzIGJ5IHByaW9yaXR5LCByZW1vdmVzIHJlZHVuZGFudCBydWxlcyBhbmQgcnVsZXMKLSAgICAgKiB0aGF0IGFyZSBzaGFkb3dlZCBieSBzdHJvbmdlciwgY29udHJhZGljdGluZyBydWxlcy4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBpbnQgcHJpb3JpdGl6ZVJ1bGVzKFZlY3RvciBydWxlcykgewotICAgICAgICBXaGl0ZXNwYWNlUnVsZSBjdXJyZW50UnVsZTsKLSAgICAgICAgaW50IGRlZmF1bHRBY3Rpb24gPSBQUkVTRVJWRV9TUEFDRTsKLQotICAgICAgICAvLyBTb3J0IGFsbCBydWxlcyB3aXRoIHJlZ2FyZCB0byBwcmlvcml0eQotICAgICAgICBxdWlja3NvcnQocnVsZXMsIDAsIHJ1bGVzLnNpemUoKS0xKTsKLQotICAgICAgICAvLyBDaGVjayBpZiB0aGVyZSBhcmUgYW55ICJ4c2w6c3RyaXAtc3BhY2UiIGVsZW1lbnRzIGF0IGFsbC4KLSAgICAgICAgLy8gSWYgdGhlcmUgYXJlIG5vIHhzbDpzdHJpcCBlbGVtZW50cyB3ZSBjYW4gaWdub3JlIGFsbCB4c2w6cHJlc2VydmUKLSAgICAgICAgLy8gZWxlbWVudHMgYW5kIHNpZ25hbCB0aGF0IGFsbCB3aGl0ZXNwYWNlcyBzaG91bGQgYmUgcHJlc2VydmVkCi0gICAgICAgIGJvb2xlYW4gc3RyaXAgPSBmYWxzZTsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBydWxlcy5zaXplKCk7IGkrKykgewotICAgICAgICAgICAgY3VycmVudFJ1bGUgPSAoV2hpdGVzcGFjZVJ1bGUpcnVsZXMuZWxlbWVudEF0KGkpOwotICAgICAgICAgICAgaWYgKGN1cnJlbnRSdWxlLmdldEFjdGlvbigpID09IFNUUklQX1NQQUNFKSB7Ci0gICAgICAgICAgICAgICAgc3RyaXAgPSB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIC8vIFJldHVybiB3aXRoIGRlZmF1bHQgYWN0aW9uOiBQUkVTRVJWRV9TUEFDRQotICAgICAgICBpZiAoIXN0cmlwKSB7Ci0gICAgICAgICAgICBydWxlcy5yZW1vdmVBbGxFbGVtZW50cygpOwotICAgICAgICAgICAgcmV0dXJuIFBSRVNFUlZFX1NQQUNFOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gUmVtb3ZlIGFsbCBydWxlcyB0aGF0IGFyZSBjb250cmFkaWN0ZWQgYnkgcnVsZXMgd2l0aCBoaWdoZXIgcHJpb3JpdHkKLSAgICAgICAgZm9yIChpbnQgaWR4ID0gMDsgaWR4IDwgcnVsZXMuc2l6ZSgpOyApIHsKLSAgICAgICAgICAgIGN1cnJlbnRSdWxlID0gKFdoaXRlc3BhY2VSdWxlKXJ1bGVzLmVsZW1lbnRBdChpZHgpOwotCi0gICAgICAgICAgICAvLyBSZW1vdmUgdGhpcyBzaW5nbGUgcnVsZSBpZiBpdCBoYXMgbm8gcHVycG9zZQotICAgICAgICAgICAgaWYgKGZpbmRDb250cmFkaWN0aW5nUnVsZShydWxlcyxjdXJyZW50UnVsZSkgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJ1bGVzLnJlbW92ZShpZHgpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgLy8gUmVtb3ZlIGFsbCBmb2xsb3dpbmcgcnVsZXMgaWYgdGhpcyBvbmUgb3ZlcnJpZGVzIGFsbAotICAgICAgICAgICAgICAgIGlmIChjdXJyZW50UnVsZS5nZXRTdHJlbmd0aCgpID09IFJVTEVfQUxMKSB7Ci0gICAgICAgICAgICAgICAgICAgIGRlZmF1bHRBY3Rpb24gPSBjdXJyZW50UnVsZS5nZXRBY3Rpb24oKTsKLSAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IGlkeDsgaSA8IHJ1bGVzLnNpemUoKTsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBydWxlcy5yZW1vdmVFbGVtZW50QXQoaSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLy8gU2tpcCB0byBuZXh0IHJ1bGUgKHRoZXJlIG1pZ2h0IG5vdCBiZSBhbnkpLi4uCi0gICAgICAgICAgICAgICAgaWR4Kys7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBUaGUgcnVsZXMgdmVjdG9yIGNvdWxkIGJlIGVtcHR5IGlmIGZpcnN0IHJ1bGUgaGFzIHN0cmVuZ3RoIFJVTEVfQUxMCi0gICAgICAgIGlmIChydWxlcy5zaXplKCkgPT0gMCkgewotICAgICAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb247Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBOb3cgd29yayBiYWNrd2FyZHMgYW5kIHN0cmlwIGF3YXkgYWxsIHJ1bGVzIHRoYXQgaGF2ZSB0aGUgc2FtZQotICAgICAgICAvLyBhY3Rpb24gYXMgdGhlIGRlZmF1bHQgcnVsZSAobm8gcmVhc29uIHRoZSBjaGVjayB0aGVtIGF0IHRoZSBlbmQpLgotICAgICAgICBkbyB7Ci0gICAgICAgICAgICBjdXJyZW50UnVsZSA9IChXaGl0ZXNwYWNlUnVsZSlydWxlcy5sYXN0RWxlbWVudCgpOwotICAgICAgICAgICAgaWYgKGN1cnJlbnRSdWxlLmdldEFjdGlvbigpID09IGRlZmF1bHRBY3Rpb24pIHsKLSAgICAgICAgICAgICAgICBydWxlcy5yZW1vdmVFbGVtZW50QXQocnVsZXMuc2l6ZSgpIC0gMSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSB3aGlsZSAocnVsZXMuc2l6ZSgpID4gMCk7Ci0KLSAgICAgICAgLy8gU2lnbmFsIHRoYXQgd2hpdGVzcGFjZSBkZXRlY3Rpb24gcHJlZGljYXRlIG11c3QgYmUgdXNlZC4KLSAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb247Ci0gICAgfQotCi0gICAgcHVibGljIHN0YXRpYyB2b2lkIGNvbXBpbGVTdHJpcFNwYWNlKEJyYW5jaEhhbmRsZSBzdHJpcFtdLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgc0NvdW50LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbnN0cnVjdGlvbkxpc3QgaWwpIHsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25IYW5kbGUgdGFyZ2V0ID0gaWwuYXBwZW5kKElDT05TVF8xKTsKLSAgICAgICAgaWwuYXBwZW5kKElSRVRVUk4pOwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNDb3VudDsgaSsrKSB7Ci0gICAgICAgICAgICBzdHJpcFtpXS5zZXRUYXJnZXQodGFyZ2V0KTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBjb21waWxlUHJlc2VydmVTcGFjZShCcmFuY2hIYW5kbGUgcHJlc2VydmVbXSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHBDb3VudCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW5zdHJ1Y3Rpb25MaXN0IGlsKSB7Ci0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uSGFuZGxlIHRhcmdldCA9IGlsLmFwcGVuZChJQ09OU1RfMCk7Ci0gICAgICAgIGlsLmFwcGVuZChJUkVUVVJOKTsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwQ291bnQ7IGkrKykgewotICAgICAgICAgICAgcHJlc2VydmVbaV0uc2V0VGFyZ2V0KHRhcmdldCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKgotICAgIHByaXZhdGUgc3RhdGljIHZvaWQgY29tcGlsZURlYnVnKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluc3RydWN0aW9uTGlzdCBpbCkgewotICAgICAgICBmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgICAgIGZpbmFsIGludCBwcnQgPSBjcGcuYWRkTWV0aG9kcmVmKCJqYXZhL2xhbmcvU3lzdGVtL291dCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJwcmludGxuIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIihMamF2YS9sYW5nL1N0cmluZzspViIpOwotICAgICAgICBpbC5hcHBlbmQoRFVQKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VTVEFUSUMocHJ0KSk7Ci0gICAgfQotICAgICovCi0KLSAgICAvKioKLSAgICAgKiBDb21waWxlcyB0aGUgcHJlZGljYXRlIG1ldGhvZAotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIHZvaWQgY29tcGlsZVByZWRpY2F0ZShWZWN0b3IgcnVsZXMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBkZWZhdWx0QWN0aW9uLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDbGFzc0dlbmVyYXRvciBjbGFzc0dlbikgewotICAgICAgICBmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG5ldyBJbnN0cnVjdGlvbkxpc3QoKTsKLSAgICAgICAgZmluYWwgWFNMVEMgeHNsdGMgPSBjbGFzc0dlbi5nZXRQYXJzZXIoKS5nZXRYU0xUQygpOwotCi0gICAgICAgIC8vIHByaXZhdGUgYm9vbGVhbiBUcmFuc2xldC5zdHJpcFNwYWNlKGludCB0eXBlKSAtIGNhbm5vdCBiZSBzdGF0aWMKLSAgICAgICAgZmluYWwgTWV0aG9kR2VuZXJhdG9yIHN0cmlwU3BhY2UgPQotICAgICAgICAgICAgbmV3IE1ldGhvZEdlbmVyYXRvcihBQ0NfUFVCTElDIHwgQUNDX0ZJTkFMICwKLSAgICAgICAgICAgICAgICAgICAgICAgIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuVHlwZS5CT09MRUFOLAotICAgICAgICAgICAgICAgICAgICAgICAgbmV3IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuVHlwZVtdIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBVdGlsLmdldEpDUmVmVHlwZShET01fSU5URl9TSUcpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuVHlwZS5JTlQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5UeXBlLklOVAotICAgICAgICAgICAgICAgICAgICAgICAgfSwKLSAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7ICJkb20iLCJub2RlIiwidHlwZSIgfSwKLSAgICAgICAgICAgICAgICAgICAgICAgICJzdHJpcFNwYWNlIixjbGFzc0dlbi5nZXRDbGFzc05hbWUoKSxpbCxjcGcpOwotCi0gICAgICAgIGNsYXNzR2VuLmFkZEludGVyZmFjZSgiY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1N0cmlwRmlsdGVyIik7Ci0KLSAgICAgICAgZmluYWwgaW50IHBhcmFtRG9tID0gc3RyaXBTcGFjZS5nZXRMb2NhbEluZGV4KCJkb20iKTsKLSAgICAgICAgZmluYWwgaW50IHBhcmFtQ3VycmVudCA9IHN0cmlwU3BhY2UuZ2V0TG9jYWxJbmRleCgibm9kZSIpOwotICAgICAgICBmaW5hbCBpbnQgcGFyYW1UeXBlID0gc3RyaXBTcGFjZS5nZXRMb2NhbEluZGV4KCJ0eXBlIik7Ci0KLSAgICAgICAgQnJhbmNoSGFuZGxlIHN0cmlwW10gPSBuZXcgQnJhbmNoSGFuZGxlW3J1bGVzLnNpemUoKV07Ci0gICAgICAgIEJyYW5jaEhhbmRsZSBwcmVzZXJ2ZVtdID0gbmV3IEJyYW5jaEhhbmRsZVtydWxlcy5zaXplKCldOwotICAgICAgICBpbnQgc0NvdW50ID0gMDsKLSAgICAgICAgaW50IHBDb3VudCA9IDA7Ci0KLSAgICAgICAgLy8gVHJhdmVyc2UgYWxsIHN0cmlwL3ByZXNlcnZlIHJ1bGVzCi0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpPHJ1bGVzLnNpemUoKTsgaSsrKSB7Ci0gICAgICAgICAgICAvLyBHZXQgdGhlIG5leHQgcnVsZSBpbiB0aGUgcHJpb3JpdGlzZWQgbGlzdAotICAgICAgICAgICAgV2hpdGVzcGFjZVJ1bGUgcnVsZSA9IChXaGl0ZXNwYWNlUnVsZSlydWxlcy5lbGVtZW50QXQoaSk7Ci0KLSAgICAgICAgICAgIC8vIFJldHVybnMgdGhlIG5hbWVzcGFjZSBmb3IgYSBub2RlIGluIHRoZSBET00KLSAgICAgICAgICAgIGZpbmFsIGludCBnbnMgPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKERPTV9JTlRGLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImdldE5hbWVzcGFjZU5hbWUiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIihJKUxqYXZhL2xhbmcvU3RyaW5nOyIpOwotCi0gICAgICAgICAgICBmaW5hbCBpbnQgc3RyY21wID0gY3BnLmFkZE1ldGhvZHJlZigiamF2YS9sYW5nL1N0cmluZyIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiY29tcGFyZVRvIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoTGphdmEvbGFuZy9TdHJpbmc7KUkiKTsKLQotICAgICAgICAgICAgLy8gSGFuZGxlIGVsZW1lbnRzPSJuczoqIiB0eXBlIHJ1bGUKLSAgICAgICAgICAgIGlmIChydWxlLmdldFN0cmVuZ3RoKCkgPT0gUlVMRV9OQU1FU1BBQ0UpIHsKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQobmV3IEFMT0FEKHBhcmFtRG9tKSk7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTE9BRChwYXJhbUN1cnJlbnQpKTsKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRUlOVEVSRkFDRShnbnMsMikpOwotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsIHJ1bGUuZ2V0TmFtZXNwYWNlKCkpKTsKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRVZJUlRVQUwoc3RyY21wKSk7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKElDT05TVF8wKTsKLQotICAgICAgICAgICAgICAgIGlmIChydWxlLmdldEFjdGlvbigpID09IFNUUklQX1NQQUNFKSB7Ci0gICAgICAgICAgICAgICAgICAgIHN0cmlwW3NDb3VudCsrXSA9IGlsLmFwcGVuZChuZXcgSUZfSUNNUEVRKG51bGwpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIHByZXNlcnZlW3BDb3VudCsrXSA9IGlsLmFwcGVuZChuZXcgSUZfSUNNUEVRKG51bGwpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyBIYW5kbGUgZWxlbWVudHM9Im5zOmVsIiB0eXBlIHJ1bGUKLSAgICAgICAgICAgIGVsc2UgaWYgKHJ1bGUuZ2V0U3RyZW5ndGgoKSA9PSBSVUxFX0VMRU1FTlQpIHsKLSAgICAgICAgICAgICAgICAvLyBDcmVhdGUgdGhlIFFOYW1lIGZvciB0aGUgZWxlbWVudAotICAgICAgICAgICAgICAgIGZpbmFsIFBhcnNlciBwYXJzZXIgPSBjbGFzc0dlbi5nZXRQYXJzZXIoKTsKLSAgICAgICAgICAgICAgICBRTmFtZSBxbmFtZTsKLSAgICAgICAgICAgICAgICBpZiAocnVsZS5nZXROYW1lc3BhY2UoKSAhPSBDb25zdGFudHMuRU1QVFlTVFJJTkcgKQotICAgICAgICAgICAgICAgICAgICBxbmFtZSA9IHBhcnNlci5nZXRRTmFtZShydWxlLmdldE5hbWVzcGFjZSgpLCBudWxsLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBydWxlLmdldEVsZW1lbnQoKSk7Ci0gICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICBxbmFtZSA9IHBhcnNlci5nZXRRTmFtZShydWxlLmdldEVsZW1lbnQoKSk7Ci0KLSAgICAgICAgICAgICAgICAvLyBSZWdpc3RlciB0aGUgZWxlbWVudC4KLSAgICAgICAgICAgICAgICBmaW5hbCBpbnQgZWxlbWVudFR5cGUgPSB4c2x0Yy5yZWdpc3RlckVsZW1lbnQocW5hbWUpOwotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSUxPQUQocGFyYW1UeXBlKSk7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgZWxlbWVudFR5cGUpKTsKLQotICAgICAgICAgICAgICAgIC8vIENvbXBhcmUgY3VycmVudCBub2RlIHR5cGUgd2l0aCB3YW50ZWQgZWxlbWVudCB0eXBlCi0gICAgICAgICAgICAgICAgaWYgKHJ1bGUuZ2V0QWN0aW9uKCkgPT0gU1RSSVBfU1BBQ0UpCi0gICAgICAgICAgICAgICAgICAgIHN0cmlwW3NDb3VudCsrXSA9IGlsLmFwcGVuZChuZXcgSUZfSUNNUEVRKG51bGwpKTsKLSAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgIHByZXNlcnZlW3BDb3VudCsrXSA9IGlsLmFwcGVuZChuZXcgSUZfSUNNUEVRKG51bGwpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGlmIChkZWZhdWx0QWN0aW9uID09IFNUUklQX1NQQUNFKSB7Ci0gICAgICAgICAgICBjb21waWxlU3RyaXBTcGFjZShzdHJpcCwgc0NvdW50LCBpbCk7Ci0gICAgICAgICAgICBjb21waWxlUHJlc2VydmVTcGFjZShwcmVzZXJ2ZSwgcENvdW50LCBpbCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBjb21waWxlUHJlc2VydmVTcGFjZShwcmVzZXJ2ZSwgcENvdW50LCBpbCk7Ci0gICAgICAgICAgICBjb21waWxlU3RyaXBTcGFjZShzdHJpcCwgc0NvdW50LCBpbCk7Ci0gICAgICAgIH0KLQotICAgICAgICBjbGFzc0dlbi5hZGRNZXRob2Qoc3RyaXBTcGFjZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29tcGlsZXMgdGhlIHByZWRpY2F0ZSBtZXRob2QKLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGNvbXBpbGVEZWZhdWx0KGludCBkZWZhdWx0QWN0aW9uLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4pIHsKLSAgICAgICAgZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBuZXcgSW5zdHJ1Y3Rpb25MaXN0KCk7Ci0gICAgICAgIGZpbmFsIFhTTFRDIHhzbHRjID0gY2xhc3NHZW4uZ2V0UGFyc2VyKCkuZ2V0WFNMVEMoKTsKLQotICAgICAgICAvLyBwcml2YXRlIGJvb2xlYW4gVHJhbnNsZXQuc3RyaXBTcGFjZShpbnQgdHlwZSkgLSBjYW5ub3QgYmUgc3RhdGljCi0gICAgICAgIGZpbmFsIE1ldGhvZEdlbmVyYXRvciBzdHJpcFNwYWNlID0KLSAgICAgICAgICAgIG5ldyBNZXRob2RHZW5lcmF0b3IoQUNDX1BVQkxJQyB8IEFDQ19GSU5BTCAsCi0gICAgICAgICAgICAgICAgICAgICAgICBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlR5cGUuQk9PTEVBTiwKLSAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlR5cGVbXSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgVXRpbC5nZXRKQ1JlZlR5cGUoRE9NX0lOVEZfU0lHKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlR5cGUuSU5ULAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuVHlwZS5JTlQKLSAgICAgICAgICAgICAgICAgICAgICAgIH0sCi0gICAgICAgICAgICAgICAgICAgICAgICBuZXcgU3RyaW5nW10geyAiZG9tIiwibm9kZSIsInR5cGUiIH0sCi0gICAgICAgICAgICAgICAgICAgICAgICAic3RyaXBTcGFjZSIsY2xhc3NHZW4uZ2V0Q2xhc3NOYW1lKCksaWwsY3BnKTsKLQotICAgICAgICBjbGFzc0dlbi5hZGRJbnRlcmZhY2UoImNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9TdHJpcEZpbHRlciIpOwotCi0gICAgICAgIGlmIChkZWZhdWx0QWN0aW9uID09IFNUUklQX1NQQUNFKQotICAgICAgICAgICAgaWwuYXBwZW5kKElDT05TVF8xKTsKLSAgICAgICAgZWxzZQotICAgICAgICAgICAgaWwuYXBwZW5kKElDT05TVF8wKTsKLSAgICAgICAgaWwuYXBwZW5kKElSRVRVUk4pOwotCi0gICAgICAgIGNsYXNzR2VuLmFkZE1ldGhvZChzdHJpcFNwYWNlKTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFRha2VzIGEgdmVjdG9yIG9mIFdoaXRlc3BhY2VSdWxlIG9iamVjdHMgYW5kIGdlbmVyYXRlcyBhIHByZWRpY2F0ZQotICAgICAqIG1ldGhvZC4gVGhpcyBtZXRob2QgcmV0dXJucyB0aGUgdHJhbnNsZXRzIGRlZmF1bHQgYWN0aW9uIGZvciBoYW5kbGluZwotICAgICAqIHdoaXRlc3BhY2UgdGV4dC1ub2RlczoKLSAgICAgKiAgICAtIFVTRV9QUkVESUNBVEUgIChydW4gdGhlIG1ldGhvZCBnZW5lcmF0ZWQgYnkgdGhpcyBtZXRob2QpCi0gICAgICogICAgLSBTVFJJUF9TUEFDRSAgICAoYWx3YXlzIHN0cmlwIHdoaXRlc3BhY2UgdGV4dC1ub2RlcykKLSAgICAgKiAgICAtIFBSRVNFUlZFX1NQQUNFIChhbHdheXMgcHJlc2VydmUgd2hpdGVzcGFjZSB0ZXh0LW5vZGVzKQotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgaW50IHRyYW5zbGF0ZVJ1bGVzKFZlY3RvciBydWxlcywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDbGFzc0dlbmVyYXRvciBjbGFzc0dlbikgewotICAgICAgICAvLyBHZXQgdGhlIGNvcmUgcnVsZXMgaW4gcHJpb3JpdGl6ZWQgb3JkZXIKLSAgICAgICAgZmluYWwgaW50IGRlZmF1bHRBY3Rpb24gPSBwcmlvcml0aXplUnVsZXMocnVsZXMpOwotICAgICAgICAvLyBUaGUgcnVsZXMgdmVjdG9yIG1heSBiZSBlbXB0eSBhZnRlciBwcmlvcml0aXNpbmcKLSAgICAgICAgaWYgKHJ1bGVzLnNpemUoKSA9PSAwKSB7Ci0gICAgICAgICAgICBjb21waWxlRGVmYXVsdChkZWZhdWx0QWN0aW9uLGNsYXNzR2VuKTsKLSAgICAgICAgICAgIHJldHVybiBkZWZhdWx0QWN0aW9uOwotICAgICAgICB9Ci0gICAgICAgIC8vIE5vdyAtIGNyZWF0ZSBhIHByZWRpY2F0ZSBtZXRob2QgYW5kIHNlcXVlbmNlIHRocm91Z2ggcnVsZXMuLi4KLSAgICAgICAgY29tcGlsZVByZWRpY2F0ZShydWxlcywgZGVmYXVsdEFjdGlvbiwgY2xhc3NHZW4pOwotICAgICAgICAvLyBSZXR1cm4gd2l0aCB0aGUgdHJhbnNsZXRzIHJlcXVpcmVkIGFjdGlvbiAoCi0gICAgICAgIHJldHVybiBVU0VfUFJFRElDQVRFOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNvcnRzIGEgcmFuZ2Ugb2YgcnVsZXMgd2l0aCByZWdhcmQgdG8gUFJJT1JJVFkgb25seQotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIHZvaWQgcXVpY2tzb3J0KFZlY3RvciBydWxlcywgaW50IHAsIGludCByKSB7Ci0gICAgICAgIHdoaWxlIChwIDwgcikgewotICAgICAgICAgICAgZmluYWwgaW50IHEgPSBwYXJ0aXRpb24ocnVsZXMsIHAsIHIpOwotICAgICAgICAgICAgcXVpY2tzb3J0KHJ1bGVzLCBwLCBxKTsKLSAgICAgICAgICAgIHAgPSBxICsgMTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFVzZWQgd2l0aCBxdWlja3NvcnQgbWV0aG9kIGFib3ZlCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgaW50IHBhcnRpdGlvbihWZWN0b3IgcnVsZXMsIGludCBwLCBpbnQgcikgewotICAgICAgICBmaW5hbCBXaGl0ZXNwYWNlUnVsZSB4ID0gKFdoaXRlc3BhY2VSdWxlKXJ1bGVzLmVsZW1lbnRBdCgocCtyKSA+Pj4gMSk7Ci0gICAgICAgIGludCBpID0gcCAtIDEsIGogPSByICsgMTsKLSAgICAgICAgd2hpbGUgKHRydWUpIHsKLSAgICAgICAgICAgIHdoaWxlICh4LmNvbXBhcmVUbygoV2hpdGVzcGFjZVJ1bGUpcnVsZXMuZWxlbWVudEF0KC0taikpIDwgMCkgewotICAgICAgICAgICAgfQotICAgICAgICAgICAgd2hpbGUgKHguY29tcGFyZVRvKChXaGl0ZXNwYWNlUnVsZSlydWxlcy5lbGVtZW50QXQoKytpKSkgPiAwKSB7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoaSA8IGopIHsKLSAgICAgICAgICAgICAgICBmaW5hbCBXaGl0ZXNwYWNlUnVsZSB0bXAgPSAoV2hpdGVzcGFjZVJ1bGUpcnVsZXMuZWxlbWVudEF0KGkpOwotICAgICAgICAgICAgICAgIHJ1bGVzLnNldEVsZW1lbnRBdChydWxlcy5lbGVtZW50QXQoaiksIGkpOwotICAgICAgICAgICAgICAgIHJ1bGVzLnNldEVsZW1lbnRBdCh0bXAsIGopOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGo7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUeXBlLWNoZWNrIGNvbnRlbnRzL2F0dHJpYnV0ZXMgLSBub3RoaW5nIHRvIGRvLi4uCi0gICAgICovCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLSAgICAgICAgcmV0dXJuIFR5cGUuVm9pZDsgLy8gV2UgZG9uJ3QgcmV0dXJuIGFueXRoaW5nLgotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIHNob3VsZCBub3QgcHJvZHVjZSBhbnkgY29kZQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvV2l0aFBhcmFtLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL1dpdGhQYXJhbS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzN2Q0Y2Y5Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvV2l0aFBhcmFtLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyNTIgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5BTE9BRDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkFTVE9SRTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkNIRUNLQ0FTVDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkNvbnN0YW50UG9vbEdlbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklOVk9LRUlOVEVSRkFDRTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklOVk9LRVZJUlRVQUw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JbnN0cnVjdGlvbkxpc3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5Mb2NhbFZhcmlhYmxlR2VuOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuUFVTSDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5DbGFzc0dlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5FcnJvck1zZzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5NZXRob2RHZW5lcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuUmVmZXJlbmNlVHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGVDaGVja0Vycm9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlV0aWw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5YTUwxMUNoYXI7Ci0KLS8qKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKiBAYXV0aG9yIEpvaG4gSG93YXJkIDxKb2huSEBzY2hlbWFzb2Z0LmNvbT4KLSAqLwotZmluYWwgY2xhc3MgV2l0aFBhcmFtIGV4dGVuZHMgSW5zdHJ1Y3Rpb24gewotCi0gICAgLyoqCi0gICAgICogUGFyYW1ldGVyJ3MgbmFtZS4KLSAgICAgKi8KLSAgICBwcml2YXRlIFFOYW1lIF9uYW1lOwotCi0gICAgLyoqCi0gICAgICogVGhlIGVzY2FwZWQgcW5hbWUgb2YgdGhlIHdpdGgtcGFyYW0uCi0gICAgICovCi0gICAgcHJvdGVjdGVkIFN0cmluZyBfZXNjYXBlZE5hbWU7Ci0KLSAgICAvKioKLSAgICAgKiBQYXJhbWV0ZXIncyBkZWZhdWx0IHZhbHVlLgotICAgICAqLwotICAgIHByaXZhdGUgRXhwcmVzc2lvbiBfc2VsZWN0OwotCi0gICAgLyoqCi0gICAgICogUmVmZXJlbmNlIHRvIEpWTSB2YXJpYWJsZSBob2xkaW5nIHRlbXBvcmFyeSByZXN1bHQgdHJlZS4KLSAgICAgKi8KLSAgICBwcml2YXRlIExvY2FsVmFyaWFibGVHZW4gX2RvbUFkYXB0ZXI7Ci0KLSAgICAvKioKLSAgICAgKiAlT1BUJSBUaGlzIGlzIHNldCB0byB0cnVlIHdoZW4gdGhlIFdpdGhQYXJhbSBpcyB1c2VkIGluIGEgQ2FsbFRlbXBsYXRlCi0gICAgICogZm9yIGEgc2ltcGxlIG5hbWVkIHRlbXBsYXRlLiBJZiB0aGlzIGlzIHRydWUsIHRoZSBwYXJhbWV0ZXJzIGFyZQotICAgICAqIHBhc3NlZCB0byB0aGUgbmFtZWQgdGVtcGxhdGUgdGhyb3VnaCBtZXRob2QgYXJndW1lbnRzIHJhdGhlciB0aGFuCi0gICAgICogdXNpbmcgdGhlIGV4cGVuc2l2ZSBUcmFuc2xldC5hZGRQYXJhbWV0ZXIoKSBjYWxsLgotICAgICAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBfZG9QYXJhbWV0ZXJPcHRpbWl6YXRpb24gPSBmYWxzZTsKLQotICAgIC8qKgotICAgICAqIERpc3BsYXlzIHRoZSBjb250ZW50cyBvZiB0aGlzIGVsZW1lbnQKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBkaXNwbGF5KGludCBpbmRlbnQpIHsKLSAgICAgICAgaW5kZW50KGluZGVudCk7Ci0gICAgICAgIFV0aWwucHJpbnRsbigid2l0aC1wYXJhbSAiICsgX25hbWUpOwotICAgICAgICBpZiAoX3NlbGVjdCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpbmRlbnQoaW5kZW50ICsgSW5kZW50SW5jcmVtZW50KTsKLSAgICAgICAgICAgIFV0aWwucHJpbnRsbigic2VsZWN0ICIgKyBfc2VsZWN0LnRvU3RyaW5nKCkpOwotICAgICAgICB9Ci0gICAgICAgIGRpc3BsYXlDb250ZW50cyhpbmRlbnQgKyBJbmRlbnRJbmNyZW1lbnQpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIGVzY2FwZWQgcW5hbWUgb2YgdGhlIHBhcmFtZXRlcgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0RXNjYXBlZE5hbWUoKSB7Ci0gICAgICAgIHJldHVybiBfZXNjYXBlZE5hbWU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSBuYW1lIG9mIHRoaXMgV2l0aFBhcmFtLgotICAgICAqLwotICAgIHB1YmxpYyBRTmFtZSBnZXROYW1lKCkgewotICAgICAgICByZXR1cm4gX25hbWU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSBuYW1lIG9mIHRoZSB2YXJpYWJsZSBvciBwYXJlbWV0ZXIuIEVzY2FwZSBhbGwgc3BlY2lhbCBjaGFycy4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXROYW1lKFFOYW1lIG5hbWUpIHsKLSAgICAgICAgX25hbWUgPSBuYW1lOwotICAgICAgICBfZXNjYXBlZE5hbWUgPSBVdGlsLmVzY2FwZShuYW1lLmdldFN0cmluZ1JlcCgpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIGRvIHBhcmFtZXRlciBvcHRpbWl6YXRpb24gZmxhZwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldERvUGFyYW1ldGVyT3B0aW1pemF0aW9uKGJvb2xlYW4gZmxhZykgewotICAgICAgICBfZG9QYXJhbWV0ZXJPcHRpbWl6YXRpb24gPSBmbGFnOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoZSBjb250ZW50cyBvZiBhIDx4c2w6d2l0aC1wYXJhbT4gZWxlbWVudHMgYXJlIGVpdGhlciBpbiB0aGUgZWxlbWVudCdzCi0gICAgICogJ3NlbGVjdCcgYXR0cmlidXRlICh0aGlzIGhhcyBwcmVjZWRlbmNlKSBvciBpbiB0aGUgZWxlbWVudCBib2R5LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHBhcnNlQ29udGVudHMoUGFyc2VyIHBhcnNlcikgewotICAgICAgICBmaW5hbCBTdHJpbmcgbmFtZSA9IGdldEF0dHJpYnV0ZSgibmFtZSIpOwotICAgICAgICBpZiAobmFtZS5sZW5ndGgoKSA+IDApIHsKLSAgICAgICAgICAgIGlmICghWE1MMTFDaGFyLmlzWE1MMTFWYWxpZFFOYW1lKG5hbWUpKSB7Ci0gICAgICAgICAgICAgICAgRXJyb3JNc2cgZXJyID0gbmV3IEVycm9yTXNnKEVycm9yTXNnLklOVkFMSURfUU5BTUVfRVJSLCBuYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzKTsKLSAgICAgICAgICAgICAgICBwYXJzZXIucmVwb3J0RXJyb3IoQ29uc3RhbnRzLkVSUk9SLCBlcnIpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgc2V0TmFtZShwYXJzZXIuZ2V0UU5hbWVJZ25vcmVEZWZhdWx0TnMobmFtZSkpOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgcmVwb3J0RXJyb3IodGhpcywgcGFyc2VyLCBFcnJvck1zZy5SRVFVSVJFRF9BVFRSX0VSUiwgIm5hbWUiKTsKLSAgICAgICAgfQotCi0gICAgICAgIGZpbmFsIFN0cmluZyBzZWxlY3QgPSBnZXRBdHRyaWJ1dGUoInNlbGVjdCIpOwotICAgICAgICBpZiAoc2VsZWN0Lmxlbmd0aCgpID4gMCkgewotICAgICAgICAgICAgX3NlbGVjdCA9IHBhcnNlci5wYXJzZUV4cHJlc3Npb24odGhpcywgInNlbGVjdCIsIG51bGwpOwotICAgICAgICB9Ci0KLSAgICAgICAgcGFyc2VDaGlsZHJlbihwYXJzZXIpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFR5cGUtY2hlY2sgZWl0aGVyIHRoZSBzZWxlY3QgYXR0cmlidXRlIG9yIHRoZSBlbGVtZW50IGJvZHksIGRlcGVuZGluZwotICAgICAqIG9uIHdoaWNoIGlzIGluIHVzZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgVHlwZSB0eXBlQ2hlY2soU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgewotICAgICAgICBpZiAoX3NlbGVjdCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmaW5hbCBUeXBlIHRzZWxlY3QgPSBfc2VsZWN0LnR5cGVDaGVjayhzdGFibGUpOwotICAgICAgICAgICAgaWYgKHRzZWxlY3QgaW5zdGFuY2VvZiBSZWZlcmVuY2VUeXBlID09IGZhbHNlKSB7Ci0gICAgICAgICAgICAgICAgX3NlbGVjdCA9IG5ldyBDYXN0RXhwcihfc2VsZWN0LCBUeXBlLlJlZmVyZW5jZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICB0eXBlQ2hlY2tDb250ZW50cyhzdGFibGUpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBUeXBlLlZvaWQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29tcGlsZSB0aGUgdmFsdWUgb2YgdGhlIHBhcmFtZXRlciwgd2hpY2ggaXMgZWl0aGVyIGluIGFuIGV4cHJlc3Npb24gaW4KLSAgICAgKiBhICdzZWxlY3QnIGF0dHJpYnV0ZSwgb3IgaW4gdGhlIHdpdGgtcGFyYW0gZWxlbWVudCdzIGJvZHkKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVWYWx1ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKQotICAgIHsKLSAgICAgICAgLy8gQ29tcGlsZSBleHByZXNzaW9uIGlzICdzZWxlY3QnIGF0dHJpYnV0ZSBpZiBwcmVzZW50Ci0gICAgICAgIGlmIChfc2VsZWN0ICE9IG51bGwpIHsKLSAgICAgICAgICAgIF9zZWxlY3QudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICAgICAgX3NlbGVjdC5zdGFydEl0ZXJhdG9yKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICAvLyBJZiBub3QsIGNvbXBpbGUgcmVzdWx0IHRyZWUgZnJvbSBwYXJhbWV0ZXIgYm9keSBpZiBwcmVzZW50LgotICAgICAgICAvLyBTdG9yZSByZXN1bHQgdHJlZSBpbnRvIGxvY2FsIHZhcmlhYmxlIGZvciByZWxlYXNpbmcgaXQgbGF0ZXIKLSAgICAgICAgfSBlbHNlIGlmIChoYXNDb250ZW50cygpKSB7Ci0gICAgICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0gICAgICAgICAgICBjb21waWxlUmVzdWx0VHJlZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgICAgIF9kb21BZGFwdGVyID0gbWV0aG9kR2VuLmFkZExvY2FsVmFyaWFibGUyKCJAIiArIF9lc2NhcGVkTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFR5cGUuUmVzdWx0VHJlZS50b0pDVHlwZSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWwuZ2V0RW5kKCkpOwotICAgICAgICAgICAgaWwuYXBwZW5kKERVUCk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IEFTVE9SRShfZG9tQWRhcHRlci5nZXRJbmRleCgpKSk7Ci0gICAgICAgIC8vIElmIG5laXRoZXIgYXJlIHByZXNlbnQgdGhlbiBzdG9yZSBlbXB0eSBzdHJpbmcgaW4gcGFyYW1ldGVyIHNsb3QKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIGZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLSAgICAgICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsIENvbnN0YW50cy5FTVBUWVNUUklORykpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBjb2RlIGdlbmVyYXRlcyBhIHNlcXVlbmNlIG9mIGJ5dGVjb2RlcyB0aGF0IGNhbGwgdGhlCi0gICAgICogYWRkUGFyYW1ldGVyKCkgbWV0aG9kIGluIEFic3RyYWN0VHJhbnNsZXQuIFRoZSBtZXRob2QgY2FsbCB3aWxsIGFkZAotICAgICAqIChvciB1cGRhdGUpIHRoZSBwYXJhbWV0ZXIgZnJhbWUgd2l0aCB0aGUgbmV3IHBhcmFtZXRlciB2YWx1ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLSAgICAgICAgZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0KLSAgICAgICAgLy8gVHJhbnNsYXRlIHRoZSB2YWx1ZSBhbmQgcHV0IGl0IG9uIHRoZSBzdGFjawotICAgICAgICBpZiAoX2RvUGFyYW1ldGVyT3B0aW1pemF0aW9uKSB7Ci0gICAgICAgICAgICB0cmFuc2xhdGVWYWx1ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIE1ha2UgbmFtZSBhY2NlcHRhYmxlIGZvciB1c2UgYXMgZmllbGQgbmFtZSBpbiBjbGFzcwotICAgICAgICBTdHJpbmcgbmFtZSA9IFV0aWwuZXNjYXBlKGdldEVzY2FwZWROYW1lKCkpOwotCi0gICAgICAgIC8vIExvYWQgcmVmZXJlbmNlIHRvIHRoZSB0cmFuc2xldCAobWV0aG9kIGlzIGluIEFic3RyYWN0VHJhbnNsZXQpCi0gICAgICAgIGlsLmFwcGVuZChjbGFzc0dlbi5sb2FkVHJhbnNsZXQoKSk7Ci0KLSAgICAgICAgLy8gTG9hZCB0aGUgbmFtZSBvZiB0aGUgcGFyYW1ldGVyCi0gICAgICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsIG5hbWUpKTsgLy8gVE9ETzogbmFtZXNwYWNlID8KLSAgICAgICAgLy8gR2VuZXJldGUgdGhlIHZhbHVlIG9mIHRoZSBwYXJhbWV0ZXIgKHVzZSB2YWx1ZSBpbiAnc2VsZWN0JyBieSBkZWYuKQotICAgICAgICB0cmFuc2xhdGVWYWx1ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgLy8gTWFyayB0aGlzIHBhcmFtZXRlciB2YWx1ZSBpcyBub3QgYmVpbmcgdGhlIGRlZmF1bHQgdmFsdWUKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgZmFsc2UpKTsKLSAgICAgICAgLy8gUGFzcyB0aGUgcGFyYW1ldGVyIHRvIHRoZSB0ZW1wbGF0ZQotICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRVZJUlRVQUwoY3BnLmFkZE1ldGhvZHJlZihUUkFOU0xFVF9DTEFTUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQUREX1BBUkFNRVRFUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQUREX1BBUkFNRVRFUl9TSUcpKSk7Ci0gICAgICAgIGlsLmFwcGVuZChQT1ApOyAvLyBjbGVhbnVwIHN0YWNrCi0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmVsZWFzZSB0aGUgY29tcGlsZWQgcmVzdWx0IHRyZWUuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcmVsZWFzZVJlc3VsdFRyZWUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikKLSAgICB7Ci0gICAgICAgIGlmIChfZG9tQWRhcHRlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0gICAgICAgICAgICBpZiAoY2xhc3NHZW4uZ2V0U3R5bGVzaGVldCgpLmNhbGxzTm9kZXNldCgpICYmCi0gICAgICAgICAgICAgICAgY2xhc3NHZW4uZ2V0RE9NQ2xhc3MoKS5lcXVhbHMoTVVMVElfRE9NX0NMQVNTKSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBmaW5hbCBpbnQgcmVtb3ZlREEgPQotICAgICAgICAgICAgICAgICAgICBjcGcuYWRkTWV0aG9kcmVmKE1VTFRJX0RPTV9DTEFTUywgInJlbW92ZURPTUFkYXB0ZXIiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoIiArIERPTV9BREFQVEVSX1NJRyArICIpViIpOwotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQobmV3IENIRUNLQ0FTVChjcGcuYWRkQ2xhc3MoTVVMVElfRE9NX0NMQVNTKSkpOwotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgQUxPQUQoX2RvbUFkYXB0ZXIuZ2V0SW5kZXgoKSkpOwotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgQ0hFQ0tDQVNUKGNwZy5hZGRDbGFzcyhET01fQURBUFRFUl9DTEFTUykpKTsKLSAgICAgICAgICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRVZJUlRVQUwocmVtb3ZlREEpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGZpbmFsIGludCByZWxlYXNlID0KLSAgICAgICAgICAgICAgICBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKERPTV9JTVBMX0NMQVNTLCAicmVsZWFzZSIsICIoKVYiKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgQUxPQUQoX2RvbUFkYXB0ZXIuZ2V0SW5kZXgoKSkpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0UocmVsZWFzZSwgMSkpOwotICAgICAgICAgICAgX2RvbUFkYXB0ZXIuc2V0RW5kKGlsLmdldEVuZCgpKTsKLSAgICAgICAgICAgIG1ldGhvZEdlbi5yZW1vdmVMb2NhbFZhcmlhYmxlKF9kb21BZGFwdGVyKTsKLSAgICAgICAgICAgIF9kb21BZGFwdGVyID0gbnVsbDsKLSAgICAgICAgfQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvWFBhdGhMZXhlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9YUGF0aExleGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGVjZGQwMGYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9YUGF0aExleGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNjE5ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IHhwYXRoLmxleCx2IDEuMTIgMjAwNS8wOC8wMiAwMjo1OTowMyBtY25hbWFyYSBFeHAgJAotICovCi0vKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKgotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlcjsKLWltcG9ydCBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sOwotCi0KLWNsYXNzIFhQYXRoTGV4ZXIgaW1wbGVtZW50cyBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU2Nhbm5lciB7Ci0gICAgICAgIHByaXZhdGUgZmluYWwgaW50IFlZX0JVRkZFUl9TSVpFID0gNTEyOwotICAgICAgICBwcml2YXRlIGZpbmFsIGludCBZWV9GID0gLTE7Ci0gICAgICAgIHByaXZhdGUgZmluYWwgaW50IFlZX05PX1NUQVRFID0gLTE7Ci0gICAgICAgIHByaXZhdGUgZmluYWwgaW50IFlZX05PVF9BQ0NFUFQgPSAwOwotICAgICAgICBwcml2YXRlIGZpbmFsIGludCBZWV9TVEFSVCA9IDE7Ci0gICAgICAgIHByaXZhdGUgZmluYWwgaW50IFlZX0VORCA9IDI7Ci0gICAgICAgIHByaXZhdGUgZmluYWwgaW50IFlZX05PX0FOQ0hPUiA9IDQ7Ci0gICAgICAgIHByaXZhdGUgZmluYWwgaW50IFlZX0JPTCA9IDY1NTM2OwotICAgICAgICBwcml2YXRlIGZpbmFsIGludCBZWV9FT0YgPSA2NTUzNzsKLSAgICAgICAgcHVibGljIGZpbmFsIGludCBZWUVPRiA9IC0xOwotCi0gICAgICAgIGludCBsYXN0LCBiZWZvcmVMYXN0OwotICAgICAgICB2b2lkIGluaXRpYWxpemUoKSB7Ci0gICAgICAgICAgICBsYXN0ID0gYmVmb3JlTGFzdCA9IC0xOwotICAgICAgICB9Ci0gICAgICAgIHN0YXRpYyBib29sZWFuIGlzV2hpdGVzcGFjZShpbnQgYykgewotICAgICAgICAgICAgcmV0dXJuIChjID09ICcgJyB8fCBjID09ICdcdCcgfHwgYyA9PSAnXHInIHx8IGMgPT0gJ1xuJyAgfHwgYyA9PSAnXGYnKTsKLSAgICAgICAgfQotICAgICAgICAvKioKLSAgICAgICAgICogSWYgc3ltYm9sIGlzIG5vdCBmb2xsb3dlZCBieSAnOjonIG9yICcoJywgdGhlbiB0cmVhdCBpdCBhcyBhCi0gICAgICAgICAqIG5hbWUgaW5zdGVhZCBvZiBhbiBheGlzIG9yIGZ1bmN0aW9uIChKaXJhLTE5MTIpLgotICAgICAgICAgKi8KLSAgICAgICAgU3ltYm9sIGRpc2FtYmlndWF0ZUF4aXNPckZ1bmN0aW9uKGludCBzcykgdGhyb3dzIEV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICAvLyBQZWVrIGluIHRoZSBpbnB1dCBidWZmZXIgd2l0aG91dCBjaGFuZ2luZyB0aGUgaW50ZXJuYWwgc3RhdGUKLSAgICAgICAgICAgIGludCBpbmRleCA9IHl5X2J1ZmZlcl9pbmRleDsKLSAgICAgICAgICAgIC8vIFNraXAgd2hpdGVzcGFjZQotICAgICAgICAgICAgd2hpbGUgKGluZGV4IDwgeXlfYnVmZmVyX3JlYWQgJiYgaXNXaGl0ZXNwYWNlKHl5X2J1ZmZlcltpbmRleF0pKSB7Ci0gICAgICAgICAgICAgICAgaW5kZXgrKzsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIElmIGVuZCBvZiBidWZmZXIsIGNhbid0IGRpc2FtYmlndWF0ZSA6KAotICAgICAgICAgICAgaWYgKGluZGV4ID49IHl5X2J1ZmZlcl9yZWFkKSB7Ci0gICAgICAgICAgICAgICAgLy8gQ2FuJ3QgZGlzYW1iaWd1YXRlLCBzbyByZXR1cm4gYXMgc3ltYm9sCi0gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTeW1ib2woc3MpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gUmV0dXJuIHN5bWJvbCBpZiBuZXh0IHRva2VuIGlzICc6Oicgb3IgJygnCi0gICAgICAgICAgICByZXR1cm4gKHl5X2J1ZmZlcltpbmRleF0gPT0gJzonICYmIHl5X2J1ZmZlcltpbmRleCsxXSA9PSAnOicgfHwKLSAgICAgICAgICAgICAgICAgICAgeXlfYnVmZmVyW2luZGV4XSA9PSAnKCcpID8KLSAgICAgICAgICAgICAgICAgICAgbmV3U3ltYm9sKHNzKSA6IG5ld1N5bWJvbChzeW0uUU5BTUUsIHl5dGV4dCgpKTsKLSAgICAgICAgfQotICAgICAgICAvKioKLSAgICAgICAgICogSWYgc3ltYm9sIGlzIGZpcnN0IHRva2VuIG9yIGlmIGl0IGZvbGxvd3MgYW55IG9mIHRoZSBvcGVyYXRvcnMKLSAgICAgICAgICogbGlzdGVkIGluIGh0dHA6Ly93d3cudzMub3JnL1RSL3hwYXRoI2V4cHJsZXggdGhlbiB0cmVhdCBhcyBhCi0gICAgICAgICAqIG5hbWUgaW5zdGVhZCBvZiBhIGtleXdvcmQgKEppcmEtMTkxMikuIExvb2sgdHdvIHRva2VucyBiZWhpbmQKLSAgICAgICAgICogdG8gZGVzYW1iaWd1YXRlIGV4cHJlc3Npb25zIGxpa2UgIiogYW5kICoiIG9yICJhbmQgKiBhbmQiLgotICAgICAgICAgKi8KLSAgICAgICAgU3ltYm9sIGRpc2FtYmlndWF0ZU9wZXJhdG9yKGludCBzcykgdGhyb3dzIEV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICBzd2l0Y2ggKGxhc3QpIHsKLSAgICAgICAgICAgIGNhc2Ugc3ltLlNUQVI6Ci0gICAgICAgICAgICAgICAgaWYgKGJlZm9yZUxhc3QgIT0gc3ltLlFOQU1FKSBicmVhazsKLSAgICAgICAgICAgIGNhc2UgLTE6ICAgIC8vIGZpcnN0IHRva2VuCi0gICAgICAgICAgICBjYXNlIHN5bS5BVFNJR046Ci0gICAgICAgICAgICBjYXNlIHN5bS5EQ09MT046Ci0gICAgICAgICAgICBjYXNlIHN5bS5MUEFSRU46Ci0gICAgICAgICAgICBjYXNlIHN5bS5MQlJBQ0s6Ci0gICAgICAgICAgICBjYXNlIHN5bS5DT01NQToKLSAgICAgICAgICAgIGNhc2Ugc3ltLkFORDoKLSAgICAgICAgICAgIGNhc2Ugc3ltLk9SOgotICAgICAgICAgICAgY2FzZSBzeW0uTU9EOgotICAgICAgICAgICAgY2FzZSBzeW0uRElWOgotICAgICAgICAgICAgY2FzZSBzeW0uU0xBU0g6Ci0gICAgICAgICAgICBjYXNlIHN5bS5EU0xBU0g6Ci0gICAgICAgICAgICBjYXNlIHN5bS5WQkFSOgotICAgICAgICAgICAgY2FzZSBzeW0uUExVUzoKLSAgICAgICAgICAgIGNhc2Ugc3ltLk1JTlVTOgotICAgICAgICAgICAgY2FzZSBzeW0uRVE6Ci0gICAgICAgICAgICBjYXNlIHN5bS5ORToKLSAgICAgICAgICAgIGNhc2Ugc3ltLkxUOgotICAgICAgICAgICAgY2FzZSBzeW0uTEU6Ci0gICAgICAgICAgICBjYXNlIHN5bS5HVDoKLSAgICAgICAgICAgIGNhc2Ugc3ltLkdFOgotICAgICAgICAgICAgICAgIHJldHVybiBuZXdTeW1ib2woc3ltLlFOQU1FLCB5eXRleHQoKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gbmV3U3ltYm9sKHNzKTsKLSAgICAgICAgfQotICAgICAgICBTeW1ib2wgbmV3U3ltYm9sKGludCBzcykgewotICAgICAgICAgICAgYmVmb3JlTGFzdCA9IGxhc3Q7Ci0gICAgICAgICAgICBsYXN0ID0gc3M7Ci0gICAgICAgICAgICByZXR1cm4gbmV3IFN5bWJvbChzcyk7Ci0gICAgICAgIH0KLSAgICAgICAgU3ltYm9sIG5ld1N5bWJvbChpbnQgc3MsIFN0cmluZyB2YWx1ZSkgewotICAgICAgICAgICAgYmVmb3JlTGFzdCA9IGxhc3Q7Ci0gICAgICAgICAgICBsYXN0ID0gc3M7Ci0gICAgICAgICAgICByZXR1cm4gbmV3IFN5bWJvbChzcywgdmFsdWUpOwotICAgICAgICB9Ci0gICAgICAgIFN5bWJvbCBuZXdTeW1ib2woaW50IHNzLCBMb25nIHZhbHVlKSB7Ci0gICAgICAgICAgICBiZWZvcmVMYXN0ID0gbGFzdDsKLSAgICAgICAgICAgIGxhc3QgPSBzczsKLSAgICAgICAgICAgIHJldHVybiBuZXcgU3ltYm9sKHNzLCB2YWx1ZSk7Ci0gICAgICAgIH0KLSAgICAgICAgU3ltYm9sIG5ld1N5bWJvbChpbnQgc3MsIERvdWJsZSB2YWx1ZSkgewotICAgICAgICAgICAgYmVmb3JlTGFzdCA9IGxhc3Q7Ci0gICAgICAgICAgICBsYXN0ID0gc3M7Ci0gICAgICAgICAgICByZXR1cm4gbmV3IFN5bWJvbChzcywgdmFsdWUpOwotICAgICAgICB9Ci0gICAgICAgIHByaXZhdGUgamF2YS5pby5CdWZmZXJlZFJlYWRlciB5eV9yZWFkZXI7Ci0gICAgICAgIHByaXZhdGUgaW50IHl5X2J1ZmZlcl9pbmRleDsKLSAgICAgICAgcHJpdmF0ZSBpbnQgeXlfYnVmZmVyX3JlYWQ7Ci0gICAgICAgIHByaXZhdGUgaW50IHl5X2J1ZmZlcl9zdGFydDsKLSAgICAgICAgcHJpdmF0ZSBpbnQgeXlfYnVmZmVyX2VuZDsKLSAgICAgICAgcHJpdmF0ZSBjaGFyIHl5X2J1ZmZlcltdOwotICAgICAgICBwcml2YXRlIGJvb2xlYW4geXlfYXRfYm9sOwotICAgICAgICBwcml2YXRlIGludCB5eV9sZXhpY2FsX3N0YXRlOwotCi0gICAgICAgIFhQYXRoTGV4ZXIgKGphdmEuaW8uUmVhZGVyIHJlYWRlcikgewotICAgICAgICAgICAgICAgIHRoaXMgKCk7Ci0gICAgICAgICAgICAgICAgaWYgKG51bGwgPT0gcmVhZGVyKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyAobmV3IEVycm9yKCJFcnJvcjogQmFkIGlucHV0IHN0cmVhbSBpbml0aWFsaXplci4iKSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHl5X3JlYWRlciA9IG5ldyBqYXZhLmlvLkJ1ZmZlcmVkUmVhZGVyKHJlYWRlcik7Ci0gICAgICAgIH0KLQotICAgICAgICBYUGF0aExleGVyIChqYXZhLmlvLklucHV0U3RyZWFtIGluc3RyZWFtKSB7Ci0gICAgICAgICAgICAgICAgdGhpcyAoKTsKLSAgICAgICAgICAgICAgICBpZiAobnVsbCA9PSBpbnN0cmVhbSkgewotICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgKG5ldyBFcnJvcigiRXJyb3I6IEJhZCBpbnB1dCBzdHJlYW0gaW5pdGlhbGl6ZXIuIikpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB5eV9yZWFkZXIgPSBuZXcgamF2YS5pby5CdWZmZXJlZFJlYWRlcihuZXcgamF2YS5pby5JbnB1dFN0cmVhbVJlYWRlcihpbnN0cmVhbSkpOwotICAgICAgICB9Ci0KLSAgICAgICAgcHJpdmF0ZSBYUGF0aExleGVyICgpIHsKLSAgICAgICAgICAgICAgICB5eV9idWZmZXIgPSBuZXcgY2hhcltZWV9CVUZGRVJfU0laRV07Ci0gICAgICAgICAgICAgICAgeXlfYnVmZmVyX3JlYWQgPSAwOwotICAgICAgICAgICAgICAgIHl5X2J1ZmZlcl9pbmRleCA9IDA7Ci0gICAgICAgICAgICAgICAgeXlfYnVmZmVyX3N0YXJ0ID0gMDsKLSAgICAgICAgICAgICAgICB5eV9idWZmZXJfZW5kID0gMDsKLSAgICAgICAgICAgICAgICB5eV9hdF9ib2wgPSB0cnVlOwotICAgICAgICAgICAgICAgIHl5X2xleGljYWxfc3RhdGUgPSBZWUlOSVRJQUw7Ci0gICAgICAgIH0KLQotICAgICAgICBwcml2YXRlIGJvb2xlYW4geXlfZW9mX2RvbmUgPSBmYWxzZTsKLSAgICAgICAgcHJpdmF0ZSBmaW5hbCBpbnQgWVlJTklUSUFMID0gMDsKLSAgICAgICAgcHJpdmF0ZSBmaW5hbCBpbnQgeXlfc3RhdGVfZHRyYW5zW10gPSB7Ci0gICAgICAgICAgICAgICAgMAotICAgICAgICB9OwotICAgICAgICBwcml2YXRlIHZvaWQgeXliZWdpbiAoaW50IHN0YXRlKSB7Ci0gICAgICAgICAgICAgICAgeXlfbGV4aWNhbF9zdGF0ZSA9IHN0YXRlOwotICAgICAgICB9Ci0gICAgICAgIHByaXZhdGUgaW50IHl5X2FkdmFuY2UgKCkKLSAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7Ci0gICAgICAgICAgICAgICAgaW50IG5leHRfcmVhZDsKLSAgICAgICAgICAgICAgICBpbnQgaTsKLSAgICAgICAgICAgICAgICBpbnQgajsKLQotICAgICAgICAgICAgICAgIGlmICh5eV9idWZmZXJfaW5kZXggPCB5eV9idWZmZXJfcmVhZCkgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHl5X2J1ZmZlclt5eV9idWZmZXJfaW5kZXgrK107Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgaWYgKDAgIT0geXlfYnVmZmVyX3N0YXJ0KSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpID0geXlfYnVmZmVyX3N0YXJ0OwotICAgICAgICAgICAgICAgICAgICAgICAgaiA9IDA7Ci0gICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoaSA8IHl5X2J1ZmZlcl9yZWFkKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHl5X2J1ZmZlcltqXSA9IHl5X2J1ZmZlcltpXTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKytpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArK2o7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICB5eV9idWZmZXJfZW5kID0geXlfYnVmZmVyX2VuZCAtIHl5X2J1ZmZlcl9zdGFydDsKLSAgICAgICAgICAgICAgICAgICAgICAgIHl5X2J1ZmZlcl9zdGFydCA9IDA7Ci0gICAgICAgICAgICAgICAgICAgICAgICB5eV9idWZmZXJfcmVhZCA9IGo7Ci0gICAgICAgICAgICAgICAgICAgICAgICB5eV9idWZmZXJfaW5kZXggPSBqOwotICAgICAgICAgICAgICAgICAgICAgICAgbmV4dF9yZWFkID0geXlfcmVhZGVyLnJlYWQoeXlfYnVmZmVyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHl5X2J1ZmZlcl9yZWFkLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHl5X2J1ZmZlci5sZW5ndGggLSB5eV9idWZmZXJfcmVhZCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoLTEgPT0gbmV4dF9yZWFkKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBZWV9FT0Y7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICB5eV9idWZmZXJfcmVhZCA9IHl5X2J1ZmZlcl9yZWFkICsgbmV4dF9yZWFkOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIHdoaWxlICh5eV9idWZmZXJfaW5kZXggPj0geXlfYnVmZmVyX3JlYWQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmICh5eV9idWZmZXJfaW5kZXggPj0geXlfYnVmZmVyLmxlbmd0aCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5eV9idWZmZXIgPSB5eV9kb3VibGUoeXlfYnVmZmVyKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIG5leHRfcmVhZCA9IHl5X3JlYWRlci5yZWFkKHl5X2J1ZmZlciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5eV9idWZmZXJfcmVhZCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5eV9idWZmZXIubGVuZ3RoIC0geXlfYnVmZmVyX3JlYWQpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKC0xID09IG5leHRfcmVhZCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gWVlfRU9GOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgeXlfYnVmZmVyX3JlYWQgPSB5eV9idWZmZXJfcmVhZCArIG5leHRfcmVhZDsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHl5X2J1ZmZlclt5eV9idWZmZXJfaW5kZXgrK107Ci0gICAgICAgIH0KLSAgICAgICAgcHJpdmF0ZSB2b2lkIHl5X21vdmVfZW5kICgpIHsKLSAgICAgICAgICAgICAgICBpZiAoeXlfYnVmZmVyX2VuZCA+IHl5X2J1ZmZlcl9zdGFydCAmJgotICAgICAgICAgICAgICAgICAgICAnXG4nID09IHl5X2J1ZmZlclt5eV9idWZmZXJfZW5kLTFdKQotICAgICAgICAgICAgICAgICAgICAgICAgeXlfYnVmZmVyX2VuZC0tOwotICAgICAgICAgICAgICAgIGlmICh5eV9idWZmZXJfZW5kID4geXlfYnVmZmVyX3N0YXJ0ICYmCi0gICAgICAgICAgICAgICAgICAgICdccicgPT0geXlfYnVmZmVyW3l5X2J1ZmZlcl9lbmQtMV0pCi0gICAgICAgICAgICAgICAgICAgICAgICB5eV9idWZmZXJfZW5kLS07Ci0gICAgICAgIH0KLSAgICAgICAgcHJpdmF0ZSBib29sZWFuIHl5X2xhc3Rfd2FzX2NyPWZhbHNlOwotICAgICAgICBwcml2YXRlIHZvaWQgeXlfbWFya19zdGFydCAoKSB7Ci0gICAgICAgICAgICAgICAgeXlfYnVmZmVyX3N0YXJ0ID0geXlfYnVmZmVyX2luZGV4OwotICAgICAgICB9Ci0gICAgICAgIHByaXZhdGUgdm9pZCB5eV9tYXJrX2VuZCAoKSB7Ci0gICAgICAgICAgICAgICAgeXlfYnVmZmVyX2VuZCA9IHl5X2J1ZmZlcl9pbmRleDsKLSAgICAgICAgfQotICAgICAgICBwcml2YXRlIHZvaWQgeXlfdG9fbWFyayAoKSB7Ci0gICAgICAgICAgICAgICAgeXlfYnVmZmVyX2luZGV4ID0geXlfYnVmZmVyX2VuZDsKLSAgICAgICAgICAgICAgICB5eV9hdF9ib2wgPSAoeXlfYnVmZmVyX2VuZCA+IHl5X2J1ZmZlcl9zdGFydCkgJiYKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAoJ1xyJyA9PSB5eV9idWZmZXJbeXlfYnVmZmVyX2VuZC0xXSB8fAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnXG4nID09IHl5X2J1ZmZlclt5eV9idWZmZXJfZW5kLTFdIHx8Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIDIwMjgvKkxTKi8gPT0geXlfYnVmZmVyW3l5X2J1ZmZlcl9lbmQtMV0gfHwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMjAyOS8qUFMqLyA9PSB5eV9idWZmZXJbeXlfYnVmZmVyX2VuZC0xXSk7Ci0gICAgICAgIH0KLSAgICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIHl5dGV4dCAoKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIChuZXcgamF2YS5sYW5nLlN0cmluZyh5eV9idWZmZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICB5eV9idWZmZXJfc3RhcnQsCi0gICAgICAgICAgICAgICAgICAgICAgICB5eV9idWZmZXJfZW5kIC0geXlfYnVmZmVyX3N0YXJ0KSk7Ci0gICAgICAgIH0KLSAgICAgICAgcHJpdmF0ZSBpbnQgeXlsZW5ndGggKCkgewotICAgICAgICAgICAgICAgIHJldHVybiB5eV9idWZmZXJfZW5kIC0geXlfYnVmZmVyX3N0YXJ0OwotICAgICAgICB9Ci0gICAgICAgIHByaXZhdGUgY2hhcltdIHl5X2RvdWJsZSAoY2hhciBidWZbXSkgewotICAgICAgICAgICAgICAgIGludCBpOwotICAgICAgICAgICAgICAgIGNoYXIgbmV3YnVmW107Ci0gICAgICAgICAgICAgICAgbmV3YnVmID0gbmV3IGNoYXJbMipidWYubGVuZ3RoXTsKLSAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgYnVmLmxlbmd0aDsgKytpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBuZXdidWZbaV0gPSBidWZbaV07Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHJldHVybiBuZXdidWY7Ci0gICAgICAgIH0KLSAgICAgICAgcHJpdmF0ZSBmaW5hbCBpbnQgWVlfRV9JTlRFUk5BTCA9IDA7Ci0gICAgICAgIHByaXZhdGUgZmluYWwgaW50IFlZX0VfTUFUQ0ggPSAxOwotICAgICAgICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgeXlfZXJyb3Jfc3RyaW5nW10gPSB7Ci0gICAgICAgICAgICAgICAgIkVycm9yOiBJbnRlcm5hbCBlcnJvci5cbiIsCi0gICAgICAgICAgICAgICAgIkVycm9yOiBVbm1hdGNoZWQgaW5wdXQuXG4iCi0gICAgICAgIH07Ci0gICAgICAgIHByaXZhdGUgdm9pZCB5eV9lcnJvciAoaW50IGNvZGUsYm9vbGVhbiBmYXRhbCkgewotICAgICAgICAgICAgICAgIGphdmEubGFuZy5TeXN0ZW0ub3V0LnByaW50KHl5X2Vycm9yX3N0cmluZ1tjb2RlXSk7Ci0gICAgICAgICAgICAgICAgamF2YS5sYW5nLlN5c3RlbS5vdXQuZmx1c2goKTsKLSAgICAgICAgICAgICAgICBpZiAoZmF0YWwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigiRmF0YWwgRXJyb3IuXG4iKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgc3RhdGljIHByaXZhdGUgaW50W11bXSB1bnBhY2tGcm9tU3RyaW5nKGludCBzaXplMSwgaW50IHNpemUyLCBTdHJpbmcgc3QpIHsKLSAgICAgICAgICAgICAgICBpbnQgY29sb25JbmRleCA9IC0xOwotICAgICAgICAgICAgICAgIFN0cmluZyBsZW5ndGhTdHJpbmc7Ci0gICAgICAgICAgICAgICAgaW50IHNlcXVlbmNlTGVuZ3RoID0gMDsKLSAgICAgICAgICAgICAgICBpbnQgc2VxdWVuY2VJbnRlZ2VyID0gMDsKLQotICAgICAgICAgICAgICAgIGludCBjb21tYUluZGV4OwotICAgICAgICAgICAgICAgIFN0cmluZyB3b3JrU3RyaW5nOwotCi0gICAgICAgICAgICAgICAgaW50IHJlc1tdW10gPSBuZXcgaW50W3NpemUxXVtzaXplMl07Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaT0gMDsgaSA8IHNpemUxOyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGo9IDA7IGogPCBzaXplMjsgaisrKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZXF1ZW5jZUxlbmd0aCAhPSAwKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzW2ldW2pdID0gc2VxdWVuY2VJbnRlZ2VyOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlcXVlbmNlTGVuZ3RoLS07Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tbWFJbmRleCA9IHN0LmluZGV4T2YoJywnKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd29ya1N0cmluZyA9IChjb21tYUluZGV4PT0tMSkgPyBzdCA6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Quc3Vic3RyaW5nKDAsIGNvbW1hSW5kZXgpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdCA9IHN0LnN1YnN0cmluZyhjb21tYUluZGV4KzEpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvbkluZGV4ID0gd29ya1N0cmluZy5pbmRleE9mKCc6Jyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb2xvbkluZGV4ID09IC0xKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzW2ldW2pdPUludGVnZXIucGFyc2VJbnQod29ya1N0cmluZyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVuZ3RoU3RyaW5nID0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3b3JrU3RyaW5nLnN1YnN0cmluZyhjb2xvbkluZGV4KzEpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXF1ZW5jZUxlbmd0aD1JbnRlZ2VyLnBhcnNlSW50KGxlbmd0aFN0cmluZyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdvcmtTdHJpbmc9d29ya1N0cmluZy5zdWJzdHJpbmcoMCxjb2xvbkluZGV4KTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VxdWVuY2VJbnRlZ2VyPUludGVnZXIucGFyc2VJbnQod29ya1N0cmluZyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc1tpXVtqXSA9IHNlcXVlbmNlSW50ZWdlcjsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VxdWVuY2VMZW5ndGgtLTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHJlczsKLSAgICAgICAgfQotICAgICAgICBwcml2YXRlIGludCB5eV9hY3B0W10gPSB7Ci0gICAgICAgICAgICAgICAgLyogMCAqLyBZWV9OT1RfQUNDRVBULAotICAgICAgICAgICAgICAgIC8qIDEgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDIgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDMgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDQgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDUgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDYgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDcgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDggKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDkgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDEwICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiAxMSAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogMTIgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDEzICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiAxNCAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogMTUgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDE2ICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiAxNyAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogMTggKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDE5ICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiAyMCAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogMjEgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDIyICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiAyMyAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogMjQgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDI1ICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiAyNiAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogMjcgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDI4ICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiAyOSAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogMzAgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDMxICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiAzMiAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogMzMgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDM0ICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiAzNSAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogMzYgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDM3ICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiAzOCAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogMzkgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDQwICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiA0MSAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogNDIgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDQzICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiA0NCAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogNDUgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDQ2ICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiA0NyAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogNDggKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDQ5ICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiA1MCAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogNTEgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDUyICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiA1MyAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogNTQgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDU1ICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiA1NiAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogNTcgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDU4ICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiA1OSAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogNjAgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDYxICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiA2MiAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogNjMgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDY0ICovIFlZX05PVF9BQ0NFUFQsCi0gICAgICAgICAgICAgICAgLyogNjUgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDY2ICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiA2NyAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogNjggKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDY5ICovIFlZX05PVF9BQ0NFUFQsCi0gICAgICAgICAgICAgICAgLyogNzAgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDcxICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiA3MiAqLyBZWV9OT1RfQUNDRVBULAotICAgICAgICAgICAgICAgIC8qIDczICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiA3NCAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogNzUgKi8gWVlfTk9UX0FDQ0VQVCwKLSAgICAgICAgICAgICAgICAvKiA3NiAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogNzcgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDc4ICovIFlZX05PVF9BQ0NFUFQsCi0gICAgICAgICAgICAgICAgLyogNzkgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDgwICovIFlZX05PVF9BQ0NFUFQsCi0gICAgICAgICAgICAgICAgLyogODEgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDgyICovIFlZX05PVF9BQ0NFUFQsCi0gICAgICAgICAgICAgICAgLyogODMgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDg0ICovIFlZX05PVF9BQ0NFUFQsCi0gICAgICAgICAgICAgICAgLyogODUgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDg2ICovIFlZX05PVF9BQ0NFUFQsCi0gICAgICAgICAgICAgICAgLyogODcgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDg4ICovIFlZX05PVF9BQ0NFUFQsCi0gICAgICAgICAgICAgICAgLyogODkgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDkwICovIFlZX05PVF9BQ0NFUFQsCi0gICAgICAgICAgICAgICAgLyogOTEgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDkyICovIFlZX05PVF9BQ0NFUFQsCi0gICAgICAgICAgICAgICAgLyogOTMgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDk0ICovIFlZX05PVF9BQ0NFUFQsCi0gICAgICAgICAgICAgICAgLyogOTUgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDk2ICovIFlZX05PVF9BQ0NFUFQsCi0gICAgICAgICAgICAgICAgLyogOTcgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDk4ICovIFlZX05PVF9BQ0NFUFQsCi0gICAgICAgICAgICAgICAgLyogOTkgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDEwMCAqLyBZWV9OT1RfQUNDRVBULAotICAgICAgICAgICAgICAgIC8qIDEwMSAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogMTAyICovIFlZX05PVF9BQ0NFUFQsCi0gICAgICAgICAgICAgICAgLyogMTAzICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiAxMDQgKi8gWVlfTk9UX0FDQ0VQVCwKLSAgICAgICAgICAgICAgICAvKiAxMDUgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDEwNiAqLyBZWV9OT1RfQUNDRVBULAotICAgICAgICAgICAgICAgIC8qIDEwNyAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogMTA4ICovIFlZX05PVF9BQ0NFUFQsCi0gICAgICAgICAgICAgICAgLyogMTA5ICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiAxMTAgKi8gWVlfTk9UX0FDQ0VQVCwKLSAgICAgICAgICAgICAgICAvKiAxMTEgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDExMiAqLyBZWV9OT1RfQUNDRVBULAotICAgICAgICAgICAgICAgIC8qIDExMyAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogMTE0ICovIFlZX05PVF9BQ0NFUFQsCi0gICAgICAgICAgICAgICAgLyogMTE1ICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiAxMTYgKi8gWVlfTk9UX0FDQ0VQVCwKLSAgICAgICAgICAgICAgICAvKiAxMTcgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDExOCAqLyBZWV9OT1RfQUNDRVBULAotICAgICAgICAgICAgICAgIC8qIDExOSAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogMTIwICovIFlZX05PVF9BQ0NFUFQsCi0gICAgICAgICAgICAgICAgLyogMTIxICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiAxMjIgKi8gWVlfTk9UX0FDQ0VQVCwKLSAgICAgICAgICAgICAgICAvKiAxMjMgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDEyNCAqLyBZWV9OT1RfQUNDRVBULAotICAgICAgICAgICAgICAgIC8qIDEyNSAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogMTI2ICovIFlZX05PVF9BQ0NFUFQsCi0gICAgICAgICAgICAgICAgLyogMTI3ICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiAxMjggKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDEyOSAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogMTMwICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiAxMzEgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDEzMiAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogMTMzICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiAxMzQgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDEzNSAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogMTM2ICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiAxMzcgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDEzOCAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogMTM5ICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiAxNDAgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDE0MSAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogMTQyICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiAxNDMgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDE0NCAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogMTQ1ICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiAxNDYgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDE0NyAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogMTQ4ICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiAxNDkgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDE1MCAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogMTUxICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiAxNTIgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDE1MyAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogMTU0ICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiAxNTUgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDE1NiAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogMTU3ICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiAxNTggKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDE1OSAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogMTYwICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiAxNjEgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDE2MiAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogMTYzICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiAxNjQgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDE2NSAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogMTY2ICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiAxNjcgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDE2OCAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogMTY5ICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiAxNzAgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDE3MSAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogMTcyICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiAxNzMgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDE3NCAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogMTc1ICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiAxNzYgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDE3NyAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogMTc4ICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiAxNzkgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDE4MCAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogMTgxICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiAxODIgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDE4MyAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogMTg0ICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiAxODUgKi8gWVlfTk9UX0FDQ0VQVCwKLSAgICAgICAgICAgICAgICAvKiAxODYgKi8gWVlfTk9UX0FDQ0VQVCwKLSAgICAgICAgICAgICAgICAvKiAxODcgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDE4OCAqLyBZWV9OT1RfQUNDRVBULAotICAgICAgICAgICAgICAgIC8qIDE4OSAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogMTkwICovIFlZX05PVF9BQ0NFUFQsCi0gICAgICAgICAgICAgICAgLyogMTkxICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiAxOTIgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDE5MyAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogMTk0ICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiAxOTUgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDE5NiAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogMTk3ICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiAxOTggKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDE5OSAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogMjAwICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiAyMDEgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDIwMiAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogMjAzICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiAyMDQgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDIwNSAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogMjA2ICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiAyMDcgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDIwOCAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogMjA5ICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiAyMTAgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDIxMSAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogMjEyICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiAyMTMgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDIxNCAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogMjE1ICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiAyMTYgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDIxNyAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogMjE4ICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiAyMTkgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDIyMCAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogMjIxICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiAyMjIgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDIyMyAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogMjI0ICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiAyMjUgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDIyNiAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogMjI3ICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiAyMjggKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDIyOSAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogMjMwICovIFlZX05PX0FOQ0hPUiwKLSAgICAgICAgICAgICAgICAvKiAyMzEgKi8gWVlfTk9fQU5DSE9SLAotICAgICAgICAgICAgICAgIC8qIDIzMiAqLyBZWV9OT19BTkNIT1IsCi0gICAgICAgICAgICAgICAgLyogMjMzICovIFlZX05PX0FOQ0hPUgotICAgICAgICB9OwotICAgICAgICBzdGF0aWMgcHJpdmF0ZSBpbnQgeXlfY21hcFtdID0gdW5wYWNrRnJvbVN0cmluZygxLDY1NTM4LAotIjU0OjksMjc6Miw1NCwyNzoyLDU0OjE4LDI3LDE3LDUzLDU0LDE1LDU0OjIsNTUsMjUsMjYsMSwzLDExLDQsMTMsMiw1NjoxMCwxMCIgKwotIiw1NCwxOCwxNiwxOSw1NCwxMiw0NCw1NzozLDQ2LDU3OjMsNTEsNTc6NCw0OCw1Miw0Myw1Nyw0Nyw1MCw0NSw1NzozLDQ5LDU3OiIgKwotIjIsNDEsNTQsNDIsNTQsNTgsNTQsMzUsMzgsMjksNSwyMSwzOSwzMywzNiw2LDU3LDIwLDM3LDgsMjgsOSwzMCw1NywzMSwzMiwyMyIgKwotIiwzNCw3LDQwLDI0LDIyLDU3LDU0LDE0LDU0OjU4LDYwLDU0OjgsNTc6MjMsNTQsNTc6MzEsNTQsNTc6NTgsNTg6Miw1NzoxMSw1OCIgKwotIjoyLDU3OjgsNTgsNTc6NTMsNTgsNTc6NjgsNTg6OSw1NzozNiw1ODozLDU3OjIsNTg6NCw1NzozMCw1ODo1Niw1Nzo4OSw1ODoxOCIgKwotIiw1Nzo3LDU4OjYyLDYwOjcwLDU0OjI2LDYwOjIsNTQ6MTQsNTg6MTQsNTQsNTg6Nyw1Nyw1OCw1NzozLDU4LDU3LDU4LDU3OjIwLCIgKwotIjU4LDU3OjQ0LDU4LDU3OjcsNTg6Myw1Nyw1OCw1Nyw1OCw1Nyw1OCw1Nyw1OCw1NzoxOCw1ODoxMyw1NzoxMiw1OCw1Nzo2Niw1OCIgKwotIiw1NzoxMiw1OCw1NzozNiw1ODoxNCw1Nzo1Myw1ODoyLDU3OjIsNTg6Miw1NzoyLDU4OjMsNTc6MjgsNTg6Miw1Nzo4LDU4OjIsNSIgKwotIjc6Miw1ODo1NSw1NzozOCw1ODoyLDU3LDU4OjcsNTc6MzgsNTg6NzMsNTc6MjcsNTg6NSw1NzozLDU4OjQ2LDU3OjI2LDU4OjYsNSIgKwotIjc6MTAsNTg6MjEsNTk6MTAsNTg6Nyw1Nzo3MSw1ODoyLDU3OjUsNTgsNTc6MTUsNTgsNTc6NCw1OCw1Nyw1ODoxNSw1NzoyLDU4OiIgKwotIjksNTk6MTAsNTg6NTIzLDU3OjUzLDU4OjMsNTcsNTg6MjYsNTc6MTAsNTg6NCw1OToxMCw1ODoyMSw1Nzo4LDU4OjIsNTc6Miw1OCIgKwotIjoyLDU3OjIyLDU4LDU3OjcsNTgsNTcsNTg6Myw1Nzo0LDU4OjM0LDU3OjIsNTgsNTc6Myw1ODo0LDU5OjEwLDU3OjIsNTg6MTksNSIgKwotIjc6Niw1ODo0LDU3OjIsNTg6Miw1NzoyMiw1OCw1Nzo3LDU4LDU3OjIsNTgsNTc6Miw1OCw1NzoyLDU4OjMxLDU3OjQsNTgsNTcsNSIgKwotIjg6Nyw1OToxMCw1ODoyLDU3OjMsNTg6MTYsNTc6Nyw1OCw1Nyw1OCw1NzozLDU4LDU3OjIyLDU4LDU3OjcsNTgsNTc6Miw1OCw1NyIgKwotIjo1LDU4OjMsNTcsNTg6MzQsNTcsNTg6NSw1OToxMCw1ODoyMSw1Nzo4LDU4OjIsNTc6Miw1ODoyLDU3OjIyLDU4LDU3OjcsNTgsNSIgKwotIjc6Miw1ODoyLDU3OjQsNTg6Myw1Nyw1ODozMCw1NzoyLDU4LDU3OjMsNTg6NCw1OToxMCw1ODoyMSw1Nzo2LDU4OjMsNTc6Myw1OCIgKwotIiw1Nzo0LDU4OjMsNTc6Miw1OCw1Nyw1OCw1NzoyLDU4OjMsNTc6Miw1ODozLDU3OjMsNTg6Myw1Nzo4LDU4LDU3OjMsNTg6NDUsNSIgKwotIjk6OSw1ODoyMSw1Nzo4LDU4LDU3OjMsNTgsNTc6MjMsNTgsNTc6MTAsNTgsNTc6NSw1ODozOCw1NzoyLDU4OjQsNTk6MTAsNTg6MiIgKwotIjEsNTc6OCw1OCw1NzozLDU4LDU3OjIzLDU4LDU3OjEwLDU4LDU3OjUsNTg6MzYsNTcsNTgsNTc6Miw1ODo0LDU5OjEwLDU4OjIxLCIgKwotIjU3OjgsNTgsNTc6Myw1OCw1NzoyMyw1OCw1NzoxNiw1ODozOCw1NzoyLDU4OjQsNTk6MTAsNTg6MTQ1LDU3OjQ2LDU4LDU3LDU4LCIgKwotIjU3OjIsNTg6MTIsNTc6Niw1ODoxMCw1OToxMCw1ODozOSw1NzoyLDU4LDU3LDU4OjIsNTc6Miw1OCw1Nyw1ODoyLDU3LDU4OjYsNSIgKwotIjc6NCw1OCw1Nzo3LDU4LDU3OjMsNTgsNTcsNTgsNTcsNTg6Miw1NzoyLDU4LDU3OjIsNTgsNTcsNTgsNTc6Miw1ODo5LDU3LDU4OiIgKwotIjIsNTc6NSw1ODoxMSw1OToxMCw1ODo3MCw1OToxMCw1ODoyMiw1Nzo4LDU4LDU3OjMzLDU4OjMxMCw1NzozOCw1ODoxMCw1NzozOSIgKwotIiw1ODo5LDU3LDU4LDU3OjIsNTgsNTc6Myw1OCw1Nyw1OCw1NzoyLDU4LDU3OjUsNTg6NDEsNTcsNTgsNTcsNTgsNTcsNTg6MTEsNSIgKwotIjcsNTgsNTcsNTgsNTcsNTg6Myw1NzoyLDU4OjMsNTcsNTg6NSw1NzozLDU4LDU3LDU4LDU3LDU4LDU3LDU4LDU3LDU4OjMsNTc6MiIgKwotIiw1ODozLDU3OjIsNTgsNTcsNTg6NDAsNTcsNTg6OSw1Nyw1ODoyLDU3LDU4OjIsNTc6Miw1ODo3LDU3OjIsNTgsNTcsNTgsNTc6NyIgKwotIiw1ODo0MCw1Nyw1ODo0LDU3LDU4OjgsNTcsNTg6MzA3OCw1NzoxNTYsNTg6NCw1Nzo5MCw1ODo2LDU3OjIyLDU4OjIsNTc6Niw1OCIgKwotIjoyLDU3OjM4LDU4OjIsNTc6Niw1ODoyLDU3OjgsNTgsNTcsNTgsNTcsNTgsNTcsNTgsNTc6MzEsNTg6Miw1Nzo1Myw1OCw1Nzo3LCIgKwotIjU4LDU3LDU4OjMsNTc6Myw1OCw1Nzo3LDU4OjMsNTc6NCw1ODoyLDU3OjYsNTg6NCw1NzoxMyw1ODo1LDU3OjMsNTgsNTc6Nyw1OCIgKwotIjozLDU0OjEyLDU4OjIsNTQ6OTgsNTg6MTgyLDU3LDU4OjMsNTc6Miw1ODoyLDU3LDU4OjgxLDU3OjMsNTg6MTMsNTQ6MjY3Miw1OCIgKwotIjoxMDA4LDU0OjE3LDU4OjY0LDU3Ojg0LDU4OjEyLDU3OjkwLDU4OjEwLDU3OjQwLDU4OjMxNDQzLDU3OjExMTcyLDU4OjkyLDU0OiIgKwotIjg0NDgsNTg6MTIzMiw1NDozMiw1ODo1MjYsNTQ6MiwwOjIiKVswXTsKLQotICAgICAgICBzdGF0aWMgcHJpdmF0ZSBpbnQgeXlfcm1hcFtdID0gdW5wYWNrRnJvbVN0cmluZygxLDIzNCwKLSIwLDE6MiwyLDE6MiwzLDQsMSw1LDYsMTozLDcsOCwxOjUsOSwxLDEwOjIsMTozLDExLDE6NSwxMiwxMCwxLDEwOjUsMToyLDEwLDEiICsKLSI6MiwxMywxLDEwLDEsMTQsMTAsMTUsMTYsMToyLDEwOjQsMTcsMToyLDE4LDE5LDIwLDIxLDIyLDIzLDI0LDI1LDI2LDI3LDEsMjUiICsKLSIsMTAsMjg6MiwyOSw1LDMwLDMxLDMyLDMzLDM0LDM1LDM2LDM3LDM4LDM5LDQwLDQxLDQyLDQzLDQ0LDQ1LDQ2LDQ3LDQ4LDQ5LDUiICsKLSIwLDUxLDUyLDUzLDU0LDU1LDU2LDU3LDU4LDU5LDYwLDYxLDYyLDYzLDY0LDY1LDY2LDY3LDY4LDY5LDcwLDcxLDcyLDczLDc0LDciICsKLSI1LDc2LDc3LDc4LDc5LDgwLDgxLDgyLDgzLDg0LDg1LDg2LDg3LDg4LDg5LDkwLDkxLDkyLDkzLDk0LDk1LDk2LDk3LDk4LDk5LDEiICsKLSIwMCwxMDEsMTAyLDEwMywxMDQsMTA1LDEwNiwxMDcsMTA4LDEwOSwxMTAsMTExLDExMiwxMTMsMTE0LDExNSwxMTYsMTE3LDExOCwiICsKLSIxMTksMTIwLDEyMSwxMjIsMTIzLDEyNCwxMjUsMTI2LDEyNywxMjgsMTI5LDEzMCwxMzEsMTMyLDEwLDEzMywxMzQsMTM1LDEzNiwiICsKLSIxMzcsMTM4LDEzOSwxNDAsMTQxLDE0MiwxNDMsMTQ0LDE0NSwxNDYsMTQ3LDE0OCwxNDksMTUwLDE1MSwxNTIsMTUzLDE1NCwxNTUiICsKLSIsMTU2LDE1NywxNTgsMTU5LDE2MCwxNjEsMTYyLDE2MywxNjQsMTY1LDE2NiwxNjcsMTY4LDE2OSwxNzAsMTcxLDE3MiwxNzMsMTciICsKLSI0LDE3NSwxNzYsMTc3LDE3OCwxNzksMTgwLDE4MSIpWzBdOwotCi0gICAgICAgIHN0YXRpYyBwcml2YXRlIGludCB5eV9ueHRbXVtdID0gdW5wYWNrRnJvbVN0cmluZygxODIsNjEsCi0iMSwyLDMsNCw1LDYsNjUsMTg0LDIwNCw3MCw3LDgsOSwxMCwxMSwxMiwxMyw2NiwxNCwxNSwyMTEsMTg0OjIsMjE1LDE4NCwxNiwxIiArCi0iNywxOCwyMTgsMjIwLDIyMSwxODQsMjIyLDE4NDoyLDIyMywxODQ6MywyMjQsMTg0LDE5LDIwLDE4NDoxMCw3MSw3NCw3NywyMSwxIiArCi0iODQ6Miw2Nyw3NCwtMTo2MywyMiwtMTo2MiwxODQ6Miw3MywxODQ6Myw2NCwtMToyLDc2LC0xOjYsMTg0LDc5LDE4NDozLC0xOjMsIiArCi0iMTg0OjEzLC0xOjIsMTg0OjEwLC0xOjMsNzYsMTg0LDc2OjMsLTE6MTAsMjUsLTE6NTEsMjYsLTE6NzIsMjcsLTE6NDIsMjgsLTE6IiArCi0iMiwyOCwtMToxNywzMCwtMToyNiw2OSwtMToyLDcyLC0xOjMwLDMxLC0xOjU3LDM0LC0xOjQyLDIxLC0xOjIsMjEsLTE6NSwxODQ6IiArCi0iNiw2NCwtMToyLDc2LC0xOjYsMTg0OjUsLTE6MywxODQ6MTMsLTE6MiwxODQ6MTAsLTE6Myw3NiwxODQsNzY6MywtMTo1NiwyOCwtIiArCi0iMToyLDI4LC0xOjU3LDM0LC0xOjIsMzQsLTE6NSwxNTUsMTg0OjUsNjQsLTE6Miw3NiwtMTo2LDE4NDo1LC0xOjMsMTg0OjEzLC0xIiArCi0iOjIsMTg0OjEwLC0xOjMsNzYsMTg0LDc2OjMsLTE6NCwyMDksMTg0OjUsNjQsLTE6Miw3NiwtMTo2LDE4NDo1LC0xOjMsMTg0OjEzIiArCi0iLC0xOjIsMTg0OjEwLC0xOjMsNzYsMTg0LDc2OjMsLTE6NCwyMzMsMTg0OjUsNjQsLTE6Miw3NiwtMTo2LDE4NDo1LC0xOjMsMTg0IiArCi0iOjEzLC0xOjIsMTg0OjEwLC0xOjMsNzYsMTg0LDc2OjMsLTE6NCwxNTgsMTg0OjUsNjQsLTE6Miw3NiwtMTo2LDE4NDo1LC0xOjMsIiArCi0iMTg0OjEzLC0xOjIsMTg0OjEwLC0xOjMsNzYsMTg0LDc2OjMsLTE6NCwxODQ6Niw2NCwtMToyLDc2LC0xOjYsMTg0OjUsMTIyLC0xIiArCi0iLDEyNCwxODMsMTg0OjEyLC0xOjIsMTg0OjEwLC0xOjMsNzYsMTg0LDc2OjMsLTEsMzYsLTE6MywxMDM6NSwtMToyLDgwLC0xOjcsIiArCi0iMTAzOjUsLTE6MywxMDM6MTMsLTE6MiwxMDM6MTAsLTE6NCwxMDM6MywtMTo1LDE4NCwyMywxODQ6NCw2NCwtMToyLDc2LC0xOjYsIiArCi0iMTg0OjUsLTE6MywxODQ6MTMsLTE6MiwxODQ6MTAsLTE6Myw3NiwxODQsNzY6MywtMToxNiwyOSwtMTo0OCwxODQ6Niw2NCwtMToyIiArCi0iLDY4LC0xOjYsMTg0OjUsLTE6MywxODQ6MTMsLTE6MiwxODQ6MTAsLTE6Myw2NywxODQsNzYsNjcsNzYsLTE6NCwxODQ6Niw2NCwtIiArCi0iMToyLDc2LC0xOjYsMTg0OjUsLTE6MywxODQ6MTMsLTE6MiwxODQ6MTAsLTE6Myw2OCwxODQsNzYsNjgsNzYsLTE6NDQsODIsLTE6IiArCi0iMjAsMTg0OjYsNjQsLTE6Miw3NiwtMTo2LDE4NDo1LC0xOjMsMTg0OjMsMjQsMTg0OjksLTE6MiwxODQ6MTAsLTE6Myw3NiwxODQsIiArCi0iNzY6MywtMSw3NTo1MiwzMiw3NTo3LC0xOjQ5LDg0LC0xOjE1LDE4NDozLDM1LDE4NDoyLDY0LC0xOjIsNzYsLTE6NiwxODQ6NSwtIiArCi0iMTozLDE4NDoxMywtMToyLDE4NDoxMCwtMTozLDc2LDE4NCw3NjozLC0xLDc4OjU0LDMzLDc4OjUsLTE6NCwxODQ6Niw2NCwtMToyIiArCi0iLDc2LC0xOjYsMTg0OjUsLTE6MywxODQ6NCwxMDUsMTg0OjgsLTE6MiwxODQ6MTAsLTE6Myw3NiwxODQsNzY6MywtMTo0LDE4NCwzIiArCi0iNywxODQ6NCw2NCwtMToyLDc2LC0xOjYsMTg0OjUsLTE6MywxODQ6MTMsLTE6MiwxODQ6MTAsLTE6Myw3NiwxODQsNzY6MywtMTo0IiArCi0iNSwxODUsLTE6MTksMTg0OjYsNjQsLTE6Miw3NiwtMTo2LDE4NDoyLDM4LDE4NDoyLC0xOjMsMTg0OjEzLC0xOjIsMTg0OjEwLC0xIiArCi0iOjMsNzYsMTg0LDc2OjMsLTE6NDMsODYsLTE6MjEsMTg0OjYsNjQsLTE6Miw3NiwtMTo2LDE4NDo0LDE5MSwtMTozLDE4NDoxMywtIiArCi0iMToyLDE4NDoxMCwtMTozLDc2LDE4NCw3NjozLC0xOjQ3LDE4NiwtMToxNywxODQsMTA3LDE4NDo0LDY0LC0xOjIsNzYsLTE6NiwxIiArCi0iODQ6NSwtMTozLDE4NDoxMywtMToyLDE4NDoxMCwtMTozLDc2LDE4NCw3NjozLC0xOjQ2LDk2LC0xOjE4LDE4NDo0LDE5MywxODQsIiArCi0iNjQsLTE6Miw3NiwtMTo2LDE4NDo1LC0xOjMsMTg0OjEzLC0xOjIsMTg0OjEwLC0xOjMsNzYsMTg0LDc2OjMsLTE6MjYsNDIsLTE6IiArCi0iMzgsMTg0OjIsMjA1LDE4NDozLDY0LC0xOjIsNzYsLTE6NiwxODQ6NSwtMTozLDE4NDoxMywtMToyLDE4NDoxMCwtMTozLDc2LDE4IiArCi0iNCw3NjozLC0xOjI1LDEwMCwtMSw5MiwtMTozNywxODQ6NSwxOTIsNjQsLTE6Miw3NiwtMTo2LDE4NCwyMjgsMTg0OjMsLTE6MywxIiArCi0iODQ6MTMsLTE6MiwxODQ6MTAsLTE6Myw3NiwxODQsNzY6MywtMToyNiw0MywtMTozOCwxODQ6Niw2NCwtMToyLDc2LC0xOjYsMTg0IiArCi0iOjUsLTE6MywxODQ6MywyMDYsMTg0OjksLTE6MiwxODQ6MTAsLTE6Myw3NiwxODQsNzY6MywtMTo0NywxMDQsLTE6MTcsMTg0OjYsIiArCi0iNjQsLTE6Miw3NiwtMTo2LDE4NDo1LC0xOjMsMTg0OjksMTExLDE4NDozLC0xOjIsMTg0OjEwLC0xOjMsNzYsMTg0LDc2OjMsLTE6IiArCi0iNTAsMTkwLC0xOjE0LDE4NDo2LDY0LC0xOjIsNzYsLTE6NiwxODQ6MywxMTMsMTg0LC0xOjMsMTg0OjEzLC0xOjIsMTg0OjEwLC0xIiArCi0iOjMsNzYsMTg0LDc2OjMsLTE6MjYsNDUsLTE6MzgsMTg0LDM5LDE4NDo0LDY0LC0xOjIsNzYsLTE6NiwxODQ6NSwtMTozLDE4NCwyIiArCi0iMTIsMTg0OjExLC0xOjIsMTg0OjEwLC0xOjMsNzYsMTg0LDc2OjMsLTE6MjYsNDYsLTE6MzgsMTAzOjYsLTE6MywxMDMsLTE6NiwxIiArCi0iMDM6NSwtMTozLDEwMzoxMywtMToyLDEwMzoxMCwtMTozLDEwMzo1LC0xOjQ4LDEwNiwtMToxNiwxODQ6Niw2NCwtMToyLDc2LC0xIiArCi0iOjYsMTg0OjUsLTE6MywxODQsMjE2LDE4NDoxMSwtMToyLDE4NDoxMCwtMTozLDc2LDE4NCw3NjozLC0xOjE5LDQ4LC0xOjQ1LDE4IiArCi0iNDo2LDY0LC0xOjIsNzYsLTE6NiwxODQsMTE5LDE4NDozLC0xOjMsMTg0OjEzLC0xOjIsMTg0OjEwLC0xOjMsNzYsMTg0LDc2OjMsIiArCi0iLTE6NTEsMTE0LC0xOjEzLDE4NDo0LDEyMywxODQsNjQsLTE6Miw3NiwtMTo2LDE4NDo1LC0xOjMsMTg0OjEzLC0xOjIsMTg0OjEwIiArCi0iLC0xOjMsNzYsMTg0LDc2OjMsLTE6MjYsNTAsLTE6MzgsMTg0OjYsNjQsLTE6Miw3NiwtMTo2LDE4NDo1LC0xOjMsMTg0OjExLDQwIiArCi0iLDE4NCwtMToyLDE4NDoxMCwtMTozLDc2LDE4NCw3NjozLC0xOjI1LDExNiwtMSwxMTIsLTE6MzcsMTg0OjYsNjQsLTE6Miw3NiwtIiArCi0iMTo2LDE4NDo1LC0xOjMsMTg0OjMsMTI4LDE4NDo5LC0xOjIsMTg0OjEwLC0xOjMsNzYsMTg0LDc2OjMsLTE6NTIsMTE4LC0xOjEyIiArCi0iLDE4NDo2LDY0LC0xOjIsNzYsLTE6NiwxODQ6NSwtMTozLDE4NDo5LDEyOSwxODQ6MywtMToyLDE4NDoxMCwtMTozLDc2LDE4NCw3IiArCi0iNjozLC0xOjI2LDU1LC0xOjM4LDE4NDo2LDY0LC0xOjIsNzYsLTE6NiwxODQ6MywxMzAsMTg0LDkwLC0xLDkyLDE4NDoxMywtMToyIiArCi0iLDE4NDoxMCwtMTozLDc2LDE4NCw3NjozLC0xOjQ4LDEyMCwtMToxNiwxODQ6Niw2NCwtMToyLDc2LC0xOjYsMTg0LDEzMSwxODQ6IiArCi0iMyw5NCwtMSwxODgsMTg0OjEzLC0xOjIsMTg0OjEwLC0xOjMsNzYsMTg0LDc2OjMsLTE6MTksNTYsLTE6NDUsMTg0OjYsNjQsLTE6IiArCi0iMiw3NiwtMTo2LDE4NDo1LC0xOjMsMTg0OjQsMTMyLDE4NDo4LC0xOjIsMTg0OjEwLC0xOjMsNzYsMTg0LDc2OjMsLTE6MjYsNjIsIiArCi0iLTE6MzgsMTg0OjYsNjQsLTE6Miw3NiwtMTo2LDE4NCwyMDgsMTg0OjMsLTE6MywxODQ6MTMsLTE6MiwxODQ6MTAsLTE6Myw3NiwxIiArCi0iODQsNzY6MywtMToyNSwxMjYsLTEsMTI0LC0xOjM3LDE4NCw0MSwxODQ6NCw2NCwtMToyLDc2LC0xOjYsMTg0OjUsLTE6MywxODQ6IiArCi0iMTMsLTE6MiwxODQ6MTAsLTE6Myw3NiwxODQsNzY6MywtMToyNiw2MywtMTozOCwxODQ6Niw2NCwtMToyLDc2LC0xOjYsMTg0OjUsIiArCi0iLTE6MywxMzUsMTg0OjEyLC0xOjIsMTg0OjEwLC0xOjMsNzYsMTg0LDc2OjMsLTE6NCwxODQ6MiwxMzYsMTg0OjMsNjQsLTE6Miw3IiArCi0iNiwtMTo2LDE4NDo1LC0xOjMsMTg0OjEzLC0xOjIsMTg0OjEwLC0xOjMsNzYsMTg0LDc2OjMsLTE6NCwxODQ6NSwxMzgsNjQsLTE6IiArCi0iMiw3NiwtMTo2LDE4NDo1LC0xOjMsMTg0OjEzLC0xOjIsMTg0OjEwLC0xOjMsNzYsMTg0LDc2OjMsLTE6NCwxODQ6Niw2NCwtMToyIiArCi0iLDc2LC0xOjYsMTg0OjMsMTMwLDE4NCwtMToyLDkyLDE4NDoxMywtMToyLDE4NDoxMCwtMTozLDc2LDE4NCw3NjozLC0xOjQsMTg0IiArCi0iOjYsNjQsLTE6Miw3NiwtMTo2LDE4NCwxMzEsMTg0OjMsLTE6MiwxODgsMTg0OjEzLC0xOjIsMTg0OjEwLC0xOjMsNzYsMTg0LDc2IiArCi0iOjMsLTE6NCwxODQ6Niw2NCwtMToyLDc2LC0xOjYsMTg0OjUsLTE6MywxODQ6MiwxMzksMTg0OjEwLC0xOjIsMTg0OjEwLC0xOjMsIiArCi0iNzYsMTg0LDc2OjMsLTE6NCwxODQ6Niw2NCwtMToyLDc2LC0xOjYsMTg0OjUsLTE6MywxODQ6NCwxOTcsMTg0OjgsLTE6MiwxODQ6IiArCi0iMTAsLTE6Myw3NiwxODQsNzY6MywtMTo0LDE4NCwxNDAsMTg0OjQsNjQsLTE6Miw3NiwtMTo2LDE4NDo1LC0xOjMsMTg0OjEzLC0xIiArCi0iOjIsMTg0OjEwLC0xOjMsNzYsMTg0LDc2OjMsLTE6NCwxODQ6Niw2NCwtMToyLDc2LC0xOjYsMTg0OjMsNDQsMTg0LC0xOjMsMTg0IiArCi0iOjEzLC0xOjIsMTg0OjEwLC0xOjMsNzYsMTg0LDc2OjMsLTE6NCwxODQ6Niw2NCwtMToyLDc2LC0xOjYsMTg0OjUsLTE6MywxODQ6IiArCi0iMTAsMTQxLDE4NDoyLC0xOjIsMTg0OjEwLC0xOjMsNzYsMTg0LDc2OjMsLTE6NCwxODQ6Niw2NCwtMToyLDc2LC0xOjYsMTg0OjMsIiArCi0iMTQyLDE4NCwtMTozLDE4NDoxMywtMToyLDE4NDoxMCwtMTozLDc2LDE4NCw3NjozLC0xOjQsMTg0OjYsNjQsLTE6Miw3NiwtMTo2IiArCi0iLDE4NDo1LC0xOjMsMTg0OjEyLDIyNSwtMToyLDE4NDoxMCwtMTozLDc2LDE4NCw3NjozLC0xOjQsMTg0OjYsNjQsLTE6Miw3NiwtIiArCi0iMTo2LDE4NDo1LC0xOjMsMTg0OjcsMTQzLDE4NDo1LC0xOjIsMTg0OjEwLC0xOjMsNzYsMTg0LDc2OjMsLTE6NCwxODQ6MiwxNDUsIiArCi0iMTg0OjMsNjQsLTE6Miw3NiwtMTo2LDE4NDo1LC0xOjMsMTg0OjEzLC0xOjIsMTg0OjEwLC0xOjMsNzYsMTg0LDc2OjMsLTE6NCwxIiArCi0iODQ6Niw2NCwtMToyLDc2LC0xOjYsMTg0OjUsLTE6MywxODQ6NiwxNDYsMTg0OjYsLTE6MiwxODQ6MTAsLTE6Myw3NiwxODQsNzY6IiArCi0iMywtMTo0LDE4NDo1LDE0Nyw2NCwtMToyLDc2LC0xOjYsMTg0OjUsLTE6MywxODQ6MTMsLTE6MiwxODQ6MTAsLTE6Myw3NiwxODQsIiArCi0iNzY6MywtMTo0LDE4NDo2LDY0LC0xOjIsNzYsLTE6NiwxODQ6NSwtMTozLDE4NCwxNDgsMTg0OjExLC0xOjIsMTg0OjEwLC0xOjMsIiArCi0iNzYsMTg0LDc2OjMsLTE6NCwxODQ6Niw2NCwtMToyLDc2LC0xOjYsMTg0OjMsMTQ5LDE4NCwxMTAsLTEsMTEyLDE4NDoxMywtMToyIiArCi0iLDE4NDoxMCwtMTozLDc2LDE4NCw3NjozLC0xOjQsMTg0OjYsNjQsLTE6Miw3NiwtMTo2LDE4NDo1LC0xOjMsMTUwLDE4NDoxMiwtIiArCi0iMToyLDE4NDoxMCwtMTozLDc2LDE4NCw3NjozLC0xOjQsMTg0OjYsNjQsLTE6Miw3NiwtMTo2LDE4NDozLDE1MSwxODQsLTE6MywxIiArCi0iODQ6MTMsLTE6MiwxODQ6MTAsLTE6Myw3NiwxODQsNzY6MywtMTo0LDE4NDo2LDY0LC0xOjIsNzYsLTE6NiwxODQ6NSwtMTozLDE4IiArCi0iNDozLDQ3LDE4NDo5LC0xOjIsMTg0OjEwLC0xOjMsNzYsMTg0LDc2OjMsLTE6NCwxODQ6Niw2NCwtMToyLDc2LC0xOjYsMTg0LDQ5IiArCi0iLDE4NDozLC0xOjMsMTg0OjEzLC0xOjIsMTg0OjEwLC0xOjMsNzYsMTg0LDc2OjMsLTE6NCwxODQ6Niw2NCwtMToyLDc2LC0xOjYsIiArCi0iMTg0OjMsMTQ5LDE4NCwtMToyLDExMiwxODQ6MTMsLTE6MiwxODQ6MTAsLTE6Myw3NiwxODQsNzY6MywtMTo0LDE4NDo2LDY0LC0xIiArCi0iOjIsNzYsLTE6NiwxODQ6NSwtMTozLDE4NDo1LDUxLDE4NDo3LC0xOjIsMTg0OjEwLC0xOjMsNzYsMTg0LDc2OjMsLTE6NCwxODQ6IiArCi0iNiw2NCwtMToyLDc2LC0xOjYsMTg0LDUyLDE4NDozLC0xOjMsMTg0OjEzLC0xOjIsMTg0OjEwLC0xOjMsNzYsMTg0LDc2OjMsLTE6IiArCi0iNCwxODQ6Niw2NCwtMToyLDc2LC0xOjYsMTg0OjUsLTE6MywxODQ6NSw1MywxODQ6NywtMToyLDE4NDoxMCwtMTozLDc2LDE4NCw3IiArCi0iNjozLC0xOjQsMTg0OjYsNjQsLTE6Miw3NiwtMTo2LDE4NDozLDU0LDE4NCwtMTozLDE4NDoxMywtMToyLDE4NDoxMCwtMTozLDc2IiArCi0iLDE4NCw3NjozLC0xOjQsMTg0OjYsNjQsLTE6Miw3NiwtMTo2LDE4NDo1LC0xOjMsMTg0OjUsMTU2LDE4NDo3LC0xOjIsMTg0OjEwIiArCi0iLC0xOjMsNzYsMTg0LDc2OjMsLTE6NCwxODQ6NSwxNTcsNjQsLTE6Miw3NiwtMTo2LDE4NDo1LC0xOjMsMTg0OjEzLC0xOjIsMTg0IiArCi0iOjEwLC0xOjMsNzYsMTg0LDc2OjMsLTE6NCwxNTksMTg0OjUsNjQsLTE6Miw3NiwtMTo2LDE4NDo1LC0xOjMsMTg0OjEzLC0xOjIsIiArCi0iMTg0OjEwLC0xOjMsNzYsMTg0LDc2OjMsLTE6NCwxODQ6Niw2NCwtMToyLDc2LC0xOjYsMTg0OjUsLTE6MywxODQ6MywxNjAsMTg0IiArCi0iOjksLTE6MiwxODQ6MTAsLTE6Myw3NiwxODQsNzY6MywtMTo0LDE4NDo1LDE2MSw2NCwtMToyLDc2LC0xOjYsMTg0OjUsLTE6MywxIiArCi0iODQ6MTMsLTE6MiwxODQ6MTAsLTE6Myw3NiwxODQsNzY6MywtMTo0LDE4NDoyLDE2MiwxODQ6Myw2NCwtMToyLDc2LC0xOjYsMTg0IiArCi0iOjUsLTE6MywxODQ6MTMsLTE6MiwxODQ6MTAsLTE6Myw3NiwxODQsNzY6MywtMTo0LDIxMywxODQ6NSw2NCwtMToyLDc2LC0xOjYsIiArCi0iMTg0OjUsLTE6MywxODQ6MTMsLTE6MiwxODQ6MTAsLTE6Myw3NiwxODQsNzY6MywtMTo0LDE4NDo2LDY0LC0xOjIsNzYsLTE6NiwxIiArCi0iODQ6NSwtMTozLDE4NDozLDIyNiwxODQ6OSwtMToyLDE4NDoxMCwtMTozLDc2LDE4NCw3NjozLC0xOjQsMTg0OjYsNjQsLTE6Miw3IiArCi0iNiwtMTo2LDE4NDo1LC0xOjMsMjE3LDE4NDoxMiwtMToyLDE4NDoxMCwtMTozLDc2LDE4NCw3NjozLC0xOjQsMTg0OjYsNjQsLTE6IiArCi0iMiw3NiwtMTo2LDE4NDo1LC0xOjMsMTg0OjEwLDE2NCwxODQ6MiwtMToyLDE4NDoxMCwtMTozLDc2LDE4NCw3NjozLC0xOjQsMTg0IiArCi0iOjYsNjQsLTE6Miw3NiwtMTo2LDE4NDo1LC0xOjMsMTg0OjksMTY3LDE4NDozLC0xOjIsMTg0OjEwLC0xOjMsNzYsMTg0LDc2OjMsIiArCi0iLTE6NCwxODQ6Niw2NCwtMToyLDc2LC0xOjYsMTg0LDE2OCwxODQ6MywtMTozLDE4NDoxMywtMToyLDE4NDoxMCwtMTozLDc2LDE4IiArCi0iNCw3NjozLC0xOjQsMTg0OjYsNjQsLTE6Miw3NiwtMTo2LDE4NDozLDE3MCwxODQsLTE6MywxODQ6MTMsLTE6MiwxODQ6MTAsLTE6IiArCi0iMyw3NiwxODQsNzY6MywtMTo0LDE4NDoyLDE3MSwxODQ6Myw2NCwtMToyLDc2LC0xOjYsMTg0OjUsLTE6MywxODQ6MTMsLTE6MiwxIiArCi0iODQ6MTAsLTE6Myw3NiwxODQsNzY6MywtMTo0LDE4NDo2LDY0LC0xOjIsNzYsLTE6NiwxODQ6NSwtMTozLDE4NDo5LDE3MiwxODQ6IiArCi0iMywtMToyLDE4NDoxMCwtMTozLDc2LDE4NCw3NjozLC0xOjQsMTg0OjYsNjQsLTE6Miw3NiwtMTo2LDE4NCwxNzMsMTg0OjMsLTE6IiArCi0iMywxODQ6MTMsLTE6MiwxODQ6MTAsLTE6Myw3NiwxODQsNzY6MywtMTo0LDE4NDo2LDY0LC0xOjIsNzYsLTE6NiwxODQ6NSwtMTozIiArCi0iLDE4NDozLDE3NCwxODQ6OSwtMToyLDE4NDoxMCwtMTozLDc2LDE4NCw3NjozLC0xOjQsMTg0OjYsNjQsLTE6Miw3NiwtMTo2LDE4IiArCi0iNDo1LC0xOjMsMTc1LDE4NDoxMiwtMToyLDE4NDoxMCwtMTozLDc2LDE4NCw3NjozLC0xOjQsMTg0OjYsNjQsLTE6Miw3NiwtMTo2IiArCi0iLDE4NDo1LC0xOjMsMTg0OjExLDU3LDE4NCwtMToyLDE4NDoxMCwtMTozLDc2LDE4NCw3NjozLC0xOjQsMTg0OjYsNjQsLTE6Miw3IiArCi0iNiwtMTo2LDE4NDo1LC0xOjMsMTg0OjksMTc3LDE4NDozLC0xOjIsMTg0OjEwLC0xOjMsNzYsMTg0LDc2OjMsLTE6NCwxODQ6Niw2IiArCi0iNCwtMToyLDc2LC0xOjYsMTg0OjUsLTE6MywxODQ6NiwxNzgsMTg0OjYsLTE6MiwxODQ6MTAsLTE6Myw3NiwxODQsNzY6MywtMTo0IiArCi0iLDE4NDo2LDY0LC0xOjIsNzYsLTE6NiwxODQ6NSwtMTozLDE4NDo1LDU4LDE4NDo3LC0xOjIsMTg0OjEwLC0xOjMsNzYsMTg0LDc2IiArCi0iOjMsLTE6NCwxODQ6Niw2NCwtMToyLDc2LC0xOjYsMTg0OjUsLTE6MywxODQ6NSw1OSwxODQ6NywtMToyLDE4NDoxMCwtMTozLDc2IiArCi0iLDE4NCw3NjozLC0xOjQsMTg0OjYsNjQsLTE6Miw3NiwtMTo2LDE4NDo1LC0xOjMsMTg0OjExLDYwLDE4NCwtMToyLDE4NDoxMCwtIiArCi0iMTozLDc2LDE4NCw3NjozLC0xOjQsMTg0OjYsNjQsLTE6Miw3NiwtMTo2LDE4NDo1LC0xOjMsMTg0LDE3OSwxODQ6MTEsLTE6MiwxIiArCi0iODQ6MTAsLTE6Myw3NiwxODQsNzY6MywtMTo0LDE4NDo2LDY0LC0xOjIsNzYsLTE6NiwxODQ6MywxODAsMTg0LC0xOjMsMTg0OjEzIiArCi0iLC0xOjIsMTg0OjEwLC0xOjMsNzYsMTg0LDc2OjMsLTE6NCwxODQ6MiwxODEsMTg0OjMsNjQsLTE6Miw3NiwtMTo2LDE4NDo1LC0xIiArCi0iOjMsMTg0OjEzLC0xOjIsMTg0OjEwLC0xOjMsNzYsMTg0LDc2OjMsLTE6NCwxODQ6NSwxODIsNjQsLTE6Miw3NiwtMTo2LDE4NDo1IiArCi0iLC0xOjMsMTg0OjEzLC0xOjIsMTg0OjEwLC0xOjMsNzYsMTg0LDc2OjMsLTE6NCwxODQ6Niw2NCwtMToyLDc2LC0xOjYsMTg0OjUsIiArCi0iLTE6Myw2MSwxODQ6MTIsLTE6MiwxODQ6MTAsLTE6Myw3NiwxODQsNzY6MywtMTo0LDE4NDo2LDY0LC0xOjIsNzYsLTE6NiwxODQ6IiArCi0iNSwtMToyLDEyNCwxODMsMTg0OjEyLC0xOjIsMTg0OjEwLC0xOjMsNzYsMTg0LDc2OjMsLTE6NDUsODgsLTE6NjEsOTgsLTE6MTgsIiArCi0iMTg0OjQsMTA5LDE4NCw2NCwtMToyLDc2LC0xOjYsMTg0OjUsLTE6MywxODQ6MTMsLTE6MiwxODQ6MTAsLTE6Myw3NiwxODQsNzY6IiArCi0iMywtMToyNSwxMDIsLTEsMTg4LC0xOjM3LDE4NDo2LDY0LC0xOjIsNzYsLTE6NiwxODQ6NSwtMTozLDE4NDo5LDExNSwxODQ6MywtIiArCi0iMToyLDE4NDoxMCwtMTozLDc2LDE4NCw3NjozLC0xOjUwLDEwOCwtMToxNCwxODQ6Niw2NCwtMToyLDc2LC0xOjYsMTg0OjMsMTE3IiArCi0iLDE4NCwtMTozLDE4NDoxMywtMToyLDE4NDoxMCwtMTozLDc2LDE4NCw3NjozLC0xOjQsMTg0OjYsNjQsLTE6Miw3NiwtMTo2LDE4IiArCi0iNDo1LC0xOjMsMTg0LDE5NSwxODQ6MTEsLTE6MiwxODQ6MTAsLTE6Myw3NiwxODQsNzY6MywtMTo0LDE4NDo2LDY0LC0xOjIsNzYsIiArCi0iLTE6NiwxODQsMTIxLDE4NDozLC0xOjMsMTg0OjEzLC0xOjIsMTg0OjEwLC0xOjMsNzYsMTg0LDc2OjMsLTE6NCwxODQ6Niw2NCwtIiArCi0iMToyLDc2LC0xOjYsMTg0OjUsLTE6MywxODQ6NCwxMzcsMTg0OjgsLTE6MiwxODQ6MTAsLTE6Myw3NiwxODQsNzY6MywtMTo0LDE4IiArCi0iNDo2LDY0LC0xOjIsNzYsLTE6NiwxODQsMTMzLDE4NDozLC0xOjMsMTg0OjEzLC0xOjIsMTg0OjEwLC0xOjMsNzYsMTg0LDc2OjMsIiArCi0iLTE6NCwxODQ6Niw2NCwtMToyLDc2LC0xOjYsMTg0OjUsLTE6MywxOTgsMTg0OjEyLC0xOjIsMTg0OjEwLC0xOjMsNzYsMTg0LDc2IiArCi0iOjMsLTE6NCwxODQ6Niw2NCwtMToyLDc2LC0xOjYsMTg0OjUsLTE6MywxODQ6NCwyMjksMTg0OjgsLTE6MiwxODQ6MTAsLTE6Myw3IiArCi0iNiwxODQsNzY6MywtMTo0LDE4NCwyMDAsMTg0OjQsNjQsLTE6Miw3NiwtMTo2LDE4NDo1LC0xOjMsMTg0OjEzLC0xOjIsMTg0OjEwIiArCi0iLC0xOjMsNzYsMTg0LDc2OjMsLTE6NCwxODQ6Niw2NCwtMToyLDc2LC0xOjYsMTg0OjMsMTQ0LDE4NCwtMTozLDE4NDoxMywtMToyIiArCi0iLDE4NDoxMCwtMTozLDc2LDE4NCw3NjozLC0xOjQsMTg0OjYsNjQsLTE6Miw3NiwtMTo2LDE4NDo1LC0xOjMsMTg0OjcsMjEwLDE4IiArCi0iNDo1LC0xOjIsMTg0OjEwLC0xOjMsNzYsMTg0LDc2OjMsLTE6NCwxODQ6Niw2NCwtMToyLDc2LC0xOjYsMTg0OjUsLTE6MywxNTIsIiArCi0iMTg0OjEyLC0xOjIsMTg0OjEwLC0xOjMsNzYsMTg0LDc2OjMsLTE6NCwxODQ6MiwxNjMsMTg0OjMsNjQsLTE6Miw3NiwtMTo2LDE4IiArCi0iNDo1LC0xOjMsMTg0OjEzLC0xOjIsMTg0OjEwLC0xOjMsNzYsMTg0LDc2OjMsLTE6NCwxODQ6Niw2NCwtMToyLDc2LC0xOjYsMTg0IiArCi0iOjUsLTE6MywxNzYsMTg0OjEyLC0xOjIsMTg0OjEwLC0xOjMsNzYsMTg0LDc2OjMsLTE6NCwxODQ6NSw4MSw2NCwtMToyLDc2LC0xIiArCi0iOjYsMTg0OjUsLTE6MywxODQ6MTMsLTE6MiwxODQ6MTAsLTE6Myw3NiwxODQsNzY6MywtMTo0LDE4NDo2LDY0LC0xOjIsNzYsLTE6IiArCi0iNiwxODQ6NSwtMTozLDE4NDo5LDEyNSwxODQ6MywtMToyLDE4NDoxMCwtMTozLDc2LDE4NCw3NjozLC0xOjQsMTg0OjYsNjQsLTE6IiArCi0iMiw3NiwtMTo2LDE4NCwxMjcsMTg0OjMsLTE6MywxODQ6MTMsLTE6MiwxODQ6MTAsLTE6Myw3NiwxODQsNzY6MywtMTo0LDE4NDo2IiArCi0iLDY0LC0xOjIsNzYsLTE6NiwxODQsMTM0LDE4NDozLC0xOjMsMTg0OjEzLC0xOjIsMTg0OjEwLC0xOjMsNzYsMTg0LDc2OjMsLTE6IiArCi0iNCwxODQ6Niw2NCwtMToyLDc2LC0xOjYsMTg0OjUsLTE6MywxOTksMTg0OjEyLC0xOjIsMTg0OjEwLC0xOjMsNzYsMTg0LDc2OjMsIiArCi0iLTE6NCwxODQ6Niw2NCwtMToyLDc2LC0xOjYsMTg0OjUsLTE6MywxODQ6NCwyMDIsMTg0OjgsLTE6MiwxODQ6MTAsLTE6Myw3NiwxIiArCi0iODQsNzY6MywtMTo0LDE4NDo2LDY0LC0xOjIsNzYsLTE6NiwxODQ6NSwtMTozLDE1MywxODQ6MTIsLTE6MiwxODQ6MTAsLTE6Myw3IiArCi0iNiwxODQsNzY6MywtMTo0LDE4NDo2LDY0LC0xOjIsNzYsLTE6NiwxODQsODMsMTg0OjMsLTE6MywxODQ6MTMsLTE6MiwxODQ6MTAsIiArCi0iLTE6Myw3NiwxODQsNzY6MywtMTo0LDE4NDo2LDY0LC0xOjIsNzYsLTE6NiwxODQsMTk0LDE4NDozLC0xOjMsMTg0OjEzLC0xOjIsIiArCi0iMTg0OjEwLC0xOjMsNzYsMTg0LDc2OjMsLTE6NCwxODQ6Niw2NCwtMToyLDc2LC0xOjYsMTg0OjUsLTE6MywxODQ6NCwxNjUsMTg0IiArCi0iOjgsLTE6MiwxODQ6MTAsLTE6Myw3NiwxODQsNzY6MywtMTo0LDE4NDo2LDY0LC0xOjIsNzYsLTE6NiwxODQ6NSwtMTozLDE1NCwxIiArCi0iODQ6MTIsLTE6MiwxODQ6MTAsLTE6Myw3NiwxODQsNzY6MywtMTo0LDE4NDo2LDY0LC0xOjIsNzYsLTE6NiwxODQsODUsMTg0OjMsIiArCi0iLTE6MywxODQ6MTMsLTE6MiwxODQ6MTAsLTE6Myw3NiwxODQsNzY6MywtMTo0LDE4NDo2LDY0LC0xOjIsNzYsLTE6NiwxODQsMTk2IiArCi0iLDE4NDozLC0xOjMsMTg0OjEzLC0xOjIsMTg0OjEwLC0xOjMsNzYsMTg0LDc2OjMsLTE6NCwxODQ6Niw2NCwtMToyLDc2LC0xOjYsIiArCi0iMTg0OjUsLTE6MywxODQ6NCwxNjYsMTg0OjgsLTE6MiwxODQ6MTAsLTE6Myw3NiwxODQsNzY6MywtMTo0LDE4NDo1LDg3LDY0LC0xIiArCi0iOjIsNzYsLTE6NiwxODQ6NSwtMTozLDE4NDo3LDg5LDE4NDo1LC0xOjIsMTg0OjEwLC0xOjMsNzYsMTg0LDc2OjMsLTE6NCwxODQ6IiArCi0iNiw2NCwtMToyLDc2LC0xOjYsMTg0OjUsLTE6MywxODQ6NCwxNjksMTg0OjgsLTE6MiwxODQ6MTAsLTE6Myw3NiwxODQsNzY6MywtIiArCi0iMTo0LDE4NDo1LDE4Nyw2NCwtMToyLDc2LC0xOjYsMTg0OjUsLTE6MywxODQ6OCw5MSwxODQ6NCwtMToyLDE4NDoxMCwtMTozLDc2IiArCi0iLDE4NCw3NjozLC0xOjQsMTg0OjYsNjQsLTE6Miw3NiwtMTo2LDE4NDo1LC0xOjMsMTg0OjMsOTMsMTg0OjMsOTUsMTg0OjUsLTE6IiArCi0iMiwxODQ6MTAsLTE6Myw3NiwxODQsNzY6MywtMTo0LDE4NDo2LDY0LC0xOjIsNzYsLTE6NiwxODQsOTcsMTg0OjMsLTE6MywxODQ6IiArCi0iMTMsLTE6MiwxODQ6MTAsLTE6Myw3NiwxODQsNzY6MywtMTo0LDE4NDo2LDY0LC0xOjIsNzYsLTE6NiwxODQ6Myw5OSwxODQsLTE6IiArCi0iMywxMDEsMTg0OjEyLC0xOjIsMTg0OjEwLC0xOjMsNzYsMTg0LDc2OjMsLTE6NCwxODQ6NSwxODksNjQsLTE6Miw3NiwtMTo2LDE4IiArCi0iNDo1LC0xOjMsMTg0OjEzLC0xOjIsMTg0OjEwLC0xOjMsNzYsMTg0LDc2OjMsLTE6NCwxODQ6MiwyMDEsMTg0OjMsNjQsLTE6Miw3IiArCi0iNiwtMTo2LDE4NDo1LC0xOjMsMTg0OjEzLC0xOjIsMTg0OjEwLC0xOjMsNzYsMTg0LDc2OjMsLTE6NCwyMTksMTg0OjUsNjQsLTE6IiArCi0iMiw3NiwtMTo2LDE4NDo1LC0xOjMsMTg0OjEzLC0xOjIsMTg0OjEwLC0xOjMsNzYsMTg0LDc2OjMsLTE6NCwxODQ6MiwyMDMsMTg0IiArCi0iOjMsNjQsLTE6Miw3NiwtMTo2LDE4NDo1LC0xOjMsMTg0OjEzLC0xOjIsMTg0OjEwLC0xOjMsNzYsMTg0LDc2OjMsLTE6NCwxODQ6IiArCi0iNiw2NCwtMToyLDc2LC0xOjYsMTg0OjUsLTE6MywxODQsMjA3LDE4NDoxMSwtMToyLDE4NDoxMCwtMTozLDc2LDE4NCw3NjozLC0xIiArCi0iOjQsMTg0OjIsMjE0LDE4NDozLDY0LC0xOjIsNzYsLTE6NiwxODQ6NSwtMTozLDE4NDoxMywtMToyLDE4NDoxMCwtMTozLDc2LDE4IiArCi0iNCw3NjozLC0xOjQsMTg0OjYsNjQsLTE6Miw3NiwtMTo2LDE4NDo1LC0xOjMsMTg0OjksMjI3LDE4NDozLC0xOjIsMTg0OjEwLC0xIiArCi0iOjMsNzYsMTg0LDc2OjMsLTE6NCwxODQ6Niw2NCwtMToyLDc2LC0xOjYsMTg0OjUsLTE6MywxODQ6MTAsMjMwLDE4NDoyLC0xOjIsIiArCi0iMTg0OjEwLC0xOjMsNzYsMTg0LDc2OjMsLTE6NCwxODQ6MiwyMzEsMTg0OjMsNjQsLTE6Miw3NiwtMTo2LDE4NDo1LC0xOjMsMTg0IiArCi0iOjEzLC0xOjIsMTg0OjEwLC0xOjMsNzYsMTg0LDc2OjMsLTE6NCwxODQ6Niw2NCwtMToyLDc2LC0xOjYsMTg0OjUsLTE6MywxODQ6IiArCi0iNCwyMzIsMTg0OjgsLTE6MiwxODQ6MTAsLTE6Myw3NiwxODQsNzY6MyIpOwotCi0gICAgICAgIHB1YmxpYyBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sIG5leHRfdG9rZW4gKCkKLSAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiwKLUV4Y2VwdGlvbgotCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIGludCB5eV9sb29rYWhlYWQ7Ci0gICAgICAgICAgICAgICAgaW50IHl5X2FuY2hvciA9IFlZX05PX0FOQ0hPUjsKLSAgICAgICAgICAgICAgICBpbnQgeXlfc3RhdGUgPSB5eV9zdGF0ZV9kdHJhbnNbeXlfbGV4aWNhbF9zdGF0ZV07Ci0gICAgICAgICAgICAgICAgaW50IHl5X25leHRfc3RhdGUgPSBZWV9OT19TVEFURTsKLSAgICAgICAgICAgICAgICBpbnQgeXlfbGFzdF9hY2NlcHRfc3RhdGUgPSBZWV9OT19TVEFURTsKLSAgICAgICAgICAgICAgICBib29sZWFuIHl5X2luaXRpYWwgPSB0cnVlOwotICAgICAgICAgICAgICAgIGludCB5eV90aGlzX2FjY2VwdDsKLQotICAgICAgICAgICAgICAgIHl5X21hcmtfc3RhcnQoKTsKLSAgICAgICAgICAgICAgICB5eV90aGlzX2FjY2VwdCA9IHl5X2FjcHRbeXlfc3RhdGVdOwotICAgICAgICAgICAgICAgIGlmIChZWV9OT1RfQUNDRVBUICE9IHl5X3RoaXNfYWNjZXB0KSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICB5eV9sYXN0X2FjY2VwdF9zdGF0ZSA9IHl5X3N0YXRlOwotICAgICAgICAgICAgICAgICAgICAgICAgeXlfbWFya19lbmQoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgd2hpbGUgKHRydWUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmICh5eV9pbml0aWFsICYmIHl5X2F0X2JvbCkgeXlfbG9va2FoZWFkID0gWVlfQk9MOwotICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB5eV9sb29rYWhlYWQgPSB5eV9hZHZhbmNlKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB5eV9uZXh0X3N0YXRlID0gWVlfRjsKLSAgICAgICAgICAgICAgICAgICAgICAgIHl5X25leHRfc3RhdGUgPSB5eV9ueHRbeXlfcm1hcFt5eV9zdGF0ZV1dW3l5X2NtYXBbeXlfbG9va2FoZWFkXV07Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoWVlfRU9GID09IHl5X2xvb2thaGVhZCAmJiB0cnVlID09IHl5X2luaXRpYWwpIHsKLQotcmV0dXJuIG5ld1N5bWJvbChzeW0uRU9GKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChZWV9GICE9IHl5X25leHRfc3RhdGUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeXlfc3RhdGUgPSB5eV9uZXh0X3N0YXRlOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5eV9pbml0aWFsID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHl5X3RoaXNfYWNjZXB0ID0geXlfYWNwdFt5eV9zdGF0ZV07Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChZWV9OT1RfQUNDRVBUICE9IHl5X3RoaXNfYWNjZXB0KSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeXlfbGFzdF9hY2NlcHRfc3RhdGUgPSB5eV9zdGF0ZTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5eV9tYXJrX2VuZCgpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKFlZX05PX1NUQVRFID09IHl5X2xhc3RfYWNjZXB0X3N0YXRlKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgKG5ldyBFcnJvcigiTGV4aWNhbCBFcnJvcjogVW5tYXRjaGVkIElucHV0LiIpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5eV9hbmNob3IgPSB5eV9hY3B0W3l5X2xhc3RfYWNjZXB0X3N0YXRlXTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoMCAhPSAoWVlfRU5EICYgeXlfYW5jaG9yKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeXlfbW92ZV9lbmQoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeXlfdG9fbWFyaygpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN3aXRjaCAoeXlfbGFzdF9hY2NlcHRfc3RhdGUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDE6Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC0yOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAyOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5TVEFSKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTM6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDM6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLlNMQVNIKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTQ6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDQ6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLlBMVVMpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtNToKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgNToKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uTUlOVVMpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtNjoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgNjoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uUU5BTUUsIHl5dGV4dCgpKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTc6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDc6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHRocm93IG5ldyBFeGNlcHRpb24oeXl0ZXh0KCkpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtODoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgODoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uQ09NTUEpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtOToKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgOToKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uQVRTSUdOKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTEwOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxMDoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uRE9UKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTExOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxMToKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uVkJBUik7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC0xMjoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTI6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLkRPTExBUik7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC0xMzoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTM6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLkVRKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTE0OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxNDoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uTFQpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtMTU6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDE1OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5HVCk7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC0xNjoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTY6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLkxQQVJFTik7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC0xNzoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTc6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLlJQQVJFTik7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC0xODoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTg6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IC8qIGlnbm9yZSB3aGl0ZSBzcGFjZS4gKi8gfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTE5OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxOToKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uTEJSQUNLKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTIwOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAyMDoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uUkJSQUNLKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTIxOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAyMToKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uSU5ULCBuZXcgTG9uZyh5eXRleHQoKSkpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtMjI6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDIyOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5EU0xBU0gpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtMjM6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDIzOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gZGlzYW1iaWd1YXRlQXhpc09yRnVuY3Rpb24oc3ltLklEKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTI0OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAyNDoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIGRpc2FtYmlndWF0ZU9wZXJhdG9yKHN5bS5PUik7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC0yNToKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMjU6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLkRDT0xPTik7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC0yNjoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMjY6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLlFOQU1FLCB5eXRleHQoKSk7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC0yNzoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMjc6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLkRET1QpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtMjg6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDI4OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5SRUFMLCBuZXcgRG91YmxlKHl5dGV4dCgpKSk7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC0yOToKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMjk6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLk5FKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTMwOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAzMDoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uTEUpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtMzE6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDMxOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5HRSk7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC0zMjoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMzI6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLkxpdGVyYWwsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5eXRleHQoKS5zdWJzdHJpbmcoMSwgeXl0ZXh0KCkubGVuZ3RoKCkgLSAxKSk7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC0zMzoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMzM6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLkxpdGVyYWwsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5eXRleHQoKS5zdWJzdHJpbmcoMSwgeXl0ZXh0KCkubGVuZ3RoKCkgLSAxKSk7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC0zNDoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMzQ6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLlJFQUwsIG5ldyBEb3VibGUoeXl0ZXh0KCkpKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTM1OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAzNToKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIGRpc2FtYmlndWF0ZU9wZXJhdG9yKHN5bS5ESVYpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtMzY6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDM2OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5RTkFNRSwgeXl0ZXh0KCkpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtMzc6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDM3OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gZGlzYW1iaWd1YXRlT3BlcmF0b3Ioc3ltLk1PRCk7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC0zODoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMzg6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBkaXNhbWJpZ3VhdGVBeGlzT3JGdW5jdGlvbihzeW0uS0VZKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTM5OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAzOToKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIGRpc2FtYmlndWF0ZU9wZXJhdG9yKHN5bS5BTkQpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtNDA6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDQwOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gZGlzYW1iaWd1YXRlQXhpc09yRnVuY3Rpb24oc3ltLlNFTEYpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtNDE6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDQxOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gZGlzYW1iaWd1YXRlQXhpc09yRnVuY3Rpb24oc3ltLkNISUxEKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTQyOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSA0MjoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uVEVYVCk7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC00MzoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgNDM6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLk5PREUpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtNDQ6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDQ0OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gZGlzYW1iaWd1YXRlQXhpc09yRnVuY3Rpb24oc3ltLlBBUkVOVCk7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC00NToKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgNDU6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLlRFWFQpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtNDY6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDQ2OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5OT0RFKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTQ3OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSA0NzoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIGRpc2FtYmlndWF0ZUF4aXNPckZ1bmN0aW9uKHN5bS5BTkNFU1RPUik7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC00ODoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgNDg6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IGluaXRpYWxpemUoKTsgcmV0dXJuIG5ldyBTeW1ib2woc3ltLlBBVFRFUk4pOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtNDk6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDQ5OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gZGlzYW1iaWd1YXRlQXhpc09yRnVuY3Rpb24oc3ltLk5BTUVTUEFDRSk7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC01MDoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgNTA6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLkNPTU1FTlQpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtNTE6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDUxOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gZGlzYW1iaWd1YXRlQXhpc09yRnVuY3Rpb24oc3ltLlBSRUNFRElORyk7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC01MjoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgNTI6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBkaXNhbWJpZ3VhdGVBeGlzT3JGdW5jdGlvbihzeW0uQVRUUklCVVRFKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTUzOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSA1MzoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIGRpc2FtYmlndWF0ZUF4aXNPckZ1bmN0aW9uKHN5bS5GT0xMT1dJTkcpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtNTQ6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDU0OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gZGlzYW1iaWd1YXRlQXhpc09yRnVuY3Rpb24oc3ltLkRFU0NFTkRBTlQpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtNTU6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDU1OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5DT01NRU5UKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTU2OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSA1NjoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgaW5pdGlhbGl6ZSgpOyByZXR1cm4gbmV3IFN5bWJvbChzeW0uRVhQUkVTU0lPTik7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC01NzoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgNTc6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBkaXNhbWJpZ3VhdGVBeGlzT3JGdW5jdGlvbihzeW0uQU5DRVNUT1JPUlNFTEYpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtNTg6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDU4OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gZGlzYW1iaWd1YXRlQXhpc09yRnVuY3Rpb24oc3ltLlBSRUNFRElOR1NJQkxJTkcpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtNTk6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDU5OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gZGlzYW1iaWd1YXRlQXhpc09yRnVuY3Rpb24oc3ltLkZPTExPV0lOR1NJQkxJTkcpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtNjA6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDYwOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gZGlzYW1iaWd1YXRlQXhpc09yRnVuY3Rpb24oc3ltLkRFU0NFTkRBTlRPUlNFTEYpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtNjE6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDYxOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gZGlzYW1iaWd1YXRlQXhpc09yRnVuY3Rpb24oc3ltLlBJUEFSQU0pOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtNjI6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDYyOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5QSSk7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC02MzoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgNjM6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLlBJKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTY0OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSA2NToKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uUU5BTUUsIHl5dGV4dCgpKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTY1OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSA2NjoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgdGhyb3cgbmV3IEV4Y2VwdGlvbih5eXRleHQoKSk7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC02NjoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgNjc6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLklOVCwgbmV3IExvbmcoeXl0ZXh0KCkpKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTY3OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSA2ODoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uUkVBTCwgbmV3IERvdWJsZSh5eXRleHQoKSkpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtNjg6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDcwOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5RTkFNRSwgeXl0ZXh0KCkpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtNjk6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDcxOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyB0aHJvdyBuZXcgRXhjZXB0aW9uKHl5dGV4dCgpKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTcwOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSA3MzoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uUU5BTUUsIHl5dGV4dCgpKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTcxOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSA3NDoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgdGhyb3cgbmV3IEV4Y2VwdGlvbih5eXRleHQoKSk7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC03MjoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgNzY6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLlFOQU1FLCB5eXRleHQoKSk7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC03MzoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgNzc6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHRocm93IG5ldyBFeGNlcHRpb24oeXl0ZXh0KCkpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtNzQ6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDc5OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5RTkFNRSwgeXl0ZXh0KCkpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtNzU6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDgxOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5RTkFNRSwgeXl0ZXh0KCkpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtNzY6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDgzOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5RTkFNRSwgeXl0ZXh0KCkpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtNzc6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDg1OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5RTkFNRSwgeXl0ZXh0KCkpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtNzg6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDg3OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5RTkFNRSwgeXl0ZXh0KCkpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtNzk6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDg5OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5RTkFNRSwgeXl0ZXh0KCkpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtODA6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDkxOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5RTkFNRSwgeXl0ZXh0KCkpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtODE6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDkzOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5RTkFNRSwgeXl0ZXh0KCkpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtODI6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDk1OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5RTkFNRSwgeXl0ZXh0KCkpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtODM6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDk3OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5RTkFNRSwgeXl0ZXh0KCkpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtODQ6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDk5OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5RTkFNRSwgeXl0ZXh0KCkpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtODU6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDEwMToKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uUU5BTUUsIHl5dGV4dCgpKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTg2OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxMDM6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLlFOQU1FLCB5eXRleHQoKSk7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC04NzoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTA1OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5RTkFNRSwgeXl0ZXh0KCkpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtODg6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDEwNzoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uUU5BTUUsIHl5dGV4dCgpKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTg5OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxMDk6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLlFOQU1FLCB5eXRleHQoKSk7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC05MDoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTExOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5RTkFNRSwgeXl0ZXh0KCkpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtOTE6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDExMzoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uUU5BTUUsIHl5dGV4dCgpKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTkyOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxMTU6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLlFOQU1FLCB5eXRleHQoKSk7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC05MzoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTE3OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5RTkFNRSwgeXl0ZXh0KCkpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtOTQ6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDExOToKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uUU5BTUUsIHl5dGV4dCgpKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTk1OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxMjE6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLlFOQU1FLCB5eXRleHQoKSk7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC05NjoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTIzOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5RTkFNRSwgeXl0ZXh0KCkpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtOTc6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDEyNToKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uUU5BTUUsIHl5dGV4dCgpKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTk4OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxMjc6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLlFOQU1FLCB5eXRleHQoKSk7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC05OToKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTI4OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5RTkFNRSwgeXl0ZXh0KCkpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtMTAwOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxMjk6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLlFOQU1FLCB5eXRleHQoKSk7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC0xMDE6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDEzMDoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uUU5BTUUsIHl5dGV4dCgpKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTEwMjoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTMxOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5RTkFNRSwgeXl0ZXh0KCkpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtMTAzOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxMzI6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLlFOQU1FLCB5eXRleHQoKSk7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC0xMDQ6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDEzMzoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uUU5BTUUsIHl5dGV4dCgpKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTEwNToKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTM0OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5RTkFNRSwgeXl0ZXh0KCkpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtMTA2OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxMzU6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLlFOQU1FLCB5eXRleHQoKSk7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC0xMDc6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDEzNjoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uUU5BTUUsIHl5dGV4dCgpKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTEwODoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTM3OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5RTkFNRSwgeXl0ZXh0KCkpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtMTA5OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxMzg6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLlFOQU1FLCB5eXRleHQoKSk7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC0xMTA6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDEzOToKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uUU5BTUUsIHl5dGV4dCgpKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTExMToKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTQwOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5RTkFNRSwgeXl0ZXh0KCkpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtMTEyOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxNDE6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLlFOQU1FLCB5eXRleHQoKSk7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC0xMTM6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDE0MjoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uUU5BTUUsIHl5dGV4dCgpKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTExNDoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTQzOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5RTkFNRSwgeXl0ZXh0KCkpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtMTE1OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxNDQ6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLlFOQU1FLCB5eXRleHQoKSk7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC0xMTY6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDE0NToKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uUU5BTUUsIHl5dGV4dCgpKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTExNzoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTQ2OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5RTkFNRSwgeXl0ZXh0KCkpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtMTE4OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxNDc6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLlFOQU1FLCB5eXRleHQoKSk7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC0xMTk6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDE0ODoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uUU5BTUUsIHl5dGV4dCgpKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTEyMDoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTQ5OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5RTkFNRSwgeXl0ZXh0KCkpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtMTIxOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxNTA6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLlFOQU1FLCB5eXRleHQoKSk7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC0xMjI6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDE1MToKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uUU5BTUUsIHl5dGV4dCgpKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTEyMzoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTUyOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5RTkFNRSwgeXl0ZXh0KCkpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtMTI0OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxNTM6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLlFOQU1FLCB5eXRleHQoKSk7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC0xMjU6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDE1NDoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uUU5BTUUsIHl5dGV4dCgpKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTEyNjoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTU1OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5RTkFNRSwgeXl0ZXh0KCkpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtMTI3OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxNTY6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLlFOQU1FLCB5eXRleHQoKSk7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC0xMjg6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDE1NzoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uUU5BTUUsIHl5dGV4dCgpKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTEyOToKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTU4OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5RTkFNRSwgeXl0ZXh0KCkpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtMTMwOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxNTk6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLlFOQU1FLCB5eXRleHQoKSk7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC0xMzE6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDE2MDoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uUU5BTUUsIHl5dGV4dCgpKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTEzMjoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTYxOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5RTkFNRSwgeXl0ZXh0KCkpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtMTMzOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxNjI6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLlFOQU1FLCB5eXRleHQoKSk7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC0xMzQ6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDE2MzoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uUU5BTUUsIHl5dGV4dCgpKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTEzNToKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTY0OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5RTkFNRSwgeXl0ZXh0KCkpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtMTM2OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxNjU6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLlFOQU1FLCB5eXRleHQoKSk7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC0xMzc6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDE2NjoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uUU5BTUUsIHl5dGV4dCgpKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTEzODoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTY3OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5RTkFNRSwgeXl0ZXh0KCkpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtMTM5OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxNjg6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLlFOQU1FLCB5eXRleHQoKSk7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC0xNDA6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDE2OToKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uUU5BTUUsIHl5dGV4dCgpKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTE0MToKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTcwOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5RTkFNRSwgeXl0ZXh0KCkpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtMTQyOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxNzE6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLlFOQU1FLCB5eXRleHQoKSk7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC0xNDM6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDE3MjoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uUU5BTUUsIHl5dGV4dCgpKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTE0NDoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTczOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5RTkFNRSwgeXl0ZXh0KCkpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtMTQ1OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxNzQ6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLlFOQU1FLCB5eXRleHQoKSk7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC0xNDY6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDE3NToKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uUU5BTUUsIHl5dGV4dCgpKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTE0NzoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTc2OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5RTkFNRSwgeXl0ZXh0KCkpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtMTQ4OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxNzc6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLlFOQU1FLCB5eXRleHQoKSk7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC0xNDk6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDE3ODoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uUU5BTUUsIHl5dGV4dCgpKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTE1MDoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTc5OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5RTkFNRSwgeXl0ZXh0KCkpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtMTUxOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxODA6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLlFOQU1FLCB5eXRleHQoKSk7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC0xNTI6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDE4MToKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uUU5BTUUsIHl5dGV4dCgpKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTE1MzoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTgyOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5RTkFNRSwgeXl0ZXh0KCkpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtMTU0OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxODM6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLlFOQU1FLCB5eXRleHQoKSk7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC0xNTU6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDE4NDoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uUU5BTUUsIHl5dGV4dCgpKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTE1NjoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTg3OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5RTkFNRSwgeXl0ZXh0KCkpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtMTU3OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxODk6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLlFOQU1FLCB5eXRleHQoKSk7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC0xNTg6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDE5MToKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uUU5BTUUsIHl5dGV4dCgpKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTE1OToKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTkyOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5RTkFNRSwgeXl0ZXh0KCkpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtMTYwOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxOTM6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLlFOQU1FLCB5eXRleHQoKSk7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC0xNjE6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDE5NDoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uUU5BTUUsIHl5dGV4dCgpKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTE2MjoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTk1OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5RTkFNRSwgeXl0ZXh0KCkpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtMTYzOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxOTY6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLlFOQU1FLCB5eXRleHQoKSk7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC0xNjQ6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDE5NzoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uUU5BTUUsIHl5dGV4dCgpKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTE2NToKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTk4OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5RTkFNRSwgeXl0ZXh0KCkpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtMTY2OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxOTk6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLlFOQU1FLCB5eXRleHQoKSk7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC0xNjc6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDIwMDoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uUU5BTUUsIHl5dGV4dCgpKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTE2ODoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMjAxOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5RTkFNRSwgeXl0ZXh0KCkpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtMTY5OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAyMDI6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLlFOQU1FLCB5eXRleHQoKSk7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC0xNzA6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDIwMzoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uUU5BTUUsIHl5dGV4dCgpKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTE3MToKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMjA0OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5RTkFNRSwgeXl0ZXh0KCkpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtMTcyOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAyMDU6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLlFOQU1FLCB5eXRleHQoKSk7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC0xNzM6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDIwNjoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uUU5BTUUsIHl5dGV4dCgpKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTE3NDoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMjA3OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5RTkFNRSwgeXl0ZXh0KCkpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtMTc1OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAyMDg6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLlFOQU1FLCB5eXRleHQoKSk7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC0xNzY6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDIwOToKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uUU5BTUUsIHl5dGV4dCgpKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTE3NzoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMjEwOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5RTkFNRSwgeXl0ZXh0KCkpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtMTc4OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAyMTE6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLlFOQU1FLCB5eXRleHQoKSk7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC0xNzk6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDIxMjoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uUU5BTUUsIHl5dGV4dCgpKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTE4MDoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMjEzOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5RTkFNRSwgeXl0ZXh0KCkpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtMTgxOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAyMTQ6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLlFOQU1FLCB5eXRleHQoKSk7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC0xODI6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDIxNToKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uUU5BTUUsIHl5dGV4dCgpKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTE4MzoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMjE2OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5RTkFNRSwgeXl0ZXh0KCkpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtMTg0OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAyMTc6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLlFOQU1FLCB5eXRleHQoKSk7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC0xODU6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDIxODoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uUU5BTUUsIHl5dGV4dCgpKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTE4NjoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMjE5OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5RTkFNRSwgeXl0ZXh0KCkpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtMTg3OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAyMjA6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLlFOQU1FLCB5eXRleHQoKSk7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC0xODg6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDIyMToKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uUU5BTUUsIHl5dGV4dCgpKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTE4OToKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMjIyOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5RTkFNRSwgeXl0ZXh0KCkpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtMTkwOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAyMjM6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLlFOQU1FLCB5eXRleHQoKSk7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC0xOTE6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDIyNDoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uUU5BTUUsIHl5dGV4dCgpKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTE5MjoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMjI1OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5RTkFNRSwgeXl0ZXh0KCkpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtMTkzOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAyMjY6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLlFOQU1FLCB5eXRleHQoKSk7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC0xOTQ6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDIyNzoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uUU5BTUUsIHl5dGV4dCgpKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTE5NToKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMjI4OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5RTkFNRSwgeXl0ZXh0KCkpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtMTk2OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAyMjk6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLlFOQU1FLCB5eXRleHQoKSk7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC0xOTc6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDIzMDoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uUU5BTUUsIHl5dGV4dCgpKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTE5ODoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMjMxOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5RTkFNRSwgeXl0ZXh0KCkpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAtMTk5OgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAyMzI6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLlFOQU1FLCB5eXRleHQoKSk7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC0yMDA6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDIzMzoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uUU5BTUUsIHl5dGV4dCgpKTsgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgLTIwMToKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5eV9lcnJvcihZWV9FX0lOVEVSTkFMLGZhbHNlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIC0xOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5eV9pbml0aWFsID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5eV9zdGF0ZSA9IHl5X3N0YXRlX2R0cmFuc1t5eV9sZXhpY2FsX3N0YXRlXTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5eV9uZXh0X3N0YXRlID0gWVlfTk9fU1RBVEU7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeXlfbGFzdF9hY2NlcHRfc3RhdGUgPSBZWV9OT19TVEFURTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5eV9tYXJrX3N0YXJ0KCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeXlfdGhpc19hY2NlcHQgPSB5eV9hY3B0W3l5X3N0YXRlXTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoWVlfTk9UX0FDQ0VQVCAhPSB5eV90aGlzX2FjY2VwdCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeXlfbGFzdF9hY2NlcHRfc3RhdGUgPSB5eV9zdGF0ZTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHl5X21hcmtfZW5kKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL1hQYXRoUGFyc2VyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL1hQYXRoUGFyc2VyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGYzM2IzNGIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9YUGF0aFBhcnNlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzE0NiArMCwwIEBACi0KLS8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotLy8gVGhlIGZvbGxvd2luZyBjb2RlIHdhcyBnZW5lcmF0ZWQgYnkgQ1VQIHYwLjEwagotLy8gVGh1IE9jdCAwNiAxMDowOToyNiBQRFQgMjAwNQotLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgamF2YS51dGlsLlN0YWNrOwotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci1pbXBvcnQgamF2YS5pby5TdHJpbmdSZWFkZXI7Ci1pbXBvcnQgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLio7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5ET007Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uQXhpczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMucnVudGltZS5PcGVyYXRvcnM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuRXJyb3JNc2c7Ci0KLS8qKiBDVVAgdjAuMTBqIGdlbmVyYXRlZCBwYXJzZXIuCi0gICovCi1wdWJsaWMgY2xhc3MgWFBhdGhQYXJzZXIgZXh0ZW5kcyBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUubHJfcGFyc2VyIHsKLQotICAvKiogRGVmYXVsdCBjb25zdHJ1Y3Rvci4gKi8KLSAgcHVibGljIFhQYXRoUGFyc2VyKCkge3N1cGVyKCk7fQotCi0gIC8qKiBDb25zdHJ1Y3RvciB3aGljaCBzZXRzIHRoZSBkZWZhdWx0IHNjYW5uZXIuICovCi0gIHB1YmxpYyBYUGF0aFBhcnNlcihjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU2Nhbm5lciBzKSB7c3VwZXIocyk7fQotCi0gIC8qKiBQcm9kdWN0aW9uIHRhYmxlLiAqLwotICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIHNob3J0IF9wcm9kdWN0aW9uX3RhYmxlW11bXSA9Ci0gICAgdW5wYWNrRnJvbVN0cmluZ3MobmV3IFN0cmluZ1tdIHsKLSAgICAiXDAwMFwyMTVcMDAwXDAwMlwwMDJcMDA0XDAwMFwwMDJcMDAzXDAwNFwwMDBcMDAyXDAwMyIgKwotICAgICJcMDA0XDAwMFwwMDJcMDM2XDAwM1wwMDBcMDAyXDAzNlwwMDVcMDAwXDAwMlwwMzdcMDAzIiArCi0gICAgIlwwMDBcMDAyXDAzN1wwMDRcMDAwXDAwMlwwMzdcMDAzXDAwMFwwMDJcMDM3XDAwNVwwMDAiICsKLSAgICAiXDAwMlwwMzdcMDA1XDAwMFwwMDJcMDM3XDAwNFwwMDBcMDAyXDAzN1wwMDNcMDAwXDAwMiIgKwotICAgICJcMDM1XDAwNlwwMDBcMDAyXDAzNVwwMTBcMDAwXDAwMlwwNDBcMDA2XDAwMFwwMDJcMDQxIiArCi0gICAgIlwwMDNcMDAwXDAwMlwwNDFcMDA1XDAwMFwwMDJcMDQxXDAwNVwwMDBcMDAyXDA0MlwwMDMiICsKLSAgICAiXDAwMFwwMDJcMDQyXDAwNFwwMDBcMDAyXDA0MlwwMDNcMDAwXDAwMlwwNDJcMDA0XDAwMCIgKwotICAgICJcMDAyXDA0MlwwMDRcMDAwXDAwMlwwNDJcMDA1XDAwMFwwMDJcMDQyXDAwNFwwMDBcMDAyIiArCi0gICAgIlwwNDJcMDA1XDAwMFwwMDJcMDQzXDAwM1wwMDBcMDAyXDA0M1wwMDNcMDAwXDAwMlwwNDMiICsKLSAgICAiXDAwM1wwMDBcMDAyXDA0M1wwMDNcMDAwXDAwMlwwNDNcMDAzXDAwMFwwMDJcMDQ0XDAwMyIgKwotICAgICJcMDAwXDAwMlwwNDRcMDAzXDAwMFwwMDJcMDU0XDAwM1wwMDBcMDAyXDA1NFwwMDRcMDAwIiArCi0gICAgIlwwMDJcMDU0XDAwNFwwMDBcMDAyXDA0NVwwMDNcMDAwXDAwMlwwNDVcMDA0XDAwMFwwMDIiICsKLSAgICAiXDAwN1wwMDVcMDAwXDAwMlwwMDRcMDAzXDAwMFwwMDJcMDEyXDAwM1wwMDBcMDAyXDAxMiIgKwotICAgICJcMDA1XDAwMFwwMDJcMDEzXDAwM1wwMDBcMDAyXDAxM1wwMDVcMDAwXDAwMlwwMTRcMDAzIiArCi0gICAgIlwwMDBcMDAyXDAxNFwwMDVcMDAwXDAwMlwwMTRcMDA1XDAwMFwwMDJcMDE1XDAwM1wwMDAiICsKLSAgICAiXDAwMlwwMTVcMDA1XDAwMFwwMDJcMDE1XDAwNVwwMDBcMDAyXDAxNVwwMDVcMDAwXDAwMiIgKwotICAgICJcMDE1XDAwNVwwMDBcMDAyXDAxNlwwMDNcMDAwXDAwMlwwMTZcMDA1XDAwMFwwMDJcMDE2IiArCi0gICAgIlwwMDVcMDAwXDAwMlwwMTdcMDAzXDAwMFwwMDJcMDE3XDAwNVwwMDBcMDAyXDAxN1wwMDUiICsKLSAgICAiXDAwMFwwMDJcMDE3XDAwNVwwMDBcMDAyXDAyMFwwMDNcMDAwXDAwMlwwMjBcMDA0XDAwMCIgKwotICAgICJcMDAyXDAyNFwwMDNcMDAwXDAwMlwwMjRcMDA1XDAwMFwwMDJcMDI1XDAwM1wwMDBcMDAyIiArCi0gICAgIlwwMjVcMDAzXDAwMFwwMDJcMDI1XDAwNVwwMDBcMDAyXDAyNVwwMDVcMDAwXDAwMlwwMDYiICsKLSAgICAiXDAwM1wwMDBcMDAyXDAwNlwwMDNcMDAwXDAwMlwwMjdcMDAzXDAwMFwwMDJcMDI3XDAwNSIgKwotICAgICJcMDAwXDAwMlwwMjdcMDAzXDAwMFwwMDJcMDMxXDAwM1wwMDBcMDAyXDAzMVwwMDRcMDAwIiArCi0gICAgIlwwMDJcMDMxXDAwM1wwMDBcMDAyXDAzMFwwMDVcMDAwXDAwMlwwMzJcMDA0XDAwMFwwMDIiICsKLSAgICAiXDAxMVwwMDNcMDAwXDAwMlwwMTFcMDA0XDAwMFwwMDJcMDExXDAwNVwwMDBcMDAyXDAxMSIgKwotICAgICJcMDA0XDAwMFwwMDJcMDExXDAwM1wwMDBcMDAyXDA1M1wwMDRcMDAwXDAwMlwwNTNcMDAzIiArCi0gICAgIlwwMDBcMDAyXDA1MlwwMDNcMDAwXDAwMlwwNTJcMDAzXDAwMFwwMDJcMDUyXDAwM1wwMDAiICsKLSAgICAiXDAwMlwwNTJcMDAzXDAwMFwwMDJcMDUyXDAwM1wwMDBcMDAyXDA1MlwwMDNcMDAwXDAwMiIgKwotICAgICJcMDUyXDAwM1wwMDBcMDAyXDA1MlwwMDNcMDAwXDAwMlwwNTJcMDAzXDAwMFwwMDJcMDUyIiArCi0gICAgIlwwMDNcMDAwXDAwMlwwNTJcMDAzXDAwMFwwMDJcMDUyXDAwM1wwMDBcMDAyXDA1MlwwMDMiICsKLSAgICAiXDAwMFwwMDJcMDI2XDAwM1wwMDBcMDAyXDAyNlwwMDNcMDAwXDAwMlwwMTBcMDAzXDAwMCIgKwotICAgICJcMDAyXDAxMFwwMDRcMDAwXDAwMlwwMjNcMDAzXDAwMFwwMDJcMDIzXDAwNVwwMDBcMDAyIiArCi0gICAgIlwwMjNcMDAzXDAwMFwwMDJcMDIzXDAwM1wwMDBcMDAyXDAyM1wwMDNcMDAwXDAwMlwwMjMiICsKLSAgICAiXDAwM1wwMDBcMDAyXDAyMVwwMDRcMDAwXDAwMlwwMjJcMDA1XDAwMFwwMDJcMDIyXDAwNiIgKwotICAgICJcMDAwXDAwMlwwNDZcMDAzXDAwMFwwMDJcMDQ2XDAwNVwwMDBcMDAyXDA1MFwwMDNcMDAwIiArCi0gICAgIlwwMDJcMDUxXDAwM1wwMDBcMDAyXDAwNVwwMDNcMDAwXDAwMlwwMzNcMDAzXDAwMFwwMDIiICsKLSAgICAiXDAzM1wwMDNcMDAwXDAwMlwwMzNcMDAzXDAwMFwwMDJcMDMzXDAwM1wwMDBcMDAyXDAzMyIgKwotICAgICJcMDA2XDAwMFwwMDJcMDMzXDAwM1wwMDBcMDAyXDAzNFwwMDNcMDAwXDAwMlwwMzRcMDAzIiArCi0gICAgIlwwMDBcMDAyXDA0N1wwMDNcMDAwXDAwMlwwNDdcMDAzXDAwMFwwMDJcMDQ3XDAwM1wwMDAiICsKLSAgICAiXDAwMlwwNDdcMDAzXDAwMFwwMDJcMDQ3XDAwM1wwMDBcMDAyXDA0N1wwMDNcMDAwXDAwMiIgKwotICAgICJcMDQ3XDAwM1wwMDBcMDAyXDA0N1wwMDNcMDAwXDAwMlwwNDdcMDAzXDAwMFwwMDJcMDQ3IiArCi0gICAgIlwwMDNcMDAwXDAwMlwwNDdcMDAzXDAwMFwwMDJcMDQ3XDAwM1wwMDBcMDAyXDA0N1wwMDMiICsKLSAgICAiXDAwMFwwMDJcMDQ3XDAwM1wwMDBcMDAyXDA0N1wwMDNcMDAwXDAwMlwwNDdcMDAzXDAwMCIgKwotICAgICJcMDAyXDA0N1wwMDNcMDAwXDAwMlwwNDdcMDAzIiB9KTsKLQotICAvKiogQWNjZXNzIHRvIHByb2R1Y3Rpb24gdGFibGUuICovCi0gIHB1YmxpYyBzaG9ydFtdW10gcHJvZHVjdGlvbl90YWJsZSgpIHtyZXR1cm4gX3Byb2R1Y3Rpb25fdGFibGU7fQotCi0gIC8qKiBQYXJzZS1hY3Rpb24gdGFibGUuICovCi0gIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgc2hvcnRbXVtdIF9hY3Rpb25fdGFibGUgPQotICAgIHVucGFja0Zyb21TdHJpbmdzKG5ldyBTdHJpbmdbXSB7Ci0gICAgIlwwMDBcMzA3XDAwMFwwMDZcMDY2XDAwNlwwNjdcMDA1XDAwMVwwMDJcMDAwXDAwNFwwMDIiICsKLSAgICAiXDMxMVwwMDFcMDAyXDAwMFwxMTBcMDA0XDA2MVwwMDVcMTExXDAxMVwwNzFcMDEzXDEwMyIgKwotICAgICJcMDE1XDEzNFwwMTZcMDY2XDAxN1wxMDZcMDIxXDA3MFwwMzFcMDc1XDAzMlwwMzFcMDMzIiArCi0gICAgIlwwNDBcMDM0XDA1N1wwMzVcMDM0XDAzNlwxMTNcMDM3XDE0MVwwNDBcMTQyXDA0MVwxNDUiICsKLSAgICAiXDA0NFwwNjNcMDQ1XDA2MlwwNDZcMDY1XDA0N1wxMTVcMDUwXDEyM1wwNTFcMTM2XDA1MiIgKwotICAgICJcMDc3XDA1M1wxNDNcMDU0XDEzMVwwNTVcMTI1XDA1NlwxMTZcMDU3XDEwNFwwNjBcMTQwIiArCi0gICAgIlwwNjFcMDY3XDA2MlwwNjBcMDYzXDEyN1wwNjRcMTMyXDA2NVwwNzJcMDAxXDAwMlwwMDAiICsKLSAgICAiXDA3MFwwMDRcMDEzXDAxM1wwMjdcMDE2XDAyMFwwMjFcMDIzXDAzMlwwMzFcMDMzXDA0MCIgKwotICAgICJcMDM1XDAzNFwwMzZcMDMzXDAzN1wwNDZcMDQwXDA0N1wwNDFcMDUxXDA0NFwwMTVcMDQ1IiArCi0gICAgIlwwMTRcMDQ2XDAxNlwwNDdcMDM2XDA1MFwwMzdcMDUxXDA0NFwwNTJcMDI1XDA1M1wwNTAiICsKLSAgICAiXDA1NFwwNDNcMDU1XDA0MVwwNTZcMDM1XDA1N1wwMzBcMDYwXDA0NVwwNjFcMDIxXDA2MiIgKwotICAgICJcMDEyXDA2M1wwNDJcMDAxXDAwMlwwMDBcMDA2XDAwMlx1ZmZmZVwwMTBcMzA2XDAwMVwwMDIiICsKLSAgICAiXDAwMFwwMDRcMDAyXDAwMFwwMDFcMDAyXDAwMFwwMTRcMDAyXHVmZmU3XDAwNFx1ZmZlN1wwMDYiICsKLSAgICAiXHVmZmU3XDAxMFx1ZmZlN1wwMjFcdWZmZTdcMDAxXDAwMlwwMDBcMDU0XDAwMlx1ZmY3YVwwMDRcdWZmN2EiICsKLSAgICAiXDAwNlx1ZmY3YVwwMDdcdWZmN2FcMDEwXHVmZjdhXDAxMlx1ZmY3YVwwMTNcdWZmN2FcMDE0XHVmZjdhXDAyMSIgKwotICAgICJcdWZmN2FcMDIyXHVmZjdhXDAyM1x1ZmY3YVwwMjRcdWZmN2FcMDI1XHVmZjdhXDAyNlx1ZmY3YVwwMjdcdWZmN2EiICsKLSAgICAiXDAzMFx1ZmY3YVwwMzFcdWZmN2FcMDMyXHVmZjdhXDAzM1x1ZmY3YVwwNDJcdWZmN2FcMDQzXHVmZjdhXDAwMSIgKwotICAgICJcMDAyXDAwMFwwNzBcMDAyXHVmZmZjXDAxMFx1ZmZmY1wwMTNcMDI3XDAxNlwwMjBcMDMyXDAzMSIgKwotICAgICJcMDMzXDA0MFwwMzVcMDM0XDAzNlwxMTNcMDM3XDE0MVwwNDBcMDQ3XDA0MVwwNTFcMDQ0IiArCi0gICAgIlwwMTVcMDQ1XDAxNFwwNDZcMDE2XDA0N1wwMzZcMDUwXDAzN1wwNTFcMDQ0XDA1MlwwMjUiICsKLSAgICAiXDA1M1wwNTBcMDU0XDA0M1wwNTVcMDQxXDA1NlwwMzVcMDU3XDAzMFwwNjBcMDQ1XDA2MSIgKwotICAgICJcMDIxXDA2MlwwMTJcMDYzXDA0MlwwMDFcMDAyXDAwMFwwMTRcMDAyXHVmZmUzXDAwNFx1ZmZlMyIgKwotICAgICJcMDA2XHVmZmUzXDAxMFx1ZmZlM1wwMjFcdWZmZTNcMDAxXDAwMlwwMDBcMDE0XDAwMlx1ZmZlNFwwMDQiICsKLSAgICAiXHVmZmU0XDAwNlx1ZmZlNFwwMTBcdWZmZTRcMDIxXHVmZmU0XDAwMVwwMDJcMDAwXDAwNFwwMTFcMzAyIiArCi0gICAgIlwwMDFcMDAyXDAwMFwwMTJcMDAyXHVmZmZhXDAwNFwyNzdcMDEwXHVmZmZhXDAyMVwyNzZcMDAxIiArCi0gICAgIlwwMDJcMDAwXDA2MlwwMTNcdWZmZTBcMDMyXHVmZmUwXDAzM1x1ZmZlMFwwMzVcdWZmZTBcMDM2XHVmZmUwIiArCi0gICAgIlwwMzdcdWZmZTBcMDQwXHVmZmUwXDA0MVx1ZmZlMFwwNDRcdWZmZTBcMDQ1XHVmZmUwXDA0Nlx1ZmZlMFwwNDciICsKLSAgICAiXHVmZmUwXDA1MFx1ZmZlMFwwNTFcdWZmZTBcMDUyXHVmZmUwXDA1M1x1ZmZlMFwwNTRcdWZmZTBcMDU1XHVmZmUwIiArCi0gICAgIlwwNTZcdWZmZTBcMDU3XHVmZmUwXDA2MFx1ZmZlMFwwNjFcdWZmZTBcMDYyXHVmZmUwXDA2M1x1ZmZlMFwwMDEiICsKLSAgICAiXDAwMlwwMDBcMDU0XDAwMlx1ZmY3YlwwMDRcdWZmN2JcMDA2XHVmZjdiXDAwN1x1ZmY3YlwwMTBcdWZmN2IiICsKLSAgICAiXDAxMlx1ZmY3YlwwMTNcdWZmN2JcMDE0XHVmZjdiXDAyMVx1ZmY3YlwwMjJcdWZmN2JcMDIzXHVmZjdiXDAyNCIgKwotICAgICJcdWZmN2JcMDI1XHVmZjdiXDAyNlx1ZmY3YlwwMjdcdWZmN2JcMDMwXHVmZjdiXDAzMVx1ZmY3YlwwMzJcdWZmN2IiICsKLSAgICAiXDAzM1x1ZmY3YlwwNDJcdWZmN2JcMDQzXHVmZjdiXDAwMVwwMDJcMDAwXDA2MlwwMTNcMDI3XDAzMiIgKwotICAgICJcMDMxXDAzM1wwNDBcMDM1XDAzNFwwMzZcMTEzXDAzN1wxNDFcMDQwXDA0N1wwNDFcMDUxIiArCi0gICAgIlwwNDRcMDE1XDA0NVwwMTRcMDQ2XDAxNlwwNDdcMDM2XDA1MFwwMzdcMDUxXDA0NFwwNTIiICsKLSAgICAiXDE3MFwwNTNcMTY2XDA1NFwwNDNcMDU1XDA0MVwwNTZcMDM1XDA1N1wwMzBcMDYwXDA0NSIgKwotICAgICJcMDYxXDAyMVwwNjJcMDEyXDA2M1wwNDJcMDAxXDAwMlwwMDBcMDY0XDAxM1wwMjdcMDE2IiArCi0gICAgIlwwMjBcMDMyXDAzMVwwMzNcMDQwXDAzNVwwMzRcMDM2XDExM1wwMzdcMTQxXDA0MFwwNDciICsKLSAgICAiXDA0MVwwNTFcMDQ0XDAxNVwwNDVcMDE0XDA0NlwwMTZcMDQ3XDAzNlwwNTBcMDM3XDA1MSIgKwotICAgICJcMDQ0XDA1MlwwMjVcMDUzXDA1MFwwNTRcMDQzXDA1NVwwNDFcMDU2XDAzNVwwNTdcMDMwIiArCi0gICAgIlwwNjBcMDQ1XDA2MVwwMjFcMDYyXDAxMlwwNjNcMDQyXDAwMVwwMDJcMDAwXDAxMlwwMDIiICsKLSAgICAiXHVmZmYyXDAwNFwyNjZcMDEwXHVmZmYyXDAyMVwyNjVcMDAxXDAwMlwwMDBcMDE2XDAwMlx1ZmY3ZiIgKwotICAgICJcMDA0XHVmZjdmXDAwNlx1ZmY3ZlwwMTBcdWZmN2ZcMDIwXDI2NFwwMjFcdWZmN2ZcMDAxXDAwMlwwMDAiICsKLSAgICAiXDAwNlwwMDJcdWZmZjZcMDEwXHVmZmY2XDAwMVwwMDJcMDAwXDAxNFwwMDJcdWZmZTJcMDA0XHVmZmUyIiArCi0gICAgIlwwMDZcdWZmZTJcMDEwXHVmZmUyXDAyMVx1ZmZlMlwwMDFcMDAyXDAwMFwwNTRcMDAyXHVmZjdkXDAwNCIgKwotICAgICJcdWZmN2RcMDA2XHVmZjdkXDAwN1x1ZmY3ZFwwMTBcdWZmN2RcMDEyXHVmZjdkXDAxM1x1ZmY3ZFwwMTRcdWZmN2QiICsKLSAgICAiXDAyMVx1ZmY3ZFwwMjJcdWZmN2RcMDIzXHVmZjdkXDAyNFx1ZmY3ZFwwMjVcdWZmN2RcMDI2XHVmZjdkXDAyNyIgKwotICAgICJcdWZmN2RcMDMwXHVmZjdkXDAzMVx1ZmY3ZFwwMzJcdWZmN2RcMDMzXHVmZjdkXDA0Mlx1ZmY3ZFwwNDNcdWZmN2QiICsKLSAgICAiXDAwMVwwMDJcMDAwXDA1NlwwMDJcdWZmODVcMDA0XHVmZjg1XDAwNlx1ZmY4NVwwMDdcdWZmODVcMDEwIiArCi0gICAgIlx1ZmY4NVwwMTFcdWZmODVcMDEyXHVmZjg1XDAxM1x1ZmY4NVwwMTRcdWZmODVcMDIxXHVmZjg1XDAyMlx1ZmY4NSIgKwotICAgICJcMDIzXHVmZjg1XDAyNFx1ZmY4NVwwMjVcdWZmODVcMDI2XHVmZjg1XDAyN1x1ZmY4NVwwMzBcdWZmODVcMDMxIiArCi0gICAgIlx1ZmY4NVwwMzJcdWZmODVcMDMzXHVmZjg1XDA0Mlx1ZmY4NVwwNDNcdWZmODVcMDAxXDAwMlwwMDBcMDE0IiArCi0gICAgIlwwMDJcdWZmZWRcMDA0XHVmZmVkXDAwNlwwNTVcMDEwXHVmZmVkXDAyMVx1ZmZlZFwwMDFcMDAyXDAwMCIgKwotICAgICJcMDE2XDAwMlx1ZmY3NVwwMDRcdWZmNzVcMDA2XHVmZjc1XDAxMFx1ZmY3NVwwMTFcMjYwXDAyMVx1ZmY3NSIgKwotICAgICJcMDAxXDAwMlwwMDBcMDU2XDAwMlx1ZmY4NlwwMDRcdWZmODZcMDA2XHVmZjg2XDAwN1x1ZmY4NlwwMTAiICsKLSAgICAiXHVmZjg2XDAxMVx1ZmY4NlwwMTJcdWZmODZcMDEzXHVmZjg2XDAxNFx1ZmY4NlwwMjFcdWZmODZcMDIyXHVmZjg2IiArCi0gICAgIlwwMjNcdWZmODZcMDI0XHVmZjg2XDAyNVx1ZmY4NlwwMjZcdWZmODZcMDI3XHVmZjg2XDAzMFx1ZmY4NlwwMzEiICsKLSAgICAiXHVmZjg2XDAzMlx1ZmY4NlwwMzNcdWZmODZcMDQyXHVmZjg2XDA0M1x1ZmY4NlwwMDFcMDAyXDAwMFwwNTQiICsKLSAgICAiXDAwMlx1ZmY3ZVwwMDRcdWZmN2VcMDA2XHVmZjdlXDAwN1x1ZmY3ZVwwMTBcdWZmN2VcMDEyXHVmZjdlXDAxMyIgKwotICAgICJcdWZmN2VcMDE0XHVmZjdlXDAyMVx1ZmY3ZVwwMjJcdWZmN2VcMDIzXHVmZjdlXDAyNFx1ZmY3ZVwwMjVcdWZmN2UiICsKLSAgICAiXDAyNlx1ZmY3ZVwwMjdcdWZmN2VcMDMwXHVmZjdlXDAzMVx1ZmY3ZVwwMzJcdWZmN2VcMDMzXHVmZjdlXDA0MiIgKwotICAgICJcdWZmN2VcMDQzXHVmZjdlXDAwMVwwMDJcMDAwXDA1NFwwMDJcdWZmNzdcMDA0XHVmZjc3XDAwNlx1ZmY3NyIgKwotICAgICJcMDA3XHVmZjc3XDAxMFx1ZmY3N1wwMTJcdWZmNzdcMDEzXHVmZjc3XDAxNFx1ZmY3N1wwMjFcdWZmNzdcMDIyIiArCi0gICAgIlx1ZmY3N1wwMjNcdWZmNzdcMDI0XHVmZjc3XDAyNVx1ZmY3N1wwMjZcdWZmNzdcMDI3XHVmZjc3XDAzMFx1ZmY3NyIgKwotICAgICJcMDMxXHVmZjc3XDAzMlx1ZmY3N1wwMzNcdWZmNzdcMDQyXHVmZjc3XDA0M1x1ZmY3N1wwMDFcMDAyXDAwMCIgKwotICAgICJcMDU0XDAwMlx1ZmY3NlwwMDRcdWZmNzZcMDA2XHVmZjc2XDAwN1x1ZmY3NlwwMTBcdWZmNzZcMDEyXHVmZjc2IiArCi0gICAgIlwwMTNcdWZmNzZcMDE0XHVmZjc2XDAyMVx1ZmY3NlwwMjJcdWZmNzZcMDIzXHVmZjc2XDAyNFx1ZmY3NlwwMjUiICsKLSAgICAiXHVmZjc2XDAyNlx1ZmY3NlwwMjdcdWZmNzZcMDMwXHVmZjc2XDAzMVx1ZmY3NlwwMzJcdWZmNzZcMDMzXHVmZjc2IiArCi0gICAgIlwwNDJcdWZmNzZcMDQzXHVmZjc2XDAwMVwwMDJcMDAwXDA1NlwwMDJcdWZmODRcMDA0XHVmZjg0XDAwNiIgKwotICAgICJcdWZmODRcMDA3XHVmZjg0XDAxMFx1ZmY4NFwwMTFcdWZmODRcMDEyXHVmZjg0XDAxM1x1ZmY4NFwwMTRcdWZmODQiICsKLSAgICAiXDAyMVx1ZmY4NFwwMjJcdWZmODRcMDIzXHVmZjg0XDAyNFx1ZmY4NFwwMjVcdWZmODRcMDI2XHVmZjg0XDAyNyIgKwotICAgICJcdWZmODRcMDMwXHVmZjg0XDAzMVx1ZmY4NFwwMzJcdWZmODRcMDMzXHVmZjg0XDA0Mlx1ZmY4NFwwNDNcdWZmODQiICsKLSAgICAiXDAwMVwwMDJcMDAwXDA1NFwwMDJcdWZmODFcMDA0XHVmZjgxXDAwNlx1ZmY4MVwwMDdcdWZmODFcMDEwIiArCi0gICAgIlx1ZmY4MVwwMTJcdWZmODFcMDEzXHVmZjgxXDAxNFx1ZmY4MVwwMjFcdWZmODFcMDIyXHVmZjgxXDAyM1x1ZmY4MSIgKwotICAgICJcMDI0XHVmZjgxXDAyNVx1ZmY4MVwwMjZcdWZmODFcMDI3XHVmZjgxXDAzMFx1ZmY4MVwwMzFcdWZmODFcMDMyIiArCi0gICAgIlx1ZmY4MVwwMzNcdWZmODFcMDQyXHVmZjgxXDA0M1x1ZmY4MVwwMDFcMDAyXDAwMFwwNTRcMDAyXHVmZjc4IiArCi0gICAgIlwwMDRcdWZmNzhcMDA2XHVmZjc4XDAwN1x1ZmY3OFwwMTBcdWZmNzhcMDEyXHVmZjc4XDAxM1x1ZmY3OFwwMTQiICsKLSAgICAiXHVmZjc4XDAyMVx1ZmY3OFwwMjJcdWZmNzhcMDIzXHVmZjc4XDAyNFx1ZmY3OFwwMjVcdWZmNzhcMDI2XHVmZjc4IiArCi0gICAgIlwwMjdcdWZmNzhcMDMwXHVmZjc4XDAzMVx1ZmY3OFwwMzJcdWZmNzhcMDMzXHVmZjc4XDA0Mlx1ZmY3OFwwNDMiICsKLSAgICAiXHVmZjc4XDAwMVwwMDJcMDAwXDA1NFwwMDJcdWZmODJcMDA0XHVmZjgyXDAwNlx1ZmY4MlwwMDdcdWZmODIiICsKLSAgICAiXDAxMFx1ZmY4MlwwMTJcdWZmODJcMDEzXHVmZjgyXDAxNFx1ZmY4MlwwMjFcdWZmODJcMDIyXHVmZjgyXDAyMyIgKwotICAgICJcdWZmODJcMDI0XHVmZjgyXDAyNVx1ZmY4MlwwMjZcdWZmODJcMDI3XHVmZjgyXDAzMFx1ZmY4MlwwMzFcdWZmODIiICsKLSAgICAiXDAzMlx1ZmY4MlwwMzNcdWZmODJcMDQyXHVmZjgyXDA0M1x1ZmY4MlwwMDFcMDAyXDAwMFwwNTRcMDAyIiArCi0gICAgIlx1ZmY3OVwwMDRcdWZmNzlcMDA2XHVmZjc5XDAwN1x1ZmY3OVwwMTBcdWZmNzlcMDEyXHVmZjc5XDAxM1x1ZmY3OSIgKwotICAgICJcMDE0XHVmZjc5XDAyMVx1ZmY3OVwwMjJcdWZmNzlcMDIzXHVmZjc5XDAyNFx1ZmY3OVwwMjVcdWZmNzlcMDI2IiArCi0gICAgIlx1ZmY3OVwwMjdcdWZmNzlcMDMwXHVmZjc5XDAzMVx1ZmY3OVwwMzJcdWZmNzlcMDMzXHVmZjc5XDA0Mlx1ZmY3OSIgKwotICAgICJcMDQzXHVmZjc5XDAwMVwwMDJcMDAwXDA1NFwwMDJcdWZmN2NcMDA0XHVmZjdjXDAwNlx1ZmY3Y1wwMDciICsKLSAgICAiXHVmZjdjXDAxMFx1ZmY3Y1wwMTJcdWZmN2NcMDEzXHVmZjdjXDAxNFx1ZmY3Y1wwMjFcdWZmN2NcMDIyXHVmZjdjIiArCi0gICAgIlwwMjNcdWZmN2NcMDI0XHVmZjdjXDAyNVx1ZmY3Y1wwMjZcdWZmN2NcMDI3XHVmZjdjXDAzMFx1ZmY3Y1wwMzEiICsKLSAgICAiXHVmZjdjXDAzMlx1ZmY3Y1wwMzNcdWZmN2NcMDQyXHVmZjdjXDA0M1x1ZmY3Y1wwMDFcMDAyXDAwMFwwMTYiICsKLSAgICAiXDAwMlx1ZmY4M1wwMDRcdWZmODNcMDA2XHVmZjgzXDAxMFx1ZmY4M1wwMTFcMjUzXDAyMVx1ZmY4M1wwMDEiICsKLSAgICAiXDAwMlwwMDBcMDE0XDAwMlx1ZmZlNVwwMDRcdWZmZTVcMDA2XHVmZmU1XDAxMFx1ZmZlNVwwMjFcdWZmZTUiICsKLSAgICAiXDAwMVwwMDJcMDAwXDAxNlwwMDJcdWZmODBcMDA0XHVmZjgwXDAwNlx1ZmY4MFwwMTBcdWZmODBcMDIwIiArCi0gICAgIlwyNTJcMDIxXHVmZjgwXDAwMVwwMDJcMDAwXDAxNFwwMDJcdWZmZTZcMDA0XHVmZmU2XDAwNlx1ZmZlNiIgKwotICAgICJcMDEwXHVmZmU2XDAyMVx1ZmZlNlwwMDFcMDAyXDAwMFwwMTRcMDAyXHVmZmUxXDAwNFx1ZmZlMVwwMDYiICsKLSAgICAiXHVmZmUxXDAxMFx1ZmZlMVwwMjFcdWZmZTFcMDAxXDAwMlwwMDBcMDE0XDAwMlx1ZmZlZlwwMDRcdWZmZWYiICsKLSAgICAiXDAwNlwwNTVcMDEwXHVmZmVmXDAyMVx1ZmZlZlwwMDFcMDAyXDAwMFwwNTRcMDAyXHVmZmRkXDAwNCIgKwotICAgICJcdWZmZGRcMDA2XDA1NVwwMDdcdWZmZGRcMDEwXHVmZmRkXDAxMlx1ZmZkZFwwMTNcdWZmZGRcMDE0XHVmZmRkIiArCi0gICAgIlwwMjFcdWZmZGRcMDIyXHVmZmRkXDAyM1x1ZmZkZFwwMjRcdWZmZGRcMDI1XHVmZmRkXDAyNlx1ZmZkZFwwMjciICsKLSAgICAiXHVmZmRkXDAzMFx1ZmZkZFwwMzFcdWZmZGRcMDMyXHVmZmRkXDAzM1x1ZmZkZFwwNDJcdWZmZGRcMDQzXHVmZmRkIiArCi0gICAgIlwwMDFcMDAyXDAwMFwxMTBcMDA0XDA2MVwwMDVcMTExXDAxMVwwNzFcMDEzXDEwM1wwMTUiICsKLSAgICAiXDEzNFwwMTZcMDY2XDAxN1wxMDZcMDIxXDA3MFwwMzFcMDc1XDAzMlwwMzFcMDMzXDA0MCIgKwotICAgICJcMDM0XDA1N1wwMzVcMDM0XDAzNlwxMTNcMDM3XDE0MVwwNDBcMTQyXDA0MVwxNDVcMDQ0IiArCi0gICAgIlwwNjNcMDQ1XDA2MlwwNDZcMDY1XDA0N1wxMTVcMDUwXDEyM1wwNTFcMTM2XDA1MlwwNzciICsKLSAgICAiXDA1M1wxNDNcMDU0XDEzMVwwNTVcMTI1XDA1NlwxMTZcMDU3XDEwNFwwNjBcMTQwXDA2MSIgKwotICAgICJcMDY3XDA2MlwwNjBcMDYzXDEyN1wwNjRcMTMyXDA2NVwwNzJcMDAxXDAwMlwwMDBcMDEyIiArCi0gICAgIlwwMDJcdWZmZWVcMDA0XHVmZmVlXDAxMFx1ZmZlZVwwMjFcdWZmZWVcMDAxXDAwMlwwMDBcMDU0XDAwMiIgKwotICAgICJcdWZmOWFcMDA0XHVmZjlhXDAwNlx1ZmY5YVwwMDdcdWZmOWFcMDEwXHVmZjlhXDAxMlx1ZmY5YVwwMTNcdWZmOWEiICsKLSAgICAiXDAxNFx1ZmY5YVwwMjFcdWZmOWFcMDIyXHVmZjlhXDAyM1x1ZmY5YVwwMjRcdWZmOWFcMDI1XHVmZjlhXDAyNiIgKwotICAgICJcdWZmOWFcMDI3XHVmZjlhXDAzMFx1ZmY5YVwwMzFcdWZmOWFcMDMyXHVmZjlhXDAzM1x1ZmY5YVwwNDJcdWZmOWEiICsKLSAgICAiXDA0M1x1ZmY5YVwwMDFcMDAyXDAwMFwwNjBcMDAyXHVmZjdhXDAwNFx1ZmY3YVwwMDZcdWZmN2FcMDA3IiArCi0gICAgIlx1ZmY3YVwwMTBcdWZmN2FcMDExXHVmZjdhXDAxMlx1ZmY3YVwwMTNcdWZmN2FcMDE0XHVmZjdhXDAyMFx1ZmZhNSIgKwotICAgICJcMDIxXHVmZjdhXDAyMlx1ZmY3YVwwMjNcdWZmN2FcMDI0XHVmZjdhXDAyNVx1ZmY3YVwwMjZcdWZmN2FcMDI3IiArCi0gICAgIlx1ZmY3YVwwMzBcdWZmN2FcMDMxXHVmZjdhXDAzMlx1ZmY3YVwwMzNcdWZmN2FcMDQyXHVmZjdhXDA0M1x1ZmY3YSIgKwotICAgICJcMDAxXDAwMlwwMDBcMTI2XDAwMlx1ZmZiOVwwMDVcMTExXDAwN1x1ZmZiOVwwMTBcdWZmYjlcMDEyIiArCi0gICAgIlx1ZmZiOVwwMTNcMTAzXDAxNFx1ZmZiOVwwMTZcMDY2XDAxN1wxMDZcMDIyXHVmZmI5XDAyM1x1ZmZiOSIgKwotICAgICJcMDI0XHVmZmI5XDAyNVx1ZmZiOVwwMjZcdWZmYjlcMDI3XHVmZmI5XDAzMFx1ZmZiOVwwMzFcdWZmYjlcMDMyIiArCi0gICAgIlwwMzFcMDMzXDA0MFwwMzVcMDM0XDAzNlwxMTNcMDM3XDE0MVwwNDBcMTQyXDA0MVwxNDUiICsKLSAgICAiXDA0Mlx1ZmZiOVwwNDNcdWZmYjlcMDQ0XDA2M1wwNDVcMDYyXDA0NlwwNjVcMDQ3XDExNVwwNTAiICsKLSAgICAiXDEyM1wwNTFcMTM2XDA1MlwwNzdcMDUzXDE0M1wwNTRcMTMxXDA1NVwxMjVcMDU2XDExNiIgKwotICAgICJcMDU3XDEwNFwwNjBcMTQwXDA2MVwwNjdcMDYyXDA2MFwwNjNcMTI3XDAwMVwwMDJcMDAwIiArCi0gICAgIlwwNTRcMDAyXHVmZjg5XDAwNFx1ZmY4OVwwMDZcdWZmODlcMDA3XHVmZjg5XDAxMFx1ZmY4OVwwMTJcdWZmODkiICsKLSAgICAiXDAxM1x1ZmY4OVwwMTRcdWZmODlcMDIxXHVmZjg5XDAyMlx1ZmY4OVwwMjNcdWZmODlcMDI0XHVmZjg5XDAyNSIgKwotICAgICJcdWZmODlcMDI2XHVmZjg5XDAyN1x1ZmY4OVwwMzBcdWZmODlcMDMxXHVmZjg5XDAzMlx1ZmY4OVwwMzNcdWZmODkiICsKLSAgICAiXDA0Mlx1ZmY4OVwwNDNcdWZmODlcMDAxXDAwMlwwMDBcMDU0XDAwMlx1ZmY4YlwwMDRcdWZmOGJcMDA2IiArCi0gICAgIlx1ZmY4YlwwMDdcdWZmOGJcMDEwXHVmZjhiXDAxMlx1ZmY4YlwwMTNcdWZmOGJcMDE0XHVmZjhiXDAyMVx1ZmY4YiIgKwotICAgICJcMDIyXHVmZjhiXDAyM1x1ZmY4YlwwMjRcdWZmOGJcMDI1XHVmZjhiXDAyNlx1ZmY4YlwwMjdcdWZmOGJcMDMwIiArCi0gICAgIlx1ZmY4YlwwMzFcdWZmOGJcMDMyXHVmZjhiXDAzM1x1ZmY4YlwwNDJcdWZmOGJcMDQzXHVmZjhiXDAwMVwwMDIiICsKLSAgICAiXDAwMFwwMzJcMDAyXHVmZmQ1XDAwN1x1ZmZkNVwwMTJcdWZmZDVcMDE0XHVmZmQ1XDAyMlx1ZmZkNVwwMjMiICsKLSAgICAiXHVmZmQ1XDAyNFwyMjFcMDI1XDIyMlwwMjZcMjIzXDAyN1wyMjRcMDQyXHVmZmQ1XDA0M1x1ZmZkNSIgKwotICAgICJcMDAxXDAwMlwwMDBcMDA0XDAxMVwyNDVcMDAxXDAwMlwwMDBcMDYyXDAxM1x1ZmZhZVwwMzIiICsKLSAgICAiXHVmZmFlXDAzM1x1ZmZhZVwwMzVcdWZmYWVcMDM2XHVmZmFlXDAzN1x1ZmZhZVwwNDBcdWZmYWVcMDQxXHVmZmFlIiArCi0gICAgIlwwNDRcdWZmYWVcMDQ1XHVmZmFlXDA0Nlx1ZmZhZVwwNDdcdWZmYWVcMDUwXHVmZmFlXDA1MVx1ZmZhZVwwNTIiICsKLSAgICAiXHVmZmFlXDA1M1x1ZmZhZVwwNTRcdWZmYWVcMDU1XHVmZmFlXDA1Nlx1ZmZhZVwwNTdcdWZmYWVcMDYwXHVmZmFlIiArCi0gICAgIlwwNjFcdWZmYWVcMDYyXHVmZmFlXDA2M1x1ZmZhZVwwMDFcMDAyXDAwMFwwNjBcMDAyXHVmZjdiXDAwNCIgKwotICAgICJcdWZmN2JcMDA2XHVmZjdiXDAwN1x1ZmY3YlwwMTBcdWZmN2JcMDExXHVmZjdiXDAxMlx1ZmY3YlwwMTNcdWZmN2IiICsKLSAgICAiXDAxNFx1ZmY3YlwwMjBcdWZmYTZcMDIxXHVmZjdiXDAyMlx1ZmY3YlwwMjNcdWZmN2JcMDI0XHVmZjdiXDAyNSIgKwotICAgICJcdWZmN2JcMDI2XHVmZjdiXDAyN1x1ZmY3YlwwMzBcdWZmN2JcMDMxXHVmZjdiXDAzMlx1ZmY3YlwwMzNcdWZmN2IiICsKLSAgICAiXDA0Mlx1ZmY3YlwwNDNcdWZmN2JcMDAxXDAwMlwwMDBcMDcwXDAwNVwxMTFcMDEzXDEwM1wwMTYiICsKLSAgICAiXDA2NlwwMTdcMTA2XDAzMlwwMzFcMDMzXDA0MFwwMzVcMDM0XDAzNlwxMTNcMDM3XDE0MSIgKwotICAgICJcMDQwXDE0MlwwNDFcMTQ1XDA0NFwwNjNcMDQ1XDA2MlwwNDZcMDY1XDA0N1wxMTVcMDUwIiArCi0gICAgIlwxMjNcMDUxXDEzNlwwNTJcMDc3XDA1M1wxNDNcMDU0XDEzMVwwNTVcMTI1XDA1NlwxMTYiICsKLSAgICAiXDA1N1wxMDRcMDYwXDE0MFwwNjFcMDY3XDA2MlwwNjBcMDYzXDEyN1wwMDFcMDAyXDAwMCIgKwotICAgICJcMTEwXDAwNFwwNjFcMDA1XDExMVwwMTFcMDcxXDAxM1wxMDNcMDE1XDEzNFwwMTZcMDY2IiArCi0gICAgIlwwMTdcMTA2XDAyMVwwNzBcMDMxXDA3NVwwMzJcMDMxXDAzM1wwNDBcMDM0XDA1N1wwMzUiICsKLSAgICAiXDAzNFwwMzZcMTEzXDAzN1wxNDFcMDQwXDE0MlwwNDFcMTQ1XDA0NFwwNjNcMDQ1XDA2MiIgKwotICAgICJcMDQ2XDA2NVwwNDdcMTE1XDA1MFwxMjNcMDUxXDEzNlwwNTJcMDc3XDA1M1wxNDNcMDU0IiArCi0gICAgIlwxMzFcMDU1XDEyNVwwNTZcMTE2XDA1N1wxMDRcMDYwXDE0MFwwNjFcMDY3XDA2MlwwNjAiICsKLSAgICAiXDA2M1wxMjdcMDY0XDEzMlwwNjVcMDcyXDAwMVwwMDJcMDAwXDA1NFwwMDJcdWZmOTlcMDA0IiArCi0gICAgIlx1ZmY5OVwwMDZcdWZmOTlcMDA3XHVmZjk5XDAxMFx1ZmY5OVwwMTJcdWZmOTlcMDEzXHVmZjk5XDAxNFx1ZmY5OSIgKwotICAgICJcMDIxXHVmZjk5XDAyMlx1ZmY5OVwwMjNcdWZmOTlcMDI0XHVmZjk5XDAyNVx1ZmY5OVwwMjZcdWZmOTlcMDI3IiArCi0gICAgIlx1ZmY5OVwwMzBcdWZmOTlcMDMxXHVmZjk5XDAzMlx1ZmY5OVwwMzNcdWZmOTlcMDQyXHVmZjk5XDA0M1x1ZmY5OSIgKwotICAgICJcMDAxXDAwMlwwMDBcMDQ2XDAwMlx1ZmZiN1wwMDdcdWZmYjdcMDEwXHVmZmI3XDAxMlx1ZmZiN1wwMTMiICsKLSAgICAiXHVmZmI3XDAxNFx1ZmZiN1wwMjJcdWZmYjdcMDIzXHVmZmI3XDAyNFx1ZmZiN1wwMjVcdWZmYjdcMDI2XHVmZmI3IiArCi0gICAgIlwwMjdcdWZmYjdcMDMwXHVmZmI3XDAzMVx1ZmZiN1wwMzJcdWZmYjdcMDMzXHVmZmI3XDA0Mlx1ZmZiN1wwNDMiICsKLSAgICAiXHVmZmI3XDAwMVwwMDJcMDAwXDA1NFwwMDJcdWZmOTdcMDA0XHVmZjk3XDAwNlx1ZmY5N1wwMDdcdWZmOTciICsKLSAgICAiXDAxMFx1ZmY5N1wwMTJcdWZmOTdcMDEzXHVmZjk3XDAxNFx1ZmY5N1wwMjFcdWZmOTdcMDIyXHVmZjk3XDAyMyIgKwotICAgICJcdWZmOTdcMDI0XHVmZjk3XDAyNVx1ZmY5N1wwMjZcdWZmOTdcMDI3XHVmZjk3XDAzMFx1ZmY5N1wwMzFcdWZmOTciICsKLSAgICAiXDAzMlx1ZmY5N1wwMzNcdWZmOTdcMDQyXHVmZjk3XDA0M1x1ZmY5N1wwMDFcMDAyXDAwMFwxMTBcMDA0IiArCi0gICAgIlwwNjFcMDA1XDExMVwwMTFcMDcxXDAxM1wxMDNcMDE1XDEzNFwwMTZcMDY2XDAxN1wxMDYiICsKLSAgICAiXDAyMVwwNzBcMDMxXDA3NVwwMzJcMDMxXDAzM1wwNDBcMDM0XDA1N1wwMzVcMDM0XDAzNiIgKwotICAgICJcMTEzXDAzN1wxNDFcMDQwXDE0MlwwNDFcMTQ1XDA0NFwwNjNcMDQ1XDA2MlwwNDZcMDY1IiArCi0gICAgIlwwNDdcMTE1XDA1MFwxMjNcMDUxXDEzNlwwNTJcMDc3XDA1M1wxNDNcMDU0XDEzMVwwNTUiICsKLSAgICAiXDEyNVwwNTZcMTE2XDA1N1wxMDRcMDYwXDE0MFwwNjFcMDY3XDA2MlwwNjBcMDYzXDEyNyIgKwotICAgICJcMDY0XDEzMlwwNjVcMDcyXDAwMVwwMDJcMDAwXDAxNlwwMDJcdWZmZDlcMDA3XHVmZmQ5XDAxMiIgKwotICAgICJcdWZmZDlcMDE0XHVmZmQ5XDA0Mlx1ZmZkOVwwNDNcMjM0XDAwMVwwMDJcMDAwXDA2MFwwMDJcdWZmN2YiICsKLSAgICAiXDAwNFx1ZmY3ZlwwMDZcdWZmN2ZcMDA3XHVmZjdmXDAxMFx1ZmY3ZlwwMTFcdWZmN2ZcMDEyXHVmZjdmXDAxMyIgKwotICAgICJcdWZmN2ZcMDE0XHVmZjdmXDAyMFx1ZmZhYVwwMjFcdWZmN2ZcMDIyXHVmZjdmXDAyM1x1ZmY3ZlwwMjRcdWZmN2YiICsKLSAgICAiXDAyNVx1ZmY3ZlwwMjZcdWZmN2ZcMDI3XHVmZjdmXDAzMFx1ZmY3ZlwwMzFcdWZmN2ZcMDMyXHVmZjdmXDAzMyIgKwotICAgICJcdWZmN2ZcMDQyXHVmZjdmXDA0M1x1ZmY3ZlwwMDFcMDAyXDAwMFwwNjJcMDEzXDEwM1wwMzJcMDMxIiArCi0gICAgIlwwMzNcMDQwXDAzNVwwMzRcMDM2XDExM1wwMzdcMTQxXDA0MFwxNDJcMDQxXDE0NVwwNDQiICsKLSAgICAiXDA2M1wwNDVcMDYyXDA0NlwwNjVcMDQ3XDAzNlwwNTBcMDM3XDA1MVwwNDRcMDUyXDE3MCIgKwotICAgICJcMDUzXDE2NlwwNTRcMDQzXDA1NVwwNDFcMDU2XDAzNVwwNTdcMDMwXDA2MFwwNDVcMDYxIiArCi0gICAgIlwwMjFcMDYyXDAxMlwwNjNcMDQyXDAwMVwwMDJcMDAwXDAwNFwwMjBcMjM2XDAwMVwwMDIiICsKLSAgICAiXDAwMFwwMTRcMDAyXHVmZmRhXDAwN1x1ZmZkYVwwMTJcdWZmZGFcMDE0XHVmZmRhXDA0MlwyMzJcMDAxIiArCi0gICAgIlwwMDJcMDAwXDA1NFwwMDJcdWZmODhcMDA0XHVmZjg4XDAwNlx1ZmY4OFwwMDdcdWZmODhcMDEwXHVmZjg4IiArCi0gICAgIlwwMTJcdWZmODhcMDEzXHVmZjg4XDAxNFx1ZmY4OFwwMjFcdWZmODhcMDIyXHVmZjg4XDAyM1x1ZmY4OFwwMjQiICsKLSAgICAiXHVmZjg4XDAyNVx1ZmY4OFwwMjZcdWZmODhcMDI3XHVmZjg4XDAzMFx1ZmY4OFwwMzFcdWZmODhcMDMyXHVmZjg4IiArCi0gICAgIlwwMzNcdWZmODhcMDQyXHVmZjg4XDA0M1x1ZmY4OFwwMDFcMDAyXDAwMFwwNjBcMDAyXHVmZjdkXDAwNCIgKwotICAgICJcdWZmN2RcMDA2XHVmZjdkXDAwN1x1ZmY3ZFwwMTBcdWZmN2RcMDExXHVmZjdkXDAxMlx1ZmY3ZFwwMTNcdWZmN2QiICsKLSAgICAiXDAxNFx1ZmY3ZFwwMjBcdWZmYThcMDIxXHVmZjdkXDAyMlx1ZmY3ZFwwMjNcdWZmN2RcMDI0XHVmZjdkXDAyNSIgKwotICAgICJcdWZmN2RcMDI2XHVmZjdkXDAyN1x1ZmY3ZFwwMzBcdWZmN2RcMDMxXHVmZjdkXDAzMlx1ZmY3ZFwwMzNcdWZmN2QiICsKLSAgICAiXDA0Mlx1ZmY3ZFwwNDNcdWZmN2RcMDAxXDAwMlwwMDBcMDIyXDAwMlx1ZmZkN1wwMDdcdWZmZDdcMDEyIiArCi0gICAgIlx1ZmZkN1wwMTRcdWZmZDdcMDIyXDIxNlwwMjNcMjE3XDA0Mlx1ZmZkN1wwNDNcdWZmZDdcMDAxXDAwMiIgKwotICAgICJcMDAwXDA1MlwwMDJcdWZmOWZcMDA0XHVmZjlmXDAwN1x1ZmY5ZlwwMTBcdWZmOWZcMDEyXHVmZjlmXDAxMyIgKwotICAgICJcdWZmOWZcMDE0XHVmZjlmXDAyMVx1ZmY5ZlwwMjJcdWZmOWZcMDIzXHVmZjlmXDAyNFx1ZmY5ZlwwMjVcdWZmOWYiICsKLSAgICAiXDAyNlx1ZmY5ZlwwMjdcdWZmOWZcMDMwXHVmZjlmXDAzMVx1ZmY5ZlwwMzJcdWZmOWZcMDMzXHVmZjlmXDA0MiIgKwotICAgICJcdWZmOWZcMDQzXHVmZjlmXDAwMVwwMDJcMDAwXDA1NFwwMDJcdWZmYjRcMDA0XHVmZmI0XDAwNlwwNTUiICsKLSAgICAiXDAwN1x1ZmZiNFwwMTBcdWZmYjRcMDEyXHVmZmI0XDAxM1x1ZmZiNFwwMTRcdWZmYjRcMDIxXHVmZmI0XDAyMiIgKwotICAgICJcdWZmYjRcMDIzXHVmZmI0XDAyNFx1ZmZiNFwwMjVcdWZmYjRcMDI2XHVmZmI0XDAyN1x1ZmZiNFwwMzBcdWZmYjQiICsKLSAgICAiXDAzMVx1ZmZiNFwwMzJcdWZmYjRcMDMzXHVmZmI0XDA0Mlx1ZmZiNFwwNDNcdWZmYjRcMDAxXDAwMlwwMDAiICsKLSAgICAiXDA0NlwwMDJcdWZmYmRcMDA3XHVmZmJkXDAxMFx1ZmZiZFwwMTJcdWZmYmRcMDEzXHVmZmJkXDAxNFx1ZmZiZCIgKwotICAgICJcMDIyXHVmZmJkXDAyM1x1ZmZiZFwwMjRcdWZmYmRcMDI1XHVmZmJkXDAyNlx1ZmZiZFwwMjdcdWZmYmRcMDMwIiArCi0gICAgIlx1ZmZiZFwwMzFcdWZmYmRcMDMyXHVmZmJkXDAzM1x1ZmZiZFwwNDJcdWZmYmRcMDQzXHVmZmJkXDAwMVwwMDIiICsKLSAgICAiXDAwMFwwNTJcMDAyXHVmZmEwXDAwNFx1ZmZhMFwwMDdcdWZmYTBcMDEwXHVmZmEwXDAxMlx1ZmZhMFwwMTMiICsKLSAgICAiXHVmZmEwXDAxNFx1ZmZhMFwwMjFcdWZmYTBcMDIyXHVmZmEwXDAyM1x1ZmZhMFwwMjRcdWZmYTBcMDI1XHVmZmEwIiArCi0gICAgIlwwMjZcdWZmYTBcMDI3XHVmZmEwXDAzMFx1ZmZhMFwwMzFcdWZmYTBcMDMyXHVmZmEwXDAzM1x1ZmZhMFwwNDIiICsKLSAgICAiXHVmZmEwXDA0M1x1ZmZhMFwwMDFcMDAyXDAwMFwwMzZcMDAyXHVmZmQyXDAwN1x1ZmZkMlwwMTJcdWZmZDIiICsKLSAgICAiXDAxNFx1ZmZkMlwwMjJcdWZmZDJcMDIzXHVmZmQyXDAyNFx1ZmZkMlwwMjVcdWZmZDJcMDI2XHVmZmQyXDAyNyIgKwotICAgICJcdWZmZDJcMDMwXDIxMVwwMzFcMjEyXDA0Mlx1ZmZkMlwwNDNcdWZmZDJcMDAxXDAwMlwwMDBcMDU2IiArCi0gICAgIlwwMDJcdWZmNzVcMDA0XHVmZjc1XDAwNlx1ZmY3NVwwMDdcdWZmNzVcMDEwXHVmZjc1XDAxMVx1ZmY3NVwwMTIiICsKLSAgICAiXHVmZjc1XDAxM1x1ZmY3NVwwMTRcdWZmNzVcMDIxXHVmZjc1XDAyMlx1ZmY3NVwwMjNcdWZmNzVcMDI0XHVmZjc1IiArCi0gICAgIlwwMjVcdWZmNzVcMDI2XHVmZjc1XDAyN1x1ZmY3NVwwMzBcdWZmNzVcMDMxXHVmZjc1XDAzMlx1ZmY3NVwwMzMiICsKLSAgICAiXHVmZjc1XDA0Mlx1ZmY3NVwwNDNcdWZmNzVcMDAxXDAwMlwwMDBcMDQ0XDAwMlx1ZmZjYVwwMDdcdWZmY2EiICsKLSAgICAiXDAxMlx1ZmZjYVwwMTNcdWZmY2FcMDE0XHVmZmNhXDAyMlx1ZmZjYVwwMjNcdWZmY2FcMDI0XHVmZmNhXDAyNSIgKwotICAgICJcdWZmY2FcMDI2XHVmZmNhXDAyN1x1ZmZjYVwwMzBcdWZmY2FcMDMxXHVmZmNhXDAzMlx1ZmZjYVwwMzNcdWZmY2EiICsKLSAgICAiXDA0Mlx1ZmZjYVwwNDNcdWZmY2FcMDAxXDAwMlwwMDBcMDYwXDAwMlx1ZmY3N1wwMDRcdWZmNzdcMDA2IiArCi0gICAgIlx1ZmY3N1wwMDdcdWZmNzdcMDEwXHVmZjc3XDAxMVx1ZmY3N1wwMTJcdWZmNzdcMDEzXHVmZjc3XDAxNFx1ZmY3NyIgKwotICAgICJcMDIwXHVmZmEyXDAyMVx1ZmY3N1wwMjJcdWZmNzdcMDIzXHVmZjc3XDAyNFx1ZmY3N1wwMjVcdWZmNzdcMDI2IiArCi0gICAgIlx1ZmY3N1wwMjdcdWZmNzdcMDMwXHVmZjc3XDAzMVx1ZmY3N1wwMzJcdWZmNzdcMDMzXHVmZjc3XDA0Mlx1ZmY3NyIgKwotICAgICJcMDQzXHVmZjc3XDAwMVwwMDJcMDAwXDA2MFwwMDJcdWZmN2VcMDA0XHVmZjdlXDAwNlx1ZmY3ZVwwMDciICsKLSAgICAiXHVmZjdlXDAxMFx1ZmY3ZVwwMTFcdWZmN2VcMDEyXHVmZjdlXDAxM1x1ZmY3ZVwwMTRcdWZmN2VcMDIwXHVmZmE5IiArCi0gICAgIlwwMjFcdWZmN2VcMDIyXHVmZjdlXDAyM1x1ZmY3ZVwwMjRcdWZmN2VcMDI1XHVmZjdlXDAyNlx1ZmY3ZVwwMjciICsKLSAgICAiXHVmZjdlXDAzMFx1ZmY3ZVwwMzFcdWZmN2VcMDMyXHVmZjdlXDAzM1x1ZmY3ZVwwNDJcdWZmN2VcMDQzXHVmZjdlIiArCi0gICAgIlwwMDFcMDAyXDAwMFwwMDRcMDExXDIwMVwwMDFcMDAyXDAwMFwwNTJcMDAyXHVmZmJjXDAwNCIgKwotICAgICJcdWZmYmNcMDA3XHVmZmJjXDAxMFx1ZmZiY1wwMTJcdWZmYmNcMDEzXHVmZmJjXDAxNFx1ZmZiY1wwMjFcdWZmYmMiICsKLSAgICAiXDAyMlx1ZmZiY1wwMjNcdWZmYmNcMDI0XHVmZmJjXDAyNVx1ZmZiY1wwMjZcdWZmYmNcMDI3XHVmZmJjXDAzMCIgKwotICAgICJcdWZmYmNcMDMxXHVmZmJjXDAzMlx1ZmZiY1wwMzNcdWZmYmNcMDQyXHVmZmJjXDA0M1x1ZmZiY1wwMDFcMDAyIiArCi0gICAgIlwwMDBcMDQ2XDAwMlx1ZmZjMlwwMDdcdWZmYzJcMDEwXHVmZmMyXDAxMlx1ZmZjMlwwMTNcdWZmYzJcMDE0IiArCi0gICAgIlx1ZmZjMlwwMjJcdWZmYzJcMDIzXHVmZmMyXDAyNFx1ZmZjMlwwMjVcdWZmYzJcMDI2XHVmZmMyXDAyN1x1ZmZjMiIgKwotICAgICJcMDMwXHVmZmMyXDAzMVx1ZmZjMlwwMzJcdWZmYzJcMDMzXHVmZmMyXDA0Mlx1ZmZjMlwwNDNcdWZmYzJcMDAxIiArCi0gICAgIlwwMDJcMDAwXDA1NFwwMDJcdWZmOWVcMDA0XHVmZjllXDAwNlwwNTVcMDA3XHVmZjllXDAxMFx1ZmY5ZSIgKwotICAgICJcMDEyXHVmZjllXDAxM1x1ZmY5ZVwwMTRcdWZmOWVcMDIxXHVmZjllXDAyMlx1ZmY5ZVwwMjNcdWZmOWVcMDI0IiArCi0gICAgIlx1ZmY5ZVwwMjVcdWZmOWVcMDI2XHVmZjllXDAyN1x1ZmY5ZVwwMzBcdWZmOWVcMDMxXHVmZjllXDAzMlx1ZmY5ZSIgKwotICAgICJcMDMzXHVmZjllXDA0Mlx1ZmY5ZVwwNDNcdWZmOWVcMDAxXDAwMlwwMDBcMDYwXDAwMlx1ZmY3NlwwMDQiICsKLSAgICAiXHVmZjc2XDAwNlx1ZmY3NlwwMDdcdWZmNzZcMDEwXHVmZjc2XDAxMVx1ZmY3NlwwMTJcdWZmNzZcMDEzXHVmZjc2IiArCi0gICAgIlwwMTRcdWZmNzZcMDIwXHVmZmExXDAyMVx1ZmY3NlwwMjJcdWZmNzZcMDIzXHVmZjc2XDAyNFx1ZmY3NlwwMjUiICsKLSAgICAiXHVmZjc2XDAyNlx1ZmY3NlwwMjdcdWZmNzZcMDMwXHVmZjc2XDAzMVx1ZmY3NlwwMzJcdWZmNzZcMDMzXHVmZjc2IiArCi0gICAgIlwwNDJcdWZmNzZcMDQzXHVmZjc2XDAwMVwwMDJcMDAwXDA0NlwwMDJcdWZmYzRcMDA3XHVmZmM0XDAxMCIgKwotICAgICJcMTc2XDAxMlx1ZmZjNFwwMTNcdWZmYzRcMDE0XHVmZmM0XDAyMlx1ZmZjNFwwMjNcdWZmYzRcMDI0XHVmZmM0IiArCi0gICAgIlwwMjVcdWZmYzRcMDI2XHVmZmM0XDAyN1x1ZmZjNFwwMzBcdWZmYzRcMDMxXHVmZmM0XDAzMlx1ZmZjNFwwMzMiICsKLSAgICAiXHVmZmM0XDA0Mlx1ZmZjNFwwNDNcdWZmYzRcMDAxXDAwMlwwMDBcMDYwXDAwMlx1ZmY4MVwwMDRcdWZmODEiICsKLSAgICAiXDAwNlx1ZmY4MVwwMDdcdWZmODFcMDEwXHVmZjgxXDAxMVx1ZmY4MVwwMTJcdWZmODFcMDEzXHVmZjgxXDAxNCIgKwotICAgICJcdWZmODFcMDIwXHVmZmFjXDAyMVx1ZmY4MVwwMjJcdWZmODFcMDIzXHVmZjgxXDAyNFx1ZmY4MVwwMjVcdWZmODEiICsKLSAgICAiXDAyNlx1ZmY4MVwwMjdcdWZmODFcMDMwXHVmZjgxXDAzMVx1ZmY4MVwwMzJcdWZmODFcMDMzXHVmZjgxXDA0MiIgKwotICAgICJcdWZmODFcMDQzXHVmZjgxXDAwMVwwMDJcMDAwXDA1NFwwMDJcdWZmOWNcMDA0XHVmZjljXDAwNlx1ZmY5YyIgKwotICAgICJcMDA3XHVmZjljXDAxMFx1ZmY5Y1wwMTJcdWZmOWNcMDEzXHVmZjljXDAxNFx1ZmY5Y1wwMjFcdWZmOWNcMDIyIiArCi0gICAgIlx1ZmY5Y1wwMjNcdWZmOWNcMDI0XHVmZjljXDAyNVx1ZmY5Y1wwMjZcdWZmOWNcMDI3XHVmZjljXDAzMFx1ZmY5YyIgKwotICAgICJcMDMxXHVmZjljXDAzMlx1ZmY5Y1wwMzNcdWZmOWNcMDQyXHVmZjljXDA0M1x1ZmY5Y1wwMDFcMDAyXDAwMCIgKwotICAgICJcMDYwXDAwMlx1ZmY3OFwwMDRcdWZmNzhcMDA2XHVmZjc4XDAwN1x1ZmY3OFwwMTBcdWZmNzhcMDExXHVmZjc4IiArCi0gICAgIlwwMTJcdWZmNzhcMDEzXHVmZjc4XDAxNFx1ZmY3OFwwMjBcdWZmYTNcMDIxXHVmZjc4XDAyMlx1ZmY3OFwwMjMiICsKLSAgICAiXHVmZjc4XDAyNFx1ZmY3OFwwMjVcdWZmNzhcMDI2XHVmZjc4XDAyN1x1ZmY3OFwwMzBcdWZmNzhcMDMxXHVmZjc4IiArCi0gICAgIlwwMzJcdWZmNzhcMDMzXHVmZjc4XDA0Mlx1ZmY3OFwwNDNcdWZmNzhcMDAxXDAwMlwwMDBcMDUyXDAwMiIgKwotICAgICJcdWZmYzFcMDA0XDE3M1wwMDdcdWZmYzFcMDEwXHVmZmMxXDAxMlx1ZmZjMVwwMTNcdWZmYzFcMDE0XHVmZmMxIiArCi0gICAgIlwwMjFcMTcyXDAyMlx1ZmZjMVwwMjNcdWZmYzFcMDI0XHVmZmMxXDAyNVx1ZmZjMVwwMjZcdWZmYzFcMDI3IiArCi0gICAgIlx1ZmZjMVwwMzBcdWZmYzFcMDMxXHVmZmMxXDAzMlx1ZmZjMVwwMzNcdWZmYzFcMDQyXHVmZmMxXDA0M1x1ZmZjMSIgKwotICAgICJcMDAxXDAwMlwwMDBcMDYwXDAwMlx1ZmY4MlwwMDRcdWZmODJcMDA2XHVmZjgyXDAwN1x1ZmY4MlwwMTAiICsKLSAgICAiXHVmZjgyXDAxMVx1ZmY4MlwwMTJcdWZmODJcMDEzXHVmZjgyXDAxNFx1ZmY4MlwwMjBcdWZmYWRcMDIxXHVmZjgyIiArCi0gICAgIlwwMjJcdWZmODJcMDIzXHVmZjgyXDAyNFx1ZmY4MlwwMjVcdWZmODJcMDI2XHVmZjgyXDAyN1x1ZmY4MlwwMzAiICsKLSAgICAiXHVmZjgyXDAzMVx1ZmY4MlwwMzJcdWZmODJcMDMzXHVmZjgyXDA0Mlx1ZmY4MlwwNDNcdWZmODJcMDAxXDAwMiIgKwotICAgICJcMDAwXDA1NFwwMDJcdWZmOThcMDA0XHVmZjk4XDAwNlx1ZmY5OFwwMDdcdWZmOThcMDEwXHVmZjk4XDAxMiIgKwotICAgICJcdWZmOThcMDEzXHVmZjk4XDAxNFx1ZmY5OFwwMjFcdWZmOThcMDIyXHVmZjk4XDAyM1x1ZmY5OFwwMjRcdWZmOTgiICsKLSAgICAiXDAyNVx1ZmY5OFwwMjZcdWZmOThcMDI3XHVmZjk4XDAzMFx1ZmY5OFwwMzFcdWZmOThcMDMyXHVmZjk4XDAzMyIgKwotICAgICJcdWZmOThcMDQyXHVmZjk4XDA0M1x1ZmY5OFwwMDFcMDAyXDAwMFwwMDRcMDA3XDE3MVwwMDFcMDAyIiArCi0gICAgIlwwMDBcMDQ2XDAzMlwwMzFcMDMzXDA0MFwwMzVcMDM0XDAzNlwxMTNcMDM3XDE0MVwwNDciICsKLSAgICAiXDAzNlwwNTBcMDM3XDA1MVwwNDRcMDUyXDE3MFwwNTNcMTY2XDA1NFwwNDNcMDU1XDA0MSIgKwotICAgICJcMDU2XDAzNVwwNTdcMDMwXDA2MFwwNDVcMDYxXDAyMVwwNjJcMDEyXDA2M1wwNDJcMDAxIiArCi0gICAgIlwwMDJcMDAwXDA1MlwwMDJcdWZmYmFcMDA0XHVmZmJhXDAwN1x1ZmZiYVwwMTBcdWZmYmFcMDEyXHVmZmJhIiArCi0gICAgIlwwMTNcdWZmYmFcMDE0XHVmZmJhXDAyMVx1ZmZiYVwwMjJcdWZmYmFcMDIzXHVmZmJhXDAyNFx1ZmZiYVwwMjUiICsKLSAgICAiXHVmZmJhXDAyNlx1ZmZiYVwwMjdcdWZmYmFcMDMwXHVmZmJhXDAzMVx1ZmZiYVwwMzJcdWZmYmFcMDMzXHVmZmJhIiArCi0gICAgIlwwNDJcdWZmYmFcMDQzXHVmZmJhXDAwMVwwMDJcMDAwXDA2MFwwMDJcdWZmNzlcMDA0XHVmZjc5XDAwNiIgKwotICAgICJcdWZmNzlcMDA3XHVmZjc5XDAxMFx1ZmY3OVwwMTFcdWZmNzlcMDEyXHVmZjc5XDAxM1x1ZmY3OVwwMTRcdWZmNzkiICsKLSAgICAiXDAyMFx1ZmZhNFwwMjFcdWZmNzlcMDIyXHVmZjc5XDAyM1x1ZmY3OVwwMjRcdWZmNzlcMDI1XHVmZjc5XDAyNiIgKwotICAgICJcdWZmNzlcMDI3XHVmZjc5XDAzMFx1ZmY3OVwwMzFcdWZmNzlcMDMyXHVmZjc5XDAzM1x1ZmY3OVwwNDJcdWZmNzkiICsKLSAgICAiXDA0M1x1ZmY3OVwwMDFcMDAyXDAwMFwwNTJcMDAyXHVmZmIwXDAwNFx1ZmZiMFwwMDdcdWZmYjBcMDEwIiArCi0gICAgIlx1ZmZiMFwwMTJcdWZmYjBcMDEzXHVmZmIwXDAxNFx1ZmZiMFwwMjFcdWZmYjBcMDIyXHVmZmIwXDAyM1x1ZmZiMCIgKwotICAgICJcMDI0XHVmZmIwXDAyNVx1ZmZiMFwwMjZcdWZmYjBcMDI3XHVmZmIwXDAzMFx1ZmZiMFwwMzFcdWZmYjBcMDMyIiArCi0gICAgIlx1ZmZiMFwwMzNcdWZmYjBcMDQyXHVmZmIwXDA0M1x1ZmZiMFwwMDFcMDAyXDAwMFwwNjBcMDAyXHVmZjdjIiArCi0gICAgIlwwMDRcdWZmN2NcMDA2XHVmZjdjXDAwN1x1ZmY3Y1wwMTBcdWZmN2NcMDExXHVmZjdjXDAxMlx1ZmY3Y1wwMTMiICsKLSAgICAiXHVmZjdjXDAxNFx1ZmY3Y1wwMjBcdWZmYTdcMDIxXHVmZjdjXDAyMlx1ZmY3Y1wwMjNcdWZmN2NcMDI0XHVmZjdjIiArCi0gICAgIlwwMjVcdWZmN2NcMDI2XHVmZjdjXDAyN1x1ZmY3Y1wwMzBcdWZmN2NcMDMxXHVmZjdjXDAzMlx1ZmY3Y1wwMzMiICsKLSAgICAiXHVmZjdjXDA0Mlx1ZmY3Y1wwNDNcdWZmN2NcMDAxXDAwMlwwMDBcMDU2XDAwMlx1ZmY4M1wwMDRcdWZmODMiICsKLSAgICAiXDAwNlx1ZmY4M1wwMDdcdWZmODNcMDEwXHVmZjgzXDAxMVx1ZmY4M1wwMTJcdWZmODNcMDEzXHVmZjgzXDAxNCIgKwotICAgICJcdWZmODNcMDIxXHVmZjgzXDAyMlx1ZmY4M1wwMjNcdWZmODNcMDI0XHVmZjgzXDAyNVx1ZmY4M1wwMjZcdWZmODMiICsKLSAgICAiXDAyN1x1ZmY4M1wwMzBcdWZmODNcMDMxXHVmZjgzXDAzMlx1ZmY4M1wwMzNcdWZmODNcMDQyXHVmZjgzXDA0MyIgKwotICAgICJcdWZmODNcMDAxXDAwMlwwMDBcMDU0XDAwMlx1ZmY4Y1wwMDRcdWZmOGNcMDA2XHVmZjhjXDAwN1x1ZmY4YyIgKwotICAgICJcMDEwXHVmZjhjXDAxMlx1ZmY4Y1wwMTNcdWZmOGNcMDE0XHVmZjhjXDAyMVx1ZmY4Y1wwMjJcdWZmOGNcMDIzIiArCi0gICAgIlx1ZmY4Y1wwMjRcdWZmOGNcMDI1XHVmZjhjXDAyNlx1ZmY4Y1wwMjdcdWZmOGNcMDMwXHVmZjhjXDAzMVx1ZmY4YyIgKwotICAgICJcMDMyXHVmZjhjXDAzM1x1ZmY4Y1wwNDJcdWZmOGNcMDQzXHVmZjhjXDAwMVwwMDJcMDAwXDA2MFwwMDIiICsKLSAgICAiXHVmZjgwXDAwNFx1ZmY4MFwwMDZcdWZmODBcMDA3XHVmZjgwXDAxMFx1ZmY4MFwwMTFcdWZmODBcMDEyXHVmZjgwIiArCi0gICAgIlwwMTNcdWZmODBcMDE0XHVmZjgwXDAyMFx1ZmZhYlwwMjFcdWZmODBcMDIyXHVmZjgwXDAyM1x1ZmY4MFwwMjQiICsKLSAgICAiXHVmZjgwXDAyNVx1ZmY4MFwwMjZcdWZmODBcMDI3XHVmZjgwXDAzMFx1ZmY4MFwwMzFcdWZmODBcMDMyXHVmZjgwIiArCi0gICAgIlwwMzNcdWZmODBcMDQyXHVmZjgwXDA0M1x1ZmY4MFwwMDFcMDAyXDAwMFwwNDRcMDAyXHVmZmM2XDAwNyIgKwotICAgICJcdWZmYzZcMDEyXHVmZmM2XDAxM1x1ZmZjNlwwMTRcdWZmYzZcMDIyXHVmZmM2XDAyM1x1ZmZjNlwwMjRcdWZmYzYiICsKLSAgICAiXDAyNVx1ZmZjNlwwMjZcdWZmYzZcMDI3XHVmZmM2XDAzMFx1ZmZjNlwwMzFcdWZmYzZcMDMyXHVmZmM2XDAzMyIgKwotICAgICJcdWZmYzZcMDQyXHVmZmM2XDA0M1x1ZmZjNlwwMDFcMDAyXDAwMFwwNTRcMDAyXHVmZjhkXDAwNFx1ZmY4ZCIgKwotICAgICJcMDA2XHVmZjhkXDAwN1x1ZmY4ZFwwMTBcdWZmOGRcMDEyXHVmZjhkXDAxM1x1ZmY4ZFwwMTRcdWZmOGRcMDIxIiArCi0gICAgIlx1ZmY4ZFwwMjJcdWZmOGRcMDIzXHVmZjhkXDAyNFx1ZmY4ZFwwMjVcdWZmOGRcMDI2XHVmZjhkXDAyN1x1ZmY4ZCIgKwotICAgICJcMDMwXHVmZjhkXDAzMVx1ZmY4ZFwwMzJcdWZmOGRcMDMzXHVmZjhkXDA0Mlx1ZmY4ZFwwNDNcdWZmOGRcMDAxIiArCi0gICAgIlwwMDJcMDAwXDA0NFwwMDJcdWZmY2RcMDA3XHVmZmNkXDAxMlx1ZmZjZFwwMTNcMTYwXDAxNFx1ZmZjZCIgKwotICAgICJcMDIyXHVmZmNkXDAyM1x1ZmZjZFwwMjRcdWZmY2RcMDI1XHVmZmNkXDAyNlx1ZmZjZFwwMjdcdWZmY2RcMDMwIiArCi0gICAgIlx1ZmZjZFwwMzFcdWZmY2RcMDMyXDE2MVwwMzNcMTU3XDA0Mlx1ZmZjZFwwNDNcdWZmY2RcMDAxXDAwMiIgKwotICAgICJcMDAwXDA1MlwwMDJcdWZmYmVcMDA0XDE1M1wwMDdcdWZmYmVcMDEwXHVmZmJlXDAxMlx1ZmZiZVwwMTMiICsKLSAgICAiXHVmZmJlXDAxNFx1ZmZiZVwwMjFcMTUyXDAyMlx1ZmZiZVwwMjNcdWZmYmVcMDI0XHVmZmJlXDAyNVx1ZmZiZSIgKwotICAgICJcMDI2XHVmZmJlXDAyN1x1ZmZiZVwwMzBcdWZmYmVcMDMxXHVmZmJlXDAzMlx1ZmZiZVwwMzNcdWZmYmVcMDQyIiArCi0gICAgIlx1ZmZiZVwwNDNcdWZmYmVcMDAxXDAwMlwwMDBcMDU0XDAwMlx1ZmY4ZVwwMDRcdWZmOGVcMDA2XHVmZjhlIiArCi0gICAgIlwwMDdcdWZmOGVcMDEwXHVmZjhlXDAxMlx1ZmY4ZVwwMTNcdWZmOGVcMDE0XHVmZjhlXDAyMVx1ZmY4ZVwwMjIiICsKLSAgICAiXHVmZjhlXDAyM1x1ZmY4ZVwwMjRcdWZmOGVcMDI1XHVmZjhlXDAyNlx1ZmY4ZVwwMjdcdWZmOGVcMDMwXHVmZjhlIiArCi0gICAgIlwwMzFcdWZmOGVcMDMyXHVmZjhlXDAzM1x1ZmY4ZVwwNDJcdWZmOGVcMDQzXHVmZjhlXDAwMVwwMDJcMDAwIiArCi0gICAgIlwwNTZcMDAyXHVmZjg3XDAwNFx1ZmY4N1wwMDZcdWZmODdcMDA3XHVmZjg3XDAxMFx1ZmY4N1wwMTFcdWZmOTEiICsKLSAgICAiXDAxMlx1ZmY4N1wwMTNcdWZmODdcMDE0XHVmZjg3XDAyMVx1ZmY4N1wwMjJcdWZmODdcMDIzXHVmZjg3XDAyNCIgKwotICAgICJcdWZmODdcMDI1XHVmZjg3XDAyNlx1ZmY4N1wwMjdcdWZmODdcMDMwXHVmZjg3XDAzMVx1ZmY4N1wwMzJcdWZmODciICsKLSAgICAiXDAzM1x1ZmY4N1wwNDJcdWZmODdcMDQzXHVmZjg3XDAwMVwwMDJcMDAwXDA3MFwwMDVcMTExXDAxMyIgKwotICAgICJcMTAzXDAxNlwwNjZcMDE3XDEwNlwwMzJcMDMxXDAzM1wwNDBcMDM1XDAzNFwwMzZcMTEzIiArCi0gICAgIlwwMzdcMTQxXDA0MFwxNDJcMDQxXDE0NVwwNDRcMDYzXDA0NVwwNjJcMDQ2XDA2NVwwNDciICsKLSAgICAiXDExNVwwNTBcMTIzXDA1MVwxMzZcMDUyXDA3N1wwNTNcMTQzXDA1NFwxMzFcMDU1XDEyNSIgKwotICAgICJcMDU2XDExNlwwNTdcMTA0XDA2MFwxNDBcMDYxXDA2N1wwNjJcMDYwXDA2M1wxMjdcMDAxIiArCi0gICAgIlwwMDJcMDAwXDA3MFwwMDVcMTExXDAxM1wxMDNcMDE2XDA2NlwwMTdcMTA2XDAzMlwwMzEiICsKLSAgICAiXDAzM1wwNDBcMDM1XDAzNFwwMzZcMTEzXDAzN1wxNDFcMDQwXDE0MlwwNDFcMTQ1XDA0NCIgKwotICAgICJcMDYzXDA0NVwwNjJcMDQ2XDA2NVwwNDdcMTE1XDA1MFwxMjNcMDUxXDEzNlwwNTJcMDc3IiArCi0gICAgIlwwNTNcMTQzXDA1NFwxMzFcMDU1XDEyNVwwNTZcMTE2XDA1N1wxMDRcMDYwXDE0MFwwNjEiICsKLSAgICAiXDA2N1wwNjJcMDYwXDA2M1wxMjdcMDAxXDAwMlwwMDBcMDU0XDAwMlx1ZmY4N1wwMDRcdWZmODciICsKLSAgICAiXDAwNlx1ZmY4N1wwMDdcdWZmODdcMDEwXHVmZjg3XDAxMlx1ZmY4N1wwMTNcdWZmODdcMDE0XHVmZjg3XDAyMSIgKwotICAgICJcdWZmODdcMDIyXHVmZjg3XDAyM1x1ZmY4N1wwMjRcdWZmODdcMDI1XHVmZjg3XDAyNlx1ZmY4N1wwMjdcdWZmODciICsKLSAgICAiXDAzMFx1ZmY4N1wwMzFcdWZmODdcMDMyXHVmZjg3XDAzM1x1ZmY4N1wwNDJcdWZmODdcMDQzXHVmZjg3XDAwMSIgKwotICAgICJcMDAyXDAwMFwwNTJcMDAyXHVmZmJiXDAwNFx1ZmZiYlwwMDdcdWZmYmJcMDEwXHVmZmJiXDAxMlx1ZmZiYiIgKwotICAgICJcMDEzXHVmZmJiXDAxNFx1ZmZiYlwwMjFcdWZmYmJcMDIyXHVmZmJiXDAyM1x1ZmZiYlwwMjRcdWZmYmJcMDI1IiArCi0gICAgIlx1ZmZiYlwwMjZcdWZmYmJcMDI3XHVmZmJiXDAzMFx1ZmZiYlwwMzFcdWZmYmJcMDMyXHVmZmJiXDAzM1x1ZmZiYiIgKwotICAgICJcMDQyXHVmZmJiXDA0M1x1ZmZiYlwwMDFcMDAyXDAwMFwwNTJcMDAyXHVmZmI2XDAwNFx1ZmZiNlwwMDciICsKLSAgICAiXHVmZmI2XDAxMFx1ZmZiNlwwMTJcdWZmYjZcMDEzXHVmZmI2XDAxNFx1ZmZiNlwwMjFcdWZmYjZcMDIyXHVmZmI2IiArCi0gICAgIlwwMjNcdWZmYjZcMDI0XHVmZmI2XDAyNVx1ZmZiNlwwMjZcdWZmYjZcMDI3XHVmZmI2XDAzMFx1ZmZiNlwwMzEiICsKLSAgICAiXHVmZmI2XDAzMlx1ZmZiNlwwMzNcdWZmYjZcMDQyXHVmZmI2XDA0M1x1ZmZiNlwwMDFcMDAyXDAwMFwxMTAiICsKLSAgICAiXDAwNFwwNjFcMDA1XDExMVwwMTFcMDcxXDAxM1wxMDNcMDE1XDEzNFwwMTZcMDY2XDAxNyIgKwotICAgICJcMTA2XDAyMVwwNzBcMDMxXDA3NVwwMzJcMDMxXDAzM1wwNDBcMDM0XDA1N1wwMzVcMDM0IiArCi0gICAgIlwwMzZcMTEzXDAzN1wxNDFcMDQwXDE0MlwwNDFcMTQ1XDA0NFwwNjNcMDQ1XDA2MlwwNDYiICsKLSAgICAiXDA2NVwwNDdcMTE1XDA1MFwxMjNcMDUxXDEzNlwwNTJcMDc3XDA1M1wxNDNcMDU0XDEzMSIgKwotICAgICJcMDU1XDEyNVwwNTZcMTE2XDA1N1wxMDRcMDYwXDE0MFwwNjFcMDY3XDA2MlwwNjBcMDYzIiArCi0gICAgIlwxMjdcMDY0XDEzMlwwNjVcMDcyXDAwMVwwMDJcMDAwXDExMFwwMDRcMDYxXDAwNVwxMTEiICsKLSAgICAiXDAxMVwwNzFcMDEzXDEwM1wwMTVcMTM0XDAxNlwwNjZcMDE3XDEwNlwwMjFcMDcwXDAzMSIgKwotICAgICJcMDc1XDAzMlwwMzFcMDMzXDA0MFwwMzRcMDU3XDAzNVwwMzRcMDM2XDExM1wwMzdcMTQxIiArCi0gICAgIlwwNDBcMTQyXDA0MVwxNDVcMDQ0XDA2M1wwNDVcMDYyXDA0NlwwNjVcMDQ3XDExNVwwNTAiICsKLSAgICAiXDEyM1wwNTFcMTM2XDA1MlwwNzdcMDUzXDE0M1wwNTRcMTMxXDA1NVwxMjVcMDU2XDExNiIgKwotICAgICJcMDU3XDEwNFwwNjBcMTQwXDA2MVwwNjdcMDYyXDA2MFwwNjNcMTI3XDA2NFwxMzJcMDY1IiArCi0gICAgIlwwNzJcMDAxXDAwMlwwMDBcMTEwXDAwNFwwNjFcMDA1XDExMVwwMTFcMDcxXDAxM1wxMDMiICsKLSAgICAiXDAxNVwxMzRcMDE2XDA2NlwwMTdcMTA2XDAyMVwwNzBcMDMxXDA3NVwwMzJcMDMxXDAzMyIgKwotICAgICJcMDQwXDAzNFwwNTdcMDM1XDAzNFwwMzZcMTEzXDAzN1wxNDFcMDQwXDE0MlwwNDFcMTQ1IiArCi0gICAgIlwwNDRcMDYzXDA0NVwwNjJcMDQ2XDA2NVwwNDdcMTE1XDA1MFwxMjNcMDUxXDEzNlwwNTIiICsKLSAgICAiXDA3N1wwNTNcMTQzXDA1NFwxMzFcMDU1XDEyNVwwNTZcMTE2XDA1N1wxMDRcMDYwXDE0MCIgKwotICAgICJcMDYxXDA2N1wwNjJcMDYwXDA2M1wxMjdcMDY0XDEzMlwwNjVcMDcyXDAwMVwwMDJcMDAwIiArCi0gICAgIlwwNDRcMDAyXHVmZmM4XDAwN1x1ZmZjOFwwMTJcdWZmYzhcMDEzXHVmZmM4XDAxNFx1ZmZjOFwwMjJcdWZmYzgiICsKLSAgICAiXDAyM1x1ZmZjOFwwMjRcdWZmYzhcMDI1XHVmZmM4XDAyNlx1ZmZjOFwwMjdcdWZmYzhcMDMwXHVmZmM4XDAzMSIgKwotICAgICJcdWZmYzhcMDMyXHVmZmM4XDAzM1x1ZmZjOFwwNDJcdWZmYzhcMDQzXHVmZmM4XDAwMVwwMDJcMDAwXDA0NCIgKwotICAgICJcMDAyXHVmZmM5XDAwN1x1ZmZjOVwwMTJcdWZmYzlcMDEzXHVmZmM5XDAxNFx1ZmZjOVwwMjJcdWZmYzlcMDIzIiArCi0gICAgIlx1ZmZjOVwwMjRcdWZmYzlcMDI1XHVmZmM5XDAyNlx1ZmZjOVwwMjdcdWZmYzlcMDMwXHVmZmM5XDAzMVx1ZmZjOSIgKwotICAgICJcMDMyXHVmZmM5XDAzM1x1ZmZjOVwwNDJcdWZmYzlcMDQzXHVmZmM5XDAwMVwwMDJcMDAwXDA0NFwwMDIiICsKLSAgICAiXHVmZmM3XDAwN1x1ZmZjN1wwMTJcdWZmYzdcMDEzXHVmZmM3XDAxNFx1ZmZjN1wwMjJcdWZmYzdcMDIzXHVmZmM3IiArCi0gICAgIlwwMjRcdWZmYzdcMDI1XHVmZmM3XDAyNlx1ZmZjN1wwMjdcdWZmYzdcMDMwXHVmZmM3XDAzMVx1ZmZjN1wwMzIiICsKLSAgICAiXHVmZmM3XDAzM1x1ZmZjN1wwNDJcdWZmYzdcMDQzXHVmZmM3XDAwMVwwMDJcMDAwXDA1NFwwMDJcdWZmOTAiICsKLSAgICAiXDAwNFx1ZmY5MFwwMDZcdWZmOTBcMDA3XHVmZjkwXDAxMFx1ZmY5MFwwMTJcdWZmOTBcMDEzXHVmZjkwXDAxNCIgKwotICAgICJcdWZmOTBcMDIxXHVmZjkwXDAyMlx1ZmY5MFwwMjNcdWZmOTBcMDI0XHVmZjkwXDAyNVx1ZmY5MFwwMjZcdWZmOTAiICsKLSAgICAiXDAyN1x1ZmY5MFwwMzBcdWZmOTBcMDMxXHVmZjkwXDAzMlx1ZmY5MFwwMzNcdWZmOTBcMDQyXHVmZjkwXDA0MyIgKwotICAgICJcdWZmOTBcMDAxXDAwMlwwMDBcMDU0XDAwMlx1ZmY4MFwwMDRcdWZmODBcMDA2XHVmZjgwXDAwN1x1ZmY4MCIgKwotICAgICJcMDEwXHVmZjgwXDAxMlx1ZmY4MFwwMTNcdWZmODBcMDE0XHVmZjgwXDAyMVx1ZmY4MFwwMjJcdWZmODBcMDIzIiArCi0gICAgIlx1ZmY4MFwwMjRcdWZmODBcMDI1XHVmZjgwXDAyNlx1ZmY4MFwwMjdcdWZmODBcMDMwXHVmZjgwXDAzMVx1ZmY4MCIgKwotICAgICJcMDMyXHVmZjgwXDAzM1x1ZmY4MFwwNDJcdWZmODBcMDQzXHVmZjgwXDAwMVwwMDJcMDAwXDA1NFwwMDIiICsKLSAgICAiXHVmZjk2XDAwNFx1ZmY5NlwwMDZcdWZmOTZcMDA3XHVmZjk2XDAxMFx1ZmY5NlwwMTJcdWZmOTZcMDEzXHVmZjk2IiArCi0gICAgIlwwMTRcdWZmOTZcMDIxXHVmZjk2XDAyMlx1ZmY5NlwwMjNcdWZmOTZcMDI0XHVmZjk2XDAyNVx1ZmY5NlwwMjYiICsKLSAgICAiXHVmZjk2XDAyN1x1ZmY5NlwwMzBcdWZmOTZcMDMxXHVmZjk2XDAzMlx1ZmY5NlwwMzNcdWZmOTZcMDQyXHVmZjk2IiArCi0gICAgIlwwNDNcdWZmOTZcMDAxXDAwMlwwMDBcMDU0XDAwMlx1ZmY3ZlwwMDRcdWZmN2ZcMDA2XHVmZjdmXDAwNyIgKwotICAgICJcdWZmN2ZcMDEwXHVmZjdmXDAxMlx1ZmY3ZlwwMTNcdWZmN2ZcMDE0XHVmZjdmXDAyMVx1ZmY3ZlwwMjJcdWZmN2YiICsKLSAgICAiXDAyM1x1ZmY3ZlwwMjRcdWZmN2ZcMDI1XHVmZjdmXDAyNlx1ZmY3ZlwwMjdcdWZmN2ZcMDMwXHVmZjdmXDAzMSIgKwotICAgICJcdWZmN2ZcMDMyXHVmZjdmXDAzM1x1ZmY3ZlwwNDJcdWZmN2ZcMDQzXHVmZjdmXDAwMVwwMDJcMDAwXDA1NCIgKwotICAgICJcMDAyXHVmZmRiXDAwNFx1ZmZkYlwwMDZcdWZmZGJcMDA3XHVmZmRiXDAxMFx1ZmZkYlwwMTJcdWZmZGJcMDEzIiArCi0gICAgIlx1ZmZkYlwwMTRcdWZmZGJcMDIxXHVmZmRiXDAyMlx1ZmZkYlwwMjNcdWZmZGJcMDI0XHVmZmRiXDAyNVx1ZmZkYiIgKwotICAgICJcMDI2XHVmZmRiXDAyN1x1ZmZkYlwwMzBcdWZmZGJcMDMxXHVmZmRiXDAzMlx1ZmZkYlwwMzNcdWZmZGJcMDQyIiArCi0gICAgIlx1ZmZkYlwwNDNcdWZmZGJcMDAxXDAwMlwwMDBcMDcwXDAwNVwxMTFcMDEzXDEwM1wwMTZcMDY2IiArCi0gICAgIlwwMTdcMTA2XDAzMlwwMzFcMDMzXDA0MFwwMzVcMDM0XDAzNlwxMTNcMDM3XDE0MVwwNDAiICsKLSAgICAiXDE0MlwwNDFcMTQ1XDA0NFwwNjNcMDQ1XDA2MlwwNDZcMDY1XDA0N1wxMTVcMDUwXDEyMyIgKwotICAgICJcMDUxXDEzNlwwNTJcMDc3XDA1M1wxNDNcMDU0XDEzMVwwNTVcMTI1XDA1NlwxMTZcMDU3IiArCi0gICAgIlwxMDRcMDYwXDE0MFwwNjFcMDY3XDA2MlwwNjBcMDYzXDEyN1wwMDFcMDAyXDAwMFwwNzAiICsKLSAgICAiXDAwNVwxMTFcMDEzXDEwM1wwMTZcMDY2XDAxN1wxMDZcMDMyXDAzMVwwMzNcMDQwXDAzNSIgKwotICAgICJcMDM0XDAzNlwxMTNcMDM3XDE0MVwwNDBcMTQyXDA0MVwxNDVcMDQ0XDA2M1wwNDVcMDYyIiArCi0gICAgIlwwNDZcMDY1XDA0N1wxMTVcMDUwXDEyM1wwNTFcMTM2XDA1MlwwNzdcMDUzXDE0M1wwNTQiICsKLSAgICAiXDEzMVwwNTVcMTI1XDA1NlwxMTZcMDU3XDEwNFwwNjBcMTQwXDA2MVwwNjdcMDYyXDA2MCIgKwotICAgICJcMDYzXDEyN1wwMDFcMDAyXDAwMFwwNTJcMDAyXHVmZmMwXDAwNFwxNTNcMDA3XHVmZmMwXDAxMCIgKwotICAgICJcdWZmYzBcMDEyXHVmZmMwXDAxM1x1ZmZjMFwwMTRcdWZmYzBcMDIxXDE1MlwwMjJcdWZmYzBcMDIzXHVmZmMwIiArCi0gICAgIlwwMjRcdWZmYzBcMDI1XHVmZmMwXDAyNlx1ZmZjMFwwMjdcdWZmYzBcMDMwXHVmZmMwXDAzMVx1ZmZjMFwwMzIiICsKLSAgICAiXHVmZmMwXDAzM1x1ZmZjMFwwNDJcdWZmYzBcMDQzXHVmZmMwXDAwMVwwMDJcMDAwXDA1MlwwMDJcdWZmYmYiICsKLSAgICAiXDAwNFwxNTNcMDA3XHVmZmJmXDAxMFx1ZmZiZlwwMTJcdWZmYmZcMDEzXHVmZmJmXDAxNFx1ZmZiZlwwMjEiICsKLSAgICAiXDE1MlwwMjJcdWZmYmZcMDIzXHVmZmJmXDAyNFx1ZmZiZlwwMjVcdWZmYmZcMDI2XHVmZmJmXDAyN1x1ZmZiZiIgKwotICAgICJcMDMwXHVmZmJmXDAzMVx1ZmZiZlwwMzJcdWZmYmZcMDMzXHVmZmJmXDA0Mlx1ZmZiZlwwNDNcdWZmYmZcMDAxIiArCi0gICAgIlwwMDJcMDAwXDEwNlwwMDRcMDYxXDAwNVwxMTFcMDExXDA3MVwwMTNcMTAzXDAxNVwxMzQiICsKLSAgICAiXDAxNlwwNjZcMDE3XDEwNlwwMjFcMDcwXDAzMlwwMzFcMDMzXDA0MFwwMzRcMDU3XDAzNSIgKwotICAgICJcMDM0XDAzNlwxMTNcMDM3XDE0MVwwNDBcMTQyXDA0MVwxNDVcMDQ0XDA2M1wwNDVcMDYyIiArCi0gICAgIlwwNDZcMDY1XDA0N1wxMTVcMDUwXDEyM1wwNTFcMTM2XDA1MlwwNzdcMDUzXDE0M1wwNTQiICsKLSAgICAiXDEzMVwwNTVcMTI1XDA1NlwxMTZcMDU3XDEwNFwwNjBcMTQwXDA2MVwwNjdcMDYyXDA2MCIgKwotICAgICJcMDYzXDEyN1wwNjRcMTMyXDA2NVwwNzJcMDAxXDAwMlwwMDBcMDQ0XDAwMlx1ZmZjM1wwMDciICsKLSAgICAiXHVmZmMzXDAxMlx1ZmZjM1wwMTNcdWZmYzNcMDE0XHVmZmMzXDAyMlx1ZmZjM1wwMjNcdWZmYzNcMDI0XHVmZmMzIiArCi0gICAgIlwwMjVcdWZmYzNcMDI2XHVmZmMzXDAyN1x1ZmZjM1wwMzBcdWZmYzNcMDMxXHVmZmMzXDAzMlx1ZmZjM1wwMzMiICsKLSAgICAiXHVmZmMzXDA0Mlx1ZmZjM1wwNDNcdWZmYzNcMDAxXDAwMlwwMDBcMDUyXDAwMlx1ZmY5ZFwwMDRcdWZmOWQiICsKLSAgICAiXDAwN1x1ZmY5ZFwwMTBcdWZmOWRcMDEyXHVmZjlkXDAxM1x1ZmY5ZFwwMTRcdWZmOWRcMDIxXHVmZjlkXDAyMiIgKwotICAgICJcdWZmOWRcMDIzXHVmZjlkXDAyNFx1ZmY5ZFwwMjVcdWZmOWRcMDI2XHVmZjlkXDAyN1x1ZmY5ZFwwMzBcdWZmOWQiICsKLSAgICAiXDAzMVx1ZmY5ZFwwMzJcdWZmOWRcMDMzXHVmZjlkXDA0Mlx1ZmY5ZFwwNDNcdWZmOWRcMDAxXDAwMlwwMDAiICsKLSAgICAiXDExMlwwMDRcMDYxXDAwNVwxMTFcMDExXDA3MVwwMTJcMjAyXDAxM1wxMDNcMDE1XDEzNCIgKwotICAgICJcMDE2XDA2NlwwMTdcMTA2XDAyMVwwNzBcMDMxXDA3NVwwMzJcMDMxXDAzM1wwNDBcMDM0IiArCi0gICAgIlwwNTdcMDM1XDAzNFwwMzZcMTEzXDAzN1wxNDFcMDQwXDE0MlwwNDFcMTQ1XDA0NFwwNjMiICsKLSAgICAiXDA0NVwwNjJcMDQ2XDA2NVwwNDdcMTE1XDA1MFwxMjNcMDUxXDEzNlwwNTJcMDc3XDA1MyIgKwotICAgICJcMTQzXDA1NFwxMzFcMDU1XDEyNVwwNTZcMTE2XDA1N1wxMDRcMDYwXDE0MFwwNjFcMDY3IiArCi0gICAgIlwwNjJcMDYwXDA2M1wxMjdcMDY0XDEzMlwwNjVcMDcyXDAwMVwwMDJcMDAwXDA1NFwwMDIiICsKLSAgICAiXHVmZjk1XDAwNFx1ZmY5NVwwMDZcdWZmOTVcMDA3XHVmZjk1XDAxMFx1ZmY5NVwwMTJcdWZmOTVcMDEzXHVmZjk1IiArCi0gICAgIlwwMTRcdWZmOTVcMDIxXHVmZjk1XDAyMlx1ZmY5NVwwMjNcdWZmOTVcMDI0XHVmZjk1XDAyNVx1ZmY5NVwwMjYiICsKLSAgICAiXHVmZjk1XDAyN1x1ZmY5NVwwMzBcdWZmOTVcMDMxXHVmZjk1XDAzMlx1ZmY5NVwwMzNcdWZmOTVcMDQyXHVmZjk1IiArCi0gICAgIlwwNDNcdWZmOTVcMDAxXDAwMlwwMDBcMDA2XDAxMlx1ZmY5M1wwMTRcMjA3XDAwMVwwMDJcMDAwIiArCi0gICAgIlwwMDZcMDEyXHVmZjhmXDAxNFx1ZmY4ZlwwMDFcMDAyXDAwMFwwMDRcMDEyXDIwNlwwMDFcMDAyIiArCi0gICAgIlwwMDBcMDU0XDAwMlx1ZmY5NFwwMDRcdWZmOTRcMDA2XHVmZjk0XDAwN1x1ZmY5NFwwMTBcdWZmOTRcMDEyIiArCi0gICAgIlx1ZmY5NFwwMTNcdWZmOTRcMDE0XHVmZjk0XDAyMVx1ZmY5NFwwMjJcdWZmOTRcMDIzXHVmZjk0XDAyNFx1ZmY5NCIgKwotICAgICJcMDI1XHVmZjk0XDAyNlx1ZmY5NFwwMjdcdWZmOTRcMDMwXHVmZjk0XDAzMVx1ZmY5NFwwMzJcdWZmOTRcMDMzIiArCi0gICAgIlx1ZmY5NFwwNDJcdWZmOTRcMDQzXHVmZjk0XDAwMVwwMDJcMDAwXDExMFwwMDRcMDYxXDAwNVwxMTEiICsKLSAgICAiXDAxMVwwNzFcMDEzXDEwM1wwMTVcMTM0XDAxNlwwNjZcMDE3XDEwNlwwMjFcMDcwXDAzMSIgKwotICAgICJcMDc1XDAzMlwwMzFcMDMzXDA0MFwwMzRcMDU3XDAzNVwwMzRcMDM2XDExM1wwMzdcMTQxIiArCi0gICAgIlwwNDBcMTQyXDA0MVwxNDVcMDQ0XDA2M1wwNDVcMDYyXDA0NlwwNjVcMDQ3XDExNVwwNTAiICsKLSAgICAiXDEyM1wwNTFcMTM2XDA1MlwwNzdcMDUzXDE0M1wwNTRcMTMxXDA1NVwxMjVcMDU2XDExNiIgKwotICAgICJcMDU3XDEwNFwwNjBcMTQwXDA2MVwwNjdcMDYyXDA2MFwwNjNcMTI3XDA2NFwxMzJcMDY1IiArCi0gICAgIlwwNzJcMDAxXDAwMlwwMDBcMDA0XDAxMlx1ZmY5MlwwMDFcMDAyXDAwMFwxMTBcMDA0XDA2MSIgKwotICAgICJcMDA1XDExMVwwMTFcMDcxXDAxM1wxMDNcMDE1XDEzNFwwMTZcMDY2XDAxN1wxMDZcMDIxIiArCi0gICAgIlwwNzBcMDMxXDA3NVwwMzJcMDMxXDAzM1wwNDBcMDM0XDA1N1wwMzVcMDM0XDAzNlwxMTMiICsKLSAgICAiXDAzN1wxNDFcMDQwXDE0MlwwNDFcMTQ1XDA0NFwwNjNcMDQ1XDA2MlwwNDZcMDY1XDA0NyIgKwotICAgICJcMTE1XDA1MFwxMjNcMDUxXDEzNlwwNTJcMDc3XDA1M1wxNDNcMDU0XDEzMVwwNTVcMTI1IiArCi0gICAgIlwwNTZcMTE2XDA1N1wxMDRcMDYwXDE0MFwwNjFcMDY3XDA2MlwwNjBcMDYzXDEyN1wwNjQiICsKLSAgICAiXDEzMlwwNjVcMDcyXDAwMVwwMDJcMDAwXDExMFwwMDRcMDYxXDAwNVwxMTFcMDExXDA3MSIgKwotICAgICJcMDEzXDEwM1wwMTVcMTM0XDAxNlwwNjZcMDE3XDEwNlwwMjFcMDcwXDAzMVwwNzVcMDMyIiArCi0gICAgIlwwMzFcMDMzXDA0MFwwMzRcMDU3XDAzNVwwMzRcMDM2XDExM1wwMzdcMTQxXDA0MFwxNDIiICsKLSAgICAiXDA0MVwxNDVcMDQ0XDA2M1wwNDVcMDYyXDA0NlwwNjVcMDQ3XDExNVwwNTBcMTIzXDA1MSIgKwotICAgICJcMTM2XDA1MlwwNzdcMDUzXDE0M1wwNTRcMTMxXDA1NVwxMjVcMDU2XDExNlwwNTdcMTA0IiArCi0gICAgIlwwNjBcMTQwXDA2MVwwNjdcMDYyXDA2MFwwNjNcMTI3XDA2NFwxMzJcMDY1XDA3MlwwMDEiICsKLSAgICAiXDAwMlwwMDBcMDQ0XDAwMlx1ZmZjYlwwMDdcdWZmY2JcMDEyXHVmZmNiXDAxM1wxNjBcMDE0XHVmZmNiIiArCi0gICAgIlwwMjJcdWZmY2JcMDIzXHVmZmNiXDAyNFx1ZmZjYlwwMjVcdWZmY2JcMDI2XHVmZmNiXDAyN1x1ZmZjYlwwMzAiICsKLSAgICAiXHVmZmNiXDAzMVx1ZmZjYlwwMzJcMTYxXDAzM1wxNTdcMDQyXHVmZmNiXDA0M1x1ZmZjYlwwMDFcMDAyIiArCi0gICAgIlwwMDBcMDQ0XDAwMlx1ZmZjY1wwMDdcdWZmY2NcMDEyXHVmZmNjXDAxM1wxNjBcMDE0XHVmZmNjXDAyMiIgKwotICAgICJcdWZmY2NcMDIzXHVmZmNjXDAyNFx1ZmZjY1wwMjVcdWZmY2NcMDI2XHVmZmNjXDAyN1x1ZmZjY1wwMzBcdWZmY2MiICsKLSAgICAiXDAzMVx1ZmZjY1wwMzJcMTYxXDAzM1wxNTdcMDQyXHVmZmNjXDA0M1x1ZmZjY1wwMDFcMDAyXDAwMCIgKwotICAgICJcMDUyXDAwMlx1ZmZiM1wwMDRcdWZmYjNcMDA3XHVmZmIzXDAxMFx1ZmZiM1wwMTJcdWZmYjNcMDEzXHVmZmIzIiArCi0gICAgIlwwMTRcdWZmYjNcMDIxXHVmZmIzXDAyMlx1ZmZiM1wwMjNcdWZmYjNcMDI0XHVmZmIzXDAyNVx1ZmZiM1wwMjYiICsKLSAgICAiXHVmZmIzXDAyN1x1ZmZiM1wwMzBcdWZmYjNcMDMxXHVmZmIzXDAzMlx1ZmZiM1wwMzNcdWZmYjNcMDQyXHVmZmIzIiArCi0gICAgIlwwNDNcdWZmYjNcMDAxXDAwMlwwMDBcMTEwXDAwNFwwNjFcMDA1XDExMVwwMTFcMDcxXDAxMyIgKwotICAgICJcMTAzXDAxNVwxMzRcMDE2XDA2NlwwMTdcMTA2XDAyMVwwNzBcMDMxXDA3NVwwMzJcMDMxIiArCi0gICAgIlwwMzNcMDQwXDAzNFwwNTdcMDM1XDAzNFwwMzZcMTEzXDAzN1wxNDFcMDQwXDE0MlwwNDEiICsKLSAgICAiXDE0NVwwNDRcMDYzXDA0NVwwNjJcMDQ2XDA2NVwwNDdcMTE1XDA1MFwxMjNcMDUxXDEzNiIgKwotICAgICJcMDUyXDA3N1wwNTNcMTQzXDA1NFwxMzFcMDU1XDEyNVwwNTZcMTE2XDA1N1wxMDRcMDYwIiArCi0gICAgIlwxNDBcMDYxXDA2N1wwNjJcMDYwXDA2M1wxMjdcMDY0XDEzMlwwNjVcMDcyXDAwMVwwMDIiICsKLSAgICAiXDAwMFwxMTBcMDA0XDA2MVwwMDVcMTExXDAxMVwwNzFcMDEzXDEwM1wwMTVcMTM0XDAxNiIgKwotICAgICJcMDY2XDAxN1wxMDZcMDIxXDA3MFwwMzFcMDc1XDAzMlwwMzFcMDMzXDA0MFwwMzRcMDU3IiArCi0gICAgIlwwMzVcMDM0XDAzNlwxMTNcMDM3XDE0MVwwNDBcMTQyXDA0MVwxNDVcMDQ0XDA2M1wwNDUiICsKLSAgICAiXDA2MlwwNDZcMDY1XDA0N1wxMTVcMDUwXDEyM1wwNTFcMTM2XDA1MlwwNzdcMDUzXDE0MyIgKwotICAgICJcMDU0XDEzMVwwNTVcMTI1XDA1NlwxMTZcMDU3XDEwNFwwNjBcMTQwXDA2MVwwNjdcMDYyIiArCi0gICAgIlwwNjBcMDYzXDEyN1wwNjRcMTMyXDA2NVwwNzJcMDAxXDAwMlwwMDBcMDMyXDAwMlx1ZmZkMyIgKwotICAgICJcMDA3XHVmZmQzXDAxMlx1ZmZkM1wwMTRcdWZmZDNcMDIyXHVmZmQzXDAyM1x1ZmZkM1wwMjRcMjIxXDAyNSIgKwotICAgICJcMjIyXDAyNlwyMjNcMDI3XDIyNFwwNDJcdWZmZDNcMDQzXHVmZmQzXDAwMVwwMDJcMDAwXDExMCIgKwotICAgICJcMDA0XDA2MVwwMDVcMTExXDAxMVwwNzFcMDEzXDEwM1wwMTVcMTM0XDAxNlwwNjZcMDE3IiArCi0gICAgIlwxMDZcMDIxXDA3MFwwMzFcMDc1XDAzMlwwMzFcMDMzXDA0MFwwMzRcMDU3XDAzNVwwMzQiICsKLSAgICAiXDAzNlwxMTNcMDM3XDE0MVwwNDBcMTQyXDA0MVwxNDVcMDQ0XDA2M1wwNDVcMDYyXDA0NiIgKwotICAgICJcMDY1XDA0N1wxMTVcMDUwXDEyM1wwNTFcMTM2XDA1MlwwNzdcMDUzXDE0M1wwNTRcMTMxIiArCi0gICAgIlwwNTVcMTI1XDA1NlwxMTZcMDU3XDEwNFwwNjBcMTQwXDA2MVwwNjdcMDYyXDA2MFwwNjMiICsKLSAgICAiXDEyN1wwNjRcMTMyXDA2NVwwNzJcMDAxXDAwMlwwMDBcMTEwXDAwNFwwNjFcMDA1XDExMSIgKwotICAgICJcMDExXDA3MVwwMTNcMTAzXDAxNVwxMzRcMDE2XDA2NlwwMTdcMTA2XDAyMVwwNzBcMDMxIiArCi0gICAgIlwwNzVcMDMyXDAzMVwwMzNcMDQwXDAzNFwwNTdcMDM1XDAzNFwwMzZcMTEzXDAzN1wxNDEiICsKLSAgICAiXDA0MFwxNDJcMDQxXDE0NVwwNDRcMDYzXDA0NVwwNjJcMDQ2XDA2NVwwNDdcMTE1XDA1MCIgKwotICAgICJcMTIzXDA1MVwxMzZcMDUyXDA3N1wwNTNcMTQzXDA1NFwxMzFcMDU1XDEyNVwwNTZcMTE2IiArCi0gICAgIlwwNTdcMTA0XDA2MFwxNDBcMDYxXDA2N1wwNjJcMDYwXDA2M1wxMjdcMDY0XDEzMlwwNjUiICsKLSAgICAiXDA3MlwwMDFcMDAyXDAwMFwxMTBcMDA0XDA2MVwwMDVcMTExXDAxMVwwNzFcMDEzXDEwMyIgKwotICAgICJcMDE1XDEzNFwwMTZcMDY2XDAxN1wxMDZcMDIxXDA3MFwwMzFcMDc1XDAzMlwwMzFcMDMzIiArCi0gICAgIlwwNDBcMDM0XDA1N1wwMzVcMDM0XDAzNlwxMTNcMDM3XDE0MVwwNDBcMTQyXDA0MVwxNDUiICsKLSAgICAiXDA0NFwwNjNcMDQ1XDA2MlwwNDZcMDY1XDA0N1wxMTVcMDUwXDEyM1wwNTFcMTM2XDA1MiIgKwotICAgICJcMDc3XDA1M1wxNDNcMDU0XDEzMVwwNTVcMTI1XDA1NlwxMTZcMDU3XDEwNFwwNjBcMTQwIiArCi0gICAgIlwwNjFcMDY3XDA2MlwwNjBcMDYzXDEyN1wwNjRcMTMyXDA2NVwwNzJcMDAxXDAwMlwwMDAiICsKLSAgICAiXDExMFwwMDRcMDYxXDAwNVwxMTFcMDExXDA3MVwwMTNcMTAzXDAxNVwxMzRcMDE2XDA2NiIgKwotICAgICJcMDE3XDEwNlwwMjFcMDcwXDAzMVwwNzVcMDMyXDAzMVwwMzNcMDQwXDAzNFwwNTdcMDM1IiArCi0gICAgIlwwMzRcMDM2XDExM1wwMzdcMTQxXDA0MFwxNDJcMDQxXDE0NVwwNDRcMDYzXDA0NVwwNjIiICsKLSAgICAiXDA0NlwwNjVcMDQ3XDExNVwwNTBcMTIzXDA1MVwxMzZcMDUyXDA3N1wwNTNcMTQzXDA1NCIgKwotICAgICJcMTMxXDA1NVwxMjVcMDU2XDExNlwwNTdcMTA0XDA2MFwxNDBcMDYxXDA2N1wwNjJcMDYwIiArCi0gICAgIlwwNjNcMTI3XDA2NFwxMzJcMDY1XDA3MlwwMDFcMDAyXDAwMFwwMzZcMDAyXHVmZmNlXDAwNyIgKwotICAgICJcdWZmY2VcMDEyXHVmZmNlXDAxNFx1ZmZjZVwwMjJcdWZmY2VcMDIzXHVmZmNlXDAyNFx1ZmZjZVwwMjVcdWZmY2UiICsKLSAgICAiXDAyNlx1ZmZjZVwwMjdcdWZmY2VcMDMwXDIxMVwwMzFcMjEyXDA0Mlx1ZmZjZVwwNDNcdWZmY2VcMDAxIiArCi0gICAgIlwwMDJcMDAwXDAzNlwwMDJcdWZmY2ZcMDA3XHVmZmNmXDAxMlx1ZmZjZlwwMTRcdWZmY2ZcMDIyXHVmZmNmIiArCi0gICAgIlwwMjNcdWZmY2ZcMDI0XHVmZmNmXDAyNVx1ZmZjZlwwMjZcdWZmY2ZcMDI3XHVmZmNmXDAzMFwyMTFcMDMxIiArCi0gICAgIlwyMTJcMDQyXHVmZmNmXDA0M1x1ZmZjZlwwMDFcMDAyXDAwMFwwMzZcMDAyXHVmZmQwXDAwN1x1ZmZkMCIgKwotICAgICJcMDEyXHVmZmQwXDAxNFx1ZmZkMFwwMjJcdWZmZDBcMDIzXHVmZmQwXDAyNFx1ZmZkMFwwMjVcdWZmZDBcMDI2IiArCi0gICAgIlx1ZmZkMFwwMjdcdWZmZDBcMDMwXDIxMVwwMzFcMjEyXDA0Mlx1ZmZkMFwwNDNcdWZmZDBcMDAxXDAwMiIgKwotICAgICJcMDAwXDAzNlwwMDJcdWZmZDFcMDA3XHVmZmQxXDAxMlx1ZmZkMVwwMTRcdWZmZDFcMDIyXHVmZmQxXDAyMyIgKwotICAgICJcdWZmZDFcMDI0XHVmZmQxXDAyNVx1ZmZkMVwwMjZcdWZmZDFcMDI3XHVmZmQxXDAzMFwyMTFcMDMxXDIxMiIgKwotICAgICJcMDQyXHVmZmQxXDA0M1x1ZmZkMVwwMDFcMDAyXDAwMFwwMzJcMDAyXHVmZmQ0XDAwN1x1ZmZkNFwwMTIiICsKLSAgICAiXHVmZmQ0XDAxNFx1ZmZkNFwwMjJcdWZmZDRcMDIzXHVmZmQ0XDAyNFwyMjFcMDI1XDIyMlwwMjZcMjIzIiArCi0gICAgIlwwMjdcMjI0XDA0Mlx1ZmZkNFwwNDNcdWZmZDRcMDAxXDAwMlwwMDBcMTEwXDAwNFwwNjFcMDA1IiArCi0gICAgIlwxMTFcMDExXDA3MVwwMTNcMTAzXDAxNVwxMzRcMDE2XDA2NlwwMTdcMTA2XDAyMVwwNzAiICsKLSAgICAiXDAzMVwwNzVcMDMyXDAzMVwwMzNcMDQwXDAzNFwwNTdcMDM1XDAzNFwwMzZcMTEzXDAzNyIgKwotICAgICJcMTQxXDA0MFwxNDJcMDQxXDE0NVwwNDRcMDYzXDA0NVwwNjJcMDQ2XDA2NVwwNDdcMTE1IiArCi0gICAgIlwwNTBcMTIzXDA1MVwxMzZcMDUyXDA3N1wwNTNcMTQzXDA1NFwxMzFcMDU1XDEyNVwwNTYiICsKLSAgICAiXDExNlwwNTdcMTA0XDA2MFwxNDBcMDYxXDA2N1wwNjJcMDYwXDA2M1wxMjdcMDY0XDEzMiIgKwotICAgICJcMDY1XDA3MlwwMDFcMDAyXDAwMFwwMTZcMDAyXHVmZmQ4XDAwN1x1ZmZkOFwwMTJcdWZmZDhcMDE0IiArCi0gICAgIlx1ZmZkOFwwNDJcdWZmZDhcMDQzXDIzNFwwMDFcMDAyXDAwMFwxMTBcMDA0XDA2MVwwMDVcMTExIiArCi0gICAgIlwwMTFcMDcxXDAxM1wxMDNcMDE1XDEzNFwwMTZcMDY2XDAxN1wxMDZcMDIxXDA3MFwwMzEiICsKLSAgICAiXDA3NVwwMzJcMDMxXDAzM1wwNDBcMDM0XDA1N1wwMzVcMDM0XDAzNlwxMTNcMDM3XDE0MSIgKwotICAgICJcMDQwXDE0MlwwNDFcMTQ1XDA0NFwwNjNcMDQ1XDA2MlwwNDZcMDY1XDA0N1wxMTVcMDUwIiArCi0gICAgIlwxMjNcMDUxXDEzNlwwNTJcMDc3XDA1M1wxNDNcMDU0XDEzMVwwNTVcMTI1XDA1NlwxMTYiICsKLSAgICAiXDA1N1wxMDRcMDYwXDE0MFwwNjFcMDY3XDA2MlwwNjBcMDYzXDEyN1wwNjRcMTMyXDA2NSIgKwotICAgICJcMDcyXDAwMVwwMDJcMDAwXDAyMlwwMDJcdWZmZDZcMDA3XHVmZmQ2XDAxMlx1ZmZkNlwwMTRcdWZmZDYiICsKLSAgICAiXDAyMlwyMTZcMDIzXDIxN1wwNDJcdWZmZDZcMDQzXHVmZmQ2XDAwMVwwMDJcMDAwXDA2MlwwMTMiICsKLSAgICAiXHVmZmFmXDAzMlx1ZmZhZlwwMzNcdWZmYWZcMDM1XHVmZmFmXDAzNlx1ZmZhZlwwMzdcdWZmYWZcMDQwXHVmZmFmIiArCi0gICAgIlwwNDFcdWZmYWZcMDQ0XHVmZmFmXDA0NVx1ZmZhZlwwNDZcdWZmYWZcMDQ3XHVmZmFmXDA1MFx1ZmZhZlwwNTEiICsKLSAgICAiXHVmZmFmXDA1Mlx1ZmZhZlwwNTNcdWZmYWZcMDU0XHVmZmFmXDA1NVx1ZmZhZlwwNTZcdWZmYWZcMDU3XHVmZmFmIiArCi0gICAgIlwwNjBcdWZmYWZcMDYxXHVmZmFmXDA2Mlx1ZmZhZlwwNjNcdWZmYWZcMDAxXDAwMlwwMDBcMDU0XDAwMiIgKwotICAgICJcdWZmYjFcMDA0XHVmZmIxXDAwNlwwNTVcMDA3XHVmZmIxXDAxMFx1ZmZiMVwwMTJcdWZmYjFcMDEzXHVmZmIxIiArCi0gICAgIlwwMTRcdWZmYjFcMDIxXHVmZmIxXDAyMlx1ZmZiMVwwMjNcdWZmYjFcMDI0XHVmZmIxXDAyNVx1ZmZiMVwwMjYiICsKLSAgICAiXHVmZmIxXDAyN1x1ZmZiMVwwMzBcdWZmYjFcMDMxXHVmZmIxXDAzMlx1ZmZiMVwwMzNcdWZmYjFcMDQyXHVmZmIxIiArCi0gICAgIlwwNDNcdWZmYjFcMDAxXDAwMlwwMDBcMDUyXDAwMlx1ZmZiMlwwMDRcdWZmYjJcMDA3XHVmZmIyXDAxMCIgKwotICAgICJcdWZmYjJcMDEyXHVmZmIyXDAxM1x1ZmZiMlwwMTRcdWZmYjJcMDIxXHVmZmIyXDAyMlx1ZmZiMlwwMjNcdWZmYjIiICsKLSAgICAiXDAyNFx1ZmZiMlwwMjVcdWZmYjJcMDI2XHVmZmIyXDAyN1x1ZmZiMlwwMzBcdWZmYjJcMDMxXHVmZmIyXDAzMiIgKwotICAgICJcdWZmYjJcMDMzXHVmZmIyXDA0Mlx1ZmZiMlwwNDNcdWZmYjJcMDAxXDAwMlwwMDBcMDQ0XDAwMlx1ZmZjNSIgKwotICAgICJcMDA3XHVmZmM1XDAxMlx1ZmZjNVwwMTNcdWZmYzVcMDE0XHVmZmM1XDAyMlx1ZmZjNVwwMjNcdWZmYzVcMDI0IiArCi0gICAgIlx1ZmZjNVwwMjVcdWZmYzVcMDI2XHVmZmM1XDAyN1x1ZmZjNVwwMzBcdWZmYzVcMDMxXHVmZmM1XDAzMlx1ZmZjNSIgKwotICAgICJcMDMzXHVmZmM1XDA0Mlx1ZmZjNVwwNDNcdWZmYzVcMDAxXDAwMlwwMDBcMDA0XDAxMlwyNDNcMDAxIiArCi0gICAgIlwwMDJcMDAwXDA1NFwwMDJcdWZmOWJcMDA0XHVmZjliXDAwNlx1ZmY5YlwwMDdcdWZmOWJcMDEwXHVmZjliIiArCi0gICAgIlwwMTJcdWZmOWJcMDEzXHVmZjliXDAxNFx1ZmY5YlwwMjFcdWZmOWJcMDIyXHVmZjliXDAyM1x1ZmY5YlwwMjQiICsKLSAgICAiXHVmZjliXDAyNVx1ZmY5YlwwMjZcdWZmOWJcMDI3XHVmZjliXDAzMFx1ZmY5YlwwMzFcdWZmOWJcMDMyXHVmZjliIiArCi0gICAgIlwwMzNcdWZmOWJcMDQyXHVmZjliXDA0M1x1ZmY5YlwwMDFcMDAyXDAwMFwwNTJcMDAyXHVmZmI1XDAwNCIgKwotICAgICJcMTUzXDAwN1x1ZmZiNVwwMTBcdWZmYjVcMDEyXHVmZmI1XDAxM1x1ZmZiNVwwMTRcdWZmYjVcMDIxXDE1MiIgKwotICAgICJcMDIyXHVmZmI1XDAyM1x1ZmZiNVwwMjRcdWZmYjVcMDI1XHVmZmI1XDAyNlx1ZmZiNVwwMjdcdWZmYjVcMDMwIiArCi0gICAgIlx1ZmZiNVwwMzFcdWZmYjVcMDMyXHVmZmI1XDAzM1x1ZmZiNVwwNDJcdWZmYjVcMDQzXHVmZmI1XDAwMVwwMDIiICsKLSAgICAiXDAwMFwwMDRcMDM0XDI0NlwwMDFcMDAyXDAwMFwwMDRcMDEyXDI0N1wwMDFcMDAyXDAwMCIgKwotICAgICJcMDU0XDAwMlx1ZmY4YVwwMDRcdWZmOGFcMDA2XHVmZjhhXDAwN1x1ZmY4YVwwMTBcdWZmOGFcMDEyXHVmZjhhIiArCi0gICAgIlwwMTNcdWZmOGFcMDE0XHVmZjhhXDAyMVx1ZmY4YVwwMjJcdWZmOGFcMDIzXHVmZjhhXDAyNFx1ZmY4YVwwMjUiICsKLSAgICAiXHVmZjhhXDAyNlx1ZmY4YVwwMjdcdWZmOGFcMDMwXHVmZjhhXDAzMVx1ZmY4YVwwMzJcdWZmOGFcMDMzXHVmZjhhIiArCi0gICAgIlwwNDJcdWZmOGFcMDQzXHVmZjhhXDAwMVwwMDJcMDAwXDA1MlwwMDJcdWZmYjhcMDA0XDE1M1wwMDciICsKLSAgICAiXHVmZmI4XDAxMFx1ZmZiOFwwMTJcdWZmYjhcMDEzXHVmZmI4XDAxNFx1ZmZiOFwwMjFcMTUyXDAyMlx1ZmZiOCIgKwotICAgICJcMDIzXHVmZmI4XDAyNFx1ZmZiOFwwMjVcdWZmYjhcMDI2XHVmZmI4XDAyN1x1ZmZiOFwwMzBcdWZmYjhcMDMxIiArCi0gICAgIlx1ZmZiOFwwMzJcdWZmYjhcMDMzXHVmZmI4XDA0Mlx1ZmZiOFwwNDNcdWZmYjhcMDAxXDAwMlwwMDBcMDUyIiArCi0gICAgIlwwMDJcdWZmZGNcMDA0XHVmZmRjXDAwN1x1ZmZkY1wwMTBcdWZmZGNcMDEyXHVmZmRjXDAxM1x1ZmZkY1wwMTQiICsKLSAgICAiXHVmZmRjXDAyMVx1ZmZkY1wwMjJcdWZmZGNcMDIzXHVmZmRjXDAyNFx1ZmZkY1wwMjVcdWZmZGNcMDI2XHVmZmRjIiArCi0gICAgIlwwMjdcdWZmZGNcMDMwXHVmZmRjXDAzMVx1ZmZkY1wwMzJcdWZmZGNcMDMzXHVmZmRjXDA0Mlx1ZmZkY1wwNDMiICsKLSAgICAiXHVmZmRjXDAwMVwwMDJcMDAwXDA2MlwwMTNcdWZmZGVcMDMyXHVmZmRlXDAzM1x1ZmZkZVwwMzVcdWZmZGUiICsKLSAgICAiXDAzNlx1ZmZkZVwwMzdcdWZmZGVcMDQwXHVmZmRlXDA0MVx1ZmZkZVwwNDRcdWZmZGVcMDQ1XHVmZmRlXDA0NiIgKwotICAgICJcdWZmZGVcMDQ3XHVmZmRlXDA1MFx1ZmZkZVwwNTFcdWZmZGVcMDUyXHVmZmRlXDA1M1x1ZmZkZVwwNTRcdWZmZGUiICsKLSAgICAiXDA1NVx1ZmZkZVwwNTZcdWZmZGVcMDU3XHVmZmRlXDA2MFx1ZmZkZVwwNjFcdWZmZGVcMDYyXHVmZmRlXDA2MyIgKwotICAgICJcdWZmZGVcMDAxXDAwMlwwMDBcMDA0XDAzNFwyNTRcMDAxXDAwMlwwMDBcMDA0XDAxNFwyNTUiICsKLSAgICAiXDAwMVwwMDJcMDAwXDAwNFwwMzRcMjU2XDAwMVwwMDJcMDAwXDAwNFwwMTJcMjU3XDAwMSIgKwotICAgICJcMDAyXDAwMFwwMTJcMDAyXHVmZmY0XDAwNFx1ZmZmNFwwMTBcdWZmZjRcMDIxXHVmZmY0XDAwMVwwMDIiICsKLSAgICAiXDAwMFwwMDRcMDM0XDI2MVwwMDFcMDAyXDAwMFwwMDRcMDEyXDI2MlwwMDFcMDAyXDAwMCIgKwotICAgICJcMDEyXDAwMlx1ZmZmNVwwMDRcdWZmZjVcMDEwXHVmZmY1XDAyMVx1ZmZmNVwwMDFcMDAyXDAwMFwwMTIiICsKLSAgICAiXDAwMlx1ZmZlY1wwMDRcdWZmZWNcMDEwXHVmZmVjXDAyMVx1ZmZlY1wwMDFcMDAyXDAwMFwwNjJcMDEzIiArCi0gICAgIlx1ZmZkZlwwMzJcdWZmZGZcMDMzXHVmZmRmXDAzNVx1ZmZkZlwwMzZcdWZmZGZcMDM3XHVmZmRmXDA0MFx1ZmZkZiIgKwotICAgICJcMDQxXHVmZmRmXDA0NFx1ZmZkZlwwNDVcdWZmZGZcMDQ2XHVmZmRmXDA0N1x1ZmZkZlwwNTBcdWZmZGZcMDUxIiArCi0gICAgIlx1ZmZkZlwwNTJcdWZmZGZcMDUzXHVmZmRmXDA1NFx1ZmZkZlwwNTVcdWZmZGZcMDU2XHVmZmRmXDA1N1x1ZmZkZiIgKwotICAgICJcMDYwXHVmZmRmXDA2MVx1ZmZkZlwwNjJcdWZmZGZcMDYzXHVmZmRmXDAwMVwwMDJcMDAwXDA2NFwwMTMiICsKLSAgICAiXDAyN1wwMTZcMDIwXDAzMlwwMzFcMDMzXDA0MFwwMzVcMDM0XDAzNlwxMTNcMDM3XDE0MSIgKwotICAgICJcMDQwXDA0N1wwNDFcMDUxXDA0NFwwMTVcMDQ1XDAxNFwwNDZcMDE2XDA0N1wwMzZcMDUwIiArCi0gICAgIlwwMzdcMDUxXDA0NFwwNTJcMDI1XDA1M1wwNTBcMDU0XDA0M1wwNTVcMDQxXDA1NlwwMzUiICsKLSAgICAiXDA1N1wwMzBcMDYwXDA0NVwwNjFcMDIxXDA2MlwwMTJcMDYzXDA0MlwwMDFcMDAyXDAwMCIgKwotICAgICJcMDY0XDAxM1wwMjdcMDE2XDAyMFwwMzJcMDMxXDAzM1wwNDBcMDM1XDAzNFwwMzZcMTEzIiArCi0gICAgIlwwMzdcMTQxXDA0MFwwNDdcMDQxXDA1MVwwNDRcMDE1XDA0NVwwMTRcMDQ2XDAxNlwwNDciICsKLSAgICAiXDAzNlwwNTBcMDM3XDA1MVwwNDRcMDUyXDAyNVwwNTNcMDUwXDA1NFwwNDNcMDU1XDA0MSIgKwotICAgICJcMDU2XDAzNVwwNTdcMDMwXDA2MFwwNDVcMDYxXDAyMVwwNjJcMDEyXDA2M1wwNDJcMDAxIiArCi0gICAgIlwwMDJcMDAwXDAwNlwwMDJcdWZmZjFcMDEwXHVmZmYxXDAwMVwwMDJcMDAwXDAwNlwwMDJcdWZmZjAiICsKLSAgICAiXDAxMFx1ZmZmMFwwMDFcMDAyXDAwMFwwMDZcMDAyXHVmZmY3XDAxMFx1ZmZmN1wwMDFcMDAyXDAwMCIgKwotICAgICJcMDE0XDAwMlx1ZmZlOVwwMDRcdWZmZTlcMDA2XDA1NVwwMTBcdWZmZTlcMDIxXHVmZmU5XDAwMVwwMDIiICsKLSAgICAiXDAwMFwwMTRcMDAyXHVmZmViXDAwNFx1ZmZlYlwwMDZcMDU1XDAxMFx1ZmZlYlwwMjFcdWZmZWJcMDAxIiArCi0gICAgIlwwMDJcMDAwXDAxMlwwMDJcdWZmZWFcMDA0XHVmZmVhXDAxMFx1ZmZlYVwwMjFcdWZmZWFcMDAxXDAwMiIgKwotICAgICJcMDAwXDAxMlwwMDJcdWZmZThcMDA0XHVmZmU4XDAxMFx1ZmZlOFwwMjFcdWZmZThcMDAxXDAwMlwwMDAiICsKLSAgICAiXDA2NFwwMTNcMDI3XDAxNlwwMjBcMDMyXDAzMVwwMzNcMDQwXDAzNVwwMzRcMDM2XDExMyIgKwotICAgICJcMDM3XDE0MVwwNDBcMDQ3XDA0MVwwNTFcMDQ0XDAxNVwwNDVcMDE0XDA0NlwwMTZcMDQ3IiArCi0gICAgIlwwMzZcMDUwXDAzN1wwNTFcMDQ0XDA1MlwwMjVcMDUzXDA1MFwwNTRcMDQzXDA1NVwwNDEiICsKLSAgICAiXDA1NlwwMzVcMDU3XDAzMFwwNjBcMDQ1XDA2MVwwMjFcMDYyXDAxMlwwNjNcMDQyXDAwMSIgKwotICAgICJcMDAyXDAwMFwwNjRcMDEzXDAyN1wwMTZcMDIwXDAzMlwwMzFcMDMzXDA0MFwwMzVcMDM0IiArCi0gICAgIlwwMzZcMTEzXDAzN1wxNDFcMDQwXDA0N1wwNDFcMDUxXDA0NFwwMTVcMDQ1XDAxNFwwNDYiICsKLSAgICAiXDAxNlwwNDdcMDM2XDA1MFwwMzdcMDUxXDA0NFwwNTJcMDI1XDA1M1wwNTBcMDU0XDA0MyIgKwotICAgICJcMDU1XDA0MVwwNTZcMDM1XDA1N1wwMzBcMDYwXDA0NVwwNjFcMDIxXDA2MlwwMTJcMDYzIiArCi0gICAgIlwwNDJcMDAxXDAwMlwwMDBcMDA2XDAwMlx1ZmZmOVwwMTBcdWZmZjlcMDAxXDAwMlwwMDBcMDA2IiArCi0gICAgIlwwMDJcdWZmZjhcMDEwXHVmZmY4XDAwMVwwMDJcMDAwXDAwNFwwMzRcMzAzXDAwMVwwMDJcMDAwIiArCi0gICAgIlwwMDRcMDEyXDMwNFwwMDFcMDAyXDAwMFwwMTRcMDAyXHVmZmYzXDAwNFx1ZmZmM1wwMDZcdWZmZjMiICsKLSAgICAiXDAxMFx1ZmZmM1wwMjFcdWZmZjNcMDAxXDAwMlwwMDBcMDA2XDAwMlx1ZmZmYlwwMTBcdWZmZmJcMDAxIiArCi0gICAgIlwwMDJcMDAwXDA3MFwwMDRcMDEzXDAxM1wwMjdcMDE2XDAyMFwwMjFcMDIzXDAzMlwwMzEiICsKLSAgICAiXDAzM1wwNDBcMDM1XDAzNFwwMzZcMDMzXDAzN1wwNDZcMDQwXDA0N1wwNDFcMDUxXDA0NCIgKwotICAgICJcMDE1XDA0NVwwMTRcMDQ2XDAxNlwwNDdcMDM2XDA1MFwwMzdcMDUxXDA0NFwwNTJcMDI1IiArCi0gICAgIlwwNTNcMDUwXDA1NFwwNDNcMDU1XDA0MVwwNTZcMDM1XDA1N1wwMzBcMDYwXDA0NVwwNjEiICsKLSAgICAiXDAyMVwwNjJcMDEyXDA2M1wwNDJcMDAxXDAwMlwwMDBcMDA0XDAwMlx1ZmZmZFwwMDFcMDAyIiArCi0gICAgIlwwMDBcMDA0XDAwMlx1ZmZmZlwwMDFcMDAyXDAwMFwwMDRcMDAyXDAwMVwwMDFcMDAyIiB9KTsKLQotICAvKiogQWNjZXNzIHRvIHBhcnNlLWFjdGlvbiB0YWJsZS4gKi8KLSAgcHVibGljIHNob3J0W11bXSBhY3Rpb25fdGFibGUoKSB7cmV0dXJuIF9hY3Rpb25fdGFibGU7fQotCi0gIC8qKiA8Y29kZT5yZWR1Y2VfZ290bzwvY29kZT4gdGFibGUuICovCi0gIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgc2hvcnRbXVtdIF9yZWR1Y2VfdGFibGUgPQotICAgIHVucGFja0Zyb21TdHJpbmdzKG5ldyBTdHJpbmdbXSB7Ci0gICAgIlwwMDBcMzA3XDAwMFwwMDRcMDAzXDAwM1wwMDFcMDAxXDAwMFwwMDJcMDAxXDAwMVwwMDAiICsKLSAgICAiXDA3MFwwMDRcMzA3XDAwNlwxMjBcMDEwXDEyN1wwMTFcMTE3XDAxMlwxMDFcMDEzXDA3NSIgKwotICAgICJcMDE0XDEwNFwwMTVcMDYzXDAxNlwxMTFcMDE3XDE0NVwwMjBcMTEzXDAyMVwxMjVcMDIyIiArCi0gICAgIlwwNzNcMDIzXDEyMVwwMjRcMTQzXDAyNVwxMjNcMDI2XDEzNlwwMjdcMTQ2XDAzMFwxMzQiICsKLSAgICAiXDAzMVwxMDdcMDMyXDA3MlwwMzNcMTA2XDAzNFwxNDdcMDQ3XDE1MFwwNTBcMTE2XDA1MiIgKwotICAgICJcMTAwXDA1M1wwNzdcMDAxXDAwMVwwMDBcMDI2XDAzNVwwMTZcMDM2XDAwN1wwMzdcMDA2IiArCi0gICAgIlwwNDBcMDMxXDA0MVwwMjVcMDQyXDAyM1wwNDNcMDUyXDA0NFwwMTBcMDQ3XDA1MVwwNTQiICsKLSAgICAiXDAyMVwwMDFcMDAxXDAwMFwwMDJcMDAxXDAwMVwwMDBcMDAyXDAwMVwwMDFcMDAwXDAwMiIgKwotICAgICJcMDAxXDAwMVwwMDBcMDAyXDAwMVwwMDFcMDAwXDAyMFwwNDBcMDMxXDA0MVwzMDRcMDQyIiArCi0gICAgIlwwMjNcMDQzXDA1MlwwNDRcMDEwXDA0N1wwNTFcMDU0XDAyMVwwMDFcMDAxXDAwMFwwMDIiICsKLSAgICAiXDAwMVwwMDFcMDAwXDAwMlwwMDFcMDAxXDAwMFwwMDJcMDAxXDAwMVwwMDBcMDAyXDAwMSIgKwotICAgICJcMDAxXDAwMFwwMDJcMDAxXDAwMVwwMDBcMDAyXDAwMVwwMDFcMDAwXDAxMlwwNDBcMjcxIiArCi0gICAgIlwwNDNcMjcyXDA0NFwwMTBcMDQ3XDA1MVwwMDFcMDAxXDAwMFwwMjBcMDQwXDAzMVwwNDEiICsKLSAgICAiXDI3MFwwNDJcMDIzXDA0M1wwNTJcMDQ0XDAxMFwwNDdcMDUxXDA1NFwwMjFcMDAxXDAwMSIgKwotICAgICJcMDAwXDAwMlwwMDFcMDAxXDAwMFwwMDJcMDAxXDAwMVwwMDBcMDAyXDAwMVwwMDFcMDAwIiArCi0gICAgIlwwMDJcMDAxXDAwMVwwMDBcMDAyXDAwMVwwMDFcMDAwXDAwMlwwMDFcMDAxXDAwMFwwMDYiICsKLSAgICAiXDAwN1wwNTNcMDQ1XDI2MlwwMDFcMDAxXDAwMFwwMDJcMDAxXDAwMVwwMDBcMDAyXDAwMSIgKwotICAgICJcMDAxXDAwMFwwMDJcMDAxXDAwMVwwMDBcMDAyXDAwMVwwMDFcMDAwXDAwMlwwMDFcMDAxIiArCi0gICAgIlwwMDBcMDAyXDAwMVwwMDFcMDAwXDAwMlwwMDFcMDAxXDAwMFwwMDJcMDAxXDAwMVwwMDAiICsKLSAgICAiXDAwMlwwMDFcMDAxXDAwMFwwMDJcMDAxXDAwMVwwMDBcMDAyXDAwMVwwMDFcMDAwXDAwMiIgKwotICAgICJcMDAxXDAwMVwwMDBcMDAyXDAwMVwwMDFcMDAwXDAwMlwwMDFcMDAxXDAwMFwwMDJcMDAxIiArCi0gICAgIlwwMDFcMDAwXDAwMlwwMDFcMDAxXDAwMFwwMDZcMDA3XDA1M1wwNDVcMDU1XDAwMVwwMDEiICsKLSAgICAiXDAwMFwwMDZcMDA3XDA1M1wwNDVcMjUwXDAwMVwwMDFcMDAwXDA3MFwwMDRcMTMyXDAwNiIgKwotICAgICJcMTIwXDAxMFwxMjdcMDExXDExN1wwMTJcMTAxXDAxM1wwNzVcMDE0XDEwNFwwMTVcMDYzIiArCi0gICAgIlwwMTZcMTExXDAxN1wxNDVcMDIwXDExM1wwMjFcMTI1XDAyMlwwNzNcMDIzXDEyMVwwMjQiICsKLSAgICAiXDE0M1wwMjVcMTIzXDAyNlwxMzZcMDI3XDE0NlwwMzBcMTM0XDAzMVwxMDdcMDMyXDA3MiIgKwotICAgICJcMDMzXDEwNlwwMzRcMTQ3XDA0N1wxNTBcMDUwXDExNlwwNTJcMTAwXDA1M1wwNzdcMDAxIiArCi0gICAgIlwwMDFcMDAwXDAwMlwwMDFcMDAxXDAwMFwwMDJcMDAxXDAwMVwwMDBcMDAyXDAwMVwwMDEiICsKLSAgICAiXDAwMFwwMjRcMDExXDExN1wwMjZcMTM2XDAyN1wyNDdcMDMwXDEzNFwwMzNcMTA2XDAzNCIgKwotICAgICJcMTQ3XDA0N1wxNTNcMDUyXDEwMFwwNTNcMDc3XDAwMVwwMDFcMDAwXDAwMlwwMDFcMDAxIiArCi0gICAgIlwwMDBcMDAyXDAwMVwwMDFcMDAwXDAwMlwwMDFcMDAxXDAwMFwwMDJcMDAxXDAwMVwwMDAiICsKLSAgICAiXDAwMlwwMDFcMDAxXDAwMFwwMDJcMDAxXDAwMVwwMDBcMDI0XDAxMVwxMTdcMDI2XDEzNiIgKwotICAgICJcMDI3XDI0M1wwMzBcMTM0XDAzM1wxMDZcMDM0XDE0N1wwNDdcMTUzXDA1MlwxMDBcMDUzIiArCi0gICAgIlwwNzdcMDAxXDAwMVwwMDBcMDcwXDAwNFwyNDFcMDA2XDEyMFwwMTBcMTI3XDAxMVwxMTciICsKLSAgICAiXDAxMlwxMDFcMDEzXDA3NVwwMTRcMTA0XDAxNVwwNjNcMDE2XDExMVwwMTdcMTQ1XDAyMCIgKwotICAgICJcMTEzXDAyMVwxMjVcMDIyXDA3M1wwMjNcMTIxXDAyNFwxNDNcMDI1XDEyM1wwMjZcMTM2IiArCi0gICAgIlwwMjdcMTQ2XDAzMFwxMzRcMDMxXDEwN1wwMzJcMDcyXDAzM1wxMDZcMDM0XDE0N1wwNDciICsKLSAgICAiXDE1MFwwNTBcMTE2XDA1MlwxMDBcMDUzXDA3N1wwMDFcMDAxXDAwMFwwMDJcMDAxXDAwMSIgKwotICAgICJcMDAwXDAwMlwwMDFcMDAxXDAwMFwwMDJcMDAxXDAwMVwwMDBcMDUyXDAwNlwxMjBcMDEwIiArCi0gICAgIlwxMjdcMDExXDExN1wwMjBcMjQwXDAyMVwxMjVcMDIyXDA3M1wwMjNcMTIxXDAyNFwxNDMiICsKLSAgICAiXDAyNVwxMjNcMDI2XDEzNlwwMjdcMTQ2XDAzMFwxMzRcMDMxXDEwN1wwMzJcMDcyXDAzMyIgKwotICAgICJcMTA2XDAzNFwxNDdcMDQ3XDE1MFwwNTBcMTE2XDA1MlwxMDBcMDUzXDA3N1wwMDFcMDAxIiArCi0gICAgIlwwMDBcMDAyXDAwMVwwMDFcMDAwXDAwMlwwMDFcMDAxXDAwMFwwMTBcMDMzXDIzNlwwMzQiICsKLSAgICAiXDE0N1wwNDdcMTUzXDAwMVwwMDFcMDAwXDAwMlwwMDFcMDAxXDAwMFwwMDJcMDAxXDAwMSIgKwotICAgICJcMDAwXDAwMlwwMDFcMDAxXDAwMFwwMDJcMDAxXDAwMVwwMDBcMDAyXDAwMVwwMDFcMDAwIiArCi0gICAgIlwwMDJcMDAxXDAwMVwwMDBcMDA2XDAwN1wwNTNcMDQ1XDIxNFwwMDFcMDAxXDAwMFwwMDIiICsKLSAgICAiXDAwMVwwMDFcMDAwXDAwMlwwMDFcMDAxXDAwMFwwMDJcMDAxXDAwMVwwMDBcMDAyXDAwMSIgKwotICAgICJcMDAxXDAwMFwwMDJcMDAxXDAwMVwwMDBcMDAyXDAwMVwwMDFcMDAwXDAwMlwwMDFcMDAxIiArCi0gICAgIlwwMDBcMDAyXDAwMVwwMDFcMDAwXDAwMlwwMDFcMDAxXDAwMFwwMDJcMDAxXDAwMVwwMDAiICsKLSAgICAiXDAwNlwwMDdcMDUzXDA0NVwxNzdcMDAxXDAwMVwwMDBcMDAyXDAwMVwwMDFcMDAwXDAwMiIgKwotICAgICJcMDAxXDAwMVwwMDBcMDAyXDAwMVwwMDFcMDAwXDAwMlwwMDFcMDAxXDAwMFwwMDJcMDAxIiArCi0gICAgIlwwMDFcMDAwXDAwMlwwMDFcMDAxXDAwMFwwMDJcMDAxXDAwMVwwMDBcMDAyXDAwMVwwMDEiICsKLSAgICAiXDAwMFwwMDJcMDAxXDAwMVwwMDBcMDA2XDA0N1wxNjRcMDUxXDE2NlwwMDFcMDAxXDAwMCIgKwotICAgICJcMDAyXDAwMVwwMDFcMDAwXDAwMlwwMDFcMDAxXDAwMFwwMDJcMDAxXDAwMVwwMDBcMDAyIiArCi0gICAgIlwwMDFcMDAxXDAwMFwwMDJcMDAxXDAwMVwwMDBcMDAyXDAwMVwwMDFcMDAwXDAwMlwwMDEiICsKLSAgICAiXDAwMVwwMDBcMDAyXDAwMVwwMDFcMDAwXDAwMlwwMDFcMDAxXDAwMFwwMDJcMDAxXDAwMSIgKwotICAgICJcMDAwXDAwMlwwMDFcMDAxXDAwMFwwMDJcMDAxXDAwMVwwMDBcMDAyXDAwMVwwMDFcMDAwIiArCi0gICAgIlwwMjBcMDExXDE1NVwwMjZcMTM2XDAzM1wxMDZcMDM0XDE0N1wwNDdcMTUzXDA1MlwxMDAiICsKLSAgICAiXDA1M1wwNzdcMDAxXDAwMVwwMDBcMDIwXDAxMVwxNTRcMDI2XDEzNlwwMzNcMTA2XDAzNCIgKwotICAgICJcMTQ3XDA0N1wxNTNcMDUyXDEwMFwwNTNcMDc3XDAwMVwwMDFcMDAwXDAwMlwwMDFcMDAxIiArCi0gICAgIlwwMDBcMDAyXDAwMVwwMDFcMDAwXDAwMlwwMDFcMDAxXDAwMFwwNTJcMDA2XDEyMFwwMTAiICsKLSAgICAiXDEyN1wwMTFcMTE3XDAyMFwxNjNcMDIxXDEyNVwwMjJcMDczXDAyM1wxMjFcMDI0XDE0MyIgKwotICAgICJcMDI1XDEyM1wwMjZcMTM2XDAyN1wxNDZcMDMwXDEzNFwwMzFcMTA3XDAzMlwwNzJcMDMzIiArCi0gICAgIlwxMDZcMDM0XDE0N1wwNDdcMTUwXDA1MFwxMTZcMDUyXDEwMFwwNTNcMDc3XDAwMVwwMDEiICsKLSAgICAiXDAwMFwwNTJcMDA2XDEyMFwwMTBcMTI3XDAxMVwxMTdcMDIwXDE2MlwwMjFcMTI1XDAyMiIgKwotICAgICJcMDczXDAyM1wxMjFcMDI0XDE0M1wwMjVcMTIzXDAyNlwxMzZcMDI3XDE0NlwwMzBcMTM0IiArCi0gICAgIlwwMzFcMTA3XDAzMlwwNzJcMDMzXDEwNlwwMzRcMTQ3XDA0N1wxNTBcMDUwXDExNlwwNTIiICsKLSAgICAiXDEwMFwwNTNcMDc3XDAwMVwwMDFcMDAwXDA1MlwwMDZcMTIwXDAxMFwxMjdcMDExXDExNyIgKwotICAgICJcMDIwXDE2MVwwMjFcMTI1XDAyMlwwNzNcMDIzXDEyMVwwMjRcMTQzXDAyNVwxMjNcMDI2IiArCi0gICAgIlwxMzZcMDI3XDE0NlwwMzBcMTM0XDAzMVwxMDdcMDMyXDA3MlwwMzNcMTA2XDAzNFwxNDciICsKLSAgICAiXDA0N1wxNTBcMDUwXDExNlwwNTJcMTAwXDA1M1wwNzdcMDAxXDAwMVwwMDBcMDAyXDAwMSIgKwotICAgICJcMDAxXDAwMFwwMDJcMDAxXDAwMVwwMDBcMDAyXDAwMVwwMDFcMDAwXDAwMlwwMDFcMDAxIiArCi0gICAgIlwwMDBcMDAyXDAwMVwwMDFcMDAwXDAwMlwwMDFcMDAxXDAwMFwwMDJcMDAxXDAwMVwwMDAiICsKLSAgICAiXDAwMlwwMDFcMDAxXDAwMFwwMjRcMDExXDExN1wwMjZcMTM2XDAyN1wxNzRcMDMwXDEzNCIgKwotICAgICJcMDMzXDEwNlwwMzRcMTQ3XDA0N1wxNTNcMDUyXDEwMFwwNTNcMDc3XDAwMVwwMDFcMDAwIiArCi0gICAgIlwwMjRcMDExXDExN1wwMjZcMTM2XDAyN1wxNzNcMDMwXDEzNFwwMzNcMTA2XDAzNFwxNDciICsKLSAgICAiXDA0N1wxNTNcMDUyXDEwMFwwNTNcMDc3XDAwMVwwMDFcMDAwXDAwMlwwMDFcMDAxXDAwMCIgKwotICAgICJcMDAyXDAwMVwwMDFcMDAwXDA1MFwwMDZcMTIwXDAxMFwxMjdcMDExXDExN1wwMjFcMTI1IiArCi0gICAgIlwwMjJcMDczXDAyM1wxMjFcMDI0XDE3NlwwMjVcMTIzXDAyNlwxMzZcMDI3XDE0NlwwMzAiICsKLSAgICAiXDEzNFwwMzFcMTA3XDAzMlwwNzJcMDMzXDEwNlwwMzRcMTQ3XDA0N1wxNTBcMDUwXDExNiIgKwotICAgICJcMDUyXDEwMFwwNTNcMDc3XDAwMVwwMDFcMDAwXDAwMlwwMDFcMDAxXDAwMFwwMDJcMDAxIiArCi0gICAgIlwwMDFcMDAwXDA3NFwwMDRcMjAzXDAwNVwyMDJcMDA2XDEyMFwwMTBcMTI3XDAxMVwxMTciICsKLSAgICAiXDAxMlwxMDFcMDEzXDA3NVwwMTRcMTA0XDAxNVwwNjNcMDE2XDExMVwwMTdcMTQ1XDAyMCIgKwotICAgICJcMTEzXDAyMVwxMjVcMDIyXDA3M1wwMjNcMTIxXDAyNFwxNDNcMDI1XDEyM1wwMjZcMTM2IiArCi0gICAgIlwwMjdcMTQ2XDAzMFwxMzRcMDMxXDEwN1wwMzJcMDcyXDAzM1wxMDZcMDM0XDE0N1wwNDYiICsKLSAgICAiXDIwNFwwNDdcMTUwXDA1MFwxMTZcMDUyXDEwMFwwNTNcMDc3XDAwMVwwMDFcMDAwXDAwMiIgKwotICAgICJcMDAxXDAwMVwwMDBcMDAyXDAwMVwwMDFcMDAwXDAwMlwwMDFcMDAxXDAwMFwwMDJcMDAxIiArCi0gICAgIlwwMDFcMDAwXDAwMlwwMDFcMDAxXDAwMFwwNzRcMDA0XDIwM1wwMDVcMjAyXDAwNlwxMjAiICsKLSAgICAiXDAxMFwxMjdcMDExXDExN1wwMTJcMTAxXDAxM1wwNzVcMDE0XDEwNFwwMTVcMDYzXDAxNiIgKwotICAgICJcMTExXDAxN1wxNDVcMDIwXDExM1wwMjFcMTI1XDAyMlwwNzNcMDIzXDEyMVwwMjRcMTQzIiArCi0gICAgIlwwMjVcMTIzXDAyNlwxMzZcMDI3XDE0NlwwMzBcMTM0XDAzMVwxMDdcMDMyXDA3MlwwMzMiICsKLSAgICAiXDEwNlwwMzRcMTQ3XDA0NlwyMDdcMDQ3XDE1MFwwNTBcMTE2XDA1MlwxMDBcMDUzXDA3NyIgKwotICAgICJcMDAxXDAwMVwwMDBcMDAyXDAwMVwwMDFcMDAwXDA1NFwwMDZcMTIwXDAxMFwxMjdcMDExIiArCi0gICAgIlwxMTdcMDE3XDIxM1wwMjBcMTEzXDAyMVwxMjVcMDIyXDA3M1wwMjNcMTIxXDAyNFwxNDMiICsKLSAgICAiXDAyNVwxMjNcMDI2XDEzNlwwMjdcMTQ2XDAzMFwxMzRcMDMxXDEwN1wwMzJcMDcyXDAzMyIgKwotICAgICJcMTA2XDAzNFwxNDdcMDQ3XDE1MFwwNTBcMTE2XDA1MlwxMDBcMDUzXDA3N1wwMDFcMDAxIiArCi0gICAgIlwwMDBcMDU0XDAwNlwxMjBcMDEwXDEyN1wwMTFcMTE3XDAxN1wyMTJcMDIwXDExM1wwMjEiICsKLSAgICAiXDEyNVwwMjJcMDczXDAyM1wxMjFcMDI0XDE0M1wwMjVcMTIzXDAyNlwxMzZcMDI3XDE0NiIgKwotICAgICJcMDMwXDEzNFwwMzFcMTA3XDAzMlwwNzJcMDMzXDEwNlwwMzRcMTQ3XDA0N1wxNTBcMDUwIiArCi0gICAgIlwxMTZcMDUyXDEwMFwwNTNcMDc3XDAwMVwwMDFcMDAwXDAwMlwwMDFcMDAxXDAwMFwwMDIiICsKLSAgICAiXDAwMVwwMDFcMDAwXDAwMlwwMDFcMDAxXDAwMFwwNjBcMDA2XDEyMFwwMTBcMTI3XDAxMSIgKwotICAgICJcMTE3XDAxNVwyMzBcMDE2XDExMVwwMTdcMTQ1XDAyMFwxMTNcMDIxXDEyNVwwMjJcMDczIiArCi0gICAgIlwwMjNcMTIxXDAyNFwxNDNcMDI1XDEyM1wwMjZcMTM2XDAyN1wxNDZcMDMwXDEzNFwwMzEiICsKLSAgICAiXDEwN1wwMzJcMDcyXDAzM1wxMDZcMDM0XDE0N1wwNDdcMTUwXDA1MFwxMTZcMDUyXDEwMCIgKwotICAgICJcMDUzXDA3N1wwMDFcMDAxXDAwMFwwNjBcMDA2XDEyMFwwMTBcMTI3XDAxMVwxMTdcMDE1IiArCi0gICAgIlwyMTdcMDE2XDExMVwwMTdcMTQ1XDAyMFwxMTNcMDIxXDEyNVwwMjJcMDczXDAyM1wxMjEiICsKLSAgICAiXDAyNFwxNDNcMDI1XDEyM1wwMjZcMTM2XDAyN1wxNDZcMDMwXDEzNFwwMzFcMTA3XDAzMiIgKwotICAgICJcMDcyXDAzM1wxMDZcMDM0XDE0N1wwNDdcMTUwXDA1MFwxMTZcMDUyXDEwMFwwNTNcMDc3IiArCi0gICAgIlwwMDFcMDAxXDAwMFwwMDJcMDAxXDAwMVwwMDBcMDU2XDAwNlwxMjBcMDEwXDEyN1wwMTEiICsKLSAgICAiXDExN1wwMTZcMjI3XDAxN1wxNDVcMDIwXDExM1wwMjFcMTI1XDAyMlwwNzNcMDIzXDEyMSIgKwotICAgICJcMDI0XDE0M1wwMjVcMTIzXDAyNlwxMzZcMDI3XDE0NlwwMzBcMTM0XDAzMVwxMDdcMDMyIiArCi0gICAgIlwwNzJcMDMzXDEwNlwwMzRcMTQ3XDA0N1wxNTBcMDUwXDExNlwwNTJcMTAwXDA1M1wwNzciICsKLSAgICAiXDAwMVwwMDFcMDAwXDA1NlwwMDZcMTIwXDAxMFwxMjdcMDExXDExN1wwMTZcMjI2XDAxNyIgKwotICAgICJcMTQ1XDAyMFwxMTNcMDIxXDEyNVwwMjJcMDczXDAyM1wxMjFcMDI0XDE0M1wwMjVcMTIzIiArCi0gICAgIlwwMjZcMTM2XDAyN1wxNDZcMDMwXDEzNFwwMzFcMTA3XDAzMlwwNzJcMDMzXDEwNlwwMzQiICsKLSAgICAiXDE0N1wwNDdcMTUwXDA1MFwxMTZcMDUyXDEwMFwwNTNcMDc3XDAwMVwwMDFcMDAwXDA1NiIgKwotICAgICJcMDA2XDEyMFwwMTBcMTI3XDAxMVwxMTdcMDE2XDIyNVwwMTdcMTQ1XDAyMFwxMTNcMDIxIiArCi0gICAgIlwxMjVcMDIyXDA3M1wwMjNcMTIxXDAyNFwxNDNcMDI1XDEyM1wwMjZcMTM2XDAyN1wxNDYiICsKLSAgICAiXDAzMFwxMzRcMDMxXDEwN1wwMzJcMDcyXDAzM1wxMDZcMDM0XDE0N1wwNDdcMTUwXDA1MCIgKwotICAgICJcMTE2XDA1MlwxMDBcMDUzXDA3N1wwMDFcMDAxXDAwMFwwNTZcMDA2XDEyMFwwMTBcMTI3IiArCi0gICAgIlwwMTFcMTE3XDAxNlwyMjRcMDE3XDE0NVwwMjBcMTEzXDAyMVwxMjVcMDIyXDA3M1wwMjMiICsKLSAgICAiXDEyMVwwMjRcMTQzXDAyNVwxMjNcMDI2XDEzNlwwMjdcMTQ2XDAzMFwxMzRcMDMxXDEwNyIgKwotICAgICJcMDMyXDA3MlwwMzNcMTA2XDAzNFwxNDdcMDQ3XDE1MFwwNTBcMTE2XDA1MlwxMDBcMDUzIiArCi0gICAgIlwwNzdcMDAxXDAwMVwwMDBcMDAyXDAwMVwwMDFcMDAwXDAwMlwwMDFcMDAxXDAwMFwwMDIiICsKLSAgICAiXDAwMVwwMDFcMDAwXDAwMlwwMDFcMDAxXDAwMFwwMDJcMDAxXDAwMVwwMDBcMDY0XDAwNiIgKwotICAgICJcMTIwXDAxMFwxMjdcMDExXDExN1wwMTNcMjMyXDAxNFwxMDRcMDE1XDA2M1wwMTZcMTExIiArCi0gICAgIlwwMTdcMTQ1XDAyMFwxMTNcMDIxXDEyNVwwMjJcMDczXDAyM1wxMjFcMDI0XDE0M1wwMjUiICsKLSAgICAiXDEyM1wwMjZcMTM2XDAyN1wxNDZcMDMwXDEzNFwwMzFcMTA3XDAzMlwwNzJcMDMzXDEwNiIgKwotICAgICJcMDM0XDE0N1wwNDdcMTUwXDA1MFwxMTZcMDUyXDEwMFwwNTNcMDc3XDAwMVwwMDFcMDAwIiArCi0gICAgIlwwMDJcMDAxXDAwMVwwMDBcMDYyXDAwNlwxMjBcMDEwXDEyN1wwMTFcMTE3XDAxNFwyMzQiICsKLSAgICAiXDAxNVwwNjNcMDE2XDExMVwwMTdcMTQ1XDAyMFwxMTNcMDIxXDEyNVwwMjJcMDczXDAyMyIgKwotICAgICJcMTIxXDAyNFwxNDNcMDI1XDEyM1wwMjZcMTM2XDAyN1wxNDZcMDMwXDEzNFwwMzFcMTA3IiArCi0gICAgIlwwMzJcMDcyXDAzM1wxMDZcMDM0XDE0N1wwNDdcMTUwXDA1MFwxMTZcMDUyXDEwMFwwNTMiICsKLSAgICAiXDA3N1wwMDFcMDAxXDAwMFwwMDJcMDAxXDAwMVwwMDBcMDAyXDAwMVwwMDFcMDAwXDAwNiIgKwotICAgICJcMDA3XDA1M1wwNDVcMjM3XDAwMVwwMDFcMDAwXDAwMlwwMDFcMDAxXDAwMFwwMDJcMDAxIiArCi0gICAgIlwwMDFcMDAwXDAwMlwwMDFcMDAxXDAwMFwwMDJcMDAxXDAwMVwwMDBcMDAyXDAwMVwwMDEiICsKLSAgICAiXDAwMFwwMDJcMDAxXDAwMVwwMDBcMDAyXDAwMVwwMDFcMDAwXDAwMlwwMDFcMDAxXDAwMCIgKwotICAgICJcMDAyXDAwMVwwMDFcMDAwXDAwMlwwMDFcMDAxXDAwMFwwMDJcMDAxXDAwMVwwMDBcMDAyIiArCi0gICAgIlwwMDFcMDAxXDAwMFwwMDJcMDAxXDAwMVwwMDBcMDAyXDAwMVwwMDFcMDAwXDAwMlwwMDEiICsKLSAgICAiXDAwMVwwMDBcMDAyXDAwMVwwMDFcMDAwXDAwMlwwMDFcMDAxXDAwMFwwMDJcMDAxXDAwMSIgKwotICAgICJcMDAwXDAwMlwwMDFcMDAxXDAwMFwwMDJcMDAxXDAwMVwwMDBcMDAyXDAwMVwwMDFcMDAwIiArCi0gICAgIlwwMjBcMDQwXDAzMVwwNDFcMjY3XDA0MlwwMjNcMDQzXDA1MlwwNDRcMDEwXDA0N1wwNTEiICsKLSAgICAiXDA1NFwwMjFcMDAxXDAwMVwwMDBcMDIwXDA0MFwwMzFcMDQxXDI2NlwwNDJcMDIzXDA0MyIgKwotICAgICJcMDUyXDA0NFwwMTBcMDQ3XDA1MVwwNTRcMDIxXDAwMVwwMDFcMDAwXDAwMlwwMDFcMDAxIiArCi0gICAgIlwwMDBcMDAyXDAwMVwwMDFcMDAwXDAwMlwwMDFcMDAxXDAwMFwwMDZcMDA3XDA1M1wwNDUiICsKLSAgICAiXDI3NFwwMDFcMDAxXDAwMFwwMDZcMDA3XDA1M1wwNDVcMjczXDAwMVwwMDFcMDAwXDAwMiIgKwotICAgICJcMDAxXDAwMVwwMDBcMDAyXDAwMVwwMDFcMDAwXDAyMFwwNDBcMDMxXDA0MVwzMDBcMDQyIiArCi0gICAgIlwwMjNcMDQzXDA1MlwwNDRcMDEwXDA0N1wwNTFcMDU0XDAyMVwwMDFcMDAxXDAwMFwwMjAiICsKLSAgICAiXDA0MFwwMzFcMDQxXDI3N1wwNDJcMDIzXDA0M1wwNTJcMDQ0XDAxMFwwNDdcMDUxXDA1NCIgKwotICAgICJcMDIxXDAwMVwwMDFcMDAwXDAwMlwwMDFcMDAxXDAwMFwwMDJcMDAxXDAwMVwwMDBcMDAyIiArCi0gICAgIlwwMDFcMDAxXDAwMFwwMDJcMDAxXDAwMVwwMDBcMDAyXDAwMVwwMDFcMDAwXDAwMlwwMDEiICsKLSAgICAiXDAwMVwwMDBcMDI2XDAzNVwwMTZcMDM2XDMwNlwwMzdcMDA2XDA0MFwwMzFcMDQxXDAyNSIgKwotICAgICJcMDQyXDAyM1wwNDNcMDUyXDA0NFwwMTBcMDQ3XDA1MVwwNTRcMDIxXDAwMVwwMDFcMDAwIiArCi0gICAgIlwwMDJcMDAxXDAwMVwwMDBcMDAyXDAwMVwwMDFcMDAwXDAwMlwwMDFcMDAxIiB9KTsKLQotICAvKiogQWNjZXNzIHRvIDxjb2RlPnJlZHVjZV9nb3RvPC9jb2RlPiB0YWJsZS4gKi8KLSAgcHVibGljIHNob3J0W11bXSByZWR1Y2VfdGFibGUoKSB7cmV0dXJuIF9yZWR1Y2VfdGFibGU7fQotCi0gIC8qKiBJbnN0YW5jZSBvZiBhY3Rpb24gZW5jYXBzdWxhdGlvbiBjbGFzcy4gKi8KLSAgcHJvdGVjdGVkIENVUCRYUGF0aFBhcnNlciRhY3Rpb25zIGFjdGlvbl9vYmo7Ci0KLSAgLyoqIEFjdGlvbiBlbmNhcHN1bGF0aW9uIG9iamVjdCBpbml0aWFsaXplci4gKi8KLSAgcHJvdGVjdGVkIHZvaWQgaW5pdF9hY3Rpb25zKCkKLSAgICB7Ci0gICAgICBhY3Rpb25fb2JqID0gbmV3IENVUCRYUGF0aFBhcnNlciRhY3Rpb25zKHRoaXMpOwotICAgIH0KLQotICAvKiogSW52b2tlIGEgdXNlciBzdXBwbGllZCBwYXJzZSBhY3Rpb24uICovCi0gIHB1YmxpYyBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sIGRvX2FjdGlvbigKLSAgICBpbnQgICAgICAgICAgICAgICAgICAgICAgICBhY3RfbnVtLAotICAgIGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5scl9wYXJzZXIgcGFyc2VyLAotICAgIGphdmEudXRpbC5TdGFjayAgICAgICAgICAgIHN0YWNrLAotICAgIGludCAgICAgICAgICAgICAgICAgICAgICAgIHRvcCkKLSAgICB0aHJvd3MgamF2YS5sYW5nLkV4Y2VwdGlvbgotICB7Ci0gICAgLyogY2FsbCBjb2RlIGluIGdlbmVyYXRlZCBjbGFzcyAqLwotICAgIHJldHVybiBhY3Rpb25fb2JqLkNVUCRYUGF0aFBhcnNlciRkb19hY3Rpb24oYWN0X251bSwgcGFyc2VyLCBzdGFjaywgdG9wKTsKLSAgfQotCi0gIC8qKiBJbmRpY2F0ZXMgc3RhcnQgc3RhdGUuICovCi0gIHB1YmxpYyBpbnQgc3RhcnRfc3RhdGUoKSB7cmV0dXJuIDA7fQotICAvKiogSW5kaWNhdGVzIHN0YXJ0IHByb2R1Y3Rpb24uICovCi0gIHB1YmxpYyBpbnQgc3RhcnRfcHJvZHVjdGlvbigpIHtyZXR1cm4gMDt9Ci0KLSAgLyoqIDxjb2RlPkVPRjwvY29kZT4gU3ltYm9sIGluZGV4LiAqLwotICBwdWJsaWMgaW50IEVPRl9zeW0oKSB7cmV0dXJuIDA7fQotCi0gIC8qKiA8Y29kZT5lcnJvcjwvY29kZT4gU3ltYm9sIGluZGV4LiAqLwotICBwdWJsaWMgaW50IGVycm9yX3N5bSgpIHtyZXR1cm4gMTt9Ci0KLQotCi0gICAgLyoqCi0gICAgICogVXNlZCBieSBmdW5jdGlvbiBjYWxscyB3aXRoIG5vIGFyZ3MuCi0gICAgICovCi0gICAgc3RhdGljIHB1YmxpYyBmaW5hbCBWZWN0b3IgRW1wdHlBcmdzID0gbmV3IFZlY3RvcigwKTsKLQotICAgIC8qKgotICAgICAqIFJlZmVyZW5jZSB0byBub24tZXhpc3RpbmcgdmFyaWFibGUuCi0gICAgICovCi0gICAgc3RhdGljIHB1YmxpYyBmaW5hbCBWYXJpYWJsZVJlZiBEdW1teVZhclJlZiA9IG51bGw7Ci0KLSAgICAvKioKLSAgICAgKiBSZWZlcmVuY2UgdG8gdGhlIFBhcnNlciBjbGFzcy4KLSAgICAgKi8KLSAgICBwcml2YXRlIFBhcnNlciBfcGFyc2VyOwotICAgIHByaXZhdGUgWFNMVEMgIF94c2x0YzsKLQotICAgIC8qKgotICAgICAqIFN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgZXhwcmVzc2lvbiBiZWluZyBwYXJzZWQuCi0gICAgICovCi0gICAgcHJpdmF0ZSBTdHJpbmcgX2V4cHJlc3Npb247Ci0KLSAgICAvKioKLSAgICAgKiBMaW5lIG51bWJlciB3aGVyZSB0aGlzIGV4cHJlc3Npb24vcGF0dGVybiB3YXMgZGVjbGFyZWQuCi0gICAgICovCi0gICAgcHJpdmF0ZSBpbnQgX2xpbmVOdW1iZXIgPSAwOwotCi0gICAgLyoqCi0gICAgICogUmVmZXJlbmNlIHRvIHRoZSBzeW1ib2wgdGFibGUuCi0gICAgICovCi0gICAgcHVibGljIFN5bWJvbFRhYmxlIF9zeW1ib2xUYWJsZTsKLQotICAgIHB1YmxpYyBYUGF0aFBhcnNlcihQYXJzZXIgcGFyc2VyKSB7Ci0gICAgICAgIF9wYXJzZXIgPSBwYXJzZXI7Ci0gICAgICAgIF94c2x0YyA9IHBhcnNlci5nZXRYU0xUQygpOwotICAgICAgICBfc3ltYm9sVGFibGUgPSBwYXJzZXIuZ2V0U3ltYm9sVGFibGUoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldExpbmVOdW1iZXIoKSB7Ci0gICAgICAgIHJldHVybiBfbGluZU51bWJlcjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgUU5hbWUgZ2V0UU5hbWVJZ25vcmVEZWZhdWx0TnMoU3RyaW5nIG5hbWUpIHsKLSAgICAgICAgICByZXR1cm4gX3BhcnNlci5nZXRRTmFtZUlnbm9yZURlZmF1bHROcyhuYW1lKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgUU5hbWUgZ2V0UU5hbWUoU3RyaW5nIG5hbWVzcGFjZSwgU3RyaW5nIHByZWZpeCwgU3RyaW5nIGxvY2FsbmFtZSkgewotICAgICAgICByZXR1cm4gX3BhcnNlci5nZXRRTmFtZShuYW1lc3BhY2UsIHByZWZpeCwgbG9jYWxuYW1lKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRNdWx0aURvY3VtZW50KGJvb2xlYW4gZmxhZykgewotICAgICAgICAgIF94c2x0Yy5zZXRNdWx0aURvY3VtZW50KGZsYWcpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldENhbGxzTm9kZXNldChib29sZWFuIGZsYWcpIHsKLSAgICAgICAgICBfeHNsdGMuc2V0Q2FsbHNOb2Rlc2V0KGZsYWcpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldEhhc0lkQ2FsbChib29sZWFuIGZsYWcpIHsKLSAgICAgICAgICBfeHNsdGMuc2V0SGFzSWRDYWxsKGZsYWcpOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgaXMgc2ltaWxhciB0byBmaW5kTm9kZVR5cGUoaW50LCBPYmplY3QpIGV4Y2VwdCB0aGF0IGl0Ci0gICAgICogY3JlYXRlcyBhIFN0ZXBQYXR0ZXJuIGluc3RlYWQgb2YganVzdCByZXR1cm5pbmcgYSBub2RlIHR5cGUuIEl0IGFsc28KLSAgICAgKiBkaWZmZXJzIGluIHRoZSB3YXkgaXQgaGFuZGxlcyAie3VyaX06KiIgYW5kICJ7dXJpfTpAKiIuIFRoZSBsYXN0IHR3bwotICAgICAqIHBhdHRlcm5zIGFyZSBleHBhbmRlZCBhcyAiKltuYW1lc3BhY2UtdXJpKCkgPSAndXJpJ10iIGFuZAotICAgICAqICJAKltuYW1lc3BhY2UtdXJpKCkgPSAndXJpJ10iLCByZXNwZWN0aXZlbHkuIFRoaXMgZXhwYW5zaW9uIGNvbnNpZGVyYWJseQotICAgICAqIHNpbXBsaWZpZXMgdGhlIGdyb3VwaW5nIG9mIHBhdHRlcm5zIGluIHRoZSBNb2RlIGNsYXNzLiBGb3IgdGhpcwotICAgICAqIGV4cGFuc2lvbiB0byBiZSBjb3JyZWN0LCB0aGUgcHJpb3JpdHkgb2YgdGhlIHBhdHRlcm4vdGVtcGxhdGUgbXVzdCBiZQotICAgICAqIHNldCB0byAtMC4yNSAod2hlbiBubyBvdGhlciBwcmVkaWNhdGVzIGFyZSBwcmVzZW50KS4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RlcFBhdHRlcm4gY3JlYXRlU3RlcFBhdHRlcm4oaW50IGF4aXMsIE9iamVjdCB0ZXN0LCBWZWN0b3IgcHJlZGljYXRlcykgewotICAgICAgICBpbnQgbm9kZVR5cGU7Ci0KLSAgICAgICAgaWYgKHRlc3QgPT0gbnVsbCkgeyAgLy8gIioiCi0gICAgICAgICAgICBub2RlVHlwZSA9IChheGlzID09IEF4aXMuQVRUUklCVVRFKSA/IE5vZGVUZXN0LkFUVFJJQlVURSA6Ci0gICAgICAgICAgICAgICAgKGF4aXMgPT0gQXhpcy5OQU1FU1BBQ0UpID8gLTEgOiBOb2RlVGVzdC5FTEVNRU5UOwotCi0gICAgICAgICAgICByZXR1cm4gbmV3IFN0ZXBQYXR0ZXJuKGF4aXMsIG5vZGVUeXBlLCBwcmVkaWNhdGVzKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICh0ZXN0IGluc3RhbmNlb2YgSW50ZWdlcikgewotICAgICAgICAgICAgbm9kZVR5cGUgPSAoKEludGVnZXIpIHRlc3QpLmludFZhbHVlKCk7Ci0KLSAgICAgICAgICAgIHJldHVybiBuZXcgU3RlcFBhdHRlcm4oYXhpcywgbm9kZVR5cGUsIHByZWRpY2F0ZXMpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgUU5hbWUgbmFtZSA9IChRTmFtZSl0ZXN0OwotICAgICAgICAgICAgYm9vbGVhbiBzZXRQcmlvcml0eSA9IGZhbHNlOwotCi0gICAgICAgICAgICBpZiAoYXhpcyA9PSBBeGlzLk5BTUVTUEFDRSkgewotICAgICAgICAgICAgICAgIG5vZGVUeXBlID0gKG5hbWUudG9TdHJpbmcoKS5lcXVhbHMoIioiKSkgPyAtMQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IF94c2x0Yy5yZWdpc3Rlck5hbWVzcGFjZVByZWZpeChuYW1lKTs7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgdXJpID0gbmFtZS5nZXROYW1lc3BhY2UoKTsKLSAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgbG9jYWwgPSBuYW1lLmdldExvY2FsUGFydCgpOwotICAgICAgICAgICAgICAgIGZpbmFsIFFOYW1lIG5hbWVzcGFjZV91cmkgPQotICAgICAgICAgICAgICAgICAgICBfcGFyc2VyLmdldFFOYW1lSWdub3JlRGVmYXVsdE5zKCJuYW1lc3BhY2UtdXJpIik7Ci0KLSAgICAgICAgICAgICAgICAvLyBFeHBhbmQge3VyaX06KiB0byAqW25hbWVzcGFjZS11cmkoKSA9ICd1cmknXSAtIHNhbWUgZm9yIEAqCi0gICAgICAgICAgICAgICAgaWYgKHVyaSAhPSBudWxsICYmIChsb2NhbC5lcXVhbHMoIioiKSB8fCBsb2NhbC5lcXVhbHMoIkAqIikpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChwcmVkaWNhdGVzID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHByZWRpY2F0ZXMgPSBuZXcgVmVjdG9yKDIpOwotICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgLy8gUHJpb3JpdHkgaXMgc2V0IGJ5IGhhbmQgaWYgbm8gb3RoZXIgcHJlZGljYXRlcyBleGlzdAotICAgICAgICAgICAgICAgICAgICBzZXRQcmlvcml0eSA9IChwcmVkaWNhdGVzLnNpemUoKSA9PSAwKTsKLQotICAgICAgICAgICAgICAgICAgICBwcmVkaWNhdGVzLmFkZCgKLSAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBQcmVkaWNhdGUoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IEVxdWFsaXR5RXhwcihPcGVyYXRvcnMuRVEsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBOYW1lc3BhY2VVcmlDYWxsKG5hbWVzcGFjZV91cmkpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgTGl0ZXJhbEV4cHIodXJpKSkpKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBpZiAobG9jYWwuZXF1YWxzKCIqIikpIHsKLSAgICAgICAgICAgICAgICAgICAgbm9kZVR5cGUgPSAoYXhpcyA9PSBBeGlzLkFUVFJJQlVURSkgPyBOb2RlVGVzdC5BVFRSSUJVVEUKLSAgICAgICAgICAgICAgICAgICAgICAgIDogTm9kZVRlc3QuRUxFTUVOVDsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSBpZiAobG9jYWwuZXF1YWxzKCJAKiIpKSB7Ci0gICAgICAgICAgICAgICAgICAgIG5vZGVUeXBlID0gTm9kZVRlc3QuQVRUUklCVVRFOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgbm9kZVR5cGUgPSAoYXhpcyA9PSBBeGlzLkFUVFJJQlVURSkgPyBfeHNsdGMucmVnaXN0ZXJBdHRyaWJ1dGUobmFtZSkKLSAgICAgICAgICAgICAgICAgICAgICAgIDogX3hzbHRjLnJlZ2lzdGVyRWxlbWVudChuYW1lKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGZpbmFsIFN0ZXBQYXR0ZXJuIHJlc3VsdCA9IG5ldyBTdGVwUGF0dGVybihheGlzLCBub2RlVHlwZSwgcHJlZGljYXRlcyk7Ci0KLSAgICAgICAgICAgIC8vIFNldCBwcmlvcml0eSBmb3IgY2FzZSBwcmVmaXg6KiBhbmQgcHJlZml4OkAqIChubyBwcmVkaWNhdGVzKQotICAgICAgICAgICAgaWYgKHNldFByaW9yaXR5KSB7Ci0gICAgICAgICAgICAgICAgcmVzdWx0LnNldFByaW9yaXR5KC0wLjI1KTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgZmluZE5vZGVUeXBlKGludCBheGlzLCBPYmplY3QgdGVzdCkgewotICAgICAgICBpZiAodGVzdCA9PSBudWxsKSB7ICAvLyAqCi0gICAgICAgICAgICByZXR1cm4gKGF4aXMgPT0gQXhpcy5BVFRSSUJVVEUpID8KLSAgICAgICAgICAgICAgICBOb2RlVGVzdC5BVFRSSUJVVEUgOgotICAgICAgICAgICAgICAgIChheGlzID09IEF4aXMuTkFNRVNQQUNFKSA/IC0xIDogTm9kZVRlc3QuRUxFTUVOVDsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICh0ZXN0IGluc3RhbmNlb2YgSW50ZWdlcikgewotICAgICAgICAgICAgcmV0dXJuICgoSW50ZWdlcil0ZXN0KS5pbnRWYWx1ZSgpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgUU5hbWUgbmFtZSA9IChRTmFtZSl0ZXN0OwotCi0gICAgICAgICAgICBpZiAoYXhpcyA9PSBBeGlzLk5BTUVTUEFDRSkgewotICAgICAgICAgICAgICAgIHJldHVybiAobmFtZS50b1N0cmluZygpLmVxdWFscygiKiIpKSA/IC0xCi0gICAgICAgICAgICAgICAgICAgIDogX3hzbHRjLnJlZ2lzdGVyTmFtZXNwYWNlUHJlZml4KG5hbWUpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAobmFtZS5nZXROYW1lc3BhY2UoKSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIGxvY2FsID0gbmFtZS5nZXRMb2NhbFBhcnQoKTsKLQotICAgICAgICAgICAgICAgIGlmIChsb2NhbC5lcXVhbHMoIioiKSkgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gKGF4aXMgPT0gQXhpcy5BVFRSSUJVVEUpID8gTm9kZVRlc3QuQVRUUklCVVRFCi0gICAgICAgICAgICAgICAgICAgICAgICA6IE5vZGVUZXN0LkVMRU1FTlQ7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgaWYgKGxvY2FsLmVxdWFscygiQCoiKSkgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gTm9kZVRlc3QuQVRUUklCVVRFOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgcmV0dXJuIChheGlzID09IEF4aXMuQVRUUklCVVRFKSA/IF94c2x0Yy5yZWdpc3RlckF0dHJpYnV0ZShuYW1lKQotICAgICAgICAgICAgICAgIDogX3hzbHRjLnJlZ2lzdGVyRWxlbWVudChuYW1lKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFBhcnNlIHRoZSBleHByZXNzaW9uIHBhc3NlZCB0byB0aGUgY3VycmVudCBzY2FubmVyLiBJZiB0aGlzCi0gICAgICogZXhwcmVzc2lvbiBjb250YWlucyByZWZlcmVuY2VzIHRvIGxvY2FsIHZhcmlhYmxlcyBhbmQgaXQgd2lsbCBiZQotICAgICAqIGNvbXBpbGVkIGluIGFuIGV4dGVybmFsIG1vZHVsZSAobm90IGluIHRoZSBtYWluIGNsYXNzKSByZXF1ZXN0Ci0gICAgICogdGhlIGN1cnJlbnQgdGVtcGxhdGUgdG8gY3JlYXRlIGEgbmV3IHZhcmlhYmxlIHN0YWNrIGZyYW1lLgotICAgICAqCi0gICAgICogQHBhcmFtIGxpbmVOdW1iZXIgTGluZSB3aGVyZSB0aGUgY3VycmVudCBleHByZXNzaW9uIGlzIGRlZmluZWQuCi0gICAgICogQHBhcmFtIGV4dGVybmFsICAgU2V0IHRvIDx0dD50cnVlPC90dD4gaWYgdGhpcyBleHByZXNzaW9uIGlzCi0gICAgICogICAgICAgICAgICAgICAgICAgY29tcGlsZWQgaW4gYSBzZXBhcmF0ZSBtb2R1bGUuCi0gICAgICoKLSAgICAgKi8KLSAgICBwdWJsaWMgU3ltYm9sIHBhcnNlKFN0cmluZyBleHByZXNzaW9uLCBpbnQgbGluZU51bWJlcikgdGhyb3dzIEV4Y2VwdGlvbiB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBfZXhwcmVzc2lvbiA9IGV4cHJlc3Npb247Ci0gICAgICAgICAgICBfbGluZU51bWJlciA9IGxpbmVOdW1iZXI7Ci0gICAgICAgICAgICByZXR1cm4gc3VwZXIucGFyc2UoKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoSWxsZWdhbENoYXJFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgRXJyb3JNc2cgZXJyID0gbmV3IEVycm9yTXNnKEVycm9yTXNnLklMTEVHQUxfQ0hBUl9FUlIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGluZU51bWJlciwgZS5nZXRNZXNzYWdlKCkpOwotICAgICAgICAgICAgX3BhcnNlci5yZXBvcnRFcnJvcihDb25zdGFudHMuRkFUQUwsIGVycik7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogTG9va3VwIGEgdmFyaWFibGUgb3IgcGFyYW1ldGVyIGluIHRoZSBzeW1ib2wgdGFibGUgZ2l2ZW4gaXRzIG5hbWUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSBOYW1lIG9mIHRoZSBzeW1ib2wgYmVpbmcgbG9va2VkIHVwLgotICAgICAqLwotICAgIGZpbmFsIFN5bnRheFRyZWVOb2RlIGxvb2t1cE5hbWUoUU5hbWUgbmFtZSkgewotICAgICAgICAvLyBJcyBpdCBhIGxvY2FsIHZhciBvciBwYXJhbSA/Ci0gICAgICAgIGZpbmFsIFN5bnRheFRyZWVOb2RlIHJlc3VsdCA9IF9wYXJzZXIubG9va3VwVmFyaWFibGUobmFtZSk7Ci0gICAgICAgIGlmIChyZXN1bHQgIT0gbnVsbCkKLSAgICAgICAgICAgIHJldHVybihyZXN1bHQpOwotICAgICAgICBlbHNlCi0gICAgICAgICAgICByZXR1cm4oX3N5bWJvbFRhYmxlLmxvb2t1cE5hbWUobmFtZSkpOwotICAgIH0KLQotICAgIHB1YmxpYyBmaW5hbCB2b2lkIGFkZEVycm9yKEVycm9yTXNnIGVycm9yKSB7Ci0gICAgICAgIF9wYXJzZXIucmVwb3J0RXJyb3IoQ29uc3RhbnRzLkVSUk9SLCBlcnJvcik7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgcmVwb3J0X2Vycm9yKFN0cmluZyBtZXNzYWdlLCBPYmplY3QgaW5mbykgewotICAgICAgICBmaW5hbCBFcnJvck1zZyBlcnIgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuU1lOVEFYX0VSUiwgX2xpbmVOdW1iZXIsCi0gICAgICAgICAgICBfZXhwcmVzc2lvbik7Ci0gICAgICAgIF9wYXJzZXIucmVwb3J0RXJyb3IoQ29uc3RhbnRzLkZBVEFMLCBlcnIpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHJlcG9ydF9mYXRhbF9lcnJvcihTdHJpbmcgbWVzc2FnZSwgT2JqZWN0IGluZm8pIHsKLSAgICAgICAgLy8gZW1wdHkKLSAgICB9Ci0KLSAgICBwdWJsaWMgUmVsYXRpdmVMb2NhdGlvblBhdGggaW5zZXJ0U3RlcChTdGVwIHN0ZXAsIFJlbGF0aXZlTG9jYXRpb25QYXRoIHJscCkgewotICAgICAgICBpZiAocmxwIGluc3RhbmNlb2YgU3RlcCkgewotICAgICAgICAgICAgcmV0dXJuIG5ldyBQYXJlbnRMb2NhdGlvblBhdGgoc3RlcCwgKFN0ZXApIHJscCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAocmxwIGluc3RhbmNlb2YgUGFyZW50TG9jYXRpb25QYXRoKSB7Ci0gICAgICAgICAgICBmaW5hbCBQYXJlbnRMb2NhdGlvblBhdGggcGxwID0gKFBhcmVudExvY2F0aW9uUGF0aCkgcmxwOwotICAgICAgICAgICAgZmluYWwgUmVsYXRpdmVMb2NhdGlvblBhdGggbmV3cmxwID0gaW5zZXJ0U3RlcChzdGVwLCBwbHAuZ2V0UGF0aCgpKTsKLSAgICAgICAgICAgIHJldHVybiBuZXcgUGFyZW50TG9jYXRpb25QYXRoKG5ld3JscCwgcGxwLmdldFN0ZXAoKSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBhZGRFcnJvcihuZXcgRXJyb3JNc2coRXJyb3JNc2cuSU5URVJOQUxfRVJSLCAiWFBhdGhQYXJzZXIuaW5zZXJ0U3RlcCIpKTsKLSAgICAgICAgICAgIHJldHVybiBybHA7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIGF4aXMgYXBwbGllcyB0byBlbGVtZW50cyBvbmx5LiBUaGUgYXhlcwotICAgICAqIGNoaWxkLCBhdHRyaWJ1dGUsIG5hbWVzcGFjZSwgZGVzY2VuZGFudCByZXN1bHQgaW4gbm9uLWVtcHR5Ci0gICAgICogbm9kZXNldHMgb25seSBpZiB0aGUgY29udGV4dCBub2RlIGlzIG9mIHR5cGUgZWxlbWVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0VsZW1lbnRBeGlzKGludCBheGlzKSB7Ci0gICAgICAgIHJldHVybiAoYXhpcyA9PSBBeGlzLkNISUxEIHx8IGF4aXMgPT0gQXhpcy5BVFRSSUJVVEUgfHwKLSAgICAgICAgICAgICAgICBheGlzID09IEF4aXMuTkFNRVNQQUNFIHx8IGF4aXMgPT0gQXhpcy5ERVNDRU5EQU5UKTsKLSAgICB9Ci0KLX0KLQotLyoqIEN1cCBnZW5lcmF0ZWQgY2xhc3MgdG8gZW5jYXBzdWxhdGUgdXNlciBzdXBwbGllZCBhY3Rpb24gY29kZS4qLwotY2xhc3MgQ1VQJFhQYXRoUGFyc2VyJGFjdGlvbnMgewotICBwcml2YXRlIGZpbmFsIFhQYXRoUGFyc2VyIHBhcnNlcjsKLQotICAvKiogQ29uc3RydWN0b3IgKi8KLSAgQ1VQJFhQYXRoUGFyc2VyJGFjdGlvbnMoWFBhdGhQYXJzZXIgcGFyc2VyKSB7Ci0gICAgdGhpcy5wYXJzZXIgPSBwYXJzZXI7Ci0gIH0KLQotICAvKiogTWV0aG9kIHdpdGggdGhlIGFjdHVhbCBnZW5lcmF0ZWQgYWN0aW9uIGNvZGUuICovCi0gIHB1YmxpYyBmaW5hbCBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sIENVUCRYUGF0aFBhcnNlciRkb19hY3Rpb24oCi0gICAgaW50ICAgICAgICAgICAgICAgICAgICAgICAgQ1VQJFhQYXRoUGFyc2VyJGFjdF9udW0sCi0gICAgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLmxyX3BhcnNlciBDVVAkWFBhdGhQYXJzZXIkcGFyc2VyLAotICAgIGphdmEudXRpbC5TdGFjayAgICAgICAgICAgIENVUCRYUGF0aFBhcnNlciRzdGFjaywKLSAgICBpbnQgICAgICAgICAgICAgICAgICAgICAgICBDVVAkWFBhdGhQYXJzZXIkdG9wKQotICAgIHRocm93cyBqYXZhLmxhbmcuRXhjZXB0aW9uCi0gICAgewotICAgICAgLyogU3ltYm9sIG9iamVjdCBmb3IgcmV0dXJuIGZyb20gYWN0aW9ucyAqLwotICAgICAgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0OwotCi0gICAgICAvKiBzZWxlY3QgdGhlIGFjdGlvbiBiYXNlZCBvbiB0aGUgYWN0aW9uIG51bWJlciAqLwotICAgICAgc3dpdGNoIChDVVAkWFBhdGhQYXJzZXIkYWN0X251bSkKLSAgICAgICAgewotICAgICAgICAgIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuKi8KLSAgICAgICAgICBjYXNlIDE0MDogLy8gUU5hbWUgOjo9IElECi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIFFOYW1lIFJFU1VMVCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgIFJFU1VMVCA9IHBhcnNlci5nZXRRTmFtZUlnbm9yZURlZmF1bHROcygiaWQiKTsKLSAgICAgICAgICAgICAgQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdCA9IG5ldyBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKDM3LypRTmFtZSovLCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0LCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodCwgUkVTVUxUKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICByZXR1cm4gQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdDsKLQotICAgICAgICAgIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuKi8KLSAgICAgICAgICBjYXNlIDEzOTogLy8gUU5hbWUgOjo9IFNFTEYKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgUU5hbWUgUkVTVUxUID0gbnVsbDsKLSAgICAgICAgICAgICAgICAgUkVTVUxUID0gcGFyc2VyLmdldFFOYW1lSWdub3JlRGVmYXVsdE5zKCJzZWxmIik7Ci0gICAgICAgICAgICAgIENVUCRYUGF0aFBhcnNlciRyZXN1bHQgPSBuZXcgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCgzNy8qUU5hbWUqLywgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkubGVmdCwgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQsIFJFU1VMVCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgcmV0dXJuIENVUCRYUGF0aFBhcnNlciRyZXN1bHQ7Ci0KLSAgICAgICAgICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0gICAgICAgICAgY2FzZSAxMzg6IC8vIFFOYW1lIDo6PSBQUkVDRURJTkdTSUJMSU5HCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIFFOYW1lIFJFU1VMVCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgIFJFU1VMVCA9IHBhcnNlci5nZXRRTmFtZUlnbm9yZURlZmF1bHROcygicHJlY2VkaW5nLXNpYmxpbmciKTsKLSAgICAgICAgICAgICAgQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdCA9IG5ldyBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKDM3LypRTmFtZSovLCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0LCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodCwgUkVTVUxUKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICByZXR1cm4gQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdDsKLQotICAgICAgICAgIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuKi8KLSAgICAgICAgICBjYXNlIDEzNzogLy8gUU5hbWUgOjo9IFBSRUNFRElORwotICAgICAgICAgICAgewotICAgICAgICAgICAgICBRTmFtZSBSRVNVTFQgPSBudWxsOwotICAgICAgICAgICAgICAgICBSRVNVTFQgPSBwYXJzZXIuZ2V0UU5hbWVJZ25vcmVEZWZhdWx0TnMoInByZWNlZGluZyIpOwotICAgICAgICAgICAgICBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0ID0gbmV3IGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2woMzcvKlFOYW1lKi8sICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLmxlZnQsICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0LCBSRVNVTFQpOwotICAgICAgICAgICAgfQotICAgICAgICAgIHJldHVybiBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0OwotCi0gICAgICAgICAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotICAgICAgICAgIGNhc2UgMTM2OiAvLyBRTmFtZSA6Oj0gUEFSRU5UCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIFFOYW1lIFJFU1VMVCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgIFJFU1VMVCA9IHBhcnNlci5nZXRRTmFtZUlnbm9yZURlZmF1bHROcygicGFyZW50Iik7Ci0gICAgICAgICAgICAgIENVUCRYUGF0aFBhcnNlciRyZXN1bHQgPSBuZXcgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCgzNy8qUU5hbWUqLywgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkubGVmdCwgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQsIFJFU1VMVCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgcmV0dXJuIENVUCRYUGF0aFBhcnNlciRyZXN1bHQ7Ci0KLSAgICAgICAgICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0gICAgICAgICAgY2FzZSAxMzU6IC8vIFFOYW1lIDo6PSBOQU1FU1BBQ0UKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgUU5hbWUgUkVTVUxUID0gbnVsbDsKLSAgICAgICAgICAgICAgICAgUkVTVUxUID0gcGFyc2VyLmdldFFOYW1lSWdub3JlRGVmYXVsdE5zKCJuYW1lc3BhY2UiKTsKLSAgICAgICAgICAgICAgQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdCA9IG5ldyBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKDM3LypRTmFtZSovLCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0LCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodCwgUkVTVUxUKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICByZXR1cm4gQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdDsKLQotICAgICAgICAgIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuKi8KLSAgICAgICAgICBjYXNlIDEzNDogLy8gUU5hbWUgOjo9IEZPTExPV0lOR1NJQkxJTkcKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgUU5hbWUgUkVTVUxUID0gbnVsbDsKLSAgICAgICAgICAgICAgICAgUkVTVUxUID0gcGFyc2VyLmdldFFOYW1lSWdub3JlRGVmYXVsdE5zKCJmb2xsb3dpbmctc2libGluZyIpOwotICAgICAgICAgICAgICBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0ID0gbmV3IGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2woMzcvKlFOYW1lKi8sICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLmxlZnQsICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0LCBSRVNVTFQpOwotICAgICAgICAgICAgfQotICAgICAgICAgIHJldHVybiBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0OwotCi0gICAgICAgICAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotICAgICAgICAgIGNhc2UgMTMzOiAvLyBRTmFtZSA6Oj0gRk9MTE9XSU5HCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIFFOYW1lIFJFU1VMVCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgIFJFU1VMVCA9IHBhcnNlci5nZXRRTmFtZUlnbm9yZURlZmF1bHROcygiZm9sbG93aW5nIik7Ci0gICAgICAgICAgICAgIENVUCRYUGF0aFBhcnNlciRyZXN1bHQgPSBuZXcgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCgzNy8qUU5hbWUqLywgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkubGVmdCwgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQsIFJFU1VMVCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgcmV0dXJuIENVUCRYUGF0aFBhcnNlciRyZXN1bHQ7Ci0KLSAgICAgICAgICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0gICAgICAgICAgY2FzZSAxMzI6IC8vIFFOYW1lIDo6PSBERVNDRU5EQU5UT1JTRUxGCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIFFOYW1lIFJFU1VMVCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgIFJFU1VMVCA9IHBhcnNlci5nZXRRTmFtZUlnbm9yZURlZmF1bHROcygiZGVjZW5kYW50LW9yLXNlbGYiKTsKLSAgICAgICAgICAgICAgQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdCA9IG5ldyBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKDM3LypRTmFtZSovLCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0LCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodCwgUkVTVUxUKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICByZXR1cm4gQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdDsKLQotICAgICAgICAgIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuKi8KLSAgICAgICAgICBjYXNlIDEzMTogLy8gUU5hbWUgOjo9IERFU0NFTkRBTlQKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgUU5hbWUgUkVTVUxUID0gbnVsbDsKLSAgICAgICAgICAgICAgICAgUkVTVUxUID0gcGFyc2VyLmdldFFOYW1lSWdub3JlRGVmYXVsdE5zKCJkZWNlbmRhbnQiKTsKLSAgICAgICAgICAgICAgQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdCA9IG5ldyBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKDM3LypRTmFtZSovLCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0LCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodCwgUkVTVUxUKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICByZXR1cm4gQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdDsKLQotICAgICAgICAgIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuKi8KLSAgICAgICAgICBjYXNlIDEzMDogLy8gUU5hbWUgOjo9IENISUxECi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIFFOYW1lIFJFU1VMVCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgIFJFU1VMVCA9IHBhcnNlci5nZXRRTmFtZUlnbm9yZURlZmF1bHROcygiY2hpbGQiKTsKLSAgICAgICAgICAgICAgQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdCA9IG5ldyBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKDM3LypRTmFtZSovLCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0LCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodCwgUkVTVUxUKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICByZXR1cm4gQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdDsKLQotICAgICAgICAgIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuKi8KLSAgICAgICAgICBjYXNlIDEyOTogLy8gUU5hbWUgOjo9IEFUVFJJQlVURQotICAgICAgICAgICAgewotICAgICAgICAgICAgICBRTmFtZSBSRVNVTFQgPSBudWxsOwotICAgICAgICAgICAgICAgICBSRVNVTFQgPSBwYXJzZXIuZ2V0UU5hbWVJZ25vcmVEZWZhdWx0TnMoImF0dHJpYnV0ZSIpOwotICAgICAgICAgICAgICBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0ID0gbmV3IGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2woMzcvKlFOYW1lKi8sICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLmxlZnQsICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0LCBSRVNVTFQpOwotICAgICAgICAgICAgfQotICAgICAgICAgIHJldHVybiBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0OwotCi0gICAgICAgICAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotICAgICAgICAgIGNhc2UgMTI4OiAvLyBRTmFtZSA6Oj0gQU5DRVNUT1JPUlNFTEYKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgUU5hbWUgUkVTVUxUID0gbnVsbDsKLSAgICAgICAgICAgICAgICAgUkVTVUxUID0gcGFyc2VyLmdldFFOYW1lSWdub3JlRGVmYXVsdE5zKCJhbmNlc3Rvci1vci1zZWxmIik7Ci0gICAgICAgICAgICAgIENVUCRYUGF0aFBhcnNlciRyZXN1bHQgPSBuZXcgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCgzNy8qUU5hbWUqLywgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkubGVmdCwgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQsIFJFU1VMVCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgcmV0dXJuIENVUCRYUGF0aFBhcnNlciRyZXN1bHQ7Ci0KLSAgICAgICAgICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0gICAgICAgICAgY2FzZSAxMjc6IC8vIFFOYW1lIDo6PSBBTkNFU1RPUgotICAgICAgICAgICAgewotICAgICAgICAgICAgICBRTmFtZSBSRVNVTFQgPSBudWxsOwotICAgICAgICAgICAgICAgICBSRVNVTFQgPSBwYXJzZXIuZ2V0UU5hbWVJZ25vcmVEZWZhdWx0TnMoImNoaWxkIik7Ci0gICAgICAgICAgICAgIENVUCRYUGF0aFBhcnNlciRyZXN1bHQgPSBuZXcgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCgzNy8qUU5hbWUqLywgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkubGVmdCwgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQsIFJFU1VMVCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgcmV0dXJuIENVUCRYUGF0aFBhcnNlciRyZXN1bHQ7Ci0KLSAgICAgICAgICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0gICAgICAgICAgY2FzZSAxMjY6IC8vIFFOYW1lIDo6PSBLRVkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgUU5hbWUgUkVTVUxUID0gbnVsbDsKLSAgICAgICAgICAgICAgICAgUkVTVUxUID0gcGFyc2VyLmdldFFOYW1lSWdub3JlRGVmYXVsdE5zKCJrZXkiKTsKLSAgICAgICAgICAgICAgQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdCA9IG5ldyBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKDM3LypRTmFtZSovLCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0LCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodCwgUkVTVUxUKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICByZXR1cm4gQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdDsKLQotICAgICAgICAgIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuKi8KLSAgICAgICAgICBjYXNlIDEyNTogLy8gUU5hbWUgOjo9IE1PRAotICAgICAgICAgICAgewotICAgICAgICAgICAgICBRTmFtZSBSRVNVTFQgPSBudWxsOwotICAgICAgICAgICAgICAgICBSRVNVTFQgPSBwYXJzZXIuZ2V0UU5hbWVJZ25vcmVEZWZhdWx0TnMoIm1vZCIpOwotICAgICAgICAgICAgICBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0ID0gbmV3IGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2woMzcvKlFOYW1lKi8sICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLmxlZnQsICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0LCBSRVNVTFQpOwotICAgICAgICAgICAgfQotICAgICAgICAgIHJldHVybiBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0OwotCi0gICAgICAgICAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotICAgICAgICAgIGNhc2UgMTI0OiAvLyBRTmFtZSA6Oj0gRElWCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIFFOYW1lIFJFU1VMVCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgIFJFU1VMVCA9IHBhcnNlci5nZXRRTmFtZUlnbm9yZURlZmF1bHROcygiZGl2Iik7Ci0gICAgICAgICAgICAgIENVUCRYUGF0aFBhcnNlciRyZXN1bHQgPSBuZXcgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCgzNy8qUU5hbWUqLywgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkubGVmdCwgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQsIFJFU1VMVCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgcmV0dXJuIENVUCRYUGF0aFBhcnNlciRyZXN1bHQ7Ci0KLSAgICAgICAgICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0gICAgICAgICAgY2FzZSAxMjM6IC8vIFFOYW1lIDo6PSBRTkFNRQotICAgICAgICAgICAgewotICAgICAgICAgICAgICBRTmFtZSBSRVNVTFQgPSBudWxsOwotICAgICAgICAgICAgICAgIGludCBxbmFtZWxlZnQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0OwotICAgICAgICAgICAgICAgIGludCBxbmFtZXJpZ2h0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQ7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIHFuYW1lID0gKFN0cmluZykoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpIENVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkudmFsdWU7Ci0gICAgICAgICAgICAgICAgIFJFU1VMVCA9IHBhcnNlci5nZXRRTmFtZUlnbm9yZURlZmF1bHROcyhxbmFtZSk7Ci0gICAgICAgICAgICAgIENVUCRYUGF0aFBhcnNlciRyZXN1bHQgPSBuZXcgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCgzNy8qUU5hbWUqLywgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkubGVmdCwgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQsIFJFU1VMVCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgcmV0dXJuIENVUCRYUGF0aFBhcnNlciRyZXN1bHQ7Ci0KLSAgICAgICAgICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0gICAgICAgICAgY2FzZSAxMjI6IC8vIE5hbWVUZXN0IDo6PSBRTmFtZQotICAgICAgICAgICAgewotICAgICAgICAgICAgICBPYmplY3QgUkVTVUxUID0gbnVsbDsKLSAgICAgICAgICAgICAgICBpbnQgcW5sZWZ0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkubGVmdDsKLSAgICAgICAgICAgICAgICBpbnQgcW5yaWdodCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0OwotICAgICAgICAgICAgICAgIFFOYW1lIHFuID0gKFFOYW1lKSgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCkgQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS52YWx1ZTsKLSAgICAgICAgICAgICAgICAgUkVTVUxUID0gcW47Ci0gICAgICAgICAgICAgIENVUCRYUGF0aFBhcnNlciRyZXN1bHQgPSBuZXcgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCgyNi8qTmFtZVRlc3QqLywgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkubGVmdCwgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQsIFJFU1VMVCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgcmV0dXJuIENVUCRYUGF0aFBhcnNlciRyZXN1bHQ7Ci0KLSAgICAgICAgICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0gICAgICAgICAgY2FzZSAxMjE6IC8vIE5hbWVUZXN0IDo6PSBTVEFSCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIE9iamVjdCBSRVNVTFQgPSBudWxsOwotICAgICAgICAgICAgICAgICBSRVNVTFQgPSBudWxsOwotICAgICAgICAgICAgICBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0ID0gbmV3IGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2woMjYvKk5hbWVUZXN0Ki8sICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLmxlZnQsICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0LCBSRVNVTFQpOwotICAgICAgICAgICAgfQotICAgICAgICAgIHJldHVybiBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0OwotCi0gICAgICAgICAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotICAgICAgICAgIGNhc2UgMTIwOiAvLyBOb2RlVGVzdCA6Oj0gUEkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgT2JqZWN0IFJFU1VMVCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBJbnRlZ2VyKE5vZGVUZXN0LlBJKTsKLSAgICAgICAgICAgICAgQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdCA9IG5ldyBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKDI1LypOb2RlVGVzdCovLCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0LCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodCwgUkVTVUxUKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICByZXR1cm4gQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdDsKLQotICAgICAgICAgIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuKi8KLSAgICAgICAgICBjYXNlIDExOTogLy8gTm9kZVRlc3QgOjo9IFBJUEFSQU0gTFBBUkVOIExpdGVyYWwgUlBBUkVOCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIE9iamVjdCBSRVNVTFQgPSBudWxsOwotICAgICAgICAgICAgICAgIGludCBsbGVmdCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMSkpLmxlZnQ7Ci0gICAgICAgICAgICAgICAgaW50IGxyaWdodCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMSkpLnJpZ2h0OwotICAgICAgICAgICAgICAgIFN0cmluZyBsID0gKFN0cmluZykoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpIENVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0xKSkudmFsdWU7Ci0KLSAgICAgICAgICAgUU5hbWUgbmFtZSA9IHBhcnNlci5nZXRRTmFtZUlnbm9yZURlZmF1bHROcygibmFtZSIpOwotICAgICAgICAgICBFeHByZXNzaW9uIGV4cCA9IG5ldyBFcXVhbGl0eUV4cHIoT3BlcmF0b3JzLkVRLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE5hbWVDYWxsKG5hbWUpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IExpdGVyYWxFeHByKGwpKTsKLSAgICAgICAgICAgVmVjdG9yIHByZWRpY2F0ZXMgPSBuZXcgVmVjdG9yKCk7Ci0gICAgICAgICAgIHByZWRpY2F0ZXMuYWRkRWxlbWVudChuZXcgUHJlZGljYXRlKGV4cCkpOwotICAgICAgICAgICBSRVNVTFQgPSBuZXcgU3RlcChBeGlzLkNISUxELCBOb2RlVGVzdC5QSSwgcHJlZGljYXRlcyk7Ci0KLSAgICAgICAgICAgICAgQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdCA9IG5ldyBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKDI1LypOb2RlVGVzdCovLCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTMpKS5sZWZ0LCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodCwgUkVTVUxUKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICByZXR1cm4gQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdDsKLQotICAgICAgICAgIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuKi8KLSAgICAgICAgICBjYXNlIDExODogLy8gTm9kZVRlc3QgOjo9IENPTU1FTlQKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgT2JqZWN0IFJFU1VMVCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBJbnRlZ2VyKE5vZGVUZXN0LkNPTU1FTlQpOwotICAgICAgICAgICAgICBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0ID0gbmV3IGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2woMjUvKk5vZGVUZXN0Ki8sICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLmxlZnQsICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0LCBSRVNVTFQpOwotICAgICAgICAgICAgfQotICAgICAgICAgIHJldHVybiBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0OwotCi0gICAgICAgICAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotICAgICAgICAgIGNhc2UgMTE3OiAvLyBOb2RlVGVzdCA6Oj0gVEVYVAotICAgICAgICAgICAgewotICAgICAgICAgICAgICBPYmplY3QgUkVTVUxUID0gbnVsbDsKLSAgICAgICAgICAgICAgICAgUkVTVUxUID0gbmV3IEludGVnZXIoTm9kZVRlc3QuVEVYVCk7Ci0gICAgICAgICAgICAgIENVUCRYUGF0aFBhcnNlciRyZXN1bHQgPSBuZXcgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCgyNS8qTm9kZVRlc3QqLywgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkubGVmdCwgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQsIFJFU1VMVCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgcmV0dXJuIENVUCRYUGF0aFBhcnNlciRyZXN1bHQ7Ci0KLSAgICAgICAgICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0gICAgICAgICAgY2FzZSAxMTY6IC8vIE5vZGVUZXN0IDo6PSBOT0RFCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIE9iamVjdCBSRVNVTFQgPSBudWxsOwotICAgICAgICAgICAgICAgICBSRVNVTFQgPSBuZXcgSW50ZWdlcihOb2RlVGVzdC5BTk9ERSk7Ci0gICAgICAgICAgICAgIENVUCRYUGF0aFBhcnNlciRyZXN1bHQgPSBuZXcgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCgyNS8qTm9kZVRlc3QqLywgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkubGVmdCwgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQsIFJFU1VMVCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgcmV0dXJuIENVUCRYUGF0aFBhcnNlciRyZXN1bHQ7Ci0KLSAgICAgICAgICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0gICAgICAgICAgY2FzZSAxMTU6IC8vIE5vZGVUZXN0IDo6PSBOYW1lVGVzdAotICAgICAgICAgICAgewotICAgICAgICAgICAgICBPYmplY3QgUkVTVUxUID0gbnVsbDsKLSAgICAgICAgICAgICAgICBpbnQgbnRsZWZ0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkubGVmdDsKLSAgICAgICAgICAgICAgICBpbnQgbnRyaWdodCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0OwotICAgICAgICAgICAgICAgIE9iamVjdCBudCA9IChPYmplY3QpKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKSBDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnZhbHVlOwotICAgICAgICAgICAgICAgICBSRVNVTFQgPSBudDsKLSAgICAgICAgICAgICAgQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdCA9IG5ldyBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKDI1LypOb2RlVGVzdCovLCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0LCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodCwgUkVTVUxUKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICByZXR1cm4gQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdDsKLQotICAgICAgICAgIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuKi8KLSAgICAgICAgICBjYXNlIDExNDogLy8gQXJndW1lbnQgOjo9IEV4cHIKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgRXhwcmVzc2lvbiBSRVNVTFQgPSBudWxsOwotICAgICAgICAgICAgICAgIGludCBleGxlZnQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0OwotICAgICAgICAgICAgICAgIGludCBleHJpZ2h0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQ7Ci0gICAgICAgICAgICAgICAgRXhwcmVzc2lvbiBleCA9IChFeHByZXNzaW9uKSgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCkgQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS52YWx1ZTsKLSAgICAgICAgICAgICAgICAgUkVTVUxUID0gZXg7Ci0gICAgICAgICAgICAgIENVUCRYUGF0aFBhcnNlciRyZXN1bHQgPSBuZXcgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCgzLypBcmd1bWVudCovLCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0LCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodCwgUkVTVUxUKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICByZXR1cm4gQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdDsKLQotICAgICAgICAgIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuKi8KLSAgICAgICAgICBjYXNlIDExMzogLy8gVmFyaWFibGVOYW1lIDo6PSBRTmFtZQotICAgICAgICAgICAgewotICAgICAgICAgICAgICBRTmFtZSBSRVNVTFQgPSBudWxsOwotICAgICAgICAgICAgICAgIGludCB2bmFtZWxlZnQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0OwotICAgICAgICAgICAgICAgIGludCB2bmFtZXJpZ2h0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQ7Ci0gICAgICAgICAgICAgICAgUU5hbWUgdm5hbWUgPSAoUU5hbWUpKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKSBDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnZhbHVlOwotCi0gICAgICAgICAgICBSRVNVTFQgPSB2bmFtZTsKLQotICAgICAgICAgICAgICBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0ID0gbmV3IGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2woMzkvKlZhcmlhYmxlTmFtZSovLCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0LCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodCwgUkVTVUxUKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICByZXR1cm4gQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdDsKLQotICAgICAgICAgIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuKi8KLSAgICAgICAgICBjYXNlIDExMjogLy8gRnVuY3Rpb25OYW1lIDo6PSBRTmFtZQotICAgICAgICAgICAgewotICAgICAgICAgICAgICBRTmFtZSBSRVNVTFQgPSBudWxsOwotICAgICAgICAgICAgICAgIGludCBmbmFtZWxlZnQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0OwotICAgICAgICAgICAgICAgIGludCBmbmFtZXJpZ2h0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQ7Ci0gICAgICAgICAgICAgICAgUU5hbWUgZm5hbWUgPSAoUU5hbWUpKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKSBDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnZhbHVlOwotCi0gICAgICAgICAgICBSRVNVTFQgPSBmbmFtZTsKLQotICAgICAgICAgICAgICBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0ID0gbmV3IGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2woMzgvKkZ1bmN0aW9uTmFtZSovLCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0LCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodCwgUkVTVUxUKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICByZXR1cm4gQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdDsKLQotICAgICAgICAgIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuKi8KLSAgICAgICAgICBjYXNlIDExMTogLy8gTm9uZW1wdHlBcmd1bWVudExpc3QgOjo9IEFyZ3VtZW50IENPTU1BIE5vbmVtcHR5QXJndW1lbnRMaXN0Ci0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIFZlY3RvciBSRVNVTFQgPSBudWxsOwotICAgICAgICAgICAgICAgIGludCBhcmdsZWZ0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0yKSkubGVmdDsKLSAgICAgICAgICAgICAgICBpbnQgYXJncmlnaHQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTIpKS5yaWdodDsKLSAgICAgICAgICAgICAgICBFeHByZXNzaW9uIGFyZyA9IChFeHByZXNzaW9uKSgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCkgQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTIpKS52YWx1ZTsKLSAgICAgICAgICAgICAgICBpbnQgYXJnbGxlZnQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0OwotICAgICAgICAgICAgICAgIGludCBhcmdscmlnaHQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodDsKLSAgICAgICAgICAgICAgICBWZWN0b3IgYXJnbCA9IChWZWN0b3IpKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKSBDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnZhbHVlOwotICAgICAgICAgICAgICAgICBhcmdsLmluc2VydEVsZW1lbnRBdChhcmcsIDApOyBSRVNVTFQgPSBhcmdsOwotICAgICAgICAgICAgICBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0ID0gbmV3IGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2woMzYvKk5vbmVtcHR5QXJndW1lbnRMaXN0Ki8sICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMikpLmxlZnQsICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0LCBSRVNVTFQpOwotICAgICAgICAgICAgfQotICAgICAgICAgIHJldHVybiBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0OwotCi0gICAgICAgICAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotICAgICAgICAgIGNhc2UgMTEwOiAvLyBOb25lbXB0eUFyZ3VtZW50TGlzdCA6Oj0gQXJndW1lbnQKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgVmVjdG9yIFJFU1VMVCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgaW50IGFyZ2xlZnQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0OwotICAgICAgICAgICAgICAgIGludCBhcmdyaWdodCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0OwotICAgICAgICAgICAgICAgIEV4cHJlc3Npb24gYXJnID0gKEV4cHJlc3Npb24pKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKSBDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnZhbHVlOwotCi0gICAgICAgICAgICBWZWN0b3IgdGVtcCA9IG5ldyBWZWN0b3IoKTsKLSAgICAgICAgICAgIHRlbXAuYWRkRWxlbWVudChhcmcpOwotICAgICAgICAgICAgUkVTVUxUID0gdGVtcDsKLQotICAgICAgICAgICAgICBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0ID0gbmV3IGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2woMzYvKk5vbmVtcHR5QXJndW1lbnRMaXN0Ki8sICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLmxlZnQsICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0LCBSRVNVTFQpOwotICAgICAgICAgICAgfQotICAgICAgICAgIHJldHVybiBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0OwotCi0gICAgICAgICAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotICAgICAgICAgIGNhc2UgMTA5OiAvLyBGdW5jdGlvbkNhbGwgOjo9IEZ1bmN0aW9uTmFtZSBMUEFSRU4gTm9uZW1wdHlBcmd1bWVudExpc3QgUlBBUkVOCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIEV4cHJlc3Npb24gUkVTVUxUID0gbnVsbDsKLSAgICAgICAgICAgICAgICBpbnQgZm5hbWVsZWZ0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0zKSkubGVmdDsKLSAgICAgICAgICAgICAgICBpbnQgZm5hbWVyaWdodCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMykpLnJpZ2h0OwotICAgICAgICAgICAgICAgIFFOYW1lIGZuYW1lID0gKFFOYW1lKSgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCkgQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTMpKS52YWx1ZTsKLSAgICAgICAgICAgICAgICBpbnQgYXJnbGxlZnQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTEpKS5sZWZ0OwotICAgICAgICAgICAgICAgIGludCBhcmdscmlnaHQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTEpKS5yaWdodDsKLSAgICAgICAgICAgICAgICBWZWN0b3IgYXJnbCA9IChWZWN0b3IpKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKSBDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMSkpLnZhbHVlOwotCi0gICAgICAgICAgaWYgKGZuYW1lID09IHBhcnNlci5nZXRRTmFtZUlnbm9yZURlZmF1bHROcygiY29uY2F0IikpIHsKLSAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBDb25jYXRDYWxsKGZuYW1lLCBhcmdsKTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgZWxzZSBpZiAoZm5hbWUgPT0gcGFyc2VyLmdldFFOYW1lSWdub3JlRGVmYXVsdE5zKCJudW1iZXIiKSkgewotICAgICAgICAgICAgUkVTVUxUID0gbmV3IE51bWJlckNhbGwoZm5hbWUsIGFyZ2wpOwotICAgICAgICAgIH0KLSAgICAgICAgICBlbHNlIGlmIChmbmFtZSA9PSBwYXJzZXIuZ2V0UU5hbWVJZ25vcmVEZWZhdWx0TnMoImRvY3VtZW50IikpIHsKLSAgICAgICAgICAgIHBhcnNlci5zZXRNdWx0aURvY3VtZW50KHRydWUpOwotICAgICAgICAgICAgUkVTVUxUID0gbmV3IERvY3VtZW50Q2FsbChmbmFtZSwgYXJnbCk7Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UgaWYgKGZuYW1lID09IHBhcnNlci5nZXRRTmFtZUlnbm9yZURlZmF1bHROcygic3RyaW5nIikpIHsKLSAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBTdHJpbmdDYWxsKGZuYW1lLCBhcmdsKTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgZWxzZSBpZiAoZm5hbWUgPT0gcGFyc2VyLmdldFFOYW1lSWdub3JlRGVmYXVsdE5zKCJib29sZWFuIikpIHsKLSAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBCb29sZWFuQ2FsbChmbmFtZSwgYXJnbCk7Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UgaWYgKGZuYW1lID09IHBhcnNlci5nZXRRTmFtZUlnbm9yZURlZmF1bHROcygibmFtZSIpKSB7Ci0gICAgICAgICAgICBSRVNVTFQgPSBuZXcgTmFtZUNhbGwoZm5hbWUsIGFyZ2wpOwotICAgICAgICAgIH0KLSAgICAgICAgICBlbHNlIGlmIChmbmFtZSA9PSBwYXJzZXIuZ2V0UU5hbWVJZ25vcmVEZWZhdWx0TnMoImdlbmVyYXRlLWlkIikpIHsKLSAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBHZW5lcmF0ZUlkQ2FsbChmbmFtZSwgYXJnbCk7Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UgaWYgKGZuYW1lID09IHBhcnNlci5nZXRRTmFtZUlnbm9yZURlZmF1bHROcygibm90IikpIHsKLSAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBOb3RDYWxsKGZuYW1lLCBhcmdsKTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgZWxzZSBpZiAoZm5hbWUgPT0gcGFyc2VyLmdldFFOYW1lSWdub3JlRGVmYXVsdE5zKCJmb3JtYXQtbnVtYmVyIikpIHsKLSAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBGb3JtYXROdW1iZXJDYWxsKGZuYW1lLCBhcmdsKTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgZWxzZSBpZiAoZm5hbWUgPT0gcGFyc2VyLmdldFFOYW1lSWdub3JlRGVmYXVsdE5zKCJ1bnBhcnNlZC1lbnRpdHktdXJpIikpIHsKLSAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBVbnBhcnNlZEVudGl0eVVyaUNhbGwoZm5hbWUsIGFyZ2wpOwotICAgICAgICAgIH0KLSAgICAgICAgICBlbHNlIGlmIChmbmFtZSA9PSBwYXJzZXIuZ2V0UU5hbWVJZ25vcmVEZWZhdWx0TnMoImtleSIpKSB7Ci0gICAgICAgICAgICBSRVNVTFQgPSBuZXcgS2V5Q2FsbChmbmFtZSwgYXJnbCk7Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UgaWYgKGZuYW1lID09IHBhcnNlci5nZXRRTmFtZUlnbm9yZURlZmF1bHROcygiaWQiKSkgewotICAgICAgICAgICAgUkVTVUxUID0gbmV3IEtleUNhbGwoZm5hbWUsIGFyZ2wpOwotICAgICAgICAgICAgcGFyc2VyLnNldEhhc0lkQ2FsbCh0cnVlKTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgZWxzZSBpZiAoZm5hbWUgPT0gcGFyc2VyLmdldFFOYW1lSWdub3JlRGVmYXVsdE5zKCJjZWlsaW5nIikpIHsKLSAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBDZWlsaW5nQ2FsbChmbmFtZSwgYXJnbCk7Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UgaWYgKGZuYW1lID09IHBhcnNlci5nZXRRTmFtZUlnbm9yZURlZmF1bHROcygicm91bmQiKSkgewotICAgICAgICAgICAgUkVTVUxUID0gbmV3IFJvdW5kQ2FsbChmbmFtZSwgYXJnbCk7Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UgaWYgKGZuYW1lID09IHBhcnNlci5nZXRRTmFtZUlnbm9yZURlZmF1bHROcygiZmxvb3IiKSkgewotICAgICAgICAgICAgUkVTVUxUID0gbmV3IEZsb29yQ2FsbChmbmFtZSwgYXJnbCk7Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UgaWYgKGZuYW1lID09IHBhcnNlci5nZXRRTmFtZUlnbm9yZURlZmF1bHROcygiY29udGFpbnMiKSkgewotICAgICAgICAgICAgUkVTVUxUID0gbmV3IENvbnRhaW5zQ2FsbChmbmFtZSwgYXJnbCk7Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UgaWYgKGZuYW1lID09IHBhcnNlci5nZXRRTmFtZUlnbm9yZURlZmF1bHROcygic3RyaW5nLWxlbmd0aCIpKSB7Ci0gICAgICAgICAgICBSRVNVTFQgPSBuZXcgU3RyaW5nTGVuZ3RoQ2FsbChmbmFtZSwgYXJnbCk7Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UgaWYgKGZuYW1lID09IHBhcnNlci5nZXRRTmFtZUlnbm9yZURlZmF1bHROcygic3RhcnRzLXdpdGgiKSkgewotICAgICAgICAgICAgUkVTVUxUID0gbmV3IFN0YXJ0c1dpdGhDYWxsKGZuYW1lLCBhcmdsKTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgZWxzZSBpZiAoZm5hbWUgPT0gcGFyc2VyLmdldFFOYW1lSWdub3JlRGVmYXVsdE5zKCJmdW5jdGlvbi1hdmFpbGFibGUiKSkgewotICAgICAgICAgICAgUkVTVUxUID0gbmV3IEZ1bmN0aW9uQXZhaWxhYmxlQ2FsbChmbmFtZSwgYXJnbCk7Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UgaWYgKGZuYW1lID09IHBhcnNlci5nZXRRTmFtZUlnbm9yZURlZmF1bHROcygiZWxlbWVudC1hdmFpbGFibGUiKSkgewotICAgICAgICAgICAgUkVTVUxUID0gbmV3IEVsZW1lbnRBdmFpbGFibGVDYWxsKGZuYW1lLCBhcmdsKTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgZWxzZSBpZiAoZm5hbWUgPT0gcGFyc2VyLmdldFFOYW1lSWdub3JlRGVmYXVsdE5zKCJsb2NhbC1uYW1lIikpIHsKLSAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBMb2NhbE5hbWVDYWxsKGZuYW1lLCBhcmdsKTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgZWxzZSBpZiAoZm5hbWUgPT0gcGFyc2VyLmdldFFOYW1lSWdub3JlRGVmYXVsdE5zKCJsYW5nIikpIHsKLSAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBMYW5nQ2FsbChmbmFtZSwgYXJnbCk7Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UgaWYgKGZuYW1lID09IHBhcnNlci5nZXRRTmFtZUlnbm9yZURlZmF1bHROcygibmFtZXNwYWNlLXVyaSIpKSB7Ci0gICAgICAgICAgICBSRVNVTFQgPSBuZXcgTmFtZXNwYWNlVXJpQ2FsbChmbmFtZSwgYXJnbCk7Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UgaWYgKGZuYW1lID09IHBhcnNlci5nZXRRTmFtZShDb25zdGFudHMuVFJBTlNMRVRfVVJJLCAieHNsdGMiLCAiY2FzdCIpKSB7Ci0gICAgICAgICAgICBSRVNVTFQgPSBuZXcgQ2FzdENhbGwoZm5hbWUsIGFyZ2wpOwotICAgICAgICAgIH0KLSAgICAgICAgICAvLyBTcGVjaWFsIGNhc2UgZm9yIGV4dGVuc2lvbiBmdW5jdGlvbiBub2Rlc2V0KCkKLSAgICAgICAgICBlbHNlIGlmIChmbmFtZS5nZXRMb2NhbFBhcnQoKS5lcXVhbHMoIm5vZGVzZXQiKSB8fCBmbmFtZS5nZXRMb2NhbFBhcnQoKS5lcXVhbHMoIm5vZGUtc2V0IikpIHsKLSAgICAgICAgICAgIHBhcnNlci5zZXRDYWxsc05vZGVzZXQodHJ1ZSk7ICAvLyBpbXBsaWVzIE11bHRpRE9NCi0gICAgICAgICAgICBSRVNVTFQgPSBuZXcgRnVuY3Rpb25DYWxsKGZuYW1lLCBhcmdsKTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBSRVNVTFQgPSBuZXcgRnVuY3Rpb25DYWxsKGZuYW1lLCBhcmdsKTsKLSAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdCA9IG5ldyBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKDE2LypGdW5jdGlvbkNhbGwqLywgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0zKSkubGVmdCwgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQsIFJFU1VMVCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgcmV0dXJuIENVUCRYUGF0aFBhcnNlciRyZXN1bHQ7Ci0KLSAgICAgICAgICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0gICAgICAgICAgY2FzZSAxMDg6IC8vIEZ1bmN0aW9uQ2FsbCA6Oj0gRnVuY3Rpb25OYW1lIExQQVJFTiBSUEFSRU4KLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgRXhwcmVzc2lvbiBSRVNVTFQgPSBudWxsOwotICAgICAgICAgICAgICAgIGludCBmbmFtZWxlZnQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTIpKS5sZWZ0OwotICAgICAgICAgICAgICAgIGludCBmbmFtZXJpZ2h0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0yKSkucmlnaHQ7Ci0gICAgICAgICAgICAgICAgUU5hbWUgZm5hbWUgPSAoUU5hbWUpKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKSBDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMikpLnZhbHVlOwotCi0KLSAgICAgICAgICBpZiAoZm5hbWUgPT0gcGFyc2VyLmdldFFOYW1lSWdub3JlRGVmYXVsdE5zKCJjdXJyZW50IikpIHsKLSAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBDdXJyZW50Q2FsbChmbmFtZSk7Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UgaWYgKGZuYW1lID09IHBhcnNlci5nZXRRTmFtZUlnbm9yZURlZmF1bHROcygibnVtYmVyIikpIHsKLSAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBOdW1iZXJDYWxsKGZuYW1lLCBwYXJzZXIuRW1wdHlBcmdzKTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgZWxzZSBpZiAoZm5hbWUgPT0gcGFyc2VyLmdldFFOYW1lSWdub3JlRGVmYXVsdE5zKCJzdHJpbmciKSkgewotICAgICAgICAgICAgUkVTVUxUID0gbmV3IFN0cmluZ0NhbGwoZm5hbWUsIHBhcnNlci5FbXB0eUFyZ3MpOwotICAgICAgICAgIH0KLSAgICAgICAgICBlbHNlIGlmIChmbmFtZSA9PSBwYXJzZXIuZ2V0UU5hbWVJZ25vcmVEZWZhdWx0TnMoImNvbmNhdCIpKSB7Ci0gICAgICAgICAgICBSRVNVTFQgPSBuZXcgQ29uY2F0Q2FsbChmbmFtZSwgcGFyc2VyLkVtcHR5QXJncyk7Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UgaWYgKGZuYW1lID09IHBhcnNlci5nZXRRTmFtZUlnbm9yZURlZmF1bHROcygidHJ1ZSIpKSB7Ci0gICAgICAgICAgICBSRVNVTFQgPSBuZXcgQm9vbGVhbkV4cHIodHJ1ZSk7Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UgaWYgKGZuYW1lID09IHBhcnNlci5nZXRRTmFtZUlnbm9yZURlZmF1bHROcygiZmFsc2UiKSkgewotICAgICAgICAgICAgUkVTVUxUID0gbmV3IEJvb2xlYW5FeHByKGZhbHNlKTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgZWxzZSBpZiAoZm5hbWUgPT0gcGFyc2VyLmdldFFOYW1lSWdub3JlRGVmYXVsdE5zKCJuYW1lIikpIHsKLSAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBOYW1lQ2FsbChmbmFtZSk7Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UgaWYgKGZuYW1lID09IHBhcnNlci5nZXRRTmFtZUlnbm9yZURlZmF1bHROcygiZ2VuZXJhdGUtaWQiKSkgewotICAgICAgICAgICAgUkVTVUxUID0gbmV3IEdlbmVyYXRlSWRDYWxsKGZuYW1lLCBwYXJzZXIuRW1wdHlBcmdzKTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgZWxzZSBpZiAoZm5hbWUgPT0gcGFyc2VyLmdldFFOYW1lSWdub3JlRGVmYXVsdE5zKCJzdHJpbmctbGVuZ3RoIikpIHsKLSAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBTdHJpbmdMZW5ndGhDYWxsKGZuYW1lLCBwYXJzZXIuRW1wdHlBcmdzKTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgZWxzZSBpZiAoZm5hbWUgPT0gcGFyc2VyLmdldFFOYW1lSWdub3JlRGVmYXVsdE5zKCJwb3NpdGlvbiIpKSB7Ci0gICAgICAgICAgICBSRVNVTFQgPSBuZXcgUG9zaXRpb25DYWxsKGZuYW1lKTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgZWxzZSBpZiAoZm5hbWUgPT0gcGFyc2VyLmdldFFOYW1lSWdub3JlRGVmYXVsdE5zKCJsYXN0IikpIHsKLSAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBMYXN0Q2FsbChmbmFtZSk7Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UgaWYgKGZuYW1lID09IHBhcnNlci5nZXRRTmFtZUlnbm9yZURlZmF1bHROcygibG9jYWwtbmFtZSIpKSB7Ci0gICAgICAgICAgICBSRVNVTFQgPSBuZXcgTG9jYWxOYW1lQ2FsbChmbmFtZSk7Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UgaWYgKGZuYW1lID09IHBhcnNlci5nZXRRTmFtZUlnbm9yZURlZmF1bHROcygibmFtZXNwYWNlLXVyaSIpKSB7Ci0gICAgICAgICAgICBSRVNVTFQgPSBuZXcgTmFtZXNwYWNlVXJpQ2FsbChmbmFtZSk7Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgUkVTVUxUID0gbmV3IEZ1bmN0aW9uQ2FsbChmbmFtZSwgcGFyc2VyLkVtcHR5QXJncyk7Ci0gICAgICAgICAgfQotCi0gICAgICAgICAgICAgIENVUCRYUGF0aFBhcnNlciRyZXN1bHQgPSBuZXcgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCgxNi8qRnVuY3Rpb25DYWxsKi8sICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMikpLmxlZnQsICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0LCBSRVNVTFQpOwotICAgICAgICAgICAgfQotICAgICAgICAgIHJldHVybiBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0OwotCi0gICAgICAgICAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotICAgICAgICAgIGNhc2UgMTA3OiAvLyBWYXJpYWJsZVJlZmVyZW5jZSA6Oj0gRE9MTEFSIFZhcmlhYmxlTmFtZQotICAgICAgICAgICAgewotICAgICAgICAgICAgICBFeHByZXNzaW9uIFJFU1VMVCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgaW50IHZhck5hbWVsZWZ0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkubGVmdDsKLSAgICAgICAgICAgICAgICBpbnQgdmFyTmFtZXJpZ2h0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQ7Ci0gICAgICAgICAgICAgICAgUU5hbWUgdmFyTmFtZSA9IChRTmFtZSkoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpIENVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkudmFsdWU7Ci0KLSAgICAgICAgICAgIC8vIEFuIGVtcHR5IHFuYW1lIHByZWZpeCBmb3IgYSB2YXJpYWJsZSBvciBwYXJhbWV0ZXIgcmVmZXJlbmNlCi0gICAgICAgICAgICAvLyBzaG91bGQgbWFwIHRvIHRoZSBudWxsIG5hbWVzcGFjZSBhbmQgbm90IHRoZSBkZWZhdWx0IFVSSS4KLSAgICAgICAgICAgIFN5bnRheFRyZWVOb2RlIG5vZGUgPSBwYXJzZXIubG9va3VwTmFtZSh2YXJOYW1lKTsKLQotICAgICAgICAgICAgaWYgKG5vZGUgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGlmIChub2RlIGluc3RhbmNlb2YgVmFyaWFibGUpIHsKLSAgICAgICAgICAgICAgICAgICAgUkVTVUxUID0gbmV3IFZhcmlhYmxlUmVmKChWYXJpYWJsZSlub2RlKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSBpZiAobm9kZSBpbnN0YW5jZW9mIFBhcmFtKSB7Ci0gICAgICAgICAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBQYXJhbWV0ZXJSZWYoKFBhcmFtKW5vZGUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgUkVTVUxUID0gbmV3IFVucmVzb2x2ZWRSZWYodmFyTmFtZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAobm9kZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgUkVTVUxUID0gbmV3IFVucmVzb2x2ZWRSZWYodmFyTmFtZSk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdCA9IG5ldyBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKDE1LypWYXJpYWJsZVJlZmVyZW5jZSovLCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTEpKS5sZWZ0LCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodCwgUkVTVUxUKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICByZXR1cm4gQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdDsKLQotICAgICAgICAgIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuKi8KLSAgICAgICAgICBjYXNlIDEwNjogLy8gUHJpbWFyeUV4cHIgOjo9IEZ1bmN0aW9uQ2FsbAotICAgICAgICAgICAgewotICAgICAgICAgICAgICBFeHByZXNzaW9uIFJFU1VMVCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgaW50IGZjbGVmdCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLmxlZnQ7Ci0gICAgICAgICAgICAgICAgaW50IGZjcmlnaHQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodDsKLSAgICAgICAgICAgICAgICBFeHByZXNzaW9uIGZjID0gKEV4cHJlc3Npb24pKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKSBDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnZhbHVlOwotICAgICAgICAgICAgICAgICBSRVNVTFQgPSBmYzsKLSAgICAgICAgICAgICAgQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdCA9IG5ldyBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKDE3LypQcmltYXJ5RXhwciovLCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0LCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodCwgUkVTVUxUKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICByZXR1cm4gQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdDsKLQotICAgICAgICAgIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuKi8KLSAgICAgICAgICBjYXNlIDEwNTogLy8gUHJpbWFyeUV4cHIgOjo9IFJFQUwKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgRXhwcmVzc2lvbiBSRVNVTFQgPSBudWxsOwotICAgICAgICAgICAgICAgIGludCBudW1sZWZ0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkubGVmdDsKLSAgICAgICAgICAgICAgICBpbnQgbnVtcmlnaHQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodDsKLSAgICAgICAgICAgICAgICBEb3VibGUgbnVtID0gKERvdWJsZSkoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpIENVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkudmFsdWU7Ci0gICAgICAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBSZWFsRXhwcihudW0uZG91YmxlVmFsdWUoKSk7Ci0gICAgICAgICAgICAgIENVUCRYUGF0aFBhcnNlciRyZXN1bHQgPSBuZXcgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCgxNy8qUHJpbWFyeUV4cHIqLywgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkubGVmdCwgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQsIFJFU1VMVCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgcmV0dXJuIENVUCRYUGF0aFBhcnNlciRyZXN1bHQ7Ci0KLSAgICAgICAgICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0gICAgICAgICAgY2FzZSAxMDQ6IC8vIFByaW1hcnlFeHByIDo6PSBJTlQKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgRXhwcmVzc2lvbiBSRVNVTFQgPSBudWxsOwotICAgICAgICAgICAgICAgIGludCBudW1sZWZ0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkubGVmdDsKLSAgICAgICAgICAgICAgICBpbnQgbnVtcmlnaHQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodDsKLSAgICAgICAgICAgICAgICBMb25nIG51bSA9IChMb25nKSgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCkgQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS52YWx1ZTsKLQotICAgICAgICAgICBsb25nIHZhbHVlID0gbnVtLmxvbmdWYWx1ZSgpOwotICAgICAgICAgICBpZiAodmFsdWUgPCBJbnRlZ2VyLk1JTl9WQUxVRSB8fCB2YWx1ZSA+IEludGVnZXIuTUFYX1ZBTFVFKSB7Ci0gICAgICAgICAgICAgICAgUkVTVUxUID0gbmV3IFJlYWxFeHByKHZhbHVlKTsKLSAgICAgICAgICAgfQotICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgIGlmIChudW0uZG91YmxlVmFsdWUoKSA9PSAtMCkKLSAgICAgICAgICAgICAgICAgICBSRVNVTFQgPSBuZXcgUmVhbEV4cHIobnVtLmRvdWJsZVZhbHVlKCkpOwotICAgICAgICAgICAgICAgZWxzZSBpZiAobnVtLmludFZhbHVlKCkgPT0gMCkKLSAgICAgICAgICAgICAgICAgICBSRVNVTFQgPSBuZXcgSW50RXhwcihudW0uaW50VmFsdWUoKSk7Ci0gICAgICAgICAgICAgICBlbHNlIGlmIChudW0uZG91YmxlVmFsdWUoKSA9PSAwLjApCi0gICAgICAgICAgICAgICAgICAgUkVTVUxUID0gbmV3IFJlYWxFeHByKG51bS5kb3VibGVWYWx1ZSgpKTsKLSAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgICBSRVNVTFQgPSBuZXcgSW50RXhwcihudW0uaW50VmFsdWUoKSk7Ci0gICAgICAgICAgIH0KLQotICAgICAgICAgICAgICBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0ID0gbmV3IGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2woMTcvKlByaW1hcnlFeHByKi8sICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLmxlZnQsICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0LCBSRVNVTFQpOwotICAgICAgICAgICAgfQotICAgICAgICAgIHJldHVybiBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0OwotCi0gICAgICAgICAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotICAgICAgICAgIGNhc2UgMTAzOiAvLyBQcmltYXJ5RXhwciA6Oj0gTGl0ZXJhbAotICAgICAgICAgICAgewotICAgICAgICAgICAgICBFeHByZXNzaW9uIFJFU1VMVCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgaW50IHN0cmluZ2xlZnQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0OwotICAgICAgICAgICAgICAgIGludCBzdHJpbmdyaWdodCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0OwotICAgICAgICAgICAgICAgIFN0cmluZyBzdHJpbmcgPSAoU3RyaW5nKSgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCkgQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS52YWx1ZTsKLQotICAgICAgICAvKgotICAgICAgICAqIElmIHRoZSBzdHJpbmcgYXBwZWFycyB0byBoYXZlIHRoZSBzeW50YXggb2YgYSBRTmFtZSwgc3RvcmUKLSAgICAgICAgKiBuYW1lc3BhY2UgaW5mbyBpbiB0aGUgbGl0ZXJhbCBleHByZXNzaW9uLiBUaGlzIGlzIHVzZWQgZm9yCi0gICAgICAgICogZWxlbWVudC1hdmFpbGFibGUgYW5kIGZ1bmN0aW9uLWF2YWlsYWJsZSBmdW5jdGlvbnMsIGFtb25nCi0gICAgICAgICogb3RoZXJzLiBBbHNvLCB0aGUgZGVmYXVsdCBuYW1lc3BhY2UgbXVzdCBiZSBpZ25vcmVkLgotICAgICAgICAqLwotICAgICAgICBTdHJpbmcgbmFtZXNwYWNlID0gbnVsbDsKLSAgICAgICAgZmluYWwgaW50IGluZGV4ID0gc3RyaW5nLmxhc3RJbmRleE9mKCc6Jyk7Ci0KLSAgICAgICAgaWYgKGluZGV4ID4gMCkgewotICAgICAgICAgICAgZmluYWwgU3RyaW5nIHByZWZpeCA9IHN0cmluZy5zdWJzdHJpbmcoMCwgaW5kZXgpOwotICAgICAgICAgICAgbmFtZXNwYWNlID0gcGFyc2VyLl9zeW1ib2xUYWJsZS5sb29rdXBOYW1lc3BhY2UocHJlZml4KTsKLSAgICAgICAgfQotICAgICAgICBSRVNVTFQgPSAobmFtZXNwYWNlID09IG51bGwpID8gbmV3IExpdGVyYWxFeHByKHN0cmluZykKLSAgICAgICAgICAgICAgICAgICAgIDogbmV3IExpdGVyYWxFeHByKHN0cmluZywgbmFtZXNwYWNlKTsKLQotICAgICAgICAgICAgICBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0ID0gbmV3IGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2woMTcvKlByaW1hcnlFeHByKi8sICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLmxlZnQsICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0LCBSRVNVTFQpOwotICAgICAgICAgICAgfQotICAgICAgICAgIHJldHVybiBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0OwotCi0gICAgICAgICAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotICAgICAgICAgIGNhc2UgMTAyOiAvLyBQcmltYXJ5RXhwciA6Oj0gTFBBUkVOIEV4cHIgUlBBUkVOCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIEV4cHJlc3Npb24gUkVTVUxUID0gbnVsbDsKLSAgICAgICAgICAgICAgICBpbnQgZXhsZWZ0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0xKSkubGVmdDsKLSAgICAgICAgICAgICAgICBpbnQgZXhyaWdodCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMSkpLnJpZ2h0OwotICAgICAgICAgICAgICAgIEV4cHJlc3Npb24gZXggPSAoRXhwcmVzc2lvbikoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpIENVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0xKSkudmFsdWU7Ci0gICAgICAgICAgICAgICAgIFJFU1VMVCA9IGV4OwotICAgICAgICAgICAgICBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0ID0gbmV3IGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2woMTcvKlByaW1hcnlFeHByKi8sICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMikpLmxlZnQsICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0LCBSRVNVTFQpOwotICAgICAgICAgICAgfQotICAgICAgICAgIHJldHVybiBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0OwotCi0gICAgICAgICAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotICAgICAgICAgIGNhc2UgMTAxOiAvLyBQcmltYXJ5RXhwciA6Oj0gVmFyaWFibGVSZWZlcmVuY2UKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgRXhwcmVzc2lvbiBSRVNVTFQgPSBudWxsOwotICAgICAgICAgICAgICAgIGludCB2cmxlZnQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0OwotICAgICAgICAgICAgICAgIGludCB2cnJpZ2h0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQ7Ci0gICAgICAgICAgICAgICAgRXhwcmVzc2lvbiB2ciA9IChFeHByZXNzaW9uKSgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCkgQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS52YWx1ZTsKLSAgICAgICAgICAgICAgICAgUkVTVUxUID0gdnI7Ci0gICAgICAgICAgICAgIENVUCRYUGF0aFBhcnNlciRyZXN1bHQgPSBuZXcgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCgxNy8qUHJpbWFyeUV4cHIqLywgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkubGVmdCwgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQsIFJFU1VMVCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgcmV0dXJuIENVUCRYUGF0aFBhcnNlciRyZXN1bHQ7Ci0KLSAgICAgICAgICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0gICAgICAgICAgY2FzZSAxMDA6IC8vIEZpbHRlckV4cHIgOjo9IFByaW1hcnlFeHByIFByZWRpY2F0ZXMKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgRXhwcmVzc2lvbiBSRVNVTFQgPSBudWxsOwotICAgICAgICAgICAgICAgIGludCBwcmltYXJ5bGVmdCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMSkpLmxlZnQ7Ci0gICAgICAgICAgICAgICAgaW50IHByaW1hcnlyaWdodCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMSkpLnJpZ2h0OwotICAgICAgICAgICAgICAgIEV4cHJlc3Npb24gcHJpbWFyeSA9IChFeHByZXNzaW9uKSgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCkgQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTEpKS52YWx1ZTsKLSAgICAgICAgICAgICAgICBpbnQgcHBsZWZ0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkubGVmdDsKLSAgICAgICAgICAgICAgICBpbnQgcHByaWdodCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0OwotICAgICAgICAgICAgICAgIFZlY3RvciBwcCA9IChWZWN0b3IpKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKSBDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnZhbHVlOwotICAgICAgICAgICAgICAgICBSRVNVTFQgPSBuZXcgRmlsdGVyRXhwcihwcmltYXJ5LCBwcCk7Ci0gICAgICAgICAgICAgIENVUCRYUGF0aFBhcnNlciRyZXN1bHQgPSBuZXcgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCg2LypGaWx0ZXJFeHByKi8sICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMSkpLmxlZnQsICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0LCBSRVNVTFQpOwotICAgICAgICAgICAgfQotICAgICAgICAgIHJldHVybiBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0OwotCi0gICAgICAgICAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotICAgICAgICAgIGNhc2UgOTk6IC8vIEZpbHRlckV4cHIgOjo9IFByaW1hcnlFeHByCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIEV4cHJlc3Npb24gUkVTVUxUID0gbnVsbDsKLSAgICAgICAgICAgICAgICBpbnQgcHJpbWFyeWxlZnQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0OwotICAgICAgICAgICAgICAgIGludCBwcmltYXJ5cmlnaHQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodDsKLSAgICAgICAgICAgICAgICBFeHByZXNzaW9uIHByaW1hcnkgPSAoRXhwcmVzc2lvbikoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpIENVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkudmFsdWU7Ci0gICAgICAgICAgICAgICAgIFJFU1VMVCA9IHByaW1hcnk7Ci0gICAgICAgICAgICAgIENVUCRYUGF0aFBhcnNlciRyZXN1bHQgPSBuZXcgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCg2LypGaWx0ZXJFeHByKi8sICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLmxlZnQsICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0LCBSRVNVTFQpOwotICAgICAgICAgICAgfQotICAgICAgICAgIHJldHVybiBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0OwotCi0gICAgICAgICAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotICAgICAgICAgIGNhc2UgOTg6IC8vIEFiYnJldmlhdGVkU3RlcCA6Oj0gRERPVAotICAgICAgICAgICAgewotICAgICAgICAgICAgICBFeHByZXNzaW9uIFJFU1VMVCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBTdGVwKEF4aXMuUEFSRU5ULCBOb2RlVGVzdC5BTk9ERSwgbnVsbCk7Ci0gICAgICAgICAgICAgIENVUCRYUGF0aFBhcnNlciRyZXN1bHQgPSBuZXcgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCgyMC8qQWJicmV2aWF0ZWRTdGVwKi8sICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLmxlZnQsICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0LCBSRVNVTFQpOwotICAgICAgICAgICAgfQotICAgICAgICAgIHJldHVybiBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0OwotCi0gICAgICAgICAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotICAgICAgICAgIGNhc2UgOTc6IC8vIEFiYnJldmlhdGVkU3RlcCA6Oj0gRE9UCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIEV4cHJlc3Npb24gUkVTVUxUID0gbnVsbDsKLSAgICAgICAgICAgICAgICAgUkVTVUxUID0gbmV3IFN0ZXAoQXhpcy5TRUxGLCBOb2RlVGVzdC5BTk9ERSwgbnVsbCk7Ci0gICAgICAgICAgICAgIENVUCRYUGF0aFBhcnNlciRyZXN1bHQgPSBuZXcgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCgyMC8qQWJicmV2aWF0ZWRTdGVwKi8sICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLmxlZnQsICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0LCBSRVNVTFQpOwotICAgICAgICAgICAgfQotICAgICAgICAgIHJldHVybiBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0OwotCi0gICAgICAgICAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotICAgICAgICAgIGNhc2UgOTY6IC8vIEF4aXNOYW1lIDo6PSBTRUxGCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIEludGVnZXIgUkVTVUxUID0gbnVsbDsKLSAgICAgICAgICAgICAgICAgUkVTVUxUID0gbmV3IEludGVnZXIoQXhpcy5TRUxGKTsKLSAgICAgICAgICAgICAgQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdCA9IG5ldyBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKDQwLypBeGlzTmFtZSovLCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0LCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodCwgUkVTVUxUKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICByZXR1cm4gQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdDsKLQotICAgICAgICAgIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuKi8KLSAgICAgICAgICBjYXNlIDk1OiAvLyBBeGlzTmFtZSA6Oj0gUFJFQ0VESU5HU0lCTElORwotICAgICAgICAgICAgewotICAgICAgICAgICAgICBJbnRlZ2VyIFJFU1VMVCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBJbnRlZ2VyKEF4aXMuUFJFQ0VESU5HU0lCTElORyk7Ci0gICAgICAgICAgICAgIENVUCRYUGF0aFBhcnNlciRyZXN1bHQgPSBuZXcgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCg0MC8qQXhpc05hbWUqLywgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkubGVmdCwgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQsIFJFU1VMVCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgcmV0dXJuIENVUCRYUGF0aFBhcnNlciRyZXN1bHQ7Ci0KLSAgICAgICAgICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0gICAgICAgICAgY2FzZSA5NDogLy8gQXhpc05hbWUgOjo9IFBSRUNFRElORwotICAgICAgICAgICAgewotICAgICAgICAgICAgICBJbnRlZ2VyIFJFU1VMVCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBJbnRlZ2VyKEF4aXMuUFJFQ0VESU5HKTsKLSAgICAgICAgICAgICAgQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdCA9IG5ldyBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKDQwLypBeGlzTmFtZSovLCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0LCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodCwgUkVTVUxUKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICByZXR1cm4gQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdDsKLQotICAgICAgICAgIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuKi8KLSAgICAgICAgICBjYXNlIDkzOiAvLyBBeGlzTmFtZSA6Oj0gUEFSRU5UCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIEludGVnZXIgUkVTVUxUID0gbnVsbDsKLSAgICAgICAgICAgICAgICAgUkVTVUxUID0gbmV3IEludGVnZXIoQXhpcy5QQVJFTlQpOwotICAgICAgICAgICAgICBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0ID0gbmV3IGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2woNDAvKkF4aXNOYW1lKi8sICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLmxlZnQsICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0LCBSRVNVTFQpOwotICAgICAgICAgICAgfQotICAgICAgICAgIHJldHVybiBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0OwotCi0gICAgICAgICAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotICAgICAgICAgIGNhc2UgOTI6IC8vIEF4aXNOYW1lIDo6PSBOQU1FU1BBQ0UKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgSW50ZWdlciBSRVNVTFQgPSBudWxsOwotICAgICAgICAgICAgICAgICBSRVNVTFQgPSBuZXcgSW50ZWdlcihBeGlzLk5BTUVTUEFDRSk7Ci0gICAgICAgICAgICAgIENVUCRYUGF0aFBhcnNlciRyZXN1bHQgPSBuZXcgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCg0MC8qQXhpc05hbWUqLywgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkubGVmdCwgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQsIFJFU1VMVCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgcmV0dXJuIENVUCRYUGF0aFBhcnNlciRyZXN1bHQ7Ci0KLSAgICAgICAgICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0gICAgICAgICAgY2FzZSA5MTogLy8gQXhpc05hbWUgOjo9IEZPTExPV0lOR1NJQkxJTkcKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgSW50ZWdlciBSRVNVTFQgPSBudWxsOwotICAgICAgICAgICAgICAgICBSRVNVTFQgPSBuZXcgSW50ZWdlcihBeGlzLkZPTExPV0lOR1NJQkxJTkcpOwotICAgICAgICAgICAgICBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0ID0gbmV3IGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2woNDAvKkF4aXNOYW1lKi8sICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLmxlZnQsICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0LCBSRVNVTFQpOwotICAgICAgICAgICAgfQotICAgICAgICAgIHJldHVybiBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0OwotCi0gICAgICAgICAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotICAgICAgICAgIGNhc2UgOTA6IC8vIEF4aXNOYW1lIDo6PSBGT0xMT1dJTkcKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgSW50ZWdlciBSRVNVTFQgPSBudWxsOwotICAgICAgICAgICAgICAgICBSRVNVTFQgPSBuZXcgSW50ZWdlcihBeGlzLkZPTExPV0lORyk7Ci0gICAgICAgICAgICAgIENVUCRYUGF0aFBhcnNlciRyZXN1bHQgPSBuZXcgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCg0MC8qQXhpc05hbWUqLywgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkubGVmdCwgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQsIFJFU1VMVCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgcmV0dXJuIENVUCRYUGF0aFBhcnNlciRyZXN1bHQ7Ci0KLSAgICAgICAgICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0gICAgICAgICAgY2FzZSA4OTogLy8gQXhpc05hbWUgOjo9IERFU0NFTkRBTlRPUlNFTEYKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgSW50ZWdlciBSRVNVTFQgPSBudWxsOwotICAgICAgICAgICAgICAgICBSRVNVTFQgPSBuZXcgSW50ZWdlcihBeGlzLkRFU0NFTkRBTlRPUlNFTEYpOwotICAgICAgICAgICAgICBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0ID0gbmV3IGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2woNDAvKkF4aXNOYW1lKi8sICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLmxlZnQsICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0LCBSRVNVTFQpOwotICAgICAgICAgICAgfQotICAgICAgICAgIHJldHVybiBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0OwotCi0gICAgICAgICAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotICAgICAgICAgIGNhc2UgODg6IC8vIEF4aXNOYW1lIDo6PSBERVNDRU5EQU5UCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIEludGVnZXIgUkVTVUxUID0gbnVsbDsKLSAgICAgICAgICAgICAgICAgUkVTVUxUID0gbmV3IEludGVnZXIoQXhpcy5ERVNDRU5EQU5UKTsKLSAgICAgICAgICAgICAgQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdCA9IG5ldyBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKDQwLypBeGlzTmFtZSovLCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0LCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodCwgUkVTVUxUKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICByZXR1cm4gQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdDsKLQotICAgICAgICAgIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuKi8KLSAgICAgICAgICBjYXNlIDg3OiAvLyBBeGlzTmFtZSA6Oj0gQ0hJTEQKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgSW50ZWdlciBSRVNVTFQgPSBudWxsOwotICAgICAgICAgICAgICAgICBSRVNVTFQgPSBuZXcgSW50ZWdlcihBeGlzLkNISUxEKTsKLSAgICAgICAgICAgICAgQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdCA9IG5ldyBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKDQwLypBeGlzTmFtZSovLCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0LCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodCwgUkVTVUxUKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICByZXR1cm4gQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdDsKLQotICAgICAgICAgIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuKi8KLSAgICAgICAgICBjYXNlIDg2OiAvLyBBeGlzTmFtZSA6Oj0gQVRUUklCVVRFCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIEludGVnZXIgUkVTVUxUID0gbnVsbDsKLSAgICAgICAgICAgICAgICAgUkVTVUxUID0gbmV3IEludGVnZXIoQXhpcy5BVFRSSUJVVEUpOwotICAgICAgICAgICAgICBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0ID0gbmV3IGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2woNDAvKkF4aXNOYW1lKi8sICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLmxlZnQsICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0LCBSRVNVTFQpOwotICAgICAgICAgICAgfQotICAgICAgICAgIHJldHVybiBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0OwotCi0gICAgICAgICAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotICAgICAgICAgIGNhc2UgODU6IC8vIEF4aXNOYW1lIDo6PSBBTkNFU1RPUk9SU0VMRgotICAgICAgICAgICAgewotICAgICAgICAgICAgICBJbnRlZ2VyIFJFU1VMVCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBJbnRlZ2VyKEF4aXMuQU5DRVNUT1JPUlNFTEYpOwotICAgICAgICAgICAgICBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0ID0gbmV3IGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2woNDAvKkF4aXNOYW1lKi8sICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLmxlZnQsICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0LCBSRVNVTFQpOwotICAgICAgICAgICAgfQotICAgICAgICAgIHJldHVybiBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0OwotCi0gICAgICAgICAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotICAgICAgICAgIGNhc2UgODQ6IC8vIEF4aXNOYW1lIDo6PSBBTkNFU1RPUgotICAgICAgICAgICAgewotICAgICAgICAgICAgICBJbnRlZ2VyIFJFU1VMVCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBJbnRlZ2VyKEF4aXMuQU5DRVNUT1IpOwotICAgICAgICAgICAgICBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0ID0gbmV3IGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2woNDAvKkF4aXNOYW1lKi8sICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLmxlZnQsICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0LCBSRVNVTFQpOwotICAgICAgICAgICAgfQotICAgICAgICAgIHJldHVybiBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0OwotCi0gICAgICAgICAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotICAgICAgICAgIGNhc2UgODM6IC8vIEF4aXNTcGVjaWZpZXIgOjo9IEFUU0lHTgotICAgICAgICAgICAgewotICAgICAgICAgICAgICBJbnRlZ2VyIFJFU1VMVCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBJbnRlZ2VyKEF4aXMuQVRUUklCVVRFKTsKLSAgICAgICAgICAgICAgQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdCA9IG5ldyBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKDQxLypBeGlzU3BlY2lmaWVyKi8sICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLmxlZnQsICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0LCBSRVNVTFQpOwotICAgICAgICAgICAgfQotICAgICAgICAgIHJldHVybiBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0OwotCi0gICAgICAgICAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotICAgICAgICAgIGNhc2UgODI6IC8vIEF4aXNTcGVjaWZpZXIgOjo9IEF4aXNOYW1lIERDT0xPTgotICAgICAgICAgICAgewotICAgICAgICAgICAgICBJbnRlZ2VyIFJFU1VMVCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgaW50IGFubGVmdCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMSkpLmxlZnQ7Ci0gICAgICAgICAgICAgICAgaW50IGFucmlnaHQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTEpKS5yaWdodDsKLSAgICAgICAgICAgICAgICBJbnRlZ2VyIGFuID0gKEludGVnZXIpKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKSBDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMSkpLnZhbHVlOwotICAgICAgICAgICAgICAgICBSRVNVTFQgPSBhbjsKLSAgICAgICAgICAgICAgQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdCA9IG5ldyBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKDQxLypBeGlzU3BlY2lmaWVyKi8sICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMSkpLmxlZnQsICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0LCBSRVNVTFQpOwotICAgICAgICAgICAgfQotICAgICAgICAgIHJldHVybiBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0OwotCi0gICAgICAgICAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotICAgICAgICAgIGNhc2UgODE6IC8vIFN0ZXAgOjo9IEFiYnJldmlhdGVkU3RlcAotICAgICAgICAgICAgewotICAgICAgICAgICAgICBFeHByZXNzaW9uIFJFU1VMVCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgaW50IGFiYnJldmxlZnQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0OwotICAgICAgICAgICAgICAgIGludCBhYmJyZXZyaWdodCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0OwotICAgICAgICAgICAgICAgIEV4cHJlc3Npb24gYWJicmV2ID0gKEV4cHJlc3Npb24pKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKSBDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnZhbHVlOwotICAgICAgICAgICAgICAgICBSRVNVTFQgPSBhYmJyZXY7Ci0gICAgICAgICAgICAgIENVUCRYUGF0aFBhcnNlciRyZXN1bHQgPSBuZXcgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCg3LypTdGVwKi8sICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLmxlZnQsICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0LCBSRVNVTFQpOwotICAgICAgICAgICAgfQotICAgICAgICAgIHJldHVybiBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0OwotCi0gICAgICAgICAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotICAgICAgICAgIGNhc2UgODA6IC8vIFN0ZXAgOjo9IEF4aXNTcGVjaWZpZXIgTm9kZVRlc3QKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgRXhwcmVzc2lvbiBSRVNVTFQgPSBudWxsOwotICAgICAgICAgICAgICAgIGludCBheGlzbGVmdCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMSkpLmxlZnQ7Ci0gICAgICAgICAgICAgICAgaW50IGF4aXNyaWdodCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMSkpLnJpZ2h0OwotICAgICAgICAgICAgICAgIEludGVnZXIgYXhpcyA9IChJbnRlZ2VyKSgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCkgQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTEpKS52YWx1ZTsKLSAgICAgICAgICAgICAgICBpbnQgbnRlc3RsZWZ0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkubGVmdDsKLSAgICAgICAgICAgICAgICBpbnQgbnRlc3RyaWdodCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0OwotICAgICAgICAgICAgICAgIE9iamVjdCBudGVzdCA9IChPYmplY3QpKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKSBDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnZhbHVlOwotICAgICAgICAgICAgICAgICBSRVNVTFQgPSBuZXcgU3RlcChheGlzLmludFZhbHVlKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcnNlci5maW5kTm9kZVR5cGUoYXhpcy5pbnRWYWx1ZSgpLCBudGVzdCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwpOwotCi0gICAgICAgICAgICAgIENVUCRYUGF0aFBhcnNlciRyZXN1bHQgPSBuZXcgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCg3LypTdGVwKi8sICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMSkpLmxlZnQsICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0LCBSRVNVTFQpOwotICAgICAgICAgICAgfQotICAgICAgICAgIHJldHVybiBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0OwotCi0gICAgICAgICAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotICAgICAgICAgIGNhc2UgNzk6IC8vIFN0ZXAgOjo9IEF4aXNTcGVjaWZpZXIgTm9kZVRlc3QgUHJlZGljYXRlcwotICAgICAgICAgICAgewotICAgICAgICAgICAgICBFeHByZXNzaW9uIFJFU1VMVCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgaW50IGF4aXNsZWZ0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0yKSkubGVmdDsKLSAgICAgICAgICAgICAgICBpbnQgYXhpc3JpZ2h0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0yKSkucmlnaHQ7Ci0gICAgICAgICAgICAgICAgSW50ZWdlciBheGlzID0gKEludGVnZXIpKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKSBDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMikpLnZhbHVlOwotICAgICAgICAgICAgICAgIGludCBudGVzdGxlZnQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTEpKS5sZWZ0OwotICAgICAgICAgICAgICAgIGludCBudGVzdHJpZ2h0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0xKSkucmlnaHQ7Ci0gICAgICAgICAgICAgICAgT2JqZWN0IG50ZXN0ID0gKE9iamVjdCkoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpIENVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0xKSkudmFsdWU7Ci0gICAgICAgICAgICAgICAgaW50IHBwbGVmdCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLmxlZnQ7Ci0gICAgICAgICAgICAgICAgaW50IHBwcmlnaHQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodDsKLSAgICAgICAgICAgICAgICBWZWN0b3IgcHAgPSAoVmVjdG9yKSgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCkgQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS52YWx1ZTsKLSAgICAgICAgICAgICAgICAgUkVTVUxUID0gbmV3IFN0ZXAoYXhpcy5pbnRWYWx1ZSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJzZXIuZmluZE5vZGVUeXBlKGF4aXMuaW50VmFsdWUoKSwgbnRlc3QpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcCk7Ci0KLSAgICAgICAgICAgICAgQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdCA9IG5ldyBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKDcvKlN0ZXAqLywgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0yKSkubGVmdCwgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQsIFJFU1VMVCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgcmV0dXJuIENVUCRYUGF0aFBhcnNlciRyZXN1bHQ7Ci0KLSAgICAgICAgICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0gICAgICAgICAgY2FzZSA3ODogLy8gU3RlcCA6Oj0gTm9kZVRlc3QgUHJlZGljYXRlcwotICAgICAgICAgICAgewotICAgICAgICAgICAgICBFeHByZXNzaW9uIFJFU1VMVCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgaW50IG50ZXN0bGVmdCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMSkpLmxlZnQ7Ci0gICAgICAgICAgICAgICAgaW50IG50ZXN0cmlnaHQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTEpKS5yaWdodDsKLSAgICAgICAgICAgICAgICBPYmplY3QgbnRlc3QgPSAoT2JqZWN0KSgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCkgQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTEpKS52YWx1ZTsKLSAgICAgICAgICAgICAgICBpbnQgcHBsZWZ0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkubGVmdDsKLSAgICAgICAgICAgICAgICBpbnQgcHByaWdodCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0OwotICAgICAgICAgICAgICAgIFZlY3RvciBwcCA9IChWZWN0b3IpKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKSBDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnZhbHVlOwotCi0gICAgICAgICAgICBpZiAobnRlc3QgaW5zdGFuY2VvZiBTdGVwKSB7Ci0gICAgICAgICAgICAgICAgU3RlcCBzdGVwID0gKFN0ZXApbnRlc3Q7Ci0gICAgICAgICAgICAgICAgc3RlcC5hZGRQcmVkaWNhdGVzKHBwKTsKLSAgICAgICAgICAgICAgICBSRVNVTFQgPSAoU3RlcCludGVzdDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBTdGVwKEF4aXMuQ0hJTEQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcnNlci5maW5kTm9kZVR5cGUoQXhpcy5DSElMRCwgbnRlc3QpLCBwcCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdCA9IG5ldyBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKDcvKlN0ZXAqLywgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0xKSkubGVmdCwgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQsIFJFU1VMVCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgcmV0dXJuIENVUCRYUGF0aFBhcnNlciRyZXN1bHQ7Ci0KLSAgICAgICAgICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0gICAgICAgICAgY2FzZSA3NzogLy8gU3RlcCA6Oj0gTm9kZVRlc3QKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgRXhwcmVzc2lvbiBSRVNVTFQgPSBudWxsOwotICAgICAgICAgICAgICAgIGludCBudGVzdGxlZnQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0OwotICAgICAgICAgICAgICAgIGludCBudGVzdHJpZ2h0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQ7Ci0gICAgICAgICAgICAgICAgT2JqZWN0IG50ZXN0ID0gKE9iamVjdCkoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpIENVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkudmFsdWU7Ci0KLSAgICAgICAgICAgIGlmIChudGVzdCBpbnN0YW5jZW9mIFN0ZXApIHsKLSAgICAgICAgICAgICAgICBSRVNVTFQgPSAoU3RlcCludGVzdDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBTdGVwKEF4aXMuQ0hJTEQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcnNlci5maW5kTm9kZVR5cGUoQXhpcy5DSElMRCwgbnRlc3QpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0ID0gbmV3IGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2woNy8qU3RlcCovLCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0LCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodCwgUkVTVUxUKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICByZXR1cm4gQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdDsKLQotICAgICAgICAgIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuKi8KLSAgICAgICAgICBjYXNlIDc2OiAvLyBBYmJyZXZpYXRlZEFic29sdXRlTG9jYXRpb25QYXRoIDo6PSBEU0xBU0ggUmVsYXRpdmVMb2NhdGlvblBhdGgKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgRXhwcmVzc2lvbiBSRVNVTFQgPSBudWxsOwotICAgICAgICAgICAgICAgIGludCBybHBsZWZ0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkubGVmdDsKLSAgICAgICAgICAgICAgICBpbnQgcmxwcmlnaHQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodDsKLSAgICAgICAgICAgICAgICBFeHByZXNzaW9uIHJscCA9IChFeHByZXNzaW9uKSgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCkgQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS52YWx1ZTsKLQotICAgICAgICAgICAvLwotICAgICAgICAgICAvLyBFeHBhbmQgJy8vJyBpbnRvICcvZGVzY2VuZGFudC1vci1zZWxmOjpub2RlKCkvJyBvcgotICAgICAgICAgICAvLyBpbnRvIC9kZXNjZW5kYW50LW9yLXNlbGY6OiovCi0gICAgICAgICAgIC8vCi0gICAgICAgICAgIGludCBub2RlVHlwZSA9IERPTS5OT19UWVBFOwotICAgICAgICAgICBpZiAocmxwIGluc3RhbmNlb2YgU3RlcCAmJgotICAgICAgICAgICAgICAgcGFyc2VyLmlzRWxlbWVudEF4aXMoKChTdGVwKSBybHApLmdldEF4aXMoKSkpCi0gICAgICAgICAgIHsKLSAgICAgICAgICAgICAgIG5vZGVUeXBlID0gRFRNLkVMRU1FTlRfTk9ERTsKLSAgICAgICAgICAgfQotICAgICAgICAgICBmaW5hbCBTdGVwIHN0ZXAgPSBuZXcgU3RlcChBeGlzLkRFU0NFTkRBTlRPUlNFTEYsIG5vZGVUeXBlLCBudWxsKTsKLSAgICAgICAgICAgUkVTVUxUID0gbmV3IEFic29sdXRlTG9jYXRpb25QYXRoKHBhcnNlci5pbnNlcnRTdGVwKHN0ZXAsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChSZWxhdGl2ZUxvY2F0aW9uUGF0aCkgcmxwKSk7Ci0KLSAgICAgICAgICAgICAgQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdCA9IG5ldyBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKDI0LypBYmJyZXZpYXRlZEFic29sdXRlTG9jYXRpb25QYXRoKi8sICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMSkpLmxlZnQsICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0LCBSRVNVTFQpOwotICAgICAgICAgICAgfQotICAgICAgICAgIHJldHVybiBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0OwotCi0gICAgICAgICAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotICAgICAgICAgIGNhc2UgNzU6IC8vIEFiYnJldmlhdGVkUmVsYXRpdmVMb2NhdGlvblBhdGggOjo9IFJlbGF0aXZlTG9jYXRpb25QYXRoIERTTEFTSCBTdGVwCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIEV4cHJlc3Npb24gUkVTVUxUID0gbnVsbDsKLSAgICAgICAgICAgICAgICBpbnQgcmxwbGVmdCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMikpLmxlZnQ7Ci0gICAgICAgICAgICAgICAgaW50IHJscHJpZ2h0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0yKSkucmlnaHQ7Ci0gICAgICAgICAgICAgICAgRXhwcmVzc2lvbiBybHAgPSAoRXhwcmVzc2lvbikoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpIENVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0yKSkudmFsdWU7Ci0gICAgICAgICAgICAgICAgaW50IHN0ZXBsZWZ0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkubGVmdDsKLSAgICAgICAgICAgICAgICBpbnQgc3RlcHJpZ2h0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQ7Ci0gICAgICAgICAgICAgICAgRXhwcmVzc2lvbiBzdGVwID0gKEV4cHJlc3Npb24pKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKSBDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnZhbHVlOwotCi0gICAgICAgICAgIGZpbmFsIFN0ZXAgcmlnaHQgID0gKFN0ZXApc3RlcDsKLSAgICAgICAgICAgZmluYWwgaW50ICBheGlzICAgPSByaWdodC5nZXRBeGlzKCk7Ci0gICAgICAgICAgIGZpbmFsIGludCAgdHlwZSAgID0gcmlnaHQuZ2V0Tm9kZVR5cGUoKTsKLSAgICAgICAgICAgZmluYWwgVmVjdG9yIHByZWRpY2F0ZXMgPSByaWdodC5nZXRQcmVkaWNhdGVzKCk7Ci0KLSAgICAgICAgICAgaWYgKChheGlzID09IEF4aXMuQ0hJTEQpICYmICh0eXBlICE9IE5vZGVUZXN0LkFUVFJJQlVURSkpIHsKLSAgICAgICAgICAgICAgIC8vIENvbXByZXNzICcuLy9jaGlsZDpFJyBpbnRvICdkZXNjZW5kYW50OjpFJyAtIGlmIHBvc3NpYmxlCi0gICAgICAgICAgICAgICBpZiAocHJlZGljYXRlcyA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgcmlnaHQuc2V0QXhpcyhBeGlzLkRFU0NFTkRBTlQpOwotICAgICAgICAgICAgICAgICAgIGlmIChybHAgaW5zdGFuY2VvZiBTdGVwICYmICgoU3RlcClybHApLmlzQWJicmV2aWF0ZWREb3QoKSkgewotICAgICAgICAgICAgICAgICAgICAgICBSRVNVTFQgPSByaWdodDsKLSAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgIC8vIEV4cGFuZCAncmxwLy9jaGlsZDo6RScgaW50byAncmxwL2Rlc2NlbmRhbnQ6OkUnCi0gICAgICAgICAgICAgICAgICAgICAgIFJlbGF0aXZlTG9jYXRpb25QYXRoIGxlZnQgPSAoUmVsYXRpdmVMb2NhdGlvblBhdGgpcmxwOwotICAgICAgICAgICAgICAgICAgICAgICBSRVNVTFQgPSBuZXcgUGFyZW50TG9jYXRpb25QYXRoKGxlZnQsIHJpZ2h0KTsKLSAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAvLyBFeHBhbmQgJy4vL3N0ZXAnIC0+ICdkZXNjZW5kYW50LW9yLXNlbGY6Oiovc3RlcCcKLSAgICAgICAgICAgICAgICAgICBpZiAocmxwIGluc3RhbmNlb2YgU3RlcCAmJiAoKFN0ZXApcmxwKS5pc0FiYnJldmlhdGVkRG90KCkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgU3RlcCBsZWZ0ID0gbmV3IFN0ZXAoQXhpcy5ERVNDRU5EQU5UT1JTRUxGLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIERUTS5FTEVNRU5UX05PREUsIG51bGwpOwotICAgICAgICAgICAgICAgICAgICAgICBSRVNVTFQgPSBuZXcgUGFyZW50TG9jYXRpb25QYXRoKGxlZnQsIHJpZ2h0KTsKLSAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgIC8vIEV4cGFuZCAncmxwLy9zdGVwJyAtPiAncmxwL2Rlc2NlbmRhbnQtb3Itc2VsZjo6Ki9zdGVwJwotICAgICAgICAgICAgICAgICAgICAgICBSZWxhdGl2ZUxvY2F0aW9uUGF0aCBsZWZ0ID0gKFJlbGF0aXZlTG9jYXRpb25QYXRoKXJscDsKLSAgICAgICAgICAgICAgICAgICAgICAgU3RlcCBtaWQgPSBuZXcgU3RlcChBeGlzLkRFU0NFTkRBTlRPUlNFTEYsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgRFRNLkVMRU1FTlRfTk9ERSwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgICAgIFBhcmVudExvY2F0aW9uUGF0aCBwcGwgPSBuZXcgUGFyZW50TG9jYXRpb25QYXRoKG1pZCwgcmlnaHQpOwotICAgICAgICAgICAgICAgICAgICAgICBSRVNVTFQgPSBuZXcgUGFyZW50TG9jYXRpb25QYXRoKGxlZnQsIHBwbCk7Ci0gICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgfQotICAgICAgICAgICB9Ci0gICAgICAgICAgIGVsc2UgaWYgKChheGlzID09IEF4aXMuQVRUUklCVVRFKSB8fCAodHlwZSA9PSBOb2RlVGVzdC5BVFRSSUJVVEUpKSB7Ci0gICAgICAgICAgICAgICAvLyBFeHBhbmQgJ3JscC8vc3RlcCcgLT4gJ3JscC9kZXNjZW5kYW50LW9yLXNlbGY6Oiovc3RlcCcKLSAgICAgICAgICAgICAgIFJlbGF0aXZlTG9jYXRpb25QYXRoIGxlZnQgPSAoUmVsYXRpdmVMb2NhdGlvblBhdGgpcmxwOwotICAgICAgICAgICAgICAgU3RlcCBtaWRkbGUgPSBuZXcgU3RlcChBeGlzLkRFU0NFTkRBTlRPUlNFTEYsCi0gICAgICAgICAgICAgICAgICAgIERUTS5FTEVNRU5UX05PREUsIG51bGwpOwotICAgICAgICAgICAgICAgUGFyZW50TG9jYXRpb25QYXRoIHBwbCA9IG5ldyBQYXJlbnRMb2NhdGlvblBhdGgobWlkZGxlLCByaWdodCk7Ci0gICAgICAgICAgICAgICBSRVNVTFQgPSBuZXcgUGFyZW50TG9jYXRpb25QYXRoKGxlZnQsIHBwbCk7Ci0gICAgICAgICAgIH0KLSAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAvLyBFeHBhbmQgJ3JscC8vc3RlcCcgLT4gJ3JscC9kZXNjZW5kYW50LW9yLXNlbGY6Om5vZGUoKS9zdGVwJwotICAgICAgICAgICAgICAgUmVsYXRpdmVMb2NhdGlvblBhdGggbGVmdCA9IChSZWxhdGl2ZUxvY2F0aW9uUGF0aClybHA7Ci0gICAgICAgICAgICAgICBTdGVwIG1pZGRsZSA9IG5ldyBTdGVwKEF4aXMuREVTQ0VOREFOVE9SU0VMRiwKLSAgICAgICAgICAgICAgICAgICAgRE9NLk5PX1RZUEUsIG51bGwpOwotICAgICAgICAgICAgICAgUGFyZW50TG9jYXRpb25QYXRoIHBwbCA9IG5ldyBQYXJlbnRMb2NhdGlvblBhdGgobWlkZGxlLCByaWdodCk7Ci0gICAgICAgICAgICAgICBSRVNVTFQgPSBuZXcgUGFyZW50TG9jYXRpb25QYXRoKGxlZnQsIHBwbCk7Ci0gICAgICAgICAgIH0KLQotICAgICAgICAgICAgICBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0ID0gbmV3IGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2woMjIvKkFiYnJldmlhdGVkUmVsYXRpdmVMb2NhdGlvblBhdGgqLywgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0yKSkubGVmdCwgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQsIFJFU1VMVCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgcmV0dXJuIENVUCRYUGF0aFBhcnNlciRyZXN1bHQ7Ci0KLSAgICAgICAgICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0gICAgICAgICAgY2FzZSA3NDogLy8gQWJzb2x1dGVMb2NhdGlvblBhdGggOjo9IEFiYnJldmlhdGVkQWJzb2x1dGVMb2NhdGlvblBhdGgKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgRXhwcmVzc2lvbiBSRVNVTFQgPSBudWxsOwotICAgICAgICAgICAgICAgIGludCBhYWxwbGVmdCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLmxlZnQ7Ci0gICAgICAgICAgICAgICAgaW50IGFhbHByaWdodCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0OwotICAgICAgICAgICAgICAgIEV4cHJlc3Npb24gYWFscCA9IChFeHByZXNzaW9uKSgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCkgQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS52YWx1ZTsKLSAgICAgICAgICAgICAgICAgUkVTVUxUID0gYWFscDsKLSAgICAgICAgICAgICAgQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdCA9IG5ldyBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKDIzLypBYnNvbHV0ZUxvY2F0aW9uUGF0aCovLCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0LCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodCwgUkVTVUxUKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICByZXR1cm4gQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdDsKLQotICAgICAgICAgIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuKi8KLSAgICAgICAgICBjYXNlIDczOiAvLyBBYnNvbHV0ZUxvY2F0aW9uUGF0aCA6Oj0gU0xBU0ggUmVsYXRpdmVMb2NhdGlvblBhdGgKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgRXhwcmVzc2lvbiBSRVNVTFQgPSBudWxsOwotICAgICAgICAgICAgICAgIGludCBybHBsZWZ0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkubGVmdDsKLSAgICAgICAgICAgICAgICBpbnQgcmxwcmlnaHQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodDsKLSAgICAgICAgICAgICAgICBFeHByZXNzaW9uIHJscCA9IChFeHByZXNzaW9uKSgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCkgQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS52YWx1ZTsKLSAgICAgICAgICAgICAgICAgUkVTVUxUID0gbmV3IEFic29sdXRlTG9jYXRpb25QYXRoKHJscCk7Ci0gICAgICAgICAgICAgIENVUCRYUGF0aFBhcnNlciRyZXN1bHQgPSBuZXcgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCgyMy8qQWJzb2x1dGVMb2NhdGlvblBhdGgqLywgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0xKSkubGVmdCwgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQsIFJFU1VMVCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgcmV0dXJuIENVUCRYUGF0aFBhcnNlciRyZXN1bHQ7Ci0KLSAgICAgICAgICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0gICAgICAgICAgY2FzZSA3MjogLy8gQWJzb2x1dGVMb2NhdGlvblBhdGggOjo9IFNMQVNICi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIEV4cHJlc3Npb24gUkVTVUxUID0gbnVsbDsKLSAgICAgICAgICAgICAgICAgUkVTVUxUID0gbmV3IEFic29sdXRlTG9jYXRpb25QYXRoKCk7Ci0gICAgICAgICAgICAgIENVUCRYUGF0aFBhcnNlciRyZXN1bHQgPSBuZXcgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCgyMy8qQWJzb2x1dGVMb2NhdGlvblBhdGgqLywgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkubGVmdCwgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQsIFJFU1VMVCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgcmV0dXJuIENVUCRYUGF0aFBhcnNlciRyZXN1bHQ7Ci0KLSAgICAgICAgICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0gICAgICAgICAgY2FzZSA3MTogLy8gUmVsYXRpdmVMb2NhdGlvblBhdGggOjo9IEFiYnJldmlhdGVkUmVsYXRpdmVMb2NhdGlvblBhdGgKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgRXhwcmVzc2lvbiBSRVNVTFQgPSBudWxsOwotICAgICAgICAgICAgICAgIGludCBhcmxwbGVmdCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLmxlZnQ7Ci0gICAgICAgICAgICAgICAgaW50IGFybHByaWdodCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0OwotICAgICAgICAgICAgICAgIEV4cHJlc3Npb24gYXJscCA9IChFeHByZXNzaW9uKSgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCkgQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS52YWx1ZTsKLSAgICAgICAgICAgICAgICAgUkVTVUxUID0gYXJscDsKLSAgICAgICAgICAgICAgQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdCA9IG5ldyBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKDIxLypSZWxhdGl2ZUxvY2F0aW9uUGF0aCovLCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0LCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodCwgUkVTVUxUKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICByZXR1cm4gQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdDsKLQotICAgICAgICAgIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuKi8KLSAgICAgICAgICBjYXNlIDcwOiAvLyBSZWxhdGl2ZUxvY2F0aW9uUGF0aCA6Oj0gUmVsYXRpdmVMb2NhdGlvblBhdGggU0xBU0ggU3RlcAotICAgICAgICAgICAgewotICAgICAgICAgICAgICBFeHByZXNzaW9uIFJFU1VMVCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgaW50IHJscGxlZnQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTIpKS5sZWZ0OwotICAgICAgICAgICAgICAgIGludCBybHByaWdodCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMikpLnJpZ2h0OwotICAgICAgICAgICAgICAgIEV4cHJlc3Npb24gcmxwID0gKEV4cHJlc3Npb24pKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKSBDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMikpLnZhbHVlOwotICAgICAgICAgICAgICAgIGludCBzdGVwbGVmdCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLmxlZnQ7Ci0gICAgICAgICAgICAgICAgaW50IHN0ZXByaWdodCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0OwotICAgICAgICAgICAgICAgIEV4cHJlc3Npb24gc3RlcCA9IChFeHByZXNzaW9uKSgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCkgQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS52YWx1ZTsKLQotICAgICAgICBpZiAocmxwIGluc3RhbmNlb2YgU3RlcCAmJiAoKFN0ZXApIHJscCkuaXNBYmJyZXZpYXRlZERvdCgpKSB7Ci0gICAgICAgICAgICAgIFJFU1VMVCA9IHN0ZXA7ICAgICAgIC8vIFJlbW92ZSAnLi8nIGZyb20gdGhlIG1pZGRsZQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKCgoU3RlcCkgc3RlcCkuaXNBYmJyZXZpYXRlZERvdCgpKSB7Ci0gICAgICAgICAgICAgIFJFU1VMVCA9IHJscDsgICAgICAgIC8vIFJlbW92ZSAnLy4nIGZyb20gdGhlIGVuZAotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgIFJFU1VMVCA9Ci0gICAgICAgICAgICAgICAgbmV3IFBhcmVudExvY2F0aW9uUGF0aCgoUmVsYXRpdmVMb2NhdGlvblBhdGgpIHJscCwgc3RlcCk7Ci0gICAgICAgICAgIH0KLQotICAgICAgICAgICAgICBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0ID0gbmV3IGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2woMjEvKlJlbGF0aXZlTG9jYXRpb25QYXRoKi8sICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMikpLmxlZnQsICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0LCBSRVNVTFQpOwotICAgICAgICAgICAgfQotICAgICAgICAgIHJldHVybiBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0OwotCi0gICAgICAgICAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotICAgICAgICAgIGNhc2UgNjk6IC8vIFJlbGF0aXZlTG9jYXRpb25QYXRoIDo6PSBTdGVwCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIEV4cHJlc3Npb24gUkVTVUxUID0gbnVsbDsKLSAgICAgICAgICAgICAgICBpbnQgc3RlcGxlZnQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0OwotICAgICAgICAgICAgICAgIGludCBzdGVwcmlnaHQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodDsKLSAgICAgICAgICAgICAgICBFeHByZXNzaW9uIHN0ZXAgPSAoRXhwcmVzc2lvbikoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpIENVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkudmFsdWU7Ci0gICAgICAgICAgICAgICAgIFJFU1VMVCA9IHN0ZXA7Ci0gICAgICAgICAgICAgIENVUCRYUGF0aFBhcnNlciRyZXN1bHQgPSBuZXcgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCgyMS8qUmVsYXRpdmVMb2NhdGlvblBhdGgqLywgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkubGVmdCwgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQsIFJFU1VMVCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgcmV0dXJuIENVUCRYUGF0aFBhcnNlciRyZXN1bHQ7Ci0KLSAgICAgICAgICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0gICAgICAgICAgY2FzZSA2ODogLy8gTG9jYXRpb25QYXRoIDo6PSBBYnNvbHV0ZUxvY2F0aW9uUGF0aAotICAgICAgICAgICAgewotICAgICAgICAgICAgICBFeHByZXNzaW9uIFJFU1VMVCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgaW50IGFscGxlZnQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0OwotICAgICAgICAgICAgICAgIGludCBhbHByaWdodCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0OwotICAgICAgICAgICAgICAgIEV4cHJlc3Npb24gYWxwID0gKEV4cHJlc3Npb24pKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKSBDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnZhbHVlOwotICAgICAgICAgICAgICAgICBSRVNVTFQgPSBhbHA7Ci0gICAgICAgICAgICAgIENVUCRYUGF0aFBhcnNlciRyZXN1bHQgPSBuZXcgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCg0LypMb2NhdGlvblBhdGgqLywgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkubGVmdCwgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQsIFJFU1VMVCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgcmV0dXJuIENVUCRYUGF0aFBhcnNlciRyZXN1bHQ7Ci0KLSAgICAgICAgICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0gICAgICAgICAgY2FzZSA2NzogLy8gTG9jYXRpb25QYXRoIDo6PSBSZWxhdGl2ZUxvY2F0aW9uUGF0aAotICAgICAgICAgICAgewotICAgICAgICAgICAgICBFeHByZXNzaW9uIFJFU1VMVCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgaW50IHJscGxlZnQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0OwotICAgICAgICAgICAgICAgIGludCBybHByaWdodCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0OwotICAgICAgICAgICAgICAgIEV4cHJlc3Npb24gcmxwID0gKEV4cHJlc3Npb24pKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKSBDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnZhbHVlOwotICAgICAgICAgICAgICAgICBSRVNVTFQgPSBybHA7Ci0gICAgICAgICAgICAgIENVUCRYUGF0aFBhcnNlciRyZXN1bHQgPSBuZXcgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCg0LypMb2NhdGlvblBhdGgqLywgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkubGVmdCwgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQsIFJFU1VMVCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgcmV0dXJuIENVUCRYUGF0aFBhcnNlciRyZXN1bHQ7Ci0KLSAgICAgICAgICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0gICAgICAgICAgY2FzZSA2NjogLy8gUGF0aEV4cHIgOjo9IEZpbHRlckV4cHIgRFNMQVNIIFJlbGF0aXZlTG9jYXRpb25QYXRoCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIEV4cHJlc3Npb24gUkVTVUxUID0gbnVsbDsKLSAgICAgICAgICAgICAgICBpbnQgZmV4cGxlZnQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTIpKS5sZWZ0OwotICAgICAgICAgICAgICAgIGludCBmZXhwcmlnaHQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTIpKS5yaWdodDsKLSAgICAgICAgICAgICAgICBFeHByZXNzaW9uIGZleHAgPSAoRXhwcmVzc2lvbikoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpIENVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0yKSkudmFsdWU7Ci0gICAgICAgICAgICAgICAgaW50IHJscGxlZnQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0OwotICAgICAgICAgICAgICAgIGludCBybHByaWdodCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0OwotICAgICAgICAgICAgICAgIEV4cHJlc3Npb24gcmxwID0gKEV4cHJlc3Npb24pKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKSBDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnZhbHVlOwotCi0gICAgICAgICAgIC8vCi0gICAgICAgICAgIC8vIEV4cGFuZCAnLy8nIGludG8gJy9kZXNjZW5kYW50LW9yLXNlbGY6Om5vZGUoKS8nIG9yCi0gICAgICAgICAgIC8vIGludG8gL2Rlc2NlbmRhbnQtb3Itc2VsZjo6Ki8KLSAgICAgICAgICAgLy8KLSAgICAgICAgICAgaW50IG5vZGVUeXBlID0gRE9NLk5PX1RZUEU7Ci0gICAgICAgICAgIGlmIChybHAgaW5zdGFuY2VvZiBTdGVwICYmCi0gICAgICAgICAgICAgICBwYXJzZXIuaXNFbGVtZW50QXhpcygoKFN0ZXApIHJscCkuZ2V0QXhpcygpKSkKLSAgICAgICAgICAgewotICAgICAgICAgICAgICAgbm9kZVR5cGUgPSBEVE0uRUxFTUVOVF9OT0RFOwotICAgICAgICAgICB9Ci0gICAgICAgICAgIGZpbmFsIFN0ZXAgc3RlcCA9IG5ldyBTdGVwKEF4aXMuREVTQ0VOREFOVE9SU0VMRiwgbm9kZVR5cGUsIG51bGwpOwotICAgICAgICAgICBGaWx0ZXJQYXJlbnRQYXRoIGZwcCA9IG5ldyBGaWx0ZXJQYXJlbnRQYXRoKGZleHAsIHN0ZXApOwotICAgICAgICAgICBmcHAgPSBuZXcgRmlsdGVyUGFyZW50UGF0aChmcHAsIHJscCk7Ci0gICAgICAgICAgIGlmIChmZXhwIGluc3RhbmNlb2YgS2V5Q2FsbCA9PSBmYWxzZSkgewotICAgICAgICAgICAgICAgZnBwLnNldERlc2NlbmRhbnRBeGlzKCk7Ci0gICAgICAgICAgIH0KLSAgICAgICAgICAgUkVTVUxUID0gZnBwOwotCi0gICAgICAgICAgICAgIENVUCRYUGF0aFBhcnNlciRyZXN1bHQgPSBuZXcgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCgxOS8qUGF0aEV4cHIqLywgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0yKSkubGVmdCwgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQsIFJFU1VMVCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgcmV0dXJuIENVUCRYUGF0aFBhcnNlciRyZXN1bHQ7Ci0KLSAgICAgICAgICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0gICAgICAgICAgY2FzZSA2NTogLy8gUGF0aEV4cHIgOjo9IEZpbHRlckV4cHIgU0xBU0ggUmVsYXRpdmVMb2NhdGlvblBhdGgKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgRXhwcmVzc2lvbiBSRVNVTFQgPSBudWxsOwotICAgICAgICAgICAgICAgIGludCBmZXhwbGVmdCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMikpLmxlZnQ7Ci0gICAgICAgICAgICAgICAgaW50IGZleHByaWdodCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMikpLnJpZ2h0OwotICAgICAgICAgICAgICAgIEV4cHJlc3Npb24gZmV4cCA9IChFeHByZXNzaW9uKSgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCkgQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTIpKS52YWx1ZTsKLSAgICAgICAgICAgICAgICBpbnQgcmxwbGVmdCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLmxlZnQ7Ci0gICAgICAgICAgICAgICAgaW50IHJscHJpZ2h0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQ7Ci0gICAgICAgICAgICAgICAgRXhwcmVzc2lvbiBybHAgPSAoRXhwcmVzc2lvbikoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpIENVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkudmFsdWU7Ci0gICAgICAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBGaWx0ZXJQYXJlbnRQYXRoKGZleHAsIHJscCk7Ci0gICAgICAgICAgICAgIENVUCRYUGF0aFBhcnNlciRyZXN1bHQgPSBuZXcgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCgxOS8qUGF0aEV4cHIqLywgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0yKSkubGVmdCwgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQsIFJFU1VMVCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgcmV0dXJuIENVUCRYUGF0aFBhcnNlciRyZXN1bHQ7Ci0KLSAgICAgICAgICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0gICAgICAgICAgY2FzZSA2NDogLy8gUGF0aEV4cHIgOjo9IEZpbHRlckV4cHIKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgRXhwcmVzc2lvbiBSRVNVTFQgPSBudWxsOwotICAgICAgICAgICAgICAgIGludCBmZXhwbGVmdCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLmxlZnQ7Ci0gICAgICAgICAgICAgICAgaW50IGZleHByaWdodCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0OwotICAgICAgICAgICAgICAgIEV4cHJlc3Npb24gZmV4cCA9IChFeHByZXNzaW9uKSgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCkgQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS52YWx1ZTsKLSAgICAgICAgICAgICAgICAgUkVTVUxUID0gZmV4cDsKLSAgICAgICAgICAgICAgQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdCA9IG5ldyBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKDE5LypQYXRoRXhwciovLCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0LCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodCwgUkVTVUxUKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICByZXR1cm4gQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdDsKLQotICAgICAgICAgIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuKi8KLSAgICAgICAgICBjYXNlIDYzOiAvLyBQYXRoRXhwciA6Oj0gTG9jYXRpb25QYXRoCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIEV4cHJlc3Npb24gUkVTVUxUID0gbnVsbDsKLSAgICAgICAgICAgICAgICBpbnQgbHBsZWZ0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkubGVmdDsKLSAgICAgICAgICAgICAgICBpbnQgbHByaWdodCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0OwotICAgICAgICAgICAgICAgIEV4cHJlc3Npb24gbHAgPSAoRXhwcmVzc2lvbikoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpIENVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkudmFsdWU7Ci0gICAgICAgICAgICAgICAgIFJFU1VMVCA9IGxwOwotICAgICAgICAgICAgICBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0ID0gbmV3IGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2woMTkvKlBhdGhFeHByKi8sICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLmxlZnQsICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0LCBSRVNVTFQpOwotICAgICAgICAgICAgfQotICAgICAgICAgIHJldHVybiBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0OwotCi0gICAgICAgICAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotICAgICAgICAgIGNhc2UgNjI6IC8vIFVuaW9uRXhwciA6Oj0gUGF0aEV4cHIgVkJBUiBVbmlvbkV4cHIKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgRXhwcmVzc2lvbiBSRVNVTFQgPSBudWxsOwotICAgICAgICAgICAgICAgIGludCBwZWxlZnQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTIpKS5sZWZ0OwotICAgICAgICAgICAgICAgIGludCBwZXJpZ2h0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0yKSkucmlnaHQ7Ci0gICAgICAgICAgICAgICAgRXhwcmVzc2lvbiBwZSA9IChFeHByZXNzaW9uKSgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCkgQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTIpKS52YWx1ZTsKLSAgICAgICAgICAgICAgICBpbnQgcmVzdGxlZnQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0OwotICAgICAgICAgICAgICAgIGludCByZXN0cmlnaHQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodDsKLSAgICAgICAgICAgICAgICBFeHByZXNzaW9uIHJlc3QgPSAoRXhwcmVzc2lvbikoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpIENVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkudmFsdWU7Ci0gICAgICAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBVbmlvblBhdGhFeHByKHBlLCByZXN0KTsKLSAgICAgICAgICAgICAgQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdCA9IG5ldyBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKDE4LypVbmlvbkV4cHIqLywgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0yKSkubGVmdCwgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQsIFJFU1VMVCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgcmV0dXJuIENVUCRYUGF0aFBhcnNlciRyZXN1bHQ7Ci0KLSAgICAgICAgICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0gICAgICAgICAgY2FzZSA2MTogLy8gVW5pb25FeHByIDo6PSBQYXRoRXhwcgotICAgICAgICAgICAgewotICAgICAgICAgICAgICBFeHByZXNzaW9uIFJFU1VMVCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgaW50IHBlbGVmdCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLmxlZnQ7Ci0gICAgICAgICAgICAgICAgaW50IHBlcmlnaHQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodDsKLSAgICAgICAgICAgICAgICBFeHByZXNzaW9uIHBlID0gKEV4cHJlc3Npb24pKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKSBDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnZhbHVlOwotICAgICAgICAgICAgICAgICBSRVNVTFQgPSBwZTsKLSAgICAgICAgICAgICAgQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdCA9IG5ldyBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKDE4LypVbmlvbkV4cHIqLywgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkubGVmdCwgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQsIFJFU1VMVCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgcmV0dXJuIENVUCRYUGF0aFBhcnNlciRyZXN1bHQ7Ci0KLSAgICAgICAgICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0gICAgICAgICAgY2FzZSA2MDogLy8gVW5hcnlFeHByIDo6PSBNSU5VUyBVbmFyeUV4cHIKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgRXhwcmVzc2lvbiBSRVNVTFQgPSBudWxsOwotICAgICAgICAgICAgICAgIGludCB1ZWxlZnQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0OwotICAgICAgICAgICAgICAgIGludCB1ZXJpZ2h0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQ7Ci0gICAgICAgICAgICAgICAgRXhwcmVzc2lvbiB1ZSA9IChFeHByZXNzaW9uKSgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCkgQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS52YWx1ZTsKLSAgICAgICAgICAgICAgICAgUkVTVUxUID0gbmV3IFVuYXJ5T3BFeHByKHVlKTsKLSAgICAgICAgICAgICAgQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdCA9IG5ldyBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKDE0LypVbmFyeUV4cHIqLywgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0xKSkubGVmdCwgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQsIFJFU1VMVCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgcmV0dXJuIENVUCRYUGF0aFBhcnNlciRyZXN1bHQ7Ci0KLSAgICAgICAgICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0gICAgICAgICAgY2FzZSA1OTogLy8gVW5hcnlFeHByIDo6PSBVbmlvbkV4cHIKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgRXhwcmVzc2lvbiBSRVNVTFQgPSBudWxsOwotICAgICAgICAgICAgICAgIGludCB1ZWxlZnQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0OwotICAgICAgICAgICAgICAgIGludCB1ZXJpZ2h0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQ7Ci0gICAgICAgICAgICAgICAgRXhwcmVzc2lvbiB1ZSA9IChFeHByZXNzaW9uKSgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCkgQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS52YWx1ZTsKLSAgICAgICAgICAgICAgICAgUkVTVUxUID0gdWU7Ci0gICAgICAgICAgICAgIENVUCRYUGF0aFBhcnNlciRyZXN1bHQgPSBuZXcgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCgxNC8qVW5hcnlFeHByKi8sICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLmxlZnQsICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0LCBSRVNVTFQpOwotICAgICAgICAgICAgfQotICAgICAgICAgIHJldHVybiBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0OwotCi0gICAgICAgICAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotICAgICAgICAgIGNhc2UgNTg6IC8vIE11bHRpcGxpY2F0aXZlRXhwciA6Oj0gTXVsdGlwbGljYXRpdmVFeHByIE1PRCBVbmFyeUV4cHIKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgRXhwcmVzc2lvbiBSRVNVTFQgPSBudWxsOwotICAgICAgICAgICAgICAgIGludCBtZWxlZnQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTIpKS5sZWZ0OwotICAgICAgICAgICAgICAgIGludCBtZXJpZ2h0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0yKSkucmlnaHQ7Ci0gICAgICAgICAgICAgICAgRXhwcmVzc2lvbiBtZSA9IChFeHByZXNzaW9uKSgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCkgQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTIpKS52YWx1ZTsKLSAgICAgICAgICAgICAgICBpbnQgdWVsZWZ0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkubGVmdDsKLSAgICAgICAgICAgICAgICBpbnQgdWVyaWdodCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0OwotICAgICAgICAgICAgICAgIEV4cHJlc3Npb24gdWUgPSAoRXhwcmVzc2lvbikoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpIENVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkudmFsdWU7Ci0gICAgICAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBCaW5PcEV4cHIoQmluT3BFeHByLk1PRCwgbWUsIHVlKTsKLSAgICAgICAgICAgICAgQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdCA9IG5ldyBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKDEzLypNdWx0aXBsaWNhdGl2ZUV4cHIqLywgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0yKSkubGVmdCwgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQsIFJFU1VMVCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgcmV0dXJuIENVUCRYUGF0aFBhcnNlciRyZXN1bHQ7Ci0KLSAgICAgICAgICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0gICAgICAgICAgY2FzZSA1NzogLy8gTXVsdGlwbGljYXRpdmVFeHByIDo6PSBNdWx0aXBsaWNhdGl2ZUV4cHIgRElWIFVuYXJ5RXhwcgotICAgICAgICAgICAgewotICAgICAgICAgICAgICBFeHByZXNzaW9uIFJFU1VMVCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgaW50IG1lbGVmdCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMikpLmxlZnQ7Ci0gICAgICAgICAgICAgICAgaW50IG1lcmlnaHQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTIpKS5yaWdodDsKLSAgICAgICAgICAgICAgICBFeHByZXNzaW9uIG1lID0gKEV4cHJlc3Npb24pKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKSBDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMikpLnZhbHVlOwotICAgICAgICAgICAgICAgIGludCB1ZWxlZnQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0OwotICAgICAgICAgICAgICAgIGludCB1ZXJpZ2h0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQ7Ci0gICAgICAgICAgICAgICAgRXhwcmVzc2lvbiB1ZSA9IChFeHByZXNzaW9uKSgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCkgQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS52YWx1ZTsKLSAgICAgICAgICAgICAgICAgUkVTVUxUID0gbmV3IEJpbk9wRXhwcihCaW5PcEV4cHIuRElWLCBtZSwgdWUpOwotICAgICAgICAgICAgICBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0ID0gbmV3IGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2woMTMvKk11bHRpcGxpY2F0aXZlRXhwciovLCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTIpKS5sZWZ0LCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodCwgUkVTVUxUKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICByZXR1cm4gQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdDsKLQotICAgICAgICAgIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuKi8KLSAgICAgICAgICBjYXNlIDU2OiAvLyBNdWx0aXBsaWNhdGl2ZUV4cHIgOjo9IE11bHRpcGxpY2F0aXZlRXhwciBTVEFSIFVuYXJ5RXhwcgotICAgICAgICAgICAgewotICAgICAgICAgICAgICBFeHByZXNzaW9uIFJFU1VMVCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgaW50IG1lbGVmdCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMikpLmxlZnQ7Ci0gICAgICAgICAgICAgICAgaW50IG1lcmlnaHQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTIpKS5yaWdodDsKLSAgICAgICAgICAgICAgICBFeHByZXNzaW9uIG1lID0gKEV4cHJlc3Npb24pKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKSBDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMikpLnZhbHVlOwotICAgICAgICAgICAgICAgIGludCB1ZWxlZnQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0OwotICAgICAgICAgICAgICAgIGludCB1ZXJpZ2h0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQ7Ci0gICAgICAgICAgICAgICAgRXhwcmVzc2lvbiB1ZSA9IChFeHByZXNzaW9uKSgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCkgQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS52YWx1ZTsKLSAgICAgICAgICAgICAgICAgUkVTVUxUID0gbmV3IEJpbk9wRXhwcihCaW5PcEV4cHIuVElNRVMsIG1lLCB1ZSk7Ci0gICAgICAgICAgICAgIENVUCRYUGF0aFBhcnNlciRyZXN1bHQgPSBuZXcgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCgxMy8qTXVsdGlwbGljYXRpdmVFeHByKi8sICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMikpLmxlZnQsICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0LCBSRVNVTFQpOwotICAgICAgICAgICAgfQotICAgICAgICAgIHJldHVybiBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0OwotCi0gICAgICAgICAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotICAgICAgICAgIGNhc2UgNTU6IC8vIE11bHRpcGxpY2F0aXZlRXhwciA6Oj0gVW5hcnlFeHByCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIEV4cHJlc3Npb24gUkVTVUxUID0gbnVsbDsKLSAgICAgICAgICAgICAgICBpbnQgdWVsZWZ0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkubGVmdDsKLSAgICAgICAgICAgICAgICBpbnQgdWVyaWdodCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0OwotICAgICAgICAgICAgICAgIEV4cHJlc3Npb24gdWUgPSAoRXhwcmVzc2lvbikoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpIENVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkudmFsdWU7Ci0gICAgICAgICAgICAgICAgIFJFU1VMVCA9IHVlOwotICAgICAgICAgICAgICBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0ID0gbmV3IGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2woMTMvKk11bHRpcGxpY2F0aXZlRXhwciovLCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0LCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodCwgUkVTVUxUKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICByZXR1cm4gQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdDsKLQotICAgICAgICAgIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuKi8KLSAgICAgICAgICBjYXNlIDU0OiAvLyBBZGRpdGl2ZUV4cHIgOjo9IEFkZGl0aXZlRXhwciBNSU5VUyBNdWx0aXBsaWNhdGl2ZUV4cHIKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgRXhwcmVzc2lvbiBSRVNVTFQgPSBudWxsOwotICAgICAgICAgICAgICAgIGludCBhZWxlZnQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTIpKS5sZWZ0OwotICAgICAgICAgICAgICAgIGludCBhZXJpZ2h0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0yKSkucmlnaHQ7Ci0gICAgICAgICAgICAgICAgRXhwcmVzc2lvbiBhZSA9IChFeHByZXNzaW9uKSgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCkgQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTIpKS52YWx1ZTsKLSAgICAgICAgICAgICAgICBpbnQgbWVsZWZ0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkubGVmdDsKLSAgICAgICAgICAgICAgICBpbnQgbWVyaWdodCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0OwotICAgICAgICAgICAgICAgIEV4cHJlc3Npb24gbWUgPSAoRXhwcmVzc2lvbikoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpIENVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkudmFsdWU7Ci0gICAgICAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBCaW5PcEV4cHIoQmluT3BFeHByLk1JTlVTLCBhZSwgbWUpOwotICAgICAgICAgICAgICBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0ID0gbmV3IGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2woMTIvKkFkZGl0aXZlRXhwciovLCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTIpKS5sZWZ0LCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodCwgUkVTVUxUKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICByZXR1cm4gQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdDsKLQotICAgICAgICAgIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuKi8KLSAgICAgICAgICBjYXNlIDUzOiAvLyBBZGRpdGl2ZUV4cHIgOjo9IEFkZGl0aXZlRXhwciBQTFVTIE11bHRpcGxpY2F0aXZlRXhwcgotICAgICAgICAgICAgewotICAgICAgICAgICAgICBFeHByZXNzaW9uIFJFU1VMVCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgaW50IGFlbGVmdCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMikpLmxlZnQ7Ci0gICAgICAgICAgICAgICAgaW50IGFlcmlnaHQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTIpKS5yaWdodDsKLSAgICAgICAgICAgICAgICBFeHByZXNzaW9uIGFlID0gKEV4cHJlc3Npb24pKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKSBDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMikpLnZhbHVlOwotICAgICAgICAgICAgICAgIGludCBtZWxlZnQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0OwotICAgICAgICAgICAgICAgIGludCBtZXJpZ2h0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQ7Ci0gICAgICAgICAgICAgICAgRXhwcmVzc2lvbiBtZSA9IChFeHByZXNzaW9uKSgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCkgQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS52YWx1ZTsKLSAgICAgICAgICAgICAgICAgUkVTVUxUID0gbmV3IEJpbk9wRXhwcihCaW5PcEV4cHIuUExVUywgYWUsIG1lKTsKLSAgICAgICAgICAgICAgQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdCA9IG5ldyBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKDEyLypBZGRpdGl2ZUV4cHIqLywgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0yKSkubGVmdCwgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQsIFJFU1VMVCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgcmV0dXJuIENVUCRYUGF0aFBhcnNlciRyZXN1bHQ7Ci0KLSAgICAgICAgICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0gICAgICAgICAgY2FzZSA1MjogLy8gQWRkaXRpdmVFeHByIDo6PSBNdWx0aXBsaWNhdGl2ZUV4cHIKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgRXhwcmVzc2lvbiBSRVNVTFQgPSBudWxsOwotICAgICAgICAgICAgICAgIGludCBtZWxlZnQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0OwotICAgICAgICAgICAgICAgIGludCBtZXJpZ2h0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQ7Ci0gICAgICAgICAgICAgICAgRXhwcmVzc2lvbiBtZSA9IChFeHByZXNzaW9uKSgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCkgQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS52YWx1ZTsKLSAgICAgICAgICAgICAgICAgUkVTVUxUID0gbWU7Ci0gICAgICAgICAgICAgIENVUCRYUGF0aFBhcnNlciRyZXN1bHQgPSBuZXcgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCgxMi8qQWRkaXRpdmVFeHByKi8sICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLmxlZnQsICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0LCBSRVNVTFQpOwotICAgICAgICAgICAgfQotICAgICAgICAgIHJldHVybiBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0OwotCi0gICAgICAgICAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotICAgICAgICAgIGNhc2UgNTE6IC8vIFJlbGF0aW9uYWxFeHByIDo6PSBSZWxhdGlvbmFsRXhwciBHRSBBZGRpdGl2ZUV4cHIKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgRXhwcmVzc2lvbiBSRVNVTFQgPSBudWxsOwotICAgICAgICAgICAgICAgIGludCByZWxlZnQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTIpKS5sZWZ0OwotICAgICAgICAgICAgICAgIGludCByZXJpZ2h0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0yKSkucmlnaHQ7Ci0gICAgICAgICAgICAgICAgRXhwcmVzc2lvbiByZSA9IChFeHByZXNzaW9uKSgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCkgQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTIpKS52YWx1ZTsKLSAgICAgICAgICAgICAgICBpbnQgYWVsZWZ0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkubGVmdDsKLSAgICAgICAgICAgICAgICBpbnQgYWVyaWdodCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0OwotICAgICAgICAgICAgICAgIEV4cHJlc3Npb24gYWUgPSAoRXhwcmVzc2lvbikoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpIENVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkudmFsdWU7Ci0gICAgICAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBSZWxhdGlvbmFsRXhwcihPcGVyYXRvcnMuR0UsIHJlLCBhZSk7Ci0gICAgICAgICAgICAgIENVUCRYUGF0aFBhcnNlciRyZXN1bHQgPSBuZXcgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCgxMS8qUmVsYXRpb25hbEV4cHIqLywgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0yKSkubGVmdCwgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQsIFJFU1VMVCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgcmV0dXJuIENVUCRYUGF0aFBhcnNlciRyZXN1bHQ7Ci0KLSAgICAgICAgICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0gICAgICAgICAgY2FzZSA1MDogLy8gUmVsYXRpb25hbEV4cHIgOjo9IFJlbGF0aW9uYWxFeHByIExFIEFkZGl0aXZlRXhwcgotICAgICAgICAgICAgewotICAgICAgICAgICAgICBFeHByZXNzaW9uIFJFU1VMVCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgaW50IHJlbGVmdCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMikpLmxlZnQ7Ci0gICAgICAgICAgICAgICAgaW50IHJlcmlnaHQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTIpKS5yaWdodDsKLSAgICAgICAgICAgICAgICBFeHByZXNzaW9uIHJlID0gKEV4cHJlc3Npb24pKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKSBDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMikpLnZhbHVlOwotICAgICAgICAgICAgICAgIGludCBhZWxlZnQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0OwotICAgICAgICAgICAgICAgIGludCBhZXJpZ2h0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQ7Ci0gICAgICAgICAgICAgICAgRXhwcmVzc2lvbiBhZSA9IChFeHByZXNzaW9uKSgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCkgQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS52YWx1ZTsKLSAgICAgICAgICAgICAgICAgUkVTVUxUID0gbmV3IFJlbGF0aW9uYWxFeHByKE9wZXJhdG9ycy5MRSwgcmUsIGFlKTsKLSAgICAgICAgICAgICAgQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdCA9IG5ldyBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKDExLypSZWxhdGlvbmFsRXhwciovLCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTIpKS5sZWZ0LCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodCwgUkVTVUxUKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICByZXR1cm4gQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdDsKLQotICAgICAgICAgIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuKi8KLSAgICAgICAgICBjYXNlIDQ5OiAvLyBSZWxhdGlvbmFsRXhwciA6Oj0gUmVsYXRpb25hbEV4cHIgR1QgQWRkaXRpdmVFeHByCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIEV4cHJlc3Npb24gUkVTVUxUID0gbnVsbDsKLSAgICAgICAgICAgICAgICBpbnQgcmVsZWZ0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0yKSkubGVmdDsKLSAgICAgICAgICAgICAgICBpbnQgcmVyaWdodCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMikpLnJpZ2h0OwotICAgICAgICAgICAgICAgIEV4cHJlc3Npb24gcmUgPSAoRXhwcmVzc2lvbikoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpIENVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0yKSkudmFsdWU7Ci0gICAgICAgICAgICAgICAgaW50IGFlbGVmdCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLmxlZnQ7Ci0gICAgICAgICAgICAgICAgaW50IGFlcmlnaHQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodDsKLSAgICAgICAgICAgICAgICBFeHByZXNzaW9uIGFlID0gKEV4cHJlc3Npb24pKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKSBDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnZhbHVlOwotICAgICAgICAgICAgICAgICBSRVNVTFQgPSBuZXcgUmVsYXRpb25hbEV4cHIoT3BlcmF0b3JzLkdULCByZSwgYWUpOwotICAgICAgICAgICAgICBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0ID0gbmV3IGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2woMTEvKlJlbGF0aW9uYWxFeHByKi8sICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMikpLmxlZnQsICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0LCBSRVNVTFQpOwotICAgICAgICAgICAgfQotICAgICAgICAgIHJldHVybiBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0OwotCi0gICAgICAgICAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotICAgICAgICAgIGNhc2UgNDg6IC8vIFJlbGF0aW9uYWxFeHByIDo6PSBSZWxhdGlvbmFsRXhwciBMVCBBZGRpdGl2ZUV4cHIKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgRXhwcmVzc2lvbiBSRVNVTFQgPSBudWxsOwotICAgICAgICAgICAgICAgIGludCByZWxlZnQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTIpKS5sZWZ0OwotICAgICAgICAgICAgICAgIGludCByZXJpZ2h0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0yKSkucmlnaHQ7Ci0gICAgICAgICAgICAgICAgRXhwcmVzc2lvbiByZSA9IChFeHByZXNzaW9uKSgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCkgQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTIpKS52YWx1ZTsKLSAgICAgICAgICAgICAgICBpbnQgYWVsZWZ0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkubGVmdDsKLSAgICAgICAgICAgICAgICBpbnQgYWVyaWdodCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0OwotICAgICAgICAgICAgICAgIEV4cHJlc3Npb24gYWUgPSAoRXhwcmVzc2lvbikoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpIENVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkudmFsdWU7Ci0gICAgICAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBSZWxhdGlvbmFsRXhwcihPcGVyYXRvcnMuTFQsIHJlLCBhZSk7Ci0gICAgICAgICAgICAgIENVUCRYUGF0aFBhcnNlciRyZXN1bHQgPSBuZXcgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCgxMS8qUmVsYXRpb25hbEV4cHIqLywgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0yKSkubGVmdCwgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQsIFJFU1VMVCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgcmV0dXJuIENVUCRYUGF0aFBhcnNlciRyZXN1bHQ7Ci0KLSAgICAgICAgICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0gICAgICAgICAgY2FzZSA0NzogLy8gUmVsYXRpb25hbEV4cHIgOjo9IEFkZGl0aXZlRXhwcgotICAgICAgICAgICAgewotICAgICAgICAgICAgICBFeHByZXNzaW9uIFJFU1VMVCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgaW50IGFlbGVmdCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLmxlZnQ7Ci0gICAgICAgICAgICAgICAgaW50IGFlcmlnaHQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodDsKLSAgICAgICAgICAgICAgICBFeHByZXNzaW9uIGFlID0gKEV4cHJlc3Npb24pKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKSBDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnZhbHVlOwotICAgICAgICAgICAgICAgICBSRVNVTFQgPSBhZTsKLSAgICAgICAgICAgICAgQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdCA9IG5ldyBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKDExLypSZWxhdGlvbmFsRXhwciovLCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0LCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodCwgUkVTVUxUKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICByZXR1cm4gQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdDsKLQotICAgICAgICAgIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuKi8KLSAgICAgICAgICBjYXNlIDQ2OiAvLyBFcXVhbGl0eUV4cHIgOjo9IEVxdWFsaXR5RXhwciBORSBSZWxhdGlvbmFsRXhwcgotICAgICAgICAgICAgewotICAgICAgICAgICAgICBFeHByZXNzaW9uIFJFU1VMVCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgaW50IGVlbGVmdCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMikpLmxlZnQ7Ci0gICAgICAgICAgICAgICAgaW50IGVlcmlnaHQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTIpKS5yaWdodDsKLSAgICAgICAgICAgICAgICBFeHByZXNzaW9uIGVlID0gKEV4cHJlc3Npb24pKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKSBDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMikpLnZhbHVlOwotICAgICAgICAgICAgICAgIGludCByZWxlZnQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0OwotICAgICAgICAgICAgICAgIGludCByZXJpZ2h0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQ7Ci0gICAgICAgICAgICAgICAgRXhwcmVzc2lvbiByZSA9IChFeHByZXNzaW9uKSgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCkgQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS52YWx1ZTsKLSAgICAgICAgICAgICAgICAgUkVTVUxUID0gbmV3IEVxdWFsaXR5RXhwcihPcGVyYXRvcnMuTkUsIGVlLCByZSk7Ci0gICAgICAgICAgICAgIENVUCRYUGF0aFBhcnNlciRyZXN1bHQgPSBuZXcgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCgxMC8qRXF1YWxpdHlFeHByKi8sICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMikpLmxlZnQsICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0LCBSRVNVTFQpOwotICAgICAgICAgICAgfQotICAgICAgICAgIHJldHVybiBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0OwotCi0gICAgICAgICAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotICAgICAgICAgIGNhc2UgNDU6IC8vIEVxdWFsaXR5RXhwciA6Oj0gRXF1YWxpdHlFeHByIEVRIFJlbGF0aW9uYWxFeHByCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIEV4cHJlc3Npb24gUkVTVUxUID0gbnVsbDsKLSAgICAgICAgICAgICAgICBpbnQgZWVsZWZ0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0yKSkubGVmdDsKLSAgICAgICAgICAgICAgICBpbnQgZWVyaWdodCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMikpLnJpZ2h0OwotICAgICAgICAgICAgICAgIEV4cHJlc3Npb24gZWUgPSAoRXhwcmVzc2lvbikoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpIENVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0yKSkudmFsdWU7Ci0gICAgICAgICAgICAgICAgaW50IHJlbGVmdCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLmxlZnQ7Ci0gICAgICAgICAgICAgICAgaW50IHJlcmlnaHQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodDsKLSAgICAgICAgICAgICAgICBFeHByZXNzaW9uIHJlID0gKEV4cHJlc3Npb24pKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKSBDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnZhbHVlOwotICAgICAgICAgICAgICAgICBSRVNVTFQgPSBuZXcgRXF1YWxpdHlFeHByKE9wZXJhdG9ycy5FUSwgZWUsIHJlKTsKLSAgICAgICAgICAgICAgQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdCA9IG5ldyBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKDEwLypFcXVhbGl0eUV4cHIqLywgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0yKSkubGVmdCwgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQsIFJFU1VMVCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgcmV0dXJuIENVUCRYUGF0aFBhcnNlciRyZXN1bHQ7Ci0KLSAgICAgICAgICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0gICAgICAgICAgY2FzZSA0NDogLy8gRXF1YWxpdHlFeHByIDo6PSBSZWxhdGlvbmFsRXhwcgotICAgICAgICAgICAgewotICAgICAgICAgICAgICBFeHByZXNzaW9uIFJFU1VMVCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgaW50IHJlbGVmdCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLmxlZnQ7Ci0gICAgICAgICAgICAgICAgaW50IHJlcmlnaHQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodDsKLSAgICAgICAgICAgICAgICBFeHByZXNzaW9uIHJlID0gKEV4cHJlc3Npb24pKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKSBDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnZhbHVlOwotICAgICAgICAgICAgICAgICBSRVNVTFQgPSByZTsKLSAgICAgICAgICAgICAgQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdCA9IG5ldyBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKDEwLypFcXVhbGl0eUV4cHIqLywgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkubGVmdCwgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQsIFJFU1VMVCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgcmV0dXJuIENVUCRYUGF0aFBhcnNlciRyZXN1bHQ7Ci0KLSAgICAgICAgICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0gICAgICAgICAgY2FzZSA0MzogLy8gQW5kRXhwciA6Oj0gQW5kRXhwciBBTkQgRXF1YWxpdHlFeHByCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIEV4cHJlc3Npb24gUkVTVUxUID0gbnVsbDsKLSAgICAgICAgICAgICAgICBpbnQgYWVsZWZ0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0yKSkubGVmdDsKLSAgICAgICAgICAgICAgICBpbnQgYWVyaWdodCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMikpLnJpZ2h0OwotICAgICAgICAgICAgICAgIEV4cHJlc3Npb24gYWUgPSAoRXhwcmVzc2lvbikoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpIENVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0yKSkudmFsdWU7Ci0gICAgICAgICAgICAgICAgaW50IGVlbGVmdCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLmxlZnQ7Ci0gICAgICAgICAgICAgICAgaW50IGVlcmlnaHQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodDsKLSAgICAgICAgICAgICAgICBFeHByZXNzaW9uIGVlID0gKEV4cHJlc3Npb24pKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKSBDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnZhbHVlOwotICAgICAgICAgICAgICAgICBSRVNVTFQgPSBuZXcgTG9naWNhbEV4cHIoTG9naWNhbEV4cHIuQU5ELCBhZSwgZWUpOwotICAgICAgICAgICAgICBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0ID0gbmV3IGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2woOS8qQW5kRXhwciovLCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTIpKS5sZWZ0LCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodCwgUkVTVUxUKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICByZXR1cm4gQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdDsKLQotICAgICAgICAgIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuKi8KLSAgICAgICAgICBjYXNlIDQyOiAvLyBBbmRFeHByIDo6PSBFcXVhbGl0eUV4cHIKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgRXhwcmVzc2lvbiBSRVNVTFQgPSBudWxsOwotICAgICAgICAgICAgICAgIGludCBlbGVmdCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLmxlZnQ7Ci0gICAgICAgICAgICAgICAgaW50IGVyaWdodCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0OwotICAgICAgICAgICAgICAgIEV4cHJlc3Npb24gZSA9IChFeHByZXNzaW9uKSgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCkgQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS52YWx1ZTsKLSAgICAgICAgICAgICAgICAgUkVTVUxUID0gZTsKLSAgICAgICAgICAgICAgQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdCA9IG5ldyBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKDkvKkFuZEV4cHIqLywgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkubGVmdCwgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQsIFJFU1VMVCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgcmV0dXJuIENVUCRYUGF0aFBhcnNlciRyZXN1bHQ7Ci0KLSAgICAgICAgICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0gICAgICAgICAgY2FzZSA0MTogLy8gT3JFeHByIDo6PSBPckV4cHIgT1IgQW5kRXhwcgotICAgICAgICAgICAgewotICAgICAgICAgICAgICBFeHByZXNzaW9uIFJFU1VMVCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgaW50IG9lbGVmdCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMikpLmxlZnQ7Ci0gICAgICAgICAgICAgICAgaW50IG9lcmlnaHQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTIpKS5yaWdodDsKLSAgICAgICAgICAgICAgICBFeHByZXNzaW9uIG9lID0gKEV4cHJlc3Npb24pKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKSBDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMikpLnZhbHVlOwotICAgICAgICAgICAgICAgIGludCBhZWxlZnQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0OwotICAgICAgICAgICAgICAgIGludCBhZXJpZ2h0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQ7Ci0gICAgICAgICAgICAgICAgRXhwcmVzc2lvbiBhZSA9IChFeHByZXNzaW9uKSgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCkgQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS52YWx1ZTsKLSAgICAgICAgICAgICAgICAgUkVTVUxUID0gbmV3IExvZ2ljYWxFeHByKExvZ2ljYWxFeHByLk9SLCBvZSwgYWUpOwotICAgICAgICAgICAgICBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0ID0gbmV3IGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2woOC8qT3JFeHByKi8sICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMikpLmxlZnQsICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0LCBSRVNVTFQpOwotICAgICAgICAgICAgfQotICAgICAgICAgIHJldHVybiBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0OwotCi0gICAgICAgICAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotICAgICAgICAgIGNhc2UgNDA6IC8vIE9yRXhwciA6Oj0gQW5kRXhwcgotICAgICAgICAgICAgewotICAgICAgICAgICAgICBFeHByZXNzaW9uIFJFU1VMVCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgaW50IGFlbGVmdCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLmxlZnQ7Ci0gICAgICAgICAgICAgICAgaW50IGFlcmlnaHQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodDsKLSAgICAgICAgICAgICAgICBFeHByZXNzaW9uIGFlID0gKEV4cHJlc3Npb24pKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKSBDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnZhbHVlOwotICAgICAgICAgICAgICAgICBSRVNVTFQgPSBhZTsKLSAgICAgICAgICAgICAgQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdCA9IG5ldyBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKDgvKk9yRXhwciovLCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0LCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodCwgUkVTVUxUKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICByZXR1cm4gQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdDsKLQotICAgICAgICAgIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuKi8KLSAgICAgICAgICBjYXNlIDM5OiAvLyBFeHByIDo6PSBPckV4cHIKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgRXhwcmVzc2lvbiBSRVNVTFQgPSBudWxsOwotICAgICAgICAgICAgICAgIGludCBleGxlZnQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0OwotICAgICAgICAgICAgICAgIGludCBleHJpZ2h0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQ7Ci0gICAgICAgICAgICAgICAgRXhwcmVzc2lvbiBleCA9IChFeHByZXNzaW9uKSgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCkgQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS52YWx1ZTsKLSAgICAgICAgICAgICAgICAgUkVTVUxUID0gZXg7Ci0gICAgICAgICAgICAgIENVUCRYUGF0aFBhcnNlciRyZXN1bHQgPSBuZXcgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCgyLypFeHByKi8sICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLmxlZnQsICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0LCBSRVNVTFQpOwotICAgICAgICAgICAgfQotICAgICAgICAgIHJldHVybiBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0OwotCi0gICAgICAgICAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotICAgICAgICAgIGNhc2UgMzg6IC8vIFByZWRpY2F0ZSA6Oj0gTEJSQUNLIEV4cHIgUkJSQUNLCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIEV4cHJlc3Npb24gUkVTVUxUID0gbnVsbDsKLSAgICAgICAgICAgICAgICBpbnQgZWxlZnQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTEpKS5sZWZ0OwotICAgICAgICAgICAgICAgIGludCBlcmlnaHQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTEpKS5yaWdodDsKLSAgICAgICAgICAgICAgICBFeHByZXNzaW9uIGUgPSAoRXhwcmVzc2lvbikoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpIENVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0xKSkudmFsdWU7Ci0KLSAgICAgICAgICAgICAgICBSRVNVTFQgPSBuZXcgUHJlZGljYXRlKGUpOwotCi0gICAgICAgICAgICAgIENVUCRYUGF0aFBhcnNlciRyZXN1bHQgPSBuZXcgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCg1LypQcmVkaWNhdGUqLywgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0yKSkubGVmdCwgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQsIFJFU1VMVCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgcmV0dXJuIENVUCRYUGF0aFBhcnNlciRyZXN1bHQ7Ci0KLSAgICAgICAgICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0gICAgICAgICAgY2FzZSAzNzogLy8gUHJlZGljYXRlcyA6Oj0gUHJlZGljYXRlIFByZWRpY2F0ZXMKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgVmVjdG9yIFJFU1VMVCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgaW50IHBsZWZ0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0xKSkubGVmdDsKLSAgICAgICAgICAgICAgICBpbnQgcHJpZ2h0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0xKSkucmlnaHQ7Ci0gICAgICAgICAgICAgICAgRXhwcmVzc2lvbiBwID0gKEV4cHJlc3Npb24pKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKSBDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMSkpLnZhbHVlOwotICAgICAgICAgICAgICAgIGludCBwcGxlZnQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0OwotICAgICAgICAgICAgICAgIGludCBwcHJpZ2h0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQ7Ci0gICAgICAgICAgICAgICAgVmVjdG9yIHBwID0gKFZlY3RvcikoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpIENVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkudmFsdWU7Ci0gICAgICAgICAgICAgICAgIHBwLmluc2VydEVsZW1lbnRBdChwLCAwKTsgUkVTVUxUID0gcHA7Ci0gICAgICAgICAgICAgIENVUCRYUGF0aFBhcnNlciRyZXN1bHQgPSBuZXcgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCgzNS8qUHJlZGljYXRlcyovLCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTEpKS5sZWZ0LCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodCwgUkVTVUxUKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICByZXR1cm4gQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdDsKLQotICAgICAgICAgIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuKi8KLSAgICAgICAgICBjYXNlIDM2OiAvLyBQcmVkaWNhdGVzIDo6PSBQcmVkaWNhdGUKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgVmVjdG9yIFJFU1VMVCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgaW50IHBsZWZ0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkubGVmdDsKLSAgICAgICAgICAgICAgICBpbnQgcHJpZ2h0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQ7Ci0gICAgICAgICAgICAgICAgRXhwcmVzc2lvbiBwID0gKEV4cHJlc3Npb24pKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKSBDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnZhbHVlOwotCi0gICAgICAgICAgICAgICAgVmVjdG9yIHRlbXAgPSBuZXcgVmVjdG9yKCk7Ci0gICAgICAgICAgICAgICAgdGVtcC5hZGRFbGVtZW50KHApOwotICAgICAgICAgICAgICAgIFJFU1VMVCA9IHRlbXA7Ci0KLSAgICAgICAgICAgICAgQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdCA9IG5ldyBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKDM1LypQcmVkaWNhdGVzKi8sICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLmxlZnQsICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0LCBSRVNVTFQpOwotICAgICAgICAgICAgfQotICAgICAgICAgIHJldHVybiBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0OwotCi0gICAgICAgICAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotICAgICAgICAgIGNhc2UgMzU6IC8vIENoaWxkT3JBdHRyaWJ1dGVBeGlzU3BlY2lmaWVyIDo6PSBBVFRSSUJVVEUgRENPTE9OCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIEludGVnZXIgUkVTVUxUID0gbnVsbDsKLSAgICAgICAgICAgICAgICAgUkVTVUxUID0gbmV3IEludGVnZXIoQXhpcy5BVFRSSUJVVEUpOwotICAgICAgICAgICAgICBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0ID0gbmV3IGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2woNDIvKkNoaWxkT3JBdHRyaWJ1dGVBeGlzU3BlY2lmaWVyKi8sICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMSkpLmxlZnQsICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0LCBSRVNVTFQpOwotICAgICAgICAgICAgfQotICAgICAgICAgIHJldHVybiBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0OwotCi0gICAgICAgICAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotICAgICAgICAgIGNhc2UgMzQ6IC8vIENoaWxkT3JBdHRyaWJ1dGVBeGlzU3BlY2lmaWVyIDo6PSBDSElMRCBEQ09MT04KLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgSW50ZWdlciBSRVNVTFQgPSBudWxsOwotICAgICAgICAgICAgICAgICBSRVNVTFQgPSBuZXcgSW50ZWdlcihBeGlzLkNISUxEKTsKLSAgICAgICAgICAgICAgQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdCA9IG5ldyBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKDQyLypDaGlsZE9yQXR0cmlidXRlQXhpc1NwZWNpZmllciovLCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTEpKS5sZWZ0LCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodCwgUkVTVUxUKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICByZXR1cm4gQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdDsKLQotICAgICAgICAgIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuKi8KLSAgICAgICAgICBjYXNlIDMzOiAvLyBDaGlsZE9yQXR0cmlidXRlQXhpc1NwZWNpZmllciA6Oj0gQVRTSUdOCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIEludGVnZXIgUkVTVUxUID0gbnVsbDsKLSAgICAgICAgICAgICAgICAgUkVTVUxUID0gbmV3IEludGVnZXIoQXhpcy5BVFRSSUJVVEUpOwotICAgICAgICAgICAgICBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0ID0gbmV3IGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2woNDIvKkNoaWxkT3JBdHRyaWJ1dGVBeGlzU3BlY2lmaWVyKi8sICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLmxlZnQsICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0LCBSRVNVTFQpOwotICAgICAgICAgICAgfQotICAgICAgICAgIHJldHVybiBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0OwotCi0gICAgICAgICAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotICAgICAgICAgIGNhc2UgMzI6IC8vIE5hbWVUZXN0UGF0dGVybiA6Oj0gUU5hbWUKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgT2JqZWN0IFJFU1VMVCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgaW50IHFubGVmdCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLmxlZnQ7Ci0gICAgICAgICAgICAgICAgaW50IHFucmlnaHQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodDsKLSAgICAgICAgICAgICAgICBRTmFtZSBxbiA9IChRTmFtZSkoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpIENVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkudmFsdWU7Ci0gICAgICAgICAgICAgICAgIFJFU1VMVCA9IHFuOwotICAgICAgICAgICAgICBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0ID0gbmV3IGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2woMzQvKk5hbWVUZXN0UGF0dGVybiovLCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0LCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodCwgUkVTVUxUKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICByZXR1cm4gQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdDsKLQotICAgICAgICAgIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuKi8KLSAgICAgICAgICBjYXNlIDMxOiAvLyBOYW1lVGVzdFBhdHRlcm4gOjo9IFNUQVIKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgT2JqZWN0IFJFU1VMVCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgIFJFU1VMVCA9IG51bGw7Ci0gICAgICAgICAgICAgIENVUCRYUGF0aFBhcnNlciRyZXN1bHQgPSBuZXcgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCgzNC8qTmFtZVRlc3RQYXR0ZXJuKi8sICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLmxlZnQsICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0LCBSRVNVTFQpOwotICAgICAgICAgICAgfQotICAgICAgICAgIHJldHVybiBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0OwotCi0gICAgICAgICAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotICAgICAgICAgIGNhc2UgMzA6IC8vIE5vZGVUZXN0UGF0dGVybiA6Oj0gUEkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgT2JqZWN0IFJFU1VMVCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBJbnRlZ2VyKE5vZGVUZXN0LlBJKTsKLSAgICAgICAgICAgICAgQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdCA9IG5ldyBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKDMzLypOb2RlVGVzdFBhdHRlcm4qLywgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkubGVmdCwgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQsIFJFU1VMVCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgcmV0dXJuIENVUCRYUGF0aFBhcnNlciRyZXN1bHQ7Ci0KLSAgICAgICAgICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0gICAgICAgICAgY2FzZSAyOTogLy8gTm9kZVRlc3RQYXR0ZXJuIDo6PSBDT01NRU5UCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIE9iamVjdCBSRVNVTFQgPSBudWxsOwotICAgICAgICAgICAgICAgICBSRVNVTFQgPSBuZXcgSW50ZWdlcihOb2RlVGVzdC5DT01NRU5UKTsKLSAgICAgICAgICAgICAgQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdCA9IG5ldyBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKDMzLypOb2RlVGVzdFBhdHRlcm4qLywgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkubGVmdCwgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQsIFJFU1VMVCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgcmV0dXJuIENVUCRYUGF0aFBhcnNlciRyZXN1bHQ7Ci0KLSAgICAgICAgICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0gICAgICAgICAgY2FzZSAyODogLy8gTm9kZVRlc3RQYXR0ZXJuIDo6PSBURVhUCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIE9iamVjdCBSRVNVTFQgPSBudWxsOwotICAgICAgICAgICAgICAgICBSRVNVTFQgPSBuZXcgSW50ZWdlcihOb2RlVGVzdC5URVhUKTsKLSAgICAgICAgICAgICAgQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdCA9IG5ldyBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKDMzLypOb2RlVGVzdFBhdHRlcm4qLywgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkubGVmdCwgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQsIFJFU1VMVCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgcmV0dXJuIENVUCRYUGF0aFBhcnNlciRyZXN1bHQ7Ci0KLSAgICAgICAgICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0gICAgICAgICAgY2FzZSAyNzogLy8gTm9kZVRlc3RQYXR0ZXJuIDo6PSBOT0RFCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIE9iamVjdCBSRVNVTFQgPSBudWxsOwotICAgICAgICAgICAgICAgICBSRVNVTFQgPSBuZXcgSW50ZWdlcihOb2RlVGVzdC5BTk9ERSk7Ci0gICAgICAgICAgICAgIENVUCRYUGF0aFBhcnNlciRyZXN1bHQgPSBuZXcgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCgzMy8qTm9kZVRlc3RQYXR0ZXJuKi8sICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLmxlZnQsICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0LCBSRVNVTFQpOwotICAgICAgICAgICAgfQotICAgICAgICAgIHJldHVybiBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0OwotCi0gICAgICAgICAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotICAgICAgICAgIGNhc2UgMjY6IC8vIE5vZGVUZXN0UGF0dGVybiA6Oj0gTmFtZVRlc3RQYXR0ZXJuCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIE9iamVjdCBSRVNVTFQgPSBudWxsOwotICAgICAgICAgICAgICAgIGludCBudGxlZnQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0OwotICAgICAgICAgICAgICAgIGludCBudHJpZ2h0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQ7Ci0gICAgICAgICAgICAgICAgT2JqZWN0IG50ID0gKE9iamVjdCkoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpIENVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkudmFsdWU7Ci0gICAgICAgICAgICAgICAgIFJFU1VMVCA9IG50OwotICAgICAgICAgICAgICBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0ID0gbmV3IGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2woMzMvKk5vZGVUZXN0UGF0dGVybiovLCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0LCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodCwgUkVTVUxUKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICByZXR1cm4gQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdDsKLQotICAgICAgICAgIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuKi8KLSAgICAgICAgICBjYXNlIDI1OiAvLyBTdGVwUGF0dGVybiA6Oj0gQ2hpbGRPckF0dHJpYnV0ZUF4aXNTcGVjaWZpZXIgUHJvY2Vzc2luZ0luc3RydWN0aW9uUGF0dGVybiBQcmVkaWNhdGVzCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIFN0ZXBQYXR0ZXJuIFJFU1VMVCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgaW50IGF4aXNsZWZ0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0yKSkubGVmdDsKLSAgICAgICAgICAgICAgICBpbnQgYXhpc3JpZ2h0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0yKSkucmlnaHQ7Ci0gICAgICAgICAgICAgICAgSW50ZWdlciBheGlzID0gKEludGVnZXIpKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKSBDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMikpLnZhbHVlOwotICAgICAgICAgICAgICAgIGludCBwaXBsZWZ0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0xKSkubGVmdDsKLSAgICAgICAgICAgICAgICBpbnQgcGlwcmlnaHQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTEpKS5yaWdodDsKLSAgICAgICAgICAgICAgICBTdGVwUGF0dGVybiBwaXAgPSAoU3RlcFBhdHRlcm4pKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKSBDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMSkpLnZhbHVlOwotICAgICAgICAgICAgICAgIGludCBwcGxlZnQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0OwotICAgICAgICAgICAgICAgIGludCBwcHJpZ2h0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQ7Ci0gICAgICAgICAgICAgICAgVmVjdG9yIHBwID0gKFZlY3RvcikoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpIENVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkudmFsdWU7Ci0KLSAgICAgICAgICAgICAgIC8vIFRPRE86IHJlcG9ydCBlcnJvciBpZiBheGlzIGlzIGF0dHJpYnV0ZQotICAgICAgICAgICAgICAgUkVTVUxUID0gKFByb2Nlc3NpbmdJbnN0cnVjdGlvblBhdHRlcm4pcGlwLnNldFByZWRpY2F0ZXMocHApOwotCi0gICAgICAgICAgICAgIENVUCRYUGF0aFBhcnNlciRyZXN1bHQgPSBuZXcgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCgzMi8qU3RlcFBhdHRlcm4qLywgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0yKSkubGVmdCwgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQsIFJFU1VMVCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgcmV0dXJuIENVUCRYUGF0aFBhcnNlciRyZXN1bHQ7Ci0KLSAgICAgICAgICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0gICAgICAgICAgY2FzZSAyNDogLy8gU3RlcFBhdHRlcm4gOjo9IENoaWxkT3JBdHRyaWJ1dGVBeGlzU3BlY2lmaWVyIFByb2Nlc3NpbmdJbnN0cnVjdGlvblBhdHRlcm4KLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgU3RlcFBhdHRlcm4gUkVTVUxUID0gbnVsbDsKLSAgICAgICAgICAgICAgICBpbnQgYXhpc2xlZnQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTEpKS5sZWZ0OwotICAgICAgICAgICAgICAgIGludCBheGlzcmlnaHQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTEpKS5yaWdodDsKLSAgICAgICAgICAgICAgICBJbnRlZ2VyIGF4aXMgPSAoSW50ZWdlcikoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpIENVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0xKSkudmFsdWU7Ci0gICAgICAgICAgICAgICAgaW50IHBpcGxlZnQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0OwotICAgICAgICAgICAgICAgIGludCBwaXByaWdodCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0OwotICAgICAgICAgICAgICAgIFN0ZXBQYXR0ZXJuIHBpcCA9IChTdGVwUGF0dGVybikoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpIENVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkudmFsdWU7Ci0KLSAgICAgICAgICAgICAgIFJFU1VMVCA9IHBpcDsgICAgLy8gVE9ETzogcmVwb3J0IGVycm9yIGlmIGF4aXMgaXMgYXR0cmlidXRlCi0KLSAgICAgICAgICAgICAgQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdCA9IG5ldyBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKDMyLypTdGVwUGF0dGVybiovLCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTEpKS5sZWZ0LCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodCwgUkVTVUxUKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICByZXR1cm4gQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdDsKLQotICAgICAgICAgIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuKi8KLSAgICAgICAgICBjYXNlIDIzOiAvLyBTdGVwUGF0dGVybiA6Oj0gQ2hpbGRPckF0dHJpYnV0ZUF4aXNTcGVjaWZpZXIgTm9kZVRlc3RQYXR0ZXJuIFByZWRpY2F0ZXMKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgU3RlcFBhdHRlcm4gUkVTVUxUID0gbnVsbDsKLSAgICAgICAgICAgICAgICBpbnQgYXhpc2xlZnQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTIpKS5sZWZ0OwotICAgICAgICAgICAgICAgIGludCBheGlzcmlnaHQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTIpKS5yaWdodDsKLSAgICAgICAgICAgICAgICBJbnRlZ2VyIGF4aXMgPSAoSW50ZWdlcikoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpIENVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0yKSkudmFsdWU7Ci0gICAgICAgICAgICAgICAgaW50IG50bGVmdCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMSkpLmxlZnQ7Ci0gICAgICAgICAgICAgICAgaW50IG50cmlnaHQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTEpKS5yaWdodDsKLSAgICAgICAgICAgICAgICBPYmplY3QgbnQgPSAoT2JqZWN0KSgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCkgQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTEpKS52YWx1ZTsKLSAgICAgICAgICAgICAgICBpbnQgcHBsZWZ0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkubGVmdDsKLSAgICAgICAgICAgICAgICBpbnQgcHByaWdodCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0OwotICAgICAgICAgICAgICAgIFZlY3RvciBwcCA9IChWZWN0b3IpKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKSBDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnZhbHVlOwotCi0gICAgICAgICAgICAgICBSRVNVTFQgPSBwYXJzZXIuY3JlYXRlU3RlcFBhdHRlcm4oYXhpcy5pbnRWYWx1ZSgpLCBudCwgcHApOwotCi0gICAgICAgICAgICAgIENVUCRYUGF0aFBhcnNlciRyZXN1bHQgPSBuZXcgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCgzMi8qU3RlcFBhdHRlcm4qLywgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0yKSkubGVmdCwgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQsIFJFU1VMVCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgcmV0dXJuIENVUCRYUGF0aFBhcnNlciRyZXN1bHQ7Ci0KLSAgICAgICAgICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0gICAgICAgICAgY2FzZSAyMjogLy8gU3RlcFBhdHRlcm4gOjo9IENoaWxkT3JBdHRyaWJ1dGVBeGlzU3BlY2lmaWVyIE5vZGVUZXN0UGF0dGVybgotICAgICAgICAgICAgewotICAgICAgICAgICAgICBTdGVwUGF0dGVybiBSRVNVTFQgPSBudWxsOwotICAgICAgICAgICAgICAgIGludCBheGlzbGVmdCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMSkpLmxlZnQ7Ci0gICAgICAgICAgICAgICAgaW50IGF4aXNyaWdodCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMSkpLnJpZ2h0OwotICAgICAgICAgICAgICAgIEludGVnZXIgYXhpcyA9IChJbnRlZ2VyKSgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCkgQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTEpKS52YWx1ZTsKLSAgICAgICAgICAgICAgICBpbnQgbnRsZWZ0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkubGVmdDsKLSAgICAgICAgICAgICAgICBpbnQgbnRyaWdodCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0OwotICAgICAgICAgICAgICAgIE9iamVjdCBudCA9IChPYmplY3QpKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKSBDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnZhbHVlOwotCi0gICAgICAgICAgICAgICBSRVNVTFQgPSBwYXJzZXIuY3JlYXRlU3RlcFBhdHRlcm4oYXhpcy5pbnRWYWx1ZSgpLCBudCwgbnVsbCk7Ci0KLSAgICAgICAgICAgICAgQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdCA9IG5ldyBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKDMyLypTdGVwUGF0dGVybiovLCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTEpKS5sZWZ0LCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodCwgUkVTVUxUKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICByZXR1cm4gQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdDsKLQotICAgICAgICAgIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuKi8KLSAgICAgICAgICBjYXNlIDIxOiAvLyBTdGVwUGF0dGVybiA6Oj0gUHJvY2Vzc2luZ0luc3RydWN0aW9uUGF0dGVybiBQcmVkaWNhdGVzCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIFN0ZXBQYXR0ZXJuIFJFU1VMVCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgaW50IHBpcGxlZnQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTEpKS5sZWZ0OwotICAgICAgICAgICAgICAgIGludCBwaXByaWdodCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMSkpLnJpZ2h0OwotICAgICAgICAgICAgICAgIFN0ZXBQYXR0ZXJuIHBpcCA9IChTdGVwUGF0dGVybikoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpIENVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0xKSkudmFsdWU7Ci0gICAgICAgICAgICAgICAgaW50IHBwbGVmdCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLmxlZnQ7Ci0gICAgICAgICAgICAgICAgaW50IHBwcmlnaHQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodDsKLSAgICAgICAgICAgICAgICBWZWN0b3IgcHAgPSAoVmVjdG9yKSgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCkgQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS52YWx1ZTsKLSAgICAgICAgICAgICAgICAgUkVTVUxUID0gKFByb2Nlc3NpbmdJbnN0cnVjdGlvblBhdHRlcm4pcGlwLnNldFByZWRpY2F0ZXMocHApOwotICAgICAgICAgICAgICBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0ID0gbmV3IGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2woMzIvKlN0ZXBQYXR0ZXJuKi8sICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMSkpLmxlZnQsICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0LCBSRVNVTFQpOwotICAgICAgICAgICAgfQotICAgICAgICAgIHJldHVybiBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0OwotCi0gICAgICAgICAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotICAgICAgICAgIGNhc2UgMjA6IC8vIFN0ZXBQYXR0ZXJuIDo6PSBQcm9jZXNzaW5nSW5zdHJ1Y3Rpb25QYXR0ZXJuCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIFN0ZXBQYXR0ZXJuIFJFU1VMVCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgaW50IHBpcGxlZnQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0OwotICAgICAgICAgICAgICAgIGludCBwaXByaWdodCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0OwotICAgICAgICAgICAgICAgIFN0ZXBQYXR0ZXJuIHBpcCA9IChTdGVwUGF0dGVybikoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpIENVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkudmFsdWU7Ci0gICAgICAgICAgICAgICAgIFJFU1VMVCA9IHBpcDsKLSAgICAgICAgICAgICAgQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdCA9IG5ldyBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKDMyLypTdGVwUGF0dGVybiovLCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0LCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodCwgUkVTVUxUKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICByZXR1cm4gQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdDsKLQotICAgICAgICAgIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuKi8KLSAgICAgICAgICBjYXNlIDE5OiAvLyBTdGVwUGF0dGVybiA6Oj0gTm9kZVRlc3RQYXR0ZXJuIFByZWRpY2F0ZXMKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgU3RlcFBhdHRlcm4gUkVTVUxUID0gbnVsbDsKLSAgICAgICAgICAgICAgICBpbnQgbnRsZWZ0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0xKSkubGVmdDsKLSAgICAgICAgICAgICAgICBpbnQgbnRyaWdodCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMSkpLnJpZ2h0OwotICAgICAgICAgICAgICAgIE9iamVjdCBudCA9IChPYmplY3QpKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKSBDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMSkpLnZhbHVlOwotICAgICAgICAgICAgICAgIGludCBwcGxlZnQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0OwotICAgICAgICAgICAgICAgIGludCBwcHJpZ2h0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQ7Ci0gICAgICAgICAgICAgICAgVmVjdG9yIHBwID0gKFZlY3RvcikoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpIENVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkudmFsdWU7Ci0KLSAgICAgICAgICAgICAgICBSRVNVTFQgPSBwYXJzZXIuY3JlYXRlU3RlcFBhdHRlcm4oQXhpcy5DSElMRCwgbnQsIHBwKTsKLQotICAgICAgICAgICAgICBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0ID0gbmV3IGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2woMzIvKlN0ZXBQYXR0ZXJuKi8sICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMSkpLmxlZnQsICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0LCBSRVNVTFQpOwotICAgICAgICAgICAgfQotICAgICAgICAgIHJldHVybiBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0OwotCi0gICAgICAgICAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotICAgICAgICAgIGNhc2UgMTg6IC8vIFN0ZXBQYXR0ZXJuIDo6PSBOb2RlVGVzdFBhdHRlcm4KLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgU3RlcFBhdHRlcm4gUkVTVUxUID0gbnVsbDsKLSAgICAgICAgICAgICAgICBpbnQgbnRsZWZ0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkubGVmdDsKLSAgICAgICAgICAgICAgICBpbnQgbnRyaWdodCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0OwotICAgICAgICAgICAgICAgIE9iamVjdCBudCA9IChPYmplY3QpKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKSBDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnZhbHVlOwotCi0gICAgICAgICAgICAgICAgUkVTVUxUID0gcGFyc2VyLmNyZWF0ZVN0ZXBQYXR0ZXJuKEF4aXMuQ0hJTEQsIG50LCBudWxsKTsKLQotICAgICAgICAgICAgICBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0ID0gbmV3IGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2woMzIvKlN0ZXBQYXR0ZXJuKi8sICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLmxlZnQsICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0LCBSRVNVTFQpOwotICAgICAgICAgICAgfQotICAgICAgICAgIHJldHVybiBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0OwotCi0gICAgICAgICAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotICAgICAgICAgIGNhc2UgMTc6IC8vIFJlbGF0aXZlUGF0aFBhdHRlcm4gOjo9IFN0ZXBQYXR0ZXJuIERTTEFTSCBSZWxhdGl2ZVBhdGhQYXR0ZXJuCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIFJlbGF0aXZlUGF0aFBhdHRlcm4gUkVTVUxUID0gbnVsbDsKLSAgICAgICAgICAgICAgICBpbnQgc3BsZWZ0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0yKSkubGVmdDsKLSAgICAgICAgICAgICAgICBpbnQgc3ByaWdodCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMikpLnJpZ2h0OwotICAgICAgICAgICAgICAgIFN0ZXBQYXR0ZXJuIHNwID0gKFN0ZXBQYXR0ZXJuKSgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCkgQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTIpKS52YWx1ZTsKLSAgICAgICAgICAgICAgICBpbnQgcnBwbGVmdCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLmxlZnQ7Ci0gICAgICAgICAgICAgICAgaW50IHJwcHJpZ2h0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQ7Ci0gICAgICAgICAgICAgICAgUmVsYXRpdmVQYXRoUGF0dGVybiBycHAgPSAoUmVsYXRpdmVQYXRoUGF0dGVybikoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpIENVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkudmFsdWU7Ci0gICAgICAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBBbmNlc3RvclBhdHRlcm4oc3AsIHJwcCk7Ci0gICAgICAgICAgICAgIENVUCRYUGF0aFBhcnNlciRyZXN1bHQgPSBuZXcgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCgzMS8qUmVsYXRpdmVQYXRoUGF0dGVybiovLCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTIpKS5sZWZ0LCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodCwgUkVTVUxUKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICByZXR1cm4gQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdDsKLQotICAgICAgICAgIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuKi8KLSAgICAgICAgICBjYXNlIDE2OiAvLyBSZWxhdGl2ZVBhdGhQYXR0ZXJuIDo6PSBTdGVwUGF0dGVybiBTTEFTSCBSZWxhdGl2ZVBhdGhQYXR0ZXJuCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIFJlbGF0aXZlUGF0aFBhdHRlcm4gUkVTVUxUID0gbnVsbDsKLSAgICAgICAgICAgICAgICBpbnQgc3BsZWZ0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0yKSkubGVmdDsKLSAgICAgICAgICAgICAgICBpbnQgc3ByaWdodCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMikpLnJpZ2h0OwotICAgICAgICAgICAgICAgIFN0ZXBQYXR0ZXJuIHNwID0gKFN0ZXBQYXR0ZXJuKSgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCkgQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTIpKS52YWx1ZTsKLSAgICAgICAgICAgICAgICBpbnQgcnBwbGVmdCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLmxlZnQ7Ci0gICAgICAgICAgICAgICAgaW50IHJwcHJpZ2h0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQ7Ci0gICAgICAgICAgICAgICAgUmVsYXRpdmVQYXRoUGF0dGVybiBycHAgPSAoUmVsYXRpdmVQYXRoUGF0dGVybikoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpIENVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkudmFsdWU7Ci0gICAgICAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBQYXJlbnRQYXR0ZXJuKHNwLCBycHApOwotICAgICAgICAgICAgICBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0ID0gbmV3IGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2woMzEvKlJlbGF0aXZlUGF0aFBhdHRlcm4qLywgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0yKSkubGVmdCwgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQsIFJFU1VMVCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgcmV0dXJuIENVUCRYUGF0aFBhcnNlciRyZXN1bHQ7Ci0KLSAgICAgICAgICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0gICAgICAgICAgY2FzZSAxNTogLy8gUmVsYXRpdmVQYXRoUGF0dGVybiA6Oj0gU3RlcFBhdHRlcm4KLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgUmVsYXRpdmVQYXRoUGF0dGVybiBSRVNVTFQgPSBudWxsOwotICAgICAgICAgICAgICAgIGludCBzcGxlZnQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0OwotICAgICAgICAgICAgICAgIGludCBzcHJpZ2h0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQ7Ci0gICAgICAgICAgICAgICAgU3RlcFBhdHRlcm4gc3AgPSAoU3RlcFBhdHRlcm4pKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKSBDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnZhbHVlOwotICAgICAgICAgICAgICAgICBSRVNVTFQgPSBzcDsKLSAgICAgICAgICAgICAgQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdCA9IG5ldyBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKDMxLypSZWxhdGl2ZVBhdGhQYXR0ZXJuKi8sICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLmxlZnQsICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0LCBSRVNVTFQpOwotICAgICAgICAgICAgfQotICAgICAgICAgIHJldHVybiBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0OwotCi0gICAgICAgICAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotICAgICAgICAgIGNhc2UgMTQ6IC8vIFByb2Nlc3NpbmdJbnN0cnVjdGlvblBhdHRlcm4gOjo9IFBJUEFSQU0gTFBBUkVOIExpdGVyYWwgUlBBUkVOCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIFN0ZXBQYXR0ZXJuIFJFU1VMVCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgaW50IGxsZWZ0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0xKSkubGVmdDsKLSAgICAgICAgICAgICAgICBpbnQgbHJpZ2h0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0xKSkucmlnaHQ7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIGwgPSAoU3RyaW5nKSgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCkgQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTEpKS52YWx1ZTsKLSAgICAgICAgICAgICAgICAgUkVTVUxUID0gbmV3IFByb2Nlc3NpbmdJbnN0cnVjdGlvblBhdHRlcm4obCk7Ci0gICAgICAgICAgICAgIENVUCRYUGF0aFBhcnNlciRyZXN1bHQgPSBuZXcgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCgzMC8qUHJvY2Vzc2luZ0luc3RydWN0aW9uUGF0dGVybiovLCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTMpKS5sZWZ0LCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodCwgUkVTVUxUKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICByZXR1cm4gQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdDsKLQotICAgICAgICAgIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuKi8KLSAgICAgICAgICBjYXNlIDEzOiAvLyBJZEtleVBhdHRlcm4gOjo9IEtFWSBMUEFSRU4gTGl0ZXJhbCBDT01NQSBMaXRlcmFsIFJQQVJFTgotICAgICAgICAgICAgewotICAgICAgICAgICAgICBJZEtleVBhdHRlcm4gUkVTVUxUID0gbnVsbDsKLSAgICAgICAgICAgICAgICBpbnQgbDFsZWZ0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0zKSkubGVmdDsKLSAgICAgICAgICAgICAgICBpbnQgbDFyaWdodCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMykpLnJpZ2h0OwotICAgICAgICAgICAgICAgIFN0cmluZyBsMSA9IChTdHJpbmcpKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKSBDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMykpLnZhbHVlOwotICAgICAgICAgICAgICAgIGludCBsMmxlZnQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTEpKS5sZWZ0OwotICAgICAgICAgICAgICAgIGludCBsMnJpZ2h0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0xKSkucmlnaHQ7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIGwyID0gKFN0cmluZykoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpIENVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0xKSkudmFsdWU7Ci0gICAgICAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBLZXlQYXR0ZXJuKGwxLCBsMik7Ci0gICAgICAgICAgICAgIENVUCRYUGF0aFBhcnNlciRyZXN1bHQgPSBuZXcgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCgyNy8qSWRLZXlQYXR0ZXJuKi8sICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtNSkpLmxlZnQsICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0LCBSRVNVTFQpOwotICAgICAgICAgICAgfQotICAgICAgICAgIHJldHVybiBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0OwotCi0gICAgICAgICAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotICAgICAgICAgIGNhc2UgMTI6IC8vIElkS2V5UGF0dGVybiA6Oj0gSUQgTFBBUkVOIExpdGVyYWwgUlBBUkVOCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIElkS2V5UGF0dGVybiBSRVNVTFQgPSBudWxsOwotICAgICAgICAgICAgICAgIGludCBsbGVmdCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMSkpLmxlZnQ7Ci0gICAgICAgICAgICAgICAgaW50IGxyaWdodCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMSkpLnJpZ2h0OwotICAgICAgICAgICAgICAgIFN0cmluZyBsID0gKFN0cmluZykoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpIENVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0xKSkudmFsdWU7Ci0gICAgICAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBJZFBhdHRlcm4obCk7Ci0gICAgICAgICAgICAgICBwYXJzZXIuc2V0SGFzSWRDYWxsKHRydWUpOwotCi0gICAgICAgICAgICAgIENVUCRYUGF0aFBhcnNlciRyZXN1bHQgPSBuZXcgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCgyNy8qSWRLZXlQYXR0ZXJuKi8sICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMykpLmxlZnQsICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0LCBSRVNVTFQpOwotICAgICAgICAgICAgfQotICAgICAgICAgIHJldHVybiBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0OwotCi0gICAgICAgICAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotICAgICAgICAgIGNhc2UgMTE6IC8vIExvY2F0aW9uUGF0aFBhdHRlcm4gOjo9IFJlbGF0aXZlUGF0aFBhdHRlcm4KLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgUGF0dGVybiBSRVNVTFQgPSBudWxsOwotICAgICAgICAgICAgICAgIGludCBycHBsZWZ0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkubGVmdDsKLSAgICAgICAgICAgICAgICBpbnQgcnBwcmlnaHQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodDsKLSAgICAgICAgICAgICAgICBSZWxhdGl2ZVBhdGhQYXR0ZXJuIHJwcCA9IChSZWxhdGl2ZVBhdGhQYXR0ZXJuKSgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCkgQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS52YWx1ZTsKLSAgICAgICAgICAgICAgICAgUkVTVUxUID0gcnBwOwotICAgICAgICAgICAgICBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0ID0gbmV3IGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2woMjkvKkxvY2F0aW9uUGF0aFBhdHRlcm4qLywgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkubGVmdCwgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQsIFJFU1VMVCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgcmV0dXJuIENVUCRYUGF0aFBhcnNlciRyZXN1bHQ7Ci0KLSAgICAgICAgICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0gICAgICAgICAgY2FzZSAxMDogLy8gTG9jYXRpb25QYXRoUGF0dGVybiA6Oj0gRFNMQVNIIFJlbGF0aXZlUGF0aFBhdHRlcm4KLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgUGF0dGVybiBSRVNVTFQgPSBudWxsOwotICAgICAgICAgICAgICAgIGludCBycHBsZWZ0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkubGVmdDsKLSAgICAgICAgICAgICAgICBpbnQgcnBwcmlnaHQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodDsKLSAgICAgICAgICAgICAgICBSZWxhdGl2ZVBhdGhQYXR0ZXJuIHJwcCA9IChSZWxhdGl2ZVBhdGhQYXR0ZXJuKSgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCkgQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS52YWx1ZTsKLSAgICAgICAgICAgICAgICAgUkVTVUxUID0gbmV3IEFuY2VzdG9yUGF0dGVybihycHApOwotICAgICAgICAgICAgICBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0ID0gbmV3IGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2woMjkvKkxvY2F0aW9uUGF0aFBhdHRlcm4qLywgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0xKSkubGVmdCwgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQsIFJFU1VMVCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgcmV0dXJuIENVUCRYUGF0aFBhcnNlciRyZXN1bHQ7Ci0KLSAgICAgICAgICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0gICAgICAgICAgY2FzZSA5OiAvLyBMb2NhdGlvblBhdGhQYXR0ZXJuIDo6PSBJZEtleVBhdHRlcm4gRFNMQVNIIFJlbGF0aXZlUGF0aFBhdHRlcm4KLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgUGF0dGVybiBSRVNVTFQgPSBudWxsOwotICAgICAgICAgICAgICAgIGludCBpa3BsZWZ0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0yKSkubGVmdDsKLSAgICAgICAgICAgICAgICBpbnQgaWtwcmlnaHQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTIpKS5yaWdodDsKLSAgICAgICAgICAgICAgICBJZEtleVBhdHRlcm4gaWtwID0gKElkS2V5UGF0dGVybikoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpIENVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0yKSkudmFsdWU7Ci0gICAgICAgICAgICAgICAgaW50IHJwcGxlZnQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0OwotICAgICAgICAgICAgICAgIGludCBycHByaWdodCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0OwotICAgICAgICAgICAgICAgIFJlbGF0aXZlUGF0aFBhdHRlcm4gcnBwID0gKFJlbGF0aXZlUGF0aFBhdHRlcm4pKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKSBDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnZhbHVlOwotICAgICAgICAgICAgICAgICBSRVNVTFQgPSBuZXcgQW5jZXN0b3JQYXR0ZXJuKGlrcCwgcnBwKTsKLSAgICAgICAgICAgICAgQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdCA9IG5ldyBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKDI5LypMb2NhdGlvblBhdGhQYXR0ZXJuKi8sICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMikpLmxlZnQsICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0LCBSRVNVTFQpOwotICAgICAgICAgICAgfQotICAgICAgICAgIHJldHVybiBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0OwotCi0gICAgICAgICAgLyouIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4qLwotICAgICAgICAgIGNhc2UgODogLy8gTG9jYXRpb25QYXRoUGF0dGVybiA6Oj0gSWRLZXlQYXR0ZXJuIFNMQVNIIFJlbGF0aXZlUGF0aFBhdHRlcm4KLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgUGF0dGVybiBSRVNVTFQgPSBudWxsOwotICAgICAgICAgICAgICAgIGludCBpa3BsZWZ0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0yKSkubGVmdDsKLSAgICAgICAgICAgICAgICBpbnQgaWtwcmlnaHQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTIpKS5yaWdodDsKLSAgICAgICAgICAgICAgICBJZEtleVBhdHRlcm4gaWtwID0gKElkS2V5UGF0dGVybikoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpIENVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0yKSkudmFsdWU7Ci0gICAgICAgICAgICAgICAgaW50IHJwcGxlZnQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0OwotICAgICAgICAgICAgICAgIGludCBycHByaWdodCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0OwotICAgICAgICAgICAgICAgIFJlbGF0aXZlUGF0aFBhdHRlcm4gcnBwID0gKFJlbGF0aXZlUGF0aFBhdHRlcm4pKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKSBDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnZhbHVlOwotICAgICAgICAgICAgICAgICBSRVNVTFQgPSBuZXcgUGFyZW50UGF0dGVybihpa3AsIHJwcCk7Ci0gICAgICAgICAgICAgIENVUCRYUGF0aFBhcnNlciRyZXN1bHQgPSBuZXcgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCgyOS8qTG9jYXRpb25QYXRoUGF0dGVybiovLCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTIpKS5sZWZ0LCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodCwgUkVTVUxUKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICByZXR1cm4gQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdDsKLQotICAgICAgICAgIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuKi8KLSAgICAgICAgICBjYXNlIDc6IC8vIExvY2F0aW9uUGF0aFBhdHRlcm4gOjo9IElkS2V5UGF0dGVybgotICAgICAgICAgICAgewotICAgICAgICAgICAgICBQYXR0ZXJuIFJFU1VMVCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgaW50IGlrcGxlZnQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0OwotICAgICAgICAgICAgICAgIGludCBpa3ByaWdodCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnJpZ2h0OwotICAgICAgICAgICAgICAgIElkS2V5UGF0dGVybiBpa3AgPSAoSWRLZXlQYXR0ZXJuKSgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCkgQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS52YWx1ZTsKLSAgICAgICAgICAgICAgICAgUkVTVUxUID0gaWtwOwotICAgICAgICAgICAgICBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0ID0gbmV3IGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2woMjkvKkxvY2F0aW9uUGF0aFBhdHRlcm4qLywgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkubGVmdCwgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQsIFJFU1VMVCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgcmV0dXJuIENVUCRYUGF0aFBhcnNlciRyZXN1bHQ7Ci0KLSAgICAgICAgICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0gICAgICAgICAgY2FzZSA2OiAvLyBMb2NhdGlvblBhdGhQYXR0ZXJuIDo6PSBTTEFTSCBSZWxhdGl2ZVBhdGhQYXR0ZXJuCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIFBhdHRlcm4gUkVTVUxUID0gbnVsbDsKLSAgICAgICAgICAgICAgICBpbnQgcnBwbGVmdCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLmxlZnQ7Ci0gICAgICAgICAgICAgICAgaW50IHJwcHJpZ2h0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQ7Ci0gICAgICAgICAgICAgICAgUmVsYXRpdmVQYXRoUGF0dGVybiBycHAgPSAoUmVsYXRpdmVQYXRoUGF0dGVybikoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpIENVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkudmFsdWU7Ci0gICAgICAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBBYnNvbHV0ZVBhdGhQYXR0ZXJuKHJwcCk7Ci0gICAgICAgICAgICAgIENVUCRYUGF0aFBhcnNlciRyZXN1bHQgPSBuZXcgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCgyOS8qTG9jYXRpb25QYXRoUGF0dGVybiovLCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTEpKS5sZWZ0LCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodCwgUkVTVUxUKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICByZXR1cm4gQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdDsKLQotICAgICAgICAgIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuKi8KLSAgICAgICAgICBjYXNlIDU6IC8vIExvY2F0aW9uUGF0aFBhdHRlcm4gOjo9IFNMQVNICi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIFBhdHRlcm4gUkVTVUxUID0gbnVsbDsKLSAgICAgICAgICAgICAgICAgUkVTVUxUID0gbmV3IEFic29sdXRlUGF0aFBhdHRlcm4obnVsbCk7Ci0gICAgICAgICAgICAgIENVUCRYUGF0aFBhcnNlciRyZXN1bHQgPSBuZXcgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCgyOS8qTG9jYXRpb25QYXRoUGF0dGVybiovLCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5sZWZ0LCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodCwgUkVTVUxUKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICByZXR1cm4gQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdDsKLQotICAgICAgICAgIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuKi8KLSAgICAgICAgICBjYXNlIDQ6IC8vIFBhdHRlcm4gOjo9IExvY2F0aW9uUGF0aFBhdHRlcm4gVkJBUiBQYXR0ZXJuCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIFBhdHRlcm4gUkVTVUxUID0gbnVsbDsKLSAgICAgICAgICAgICAgICBpbnQgbHBwbGVmdCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMikpLmxlZnQ7Ci0gICAgICAgICAgICAgICAgaW50IGxwcHJpZ2h0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0yKSkucmlnaHQ7Ci0gICAgICAgICAgICAgICAgUGF0dGVybiBscHAgPSAoUGF0dGVybikoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpIENVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0yKSkudmFsdWU7Ci0gICAgICAgICAgICAgICAgaW50IHBsZWZ0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkubGVmdDsKLSAgICAgICAgICAgICAgICBpbnQgcHJpZ2h0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQ7Ci0gICAgICAgICAgICAgICAgUGF0dGVybiBwID0gKFBhdHRlcm4pKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKSBDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnZhbHVlOwotICAgICAgICAgICAgICAgICBSRVNVTFQgPSBuZXcgQWx0ZXJuYXRpdmVQYXR0ZXJuKGxwcCwgcCk7Ci0gICAgICAgICAgICAgIENVUCRYUGF0aFBhcnNlciRyZXN1bHQgPSBuZXcgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCgyOC8qUGF0dGVybiovLCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTIpKS5sZWZ0LCAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodCwgUkVTVUxUKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICByZXR1cm4gQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdDsKLQotICAgICAgICAgIC8qLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuKi8KLSAgICAgICAgICBjYXNlIDM6IC8vIFBhdHRlcm4gOjo9IExvY2F0aW9uUGF0aFBhdHRlcm4KLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgUGF0dGVybiBSRVNVTFQgPSBudWxsOwotICAgICAgICAgICAgICAgIGludCBscHBsZWZ0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkubGVmdDsKLSAgICAgICAgICAgICAgICBpbnQgbHBwcmlnaHQgPSAoKGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2wpQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS5yaWdodDsKLSAgICAgICAgICAgICAgICBQYXR0ZXJuIGxwcCA9IChQYXR0ZXJuKSgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCkgQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTApKS52YWx1ZTsKLSAgICAgICAgICAgICAgICAgUkVTVUxUID0gbHBwOwotICAgICAgICAgICAgICBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0ID0gbmV3IGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2woMjgvKlBhdHRlcm4qLywgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkubGVmdCwgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQsIFJFU1VMVCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgcmV0dXJuIENVUCRYUGF0aFBhcnNlciRyZXN1bHQ7Ci0KLSAgICAgICAgICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0gICAgICAgICAgY2FzZSAyOiAvLyBUb3BMZXZlbCA6Oj0gRVhQUkVTU0lPTiBFeHByCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIFN5bnRheFRyZWVOb2RlIFJFU1VMVCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgaW50IGV4cHJsZWZ0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkubGVmdDsKLSAgICAgICAgICAgICAgICBpbnQgZXhwcnJpZ2h0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQ7Ci0gICAgICAgICAgICAgICAgRXhwcmVzc2lvbiBleHByID0gKEV4cHJlc3Npb24pKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKSBDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnZhbHVlOwotICAgICAgICAgICAgICAgICBSRVNVTFQgPSBleHByOwotICAgICAgICAgICAgICBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0ID0gbmV3IGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2woMS8qVG9wTGV2ZWwqLywgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0xKSkubGVmdCwgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQsIFJFU1VMVCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgcmV0dXJuIENVUCRYUGF0aFBhcnNlciRyZXN1bHQ7Ci0KLSAgICAgICAgICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0gICAgICAgICAgY2FzZSAxOiAvLyBUb3BMZXZlbCA6Oj0gUEFUVEVSTiBQYXR0ZXJuCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIFN5bnRheFRyZWVOb2RlIFJFU1VMVCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgaW50IHBhdHRlcm5sZWZ0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkubGVmdDsKLSAgICAgICAgICAgICAgICBpbnQgcGF0dGVybnJpZ2h0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQ7Ci0gICAgICAgICAgICAgICAgUGF0dGVybiBwYXR0ZXJuID0gKFBhdHRlcm4pKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKSBDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMCkpLnZhbHVlOwotICAgICAgICAgICAgICAgICBSRVNVTFQgPSBwYXR0ZXJuOwotICAgICAgICAgICAgICBDVVAkWFBhdGhQYXJzZXIkcmVzdWx0ID0gbmV3IGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2woMS8qVG9wTGV2ZWwqLywgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0xKSkubGVmdCwgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQsIFJFU1VMVCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgcmV0dXJuIENVUCRYUGF0aFBhcnNlciRyZXN1bHQ7Ci0KLSAgICAgICAgICAvKi4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiAuIC4gLiovCi0gICAgICAgICAgY2FzZSAwOiAvLyAkU1RBUlQgOjo9IFRvcExldmVsIEVPRgotICAgICAgICAgICAgewotICAgICAgICAgICAgICBPYmplY3QgUkVTVUxUID0gbnVsbDsKLSAgICAgICAgICAgICAgICBpbnQgc3RhcnRfdmFsbGVmdCA9ICgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbClDVVAkWFBhdGhQYXJzZXIkc3RhY2suZWxlbWVudEF0KENVUCRYUGF0aFBhcnNlciR0b3AtMSkpLmxlZnQ7Ci0gICAgICAgICAgICAgICAgaW50IHN0YXJ0X3ZhbHJpZ2h0ID0gKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0xKSkucmlnaHQ7Ci0gICAgICAgICAgICAgICAgU3ludGF4VHJlZU5vZGUgc3RhcnRfdmFsID0gKFN5bnRheFRyZWVOb2RlKSgoY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCkgQ1VQJFhQYXRoUGFyc2VyJHN0YWNrLmVsZW1lbnRBdChDVVAkWFBhdGhQYXJzZXIkdG9wLTEpKS52YWx1ZTsKLSAgICAgICAgICAgICAgICBSRVNVTFQgPSBzdGFydF92YWw7Ci0gICAgICAgICAgICAgIENVUCRYUGF0aFBhcnNlciRyZXN1bHQgPSBuZXcgY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lLlN5bWJvbCgwLyokU1RBUlQqLywgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0xKSkubGVmdCwgKChjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuU3ltYm9sKUNVUCRYUGF0aFBhcnNlciRzdGFjay5lbGVtZW50QXQoQ1VQJFhQYXRoUGFyc2VyJHRvcC0wKSkucmlnaHQsIFJFU1VMVCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgLyogQUNDRVBUICovCi0gICAgICAgICAgQ1VQJFhQYXRoUGFyc2VyJHBhcnNlci5kb25lX3BhcnNpbmcoKTsKLSAgICAgICAgICByZXR1cm4gQ1VQJFhQYXRoUGFyc2VyJHJlc3VsdDsKLQotICAgICAgICAgIC8qIC4gLiAuIC4gLiAuKi8KLSAgICAgICAgICBkZWZhdWx0OgotICAgICAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICJJbnZhbGlkIGFjdGlvbiBudW1iZXIgZm91bmQgaW4gaW50ZXJuYWwgcGFyc2UgdGFibGUiKTsKLQotICAgICAgICB9Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9YU0xUQy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9YU0xUQy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2MzFlZGJkLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvWFNMVEMuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEwMzIgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAxMiwgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqLwotLyoKLSAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQotICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCi0gKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCi0gKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAotICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKLSAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuY2xhc3NmaWxlLkphdmFDbGFzczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwuWGFsYW5Db25zdGFudHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnV0aWxzLkZlYXR1cmVNYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC51dGlscy5GZWF0dXJlTWFuYWdlci5GZWF0dXJlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC51dGlscy5TZWN1cml0eVN1cHBvcnQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnV0aWxzLlhNTFNlY3VyaXR5TWFuYWdlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5FcnJvck1zZzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5VdGlsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTTsKLWltcG9ydCBqYXZhLmlvLkJ1ZmZlcmVkT3V0cHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uRmlsZTsKLWltcG9ydCBqYXZhLmlvLkZpbGVPdXRwdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOwotaW1wb3J0IGphdmEubmV0LlVSTDsKLWltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwotaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKLWltcG9ydCBqYXZhLnV0aWwuRGF0ZTsKLWltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247Ci1pbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7Ci1pbXBvcnQgamF2YS51dGlsLk1hcDsKLWltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotaW1wb3J0IGphdmEudXRpbC5qYXIuSmFyRW50cnk7Ci1pbXBvcnQgamF2YS51dGlsLmphci5KYXJPdXRwdXRTdHJlYW07Ci1pbXBvcnQgamF2YS51dGlsLmphci5NYW5pZmVzdDsKLWltcG9ydCBqYXZheC54bWwuWE1MQ29uc3RhbnRzOwotaW1wb3J0IG9yZy54bWwuc2F4LklucHV0U291cmNlOwotaW1wb3J0IG9yZy54bWwuc2F4LlhNTFJlYWRlcjsKLQotLyoqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKiBAYXV0aG9yIEcuIFRvZGQgTWlsbGVyCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqIEBhdXRob3IgSm9obiBIb3dhcmQgKGpvaG5oQHNjaGVtYXNvZnQuY29tKQotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgWFNMVEMgewotCi0gICAgLy8gQSByZWZlcmVuY2UgdG8gdGhlIG1haW4gc3R5bGVzaGVldCBwYXJzZXIgb2JqZWN0LgotICAgIHByaXZhdGUgUGFyc2VyIF9wYXJzZXI7Ci0KLSAgICAvLyBBIHJlZmVyZW5jZSB0byBhbiBleHRlcm5hbCBYTUxSZWFkZXIgKFNBWCBwYXJzZXIpIHBhc3NlZCB0byB1cwotICAgIHByaXZhdGUgWE1MUmVhZGVyIF9yZWFkZXIgPSBudWxsOwotCi0gICAgLy8gQSByZWZlcmVuY2UgdG8gYW4gZXh0ZXJuYWwgU291cmNlTG9hZGVyIChmb3IgdXNlIHdpdGggaW5jbHVkZS9pbXBvcnQpCi0gICAgcHJpdmF0ZSBTb3VyY2VMb2FkZXIgX2xvYWRlciA9IG51bGw7Ci0KLSAgICAvLyBBIHJlZmVyZW5jZSB0byB0aGUgc3R5bGVzaGVldCBiZWluZyBjb21waWxlZC4KLSAgICBwcml2YXRlIFN0eWxlc2hlZXQgX3N0eWxlc2hlZXQ7Ci0KLSAgICAvLyBDb3VudGVycyB1c2VkIGJ5IHZhcmlvdXMgY2xhc3NlcyB0byBnZW5lcmF0ZSB1bmlxdWUgbmFtZXMuCi0gICAgLy8gcHJpdmF0ZSBpbnQgX3ZhcmlhYmxlU2VyaWFsICAgICA9IDE7Ci0gICAgcHJpdmF0ZSBpbnQgX21vZGVTZXJpYWwgICAgICAgICA9IDE7Ci0gICAgcHJpdmF0ZSBpbnQgX3N0eWxlc2hlZXRTZXJpYWwgICA9IDE7Ci0gICAgcHJpdmF0ZSBpbnQgX3N0ZXBQYXR0ZXJuU2VyaWFsICA9IDE7Ci0gICAgcHJpdmF0ZSBpbnQgX2hlbHBlckNsYXNzU2VyaWFsICA9IDA7Ci0gICAgcHJpdmF0ZSBpbnQgX2F0dHJpYnV0ZVNldFNlcmlhbCA9IDA7Ci0KLSAgICBwcml2YXRlIGludFtdIF9udW1iZXJGaWVsZEluZGV4ZXM7Ci0KLSAgICAvLyBOYW1lIGluZGV4IHRhYmxlcwotICAgIHByaXZhdGUgaW50ICAgICAgIF9uZXh0R1R5cGU7ICAvLyBOZXh0IGF2YWlsYWJsZSBlbGVtZW50IHR5cGUKLSAgICBwcml2YXRlIFZlY3RvciAgICBfbmFtZXNJbmRleDsgLy8gSW5kZXggb2YgYWxsIHJlZ2lzdGVyZWQgUU5hbWVzCi0gICAgcHJpdmF0ZSBNYXA8U3RyaW5nLCBJbnRlZ2VyPiBfZWxlbWVudHM7ICAgLy8gTWFwIG9mIGFsbCByZWdpc3RlcmVkIGVsZW1lbnRzCi0gICAgcHJpdmF0ZSBNYXA8U3RyaW5nLCBJbnRlZ2VyPiBfYXR0cmlidXRlczsgLy8gTWFwIG9mIGFsbCByZWdpc3RlcmVkIGF0dHJpYnV0ZXMKLQotICAgIC8vIE5hbWVzcGFjZSBpbmRleCB0YWJsZXMKLSAgICBwcml2YXRlIGludCAgICAgICBfbmV4dE5TVHlwZTsgLy8gTmV4dCBhdmFpbGFibGUgbmFtZXNwYWNlIHR5cGUKLSAgICBwcml2YXRlIFZlY3RvciAgICBfbmFtZXNwYWNlSW5kZXg7IC8vIEluZGV4IG9mIGFsbCByZWdpc3RlcmVkIG5hbWVzcGFjZXMKLSAgICBwcml2YXRlIE1hcDxTdHJpbmcsIEludGVnZXI+IF9uYW1lc3BhY2VzOyAvLyBNYXAgb2YgYWxsIHJlZ2lzdGVyZWQgbmFtZXNwYWNlcwotICAgIHByaXZhdGUgTWFwPFN0cmluZywgSW50ZWdlcj4gX25hbWVzcGFjZVByZWZpeGVzOy8vIE1hcCBvZiBhbGwgcmVnaXN0ZXJlZCBuYW1lc3BhY2UgcHJlZml4ZXMKLQotCi0gICAgLy8gQWxsIGxpdGVyYWwgdGV4dCBpbiB0aGUgc3R5bGVzaGVldAotICAgIHByaXZhdGUgVmVjdG9yIG1fY2hhcmFjdGVyRGF0YTsKLQotICAgIC8vIFRoZXNlIGRlZmluZSB0aGUgdmFyaW91cyBtZXRob2RzIGZvciBvdXRwdXR0aW5nIHRoZSB0cmFuc2xldAotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJTEVfT1VUUFVUICAgICAgICA9IDA7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSkFSX09VVFBVVCAgICAgICAgID0gMTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCWVRFQVJSQVlfT1VUUFVUICAgPSAyOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENMQVNTTE9BREVSX09VVFBVVCA9IDM7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQllURUFSUkFZX0FORF9GSUxFX09VVFBVVCA9IDQ7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQllURUFSUkFZX0FORF9KQVJfT1VUUFVUICA9IDU7Ci0KLQotICAgIC8vIENvbXBpbGVyIG9wdGlvbnMgKHBhc3NlZCBmcm9tIGNvbW1hbmQgbGluZSBvciBYU0xUQyBjbGllbnQpCi0gICAgcHJpdmF0ZSBib29sZWFuIF9kZWJ1ZyA9IGZhbHNlOyAgICAgIC8vIC14Ci0gICAgcHJpdmF0ZSBTdHJpbmcgIF9qYXJGaWxlTmFtZSA9IG51bGw7IC8vIC1qIDxqYXItZmlsZS1uYW1lPgotICAgIHByaXZhdGUgU3RyaW5nICBfY2xhc3NOYW1lID0gbnVsbDsgICAvLyAtbyA8Y2xhc3MtbmFtZT4KLSAgICBwcml2YXRlIFN0cmluZyAgX3BhY2thZ2VOYW1lID0gbnVsbDsgLy8gLXAgPHBhY2thZ2UtbmFtZT4KLSAgICBwcml2YXRlIEZpbGUgICAgX2Rlc3REaXIgPSBudWxsOyAgICAgLy8gLWQgPGRpcmVjdG9yeS1uYW1lPgotICAgIHByaXZhdGUgaW50ICAgICBfb3V0cHV0VHlwZSA9IEZJTEVfT1VUUFVUOyAvLyBieSBkZWZhdWx0Ci0KLSAgICBwcml2YXRlIFZlY3RvciAgX2NsYXNzZXM7Ci0gICAgcHJpdmF0ZSBWZWN0b3IgIF9iY2VsQ2xhc3NlczsKLSAgICBwcml2YXRlIGJvb2xlYW4gX2NhbGxzTm9kZXNldCA9IGZhbHNlOwotICAgIHByaXZhdGUgYm9vbGVhbiBfbXVsdGlEb2N1bWVudCA9IGZhbHNlOwotICAgIHByaXZhdGUgYm9vbGVhbiBfaGFzSWRDYWxsID0gZmFsc2U7Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgdG8gdHJ1ZSBpZiB0ZW1wbGF0ZSBpbmxpbmluZyBpcyByZXF1ZXN0ZWQuIFRlbXBsYXRlCi0gICAgICogaW5saW5pbmcgdXNlZCB0byBiZSB0aGUgZGVmYXVsdCwgYnV0IHdlIGhhdmUgZm91bmQgdGhhdAotICAgICAqIEhvdHNwb3RzIGRvZXMgYSBiZXR0ZXIgam9iIHdpdGggc2hvcnRlciBtZXRob2RzLCBzbyB0aGUKLSAgICAgKiBkZWZhdWx0IGlzICpub3QqIHRvIGlubGluZSBub3cuCi0gICAgICovCi0gICAgcHJpdmF0ZSBib29sZWFuIF90ZW1wbGF0ZUlubGluaW5nID0gZmFsc2U7Ci0KLSAgICAvKioKLSAgICAgKiBTdGF0ZSBvZiB0aGUgc2VjdXJlIHByb2Nlc3NpbmcgZmVhdHVyZS4KLSAgICAgKi8KLSAgICBwcml2YXRlIGJvb2xlYW4gX2lzU2VjdXJlUHJvY2Vzc2luZyA9IGZhbHNlOwotCi0gICAgcHJpdmF0ZSBib29sZWFuIF91c2VTZXJ2aWNlc01lY2hhbmlzbSA9IHRydWU7Ci0KLSAgICAvKioKLSAgICAgKiBwcm90b2NvbHMgYWxsb3dlZCBmb3IgZXh0ZXJuYWwgcmVmZXJlbmNlcyBzZXQgYnkgdGhlIHN0eWxlc2hlZXQgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiwgSW1wb3J0IGFuZCBJbmNsdWRlIGVsZW1lbnQuCi0gICAgICovCi0gICAgcHJpdmF0ZSBTdHJpbmcgX2FjY2Vzc0V4dGVybmFsU3R5bGVzaGVldCA9IFhhbGFuQ29uc3RhbnRzLkVYVEVSTkFMX0FDQ0VTU19ERUZBVUxUOwotICAgICAvKioKLSAgICAgKiBwcm90b2NvbHMgYWxsb3dlZCBmb3IgZXh0ZXJuYWwgRFREIHJlZmVyZW5jZXMgaW4gc291cmNlIGZpbGUgYW5kL29yIHN0eWxlc2hlZXQuCi0gICAgICovCi0gICAgcHJpdmF0ZSBTdHJpbmcgX2FjY2Vzc0V4dGVybmFsRFREID0gWGFsYW5Db25zdGFudHMuRVhURVJOQUxfQUNDRVNTX0RFRkFVTFQ7Ci0KLSAgICBwcml2YXRlIFhNTFNlY3VyaXR5TWFuYWdlciBfeG1sU2VjdXJpdHlNYW5hZ2VyOwotCi0gICAgcHJpdmF0ZSBmaW5hbCBGZWF0dXJlTWFuYWdlciBfZmVhdHVyZU1hbmFnZXI7Ci0KLSAgICAvKioKLSAgICAqICBFeHRlbnNpb24gZnVuY3Rpb24gY2xhc3MgbG9hZGVyIHZhcmlhYmxlcwotICAgICovCi0KLSAgICAvKiBDbGFzcyBsb2FkZXIgcmVmZXJlbmNlIHRoYXQgd2lsbCBiZSB1c2VkIGZvciBleHRlcm5hbCBleHRlbnNpb24gZnVuY3Rpb25zIGxvYWRpbmcgKi8KLSAgICBwcml2YXRlIENsYXNzTG9hZGVyIF9leHRlbnNpb25DbGFzc0xvYWRlcjsKLQotICAgIC8qKgotICAgICogIEhhc2hNYXAgd2l0aCB0aGUgbG9hZGVkIGNsYXNzZXMKLSAgICAqLwotICAgIHByaXZhdGUgZmluYWwgTWFwPFN0cmluZywgQ2xhc3M+IF9leHRlcm5hbEV4dGVuc2lvbkZ1bmN0aW9uczsKLQotICAgIC8qKgotICAgICAqIFhTTFRDIGNvbXBpbGVyIGNvbnN0cnVjdG9yCi0gICAgICovCi0gICAgcHVibGljIFhTTFRDKGJvb2xlYW4gdXNlU2VydmljZXNNZWNoYW5pc20sIEZlYXR1cmVNYW5hZ2VyIGZlYXR1cmVNYW5hZ2VyKSB7Ci0gICAgICAgIF9wYXJzZXIgPSBuZXcgUGFyc2VyKHRoaXMsIHVzZVNlcnZpY2VzTWVjaGFuaXNtKTsKLSAgICAgICAgX2ZlYXR1cmVNYW5hZ2VyID0gZmVhdHVyZU1hbmFnZXI7Ci0gICAgICAgIF9leHRlbnNpb25DbGFzc0xvYWRlciA9IG51bGw7Ci0gICAgICAgIF9leHRlcm5hbEV4dGVuc2lvbkZ1bmN0aW9ucyA9IG5ldyBIYXNoTWFwPD4oKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIHN0YXRlIG9mIHRoZSBzZWN1cmUgcHJvY2Vzc2luZyBmZWF0dXJlLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFNlY3VyZVByb2Nlc3NpbmcoYm9vbGVhbiBmbGFnKSB7Ci0gICAgICAgIF9pc1NlY3VyZVByb2Nlc3NpbmcgPSBmbGFnOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybiB0aGUgc3RhdGUgb2YgdGhlIHNlY3VyZSBwcm9jZXNzaW5nIGZlYXR1cmUuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNTZWN1cmVQcm9jZXNzaW5nKCkgewotICAgICAgICByZXR1cm4gX2lzU2VjdXJlUHJvY2Vzc2luZzsKLSAgICB9Ci0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSBzdGF0ZSBvZiB0aGUgc2VydmljZXMgbWVjaGFuaXNtIGZlYXR1cmUuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gdXNlU2VydmljZXNNZWNobmlzbSgpIHsKLSAgICAgICAgcmV0dXJuIF91c2VTZXJ2aWNlc01lY2hhbmlzbTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIHN0YXRlIG9mIHRoZSBzZXJ2aWNlcyBtZWNoYW5pc20gZmVhdHVyZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRTZXJ2aWNlc01lY2huaXNtKGJvb2xlYW4gZmxhZykgewotICAgICAgICBfdXNlU2VydmljZXNNZWNoYW5pc20gPSBmbGFnOwotICAgIH0KLQotICAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgZmVhdHVyZQotICAgICAqIEBwYXJhbSBuYW1lIG5hbWUgb2YgdGhlIGZlYXR1cmUKLSAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGZlYXR1cmUgaXMgZW5hYmxlZCwgZmFsc2Ugb3RoZXJ3aXNlCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0RmVhdHVyZShGZWF0dXJlIG5hbWUpIHsKLSAgICAgICAgcmV0dXJuIF9mZWF0dXJlTWFuYWdlci5pc0ZlYXR1cmVFbmFibGVkKG5hbWUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybiBhbGxvd2VkIHByb3RvY29scyBmb3IgYWNjZXNzaW5nIGV4dGVybmFsIHN0eWxlc2hlZXQuCi0gICAgICovCi0gICAgcHVibGljIE9iamVjdCBnZXRQcm9wZXJ0eShTdHJpbmcgbmFtZSkgewotICAgICAgICBpZiAobmFtZS5lcXVhbHMoWE1MQ29uc3RhbnRzLkFDQ0VTU19FWFRFUk5BTF9TVFlMRVNIRUVUKSkgewotICAgICAgICAgICAgcmV0dXJuIF9hY2Nlc3NFeHRlcm5hbFN0eWxlc2hlZXQ7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAobmFtZS5lcXVhbHMoWE1MQ29uc3RhbnRzLkFDQ0VTU19FWFRFUk5BTF9EVEQpKSB7Ci0gICAgICAgICAgICByZXR1cm4gX2FjY2Vzc0V4dGVybmFsRFREOwotICAgICAgICB9IGVsc2UgaWYgKG5hbWUuZXF1YWxzKFhhbGFuQ29uc3RhbnRzLlNFQ1VSSVRZX01BTkFHRVIpKSB7Ci0gICAgICAgICAgICByZXR1cm4gX3htbFNlY3VyaXR5TWFuYWdlcjsKLSAgICAgICAgfSBlbHNlIGlmIChuYW1lLmVxdWFscyhYYWxhbkNvbnN0YW50cy5KREtfRVhURU5TSU9OX0NMQVNTTE9BREVSKSkgewotICAgICAgICAgICAgcmV0dXJuIF9leHRlbnNpb25DbGFzc0xvYWRlcjsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgYWxsb3dlZCBwcm90b2NvbHMgZm9yIGFjY2Vzc2luZyBleHRlcm5hbCBzdHlsZXNoZWV0LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFByb3BlcnR5KFN0cmluZyBuYW1lLCBPYmplY3QgdmFsdWUpIHsKLSAgICAgICAgaWYgKG5hbWUuZXF1YWxzKFhNTENvbnN0YW50cy5BQ0NFU1NfRVhURVJOQUxfU1RZTEVTSEVFVCkpIHsKLSAgICAgICAgICAgIF9hY2Nlc3NFeHRlcm5hbFN0eWxlc2hlZXQgPSAoU3RyaW5nKXZhbHVlOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzKFhNTENvbnN0YW50cy5BQ0NFU1NfRVhURVJOQUxfRFREKSkgewotICAgICAgICAgICAgX2FjY2Vzc0V4dGVybmFsRFREID0gKFN0cmluZyl2YWx1ZTsKLSAgICAgICAgfSBlbHNlIGlmIChuYW1lLmVxdWFscyhYYWxhbkNvbnN0YW50cy5TRUNVUklUWV9NQU5BR0VSKSkgewotICAgICAgICAgICAgX3htbFNlY3VyaXR5TWFuYWdlciA9IChYTUxTZWN1cml0eU1hbmFnZXIpdmFsdWU7Ci0gICAgICAgIH0gZWxzZSBpZiAobmFtZS5lcXVhbHMoWGFsYW5Db25zdGFudHMuSkRLX0VYVEVOU0lPTl9DTEFTU0xPQURFUikpIHsKLSAgICAgICAgICAgIF9leHRlbnNpb25DbGFzc0xvYWRlciA9IChDbGFzc0xvYWRlcikgdmFsdWU7Ci0gICAgICAgICAgICAvKiBDbGVhciB0aGUgZXh0ZXJuYWwgZXh0ZW5zaW9uIGZ1bmN0aW9ucyBIYXNoTWFwIGlmIGV4dGVuc2lvbiBjbGFzcwotICAgICAgICAgICAgICAgbG9hZGVyIHdhcyBjaGFuZ2VkICovCi0gICAgICAgICAgICBfZXh0ZXJuYWxFeHRlbnNpb25GdW5jdGlvbnMuY2xlYXIoKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIE9ubHkgZm9yIHVzZXIgYnkgdGhlIGludGVybmFsIFRyQVggaW1wbGVtZW50YXRpb24uCi0gICAgICovCi0gICAgcHVibGljIFBhcnNlciBnZXRQYXJzZXIoKSB7Ci0gICAgICAgIHJldHVybiBfcGFyc2VyOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIE9ubHkgZm9yIHVzZXIgYnkgdGhlIGludGVybmFsIFRyQVggaW1wbGVtZW50YXRpb24uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0T3V0cHV0VHlwZShpbnQgdHlwZSkgewotICAgICAgICBfb3V0cHV0VHlwZSA9IHR5cGU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogT25seSBmb3IgdXNlciBieSB0aGUgaW50ZXJuYWwgVHJBWCBpbXBsZW1lbnRhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgUHJvcGVydGllcyBnZXRPdXRwdXRQcm9wZXJ0aWVzKCkgewotICAgICAgICByZXR1cm4gX3BhcnNlci5nZXRPdXRwdXRQcm9wZXJ0aWVzKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSW5pdGlhbGl6ZXMgdGhlIGNvbXBpbGVyIHRvIGNvbXBpbGUgYSBuZXcgc3R5bGVzaGVldAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGluaXQoKSB7Ci0gICAgICAgIHJlc2V0KCk7Ci0gICAgICAgIF9yZWFkZXIgPSBudWxsOwotICAgICAgICBfY2xhc3NlcyA9IG5ldyBWZWN0b3IoKTsKLSAgICAgICAgX2JjZWxDbGFzc2VzID0gbmV3IFZlY3RvcigpOwotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBzZXRFeHRlcm5hbEV4dGVuc2lvbkZ1bmN0aW9ucyhTdHJpbmcgbmFtZSwgQ2xhc3MgY2xhenopIHsKLSAgICAgICAgaWYgKF9pc1NlY3VyZVByb2Nlc3NpbmcgJiYgY2xhenogIT0gbnVsbCAmJiAhX2V4dGVybmFsRXh0ZW5zaW9uRnVuY3Rpb25zLmNvbnRhaW5zS2V5KG5hbWUpKSB7Ci0gICAgICAgICAgICBfZXh0ZXJuYWxFeHRlbnNpb25GdW5jdGlvbnMucHV0KG5hbWUsIGNsYXp6KTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qCi0gICAgICogRnVuY3Rpb24gbG9hZHMgYW4gZXh0ZXJuYWwgZXh0ZW5zaW9uIGZ1bmN0aW9uLgotICAgICAqIFRoZSBmaWx0ZXJpbmcgb2YgZnVuY3Rpb24gdHlwZXMgKGV4dGVybmFsLGludGVybmFsKSB0YWtlcyBwbGFjZSBpbiBGdW5jdGlvbkNhbGwgY2xhc3MKLSAgICAgKgotICAgICAqLwotICAgIENsYXNzIGxvYWRFeHRlcm5hbEZ1bmN0aW9uKFN0cmluZyBuYW1lKSB0aHJvd3MgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB7Ci0gICAgICAgIENsYXNzIGxvYWRlZCA9IG51bGw7Ci0gICAgICAgIC8vQ2hlY2sgaWYgdGhlIGZ1bmN0aW9uIGlzIG5vdCBsb2FkZWQgYWxyZWFkeQotICAgICAgICBpZiAoX2V4dGVybmFsRXh0ZW5zaW9uRnVuY3Rpb25zLmNvbnRhaW5zS2V5KG5hbWUpKSB7Ci0gICAgICAgICAgICBsb2FkZWQgPSBfZXh0ZXJuYWxFeHRlbnNpb25GdW5jdGlvbnMuZ2V0KG5hbWUpOwotICAgICAgICB9IGVsc2UgaWYgKF9leHRlbnNpb25DbGFzc0xvYWRlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBsb2FkZWQgPSBDbGFzcy5mb3JOYW1lKG5hbWUsIHRydWUsIF9leHRlbnNpb25DbGFzc0xvYWRlcik7Ci0gICAgICAgICAgICBzZXRFeHRlcm5hbEV4dGVuc2lvbkZ1bmN0aW9ucyhuYW1lLCBsb2FkZWQpOwotICAgICAgICB9Ci0gICAgICAgIGlmIChsb2FkZWQgPT0gbnVsbCkgewotICAgICAgICAgICAgdGhyb3cgbmV3IENsYXNzTm90Rm91bmRFeGNlcHRpb24obmFtZSk7Ci0gICAgICAgIH0KLSAgICAgICAgLy9SZXR1cm4gbG9hZGVkIGNsYXNzCi0gICAgICAgIHJldHVybiAoQ2xhc3MpIGxvYWRlZDsKLSAgICB9Ci0KLSAgICAvKgotICAgICAqIFJldHVybnMgdW5tb2RpZmlhYmxlIHZpZXcgb2YgSGFzaE1hcCB3aXRoIGxvYWRlZCBleHRlcm5hbCBleHRlbnNpb24KLSAgICAgKiBmdW5jdGlvbnMgLSB3aWxsIGJlIG5lZWRlZCBmb3IgdGhlIFRyYW5zZm9ybWVySW1wbAotICAgICovCi0gICAgcHVibGljIE1hcDxTdHJpbmcsIENsYXNzPiBnZXRFeHRlcm5hbEV4dGVuc2lvbkZ1bmN0aW9ucygpIHsKLSAgICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZU1hcChfZXh0ZXJuYWxFeHRlbnNpb25GdW5jdGlvbnMpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEluaXRpYWxpemVzIHRoZSBjb21waWxlciB0byBwcm9kdWNlIGEgbmV3IHRyYW5zbGV0Ci0gICAgICovCi0gICAgcHJpdmF0ZSB2b2lkIHJlc2V0KCkgewotICAgICAgICBfbmV4dEdUeXBlICAgICAgPSBEVE0uTlRZUEVTOwotICAgICAgICBfZWxlbWVudHMgICAgICAgPSBuZXcgSGFzaE1hcDw+KCk7Ci0gICAgICAgIF9hdHRyaWJ1dGVzICAgICA9IG5ldyBIYXNoTWFwPD4oKTsKLSAgICAgICAgX25hbWVzcGFjZXMgICAgID0gbmV3IEhhc2hNYXA8PigpOwotICAgICAgICBfbmFtZXNwYWNlcy5wdXQoIiIsbmV3IEludGVnZXIoX25leHROU1R5cGUpKTsKLSAgICAgICAgX25hbWVzSW5kZXggICAgID0gbmV3IFZlY3RvcigxMjgpOwotICAgICAgICBfbmFtZXNwYWNlSW5kZXggPSBuZXcgVmVjdG9yKDMyKTsKLSAgICAgICAgX25hbWVzcGFjZVByZWZpeGVzID0gbmV3IEhhc2hNYXA8PigpOwotICAgICAgICBfc3R5bGVzaGVldCAgICAgPSBudWxsOwotICAgICAgICBfcGFyc2VyLmluaXQoKTsKLSAgICAgICAgLy9fdmFyaWFibGVTZXJpYWwgICAgID0gMTsKLSAgICAgICAgX21vZGVTZXJpYWwgICAgICAgICA9IDE7Ci0gICAgICAgIF9zdHlsZXNoZWV0U2VyaWFsICAgPSAxOwotICAgICAgICBfc3RlcFBhdHRlcm5TZXJpYWwgID0gMTsKLSAgICAgICAgX2hlbHBlckNsYXNzU2VyaWFsICA9IDA7Ci0gICAgICAgIF9hdHRyaWJ1dGVTZXRTZXJpYWwgPSAwOwotICAgICAgICBfbXVsdGlEb2N1bWVudCAgICAgID0gZmFsc2U7Ci0gICAgICAgIF9oYXNJZENhbGwgICAgICAgICAgPSBmYWxzZTsKLSAgICAgICAgX251bWJlckZpZWxkSW5kZXhlcyA9IG5ldyBpbnRbXSB7Ci0gICAgICAgICAgICAtMSwgICAgICAgICAvLyBMRVZFTF9TSU5HTEUKLSAgICAgICAgICAgIC0xLCAgICAgICAgIC8vIExFVkVMX01VTFRJUExFCi0gICAgICAgICAgICAtMSAgICAgICAgICAvLyBMRVZFTF9BTlkKLSAgICAgICAgfTsKLSAgICAgICAgX2V4dGVybmFsRXh0ZW5zaW9uRnVuY3Rpb25zLmNsZWFyKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRGVmaW5lcyBhbiBleHRlcm5hbCBTb3VyY2VMb2FkZXIgdG8gcHJvdmlkZSB0aGUgY29tcGlsZXIgd2l0aCBkb2N1bWVudHMKLSAgICAgKiByZWZlcmVuY2VkIGluIHhzbDppbmNsdWRlL2ltcG9ydAotICAgICAqIEBwYXJhbSBsb2FkZXIgVGhlIFNvdXJjZUxvYWRlciB0byB1c2UgZm9yIGluY2x1ZGUvaW1wb3J0Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0U291cmNlTG9hZGVyKFNvdXJjZUxvYWRlciBsb2FkZXIpIHsKLSAgICAgICAgX2xvYWRlciA9IGxvYWRlcjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgYSBmbGFnIGluZGljYXRpbmcgaWYgdGVtcGxhdGVzIGFyZSB0byBiZSBpbmxpbmVkIG9yIG5vdC4gVGhlCi0gICAgICogZGVmYXVsdCBpcyB0byBkbyBpbmxpbmluZywgYnV0IHRoaXMgY2F1c2VzIHByb2JsZW1zIHdoZW4gdGhlCi0gICAgICogc3R5bGVzaGVldHMgaGF2ZSBhIGxhcmdlIG51bWJlciBvZiB0ZW1wbGF0ZXMgKGUuZy4gYnJhbmNoIHRhcmdldHMKLSAgICAgKiBleGNlZWRpbmcgNjRLIG9yIGEgbGVuZ3RoIG9mIGEgbWV0aG9kIGV4Y2VlZGluZyA2NEspLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFRlbXBsYXRlSW5saW5pbmcoYm9vbGVhbiB0ZW1wbGF0ZUlubGluaW5nKSB7Ci0gICAgICAgIF90ZW1wbGF0ZUlubGluaW5nID0gdGVtcGxhdGVJbmxpbmluZzsKLSAgICB9Ci0gICAgIC8qKgotICAgICAqIFJldHVybiB0aGUgc3RhdGUgb2YgdGhlIHRlbXBsYXRlIGlubGluaW5nIGZlYXR1cmUuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0VGVtcGxhdGVJbmxpbmluZygpIHsKLSAgICAgICAgcmV0dXJuIF90ZW1wbGF0ZUlubGluaW5nOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldCB0aGUgcGFyYW1ldGVycyB0byB1c2UgdG8gbG9jYXRlIHRoZSBjb3JyZWN0IDw/eG1sLXN0eWxlc2hlZXQgLi4uPz4KLSAgICAgKiBwcm9jZXNzaW5nIGluc3RydWN0aW9uIGluIHRoZSBjYXNlIHdoZXJlIHRoZSBpbnB1dCBkb2N1bWVudCB0byB0aGUKLSAgICAgKiBjb21waWxlciAoYW5kIHBhcnNlcikgaXMgYW4gWE1MIGRvY3VtZW50LgotICAgICAqIEBwYXJhbSBtZWRpYSBUaGUgbWVkaWEgYXR0cmlidXRlIHRvIGJlIG1hdGNoZWQuIE1heSBiZSBudWxsLCBpbiB3aGljaAotICAgICAqIGNhc2UgdGhlIHByZWZlcmVkIHRlbXBsYXRlcyB3aWxsIGJlIHVzZWQgKGkuZS4gYWx0ZXJuYXRlID0gbm8pLgotICAgICAqIEBwYXJhbSB0aXRsZSBUaGUgdmFsdWUgb2YgdGhlIHRpdGxlIGF0dHJpYnV0ZSB0byBtYXRjaC4gTWF5IGJlIG51bGwuCi0gICAgICogQHBhcmFtIGNoYXJzZXQgVGhlIHZhbHVlIG9mIHRoZSBjaGFyc2V0IGF0dHJpYnV0ZSB0byBtYXRjaC4gTWF5IGJlIG51bGwuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0UElQYXJhbWV0ZXJzKFN0cmluZyBtZWRpYSwgU3RyaW5nIHRpdGxlLCBTdHJpbmcgY2hhcnNldCkgewotICAgICAgICBfcGFyc2VyLnNldFBJUGFyYW1ldGVycyhtZWRpYSwgdGl0bGUsIGNoYXJzZXQpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbXBpbGVzIGFuIFhTTCBzdHlsZXNoZWV0IHBvaW50ZWQgdG8gYnkgYSBVUkwKLSAgICAgKiBAcGFyYW0gdXJsIEFuIFVSTCBjb250YWluaW5nIHRoZSBpbnB1dCBYU0wgc3R5bGVzaGVldAotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGNvbXBpbGUoVVJMIHVybCkgewotICAgICAgICB0cnkgewotICAgICAgICAgICAgLy8gT3BlbiBpbnB1dCBzdHJlYW0gZnJvbSBVUkwgYW5kIHdyYXAgaW5zaWRlIElucHV0U291cmNlCi0gICAgICAgICAgICBmaW5hbCBJbnB1dFN0cmVhbSBzdHJlYW0gPSB1cmwub3BlblN0cmVhbSgpOwotICAgICAgICAgICAgZmluYWwgSW5wdXRTb3VyY2UgaW5wdXQgPSBuZXcgSW5wdXRTb3VyY2Uoc3RyZWFtKTsKLSAgICAgICAgICAgIGlucHV0LnNldFN5c3RlbUlkKHVybC50b1N0cmluZygpKTsKLSAgICAgICAgICAgIHJldHVybiBjb21waWxlKGlucHV0LCBfY2xhc3NOYW1lKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewotICAgICAgICAgICAgX3BhcnNlci5yZXBvcnRFcnJvcihDb25zdGFudHMuRkFUQUwsIG5ldyBFcnJvck1zZyhFcnJvck1zZy5KQVhQX0NPTVBJTEVfRVJSLCBlKSk7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb21waWxlcyBhbiBYU0wgc3R5bGVzaGVldCBwb2ludGVkIHRvIGJ5IGEgVVJMCi0gICAgICogQHBhcmFtIHVybCBBbiBVUkwgY29udGFpbmluZyB0aGUgaW5wdXQgWFNMIHN0eWxlc2hlZXQKLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSB0byBhc3NpZ24gdG8gdGhlIHRyYW5zbGV0IGNsYXNzCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gY29tcGlsZShVUkwgdXJsLCBTdHJpbmcgbmFtZSkgewotICAgICAgICB0cnkgewotICAgICAgICAgICAgLy8gT3BlbiBpbnB1dCBzdHJlYW0gZnJvbSBVUkwgYW5kIHdyYXAgaW5zaWRlIElucHV0U291cmNlCi0gICAgICAgICAgICBmaW5hbCBJbnB1dFN0cmVhbSBzdHJlYW0gPSB1cmwub3BlblN0cmVhbSgpOwotICAgICAgICAgICAgZmluYWwgSW5wdXRTb3VyY2UgaW5wdXQgPSBuZXcgSW5wdXRTb3VyY2Uoc3RyZWFtKTsKLSAgICAgICAgICAgIGlucHV0LnNldFN5c3RlbUlkKHVybC50b1N0cmluZygpKTsKLSAgICAgICAgICAgIHJldHVybiBjb21waWxlKGlucHV0LCBuYW1lKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewotICAgICAgICAgICAgX3BhcnNlci5yZXBvcnRFcnJvcihDb25zdGFudHMuRkFUQUwsIG5ldyBFcnJvck1zZyhFcnJvck1zZy5KQVhQX0NPTVBJTEVfRVJSLCBlKSk7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb21waWxlcyBhbiBYU0wgc3R5bGVzaGVldCBwYXNzZWQgaW4gdGhyb3VnaCBhbiBJbnB1dFN0cmVhbQotICAgICAqIEBwYXJhbSBzdHJlYW0gQW4gSW5wdXRTdHJlYW0gdGhhdCB3aWxsIHBhc3MgaW4gdGhlIHN0eWxlc2hlZXQgY29udGVudHMKLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgdHJhbnNsZXQgY2xhc3MgdG8gZ2VuZXJhdGUKLSAgICAgKiBAcmV0dXJuICd0cnVlJyBpZiB0aGUgY29tcGlsYXRpb24gd2FzIHN1Y2Nlc3NmdWwKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBjb21waWxlKElucHV0U3RyZWFtIHN0cmVhbSwgU3RyaW5nIG5hbWUpIHsKLSAgICAgICAgZmluYWwgSW5wdXRTb3VyY2UgaW5wdXQgPSBuZXcgSW5wdXRTb3VyY2Uoc3RyZWFtKTsKLSAgICAgICAgaW5wdXQuc2V0U3lzdGVtSWQobmFtZSk7IC8vIFdlIGhhdmUgbm90aGluZyBlbHNlISEhCi0gICAgICAgIHJldHVybiBjb21waWxlKGlucHV0LCBuYW1lKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb21waWxlcyBhbiBYU0wgc3R5bGVzaGVldCBwYXNzZWQgaW4gdGhyb3VnaCBhbiBJbnB1dFN0cmVhbQotICAgICAqIEBwYXJhbSBpbnB1dCBBbiBJbnB1dFNvdXJjZSB0aGF0IHdpbGwgcGFzcyBpbiB0aGUgc3R5bGVzaGVldCBjb250ZW50cwotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSB0cmFuc2xldCBjbGFzcyB0byBnZW5lcmF0ZSAtIGNhbiBiZSBudWxsCi0gICAgICogQHJldHVybiAndHJ1ZScgaWYgdGhlIGNvbXBpbGF0aW9uIHdhcyBzdWNjZXNzZnVsCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gY29tcGlsZShJbnB1dFNvdXJjZSBpbnB1dCwgU3RyaW5nIG5hbWUpIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIC8vIFJlc2V0IGdsb2JhbHMgaW4gY2FzZSB3ZSdyZSBjYWxsZWQgYnkgY29tcGlsZShWZWN0b3Igdik7Ci0gICAgICAgICAgICByZXNldCgpOwotCi0gICAgICAgICAgICAvLyBUaGUgc3lzdGVtSWQgbWF5IG5vdCBiZSBzZXQsIHNvIHdlJ2xsIGhhdmUgdG8gY2hlY2sgdGhlIFVSTAotICAgICAgICAgICAgU3RyaW5nIHN5c3RlbUlkID0gbnVsbDsKLSAgICAgICAgICAgIGlmIChpbnB1dCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgc3lzdGVtSWQgPSBpbnB1dC5nZXRTeXN0ZW1JZCgpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBTZXQgdGhlIHRyYW5zbGV0IGNsYXNzIG5hbWUgaWYgbm90IGFscmVhZHkgc2V0Ci0gICAgICAgICAgICBpZiAoX2NsYXNzTmFtZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgaWYgKG5hbWUgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBzZXRDbGFzc05hbWUobmFtZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgaWYgKHN5c3RlbUlkICE9IG51bGwgJiYgIXN5c3RlbUlkLmVxdWFscygiIikpIHsKLSAgICAgICAgICAgICAgICAgICAgc2V0Q2xhc3NOYW1lKFV0aWwuYmFzZU5hbWUoc3lzdGVtSWQpKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyBFbnN1cmUgd2UgaGF2ZSBhIG5vbi1lbXB0eSBjbGFzcyBuYW1lIGF0IHRoaXMgcG9pbnQKLSAgICAgICAgICAgICAgICBpZiAoX2NsYXNzTmFtZSA9PSBudWxsIHx8IF9jbGFzc05hbWUubGVuZ3RoKCkgPT0gMCkgewotICAgICAgICAgICAgICAgICAgICBzZXRDbGFzc05hbWUoIkdyZWdvclNhbXNhIik7IC8vIGRlZmF1bHQgdHJhbnNsZXQgbmFtZQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gR2V0IHRoZSByb290IG5vZGUgb2YgdGhlIGFic3RyYWN0IHN5bnRheCB0cmVlCi0gICAgICAgICAgICBTeW50YXhUcmVlTm9kZSBlbGVtZW50ID0gbnVsbDsKLSAgICAgICAgICAgIGlmIChfcmVhZGVyID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBlbGVtZW50ID0gX3BhcnNlci5wYXJzZShpbnB1dCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBlbGVtZW50ID0gX3BhcnNlci5wYXJzZShfcmVhZGVyLCBpbnB1dCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIENvbXBpbGUgdGhlIHRyYW5zbGV0IC0gdGhpcyBpcyB3aGVyZSB0aGUgd29yayBpcyBkb25lIQotICAgICAgICAgICAgaWYgKCghX3BhcnNlci5lcnJvcnNGb3VuZCgpKSAmJiAoZWxlbWVudCAhPSBudWxsKSkgewotICAgICAgICAgICAgICAgIC8vIENyZWF0ZSBhIFN0eWxlc2hlZXQgZWxlbWVudCBmcm9tIHRoZSByb290IG5vZGUKLSAgICAgICAgICAgICAgICBfc3R5bGVzaGVldCA9IF9wYXJzZXIubWFrZVN0eWxlc2hlZXQoZWxlbWVudCk7Ci0gICAgICAgICAgICAgICAgX3N0eWxlc2hlZXQuc2V0U291cmNlTG9hZGVyKF9sb2FkZXIpOwotICAgICAgICAgICAgICAgIF9zdHlsZXNoZWV0LnNldFN5c3RlbUlkKHN5c3RlbUlkKTsKLSAgICAgICAgICAgICAgICBfc3R5bGVzaGVldC5zZXRQYXJlbnRTdHlsZXNoZWV0KG51bGwpOwotICAgICAgICAgICAgICAgIF9zdHlsZXNoZWV0LnNldFRlbXBsYXRlSW5saW5pbmcoX3RlbXBsYXRlSW5saW5pbmcpOwotICAgICAgICAgICAgICAgIF9wYXJzZXIuc2V0Q3VycmVudFN0eWxlc2hlZXQoX3N0eWxlc2hlZXQpOwotCi0gICAgICAgICAgICAgICAgLy8gQ3JlYXRlIEFTVCB1bmRlciB0aGUgU3R5bGVzaGVldCBlbGVtZW50IChwYXJzZSAmIHR5cGUtY2hlY2spCi0gICAgICAgICAgICAgICAgX3BhcnNlci5jcmVhdGVBU1QoX3N0eWxlc2hlZXQpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gR2VuZXJhdGUgdGhlIGJ5dGVjb2RlcyBhbmQgb3V0cHV0IHRoZSB0cmFuc2xldCBjbGFzcyhlcykKLSAgICAgICAgICAgIGlmICgoIV9wYXJzZXIuZXJyb3JzRm91bmQoKSkgJiYgKF9zdHlsZXNoZWV0ICE9IG51bGwpKSB7Ci0gICAgICAgICAgICAgICAgX3N0eWxlc2hlZXQuc2V0Q2FsbHNOb2Rlc2V0KF9jYWxsc05vZGVzZXQpOwotICAgICAgICAgICAgICAgIF9zdHlsZXNoZWV0LnNldE11bHRpRG9jdW1lbnQoX211bHRpRG9jdW1lbnQpOwotICAgICAgICAgICAgICAgIF9zdHlsZXNoZWV0LnNldEhhc0lkQ2FsbChfaGFzSWRDYWxsKTsKLQotICAgICAgICAgICAgICAgIC8vIENsYXNzIHN5bmNocm9uaXphdGlvbiBpcyBuZWVkZWQgZm9yIEJDRUwKLSAgICAgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKGdldENsYXNzKCkpIHsKLSAgICAgICAgICAgICAgICAgICAgX3N0eWxlc2hlZXQudHJhbnNsYXRlKCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgLyppZiAoX2RlYnVnKSovIGUucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgICAgICBfcGFyc2VyLnJlcG9ydEVycm9yKENvbnN0YW50cy5GQVRBTCwgbmV3IEVycm9yTXNnKEVycm9yTXNnLkpBWFBfQ09NUElMRV9FUlIsIGUpKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoRXJyb3IgZSkgewotICAgICAgICAgICAgaWYgKF9kZWJ1ZykgZS5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgICAgICAgIF9wYXJzZXIucmVwb3J0RXJyb3IoQ29uc3RhbnRzLkZBVEFMLCBuZXcgRXJyb3JNc2coRXJyb3JNc2cuSkFYUF9DT01QSUxFX0VSUiwgZSkpOwotICAgICAgICB9Ci0gICAgICAgIGZpbmFsbHkgewotICAgICAgICAgICAgX3JlYWRlciA9IG51bGw7IC8vIHJlc2V0IHRoaXMgaGVyZSB0byBiZSBzdXJlIGl0IGlzIG5vdCByZS11c2VkCi0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuICFfcGFyc2VyLmVycm9yc0ZvdW5kKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29tcGlsZXMgYSBzZXQgb2Ygc3R5bGVzaGVldHMgcG9pbnRlZCB0byBieSBhIFZlY3RvciBvZiBVUkxzCi0gICAgICogQHBhcmFtIHN0eWxlc2hlZXRzIEEgVmVjdG9yIGNvbnRhaW5pbmcgVVJMcyBwb2ludGluZyB0byB0aGUgc3R5bGVzaGVldHMKLSAgICAgKiBAcmV0dXJuICd0cnVlJyBpZiB0aGUgY29tcGlsYXRpb24gd2FzIHN1Y2Nlc3NmdWwKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBjb21waWxlKFZlY3RvciBzdHlsZXNoZWV0cykgewotICAgICAgICAvLyBHZXQgdGhlIG51bWJlciBvZiBzdHlsZXNoZWV0cyAoaWUuIFVSTHMpIGluIHRoZSB2ZWN0b3IKLSAgICAgICAgZmluYWwgaW50IGNvdW50ID0gc3R5bGVzaGVldHMuc2l6ZSgpOwotCi0gICAgICAgIC8vIFJldHVybiBzdHJhaWdodCBhd2F5IGlmIHRoZSB2ZWN0b3IgaXMgZW1wdHkKLSAgICAgICAgaWYgKGNvdW50ID09IDApIHJldHVybiB0cnVlOwotCi0gICAgICAgIC8vIFNwZWNpYWwgaGFuZGxpbmcgbmVlZGVkIGlmIHRoZSBVUkwgY291bnQgaXMgb25lLCBiZWN1YXNlIHRoZQotICAgICAgICAvLyBfY2xhc3NOYW1lIGdsb2JhbCBtdXN0IG5vdCBiZSByZXNldCBpZiBpdCB3YXMgc2V0IGV4cGxpY2l0bHkKLSAgICAgICAgaWYgKGNvdW50ID09IDEpIHsKLSAgICAgICAgICAgIGZpbmFsIE9iamVjdCB1cmwgPSBzdHlsZXNoZWV0cy5maXJzdEVsZW1lbnQoKTsKLSAgICAgICAgICAgIGlmICh1cmwgaW5zdGFuY2VvZiBVUkwpCi0gICAgICAgICAgICAgICAgcmV0dXJuIGNvbXBpbGUoKFVSTCl1cmwpOwotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIC8vIFRyYXZlcnNlIGFsbCBlbGVtZW50cyBpbiB0aGUgdmVjdG9yIGFuZCBjb21waWxlCi0gICAgICAgICAgICBmaW5hbCBFbnVtZXJhdGlvbiB1cmxzID0gc3R5bGVzaGVldHMuZWxlbWVudHMoKTsKLSAgICAgICAgICAgIHdoaWxlICh1cmxzLmhhc01vcmVFbGVtZW50cygpKSB7Ci0gICAgICAgICAgICAgICAgX2NsYXNzTmFtZSA9IG51bGw7IC8vIHJlc2V0LCBzbyB0aGF0IG5ldyBuYW1lIHdpbGwgYmUgY29tcHV0ZWQKLSAgICAgICAgICAgICAgICBmaW5hbCBPYmplY3QgdXJsID0gdXJscy5uZXh0RWxlbWVudCgpOwotICAgICAgICAgICAgICAgIGlmICh1cmwgaW5zdGFuY2VvZiBVUkwpIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKCFjb21waWxlKChVUkwpdXJsKSkgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGFuIGFycmF5IG9mIGJ5dGVjb2RlIGFycmF5cyBnZW5lcmF0ZWQgYnkgYSBjb21waWxhdGlvbi4KLSAgICAgKiBAcmV0dXJuIEpWTSBieXRlY29kZXMgdGhhdCByZXByZXNlbnQgdHJhbnNsZXQgY2xhc3MgZGVmaW5pdGlvbgotICAgICAqLwotICAgIHB1YmxpYyBieXRlW11bXSBnZXRCeXRlY29kZXMoKSB7Ci0gICAgICAgIGZpbmFsIGludCBjb3VudCA9IF9jbGFzc2VzLnNpemUoKTsKLSAgICAgICAgZmluYWwgYnl0ZVtdW10gcmVzdWx0ID0gbmV3IGJ5dGVbY291bnRdWzFdOwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvdW50OyBpKyspCi0gICAgICAgICAgICByZXN1bHRbaV0gPSAoYnl0ZVtdKV9jbGFzc2VzLmVsZW1lbnRBdChpKTsKLSAgICAgICAgcmV0dXJuIHJlc3VsdDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb21waWxlcyBhIHN0eWxlc2hlZXQgcG9pbnRlZCB0byBieSBhIFVSTC4gVGhlIHJlc3VsdCBpcyBwdXQgaW4gYQotICAgICAqIHNldCBvZiBieXRlIGFycmF5cy4gT25lIGJ5dGUgYXJyYXkgZm9yIGVhY2ggZ2VuZXJhdGVkIGNsYXNzLgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSB0cmFuc2xldCBjbGFzcyB0byBnZW5lcmF0ZQotICAgICAqIEBwYXJhbSBpbnB1dCBBbiBJbnB1dFNvdXJjZSB0aGF0IHdpbGwgcGFzcyBpbiB0aGUgc3R5bGVzaGVldCBjb250ZW50cwotICAgICAqIEBwYXJhbSBvdXRwdXRUeXBlIFRoZSBvdXRwdXQgdHlwZQotICAgICAqIEByZXR1cm4gSlZNIGJ5dGVjb2RlcyB0aGF0IHJlcHJlc2VudCB0cmFuc2xldCBjbGFzcyBkZWZpbml0aW9uCi0gICAgICovCi0gICAgcHVibGljIGJ5dGVbXVtdIGNvbXBpbGUoU3RyaW5nIG5hbWUsIElucHV0U291cmNlIGlucHV0LCBpbnQgb3V0cHV0VHlwZSkgewotICAgICAgICBfb3V0cHV0VHlwZSA9IG91dHB1dFR5cGU7Ci0gICAgICAgIGlmIChjb21waWxlKGlucHV0LCBuYW1lKSkKLSAgICAgICAgICAgIHJldHVybiBnZXRCeXRlY29kZXMoKTsKLSAgICAgICAgZWxzZQotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29tcGlsZXMgYSBzdHlsZXNoZWV0IHBvaW50ZWQgdG8gYnkgYSBVUkwuIFRoZSByZXN1bHQgaXMgcHV0IGluIGEKLSAgICAgKiBzZXQgb2YgYnl0ZSBhcnJheXMuIE9uZSBieXRlIGFycmF5IGZvciBlYWNoIGdlbmVyYXRlZCBjbGFzcy4KLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgdHJhbnNsZXQgY2xhc3MgdG8gZ2VuZXJhdGUKLSAgICAgKiBAcGFyYW0gaW5wdXQgQW4gSW5wdXRTb3VyY2UgdGhhdCB3aWxsIHBhc3MgaW4gdGhlIHN0eWxlc2hlZXQgY29udGVudHMKLSAgICAgKiBAcmV0dXJuIEpWTSBieXRlY29kZXMgdGhhdCByZXByZXNlbnQgdHJhbnNsZXQgY2xhc3MgZGVmaW5pdGlvbgotICAgICAqLwotICAgIHB1YmxpYyBieXRlW11bXSBjb21waWxlKFN0cmluZyBuYW1lLCBJbnB1dFNvdXJjZSBpbnB1dCkgewotICAgICAgICByZXR1cm4gY29tcGlsZShuYW1lLCBpbnB1dCwgQllURUFSUkFZX09VVFBVVCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSBYTUxSZWFkZXIgdG8gdXNlIGZvciBwYXJzaW5nIHRoZSBuZXh0IGlucHV0IHN0eWxlc2hlZXQKLSAgICAgKiBAcGFyYW0gcmVhZGVyIFhNTFJlYWRlciAoU0FYMiBwYXJzZXIpIHRvIHVzZQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFhNTFJlYWRlcihYTUxSZWFkZXIgcmVhZGVyKSB7Ci0gICAgICAgIF9yZWFkZXIgPSByZWFkZXI7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBYTUxSZWFkZXIgdG8gdXNlIGZvciBwYXJzaW5nIHRoZSBuZXh0IGlucHV0IHN0eWxlc2hlZXQKLSAgICAgKi8KLSAgICBwdWJsaWMgWE1MUmVhZGVyIGdldFhNTFJlYWRlcigpIHsKLSAgICAgICAgcmV0dXJuIF9yZWFkZXIgOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCBhIGxpc3Qgb2YgYWxsIGNvbXBpbGUgZXJyb3IgbWVzc2FnZXMKLSAgICAgKiBAcmV0dXJuIEEgTGlzdCBjb250YWluaW5nIGFsbCBjb21waWxlIGVycm9yIG1lc3NhZ2VzCi0gICAgICovCi0gICAgcHVibGljIEFycmF5TGlzdDxFcnJvck1zZz4gZ2V0RXJyb3JzKCkgewotICAgICAgICByZXR1cm4gX3BhcnNlci5nZXRFcnJvcnMoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgYSBsaXN0IG9mIGFsbCBjb21waWxlIHdhcm5pbmcgbWVzc2FnZXMKLSAgICAgKiBAcmV0dXJuIEEgTGlzdCBjb250YWluaW5nIGFsbCBjb21waWxlIGVycm9yIG1lc3NhZ2VzCi0gICAgICovCi0gICAgcHVibGljIEFycmF5TGlzdDxFcnJvck1zZz4gZ2V0V2FybmluZ3MoKSB7Ci0gICAgICAgIHJldHVybiBfcGFyc2VyLmdldFdhcm5pbmdzKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUHJpbnQgYWxsIGNvbXBpbGUgZXJyb3IgbWVzc2FnZXMgdG8gc3RhbmRhcmQgb3V0cHV0Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgcHJpbnRFcnJvcnMoKSB7Ci0gICAgICAgIF9wYXJzZXIucHJpbnRFcnJvcnMoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBQcmludCBhbGwgY29tcGlsZSB3YXJuaW5nIG1lc3NhZ2VzIHRvIHN0YW5kYXJkIG91dHB1dAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHByaW50V2FybmluZ3MoKSB7Ci0gICAgICAgIF9wYXJzZXIucHJpbnRXYXJuaW5ncygpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSB0aGUgWFBhdGhQYXJzZXIgd2hlbiBpdCBlbmNvdW50ZXJzIGEgY2FsbAotICAgICAqIHRvIHRoZSBkb2N1bWVudCgpIGZ1bmN0aW9uLiBBZmZlY3RzIHRoZSBET00gdXNlZCBieSB0aGUgdHJhbnNsZXQuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgc2V0TXVsdGlEb2N1bWVudChib29sZWFuIGZsYWcpIHsKLSAgICAgICAgX211bHRpRG9jdW1lbnQgPSBmbGFnOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGlzTXVsdGlEb2N1bWVudCgpIHsKLSAgICAgICAgcmV0dXJuIF9tdWx0aURvY3VtZW50OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSB0aGUgWFBhdGhQYXJzZXIgd2hlbiBpdCBlbmNvdW50ZXJzIGEgY2FsbAotICAgICAqIHRvIHRoZSBub2Rlc2V0KCkgZXh0ZW5zaW9uIGZ1bmN0aW9uLiBJbXBsaWVzIG11bHRpIGRvY3VtZW50LgotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIHNldENhbGxzTm9kZXNldChib29sZWFuIGZsYWcpIHsKLSAgICAgICAgaWYgKGZsYWcpIHNldE11bHRpRG9jdW1lbnQoZmxhZyk7Ci0gICAgICAgIF9jYWxsc05vZGVzZXQgPSBmbGFnOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGNhbGxzTm9kZXNldCgpIHsKLSAgICAgICAgcmV0dXJuIF9jYWxsc05vZGVzZXQ7Ci0gICAgfQotCi0gICAgcHJvdGVjdGVkIHZvaWQgc2V0SGFzSWRDYWxsKGJvb2xlYW4gZmxhZykgewotICAgICAgICBfaGFzSWRDYWxsID0gZmxhZzsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBoYXNJZENhbGwoKSB7Ci0gICAgICAgIHJldHVybiBfaGFzSWRDYWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldCB0aGUgY2xhc3MgbmFtZSBmb3IgdGhlIGdlbmVyYXRlZCB0cmFuc2xldC4gVGhpcyBjbGFzcyBuYW1lIGlzCi0gICAgICogb3ZlcnJpZGRlbiBpZiBtdWx0aXBsZSBzdHlsZXNoZWV0cyBhcmUgY29tcGlsZWQgaW4gb25lIGdvIHVzaW5nIHRoZQotICAgICAqIGNvbXBpbGUoVmVjdG9yIHVybHMpIG1ldGhvZC4KLSAgICAgKiBAcGFyYW0gY2xhc3NOYW1lIFRoZSBuYW1lIHRvIGFzc2lnbiB0byB0aGUgdHJhbnNsZXQgY2xhc3MKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRDbGFzc05hbWUoU3RyaW5nIGNsYXNzTmFtZSkgewotICAgICAgICBmaW5hbCBTdHJpbmcgYmFzZSAgPSBVdGlsLmJhc2VOYW1lKGNsYXNzTmFtZSk7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBub2V4dCA9IFV0aWwubm9FeHROYW1lKGJhc2UpOwotICAgICAgICBTdHJpbmcgbmFtZSAgPSBVdGlsLnRvSmF2YU5hbWUobm9leHQpOwotCi0gICAgICAgIGlmIChfcGFja2FnZU5hbWUgPT0gbnVsbCkKLSAgICAgICAgICAgIF9jbGFzc05hbWUgPSBuYW1lOwotICAgICAgICBlbHNlCi0gICAgICAgICAgICBfY2xhc3NOYW1lID0gX3BhY2thZ2VOYW1lICsgJy4nICsgbmFtZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIGNsYXNzIG5hbWUgZm9yIHRoZSBnZW5lcmF0ZWQgdHJhbnNsZXQuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRDbGFzc05hbWUoKSB7Ci0gICAgICAgIHJldHVybiBfY2xhc3NOYW1lOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbnZlcnQgZm9yIEphdmEgY2xhc3MgbmFtZSBvZiBsb2NhbCBzeXN0ZW0gZmlsZSBuYW1lLgotICAgICAqIChSZXBsYWNlICcuJyB3aXRoICcvJyBvbiBVTklYIGFuZCByZXBsYWNlICcuJyBieSAnXCcgb24gV2luZG93cy9ET1MuKQotICAgICAqLwotICAgIHByaXZhdGUgU3RyaW5nIGNsYXNzRmlsZU5hbWUoZmluYWwgU3RyaW5nIGNsYXNzTmFtZSkgewotICAgICAgICByZXR1cm4gY2xhc3NOYW1lLnJlcGxhY2UoJy4nLCBGaWxlLnNlcGFyYXRvckNoYXIpICsgIi5jbGFzcyI7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2VuZXJhdGUgYW4gb3V0cHV0IEZpbGUgb2JqZWN0IHRvIHNlbmQgdGhlIHRyYW5zbGV0IHRvCi0gICAgICovCi0gICAgcHJpdmF0ZSBGaWxlIGdldE91dHB1dEZpbGUoU3RyaW5nIGNsYXNzTmFtZSkgewotICAgICAgICBpZiAoX2Rlc3REaXIgIT0gbnVsbCkKLSAgICAgICAgICAgIHJldHVybiBuZXcgRmlsZShfZGVzdERpciwgY2xhc3NGaWxlTmFtZShjbGFzc05hbWUpKTsKLSAgICAgICAgZWxzZQotICAgICAgICAgICAgcmV0dXJuIG5ldyBGaWxlKGNsYXNzRmlsZU5hbWUoY2xhc3NOYW1lKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSBkZXN0aW5hdGlvbiBkaXJlY3RvcnkgZm9yIHRoZSB0cmFuc2xldC4KLSAgICAgKiBUaGUgY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeSB3aWxsIGJlIHVzZWQgYnkgZGVmYXVsdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBzZXREZXN0RGlyZWN0b3J5KFN0cmluZyBkc3REaXJOYW1lKSB7Ci0gICAgICAgIGZpbmFsIEZpbGUgZGlyID0gbmV3IEZpbGUoZHN0RGlyTmFtZSk7Ci0gICAgICAgIGlmIChTZWN1cml0eVN1cHBvcnQuZ2V0RmlsZUV4aXN0cyhkaXIpIHx8IGRpci5ta2RpcnMoKSkgewotICAgICAgICAgICAgX2Rlc3REaXIgPSBkaXI7Ci0gICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIF9kZXN0RGlyID0gbnVsbDsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldCBhbiBvcHRpb25hbCBwYWNrYWdlIG5hbWUgZm9yIHRoZSB0cmFuc2xldCBhbmQgYXV4aWxpYXJ5IGNsYXNzZXMKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRQYWNrYWdlTmFtZShTdHJpbmcgcGFja2FnZU5hbWUpIHsKLSAgICAgICAgX3BhY2thZ2VOYW1lID0gcGFja2FnZU5hbWU7Ci0gICAgICAgIGlmIChfY2xhc3NOYW1lICE9IG51bGwpIHNldENsYXNzTmFtZShfY2xhc3NOYW1lKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIG5hbWUgb2YgYW4gb3B0aW9uYWwgSkFSLWZpbGUgdG8gZHVtcCB0aGUgdHJhbnNsZXQgYW5kCi0gICAgICogYXV4aWxpYXJ5IGNsYXNzZXMgdG8KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRKYXJGaWxlTmFtZShTdHJpbmcgamFyRmlsZU5hbWUpIHsKLSAgICAgICAgZmluYWwgU3RyaW5nIEpBUl9FWFQgPSAiLmphciI7Ci0gICAgICAgIGlmIChqYXJGaWxlTmFtZS5lbmRzV2l0aChKQVJfRVhUKSkKLSAgICAgICAgICAgIF9qYXJGaWxlTmFtZSA9IGphckZpbGVOYW1lOwotICAgICAgICBlbHNlCi0gICAgICAgICAgICBfamFyRmlsZU5hbWUgPSBqYXJGaWxlTmFtZSArIEpBUl9FWFQ7Ci0gICAgICAgIF9vdXRwdXRUeXBlID0gSkFSX09VVFBVVDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldEphckZpbGVOYW1lKCkgewotICAgICAgICByZXR1cm4gX2phckZpbGVOYW1lOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldCB0aGUgdG9wLWxldmVsIHN0eWxlc2hlZXQKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRTdHlsZXNoZWV0KFN0eWxlc2hlZXQgc3R5bGVzaGVldCkgewotICAgICAgICBpZiAoX3N0eWxlc2hlZXQgPT0gbnVsbCkgX3N0eWxlc2hlZXQgPSBzdHlsZXNoZWV0OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIHRvcC1sZXZlbCBzdHlsZXNoZWV0Ci0gICAgICovCi0gICAgcHVibGljIFN0eWxlc2hlZXQgZ2V0U3R5bGVzaGVldCgpIHsKLSAgICAgICAgcmV0dXJuIF9zdHlsZXNoZWV0OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJlZ2lzdGVycyBhbiBhdHRyaWJ1dGUgYW5kIGdpdmVzIGl0IGEgdHlwZSBzbyB0aGF0IGl0IGNhbiBiZSBtYXBwZWQgdG8KLSAgICAgKiBET00gYXR0cmlidXRlIHR5cGVzIGF0IHJ1bi10aW1lLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgcmVnaXN0ZXJBdHRyaWJ1dGUoUU5hbWUgbmFtZSkgewotICAgICAgICBJbnRlZ2VyIGNvZGUgPSBfYXR0cmlidXRlcy5nZXQobmFtZS50b1N0cmluZygpKTsKLSAgICAgICAgaWYgKGNvZGUgPT0gbnVsbCkgewotICAgICAgICAgICAgY29kZSA9IF9uZXh0R1R5cGUrKzsKLSAgICAgICAgICAgIF9hdHRyaWJ1dGVzLnB1dChuYW1lLnRvU3RyaW5nKCksIGNvZGUpOwotICAgICAgICAgICAgZmluYWwgU3RyaW5nIHVyaSA9IG5hbWUuZ2V0TmFtZXNwYWNlKCk7Ci0gICAgICAgICAgICBmaW5hbCBTdHJpbmcgbG9jYWwgPSAiQCIrbmFtZS5nZXRMb2NhbFBhcnQoKTsKLSAgICAgICAgICAgIGlmICgodXJpICE9IG51bGwpICYmICghdXJpLmVxdWFscygiIikpKQotICAgICAgICAgICAgICAgIF9uYW1lc0luZGV4LmFkZEVsZW1lbnQodXJpKyI6Iitsb2NhbCk7Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgX25hbWVzSW5kZXguYWRkRWxlbWVudChsb2NhbCk7Ci0gICAgICAgICAgICBpZiAobmFtZS5nZXRMb2NhbFBhcnQoKS5lcXVhbHMoIioiKSkgewotICAgICAgICAgICAgICAgIHJlZ2lzdGVyTmFtZXNwYWNlKG5hbWUuZ2V0TmFtZXNwYWNlKCkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBjb2RlLmludFZhbHVlKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmVnaXN0ZXJzIGFuIGVsZW1lbnQgYW5kIGdpdmVzIGl0IGEgdHlwZSBzbyB0aGF0IGl0IGNhbiBiZSBtYXBwZWQgdG8KLSAgICAgKiBET00gZWxlbWVudCB0eXBlcyBhdCBydW4tdGltZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IHJlZ2lzdGVyRWxlbWVudChRTmFtZSBuYW1lKSB7Ci0gICAgICAgIC8vIFJlZ2lzdGVyIGVsZW1lbnQgKGZ1bGwgUU5hbWUpCi0gICAgICAgIEludGVnZXIgY29kZSA9IF9lbGVtZW50cy5nZXQobmFtZS50b1N0cmluZygpKTsKLSAgICAgICAgaWYgKGNvZGUgPT0gbnVsbCkgewotICAgICAgICAgICAgX2VsZW1lbnRzLnB1dChuYW1lLnRvU3RyaW5nKCksIGNvZGUgPSBfbmV4dEdUeXBlKyspOwotICAgICAgICAgICAgX25hbWVzSW5kZXguYWRkRWxlbWVudChuYW1lLnRvU3RyaW5nKCkpOwotICAgICAgICB9Ci0gICAgICAgIGlmIChuYW1lLmdldExvY2FsUGFydCgpLmVxdWFscygiKiIpKSB7Ci0gICAgICAgICAgICByZWdpc3Rlck5hbWVzcGFjZShuYW1lLmdldE5hbWVzcGFjZSgpKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gY29kZS5pbnRWYWx1ZSgpOwotICAgIH0KLQotICAgICAvKioKLSAgICAgICogUmVnaXN0ZXJzIGEgbmFtZXNwYWNlIHByZWZpeCBhbmQgZ2l2ZXMgaXQgYSB0eXBlIHNvIHRoYXQgaXQgY2FuIGJlIG1hcHBlZCB0bwotICAgICAgKiBET00gbmFtZXNwYWNlIHR5cGVzIGF0IHJ1bi10aW1lLgotICAgICAgKi8KLQotICAgIHB1YmxpYyBpbnQgcmVnaXN0ZXJOYW1lc3BhY2VQcmVmaXgoUU5hbWUgbmFtZSkgewotCi0gICAgSW50ZWdlciBjb2RlID0gX25hbWVzcGFjZVByZWZpeGVzLmdldChuYW1lLnRvU3RyaW5nKCkpOwotICAgIGlmIChjb2RlID09IG51bGwpIHsKLSAgICAgICAgY29kZSA9IF9uZXh0R1R5cGUrKzsKLSAgICAgICAgX25hbWVzcGFjZVByZWZpeGVzLnB1dChuYW1lLnRvU3RyaW5nKCksIGNvZGUpOwotICAgICAgICBmaW5hbCBTdHJpbmcgdXJpID0gbmFtZS5nZXROYW1lc3BhY2UoKTsKLSAgICAgICAgaWYgKCh1cmkgIT0gbnVsbCkgJiYgKCF1cmkuZXF1YWxzKCIiKSkpewotICAgICAgICAgICAgLy8gbmFtZXNwYWNlOjpleHQyOnBlZDIgd2lsbCBiZSBtYWRlIGVtcHR5IGluIFR5cGVkTmFtZXNwYWNlSXRlcmF0b3IKLSAgICAgICAgICAgIF9uYW1lc0luZGV4LmFkZEVsZW1lbnQoIj8iKTsKLSAgICAgICAgfSBlbHNlewotICAgICAgICAgICBfbmFtZXNJbmRleC5hZGRFbGVtZW50KCI/IituYW1lLmdldExvY2FsUGFydCgpKTsKLSAgICAgICAgfQotICAgIH0KLSAgICByZXR1cm4gY29kZS5pbnRWYWx1ZSgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJlZ2lzdGVycyBhIG5hbWVzcGFjZSBhbmQgZ2l2ZXMgaXQgYSB0eXBlIHNvIHRoYXQgaXQgY2FuIGJlIG1hcHBlZCB0bwotICAgICAqIERPTSBuYW1lc3BhY2UgdHlwZXMgYXQgcnVuLXRpbWUuCi0gICAgICovCi0gICAgcHVibGljIGludCByZWdpc3Rlck5hbWVzcGFjZShTdHJpbmcgbmFtZXNwYWNlVVJJKSB7Ci0gICAgICAgIEludGVnZXIgY29kZSA9IF9uYW1lc3BhY2VzLmdldChuYW1lc3BhY2VVUkkpOwotICAgICAgICBpZiAoY29kZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBjb2RlID0gX25leHROU1R5cGUrKzsKLSAgICAgICAgICAgIF9uYW1lc3BhY2VzLnB1dChuYW1lc3BhY2VVUkksY29kZSk7Ci0gICAgICAgICAgICBfbmFtZXNwYWNlSW5kZXguYWRkRWxlbWVudChuYW1lc3BhY2VVUkkpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBjb2RlLmludFZhbHVlKCk7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBuZXh0TW9kZVNlcmlhbCgpIHsKLSAgICAgICAgcmV0dXJuIF9tb2RlU2VyaWFsKys7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBuZXh0U3R5bGVzaGVldFNlcmlhbCgpIHsKLSAgICAgICAgcmV0dXJuIF9zdHlsZXNoZWV0U2VyaWFsKys7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBuZXh0U3RlcFBhdHRlcm5TZXJpYWwoKSB7Ci0gICAgICAgIHJldHVybiBfc3RlcFBhdHRlcm5TZXJpYWwrKzsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50W10gZ2V0TnVtYmVyRmllbGRJbmRleGVzKCkgewotICAgICAgICByZXR1cm4gX251bWJlckZpZWxkSW5kZXhlczsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IG5leHRIZWxwZXJDbGFzc1NlcmlhbCgpIHsKLSAgICAgICAgcmV0dXJuIF9oZWxwZXJDbGFzc1NlcmlhbCsrOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgbmV4dEF0dHJpYnV0ZVNldFNlcmlhbCgpIHsKLSAgICAgICAgcmV0dXJuIF9hdHRyaWJ1dGVTZXRTZXJpYWwrKzsKLSAgICB9Ci0KLSAgICBwdWJsaWMgVmVjdG9yIGdldE5hbWVzSW5kZXgoKSB7Ci0gICAgICAgIHJldHVybiBfbmFtZXNJbmRleDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgVmVjdG9yIGdldE5hbWVzcGFjZUluZGV4KCkgewotICAgICAgICByZXR1cm4gX25hbWVzcGFjZUluZGV4OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYSB1bmlxdWUgbmFtZSBmb3IgZXZlcnkgaGVscGVyIGNsYXNzIG5lZWRlZCB0bwotICAgICAqIGV4ZWN1dGUgYSB0cmFuc2xldC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEhlbHBlckNsYXNzTmFtZSgpIHsKLSAgICAgICAgcmV0dXJuIGdldENsYXNzTmFtZSgpICsgJyQnICsgX2hlbHBlckNsYXNzU2VyaWFsKys7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgZHVtcENsYXNzKEphdmFDbGFzcyBjbGF6eikgewotCi0gICAgICAgIGlmIChfb3V0cHV0VHlwZSA9PSBGSUxFX09VVFBVVCB8fAotICAgICAgICAgICAgX291dHB1dFR5cGUgPT0gQllURUFSUkFZX0FORF9GSUxFX09VVFBVVCkKLSAgICAgICAgewotICAgICAgICAgICAgRmlsZSBvdXRGaWxlID0gZ2V0T3V0cHV0RmlsZShjbGF6ei5nZXRDbGFzc05hbWUoKSk7Ci0gICAgICAgICAgICBTdHJpbmcgcGFyZW50RGlyID0gb3V0RmlsZS5nZXRQYXJlbnQoKTsKLSAgICAgICAgICAgIGlmIChwYXJlbnREaXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIEZpbGUgcGFyZW50RmlsZSA9IG5ldyBGaWxlKHBhcmVudERpcik7Ci0gICAgICAgICAgICAgICAgaWYgKCFTZWN1cml0eVN1cHBvcnQuZ2V0RmlsZUV4aXN0cyhwYXJlbnRGaWxlKSkKLSAgICAgICAgICAgICAgICAgICAgcGFyZW50RmlsZS5ta2RpcnMoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBzd2l0Y2ggKF9vdXRwdXRUeXBlKSB7Ci0gICAgICAgICAgICBjYXNlIEZJTEVfT1VUUFVUOgotICAgICAgICAgICAgICAgIGNsYXp6LmR1bXAoCi0gICAgICAgICAgICAgICAgICAgIG5ldyBCdWZmZXJlZE91dHB1dFN0cmVhbSgKLSAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBGaWxlT3V0cHV0U3RyZWFtKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldE91dHB1dEZpbGUoY2xhenouZ2V0Q2xhc3NOYW1lKCkpKSkpOwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgY2FzZSBKQVJfT1VUUFVUOgotICAgICAgICAgICAgICAgIF9iY2VsQ2xhc3Nlcy5hZGRFbGVtZW50KGNsYXp6KTsKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIGNhc2UgQllURUFSUkFZX09VVFBVVDoKLSAgICAgICAgICAgIGNhc2UgQllURUFSUkFZX0FORF9GSUxFX09VVFBVVDoKLSAgICAgICAgICAgIGNhc2UgQllURUFSUkFZX0FORF9KQVJfT1VUUFVUOgotICAgICAgICAgICAgY2FzZSBDTEFTU0xPQURFUl9PVVRQVVQ6Ci0gICAgICAgICAgICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIG91dCA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oMjA0OCk7Ci0gICAgICAgICAgICAgICAgY2xhenouZHVtcChvdXQpOwotICAgICAgICAgICAgICAgIF9jbGFzc2VzLmFkZEVsZW1lbnQob3V0LnRvQnl0ZUFycmF5KCkpOwotCi0gICAgICAgICAgICAgICAgaWYgKF9vdXRwdXRUeXBlID09IEJZVEVBUlJBWV9BTkRfRklMRV9PVVRQVVQpCi0gICAgICAgICAgICAgICAgICBjbGF6ei5kdW1wKG5ldyBCdWZmZXJlZE91dHB1dFN0cmVhbSgKLSAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBGaWxlT3V0cHV0U3RyZWFtKGdldE91dHB1dEZpbGUoY2xhenouZ2V0Q2xhc3NOYW1lKCkpKSkpOwotICAgICAgICAgICAgICAgIGVsc2UgaWYgKF9vdXRwdXRUeXBlID09IEJZVEVBUlJBWV9BTkRfSkFSX09VVFBVVCkKLSAgICAgICAgICAgICAgICAgIF9iY2VsQ2xhc3Nlcy5hZGRFbGVtZW50KGNsYXp6KTsKLQotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEZpbGUgc2VwYXJhdG9ycyBhcmUgY29udmVydGVkIHRvIGZvcndhcmQgc2xhc2hlcyBmb3IgWklQIGZpbGVzLgotICAgICAqLwotICAgIHByaXZhdGUgU3RyaW5nIGVudHJ5TmFtZShGaWxlIGYpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgIHJldHVybiBmLmdldE5hbWUoKS5yZXBsYWNlKEZpbGUuc2VwYXJhdG9yQ2hhciwgJy8nKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZW5lcmF0ZSBvdXRwdXQgSkFSLWZpbGUgYW5kIHBhY2thZ2VzCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgb3V0cHV0VG9KYXIoKSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgICAgICAvLyBjcmVhdGUgdGhlIG1hbmlmZXN0Ci0gICAgICAgIGZpbmFsIE1hbmlmZXN0IG1hbmlmZXN0ID0gbmV3IE1hbmlmZXN0KCk7Ci0gICAgICAgIGZpbmFsIGphdmEudXRpbC5qYXIuQXR0cmlidXRlcyBhdHJzID0gbWFuaWZlc3QuZ2V0TWFpbkF0dHJpYnV0ZXMoKTsKLSAgICAgICAgYXRycy5wdXQoamF2YS51dGlsLmphci5BdHRyaWJ1dGVzLk5hbWUuTUFOSUZFU1RfVkVSU0lPTiwiMS4yIik7Ci0KLSAgICAgICAgZmluYWwgTWFwIG1hcCA9IG1hbmlmZXN0LmdldEVudHJpZXMoKTsKLSAgICAgICAgLy8gY3JlYXRlIG1hbmlmZXN0Ci0gICAgICAgIEVudW1lcmF0aW9uIGNsYXNzZXMgPSBfYmNlbENsYXNzZXMuZWxlbWVudHMoKTsKLSAgICAgICAgZmluYWwgU3RyaW5nIG5vdyA9IChuZXcgRGF0ZSgpKS50b1N0cmluZygpOwotICAgICAgICBmaW5hbCBqYXZhLnV0aWwuamFyLkF0dHJpYnV0ZXMuTmFtZSBkYXRlQXR0ciA9Ci0gICAgICAgICAgICBuZXcgamF2YS51dGlsLmphci5BdHRyaWJ1dGVzLk5hbWUoIkRhdGUiKTsKLSAgICAgICAgd2hpbGUgKGNsYXNzZXMuaGFzTW9yZUVsZW1lbnRzKCkpIHsKLSAgICAgICAgICAgIGZpbmFsIEphdmFDbGFzcyBjbGF6eiA9IChKYXZhQ2xhc3MpY2xhc3Nlcy5uZXh0RWxlbWVudCgpOwotICAgICAgICAgICAgZmluYWwgU3RyaW5nIGNsYXNzTmFtZSA9IGNsYXp6LmdldENsYXNzTmFtZSgpLnJlcGxhY2UoJy4nLCcvJyk7Ci0gICAgICAgICAgICBmaW5hbCBqYXZhLnV0aWwuamFyLkF0dHJpYnV0ZXMgYXR0ciA9IG5ldyBqYXZhLnV0aWwuamFyLkF0dHJpYnV0ZXMoKTsKLSAgICAgICAgICAgIGF0dHIucHV0KGRhdGVBdHRyLCBub3cpOwotICAgICAgICAgICAgbWFwLnB1dChjbGFzc05hbWUrIi5jbGFzcyIsIGF0dHIpOwotICAgICAgICB9Ci0KLSAgICAgICAgZmluYWwgRmlsZSBqYXJGaWxlID0gbmV3IEZpbGUoX2Rlc3REaXIsIF9qYXJGaWxlTmFtZSk7Ci0gICAgICAgIGZpbmFsIEphck91dHB1dFN0cmVhbSBqb3MgPQotICAgICAgICAgICAgbmV3IEphck91dHB1dFN0cmVhbShuZXcgRmlsZU91dHB1dFN0cmVhbShqYXJGaWxlKSwgbWFuaWZlc3QpOwotICAgICAgICBjbGFzc2VzID0gX2JjZWxDbGFzc2VzLmVsZW1lbnRzKCk7Ci0gICAgICAgIHdoaWxlIChjbGFzc2VzLmhhc01vcmVFbGVtZW50cygpKSB7Ci0gICAgICAgICAgICBmaW5hbCBKYXZhQ2xhc3MgY2xhenogPSAoSmF2YUNsYXNzKWNsYXNzZXMubmV4dEVsZW1lbnQoKTsKLSAgICAgICAgICAgIGZpbmFsIFN0cmluZyBjbGFzc05hbWUgPSBjbGF6ei5nZXRDbGFzc05hbWUoKS5yZXBsYWNlKCcuJywnLycpOwotICAgICAgICAgICAgam9zLnB1dE5leHRFbnRyeShuZXcgSmFyRW50cnkoY2xhc3NOYW1lKyIuY2xhc3MiKSk7Ci0gICAgICAgICAgICBmaW5hbCBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gb3V0ID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgyMDQ4KTsKLSAgICAgICAgICAgIGNsYXp6LmR1bXAob3V0KTsgLy8gZHVtcCgpIGNsb3NlcyBpdCdzIG91dHB1dCBzdHJlYW0KLSAgICAgICAgICAgIG91dC53cml0ZVRvKGpvcyk7Ci0gICAgICAgIH0KLSAgICAgICAgam9zLmNsb3NlKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHVybiBkZWJ1Z2dpbmcgbWVzc2FnZXMgb24vb2ZmCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RGVidWcoYm9vbGVhbiBkZWJ1ZykgewotICAgICAgICBfZGVidWcgPSBkZWJ1ZzsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgY3VycmVudCBkZWJ1Z2dpbmcgbWVzc2FnZSBzZXR0aW5nCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZGVidWcoKSB7Ci0gICAgICAgIHJldHVybiBfZGVidWc7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBSZXRyaWV2ZSBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgY2hhcmFjdGVyIGRhdGEgdG8gYmUgc3RvcmVkCi0gICAgICogaW4gdGhlIHRyYW5zbGV0IGFzIGEgPGNvZGU+Y2hhcltdPC9jb2RlPi4gIFRoZXJlIG1heSBiZSBtb3JlIHRoYW4KLSAgICAgKiBvbmUgc3VjaCBhcnJheSByZXF1aXJlZC4KLSAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSA8Y29kZT5jaGFyW108L2NvZGU+LiAgWmVyby1iYXNlZC4KLSAgICAgKiBAcmV0dXJuIFN0cmluZyBUaGUgY2hhcmFjdGVyIGRhdGEgdG8gYmUgc3RvcmVkIGluIHRoZSBjb3JyZXNwb25kaW5nCi0gICAgICogICAgICAgICAgICAgICA8Y29kZT5jaGFyW108L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q2hhcmFjdGVyRGF0YShpbnQgaW5kZXgpIHsKLSAgICAgICAgcmV0dXJuICgoU3RyaW5nQnVmZmVyKSBtX2NoYXJhY3RlckRhdGEuZWxlbWVudEF0KGluZGV4KSkudG9TdHJpbmcoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIG51bWJlciBvZiBjaGFyW10gYXJyYXlzLCB0aHVzIGZhciwgdGhhdCB3aWxsIGJlIGNyZWF0ZWQgdG8KLSAgICAgKiBzdG9yZSBsaXRlcmFsIHRleHQgaW4gdGhlIHN0eWxlc2hlZXQuCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRDaGFyYWN0ZXJEYXRhQ291bnQoKSB7Ci0gICAgICAgIHJldHVybiAobV9jaGFyYWN0ZXJEYXRhICE9IG51bGwpID8gbV9jaGFyYWN0ZXJEYXRhLnNpemUoKSA6IDA7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQWRkIGxpdGVyYWwgdGV4dCB0byBjaGFyIGFycmF5cyB0aGF0IHdpbGwgYmUgdXNlZCB0byBzdG9yZSBjaGFyYWN0ZXIKLSAgICAgKiBkYXRhIGluIHRoZSBzdHlsZXNoZWV0LgotICAgICAqIEBwYXJhbSBuZXdEYXRhIFN0cmluZyBkYXRhIHRvIGJlIGFkZGVkIHRvIGNoYXIgYXJyYXlzLgotICAgICAqICAgICAgICAgICAgICAgIFByZS1jb25kaXRpb246ICA8Y29kZT5uZXdEYXRhLmxlbmd0aCgpICZsZTsgMjE4NDU8L2NvZGU+Ci0gICAgICogQHJldHVybiBpbnQgb2Zmc2V0IGF0IHdoaWNoIGNoYXJhY3RlciBkYXRhIHdpbGwgYmUgc3RvcmVkCi0gICAgICovCi0gICAgcHVibGljIGludCBhZGRDaGFyYWN0ZXJEYXRhKFN0cmluZyBuZXdEYXRhKSB7Ci0gICAgICAgIFN0cmluZ0J1ZmZlciBjdXJyRGF0YTsKLSAgICAgICAgaWYgKG1fY2hhcmFjdGVyRGF0YSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBtX2NoYXJhY3RlckRhdGEgPSBuZXcgVmVjdG9yKCk7Ci0gICAgICAgICAgICBjdXJyRGF0YSA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLSAgICAgICAgICAgIG1fY2hhcmFjdGVyRGF0YS5hZGRFbGVtZW50KGN1cnJEYXRhKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIGN1cnJEYXRhID0gKFN0cmluZ0J1ZmZlcikgbV9jaGFyYWN0ZXJEYXRhCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmVsZW1lbnRBdChtX2NoYXJhY3RlckRhdGEuc2l6ZSgpLTEpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gQ2hhcmFjdGVyIGRhdGEgY291bGQgdGFrZSB1cCB0byB0aHJlZS10aW1lcyBhcyBtdWNoIHNwYWNlIHdoZW4KLSAgICAgICAgLy8gd3JpdHRlbiB0byB0aGUgY2xhc3MgZmlsZSBhcyBVVEYtOC4gIFRoZSBtYXhpbXVtIHNpemUgZm9yIGEKLSAgICAgICAgLy8gY29uc3RhbnQgaXMgNjU1MzUvMy4gIElmIHdlIGV4Y2VlZCB0aGF0LAotICAgICAgICAvLyAoV2UgcmVhbGx5IHNob3VsZCB1c2Ugc29tZSAiYmluIHBhY2tpbmciLikKLSAgICAgICAgaWYgKG5ld0RhdGEubGVuZ3RoKCkgKyBjdXJyRGF0YS5sZW5ndGgoKSA+IDIxODQ1KSB7Ci0gICAgICAgICAgICBjdXJyRGF0YSA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLSAgICAgICAgICAgIG1fY2hhcmFjdGVyRGF0YS5hZGRFbGVtZW50KGN1cnJEYXRhKTsKLSAgICAgICAgfQotCi0gICAgICAgIGludCBuZXdEYXRhT2Zmc2V0ID0gY3VyckRhdGEubGVuZ3RoKCk7Ci0gICAgICAgIGN1cnJEYXRhLmFwcGVuZChuZXdEYXRhKTsKLQotICAgICAgICByZXR1cm4gbmV3RGF0YU9mZnNldDsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL1hzbEF0dHJpYnV0ZS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9Yc2xBdHRyaWJ1dGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYzk5MTI5YS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL1hzbEF0dHJpYnV0ZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjkzICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKi8KLS8qCi0gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKLSAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAotICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgotICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKLSAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCi0gKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogWHNsQXR0cmlidXRlLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTIgMTE6Mzk6MzIgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5BTE9BRDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkFTVE9SRTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkNvbnN0YW50UG9vbEdlbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkdFVEZJRUxEOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFU1RBVElDOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFVklSVFVBTDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uTGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkxvY2FsVmFyaWFibGVHZW47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5QVVNIOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkNsYXNzR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkVycm9yTXNnOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLk1ldGhvZEdlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGVDaGVja0Vycm9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlV0aWw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyLkVsZW1EZXNjOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplci5TZXJpYWxpemF0aW9uSGFuZGxlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLlhNTDExQ2hhcjsKLWltcG9ydCBqYXZhLnV0aWwuTGlzdDsKLQotLyoqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqIEBhdXRob3IgRXJ3aW4gQm9sd2lkdCA8ZWpiQGtsb21wLm9yZz4KLSAqIEBhdXRob3IgR3VubmxhdWd1ciBCcmllbSA8Z3RoYkBkaW1vbi5pcz4KLSAqLwotZmluYWwgY2xhc3MgWHNsQXR0cmlidXRlIGV4dGVuZHMgSW5zdHJ1Y3Rpb24gewotCi0gICAgcHJpdmF0ZSBTdHJpbmcgX3ByZWZpeDsKLSAgICBwcml2YXRlIEF0dHJpYnV0ZVZhbHVlIF9uYW1lOyAgICAgICAvLyBuYW1lIHRyZWF0ZWQgYXMgQVZUICg3LjEuMykKLSAgICBwcml2YXRlIEF0dHJpYnV0ZVZhbHVlVGVtcGxhdGUgX25hbWVzcGFjZSA9IG51bGw7Ci0gICAgcHJpdmF0ZSBib29sZWFuIF9pZ25vcmUgPSBmYWxzZTsKLSAgICBwcml2YXRlIGJvb2xlYW4gX2lzTGl0ZXJhbCA9IGZhbHNlOyAgLy8gc3BlY2lmaWVkIG5hbWUgaXMgbm90IEFWVAotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlCi0gICAgICovCi0gICAgcHVibGljIEF0dHJpYnV0ZVZhbHVlIGdldE5hbWUoKSB7Ci0gICAgICAgIHJldHVybiBfbmFtZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBEaXNwbGF5cyB0aGUgY29udGVudHMgb2YgdGhlIGF0dHJpYnV0ZQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGRpc3BsYXkoaW50IGluZGVudCkgewotICAgICAgICBpbmRlbnQoaW5kZW50KTsKLSAgICAgICAgVXRpbC5wcmludGxuKCJBdHRyaWJ1dGUgIiArIF9uYW1lKTsKLSAgICAgICAgZGlzcGxheUNvbnRlbnRzKGluZGVudCArIEluZGVudEluY3JlbWVudCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUGFyc2VzIHRoZSBhdHRyaWJ1dGUncyBjb250ZW50cy4gU3BlY2lhbCBjYXJlIHRha2VuIGZvciBuYW1lc3BhY2VzLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHBhcnNlQ29udGVudHMoUGFyc2VyIHBhcnNlcikgewotICAgICAgICBib29sZWFuIGdlbmVyYXRlZCA9IGZhbHNlOwotICAgICAgICBmaW5hbCBTeW1ib2xUYWJsZSBzdGFibGUgPSBwYXJzZXIuZ2V0U3ltYm9sVGFibGUoKTsKLQotICAgICAgICBTdHJpbmcgbmFtZSA9IGdldEF0dHJpYnV0ZSgibmFtZSIpOwotICAgICAgICBTdHJpbmcgbmFtZXNwYWNlID0gZ2V0QXR0cmlidXRlKCJuYW1lc3BhY2UiKTsKLSAgICAgICAgUU5hbWUgcW5hbWUgPSBwYXJzZXIuZ2V0UU5hbWUobmFtZSwgZmFsc2UpOwotICAgICAgICBmaW5hbCBTdHJpbmcgcHJlZml4ID0gcW5hbWUuZ2V0UHJlZml4KCk7Ci0KLSAgICAgICAgaWYgKCgocHJlZml4ICE9IG51bGwpICYmIChwcmVmaXguZXF1YWxzKFhNTE5TX1BSRUZJWCkpKXx8KG5hbWUuZXF1YWxzKFhNTE5TX1BSRUZJWCkpKSB7Ci0gICAgICAgICAgICByZXBvcnRFcnJvcih0aGlzLCBwYXJzZXIsIEVycm9yTXNnLklMTEVHQUxfQVRUUl9OQU1FX0VSUiwgbmFtZSk7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLQotICAgICAgICBfaXNMaXRlcmFsID0gVXRpbC5pc0xpdGVyYWwobmFtZSk7Ci0gICAgICAgIGlmIChfaXNMaXRlcmFsKSB7Ci0gICAgICAgICAgICBpZiAoIVhNTDExQ2hhci5pc1hNTDExVmFsaWRRTmFtZShuYW1lKSkgewotICAgICAgICAgICAgICAgIHJlcG9ydEVycm9yKHRoaXMsIHBhcnNlciwgRXJyb3JNc2cuSUxMRUdBTF9BVFRSX05BTUVfRVJSLCBuYW1lKTsKLSAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBJZ25vcmUgYXR0cmlidXRlIGlmIHByZWNlZWRlZCBieSBzb21lIG90aGVyIHR5cGUgb2YgZWxlbWVudAotICAgICAgICBmaW5hbCBTeW50YXhUcmVlTm9kZSBwYXJlbnQgPSBnZXRQYXJlbnQoKTsKLSAgICAgICAgZmluYWwgTGlzdDxTeW50YXhUcmVlTm9kZT4gc2libGluZ3MgPSBwYXJlbnQuZ2V0Q29udGVudHMoKTsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYXJlbnQuZWxlbWVudENvdW50KCk7IGkrKykgewotICAgICAgICAgICAgU3ludGF4VHJlZU5vZGUgaXRlbSA9IHNpYmxpbmdzLmdldChpKTsKLSAgICAgICAgICAgIGlmIChpdGVtID09IHRoaXMpIGJyZWFrOwotCi0gICAgICAgICAgICAvLyBUaGVzZSB0aHJlZSBvYmplY3RzIHJlc3VsdCBpbiBvbmUgb3IgbW9yZSBhdHRyaWJ1dGUgb3V0cHV0Ci0gICAgICAgICAgICBpZiAoaXRlbSBpbnN0YW5jZW9mIFhzbEF0dHJpYnV0ZSkgY29udGludWU7Ci0gICAgICAgICAgICBpZiAoaXRlbSBpbnN0YW5jZW9mIFVzZUF0dHJpYnV0ZVNldHMpIGNvbnRpbnVlOwotICAgICAgICAgICAgaWYgKGl0ZW0gaW5zdGFuY2VvZiBMaXRlcmFsQXR0cmlidXRlKSBjb250aW51ZTsKLSAgICAgICAgICAgIGlmIChpdGVtIGluc3RhbmNlb2YgVGV4dCkgY29udGludWU7Ci0KLSAgICAgICAgICAgIC8vIFRoZXNlIG9iamVjdHMgX2Nhbl8gcmVzdWx0IGluIG9uZSBvciBtb3JlIGF0dHJpYnV0ZQotICAgICAgICAgICAgLy8gVGhlIG91dHB1dCBoYW5kbGVyIHdpbGwgZ2VuZXJhdGUgYW4gZXJyb3IgaWYgbm90IChhdCBydW50aW1lKQotICAgICAgICAgICAgaWYgKGl0ZW0gaW5zdGFuY2VvZiBJZikgY29udGludWU7Ci0gICAgICAgICAgICBpZiAoaXRlbSBpbnN0YW5jZW9mIENob29zZSkgY29udGludWU7Ci0gICAgICAgICAgICBpZiAoaXRlbSBpbnN0YW5jZW9mIENvcHlPZikgY29udGludWU7Ci0gICAgICAgICAgICBpZiAoaXRlbSBpbnN0YW5jZW9mIFZhcmlhYmxlQmFzZSkgY29udGludWU7Ci0KLSAgICAgICAgICAgIC8vIFJlcG9ydCB3YXJuaW5nIGJ1dCBkbyBub3QgaWdub3JlIGF0dHJpYnV0ZQotICAgICAgICAgICAgcmVwb3J0V2FybmluZyh0aGlzLCBwYXJzZXIsIEVycm9yTXNnLlNUUkFZX0FUVFJJQlVURV9FUlIsIG5hbWUpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gR2V0IG5hbWVzcGFjZSBmcm9tIG5hbWVzcGFjZSBhdHRyaWJ1dGU/Ci0gICAgICAgIGlmIChuYW1lc3BhY2UgIT0gbnVsbCAmJiBuYW1lc3BhY2UgIT0gQ29uc3RhbnRzLkVNUFRZU1RSSU5HKSB7Ci0gICAgICAgICAgICBfcHJlZml4ID0gbG9va3VwUHJlZml4KG5hbWVzcGFjZSk7Ci0gICAgICAgICAgICBfbmFtZXNwYWNlID0gbmV3IEF0dHJpYnV0ZVZhbHVlVGVtcGxhdGUobmFtZXNwYWNlLCBwYXJzZXIsIHRoaXMpOwotICAgICAgICB9Ci0gICAgICAgIC8vIEdldCBuYW1lc3BhY2UgZnJvbSBwcmVmaXggaW4gbmFtZSBhdHRyaWJ1dGU/Ci0gICAgICAgIGVsc2UgaWYgKHByZWZpeCAhPSBudWxsICYmIHByZWZpeCAhPSBDb25zdGFudHMuRU1QVFlTVFJJTkcpIHsKLSAgICAgICAgICAgIF9wcmVmaXggPSBwcmVmaXg7Ci0gICAgICAgICAgICBuYW1lc3BhY2UgPSBsb29rdXBOYW1lc3BhY2UocHJlZml4KTsKLSAgICAgICAgICAgIGlmIChuYW1lc3BhY2UgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIF9uYW1lc3BhY2UgPSBuZXcgQXR0cmlidXRlVmFsdWVUZW1wbGF0ZShuYW1lc3BhY2UsIHBhcnNlciwgdGhpcyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBDb21tb24gaGFuZGxpbmcgZm9yIG5hbWVzcGFjZXM6Ci0gICAgICAgIGlmIChfbmFtZXNwYWNlICE9IG51bGwpIHsKLSAgICAgICAgICAgIC8vIEdlbmVyYXRlIHByZWZpeCBpZiB3ZSBoYXZlIG5vbmUKLSAgICAgICAgICAgIGlmIChfcHJlZml4ID09IG51bGwgfHwgX3ByZWZpeCA9PSBDb25zdGFudHMuRU1QVFlTVFJJTkcpIHsKLSAgICAgICAgICAgICAgICBpZiAocHJlZml4ICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgX3ByZWZpeCA9IHByZWZpeDsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIF9wcmVmaXggPSBzdGFibGUuZ2VuZXJhdGVOYW1lc3BhY2VQcmVmaXgoKTsKLSAgICAgICAgICAgICAgICAgICAgZ2VuZXJhdGVkID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChwcmVmaXggIT0gbnVsbCAmJiAhcHJlZml4LmVxdWFscyhfcHJlZml4KSkgewotICAgICAgICAgICAgICAgIF9wcmVmaXggPSBwcmVmaXg7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIG5hbWUgPSBfcHJlZml4ICsgIjoiICsgcW5hbWUuZ2V0TG9jYWxQYXJ0KCk7Ci0KLSAgICAgICAgICAgIC8qCi0gICAgICAgICAgICAgKiBUT0RPOiBUaGUgbmFtZXNwYWNlIFVSSSBtdXN0IGJlIHBhc3NlZCB0byB0aGUgcGFyZW50Ci0gICAgICAgICAgICAgKiBlbGVtZW50IGJ1dCB3ZSBkb24ndCB5ZXQga25vdyB3aGF0IHRoZSBhY3R1YWwgVVJJIGlzCi0gICAgICAgICAgICAgKiAoYXMgd2Ugb25seSBrbm93IGl0IGFzIGFuIGF0dHJpYnV0ZSB2YWx1ZSB0ZW1wbGF0ZSkuCi0gICAgICAgICAgICAgKi8KLSAgICAgICAgICAgIGlmICgocGFyZW50IGluc3RhbmNlb2YgTGl0ZXJhbEVsZW1lbnQpICYmICghZ2VuZXJhdGVkKSkgewotICAgICAgICAgICAgICAgICgoTGl0ZXJhbEVsZW1lbnQpcGFyZW50KS5yZWdpc3Rlck5hbWVzcGFjZShfcHJlZml4LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lc3BhY2UsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YWJsZSwgZmFsc2UpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKHBhcmVudCBpbnN0YW5jZW9mIExpdGVyYWxFbGVtZW50KSB7Ci0gICAgICAgICAgICAoKExpdGVyYWxFbGVtZW50KXBhcmVudCkuYWRkQXR0cmlidXRlKHRoaXMpOwotICAgICAgICB9Ci0KLSAgICAgICAgX25hbWUgPSBBdHRyaWJ1dGVWYWx1ZS5jcmVhdGUodGhpcywgbmFtZSwgcGFyc2VyKTsKLSAgICAgICAgcGFyc2VDaGlsZHJlbihwYXJzZXIpOwotICAgIH0KLQotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0gICAgICAgIGlmICghX2lnbm9yZSkgewotICAgICAgICAgICAgX25hbWUudHlwZUNoZWNrKHN0YWJsZSk7Ci0gICAgICAgICAgICBpZiAoX25hbWVzcGFjZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgX25hbWVzcGFjZS50eXBlQ2hlY2soc3RhYmxlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHR5cGVDaGVja0NvbnRlbnRzKHN0YWJsZSk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIFR5cGUuVm9pZDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotICAgICAgICBmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQotICAgICAgICBpZiAoX2lnbm9yZSkgcmV0dXJuOwotICAgICAgICBfaWdub3JlID0gdHJ1ZTsKLQotICAgICAgICAvLyBDb21waWxlIGNvZGUgdGhhdCBlbWl0cyBhbnkgbmVlZGVkIG5hbWVzcGFjZSBkZWNsYXJhdGlvbgotICAgICAgICBpZiAoX25hbWVzcGFjZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAvLyBwdWJsaWMgdm9pZCBhdHRyaWJ1dGUoZmluYWwgU3RyaW5nIG5hbWUsIGZpbmFsIFN0cmluZyB2YWx1ZSkKLSAgICAgICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZEhhbmRsZXIoKSk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLF9wcmVmaXgpKTsKLSAgICAgICAgICAgIF9uYW1lc3BhY2UudHJhbnNsYXRlKGNsYXNzR2VuLG1ldGhvZEdlbik7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLm5hbWVzcGFjZSgpKTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmICghX2lzTGl0ZXJhbCkgewotICAgICAgICAgICAgLy8gaWYgdGhlIHFuYW1lIGlzIGFuIEFWVCwgdGhlbiB0aGUgcW5hbWUgaGFzIHRvIGJlIGNoZWNrZWQgYXQgcnVudGltZSBpZiBpdCBpcyBhIHZhbGlkIHFuYW1lCi0gICAgICAgICAgICBMb2NhbFZhcmlhYmxlR2VuIG5hbWVWYWx1ZSA9Ci0gICAgICAgICAgICAgICAgICAgIG1ldGhvZEdlbi5hZGRMb2NhbFZhcmlhYmxlMigibmFtZVZhbHVlIiwKLSAgICAgICAgICAgICAgICAgICAgVXRpbC5nZXRKQ1JlZlR5cGUoU1RSSU5HX1NJRyksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsKTsKLQotICAgICAgICAgICAgLy8gc3RvcmUgdGhlIG5hbWUgaW50byBhIHZhcmlhYmxlIGZpcnN0IHNvIF9uYW1lLnRyYW5zbGF0ZSBvbmx5IG5lZWRzIHRvIGJlIGNhbGxlZCBvbmNlCi0gICAgICAgICAgICBfbmFtZS50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgICAgICBuYW1lVmFsdWUuc2V0U3RhcnQoaWwuYXBwZW5kKG5ldyBBU1RPUkUobmFtZVZhbHVlLmdldEluZGV4KCkpKSk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IEFMT0FEKG5hbWVWYWx1ZS5nZXRJbmRleCgpKSk7Ci0KLSAgICAgICAgICAgIC8vIGNhbGwgY2hlY2tRTmFtZSBpZiB0aGUgbmFtZSBpcyBhbiBBVlQKLSAgICAgICAgICAgIGZpbmFsIGludCBjaGVjayA9IGNwZy5hZGRNZXRob2RyZWYoQkFTSVNfTElCUkFSWV9DTEFTUywgImNoZWNrQXR0cmliUU5hbWUiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICtTVFJJTkdfU0lHCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgKyIpViIpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VTVEFUSUMoY2hlY2spKTsKLQotICAgICAgICAgICAgLy8gU2F2ZSB0aGUgY3VycmVudCBoYW5kbGVyIGJhc2Ugb24gdGhlIHN0YWNrCi0gICAgICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRIYW5kbGVyKCkpOwotICAgICAgICAgICAgaWwuYXBwZW5kKERVUCk7ICAgICAvLyBmaXJzdCBhcmcgdG8gImF0dHJpYnV0ZXMiIGNhbGwKLQotICAgICAgICAgICAgLy8gbG9hZCBuYW1lIHZhbHVlIGFnYWluCi0gICAgICAgICAgICBuYW1lVmFsdWUuc2V0RW5kKGlsLmFwcGVuZChuZXcgQUxPQUQobmFtZVZhbHVlLmdldEluZGV4KCkpKSk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAvLyBTYXZlIHRoZSBjdXJyZW50IGhhbmRsZXIgYmFzZSBvbiB0aGUgc3RhY2sKLSAgICAgICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZEhhbmRsZXIoKSk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQoRFVQKTsgICAgIC8vIGZpcnN0IGFyZyB0byAiYXR0cmlidXRlcyIgY2FsbAotCi0gICAgICAgICAgICAvLyBQdXNoIGF0dHJpYnV0ZSBuYW1lCi0gICAgICAgICAgICBfbmFtZS50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ly8gMm5kIGFyZwotCi0gICAgICAgIH0KLQotICAgICAgICAvLyBQdXNoIGF0dHJpYnV0ZSB2YWx1ZSAtIHNob3J0Y3V0IGZvciBsaXRlcmFsIHN0cmluZ3MKLSAgICAgICAgaWYgKChlbGVtZW50Q291bnQoKSA9PSAxKSAmJiAoZWxlbWVudEF0KDApIGluc3RhbmNlb2YgVGV4dCkpIHsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsICgoVGV4dCllbGVtZW50QXQoMCkpLmdldFRleHQoKSkpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgaWwuYXBwZW5kKGNsYXNzR2VuLmxvYWRUcmFuc2xldCgpKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgR0VURklFTEQoY3BnLmFkZEZpZWxkcmVmKFRSQU5TTEVUX0NMQVNTLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInN0cmluZ1ZhbHVlSGFuZGxlciIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTVFJJTkdfVkFMVUVfSEFORExFUl9TSUcpKSk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQoRFVQKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4uc3RvcmVIYW5kbGVyKCkpOwotICAgICAgICAgICAgLy8gdHJhbnNsYXRlIGNvbnRlbnRzIHdpdGggc3Vic3RpdHV0ZWQgaGFuZGxlcgotICAgICAgICAgICAgdHJhbnNsYXRlQ29udGVudHMoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgICAgICAvLyBnZXQgU3RyaW5nIG91dCBvZiB0aGUgaGFuZGxlcgotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VWSVJUVUFMKGNwZy5hZGRNZXRob2RyZWYoU1RSSU5HX1ZBTFVFX0hBTkRMRVIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZ2V0VmFsdWUiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIigpIiArIFNUUklOR19TSUcpKSk7Ci0gICAgICAgIH0KLQotICAgICAgICBTeW50YXhUcmVlTm9kZSBwYXJlbnQgPSBnZXRQYXJlbnQoKTsKLSAgICAgICAgaWYgKHBhcmVudCBpbnN0YW5jZW9mIExpdGVyYWxFbGVtZW50Ci0gICAgICAgICAgICAmJiAoKExpdGVyYWxFbGVtZW50KXBhcmVudCkuYWxsQXR0cmlidXRlc1VuaXF1ZSgpKSB7Ci0gICAgICAgICAgICBpbnQgZmxhZ3MgPSAwOwotICAgICAgICAgICAgRWxlbURlc2MgZWxlbURlc2MgPSAoKExpdGVyYWxFbGVtZW50KXBhcmVudCkuZ2V0RWxlbURlc2MoKTsKLQotICAgICAgICAgICAgLy8gU2V0IHRoZSBIVE1MIGZsYWdzCi0gICAgICAgICAgICBpZiAoZWxlbURlc2MgIT0gbnVsbCAmJiBfbmFtZSBpbnN0YW5jZW9mIFNpbXBsZUF0dHJpYnV0ZVZhbHVlKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIGF0dHJOYW1lID0gKChTaW1wbGVBdHRyaWJ1dGVWYWx1ZSlfbmFtZSkudG9TdHJpbmcoKTsKLSAgICAgICAgICAgICAgICBpZiAoZWxlbURlc2MuaXNBdHRyRmxhZ1NldChhdHRyTmFtZSwgRWxlbURlc2MuQVRUUkVNUFRZKSkgewotICAgICAgICAgICAgICAgICAgICBmbGFncyA9IGZsYWdzIHwgU2VyaWFsaXphdGlvbkhhbmRsZXIuSFRNTF9BVFRSRU1QVFk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgaWYgKGVsZW1EZXNjLmlzQXR0ckZsYWdTZXQoYXR0ck5hbWUsIEVsZW1EZXNjLkFUVFJVUkwpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZsYWdzID0gZmxhZ3MgfCBTZXJpYWxpemF0aW9uSGFuZGxlci5IVE1MX0FUVFJVUkw7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgZmxhZ3MpKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4udW5pcXVlQXR0cmlidXRlKCkpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgLy8gY2FsbCAiYXR0cmlidXRlIgotICAgICAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5hdHRyaWJ1dGUoKSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBSZXN0b3JlIG9sZCBoYW5kbGVyIGJhc2UgZnJvbSBzdGFjawotICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLnN0b3JlSGFuZGxlcigpKTsKLQotCi0KLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvWHNsRWxlbWVudC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9Yc2xFbGVtZW50LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGU5NGViYjEuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9Yc2xFbGVtZW50LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyODEgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAxNSwgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqLwotLyoKLSAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQotICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCi0gKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCi0gKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAotICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKLSAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5BTE9BRDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkFTVE9SRTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkNvbnN0YW50UG9vbEdlbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklOVk9LRVNUQVRJQzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uTGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkxvY2FsVmFyaWFibGVHZW47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5QVVNIOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkNsYXNzR2VuZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkVycm9yTXNnOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLk1ldGhvZEdlbmVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGVDaGVja0Vycm9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlV0aWw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5YTUwxMUNoYXI7Ci0KLS8qKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKi8KLWZpbmFsIGNsYXNzIFhzbEVsZW1lbnQgZXh0ZW5kcyBJbnN0cnVjdGlvbiB7Ci0KLSAgICBwcml2YXRlIFN0cmluZyAgX3ByZWZpeDsKLSAgICBwcml2YXRlIGJvb2xlYW4gX2lnbm9yZSA9IGZhbHNlOwotICAgIHByaXZhdGUgYm9vbGVhbiBfaXNMaXRlcmFsTmFtZSA9IHRydWU7Ci0gICAgcHJpdmF0ZSBBdHRyaWJ1dGVWYWx1ZVRlbXBsYXRlIF9uYW1lOwotICAgIHByaXZhdGUgQXR0cmlidXRlVmFsdWVUZW1wbGF0ZSBfbmFtZXNwYWNlOwotCi0gICAgLyoqCi0gICAgICogRGlzcGxheXMgdGhlIGNvbnRlbnRzIG9mIHRoZSBlbGVtZW50Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgZGlzcGxheShpbnQgaW5kZW50KSB7Ci0gICAgICAgIGluZGVudChpbmRlbnQpOwotICAgICAgICBVdGlsLnByaW50bG4oIkVsZW1lbnQgIiArIF9uYW1lKTsKLSAgICAgICAgZGlzcGxheUNvbnRlbnRzKGluZGVudCArIEluZGVudEluY3JlbWVudCk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgcGFyc2VDb250ZW50cyhQYXJzZXIgcGFyc2VyKSB7Ci0gICAgICAgIGZpbmFsIFN5bWJvbFRhYmxlIHN0YWJsZSA9IHBhcnNlci5nZXRTeW1ib2xUYWJsZSgpOwotCi0gICAgICAgIC8vIEhhbmRsZSB0aGUgJ25hbWUnIGF0dHJpYnV0ZQotICAgICAgICBTdHJpbmcgbmFtZSA9IGdldEF0dHJpYnV0ZSgibmFtZSIpOwotICAgICAgICBpZiAobmFtZSA9PSBFTVBUWVNUUklORykgewotICAgICAgICAgICAgRXJyb3JNc2cgbXNnID0gbmV3IEVycm9yTXNnKEVycm9yTXNnLklMTEVHQUxfRUxFTV9OQU1FX0VSUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lLCB0aGlzKTsKLSAgICAgICAgICAgIHBhcnNlci5yZXBvcnRFcnJvcihXQVJOSU5HLCBtc2cpOwotICAgICAgICAgICAgcGFyc2VDaGlsZHJlbihwYXJzZXIpOwotICAgICAgICAgICAgX2lnbm9yZSA9IHRydWU7ICAgICAvLyBJZ25vcmUgdGhlIGVsZW1lbnQgaWYgdGhlIFFOYW1lIGlzIGludmFsaWQKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIEdldCBuYW1lc3BhY2UgYXR0cmlidXRlCi0gICAgICAgIFN0cmluZyBuYW1lc3BhY2UgPSBnZXRBdHRyaWJ1dGUoIm5hbWVzcGFjZSIpOwotCi0gICAgICAgIC8vIE9wdGltaXplIGNvbXBpbGF0aW9uIHdoZW4gbmFtZSBpcyBrbm93biBhdCBjb21waWxlIHRpbWUKLSAgICAgICAgX2lzTGl0ZXJhbE5hbWUgPSBVdGlsLmlzTGl0ZXJhbChuYW1lKTsKLSAgICAgICAgaWYgKF9pc0xpdGVyYWxOYW1lKSB7Ci0gICAgICAgICAgICBpZiAoIVhNTDExQ2hhci5pc1hNTDExVmFsaWRRTmFtZShuYW1lKSkgewotICAgICAgICAgICAgICAgIEVycm9yTXNnIG1zZyA9IG5ldyBFcnJvck1zZyhFcnJvck1zZy5JTExFR0FMX0VMRU1fTkFNRV9FUlIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUsIHRoaXMpOwotICAgICAgICAgICAgICAgIHBhcnNlci5yZXBvcnRFcnJvcihXQVJOSU5HLCBtc2cpOwotICAgICAgICAgICAgICAgIHBhcnNlQ2hpbGRyZW4ocGFyc2VyKTsKLSAgICAgICAgICAgICAgICBfaWdub3JlID0gdHJ1ZTsgICAgICAgICAvLyBJZ25vcmUgdGhlIGVsZW1lbnQgaWYgdGhlIFFOYW1lIGlzIGludmFsaWQKLSAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGZpbmFsIFFOYW1lIHFuYW1lID0gcGFyc2VyLmdldFFOYW1lU2FmZShuYW1lKTsKLSAgICAgICAgICAgIFN0cmluZyBwcmVmaXggPSBxbmFtZS5nZXRQcmVmaXgoKTsKLSAgICAgICAgICAgIFN0cmluZyBsb2NhbCA9IHFuYW1lLmdldExvY2FsUGFydCgpOwotCi0gICAgICAgICAgICBpZiAocHJlZml4ID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBwcmVmaXggPSBFTVBUWVNUUklORzsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKCFoYXNBdHRyaWJ1dGUoIm5hbWVzcGFjZSIpKSB7Ci0gICAgICAgICAgICAgICAgbmFtZXNwYWNlID0gbG9va3VwTmFtZXNwYWNlKHByZWZpeCk7Ci0gICAgICAgICAgICAgICAgaWYgKG5hbWVzcGFjZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIEVycm9yTXNnIGVyciA9IG5ldyBFcnJvck1zZyhFcnJvck1zZy5OQU1FU1BBQ0VfVU5ERUZfRVJSLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJlZml4LCB0aGlzKTsKLSAgICAgICAgICAgICAgICAgICAgcGFyc2VyLnJlcG9ydEVycm9yKFdBUk5JTkcsIGVycik7Ci0gICAgICAgICAgICAgICAgICAgIHBhcnNlQ2hpbGRyZW4ocGFyc2VyKTsKLSAgICAgICAgICAgICAgICAgICAgX2lnbm9yZSA9IHRydWU7ICAgICAvLyBJZ25vcmUgdGhlIGVsZW1lbnQgaWYgcHJlZml4IGlzIHVuZGVjbGFyZWQKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBfcHJlZml4ID0gcHJlZml4OwotICAgICAgICAgICAgICAgIF9uYW1lc3BhY2UgPSBuZXcgQXR0cmlidXRlVmFsdWVUZW1wbGF0ZShuYW1lc3BhY2UsIHBhcnNlciwgdGhpcyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBpZiAocHJlZml4ID09IEVNUFRZU1RSSU5HKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChVdGlsLmlzTGl0ZXJhbChuYW1lc3BhY2UpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBwcmVmaXggPSBsb29rdXBQcmVmaXgobmFtZXNwYWNlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwcmVmaXggPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZWZpeCA9IHN0YWJsZS5nZW5lcmF0ZU5hbWVzcGFjZVByZWZpeCgpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgLy8gUHJlcGVuZCBwcmVmaXggdG8gbG9jYWwgbmFtZQotICAgICAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmdCdWZmZXIgbmV3TmFtZSA9IG5ldyBTdHJpbmdCdWZmZXIocHJlZml4KTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKHByZWZpeCAhPSBFTVBUWVNUUklORykgewotICAgICAgICAgICAgICAgICAgICAgICAgbmV3TmFtZS5hcHBlbmQoJzonKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBuYW1lID0gbmV3TmFtZS5hcHBlbmQobG9jYWwpLnRvU3RyaW5nKCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIF9wcmVmaXggPSBwcmVmaXg7Ci0gICAgICAgICAgICAgICAgX25hbWVzcGFjZSA9IG5ldyBBdHRyaWJ1dGVWYWx1ZVRlbXBsYXRlKG5hbWVzcGFjZSwgcGFyc2VyLCB0aGlzKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIF9uYW1lc3BhY2UgPSAobmFtZXNwYWNlID09IEVNUFRZU1RSSU5HKSA/IG51bGwgOgotICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBBdHRyaWJ1dGVWYWx1ZVRlbXBsYXRlKG5hbWVzcGFjZSwgcGFyc2VyLCB0aGlzKTsKLSAgICAgICAgfQotCi0gICAgICAgIF9uYW1lID0gbmV3IEF0dHJpYnV0ZVZhbHVlVGVtcGxhdGUobmFtZSwgcGFyc2VyLCB0aGlzKTsKLQotICAgICAgICBmaW5hbCBTdHJpbmcgdXNlU2V0cyA9IGdldEF0dHJpYnV0ZSgidXNlLWF0dHJpYnV0ZS1zZXRzIik7Ci0gICAgICAgIGlmICh1c2VTZXRzLmxlbmd0aCgpID4gMCkgewotICAgICAgICAgICAgaWYgKCFVdGlsLmlzVmFsaWRRTmFtZXModXNlU2V0cykpIHsKLSAgICAgICAgICAgICAgICBFcnJvck1zZyBlcnIgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuSU5WQUxJRF9RTkFNRV9FUlIsIHVzZVNldHMsIHRoaXMpOwotICAgICAgICAgICAgICAgIHBhcnNlci5yZXBvcnRFcnJvcihDb25zdGFudHMuRVJST1IsIGVycik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBzZXRGaXJzdEVsZW1lbnQobmV3IFVzZUF0dHJpYnV0ZVNldHModXNlU2V0cywgcGFyc2VyKSk7Ci0gICAgICAgIH0KLQotICAgICAgICBwYXJzZUNoaWxkcmVuKHBhcnNlcik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUnVuIHR5cGUgY2hlY2sgb24gZWxlbWVudCBuYW1lICYgY29udGVudHMKLSAgICAgKi8KLSAgICBwdWJsaWMgVHlwZSB0eXBlQ2hlY2soU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgewotICAgICAgICBpZiAoIV9pZ25vcmUpIHsKLSAgICAgICAgICAgIF9uYW1lLnR5cGVDaGVjayhzdGFibGUpOwotICAgICAgICAgICAgaWYgKF9uYW1lc3BhY2UgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIF9uYW1lc3BhY2UudHlwZUNoZWNrKHN0YWJsZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgdHlwZUNoZWNrQ29udGVudHMoc3RhYmxlKTsKLSAgICAgICAgcmV0dXJuIFR5cGUuVm9pZDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgd2hlbiB0aGUgbmFtZSBvZiB0aGUgZWxlbWVudCBpcyBrbm93biBhdCBjb21waWxlIHRpbWUuCi0gICAgICogSW4gdGhpcyBjYXNlLCB0aGVyZSBpcyBubyBuZWVkIHRvIGluc3BlY3QgdGhlIGVsZW1lbnQgbmFtZSBhdCBydW50aW1lIHRvCi0gICAgICogZGV0ZXJtaW5lIGlmIGEgcHJlZml4IGV4aXN0cywgbmVlZHMgdG8gYmUgZ2VuZXJhdGVkLCBldGMuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlTGl0ZXJhbChDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotICAgICAgICBmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQotICAgICAgICBpZiAoIV9pZ25vcmUpIHsKLSAgICAgICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZEhhbmRsZXIoKSk7Ci0gICAgICAgICAgICBfbmFtZS50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgICAgICBpbC5hcHBlbmQoRFVQMik7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLnN0YXJ0RWxlbWVudCgpKTsKLQotICAgICAgICAgICAgaWYgKF9uYW1lc3BhY2UgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZEhhbmRsZXIoKSk7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgX3ByZWZpeCkpOwotICAgICAgICAgICAgICAgIF9uYW1lc3BhY2UudHJhbnNsYXRlKGNsYXNzR2VuLG1ldGhvZEdlbik7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5uYW1lc3BhY2UoKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICB0cmFuc2xhdGVDb250ZW50cyhjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQotICAgICAgICBpZiAoIV9pZ25vcmUpIHsKLSAgICAgICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4uZW5kRWxlbWVudCgpKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEF0IHJ1bnRpbWUgdGhlIGNvbXBpbGF0aW9uIG9mIHhzbDplbGVtZW50IHJlc3VsdHMgaW4gY29kZSB0aGF0OiAoaSkKLSAgICAgKiBldmFsdWF0ZXMgdGhlIGF2dCBmb3IgdGhlIG5hbWUsIChpaSkgY2hlY2tzIGZvciBhIHByZWZpeCBpbiB0aGUgbmFtZQotICAgICAqIChpaWkpIGdlbmVyYXRlcyBhIG5ldyBwcmVmaXggYW5kIGNyZWF0ZSBhIG5ldyBxbmFtZSB3aGVuIG5lY2Vzc2FyeQotICAgICAqIChpdikgY2FsbHMgc3RhcnRFbGVtZW50KCkgb24gdGhlIGhhbmRsZXIgKHYpIGxvb2tzIHVwIGEgdXJpIGluIHRoZSBYTUwKLSAgICAgKiB3aGVuIHRoZSBwcmVmaXggaXMgbm90IGtub3duIGF0IGNvbXBpbGUgdGltZSAodmkpIGNhbGxzIG5hbWVzcGFjZSgpCi0gICAgICogb24gdGhlIGhhbmRsZXIgKHZpaSkgZXZhbHVhdGVzIHRoZSBjb250ZW50cyAodmlpaSkgY2FsbHMgZW5kRWxlbWVudCgpLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotICAgICAgICBmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQotICAgICAgICAvLyBPcHRpbWl6ZSB0cmFuc2xhdGlvbiBpZiBlbGVtZW50IG5hbWUgaXMgYSBsaXRlcmFsCi0gICAgICAgIGlmIChfaXNMaXRlcmFsTmFtZSkgewotICAgICAgICAgICAgdHJhbnNsYXRlTGl0ZXJhbChjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotCi0gICAgICAgIGlmICghX2lnbm9yZSkgewotCi0gICAgICAgICAgICAvLyBpZiB0aGUgcW5hbWUgaXMgYW4gQVZULCB0aGVuIHRoZSBxbmFtZSBoYXMgdG8gYmUgY2hlY2tlZCBhdCBydW50aW1lIGlmIGl0IGlzIGEgdmFsaWQgcW5hbWUKLSAgICAgICAgICAgIExvY2FsVmFyaWFibGVHZW4gbmFtZVZhbHVlID0KLSAgICAgICAgICAgICAgICAgICAgbWV0aG9kR2VuLmFkZExvY2FsVmFyaWFibGUyKCJuYW1lVmFsdWUiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVXRpbC5nZXRKQ1JlZlR5cGUoU1RSSU5HX1NJRyksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsKTsKLQotICAgICAgICAgICAgLy8gc3RvcmUgdGhlIG5hbWUgaW50byBhIHZhcmlhYmxlIGZpcnN0IHNvIF9uYW1lLnRyYW5zbGF0ZSBvbmx5IG5lZWRzIHRvIGJlIGNhbGxlZCBvbmNlCi0gICAgICAgICAgICBfbmFtZS50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgICAgICAgICBuYW1lVmFsdWUuc2V0U3RhcnQoaWwuYXBwZW5kKG5ldyBBU1RPUkUobmFtZVZhbHVlLmdldEluZGV4KCkpKSk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IEFMT0FEKG5hbWVWYWx1ZS5nZXRJbmRleCgpKSk7Ci0KLSAgICAgICAgICAgIC8vIGNhbGwgY2hlY2tRTmFtZSBpZiB0aGUgbmFtZSBpcyBhbiBBVlQKLSAgICAgICAgICAgIGZpbmFsIGludCBjaGVjayA9IGNwZy5hZGRNZXRob2RyZWYoQkFTSVNfTElCUkFSWV9DTEFTUywgImNoZWNrUU5hbWUiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICtTVFJJTkdfU0lHCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgKyIpViIpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VTVEFUSUMoY2hlY2spKTsKLQotICAgICAgICAgICAgLy8gUHVzaCBoYW5kbGVyIGZvciBjYWxsIHRvIGVuZEVsZW1lbnQoKQotICAgICAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkSGFuZGxlcigpKTsKLQotICAgICAgICAgICAgLy8gbG9hZCBuYW1lIHZhbHVlIGFnYWluCi0gICAgICAgICAgICBuYW1lVmFsdWUuc2V0RW5kKGlsLmFwcGVuZChuZXcgQUxPQUQobmFtZVZhbHVlLmdldEluZGV4KCkpKSk7Ci0KLSAgICAgICAgICAgIGlmIChfbmFtZXNwYWNlICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBfbmFtZXNwYWNlLnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChBQ09OU1RfTlVMTCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIFB1c2ggYWRkaXRpb25hbCBhcmd1bWVudHMKLSAgICAgICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZEhhbmRsZXIoKSk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRDdXJyZW50Tm9kZSgpKTsKLQotICAgICAgICAgICAgLy8gSW52b2tlIEJhc2lzTGlicmFyeS5zdGFydFhzbEVsZW1DaGVja1FOYW1lKCkKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFU1RBVElDKAotICAgICAgICAgICAgY3BnLmFkZE1ldGhvZHJlZihCQVNJU19MSUJSQVJZX0NMQVNTLCAic3RhcnRYc2xFbGVtZW50IiwKLSAgICAgICAgICAgICAgICAgICAgIigiICsgU1RSSU5HX1NJRwotICAgICAgICAgICAgICAgICAgICArIFNUUklOR19TSUcKLSAgICAgICAgICAgICAgICAgICAgKyBUUkFOU0xFVF9PVVRQVVRfU0lHCi0gICAgICAgICAgICAgICAgICAgICsgRE9NX0lOVEZfU0lHICsgIkkpIiArIFNUUklOR19TSUcpKSk7Ci0KLQotICAgICAgICB9Ci0KLSAgICAgICAgdHJhbnNsYXRlQ29udGVudHMoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0KLSAgICAgICAgaWYgKCFfaWdub3JlKSB7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmVuZEVsZW1lbnQoKSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBPdmVycmlkZSB0aGlzIG1ldGhvZCB0byBtYWtlIHN1cmUgdGhhdCB4c2w6YXR0cmlidXRlcyBhcmUgbm90Ci0gICAgICogY29waWVkIHRvIG91dHB1dCBpZiB0aGlzIHhzbDplbGVtZW50IGlzIHRvIGJlIGlnbm9yZWQKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVDb250ZW50cyhDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0gICAgICAgIGZpbmFsIGludCBuID0gZWxlbWVudENvdW50KCk7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKSB7Ci0gICAgICAgICAgICBmaW5hbCBTeW50YXhUcmVlTm9kZSBpdGVtID0gZ2V0Q29udGVudHMoKS5nZXQoaSk7Ci0gICAgICAgICAgICBpZiAoX2lnbm9yZSAmJiBpdGVtIGluc3RhbmNlb2YgWHNsQXR0cmlidXRlKSBjb250aW51ZTsKLSAgICAgICAgICAgIGl0ZW0udHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgICAgICB9Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL3N5bS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9zeW0uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZDY0ZGMzZi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL3N5bS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNjYgKzAsMCBAQAotCi0vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLS8vIFRoZSBmb2xsb3dpbmcgY29kZSB3YXMgZ2VuZXJhdGVkIGJ5IENVUCB2MC4xMGoKLS8vIEZyaSBGZWIgMjcgMTM6MDE6NTAgUFNUIDIwMDQKLS8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlcjsKLQotLyoqIENVUCBnZW5lcmF0ZWQgY2xhc3MgY29udGFpbmluZyBzeW1ib2wgY29uc3RhbnRzLiAqLwotcHVibGljIGNsYXNzIHN5bSB7Ci0gIC8qIHRlcm1pbmFscyAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMaXRlcmFsID0gMjY7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEdFID0gMjE7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE5BTUVTUEFDRSA9IDQ4OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTTEFTSCA9IDI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBJID0gMzU7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENPTU1FTlQgPSAzNDsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUElQQVJBTSA9IDM2OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGT0xMT1dJTkdTSUJMSU5HID0gNDc7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFUU0lHTiA9IDEyOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBEU0xBU0ggPSAxNTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTFBBUkVOID0gNzsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVhQUkVTU0lPTiA9IDUzOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJTlQgPSA1MTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ0hJTEQgPSA0MDsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUlOVVMgPSAyMzsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1RBUiA9IDk7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFU0NFTkRBTlRPUlNFTEYgPSA0NTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUlBBUkVOID0gODsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQU5EID0gMzM7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExUID0gMTg7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9SID0gMzI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENPTU1BID0gMTA7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERET1QgPSAxMzsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRElWID0gMjQ7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBMVVMgPSAyMjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRE9UID0gMzsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSUQgPSAyODsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTEUgPSAyMDsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUU5BTUUgPSAyNzsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgREVTQ0VOREFOVCA9IDQ0OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQUkVDRURJTkdTSUJMSU5HID0gMzc7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVPRiA9IDA7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGVycm9yID0gMTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0VMRiA9IDM4OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWQkFSID0gNjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTU9EID0gMjU7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFOQ0VTVE9ST1JTRUxGID0gNDM7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBSRUNFRElORyA9IDQ5OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUSA9IDE2OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQQVRURVJOID0gNTI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExCUkFDSyA9IDQ7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFQUwgPSA1MDsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQU5DRVNUT1IgPSA0MjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkJSQUNLID0gNTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRENPTE9OID0gMTQ7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERPTExBUiA9IDExOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBORSA9IDE3OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQQVJFTlQgPSAzOTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRk9MTE9XSU5HID0gNDY7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEtFWSA9IDI5OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBURVhUID0gMzA7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFUVFJJQlVURSA9IDQxOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBHVCA9IDE5OwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBOT0RFID0gMzE7Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL3V0aWwvQXR0cmlidXRlU2V0TWV0aG9kR2VuZXJhdG9yLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL3V0aWwvQXR0cmlidXRlU2V0TWV0aG9kR2VuZXJhdG9yLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDgyYWYwYjguLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci91dGlsL0F0dHJpYnV0ZVNldE1ldGhvZEdlbmVyYXRvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNzkgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogQXR0cmlidXRlU2V0TWV0aG9kR2VuZXJhdG9yLmphdmEsdiAxLjUgMjAwNS8wOS8yOCAxMzo0ODoyNCBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbDsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQUxPQUQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5BU1RPUkU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5Db25zdGFudFBvb2xHZW47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JbnN0cnVjdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uTGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlR5cGU7Ci0KLS8qKgotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBBdHRyaWJ1dGVTZXRNZXRob2RHZW5lcmF0b3IgZXh0ZW5kcyBNZXRob2RHZW5lcmF0b3IgewotCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBpbnQgQ1VSUkVOVF9JTkRFWCAgPSA0OwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBQQVJBTV9TVEFSVF9JTkRFWCA9IDU7Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSBhcmdOYW1lcyA9IG5ldyBTdHJpbmdbNF07Ci0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5UeXBlW10gYXJnVHlwZXMgPQotICAgICAgICBuZXcgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5UeXBlWzRdOwotCi0gICAgc3RhdGljIHsKLSAgICAgICAgYXJnVHlwZXNbMF0gPSBVdGlsLmdldEpDUmVmVHlwZShET01fSU5URl9TSUcpOwotICAgICAgICBhcmdUeXBlc1sxXSA9IFV0aWwuZ2V0SkNSZWZUeXBlKE5PREVfSVRFUkFUT1JfU0lHKTsKLSAgICAgICAgYXJnVHlwZXNbMl0gPSBVdGlsLmdldEpDUmVmVHlwZShUUkFOU0xFVF9PVVRQVVRfU0lHKTsKLSAgICAgICAgYXJnVHlwZXNbM10gPSBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlR5cGUuSU5UOwotICAgICAgICBhcmdOYW1lc1swXSA9IERPQ1VNRU5UX1BOQU1FOwotICAgICAgICBhcmdOYW1lc1sxXSA9IElURVJBVE9SX1BOQU1FOwotICAgICAgICBhcmdOYW1lc1syXSA9IFRSQU5TTEVUX09VVFBVVF9QTkFNRTsKLSAgICAgICAgYXJnTmFtZXNbM10gPSBOT0RFX1BOQU1FOwotICAgIH0KLQotICAgcHVibGljIEF0dHJpYnV0ZVNldE1ldGhvZEdlbmVyYXRvcihTdHJpbmcgbWV0aG9kTmFtZSwgQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4pIHsKLSAgICAgICAgc3VwZXIoY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuQ29uc3RhbnRzLkFDQ19QUklWQVRFLAotICAgICAgICAgICAgICBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlR5cGUuVk9JRCwKLSAgICAgICAgICAgICAgYXJnVHlwZXMsIGFyZ05hbWVzLCBtZXRob2ROYW1lLAotICAgICAgICAgICAgICBjbGFzc0dlbi5nZXRDbGFzc05hbWUoKSwKLSAgICAgICAgICAgICAgbmV3IEluc3RydWN0aW9uTGlzdCgpLAotICAgICAgICAgICAgICBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKSk7Ci0gICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldExvY2FsSW5kZXgoU3RyaW5nIG5hbWUpIHsKLSAgICAgICAgaWYgKG5hbWUuZXF1YWxzKCJjdXJyZW50IikpIHsKLSAgICAgICAgICAgIHJldHVybiBDVVJSRU5UX0lOREVYOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBzdXBlci5nZXRMb2NhbEluZGV4KG5hbWUpOwotICAgIH0KLQotICAgIHB1YmxpYyBJbnN0cnVjdGlvbiBsb2FkUGFyYW1ldGVyKGludCBpbmRleCkgewotICAgICAgICByZXR1cm4gbmV3IEFMT0FEKGluZGV4ICsgUEFSQU1fU1RBUlRfSU5ERVgpOwotICAgIH0KLQotICAgIHB1YmxpYyBJbnN0cnVjdGlvbiBzdG9yZVBhcmFtZXRlcihpbnQgaW5kZXgpIHsKLSAgICAgICAgcmV0dXJuIG5ldyBBU1RPUkUoaW5kZXggKyBQQVJBTV9TVEFSVF9JTkRFWCk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci91dGlsL0Jvb2xlYW5UeXBlLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL3V0aWwvQm9vbGVhblR5cGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMWZlY2E4OS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL3V0aWwvQm9vbGVhblR5cGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIyNSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBCb29sZWFuVHlwZS5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzA1IDExOjAzOjM3IHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5CcmFuY2hIYW5kbGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5CcmFuY2hJbnN0cnVjdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkNIRUNLQ0FTVDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkNvbnN0YW50UG9vbEdlbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkdPVE87Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JRkVROwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSUZHRTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklGR1Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JRkxFOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSUZMVDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklGX0lDTVBHRTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklGX0lDTVBHVDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklGX0lDTVBMRTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklGX0lDTVBMVDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklMT0FEOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFU1BFQ0lBTDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklOVk9LRVZJUlRVQUw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JU1RPUkU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JbnN0cnVjdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uTGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLk5FVzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlBVU0g7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLkNvbnN0YW50czsKLQotLyoqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBCb29sZWFuVHlwZSBleHRlbmRzIFR5cGUgewotICAgIHByb3RlY3RlZCBCb29sZWFuVHlwZSgpIHt9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgICAgICByZXR1cm4gImJvb2xlYW4iOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGlkZW50aWNhbFRvKFR5cGUgb3RoZXIpIHsKLSAgICAgICAgcmV0dXJuIHRoaXMgPT0gb3RoZXI7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyB0b1NpZ25hdHVyZSgpIHsKLSAgICAgICAgcmV0dXJuICJaIjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBpc1NpbXBsZSgpIHsKLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotCi0gICAgcHVibGljIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuVHlwZSB0b0pDVHlwZSgpIHsKLSAgICAgICAgcmV0dXJuIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuVHlwZS5CT09MRUFOOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZXMgYSByZWFsIGludG8gYW4gb2JqZWN0IG9mIGludGVybmFsIHR5cGUgPGNvZGU+dHlwZTwvY29kZT4uIFRoZQotICAgICAqIHRyYW5zbGF0aW9uIHRvIGludCBpcyB1bmRlZmluZWQgc2luY2UgYm9vbGVhbnMgYXJlIGFsd2F5cyBjb252ZXJ0ZWQgdG8KLSAgICAgKiByZWFscyBpbiBhcml0aG1ldGljIGV4cHJlc3Npb25zLgotICAgICAqCi0gICAgICogQHNlZSAgICAgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZSN0cmFuc2xhdGVUbwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZVRvKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFR5cGUgdHlwZSkgewotICAgICAgICBpZiAodHlwZSA9PSBUeXBlLlN0cmluZykgewotICAgICAgICAgICAgdHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgKFN0cmluZ1R5cGUpIHR5cGUpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKHR5cGUgPT0gVHlwZS5SZWFsKSB7Ci0gICAgICAgICAgICB0cmFuc2xhdGVUbyhjbGFzc0dlbiwgbWV0aG9kR2VuLCAoUmVhbFR5cGUpIHR5cGUpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKHR5cGUgPT0gVHlwZS5SZWZlcmVuY2UpIHsKLSAgICAgICAgICAgIHRyYW5zbGF0ZVRvKGNsYXNzR2VuLCBtZXRob2RHZW4sIChSZWZlcmVuY2VUeXBlKSB0eXBlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIEVycm9yTXNnIGVyciA9IG5ldyBFcnJvck1zZyhFcnJvck1zZy5EQVRBX0NPTlZFUlNJT05fRVJSLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvU3RyaW5nKCksIHR5cGUudG9TdHJpbmcoKSk7Ci0gICAgICAgICAgICBjbGFzc0dlbi5nZXRQYXJzZXIoKS5yZXBvcnRFcnJvcihDb25zdGFudHMuRkFUQUwsIGVycik7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBFeHBlY3RzIGEgYm9vbGVhbiBvbiB0aGUgc3RhY2sgYW5kIHB1c2hlcyBhIHN0cmluZy4gSWYgdGhlIHZhbHVlIG9uIHRoZQotICAgICAqIHN0YWNrIGlzIHplcm8sIHRoZW4gdGhlIHN0cmluZyAnZmFsc2UnIGlzIHB1c2hlZC4gT3RoZXJ3aXNlLCB0aGUgc3RyaW5nCi0gICAgICogJ3RydWUnIGlzIHB1c2hlZC4KLSAgICAgKgotICAgICAqIEBzZWUgICAgIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGUjdHJhbnNsYXRlVG8KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVUbyhDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmdUeXBlIHR5cGUpIHsKLSAgICAgICAgZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0gICAgICAgIGZpbmFsIEJyYW5jaEhhbmRsZSBmYWxzZWMgPSBpbC5hcHBlbmQobmV3IElGRVEobnVsbCkpOwotICAgICAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCAidHJ1ZSIpKTsKLSAgICAgICAgZmluYWwgQnJhbmNoSGFuZGxlIHRydWVjID0gaWwuYXBwZW5kKG5ldyBHT1RPKG51bGwpKTsKLSAgICAgICAgZmFsc2VjLnNldFRhcmdldChpbC5hcHBlbmQobmV3IFBVU0goY3BnLCAiZmFsc2UiKSkpOwotICAgICAgICB0cnVlYy5zZXRUYXJnZXQoaWwuYXBwZW5kKE5PUCkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEV4cGVjdHMgYSBib29sZWFuIG9uIHRoZSBzdGFjayBhbmQgcHVzaGVzIGEgcmVhbC4gVGhlIHZhbHVlICJ0cnVlIiBpcwotICAgICAqIGNvbnZlcnRlZCB0byAxLjAgYW5kIHRoZSB2YWx1ZSAiZmFsc2UiIHRvIDAuMC4KLSAgICAgKgotICAgICAqIEBzZWUgICAgIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGUjdHJhbnNsYXRlVG8KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVUbyhDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZWFsVHlwZSB0eXBlKSB7Ci0gICAgICAgIG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKS5hcHBlbmQoSTJEKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBFeHBlY3RzIGEgYm9vbGVhbiBvbiB0aGUgc3RhY2sgYW5kIHB1c2hlcyBhIGJveGVkIGJvb2xlYW4uCi0gICAgICogQm94ZWQgYm9vbGVhbnMgYXJlIHJlcHJlc2VudGVkIGJ5IGFuIGluc3RhbmNlIG9mCi0gICAgICogPGNvZGU+amF2YS5sYW5nLkJvb2xlYW48L2NvZGU+LgotICAgICAqCi0gICAgICogQHNlZSAgICAgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZSN0cmFuc2xhdGVUbwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZVRvKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlZmVyZW5jZVR5cGUgdHlwZSkgewotICAgICAgICBmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBORVcoY3BnLmFkZENsYXNzKEJPT0xFQU5fQ0xBU1MpKSk7Ci0gICAgICAgIGlsLmFwcGVuZChEVVBfWDEpOwotICAgICAgICBpbC5hcHBlbmQoU1dBUCk7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFU1BFQ0lBTChjcGcuYWRkTWV0aG9kcmVmKEJPT0xFQU5fQ0xBU1MsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI8aW5pdD4iLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKFopViIpKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhbnNsYXRlcyBhbiBpbnRlcm5hbCBib29sZWFuIGludG8gYW4gZXh0ZXJuYWwgKEphdmEpIGJvb2xlYW4uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlVG8oQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2xhc3MgY2xhenopIHsKLSAgICAgICAgaWYgKGNsYXp6ID09IGphdmEubGFuZy5Cb29sZWFuLlRZUEUpIHsKLSAgICAgICAgICAgIG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKS5hcHBlbmQoTk9QKTsKLSAgICAgICAgfQotICAgICAgICAvLyBJcyBCb29sZWFuIDw6IGNsYXp6PyBJLmUuIGNsYXp6IGluIHsgQm9vbGVhbiwgT2JqZWN0IH0KLSAgICAgICAgZWxzZSBpZiAoY2xhenouaXNBc3NpZ25hYmxlRnJvbShqYXZhLmxhbmcuQm9vbGVhbi5jbGFzcykpIHsKLSAgICAgICAgICAgIHRyYW5zbGF0ZVRvKGNsYXNzR2VuLCBtZXRob2RHZW4sIFR5cGUuUmVmZXJlbmNlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIEVycm9yTXNnIGVyciA9IG5ldyBFcnJvck1zZyhFcnJvck1zZy5EQVRBX0NPTlZFUlNJT05fRVJSLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvU3RyaW5nKCksIGNsYXp6LmdldE5hbWUoKSk7Ci0gICAgICAgICAgICBjbGFzc0dlbi5nZXRQYXJzZXIoKS5yZXBvcnRFcnJvcihDb25zdGFudHMuRkFUQUwsIGVycik7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGVzIGFuIGV4dGVybmFsIChKYXZhKSBib29sZWFuIGludG8gaW50ZXJuYWwgYm9vbGVhbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVGcm9tKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2xhc3MgY2xhenopIHsKLSAgICAgICAgdHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgY2xhenopOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZXMgYW4gb2JqZWN0IG9mIHRoaXMgdHlwZSB0byBpdHMgYm94ZWQgcmVwcmVzZW50YXRpb24uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlQm94KENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0gICAgICAgIHRyYW5zbGF0ZVRvKGNsYXNzR2VuLCBtZXRob2RHZW4sIFR5cGUuUmVmZXJlbmNlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGVzIGFuIG9iamVjdCBvZiB0aGlzIHR5cGUgdG8gaXRzIHVuYm94ZWQgcmVwcmVzZW50YXRpb24uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlVW5Cb3goQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotICAgICAgICBmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBDSEVDS0NBU1QoY3BnLmFkZENsYXNzKEJPT0xFQU5fQ0xBU1MpKSk7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChjcGcuYWRkTWV0aG9kcmVmKEJPT0xFQU5fQ0xBU1MsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJPT0xFQU5fVkFMVUUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJPT0xFQU5fVkFMVUVfU0lHKSkpOwotICAgIH0KLQotICAgIHB1YmxpYyBJbnN0cnVjdGlvbiBMT0FEKGludCBzbG90KSB7Ci0gICAgICAgIHJldHVybiBuZXcgSUxPQUQoc2xvdCk7Ci0gICAgfQotCi0gICAgcHVibGljIEluc3RydWN0aW9uIFNUT1JFKGludCBzbG90KSB7Ci0gICAgICAgIHJldHVybiBuZXcgSVNUT1JFKHNsb3QpOwotICAgIH0KLQotICAgIHB1YmxpYyBCcmFuY2hJbnN0cnVjdGlvbiBHVChib29sZWFuIHRvemVybykgewotICAgICAgICByZXR1cm4gdG96ZXJvID8gKEJyYW5jaEluc3RydWN0aW9uKSBuZXcgSUZHVChudWxsKSA6Ci0gICAgICAgICAgICAoQnJhbmNoSW5zdHJ1Y3Rpb24pIG5ldyBJRl9JQ01QR1QobnVsbCk7Ci0gICAgfQotCi0gICAgcHVibGljIEJyYW5jaEluc3RydWN0aW9uIEdFKGJvb2xlYW4gdG96ZXJvKSB7Ci0gICAgICAgIHJldHVybiB0b3plcm8gPyAoQnJhbmNoSW5zdHJ1Y3Rpb24pIG5ldyBJRkdFKG51bGwpIDoKLSAgICAgICAgICAgIChCcmFuY2hJbnN0cnVjdGlvbikgbmV3IElGX0lDTVBHRShudWxsKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgQnJhbmNoSW5zdHJ1Y3Rpb24gTFQoYm9vbGVhbiB0b3plcm8pIHsKLSAgICAgICAgcmV0dXJuIHRvemVybyA/IChCcmFuY2hJbnN0cnVjdGlvbikgbmV3IElGTFQobnVsbCkgOgotICAgICAgICAgICAgKEJyYW5jaEluc3RydWN0aW9uKSBuZXcgSUZfSUNNUExUKG51bGwpOwotICAgIH0KLQotICAgIHB1YmxpYyBCcmFuY2hJbnN0cnVjdGlvbiBMRShib29sZWFuIHRvemVybykgewotICAgICAgICByZXR1cm4gdG96ZXJvID8gKEJyYW5jaEluc3RydWN0aW9uKSBuZXcgSUZMRShudWxsKSA6Ci0gICAgICAgICAgICAoQnJhbmNoSW5zdHJ1Y3Rpb24pIG5ldyBJRl9JQ01QTEUobnVsbCk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci91dGlsL0NsYXNzR2VuZXJhdG9yLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL3V0aWwvQ2xhc3NHZW5lcmF0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZDc0NzA3NS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL3V0aWwvQ2xhc3NHZW5lcmF0b3IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE0NCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBDbGFzc0dlbmVyYXRvci5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzA1IDExOjA3OjA5IHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuY2xhc3NmaWxlLk1ldGhvZDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkFMT0FEOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQ2xhc3NHZW47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JbnN0cnVjdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIuQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci5QYXJzZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLlN0eWxlc2hlZXQ7Ci0KLS8qKgotICogVGhlIGNsYXNzIHRoYXQgaW1wbGVtZW50cyBhbnkgY2xhc3MgdGhhdCBpbmhlcml0cyBmcm9tCi0gKiA8dHQ+QWJzdHJhY3RUcmFuc2xldDwvdHQ+LCBpLmUuIGFueSB0cmFuc2xldC4gTWV0aG9kcyBpbiB0aGlzCi0gKiBjbGFzcyBtYXkgYmUgb2YgdGhlIGZvbGxvd2luZyBraW5kczoKLSAqCi0gKiAxLiBNYWluIG1ldGhvZDogYXBwbHlUZW1wbGF0ZXMsIGltcGxlbWVudGVkIGJ5IGludGFuY2VzIG9mCi0gKiA8dHQ+TWV0aG9kR2VuZXJhdG9yPC90dD4uCi0gKgotICogMi4gTmFtZWQgbWV0aG9kczogZm9yIG5hbWVkIHRlbXBsYXRlcywgaW1wbGVtZW50ZWQgYnkgaW5zdGFuY2VzCi0gKiBvZiA8dHQ+TmFtZWRNZXRob2RHZW5lcmF0b3I8L3R0Pi4KLSAqCi0gKiAzLiBSdCBtZXRob2RzOiBmb3IgcmVzdWx0IHRyZWUgZnJhZ21lbnRzLCBpbXBsZW1lbnRlZCBieQotICogaW5zdGFuY2VzIG9mIDx0dD5SdE1ldGhvZEdlbmVyYXRvcjwvdHQ+LgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICovCi1wdWJsaWMgY2xhc3MgQ2xhc3NHZW5lcmF0b3IgZXh0ZW5kcyBDbGFzc0dlbiB7Ci0gICAgcHJvdGVjdGVkIGZpbmFsIHN0YXRpYyBpbnQgVFJBTlNMRVRfSU5ERVggPSAwOwotICAgIHByb3RlY3RlZCBzdGF0aWMgaW50IElOVkFMSURfSU5ERVggID0gLTE7Ci0KLSAgICBwcml2YXRlIFN0eWxlc2hlZXQgX3N0eWxlc2hlZXQ7Ci0gICAgcHJpdmF0ZSBmaW5hbCBQYXJzZXIgX3BhcnNlcjsgICAgICAgICAgICAgICAvLyAtLT4gY2FuIGJlIG1vdmVkIHRvIFhTTFQKLSAgICAvLyBhICBzaW5nbGUgaW5zdGFuY2UgY2FjaGVkIGhlcmUKLSAgICBwcml2YXRlIGZpbmFsIEluc3RydWN0aW9uIF9hbG9hZFRyYW5zbGV0OwotICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIF9kb21DbGFzczsKLSAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBfZG9tQ2xhc3NTaWc7Ci0gICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgX2FwcGx5VGVtcGxhdGVzU2lnOwotICAgICAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBfYXBwbHlUZW1wbGF0ZXNTaWdGb3JJbXBvcnQ7Ci0KLSAgICBwdWJsaWMgQ2xhc3NHZW5lcmF0b3IoU3RyaW5nIGNsYXNzX25hbWUsIFN0cmluZyBzdXBlcl9jbGFzc19uYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgZmlsZV9uYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgYWNjZXNzX2ZsYWdzLCBTdHJpbmdbXSBpbnRlcmZhY2VzLAotICAgICAgICAgICAgICAgICAgICAgICAgICBTdHlsZXNoZWV0IHN0eWxlc2hlZXQpIHsKLSAgICAgICAgc3VwZXIoY2xhc3NfbmFtZSwgc3VwZXJfY2xhc3NfbmFtZSwgZmlsZV9uYW1lLAotICAgICAgICAgICAgICBhY2Nlc3NfZmxhZ3MsIGludGVyZmFjZXMpOwotICAgICAgICBfc3R5bGVzaGVldCA9IHN0eWxlc2hlZXQ7Ci0gICAgICAgIF9wYXJzZXIgPSBzdHlsZXNoZWV0LmdldFBhcnNlcigpOwotICAgICAgICBfYWxvYWRUcmFuc2xldCA9IG5ldyBBTE9BRChUUkFOU0xFVF9JTkRFWCk7Ci0KLSAgICAgICAgaWYgKHN0eWxlc2hlZXQuaXNNdWx0aURvY3VtZW50KCkpIHsKLSAgICAgICAgICAgIF9kb21DbGFzcyA9ICJjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuZG9tLk11bHRpRE9NIjsKLSAgICAgICAgICAgIF9kb21DbGFzc1NpZyA9ICJMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2RvbS9NdWx0aURPTTsiOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgX2RvbUNsYXNzID0gImNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5kb20uRE9NQWRhcHRlciI7Ci0gICAgICAgICAgICBfZG9tQ2xhc3NTaWcgPSAiTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vRE9NQWRhcHRlcjsiOwotICAgICAgICB9Ci0gICAgICAgIF9hcHBseVRlbXBsYXRlc1NpZyA9ICIoIgotICAgICAgICAgICAgKyBDb25zdGFudHMuRE9NX0lOVEZfU0lHCi0gICAgICAgICAgICArIENvbnN0YW50cy5OT0RFX0lURVJBVE9SX1NJRwotICAgICAgICAgICAgKyBDb25zdGFudHMuVFJBTlNMRVRfT1VUUFVUX1NJRwotICAgICAgICAgICAgKyAiKVYiOwotCi0gICAgX2FwcGx5VGVtcGxhdGVzU2lnRm9ySW1wb3J0ID0gIigiCi0gICAgICAgICsgQ29uc3RhbnRzLkRPTV9JTlRGX1NJRwotICAgICAgICArIENvbnN0YW50cy5OT0RFX0lURVJBVE9SX1NJRwotICAgICAgICArIENvbnN0YW50cy5UUkFOU0xFVF9PVVRQVVRfU0lHCi0gICAgICAgICsgQ29uc3RhbnRzLk5PREVfRklFTERfU0lHCi0gICAgICAgICsgIilWIjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgZmluYWwgUGFyc2VyIGdldFBhcnNlcigpIHsKLSAgICAgICAgcmV0dXJuIF9wYXJzZXI7Ci0gICAgfQotCi0gICAgcHVibGljIGZpbmFsIFN0eWxlc2hlZXQgZ2V0U3R5bGVzaGVldCgpIHsKLSAgICAgICAgcmV0dXJuIF9zdHlsZXNoZWV0OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFByZXRlbmQgdGhpcyBpcyB0aGUgc3R5bGVzaGVldCBjbGFzcy4gVXNlZnVsIHdoZW4gY29tcGlsaW5nCi0gICAgICogcmVmZXJlbmNlcyB0byBnbG9iYWwgdmFyaWFibGVzIGluc2lkZSBhIHByZWRpY2F0ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgZmluYWwgU3RyaW5nIGdldENsYXNzTmFtZSgpIHsKLSAgICAgICAgcmV0dXJuIF9zdHlsZXNoZWV0LmdldENsYXNzTmFtZSgpOwotICAgIH0KLQotICAgIHB1YmxpYyBJbnN0cnVjdGlvbiBsb2FkVHJhbnNsZXQoKSB7Ci0gICAgICAgIHJldHVybiBfYWxvYWRUcmFuc2xldDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgZmluYWwgU3RyaW5nIGdldERPTUNsYXNzKCkgewotICAgICAgICByZXR1cm4gX2RvbUNsYXNzOwotICAgIH0KLQotICAgIHB1YmxpYyBmaW5hbCBTdHJpbmcgZ2V0RE9NQ2xhc3NTaWcoKSB7Ci0gICAgICAgIHJldHVybiBfZG9tQ2xhc3NTaWc7Ci0gICAgfQotCi0gICAgcHVibGljIGZpbmFsIFN0cmluZyBnZXRBcHBseVRlbXBsYXRlc1NpZygpIHsKLSAgICAgICAgcmV0dXJuIF9hcHBseVRlbXBsYXRlc1NpZzsKLSAgICB9Ci0KLSAgICBwdWJsaWMgZmluYWwgU3RyaW5nIGdldEFwcGx5VGVtcGxhdGVzU2lnRm9ySW1wb3J0KCkgewotICAgIHJldHVybiBfYXBwbHlUZW1wbGF0ZXNTaWdGb3JJbXBvcnQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyA8dHQ+dHJ1ZTwvdHQ+IG9yIDx0dD5mYWxzZTwvdHQ+IGRlcGVuZGluZyBvbiB3aGV0aGVyCi0gICAgICogdGhpcyBjbGFzcyBpbmhlcml0cyBmcm9tIDx0dD5BYnN0cmFjdFRyYW5zbGV0PC90dD4gb3Igbm90LgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzRXh0ZXJuYWwoKSB7Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0gICAgcHVibGljIHZvaWQgYWRkTWV0aG9kKE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLSAgICAgICAgTWV0aG9kW10gbWV0aG9kc1RvQWRkID0gbWV0aG9kR2VuLmdldEdlbmVyYXRlZE1ldGhvZHModGhpcyk7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbWV0aG9kc1RvQWRkLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICBhZGRNZXRob2QobWV0aG9kc1RvQWRkW2ldKTsKLX0KLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL3V0aWwvQ29tcGFyZUdlbmVyYXRvci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci91dGlsL0NvbXBhcmVHZW5lcmF0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYmI0MGRjMS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL3V0aWwvQ29tcGFyZUdlbmVyYXRvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTIwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IENvbXBhcmVHZW5lcmF0b3IuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8wNSAxMTowODowMiBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbDsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQUNPTlNUX05VTEw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5BTE9BRDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkFTVE9SRTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkNvbnN0YW50UG9vbEdlbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklMT0FEOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSVNUT1JFOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW5zdHJ1Y3Rpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JbnN0cnVjdGlvbkxpc3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5Mb2NhbFZhcmlhYmxlR2VuOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuVHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIuQ29uc3RhbnRzOwotCi0vKioKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIENvbXBhcmVHZW5lcmF0b3IgZXh0ZW5kcyBNZXRob2RHZW5lcmF0b3IgewotCi0gICAgcHJpdmF0ZSBzdGF0aWMgaW50IERPTV9JTkRFWCAgICAgID0gMTsKLSAgICBwcml2YXRlIHN0YXRpYyBpbnQgQ1VSUkVOVF9JTkRFWCAgPSAyOwotICAgIHByaXZhdGUgc3RhdGljIGludCBMRVZFTF9JTkRFWCAgICA9IDM7Ci0gICAgcHJpdmF0ZSBzdGF0aWMgaW50IFRSQU5TTEVUX0lOREVYID0gNDsKLSAgICBwcml2YXRlIHN0YXRpYyBpbnQgTEFTVF9JTkRFWCAgICAgPSA1OwotICAgIHByaXZhdGUgaW50IElURVJBVE9SX0lOREVYID0gNjsKLQotICAgIHByaXZhdGUgZmluYWwgSW5zdHJ1Y3Rpb24gX2lsb2FkQ3VycmVudDsKLSAgICBwcml2YXRlIGZpbmFsIEluc3RydWN0aW9uIF9pc3RvcmVDdXJyZW50OwotICAgIHByaXZhdGUgZmluYWwgSW5zdHJ1Y3Rpb24gX2Fsb2FkRG9tOwotICAgIHByaXZhdGUgZmluYWwgSW5zdHJ1Y3Rpb24gX2lsb2FkTGFzdDsKLSAgICBwcml2YXRlIGZpbmFsIEluc3RydWN0aW9uIF9hbG9hZEl0ZXJhdG9yOwotICAgIHByaXZhdGUgZmluYWwgSW5zdHJ1Y3Rpb24gX2FzdG9yZUl0ZXJhdG9yOwotCi0gICAgcHVibGljIENvbXBhcmVHZW5lcmF0b3IoaW50IGFjY2Vzc19mbGFncywgVHlwZSByZXR1cm5fdHlwZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlW10gYXJnX3R5cGVzLCBTdHJpbmdbXSBhcmdfbmFtZXMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG1ldGhvZF9uYW1lLCBTdHJpbmcgY2xhc3NfbmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbnN0cnVjdGlvbkxpc3QgaWwsIENvbnN0YW50UG9vbEdlbiBjcCkgewotICAgICAgICBzdXBlcihhY2Nlc3NfZmxhZ3MsIHJldHVybl90eXBlLCBhcmdfdHlwZXMsIGFyZ19uYW1lcywgbWV0aG9kX25hbWUsCi0gICAgICAgICAgICAgIGNsYXNzX25hbWUsIGlsLCBjcCk7Ci0KLSAgICAgICAgX2lsb2FkQ3VycmVudCA9IG5ldyBJTE9BRChDVVJSRU5UX0lOREVYKTsKLSAgICAgICAgX2lzdG9yZUN1cnJlbnQgPSBuZXcgSVNUT1JFKENVUlJFTlRfSU5ERVgpOwotICAgICAgICBfYWxvYWREb20gPSBuZXcgQUxPQUQoRE9NX0lOREVYKTsKLSAgICAgICAgX2lsb2FkTGFzdCA9IG5ldyBJTE9BRChMQVNUX0lOREVYKTsKLQotICAgICAgICBMb2NhbFZhcmlhYmxlR2VuIGl0ZXJhdG9yID0KLSAgICAgICAgICAgIGFkZExvY2FsVmFyaWFibGUoIml0ZXJhdG9yIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVXRpbC5nZXRKQ1JlZlR5cGUoQ29uc3RhbnRzLk5PREVfSVRFUkFUT1JfU0lHKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwgbnVsbCk7Ci0gICAgICAgIElURVJBVE9SX0lOREVYID0gaXRlcmF0b3IuZ2V0SW5kZXgoKTsKLSAgICAgICAgX2Fsb2FkSXRlcmF0b3IgPSBuZXcgQUxPQUQoSVRFUkFUT1JfSU5ERVgpOwotICAgICAgICBfYXN0b3JlSXRlcmF0b3IgPSBuZXcgQVNUT1JFKElURVJBVE9SX0lOREVYKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBBQ09OU1RfTlVMTCgpKTsKLSAgICAgICAgaWwuYXBwZW5kKHN0b3JlSXRlcmF0b3IoKSk7Ci0gICAgfQotCi0gICAgcHVibGljIEluc3RydWN0aW9uIGxvYWRMYXN0Tm9kZSgpIHsKLSAgICAgICAgcmV0dXJuIF9pbG9hZExhc3Q7Ci0gICAgfQotCi0gICAgcHVibGljIEluc3RydWN0aW9uIGxvYWRDdXJyZW50Tm9kZSgpIHsKLSAgICAgICAgcmV0dXJuIF9pbG9hZEN1cnJlbnQ7Ci0gICAgfQotCi0gICAgcHVibGljIEluc3RydWN0aW9uIHN0b3JlQ3VycmVudE5vZGUoKSB7Ci0gICAgICAgIHJldHVybiBfaXN0b3JlQ3VycmVudDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb24gbG9hZERPTSgpIHsKLSAgICAgICAgcmV0dXJuIF9hbG9hZERvbTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldEhhbmRsZXJJbmRleCgpIHsKLSAgICAgICAgcmV0dXJuIElOVkFMSURfSU5ERVg7ICAgICAgICAgICAvLyBub3QgYXZhaWxhYmxlCi0gICAgfQotCi0gICAgcHVibGljIGludCBnZXRJdGVyYXRvckluZGV4KCkgewotICAgICAgICByZXR1cm4gSU5WQUxJRF9JTkRFWDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb24gc3RvcmVJdGVyYXRvcigpIHsKLSAgICAgICAgcmV0dXJuIF9hc3RvcmVJdGVyYXRvcjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb24gbG9hZEl0ZXJhdG9yKCkgewotICAgICAgICByZXR1cm4gX2Fsb2FkSXRlcmF0b3I7Ci0gICAgfQotCi0gICAgLy8/Pz8gbWF5IG5vdCBiZSB1c2VkIGFueW1vcmUKLSAgICBwdWJsaWMgaW50IGdldExvY2FsSW5kZXgoU3RyaW5nIG5hbWUpIHsKLSAgICAgICAgaWYgKG5hbWUuZXF1YWxzKCJjdXJyZW50IikpIHsKLSAgICAgICAgICAgIHJldHVybiBDVVJSRU5UX0lOREVYOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBzdXBlci5nZXRMb2NhbEluZGV4KG5hbWUpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvdXRpbC9FcnJvck1lc3NhZ2VzLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL3V0aWwvRXJyb3JNZXNzYWdlcy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1MmY5NDQxLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvdXRpbC9FcnJvck1lc3NhZ2VzLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMDIyICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbDsKLQotaW1wb3J0IGphdmEudXRpbC5MaXN0UmVzb3VyY2VCdW5kbGU7Ci0KLS8qKgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKi8KLXB1YmxpYyBjbGFzcyBFcnJvck1lc3NhZ2VzIGV4dGVuZHMgTGlzdFJlc291cmNlQnVuZGxlIHsKLQotLyoKLSAqIFhTTFRDIGNvbXBpbGUtdGltZSBlcnJvciBtZXNzYWdlcy4KLSAqCi0gKiBHZW5lcmFsIG5vdGVzIHRvIHRyYW5zbGF0b3JzIGFuZCBkZWZpbml0aW9uczoKLSAqCi0gKiAgIDEpIFhTTFRDIGlzIHRoZSBuYW1lIG9mIHRoZSBwcm9kdWN0LiAgSXQgaXMgYW4gYWNyb255bSBmb3IgIlhTTFQgQ29tcGlsZXIiLgotICogICAgICBYU0xUIGlzIGFuIGFjcm9ueW0gZm9yICJYTUwgU3R5bGVzaGVldCBMYW5ndWFnZTogVHJhbnNmb3JtYXRpb25zIi4KLSAqCi0gKiAgIDIpIEEgc3R5bGVzaGVldCBpcyBhIGRlc2NyaXB0aW9uIG9mIGhvdyB0byB0cmFuc2Zvcm0gYW4gaW5wdXQgWE1MIGRvY3VtZW50Ci0gKiAgICAgIGludG8gYSByZXN1bHRhbnQgWE1MIGRvY3VtZW50IChvciBIVE1MIGRvY3VtZW50IG9yIHRleHQpLiAgVGhlCi0gKiAgICAgIHN0eWxlc2hlZXQgaXRzZWxmIGlzIGRlc2NyaWJlZCBpbiB0aGUgZm9ybSBvZiBhbiBYTUwgZG9jdW1lbnQuCi0gKgotICogICAzKSBBIHRlbXBsYXRlIGlzIGEgY29tcG9uZW50IG9mIGEgc3R5bGVzaGVldCB0aGF0IGlzIHVzZWQgdG8gbWF0Y2ggYQotICogICAgICBwYXJ0aWN1bGFyIHBvcnRpb24gb2YgYW4gaW5wdXQgZG9jdW1lbnQgYW5kIHNwZWNpZmllcyB0aGUgZm9ybSBvZiB0aGUKLSAqICAgICAgY29ycmVzcG9uZGluZyBwb3J0aW9uIG9mIHRoZSBvdXRwdXQgZG9jdW1lbnQuCi0gKgotICogICA0KSBBbiBheGlzIGlzIGEgcGFydGljdWxhciAiZGltZW5zaW9uIiBpbiBhIHRyZWUgcmVwcmVzZW50YXRpb24gb2YgYW4gWE1MCi0gKiAgICAgIGRvY3VtZW50OyB0aGUgbm9kZXMgaW4gdGhlIHRyZWUgYXJlIGRpdmlkZWQgYWxvbmcgZGlmZmVyZW50IGF4ZXMuCi0gKiAgICAgIFRyYXZlcnNpbmcgdGhlICJjaGlsZCIgYXhpcywgZm9yIGluc3RhbmNlLCBtZWFucyB0aGF0IHRoZSBwcm9ncmFtCi0gKiAgICAgIHdvdWxkIHZpc2l0IGVhY2ggY2hpbGQgb2YgYSBwYXJ0aWN1bGFyIG5vZGU7IHRyYXZlcnNpbmcgdGhlICJkZXNjZW5kYW50IgotICogICAgICBheGlzIG1lYW5zIHRoYXQgdGhlIHByb2dyYW0gd291bGQgdmlzaXQgdGhlIGNoaWxkIG5vZGVzIG9mIGEgcGFydGljdWxhcgotICogICAgICBub2RlLCB0aGVpciBjaGlsZHJlbiwgYW5kIHNvIG9uIHVudGlsIHRoZSBsZWFmIG5vZGVzIG9mIHRoZSB0cmVlIGFyZQotICogICAgICByZWFjaGVkLgotICoKLSAqICAgNSkgQW4gaXRlcmF0b3IgaXMgYW4gb2JqZWN0IHRoYXQgdHJhdmVyc2VzIG5vZGVzIGluIGEgdHJlZSBhbG9uZyBhCi0gKiAgICAgIHBhcnRpY3VsYXIgYXhpcywgb25lIGF0IGEgdGltZS4KLSAqCi0gKiAgIDYpIEFuIGVsZW1lbnQgaXMgYSBtYXJrLXVwIHRhZyBpbiBhbiBYTUwgZG9jdW1lbnQ7IGFuIGF0dHJpYnV0ZSBpcyBhCi0gKiAgICAgIG1vZGlmaWVyIG9uIHRoZSB0YWcuICBGb3IgZXhhbXBsZSwgaW4gPGVsZW0gYXR0cj0ndmFsJyBhdHRyMj0ndmFsMic+Ci0gKiAgICAgICJlbGVtIiBpcyBhbiBlbGVtZW50IG5hbWUsICJhdHRyIiBhbmQgImF0dHIyIiBhcmUgYXR0cmlidXRlIG5hbWVzIHdpdGgKLSAqICAgICAgdGhlIHZhbHVlcyAidmFsIiBhbmQgInZhbDIiLCByZXNwZWN0aXZlbHkuCi0gKgotICogICA3KSBBIG5hbWVzcGFjZSBkZWNsYXJhdGlvbiBpcyBhIHNwZWNpYWwgYXR0cmlidXRlIHRoYXQgaXMgdXNlZCB0byBhc3NvY2lhdGUKLSAqICAgICAgYSBwcmVmaXggd2l0aCBhIFVSSSAodGhlIG5hbWVzcGFjZSkuICBUaGUgbWVhbmluZ3Mgb2YgZWxlbWVudCBuYW1lcyBhbmQKLSAqICAgICAgYXR0cmlidXRlIG5hbWVzIHRoYXQgdXNlIHRoYXQgcHJlZml4IGFyZSBkZWZpbmVkIHdpdGggcmVzcGVjdCB0byB0aGF0Ci0gKiAgICAgIG5hbWVzcGFjZS4KLSAqCi0gKiAgIDgpIERPTSBpcyBhbiBhY3JvbnltIGZvciBEb2N1bWVudCBPYmplY3QgTW9kZWwuICBJdCBpcyBhIHRyZWUKLSAqICAgICAgcmVwcmVzZW50YXRpb24gb2YgYW4gWE1MIGRvY3VtZW50LgotICoKLSAqICAgICAgU0FYIGlzIGFuIGFjcm9ueW0gZm9yIHRoZSBTaW1wbGUgQVBJIGZvciBYTUwgcHJvY2Vzc2luZy4gIEl0IGlzIGFuIEFQSQotICogICAgICB1c2VkIGluZm9ybSBhbiBYTUwgcHJvY2Vzc29yIChpbiB0aGlzIGNhc2UgWFNMVEMpIG9mIHRoZSBzdHJ1Y3R1cmUgYW5kCi0gKiAgICAgIGNvbnRlbnQgb2YgYW4gWE1MIGRvY3VtZW50LgotICoKLSAqICAgICAgSW5wdXQgdG8gdGhlIHN0eWxlc2hlZXQgcHJvY2Vzc29yIGNhbiBjb21lIGZyb20gYW4gWE1MIHBhcnNlciBpbiB0aGUKLSAqICAgICAgZm9ybSBvZiBhIERPTSB0cmVlIG9yIHRocm91Z2ggdGhlIFNBWCBBUEkuCi0gKgotICogICA5KSBEVEQgaXMgYSBkb2N1bWVudCB0eXBlIGRlY2xhcmF0aW9uLiAgSXQgaXMgYSB3YXkgb2Ygc3BlY2lmeWluZyB0aGUKLSAqICAgICAgZ3JhbW1hciBmb3IgYW4gWE1MIGZpbGUsIHRoZSBuYW1lcyBhbmQgdHlwZXMgb2YgZWxlbWVudHMsIGF0dHJpYnV0ZXMsCi0gKiAgICAgIGV0Yy4KLSAqCi0gKiAgMTApIFhQYXRoIGlzIGEgc3BlY2lmaWNhdGlvbiB0aGF0IGRlc2NyaWJlcyBhIG5vdGF0aW9uIGZvciBpZGVudGlmeWluZwotICogICAgICBub2RlcyBpbiBhIHRyZWUtc3RydWN0dXJlZCByZXByZXNlbnRhdGlvbiBvZiBhbiBYTUwgZG9jdW1lbnQuICBBbgotICogICAgICBpbnN0YW5jZSBvZiB0aGF0IG5vdGF0aW9uIGlzIHJlZmVycmVkIHRvIGFzIGFuIFhQYXRoIGV4cHJlc3Npb24uCi0gKgotICogIDExKSBUcmFuc2xldCBpcyBhbiBpbnZlbnRlZCB0ZXJtIHRoYXQgcmVmZXJzIHRvIHRoZSBjbGFzcyBmaWxlIHRoYXQgY29udGFpbnMKLSAqICAgICAgdGhlIGNvbXBpbGVkIGZvcm0gb2YgYSBzdHlsZXNoZWV0LgotICovCi0KLSAgICAvLyBUaGVzZSBtZXNzYWdlIHNob3VsZCBiZSByZWFkIGZyb20gYSBsb2NhbGUtc3BlY2lmaWMgcmVzb3VyY2UgYnVuZGxlCi0gICAgLyoqIEdldCB0aGUgbG9va3VwIHRhYmxlIGZvciBlcnJvciBtZXNzYWdlcy4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIG1lc3NhZ2UgbG9va3VwIHRhYmxlLgotICAgICAqLwotICAgIHB1YmxpYyBPYmplY3RbXVtdIGdldENvbnRlbnRzKCkKLSAgICB7Ci0gICAgICByZXR1cm4gbmV3IE9iamVjdFtdW10gewotICAgICAgICB7RXJyb3JNc2cuTVVMVElQTEVfU1RZTEVTSEVFVF9FUlIsCi0gICAgICAgICJNb3JlIHRoYW4gb25lIHN0eWxlc2hlZXQgZGVmaW5lZCBpbiB0aGUgc2FtZSBmaWxlLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYQotICAgICAgICAgKiB0ZW1wbGF0ZS4gIFRoZSBzYW1lIG5hbWUgd2FzIHVzZWQgb24gdHdvIGRpZmZlcmVudCB0ZW1wbGF0ZXMgaW4gdGhlCi0gICAgICAgICAqIHNhbWUgc3R5bGVzaGVldC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5URU1QTEFURV9SRURFRl9FUlIsCi0gICAgICAgICJUZW1wbGF0ZSAnJ3swfScnIGFscmVhZHkgZGVmaW5lZCBpbiB0aGlzIHN0eWxlc2hlZXQuIn0sCi0KLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIGEKLSAgICAgICAgICogdGVtcGxhdGUuICBBIHJlZmVyZW5jZSB0byB0aGUgdGVtcGxhdGUgbmFtZSB3YXMgZW5jb3VudGVyZWQsIGJ1dCB0aGUKLSAgICAgICAgICogdGVtcGxhdGUgaXMgdW5kZWZpbmVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlRFTVBMQVRFX1VOREVGX0VSUiwKLSAgICAgICAgIlRlbXBsYXRlICcnezB9Jycgbm90IGRlZmluZWQgaW4gdGhpcyBzdHlsZXNoZWV0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYSB2YXJpYWJsZQotICAgICAgICAgKiB0aGF0IHdhcyBkZWZpbmVkIG1vcmUgdGhhbiBvbmNlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlZBUklBQkxFX1JFREVGX0VSUiwKLSAgICAgICAgIlZhcmlhYmxlICcnezB9JycgaXMgbXVsdGlwbHkgZGVmaW5lZCBpbiB0aGUgc2FtZSBzY29wZS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIGEgdmFyaWFibGUKLSAgICAgICAgICogb3IgcGFyYW1ldGVyLiAgQSByZWZlcmVuY2UgdG8gdGhlIHZhcmlhYmxlIG9yIHBhcmFtZXRlciB3YXMgZm91bmQsCi0gICAgICAgICAqIGJ1dCBpdCB3YXMgbmV2ZXIgZGVmaW5lZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5WQVJJQUJMRV9VTkRFRl9FUlIsCi0gICAgICAgICJWYXJpYWJsZSBvciBwYXJhbWV0ZXIgJyd7MH0nJyBpcyB1bmRlZmluZWQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSB3b3JkICJjbGFzcyIgaGVyZSByZWZlcnMgdG8gYSBKYXZhIGNsYXNzLgotICAgICAgICAgKiBQcm9jZXNzaW5nIHRoZSBzdHlsZXNoZWV0IHJlcXVpcmVkIGEgY2xhc3MgdG8gYmUgbG9hZGVkLCBidXQgaXQgY291bGQKLSAgICAgICAgICogbm90IGJlIGZvdW5kLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIHRoZSBjbGFzcy4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5DTEFTU19OT1RfRk9VTkRfRVJSLAotICAgICAgICAiQ2Fubm90IGZpbmQgY2xhc3MgJyd7MH0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHdvcmQgIm1ldGhvZCIgaGVyZSByZWZlcnMgdG8gYSBKYXZhIG1ldGhvZC4KLSAgICAgICAgICogUHJvY2Vzc2luZyB0aGUgc3R5bGVzaGVldCByZXF1aXJlZCBhIHJlZmVyZW5jZSB0byB0aGUgbWV0aG9kIG5hbWVkIGJ5Ci0gICAgICAgICAqIHRoZSBzdWJzdGl0dXRpb24gdGV4dCwgYnV0IGl0IGNvdWxkIG5vdCBiZSBmb3VuZC4gICJwdWJsaWMiIGlzIHRoZQotICAgICAgICAgKiBKYXZhIGtleXdvcmQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTUVUSE9EX05PVF9GT1VORF9FUlIsCi0gICAgICAgICJDYW5ub3QgZmluZCBleHRlcm5hbCBtZXRob2QgJyd7MH0nJyAobXVzdCBiZSBwdWJsaWMpLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgd29yZCAibWV0aG9kIiBoZXJlIHJlZmVycyB0byBhIEphdmEgbWV0aG9kLgotICAgICAgICAgKiBQcm9jZXNzaW5nIHRoZSBzdHlsZXNoZWV0IHJlcXVpcmVkIGEgcmVmZXJlbmNlIHRvIHRoZSBtZXRob2QgbmFtZWQgYnkKLSAgICAgICAgICogdGhlIHN1YnN0aXR1dGlvbiB0ZXh0LCBidXQgbm8gbWV0aG9kIHdpdGggdGhlIHJlcXVpcmVkIHR5cGVzIG9mCi0gICAgICAgICAqIGFyZ3VtZW50cyBvciByZXR1cm4gdHlwZSBjb3VsZCBiZSBmb3VuZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5BUkdVTUVOVF9DT05WRVJTSU9OX0VSUiwKLSAgICAgICAgIkNhbm5vdCBjb252ZXJ0IGFyZ3VtZW50L3JldHVybiB0eXBlIGluIGNhbGwgdG8gbWV0aG9kICcnezB9JycifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZpbGUgb3IgVVJJIG5hbWVkIGluIHRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICAgKiBpcyBtaXNzaW5nLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkZJTEVfTk9UX0ZPVU5EX0VSUiwKLSAgICAgICAgIkZpbGUgb3IgVVJJICcnezB9Jycgbm90IGZvdW5kLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgZGlzcGxheWVkIHdoZW4gdGhlIFVSSQotICAgICAgICAgKiBtZW50aW9uZWQgaW4gdGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIG5vdCB3ZWxsLWZvcm1lZCBzeW50YWN0aWNhbGx5LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklOVkFMSURfVVJJX0VSUiwKLSAgICAgICAgIkludmFsaWQgVVJJICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmaWxlIG9yIFVSSSBuYW1lZCBpbiB0aGUgc3Vic3RpdHV0aW9uIHRleHQKLSAgICAgICAgICogZXhpc3RzIGJ1dCBjb3VsZCBub3QgYmUgb3BlbmVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkZJTEVfQUNDRVNTX0VSUiwKLSAgICAgICAgIkNhbm5vdCBvcGVuIGZpbGUgb3IgVVJJICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogPHhzbDpzdHlsZXNoZWV0PiBhbmQgPHhzbDp0cmFuc2Zvcm0+IGFyZQotICAgICAgICAgKiBrZXl3b3JkcyB0aGF0IHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5NSVNTSU5HX1JPT1RfRVJSLAotICAgICAgICAiPHhzbDpzdHlsZXNoZWV0PiBvciA8eHNsOnRyYW5zZm9ybT4gZWxlbWVudCBleHBlY3RlZC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN0eWxlc2hlZXQgY29udGFpbmVkIGEgcmVmZXJlbmNlIHRvIGEKLSAgICAgICAgICogbmFtZXNwYWNlIHByZWZpeCB0aGF0IHdhcyB1bmRlZmluZWQuICBUaGUgdmFsdWUgb2YgdGhlIHN1YnN0aXR1dGlvbgotICAgICAgICAgKiB0ZXh0IGlzIHRoZSBuYW1lIG9mIHRoZSBwcmVmaXguCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTkFNRVNQQUNFX1VOREVGX0VSUiwKLSAgICAgICAgIk5hbWVzcGFjZSBwcmVmaXggJyd7MH0nJyBpcyB1bmRlY2xhcmVkLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgSmF2YSBmdW5jdGlvbiBuYW1lZCBpbiB0aGUgc3R5bGVzaGVldCBjb3VsZAotICAgICAgICAgKiBub3QgYmUgZm91bmQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuRlVOQ1RJT05fUkVTT0xWRV9FUlIsCi0gICAgICAgICJVbmFibGUgdG8gcmVzb2x2ZSBjYWxsIHRvIGZ1bmN0aW9uICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBhCi0gICAgICAgICAqIGZ1bmN0aW9uLiAgQSBsaXRlcmFsIHN0cmluZyBoZXJlIG1lYW5zIGEgY29uc3RhbnQgc3RyaW5nIHZhbHVlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk5FRURfTElURVJBTF9FUlIsCi0gICAgICAgICJBcmd1bWVudCB0byAnJ3swfScnIG11c3QgYmUgYSBsaXRlcmFsIHN0cmluZy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGluZGljYXRlcyB0aGVyZSB3YXMgYSBzeW50YWN0aWMKLSAgICAgICAgICogZXJyb3IgaW4gdGhlIGZvcm0gb2YgYW4gWFBhdGggZXhwcmVzc2lvbi4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcwotICAgICAgICAgKiB0aGUgZXhwcmVzc2lvbi4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5YUEFUSF9QQVJTRVJfRVJSLAotICAgICAgICAiRXJyb3IgcGFyc2luZyBYUGF0aCBleHByZXNzaW9uICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIGVsZW1lbnQgaW4gdGhlIHN0eWxlc2hlZXQgcmVxdWlyZXMgYQotICAgICAgICAgKiBwYXJ0aWN1bGFyIGF0dHJpYnV0ZSBuYW1lZCBieSB0aGUgc3Vic3RpdHV0aW9uIHRleHQsIGJ1dCB0aGF0Ci0gICAgICAgICAqIGF0dHJpYnV0ZSB3YXMgbm90IHNwZWNpZmllZCBpbiB0aGUgc3R5bGVzaGVldC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5SRVFVSVJFRF9BVFRSX0VSUiwKLSAgICAgICAgIlJlcXVpcmVkIGF0dHJpYnV0ZSAnJ3swfScnIGlzIG1pc3NpbmcuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCBhIGNoYXJhY3RlciBub3QKLSAgICAgICAgICogcGVybWl0dGVkIGluIGFuIFhQYXRoIGV4cHJlc3Npb24gd2FzIGVuY291bnRlcmVkLiAgVGhlIHN1YnN0aXR1dGlvbgotICAgICAgICAgKiB0ZXh0IGlzIHRoZSBvZmZlbmRpbmcgY2hhcmFjdGVyLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfQ0hBUl9FUlIsCi0gICAgICAgICJJbGxlZ2FsIGNoYXJhY3RlciAnJ3swfScnIGluIFhQYXRoIGV4cHJlc3Npb24uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEEgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiBpcyBhIG1hcmstdXAgaXRlbSBpbgotICAgICAgICAgKiBhbiBYTUwgZG9jdW1lbnQgdGhhdCByZXF1ZXN0IHNvbWUgYmVoYXZpb3VyIG9mIGFuIFhNTCBwcm9jZXNzb3IuICBUaGUKLSAgICAgICAgICogZm9ybSBvZiB0aGUgbmFtZSBvZiB3YXMgaW52YWxpZCBpbiB0aGlzIGNhc2UsIGFuZCB0aGUgc3Vic3RpdHV0aW9uCi0gICAgICAgICAqIHRleHQgaXMgdGhlIG5hbWUuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSUxMRUdBTF9QSV9FUlIsCi0gICAgICAgICJJbGxlZ2FsIG5hbWUgJyd7MH0nJyBmb3IgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbi4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIHJlcG9ydGVkIGlmIHRoZSBzdHlsZXNoZWV0Ci0gICAgICAgICAqIGJlaW5nIHByb2Nlc3NlZCBhdHRlbXB0ZWQgdG8gY29uc3RydWN0IGFuIFhNTCBkb2N1bWVudCB3aXRoIGFuCi0gICAgICAgICAqIGF0dHJpYnV0ZSBpbiBhIHBsYWNlIG90aGVyIHRoYW4gb24gYW4gZWxlbWVudC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICAgKiBzcGVjaWZpZXMgdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5TVFJBWV9BVFRSSUJVVEVfRVJSLAotICAgICAgICAiQXR0cmlidXRlICcnezB9Jycgb3V0c2lkZSBvZiBlbGVtZW50LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBbiBhdHRyaWJ1dGUgdGhhdCB3YXNuJ3QgcmVjb2duaXplZCB3YXMKLSAgICAgICAgICogc3BlY2lmaWVkIG9uIGFuIGVsZW1lbnQgaW4gdGhlIHN0eWxlc2hlZXQuICBUaGUgYXR0cmlidXRlIGlzIG5hbWVkCi0gICAgICAgICAqIGJ5IHRoZSBzdWJzdGl0dXRpb24KLSAgICAgICAgICogdGV4dC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTExFR0FMX0FUVFJJQlVURV9FUlIsCi0gICAgICAgICJJbGxlZ2FsIGF0dHJpYnV0ZSAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiaW1wb3J0IiBhbmQgImluY2x1ZGUiIGFyZSBrZXl3b3JkcyB0aGF0IHNob3VsZAotICAgICAgICAgKiBub3QgYmUgdHJhbnNsYXRlZC4gIFRoaXMgbWVzc2FnZXMgaW5kaWNhdGVzIHRoYXQgdGhlIHN0eWxlc2hlZXQKLSAgICAgICAgICogbmFtZWQgaW4gdGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGltcG9ydGVkIG9yIGluY2x1ZGVkIGl0c2VsZiBlaXRoZXIKLSAgICAgICAgICogZGlyZWN0bHkgb3IgaW5kaXJlY3RseS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5DSVJDVUxBUl9JTkNMVURFX0VSUiwKLSAgICAgICAgIkNpcmN1bGFyIGltcG9ydC9pbmNsdWRlLiBTdHlsZXNoZWV0ICcnezB9JycgYWxyZWFkeSBsb2FkZWQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEEgcmVzdWx0LXRyZWUgZnJhZ21lbnQgaXMgYSBwb3J0aW9uIG9mIGEKLSAgICAgICAgICogcmVzdWx0aW5nIFhNTCBkb2N1bWVudCByZXByZXNlbnRlZCBhcyBhIHRyZWUuICAiPHhzbDpzb3J0PiIgaXMgYQotICAgICAgICAgKiBrZXl3b3JkIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuUkVTVUxUX1RSRUVfU09SVF9FUlIsCi0gICAgICAgICJSZXN1bHQtdHJlZSBmcmFnbWVudHMgY2Fubm90IGJlIHNvcnRlZCAoPHhzbDpzb3J0PiBlbGVtZW50cyBhcmUgIiArCi0gICAgICAgICJpZ25vcmVkKS4gWW91IG11c3Qgc29ydCB0aGUgbm9kZXMgd2hlbiBjcmVhdGluZyB0aGUgcmVzdWx0IHRyZWUuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEEgbmFtZSBjYW4gYmUgZ2l2ZW4gdG8gYSBwYXJ0aWN1bGFyIHN0eWxlIHRvIGJlCi0gICAgICAgICAqIHVzZWQgdG8gZm9ybWF0IGRlY2ltYWwgdmFsdWVzLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGdpdmVzIHRoZSBuYW1lCi0gICAgICAgICAqIG9mIHN1Y2ggYSBzdHlsZSBmb3Igd2hpY2ggbW9yZSB0aGFuIG9uZSBkZWNsYXJhdGlvbiB3YXMgZW5jb3VudGVyZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuU1lNQk9MU19SRURFRl9FUlIsCi0gICAgICAgICJEZWNpbWFsIGZvcm1hdHRpbmcgJyd7MH0nJyBpcyBhbHJlYWR5IGRlZmluZWQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IHZlcnNpb24gbmFtZWQgaW4gdGhlCi0gICAgICAgICAqIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIG5vdCBzdXBwb3J0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuWFNMX1ZFUlNJT05fRVJSLAotICAgICAgICAiWFNMIHZlcnNpb24gJyd7MH0nJyBpcyBub3Qgc3VwcG9ydGVkIGJ5IFhTTFRDLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZGVmaW5pdGlvbnMgb2Ygb25lIG9yIG1vcmUgdmFyaWFibGVzIG9yCi0gICAgICAgICAqIHBhcmFtZXRlcnMgZGVwZW5kIG9uIG9uZSBhbm90aGVyLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkNJUkNVTEFSX1ZBUklBQkxFX0VSUiwKLSAgICAgICAgIkNpcmN1bGFyIHZhcmlhYmxlL3BhcmFtZXRlciByZWZlcmVuY2UgaW4gJyd7MH0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIG9wZXJhdG9yIGluIGFuIGV4cHJlc2lvbiB3aXRoIHR3byBvcGVyYW5kcyB3YXMKLSAgICAgICAgICogbm90IHJlY29nbml6ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSUxMRUdBTF9CSU5BUllfT1BfRVJSLAotICAgICAgICAiVW5rbm93biBvcGVyYXRvciBmb3IgYmluYXJ5IGV4cHJlc3Npb24uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyBwcm9kdWNlZCBpZiBhIHJlZmVyZW5jZSB0byBhCi0gICAgICAgICAqIGZ1bmN0aW9uIGhhcyB0b28gbWFueSBvciB0b28gZmV3IGFyZ3VtZW50cy4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTExFR0FMX0FSR19FUlIsCi0gICAgICAgICJJbGxlZ2FsIGFyZ3VtZW50KHMpIGZvciBmdW5jdGlvbiBjYWxsLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiZG9jdW1lbnQoKSIgaXMgdGhlIG5hbWUgb2YgZnVuY3Rpb24gYW5kIG11c3QKLSAgICAgICAgICogbm90IGJlIHRyYW5zbGF0ZWQuICBBIG5vZGUtc2V0IGlzIGEgc2V0IG9mIHRoZSBub2RlcyBpbiB0aGUgdHJlZQotICAgICAgICAgKiByZXByZXNlbnRhdGlvbiBvZiBhbiBYTUwgZG9jdW1lbnQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuRE9DVU1FTlRfQVJHX0VSUiwKLSAgICAgICAgIlNlY29uZCBhcmd1bWVudCB0byBkb2N1bWVudCgpIGZ1bmN0aW9uIG11c3QgYmUgYSBub2RlLXNldC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIjx4c2w6d2hlbj4iIGFuZCAiPHhzbDpjaG9vc2U+IiBhcmUga2V5d29yZHMKLSAgICAgICAgICogYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoaXMgbWVzc2FnZSBkZXNjcmliZXMgYSBzeW50YXggZXJyb3IKLSAgICAgICAgICogaW4gdGhlIHN0eWxlc2hlZXQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTUlTU0lOR19XSEVOX0VSUiwKLSAgICAgICAgIkF0IGxlYXN0IG9uZSA8eHNsOndoZW4+IGVsZW1lbnQgcmVxdWlyZWQgaW4gPHhzbDpjaG9vc2U+LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiPHhzbDpvdGhlcndpc2U+IiBhbmQgIjx4c2w6Y2hvb3NlPiIgYXJlCi0gICAgICAgICAqIGtleXdvcmRzIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGlzIG1lc3NhZ2UgZGVzY3JpYmVzIGEKLSAgICAgICAgICogc3ludGF4IGVycm9yIGluIHRoZSBzdHlsZXNoZWV0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk1VTFRJUExFX09USEVSV0lTRV9FUlIsCi0gICAgICAgICJPbmx5IG9uZSA8eHNsOm90aGVyd2lzZT4gZWxlbWVudCBhbGxvd2VkIGluIDx4c2w6Y2hvb3NlPi4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIjx4c2w6b3RoZXJ3aXNlPiIgYW5kICI8eHNsOmNob29zZT4iIGFyZQotICAgICAgICAgKiBrZXl3b3JkcyBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhpcyBtZXNzYWdlIGRlc2NyaWJlcyBhCi0gICAgICAgICAqIHN5bnRheCBlcnJvciBpbiB0aGUgc3R5bGVzaGVldC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5TVFJBWV9PVEhFUldJU0VfRVJSLAotICAgICAgICAiPHhzbDpvdGhlcndpc2U+IGNhbiBvbmx5IGJlIHVzZWQgd2l0aGluIDx4c2w6Y2hvb3NlPi4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIjx4c2w6d2hlbj4iIGFuZCAiPHhzbDpjaG9vc2U+IiBhcmUga2V5d29yZHMKLSAgICAgICAgICogYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoaXMgbWVzc2FnZSBkZXNjcmliZXMgYSBzeW50YXggZXJyb3IKLSAgICAgICAgICogaW4gdGhlIHN0eWxlc2hlZXQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuU1RSQVlfV0hFTl9FUlIsCi0gICAgICAgICI8eHNsOndoZW4+IGNhbiBvbmx5IGJlIHVzZWQgd2l0aGluIDx4c2w6Y2hvb3NlPi4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIjx4c2w6d2hlbj4iLCAiPHhzbDpvdGhlcndpc2U+IiBhbmQKLSAgICAgICAgICogIjx4c2w6Y2hvb3NlPiIgYXJlIGtleXdvcmRzIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGlzCi0gICAgICAgICAqIG1lc3NhZ2UgZGVzY3JpYmVzIGEgc3ludGF4IGVycm9yIGluIHRoZSBzdHlsZXNoZWV0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLldIRU5fRUxFTUVOVF9FUlIsCi0gICAgICAgICJPbmx5IDx4c2w6d2hlbj4gYW5kIDx4c2w6b3RoZXJ3aXNlPiBlbGVtZW50cyBhbGxvd2VkIGluIDx4c2w6Y2hvb3NlPi4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIjx4c2w6YXR0cmlidXRlLXNldD4iIGFuZCAibmFtZSIgYXJlIGtleXdvcmRzCi0gICAgICAgICAqIHRoYXQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlVOTkFNRURfQVRUUklCU0VUX0VSUiwKLSAgICAgICAgIjx4c2w6YXR0cmlidXRlLXNldD4gaXMgbWlzc2luZyB0aGUgJ25hbWUnIGF0dHJpYnV0ZS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQW4gZWxlbWVudCBpbiB0aGUgc3R5bGVzaGVldCBjb250YWluZWQgYW4KLSAgICAgICAgICogZWxlbWVudCBvZiBhIHR5cGUgdGhhdCBpdCB3YXMgbm90IHBlcm1pdHRlZCB0byBjb250YWluLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfQ0hJTERfRVJSLAotICAgICAgICAiSWxsZWdhbCBjaGlsZCBlbGVtZW50LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3R5bGVzaGVldCB0cmllZCB0byBjcmVhdGUgYW4gZWxlbWVudCB3aXRoCi0gICAgICAgICAqIGEgbmFtZSB0aGF0IHdhcyBub3QgYSB2YWxpZCBYTUwgbmFtZS4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBjb250YWlucwotICAgICAgICAgKiB0aGUgbmFtZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTExFR0FMX0VMRU1fTkFNRV9FUlIsCi0gICAgICAgICJZb3UgY2Fubm90IGNhbGwgYW4gZWxlbWVudCAnJ3swfScnIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IHRyaWVkIHRvIGNyZWF0ZSBhbiBhdHRyaWJ1dGUKLSAgICAgICAgICogd2l0aCBhIG5hbWUgdGhhdCB3YXMgbm90IGEgdmFsaWQgWE1MIG5hbWUuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQKLSAgICAgICAgICogY29udGFpbnMgdGhlIG5hbWUuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSUxMRUdBTF9BVFRSX05BTUVfRVJSLAotICAgICAgICAiWW91IGNhbm5vdCBjYWxsIGFuIGF0dHJpYnV0ZSAnJ3swfScnIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBjaGlsZHJlbiBvZiB0aGUgb3V0ZXJtb3N0IGVsZW1lbnQgb2YgYQotICAgICAgICAgKiBzdHlsZXNoZWV0IGFyZSByZWZlcnJlZCB0byBhcyB0b3AtbGV2ZWwgZWxlbWVudHMuICBObyB0ZXh0IHNob3VsZAotICAgICAgICAgKiBvY2N1ciB3aXRoaW4gdGhhdCBvdXRlcm1vc3QgZWxlbWVudCB1bmxlc3MgaXQgaXMgd2l0aGluIGEgdG9wLWxldmVsCi0gICAgICAgICAqIGVsZW1lbnQuICBUaGlzIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhhdCBjb25zdHJhaW50IHdhcyB2aW9sYXRlZC4KLSAgICAgICAgICogIjx4c2w6c3R5bGVzaGVldD4iIGlzIGEga2V5d29yZCB0aGF0IHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTExFR0FMX1RFWFRfTk9ERV9FUlIsCi0gICAgICAgICJUZXh0IGRhdGEgb3V0c2lkZSBvZiB0b3AtbGV2ZWwgPHhzbDpzdHlsZXNoZWV0PiBlbGVtZW50LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBKQVhQIGlzIGFuIGFjcm9ueW0gZm9yIHRoZSBKYXZhIEFQSSBmb3IgWE1MCi0gICAgICAgICAqIFByb2Nlc3NpbmcuICBUaGlzIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhlIFhNTCBwYXJzZXIgcHJvdmlkZWQgdG8KLSAgICAgICAgICogWFNMVEMgdG8gcHJvY2VzcyB0aGUgWE1MIGlucHV0IGRvY3VtZW50IGhhZCBhIGNvbmZpZ3VyYXRpb24gcHJvYmxlbS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5TQVhfUEFSU0VSX0NPTkZJR19FUlIsCi0gICAgICAgICJKQVhQIHBhcnNlciBub3QgY29uZmlndXJlZCBjb3JyZWN0bHkifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IG5hbWVzIHRoZSBpbnRlcm5hbCBlcnJvcgotICAgICAgICAgKiBlbmNvdW50ZXJlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTlRFUk5BTF9FUlIsCi0gICAgICAgICJVbnJlY292ZXJhYmxlIFhTTFRDLWludGVybmFsIGVycm9yOiAnJ3swfScnIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IGNvbnRhaW5lZCBhbiBlbGVtZW50IHRoYXQgd2FzCi0gICAgICAgICAqIG5vdCByZWNvZ25pemVkIGFzIHBhcnQgb2YgdGhlIFhTTCBzeW50YXguICBUaGUgc3Vic3RpdHV0aW9uIHRleHQKLSAgICAgICAgICogZ2l2ZXMgdGhlIGVsZW1lbnQgbmFtZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5VTlNVUFBPUlRFRF9YU0xfRVJSLAotICAgICAgICAiVW5zdXBwb3J0ZWQgWFNMIGVsZW1lbnQgJyd7MH0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN0eWxlc2hlZXQgcmVmZXJyZWQgdG8gYW4gZXh0ZW5zaW9uIHRvIHRoZQotICAgICAgICAgKiBYU0wgc3ludGF4IGFuZCBpbmRpY2F0ZWQgdGhhdCBpdCB3YXMgZGVmaW5lZCBieSBYU0xUQywgYnV0IFhTVExDIGRvZXMKLSAgICAgICAgICogbm90IHJlY29nbml6ZWQgdGhlIHBhcnRpY3VsYXIgZXh0ZW5zaW9uIG5hbWVkLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgICAqIGdpdmVzIHRoZSBleHRlbnNpb24gbmFtZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5VTlNVUFBPUlRFRF9FWFRfRVJSLAotICAgICAgICAiVW5yZWNvZ25pc2VkIFhTTFRDIGV4dGVuc2lvbiAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgWE1MIGRvY3VtZW50IGdpdmVuIHRvIFhTTFRDIGFzIGEgc3R5bGVzaGVldAotICAgICAgICAgKiB3YXMgbm90LCBpbiBmYWN0LCBhIHN0eWxlc2hlZXQuICBYU0xUQyBpcyBhYmxlIHRvIGRldGVjdCB0aGF0IGluIHRoaXMKLSAgICAgICAgICogY2FzZSBiZWNhdXNlIHRoZSBvdXRlcm1vc3QgZWxlbWVudCBpbiB0aGUgc3R5bGVzaGVldCBoYXMgdG8gYmUKLSAgICAgICAgICogZGVjbGFyZWQgd2l0aCByZXNwZWN0IHRvIHRoZSBYU0wgbmFtZXNwYWNlIFVSSSwgYnV0IG5vIGRlY2xhcmF0aW9uCi0gICAgICAgICAqIGZvciB0aGF0IG5hbWVzcGFjZSB3YXMgc2Vlbi4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5NSVNTSU5HX1hTTFRfVVJJX0VSUiwKLSAgICAgICAgIlRoZSBpbnB1dCBkb2N1bWVudCBpcyBub3QgYSBzdHlsZXNoZWV0ICh0aGUgWFNMIG5hbWVzcGFjZSBpcyBub3QgIisKLSAgICAgICAgImRlY2xhcmVkIGluIHRoZSByb290IGVsZW1lbnQpLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBYU0xUQyBjb3VsZCBub3QgZmluZCB0aGUgc3R5bGVzaGVldCBkb2N1bWVudAotICAgICAgICAgKiB3aXRoIHRoZSBuYW1lIHNwZWNpZmllZCBieSB0aGUgc3Vic3RpdHV0aW9uIHRleHQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTUlTU0lOR19YU0xUX1RBUkdFVF9FUlIsCi0gICAgICAgICJDb3VsZCBub3QgZmluZCBzdHlsZXNoZWV0IHRhcmdldCAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBhY2Nlc3MgdG8gdGhlIHN0eWxlc2hlZXQgdGFyZ2V0IGlzIGRlbmllZAotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkFDQ0VTU0lOR19YU0xUX1RBUkdFVF9FUlIsCi0gICAgICAgICJDb3VsZCBub3QgcmVhZCBzdHlsZXNoZWV0IHRhcmdldCAnJ3swfScnLCBiZWNhdXNlICcnezF9JycgYWNjZXNzIGlzIG5vdCBhbGxvd2VkIGR1ZSB0byByZXN0cmljdGlvbiBzZXQgYnkgdGhlIGFjY2Vzc0V4dGVybmFsU3R5bGVzaGVldCBwcm9wZXJ0eS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIHJlcHJlc2VudHMgYW4gaW50ZXJuYWwgZXJyb3IgaW4KLSAgICAgICAgICogY29uZGl0aW9uIGluIFhTTFRDLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBjbGFzcyBuYW1lIGluIFhTTFRDCi0gICAgICAgICAqIHRoYXQgaXMgbWlzc2luZyBzb21lIGZ1bmN0aW9uYWxpdHkuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTk9UX0lNUExFTUVOVEVEX0VSUiwKLSAgICAgICAgIk5vdCBpbXBsZW1lbnRlZDogJyd7MH0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIFhNTCBkb2N1bWVudCBnaXZlbiB0byBYU0xUQyBhcyBhIHN0eWxlc2hlZXQKLSAgICAgICAgICogd2FzIG5vdCwgaW4gZmFjdCwgYSBzdHlsZXNoZWV0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk5PVF9TVFlMRVNIRUVUX0VSUiwKLSAgICAgICAgIlRoZSBpbnB1dCBkb2N1bWVudCBkb2VzIG5vdCBjb250YWluIGFuIFhTTCBzdHlsZXNoZWV0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZWxlbWVudCBuYW1lZCBpbiB0aGUgc3Vic3RpdHV0aW9uIHRleHQgd2FzCi0gICAgICAgICAqIGVuY291bnRlcmVkIGluIHRoZSBzdHlsZXNoZWV0IGJ1dCBpcyBub3QgcmVjb2duaXplZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5FTEVNRU5UX1BBUlNFX0VSUiwKLSAgICAgICAgIkNvdWxkIG5vdCBwYXJzZSBlbGVtZW50ICcnezB9JycifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgInVzZSIsICI8a2V5PiIsICJub2RlIiwgIm5vZGUtc2V0IiwgInN0cmluZyIKLSAgICAgICAgICogYW5kICJudW1iZXIiIGFyZSBrZXl3b3JkcyBpbiB0aGlzIGNvbnRleHQgYW5kIHNob3VsZCBub3QgYmUKLSAgICAgICAgICogdHJhbnNsYXRlZC4gIFRoaXMgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUgdmFsdWUgb2YgdGhlICJ1c2UiCi0gICAgICAgICAqIGF0dHJpYnV0ZSB3YXMgbm90IG9uZSBvZiB0aGUgcGVybWl0dGVkIHZhbHVlcy4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5LRVlfVVNFX0FUVFJfRVJSLAotICAgICAgICAiVGhlIHVzZSBhdHRyaWJ1dGUgb2YgPGtleT4gbXVzdCBiZSBub2RlLCBub2RlLXNldCwgc3RyaW5nIG9yIG51bWJlci4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQW4gWE1MIGRvY3VtZW50IGNhbiBzcGVjaWZ5IHRoZSB2ZXJzaW9uIG9mIHRoZQotICAgICAgICAgKiBYTUwgc3BlY2lmaWNhdGlvbiB0byB3aGljaCBpdCBhZGhlcmVzLiAgVGhpcyBtZXNzYWdlIGluZGljYXRlcyB0aGF0Ci0gICAgICAgICAqIHRoZSB2ZXJzaW9uIHNwZWNpZmllZCBmb3IgdGhlIG91dHB1dCBkb2N1bWVudCB3YXMgbm90IHZhbGlkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk9VVFBVVF9WRVJTSU9OX0VSUiwKLSAgICAgICAgIk91dHB1dCBYTUwgZG9jdW1lbnQgdmVyc2lvbiBzaG91bGQgYmUgMS4wIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBvcGVyYXRvciBpbiBhIGNvbXBhcmlzb24gb3BlcmF0aW9uIHdhcwotICAgICAgICAgKiBub3QgcmVjb2duaXplZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTExFR0FMX1JFTEFUX09QX0VSUiwKLSAgICAgICAgIlVua25vd24gb3BlcmF0b3IgZm9yIHJlbGF0aW9uYWwgZXhwcmVzc2lvbiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBbiBhdHRyaWJ1dGUgc2V0IGRlZmluZXMgYXMgYSBzZXQgb2YgWE1MCi0gICAgICAgICAqIGF0dHJpYnV0ZXMgdGhhdCBjYW4gYmUgYWRkZWQgdG8gYW4gZWxlbWVudCBpbiB0aGUgb3V0cHV0IFhNTCBkb2N1bWVudAotICAgICAgICAgKiBhcyBhIGdyb3VwLiAgVGhpcyBtZXNzYWdlIGlzIHJlcG9ydGVkIGlmIHRoZSBuYW1lIHNwZWNpZmllZCB3YXMgbm90Ci0gICAgICAgICAqIHVzZWQgdG8gZGVjbGFyZSBhbiBhdHRyaWJ1dGUgc2V0LiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lCi0gICAgICAgICAqIHRoYXQgaXMgaW4gZXJyb3IuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuQVRUUklCU0VUX1VOREVGX0VSUiwKLSAgICAgICAgIkF0dGVtcHRpbmcgdG8gdXNlIG5vbi1leGlzdGluZyBhdHRyaWJ1dGUgc2V0ICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSB0ZXJtICJhdHRyaWJ1dGUgdmFsdWUgdGVtcGxhdGUiIGlzIGEgdGVybQotICAgICAgICAgKiBkZWZpbmVkIGJ5IFhTTFQgd2hpY2ggZGVzY3JpYmVzIHRoZSB2YWx1ZSBvZiBhbiBhdHRyaWJ1dGUgdGhhdCBpcwotICAgICAgICAgKiBkZXRlcm1pbmVkIGJ5IGFuIFhQYXRoIGV4cHJlc3Npb24uICBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUKLSAgICAgICAgICogZXhwcmVzc2lvbiB3YXMgc3ludGFjdGljYWxseSBpbmNvcnJlY3Q7IHRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICAgKiBjb250YWlucyB0aGUgZXhwcmVzc2lvbiB0aGF0IHdhcyBpbiBlcnJvci4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5BVFRSX1ZBTF9URU1QTEFURV9FUlIsCi0gICAgICAgICJDYW5ub3QgcGFyc2UgYXR0cmlidXRlIHZhbHVlIHRlbXBsYXRlICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogID8/PwotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlVOS05PV05fU0lHX1RZUEVfRVJSLAotICAgICAgICAiVW5rbm93biBkYXRhLXR5cGUgaW4gc2lnbmF0dXJlIGZvciBjbGFzcyAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgcmVmZXJzIHRvIGRhdGEgdHlwZXMuCi0gICAgICAgICAqIFRoZSBtZXNzYWdlIGlzIGRpc3BsYXllZCBpZiBhIHZhbHVlIGluIGEgcGFydGljdWxhciBjb250ZXh0IG5lZWRzIHRvCi0gICAgICAgICAqIGJlIGNvbnZlcnRlZCB0byB0eXBlIHsxfSwgYnV0IHRoYXQncyBub3QgcG9zc2libGUgZm9yIGEgdmFsdWUgb2YKLSAgICAgICAgICogdHlwZSB7MH0uCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuREFUQV9DT05WRVJTSU9OX0VSUiwKLSAgICAgICAgIkNhbm5vdCBjb252ZXJ0IGRhdGEtdHlwZSAnJ3swfScnIHRvICcnezF9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJUZW1wbGF0ZXMiIGlzIGEgSmF2YSBjbGFzcyBuYW1lIHRoYXQgc2hvdWxkCi0gICAgICAgICAqIG5vdCBiZSB0cmFuc2xhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk5PX1RSQU5TTEVUX0NMQVNTX0VSUiwKLSAgICAgICAgIlRoaXMgVGVtcGxhdGVzIGRvZXMgbm90IGNvbnRhaW4gYSB2YWxpZCB0cmFuc2xldCBjbGFzcyBkZWZpbml0aW9uLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiVGVtcGxhdGVzIiBpcyBhIEphdmEgY2xhc3MgbmFtZSB0aGF0IHNob3VsZAotICAgICAgICAgKiBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5OT19NQUlOX1RSQU5TTEVUX0VSUiwKLSAgICAgICAgIlRoaXMgVGVtcGxhdGVzIGRvZXMgbm90IGNvbnRhaW4gYSBjbGFzcyB3aXRoIHRoZSBuYW1lICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBhIGNsYXNzLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlRSQU5TTEVUX0NMQVNTX0VSUiwKLSAgICAgICAgIkNvdWxkIG5vdCBsb2FkIHRoZSB0cmFuc2xldCBjbGFzcyAnJ3swfScnLiJ9LAotCi0gICAgICAgIHtFcnJvck1zZy5UUkFOU0xFVF9PQkpFQ1RfRVJSLAotICAgICAgICAiVHJhbnNsZXQgY2xhc3MgbG9hZGVkLCBidXQgdW5hYmxlIHRvIGNyZWF0ZSB0cmFuc2xldCBpbnN0YW5jZS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIkVycm9yTGlzdGVuZXIiIGlzIGEgSmF2YSBpbnRlcmZhY2UgbmFtZSB0aGF0Ci0gICAgICAgICAqIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoZSBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoZSB1c2VyIHRyaWVkCi0gICAgICAgICAqIHRvIHNldCBhbiBFcnJvckxpc3RlbmVyIG9iamVjdCBvbiBvYmplY3Qgb2YgdGhlIGNsYXNzIG5hbWVkIGluIHRoZQotICAgICAgICAgKiBzdWJzdGl0dXRpb24gdGV4dCB3aXRoICJudWxsIiBKYXZhIHZhbHVlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkVSUk9SX0xJU1RFTkVSX05VTExfRVJSLAotICAgICAgICAiQXR0ZW1wdGluZyB0byBzZXQgRXJyb3JMaXN0ZW5lciBmb3IgJyd7MH0nJyB0byBudWxsIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFN0cmVhbVNvdXJjZSwgU0FYU291cmNlIGFuZCBET01Tb3VyY2UgYXJlIEphdmEKLSAgICAgICAgICogaW50ZXJmYWNlIG5hbWVzIHRoYXQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfVU5LTk9XTl9TT1VSQ0VfRVJSLAotICAgICAgICAiT25seSBTdHJlYW1Tb3VyY2UsIFNBWFNvdXJjZSBhbmQgRE9NU291cmNlIGFyZSBzdXBwb3J0ZWQgYnkgWFNMVEMifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIlNvdXJjZSIgaXMgYSBKYXZhIGNsYXNzIG5hbWUgdGhhdCBzaG91bGQgbm90Ci0gICAgICAgICAqIGJlIHRyYW5zbGF0ZWQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgSmF2YSBtZXRob2QuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSkFYUF9OT19TT1VSQ0VfRVJSLAotICAgICAgICAiU291cmNlIG9iamVjdCBwYXNzZWQgdG8gJyd7MH0nJyBoYXMgbm8gY29udGVudHMuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBtZXNzYWdlIGluZGljYXRlcyB0aGF0IFhTTFRDIGZhaWxlZCB0bwotICAgICAgICAgKiBjb21waWxlIHRoZSBzdHlsZXNoZWV0IGludG8gYSB0cmFuc2xldCAoY2xhc3MgZmlsZSkuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSkFYUF9DT01QSUxFX0VSUiwKLSAgICAgICAgIkNvdWxkIG5vdCBjb21waWxlIHN0eWxlc2hlZXQifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIlRyYW5zZm9ybWVyRmFjdG9yeSIgaXMgYSBjbGFzcyBuYW1lLiAgSW4gdGhpcwotICAgICAgICAgKiBjb250ZXh0LCBhbiBhdHRyaWJ1dGUgaXMgYSBwcm9wZXJ0eSBvciBzZXR0aW5nIG9mIHRoZQotICAgICAgICAgKiBUcmFuc2Zvcm1lckZhY3Rvcnkgb2JqZWN0LiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIHRoZQotICAgICAgICAgKiB1bnJlY29nbmlzZWQgYXR0cmlidXRlLiAgVGhlIG1ldGhvZCB1c2VkIHRvIHJldHJpZXZlIHRoZSBhdHRyaWJ1dGUgaXMKLSAgICAgICAgICogImdldEF0dHJpYnV0ZSIsIHNvIGl0J3Mgbm90IGNsZWFyIHdoZXRoZXIgaXQgd291bGQgYmUgYmVzdCB0bwotICAgICAgICAgKiB0cmFuc2xhdGUgdGhlIHRlcm0gImF0dHJpYnV0ZSIuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSkFYUF9JTlZBTElEX0FUVFJfRVJSLAotICAgICAgICAiVHJhbnNmb3JtZXJGYWN0b3J5IGRvZXMgbm90IHJlY29nbmlzZSBhdHRyaWJ1dGUgJyd7MH0nJy4ifSwKLQotICAgICAgICB7RXJyb3JNc2cuSkFYUF9JTlZBTElEX0FUVFJfVkFMVUVfRVJSLAotICAgICAgICAiSW5jb3JyZWN0IHZhbHVlIHNwZWNpZmllZCBmb3IgJyd7MH0nJyBhdHRyaWJ1dGUuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJzZXRSZXN1bHQoKSIgYW5kICJzdGFydERvY3VtZW50KCkiIGFyZSBKYXZhCi0gICAgICAgICAqIG1ldGhvZCBuYW1lcyB0aGF0IHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX1NFVF9SRVNVTFRfRVJSLAotICAgICAgICAic2V0UmVzdWx0KCkgbXVzdCBiZSBjYWxsZWQgcHJpb3IgdG8gc3RhcnREb2N1bWVudCgpLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiVHJhbnNmb3JtZXIiIGlzIGEgSmF2YSBpbnRlcmZhY2UgbmFtZSB0aGF0Ci0gICAgICAgICAqIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIEEgVHJhbnNmb3JtZXIgb2JqZWN0IHNob3VsZCBjb250YWluZWQgYQotICAgICAgICAgKiByZWZlcmVuY2UgdG8gYSB0cmFuc2xldCBvYmplY3QgaW4gb3JkZXIgdG8gYmUgdXNlZCBmb3IKLSAgICAgICAgICogdHJhbnNmb3JtYXRpb25zOyB0aGlzIG1lc3NhZ2UgaXMgcHJvZHVjZWQgaWYgdGhhdCByZXF1aXJlbWVudCBpcyBub3QKLSAgICAgICAgICogbWV0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfTk9fVFJBTlNMRVRfRVJSLAotICAgICAgICAiVGhlIFRyYW5zZm9ybWVyIGhhcyBubyBlbmNhcHN1bGF0ZWQgdHJhbnNsZXQgb2JqZWN0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgWE1MIGRvY3VtZW50IHRoYXQgcmVzdWx0cyBmcm9tIGEKLSAgICAgICAgICogdHJhbnNmb3JtYXRpb24gbmVlZHMgdG8gYmUgc2VudCB0byBhbiBvdXRwdXQgaGFuZGxlciBvYmplY3Q7IHRoaXMKLSAgICAgICAgICogbWVzc2FnZSBpcyBwcm9kdWNlZCBpZiB0aGF0IHJlcXVpcmVtZW50IGlzIG5vdCBtZXQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSkFYUF9OT19IQU5ETEVSX0VSUiwKLSAgICAgICAgIk5vIGRlZmluZWQgb3V0cHV0IGhhbmRsZXIgZm9yIHRyYW5zZm9ybWF0aW9uIHJlc3VsdC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIlJlc3VsdCIgaXMgYSBKYXZhIGludGVyZmFjZSBuYW1lIGluIHRoaXMKLSAgICAgICAgICogY29udGV4dC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyBhIG1ldGhvZCBuYW1lLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfTk9fUkVTVUxUX0VSUiwKLSAgICAgICAgIlJlc3VsdCBvYmplY3QgcGFzc2VkIHRvICcnezB9JycgaXMgaW52YWxpZC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIlRyYW5zZm9ybWVyIiBpcyBhIEphdmEgaW50ZXJmYWNlIG5hbWUuICBUaGUKLSAgICAgICAgICogdXNlcidzIHByb2dyYW0gYXR0ZW1wdGVkIHRvIGFjY2VzcyBhbiB1bnJlY29nbml6ZWQgcHJvcGVydHkgd2l0aCB0aGUKLSAgICAgICAgICogbmFtZSBzcGVjaWZpZWQgaW4gdGhlIHN1YnN0aXR1dGlvbiB0ZXh0LiAgVGhlIG1ldGhvZCB1c2VkIHRvIHJldHJpZXZlCi0gICAgICAgICAqIHRoZSBwcm9wZXJ0eSBpcyAiZ2V0T3V0cHV0UHJvcGVydHkiLCBzbyBpdCdzIG5vdCBjbGVhciB3aGV0aGVyIGl0Ci0gICAgICAgICAqIHdvdWxkIGJlIGJlc3QgdG8gdHJhbnNsYXRlIHRoZSB0ZXJtICJwcm9wZXJ0eSIuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSkFYUF9VTktOT1dOX1BST1BfRVJSLAotICAgICAgICAiQXR0ZW1wdGluZyB0byBhY2Nlc3MgaW52YWxpZCBUcmFuc2Zvcm1lciBwcm9wZXJ0eSAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBTQVgyRE9NIGlzIHRoZSBuYW1lIG9mIGEgSmF2YSBjbGFzcyB0aGF0IHNob3VsZAotICAgICAgICAgKiBub3QgYmUgdHJhbnNsYXRlZC4gIFRoaXMgaXMgYW4gYWRhcHRlciBpbiB0aGUgc2Vuc2UgdGhhdCBpdCB0YWtlcyBhCi0gICAgICAgICAqIERPTSBvYmplY3QgYW5kIGNvbnZlcnRzIGl0IHRvIHNvbWV0aGluZyB0aGF0IHVzZXMgdGhlIFNBWCBBUEkuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuU0FYMkRPTV9BREFQVEVSX0VSUiwKLSAgICAgICAgIkNvdWxkIG5vdCBjcmVhdGUgU0FYMkRPTSBhZGFwdGVyOiAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiWFNMVENTb3VyY2UuYnVpbGQoKSIgaXMgYSBKYXZhIG1ldGhvZCBuYW1lLgotICAgICAgICAgKiAic3lzdGVtSWQiIGlzIGFuIFhNTCB0ZXJtIHRoYXQgaXMgc2hvcnQgZm9yICJzeXN0ZW0gaWRlbnRpZmljYXRpb24iLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlhTTFRDX1NPVVJDRV9FUlIsCi0gICAgICAgICJYU0xUQ1NvdXJjZS5idWlsZCgpIGNhbGxlZCB3aXRob3V0IHN5c3RlbUlkIGJlaW5nIHNldC4ifSwKLQotICAgICAgICB7IEVycm9yTXNnLkVSX1JFU1VMVF9OVUxMLAotICAgICAgICAgICAgIlJlc3VsdCBzaG91bGQgbm90IGJlIG51bGwifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoZSB2YWx1ZSBhcmd1bWVudAotICAgICAgICAgKiBvZiBzZXRQYXJhbWV0ZXIgbXVzdCBiZSBhIHZhbGlkIEphdmEgT2JqZWN0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfSU5WQUxJRF9TRVRfUEFSQU1fVkFMVUUsCi0gICAgICAgICJUaGUgdmFsdWUgb2YgcGFyYW0gezB9IG11c3QgYmUgYSB2YWxpZCBKYXZhIE9iamVjdCJ9LAotCi0KLSAgICAgICAge0Vycm9yTXNnLkNPTVBJTEVfU1RESU5fRVJSLAotICAgICAgICAiVGhlIC1pIG9wdGlvbiBtdXN0IGJlIHVzZWQgd2l0aCB0aGUgLW8gb3B0aW9uLiJ9LAotCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBjb250YWlucyB1c2FnZSBpbmZvcm1hdGlvbiBmb3IgYQotICAgICAgICAgKiBtZWFucyBvZiBpbnZva2luZyBYU0xUQyBmcm9tIHRoZSBjb21tYW5kLWxpbmUuICBUaGUgbWVzc2FnZSBpcwotICAgICAgICAgKiBmb3JtYXR0ZWQgZm9yIHByZXNlbnRhdGlvbiBpbiBFbmdsaXNoLiAgVGhlIHN0cmluZ3MgPG91dHB1dD4sCi0gICAgICAgICAqIDxkaXJlY3Rvcnk+LCBldGMuIGluZGljYXRlIHVzZXItc3BlY2lmaWVkIGFyZ3VtZW50IHZhbHVlcywgYW5kIGNhbgotICAgICAgICAgKiBiZSB0cmFuc2xhdGVkIC0gdGhlIGFyZ3VtZW50IDxwYWNrYWdlPiByZWZlcnMgdG8gYSBKYXZhIHBhY2thZ2UsIHNvCi0gICAgICAgICAqIGl0IHNob3VsZCBiZSBoYW5kbGVkIGluIHRoZSBzYW1lIHdheSB0aGUgdGVybSBpcyBoYW5kbGVkIGZvciBKREsKLSAgICAgICAgICogZG9jdW1lbnRhdGlvbi4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5DT01QSUxFX1VTQUdFX1NUUiwKLSAgICAgICAgIlNZTk9QU0lTXG4iKwotICAgICAgICAiICAgamF2YSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY21kbGluZS5Db21waWxlIFstbyA8b3V0cHV0Pl1cbiIrCi0gICAgICAgICIgICAgICBbLWQgPGRpcmVjdG9yeT5dIFstaiA8amFyZmlsZT5dIFstcCA8cGFja2FnZT5dXG4iKwotICAgICAgICAiICAgICAgWy1uXSBbLXhdIFstdV0gWy12XSBbLWhdIHsgPHN0eWxlc2hlZXQ+IHwgLWkgfVxuXG4iKwotICAgICAgICAiT1BUSU9OU1xuIisKLSAgICAgICAgIiAgIC1vIDxvdXRwdXQ+ICAgIGFzc2lnbnMgdGhlIG5hbWUgPG91dHB1dD4gdG8gdGhlIGdlbmVyYXRlZFxuIisKLSAgICAgICAgIiAgICAgICAgICAgICAgICAgIHRyYW5zbGV0LiAgQnkgZGVmYXVsdCB0aGUgdHJhbnNsZXQgbmFtZSBpc1xuIisKLSAgICAgICAgIiAgICAgICAgICAgICAgICAgIGRlcml2ZWQgZnJvbSB0aGUgPHN0eWxlc2hlZXQ+IG5hbWUuICBUaGlzIG9wdGlvblxuIisKLSAgICAgICAgIiAgICAgICAgICAgICAgICAgIGlzIGlnbm9yZWQgaWYgY29tcGlsaW5nIG11bHRpcGxlIHN0eWxlc2hlZXRzLlxuIisKLSAgICAgICAgIiAgIC1kIDxkaXJlY3Rvcnk+IHNwZWNpZmllcyBhIGRlc3RpbmF0aW9uIGRpcmVjdG9yeSBmb3IgdHJhbnNsZXRcbiIrCi0gICAgICAgICIgICAtaiA8amFyZmlsZT4gICBwYWNrYWdlcyB0cmFuc2xldCBjbGFzc2VzIGludG8gYSBqYXIgZmlsZSBvZiB0aGVcbiIrCi0gICAgICAgICIgICAgICAgICAgICAgICAgICBuYW1lIHNwZWNpZmllZCBhcyA8amFyZmlsZT5cbiIrCi0gICAgICAgICIgICAtcCA8cGFja2FnZT4gICBzcGVjaWZpZXMgYSBwYWNrYWdlIG5hbWUgcHJlZml4IGZvciBhbGwgZ2VuZXJhdGVkXG4iKwotICAgICAgICAiICAgICAgICAgICAgICAgICAgdHJhbnNsZXQgY2xhc3Nlcy5cbiIrCi0gICAgICAgICIgICAtbiAgICAgICAgICAgICBlbmFibGVzIHRlbXBsYXRlIGlubGluaW5nIChkZWZhdWx0IGJlaGF2aW9yIGJldHRlclxuIisKLSAgICAgICAgIiAgICAgICAgICAgICAgICAgIG9uIGF2ZXJhZ2UpLlxuIisKLSAgICAgICAgIiAgIC14ICAgICAgICAgICAgIHR1cm5zIG9uIGFkZGl0aW9uYWwgZGVidWdnaW5nIG1lc3NhZ2Ugb3V0cHV0XG4iKwotICAgICAgICAiICAgLXUgICAgICAgICAgICAgaW50ZXJwcmV0cyA8c3R5bGVzaGVldD4gYXJndW1lbnRzIGFzIFVSTHNcbiIrCi0gICAgICAgICIgICAtaSAgICAgICAgICAgICBmb3JjZXMgY29tcGlsZXIgdG8gcmVhZCBzdHlsZXNoZWV0IGZyb20gc3RkaW5cbiIrCi0gICAgICAgICIgICAtdiAgICAgICAgICAgICBwcmludHMgdGhlIHZlcnNpb24gb2YgdGhlIGNvbXBpbGVyXG4iKwotICAgICAgICAiICAgLWggICAgICAgICAgICAgcHJpbnRzIHRoaXMgdXNhZ2Ugc3RhdGVtZW50XG4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGNvbnRhaW5zIHVzYWdlIGluZm9ybWF0aW9uIGZvciBhCi0gICAgICAgICAqIG1lYW5zIG9mIGludm9raW5nIFhTTFRDIGZyb20gdGhlIGNvbW1hbmQtbGluZS4gIFRoZSBtZXNzYWdlIGlzCi0gICAgICAgICAqIGZvcm1hdHRlZCBmb3IgcHJlc2VudGF0aW9uIGluIEVuZ2xpc2guICBUaGUgc3RyaW5ncyA8amFyZmlsZT4sCi0gICAgICAgICAqIDxkb2N1bWVudD4sIGV0Yy4gaW5kaWNhdGUgdXNlci1zcGVjaWZpZWQgYXJndW1lbnQgdmFsdWVzLCBhbmQgY2FuCi0gICAgICAgICAqIGJlIHRyYW5zbGF0ZWQgLSB0aGUgYXJndW1lbnQgPGNsYXNzPiByZWZlcnMgdG8gYSBKYXZhIGNsYXNzLCBzbyBpdAotICAgICAgICAgKiBzaG91bGQgYmUgaGFuZGxlZCBpbiB0aGUgc2FtZSB3YXkgdGhlIHRlcm0gaXMgaGFuZGxlZCBmb3IgSkRLCi0gICAgICAgICAqIGRvY3VtZW50YXRpb24uCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVFJBTlNGT1JNX1VTQUdFX1NUUiwKLSAgICAgICAgIlNZTk9QU0lTIFxuIisKLSAgICAgICAgIiAgIGphdmEgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNtZGxpbmUuVHJhbnNmb3JtIFstaiA8amFyZmlsZT5dXG4iKwotICAgICAgICAiICAgICAgWy14XSBbLW4gPGl0ZXJhdGlvbnM+XSB7LXUgPGRvY3VtZW50X3VybD4gfCA8ZG9jdW1lbnQ+fVxuIisKLSAgICAgICAgIiAgICAgIDxjbGFzcz4gWzxwYXJhbTE+PTx2YWx1ZTE+IC4uLl1cblxuIisKLSAgICAgICAgIiAgIHVzZXMgdGhlIHRyYW5zbGV0IDxjbGFzcz4gdG8gdHJhbnNmb3JtIGFuIFhNTCBkb2N1bWVudCBcbiIrCi0gICAgICAgICIgICBzcGVjaWZpZWQgYXMgPGRvY3VtZW50Pi4gVGhlIHRyYW5zbGV0IDxjbGFzcz4gaXMgZWl0aGVyIGluXG4iKwotICAgICAgICAiICAgdGhlIHVzZXIncyBDTEFTU1BBVEggb3IgaW4gdGhlIG9wdGlvbmFsbHkgc3BlY2lmaWVkIDxqYXJmaWxlPi5cbiIrCi0gICAgICAgICJPUFRJT05TXG4iKwotICAgICAgICAiICAgLWogPGphcmZpbGU+ICAgIHNwZWNpZmllcyBhIGphcmZpbGUgZnJvbSB3aGljaCB0byBsb2FkIHRyYW5zbGV0XG4iKwotICAgICAgICAiICAgLXggICAgICAgICAgICAgIHR1cm5zIG9uIGFkZGl0aW9uYWwgZGVidWdnaW5nIG1lc3NhZ2Ugb3V0cHV0XG4iKwotICAgICAgICAiICAgLW4gPGl0ZXJhdGlvbnM+IHJ1bnMgdGhlIHRyYW5zZm9ybWF0aW9uIDxpdGVyYXRpb25zPiB0aW1lcyBhbmRcbiIrCi0gICAgICAgICIgICAgICAgICAgICAgICAgICAgZGlzcGxheXMgcHJvZmlsaW5nIGluZm9ybWF0aW9uXG4iKwotICAgICAgICAiICAgLXUgPGRvY3VtZW50X3VybD4gc3BlY2lmaWVzIFhNTCBpbnB1dCBkb2N1bWVudCBhcyBhIFVSTFxuIn0sCi0KLQotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiPHhzbDpzb3J0PiIsICI8eHNsOmZvci1lYWNoPiIgYW5kCi0gICAgICAgICAqICI8eHNsOmFwcGx5LXRlbXBsYXRlcz4iIGFyZSBrZXl3b3JkcyB0aGF0IHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICAgICAgICogVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgYW4geHNsOnNvcnQgZWxlbWVudCBtdXN0IGJlIGEgY2hpbGQgb2YKLSAgICAgICAgICogb25lIG9mIHRoZSBvdGhlciBraW5kcyBvZiBlbGVtZW50cyBtZW50aW9uZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuU1RSQVlfU09SVF9FUlIsCi0gICAgICAgICI8eHNsOnNvcnQ+IGNhbiBvbmx5IGJlIHVzZWQgd2l0aGluIDx4c2w6Zm9yLWVhY2g+IG9yIDx4c2w6YXBwbHktdGVtcGxhdGVzPi4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhlIGVuY29kaW5nCi0gICAgICAgICAqIHJlcXVlc3RlZCBmb3IgdGhlIG91dHB1dCBkb2N1bWVudCB3YXMgb24gdGhhdCByZXF1aXJlcyBzdXBwb3J0IHRoYXQKLSAgICAgICAgICogaXMgbm90IGF2YWlsYWJsZSBmcm9tIHRoZSBKYXZhIFZpcnR1YWwgTWFjaGluZSBiZWluZyB1c2VkIHRvIGV4ZWN1dGUKLSAgICAgICAgICogdGhlIHByb2dyYW0uCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVU5TVVBQT1JURURfRU5DT0RJTkcsCi0gICAgICAgICJPdXRwdXQgZW5jb2RpbmcgJyd7MH0nJyBpcyBub3Qgc3VwcG9ydGVkIG9uIHRoaXMgSlZNLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUgWFBhdGggZXhwcmVzc2lvbgotICAgICAgICAgKiBuYW1lZCBpbiB0aGUgc3Vic3RpdHV0aW9uIHRleHQgd2FzIG5vdCB3ZWxsIGZvcm1lZCBzeW50YWN0aWNhbGx5LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlNZTlRBWF9FUlIsCi0gICAgICAgICJTeW50YXggZXJyb3IgaW4gJyd7MH0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIGEgSmF2YQotICAgICAgICAgKiBjbGFzcy4gIFRoZSB0ZXJtICJjb25zdHJ1Y3RvciIgaGVyZSBpcyB0aGUgSmF2YSB0ZXJtLiAgVGhlIG1lc3NhZ2UgaXMKLSAgICAgICAgICogZGlzcGxheWVkIGlmIFhTTFRDIGNvdWxkIG5vdCBmaW5kIGEgY29uc3RydWN0b3IgZm9yIHRoZSBzcGVjaWZpZWQKLSAgICAgICAgICogY2xhc3MuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuQ09OU1RSVUNUT1JfTk9UX0ZPVU5ELAotICAgICAgICAiQ2Fubm90IGZpbmQgZXh0ZXJuYWwgY29uc3RydWN0b3IgJyd7MH0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgInN0YXRpYyIgaXMgdGhlIEphdmEga2V5d29yZC4gIFRoZSBzdWJzdGl0dXRpb24KLSAgICAgICAgICogdGV4dCBpcyB0aGUgbmFtZSBvZiBhIGZ1bmN0aW9uLiAgVGhlIGZpcnN0IGFyZ3VtZW50IG9mIHRoYXQgZnVuY3Rpb24KLSAgICAgICAgICogaXMgbm90IG9mIHRoZSByZXF1aXJlZCB0eXBlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk5PX0pBVkFfRlVOQ1RfVEhJU19SRUYsCi0gICAgICAgICJUaGUgZmlyc3QgYXJndW1lbnQgdG8gdGhlIG5vbi1zdGF0aWMgSmF2YSBmdW5jdGlvbiAnJ3swfScnIGlzIG5vdCBhICIrCi0gICAgICAgICJ2YWxpZCBvYmplY3QgcmVmZXJlbmNlLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBbiBYUGF0aCBleHByZXNzaW9uIHdhcyBub3Qgb2YgdGhlIHR5cGUKLSAgICAgICAgICogcmVxdWlyZWQgaW4gYSBwYXJ0aWN1bGFyIGNvbnRleHQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlCi0gICAgICAgICAqIGV4cHJlc3Npb24gdGhhdCB3YXMgaW4gZXJyb3IuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVFlQRV9DSEVDS19FUlIsCi0gICAgICAgICJFcnJvciBjaGVja2luZyB0eXBlIG9mIHRoZSBleHByZXNzaW9uICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIFhQYXRoIGV4cHJlc3Npb24gd2FzIG5vdCBvZiB0aGUgdHlwZQotICAgICAgICAgKiByZXF1aXJlZCBpbiBhIHBhcnRpY3VsYXIgY29udGV4dC4gIEhvd2V2ZXIsIHRoZSBsb2NhdGlvbiBvZiB0aGUKLSAgICAgICAgICogcHJvYmxlbWF0aWMgZXhwcmVzc2lvbiBpcyB1bmtub3duLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlRZUEVfQ0hFQ0tfVU5LX0xPQ19FUlIsCi0gICAgICAgICJFcnJvciBjaGVja2luZyB0eXBlIG9mIGFuIGV4cHJlc3Npb24gYXQgYW4gdW5rbm93biBsb2NhdGlvbi4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIGEgY29tbWFuZC0KLSAgICAgICAgICogbGluZSBvcHRpb24gdGhhdCB3YXMgbm90IHJlY29nbml6ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSUxMRUdBTF9DTURMSU5FX09QVElPTl9FUlIsCi0gICAgICAgICJUaGUgY29tbWFuZC1saW5lIG9wdGlvbiAnJ3swfScnIGlzIG5vdCB2YWxpZC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIGEgY29tbWFuZC0KLSAgICAgICAgICogbGluZSBvcHRpb24uCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuQ01ETElORV9PUFRfTUlTU0lOR19BUkdfRVJSLAotICAgICAgICAiVGhlIGNvbW1hbmQtbGluZSBvcHRpb24gJyd7MH0nJyBpcyBtaXNzaW5nIGEgcmVxdWlyZWQgYXJndW1lbnQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyB1c2VkIHRvIGluZGljYXRlIHRoZSBzZXZlcml0eQotICAgICAgICAgKiBvZiBhbm90aGVyIG1lc3NhZ2UuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgY29udGFpbnMgdHdvIGVycm9yCi0gICAgICAgICAqIG1lc3NhZ2VzLiAgVGhlIHNwYWNpbmcgYmVmb3JlIHRoZSBzZWNvbmQgc3Vic3RpdHV0aW9uIHRleHQgaW5kZW50cwotICAgICAgICAgKiBpdCB0aGUgc2FtZSBhbW91bnQgYXMgdGhlIGZpcnN0IGluIEVuZ2xpc2guCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuV0FSTklOR19QTFVTX1dSQVBQRURfTVNHLAotICAgICAgICAiV0FSTklORzogICcnezB9JydcbiAgICAgICA6ezF9In0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyB1c2VkIHRvIGluZGljYXRlIHRoZSBzZXZlcml0eQotICAgICAgICAgKiBvZiBhbm90aGVyIG1lc3NhZ2UuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgYW4gZXJyb3IgbWVzc2FnZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5XQVJOSU5HX01TRywKLSAgICAgICAgIldBUk5JTkc6ICAnJ3swfScnIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyB1c2VkIHRvIGluZGljYXRlIHRoZSBzZXZlcml0eQotICAgICAgICAgKiBvZiBhbm90aGVyIG1lc3NhZ2UuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgY29udGFpbnMgdHdvIGVycm9yCi0gICAgICAgICAqIG1lc3NhZ2VzLiAgVGhlIHNwYWNpbmcgYmVmb3JlIHRoZSBzZWNvbmQgc3Vic3RpdHV0aW9uIHRleHQgaW5kZW50cwotICAgICAgICAgKiBpdCB0aGUgc2FtZSBhbW91bnQgYXMgdGhlIGZpcnN0IGluIEVuZ2xpc2guCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuRkFUQUxfRVJSX1BMVVNfV1JBUFBFRF9NU0csCi0gICAgICAgICJGQVRBTCBFUlJPUjogICcnezB9JydcbiAgICAgICAgICAgOnsxfSJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgdXNlZCB0byBpbmRpY2F0ZSB0aGUgc2V2ZXJpdHkKLSAgICAgICAgICogb2YgYW5vdGhlciBtZXNzYWdlLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIGFuIGVycm9yIG1lc3NhZ2UuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuRkFUQUxfRVJSX01TRywKLSAgICAgICAgIkZBVEFMIEVSUk9SOiAgJyd7MH0nJyJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgdXNlZCB0byBpbmRpY2F0ZSB0aGUgc2V2ZXJpdHkKLSAgICAgICAgICogb2YgYW5vdGhlciBtZXNzYWdlLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGNvbnRhaW5zIHR3byBlcnJvcgotICAgICAgICAgKiBtZXNzYWdlcy4gIFRoZSBzcGFjaW5nIGJlZm9yZSB0aGUgc2Vjb25kIHN1YnN0aXR1dGlvbiB0ZXh0IGluZGVudHMKLSAgICAgICAgICogaXQgdGhlIHNhbWUgYW1vdW50IGFzIHRoZSBmaXJzdCBpbiBFbmdsaXNoLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkVSUk9SX1BMVVNfV1JBUFBFRF9NU0csCi0gICAgICAgICJFUlJPUjogICcnezB9JydcbiAgICAgOnsxfSJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgdXNlZCB0byBpbmRpY2F0ZSB0aGUgc2V2ZXJpdHkKLSAgICAgICAgICogb2YgYW5vdGhlciBtZXNzYWdlLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIGFuIGVycm9yIG1lc3NhZ2UuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuRVJST1JfTVNHLAotICAgICAgICAiRVJST1I6ICAnJ3swfScnIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBhIGNsYXNzLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlRSQU5TRk9STV9XSVRIX1RSQU5TTEVUX1NUUiwKLSAgICAgICAgIlRyYW5zZm9ybSB1c2luZyB0cmFuc2xldCAnJ3swfScnICJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZmlyc3Qgc3Vic3RpdHV0aW9uIGlzIHRoZSBuYW1lIG9mIGEgY2xhc3MsCi0gICAgICAgICAqIHdoaWxlIHRoZSBzZWNvbmQgc3Vic3RpdHV0aW9uIGlzIHRoZSBuYW1lIG9mIGEgamFyIGZpbGUuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVFJBTlNGT1JNX1dJVEhfSkFSX1NUUiwKLSAgICAgICAgIlRyYW5zZm9ybSB1c2luZyB0cmFuc2xldCAnJ3swfScnIGZyb20gamFyIGZpbGUgJyd7MX0nJyJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiVHJhbnNmb3JtZXJGYWN0b3J5IiBpcyB0aGUgbmFtZSBvZiBhIEphdmEKLSAgICAgICAgICogaW50ZXJmYWNlIGFuZCBtdXN0IG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzCi0gICAgICAgICAqIHRoZSBuYW1lIG9mIHRoZSBjbGFzcyB0aGF0IGNvdWxkIG5vdCBiZSBpbnN0YW50aWF0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuQ09VTERfTk9UX0NSRUFURV9UUkFOU19GQUNULAotICAgICAgICAiQ291bGQgbm90IGNyZWF0ZSBhbiBpbnN0YW5jZSBvZiB0aGUgVHJhbnNmb3JtZXJGYWN0b3J5IGNsYXNzICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyBwcm9kdWNlZCB3aGVuIHRoZSB1c2VyCi0gICAgICAgICAqIHNwZWNpZmllZCBhIG5hbWUgZm9yIHRoZSB0cmFuc2xldCBjbGFzcyB0aGF0IGNvbnRhaW5zIGNoYXJhY3RlcnMKLSAgICAgICAgICogdGhhdCBhcmUgbm90IHBlcm1pdHRlZCBpbiBhIEphdmEgY2xhc3MgbmFtZS4gIFRoZSBzdWJzdGl0dXRpb24KLSAgICAgICAgICogdGV4dCAiezB9IiBzcGVjaWZpZXMgdGhlIG5hbWUgdGhlIHVzZXIgcmVxdWVzdGVkLCB3aGlsZSAiezF9IgotICAgICAgICAgKiBzcGVjaWZpZXMgdGhlIG5hbWUgdGhlIHByb2Nlc3NvciB1c2VkIGluc3RlYWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVFJBTlNMRVRfTkFNRV9KQVZBX0NPTkZMSUNULAotICAgICAgICAgIlRoZSBuYW1lICcnezB9JycgY291bGQgbm90IGJlIHVzZWQgYXMgdGhlIG5hbWUgb2YgdGhlIHRyYW5zbGV0ICIrCi0gICAgICAgICAiY2xhc3MgYmVjYXVzZSBpdCBjb250YWlucyBjaGFyYWN0ZXJzIHRoYXQgYXJlIG5vdCBwZXJtaXR0ZWQgaW4gdGhlICIrCi0gICAgICAgICAibmFtZSBvZiBKYXZhIGNsYXNzLiAgVGhlIG5hbWUgJyd7MX0nJyB3YXMgdXNlZCBpbnN0ZWFkLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgaXMgdXNlZCBhcyBhIGhlYWRlci4KLSAgICAgICAgICogQWxsIHRoZSBlcnJvciBtZXNzYWdlcyBhcmUgY29sbGVjdGVkIHRvZ2V0aGVyIGFuZCBkaXNwbGF5ZWQgYmVuZWF0aAotICAgICAgICAgKiB0aGlzIG1lc3NhZ2UuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuQ09NUElMRVJfRVJST1JfS0VZLAotICAgICAgICAiQ29tcGlsZXIgZXJyb3JzOiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgaXMgdXNlZCBhcyBhIGhlYWRlci4KLSAgICAgICAgICogQWxsIHRoZSB3YXJuaW5nIG1lc3NhZ2VzIGFyZSBjb2xsZWN0ZWQgdG9nZXRoZXIgYW5kIGRpc3BsYXllZAotICAgICAgICAgKiBiZW5lYXRoIHRoaXMgbWVzc2FnZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5DT01QSUxFUl9XQVJOSU5HX0tFWSwKLSAgICAgICAgIkNvbXBpbGVyIHdhcm5pbmdzOiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgaXMgdXNlZCBhcyBhIGhlYWRlci4KLSAgICAgICAgICogQWxsIHRoZSBlcnJvciBtZXNzYWdlcyB0aGF0IGFyZSBwcm9kdWNlZCB3aGVuIHRoZSBzdHlsZXNoZWV0IGlzCi0gICAgICAgICAqIGFwcGxpZWQgdG8gYW4gaW5wdXQgZG9jdW1lbnQgYXJlIGNvbGxlY3RlZCB0b2dldGhlciBhbmQgZGlzcGxheWVkCi0gICAgICAgICAqIGJlbmVhdGggdGhpcyBtZXNzYWdlLiAgQSAndHJhbnNsZXQnIGlzIHRoZSBjb21waWxlZCBmb3JtIG9mIGEKLSAgICAgICAgICogc3R5bGVzaGVldCAoc2VlIGFib3ZlKS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5SVU5USU1FX0VSUk9SX0tFWSwKLSAgICAgICAgIlRyYW5zbGV0IGVycm9yczoifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQW4gYXR0cmlidXRlIHdob3NlIHZhbHVlIGlzIGNvbnN0cmFpbmVkIHRvCi0gICAgICAgICAqIGJlIGEgIlFOYW1lIiBvciBhIGxpc3Qgb2YgIlFOYW1lcyIgaGFkIGEgdmFsdWUgdGhhdCB3YXMgaW5jb3JyZWN0LgotICAgICAgICAgKiAnUU5hbWUnIGlzIGFuIFhNTCBzeW50YWN0aWMgdGVybSB0aGF0IG11c3Qgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGUKLSAgICAgICAgICogc3Vic3RpdHV0aW9uIHRleHQgY29udGFpbnMgdGhlIGFjdHVhbCB2YWx1ZSBvZiB0aGUgYXR0cmlidXRlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklOVkFMSURfUU5BTUVfRVJSLAotICAgICAgICAiQW4gYXR0cmlidXRlIHdob3NlIHZhbHVlIG11c3QgYmUgYSBRTmFtZSBvciB3aGl0ZXNwYWNlLXNlcGFyYXRlZCBsaXN0IG9mIFFOYW1lcyBoYWQgdGhlIHZhbHVlICcnezB9JycifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQW4gYXR0cmlidXRlIHdob3NlIHZhbHVlIGlzIHJlcXVpcmVkIHRvCi0gICAgICAgICAqIGJlIGFuICJOQ05hbWUiLgotICAgICAgICAgKiAnTkNOYW1lJyBpcyBhbiBYTUwgc3ludGFjdGljIHRlcm0gdGhhdCBtdXN0IG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhlCi0gICAgICAgICAqIHN1YnN0aXR1dGlvbiB0ZXh0IGNvbnRhaW5zIHRoZSBhY3R1YWwgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTlZBTElEX05DTkFNRV9FUlIsCi0gICAgICAgICJBbiBhdHRyaWJ1dGUgd2hvc2UgdmFsdWUgbXVzdCBiZSBhbiBOQ05hbWUgaGFkIHRoZSB2YWx1ZSAnJ3swfScnIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIGF0dHJpYnV0ZSB3aXRoIGFuIGluY29ycmVjdCB2YWx1ZSB3YXMKLSAgICAgICAgICogZW5jb3VudGVyZWQuICBUaGUgcGVybWl0dGVkIHZhbHVlIGlzIG9uZSBvZiB0aGUgbGl0ZXJhbCB2YWx1ZXMKLSAgICAgICAgICogInhtbCIsICJodG1sIiBvciAidGV4dCI7IGl0IGlzIGFsc28gcGVybWl0dGVkIHRvIGhhdmUgdGhlIGZvcm0gb2YKLSAgICAgICAgICogYSBRTmFtZSB0aGF0IGlzIG5vdCBhbHNvIGFuIE5DTmFtZS4gIFRoZSB0ZXJtcyAibWV0aG9kIiwKLSAgICAgICAgICogInhzbDpvdXRwdXQiLCAieG1sIiwgImh0bWwiIGFuZCAidGV4dCIgYXJlIGtleXdvcmRzIHRoYXQgbXVzdCBub3QKLSAgICAgICAgICogYmUgdHJhbnNsYXRlZC4gIFRoZSB0ZXJtICJxbmFtZS1idXQtbm90LW5jbmFtZSIgaXMgYW4gWE1MIHN5bnRhY3RpYwotICAgICAgICAgKiB0ZXJtLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGNvbnRhaW5zIHRoZSBhY3R1YWwgdmFsdWUgb2YgdGhlCi0gICAgICAgICAqIGF0dHJpYnV0ZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTlZBTElEX01FVEhPRF9JTl9PVVRQVVQsCi0gICAgICAgICJUaGUgbWV0aG9kIGF0dHJpYnV0ZSBvZiBhbiA8eHNsOm91dHB1dD4gZWxlbWVudCBoYWQgdGhlIHZhbHVlICcnezB9JycuICBUaGUgdmFsdWUgbXVzdCBiZSBvbmUgb2YgJyd4bWwnJywgJydodG1sJycsICcndGV4dCcnLCBvciBxbmFtZS1idXQtbm90LW5jbmFtZSJ9LAotCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX0dFVF9GRUFUVVJFX05VTExfTkFNRSwKLSAgICAgICAgIlRoZSBmZWF0dXJlIG5hbWUgY2Fubm90IGJlIG51bGwgaW4gVHJhbnNmb3JtZXJGYWN0b3J5LmdldEZlYXR1cmUoU3RyaW5nIG5hbWUpLiJ9LAotCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX1NFVF9GRUFUVVJFX05VTExfTkFNRSwKLSAgICAgICAgIlRoZSBmZWF0dXJlIG5hbWUgY2Fubm90IGJlIG51bGwgaW4gVHJhbnNmb3JtZXJGYWN0b3J5LnNldEZlYXR1cmUoU3RyaW5nIG5hbWUsIGJvb2xlYW4gdmFsdWUpLiJ9LAotCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX1VOU1VQUE9SVEVEX0ZFQVRVUkUsCi0gICAgICAgICJDYW5ub3Qgc2V0IHRoZSBmZWF0dXJlICcnezB9Jycgb24gdGhpcyBUcmFuc2Zvcm1lckZhY3RvcnkuIn0sCi0KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfU0VDVVJFUFJPQ0VTU0lOR19GRUFUVVJFLAotICAgICAgICAiRkVBVFVSRV9TRUNVUkVfUFJPQ0VTU0lORzogQ2Fubm90IHNldCB0aGUgZmVhdHVyZSB0byBmYWxzZSB3aGVuIHNlY3VyaXR5IG1hbmFnZXIgaXMgcHJlc2VudC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGRlc2NyaWJlcyBhbiBpbnRlcm5hbCBlcnJvciBpbiB0aGUKLSAgICAgICAgICogcHJvY2Vzc29yLiAgVGhlIHRlcm0gImJ5dGUgY29kZSIgaXMgYSBKYXZhIHRlY2huaWNhbCB0ZXJtIGZvciB0aGUKLSAgICAgICAgICogZXhlY3V0YWJsZSBjb2RlIGluIGEgSmF2YSBtZXRob2QsIGFuZCAidHJ5LWNhdGNoLWZpbmFsbHkgYmxvY2siCi0gICAgICAgICAqIHJlZmVycyB0byB0aGUgSmF2YSBrZXl3b3JkcyB3aXRoIHRob3NlIG5hbWVzLiAgIk91dGxpbmVkIiBpcyBhCi0gICAgICAgICAqIHRlY2huaWNhbCB0ZXJtIGludGVybmFsIHRvIFhTTFRDIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuT1VUTElORV9FUlJfVFJZX0NBVENILAotICAgICAgICAgIkludGVybmFsIFhTTFRDIGVycm9yOiAgdGhlIGdlbmVyYXRlZCBieXRlIGNvZGUgY29udGFpbnMgYSAiICsKLSAgICAgICAgICJ0cnktY2F0Y2gtZmluYWxseSBibG9jayBhbmQgY2Fubm90IGJlIG91dGxpbmVkLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgZGVzY3JpYmVzIGFuIGludGVybmFsIGVycm9yIGluIHRoZQotICAgICAgICAgKiBwcm9jZXNzb3IuICBUaGUgdGVybXMgIk91dGxpbmVhYmxlQ2h1bmtTdGFydCIgYW5kCi0gICAgICAgICAqICJPdXRsaW5lYWJsZUNodW5rRW5kIiBhcmUgdGhlIG5hbWVzIG9mIGNsYXNzZXMgaW50ZXJuYWwgdG8gWFNMVEMgYW5kCi0gICAgICAgICAqIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoZSBtZXNzYWdlIGluZGljYXRlcyB0aGF0IGZvciBldmVyeQotICAgICAgICAgKiAic3RhcnQiIHRoZXJlIG11c3QgYmUgYSBjb3JyZXNwb25kaW5nICJlbmQiLCBhbmQgdmljZSB2ZXJzYSwgYW5kCi0gICAgICAgICAqIHRoYXQgaWYgb25lIG9mIGEgcGFpciBvZiAic3RhcnQiIGFuZCAiZW5kIiBhcHBlYXJzIGJldHdlZW4gYW5vdGhlcgotICAgICAgICAgKiBwYWlyIG9mIGNvcnJlc3BvbmRpbmcgInN0YXJ0IiBhbmQgImVuZCIsIHRoZW4gdGhlIG90aGVyIGhhbGYgb2YgdGhlCi0gICAgICAgICAqIHBhaXIgbXVzdCBhbHNvIGJlIGJldHdlZW4gdGhhdCBzYW1lIGVuY2xvc2luZyBwYWlyLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk9VVExJTkVfRVJSX1VOQkFMQU5DRURfTUFSS0VSUywKLSAgICAgICAgICJJbnRlcm5hbCBYU0xUQyBlcnJvcjogIE91dGxpbmVhYmxlQ2h1bmtTdGFydCBhbmQgIiArCi0gICAgICAgICAiT3V0bGluZWFibGVDaHVua0VuZCBtYXJrZXJzIG11c3QgYmUgYmFsYW5jZWQgYW5kIHByb3Blcmx5IG5lc3RlZC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGRlc2NyaWJlcyBhbiBpbnRlcm5hbCBlcnJvciBpbiB0aGUKLSAgICAgICAgICogcHJvY2Vzc29yLiAgVGhlIHRlcm0gImJ5dGUgY29kZSIgaXMgYSBKYXZhIHRlY2huaWNhbCB0ZXJtIGZvciB0aGUKLSAgICAgICAgICogZXhlY3V0YWJsZSBjb2RlIGluIGEgSmF2YSBtZXRob2QuICBUaGUgIm1ldGhvZCIgdGhhdCBpcyBiZWluZwotICAgICAgICAgKiByZWZlcnJlZCB0byBpcyBhIEphdmEgbWV0aG9kIGluIGEgdHJhbnNsZXQgdGhhdCBYU0xUQyBpcyBnZW5lcmF0aW5nCi0gICAgICAgICAqIGluIHByb2Nlc3NpbmcgYSBzdHlsZXNoZWV0LiAgVGhlICJpbnN0cnVjdGlvbiIgdGhhdCBpcyBiZWluZwotICAgICAgICAgKiByZWZlcnJlZCB0byBpcyBvbmUgb2YgdGhlIGluc3RydXRpb25zIGluIHRoZSBKYXZhIGJ5dGUgY29kZSBpbiB0aGF0Ci0gICAgICAgICAqIG1ldGhvZC4gICJPdXRsaW5lZCIgaXMgYSB0ZWNobmljYWwgdGVybSBpbnRlcm5hbCB0byBYU0xUQyBhbmQKLSAgICAgICAgICogc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk9VVExJTkVfRVJSX0RFTEVURURfVEFSR0VULAotICAgICAgICAgIkludGVybmFsIFhTTFRDIGVycm9yOiAgYW4gaW5zdHJ1Y3Rpb24gdGhhdCB3YXMgcGFydCBvZiBhIGJsb2NrIG9mICIgKwotICAgICAgICAgImJ5dGUgY29kZSB0aGF0IHdhcyBvdXRsaW5lZCBpcyBzdGlsbCByZWZlcnJlZCB0byBpbiB0aGUgb3JpZ2luYWwgIiArCi0gICAgICAgICAibWV0aG9kLiIKLSAgICAgICAgfSwKLQotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgZGVzY3JpYmVzIGFuIGludGVybmFsIGVycm9yIGluIHRoZQotICAgICAgICAgKiBwcm9jZXNzb3IuICBUaGUgIm1ldGhvZCIgdGhhdCBpcyBiZWluZyByZWZlcnJlZCB0byBpcyBhIEphdmEgbWV0aG9kCi0gICAgICAgICAqIGluIGEgdHJhbnNsZXQgdGhhdCBYU0xUQyBpcyBnZW5lcmF0aW5nLgotICAgICAgICAgKgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk9VVExJTkVfRVJSX01FVEhPRF9UT09fQklHLAotICAgICAgICAgIkludGVybmFsIFhTTFRDIGVycm9yOiAgYSBtZXRob2QgaW4gdGhlIHRyYW5zbGV0IGV4Y2VlZHMgdGhlIEphdmEgIiArCi0gICAgICAgICAiVmlydHVhbCBNYWNoaW5lIGxpbWl0YXRpb24gb24gdGhlIGxlbmd0aCBvZiBhIG1ldGhvZCBvZiA2NCAiICsKLSAgICAgICAgICJraWxvYnl0ZXMuICBUaGlzIGlzIHVzdWFsbHkgY2F1c2VkIGJ5IHRlbXBsYXRlcyBpbiBhIHN0eWxlc2hlZXQgIiArCi0gICAgICAgICAidGhhdCBhcmUgdmVyeSBsYXJnZS4gIFRyeSByZXN0cnVjdHVyaW5nIHlvdXIgc3R5bGVzaGVldCB0byB1c2UgIiArCi0gICAgICAgICAic21hbGxlciB0ZW1wbGF0ZXMuIgotICAgICAgICB9LAotCi0gICAgICAgICB7RXJyb3JNc2cuREVTRVJJQUxJWkVfVFJBTlNMRVRfRVJSLCAiV2hlbiBKYXZhIHNlY3VyaXR5IGlzIGVuYWJsZWQsICIgKwotICAgICAgICAgICAgICAgICAgICAgICAgInN1cHBvcnQgZm9yIGRlc2VyaWFsaXppbmcgVGVtcGxhdGVzSW1wbCBpcyBkaXNhYmxlZC4iICsKLSAgICAgICAgICAgICAgICAgICAgICAgICJUaGlzIGNhbiBiZSBvdmVycmlkZGVuIGJ5IHNldHRpbmcgdGhlIGpkay54bWwuZW5hYmxlVGVtcGxhdGVzSW1wbERlc2VyaWFsaXphdGlvbiIgKwotICAgICAgICAgICAgICAgICAgICAgICAgIiBzeXN0ZW0gcHJvcGVydHkgdG8gdHJ1ZS4ifQotCi0gICAgfTsKLQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvdXRpbC9FcnJvck1lc3NhZ2VzX2NhLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL3V0aWwvRXJyb3JNZXNzYWdlc19jYS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3MDhmNzQ0Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvdXRpbC9FcnJvck1lc3NhZ2VzX2NhLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4NjMgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRXJyb3JNZXNzYWdlc19jYS5qYXZhLHYgMS4xLjYuMSAyMDA1LzA5LzA1IDExOjUyOjU5IHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsOwotCi1pbXBvcnQgamF2YS51dGlsLkxpc3RSZXNvdXJjZUJ1bmRsZTsKLQotLyoqCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqLwotcHVibGljIGNsYXNzIEVycm9yTWVzc2FnZXNfY2EgZXh0ZW5kcyBMaXN0UmVzb3VyY2VCdW5kbGUgewotCi0vKgotICogWFNMVEMgY29tcGlsZS10aW1lIGVycm9yIG1lc3NhZ2VzLgotICoKLSAqIEdlbmVyYWwgbm90ZXMgdG8gdHJhbnNsYXRvcnMgYW5kIGRlZmluaXRpb25zOgotICoKLSAqICAgMSkgWFNMVEMgaXMgdGhlIG5hbWUgb2YgdGhlIHByb2R1Y3QuICBJdCBpcyBhbiBhY3JvbnltIGZvciAiWFNMVCBDb21waWxlciIuCi0gKiAgICAgIFhTTFQgaXMgYW4gYWNyb255bSBmb3IgIlhNTCBTdHlsZXNoZWV0IExhbmd1YWdlOiBUcmFuc2Zvcm1hdGlvbnMiLgotICoKLSAqICAgMikgQSBzdHlsZXNoZWV0IGlzIGEgZGVzY3JpcHRpb24gb2YgaG93IHRvIHRyYW5zZm9ybSBhbiBpbnB1dCBYTUwgZG9jdW1lbnQKLSAqICAgICAgaW50byBhIHJlc3VsdGFudCBYTUwgZG9jdW1lbnQgKG9yIEhUTUwgZG9jdW1lbnQgb3IgdGV4dCkuICBUaGUKLSAqICAgICAgc3R5bGVzaGVldCBpdHNlbGYgaXMgZGVzY3JpYmVkIGluIHRoZSBmb3JtIG9mIGFuIFhNTCBkb2N1bWVudC4KLSAqCi0gKiAgIDMpIEEgdGVtcGxhdGUgaXMgYSBjb21wb25lbnQgb2YgYSBzdHlsZXNoZWV0IHRoYXQgaXMgdXNlZCB0byBtYXRjaCBhCi0gKiAgICAgIHBhcnRpY3VsYXIgcG9ydGlvbiBvZiBhbiBpbnB1dCBkb2N1bWVudCBhbmQgc3BlY2lmaWVzIHRoZSBmb3JtIG9mIHRoZQotICogICAgICBjb3JyZXNwb25kaW5nIHBvcnRpb24gb2YgdGhlIG91dHB1dCBkb2N1bWVudC4KLSAqCi0gKiAgIDQpIEFuIGF4aXMgaXMgYSBwYXJ0aWN1bGFyICJkaW1lbnNpb24iIGluIGEgdHJlZSByZXByZXNlbnRhdGlvbiBvZiBhbiBYTUwKLSAqICAgICAgZG9jdW1lbnQ7IHRoZSBub2RlcyBpbiB0aGUgdHJlZSBhcmUgZGl2aWRlZCBhbG9uZyBkaWZmZXJlbnQgYXhlcy4KLSAqICAgICAgVHJhdmVyc2luZyB0aGUgImNoaWxkIiBheGlzLCBmb3IgaW5zdGFuY2UsIG1lYW5zIHRoYXQgdGhlIHByb2dyYW0KLSAqICAgICAgd291bGQgdmlzaXQgZWFjaCBjaGlsZCBvZiBhIHBhcnRpY3VsYXIgbm9kZTsgdHJhdmVyc2luZyB0aGUgImRlc2NlbmRhbnQiCi0gKiAgICAgIGF4aXMgbWVhbnMgdGhhdCB0aGUgcHJvZ3JhbSB3b3VsZCB2aXNpdCB0aGUgY2hpbGQgbm9kZXMgb2YgYSBwYXJ0aWN1bGFyCi0gKiAgICAgIG5vZGUsIHRoZWlyIGNoaWxkcmVuLCBhbmQgc28gb24gdW50aWwgdGhlIGxlYWYgbm9kZXMgb2YgdGhlIHRyZWUgYXJlCi0gKiAgICAgIHJlYWNoZWQuCi0gKgotICogICA1KSBBbiBpdGVyYXRvciBpcyBhbiBvYmplY3QgdGhhdCB0cmF2ZXJzZXMgbm9kZXMgaW4gYSB0cmVlIGFsb25nIGEKLSAqICAgICAgcGFydGljdWxhciBheGlzLCBvbmUgYXQgYSB0aW1lLgotICoKLSAqICAgNikgQW4gZWxlbWVudCBpcyBhIG1hcmstdXAgdGFnIGluIGFuIFhNTCBkb2N1bWVudDsgYW4gYXR0cmlidXRlIGlzIGEKLSAqICAgICAgbW9kaWZpZXIgb24gdGhlIHRhZy4gIEZvciBleGFtcGxlLCBpbiA8ZWxlbSBhdHRyPSd2YWwnIGF0dHIyPSd2YWwyJz4KLSAqICAgICAgImVsZW0iIGlzIGFuIGVsZW1lbnQgbmFtZSwgImF0dHIiIGFuZCAiYXR0cjIiIGFyZSBhdHRyaWJ1dGUgbmFtZXMgd2l0aAotICogICAgICB0aGUgdmFsdWVzICJ2YWwiIGFuZCAidmFsMiIsIHJlc3BlY3RpdmVseS4KLSAqCi0gKiAgIDcpIEEgbmFtZXNwYWNlIGRlY2xhcmF0aW9uIGlzIGEgc3BlY2lhbCBhdHRyaWJ1dGUgdGhhdCBpcyB1c2VkIHRvIGFzc29jaWF0ZQotICogICAgICBhIHByZWZpeCB3aXRoIGEgVVJJICh0aGUgbmFtZXNwYWNlKS4gIFRoZSBtZWFuaW5ncyBvZiBlbGVtZW50IG5hbWVzIGFuZAotICogICAgICBhdHRyaWJ1dGUgbmFtZXMgdGhhdCB1c2UgdGhhdCBwcmVmaXggYXJlIGRlZmluZWQgd2l0aCByZXNwZWN0IHRvIHRoYXQKLSAqICAgICAgbmFtZXNwYWNlLgotICoKLSAqICAgOCkgRE9NIGlzIGFuIGFjcm9ueW0gZm9yIERvY3VtZW50IE9iamVjdCBNb2RlbC4gIEl0IGlzIGEgdHJlZQotICogICAgICByZXByZXNlbnRhdGlvbiBvZiBhbiBYTUwgZG9jdW1lbnQuCi0gKgotICogICAgICBTQVggaXMgYW4gYWNyb255bSBmb3IgdGhlIFNpbXBsZSBBUEkgZm9yIFhNTCBwcm9jZXNzaW5nLiAgSXQgaXMgYW4gQVBJCi0gKiAgICAgIHVzZWQgaW5mb3JtIGFuIFhNTCBwcm9jZXNzb3IgKGluIHRoaXMgY2FzZSBYU0xUQykgb2YgdGhlIHN0cnVjdHVyZSBhbmQKLSAqICAgICAgY29udGVudCBvZiBhbiBYTUwgZG9jdW1lbnQuCi0gKgotICogICAgICBJbnB1dCB0byB0aGUgc3R5bGVzaGVldCBwcm9jZXNzb3IgY2FuIGNvbWUgZnJvbSBhbiBYTUwgcGFyc2VyIGluIHRoZQotICogICAgICBmb3JtIG9mIGEgRE9NIHRyZWUgb3IgdGhyb3VnaCB0aGUgU0FYIEFQSS4KLSAqCi0gKiAgIDkpIERURCBpcyBhIGRvY3VtZW50IHR5cGUgZGVjbGFyYXRpb24uICBJdCBpcyBhIHdheSBvZiBzcGVjaWZ5aW5nIHRoZQotICogICAgICBncmFtbWFyIGZvciBhbiBYTUwgZmlsZSwgdGhlIG5hbWVzIGFuZCB0eXBlcyBvZiBlbGVtZW50cywgYXR0cmlidXRlcywKLSAqICAgICAgZXRjLgotICoKLSAqICAxMCkgWFBhdGggaXMgYSBzcGVjaWZpY2F0aW9uIHRoYXQgZGVzY3JpYmVzIGEgbm90YXRpb24gZm9yIGlkZW50aWZ5aW5nCi0gKiAgICAgIG5vZGVzIGluIGEgdHJlZS1zdHJ1Y3R1cmVkIHJlcHJlc2VudGF0aW9uIG9mIGFuIFhNTCBkb2N1bWVudC4gIEFuCi0gKiAgICAgIGluc3RhbmNlIG9mIHRoYXQgbm90YXRpb24gaXMgcmVmZXJyZWQgdG8gYXMgYW4gWFBhdGggZXhwcmVzc2lvbi4KLSAqCi0gKiAgMTEpIFRyYW5zbGV0IGlzIGFuIGludmVudGVkIHRlcm0gdGhhdCByZWZlcnMgdG8gdGhlIGNsYXNzIGZpbGUgdGhhdCBjb250YWlucwotICogICAgICB0aGUgY29tcGlsZWQgZm9ybSBvZiBhIHN0eWxlc2hlZXQuCi0gKi8KLQotICAgIC8vIFRoZXNlIG1lc3NhZ2Ugc2hvdWxkIGJlIHJlYWQgZnJvbSBhIGxvY2FsZS1zcGVjaWZpYyByZXNvdXJjZSBidW5kbGUKLSAgICAvKiogR2V0IHRoZSBsb29rdXAgdGFibGUgZm9yIGVycm9yIG1lc3NhZ2VzLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgbWVzc2FnZSBsb29rdXAgdGFibGUuCi0gICAgICovCi0gICAgcHVibGljIE9iamVjdFtdW10gZ2V0Q29udGVudHMoKQotICAgIHsKLSAgICAgIHJldHVybiBuZXcgT2JqZWN0W11bXSB7Ci0gICAgICAgIHtFcnJvck1zZy5NVUxUSVBMRV9TVFlMRVNIRUVUX0VSUiwKLSAgICAgICAgIlMnaGEgZGVmaW5pdCBtXHUwMGU5cyBkJ3VuIGZ1bGwgZCdlc3RpbHMgZW4gZWwgbWF0ZWl4IGZpdHhlci4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIGEKLSAgICAgICAgICogdGVtcGxhdGUuICBUaGUgc2FtZSBuYW1lIHdhcyB1c2VkIG9uIHR3byBkaWZmZXJlbnQgdGVtcGxhdGVzIGluIHRoZQotICAgICAgICAgKiBzYW1lIHN0eWxlc2hlZXQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVEVNUExBVEVfUkVERUZfRVJSLAotICAgICAgICAiTGEgcGxhbnRpbGxhICcnezB9JycgamEgZXN0XHUwMGUwIGRlZmluaWRhIGVuIGFxdWVzdCBmdWxsIGQnJ2VzdGlscy4ifSwKLQotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYQotICAgICAgICAgKiB0ZW1wbGF0ZS4gIEEgcmVmZXJlbmNlIHRvIHRoZSB0ZW1wbGF0ZSBuYW1lIHdhcyBlbmNvdW50ZXJlZCwgYnV0IHRoZQotICAgICAgICAgKiB0ZW1wbGF0ZSBpcyB1bmRlZmluZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVEVNUExBVEVfVU5ERUZfRVJSLAotICAgICAgICAiTGEgcGxhbnRpbGxhICcnezB9Jycgbm8gZXN0XHUwMGUwIGRlZmluaWRhIGVuIGFxdWVzdCBmdWxsIGQnJ2VzdGlscy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIGEgdmFyaWFibGUKLSAgICAgICAgICogdGhhdCB3YXMgZGVmaW5lZCBtb3JlIHRoYW4gb25jZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5WQVJJQUJMRV9SRURFRl9FUlIsCi0gICAgICAgICJMYSB2YXJpYWJsZSAnJ3swfScnIHMnJ2hhIGRlZmluaXQgbVx1MDBlOXMgZCcndW5hIHZlZ2FkYSBlbiBlbCBtYXRlaXggXHUwMGUwbWJpdC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIGEgdmFyaWFibGUKLSAgICAgICAgICogb3IgcGFyYW1ldGVyLiAgQSByZWZlcmVuY2UgdG8gdGhlIHZhcmlhYmxlIG9yIHBhcmFtZXRlciB3YXMgZm91bmQsCi0gICAgICAgICAqIGJ1dCBpdCB3YXMgbmV2ZXIgZGVmaW5lZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5WQVJJQUJMRV9VTkRFRl9FUlIsCi0gICAgICAgICJMYSB2YXJpYWJsZSBvIGVsIHBhclx1MDBlMG1ldHJlICcnezB9Jycgbm8gcycnaGEgZGVmaW5pdC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHdvcmQgImNsYXNzIiBoZXJlIHJlZmVycyB0byBhIEphdmEgY2xhc3MuCi0gICAgICAgICAqIFByb2Nlc3NpbmcgdGhlIHN0eWxlc2hlZXQgcmVxdWlyZWQgYSBjbGFzcyB0byBiZSBsb2FkZWQsIGJ1dCBpdCBjb3VsZAotICAgICAgICAgKiBub3QgYmUgZm91bmQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgdGhlIGNsYXNzLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkNMQVNTX05PVF9GT1VORF9FUlIsCi0gICAgICAgICJObyBzJydoYSB0cm9iYXQgbGEgY2xhc3NlICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSB3b3JkICJtZXRob2QiIGhlcmUgcmVmZXJzIHRvIGEgSmF2YSBtZXRob2QuCi0gICAgICAgICAqIFByb2Nlc3NpbmcgdGhlIHN0eWxlc2hlZXQgcmVxdWlyZWQgYSByZWZlcmVuY2UgdG8gdGhlIG1ldGhvZCBuYW1lZCBieQotICAgICAgICAgKiB0aGUgc3Vic3RpdHV0aW9uIHRleHQsIGJ1dCBpdCBjb3VsZCBub3QgYmUgZm91bmQuICAicHVibGljIiBpcyB0aGUKLSAgICAgICAgICogSmF2YSBrZXl3b3JkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk1FVEhPRF9OT1RfRk9VTkRfRVJSLAotICAgICAgICAiTm8gcycnaGEgdHJvYmF0IGVsIG1cdTAwZTh0b2RlIGV4dGVybiAnJ3swfScnIChoYSBkZSBzZXIgcHVibGljKS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHdvcmQgIm1ldGhvZCIgaGVyZSByZWZlcnMgdG8gYSBKYXZhIG1ldGhvZC4KLSAgICAgICAgICogUHJvY2Vzc2luZyB0aGUgc3R5bGVzaGVldCByZXF1aXJlZCBhIHJlZmVyZW5jZSB0byB0aGUgbWV0aG9kIG5hbWVkIGJ5Ci0gICAgICAgICAqIHRoZSBzdWJzdGl0dXRpb24gdGV4dCwgYnV0IG5vIG1ldGhvZCB3aXRoIHRoZSByZXF1aXJlZCB0eXBlcyBvZgotICAgICAgICAgKiBhcmd1bWVudHMgb3IgcmV0dXJuIHR5cGUgY291bGQgYmUgZm91bmQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuQVJHVU1FTlRfQ09OVkVSU0lPTl9FUlIsCi0gICAgICAgICJObyBzJydoYSBwb2d1dCBjb252ZXJ0aXIgbCcnYXJndW1lbnQgbyB0aXB1cyBkZSByZXRvcm4gYSBsYSBjcmlkYSBkZWwgbVx1MDBlOHRvZGUgJyd7MH0nJyJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZmlsZSBvciBVUkkgbmFtZWQgaW4gdGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgICAqIGlzIG1pc3NpbmcuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuRklMRV9OT1RfRk9VTkRfRVJSLAotICAgICAgICAiTm8gcycnaGEgdHJvYmF0IGVsIGZpdHhlciBvIFVSSSAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgZGlzcGxheWVkIHdoZW4gdGhlIFVSSQotICAgICAgICAgKiBtZW50aW9uZWQgaW4gdGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIG5vdCB3ZWxsLWZvcm1lZCBzeW50YWN0aWNhbGx5LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklOVkFMSURfVVJJX0VSUiwKLSAgICAgICAgIkwnJ1VSSSAnJ3swfScnIG5vIFx1MDBlOXMgdlx1MDBlMGxpZC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZpbGUgb3IgVVJJIG5hbWVkIGluIHRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICAgKiBleGlzdHMgYnV0IGNvdWxkIG5vdCBiZSBvcGVuZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuRklMRV9BQ0NFU1NfRVJSLAotICAgICAgICAiTm8gZXMgcG90IG9icmlyIGVsIGZpdHhlciBvIGwnJ1VSSSAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6IDx4c2w6c3R5bGVzaGVldD4gYW5kIDx4c2w6dHJhbnNmb3JtPiBhcmUKLSAgICAgICAgICoga2V5d29yZHMgdGhhdCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTUlTU0lOR19ST09UX0VSUiwKLSAgICAgICAgIlMnJ2VzcGVyYXZhIGwnJ2VsZW1lbnQgPHhzbDpzdHlsZXNoZWV0PiBvIDx4c2w6dHJhbnNmb3JtPi4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN0eWxlc2hlZXQgY29udGFpbmVkIGEgcmVmZXJlbmNlIHRvIGEKLSAgICAgICAgICogbmFtZXNwYWNlIHByZWZpeCB0aGF0IHdhcyB1bmRlZmluZWQuICBUaGUgdmFsdWUgb2YgdGhlIHN1YnN0aXR1dGlvbgotICAgICAgICAgKiB0ZXh0IGlzIHRoZSBuYW1lIG9mIHRoZSBwcmVmaXguCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTkFNRVNQQUNFX1VOREVGX0VSUiwKLSAgICAgICAgIkVsIHByZWZpeCBkJydlc3BhaSBkZSBub21zICcnezB9Jycgbm8gcycnaGEgZGVjbGFyYXQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBKYXZhIGZ1bmN0aW9uIG5hbWVkIGluIHRoZSBzdHlsZXNoZWV0IGNvdWxkCi0gICAgICAgICAqIG5vdCBiZSBmb3VuZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5GVU5DVElPTl9SRVNPTFZFX0VSUiwKLSAgICAgICAgIk5vIHMnJ2hhIHBvZ3V0IHJlc29sZHJlIGxhIGNyaWRhIGRlIGxhIGZ1bmNpXHUwMGYzICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBhCi0gICAgICAgICAqIGZ1bmN0aW9uLiAgQSBsaXRlcmFsIHN0cmluZyBoZXJlIG1lYW5zIGEgY29uc3RhbnQgc3RyaW5nIHZhbHVlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk5FRURfTElURVJBTF9FUlIsCi0gICAgICAgICJMJydhcmd1bWVudCBkZSAnJ3swfScnIGhhIGRlIHNlciB1bmEgY2FkZW5hIGRlIGxpdGVyYWxzLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaW5kaWNhdGVzIHRoZXJlIHdhcyBhIHN5bnRhY3RpYwotICAgICAgICAgKiBlcnJvciBpbiB0aGUgZm9ybSBvZiBhbiBYUGF0aCBleHByZXNzaW9uLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzCi0gICAgICAgICAqIHRoZSBleHByZXNzaW9uLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlhQQVRIX1BBUlNFUl9FUlIsCi0gICAgICAgICJTJydoYSBwcm9kdVx1MDBlZnQgdW4gZXJyb3IgZW4gYW5hbGl0emFyIGwnJ2V4cHJlc3NpXHUwMGYzIFhQYXRoICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIGVsZW1lbnQgaW4gdGhlIHN0eWxlc2hlZXQgcmVxdWlyZXMgYQotICAgICAgICAgKiBwYXJ0aWN1bGFyIGF0dHJpYnV0ZSBuYW1lZCBieSB0aGUgc3Vic3RpdHV0aW9uIHRleHQsIGJ1dCB0aGF0Ci0gICAgICAgICAqIGF0dHJpYnV0ZSB3YXMgbm90IHNwZWNpZmllZCBpbiB0aGUgc3R5bGVzaGVldC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5SRVFVSVJFRF9BVFRSX0VSUiwKLSAgICAgICAgIk5vIHMnJ2hhIGVzcGVjaWZpY2F0IGwnJ2F0cmlidXQgb2JsaWdhdG9yaSAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgYSBjaGFyYWN0ZXIgbm90Ci0gICAgICAgICAqIHBlcm1pdHRlZCBpbiBhbiBYUGF0aCBleHByZXNzaW9uIHdhcyBlbmNvdW50ZXJlZC4gIFRoZSBzdWJzdGl0dXRpb24KLSAgICAgICAgICogdGV4dCBpcyB0aGUgb2ZmZW5kaW5nIGNoYXJhY3Rlci4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTExFR0FMX0NIQVJfRVJSLAotICAgICAgICAiTCcnZXhwcmVzc2lcdTAwZjMgWFBhdGggY29udFx1MDBlOSBlbCBjYXJcdTAwZTBjdGVyIG5vIHBlcm1cdTAwZThzICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEEgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiBpcyBhIG1hcmstdXAgaXRlbSBpbgotICAgICAgICAgKiBhbiBYTUwgZG9jdW1lbnQgdGhhdCByZXF1ZXN0IHNvbWUgYmVoYXZpb3VyIG9mIGFuIFhNTCBwcm9jZXNzb3IuICBUaGUKLSAgICAgICAgICogZm9ybSBvZiB0aGUgbmFtZSBvZiB3YXMgaW52YWxpZCBpbiB0aGlzIGNhc2UsIGFuZCB0aGUgc3Vic3RpdHV0aW9uCi0gICAgICAgICAqIHRleHQgaXMgdGhlIG5hbWUuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSUxMRUdBTF9QSV9FUlIsCi0gICAgICAgICJMYSBpbnN0cnVjY2lcdTAwZjMgZGUgcHJvY2Vzc2FtZW50IHRcdTAwZTkgZWwgbm9tIG5vIHBlcm1cdTAwZThzICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyByZXBvcnRlZCBpZiB0aGUgc3R5bGVzaGVldAotICAgICAgICAgKiBiZWluZyBwcm9jZXNzZWQgYXR0ZW1wdGVkIHRvIGNvbnN0cnVjdCBhbiBYTUwgZG9jdW1lbnQgd2l0aCBhbgotICAgICAgICAgKiBhdHRyaWJ1dGUgaW4gYSBwbGFjZSBvdGhlciB0aGFuIG9uIGFuIGVsZW1lbnQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQKLSAgICAgICAgICogc3BlY2lmaWVzIHRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuU1RSQVlfQVRUUklCVVRFX0VSUiwKLSAgICAgICAgIkwnJ2F0cmlidXQgJyd7MH0nJyBlcyB0cm9iYSBmb3JhIGRlIGwnJ2VsZW1lbnQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIGF0dHJpYnV0ZSB0aGF0IHdhc24ndCByZWNvZ25pemVkIHdhcwotICAgICAgICAgKiBzcGVjaWZpZWQgb24gYW4gZWxlbWVudCBpbiB0aGUgc3R5bGVzaGVldC4gIFRoZSBhdHRyaWJ1dGUgaXMgbmFtZWQKLSAgICAgICAgICogYnkgdGhlIHN1YnN0aXR1dGlvbgotICAgICAgICAgKiB0ZXh0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfQVRUUklCVVRFX0VSUiwKLSAgICAgICAgIk5vIGVzIHBlcm1ldCBsJydhdHJpYnV0ICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJpbXBvcnQiIGFuZCAiaW5jbHVkZSIgYXJlIGtleXdvcmRzIHRoYXQgc2hvdWxkCi0gICAgICAgICAqIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhpcyBtZXNzYWdlcyBpbmRpY2F0ZXMgdGhhdCB0aGUgc3R5bGVzaGVldAotICAgICAgICAgKiBuYW1lZCBpbiB0aGUgc3Vic3RpdHV0aW9uIHRleHQgaW1wb3J0ZWQgb3IgaW5jbHVkZWQgaXRzZWxmIGVpdGhlcgotICAgICAgICAgKiBkaXJlY3RseSBvciBpbmRpcmVjdGx5LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkNJUkNVTEFSX0lOQ0xVREVfRVJSLAotICAgICAgICAiSW1wb3J0L2luY2x1ZGUgY2lyY3VsYXIuIEVsIGZ1bGwgZCcnZXN0aWxzICcnezB9JycgamEgcycnaGEgY2FycmVnYXQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEEgcmVzdWx0LXRyZWUgZnJhZ21lbnQgaXMgYSBwb3J0aW9uIG9mIGEKLSAgICAgICAgICogcmVzdWx0aW5nIFhNTCBkb2N1bWVudCByZXByZXNlbnRlZCBhcyBhIHRyZWUuICAiPHhzbDpzb3J0PiIgaXMgYQotICAgICAgICAgKiBrZXl3b3JkIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuUkVTVUxUX1RSRUVfU09SVF9FUlIsCi0gICAgICAgICJFbHMgZnJhZ21lbnRzIGRlIGwnYXJicmUgZGUgcmVzdWx0YXRzIG5vIGVzIHBvZGVuIGNsYXNzaWZpY2FyIChlcyBwYXNzZW4gcGVyIGFsdCBlbHMgZWxlbWVudHMgPHhzbDpzb3J0PikuIEhldSBkZSBjbGFzc2lmaWNhciBlbHMgbm9kZXMgcXVhbiBjcmVldSBsJ2FyYnJlIGRlIHJlc3VsdGF0cy4gIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEEgbmFtZSBjYW4gYmUgZ2l2ZW4gdG8gYSBwYXJ0aWN1bGFyIHN0eWxlIHRvIGJlCi0gICAgICAgICAqIHVzZWQgdG8gZm9ybWF0IGRlY2ltYWwgdmFsdWVzLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGdpdmVzIHRoZSBuYW1lCi0gICAgICAgICAqIG9mIHN1Y2ggYSBzdHlsZSBmb3Igd2hpY2ggbW9yZSB0aGFuIG9uZSBkZWNsYXJhdGlvbiB3YXMgZW5jb3VudGVyZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuU1lNQk9MU19SRURFRl9FUlIsCi0gICAgICAgICJFbCBmb3JtYXRhdGdlIGRlY2ltYWwgJyd7MH0nJyBqYSBlc3RcdTAwZTAgZGVmaW5pdC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN0eWxlc2hlZXQgdmVyc2lvbiBuYW1lZCBpbiB0aGUKLSAgICAgICAgICogc3Vic3RpdHV0aW9uIHRleHQgaXMgbm90IHN1cHBvcnRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5YU0xfVkVSU0lPTl9FUlIsCi0gICAgICAgICJYU0xUQyBubyBkXHUwMGYzbmEgc3Vwb3J0IGEgbGEgdmVyc2lcdTAwZjMgWFNMICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBkZWZpbml0aW9ucyBvZiBvbmUgb3IgbW9yZSB2YXJpYWJsZXMgb3IKLSAgICAgICAgICogcGFyYW1ldGVycyBkZXBlbmQgb24gb25lIGFub3RoZXIuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuQ0lSQ1VMQVJfVkFSSUFCTEVfRVJSLAotICAgICAgICAiSGkgaGEgdW5hIHJlZmVyXHUwMGU4bmNpYSBkZSB2YXJpYWJsZS9wYXJcdTAwZTBtZXRyZSBjaXJjdWxhciBhICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBvcGVyYXRvciBpbiBhbiBleHByZXNpb24gd2l0aCB0d28gb3BlcmFuZHMgd2FzCi0gICAgICAgICAqIG5vdCByZWNvZ25pemVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfQklOQVJZX09QX0VSUiwKLSAgICAgICAgIkwnb3BlcmFkb3IgZGUgbCdleHByZXNzaVx1MDBmMyBiaW5cdTAwZTByaWEgXHUwMGU5cyBkZXNjb25lZ3V0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgcHJvZHVjZWQgaWYgYSByZWZlcmVuY2UgdG8gYQotICAgICAgICAgKiBmdW5jdGlvbiBoYXMgdG9vIG1hbnkgb3IgdG9vIGZldyBhcmd1bWVudHMuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSUxMRUdBTF9BUkdfRVJSLAotICAgICAgICAiTGEgY3JpZGEgZGUgZnVuY2lcdTAwZjMgdFx1MDBlOSBhcmd1bWVudHMgbm8gcGVybWVzb3MuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJkb2N1bWVudCgpIiBpcyB0aGUgbmFtZSBvZiBmdW5jdGlvbiBhbmQgbXVzdAotICAgICAgICAgKiBub3QgYmUgdHJhbnNsYXRlZC4gIEEgbm9kZS1zZXQgaXMgYSBzZXQgb2YgdGhlIG5vZGVzIGluIHRoZSB0cmVlCi0gICAgICAgICAqIHJlcHJlc2VudGF0aW9uIG9mIGFuIFhNTCBkb2N1bWVudC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5ET0NVTUVOVF9BUkdfRVJSLAotICAgICAgICAiRWwgc2Vnb24gYXJndW1lbnQgZGUgbGEgZnVuY2lcdTAwZjMgZG9jdW1lbnQoKSBoYSBkZSBzZXIgdW4gY29uanVudCBkZSBub2Rlcy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIjx4c2w6d2hlbj4iIGFuZCAiPHhzbDpjaG9vc2U+IiBhcmUga2V5d29yZHMKLSAgICAgICAgICogYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoaXMgbWVzc2FnZSBkZXNjcmliZXMgYSBzeW50YXggZXJyb3IKLSAgICAgICAgICogaW4gdGhlIHN0eWxlc2hlZXQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTUlTU0lOR19XSEVOX0VSUiwKLSAgICAgICAgIkVzIG5lY2Vzc2l0YSBjb20gYSBtXHUwMGVkbmltIHVuIGVsZW1lbnQgPHhzbDp3aGVuPiBhIDx4c2w6Y2hvb3NlPi4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIjx4c2w6b3RoZXJ3aXNlPiIgYW5kICI8eHNsOmNob29zZT4iIGFyZQotICAgICAgICAgKiBrZXl3b3JkcyBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhpcyBtZXNzYWdlIGRlc2NyaWJlcyBhCi0gICAgICAgICAqIHN5bnRheCBlcnJvciBpbiB0aGUgc3R5bGVzaGVldC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5NVUxUSVBMRV9PVEhFUldJU0VfRVJSLAotICAgICAgICAiTm9tXHUwMGU5cyBlcyBwZXJtZXQgdW4gZWxlbWVudCA8eHNsOm90aGVyd2lzZT4gYSA8eHNsOmNob29zZT4uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICI8eHNsOm90aGVyd2lzZT4iIGFuZCAiPHhzbDpjaG9vc2U+IiBhcmUKLSAgICAgICAgICoga2V5d29yZHMgYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoaXMgbWVzc2FnZSBkZXNjcmliZXMgYQotICAgICAgICAgKiBzeW50YXggZXJyb3IgaW4gdGhlIHN0eWxlc2hlZXQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuU1RSQVlfT1RIRVJXSVNFX0VSUiwKLSAgICAgICAgIjx4c2w6b3RoZXJ3aXNlPiBub21cdTAwZTlzIGVzIHBvdCB1dGlsaXR6YXIgZGlucyBkZSA8eHNsOmNob29zZT4uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICI8eHNsOndoZW4+IiBhbmQgIjx4c2w6Y2hvb3NlPiIgYXJlIGtleXdvcmRzCi0gICAgICAgICAqIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGlzIG1lc3NhZ2UgZGVzY3JpYmVzIGEgc3ludGF4IGVycm9yCi0gICAgICAgICAqIGluIHRoZSBzdHlsZXNoZWV0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlNUUkFZX1dIRU5fRVJSLAotICAgICAgICAiPHhzbDp3aGVuPiBub21cdTAwZTlzIGVzIHBvdCB1dGlsaXR6YXIgZGlucyBkZSA8eHNsOmNob29zZT4uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICI8eHNsOndoZW4+IiwgIjx4c2w6b3RoZXJ3aXNlPiIgYW5kCi0gICAgICAgICAqICI8eHNsOmNob29zZT4iIGFyZSBrZXl3b3JkcyBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhpcwotICAgICAgICAgKiBtZXNzYWdlIGRlc2NyaWJlcyBhIHN5bnRheCBlcnJvciBpbiB0aGUgc3R5bGVzaGVldC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5XSEVOX0VMRU1FTlRfRVJSLAotICAgICAgICAiQSA8eHNsOmNob29zZT4gbm9tXHUwMGU5cyBlcyBwZXJtZXRlbiBlbHMgZWxlbWVudHMgPHhzbDp3aGVuPiBpIDx4c2w6b3RoZXJ3aXNlPi4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIjx4c2w6YXR0cmlidXRlLXNldD4iIGFuZCAibmFtZSIgYXJlIGtleXdvcmRzCi0gICAgICAgICAqIHRoYXQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlVOTkFNRURfQVRUUklCU0VUX0VSUiwKLSAgICAgICAgIkwnYXRyaWJ1dCAnbmFtZScgZmFsdGEgYSA8eHNsOmF0dHJpYnV0ZS1zZXQ+LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBbiBlbGVtZW50IGluIHRoZSBzdHlsZXNoZWV0IGNvbnRhaW5lZCBhbgotICAgICAgICAgKiBlbGVtZW50IG9mIGEgdHlwZSB0aGF0IGl0IHdhcyBub3QgcGVybWl0dGVkIHRvIGNvbnRhaW4uCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSUxMRUdBTF9DSElMRF9FUlIsCi0gICAgICAgICJMJ2VsZW1lbnQgc3Vib3JkaW5hdCBubyBcdTAwZTlzIHBlcm1cdTAwZThzLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3R5bGVzaGVldCB0cmllZCB0byBjcmVhdGUgYW4gZWxlbWVudCB3aXRoCi0gICAgICAgICAqIGEgbmFtZSB0aGF0IHdhcyBub3QgYSB2YWxpZCBYTUwgbmFtZS4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBjb250YWlucwotICAgICAgICAgKiB0aGUgbmFtZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTExFR0FMX0VMRU1fTkFNRV9FUlIsCi0gICAgICAgICJObyBwb2RldSBjcmlkYXIgdW4gZWxlbWVudCAnJ3swfScnIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IHRyaWVkIHRvIGNyZWF0ZSBhbiBhdHRyaWJ1dGUKLSAgICAgICAgICogd2l0aCBhIG5hbWUgdGhhdCB3YXMgbm90IGEgdmFsaWQgWE1MIG5hbWUuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQKLSAgICAgICAgICogY29udGFpbnMgdGhlIG5hbWUuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSUxMRUdBTF9BVFRSX05BTUVfRVJSLAotICAgICAgICAiTm8gcG9kZXUgY3JpZGFyIHVuIGF0cmlidXQgJyd7MH0nJyJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgY2hpbGRyZW4gb2YgdGhlIG91dGVybW9zdCBlbGVtZW50IG9mIGEKLSAgICAgICAgICogc3R5bGVzaGVldCBhcmUgcmVmZXJyZWQgdG8gYXMgdG9wLWxldmVsIGVsZW1lbnRzLiAgTm8gdGV4dCBzaG91bGQKLSAgICAgICAgICogb2NjdXIgd2l0aGluIHRoYXQgb3V0ZXJtb3N0IGVsZW1lbnQgdW5sZXNzIGl0IGlzIHdpdGhpbiBhIHRvcC1sZXZlbAotICAgICAgICAgKiBlbGVtZW50LiAgVGhpcyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoYXQgY29uc3RyYWludCB3YXMgdmlvbGF0ZWQuCi0gICAgICAgICAqICI8eHNsOnN0eWxlc2hlZXQ+IiBpcyBhIGtleXdvcmQgdGhhdCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSUxMRUdBTF9URVhUX05PREVfRVJSLAotICAgICAgICAiSGkgaGEgZGFkZXMgZm9yYSBkZSBsJ2VsZW1lbnQgZGUgbml2ZWxsIHN1cGVyaW9yIDx4c2w6c3R5bGVzaGVldD4uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEpBWFAgaXMgYW4gYWNyb255bSBmb3IgdGhlIEphdmEgQVBJIGZvciBYTUwKLSAgICAgICAgICogUHJvY2Vzc2luZy4gIFRoaXMgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUgWE1MIHBhcnNlciBwcm92aWRlZCB0bwotICAgICAgICAgKiBYU0xUQyB0byBwcm9jZXNzIHRoZSBYTUwgaW5wdXQgZG9jdW1lbnQgaGFkIGEgY29uZmlndXJhdGlvbiBwcm9ibGVtLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlNBWF9QQVJTRVJfQ09ORklHX0VSUiwKLSAgICAgICAgIkwnYW5hbGl0emFkb3IgSkFYUCBubyBzJ2hhIGNvbmZpZ3VyYXQgY29ycmVjdGFtZW50In0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBuYW1lcyB0aGUgaW50ZXJuYWwgZXJyb3IKLSAgICAgICAgICogZW5jb3VudGVyZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSU5URVJOQUxfRVJSLAotICAgICAgICAiUycnaGEgcHJvZHVcdTAwZWZ0IHVuIGVycm9yIGludGVybiBkJydYU0xUQyBpcnJlY3VwZXJhYmxlOiAnJ3swfScnIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IGNvbnRhaW5lZCBhbiBlbGVtZW50IHRoYXQgd2FzCi0gICAgICAgICAqIG5vdCByZWNvZ25pemVkIGFzIHBhcnQgb2YgdGhlIFhTTCBzeW50YXguICBUaGUgc3Vic3RpdHV0aW9uIHRleHQKLSAgICAgICAgICogZ2l2ZXMgdGhlIGVsZW1lbnQgbmFtZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5VTlNVUFBPUlRFRF9YU0xfRVJSLAotICAgICAgICAiTCcnZWxlbWVudCBkJydYU0wgJyd7MH0nJyBubyB0XHUwMGU5IHN1cG9ydC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN0eWxlc2hlZXQgcmVmZXJyZWQgdG8gYW4gZXh0ZW5zaW9uIHRvIHRoZQotICAgICAgICAgKiBYU0wgc3ludGF4IGFuZCBpbmRpY2F0ZWQgdGhhdCBpdCB3YXMgZGVmaW5lZCBieSBYU0xUQywgYnV0IFhTVExDIGRvZXMKLSAgICAgICAgICogbm90IHJlY29nbml6ZWQgdGhlIHBhcnRpY3VsYXIgZXh0ZW5zaW9uIG5hbWVkLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgICAqIGdpdmVzIHRoZSBleHRlbnNpb24gbmFtZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5VTlNVUFBPUlRFRF9FWFRfRVJSLAotICAgICAgICAiTm8gZXMgcmVjb25laXggbCcnZXh0ZW5zaVx1MDBmMyBkJydYU0xUQyAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgWE1MIGRvY3VtZW50IGdpdmVuIHRvIFhTTFRDIGFzIGEgc3R5bGVzaGVldAotICAgICAgICAgKiB3YXMgbm90LCBpbiBmYWN0LCBhIHN0eWxlc2hlZXQuICBYU0xUQyBpcyBhYmxlIHRvIGRldGVjdCB0aGF0IGluIHRoaXMKLSAgICAgICAgICogY2FzZSBiZWNhdXNlIHRoZSBvdXRlcm1vc3QgZWxlbWVudCBpbiB0aGUgc3R5bGVzaGVldCBoYXMgdG8gYmUKLSAgICAgICAgICogZGVjbGFyZWQgd2l0aCByZXNwZWN0IHRvIHRoZSBYU0wgbmFtZXNwYWNlIFVSSSwgYnV0IG5vIGRlY2xhcmF0aW9uCi0gICAgICAgICAqIGZvciB0aGF0IG5hbWVzcGFjZSB3YXMgc2Vlbi4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5NSVNTSU5HX1hTTFRfVVJJX0VSUiwKLSAgICAgICAgIkVsIGRvY3VtZW50IGQnZW50cmFkYSBubyBcdTAwZTlzIHVuIGZ1bGwgZCdlc3RpbHMgKGwnZXNwYWkgZGUgbm9tcyBYU0wgbm8gcydoYSBkZWNsYXJhdCBlbiBsJ2VsZW1lbnQgYXJyZWwpLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBYU0xUQyBjb3VsZCBub3QgZmluZCB0aGUgc3R5bGVzaGVldCBkb2N1bWVudAotICAgICAgICAgKiB3aXRoIHRoZSBuYW1lIHNwZWNpZmllZCBieSB0aGUgc3Vic3RpdHV0aW9uIHRleHQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTUlTU0lOR19YU0xUX1RBUkdFVF9FUlIsCi0gICAgICAgICJObyBzJydoYSB0cm9iYXQgbGEgZGVzdGluYWNpXHUwMGYzICcnezB9JycgZGVsIGZ1bGwgZCcnZXN0aWxzLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBhY2Nlc3MgdG8gdGhlIHN0eWxlc2hlZXQgdGFyZ2V0IGlzIGRlbmllZAotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkFDQ0VTU0lOR19YU0xUX1RBUkdFVF9FUlIsCi0gICAgICAgICJDb3VsZCBub3QgcmVhZCBzdHlsZXNoZWV0IHRhcmdldCAnJ3swfScnLCBiZWNhdXNlICcnezF9JycgYWNjZXNzIGlzIG5vdCBhbGxvd2VkLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgcmVwcmVzZW50cyBhbiBpbnRlcm5hbCBlcnJvciBpbgotICAgICAgICAgKiBjb25kaXRpb24gaW4gWFNMVEMuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIGNsYXNzIG5hbWUgaW4gWFNMVEMKLSAgICAgICAgICogdGhhdCBpcyBtaXNzaW5nIHNvbWUgZnVuY3Rpb25hbGl0eS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5OT1RfSU1QTEVNRU5URURfRVJSLAotICAgICAgICAiTm8gcycnaGEgaW1wbGVtZW50YXQgJyd7MH0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIFhNTCBkb2N1bWVudCBnaXZlbiB0byBYU0xUQyBhcyBhIHN0eWxlc2hlZXQKLSAgICAgICAgICogd2FzIG5vdCwgaW4gZmFjdCwgYSBzdHlsZXNoZWV0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk5PVF9TVFlMRVNIRUVUX0VSUiwKLSAgICAgICAgIkVsIGRvY3VtZW50IGQnZW50cmFkYSBubyBjb250XHUwMGU5IGNhcCBmdWxsIGQnZXN0aWxzIFhTTC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGVsZW1lbnQgbmFtZWQgaW4gdGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHdhcwotICAgICAgICAgKiBlbmNvdW50ZXJlZCBpbiB0aGUgc3R5bGVzaGVldCBidXQgaXMgbm90IHJlY29nbml6ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuRUxFTUVOVF9QQVJTRV9FUlIsCi0gICAgICAgICJObyBzJydoYSBwb2d1dCBhbmFsaXR6YXIgbCcnZWxlbWVudCAnJ3swfScnIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJ1c2UiLCAiPGtleT4iLCAibm9kZSIsICJub2RlLXNldCIsICJzdHJpbmciCi0gICAgICAgICAqIGFuZCAibnVtYmVyIiBhcmUga2V5d29yZHMgaW4gdGhpcyBjb250ZXh0IGFuZCBzaG91bGQgbm90IGJlCi0gICAgICAgICAqIHRyYW5zbGF0ZWQuICBUaGlzIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhlIHZhbHVlIG9mIHRoZSAidXNlIgotICAgICAgICAgKiBhdHRyaWJ1dGUgd2FzIG5vdCBvbmUgb2YgdGhlIHBlcm1pdHRlZCB2YWx1ZXMuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuS0VZX1VTRV9BVFRSX0VSUiwKLSAgICAgICAgIkwnYXRyaWJ1dCB1c2UgZGUgPGtleT4gaGEgZGUgc2VyIG5vZGUsIG5vZGUtc2V0LCBzdHJpbmcgbyBudW1iZXIuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIFhNTCBkb2N1bWVudCBjYW4gc3BlY2lmeSB0aGUgdmVyc2lvbiBvZiB0aGUKLSAgICAgICAgICogWE1MIHNwZWNpZmljYXRpb24gdG8gd2hpY2ggaXQgYWRoZXJlcy4gIFRoaXMgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdAotICAgICAgICAgKiB0aGUgdmVyc2lvbiBzcGVjaWZpZWQgZm9yIHRoZSBvdXRwdXQgZG9jdW1lbnQgd2FzIG5vdCB2YWxpZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5PVVRQVVRfVkVSU0lPTl9FUlIsCi0gICAgICAgICJMYSB2ZXJzaVx1MDBmMyBkZWwgZG9jdW1lbnQgWE1MIGRlIHNvcnRpZGEgaGEgZGUgc2VyIDEuMCJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgb3BlcmF0b3IgaW4gYSBjb21wYXJpc29uIG9wZXJhdGlvbiB3YXMKLSAgICAgICAgICogbm90IHJlY29nbml6ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSUxMRUdBTF9SRUxBVF9PUF9FUlIsCi0gICAgICAgICJMJ29wZXJhZG9yIGRlIGwnZXhwcmVzc2lcdTAwZjMgcmVsYWNpb25hbCBcdTAwZTlzIGRlc2NvbmVndXQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIGF0dHJpYnV0ZSBzZXQgZGVmaW5lcyBhcyBhIHNldCBvZiBYTUwKLSAgICAgICAgICogYXR0cmlidXRlcyB0aGF0IGNhbiBiZSBhZGRlZCB0byBhbiBlbGVtZW50IGluIHRoZSBvdXRwdXQgWE1MIGRvY3VtZW50Ci0gICAgICAgICAqIGFzIGEgZ3JvdXAuICBUaGlzIG1lc3NhZ2UgaXMgcmVwb3J0ZWQgaWYgdGhlIG5hbWUgc3BlY2lmaWVkIHdhcyBub3QKLSAgICAgICAgICogdXNlZCB0byBkZWNsYXJlIGFuIGF0dHJpYnV0ZSBzZXQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUKLSAgICAgICAgICogdGhhdCBpcyBpbiBlcnJvci4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5BVFRSSUJTRVRfVU5ERUZfRVJSLAotICAgICAgICAiUycnaGEgaW50ZW50YXQgdXRpbGl0emFyIGVsIGNvbmp1bnQgZCcnYXRyaWJ1dHMgJyd7MH0nJyBxdWUgbm8gZXhpc3RlaXguIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSB0ZXJtICJhdHRyaWJ1dGUgdmFsdWUgdGVtcGxhdGUiIGlzIGEgdGVybQotICAgICAgICAgKiBkZWZpbmVkIGJ5IFhTTFQgd2hpY2ggZGVzY3JpYmVzIHRoZSB2YWx1ZSBvZiBhbiBhdHRyaWJ1dGUgdGhhdCBpcwotICAgICAgICAgKiBkZXRlcm1pbmVkIGJ5IGFuIFhQYXRoIGV4cHJlc3Npb24uICBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUKLSAgICAgICAgICogZXhwcmVzc2lvbiB3YXMgc3ludGFjdGljYWxseSBpbmNvcnJlY3Q7IHRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICAgKiBjb250YWlucyB0aGUgZXhwcmVzc2lvbiB0aGF0IHdhcyBpbiBlcnJvci4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5BVFRSX1ZBTF9URU1QTEFURV9FUlIsCi0gICAgICAgICJObyBlcyBwb3QgYW5hbGl0emFyIGxhIHBsYW50aWxsYSBkZSB2YWxvcnMgZCcnYXRyaWJ1dHMgJyd7MH0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgPz8/Ci0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVU5LTk9XTl9TSUdfVFlQRV9FUlIsCi0gICAgICAgICJFbCB0aXB1cyBkZSBkYWRlcyBkZSBsYSBzaWduYXR1cmEgZGUgbGEgY2xhc3NlICcnezB9JycgXHUwMGU5cyBkZXNjb25lZ3V0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgcmVmZXJzIHRvIGRhdGEgdHlwZXMuCi0gICAgICAgICAqIFRoZSBtZXNzYWdlIGlzIGRpc3BsYXllZCBpZiBhIHZhbHVlIGluIGEgcGFydGljdWxhciBjb250ZXh0IG5lZWRzIHRvCi0gICAgICAgICAqIGJlIGNvbnZlcnRlZCB0byB0eXBlIHsxfSwgYnV0IHRoYXQncyBub3QgcG9zc2libGUgZm9yIGEgdmFsdWUgb2YKLSAgICAgICAgICogdHlwZSB7MH0uCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuREFUQV9DT05WRVJTSU9OX0VSUiwKLSAgICAgICAgIk5vIGVzIHBvdCBjb252ZXJ0aXIgZWwgdGlwdXMgZGUgZGFkZXMgJyd7MH0nJyBlbiAnJ3sxfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiVGVtcGxhdGVzIiBpcyBhIEphdmEgY2xhc3MgbmFtZSB0aGF0IHNob3VsZAotICAgICAgICAgKiBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5OT19UUkFOU0xFVF9DTEFTU19FUlIsCi0gICAgICAgICJUZW1wbGF0ZXMgbm8gY29udFx1MDBlOSBjYXAgZGVmaW5pY2lcdTAwZjMgZGUgY2xhc3NlIHRyYW5zbGV0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiVGVtcGxhdGVzIiBpcyBhIEphdmEgY2xhc3MgbmFtZSB0aGF0IHNob3VsZAotICAgICAgICAgKiBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5OT19NQUlOX1RSQU5TTEVUX0VSUiwKLSAgICAgICAgIlRlbXBsYXRlcyBubyBjb250XHUwMGU5IGNhcCBjbGFzc2UgYW1iIGVsIG5vbSAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYSBjbGFzcy4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5UUkFOU0xFVF9DTEFTU19FUlIsCi0gICAgICAgICJObyBzJydoYSBwb2d1dCBjYXJyZWdhciBsYSBjbGFzc2UgdHJhbnNsZXQgJyd7MH0nJy4ifSwKLQotICAgICAgICB7RXJyb3JNc2cuVFJBTlNMRVRfT0JKRUNUX0VSUiwKLSAgICAgICAgIkxhIGNsYXNzZSB0cmFuc2xldCBzJydoYSBjYXJyZWdhdCwgcGVyXHUwMGYyIG5vIGVzIHBvdCBjcmVhciBsYSBpbnN0XHUwMGUwbmNpYSB0cmFuc2xldC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIkVycm9yTGlzdGVuZXIiIGlzIGEgSmF2YSBpbnRlcmZhY2UgbmFtZSB0aGF0Ci0gICAgICAgICAqIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoZSBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoZSB1c2VyIHRyaWVkCi0gICAgICAgICAqIHRvIHNldCBhbiBFcnJvckxpc3RlbmVyIG9iamVjdCBvbiBvYmplY3Qgb2YgdGhlIGNsYXNzIG5hbWVkIGluIHRoZQotICAgICAgICAgKiBzdWJzdGl0dXRpb24gdGV4dCB3aXRoICJudWxsIiBKYXZhIHZhbHVlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkVSUk9SX0xJU1RFTkVSX05VTExfRVJSLAotICAgICAgICAiUycnaGEgaW50ZW50YXQgZXN0YWJsaXIgRXJyb3JMaXN0ZW5lciBkZSAnJ3swfScnIGVuIHVuIHZhbG9yIG51bC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgU3RyZWFtU291cmNlLCBTQVhTb3VyY2UgYW5kIERPTVNvdXJjZSBhcmUgSmF2YQotICAgICAgICAgKiBpbnRlcmZhY2UgbmFtZXMgdGhhdCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSkFYUF9VTktOT1dOX1NPVVJDRV9FUlIsCi0gICAgICAgICJYU0xUQyBub21cdTAwZTlzIGRcdTAwZjNuYSBzdXBvcnQgYSBTdHJlYW1Tb3VyY2UsIFNBWFNvdXJjZSBpIERPTVNvdXJjZS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIlNvdXJjZSIgaXMgYSBKYXZhIGNsYXNzIG5hbWUgdGhhdCBzaG91bGQgbm90Ci0gICAgICAgICAqIGJlIHRyYW5zbGF0ZWQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgSmF2YSBtZXRob2QuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSkFYUF9OT19TT1VSQ0VfRVJSLAotICAgICAgICAiTCcnb2JqZWN0ZSBzb3VyY2UgZG9uYXQgYSAnJ3swfScnIG5vIHRcdTAwZTkgY29udGluZ3V0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCBYU0xUQyBmYWlsZWQgdG8KLSAgICAgICAgICogY29tcGlsZSB0aGUgc3R5bGVzaGVldCBpbnRvIGEgdHJhbnNsZXQgKGNsYXNzIGZpbGUpLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfQ09NUElMRV9FUlIsCi0gICAgICAgICJObyBzJ2hhIHBvZ3V0IGNvbXBpbGFyIGVsIGZ1bGwgZCdlc3RpbHMuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJUcmFuc2Zvcm1lckZhY3RvcnkiIGlzIGEgY2xhc3MgbmFtZS4gIEluIHRoaXMKLSAgICAgICAgICogY29udGV4dCwgYW4gYXR0cmlidXRlIGlzIGEgcHJvcGVydHkgb3Igc2V0dGluZyBvZiB0aGUKLSAgICAgICAgICogVHJhbnNmb3JtZXJGYWN0b3J5IG9iamVjdC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiB0aGUKLSAgICAgICAgICogdW5yZWNvZ25pc2VkIGF0dHJpYnV0ZS4gIFRoZSBtZXRob2QgdXNlZCB0byByZXRyaWV2ZSB0aGUgYXR0cmlidXRlIGlzCi0gICAgICAgICAqICJnZXRBdHRyaWJ1dGUiLCBzbyBpdCdzIG5vdCBjbGVhciB3aGV0aGVyIGl0IHdvdWxkIGJlIGJlc3QgdG8KLSAgICAgICAgICogdHJhbnNsYXRlIHRoZSB0ZXJtICJhdHRyaWJ1dGUiLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfSU5WQUxJRF9BVFRSX0VSUiwKLSAgICAgICAgIlRyYW5zZm9ybWVyRmFjdG9yeSBubyByZWNvbmVpeCBsJydhdHJpYnV0ICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJzZXRSZXN1bHQoKSIgYW5kICJzdGFydERvY3VtZW50KCkiIGFyZSBKYXZhCi0gICAgICAgICAqIG1ldGhvZCBuYW1lcyB0aGF0IHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX1NFVF9SRVNVTFRfRVJSLAotICAgICAgICAic2V0UmVzdWx0KCkgcydoYSBkZSBjcmlkYXIgYWJhbnMgZGUgc3RhcnREb2N1bWVudCgpLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiVHJhbnNmb3JtZXIiIGlzIGEgSmF2YSBpbnRlcmZhY2UgbmFtZSB0aGF0Ci0gICAgICAgICAqIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIEEgVHJhbnNmb3JtZXIgb2JqZWN0IHNob3VsZCBjb250YWluZWQgYQotICAgICAgICAgKiByZWZlcmVuY2UgdG8gYSB0cmFuc2xldCBvYmplY3QgaW4gb3JkZXIgdG8gYmUgdXNlZCBmb3IKLSAgICAgICAgICogdHJhbnNmb3JtYXRpb25zOyB0aGlzIG1lc3NhZ2UgaXMgcHJvZHVjZWQgaWYgdGhhdCByZXF1aXJlbWVudCBpcyBub3QKLSAgICAgICAgICogbWV0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfTk9fVFJBTlNMRVRfRVJSLAotICAgICAgICAiVHJhbnNmb3JtZXIgbm8gY29udFx1MDBlOSBjYXAgb2JqZWN0ZSB0cmFuc2xldC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIFhNTCBkb2N1bWVudCB0aGF0IHJlc3VsdHMgZnJvbSBhCi0gICAgICAgICAqIHRyYW5zZm9ybWF0aW9uIG5lZWRzIHRvIGJlIHNlbnQgdG8gYW4gb3V0cHV0IGhhbmRsZXIgb2JqZWN0OyB0aGlzCi0gICAgICAgICAqIG1lc3NhZ2UgaXMgcHJvZHVjZWQgaWYgdGhhdCByZXF1aXJlbWVudCBpcyBub3QgbWV0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfTk9fSEFORExFUl9FUlIsCi0gICAgICAgICJObyBzJ2hhIGRlZmluaXQgY2FwIG1hbmVqYWRvciBkZSBzb3J0aWRhIHBlciBhbCByZXN1bHRhdCBkZSB0cmFuc2Zvcm1hY2lcdTAwZjMuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJSZXN1bHQiIGlzIGEgSmF2YSBpbnRlcmZhY2UgbmFtZSBpbiB0aGlzCi0gICAgICAgICAqIGNvbnRleHQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgYSBtZXRob2QgbmFtZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX05PX1JFU1VMVF9FUlIsCi0gICAgICAgICJMJydvYmplY3RlIHJlc3VsdCBkb25hdCBhICcnezB9Jycgbm8gXHUwMGU5cyB2XHUwMGUwbGlkLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiVHJhbnNmb3JtZXIiIGlzIGEgSmF2YSBpbnRlcmZhY2UgbmFtZS4gIFRoZQotICAgICAgICAgKiB1c2VyJ3MgcHJvZ3JhbSBhdHRlbXB0ZWQgdG8gYWNjZXNzIGFuIHVucmVjb2duaXplZCBwcm9wZXJ0eSB3aXRoIHRoZQotICAgICAgICAgKiBuYW1lIHNwZWNpZmllZCBpbiB0aGUgc3Vic3RpdHV0aW9uIHRleHQuICBUaGUgbWV0aG9kIHVzZWQgdG8gcmV0cmlldmUKLSAgICAgICAgICogdGhlIHByb3BlcnR5IGlzICJnZXRPdXRwdXRQcm9wZXJ0eSIsIHNvIGl0J3Mgbm90IGNsZWFyIHdoZXRoZXIgaXQKLSAgICAgICAgICogd291bGQgYmUgYmVzdCB0byB0cmFuc2xhdGUgdGhlIHRlcm0gInByb3BlcnR5Ii4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX1VOS05PV05fUFJPUF9FUlIsCi0gICAgICAgICJTJydoYSBpbnRlbnRhdCBhY2NlZGlyIGEgdW5hIHByb3BpZXRhdCBUcmFuc2Zvcm1lciAnJ3swfScnIG5vIHZcdTAwZTBsaWRhLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBTQVgyRE9NIGlzIHRoZSBuYW1lIG9mIGEgSmF2YSBjbGFzcyB0aGF0IHNob3VsZAotICAgICAgICAgKiBub3QgYmUgdHJhbnNsYXRlZC4gIFRoaXMgaXMgYW4gYWRhcHRlciBpbiB0aGUgc2Vuc2UgdGhhdCBpdCB0YWtlcyBhCi0gICAgICAgICAqIERPTSBvYmplY3QgYW5kIGNvbnZlcnRzIGl0IHRvIHNvbWV0aGluZyB0aGF0IHVzZXMgdGhlIFNBWCBBUEkuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuU0FYMkRPTV9BREFQVEVSX0VSUiwKLSAgICAgICAgIk5vIHMnJ2hhIHBvZ3V0IGNyZWFyIGwnJ2FkYXB0YWRvciBTQVgyRE9NICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJYU0xUQ1NvdXJjZS5idWlsZCgpIiBpcyBhIEphdmEgbWV0aG9kIG5hbWUuCi0gICAgICAgICAqICJzeXN0ZW1JZCIgaXMgYW4gWE1MIHRlcm0gdGhhdCBpcyBzaG9ydCBmb3IgInN5c3RlbSBpZGVudGlmaWNhdGlvbiIuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuWFNMVENfU09VUkNFX0VSUiwKLSAgICAgICAgIlMnaGEgY3JpZGF0IFhTTFRDU291cmNlLmJ1aWxkKCkgc2Vuc2UgcXVlIHMnaGFndVx1MDBlOXMgZXN0YWJsZXJ0IGxhIGlkZW50aWZpY2FjaVx1MDBmMyBkZWwgc2lzdGVtYS4ifSwKLQotCi0gICAgICAgIHtFcnJvck1zZy5DT01QSUxFX1NURElOX0VSUiwKLSAgICAgICAgIkwnb3BjaVx1MDBmMyAtaSBzJ2hhIGQndXRpbGl0emFyIGFtYiBsJ29wY2lcdTAwZjMgLW8uIn0sCi0KLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGNvbnRhaW5zIHVzYWdlIGluZm9ybWF0aW9uIGZvciBhCi0gICAgICAgICAqIG1lYW5zIG9mIGludm9raW5nIFhTTFRDIGZyb20gdGhlIGNvbW1hbmQtbGluZS4gIFRoZSBtZXNzYWdlIGlzCi0gICAgICAgICAqIGZvcm1hdHRlZCBmb3IgcHJlc2VudGF0aW9uIGluIEVuZ2xpc2guICBUaGUgc3RyaW5ncyA8b3V0cHV0PiwKLSAgICAgICAgICogPGRpcmVjdG9yeT4sIGV0Yy4gaW5kaWNhdGUgdXNlci1zcGVjaWZpZWQgYXJndW1lbnQgdmFsdWVzLCBhbmQgY2FuCi0gICAgICAgICAqIGJlIHRyYW5zbGF0ZWQgLSB0aGUgYXJndW1lbnQgPHBhY2thZ2U+IHJlZmVycyB0byBhIEphdmEgcGFja2FnZSwgc28KLSAgICAgICAgICogaXQgc2hvdWxkIGJlIGhhbmRsZWQgaW4gdGhlIHNhbWUgd2F5IHRoZSB0ZXJtIGlzIGhhbmRsZWQgZm9yIEpESwotICAgICAgICAgKiBkb2N1bWVudGF0aW9uLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkNPTVBJTEVfVVNBR0VfU1RSLAotICAgICAgICAiUkVTVU1cbiAgIGphdmEgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNtZGxpbmUuQ29tcGlsZSBbLW8gPHNvcnRpZGE+XVxuICAgICAgWy1kIDxkaXJlY3Rvcmk+XSBbLWogPGZpdHhlcl9qYXI+XSBbLXAgPHBhcXVldD5dXG4gICAgICBbLW5dIFsteF0gWy1zXSBbLXVdIFstdl0gWy1oXSB7IDxmdWxsX2VzdGlscz4gfCAgLWkgfVxuXG5PUENJT05TXG4gICAtbyA8c29ydGlkYT4gICAgYXNzaWduYSBlbCBub20gPHNvcnRpZGE+IGFsIHRyYW5zbGV0XG4gZ2VuZXJhdC4gUGVyIGRlZmVjdGUsIGVsIG5vbSBkZSB0cmFuc2xldFxuIHMnb2J0XHUwMGU5IGRlbCBub20gZGUgPGZ1bGxfZXN0aWxzPi4gQXF1ZXN0YSBvcGNpXHUwMGYzXG4gbm8gZXMgdFx1MDBlOSBlbiBjb21wdGUgc2kgZXMgY29tcGlsZW4gZGl2ZXJzb3MgZnVsbHMgZCdlc3RpbHMuXG4gICAtZCA8ZGlyZWN0b3JpPiBlc3BlY2lmaWNhIHVuIGRpcmVjdG9yaSBkZSBkZXN0aW5hY2lcdTAwZjMgcGVyIGFsIHRyYW5zbGV0XG4gICAtaiA8Zml0eGVyX2phcj4gICBlbXBhcXVldGEgbGVzIGNsYXNzZXMgdHJhbnNsZXQgZW4gdW4gZml0eGVyIGphciBkZWwgbm9tXG4gICAgICAgICAgICAgICAgICBlc3BlY2lmaWNhdCBjb20gYSA8Zml0eGVyX2phcj5cbiAgIC1wIDxwYXF1ZXQ+IGVzcGVjaWZpY2EgdW4gcHJlZml4IGRlIG5vbSBkZSBwYXF1ZXQgcGVyIGEgdG90ZXMgbGVzIGNsYXNzZXNcbiAgICAgICAgICAgICAgICAgIHRyYW5zbGV0IGdlbmVyYWRlcy5cbiAtbiBoYWJpbGl0YSBsJ2lubGluaW5nIChjb20gYSBtaXRqYW5hLCBlbCBmdW5jaW9uYW1lbnQgcGVyIGRlZmVjdGVcbiBcdTAwZTlzIG1pbGxvcikuXG4gICAteCAgICAgICAgICAgIGhhYmlsaXRhIGxhIHNvcnRpZGEgZGUgbWlzc2F0Z2VzIGRlIGRlcHVyYWNpXHUwMGYzIGFkZGljaW9uYWxzXG4gICAtcyBpbmhhYmlsaXRhIGxhIGNyaWRhIGRlIFN5c3RlbS5leGl0XG4gICAtdSAgICAgICAgICAgICBpbnRlcnByZXRhIGVscyBhcmd1bWVudHMgPGZ1bGxfZXN0aWxzPiBjb20gVVJMXG4gLWkgb2JsaWdhIGVsIGNvbXBpbGFkb3IgYSBsbGVnaXIgZWwgZnVsbCBkJ2VzdGlscyBkZXMgZGUgbCdlbnRyYWRhIGVzdFx1MDBlMG5kYXJkXG4gICAtdiBpbXByaW1laXggbGEgdmVyc2lcdTAwZjMgZGVsIGNvbXBpbGFkb3JcbiAgIC1oICAgICAgICAgICAgIGltcHJpbWVpeCBhcXVlc3RhIHNlbnRcdTAwZThuY2lhIGQnXHUwMGZhcy5cbiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgY29udGFpbnMgdXNhZ2UgaW5mb3JtYXRpb24gZm9yIGEKLSAgICAgICAgICogbWVhbnMgb2YgaW52b2tpbmcgWFNMVEMgZnJvbSB0aGUgY29tbWFuZC1saW5lLiAgVGhlIG1lc3NhZ2UgaXMKLSAgICAgICAgICogZm9ybWF0dGVkIGZvciBwcmVzZW50YXRpb24gaW4gRW5nbGlzaC4gIFRoZSBzdHJpbmdzIDxqYXJmaWxlPiwKLSAgICAgICAgICogPGRvY3VtZW50PiwgZXRjLiBpbmRpY2F0ZSB1c2VyLXNwZWNpZmllZCBhcmd1bWVudCB2YWx1ZXMsIGFuZCBjYW4KLSAgICAgICAgICogYmUgdHJhbnNsYXRlZCAtIHRoZSBhcmd1bWVudCA8Y2xhc3M+IHJlZmVycyB0byBhIEphdmEgY2xhc3MsIHNvIGl0Ci0gICAgICAgICAqIHNob3VsZCBiZSBoYW5kbGVkIGluIHRoZSBzYW1lIHdheSB0aGUgdGVybSBpcyBoYW5kbGVkIGZvciBKREsKLSAgICAgICAgICogZG9jdW1lbnRhdGlvbi4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5UUkFOU0ZPUk1fVVNBR0VfU1RSLAotICAgICAgICAiUkVTVU0gXG4gICBqYXZhIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jbWRsaW5lLlRyYW5zZm9ybSBbLWogPGZpdHhlcl9qYXI+XVxuICAgICAgWy14XSBbLXNdIFstbiA8aXRlcmFjaW9ucz5dIHstdSA8dXJsX2RvY3VtZW50PiB8IDxkb2N1bWVudD59XG4gICAgICA8Y2xhc3NlPiBbPHBhclx1MDBlMG0xPj08dmFsb3IxPiAuLi5dXG5cbiAgIHV0aWxpdHphIGxhIDxjbGFzc2U+IHRyYW5zbGV0IHBlciB0cmFuc2Zvcm1hciB1biBkb2N1bWVudCBYTUxcbiAgIGVzcGVjaWZpY2F0IGNvbSBhIDxkb2N1bWVudD4uIExhIDxjbGFzc2U+IHRyYW5zbGV0IGVzIHRyb2JhXG4gICBvIGJcdTAwZTkgYSBsYSBDTEFTU1BBVEggZGUgbCd1c3VhcmkgbyBiXHUwMGU5IGFsIDxmaXR4ZXJfamFyPiBxdWUgZXMgcG90IGVzcGVjaWZpY2FyIG9wY2lvbmFsbWVudC5cbk9QQ0lPTlNcbiAgIC1qIDxmaXR4ZXJfamFyPiAgICBlc3BlY2lmaWNhIHVuIGZpdHhlciBqYXIgZGVzIGRlbCBxdWFsIGVzIHBvdCBjYXJyZWdhciBlbCB0cmFuc2xldFxuICAgLXggaGFiaWxpdGEgbGEgc29ydGlkYSBkZSBtaXNzYXRnZXMgZGUgZGVwdXJhY2lcdTAwZjMgYWRkaWNpb25hbHNcbiAgIC1zICAgICAgICAgICAgICBpbmhhYmlsaXRhIGxhIGNyaWRhIGRlIFN5c3RlbS5leGl0XG4gICAtbiA8aXRlcmFjaW9ucz4gZXhlY3V0YSBsYSB0cmFuc2Zvcm1hY2lcdTAwZjMgZWwgbm9tYnJlIGRlIHZlZ2FkZXMgPGl0ZXJhY2lvbnM+IGlcbiAgICAgICAgICAgICAgIG1vc3RyYSBpbmZvcm1hY2lcdTAwZjMgZGUgcGVyZmlsXG4gICAtdSA8dXJsX2RvY3VtZW50PiBlc3BlY2lmaWNhIGVsIGRvY3VtZW50IGQnZW50cmFkYSBYTUwgY29tIHVuYSBVUkxcbiJ9LAotCi0KLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIjx4c2w6c29ydD4iLCAiPHhzbDpmb3ItZWFjaD4iIGFuZAotICAgICAgICAgKiAiPHhzbDphcHBseS10ZW1wbGF0ZXM+IiBhcmUga2V5d29yZHMgdGhhdCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqIFRoZSBtZXNzYWdlIGluZGljYXRlcyB0aGF0IGFuIHhzbDpzb3J0IGVsZW1lbnQgbXVzdCBiZSBhIGNoaWxkIG9mCi0gICAgICAgICAqIG9uZSBvZiB0aGUgb3RoZXIga2luZHMgb2YgZWxlbWVudHMgbWVudGlvbmVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlNUUkFZX1NPUlRfRVJSLAotICAgICAgICAiPHhzbDpzb3J0PiBub21cdTAwZTlzIGVzIHBvdCB1dGlsaXR6YXIgYW1iIDx4c2w6Zm9yLWVhY2g+IG8gPHhzbDphcHBseS10ZW1wbGF0ZXM+LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUgZW5jb2RpbmcKLSAgICAgICAgICogcmVxdWVzdGVkIGZvciB0aGUgb3V0cHV0IGRvY3VtZW50IHdhcyBvbiB0aGF0IHJlcXVpcmVzIHN1cHBvcnQgdGhhdAotICAgICAgICAgKiBpcyBub3QgYXZhaWxhYmxlIGZyb20gdGhlIEphdmEgVmlydHVhbCBNYWNoaW5lIGJlaW5nIHVzZWQgdG8gZXhlY3V0ZQotICAgICAgICAgKiB0aGUgcHJvZ3JhbS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5VTlNVUFBPUlRFRF9FTkNPRElORywKLSAgICAgICAgIkFxdWVzdGEgSlZNIG5vIGRcdTAwZjNuYSBzdXBvcnQgYSBsYSBjb2RpZmljYWNpXHUwMGYzIGRlIHNvcnRpZGEgJyd7MH0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhlIFhQYXRoIGV4cHJlc3Npb24KLSAgICAgICAgICogbmFtZWQgaW4gdGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHdhcyBub3Qgd2VsbCBmb3JtZWQgc3ludGFjdGljYWxseS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5TWU5UQVhfRVJSLAotICAgICAgICAiUycnaGEgcHJvZHVcdTAwZWZ0IHVuIGVycm9yIGRlIHNpbnRheGkgYSAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYSBKYXZhCi0gICAgICAgICAqIGNsYXNzLiAgVGhlIHRlcm0gImNvbnN0cnVjdG9yIiBoZXJlIGlzIHRoZSBKYXZhIHRlcm0uICBUaGUgbWVzc2FnZSBpcwotICAgICAgICAgKiBkaXNwbGF5ZWQgaWYgWFNMVEMgY291bGQgbm90IGZpbmQgYSBjb25zdHJ1Y3RvciBmb3IgdGhlIHNwZWNpZmllZAotICAgICAgICAgKiBjbGFzcy4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5DT05TVFJVQ1RPUl9OT1RfRk9VTkQsCi0gICAgICAgICJObyBzJydoYSB0cm9iYXQgZWwgY29uc3RydWN0b3IgZXh0ZXJuICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJzdGF0aWMiIGlzIHRoZSBKYXZhIGtleXdvcmQuICBUaGUgc3Vic3RpdHV0aW9uCi0gICAgICAgICAqIHRleHQgaXMgdGhlIG5hbWUgb2YgYSBmdW5jdGlvbi4gIFRoZSBmaXJzdCBhcmd1bWVudCBvZiB0aGF0IGZ1bmN0aW9uCi0gICAgICAgICAqIGlzIG5vdCBvZiB0aGUgcmVxdWlyZWQgdHlwZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5OT19KQVZBX0ZVTkNUX1RISVNfUkVGLAotICAgICAgICAiRWwgcHJpbWVyIGFyZ3VtZW50IGRlIGxhIGZ1bmNpXHUwMGYzIEphdmEgbm8gc3RhdGljICcnezB9Jycgbm8gXHUwMGU5cyB1bmEgcmVmZXJcdTAwZThuY2lhIGQnJ29iamVjdGUgdlx1MDBlMGxpZGEuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIFhQYXRoIGV4cHJlc3Npb24gd2FzIG5vdCBvZiB0aGUgdHlwZQotICAgICAgICAgKiByZXF1aXJlZCBpbiBhIHBhcnRpY3VsYXIgY29udGV4dC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUKLSAgICAgICAgICogZXhwcmVzc2lvbiB0aGF0IHdhcyBpbiBlcnJvci4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5UWVBFX0NIRUNLX0VSUiwKLSAgICAgICAgIlMnJ2hhIHByb2R1XHUwMGVmdCB1biBlcnJvciBlbiBjb21wcm92YXIgZWwgdGlwdXMgZGUgbCcnZXhwcmVzc2lcdTAwZjMgJyd7MH0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQW4gWFBhdGggZXhwcmVzc2lvbiB3YXMgbm90IG9mIHRoZSB0eXBlCi0gICAgICAgICAqIHJlcXVpcmVkIGluIGEgcGFydGljdWxhciBjb250ZXh0LiAgSG93ZXZlciwgdGhlIGxvY2F0aW9uIG9mIHRoZQotICAgICAgICAgKiBwcm9ibGVtYXRpYyBleHByZXNzaW9uIGlzIHVua25vd24uCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVFlQRV9DSEVDS19VTktfTE9DX0VSUiwKLSAgICAgICAgIlMnaGEgcHJvZHVcdTAwZWZ0IHVuIGVycm9yIGVuIGNvbXByb3ZhciBlbCB0aXB1cyBkJ2V4cHJlc3NpXHUwMGYzIGVuIHVuYSB1YmljYWNpXHUwMGYzIGRlc2NvbmVndWRhLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYSBjb21tYW5kLQotICAgICAgICAgKiBsaW5lIG9wdGlvbiB0aGF0IHdhcyBub3QgcmVjb2duaXplZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTExFR0FMX0NNRExJTkVfT1BUSU9OX0VSUiwKLSAgICAgICAgIkwnJ29wY2lcdTAwZjMgZGUgbFx1MDBlZG5pYSBkJydvcmRyZXMgJyd7MH0nJyBubyBcdTAwZTlzIHZcdTAwZTBsaWRhLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYSBjb21tYW5kLQotICAgICAgICAgKiBsaW5lIG9wdGlvbi4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5DTURMSU5FX09QVF9NSVNTSU5HX0FSR19FUlIsCi0gICAgICAgICJBIGwnJ29wY2lcdTAwZjMgZGUgbFx1MDBlZG5pYSBkJydvcmRyZXMgJyd7MH0nJyBsaSBmYWx0YSB1biBhcmd1bWVudCBvYmxpZ2F0b3JpLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgdXNlZCB0byBpbmRpY2F0ZSB0aGUgc2V2ZXJpdHkKLSAgICAgICAgICogb2YgYW5vdGhlciBtZXNzYWdlLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGNvbnRhaW5zIHR3byBlcnJvcgotICAgICAgICAgKiBtZXNzYWdlcy4gIFRoZSBzcGFjaW5nIGJlZm9yZSB0aGUgc2Vjb25kIHN1YnN0aXR1dGlvbiB0ZXh0IGluZGVudHMKLSAgICAgICAgICogaXQgdGhlIHNhbWUgYW1vdW50IGFzIHRoZSBmaXJzdCBpbiBFbmdsaXNoLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLldBUk5JTkdfUExVU19XUkFQUEVEX01TRywKLSAgICAgICAgIkFWXHUwMGNkUzogJyd7MH0nJ1xuICAgICAgIDp7MX0ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIHVzZWQgdG8gaW5kaWNhdGUgdGhlIHNldmVyaXR5Ci0gICAgICAgICAqIG9mIGFub3RoZXIgbWVzc2FnZS4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyBhbiBlcnJvciBtZXNzYWdlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLldBUk5JTkdfTVNHLAotICAgICAgICAiQVZcdTAwY2RTOiAnJ3swfScnIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyB1c2VkIHRvIGluZGljYXRlIHRoZSBzZXZlcml0eQotICAgICAgICAgKiBvZiBhbm90aGVyIG1lc3NhZ2UuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgY29udGFpbnMgdHdvIGVycm9yCi0gICAgICAgICAqIG1lc3NhZ2VzLiAgVGhlIHNwYWNpbmcgYmVmb3JlIHRoZSBzZWNvbmQgc3Vic3RpdHV0aW9uIHRleHQgaW5kZW50cwotICAgICAgICAgKiBpdCB0aGUgc2FtZSBhbW91bnQgYXMgdGhlIGZpcnN0IGluIEVuZ2xpc2guCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuRkFUQUxfRVJSX1BMVVNfV1JBUFBFRF9NU0csCi0gICAgICAgICJFUlJPUiBNT0xUIEdSRVU6ICcnezB9JydcbiAgICAgICAgICAgOnsxfSJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgdXNlZCB0byBpbmRpY2F0ZSB0aGUgc2V2ZXJpdHkKLSAgICAgICAgICogb2YgYW5vdGhlciBtZXNzYWdlLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIGFuIGVycm9yIG1lc3NhZ2UuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuRkFUQUxfRVJSX01TRywKLSAgICAgICAgIkVSUk9SIE1PTFQgR1JFVTogJyd7MH0nJyJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgdXNlZCB0byBpbmRpY2F0ZSB0aGUgc2V2ZXJpdHkKLSAgICAgICAgICogb2YgYW5vdGhlciBtZXNzYWdlLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGNvbnRhaW5zIHR3byBlcnJvcgotICAgICAgICAgKiBtZXNzYWdlcy4gIFRoZSBzcGFjaW5nIGJlZm9yZSB0aGUgc2Vjb25kIHN1YnN0aXR1dGlvbiB0ZXh0IGluZGVudHMKLSAgICAgICAgICogaXQgdGhlIHNhbWUgYW1vdW50IGFzIHRoZSBmaXJzdCBpbiBFbmdsaXNoLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkVSUk9SX1BMVVNfV1JBUFBFRF9NU0csCi0gICAgICAgICJFUlJPUjogICcnezB9JydcbiAgICAgOnsxfSJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgdXNlZCB0byBpbmRpY2F0ZSB0aGUgc2V2ZXJpdHkKLSAgICAgICAgICogb2YgYW5vdGhlciBtZXNzYWdlLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIGFuIGVycm9yIG1lc3NhZ2UuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuRVJST1JfTVNHLAotICAgICAgICAiRVJST1I6ICAnJ3swfScnIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBhIGNsYXNzLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlRSQU5TRk9STV9XSVRIX1RSQU5TTEVUX1NUUiwKLSAgICAgICAgIlRyYW5zZm9ybWFjaVx1MDBmMyBtaXRqYW5cdTAwZTdhbnQgdHJhbnNsZXQgJyd7MH0nJyAifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZpcnN0IHN1YnN0aXR1dGlvbiBpcyB0aGUgbmFtZSBvZiBhIGNsYXNzLAotICAgICAgICAgKiB3aGlsZSB0aGUgc2Vjb25kIHN1YnN0aXR1dGlvbiBpcyB0aGUgbmFtZSBvZiBhIGphciBmaWxlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlRSQU5TRk9STV9XSVRIX0pBUl9TVFIsCi0gICAgICAgICJUcmFuc2Zvcm1hY2lcdTAwZjMgbWl0amFuXHUwMGU3YW50IHRyYW5zbGV0ICcnezB9JycgZGVzIGRlbCBmaXR4ZXIgamFyICcnezF9JycifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIlRyYW5zZm9ybWVyRmFjdG9yeSIgaXMgdGhlIG5hbWUgb2YgYSBKYXZhCi0gICAgICAgICAqIGludGVyZmFjZSBhbmQgbXVzdCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcwotICAgICAgICAgKiB0aGUgbmFtZSBvZiB0aGUgY2xhc3MgdGhhdCBjb3VsZCBub3QgYmUgaW5zdGFudGlhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkNPVUxEX05PVF9DUkVBVEVfVFJBTlNfRkFDVCwKLSAgICAgICAgIk5vIHMnJ2hhIHBvZ3V0IGNyZWFyIHVuYSBpbnN0XHUwMGUwbmNpYSBkZSBsYSBjbGFzc2UgVHJhbnNmb3JtZXJGYWN0b3J5ICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBpcyB1c2VkIGFzIGEgaGVhZGVyLgotICAgICAgICAgKiBBbGwgdGhlIGVycm9yIG1lc3NhZ2VzIGFyZSBjb2xsZWN0ZWQgdG9nZXRoZXIgYW5kIGRpc3BsYXllZCBiZW5lYXRoCi0gICAgICAgICAqIHRoaXMgbWVzc2FnZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5DT01QSUxFUl9FUlJPUl9LRVksCi0gICAgICAgICJFcnJvcnMgZGVsIGNvbXBpbGFkb3I6In0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBpcyB1c2VkIGFzIGEgaGVhZGVyLgotICAgICAgICAgKiBBbGwgdGhlIHdhcm5pbmcgbWVzc2FnZXMgYXJlIGNvbGxlY3RlZCB0b2dldGhlciBhbmQgZGlzcGxheWVkCi0gICAgICAgICAqIGJlbmVhdGggdGhpcyBtZXNzYWdlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkNPTVBJTEVSX1dBUk5JTkdfS0VZLAotICAgICAgICAiQXZpc29zIGRlbCBjb21waWxhZG9yOiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgaXMgdXNlZCBhcyBhIGhlYWRlci4KLSAgICAgICAgICogQWxsIHRoZSBlcnJvciBtZXNzYWdlcyB0aGF0IGFyZSBwcm9kdWNlZCB3aGVuIHRoZSBzdHlsZXNoZWV0IGlzCi0gICAgICAgICAqIGFwcGxpZWQgdG8gYW4gaW5wdXQgZG9jdW1lbnQgYXJlIGNvbGxlY3RlZCB0b2dldGhlciBhbmQgZGlzcGxheWVkCi0gICAgICAgICAqIGJlbmVhdGggdGhpcyBtZXNzYWdlLiAgQSAndHJhbnNsZXQnIGlzIHRoZSBjb21waWxlZCBmb3JtIG9mIGEKLSAgICAgICAgICogc3R5bGVzaGVldCAoc2VlIGFib3ZlKS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5SVU5USU1FX0VSUk9SX0tFWSwKLSAgICAgICAgIkVycm9ycyBkZSB0cmFuc2xldDoifSwKLQotICAgICAgICB7RXJyb3JNc2cuSkFYUF9TRUNVUkVQUk9DRVNTSU5HX0ZFQVRVUkUsCi0gICAgICAgICJGRUFUVVJFX1NFQ1VSRV9QUk9DRVNTSU5HOiBDYW5ub3Qgc2V0IHRoZSBmZWF0dXJlIHRvIGZhbHNlIHdoZW4gc2VjdXJpdHkgbWFuYWdlciBpcyBwcmVzZW50LiJ9Ci0gICAgfTsKLQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvdXRpbC9FcnJvck1lc3NhZ2VzX2NzLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL3V0aWwvRXJyb3JNZXNzYWdlc19jcy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmMTcyNjQzLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvdXRpbC9FcnJvck1lc3NhZ2VzX2NzLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4NjMgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRXJyb3JNZXNzYWdlc19jcy5qYXZhLHYgMS4xLjYuMSAyMDA1LzA5LzA1IDExOjUyOjU5IHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsOwotCi1pbXBvcnQgamF2YS51dGlsLkxpc3RSZXNvdXJjZUJ1bmRsZTsKLQotLyoqCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqLwotcHVibGljIGNsYXNzIEVycm9yTWVzc2FnZXNfY3MgZXh0ZW5kcyBMaXN0UmVzb3VyY2VCdW5kbGUgewotCi0vKgotICogWFNMVEMgY29tcGlsZS10aW1lIGVycm9yIG1lc3NhZ2VzLgotICoKLSAqIEdlbmVyYWwgbm90ZXMgdG8gdHJhbnNsYXRvcnMgYW5kIGRlZmluaXRpb25zOgotICoKLSAqICAgMSkgWFNMVEMgaXMgdGhlIG5hbWUgb2YgdGhlIHByb2R1Y3QuICBJdCBpcyBhbiBhY3JvbnltIGZvciAiWFNMVCBDb21waWxlciIuCi0gKiAgICAgIFhTTFQgaXMgYW4gYWNyb255bSBmb3IgIlhNTCBTdHlsZXNoZWV0IExhbmd1YWdlOiBUcmFuc2Zvcm1hdGlvbnMiLgotICoKLSAqICAgMikgQSBzdHlsZXNoZWV0IGlzIGEgZGVzY3JpcHRpb24gb2YgaG93IHRvIHRyYW5zZm9ybSBhbiBpbnB1dCBYTUwgZG9jdW1lbnQKLSAqICAgICAgaW50byBhIHJlc3VsdGFudCBYTUwgZG9jdW1lbnQgKG9yIEhUTUwgZG9jdW1lbnQgb3IgdGV4dCkuICBUaGUKLSAqICAgICAgc3R5bGVzaGVldCBpdHNlbGYgaXMgZGVzY3JpYmVkIGluIHRoZSBmb3JtIG9mIGFuIFhNTCBkb2N1bWVudC4KLSAqCi0gKiAgIDMpIEEgdGVtcGxhdGUgaXMgYSBjb21wb25lbnQgb2YgYSBzdHlsZXNoZWV0IHRoYXQgaXMgdXNlZCB0byBtYXRjaCBhCi0gKiAgICAgIHBhcnRpY3VsYXIgcG9ydGlvbiBvZiBhbiBpbnB1dCBkb2N1bWVudCBhbmQgc3BlY2lmaWVzIHRoZSBmb3JtIG9mIHRoZQotICogICAgICBjb3JyZXNwb25kaW5nIHBvcnRpb24gb2YgdGhlIG91dHB1dCBkb2N1bWVudC4KLSAqCi0gKiAgIDQpIEFuIGF4aXMgaXMgYSBwYXJ0aWN1bGFyICJkaW1lbnNpb24iIGluIGEgdHJlZSByZXByZXNlbnRhdGlvbiBvZiBhbiBYTUwKLSAqICAgICAgZG9jdW1lbnQ7IHRoZSBub2RlcyBpbiB0aGUgdHJlZSBhcmUgZGl2aWRlZCBhbG9uZyBkaWZmZXJlbnQgYXhlcy4KLSAqICAgICAgVHJhdmVyc2luZyB0aGUgImNoaWxkIiBheGlzLCBmb3IgaW5zdGFuY2UsIG1lYW5zIHRoYXQgdGhlIHByb2dyYW0KLSAqICAgICAgd291bGQgdmlzaXQgZWFjaCBjaGlsZCBvZiBhIHBhcnRpY3VsYXIgbm9kZTsgdHJhdmVyc2luZyB0aGUgImRlc2NlbmRhbnQiCi0gKiAgICAgIGF4aXMgbWVhbnMgdGhhdCB0aGUgcHJvZ3JhbSB3b3VsZCB2aXNpdCB0aGUgY2hpbGQgbm9kZXMgb2YgYSBwYXJ0aWN1bGFyCi0gKiAgICAgIG5vZGUsIHRoZWlyIGNoaWxkcmVuLCBhbmQgc28gb24gdW50aWwgdGhlIGxlYWYgbm9kZXMgb2YgdGhlIHRyZWUgYXJlCi0gKiAgICAgIHJlYWNoZWQuCi0gKgotICogICA1KSBBbiBpdGVyYXRvciBpcyBhbiBvYmplY3QgdGhhdCB0cmF2ZXJzZXMgbm9kZXMgaW4gYSB0cmVlIGFsb25nIGEKLSAqICAgICAgcGFydGljdWxhciBheGlzLCBvbmUgYXQgYSB0aW1lLgotICoKLSAqICAgNikgQW4gZWxlbWVudCBpcyBhIG1hcmstdXAgdGFnIGluIGFuIFhNTCBkb2N1bWVudDsgYW4gYXR0cmlidXRlIGlzIGEKLSAqICAgICAgbW9kaWZpZXIgb24gdGhlIHRhZy4gIEZvciBleGFtcGxlLCBpbiA8ZWxlbSBhdHRyPSd2YWwnIGF0dHIyPSd2YWwyJz4KLSAqICAgICAgImVsZW0iIGlzIGFuIGVsZW1lbnQgbmFtZSwgImF0dHIiIGFuZCAiYXR0cjIiIGFyZSBhdHRyaWJ1dGUgbmFtZXMgd2l0aAotICogICAgICB0aGUgdmFsdWVzICJ2YWwiIGFuZCAidmFsMiIsIHJlc3BlY3RpdmVseS4KLSAqCi0gKiAgIDcpIEEgbmFtZXNwYWNlIGRlY2xhcmF0aW9uIGlzIGEgc3BlY2lhbCBhdHRyaWJ1dGUgdGhhdCBpcyB1c2VkIHRvIGFzc29jaWF0ZQotICogICAgICBhIHByZWZpeCB3aXRoIGEgVVJJICh0aGUgbmFtZXNwYWNlKS4gIFRoZSBtZWFuaW5ncyBvZiBlbGVtZW50IG5hbWVzIGFuZAotICogICAgICBhdHRyaWJ1dGUgbmFtZXMgdGhhdCB1c2UgdGhhdCBwcmVmaXggYXJlIGRlZmluZWQgd2l0aCByZXNwZWN0IHRvIHRoYXQKLSAqICAgICAgbmFtZXNwYWNlLgotICoKLSAqICAgOCkgRE9NIGlzIGFuIGFjcm9ueW0gZm9yIERvY3VtZW50IE9iamVjdCBNb2RlbC4gIEl0IGlzIGEgdHJlZQotICogICAgICByZXByZXNlbnRhdGlvbiBvZiBhbiBYTUwgZG9jdW1lbnQuCi0gKgotICogICAgICBTQVggaXMgYW4gYWNyb255bSBmb3IgdGhlIFNpbXBsZSBBUEkgZm9yIFhNTCBwcm9jZXNzaW5nLiAgSXQgaXMgYW4gQVBJCi0gKiAgICAgIHVzZWQgaW5mb3JtIGFuIFhNTCBwcm9jZXNzb3IgKGluIHRoaXMgY2FzZSBYU0xUQykgb2YgdGhlIHN0cnVjdHVyZSBhbmQKLSAqICAgICAgY29udGVudCBvZiBhbiBYTUwgZG9jdW1lbnQuCi0gKgotICogICAgICBJbnB1dCB0byB0aGUgc3R5bGVzaGVldCBwcm9jZXNzb3IgY2FuIGNvbWUgZnJvbSBhbiBYTUwgcGFyc2VyIGluIHRoZQotICogICAgICBmb3JtIG9mIGEgRE9NIHRyZWUgb3IgdGhyb3VnaCB0aGUgU0FYIEFQSS4KLSAqCi0gKiAgIDkpIERURCBpcyBhIGRvY3VtZW50IHR5cGUgZGVjbGFyYXRpb24uICBJdCBpcyBhIHdheSBvZiBzcGVjaWZ5aW5nIHRoZQotICogICAgICBncmFtbWFyIGZvciBhbiBYTUwgZmlsZSwgdGhlIG5hbWVzIGFuZCB0eXBlcyBvZiBlbGVtZW50cywgYXR0cmlidXRlcywKLSAqICAgICAgZXRjLgotICoKLSAqICAxMCkgWFBhdGggaXMgYSBzcGVjaWZpY2F0aW9uIHRoYXQgZGVzY3JpYmVzIGEgbm90YXRpb24gZm9yIGlkZW50aWZ5aW5nCi0gKiAgICAgIG5vZGVzIGluIGEgdHJlZS1zdHJ1Y3R1cmVkIHJlcHJlc2VudGF0aW9uIG9mIGFuIFhNTCBkb2N1bWVudC4gIEFuCi0gKiAgICAgIGluc3RhbmNlIG9mIHRoYXQgbm90YXRpb24gaXMgcmVmZXJyZWQgdG8gYXMgYW4gWFBhdGggZXhwcmVzc2lvbi4KLSAqCi0gKiAgMTEpIFRyYW5zbGV0IGlzIGFuIGludmVudGVkIHRlcm0gdGhhdCByZWZlcnMgdG8gdGhlIGNsYXNzIGZpbGUgdGhhdCBjb250YWlucwotICogICAgICB0aGUgY29tcGlsZWQgZm9ybSBvZiBhIHN0eWxlc2hlZXQuCi0gKi8KLQotICAgIC8vIFRoZXNlIG1lc3NhZ2Ugc2hvdWxkIGJlIHJlYWQgZnJvbSBhIGxvY2FsZS1zcGVjaWZpYyByZXNvdXJjZSBidW5kbGUKLSAgICAvKiogR2V0IHRoZSBsb29rdXAgdGFibGUgZm9yIGVycm9yIG1lc3NhZ2VzLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgbWVzc2FnZSBsb29rdXAgdGFibGUuCi0gICAgICovCi0gICAgcHVibGljIE9iamVjdFtdW10gZ2V0Q29udGVudHMoKQotICAgIHsKLSAgICAgIHJldHVybiBuZXcgT2JqZWN0W11bXSB7Ci0gICAgICAgIHtFcnJvck1zZy5NVUxUSVBMRV9TVFlMRVNIRUVUX0VSUiwKLSAgICAgICAgIlZcdTAwZWRjZSBuZVx1MDE3ZSBqZWRuYSBwXHUwMTU5ZWRsb2hhIHN0eWx1IGplIGRlZmlub3ZcdTAwZTFuYSB2ZSBzdGVqblx1MDBlOW0gc291Ym9ydS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIGEKLSAgICAgICAgICogdGVtcGxhdGUuICBUaGUgc2FtZSBuYW1lIHdhcyB1c2VkIG9uIHR3byBkaWZmZXJlbnQgdGVtcGxhdGVzIGluIHRoZQotICAgICAgICAgKiBzYW1lIHN0eWxlc2hlZXQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVEVNUExBVEVfUkVERUZfRVJSLAotICAgICAgICAiXHUwMTYwYWJsb25hICcnezB9JycgamUgamlcdTAxN2UgdiB0XHUwMGU5dG8gcFx1MDE1OWVkbG96ZSBzdHlsdSBkZWZpbm92XHUwMGUxbmEuIn0sCi0KLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIGEKLSAgICAgICAgICogdGVtcGxhdGUuICBBIHJlZmVyZW5jZSB0byB0aGUgdGVtcGxhdGUgbmFtZSB3YXMgZW5jb3VudGVyZWQsIGJ1dCB0aGUKLSAgICAgICAgICogdGVtcGxhdGUgaXMgdW5kZWZpbmVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlRFTVBMQVRFX1VOREVGX0VSUiwKLSAgICAgICAgIlx1MDE2MGFibG9uYSAnJ3swfScnIG5lblx1MDBlZCB2IHRcdTAwZTl0byBwXHUwMTU5ZWRsb3plIHN0eWx1IGRlZmlub3ZcdTAwZTFuYS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIGEgdmFyaWFibGUKLSAgICAgICAgICogdGhhdCB3YXMgZGVmaW5lZCBtb3JlIHRoYW4gb25jZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5WQVJJQUJMRV9SRURFRl9FUlIsCi0gICAgICAgICJQcm9tXHUwMTFibm5cdTAwZTEgJyd7MH0nJyBqZSBuXHUwMTFia29saWthblx1MDBlMXNvYm5cdTAxMWIgZGVmaW5vdlx1MDBlMW5hIHZlIHN0ZWpuXHUwMGU5bSBvYm9ydS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIGEgdmFyaWFibGUKLSAgICAgICAgICogb3IgcGFyYW1ldGVyLiAgQSByZWZlcmVuY2UgdG8gdGhlIHZhcmlhYmxlIG9yIHBhcmFtZXRlciB3YXMgZm91bmQsCi0gICAgICAgICAqIGJ1dCBpdCB3YXMgbmV2ZXIgZGVmaW5lZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5WQVJJQUJMRV9VTkRFRl9FUlIsCi0gICAgICAgICJQcm9tXHUwMTFibm5cdTAwZTEgbmVibyBwYXJhbWV0ciAnJ3swfScnIG5lanNvdSBkZWZpbm92XHUwMGUxbnkuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSB3b3JkICJjbGFzcyIgaGVyZSByZWZlcnMgdG8gYSBKYXZhIGNsYXNzLgotICAgICAgICAgKiBQcm9jZXNzaW5nIHRoZSBzdHlsZXNoZWV0IHJlcXVpcmVkIGEgY2xhc3MgdG8gYmUgbG9hZGVkLCBidXQgaXQgY291bGQKLSAgICAgICAgICogbm90IGJlIGZvdW5kLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIHRoZSBjbGFzcy4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5DTEFTU19OT1RfRk9VTkRfRVJSLAotICAgICAgICAiTmVsemUgbmFqXHUwMGVkdCB0XHUwMTU5XHUwMGVkZHUgJyd7MH0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHdvcmQgIm1ldGhvZCIgaGVyZSByZWZlcnMgdG8gYSBKYXZhIG1ldGhvZC4KLSAgICAgICAgICogUHJvY2Vzc2luZyB0aGUgc3R5bGVzaGVldCByZXF1aXJlZCBhIHJlZmVyZW5jZSB0byB0aGUgbWV0aG9kIG5hbWVkIGJ5Ci0gICAgICAgICAqIHRoZSBzdWJzdGl0dXRpb24gdGV4dCwgYnV0IGl0IGNvdWxkIG5vdCBiZSBmb3VuZC4gICJwdWJsaWMiIGlzIHRoZQotICAgICAgICAgKiBKYXZhIGtleXdvcmQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTUVUSE9EX05PVF9GT1VORF9FUlIsCi0gICAgICAgICJOZWx6ZSBuYWpcdTAwZWR0IGV4dGVyblx1MDBlZCBtZXRvZHUgJyd7MH0nJyAobXVzXHUwMGVkIGJcdTAwZmR0IHZlXHUwMTU5ZWpuXHUwMGUxKS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHdvcmQgIm1ldGhvZCIgaGVyZSByZWZlcnMgdG8gYSBKYXZhIG1ldGhvZC4KLSAgICAgICAgICogUHJvY2Vzc2luZyB0aGUgc3R5bGVzaGVldCByZXF1aXJlZCBhIHJlZmVyZW5jZSB0byB0aGUgbWV0aG9kIG5hbWVkIGJ5Ci0gICAgICAgICAqIHRoZSBzdWJzdGl0dXRpb24gdGV4dCwgYnV0IG5vIG1ldGhvZCB3aXRoIHRoZSByZXF1aXJlZCB0eXBlcyBvZgotICAgICAgICAgKiBhcmd1bWVudHMgb3IgcmV0dXJuIHR5cGUgY291bGQgYmUgZm91bmQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuQVJHVU1FTlRfQ09OVkVSU0lPTl9FUlIsCi0gICAgICAgICJOZWx6ZSBwXHUwMTU5ZXZcdTAwZTlzdCBhcmd1bWVudC9uXHUwMGUxdnJhdG92XHUwMGZkIHR5cCB2ZSB2b2xcdTAwZTFuXHUwMGVkIG1ldG9keSAnJ3swfScnIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmaWxlIG9yIFVSSSBuYW1lZCBpbiB0aGUgc3Vic3RpdHV0aW9uIHRleHQKLSAgICAgICAgICogaXMgbWlzc2luZy4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5GSUxFX05PVF9GT1VORF9FUlIsCi0gICAgICAgICJTb3Vib3IgbmVibyBVUkkgJyd7MH0nJyBuZWJ5bCBuYWxlemVuLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgZGlzcGxheWVkIHdoZW4gdGhlIFVSSQotICAgICAgICAgKiBtZW50aW9uZWQgaW4gdGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIG5vdCB3ZWxsLWZvcm1lZCBzeW50YWN0aWNhbGx5LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklOVkFMSURfVVJJX0VSUiwKLSAgICAgICAgIk5lcGxhdG5cdTAwZTkgVVJJICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmaWxlIG9yIFVSSSBuYW1lZCBpbiB0aGUgc3Vic3RpdHV0aW9uIHRleHQKLSAgICAgICAgICogZXhpc3RzIGJ1dCBjb3VsZCBub3QgYmUgb3BlbmVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkZJTEVfQUNDRVNTX0VSUiwKLSAgICAgICAgIk5lbHplIG90ZXZcdTAxNTlcdTAwZWR0IHNvdWJvciBuZWJvIFVSSSAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6IDx4c2w6c3R5bGVzaGVldD4gYW5kIDx4c2w6dHJhbnNmb3JtPiBhcmUKLSAgICAgICAgICoga2V5d29yZHMgdGhhdCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTUlTU0lOR19ST09UX0VSUiwKLSAgICAgICAgIkJ5bCBvXHUwMTBkZWtcdTAwZTF2XHUwMGUxbiBwcnZlayA8eHNsOnN0eWxlc2hlZXQ+IG5lYm8gPHhzbDp0cmFuc2Zvcm0+LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3R5bGVzaGVldCBjb250YWluZWQgYSByZWZlcmVuY2UgdG8gYQotICAgICAgICAgKiBuYW1lc3BhY2UgcHJlZml4IHRoYXQgd2FzIHVuZGVmaW5lZC4gIFRoZSB2YWx1ZSBvZiB0aGUgc3Vic3RpdHV0aW9uCi0gICAgICAgICAqIHRleHQgaXMgdGhlIG5hbWUgb2YgdGhlIHByZWZpeC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5OQU1FU1BBQ0VfVU5ERUZfRVJSLAotICAgICAgICAiUFx1MDE1OWVkcG9uYSBvYm9ydSBuXHUwMGUxenZcdTAxNmYgJyd7MH0nJyBuZW5cdTAwZWQgZGVrbGFyb3ZcdTAwZTFuYS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIEphdmEgZnVuY3Rpb24gbmFtZWQgaW4gdGhlIHN0eWxlc2hlZXQgY291bGQKLSAgICAgICAgICogbm90IGJlIGZvdW5kLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkZVTkNUSU9OX1JFU09MVkVfRVJSLAotICAgICAgICAiTmVsemUgdnlcdTAxNTllXHUwMTYxaXQgdm9sXHUwMGUxblx1MDBlZCBmdW5rY2UgJyd7MH0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIGEKLSAgICAgICAgICogZnVuY3Rpb24uICBBIGxpdGVyYWwgc3RyaW5nIGhlcmUgbWVhbnMgYSBjb25zdGFudCBzdHJpbmcgdmFsdWUuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTkVFRF9MSVRFUkFMX0VSUiwKLSAgICAgICAgIkFyZ3VtZW50IHBybyAnJ3swfScnIG11c1x1MDBlZCBiXHUwMGZkdCBcdTAxNTlldFx1MDExYnpjZW0gbGl0ZXJcdTAwZTFsdS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGluZGljYXRlcyB0aGVyZSB3YXMgYSBzeW50YWN0aWMKLSAgICAgICAgICogZXJyb3IgaW4gdGhlIGZvcm0gb2YgYW4gWFBhdGggZXhwcmVzc2lvbi4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcwotICAgICAgICAgKiB0aGUgZXhwcmVzc2lvbi4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5YUEFUSF9QQVJTRVJfRVJSLAotICAgICAgICAiQ2h5YmEgcFx1MDE1OWkgYW5hbFx1MDBmZHplIHZcdTAwZmRyYXp1IFhQYXRoICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIGVsZW1lbnQgaW4gdGhlIHN0eWxlc2hlZXQgcmVxdWlyZXMgYQotICAgICAgICAgKiBwYXJ0aWN1bGFyIGF0dHJpYnV0ZSBuYW1lZCBieSB0aGUgc3Vic3RpdHV0aW9uIHRleHQsIGJ1dCB0aGF0Ci0gICAgICAgICAqIGF0dHJpYnV0ZSB3YXMgbm90IHNwZWNpZmllZCBpbiB0aGUgc3R5bGVzaGVldC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5SRVFVSVJFRF9BVFRSX0VSUiwKLSAgICAgICAgIlBvXHUwMTdlYWRvdmFuXHUwMGZkIGF0cmlidXQgJyd7MH0nJyBjaHliXHUwMGVkLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgYSBjaGFyYWN0ZXIgbm90Ci0gICAgICAgICAqIHBlcm1pdHRlZCBpbiBhbiBYUGF0aCBleHByZXNzaW9uIHdhcyBlbmNvdW50ZXJlZC4gIFRoZSBzdWJzdGl0dXRpb24KLSAgICAgICAgICogdGV4dCBpcyB0aGUgb2ZmZW5kaW5nIGNoYXJhY3Rlci4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTExFR0FMX0NIQVJfRVJSLAotICAgICAgICAiTmVwbGF0blx1MDBmZCB6bmFrICcnezB9JycgdmUgdlx1MDBmZHJhenUgWFBhdGguIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEEgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiBpcyBhIG1hcmstdXAgaXRlbSBpbgotICAgICAgICAgKiBhbiBYTUwgZG9jdW1lbnQgdGhhdCByZXF1ZXN0IHNvbWUgYmVoYXZpb3VyIG9mIGFuIFhNTCBwcm9jZXNzb3IuICBUaGUKLSAgICAgICAgICogZm9ybSBvZiB0aGUgbmFtZSBvZiB3YXMgaW52YWxpZCBpbiB0aGlzIGNhc2UsIGFuZCB0aGUgc3Vic3RpdHV0aW9uCi0gICAgICAgICAqIHRleHQgaXMgdGhlIG5hbWUuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSUxMRUdBTF9QSV9FUlIsCi0gICAgICAgICJOZXBsYXRuXHUwMGZkIG5cdTAwZTF6ZXYgJyd7MH0nJyBwcm8genByYWNvdlx1MDBlMW5cdTAwZWQgaW5zdHJ1a2NlLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgcmVwb3J0ZWQgaWYgdGhlIHN0eWxlc2hlZXQKLSAgICAgICAgICogYmVpbmcgcHJvY2Vzc2VkIGF0dGVtcHRlZCB0byBjb25zdHJ1Y3QgYW4gWE1MIGRvY3VtZW50IHdpdGggYW4KLSAgICAgICAgICogYXR0cmlidXRlIGluIGEgcGxhY2Ugb3RoZXIgdGhhbiBvbiBhbiBlbGVtZW50LiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgICAqIHNwZWNpZmllcyB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlNUUkFZX0FUVFJJQlVURV9FUlIsCi0gICAgICAgICJBdHJpYnV0ICcnezB9JycgamUgdm5cdTAxMWIgcHJ2a3UuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIGF0dHJpYnV0ZSB0aGF0IHdhc24ndCByZWNvZ25pemVkIHdhcwotICAgICAgICAgKiBzcGVjaWZpZWQgb24gYW4gZWxlbWVudCBpbiB0aGUgc3R5bGVzaGVldC4gIFRoZSBhdHRyaWJ1dGUgaXMgbmFtZWQKLSAgICAgICAgICogYnkgdGhlIHN1YnN0aXR1dGlvbgotICAgICAgICAgKiB0ZXh0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfQVRUUklCVVRFX0VSUiwKLSAgICAgICAgIk5lcGxhdG5cdTAwZmQgYXRyaWJ1dCAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiaW1wb3J0IiBhbmQgImluY2x1ZGUiIGFyZSBrZXl3b3JkcyB0aGF0IHNob3VsZAotICAgICAgICAgKiBub3QgYmUgdHJhbnNsYXRlZC4gIFRoaXMgbWVzc2FnZXMgaW5kaWNhdGVzIHRoYXQgdGhlIHN0eWxlc2hlZXQKLSAgICAgICAgICogbmFtZWQgaW4gdGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGltcG9ydGVkIG9yIGluY2x1ZGVkIGl0c2VsZiBlaXRoZXIKLSAgICAgICAgICogZGlyZWN0bHkgb3IgaW5kaXJlY3RseS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5DSVJDVUxBUl9JTkNMVURFX0VSUiwKLSAgICAgICAgIkN5a2xpY2tcdTAwZmQgaW1wb3J0L3phaHJudXRcdTAwZWQuIFBcdTAxNTllZGxvaGEgc3R5bHUgJyd7MH0nJyBqZSBqaVx1MDE3ZSB6YXZlZGVuYS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQSByZXN1bHQtdHJlZSBmcmFnbWVudCBpcyBhIHBvcnRpb24gb2YgYQotICAgICAgICAgKiByZXN1bHRpbmcgWE1MIGRvY3VtZW50IHJlcHJlc2VudGVkIGFzIGEgdHJlZS4gICI8eHNsOnNvcnQ+IiBpcyBhCi0gICAgICAgICAqIGtleXdvcmQgYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5SRVNVTFRfVFJFRV9TT1JUX0VSUiwKLSAgICAgICAgIkZyYWdtZW50eSBzdHJvbXUgdlx1MDBmZHNsZWRrXHUwMTZmIG5lbW9ob3UgYlx1MDBmZHQgXHUwMTU5YXplbnkgKHBydmt5IDx4c2w6c29ydD4gc2UgaWdub3J1alx1MDBlZCkuIFBcdTAxNTlpIHZ5dHZcdTAwZTFcdTAxNTllblx1MDBlZCBzdHJvbXUgdlx1MDBmZHNsZWRrXHUwMTZmIG11c1x1MDBlZHRlIHNlXHUwMTU5YWRpdCB1emx5LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBIG5hbWUgY2FuIGJlIGdpdmVuIHRvIGEgcGFydGljdWxhciBzdHlsZSB0byBiZQotICAgICAgICAgKiB1c2VkIHRvIGZvcm1hdCBkZWNpbWFsIHZhbHVlcy4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBnaXZlcyB0aGUgbmFtZQotICAgICAgICAgKiBvZiBzdWNoIGEgc3R5bGUgZm9yIHdoaWNoIG1vcmUgdGhhbiBvbmUgZGVjbGFyYXRpb24gd2FzIGVuY291bnRlcmVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlNZTUJPTFNfUkVERUZfRVJSLAotICAgICAgICAiRGVzZXRpbm5cdTAwZTkgZm9ybVx1MDBlMXRvdlx1MDBlMW5cdTAwZWQgJyd7MH0nJyBqZSBqaVx1MDE3ZSBkZWZpbm92XHUwMGUxbm8uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IHZlcnNpb24gbmFtZWQgaW4gdGhlCi0gICAgICAgICAqIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIG5vdCBzdXBwb3J0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuWFNMX1ZFUlNJT05fRVJSLAotICAgICAgICAiVmVyemUgWFNMICcnezB9JycgbmVuXHUwMGVkIHByb2R1a3RlbSBYU0xUQyBwb2Rwb3Jvdlx1MDBlMW5hLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZGVmaW5pdGlvbnMgb2Ygb25lIG9yIG1vcmUgdmFyaWFibGVzIG9yCi0gICAgICAgICAqIHBhcmFtZXRlcnMgZGVwZW5kIG9uIG9uZSBhbm90aGVyLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkNJUkNVTEFSX1ZBUklBQkxFX0VSUiwKLSAgICAgICAgIkN5a2xpY2tcdTAwZmQgb2RrYXogbmEgcHJvbVx1MDExYm5ub3UvcGFyYW1ldHIgdiAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgb3BlcmF0b3IgaW4gYW4gZXhwcmVzaW9uIHdpdGggdHdvIG9wZXJhbmRzIHdhcwotICAgICAgICAgKiBub3QgcmVjb2duaXplZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTExFR0FMX0JJTkFSWV9PUF9FUlIsCi0gICAgICAgICJOZXpuXHUwMGUxbVx1MDBmZCBvcGVyXHUwMGUxdG9yIHBybyBiaW5cdTAwZTFyblx1MDBlZCB2XHUwMGZkcmF6LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgcHJvZHVjZWQgaWYgYSByZWZlcmVuY2UgdG8gYQotICAgICAgICAgKiBmdW5jdGlvbiBoYXMgdG9vIG1hbnkgb3IgdG9vIGZldyBhcmd1bWVudHMuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSUxMRUdBTF9BUkdfRVJSLAotICAgICAgICAiTmVwbGF0blx1MDBmZCBhcmd1bWVudCBwcm8gdm9sXHUwMGUxblx1MDBlZCBmdW5rY2UuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJkb2N1bWVudCgpIiBpcyB0aGUgbmFtZSBvZiBmdW5jdGlvbiBhbmQgbXVzdAotICAgICAgICAgKiBub3QgYmUgdHJhbnNsYXRlZC4gIEEgbm9kZS1zZXQgaXMgYSBzZXQgb2YgdGhlIG5vZGVzIGluIHRoZSB0cmVlCi0gICAgICAgICAqIHJlcHJlc2VudGF0aW9uIG9mIGFuIFhNTCBkb2N1bWVudC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5ET0NVTUVOVF9BUkdfRVJSLAotICAgICAgICAiRHJ1aFx1MDBmZCBhcmd1bWVudCBwcm8gZnVua2NpIGRvY3VtZW50KCkgbXVzXHUwMGVkIGJcdTAwZmR0IG5vZGUtc2V0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiPHhzbDp3aGVuPiIgYW5kICI8eHNsOmNob29zZT4iIGFyZSBrZXl3b3JkcwotICAgICAgICAgKiBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhpcyBtZXNzYWdlIGRlc2NyaWJlcyBhIHN5bnRheCBlcnJvcgotICAgICAgICAgKiBpbiB0aGUgc3R5bGVzaGVldC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5NSVNTSU5HX1dIRU5fRVJSLAotICAgICAgICAiQWxlc3BvXHUwMTQ4IGplZGVuIHBydmVrIDx4c2w6d2hlbj4gc2UgdnlcdTAxN2VhZHVqZSB2IDx4c2w6Y2hvb3NlPi4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIjx4c2w6b3RoZXJ3aXNlPiIgYW5kICI8eHNsOmNob29zZT4iIGFyZQotICAgICAgICAgKiBrZXl3b3JkcyBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhpcyBtZXNzYWdlIGRlc2NyaWJlcyBhCi0gICAgICAgICAqIHN5bnRheCBlcnJvciBpbiB0aGUgc3R5bGVzaGVldC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5NVUxUSVBMRV9PVEhFUldJU0VfRVJSLAotICAgICAgICAiSmVuIGplZGVuIHBydmVrIDx4c2w6b3RoZXJ3aXNlPiBqZSBwb3ZvbGVuIHYgPHhzbDpjaG9vc2U+LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiPHhzbDpvdGhlcndpc2U+IiBhbmQgIjx4c2w6Y2hvb3NlPiIgYXJlCi0gICAgICAgICAqIGtleXdvcmRzIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGlzIG1lc3NhZ2UgZGVzY3JpYmVzIGEKLSAgICAgICAgICogc3ludGF4IGVycm9yIGluIHRoZSBzdHlsZXNoZWV0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlNUUkFZX09USEVSV0lTRV9FUlIsCi0gICAgICAgICJQcnZlayA8eHNsOm90aGVyd2lzZT4gbVx1MDE2Zlx1MDE3ZWUgYlx1MDBmZHQgcG91XHUwMTdlaXQgamVuIHYgPHhzbDpjaG9vc2U+LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiPHhzbDp3aGVuPiIgYW5kICI8eHNsOmNob29zZT4iIGFyZSBrZXl3b3JkcwotICAgICAgICAgKiBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhpcyBtZXNzYWdlIGRlc2NyaWJlcyBhIHN5bnRheCBlcnJvcgotICAgICAgICAgKiBpbiB0aGUgc3R5bGVzaGVldC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5TVFJBWV9XSEVOX0VSUiwKLSAgICAgICAgIlBydmVrIDx4c2w6d2hlbj4gbVx1MDE2Zlx1MDE3ZWUgYlx1MDBmZHQgcG91XHUwMTdlaXQgamVuIHYgPHhzbDpjaG9vc2U+LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiPHhzbDp3aGVuPiIsICI8eHNsOm90aGVyd2lzZT4iIGFuZAotICAgICAgICAgKiAiPHhzbDpjaG9vc2U+IiBhcmUga2V5d29yZHMgYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoaXMKLSAgICAgICAgICogbWVzc2FnZSBkZXNjcmliZXMgYSBzeW50YXggZXJyb3IgaW4gdGhlIHN0eWxlc2hlZXQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuV0hFTl9FTEVNRU5UX0VSUiwKLSAgICAgICAgIlBvdXplIHBydmt5IDx4c2w6d2hlbj4gYSA8eHNsOm90aGVyd2lzZT4ganNvdSBwb3ZvbGVueSB2IDx4c2w6Y2hvb3NlPi4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIjx4c2w6YXR0cmlidXRlLXNldD4iIGFuZCAibmFtZSIgYXJlIGtleXdvcmRzCi0gICAgICAgICAqIHRoYXQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlVOTkFNRURfQVRUUklCU0VUX0VSUiwKLSAgICAgICAgIlYgcHJ2a3UgPHhzbDphdHRyaWJ1dGUtc2V0PiBjaHliXHUwMGVkIGF0cmlidXQgJ25hbWUnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBbiBlbGVtZW50IGluIHRoZSBzdHlsZXNoZWV0IGNvbnRhaW5lZCBhbgotICAgICAgICAgKiBlbGVtZW50IG9mIGEgdHlwZSB0aGF0IGl0IHdhcyBub3QgcGVybWl0dGVkIHRvIGNvbnRhaW4uCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSUxMRUdBTF9DSElMRF9FUlIsCi0gICAgICAgICJOZXBsYXRuXHUwMGZkIHBydmVrIHBvdG9ta2EuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IHRyaWVkIHRvIGNyZWF0ZSBhbiBlbGVtZW50IHdpdGgKLSAgICAgICAgICogYSBuYW1lIHRoYXQgd2FzIG5vdCBhIHZhbGlkIFhNTCBuYW1lLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGNvbnRhaW5zCi0gICAgICAgICAqIHRoZSBuYW1lLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfRUxFTV9OQU1FX0VSUiwKLSAgICAgICAgIk5lbHplIHZvbGF0IHBydmVrICcnezB9JycifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN0eWxlc2hlZXQgdHJpZWQgdG8gY3JlYXRlIGFuIGF0dHJpYnV0ZQotICAgICAgICAgKiB3aXRoIGEgbmFtZSB0aGF0IHdhcyBub3QgYSB2YWxpZCBYTUwgbmFtZS4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICAgKiBjb250YWlucyB0aGUgbmFtZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTExFR0FMX0FUVFJfTkFNRV9FUlIsCi0gICAgICAgICJOZWx6ZSB2b2xhdCBhdHJpYnV0ICcnezB9JycifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGNoaWxkcmVuIG9mIHRoZSBvdXRlcm1vc3QgZWxlbWVudCBvZiBhCi0gICAgICAgICAqIHN0eWxlc2hlZXQgYXJlIHJlZmVycmVkIHRvIGFzIHRvcC1sZXZlbCBlbGVtZW50cy4gIE5vIHRleHQgc2hvdWxkCi0gICAgICAgICAqIG9jY3VyIHdpdGhpbiB0aGF0IG91dGVybW9zdCBlbGVtZW50IHVubGVzcyBpdCBpcyB3aXRoaW4gYSB0b3AtbGV2ZWwKLSAgICAgICAgICogZWxlbWVudC4gIFRoaXMgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGF0IGNvbnN0cmFpbnQgd2FzIHZpb2xhdGVkLgotICAgICAgICAgKiAiPHhzbDpzdHlsZXNoZWV0PiIgaXMgYSBrZXl3b3JkIHRoYXQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfVEVYVF9OT0RFX0VSUiwKLSAgICAgICAgIlRleHRvdlx1MDBlMSBkYXRhIGpzb3Ugdm5cdTAxMWIgcHJ2a3UgbmVqdnlcdTAxNjFcdTAxNjFcdTAwZWQgXHUwMGZhcm92blx1MDExYiA8eHNsOnN0eWxlc2hlZXQ+LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBKQVhQIGlzIGFuIGFjcm9ueW0gZm9yIHRoZSBKYXZhIEFQSSBmb3IgWE1MCi0gICAgICAgICAqIFByb2Nlc3NpbmcuICBUaGlzIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhlIFhNTCBwYXJzZXIgcHJvdmlkZWQgdG8KLSAgICAgICAgICogWFNMVEMgdG8gcHJvY2VzcyB0aGUgWE1MIGlucHV0IGRvY3VtZW50IGhhZCBhIGNvbmZpZ3VyYXRpb24gcHJvYmxlbS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5TQVhfUEFSU0VSX0NPTkZJR19FUlIsCi0gICAgICAgICJBbmFseXpcdTAwZTF0b3IgSkFYUCBqZSBuZXNwclx1MDBlMXZuXHUwMTFiIGtvbmZpZ3Vyb3ZcdTAwZTFuLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgbmFtZXMgdGhlIGludGVybmFsIGVycm9yCi0gICAgICAgICAqIGVuY291bnRlcmVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklOVEVSTkFMX0VSUiwKLSAgICAgICAgIk5lb3ByYXZpdGVsblx1MDBlMSBjaHliYSBYU0xUQy1pbnRlcm5hbDogJyd7MH0nJyJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3R5bGVzaGVldCBjb250YWluZWQgYW4gZWxlbWVudCB0aGF0IHdhcwotICAgICAgICAgKiBub3QgcmVjb2duaXplZCBhcyBwYXJ0IG9mIHRoZSBYU0wgc3ludGF4LiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgICAqIGdpdmVzIHRoZSBlbGVtZW50IG5hbWUuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVU5TVVBQT1JURURfWFNMX0VSUiwKLSAgICAgICAgIk5lcG9kcG9yb3Zhblx1MDBmZCBwcnZlayBYU0wgJyd7MH0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN0eWxlc2hlZXQgcmVmZXJyZWQgdG8gYW4gZXh0ZW5zaW9uIHRvIHRoZQotICAgICAgICAgKiBYU0wgc3ludGF4IGFuZCBpbmRpY2F0ZWQgdGhhdCBpdCB3YXMgZGVmaW5lZCBieSBYU0xUQywgYnV0IFhTVExDIGRvZXMKLSAgICAgICAgICogbm90IHJlY29nbml6ZWQgdGhlIHBhcnRpY3VsYXIgZXh0ZW5zaW9uIG5hbWVkLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgICAqIGdpdmVzIHRoZSBleHRlbnNpb24gbmFtZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5VTlNVUFBPUlRFRF9FWFRfRVJSLAotICAgICAgICAiTmVyb3pwb3puYW5cdTAwZTEgcFx1MDE1OVx1MDBlZHBvbmEgWFNMVEMgJyd7MH0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIFhNTCBkb2N1bWVudCBnaXZlbiB0byBYU0xUQyBhcyBhIHN0eWxlc2hlZXQKLSAgICAgICAgICogd2FzIG5vdCwgaW4gZmFjdCwgYSBzdHlsZXNoZWV0LiAgWFNMVEMgaXMgYWJsZSB0byBkZXRlY3QgdGhhdCBpbiB0aGlzCi0gICAgICAgICAqIGNhc2UgYmVjYXVzZSB0aGUgb3V0ZXJtb3N0IGVsZW1lbnQgaW4gdGhlIHN0eWxlc2hlZXQgaGFzIHRvIGJlCi0gICAgICAgICAqIGRlY2xhcmVkIHdpdGggcmVzcGVjdCB0byB0aGUgWFNMIG5hbWVzcGFjZSBVUkksIGJ1dCBubyBkZWNsYXJhdGlvbgotICAgICAgICAgKiBmb3IgdGhhdCBuYW1lc3BhY2Ugd2FzIHNlZW4uCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTUlTU0lOR19YU0xUX1VSSV9FUlIsCi0gICAgICAgICJWc3R1cG5cdTAwZWQgZG9rdW1lbnQgbmVuXHUwMGVkIHBcdTAxNTllZGxvaGEgc3R5bHUgKG9ib3Igblx1MDBlMXp2XHUwMTZmIFhTTCBuZW5cdTAwZWQgZGVrbGFyb3ZcdTAwZTFuIHYga29cdTAxNTllbm92XHUwMGU5bSBlbGVtZW50dSkuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFhTTFRDIGNvdWxkIG5vdCBmaW5kIHRoZSBzdHlsZXNoZWV0IGRvY3VtZW50Ci0gICAgICAgICAqIHdpdGggdGhlIG5hbWUgc3BlY2lmaWVkIGJ5IHRoZSBzdWJzdGl0dXRpb24gdGV4dC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5NSVNTSU5HX1hTTFRfVEFSR0VUX0VSUiwKLSAgICAgICAgIk5lbHplIG5halx1MDBlZHQgY1x1MDBlZGxvdm91IHBcdTAxNTllZGxvaHUgc2Ugc3R5bGVtICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIGFjY2VzcyB0byB0aGUgc3R5bGVzaGVldCB0YXJnZXQgaXMgZGVuaWVkCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuQUNDRVNTSU5HX1hTTFRfVEFSR0VUX0VSUiwKLSAgICAgICAgIkNvdWxkIG5vdCByZWFkIHN0eWxlc2hlZXQgdGFyZ2V0ICcnezB9JycsIGJlY2F1c2UgJyd7MX0nJyBhY2Nlc3MgaXMgbm90IGFsbG93ZWQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSByZXByZXNlbnRzIGFuIGludGVybmFsIGVycm9yIGluCi0gICAgICAgICAqIGNvbmRpdGlvbiBpbiBYU0xUQy4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgY2xhc3MgbmFtZSBpbiBYU0xUQwotICAgICAgICAgKiB0aGF0IGlzIG1pc3Npbmcgc29tZSBmdW5jdGlvbmFsaXR5LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk5PVF9JTVBMRU1FTlRFRF9FUlIsCi0gICAgICAgICJOZWltcGxlbWVudG92XHUwMGUxbm86ICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBYTUwgZG9jdW1lbnQgZ2l2ZW4gdG8gWFNMVEMgYXMgYSBzdHlsZXNoZWV0Ci0gICAgICAgICAqIHdhcyBub3QsIGluIGZhY3QsIGEgc3R5bGVzaGVldC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5OT1RfU1RZTEVTSEVFVF9FUlIsCi0gICAgICAgICJWc3R1cG5cdTAwZWQgZG9rdW1lbnQgbmVvYnNhaHVqZSBwXHUwMTU5ZWRsb2h1IHN0eWx1IFhTTC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGVsZW1lbnQgbmFtZWQgaW4gdGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHdhcwotICAgICAgICAgKiBlbmNvdW50ZXJlZCBpbiB0aGUgc3R5bGVzaGVldCBidXQgaXMgbm90IHJlY29nbml6ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuRUxFTUVOVF9QQVJTRV9FUlIsCi0gICAgICAgICJOZWx6ZSBhbmFseXpvdmF0IHBydmVrICcnezB9JycifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgInVzZSIsICI8a2V5PiIsICJub2RlIiwgIm5vZGUtc2V0IiwgInN0cmluZyIKLSAgICAgICAgICogYW5kICJudW1iZXIiIGFyZSBrZXl3b3JkcyBpbiB0aGlzIGNvbnRleHQgYW5kIHNob3VsZCBub3QgYmUKLSAgICAgICAgICogdHJhbnNsYXRlZC4gIFRoaXMgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUgdmFsdWUgb2YgdGhlICJ1c2UiCi0gICAgICAgICAqIGF0dHJpYnV0ZSB3YXMgbm90IG9uZSBvZiB0aGUgcGVybWl0dGVkIHZhbHVlcy4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5LRVlfVVNFX0FUVFJfRVJSLAotICAgICAgICAiQXRyaWJ1dCB1c2UgcHJvbVx1MDExYm5uXHUwMGU5IDxrZXk+IG11c1x1MDBlZCBiXHUwMGZkdCB0eXB1IG5vZGUsIG5vZGUtc2V0LCBzdHJpbmcgbmVibyBudW1iZXIuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIFhNTCBkb2N1bWVudCBjYW4gc3BlY2lmeSB0aGUgdmVyc2lvbiBvZiB0aGUKLSAgICAgICAgICogWE1MIHNwZWNpZmljYXRpb24gdG8gd2hpY2ggaXQgYWRoZXJlcy4gIFRoaXMgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdAotICAgICAgICAgKiB0aGUgdmVyc2lvbiBzcGVjaWZpZWQgZm9yIHRoZSBvdXRwdXQgZG9jdW1lbnQgd2FzIG5vdCB2YWxpZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5PVVRQVVRfVkVSU0lPTl9FUlIsCi0gICAgICAgICJWXHUwMGZkc3R1cG5cdTAwZWQgdmVyemUgZG9rdW1lbnR1IFhNTCBieSBtXHUwMTFibGEgYlx1MDBmZHQgMS4wIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBvcGVyYXRvciBpbiBhIGNvbXBhcmlzb24gb3BlcmF0aW9uIHdhcwotICAgICAgICAgKiBub3QgcmVjb2duaXplZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTExFR0FMX1JFTEFUX09QX0VSUiwKLSAgICAgICAgIk5lem5cdTAwZTFtXHUwMGZkIG9wZXJcdTAwZTF0b3IgcHJvIHJlbGFcdTAxMGRuXHUwMGVkIHZcdTAwZmRyYXoifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQW4gYXR0cmlidXRlIHNldCBkZWZpbmVzIGFzIGEgc2V0IG9mIFhNTAotICAgICAgICAgKiBhdHRyaWJ1dGVzIHRoYXQgY2FuIGJlIGFkZGVkIHRvIGFuIGVsZW1lbnQgaW4gdGhlIG91dHB1dCBYTUwgZG9jdW1lbnQKLSAgICAgICAgICogYXMgYSBncm91cC4gIFRoaXMgbWVzc2FnZSBpcyByZXBvcnRlZCBpZiB0aGUgbmFtZSBzcGVjaWZpZWQgd2FzIG5vdAotICAgICAgICAgKiB1c2VkIHRvIGRlY2xhcmUgYW4gYXR0cmlidXRlIHNldC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZQotICAgICAgICAgKiB0aGF0IGlzIGluIGVycm9yLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkFUVFJJQlNFVF9VTkRFRl9FUlIsCi0gICAgICAgICJQb2t1cyBwb3VcdTAxN2VcdTAwZWR0IG5lZXhpc3R1alx1MDBlZGNcdTAwZWQgc2FkdSBhdHJpYnV0XHUwMTZmICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSB0ZXJtICJhdHRyaWJ1dGUgdmFsdWUgdGVtcGxhdGUiIGlzIGEgdGVybQotICAgICAgICAgKiBkZWZpbmVkIGJ5IFhTTFQgd2hpY2ggZGVzY3JpYmVzIHRoZSB2YWx1ZSBvZiBhbiBhdHRyaWJ1dGUgdGhhdCBpcwotICAgICAgICAgKiBkZXRlcm1pbmVkIGJ5IGFuIFhQYXRoIGV4cHJlc3Npb24uICBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUKLSAgICAgICAgICogZXhwcmVzc2lvbiB3YXMgc3ludGFjdGljYWxseSBpbmNvcnJlY3Q7IHRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICAgKiBjb250YWlucyB0aGUgZXhwcmVzc2lvbiB0aGF0IHdhcyBpbiBlcnJvci4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5BVFRSX1ZBTF9URU1QTEFURV9FUlIsCi0gICAgICAgICJOZWx6ZSBhbmFseXpvdmF0IFx1MDE2MWFibG9udSBob2Rub3R5IGF0cmlidXR1ICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogID8/PwotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlVOS05PV05fU0lHX1RZUEVfRVJSLAotICAgICAgICAiTmV6blx1MDBlMW1cdTAwZmQgZGF0b3ZcdTAwZmQgdHlwIHByb21cdTAxMWJublx1MDBlOSBzaWduYXR1cmUgcHJvIHRcdTAxNTlcdTAwZWRkdSAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgcmVmZXJzIHRvIGRhdGEgdHlwZXMuCi0gICAgICAgICAqIFRoZSBtZXNzYWdlIGlzIGRpc3BsYXllZCBpZiBhIHZhbHVlIGluIGEgcGFydGljdWxhciBjb250ZXh0IG5lZWRzIHRvCi0gICAgICAgICAqIGJlIGNvbnZlcnRlZCB0byB0eXBlIHsxfSwgYnV0IHRoYXQncyBub3QgcG9zc2libGUgZm9yIGEgdmFsdWUgb2YKLSAgICAgICAgICogdHlwZSB7MH0uCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuREFUQV9DT05WRVJTSU9OX0VSUiwKLSAgICAgICAgIk5lbHplIHBcdTAxNTlldlx1MDBlOXN0IGRhdG92XHUwMGZkIHR5cCAnJ3swfScnIG5hICcnezF9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJUZW1wbGF0ZXMiIGlzIGEgSmF2YSBjbGFzcyBuYW1lIHRoYXQgc2hvdWxkCi0gICAgICAgICAqIG5vdCBiZSB0cmFuc2xhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk5PX1RSQU5TTEVUX0NMQVNTX0VSUiwKLSAgICAgICAgIlRhdG8gXHUwMTYxYWJsb25hIG5lb2JzYWh1amUgcGxhdG5vdSBkZWZpbmljaSB0XHUwMTU5XHUwMGVkZHkgdHJhbnNsZXQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJUZW1wbGF0ZXMiIGlzIGEgSmF2YSBjbGFzcyBuYW1lIHRoYXQgc2hvdWxkCi0gICAgICAgICAqIG5vdCBiZSB0cmFuc2xhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk5PX01BSU5fVFJBTlNMRVRfRVJSLAotICAgICAgICAiVGF0byBcdTAxNjFhYmxvbmEgbmVvYnNhaHVqZSB0XHUwMTU5XHUwMGVkZHUgc2Ugam1cdTAwZTluZW0gJyd7MH0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIGEgY2xhc3MuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVFJBTlNMRVRfQ0xBU1NfRVJSLAotICAgICAgICAiTmVsemUgemF2XHUwMGU5c3QgdFx1MDE1OVx1MDBlZGR1IHRyYW5zbGV0ICcnezB9JycuIn0sCi0KLSAgICAgICAge0Vycm9yTXNnLlRSQU5TTEVUX09CSkVDVF9FUlIsCi0gICAgICAgICJUXHUwMTU5XHUwMGVkZGEgdHJhbnNsZXQgYnlsYSB6YXZlZGVuYSwgYXZcdTAxNjFhayBuZWx6ZSB2eXR2b1x1MDE1OWl0IGluc3RhbmNpIHRyYW5zbGV0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiRXJyb3JMaXN0ZW5lciIgaXMgYSBKYXZhIGludGVyZmFjZSBuYW1lIHRoYXQKLSAgICAgICAgICogc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhlIHVzZXIgdHJpZWQKLSAgICAgICAgICogdG8gc2V0IGFuIEVycm9yTGlzdGVuZXIgb2JqZWN0IG9uIG9iamVjdCBvZiB0aGUgY2xhc3MgbmFtZWQgaW4gdGhlCi0gICAgICAgICAqIHN1YnN0aXR1dGlvbiB0ZXh0IHdpdGggIm51bGwiIEphdmEgdmFsdWUuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuRVJST1JfTElTVEVORVJfTlVMTF9FUlIsCi0gICAgICAgICJQb2t1cyBuYXN0YXZpdCBvYmpla3QgRXJyb3JMaXN0ZW5lciBwcm8gJyd7MH0nJyBuYSBob2Rub3R1IG51bGwifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgU3RyZWFtU291cmNlLCBTQVhTb3VyY2UgYW5kIERPTVNvdXJjZSBhcmUgSmF2YQotICAgICAgICAgKiBpbnRlcmZhY2UgbmFtZXMgdGhhdCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSkFYUF9VTktOT1dOX1NPVVJDRV9FUlIsCi0gICAgICAgICJQb3V6ZSBwcm9tXHUwMTFibm5cdTAwZTkgU3RyZWFtU291cmNlLCBTQVhTb3VyY2UgYSBET01Tb3VyY2UganNvdSBwb2Rwb3Jvdlx1MDBlMW55IHByb2R1a3RlbSBYU0xUQyJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiU291cmNlIiBpcyBhIEphdmEgY2xhc3MgbmFtZSB0aGF0IHNob3VsZCBub3QKLSAgICAgICAgICogYmUgdHJhbnNsYXRlZC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBKYXZhIG1ldGhvZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX05PX1NPVVJDRV9FUlIsCi0gICAgICAgICJaZHJvam92XHUwMGZkIG9iamVrdCBwXHUwMTU5ZWRhblx1MDBmZCAnJ3swfScnIG5lbVx1MDBlMSBcdTAxN2VcdTAwZTFkblx1MDBmZCBvYnNhaC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgWFNMVEMgZmFpbGVkIHRvCi0gICAgICAgICAqIGNvbXBpbGUgdGhlIHN0eWxlc2hlZXQgaW50byBhIHRyYW5zbGV0IChjbGFzcyBmaWxlKS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX0NPTVBJTEVfRVJSLAotICAgICAgICAiTmVsemUga29tcGlsb3ZhdCBwXHUwMTU5ZWRsb2h1IHNlIHN0eWxlbSJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiVHJhbnNmb3JtZXJGYWN0b3J5IiBpcyBhIGNsYXNzIG5hbWUuICBJbiB0aGlzCi0gICAgICAgICAqIGNvbnRleHQsIGFuIGF0dHJpYnV0ZSBpcyBhIHByb3BlcnR5IG9yIHNldHRpbmcgb2YgdGhlCi0gICAgICAgICAqIFRyYW5zZm9ybWVyRmFjdG9yeSBvYmplY3QuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgdGhlCi0gICAgICAgICAqIHVucmVjb2duaXNlZCBhdHRyaWJ1dGUuICBUaGUgbWV0aG9kIHVzZWQgdG8gcmV0cmlldmUgdGhlIGF0dHJpYnV0ZSBpcwotICAgICAgICAgKiAiZ2V0QXR0cmlidXRlIiwgc28gaXQncyBub3QgY2xlYXIgd2hldGhlciBpdCB3b3VsZCBiZSBiZXN0IHRvCi0gICAgICAgICAqIHRyYW5zbGF0ZSB0aGUgdGVybSAiYXR0cmlidXRlIi4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX0lOVkFMSURfQVRUUl9FUlIsCi0gICAgICAgICJUXHUwMTU5XHUwMGVkZGEgVHJhbnNmb3JtZXJGYWN0b3J5IG5lcm96cG96bmFsYSBhdHJpYnV0ICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJzZXRSZXN1bHQoKSIgYW5kICJzdGFydERvY3VtZW50KCkiIGFyZSBKYXZhCi0gICAgICAgICAqIG1ldGhvZCBuYW1lcyB0aGF0IHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX1NFVF9SRVNVTFRfRVJSLAotICAgICAgICAiTWV0b2RhIHNldFJlc3VsdCgpIG11c1x1MDBlZCBiXHUwMGZkdCB2b2xcdTAwZTFuYSBwXHUwMTU5ZWQgbWV0b2RvdSBzdGFydERvY3VtZW50KCkuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJUcmFuc2Zvcm1lciIgaXMgYSBKYXZhIGludGVyZmFjZSBuYW1lIHRoYXQKLSAgICAgICAgICogc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgQSBUcmFuc2Zvcm1lciBvYmplY3Qgc2hvdWxkIGNvbnRhaW5lZCBhCi0gICAgICAgICAqIHJlZmVyZW5jZSB0byBhIHRyYW5zbGV0IG9iamVjdCBpbiBvcmRlciB0byBiZSB1c2VkIGZvcgotICAgICAgICAgKiB0cmFuc2Zvcm1hdGlvbnM7IHRoaXMgbWVzc2FnZSBpcyBwcm9kdWNlZCBpZiB0aGF0IHJlcXVpcmVtZW50IGlzIG5vdAotICAgICAgICAgKiBtZXQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSkFYUF9OT19UUkFOU0xFVF9FUlIsCi0gICAgICAgICJPYmpla3QgVHJhbnNmb3JtZXIgbmVtXHUwMGUxIFx1MDE3ZVx1MDBlMWRuXHUwMGZkIHphcG91emRcdTAxNTllblx1MDBmZCBvYmpla3QgdHJhbnNsZXQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBYTUwgZG9jdW1lbnQgdGhhdCByZXN1bHRzIGZyb20gYQotICAgICAgICAgKiB0cmFuc2Zvcm1hdGlvbiBuZWVkcyB0byBiZSBzZW50IHRvIGFuIG91dHB1dCBoYW5kbGVyIG9iamVjdDsgdGhpcwotICAgICAgICAgKiBtZXNzYWdlIGlzIHByb2R1Y2VkIGlmIHRoYXQgcmVxdWlyZW1lbnQgaXMgbm90IG1ldC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX05PX0hBTkRMRVJfRVJSLAotICAgICAgICAiTmVleGlzdHVqZSBcdTAxN2VcdTAwZTFkblx1MDBmZCBkZWZpbm92YW5cdTAwZmQgdlx1MDBmZHN0dXBuXHUwMGVkIG9ic2x1XHUwMTdlblx1MDBmZCBwcm9ncmFtIHBybyB2XHUwMGZkc2xlZGVrIHRyYW5zZm9ybWFjZS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIlJlc3VsdCIgaXMgYSBKYXZhIGludGVyZmFjZSBuYW1lIGluIHRoaXMKLSAgICAgICAgICogY29udGV4dC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyBhIG1ldGhvZCBuYW1lLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfTk9fUkVTVUxUX0VSUiwKLSAgICAgICAgIlZcdTAwZmRzbGVkblx1MDBmZCBvYmpla3QgcFx1MDE1OWVkYW5cdTAwZmQgJyd7MH0nJyBqZSBuZXBsYXRuXHUwMGZkLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiVHJhbnNmb3JtZXIiIGlzIGEgSmF2YSBpbnRlcmZhY2UgbmFtZS4gIFRoZQotICAgICAgICAgKiB1c2VyJ3MgcHJvZ3JhbSBhdHRlbXB0ZWQgdG8gYWNjZXNzIGFuIHVucmVjb2duaXplZCBwcm9wZXJ0eSB3aXRoIHRoZQotICAgICAgICAgKiBuYW1lIHNwZWNpZmllZCBpbiB0aGUgc3Vic3RpdHV0aW9uIHRleHQuICBUaGUgbWV0aG9kIHVzZWQgdG8gcmV0cmlldmUKLSAgICAgICAgICogdGhlIHByb3BlcnR5IGlzICJnZXRPdXRwdXRQcm9wZXJ0eSIsIHNvIGl0J3Mgbm90IGNsZWFyIHdoZXRoZXIgaXQKLSAgICAgICAgICogd291bGQgYmUgYmVzdCB0byB0cmFuc2xhdGUgdGhlIHRlcm0gInByb3BlcnR5Ii4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX1VOS05PV05fUFJPUF9FUlIsCi0gICAgICAgICJQb2t1cyBvIHBcdTAxNTlcdTAwZWRzdHVwIGsgbmVwbGF0blx1MDBlOSB2bGFzdG5vc3RpIG9iamVrdHUgVHJhbnNmb3JtZXI6ICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFNBWDJET00gaXMgdGhlIG5hbWUgb2YgYSBKYXZhIGNsYXNzIHRoYXQgc2hvdWxkCi0gICAgICAgICAqIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhpcyBpcyBhbiBhZGFwdGVyIGluIHRoZSBzZW5zZSB0aGF0IGl0IHRha2VzIGEKLSAgICAgICAgICogRE9NIG9iamVjdCBhbmQgY29udmVydHMgaXQgdG8gc29tZXRoaW5nIHRoYXQgdXNlcyB0aGUgU0FYIEFQSS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5TQVgyRE9NX0FEQVBURVJfRVJSLAotICAgICAgICAiTmVsemUgdnl0dm9cdTAxNTlpdCBhZGFwdFx1MDBlOXIgU0FYMkRPTTogJyd7MH0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIlhTTFRDU291cmNlLmJ1aWxkKCkiIGlzIGEgSmF2YSBtZXRob2QgbmFtZS4KLSAgICAgICAgICogInN5c3RlbUlkIiBpcyBhbiBYTUwgdGVybSB0aGF0IGlzIHNob3J0IGZvciAic3lzdGVtIGlkZW50aWZpY2F0aW9uIi4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5YU0xUQ19TT1VSQ0VfRVJSLAotICAgICAgICAiQnlsYSB2b2xcdTAwZTFuYSBtZXRvZGEgWFNMVENTb3VyY2UuYnVpbGQoKSwgYW5pXHUwMTdlIGJ5IGJ5bGEgbmFzdGF2ZW5hIGhvZG5vdGEgc3lzdGVtSWQuIn0sCi0KLQotICAgICAgICB7RXJyb3JNc2cuQ09NUElMRV9TVERJTl9FUlIsCi0gICAgICAgICJWb2xiYSAtaSBtdXNcdTAwZWQgYlx1MDBmZHQgcG91XHUwMTdlaXRhIHMgdm9sYm91IC1vLiJ9LAotCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBjb250YWlucyB1c2FnZSBpbmZvcm1hdGlvbiBmb3IgYQotICAgICAgICAgKiBtZWFucyBvZiBpbnZva2luZyBYU0xUQyBmcm9tIHRoZSBjb21tYW5kLWxpbmUuICBUaGUgbWVzc2FnZSBpcwotICAgICAgICAgKiBmb3JtYXR0ZWQgZm9yIHByZXNlbnRhdGlvbiBpbiBFbmdsaXNoLiAgVGhlIHN0cmluZ3MgPG91dHB1dD4sCi0gICAgICAgICAqIDxkaXJlY3Rvcnk+LCBldGMuIGluZGljYXRlIHVzZXItc3BlY2lmaWVkIGFyZ3VtZW50IHZhbHVlcywgYW5kIGNhbgotICAgICAgICAgKiBiZSB0cmFuc2xhdGVkIC0gdGhlIGFyZ3VtZW50IDxwYWNrYWdlPiByZWZlcnMgdG8gYSBKYXZhIHBhY2thZ2UsIHNvCi0gICAgICAgICAqIGl0IHNob3VsZCBiZSBoYW5kbGVkIGluIHRoZSBzYW1lIHdheSB0aGUgdGVybSBpcyBoYW5kbGVkIGZvciBKREsKLSAgICAgICAgICogZG9jdW1lbnRhdGlvbi4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5DT01QSUxFX1VTQUdFX1NUUiwKLSAgICAgICAgIlNZTk9QU0lTXG4gICBqYXZhIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jbWRsaW5lLkNvbXBpbGUgWy1vIDxvdXRwdXQ+XVxuICAgICAgWy1kIDxkaXJlY3Rvcnk+XSBbLWogPGphcmZpbGU+XSBbLXAgPHBhY2thZ2U+XVxuICAgICAgWy1uXSBbLXhdIFstc10gWy11XSBbLXZdIFstaF0geyA8c3R5bGVzaGVldD4gfCAtaSB9XG5cblZPTEJZXG4gICAtbyA8b3V0cHV0PiAgICBwXHUwMTU5aVx1MDE1OWF6dWplIG5cdTAwZTF6ZXYgPG91dHB1dD4gZ2VuZXJvdmFuXHUwMGU5bXVcbiAgICAgICAgICAgICAgICAgIHRyYW5zbGV0dS4gU3RhbmRhcmRuXHUwMTFiIGplIG5cdTAwZTF6ZXYgdHJhbnNsZXR1XG4gICAgICAgICAgICAgICAgICBwXHUwMTU5ZXZ6YXQgeiBuXHUwMGUxenZ1IDxzdHlsZXNoZWV0Pi4gVGF0byB2b2xiYVxuICAgICAgICAgICAgICAgICAgIHNlIGlnbm9ydWplLCBwb2t1ZCBzZSBrb21waWx1alx1MDBlZCBuXHUwMGUxc29iblx1MDBlOSBwXHUwMTU5ZWRsb2h5IHN0eWxcdTAxNmYuXG4gICAtZCA8ZGlyZWN0b3J5PiB1clx1MDEwZHVqZSB2XHUwMGZkY2hvelx1MDBlZCBhZHJlc1x1MDBlMVx1MDE1OSBwcm8gdHJhbnNsZXRcbiAgIC1qIDxqYXJmaWxlPiAgIHphYmFsXHUwMGVkIHRcdTAxNTlcdTAwZWRkdSB0cmFuc2xldHUgZG8gc291Ym9ydSBqYXJcbiAgICAgcG9qbWVub3Zhblx1MDBlOWhvIGpha28gPGphcmZpbGU+XG4gICAtcCA8cGFja2FnZT4gICB1clx1MDEwZHVqZSBwXHUwMTU5ZWRwb251IG5cdTAwZTF6dnUgYmFsXHUwMGVkXHUwMTBka3UgcHJvIHZcdTAxNjFlY2hueSBnZW5lcm92YW5cdTAwZTkgXG4gdFx1MDE1OVx1MDBlZGR5IHRyYW5zbGV0dS5cbiAgIC1uICAgICAgICAgICAgIHBvdm9sdWplIHphcm92blx1MDBlMW5cdTAwZWQgXHUwMTYxYWJsb255ICh2XHUwMGZkY2hvelx1MDBlZCBjaG92XHUwMGUxblx1MDBlZCBqZSB2IHByXHUwMTZmbVx1MDExYnJ1IGxlcFx1MDE2MVx1MDBlZFxuICAgICAgICAgICAgICAgICAgLlxuICAgLXggICAgICAgICAgICAgemFwbmUgZGFsXHUwMTYxXHUwMGVkIHZcdTAwZmRzdHVwIHpwclx1MDBlMXZ5IGxhZFx1MDExYm5cdTAwZWRcbiAgIC1zICAgICAgICAgICAgIHpha1x1MDBlMVx1MDE3ZWUgdm9sXHUwMGUxblx1MDBlZCBTeXN0ZW0uZXhpdFxuICAgLXUgICAgICAgICAgICAgaW50ZXJwcmV0dWplIDxzdHlsZXNoZWV0PiBhcmd1bWVudHkgamFrbyBVUkxcbiAgIC1pICAgICAgICAgICAgIHZ5bnV0XHUwMGVkIGtvbXBpbFx1MDBlMXRvciBcdTAxMGRcdTAwZWRzdCBwXHUwMTU5ZWRsb2h1IHN0eWxcdTAxNmYgemUgc3RkaW5cbiAgIC12ICAgICAgICAgICAgIHRpc2tuZSB2ZXJ6aSBrb21waWxcdTAwZTF0b3J1IFxuICAgLWggICAgICAgICAgICAgdGlza25lIHZcdTAwZmRwaXMgdG9ob3RvIHBvdVx1MDE3ZWl0XHUwMGVkIFxuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBjb250YWlucyB1c2FnZSBpbmZvcm1hdGlvbiBmb3IgYQotICAgICAgICAgKiBtZWFucyBvZiBpbnZva2luZyBYU0xUQyBmcm9tIHRoZSBjb21tYW5kLWxpbmUuICBUaGUgbWVzc2FnZSBpcwotICAgICAgICAgKiBmb3JtYXR0ZWQgZm9yIHByZXNlbnRhdGlvbiBpbiBFbmdsaXNoLiAgVGhlIHN0cmluZ3MgPGphcmZpbGU+LAotICAgICAgICAgKiA8ZG9jdW1lbnQ+LCBldGMuIGluZGljYXRlIHVzZXItc3BlY2lmaWVkIGFyZ3VtZW50IHZhbHVlcywgYW5kIGNhbgotICAgICAgICAgKiBiZSB0cmFuc2xhdGVkIC0gdGhlIGFyZ3VtZW50IDxjbGFzcz4gcmVmZXJzIHRvIGEgSmF2YSBjbGFzcywgc28gaXQKLSAgICAgICAgICogc2hvdWxkIGJlIGhhbmRsZWQgaW4gdGhlIHNhbWUgd2F5IHRoZSB0ZXJtIGlzIGhhbmRsZWQgZm9yIEpESwotICAgICAgICAgKiBkb2N1bWVudGF0aW9uLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlRSQU5TRk9STV9VU0FHRV9TVFIsCi0gICAgICAgICJTWU5PUFNJUyBcbiAgIGphdmEgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNtZGxpbmUuVHJhbnNmb3JtIFstaiA8amFyZmlsZT5dXG4gICAgICBbLXhdIFstc10gWy1uIDxpdGVyYXRpb25zPl0gey11IDxkb2N1bWVudF91cmw+IHwgPGRvY3VtZW50Pn1cbiAgICAgIDxjbGFzcz4gWzxwYXJhbTE+PTx2YWx1ZTE+IC4uLl1cblxuICAgcG91XHUwMTdlaWplIHRyYW5zbGV0IDxjbGFzcz4gayB0cmFuc2Zvcm1hY2kgZG9rdW1lbnR1IFhNTCBcbiB1clx1MDEwZGVuXHUwMGU5aG8gamFrbyA8ZG9jdW1lbnQ+LiBUcmFuc2xldCA8Y2xhc3M+IGplIGJ1XHUwMTBmIHZcbiAgIHYgdVx1MDE3ZWl2YXRlbHNrXHUwMGU5IGNlc3RcdTAxMWIgQ0xBU1NQQVRIIG5lYm8gdmUgdm9saXRlbG5cdTAxMWIgdXJcdTAxMGRlblx1MDBlOW0gc291Ym9ydSA8amFyZmlsZT4uXG5WT0xCWVxuICAgICAtaiA8amFyZmlsZT4gICAgdXJcdTAxMGR1amUgc291Ym9yIGphcmZpbGUsIHplIGt0ZXJcdTAwZTlobyBzZSB6YXZlZGUgdHJhbnNsZXRcbiAgIC14ICAgICAgcFx1MDE1OWV2ZWRlIGRhbFx1MDE2MVx1MDBlZCB2XHUwMGZkc3R1cCB6cHJcdTAwZTF2eSBsYWRcdTAxMWJuXHUwMGVkXG4gICAtcyAgICAgICAgICAgICAgdnlwbmUgdm9sXHUwMGUxblx1MDBlZCBTeXN0ZW0uZXhpdFxuICAgLW4gPGl0ZXJhdGlvbnM+IHNwdXN0XHUwMGVkIHRyYW5zZm9ybWFjaSA8aXRlcmF0aW9ucz4ga3JcdTAwZTF0IGFcbiAgICAgICAgICAgICAgICAgICB6b2JyYXpcdTAwZWQgaW5mb3JtYWNpICBvIHByb2ZpbHVcbiAgIC11IDxkb2N1bWVudF91cmw+IHVyXHUwMTBkXHUwMGVkIHZzdHVwblx1MDBlZCBkb2t1bWVudCBYTUwgamFrbyBVUkxcbiJ9LAotCi0KLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIjx4c2w6c29ydD4iLCAiPHhzbDpmb3ItZWFjaD4iIGFuZAotICAgICAgICAgKiAiPHhzbDphcHBseS10ZW1wbGF0ZXM+IiBhcmUga2V5d29yZHMgdGhhdCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqIFRoZSBtZXNzYWdlIGluZGljYXRlcyB0aGF0IGFuIHhzbDpzb3J0IGVsZW1lbnQgbXVzdCBiZSBhIGNoaWxkIG9mCi0gICAgICAgICAqIG9uZSBvZiB0aGUgb3RoZXIga2luZHMgb2YgZWxlbWVudHMgbWVudGlvbmVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlNUUkFZX1NPUlRfRVJSLAotICAgICAgICAiUHJ2ZWsgPHhzbDpzb3J0PiBtXHUwMTZmXHUwMTdlZSBiXHUwMGZkdCBwb3VcdTAxN2VpdCBqZW4gdiA8eHNsOmZvci1lYWNoPiBuZWJvIDx4c2w6YXBwbHktdGVtcGxhdGVzPi4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhlIGVuY29kaW5nCi0gICAgICAgICAqIHJlcXVlc3RlZCBmb3IgdGhlIG91dHB1dCBkb2N1bWVudCB3YXMgb24gdGhhdCByZXF1aXJlcyBzdXBwb3J0IHRoYXQKLSAgICAgICAgICogaXMgbm90IGF2YWlsYWJsZSBmcm9tIHRoZSBKYXZhIFZpcnR1YWwgTWFjaGluZSBiZWluZyB1c2VkIHRvIGV4ZWN1dGUKLSAgICAgICAgICogdGhlIHByb2dyYW0uCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVU5TVVBQT1JURURfRU5DT0RJTkcsCi0gICAgICAgICJWXHUwMGZkc3R1cG5cdTAwZWQga1x1MDBmM2Rvdlx1MDBlMW5cdTAwZWQgJyd7MH0nJyBuZW5cdTAwZWQgdiB0b210byBwcm9zdFx1MDE1OWVkXHUwMGVkIEpWTSBwb2Rwb3Jvdlx1MDBlMW5vLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUgWFBhdGggZXhwcmVzc2lvbgotICAgICAgICAgKiBuYW1lZCBpbiB0aGUgc3Vic3RpdHV0aW9uIHRleHQgd2FzIG5vdCB3ZWxsIGZvcm1lZCBzeW50YWN0aWNhbGx5LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlNZTlRBWF9FUlIsCi0gICAgICAgICJDaHliYSBzeW50YXhlIHYgJyd7MH0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIGEgSmF2YQotICAgICAgICAgKiBjbGFzcy4gIFRoZSB0ZXJtICJjb25zdHJ1Y3RvciIgaGVyZSBpcyB0aGUgSmF2YSB0ZXJtLiAgVGhlIG1lc3NhZ2UgaXMKLSAgICAgICAgICogZGlzcGxheWVkIGlmIFhTTFRDIGNvdWxkIG5vdCBmaW5kIGEgY29uc3RydWN0b3IgZm9yIHRoZSBzcGVjaWZpZWQKLSAgICAgICAgICogY2xhc3MuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuQ09OU1RSVUNUT1JfTk9UX0ZPVU5ELAotICAgICAgICAiTmVsemUgbmFqXHUwMGVkdCB2blx1MDExYmpcdTAxNjFcdTAwZWQga29uc3RydWt0b3IgJyd7MH0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgInN0YXRpYyIgaXMgdGhlIEphdmEga2V5d29yZC4gIFRoZSBzdWJzdGl0dXRpb24KLSAgICAgICAgICogdGV4dCBpcyB0aGUgbmFtZSBvZiBhIGZ1bmN0aW9uLiAgVGhlIGZpcnN0IGFyZ3VtZW50IG9mIHRoYXQgZnVuY3Rpb24KLSAgICAgICAgICogaXMgbm90IG9mIHRoZSByZXF1aXJlZCB0eXBlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk5PX0pBVkFfRlVOQ1RfVEhJU19SRUYsCi0gICAgICAgICJQcnZuXHUwMGVkIGFyZ3VtZW50IG5lc3RhdGlja1x1MDBlOSBmdW5rY2UgSmF2YSAnJ3swfScnIG5lblx1MDBlZCBwbGF0blx1MDBmZG0gb2RrYXplbSBuYSBvYmpla3QuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIFhQYXRoIGV4cHJlc3Npb24gd2FzIG5vdCBvZiB0aGUgdHlwZQotICAgICAgICAgKiByZXF1aXJlZCBpbiBhIHBhcnRpY3VsYXIgY29udGV4dC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUKLSAgICAgICAgICogZXhwcmVzc2lvbiB0aGF0IHdhcyBpbiBlcnJvci4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5UWVBFX0NIRUNLX0VSUiwKLSAgICAgICAgIkNoeWJhIHBcdTAxNTlpIGtvbnRyb2xlIHR5cHUgdlx1MDBmZHJhenUgJyd7MH0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQW4gWFBhdGggZXhwcmVzc2lvbiB3YXMgbm90IG9mIHRoZSB0eXBlCi0gICAgICAgICAqIHJlcXVpcmVkIGluIGEgcGFydGljdWxhciBjb250ZXh0LiAgSG93ZXZlciwgdGhlIGxvY2F0aW9uIG9mIHRoZQotICAgICAgICAgKiBwcm9ibGVtYXRpYyBleHByZXNzaW9uIGlzIHVua25vd24uCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVFlQRV9DSEVDS19VTktfTE9DX0VSUiwKLSAgICAgICAgIkNoeWJhIHBcdTAxNTlpIGtvbnRyb2xlIHR5cHUgdlx1MDBmZHJhenUgbmEgbmV6blx1MDBlMW1cdTAwZTltIG1cdTAwZWRzdFx1MDExYi4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIGEgY29tbWFuZC0KLSAgICAgICAgICogbGluZSBvcHRpb24gdGhhdCB3YXMgbm90IHJlY29nbml6ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSUxMRUdBTF9DTURMSU5FX09QVElPTl9FUlIsCi0gICAgICAgICJWb2xiYSBwXHUwMTU5XHUwMGVka2F6b3ZcdTAwZTlobyBcdTAxNTlcdTAwZTFka3UgJyd7MH0nJyBuZW5cdTAwZWQgcGxhdG5cdTAwZTEuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBhIGNvbW1hbmQtCi0gICAgICAgICAqIGxpbmUgb3B0aW9uLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkNNRExJTkVfT1BUX01JU1NJTkdfQVJHX0VSUiwKLSAgICAgICAgIlZvbGJcdTAxMWIgcFx1MDE1OVx1MDBlZGthem92XHUwMGU5aG8gXHUwMTU5XHUwMGUxZGt1ICcnezB9JycgY2h5Ylx1MDBlZCBwb1x1MDE3ZWFkb3Zhblx1MDBmZCBhcmd1bWVudC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIHVzZWQgdG8gaW5kaWNhdGUgdGhlIHNldmVyaXR5Ci0gICAgICAgICAqIG9mIGFub3RoZXIgbWVzc2FnZS4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBjb250YWlucyB0d28gZXJyb3IKLSAgICAgICAgICogbWVzc2FnZXMuICBUaGUgc3BhY2luZyBiZWZvcmUgdGhlIHNlY29uZCBzdWJzdGl0dXRpb24gdGV4dCBpbmRlbnRzCi0gICAgICAgICAqIGl0IHRoZSBzYW1lIGFtb3VudCBhcyB0aGUgZmlyc3QgaW4gRW5nbGlzaC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5XQVJOSU5HX1BMVVNfV1JBUFBFRF9NU0csCi0gICAgICAgICJWQVJPVlx1MDBjMU5cdTAwY2Q6ICcnezB9JydcbiAgICAgICAgOnsxfSJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgdXNlZCB0byBpbmRpY2F0ZSB0aGUgc2V2ZXJpdHkKLSAgICAgICAgICogb2YgYW5vdGhlciBtZXNzYWdlLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIGFuIGVycm9yIG1lc3NhZ2UuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuV0FSTklOR19NU0csCi0gICAgICAgICJWQVJPVlx1MDBjMU5cdTAwY2Q6ICcnezB9JycifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIHVzZWQgdG8gaW5kaWNhdGUgdGhlIHNldmVyaXR5Ci0gICAgICAgICAqIG9mIGFub3RoZXIgbWVzc2FnZS4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBjb250YWlucyB0d28gZXJyb3IKLSAgICAgICAgICogbWVzc2FnZXMuICBUaGUgc3BhY2luZyBiZWZvcmUgdGhlIHNlY29uZCBzdWJzdGl0dXRpb24gdGV4dCBpbmRlbnRzCi0gICAgICAgICAqIGl0IHRoZSBzYW1lIGFtb3VudCBhcyB0aGUgZmlyc3QgaW4gRW5nbGlzaC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5GQVRBTF9FUlJfUExVU19XUkFQUEVEX01TRywKLSAgICAgICAgIlpcdTAwYzFWQVx1MDE3ZE5cdTAwYzEgQ0hZQkE6ICcnezB9JydcbiAgICAgICAgICAgICA6ezF9In0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyB1c2VkIHRvIGluZGljYXRlIHRoZSBzZXZlcml0eQotICAgICAgICAgKiBvZiBhbm90aGVyIG1lc3NhZ2UuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgYW4gZXJyb3IgbWVzc2FnZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5GQVRBTF9FUlJfTVNHLAotICAgICAgICAiWlx1MDBjMVZBXHUwMTdkTlx1MDBjMSBDSFlCQTogJyd7MH0nJyJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgdXNlZCB0byBpbmRpY2F0ZSB0aGUgc2V2ZXJpdHkKLSAgICAgICAgICogb2YgYW5vdGhlciBtZXNzYWdlLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGNvbnRhaW5zIHR3byBlcnJvcgotICAgICAgICAgKiBtZXNzYWdlcy4gIFRoZSBzcGFjaW5nIGJlZm9yZSB0aGUgc2Vjb25kIHN1YnN0aXR1dGlvbiB0ZXh0IGluZGVudHMKLSAgICAgICAgICogaXQgdGhlIHNhbWUgYW1vdW50IGFzIHRoZSBmaXJzdCBpbiBFbmdsaXNoLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkVSUk9SX1BMVVNfV1JBUFBFRF9NU0csCi0gICAgICAgICJDSFlCQTogJyd7MH0nJ1xuICAgICA6ezF9In0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyB1c2VkIHRvIGluZGljYXRlIHRoZSBzZXZlcml0eQotICAgICAgICAgKiBvZiBhbm90aGVyIG1lc3NhZ2UuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgYW4gZXJyb3IgbWVzc2FnZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5FUlJPUl9NU0csCi0gICAgICAgICJDSFlCQTogJyd7MH0nJyJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYSBjbGFzcy4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5UUkFOU0ZPUk1fV0lUSF9UUkFOU0xFVF9TVFIsCi0gICAgICAgICJUcmFuc2Zvcm1hY2UgcG91XHUwMTdlaXRcdTAwZWRtIHRyYW5zbGV0dSAnJ3swfScnICJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZmlyc3Qgc3Vic3RpdHV0aW9uIGlzIHRoZSBuYW1lIG9mIGEgY2xhc3MsCi0gICAgICAgICAqIHdoaWxlIHRoZSBzZWNvbmQgc3Vic3RpdHV0aW9uIGlzIHRoZSBuYW1lIG9mIGEgamFyIGZpbGUuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVFJBTlNGT1JNX1dJVEhfSkFSX1NUUiwKLSAgICAgICAgIlRyYW5zZm9ybWFjZSBwb3VcdTAxN2VpdFx1MDBlZG0gdHJhbnNsZXR1ICcnezB9JycgemUgc291Ym9ydSBqYXIgJyd7MX0nJyJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiVHJhbnNmb3JtZXJGYWN0b3J5IiBpcyB0aGUgbmFtZSBvZiBhIEphdmEKLSAgICAgICAgICogaW50ZXJmYWNlIGFuZCBtdXN0IG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzCi0gICAgICAgICAqIHRoZSBuYW1lIG9mIHRoZSBjbGFzcyB0aGF0IGNvdWxkIG5vdCBiZSBpbnN0YW50aWF0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuQ09VTERfTk9UX0NSRUFURV9UUkFOU19GQUNULAotICAgICAgICAiTmVsemUgdnl0dm9cdTAxNTlpdCBpbnN0YW5jaSB0XHUwMTU5XHUwMGVkZHkgVHJhbnNmb3JtZXJGYWN0b3J5ICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBpcyB1c2VkIGFzIGEgaGVhZGVyLgotICAgICAgICAgKiBBbGwgdGhlIGVycm9yIG1lc3NhZ2VzIGFyZSBjb2xsZWN0ZWQgdG9nZXRoZXIgYW5kIGRpc3BsYXllZCBiZW5lYXRoCi0gICAgICAgICAqIHRoaXMgbWVzc2FnZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5DT01QSUxFUl9FUlJPUl9LRVksCi0gICAgICAgICJDaHlieSBrb21waWxcdTAwZTF0b3J1OiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgaXMgdXNlZCBhcyBhIGhlYWRlci4KLSAgICAgICAgICogQWxsIHRoZSB3YXJuaW5nIG1lc3NhZ2VzIGFyZSBjb2xsZWN0ZWQgdG9nZXRoZXIgYW5kIGRpc3BsYXllZAotICAgICAgICAgKiBiZW5lYXRoIHRoaXMgbWVzc2FnZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5DT01QSUxFUl9XQVJOSU5HX0tFWSwKLSAgICAgICAgIlZhcm92XHUwMGUxblx1MDBlZCBrb21waWxcdTAwZTF0b3J1OiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgaXMgdXNlZCBhcyBhIGhlYWRlci4KLSAgICAgICAgICogQWxsIHRoZSBlcnJvciBtZXNzYWdlcyB0aGF0IGFyZSBwcm9kdWNlZCB3aGVuIHRoZSBzdHlsZXNoZWV0IGlzCi0gICAgICAgICAqIGFwcGxpZWQgdG8gYW4gaW5wdXQgZG9jdW1lbnQgYXJlIGNvbGxlY3RlZCB0b2dldGhlciBhbmQgZGlzcGxheWVkCi0gICAgICAgICAqIGJlbmVhdGggdGhpcyBtZXNzYWdlLiAgQSAndHJhbnNsZXQnIGlzIHRoZSBjb21waWxlZCBmb3JtIG9mIGEKLSAgICAgICAgICogc3R5bGVzaGVldCAoc2VlIGFib3ZlKS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5SVU5USU1FX0VSUk9SX0tFWSwKLSAgICAgICAgIkNoeWJ5IHRyYW5zbGV0dToifSwKLQotICAgICAgICB7RXJyb3JNc2cuSkFYUF9TRUNVUkVQUk9DRVNTSU5HX0ZFQVRVUkUsCi0gICAgICAgICJGRUFUVVJFX1NFQ1VSRV9QUk9DRVNTSU5HOiBDYW5ub3Qgc2V0IHRoZSBmZWF0dXJlIHRvIGZhbHNlIHdoZW4gc2VjdXJpdHkgbWFuYWdlciBpcyBwcmVzZW50LiJ9Ci0gICAgfTsKLQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvdXRpbC9FcnJvck1lc3NhZ2VzX2RlLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL3V0aWwvRXJyb3JNZXNzYWdlc19kZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA5ZGE3MDU5Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvdXRpbC9FcnJvck1lc3NhZ2VzX2RlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5NzQgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsOwotCi1pbXBvcnQgamF2YS51dGlsLkxpc3RSZXNvdXJjZUJ1bmRsZTsKLQotLyoqCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqLwotcHVibGljIGNsYXNzIEVycm9yTWVzc2FnZXNfZGUgZXh0ZW5kcyBMaXN0UmVzb3VyY2VCdW5kbGUgewotCi0vKgotICogWFNMVEMgY29tcGlsZS10aW1lIGVycm9yIG1lc3NhZ2VzLgotICoKLSAqIEdlbmVyYWwgbm90ZXMgdG8gdHJhbnNsYXRvcnMgYW5kIGRlZmluaXRpb25zOgotICoKLSAqICAgMSkgWFNMVEMgaXMgdGhlIG5hbWUgb2YgdGhlIHByb2R1Y3QuICBJdCBpcyBhbiBhY3JvbnltIGZvciAiWFNMVCBDb21waWxlciIuCi0gKiAgICAgIFhTTFQgaXMgYW4gYWNyb255bSBmb3IgIlhNTCBTdHlsZXNoZWV0IExhbmd1YWdlOiBUcmFuc2Zvcm1hdGlvbnMiLgotICoKLSAqICAgMikgQSBzdHlsZXNoZWV0IGlzIGEgZGVzY3JpcHRpb24gb2YgaG93IHRvIHRyYW5zZm9ybSBhbiBpbnB1dCBYTUwgZG9jdW1lbnQKLSAqICAgICAgaW50byBhIHJlc3VsdGFudCBYTUwgZG9jdW1lbnQgKG9yIEhUTUwgZG9jdW1lbnQgb3IgdGV4dCkuICBUaGUKLSAqICAgICAgc3R5bGVzaGVldCBpdHNlbGYgaXMgZGVzY3JpYmVkIGluIHRoZSBmb3JtIG9mIGFuIFhNTCBkb2N1bWVudC4KLSAqCi0gKiAgIDMpIEEgdGVtcGxhdGUgaXMgYSBjb21wb25lbnQgb2YgYSBzdHlsZXNoZWV0IHRoYXQgaXMgdXNlZCB0byBtYXRjaCBhCi0gKiAgICAgIHBhcnRpY3VsYXIgcG9ydGlvbiBvZiBhbiBpbnB1dCBkb2N1bWVudCBhbmQgc3BlY2lmaWVzIHRoZSBmb3JtIG9mIHRoZQotICogICAgICBjb3JyZXNwb25kaW5nIHBvcnRpb24gb2YgdGhlIG91dHB1dCBkb2N1bWVudC4KLSAqCi0gKiAgIDQpIEFuIGF4aXMgaXMgYSBwYXJ0aWN1bGFyICJkaW1lbnNpb24iIGluIGEgdHJlZSByZXByZXNlbnRhdGlvbiBvZiBhbiBYTUwKLSAqICAgICAgZG9jdW1lbnQ7IHRoZSBub2RlcyBpbiB0aGUgdHJlZSBhcmUgZGl2aWRlZCBhbG9uZyBkaWZmZXJlbnQgYXhlcy4KLSAqICAgICAgVHJhdmVyc2luZyB0aGUgImNoaWxkIiBheGlzLCBmb3IgaW5zdGFuY2UsIG1lYW5zIHRoYXQgdGhlIHByb2dyYW0KLSAqICAgICAgd291bGQgdmlzaXQgZWFjaCBjaGlsZCBvZiBhIHBhcnRpY3VsYXIgbm9kZTsgdHJhdmVyc2luZyB0aGUgImRlc2NlbmRhbnQiCi0gKiAgICAgIGF4aXMgbWVhbnMgdGhhdCB0aGUgcHJvZ3JhbSB3b3VsZCB2aXNpdCB0aGUgY2hpbGQgbm9kZXMgb2YgYSBwYXJ0aWN1bGFyCi0gKiAgICAgIG5vZGUsIHRoZWlyIGNoaWxkcmVuLCBhbmQgc28gb24gdW50aWwgdGhlIGxlYWYgbm9kZXMgb2YgdGhlIHRyZWUgYXJlCi0gKiAgICAgIHJlYWNoZWQuCi0gKgotICogICA1KSBBbiBpdGVyYXRvciBpcyBhbiBvYmplY3QgdGhhdCB0cmF2ZXJzZXMgbm9kZXMgaW4gYSB0cmVlIGFsb25nIGEKLSAqICAgICAgcGFydGljdWxhciBheGlzLCBvbmUgYXQgYSB0aW1lLgotICoKLSAqICAgNikgQW4gZWxlbWVudCBpcyBhIG1hcmstdXAgdGFnIGluIGFuIFhNTCBkb2N1bWVudDsgYW4gYXR0cmlidXRlIGlzIGEKLSAqICAgICAgbW9kaWZpZXIgb24gdGhlIHRhZy4gIEZvciBleGFtcGxlLCBpbiA8ZWxlbSBhdHRyPSd2YWwnIGF0dHIyPSd2YWwyJz4KLSAqICAgICAgImVsZW0iIGlzIGFuIGVsZW1lbnQgbmFtZSwgImF0dHIiIGFuZCAiYXR0cjIiIGFyZSBhdHRyaWJ1dGUgbmFtZXMgd2l0aAotICogICAgICB0aGUgdmFsdWVzICJ2YWwiIGFuZCAidmFsMiIsIHJlc3BlY3RpdmVseS4KLSAqCi0gKiAgIDcpIEEgbmFtZXNwYWNlIGRlY2xhcmF0aW9uIGlzIGEgc3BlY2lhbCBhdHRyaWJ1dGUgdGhhdCBpcyB1c2VkIHRvIGFzc29jaWF0ZQotICogICAgICBhIHByZWZpeCB3aXRoIGEgVVJJICh0aGUgbmFtZXNwYWNlKS4gIFRoZSBtZWFuaW5ncyBvZiBlbGVtZW50IG5hbWVzIGFuZAotICogICAgICBhdHRyaWJ1dGUgbmFtZXMgdGhhdCB1c2UgdGhhdCBwcmVmaXggYXJlIGRlZmluZWQgd2l0aCByZXNwZWN0IHRvIHRoYXQKLSAqICAgICAgbmFtZXNwYWNlLgotICoKLSAqICAgOCkgRE9NIGlzIGFuIGFjcm9ueW0gZm9yIERvY3VtZW50IE9iamVjdCBNb2RlbC4gIEl0IGlzIGEgdHJlZQotICogICAgICByZXByZXNlbnRhdGlvbiBvZiBhbiBYTUwgZG9jdW1lbnQuCi0gKgotICogICAgICBTQVggaXMgYW4gYWNyb255bSBmb3IgdGhlIFNpbXBsZSBBUEkgZm9yIFhNTCBwcm9jZXNzaW5nLiAgSXQgaXMgYW4gQVBJCi0gKiAgICAgIHVzZWQgaW5mb3JtIGFuIFhNTCBwcm9jZXNzb3IgKGluIHRoaXMgY2FzZSBYU0xUQykgb2YgdGhlIHN0cnVjdHVyZSBhbmQKLSAqICAgICAgY29udGVudCBvZiBhbiBYTUwgZG9jdW1lbnQuCi0gKgotICogICAgICBJbnB1dCB0byB0aGUgc3R5bGVzaGVldCBwcm9jZXNzb3IgY2FuIGNvbWUgZnJvbSBhbiBYTUwgcGFyc2VyIGluIHRoZQotICogICAgICBmb3JtIG9mIGEgRE9NIHRyZWUgb3IgdGhyb3VnaCB0aGUgU0FYIEFQSS4KLSAqCi0gKiAgIDkpIERURCBpcyBhIGRvY3VtZW50IHR5cGUgZGVjbGFyYXRpb24uICBJdCBpcyBhIHdheSBvZiBzcGVjaWZ5aW5nIHRoZQotICogICAgICBncmFtbWFyIGZvciBhbiBYTUwgZmlsZSwgdGhlIG5hbWVzIGFuZCB0eXBlcyBvZiBlbGVtZW50cywgYXR0cmlidXRlcywKLSAqICAgICAgZXRjLgotICoKLSAqICAxMCkgWFBhdGggaXMgYSBzcGVjaWZpY2F0aW9uIHRoYXQgZGVzY3JpYmVzIGEgbm90YXRpb24gZm9yIGlkZW50aWZ5aW5nCi0gKiAgICAgIG5vZGVzIGluIGEgdHJlZS1zdHJ1Y3R1cmVkIHJlcHJlc2VudGF0aW9uIG9mIGFuIFhNTCBkb2N1bWVudC4gIEFuCi0gKiAgICAgIGluc3RhbmNlIG9mIHRoYXQgbm90YXRpb24gaXMgcmVmZXJyZWQgdG8gYXMgYW4gWFBhdGggZXhwcmVzc2lvbi4KLSAqCi0gKiAgMTEpIFRyYW5zbGV0IGlzIGFuIGludmVudGVkIHRlcm0gdGhhdCByZWZlcnMgdG8gdGhlIGNsYXNzIGZpbGUgdGhhdCBjb250YWlucwotICogICAgICB0aGUgY29tcGlsZWQgZm9ybSBvZiBhIHN0eWxlc2hlZXQuCi0gKi8KLQotICAgIC8vIFRoZXNlIG1lc3NhZ2Ugc2hvdWxkIGJlIHJlYWQgZnJvbSBhIGxvY2FsZS1zcGVjaWZpYyByZXNvdXJjZSBidW5kbGUKLSAgICAvKiogR2V0IHRoZSBsb29rdXAgdGFibGUgZm9yIGVycm9yIG1lc3NhZ2VzLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgbWVzc2FnZSBsb29rdXAgdGFibGUuCi0gICAgICovCi0gICAgcHVibGljIE9iamVjdFtdW10gZ2V0Q29udGVudHMoKQotICAgIHsKLSAgICAgIHJldHVybiBuZXcgT2JqZWN0W11bXSB7Ci0gICAgICAgIHtFcnJvck1zZy5NVUxUSVBMRV9TVFlMRVNIRUVUX0VSUiwKLSAgICAgICAgIk1laHJlcmUgU3R5bGVzaGVldHMgaW4gZGVyc2VsYmVuIERhdGVpIGRlZmluaWVydC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIGEKLSAgICAgICAgICogdGVtcGxhdGUuICBUaGUgc2FtZSBuYW1lIHdhcyB1c2VkIG9uIHR3byBkaWZmZXJlbnQgdGVtcGxhdGVzIGluIHRoZQotICAgICAgICAgKiBzYW1lIHN0eWxlc2hlZXQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVEVNUExBVEVfUkVERUZfRVJSLAotICAgICAgICAiVm9ybGFnZSBcInswfVwiIGJlcmVpdHMgaW4gZGllc2VtIFN0eWxlc2hlZXQgZGVmaW5pZXJ0LiJ9LAotCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBhCi0gICAgICAgICAqIHRlbXBsYXRlLiAgQSByZWZlcmVuY2UgdG8gdGhlIHRlbXBsYXRlIG5hbWUgd2FzIGVuY291bnRlcmVkLCBidXQgdGhlCi0gICAgICAgICAqIHRlbXBsYXRlIGlzIHVuZGVmaW5lZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5URU1QTEFURV9VTkRFRl9FUlIsCi0gICAgICAgICJWb3JsYWdlIFwiezB9XCIgbmljaHQgaW4gZGllc2VtIFN0eWxlc2hlZXQgZGVmaW5pZXJ0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYSB2YXJpYWJsZQotICAgICAgICAgKiB0aGF0IHdhcyBkZWZpbmVkIG1vcmUgdGhhbiBvbmNlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlZBUklBQkxFX1JFREVGX0VSUiwKLSAgICAgICAgIlZhcmlhYmxlIFwiezB9XCIgaXN0IG1laHJtYWxzIGluIGRlbXNlbGJlbiBHXHUwMEZDbHRpZ2tlaXRzYmVyZWljaCBkZWZpbmllcnQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBhIHZhcmlhYmxlCi0gICAgICAgICAqIG9yIHBhcmFtZXRlci4gIEEgcmVmZXJlbmNlIHRvIHRoZSB2YXJpYWJsZSBvciBwYXJhbWV0ZXIgd2FzIGZvdW5kLAotICAgICAgICAgKiBidXQgaXQgd2FzIG5ldmVyIGRlZmluZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVkFSSUFCTEVfVU5ERUZfRVJSLAotICAgICAgICAiVmFyaWFibGUgb2RlciBQYXJhbWV0ZXIgXCJ7MH1cIiBpc3QgbmljaHQgZGVmaW5pZXJ0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgd29yZCAiY2xhc3MiIGhlcmUgcmVmZXJzIHRvIGEgSmF2YSBjbGFzcy4KLSAgICAgICAgICogUHJvY2Vzc2luZyB0aGUgc3R5bGVzaGVldCByZXF1aXJlZCBhIGNsYXNzIHRvIGJlIGxvYWRlZCwgYnV0IGl0IGNvdWxkCi0gICAgICAgICAqIG5vdCBiZSBmb3VuZC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiB0aGUgY2xhc3MuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuQ0xBU1NfTk9UX0ZPVU5EX0VSUiwKLSAgICAgICAgIktsYXNzZSBcInswfVwiIGthbm4gbmljaHQgZ2VmdW5kZW4gd2VyZGVuLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgd29yZCAibWV0aG9kIiBoZXJlIHJlZmVycyB0byBhIEphdmEgbWV0aG9kLgotICAgICAgICAgKiBQcm9jZXNzaW5nIHRoZSBzdHlsZXNoZWV0IHJlcXVpcmVkIGEgcmVmZXJlbmNlIHRvIHRoZSBtZXRob2QgbmFtZWQgYnkKLSAgICAgICAgICogdGhlIHN1YnN0aXR1dGlvbiB0ZXh0LCBidXQgaXQgY291bGQgbm90IGJlIGZvdW5kLiAgInB1YmxpYyIgaXMgdGhlCi0gICAgICAgICAqIEphdmEga2V5d29yZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5NRVRIT0RfTk9UX0ZPVU5EX0VSUiwKLSAgICAgICAgIkV4dGVybmUgTWV0aG9kZSBcInswfVwiIGthbm4gbmljaHQgZ2VmdW5kZW4gd2VyZGVuIChtdXNzIFwicHVibGljXCIgc2VpbikuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSB3b3JkICJtZXRob2QiIGhlcmUgcmVmZXJzIHRvIGEgSmF2YSBtZXRob2QuCi0gICAgICAgICAqIFByb2Nlc3NpbmcgdGhlIHN0eWxlc2hlZXQgcmVxdWlyZWQgYSByZWZlcmVuY2UgdG8gdGhlIG1ldGhvZCBuYW1lZCBieQotICAgICAgICAgKiB0aGUgc3Vic3RpdHV0aW9uIHRleHQsIGJ1dCBubyBtZXRob2Qgd2l0aCB0aGUgcmVxdWlyZWQgdHlwZXMgb2YKLSAgICAgICAgICogYXJndW1lbnRzIG9yIHJldHVybiB0eXBlIGNvdWxkIGJlIGZvdW5kLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkFSR1VNRU5UX0NPTlZFUlNJT05fRVJSLAotICAgICAgICAiS29udmVydGllcnVuZyB2b24gQXJndW1lbnQtL1JcdTAwRkNja2dhYmV0eXAgaW4gQXVmcnVmIHZvbiBNZXRob2RlIFwiezB9XCIgbmljaHQgbVx1MDBGNmdsaWNoIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmaWxlIG9yIFVSSSBuYW1lZCBpbiB0aGUgc3Vic3RpdHV0aW9uIHRleHQKLSAgICAgICAgICogaXMgbWlzc2luZy4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5GSUxFX05PVF9GT1VORF9FUlIsCi0gICAgICAgICJEYXRlaSBvZGVyIFVSSSBcInswfVwiIG5pY2h0IGdlZnVuZGVuLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgZGlzcGxheWVkIHdoZW4gdGhlIFVSSQotICAgICAgICAgKiBtZW50aW9uZWQgaW4gdGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIG5vdCB3ZWxsLWZvcm1lZCBzeW50YWN0aWNhbGx5LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklOVkFMSURfVVJJX0VSUiwKLSAgICAgICAgIlVuZ1x1MDBGQ2x0aWdlciBVUkkgXCJ7MH1cIi4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZpbGUgb3IgVVJJIG5hbWVkIGluIHRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICAgKiBleGlzdHMgYnV0IGNvdWxkIG5vdCBiZSBvcGVuZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuRklMRV9BQ0NFU1NfRVJSLAotICAgICAgICAiRGF0ZWkgb2RlciBVUkkgXCJ7MH1cIiBrYW5uIG5pY2h0IGdlXHUwMEY2ZmZuZXQgd2VyZGVuLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6IDx4c2w6c3R5bGVzaGVldD4gYW5kIDx4c2w6dHJhbnNmb3JtPiBhcmUKLSAgICAgICAgICoga2V5d29yZHMgdGhhdCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTUlTU0lOR19ST09UX0VSUiwKLSAgICAgICAgIjx4c2w6c3R5bGVzaGVldD4tIG9kZXIgPHhzbDp0cmFuc2Zvcm0+LUVsZW1lbnQgZXJ3YXJ0ZXQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IGNvbnRhaW5lZCBhIHJlZmVyZW5jZSB0byBhCi0gICAgICAgICAqIG5hbWVzcGFjZSBwcmVmaXggdGhhdCB3YXMgdW5kZWZpbmVkLiAgVGhlIHZhbHVlIG9mIHRoZSBzdWJzdGl0dXRpb24KLSAgICAgICAgICogdGV4dCBpcyB0aGUgbmFtZSBvZiB0aGUgcHJlZml4LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk5BTUVTUEFDRV9VTkRFRl9FUlIsCi0gICAgICAgICJOYW1lc3BhY2UtUHJcdTAwRTRmaXggXCJ7MH1cIiBpc3QgbmljaHQgZGVrbGFyaWVydC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIEphdmEgZnVuY3Rpb24gbmFtZWQgaW4gdGhlIHN0eWxlc2hlZXQgY291bGQKLSAgICAgICAgICogbm90IGJlIGZvdW5kLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkZVTkNUSU9OX1JFU09MVkVfRVJSLAotICAgICAgICAiQXVmcnVmIGthbm4gbmljaHQgaW4gRnVua3Rpb24gXCJ7MH1cIiBhdWZnZWxcdTAwRjZzdCB3ZXJkZW4uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBhCi0gICAgICAgICAqIGZ1bmN0aW9uLiAgQSBsaXRlcmFsIHN0cmluZyBoZXJlIG1lYW5zIGEgY29uc3RhbnQgc3RyaW5nIHZhbHVlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk5FRURfTElURVJBTF9FUlIsCi0gICAgICAgICJBcmd1bWVudCBmXHUwMEZDciBcInswfVwiIG11c3MgZWluZSBsaXRlcmFsZSBaZWljaGVuZm9sZ2Ugc2Vpbi4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGluZGljYXRlcyB0aGVyZSB3YXMgYSBzeW50YWN0aWMKLSAgICAgICAgICogZXJyb3IgaW4gdGhlIGZvcm0gb2YgYW4gWFBhdGggZXhwcmVzc2lvbi4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcwotICAgICAgICAgKiB0aGUgZXhwcmVzc2lvbi4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5YUEFUSF9QQVJTRVJfRVJSLAotICAgICAgICAiRmVobGVyIGJlaW0gUGFyc2VuIHZvbiBYUGF0aC1BdXNkcnVjayBcInswfVwiLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBbiBlbGVtZW50IGluIHRoZSBzdHlsZXNoZWV0IHJlcXVpcmVzIGEKLSAgICAgICAgICogcGFydGljdWxhciBhdHRyaWJ1dGUgbmFtZWQgYnkgdGhlIHN1YnN0aXR1dGlvbiB0ZXh0LCBidXQgdGhhdAotICAgICAgICAgKiBhdHRyaWJ1dGUgd2FzIG5vdCBzcGVjaWZpZWQgaW4gdGhlIHN0eWxlc2hlZXQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuUkVRVUlSRURfQVRUUl9FUlIsCi0gICAgICAgICJFcmZvcmRlcmxpY2hlcyBBdHRyaWJ1dCBcInswfVwiIGZlaGx0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgYSBjaGFyYWN0ZXIgbm90Ci0gICAgICAgICAqIHBlcm1pdHRlZCBpbiBhbiBYUGF0aCBleHByZXNzaW9uIHdhcyBlbmNvdW50ZXJlZC4gIFRoZSBzdWJzdGl0dXRpb24KLSAgICAgICAgICogdGV4dCBpcyB0aGUgb2ZmZW5kaW5nIGNoYXJhY3Rlci4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTExFR0FMX0NIQVJfRVJSLAotICAgICAgICAiVW5nXHUwMEZDbHRpZ2VzIFplaWNoZW4gXCJ7MH1cIiBpbiBYUGF0aC1BdXNkcnVjay4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQSBwcm9jZXNzaW5nIGluc3RydWN0aW9uIGlzIGEgbWFyay11cCBpdGVtIGluCi0gICAgICAgICAqIGFuIFhNTCBkb2N1bWVudCB0aGF0IHJlcXVlc3Qgc29tZSBiZWhhdmlvdXIgb2YgYW4gWE1MIHByb2Nlc3Nvci4gIFRoZQotICAgICAgICAgKiBmb3JtIG9mIHRoZSBuYW1lIG9mIHdhcyBpbnZhbGlkIGluIHRoaXMgY2FzZSwgYW5kIHRoZSBzdWJzdGl0dXRpb24KLSAgICAgICAgICogdGV4dCBpcyB0aGUgbmFtZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTExFR0FMX1BJX0VSUiwKLSAgICAgICAgIlVuZ1x1MDBGQ2x0aWdlciBOYW1lIFwiezB9XCIgZlx1MDBGQ3IgVmVyYXJiZWl0dW5nc2Fud2Vpc3VuZy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIHJlcG9ydGVkIGlmIHRoZSBzdHlsZXNoZWV0Ci0gICAgICAgICAqIGJlaW5nIHByb2Nlc3NlZCBhdHRlbXB0ZWQgdG8gY29uc3RydWN0IGFuIFhNTCBkb2N1bWVudCB3aXRoIGFuCi0gICAgICAgICAqIGF0dHJpYnV0ZSBpbiBhIHBsYWNlIG90aGVyIHRoYW4gb24gYW4gZWxlbWVudC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICAgKiBzcGVjaWZpZXMgdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5TVFJBWV9BVFRSSUJVVEVfRVJSLAotICAgICAgICAiQXR0cmlidXQgXCJ7MH1cIiBhdVx1MDBERmVyaGFsYiBkZXMgRWxlbWVudHMuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIGF0dHJpYnV0ZSB0aGF0IHdhc24ndCByZWNvZ25pemVkIHdhcwotICAgICAgICAgKiBzcGVjaWZpZWQgb24gYW4gZWxlbWVudCBpbiB0aGUgc3R5bGVzaGVldC4gIFRoZSBhdHRyaWJ1dGUgaXMgbmFtZWQKLSAgICAgICAgICogYnkgdGhlIHN1YnN0aXR1dGlvbgotICAgICAgICAgKiB0ZXh0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfQVRUUklCVVRFX0VSUiwKLSAgICAgICAgIlVuZ1x1MDBGQ2x0aWdlcyBBdHRyaWJ1dCBcInswfVwiLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiaW1wb3J0IiBhbmQgImluY2x1ZGUiIGFyZSBrZXl3b3JkcyB0aGF0IHNob3VsZAotICAgICAgICAgKiBub3QgYmUgdHJhbnNsYXRlZC4gIFRoaXMgbWVzc2FnZXMgaW5kaWNhdGVzIHRoYXQgdGhlIHN0eWxlc2hlZXQKLSAgICAgICAgICogbmFtZWQgaW4gdGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGltcG9ydGVkIG9yIGluY2x1ZGVkIGl0c2VsZiBlaXRoZXIKLSAgICAgICAgICogZGlyZWN0bHkgb3IgaW5kaXJlY3RseS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5DSVJDVUxBUl9JTkNMVURFX0VSUiwKLSAgICAgICAgIlp5a2xpc2NoZXMgaW1wb3J0L2luY2x1ZGUuIFN0eWxlc2hlZXQgXCJ7MH1cIiBiZXJlaXRzIGdlbGFkZW4uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEEgcmVzdWx0LXRyZWUgZnJhZ21lbnQgaXMgYSBwb3J0aW9uIG9mIGEKLSAgICAgICAgICogcmVzdWx0aW5nIFhNTCBkb2N1bWVudCByZXByZXNlbnRlZCBhcyBhIHRyZWUuICAiPHhzbDpzb3J0PiIgaXMgYQotICAgICAgICAgKiBrZXl3b3JkIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuUkVTVUxUX1RSRUVfU09SVF9FUlIsCi0gICAgICAgICJFcmdlYm5pc2JhdW1mcmFnbWVudGUga1x1MDBGNm5uZW4gbmljaHQgc29ydGllcnQgd2VyZGVuICg8eHNsOnNvcnQ+LUVsZW1lbnRlIHdlcmRlbiBpZ25vcmllcnQpLiBTaWUgbVx1MDBGQ3NzZW4gZGllIEtub3RlbiBzb3J0aWVyZW4sIHdlbm4gU2llIGRlbiBFcmdlYm5pc2JhdW0gZXJzdGVsbGVuLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBIG5hbWUgY2FuIGJlIGdpdmVuIHRvIGEgcGFydGljdWxhciBzdHlsZSB0byBiZQotICAgICAgICAgKiB1c2VkIHRvIGZvcm1hdCBkZWNpbWFsIHZhbHVlcy4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBnaXZlcyB0aGUgbmFtZQotICAgICAgICAgKiBvZiBzdWNoIGEgc3R5bGUgZm9yIHdoaWNoIG1vcmUgdGhhbiBvbmUgZGVjbGFyYXRpb24gd2FzIGVuY291bnRlcmVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlNZTUJPTFNfUkVERUZfRVJSLAotICAgICAgICAiRGV6aW1hbGZvcm1hdGllcnVuZyBcInswfVwiIGlzdCBiZXJlaXRzIGRlZmluaWVydC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN0eWxlc2hlZXQgdmVyc2lvbiBuYW1lZCBpbiB0aGUKLSAgICAgICAgICogc3Vic3RpdHV0aW9uIHRleHQgaXMgbm90IHN1cHBvcnRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5YU0xfVkVSU0lPTl9FUlIsCi0gICAgICAgICJYU0wtVmVyc2lvbiBcInswfVwiIHdpcmQgbmljaHQgdm9uIFhTTFRDIHVudGVyc3RcdTAwRkN0enQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBkZWZpbml0aW9ucyBvZiBvbmUgb3IgbW9yZSB2YXJpYWJsZXMgb3IKLSAgICAgICAgICogcGFyYW1ldGVycyBkZXBlbmQgb24gb25lIGFub3RoZXIuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuQ0lSQ1VMQVJfVkFSSUFCTEVfRVJSLAotICAgICAgICAiWnlrbGlzY2hlIFZhcmlhYmxlbi0vUGFyYW1ldGVycmVmZXJlbnogaW4gXCJ7MH1cIi4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIG9wZXJhdG9yIGluIGFuIGV4cHJlc2lvbiB3aXRoIHR3byBvcGVyYW5kcyB3YXMKLSAgICAgICAgICogbm90IHJlY29nbml6ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSUxMRUdBTF9CSU5BUllfT1BfRVJSLAotICAgICAgICAiVW5iZWthbm50ZXIgT3BlcmF0b3IgZlx1MDBGQ3IgQmluXHUwMEU0cmF1c2RydWNrLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgcHJvZHVjZWQgaWYgYSByZWZlcmVuY2UgdG8gYQotICAgICAgICAgKiBmdW5jdGlvbiBoYXMgdG9vIG1hbnkgb3IgdG9vIGZldyBhcmd1bWVudHMuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSUxMRUdBTF9BUkdfRVJSLAotICAgICAgICAiVW5nXHUwMEZDbHRpZ2UgQXJndW1lbnRlIGZcdTAwRkNyIEZ1bmt0aW9uc2F1ZnJ1Zi4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgImRvY3VtZW50KCkiIGlzIHRoZSBuYW1lIG9mIGZ1bmN0aW9uIGFuZCBtdXN0Ci0gICAgICAgICAqIG5vdCBiZSB0cmFuc2xhdGVkLiAgQSBub2RlLXNldCBpcyBhIHNldCBvZiB0aGUgbm9kZXMgaW4gdGhlIHRyZWUKLSAgICAgICAgICogcmVwcmVzZW50YXRpb24gb2YgYW4gWE1MIGRvY3VtZW50LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkRPQ1VNRU5UX0FSR19FUlIsCi0gICAgICAgICJad2VpdGVzIEFyZ3VtZW50IGZcdTAwRkNyIGRvY3VtZW50KCktRnVua3Rpb24gbXVzcyBlaW4gTm9kZVNldCBzZWluLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiPHhzbDp3aGVuPiIgYW5kICI8eHNsOmNob29zZT4iIGFyZSBrZXl3b3JkcwotICAgICAgICAgKiBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhpcyBtZXNzYWdlIGRlc2NyaWJlcyBhIHN5bnRheCBlcnJvcgotICAgICAgICAgKiBpbiB0aGUgc3R5bGVzaGVldC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5NSVNTSU5HX1dIRU5fRVJSLAotICAgICAgICAiTWluZGVzdGVucyBlaW4gPHhzbDp3aGVuPi1FbGVtZW50IGluIDx4c2w6Y2hvb3NlPiBlcmZvcmRlcmxpY2guIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICI8eHNsOm90aGVyd2lzZT4iIGFuZCAiPHhzbDpjaG9vc2U+IiBhcmUKLSAgICAgICAgICoga2V5d29yZHMgYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoaXMgbWVzc2FnZSBkZXNjcmliZXMgYQotICAgICAgICAgKiBzeW50YXggZXJyb3IgaW4gdGhlIHN0eWxlc2hlZXQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTVVMVElQTEVfT1RIRVJXSVNFX0VSUiwKLSAgICAgICAgIk51ciBlaW4gPHhzbDpvdGhlcndpc2U+LUVsZW1lbnQgaW4gPHhzbDpjaG9vc2U+IHp1bFx1MDBFNHNzaWcuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICI8eHNsOm90aGVyd2lzZT4iIGFuZCAiPHhzbDpjaG9vc2U+IiBhcmUKLSAgICAgICAgICoga2V5d29yZHMgYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoaXMgbWVzc2FnZSBkZXNjcmliZXMgYQotICAgICAgICAgKiBzeW50YXggZXJyb3IgaW4gdGhlIHN0eWxlc2hlZXQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuU1RSQVlfT1RIRVJXSVNFX0VSUiwKLSAgICAgICAgIjx4c2w6b3RoZXJ3aXNlPiBrYW5uIG51ciBpbiA8eHNsOmNob29zZT4gdmVyd2VuZGV0IHdlcmRlbi4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIjx4c2w6d2hlbj4iIGFuZCAiPHhzbDpjaG9vc2U+IiBhcmUga2V5d29yZHMKLSAgICAgICAgICogYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoaXMgbWVzc2FnZSBkZXNjcmliZXMgYSBzeW50YXggZXJyb3IKLSAgICAgICAgICogaW4gdGhlIHN0eWxlc2hlZXQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuU1RSQVlfV0hFTl9FUlIsCi0gICAgICAgICI8eHNsOndoZW4+IGthbm4gbnVyIGluIDx4c2w6Y2hvb3NlPiB2ZXJ3ZW5kZXQgd2VyZGVuLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiPHhzbDp3aGVuPiIsICI8eHNsOm90aGVyd2lzZT4iIGFuZAotICAgICAgICAgKiAiPHhzbDpjaG9vc2U+IiBhcmUga2V5d29yZHMgYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoaXMKLSAgICAgICAgICogbWVzc2FnZSBkZXNjcmliZXMgYSBzeW50YXggZXJyb3IgaW4gdGhlIHN0eWxlc2hlZXQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuV0hFTl9FTEVNRU5UX0VSUiwKLSAgICAgICAgIk51ciA8eHNsOndoZW4+LSB1bmQgPHhzbDpvdGhlcndpc2U+LUVsZW1lbnRlIGluIDx4c2w6Y2hvb3NlPiB6dWxcdTAwRTRzc2lnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiPHhzbDphdHRyaWJ1dGUtc2V0PiIgYW5kICJuYW1lIiBhcmUga2V5d29yZHMKLSAgICAgICAgICogdGhhdCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVU5OQU1FRF9BVFRSSUJTRVRfRVJSLAotICAgICAgICAiQmVpIDx4c2w6YXR0cmlidXRlLXNldD4gZmVobHQgZGFzIFwibmFtZVwiLUF0dHJpYnV0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBbiBlbGVtZW50IGluIHRoZSBzdHlsZXNoZWV0IGNvbnRhaW5lZCBhbgotICAgICAgICAgKiBlbGVtZW50IG9mIGEgdHlwZSB0aGF0IGl0IHdhcyBub3QgcGVybWl0dGVkIHRvIGNvbnRhaW4uCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSUxMRUdBTF9DSElMRF9FUlIsCi0gICAgICAgICJVbmdcdTAwRkNsdGlnZXMgdW50ZXJnZW9yZG5ldGVzIEVsZW1lbnQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IHRyaWVkIHRvIGNyZWF0ZSBhbiBlbGVtZW50IHdpdGgKLSAgICAgICAgICogYSBuYW1lIHRoYXQgd2FzIG5vdCBhIHZhbGlkIFhNTCBuYW1lLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGNvbnRhaW5zCi0gICAgICAgICAqIHRoZSBuYW1lLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfRUxFTV9OQU1FX0VSUiwKLSAgICAgICAgIkVsZW1lbnRlIGRcdTAwRkNyZmVuIG5pY2h0IGRlbiBOYW1lbiBcInswfVwiIGhhYmVuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IHRyaWVkIHRvIGNyZWF0ZSBhbiBhdHRyaWJ1dGUKLSAgICAgICAgICogd2l0aCBhIG5hbWUgdGhhdCB3YXMgbm90IGEgdmFsaWQgWE1MIG5hbWUuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQKLSAgICAgICAgICogY29udGFpbnMgdGhlIG5hbWUuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSUxMRUdBTF9BVFRSX05BTUVfRVJSLAotICAgICAgICAiQXR0cmlidXRlIGRcdTAwRkNyZmVuIG5pY2h0IGRlbiBOYW1lbiBcInswfVwiIGhhYmVuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBjaGlsZHJlbiBvZiB0aGUgb3V0ZXJtb3N0IGVsZW1lbnQgb2YgYQotICAgICAgICAgKiBzdHlsZXNoZWV0IGFyZSByZWZlcnJlZCB0byBhcyB0b3AtbGV2ZWwgZWxlbWVudHMuICBObyB0ZXh0IHNob3VsZAotICAgICAgICAgKiBvY2N1ciB3aXRoaW4gdGhhdCBvdXRlcm1vc3QgZWxlbWVudCB1bmxlc3MgaXQgaXMgd2l0aGluIGEgdG9wLWxldmVsCi0gICAgICAgICAqIGVsZW1lbnQuICBUaGlzIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhhdCBjb25zdHJhaW50IHdhcyB2aW9sYXRlZC4KLSAgICAgICAgICogIjx4c2w6c3R5bGVzaGVldD4iIGlzIGEga2V5d29yZCB0aGF0IHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTExFR0FMX1RFWFRfTk9ERV9FUlIsCi0gICAgICAgICJUZXh0ZGF0ZW4gYXVcdTAwREZlcmhhbGIgZGVzIDx4c2w6c3R5bGVzaGVldD4tRWxlbWVudHMgZGVyIG9iZXJzdGVuIEViZW5lLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBKQVhQIGlzIGFuIGFjcm9ueW0gZm9yIHRoZSBKYXZhIEFQSSBmb3IgWE1MCi0gICAgICAgICAqIFByb2Nlc3NpbmcuICBUaGlzIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhlIFhNTCBwYXJzZXIgcHJvdmlkZWQgdG8KLSAgICAgICAgICogWFNMVEMgdG8gcHJvY2VzcyB0aGUgWE1MIGlucHV0IGRvY3VtZW50IGhhZCBhIGNvbmZpZ3VyYXRpb24gcHJvYmxlbS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5TQVhfUEFSU0VSX0NPTkZJR19FUlIsCi0gICAgICAgICJKQVhQLVBhcnNlciBuaWNodCBrb3JyZWt0IGtvbmZpZ3VyaWVydCJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgbmFtZXMgdGhlIGludGVybmFsIGVycm9yCi0gICAgICAgICAqIGVuY291bnRlcmVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklOVEVSTkFMX0VSUiwKLSAgICAgICAgIk5pY2h0IGJlaGViYmFyZXIgaW50ZXJuZXIgWFNMVEMtRmVobGVyOiBcInswfVwiIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IGNvbnRhaW5lZCBhbiBlbGVtZW50IHRoYXQgd2FzCi0gICAgICAgICAqIG5vdCByZWNvZ25pemVkIGFzIHBhcnQgb2YgdGhlIFhTTCBzeW50YXguICBUaGUgc3Vic3RpdHV0aW9uIHRleHQKLSAgICAgICAgICogZ2l2ZXMgdGhlIGVsZW1lbnQgbmFtZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5VTlNVUFBPUlRFRF9YU0xfRVJSLAotICAgICAgICAiTmljaHQgdW50ZXJzdFx1MDBGQ3R6dGVzIFhTTC1FbGVtZW50IFwiezB9XCIuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IHJlZmVycmVkIHRvIGFuIGV4dGVuc2lvbiB0byB0aGUKLSAgICAgICAgICogWFNMIHN5bnRheCBhbmQgaW5kaWNhdGVkIHRoYXQgaXQgd2FzIGRlZmluZWQgYnkgWFNMVEMsIGJ1dCBYU1RMQyBkb2VzCi0gICAgICAgICAqIG5vdCByZWNvZ25pemVkIHRoZSBwYXJ0aWN1bGFyIGV4dGVuc2lvbiBuYW1lZC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICAgKiBnaXZlcyB0aGUgZXh0ZW5zaW9uIG5hbWUuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVU5TVVBQT1JURURfRVhUX0VSUiwKLSAgICAgICAgIlVuYmVrYW5udGUgWFNMVEMtRXJ3ZWl0ZXJ1bmcgXCJ7MH1cIi4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIFhNTCBkb2N1bWVudCBnaXZlbiB0byBYU0xUQyBhcyBhIHN0eWxlc2hlZXQKLSAgICAgICAgICogd2FzIG5vdCwgaW4gZmFjdCwgYSBzdHlsZXNoZWV0LiAgWFNMVEMgaXMgYWJsZSB0byBkZXRlY3QgdGhhdCBpbiB0aGlzCi0gICAgICAgICAqIGNhc2UgYmVjYXVzZSB0aGUgb3V0ZXJtb3N0IGVsZW1lbnQgaW4gdGhlIHN0eWxlc2hlZXQgaGFzIHRvIGJlCi0gICAgICAgICAqIGRlY2xhcmVkIHdpdGggcmVzcGVjdCB0byB0aGUgWFNMIG5hbWVzcGFjZSBVUkksIGJ1dCBubyBkZWNsYXJhdGlvbgotICAgICAgICAgKiBmb3IgdGhhdCBuYW1lc3BhY2Ugd2FzIHNlZW4uCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTUlTU0lOR19YU0xUX1VSSV9FUlIsCi0gICAgICAgICJEYXMgRWluZ2FiZWRva3VtZW50IGlzdCBrZWluIFN0eWxlc2hlZXQgKGRlciBYU0wtTmFtZXNwYWNlIGlzdCBuaWNodCBpbSBSb290LUVsZW1lbnQgZGVrbGFyaWVydCkuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFhTTFRDIGNvdWxkIG5vdCBmaW5kIHRoZSBzdHlsZXNoZWV0IGRvY3VtZW50Ci0gICAgICAgICAqIHdpdGggdGhlIG5hbWUgc3BlY2lmaWVkIGJ5IHRoZSBzdWJzdGl0dXRpb24gdGV4dC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5NSVNTSU5HX1hTTFRfVEFSR0VUX0VSUiwKLSAgICAgICAgIlN0eWxlc2hlZXQtWmllbCBcInswfVwiIGtvbm50ZSBuaWNodCBnZWZ1bmRlbiB3ZXJkZW4uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIGFjY2VzcyB0byB0aGUgc3R5bGVzaGVldCB0YXJnZXQgaXMgZGVuaWVkCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuQUNDRVNTSU5HX1hTTFRfVEFSR0VUX0VSUiwKLSAgICAgICAgIlN0eWxlc2hlZXQtWmllbCBcInswfVwiIGtvbm50ZSBuaWNodCBnZWxlc2VuIHdlcmRlbiwgd2VpbCBkZXIgXCJ7MX1cIi1adWdyaWZmIHdlZ2VuIGVpbmVyIHZvbiBkZXIgRWlnZW5zY2hhZnQgYWNjZXNzRXh0ZXJuYWxTdHlsZXNoZWV0IGZlc3RnZWxlZ3RlbiBFaW5zY2hyXHUwMEU0bmt1bmcgbmljaHQgenVsXHUwMEU0c3NpZyBpc3QuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSByZXByZXNlbnRzIGFuIGludGVybmFsIGVycm9yIGluCi0gICAgICAgICAqIGNvbmRpdGlvbiBpbiBYU0xUQy4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgY2xhc3MgbmFtZSBpbiBYU0xUQwotICAgICAgICAgKiB0aGF0IGlzIG1pc3Npbmcgc29tZSBmdW5jdGlvbmFsaXR5LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk5PVF9JTVBMRU1FTlRFRF9FUlIsCi0gICAgICAgICJOaWNodCBpbXBsZW1lbnRpZXJ0OiBcInswfVwiLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgWE1MIGRvY3VtZW50IGdpdmVuIHRvIFhTTFRDIGFzIGEgc3R5bGVzaGVldAotICAgICAgICAgKiB3YXMgbm90LCBpbiBmYWN0LCBhIHN0eWxlc2hlZXQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTk9UX1NUWUxFU0hFRVRfRVJSLAotICAgICAgICAiRGFzIEVpbmdhYmVkb2t1bWVudCBlbnRoXHUwMEU0bHQga2VpbiBYU0wtU3R5bGVzaGVldC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGVsZW1lbnQgbmFtZWQgaW4gdGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHdhcwotICAgICAgICAgKiBlbmNvdW50ZXJlZCBpbiB0aGUgc3R5bGVzaGVldCBidXQgaXMgbm90IHJlY29nbml6ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuRUxFTUVOVF9QQVJTRV9FUlIsCi0gICAgICAgICJFbGVtZW50IFwiezB9XCIga29ubnRlIG5pY2h0IGdlcGFyc3Qgd2VyZGVuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJ1c2UiLCAiPGtleT4iLCAibm9kZSIsICJub2RlLXNldCIsICJzdHJpbmciCi0gICAgICAgICAqIGFuZCAibnVtYmVyIiBhcmUga2V5d29yZHMgaW4gdGhpcyBjb250ZXh0IGFuZCBzaG91bGQgbm90IGJlCi0gICAgICAgICAqIHRyYW5zbGF0ZWQuICBUaGlzIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhlIHZhbHVlIG9mIHRoZSAidXNlIgotICAgICAgICAgKiBhdHRyaWJ1dGUgd2FzIG5vdCBvbmUgb2YgdGhlIHBlcm1pdHRlZCB2YWx1ZXMuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuS0VZX1VTRV9BVFRSX0VSUiwKLSAgICAgICAgIkRhcyBcInVzZVwiLUF0dHJpYnV0IHZvbiA8a2V5PiBtdXNzIFwibm9kZVwiLCBcIm5vZGUtc2V0XCIsIFwic3RyaW5nXCIgb2RlciBcIm51bWJlclwiIHNlaW4uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIFhNTCBkb2N1bWVudCBjYW4gc3BlY2lmeSB0aGUgdmVyc2lvbiBvZiB0aGUKLSAgICAgICAgICogWE1MIHNwZWNpZmljYXRpb24gdG8gd2hpY2ggaXQgYWRoZXJlcy4gIFRoaXMgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdAotICAgICAgICAgKiB0aGUgdmVyc2lvbiBzcGVjaWZpZWQgZm9yIHRoZSBvdXRwdXQgZG9jdW1lbnQgd2FzIG5vdCB2YWxpZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5PVVRQVVRfVkVSU0lPTl9FUlIsCi0gICAgICAgICJBdXNnYWJlLVhNTC1Eb2t1bWVudHZlcnNpb24gbXVzcyAxLjAgc2VpbiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgb3BlcmF0b3IgaW4gYSBjb21wYXJpc29uIG9wZXJhdGlvbiB3YXMKLSAgICAgICAgICogbm90IHJlY29nbml6ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSUxMRUdBTF9SRUxBVF9PUF9FUlIsCi0gICAgICAgICJVbmJla2FubnRlciBPcGVyYXRvciBmXHUwMEZDciBWZXJnbGVpY2hzYXVzZHJ1Y2sifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQW4gYXR0cmlidXRlIHNldCBkZWZpbmVzIGFzIGEgc2V0IG9mIFhNTAotICAgICAgICAgKiBhdHRyaWJ1dGVzIHRoYXQgY2FuIGJlIGFkZGVkIHRvIGFuIGVsZW1lbnQgaW4gdGhlIG91dHB1dCBYTUwgZG9jdW1lbnQKLSAgICAgICAgICogYXMgYSBncm91cC4gIFRoaXMgbWVzc2FnZSBpcyByZXBvcnRlZCBpZiB0aGUgbmFtZSBzcGVjaWZpZWQgd2FzIG5vdAotICAgICAgICAgKiB1c2VkIHRvIGRlY2xhcmUgYW4gYXR0cmlidXRlIHNldC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZQotICAgICAgICAgKiB0aGF0IGlzIGluIGVycm9yLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkFUVFJJQlNFVF9VTkRFRl9FUlIsCi0gICAgICAgICJWZXJzdWNoLCBuaWNodCB2b3JoYW5kZW5lIEF0dHJpYnV0Z3J1cHBlIFwiezB9XCIgenUgdmVyd2VuZGVuLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgdGVybSAiYXR0cmlidXRlIHZhbHVlIHRlbXBsYXRlIiBpcyBhIHRlcm0KLSAgICAgICAgICogZGVmaW5lZCBieSBYU0xUIHdoaWNoIGRlc2NyaWJlcyB0aGUgdmFsdWUgb2YgYW4gYXR0cmlidXRlIHRoYXQgaXMKLSAgICAgICAgICogZGV0ZXJtaW5lZCBieSBhbiBYUGF0aCBleHByZXNzaW9uLiAgVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhlCi0gICAgICAgICAqIGV4cHJlc3Npb24gd2FzIHN5bnRhY3RpY2FsbHkgaW5jb3JyZWN0OyB0aGUgc3Vic3RpdHV0aW9uIHRleHQKLSAgICAgICAgICogY29udGFpbnMgdGhlIGV4cHJlc3Npb24gdGhhdCB3YXMgaW4gZXJyb3IuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuQVRUUl9WQUxfVEVNUExBVEVfRVJSLAotICAgICAgICAiQXR0cmlidXR3ZXJ0dm9ybGFnZSBcInswfVwiIGthbm4gbmljaHQgZ2VwYXJzdCB3ZXJkZW4uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogID8/PwotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlVOS05PV05fU0lHX1RZUEVfRVJSLAotICAgICAgICAiVW5iZWthbm50ZXIgRGF0ZW50eXAgaW4gU2lnbmF0dXIgZlx1MDBGQ3IgS2xhc3NlIFwiezB9XCIuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCByZWZlcnMgdG8gZGF0YSB0eXBlcy4KLSAgICAgICAgICogVGhlIG1lc3NhZ2UgaXMgZGlzcGxheWVkIGlmIGEgdmFsdWUgaW4gYSBwYXJ0aWN1bGFyIGNvbnRleHQgbmVlZHMgdG8KLSAgICAgICAgICogYmUgY29udmVydGVkIHRvIHR5cGUgezF9LCBidXQgdGhhdCdzIG5vdCBwb3NzaWJsZSBmb3IgYSB2YWx1ZSBvZgotICAgICAgICAgKiB0eXBlIHswfS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5EQVRBX0NPTlZFUlNJT05fRVJSLAotICAgICAgICAiRGF0ZW50eXAgXCJ7MH1cIiBrYW5uIG5pY2h0IGluIFwiezF9XCIga29udmVydGllcnQgd2VyZGVuLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiVGVtcGxhdGVzIiBpcyBhIEphdmEgY2xhc3MgbmFtZSB0aGF0IHNob3VsZAotICAgICAgICAgKiBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5OT19UUkFOU0xFVF9DTEFTU19FUlIsCi0gICAgICAgICJEaWVzZXMgXCJUZW1wbGF0ZXNcIiBlbnRoXHUwMEU0bHQga2VpbmUgZ1x1MDBGQ2x0aWdlIFRyYW5zbGV0LUtsYXNzZW5kZWZpbml0aW9uLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiVGVtcGxhdGVzIiBpcyBhIEphdmEgY2xhc3MgbmFtZSB0aGF0IHNob3VsZAotICAgICAgICAgKiBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5OT19NQUlOX1RSQU5TTEVUX0VSUiwKLSAgICAgICAgIkRpZXNlcyBcIlRlbXBsYXRlc1wiIGVudGhcdTAwRTRsdCBrZWluZSBLbGFzc2UgbWl0IGRlbSBOYW1lbiBcInswfVwiLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYSBjbGFzcy4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5UUkFOU0xFVF9DTEFTU19FUlIsCi0gICAgICAgICJUcmFuc2xldC1LbGFzc2UgXCJ7MH1cIiBrb25udGUgbmljaHQgZ2VsYWRlbiB3ZXJkZW4uIn0sCi0KLSAgICAgICAge0Vycm9yTXNnLlRSQU5TTEVUX09CSkVDVF9FUlIsCi0gICAgICAgICJUcmFuc2xldC1LbGFzc2UgZ2VsYWRlbiwgVHJhbnNsZXQtSW5zdGFueiBrYW5uIGFiZXIgbmljaHQgZXJzdGVsbHQgd2VyZGVuLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiRXJyb3JMaXN0ZW5lciIgaXMgYSBKYXZhIGludGVyZmFjZSBuYW1lIHRoYXQKLSAgICAgICAgICogc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhlIHVzZXIgdHJpZWQKLSAgICAgICAgICogdG8gc2V0IGFuIEVycm9yTGlzdGVuZXIgb2JqZWN0IG9uIG9iamVjdCBvZiB0aGUgY2xhc3MgbmFtZWQgaW4gdGhlCi0gICAgICAgICAqIHN1YnN0aXR1dGlvbiB0ZXh0IHdpdGggIm51bGwiIEphdmEgdmFsdWUuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuRVJST1JfTElTVEVORVJfTlVMTF9FUlIsCi0gICAgICAgICJWZXJzdWNoLCBFcnJvckxpc3RlbmVyIGZcdTAwRkNyIFwiezB9XCIgYXVmIG51bGwgenUgc2V0emVuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFN0cmVhbVNvdXJjZSwgU0FYU291cmNlIGFuZCBET01Tb3VyY2UgYXJlIEphdmEKLSAgICAgICAgICogaW50ZXJmYWNlIG5hbWVzIHRoYXQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfVU5LTk9XTl9TT1VSQ0VfRVJSLAotICAgICAgICAiTnVyIFN0cmVhbVNvdXJjZSwgU0FYU291cmNlIHVuZCBET01Tb3VyY2Ugd2VyZGVuIHZvbiBYU0xUQyB1bnRlcnN0XHUwMEZDdHp0In0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJTb3VyY2UiIGlzIGEgSmF2YSBjbGFzcyBuYW1lIHRoYXQgc2hvdWxkIG5vdAotICAgICAgICAgKiBiZSB0cmFuc2xhdGVkLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIEphdmEgbWV0aG9kLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfTk9fU09VUkNFX0VSUiwKLSAgICAgICAgIkFuIFwiezB9XCIgXHUwMEZDYmVyZ2ViZW5lcyBTb3VyY2UtT2JqZWt0IGhhdCBrZWluZW4gSW5oYWx0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCBYU0xUQyBmYWlsZWQgdG8KLSAgICAgICAgICogY29tcGlsZSB0aGUgc3R5bGVzaGVldCBpbnRvIGEgdHJhbnNsZXQgKGNsYXNzIGZpbGUpLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfQ09NUElMRV9FUlIsCi0gICAgICAgICJTdHlsZXNoZWV0IGtvbm50ZSBuaWNodCBrb21waWxpZXJ0IHdlcmRlbiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiVHJhbnNmb3JtZXJGYWN0b3J5IiBpcyBhIGNsYXNzIG5hbWUuICBJbiB0aGlzCi0gICAgICAgICAqIGNvbnRleHQsIGFuIGF0dHJpYnV0ZSBpcyBhIHByb3BlcnR5IG9yIHNldHRpbmcgb2YgdGhlCi0gICAgICAgICAqIFRyYW5zZm9ybWVyRmFjdG9yeSBvYmplY3QuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgdGhlCi0gICAgICAgICAqIHVucmVjb2duaXNlZCBhdHRyaWJ1dGUuICBUaGUgbWV0aG9kIHVzZWQgdG8gcmV0cmlldmUgdGhlIGF0dHJpYnV0ZSBpcwotICAgICAgICAgKiAiZ2V0QXR0cmlidXRlIiwgc28gaXQncyBub3QgY2xlYXIgd2hldGhlciBpdCB3b3VsZCBiZSBiZXN0IHRvCi0gICAgICAgICAqIHRyYW5zbGF0ZSB0aGUgdGVybSAiYXR0cmlidXRlIi4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX0lOVkFMSURfQVRUUl9FUlIsCi0gICAgICAgICJUcmFuc2Zvcm1lckZhY3RvcnkgZXJrZW5udCBBdHRyaWJ1dCBcInswfVwiIG5pY2h0LiJ9LAotCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX0lOVkFMSURfQVRUUl9WQUxVRV9FUlIsCi0gICAgICAgICJGYWxzY2hlciBXZXJ0IGZcdTAwRkNyIEF0dHJpYnV0IFwiezB9XCIgYW5nZWdlYmVuLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAic2V0UmVzdWx0KCkiIGFuZCAic3RhcnREb2N1bWVudCgpIiBhcmUgSmF2YQotICAgICAgICAgKiBtZXRob2QgbmFtZXMgdGhhdCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSkFYUF9TRVRfUkVTVUxUX0VSUiwKLSAgICAgICAgInNldFJlc3VsdCgpIG11c3Mgdm9yIHN0YXJ0RG9jdW1lbnQoKSBhdWZnZXJ1ZmVuIHdlcmRlbi4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIlRyYW5zZm9ybWVyIiBpcyBhIEphdmEgaW50ZXJmYWNlIG5hbWUgdGhhdAotICAgICAgICAgKiBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBBIFRyYW5zZm9ybWVyIG9iamVjdCBzaG91bGQgY29udGFpbmVkIGEKLSAgICAgICAgICogcmVmZXJlbmNlIHRvIGEgdHJhbnNsZXQgb2JqZWN0IGluIG9yZGVyIHRvIGJlIHVzZWQgZm9yCi0gICAgICAgICAqIHRyYW5zZm9ybWF0aW9uczsgdGhpcyBtZXNzYWdlIGlzIHByb2R1Y2VkIGlmIHRoYXQgcmVxdWlyZW1lbnQgaXMgbm90Ci0gICAgICAgICAqIG1ldC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX05PX1RSQU5TTEVUX0VSUiwKLSAgICAgICAgIkRlciBUcmFuc2Zvcm1lciBoYXQga2VpbiBnZWthcHNlbHRlcyBUcmFuc2xldC1PYmpla3QuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBYTUwgZG9jdW1lbnQgdGhhdCByZXN1bHRzIGZyb20gYQotICAgICAgICAgKiB0cmFuc2Zvcm1hdGlvbiBuZWVkcyB0byBiZSBzZW50IHRvIGFuIG91dHB1dCBoYW5kbGVyIG9iamVjdDsgdGhpcwotICAgICAgICAgKiBtZXNzYWdlIGlzIHByb2R1Y2VkIGlmIHRoYXQgcmVxdWlyZW1lbnQgaXMgbm90IG1ldC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX05PX0hBTkRMRVJfRVJSLAotICAgICAgICAiS2VpbiBkZWZpbmllcnRlciBBdXNnYWJlLUhhbmRsZXIgZlx1MDBGQ3IgVHJhbnNmb3JtYXRpb25zZXJnZWJuaXMuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJSZXN1bHQiIGlzIGEgSmF2YSBpbnRlcmZhY2UgbmFtZSBpbiB0aGlzCi0gICAgICAgICAqIGNvbnRleHQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgYSBtZXRob2QgbmFtZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX05PX1JFU1VMVF9FUlIsCi0gICAgICAgICJBbiBcInswfVwiIFx1MDBGQ2JlcmdlYmVuZXMgUmVzdWx0LU9iamVrdCBpc3QgdW5nXHUwMEZDbHRpZy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIlRyYW5zZm9ybWVyIiBpcyBhIEphdmEgaW50ZXJmYWNlIG5hbWUuICBUaGUKLSAgICAgICAgICogdXNlcidzIHByb2dyYW0gYXR0ZW1wdGVkIHRvIGFjY2VzcyBhbiB1bnJlY29nbml6ZWQgcHJvcGVydHkgd2l0aCB0aGUKLSAgICAgICAgICogbmFtZSBzcGVjaWZpZWQgaW4gdGhlIHN1YnN0aXR1dGlvbiB0ZXh0LiAgVGhlIG1ldGhvZCB1c2VkIHRvIHJldHJpZXZlCi0gICAgICAgICAqIHRoZSBwcm9wZXJ0eSBpcyAiZ2V0T3V0cHV0UHJvcGVydHkiLCBzbyBpdCdzIG5vdCBjbGVhciB3aGV0aGVyIGl0Ci0gICAgICAgICAqIHdvdWxkIGJlIGJlc3QgdG8gdHJhbnNsYXRlIHRoZSB0ZXJtICJwcm9wZXJ0eSIuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSkFYUF9VTktOT1dOX1BST1BfRVJSLAotICAgICAgICAiVmVyc3VjaCwgYXVmIHVuZ1x1MDBGQ2x0aWdlIFRyYW5zZm9ybWVyLUVpZ2Vuc2NoYWZ0IFwiezB9XCIgenV6dWdyZWlmZW4uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFNBWDJET00gaXMgdGhlIG5hbWUgb2YgYSBKYXZhIGNsYXNzIHRoYXQgc2hvdWxkCi0gICAgICAgICAqIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhpcyBpcyBhbiBhZGFwdGVyIGluIHRoZSBzZW5zZSB0aGF0IGl0IHRha2VzIGEKLSAgICAgICAgICogRE9NIG9iamVjdCBhbmQgY29udmVydHMgaXQgdG8gc29tZXRoaW5nIHRoYXQgdXNlcyB0aGUgU0FYIEFQSS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5TQVgyRE9NX0FEQVBURVJfRVJSLAotICAgICAgICAiU0FYMkRPTS1BZGFwdGVyIFwiezB9XCIga29ubnRlIG5pY2h0IGVyc3RlbGx0IHdlcmRlbi4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIlhTTFRDU291cmNlLmJ1aWxkKCkiIGlzIGEgSmF2YSBtZXRob2QgbmFtZS4KLSAgICAgICAgICogInN5c3RlbUlkIiBpcyBhbiBYTUwgdGVybSB0aGF0IGlzIHNob3J0IGZvciAic3lzdGVtIGlkZW50aWZpY2F0aW9uIi4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5YU0xUQ19TT1VSQ0VfRVJSLAotICAgICAgICAiWFNMVENTb3VyY2UuYnVpbGQoKSBvaG5lIGZlc3RnZWxlZ3RlIHN5c3RlbUlEIGF1ZmdlcnVmZW4uIn0sCi0KLSAgICAgICAgeyBFcnJvck1zZy5FUl9SRVNVTFRfTlVMTCwKLSAgICAgICAgICAgICJFcmdlYm5pcyBkYXJmIG5pY2h0IG51bGwgc2VpbiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhlIHZhbHVlIGFyZ3VtZW50Ci0gICAgICAgICAqIG9mIHNldFBhcmFtZXRlciBtdXN0IGJlIGEgdmFsaWQgSmF2YSBPYmplY3QuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSkFYUF9JTlZBTElEX1NFVF9QQVJBTV9WQUxVRSwKLSAgICAgICAgIldlcnQgdm9uIFBhcmFtZXRlciB7MH0gbXVzcyBlaW4gZ1x1MDBGQ2x0aWdlcyBKYXZhLU9iamVrdCBzZWluIn0sCi0KLQotICAgICAgICB7RXJyb3JNc2cuQ09NUElMRV9TVERJTl9FUlIsCi0gICAgICAgICJEaWUgT3B0aW9uIFwiLWlcIiBtdXNzIG1pdCBkZXIgT3B0aW9uIFwiLW9cIiB2ZXJ3ZW5kZXQgd2VyZGVuLiJ9LAotCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBjb250YWlucyB1c2FnZSBpbmZvcm1hdGlvbiBmb3IgYQotICAgICAgICAgKiBtZWFucyBvZiBpbnZva2luZyBYU0xUQyBmcm9tIHRoZSBjb21tYW5kLWxpbmUuICBUaGUgbWVzc2FnZSBpcwotICAgICAgICAgKiBmb3JtYXR0ZWQgZm9yIHByZXNlbnRhdGlvbiBpbiBFbmdsaXNoLiAgVGhlIHN0cmluZ3MgPG91dHB1dD4sCi0gICAgICAgICAqIDxkaXJlY3Rvcnk+LCBldGMuIGluZGljYXRlIHVzZXItc3BlY2lmaWVkIGFyZ3VtZW50IHZhbHVlcywgYW5kIGNhbgotICAgICAgICAgKiBiZSB0cmFuc2xhdGVkIC0gdGhlIGFyZ3VtZW50IDxwYWNrYWdlPiByZWZlcnMgdG8gYSBKYXZhIHBhY2thZ2UsIHNvCi0gICAgICAgICAqIGl0IHNob3VsZCBiZSBoYW5kbGVkIGluIHRoZSBzYW1lIHdheSB0aGUgdGVybSBpcyBoYW5kbGVkIGZvciBKREsKLSAgICAgICAgICogZG9jdW1lbnRhdGlvbi4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5DT01QSUxFX1VTQUdFX1NUUiwKLSAgICAgICAgIlNZTk9QU0lTXG4gICBqYXZhIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jbWRsaW5lLkNvbXBpbGUgWy1vIDxBdXNnYWJlPl1cbiAgICAgIFstZCA8VmVyemVpY2huaXM+XSBbLWogPEpBUi1EYXRlaT5dIFstcCA8UGFja2FnZT5dXG4gICAgICBbLW5dIFsteF0gWy11XSBbLXZdIFstaF0geyA8U3R5bGVzaGVldD4gfCAtaSB9XG5cbk9QVElPTlNcbiAgIC1vIDxBdXNnYWJlPiAgICB3ZWlzdCBkZW4gTmFtZW4gPEF1c2dhYmU+IGRlbSBnZW5lcmllcnRlblxuICAgICAgICAgICAgICAgICAgVHJhbnNsZXQgenUuIFN0YW5kYXJkbVx1MDBFNFx1MDBERmlnIHdpcmQgZGVyIFRyYW5zbGV0LU5hbWVcbiAgICAgICAgICAgICAgICAgIHZvbSA8U3R5bGVzaGVldD4tTmFtZW4gYWJnZWxlaXRldC4gRGllc2UgT3B0aW9uXG4gICAgICAgICAgICAgICAgICB3aXJkIGlnbm9yaWVydCwgd2VubiBtZWhyZXJlIFN0eWxlc2hlZXRzIGtvbXBpbGllcnQgd2VyZGVuLlxuICAgLWQgPFZlcnplaWNobmlzPiBnaWJ0IGVpbiBaaWVsdmVyemVpY2huaXMgZlx1MDBGQ3IgZGFzIFRyYW5zbGV0IGFuXG4gICAtaiA8SkFSLURhdGVpPiAgIHZlcnBhY2t0IFRyYW5zbGV0LUtsYXNzZW4gaW4gZWluZXIgSkFSLURhdGVpIG1pdCBkZW1cbiAgICAgICAgICAgICAgICAgIGFscyA8amFyZmlsZT4gYW5nZWdlYmVuZW4gTmFtZW5cbiAgIC1wIDxwYWNrYWdlPiAgIGdpYnQgZWluIFBhY2thZ2VuYW1lbnNwclx1MDBFNGZpeCBmXHUwMEZDciBhbGxlIGdlbmVyaWVydGVuXG4gICAgICAgICAgICAgICAgICBUcmFuc2xldC1LbGFzc2VuIGFuLlxuICAgLW4gICAgICAgICAgICAgYWt0aXZpZXJ0IGRhcyBWb3JsYWdlbi1JbmxpbmluZyAoU3RhbmRhcmR2ZXJoYWx0ZW4gZHVyY2hzY2huaXR0bGljaFxuICAgICAgICAgICAgICAgICAgYmVzc2VyKS5cbiAgIC14ICAgICAgICAgICAgIHNjaGFsdGV0IGRpZSB6dXNcdTAwRTR0emxpY2hlIERlYnVnZ2luZy1NZWxkdW5nc2F1c2dhYmUgZWluXG4gICAtdSAgICAgICAgICAgICBpbnRlcnByZXRpZXJ0IDxTdHlsZXNoZWV0Pi1Bcmd1bWVudGUgYWxzIFVSTHNcbiAgIC1pICAgICAgICAgICAgIGVyendpbmd0LCBkYXNzIGRlciBDb21waWxlciBkYXMgU3R5bGVzaGVldCBhdXMgc3RkaW4gbGllc3RcbiAgIC12ICAgICAgICAgICAgIGRydWNrdCBkaWUgVmVyc2lvbiBkZXMgQ29tcGlsZXJzXG4gICAtaCAgICAgICAgICAgICBkcnVja3QgZGllc2UgVmVyd2VuZHVuZ3NhbndlaXN1bmdcbiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgY29udGFpbnMgdXNhZ2UgaW5mb3JtYXRpb24gZm9yIGEKLSAgICAgICAgICogbWVhbnMgb2YgaW52b2tpbmcgWFNMVEMgZnJvbSB0aGUgY29tbWFuZC1saW5lLiAgVGhlIG1lc3NhZ2UgaXMKLSAgICAgICAgICogZm9ybWF0dGVkIGZvciBwcmVzZW50YXRpb24gaW4gRW5nbGlzaC4gIFRoZSBzdHJpbmdzIDxqYXJmaWxlPiwKLSAgICAgICAgICogPGRvY3VtZW50PiwgZXRjLiBpbmRpY2F0ZSB1c2VyLXNwZWNpZmllZCBhcmd1bWVudCB2YWx1ZXMsIGFuZCBjYW4KLSAgICAgICAgICogYmUgdHJhbnNsYXRlZCAtIHRoZSBhcmd1bWVudCA8Y2xhc3M+IHJlZmVycyB0byBhIEphdmEgY2xhc3MsIHNvIGl0Ci0gICAgICAgICAqIHNob3VsZCBiZSBoYW5kbGVkIGluIHRoZSBzYW1lIHdheSB0aGUgdGVybSBpcyBoYW5kbGVkIGZvciBKREsKLSAgICAgICAgICogZG9jdW1lbnRhdGlvbi4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5UUkFOU0ZPUk1fVVNBR0VfU1RSLAotICAgICAgICAiU1lOT1BTSVMgXG4gICBqYXZhIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jbWRsaW5lLlRyYW5zZm9ybSBbLWogPEpBUi1EYXRlaT5dXG4gICAgICBbLXhdIFstbiA8SXRlcmF0aW9uZW4+XSB7LXUgPGRvY3VtZW50X3VybD4gfCA8RG9rdW1lbnQ+fVxuICAgICAgPEtsYXNzZT4gWzxwYXJhbTE+PTx2YWx1ZTE+IC4uLl1cblxuICAgdmVyd2VuZGV0IGRpZSBUcmFuc2xldC08S2xhc3NlPiB6dXIgVHJhbnNmb3JtYXRpb24gZWluZXMgWE1MLURva3VtZW50cywgXG4gICBkYXMgYWxzIDxEb2t1bWVudD4gYW5nZWdlYmVuIHdpcmQuIERpZSBUcmFuc2xldC08S2xhc3NlPiBiZWZpbmRldCBzaWNoIGVudHdlZGVyIGltXG4gICBDTEFTU1BBVEggZGVzIEJlbnV0emVycyBvZGVyIGluIGRlciBvcHRpb25hbCBhbmdlZ2ViZW5lbiA8SkFSLURhdGVpPi5cbk9QVElPTlNcbiAgIC1qIDxKQVItRGF0ZWk+ICAgIGdpYnQgZWluZSBKQVItRGF0ZWkgYW4sIGF1cyBkZXIgZGFzIFRyYW5zbGV0IGdlbGFkZW4gd2VyZGVuIHNvbGxcbiAgIC14ICAgICAgICAgICAgICBzY2hhbHRldCBkaWUgenVzXHUwMEU0dHpsaWNoZSBEZWJ1Z2dpbmctTWVsZHVuZ3NhdXNnYWJlIGVpblxuICAgLW4gPEl0ZXJhdGlvbmVuPiBmXHUwMEZDaHJ0IGRpZSBUcmFuc2Zvcm1hdGlvbiBzbyBvZnQgYXVzLCB3aWUgaW4gPEl0ZXJhdGlvbmVuPiBhbmdlZ2ViZW4gdW5kXG4gICAgICAgICAgICAgICAgICAgemVpZ3QgUHJvZmlsaW5mb3JtYXRpb25lbiBhblxuICAgLXUgPGRvY3VtZW50X3VybD4gZ2lidCBkYXMgWE1MLUVpbmdhYmVkb2t1bWVudCBhbHMgVVJMIGFuXG4ifSwKLQotCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICI8eHNsOnNvcnQ+IiwgIjx4c2w6Zm9yLWVhY2g+IiBhbmQKLSAgICAgICAgICogIjx4c2w6YXBwbHktdGVtcGxhdGVzPiIgYXJlIGtleXdvcmRzIHRoYXQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLgotICAgICAgICAgKiBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCBhbiB4c2w6c29ydCBlbGVtZW50IG11c3QgYmUgYSBjaGlsZCBvZgotICAgICAgICAgKiBvbmUgb2YgdGhlIG90aGVyIGtpbmRzIG9mIGVsZW1lbnRzIG1lbnRpb25lZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5TVFJBWV9TT1JUX0VSUiwKLSAgICAgICAgIjx4c2w6c29ydD4ga2FubiBudXIgaW4gPHhzbDpmb3ItZWFjaD4gb2RlciA8eHNsOmFwcGx5LXRlbXBsYXRlcz4gdmVyd2VuZGV0IHdlcmRlbi4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhlIGVuY29kaW5nCi0gICAgICAgICAqIHJlcXVlc3RlZCBmb3IgdGhlIG91dHB1dCBkb2N1bWVudCB3YXMgb24gdGhhdCByZXF1aXJlcyBzdXBwb3J0IHRoYXQKLSAgICAgICAgICogaXMgbm90IGF2YWlsYWJsZSBmcm9tIHRoZSBKYXZhIFZpcnR1YWwgTWFjaGluZSBiZWluZyB1c2VkIHRvIGV4ZWN1dGUKLSAgICAgICAgICogdGhlIHByb2dyYW0uCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVU5TVVBQT1JURURfRU5DT0RJTkcsCi0gICAgICAgICJBdXNnYWJlY29kaWVydW5nIFwiezB9XCIgd2lyZCBhdWYgZGllc2VyIEpWTSBuaWNodCB1bnRlcnN0XHUwMEZDdHp0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUgWFBhdGggZXhwcmVzc2lvbgotICAgICAgICAgKiBuYW1lZCBpbiB0aGUgc3Vic3RpdHV0aW9uIHRleHQgd2FzIG5vdCB3ZWxsIGZvcm1lZCBzeW50YWN0aWNhbGx5LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlNZTlRBWF9FUlIsCi0gICAgICAgICJTeW50YXhmZWhsZXIgaW4gXCJ7MH1cIi4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIGEgSmF2YQotICAgICAgICAgKiBjbGFzcy4gIFRoZSB0ZXJtICJjb25zdHJ1Y3RvciIgaGVyZSBpcyB0aGUgSmF2YSB0ZXJtLiAgVGhlIG1lc3NhZ2UgaXMKLSAgICAgICAgICogZGlzcGxheWVkIGlmIFhTTFRDIGNvdWxkIG5vdCBmaW5kIGEgY29uc3RydWN0b3IgZm9yIHRoZSBzcGVjaWZpZWQKLSAgICAgICAgICogY2xhc3MuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuQ09OU1RSVUNUT1JfTk9UX0ZPVU5ELAotICAgICAgICAiRXh0ZXJuZXIgQ29uc3RydWN0b3IgXCJ7MH1cIiBrYW5uIG5pY2h0IGdlZnVuZGVuIHdlcmRlbi4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgInN0YXRpYyIgaXMgdGhlIEphdmEga2V5d29yZC4gIFRoZSBzdWJzdGl0dXRpb24KLSAgICAgICAgICogdGV4dCBpcyB0aGUgbmFtZSBvZiBhIGZ1bmN0aW9uLiAgVGhlIGZpcnN0IGFyZ3VtZW50IG9mIHRoYXQgZnVuY3Rpb24KLSAgICAgICAgICogaXMgbm90IG9mIHRoZSByZXF1aXJlZCB0eXBlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk5PX0pBVkFfRlVOQ1RfVEhJU19SRUYsCi0gICAgICAgICJEYXMgZXJzdGUgQXJndW1lbnQgZlx1MDBGQ3IgZGllIG5pY2h0LVwic3RhdGljXCItSmF2YS1GdW5rdGlvbiBcInswfVwiIGlzdCBrZWluZSBnXHUwMEZDbHRpZ2UgT2JqZWt0cmVmZXJlbnouIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIFhQYXRoIGV4cHJlc3Npb24gd2FzIG5vdCBvZiB0aGUgdHlwZQotICAgICAgICAgKiByZXF1aXJlZCBpbiBhIHBhcnRpY3VsYXIgY29udGV4dC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUKLSAgICAgICAgICogZXhwcmVzc2lvbiB0aGF0IHdhcyBpbiBlcnJvci4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5UWVBFX0NIRUNLX0VSUiwKLSAgICAgICAgIkZlaGxlciBiZWltIFByXHUwMEZDZmVuIGRlcyBUeXBzIGRlcyBBdXNkcnVja3MgXCJ7MH1cIi4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQW4gWFBhdGggZXhwcmVzc2lvbiB3YXMgbm90IG9mIHRoZSB0eXBlCi0gICAgICAgICAqIHJlcXVpcmVkIGluIGEgcGFydGljdWxhciBjb250ZXh0LiAgSG93ZXZlciwgdGhlIGxvY2F0aW9uIG9mIHRoZQotICAgICAgICAgKiBwcm9ibGVtYXRpYyBleHByZXNzaW9uIGlzIHVua25vd24uCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVFlQRV9DSEVDS19VTktfTE9DX0VSUiwKLSAgICAgICAgIkZlaGxlciBiZWltIFByXHUwMEZDZmVuIGRlcyBUeXBzIGVpbmVzIEF1c2RydWNrcyBhbiBlaW5lciB1bmJla2FubnRlbiBTdGVsbGUuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBhIGNvbW1hbmQtCi0gICAgICAgICAqIGxpbmUgb3B0aW9uIHRoYXQgd2FzIG5vdCByZWNvZ25pemVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfQ01ETElORV9PUFRJT05fRVJSLAotICAgICAgICAiRGllIEJlZmVobHN6ZWlsZW5vcHRpb24gXCJ7MH1cIiBpc3QgbmljaHQgZ1x1MDBGQ2x0aWcuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBhIGNvbW1hbmQtCi0gICAgICAgICAqIGxpbmUgb3B0aW9uLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkNNRExJTkVfT1BUX01JU1NJTkdfQVJHX0VSUiwKLSAgICAgICAgIkJlaSBkZXIgQmVmZWhsc3plaWxlbm9wdGlvbiBcInswfVwiIGZlaGx0IGVpbiBlcmZvcmRlcmxpY2hlcyBBcmd1bWVudC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIHVzZWQgdG8gaW5kaWNhdGUgdGhlIHNldmVyaXR5Ci0gICAgICAgICAqIG9mIGFub3RoZXIgbWVzc2FnZS4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBjb250YWlucyB0d28gZXJyb3IKLSAgICAgICAgICogbWVzc2FnZXMuICBUaGUgc3BhY2luZyBiZWZvcmUgdGhlIHNlY29uZCBzdWJzdGl0dXRpb24gdGV4dCBpbmRlbnRzCi0gICAgICAgICAqIGl0IHRoZSBzYW1lIGFtb3VudCBhcyB0aGUgZmlyc3QgaW4gRW5nbGlzaC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5XQVJOSU5HX1BMVVNfV1JBUFBFRF9NU0csCi0gICAgICAgICJXQVJOSU5HOiAgJyd7MH0nJ1xuICAgICAgIDp7MX0ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIHVzZWQgdG8gaW5kaWNhdGUgdGhlIHNldmVyaXR5Ci0gICAgICAgICAqIG9mIGFub3RoZXIgbWVzc2FnZS4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyBhbiBlcnJvciBtZXNzYWdlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLldBUk5JTkdfTVNHLAotICAgICAgICAiV0FSTklORzogICcnezB9JycifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIHVzZWQgdG8gaW5kaWNhdGUgdGhlIHNldmVyaXR5Ci0gICAgICAgICAqIG9mIGFub3RoZXIgbWVzc2FnZS4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBjb250YWlucyB0d28gZXJyb3IKLSAgICAgICAgICogbWVzc2FnZXMuICBUaGUgc3BhY2luZyBiZWZvcmUgdGhlIHNlY29uZCBzdWJzdGl0dXRpb24gdGV4dCBpbmRlbnRzCi0gICAgICAgICAqIGl0IHRoZSBzYW1lIGFtb3VudCBhcyB0aGUgZmlyc3QgaW4gRW5nbGlzaC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5GQVRBTF9FUlJfUExVU19XUkFQUEVEX01TRywKLSAgICAgICAgIkZBVEFMIEVSUk9SOiAgJyd7MH0nJ1xuICAgICAgICAgICA6ezF9In0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyB1c2VkIHRvIGluZGljYXRlIHRoZSBzZXZlcml0eQotICAgICAgICAgKiBvZiBhbm90aGVyIG1lc3NhZ2UuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgYW4gZXJyb3IgbWVzc2FnZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5GQVRBTF9FUlJfTVNHLAotICAgICAgICAiRkFUQUwgRVJST1I6ICAnJ3swfScnIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyB1c2VkIHRvIGluZGljYXRlIHRoZSBzZXZlcml0eQotICAgICAgICAgKiBvZiBhbm90aGVyIG1lc3NhZ2UuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgY29udGFpbnMgdHdvIGVycm9yCi0gICAgICAgICAqIG1lc3NhZ2VzLiAgVGhlIHNwYWNpbmcgYmVmb3JlIHRoZSBzZWNvbmQgc3Vic3RpdHV0aW9uIHRleHQgaW5kZW50cwotICAgICAgICAgKiBpdCB0aGUgc2FtZSBhbW91bnQgYXMgdGhlIGZpcnN0IGluIEVuZ2xpc2guCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuRVJST1JfUExVU19XUkFQUEVEX01TRywKLSAgICAgICAgIkVSUk9SOiAgJyd7MH0nJ1xuICAgICA6ezF9In0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyB1c2VkIHRvIGluZGljYXRlIHRoZSBzZXZlcml0eQotICAgICAgICAgKiBvZiBhbm90aGVyIG1lc3NhZ2UuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgYW4gZXJyb3IgbWVzc2FnZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5FUlJPUl9NU0csCi0gICAgICAgICJFUlJPUjogICcnezB9JycifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIGEgY2xhc3MuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVFJBTlNGT1JNX1dJVEhfVFJBTlNMRVRfU1RSLAotICAgICAgICAiVHJhbnNmb3JtYXRpb24gbWl0IFRyYW5zbGV0IFwiezB9XCIgIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmaXJzdCBzdWJzdGl0dXRpb24gaXMgdGhlIG5hbWUgb2YgYSBjbGFzcywKLSAgICAgICAgICogd2hpbGUgdGhlIHNlY29uZCBzdWJzdGl0dXRpb24gaXMgdGhlIG5hbWUgb2YgYSBqYXIgZmlsZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5UUkFOU0ZPUk1fV0lUSF9KQVJfU1RSLAotICAgICAgICAiVHJhbnNmb3JtYXRpb24gbWl0IFRyYW5zbGV0IFwiezB9XCIgYXVzIEpBUi1EYXRlaSBcInsxfVwiIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJUcmFuc2Zvcm1lckZhY3RvcnkiIGlzIHRoZSBuYW1lIG9mIGEgSmF2YQotICAgICAgICAgKiBpbnRlcmZhY2UgYW5kIG11c3Qgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMKLSAgICAgICAgICogdGhlIG5hbWUgb2YgdGhlIGNsYXNzIHRoYXQgY291bGQgbm90IGJlIGluc3RhbnRpYXRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5DT1VMRF9OT1RfQ1JFQVRFX1RSQU5TX0ZBQ1QsCi0gICAgICAgICJFcyBrb25udGUga2VpbmUgSW5zdGFueiBkZXIgVHJhbnNmb3JtZXJGYWN0b3J5LUtsYXNzZSBcInswfVwiIGVyc3RlbGx0IHdlcmRlbi4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIHByb2R1Y2VkIHdoZW4gdGhlIHVzZXIKLSAgICAgICAgICogc3BlY2lmaWVkIGEgbmFtZSBmb3IgdGhlIHRyYW5zbGV0IGNsYXNzIHRoYXQgY29udGFpbnMgY2hhcmFjdGVycwotICAgICAgICAgKiB0aGF0IGFyZSBub3QgcGVybWl0dGVkIGluIGEgSmF2YSBjbGFzcyBuYW1lLiAgVGhlIHN1YnN0aXR1dGlvbgotICAgICAgICAgKiB0ZXh0ICJ7MH0iIHNwZWNpZmllcyB0aGUgbmFtZSB0aGUgdXNlciByZXF1ZXN0ZWQsIHdoaWxlICJ7MX0iCi0gICAgICAgICAqIHNwZWNpZmllcyB0aGUgbmFtZSB0aGUgcHJvY2Vzc29yIHVzZWQgaW5zdGVhZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5UUkFOU0xFVF9OQU1FX0pBVkFfQ09ORkxJQ1QsCi0gICAgICAgICAiRGVyIE5hbWUgXCJ7MH1cIiBrb25udGUgbmljaHQgYWxzIE5hbWUgZGVyIFRyYW5zbGV0LUtsYXNzZSB2ZXJ3ZW5kZXQgd2VyZGVuLCBkYSBlciBaZWljaGVuIGVudGhcdTAwRTRsdCwgZGllIG5pY2h0IGltIE5hbWVuIGVpbmVyIEphdmEtS2xhc3NlIHp1bFx1MDBFNHNzaWcgc2luZC4gRGVyIE5hbWUgXCJ7MX1cIiB3dXJkZSBzdGF0dGRlc3NlbiB2ZXJ3ZW5kZXQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBpcyB1c2VkIGFzIGEgaGVhZGVyLgotICAgICAgICAgKiBBbGwgdGhlIGVycm9yIG1lc3NhZ2VzIGFyZSBjb2xsZWN0ZWQgdG9nZXRoZXIgYW5kIGRpc3BsYXllZCBiZW5lYXRoCi0gICAgICAgICAqIHRoaXMgbWVzc2FnZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5DT01QSUxFUl9FUlJPUl9LRVksCi0gICAgICAgICJDb21waWxlci1GZWhsZXI6In0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBpcyB1c2VkIGFzIGEgaGVhZGVyLgotICAgICAgICAgKiBBbGwgdGhlIHdhcm5pbmcgbWVzc2FnZXMgYXJlIGNvbGxlY3RlZCB0b2dldGhlciBhbmQgZGlzcGxheWVkCi0gICAgICAgICAqIGJlbmVhdGggdGhpcyBtZXNzYWdlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkNPTVBJTEVSX1dBUk5JTkdfS0VZLAotICAgICAgICAiQ29tcGlsZXItV2FybnVuZ2VuOiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgaXMgdXNlZCBhcyBhIGhlYWRlci4KLSAgICAgICAgICogQWxsIHRoZSBlcnJvciBtZXNzYWdlcyB0aGF0IGFyZSBwcm9kdWNlZCB3aGVuIHRoZSBzdHlsZXNoZWV0IGlzCi0gICAgICAgICAqIGFwcGxpZWQgdG8gYW4gaW5wdXQgZG9jdW1lbnQgYXJlIGNvbGxlY3RlZCB0b2dldGhlciBhbmQgZGlzcGxheWVkCi0gICAgICAgICAqIGJlbmVhdGggdGhpcyBtZXNzYWdlLiAgQSAndHJhbnNsZXQnIGlzIHRoZSBjb21waWxlZCBmb3JtIG9mIGEKLSAgICAgICAgICogc3R5bGVzaGVldCAoc2VlIGFib3ZlKS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5SVU5USU1FX0VSUk9SX0tFWSwKLSAgICAgICAgIlRyYW5zbGV0LUZlaGxlcjoifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQW4gYXR0cmlidXRlIHdob3NlIHZhbHVlIGlzIGNvbnN0cmFpbmVkIHRvCi0gICAgICAgICAqIGJlIGEgIlFOYW1lIiBvciBhIGxpc3Qgb2YgIlFOYW1lcyIgaGFkIGEgdmFsdWUgdGhhdCB3YXMgaW5jb3JyZWN0LgotICAgICAgICAgKiAnUU5hbWUnIGlzIGFuIFhNTCBzeW50YWN0aWMgdGVybSB0aGF0IG11c3Qgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGUKLSAgICAgICAgICogc3Vic3RpdHV0aW9uIHRleHQgY29udGFpbnMgdGhlIGFjdHVhbCB2YWx1ZSBvZiB0aGUgYXR0cmlidXRlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklOVkFMSURfUU5BTUVfRVJSLAotICAgICAgICAiRWluIEF0dHJpYnV0LCBkZXNzZW4gV2VydCBlaW4gUU5hbWUgb2RlciBlaW5lIGR1cmNoIExlZXJzdGVsbGVuIGdldHJlbm50ZSBMaXN0ZSBtaXQgUU5hbWVzIHNlaW4gbXVzcywgaGF0dGUgZGVuIFdlcnQgXCJ7MH1cIiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBbiBhdHRyaWJ1dGUgd2hvc2UgdmFsdWUgaXMgcmVxdWlyZWQgdG8KLSAgICAgICAgICogYmUgYW4gIk5DTmFtZSIuCi0gICAgICAgICAqICdOQ05hbWUnIGlzIGFuIFhNTCBzeW50YWN0aWMgdGVybSB0aGF0IG11c3Qgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGUKLSAgICAgICAgICogc3Vic3RpdHV0aW9uIHRleHQgY29udGFpbnMgdGhlIGFjdHVhbCB2YWx1ZSBvZiB0aGUgYXR0cmlidXRlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklOVkFMSURfTkNOQU1FX0VSUiwKLSAgICAgICAgIkVpbiBBdHRyaWJ1dCwgZGVzc2VuIFdlcnQgZWluIE5DTmFtZSBzZWluIG11c3MsIGhhdHRlIGRlbiBXZXJ0IFwiezB9XCIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQW4gYXR0cmlidXRlIHdpdGggYW4gaW5jb3JyZWN0IHZhbHVlIHdhcwotICAgICAgICAgKiBlbmNvdW50ZXJlZC4gIFRoZSBwZXJtaXR0ZWQgdmFsdWUgaXMgb25lIG9mIHRoZSBsaXRlcmFsIHZhbHVlcwotICAgICAgICAgKiAieG1sIiwgImh0bWwiIG9yICJ0ZXh0IjsgaXQgaXMgYWxzbyBwZXJtaXR0ZWQgdG8gaGF2ZSB0aGUgZm9ybSBvZgotICAgICAgICAgKiBhIFFOYW1lIHRoYXQgaXMgbm90IGFsc28gYW4gTkNOYW1lLiAgVGhlIHRlcm1zICJtZXRob2QiLAotICAgICAgICAgKiAieHNsOm91dHB1dCIsICJ4bWwiLCAiaHRtbCIgYW5kICJ0ZXh0IiBhcmUga2V5d29yZHMgdGhhdCBtdXN0IG5vdAotICAgICAgICAgKiBiZSB0cmFuc2xhdGVkLiAgVGhlIHRlcm0gInFuYW1lLWJ1dC1ub3QtbmNuYW1lIiBpcyBhbiBYTUwgc3ludGFjdGljCi0gICAgICAgICAqIHRlcm0uICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgY29udGFpbnMgdGhlIGFjdHVhbCB2YWx1ZSBvZiB0aGUKLSAgICAgICAgICogYXR0cmlidXRlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklOVkFMSURfTUVUSE9EX0lOX09VVFBVVCwKLSAgICAgICAgIkRhcyBcIm1ldGhvZFwiLUF0dHJpYnV0IGVpbmVzIDx4c2w6b3V0cHV0Pi1FbGVtZW50cyBoYXR0ZSBkZW4gV2VydCBcInswfVwiLiBEZXIgV2VydCBtdXNzIFwieG1sXCIsIFwiaHRtbFwiLCBcInRleHRcIiBvZGVyIHFuYW1lLWJ1dC1ub3QtbmNuYW1lIHNlaW4ifSwKLQotICAgICAgICB7RXJyb3JNc2cuSkFYUF9HRVRfRkVBVFVSRV9OVUxMX05BTUUsCi0gICAgICAgICJEZXIgRmVhdHVyZW5hbWUgZGFyZiBuaWNodCBudWxsIGluIFRyYW5zZm9ybWVyRmFjdG9yeS5nZXRGZWF0dXJlKFplaWNoZW5mb2xnZW5uYW1lKSBzZWluLiJ9LAotCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX1NFVF9GRUFUVVJFX05VTExfTkFNRSwKLSAgICAgICAgIkRlciBGZWF0dXJlbmFtZSBkYXJmIG5pY2h0IG51bGwgaW4gVHJhbnNmb3JtZXJGYWN0b3J5LnNldEZlYXR1cmUoWmVpY2hlbmZvbGdlbm5hbWUsIGJvb2xlc2NoZXIgV2VydCkgc2Vpbi4ifSwKLQotICAgICAgICB7RXJyb3JNc2cuSkFYUF9VTlNVUFBPUlRFRF9GRUFUVVJFLAotICAgICAgICAiRGFzIEZlYXR1cmUgXCJ7MH1cIiBrYW5uIG5pY2h0IGZcdTAwRkNyIGRpZXNlIFRyYW5zZm9ybWVyRmFjdG9yeSBmZXN0Z2VsZWd0IHdlcmRlbi4ifSwKLQotICAgICAgICB7RXJyb3JNc2cuSkFYUF9TRUNVUkVQUk9DRVNTSU5HX0ZFQVRVUkUsCi0gICAgICAgICJGRUFUVVJFX1NFQ1VSRV9QUk9DRVNTSU5HOiBGZWF0dXJlIGthbm4gbmljaHQgYXVmIFwiZmFsc2VcIiBnZXNldHp0IHdlcmRlbiwgd2VubiBTZWN1cml0eSBNYW5hZ2VyIHZvcmhhbmRlbiBpc3QuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBkZXNjcmliZXMgYW4gaW50ZXJuYWwgZXJyb3IgaW4gdGhlCi0gICAgICAgICAqIHByb2Nlc3Nvci4gIFRoZSB0ZXJtICJieXRlIGNvZGUiIGlzIGEgSmF2YSB0ZWNobmljYWwgdGVybSBmb3IgdGhlCi0gICAgICAgICAqIGV4ZWN1dGFibGUgY29kZSBpbiBhIEphdmEgbWV0aG9kLCBhbmQgInRyeS1jYXRjaC1maW5hbGx5IGJsb2NrIgotICAgICAgICAgKiByZWZlcnMgdG8gdGhlIEphdmEga2V5d29yZHMgd2l0aCB0aG9zZSBuYW1lcy4gICJPdXRsaW5lZCIgaXMgYQotICAgICAgICAgKiB0ZWNobmljYWwgdGVybSBpbnRlcm5hbCB0byBYU0xUQyBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk9VVExJTkVfRVJSX1RSWV9DQVRDSCwKLSAgICAgICAgICJJbnRlcm5lciBYU0xUQy1GZWhsZXI6IERlciBnZW5lcmllcnRlIEJ5dGVjb2RlIGVudGhcdTAwRTRsdCBlaW5lbiBUcnktQ2F0Y2gtRmluYWxseS1CbG9jay4gT3V0bGluZSBuaWNodCBtXHUwMEY2Z2xpY2guIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBkZXNjcmliZXMgYW4gaW50ZXJuYWwgZXJyb3IgaW4gdGhlCi0gICAgICAgICAqIHByb2Nlc3Nvci4gIFRoZSB0ZXJtcyAiT3V0bGluZWFibGVDaHVua1N0YXJ0IiBhbmQKLSAgICAgICAgICogIk91dGxpbmVhYmxlQ2h1bmtFbmQiIGFyZSB0aGUgbmFtZXMgb2YgY2xhc3NlcyBpbnRlcm5hbCB0byBYU0xUQyBhbmQKLSAgICAgICAgICogc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgZm9yIGV2ZXJ5Ci0gICAgICAgICAqICJzdGFydCIgdGhlcmUgbXVzdCBiZSBhIGNvcnJlc3BvbmRpbmcgImVuZCIsIGFuZCB2aWNlIHZlcnNhLCBhbmQKLSAgICAgICAgICogdGhhdCBpZiBvbmUgb2YgYSBwYWlyIG9mICJzdGFydCIgYW5kICJlbmQiIGFwcGVhcnMgYmV0d2VlbiBhbm90aGVyCi0gICAgICAgICAqIHBhaXIgb2YgY29ycmVzcG9uZGluZyAic3RhcnQiIGFuZCAiZW5kIiwgdGhlbiB0aGUgb3RoZXIgaGFsZiBvZiB0aGUKLSAgICAgICAgICogcGFpciBtdXN0IGFsc28gYmUgYmV0d2VlbiB0aGF0IHNhbWUgZW5jbG9zaW5nIHBhaXIuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuT1VUTElORV9FUlJfVU5CQUxBTkNFRF9NQVJLRVJTLAotICAgICAgICAgIkludGVybmVyIFhTTFRDLUZlaGxlcjogRGllIE1hcmtlciBPdXRsaW5lYWJsZUNodW5rU3RhcnQgdW5kIE91dGxpbmVhYmxlQ2h1bmtFbmQgbVx1MDBGQ3NzZW4gYXVzZ2VnbGljaGVuIHVuZCBvcmRudW5nc2dlbVx1MDBFNFx1MDBERiBwbGF0emllcnQgc2Vpbi4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGRlc2NyaWJlcyBhbiBpbnRlcm5hbCBlcnJvciBpbiB0aGUKLSAgICAgICAgICogcHJvY2Vzc29yLiAgVGhlIHRlcm0gImJ5dGUgY29kZSIgaXMgYSBKYXZhIHRlY2huaWNhbCB0ZXJtIGZvciB0aGUKLSAgICAgICAgICogZXhlY3V0YWJsZSBjb2RlIGluIGEgSmF2YSBtZXRob2QuICBUaGUgIm1ldGhvZCIgdGhhdCBpcyBiZWluZwotICAgICAgICAgKiByZWZlcnJlZCB0byBpcyBhIEphdmEgbWV0aG9kIGluIGEgdHJhbnNsZXQgdGhhdCBYU0xUQyBpcyBnZW5lcmF0aW5nCi0gICAgICAgICAqIGluIHByb2Nlc3NpbmcgYSBzdHlsZXNoZWV0LiAgVGhlICJpbnN0cnVjdGlvbiIgdGhhdCBpcyBiZWluZwotICAgICAgICAgKiByZWZlcnJlZCB0byBpcyBvbmUgb2YgdGhlIGluc3RydXRpb25zIGluIHRoZSBKYXZhIGJ5dGUgY29kZSBpbiB0aGF0Ci0gICAgICAgICAqIG1ldGhvZC4gICJPdXRsaW5lZCIgaXMgYSB0ZWNobmljYWwgdGVybSBpbnRlcm5hbCB0byBYU0xUQyBhbmQKLSAgICAgICAgICogc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk9VVExJTkVfRVJSX0RFTEVURURfVEFSR0VULAotICAgICAgICAgIkludGVybmVyIFhTTFRDLUZlaGxlcjogRWluZSBBbndlaXN1bmcsIGRpZSBUZWlsIGVpbmVzIEJ5dGVjb2RlYmxvY2tzIHdhciwgZlx1MDBGQ3IgZGVuIGVpbiBPdXRsaW5lIGVyc3RlbGx0IHd1cmRlLCB3aXJkIG5hY2ggd2llIHZvciBpbiBkZXIgT3JpZ2luYWxtZXRob2RlIHJlZmVyZW56aWVydC4iCi0gICAgICAgIH0sCi0KLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGRlc2NyaWJlcyBhbiBpbnRlcm5hbCBlcnJvciBpbiB0aGUKLSAgICAgICAgICogcHJvY2Vzc29yLiAgVGhlICJtZXRob2QiIHRoYXQgaXMgYmVpbmcgcmVmZXJyZWQgdG8gaXMgYSBKYXZhIG1ldGhvZAotICAgICAgICAgKiBpbiBhIHRyYW5zbGV0IHRoYXQgWFNMVEMgaXMgZ2VuZXJhdGluZy4KLSAgICAgICAgICoKLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5PVVRMSU5FX0VSUl9NRVRIT0RfVE9PX0JJRywKLSAgICAgICAgICJJbnRlcm5lciBYU0xUQy1GZWhsZXI6IEVpbmUgTWV0aG9kZSBpbSBUcmFuc2xldCBcdTAwRkNiZXJzY2hyZWl0ZXQgZGllIEphdmEgVmlydHVhbCBNYWNoaW5lLUxcdTAwRTRuZ2VuZWluc2Noclx1MDBFNG5rdW5nIGVpbmVyIE1ldGhvZGUgdm9uIDY0IEtCLiBVcnNhY2hlIGhpZXJmXHUwMEZDciBzaW5kIGluIGRlciBSZWdlbCBzZWhyIGdyb1x1MDBERmUgVm9ybGFnZW4gaW4gZWluZW0gU3R5bGVzaGVldC4gVmVyc3VjaGVuIFNpZSwgZGFzIFN0eWxlc2hlZXQgbWl0IGtsZWluZXJlbiBWb3JsYWdlbiB1bXp1c3RydWt0dXJpZXJlbi4iCi0gICAgICAgIH0sCi0KLSAgICAgICAgIHtFcnJvck1zZy5ERVNFUklBTElaRV9UUkFOU0xFVF9FUlIsICJXZW5uIGRpZSBKYXZhLVNpY2hlcmhlaXQgYWt0aXZpZXJ0IGlzdCwgaXN0IGRpZSBVbnRlcnN0XHUwMEZDdHp1bmcgZlx1MDBGQ3IgZGFzIERlc2VyaWFsaXNpZXJlbiB2b24gVGVtcGxhdGVzSW1wbCBkZWFrdGl2aWVydC4gRGllcyBrYW5uIGR1cmNoIFNldHplbiBkZXIgU3lzdGVtZWlnZW5zY2hhZnQgamRrLnhtbC5lbmFibGVUZW1wbGF0ZXNJbXBsRGVzZXJpYWxpemF0aW9uIGF1ZiBcIlRydWVcIiBhdVx1MDBERmVyIEtyYWZ0IGdlc2V0enQgd2VyZGVuLiJ9Ci0KLSAgICB9OwotCi0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci91dGlsL0Vycm9yTWVzc2FnZXNfZXMuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvdXRpbC9FcnJvck1lc3NhZ2VzX2VzLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDdiNmQxYjQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci91dGlsL0Vycm9yTWVzc2FnZXNfZXMuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDk3NCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWw7Ci0KLWltcG9ydCBqYXZhLnV0aWwuTGlzdFJlc291cmNlQnVuZGxlOwotCi0vKioKLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICovCi1wdWJsaWMgY2xhc3MgRXJyb3JNZXNzYWdlc19lcyBleHRlbmRzIExpc3RSZXNvdXJjZUJ1bmRsZSB7Ci0KLS8qCi0gKiBYU0xUQyBjb21waWxlLXRpbWUgZXJyb3IgbWVzc2FnZXMuCi0gKgotICogR2VuZXJhbCBub3RlcyB0byB0cmFuc2xhdG9ycyBhbmQgZGVmaW5pdGlvbnM6Ci0gKgotICogICAxKSBYU0xUQyBpcyB0aGUgbmFtZSBvZiB0aGUgcHJvZHVjdC4gIEl0IGlzIGFuIGFjcm9ueW0gZm9yICJYU0xUIENvbXBpbGVyIi4KLSAqICAgICAgWFNMVCBpcyBhbiBhY3JvbnltIGZvciAiWE1MIFN0eWxlc2hlZXQgTGFuZ3VhZ2U6IFRyYW5zZm9ybWF0aW9ucyIuCi0gKgotICogICAyKSBBIHN0eWxlc2hlZXQgaXMgYSBkZXNjcmlwdGlvbiBvZiBob3cgdG8gdHJhbnNmb3JtIGFuIGlucHV0IFhNTCBkb2N1bWVudAotICogICAgICBpbnRvIGEgcmVzdWx0YW50IFhNTCBkb2N1bWVudCAob3IgSFRNTCBkb2N1bWVudCBvciB0ZXh0KS4gIFRoZQotICogICAgICBzdHlsZXNoZWV0IGl0c2VsZiBpcyBkZXNjcmliZWQgaW4gdGhlIGZvcm0gb2YgYW4gWE1MIGRvY3VtZW50LgotICoKLSAqICAgMykgQSB0ZW1wbGF0ZSBpcyBhIGNvbXBvbmVudCBvZiBhIHN0eWxlc2hlZXQgdGhhdCBpcyB1c2VkIHRvIG1hdGNoIGEKLSAqICAgICAgcGFydGljdWxhciBwb3J0aW9uIG9mIGFuIGlucHV0IGRvY3VtZW50IGFuZCBzcGVjaWZpZXMgdGhlIGZvcm0gb2YgdGhlCi0gKiAgICAgIGNvcnJlc3BvbmRpbmcgcG9ydGlvbiBvZiB0aGUgb3V0cHV0IGRvY3VtZW50LgotICoKLSAqICAgNCkgQW4gYXhpcyBpcyBhIHBhcnRpY3VsYXIgImRpbWVuc2lvbiIgaW4gYSB0cmVlIHJlcHJlc2VudGF0aW9uIG9mIGFuIFhNTAotICogICAgICBkb2N1bWVudDsgdGhlIG5vZGVzIGluIHRoZSB0cmVlIGFyZSBkaXZpZGVkIGFsb25nIGRpZmZlcmVudCBheGVzLgotICogICAgICBUcmF2ZXJzaW5nIHRoZSAiY2hpbGQiIGF4aXMsIGZvciBpbnN0YW5jZSwgbWVhbnMgdGhhdCB0aGUgcHJvZ3JhbQotICogICAgICB3b3VsZCB2aXNpdCBlYWNoIGNoaWxkIG9mIGEgcGFydGljdWxhciBub2RlOyB0cmF2ZXJzaW5nIHRoZSAiZGVzY2VuZGFudCIKLSAqICAgICAgYXhpcyBtZWFucyB0aGF0IHRoZSBwcm9ncmFtIHdvdWxkIHZpc2l0IHRoZSBjaGlsZCBub2RlcyBvZiBhIHBhcnRpY3VsYXIKLSAqICAgICAgbm9kZSwgdGhlaXIgY2hpbGRyZW4sIGFuZCBzbyBvbiB1bnRpbCB0aGUgbGVhZiBub2RlcyBvZiB0aGUgdHJlZSBhcmUKLSAqICAgICAgcmVhY2hlZC4KLSAqCi0gKiAgIDUpIEFuIGl0ZXJhdG9yIGlzIGFuIG9iamVjdCB0aGF0IHRyYXZlcnNlcyBub2RlcyBpbiBhIHRyZWUgYWxvbmcgYQotICogICAgICBwYXJ0aWN1bGFyIGF4aXMsIG9uZSBhdCBhIHRpbWUuCi0gKgotICogICA2KSBBbiBlbGVtZW50IGlzIGEgbWFyay11cCB0YWcgaW4gYW4gWE1MIGRvY3VtZW50OyBhbiBhdHRyaWJ1dGUgaXMgYQotICogICAgICBtb2RpZmllciBvbiB0aGUgdGFnLiAgRm9yIGV4YW1wbGUsIGluIDxlbGVtIGF0dHI9J3ZhbCcgYXR0cjI9J3ZhbDInPgotICogICAgICAiZWxlbSIgaXMgYW4gZWxlbWVudCBuYW1lLCAiYXR0ciIgYW5kICJhdHRyMiIgYXJlIGF0dHJpYnV0ZSBuYW1lcyB3aXRoCi0gKiAgICAgIHRoZSB2YWx1ZXMgInZhbCIgYW5kICJ2YWwyIiwgcmVzcGVjdGl2ZWx5LgotICoKLSAqICAgNykgQSBuYW1lc3BhY2UgZGVjbGFyYXRpb24gaXMgYSBzcGVjaWFsIGF0dHJpYnV0ZSB0aGF0IGlzIHVzZWQgdG8gYXNzb2NpYXRlCi0gKiAgICAgIGEgcHJlZml4IHdpdGggYSBVUkkgKHRoZSBuYW1lc3BhY2UpLiAgVGhlIG1lYW5pbmdzIG9mIGVsZW1lbnQgbmFtZXMgYW5kCi0gKiAgICAgIGF0dHJpYnV0ZSBuYW1lcyB0aGF0IHVzZSB0aGF0IHByZWZpeCBhcmUgZGVmaW5lZCB3aXRoIHJlc3BlY3QgdG8gdGhhdAotICogICAgICBuYW1lc3BhY2UuCi0gKgotICogICA4KSBET00gaXMgYW4gYWNyb255bSBmb3IgRG9jdW1lbnQgT2JqZWN0IE1vZGVsLiAgSXQgaXMgYSB0cmVlCi0gKiAgICAgIHJlcHJlc2VudGF0aW9uIG9mIGFuIFhNTCBkb2N1bWVudC4KLSAqCi0gKiAgICAgIFNBWCBpcyBhbiBhY3JvbnltIGZvciB0aGUgU2ltcGxlIEFQSSBmb3IgWE1MIHByb2Nlc3NpbmcuICBJdCBpcyBhbiBBUEkKLSAqICAgICAgdXNlZCBpbmZvcm0gYW4gWE1MIHByb2Nlc3NvciAoaW4gdGhpcyBjYXNlIFhTTFRDKSBvZiB0aGUgc3RydWN0dXJlIGFuZAotICogICAgICBjb250ZW50IG9mIGFuIFhNTCBkb2N1bWVudC4KLSAqCi0gKiAgICAgIElucHV0IHRvIHRoZSBzdHlsZXNoZWV0IHByb2Nlc3NvciBjYW4gY29tZSBmcm9tIGFuIFhNTCBwYXJzZXIgaW4gdGhlCi0gKiAgICAgIGZvcm0gb2YgYSBET00gdHJlZSBvciB0aHJvdWdoIHRoZSBTQVggQVBJLgotICoKLSAqICAgOSkgRFREIGlzIGEgZG9jdW1lbnQgdHlwZSBkZWNsYXJhdGlvbi4gIEl0IGlzIGEgd2F5IG9mIHNwZWNpZnlpbmcgdGhlCi0gKiAgICAgIGdyYW1tYXIgZm9yIGFuIFhNTCBmaWxlLCB0aGUgbmFtZXMgYW5kIHR5cGVzIG9mIGVsZW1lbnRzLCBhdHRyaWJ1dGVzLAotICogICAgICBldGMuCi0gKgotICogIDEwKSBYUGF0aCBpcyBhIHNwZWNpZmljYXRpb24gdGhhdCBkZXNjcmliZXMgYSBub3RhdGlvbiBmb3IgaWRlbnRpZnlpbmcKLSAqICAgICAgbm9kZXMgaW4gYSB0cmVlLXN0cnVjdHVyZWQgcmVwcmVzZW50YXRpb24gb2YgYW4gWE1MIGRvY3VtZW50LiAgQW4KLSAqICAgICAgaW5zdGFuY2Ugb2YgdGhhdCBub3RhdGlvbiBpcyByZWZlcnJlZCB0byBhcyBhbiBYUGF0aCBleHByZXNzaW9uLgotICoKLSAqICAxMSkgVHJhbnNsZXQgaXMgYW4gaW52ZW50ZWQgdGVybSB0aGF0IHJlZmVycyB0byB0aGUgY2xhc3MgZmlsZSB0aGF0IGNvbnRhaW5zCi0gKiAgICAgIHRoZSBjb21waWxlZCBmb3JtIG9mIGEgc3R5bGVzaGVldC4KLSAqLwotCi0gICAgLy8gVGhlc2UgbWVzc2FnZSBzaG91bGQgYmUgcmVhZCBmcm9tIGEgbG9jYWxlLXNwZWNpZmljIHJlc291cmNlIGJ1bmRsZQotICAgIC8qKiBHZXQgdGhlIGxvb2t1cCB0YWJsZSBmb3IgZXJyb3IgbWVzc2FnZXMuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBtZXNzYWdlIGxvb2t1cCB0YWJsZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0W11bXSBnZXRDb250ZW50cygpCi0gICAgewotICAgICAgcmV0dXJuIG5ldyBPYmplY3RbXVtdIHsKLSAgICAgICAge0Vycm9yTXNnLk1VTFRJUExFX1NUWUxFU0hFRVRfRVJSLAotICAgICAgICAiU2UgaGEgZGVmaW5pZG8gbVx1MDBFMXMgZGUgdW5hIGhvamEgZGUgZXN0aWxvIGVuIGVsIG1pc21vIGFyY2hpdm8uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBhCi0gICAgICAgICAqIHRlbXBsYXRlLiAgVGhlIHNhbWUgbmFtZSB3YXMgdXNlZCBvbiB0d28gZGlmZmVyZW50IHRlbXBsYXRlcyBpbiB0aGUKLSAgICAgICAgICogc2FtZSBzdHlsZXNoZWV0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlRFTVBMQVRFX1JFREVGX0VSUiwKLSAgICAgICAgIkxhIHBsYW50aWxsYSAnJ3swfScnIHlhIHNlIGhhIGRlZmluaWRvIGVuIGVzdGEgaG9qYSBkZSBlc3RpbG8uIn0sCi0KLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIGEKLSAgICAgICAgICogdGVtcGxhdGUuICBBIHJlZmVyZW5jZSB0byB0aGUgdGVtcGxhdGUgbmFtZSB3YXMgZW5jb3VudGVyZWQsIGJ1dCB0aGUKLSAgICAgICAgICogdGVtcGxhdGUgaXMgdW5kZWZpbmVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlRFTVBMQVRFX1VOREVGX0VSUiwKLSAgICAgICAgIkxhIHBsYW50aWxsYSAnJ3swfScnIG5vIHNlIGhhIGRlZmluaWRvIGVuIGVzdGEgaG9qYSBkZSBlc3RpbG8uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBhIHZhcmlhYmxlCi0gICAgICAgICAqIHRoYXQgd2FzIGRlZmluZWQgbW9yZSB0aGFuIG9uY2UuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVkFSSUFCTEVfUkVERUZfRVJSLAotICAgICAgICAiU2UgaGEgZGVmaW5pZG8gdmFyaWFzIHZlY2VzIGxhIHZhcmlhYmxlICcnezB9JycgZW4gZWwgbWlzbW8gXHUwMEUxbWJpdG8uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBhIHZhcmlhYmxlCi0gICAgICAgICAqIG9yIHBhcmFtZXRlci4gIEEgcmVmZXJlbmNlIHRvIHRoZSB2YXJpYWJsZSBvciBwYXJhbWV0ZXIgd2FzIGZvdW5kLAotICAgICAgICAgKiBidXQgaXQgd2FzIG5ldmVyIGRlZmluZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVkFSSUFCTEVfVU5ERUZfRVJSLAotICAgICAgICAiTm8gc2UgaGEgZGVmaW5pZG8gbGEgdmFyaWFibGUgbyBlbCBwYXJcdTAwRTFtZXRybyAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgd29yZCAiY2xhc3MiIGhlcmUgcmVmZXJzIHRvIGEgSmF2YSBjbGFzcy4KLSAgICAgICAgICogUHJvY2Vzc2luZyB0aGUgc3R5bGVzaGVldCByZXF1aXJlZCBhIGNsYXNzIHRvIGJlIGxvYWRlZCwgYnV0IGl0IGNvdWxkCi0gICAgICAgICAqIG5vdCBiZSBmb3VuZC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiB0aGUgY2xhc3MuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuQ0xBU1NfTk9UX0ZPVU5EX0VSUiwKLSAgICAgICAgIk5vIHNlIGhhIGVuY29udHJhZG8gbGEgY2xhc2UgJyd7MH0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHdvcmQgIm1ldGhvZCIgaGVyZSByZWZlcnMgdG8gYSBKYXZhIG1ldGhvZC4KLSAgICAgICAgICogUHJvY2Vzc2luZyB0aGUgc3R5bGVzaGVldCByZXF1aXJlZCBhIHJlZmVyZW5jZSB0byB0aGUgbWV0aG9kIG5hbWVkIGJ5Ci0gICAgICAgICAqIHRoZSBzdWJzdGl0dXRpb24gdGV4dCwgYnV0IGl0IGNvdWxkIG5vdCBiZSBmb3VuZC4gICJwdWJsaWMiIGlzIHRoZQotICAgICAgICAgKiBKYXZhIGtleXdvcmQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTUVUSE9EX05PVF9GT1VORF9FUlIsCi0gICAgICAgICJObyBzZSBoYSBlbmNvbnRyYWRvIGVsIG1cdTAwRTl0b2RvIGV4dGVybm8gJyd7MH0nJyAoZGViZSBzZXIgcFx1MDBGQWJsaWNvKS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHdvcmQgIm1ldGhvZCIgaGVyZSByZWZlcnMgdG8gYSBKYXZhIG1ldGhvZC4KLSAgICAgICAgICogUHJvY2Vzc2luZyB0aGUgc3R5bGVzaGVldCByZXF1aXJlZCBhIHJlZmVyZW5jZSB0byB0aGUgbWV0aG9kIG5hbWVkIGJ5Ci0gICAgICAgICAqIHRoZSBzdWJzdGl0dXRpb24gdGV4dCwgYnV0IG5vIG1ldGhvZCB3aXRoIHRoZSByZXF1aXJlZCB0eXBlcyBvZgotICAgICAgICAgKiBhcmd1bWVudHMgb3IgcmV0dXJuIHR5cGUgY291bGQgYmUgZm91bmQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuQVJHVU1FTlRfQ09OVkVSU0lPTl9FUlIsCi0gICAgICAgICJObyBzZSBwdWVkZSBjb252ZXJ0aXIgZWwgdGlwbyBkZSBhcmd1bWVudG8vcmV0b3JubyBlbiBsYSBsbGFtYWRhIGFsIG1cdTAwRTl0b2RvICcnezB9JycifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZpbGUgb3IgVVJJIG5hbWVkIGluIHRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICAgKiBpcyBtaXNzaW5nLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkZJTEVfTk9UX0ZPVU5EX0VSUiwKLSAgICAgICAgIk5vIHNlIGhhIGVuY29udHJhZG8gZWwgYXJjaGl2byBvIFVSSSAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgZGlzcGxheWVkIHdoZW4gdGhlIFVSSQotICAgICAgICAgKiBtZW50aW9uZWQgaW4gdGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIG5vdCB3ZWxsLWZvcm1lZCBzeW50YWN0aWNhbGx5LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklOVkFMSURfVVJJX0VSUiwKLSAgICAgICAgIlVSSSAnJ3swfScnIG5vIHZcdTAwRTFsaWRvLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZmlsZSBvciBVUkkgbmFtZWQgaW4gdGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgICAqIGV4aXN0cyBidXQgY291bGQgbm90IGJlIG9wZW5lZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5GSUxFX0FDQ0VTU19FUlIsCi0gICAgICAgICJObyBzZSBwdWVkZSBhYnJpciBlbCBhcmNoaXZvIG8gVVJJICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogPHhzbDpzdHlsZXNoZWV0PiBhbmQgPHhzbDp0cmFuc2Zvcm0+IGFyZQotICAgICAgICAgKiBrZXl3b3JkcyB0aGF0IHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5NSVNTSU5HX1JPT1RfRVJSLAotICAgICAgICAiU2UgZXNwZXJhYmEgZWwgZWxlbWVudG8gPHhzbDpzdHlsZXNoZWV0PiBvIDx4c2w6dHJhbnNmb3JtPi4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN0eWxlc2hlZXQgY29udGFpbmVkIGEgcmVmZXJlbmNlIHRvIGEKLSAgICAgICAgICogbmFtZXNwYWNlIHByZWZpeCB0aGF0IHdhcyB1bmRlZmluZWQuICBUaGUgdmFsdWUgb2YgdGhlIHN1YnN0aXR1dGlvbgotICAgICAgICAgKiB0ZXh0IGlzIHRoZSBuYW1lIG9mIHRoZSBwcmVmaXguCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTkFNRVNQQUNFX1VOREVGX0VSUiwKLSAgICAgICAgIk5vIHNlIGhhIGRlY2xhcmFkbyBlbCBwcmVmaWpvIGRlIGVzcGFjaW8gZGUgbm9tYnJlcyAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgSmF2YSBmdW5jdGlvbiBuYW1lZCBpbiB0aGUgc3R5bGVzaGVldCBjb3VsZAotICAgICAgICAgKiBub3QgYmUgZm91bmQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuRlVOQ1RJT05fUkVTT0xWRV9FUlIsCi0gICAgICAgICJObyBzZSBoYSBwb2RpZG8gcmVzb2x2ZXIgbGEgbGxhbWFkYSBhIGxhIGZ1bmNpXHUwMEYzbiAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYQotICAgICAgICAgKiBmdW5jdGlvbi4gIEEgbGl0ZXJhbCBzdHJpbmcgaGVyZSBtZWFucyBhIGNvbnN0YW50IHN0cmluZyB2YWx1ZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5ORUVEX0xJVEVSQUxfRVJSLAotICAgICAgICAiRWwgYXJndW1lbnRvIGVuICcnezB9JycgZGViZSBzZXIgdW5hIGNhZGVuYSBsaXRlcmFsLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaW5kaWNhdGVzIHRoZXJlIHdhcyBhIHN5bnRhY3RpYwotICAgICAgICAgKiBlcnJvciBpbiB0aGUgZm9ybSBvZiBhbiBYUGF0aCBleHByZXNzaW9uLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzCi0gICAgICAgICAqIHRoZSBleHByZXNzaW9uLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlhQQVRIX1BBUlNFUl9FUlIsCi0gICAgICAgICJFcnJvciBhbCBhbmFsaXphciBsYSBleHByZXNpXHUwMEYzbiBYUGF0aCAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBbiBlbGVtZW50IGluIHRoZSBzdHlsZXNoZWV0IHJlcXVpcmVzIGEKLSAgICAgICAgICogcGFydGljdWxhciBhdHRyaWJ1dGUgbmFtZWQgYnkgdGhlIHN1YnN0aXR1dGlvbiB0ZXh0LCBidXQgdGhhdAotICAgICAgICAgKiBhdHRyaWJ1dGUgd2FzIG5vdCBzcGVjaWZpZWQgaW4gdGhlIHN0eWxlc2hlZXQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuUkVRVUlSRURfQVRUUl9FUlIsCi0gICAgICAgICJGYWx0YSBlbCBhdHJpYnV0byAnJ3swfScnIG5lY2VzYXJpby4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IGEgY2hhcmFjdGVyIG5vdAotICAgICAgICAgKiBwZXJtaXR0ZWQgaW4gYW4gWFBhdGggZXhwcmVzc2lvbiB3YXMgZW5jb3VudGVyZWQuICBUaGUgc3Vic3RpdHV0aW9uCi0gICAgICAgICAqIHRleHQgaXMgdGhlIG9mZmVuZGluZyBjaGFyYWN0ZXIuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSUxMRUdBTF9DSEFSX0VSUiwKLSAgICAgICAgIkNhclx1MDBFMWN0ZXIgJyd7MH0nJyBubyBwZXJtaXRpZG8gZW4gbGEgZXhwcmVzaVx1MDBGM24gWFBhdGguIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEEgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiBpcyBhIG1hcmstdXAgaXRlbSBpbgotICAgICAgICAgKiBhbiBYTUwgZG9jdW1lbnQgdGhhdCByZXF1ZXN0IHNvbWUgYmVoYXZpb3VyIG9mIGFuIFhNTCBwcm9jZXNzb3IuICBUaGUKLSAgICAgICAgICogZm9ybSBvZiB0aGUgbmFtZSBvZiB3YXMgaW52YWxpZCBpbiB0aGlzIGNhc2UsIGFuZCB0aGUgc3Vic3RpdHV0aW9uCi0gICAgICAgICAqIHRleHQgaXMgdGhlIG5hbWUuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSUxMRUdBTF9QSV9FUlIsCi0gICAgICAgICJOb21icmUgJyd7MH0nJyBubyBwZXJtaXRpZG8gcGFyYSBsYSBpbnN0cnVjY2lcdTAwRjNuIGRlIHByb2Nlc2FtaWVudG8uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyByZXBvcnRlZCBpZiB0aGUgc3R5bGVzaGVldAotICAgICAgICAgKiBiZWluZyBwcm9jZXNzZWQgYXR0ZW1wdGVkIHRvIGNvbnN0cnVjdCBhbiBYTUwgZG9jdW1lbnQgd2l0aCBhbgotICAgICAgICAgKiBhdHRyaWJ1dGUgaW4gYSBwbGFjZSBvdGhlciB0aGFuIG9uIGFuIGVsZW1lbnQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQKLSAgICAgICAgICogc3BlY2lmaWVzIHRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuU1RSQVlfQVRUUklCVVRFX0VSUiwKLSAgICAgICAgIkVsIGF0cmlidXRvICcnezB9JycgZXN0XHUwMEUxIGZ1ZXJhIGRlbCBlbGVtZW50by4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQW4gYXR0cmlidXRlIHRoYXQgd2Fzbid0IHJlY29nbml6ZWQgd2FzCi0gICAgICAgICAqIHNwZWNpZmllZCBvbiBhbiBlbGVtZW50IGluIHRoZSBzdHlsZXNoZWV0LiAgVGhlIGF0dHJpYnV0ZSBpcyBuYW1lZAotICAgICAgICAgKiBieSB0aGUgc3Vic3RpdHV0aW9uCi0gICAgICAgICAqIHRleHQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSUxMRUdBTF9BVFRSSUJVVEVfRVJSLAotICAgICAgICAiQXRyaWJ1dG8gJyd7MH0nJyBubyBwZXJtaXRpZG8uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJpbXBvcnQiIGFuZCAiaW5jbHVkZSIgYXJlIGtleXdvcmRzIHRoYXQgc2hvdWxkCi0gICAgICAgICAqIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhpcyBtZXNzYWdlcyBpbmRpY2F0ZXMgdGhhdCB0aGUgc3R5bGVzaGVldAotICAgICAgICAgKiBuYW1lZCBpbiB0aGUgc3Vic3RpdHV0aW9uIHRleHQgaW1wb3J0ZWQgb3IgaW5jbHVkZWQgaXRzZWxmIGVpdGhlcgotICAgICAgICAgKiBkaXJlY3RseSBvciBpbmRpcmVjdGx5LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkNJUkNVTEFSX0lOQ0xVREVfRVJSLAotICAgICAgICAiSW1wb3J0L2luY2x1ZGUgY2lyY3VsYXIuIExhIGhvamEgZGUgZXN0aWxvICcnezB9JycgeWEgc2UgaGEgY2FyZ2Fkby4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQSByZXN1bHQtdHJlZSBmcmFnbWVudCBpcyBhIHBvcnRpb24gb2YgYQotICAgICAgICAgKiByZXN1bHRpbmcgWE1MIGRvY3VtZW50IHJlcHJlc2VudGVkIGFzIGEgdHJlZS4gICI8eHNsOnNvcnQ+IiBpcyBhCi0gICAgICAgICAqIGtleXdvcmQgYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5SRVNVTFRfVFJFRV9TT1JUX0VSUiwKLSAgICAgICAgIkxvcyBmcmFnbWVudG9zIGRlbCBcdTAwRTFyYm9sIGRlIHJlc3VsdGFkb3Mgbm8gc2UgcHVlZGVuIG9yZGVuYXIgKGxvcyBlbGVtZW50b3MgPHhzbDpzb3J0PiBzZSBpZ25vcmFuKS4gRGViZSBvcmRlbmFyIGxvcyBub2RvcyBhbCBjcmVhciBlbCBcdTAwRTFyYm9sIGRlIHJlc3VsdGFkb3MuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEEgbmFtZSBjYW4gYmUgZ2l2ZW4gdG8gYSBwYXJ0aWN1bGFyIHN0eWxlIHRvIGJlCi0gICAgICAgICAqIHVzZWQgdG8gZm9ybWF0IGRlY2ltYWwgdmFsdWVzLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGdpdmVzIHRoZSBuYW1lCi0gICAgICAgICAqIG9mIHN1Y2ggYSBzdHlsZSBmb3Igd2hpY2ggbW9yZSB0aGFuIG9uZSBkZWNsYXJhdGlvbiB3YXMgZW5jb3VudGVyZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuU1lNQk9MU19SRURFRl9FUlIsCi0gICAgICAgICJZYSBzZSBoYSBkZWZpbmlkbyBlbCBmb3JtYXRvIGRlY2ltYWwgJyd7MH0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN0eWxlc2hlZXQgdmVyc2lvbiBuYW1lZCBpbiB0aGUKLSAgICAgICAgICogc3Vic3RpdHV0aW9uIHRleHQgaXMgbm90IHN1cHBvcnRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5YU0xfVkVSU0lPTl9FUlIsCi0gICAgICAgICJMYSB2ZXJzaVx1MDBGM24gWFNMICcnezB9Jycgbm8gZXN0XHUwMEUxIHNvcG9ydGFkYSBwb3IgWFNMVEMuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBkZWZpbml0aW9ucyBvZiBvbmUgb3IgbW9yZSB2YXJpYWJsZXMgb3IKLSAgICAgICAgICogcGFyYW1ldGVycyBkZXBlbmQgb24gb25lIGFub3RoZXIuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuQ0lSQ1VMQVJfVkFSSUFCTEVfRVJSLAotICAgICAgICAiTGEgcmVmZXJlbmNpYSBkZSB2YXJpYWJsZS9wYXJcdTAwRTFtZXRybyBjaXJjdWxhciBlbiAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgb3BlcmF0b3IgaW4gYW4gZXhwcmVzaW9uIHdpdGggdHdvIG9wZXJhbmRzIHdhcwotICAgICAgICAgKiBub3QgcmVjb2duaXplZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTExFR0FMX0JJTkFSWV9PUF9FUlIsCi0gICAgICAgICJPcGVyYWRvciBkZXNjb25vY2lkbyBwYXJhIGxhIGV4cHJlc2lcdTAwRjNuIGJpbmFyaWEuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyBwcm9kdWNlZCBpZiBhIHJlZmVyZW5jZSB0byBhCi0gICAgICAgICAqIGZ1bmN0aW9uIGhhcyB0b28gbWFueSBvciB0b28gZmV3IGFyZ3VtZW50cy4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTExFR0FMX0FSR19FUlIsCi0gICAgICAgICJBcmd1bWVudG9zIG5vIHBlcm1pdGlkb3MgcGFyYSBsYSBsbGFtYWRhIGRlIGZ1bmNpXHUwMEYzbi4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgImRvY3VtZW50KCkiIGlzIHRoZSBuYW1lIG9mIGZ1bmN0aW9uIGFuZCBtdXN0Ci0gICAgICAgICAqIG5vdCBiZSB0cmFuc2xhdGVkLiAgQSBub2RlLXNldCBpcyBhIHNldCBvZiB0aGUgbm9kZXMgaW4gdGhlIHRyZWUKLSAgICAgICAgICogcmVwcmVzZW50YXRpb24gb2YgYW4gWE1MIGRvY3VtZW50LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkRPQ1VNRU5UX0FSR19FUlIsCi0gICAgICAgICJFbCBzZWd1bmRvIGFyZ3VtZW50byBlbiBsYSBmdW5jaVx1MDBGM24gZG9jdW1lbnQoKSBkZWJlIHNlciB1biBqdWVnbyBkZSBub2Rvcy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIjx4c2w6d2hlbj4iIGFuZCAiPHhzbDpjaG9vc2U+IiBhcmUga2V5d29yZHMKLSAgICAgICAgICogYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoaXMgbWVzc2FnZSBkZXNjcmliZXMgYSBzeW50YXggZXJyb3IKLSAgICAgICAgICogaW4gdGhlIHN0eWxlc2hlZXQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTUlTU0lOR19XSEVOX0VSUiwKLSAgICAgICAgIlNlIG5lY2VzaXRhIGFsIG1lbm9zIHVuIGVsZW1lbnRvIDx4c2w6d2hlbj4gZW4gPHhzbDpjaG9vc2U+LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiPHhzbDpvdGhlcndpc2U+IiBhbmQgIjx4c2w6Y2hvb3NlPiIgYXJlCi0gICAgICAgICAqIGtleXdvcmRzIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGlzIG1lc3NhZ2UgZGVzY3JpYmVzIGEKLSAgICAgICAgICogc3ludGF4IGVycm9yIGluIHRoZSBzdHlsZXNoZWV0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk1VTFRJUExFX09USEVSV0lTRV9FUlIsCi0gICAgICAgICJTXHUwMEYzbG8gc2UgcGVybWl0ZSB1biBlbGVtZW50byA8eHNsOm90aGVyd2lzZT4gZW4gPHhzbDpjaG9vc2U+LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiPHhzbDpvdGhlcndpc2U+IiBhbmQgIjx4c2w6Y2hvb3NlPiIgYXJlCi0gICAgICAgICAqIGtleXdvcmRzIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGlzIG1lc3NhZ2UgZGVzY3JpYmVzIGEKLSAgICAgICAgICogc3ludGF4IGVycm9yIGluIHRoZSBzdHlsZXNoZWV0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlNUUkFZX09USEVSV0lTRV9FUlIsCi0gICAgICAgICI8eHNsOm90aGVyd2lzZT4gc1x1MDBGM2xvIHNlIHB1ZWRlIHV0aWxpemFyIGVuIDx4c2w6Y2hvb3NlPi4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIjx4c2w6d2hlbj4iIGFuZCAiPHhzbDpjaG9vc2U+IiBhcmUga2V5d29yZHMKLSAgICAgICAgICogYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoaXMgbWVzc2FnZSBkZXNjcmliZXMgYSBzeW50YXggZXJyb3IKLSAgICAgICAgICogaW4gdGhlIHN0eWxlc2hlZXQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuU1RSQVlfV0hFTl9FUlIsCi0gICAgICAgICI8eHNsOndoZW4+IHNcdTAwRjNsbyBzZSBwdWVkZSB1dGlsaXphciBlbiA8eHNsOmNob29zZT4uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICI8eHNsOndoZW4+IiwgIjx4c2w6b3RoZXJ3aXNlPiIgYW5kCi0gICAgICAgICAqICI8eHNsOmNob29zZT4iIGFyZSBrZXl3b3JkcyBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhpcwotICAgICAgICAgKiBtZXNzYWdlIGRlc2NyaWJlcyBhIHN5bnRheCBlcnJvciBpbiB0aGUgc3R5bGVzaGVldC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5XSEVOX0VMRU1FTlRfRVJSLAotICAgICAgICAiU1x1MDBGM2xvIHNlIHBlcm1pdGVuIGxvcyBlbGVtZW50b3MgPHhzbDp3aGVuPiB5IDx4c2w6b3RoZXJ3aXNlPiBlbiA8eHNsOmNob29zZT4uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICI8eHNsOmF0dHJpYnV0ZS1zZXQ+IiBhbmQgIm5hbWUiIGFyZSBrZXl3b3JkcwotICAgICAgICAgKiB0aGF0IHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5VTk5BTUVEX0FUVFJJQlNFVF9FUlIsCi0gICAgICAgICJGYWx0YSBlbCBhdHJpYnV0byAnbmFtZScgZW4gPHhzbDphdHRyaWJ1dGUtc2V0PiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBbiBlbGVtZW50IGluIHRoZSBzdHlsZXNoZWV0IGNvbnRhaW5lZCBhbgotICAgICAgICAgKiBlbGVtZW50IG9mIGEgdHlwZSB0aGF0IGl0IHdhcyBub3QgcGVybWl0dGVkIHRvIGNvbnRhaW4uCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSUxMRUdBTF9DSElMRF9FUlIsCi0gICAgICAgICJFbGVtZW50byBzZWN1bmRhcmlvIG5vIHBlcm1pdGlkby4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN0eWxlc2hlZXQgdHJpZWQgdG8gY3JlYXRlIGFuIGVsZW1lbnQgd2l0aAotICAgICAgICAgKiBhIG5hbWUgdGhhdCB3YXMgbm90IGEgdmFsaWQgWE1MIG5hbWUuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgY29udGFpbnMKLSAgICAgICAgICogdGhlIG5hbWUuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSUxMRUdBTF9FTEVNX05BTUVfRVJSLAotICAgICAgICAiTm8gc2UgcHVlZGUgbGxhbWFyICcnezB9JycgYSB1biBlbGVtZW50byJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3R5bGVzaGVldCB0cmllZCB0byBjcmVhdGUgYW4gYXR0cmlidXRlCi0gICAgICAgICAqIHdpdGggYSBuYW1lIHRoYXQgd2FzIG5vdCBhIHZhbGlkIFhNTCBuYW1lLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgICAqIGNvbnRhaW5zIHRoZSBuYW1lLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfQVRUUl9OQU1FX0VSUiwKLSAgICAgICAgIk5vIHNlIHB1ZWRlIGxsYW1hciAnJ3swfScnIGEgdW4gYXRyaWJ1dG8ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGNoaWxkcmVuIG9mIHRoZSBvdXRlcm1vc3QgZWxlbWVudCBvZiBhCi0gICAgICAgICAqIHN0eWxlc2hlZXQgYXJlIHJlZmVycmVkIHRvIGFzIHRvcC1sZXZlbCBlbGVtZW50cy4gIE5vIHRleHQgc2hvdWxkCi0gICAgICAgICAqIG9jY3VyIHdpdGhpbiB0aGF0IG91dGVybW9zdCBlbGVtZW50IHVubGVzcyBpdCBpcyB3aXRoaW4gYSB0b3AtbGV2ZWwKLSAgICAgICAgICogZWxlbWVudC4gIFRoaXMgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGF0IGNvbnN0cmFpbnQgd2FzIHZpb2xhdGVkLgotICAgICAgICAgKiAiPHhzbDpzdHlsZXNoZWV0PiIgaXMgYSBrZXl3b3JkIHRoYXQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfVEVYVF9OT0RFX0VSUiwKLSAgICAgICAgIkRhdG9zIGRlIHRleHRvIGZ1ZXJhIGRlbCBlbGVtZW50byA8eHNsOnN0eWxlc2hlZXQ+IGRlIG5pdmVsIHN1cGVyaW9yLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBKQVhQIGlzIGFuIGFjcm9ueW0gZm9yIHRoZSBKYXZhIEFQSSBmb3IgWE1MCi0gICAgICAgICAqIFByb2Nlc3NpbmcuICBUaGlzIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhlIFhNTCBwYXJzZXIgcHJvdmlkZWQgdG8KLSAgICAgICAgICogWFNMVEMgdG8gcHJvY2VzcyB0aGUgWE1MIGlucHV0IGRvY3VtZW50IGhhZCBhIGNvbmZpZ3VyYXRpb24gcHJvYmxlbS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5TQVhfUEFSU0VSX0NPTkZJR19FUlIsCi0gICAgICAgICJFbCBhbmFsaXphZG9yIEpBWFAgbm8gc2UgaGEgY29uZmlndXJhZG8gY29ycmVjdGFtZW50ZSJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgbmFtZXMgdGhlIGludGVybmFsIGVycm9yCi0gICAgICAgICAqIGVuY291bnRlcmVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklOVEVSTkFMX0VSUiwKLSAgICAgICAgIkVycm9yIGludGVybm8gZGUgWFNMVEMgaXJyZWN1cGVyYWJsZTogJyd7MH0nJyJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3R5bGVzaGVldCBjb250YWluZWQgYW4gZWxlbWVudCB0aGF0IHdhcwotICAgICAgICAgKiBub3QgcmVjb2duaXplZCBhcyBwYXJ0IG9mIHRoZSBYU0wgc3ludGF4LiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgICAqIGdpdmVzIHRoZSBlbGVtZW50IG5hbWUuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVU5TVVBQT1JURURfWFNMX0VSUiwKLSAgICAgICAgIkVsZW1lbnRvICcnezB9JycgZGUgWFNMIG5vIHNvcG9ydGFkby4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN0eWxlc2hlZXQgcmVmZXJyZWQgdG8gYW4gZXh0ZW5zaW9uIHRvIHRoZQotICAgICAgICAgKiBYU0wgc3ludGF4IGFuZCBpbmRpY2F0ZWQgdGhhdCBpdCB3YXMgZGVmaW5lZCBieSBYU0xUQywgYnV0IFhTVExDIGRvZXMKLSAgICAgICAgICogbm90IHJlY29nbml6ZWQgdGhlIHBhcnRpY3VsYXIgZXh0ZW5zaW9uIG5hbWVkLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgICAqIGdpdmVzIHRoZSBleHRlbnNpb24gbmFtZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5VTlNVUFBPUlRFRF9FWFRfRVJSLAotICAgICAgICAiRXh0ZW5zaVx1MDBGM24gJyd7MH0nJyBkZSBYU0xUQyBubyByZWNvbm9jaWRhLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgWE1MIGRvY3VtZW50IGdpdmVuIHRvIFhTTFRDIGFzIGEgc3R5bGVzaGVldAotICAgICAgICAgKiB3YXMgbm90LCBpbiBmYWN0LCBhIHN0eWxlc2hlZXQuICBYU0xUQyBpcyBhYmxlIHRvIGRldGVjdCB0aGF0IGluIHRoaXMKLSAgICAgICAgICogY2FzZSBiZWNhdXNlIHRoZSBvdXRlcm1vc3QgZWxlbWVudCBpbiB0aGUgc3R5bGVzaGVldCBoYXMgdG8gYmUKLSAgICAgICAgICogZGVjbGFyZWQgd2l0aCByZXNwZWN0IHRvIHRoZSBYU0wgbmFtZXNwYWNlIFVSSSwgYnV0IG5vIGRlY2xhcmF0aW9uCi0gICAgICAgICAqIGZvciB0aGF0IG5hbWVzcGFjZSB3YXMgc2Vlbi4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5NSVNTSU5HX1hTTFRfVVJJX0VSUiwKLSAgICAgICAgIkVsIGRvY3VtZW50byBkZSBlbnRyYWRhIG5vIGVzIHVuYSBob2phIGRlIGVzdGlsbyAoZWwgZXNwYWNpbyBkZSBub21icmVzIFhTTCBubyBzZSBoYSBkZWNsYXJhZG8gZW4gZWwgZWxlbWVudG8gcmFcdTAwRUR6KS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgWFNMVEMgY291bGQgbm90IGZpbmQgdGhlIHN0eWxlc2hlZXQgZG9jdW1lbnQKLSAgICAgICAgICogd2l0aCB0aGUgbmFtZSBzcGVjaWZpZWQgYnkgdGhlIHN1YnN0aXR1dGlvbiB0ZXh0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk1JU1NJTkdfWFNMVF9UQVJHRVRfRVJSLAotICAgICAgICAiTm8gc2UgaGEgZW5jb250cmFkbyBlbCBkZXN0aW5vIGRlIGhvamEgZGUgZXN0aWxvICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIGFjY2VzcyB0byB0aGUgc3R5bGVzaGVldCB0YXJnZXQgaXMgZGVuaWVkCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuQUNDRVNTSU5HX1hTTFRfVEFSR0VUX0VSUiwKLSAgICAgICAgIk5vIHNlIGhhIHBvZGlkbyBsZWVyIGVsIGRlc3Rpbm8gZGUgaG9qYSBkZSBlc3RpbG9zICcnezB9JycsIHBvcnF1ZSBubyBzZSBwZXJtaXRlIGVsIGFjY2VzbyAnJ3sxfScnIGRlYmlkbyBhIHVuYSByZXN0cmljY2lcdTAwRjNuIGRlZmluaWRhIHBvciBsYSBwcm9waWVkYWQgYWNjZXNzRXh0ZXJuYWxTdHlsZXNoZWV0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgcmVwcmVzZW50cyBhbiBpbnRlcm5hbCBlcnJvciBpbgotICAgICAgICAgKiBjb25kaXRpb24gaW4gWFNMVEMuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIGNsYXNzIG5hbWUgaW4gWFNMVEMKLSAgICAgICAgICogdGhhdCBpcyBtaXNzaW5nIHNvbWUgZnVuY3Rpb25hbGl0eS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5OT1RfSU1QTEVNRU5URURfRVJSLAotICAgICAgICAiTm8gaW1wbGFudGFkbzogJyd7MH0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIFhNTCBkb2N1bWVudCBnaXZlbiB0byBYU0xUQyBhcyBhIHN0eWxlc2hlZXQKLSAgICAgICAgICogd2FzIG5vdCwgaW4gZmFjdCwgYSBzdHlsZXNoZWV0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk5PVF9TVFlMRVNIRUVUX0VSUiwKLSAgICAgICAgIkVsIGRvY3VtZW50byBkZSBlbnRyYWRhIG5vIGNvbnRpZW5lIHVuYSBob2phIGRlIGVzdGlsbyBYU0wuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBlbGVtZW50IG5hbWVkIGluIHRoZSBzdWJzdGl0dXRpb24gdGV4dCB3YXMKLSAgICAgICAgICogZW5jb3VudGVyZWQgaW4gdGhlIHN0eWxlc2hlZXQgYnV0IGlzIG5vdCByZWNvZ25pemVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkVMRU1FTlRfUEFSU0VfRVJSLAotICAgICAgICAiTm8gc2UgaGEgcG9kaWRvIGFuYWxpemFyIGVsIGVsZW1lbnRvICcnezB9JycifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgInVzZSIsICI8a2V5PiIsICJub2RlIiwgIm5vZGUtc2V0IiwgInN0cmluZyIKLSAgICAgICAgICogYW5kICJudW1iZXIiIGFyZSBrZXl3b3JkcyBpbiB0aGlzIGNvbnRleHQgYW5kIHNob3VsZCBub3QgYmUKLSAgICAgICAgICogdHJhbnNsYXRlZC4gIFRoaXMgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUgdmFsdWUgb2YgdGhlICJ1c2UiCi0gICAgICAgICAqIGF0dHJpYnV0ZSB3YXMgbm90IG9uZSBvZiB0aGUgcGVybWl0dGVkIHZhbHVlcy4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5LRVlfVVNFX0FUVFJfRVJSLAotICAgICAgICAiRWwgYXRyaWJ1dG8gdXNlIGRlIDxrZXk+IGRlYmUgc2VyIG5vZGUsIG5vZGUtc2V0LCBzdHJpbmcgbyBudW1iZXIuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIFhNTCBkb2N1bWVudCBjYW4gc3BlY2lmeSB0aGUgdmVyc2lvbiBvZiB0aGUKLSAgICAgICAgICogWE1MIHNwZWNpZmljYXRpb24gdG8gd2hpY2ggaXQgYWRoZXJlcy4gIFRoaXMgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdAotICAgICAgICAgKiB0aGUgdmVyc2lvbiBzcGVjaWZpZWQgZm9yIHRoZSBvdXRwdXQgZG9jdW1lbnQgd2FzIG5vdCB2YWxpZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5PVVRQVVRfVkVSU0lPTl9FUlIsCi0gICAgICAgICJMYSB2ZXJzaVx1MDBGM24gZGVsIGRvY3VtZW50byBYTUwgZGUgc2FsaWRhIGRlYmUgc2VyIDEuMCJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgb3BlcmF0b3IgaW4gYSBjb21wYXJpc29uIG9wZXJhdGlvbiB3YXMKLSAgICAgICAgICogbm90IHJlY29nbml6ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSUxMRUdBTF9SRUxBVF9PUF9FUlIsCi0gICAgICAgICJPcGVyYWRvciBkZXNjb25vY2lkbyBwYXJhIGxhIGV4cHJlc2lcdTAwRjNuIHJlbGFjaW9uYWwifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQW4gYXR0cmlidXRlIHNldCBkZWZpbmVzIGFzIGEgc2V0IG9mIFhNTAotICAgICAgICAgKiBhdHRyaWJ1dGVzIHRoYXQgY2FuIGJlIGFkZGVkIHRvIGFuIGVsZW1lbnQgaW4gdGhlIG91dHB1dCBYTUwgZG9jdW1lbnQKLSAgICAgICAgICogYXMgYSBncm91cC4gIFRoaXMgbWVzc2FnZSBpcyByZXBvcnRlZCBpZiB0aGUgbmFtZSBzcGVjaWZpZWQgd2FzIG5vdAotICAgICAgICAgKiB1c2VkIHRvIGRlY2xhcmUgYW4gYXR0cmlidXRlIHNldC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZQotICAgICAgICAgKiB0aGF0IGlzIGluIGVycm9yLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkFUVFJJQlNFVF9VTkRFRl9FUlIsCi0gICAgICAgICJTZSBlc3RcdTAwRTEgaW50ZW50YW5kbyB1dGlsaXphciBlbCBqdWVnbyBkZSBhdHJpYnV0b3MgJyd7MH0nJyBubyBleGlzdGVudGUuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSB0ZXJtICJhdHRyaWJ1dGUgdmFsdWUgdGVtcGxhdGUiIGlzIGEgdGVybQotICAgICAgICAgKiBkZWZpbmVkIGJ5IFhTTFQgd2hpY2ggZGVzY3JpYmVzIHRoZSB2YWx1ZSBvZiBhbiBhdHRyaWJ1dGUgdGhhdCBpcwotICAgICAgICAgKiBkZXRlcm1pbmVkIGJ5IGFuIFhQYXRoIGV4cHJlc3Npb24uICBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUKLSAgICAgICAgICogZXhwcmVzc2lvbiB3YXMgc3ludGFjdGljYWxseSBpbmNvcnJlY3Q7IHRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICAgKiBjb250YWlucyB0aGUgZXhwcmVzc2lvbiB0aGF0IHdhcyBpbiBlcnJvci4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5BVFRSX1ZBTF9URU1QTEFURV9FUlIsCi0gICAgICAgICJObyBzZSBwdWVkZSBhbmFsaXphciBsYSBwbGFudGlsbGEgZGVsIHZhbG9yIGRlIGF0cmlidXRvICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogID8/PwotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlVOS05PV05fU0lHX1RZUEVfRVJSLAotICAgICAgICAiVGlwbyBkZSBkYXRvcyBkZXNjb25vY2lkbyBlbiBsYSBmaXJtYSBwYXJhIGxhIGNsYXNlICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCByZWZlcnMgdG8gZGF0YSB0eXBlcy4KLSAgICAgICAgICogVGhlIG1lc3NhZ2UgaXMgZGlzcGxheWVkIGlmIGEgdmFsdWUgaW4gYSBwYXJ0aWN1bGFyIGNvbnRleHQgbmVlZHMgdG8KLSAgICAgICAgICogYmUgY29udmVydGVkIHRvIHR5cGUgezF9LCBidXQgdGhhdCdzIG5vdCBwb3NzaWJsZSBmb3IgYSB2YWx1ZSBvZgotICAgICAgICAgKiB0eXBlIHswfS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5EQVRBX0NPTlZFUlNJT05fRVJSLAotICAgICAgICAiTm8gc2UgcHVlZGUgY29udmVydGlyIGVsIHRpcG8gZGUgZGF0b3MgJyd7MH0nJyBlbiAnJ3sxfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiVGVtcGxhdGVzIiBpcyBhIEphdmEgY2xhc3MgbmFtZSB0aGF0IHNob3VsZAotICAgICAgICAgKiBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5OT19UUkFOU0xFVF9DTEFTU19FUlIsCi0gICAgICAgICJUZW1wbGF0ZXMgbm8gY29udGllbmUgdW5hIGRlZmluaWNpXHUwMEYzbiBkZSBjbGFzZSB0cmFuc2xldC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIlRlbXBsYXRlcyIgaXMgYSBKYXZhIGNsYXNzIG5hbWUgdGhhdCBzaG91bGQKLSAgICAgICAgICogbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTk9fTUFJTl9UUkFOU0xFVF9FUlIsCi0gICAgICAgICJUZW1wbGF0ZXMgbm8gY29udGllbmUgdW5hIGNsYXNlIGNvbiBlbCBub21icmUgJyd7MH0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIGEgY2xhc3MuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVFJBTlNMRVRfQ0xBU1NfRVJSLAotICAgICAgICAiTm8gc2UgaGEgcG9kaWRvIGNhcmdhciBsYSBjbGFzZSBkZSB0cmFuc2xldCAnJ3swfScnLiJ9LAotCi0gICAgICAgIHtFcnJvck1zZy5UUkFOU0xFVF9PQkpFQ1RfRVJSLAotICAgICAgICAiTGEgY2xhc2UgZGUgdHJhbnNsZXQgc2UgaGEgY2FyZ2FkbywgcGVybyBubyBzZSBwdWVkZSBjcmVhciB1bmEgaW5zdGFuY2lhIGRlIHRyYW5zbGV0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiRXJyb3JMaXN0ZW5lciIgaXMgYSBKYXZhIGludGVyZmFjZSBuYW1lIHRoYXQKLSAgICAgICAgICogc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhlIHVzZXIgdHJpZWQKLSAgICAgICAgICogdG8gc2V0IGFuIEVycm9yTGlzdGVuZXIgb2JqZWN0IG9uIG9iamVjdCBvZiB0aGUgY2xhc3MgbmFtZWQgaW4gdGhlCi0gICAgICAgICAqIHN1YnN0aXR1dGlvbiB0ZXh0IHdpdGggIm51bGwiIEphdmEgdmFsdWUuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuRVJST1JfTElTVEVORVJfTlVMTF9FUlIsCi0gICAgICAgICJJbnRlbnRhbmRvIGRlZmluaXIgRXJyb3JMaXN0ZW5lciBwYXJhICcnezB9JycgY29tbyBudWxvIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFN0cmVhbVNvdXJjZSwgU0FYU291cmNlIGFuZCBET01Tb3VyY2UgYXJlIEphdmEKLSAgICAgICAgICogaW50ZXJmYWNlIG5hbWVzIHRoYXQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfVU5LTk9XTl9TT1VSQ0VfRVJSLAotICAgICAgICAiU1x1MDBGM2xvIFN0cmVhbVNvdXJjZSwgU0FYU291cmNlIHkgRE9NU291cmNlIGVzdFx1MDBFMW4gc29wb3J0YWRvcyBwb3IgWFNMVEMifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIlNvdXJjZSIgaXMgYSBKYXZhIGNsYXNzIG5hbWUgdGhhdCBzaG91bGQgbm90Ci0gICAgICAgICAqIGJlIHRyYW5zbGF0ZWQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgSmF2YSBtZXRob2QuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSkFYUF9OT19TT1VSQ0VfRVJSLAotICAgICAgICAiRWwgb2JqZXRvIFNvdXJjZSBxdWUgc2UgaGEgdHJhbnNmZXJpZG8gYSAnJ3swfScnIG5vIHRpZW5lIGNvbnRlbmlkby4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgWFNMVEMgZmFpbGVkIHRvCi0gICAgICAgICAqIGNvbXBpbGUgdGhlIHN0eWxlc2hlZXQgaW50byBhIHRyYW5zbGV0IChjbGFzcyBmaWxlKS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX0NPTVBJTEVfRVJSLAotICAgICAgICAiTm8gc2UgaGEgcG9kaWRvIGNvbXBpbGFyIGxhIGhvamEgZGUgZXN0aWxvIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJUcmFuc2Zvcm1lckZhY3RvcnkiIGlzIGEgY2xhc3MgbmFtZS4gIEluIHRoaXMKLSAgICAgICAgICogY29udGV4dCwgYW4gYXR0cmlidXRlIGlzIGEgcHJvcGVydHkgb3Igc2V0dGluZyBvZiB0aGUKLSAgICAgICAgICogVHJhbnNmb3JtZXJGYWN0b3J5IG9iamVjdC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiB0aGUKLSAgICAgICAgICogdW5yZWNvZ25pc2VkIGF0dHJpYnV0ZS4gIFRoZSBtZXRob2QgdXNlZCB0byByZXRyaWV2ZSB0aGUgYXR0cmlidXRlIGlzCi0gICAgICAgICAqICJnZXRBdHRyaWJ1dGUiLCBzbyBpdCdzIG5vdCBjbGVhciB3aGV0aGVyIGl0IHdvdWxkIGJlIGJlc3QgdG8KLSAgICAgICAgICogdHJhbnNsYXRlIHRoZSB0ZXJtICJhdHRyaWJ1dGUiLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfSU5WQUxJRF9BVFRSX0VSUiwKLSAgICAgICAgIlRyYW5zZm9ybWVyRmFjdG9yeSBubyByZWNvbm9jZSBlbCBhdHJpYnV0byAnJ3swfScnLiJ9LAotCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX0lOVkFMSURfQVRUUl9WQUxVRV9FUlIsCi0gICAgICAgICJWYWxvciBubyB2XHUwMEUxbGlkbyBlc3BlY2lmaWNhZG8gcGFyYSBlbCBhdHJpYnV0byAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAic2V0UmVzdWx0KCkiIGFuZCAic3RhcnREb2N1bWVudCgpIiBhcmUgSmF2YQotICAgICAgICAgKiBtZXRob2QgbmFtZXMgdGhhdCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSkFYUF9TRVRfUkVTVUxUX0VSUiwKLSAgICAgICAgInNldFJlc3VsdCgpIGRlYmUgbGxhbWFyc2UgYW50ZXMgZGUgc3RhcnREb2N1bWVudCgpLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiVHJhbnNmb3JtZXIiIGlzIGEgSmF2YSBpbnRlcmZhY2UgbmFtZSB0aGF0Ci0gICAgICAgICAqIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIEEgVHJhbnNmb3JtZXIgb2JqZWN0IHNob3VsZCBjb250YWluZWQgYQotICAgICAgICAgKiByZWZlcmVuY2UgdG8gYSB0cmFuc2xldCBvYmplY3QgaW4gb3JkZXIgdG8gYmUgdXNlZCBmb3IKLSAgICAgICAgICogdHJhbnNmb3JtYXRpb25zOyB0aGlzIG1lc3NhZ2UgaXMgcHJvZHVjZWQgaWYgdGhhdCByZXF1aXJlbWVudCBpcyBub3QKLSAgICAgICAgICogbWV0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfTk9fVFJBTlNMRVRfRVJSLAotICAgICAgICAiVHJhbnNmb3JtZXIgbm8gdGllbmUgdW4gb2JqZXRvIHRyYW5zbGV0IGVuY2Fwc3VsYWRvLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgWE1MIGRvY3VtZW50IHRoYXQgcmVzdWx0cyBmcm9tIGEKLSAgICAgICAgICogdHJhbnNmb3JtYXRpb24gbmVlZHMgdG8gYmUgc2VudCB0byBhbiBvdXRwdXQgaGFuZGxlciBvYmplY3Q7IHRoaXMKLSAgICAgICAgICogbWVzc2FnZSBpcyBwcm9kdWNlZCBpZiB0aGF0IHJlcXVpcmVtZW50IGlzIG5vdCBtZXQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSkFYUF9OT19IQU5ETEVSX0VSUiwKLSAgICAgICAgIk5vIHNlIGhhIGRlZmluaWRvIGVsIG1hbmVqYWRvciBkZSBzYWxpZGEgcGFyYSBlbCByZXN1bHRhZG8gZGUgbGEgdHJhbnNmb3JtYWNpXHUwMEYzbi4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIlJlc3VsdCIgaXMgYSBKYXZhIGludGVyZmFjZSBuYW1lIGluIHRoaXMKLSAgICAgICAgICogY29udGV4dC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyBhIG1ldGhvZCBuYW1lLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfTk9fUkVTVUxUX0VSUiwKLSAgICAgICAgIkVsIG9iamV0byBSZXN1bHQgcXVlIHNlIGhhIHBhc2FkbyBhICcnezB9Jycgbm8gZXMgdlx1MDBFMWxpZG8uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJUcmFuc2Zvcm1lciIgaXMgYSBKYXZhIGludGVyZmFjZSBuYW1lLiAgVGhlCi0gICAgICAgICAqIHVzZXIncyBwcm9ncmFtIGF0dGVtcHRlZCB0byBhY2Nlc3MgYW4gdW5yZWNvZ25pemVkIHByb3BlcnR5IHdpdGggdGhlCi0gICAgICAgICAqIG5hbWUgc3BlY2lmaWVkIGluIHRoZSBzdWJzdGl0dXRpb24gdGV4dC4gIFRoZSBtZXRob2QgdXNlZCB0byByZXRyaWV2ZQotICAgICAgICAgKiB0aGUgcHJvcGVydHkgaXMgImdldE91dHB1dFByb3BlcnR5Iiwgc28gaXQncyBub3QgY2xlYXIgd2hldGhlciBpdAotICAgICAgICAgKiB3b3VsZCBiZSBiZXN0IHRvIHRyYW5zbGF0ZSB0aGUgdGVybSAicHJvcGVydHkiLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfVU5LTk9XTl9QUk9QX0VSUiwKLSAgICAgICAgIlNlIGVzdFx1MDBFMSBpbnRlbnRhbmRvIGFjY2VkZXIgYSBsYSBwcm9waWVkYWQgJyd7MH0nJyBkZSBUcmFuc2Zvcm1lciBubyB2XHUwMEUxbGlkYS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgU0FYMkRPTSBpcyB0aGUgbmFtZSBvZiBhIEphdmEgY2xhc3MgdGhhdCBzaG91bGQKLSAgICAgICAgICogbm90IGJlIHRyYW5zbGF0ZWQuICBUaGlzIGlzIGFuIGFkYXB0ZXIgaW4gdGhlIHNlbnNlIHRoYXQgaXQgdGFrZXMgYQotICAgICAgICAgKiBET00gb2JqZWN0IGFuZCBjb252ZXJ0cyBpdCB0byBzb21ldGhpbmcgdGhhdCB1c2VzIHRoZSBTQVggQVBJLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlNBWDJET01fQURBUFRFUl9FUlIsCi0gICAgICAgICJObyBzZSBoYSBwb2RpZG8gY3JlYXIgZWwgYWRhcHRhZG9yIFNBWDJET006ICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJYU0xUQ1NvdXJjZS5idWlsZCgpIiBpcyBhIEphdmEgbWV0aG9kIG5hbWUuCi0gICAgICAgICAqICJzeXN0ZW1JZCIgaXMgYW4gWE1MIHRlcm0gdGhhdCBpcyBzaG9ydCBmb3IgInN5c3RlbSBpZGVudGlmaWNhdGlvbiIuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuWFNMVENfU09VUkNFX0VSUiwKLSAgICAgICAgIlNlIGhhIGxsYW1hZG8gYSBYU0xUQ1NvdXJjZS5idWlsZCgpIHNpbiBoYWJlciBkZWZpbmlkbyBsYSBpZGVudGlmaWNhY2lcdTAwRjNuIGRlbCBzaXN0ZW1hLiJ9LAotCi0gICAgICAgIHsgRXJyb3JNc2cuRVJfUkVTVUxUX05VTEwsCi0gICAgICAgICAgICAiRWwgcmVzdWx0YWRvIG5vIGRlYmUgc2VyIG51bG8ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoZSB2YWx1ZSBhcmd1bWVudAotICAgICAgICAgKiBvZiBzZXRQYXJhbWV0ZXIgbXVzdCBiZSBhIHZhbGlkIEphdmEgT2JqZWN0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfSU5WQUxJRF9TRVRfUEFSQU1fVkFMVUUsCi0gICAgICAgICJFbCB2YWxvciBkZWwgcGFyXHUwMEUxbWV0cm8gezB9IGRlYmUgc2VyIHVuIG9iamV0byBKYXZhIHZcdTAwRTFsaWRvIn0sCi0KLQotICAgICAgICB7RXJyb3JNc2cuQ09NUElMRV9TVERJTl9FUlIsCi0gICAgICAgICJMYSBvcGNpXHUwMEYzbiAtaSBkZWJlIHV0aWxpemFyc2UgY29uIGxhIG9wY2lcdTAwRjNuIC1vLiJ9LAotCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBjb250YWlucyB1c2FnZSBpbmZvcm1hdGlvbiBmb3IgYQotICAgICAgICAgKiBtZWFucyBvZiBpbnZva2luZyBYU0xUQyBmcm9tIHRoZSBjb21tYW5kLWxpbmUuICBUaGUgbWVzc2FnZSBpcwotICAgICAgICAgKiBmb3JtYXR0ZWQgZm9yIHByZXNlbnRhdGlvbiBpbiBFbmdsaXNoLiAgVGhlIHN0cmluZ3MgPG91dHB1dD4sCi0gICAgICAgICAqIDxkaXJlY3Rvcnk+LCBldGMuIGluZGljYXRlIHVzZXItc3BlY2lmaWVkIGFyZ3VtZW50IHZhbHVlcywgYW5kIGNhbgotICAgICAgICAgKiBiZSB0cmFuc2xhdGVkIC0gdGhlIGFyZ3VtZW50IDxwYWNrYWdlPiByZWZlcnMgdG8gYSBKYXZhIHBhY2thZ2UsIHNvCi0gICAgICAgICAqIGl0IHNob3VsZCBiZSBoYW5kbGVkIGluIHRoZSBzYW1lIHdheSB0aGUgdGVybSBpcyBoYW5kbGVkIGZvciBKREsKLSAgICAgICAgICogZG9jdW1lbnRhdGlvbi4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5DT01QSUxFX1VTQUdFX1NUUiwKLSAgICAgICAgIlNJTk9QU0lTXG4gICBqYXZhIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jbWRsaW5lLkNvbXBpbGUgWy1vIDxzYWxpZGE+XVxuICAgICAgWy1kIDxkaXJlY3RvcmlvPl0gWy1qIDxhcmNoaXZvIGphcj5dIFstcCA8cGFxdWV0ZT5dXG4gICAgICBbLW5dIFsteF0gWy11XSBbLXZdIFstaF0geyA8aG9qYSBkZSBlc3RpbG8+IHwgLWkgfVxuXG5PUENJT05FU1xuICAgLW8gPHNhbGlkYT4gICAgYXNpZ25hIGVsIG5vbWJyZSBkZSA8c2FsaWRhPiBhbCB0cmFuc2xldFxuICAgICAgICAgICAgICAgICAgZ2VuZXJhZG8uIFBvciBkZWZlY3RvLCBlbCBub21icmUgZGVsIHRyYW5zbGV0IHNlXG4gICAgICAgICAgICAgICAgICBkZXJpdmEgZGVsIG5vbWJyZSBkZSA8aG9qYSBkZSBlc3RpbG8+LiBFc3RhIG9wY2lcdTAwRjNuXG4gICAgICAgICAgICAgICAgICBzZSBpZ25vcmEgc2kgc2UgY29tcGlsYW4gdmFyaWFzIGhvamFzIGRlIGVzdGlsby5cbiAgIC1kIDxkaXJlY3RvcmlvPiBlc3BlY2lmaWNhIHVuIGRpcmVjdG9yaW8gZGUgZGVzdGlubyBwYXJhIGVsIHRyYW5zbGV0XG4gICAtaiA8YXJjaGl2byBqYXI+ICAgZW1wYXF1ZXRhIGxhcyBjbGFzZXMgZGUgdHJhbnNsZXQgZW4gdW4gYXJjaGl2byBqYXIgZGVsXG4gICAgICAgICAgICAgICAgICBub21icmUgZXNwZWNpZmljYWRvIGNvbW8gPGFyY2hpdm8gamFyPlxuICAgLXAgPHBhcXVldGU+ICAgZXNwZWNpZmljYSB1biBwcmVmaWpvIGRlIG5vbWJyZSBkZSBwYXF1ZXRlIHBhcmEgdG9kYXMgbGFzIGNsYXNlcyBkZSB0cmFuc2xldCBuXG4gICAgICAgICAgICAgICAgICBnZW5lcmFkYXMuXG4gICAtbiAgICAgICAgICAgICBwZXJtaXRlIHBvbmVyIGVuIGxcdTAwRURuZWEgbGEgcGxhbnRpbGxhIChjb21wb3J0YW1pZW50byBwb3IgZGVmZWN0byBtZWpvclxuICAgICAgICAgICAgICAgICAgc29icmUgbGEgbWVkaWEpLlxuICAgLXggICAgICAgICAgICAgYWN0aXZhIGxhIHNhbGlkYSBkZWwgbWVuc2FqZSBkZSBkZXB1cmFjaVx1MDBGM25cbiAgIC11ICAgICAgICAgICAgIGludGVycHJldGEgbG9zIGFyZ3VtZW50b3MgPGhvamEgZGUgZXN0aWxvPiBjb21vIFVSTFxuICAgLWkgICAgICAgICAgICAgb2JsaWdhIGFsIGNvbXBpbGFkb3IgYSBsZWVyIGxhIGhvamEgZGUgZXN0aWxvIGRlIHN0ZGluXG4gICAtdiAgICAgICAgICAgICBpbXByaW1lIGxhIHZlcnNpXHUwMEYzbiBkZWwgY29tcGlsYWRvclxuICAgLWggICAgICAgICAgICAgaW1wcmltZSBlc3RhIHNlbnRlbmNpYSBkZSB1c29cbiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgY29udGFpbnMgdXNhZ2UgaW5mb3JtYXRpb24gZm9yIGEKLSAgICAgICAgICogbWVhbnMgb2YgaW52b2tpbmcgWFNMVEMgZnJvbSB0aGUgY29tbWFuZC1saW5lLiAgVGhlIG1lc3NhZ2UgaXMKLSAgICAgICAgICogZm9ybWF0dGVkIGZvciBwcmVzZW50YXRpb24gaW4gRW5nbGlzaC4gIFRoZSBzdHJpbmdzIDxqYXJmaWxlPiwKLSAgICAgICAgICogPGRvY3VtZW50PiwgZXRjLiBpbmRpY2F0ZSB1c2VyLXNwZWNpZmllZCBhcmd1bWVudCB2YWx1ZXMsIGFuZCBjYW4KLSAgICAgICAgICogYmUgdHJhbnNsYXRlZCAtIHRoZSBhcmd1bWVudCA8Y2xhc3M+IHJlZmVycyB0byBhIEphdmEgY2xhc3MsIHNvIGl0Ci0gICAgICAgICAqIHNob3VsZCBiZSBoYW5kbGVkIGluIHRoZSBzYW1lIHdheSB0aGUgdGVybSBpcyBoYW5kbGVkIGZvciBKREsKLSAgICAgICAgICogZG9jdW1lbnRhdGlvbi4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5UUkFOU0ZPUk1fVVNBR0VfU1RSLAotICAgICAgICAiU1lOT1BTSVMgXG4gICBqYXZhIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jbWRsaW5lLlRyYW5zZm9ybSBbLWogPGFyY2hpdm8gamFyPl1cbiAgICAgIFsteF0gWy1uIDxpdGVyYWNpb25lcz5dIHstdSA8dXJsX2RvY3VtZW50bz4gfCA8ZG9jdW1lbnRvPn1cbiAgICAgIDxjbGFzZT4gWzxwYXJcdTAwRTFtZXRybzE+PTx2YWxvcjE+IC4uLl1cblxuICAgdXRpbGl6YSBlbCB0cmFuc2xldCA8Y2xhc2U+IHBhcmEgdHJhbnNmb3JtYXIgdW4gZG9jdW1lbnRvIFhNTCBcbiAgIGVzcGVjaWZpY2FkbyBjb21vIDxkb2N1bWVudG8+LiBFbCB0cmFuc2xldCA8Y2xhc2U+IHNlIGVuY3VlbnRyYSBlblxuICAgbGEgQ0xBU1NQQVRIIGRlbCB1c3VhcmlvIG8gZW4gZWwgPGFyY2hpdm8gamFyPiBlc3BlY2lmaWNhZG8gb3BjaW9uYWxtZW50ZS5cbk9QQ0lPTkVTXG4gICAtaiA8YXJjaGl2byBqYXI+ICAgIGVzcGVjaWZpY2EgdW4gYXJjaGl2byBqYXIgZGVzZGUgZWwgcXVlIGNhcmdhciBlbCB0cmFuc2xldFxuICAgLXggICAgICAgICAgICAgIGFjdGl2YSBsYSBzYWxpZGEgZGVsIG1lbnNhamUgZGUgZGVwdXJhY2lcdTAwRjNuIGFkaWNpb25hbFxuICAgLW4gPGl0ZXJhY2lvbmVzPiBlamVjdXRhIGVsIG5cdTAwRkFtZXJvIGRlIDxpdGVyYWNpb25lcz4gZGUgdW5hIHRyYW5zZm9ybWFjaVx1MDBGM24geVxuICAgICAgICAgICAgICAgICAgIG11ZXN0cmEgbGEgaW5mb3JtYWNpXHUwMEYzbiBkZSBsYSBjcmVhY2lcdTAwRjNuIGRlIHBlcmZpbFxuICAgLXUgPHVybF9kb2N1bWVudG8+IGVzcGVjaWZpY2EgZWwgZG9jdW1lbnRvIGRlIGVudHJhZGEgWE1MIGNvbW8gdW5hIFVSTFxuIn0sCi0KLQotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiPHhzbDpzb3J0PiIsICI8eHNsOmZvci1lYWNoPiIgYW5kCi0gICAgICAgICAqICI8eHNsOmFwcGx5LXRlbXBsYXRlcz4iIGFyZSBrZXl3b3JkcyB0aGF0IHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICAgICAgICogVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgYW4geHNsOnNvcnQgZWxlbWVudCBtdXN0IGJlIGEgY2hpbGQgb2YKLSAgICAgICAgICogb25lIG9mIHRoZSBvdGhlciBraW5kcyBvZiBlbGVtZW50cyBtZW50aW9uZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuU1RSQVlfU09SVF9FUlIsCi0gICAgICAgICI8eHNsOnNvcnQ+IHNcdTAwRjNsbyBzZSBwdWVkZSB1dGlsaXphciBlbiA8eHNsOmZvci1lYWNoPiBvIDx4c2w6YXBwbHktdGVtcGxhdGVzPi4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhlIGVuY29kaW5nCi0gICAgICAgICAqIHJlcXVlc3RlZCBmb3IgdGhlIG91dHB1dCBkb2N1bWVudCB3YXMgb24gdGhhdCByZXF1aXJlcyBzdXBwb3J0IHRoYXQKLSAgICAgICAgICogaXMgbm90IGF2YWlsYWJsZSBmcm9tIHRoZSBKYXZhIFZpcnR1YWwgTWFjaGluZSBiZWluZyB1c2VkIHRvIGV4ZWN1dGUKLSAgICAgICAgICogdGhlIHByb2dyYW0uCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVU5TVVBQT1JURURfRU5DT0RJTkcsCi0gICAgICAgICJMYSBjb2RpZmljYWNpXHUwMEYzbiBkZSBzYWxpZGEgJyd7MH0nJyBubyBlc3RcdTAwRTEgc29wb3J0YWRhIGVuIGVzdGEgSlZNLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUgWFBhdGggZXhwcmVzc2lvbgotICAgICAgICAgKiBuYW1lZCBpbiB0aGUgc3Vic3RpdHV0aW9uIHRleHQgd2FzIG5vdCB3ZWxsIGZvcm1lZCBzeW50YWN0aWNhbGx5LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlNZTlRBWF9FUlIsCi0gICAgICAgICJFcnJvciBkZSBzaW50YXhpcyBlbiAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYSBKYXZhCi0gICAgICAgICAqIGNsYXNzLiAgVGhlIHRlcm0gImNvbnN0cnVjdG9yIiBoZXJlIGlzIHRoZSBKYXZhIHRlcm0uICBUaGUgbWVzc2FnZSBpcwotICAgICAgICAgKiBkaXNwbGF5ZWQgaWYgWFNMVEMgY291bGQgbm90IGZpbmQgYSBjb25zdHJ1Y3RvciBmb3IgdGhlIHNwZWNpZmllZAotICAgICAgICAgKiBjbGFzcy4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5DT05TVFJVQ1RPUl9OT1RfRk9VTkQsCi0gICAgICAgICJObyBzZSBoYSBlbmNvbnRyYWRvIGVsIGNvbnN0cnVjdG9yIGV4dGVybm8gJyd7MH0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgInN0YXRpYyIgaXMgdGhlIEphdmEga2V5d29yZC4gIFRoZSBzdWJzdGl0dXRpb24KLSAgICAgICAgICogdGV4dCBpcyB0aGUgbmFtZSBvZiBhIGZ1bmN0aW9uLiAgVGhlIGZpcnN0IGFyZ3VtZW50IG9mIHRoYXQgZnVuY3Rpb24KLSAgICAgICAgICogaXMgbm90IG9mIHRoZSByZXF1aXJlZCB0eXBlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk5PX0pBVkFfRlVOQ1RfVEhJU19SRUYsCi0gICAgICAgICJFbCBwcmltZXIgYXJndW1lbnRvIGRlIGxhIGZ1bmNpXHUwMEYzbiBKYXZhIG5vIGVzdFx1MDBFMXRpY2EgJyd7MH0nJyBubyBlcyB1bmEgcmVmZXJlbmNpYSBkZSBvYmpldG8gdlx1MDBFMWxpZGEuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIFhQYXRoIGV4cHJlc3Npb24gd2FzIG5vdCBvZiB0aGUgdHlwZQotICAgICAgICAgKiByZXF1aXJlZCBpbiBhIHBhcnRpY3VsYXIgY29udGV4dC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUKLSAgICAgICAgICogZXhwcmVzc2lvbiB0aGF0IHdhcyBpbiBlcnJvci4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5UWVBFX0NIRUNLX0VSUiwKLSAgICAgICAgIkVycm9yIGFsIGNvbXByb2JhciBlbCB0aXBvIGRlIGxhIGV4cHJlc2lcdTAwRjNuICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIFhQYXRoIGV4cHJlc3Npb24gd2FzIG5vdCBvZiB0aGUgdHlwZQotICAgICAgICAgKiByZXF1aXJlZCBpbiBhIHBhcnRpY3VsYXIgY29udGV4dC4gIEhvd2V2ZXIsIHRoZSBsb2NhdGlvbiBvZiB0aGUKLSAgICAgICAgICogcHJvYmxlbWF0aWMgZXhwcmVzc2lvbiBpcyB1bmtub3duLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlRZUEVfQ0hFQ0tfVU5LX0xPQ19FUlIsCi0gICAgICAgICJFcnJvciBhbCBjb21wcm9iYXIgZWwgdGlwbyBkZSB1bmEgZXhwcmVzaVx1MDBGM24gZW4gdW5hIHViaWNhY2lcdTAwRjNuIGRlc2Nvbm9jaWRhLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYSBjb21tYW5kLQotICAgICAgICAgKiBsaW5lIG9wdGlvbiB0aGF0IHdhcyBub3QgcmVjb2duaXplZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTExFR0FMX0NNRExJTkVfT1BUSU9OX0VSUiwKLSAgICAgICAgIkxhIG9wY2lcdTAwRjNuIGRlIGxcdTAwRURuZWEgZGUgY29tYW5kb3MgJyd7MH0nJyBubyBlcyB2XHUwMEUxbGlkYS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIGEgY29tbWFuZC0KLSAgICAgICAgICogbGluZSBvcHRpb24uCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuQ01ETElORV9PUFRfTUlTU0lOR19BUkdfRVJSLAotICAgICAgICAiRmFsdGEgdW4gYXJndW1lbnRvIG5lY2VzYXJpbyBlbiBsYSBvcGNpXHUwMEYzbiBkZSBsXHUwMEVEbmVhIGRlIGNvbWFuZG9zICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyB1c2VkIHRvIGluZGljYXRlIHRoZSBzZXZlcml0eQotICAgICAgICAgKiBvZiBhbm90aGVyIG1lc3NhZ2UuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgY29udGFpbnMgdHdvIGVycm9yCi0gICAgICAgICAqIG1lc3NhZ2VzLiAgVGhlIHNwYWNpbmcgYmVmb3JlIHRoZSBzZWNvbmQgc3Vic3RpdHV0aW9uIHRleHQgaW5kZW50cwotICAgICAgICAgKiBpdCB0aGUgc2FtZSBhbW91bnQgYXMgdGhlIGZpcnN0IGluIEVuZ2xpc2guCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuV0FSTklOR19QTFVTX1dSQVBQRURfTVNHLAotICAgICAgICAiV0FSTklORzogICcnezB9JydcbiAgICAgICA6ezF9In0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyB1c2VkIHRvIGluZGljYXRlIHRoZSBzZXZlcml0eQotICAgICAgICAgKiBvZiBhbm90aGVyIG1lc3NhZ2UuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgYW4gZXJyb3IgbWVzc2FnZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5XQVJOSU5HX01TRywKLSAgICAgICAgIldBUk5JTkc6ICAnJ3swfScnIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyB1c2VkIHRvIGluZGljYXRlIHRoZSBzZXZlcml0eQotICAgICAgICAgKiBvZiBhbm90aGVyIG1lc3NhZ2UuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgY29udGFpbnMgdHdvIGVycm9yCi0gICAgICAgICAqIG1lc3NhZ2VzLiAgVGhlIHNwYWNpbmcgYmVmb3JlIHRoZSBzZWNvbmQgc3Vic3RpdHV0aW9uIHRleHQgaW5kZW50cwotICAgICAgICAgKiBpdCB0aGUgc2FtZSBhbW91bnQgYXMgdGhlIGZpcnN0IGluIEVuZ2xpc2guCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuRkFUQUxfRVJSX1BMVVNfV1JBUFBFRF9NU0csCi0gICAgICAgICJGQVRBTCBFUlJPUjogICcnezB9JydcbiAgICAgICAgICAgOnsxfSJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgdXNlZCB0byBpbmRpY2F0ZSB0aGUgc2V2ZXJpdHkKLSAgICAgICAgICogb2YgYW5vdGhlciBtZXNzYWdlLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIGFuIGVycm9yIG1lc3NhZ2UuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuRkFUQUxfRVJSX01TRywKLSAgICAgICAgIkZBVEFMIEVSUk9SOiAgJyd7MH0nJyJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgdXNlZCB0byBpbmRpY2F0ZSB0aGUgc2V2ZXJpdHkKLSAgICAgICAgICogb2YgYW5vdGhlciBtZXNzYWdlLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGNvbnRhaW5zIHR3byBlcnJvcgotICAgICAgICAgKiBtZXNzYWdlcy4gIFRoZSBzcGFjaW5nIGJlZm9yZSB0aGUgc2Vjb25kIHN1YnN0aXR1dGlvbiB0ZXh0IGluZGVudHMKLSAgICAgICAgICogaXQgdGhlIHNhbWUgYW1vdW50IGFzIHRoZSBmaXJzdCBpbiBFbmdsaXNoLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkVSUk9SX1BMVVNfV1JBUFBFRF9NU0csCi0gICAgICAgICJFUlJPUjogICcnezB9JydcbiAgICAgOnsxfSJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgdXNlZCB0byBpbmRpY2F0ZSB0aGUgc2V2ZXJpdHkKLSAgICAgICAgICogb2YgYW5vdGhlciBtZXNzYWdlLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIGFuIGVycm9yIG1lc3NhZ2UuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuRVJST1JfTVNHLAotICAgICAgICAiRVJST1I6ICAnJ3swfScnIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBhIGNsYXNzLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlRSQU5TRk9STV9XSVRIX1RSQU5TTEVUX1NUUiwKLSAgICAgICAgIlRyYW5zZm9ybWFjaVx1MDBGM24gcXVlIHV0aWxpemEgZWwgdHJhbnNsZXQgJyd7MH0nJyAifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZpcnN0IHN1YnN0aXR1dGlvbiBpcyB0aGUgbmFtZSBvZiBhIGNsYXNzLAotICAgICAgICAgKiB3aGlsZSB0aGUgc2Vjb25kIHN1YnN0aXR1dGlvbiBpcyB0aGUgbmFtZSBvZiBhIGphciBmaWxlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlRSQU5TRk9STV9XSVRIX0pBUl9TVFIsCi0gICAgICAgICJUcmFuc2Zvcm1hY2lcdTAwRjNuIHF1ZSB1dGlsaXphIGVsIHRyYW5zbGV0ICcnezB9JycgZGVsIGFyY2hpdm8gamFyICcnezF9JycifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIlRyYW5zZm9ybWVyRmFjdG9yeSIgaXMgdGhlIG5hbWUgb2YgYSBKYXZhCi0gICAgICAgICAqIGludGVyZmFjZSBhbmQgbXVzdCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcwotICAgICAgICAgKiB0aGUgbmFtZSBvZiB0aGUgY2xhc3MgdGhhdCBjb3VsZCBub3QgYmUgaW5zdGFudGlhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkNPVUxEX05PVF9DUkVBVEVfVFJBTlNfRkFDVCwKLSAgICAgICAgIk5vIHNlIGhhIHBvZGlkbyBjcmVhciB1bmEgaW5zdGFuY2lhIGRlIGxhIGNsYXNlIFRyYW5zZm9ybWVyRmFjdG9yeSAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgcHJvZHVjZWQgd2hlbiB0aGUgdXNlcgotICAgICAgICAgKiBzcGVjaWZpZWQgYSBuYW1lIGZvciB0aGUgdHJhbnNsZXQgY2xhc3MgdGhhdCBjb250YWlucyBjaGFyYWN0ZXJzCi0gICAgICAgICAqIHRoYXQgYXJlIG5vdCBwZXJtaXR0ZWQgaW4gYSBKYXZhIGNsYXNzIG5hbWUuICBUaGUgc3Vic3RpdHV0aW9uCi0gICAgICAgICAqIHRleHQgInswfSIgc3BlY2lmaWVzIHRoZSBuYW1lIHRoZSB1c2VyIHJlcXVlc3RlZCwgd2hpbGUgInsxfSIKLSAgICAgICAgICogc3BlY2lmaWVzIHRoZSBuYW1lIHRoZSBwcm9jZXNzb3IgdXNlZCBpbnN0ZWFkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlRSQU5TTEVUX05BTUVfSkFWQV9DT05GTElDVCwKLSAgICAgICAgICJFbCBub21icmUgJyd7MH0nJyBubyBzZSBoYSBwb2RpZG8gdXRpbGl6YXIgY29tbyBlbCBub21icmUgZGUgbGEgY2xhc2UgZGUgdHJhbnNsZXQgcG9ycXVlIGNvbnRpZW5lIGNhcmFjdGVyZXMgcXVlIG5vIGVzdFx1MDBFMW4gcGVybWl0aWRvcyBlbiBlbCBub21icmUgZGUgbGEgY2xhc2UgSmF2YS4gU2UgaGEgdXRpbGl6YWRvIGVsIG5vbWJyZSAnJ3sxfScnIGVuIHN1IGx1Z2FyLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgaXMgdXNlZCBhcyBhIGhlYWRlci4KLSAgICAgICAgICogQWxsIHRoZSBlcnJvciBtZXNzYWdlcyBhcmUgY29sbGVjdGVkIHRvZ2V0aGVyIGFuZCBkaXNwbGF5ZWQgYmVuZWF0aAotICAgICAgICAgKiB0aGlzIG1lc3NhZ2UuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuQ09NUElMRVJfRVJST1JfS0VZLAotICAgICAgICAiRXJyb3JlcyBkZWwgY29tcGlsYWRvcjoifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIGlzIHVzZWQgYXMgYSBoZWFkZXIuCi0gICAgICAgICAqIEFsbCB0aGUgd2FybmluZyBtZXNzYWdlcyBhcmUgY29sbGVjdGVkIHRvZ2V0aGVyIGFuZCBkaXNwbGF5ZWQKLSAgICAgICAgICogYmVuZWF0aCB0aGlzIG1lc3NhZ2UuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuQ09NUElMRVJfV0FSTklOR19LRVksCi0gICAgICAgICJBZHZlcnRlbmNpYXMgZGVsIGNvbXBpbGFkb3I6In0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBpcyB1c2VkIGFzIGEgaGVhZGVyLgotICAgICAgICAgKiBBbGwgdGhlIGVycm9yIG1lc3NhZ2VzIHRoYXQgYXJlIHByb2R1Y2VkIHdoZW4gdGhlIHN0eWxlc2hlZXQgaXMKLSAgICAgICAgICogYXBwbGllZCB0byBhbiBpbnB1dCBkb2N1bWVudCBhcmUgY29sbGVjdGVkIHRvZ2V0aGVyIGFuZCBkaXNwbGF5ZWQKLSAgICAgICAgICogYmVuZWF0aCB0aGlzIG1lc3NhZ2UuICBBICd0cmFuc2xldCcgaXMgdGhlIGNvbXBpbGVkIGZvcm0gb2YgYQotICAgICAgICAgKiBzdHlsZXNoZWV0IChzZWUgYWJvdmUpLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlJVTlRJTUVfRVJST1JfS0VZLAotICAgICAgICAiRXJyb3JlcyBkZWwgdHJhbnNsZXQ6In0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIGF0dHJpYnV0ZSB3aG9zZSB2YWx1ZSBpcyBjb25zdHJhaW5lZCB0bwotICAgICAgICAgKiBiZSBhICJRTmFtZSIgb3IgYSBsaXN0IG9mICJRTmFtZXMiIGhhZCBhIHZhbHVlIHRoYXQgd2FzIGluY29ycmVjdC4KLSAgICAgICAgICogJ1FOYW1lJyBpcyBhbiBYTUwgc3ludGFjdGljIHRlcm0gdGhhdCBtdXN0IG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhlCi0gICAgICAgICAqIHN1YnN0aXR1dGlvbiB0ZXh0IGNvbnRhaW5zIHRoZSBhY3R1YWwgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTlZBTElEX1FOQU1FX0VSUiwKLSAgICAgICAgIlVuIGF0cmlidXRvIGN1eW8gdmFsb3IgZGViZSBzZXIgdW4gUU5hbWUgbyBsaXN0YSBkZSBRTmFtZXMgc2VwYXJhZG9zIHBvciBlc3BhY2lvcyBlbiBibGFuY28gdGVuXHUwMEVEYSBlbCB2YWxvciAnJ3swfScnIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIGF0dHJpYnV0ZSB3aG9zZSB2YWx1ZSBpcyByZXF1aXJlZCB0bwotICAgICAgICAgKiBiZSBhbiAiTkNOYW1lIi4KLSAgICAgICAgICogJ05DTmFtZScgaXMgYW4gWE1MIHN5bnRhY3RpYyB0ZXJtIHRoYXQgbXVzdCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoZQotICAgICAgICAgKiBzdWJzdGl0dXRpb24gdGV4dCBjb250YWlucyB0aGUgYWN0dWFsIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSU5WQUxJRF9OQ05BTUVfRVJSLAotICAgICAgICAiVW4gYXRyaWJ1dG8gY3V5byB2YWxvciBkZWJlIHNlciB1biBOQ05hbWUgdGVuXHUwMEVEYSBlbCB2YWxvciAnJ3swfScnIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIGF0dHJpYnV0ZSB3aXRoIGFuIGluY29ycmVjdCB2YWx1ZSB3YXMKLSAgICAgICAgICogZW5jb3VudGVyZWQuICBUaGUgcGVybWl0dGVkIHZhbHVlIGlzIG9uZSBvZiB0aGUgbGl0ZXJhbCB2YWx1ZXMKLSAgICAgICAgICogInhtbCIsICJodG1sIiBvciAidGV4dCI7IGl0IGlzIGFsc28gcGVybWl0dGVkIHRvIGhhdmUgdGhlIGZvcm0gb2YKLSAgICAgICAgICogYSBRTmFtZSB0aGF0IGlzIG5vdCBhbHNvIGFuIE5DTmFtZS4gIFRoZSB0ZXJtcyAibWV0aG9kIiwKLSAgICAgICAgICogInhzbDpvdXRwdXQiLCAieG1sIiwgImh0bWwiIGFuZCAidGV4dCIgYXJlIGtleXdvcmRzIHRoYXQgbXVzdCBub3QKLSAgICAgICAgICogYmUgdHJhbnNsYXRlZC4gIFRoZSB0ZXJtICJxbmFtZS1idXQtbm90LW5jbmFtZSIgaXMgYW4gWE1MIHN5bnRhY3RpYwotICAgICAgICAgKiB0ZXJtLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGNvbnRhaW5zIHRoZSBhY3R1YWwgdmFsdWUgb2YgdGhlCi0gICAgICAgICAqIGF0dHJpYnV0ZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTlZBTElEX01FVEhPRF9JTl9PVVRQVVQsCi0gICAgICAgICJFbCBhdHJpYnV0byBtZXRob2QgZGUgdW4gZWxlbWVudG8gPHhzbDpvdXRwdXQ+IHRlblx1MDBFRGEgZWwgdmFsb3IgJyd7MH0nJy4gRWwgdmFsb3IgZGViZSBzZXIgJyd4bWwnJywgJydodG1sJycsICcndGV4dCcnIG8gcW5hbWUtYnV0LW5vdC1uY25hbWUifSwKLQotICAgICAgICB7RXJyb3JNc2cuSkFYUF9HRVRfRkVBVFVSRV9OVUxMX05BTUUsCi0gICAgICAgICJFbCBub21icmUgZGUgZnVuY2lcdTAwRjNuIG5vIHB1ZWRlIHNlciBudWxvIGVuIFRyYW5zZm9ybWVyRmFjdG9yeS5nZXRGZWF0dXJlIChub21icmUgZGUgY2FkZW5hKS4ifSwKLQotICAgICAgICB7RXJyb3JNc2cuSkFYUF9TRVRfRkVBVFVSRV9OVUxMX05BTUUsCi0gICAgICAgICJFbCBub21icmUgZGUgZnVuY2lcdTAwRjNuIG5vIHB1ZWRlIHNlciBudWxvIGVuIFRyYW5zZm9ybWVyRmFjdG9yeS5zZXRGZWF0dXJlIChub21icmUgZGUgY2FkZW5hLCB2YWxvciBib29sZWFubykuIn0sCi0KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfVU5TVVBQT1JURURfRkVBVFVSRSwKLSAgICAgICAgIk5vIHNlIHB1ZWRlIGRlZmluaXIgbGEgZnVuY2lcdTAwRjNuICcnezB9JydlbiBlc3RhIGZcdTAwRTFicmljYSBkZWwgdHJhbnNmb3JtYWRvci4ifSwKLQotICAgICAgICB7RXJyb3JNc2cuSkFYUF9TRUNVUkVQUk9DRVNTSU5HX0ZFQVRVUkUsCi0gICAgICAgICJGRUFUVVJFX1NFQ1VSRV9QUk9DRVNTSU5HOiBubyBzZSBwdWVkZSBkZWZpbmlyIGxhIGZ1bmNpXHUwMEYzbiBlbiBmYWxzZSBjdWFuZG8gZXN0XHUwMEUxIHByZXNlbnRlIGVsIGdlc3RvciBkZSBzZWd1cmlkYWQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBkZXNjcmliZXMgYW4gaW50ZXJuYWwgZXJyb3IgaW4gdGhlCi0gICAgICAgICAqIHByb2Nlc3Nvci4gIFRoZSB0ZXJtICJieXRlIGNvZGUiIGlzIGEgSmF2YSB0ZWNobmljYWwgdGVybSBmb3IgdGhlCi0gICAgICAgICAqIGV4ZWN1dGFibGUgY29kZSBpbiBhIEphdmEgbWV0aG9kLCBhbmQgInRyeS1jYXRjaC1maW5hbGx5IGJsb2NrIgotICAgICAgICAgKiByZWZlcnMgdG8gdGhlIEphdmEga2V5d29yZHMgd2l0aCB0aG9zZSBuYW1lcy4gICJPdXRsaW5lZCIgaXMgYQotICAgICAgICAgKiB0ZWNobmljYWwgdGVybSBpbnRlcm5hbCB0byBYU0xUQyBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk9VVExJTkVfRVJSX1RSWV9DQVRDSCwKLSAgICAgICAgICJFcnJvciBpbnRlcm5vIGRlIFhTTFRDOiBlbCBjXHUwMEYzZGlnbyBkZSBieXRlcyBnZW5lcmFkbyBjb250aWVuZSB1biBibG9xdWUgdHJ5LWNhdGNoLWZpbmFsbHkgeSBubyBzZSBwdWVkZSBkZWxpbWl0YXIuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBkZXNjcmliZXMgYW4gaW50ZXJuYWwgZXJyb3IgaW4gdGhlCi0gICAgICAgICAqIHByb2Nlc3Nvci4gIFRoZSB0ZXJtcyAiT3V0bGluZWFibGVDaHVua1N0YXJ0IiBhbmQKLSAgICAgICAgICogIk91dGxpbmVhYmxlQ2h1bmtFbmQiIGFyZSB0aGUgbmFtZXMgb2YgY2xhc3NlcyBpbnRlcm5hbCB0byBYU0xUQyBhbmQKLSAgICAgICAgICogc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgZm9yIGV2ZXJ5Ci0gICAgICAgICAqICJzdGFydCIgdGhlcmUgbXVzdCBiZSBhIGNvcnJlc3BvbmRpbmcgImVuZCIsIGFuZCB2aWNlIHZlcnNhLCBhbmQKLSAgICAgICAgICogdGhhdCBpZiBvbmUgb2YgYSBwYWlyIG9mICJzdGFydCIgYW5kICJlbmQiIGFwcGVhcnMgYmV0d2VlbiBhbm90aGVyCi0gICAgICAgICAqIHBhaXIgb2YgY29ycmVzcG9uZGluZyAic3RhcnQiIGFuZCAiZW5kIiwgdGhlbiB0aGUgb3RoZXIgaGFsZiBvZiB0aGUKLSAgICAgICAgICogcGFpciBtdXN0IGFsc28gYmUgYmV0d2VlbiB0aGF0IHNhbWUgZW5jbG9zaW5nIHBhaXIuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuT1VUTElORV9FUlJfVU5CQUxBTkNFRF9NQVJLRVJTLAotICAgICAgICAgIkVycm9yIGludGVybm8gZGUgWFNMVEM6IGxvcyBtYXJjYWRvcmVzIE91dGxpbmVhYmxlQ2h1bmtTdGFydCB5IE91dGxpbmVhYmxlQ2h1bmtFbmQgZGViZW4gZXN0YXIgZXF1aWxpYnJhZG9zIHkgY29ycmVjdGFtZW50ZSBhbmlkYWRvcy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGRlc2NyaWJlcyBhbiBpbnRlcm5hbCBlcnJvciBpbiB0aGUKLSAgICAgICAgICogcHJvY2Vzc29yLiAgVGhlIHRlcm0gImJ5dGUgY29kZSIgaXMgYSBKYXZhIHRlY2huaWNhbCB0ZXJtIGZvciB0aGUKLSAgICAgICAgICogZXhlY3V0YWJsZSBjb2RlIGluIGEgSmF2YSBtZXRob2QuICBUaGUgIm1ldGhvZCIgdGhhdCBpcyBiZWluZwotICAgICAgICAgKiByZWZlcnJlZCB0byBpcyBhIEphdmEgbWV0aG9kIGluIGEgdHJhbnNsZXQgdGhhdCBYU0xUQyBpcyBnZW5lcmF0aW5nCi0gICAgICAgICAqIGluIHByb2Nlc3NpbmcgYSBzdHlsZXNoZWV0LiAgVGhlICJpbnN0cnVjdGlvbiIgdGhhdCBpcyBiZWluZwotICAgICAgICAgKiByZWZlcnJlZCB0byBpcyBvbmUgb2YgdGhlIGluc3RydXRpb25zIGluIHRoZSBKYXZhIGJ5dGUgY29kZSBpbiB0aGF0Ci0gICAgICAgICAqIG1ldGhvZC4gICJPdXRsaW5lZCIgaXMgYSB0ZWNobmljYWwgdGVybSBpbnRlcm5hbCB0byBYU0xUQyBhbmQKLSAgICAgICAgICogc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk9VVExJTkVfRVJSX0RFTEVURURfVEFSR0VULAotICAgICAgICAgIkVycm9yIGludGVybm8gZGUgWFNMVEM6IHRvZGF2XHUwMEVEYSBzZSBoYWNlIHJlZmVyZW5jaWEgYSB1bmEgaW5zdHJ1Y2NpXHUwMEYzbiBxdWUgZm9ybWFiYSBwYXJ0ZSBkZSB1biBibG9xdWUgZGUgY1x1MDBGM2RpZ28gZGUgYnl0ZXMgZGVsaW1pdGFkbyBlbiBlbCBtXHUwMEU5dG9kbyBvcmlnaW5hbC4iCi0gICAgICAgIH0sCi0KLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGRlc2NyaWJlcyBhbiBpbnRlcm5hbCBlcnJvciBpbiB0aGUKLSAgICAgICAgICogcHJvY2Vzc29yLiAgVGhlICJtZXRob2QiIHRoYXQgaXMgYmVpbmcgcmVmZXJyZWQgdG8gaXMgYSBKYXZhIG1ldGhvZAotICAgICAgICAgKiBpbiBhIHRyYW5zbGV0IHRoYXQgWFNMVEMgaXMgZ2VuZXJhdGluZy4KLSAgICAgICAgICoKLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5PVVRMSU5FX0VSUl9NRVRIT0RfVE9PX0JJRywKLSAgICAgICAgICJFcnJvciBpbnRlcm5vIGRlIFhTTFRDOiB1biBtXHUwMEU5dG9kbyBlbiBlbCB0cmFuc2xldCBleGNlZGUgbGEgbGltaXRhY2lcdTAwRjNuIGRlIEphdmEgVmlydHVhbCBNYWNoaW5lIGRlIGxvbmdpdHVkIGRlIHVuIG1cdTAwRTl0b2RvIGRlIDY0IGtpbG9ieXRlcy4gTm9ybWFsbWVudGUsIGVzdG8gbG8gY2F1c2FuIHBsYW50aWxsYXMgZW4gdW5hIGhvamEgZGUgZXN0aWxvcyBkZW1hc2lhZG8gZ3JhbmRlcy4gUHJ1ZWJlIGEgcmVlc3RydWN0dXJhciBsYSBob2phIGRlIGVzdGlsb3MgcGFyYSB1dGlsaXphciBwbGFudGlsbGFzIG1cdTAwRTFzIHBlcXVlXHUwMEYxYXMuIgotICAgICAgICB9LAotCi0gICAgICAgICB7RXJyb3JNc2cuREVTRVJJQUxJWkVfVFJBTlNMRVRfRVJSLCAiQ3VhbmRvIGxhIHNlZ3VyaWRhZCBkZSBKYXZhIGVzdFx1MDBFMSBhY3RpdmFkYSwgZWwgc29wb3J0ZSBwYXJhIGFudWxhciBsYSBzZXJpYWxpemFjaVx1MDBGM24gZGUgVGVtcGxhdGVzSW1wbCBlc3RcdTAwRTEgZGVzYWN0aXZhZG8uIEVzdG8gc2UgcHVlZGUgc3VzdGl0dWlyIGRlZmluaWVuZG8gbGEgcHJvcGllZGFkIGRlbCBzaXN0ZW1hIGpkay54bWwuZW5hYmxlVGVtcGxhdGVzSW1wbERlc2VyaWFsaXphdGlvbiBlbiB0cnVlLiJ9Ci0KLSAgICB9OwotCi0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci91dGlsL0Vycm9yTWVzc2FnZXNfZnIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvdXRpbC9FcnJvck1lc3NhZ2VzX2ZyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGRkMzE0OWEuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci91dGlsL0Vycm9yTWVzc2FnZXNfZnIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDk3NCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWw7Ci0KLWltcG9ydCBqYXZhLnV0aWwuTGlzdFJlc291cmNlQnVuZGxlOwotCi0vKioKLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICovCi1wdWJsaWMgY2xhc3MgRXJyb3JNZXNzYWdlc19mciBleHRlbmRzIExpc3RSZXNvdXJjZUJ1bmRsZSB7Ci0KLS8qCi0gKiBYU0xUQyBjb21waWxlLXRpbWUgZXJyb3IgbWVzc2FnZXMuCi0gKgotICogR2VuZXJhbCBub3RlcyB0byB0cmFuc2xhdG9ycyBhbmQgZGVmaW5pdGlvbnM6Ci0gKgotICogICAxKSBYU0xUQyBpcyB0aGUgbmFtZSBvZiB0aGUgcHJvZHVjdC4gIEl0IGlzIGFuIGFjcm9ueW0gZm9yICJYU0xUIENvbXBpbGVyIi4KLSAqICAgICAgWFNMVCBpcyBhbiBhY3JvbnltIGZvciAiWE1MIFN0eWxlc2hlZXQgTGFuZ3VhZ2U6IFRyYW5zZm9ybWF0aW9ucyIuCi0gKgotICogICAyKSBBIHN0eWxlc2hlZXQgaXMgYSBkZXNjcmlwdGlvbiBvZiBob3cgdG8gdHJhbnNmb3JtIGFuIGlucHV0IFhNTCBkb2N1bWVudAotICogICAgICBpbnRvIGEgcmVzdWx0YW50IFhNTCBkb2N1bWVudCAob3IgSFRNTCBkb2N1bWVudCBvciB0ZXh0KS4gIFRoZQotICogICAgICBzdHlsZXNoZWV0IGl0c2VsZiBpcyBkZXNjcmliZWQgaW4gdGhlIGZvcm0gb2YgYW4gWE1MIGRvY3VtZW50LgotICoKLSAqICAgMykgQSB0ZW1wbGF0ZSBpcyBhIGNvbXBvbmVudCBvZiBhIHN0eWxlc2hlZXQgdGhhdCBpcyB1c2VkIHRvIG1hdGNoIGEKLSAqICAgICAgcGFydGljdWxhciBwb3J0aW9uIG9mIGFuIGlucHV0IGRvY3VtZW50IGFuZCBzcGVjaWZpZXMgdGhlIGZvcm0gb2YgdGhlCi0gKiAgICAgIGNvcnJlc3BvbmRpbmcgcG9ydGlvbiBvZiB0aGUgb3V0cHV0IGRvY3VtZW50LgotICoKLSAqICAgNCkgQW4gYXhpcyBpcyBhIHBhcnRpY3VsYXIgImRpbWVuc2lvbiIgaW4gYSB0cmVlIHJlcHJlc2VudGF0aW9uIG9mIGFuIFhNTAotICogICAgICBkb2N1bWVudDsgdGhlIG5vZGVzIGluIHRoZSB0cmVlIGFyZSBkaXZpZGVkIGFsb25nIGRpZmZlcmVudCBheGVzLgotICogICAgICBUcmF2ZXJzaW5nIHRoZSAiY2hpbGQiIGF4aXMsIGZvciBpbnN0YW5jZSwgbWVhbnMgdGhhdCB0aGUgcHJvZ3JhbQotICogICAgICB3b3VsZCB2aXNpdCBlYWNoIGNoaWxkIG9mIGEgcGFydGljdWxhciBub2RlOyB0cmF2ZXJzaW5nIHRoZSAiZGVzY2VuZGFudCIKLSAqICAgICAgYXhpcyBtZWFucyB0aGF0IHRoZSBwcm9ncmFtIHdvdWxkIHZpc2l0IHRoZSBjaGlsZCBub2RlcyBvZiBhIHBhcnRpY3VsYXIKLSAqICAgICAgbm9kZSwgdGhlaXIgY2hpbGRyZW4sIGFuZCBzbyBvbiB1bnRpbCB0aGUgbGVhZiBub2RlcyBvZiB0aGUgdHJlZSBhcmUKLSAqICAgICAgcmVhY2hlZC4KLSAqCi0gKiAgIDUpIEFuIGl0ZXJhdG9yIGlzIGFuIG9iamVjdCB0aGF0IHRyYXZlcnNlcyBub2RlcyBpbiBhIHRyZWUgYWxvbmcgYQotICogICAgICBwYXJ0aWN1bGFyIGF4aXMsIG9uZSBhdCBhIHRpbWUuCi0gKgotICogICA2KSBBbiBlbGVtZW50IGlzIGEgbWFyay11cCB0YWcgaW4gYW4gWE1MIGRvY3VtZW50OyBhbiBhdHRyaWJ1dGUgaXMgYQotICogICAgICBtb2RpZmllciBvbiB0aGUgdGFnLiAgRm9yIGV4YW1wbGUsIGluIDxlbGVtIGF0dHI9J3ZhbCcgYXR0cjI9J3ZhbDInPgotICogICAgICAiZWxlbSIgaXMgYW4gZWxlbWVudCBuYW1lLCAiYXR0ciIgYW5kICJhdHRyMiIgYXJlIGF0dHJpYnV0ZSBuYW1lcyB3aXRoCi0gKiAgICAgIHRoZSB2YWx1ZXMgInZhbCIgYW5kICJ2YWwyIiwgcmVzcGVjdGl2ZWx5LgotICoKLSAqICAgNykgQSBuYW1lc3BhY2UgZGVjbGFyYXRpb24gaXMgYSBzcGVjaWFsIGF0dHJpYnV0ZSB0aGF0IGlzIHVzZWQgdG8gYXNzb2NpYXRlCi0gKiAgICAgIGEgcHJlZml4IHdpdGggYSBVUkkgKHRoZSBuYW1lc3BhY2UpLiAgVGhlIG1lYW5pbmdzIG9mIGVsZW1lbnQgbmFtZXMgYW5kCi0gKiAgICAgIGF0dHJpYnV0ZSBuYW1lcyB0aGF0IHVzZSB0aGF0IHByZWZpeCBhcmUgZGVmaW5lZCB3aXRoIHJlc3BlY3QgdG8gdGhhdAotICogICAgICBuYW1lc3BhY2UuCi0gKgotICogICA4KSBET00gaXMgYW4gYWNyb255bSBmb3IgRG9jdW1lbnQgT2JqZWN0IE1vZGVsLiAgSXQgaXMgYSB0cmVlCi0gKiAgICAgIHJlcHJlc2VudGF0aW9uIG9mIGFuIFhNTCBkb2N1bWVudC4KLSAqCi0gKiAgICAgIFNBWCBpcyBhbiBhY3JvbnltIGZvciB0aGUgU2ltcGxlIEFQSSBmb3IgWE1MIHByb2Nlc3NpbmcuICBJdCBpcyBhbiBBUEkKLSAqICAgICAgdXNlZCBpbmZvcm0gYW4gWE1MIHByb2Nlc3NvciAoaW4gdGhpcyBjYXNlIFhTTFRDKSBvZiB0aGUgc3RydWN0dXJlIGFuZAotICogICAgICBjb250ZW50IG9mIGFuIFhNTCBkb2N1bWVudC4KLSAqCi0gKiAgICAgIElucHV0IHRvIHRoZSBzdHlsZXNoZWV0IHByb2Nlc3NvciBjYW4gY29tZSBmcm9tIGFuIFhNTCBwYXJzZXIgaW4gdGhlCi0gKiAgICAgIGZvcm0gb2YgYSBET00gdHJlZSBvciB0aHJvdWdoIHRoZSBTQVggQVBJLgotICoKLSAqICAgOSkgRFREIGlzIGEgZG9jdW1lbnQgdHlwZSBkZWNsYXJhdGlvbi4gIEl0IGlzIGEgd2F5IG9mIHNwZWNpZnlpbmcgdGhlCi0gKiAgICAgIGdyYW1tYXIgZm9yIGFuIFhNTCBmaWxlLCB0aGUgbmFtZXMgYW5kIHR5cGVzIG9mIGVsZW1lbnRzLCBhdHRyaWJ1dGVzLAotICogICAgICBldGMuCi0gKgotICogIDEwKSBYUGF0aCBpcyBhIHNwZWNpZmljYXRpb24gdGhhdCBkZXNjcmliZXMgYSBub3RhdGlvbiBmb3IgaWRlbnRpZnlpbmcKLSAqICAgICAgbm9kZXMgaW4gYSB0cmVlLXN0cnVjdHVyZWQgcmVwcmVzZW50YXRpb24gb2YgYW4gWE1MIGRvY3VtZW50LiAgQW4KLSAqICAgICAgaW5zdGFuY2Ugb2YgdGhhdCBub3RhdGlvbiBpcyByZWZlcnJlZCB0byBhcyBhbiBYUGF0aCBleHByZXNzaW9uLgotICoKLSAqICAxMSkgVHJhbnNsZXQgaXMgYW4gaW52ZW50ZWQgdGVybSB0aGF0IHJlZmVycyB0byB0aGUgY2xhc3MgZmlsZSB0aGF0IGNvbnRhaW5zCi0gKiAgICAgIHRoZSBjb21waWxlZCBmb3JtIG9mIGEgc3R5bGVzaGVldC4KLSAqLwotCi0gICAgLy8gVGhlc2UgbWVzc2FnZSBzaG91bGQgYmUgcmVhZCBmcm9tIGEgbG9jYWxlLXNwZWNpZmljIHJlc291cmNlIGJ1bmRsZQotICAgIC8qKiBHZXQgdGhlIGxvb2t1cCB0YWJsZSBmb3IgZXJyb3IgbWVzc2FnZXMuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBtZXNzYWdlIGxvb2t1cCB0YWJsZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0W11bXSBnZXRDb250ZW50cygpCi0gICAgewotICAgICAgcmV0dXJuIG5ldyBPYmplY3RbXVtdIHsKLSAgICAgICAge0Vycm9yTXNnLk1VTFRJUExFX1NUWUxFU0hFRVRfRVJSLAotICAgICAgICAiUGx1c2lldXJzIGZldWlsbGVzIGRlIHN0eWxlIGRcdTAwRTlmaW5pZXMgZGFucyBsZSBtXHUwMEVBbWUgZmljaGllci4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIGEKLSAgICAgICAgICogdGVtcGxhdGUuICBUaGUgc2FtZSBuYW1lIHdhcyB1c2VkIG9uIHR3byBkaWZmZXJlbnQgdGVtcGxhdGVzIGluIHRoZQotICAgICAgICAgKiBzYW1lIHN0eWxlc2hlZXQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVEVNUExBVEVfUkVERUZfRVJSLAotICAgICAgICAiTW9kXHUwMEU4bGUgJyd7MH0nJyBkXHUwMEU5alx1MDBFMCBkXHUwMEU5ZmluaSBkYW5zIGNldHRlIGZldWlsbGUgZGUgc3R5bGUuIn0sCi0KLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIGEKLSAgICAgICAgICogdGVtcGxhdGUuICBBIHJlZmVyZW5jZSB0byB0aGUgdGVtcGxhdGUgbmFtZSB3YXMgZW5jb3VudGVyZWQsIGJ1dCB0aGUKLSAgICAgICAgICogdGVtcGxhdGUgaXMgdW5kZWZpbmVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlRFTVBMQVRFX1VOREVGX0VSUiwKLSAgICAgICAgIk1vZFx1MDBFOGxlICcnezB9Jycgbm9uIGRcdTAwRTlmaW5pIGRhbnMgY2V0dGUgZmV1aWxsZSBkZSBzdHlsZS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIGEgdmFyaWFibGUKLSAgICAgICAgICogdGhhdCB3YXMgZGVmaW5lZCBtb3JlIHRoYW4gb25jZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5WQVJJQUJMRV9SRURFRl9FUlIsCi0gICAgICAgICJQbHVzaWV1cnMgdmFyaWFibGVzICcnezB9JycgZFx1MDBFOWZpbmllcyBkYW5zIGxhIG1cdTAwRUFtZSBwb3J0XHUwMEU5ZS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIGEgdmFyaWFibGUKLSAgICAgICAgICogb3IgcGFyYW1ldGVyLiAgQSByZWZlcmVuY2UgdG8gdGhlIHZhcmlhYmxlIG9yIHBhcmFtZXRlciB3YXMgZm91bmQsCi0gICAgICAgICAqIGJ1dCBpdCB3YXMgbmV2ZXIgZGVmaW5lZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5WQVJJQUJMRV9VTkRFRl9FUlIsCi0gICAgICAgICJMYSB2YXJpYWJsZSBvdSBsZSBwYXJhbVx1MDBFOHRyZSAnJ3swfScnIG4nJ2VzdCBwYXMgZFx1MDBFOWZpbmkuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSB3b3JkICJjbGFzcyIgaGVyZSByZWZlcnMgdG8gYSBKYXZhIGNsYXNzLgotICAgICAgICAgKiBQcm9jZXNzaW5nIHRoZSBzdHlsZXNoZWV0IHJlcXVpcmVkIGEgY2xhc3MgdG8gYmUgbG9hZGVkLCBidXQgaXQgY291bGQKLSAgICAgICAgICogbm90IGJlIGZvdW5kLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIHRoZSBjbGFzcy4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5DTEFTU19OT1RfRk9VTkRfRVJSLAotICAgICAgICAiSW1wb3NzaWJsZSBkZSB0cm91dmVyIGxhIGNsYXNzZSAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgd29yZCAibWV0aG9kIiBoZXJlIHJlZmVycyB0byBhIEphdmEgbWV0aG9kLgotICAgICAgICAgKiBQcm9jZXNzaW5nIHRoZSBzdHlsZXNoZWV0IHJlcXVpcmVkIGEgcmVmZXJlbmNlIHRvIHRoZSBtZXRob2QgbmFtZWQgYnkKLSAgICAgICAgICogdGhlIHN1YnN0aXR1dGlvbiB0ZXh0LCBidXQgaXQgY291bGQgbm90IGJlIGZvdW5kLiAgInB1YmxpYyIgaXMgdGhlCi0gICAgICAgICAqIEphdmEga2V5d29yZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5NRVRIT0RfTk9UX0ZPVU5EX0VSUiwKLSAgICAgICAgIk1cdTAwRTl0aG9kZSBleHRlcm5lICcnezB9JycgaW50cm91dmFibGUgKGVsbGUgZG9pdCBcdTAwRUF0cmUgXCJwdWJsaWNcIikuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSB3b3JkICJtZXRob2QiIGhlcmUgcmVmZXJzIHRvIGEgSmF2YSBtZXRob2QuCi0gICAgICAgICAqIFByb2Nlc3NpbmcgdGhlIHN0eWxlc2hlZXQgcmVxdWlyZWQgYSByZWZlcmVuY2UgdG8gdGhlIG1ldGhvZCBuYW1lZCBieQotICAgICAgICAgKiB0aGUgc3Vic3RpdHV0aW9uIHRleHQsIGJ1dCBubyBtZXRob2Qgd2l0aCB0aGUgcmVxdWlyZWQgdHlwZXMgb2YKLSAgICAgICAgICogYXJndW1lbnRzIG9yIHJldHVybiB0eXBlIGNvdWxkIGJlIGZvdW5kLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkFSR1VNRU5UX0NPTlZFUlNJT05fRVJSLAotICAgICAgICAiSW1wb3NzaWJsZSBkZSBjb252ZXJ0aXIgbGUgdHlwZSBkZSByZXRvdXIvZCcnYXJndW1lbnQgZGFucyBsJydhcHBlbCBkZSBsYSBtXHUwMEU5dGhvZGUgJyd7MH0nJyJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZmlsZSBvciBVUkkgbmFtZWQgaW4gdGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgICAqIGlzIG1pc3NpbmcuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuRklMRV9OT1RfRk9VTkRfRVJSLAotICAgICAgICAiRmljaGllciBvdSBVUkkgJyd7MH0nJyBpbnRyb3V2YWJsZS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIGRpc3BsYXllZCB3aGVuIHRoZSBVUkkKLSAgICAgICAgICogbWVudGlvbmVkIGluIHRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyBub3Qgd2VsbC1mb3JtZWQgc3ludGFjdGljYWxseS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTlZBTElEX1VSSV9FUlIsCi0gICAgICAgICJVUkkgJyd7MH0nJyBub24gdmFsaWRlLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZmlsZSBvciBVUkkgbmFtZWQgaW4gdGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgICAqIGV4aXN0cyBidXQgY291bGQgbm90IGJlIG9wZW5lZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5GSUxFX0FDQ0VTU19FUlIsCi0gICAgICAgICJJbXBvc3NpYmxlIGQnJ291dnJpciBsZSBmaWNoaWVyIG91IGwnJ1VSSSAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6IDx4c2w6c3R5bGVzaGVldD4gYW5kIDx4c2w6dHJhbnNmb3JtPiBhcmUKLSAgICAgICAgICoga2V5d29yZHMgdGhhdCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTUlTU0lOR19ST09UX0VSUiwKLSAgICAgICAgIkVsXHUwMEU5bWVudCA8eHNsOnN0eWxlc2hlZXQ+IG91IDx4c2w6dHJhbnNmb3JtPiBhdHRlbmR1LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3R5bGVzaGVldCBjb250YWluZWQgYSByZWZlcmVuY2UgdG8gYQotICAgICAgICAgKiBuYW1lc3BhY2UgcHJlZml4IHRoYXQgd2FzIHVuZGVmaW5lZC4gIFRoZSB2YWx1ZSBvZiB0aGUgc3Vic3RpdHV0aW9uCi0gICAgICAgICAqIHRleHQgaXMgdGhlIG5hbWUgb2YgdGhlIHByZWZpeC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5OQU1FU1BBQ0VfVU5ERUZfRVJSLAotICAgICAgICAiTGUgcHJcdTAwRTlmaXhlIGRlIGwnJ2VzcGFjZSBkZSBub21zICcnezB9JycgbicnYSBwYXMgXHUwMEU5dFx1MDBFOSBkXHUwMEU5Y2xhclx1MDBFOS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIEphdmEgZnVuY3Rpb24gbmFtZWQgaW4gdGhlIHN0eWxlc2hlZXQgY291bGQKLSAgICAgICAgICogbm90IGJlIGZvdW5kLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkZVTkNUSU9OX1JFU09MVkVfRVJSLAotICAgICAgICAiSW1wb3NzaWJsZSBkZSByXHUwMEU5c291ZHJlIGwnJ2FwcGVsIGRlIGxhIGZvbmN0aW9uICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBhCi0gICAgICAgICAqIGZ1bmN0aW9uLiAgQSBsaXRlcmFsIHN0cmluZyBoZXJlIG1lYW5zIGEgY29uc3RhbnQgc3RyaW5nIHZhbHVlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk5FRURfTElURVJBTF9FUlIsCi0gICAgICAgICJMJydhcmd1bWVudCBwb3VyICcnezB9JycgZG9pdCBcdTAwRUF0cmUgdW5lIGNoYVx1MDBFRW5lIGxpdHRcdTAwRTlyYWxlLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaW5kaWNhdGVzIHRoZXJlIHdhcyBhIHN5bnRhY3RpYwotICAgICAgICAgKiBlcnJvciBpbiB0aGUgZm9ybSBvZiBhbiBYUGF0aCBleHByZXNzaW9uLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzCi0gICAgICAgICAqIHRoZSBleHByZXNzaW9uLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlhQQVRIX1BBUlNFUl9FUlIsCi0gICAgICAgICJFcnJldXIgbG9ycyBkZSBsJydhbmFseXNlIGRlIGwnJ2V4cHJlc3Npb24gWFBhdGggJyd7MH0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQW4gZWxlbWVudCBpbiB0aGUgc3R5bGVzaGVldCByZXF1aXJlcyBhCi0gICAgICAgICAqIHBhcnRpY3VsYXIgYXR0cmlidXRlIG5hbWVkIGJ5IHRoZSBzdWJzdGl0dXRpb24gdGV4dCwgYnV0IHRoYXQKLSAgICAgICAgICogYXR0cmlidXRlIHdhcyBub3Qgc3BlY2lmaWVkIGluIHRoZSBzdHlsZXNoZWV0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlJFUVVJUkVEX0FUVFJfRVJSLAotICAgICAgICAiQXR0cmlidXQgJyd7MH0nJyBvYmxpZ2F0b2lyZSBtYW5xdWFudC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IGEgY2hhcmFjdGVyIG5vdAotICAgICAgICAgKiBwZXJtaXR0ZWQgaW4gYW4gWFBhdGggZXhwcmVzc2lvbiB3YXMgZW5jb3VudGVyZWQuICBUaGUgc3Vic3RpdHV0aW9uCi0gICAgICAgICAqIHRleHQgaXMgdGhlIG9mZmVuZGluZyBjaGFyYWN0ZXIuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSUxMRUdBTF9DSEFSX0VSUiwKLSAgICAgICAgIkNhcmFjdFx1MDBFOHJlICcnezB9Jycgbm9uIGFkbWlzIGRhbnMgbCcnZXhwcmVzc2lvbiBYUGF0aC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQSBwcm9jZXNzaW5nIGluc3RydWN0aW9uIGlzIGEgbWFyay11cCBpdGVtIGluCi0gICAgICAgICAqIGFuIFhNTCBkb2N1bWVudCB0aGF0IHJlcXVlc3Qgc29tZSBiZWhhdmlvdXIgb2YgYW4gWE1MIHByb2Nlc3Nvci4gIFRoZQotICAgICAgICAgKiBmb3JtIG9mIHRoZSBuYW1lIG9mIHdhcyBpbnZhbGlkIGluIHRoaXMgY2FzZSwgYW5kIHRoZSBzdWJzdGl0dXRpb24KLSAgICAgICAgICogdGV4dCBpcyB0aGUgbmFtZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTExFR0FMX1BJX0VSUiwKLSAgICAgICAgIk5vbSAnJ3swfScnIG5vbiBhZG1pcyBwb3VyIGwnJ2luc3RydWN0aW9uIGRlIHRyYWl0ZW1lbnQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyByZXBvcnRlZCBpZiB0aGUgc3R5bGVzaGVldAotICAgICAgICAgKiBiZWluZyBwcm9jZXNzZWQgYXR0ZW1wdGVkIHRvIGNvbnN0cnVjdCBhbiBYTUwgZG9jdW1lbnQgd2l0aCBhbgotICAgICAgICAgKiBhdHRyaWJ1dGUgaW4gYSBwbGFjZSBvdGhlciB0aGFuIG9uIGFuIGVsZW1lbnQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQKLSAgICAgICAgICogc3BlY2lmaWVzIHRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuU1RSQVlfQVRUUklCVVRFX0VSUiwKLSAgICAgICAgIkF0dHJpYnV0ICcnezB9JycgXHUwMEUwIGwnJ2V4dFx1MDBFOXJpZXVyIGRlIGwnJ1x1MDBFOWxcdTAwRTltZW50LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBbiBhdHRyaWJ1dGUgdGhhdCB3YXNuJ3QgcmVjb2duaXplZCB3YXMKLSAgICAgICAgICogc3BlY2lmaWVkIG9uIGFuIGVsZW1lbnQgaW4gdGhlIHN0eWxlc2hlZXQuICBUaGUgYXR0cmlidXRlIGlzIG5hbWVkCi0gICAgICAgICAqIGJ5IHRoZSBzdWJzdGl0dXRpb24KLSAgICAgICAgICogdGV4dC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTExFR0FMX0FUVFJJQlVURV9FUlIsCi0gICAgICAgICJBdHRyaWJ1dCAnJ3swfScnIG5vbiBhZG1pcy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgImltcG9ydCIgYW5kICJpbmNsdWRlIiBhcmUga2V5d29yZHMgdGhhdCBzaG91bGQKLSAgICAgICAgICogbm90IGJlIHRyYW5zbGF0ZWQuICBUaGlzIG1lc3NhZ2VzIGluZGljYXRlcyB0aGF0IHRoZSBzdHlsZXNoZWV0Ci0gICAgICAgICAqIG5hbWVkIGluIHRoZSBzdWJzdGl0dXRpb24gdGV4dCBpbXBvcnRlZCBvciBpbmNsdWRlZCBpdHNlbGYgZWl0aGVyCi0gICAgICAgICAqIGRpcmVjdGx5IG9yIGluZGlyZWN0bHkuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuQ0lSQ1VMQVJfSU5DTFVERV9FUlIsCi0gICAgICAgICJPcFx1MDBFOXJhdGlvbiBpbXBvcnQvaW5jbHVkZSBjaXJjdWxhaXJlLiBMYSBmZXVpbGxlIGRlIHN0eWxlICcnezB9JycgZXN0IGRcdTAwRTlqXHUwMEUwIGNoYXJnXHUwMEU5ZS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQSByZXN1bHQtdHJlZSBmcmFnbWVudCBpcyBhIHBvcnRpb24gb2YgYQotICAgICAgICAgKiByZXN1bHRpbmcgWE1MIGRvY3VtZW50IHJlcHJlc2VudGVkIGFzIGEgdHJlZS4gICI8eHNsOnNvcnQ+IiBpcyBhCi0gICAgICAgICAqIGtleXdvcmQgYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5SRVNVTFRfVFJFRV9TT1JUX0VSUiwKLSAgICAgICAgIkxlcyBmcmFnbWVudHMgZGUgbCdhcmJvcmVzY2VuY2UgZGUgclx1MDBFOXN1bHRhdHMgbmUgcGV1dmVudCBwYXMgXHUwMEVBdHJlIHRyaVx1MDBFOXMgKGxlcyBcdTAwRTlsXHUwMEU5bWVudHMgPHhzbDpzb3J0PiBuZSBzb250IHBhcyBwcmlzIGVuIGNvbXB0ZSkuIFZvdXMgZGV2ZXogdHJpZXIgbGVzIG5vZXVkcyBsb3JzcXVlIHZvdXMgY3JcdTAwRTlleiBsJ2FyYm9yZXNjZW5jZSBkZSByXHUwMEU5c3VsdGF0cy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQSBuYW1lIGNhbiBiZSBnaXZlbiB0byBhIHBhcnRpY3VsYXIgc3R5bGUgdG8gYmUKLSAgICAgICAgICogdXNlZCB0byBmb3JtYXQgZGVjaW1hbCB2YWx1ZXMuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgZ2l2ZXMgdGhlIG5hbWUKLSAgICAgICAgICogb2Ygc3VjaCBhIHN0eWxlIGZvciB3aGljaCBtb3JlIHRoYW4gb25lIGRlY2xhcmF0aW9uIHdhcyBlbmNvdW50ZXJlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5TWU1CT0xTX1JFREVGX0VSUiwKLSAgICAgICAgIkxlIGZvcm1hdGFnZSBkXHUwMEU5Y2ltYWwgJyd7MH0nJyBlc3QgZFx1MDBFOWpcdTAwRTAgZFx1MDBFOWZpbmkuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IHZlcnNpb24gbmFtZWQgaW4gdGhlCi0gICAgICAgICAqIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIG5vdCBzdXBwb3J0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuWFNMX1ZFUlNJT05fRVJSLAotICAgICAgICAiTGEgdmVyc2lvbiBYU0wgJyd7MH0nJyBuJydlc3QgcGFzIHByaXNlIGVuIGNoYXJnZSBwYXIgWFNMVEMuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBkZWZpbml0aW9ucyBvZiBvbmUgb3IgbW9yZSB2YXJpYWJsZXMgb3IKLSAgICAgICAgICogcGFyYW1ldGVycyBkZXBlbmQgb24gb25lIGFub3RoZXIuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuQ0lSQ1VMQVJfVkFSSUFCTEVfRVJSLAotICAgICAgICAiUlx1MDBFOWZcdTAwRTlyZW5jZSBkZSBwYXJhbVx1MDBFOHRyZS92YXJpYWJsZSBjaXJjdWxhaXJlIGRhbnMgJyd7MH0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIG9wZXJhdG9yIGluIGFuIGV4cHJlc2lvbiB3aXRoIHR3byBvcGVyYW5kcyB3YXMKLSAgICAgICAgICogbm90IHJlY29nbml6ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSUxMRUdBTF9CSU5BUllfT1BfRVJSLAotICAgICAgICAiT3BcdTAwRTlyYXRldXIgaW5jb25udSBwb3VyIGwnZXhwcmVzc2lvbiBiaW5haXJlLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgcHJvZHVjZWQgaWYgYSByZWZlcmVuY2UgdG8gYQotICAgICAgICAgKiBmdW5jdGlvbiBoYXMgdG9vIG1hbnkgb3IgdG9vIGZldyBhcmd1bWVudHMuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSUxMRUdBTF9BUkdfRVJSLAotICAgICAgICAiQXJndW1lbnRzIG5vbiBhZG1pcyBwb3VyIGwnYXBwZWwgZGUgbGEgZm9uY3Rpb24uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJkb2N1bWVudCgpIiBpcyB0aGUgbmFtZSBvZiBmdW5jdGlvbiBhbmQgbXVzdAotICAgICAgICAgKiBub3QgYmUgdHJhbnNsYXRlZC4gIEEgbm9kZS1zZXQgaXMgYSBzZXQgb2YgdGhlIG5vZGVzIGluIHRoZSB0cmVlCi0gICAgICAgICAqIHJlcHJlc2VudGF0aW9uIG9mIGFuIFhNTCBkb2N1bWVudC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5ET0NVTUVOVF9BUkdfRVJSLAotICAgICAgICAiTGUgZGV1eGlcdTAwRThtZSBhcmd1bWVudCBkZSBsYSBmb25jdGlvbiBkb2N1bWVudCgpIGRvaXQgXHUwMEVBdHJlIHVuIGpldSBkZSBub2V1ZHMuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICI8eHNsOndoZW4+IiBhbmQgIjx4c2w6Y2hvb3NlPiIgYXJlIGtleXdvcmRzCi0gICAgICAgICAqIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGlzIG1lc3NhZ2UgZGVzY3JpYmVzIGEgc3ludGF4IGVycm9yCi0gICAgICAgICAqIGluIHRoZSBzdHlsZXNoZWV0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk1JU1NJTkdfV0hFTl9FUlIsCi0gICAgICAgICJBdSBtb2lucyB1biBcdTAwRTlsXHUwMEU5bWVudCA8eHNsOndoZW4+IGVzdCBvYmxpZ2F0b2lyZSBkYW5zIDx4c2w6Y2hvb3NlPi4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIjx4c2w6b3RoZXJ3aXNlPiIgYW5kICI8eHNsOmNob29zZT4iIGFyZQotICAgICAgICAgKiBrZXl3b3JkcyBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhpcyBtZXNzYWdlIGRlc2NyaWJlcyBhCi0gICAgICAgICAqIHN5bnRheCBlcnJvciBpbiB0aGUgc3R5bGVzaGVldC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5NVUxUSVBMRV9PVEhFUldJU0VfRVJSLAotICAgICAgICAiVW4gc2V1bCBcdTAwRTlsXHUwMEU5bWVudCA8eHNsOm90aGVyd2lzZT4gZXN0IGF1dG9yaXNcdTAwRTkgZGFucyA8eHNsOmNob29zZT4uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICI8eHNsOm90aGVyd2lzZT4iIGFuZCAiPHhzbDpjaG9vc2U+IiBhcmUKLSAgICAgICAgICoga2V5d29yZHMgYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoaXMgbWVzc2FnZSBkZXNjcmliZXMgYQotICAgICAgICAgKiBzeW50YXggZXJyb3IgaW4gdGhlIHN0eWxlc2hlZXQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuU1RSQVlfT1RIRVJXSVNFX0VSUiwKLSAgICAgICAgIjx4c2w6b3RoZXJ3aXNlPiBuZSBwZXV0IFx1MDBFQXRyZSB1dGlsaXNcdTAwRTkgcXVlIGRhbnMgPHhzbDpjaG9vc2U+LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiPHhzbDp3aGVuPiIgYW5kICI8eHNsOmNob29zZT4iIGFyZSBrZXl3b3JkcwotICAgICAgICAgKiBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhpcyBtZXNzYWdlIGRlc2NyaWJlcyBhIHN5bnRheCBlcnJvcgotICAgICAgICAgKiBpbiB0aGUgc3R5bGVzaGVldC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5TVFJBWV9XSEVOX0VSUiwKLSAgICAgICAgIjx4c2w6d2hlbj4gbmUgcGV1dCBcdTAwRUF0cmUgdXRpbGlzXHUwMEU5IHF1ZSBkYW5zIDx4c2w6Y2hvb3NlPi4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIjx4c2w6d2hlbj4iLCAiPHhzbDpvdGhlcndpc2U+IiBhbmQKLSAgICAgICAgICogIjx4c2w6Y2hvb3NlPiIgYXJlIGtleXdvcmRzIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGlzCi0gICAgICAgICAqIG1lc3NhZ2UgZGVzY3JpYmVzIGEgc3ludGF4IGVycm9yIGluIHRoZSBzdHlsZXNoZWV0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLldIRU5fRUxFTUVOVF9FUlIsCi0gICAgICAgICJTZXVscyBsZXMgXHUwMEU5bFx1MDBFOW1lbnRzIDx4c2w6d2hlbj4gZXQgPHhzbDpvdGhlcndpc2U+IHNvbnQgYXV0b3Jpc1x1MDBFOXMgZGFucyA8eHNsOmNob29zZT4uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICI8eHNsOmF0dHJpYnV0ZS1zZXQ+IiBhbmQgIm5hbWUiIGFyZSBrZXl3b3JkcwotICAgICAgICAgKiB0aGF0IHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5VTk5BTUVEX0FUVFJJQlNFVF9FUlIsCi0gICAgICAgICJBdHRyaWJ1dCBcIm5hbWVcIiBtYW5xdWFudCBkYW5zIDx4c2w6YXR0cmlidXRlLXNldD4uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIGVsZW1lbnQgaW4gdGhlIHN0eWxlc2hlZXQgY29udGFpbmVkIGFuCi0gICAgICAgICAqIGVsZW1lbnQgb2YgYSB0eXBlIHRoYXQgaXQgd2FzIG5vdCBwZXJtaXR0ZWQgdG8gY29udGFpbi4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTExFR0FMX0NISUxEX0VSUiwKLSAgICAgICAgIkVsXHUwMEU5bWVudCBlbmZhbnQgbm9uIGFkbWlzLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3R5bGVzaGVldCB0cmllZCB0byBjcmVhdGUgYW4gZWxlbWVudCB3aXRoCi0gICAgICAgICAqIGEgbmFtZSB0aGF0IHdhcyBub3QgYSB2YWxpZCBYTUwgbmFtZS4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBjb250YWlucwotICAgICAgICAgKiB0aGUgbmFtZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTExFR0FMX0VMRU1fTkFNRV9FUlIsCi0gICAgICAgICJWb3VzIG5lIHBvdXZleiBwYXMgYXBwZWxlciB1biBcdTAwRTlsXHUwMEU5bWVudCAnJ3swfScnIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IHRyaWVkIHRvIGNyZWF0ZSBhbiBhdHRyaWJ1dGUKLSAgICAgICAgICogd2l0aCBhIG5hbWUgdGhhdCB3YXMgbm90IGEgdmFsaWQgWE1MIG5hbWUuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQKLSAgICAgICAgICogY29udGFpbnMgdGhlIG5hbWUuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSUxMRUdBTF9BVFRSX05BTUVfRVJSLAotICAgICAgICAiVm91cyBuZSBwb3V2ZXogcGFzIGFwcGVsZXIgdW4gYXR0cmlidXQgJyd7MH0nJyJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgY2hpbGRyZW4gb2YgdGhlIG91dGVybW9zdCBlbGVtZW50IG9mIGEKLSAgICAgICAgICogc3R5bGVzaGVldCBhcmUgcmVmZXJyZWQgdG8gYXMgdG9wLWxldmVsIGVsZW1lbnRzLiAgTm8gdGV4dCBzaG91bGQKLSAgICAgICAgICogb2NjdXIgd2l0aGluIHRoYXQgb3V0ZXJtb3N0IGVsZW1lbnQgdW5sZXNzIGl0IGlzIHdpdGhpbiBhIHRvcC1sZXZlbAotICAgICAgICAgKiBlbGVtZW50LiAgVGhpcyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoYXQgY29uc3RyYWludCB3YXMgdmlvbGF0ZWQuCi0gICAgICAgICAqICI8eHNsOnN0eWxlc2hlZXQ+IiBpcyBhIGtleXdvcmQgdGhhdCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSUxMRUdBTF9URVhUX05PREVfRVJSLAotICAgICAgICAiRG9ublx1MDBFOWVzIHRleHRlIGVuIGRlaG9ycyBkZSBsJ1x1MDBFOWxcdTAwRTltZW50IDx4c2w6c3R5bGVzaGVldD4gZGUgbml2ZWF1IHN1cFx1MDBFOXJpZXVyLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBKQVhQIGlzIGFuIGFjcm9ueW0gZm9yIHRoZSBKYXZhIEFQSSBmb3IgWE1MCi0gICAgICAgICAqIFByb2Nlc3NpbmcuICBUaGlzIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhlIFhNTCBwYXJzZXIgcHJvdmlkZWQgdG8KLSAgICAgICAgICogWFNMVEMgdG8gcHJvY2VzcyB0aGUgWE1MIGlucHV0IGRvY3VtZW50IGhhZCBhIGNvbmZpZ3VyYXRpb24gcHJvYmxlbS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5TQVhfUEFSU0VSX0NPTkZJR19FUlIsCi0gICAgICAgICJMJ2FuYWx5c2V1ciBKQVhQIG4nZXN0IHBhcyBjb25maWd1clx1MDBFOSBjb3JyZWN0ZW1lbnQifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IG5hbWVzIHRoZSBpbnRlcm5hbCBlcnJvcgotICAgICAgICAgKiBlbmNvdW50ZXJlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTlRFUk5BTF9FUlIsCi0gICAgICAgICJFcnJldXIgaW50ZXJuZSBYU0xUQyBpcnJcdTAwRTljdXBcdTAwRTlyYWJsZSA6ICcnezB9JycifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN0eWxlc2hlZXQgY29udGFpbmVkIGFuIGVsZW1lbnQgdGhhdCB3YXMKLSAgICAgICAgICogbm90IHJlY29nbml6ZWQgYXMgcGFydCBvZiB0aGUgWFNMIHN5bnRheC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICAgKiBnaXZlcyB0aGUgZWxlbWVudCBuYW1lLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlVOU1VQUE9SVEVEX1hTTF9FUlIsCi0gICAgICAgICJFbFx1MDBFOW1lbnQgJyd7MH0nJyBYU0wgbm9uIHByaXMgZW4gY2hhcmdlLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3R5bGVzaGVldCByZWZlcnJlZCB0byBhbiBleHRlbnNpb24gdG8gdGhlCi0gICAgICAgICAqIFhTTCBzeW50YXggYW5kIGluZGljYXRlZCB0aGF0IGl0IHdhcyBkZWZpbmVkIGJ5IFhTTFRDLCBidXQgWFNUTEMgZG9lcwotICAgICAgICAgKiBub3QgcmVjb2duaXplZCB0aGUgcGFydGljdWxhciBleHRlbnNpb24gbmFtZWQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQKLSAgICAgICAgICogZ2l2ZXMgdGhlIGV4dGVuc2lvbiBuYW1lLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlVOU1VQUE9SVEVEX0VYVF9FUlIsCi0gICAgICAgICJFeHRlbnNpb24gJyd7MH0nJyBYU0xUQyBub24gcmVjb25udWUuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBYTUwgZG9jdW1lbnQgZ2l2ZW4gdG8gWFNMVEMgYXMgYSBzdHlsZXNoZWV0Ci0gICAgICAgICAqIHdhcyBub3QsIGluIGZhY3QsIGEgc3R5bGVzaGVldC4gIFhTTFRDIGlzIGFibGUgdG8gZGV0ZWN0IHRoYXQgaW4gdGhpcwotICAgICAgICAgKiBjYXNlIGJlY2F1c2UgdGhlIG91dGVybW9zdCBlbGVtZW50IGluIHRoZSBzdHlsZXNoZWV0IGhhcyB0byBiZQotICAgICAgICAgKiBkZWNsYXJlZCB3aXRoIHJlc3BlY3QgdG8gdGhlIFhTTCBuYW1lc3BhY2UgVVJJLCBidXQgbm8gZGVjbGFyYXRpb24KLSAgICAgICAgICogZm9yIHRoYXQgbmFtZXNwYWNlIHdhcyBzZWVuLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk1JU1NJTkdfWFNMVF9VUklfRVJSLAotICAgICAgICAiTGUgZG9jdW1lbnQgZCdlbnRyXHUwMEU5ZSBuJ2VzdCBwYXMgdW5lIGZldWlsbGUgZGUgc3R5bGUgKGwnZXNwYWNlIGRlIG5vbXMgWFNMIG4nZXN0IHBhcyBkXHUwMEU5Y2xhclx1MDBFOSBkYW5zIGwnXHUwMEU5bFx1MDBFOW1lbnQgcmFjaW5lKS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgWFNMVEMgY291bGQgbm90IGZpbmQgdGhlIHN0eWxlc2hlZXQgZG9jdW1lbnQKLSAgICAgICAgICogd2l0aCB0aGUgbmFtZSBzcGVjaWZpZWQgYnkgdGhlIHN1YnN0aXR1dGlvbiB0ZXh0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk1JU1NJTkdfWFNMVF9UQVJHRVRfRVJSLAotICAgICAgICAiQ2libGUgZGUgZmV1aWxsZSBkZSBzdHlsZSAnJ3swfScnIGludHJvdXZhYmxlLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBhY2Nlc3MgdG8gdGhlIHN0eWxlc2hlZXQgdGFyZ2V0IGlzIGRlbmllZAotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkFDQ0VTU0lOR19YU0xUX1RBUkdFVF9FUlIsCi0gICAgICAgICJJbXBvc3NpYmxlIGRlIGxpcmUgbGEgY2libGUgZGUgZmV1aWxsZSBkZSBzdHlsZSAnJ3swfScnIGNhciBsJydhY2NcdTAwRThzIFx1MDBFMCAnJ3sxfScnIG4nJ2VzdCBwYXMgYXV0b3Jpc1x1MDBFOSBlbiByYWlzb24gZCcndW5lIHJlc3RyaWN0aW9uIGRcdTAwRTlmaW5pZSBwYXIgbGEgcHJvcHJpXHUwMEU5dFx1MDBFOSBhY2Nlc3NFeHRlcm5hbFN0eWxlc2hlZXQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSByZXByZXNlbnRzIGFuIGludGVybmFsIGVycm9yIGluCi0gICAgICAgICAqIGNvbmRpdGlvbiBpbiBYU0xUQy4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgY2xhc3MgbmFtZSBpbiBYU0xUQwotICAgICAgICAgKiB0aGF0IGlzIG1pc3Npbmcgc29tZSBmdW5jdGlvbmFsaXR5LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk5PVF9JTVBMRU1FTlRFRF9FUlIsCi0gICAgICAgICJOb24gaW1wbFx1MDBFOW1lbnRcdTAwRTkgOiAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgWE1MIGRvY3VtZW50IGdpdmVuIHRvIFhTTFRDIGFzIGEgc3R5bGVzaGVldAotICAgICAgICAgKiB3YXMgbm90LCBpbiBmYWN0LCBhIHN0eWxlc2hlZXQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTk9UX1NUWUxFU0hFRVRfRVJSLAotICAgICAgICAiTGUgZG9jdW1lbnQgZCdlbnRyXHUwMEU5ZSBuZSBjb250aWVudCBwYXMgZGUgZmV1aWxsZSBkZSBzdHlsZSBYU0wuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBlbGVtZW50IG5hbWVkIGluIHRoZSBzdWJzdGl0dXRpb24gdGV4dCB3YXMKLSAgICAgICAgICogZW5jb3VudGVyZWQgaW4gdGhlIHN0eWxlc2hlZXQgYnV0IGlzIG5vdCByZWNvZ25pemVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkVMRU1FTlRfUEFSU0VfRVJSLAotICAgICAgICAiSW1wb3NzaWJsZSBkJydhbmFseXNlciBsJydcdTAwRTlsXHUwMEU5bWVudCAnJ3swfScnIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJ1c2UiLCAiPGtleT4iLCAibm9kZSIsICJub2RlLXNldCIsICJzdHJpbmciCi0gICAgICAgICAqIGFuZCAibnVtYmVyIiBhcmUga2V5d29yZHMgaW4gdGhpcyBjb250ZXh0IGFuZCBzaG91bGQgbm90IGJlCi0gICAgICAgICAqIHRyYW5zbGF0ZWQuICBUaGlzIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhlIHZhbHVlIG9mIHRoZSAidXNlIgotICAgICAgICAgKiBhdHRyaWJ1dGUgd2FzIG5vdCBvbmUgb2YgdGhlIHBlcm1pdHRlZCB2YWx1ZXMuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuS0VZX1VTRV9BVFRSX0VSUiwKLSAgICAgICAgIkwnYXR0cmlidXQgXCJ1c2VcIiBkZSA8a2V5PiBkb2l0IFx1MDBFQXRyZSBub2RlLCBub2RlLXNldCwgc3RyaW5nIG91IG51bWJlci4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQW4gWE1MIGRvY3VtZW50IGNhbiBzcGVjaWZ5IHRoZSB2ZXJzaW9uIG9mIHRoZQotICAgICAgICAgKiBYTUwgc3BlY2lmaWNhdGlvbiB0byB3aGljaCBpdCBhZGhlcmVzLiAgVGhpcyBtZXNzYWdlIGluZGljYXRlcyB0aGF0Ci0gICAgICAgICAqIHRoZSB2ZXJzaW9uIHNwZWNpZmllZCBmb3IgdGhlIG91dHB1dCBkb2N1bWVudCB3YXMgbm90IHZhbGlkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk9VVFBVVF9WRVJTSU9OX0VSUiwKLSAgICAgICAgIkxhIHZlcnNpb24gZHUgZG9jdW1lbnQgWE1MIGRlIHNvcnRpZSBkb2l0IFx1MDBFQXRyZSAxLjAifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIG9wZXJhdG9yIGluIGEgY29tcGFyaXNvbiBvcGVyYXRpb24gd2FzCi0gICAgICAgICAqIG5vdCByZWNvZ25pemVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfUkVMQVRfT1BfRVJSLAotICAgICAgICAiT3BcdTAwRTlyYXRldXIgaW5jb25udSBwb3VyIGwnZXhwcmVzc2lvbiByZWxhdGlvbm5lbGxlIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIGF0dHJpYnV0ZSBzZXQgZGVmaW5lcyBhcyBhIHNldCBvZiBYTUwKLSAgICAgICAgICogYXR0cmlidXRlcyB0aGF0IGNhbiBiZSBhZGRlZCB0byBhbiBlbGVtZW50IGluIHRoZSBvdXRwdXQgWE1MIGRvY3VtZW50Ci0gICAgICAgICAqIGFzIGEgZ3JvdXAuICBUaGlzIG1lc3NhZ2UgaXMgcmVwb3J0ZWQgaWYgdGhlIG5hbWUgc3BlY2lmaWVkIHdhcyBub3QKLSAgICAgICAgICogdXNlZCB0byBkZWNsYXJlIGFuIGF0dHJpYnV0ZSBzZXQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUKLSAgICAgICAgICogdGhhdCBpcyBpbiBlcnJvci4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5BVFRSSUJTRVRfVU5ERUZfRVJSLAotICAgICAgICAiVGVudGF0aXZlIGQnJ3V0aWxpc2F0aW9uIGRlIGwnJ2Vuc2VtYmxlIGQnJ2F0dHJpYnV0cyBub24gZXhpc3RhbnQgJyd7MH0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHRlcm0gImF0dHJpYnV0ZSB2YWx1ZSB0ZW1wbGF0ZSIgaXMgYSB0ZXJtCi0gICAgICAgICAqIGRlZmluZWQgYnkgWFNMVCB3aGljaCBkZXNjcmliZXMgdGhlIHZhbHVlIG9mIGFuIGF0dHJpYnV0ZSB0aGF0IGlzCi0gICAgICAgICAqIGRldGVybWluZWQgYnkgYW4gWFBhdGggZXhwcmVzc2lvbi4gIFRoZSBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoZQotICAgICAgICAgKiBleHByZXNzaW9uIHdhcyBzeW50YWN0aWNhbGx5IGluY29ycmVjdDsgdGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgICAqIGNvbnRhaW5zIHRoZSBleHByZXNzaW9uIHRoYXQgd2FzIGluIGVycm9yLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkFUVFJfVkFMX1RFTVBMQVRFX0VSUiwKLSAgICAgICAgIkltcG9zc2libGUgZCcnYW5hbHlzZXIgbGUgbW9kXHUwMEU4bGUgZGUgdmFsZXVyIGQnJ2F0dHJpYnV0ICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogID8/PwotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlVOS05PV05fU0lHX1RZUEVfRVJSLAotICAgICAgICAiVHlwZSBkZSBkb25uXHUwMEU5ZXMgaW5jb25udSBkYW5zIGxhIHNpZ25hdHVyZSBwb3VyIGxhIGNsYXNzZSAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgcmVmZXJzIHRvIGRhdGEgdHlwZXMuCi0gICAgICAgICAqIFRoZSBtZXNzYWdlIGlzIGRpc3BsYXllZCBpZiBhIHZhbHVlIGluIGEgcGFydGljdWxhciBjb250ZXh0IG5lZWRzIHRvCi0gICAgICAgICAqIGJlIGNvbnZlcnRlZCB0byB0eXBlIHsxfSwgYnV0IHRoYXQncyBub3QgcG9zc2libGUgZm9yIGEgdmFsdWUgb2YKLSAgICAgICAgICogdHlwZSB7MH0uCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuREFUQV9DT05WRVJTSU9OX0VSUiwKLSAgICAgICAgIkltcG9zc2libGUgZGUgY29udmVydGlyIGxlIHR5cGUgZGUgZG9ublx1MDBFOWVzICcnezB9JycgZW4gJyd7MX0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIlRlbXBsYXRlcyIgaXMgYSBKYXZhIGNsYXNzIG5hbWUgdGhhdCBzaG91bGQKLSAgICAgICAgICogbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTk9fVFJBTlNMRVRfQ0xBU1NfRVJSLAotICAgICAgICAiQ2V0dGUgY2xhc3NlIFRlbXBsYXRlcyBuZSBjb250aWVudCBwYXMgZGUgZFx1MDBFOWZpbml0aW9uIGRlIGNsYXNzZSBkZSB0cmFuc2xldCB2YWxpZGUuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJUZW1wbGF0ZXMiIGlzIGEgSmF2YSBjbGFzcyBuYW1lIHRoYXQgc2hvdWxkCi0gICAgICAgICAqIG5vdCBiZSB0cmFuc2xhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk5PX01BSU5fVFJBTlNMRVRfRVJSLAotICAgICAgICAiQ2V0dGUgY2xhc3NlIFRlcm1wbGF0ZXMgbmUgY29udGllbnQgcGFzIGRlIGNsYXNzZSBwb3J0YW50IGxlIG5vbSAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYSBjbGFzcy4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5UUkFOU0xFVF9DTEFTU19FUlIsCi0gICAgICAgICJJbXBvc3NpYmxlIGRlIGNoYXJnZXIgbGEgY2xhc3NlIGRlIHRyYW5zbGV0ICcnezB9JycuIn0sCi0KLSAgICAgICAge0Vycm9yTXNnLlRSQU5TTEVUX09CSkVDVF9FUlIsCi0gICAgICAgICJDbGFzc2UgZGUgdHJhbnNsZXQgY2hhcmdcdTAwRTllLCBtYWlzIGltcG9zc2libGUgZGUgY3JcdTAwRTllciB1bmUgaW5zdGFuY2UgZGUgdHJhbnNsZXQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJFcnJvckxpc3RlbmVyIiBpcyBhIEphdmEgaW50ZXJmYWNlIG5hbWUgdGhhdAotICAgICAgICAgKiBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUgdXNlciB0cmllZAotICAgICAgICAgKiB0byBzZXQgYW4gRXJyb3JMaXN0ZW5lciBvYmplY3Qgb24gb2JqZWN0IG9mIHRoZSBjbGFzcyBuYW1lZCBpbiB0aGUKLSAgICAgICAgICogc3Vic3RpdHV0aW9uIHRleHQgd2l0aCAibnVsbCIgSmF2YSB2YWx1ZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5FUlJPUl9MSVNURU5FUl9OVUxMX0VSUiwKLSAgICAgICAgIlRlbnRhdGl2ZSBkZSBkXHUwMEU5ZmluaXRpb24gZCcnRXJyb3JMaXN0ZW5lciBzdXIgTlVMTCBwb3VyICcnezB9JycifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgU3RyZWFtU291cmNlLCBTQVhTb3VyY2UgYW5kIERPTVNvdXJjZSBhcmUgSmF2YQotICAgICAgICAgKiBpbnRlcmZhY2UgbmFtZXMgdGhhdCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSkFYUF9VTktOT1dOX1NPVVJDRV9FUlIsCi0gICAgICAgICJTZXVscyBTdHJlYW1Tb3VyY2UsIFNBWFNvdXJjZSBldCBET01Tb3VyY2Ugc29udCBwcmlzIGVuIGNoYXJnZSBwYXIgWFNMVEMifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIlNvdXJjZSIgaXMgYSBKYXZhIGNsYXNzIG5hbWUgdGhhdCBzaG91bGQgbm90Ci0gICAgICAgICAqIGJlIHRyYW5zbGF0ZWQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgSmF2YSBtZXRob2QuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSkFYUF9OT19TT1VSQ0VfRVJSLAotICAgICAgICAiTCcnb2JqZXQgU291cmNlIHRyYW5zbWlzIFx1MDBFMCAnJ3swfScnIG4nJ2EgcGFzIGRlIGNvbnRlbnUuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBtZXNzYWdlIGluZGljYXRlcyB0aGF0IFhTTFRDIGZhaWxlZCB0bwotICAgICAgICAgKiBjb21waWxlIHRoZSBzdHlsZXNoZWV0IGludG8gYSB0cmFuc2xldCAoY2xhc3MgZmlsZSkuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSkFYUF9DT01QSUxFX0VSUiwKLSAgICAgICAgIkltcG9zc2libGUgZGUgY29tcGlsZXIgbGEgZmV1aWxsZSBkZSBzdHlsZSJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiVHJhbnNmb3JtZXJGYWN0b3J5IiBpcyBhIGNsYXNzIG5hbWUuICBJbiB0aGlzCi0gICAgICAgICAqIGNvbnRleHQsIGFuIGF0dHJpYnV0ZSBpcyBhIHByb3BlcnR5IG9yIHNldHRpbmcgb2YgdGhlCi0gICAgICAgICAqIFRyYW5zZm9ybWVyRmFjdG9yeSBvYmplY3QuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgdGhlCi0gICAgICAgICAqIHVucmVjb2duaXNlZCBhdHRyaWJ1dGUuICBUaGUgbWV0aG9kIHVzZWQgdG8gcmV0cmlldmUgdGhlIGF0dHJpYnV0ZSBpcwotICAgICAgICAgKiAiZ2V0QXR0cmlidXRlIiwgc28gaXQncyBub3QgY2xlYXIgd2hldGhlciBpdCB3b3VsZCBiZSBiZXN0IHRvCi0gICAgICAgICAqIHRyYW5zbGF0ZSB0aGUgdGVybSAiYXR0cmlidXRlIi4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX0lOVkFMSURfQVRUUl9FUlIsCi0gICAgICAgICJUcmFuc2Zvcm1lckZhY3RvcnkgbmUgcmVjb25uYVx1MDBFRXQgcGFzIGwnJ2F0dHJpYnV0ICcnezB9JycuIn0sCi0KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfSU5WQUxJRF9BVFRSX1ZBTFVFX0VSUiwKLSAgICAgICAgIkxhIHZhbGV1ciBpbmRpcXVcdTAwRTllIHBvdXIgbCcnYXR0cmlidXQgJyd7MH0nJyBlc3QgaW5jb3JyZWN0ZS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgInNldFJlc3VsdCgpIiBhbmQgInN0YXJ0RG9jdW1lbnQoKSIgYXJlIEphdmEKLSAgICAgICAgICogbWV0aG9kIG5hbWVzIHRoYXQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfU0VUX1JFU1VMVF9FUlIsCi0gICAgICAgICJzZXRSZXN1bHQoKSBkb2l0IFx1MDBFQXRyZSBhcHBlbFx1MDBFOSBhdmFudCBzdGFydERvY3VtZW50KCkuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJUcmFuc2Zvcm1lciIgaXMgYSBKYXZhIGludGVyZmFjZSBuYW1lIHRoYXQKLSAgICAgICAgICogc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgQSBUcmFuc2Zvcm1lciBvYmplY3Qgc2hvdWxkIGNvbnRhaW5lZCBhCi0gICAgICAgICAqIHJlZmVyZW5jZSB0byBhIHRyYW5zbGV0IG9iamVjdCBpbiBvcmRlciB0byBiZSB1c2VkIGZvcgotICAgICAgICAgKiB0cmFuc2Zvcm1hdGlvbnM7IHRoaXMgbWVzc2FnZSBpcyBwcm9kdWNlZCBpZiB0aGF0IHJlcXVpcmVtZW50IGlzIG5vdAotICAgICAgICAgKiBtZXQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSkFYUF9OT19UUkFOU0xFVF9FUlIsCi0gICAgICAgICJMYSBjbGFzc2UgVHJhbnNmb3JtZXIgbmUgY29udGllbnQgcGFzIGQnb2JqZXQgdHJhbnNsZXQgZW5jYXBzdWxcdTAwRTkuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBYTUwgZG9jdW1lbnQgdGhhdCByZXN1bHRzIGZyb20gYQotICAgICAgICAgKiB0cmFuc2Zvcm1hdGlvbiBuZWVkcyB0byBiZSBzZW50IHRvIGFuIG91dHB1dCBoYW5kbGVyIG9iamVjdDsgdGhpcwotICAgICAgICAgKiBtZXNzYWdlIGlzIHByb2R1Y2VkIGlmIHRoYXQgcmVxdWlyZW1lbnQgaXMgbm90IG1ldC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX05PX0hBTkRMRVJfRVJSLAotICAgICAgICAiQXVjdW4gZ2VzdGlvbm5haXJlIGRlIHNvcnRpZSBkXHUwMEU5ZmluaSBwb3VyIGxlIHJcdTAwRTlzdWx0YXQgZGUgbGEgdHJhbnNmb3JtYXRpb24uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJSZXN1bHQiIGlzIGEgSmF2YSBpbnRlcmZhY2UgbmFtZSBpbiB0aGlzCi0gICAgICAgICAqIGNvbnRleHQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgYSBtZXRob2QgbmFtZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX05PX1JFU1VMVF9FUlIsCi0gICAgICAgICJMJydvYmpldCBkZSByXHUwMEU5c3VsdGF0IHRyYW5zbWlzIFx1MDBFMCAnJ3swfScnIG4nJ2VzdCBwYXMgdmFsaWRlLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiVHJhbnNmb3JtZXIiIGlzIGEgSmF2YSBpbnRlcmZhY2UgbmFtZS4gIFRoZQotICAgICAgICAgKiB1c2VyJ3MgcHJvZ3JhbSBhdHRlbXB0ZWQgdG8gYWNjZXNzIGFuIHVucmVjb2duaXplZCBwcm9wZXJ0eSB3aXRoIHRoZQotICAgICAgICAgKiBuYW1lIHNwZWNpZmllZCBpbiB0aGUgc3Vic3RpdHV0aW9uIHRleHQuICBUaGUgbWV0aG9kIHVzZWQgdG8gcmV0cmlldmUKLSAgICAgICAgICogdGhlIHByb3BlcnR5IGlzICJnZXRPdXRwdXRQcm9wZXJ0eSIsIHNvIGl0J3Mgbm90IGNsZWFyIHdoZXRoZXIgaXQKLSAgICAgICAgICogd291bGQgYmUgYmVzdCB0byB0cmFuc2xhdGUgdGhlIHRlcm0gInByb3BlcnR5Ii4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX1VOS05PV05fUFJPUF9FUlIsCi0gICAgICAgICJUZW50YXRpdmUgZCcnYWNjXHUwMEU4cyBcdTAwRTAgbGEgcHJvcHJpXHUwMEU5dFx1MDBFOSBUcmFuc2Zvcm1lciBub24gdmFsaWRlICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFNBWDJET00gaXMgdGhlIG5hbWUgb2YgYSBKYXZhIGNsYXNzIHRoYXQgc2hvdWxkCi0gICAgICAgICAqIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhpcyBpcyBhbiBhZGFwdGVyIGluIHRoZSBzZW5zZSB0aGF0IGl0IHRha2VzIGEKLSAgICAgICAgICogRE9NIG9iamVjdCBhbmQgY29udmVydHMgaXQgdG8gc29tZXRoaW5nIHRoYXQgdXNlcyB0aGUgU0FYIEFQSS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5TQVgyRE9NX0FEQVBURVJfRVJSLAotICAgICAgICAiSW1wb3NzaWJsZSBkZSBjclx1MDBFOWVyIGwnJ2FkYXB0YXRldXIgU0FYMkRPTSA6ICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJYU0xUQ1NvdXJjZS5idWlsZCgpIiBpcyBhIEphdmEgbWV0aG9kIG5hbWUuCi0gICAgICAgICAqICJzeXN0ZW1JZCIgaXMgYW4gWE1MIHRlcm0gdGhhdCBpcyBzaG9ydCBmb3IgInN5c3RlbSBpZGVudGlmaWNhdGlvbiIuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuWFNMVENfU09VUkNFX0VSUiwKLSAgICAgICAgIlhTTFRDU291cmNlLmJ1aWxkKCkgYXBwZWxcdTAwRTkgc2FucyBxdWUgbCdJRCBzeXN0XHUwMEU4bWUgc29pdCBkXHUwMEU5ZmluaS4ifSwKLQotICAgICAgICB7IEVycm9yTXNnLkVSX1JFU1VMVF9OVUxMLAotICAgICAgICAgICAgIkxlIHJcdTAwRTlzdWx0YXQgbmUgZG9pdCBwYXMgXHUwMEVBdHJlIE5VTEwifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoZSB2YWx1ZSBhcmd1bWVudAotICAgICAgICAgKiBvZiBzZXRQYXJhbWV0ZXIgbXVzdCBiZSBhIHZhbGlkIEphdmEgT2JqZWN0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfSU5WQUxJRF9TRVRfUEFSQU1fVkFMVUUsCi0gICAgICAgICJMYSB2YWxldXIgZHUgcGFyYW1cdTAwRTh0cmUgezB9IGRvaXQgXHUwMEVBdHJlIHVuIG9iamV0IEphdmEgdmFsaWRlIn0sCi0KLQotICAgICAgICB7RXJyb3JNc2cuQ09NUElMRV9TVERJTl9FUlIsCi0gICAgICAgICJMJ29wdGlvbiAtaSBkb2l0IFx1MDBFQXRyZSB1dGlsaXNcdTAwRTllIGF2ZWMgbCdvcHRpb24gLW8uIn0sCi0KLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGNvbnRhaW5zIHVzYWdlIGluZm9ybWF0aW9uIGZvciBhCi0gICAgICAgICAqIG1lYW5zIG9mIGludm9raW5nIFhTTFRDIGZyb20gdGhlIGNvbW1hbmQtbGluZS4gIFRoZSBtZXNzYWdlIGlzCi0gICAgICAgICAqIGZvcm1hdHRlZCBmb3IgcHJlc2VudGF0aW9uIGluIEVuZ2xpc2guICBUaGUgc3RyaW5ncyA8b3V0cHV0PiwKLSAgICAgICAgICogPGRpcmVjdG9yeT4sIGV0Yy4gaW5kaWNhdGUgdXNlci1zcGVjaWZpZWQgYXJndW1lbnQgdmFsdWVzLCBhbmQgY2FuCi0gICAgICAgICAqIGJlIHRyYW5zbGF0ZWQgLSB0aGUgYXJndW1lbnQgPHBhY2thZ2U+IHJlZmVycyB0byBhIEphdmEgcGFja2FnZSwgc28KLSAgICAgICAgICogaXQgc2hvdWxkIGJlIGhhbmRsZWQgaW4gdGhlIHNhbWUgd2F5IHRoZSB0ZXJtIGlzIGhhbmRsZWQgZm9yIEpESwotICAgICAgICAgKiBkb2N1bWVudGF0aW9uLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkNPTVBJTEVfVVNBR0VfU1RSLAotICAgICAgICAiU1lOVEFYRVxuICAgamF2YSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY21kbGluZS5Db21waWxlIFstbyA8b3V0cHV0Pl1cbiAgICAgIFstZCA8ZGlyZWN0b3J5Pl0gWy1qIDxqYXJmaWxlPl0gWy1wIDxwYWNrYWdlPl1cbiAgICAgIFstbl0gWy14XSBbLXVdIFstdl0gWy1oXSB7IDxzdHlsZXNoZWV0PiB8IC1pIH1cblxuT1BUSU9OU1xuICAgLW8gPG91dHB1dD4gICAgYXR0cmlidWUgbGUgbm9tIDxvdXRwdXQ+IGF1XG4gICAgICAgICAgICAgICAgICB0cmFuc2xldCBnXHUwMEU5blx1MDBFOXJcdTAwRTkuIFBhciBkXHUwMEU5ZmF1dCwgbGUgbm9tIGR1IHRyYW5zbGV0IGVzdFxuICAgICAgICAgICAgICAgICAgZFx1MDBFOXJpdlx1MDBFOSBkdSBub20gPHN0eWxlc2hlZXQ+LiBDZXR0ZSBvcHRpb25cbiAgICAgICAgICAgICAgICAgIG4nZXN0IHBhcyBwcmlzZSBlbiBjb21wdGUgbG9ycyBkZSBsYSBjb21waWxhdGlvbiBkZSBwbHVzaWV1cnMgZmV1aWxsZXMgZGUgc3R5bGUuXG4gICAtZCA8ZGlyZWN0b3J5PiBpbmRpcXVlIHVuIHJcdTAwRTlwZXJ0b2lyZSBkZSBkZXN0aW5hdGlvbiBwb3VyIGxlIHRyYW5zbGV0XG4gICAtaiA8amFyZmlsZT4gICBwYWNrYWdlIGxlcyBjbGFzc2VzIGRlIHRyYW5zbGV0IGRhbnMgdW4gZmljaGllciBKQVIgcG9ydGFudCBsZVxuICAgICAgICAgICAgICAgICAgbm9tIHNwXHUwMEU5Y2lmaVx1MDBFOSBjb21tZSA8amFyZmlsZT5cbiAgIC1wIDxwYWNrYWdlPiAgIGluZGlxdWUgdW4gcHJcdTAwRTlmaXhlIGRlIG5vbSBkZSBwYWNrYWdlIHBvdXIgdG91dGVzIGxlc1xuICAgICAgICAgICAgICAgICAgY2xhc3NlcyBkZSB0cmFuc2xldCBnXHUwMEU5blx1MDBFOXJcdTAwRTllcy5cbiAgIC1uICAgICAgICAgICAgIGFjdGl2ZSBsZSBtb2RlIElOTElORSBkdSBtb2RcdTAwRThsZSAoY29tcG9ydGVtZW50IHBhciBkXHUwMEU5ZmF1dCBhbVx1MDBFOWxpb3JcdTAwRTlcbiAgICAgICAgICAgICAgICAgIGVuIG1veWVubmUpLlxuICAgLXggICAgICAgICAgICAgYWN0aXZlIGxhIHNvcnRpZSBkZSBtZXNzYWdlcyBkZSBkXHUwMEU5Ym9nYWdlIHN1cHBsXHUwMEU5bWVudGFpcmVzXG4gICAtdSAgICAgICAgICAgICBpbnRlcnByXHUwMEU4dGUgbGVzIGFyZ3VtZW50cyA8c3R5bGVzaGVldD4gY29tbWUgZGVzIFVSTFxuICAgLWkgICAgICAgICAgICAgZm9yY2UgbGUgY29tcGlsYXRldXIgXHUwMEUwIGxpcmUgbGEgZmV1aWxsZSBkZSBzdHlsZSBcdTAwRTAgcGFydGlyIGRlIFNURElOXG4gICAtdiAgICAgICAgICAgICBhZmZpY2hlIGxhIHZlcnNpb24gZHUgY29tcGlsYXRldXJcbiAgIC1oICAgICAgICAgICAgIGFmZmljaGUgY2V0dGUgaW5zdHJ1Y3Rpb24gZGUgc3ludGF4ZVxuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBjb250YWlucyB1c2FnZSBpbmZvcm1hdGlvbiBmb3IgYQotICAgICAgICAgKiBtZWFucyBvZiBpbnZva2luZyBYU0xUQyBmcm9tIHRoZSBjb21tYW5kLWxpbmUuICBUaGUgbWVzc2FnZSBpcwotICAgICAgICAgKiBmb3JtYXR0ZWQgZm9yIHByZXNlbnRhdGlvbiBpbiBFbmdsaXNoLiAgVGhlIHN0cmluZ3MgPGphcmZpbGU+LAotICAgICAgICAgKiA8ZG9jdW1lbnQ+LCBldGMuIGluZGljYXRlIHVzZXItc3BlY2lmaWVkIGFyZ3VtZW50IHZhbHVlcywgYW5kIGNhbgotICAgICAgICAgKiBiZSB0cmFuc2xhdGVkIC0gdGhlIGFyZ3VtZW50IDxjbGFzcz4gcmVmZXJzIHRvIGEgSmF2YSBjbGFzcywgc28gaXQKLSAgICAgICAgICogc2hvdWxkIGJlIGhhbmRsZWQgaW4gdGhlIHNhbWUgd2F5IHRoZSB0ZXJtIGlzIGhhbmRsZWQgZm9yIEpESwotICAgICAgICAgKiBkb2N1bWVudGF0aW9uLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlRSQU5TRk9STV9VU0FHRV9TVFIsCi0gICAgICAgICJTWU5UQVhFIFxuICAgamF2YSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY21kbGluZS5UcmFuc2Zvcm0gWy1qIDxqYXJmaWxlPl1cbiAgICAgIFsteF0gWy1uIDxpdGVyYXRpb25zPl0gey11IDxkb2N1bWVudF91cmw+IHwgPGRvY3VtZW50Pn1cbiAgICAgIDxjbGFzcz4gWzxwYXJhbTE+PTx2YWx1ZTE+IC4uLl1cblxuICAgdXRpbGlzZSBsZSB0cmFuc2xldCA8Y2xhc3M+IHBvdXIgdHJhbnNmb3JtZXIgdW4gZG9jdW1lbnQgWE1MXG4gICBzcFx1MDBFOWNpZmlcdTAwRTkgY29tbWUgPGRvY3VtZW50Pi4gTGUgdHJhbnNsZXQgPGNsYXNzPiBlc3Qgc29pdCBkYW5zXG4gICBsYSB2YXJpYWJsZSBkJ2Vudmlyb25uZW1lbnQgQ0xBU1NQQVRIIGRlIGwndXRpbGlzYXRldXIsIHNvaXQgZGFucyB1biBmaWNoaWVyIDxqYXJmaWxlPiBpbmRpcXVcdTAwRTkgZW4gb3B0aW9uLlxuT1BUSU9OU1xuICAgLWogPGphcmZpbGU+ICAgIGluZGlxdWUgdW4gZmljaGllciBKQVIgXHUwMEUwIHBhcnRpciBkdXF1ZWwgY2hhcmdlciBsZSB0cmFuc2xldFxuICAgLXggICAgICAgICAgICAgIGFjdGl2ZSBsYSBzb3J0aWUgZGUgbWVzc2FnZXMgZGUgZFx1MDBFOWJvZ2FnZSBzdXBwbFx1MDBFOW1lbnRhaXJlc1xuICAgLW4gPGl0ZXJhdGlvbnM+IGV4XHUwMEU5Y3V0ZSBsYSB0cmFuc2Zvcm1hdGlvbiA8aXRlcmF0aW9ucz4gZm9pcyBldFxuICAgICAgICAgICAgICAgICAgIGFmZmljaGUgbGVzIGluZm9ybWF0aW9ucyBkZSBwcm9maWxhZ2VcbiAgIC11IDxkb2N1bWVudF91cmw+IHNwXHUwMEU5Y2lmaWUgbGUgZG9jdW1lbnQgZCdlbnRyXHUwMEU5ZSBYTUwgY29tbWUgVVJMXG4ifSwKLQotCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICI8eHNsOnNvcnQ+IiwgIjx4c2w6Zm9yLWVhY2g+IiBhbmQKLSAgICAgICAgICogIjx4c2w6YXBwbHktdGVtcGxhdGVzPiIgYXJlIGtleXdvcmRzIHRoYXQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLgotICAgICAgICAgKiBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCBhbiB4c2w6c29ydCBlbGVtZW50IG11c3QgYmUgYSBjaGlsZCBvZgotICAgICAgICAgKiBvbmUgb2YgdGhlIG90aGVyIGtpbmRzIG9mIGVsZW1lbnRzIG1lbnRpb25lZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5TVFJBWV9TT1JUX0VSUiwKLSAgICAgICAgIjx4c2w6c29ydD4gcGV1dCB1bmlxdWVtZW50IFx1MDBFQXRyZSB1dGlsaXNcdTAwRTkgZGFucyA8eHNsOmZvci1lYWNoPiBvdSA8eHNsOmFwcGx5LXRlbXBsYXRlcz4uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoZSBlbmNvZGluZwotICAgICAgICAgKiByZXF1ZXN0ZWQgZm9yIHRoZSBvdXRwdXQgZG9jdW1lbnQgd2FzIG9uIHRoYXQgcmVxdWlyZXMgc3VwcG9ydCB0aGF0Ci0gICAgICAgICAqIGlzIG5vdCBhdmFpbGFibGUgZnJvbSB0aGUgSmF2YSBWaXJ0dWFsIE1hY2hpbmUgYmVpbmcgdXNlZCB0byBleGVjdXRlCi0gICAgICAgICAqIHRoZSBwcm9ncmFtLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlVOU1VQUE9SVEVEX0VOQ09ESU5HLAotICAgICAgICAiTCcnZW5jb2RhZ2UgZGUgc29ydGllICcnezB9JycgbicnZXN0IHBhcyBwcmlzIGVuIGNoYXJnZSBzdXIgY2V0dGUgSmF2YSBWaXJ0dWFsIE1hY2hpbmUgKEpWTSkuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoZSBYUGF0aCBleHByZXNzaW9uCi0gICAgICAgICAqIG5hbWVkIGluIHRoZSBzdWJzdGl0dXRpb24gdGV4dCB3YXMgbm90IHdlbGwgZm9ybWVkIHN5bnRhY3RpY2FsbHkuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuU1lOVEFYX0VSUiwKLSAgICAgICAgIkVycmV1ciBkZSBzeW50YXhlIGRhbnMgJyd7MH0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIGEgSmF2YQotICAgICAgICAgKiBjbGFzcy4gIFRoZSB0ZXJtICJjb25zdHJ1Y3RvciIgaGVyZSBpcyB0aGUgSmF2YSB0ZXJtLiAgVGhlIG1lc3NhZ2UgaXMKLSAgICAgICAgICogZGlzcGxheWVkIGlmIFhTTFRDIGNvdWxkIG5vdCBmaW5kIGEgY29uc3RydWN0b3IgZm9yIHRoZSBzcGVjaWZpZWQKLSAgICAgICAgICogY2xhc3MuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuQ09OU1RSVUNUT1JfTk9UX0ZPVU5ELAotICAgICAgICAiQ29uc3RydWN0ZXVyICcnezB9JycgZXh0ZXJuZSBpbnRyb3V2YWJsZS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgInN0YXRpYyIgaXMgdGhlIEphdmEga2V5d29yZC4gIFRoZSBzdWJzdGl0dXRpb24KLSAgICAgICAgICogdGV4dCBpcyB0aGUgbmFtZSBvZiBhIGZ1bmN0aW9uLiAgVGhlIGZpcnN0IGFyZ3VtZW50IG9mIHRoYXQgZnVuY3Rpb24KLSAgICAgICAgICogaXMgbm90IG9mIHRoZSByZXF1aXJlZCB0eXBlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk5PX0pBVkFfRlVOQ1RfVEhJU19SRUYsCi0gICAgICAgICJMZSBwcmVtaWVyIGFyZ3VtZW50IHBvdXIgbGEgZm9uY3Rpb24gSmF2YSAnJ3swfScnIG5vbiBzdGF0aWMgbicnZXN0IHBhcyB1bmUgclx1MDBFOWZcdTAwRTlyZW5jZSBkJydvYmpldCB2YWxpZGUuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIFhQYXRoIGV4cHJlc3Npb24gd2FzIG5vdCBvZiB0aGUgdHlwZQotICAgICAgICAgKiByZXF1aXJlZCBpbiBhIHBhcnRpY3VsYXIgY29udGV4dC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUKLSAgICAgICAgICogZXhwcmVzc2lvbiB0aGF0IHdhcyBpbiBlcnJvci4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5UWVBFX0NIRUNLX0VSUiwKLSAgICAgICAgIkVycmV1ciBsb3JzIGRlIGxhIHZcdTAwRTlyaWZpY2F0aW9uIGR1IHR5cGUgZGUgbCcnZXhwcmVzc2lvbiAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBbiBYUGF0aCBleHByZXNzaW9uIHdhcyBub3Qgb2YgdGhlIHR5cGUKLSAgICAgICAgICogcmVxdWlyZWQgaW4gYSBwYXJ0aWN1bGFyIGNvbnRleHQuICBIb3dldmVyLCB0aGUgbG9jYXRpb24gb2YgdGhlCi0gICAgICAgICAqIHByb2JsZW1hdGljIGV4cHJlc3Npb24gaXMgdW5rbm93bi4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5UWVBFX0NIRUNLX1VOS19MT0NfRVJSLAotICAgICAgICAiRXJyZXVyIGxvcnMgZGUgbGEgdlx1MDBFOXJpZmljYXRpb24gZHUgdHlwZSBkJ2V4cHJlc3Npb24gXHUwMEUwIHVuIGVtcGxhY2VtZW50IGluY29ubnUuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBhIGNvbW1hbmQtCi0gICAgICAgICAqIGxpbmUgb3B0aW9uIHRoYXQgd2FzIG5vdCByZWNvZ25pemVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfQ01ETElORV9PUFRJT05fRVJSLAotICAgICAgICAiTCcnb3B0aW9uIGRlIGxpZ25lIGRlIGNvbW1hbmRlICcnezB9JycgbicnZXN0IHBhcyB2YWxpZGUuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBhIGNvbW1hbmQtCi0gICAgICAgICAqIGxpbmUgb3B0aW9uLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkNNRExJTkVfT1BUX01JU1NJTkdfQVJHX0VSUiwKLSAgICAgICAgIkFyZ3VtZW50IG9ibGlnYXRvaXJlIG1hbnF1YW50IGRhbnMgbCcnb3B0aW9uIGRlIGxpZ25lIGRlIGNvbW1hbmRlICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyB1c2VkIHRvIGluZGljYXRlIHRoZSBzZXZlcml0eQotICAgICAgICAgKiBvZiBhbm90aGVyIG1lc3NhZ2UuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgY29udGFpbnMgdHdvIGVycm9yCi0gICAgICAgICAqIG1lc3NhZ2VzLiAgVGhlIHNwYWNpbmcgYmVmb3JlIHRoZSBzZWNvbmQgc3Vic3RpdHV0aW9uIHRleHQgaW5kZW50cwotICAgICAgICAgKiBpdCB0aGUgc2FtZSBhbW91bnQgYXMgdGhlIGZpcnN0IGluIEVuZ2xpc2guCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuV0FSTklOR19QTFVTX1dSQVBQRURfTVNHLAotICAgICAgICAiV0FSTklORzogICcnezB9JydcbiAgICAgICA6ezF9In0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyB1c2VkIHRvIGluZGljYXRlIHRoZSBzZXZlcml0eQotICAgICAgICAgKiBvZiBhbm90aGVyIG1lc3NhZ2UuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgYW4gZXJyb3IgbWVzc2FnZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5XQVJOSU5HX01TRywKLSAgICAgICAgIldBUk5JTkc6ICAnJ3swfScnIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyB1c2VkIHRvIGluZGljYXRlIHRoZSBzZXZlcml0eQotICAgICAgICAgKiBvZiBhbm90aGVyIG1lc3NhZ2UuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgY29udGFpbnMgdHdvIGVycm9yCi0gICAgICAgICAqIG1lc3NhZ2VzLiAgVGhlIHNwYWNpbmcgYmVmb3JlIHRoZSBzZWNvbmQgc3Vic3RpdHV0aW9uIHRleHQgaW5kZW50cwotICAgICAgICAgKiBpdCB0aGUgc2FtZSBhbW91bnQgYXMgdGhlIGZpcnN0IGluIEVuZ2xpc2guCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuRkFUQUxfRVJSX1BMVVNfV1JBUFBFRF9NU0csCi0gICAgICAgICJGQVRBTCBFUlJPUjogICcnezB9JydcbiAgICAgICAgICAgOnsxfSJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgdXNlZCB0byBpbmRpY2F0ZSB0aGUgc2V2ZXJpdHkKLSAgICAgICAgICogb2YgYW5vdGhlciBtZXNzYWdlLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIGFuIGVycm9yIG1lc3NhZ2UuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuRkFUQUxfRVJSX01TRywKLSAgICAgICAgIkZBVEFMIEVSUk9SOiAgJyd7MH0nJyJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgdXNlZCB0byBpbmRpY2F0ZSB0aGUgc2V2ZXJpdHkKLSAgICAgICAgICogb2YgYW5vdGhlciBtZXNzYWdlLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGNvbnRhaW5zIHR3byBlcnJvcgotICAgICAgICAgKiBtZXNzYWdlcy4gIFRoZSBzcGFjaW5nIGJlZm9yZSB0aGUgc2Vjb25kIHN1YnN0aXR1dGlvbiB0ZXh0IGluZGVudHMKLSAgICAgICAgICogaXQgdGhlIHNhbWUgYW1vdW50IGFzIHRoZSBmaXJzdCBpbiBFbmdsaXNoLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkVSUk9SX1BMVVNfV1JBUFBFRF9NU0csCi0gICAgICAgICJFUlJPUjogICcnezB9JydcbiAgICAgOnsxfSJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgdXNlZCB0byBpbmRpY2F0ZSB0aGUgc2V2ZXJpdHkKLSAgICAgICAgICogb2YgYW5vdGhlciBtZXNzYWdlLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIGFuIGVycm9yIG1lc3NhZ2UuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuRVJST1JfTVNHLAotICAgICAgICAiRVJST1I6ICAnJ3swfScnIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBhIGNsYXNzLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlRSQU5TRk9STV9XSVRIX1RSQU5TTEVUX1NUUiwKLSAgICAgICAgIlRyYW5zZm9ybWF0aW9uIFx1MDBFMCBsJydhaWRlIGR1IHRyYW5zbGV0ICcnezB9JycgIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmaXJzdCBzdWJzdGl0dXRpb24gaXMgdGhlIG5hbWUgb2YgYSBjbGFzcywKLSAgICAgICAgICogd2hpbGUgdGhlIHNlY29uZCBzdWJzdGl0dXRpb24gaXMgdGhlIG5hbWUgb2YgYSBqYXIgZmlsZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5UUkFOU0ZPUk1fV0lUSF9KQVJfU1RSLAotICAgICAgICAiVHJhbnNmb3JtYXRpb24gXHUwMEUwIGwnJ2FpZGUgZHUgdHJhbnNsZXQgJyd7MH0nJyBkYW5zIGxlIGZpY2hpZXIgSkFSICcnezF9JycifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIlRyYW5zZm9ybWVyRmFjdG9yeSIgaXMgdGhlIG5hbWUgb2YgYSBKYXZhCi0gICAgICAgICAqIGludGVyZmFjZSBhbmQgbXVzdCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcwotICAgICAgICAgKiB0aGUgbmFtZSBvZiB0aGUgY2xhc3MgdGhhdCBjb3VsZCBub3QgYmUgaW5zdGFudGlhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkNPVUxEX05PVF9DUkVBVEVfVFJBTlNfRkFDVCwKLSAgICAgICAgIkltcG9zc2libGUgZGUgY3JcdTAwRTllciB1bmUgaW5zdGFuY2UgZGUgbGEgY2xhc3NlIFRyYW5zZm9ybWVyRmFjdG9yeSAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgcHJvZHVjZWQgd2hlbiB0aGUgdXNlcgotICAgICAgICAgKiBzcGVjaWZpZWQgYSBuYW1lIGZvciB0aGUgdHJhbnNsZXQgY2xhc3MgdGhhdCBjb250YWlucyBjaGFyYWN0ZXJzCi0gICAgICAgICAqIHRoYXQgYXJlIG5vdCBwZXJtaXR0ZWQgaW4gYSBKYXZhIGNsYXNzIG5hbWUuICBUaGUgc3Vic3RpdHV0aW9uCi0gICAgICAgICAqIHRleHQgInswfSIgc3BlY2lmaWVzIHRoZSBuYW1lIHRoZSB1c2VyIHJlcXVlc3RlZCwgd2hpbGUgInsxfSIKLSAgICAgICAgICogc3BlY2lmaWVzIHRoZSBuYW1lIHRoZSBwcm9jZXNzb3IgdXNlZCBpbnN0ZWFkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlRSQU5TTEVUX05BTUVfSkFWQV9DT05GTElDVCwKLSAgICAgICAgICJJbXBvc3NpYmxlIGQnJ3V0aWxpc2VyIGxlIG5vbSAnJ3swfScnIGNvbW1lIG5vbSBkZSBjbGFzc2UgZGUgdHJhbnNsZXQgY2FyIGlsIGNvbnRpZW50IGRlcyBjYXJhY3RcdTAwRThyZXMgbm9uIGF1dG9yaXNcdTAwRTlzIGRhbnMgbGUgbm9tIGRlIGxhIGNsYXNzZSBKYXZhLiBMZSBub20gJyd7MX0nJyBhIFx1MDBFOXRcdTAwRTkgdXRpbGlzXHUwMEU5IFx1MDBFMCBsYSBwbGFjZS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIGlzIHVzZWQgYXMgYSBoZWFkZXIuCi0gICAgICAgICAqIEFsbCB0aGUgZXJyb3IgbWVzc2FnZXMgYXJlIGNvbGxlY3RlZCB0b2dldGhlciBhbmQgZGlzcGxheWVkIGJlbmVhdGgKLSAgICAgICAgICogdGhpcyBtZXNzYWdlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkNPTVBJTEVSX0VSUk9SX0tFWSwKLSAgICAgICAgIkVycmV1cnMgZGUgY29tcGlsYXRldXIgOiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgaXMgdXNlZCBhcyBhIGhlYWRlci4KLSAgICAgICAgICogQWxsIHRoZSB3YXJuaW5nIG1lc3NhZ2VzIGFyZSBjb2xsZWN0ZWQgdG9nZXRoZXIgYW5kIGRpc3BsYXllZAotICAgICAgICAgKiBiZW5lYXRoIHRoaXMgbWVzc2FnZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5DT01QSUxFUl9XQVJOSU5HX0tFWSwKLSAgICAgICAgIkF2ZXJ0aXNzZW1lbnRzIGRlIGNvbXBpbGF0ZXVyIDoifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIGlzIHVzZWQgYXMgYSBoZWFkZXIuCi0gICAgICAgICAqIEFsbCB0aGUgZXJyb3IgbWVzc2FnZXMgdGhhdCBhcmUgcHJvZHVjZWQgd2hlbiB0aGUgc3R5bGVzaGVldCBpcwotICAgICAgICAgKiBhcHBsaWVkIHRvIGFuIGlucHV0IGRvY3VtZW50IGFyZSBjb2xsZWN0ZWQgdG9nZXRoZXIgYW5kIGRpc3BsYXllZAotICAgICAgICAgKiBiZW5lYXRoIHRoaXMgbWVzc2FnZS4gIEEgJ3RyYW5zbGV0JyBpcyB0aGUgY29tcGlsZWQgZm9ybSBvZiBhCi0gICAgICAgICAqIHN0eWxlc2hlZXQgKHNlZSBhYm92ZSkuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuUlVOVElNRV9FUlJPUl9LRVksCi0gICAgICAgICJFcnJldXJzIGRlIHRyYW5zbGV0IDoifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQW4gYXR0cmlidXRlIHdob3NlIHZhbHVlIGlzIGNvbnN0cmFpbmVkIHRvCi0gICAgICAgICAqIGJlIGEgIlFOYW1lIiBvciBhIGxpc3Qgb2YgIlFOYW1lcyIgaGFkIGEgdmFsdWUgdGhhdCB3YXMgaW5jb3JyZWN0LgotICAgICAgICAgKiAnUU5hbWUnIGlzIGFuIFhNTCBzeW50YWN0aWMgdGVybSB0aGF0IG11c3Qgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGUKLSAgICAgICAgICogc3Vic3RpdHV0aW9uIHRleHQgY29udGFpbnMgdGhlIGFjdHVhbCB2YWx1ZSBvZiB0aGUgYXR0cmlidXRlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklOVkFMSURfUU5BTUVfRVJSLAotICAgICAgICAiVW4gYXR0cmlidXQgZG9udCBsYSB2YWxldXIgZG9pdCBcdTAwRUF0cmUgdW4gUU5hbWUgb3UgdW5lIGxpc3RlIGRlIFFOYW1lcyBzXHUwMEU5cGFyXHUwMEU5cyBwYXIgZGVzIGVzcGFjZXMgYXZhaXQgbGEgdmFsZXVyICcnezB9JycifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQW4gYXR0cmlidXRlIHdob3NlIHZhbHVlIGlzIHJlcXVpcmVkIHRvCi0gICAgICAgICAqIGJlIGFuICJOQ05hbWUiLgotICAgICAgICAgKiAnTkNOYW1lJyBpcyBhbiBYTUwgc3ludGFjdGljIHRlcm0gdGhhdCBtdXN0IG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhlCi0gICAgICAgICAqIHN1YnN0aXR1dGlvbiB0ZXh0IGNvbnRhaW5zIHRoZSBhY3R1YWwgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTlZBTElEX05DTkFNRV9FUlIsCi0gICAgICAgICJVbiBhdHRyaWJ1dCBkb250IGxhIHZhbGV1ciBkb2l0IFx1MDBFQXRyZSB1biBOQ05hbWUgYXZhaXQgbGEgdmFsZXVyICcnezB9JycifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQW4gYXR0cmlidXRlIHdpdGggYW4gaW5jb3JyZWN0IHZhbHVlIHdhcwotICAgICAgICAgKiBlbmNvdW50ZXJlZC4gIFRoZSBwZXJtaXR0ZWQgdmFsdWUgaXMgb25lIG9mIHRoZSBsaXRlcmFsIHZhbHVlcwotICAgICAgICAgKiAieG1sIiwgImh0bWwiIG9yICJ0ZXh0IjsgaXQgaXMgYWxzbyBwZXJtaXR0ZWQgdG8gaGF2ZSB0aGUgZm9ybSBvZgotICAgICAgICAgKiBhIFFOYW1lIHRoYXQgaXMgbm90IGFsc28gYW4gTkNOYW1lLiAgVGhlIHRlcm1zICJtZXRob2QiLAotICAgICAgICAgKiAieHNsOm91dHB1dCIsICJ4bWwiLCAiaHRtbCIgYW5kICJ0ZXh0IiBhcmUga2V5d29yZHMgdGhhdCBtdXN0IG5vdAotICAgICAgICAgKiBiZSB0cmFuc2xhdGVkLiAgVGhlIHRlcm0gInFuYW1lLWJ1dC1ub3QtbmNuYW1lIiBpcyBhbiBYTUwgc3ludGFjdGljCi0gICAgICAgICAqIHRlcm0uICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgY29udGFpbnMgdGhlIGFjdHVhbCB2YWx1ZSBvZiB0aGUKLSAgICAgICAgICogYXR0cmlidXRlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklOVkFMSURfTUVUSE9EX0lOX09VVFBVVCwKLSAgICAgICAgIkwnJ2F0dHJpYnV0IFwibWV0aG9kXCIgZCcndW4gXHUwMEU5bFx1MDBFOW1lbnQgPHhzbDpvdXRwdXQ+IGF2YWl0IGxhIHZhbGV1ciAnJ3swfScnLiBMYSB2YWxldXIgZG9pdCBcdTAwRUF0cmUgbCcndW5lIGRlcyBzdWl2YW50ZXMgOiAnJ3htbCcnLCAnJ2h0bWwnJywgJyd0ZXh0Jycgb3UgcW5hbWUtYnV0LW5vdC1uY25hbWUifSwKLQotICAgICAgICB7RXJyb3JNc2cuSkFYUF9HRVRfRkVBVFVSRV9OVUxMX05BTUUsCi0gICAgICAgICJMZSBub20gZGUgbGEgZm9uY3Rpb25uYWxpdFx1MDBFOSBuZSBwZXV0IHBhcyBcdTAwRUF0cmUgTlVMTCBkYW5zIFRyYW5zZm9ybWVyRmFjdG9yeS5nZXRGZWF0dXJlIChjaGFcdTAwRUVuZSBwb3VyIGxlIG5vbSkuIn0sCi0KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfU0VUX0ZFQVRVUkVfTlVMTF9OQU1FLAotICAgICAgICAiTGUgbm9tIGRlIGxhIGZvbmN0aW9ubmFsaXRcdTAwRTkgbmUgcGV1dCBwYXMgXHUwMEVBdHJlIE5VTEwgZGFucyBUcmFuc2Zvcm1lckZhY3Rvcnkuc2V0RmVhdHVyZSAoY2hhXHUwMEVFbmUgcG91ciBsZSBub20sIHZhbGV1ciBib29sXHUwMEU5ZW5uZSkuIn0sCi0KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfVU5TVVBQT1JURURfRkVBVFVSRSwKLSAgICAgICAgIkltcG9zc2libGUgZGUgZFx1MDBFOWZpbmlyIGxhIGZvbmN0aW9ubmFsaXRcdTAwRTkgJyd7MH0nJyBzdXIgY2V0dGUgcHJvcHJpXHUwMEU5dFx1MDBFOSBUcmFuc2Zvcm1lckZhY3RvcnkuIn0sCi0KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfU0VDVVJFUFJPQ0VTU0lOR19GRUFUVVJFLAotICAgICAgICAiRkVBVFVSRV9TRUNVUkVfUFJPQ0VTU0lORyA6IGltcG9zc2libGUgZGUgZFx1MDBFOWZpbmlyIGxhIGZvbmN0aW9ubmFsaXRcdTAwRTkgc3VyIEZhbHNlIGVuIHByXHUwMEU5c2VuY2UgZHUgZ2VzdGlvbm5haXJlIGRlIHNcdTAwRTljdXJpdFx1MDBFOS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGRlc2NyaWJlcyBhbiBpbnRlcm5hbCBlcnJvciBpbiB0aGUKLSAgICAgICAgICogcHJvY2Vzc29yLiAgVGhlIHRlcm0gImJ5dGUgY29kZSIgaXMgYSBKYXZhIHRlY2huaWNhbCB0ZXJtIGZvciB0aGUKLSAgICAgICAgICogZXhlY3V0YWJsZSBjb2RlIGluIGEgSmF2YSBtZXRob2QsIGFuZCAidHJ5LWNhdGNoLWZpbmFsbHkgYmxvY2siCi0gICAgICAgICAqIHJlZmVycyB0byB0aGUgSmF2YSBrZXl3b3JkcyB3aXRoIHRob3NlIG5hbWVzLiAgIk91dGxpbmVkIiBpcyBhCi0gICAgICAgICAqIHRlY2huaWNhbCB0ZXJtIGludGVybmFsIHRvIFhTTFRDIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuT1VUTElORV9FUlJfVFJZX0NBVENILAotICAgICAgICAgIkVycmV1ciBYU0xUQyBpbnRlcm5lIDogbGUgY29kZSBleFx1MDBFOWN1dGFibGUgZ1x1MDBFOW5cdTAwRTlyXHUwMEU5IGNvbnRpZW50IHVuIGJsb2MgdHJ5LWNhdGNoLWZpbmFsbHkgZXQgbmUgcGV1dCBwYXMgXHUwMEVBdHJlIGRcdTAwRTlsaW1pdFx1MDBFOS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGRlc2NyaWJlcyBhbiBpbnRlcm5hbCBlcnJvciBpbiB0aGUKLSAgICAgICAgICogcHJvY2Vzc29yLiAgVGhlIHRlcm1zICJPdXRsaW5lYWJsZUNodW5rU3RhcnQiIGFuZAotICAgICAgICAgKiAiT3V0bGluZWFibGVDaHVua0VuZCIgYXJlIHRoZSBuYW1lcyBvZiBjbGFzc2VzIGludGVybmFsIHRvIFhTTFRDIGFuZAotICAgICAgICAgKiBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCBmb3IgZXZlcnkKLSAgICAgICAgICogInN0YXJ0IiB0aGVyZSBtdXN0IGJlIGEgY29ycmVzcG9uZGluZyAiZW5kIiwgYW5kIHZpY2UgdmVyc2EsIGFuZAotICAgICAgICAgKiB0aGF0IGlmIG9uZSBvZiBhIHBhaXIgb2YgInN0YXJ0IiBhbmQgImVuZCIgYXBwZWFycyBiZXR3ZWVuIGFub3RoZXIKLSAgICAgICAgICogcGFpciBvZiBjb3JyZXNwb25kaW5nICJzdGFydCIgYW5kICJlbmQiLCB0aGVuIHRoZSBvdGhlciBoYWxmIG9mIHRoZQotICAgICAgICAgKiBwYWlyIG11c3QgYWxzbyBiZSBiZXR3ZWVuIHRoYXQgc2FtZSBlbmNsb3NpbmcgcGFpci4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5PVVRMSU5FX0VSUl9VTkJBTEFOQ0VEX01BUktFUlMsCi0gICAgICAgICAiRXJyZXVyIFhTTFRDIGludGVybmUgOiBsZXMgbWFycXVldXJzIE91dGxpbmVhYmxlQ2h1bmtTdGFydCBldCBPdXRsaW5lYWJsZUNodW5rRW5kIGRvaXZlbnQgXHUwMEVBdHJlIFx1MDBFOXF1aWxpYnJcdTAwRTlzIGV0IGNvcnJlY3RlbWVudCBpbWJyaXF1XHUwMEU5cy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGRlc2NyaWJlcyBhbiBpbnRlcm5hbCBlcnJvciBpbiB0aGUKLSAgICAgICAgICogcHJvY2Vzc29yLiAgVGhlIHRlcm0gImJ5dGUgY29kZSIgaXMgYSBKYXZhIHRlY2huaWNhbCB0ZXJtIGZvciB0aGUKLSAgICAgICAgICogZXhlY3V0YWJsZSBjb2RlIGluIGEgSmF2YSBtZXRob2QuICBUaGUgIm1ldGhvZCIgdGhhdCBpcyBiZWluZwotICAgICAgICAgKiByZWZlcnJlZCB0byBpcyBhIEphdmEgbWV0aG9kIGluIGEgdHJhbnNsZXQgdGhhdCBYU0xUQyBpcyBnZW5lcmF0aW5nCi0gICAgICAgICAqIGluIHByb2Nlc3NpbmcgYSBzdHlsZXNoZWV0LiAgVGhlICJpbnN0cnVjdGlvbiIgdGhhdCBpcyBiZWluZwotICAgICAgICAgKiByZWZlcnJlZCB0byBpcyBvbmUgb2YgdGhlIGluc3RydXRpb25zIGluIHRoZSBKYXZhIGJ5dGUgY29kZSBpbiB0aGF0Ci0gICAgICAgICAqIG1ldGhvZC4gICJPdXRsaW5lZCIgaXMgYSB0ZWNobmljYWwgdGVybSBpbnRlcm5hbCB0byBYU0xUQyBhbmQKLSAgICAgICAgICogc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk9VVExJTkVfRVJSX0RFTEVURURfVEFSR0VULAotICAgICAgICAgIkVycmV1ciBYU0xUQyBpbnRlcm5lIDogdW5lIGluc3RydWN0aW9uIGF5YW50IGZhaXQgcGFydGllIGQndW4gYmxvYyBkZSBjb2RlIGV4XHUwMEU5Y3V0YWJsZSBkXHUwMEU5bGltaXRcdTAwRTkgZXN0IHRvdWpvdXJzIHJcdTAwRTlmXHUwMEU5cmVuY1x1MDBFOWUgZGFucyBsYSBtXHUwMEU5dGhvZGUgZCdvcmlnaW5lLiIKLSAgICAgICAgfSwKLQotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgZGVzY3JpYmVzIGFuIGludGVybmFsIGVycm9yIGluIHRoZQotICAgICAgICAgKiBwcm9jZXNzb3IuICBUaGUgIm1ldGhvZCIgdGhhdCBpcyBiZWluZyByZWZlcnJlZCB0byBpcyBhIEphdmEgbWV0aG9kCi0gICAgICAgICAqIGluIGEgdHJhbnNsZXQgdGhhdCBYU0xUQyBpcyBnZW5lcmF0aW5nLgotICAgICAgICAgKgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk9VVExJTkVfRVJSX01FVEhPRF9UT09fQklHLAotICAgICAgICAgIkVycmV1ciBYU0xUQyBpbnRlcm5lIDogdW5lIG1cdTAwRTl0aG9kZSBkYW5zIGxlIHRyYW5zbGV0IGRcdTAwRTlwYXNzZSBsYSBsaW1pdGUgZGUgbGEgSlZNIGNvbmNlcm5hbnQgbGEgbG9uZ3VldXIgZCd1bmUgbVx1MDBFOXRob2RlIGRlIDY0IGtpbG8tb2N0ZXRzLiBFbiBnXHUwMEU5blx1MDBFOXJhbCwgY2VjaSBlc3QgZFx1MDBGQiBcdTAwRTAgZGUgdHJcdTAwRThzIGdyYW5kcyBtb2RcdTAwRThsZXMgZGFucyB1bmUgZmV1aWxsZSBkZSBzdHlsZS4gRXNzYXlleiBkZSByZXN0cnVjdHVyZXIgbGEgZmV1aWxsZSBkZSBzdHlsZSBwb3VyIHV0aWxpc2VyIGRlcyBtb2RcdTAwRThsZXMgcGx1cyBwZXRpdHMuIgotICAgICAgICB9LAotCi0gICAgICAgICB7RXJyb3JNc2cuREVTRVJJQUxJWkVfVFJBTlNMRVRfRVJSLCAiTG9yc3F1ZSBsYSBzXHUwMEU5Y3VyaXRcdTAwRTkgSmF2YSBlc3QgYWN0aXZcdTAwRTllLCBsYSBwcmlzZSBlbiBjaGFyZ2UgZGUgbGEgZFx1MDBFOXNcdTAwRTlyaWFsaXNhdGlvbiBkZSBUZW1wbGF0ZXNJbXBsIGVzdCBkXHUwMEU5c2FjdGl2XHUwMEU5ZS4gTGEgZFx1MDBFOWZpbml0aW9uIGRlIGxhIHByb3ByaVx1MDBFOXRcdTAwRTkgc3lzdFx1MDBFOG1lIGpkay54bWwuZW5hYmxlVGVtcGxhdGVzSW1wbERlc2VyaWFsaXphdGlvbiBzdXIgVHJ1ZSBwZXJtZXQgZGUgcmVtcGxhY2VyIGNlIHBhcmFtXHUwMEU4dHJlLiJ9Ci0KLSAgICB9OwotCi0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci91dGlsL0Vycm9yTWVzc2FnZXNfaXQuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvdXRpbC9FcnJvck1lc3NhZ2VzX2l0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGU2MTBmZjUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci91dGlsL0Vycm9yTWVzc2FnZXNfaXQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDk3NCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWw7Ci0KLWltcG9ydCBqYXZhLnV0aWwuTGlzdFJlc291cmNlQnVuZGxlOwotCi0vKioKLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICovCi1wdWJsaWMgY2xhc3MgRXJyb3JNZXNzYWdlc19pdCBleHRlbmRzIExpc3RSZXNvdXJjZUJ1bmRsZSB7Ci0KLS8qCi0gKiBYU0xUQyBjb21waWxlLXRpbWUgZXJyb3IgbWVzc2FnZXMuCi0gKgotICogR2VuZXJhbCBub3RlcyB0byB0cmFuc2xhdG9ycyBhbmQgZGVmaW5pdGlvbnM6Ci0gKgotICogICAxKSBYU0xUQyBpcyB0aGUgbmFtZSBvZiB0aGUgcHJvZHVjdC4gIEl0IGlzIGFuIGFjcm9ueW0gZm9yICJYU0xUIENvbXBpbGVyIi4KLSAqICAgICAgWFNMVCBpcyBhbiBhY3JvbnltIGZvciAiWE1MIFN0eWxlc2hlZXQgTGFuZ3VhZ2U6IFRyYW5zZm9ybWF0aW9ucyIuCi0gKgotICogICAyKSBBIHN0eWxlc2hlZXQgaXMgYSBkZXNjcmlwdGlvbiBvZiBob3cgdG8gdHJhbnNmb3JtIGFuIGlucHV0IFhNTCBkb2N1bWVudAotICogICAgICBpbnRvIGEgcmVzdWx0YW50IFhNTCBkb2N1bWVudCAob3IgSFRNTCBkb2N1bWVudCBvciB0ZXh0KS4gIFRoZQotICogICAgICBzdHlsZXNoZWV0IGl0c2VsZiBpcyBkZXNjcmliZWQgaW4gdGhlIGZvcm0gb2YgYW4gWE1MIGRvY3VtZW50LgotICoKLSAqICAgMykgQSB0ZW1wbGF0ZSBpcyBhIGNvbXBvbmVudCBvZiBhIHN0eWxlc2hlZXQgdGhhdCBpcyB1c2VkIHRvIG1hdGNoIGEKLSAqICAgICAgcGFydGljdWxhciBwb3J0aW9uIG9mIGFuIGlucHV0IGRvY3VtZW50IGFuZCBzcGVjaWZpZXMgdGhlIGZvcm0gb2YgdGhlCi0gKiAgICAgIGNvcnJlc3BvbmRpbmcgcG9ydGlvbiBvZiB0aGUgb3V0cHV0IGRvY3VtZW50LgotICoKLSAqICAgNCkgQW4gYXhpcyBpcyBhIHBhcnRpY3VsYXIgImRpbWVuc2lvbiIgaW4gYSB0cmVlIHJlcHJlc2VudGF0aW9uIG9mIGFuIFhNTAotICogICAgICBkb2N1bWVudDsgdGhlIG5vZGVzIGluIHRoZSB0cmVlIGFyZSBkaXZpZGVkIGFsb25nIGRpZmZlcmVudCBheGVzLgotICogICAgICBUcmF2ZXJzaW5nIHRoZSAiY2hpbGQiIGF4aXMsIGZvciBpbnN0YW5jZSwgbWVhbnMgdGhhdCB0aGUgcHJvZ3JhbQotICogICAgICB3b3VsZCB2aXNpdCBlYWNoIGNoaWxkIG9mIGEgcGFydGljdWxhciBub2RlOyB0cmF2ZXJzaW5nIHRoZSAiZGVzY2VuZGFudCIKLSAqICAgICAgYXhpcyBtZWFucyB0aGF0IHRoZSBwcm9ncmFtIHdvdWxkIHZpc2l0IHRoZSBjaGlsZCBub2RlcyBvZiBhIHBhcnRpY3VsYXIKLSAqICAgICAgbm9kZSwgdGhlaXIgY2hpbGRyZW4sIGFuZCBzbyBvbiB1bnRpbCB0aGUgbGVhZiBub2RlcyBvZiB0aGUgdHJlZSBhcmUKLSAqICAgICAgcmVhY2hlZC4KLSAqCi0gKiAgIDUpIEFuIGl0ZXJhdG9yIGlzIGFuIG9iamVjdCB0aGF0IHRyYXZlcnNlcyBub2RlcyBpbiBhIHRyZWUgYWxvbmcgYQotICogICAgICBwYXJ0aWN1bGFyIGF4aXMsIG9uZSBhdCBhIHRpbWUuCi0gKgotICogICA2KSBBbiBlbGVtZW50IGlzIGEgbWFyay11cCB0YWcgaW4gYW4gWE1MIGRvY3VtZW50OyBhbiBhdHRyaWJ1dGUgaXMgYQotICogICAgICBtb2RpZmllciBvbiB0aGUgdGFnLiAgRm9yIGV4YW1wbGUsIGluIDxlbGVtIGF0dHI9J3ZhbCcgYXR0cjI9J3ZhbDInPgotICogICAgICAiZWxlbSIgaXMgYW4gZWxlbWVudCBuYW1lLCAiYXR0ciIgYW5kICJhdHRyMiIgYXJlIGF0dHJpYnV0ZSBuYW1lcyB3aXRoCi0gKiAgICAgIHRoZSB2YWx1ZXMgInZhbCIgYW5kICJ2YWwyIiwgcmVzcGVjdGl2ZWx5LgotICoKLSAqICAgNykgQSBuYW1lc3BhY2UgZGVjbGFyYXRpb24gaXMgYSBzcGVjaWFsIGF0dHJpYnV0ZSB0aGF0IGlzIHVzZWQgdG8gYXNzb2NpYXRlCi0gKiAgICAgIGEgcHJlZml4IHdpdGggYSBVUkkgKHRoZSBuYW1lc3BhY2UpLiAgVGhlIG1lYW5pbmdzIG9mIGVsZW1lbnQgbmFtZXMgYW5kCi0gKiAgICAgIGF0dHJpYnV0ZSBuYW1lcyB0aGF0IHVzZSB0aGF0IHByZWZpeCBhcmUgZGVmaW5lZCB3aXRoIHJlc3BlY3QgdG8gdGhhdAotICogICAgICBuYW1lc3BhY2UuCi0gKgotICogICA4KSBET00gaXMgYW4gYWNyb255bSBmb3IgRG9jdW1lbnQgT2JqZWN0IE1vZGVsLiAgSXQgaXMgYSB0cmVlCi0gKiAgICAgIHJlcHJlc2VudGF0aW9uIG9mIGFuIFhNTCBkb2N1bWVudC4KLSAqCi0gKiAgICAgIFNBWCBpcyBhbiBhY3JvbnltIGZvciB0aGUgU2ltcGxlIEFQSSBmb3IgWE1MIHByb2Nlc3NpbmcuICBJdCBpcyBhbiBBUEkKLSAqICAgICAgdXNlZCBpbmZvcm0gYW4gWE1MIHByb2Nlc3NvciAoaW4gdGhpcyBjYXNlIFhTTFRDKSBvZiB0aGUgc3RydWN0dXJlIGFuZAotICogICAgICBjb250ZW50IG9mIGFuIFhNTCBkb2N1bWVudC4KLSAqCi0gKiAgICAgIElucHV0IHRvIHRoZSBzdHlsZXNoZWV0IHByb2Nlc3NvciBjYW4gY29tZSBmcm9tIGFuIFhNTCBwYXJzZXIgaW4gdGhlCi0gKiAgICAgIGZvcm0gb2YgYSBET00gdHJlZSBvciB0aHJvdWdoIHRoZSBTQVggQVBJLgotICoKLSAqICAgOSkgRFREIGlzIGEgZG9jdW1lbnQgdHlwZSBkZWNsYXJhdGlvbi4gIEl0IGlzIGEgd2F5IG9mIHNwZWNpZnlpbmcgdGhlCi0gKiAgICAgIGdyYW1tYXIgZm9yIGFuIFhNTCBmaWxlLCB0aGUgbmFtZXMgYW5kIHR5cGVzIG9mIGVsZW1lbnRzLCBhdHRyaWJ1dGVzLAotICogICAgICBldGMuCi0gKgotICogIDEwKSBYUGF0aCBpcyBhIHNwZWNpZmljYXRpb24gdGhhdCBkZXNjcmliZXMgYSBub3RhdGlvbiBmb3IgaWRlbnRpZnlpbmcKLSAqICAgICAgbm9kZXMgaW4gYSB0cmVlLXN0cnVjdHVyZWQgcmVwcmVzZW50YXRpb24gb2YgYW4gWE1MIGRvY3VtZW50LiAgQW4KLSAqICAgICAgaW5zdGFuY2Ugb2YgdGhhdCBub3RhdGlvbiBpcyByZWZlcnJlZCB0byBhcyBhbiBYUGF0aCBleHByZXNzaW9uLgotICoKLSAqICAxMSkgVHJhbnNsZXQgaXMgYW4gaW52ZW50ZWQgdGVybSB0aGF0IHJlZmVycyB0byB0aGUgY2xhc3MgZmlsZSB0aGF0IGNvbnRhaW5zCi0gKiAgICAgIHRoZSBjb21waWxlZCBmb3JtIG9mIGEgc3R5bGVzaGVldC4KLSAqLwotCi0gICAgLy8gVGhlc2UgbWVzc2FnZSBzaG91bGQgYmUgcmVhZCBmcm9tIGEgbG9jYWxlLXNwZWNpZmljIHJlc291cmNlIGJ1bmRsZQotICAgIC8qKiBHZXQgdGhlIGxvb2t1cCB0YWJsZSBmb3IgZXJyb3IgbWVzc2FnZXMuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBtZXNzYWdlIGxvb2t1cCB0YWJsZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0W11bXSBnZXRDb250ZW50cygpCi0gICAgewotICAgICAgcmV0dXJuIG5ldyBPYmplY3RbXVtdIHsKLSAgICAgICAge0Vycm9yTXNnLk1VTFRJUExFX1NUWUxFU0hFRVRfRVJSLAotICAgICAgICAiU29ubyBzdGF0aSBkZWZpbml0aSBwaVx1MDBGOSBmb2dsaSBkaSBzdGlsZSBuZWxsbyBzdGVzc28gZmlsZS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIGEKLSAgICAgICAgICogdGVtcGxhdGUuICBUaGUgc2FtZSBuYW1lIHdhcyB1c2VkIG9uIHR3byBkaWZmZXJlbnQgdGVtcGxhdGVzIGluIHRoZQotICAgICAgICAgKiBzYW1lIHN0eWxlc2hlZXQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVEVNUExBVEVfUkVERUZfRVJSLAotICAgICAgICAiSWwgbW9kZWxsbyAnJ3swfScnIFx1MDBFOCBnaVx1MDBFMCBzdGF0byBkZWZpbml0byBpbiBxdWVzdG8gZm9nbGlvIGRpIHN0aWxlLiJ9LAotCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBhCi0gICAgICAgICAqIHRlbXBsYXRlLiAgQSByZWZlcmVuY2UgdG8gdGhlIHRlbXBsYXRlIG5hbWUgd2FzIGVuY291bnRlcmVkLCBidXQgdGhlCi0gICAgICAgICAqIHRlbXBsYXRlIGlzIHVuZGVmaW5lZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5URU1QTEFURV9VTkRFRl9FUlIsCi0gICAgICAgICJJbCBtb2RlbGxvICcnezB9Jycgbm9uIFx1MDBFOCBzdGF0byBkZWZpbml0byBpbiBxdWVzdG8gZm9nbGlvIGRpIHN0aWxlLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYSB2YXJpYWJsZQotICAgICAgICAgKiB0aGF0IHdhcyBkZWZpbmVkIG1vcmUgdGhhbiBvbmNlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlZBUklBQkxFX1JFREVGX0VSUiwKLSAgICAgICAgIkxhIHZhcmlhYmlsZSAnJ3swfScnIFx1MDBFOCBzdGF0YSBkZWZpbml0YSBwaVx1MDBGOSB2b2x0ZSBuZWxsbyBzdGVzc28gYW1iaXRvLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYSB2YXJpYWJsZQotICAgICAgICAgKiBvciBwYXJhbWV0ZXIuICBBIHJlZmVyZW5jZSB0byB0aGUgdmFyaWFibGUgb3IgcGFyYW1ldGVyIHdhcyBmb3VuZCwKLSAgICAgICAgICogYnV0IGl0IHdhcyBuZXZlciBkZWZpbmVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlZBUklBQkxFX1VOREVGX0VSUiwKLSAgICAgICAgIlZhcmlhYmlsZSBvIHBhcmFtZXRybyAnJ3swfScnIG5vbiBkZWZpbml0by4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHdvcmQgImNsYXNzIiBoZXJlIHJlZmVycyB0byBhIEphdmEgY2xhc3MuCi0gICAgICAgICAqIFByb2Nlc3NpbmcgdGhlIHN0eWxlc2hlZXQgcmVxdWlyZWQgYSBjbGFzcyB0byBiZSBsb2FkZWQsIGJ1dCBpdCBjb3VsZAotICAgICAgICAgKiBub3QgYmUgZm91bmQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgdGhlIGNsYXNzLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkNMQVNTX05PVF9GT1VORF9FUlIsCi0gICAgICAgICJJbXBvc3NpYmlsZSB0cm92YXJlIGxhIGNsYXNzZSBcInswfVwiLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgd29yZCAibWV0aG9kIiBoZXJlIHJlZmVycyB0byBhIEphdmEgbWV0aG9kLgotICAgICAgICAgKiBQcm9jZXNzaW5nIHRoZSBzdHlsZXNoZWV0IHJlcXVpcmVkIGEgcmVmZXJlbmNlIHRvIHRoZSBtZXRob2QgbmFtZWQgYnkKLSAgICAgICAgICogdGhlIHN1YnN0aXR1dGlvbiB0ZXh0LCBidXQgaXQgY291bGQgbm90IGJlIGZvdW5kLiAgInB1YmxpYyIgaXMgdGhlCi0gICAgICAgICAqIEphdmEga2V5d29yZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5NRVRIT0RfTk9UX0ZPVU5EX0VSUiwKLSAgICAgICAgIkltcG9zc2liaWxlIHRyb3ZhcmUgaWwgbWV0b2RvIGVzdGVybm8gJyd7MH0nJyAoZGV2ZSBlc3NlcmUgcHViYmxpY28pLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgd29yZCAibWV0aG9kIiBoZXJlIHJlZmVycyB0byBhIEphdmEgbWV0aG9kLgotICAgICAgICAgKiBQcm9jZXNzaW5nIHRoZSBzdHlsZXNoZWV0IHJlcXVpcmVkIGEgcmVmZXJlbmNlIHRvIHRoZSBtZXRob2QgbmFtZWQgYnkKLSAgICAgICAgICogdGhlIHN1YnN0aXR1dGlvbiB0ZXh0LCBidXQgbm8gbWV0aG9kIHdpdGggdGhlIHJlcXVpcmVkIHR5cGVzIG9mCi0gICAgICAgICAqIGFyZ3VtZW50cyBvciByZXR1cm4gdHlwZSBjb3VsZCBiZSBmb3VuZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5BUkdVTUVOVF9DT05WRVJTSU9OX0VSUiwKLSAgICAgICAgIkltcG9zc2liaWxlIGNvbnZlcnRpcmUgbCcnYXJnb21lbnRvIG8gaWwgdGlwbyByZXN0aXR1aXRvIGluIHVuYSBjaGlhbWF0YSBwZXIgaWwgbWV0b2RvICcnezB9JycifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZpbGUgb3IgVVJJIG5hbWVkIGluIHRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICAgKiBpcyBtaXNzaW5nLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkZJTEVfTk9UX0ZPVU5EX0VSUiwKLSAgICAgICAgIkZpbGUgbyBVUkkgJyd7MH0nJyBub24gdHJvdmF0by4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIGRpc3BsYXllZCB3aGVuIHRoZSBVUkkKLSAgICAgICAgICogbWVudGlvbmVkIGluIHRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyBub3Qgd2VsbC1mb3JtZWQgc3ludGFjdGljYWxseS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTlZBTElEX1VSSV9FUlIsCi0gICAgICAgICJVUkkgJyd7MH0nJyBub24gdmFsaWRvLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZmlsZSBvciBVUkkgbmFtZWQgaW4gdGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgICAqIGV4aXN0cyBidXQgY291bGQgbm90IGJlIG9wZW5lZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5GSUxFX0FDQ0VTU19FUlIsCi0gICAgICAgICJJbXBvc3NpYmlsZSBhcHJpcmUgaWwgZmlsZSBvIGwnJ1VSSSAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6IDx4c2w6c3R5bGVzaGVldD4gYW5kIDx4c2w6dHJhbnNmb3JtPiBhcmUKLSAgICAgICAgICoga2V5d29yZHMgdGhhdCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTUlTU0lOR19ST09UX0VSUiwKLSAgICAgICAgIlx1MDBDOCBwcmV2aXN0byB1biBlbGVtZW50byA8eHNsOnN0eWxlc2hlZXQ+IG8gPHhzbDp0cmFuc2Zvcm0+LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3R5bGVzaGVldCBjb250YWluZWQgYSByZWZlcmVuY2UgdG8gYQotICAgICAgICAgKiBuYW1lc3BhY2UgcHJlZml4IHRoYXQgd2FzIHVuZGVmaW5lZC4gIFRoZSB2YWx1ZSBvZiB0aGUgc3Vic3RpdHV0aW9uCi0gICAgICAgICAqIHRleHQgaXMgdGhlIG5hbWUgb2YgdGhlIHByZWZpeC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5OQU1FU1BBQ0VfVU5ERUZfRVJSLAotICAgICAgICAiUHJlZmlzc28gc3BhemlvIGRpIG5vbWkgJyd7MH0nJyBub24gZGljaGlhcmF0by4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIEphdmEgZnVuY3Rpb24gbmFtZWQgaW4gdGhlIHN0eWxlc2hlZXQgY291bGQKLSAgICAgICAgICogbm90IGJlIGZvdW5kLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkZVTkNUSU9OX1JFU09MVkVfRVJSLAotICAgICAgICAiSW1wb3NzaWJpbGUgcmlzb2x2ZXJlIGxhIGNoaWFtYXRhIHBlciBsYSBmdW56aW9uZSAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYQotICAgICAgICAgKiBmdW5jdGlvbi4gIEEgbGl0ZXJhbCBzdHJpbmcgaGVyZSBtZWFucyBhIGNvbnN0YW50IHN0cmluZyB2YWx1ZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5ORUVEX0xJVEVSQUxfRVJSLAotICAgICAgICAiTCcnYXJnb21lbnRvIHBlciAnJ3swfScnIGRldmUgZXNzZXJlIHVuYSBzdHJpbmdhIGRpIHZhbG9yaS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGluZGljYXRlcyB0aGVyZSB3YXMgYSBzeW50YWN0aWMKLSAgICAgICAgICogZXJyb3IgaW4gdGhlIGZvcm0gb2YgYW4gWFBhdGggZXhwcmVzc2lvbi4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcwotICAgICAgICAgKiB0aGUgZXhwcmVzc2lvbi4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5YUEFUSF9QQVJTRVJfRVJSLAotICAgICAgICAiRXJyb3JlIGR1cmFudGUgbCcnYW5hbGlzaSBkZWxsJydlc3ByZXNzaW9uZSBYUGF0aCAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBbiBlbGVtZW50IGluIHRoZSBzdHlsZXNoZWV0IHJlcXVpcmVzIGEKLSAgICAgICAgICogcGFydGljdWxhciBhdHRyaWJ1dGUgbmFtZWQgYnkgdGhlIHN1YnN0aXR1dGlvbiB0ZXh0LCBidXQgdGhhdAotICAgICAgICAgKiBhdHRyaWJ1dGUgd2FzIG5vdCBzcGVjaWZpZWQgaW4gdGhlIHN0eWxlc2hlZXQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuUkVRVUlSRURfQVRUUl9FUlIsCi0gICAgICAgICJBdHRyaWJ1dG8gb2JibGlnYXRvcmlvICcnezB9JycgbWFuY2FudGUuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCBhIGNoYXJhY3RlciBub3QKLSAgICAgICAgICogcGVybWl0dGVkIGluIGFuIFhQYXRoIGV4cHJlc3Npb24gd2FzIGVuY291bnRlcmVkLiAgVGhlIHN1YnN0aXR1dGlvbgotICAgICAgICAgKiB0ZXh0IGlzIHRoZSBvZmZlbmRpbmcgY2hhcmFjdGVyLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfQ0hBUl9FUlIsCi0gICAgICAgICJDYXJhdHRlcmUgJyd7MH0nJyBub24gdmFsaWRvIG5lbGwnJ2VzcHJlc3Npb25lIFhQYXRoLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gaXMgYSBtYXJrLXVwIGl0ZW0gaW4KLSAgICAgICAgICogYW4gWE1MIGRvY3VtZW50IHRoYXQgcmVxdWVzdCBzb21lIGJlaGF2aW91ciBvZiBhbiBYTUwgcHJvY2Vzc29yLiAgVGhlCi0gICAgICAgICAqIGZvcm0gb2YgdGhlIG5hbWUgb2Ygd2FzIGludmFsaWQgaW4gdGhpcyBjYXNlLCBhbmQgdGhlIHN1YnN0aXR1dGlvbgotICAgICAgICAgKiB0ZXh0IGlzIHRoZSBuYW1lLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfUElfRVJSLAotICAgICAgICAiTm9tZSAnJ3swfScnIG5vbiB2YWxpZG8gcGVyIGwnJ2lzdHJ1emlvbmUgZGkgZWxhYm9yYXppb25lLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgcmVwb3J0ZWQgaWYgdGhlIHN0eWxlc2hlZXQKLSAgICAgICAgICogYmVpbmcgcHJvY2Vzc2VkIGF0dGVtcHRlZCB0byBjb25zdHJ1Y3QgYW4gWE1MIGRvY3VtZW50IHdpdGggYW4KLSAgICAgICAgICogYXR0cmlidXRlIGluIGEgcGxhY2Ugb3RoZXIgdGhhbiBvbiBhbiBlbGVtZW50LiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgICAqIHNwZWNpZmllcyB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlNUUkFZX0FUVFJJQlVURV9FUlIsCi0gICAgICAgICJBdHRyaWJ1dG8gJyd7MH0nJyBhbCBkaSBmdW9yaSBkZWxsJydlbGVtZW50by4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQW4gYXR0cmlidXRlIHRoYXQgd2Fzbid0IHJlY29nbml6ZWQgd2FzCi0gICAgICAgICAqIHNwZWNpZmllZCBvbiBhbiBlbGVtZW50IGluIHRoZSBzdHlsZXNoZWV0LiAgVGhlIGF0dHJpYnV0ZSBpcyBuYW1lZAotICAgICAgICAgKiBieSB0aGUgc3Vic3RpdHV0aW9uCi0gICAgICAgICAqIHRleHQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSUxMRUdBTF9BVFRSSUJVVEVfRVJSLAotICAgICAgICAiQXR0cmlidXRvICcnezB9Jycgbm9uIHZhbGlkby4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgImltcG9ydCIgYW5kICJpbmNsdWRlIiBhcmUga2V5d29yZHMgdGhhdCBzaG91bGQKLSAgICAgICAgICogbm90IGJlIHRyYW5zbGF0ZWQuICBUaGlzIG1lc3NhZ2VzIGluZGljYXRlcyB0aGF0IHRoZSBzdHlsZXNoZWV0Ci0gICAgICAgICAqIG5hbWVkIGluIHRoZSBzdWJzdGl0dXRpb24gdGV4dCBpbXBvcnRlZCBvciBpbmNsdWRlZCBpdHNlbGYgZWl0aGVyCi0gICAgICAgICAqIGRpcmVjdGx5IG9yIGluZGlyZWN0bHkuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuQ0lSQ1VMQVJfSU5DTFVERV9FUlIsCi0gICAgICAgICJJbXBvcnRhemlvbmUvaW5jbHVzaW9uZSBjaXJjb2xhcmUuIElsIGZvZ2xpbyBkaSBzdGlsZSAnJ3swfScnIFx1MDBFOCBnaVx1MDBFMCBzdGF0byBjYXJpY2F0by4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQSByZXN1bHQtdHJlZSBmcmFnbWVudCBpcyBhIHBvcnRpb24gb2YgYQotICAgICAgICAgKiByZXN1bHRpbmcgWE1MIGRvY3VtZW50IHJlcHJlc2VudGVkIGFzIGEgdHJlZS4gICI8eHNsOnNvcnQ+IiBpcyBhCi0gICAgICAgICAqIGtleXdvcmQgYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5SRVNVTFRfVFJFRV9TT1JUX0VSUiwKLSAgICAgICAgIkltcG9zc2liaWxlIG9yZGluYXJlIGkgZnJhbW1lbnRpIGRlbGxhIHN0cnV0dHVyYSBkaSByaXN1bHRhdGkgKGdsaSBlbGVtZW50aSA8eHNsOnNvcnQ+IHZlcnJhbm5vIGlnbm9yYXRpKS4gXHUwMEM4IG5lY2Vzc2FyaW8gb3JkaW5hcmUgaSBub2RpIHF1YW5kbyBzaSBjcmVhIGxhIHN0cnV0dHVyYSBkaSByaXN1bHRhdGkuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEEgbmFtZSBjYW4gYmUgZ2l2ZW4gdG8gYSBwYXJ0aWN1bGFyIHN0eWxlIHRvIGJlCi0gICAgICAgICAqIHVzZWQgdG8gZm9ybWF0IGRlY2ltYWwgdmFsdWVzLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGdpdmVzIHRoZSBuYW1lCi0gICAgICAgICAqIG9mIHN1Y2ggYSBzdHlsZSBmb3Igd2hpY2ggbW9yZSB0aGFuIG9uZSBkZWNsYXJhdGlvbiB3YXMgZW5jb3VudGVyZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuU1lNQk9MU19SRURFRl9FUlIsCi0gICAgICAgICJGb3JtYXR0YXppb25lIGRlY2ltYWxlICcnezB9JycgZ2lcdTAwRTAgZGVmaW5pdGEuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IHZlcnNpb24gbmFtZWQgaW4gdGhlCi0gICAgICAgICAqIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIG5vdCBzdXBwb3J0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuWFNMX1ZFUlNJT05fRVJSLAotICAgICAgICAiTGEgdmVyc2lvbmUgWFNMICcnezB9Jycgbm9uIFx1MDBFOCBzdXBwb3J0YXRhIGRhIFhTTFRDLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZGVmaW5pdGlvbnMgb2Ygb25lIG9yIG1vcmUgdmFyaWFibGVzIG9yCi0gICAgICAgICAqIHBhcmFtZXRlcnMgZGVwZW5kIG9uIG9uZSBhbm90aGVyLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkNJUkNVTEFSX1ZBUklBQkxFX0VSUiwKLSAgICAgICAgIlJpZmVyaW1lbnRvIGRpIHZhcmlhYmlsZS9wYXJhbWV0cm8gY2lyY29sYXJlIGluICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBvcGVyYXRvciBpbiBhbiBleHByZXNpb24gd2l0aCB0d28gb3BlcmFuZHMgd2FzCi0gICAgICAgICAqIG5vdCByZWNvZ25pemVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfQklOQVJZX09QX0VSUiwKLSAgICAgICAgIk9wZXJhdG9yZSBzY29ub3NjaXV0byBwZXIgbCdlc3ByZXNzaW9uZSBiaW5hcmlhLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgcHJvZHVjZWQgaWYgYSByZWZlcmVuY2UgdG8gYQotICAgICAgICAgKiBmdW5jdGlvbiBoYXMgdG9vIG1hbnkgb3IgdG9vIGZldyBhcmd1bWVudHMuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSUxMRUdBTF9BUkdfRVJSLAotICAgICAgICAiVW5vIG8gcGlcdTAwRjkgYXJnb21lbnRpIG5vbiB2YWxpZGkgcGVyIGxhIGNoaWFtYXRhIGRlbGxhIGZ1bnppb25lLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiZG9jdW1lbnQoKSIgaXMgdGhlIG5hbWUgb2YgZnVuY3Rpb24gYW5kIG11c3QKLSAgICAgICAgICogbm90IGJlIHRyYW5zbGF0ZWQuICBBIG5vZGUtc2V0IGlzIGEgc2V0IG9mIHRoZSBub2RlcyBpbiB0aGUgdHJlZQotICAgICAgICAgKiByZXByZXNlbnRhdGlvbiBvZiBhbiBYTUwgZG9jdW1lbnQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuRE9DVU1FTlRfQVJHX0VSUiwKLSAgICAgICAgIklsIHNlY29uZG8gYXJnb21lbnRvIHBlciBsYSBmdW56aW9uZSBkb2N1bWVudCgpIGRldmUgZXNzZXJlIHVuIHNldCBkaSBub2RpLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiPHhzbDp3aGVuPiIgYW5kICI8eHNsOmNob29zZT4iIGFyZSBrZXl3b3JkcwotICAgICAgICAgKiBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhpcyBtZXNzYWdlIGRlc2NyaWJlcyBhIHN5bnRheCBlcnJvcgotICAgICAgICAgKiBpbiB0aGUgc3R5bGVzaGVldC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5NSVNTSU5HX1dIRU5fRVJSLAotICAgICAgICAiXHUwMEM4IHJpY2hpZXN0byBhbG1lbm8gdW4gZWxlbWVudG8gPHhzbDp3aGVuPiBpbiA8eHNsOmNob29zZT4uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICI8eHNsOm90aGVyd2lzZT4iIGFuZCAiPHhzbDpjaG9vc2U+IiBhcmUKLSAgICAgICAgICoga2V5d29yZHMgYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoaXMgbWVzc2FnZSBkZXNjcmliZXMgYQotICAgICAgICAgKiBzeW50YXggZXJyb3IgaW4gdGhlIHN0eWxlc2hlZXQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTVVMVElQTEVfT1RIRVJXSVNFX0VSUiwKLSAgICAgICAgIlx1MDBDOCBjb25zZW50aXRvIHVuIHNvbG8gZWxlbWVudG8gPHhzbDpvdGhlcndpc2U+IGluIDx4c2w6Y2hvb3NlPi4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIjx4c2w6b3RoZXJ3aXNlPiIgYW5kICI8eHNsOmNob29zZT4iIGFyZQotICAgICAgICAgKiBrZXl3b3JkcyBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhpcyBtZXNzYWdlIGRlc2NyaWJlcyBhCi0gICAgICAgICAqIHN5bnRheCBlcnJvciBpbiB0aGUgc3R5bGVzaGVldC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5TVFJBWV9PVEhFUldJU0VfRVJSLAotICAgICAgICAiPHhzbDpvdGhlcndpc2U+IHB1XHUwMEYyIGVzc2VyZSB1dGlsaXp6YXRvIHNvbm8gaW4gPHhzbDpjaG9vc2U+LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiPHhzbDp3aGVuPiIgYW5kICI8eHNsOmNob29zZT4iIGFyZSBrZXl3b3JkcwotICAgICAgICAgKiBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhpcyBtZXNzYWdlIGRlc2NyaWJlcyBhIHN5bnRheCBlcnJvcgotICAgICAgICAgKiBpbiB0aGUgc3R5bGVzaGVldC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5TVFJBWV9XSEVOX0VSUiwKLSAgICAgICAgIjx4c2w6d2hlbj4gcHVcdTAwRjIgZXNzZXJlIHV0aWxpenphdG8gc29ubyBpbiA8eHNsOmNob29zZT4uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICI8eHNsOndoZW4+IiwgIjx4c2w6b3RoZXJ3aXNlPiIgYW5kCi0gICAgICAgICAqICI8eHNsOmNob29zZT4iIGFyZSBrZXl3b3JkcyBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhpcwotICAgICAgICAgKiBtZXNzYWdlIGRlc2NyaWJlcyBhIHN5bnRheCBlcnJvciBpbiB0aGUgc3R5bGVzaGVldC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5XSEVOX0VMRU1FTlRfRVJSLAotICAgICAgICAiU29ubyBjb25zZW50aXRpIHNvbG8gZWxlbWVudGkgPHhzbDp3aGVuPiBlIDx4c2w6b3RoZXJ3aXNlPiBpbiA8eHNsOmNob29zZT4uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICI8eHNsOmF0dHJpYnV0ZS1zZXQ+IiBhbmQgIm5hbWUiIGFyZSBrZXl3b3JkcwotICAgICAgICAgKiB0aGF0IHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5VTk5BTUVEX0FUVFJJQlNFVF9FUlIsCi0gICAgICAgICI8eHNsOmF0dHJpYnV0ZS1zZXQ+IG1hbmNhbnRlIG5lbGwnYXR0cmlidXRvICduYW1lJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQW4gZWxlbWVudCBpbiB0aGUgc3R5bGVzaGVldCBjb250YWluZWQgYW4KLSAgICAgICAgICogZWxlbWVudCBvZiBhIHR5cGUgdGhhdCBpdCB3YXMgbm90IHBlcm1pdHRlZCB0byBjb250YWluLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfQ0hJTERfRVJSLAotICAgICAgICAiRWxlbWVudG8gZmlnbGlvIG5vbiB2YWxpZG8uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IHRyaWVkIHRvIGNyZWF0ZSBhbiBlbGVtZW50IHdpdGgKLSAgICAgICAgICogYSBuYW1lIHRoYXQgd2FzIG5vdCBhIHZhbGlkIFhNTCBuYW1lLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGNvbnRhaW5zCi0gICAgICAgICAqIHRoZSBuYW1lLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfRUxFTV9OQU1FX0VSUiwKLSAgICAgICAgIkltcG9zc2liaWxlIHJpY2hpYW1hcmUgdW4gZWxlbWVudG8gJyd7MH0nJyJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3R5bGVzaGVldCB0cmllZCB0byBjcmVhdGUgYW4gYXR0cmlidXRlCi0gICAgICAgICAqIHdpdGggYSBuYW1lIHRoYXQgd2FzIG5vdCBhIHZhbGlkIFhNTCBuYW1lLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgICAqIGNvbnRhaW5zIHRoZSBuYW1lLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfQVRUUl9OQU1FX0VSUiwKLSAgICAgICAgIkltcG9zc2liaWxlIHJpY2hpYW1hcmUgdW4gYXR0cmlidXRvICcnezB9JycifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGNoaWxkcmVuIG9mIHRoZSBvdXRlcm1vc3QgZWxlbWVudCBvZiBhCi0gICAgICAgICAqIHN0eWxlc2hlZXQgYXJlIHJlZmVycmVkIHRvIGFzIHRvcC1sZXZlbCBlbGVtZW50cy4gIE5vIHRleHQgc2hvdWxkCi0gICAgICAgICAqIG9jY3VyIHdpdGhpbiB0aGF0IG91dGVybW9zdCBlbGVtZW50IHVubGVzcyBpdCBpcyB3aXRoaW4gYSB0b3AtbGV2ZWwKLSAgICAgICAgICogZWxlbWVudC4gIFRoaXMgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGF0IGNvbnN0cmFpbnQgd2FzIHZpb2xhdGVkLgotICAgICAgICAgKiAiPHhzbDpzdHlsZXNoZWV0PiIgaXMgYSBrZXl3b3JkIHRoYXQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfVEVYVF9OT0RFX0VSUiwKLSAgICAgICAgIkkgZGF0aSBkaSB0ZXN0byBub24gcmllbnRyYW5vIG5lbGwnZWxlbWVudG8gPHhzbDpzdHlsZXNoZWV0PiBkaSBsaXZlbGxvIHN1cGVyaW9yZS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgSkFYUCBpcyBhbiBhY3JvbnltIGZvciB0aGUgSmF2YSBBUEkgZm9yIFhNTAotICAgICAgICAgKiBQcm9jZXNzaW5nLiAgVGhpcyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoZSBYTUwgcGFyc2VyIHByb3ZpZGVkIHRvCi0gICAgICAgICAqIFhTTFRDIHRvIHByb2Nlc3MgdGhlIFhNTCBpbnB1dCBkb2N1bWVudCBoYWQgYSBjb25maWd1cmF0aW9uIHByb2JsZW0uCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuU0FYX1BBUlNFUl9DT05GSUdfRVJSLAotICAgICAgICAiUGFyc2VyIEpBWFAgbm9uIGNvbmZpZ3VyYXRvIGNvcnJldHRhbWVudGUifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IG5hbWVzIHRoZSBpbnRlcm5hbCBlcnJvcgotICAgICAgICAgKiBlbmNvdW50ZXJlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTlRFUk5BTF9FUlIsCi0gICAgICAgICJFcnJvcmUgaW50ZXJubyBYU0xUQyBpcnJldmVyc2liaWxlOiAnJ3swfScnIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IGNvbnRhaW5lZCBhbiBlbGVtZW50IHRoYXQgd2FzCi0gICAgICAgICAqIG5vdCByZWNvZ25pemVkIGFzIHBhcnQgb2YgdGhlIFhTTCBzeW50YXguICBUaGUgc3Vic3RpdHV0aW9uIHRleHQKLSAgICAgICAgICogZ2l2ZXMgdGhlIGVsZW1lbnQgbmFtZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5VTlNVUFBPUlRFRF9YU0xfRVJSLAotICAgICAgICAiRWxlbWVudG8gWFNMIFwiezB9XCIgbm9uIHN1cHBvcnRhdG8uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IHJlZmVycmVkIHRvIGFuIGV4dGVuc2lvbiB0byB0aGUKLSAgICAgICAgICogWFNMIHN5bnRheCBhbmQgaW5kaWNhdGVkIHRoYXQgaXQgd2FzIGRlZmluZWQgYnkgWFNMVEMsIGJ1dCBYU1RMQyBkb2VzCi0gICAgICAgICAqIG5vdCByZWNvZ25pemVkIHRoZSBwYXJ0aWN1bGFyIGV4dGVuc2lvbiBuYW1lZC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICAgKiBnaXZlcyB0aGUgZXh0ZW5zaW9uIG5hbWUuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVU5TVVBQT1JURURfRVhUX0VSUiwKLSAgICAgICAgIkVzdGVuc2lvbmUgWFNMVEMgJyd7MH0nJyBub24gcmljb25vc2NpdXRhLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgWE1MIGRvY3VtZW50IGdpdmVuIHRvIFhTTFRDIGFzIGEgc3R5bGVzaGVldAotICAgICAgICAgKiB3YXMgbm90LCBpbiBmYWN0LCBhIHN0eWxlc2hlZXQuICBYU0xUQyBpcyBhYmxlIHRvIGRldGVjdCB0aGF0IGluIHRoaXMKLSAgICAgICAgICogY2FzZSBiZWNhdXNlIHRoZSBvdXRlcm1vc3QgZWxlbWVudCBpbiB0aGUgc3R5bGVzaGVldCBoYXMgdG8gYmUKLSAgICAgICAgICogZGVjbGFyZWQgd2l0aCByZXNwZWN0IHRvIHRoZSBYU0wgbmFtZXNwYWNlIFVSSSwgYnV0IG5vIGRlY2xhcmF0aW9uCi0gICAgICAgICAqIGZvciB0aGF0IG5hbWVzcGFjZSB3YXMgc2Vlbi4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5NSVNTSU5HX1hTTFRfVVJJX0VSUiwKLSAgICAgICAgIklsIGRvY3VtZW50byBkaSBpbnB1dCBub24gXHUwMEU4IHVuIGZvZ2xpbyBkaSBzdGlsZSAoc3BhemlvIGRpIG5vbWkgWFNMIG5vbiBkaWNoaWFyYXRvIG5lbGwnZWxlbWVudG8gcmFkaWNlKS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgWFNMVEMgY291bGQgbm90IGZpbmQgdGhlIHN0eWxlc2hlZXQgZG9jdW1lbnQKLSAgICAgICAgICogd2l0aCB0aGUgbmFtZSBzcGVjaWZpZWQgYnkgdGhlIHN1YnN0aXR1dGlvbiB0ZXh0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk1JU1NJTkdfWFNMVF9UQVJHRVRfRVJSLAotICAgICAgICAiSW1wb3NzaWJpbGUgdHJvdmFyZSBsYSBkZXN0aW5hemlvbmUgJyd7MH0nJyBkZWwgZm9nbGlvIGRpIHN0aWxlLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBhY2Nlc3MgdG8gdGhlIHN0eWxlc2hlZXQgdGFyZ2V0IGlzIGRlbmllZAotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkFDQ0VTU0lOR19YU0xUX1RBUkdFVF9FUlIsCi0gICAgICAgICJJbXBvc3NpYmlsZSBsZWdnZXJlIGxhIGRlc3RpbmF6aW9uZSBkZWwgZm9nbGlvIGRpIHN0aWxlICcnezB9JycuIEFjY2Vzc28gJyd7MX0nJyBub24gY29uc2VudGl0byBhIGNhdXNhIGRlbGxhIGxpbWl0YXppb25lIGRlZmluaXRhIGRhbGxhIHByb3ByaWV0XHUwMEUwIGFjY2Vzc0V4dGVybmFsU3R5bGVzaGVldC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIHJlcHJlc2VudHMgYW4gaW50ZXJuYWwgZXJyb3IgaW4KLSAgICAgICAgICogY29uZGl0aW9uIGluIFhTTFRDLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBjbGFzcyBuYW1lIGluIFhTTFRDCi0gICAgICAgICAqIHRoYXQgaXMgbWlzc2luZyBzb21lIGZ1bmN0aW9uYWxpdHkuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTk9UX0lNUExFTUVOVEVEX0VSUiwKLSAgICAgICAgIk5vbiBpbXBsZW1lbnRhdG86ICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBYTUwgZG9jdW1lbnQgZ2l2ZW4gdG8gWFNMVEMgYXMgYSBzdHlsZXNoZWV0Ci0gICAgICAgICAqIHdhcyBub3QsIGluIGZhY3QsIGEgc3R5bGVzaGVldC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5OT1RfU1RZTEVTSEVFVF9FUlIsCi0gICAgICAgICJJbCBkb2N1bWVudG8gZGkgaW5wdXQgbm9uIGNvbnRpZW5lIHVuIGZvZ2xpbyBkaSBzdGlsZSBYU0wuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBlbGVtZW50IG5hbWVkIGluIHRoZSBzdWJzdGl0dXRpb24gdGV4dCB3YXMKLSAgICAgICAgICogZW5jb3VudGVyZWQgaW4gdGhlIHN0eWxlc2hlZXQgYnV0IGlzIG5vdCByZWNvZ25pemVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkVMRU1FTlRfUEFSU0VfRVJSLAotICAgICAgICAiSW1wb3NzaWJpbGUgYW5hbGl6emFyZSBsJydlbGVtZW50byAnJ3swfScnIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJ1c2UiLCAiPGtleT4iLCAibm9kZSIsICJub2RlLXNldCIsICJzdHJpbmciCi0gICAgICAgICAqIGFuZCAibnVtYmVyIiBhcmUga2V5d29yZHMgaW4gdGhpcyBjb250ZXh0IGFuZCBzaG91bGQgbm90IGJlCi0gICAgICAgICAqIHRyYW5zbGF0ZWQuICBUaGlzIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhlIHZhbHVlIG9mIHRoZSAidXNlIgotICAgICAgICAgKiBhdHRyaWJ1dGUgd2FzIG5vdCBvbmUgb2YgdGhlIHBlcm1pdHRlZCB2YWx1ZXMuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuS0VZX1VTRV9BVFRSX0VSUiwKLSAgICAgICAgIkwnYXR0cmlidXRvIGRpIHVzbyA8a2V5PiBkZXZlIGVzc2VyZSB1biBub2RvLCB1biBzZXQgZGkgbm9kaSwgdW5hIHN0cmluZ2EgbyB1biBudW1lcm8uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIFhNTCBkb2N1bWVudCBjYW4gc3BlY2lmeSB0aGUgdmVyc2lvbiBvZiB0aGUKLSAgICAgICAgICogWE1MIHNwZWNpZmljYXRpb24gdG8gd2hpY2ggaXQgYWRoZXJlcy4gIFRoaXMgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdAotICAgICAgICAgKiB0aGUgdmVyc2lvbiBzcGVjaWZpZWQgZm9yIHRoZSBvdXRwdXQgZG9jdW1lbnQgd2FzIG5vdCB2YWxpZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5PVVRQVVRfVkVSU0lPTl9FUlIsCi0gICAgICAgICJMYSB2ZXJzaW9uZSBkZWwgZG9jdW1lbnRvIFhNTCBkaSBvdXRwdXQgZGV2ZSBlc3NlcmUgMS4wIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBvcGVyYXRvciBpbiBhIGNvbXBhcmlzb24gb3BlcmF0aW9uIHdhcwotICAgICAgICAgKiBub3QgcmVjb2duaXplZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTExFR0FMX1JFTEFUX09QX0VSUiwKLSAgICAgICAgIk9wZXJhdG9yZSBzY29ub3NjaXV0byBwZXIgbCdlc3ByZXNzaW9uZSByZWxhemlvbmFsZSJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBbiBhdHRyaWJ1dGUgc2V0IGRlZmluZXMgYXMgYSBzZXQgb2YgWE1MCi0gICAgICAgICAqIGF0dHJpYnV0ZXMgdGhhdCBjYW4gYmUgYWRkZWQgdG8gYW4gZWxlbWVudCBpbiB0aGUgb3V0cHV0IFhNTCBkb2N1bWVudAotICAgICAgICAgKiBhcyBhIGdyb3VwLiAgVGhpcyBtZXNzYWdlIGlzIHJlcG9ydGVkIGlmIHRoZSBuYW1lIHNwZWNpZmllZCB3YXMgbm90Ci0gICAgICAgICAqIHVzZWQgdG8gZGVjbGFyZSBhbiBhdHRyaWJ1dGUgc2V0LiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lCi0gICAgICAgICAqIHRoYXQgaXMgaW4gZXJyb3IuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuQVRUUklCU0VUX1VOREVGX0VSUiwKLSAgICAgICAgIlRlbnRhdGl2byBkaSB1dGlsaXp6YXJlIHVuIHNldCBkaSBhdHRyaWJ1dGkgJyd7MH0nJyBpbmVzaXN0ZW50ZS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHRlcm0gImF0dHJpYnV0ZSB2YWx1ZSB0ZW1wbGF0ZSIgaXMgYSB0ZXJtCi0gICAgICAgICAqIGRlZmluZWQgYnkgWFNMVCB3aGljaCBkZXNjcmliZXMgdGhlIHZhbHVlIG9mIGFuIGF0dHJpYnV0ZSB0aGF0IGlzCi0gICAgICAgICAqIGRldGVybWluZWQgYnkgYW4gWFBhdGggZXhwcmVzc2lvbi4gIFRoZSBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoZQotICAgICAgICAgKiBleHByZXNzaW9uIHdhcyBzeW50YWN0aWNhbGx5IGluY29ycmVjdDsgdGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgICAqIGNvbnRhaW5zIHRoZSBleHByZXNzaW9uIHRoYXQgd2FzIGluIGVycm9yLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkFUVFJfVkFMX1RFTVBMQVRFX0VSUiwKLSAgICAgICAgIkltcG9zc2liaWxlIGFuYWxpenphcmUgaWwgbW9kZWxsbyBkaSB2YWxvcmUgZGkgYXR0cmlidXRvICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogID8/PwotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlVOS05PV05fU0lHX1RZUEVfRVJSLAotICAgICAgICAiVGlwbyBkaSBkYXRpIHNjb25vc2NpdXRvIG5lbGxhIGZpcm1hIHBlciBsYSBjbGFzc2UgJyd7MH0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHJlZmVycyB0byBkYXRhIHR5cGVzLgotICAgICAgICAgKiBUaGUgbWVzc2FnZSBpcyBkaXNwbGF5ZWQgaWYgYSB2YWx1ZSBpbiBhIHBhcnRpY3VsYXIgY29udGV4dCBuZWVkcyB0bwotICAgICAgICAgKiBiZSBjb252ZXJ0ZWQgdG8gdHlwZSB7MX0sIGJ1dCB0aGF0J3Mgbm90IHBvc3NpYmxlIGZvciBhIHZhbHVlIG9mCi0gICAgICAgICAqIHR5cGUgezB9LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkRBVEFfQ09OVkVSU0lPTl9FUlIsCi0gICAgICAgICJJbXBvc3NpYmlsZSBjb252ZXJ0aXJlIGlsIHRpcG8gZGkgZGF0aSAnJ3swfScnIGluICcnezF9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJUZW1wbGF0ZXMiIGlzIGEgSmF2YSBjbGFzcyBuYW1lIHRoYXQgc2hvdWxkCi0gICAgICAgICAqIG5vdCBiZSB0cmFuc2xhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk5PX1RSQU5TTEVUX0NMQVNTX0VSUiwKLSAgICAgICAgIklsIG1vZGVsbG8gbm9uIGNvbnRpZW5lIHVuYSBkZWZpbml6aW9uZSBkaSBjbGFzc2UgZGkgdHJhbnNsZXQgdmFsaWRhLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiVGVtcGxhdGVzIiBpcyBhIEphdmEgY2xhc3MgbmFtZSB0aGF0IHNob3VsZAotICAgICAgICAgKiBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5OT19NQUlOX1RSQU5TTEVUX0VSUiwKLSAgICAgICAgIklsIG1vZGVsbG8gbm9uIGNvbnRpZW5lIHVuYSBjbGFzc2UgZGVub21pbmF0YSAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYSBjbGFzcy4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5UUkFOU0xFVF9DTEFTU19FUlIsCi0gICAgICAgICJJbXBvc3NpYmlsZSBjYXJpY2FyZSBsYSBjbGFzc2UgZGkgdHJhbnNsZXQgJyd7MH0nJy4ifSwKLQotICAgICAgICB7RXJyb3JNc2cuVFJBTlNMRVRfT0JKRUNUX0VSUiwKLSAgICAgICAgIkxhIGNsYXNzZSBkaSB0cmFuc2xldCBcdTAwRTggc3RhdGEgY2FyaWNhdGEsIG1hIG5vbiBcdTAwRTggcG9zc2liaWxlIGNyZWFyZSBsJ2lzdGFuemEgZGVsIHRyYW5zbGV0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiRXJyb3JMaXN0ZW5lciIgaXMgYSBKYXZhIGludGVyZmFjZSBuYW1lIHRoYXQKLSAgICAgICAgICogc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhlIHVzZXIgdHJpZWQKLSAgICAgICAgICogdG8gc2V0IGFuIEVycm9yTGlzdGVuZXIgb2JqZWN0IG9uIG9iamVjdCBvZiB0aGUgY2xhc3MgbmFtZWQgaW4gdGhlCi0gICAgICAgICAqIHN1YnN0aXR1dGlvbiB0ZXh0IHdpdGggIm51bGwiIEphdmEgdmFsdWUuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuRVJST1JfTElTVEVORVJfTlVMTF9FUlIsCi0gICAgICAgICJUZW50YXRpdm8gZGkgaW1wb3N0YXJlIEVycm9yTGlzdGVuZXIgcGVyICcnezB9Jycgc3UgbnVsbCJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBTdHJlYW1Tb3VyY2UsIFNBWFNvdXJjZSBhbmQgRE9NU291cmNlIGFyZSBKYXZhCi0gICAgICAgICAqIGludGVyZmFjZSBuYW1lcyB0aGF0IHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX1VOS05PV05fU09VUkNFX0VSUiwKLSAgICAgICAgIlhTTFRDIHN1cHBvcnRhIHNvbG8gU3RyZWFtU291cmNlLCBTQVhTb3VyY2UgZSBET01Tb3VyY2UuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJTb3VyY2UiIGlzIGEgSmF2YSBjbGFzcyBuYW1lIHRoYXQgc2hvdWxkIG5vdAotICAgICAgICAgKiBiZSB0cmFuc2xhdGVkLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIEphdmEgbWV0aG9kLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfTk9fU09VUkNFX0VSUiwKLSAgICAgICAgIkwnJ29nZ2V0dG8gZGkgb3JpZ2luZSBwYXNzYXRvIGEgJyd7MH0nJyBub24gaGEgY29udGVudXRpLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCBYU0xUQyBmYWlsZWQgdG8KLSAgICAgICAgICogY29tcGlsZSB0aGUgc3R5bGVzaGVldCBpbnRvIGEgdHJhbnNsZXQgKGNsYXNzIGZpbGUpLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfQ09NUElMRV9FUlIsCi0gICAgICAgICJJbXBvc3NpYmlsZSBjb21waWxhcmUgaWwgZm9nbGlvIGRpIHN0aWxlIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJUcmFuc2Zvcm1lckZhY3RvcnkiIGlzIGEgY2xhc3MgbmFtZS4gIEluIHRoaXMKLSAgICAgICAgICogY29udGV4dCwgYW4gYXR0cmlidXRlIGlzIGEgcHJvcGVydHkgb3Igc2V0dGluZyBvZiB0aGUKLSAgICAgICAgICogVHJhbnNmb3JtZXJGYWN0b3J5IG9iamVjdC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiB0aGUKLSAgICAgICAgICogdW5yZWNvZ25pc2VkIGF0dHJpYnV0ZS4gIFRoZSBtZXRob2QgdXNlZCB0byByZXRyaWV2ZSB0aGUgYXR0cmlidXRlIGlzCi0gICAgICAgICAqICJnZXRBdHRyaWJ1dGUiLCBzbyBpdCdzIG5vdCBjbGVhciB3aGV0aGVyIGl0IHdvdWxkIGJlIGJlc3QgdG8KLSAgICAgICAgICogdHJhbnNsYXRlIHRoZSB0ZXJtICJhdHRyaWJ1dGUiLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfSU5WQUxJRF9BVFRSX0VSUiwKLSAgICAgICAgIlRyYW5zZm9ybWVyRmFjdG9yeSBub24gcmljb25vc2NlIGwnJ2F0dHJpYnV0byAnJ3swfScnLiJ9LAotCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX0lOVkFMSURfQVRUUl9WQUxVRV9FUlIsCi0gICAgICAgICJWYWxvcmUgZXJyYXRvIHNwZWNpZmljYXRvIHBlciBsJydhdHRyaWJ1dG8gJyd7MH0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgInNldFJlc3VsdCgpIiBhbmQgInN0YXJ0RG9jdW1lbnQoKSIgYXJlIEphdmEKLSAgICAgICAgICogbWV0aG9kIG5hbWVzIHRoYXQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfU0VUX1JFU1VMVF9FUlIsCi0gICAgICAgICJzZXRSZXN1bHQoKSBkZXZlIGVzc2VyZSByaWNoaWFtYXRvIHByaW1hIGRpIHN0YXJ0RG9jdW1lbnQoKS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIlRyYW5zZm9ybWVyIiBpcyBhIEphdmEgaW50ZXJmYWNlIG5hbWUgdGhhdAotICAgICAgICAgKiBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBBIFRyYW5zZm9ybWVyIG9iamVjdCBzaG91bGQgY29udGFpbmVkIGEKLSAgICAgICAgICogcmVmZXJlbmNlIHRvIGEgdHJhbnNsZXQgb2JqZWN0IGluIG9yZGVyIHRvIGJlIHVzZWQgZm9yCi0gICAgICAgICAqIHRyYW5zZm9ybWF0aW9uczsgdGhpcyBtZXNzYWdlIGlzIHByb2R1Y2VkIGlmIHRoYXQgcmVxdWlyZW1lbnQgaXMgbm90Ci0gICAgICAgICAqIG1ldC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX05PX1RSQU5TTEVUX0VSUiwKLSAgICAgICAgIklsIHRyYXNmb3JtYXRvcmUgbm9uIGNvbnRpZW5lIGFsY3VuIG9nZ2V0dG8gaW5jYXBzdWxhdG8uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBYTUwgZG9jdW1lbnQgdGhhdCByZXN1bHRzIGZyb20gYQotICAgICAgICAgKiB0cmFuc2Zvcm1hdGlvbiBuZWVkcyB0byBiZSBzZW50IHRvIGFuIG91dHB1dCBoYW5kbGVyIG9iamVjdDsgdGhpcwotICAgICAgICAgKiBtZXNzYWdlIGlzIHByb2R1Y2VkIGlmIHRoYXQgcmVxdWlyZW1lbnQgaXMgbm90IG1ldC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX05PX0hBTkRMRVJfRVJSLAotICAgICAgICAiTmVzc3VuIGhhbmRsZXIgZGkgb3V0cHV0IGRlZmluaXRvIHBlciBpbCByaXN1bHRhdG8gZGVsbGEgdHJhc2Zvcm1hemlvbmUuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJSZXN1bHQiIGlzIGEgSmF2YSBpbnRlcmZhY2UgbmFtZSBpbiB0aGlzCi0gICAgICAgICAqIGNvbnRleHQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgYSBtZXRob2QgbmFtZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX05PX1JFU1VMVF9FUlIsCi0gICAgICAgICJMJydvZ2dldHRvIGRpIHJpc3VsdGF0byBwYXNzYXRvIGEgJyd7MH0nJyBub24gXHUwMEU4IHZhbGlkby4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIlRyYW5zZm9ybWVyIiBpcyBhIEphdmEgaW50ZXJmYWNlIG5hbWUuICBUaGUKLSAgICAgICAgICogdXNlcidzIHByb2dyYW0gYXR0ZW1wdGVkIHRvIGFjY2VzcyBhbiB1bnJlY29nbml6ZWQgcHJvcGVydHkgd2l0aCB0aGUKLSAgICAgICAgICogbmFtZSBzcGVjaWZpZWQgaW4gdGhlIHN1YnN0aXR1dGlvbiB0ZXh0LiAgVGhlIG1ldGhvZCB1c2VkIHRvIHJldHJpZXZlCi0gICAgICAgICAqIHRoZSBwcm9wZXJ0eSBpcyAiZ2V0T3V0cHV0UHJvcGVydHkiLCBzbyBpdCdzIG5vdCBjbGVhciB3aGV0aGVyIGl0Ci0gICAgICAgICAqIHdvdWxkIGJlIGJlc3QgdG8gdHJhbnNsYXRlIHRoZSB0ZXJtICJwcm9wZXJ0eSIuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSkFYUF9VTktOT1dOX1BST1BfRVJSLAotICAgICAgICAiVGVudGF0aXZvIGRpIGFjY2VkZXJlIGEgdW5hIHByb3ByaWV0XHUwMEUwICcnezB9JycgZGVsIHRyYXNmb3JtYXRvcmUgbm9uIHZhbGlkYS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgU0FYMkRPTSBpcyB0aGUgbmFtZSBvZiBhIEphdmEgY2xhc3MgdGhhdCBzaG91bGQKLSAgICAgICAgICogbm90IGJlIHRyYW5zbGF0ZWQuICBUaGlzIGlzIGFuIGFkYXB0ZXIgaW4gdGhlIHNlbnNlIHRoYXQgaXQgdGFrZXMgYQotICAgICAgICAgKiBET00gb2JqZWN0IGFuZCBjb252ZXJ0cyBpdCB0byBzb21ldGhpbmcgdGhhdCB1c2VzIHRoZSBTQVggQVBJLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlNBWDJET01fQURBUFRFUl9FUlIsCi0gICAgICAgICJJbXBvc3NpYmlsZSBjcmVhcmUgbCcnYWRhdHRhdG9yZSBTQVgyRE9NICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJYU0xUQ1NvdXJjZS5idWlsZCgpIiBpcyBhIEphdmEgbWV0aG9kIG5hbWUuCi0gICAgICAgICAqICJzeXN0ZW1JZCIgaXMgYW4gWE1MIHRlcm0gdGhhdCBpcyBzaG9ydCBmb3IgInN5c3RlbSBpZGVudGlmaWNhdGlvbiIuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuWFNMVENfU09VUkNFX0VSUiwKLSAgICAgICAgIlhTTFRDU291cmNlLmJ1aWxkKCkgcmljaGlhbWF0byBzZW56YSBjaGUgc2lhIHN0YXRvIGltcG9zdGF0byBzeXN0ZW1JZC4ifSwKLQotICAgICAgICB7IEVycm9yTXNnLkVSX1JFU1VMVF9OVUxMLAotICAgICAgICAgICAgIklsIHJpc3VsdGF0byBub24gZGV2ZSBlc3NlcmUgbnVsbG8ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoZSB2YWx1ZSBhcmd1bWVudAotICAgICAgICAgKiBvZiBzZXRQYXJhbWV0ZXIgbXVzdCBiZSBhIHZhbGlkIEphdmEgT2JqZWN0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfSU5WQUxJRF9TRVRfUEFSQU1fVkFMVUUsCi0gICAgICAgICJJbCB2YWxvcmUgZGVsIHBhcmFtZXRybyB7MH0gZGV2ZSBlc3NlcmUgdW4gb2dnZXR0byBKYXZhIHZhbGlkbyJ9LAotCi0KLSAgICAgICAge0Vycm9yTXNnLkNPTVBJTEVfU1RESU5fRVJSLAotICAgICAgICAiTCdvcHppb25lIC1pIGRldmUgZXNzZXJlIHV0aWxpenphdGEgY29uIGwnb3B6aW9uZSAtby4ifSwKLQotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgY29udGFpbnMgdXNhZ2UgaW5mb3JtYXRpb24gZm9yIGEKLSAgICAgICAgICogbWVhbnMgb2YgaW52b2tpbmcgWFNMVEMgZnJvbSB0aGUgY29tbWFuZC1saW5lLiAgVGhlIG1lc3NhZ2UgaXMKLSAgICAgICAgICogZm9ybWF0dGVkIGZvciBwcmVzZW50YXRpb24gaW4gRW5nbGlzaC4gIFRoZSBzdHJpbmdzIDxvdXRwdXQ+LAotICAgICAgICAgKiA8ZGlyZWN0b3J5PiwgZXRjLiBpbmRpY2F0ZSB1c2VyLXNwZWNpZmllZCBhcmd1bWVudCB2YWx1ZXMsIGFuZCBjYW4KLSAgICAgICAgICogYmUgdHJhbnNsYXRlZCAtIHRoZSBhcmd1bWVudCA8cGFja2FnZT4gcmVmZXJzIHRvIGEgSmF2YSBwYWNrYWdlLCBzbwotICAgICAgICAgKiBpdCBzaG91bGQgYmUgaGFuZGxlZCBpbiB0aGUgc2FtZSB3YXkgdGhlIHRlcm0gaXMgaGFuZGxlZCBmb3IgSkRLCi0gICAgICAgICAqIGRvY3VtZW50YXRpb24uCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuQ09NUElMRV9VU0FHRV9TVFIsCi0gICAgICAgICJSSUVQSUxPR09cbiAgIGphdmEgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNtZGxpbmUuQ29tcGlsZSBbLW8gPG91dHB1dD5dXG4gICAgICBbLWQgPGRpcmVjdG9yeT5dIFstaiA8ZmlsZSBqYXI+XSBbLXAgPHBhY2thZ2U+XVxuICAgICAgWy1uXSBbLXhdIFstdV0gWy12XSBbLWhdIHsgPGZvZ2xpbyBkaSBzdGlsZT4gfCAtaSB9XG5cbk9QWklPTklcbiAgIC1vIDxvdXRwdXQ+ICAgIGFzc2VnbmEgbCc8b3V0cHV0PiBkZWwgbm9tZSBhbCB0cmFuc2xldFxuICAgICAgICAgICAgICAgICAgZ2VuZXJhdG8uICBQZXIgaW1wb3N0YXppb25lIHByZWRlZmluaXRhLCBpbCBub21lIHRyYW5zbGV0XG4gICAgICAgICAgICAgICAgICBcdTAwRTggZGVyaXZhdG8gZGFsIG5vbWUgPGZvZ2xpbyBkaSBzdGlsZT4uICBRdWVzdGEgb3B6aW9uZVxuICAgICAgICAgICAgICAgICAgdmllbmUgaWdub3JhdGEgc2Ugc2kgY29tcGlsYW5vIHBpXHUwMEY5IGZvZ2xpIGRpIHN0aWxlLlxuICAgLWQgPGRpcmVjdG9yeT4gc3BlY2lmaWNhIHVuYSBkaXJlY3RvcnkgZGkgZGVzdGluYXppb25lIHBlciBpbCB0cmFuc2xldFxuICAgLWogPGZpbGUgamFyPiAgIGNyZWEgdW4gcGFja2FnZSBkaSBjbGFzc2kgZGkgdHJhbnNsZXQgaW5zZXJlbmRvbG8gaW4gdW4gZmlsZSBKQVIgY29uIGlsXG4gICAgICAgICAgICAgICAgICBub21lIHNwZWNpZmljYXRvIGNvbWUgPGphcmZpbGU+XG4gICAtcCA8cGFja2FnZT4gICBzcGVjaWZpY2EgdW4gcHJlZmlzc28gZGkgbm9tZSBwYWNrYWdlIHBlciB0dXR0ZSBsZVxuICAgICAgICAgICAgICAgICAgY2xhc3NpIGRpIHRyYW5zbGV0IGdlbmVyYXRlLlxuICAgLW4gICAgICAgICAgICAgYWJpbGl0YSBsJ2luc2VyaW1lbnRvIGluIGxpbmVhIGRlaSBtb2RlbGxpIChpbiBtZWRpYSwgbCdpbXBvc3RhemlvbmUgcHJlZGVmaW5pdGEgXHUwMEU4XG4gICAgICAgICAgICAgICAgICBsYSBtaWdsaW9yZSkuXG4gICAteCAgICAgICAgICAgICBhdHRpdmEgbCdvdXRwdXQgZGkgYWx0cmkgbWVzc2FnZ2kgZGkgZGVidWdcbiAgIC11ICAgICAgICAgICAgIGludGVycHJldGEgZ2xpIGFyZ29tZW50aSA8c3R5bGVzaGVldD4gY29tZSBVUkxcbiAgIC1pICAgICAgICAgICAgIG9iYmxpZ2EgaWwgY29tcGlsYXRvcmUgYSBsZWdnZXJlIGlsIGZvZ2xpbyBkaSBzdGlsZSBkYSBzdGRpblxuICAgLXYgICAgICAgICAgICAgdmlzdWFsaXp6YSBsYSB2ZXJzaW9uZSBkZWwgY29tcGlsYXRvcmVcbiAgIC1oICAgICAgICAgICAgIHZpc3VhbGl6emEgcXVlc3RhIGlzdHJ1emlvbmUgZGkgdXNvXG4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGNvbnRhaW5zIHVzYWdlIGluZm9ybWF0aW9uIGZvciBhCi0gICAgICAgICAqIG1lYW5zIG9mIGludm9raW5nIFhTTFRDIGZyb20gdGhlIGNvbW1hbmQtbGluZS4gIFRoZSBtZXNzYWdlIGlzCi0gICAgICAgICAqIGZvcm1hdHRlZCBmb3IgcHJlc2VudGF0aW9uIGluIEVuZ2xpc2guICBUaGUgc3RyaW5ncyA8amFyZmlsZT4sCi0gICAgICAgICAqIDxkb2N1bWVudD4sIGV0Yy4gaW5kaWNhdGUgdXNlci1zcGVjaWZpZWQgYXJndW1lbnQgdmFsdWVzLCBhbmQgY2FuCi0gICAgICAgICAqIGJlIHRyYW5zbGF0ZWQgLSB0aGUgYXJndW1lbnQgPGNsYXNzPiByZWZlcnMgdG8gYSBKYXZhIGNsYXNzLCBzbyBpdAotICAgICAgICAgKiBzaG91bGQgYmUgaGFuZGxlZCBpbiB0aGUgc2FtZSB3YXkgdGhlIHRlcm0gaXMgaGFuZGxlZCBmb3IgSkRLCi0gICAgICAgICAqIGRvY3VtZW50YXRpb24uCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVFJBTlNGT1JNX1VTQUdFX1NUUiwKLSAgICAgICAgIlJJUEVJTE9HT1xuICAgamF2YSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY21kbGluZS5UcmFuc2Zvcm0gWy1qIDxmaWxlIGphcj5dXG4gICAgICBbLXhdIFstbiA8aXRlcmF6aW9uaT5dIHstdSA8dXJsX2RvY3VtZW50bz4gfCA8ZG9jdW1lbnRvPn1cbiAgICAgIDxjbGFzc2U+IFs8cGFyYW0xPj08dmFsb3JlMT4gLi4uXVxuXG4gICB1dGlsaXp6YSBsYSA8Y2xhc3NlPiB0cmFuc2xldCBwZXIgdHJhc2Zvcm1hcmUgdW4gZG9jdW1lbnRvIFhNTFxuICAgc3BlY2lmaWNhdG8gY29tZSA8ZG9jdW1lbnRvPi4gTGEgPGNsYXNzZT4gZGkgdHJhbnNsZXQgc2kgdHJvdmEgbmVsXG4gICBDTEFTU1BBVEggZGVsbCd1dGVudGUgbyBuZWwgPGZpbGUgamFyPiBzcGVjaWZpY2F0byBmYWNvbHRhdGl2YW1lbnRlLlxcT1BaSU9OSVxuICAgLWogPGZpbGUgamFyPiAgICBzcGVjaWZpY2EgdW4gZmlsZSBKQVIgZGFsIHF1YWxlIGNhcmljYXJlIGlsIHRyYW5zbGV0XG4gICAteCAgICAgICAgICAgICAgYXR0aXZhIGwnb3V0cHV0IGRpIGFsdHJpIG1lc3NhZ2dpIGRpIGRlYnVnXG4gICAtbiA8aXRlcmF6aW9uaT4gZXNlZ3VlIGxlIDxpdGVyYXppb25pPiBkaSB0cmFzZm9ybWF6aW9uZSBlXG4gICAgICAgICAgICAgICAgICAgdmlzdWFsaXp6YSBsZSBpbmZvcm1hemlvbmkgc3VpIHByb2ZpbGlcbiAgIC11IDx1cmxfZG9jdW1lbnRvPiBzcGVjaWZpY2EgaWwgZG9jdW1lbnRvIGRpIGlucHV0IFhNTCBjb21lIFVSTFxuIn0sCi0KLQotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiPHhzbDpzb3J0PiIsICI8eHNsOmZvci1lYWNoPiIgYW5kCi0gICAgICAgICAqICI8eHNsOmFwcGx5LXRlbXBsYXRlcz4iIGFyZSBrZXl3b3JkcyB0aGF0IHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICAgICAgICogVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgYW4geHNsOnNvcnQgZWxlbWVudCBtdXN0IGJlIGEgY2hpbGQgb2YKLSAgICAgICAgICogb25lIG9mIHRoZSBvdGhlciBraW5kcyBvZiBlbGVtZW50cyBtZW50aW9uZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuU1RSQVlfU09SVF9FUlIsCi0gICAgICAgICI8eHNsOnNvcnQ+IHB1XHUwMEYyIGVzc2VyZSB1dGlsaXp6YXRvIHNvbm8gaW4gPHhzbDpmb3ItZWFjaD4gbyA8eHNsOmFwcGx5LXRlbXBsYXRlcz4uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoZSBlbmNvZGluZwotICAgICAgICAgKiByZXF1ZXN0ZWQgZm9yIHRoZSBvdXRwdXQgZG9jdW1lbnQgd2FzIG9uIHRoYXQgcmVxdWlyZXMgc3VwcG9ydCB0aGF0Ci0gICAgICAgICAqIGlzIG5vdCBhdmFpbGFibGUgZnJvbSB0aGUgSmF2YSBWaXJ0dWFsIE1hY2hpbmUgYmVpbmcgdXNlZCB0byBleGVjdXRlCi0gICAgICAgICAqIHRoZSBwcm9ncmFtLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlVOU1VQUE9SVEVEX0VOQ09ESU5HLAotICAgICAgICAiTGEgY29kaWZpY2EgZGkgb3V0cHV0ICcnezB9Jycgbm9uIFx1MDBFOCBzdXBwb3J0YXRhIGluIHF1ZXN0YSBKVk0uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoZSBYUGF0aCBleHByZXNzaW9uCi0gICAgICAgICAqIG5hbWVkIGluIHRoZSBzdWJzdGl0dXRpb24gdGV4dCB3YXMgbm90IHdlbGwgZm9ybWVkIHN5bnRhY3RpY2FsbHkuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuU1lOVEFYX0VSUiwKLSAgICAgICAgIkVycm9yZSBkaSBzaW50YXNzaSBpbiAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYSBKYXZhCi0gICAgICAgICAqIGNsYXNzLiAgVGhlIHRlcm0gImNvbnN0cnVjdG9yIiBoZXJlIGlzIHRoZSBKYXZhIHRlcm0uICBUaGUgbWVzc2FnZSBpcwotICAgICAgICAgKiBkaXNwbGF5ZWQgaWYgWFNMVEMgY291bGQgbm90IGZpbmQgYSBjb25zdHJ1Y3RvciBmb3IgdGhlIHNwZWNpZmllZAotICAgICAgICAgKiBjbGFzcy4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5DT05TVFJVQ1RPUl9OT1RfRk9VTkQsCi0gICAgICAgICJJbXBvc3NpYmlsZSB0cm92YXJlIGlsIGNvc3RydXR0b3JlIGVzdGVybm8gJyd7MH0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgInN0YXRpYyIgaXMgdGhlIEphdmEga2V5d29yZC4gIFRoZSBzdWJzdGl0dXRpb24KLSAgICAgICAgICogdGV4dCBpcyB0aGUgbmFtZSBvZiBhIGZ1bmN0aW9uLiAgVGhlIGZpcnN0IGFyZ3VtZW50IG9mIHRoYXQgZnVuY3Rpb24KLSAgICAgICAgICogaXMgbm90IG9mIHRoZSByZXF1aXJlZCB0eXBlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk5PX0pBVkFfRlVOQ1RfVEhJU19SRUYsCi0gICAgICAgICJJbCBwcmltbyBhcmdvbWVudG8gcGVyIGxhIGZ1bnppb25lIEphdmEgbm9uIHN0YXRpY2EgJyd7MH0nJyBub24gXHUwMEU4IHVuIHJpZmVyaW1lbnRvIGRpIG9nZ2V0dG8gdmFsaWRvLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBbiBYUGF0aCBleHByZXNzaW9uIHdhcyBub3Qgb2YgdGhlIHR5cGUKLSAgICAgICAgICogcmVxdWlyZWQgaW4gYSBwYXJ0aWN1bGFyIGNvbnRleHQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlCi0gICAgICAgICAqIGV4cHJlc3Npb24gdGhhdCB3YXMgaW4gZXJyb3IuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVFlQRV9DSEVDS19FUlIsCi0gICAgICAgICJFcnJvcmUgZHVyYW50ZSBpbCBjb250cm9sbG8gZGVsIHRpcG8gZGVsbCcnZXNwcmVzc2lvbmUgJyd7MH0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQW4gWFBhdGggZXhwcmVzc2lvbiB3YXMgbm90IG9mIHRoZSB0eXBlCi0gICAgICAgICAqIHJlcXVpcmVkIGluIGEgcGFydGljdWxhciBjb250ZXh0LiAgSG93ZXZlciwgdGhlIGxvY2F0aW9uIG9mIHRoZQotICAgICAgICAgKiBwcm9ibGVtYXRpYyBleHByZXNzaW9uIGlzIHVua25vd24uCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVFlQRV9DSEVDS19VTktfTE9DX0VSUiwKLSAgICAgICAgIkVycm9yZSBkdXJhbnRlIGlsIGNvbnRyb2xsbyBkZWwgdGlwbyBkaSB1bicnZXNwcmVzc2lvbmUgaW4gdW5hIHBvc2l6aW9uZSBzY29ub3NjaXV0YS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIGEgY29tbWFuZC0KLSAgICAgICAgICogbGluZSBvcHRpb24gdGhhdCB3YXMgbm90IHJlY29nbml6ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSUxMRUdBTF9DTURMSU5FX09QVElPTl9FUlIsCi0gICAgICAgICJMJydvcHppb25lIGRpIHJpZ2EgZGkgY29tYW5kbyAnJ3swfScnIG5vbiBcdTAwRTggdmFsaWRhLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYSBjb21tYW5kLQotICAgICAgICAgKiBsaW5lIG9wdGlvbi4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5DTURMSU5FX09QVF9NSVNTSU5HX0FSR19FUlIsCi0gICAgICAgICJOZWxsJydvcHppb25lIGRpIHJpZ2EgZGkgY29tYW5kbyAnJ3swfScnIG1hbmNhIHVuIGFyZ29tZW50byBvYmJsaWdhdG9yaW8uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyB1c2VkIHRvIGluZGljYXRlIHRoZSBzZXZlcml0eQotICAgICAgICAgKiBvZiBhbm90aGVyIG1lc3NhZ2UuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgY29udGFpbnMgdHdvIGVycm9yCi0gICAgICAgICAqIG1lc3NhZ2VzLiAgVGhlIHNwYWNpbmcgYmVmb3JlIHRoZSBzZWNvbmQgc3Vic3RpdHV0aW9uIHRleHQgaW5kZW50cwotICAgICAgICAgKiBpdCB0aGUgc2FtZSBhbW91bnQgYXMgdGhlIGZpcnN0IGluIEVuZ2xpc2guCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuV0FSTklOR19QTFVTX1dSQVBQRURfTVNHLAotICAgICAgICAiV0FSTklORzogICcnezB9JydcbiAgICAgICA6ezF9In0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyB1c2VkIHRvIGluZGljYXRlIHRoZSBzZXZlcml0eQotICAgICAgICAgKiBvZiBhbm90aGVyIG1lc3NhZ2UuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgYW4gZXJyb3IgbWVzc2FnZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5XQVJOSU5HX01TRywKLSAgICAgICAgIldBUk5JTkc6ICAnJ3swfScnIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyB1c2VkIHRvIGluZGljYXRlIHRoZSBzZXZlcml0eQotICAgICAgICAgKiBvZiBhbm90aGVyIG1lc3NhZ2UuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgY29udGFpbnMgdHdvIGVycm9yCi0gICAgICAgICAqIG1lc3NhZ2VzLiAgVGhlIHNwYWNpbmcgYmVmb3JlIHRoZSBzZWNvbmQgc3Vic3RpdHV0aW9uIHRleHQgaW5kZW50cwotICAgICAgICAgKiBpdCB0aGUgc2FtZSBhbW91bnQgYXMgdGhlIGZpcnN0IGluIEVuZ2xpc2guCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuRkFUQUxfRVJSX1BMVVNfV1JBUFBFRF9NU0csCi0gICAgICAgICJGQVRBTCBFUlJPUjogICcnezB9JydcbiAgICAgICAgICAgOnsxfSJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgdXNlZCB0byBpbmRpY2F0ZSB0aGUgc2V2ZXJpdHkKLSAgICAgICAgICogb2YgYW5vdGhlciBtZXNzYWdlLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIGFuIGVycm9yIG1lc3NhZ2UuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuRkFUQUxfRVJSX01TRywKLSAgICAgICAgIkZBVEFMIEVSUk9SOiAgJyd7MH0nJyJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgdXNlZCB0byBpbmRpY2F0ZSB0aGUgc2V2ZXJpdHkKLSAgICAgICAgICogb2YgYW5vdGhlciBtZXNzYWdlLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGNvbnRhaW5zIHR3byBlcnJvcgotICAgICAgICAgKiBtZXNzYWdlcy4gIFRoZSBzcGFjaW5nIGJlZm9yZSB0aGUgc2Vjb25kIHN1YnN0aXR1dGlvbiB0ZXh0IGluZGVudHMKLSAgICAgICAgICogaXQgdGhlIHNhbWUgYW1vdW50IGFzIHRoZSBmaXJzdCBpbiBFbmdsaXNoLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkVSUk9SX1BMVVNfV1JBUFBFRF9NU0csCi0gICAgICAgICJFUlJPUjogICcnezB9JydcbiAgICAgOnsxfSJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgdXNlZCB0byBpbmRpY2F0ZSB0aGUgc2V2ZXJpdHkKLSAgICAgICAgICogb2YgYW5vdGhlciBtZXNzYWdlLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIGFuIGVycm9yIG1lc3NhZ2UuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuRVJST1JfTVNHLAotICAgICAgICAiRVJST1I6ICAnJ3swfScnIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBhIGNsYXNzLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlRSQU5TRk9STV9XSVRIX1RSQU5TTEVUX1NUUiwKLSAgICAgICAgIlRyYXNmb3JtYXppb25lIG1lZGlhbnRlIGlsIHRyYW5zbGV0ICcnezB9JycgIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmaXJzdCBzdWJzdGl0dXRpb24gaXMgdGhlIG5hbWUgb2YgYSBjbGFzcywKLSAgICAgICAgICogd2hpbGUgdGhlIHNlY29uZCBzdWJzdGl0dXRpb24gaXMgdGhlIG5hbWUgb2YgYSBqYXIgZmlsZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5UUkFOU0ZPUk1fV0lUSF9KQVJfU1RSLAotICAgICAgICAiVHJhc2Zvcm1hemlvbmUgbWVkaWFudGUgaWwgdHJhbnNsZXQgJyd7MH0nJyBkZWwgZmlsZSBqYXIgJyd7MX0nJyJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiVHJhbnNmb3JtZXJGYWN0b3J5IiBpcyB0aGUgbmFtZSBvZiBhIEphdmEKLSAgICAgICAgICogaW50ZXJmYWNlIGFuZCBtdXN0IG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzCi0gICAgICAgICAqIHRoZSBuYW1lIG9mIHRoZSBjbGFzcyB0aGF0IGNvdWxkIG5vdCBiZSBpbnN0YW50aWF0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuQ09VTERfTk9UX0NSRUFURV9UUkFOU19GQUNULAotICAgICAgICAiSW1wb3NzaWJpbGUgY3JlYXJlIHVuJydpc3RhbnphIGRlbGxhIGNsYXNzZSBUcmFuc2Zvcm1lckZhY3RvcnkgJyd7MH0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIHByb2R1Y2VkIHdoZW4gdGhlIHVzZXIKLSAgICAgICAgICogc3BlY2lmaWVkIGEgbmFtZSBmb3IgdGhlIHRyYW5zbGV0IGNsYXNzIHRoYXQgY29udGFpbnMgY2hhcmFjdGVycwotICAgICAgICAgKiB0aGF0IGFyZSBub3QgcGVybWl0dGVkIGluIGEgSmF2YSBjbGFzcyBuYW1lLiAgVGhlIHN1YnN0aXR1dGlvbgotICAgICAgICAgKiB0ZXh0ICJ7MH0iIHNwZWNpZmllcyB0aGUgbmFtZSB0aGUgdXNlciByZXF1ZXN0ZWQsIHdoaWxlICJ7MX0iCi0gICAgICAgICAqIHNwZWNpZmllcyB0aGUgbmFtZSB0aGUgcHJvY2Vzc29yIHVzZWQgaW5zdGVhZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5UUkFOU0xFVF9OQU1FX0pBVkFfQ09ORkxJQ1QsCi0gICAgICAgICAiSW1wb3NzaWJpbGUgdXRpbGl6emFyZSBpbCBub21lICcnezB9JycgcGVyIGxhIGNsYXNzZSBkaSB0cmFuc2xldCBwb2ljaFx1MDBFOSBjb250aWVuZSBjYXJhdHRlcmkgbm9uIGNvbnNlbnRpdGkgbmVsIG5vbWUgZGVsbGEgY2xhc3NlIEphdmEuIFZlcnJcdTAwRTAgdXRpbGl6emF0byBpbCBub21lICcnezF9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBpcyB1c2VkIGFzIGEgaGVhZGVyLgotICAgICAgICAgKiBBbGwgdGhlIGVycm9yIG1lc3NhZ2VzIGFyZSBjb2xsZWN0ZWQgdG9nZXRoZXIgYW5kIGRpc3BsYXllZCBiZW5lYXRoCi0gICAgICAgICAqIHRoaXMgbWVzc2FnZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5DT01QSUxFUl9FUlJPUl9LRVksCi0gICAgICAgICJFcnJvcmkgZGVsIGNvbXBpbGF0b3JlOiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgaXMgdXNlZCBhcyBhIGhlYWRlci4KLSAgICAgICAgICogQWxsIHRoZSB3YXJuaW5nIG1lc3NhZ2VzIGFyZSBjb2xsZWN0ZWQgdG9nZXRoZXIgYW5kIGRpc3BsYXllZAotICAgICAgICAgKiBiZW5lYXRoIHRoaXMgbWVzc2FnZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5DT01QSUxFUl9XQVJOSU5HX0tFWSwKLSAgICAgICAgIkF2dmVydGVuemUgZGVsIGNvbXBpbGF0b3JlOiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgaXMgdXNlZCBhcyBhIGhlYWRlci4KLSAgICAgICAgICogQWxsIHRoZSBlcnJvciBtZXNzYWdlcyB0aGF0IGFyZSBwcm9kdWNlZCB3aGVuIHRoZSBzdHlsZXNoZWV0IGlzCi0gICAgICAgICAqIGFwcGxpZWQgdG8gYW4gaW5wdXQgZG9jdW1lbnQgYXJlIGNvbGxlY3RlZCB0b2dldGhlciBhbmQgZGlzcGxheWVkCi0gICAgICAgICAqIGJlbmVhdGggdGhpcyBtZXNzYWdlLiAgQSAndHJhbnNsZXQnIGlzIHRoZSBjb21waWxlZCBmb3JtIG9mIGEKLSAgICAgICAgICogc3R5bGVzaGVldCAoc2VlIGFib3ZlKS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5SVU5USU1FX0VSUk9SX0tFWSwKLSAgICAgICAgIkVycm9yaSBkZWwgdHJhbnNsZXQ6In0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIGF0dHJpYnV0ZSB3aG9zZSB2YWx1ZSBpcyBjb25zdHJhaW5lZCB0bwotICAgICAgICAgKiBiZSBhICJRTmFtZSIgb3IgYSBsaXN0IG9mICJRTmFtZXMiIGhhZCBhIHZhbHVlIHRoYXQgd2FzIGluY29ycmVjdC4KLSAgICAgICAgICogJ1FOYW1lJyBpcyBhbiBYTUwgc3ludGFjdGljIHRlcm0gdGhhdCBtdXN0IG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhlCi0gICAgICAgICAqIHN1YnN0aXR1dGlvbiB0ZXh0IGNvbnRhaW5zIHRoZSBhY3R1YWwgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTlZBTElEX1FOQU1FX0VSUiwKLSAgICAgICAgIlVuIGF0dHJpYnV0byBpbCBjdWkgdmFsb3JlIGRldmUgZXNzZXJlIHVuIFFOYW1lIG8gdW5hIGxpc3RhIHNlcGFyYXRhIGRhIHNwYXppIGRpIFFOYW1lIGNvbnRpZW5lIGlsIHZhbG9yZSAnJ3swfScnIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIGF0dHJpYnV0ZSB3aG9zZSB2YWx1ZSBpcyByZXF1aXJlZCB0bwotICAgICAgICAgKiBiZSBhbiAiTkNOYW1lIi4KLSAgICAgICAgICogJ05DTmFtZScgaXMgYW4gWE1MIHN5bnRhY3RpYyB0ZXJtIHRoYXQgbXVzdCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoZQotICAgICAgICAgKiBzdWJzdGl0dXRpb24gdGV4dCBjb250YWlucyB0aGUgYWN0dWFsIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSU5WQUxJRF9OQ05BTUVfRVJSLAotICAgICAgICAiVW4gYXR0cmlidXRvIGlsIGN1aSB2YWxvcmUgZGV2ZSBlc3NlcmUgdW4gTkNOYW1lIGNvbnRpZW5lIGlsIHZhbG9yZSAnJ3swfScnIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIGF0dHJpYnV0ZSB3aXRoIGFuIGluY29ycmVjdCB2YWx1ZSB3YXMKLSAgICAgICAgICogZW5jb3VudGVyZWQuICBUaGUgcGVybWl0dGVkIHZhbHVlIGlzIG9uZSBvZiB0aGUgbGl0ZXJhbCB2YWx1ZXMKLSAgICAgICAgICogInhtbCIsICJodG1sIiBvciAidGV4dCI7IGl0IGlzIGFsc28gcGVybWl0dGVkIHRvIGhhdmUgdGhlIGZvcm0gb2YKLSAgICAgICAgICogYSBRTmFtZSB0aGF0IGlzIG5vdCBhbHNvIGFuIE5DTmFtZS4gIFRoZSB0ZXJtcyAibWV0aG9kIiwKLSAgICAgICAgICogInhzbDpvdXRwdXQiLCAieG1sIiwgImh0bWwiIGFuZCAidGV4dCIgYXJlIGtleXdvcmRzIHRoYXQgbXVzdCBub3QKLSAgICAgICAgICogYmUgdHJhbnNsYXRlZC4gIFRoZSB0ZXJtICJxbmFtZS1idXQtbm90LW5jbmFtZSIgaXMgYW4gWE1MIHN5bnRhY3RpYwotICAgICAgICAgKiB0ZXJtLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGNvbnRhaW5zIHRoZSBhY3R1YWwgdmFsdWUgb2YgdGhlCi0gICAgICAgICAqIGF0dHJpYnV0ZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTlZBTElEX01FVEhPRF9JTl9PVVRQVVQsCi0gICAgICAgICJMJydhdHRyaWJ1dG8gZGkgbWV0b2RvIHBlciB1biBlbGVtZW50byA8eHNsOm91dHB1dD4gaGEgaWwgdmFsb3JlICcnezB9JycsIG1hIGRldmUgZXNzZXJlIHVubyB0cmEgJyd4bWwnJywgJydodG1sJycsICcndGV4dCcnIG8gcW5hbWUtYnV0LW5vdC1uY25hbWUifSwKLQotICAgICAgICB7RXJyb3JNc2cuSkFYUF9HRVRfRkVBVFVSRV9OVUxMX05BTUUsCi0gICAgICAgICJJbCBub21lIGZ1bnppb25lIG5vbiBwdVx1MDBGMiBlc3NlcmUgbnVsbG8gaW4gVHJhbnNmb3JtZXJGYWN0b3J5LmdldEZlYXR1cmUgKG5vbWUgc3RyaW5nYSkuIn0sCi0KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfU0VUX0ZFQVRVUkVfTlVMTF9OQU1FLAotICAgICAgICAiSWwgbm9tZSBmdW56aW9uZSBub24gcHVcdTAwRjIgZXNzZXJlIG51bGxvIGluIFRyYW5zZm9ybWVyRmFjdG9yeS5zZXRGZWF0dXJlIChub21lIHN0cmluZ2EsIHZhbG9yZSBib29sZWFubykuIn0sCi0KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfVU5TVVBQT1JURURfRkVBVFVSRSwKLSAgICAgICAgIkltcG9zc2liaWxlIGltcG9zdGFyZSBsYSBmdW56aW9uZSAnJ3swfScnIGluIHF1ZXN0byBUcmFuc2Zvcm1lckZhY3RvcnkuIn0sCi0KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfU0VDVVJFUFJPQ0VTU0lOR19GRUFUVVJFLAotICAgICAgICAiRkVBVFVSRV9TRUNVUkVfUFJPQ0VTU0lORzogaW1wb3NzaWJpbGUgaW1wb3N0YXJlIGxhIGZ1bnppb25lIHN1IGZhbHNlIHNlIFx1MDBFOCBwcmVzZW50ZSBTZWN1cml0eSBNYW5hZ2VyLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgZGVzY3JpYmVzIGFuIGludGVybmFsIGVycm9yIGluIHRoZQotICAgICAgICAgKiBwcm9jZXNzb3IuICBUaGUgdGVybSAiYnl0ZSBjb2RlIiBpcyBhIEphdmEgdGVjaG5pY2FsIHRlcm0gZm9yIHRoZQotICAgICAgICAgKiBleGVjdXRhYmxlIGNvZGUgaW4gYSBKYXZhIG1ldGhvZCwgYW5kICJ0cnktY2F0Y2gtZmluYWxseSBibG9jayIKLSAgICAgICAgICogcmVmZXJzIHRvIHRoZSBKYXZhIGtleXdvcmRzIHdpdGggdGhvc2UgbmFtZXMuICAiT3V0bGluZWQiIGlzIGEKLSAgICAgICAgICogdGVjaG5pY2FsIHRlcm0gaW50ZXJuYWwgdG8gWFNMVEMgYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5PVVRMSU5FX0VSUl9UUllfQ0FUQ0gsCi0gICAgICAgICAiRXJyb3JlIFhTTFRDIGludGVybm86IGlsIGJ5dGVjb2RlIGdlbmVyYXRvIGNvbnRpZW5lIHVuIGJsb2NjbyB0cnktY2F0Y2gtZmluYWxseSBlIG5vbiBwdVx1MDBGMiBlc3NlcmUgZGkgdGlwbyBvdXRsaW5lZC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGRlc2NyaWJlcyBhbiBpbnRlcm5hbCBlcnJvciBpbiB0aGUKLSAgICAgICAgICogcHJvY2Vzc29yLiAgVGhlIHRlcm1zICJPdXRsaW5lYWJsZUNodW5rU3RhcnQiIGFuZAotICAgICAgICAgKiAiT3V0bGluZWFibGVDaHVua0VuZCIgYXJlIHRoZSBuYW1lcyBvZiBjbGFzc2VzIGludGVybmFsIHRvIFhTTFRDIGFuZAotICAgICAgICAgKiBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCBmb3IgZXZlcnkKLSAgICAgICAgICogInN0YXJ0IiB0aGVyZSBtdXN0IGJlIGEgY29ycmVzcG9uZGluZyAiZW5kIiwgYW5kIHZpY2UgdmVyc2EsIGFuZAotICAgICAgICAgKiB0aGF0IGlmIG9uZSBvZiBhIHBhaXIgb2YgInN0YXJ0IiBhbmQgImVuZCIgYXBwZWFycyBiZXR3ZWVuIGFub3RoZXIKLSAgICAgICAgICogcGFpciBvZiBjb3JyZXNwb25kaW5nICJzdGFydCIgYW5kICJlbmQiLCB0aGVuIHRoZSBvdGhlciBoYWxmIG9mIHRoZQotICAgICAgICAgKiBwYWlyIG11c3QgYWxzbyBiZSBiZXR3ZWVuIHRoYXQgc2FtZSBlbmNsb3NpbmcgcGFpci4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5PVVRMSU5FX0VSUl9VTkJBTEFOQ0VEX01BUktFUlMsCi0gICAgICAgICAiRXJyb3JlIFhTTFRDIGludGVybm86IGdsaSBpbmRpY2F0b3JpIE91dGxpbmVhYmxlQ2h1bmtTdGFydCBlIE91dGxpbmVhYmxlQ2h1bmtFbmQgZGV2b25vIGVzc2VyZSBiaWxhbmNpYXRpIGUgbmlkaWZpY2F0aSBjb3JyZXR0YW1lbnRlLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgZGVzY3JpYmVzIGFuIGludGVybmFsIGVycm9yIGluIHRoZQotICAgICAgICAgKiBwcm9jZXNzb3IuICBUaGUgdGVybSAiYnl0ZSBjb2RlIiBpcyBhIEphdmEgdGVjaG5pY2FsIHRlcm0gZm9yIHRoZQotICAgICAgICAgKiBleGVjdXRhYmxlIGNvZGUgaW4gYSBKYXZhIG1ldGhvZC4gIFRoZSAibWV0aG9kIiB0aGF0IGlzIGJlaW5nCi0gICAgICAgICAqIHJlZmVycmVkIHRvIGlzIGEgSmF2YSBtZXRob2QgaW4gYSB0cmFuc2xldCB0aGF0IFhTTFRDIGlzIGdlbmVyYXRpbmcKLSAgICAgICAgICogaW4gcHJvY2Vzc2luZyBhIHN0eWxlc2hlZXQuICBUaGUgImluc3RydWN0aW9uIiB0aGF0IGlzIGJlaW5nCi0gICAgICAgICAqIHJlZmVycmVkIHRvIGlzIG9uZSBvZiB0aGUgaW5zdHJ1dGlvbnMgaW4gdGhlIEphdmEgYnl0ZSBjb2RlIGluIHRoYXQKLSAgICAgICAgICogbWV0aG9kLiAgIk91dGxpbmVkIiBpcyBhIHRlY2huaWNhbCB0ZXJtIGludGVybmFsIHRvIFhTTFRDIGFuZAotICAgICAgICAgKiBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuT1VUTElORV9FUlJfREVMRVRFRF9UQVJHRVQsCi0gICAgICAgICAiRXJyb3JlIFhTTFRDIGludGVybm86IGEgdW4naXN0cnV6aW9uZSBjaGUgZmFjZXZhIHBhcnRlIGRpIHVuIGJsb2NjbyBkaSBieXRlY29kZSBkaSB0aXBvIG91dGxpbmVkIHZpZW5lIGFuY29yYSBmYXR0byByaWZlcmltZW50byBuZWwgbWV0b2RvIG9yaWdpbmFsZS4iCi0gICAgICAgIH0sCi0KLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGRlc2NyaWJlcyBhbiBpbnRlcm5hbCBlcnJvciBpbiB0aGUKLSAgICAgICAgICogcHJvY2Vzc29yLiAgVGhlICJtZXRob2QiIHRoYXQgaXMgYmVpbmcgcmVmZXJyZWQgdG8gaXMgYSBKYXZhIG1ldGhvZAotICAgICAgICAgKiBpbiBhIHRyYW5zbGV0IHRoYXQgWFNMVEMgaXMgZ2VuZXJhdGluZy4KLSAgICAgICAgICoKLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5PVVRMSU5FX0VSUl9NRVRIT0RfVE9PX0JJRywKLSAgICAgICAgICJFcnJvcmUgWFNMVEMgaW50ZXJubzogdW4gbWV0b2RvIG5lbCB0cmFuc2xldCBzdXBlcmEgbGEgbGltaXRhemlvbmUgSmF2YSBWaXJ0dWFsIE1hY2hpbmUgcmVsYXRpdmEgYWxsYSBsdW5naGV6emEgcGVyIHVuIG1ldG9kbyBkaSA2NCBraWxvYnl0ZS4gQ2lcdTAwRjIgXHUwMEU4IGdlbmVyYWxtZW50ZSBjYXVzYXRvIGRhbGxlIGdyYW5kaSBkaW1lbnNpb25pIGRlaSBtb2RlbGxpIGluIHVuIGZvZ2xpbyBkaSBzdGlsZS4gUHJvdmFyZSBhIHJpc3RydXR0dXJhcmUgaWwgZm9nbGlvIGRpIHN0aWxlIHBlciB1dGlsaXp6YXJlIG1vZGVsbGkgZGkgZGltZW5zaW9uaSBpbmZlcmlvcmkuIgotICAgICAgICB9LAotCi0gICAgICAgICB7RXJyb3JNc2cuREVTRVJJQUxJWkVfVFJBTlNMRVRfRVJSLCAiUXVhbmRvIGxhIHNpY3VyZXp6YSBKYXZhIFx1MDBFOCBhYmlsaXRhdGEsIGlsIHN1cHBvcnRvIHBlciBsYSBkZXNlcmlhbGl6emF6aW9uZSBUZW1wbGF0ZXNJbXBsIFx1MDBFOCBkaXNhYmlsaXRhdG8uIFx1MDBDOCBwb3NzaWJpbGUgaWdub3JhcmUgcXVlc3RhIGNvbmRpemlvbmUgaW1wb3N0YW5kbyBzdSB0cnVlIGxhIHByb3ByaWV0XHUwMEUwIGRpIHNpc3RlbWEgamRrLnhtbC5lbmFibGVUZW1wbGF0ZXNJbXBsRGVzZXJpYWxpemF0aW9uLiJ9Ci0KLSAgICB9OwotCi0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci91dGlsL0Vycm9yTWVzc2FnZXNfamEuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvdXRpbC9FcnJvck1lc3NhZ2VzX2phLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGYyNzM1M2MuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci91dGlsL0Vycm9yTWVzc2FnZXNfamEuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDk3NCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWw7Ci0KLWltcG9ydCBqYXZhLnV0aWwuTGlzdFJlc291cmNlQnVuZGxlOwotCi0vKioKLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICovCi1wdWJsaWMgY2xhc3MgRXJyb3JNZXNzYWdlc19qYSBleHRlbmRzIExpc3RSZXNvdXJjZUJ1bmRsZSB7Ci0KLS8qCi0gKiBYU0xUQyBjb21waWxlLXRpbWUgZXJyb3IgbWVzc2FnZXMuCi0gKgotICogR2VuZXJhbCBub3RlcyB0byB0cmFuc2xhdG9ycyBhbmQgZGVmaW5pdGlvbnM6Ci0gKgotICogICAxKSBYU0xUQyBpcyB0aGUgbmFtZSBvZiB0aGUgcHJvZHVjdC4gIEl0IGlzIGFuIGFjcm9ueW0gZm9yICJYU0xUIENvbXBpbGVyIi4KLSAqICAgICAgWFNMVCBpcyBhbiBhY3JvbnltIGZvciAiWE1MIFN0eWxlc2hlZXQgTGFuZ3VhZ2U6IFRyYW5zZm9ybWF0aW9ucyIuCi0gKgotICogICAyKSBBIHN0eWxlc2hlZXQgaXMgYSBkZXNjcmlwdGlvbiBvZiBob3cgdG8gdHJhbnNmb3JtIGFuIGlucHV0IFhNTCBkb2N1bWVudAotICogICAgICBpbnRvIGEgcmVzdWx0YW50IFhNTCBkb2N1bWVudCAob3IgSFRNTCBkb2N1bWVudCBvciB0ZXh0KS4gIFRoZQotICogICAgICBzdHlsZXNoZWV0IGl0c2VsZiBpcyBkZXNjcmliZWQgaW4gdGhlIGZvcm0gb2YgYW4gWE1MIGRvY3VtZW50LgotICoKLSAqICAgMykgQSB0ZW1wbGF0ZSBpcyBhIGNvbXBvbmVudCBvZiBhIHN0eWxlc2hlZXQgdGhhdCBpcyB1c2VkIHRvIG1hdGNoIGEKLSAqICAgICAgcGFydGljdWxhciBwb3J0aW9uIG9mIGFuIGlucHV0IGRvY3VtZW50IGFuZCBzcGVjaWZpZXMgdGhlIGZvcm0gb2YgdGhlCi0gKiAgICAgIGNvcnJlc3BvbmRpbmcgcG9ydGlvbiBvZiB0aGUgb3V0cHV0IGRvY3VtZW50LgotICoKLSAqICAgNCkgQW4gYXhpcyBpcyBhIHBhcnRpY3VsYXIgImRpbWVuc2lvbiIgaW4gYSB0cmVlIHJlcHJlc2VudGF0aW9uIG9mIGFuIFhNTAotICogICAgICBkb2N1bWVudDsgdGhlIG5vZGVzIGluIHRoZSB0cmVlIGFyZSBkaXZpZGVkIGFsb25nIGRpZmZlcmVudCBheGVzLgotICogICAgICBUcmF2ZXJzaW5nIHRoZSAiY2hpbGQiIGF4aXMsIGZvciBpbnN0YW5jZSwgbWVhbnMgdGhhdCB0aGUgcHJvZ3JhbQotICogICAgICB3b3VsZCB2aXNpdCBlYWNoIGNoaWxkIG9mIGEgcGFydGljdWxhciBub2RlOyB0cmF2ZXJzaW5nIHRoZSAiZGVzY2VuZGFudCIKLSAqICAgICAgYXhpcyBtZWFucyB0aGF0IHRoZSBwcm9ncmFtIHdvdWxkIHZpc2l0IHRoZSBjaGlsZCBub2RlcyBvZiBhIHBhcnRpY3VsYXIKLSAqICAgICAgbm9kZSwgdGhlaXIgY2hpbGRyZW4sIGFuZCBzbyBvbiB1bnRpbCB0aGUgbGVhZiBub2RlcyBvZiB0aGUgdHJlZSBhcmUKLSAqICAgICAgcmVhY2hlZC4KLSAqCi0gKiAgIDUpIEFuIGl0ZXJhdG9yIGlzIGFuIG9iamVjdCB0aGF0IHRyYXZlcnNlcyBub2RlcyBpbiBhIHRyZWUgYWxvbmcgYQotICogICAgICBwYXJ0aWN1bGFyIGF4aXMsIG9uZSBhdCBhIHRpbWUuCi0gKgotICogICA2KSBBbiBlbGVtZW50IGlzIGEgbWFyay11cCB0YWcgaW4gYW4gWE1MIGRvY3VtZW50OyBhbiBhdHRyaWJ1dGUgaXMgYQotICogICAgICBtb2RpZmllciBvbiB0aGUgdGFnLiAgRm9yIGV4YW1wbGUsIGluIDxlbGVtIGF0dHI9J3ZhbCcgYXR0cjI9J3ZhbDInPgotICogICAgICAiZWxlbSIgaXMgYW4gZWxlbWVudCBuYW1lLCAiYXR0ciIgYW5kICJhdHRyMiIgYXJlIGF0dHJpYnV0ZSBuYW1lcyB3aXRoCi0gKiAgICAgIHRoZSB2YWx1ZXMgInZhbCIgYW5kICJ2YWwyIiwgcmVzcGVjdGl2ZWx5LgotICoKLSAqICAgNykgQSBuYW1lc3BhY2UgZGVjbGFyYXRpb24gaXMgYSBzcGVjaWFsIGF0dHJpYnV0ZSB0aGF0IGlzIHVzZWQgdG8gYXNzb2NpYXRlCi0gKiAgICAgIGEgcHJlZml4IHdpdGggYSBVUkkgKHRoZSBuYW1lc3BhY2UpLiAgVGhlIG1lYW5pbmdzIG9mIGVsZW1lbnQgbmFtZXMgYW5kCi0gKiAgICAgIGF0dHJpYnV0ZSBuYW1lcyB0aGF0IHVzZSB0aGF0IHByZWZpeCBhcmUgZGVmaW5lZCB3aXRoIHJlc3BlY3QgdG8gdGhhdAotICogICAgICBuYW1lc3BhY2UuCi0gKgotICogICA4KSBET00gaXMgYW4gYWNyb255bSBmb3IgRG9jdW1lbnQgT2JqZWN0IE1vZGVsLiAgSXQgaXMgYSB0cmVlCi0gKiAgICAgIHJlcHJlc2VudGF0aW9uIG9mIGFuIFhNTCBkb2N1bWVudC4KLSAqCi0gKiAgICAgIFNBWCBpcyBhbiBhY3JvbnltIGZvciB0aGUgU2ltcGxlIEFQSSBmb3IgWE1MIHByb2Nlc3NpbmcuICBJdCBpcyBhbiBBUEkKLSAqICAgICAgdXNlZCBpbmZvcm0gYW4gWE1MIHByb2Nlc3NvciAoaW4gdGhpcyBjYXNlIFhTTFRDKSBvZiB0aGUgc3RydWN0dXJlIGFuZAotICogICAgICBjb250ZW50IG9mIGFuIFhNTCBkb2N1bWVudC4KLSAqCi0gKiAgICAgIElucHV0IHRvIHRoZSBzdHlsZXNoZWV0IHByb2Nlc3NvciBjYW4gY29tZSBmcm9tIGFuIFhNTCBwYXJzZXIgaW4gdGhlCi0gKiAgICAgIGZvcm0gb2YgYSBET00gdHJlZSBvciB0aHJvdWdoIHRoZSBTQVggQVBJLgotICoKLSAqICAgOSkgRFREIGlzIGEgZG9jdW1lbnQgdHlwZSBkZWNsYXJhdGlvbi4gIEl0IGlzIGEgd2F5IG9mIHNwZWNpZnlpbmcgdGhlCi0gKiAgICAgIGdyYW1tYXIgZm9yIGFuIFhNTCBmaWxlLCB0aGUgbmFtZXMgYW5kIHR5cGVzIG9mIGVsZW1lbnRzLCBhdHRyaWJ1dGVzLAotICogICAgICBldGMuCi0gKgotICogIDEwKSBYUGF0aCBpcyBhIHNwZWNpZmljYXRpb24gdGhhdCBkZXNjcmliZXMgYSBub3RhdGlvbiBmb3IgaWRlbnRpZnlpbmcKLSAqICAgICAgbm9kZXMgaW4gYSB0cmVlLXN0cnVjdHVyZWQgcmVwcmVzZW50YXRpb24gb2YgYW4gWE1MIGRvY3VtZW50LiAgQW4KLSAqICAgICAgaW5zdGFuY2Ugb2YgdGhhdCBub3RhdGlvbiBpcyByZWZlcnJlZCB0byBhcyBhbiBYUGF0aCBleHByZXNzaW9uLgotICoKLSAqICAxMSkgVHJhbnNsZXQgaXMgYW4gaW52ZW50ZWQgdGVybSB0aGF0IHJlZmVycyB0byB0aGUgY2xhc3MgZmlsZSB0aGF0IGNvbnRhaW5zCi0gKiAgICAgIHRoZSBjb21waWxlZCBmb3JtIG9mIGEgc3R5bGVzaGVldC4KLSAqLwotCi0gICAgLy8gVGhlc2UgbWVzc2FnZSBzaG91bGQgYmUgcmVhZCBmcm9tIGEgbG9jYWxlLXNwZWNpZmljIHJlc291cmNlIGJ1bmRsZQotICAgIC8qKiBHZXQgdGhlIGxvb2t1cCB0YWJsZSBmb3IgZXJyb3IgbWVzc2FnZXMuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBtZXNzYWdlIGxvb2t1cCB0YWJsZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0W11bXSBnZXRDb250ZW50cygpCi0gICAgewotICAgICAgcmV0dXJuIG5ldyBPYmplY3RbXVtdIHsKLSAgICAgICAge0Vycm9yTXNnLk1VTFRJUExFX1NUWUxFU0hFRVRfRVJSLAotICAgICAgICAiXHU1NDBDXHUzMDU4XHUzMEQ1XHUzMEExXHUzMEE0XHUzMEVCXHUzMDZCXHU4OTA3XHU2NTcwXHUzMDZFXHUzMEI5XHUzMEJGXHUzMEE0XHUzMEVCXHUzMEI3XHUzMEZDXHUzMEM4XHUzMDRDXHU1QjlBXHU3RkE5XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5XHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBhCi0gICAgICAgICAqIHRlbXBsYXRlLiAgVGhlIHNhbWUgbmFtZSB3YXMgdXNlZCBvbiB0d28gZGlmZmVyZW50IHRlbXBsYXRlcyBpbiB0aGUKLSAgICAgICAgICogc2FtZSBzdHlsZXNoZWV0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlRFTVBMQVRFX1JFREVGX0VSUiwKLSAgICAgICAgIlx1MzBDNlx1MzBGM1x1MzBEN1x1MzBFQ1x1MzBGQ1x1MzBDOCcnezB9JydcdTMwNkZcdTMwNTNcdTMwNkVcdTMwQjlcdTMwQkZcdTMwQTRcdTMwRUJcdTMwQjdcdTMwRkNcdTMwQzhcdTUxODVcdTMwNjdcdTMwNTlcdTMwNjdcdTMwNkJcdTVCOUFcdTdGQTlcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTlcdTMwMDIifSwKLQotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYQotICAgICAgICAgKiB0ZW1wbGF0ZS4gIEEgcmVmZXJlbmNlIHRvIHRoZSB0ZW1wbGF0ZSBuYW1lIHdhcyBlbmNvdW50ZXJlZCwgYnV0IHRoZQotICAgICAgICAgKiB0ZW1wbGF0ZSBpcyB1bmRlZmluZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVEVNUExBVEVfVU5ERUZfRVJSLAotICAgICAgICAiXHUzMEM2XHUzMEYzXHUzMEQ3XHUzMEVDXHUzMEZDXHUzMEM4Jyd7MH0nJ1x1MzA2Rlx1MzA1M1x1MzA2RVx1MzBCOVx1MzBCRlx1MzBBNFx1MzBFQlx1MzBCN1x1MzBGQ1x1MzBDOFx1NTE4NVx1MzA2N1x1NUI5QVx1N0ZBOVx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYSB2YXJpYWJsZQotICAgICAgICAgKiB0aGF0IHdhcyBkZWZpbmVkIG1vcmUgdGhhbiBvbmNlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlZBUklBQkxFX1JFREVGX0VSUiwKLSAgICAgICAgIlx1NTkwOVx1NjU3MCcnezB9JydcdTMwNkZcdTU0MENcdTMwNThcdTMwQjlcdTMwQjNcdTMwRkNcdTMwRDdcdTUxODVcdTMwNjdcdTg5MDdcdTY1NzBcdTVCOUFcdTdGQTlcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTlcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIGEgdmFyaWFibGUKLSAgICAgICAgICogb3IgcGFyYW1ldGVyLiAgQSByZWZlcmVuY2UgdG8gdGhlIHZhcmlhYmxlIG9yIHBhcmFtZXRlciB3YXMgZm91bmQsCi0gICAgICAgICAqIGJ1dCBpdCB3YXMgbmV2ZXIgZGVmaW5lZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5WQVJJQUJMRV9VTkRFRl9FUlIsCi0gICAgICAgICJcdTU5MDlcdTY1NzBcdTMwN0VcdTMwNUZcdTMwNkZcdTMwRDFcdTMwRTlcdTMwRTFcdTMwRkNcdTMwQkYnJ3swfScnXHUzMDRDXHU2NzJBXHU1QjlBXHU3RkE5XHUzMDY3XHUzMDU5XHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSB3b3JkICJjbGFzcyIgaGVyZSByZWZlcnMgdG8gYSBKYXZhIGNsYXNzLgotICAgICAgICAgKiBQcm9jZXNzaW5nIHRoZSBzdHlsZXNoZWV0IHJlcXVpcmVkIGEgY2xhc3MgdG8gYmUgbG9hZGVkLCBidXQgaXQgY291bGQKLSAgICAgICAgICogbm90IGJlIGZvdW5kLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIHRoZSBjbGFzcy4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5DTEFTU19OT1RfRk9VTkRfRVJSLAotICAgICAgICAiXHUzMEFGXHUzMEU5XHUzMEI5Jyd7MH0nJ1x1MzA0Q1x1ODk4Qlx1MzA2NFx1MzA0Qlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgd29yZCAibWV0aG9kIiBoZXJlIHJlZmVycyB0byBhIEphdmEgbWV0aG9kLgotICAgICAgICAgKiBQcm9jZXNzaW5nIHRoZSBzdHlsZXNoZWV0IHJlcXVpcmVkIGEgcmVmZXJlbmNlIHRvIHRoZSBtZXRob2QgbmFtZWQgYnkKLSAgICAgICAgICogdGhlIHN1YnN0aXR1dGlvbiB0ZXh0LCBidXQgaXQgY291bGQgbm90IGJlIGZvdW5kLiAgInB1YmxpYyIgaXMgdGhlCi0gICAgICAgICAqIEphdmEga2V5d29yZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5NRVRIT0RfTk9UX0ZPVU5EX0VSUiwKLSAgICAgICAgIlx1NTkxNlx1OTBFOFx1MzBFMVx1MzBCRFx1MzBDM1x1MzBDOScnezB9JydcdTMwNENcdTg5OEJcdTMwNjRcdTMwNEJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTMocHVibGljXHUzMDY3XHUzMDQyXHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5KVx1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgd29yZCAibWV0aG9kIiBoZXJlIHJlZmVycyB0byBhIEphdmEgbWV0aG9kLgotICAgICAgICAgKiBQcm9jZXNzaW5nIHRoZSBzdHlsZXNoZWV0IHJlcXVpcmVkIGEgcmVmZXJlbmNlIHRvIHRoZSBtZXRob2QgbmFtZWQgYnkKLSAgICAgICAgICogdGhlIHN1YnN0aXR1dGlvbiB0ZXh0LCBidXQgbm8gbWV0aG9kIHdpdGggdGhlIHJlcXVpcmVkIHR5cGVzIG9mCi0gICAgICAgICAqIGFyZ3VtZW50cyBvciByZXR1cm4gdHlwZSBjb3VsZCBiZSBmb3VuZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5BUkdVTUVOVF9DT05WRVJTSU9OX0VSUiwKLSAgICAgICAgIlx1MzBFMVx1MzBCRFx1MzBDM1x1MzBDOScnezB9JydcdTMwNkVcdTU0N0NcdTUxRkFcdTMwNTdcdTMwNkVcdTVGMTVcdTY1NzBcdTMwQkZcdTMwQTRcdTMwRDdcdTMwN0VcdTMwNUZcdTMwNkZcdTYyM0JcdTMwOEFcdTU3OEJcdTMwOTJcdTU5MDlcdTYzREJcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTMifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZpbGUgb3IgVVJJIG5hbWVkIGluIHRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICAgKiBpcyBtaXNzaW5nLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkZJTEVfTk9UX0ZPVU5EX0VSUiwKLSAgICAgICAgIlx1MzBENVx1MzBBMVx1MzBBNFx1MzBFQlx1MzA3RVx1MzA1Rlx1MzA2RlVSSSAnJ3swfScnXHUzMDRDXHU4OThCXHUzMDY0XHUzMDRCXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyBkaXNwbGF5ZWQgd2hlbiB0aGUgVVJJCi0gICAgICAgICAqIG1lbnRpb25lZCBpbiB0aGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgbm90IHdlbGwtZm9ybWVkIHN5bnRhY3RpY2FsbHkuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSU5WQUxJRF9VUklfRVJSLAotICAgICAgICAiVVJJICcnezB9JydcdTMwNENcdTcxMjFcdTUyQjlcdTMwNjdcdTMwNTlcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZpbGUgb3IgVVJJIG5hbWVkIGluIHRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICAgKiBleGlzdHMgYnV0IGNvdWxkIG5vdCBiZSBvcGVuZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuRklMRV9BQ0NFU1NfRVJSLAotICAgICAgICAiXHUzMEQ1XHUzMEExXHUzMEE0XHUzMEVCXHUzMDdFXHUzMDVGXHUzMDZGVVJJICcnezB9JydcdTMwOTJcdTk1OEJcdTMwNEZcdTMwNTNcdTMwNjhcdTMwNENcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiA8eHNsOnN0eWxlc2hlZXQ+IGFuZCA8eHNsOnRyYW5zZm9ybT4gYXJlCi0gICAgICAgICAqIGtleXdvcmRzIHRoYXQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk1JU1NJTkdfUk9PVF9FUlIsCi0gICAgICAgICI8eHNsOnN0eWxlc2hlZXQ+XHUzMDdFXHUzMDVGXHUzMDZGPHhzbDp0cmFuc2Zvcm0+XHUzMDZFXHU4OTgxXHU3RDIwXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IGNvbnRhaW5lZCBhIHJlZmVyZW5jZSB0byBhCi0gICAgICAgICAqIG5hbWVzcGFjZSBwcmVmaXggdGhhdCB3YXMgdW5kZWZpbmVkLiAgVGhlIHZhbHVlIG9mIHRoZSBzdWJzdGl0dXRpb24KLSAgICAgICAgICogdGV4dCBpcyB0aGUgbmFtZSBvZiB0aGUgcHJlZml4LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk5BTUVTUEFDRV9VTkRFRl9FUlIsCi0gICAgICAgICJcdTMwQ0RcdTMwRkNcdTMwRTBcdTMwQjlcdTMwREFcdTMwRkNcdTMwQjlcdTMwNkVcdTYzQTVcdTk4MkRcdThGOUUnJ3swfScnXHUzMDZGXHU1QkEzXHU4QTAwXHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBKYXZhIGZ1bmN0aW9uIG5hbWVkIGluIHRoZSBzdHlsZXNoZWV0IGNvdWxkCi0gICAgICAgICAqIG5vdCBiZSBmb3VuZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5GVU5DVElPTl9SRVNPTFZFX0VSUiwKLSAgICAgICAgIlx1OTVBMlx1NjU3MCcnezB9JydcdTMwNkVcdTU0N0NcdTUxRkFcdTMwNTdcdTMwOTJcdTg5RTNcdTZDN0FcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIGEKLSAgICAgICAgICogZnVuY3Rpb24uICBBIGxpdGVyYWwgc3RyaW5nIGhlcmUgbWVhbnMgYSBjb25zdGFudCBzdHJpbmcgdmFsdWUuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTkVFRF9MSVRFUkFMX0VSUiwKLSAgICAgICAgIicnezB9JydcdTMwNzhcdTMwNkVcdTVGMTVcdTY1NzBcdTMwNkZcdTMwRUFcdTMwQzZcdTMwRTlcdTMwRUJcdTY1ODdcdTVCNTdcdTUyMTdcdTMwNjdcdTMwNDJcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGluZGljYXRlcyB0aGVyZSB3YXMgYSBzeW50YWN0aWMKLSAgICAgICAgICogZXJyb3IgaW4gdGhlIGZvcm0gb2YgYW4gWFBhdGggZXhwcmVzc2lvbi4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcwotICAgICAgICAgKiB0aGUgZXhwcmVzc2lvbi4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5YUEFUSF9QQVJTRVJfRVJSLAotICAgICAgICAiWFBhdGhcdTVGMEYnJ3swfScnXHUzMDZFXHU4OUUzXHU2NzkwXHU0RTJEXHUzMDZCXHUzMEE4XHUzMEU5XHUzMEZDXHUzMDRDXHU3NjdBXHU3NTFGXHUzMDU3XHUzMDdFXHUzMDU3XHUzMDVGXHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIGVsZW1lbnQgaW4gdGhlIHN0eWxlc2hlZXQgcmVxdWlyZXMgYQotICAgICAgICAgKiBwYXJ0aWN1bGFyIGF0dHJpYnV0ZSBuYW1lZCBieSB0aGUgc3Vic3RpdHV0aW9uIHRleHQsIGJ1dCB0aGF0Ci0gICAgICAgICAqIGF0dHJpYnV0ZSB3YXMgbm90IHNwZWNpZmllZCBpbiB0aGUgc3R5bGVzaGVldC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5SRVFVSVJFRF9BVFRSX0VSUiwKLSAgICAgICAgIlx1NUZDNVx1OTgwOFx1NUM1RVx1NjAyNycnezB9JydcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IGEgY2hhcmFjdGVyIG5vdAotICAgICAgICAgKiBwZXJtaXR0ZWQgaW4gYW4gWFBhdGggZXhwcmVzc2lvbiB3YXMgZW5jb3VudGVyZWQuICBUaGUgc3Vic3RpdHV0aW9uCi0gICAgICAgICAqIHRleHQgaXMgdGhlIG9mZmVuZGluZyBjaGFyYWN0ZXIuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSUxMRUdBTF9DSEFSX0VSUiwKLSAgICAgICAgIlhQYXRoXHU1RjBGXHUzMDZFXHU2NTg3XHU1QjU3Jyd7MH0nJ1x1MzA2Rlx1NzEyMVx1NTJCOVx1MzA2N1x1MzA1OVx1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gaXMgYSBtYXJrLXVwIGl0ZW0gaW4KLSAgICAgICAgICogYW4gWE1MIGRvY3VtZW50IHRoYXQgcmVxdWVzdCBzb21lIGJlaGF2aW91ciBvZiBhbiBYTUwgcHJvY2Vzc29yLiAgVGhlCi0gICAgICAgICAqIGZvcm0gb2YgdGhlIG5hbWUgb2Ygd2FzIGludmFsaWQgaW4gdGhpcyBjYXNlLCBhbmQgdGhlIHN1YnN0aXR1dGlvbgotICAgICAgICAgKiB0ZXh0IGlzIHRoZSBuYW1lLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfUElfRVJSLAotICAgICAgICAiXHU1MUU2XHU3NDA2XHU1NDdEXHU0RUU0XHUzMDZFXHU1NDBEXHU1MjREJyd7MH0nJ1x1MzA2Rlx1NzEyMVx1NTJCOVx1MzA2N1x1MzA1OVx1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgcmVwb3J0ZWQgaWYgdGhlIHN0eWxlc2hlZXQKLSAgICAgICAgICogYmVpbmcgcHJvY2Vzc2VkIGF0dGVtcHRlZCB0byBjb25zdHJ1Y3QgYW4gWE1MIGRvY3VtZW50IHdpdGggYW4KLSAgICAgICAgICogYXR0cmlidXRlIGluIGEgcGxhY2Ugb3RoZXIgdGhhbiBvbiBhbiBlbGVtZW50LiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgICAqIHNwZWNpZmllcyB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlNUUkFZX0FUVFJJQlVURV9FUlIsCi0gICAgICAgICJcdTVDNUVcdTYwMjcnJ3swfScnXHUzMDRDXHU4OTgxXHU3RDIwXHUzMDZFXHU1OTE2XHU1MDc0XHUzMDZCXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIGF0dHJpYnV0ZSB0aGF0IHdhc24ndCByZWNvZ25pemVkIHdhcwotICAgICAgICAgKiBzcGVjaWZpZWQgb24gYW4gZWxlbWVudCBpbiB0aGUgc3R5bGVzaGVldC4gIFRoZSBhdHRyaWJ1dGUgaXMgbmFtZWQKLSAgICAgICAgICogYnkgdGhlIHN1YnN0aXR1dGlvbgotICAgICAgICAgKiB0ZXh0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfQVRUUklCVVRFX0VSUiwKLSAgICAgICAgIlx1NEUwRFx1NkI2M1x1MzA2QVx1NUM1RVx1NjAyNycnezB9JydcdTMwNjdcdTMwNTlcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgImltcG9ydCIgYW5kICJpbmNsdWRlIiBhcmUga2V5d29yZHMgdGhhdCBzaG91bGQKLSAgICAgICAgICogbm90IGJlIHRyYW5zbGF0ZWQuICBUaGlzIG1lc3NhZ2VzIGluZGljYXRlcyB0aGF0IHRoZSBzdHlsZXNoZWV0Ci0gICAgICAgICAqIG5hbWVkIGluIHRoZSBzdWJzdGl0dXRpb24gdGV4dCBpbXBvcnRlZCBvciBpbmNsdWRlZCBpdHNlbGYgZWl0aGVyCi0gICAgICAgICAqIGRpcmVjdGx5IG9yIGluZGlyZWN0bHkuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuQ0lSQ1VMQVJfSU5DTFVERV9FUlIsCi0gICAgICAgICJcdTMwQTRcdTMwRjNcdTMwRERcdTMwRkNcdTMwQzhcdTMwN0VcdTMwNUZcdTMwNkZcdTMwQTRcdTMwRjNcdTMwQUZcdTMwRUJcdTMwRkNcdTMwQzlcdTMwNENcdTVGQUFcdTc0QjBcdTMwNTdcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTlcdTMwMDJcdTMwQjlcdTMwQkZcdTMwQTRcdTMwRUJcdTMwQjdcdTMwRkNcdTMwQzgnJ3swfScnXHUzMDZGXHUzMDU5XHUzMDY3XHUzMDZCXHUzMEVEXHUzMEZDXHUzMEM5XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5XHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEEgcmVzdWx0LXRyZWUgZnJhZ21lbnQgaXMgYSBwb3J0aW9uIG9mIGEKLSAgICAgICAgICogcmVzdWx0aW5nIFhNTCBkb2N1bWVudCByZXByZXNlbnRlZCBhcyBhIHRyZWUuICAiPHhzbDpzb3J0PiIgaXMgYQotICAgICAgICAgKiBrZXl3b3JkIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuUkVTVUxUX1RSRUVfU09SVF9FUlIsCi0gICAgICAgICJcdTdENTBcdTY3OUNcdTMwQzRcdTMwRUFcdTMwRkNcdTMwRkJcdTMwRDVcdTMwRTlcdTMwQjBcdTMwRTFcdTMwRjNcdTMwQzhcdTMwNkZcdTMwQkRcdTMwRkNcdTMwQzhcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTMoPHhzbDpzb3J0Plx1ODk4MVx1N0QyMFx1MzA2Rlx1NzEyMVx1ODk5Nlx1MzA1NVx1MzA4Q1x1MzA3RVx1MzA1OSlcdTMwMDJcdTdENTBcdTY3OUNcdTMwQzRcdTMwRUFcdTMwRkNcdTMwOTJcdTRGNUNcdTYyMTBcdTMwNTlcdTMwOEJcdTMwNjhcdTMwNERcdTMwNkJcdTMwQ0VcdTMwRkNcdTMwQzlcdTMwOTJcdTMwQkRcdTMwRkNcdTMwQzhcdTMwNTlcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQSBuYW1lIGNhbiBiZSBnaXZlbiB0byBhIHBhcnRpY3VsYXIgc3R5bGUgdG8gYmUKLSAgICAgICAgICogdXNlZCB0byBmb3JtYXQgZGVjaW1hbCB2YWx1ZXMuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgZ2l2ZXMgdGhlIG5hbWUKLSAgICAgICAgICogb2Ygc3VjaCBhIHN0eWxlIGZvciB3aGljaCBtb3JlIHRoYW4gb25lIGRlY2xhcmF0aW9uIHdhcyBlbmNvdW50ZXJlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5TWU1CT0xTX1JFREVGX0VSUiwKLSAgICAgICAgIjEwXHU5MDMyXHU2NTcwXHUzMEQ1XHUzMEE5XHUzMEZDXHUzMERFXHUzMEMzXHUzMEM4Jyd7MH0nJ1x1MzA2Rlx1MzA1OVx1MzA2N1x1MzA2Qlx1NUI5QVx1N0ZBOVx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OVx1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3R5bGVzaGVldCB2ZXJzaW9uIG5hbWVkIGluIHRoZQotICAgICAgICAgKiBzdWJzdGl0dXRpb24gdGV4dCBpcyBub3Qgc3VwcG9ydGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlhTTF9WRVJTSU9OX0VSUiwKLSAgICAgICAgIlhTTFx1MzBEMFx1MzBGQ1x1MzBCOFx1MzBFN1x1MzBGMycnezB9JydcdTMwNkZYU0xUQ1x1MzA2Qlx1MzA4OFx1MzA2M1x1MzA2Nlx1MzBCNVx1MzBERFx1MzBGQ1x1MzBDOFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZGVmaW5pdGlvbnMgb2Ygb25lIG9yIG1vcmUgdmFyaWFibGVzIG9yCi0gICAgICAgICAqIHBhcmFtZXRlcnMgZGVwZW5kIG9uIG9uZSBhbm90aGVyLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkNJUkNVTEFSX1ZBUklBQkxFX0VSUiwKLSAgICAgICAgIicnezB9JydcdTUxODVcdTMwNkVcdTU5MDlcdTY1NzBcdTUzQzJcdTcxNjdcdTMwN0VcdTMwNUZcdTMwNkZcdTMwRDFcdTMwRTlcdTMwRTFcdTMwRkNcdTMwQkZcdTUzQzJcdTcxNjdcdTMwNENcdTVGQUFcdTc0QjBcdTMwNTdcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTlcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIG9wZXJhdG9yIGluIGFuIGV4cHJlc2lvbiB3aXRoIHR3byBvcGVyYW5kcyB3YXMKLSAgICAgICAgICogbm90IHJlY29nbml6ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSUxMRUdBTF9CSU5BUllfT1BfRVJSLAotICAgICAgICAiMlx1OTAzMlx1NjU3MFx1MzA2RVx1NUYwRlx1MzA2Qlx1NUJGRVx1MzA1OVx1MzA4Qlx1NEUwRFx1NjYwRVx1MzA2QVx1NkYxNFx1N0I5N1x1NUI1MFx1MzA2N1x1MzA1OVx1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgcHJvZHVjZWQgaWYgYSByZWZlcmVuY2UgdG8gYQotICAgICAgICAgKiBmdW5jdGlvbiBoYXMgdG9vIG1hbnkgb3IgdG9vIGZldyBhcmd1bWVudHMuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSUxMRUdBTF9BUkdfRVJSLAotICAgICAgICAiXHU5NUEyXHU2NTcwXHU1NDdDXHU1MUZBXHUzMDU3XHUzMDZFXHU1RjE1XHU2NTcwXHUzMDRDXHU0RTBEXHU2QjYzXHUzMDY3XHUzMDU5XHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJkb2N1bWVudCgpIiBpcyB0aGUgbmFtZSBvZiBmdW5jdGlvbiBhbmQgbXVzdAotICAgICAgICAgKiBub3QgYmUgdHJhbnNsYXRlZC4gIEEgbm9kZS1zZXQgaXMgYSBzZXQgb2YgdGhlIG5vZGVzIGluIHRoZSB0cmVlCi0gICAgICAgICAqIHJlcHJlc2VudGF0aW9uIG9mIGFuIFhNTCBkb2N1bWVudC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5ET0NVTUVOVF9BUkdfRVJSLAotICAgICAgICAiZG9jdW1lbnQoKVx1OTVBMlx1NjU3MFx1MzA2RTJcdTc1NkFcdTc2RUVcdTMwNkVcdTVGMTVcdTY1NzBcdTMwNkZcdTMwQ0VcdTMwRkNcdTMwQzlcdTMwQkJcdTMwQzNcdTMwQzhcdTMwNjdcdTMwNDJcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIjx4c2w6d2hlbj4iIGFuZCAiPHhzbDpjaG9vc2U+IiBhcmUga2V5d29yZHMKLSAgICAgICAgICogYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoaXMgbWVzc2FnZSBkZXNjcmliZXMgYSBzeW50YXggZXJyb3IKLSAgICAgICAgICogaW4gdGhlIHN0eWxlc2hlZXQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTUlTU0lOR19XSEVOX0VSUiwKLSAgICAgICAgIjx4c2w6Y2hvb3NlPlx1NTE4NVx1MzA2Qlx1MzA2Rlx1NUMxMVx1MzA2QVx1MzA0Rlx1MzA2OFx1MzA4MjFcdTMwNjRcdTMwNkU8eHNsOndoZW4+XHU4OTgxXHU3RDIwXHUzMDRDXHU1RkM1XHU4OTgxXHUzMDY3XHUzMDU5XHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICI8eHNsOm90aGVyd2lzZT4iIGFuZCAiPHhzbDpjaG9vc2U+IiBhcmUKLSAgICAgICAgICoga2V5d29yZHMgYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoaXMgbWVzc2FnZSBkZXNjcmliZXMgYQotICAgICAgICAgKiBzeW50YXggZXJyb3IgaW4gdGhlIHN0eWxlc2hlZXQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTVVMVElQTEVfT1RIRVJXSVNFX0VSUiwKLSAgICAgICAgIjx4c2w6Y2hvb3NlPlx1NTE4NVx1MzA2N1x1MzA2RjFcdTMwNjRcdTMwNkU8eHNsOm90aGVyd2lzZT5cdTg5ODFcdTdEMjBcdTMwNkVcdTMwN0ZcdTMwNENcdThBMzFcdTUzRUZcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTlcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIjx4c2w6b3RoZXJ3aXNlPiIgYW5kICI8eHNsOmNob29zZT4iIGFyZQotICAgICAgICAgKiBrZXl3b3JkcyBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhpcyBtZXNzYWdlIGRlc2NyaWJlcyBhCi0gICAgICAgICAqIHN5bnRheCBlcnJvciBpbiB0aGUgc3R5bGVzaGVldC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5TVFJBWV9PVEhFUldJU0VfRVJSLAotICAgICAgICAiPHhzbDpvdGhlcndpc2U+XHUzMDZGPHhzbDpjaG9vc2U+XHU1MTg1XHUzMDY3XHUzMDZFXHUzMDdGXHU0RjdGXHU3NTI4XHUzMDY3XHUzMDREXHUzMDdFXHUzMDU5XHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICI8eHNsOndoZW4+IiBhbmQgIjx4c2w6Y2hvb3NlPiIgYXJlIGtleXdvcmRzCi0gICAgICAgICAqIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGlzIG1lc3NhZ2UgZGVzY3JpYmVzIGEgc3ludGF4IGVycm9yCi0gICAgICAgICAqIGluIHRoZSBzdHlsZXNoZWV0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlNUUkFZX1dIRU5fRVJSLAotICAgICAgICAiPHhzbDp3aGVuPlx1MzA2Rjx4c2w6Y2hvb3NlPlx1NTE4NVx1MzA2N1x1MzA2RVx1MzA3Rlx1NEY3Rlx1NzUyOFx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1OVx1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiPHhzbDp3aGVuPiIsICI8eHNsOm90aGVyd2lzZT4iIGFuZAotICAgICAgICAgKiAiPHhzbDpjaG9vc2U+IiBhcmUga2V5d29yZHMgYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoaXMKLSAgICAgICAgICogbWVzc2FnZSBkZXNjcmliZXMgYSBzeW50YXggZXJyb3IgaW4gdGhlIHN0eWxlc2hlZXQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuV0hFTl9FTEVNRU5UX0VSUiwKLSAgICAgICAgIjx4c2w6Y2hvb3NlPlx1NTE4NVx1MzA2N1x1MzA2Rjx4c2w6d2hlbj5cdTMwNjg8eHNsOm90aGVyd2lzZT5cdTMwNkVcdTg5ODFcdTdEMjBcdTMwNkVcdTMwN0ZcdTMwNENcdThBMzFcdTUzRUZcdTMwNTVcdTMwOENcdTMwN0VcdTMwNTlcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIjx4c2w6YXR0cmlidXRlLXNldD4iIGFuZCAibmFtZSIgYXJlIGtleXdvcmRzCi0gICAgICAgICAqIHRoYXQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlVOTkFNRURfQVRUUklCU0VUX0VSUiwKLSAgICAgICAgIjx4c2w6YXR0cmlidXRlLXNldD5cdTMwNkInbmFtZSdcdTVDNUVcdTYwMjdcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQW4gZWxlbWVudCBpbiB0aGUgc3R5bGVzaGVldCBjb250YWluZWQgYW4KLSAgICAgICAgICogZWxlbWVudCBvZiBhIHR5cGUgdGhhdCBpdCB3YXMgbm90IHBlcm1pdHRlZCB0byBjb250YWluLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfQ0hJTERfRVJSLAotICAgICAgICAiXHU1QjUwXHU4OTgxXHU3RDIwXHUzMDRDXHU0RTBEXHU2QjYzXHUzMDY3XHUzMDU5XHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IHRyaWVkIHRvIGNyZWF0ZSBhbiBlbGVtZW50IHdpdGgKLSAgICAgICAgICogYSBuYW1lIHRoYXQgd2FzIG5vdCBhIHZhbGlkIFhNTCBuYW1lLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGNvbnRhaW5zCi0gICAgICAgICAqIHRoZSBuYW1lLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfRUxFTV9OQU1FX0VSUiwKLSAgICAgICAgIlx1ODk4MVx1N0QyMCcnezB9JydcdTMwOTJcdTU0N0NcdTMwNzNcdTUxRkFcdTMwNTlcdTMwNTNcdTMwNjhcdTMwNkZcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTMifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN0eWxlc2hlZXQgdHJpZWQgdG8gY3JlYXRlIGFuIGF0dHJpYnV0ZQotICAgICAgICAgKiB3aXRoIGEgbmFtZSB0aGF0IHdhcyBub3QgYSB2YWxpZCBYTUwgbmFtZS4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICAgKiBjb250YWlucyB0aGUgbmFtZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTExFR0FMX0FUVFJfTkFNRV9FUlIsCi0gICAgICAgICJcdTVDNUVcdTYwMjcnJ3swfScnXHUzMDkyXHU1NDdDXHUzMDczXHU1MUZBXHUzMDU5XHUzMDUzXHUzMDY4XHUzMDZGXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBjaGlsZHJlbiBvZiB0aGUgb3V0ZXJtb3N0IGVsZW1lbnQgb2YgYQotICAgICAgICAgKiBzdHlsZXNoZWV0IGFyZSByZWZlcnJlZCB0byBhcyB0b3AtbGV2ZWwgZWxlbWVudHMuICBObyB0ZXh0IHNob3VsZAotICAgICAgICAgKiBvY2N1ciB3aXRoaW4gdGhhdCBvdXRlcm1vc3QgZWxlbWVudCB1bmxlc3MgaXQgaXMgd2l0aGluIGEgdG9wLWxldmVsCi0gICAgICAgICAqIGVsZW1lbnQuICBUaGlzIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhhdCBjb25zdHJhaW50IHdhcyB2aW9sYXRlZC4KLSAgICAgICAgICogIjx4c2w6c3R5bGVzaGVldD4iIGlzIGEga2V5d29yZCB0aGF0IHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTExFR0FMX1RFWFRfTk9ERV9FUlIsCi0gICAgICAgICJcdTMwQzZcdTMwQURcdTMwQjlcdTMwQzhcdTMwRkJcdTMwQzdcdTMwRkNcdTMwQkZcdTMwNkZcdTMwQzhcdTMwQzNcdTMwRDdcdTMwRUNcdTMwRDlcdTMwRUJcdTMwNkU8eHNsOnN0eWxlc2hlZXQ+XHU4OTgxXHU3RDIwXHUzMDZFXHU1OTE2XHU1MDc0XHUzMDZCXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEpBWFAgaXMgYW4gYWNyb255bSBmb3IgdGhlIEphdmEgQVBJIGZvciBYTUwKLSAgICAgICAgICogUHJvY2Vzc2luZy4gIFRoaXMgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUgWE1MIHBhcnNlciBwcm92aWRlZCB0bwotICAgICAgICAgKiBYU0xUQyB0byBwcm9jZXNzIHRoZSBYTUwgaW5wdXQgZG9jdW1lbnQgaGFkIGEgY29uZmlndXJhdGlvbiBwcm9ibGVtLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlNBWF9QQVJTRVJfQ09ORklHX0VSUiwKLSAgICAgICAgIkpBWFBcdTMwRDFcdTMwRkNcdTMwQjVcdTMwRkNcdTMwNENcdTZCNjNcdTMwNTdcdTMwNEZcdTY5Q0JcdTYyMTBcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTMifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IG5hbWVzIHRoZSBpbnRlcm5hbCBlcnJvcgotICAgICAgICAgKiBlbmNvdW50ZXJlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTlRFUk5BTF9FUlIsCi0gICAgICAgICJcdTMwRUFcdTMwQUJcdTMwRDBcdTMwRUFcdTRFMERcdTgwRkRcdTMwNkFYU0xUQ1x1NTE4NVx1OTBFOFx1MzBBOFx1MzBFOVx1MzBGQzogJyd7MH0nJyJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3R5bGVzaGVldCBjb250YWluZWQgYW4gZWxlbWVudCB0aGF0IHdhcwotICAgICAgICAgKiBub3QgcmVjb2duaXplZCBhcyBwYXJ0IG9mIHRoZSBYU0wgc3ludGF4LiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgICAqIGdpdmVzIHRoZSBlbGVtZW50IG5hbWUuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVU5TVVBQT1JURURfWFNMX0VSUiwKLSAgICAgICAgIlhTTFx1ODk4MVx1N0QyMCcnezB9JydcdTMwNkZcdTMwQjVcdTMwRERcdTMwRkNcdTMwQzhcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN0eWxlc2hlZXQgcmVmZXJyZWQgdG8gYW4gZXh0ZW5zaW9uIHRvIHRoZQotICAgICAgICAgKiBYU0wgc3ludGF4IGFuZCBpbmRpY2F0ZWQgdGhhdCBpdCB3YXMgZGVmaW5lZCBieSBYU0xUQywgYnV0IFhTVExDIGRvZXMKLSAgICAgICAgICogbm90IHJlY29nbml6ZWQgdGhlIHBhcnRpY3VsYXIgZXh0ZW5zaW9uIG5hbWVkLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgICAqIGdpdmVzIHRoZSBleHRlbnNpb24gbmFtZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5VTlNVUFBPUlRFRF9FWFRfRVJSLAotICAgICAgICAiWFNMVENcdTYyRTFcdTVGMzUnJ3swfScnXHUzMDZGXHU4QThEXHU4QjU4XHUzMDU1XHUzMDhDXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBYTUwgZG9jdW1lbnQgZ2l2ZW4gdG8gWFNMVEMgYXMgYSBzdHlsZXNoZWV0Ci0gICAgICAgICAqIHdhcyBub3QsIGluIGZhY3QsIGEgc3R5bGVzaGVldC4gIFhTTFRDIGlzIGFibGUgdG8gZGV0ZWN0IHRoYXQgaW4gdGhpcwotICAgICAgICAgKiBjYXNlIGJlY2F1c2UgdGhlIG91dGVybW9zdCBlbGVtZW50IGluIHRoZSBzdHlsZXNoZWV0IGhhcyB0byBiZQotICAgICAgICAgKiBkZWNsYXJlZCB3aXRoIHJlc3BlY3QgdG8gdGhlIFhTTCBuYW1lc3BhY2UgVVJJLCBidXQgbm8gZGVjbGFyYXRpb24KLSAgICAgICAgICogZm9yIHRoYXQgbmFtZXNwYWNlIHdhcyBzZWVuLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk1JU1NJTkdfWFNMVF9VUklfRVJSLAotICAgICAgICAiXHU1MTY1XHU1MjlCXHUzMEM5XHUzMEFEXHUzMEU1XHUzMEUxXHUzMEYzXHUzMEM4XHUzMDZGXHUzMEI5XHUzMEJGXHUzMEE0XHUzMEVCXHUzMEI3XHUzMEZDXHUzMEM4XHUzMDY3XHUzMDZGXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzKFhTTFx1MzA2RVx1MzBDRFx1MzBGQ1x1MzBFMFx1MzBCOVx1MzBEQVx1MzBGQ1x1MzBCOVx1MzA2Rlx1MzBFQlx1MzBGQ1x1MzBDOFx1ODk4MVx1N0QyMFx1NTE4NVx1MzA2N1x1NUJBM1x1OEEwMFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5MylcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgWFNMVEMgY291bGQgbm90IGZpbmQgdGhlIHN0eWxlc2hlZXQgZG9jdW1lbnQKLSAgICAgICAgICogd2l0aCB0aGUgbmFtZSBzcGVjaWZpZWQgYnkgdGhlIHN1YnN0aXR1dGlvbiB0ZXh0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk1JU1NJTkdfWFNMVF9UQVJHRVRfRVJSLAotICAgICAgICAiXHUzMEI5XHUzMEJGXHUzMEE0XHUzMEVCXHUzMEI3XHUzMEZDXHUzMEM4XHUzMEZCXHUzMEJGXHUzMEZDXHUzMEIyXHUzMEMzXHUzMEM4Jyd7MH0nJ1x1MzA0Q1x1ODk4Qlx1MzA2NFx1MzA0Qlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5M1x1MzA2N1x1MzA1N1x1MzA1Rlx1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBhY2Nlc3MgdG8gdGhlIHN0eWxlc2hlZXQgdGFyZ2V0IGlzIGRlbmllZAotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkFDQ0VTU0lOR19YU0xUX1RBUkdFVF9FUlIsCi0gICAgICAgICJhY2Nlc3NFeHRlcm5hbFN0eWxlc2hlZXRcdTMwRDdcdTMwRURcdTMwRDFcdTMwQzZcdTMwQTNcdTMwNjdcdThBMkRcdTVCOUFcdTMwNTVcdTMwOENcdTMwNUZcdTUyMzZcdTk2NTBcdTMwNkJcdTMwODhcdTMwOEEnJ3sxfScnXHUzMEEyXHUzMEFGXHUzMEJCXHUzMEI5XHUzMDRDXHU4QTMxXHU1M0VGXHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDZBXHUzMDQ0XHUzMDVGXHUzMDgxXHUzMDAxXHUzMEI5XHUzMEJGXHUzMEE0XHUzMEVCXHUzMEI3XHUzMEZDXHUzMEM4XHUzMEZCXHUzMEJGXHUzMEZDXHUzMEIyXHUzMEMzXHUzMEM4Jyd7MH0nJ1x1MzA5Mlx1OEFBRFx1MzA3Rlx1NTNENlx1MzA4Q1x1MzA3RVx1MzA1Qlx1MzA5M1x1MzA2N1x1MzA1N1x1MzA1Rlx1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgcmVwcmVzZW50cyBhbiBpbnRlcm5hbCBlcnJvciBpbgotICAgICAgICAgKiBjb25kaXRpb24gaW4gWFNMVEMuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIGNsYXNzIG5hbWUgaW4gWFNMVEMKLSAgICAgICAgICogdGhhdCBpcyBtaXNzaW5nIHNvbWUgZnVuY3Rpb25hbGl0eS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5OT1RfSU1QTEVNRU5URURfRVJSLAotICAgICAgICAiJyd7MH0nJ1x1MzA0Q1x1NUI5Rlx1ODhDNVx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgWE1MIGRvY3VtZW50IGdpdmVuIHRvIFhTTFRDIGFzIGEgc3R5bGVzaGVldAotICAgICAgICAgKiB3YXMgbm90LCBpbiBmYWN0LCBhIHN0eWxlc2hlZXQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTk9UX1NUWUxFU0hFRVRfRVJSLAotICAgICAgICAiXHU1MTY1XHU1MjlCXHUzMEM5XHUzMEFEXHUzMEU1XHUzMEUxXHUzMEYzXHUzMEM4XHUzMDZCWFNMXHUzMEI5XHUzMEJGXHUzMEE0XHUzMEVCXHUzMEI3XHUzMEZDXHUzMEM4XHUzMDRDXHU1NDJCXHUzMDdFXHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBlbGVtZW50IG5hbWVkIGluIHRoZSBzdWJzdGl0dXRpb24gdGV4dCB3YXMKLSAgICAgICAgICogZW5jb3VudGVyZWQgaW4gdGhlIHN0eWxlc2hlZXQgYnV0IGlzIG5vdCByZWNvZ25pemVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkVMRU1FTlRfUEFSU0VfRVJSLAotICAgICAgICAiXHU4OTgxXHU3RDIwJyd7MH0nJ1x1MzA5Mlx1ODlFM1x1Njc5MFx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzA2N1x1MzA1N1x1MzA1RiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAidXNlIiwgIjxrZXk+IiwgIm5vZGUiLCAibm9kZS1zZXQiLCAic3RyaW5nIgotICAgICAgICAgKiBhbmQgIm51bWJlciIgYXJlIGtleXdvcmRzIGluIHRoaXMgY29udGV4dCBhbmQgc2hvdWxkIG5vdCBiZQotICAgICAgICAgKiB0cmFuc2xhdGVkLiAgVGhpcyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoZSB2YWx1ZSBvZiB0aGUgInVzZSIKLSAgICAgICAgICogYXR0cmlidXRlIHdhcyBub3Qgb25lIG9mIHRoZSBwZXJtaXR0ZWQgdmFsdWVzLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLktFWV9VU0VfQVRUUl9FUlIsCi0gICAgICAgICI8a2V5Plx1MzA2RXVzZVx1NUM1RVx1NjAyN1x1MzA2Rlx1MzAwMVx1MzBDRVx1MzBGQ1x1MzBDOVx1MzAwMVx1MzBDRVx1MzBGQ1x1MzBDOVx1MzBCQlx1MzBDM1x1MzBDOFx1MzAwMVx1NjU4N1x1NUI1N1x1NTIxN1x1MzA3RVx1MzA1Rlx1MzA2Rlx1NjU3MFx1NTAyNFx1MzA2N1x1MzA0Mlx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBbiBYTUwgZG9jdW1lbnQgY2FuIHNwZWNpZnkgdGhlIHZlcnNpb24gb2YgdGhlCi0gICAgICAgICAqIFhNTCBzcGVjaWZpY2F0aW9uIHRvIHdoaWNoIGl0IGFkaGVyZXMuICBUaGlzIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQKLSAgICAgICAgICogdGhlIHZlcnNpb24gc3BlY2lmaWVkIGZvciB0aGUgb3V0cHV0IGRvY3VtZW50IHdhcyBub3QgdmFsaWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuT1VUUFVUX1ZFUlNJT05fRVJSLAotICAgICAgICAiXHU1MUZBXHU1MjlCWE1MXHUzMEM5XHUzMEFEXHUzMEU1XHUzMEUxXHUzMEYzXHUzMEM4XHUzMDZFXHUzMEQwXHUzMEZDXHUzMEI4XHUzMEU3XHUzMEYzXHUzMDZGMS4wXHUzMDY3XHUzMDQyXHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5In0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBvcGVyYXRvciBpbiBhIGNvbXBhcmlzb24gb3BlcmF0aW9uIHdhcwotICAgICAgICAgKiBub3QgcmVjb2duaXplZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTExFR0FMX1JFTEFUX09QX0VSUiwKLSAgICAgICAgIlx1OTVBMlx1NEZDMlx1NUYwRlx1MzA2RVx1NEUwRFx1NjYwRVx1MzA2QVx1NkYxNFx1N0I5N1x1NUI1MFx1MzA2N1x1MzA1OSJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBbiBhdHRyaWJ1dGUgc2V0IGRlZmluZXMgYXMgYSBzZXQgb2YgWE1MCi0gICAgICAgICAqIGF0dHJpYnV0ZXMgdGhhdCBjYW4gYmUgYWRkZWQgdG8gYW4gZWxlbWVudCBpbiB0aGUgb3V0cHV0IFhNTCBkb2N1bWVudAotICAgICAgICAgKiBhcyBhIGdyb3VwLiAgVGhpcyBtZXNzYWdlIGlzIHJlcG9ydGVkIGlmIHRoZSBuYW1lIHNwZWNpZmllZCB3YXMgbm90Ci0gICAgICAgICAqIHVzZWQgdG8gZGVjbGFyZSBhbiBhdHRyaWJ1dGUgc2V0LiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lCi0gICAgICAgICAqIHRoYXQgaXMgaW4gZXJyb3IuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuQVRUUklCU0VUX1VOREVGX0VSUiwKLSAgICAgICAgIlx1NUI1OFx1NTcyOFx1MzA1N1x1MzA2QVx1MzA0NFx1NUM1RVx1NjAyN1x1MzBCQlx1MzBDM1x1MzBDOCcnezB9JydcdTMwOTJcdTRGN0ZcdTc1MjhcdTMwNTdcdTMwODhcdTMwNDZcdTMwNjhcdTMwNTdcdTMwN0VcdTMwNTdcdTMwNUZcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHRlcm0gImF0dHJpYnV0ZSB2YWx1ZSB0ZW1wbGF0ZSIgaXMgYSB0ZXJtCi0gICAgICAgICAqIGRlZmluZWQgYnkgWFNMVCB3aGljaCBkZXNjcmliZXMgdGhlIHZhbHVlIG9mIGFuIGF0dHJpYnV0ZSB0aGF0IGlzCi0gICAgICAgICAqIGRldGVybWluZWQgYnkgYW4gWFBhdGggZXhwcmVzc2lvbi4gIFRoZSBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoZQotICAgICAgICAgKiBleHByZXNzaW9uIHdhcyBzeW50YWN0aWNhbGx5IGluY29ycmVjdDsgdGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgICAqIGNvbnRhaW5zIHRoZSBleHByZXNzaW9uIHRoYXQgd2FzIGluIGVycm9yLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkFUVFJfVkFMX1RFTVBMQVRFX0VSUiwKLSAgICAgICAgIlx1NUM1RVx1NjAyN1x1NTAyNFx1MzBDNlx1MzBGM1x1MzBEN1x1MzBFQ1x1MzBGQ1x1MzBDOCcnezB9JydcdTMwOTJcdTg5RTNcdTY3OTBcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgPz8/Ci0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVU5LTk9XTl9TSUdfVFlQRV9FUlIsCi0gICAgICAgICJcdTMwQUZcdTMwRTlcdTMwQjknJ3swfScnXHUzMDZFXHU3RjcyXHU1NDBEXHUzMDZCXHU0RTBEXHU2NjBFXHUzMDZBXHUzMEM3XHUzMEZDXHUzMEJGXHU1NzhCXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCByZWZlcnMgdG8gZGF0YSB0eXBlcy4KLSAgICAgICAgICogVGhlIG1lc3NhZ2UgaXMgZGlzcGxheWVkIGlmIGEgdmFsdWUgaW4gYSBwYXJ0aWN1bGFyIGNvbnRleHQgbmVlZHMgdG8KLSAgICAgICAgICogYmUgY29udmVydGVkIHRvIHR5cGUgezF9LCBidXQgdGhhdCdzIG5vdCBwb3NzaWJsZSBmb3IgYSB2YWx1ZSBvZgotICAgICAgICAgKiB0eXBlIHswfS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5EQVRBX0NPTlZFUlNJT05fRVJSLAotICAgICAgICAiXHUzMEM3XHUzMEZDXHUzMEJGXHU1NzhCJyd7MH0nJ1x1MzA5MicnezF9JydcdTMwNkJcdTU5MDlcdTYzREJcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIlRlbXBsYXRlcyIgaXMgYSBKYXZhIGNsYXNzIG5hbWUgdGhhdCBzaG91bGQKLSAgICAgICAgICogbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTk9fVFJBTlNMRVRfQ0xBU1NfRVJSLAotICAgICAgICAiXHUzMDUzXHUzMDZFXHUzMEM2XHUzMEYzXHUzMEQ3XHUzMEVDXHUzMEZDXHUzMEM4XHUzMDZCXHUzMDZGXHU2NzA5XHU1MkI5XHUzMDZBdHJhbnNsZXRcdTMwQUZcdTMwRTlcdTMwQjlcdTVCOUFcdTdGQTlcdTMwNENcdTU0MkJcdTMwN0VcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIlRlbXBsYXRlcyIgaXMgYSBKYXZhIGNsYXNzIG5hbWUgdGhhdCBzaG91bGQKLSAgICAgICAgICogbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTk9fTUFJTl9UUkFOU0xFVF9FUlIsCi0gICAgICAgICJcdTMwNTNcdTMwNkVcdTMwQzZcdTMwRjNcdTMwRDdcdTMwRUNcdTMwRkNcdTMwQzhcdTMwNkJcdTMwNkZcdTU0MERcdTUyNEQnJ3swfScnXHUzMDkyXHU2MzAxXHUzMDY0XHUzMEFGXHUzMEU5XHUzMEI5XHUzMDRDXHU1NDJCXHUzMDdFXHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBhIGNsYXNzLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlRSQU5TTEVUX0NMQVNTX0VSUiwKLSAgICAgICAgInRyYW5zbGV0XHUzMEFGXHUzMEU5XHUzMEI5Jyd7MH0nJ1x1MzA5Mlx1MzBFRFx1MzBGQ1x1MzBDOVx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzA2N1x1MzA1N1x1MzA1Rlx1MzAwMiJ9LAotCi0gICAgICAgIHtFcnJvck1zZy5UUkFOU0xFVF9PQkpFQ1RfRVJSLAotICAgICAgICAiVHJhbnNsZXRcdTMwQUZcdTMwRTlcdTMwQjlcdTMwNENcdTMwRURcdTMwRkNcdTMwQzlcdTMwNTVcdTMwOENcdTMwN0VcdTMwNTdcdTMwNUZcdTMwNENcdTMwMDF0cmFuc2xldFx1MzBBNFx1MzBGM1x1MzBCOVx1MzBCRlx1MzBGM1x1MzBCOVx1MzA5Mlx1NEY1Q1x1NjIxMFx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiRXJyb3JMaXN0ZW5lciIgaXMgYSBKYXZhIGludGVyZmFjZSBuYW1lIHRoYXQKLSAgICAgICAgICogc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhlIHVzZXIgdHJpZWQKLSAgICAgICAgICogdG8gc2V0IGFuIEVycm9yTGlzdGVuZXIgb2JqZWN0IG9uIG9iamVjdCBvZiB0aGUgY2xhc3MgbmFtZWQgaW4gdGhlCi0gICAgICAgICAqIHN1YnN0aXR1dGlvbiB0ZXh0IHdpdGggIm51bGwiIEphdmEgdmFsdWUuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuRVJST1JfTElTVEVORVJfTlVMTF9FUlIsCi0gICAgICAgICInJ3swfScnXHUzMDZFRXJyb3JMaXN0ZW5lclx1MzA5Mm51bGxcdTMwNkJcdThBMkRcdTVCOUFcdTMwNTdcdTMwODhcdTMwNDZcdTMwNjhcdTMwNTdcdTMwN0VcdTMwNTdcdTMwNUYifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgU3RyZWFtU291cmNlLCBTQVhTb3VyY2UgYW5kIERPTVNvdXJjZSBhcmUgSmF2YQotICAgICAgICAgKiBpbnRlcmZhY2UgbmFtZXMgdGhhdCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSkFYUF9VTktOT1dOX1NPVVJDRV9FUlIsCi0gICAgICAgICJTdHJlYW1Tb3VyY2VcdTMwMDFTQVhTb3VyY2VcdTMwNEFcdTMwODhcdTMwNzNET01Tb3VyY2VcdTMwNkVcdTMwN0ZcdTMwNENYU0xUQ1x1MzA2Qlx1MzA4OFx1MzA2M1x1MzA2Nlx1MzBCNVx1MzBERFx1MzBGQ1x1MzBDOFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OSJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiU291cmNlIiBpcyBhIEphdmEgY2xhc3MgbmFtZSB0aGF0IHNob3VsZCBub3QKLSAgICAgICAgICogYmUgdHJhbnNsYXRlZC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBKYXZhIG1ldGhvZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX05PX1NPVVJDRV9FUlIsCi0gICAgICAgICInJ3swfScnXHUzMDZCXHU2RTIxXHUzMDU1XHUzMDhDXHUzMDVGXHUzMEJEXHUzMEZDXHUzMEI5XHUzMEZCXHUzMEFBXHUzMEQ2XHUzMEI4XHUzMEE3XHUzMEFGXHUzMEM4XHUzMDZCXHUzMEIzXHUzMEYzXHUzMEM2XHUzMEYzXHUzMEM0XHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBtZXNzYWdlIGluZGljYXRlcyB0aGF0IFhTTFRDIGZhaWxlZCB0bwotICAgICAgICAgKiBjb21waWxlIHRoZSBzdHlsZXNoZWV0IGludG8gYSB0cmFuc2xldCAoY2xhc3MgZmlsZSkuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSkFYUF9DT01QSUxFX0VSUiwKLSAgICAgICAgIlx1MzBCOVx1MzBCRlx1MzBBNFx1MzBFQlx1MzBCN1x1MzBGQ1x1MzBDOFx1MzA5Mlx1MzBCM1x1MzBGM1x1MzBEMVx1MzBBNFx1MzBFQlx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzA2N1x1MzA1N1x1MzA1RiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiVHJhbnNmb3JtZXJGYWN0b3J5IiBpcyBhIGNsYXNzIG5hbWUuICBJbiB0aGlzCi0gICAgICAgICAqIGNvbnRleHQsIGFuIGF0dHJpYnV0ZSBpcyBhIHByb3BlcnR5IG9yIHNldHRpbmcgb2YgdGhlCi0gICAgICAgICAqIFRyYW5zZm9ybWVyRmFjdG9yeSBvYmplY3QuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgdGhlCi0gICAgICAgICAqIHVucmVjb2duaXNlZCBhdHRyaWJ1dGUuICBUaGUgbWV0aG9kIHVzZWQgdG8gcmV0cmlldmUgdGhlIGF0dHJpYnV0ZSBpcwotICAgICAgICAgKiAiZ2V0QXR0cmlidXRlIiwgc28gaXQncyBub3QgY2xlYXIgd2hldGhlciBpdCB3b3VsZCBiZSBiZXN0IHRvCi0gICAgICAgICAqIHRyYW5zbGF0ZSB0aGUgdGVybSAiYXR0cmlidXRlIi4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX0lOVkFMSURfQVRUUl9FUlIsCi0gICAgICAgICJUcmFuc2Zvcm1lckZhY3RvcnlcdTMwNkZcdTVDNUVcdTYwMjcnJ3swfScnXHUzMDkyXHU4QThEXHU4QjU4XHUzMDU3XHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyIn0sCi0KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfSU5WQUxJRF9BVFRSX1ZBTFVFX0VSUiwKLSAgICAgICAgIicnezB9JydcdTVDNUVcdTYwMjdcdTMwNkJcdTYzMDdcdTVCOUFcdTMwNTVcdTMwOENcdTMwNUZcdTUwMjRcdTMwNENcdTZCNjNcdTMwNTdcdTMwNEZcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgInNldFJlc3VsdCgpIiBhbmQgInN0YXJ0RG9jdW1lbnQoKSIgYXJlIEphdmEKLSAgICAgICAgICogbWV0aG9kIG5hbWVzIHRoYXQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfU0VUX1JFU1VMVF9FUlIsCi0gICAgICAgICJzZXRSZXN1bHQoKVx1MzA2RnN0YXJ0RG9jdW1lbnQoKVx1MzA4OFx1MzA4QVx1MzA4Mlx1NTI0RFx1MzA2Qlx1NTQ3Q1x1MzA3M1x1NTFGQVx1MzA1OVx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiVHJhbnNmb3JtZXIiIGlzIGEgSmF2YSBpbnRlcmZhY2UgbmFtZSB0aGF0Ci0gICAgICAgICAqIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIEEgVHJhbnNmb3JtZXIgb2JqZWN0IHNob3VsZCBjb250YWluZWQgYQotICAgICAgICAgKiByZWZlcmVuY2UgdG8gYSB0cmFuc2xldCBvYmplY3QgaW4gb3JkZXIgdG8gYmUgdXNlZCBmb3IKLSAgICAgICAgICogdHJhbnNmb3JtYXRpb25zOyB0aGlzIG1lc3NhZ2UgaXMgcHJvZHVjZWQgaWYgdGhhdCByZXF1aXJlbWVudCBpcyBub3QKLSAgICAgICAgICogbWV0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfTk9fVFJBTlNMRVRfRVJSLAotICAgICAgICAiXHUzMEM4XHUzMEU5XHUzMEYzXHUzMEI5XHUzMEQ1XHUzMEE5XHUzMEZDXHUzMERFXHUzMDZCXHUzMDZGXHUzMEFCXHUzMEQ3XHUzMEJCXHUzMEVCXHU1MzE2XHUzMDU1XHUzMDhDXHUzMDVGdHJhbnNsZXRcdTMwQUFcdTMwRDZcdTMwQjhcdTMwQTdcdTMwQUZcdTMwQzhcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIFhNTCBkb2N1bWVudCB0aGF0IHJlc3VsdHMgZnJvbSBhCi0gICAgICAgICAqIHRyYW5zZm9ybWF0aW9uIG5lZWRzIHRvIGJlIHNlbnQgdG8gYW4gb3V0cHV0IGhhbmRsZXIgb2JqZWN0OyB0aGlzCi0gICAgICAgICAqIG1lc3NhZ2UgaXMgcHJvZHVjZWQgaWYgdGhhdCByZXF1aXJlbWVudCBpcyBub3QgbWV0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfTk9fSEFORExFUl9FUlIsCi0gICAgICAgICJcdTU5MDlcdTYzREJcdTdENTBcdTY3OUNcdTMwNkJcdTVCRkVcdTMwNTdcdTMwNjZcdTVCOUFcdTdGQTlcdTZFMDhcdTMwNkVcdTUxRkFcdTUyOUJcdTMwQ0ZcdTMwRjNcdTMwQzlcdTMwRTlcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIlJlc3VsdCIgaXMgYSBKYXZhIGludGVyZmFjZSBuYW1lIGluIHRoaXMKLSAgICAgICAgICogY29udGV4dC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyBhIG1ldGhvZCBuYW1lLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfTk9fUkVTVUxUX0VSUiwKLSAgICAgICAgIicnezB9JydcdTMwNkJcdTZFMjFcdTMwNTVcdTMwOENcdTMwNUZcdTdENTBcdTY3OUNcdTMwQUFcdTMwRDZcdTMwQjhcdTMwQTdcdTMwQUZcdTMwQzhcdTMwNkZcdTcxMjFcdTUyQjlcdTMwNjdcdTMwNTlcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIlRyYW5zZm9ybWVyIiBpcyBhIEphdmEgaW50ZXJmYWNlIG5hbWUuICBUaGUKLSAgICAgICAgICogdXNlcidzIHByb2dyYW0gYXR0ZW1wdGVkIHRvIGFjY2VzcyBhbiB1bnJlY29nbml6ZWQgcHJvcGVydHkgd2l0aCB0aGUKLSAgICAgICAgICogbmFtZSBzcGVjaWZpZWQgaW4gdGhlIHN1YnN0aXR1dGlvbiB0ZXh0LiAgVGhlIG1ldGhvZCB1c2VkIHRvIHJldHJpZXZlCi0gICAgICAgICAqIHRoZSBwcm9wZXJ0eSBpcyAiZ2V0T3V0cHV0UHJvcGVydHkiLCBzbyBpdCdzIG5vdCBjbGVhciB3aGV0aGVyIGl0Ci0gICAgICAgICAqIHdvdWxkIGJlIGJlc3QgdG8gdHJhbnNsYXRlIHRoZSB0ZXJtICJwcm9wZXJ0eSIuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSkFYUF9VTktOT1dOX1BST1BfRVJSLAotICAgICAgICAiXHU3MTIxXHU1MkI5XHUzMDZBXHUzMEM4XHUzMEU5XHUzMEYzXHUzMEI5XHUzMEQ1XHUzMEE5XHUzMEZDXHUzMERFXHUzMEZCXHUzMEQ3XHUzMEVEXHUzMEQxXHUzMEM2XHUzMEEzJyd7MH0nJ1x1MzA2Qlx1MzBBMlx1MzBBRlx1MzBCQlx1MzBCOVx1MzA1N1x1MzA4OFx1MzA0Nlx1MzA2OFx1MzA1N1x1MzA3RVx1MzA1N1x1MzA1Rlx1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBTQVgyRE9NIGlzIHRoZSBuYW1lIG9mIGEgSmF2YSBjbGFzcyB0aGF0IHNob3VsZAotICAgICAgICAgKiBub3QgYmUgdHJhbnNsYXRlZC4gIFRoaXMgaXMgYW4gYWRhcHRlciBpbiB0aGUgc2Vuc2UgdGhhdCBpdCB0YWtlcyBhCi0gICAgICAgICAqIERPTSBvYmplY3QgYW5kIGNvbnZlcnRzIGl0IHRvIHNvbWV0aGluZyB0aGF0IHVzZXMgdGhlIFNBWCBBUEkuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuU0FYMkRPTV9BREFQVEVSX0VSUiwKLSAgICAgICAgIlNBWDJET01cdTMwQTJcdTMwQzBcdTMwRDdcdTMwQkYnJ3swfScnXHUzMDkyXHU0RjVDXHU2MjEwXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDY3XHUzMDU3XHUzMDVGXHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJYU0xUQ1NvdXJjZS5idWlsZCgpIiBpcyBhIEphdmEgbWV0aG9kIG5hbWUuCi0gICAgICAgICAqICJzeXN0ZW1JZCIgaXMgYW4gWE1MIHRlcm0gdGhhdCBpcyBzaG9ydCBmb3IgInN5c3RlbSBpZGVudGlmaWNhdGlvbiIuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuWFNMVENfU09VUkNFX0VSUiwKLSAgICAgICAgInN5c3RlbUlkXHUzMDkyXHU4QTJEXHU1QjlBXHUzMDVCXHUzMDVBXHUzMDZCWFNMVENTb3VyY2UuYnVpbGQoKVx1MzA0Q1x1NTQ3Q1x1MzA3M1x1NTFGQVx1MzA1NVx1MzA4Q1x1MzA3RVx1MzA1N1x1MzA1Rlx1MzAwMiJ9LAotCi0gICAgICAgIHsgRXJyb3JNc2cuRVJfUkVTVUxUX05VTEwsCi0gICAgICAgICAgICAiXHU3RDUwXHU2NzlDXHUzMDZGbnVsbFx1MzA2Qlx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MyJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhlIHZhbHVlIGFyZ3VtZW50Ci0gICAgICAgICAqIG9mIHNldFBhcmFtZXRlciBtdXN0IGJlIGEgdmFsaWQgSmF2YSBPYmplY3QuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSkFYUF9JTlZBTElEX1NFVF9QQVJBTV9WQUxVRSwKLSAgICAgICAgIlx1MzBEMVx1MzBFOVx1MzBFMVx1MzBGQ1x1MzBCRnswfVx1MzA2Rlx1NjcwOVx1NTJCOVx1MzA2QUphdmFcdTMwQUFcdTMwRDZcdTMwQjhcdTMwQTdcdTMwQUZcdTMwQzhcdTMwNjdcdTMwNDJcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTkifSwKLQotCi0gICAgICAgIHtFcnJvck1zZy5DT01QSUxFX1NURElOX0VSUiwKLSAgICAgICAgIi1pXHUzMEFBXHUzMEQ3XHUzMEI3XHUzMEU3XHUzMEYzXHUzMDZGLW9cdTMwQUFcdTMwRDdcdTMwQjdcdTMwRTdcdTMwRjNcdTMwNjhcdTMwNjhcdTMwODJcdTMwNkJcdTRGN0ZcdTc1MjhcdTMwNTlcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIifSwKLQotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgY29udGFpbnMgdXNhZ2UgaW5mb3JtYXRpb24gZm9yIGEKLSAgICAgICAgICogbWVhbnMgb2YgaW52b2tpbmcgWFNMVEMgZnJvbSB0aGUgY29tbWFuZC1saW5lLiAgVGhlIG1lc3NhZ2UgaXMKLSAgICAgICAgICogZm9ybWF0dGVkIGZvciBwcmVzZW50YXRpb24gaW4gRW5nbGlzaC4gIFRoZSBzdHJpbmdzIDxvdXRwdXQ+LAotICAgICAgICAgKiA8ZGlyZWN0b3J5PiwgZXRjLiBpbmRpY2F0ZSB1c2VyLXNwZWNpZmllZCBhcmd1bWVudCB2YWx1ZXMsIGFuZCBjYW4KLSAgICAgICAgICogYmUgdHJhbnNsYXRlZCAtIHRoZSBhcmd1bWVudCA8cGFja2FnZT4gcmVmZXJzIHRvIGEgSmF2YSBwYWNrYWdlLCBzbwotICAgICAgICAgKiBpdCBzaG91bGQgYmUgaGFuZGxlZCBpbiB0aGUgc2FtZSB3YXkgdGhlIHRlcm0gaXMgaGFuZGxlZCBmb3IgSkRLCi0gICAgICAgICAqIGRvY3VtZW50YXRpb24uCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuQ09NUElMRV9VU0FHRV9TVFIsCi0gICAgICAgICJcdTVGNjJcdTVGMEZcbiAgIGphdmEgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNtZGxpbmUuQ29tcGlsZSBbLW8gPG91dHB1dD5dXG4gICAgICBbLWQgPGRpcmVjdG9yeT5dIFstaiA8amFyZmlsZT5dIFstcCA8cGFja2FnZT5dXG4gICAgICBbLW5dIFsteF0gWy11XSBbLXZdIFstaF0geyA8c3R5bGVzaGVldD4gfCAtaSB9XG5cbk9QVElPTlNcbiAgIC1vIDxvdXRwdXQ+ICAgIFx1NTQwRFx1NTI0RDxvdXRwdXQ+XHUzMDkyXHU3NTFGXHU2MjEwXHU2RTA4dHJhbnNsZXRcdTMwNkJcbiAgICAgICAgICAgICAgICAgIFx1NTI3Mlx1MzA4QVx1NUY1M1x1MzA2Nlx1MzA4Qlx1MzAwMlx1MzBDN1x1MzBENVx1MzBBOVx1MzBFQlx1MzBDOFx1MzA2N1x1MzA2Rlx1MzAwMXRyYW5zbGV0XHU1NDBEXHUzMDZGXG4gICAgICAgICAgICAgICAgICA8c3R5bGVzaGVldD5cdTU0MERcdTMwNkJcdTc1MzFcdTY3NjVcdTMwNTdcdTMwN0VcdTMwNTlcdTMwMDJcdTMwNTNcdTMwNkVcdTMwQUFcdTMwRDdcdTMwQjdcdTMwRTdcdTMwRjNcdTMwNkZcbiAgICAgICAgICAgICAgICAgIFx1ODkwN1x1NjU3MFx1MzA2RVx1MzBCOVx1MzBCRlx1MzBBNFx1MzBFQlx1MzBCN1x1MzBGQ1x1MzBDOFx1MzA5Mlx1MzBCM1x1MzBGM1x1MzBEMVx1MzBBNFx1MzBFQlx1MzA1OVx1MzA4Qlx1NTgzNFx1NTQwOFx1MzA2Rlx1NzEyMVx1ODk5Nlx1MzA1NVx1MzA4Q1x1MzA3RVx1MzA1OVx1MzAwMlxuICAgLWQgPGRpcmVjdG9yeT4gdHJhbnNsZXRcdTMwNkVcdTVCOUJcdTUxNDhcdTMwQzdcdTMwQTNcdTMwRUNcdTMwQUZcdTMwQzhcdTMwRUFcdTMwOTJcdTYzMDdcdTVCOUFcdTMwNTlcdTMwOEJcbiAgIC1qIDxqYXJmaWxlPiAgIDxqYXJmaWxlPlx1MzA2N1x1NjMwN1x1NUI5QVx1MzA1NVx1MzA4Q1x1MzA4Qlx1NTQwRFx1NTI0RFx1MzA2RWphclx1MzBENVx1MzBBMVx1MzBBNFx1MzBFQlx1MzA2QnRyYW5zbGV0XHUzMEFGXHUzMEU5XHUzMEI5XHUzMDkyXG4gICAgICAgICAgICAgICAgICBcdTMwRDFcdTMwQzNcdTMwQjFcdTMwRkNcdTMwQjhcdTMwNTlcdTMwOEJcbiAgIC1wIDxwYWNrYWdlPiAgIFx1NzUxRlx1NjIxMFx1MzA1NVx1MzA4Q1x1MzA4Qlx1MzA1OVx1MzA3OVx1MzA2Nlx1MzA2RXRyYW5zbGV0XHUzMEFGXHUzMEU5XHUzMEI5XHUzMDZFXHUzMEQxXHUzMEMzXHUzMEIxXHUzMEZDXHUzMEI4XHU1NDBEXG4gICAgICAgICAgICAgICAgICBcdTYzQTVcdTk4MkRcdThGOUVcdTMwOTJcdTYzMDdcdTVCOUFcdTMwNTlcdTMwOEJcdTMwMDJcbiAgIC1uICAgICAgICAgICAgIFx1MzBDNlx1MzBGM1x1MzBEN1x1MzBFQ1x1MzBGQ1x1MzBDOFx1MzA2RVx1MzBBNFx1MzBGM1x1MzBFOVx1MzBBNFx1MzBGM1x1NTMxNlx1MzA5Mlx1NjcwOVx1NTJCOVx1MzA2Qlx1MzA1OVx1MzA4QihcdTVFNzNcdTU3NDdcdTMwNTdcdTMwNjZcdTMwQzdcdTMwRDVcdTMwQTlcdTMwRUJcdTMwQzhcdTUyRDVcdTRGNUNcdTMwNkVcdTY1QjlcdTMwNENcbiAgICAgICAgICAgICAgICAgIFx1NTEyQVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OSlcdTMwMDJcbiAgIC14ICAgICAgICAgICAgIFx1OEZGRFx1NTJBMFx1MzA2RVx1MzBDN1x1MzBEMFx1MzBDM1x1MzBCMFx1MzBGQlx1MzBFMVx1MzBDM1x1MzBCQlx1MzBGQ1x1MzBCOFx1NTFGQVx1NTI5Qlx1MzA5Mlx1MzBBQVx1MzBGM1x1MzA2Qlx1MzA1OVx1MzA4QlxuICAgLXUgICAgICAgICAgICAgPHN0eWxlc2hlZXQ+XHU1RjE1XHU2NTcwXHUzMDkyVVJMXHUzMDY4XHUzMDU3XHUzMDY2XHU4OUUzXHU5MUM4XHUzMDU5XHUzMDhCXG4gICAtaSAgICAgICAgICAgICBcdTMwQjlcdTMwQkZcdTMwQTRcdTMwRUJcdTMwQjdcdTMwRkNcdTMwQzhcdTMwOTJzdGRpblx1MzA0Qlx1MzA4OVx1OEFBRFx1MzA3Rlx1OEZCQ1x1MzA4MFx1MzA1M1x1MzA2OFx1MzA5Mlx1MzBCM1x1MzBGM1x1MzBEMVx1MzBBNFx1MzBFOVx1MzA2Qlx1NUYzN1x1NTIzNlx1MzA1OVx1MzA4QlxuICAgLXYgICAgICAgICAgICAgXHUzMEIzXHUzMEYzXHUzMEQxXHUzMEE0XHUzMEU5XHUzMDZFXHUzMEQwXHUzMEZDXHUzMEI4XHUzMEU3XHUzMEYzXHUzMDkyXHU1MUZBXHU1MjlCXHUzMDU5XHUzMDhCXG4gICAtaCAgICAgICAgICAgICBcdTMwNTNcdTMwNkVcdTRGN0ZcdTc1MjhcdTY1QjlcdTZDRDVcdTMwNkVcdTY1ODdcdTMwOTJcdTUxRkFcdTUyOUJcdTMwNTlcdTMwOEJcbiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgY29udGFpbnMgdXNhZ2UgaW5mb3JtYXRpb24gZm9yIGEKLSAgICAgICAgICogbWVhbnMgb2YgaW52b2tpbmcgWFNMVEMgZnJvbSB0aGUgY29tbWFuZC1saW5lLiAgVGhlIG1lc3NhZ2UgaXMKLSAgICAgICAgICogZm9ybWF0dGVkIGZvciBwcmVzZW50YXRpb24gaW4gRW5nbGlzaC4gIFRoZSBzdHJpbmdzIDxqYXJmaWxlPiwKLSAgICAgICAgICogPGRvY3VtZW50PiwgZXRjLiBpbmRpY2F0ZSB1c2VyLXNwZWNpZmllZCBhcmd1bWVudCB2YWx1ZXMsIGFuZCBjYW4KLSAgICAgICAgICogYmUgdHJhbnNsYXRlZCAtIHRoZSBhcmd1bWVudCA8Y2xhc3M+IHJlZmVycyB0byBhIEphdmEgY2xhc3MsIHNvIGl0Ci0gICAgICAgICAqIHNob3VsZCBiZSBoYW5kbGVkIGluIHRoZSBzYW1lIHdheSB0aGUgdGVybSBpcyBoYW5kbGVkIGZvciBKREsKLSAgICAgICAgICogZG9jdW1lbnRhdGlvbi4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5UUkFOU0ZPUk1fVVNBR0VfU1RSLAotICAgICAgICAiXHU1RjYyXHU1RjBGIFxuICAgamF2YSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY21kbGluZS5UcmFuc2Zvcm0gWy1qIDxqYXJmaWxlPl1cbiAgICAgIFsteF0gWy1uIDxpdGVyYXRpb25zPl0gey11IDxkb2N1bWVudF91cmw+IHwgPGRvY3VtZW50Pn1cbiAgICAgIDxjbGFzcz4gWzxwYXJhbTE+PTx2YWx1ZTE+IC4uLl1cblxuICAgdHJhbnNsZXQgPGNsYXNzPlx1MzA5Mlx1NEY3Rlx1NzUyOFx1MzA1N1x1MzA2Nlx1MzAwMTxkb2N1bWVudD5cdTMwNjdcdTYzMDdcdTVCOUFcdTMwNTVcdTMwOENcdTMwOEJcbiAgIFhNTFx1MzBDOVx1MzBBRFx1MzBFNVx1MzBFMVx1MzBGM1x1MzBDOFx1MzA5Mlx1NTkwOVx1NjNEQlx1MzA1OVx1MzA4Qlx1MzAwMnRyYW5zbGV0IDxjbGFzcz5cdTMwNkZcbiAgIFx1MzBFNlx1MzBGQ1x1MzBCNlx1MzBGQ1x1MzA2RUNMQVNTUEFUSFx1NTE4NVx1MzA0Qlx1MzAwMVx1MzBBQVx1MzBEN1x1MzBCN1x1MzBFN1x1MzBGM1x1MzA2N1x1NjMwN1x1NUI5QVx1MzA1NVx1MzA4Q1x1MzA1RjxqYXJmaWxlPlx1NTE4NVx1MzA2Qlx1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMlxuT1BUSU9OU1xuICAgLWogPGphcmZpbGU+ICAgIHRyYW5zbGV0XHUzMDkyXHUzMEVEXHUzMEZDXHUzMEM5XHUzMDU5XHUzMDhCamFyZmlsZVx1MzA5Mlx1NjMwN1x1NUI5QVx1MzA1OVx1MzA4QlxuICAgLXggICAgICAgICAgICAgIFx1OEZGRFx1NTJBMFx1MzA2RVx1MzBDN1x1MzBEMFx1MzBDM1x1MzBCMFx1MzBGQlx1MzBFMVx1MzBDM1x1MzBCQlx1MzBGQ1x1MzBCOFx1NTFGQVx1NTI5Qlx1MzA5Mlx1MzBBQVx1MzBGM1x1MzA2Qlx1MzA1OVx1MzA4QlxuICAgLW4gPGl0ZXJhdGlvbnM+IFx1NTkwOVx1NjNEQlx1MzA5MjxpdGVyYXRpb25zPlx1NTZERVx1NUI5Rlx1ODg0Q1x1MzA1N1x1MzAwMVxuICAgICAgICAgICAgICAgICAgIFx1MzBEN1x1MzBFRFx1MzBENVx1MzBBMVx1MzBBNFx1MzBFQVx1MzBGM1x1MzBCMFx1NjBDNVx1NTgzMVx1MzA5Mlx1ODg2OFx1NzkzQVx1MzA1OVx1MzA4QlxuICAgLXUgPGRvY3VtZW50X3VybD4gWE1MXHU1MTY1XHU1MjlCXHUzMEM5XHUzMEFEXHUzMEU1XHUzMEUxXHUzMEYzXHUzMEM4XHUzMDkyVVJMXHUzMDY4XHUzMDU3XHUzMDY2XHU2MzA3XHU1QjlBXHUzMDU5XHUzMDhCXG4ifSwKLQotCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICI8eHNsOnNvcnQ+IiwgIjx4c2w6Zm9yLWVhY2g+IiBhbmQKLSAgICAgICAgICogIjx4c2w6YXBwbHktdGVtcGxhdGVzPiIgYXJlIGtleXdvcmRzIHRoYXQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLgotICAgICAgICAgKiBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCBhbiB4c2w6c29ydCBlbGVtZW50IG11c3QgYmUgYSBjaGlsZCBvZgotICAgICAgICAgKiBvbmUgb2YgdGhlIG90aGVyIGtpbmRzIG9mIGVsZW1lbnRzIG1lbnRpb25lZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5TVFJBWV9TT1JUX0VSUiwKLSAgICAgICAgIjx4c2w6c29ydD5cdTMwNkY8eHNsOmZvci1lYWNoPlx1MzA3RVx1MzA1Rlx1MzA2Rjx4c2w6YXBwbHktdGVtcGxhdGVzPlx1MzA2RVx1NTE4NVx1OTBFOFx1MzA2N1x1MzA2RVx1MzA3Rlx1NEY3Rlx1NzUyOFx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1OVx1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUgZW5jb2RpbmcKLSAgICAgICAgICogcmVxdWVzdGVkIGZvciB0aGUgb3V0cHV0IGRvY3VtZW50IHdhcyBvbiB0aGF0IHJlcXVpcmVzIHN1cHBvcnQgdGhhdAotICAgICAgICAgKiBpcyBub3QgYXZhaWxhYmxlIGZyb20gdGhlIEphdmEgVmlydHVhbCBNYWNoaW5lIGJlaW5nIHVzZWQgdG8gZXhlY3V0ZQotICAgICAgICAgKiB0aGUgcHJvZ3JhbS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5VTlNVUFBPUlRFRF9FTkNPRElORywKLSAgICAgICAgIlx1NTFGQVx1NTI5Qlx1MzBBOFx1MzBGM1x1MzBCM1x1MzBGQ1x1MzBDN1x1MzBBM1x1MzBGM1x1MzBCMCcnezB9JydcdTMwNkZcdTMwNTNcdTMwNkVKVk1cdTMwNjdcdTMwNkZcdTMwQjVcdTMwRERcdTMwRkNcdTMwQzhcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhlIFhQYXRoIGV4cHJlc3Npb24KLSAgICAgICAgICogbmFtZWQgaW4gdGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHdhcyBub3Qgd2VsbCBmb3JtZWQgc3ludGFjdGljYWxseS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5TWU5UQVhfRVJSLAotICAgICAgICAiJyd7MH0nJ1x1MzA2Qlx1NjlDQlx1NjU4N1x1MzBBOFx1MzBFOVx1MzBGQ1x1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYSBKYXZhCi0gICAgICAgICAqIGNsYXNzLiAgVGhlIHRlcm0gImNvbnN0cnVjdG9yIiBoZXJlIGlzIHRoZSBKYXZhIHRlcm0uICBUaGUgbWVzc2FnZSBpcwotICAgICAgICAgKiBkaXNwbGF5ZWQgaWYgWFNMVEMgY291bGQgbm90IGZpbmQgYSBjb25zdHJ1Y3RvciBmb3IgdGhlIHNwZWNpZmllZAotICAgICAgICAgKiBjbGFzcy4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5DT05TVFJVQ1RPUl9OT1RfRk9VTkQsCi0gICAgICAgICJcdTU5MTZcdTkwRThcdTMwQjNcdTMwRjNcdTMwQjlcdTMwQzhcdTMwRTlcdTMwQUZcdTMwQkYnJ3swfScnXHUzMDRDXHU4OThCXHUzMDY0XHUzMDRCXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJzdGF0aWMiIGlzIHRoZSBKYXZhIGtleXdvcmQuICBUaGUgc3Vic3RpdHV0aW9uCi0gICAgICAgICAqIHRleHQgaXMgdGhlIG5hbWUgb2YgYSBmdW5jdGlvbi4gIFRoZSBmaXJzdCBhcmd1bWVudCBvZiB0aGF0IGZ1bmN0aW9uCi0gICAgICAgICAqIGlzIG5vdCBvZiB0aGUgcmVxdWlyZWQgdHlwZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5OT19KQVZBX0ZVTkNUX1RISVNfUkVGLAotICAgICAgICAic3RhdGljXHUzMDY3XHUzMDZBXHUzMDQ0SmF2YVx1OTVBMlx1NjU3MCcnezB9JydcdTMwNkVcdTY3MDBcdTUyMURcdTMwNkVcdTVGMTVcdTY1NzBcdTMwNkZcdTcxMjFcdTUyQjlcdTMwNkFcdTMwQUFcdTMwRDZcdTMwQjhcdTMwQTdcdTMwQUZcdTMwQzhcdTUzQzJcdTcxNjdcdTMwNjdcdTMwNTlcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQW4gWFBhdGggZXhwcmVzc2lvbiB3YXMgbm90IG9mIHRoZSB0eXBlCi0gICAgICAgICAqIHJlcXVpcmVkIGluIGEgcGFydGljdWxhciBjb250ZXh0LiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZQotICAgICAgICAgKiBleHByZXNzaW9uIHRoYXQgd2FzIGluIGVycm9yLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlRZUEVfQ0hFQ0tfRVJSLAotICAgICAgICAiXHU1RjBGJyd7MH0nJ1x1MzA2RVx1MzBCRlx1MzBBNFx1MzBEN1x1MzA2RVx1NzhCQVx1OEE4RFx1NEUyRFx1MzA2Qlx1MzBBOFx1MzBFOVx1MzBGQ1x1MzA0Q1x1NzY3QVx1NzUxRlx1MzA1N1x1MzA3RVx1MzA1N1x1MzA1Rlx1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBbiBYUGF0aCBleHByZXNzaW9uIHdhcyBub3Qgb2YgdGhlIHR5cGUKLSAgICAgICAgICogcmVxdWlyZWQgaW4gYSBwYXJ0aWN1bGFyIGNvbnRleHQuICBIb3dldmVyLCB0aGUgbG9jYXRpb24gb2YgdGhlCi0gICAgICAgICAqIHByb2JsZW1hdGljIGV4cHJlc3Npb24gaXMgdW5rbm93bi4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5UWVBFX0NIRUNLX1VOS19MT0NfRVJSLAotICAgICAgICAiXHU0RTBEXHU2NjBFXHUzMDZBXHU1ODM0XHU2MjQwXHUzMDY3XHUzMDZFXHU1RjBGXHUzMDZFXHUzMEJGXHUzMEE0XHUzMEQ3XHUzMDZFXHU3OEJBXHU4QThEXHU0RTJEXHUzMDZCXHUzMEE4XHUzMEU5XHUzMEZDXHUzMDRDXHU3NjdBXHU3NTFGXHUzMDU3XHUzMDdFXHUzMDU3XHUzMDVGXHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBhIGNvbW1hbmQtCi0gICAgICAgICAqIGxpbmUgb3B0aW9uIHRoYXQgd2FzIG5vdCByZWNvZ25pemVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfQ01ETElORV9PUFRJT05fRVJSLAotICAgICAgICAiXHUzMEIzXHUzMERFXHUzMEYzXHUzMEM5XHU4ODRDXHUzMEFBXHUzMEQ3XHUzMEI3XHUzMEU3XHUzMEYzJyd7MH0nJ1x1MzA2Rlx1NzEyMVx1NTJCOVx1MzA2N1x1MzA1OVx1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYSBjb21tYW5kLQotICAgICAgICAgKiBsaW5lIG9wdGlvbi4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5DTURMSU5FX09QVF9NSVNTSU5HX0FSR19FUlIsCi0gICAgICAgICJcdTMwQjNcdTMwREVcdTMwRjNcdTMwQzlcdTg4NENcdTMwQUFcdTMwRDdcdTMwQjdcdTMwRTdcdTMwRjMnJ3swfScnXHUzMDZCXHU1RkM1XHU5ODA4XHUzMDZFXHU1RjE1XHU2NTcwXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyB1c2VkIHRvIGluZGljYXRlIHRoZSBzZXZlcml0eQotICAgICAgICAgKiBvZiBhbm90aGVyIG1lc3NhZ2UuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgY29udGFpbnMgdHdvIGVycm9yCi0gICAgICAgICAqIG1lc3NhZ2VzLiAgVGhlIHNwYWNpbmcgYmVmb3JlIHRoZSBzZWNvbmQgc3Vic3RpdHV0aW9uIHRleHQgaW5kZW50cwotICAgICAgICAgKiBpdCB0aGUgc2FtZSBhbW91bnQgYXMgdGhlIGZpcnN0IGluIEVuZ2xpc2guCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuV0FSTklOR19QTFVTX1dSQVBQRURfTVNHLAotICAgICAgICAiV0FSTklORzogICcnezB9JydcbiAgICAgICA6ezF9In0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyB1c2VkIHRvIGluZGljYXRlIHRoZSBzZXZlcml0eQotICAgICAgICAgKiBvZiBhbm90aGVyIG1lc3NhZ2UuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgYW4gZXJyb3IgbWVzc2FnZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5XQVJOSU5HX01TRywKLSAgICAgICAgIldBUk5JTkc6ICAnJ3swfScnIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyB1c2VkIHRvIGluZGljYXRlIHRoZSBzZXZlcml0eQotICAgICAgICAgKiBvZiBhbm90aGVyIG1lc3NhZ2UuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgY29udGFpbnMgdHdvIGVycm9yCi0gICAgICAgICAqIG1lc3NhZ2VzLiAgVGhlIHNwYWNpbmcgYmVmb3JlIHRoZSBzZWNvbmQgc3Vic3RpdHV0aW9uIHRleHQgaW5kZW50cwotICAgICAgICAgKiBpdCB0aGUgc2FtZSBhbW91bnQgYXMgdGhlIGZpcnN0IGluIEVuZ2xpc2guCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuRkFUQUxfRVJSX1BMVVNfV1JBUFBFRF9NU0csCi0gICAgICAgICJGQVRBTCBFUlJPUjogICcnezB9JydcbiAgICAgICAgICAgOnsxfSJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgdXNlZCB0byBpbmRpY2F0ZSB0aGUgc2V2ZXJpdHkKLSAgICAgICAgICogb2YgYW5vdGhlciBtZXNzYWdlLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIGFuIGVycm9yIG1lc3NhZ2UuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuRkFUQUxfRVJSX01TRywKLSAgICAgICAgIkZBVEFMIEVSUk9SOiAgJyd7MH0nJyJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgdXNlZCB0byBpbmRpY2F0ZSB0aGUgc2V2ZXJpdHkKLSAgICAgICAgICogb2YgYW5vdGhlciBtZXNzYWdlLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGNvbnRhaW5zIHR3byBlcnJvcgotICAgICAgICAgKiBtZXNzYWdlcy4gIFRoZSBzcGFjaW5nIGJlZm9yZSB0aGUgc2Vjb25kIHN1YnN0aXR1dGlvbiB0ZXh0IGluZGVudHMKLSAgICAgICAgICogaXQgdGhlIHNhbWUgYW1vdW50IGFzIHRoZSBmaXJzdCBpbiBFbmdsaXNoLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkVSUk9SX1BMVVNfV1JBUFBFRF9NU0csCi0gICAgICAgICJFUlJPUjogICcnezB9JydcbiAgICAgOnsxfSJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgdXNlZCB0byBpbmRpY2F0ZSB0aGUgc2V2ZXJpdHkKLSAgICAgICAgICogb2YgYW5vdGhlciBtZXNzYWdlLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIGFuIGVycm9yIG1lc3NhZ2UuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuRVJST1JfTVNHLAotICAgICAgICAiRVJST1I6ICAnJ3swfScnIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBhIGNsYXNzLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlRSQU5TRk9STV9XSVRIX1RSQU5TTEVUX1NUUiwKLSAgICAgICAgInRyYW5zbGV0ICcnezB9JydcdTMwOTJcdTRGN0ZcdTc1MjhcdTMwNTdcdTMwNjZcdTU5MDlcdTYzREJcdTMwNTdcdTMwN0VcdTMwNTkgIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmaXJzdCBzdWJzdGl0dXRpb24gaXMgdGhlIG5hbWUgb2YgYSBjbGFzcywKLSAgICAgICAgICogd2hpbGUgdGhlIHNlY29uZCBzdWJzdGl0dXRpb24gaXMgdGhlIG5hbWUgb2YgYSBqYXIgZmlsZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5UUkFOU0ZPUk1fV0lUSF9KQVJfU1RSLAotICAgICAgICAidHJhbnNsZXQgJyd7MH0nJ1x1MzA5Mlx1NEY3Rlx1NzUyOFx1MzA1N1x1MzA2Nmphclx1MzBENVx1MzBBMVx1MzBBNFx1MzBFQicnezF9JydcdTMwNEJcdTMwODlcdTU5MDlcdTYzREJcdTMwNTdcdTMwN0VcdTMwNTkifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIlRyYW5zZm9ybWVyRmFjdG9yeSIgaXMgdGhlIG5hbWUgb2YgYSBKYXZhCi0gICAgICAgICAqIGludGVyZmFjZSBhbmQgbXVzdCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcwotICAgICAgICAgKiB0aGUgbmFtZSBvZiB0aGUgY2xhc3MgdGhhdCBjb3VsZCBub3QgYmUgaW5zdGFudGlhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkNPVUxEX05PVF9DUkVBVEVfVFJBTlNfRkFDVCwKLSAgICAgICAgIlRyYW5zZm9ybWVyRmFjdG9yeVx1MzBBRlx1MzBFOVx1MzBCOScnezB9JydcdTMwNkVcdTMwQTRcdTMwRjNcdTMwQjlcdTMwQkZcdTMwRjNcdTMwQjlcdTMwOTJcdTRGNUNcdTYyMTBcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwNjdcdTMwNTdcdTMwNUZcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIHByb2R1Y2VkIHdoZW4gdGhlIHVzZXIKLSAgICAgICAgICogc3BlY2lmaWVkIGEgbmFtZSBmb3IgdGhlIHRyYW5zbGV0IGNsYXNzIHRoYXQgY29udGFpbnMgY2hhcmFjdGVycwotICAgICAgICAgKiB0aGF0IGFyZSBub3QgcGVybWl0dGVkIGluIGEgSmF2YSBjbGFzcyBuYW1lLiAgVGhlIHN1YnN0aXR1dGlvbgotICAgICAgICAgKiB0ZXh0ICJ7MH0iIHNwZWNpZmllcyB0aGUgbmFtZSB0aGUgdXNlciByZXF1ZXN0ZWQsIHdoaWxlICJ7MX0iCi0gICAgICAgICAqIHNwZWNpZmllcyB0aGUgbmFtZSB0aGUgcHJvY2Vzc29yIHVzZWQgaW5zdGVhZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5UUkFOU0xFVF9OQU1FX0pBVkFfQ09ORkxJQ1QsCi0gICAgICAgICAiXHU1NDBEXHU1MjREJyd7MH0nJ1x1MzA2Qlx1MzA2RkphdmFcdTMwQUZcdTMwRTlcdTMwQjlcdTMwNkVcdTU0MERcdTUyNERcdTMwNkJcdThBMzFcdTUzRUZcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwNkFcdTMwNDRcdTY1ODdcdTVCNTdcdTMwNENcdTU0MkJcdTMwN0VcdTMwOENcdTMwNjZcdTMwNDRcdTMwOEJcdTMwNUZcdTMwODFcdTMwMDF0cmFuc2xldFx1MzBBRlx1MzBFOVx1MzBCOVx1MzA2RVx1NTQwRFx1NTI0RFx1MzA2OFx1MzA1N1x1MzA2Nlx1NEY3Rlx1NzUyOFx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzA2N1x1MzA1N1x1MzA1Rlx1MzAwMlx1NTQwRFx1NTI0RCcnezF9JydcdTMwNENcdTMwNEJcdTMwOEZcdTMwOEFcdTMwNkJcdTRGN0ZcdTc1MjhcdTMwNTVcdTMwOENcdTMwN0VcdTMwNTlcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIGlzIHVzZWQgYXMgYSBoZWFkZXIuCi0gICAgICAgICAqIEFsbCB0aGUgZXJyb3IgbWVzc2FnZXMgYXJlIGNvbGxlY3RlZCB0b2dldGhlciBhbmQgZGlzcGxheWVkIGJlbmVhdGgKLSAgICAgICAgICogdGhpcyBtZXNzYWdlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkNPTVBJTEVSX0VSUk9SX0tFWSwKLSAgICAgICAgIlx1MzBCM1x1MzBGM1x1MzBEMVx1MzBBNFx1MzBFOVx1MzBGQlx1MzBBOFx1MzBFOVx1MzBGQzoifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIGlzIHVzZWQgYXMgYSBoZWFkZXIuCi0gICAgICAgICAqIEFsbCB0aGUgd2FybmluZyBtZXNzYWdlcyBhcmUgY29sbGVjdGVkIHRvZ2V0aGVyIGFuZCBkaXNwbGF5ZWQKLSAgICAgICAgICogYmVuZWF0aCB0aGlzIG1lc3NhZ2UuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuQ09NUElMRVJfV0FSTklOR19LRVksCi0gICAgICAgICJcdTMwQjNcdTMwRjNcdTMwRDFcdTMwQTRcdTMwRTlcdTMwNkVcdThCNjZcdTU0NEE6In0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBpcyB1c2VkIGFzIGEgaGVhZGVyLgotICAgICAgICAgKiBBbGwgdGhlIGVycm9yIG1lc3NhZ2VzIHRoYXQgYXJlIHByb2R1Y2VkIHdoZW4gdGhlIHN0eWxlc2hlZXQgaXMKLSAgICAgICAgICogYXBwbGllZCB0byBhbiBpbnB1dCBkb2N1bWVudCBhcmUgY29sbGVjdGVkIHRvZ2V0aGVyIGFuZCBkaXNwbGF5ZWQKLSAgICAgICAgICogYmVuZWF0aCB0aGlzIG1lc3NhZ2UuICBBICd0cmFuc2xldCcgaXMgdGhlIGNvbXBpbGVkIGZvcm0gb2YgYQotICAgICAgICAgKiBzdHlsZXNoZWV0IChzZWUgYWJvdmUpLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlJVTlRJTUVfRVJST1JfS0VZLAotICAgICAgICAiVHJhbnNsZXRcdTMwQThcdTMwRTlcdTMwRkM6In0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIGF0dHJpYnV0ZSB3aG9zZSB2YWx1ZSBpcyBjb25zdHJhaW5lZCB0bwotICAgICAgICAgKiBiZSBhICJRTmFtZSIgb3IgYSBsaXN0IG9mICJRTmFtZXMiIGhhZCBhIHZhbHVlIHRoYXQgd2FzIGluY29ycmVjdC4KLSAgICAgICAgICogJ1FOYW1lJyBpcyBhbiBYTUwgc3ludGFjdGljIHRlcm0gdGhhdCBtdXN0IG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhlCi0gICAgICAgICAqIHN1YnN0aXR1dGlvbiB0ZXh0IGNvbnRhaW5zIHRoZSBhY3R1YWwgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTlZBTElEX1FOQU1FX0VSUiwKLSAgICAgICAgIlx1NTAyNFx1MzA0QzFcdTMwNjRcdTMwNkVRTmFtZVx1MzA3RVx1MzA1Rlx1MzA2RlFOYW1lXHUzMDZFXHU3QTdBXHU3NjdEXHU2NTg3XHU1QjU3XHU1MzNBXHU1MjA3XHUzMDhBXHUzMEVBXHUzMEI5XHUzMEM4XHUzMDY3XHUzMDQyXHUzMDhCXHUzMDUzXHUzMDY4XHUzMDRDXHU1RkM1XHU4OTgxXHUzMDZBXHU1QzVFXHU2MDI3XHUzMDZFXHU1MDI0XHUzMDRDJyd7MH0nJ1x1MzA2N1x1MzA1N1x1MzA1RiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBbiBhdHRyaWJ1dGUgd2hvc2UgdmFsdWUgaXMgcmVxdWlyZWQgdG8KLSAgICAgICAgICogYmUgYW4gIk5DTmFtZSIuCi0gICAgICAgICAqICdOQ05hbWUnIGlzIGFuIFhNTCBzeW50YWN0aWMgdGVybSB0aGF0IG11c3Qgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGUKLSAgICAgICAgICogc3Vic3RpdHV0aW9uIHRleHQgY29udGFpbnMgdGhlIGFjdHVhbCB2YWx1ZSBvZiB0aGUgYXR0cmlidXRlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklOVkFMSURfTkNOQU1FX0VSUiwKLSAgICAgICAgIlx1NTAyNFx1MzA0Q05DTmFtZVx1MzA2N1x1MzA0Mlx1MzA4Qlx1MzA1M1x1MzA2OFx1MzA0Q1x1NUZDNVx1ODk4MVx1MzA2QVx1NUM1RVx1NjAyN1x1MzA2RVx1NTAyNFx1MzA0QycnezB9JydcdTMwNjdcdTMwNTdcdTMwNUYifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQW4gYXR0cmlidXRlIHdpdGggYW4gaW5jb3JyZWN0IHZhbHVlIHdhcwotICAgICAgICAgKiBlbmNvdW50ZXJlZC4gIFRoZSBwZXJtaXR0ZWQgdmFsdWUgaXMgb25lIG9mIHRoZSBsaXRlcmFsIHZhbHVlcwotICAgICAgICAgKiAieG1sIiwgImh0bWwiIG9yICJ0ZXh0IjsgaXQgaXMgYWxzbyBwZXJtaXR0ZWQgdG8gaGF2ZSB0aGUgZm9ybSBvZgotICAgICAgICAgKiBhIFFOYW1lIHRoYXQgaXMgbm90IGFsc28gYW4gTkNOYW1lLiAgVGhlIHRlcm1zICJtZXRob2QiLAotICAgICAgICAgKiAieHNsOm91dHB1dCIsICJ4bWwiLCAiaHRtbCIgYW5kICJ0ZXh0IiBhcmUga2V5d29yZHMgdGhhdCBtdXN0IG5vdAotICAgICAgICAgKiBiZSB0cmFuc2xhdGVkLiAgVGhlIHRlcm0gInFuYW1lLWJ1dC1ub3QtbmNuYW1lIiBpcyBhbiBYTUwgc3ludGFjdGljCi0gICAgICAgICAqIHRlcm0uICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgY29udGFpbnMgdGhlIGFjdHVhbCB2YWx1ZSBvZiB0aGUKLSAgICAgICAgICogYXR0cmlidXRlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklOVkFMSURfTUVUSE9EX0lOX09VVFBVVCwKLSAgICAgICAgIjx4c2w6b3V0cHV0Plx1ODk4MVx1N0QyMFx1MzA2RVx1MzBFMVx1MzBCRFx1MzBDM1x1MzBDOVx1NUM1RVx1NjAyN1x1MzA2RVx1NTAyNFx1MzA0QycnezB9JydcdTMwNjdcdTMwNTdcdTMwNUZcdTMwMDJcdTUwMjRcdTMwNkYnJ3htbCcnXHUzMDAxJydodG1sJydcdTMwMDEnJ3RleHQnJ1x1MzA3RVx1MzA1Rlx1MzA2RnFuYW1lLWJ1dC1ub3QtbmNuYW1lXHUzMDZFXHUzMDQ0XHUzMDVBXHUzMDhDXHUzMDRCXHUzMDY3XHUzMDQyXHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5In0sCi0KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfR0VUX0ZFQVRVUkVfTlVMTF9OQU1FLAotICAgICAgICAiXHU2QTVGXHU4MEZEXHU1NDBEXHUzMDZGVHJhbnNmb3JtZXJGYWN0b3J5LmdldEZlYXR1cmUoU3RyaW5nIG5hbWUpXHU1MTg1XHUzMDY3bnVsbFx1MzA2Qlx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMiJ9LAotCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX1NFVF9GRUFUVVJFX05VTExfTkFNRSwKLSAgICAgICAgIlx1NkE1Rlx1ODBGRFx1NTQwRFx1MzA2RlRyYW5zZm9ybWVyRmFjdG9yeS5zZXRGZWF0dXJlKFN0cmluZyBuYW1lLCBib29sZWFuIHZhbHVlKVx1NTE4NVx1MzA2N251bGxcdTMwNkJcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIifSwKLQotICAgICAgICB7RXJyb3JNc2cuSkFYUF9VTlNVUFBPUlRFRF9GRUFUVVJFLAotICAgICAgICAiXHU2QTVGXHU4MEZEJyd7MH0nJ1x1MzA5Mlx1MzA1M1x1MzA2RVRyYW5zZm9ybWVyRmFjdG9yeVx1MzA2Qlx1OEEyRFx1NUI5QVx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMiJ9LAotCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX1NFQ1VSRVBST0NFU1NJTkdfRkVBVFVSRSwKLSAgICAgICAgIkZFQVRVUkVfU0VDVVJFX1BST0NFU1NJTkc6IFx1MzBCQlx1MzBBRFx1MzBFNVx1MzBFQVx1MzBDNlx1MzBBM1x1MzBGQlx1MzBERVx1MzBDRFx1MzBGQ1x1MzBCOFx1MzBFM1x1MzA0Q1x1NUI1OFx1NTcyOFx1MzA1OVx1MzA4Qlx1MzA2OFx1MzA0RFx1MzAwMVx1NkE1Rlx1ODBGRFx1MzA5MmZhbHNlXHUzMDZCXHU4QTJEXHU1QjlBXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBkZXNjcmliZXMgYW4gaW50ZXJuYWwgZXJyb3IgaW4gdGhlCi0gICAgICAgICAqIHByb2Nlc3Nvci4gIFRoZSB0ZXJtICJieXRlIGNvZGUiIGlzIGEgSmF2YSB0ZWNobmljYWwgdGVybSBmb3IgdGhlCi0gICAgICAgICAqIGV4ZWN1dGFibGUgY29kZSBpbiBhIEphdmEgbWV0aG9kLCBhbmQgInRyeS1jYXRjaC1maW5hbGx5IGJsb2NrIgotICAgICAgICAgKiByZWZlcnMgdG8gdGhlIEphdmEga2V5d29yZHMgd2l0aCB0aG9zZSBuYW1lcy4gICJPdXRsaW5lZCIgaXMgYQotICAgICAgICAgKiB0ZWNobmljYWwgdGVybSBpbnRlcm5hbCB0byBYU0xUQyBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk9VVExJTkVfRVJSX1RSWV9DQVRDSCwKLSAgICAgICAgICJcdTUxODVcdTkwRThYU0xUQ1x1MzBBOFx1MzBFOVx1MzBGQzogXHU3NTFGXHU2MjEwXHUzMDU1XHUzMDhDXHUzMDVGXHUzMEQwXHUzMEE0XHUzMEM4XHUzMEZCXHUzMEIzXHUzMEZDXHUzMEM5XHUzMDZGXHUzMDAxdHJ5LWNhdGNoLWZpbmFsbHlcdTMwRDZcdTMwRURcdTMwQzNcdTMwQUZcdTMwOTJcdTU0MkJcdTMwOTNcdTMwNjdcdTMwNDRcdTMwOEJcdTMwNUZcdTMwODFcdTMwMDFcdTMwQTJcdTMwQTZcdTMwQzhcdTMwRTlcdTMwQTRcdTMwRjNcdTUzMTZcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGRlc2NyaWJlcyBhbiBpbnRlcm5hbCBlcnJvciBpbiB0aGUKLSAgICAgICAgICogcHJvY2Vzc29yLiAgVGhlIHRlcm1zICJPdXRsaW5lYWJsZUNodW5rU3RhcnQiIGFuZAotICAgICAgICAgKiAiT3V0bGluZWFibGVDaHVua0VuZCIgYXJlIHRoZSBuYW1lcyBvZiBjbGFzc2VzIGludGVybmFsIHRvIFhTTFRDIGFuZAotICAgICAgICAgKiBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCBmb3IgZXZlcnkKLSAgICAgICAgICogInN0YXJ0IiB0aGVyZSBtdXN0IGJlIGEgY29ycmVzcG9uZGluZyAiZW5kIiwgYW5kIHZpY2UgdmVyc2EsIGFuZAotICAgICAgICAgKiB0aGF0IGlmIG9uZSBvZiBhIHBhaXIgb2YgInN0YXJ0IiBhbmQgImVuZCIgYXBwZWFycyBiZXR3ZWVuIGFub3RoZXIKLSAgICAgICAgICogcGFpciBvZiBjb3JyZXNwb25kaW5nICJzdGFydCIgYW5kICJlbmQiLCB0aGVuIHRoZSBvdGhlciBoYWxmIG9mIHRoZQotICAgICAgICAgKiBwYWlyIG11c3QgYWxzbyBiZSBiZXR3ZWVuIHRoYXQgc2FtZSBlbmNsb3NpbmcgcGFpci4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5PVVRMSU5FX0VSUl9VTkJBTEFOQ0VEX01BUktFUlMsCi0gICAgICAgICAiXHU1MTg1XHU5MEU4WFNMVENcdTMwQThcdTMwRTlcdTMwRkM6IE91dGxpbmVhYmxlQ2h1bmtTdGFydFx1MzBERVx1MzBGQ1x1MzBBQlx1MzBGQ1x1MzA2OE91dGxpbmVhYmxlQ2h1bmtFbmRcdTMwREVcdTMwRkNcdTMwQUJcdTMwRkNcdTMwNkZcdTMwMDFcdTVCRkVcdTMwNkJcdTMwNkFcdTMwNjNcdTMwNjZcdTMwNEFcdTMwOEFcdTMwMDFcdTMwNEJcdTMwNjRcdTZCNjNcdTMwNTdcdTMwNEZcdTMwQ0RcdTMwQjlcdTMwQzhcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGRlc2NyaWJlcyBhbiBpbnRlcm5hbCBlcnJvciBpbiB0aGUKLSAgICAgICAgICogcHJvY2Vzc29yLiAgVGhlIHRlcm0gImJ5dGUgY29kZSIgaXMgYSBKYXZhIHRlY2huaWNhbCB0ZXJtIGZvciB0aGUKLSAgICAgICAgICogZXhlY3V0YWJsZSBjb2RlIGluIGEgSmF2YSBtZXRob2QuICBUaGUgIm1ldGhvZCIgdGhhdCBpcyBiZWluZwotICAgICAgICAgKiByZWZlcnJlZCB0byBpcyBhIEphdmEgbWV0aG9kIGluIGEgdHJhbnNsZXQgdGhhdCBYU0xUQyBpcyBnZW5lcmF0aW5nCi0gICAgICAgICAqIGluIHByb2Nlc3NpbmcgYSBzdHlsZXNoZWV0LiAgVGhlICJpbnN0cnVjdGlvbiIgdGhhdCBpcyBiZWluZwotICAgICAgICAgKiByZWZlcnJlZCB0byBpcyBvbmUgb2YgdGhlIGluc3RydXRpb25zIGluIHRoZSBKYXZhIGJ5dGUgY29kZSBpbiB0aGF0Ci0gICAgICAgICAqIG1ldGhvZC4gICJPdXRsaW5lZCIgaXMgYSB0ZWNobmljYWwgdGVybSBpbnRlcm5hbCB0byBYU0xUQyBhbmQKLSAgICAgICAgICogc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk9VVExJTkVfRVJSX0RFTEVURURfVEFSR0VULAotICAgICAgICAgIlx1NTE4NVx1OTBFOFhTTFRDXHUzMEE4XHUzMEU5XHUzMEZDOiBcdTMwQTJcdTMwQTZcdTMwQzhcdTMwRTlcdTMwQTRcdTMwRjNcdTUzMTZcdTMwNTVcdTMwOENcdTMwNUZcdTMwRDBcdTMwQTRcdTMwQzhcdTMwRkJcdTMwQjNcdTMwRkNcdTMwQzlcdTMwNkVcdTMwRDZcdTMwRURcdTMwQzNcdTMwQUZcdTMwNkVcdTRFMDBcdTkwRThcdTMwNjdcdTMwNDJcdTMwNjNcdTMwNUZcdTU0N0RcdTRFRTRcdTMwNkZcdTMwMDFcdTUxNDNcdTMwNkVcdTMwRTFcdTMwQkRcdTMwQzNcdTMwQzlcdTMwNkVcdTRFMkRcdTMwNjdcdTMwN0VcdTMwNjBcdTUzQzJcdTcxNjdcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTlcdTMwMDIiCi0gICAgICAgIH0sCi0KLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGRlc2NyaWJlcyBhbiBpbnRlcm5hbCBlcnJvciBpbiB0aGUKLSAgICAgICAgICogcHJvY2Vzc29yLiAgVGhlICJtZXRob2QiIHRoYXQgaXMgYmVpbmcgcmVmZXJyZWQgdG8gaXMgYSBKYXZhIG1ldGhvZAotICAgICAgICAgKiBpbiBhIHRyYW5zbGV0IHRoYXQgWFNMVEMgaXMgZ2VuZXJhdGluZy4KLSAgICAgICAgICoKLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5PVVRMSU5FX0VSUl9NRVRIT0RfVE9PX0JJRywKLSAgICAgICAgICJcdTUxODVcdTkwRThYU0xUQ1x1MzBBOFx1MzBFOVx1MzBGQzogXHUzMEM4XHUzMEU5XHUzMEYzXHUzMEI5XHUzMEVDXHUzMEMzXHUzMEM4XHU1MTg1XHUzMDZFXHUzMEUxXHUzMEJEXHUzMEMzXHUzMEM5XHUzMDRDXHUzMDAxSmF2YVx1NEVFRVx1NjBGM1x1MzBERVx1MzBCN1x1MzBGM1x1MzA2RVx1NTIzNlx1OTY1MCgxXHUzMEUxXHUzMEJEXHUzMEMzXHUzMEM5XHUzMDZFXHU5NTc3XHUzMDU1XHUzMDZGXHU2NzAwXHU1OTI3NjRcdTMwQURcdTMwRURcdTMwRDBcdTMwQTRcdTMwQzgpXHUzMDkyXHU4RDg1XHUzMDQ4XHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5XHUzMDAyXHU0RTAwXHU4MjJDXHU3Njg0XHUzMDZCXHUzMDAxXHUzMEI5XHUzMEJGXHUzMEE0XHUzMEVCXHUzMEI3XHUzMEZDXHUzMEM4XHU1MTg1XHUzMDZFXHUzMEM2XHUzMEYzXHUzMEQ3XHUzMEVDXHUzMEZDXHUzMEM4XHUzMDZFXHUzMEI1XHUzMEE0XHUzMEJBXHUzMDRDXHU1OTI3XHUzMDREXHU5MDRFXHUzMDRFXHUzMDhCXHUzMDUzXHUzMDY4XHUzMDRDXHU1MzlGXHU1NkUwXHUzMDY4XHUzMDU3XHUzMDY2XHU4MDAzXHUzMDQ4XHUzMDg5XHUzMDhDXHUzMDdFXHUzMDU5XHUzMDAyXHU1QzBGXHUzMDU1XHUzMDQ0XHUzMEI1XHUzMEE0XHUzMEJBXHUzMDZFXHUzMEM2XHUzMEYzXHUzMEQ3XHUzMEVDXHUzMEZDXHUzMEM4XHUzMDkyXHU0RjdGXHU3NTI4XHUzMDU3XHUzMDY2XHUzMDAxXHUzMEI5XHUzMEJGXHUzMEE0XHUzMEVCXHUzMEI3XHUzMEZDXHUzMEM4XHUzMDkyXHU1MThEXHU2OUNCXHU2MjEwXHUzMDU3XHUzMDY2XHUzMDRGXHUzMDYwXHUzMDU1XHUzMDQ0XHUzMDAyIgotICAgICAgICB9LAotCi0gICAgICAgICB7RXJyb3JNc2cuREVTRVJJQUxJWkVfVFJBTlNMRVRfRVJSLCAiSmF2YVx1MzBCQlx1MzBBRFx1MzBFNVx1MzBFQVx1MzBDNlx1MzBBM1x1MzA0Q1x1NjcwOVx1NTJCOVx1NTMxNlx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA4Qlx1NTgzNFx1NTQwOFx1MzAwMVRlbXBsYXRlc0ltcGxcdTMwNkVcdTMwQzdcdTMwQjdcdTMwRUFcdTMwQTJcdTMwRTlcdTMwQTRcdTMwQkFcdTMwNkVcdTMwQjVcdTMwRERcdTMwRkNcdTMwQzhcdTMwNkZcdTcxMjFcdTUyQjlcdTUzMTZcdTMwNTVcdTMwOENcdTMwN0VcdTMwNTlcdTMwMDJcdTMwNTNcdTMwOENcdTMwNkZcdTMwMDFqZGsueG1sLmVuYWJsZVRlbXBsYXRlc0ltcGxEZXNlcmlhbGl6YXRpb25cdTMwQjdcdTMwQjlcdTMwQzZcdTMwRTBcdTMwRkJcdTMwRDdcdTMwRURcdTMwRDFcdTMwQzZcdTMwQTNcdTMwOTJ0cnVlXHUzMDZCXHU4QTJEXHU1QjlBXHUzMDU3XHUzMDY2XHUzMEFBXHUzMEZDXHUzMEQwXHUzMEZDXHUzMEU5XHUzMEE0XHUzMEM5XHUzMDY3XHUzMDREXHUzMDdFXHUzMDU5XHUzMDAyIn0KLQotICAgIH07Ci0KLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL3V0aWwvRXJyb3JNZXNzYWdlc19rby5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci91dGlsL0Vycm9yTWVzc2FnZXNfa28uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZTBmMGVmNi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL3V0aWwvRXJyb3JNZXNzYWdlc19rby5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTc0ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbDsKLQotaW1wb3J0IGphdmEudXRpbC5MaXN0UmVzb3VyY2VCdW5kbGU7Ci0KLS8qKgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKi8KLXB1YmxpYyBjbGFzcyBFcnJvck1lc3NhZ2VzX2tvIGV4dGVuZHMgTGlzdFJlc291cmNlQnVuZGxlIHsKLQotLyoKLSAqIFhTTFRDIGNvbXBpbGUtdGltZSBlcnJvciBtZXNzYWdlcy4KLSAqCi0gKiBHZW5lcmFsIG5vdGVzIHRvIHRyYW5zbGF0b3JzIGFuZCBkZWZpbml0aW9uczoKLSAqCi0gKiAgIDEpIFhTTFRDIGlzIHRoZSBuYW1lIG9mIHRoZSBwcm9kdWN0LiAgSXQgaXMgYW4gYWNyb255bSBmb3IgIlhTTFQgQ29tcGlsZXIiLgotICogICAgICBYU0xUIGlzIGFuIGFjcm9ueW0gZm9yICJYTUwgU3R5bGVzaGVldCBMYW5ndWFnZTogVHJhbnNmb3JtYXRpb25zIi4KLSAqCi0gKiAgIDIpIEEgc3R5bGVzaGVldCBpcyBhIGRlc2NyaXB0aW9uIG9mIGhvdyB0byB0cmFuc2Zvcm0gYW4gaW5wdXQgWE1MIGRvY3VtZW50Ci0gKiAgICAgIGludG8gYSByZXN1bHRhbnQgWE1MIGRvY3VtZW50IChvciBIVE1MIGRvY3VtZW50IG9yIHRleHQpLiAgVGhlCi0gKiAgICAgIHN0eWxlc2hlZXQgaXRzZWxmIGlzIGRlc2NyaWJlZCBpbiB0aGUgZm9ybSBvZiBhbiBYTUwgZG9jdW1lbnQuCi0gKgotICogICAzKSBBIHRlbXBsYXRlIGlzIGEgY29tcG9uZW50IG9mIGEgc3R5bGVzaGVldCB0aGF0IGlzIHVzZWQgdG8gbWF0Y2ggYQotICogICAgICBwYXJ0aWN1bGFyIHBvcnRpb24gb2YgYW4gaW5wdXQgZG9jdW1lbnQgYW5kIHNwZWNpZmllcyB0aGUgZm9ybSBvZiB0aGUKLSAqICAgICAgY29ycmVzcG9uZGluZyBwb3J0aW9uIG9mIHRoZSBvdXRwdXQgZG9jdW1lbnQuCi0gKgotICogICA0KSBBbiBheGlzIGlzIGEgcGFydGljdWxhciAiZGltZW5zaW9uIiBpbiBhIHRyZWUgcmVwcmVzZW50YXRpb24gb2YgYW4gWE1MCi0gKiAgICAgIGRvY3VtZW50OyB0aGUgbm9kZXMgaW4gdGhlIHRyZWUgYXJlIGRpdmlkZWQgYWxvbmcgZGlmZmVyZW50IGF4ZXMuCi0gKiAgICAgIFRyYXZlcnNpbmcgdGhlICJjaGlsZCIgYXhpcywgZm9yIGluc3RhbmNlLCBtZWFucyB0aGF0IHRoZSBwcm9ncmFtCi0gKiAgICAgIHdvdWxkIHZpc2l0IGVhY2ggY2hpbGQgb2YgYSBwYXJ0aWN1bGFyIG5vZGU7IHRyYXZlcnNpbmcgdGhlICJkZXNjZW5kYW50IgotICogICAgICBheGlzIG1lYW5zIHRoYXQgdGhlIHByb2dyYW0gd291bGQgdmlzaXQgdGhlIGNoaWxkIG5vZGVzIG9mIGEgcGFydGljdWxhcgotICogICAgICBub2RlLCB0aGVpciBjaGlsZHJlbiwgYW5kIHNvIG9uIHVudGlsIHRoZSBsZWFmIG5vZGVzIG9mIHRoZSB0cmVlIGFyZQotICogICAgICByZWFjaGVkLgotICoKLSAqICAgNSkgQW4gaXRlcmF0b3IgaXMgYW4gb2JqZWN0IHRoYXQgdHJhdmVyc2VzIG5vZGVzIGluIGEgdHJlZSBhbG9uZyBhCi0gKiAgICAgIHBhcnRpY3VsYXIgYXhpcywgb25lIGF0IGEgdGltZS4KLSAqCi0gKiAgIDYpIEFuIGVsZW1lbnQgaXMgYSBtYXJrLXVwIHRhZyBpbiBhbiBYTUwgZG9jdW1lbnQ7IGFuIGF0dHJpYnV0ZSBpcyBhCi0gKiAgICAgIG1vZGlmaWVyIG9uIHRoZSB0YWcuICBGb3IgZXhhbXBsZSwgaW4gPGVsZW0gYXR0cj0ndmFsJyBhdHRyMj0ndmFsMic+Ci0gKiAgICAgICJlbGVtIiBpcyBhbiBlbGVtZW50IG5hbWUsICJhdHRyIiBhbmQgImF0dHIyIiBhcmUgYXR0cmlidXRlIG5hbWVzIHdpdGgKLSAqICAgICAgdGhlIHZhbHVlcyAidmFsIiBhbmQgInZhbDIiLCByZXNwZWN0aXZlbHkuCi0gKgotICogICA3KSBBIG5hbWVzcGFjZSBkZWNsYXJhdGlvbiBpcyBhIHNwZWNpYWwgYXR0cmlidXRlIHRoYXQgaXMgdXNlZCB0byBhc3NvY2lhdGUKLSAqICAgICAgYSBwcmVmaXggd2l0aCBhIFVSSSAodGhlIG5hbWVzcGFjZSkuICBUaGUgbWVhbmluZ3Mgb2YgZWxlbWVudCBuYW1lcyBhbmQKLSAqICAgICAgYXR0cmlidXRlIG5hbWVzIHRoYXQgdXNlIHRoYXQgcHJlZml4IGFyZSBkZWZpbmVkIHdpdGggcmVzcGVjdCB0byB0aGF0Ci0gKiAgICAgIG5hbWVzcGFjZS4KLSAqCi0gKiAgIDgpIERPTSBpcyBhbiBhY3JvbnltIGZvciBEb2N1bWVudCBPYmplY3QgTW9kZWwuICBJdCBpcyBhIHRyZWUKLSAqICAgICAgcmVwcmVzZW50YXRpb24gb2YgYW4gWE1MIGRvY3VtZW50LgotICoKLSAqICAgICAgU0FYIGlzIGFuIGFjcm9ueW0gZm9yIHRoZSBTaW1wbGUgQVBJIGZvciBYTUwgcHJvY2Vzc2luZy4gIEl0IGlzIGFuIEFQSQotICogICAgICB1c2VkIGluZm9ybSBhbiBYTUwgcHJvY2Vzc29yIChpbiB0aGlzIGNhc2UgWFNMVEMpIG9mIHRoZSBzdHJ1Y3R1cmUgYW5kCi0gKiAgICAgIGNvbnRlbnQgb2YgYW4gWE1MIGRvY3VtZW50LgotICoKLSAqICAgICAgSW5wdXQgdG8gdGhlIHN0eWxlc2hlZXQgcHJvY2Vzc29yIGNhbiBjb21lIGZyb20gYW4gWE1MIHBhcnNlciBpbiB0aGUKLSAqICAgICAgZm9ybSBvZiBhIERPTSB0cmVlIG9yIHRocm91Z2ggdGhlIFNBWCBBUEkuCi0gKgotICogICA5KSBEVEQgaXMgYSBkb2N1bWVudCB0eXBlIGRlY2xhcmF0aW9uLiAgSXQgaXMgYSB3YXkgb2Ygc3BlY2lmeWluZyB0aGUKLSAqICAgICAgZ3JhbW1hciBmb3IgYW4gWE1MIGZpbGUsIHRoZSBuYW1lcyBhbmQgdHlwZXMgb2YgZWxlbWVudHMsIGF0dHJpYnV0ZXMsCi0gKiAgICAgIGV0Yy4KLSAqCi0gKiAgMTApIFhQYXRoIGlzIGEgc3BlY2lmaWNhdGlvbiB0aGF0IGRlc2NyaWJlcyBhIG5vdGF0aW9uIGZvciBpZGVudGlmeWluZwotICogICAgICBub2RlcyBpbiBhIHRyZWUtc3RydWN0dXJlZCByZXByZXNlbnRhdGlvbiBvZiBhbiBYTUwgZG9jdW1lbnQuICBBbgotICogICAgICBpbnN0YW5jZSBvZiB0aGF0IG5vdGF0aW9uIGlzIHJlZmVycmVkIHRvIGFzIGFuIFhQYXRoIGV4cHJlc3Npb24uCi0gKgotICogIDExKSBUcmFuc2xldCBpcyBhbiBpbnZlbnRlZCB0ZXJtIHRoYXQgcmVmZXJzIHRvIHRoZSBjbGFzcyBmaWxlIHRoYXQgY29udGFpbnMKLSAqICAgICAgdGhlIGNvbXBpbGVkIGZvcm0gb2YgYSBzdHlsZXNoZWV0LgotICovCi0KLSAgICAvLyBUaGVzZSBtZXNzYWdlIHNob3VsZCBiZSByZWFkIGZyb20gYSBsb2NhbGUtc3BlY2lmaWMgcmVzb3VyY2UgYnVuZGxlCi0gICAgLyoqIEdldCB0aGUgbG9va3VwIHRhYmxlIGZvciBlcnJvciBtZXNzYWdlcy4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIG1lc3NhZ2UgbG9va3VwIHRhYmxlLgotICAgICAqLwotICAgIHB1YmxpYyBPYmplY3RbXVtdIGdldENvbnRlbnRzKCkKLSAgICB7Ci0gICAgICByZXR1cm4gbmV3IE9iamVjdFtdW10gewotICAgICAgICB7RXJyb3JNc2cuTVVMVElQTEVfU1RZTEVTSEVFVF9FUlIsCi0gICAgICAgICJcdUIzRDlcdUM3N0NcdUQ1NUMgXHVEMzBDXHVDNzdDXHVDNUQwIFx1QzJBNFx1RDBDMFx1Qzc3Q1x1QzJEQ1x1RDJCOFx1QUMwMCBcdUI0NTAgXHVBQzFDIFx1Qzc3NFx1QzBDMSBcdUM4MTVcdUM3NThcdUI0MThcdUM1QzhcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBhCi0gICAgICAgICAqIHRlbXBsYXRlLiAgVGhlIHNhbWUgbmFtZSB3YXMgdXNlZCBvbiB0d28gZGlmZmVyZW50IHRlbXBsYXRlcyBpbiB0aGUKLSAgICAgICAgICogc2FtZSBzdHlsZXNoZWV0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlRFTVBMQVRFX1JFREVGX0VSUiwKLSAgICAgICAgIlx1Qzc3NCBcdUMyQTRcdUQwQzBcdUM3N0NcdUMyRENcdUQyQjhcdUM1RDBcdUIyOTQgJyd7MH0nJyBcdUQxNUNcdUQ1MENcdUI5QUNcdUQyQjhcdUFDMDAgXHVDNzc0XHVCQkY4IFx1QzgxNVx1Qzc1OFx1QjQxOFx1QzVDOFx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYQotICAgICAgICAgKiB0ZW1wbGF0ZS4gIEEgcmVmZXJlbmNlIHRvIHRoZSB0ZW1wbGF0ZSBuYW1lIHdhcyBlbmNvdW50ZXJlZCwgYnV0IHRoZQotICAgICAgICAgKiB0ZW1wbGF0ZSBpcyB1bmRlZmluZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVEVNUExBVEVfVU5ERUZfRVJSLAotICAgICAgICAiXHVDNzc0IFx1QzJBNFx1RDBDMFx1Qzc3Q1x1QzJEQ1x1RDJCOFx1QzVEMFx1QjI5NCAnJ3swfScnIFx1RDE1Q1x1RDUwQ1x1QjlBQ1x1RDJCOFx1QUMwMCBcdUM4MTVcdUM3NThcdUI0MThcdUM5QzAgXHVDNTRBXHVDNTU4XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYSB2YXJpYWJsZQotICAgICAgICAgKiB0aGF0IHdhcyBkZWZpbmVkIG1vcmUgdGhhbiBvbmNlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlZBUklBQkxFX1JFREVGX0VSUiwKLSAgICAgICAgIlx1QjNEOVx1Qzc3Q1x1RDU1QyBcdUJDOTRcdUM3MDRcdUM1RDBcdUMxMUMgJyd7MH0nJyBcdUJDQzBcdUMyMThcdUFDMDAgXHVDNUVDXHVCN0VDIFx1QUMxQyBcdUM4MTVcdUM3NThcdUI0MThcdUM1QzhcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBhIHZhcmlhYmxlCi0gICAgICAgICAqIG9yIHBhcmFtZXRlci4gIEEgcmVmZXJlbmNlIHRvIHRoZSB2YXJpYWJsZSBvciBwYXJhbWV0ZXIgd2FzIGZvdW5kLAotICAgICAgICAgKiBidXQgaXQgd2FzIG5ldmVyIGRlZmluZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVkFSSUFCTEVfVU5ERUZfRVJSLAotICAgICAgICAiXHVCQ0MwXHVDMjE4IFx1QjYxMFx1QjI5NCBcdUI5RTRcdUFDMUNcdUJDQzBcdUMyMTggJyd7MH0nJ1x1Qzc3NChcdUFDMDApIFx1QzgxNVx1Qzc1OFx1QjQxOFx1QzlDMCBcdUM1NEFcdUM1NThcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSB3b3JkICJjbGFzcyIgaGVyZSByZWZlcnMgdG8gYSBKYXZhIGNsYXNzLgotICAgICAgICAgKiBQcm9jZXNzaW5nIHRoZSBzdHlsZXNoZWV0IHJlcXVpcmVkIGEgY2xhc3MgdG8gYmUgbG9hZGVkLCBidXQgaXQgY291bGQKLSAgICAgICAgICogbm90IGJlIGZvdW5kLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIHRoZSBjbGFzcy4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5DTEFTU19OT1RfRk9VTkRfRVJSLAotICAgICAgICAiJyd7MH0nJyBcdUQwNzRcdUI3OThcdUMyQTRcdUI5N0MgXHVDQzNFXHVDNzQ0IFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSB3b3JkICJtZXRob2QiIGhlcmUgcmVmZXJzIHRvIGEgSmF2YSBtZXRob2QuCi0gICAgICAgICAqIFByb2Nlc3NpbmcgdGhlIHN0eWxlc2hlZXQgcmVxdWlyZWQgYSByZWZlcmVuY2UgdG8gdGhlIG1ldGhvZCBuYW1lZCBieQotICAgICAgICAgKiB0aGUgc3Vic3RpdHV0aW9uIHRleHQsIGJ1dCBpdCBjb3VsZCBub3QgYmUgZm91bmQuICAicHVibGljIiBpcyB0aGUKLSAgICAgICAgICogSmF2YSBrZXl3b3JkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk1FVEhPRF9OT1RfRk9VTkRfRVJSLAotICAgICAgICAiXHVDNjc4XHVCRDgwIFx1QkE1NFx1QzE4Q1x1QjREQyAnJ3swfScnXHVDNzQ0KFx1Qjk3QykgXHVDQzNFXHVDNzQ0IFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuIFx1Qzc3NCBcdUJBNTRcdUMxOENcdUI0RENcdUIyOTQgcHVibGljXHVDNzc0XHVDNUI0XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHdvcmQgIm1ldGhvZCIgaGVyZSByZWZlcnMgdG8gYSBKYXZhIG1ldGhvZC4KLSAgICAgICAgICogUHJvY2Vzc2luZyB0aGUgc3R5bGVzaGVldCByZXF1aXJlZCBhIHJlZmVyZW5jZSB0byB0aGUgbWV0aG9kIG5hbWVkIGJ5Ci0gICAgICAgICAqIHRoZSBzdWJzdGl0dXRpb24gdGV4dCwgYnV0IG5vIG1ldGhvZCB3aXRoIHRoZSByZXF1aXJlZCB0eXBlcyBvZgotICAgICAgICAgKiBhcmd1bWVudHMgb3IgcmV0dXJuIHR5cGUgY291bGQgYmUgZm91bmQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuQVJHVU1FTlRfQ09OVkVSU0lPTl9FUlIsCi0gICAgICAgICInJ3swfScnIFx1QkE1NFx1QzE4Q1x1QjREQ1x1QzVEMCBcdUIzMDBcdUQ1NUMgXHVENjM4XHVDRDlDXHVDNUQwXHVDMTFDIFx1Qzc3OFx1QzIxOC9cdUJDMThcdUQ2NTggXHVDNzIwXHVENjE1XHVDNzQ0IFx1QkNDMFx1RDY1OFx1RDU2MCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZmlsZSBvciBVUkkgbmFtZWQgaW4gdGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgICAqIGlzIG1pc3NpbmcuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuRklMRV9OT1RfRk9VTkRfRVJSLAotICAgICAgICAiXHVEMzBDXHVDNzdDIFx1QjYxMFx1QjI5NCBVUkkgJyd7MH0nJ1x1Qzc0NChcdUI5N0MpIFx1Q0MzRVx1Qzc0NCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgZGlzcGxheWVkIHdoZW4gdGhlIFVSSQotICAgICAgICAgKiBtZW50aW9uZWQgaW4gdGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIG5vdCB3ZWxsLWZvcm1lZCBzeW50YWN0aWNhbGx5LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklOVkFMSURfVVJJX0VSUiwKLSAgICAgICAgIlVSSSAnJ3swfScnXHVDNzc0KFx1QUMwMCkgXHVCRDgwXHVDODAxXHVENTY5XHVENTY5XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZmlsZSBvciBVUkkgbmFtZWQgaW4gdGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgICAqIGV4aXN0cyBidXQgY291bGQgbm90IGJlIG9wZW5lZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5GSUxFX0FDQ0VTU19FUlIsCi0gICAgICAgICJcdUQzMENcdUM3N0MgXHVCNjEwXHVCMjk0IFVSSSAnJ3swfScnXHVDNzQ0KFx1Qjk3QykgXHVDNUY0IFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogPHhzbDpzdHlsZXNoZWV0PiBhbmQgPHhzbDp0cmFuc2Zvcm0+IGFyZQotICAgICAgICAgKiBrZXl3b3JkcyB0aGF0IHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5NSVNTSU5HX1JPT1RfRVJSLAotICAgICAgICAiPHhzbDpzdHlsZXNoZWV0PiBcdUI2MTBcdUIyOTQgPHhzbDp0cmFuc2Zvcm0+IFx1QzY5NFx1QzE4Q1x1QUMwMCBcdUQ1NDRcdUM2OTRcdUQ1NjlcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IGNvbnRhaW5lZCBhIHJlZmVyZW5jZSB0byBhCi0gICAgICAgICAqIG5hbWVzcGFjZSBwcmVmaXggdGhhdCB3YXMgdW5kZWZpbmVkLiAgVGhlIHZhbHVlIG9mIHRoZSBzdWJzdGl0dXRpb24KLSAgICAgICAgICogdGV4dCBpcyB0aGUgbmFtZSBvZiB0aGUgcHJlZml4LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk5BTUVTUEFDRV9VTkRFRl9FUlIsCi0gICAgICAgICJcdUIxMjRcdUM3ODRcdUMyQTRcdUQzOThcdUM3NzRcdUMyQTQgXHVDODExXHVCNDUwXHVDNUI0ICcnezB9JydcdUM3NzQoXHVBQzAwKSBcdUMxMjBcdUM1QjhcdUI0MThcdUM5QzAgXHVDNTRBXHVDNTU4XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgSmF2YSBmdW5jdGlvbiBuYW1lZCBpbiB0aGUgc3R5bGVzaGVldCBjb3VsZAotICAgICAgICAgKiBub3QgYmUgZm91bmQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuRlVOQ1RJT05fUkVTT0xWRV9FUlIsCi0gICAgICAgICInJ3swfScnIFx1RDU2OFx1QzIxOFx1QzVEMCBcdUIzMDBcdUQ1NUMgXHVENjM4XHVDRDlDXHVDNzQ0IFx1QkQ4NFx1QzExRFx1RDU2MCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYQotICAgICAgICAgKiBmdW5jdGlvbi4gIEEgbGl0ZXJhbCBzdHJpbmcgaGVyZSBtZWFucyBhIGNvbnN0YW50IHN0cmluZyB2YWx1ZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5ORUVEX0xJVEVSQUxfRVJSLAotICAgICAgICAiJyd7MH0nJ1x1QzVEMCBcdUIzMDBcdUQ1NUMgXHVDNzc4XHVDMjE4XHVCMjk0IFx1QjlBQ1x1RDEzMFx1QjdGNCBcdUJCMzhcdUM3OTBcdUM1RjRcdUM3NzRcdUM1QjRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaW5kaWNhdGVzIHRoZXJlIHdhcyBhIHN5bnRhY3RpYwotICAgICAgICAgKiBlcnJvciBpbiB0aGUgZm9ybSBvZiBhbiBYUGF0aCBleHByZXNzaW9uLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzCi0gICAgICAgICAqIHRoZSBleHByZXNzaW9uLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlhQQVRIX1BBUlNFUl9FUlIsCi0gICAgICAgICJYUGF0aCBcdUQ0NUNcdUQ2MDRcdUMyREQgJyd7MH0nJ1x1Qzc1OCBcdUFENkNcdUJCMzhcdUM3NDQgXHVCRDg0XHVDMTFEXHVENTU4XHVCMjk0IFx1QzkxMSBcdUM2MjRcdUI5NThcdUFDMDAgXHVCQzFDXHVDMEREXHVENTg4XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBbiBlbGVtZW50IGluIHRoZSBzdHlsZXNoZWV0IHJlcXVpcmVzIGEKLSAgICAgICAgICogcGFydGljdWxhciBhdHRyaWJ1dGUgbmFtZWQgYnkgdGhlIHN1YnN0aXR1dGlvbiB0ZXh0LCBidXQgdGhhdAotICAgICAgICAgKiBhdHRyaWJ1dGUgd2FzIG5vdCBzcGVjaWZpZWQgaW4gdGhlIHN0eWxlc2hlZXQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuUkVRVUlSRURfQVRUUl9FUlIsCi0gICAgICAgICJcdUQ1NDRcdUMyMTggXHVDMThEXHVDMTMxICcnezB9JydcdUM3NzQoXHVBQzAwKSBcdUIyMDRcdUI3N0RcdUI0MThcdUM1QzhcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCBhIGNoYXJhY3RlciBub3QKLSAgICAgICAgICogcGVybWl0dGVkIGluIGFuIFhQYXRoIGV4cHJlc3Npb24gd2FzIGVuY291bnRlcmVkLiAgVGhlIHN1YnN0aXR1dGlvbgotICAgICAgICAgKiB0ZXh0IGlzIHRoZSBvZmZlbmRpbmcgY2hhcmFjdGVyLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfQ0hBUl9FUlIsCi0gICAgICAgICJYUGF0aCBcdUQ0NUNcdUQ2MDRcdUMyRERcdUM1RDAgXHVDNzk4XHVCQUJCXHVCNDFDIFx1QkIzOFx1Qzc5MCAnJ3swfScnXHVDNzc0KFx1QUMwMCkgXHVDNzg4XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gaXMgYSBtYXJrLXVwIGl0ZW0gaW4KLSAgICAgICAgICogYW4gWE1MIGRvY3VtZW50IHRoYXQgcmVxdWVzdCBzb21lIGJlaGF2aW91ciBvZiBhbiBYTUwgcHJvY2Vzc29yLiAgVGhlCi0gICAgICAgICAqIGZvcm0gb2YgdGhlIG5hbWUgb2Ygd2FzIGludmFsaWQgaW4gdGhpcyBjYXNlLCBhbmQgdGhlIHN1YnN0aXR1dGlvbgotICAgICAgICAgKiB0ZXh0IGlzIHRoZSBuYW1lLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfUElfRVJSLAotICAgICAgICAiJyd7MH0nJ1x1Qzc0MChcdUIyOTQpIFx1QkE4NVx1QjgzOSBcdUNDOThcdUI5QUNcdUM1RDAgXHVDNzk4XHVCQUJCXHVCNDFDIFx1Qzc3NFx1Qjk4NFx1Qzc4NVx1QjJDOFx1QjJFNC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIHJlcG9ydGVkIGlmIHRoZSBzdHlsZXNoZWV0Ci0gICAgICAgICAqIGJlaW5nIHByb2Nlc3NlZCBhdHRlbXB0ZWQgdG8gY29uc3RydWN0IGFuIFhNTCBkb2N1bWVudCB3aXRoIGFuCi0gICAgICAgICAqIGF0dHJpYnV0ZSBpbiBhIHBsYWNlIG90aGVyIHRoYW4gb24gYW4gZWxlbWVudC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICAgKiBzcGVjaWZpZXMgdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5TVFJBWV9BVFRSSUJVVEVfRVJSLAotICAgICAgICAiJyd7MH0nJyBcdUMxOERcdUMxMzFcdUM3NzQgXHVDNjk0XHVDMThDXHVDNUQwIFx1RDNFQ1x1RDU2OFx1QjQxOFx1QzVCNCBcdUM3ODhcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBbiBhdHRyaWJ1dGUgdGhhdCB3YXNuJ3QgcmVjb2duaXplZCB3YXMKLSAgICAgICAgICogc3BlY2lmaWVkIG9uIGFuIGVsZW1lbnQgaW4gdGhlIHN0eWxlc2hlZXQuICBUaGUgYXR0cmlidXRlIGlzIG5hbWVkCi0gICAgICAgICAqIGJ5IHRoZSBzdWJzdGl0dXRpb24KLSAgICAgICAgICogdGV4dC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTExFR0FMX0FUVFJJQlVURV9FUlIsCi0gICAgICAgICInJ3swfScnXHVDNzQwKFx1QjI5NCkgXHVDNzk4XHVCQUJCXHVCNDFDIFx1QzE4RFx1QzEzMVx1Qzc4NVx1QjJDOFx1QjJFNC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgImltcG9ydCIgYW5kICJpbmNsdWRlIiBhcmUga2V5d29yZHMgdGhhdCBzaG91bGQKLSAgICAgICAgICogbm90IGJlIHRyYW5zbGF0ZWQuICBUaGlzIG1lc3NhZ2VzIGluZGljYXRlcyB0aGF0IHRoZSBzdHlsZXNoZWV0Ci0gICAgICAgICAqIG5hbWVkIGluIHRoZSBzdWJzdGl0dXRpb24gdGV4dCBpbXBvcnRlZCBvciBpbmNsdWRlZCBpdHNlbGYgZWl0aGVyCi0gICAgICAgICAqIGRpcmVjdGx5IG9yIGluZGlyZWN0bHkuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuQ0lSQ1VMQVJfSU5DTFVERV9FUlIsCi0gICAgICAgICJcdUMyMUNcdUQ2NTggaW1wb3J0L2luY2x1ZGVcdUM3ODVcdUIyQzhcdUIyRTQuICcnezB9JycgXHVDMkE0XHVEMEMwXHVDNzdDXHVDMkRDXHVEMkI4XHVBQzAwIFx1Qzc3NFx1QkJGOCBcdUI4NUNcdUI0RENcdUI0MThcdUM1QzhcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEEgcmVzdWx0LXRyZWUgZnJhZ21lbnQgaXMgYSBwb3J0aW9uIG9mIGEKLSAgICAgICAgICogcmVzdWx0aW5nIFhNTCBkb2N1bWVudCByZXByZXNlbnRlZCBhcyBhIHRyZWUuICAiPHhzbDpzb3J0PiIgaXMgYQotICAgICAgICAgKiBrZXl3b3JkIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuUkVTVUxUX1RSRUVfU09SVF9FUlIsCi0gICAgICAgICJSZXN1bHQtdHJlZSBcdUJEODBcdUJEODRcdUM3NDQgXHVDODE1XHVCODJDXHVENTYwIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQoPHhzbDpzb3J0PiBcdUM2OTRcdUMxOENcdUFDMDAgXHVCQjM0XHVDMkRDXHVCNDI4KS4gXHVBQ0IwXHVBQ0ZDIFx1RDJCOFx1QjlBQ1x1Qjk3QyBcdUMwRERcdUMxMzFcdUQ1NjAgXHVCNTRDXHVCMjk0IFx1QjE3OFx1QjREQ1x1Qjk3QyBcdUM4MTVcdUI4MkNcdUQ1NzRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBIG5hbWUgY2FuIGJlIGdpdmVuIHRvIGEgcGFydGljdWxhciBzdHlsZSB0byBiZQotICAgICAgICAgKiB1c2VkIHRvIGZvcm1hdCBkZWNpbWFsIHZhbHVlcy4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBnaXZlcyB0aGUgbmFtZQotICAgICAgICAgKiBvZiBzdWNoIGEgc3R5bGUgZm9yIHdoaWNoIG1vcmUgdGhhbiBvbmUgZGVjbGFyYXRpb24gd2FzIGVuY291bnRlcmVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlNZTUJPTFNfUkVERUZfRVJSLAotICAgICAgICAiXHVDMkVEXHVDOUM0XHVDMjE4IFx1RDYxNVx1QzJERCAnJ3swfScnXHVDNzc0KFx1QUMwMCkgXHVDNzc0XHVCQkY4IFx1QzgxNVx1Qzc1OFx1QjQxOFx1QzVDOFx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN0eWxlc2hlZXQgdmVyc2lvbiBuYW1lZCBpbiB0aGUKLSAgICAgICAgICogc3Vic3RpdHV0aW9uIHRleHQgaXMgbm90IHN1cHBvcnRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5YU0xfVkVSU0lPTl9FUlIsCi0gICAgICAgICJYU0xUQ1x1QjI5NCBYU0wgXHVCQzg0XHVDODA0ICcnezB9JydcdUM3NDQoXHVCOTdDKSBcdUM5QzBcdUM2RDBcdUQ1NThcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZGVmaW5pdGlvbnMgb2Ygb25lIG9yIG1vcmUgdmFyaWFibGVzIG9yCi0gICAgICAgICAqIHBhcmFtZXRlcnMgZGVwZW5kIG9uIG9uZSBhbm90aGVyLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkNJUkNVTEFSX1ZBUklBQkxFX0VSUiwKLSAgICAgICAgIicnezB9JydcdUM1RDAgXHVDMjFDXHVENjU4IFx1QkNDMFx1QzIxOC9cdUI5RTRcdUFDMUNcdUJDQzBcdUMyMTggXHVDQzM4XHVDODcwXHVBQzAwIFx1Qzc4OFx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIG9wZXJhdG9yIGluIGFuIGV4cHJlc2lvbiB3aXRoIHR3byBvcGVyYW5kcyB3YXMKLSAgICAgICAgICogbm90IHJlY29nbml6ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSUxMRUdBTF9CSU5BUllfT1BfRVJSLAotICAgICAgICAiXHVCQzE0XHVDNzc0XHVCMTA4XHVCOUFDIFx1RDQ1Q1x1RDYwNFx1QzJERFx1QzVEMCBcdUIzMDBcdUQ1NzQgXHVDNTRDIFx1QzIxOCBcdUM1QzZcdUIyOTQgXHVDNUYwXHVDMEIwXHVDNzkwXHVDNzg1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgcHJvZHVjZWQgaWYgYSByZWZlcmVuY2UgdG8gYQotICAgICAgICAgKiBmdW5jdGlvbiBoYXMgdG9vIG1hbnkgb3IgdG9vIGZldyBhcmd1bWVudHMuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSUxMRUdBTF9BUkdfRVJSLAotICAgICAgICAiXHVENTY4XHVDMjE4IFx1RDYzOFx1Q0Q5Q1x1QzVEMCBcdUIzMDBcdUQ1NUMgXHVDNzc4XHVDMjE4XHVBQzAwIFx1Qzc5OFx1QkFCQlx1QjQxOFx1QzVDOFx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgImRvY3VtZW50KCkiIGlzIHRoZSBuYW1lIG9mIGZ1bmN0aW9uIGFuZCBtdXN0Ci0gICAgICAgICAqIG5vdCBiZSB0cmFuc2xhdGVkLiAgQSBub2RlLXNldCBpcyBhIHNldCBvZiB0aGUgbm9kZXMgaW4gdGhlIHRyZWUKLSAgICAgICAgICogcmVwcmVzZW50YXRpb24gb2YgYW4gWE1MIGRvY3VtZW50LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkRPQ1VNRU5UX0FSR19FUlIsCi0gICAgICAgICJkb2N1bWVudCgpIFx1RDU2OFx1QzIxOFx1QzVEMCBcdUIzMDBcdUQ1NUMgXHVCNDUwXHVCQzg4XHVDOUY4IFx1Qzc3OFx1QzIxOFx1QjI5NCBub2RlLXNldFx1QzVFQ1x1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICI8eHNsOndoZW4+IiBhbmQgIjx4c2w6Y2hvb3NlPiIgYXJlIGtleXdvcmRzCi0gICAgICAgICAqIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGlzIG1lc3NhZ2UgZGVzY3JpYmVzIGEgc3ludGF4IGVycm9yCi0gICAgICAgICAqIGluIHRoZSBzdHlsZXNoZWV0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk1JU1NJTkdfV0hFTl9FUlIsCi0gICAgICAgICI8eHNsOmNob29zZT5cdUM1RDBcdUIyOTQgPHhzbDp3aGVuPiBcdUM2OTRcdUMxOENcdUFDMDAgXHVENTU4XHVCMDk4IFx1Qzc3NFx1QzBDMSBcdUQ1NDRcdUM2OTRcdUQ1NjlcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICI8eHNsOm90aGVyd2lzZT4iIGFuZCAiPHhzbDpjaG9vc2U+IiBhcmUKLSAgICAgICAgICoga2V5d29yZHMgYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoaXMgbWVzc2FnZSBkZXNjcmliZXMgYQotICAgICAgICAgKiBzeW50YXggZXJyb3IgaW4gdGhlIHN0eWxlc2hlZXQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTVVMVElQTEVfT1RIRVJXSVNFX0VSUiwKLSAgICAgICAgIjx4c2w6Y2hvb3NlPlx1QzVEMFx1QzExQ1x1QjI5NCA8eHNsOm90aGVyd2lzZT4gXHVDNjk0XHVDMThDXHVBQzAwIFx1RDU1OFx1QjA5OFx1QjlDQyBcdUQ1QzhcdUM2QTlcdUI0MjlcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICI8eHNsOm90aGVyd2lzZT4iIGFuZCAiPHhzbDpjaG9vc2U+IiBhcmUKLSAgICAgICAgICoga2V5d29yZHMgYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoaXMgbWVzc2FnZSBkZXNjcmliZXMgYQotICAgICAgICAgKiBzeW50YXggZXJyb3IgaW4gdGhlIHN0eWxlc2hlZXQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuU1RSQVlfT1RIRVJXSVNFX0VSUiwKLSAgICAgICAgIjx4c2w6b3RoZXJ3aXNlPlx1QjI5NCA8eHNsOmNob29zZT5cdUM1RDBcdUMxMUNcdUI5Q0MgXHVDMEFDXHVDNkE5XHVENTYwIFx1QzIxOCBcdUM3ODhcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICI8eHNsOndoZW4+IiBhbmQgIjx4c2w6Y2hvb3NlPiIgYXJlIGtleXdvcmRzCi0gICAgICAgICAqIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGlzIG1lc3NhZ2UgZGVzY3JpYmVzIGEgc3ludGF4IGVycm9yCi0gICAgICAgICAqIGluIHRoZSBzdHlsZXNoZWV0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlNUUkFZX1dIRU5fRVJSLAotICAgICAgICAiPHhzbDp3aGVuPlx1Qzc0MCA8eHNsOmNob29zZT5cdUM1RDBcdUMxMUNcdUI5Q0MgXHVDMEFDXHVDNkE5XHVENTYwIFx1QzIxOCBcdUM3ODhcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICI8eHNsOndoZW4+IiwgIjx4c2w6b3RoZXJ3aXNlPiIgYW5kCi0gICAgICAgICAqICI8eHNsOmNob29zZT4iIGFyZSBrZXl3b3JkcyBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhpcwotICAgICAgICAgKiBtZXNzYWdlIGRlc2NyaWJlcyBhIHN5bnRheCBlcnJvciBpbiB0aGUgc3R5bGVzaGVldC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5XSEVOX0VMRU1FTlRfRVJSLAotICAgICAgICAiPHhzbDpjaG9vc2U+XHVDNUQwXHVDMTFDXHVCMjk0IDx4c2w6d2hlbj4gXHVCQzBGIDx4c2w6b3RoZXJ3aXNlPiBcdUM2OTRcdUMxOENcdUI5Q0MgXHVENUM4XHVDNkE5XHVCNDI5XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiPHhzbDphdHRyaWJ1dGUtc2V0PiIgYW5kICJuYW1lIiBhcmUga2V5d29yZHMKLSAgICAgICAgICogdGhhdCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVU5OQU1FRF9BVFRSSUJTRVRfRVJSLAotICAgICAgICAiPHhzbDphdHRyaWJ1dGUtc2V0Plx1QzVEMCAnbmFtZScgXHVDMThEXHVDMTMxXHVDNzc0IFx1QjIwNFx1Qjc3RFx1QjQxOFx1QzVDOFx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQW4gZWxlbWVudCBpbiB0aGUgc3R5bGVzaGVldCBjb250YWluZWQgYW4KLSAgICAgICAgICogZWxlbWVudCBvZiBhIHR5cGUgdGhhdCBpdCB3YXMgbm90IHBlcm1pdHRlZCB0byBjb250YWluLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfQ0hJTERfRVJSLAotICAgICAgICAiXHVENTU4XHVDNzA0IFx1QzY5NFx1QzE4Q1x1QUMwMCBcdUM3OThcdUJBQkJcdUI0MThcdUM1QzhcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IHRyaWVkIHRvIGNyZWF0ZSBhbiBlbGVtZW50IHdpdGgKLSAgICAgICAgICogYSBuYW1lIHRoYXQgd2FzIG5vdCBhIHZhbGlkIFhNTCBuYW1lLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGNvbnRhaW5zCi0gICAgICAgICAqIHRoZSBuYW1lLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfRUxFTV9OQU1FX0VSUiwKLSAgICAgICAgIicnezB9JycgXHVDNjk0XHVDMThDXHVCOTdDIFx1RDYzOFx1Q0Q5Q1x1RDU2MCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3R5bGVzaGVldCB0cmllZCB0byBjcmVhdGUgYW4gYXR0cmlidXRlCi0gICAgICAgICAqIHdpdGggYSBuYW1lIHRoYXQgd2FzIG5vdCBhIHZhbGlkIFhNTCBuYW1lLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgICAqIGNvbnRhaW5zIHRoZSBuYW1lLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfQVRUUl9OQU1FX0VSUiwKLSAgICAgICAgIicnezB9JycgXHVDMThEXHVDMTMxXHVDNzQ0IFx1RDYzOFx1Q0Q5Q1x1RDU2MCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgY2hpbGRyZW4gb2YgdGhlIG91dGVybW9zdCBlbGVtZW50IG9mIGEKLSAgICAgICAgICogc3R5bGVzaGVldCBhcmUgcmVmZXJyZWQgdG8gYXMgdG9wLWxldmVsIGVsZW1lbnRzLiAgTm8gdGV4dCBzaG91bGQKLSAgICAgICAgICogb2NjdXIgd2l0aGluIHRoYXQgb3V0ZXJtb3N0IGVsZW1lbnQgdW5sZXNzIGl0IGlzIHdpdGhpbiBhIHRvcC1sZXZlbAotICAgICAgICAgKiBlbGVtZW50LiAgVGhpcyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoYXQgY29uc3RyYWludCB3YXMgdmlvbGF0ZWQuCi0gICAgICAgICAqICI8eHNsOnN0eWxlc2hlZXQ+IiBpcyBhIGtleXdvcmQgdGhhdCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSUxMRUdBTF9URVhUX05PREVfRVJSLAotICAgICAgICAiXHVEMTREXHVDMkE0XHVEMkI4IFx1QjM3MFx1Qzc3NFx1RDEzMFx1QUMwMCBcdUNENUNcdUMwQzFcdUM3MDQgXHVCODA4XHVCQ0E4IDx4c2w6c3R5bGVzaGVldD4gXHVDNjk0XHVDMThDXHVDNUQwIFx1RDNFQ1x1RDU2OFx1QjQxOFx1QzVCNCBcdUM3ODhcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBKQVhQIGlzIGFuIGFjcm9ueW0gZm9yIHRoZSBKYXZhIEFQSSBmb3IgWE1MCi0gICAgICAgICAqIFByb2Nlc3NpbmcuICBUaGlzIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhlIFhNTCBwYXJzZXIgcHJvdmlkZWQgdG8KLSAgICAgICAgICogWFNMVEMgdG8gcHJvY2VzcyB0aGUgWE1MIGlucHV0IGRvY3VtZW50IGhhZCBhIGNvbmZpZ3VyYXRpb24gcHJvYmxlbS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5TQVhfUEFSU0VSX0NPTkZJR19FUlIsCi0gICAgICAgICJKQVhQIFx1QUQ2Q1x1QkIzOCBcdUJEODRcdUMxMURcdUFFMzBcdUFDMDAgXHVDODFDXHVCMzAwXHVCODVDIFx1QUQ2Q1x1QzEzMVx1QjQxOFx1QzlDMCBcdUM1NEFcdUM1NThcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBuYW1lcyB0aGUgaW50ZXJuYWwgZXJyb3IKLSAgICAgICAgICogZW5jb3VudGVyZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSU5URVJOQUxfRVJSLAotICAgICAgICAiXHVCQ0Y1XHVBRDZDXHVENTYwIFx1QzIxOCBcdUM1QzZcdUIyOTQgWFNMVEMgXHVCMEI0XHVCRDgwIFx1QzYyNFx1Qjk1ODogJyd7MH0nJyJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3R5bGVzaGVldCBjb250YWluZWQgYW4gZWxlbWVudCB0aGF0IHdhcwotICAgICAgICAgKiBub3QgcmVjb2duaXplZCBhcyBwYXJ0IG9mIHRoZSBYU0wgc3ludGF4LiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgICAqIGdpdmVzIHRoZSBlbGVtZW50IG5hbWUuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVU5TVVBQT1JURURfWFNMX0VSUiwKLSAgICAgICAgIicnezB9JydcdUM3NDAoXHVCMjk0KSBcdUM5QzBcdUM2RDBcdUI0MThcdUM5QzAgXHVDNTRBXHVCMjk0IFhTTCBcdUM2OTRcdUMxOENcdUM3ODVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IHJlZmVycmVkIHRvIGFuIGV4dGVuc2lvbiB0byB0aGUKLSAgICAgICAgICogWFNMIHN5bnRheCBhbmQgaW5kaWNhdGVkIHRoYXQgaXQgd2FzIGRlZmluZWQgYnkgWFNMVEMsIGJ1dCBYU1RMQyBkb2VzCi0gICAgICAgICAqIG5vdCByZWNvZ25pemVkIHRoZSBwYXJ0aWN1bGFyIGV4dGVuc2lvbiBuYW1lZC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICAgKiBnaXZlcyB0aGUgZXh0ZW5zaW9uIG5hbWUuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVU5TVVBQT1JURURfRVhUX0VSUiwKLSAgICAgICAgIicnezB9JydcdUM3NDAoXHVCMjk0KSBcdUM1NEMgXHVDMjE4IFx1QzVDNlx1QjI5NCBYU0xUQyBcdUQ2NTVcdUM3QTVcdUM3ODVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBYTUwgZG9jdW1lbnQgZ2l2ZW4gdG8gWFNMVEMgYXMgYSBzdHlsZXNoZWV0Ci0gICAgICAgICAqIHdhcyBub3QsIGluIGZhY3QsIGEgc3R5bGVzaGVldC4gIFhTTFRDIGlzIGFibGUgdG8gZGV0ZWN0IHRoYXQgaW4gdGhpcwotICAgICAgICAgKiBjYXNlIGJlY2F1c2UgdGhlIG91dGVybW9zdCBlbGVtZW50IGluIHRoZSBzdHlsZXNoZWV0IGhhcyB0byBiZQotICAgICAgICAgKiBkZWNsYXJlZCB3aXRoIHJlc3BlY3QgdG8gdGhlIFhTTCBuYW1lc3BhY2UgVVJJLCBidXQgbm8gZGVjbGFyYXRpb24KLSAgICAgICAgICogZm9yIHRoYXQgbmFtZXNwYWNlIHdhcyBzZWVuLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk1JU1NJTkdfWFNMVF9VUklfRVJSLAotICAgICAgICAiXHVDNzg1XHVCODI1IFx1QkIzOFx1QzExQ1x1QjI5NCBcdUMyQTRcdUQwQzBcdUM3N0NcdUMyRENcdUQyQjhcdUFDMDAgXHVDNTQ0XHVCMkQ5XHVCMkM4XHVCMkU0LiBYU0wgXHVCMTI0XHVDNzg0XHVDMkE0XHVEMzk4XHVDNzc0XHVDMkE0XHVBQzAwIFx1QjhFOFx1RDJCOCBcdUM2OTRcdUMxOENcdUM1RDAgXHVDMTIwXHVDNUI4XHVCNDE4XHVDOUMwIFx1QzU0QVx1QzU1OFx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgWFNMVEMgY291bGQgbm90IGZpbmQgdGhlIHN0eWxlc2hlZXQgZG9jdW1lbnQKLSAgICAgICAgICogd2l0aCB0aGUgbmFtZSBzcGVjaWZpZWQgYnkgdGhlIHN1YnN0aXR1dGlvbiB0ZXh0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk1JU1NJTkdfWFNMVF9UQVJHRVRfRVJSLAotICAgICAgICAiXHVDMkE0XHVEMEMwXHVDNzdDXHVDMkRDXHVEMkI4IFx1QjMwMFx1QzBDMSAnJ3swfScnXHVDNzQ0KFx1Qjk3QykgXHVDQzNFXHVDNzQ0IFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIGFjY2VzcyB0byB0aGUgc3R5bGVzaGVldCB0YXJnZXQgaXMgZGVuaWVkCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuQUNDRVNTSU5HX1hTTFRfVEFSR0VUX0VSUiwKLSAgICAgICAgImFjY2Vzc0V4dGVybmFsU3R5bGVzaGVldCBcdUMxOERcdUMxMzFcdUM3M0NcdUI4NUMgXHVDMTI0XHVDODE1XHVCNDFDIFx1QzgxQ1x1RDU1Q1x1QzczQ1x1Qjg1QyBcdUM3NzhcdUQ1NzQgJyd7MX0nJyBcdUM1NjFcdUMxMzhcdUMyQTRcdUFDMDAgXHVENUM4XHVDNkE5XHVCNDE4XHVDOUMwIFx1QzU0QVx1QzczQ1x1QkJDMFx1Qjg1QyBcdUMyQTRcdUQwQzBcdUM3N0NcdUMyRENcdUQyQjggXHVCMzAwXHVDMEMxICcnezB9JydcdUM3NDQoXHVCOTdDKSBcdUM3N0RcdUM3NDQgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIHJlcHJlc2VudHMgYW4gaW50ZXJuYWwgZXJyb3IgaW4KLSAgICAgICAgICogY29uZGl0aW9uIGluIFhTTFRDLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBjbGFzcyBuYW1lIGluIFhTTFRDCi0gICAgICAgICAqIHRoYXQgaXMgbWlzc2luZyBzb21lIGZ1bmN0aW9uYWxpdHkuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTk9UX0lNUExFTUVOVEVEX0VSUiwKLSAgICAgICAgIlx1QUQ2Q1x1RDYwNFx1QjQxOFx1QzlDMCBcdUM1NEFcdUM3NEM6ICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBYTUwgZG9jdW1lbnQgZ2l2ZW4gdG8gWFNMVEMgYXMgYSBzdHlsZXNoZWV0Ci0gICAgICAgICAqIHdhcyBub3QsIGluIGZhY3QsIGEgc3R5bGVzaGVldC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5OT1RfU1RZTEVTSEVFVF9FUlIsCi0gICAgICAgICJcdUM3ODVcdUI4MjUgXHVCQjM4XHVDMTFDXHVDNUQwIFhTTCBcdUMyQTRcdUQwQzBcdUM3N0NcdUMyRENcdUQyQjhcdUFDMDAgXHVEM0VDXHVENTY4XHVCNDE4XHVDNUI0IFx1Qzc4OFx1QzlDMCBcdUM1NEFcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBlbGVtZW50IG5hbWVkIGluIHRoZSBzdWJzdGl0dXRpb24gdGV4dCB3YXMKLSAgICAgICAgICogZW5jb3VudGVyZWQgaW4gdGhlIHN0eWxlc2hlZXQgYnV0IGlzIG5vdCByZWNvZ25pemVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkVMRU1FTlRfUEFSU0VfRVJSLAotICAgICAgICAiJyd7MH0nJyBcdUM2OTRcdUMxOENcdUM3NTggXHVBRDZDXHVCQjM4XHVDNzQ0IFx1QkQ4NFx1QzExRFx1RDU2MCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAidXNlIiwgIjxrZXk+IiwgIm5vZGUiLCAibm9kZS1zZXQiLCAic3RyaW5nIgotICAgICAgICAgKiBhbmQgIm51bWJlciIgYXJlIGtleXdvcmRzIGluIHRoaXMgY29udGV4dCBhbmQgc2hvdWxkIG5vdCBiZQotICAgICAgICAgKiB0cmFuc2xhdGVkLiAgVGhpcyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoZSB2YWx1ZSBvZiB0aGUgInVzZSIKLSAgICAgICAgICogYXR0cmlidXRlIHdhcyBub3Qgb25lIG9mIHRoZSBwZXJtaXR0ZWQgdmFsdWVzLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLktFWV9VU0VfQVRUUl9FUlIsCi0gICAgICAgICI8a2V5Plx1Qzc1OCB1c2UgXHVDMThEXHVDMTMxXHVDNzQwIG5vZGUsIG5vZGUtc2V0LCBzdHJpbmcgXHVCNjEwXHVCMjk0IG51bWJlclx1QzVFQ1x1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIFhNTCBkb2N1bWVudCBjYW4gc3BlY2lmeSB0aGUgdmVyc2lvbiBvZiB0aGUKLSAgICAgICAgICogWE1MIHNwZWNpZmljYXRpb24gdG8gd2hpY2ggaXQgYWRoZXJlcy4gIFRoaXMgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdAotICAgICAgICAgKiB0aGUgdmVyc2lvbiBzcGVjaWZpZWQgZm9yIHRoZSBvdXRwdXQgZG9jdW1lbnQgd2FzIG5vdCB2YWxpZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5PVVRQVVRfVkVSU0lPTl9FUlIsCi0gICAgICAgICJcdUNEOUNcdUI4MjUgWE1MIFx1QkIzOFx1QzExQyBcdUJDODRcdUM4MDRcdUM3NDAgMS4wXHVDNzc0XHVDNUI0XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIG9wZXJhdG9yIGluIGEgY29tcGFyaXNvbiBvcGVyYXRpb24gd2FzCi0gICAgICAgICAqIG5vdCByZWNvZ25pemVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfUkVMQVRfT1BfRVJSLAotICAgICAgICAiXHVBRDAwXHVBQ0M0IFx1RDQ1Q1x1RDYwNFx1QzJERFx1QzVEMCBcdUIzMDBcdUQ1NzQgXHVDNTRDIFx1QzIxOCBcdUM1QzZcdUIyOTQgXHVDNUYwXHVDMEIwXHVDNzkwXHVDNzg1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBbiBhdHRyaWJ1dGUgc2V0IGRlZmluZXMgYXMgYSBzZXQgb2YgWE1MCi0gICAgICAgICAqIGF0dHJpYnV0ZXMgdGhhdCBjYW4gYmUgYWRkZWQgdG8gYW4gZWxlbWVudCBpbiB0aGUgb3V0cHV0IFhNTCBkb2N1bWVudAotICAgICAgICAgKiBhcyBhIGdyb3VwLiAgVGhpcyBtZXNzYWdlIGlzIHJlcG9ydGVkIGlmIHRoZSBuYW1lIHNwZWNpZmllZCB3YXMgbm90Ci0gICAgICAgICAqIHVzZWQgdG8gZGVjbGFyZSBhbiBhdHRyaWJ1dGUgc2V0LiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lCi0gICAgICAgICAqIHRoYXQgaXMgaW4gZXJyb3IuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuQVRUUklCU0VUX1VOREVGX0VSUiwKLSAgICAgICAgIlx1Qzg3NFx1QzdBQ1x1RDU1OFx1QzlDMCBcdUM1NEFcdUIyOTQgXHVDMThEXHVDMTMxIFx1QzlEMVx1RDU2OSAnJ3swfScnXHVDNzQ0KFx1Qjk3QykgXHVDMEFDXHVDNkE5XHVENTU4XHVCODI0XHVBQ0UwIFx1QzJEQ1x1QjNDNFx1RDU1OFx1QjI5NCBcdUM5MTFcdUM3ODVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSB0ZXJtICJhdHRyaWJ1dGUgdmFsdWUgdGVtcGxhdGUiIGlzIGEgdGVybQotICAgICAgICAgKiBkZWZpbmVkIGJ5IFhTTFQgd2hpY2ggZGVzY3JpYmVzIHRoZSB2YWx1ZSBvZiBhbiBhdHRyaWJ1dGUgdGhhdCBpcwotICAgICAgICAgKiBkZXRlcm1pbmVkIGJ5IGFuIFhQYXRoIGV4cHJlc3Npb24uICBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUKLSAgICAgICAgICogZXhwcmVzc2lvbiB3YXMgc3ludGFjdGljYWxseSBpbmNvcnJlY3Q7IHRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICAgKiBjb250YWlucyB0aGUgZXhwcmVzc2lvbiB0aGF0IHdhcyBpbiBlcnJvci4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5BVFRSX1ZBTF9URU1QTEFURV9FUlIsCi0gICAgICAgICJcdUMxOERcdUMxMzFcdUFDMTIgXHVEMTVDXHVENTBDXHVCOUFDXHVEMkI4ICcnezB9JydcdUM3NTggXHVBRDZDXHVCQjM4XHVDNzQ0IFx1QkQ4NFx1QzExRFx1RDU2MCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICA/Pz8KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5VTktOT1dOX1NJR19UWVBFX0VSUiwKLSAgICAgICAgIicnezB9JycgXHVEMDc0XHVCNzk4XHVDMkE0XHVDNUQwIFx1QjMwMFx1RDU1QyBcdUMxMUNcdUJBODVcdUM1RDAgXHVDNTRDIFx1QzIxOCBcdUM1QzZcdUIyOTQgXHVCMzcwXHVDNzc0XHVEMTMwIFx1QzcyMFx1RDYxNVx1Qzc3NCBcdUM3ODhcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCByZWZlcnMgdG8gZGF0YSB0eXBlcy4KLSAgICAgICAgICogVGhlIG1lc3NhZ2UgaXMgZGlzcGxheWVkIGlmIGEgdmFsdWUgaW4gYSBwYXJ0aWN1bGFyIGNvbnRleHQgbmVlZHMgdG8KLSAgICAgICAgICogYmUgY29udmVydGVkIHRvIHR5cGUgezF9LCBidXQgdGhhdCdzIG5vdCBwb3NzaWJsZSBmb3IgYSB2YWx1ZSBvZgotICAgICAgICAgKiB0eXBlIHswfS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5EQVRBX0NPTlZFUlNJT05fRVJSLAotICAgICAgICAiXHVCMzcwXHVDNzc0XHVEMTMwIFx1QzcyMFx1RDYxNSAnJ3swfScnXHVDNzQ0KFx1Qjk3QykgJyd7MX0nJyhcdUM3M0MpXHVCODVDIFx1QkNDMFx1RDY1OFx1RDU2MCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiVGVtcGxhdGVzIiBpcyBhIEphdmEgY2xhc3MgbmFtZSB0aGF0IHNob3VsZAotICAgICAgICAgKiBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5OT19UUkFOU0xFVF9DTEFTU19FUlIsCi0gICAgICAgICJcdUM3NzQgVGVtcGxhdGVzXHVDNUQwXHVCMjk0IFx1QzgwMVx1RDU2OVx1RDU1QyB0cmFuc2xldCBcdUQwNzRcdUI3OThcdUMyQTQgXHVDODE1XHVDNzU4XHVBQzAwIFx1RDNFQ1x1RDU2OFx1QjQxOFx1QzVCNCBcdUM3ODhcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiVGVtcGxhdGVzIiBpcyBhIEphdmEgY2xhc3MgbmFtZSB0aGF0IHNob3VsZAotICAgICAgICAgKiBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5OT19NQUlOX1RSQU5TTEVUX0VSUiwKLSAgICAgICAgIlx1Qzc3NCBUZW1wbGF0ZXNcdUM1RDBcdUIyOTQgXHVDNzc0XHVCOTg0XHVDNzc0ICcnezB9JydcdUM3NzggXHVEMDc0XHVCNzk4XHVDMkE0XHVBQzAwIFx1RDNFQ1x1RDU2OFx1QjQxOFx1QzVCNCBcdUM3ODhcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYSBjbGFzcy4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5UUkFOU0xFVF9DTEFTU19FUlIsCi0gICAgICAgICJUcmFuc2xldCBcdUQwNzRcdUI3OThcdUMyQTQgJyd7MH0nJ1x1Qzc0NChcdUI5N0MpIFx1Qjg1Q1x1QjREQ1x1RDU2MCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgICAgIHtFcnJvck1zZy5UUkFOU0xFVF9PQkpFQ1RfRVJSLAotICAgICAgICAiVHJhbnNsZXQgXHVEMDc0XHVCNzk4XHVDMkE0XHVBQzAwIFx1Qjg1Q1x1QjREQ1x1QjQxOFx1QzVDOFx1QzlDMFx1QjlDQyB0cmFuc2xldCBcdUM3NzhcdUMyQTRcdUQxMzRcdUMyQTRcdUI5N0MgXHVDMEREXHVDMTMxXHVENTYwIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJFcnJvckxpc3RlbmVyIiBpcyBhIEphdmEgaW50ZXJmYWNlIG5hbWUgdGhhdAotICAgICAgICAgKiBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUgdXNlciB0cmllZAotICAgICAgICAgKiB0byBzZXQgYW4gRXJyb3JMaXN0ZW5lciBvYmplY3Qgb24gb2JqZWN0IG9mIHRoZSBjbGFzcyBuYW1lZCBpbiB0aGUKLSAgICAgICAgICogc3Vic3RpdHV0aW9uIHRleHQgd2l0aCAibnVsbCIgSmF2YSB2YWx1ZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5FUlJPUl9MSVNURU5FUl9OVUxMX0VSUiwKLSAgICAgICAgIicnezB9JydcdUM1RDAgXHVCMzAwXHVENTVDIEVycm9yTGlzdGVuZXJcdUI5N0MgbnVsbFx1Qjg1QyBcdUMxMjRcdUM4MTVcdUQ1NThcdUI4MjRcdUFDRTAgXHVDMkRDXHVCM0M0XHVENTU4XHVCMjk0IFx1QzkxMSJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBTdHJlYW1Tb3VyY2UsIFNBWFNvdXJjZSBhbmQgRE9NU291cmNlIGFyZSBKYXZhCi0gICAgICAgICAqIGludGVyZmFjZSBuYW1lcyB0aGF0IHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX1VOS05PV05fU09VUkNFX0VSUiwKLSAgICAgICAgIlhTTFRDXHVCMjk0IFN0cmVhbVNvdXJjZSwgU0FYU291cmNlIFx1QkMwRiBET01Tb3VyY2VcdUI5Q0MgXHVDOUMwXHVDNkQwXHVENTY5XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiU291cmNlIiBpcyBhIEphdmEgY2xhc3MgbmFtZSB0aGF0IHNob3VsZCBub3QKLSAgICAgICAgICogYmUgdHJhbnNsYXRlZC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBKYXZhIG1ldGhvZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX05PX1NPVVJDRV9FUlIsCi0gICAgICAgICInJ3swfScnKFx1QzczQylcdUI4NUMgXHVDODA0XHVCMkVDXHVCNDFDIFNvdXJjZSBcdUFDMURcdUNDQjRcdUM1RDAgXHVDRjU4XHVEMTUwXHVDRTIwXHVBQzAwIFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgWFNMVEMgZmFpbGVkIHRvCi0gICAgICAgICAqIGNvbXBpbGUgdGhlIHN0eWxlc2hlZXQgaW50byBhIHRyYW5zbGV0IChjbGFzcyBmaWxlKS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX0NPTVBJTEVfRVJSLAotICAgICAgICAiXHVDMkE0XHVEMEMwXHVDNzdDXHVDMkRDXHVEMkI4XHVCOTdDIFx1Q0VGNFx1RDMwQ1x1Qzc3Q1x1RDU2MCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiVHJhbnNmb3JtZXJGYWN0b3J5IiBpcyBhIGNsYXNzIG5hbWUuICBJbiB0aGlzCi0gICAgICAgICAqIGNvbnRleHQsIGFuIGF0dHJpYnV0ZSBpcyBhIHByb3BlcnR5IG9yIHNldHRpbmcgb2YgdGhlCi0gICAgICAgICAqIFRyYW5zZm9ybWVyRmFjdG9yeSBvYmplY3QuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgdGhlCi0gICAgICAgICAqIHVucmVjb2duaXNlZCBhdHRyaWJ1dGUuICBUaGUgbWV0aG9kIHVzZWQgdG8gcmV0cmlldmUgdGhlIGF0dHJpYnV0ZSBpcwotICAgICAgICAgKiAiZ2V0QXR0cmlidXRlIiwgc28gaXQncyBub3QgY2xlYXIgd2hldGhlciBpdCB3b3VsZCBiZSBiZXN0IHRvCi0gICAgICAgICAqIHRyYW5zbGF0ZSB0aGUgdGVybSAiYXR0cmlidXRlIi4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX0lOVkFMSURfQVRUUl9FUlIsCi0gICAgICAgICJUcmFuc2Zvcm1lckZhY3RvcnlcdUM1RDBcdUMxMUMgJyd7MH0nJyBcdUMxOERcdUMxMzFcdUM3NDQgXHVDNzc4XHVDMkREXHVENTU4XHVDOUMwIFx1QkFCQlx1RDU4OFx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAgICAgICB7RXJyb3JNc2cuSkFYUF9JTlZBTElEX0FUVFJfVkFMVUVfRVJSLAotICAgICAgICAiJyd7MH0nJyBcdUMxOERcdUMxMzFcdUM1RDAgXHVCMzAwXHVENTc0IFx1QzYyQ1x1QkMxNFx1Qjk3NFx1QzlDMCBcdUM1NEFcdUM3NDAgXHVBQzEyXHVDNzc0IFx1QzlDMFx1QzgxNVx1QjQxOFx1QzVDOFx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgInNldFJlc3VsdCgpIiBhbmQgInN0YXJ0RG9jdW1lbnQoKSIgYXJlIEphdmEKLSAgICAgICAgICogbWV0aG9kIG5hbWVzIHRoYXQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfU0VUX1JFU1VMVF9FUlIsCi0gICAgICAgICJzZXRSZXN1bHQoKVx1QjI5NCBzdGFydERvY3VtZW50KCkgXHVDNTVFXHVDNUQwIFx1RDYzOFx1Q0Q5Q1x1QjQxOFx1QzVCNFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJUcmFuc2Zvcm1lciIgaXMgYSBKYXZhIGludGVyZmFjZSBuYW1lIHRoYXQKLSAgICAgICAgICogc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgQSBUcmFuc2Zvcm1lciBvYmplY3Qgc2hvdWxkIGNvbnRhaW5lZCBhCi0gICAgICAgICAqIHJlZmVyZW5jZSB0byBhIHRyYW5zbGV0IG9iamVjdCBpbiBvcmRlciB0byBiZSB1c2VkIGZvcgotICAgICAgICAgKiB0cmFuc2Zvcm1hdGlvbnM7IHRoaXMgbWVzc2FnZSBpcyBwcm9kdWNlZCBpZiB0aGF0IHJlcXVpcmVtZW50IGlzIG5vdAotICAgICAgICAgKiBtZXQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSkFYUF9OT19UUkFOU0xFVF9FUlIsCi0gICAgICAgICJUcmFuc2Zvcm1lclx1QzVEMCBcdUNFQTFcdUMyOTBcdUQ2NTRcdUI0MUMgdHJhbnNsZXQgXHVBQzFEXHVDQ0I0XHVBQzAwIFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIFhNTCBkb2N1bWVudCB0aGF0IHJlc3VsdHMgZnJvbSBhCi0gICAgICAgICAqIHRyYW5zZm9ybWF0aW9uIG5lZWRzIHRvIGJlIHNlbnQgdG8gYW4gb3V0cHV0IGhhbmRsZXIgb2JqZWN0OyB0aGlzCi0gICAgICAgICAqIG1lc3NhZ2UgaXMgcHJvZHVjZWQgaWYgdGhhdCByZXF1aXJlbWVudCBpcyBub3QgbWV0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfTk9fSEFORExFUl9FUlIsCi0gICAgICAgICJcdUJDQzBcdUQ2NTggXHVBQ0IwXHVBQ0ZDXHVDNUQwIFx1QjMwMFx1RDU3NCBcdUM4MTVcdUM3NThcdUI0MUMgXHVDRDlDXHVCODI1IFx1Q0M5OFx1QjlBQ1x1QUUzMFx1QUMwMCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJSZXN1bHQiIGlzIGEgSmF2YSBpbnRlcmZhY2UgbmFtZSBpbiB0aGlzCi0gICAgICAgICAqIGNvbnRleHQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgYSBtZXRob2QgbmFtZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX05PX1JFU1VMVF9FUlIsCi0gICAgICAgICInJ3swfScnKFx1QzczQylcdUI4NUMgXHVDODA0XHVCMkVDXHVCNDFDIFJlc3VsdCBcdUFDMURcdUNDQjRcdUFDMDAgXHVCRDgwXHVDODAxXHVENTY5XHVENTY5XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiVHJhbnNmb3JtZXIiIGlzIGEgSmF2YSBpbnRlcmZhY2UgbmFtZS4gIFRoZQotICAgICAgICAgKiB1c2VyJ3MgcHJvZ3JhbSBhdHRlbXB0ZWQgdG8gYWNjZXNzIGFuIHVucmVjb2duaXplZCBwcm9wZXJ0eSB3aXRoIHRoZQotICAgICAgICAgKiBuYW1lIHNwZWNpZmllZCBpbiB0aGUgc3Vic3RpdHV0aW9uIHRleHQuICBUaGUgbWV0aG9kIHVzZWQgdG8gcmV0cmlldmUKLSAgICAgICAgICogdGhlIHByb3BlcnR5IGlzICJnZXRPdXRwdXRQcm9wZXJ0eSIsIHNvIGl0J3Mgbm90IGNsZWFyIHdoZXRoZXIgaXQKLSAgICAgICAgICogd291bGQgYmUgYmVzdCB0byB0cmFuc2xhdGUgdGhlIHRlcm0gInByb3BlcnR5Ii4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX1VOS05PV05fUFJPUF9FUlIsCi0gICAgICAgICJcdUJEODBcdUM4MDFcdUQ1NjlcdUQ1NUMgVHJhbnNmb3JtZXIgXHVDMThEXHVDMTMxICcnezB9JydcdUM1RDAgXHVDNTYxXHVDMTM4XHVDMkE0XHVENTU4XHVCODI0XHVBQ0UwIFx1QzJEQ1x1QjNDNFx1RDU1OFx1QjI5NCBcdUM5MTFcdUM3ODVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFNBWDJET00gaXMgdGhlIG5hbWUgb2YgYSBKYXZhIGNsYXNzIHRoYXQgc2hvdWxkCi0gICAgICAgICAqIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhpcyBpcyBhbiBhZGFwdGVyIGluIHRoZSBzZW5zZSB0aGF0IGl0IHRha2VzIGEKLSAgICAgICAgICogRE9NIG9iamVjdCBhbmQgY29udmVydHMgaXQgdG8gc29tZXRoaW5nIHRoYXQgdXNlcyB0aGUgU0FYIEFQSS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5TQVgyRE9NX0FEQVBURVJfRVJSLAotICAgICAgICAiU0FYMkRPTSBcdUM1QjRcdUIzMTFcdUQxMzBcdUI5N0MgXHVDMEREXHVDMTMxXHVENTYwIFx1QzIxOCBcdUM1QzZcdUM3NEM6ICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJYU0xUQ1NvdXJjZS5idWlsZCgpIiBpcyBhIEphdmEgbWV0aG9kIG5hbWUuCi0gICAgICAgICAqICJzeXN0ZW1JZCIgaXMgYW4gWE1MIHRlcm0gdGhhdCBpcyBzaG9ydCBmb3IgInN5c3RlbSBpZGVudGlmaWNhdGlvbiIuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuWFNMVENfU09VUkNFX0VSUiwKLSAgICAgICAgInN5c3RlbUlkXHVCOTdDIFx1QzEyNFx1QzgxNVx1RDU1OFx1QzlDMCBcdUM1NEFcdUM3NDAgXHVDMEMxXHVEMERDXHVCODVDIFhTTFRDU291cmNlLmJ1aWxkKClcdUFDMDAgXHVENjM4XHVDRDlDXHVCNDE4XHVDNUM4XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgICAgIHsgRXJyb3JNc2cuRVJfUkVTVUxUX05VTEwsCi0gICAgICAgICAgICAiXHVBQ0IwXHVBQ0ZDXHVCMjk0IFx1QjExMFx1Qzc3NCBcdUM1NDRcdUIyQzhcdUM1QjRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhlIHZhbHVlIGFyZ3VtZW50Ci0gICAgICAgICAqIG9mIHNldFBhcmFtZXRlciBtdXN0IGJlIGEgdmFsaWQgSmF2YSBPYmplY3QuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSkFYUF9JTlZBTElEX1NFVF9QQVJBTV9WQUxVRSwKLSAgICAgICAgInswfSBcdUI5RTRcdUFDMUNcdUJDQzBcdUMyMThcdUM3NTggXHVBQzEyXHVDNzQwIFx1QzgwMVx1RDU2OVx1RDU1QyBKYXZhIFx1QUMxRFx1Q0NCNFx1QzVFQ1x1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuIn0sCi0KLQotICAgICAgICB7RXJyb3JNc2cuQ09NUElMRV9TVERJTl9FUlIsCi0gICAgICAgICItaSBcdUM2MzVcdUMxNThcdUM3NDAgLW8gXHVDNjM1XHVDMTU4XHVBQ0ZDIFx1RDU2OFx1QUVEOCBcdUMwQUNcdUM2QTlcdUQ1NzRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LiJ9LAotCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBjb250YWlucyB1c2FnZSBpbmZvcm1hdGlvbiBmb3IgYQotICAgICAgICAgKiBtZWFucyBvZiBpbnZva2luZyBYU0xUQyBmcm9tIHRoZSBjb21tYW5kLWxpbmUuICBUaGUgbWVzc2FnZSBpcwotICAgICAgICAgKiBmb3JtYXR0ZWQgZm9yIHByZXNlbnRhdGlvbiBpbiBFbmdsaXNoLiAgVGhlIHN0cmluZ3MgPG91dHB1dD4sCi0gICAgICAgICAqIDxkaXJlY3Rvcnk+LCBldGMuIGluZGljYXRlIHVzZXItc3BlY2lmaWVkIGFyZ3VtZW50IHZhbHVlcywgYW5kIGNhbgotICAgICAgICAgKiBiZSB0cmFuc2xhdGVkIC0gdGhlIGFyZ3VtZW50IDxwYWNrYWdlPiByZWZlcnMgdG8gYSBKYXZhIHBhY2thZ2UsIHNvCi0gICAgICAgICAqIGl0IHNob3VsZCBiZSBoYW5kbGVkIGluIHRoZSBzYW1lIHdheSB0aGUgdGVybSBpcyBoYW5kbGVkIGZvciBKREsKLSAgICAgICAgICogZG9jdW1lbnRhdGlvbi4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5DT01QSUxFX1VTQUdFX1NUUiwKLSAgICAgICAgIlx1QzBBQ1x1QzZBOVx1QkM5NVxuICAgamF2YSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY21kbGluZS5Db21waWxlIFstbyA8b3V0cHV0Pl1cbiAgICAgIFstZCA8ZGlyZWN0b3J5Pl0gWy1qIDxqYXJmaWxlPl0gWy1wIDxwYWNrYWdlPl1cbiAgICAgIFstbl0gWy14XSBbLXVdIFstdl0gWy1oXSB7IDxzdHlsZXNoZWV0PiB8IC1pIH1cblxuXHVDNjM1XHVDMTU4XG4gICAtbyA8b3V0cHV0PiAgICBcdUMwRERcdUMxMzFcdUI0MUMgdHJhbnNsZXRcdUM1RDAgPG91dHB1dD4gXHVDNzc0XHVCOTg0XHVDNzQ0XG4gICAgICAgICAgICAgICAgICBcdUM5QzBcdUM4MTVcdUQ1NjlcdUIyQzhcdUIyRTQuIFx1QUUzMFx1QkNGOFx1QzgwMVx1QzczQ1x1Qjg1QyB0cmFuc2xldCBcdUM3NzRcdUI5ODRcdUM3NDBcbiAgICAgICAgICAgICAgICAgIDxzdHlsZXNoZWV0PiBcdUM3NzRcdUI5ODRcdUM1RDBcdUMxMUMgXHVEMzBDXHVDMEREXHVCNDI5XHVCMkM4XHVCMkU0LiBcdUM1RUNcdUI3RUMgXHVDMkE0XHVEMEMwXHVDNzdDXHVDMkRDXHVEMkI4XHVCOTdDXG4gICAgICAgICAgICAgICAgICBcdUNFRjRcdUQzMENcdUM3N0NcdUQ1NThcdUIyOTQgXHVBQ0JEXHVDNkIwIFx1Qzc3NCBcdUM2MzVcdUMxNThcdUM3NDAgXHVCQjM0XHVDMkRDXHVCNDI5XHVCMkM4XHVCMkU0LlxuICAgLWQgPGRpcmVjdG9yeT4gdHJhbnNsZXRcdUM1RDAgXHVCMzAwXHVENTVDIFx1QjMwMFx1QzBDMSBcdUI1MTRcdUI4MDlcdUQxQTBcdUI5QUNcdUI5N0MgXHVDOUMwXHVDODE1XHVENTY5XHVCMkM4XHVCMkU0LlxuICAgLWogPGphcmZpbGU+ICAgdHJhbnNsZXQgXHVEMDc0XHVCNzk4XHVDMkE0XHVCOTdDIDxqYXJmaWxlPlx1Qzc3NFx1Qjc3Q1x1QjI5NCBcdUM3NzRcdUI5ODRcdUM3NzQgXHVDOUMwXHVDODE1XHVCNDFDIGphciBcdUQzMENcdUM3N0NcdUM1RDBcbiAgICAgICAgICAgICAgICAgIFx1RDMyOFx1RDBBNFx1QzlDMFx1RDY1NFx1RDU2OVx1QjJDOFx1QjJFNC5cbiAgIC1wIDxwYWNrYWdlPiAgIFx1QzBERFx1QzEzMVx1QjQxQyBcdUJBQThcdUI0RTAgdHJhbnNsZXQgXHVEMDc0XHVCNzk4XHVDMkE0XHVDNUQwIFx1QjMwMFx1RDU3NCBcdUQzMjhcdUQwQTRcdUM5QzAgXHVDNzc0XHVCOTg0IFx1QzgxMVx1QjQ1MFx1QzVCNFx1Qjk3Q1xuICAgICAgICAgICAgICAgICAgXHVDOUMwXHVDODE1XHVENTY5XHVCMkM4XHVCMkU0LlxuICAgLW4gICAgICAgICAgICAgXHVEMTVDXHVENTBDXHVCOUFDXHVEMkI4IFx1Qzc3OFx1Qjc3Q1x1Qzc3OFx1Qzc0NCBcdUMwQUNcdUM2QTlcdUM3M0NcdUI4NUMgXHVDMTI0XHVDODE1XHVENTY5XHVCMkM4XHVCMkU0LiBcdUM3N0NcdUJDMThcdUM4MDFcdUM3M0NcdUI4NUMgXHVBRTMwXHVCQ0Y4IFx1QjNEOVx1Qzc5MVx1Qzc0NFxuICAgICAgICAgICAgICAgICAgXHVDMEFDXHVDNkE5XHVENTU4XHVCMjk0IFx1QUM4M1x1Qzc3NCBcdUM4OEJcdUMyQjVcdUIyQzhcdUIyRTQuXG4gICAteCAgICAgICAgICAgICBcdUNEOTRcdUFDMDAgXHVCNTE0XHVCQzg0XHVBRTQ1IFx1QkE1NFx1QzJEQ1x1QzlDMCBcdUNEOUNcdUI4MjVcdUM3NDQgXHVDMTI0XHVDODE1XHVENTY5XHVCMkM4XHVCMkU0LlxuICAgLXUgICAgICAgICAgICAgPHN0eWxlc2hlZXQ+IFx1Qzc3OFx1QzIxOFx1Qjk3QyBVUkxcdUI4NUMgXHVENTc0XHVDMTFEXHVENTY5XHVCMkM4XHVCMkU0LlxuICAgLWkgICAgICAgICAgICAgXHVDRUY0XHVEMzBDXHVDNzdDXHVCN0VDXHVBQzAwIHN0ZGluXHVDNUQwXHVDMTFDIFx1QzJBNFx1RDBDMFx1Qzc3Q1x1QzJEQ1x1RDJCOFx1Qjk3QyBcdUFDMTVcdUM4MUNcdUI4NUMgXHVDNzdEXHVCM0M0XHVCODVEIFx1RDU2OVx1QjJDOFx1QjJFNC5cbiAgIC12ICAgICAgICAgICAgIFx1Q0VGNFx1RDMwQ1x1Qzc3Q1x1QjdFQ1x1Qzc1OCBcdUJDODRcdUM4MDRcdUM3NDQgXHVDNzc4XHVDMUM0XHVENTY5XHVCMkM4XHVCMkU0LlxuICAgLWggICAgICAgICAgICAgXHVDNzc0IFx1QzBBQ1x1QzZBOVx1QkM5NSBcdUM5QzBcdUNFNjhcdUM3NDQgXHVDNzc4XHVDMUM0XHVENTY5XHVCMkM4XHVCMkU0LlxuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBjb250YWlucyB1c2FnZSBpbmZvcm1hdGlvbiBmb3IgYQotICAgICAgICAgKiBtZWFucyBvZiBpbnZva2luZyBYU0xUQyBmcm9tIHRoZSBjb21tYW5kLWxpbmUuICBUaGUgbWVzc2FnZSBpcwotICAgICAgICAgKiBmb3JtYXR0ZWQgZm9yIHByZXNlbnRhdGlvbiBpbiBFbmdsaXNoLiAgVGhlIHN0cmluZ3MgPGphcmZpbGU+LAotICAgICAgICAgKiA8ZG9jdW1lbnQ+LCBldGMuIGluZGljYXRlIHVzZXItc3BlY2lmaWVkIGFyZ3VtZW50IHZhbHVlcywgYW5kIGNhbgotICAgICAgICAgKiBiZSB0cmFuc2xhdGVkIC0gdGhlIGFyZ3VtZW50IDxjbGFzcz4gcmVmZXJzIHRvIGEgSmF2YSBjbGFzcywgc28gaXQKLSAgICAgICAgICogc2hvdWxkIGJlIGhhbmRsZWQgaW4gdGhlIHNhbWUgd2F5IHRoZSB0ZXJtIGlzIGhhbmRsZWQgZm9yIEpESwotICAgICAgICAgKiBkb2N1bWVudGF0aW9uLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlRSQU5TRk9STV9VU0FHRV9TVFIsCi0gICAgICAgICJcdUMwQUNcdUM2QTlcdUJDOTUgXG4gICBqYXZhIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jbWRsaW5lLlRyYW5zZm9ybSBbLWogPGphcmZpbGU+XVxuICAgICAgWy14XSBbLW4gPGl0ZXJhdGlvbnM+XSB7LXUgPGRvY3VtZW50X3VybD4gfCA8ZG9jdW1lbnQ+fVxuICAgICAgPGNsYXNzPiBbPHBhcmFtMT49PHZhbHVlMT4gLi4uXVxuXG4gICB0cmFuc2xldCA8Y2xhc3M+XHVCOTdDIFx1QzBBQ1x1QzZBOVx1RDU1OFx1QzVFQyA8ZG9jdW1lbnQ+XHVCODVDIFx1QzlDMFx1QzgxNVx1QjQxQyBYTUwgXHVCQjM4XHVDMTFDXHVCOTdDIFxuICAgXHVCQ0MwXHVENjU4XHVENTY5XHVCMkM4XHVCMkU0LiB0cmFuc2xldCA8Y2xhc3M+XHVCMjk0IFxuICAgXHVDMEFDXHVDNkE5XHVDNzkwXHVDNzU4IENMQVNTUEFUSCBcdUI2MTBcdUIyOTQgXHVDMTIwXHVEMEREXHVDODAxXHVDNzNDXHVCODVDIFx1QzlDMFx1QzgxNVx1QjQxQyA8amFyZmlsZT5cdUM1RDAgXHVDNzg4XHVDMkI1XHVCMkM4XHVCMkU0LlxuXHVDNjM1XHVDMTU4XG4gICAtaiA8amFyZmlsZT4gICAgdHJhbnNsZXRcdUM3NDQgXHVCODVDXHVCNERDXHVENTc0IFx1QzYyQyBqYXJmaWxlXHVDNzQ0IFx1QzlDMFx1QzgxNVx1RDU2OVx1QjJDOFx1QjJFNC5cbiAgIC14ICAgICAgICAgICAgICBcdUNEOTRcdUFDMDAgXHVCNTE0XHVCQzg0XHVBRTQ1IFx1QkE1NFx1QzJEQ1x1QzlDMCBcdUNEOUNcdUI4MjVcdUM3NDQgXHVDMTI0XHVDODE1XHVENTY5XHVCMkM4XHVCMkU0LlxuICAgLW4gPGl0ZXJhdGlvbnM+IFx1QkNDMFx1RDY1OFx1Qzc0NCA8aXRlcmF0aW9ucz5cdUQ2OEMgXHVDMkU0XHVENTg5XHVENTU4XHVBQ0UwXG4gICAgICAgICAgICAgICAgICAgXHVENTA0XHVCODVDXHVEMzBDXHVDNzdDIFx1Qzc5MVx1QzEzMSBcdUM4MTVcdUJDRjRcdUI5N0MgXHVENDVDXHVDMkRDXHVENTY5XHVCMkM4XHVCMkU0LlxuICAgLXUgPGRvY3VtZW50X3VybD4gWE1MIFx1Qzc4NVx1QjgyNSBcdUJCMzhcdUMxMUNcdUI5N0MgVVJMXHVCODVDIFx1QzlDMFx1QzgxNVx1RDU2OVx1QjJDOFx1QjJFNC5cbiJ9LAotCi0KLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIjx4c2w6c29ydD4iLCAiPHhzbDpmb3ItZWFjaD4iIGFuZAotICAgICAgICAgKiAiPHhzbDphcHBseS10ZW1wbGF0ZXM+IiBhcmUga2V5d29yZHMgdGhhdCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqIFRoZSBtZXNzYWdlIGluZGljYXRlcyB0aGF0IGFuIHhzbDpzb3J0IGVsZW1lbnQgbXVzdCBiZSBhIGNoaWxkIG9mCi0gICAgICAgICAqIG9uZSBvZiB0aGUgb3RoZXIga2luZHMgb2YgZWxlbWVudHMgbWVudGlvbmVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlNUUkFZX1NPUlRfRVJSLAotICAgICAgICAiPHhzbDpzb3J0Plx1QjI5NCA8eHNsOmZvci1lYWNoPiBcdUI2MTBcdUIyOTQgPHhzbDphcHBseS10ZW1wbGF0ZXM+XHVDNUQwXHVDMTFDXHVCOUNDIFx1QzBBQ1x1QzZBOVx1RDU2MCBcdUMyMTggXHVDNzg4XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUgZW5jb2RpbmcKLSAgICAgICAgICogcmVxdWVzdGVkIGZvciB0aGUgb3V0cHV0IGRvY3VtZW50IHdhcyBvbiB0aGF0IHJlcXVpcmVzIHN1cHBvcnQgdGhhdAotICAgICAgICAgKiBpcyBub3QgYXZhaWxhYmxlIGZyb20gdGhlIEphdmEgVmlydHVhbCBNYWNoaW5lIGJlaW5nIHVzZWQgdG8gZXhlY3V0ZQotICAgICAgICAgKiB0aGUgcHJvZ3JhbS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5VTlNVUFBPUlRFRF9FTkNPRElORywKLSAgICAgICAgIlx1Qzc3NCBKVk1cdUM1RDBcdUMxMUNcdUIyOTQgXHVDRDlDXHVCODI1IFx1Qzc3OFx1Q0Y1NFx1QjUyOSAnJ3swfScnXHVDNzc0KFx1QUMwMCkgXHVDOUMwXHVDNkQwXHVCNDE4XHVDOUMwIFx1QzU0QVx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhlIFhQYXRoIGV4cHJlc3Npb24KLSAgICAgICAgICogbmFtZWQgaW4gdGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHdhcyBub3Qgd2VsbCBmb3JtZWQgc3ludGFjdGljYWxseS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5TWU5UQVhfRVJSLAotICAgICAgICAiJyd7MH0nJ1x1QzVEMCBcdUFENkNcdUJCMzggXHVDNjI0XHVCOTU4XHVBQzAwIFx1Qzc4OFx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIGEgSmF2YQotICAgICAgICAgKiBjbGFzcy4gIFRoZSB0ZXJtICJjb25zdHJ1Y3RvciIgaGVyZSBpcyB0aGUgSmF2YSB0ZXJtLiAgVGhlIG1lc3NhZ2UgaXMKLSAgICAgICAgICogZGlzcGxheWVkIGlmIFhTTFRDIGNvdWxkIG5vdCBmaW5kIGEgY29uc3RydWN0b3IgZm9yIHRoZSBzcGVjaWZpZWQKLSAgICAgICAgICogY2xhc3MuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuQ09OU1RSVUNUT1JfTk9UX0ZPVU5ELAotICAgICAgICAiXHVDNjc4XHVCRDgwIGNvbnN0cnVjdG9yICcnezB9JydcdUM3NDQoXHVCOTdDKSBcdUNDM0VcdUM3NDQgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgInN0YXRpYyIgaXMgdGhlIEphdmEga2V5d29yZC4gIFRoZSBzdWJzdGl0dXRpb24KLSAgICAgICAgICogdGV4dCBpcyB0aGUgbmFtZSBvZiBhIGZ1bmN0aW9uLiAgVGhlIGZpcnN0IGFyZ3VtZW50IG9mIHRoYXQgZnVuY3Rpb24KLSAgICAgICAgICogaXMgbm90IG9mIHRoZSByZXF1aXJlZCB0eXBlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk5PX0pBVkFfRlVOQ1RfVEhJU19SRUYsCi0gICAgICAgICJcdUJFNDRzdGF0aWMgSmF2YSBcdUQ1NjhcdUMyMTggJyd7MH0nJ1x1QzVEMCBcdUIzMDBcdUQ1NUMgXHVDQ0FCXHVCQzg4XHVDOUY4IFx1Qzc3OFx1QzIxOFx1QjI5NCBcdUM4MDFcdUQ1NjlcdUQ1NUMgXHVBQzFEXHVDQ0I0IFx1Q0MzOFx1Qzg3MFx1QUMwMCBcdUM1NDRcdUIyRDlcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIFhQYXRoIGV4cHJlc3Npb24gd2FzIG5vdCBvZiB0aGUgdHlwZQotICAgICAgICAgKiByZXF1aXJlZCBpbiBhIHBhcnRpY3VsYXIgY29udGV4dC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUKLSAgICAgICAgICogZXhwcmVzc2lvbiB0aGF0IHdhcyBpbiBlcnJvci4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5UWVBFX0NIRUNLX0VSUiwKLSAgICAgICAgIicnezB9JycgXHVENDVDXHVENjA0XHVDMkREXHVDNzU4IFx1QzcyMFx1RDYxNVx1Qzc0NCBcdUQ2NTVcdUM3NzhcdUQ1NThcdUIyOTQgXHVDOTExIFx1QzYyNFx1Qjk1OFx1QUMwMCBcdUJDMUNcdUMwRERcdUQ1ODhcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIFhQYXRoIGV4cHJlc3Npb24gd2FzIG5vdCBvZiB0aGUgdHlwZQotICAgICAgICAgKiByZXF1aXJlZCBpbiBhIHBhcnRpY3VsYXIgY29udGV4dC4gIEhvd2V2ZXIsIHRoZSBsb2NhdGlvbiBvZiB0aGUKLSAgICAgICAgICogcHJvYmxlbWF0aWMgZXhwcmVzc2lvbiBpcyB1bmtub3duLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlRZUEVfQ0hFQ0tfVU5LX0xPQ19FUlIsCi0gICAgICAgICJcdUM1NEMgXHVDMjE4IFx1QzVDNlx1QjI5NCBcdUM3MDRcdUNFNThcdUM1RDBcdUMxMUMgXHVENDVDXHVENjA0XHVDMkREXHVDNzU4IFx1QzcyMFx1RDYxNVx1Qzc0NCBcdUQ2NTVcdUM3NzhcdUQ1NThcdUIyOTQgXHVDOTExIFx1QzYyNFx1Qjk1OFx1QUMwMCBcdUJDMUNcdUMwRERcdUQ1ODhcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBhIGNvbW1hbmQtCi0gICAgICAgICAqIGxpbmUgb3B0aW9uIHRoYXQgd2FzIG5vdCByZWNvZ25pemVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfQ01ETElORV9PUFRJT05fRVJSLAotICAgICAgICAiXHVCQTg1XHVCODM5XHVENTg5IFx1QzYzNVx1QzE1OCAnJ3swfScnXHVDNzc0KFx1QUMwMCkgXHVCRDgwXHVDODAxXHVENTY5XHVENTY5XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYSBjb21tYW5kLQotICAgICAgICAgKiBsaW5lIG9wdGlvbi4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5DTURMSU5FX09QVF9NSVNTSU5HX0FSR19FUlIsCi0gICAgICAgICJcdUJBODVcdUI4MzlcdUQ1ODkgXHVDNjM1XHVDMTU4ICcnezB9JydcdUM1RDAgXHVENTQ0XHVDMjE4IFx1Qzc3OFx1QzIxOFx1QUMwMCBcdUIyMDRcdUI3N0RcdUI0MThcdUM1QzhcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyB1c2VkIHRvIGluZGljYXRlIHRoZSBzZXZlcml0eQotICAgICAgICAgKiBvZiBhbm90aGVyIG1lc3NhZ2UuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgY29udGFpbnMgdHdvIGVycm9yCi0gICAgICAgICAqIG1lc3NhZ2VzLiAgVGhlIHNwYWNpbmcgYmVmb3JlIHRoZSBzZWNvbmQgc3Vic3RpdHV0aW9uIHRleHQgaW5kZW50cwotICAgICAgICAgKiBpdCB0aGUgc2FtZSBhbW91bnQgYXMgdGhlIGZpcnN0IGluIEVuZ2xpc2guCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuV0FSTklOR19QTFVTX1dSQVBQRURfTVNHLAotICAgICAgICAiV0FSTklORzogICcnezB9JydcbiAgICAgICA6ezF9In0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyB1c2VkIHRvIGluZGljYXRlIHRoZSBzZXZlcml0eQotICAgICAgICAgKiBvZiBhbm90aGVyIG1lc3NhZ2UuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgYW4gZXJyb3IgbWVzc2FnZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5XQVJOSU5HX01TRywKLSAgICAgICAgIldBUk5JTkc6ICAnJ3swfScnIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyB1c2VkIHRvIGluZGljYXRlIHRoZSBzZXZlcml0eQotICAgICAgICAgKiBvZiBhbm90aGVyIG1lc3NhZ2UuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgY29udGFpbnMgdHdvIGVycm9yCi0gICAgICAgICAqIG1lc3NhZ2VzLiAgVGhlIHNwYWNpbmcgYmVmb3JlIHRoZSBzZWNvbmQgc3Vic3RpdHV0aW9uIHRleHQgaW5kZW50cwotICAgICAgICAgKiBpdCB0aGUgc2FtZSBhbW91bnQgYXMgdGhlIGZpcnN0IGluIEVuZ2xpc2guCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuRkFUQUxfRVJSX1BMVVNfV1JBUFBFRF9NU0csCi0gICAgICAgICJGQVRBTCBFUlJPUjogICcnezB9JydcbiAgICAgICAgICAgOnsxfSJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgdXNlZCB0byBpbmRpY2F0ZSB0aGUgc2V2ZXJpdHkKLSAgICAgICAgICogb2YgYW5vdGhlciBtZXNzYWdlLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIGFuIGVycm9yIG1lc3NhZ2UuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuRkFUQUxfRVJSX01TRywKLSAgICAgICAgIkZBVEFMIEVSUk9SOiAgJyd7MH0nJyJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgdXNlZCB0byBpbmRpY2F0ZSB0aGUgc2V2ZXJpdHkKLSAgICAgICAgICogb2YgYW5vdGhlciBtZXNzYWdlLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGNvbnRhaW5zIHR3byBlcnJvcgotICAgICAgICAgKiBtZXNzYWdlcy4gIFRoZSBzcGFjaW5nIGJlZm9yZSB0aGUgc2Vjb25kIHN1YnN0aXR1dGlvbiB0ZXh0IGluZGVudHMKLSAgICAgICAgICogaXQgdGhlIHNhbWUgYW1vdW50IGFzIHRoZSBmaXJzdCBpbiBFbmdsaXNoLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkVSUk9SX1BMVVNfV1JBUFBFRF9NU0csCi0gICAgICAgICJFUlJPUjogICcnezB9JydcbiAgICAgOnsxfSJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgdXNlZCB0byBpbmRpY2F0ZSB0aGUgc2V2ZXJpdHkKLSAgICAgICAgICogb2YgYW5vdGhlciBtZXNzYWdlLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIGFuIGVycm9yIG1lc3NhZ2UuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuRVJST1JfTVNHLAotICAgICAgICAiRVJST1I6ICAnJ3swfScnIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBhIGNsYXNzLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlRSQU5TRk9STV9XSVRIX1RSQU5TTEVUX1NUUiwKLSAgICAgICAgInRyYW5zbGV0ICcnezB9JydcdUM3NDQoXHVCOTdDKSBcdUMwQUNcdUM2QTlcdUQ1NThcdUM1RUMgXHVCQ0MwXHVENjU4XHVENTU4XHVDMkVEXHVDMkRDXHVDNjI0LiAifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZpcnN0IHN1YnN0aXR1dGlvbiBpcyB0aGUgbmFtZSBvZiBhIGNsYXNzLAotICAgICAgICAgKiB3aGlsZSB0aGUgc2Vjb25kIHN1YnN0aXR1dGlvbiBpcyB0aGUgbmFtZSBvZiBhIGphciBmaWxlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlRSQU5TRk9STV9XSVRIX0pBUl9TVFIsCi0gICAgICAgICJqYXIgXHVEMzBDXHVDNzdDICcnezF9JydcdUM3NTggdHJhbnNsZXQgJyd7MH0nJ1x1Qzc0NChcdUI5N0MpIFx1QzBBQ1x1QzZBOVx1RDU1OFx1QzVFQyBcdUJDQzBcdUQ2NThcdUQ1NThcdUMyRURcdUMyRENcdUM2MjQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJUcmFuc2Zvcm1lckZhY3RvcnkiIGlzIHRoZSBuYW1lIG9mIGEgSmF2YQotICAgICAgICAgKiBpbnRlcmZhY2UgYW5kIG11c3Qgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMKLSAgICAgICAgICogdGhlIG5hbWUgb2YgdGhlIGNsYXNzIHRoYXQgY291bGQgbm90IGJlIGluc3RhbnRpYXRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5DT1VMRF9OT1RfQ1JFQVRFX1RSQU5TX0ZBQ1QsCi0gICAgICAgICJUcmFuc2Zvcm1lckZhY3RvcnkgXHVEMDc0XHVCNzk4XHVDMkE0ICcnezB9JydcdUM3NTggXHVDNzc4XHVDMkE0XHVEMTM0XHVDMkE0XHVCOTdDIFx1QzBERFx1QzEzMVx1RDU2MCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgcHJvZHVjZWQgd2hlbiB0aGUgdXNlcgotICAgICAgICAgKiBzcGVjaWZpZWQgYSBuYW1lIGZvciB0aGUgdHJhbnNsZXQgY2xhc3MgdGhhdCBjb250YWlucyBjaGFyYWN0ZXJzCi0gICAgICAgICAqIHRoYXQgYXJlIG5vdCBwZXJtaXR0ZWQgaW4gYSBKYXZhIGNsYXNzIG5hbWUuICBUaGUgc3Vic3RpdHV0aW9uCi0gICAgICAgICAqIHRleHQgInswfSIgc3BlY2lmaWVzIHRoZSBuYW1lIHRoZSB1c2VyIHJlcXVlc3RlZCwgd2hpbGUgInsxfSIKLSAgICAgICAgICogc3BlY2lmaWVzIHRoZSBuYW1lIHRoZSBwcm9jZXNzb3IgdXNlZCBpbnN0ZWFkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlRSQU5TTEVUX05BTUVfSkFWQV9DT05GTElDVCwKLSAgICAgICAgICInJ3swfScnIFx1Qzc3NFx1Qjk4NFx1QzVEMFx1QjI5NCBKYXZhIFx1RDA3NFx1Qjc5OFx1QzJBNCBcdUM3NzRcdUI5ODRcdUM1RDAgXHVENUM4XHVDNkE5XHVCNDE4XHVDOUMwIFx1QzU0QVx1QjI5NCBcdUJCMzhcdUM3OTBcdUFDMDAgXHVEM0VDXHVENTY4XHVCNDE4XHVDNUI0IFx1Qzc4OFx1QzVCNCBcdUM3NzQgXHVDNzc0XHVCOTg0XHVDNzQ0IHRyYW5zbGV0IFx1RDA3NFx1Qjc5OFx1QzJBNFx1Qzc1OCBcdUM3NzRcdUI5ODRcdUM3M0NcdUI4NUMgXHVDMEFDXHVDNkE5XHVENTYwIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuIFx1QjMwMFx1QzJFMCAnJ3sxfScnIFx1Qzc3NFx1Qjk4NFx1Qzc3NCBcdUMwQUNcdUM2QTlcdUI0MThcdUM1QzhcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBpcyB1c2VkIGFzIGEgaGVhZGVyLgotICAgICAgICAgKiBBbGwgdGhlIGVycm9yIG1lc3NhZ2VzIGFyZSBjb2xsZWN0ZWQgdG9nZXRoZXIgYW5kIGRpc3BsYXllZCBiZW5lYXRoCi0gICAgICAgICAqIHRoaXMgbWVzc2FnZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5DT01QSUxFUl9FUlJPUl9LRVksCi0gICAgICAgICJcdUNFRjRcdUQzMENcdUM3N0NcdUI3RUMgXHVDNjI0XHVCOTU4OiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgaXMgdXNlZCBhcyBhIGhlYWRlci4KLSAgICAgICAgICogQWxsIHRoZSB3YXJuaW5nIG1lc3NhZ2VzIGFyZSBjb2xsZWN0ZWQgdG9nZXRoZXIgYW5kIGRpc3BsYXllZAotICAgICAgICAgKiBiZW5lYXRoIHRoaXMgbWVzc2FnZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5DT01QSUxFUl9XQVJOSU5HX0tFWSwKLSAgICAgICAgIlx1Q0VGNFx1RDMwQ1x1Qzc3Q1x1QjdFQyBcdUFDQkRcdUFDRTA6In0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBpcyB1c2VkIGFzIGEgaGVhZGVyLgotICAgICAgICAgKiBBbGwgdGhlIGVycm9yIG1lc3NhZ2VzIHRoYXQgYXJlIHByb2R1Y2VkIHdoZW4gdGhlIHN0eWxlc2hlZXQgaXMKLSAgICAgICAgICogYXBwbGllZCB0byBhbiBpbnB1dCBkb2N1bWVudCBhcmUgY29sbGVjdGVkIHRvZ2V0aGVyIGFuZCBkaXNwbGF5ZWQKLSAgICAgICAgICogYmVuZWF0aCB0aGlzIG1lc3NhZ2UuICBBICd0cmFuc2xldCcgaXMgdGhlIGNvbXBpbGVkIGZvcm0gb2YgYQotICAgICAgICAgKiBzdHlsZXNoZWV0IChzZWUgYWJvdmUpLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlJVTlRJTUVfRVJST1JfS0VZLAotICAgICAgICAiVHJhbnNsZXQgXHVDNjI0XHVCOTU4OiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBbiBhdHRyaWJ1dGUgd2hvc2UgdmFsdWUgaXMgY29uc3RyYWluZWQgdG8KLSAgICAgICAgICogYmUgYSAiUU5hbWUiIG9yIGEgbGlzdCBvZiAiUU5hbWVzIiBoYWQgYSB2YWx1ZSB0aGF0IHdhcyBpbmNvcnJlY3QuCi0gICAgICAgICAqICdRTmFtZScgaXMgYW4gWE1MIHN5bnRhY3RpYyB0ZXJtIHRoYXQgbXVzdCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoZQotICAgICAgICAgKiBzdWJzdGl0dXRpb24gdGV4dCBjb250YWlucyB0aGUgYWN0dWFsIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSU5WQUxJRF9RTkFNRV9FUlIsCi0gICAgICAgICJcdUFDMTJcdUM3NzQgUU5hbWUgXHVCNjEwXHVCMjk0IFx1QUNGNVx1QkMzMVx1QzczQ1x1Qjg1QyBcdUFENkNcdUJEODRcdUI0MUMgUU5hbWUgXHVCQUE5XHVCODVEXHVDNzc0XHVDNUI0XHVDNTdDIFx1RDU1OFx1QjI5NCBcdUMxOERcdUMxMzFcdUM3NTggXHVBQzEyXHVDNzc0ICcnezB9JydcdUM3ODVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIGF0dHJpYnV0ZSB3aG9zZSB2YWx1ZSBpcyByZXF1aXJlZCB0bwotICAgICAgICAgKiBiZSBhbiAiTkNOYW1lIi4KLSAgICAgICAgICogJ05DTmFtZScgaXMgYW4gWE1MIHN5bnRhY3RpYyB0ZXJtIHRoYXQgbXVzdCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoZQotICAgICAgICAgKiBzdWJzdGl0dXRpb24gdGV4dCBjb250YWlucyB0aGUgYWN0dWFsIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSU5WQUxJRF9OQ05BTUVfRVJSLAotICAgICAgICAiXHVBQzEyXHVDNzc0IE5DTmFtZVx1Qzc3NFx1QzVCNFx1QzU3QyBcdUQ1NThcdUIyOTQgXHVDMThEXHVDMTMxXHVDNzU4IFx1QUMxMlx1Qzc3NCAnJ3swfScnXHVDNzg1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBbiBhdHRyaWJ1dGUgd2l0aCBhbiBpbmNvcnJlY3QgdmFsdWUgd2FzCi0gICAgICAgICAqIGVuY291bnRlcmVkLiAgVGhlIHBlcm1pdHRlZCB2YWx1ZSBpcyBvbmUgb2YgdGhlIGxpdGVyYWwgdmFsdWVzCi0gICAgICAgICAqICJ4bWwiLCAiaHRtbCIgb3IgInRleHQiOyBpdCBpcyBhbHNvIHBlcm1pdHRlZCB0byBoYXZlIHRoZSBmb3JtIG9mCi0gICAgICAgICAqIGEgUU5hbWUgdGhhdCBpcyBub3QgYWxzbyBhbiBOQ05hbWUuICBUaGUgdGVybXMgIm1ldGhvZCIsCi0gICAgICAgICAqICJ4c2w6b3V0cHV0IiwgInhtbCIsICJodG1sIiBhbmQgInRleHQiIGFyZSBrZXl3b3JkcyB0aGF0IG11c3Qgbm90Ci0gICAgICAgICAqIGJlIHRyYW5zbGF0ZWQuICBUaGUgdGVybSAicW5hbWUtYnV0LW5vdC1uY25hbWUiIGlzIGFuIFhNTCBzeW50YWN0aWMKLSAgICAgICAgICogdGVybS4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBjb250YWlucyB0aGUgYWN0dWFsIHZhbHVlIG9mIHRoZQotICAgICAgICAgKiBhdHRyaWJ1dGUuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSU5WQUxJRF9NRVRIT0RfSU5fT1VUUFVULAotICAgICAgICAiPHhzbDpvdXRwdXQ+IFx1QzY5NFx1QzE4Q1x1QzVEMCBcdUIzMDBcdUQ1NUMgbWV0aG9kIFx1QzE4RFx1QzEzMVx1Qzc1OCBcdUFDMTJcdUM3NzQgJyd7MH0nJ1x1Qzc4NVx1QjJDOFx1QjJFNC4gXHVBQzEyXHVDNzQwICcneG1sJycsICcnaHRtbCcnLCAnJ3RleHQnJyBcdUI2MTBcdUIyOTQgcW5hbWUtYnV0LW5vdC1uY25hbWUgXHVDOTExIFx1RDU1OFx1QjA5OFx1QzVFQ1x1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfR0VUX0ZFQVRVUkVfTlVMTF9OQU1FLAotICAgICAgICAiXHVBRTMwXHVCMkE1IFx1Qzc3NFx1Qjk4NFx1Qzc0MCBUcmFuc2Zvcm1lckZhY3RvcnkuZ2V0RmVhdHVyZShcdUJCMzhcdUM3OTBcdUM1RjQgXHVDNzc0XHVCOTg0KVx1QzVEMFx1QzExQyBcdUIxMTBcdUM3N0MgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAgICAgICB7RXJyb3JNc2cuSkFYUF9TRVRfRkVBVFVSRV9OVUxMX05BTUUsCi0gICAgICAgICJcdUFFMzBcdUIyQTUgXHVDNzc0XHVCOTg0XHVDNzQwIFRyYW5zZm9ybWVyRmFjdG9yeS5zZXRGZWF0dXJlKFx1QkIzOFx1Qzc5MFx1QzVGNCBcdUM3NzRcdUI5ODQsIFx1QkQ4MFx1QzZCOCBcdUFDMTIpXHVDNUQwXHVDMTFDIFx1QjExMFx1Qzc3QyBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX1VOU1VQUE9SVEVEX0ZFQVRVUkUsCi0gICAgICAgICJcdUM3NzQgVHJhbnNmb3JtZXJGYWN0b3J5XHVDNUQwXHVDMTFDICcnezB9JycgXHVBRTMwXHVCMkE1XHVDNzQ0IFx1QzEyNFx1QzgxNVx1RDU2MCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX1NFQ1VSRVBST0NFU1NJTkdfRkVBVFVSRSwKLSAgICAgICAgIkZFQVRVUkVfU0VDVVJFX1BST0NFU1NJTkc6IFx1QkNGNFx1QzU0OCBcdUFEMDBcdUI5QUNcdUM3OTBcdUFDMDAgXHVDNzg4XHVDNzQ0IFx1QUNCRFx1QzZCMCBcdUFFMzBcdUIyQTVcdUM3NDQgZmFsc2VcdUI4NUMgXHVDMTI0XHVDODE1XHVENTYwIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBkZXNjcmliZXMgYW4gaW50ZXJuYWwgZXJyb3IgaW4gdGhlCi0gICAgICAgICAqIHByb2Nlc3Nvci4gIFRoZSB0ZXJtICJieXRlIGNvZGUiIGlzIGEgSmF2YSB0ZWNobmljYWwgdGVybSBmb3IgdGhlCi0gICAgICAgICAqIGV4ZWN1dGFibGUgY29kZSBpbiBhIEphdmEgbWV0aG9kLCBhbmQgInRyeS1jYXRjaC1maW5hbGx5IGJsb2NrIgotICAgICAgICAgKiByZWZlcnMgdG8gdGhlIEphdmEga2V5d29yZHMgd2l0aCB0aG9zZSBuYW1lcy4gICJPdXRsaW5lZCIgaXMgYQotICAgICAgICAgKiB0ZWNobmljYWwgdGVybSBpbnRlcm5hbCB0byBYU0xUQyBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk9VVExJTkVfRVJSX1RSWV9DQVRDSCwKLSAgICAgICAgICJcdUIwQjRcdUJEODAgWFNMVEMgXHVDNjI0XHVCOTU4OiBcdUMwRERcdUMxMzFcdUI0MUMgXHVCQzE0XHVDNzc0XHVEMkI4IFx1Q0Y1NFx1QjREQ1x1QUMwMCB0cnktY2F0Y2gtZmluYWxseSBcdUJFMTRcdUI4NURcdUM3NDQgXHVEM0VDXHVENTY4XHVENTU4XHVCQkMwXHVCODVDIG91dGxpbmVkIFx1Q0M5OFx1QjlBQ1x1RDU2MCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgZGVzY3JpYmVzIGFuIGludGVybmFsIGVycm9yIGluIHRoZQotICAgICAgICAgKiBwcm9jZXNzb3IuICBUaGUgdGVybXMgIk91dGxpbmVhYmxlQ2h1bmtTdGFydCIgYW5kCi0gICAgICAgICAqICJPdXRsaW5lYWJsZUNodW5rRW5kIiBhcmUgdGhlIG5hbWVzIG9mIGNsYXNzZXMgaW50ZXJuYWwgdG8gWFNMVEMgYW5kCi0gICAgICAgICAqIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoZSBtZXNzYWdlIGluZGljYXRlcyB0aGF0IGZvciBldmVyeQotICAgICAgICAgKiAic3RhcnQiIHRoZXJlIG11c3QgYmUgYSBjb3JyZXNwb25kaW5nICJlbmQiLCBhbmQgdmljZSB2ZXJzYSwgYW5kCi0gICAgICAgICAqIHRoYXQgaWYgb25lIG9mIGEgcGFpciBvZiAic3RhcnQiIGFuZCAiZW5kIiBhcHBlYXJzIGJldHdlZW4gYW5vdGhlcgotICAgICAgICAgKiBwYWlyIG9mIGNvcnJlc3BvbmRpbmcgInN0YXJ0IiBhbmQgImVuZCIsIHRoZW4gdGhlIG90aGVyIGhhbGYgb2YgdGhlCi0gICAgICAgICAqIHBhaXIgbXVzdCBhbHNvIGJlIGJldHdlZW4gdGhhdCBzYW1lIGVuY2xvc2luZyBwYWlyLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk9VVExJTkVfRVJSX1VOQkFMQU5DRURfTUFSS0VSUywKLSAgICAgICAgICJcdUIwQjRcdUJEODAgWFNMVEMgXHVDNjI0XHVCOTU4OiBPdXRsaW5lYWJsZUNodW5rU3RhcnQgXHVCQzBGIE91dGxpbmVhYmxlQ2h1bmtFbmQgXHVENDVDXHVDMkRDXHVDNzkwXHVDNzU4IFx1QzlERFx1Qzc3NCBcdUI5REVcdUM1NDRcdUM1N0MgXHVENTU4XHVBQ0UwIFx1QzYyQ1x1QkMxNFx1Qjk3NFx1QUM4QyBcdUM5MTFcdUNDQTlcdUI0MThcdUM1QjRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgZGVzY3JpYmVzIGFuIGludGVybmFsIGVycm9yIGluIHRoZQotICAgICAgICAgKiBwcm9jZXNzb3IuICBUaGUgdGVybSAiYnl0ZSBjb2RlIiBpcyBhIEphdmEgdGVjaG5pY2FsIHRlcm0gZm9yIHRoZQotICAgICAgICAgKiBleGVjdXRhYmxlIGNvZGUgaW4gYSBKYXZhIG1ldGhvZC4gIFRoZSAibWV0aG9kIiB0aGF0IGlzIGJlaW5nCi0gICAgICAgICAqIHJlZmVycmVkIHRvIGlzIGEgSmF2YSBtZXRob2QgaW4gYSB0cmFuc2xldCB0aGF0IFhTTFRDIGlzIGdlbmVyYXRpbmcKLSAgICAgICAgICogaW4gcHJvY2Vzc2luZyBhIHN0eWxlc2hlZXQuICBUaGUgImluc3RydWN0aW9uIiB0aGF0IGlzIGJlaW5nCi0gICAgICAgICAqIHJlZmVycmVkIHRvIGlzIG9uZSBvZiB0aGUgaW5zdHJ1dGlvbnMgaW4gdGhlIEphdmEgYnl0ZSBjb2RlIGluIHRoYXQKLSAgICAgICAgICogbWV0aG9kLiAgIk91dGxpbmVkIiBpcyBhIHRlY2huaWNhbCB0ZXJtIGludGVybmFsIHRvIFhTTFRDIGFuZAotICAgICAgICAgKiBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuT1VUTElORV9FUlJfREVMRVRFRF9UQVJHRVQsCi0gICAgICAgICAiXHVCMEI0XHVCRDgwIFhTTFRDIFx1QzYyNFx1Qjk1ODogb3V0bGluZWQgXHVDQzk4XHVCOUFDXHVCNDFDIFx1QkMxNFx1Qzc3NFx1RDJCOCBcdUNGNTRcdUI0REMgXHVCRTE0XHVCODVEXHVDNUQwIFx1QzE4RFx1RDU1QyBcdUJBODVcdUI4MzlcdUM3NzQgXHVDNUVDXHVDODA0XHVENzg4IFx1QzZEMFx1Qjc5OCBcdUJBNTRcdUMxOENcdUI0RENcdUM1RDBcdUMxMUMgXHVDQzM4XHVDODcwXHVCNDI5XHVCMkM4XHVCMkU0LiIKLSAgICAgICAgfSwKLQotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgZGVzY3JpYmVzIGFuIGludGVybmFsIGVycm9yIGluIHRoZQotICAgICAgICAgKiBwcm9jZXNzb3IuICBUaGUgIm1ldGhvZCIgdGhhdCBpcyBiZWluZyByZWZlcnJlZCB0byBpcyBhIEphdmEgbWV0aG9kCi0gICAgICAgICAqIGluIGEgdHJhbnNsZXQgdGhhdCBYU0xUQyBpcyBnZW5lcmF0aW5nLgotICAgICAgICAgKgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk9VVExJTkVfRVJSX01FVEhPRF9UT09fQklHLAotICAgICAgICAgIlx1QjBCNFx1QkQ4MCBYU0xUQyBcdUM2MjRcdUI5NTg6IHRyYW5zbGV0XHVDNzU4IFx1QkE1NFx1QzE4Q1x1QjREQ1x1QUMwMCBKYXZhIFZpcnR1YWwgTWFjaGluZVx1Qzc1OCBcdUJBNTRcdUMxOENcdUI0REMgXHVBRTM4XHVDNzc0IFx1QzgxQ1x1RDU1Q1x1Qzc3OCA2NEtCXHVCOTdDIFx1Q0QwOFx1QUNGQ1x1RDU2OVx1QjJDOFx1QjJFNC4gXHVCMzAwXHVBQzFDIFx1QzJBNFx1RDBDMFx1Qzc3Q1x1QzJEQ1x1RDJCOFx1Qzc1OCBcdUQxNUNcdUQ1MENcdUI5QUNcdUQyQjhcdUFDMDAgXHVCOUU0XHVDNkIwIFx1RDA2Q1x1QUUzMCBcdUI1NENcdUJCMzhcdUM1RDAgXHVCQzFDXHVDMEREXHVENTY5XHVCMkM4XHVCMkU0LiBcdUIzNTQgXHVDNzkxXHVDNzQwIFx1RDE1Q1x1RDUwQ1x1QjlBQ1x1RDJCOFx1Qjk3QyBcdUMwQUNcdUM2QTlcdUQ1NThcdUIzQzRcdUI4NUQgXHVDMkE0XHVEMEMwXHVDNzdDXHVDMkRDXHVEMkI4XHVCOTdDIFx1QzdBQ1x1QUQ2Q1x1QzEzMVx1RDU3NCBcdUJDRjRcdUMyRURcdUMyRENcdUM2MjQuIgotICAgICAgICB9LAotCi0gICAgICAgICB7RXJyb3JNc2cuREVTRVJJQUxJWkVfVFJBTlNMRVRfRVJSLCAiSmF2YSBcdUJDRjRcdUM1NDhcdUM3NzQgXHVDMEFDXHVDNkE5XHVDNzNDXHVCODVDIFx1QzEyNFx1QzgxNVx1QjQxQyBcdUFDQkRcdUM2QjAgVGVtcGxhdGVzSW1wbCBcdUM5QzFcdUI4MkNcdUQ2NTQgXHVENTc0XHVDODFDXHVDNUQwIFx1QjMwMFx1RDU1QyBcdUM5QzBcdUM2RDBcdUM3NzQgXHVDMEFDXHVDNkE5IFx1QzU0OFx1RDU2OFx1QzczQ1x1Qjg1QyBcdUMxMjRcdUM4MTVcdUI0MjlcdUIyQzhcdUIyRTQuIGpkay54bWwuZW5hYmxlVGVtcGxhdGVzSW1wbERlc2VyaWFsaXphdGlvbiBcdUMyRENcdUMyQTRcdUQxNUMgXHVDMThEXHVDMTMxXHVDNzQ0IHRydWVcdUI4NUMgXHVDMTI0XHVDODE1XHVENTU4XHVCQTc0IFx1Qzc3NFx1Qjk3QyBcdUJCMzRcdUQ2QThcdUQ2NTRcdUQ1NjAgXHVDMjE4IFx1Qzc4OFx1QzJCNVx1QjJDOFx1QjJFNC4ifQotCi0gICAgfTsKLQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvdXRpbC9FcnJvck1lc3NhZ2VzX3B0X0JSLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL3V0aWwvRXJyb3JNZXNzYWdlc19wdF9CUi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkNmUzNTMwLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvdXRpbC9FcnJvck1lc3NhZ2VzX3B0X0JSLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5NzQgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsOwotCi1pbXBvcnQgamF2YS51dGlsLkxpc3RSZXNvdXJjZUJ1bmRsZTsKLQotLyoqCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqLwotcHVibGljIGNsYXNzIEVycm9yTWVzc2FnZXNfcHRfQlIgZXh0ZW5kcyBMaXN0UmVzb3VyY2VCdW5kbGUgewotCi0vKgotICogWFNMVEMgY29tcGlsZS10aW1lIGVycm9yIG1lc3NhZ2VzLgotICoKLSAqIEdlbmVyYWwgbm90ZXMgdG8gdHJhbnNsYXRvcnMgYW5kIGRlZmluaXRpb25zOgotICoKLSAqICAgMSkgWFNMVEMgaXMgdGhlIG5hbWUgb2YgdGhlIHByb2R1Y3QuICBJdCBpcyBhbiBhY3JvbnltIGZvciAiWFNMVCBDb21waWxlciIuCi0gKiAgICAgIFhTTFQgaXMgYW4gYWNyb255bSBmb3IgIlhNTCBTdHlsZXNoZWV0IExhbmd1YWdlOiBUcmFuc2Zvcm1hdGlvbnMiLgotICoKLSAqICAgMikgQSBzdHlsZXNoZWV0IGlzIGEgZGVzY3JpcHRpb24gb2YgaG93IHRvIHRyYW5zZm9ybSBhbiBpbnB1dCBYTUwgZG9jdW1lbnQKLSAqICAgICAgaW50byBhIHJlc3VsdGFudCBYTUwgZG9jdW1lbnQgKG9yIEhUTUwgZG9jdW1lbnQgb3IgdGV4dCkuICBUaGUKLSAqICAgICAgc3R5bGVzaGVldCBpdHNlbGYgaXMgZGVzY3JpYmVkIGluIHRoZSBmb3JtIG9mIGFuIFhNTCBkb2N1bWVudC4KLSAqCi0gKiAgIDMpIEEgdGVtcGxhdGUgaXMgYSBjb21wb25lbnQgb2YgYSBzdHlsZXNoZWV0IHRoYXQgaXMgdXNlZCB0byBtYXRjaCBhCi0gKiAgICAgIHBhcnRpY3VsYXIgcG9ydGlvbiBvZiBhbiBpbnB1dCBkb2N1bWVudCBhbmQgc3BlY2lmaWVzIHRoZSBmb3JtIG9mIHRoZQotICogICAgICBjb3JyZXNwb25kaW5nIHBvcnRpb24gb2YgdGhlIG91dHB1dCBkb2N1bWVudC4KLSAqCi0gKiAgIDQpIEFuIGF4aXMgaXMgYSBwYXJ0aWN1bGFyICJkaW1lbnNpb24iIGluIGEgdHJlZSByZXByZXNlbnRhdGlvbiBvZiBhbiBYTUwKLSAqICAgICAgZG9jdW1lbnQ7IHRoZSBub2RlcyBpbiB0aGUgdHJlZSBhcmUgZGl2aWRlZCBhbG9uZyBkaWZmZXJlbnQgYXhlcy4KLSAqICAgICAgVHJhdmVyc2luZyB0aGUgImNoaWxkIiBheGlzLCBmb3IgaW5zdGFuY2UsIG1lYW5zIHRoYXQgdGhlIHByb2dyYW0KLSAqICAgICAgd291bGQgdmlzaXQgZWFjaCBjaGlsZCBvZiBhIHBhcnRpY3VsYXIgbm9kZTsgdHJhdmVyc2luZyB0aGUgImRlc2NlbmRhbnQiCi0gKiAgICAgIGF4aXMgbWVhbnMgdGhhdCB0aGUgcHJvZ3JhbSB3b3VsZCB2aXNpdCB0aGUgY2hpbGQgbm9kZXMgb2YgYSBwYXJ0aWN1bGFyCi0gKiAgICAgIG5vZGUsIHRoZWlyIGNoaWxkcmVuLCBhbmQgc28gb24gdW50aWwgdGhlIGxlYWYgbm9kZXMgb2YgdGhlIHRyZWUgYXJlCi0gKiAgICAgIHJlYWNoZWQuCi0gKgotICogICA1KSBBbiBpdGVyYXRvciBpcyBhbiBvYmplY3QgdGhhdCB0cmF2ZXJzZXMgbm9kZXMgaW4gYSB0cmVlIGFsb25nIGEKLSAqICAgICAgcGFydGljdWxhciBheGlzLCBvbmUgYXQgYSB0aW1lLgotICoKLSAqICAgNikgQW4gZWxlbWVudCBpcyBhIG1hcmstdXAgdGFnIGluIGFuIFhNTCBkb2N1bWVudDsgYW4gYXR0cmlidXRlIGlzIGEKLSAqICAgICAgbW9kaWZpZXIgb24gdGhlIHRhZy4gIEZvciBleGFtcGxlLCBpbiA8ZWxlbSBhdHRyPSd2YWwnIGF0dHIyPSd2YWwyJz4KLSAqICAgICAgImVsZW0iIGlzIGFuIGVsZW1lbnQgbmFtZSwgImF0dHIiIGFuZCAiYXR0cjIiIGFyZSBhdHRyaWJ1dGUgbmFtZXMgd2l0aAotICogICAgICB0aGUgdmFsdWVzICJ2YWwiIGFuZCAidmFsMiIsIHJlc3BlY3RpdmVseS4KLSAqCi0gKiAgIDcpIEEgbmFtZXNwYWNlIGRlY2xhcmF0aW9uIGlzIGEgc3BlY2lhbCBhdHRyaWJ1dGUgdGhhdCBpcyB1c2VkIHRvIGFzc29jaWF0ZQotICogICAgICBhIHByZWZpeCB3aXRoIGEgVVJJICh0aGUgbmFtZXNwYWNlKS4gIFRoZSBtZWFuaW5ncyBvZiBlbGVtZW50IG5hbWVzIGFuZAotICogICAgICBhdHRyaWJ1dGUgbmFtZXMgdGhhdCB1c2UgdGhhdCBwcmVmaXggYXJlIGRlZmluZWQgd2l0aCByZXNwZWN0IHRvIHRoYXQKLSAqICAgICAgbmFtZXNwYWNlLgotICoKLSAqICAgOCkgRE9NIGlzIGFuIGFjcm9ueW0gZm9yIERvY3VtZW50IE9iamVjdCBNb2RlbC4gIEl0IGlzIGEgdHJlZQotICogICAgICByZXByZXNlbnRhdGlvbiBvZiBhbiBYTUwgZG9jdW1lbnQuCi0gKgotICogICAgICBTQVggaXMgYW4gYWNyb255bSBmb3IgdGhlIFNpbXBsZSBBUEkgZm9yIFhNTCBwcm9jZXNzaW5nLiAgSXQgaXMgYW4gQVBJCi0gKiAgICAgIHVzZWQgaW5mb3JtIGFuIFhNTCBwcm9jZXNzb3IgKGluIHRoaXMgY2FzZSBYU0xUQykgb2YgdGhlIHN0cnVjdHVyZSBhbmQKLSAqICAgICAgY29udGVudCBvZiBhbiBYTUwgZG9jdW1lbnQuCi0gKgotICogICAgICBJbnB1dCB0byB0aGUgc3R5bGVzaGVldCBwcm9jZXNzb3IgY2FuIGNvbWUgZnJvbSBhbiBYTUwgcGFyc2VyIGluIHRoZQotICogICAgICBmb3JtIG9mIGEgRE9NIHRyZWUgb3IgdGhyb3VnaCB0aGUgU0FYIEFQSS4KLSAqCi0gKiAgIDkpIERURCBpcyBhIGRvY3VtZW50IHR5cGUgZGVjbGFyYXRpb24uICBJdCBpcyBhIHdheSBvZiBzcGVjaWZ5aW5nIHRoZQotICogICAgICBncmFtbWFyIGZvciBhbiBYTUwgZmlsZSwgdGhlIG5hbWVzIGFuZCB0eXBlcyBvZiBlbGVtZW50cywgYXR0cmlidXRlcywKLSAqICAgICAgZXRjLgotICoKLSAqICAxMCkgWFBhdGggaXMgYSBzcGVjaWZpY2F0aW9uIHRoYXQgZGVzY3JpYmVzIGEgbm90YXRpb24gZm9yIGlkZW50aWZ5aW5nCi0gKiAgICAgIG5vZGVzIGluIGEgdHJlZS1zdHJ1Y3R1cmVkIHJlcHJlc2VudGF0aW9uIG9mIGFuIFhNTCBkb2N1bWVudC4gIEFuCi0gKiAgICAgIGluc3RhbmNlIG9mIHRoYXQgbm90YXRpb24gaXMgcmVmZXJyZWQgdG8gYXMgYW4gWFBhdGggZXhwcmVzc2lvbi4KLSAqCi0gKiAgMTEpIFRyYW5zbGV0IGlzIGFuIGludmVudGVkIHRlcm0gdGhhdCByZWZlcnMgdG8gdGhlIGNsYXNzIGZpbGUgdGhhdCBjb250YWlucwotICogICAgICB0aGUgY29tcGlsZWQgZm9ybSBvZiBhIHN0eWxlc2hlZXQuCi0gKi8KLQotICAgIC8vIFRoZXNlIG1lc3NhZ2Ugc2hvdWxkIGJlIHJlYWQgZnJvbSBhIGxvY2FsZS1zcGVjaWZpYyByZXNvdXJjZSBidW5kbGUKLSAgICAvKiogR2V0IHRoZSBsb29rdXAgdGFibGUgZm9yIGVycm9yIG1lc3NhZ2VzLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgbWVzc2FnZSBsb29rdXAgdGFibGUuCi0gICAgICovCi0gICAgcHVibGljIE9iamVjdFtdW10gZ2V0Q29udGVudHMoKQotICAgIHsKLSAgICAgIHJldHVybiBuZXcgT2JqZWN0W11bXSB7Ci0gICAgICAgIHtFcnJvck1zZy5NVUxUSVBMRV9TVFlMRVNIRUVUX0VSUiwKLSAgICAgICAgIk1haXMgZGUgdW1hIGZvbGhhIGRlIGVzdGlsb3MgZGVmaW5pZGEgbm8gbWVzbW8gYXJxdWl2by4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIGEKLSAgICAgICAgICogdGVtcGxhdGUuICBUaGUgc2FtZSBuYW1lIHdhcyB1c2VkIG9uIHR3byBkaWZmZXJlbnQgdGVtcGxhdGVzIGluIHRoZQotICAgICAgICAgKiBzYW1lIHN0eWxlc2hlZXQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVEVNUExBVEVfUkVERUZfRVJSLAotICAgICAgICAiTyBtb2RlbG8gJyd7MH0nJyBqXHUwMEUxIGZvaSBkZWZpbmlkbyBuZXN0YSBmb2xoYSBkZSBlc3RpbG9zLiJ9LAotCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBhCi0gICAgICAgICAqIHRlbXBsYXRlLiAgQSByZWZlcmVuY2UgdG8gdGhlIHRlbXBsYXRlIG5hbWUgd2FzIGVuY291bnRlcmVkLCBidXQgdGhlCi0gICAgICAgICAqIHRlbXBsYXRlIGlzIHVuZGVmaW5lZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5URU1QTEFURV9VTkRFRl9FUlIsCi0gICAgICAgICJPIG1vZGVsbyAnJ3swfScnIG5cdTAwRTNvIGZvaSBkZWZpbmlkbyBuZXN0YSBmb2xoYSBkZSBlc3RpbG9zLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYSB2YXJpYWJsZQotICAgICAgICAgKiB0aGF0IHdhcyBkZWZpbmVkIG1vcmUgdGhhbiBvbmNlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlZBUklBQkxFX1JFREVGX0VSUiwKLSAgICAgICAgIkEgdmFyaVx1MDBFMXZlbCAnJ3swfScnIGVzdFx1MDBFMSBkZWZpbmlkYSB2XHUwMEUxcmlhcyB2ZXplcyBubyBtZXNtbyBlc2NvcG8uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBhIHZhcmlhYmxlCi0gICAgICAgICAqIG9yIHBhcmFtZXRlci4gIEEgcmVmZXJlbmNlIHRvIHRoZSB2YXJpYWJsZSBvciBwYXJhbWV0ZXIgd2FzIGZvdW5kLAotICAgICAgICAgKiBidXQgaXQgd2FzIG5ldmVyIGRlZmluZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVkFSSUFCTEVfVU5ERUZfRVJSLAotICAgICAgICAiVmFyaVx1MDBFMXZlbCBvdSBwYXJcdTAwRTJtZXRybyAnJ3swfScnIGluZGVmaW5pZG8uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSB3b3JkICJjbGFzcyIgaGVyZSByZWZlcnMgdG8gYSBKYXZhIGNsYXNzLgotICAgICAgICAgKiBQcm9jZXNzaW5nIHRoZSBzdHlsZXNoZWV0IHJlcXVpcmVkIGEgY2xhc3MgdG8gYmUgbG9hZGVkLCBidXQgaXQgY291bGQKLSAgICAgICAgICogbm90IGJlIGZvdW5kLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIHRoZSBjbGFzcy4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5DTEFTU19OT1RfRk9VTkRfRVJSLAotICAgICAgICAiTlx1MDBFM28gXHUwMEU5IHBvc3NcdTAwRUR2ZWwgbG9jYWxpemFyIGEgY2xhc3NlICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSB3b3JkICJtZXRob2QiIGhlcmUgcmVmZXJzIHRvIGEgSmF2YSBtZXRob2QuCi0gICAgICAgICAqIFByb2Nlc3NpbmcgdGhlIHN0eWxlc2hlZXQgcmVxdWlyZWQgYSByZWZlcmVuY2UgdG8gdGhlIG1ldGhvZCBuYW1lZCBieQotICAgICAgICAgKiB0aGUgc3Vic3RpdHV0aW9uIHRleHQsIGJ1dCBpdCBjb3VsZCBub3QgYmUgZm91bmQuICAicHVibGljIiBpcyB0aGUKLSAgICAgICAgICogSmF2YSBrZXl3b3JkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk1FVEhPRF9OT1RfRk9VTkRfRVJSLAotICAgICAgICAiTlx1MDBFM28gXHUwMEU5IHBvc3NcdTAwRUR2ZWwgbG9jYWxpemFyIG8gbVx1MDBFOXRvZG8gZXh0ZXJubyAnJ3swfScnIChkZXZlIHNlciBwXHUwMEZBYmxpY28pLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgd29yZCAibWV0aG9kIiBoZXJlIHJlZmVycyB0byBhIEphdmEgbWV0aG9kLgotICAgICAgICAgKiBQcm9jZXNzaW5nIHRoZSBzdHlsZXNoZWV0IHJlcXVpcmVkIGEgcmVmZXJlbmNlIHRvIHRoZSBtZXRob2QgbmFtZWQgYnkKLSAgICAgICAgICogdGhlIHN1YnN0aXR1dGlvbiB0ZXh0LCBidXQgbm8gbWV0aG9kIHdpdGggdGhlIHJlcXVpcmVkIHR5cGVzIG9mCi0gICAgICAgICAqIGFyZ3VtZW50cyBvciByZXR1cm4gdHlwZSBjb3VsZCBiZSBmb3VuZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5BUkdVTUVOVF9DT05WRVJTSU9OX0VSUiwKLSAgICAgICAgIk5cdTAwRTNvIFx1MDBFOSBwb3NzXHUwMEVEdmVsIGNvbnZlcnRlciBvIGFyZ3VtZW50by90aXBvIGRlIHJldG9ybm8gbmEgY2hhbWFkYSBwYXJhIG8gbVx1MDBFOXRvZG8gJyd7MH0nJyJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZmlsZSBvciBVUkkgbmFtZWQgaW4gdGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgICAqIGlzIG1pc3NpbmcuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuRklMRV9OT1RfRk9VTkRfRVJSLAotICAgICAgICAiQXJxdWl2byBvdSBVUkkgJyd7MH0nJyBuXHUwMEUzbyBlbmNvbnRyYWRvLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgZGlzcGxheWVkIHdoZW4gdGhlIFVSSQotICAgICAgICAgKiBtZW50aW9uZWQgaW4gdGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIG5vdCB3ZWxsLWZvcm1lZCBzeW50YWN0aWNhbGx5LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklOVkFMSURfVVJJX0VSUiwKLSAgICAgICAgIlVSSSBpbnZcdTAwRTFsaWRvICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmaWxlIG9yIFVSSSBuYW1lZCBpbiB0aGUgc3Vic3RpdHV0aW9uIHRleHQKLSAgICAgICAgICogZXhpc3RzIGJ1dCBjb3VsZCBub3QgYmUgb3BlbmVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkZJTEVfQUNDRVNTX0VSUiwKLSAgICAgICAgIk5cdTAwRTNvIFx1MDBFOSBwb3NzXHUwMEVEdmVsIGFicmlyIG8gYXJxdWl2byBvdSBvIFVSSSAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6IDx4c2w6c3R5bGVzaGVldD4gYW5kIDx4c2w6dHJhbnNmb3JtPiBhcmUKLSAgICAgICAgICoga2V5d29yZHMgdGhhdCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTUlTU0lOR19ST09UX0VSUiwKLSAgICAgICAgImVsZW1lbnRvIDx4c2w6c3R5bGVzaGVldD4gb3UgPHhzbDp0cmFuc2Zvcm0+IGVzcGVyYWRvLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3R5bGVzaGVldCBjb250YWluZWQgYSByZWZlcmVuY2UgdG8gYQotICAgICAgICAgKiBuYW1lc3BhY2UgcHJlZml4IHRoYXQgd2FzIHVuZGVmaW5lZC4gIFRoZSB2YWx1ZSBvZiB0aGUgc3Vic3RpdHV0aW9uCi0gICAgICAgICAqIHRleHQgaXMgdGhlIG5hbWUgb2YgdGhlIHByZWZpeC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5OQU1FU1BBQ0VfVU5ERUZfRVJSLAotICAgICAgICAiTyBwcmVmaXhvIGRvIG5hbWVzcGFjZSAnJ3swfScnIG5cdTAwRTNvIGZvaSBkZWNsYXJhZG8uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBKYXZhIGZ1bmN0aW9uIG5hbWVkIGluIHRoZSBzdHlsZXNoZWV0IGNvdWxkCi0gICAgICAgICAqIG5vdCBiZSBmb3VuZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5GVU5DVElPTl9SRVNPTFZFX0VSUiwKLSAgICAgICAgIk5cdTAwRTNvIFx1MDBFOSBwb3NzXHUwMEVEdmVsIHJlc29sdmVyIGEgY2hhbWFkYSBwYXJhIGEgZnVuXHUwMEU3XHUwMEUzbyAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYQotICAgICAgICAgKiBmdW5jdGlvbi4gIEEgbGl0ZXJhbCBzdHJpbmcgaGVyZSBtZWFucyBhIGNvbnN0YW50IHN0cmluZyB2YWx1ZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5ORUVEX0xJVEVSQUxfRVJSLAotICAgICAgICAiTyBhcmd1bWVudG8gcGFyYSBcInswfScnIGRldmUgc2VyIHVtYSBzdHJpbmcgbGl0ZXJhbC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGluZGljYXRlcyB0aGVyZSB3YXMgYSBzeW50YWN0aWMKLSAgICAgICAgICogZXJyb3IgaW4gdGhlIGZvcm0gb2YgYW4gWFBhdGggZXhwcmVzc2lvbi4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcwotICAgICAgICAgKiB0aGUgZXhwcmVzc2lvbi4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5YUEFUSF9QQVJTRVJfRVJSLAotICAgICAgICAiRXJybyBkdXJhbnRlIG8gcGFyc2luZyBkYSBleHByZXNzXHUwMEUzbyBYUGF0aCAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBbiBlbGVtZW50IGluIHRoZSBzdHlsZXNoZWV0IHJlcXVpcmVzIGEKLSAgICAgICAgICogcGFydGljdWxhciBhdHRyaWJ1dGUgbmFtZWQgYnkgdGhlIHN1YnN0aXR1dGlvbiB0ZXh0LCBidXQgdGhhdAotICAgICAgICAgKiBhdHRyaWJ1dGUgd2FzIG5vdCBzcGVjaWZpZWQgaW4gdGhlIHN0eWxlc2hlZXQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuUkVRVUlSRURfQVRUUl9FUlIsCi0gICAgICAgICJPIGF0cmlidXRvIG9icmlnYXRcdTAwRjNyaW8gJyd7MH0nJyBuXHUwMEUzbyBmb2kgZW5jb250cmFkby4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IGEgY2hhcmFjdGVyIG5vdAotICAgICAgICAgKiBwZXJtaXR0ZWQgaW4gYW4gWFBhdGggZXhwcmVzc2lvbiB3YXMgZW5jb3VudGVyZWQuICBUaGUgc3Vic3RpdHV0aW9uCi0gICAgICAgICAqIHRleHQgaXMgdGhlIG9mZmVuZGluZyBjaGFyYWN0ZXIuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSUxMRUdBTF9DSEFSX0VSUiwKLSAgICAgICAgIkNhcmFjdGVyZSBpbnZcdTAwRTFsaWRvICcnezB9JycgbmEgZXhwcmVzc1x1MDBFM28gWFBhdGguIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEEgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiBpcyBhIG1hcmstdXAgaXRlbSBpbgotICAgICAgICAgKiBhbiBYTUwgZG9jdW1lbnQgdGhhdCByZXF1ZXN0IHNvbWUgYmVoYXZpb3VyIG9mIGFuIFhNTCBwcm9jZXNzb3IuICBUaGUKLSAgICAgICAgICogZm9ybSBvZiB0aGUgbmFtZSBvZiB3YXMgaW52YWxpZCBpbiB0aGlzIGNhc2UsIGFuZCB0aGUgc3Vic3RpdHV0aW9uCi0gICAgICAgICAqIHRleHQgaXMgdGhlIG5hbWUuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSUxMRUdBTF9QSV9FUlIsCi0gICAgICAgICJOb21lIGludlx1MDBFMWxpZG8gJyd7MH0nJyBwYXJhIGluc3RydVx1MDBFN1x1MDBFM28gZGUgcHJvY2Vzc2FtZW50by4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIHJlcG9ydGVkIGlmIHRoZSBzdHlsZXNoZWV0Ci0gICAgICAgICAqIGJlaW5nIHByb2Nlc3NlZCBhdHRlbXB0ZWQgdG8gY29uc3RydWN0IGFuIFhNTCBkb2N1bWVudCB3aXRoIGFuCi0gICAgICAgICAqIGF0dHJpYnV0ZSBpbiBhIHBsYWNlIG90aGVyIHRoYW4gb24gYW4gZWxlbWVudC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICAgKiBzcGVjaWZpZXMgdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5TVFJBWV9BVFRSSUJVVEVfRVJSLAotICAgICAgICAiQXRyaWJ1dG8gJyd7MH0nJyBmb3JhIGRvIGVsZW1lbnRvLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBbiBhdHRyaWJ1dGUgdGhhdCB3YXNuJ3QgcmVjb2duaXplZCB3YXMKLSAgICAgICAgICogc3BlY2lmaWVkIG9uIGFuIGVsZW1lbnQgaW4gdGhlIHN0eWxlc2hlZXQuICBUaGUgYXR0cmlidXRlIGlzIG5hbWVkCi0gICAgICAgICAqIGJ5IHRoZSBzdWJzdGl0dXRpb24KLSAgICAgICAgICogdGV4dC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTExFR0FMX0FUVFJJQlVURV9FUlIsCi0gICAgICAgICJBdHJpYnV0byAnJ3swfScnIGludlx1MDBFMWxpZG8uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJpbXBvcnQiIGFuZCAiaW5jbHVkZSIgYXJlIGtleXdvcmRzIHRoYXQgc2hvdWxkCi0gICAgICAgICAqIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhpcyBtZXNzYWdlcyBpbmRpY2F0ZXMgdGhhdCB0aGUgc3R5bGVzaGVldAotICAgICAgICAgKiBuYW1lZCBpbiB0aGUgc3Vic3RpdHV0aW9uIHRleHQgaW1wb3J0ZWQgb3IgaW5jbHVkZWQgaXRzZWxmIGVpdGhlcgotICAgICAgICAgKiBkaXJlY3RseSBvciBpbmRpcmVjdGx5LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkNJUkNVTEFSX0lOQ0xVREVfRVJSLAotICAgICAgICAiSW1wb3J0L0luY2x1ZGUgY2lyY3VsYXIuIEZvbGhhIGRlIGVzdGlsb3MgJyd7MH0nJyBqXHUwMEUxIGNhcnJlZ2FkYS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQSByZXN1bHQtdHJlZSBmcmFnbWVudCBpcyBhIHBvcnRpb24gb2YgYQotICAgICAgICAgKiByZXN1bHRpbmcgWE1MIGRvY3VtZW50IHJlcHJlc2VudGVkIGFzIGEgdHJlZS4gICI8eHNsOnNvcnQ+IiBpcyBhCi0gICAgICAgICAqIGtleXdvcmQgYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5SRVNVTFRfVFJFRV9TT1JUX0VSUiwKLSAgICAgICAgIk9zIGZyYWdtZW50b3MgZGEgXHUwMEUxcnZvcmUgblx1MDBFM28gcG9kZW0gc2VyIGNsYXNzaWZpY2Fkb3MgKG9zIGVsZW1lbnRvcyA8eHNsOnNvcnQ+IGZvcmFtIGlnbm9yYWRvcykuIFZvY1x1MDBFQSBkZXZlIGNsYXNzaWZpY2FyIG9zIG5cdTAwRjNzIGFvIGNyaWFyIGEgXHUwMEUxcnZvcmUgZGUgcmVzdWx0YWRvcy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQSBuYW1lIGNhbiBiZSBnaXZlbiB0byBhIHBhcnRpY3VsYXIgc3R5bGUgdG8gYmUKLSAgICAgICAgICogdXNlZCB0byBmb3JtYXQgZGVjaW1hbCB2YWx1ZXMuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgZ2l2ZXMgdGhlIG5hbWUKLSAgICAgICAgICogb2Ygc3VjaCBhIHN0eWxlIGZvciB3aGljaCBtb3JlIHRoYW4gb25lIGRlY2xhcmF0aW9uIHdhcyBlbmNvdW50ZXJlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5TWU1CT0xTX1JFREVGX0VSUiwKLSAgICAgICAgIkEgZm9ybWF0YVx1MDBFN1x1MDBFM28gZGVjaW1hbCAnJ3swfScnIGpcdTAwRTEgZm9pIGRlZmluaWRhLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3R5bGVzaGVldCB2ZXJzaW9uIG5hbWVkIGluIHRoZQotICAgICAgICAgKiBzdWJzdGl0dXRpb24gdGV4dCBpcyBub3Qgc3VwcG9ydGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlhTTF9WRVJTSU9OX0VSUiwKLSAgICAgICAgIkEgdmVyc1x1MDBFM28gWFNMIFwiezB9Jycgblx1MDBFM28gXHUwMEU5IHN1cG9ydGFkYSBwb3IgWFNMVEMuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBkZWZpbml0aW9ucyBvZiBvbmUgb3IgbW9yZSB2YXJpYWJsZXMgb3IKLSAgICAgICAgICogcGFyYW1ldGVycyBkZXBlbmQgb24gb25lIGFub3RoZXIuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuQ0lSQ1VMQVJfVkFSSUFCTEVfRVJSLAotICAgICAgICAiUmVmZXJcdTAwRUFuY2lhIGRlIHZhcmlcdTAwRTF2ZWwvcGFyXHUwMEUybWV0cm8gY2lyY3VsYXJlcyAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgb3BlcmF0b3IgaW4gYW4gZXhwcmVzaW9uIHdpdGggdHdvIG9wZXJhbmRzIHdhcwotICAgICAgICAgKiBub3QgcmVjb2duaXplZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTExFR0FMX0JJTkFSWV9PUF9FUlIsCi0gICAgICAgICJPcGVyYWRvciBkZXNjb25oZWNpZG8gcGFyYSBhIGV4cHJlc3NcdTAwRTNvIGJpblx1MDBFMXJpYS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIHByb2R1Y2VkIGlmIGEgcmVmZXJlbmNlIHRvIGEKLSAgICAgICAgICogZnVuY3Rpb24gaGFzIHRvbyBtYW55IG9yIHRvbyBmZXcgYXJndW1lbnRzLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfQVJHX0VSUiwKLSAgICAgICAgIkFyZ3VtZW50byhzKSBpbnZcdTAwRTFsaWRvKHMpIHBhcmEgYSBjaGFtYWRhIGRhIGZ1blx1MDBFN1x1MDBFM28uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJkb2N1bWVudCgpIiBpcyB0aGUgbmFtZSBvZiBmdW5jdGlvbiBhbmQgbXVzdAotICAgICAgICAgKiBub3QgYmUgdHJhbnNsYXRlZC4gIEEgbm9kZS1zZXQgaXMgYSBzZXQgb2YgdGhlIG5vZGVzIGluIHRoZSB0cmVlCi0gICAgICAgICAqIHJlcHJlc2VudGF0aW9uIG9mIGFuIFhNTCBkb2N1bWVudC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5ET0NVTUVOVF9BUkdfRVJSLAotICAgICAgICAiTyBzZWd1bmRvIGFyZ3VtZW50byBwYXJhIGEgZnVuXHUwMEU3XHUwMEUzbyBkb2N1bWVudCgpIGRldmUgc2VyIHVtIGNvbmp1bnRvIGRlIG5cdTAwRjNzLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiPHhzbDp3aGVuPiIgYW5kICI8eHNsOmNob29zZT4iIGFyZSBrZXl3b3JkcwotICAgICAgICAgKiBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhpcyBtZXNzYWdlIGRlc2NyaWJlcyBhIHN5bnRheCBlcnJvcgotICAgICAgICAgKiBpbiB0aGUgc3R5bGVzaGVldC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5NSVNTSU5HX1dIRU5fRVJSLAotICAgICAgICAiXHUwMEM5IG5lY2Vzc1x1MDBFMXJpbywgcGVsbyBtZW5vcywgdW0gZWxlbWVudG8gPHhzbDp3aGVuPiBlbSA8eHNsOmNob29zZT4uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICI8eHNsOm90aGVyd2lzZT4iIGFuZCAiPHhzbDpjaG9vc2U+IiBhcmUKLSAgICAgICAgICoga2V5d29yZHMgYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoaXMgbWVzc2FnZSBkZXNjcmliZXMgYQotICAgICAgICAgKiBzeW50YXggZXJyb3IgaW4gdGhlIHN0eWxlc2hlZXQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTVVMVElQTEVfT1RIRVJXSVNFX0VSUiwKLSAgICAgICAgIlx1MDBDOSBwZXJtaXRpZG8gc29tZW50ZSB1bSBlbGVtZW50byA8eHNsOm90aGVyd2lzZT4gZW0gPHhzbDpjaG9vc2U+LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiPHhzbDpvdGhlcndpc2U+IiBhbmQgIjx4c2w6Y2hvb3NlPiIgYXJlCi0gICAgICAgICAqIGtleXdvcmRzIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGlzIG1lc3NhZ2UgZGVzY3JpYmVzIGEKLSAgICAgICAgICogc3ludGF4IGVycm9yIGluIHRoZSBzdHlsZXNoZWV0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlNUUkFZX09USEVSV0lTRV9FUlIsCi0gICAgICAgICI8eHNsOm90aGVyd2lzZT4gc1x1MDBGMyBwb2RlIHNlciB1c2FkbyBlbSA8eHNsOmNob29zZT4uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICI8eHNsOndoZW4+IiBhbmQgIjx4c2w6Y2hvb3NlPiIgYXJlIGtleXdvcmRzCi0gICAgICAgICAqIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGlzIG1lc3NhZ2UgZGVzY3JpYmVzIGEgc3ludGF4IGVycm9yCi0gICAgICAgICAqIGluIHRoZSBzdHlsZXNoZWV0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlNUUkFZX1dIRU5fRVJSLAotICAgICAgICAiPHhzbDp3aGVuPiBzXHUwMEYzIHBvZGUgc2VyIHVzYWRvIGVtIDx4c2w6Y2hvb3NlPi4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIjx4c2w6d2hlbj4iLCAiPHhzbDpvdGhlcndpc2U+IiBhbmQKLSAgICAgICAgICogIjx4c2w6Y2hvb3NlPiIgYXJlIGtleXdvcmRzIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGlzCi0gICAgICAgICAqIG1lc3NhZ2UgZGVzY3JpYmVzIGEgc3ludGF4IGVycm9yIGluIHRoZSBzdHlsZXNoZWV0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLldIRU5fRUxFTUVOVF9FUlIsCi0gICAgICAgICJTb21lbnRlIG9zIGVsZW1lbnRvcyA8eHNsOndoZW4+IGUgPHhzbDpvdGhlcndpc2U+IHNcdTAwRTNvIHBlcm1pdGlkb3MgZW0gPHhzbDpjaG9vc2U+LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiPHhzbDphdHRyaWJ1dGUtc2V0PiIgYW5kICJuYW1lIiBhcmUga2V5d29yZHMKLSAgICAgICAgICogdGhhdCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVU5OQU1FRF9BVFRSSUJTRVRfRVJSLAotICAgICAgICAiPHhzbDphdHRyaWJ1dGUtc2V0PiBuXHUwMEUzbyBlbmNvbnRyYWRvIG5vIGF0cmlidXRvICduYW1lJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQW4gZWxlbWVudCBpbiB0aGUgc3R5bGVzaGVldCBjb250YWluZWQgYW4KLSAgICAgICAgICogZWxlbWVudCBvZiBhIHR5cGUgdGhhdCBpdCB3YXMgbm90IHBlcm1pdHRlZCB0byBjb250YWluLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfQ0hJTERfRVJSLAotICAgICAgICAiRWxlbWVudG8gZmlsaG8gaW52XHUwMEUxbGlkby4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN0eWxlc2hlZXQgdHJpZWQgdG8gY3JlYXRlIGFuIGVsZW1lbnQgd2l0aAotICAgICAgICAgKiBhIG5hbWUgdGhhdCB3YXMgbm90IGEgdmFsaWQgWE1MIG5hbWUuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgY29udGFpbnMKLSAgICAgICAgICogdGhlIG5hbWUuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSUxMRUdBTF9FTEVNX05BTUVfRVJSLAotICAgICAgICAiVm9jXHUwMEVBIG5cdTAwRTNvIHBvZGUgY2hhbWFyIHVtIGVsZW1lbnRvICcnezB9JycifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN0eWxlc2hlZXQgdHJpZWQgdG8gY3JlYXRlIGFuIGF0dHJpYnV0ZQotICAgICAgICAgKiB3aXRoIGEgbmFtZSB0aGF0IHdhcyBub3QgYSB2YWxpZCBYTUwgbmFtZS4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICAgKiBjb250YWlucyB0aGUgbmFtZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTExFR0FMX0FUVFJfTkFNRV9FUlIsCi0gICAgICAgICJWb2NcdTAwRUEgblx1MDBFM28gcG9kZSBjaGFtYXIgdW0gYXRyaWJ1dG8gJyd7MH0nJyJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgY2hpbGRyZW4gb2YgdGhlIG91dGVybW9zdCBlbGVtZW50IG9mIGEKLSAgICAgICAgICogc3R5bGVzaGVldCBhcmUgcmVmZXJyZWQgdG8gYXMgdG9wLWxldmVsIGVsZW1lbnRzLiAgTm8gdGV4dCBzaG91bGQKLSAgICAgICAgICogb2NjdXIgd2l0aGluIHRoYXQgb3V0ZXJtb3N0IGVsZW1lbnQgdW5sZXNzIGl0IGlzIHdpdGhpbiBhIHRvcC1sZXZlbAotICAgICAgICAgKiBlbGVtZW50LiAgVGhpcyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoYXQgY29uc3RyYWludCB3YXMgdmlvbGF0ZWQuCi0gICAgICAgICAqICI8eHNsOnN0eWxlc2hlZXQ+IiBpcyBhIGtleXdvcmQgdGhhdCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSUxMRUdBTF9URVhUX05PREVfRVJSLAotICAgICAgICAiRGFkb3MgZGUgdGV4dG8gZm9yYSBkbyBlbGVtZW50byA8eHNsOnN0eWxlc2hlZXQ+IGRlIG5cdTAwRUR2ZWwgc3VwZXJpb3IuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEpBWFAgaXMgYW4gYWNyb255bSBmb3IgdGhlIEphdmEgQVBJIGZvciBYTUwKLSAgICAgICAgICogUHJvY2Vzc2luZy4gIFRoaXMgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUgWE1MIHBhcnNlciBwcm92aWRlZCB0bwotICAgICAgICAgKiBYU0xUQyB0byBwcm9jZXNzIHRoZSBYTUwgaW5wdXQgZG9jdW1lbnQgaGFkIGEgY29uZmlndXJhdGlvbiBwcm9ibGVtLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlNBWF9QQVJTRVJfQ09ORklHX0VSUiwKLSAgICAgICAgIlBhcnNlciBkZSBKQVhQIG5cdTAwRTNvIGNvbmZpZ3VyYWRvIGNvcnJldGFtZW50ZSJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgbmFtZXMgdGhlIGludGVybmFsIGVycm9yCi0gICAgICAgICAqIGVuY291bnRlcmVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklOVEVSTkFMX0VSUiwKLSAgICAgICAgIkVycm8gaW50ZXJuby1YU0xUQyBpcnJlY3VwZXJcdTAwRTF2ZWw6ICcnezB9JycifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN0eWxlc2hlZXQgY29udGFpbmVkIGFuIGVsZW1lbnQgdGhhdCB3YXMKLSAgICAgICAgICogbm90IHJlY29nbml6ZWQgYXMgcGFydCBvZiB0aGUgWFNMIHN5bnRheC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICAgKiBnaXZlcyB0aGUgZWxlbWVudCBuYW1lLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlVOU1VQUE9SVEVEX1hTTF9FUlIsCi0gICAgICAgICJFbGVtZW50byBYU0wgblx1MDBFM28gc3Vwb3J0YWRvICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IHJlZmVycmVkIHRvIGFuIGV4dGVuc2lvbiB0byB0aGUKLSAgICAgICAgICogWFNMIHN5bnRheCBhbmQgaW5kaWNhdGVkIHRoYXQgaXQgd2FzIGRlZmluZWQgYnkgWFNMVEMsIGJ1dCBYU1RMQyBkb2VzCi0gICAgICAgICAqIG5vdCByZWNvZ25pemVkIHRoZSBwYXJ0aWN1bGFyIGV4dGVuc2lvbiBuYW1lZC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICAgKiBnaXZlcyB0aGUgZXh0ZW5zaW9uIG5hbWUuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVU5TVVBQT1JURURfRVhUX0VSUiwKLSAgICAgICAgIkV4dGVuc1x1MDBFM28gZGUgWFNMVEMgblx1MDBFM28gcmVjb25oZWNpZGEgJyd7MH0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIFhNTCBkb2N1bWVudCBnaXZlbiB0byBYU0xUQyBhcyBhIHN0eWxlc2hlZXQKLSAgICAgICAgICogd2FzIG5vdCwgaW4gZmFjdCwgYSBzdHlsZXNoZWV0LiAgWFNMVEMgaXMgYWJsZSB0byBkZXRlY3QgdGhhdCBpbiB0aGlzCi0gICAgICAgICAqIGNhc2UgYmVjYXVzZSB0aGUgb3V0ZXJtb3N0IGVsZW1lbnQgaW4gdGhlIHN0eWxlc2hlZXQgaGFzIHRvIGJlCi0gICAgICAgICAqIGRlY2xhcmVkIHdpdGggcmVzcGVjdCB0byB0aGUgWFNMIG5hbWVzcGFjZSBVUkksIGJ1dCBubyBkZWNsYXJhdGlvbgotICAgICAgICAgKiBmb3IgdGhhdCBuYW1lc3BhY2Ugd2FzIHNlZW4uCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTUlTU0lOR19YU0xUX1VSSV9FUlIsCi0gICAgICAgICJPIGRvY3VtZW50byBkZSBlbnRyYWRhIG5cdTAwRTNvIFx1MDBFOSB1bWEgZm9saGEgZGUgZXN0aWxvcyAobyBuYW1lc3BhY2UgWFNMIG5cdTAwRTNvIGZvaSBkZWNsYXJhZG8gbm8gZWxlbWVudG8tcmFpeikuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFhTTFRDIGNvdWxkIG5vdCBmaW5kIHRoZSBzdHlsZXNoZWV0IGRvY3VtZW50Ci0gICAgICAgICAqIHdpdGggdGhlIG5hbWUgc3BlY2lmaWVkIGJ5IHRoZSBzdWJzdGl0dXRpb24gdGV4dC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5NSVNTSU5HX1hTTFRfVEFSR0VUX0VSUiwKLSAgICAgICAgIk5cdTAwRTNvIGZvaSBwb3NzXHUwMEVEdmVsIGxvY2FsaXphciBvIGFsdm8gZGEgZm9saGEgZGUgZXN0aWxvcyAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBhY2Nlc3MgdG8gdGhlIHN0eWxlc2hlZXQgdGFyZ2V0IGlzIGRlbmllZAotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkFDQ0VTU0lOR19YU0xUX1RBUkdFVF9FUlIsCi0gICAgICAgICJOXHUwMEUzbyBmb2kgcG9zc1x1MDBFRHZlbCBsZXIgbyBhbHZvICcnezB9JycgZGEgZm9saGEgZGUgZXN0aWxvcywgcG9ycXVlIG8gYWNlc3NvIGEgJyd7MX0nJyBuXHUwMEUzbyBcdTAwRTkgcGVybWl0aWRvIGVtIHZpcnR1ZGUgZGEgcmVzdHJpXHUwMEU3XHUwMEUzbyBkZWZpbmlkYSBwZWxhIHByb3ByaWVkYWRlIGFjY2Vzc0V4dGVybmFsU3R5bGVzaGVldC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIHJlcHJlc2VudHMgYW4gaW50ZXJuYWwgZXJyb3IgaW4KLSAgICAgICAgICogY29uZGl0aW9uIGluIFhTTFRDLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBjbGFzcyBuYW1lIGluIFhTTFRDCi0gICAgICAgICAqIHRoYXQgaXMgbWlzc2luZyBzb21lIGZ1bmN0aW9uYWxpdHkuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTk9UX0lNUExFTUVOVEVEX0VSUiwKLSAgICAgICAgIk5cdTAwRTNvIGltcGxlbWVudGFkbzogJyd7MH0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIFhNTCBkb2N1bWVudCBnaXZlbiB0byBYU0xUQyBhcyBhIHN0eWxlc2hlZXQKLSAgICAgICAgICogd2FzIG5vdCwgaW4gZmFjdCwgYSBzdHlsZXNoZWV0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk5PVF9TVFlMRVNIRUVUX0VSUiwKLSAgICAgICAgIk8gZG9jdW1lbnRvIGRlIGVudHJhZGEgblx1MDBFM28gY29udFx1MDBFOW0gdW1hIGZvbGhhIGRlIGVzdGlsb3MgWFNMLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZWxlbWVudCBuYW1lZCBpbiB0aGUgc3Vic3RpdHV0aW9uIHRleHQgd2FzCi0gICAgICAgICAqIGVuY291bnRlcmVkIGluIHRoZSBzdHlsZXNoZWV0IGJ1dCBpcyBub3QgcmVjb2duaXplZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5FTEVNRU5UX1BBUlNFX0VSUiwKLSAgICAgICAgIk5cdTAwRTNvIGZvaSBwb3NzXHUwMEVEdmVsIGZhemVyIHBhcnNpbmcgZG8gZWxlbWVudG8gJyd7MH0nJyJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAidXNlIiwgIjxrZXk+IiwgIm5vZGUiLCAibm9kZS1zZXQiLCAic3RyaW5nIgotICAgICAgICAgKiBhbmQgIm51bWJlciIgYXJlIGtleXdvcmRzIGluIHRoaXMgY29udGV4dCBhbmQgc2hvdWxkIG5vdCBiZQotICAgICAgICAgKiB0cmFuc2xhdGVkLiAgVGhpcyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoZSB2YWx1ZSBvZiB0aGUgInVzZSIKLSAgICAgICAgICogYXR0cmlidXRlIHdhcyBub3Qgb25lIG9mIHRoZSBwZXJtaXR0ZWQgdmFsdWVzLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLktFWV9VU0VfQVRUUl9FUlIsCi0gICAgICAgICJPIGF0cmlidXRvIHVzZSBkZSA8a2V5PiBkZXZlIHNlciBub2RlLCBub2RlLXNldCwgc3RyaW5nIG91IG51bWJlci4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQW4gWE1MIGRvY3VtZW50IGNhbiBzcGVjaWZ5IHRoZSB2ZXJzaW9uIG9mIHRoZQotICAgICAgICAgKiBYTUwgc3BlY2lmaWNhdGlvbiB0byB3aGljaCBpdCBhZGhlcmVzLiAgVGhpcyBtZXNzYWdlIGluZGljYXRlcyB0aGF0Ci0gICAgICAgICAqIHRoZSB2ZXJzaW9uIHNwZWNpZmllZCBmb3IgdGhlIG91dHB1dCBkb2N1bWVudCB3YXMgbm90IHZhbGlkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk9VVFBVVF9WRVJTSU9OX0VSUiwKLSAgICAgICAgIkEgdmVyc1x1MDBFM28gZG8gZG9jdW1lbnRvIFhNTCBkZSBzYVx1MDBFRGRhIGRldmUgc2VyIDEuMCJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgb3BlcmF0b3IgaW4gYSBjb21wYXJpc29uIG9wZXJhdGlvbiB3YXMKLSAgICAgICAgICogbm90IHJlY29nbml6ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSUxMRUdBTF9SRUxBVF9PUF9FUlIsCi0gICAgICAgICJPcGVyYVx1MDBFN1x1MDBFM28gZGVzY29uaGVjaWRhIHBhcmEgYSBleHByZXNzXHUwMEUzbyByZWxhY2lvbmFsIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIGF0dHJpYnV0ZSBzZXQgZGVmaW5lcyBhcyBhIHNldCBvZiBYTUwKLSAgICAgICAgICogYXR0cmlidXRlcyB0aGF0IGNhbiBiZSBhZGRlZCB0byBhbiBlbGVtZW50IGluIHRoZSBvdXRwdXQgWE1MIGRvY3VtZW50Ci0gICAgICAgICAqIGFzIGEgZ3JvdXAuICBUaGlzIG1lc3NhZ2UgaXMgcmVwb3J0ZWQgaWYgdGhlIG5hbWUgc3BlY2lmaWVkIHdhcyBub3QKLSAgICAgICAgICogdXNlZCB0byBkZWNsYXJlIGFuIGF0dHJpYnV0ZSBzZXQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUKLSAgICAgICAgICogdGhhdCBpcyBpbiBlcnJvci4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5BVFRSSUJTRVRfVU5ERUZfRVJSLAotICAgICAgICAiVGVudGF0aXZhIGRlIHVzYXIgdW0gY29uanVudG8gZGUgYXRyaWJ1dG9zICcnezB9Jycgblx1MDBFM28gZXhpc3RlbnRlLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgdGVybSAiYXR0cmlidXRlIHZhbHVlIHRlbXBsYXRlIiBpcyBhIHRlcm0KLSAgICAgICAgICogZGVmaW5lZCBieSBYU0xUIHdoaWNoIGRlc2NyaWJlcyB0aGUgdmFsdWUgb2YgYW4gYXR0cmlidXRlIHRoYXQgaXMKLSAgICAgICAgICogZGV0ZXJtaW5lZCBieSBhbiBYUGF0aCBleHByZXNzaW9uLiAgVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhlCi0gICAgICAgICAqIGV4cHJlc3Npb24gd2FzIHN5bnRhY3RpY2FsbHkgaW5jb3JyZWN0OyB0aGUgc3Vic3RpdHV0aW9uIHRleHQKLSAgICAgICAgICogY29udGFpbnMgdGhlIGV4cHJlc3Npb24gdGhhdCB3YXMgaW4gZXJyb3IuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuQVRUUl9WQUxfVEVNUExBVEVfRVJSLAotICAgICAgICAiTlx1MDBFM28gXHUwMEU5IHBvc3NcdTAwRUR2ZWwgZmF6ZXIgcGFyc2luZyBkbyBtb2RlbG8gZG8gdmFsb3IgZG8gYXRyaWJ1dG8gJyd7MH0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgPz8/Ci0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVU5LTk9XTl9TSUdfVFlQRV9FUlIsCi0gICAgICAgICJUaXBvIGRlIGRhZG9zIGRlc2NvbmhlY2lkbyBuYSBhc3NpbmF0dXJhIGRhIGNsYXNzZSAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgcmVmZXJzIHRvIGRhdGEgdHlwZXMuCi0gICAgICAgICAqIFRoZSBtZXNzYWdlIGlzIGRpc3BsYXllZCBpZiBhIHZhbHVlIGluIGEgcGFydGljdWxhciBjb250ZXh0IG5lZWRzIHRvCi0gICAgICAgICAqIGJlIGNvbnZlcnRlZCB0byB0eXBlIHsxfSwgYnV0IHRoYXQncyBub3QgcG9zc2libGUgZm9yIGEgdmFsdWUgb2YKLSAgICAgICAgICogdHlwZSB7MH0uCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuREFUQV9DT05WRVJTSU9OX0VSUiwKLSAgICAgICAgIk5cdTAwRTNvIFx1MDBFOSBwb3NzXHUwMEVEdmVsIGNvbnZlcnRlciBvIHRpcG8gZGUgZGFkb3MgJyd7MH0nJyBlbSAnJ3sxfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiVGVtcGxhdGVzIiBpcyBhIEphdmEgY2xhc3MgbmFtZSB0aGF0IHNob3VsZAotICAgICAgICAgKiBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5OT19UUkFOU0xFVF9DTEFTU19FUlIsCi0gICAgICAgICJFc3RlIFRlbXBsYXRlcyBuXHUwMEUzbyBjb250XHUwMEU5bSB1bWEgZGVmaW5pXHUwMEU3XHUwMEUzbyBkZSBjbGFzc2UgdHJhbnNsZXQgdlx1MDBFMWxpZGEuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJUZW1wbGF0ZXMiIGlzIGEgSmF2YSBjbGFzcyBuYW1lIHRoYXQgc2hvdWxkCi0gICAgICAgICAqIG5vdCBiZSB0cmFuc2xhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk5PX01BSU5fVFJBTlNMRVRfRVJSLAotICAgICAgICAiRXN0ZSBUZW1wbGF0ZXMgblx1MDBFM28gY29udFx1MDBFOW0gdW1hIGNsYXNzZSBjb20gbyBub21lICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBhIGNsYXNzLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlRSQU5TTEVUX0NMQVNTX0VSUiwKLSAgICAgICAgIk5cdTAwRTNvIGZvaSBwb3NzXHUwMEVEdmVsIGNhcnJlZ2FyIGEgY2xhc3NlIHRyYW5zbGV0ICcnezB9JycuIn0sCi0KLSAgICAgICAge0Vycm9yTXNnLlRSQU5TTEVUX09CSkVDVF9FUlIsCi0gICAgICAgICJDbGFzc2UgdHJhbnNsZXQgY2FycmVnYWRhLCBtYXMgblx1MDBFM28gXHUwMEU5IHBvc3NcdTAwRUR2ZWwgY3JpYXIgdW1hIGluc3RcdTAwRTJuY2lhIHRyYW5zbGV0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiRXJyb3JMaXN0ZW5lciIgaXMgYSBKYXZhIGludGVyZmFjZSBuYW1lIHRoYXQKLSAgICAgICAgICogc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhlIHVzZXIgdHJpZWQKLSAgICAgICAgICogdG8gc2V0IGFuIEVycm9yTGlzdGVuZXIgb2JqZWN0IG9uIG9iamVjdCBvZiB0aGUgY2xhc3MgbmFtZWQgaW4gdGhlCi0gICAgICAgICAqIHN1YnN0aXR1dGlvbiB0ZXh0IHdpdGggIm51bGwiIEphdmEgdmFsdWUuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuRVJST1JfTElTVEVORVJfTlVMTF9FUlIsCi0gICAgICAgICJUZW50YXRpdmEgZGUgZGVmaW5pciBFcnJvckxpc3RlbmVyIHBhcmEgJyd7MH0nJyBjb21vIG51bG8ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgU3RyZWFtU291cmNlLCBTQVhTb3VyY2UgYW5kIERPTVNvdXJjZSBhcmUgSmF2YQotICAgICAgICAgKiBpbnRlcmZhY2UgbmFtZXMgdGhhdCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSkFYUF9VTktOT1dOX1NPVVJDRV9FUlIsCi0gICAgICAgICJTb21lbnRlIFN0cmVhbVNvdXJjZSwgU0FYU291cmNlIGUgRE9NU291cmNlIHNcdTAwRTNvIHN1cG9ydGFkb3MgcG9yIFhTTFRDIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJTb3VyY2UiIGlzIGEgSmF2YSBjbGFzcyBuYW1lIHRoYXQgc2hvdWxkIG5vdAotICAgICAgICAgKiBiZSB0cmFuc2xhdGVkLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIEphdmEgbWV0aG9kLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfTk9fU09VUkNFX0VSUiwKLSAgICAgICAgIk8gb2JqZXRvIHNvdXJjZSBlc3BlY2lmaWNhZG8gcGFyYSAnJ3swfScnIG5cdTAwRTNvIHRlbSBjb250ZVx1MDBGQWRvLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCBYU0xUQyBmYWlsZWQgdG8KLSAgICAgICAgICogY29tcGlsZSB0aGUgc3R5bGVzaGVldCBpbnRvIGEgdHJhbnNsZXQgKGNsYXNzIGZpbGUpLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfQ09NUElMRV9FUlIsCi0gICAgICAgICJOXHUwMEUzbyBmb2kgcG9zc1x1MDBFRHZlbCBjb21waWxhciBhIGZvbGhhIGRlIGVzdGlsb3MifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIlRyYW5zZm9ybWVyRmFjdG9yeSIgaXMgYSBjbGFzcyBuYW1lLiAgSW4gdGhpcwotICAgICAgICAgKiBjb250ZXh0LCBhbiBhdHRyaWJ1dGUgaXMgYSBwcm9wZXJ0eSBvciBzZXR0aW5nIG9mIHRoZQotICAgICAgICAgKiBUcmFuc2Zvcm1lckZhY3Rvcnkgb2JqZWN0LiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIHRoZQotICAgICAgICAgKiB1bnJlY29nbmlzZWQgYXR0cmlidXRlLiAgVGhlIG1ldGhvZCB1c2VkIHRvIHJldHJpZXZlIHRoZSBhdHRyaWJ1dGUgaXMKLSAgICAgICAgICogImdldEF0dHJpYnV0ZSIsIHNvIGl0J3Mgbm90IGNsZWFyIHdoZXRoZXIgaXQgd291bGQgYmUgYmVzdCB0bwotICAgICAgICAgKiB0cmFuc2xhdGUgdGhlIHRlcm0gImF0dHJpYnV0ZSIuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSkFYUF9JTlZBTElEX0FUVFJfRVJSLAotICAgICAgICAiVHJhbnNmb3JtZXJGYWN0b3J5IG5cdTAwRTNvIHJlY29uaGVjZSBvIGF0cmlidXRvICcnezB9JycuIn0sCi0KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfSU5WQUxJRF9BVFRSX1ZBTFVFX0VSUiwKLSAgICAgICAgIlZhbG9yIGluY29ycmV0byBlc3BlY2lmaWNhZG8gcGFyYSBvIGF0cmlidXRvICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJzZXRSZXN1bHQoKSIgYW5kICJzdGFydERvY3VtZW50KCkiIGFyZSBKYXZhCi0gICAgICAgICAqIG1ldGhvZCBuYW1lcyB0aGF0IHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX1NFVF9SRVNVTFRfRVJSLAotICAgICAgICAic2V0UmVzdWx0KCkgZGV2ZSBzZXIgY2hhbWFkbyBhbnRlcyBkZSBzdGFydERvY3VtZW50KCkuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJUcmFuc2Zvcm1lciIgaXMgYSBKYXZhIGludGVyZmFjZSBuYW1lIHRoYXQKLSAgICAgICAgICogc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgQSBUcmFuc2Zvcm1lciBvYmplY3Qgc2hvdWxkIGNvbnRhaW5lZCBhCi0gICAgICAgICAqIHJlZmVyZW5jZSB0byBhIHRyYW5zbGV0IG9iamVjdCBpbiBvcmRlciB0byBiZSB1c2VkIGZvcgotICAgICAgICAgKiB0cmFuc2Zvcm1hdGlvbnM7IHRoaXMgbWVzc2FnZSBpcyBwcm9kdWNlZCBpZiB0aGF0IHJlcXVpcmVtZW50IGlzIG5vdAotICAgICAgICAgKiBtZXQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSkFYUF9OT19UUkFOU0xFVF9FUlIsCi0gICAgICAgICJPIFRyYW5zZm9ybWVyIG5cdTAwRTNvIHRlbSB1bSBvYmpldG8gdHJhbnNsZXQgZW5jYXBzdWxhZG8uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBYTUwgZG9jdW1lbnQgdGhhdCByZXN1bHRzIGZyb20gYQotICAgICAgICAgKiB0cmFuc2Zvcm1hdGlvbiBuZWVkcyB0byBiZSBzZW50IHRvIGFuIG91dHB1dCBoYW5kbGVyIG9iamVjdDsgdGhpcwotICAgICAgICAgKiBtZXNzYWdlIGlzIHByb2R1Y2VkIGlmIHRoYXQgcmVxdWlyZW1lbnQgaXMgbm90IG1ldC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX05PX0hBTkRMRVJfRVJSLAotICAgICAgICAiTmVuaHVtIGhhbmRsZXIgZGUgc2FcdTAwRURkYSBkZWZpbmlkbyBwYXJhIG8gcmVzdWx0YWRvIGRhIHRyYW5zZm9ybWFcdTAwRTdcdTAwRTNvLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiUmVzdWx0IiBpcyBhIEphdmEgaW50ZXJmYWNlIG5hbWUgaW4gdGhpcwotICAgICAgICAgKiBjb250ZXh0LiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIGEgbWV0aG9kIG5hbWUuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSkFYUF9OT19SRVNVTFRfRVJSLAotICAgICAgICAiTyBvYmpldG8gcmVzdWx0IGVzcGVjaWZpY2FkbyBwYXJhICcnezB9JycgXHUwMEU5IGludlx1MDBFMWxpZG8uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJUcmFuc2Zvcm1lciIgaXMgYSBKYXZhIGludGVyZmFjZSBuYW1lLiAgVGhlCi0gICAgICAgICAqIHVzZXIncyBwcm9ncmFtIGF0dGVtcHRlZCB0byBhY2Nlc3MgYW4gdW5yZWNvZ25pemVkIHByb3BlcnR5IHdpdGggdGhlCi0gICAgICAgICAqIG5hbWUgc3BlY2lmaWVkIGluIHRoZSBzdWJzdGl0dXRpb24gdGV4dC4gIFRoZSBtZXRob2QgdXNlZCB0byByZXRyaWV2ZQotICAgICAgICAgKiB0aGUgcHJvcGVydHkgaXMgImdldE91dHB1dFByb3BlcnR5Iiwgc28gaXQncyBub3QgY2xlYXIgd2hldGhlciBpdAotICAgICAgICAgKiB3b3VsZCBiZSBiZXN0IHRvIHRyYW5zbGF0ZSB0aGUgdGVybSAicHJvcGVydHkiLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfVU5LTk9XTl9QUk9QX0VSUiwKLSAgICAgICAgIlRlbnRhdGl2YSBkZSBhY2Vzc2FyIGEgcHJvcHJpZWRhZGUgJyd7MH0nJyBkbyBUcmFuc2Zvcm1lciBpbnZcdTAwRTFsaWRhLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBTQVgyRE9NIGlzIHRoZSBuYW1lIG9mIGEgSmF2YSBjbGFzcyB0aGF0IHNob3VsZAotICAgICAgICAgKiBub3QgYmUgdHJhbnNsYXRlZC4gIFRoaXMgaXMgYW4gYWRhcHRlciBpbiB0aGUgc2Vuc2UgdGhhdCBpdCB0YWtlcyBhCi0gICAgICAgICAqIERPTSBvYmplY3QgYW5kIGNvbnZlcnRzIGl0IHRvIHNvbWV0aGluZyB0aGF0IHVzZXMgdGhlIFNBWCBBUEkuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuU0FYMkRPTV9BREFQVEVSX0VSUiwKLSAgICAgICAgIk5cdTAwRTNvIGZvaSBwb3NzXHUwMEVEdmVsIGNyaWFyIG8gYWRhcHRhZG9yIFNBWDJET006ICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJYU0xUQ1NvdXJjZS5idWlsZCgpIiBpcyBhIEphdmEgbWV0aG9kIG5hbWUuCi0gICAgICAgICAqICJzeXN0ZW1JZCIgaXMgYW4gWE1MIHRlcm0gdGhhdCBpcyBzaG9ydCBmb3IgInN5c3RlbSBpZGVudGlmaWNhdGlvbiIuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuWFNMVENfU09VUkNFX0VSUiwKLSAgICAgICAgIlhTTFRDU291cmNlLmJ1aWxkKCkgY2hhbWFkbyBzZW0gbyBzeXN0ZW1JZCBzZXIgZGVmaW5pZG8uIn0sCi0KLSAgICAgICAgeyBFcnJvck1zZy5FUl9SRVNVTFRfTlVMTCwKLSAgICAgICAgICAgICJPIHJlc3VsdGFkbyBuXHUwMEUzbyBkZXZlIHNlciBudWxvIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUgdmFsdWUgYXJndW1lbnQKLSAgICAgICAgICogb2Ygc2V0UGFyYW1ldGVyIG11c3QgYmUgYSB2YWxpZCBKYXZhIE9iamVjdC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX0lOVkFMSURfU0VUX1BBUkFNX1ZBTFVFLAotICAgICAgICAiTyB2YWxvciBkbyBwYXJcdTAwRTJtZXRybyB7MH0gZGV2ZSBzZXIgdW0gT2JqZXRvIEphdmEgdlx1MDBFMWxpZG8ifSwKLQotCi0gICAgICAgIHtFcnJvck1zZy5DT01QSUxFX1NURElOX0VSUiwKLSAgICAgICAgIkEgb3BcdTAwRTdcdTAwRTNvIC1pIGRldmUgc2VyIHVzYWRhIGNvbSBhIG9wXHUwMEU3XHUwMEUzbyAtby4ifSwKLQotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgY29udGFpbnMgdXNhZ2UgaW5mb3JtYXRpb24gZm9yIGEKLSAgICAgICAgICogbWVhbnMgb2YgaW52b2tpbmcgWFNMVEMgZnJvbSB0aGUgY29tbWFuZC1saW5lLiAgVGhlIG1lc3NhZ2UgaXMKLSAgICAgICAgICogZm9ybWF0dGVkIGZvciBwcmVzZW50YXRpb24gaW4gRW5nbGlzaC4gIFRoZSBzdHJpbmdzIDxvdXRwdXQ+LAotICAgICAgICAgKiA8ZGlyZWN0b3J5PiwgZXRjLiBpbmRpY2F0ZSB1c2VyLXNwZWNpZmllZCBhcmd1bWVudCB2YWx1ZXMsIGFuZCBjYW4KLSAgICAgICAgICogYmUgdHJhbnNsYXRlZCAtIHRoZSBhcmd1bWVudCA8cGFja2FnZT4gcmVmZXJzIHRvIGEgSmF2YSBwYWNrYWdlLCBzbwotICAgICAgICAgKiBpdCBzaG91bGQgYmUgaGFuZGxlZCBpbiB0aGUgc2FtZSB3YXkgdGhlIHRlcm0gaXMgaGFuZGxlZCBmb3IgSkRLCi0gICAgICAgICAqIGRvY3VtZW50YXRpb24uCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuQ09NUElMRV9VU0FHRV9TVFIsCi0gICAgICAgICJTSU5PUFNFXG4gICBqYXZhIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jbWRsaW5lLkNvbXBpbGUgWy1vIDxzYVx1MDBFRGRhPl1cbiAgICAgIFstZCA8ZGlyZXRcdTAwRjNyaW8+XSBbLWogPGphcmZpbGU+XSBbLXAgPHBhY290ZT5dXG4gICAgICBbLW5dIFsteF0gWy11XSBbLXZdIFstaF0geyA8Zm9saGEgZGUgZXN0aWxvcz4gfCAtaSB9XG5cbk9QXHUwMEM3XHUwMEQ1RVNcbiAgIC1vIDxzYVx1MDBFRGRhPiAgICBhdHJpYnVpIG8gbm9tZSA8c2FcdTAwRURkYT4gYW8gdHJhbnNsZXRcbiAgICAgICAgICAgICAgICAgIGdlcmFkby4gIFBvciBwYWRyXHUwMEUzbywgbyBub21lIHRyYW5zbGV0XG4gICAgICAgICAgICAgICAgICBvcmlnaW5hLXNlIGRvIG5vbWUgPGZvbGhhIGRlIGVzdGlsb3M+LiAgRXN0YSBvcFx1MDBFN1x1MDBFM29cbiAgICAgICAgICAgICAgICAgIFx1MDBFOSBpZ25vcmFkYSBjYXNvIHNlamFtIGNvbXBpbGFkYXMgdlx1MDBFMXJpYXMgZm9saGFzIGRlIGVzdGlsb3MuXG4gICAtZCA8ZGlyZXRcdTAwRjNyaW8+IGVzcGVjaWZpY2EgdW0gZGlyZXRcdTAwRjNyaW8gZGUgZGVzdGlubyBwYXJhIHRyYW5zbGV0XG4gICAtaiA8YXJxdWl2byBqYXI+ICAgZW1wYWNvdGEgYXMgY2xhc3NlcyB0cmFuc2xldCBlbSB1bSBhcnF1aXZvIGphciBkb1xuICAgICAgICAgICAgICAgICAgbm9tZSBlc3BlY2lmaWNhZG8gY29tbyA8YXJxdWl2byBqYXI+XG4gICAtcCA8cGFjb3RlPiAgIGVzcGVjaWZpY2EgdW0gcHJlZml4byBkZSBub21lIGRvIHBhY290ZSBwYXJhIHRvZGFzIGFzIGNsYXNzZXNcbiAgICAgICAgICAgICAgICAgIHRyYW5zbGV0IGdlcmFkYXMuXG4gICAtbiAgICAgICAgICAgICBwZXJtaXRlIGEgaW5jbHVzXHUwMEUzbyBkbyBtb2RlbG8gbmEgbGluaGEgKGNvbXBvcnRhbWVudG8gcGFkclx1MDBFM28gbWVsaG9yXG4gICAgICAgICAgICAgICAgICBlbSBtXHUwMEU5ZGlhKS5cbiAgIC14ICAgICAgICAgICAgIGF0aXZhIGEgc2FcdTAwRURkYSBkZSBtZW5zYWdlbnMgZGUgZGVwdXJhXHUwMEU3XHUwMEUzbyBhZGljaW9uYWlzXG4gICAtdSAgICAgICAgICAgICBpbnRlcnByZXRhIG9zIGFyZ3VtZW50b3MgPGZvbGhhIGRlIGVzdGlsb3M+IGNvbW8gVVJMc1xuICAgLWkgICAgICAgICAgICAgb2JyaWdhIG8gY29tcGlsYWRvciBhIGxlciBhIGZvbGhhIGRlIGVzdGlsb3MgZGUgc3RkaW5cbiAgIC12ICAgICAgICAgICAgIGltcHJpbWUgYSB2ZXJzXHUwMEUzbyBkbyBjb21waWxhZG9yXG4gICAtaCAgICAgICAgICAgICBpbXByaW1lIGVzdGEgaW5zdHJ1XHUwMEU3XHUwMEUzbyBkZSB1c29cbiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgY29udGFpbnMgdXNhZ2UgaW5mb3JtYXRpb24gZm9yIGEKLSAgICAgICAgICogbWVhbnMgb2YgaW52b2tpbmcgWFNMVEMgZnJvbSB0aGUgY29tbWFuZC1saW5lLiAgVGhlIG1lc3NhZ2UgaXMKLSAgICAgICAgICogZm9ybWF0dGVkIGZvciBwcmVzZW50YXRpb24gaW4gRW5nbGlzaC4gIFRoZSBzdHJpbmdzIDxqYXJmaWxlPiwKLSAgICAgICAgICogPGRvY3VtZW50PiwgZXRjLiBpbmRpY2F0ZSB1c2VyLXNwZWNpZmllZCBhcmd1bWVudCB2YWx1ZXMsIGFuZCBjYW4KLSAgICAgICAgICogYmUgdHJhbnNsYXRlZCAtIHRoZSBhcmd1bWVudCA8Y2xhc3M+IHJlZmVycyB0byBhIEphdmEgY2xhc3MsIHNvIGl0Ci0gICAgICAgICAqIHNob3VsZCBiZSBoYW5kbGVkIGluIHRoZSBzYW1lIHdheSB0aGUgdGVybSBpcyBoYW5kbGVkIGZvciBKREsKLSAgICAgICAgICogZG9jdW1lbnRhdGlvbi4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5UUkFOU0ZPUk1fVVNBR0VfU1RSLAotICAgICAgICAiU0lOT1BTRSBcbiAgIGphdmEgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNtZGxpbmUuVHJhbnNmb3JtZSBbLWogPGFycXVpdm8gamFyPl1cbiAgICAgIFsteF0gWy1uIDxpdGVyYVx1MDBFN1x1MDBGNWVzPl0gey11IDx1cmxfZG9jdW1lbnRvPiB8IDxkb2N1bWVudG8+fVxuICAgICAgPGNsYXNzZT4gWzxwYXJcdTAwRTJtMT49PHZhbG9yMT4gLi4uXVxuXG4gICB1c2EgYSA8Y2xhc3NlPiB0cmFuc2xldCBwYXJhIHRyYW5zZm9ybWFyIHVtIGRvY3VtZW50byBYTUwgXG4gICBlc3BlY2lmaWNhZG8gY29tbyA8ZG9jdW1lbnRvPi4gTyB0cmFuc2xldCA8Y2xhc3NlPiBlc3RcdTAwRTEgbm9cbiAgIENMQVNTUEFUSCBkbyB1c3VcdTAwRTFyaW8gb3Ugbm8gPGFycXVpdm8gamFyPiBvcGNpb25hbG1lbnRlIGVzcGVjaWZpY2Fkby5cbk9QXHUwMEM3XHUwMEQ1RVNcbiAgIC1qIDxhcnF1aXZvIGphcj4gICAgZXNwZWNpZmljYSB1bSBhcnF1aXZvIGphciBjb20gYmFzZSBubyBxdWFsIHNlclx1MDBFMSBjYXJyZWdhZG8gbyB0cmFuc2xldFxuICAgLXggICAgICAgICAgICAgIGF0aXZhIGEgc2FcdTAwRURkYSBkZSBtZW5zYWdlbnMgZGUgZGVwdXJhXHUwMEU3XHUwMEUzbyBhZGljaW9uYWlzXG4gICAtbiA8aXRlcmFcdTAwRTdcdTAwRjVlcz4gZXhlY3V0YSBhIHRyYW5zZm9ybWFcdTAwRTdcdTAwRTNvIDxpdGVyYVx1MDBFN1x1MDBGNWVzPiB2ZXplcyBlXG4gICAgICAgICAgICAgICAgICAgZXhpYmUgYXMgaW5mb3JtYVx1MDBFN1x1MDBGNWVzIGRlIHBlcmZpc1xuICAgLXUgPHVybF9kb2N1bWVudG8+IGVzcGVjaWZpY2EgbyBkb2N1bWVudG8gWE1MIGRlIGVudHJhZGEgbmEgZm9ybWEgZGUgVVJMXG4ifSwKLQotCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICI8eHNsOnNvcnQ+IiwgIjx4c2w6Zm9yLWVhY2g+IiBhbmQKLSAgICAgICAgICogIjx4c2w6YXBwbHktdGVtcGxhdGVzPiIgYXJlIGtleXdvcmRzIHRoYXQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLgotICAgICAgICAgKiBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCBhbiB4c2w6c29ydCBlbGVtZW50IG11c3QgYmUgYSBjaGlsZCBvZgotICAgICAgICAgKiBvbmUgb2YgdGhlIG90aGVyIGtpbmRzIG9mIGVsZW1lbnRzIG1lbnRpb25lZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5TVFJBWV9TT1JUX0VSUiwKLSAgICAgICAgIjx4c2w6c29ydD4gc1x1MDBGMyBwb2RlIHNlciB1c2FkbyBkZW50cm8gZGUgPHhzbDpmb3ItZWFjaD4gb3UgPHhzbDphcHBseS10ZW1wbGF0ZXM+LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUgZW5jb2RpbmcKLSAgICAgICAgICogcmVxdWVzdGVkIGZvciB0aGUgb3V0cHV0IGRvY3VtZW50IHdhcyBvbiB0aGF0IHJlcXVpcmVzIHN1cHBvcnQgdGhhdAotICAgICAgICAgKiBpcyBub3QgYXZhaWxhYmxlIGZyb20gdGhlIEphdmEgVmlydHVhbCBNYWNoaW5lIGJlaW5nIHVzZWQgdG8gZXhlY3V0ZQotICAgICAgICAgKiB0aGUgcHJvZ3JhbS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5VTlNVUFBPUlRFRF9FTkNPRElORywKLSAgICAgICAgIkEgY29kaWZpY2FcdTAwRTdcdTAwRTNvIGRlIHNhXHUwMEVEZGEgJyd7MH0nJyBuXHUwMEUzbyBcdTAwRTkgc3Vwb3J0YWRhIG5lc3RhIEpWTS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhlIFhQYXRoIGV4cHJlc3Npb24KLSAgICAgICAgICogbmFtZWQgaW4gdGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHdhcyBub3Qgd2VsbCBmb3JtZWQgc3ludGFjdGljYWxseS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5TWU5UQVhfRVJSLAotICAgICAgICAiRXJybyBkZSBzaW50YXhlIGVtICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBhIEphdmEKLSAgICAgICAgICogY2xhc3MuICBUaGUgdGVybSAiY29uc3RydWN0b3IiIGhlcmUgaXMgdGhlIEphdmEgdGVybS4gIFRoZSBtZXNzYWdlIGlzCi0gICAgICAgICAqIGRpc3BsYXllZCBpZiBYU0xUQyBjb3VsZCBub3QgZmluZCBhIGNvbnN0cnVjdG9yIGZvciB0aGUgc3BlY2lmaWVkCi0gICAgICAgICAqIGNsYXNzLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkNPTlNUUlVDVE9SX05PVF9GT1VORCwKLSAgICAgICAgIk5cdTAwRTNvIFx1MDBFOSBwb3NzXHUwMEVEdmVsIGxvY2FsaXphciBvIGNvbnN0cnV0b3IgZXh0ZXJubyAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAic3RhdGljIiBpcyB0aGUgSmF2YSBrZXl3b3JkLiAgVGhlIHN1YnN0aXR1dGlvbgotICAgICAgICAgKiB0ZXh0IGlzIHRoZSBuYW1lIG9mIGEgZnVuY3Rpb24uICBUaGUgZmlyc3QgYXJndW1lbnQgb2YgdGhhdCBmdW5jdGlvbgotICAgICAgICAgKiBpcyBub3Qgb2YgdGhlIHJlcXVpcmVkIHR5cGUuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTk9fSkFWQV9GVU5DVF9USElTX1JFRiwKLSAgICAgICAgIk8gcHJpbWVpcm8gYXJndW1lbnRvIHBhcmEgYSBmdW5cdTAwRTdcdTAwRTNvIEphdmEgblx1MDBFM28gc3RhdGljICcnezB9Jycgblx1MDBFM28gXHUwMEU5IHVtYSByZWZlclx1MDBFQW5jaWEgZGUgb2JqZXRvIHZcdTAwRTFsaWRhLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBbiBYUGF0aCBleHByZXNzaW9uIHdhcyBub3Qgb2YgdGhlIHR5cGUKLSAgICAgICAgICogcmVxdWlyZWQgaW4gYSBwYXJ0aWN1bGFyIGNvbnRleHQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlCi0gICAgICAgICAqIGV4cHJlc3Npb24gdGhhdCB3YXMgaW4gZXJyb3IuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVFlQRV9DSEVDS19FUlIsCi0gICAgICAgICJFcnJvIGFvIHZlcmlmaWNhciBvIHRpcG8gZGUgZXhwcmVzc1x1MDBFM28gJyd7MH0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQW4gWFBhdGggZXhwcmVzc2lvbiB3YXMgbm90IG9mIHRoZSB0eXBlCi0gICAgICAgICAqIHJlcXVpcmVkIGluIGEgcGFydGljdWxhciBjb250ZXh0LiAgSG93ZXZlciwgdGhlIGxvY2F0aW9uIG9mIHRoZQotICAgICAgICAgKiBwcm9ibGVtYXRpYyBleHByZXNzaW9uIGlzIHVua25vd24uCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVFlQRV9DSEVDS19VTktfTE9DX0VSUiwKLSAgICAgICAgIkVycm8gYW8gdmVyaWZpY2FyIG8gdGlwbyBkZSB1bWEgZXhwcmVzc1x1MDBFM28gZW0gdW1hIGxvY2FsaXphXHUwMEU3XHUwMEUzbyBkZXNjb25oZWNpZGEuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBhIGNvbW1hbmQtCi0gICAgICAgICAqIGxpbmUgb3B0aW9uIHRoYXQgd2FzIG5vdCByZWNvZ25pemVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfQ01ETElORV9PUFRJT05fRVJSLAotICAgICAgICAiQSBvcFx1MDBFN1x1MDBFM28gZGEgbGluaGEgZGUgY29tYW5kb3MgJyd7MH0nJyBuXHUwMEUzbyBcdTAwRTkgdlx1MDBFMWxpZGEuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBhIGNvbW1hbmQtCi0gICAgICAgICAqIGxpbmUgb3B0aW9uLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkNNRExJTkVfT1BUX01JU1NJTkdfQVJHX0VSUiwKLSAgICAgICAgIkEgb3BcdTAwRTdcdTAwRTNvIGRhIGxpbmhhIGRlIGNvbWFuZG9zICcnezB9Jycgblx1MDBFM28gZW5jb250cm91IHVtIGFyZ3VtZW50byBvYnJpZ2F0XHUwMEYzcmlvLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgdXNlZCB0byBpbmRpY2F0ZSB0aGUgc2V2ZXJpdHkKLSAgICAgICAgICogb2YgYW5vdGhlciBtZXNzYWdlLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGNvbnRhaW5zIHR3byBlcnJvcgotICAgICAgICAgKiBtZXNzYWdlcy4gIFRoZSBzcGFjaW5nIGJlZm9yZSB0aGUgc2Vjb25kIHN1YnN0aXR1dGlvbiB0ZXh0IGluZGVudHMKLSAgICAgICAgICogaXQgdGhlIHNhbWUgYW1vdW50IGFzIHRoZSBmaXJzdCBpbiBFbmdsaXNoLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLldBUk5JTkdfUExVU19XUkFQUEVEX01TRywKLSAgICAgICAgIldBUk5JTkc6ICAnJ3swfScnXG4gICAgICAgOnsxfSJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgdXNlZCB0byBpbmRpY2F0ZSB0aGUgc2V2ZXJpdHkKLSAgICAgICAgICogb2YgYW5vdGhlciBtZXNzYWdlLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIGFuIGVycm9yIG1lc3NhZ2UuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuV0FSTklOR19NU0csCi0gICAgICAgICJXQVJOSU5HOiAgJyd7MH0nJyJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgdXNlZCB0byBpbmRpY2F0ZSB0aGUgc2V2ZXJpdHkKLSAgICAgICAgICogb2YgYW5vdGhlciBtZXNzYWdlLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGNvbnRhaW5zIHR3byBlcnJvcgotICAgICAgICAgKiBtZXNzYWdlcy4gIFRoZSBzcGFjaW5nIGJlZm9yZSB0aGUgc2Vjb25kIHN1YnN0aXR1dGlvbiB0ZXh0IGluZGVudHMKLSAgICAgICAgICogaXQgdGhlIHNhbWUgYW1vdW50IGFzIHRoZSBmaXJzdCBpbiBFbmdsaXNoLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkZBVEFMX0VSUl9QTFVTX1dSQVBQRURfTVNHLAotICAgICAgICAiRkFUQUwgRVJST1I6ICAnJ3swfScnXG4gICAgICAgICAgIDp7MX0ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIHVzZWQgdG8gaW5kaWNhdGUgdGhlIHNldmVyaXR5Ci0gICAgICAgICAqIG9mIGFub3RoZXIgbWVzc2FnZS4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyBhbiBlcnJvciBtZXNzYWdlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkZBVEFMX0VSUl9NU0csCi0gICAgICAgICJGQVRBTCBFUlJPUjogICcnezB9JycifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIHVzZWQgdG8gaW5kaWNhdGUgdGhlIHNldmVyaXR5Ci0gICAgICAgICAqIG9mIGFub3RoZXIgbWVzc2FnZS4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBjb250YWlucyB0d28gZXJyb3IKLSAgICAgICAgICogbWVzc2FnZXMuICBUaGUgc3BhY2luZyBiZWZvcmUgdGhlIHNlY29uZCBzdWJzdGl0dXRpb24gdGV4dCBpbmRlbnRzCi0gICAgICAgICAqIGl0IHRoZSBzYW1lIGFtb3VudCBhcyB0aGUgZmlyc3QgaW4gRW5nbGlzaC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5FUlJPUl9QTFVTX1dSQVBQRURfTVNHLAotICAgICAgICAiRVJST1I6ICAnJ3swfScnXG4gICAgIDp7MX0ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIHVzZWQgdG8gaW5kaWNhdGUgdGhlIHNldmVyaXR5Ci0gICAgICAgICAqIG9mIGFub3RoZXIgbWVzc2FnZS4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyBhbiBlcnJvciBtZXNzYWdlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkVSUk9SX01TRywKLSAgICAgICAgIkVSUk9SOiAgJyd7MH0nJyJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYSBjbGFzcy4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5UUkFOU0ZPUk1fV0lUSF9UUkFOU0xFVF9TVFIsCi0gICAgICAgICJUcmFuc2Zvcm1hciB1c2FuZG8gdHJhbnNsZXQgJyd7MH0nJyAifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZpcnN0IHN1YnN0aXR1dGlvbiBpcyB0aGUgbmFtZSBvZiBhIGNsYXNzLAotICAgICAgICAgKiB3aGlsZSB0aGUgc2Vjb25kIHN1YnN0aXR1dGlvbiBpcyB0aGUgbmFtZSBvZiBhIGphciBmaWxlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlRSQU5TRk9STV9XSVRIX0pBUl9TVFIsCi0gICAgICAgICJUcmFuc2Zvcm1hciB1c2FuZG8gdHJhbnNsZXQgJyd7MH0nJyBkbyBhcnF1aXZvIGphciAnJ3sxfScnIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJUcmFuc2Zvcm1lckZhY3RvcnkiIGlzIHRoZSBuYW1lIG9mIGEgSmF2YQotICAgICAgICAgKiBpbnRlcmZhY2UgYW5kIG11c3Qgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMKLSAgICAgICAgICogdGhlIG5hbWUgb2YgdGhlIGNsYXNzIHRoYXQgY291bGQgbm90IGJlIGluc3RhbnRpYXRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5DT1VMRF9OT1RfQ1JFQVRFX1RSQU5TX0ZBQ1QsCi0gICAgICAgICJOXHUwMEUzbyBmb2kgcG9zc1x1MDBFRHZlbCBjcmlhciB1bWEgaW5zdFx1MDBFMm5jaWEgZGEgY2xhc3NlIFRyYW5zZm9ybWVyRmFjdG9yeSAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgcHJvZHVjZWQgd2hlbiB0aGUgdXNlcgotICAgICAgICAgKiBzcGVjaWZpZWQgYSBuYW1lIGZvciB0aGUgdHJhbnNsZXQgY2xhc3MgdGhhdCBjb250YWlucyBjaGFyYWN0ZXJzCi0gICAgICAgICAqIHRoYXQgYXJlIG5vdCBwZXJtaXR0ZWQgaW4gYSBKYXZhIGNsYXNzIG5hbWUuICBUaGUgc3Vic3RpdHV0aW9uCi0gICAgICAgICAqIHRleHQgInswfSIgc3BlY2lmaWVzIHRoZSBuYW1lIHRoZSB1c2VyIHJlcXVlc3RlZCwgd2hpbGUgInsxfSIKLSAgICAgICAgICogc3BlY2lmaWVzIHRoZSBuYW1lIHRoZSBwcm9jZXNzb3IgdXNlZCBpbnN0ZWFkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlRSQU5TTEVUX05BTUVfSkFWQV9DT05GTElDVCwKLSAgICAgICAgICJOXHUwMEUzbyBmb2kgcG9zc1x1MDBFRHZlbCB1c2FyIG8gbm9tZSAnJ3swfScnIGNvbW8gbyBub21lIGRhIGNsYXNzZSB0cmFuc2xldCwgcG9pcyBlbGUgY29udFx1MDBFOW0gY2FyYWN0ZXJlcyBxdWUgblx1MDBFM28gc1x1MDBFM28gcGVybWl0aWRvcyBubyBub21lIGRhIGNsYXNzZSBKYXZhLiBPIG5vbWUgJyd7MX0nJyBmb2kgdXNhZG8uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBpcyB1c2VkIGFzIGEgaGVhZGVyLgotICAgICAgICAgKiBBbGwgdGhlIGVycm9yIG1lc3NhZ2VzIGFyZSBjb2xsZWN0ZWQgdG9nZXRoZXIgYW5kIGRpc3BsYXllZCBiZW5lYXRoCi0gICAgICAgICAqIHRoaXMgbWVzc2FnZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5DT01QSUxFUl9FUlJPUl9LRVksCi0gICAgICAgICJFcnJvcyBkbyBjb21waWxhZG9yOiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgaXMgdXNlZCBhcyBhIGhlYWRlci4KLSAgICAgICAgICogQWxsIHRoZSB3YXJuaW5nIG1lc3NhZ2VzIGFyZSBjb2xsZWN0ZWQgdG9nZXRoZXIgYW5kIGRpc3BsYXllZAotICAgICAgICAgKiBiZW5lYXRoIHRoaXMgbWVzc2FnZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5DT01QSUxFUl9XQVJOSU5HX0tFWSwKLSAgICAgICAgIkFkdmVydFx1MDBFQW5jaWFzIGRvIGNvbXBpbGFkb3I6In0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBpcyB1c2VkIGFzIGEgaGVhZGVyLgotICAgICAgICAgKiBBbGwgdGhlIGVycm9yIG1lc3NhZ2VzIHRoYXQgYXJlIHByb2R1Y2VkIHdoZW4gdGhlIHN0eWxlc2hlZXQgaXMKLSAgICAgICAgICogYXBwbGllZCB0byBhbiBpbnB1dCBkb2N1bWVudCBhcmUgY29sbGVjdGVkIHRvZ2V0aGVyIGFuZCBkaXNwbGF5ZWQKLSAgICAgICAgICogYmVuZWF0aCB0aGlzIG1lc3NhZ2UuICBBICd0cmFuc2xldCcgaXMgdGhlIGNvbXBpbGVkIGZvcm0gb2YgYQotICAgICAgICAgKiBzdHlsZXNoZWV0IChzZWUgYWJvdmUpLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlJVTlRJTUVfRVJST1JfS0VZLAotICAgICAgICAiRXJyb3MgZGUgdHJhbnNsZXQ6In0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIGF0dHJpYnV0ZSB3aG9zZSB2YWx1ZSBpcyBjb25zdHJhaW5lZCB0bwotICAgICAgICAgKiBiZSBhICJRTmFtZSIgb3IgYSBsaXN0IG9mICJRTmFtZXMiIGhhZCBhIHZhbHVlIHRoYXQgd2FzIGluY29ycmVjdC4KLSAgICAgICAgICogJ1FOYW1lJyBpcyBhbiBYTUwgc3ludGFjdGljIHRlcm0gdGhhdCBtdXN0IG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhlCi0gICAgICAgICAqIHN1YnN0aXR1dGlvbiB0ZXh0IGNvbnRhaW5zIHRoZSBhY3R1YWwgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTlZBTElEX1FOQU1FX0VSUiwKLSAgICAgICAgIlVtIGF0cmlidXRvIGN1am8gdmFsb3IgZGV2ZSBzZXIgdW0gUU5hbWUgb3UgdW1hIGxpc3RhIGRlIFFOYW1lcyBzZXBhcmFkYSBwb3IgZXNwYVx1MDBFN29zIGVtIGJyYW5jbyB0aW5oYSBvIHZhbG9yICcnezB9JycifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQW4gYXR0cmlidXRlIHdob3NlIHZhbHVlIGlzIHJlcXVpcmVkIHRvCi0gICAgICAgICAqIGJlIGFuICJOQ05hbWUiLgotICAgICAgICAgKiAnTkNOYW1lJyBpcyBhbiBYTUwgc3ludGFjdGljIHRlcm0gdGhhdCBtdXN0IG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhlCi0gICAgICAgICAqIHN1YnN0aXR1dGlvbiB0ZXh0IGNvbnRhaW5zIHRoZSBhY3R1YWwgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTlZBTElEX05DTkFNRV9FUlIsCi0gICAgICAgICJVbSBhdHJpYnV0byBjdWpvIHZhbG9yIGRldmUgc2VyIHVtIE5DTmFtZSB0aW5oYSBvIHZhbG9yICcnezB9JycifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQW4gYXR0cmlidXRlIHdpdGggYW4gaW5jb3JyZWN0IHZhbHVlIHdhcwotICAgICAgICAgKiBlbmNvdW50ZXJlZC4gIFRoZSBwZXJtaXR0ZWQgdmFsdWUgaXMgb25lIG9mIHRoZSBsaXRlcmFsIHZhbHVlcwotICAgICAgICAgKiAieG1sIiwgImh0bWwiIG9yICJ0ZXh0IjsgaXQgaXMgYWxzbyBwZXJtaXR0ZWQgdG8gaGF2ZSB0aGUgZm9ybSBvZgotICAgICAgICAgKiBhIFFOYW1lIHRoYXQgaXMgbm90IGFsc28gYW4gTkNOYW1lLiAgVGhlIHRlcm1zICJtZXRob2QiLAotICAgICAgICAgKiAieHNsOm91dHB1dCIsICJ4bWwiLCAiaHRtbCIgYW5kICJ0ZXh0IiBhcmUga2V5d29yZHMgdGhhdCBtdXN0IG5vdAotICAgICAgICAgKiBiZSB0cmFuc2xhdGVkLiAgVGhlIHRlcm0gInFuYW1lLWJ1dC1ub3QtbmNuYW1lIiBpcyBhbiBYTUwgc3ludGFjdGljCi0gICAgICAgICAqIHRlcm0uICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgY29udGFpbnMgdGhlIGFjdHVhbCB2YWx1ZSBvZiB0aGUKLSAgICAgICAgICogYXR0cmlidXRlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklOVkFMSURfTUVUSE9EX0lOX09VVFBVVCwKLSAgICAgICAgIk8gYXRyaWJ1dG8gbWV0aG9kIGRlIHVtIGVsZW1lbnRvIDx4c2w6b3V0cHV0PiB0aW5oYSBvIHZhbG9yICcnezB9JycuIE8gdmFsb3IgZGV2ZSBzZXIgdW0gZG9zIHNlZ3VpbnRlczogJyd4bWwnJywgJydodG1sJycsICcndGV4dCcnLCBvdSBxbmFtZSwgbWFzIG5cdTAwRTNvIG5jbmFtZSJ9LAotCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX0dFVF9GRUFUVVJFX05VTExfTkFNRSwKLSAgICAgICAgIk8gbm9tZSBkbyByZWN1cnNvIG5cdTAwRTNvIHBvZGUgc2VyIG51bG8gZW0gVHJhbnNmb3JtZXJGYWN0b3J5LmdldEZlYXR1cmUoTm9tZSBkYSBzdHJpbmcpLiJ9LAotCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX1NFVF9GRUFUVVJFX05VTExfTkFNRSwKLSAgICAgICAgIk8gbm9tZSBkbyByZWN1cnNvIG5cdTAwRTNvIHBvZGUgc2VyIG51bG8gZW0gVHJhbnNmb3JtZXJGYWN0b3J5LnNldEZlYXR1cmUoTm9tZSBkYSBzdHJpbmcsIHZhbG9yIGJvb2xpYW5vKS4ifSwKLQotICAgICAgICB7RXJyb3JNc2cuSkFYUF9VTlNVUFBPUlRFRF9GRUFUVVJFLAotICAgICAgICAiTlx1MDBFM28gXHUwMEU5IHBvc3NcdTAwRUR2ZWwgZGVmaW5pciBvIHJlY3Vyc28gJyd7MH0nJyBuZXN0YSBUcmFuc2Zvcm1lckZhY3RvcnkuIn0sCi0KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfU0VDVVJFUFJPQ0VTU0lOR19GRUFUVVJFLAotICAgICAgICAiRkVBVFVSRV9TRUNVUkVfUFJPQ0VTU0lORzogTlx1MDBFM28gXHUwMEU5IHBvc3NcdTAwRUR2ZWwgZGVmaW5pciBvIHJlY3Vyc28gY29tbyBmYWxzbyBxdWFuZG8gbyBnZXJlbmNpYWRvciBkZSBzZWd1cmFuXHUwMEU3YSBlc3RcdTAwRTEgcHJlc2VudGUuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBkZXNjcmliZXMgYW4gaW50ZXJuYWwgZXJyb3IgaW4gdGhlCi0gICAgICAgICAqIHByb2Nlc3Nvci4gIFRoZSB0ZXJtICJieXRlIGNvZGUiIGlzIGEgSmF2YSB0ZWNobmljYWwgdGVybSBmb3IgdGhlCi0gICAgICAgICAqIGV4ZWN1dGFibGUgY29kZSBpbiBhIEphdmEgbWV0aG9kLCBhbmQgInRyeS1jYXRjaC1maW5hbGx5IGJsb2NrIgotICAgICAgICAgKiByZWZlcnMgdG8gdGhlIEphdmEga2V5d29yZHMgd2l0aCB0aG9zZSBuYW1lcy4gICJPdXRsaW5lZCIgaXMgYQotICAgICAgICAgKiB0ZWNobmljYWwgdGVybSBpbnRlcm5hbCB0byBYU0xUQyBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk9VVExJTkVfRVJSX1RSWV9DQVRDSCwKLSAgICAgICAgICJFcnJvIGludGVybm8gZGUgWFNMVEM6IG8gYnl0ZSBjb2RlIGdlcmFkbyBjb250XHUwMEU5bSB1bSBibG9jbyB0cnktY2F0Y2gtZmluYWxseSBlIG5cdTAwRTNvIHBvZGUgc2VyIG91dGxpbmVkLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgZGVzY3JpYmVzIGFuIGludGVybmFsIGVycm9yIGluIHRoZQotICAgICAgICAgKiBwcm9jZXNzb3IuICBUaGUgdGVybXMgIk91dGxpbmVhYmxlQ2h1bmtTdGFydCIgYW5kCi0gICAgICAgICAqICJPdXRsaW5lYWJsZUNodW5rRW5kIiBhcmUgdGhlIG5hbWVzIG9mIGNsYXNzZXMgaW50ZXJuYWwgdG8gWFNMVEMgYW5kCi0gICAgICAgICAqIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoZSBtZXNzYWdlIGluZGljYXRlcyB0aGF0IGZvciBldmVyeQotICAgICAgICAgKiAic3RhcnQiIHRoZXJlIG11c3QgYmUgYSBjb3JyZXNwb25kaW5nICJlbmQiLCBhbmQgdmljZSB2ZXJzYSwgYW5kCi0gICAgICAgICAqIHRoYXQgaWYgb25lIG9mIGEgcGFpciBvZiAic3RhcnQiIGFuZCAiZW5kIiBhcHBlYXJzIGJldHdlZW4gYW5vdGhlcgotICAgICAgICAgKiBwYWlyIG9mIGNvcnJlc3BvbmRpbmcgInN0YXJ0IiBhbmQgImVuZCIsIHRoZW4gdGhlIG90aGVyIGhhbGYgb2YgdGhlCi0gICAgICAgICAqIHBhaXIgbXVzdCBhbHNvIGJlIGJldHdlZW4gdGhhdCBzYW1lIGVuY2xvc2luZyBwYWlyLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk9VVExJTkVfRVJSX1VOQkFMQU5DRURfTUFSS0VSUywKLSAgICAgICAgICJFcnJvIGludGVybm8gZGUgWFNMVEM6IG9zIG1hcmNhZG9yZXMgT3V0bGluZWFibGVDaHVua1N0YXJ0IGUgT3V0bGluZWFibGVDaHVua0VuZCBkZXZlbSBzZXIgYmFsYW5jZWFkb3MgZSBhbmluaGFkb3MgY29ycmV0YW1lbnRlLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgZGVzY3JpYmVzIGFuIGludGVybmFsIGVycm9yIGluIHRoZQotICAgICAgICAgKiBwcm9jZXNzb3IuICBUaGUgdGVybSAiYnl0ZSBjb2RlIiBpcyBhIEphdmEgdGVjaG5pY2FsIHRlcm0gZm9yIHRoZQotICAgICAgICAgKiBleGVjdXRhYmxlIGNvZGUgaW4gYSBKYXZhIG1ldGhvZC4gIFRoZSAibWV0aG9kIiB0aGF0IGlzIGJlaW5nCi0gICAgICAgICAqIHJlZmVycmVkIHRvIGlzIGEgSmF2YSBtZXRob2QgaW4gYSB0cmFuc2xldCB0aGF0IFhTTFRDIGlzIGdlbmVyYXRpbmcKLSAgICAgICAgICogaW4gcHJvY2Vzc2luZyBhIHN0eWxlc2hlZXQuICBUaGUgImluc3RydWN0aW9uIiB0aGF0IGlzIGJlaW5nCi0gICAgICAgICAqIHJlZmVycmVkIHRvIGlzIG9uZSBvZiB0aGUgaW5zdHJ1dGlvbnMgaW4gdGhlIEphdmEgYnl0ZSBjb2RlIGluIHRoYXQKLSAgICAgICAgICogbWV0aG9kLiAgIk91dGxpbmVkIiBpcyBhIHRlY2huaWNhbCB0ZXJtIGludGVybmFsIHRvIFhTTFRDIGFuZAotICAgICAgICAgKiBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuT1VUTElORV9FUlJfREVMRVRFRF9UQVJHRVQsCi0gICAgICAgICAiRXJybyBpbnRlcm5vIGRlIFhTTFRDOiBhaW5kYSBoXHUwMEUxIHJlZmVyXHUwMEVBbmNpYSBubyBtXHUwMEU5dG9kbyBvcmlnaW5hbCBhIHVtYSBpbnN0cnVcdTAwRTdcdTAwRTNvIHF1ZSBmYXppYSBwYXJ0ZSBkZSB1bSBibG9jbyBkZSBieXRlIGNvZGUgcXVlIGZvaSBvdXRsaW5lZC4iCi0gICAgICAgIH0sCi0KLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGRlc2NyaWJlcyBhbiBpbnRlcm5hbCBlcnJvciBpbiB0aGUKLSAgICAgICAgICogcHJvY2Vzc29yLiAgVGhlICJtZXRob2QiIHRoYXQgaXMgYmVpbmcgcmVmZXJyZWQgdG8gaXMgYSBKYXZhIG1ldGhvZAotICAgICAgICAgKiBpbiBhIHRyYW5zbGV0IHRoYXQgWFNMVEMgaXMgZ2VuZXJhdGluZy4KLSAgICAgICAgICoKLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5PVVRMSU5FX0VSUl9NRVRIT0RfVE9PX0JJRywKLSAgICAgICAgICJFcnJvIGludGVybm8gZGUgWFNMVEM6IHVtIG1cdTAwRTl0b2RvIG5vIHRyYW5zbGV0IGV4Y2VkZSBhIGxpbWl0YVx1MDBFN1x1MDBFM28gZGEgTVx1MDBFMXF1aW5hIFZpcnR1YWwgSmF2YSBxdWFudG8gYW8gdGFtYW5obyBkZSB1bSBtXHUwMEU5dG9kbyBkZSBkZSA2NCBraWxvYnl0ZXMuIEVtIGdlcmFsLCBlc3NhIHNpdHVhXHUwMEU3XHUwMEUzbyBcdTAwRTkgY2F1c2FkYSBwb3IgbW9kZWxvcyBkZSB1bWEgZm9saGEgZGUgZXN0aWxvcyBxdWUgc1x1MDBFM28gbXVpdG8gZ3JhbmRlcy4gVGVudGUgcmVlc3RydXR1cmFyIHN1YSBmb2xoYSBkZSBlc3RpbG9zIGRlIGZvcm1hIGEgdXNhciBtb2RlbG9zIG1lbm9yZXMuIgotICAgICAgICB9LAotCi0gICAgICAgICB7RXJyb3JNc2cuREVTRVJJQUxJWkVfVFJBTlNMRVRfRVJSLCAiUXVhbmRvIGEgc2VndXJhblx1MDBFN2EgZG8gSmF2YSBlc3RcdTAwRTEgYXRpdmFkYSwgbyBzdXBvcnRlIHBhcmEgZGVzc2VyaWFsaXphciBUZW1wbGF0ZXNJbXBsIGZpY2EgZGVzYXRpdmFkby4gRXNzYSBzaXR1YVx1MDBFN1x1MDBFM28gcG9kZSBzZXIgY29ycmlnaWRhIGRlZmluaW5kbyBhIHByb3ByaWVkYWRlIGRvIHNpc3RlbWEgamRrLnhtbC5lbmFibGVUZW1wbGF0ZXNJbXBsRGVzZXJpYWxpemF0aW9uIGNvbW8gdHJ1ZS4ifQotCi0gICAgfTsKLQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvdXRpbC9FcnJvck1lc3NhZ2VzX3NrLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL3V0aWwvRXJyb3JNZXNzYWdlc19zay5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxNzY0NmU5Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvdXRpbC9FcnJvck1lc3NhZ2VzX3NrLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4NjMgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRXJyb3JNZXNzYWdlc19zay5qYXZhLHYgMS4xLjYuMSAyMDA1LzA5LzA1IDExOjUzOjAwIHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsOwotCi1pbXBvcnQgamF2YS51dGlsLkxpc3RSZXNvdXJjZUJ1bmRsZTsKLQotLyoqCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqLwotcHVibGljIGNsYXNzIEVycm9yTWVzc2FnZXNfc2sgZXh0ZW5kcyBMaXN0UmVzb3VyY2VCdW5kbGUgewotCi0vKgotICogWFNMVEMgY29tcGlsZS10aW1lIGVycm9yIG1lc3NhZ2VzLgotICoKLSAqIEdlbmVyYWwgbm90ZXMgdG8gdHJhbnNsYXRvcnMgYW5kIGRlZmluaXRpb25zOgotICoKLSAqICAgMSkgWFNMVEMgaXMgdGhlIG5hbWUgb2YgdGhlIHByb2R1Y3QuICBJdCBpcyBhbiBhY3JvbnltIGZvciAiWFNMVCBDb21waWxlciIuCi0gKiAgICAgIFhTTFQgaXMgYW4gYWNyb255bSBmb3IgIlhNTCBTdHlsZXNoZWV0IExhbmd1YWdlOiBUcmFuc2Zvcm1hdGlvbnMiLgotICoKLSAqICAgMikgQSBzdHlsZXNoZWV0IGlzIGEgZGVzY3JpcHRpb24gb2YgaG93IHRvIHRyYW5zZm9ybSBhbiBpbnB1dCBYTUwgZG9jdW1lbnQKLSAqICAgICAgaW50byBhIHJlc3VsdGFudCBYTUwgZG9jdW1lbnQgKG9yIEhUTUwgZG9jdW1lbnQgb3IgdGV4dCkuICBUaGUKLSAqICAgICAgc3R5bGVzaGVldCBpdHNlbGYgaXMgZGVzY3JpYmVkIGluIHRoZSBmb3JtIG9mIGFuIFhNTCBkb2N1bWVudC4KLSAqCi0gKiAgIDMpIEEgdGVtcGxhdGUgaXMgYSBjb21wb25lbnQgb2YgYSBzdHlsZXNoZWV0IHRoYXQgaXMgdXNlZCB0byBtYXRjaCBhCi0gKiAgICAgIHBhcnRpY3VsYXIgcG9ydGlvbiBvZiBhbiBpbnB1dCBkb2N1bWVudCBhbmQgc3BlY2lmaWVzIHRoZSBmb3JtIG9mIHRoZQotICogICAgICBjb3JyZXNwb25kaW5nIHBvcnRpb24gb2YgdGhlIG91dHB1dCBkb2N1bWVudC4KLSAqCi0gKiAgIDQpIEFuIGF4aXMgaXMgYSBwYXJ0aWN1bGFyICJkaW1lbnNpb24iIGluIGEgdHJlZSByZXByZXNlbnRhdGlvbiBvZiBhbiBYTUwKLSAqICAgICAgZG9jdW1lbnQ7IHRoZSBub2RlcyBpbiB0aGUgdHJlZSBhcmUgZGl2aWRlZCBhbG9uZyBkaWZmZXJlbnQgYXhlcy4KLSAqICAgICAgVHJhdmVyc2luZyB0aGUgImNoaWxkIiBheGlzLCBmb3IgaW5zdGFuY2UsIG1lYW5zIHRoYXQgdGhlIHByb2dyYW0KLSAqICAgICAgd291bGQgdmlzaXQgZWFjaCBjaGlsZCBvZiBhIHBhcnRpY3VsYXIgbm9kZTsgdHJhdmVyc2luZyB0aGUgImRlc2NlbmRhbnQiCi0gKiAgICAgIGF4aXMgbWVhbnMgdGhhdCB0aGUgcHJvZ3JhbSB3b3VsZCB2aXNpdCB0aGUgY2hpbGQgbm9kZXMgb2YgYSBwYXJ0aWN1bGFyCi0gKiAgICAgIG5vZGUsIHRoZWlyIGNoaWxkcmVuLCBhbmQgc28gb24gdW50aWwgdGhlIGxlYWYgbm9kZXMgb2YgdGhlIHRyZWUgYXJlCi0gKiAgICAgIHJlYWNoZWQuCi0gKgotICogICA1KSBBbiBpdGVyYXRvciBpcyBhbiBvYmplY3QgdGhhdCB0cmF2ZXJzZXMgbm9kZXMgaW4gYSB0cmVlIGFsb25nIGEKLSAqICAgICAgcGFydGljdWxhciBheGlzLCBvbmUgYXQgYSB0aW1lLgotICoKLSAqICAgNikgQW4gZWxlbWVudCBpcyBhIG1hcmstdXAgdGFnIGluIGFuIFhNTCBkb2N1bWVudDsgYW4gYXR0cmlidXRlIGlzIGEKLSAqICAgICAgbW9kaWZpZXIgb24gdGhlIHRhZy4gIEZvciBleGFtcGxlLCBpbiA8ZWxlbSBhdHRyPSd2YWwnIGF0dHIyPSd2YWwyJz4KLSAqICAgICAgImVsZW0iIGlzIGFuIGVsZW1lbnQgbmFtZSwgImF0dHIiIGFuZCAiYXR0cjIiIGFyZSBhdHRyaWJ1dGUgbmFtZXMgd2l0aAotICogICAgICB0aGUgdmFsdWVzICJ2YWwiIGFuZCAidmFsMiIsIHJlc3BlY3RpdmVseS4KLSAqCi0gKiAgIDcpIEEgbmFtZXNwYWNlIGRlY2xhcmF0aW9uIGlzIGEgc3BlY2lhbCBhdHRyaWJ1dGUgdGhhdCBpcyB1c2VkIHRvIGFzc29jaWF0ZQotICogICAgICBhIHByZWZpeCB3aXRoIGEgVVJJICh0aGUgbmFtZXNwYWNlKS4gIFRoZSBtZWFuaW5ncyBvZiBlbGVtZW50IG5hbWVzIGFuZAotICogICAgICBhdHRyaWJ1dGUgbmFtZXMgdGhhdCB1c2UgdGhhdCBwcmVmaXggYXJlIGRlZmluZWQgd2l0aCByZXNwZWN0IHRvIHRoYXQKLSAqICAgICAgbmFtZXNwYWNlLgotICoKLSAqICAgOCkgRE9NIGlzIGFuIGFjcm9ueW0gZm9yIERvY3VtZW50IE9iamVjdCBNb2RlbC4gIEl0IGlzIGEgdHJlZQotICogICAgICByZXByZXNlbnRhdGlvbiBvZiBhbiBYTUwgZG9jdW1lbnQuCi0gKgotICogICAgICBTQVggaXMgYW4gYWNyb255bSBmb3IgdGhlIFNpbXBsZSBBUEkgZm9yIFhNTCBwcm9jZXNzaW5nLiAgSXQgaXMgYW4gQVBJCi0gKiAgICAgIHVzZWQgaW5mb3JtIGFuIFhNTCBwcm9jZXNzb3IgKGluIHRoaXMgY2FzZSBYU0xUQykgb2YgdGhlIHN0cnVjdHVyZSBhbmQKLSAqICAgICAgY29udGVudCBvZiBhbiBYTUwgZG9jdW1lbnQuCi0gKgotICogICAgICBJbnB1dCB0byB0aGUgc3R5bGVzaGVldCBwcm9jZXNzb3IgY2FuIGNvbWUgZnJvbSBhbiBYTUwgcGFyc2VyIGluIHRoZQotICogICAgICBmb3JtIG9mIGEgRE9NIHRyZWUgb3IgdGhyb3VnaCB0aGUgU0FYIEFQSS4KLSAqCi0gKiAgIDkpIERURCBpcyBhIGRvY3VtZW50IHR5cGUgZGVjbGFyYXRpb24uICBJdCBpcyBhIHdheSBvZiBzcGVjaWZ5aW5nIHRoZQotICogICAgICBncmFtbWFyIGZvciBhbiBYTUwgZmlsZSwgdGhlIG5hbWVzIGFuZCB0eXBlcyBvZiBlbGVtZW50cywgYXR0cmlidXRlcywKLSAqICAgICAgZXRjLgotICoKLSAqICAxMCkgWFBhdGggaXMgYSBzcGVjaWZpY2F0aW9uIHRoYXQgZGVzY3JpYmVzIGEgbm90YXRpb24gZm9yIGlkZW50aWZ5aW5nCi0gKiAgICAgIG5vZGVzIGluIGEgdHJlZS1zdHJ1Y3R1cmVkIHJlcHJlc2VudGF0aW9uIG9mIGFuIFhNTCBkb2N1bWVudC4gIEFuCi0gKiAgICAgIGluc3RhbmNlIG9mIHRoYXQgbm90YXRpb24gaXMgcmVmZXJyZWQgdG8gYXMgYW4gWFBhdGggZXhwcmVzc2lvbi4KLSAqCi0gKiAgMTEpIFRyYW5zbGV0IGlzIGFuIGludmVudGVkIHRlcm0gdGhhdCByZWZlcnMgdG8gdGhlIGNsYXNzIGZpbGUgdGhhdCBjb250YWlucwotICogICAgICB0aGUgY29tcGlsZWQgZm9ybSBvZiBhIHN0eWxlc2hlZXQuCi0gKi8KLQotICAgIC8vIFRoZXNlIG1lc3NhZ2Ugc2hvdWxkIGJlIHJlYWQgZnJvbSBhIGxvY2FsZS1zcGVjaWZpYyByZXNvdXJjZSBidW5kbGUKLSAgICAvKiogR2V0IHRoZSBsb29rdXAgdGFibGUgZm9yIGVycm9yIG1lc3NhZ2VzLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgbWVzc2FnZSBsb29rdXAgdGFibGUuCi0gICAgICovCi0gICAgcHVibGljIE9iamVjdFtdW10gZ2V0Q29udGVudHMoKQotICAgIHsKLSAgICAgIHJldHVybiBuZXcgT2JqZWN0W11bXSB7Ci0gICAgICAgIHtFcnJvck1zZy5NVUxUSVBMRV9TVFlMRVNIRUVUX0VSUiwKLSAgICAgICAgIlZpYWMgbmVcdTAxN2UgamVkZW4gXHUwMTYxdFx1MDBmZGwgZG9rdW1lbnR1IGJvbCBkZWZpbm92YW5cdTAwZmQgdiByb3ZuYWtvbSBzXHUwMGZhYm9yZS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIGEKLSAgICAgICAgICogdGVtcGxhdGUuICBUaGUgc2FtZSBuYW1lIHdhcyB1c2VkIG9uIHR3byBkaWZmZXJlbnQgdGVtcGxhdGVzIGluIHRoZQotICAgICAgICAgKiBzYW1lIHN0eWxlc2hlZXQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVEVNUExBVEVfUkVERUZfRVJSLAotICAgICAgICAiVnpvciAnJ3swfScnIGplIHVcdTAxN2UgdiB0b210byBcdTAxNjF0XHUwMGZkbGUgZG9rdW1lbnR1IGRlZmlub3Zhblx1MDBmZC4ifSwKLQotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYQotICAgICAgICAgKiB0ZW1wbGF0ZS4gIEEgcmVmZXJlbmNlIHRvIHRoZSB0ZW1wbGF0ZSBuYW1lIHdhcyBlbmNvdW50ZXJlZCwgYnV0IHRoZQotICAgICAgICAgKiB0ZW1wbGF0ZSBpcyB1bmRlZmluZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVEVNUExBVEVfVU5ERUZfRVJSLAotICAgICAgICAiVnpvciAnJ3swfScnIG5pZSBqZSB2IHRvbXRvIFx1MDE2MXRcdTAwZmRsZSBkb2t1bWVudHUgZGVmaW5vdmFuXHUwMGZkLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYSB2YXJpYWJsZQotICAgICAgICAgKiB0aGF0IHdhcyBkZWZpbmVkIG1vcmUgdGhhbiBvbmNlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlZBUklBQkxFX1JFREVGX0VSUiwKLSAgICAgICAgIlByZW1lbm5cdTAwZTEgJyd7MH0nJyBqZSB2aWFja3JcdTAwZTF0IGRlZmlub3Zhblx1MDBlMSB2IHRvbSBpc3RvbSByb3pzYWh1LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYSB2YXJpYWJsZQotICAgICAgICAgKiBvciBwYXJhbWV0ZXIuICBBIHJlZmVyZW5jZSB0byB0aGUgdmFyaWFibGUgb3IgcGFyYW1ldGVyIHdhcyBmb3VuZCwKLSAgICAgICAgICogYnV0IGl0IHdhcyBuZXZlciBkZWZpbmVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlZBUklBQkxFX1VOREVGX0VSUiwKLSAgICAgICAgIlByZW1lbm5cdTAwZTEgYWxlYm8gcGFyYW1ldGVyICcnezB9JycgbmllIGplIGRlZmlub3Zhblx1MDBlMS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHdvcmQgImNsYXNzIiBoZXJlIHJlZmVycyB0byBhIEphdmEgY2xhc3MuCi0gICAgICAgICAqIFByb2Nlc3NpbmcgdGhlIHN0eWxlc2hlZXQgcmVxdWlyZWQgYSBjbGFzcyB0byBiZSBsb2FkZWQsIGJ1dCBpdCBjb3VsZAotICAgICAgICAgKiBub3QgYmUgZm91bmQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgdGhlIGNsYXNzLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkNMQVNTX05PVF9GT1VORF9FUlIsCi0gICAgICAgICJOaWUgamUgbW9cdTAxN2VuXHUwMGU5IG5cdTAwZTFqc1x1MDE2NSB0cmllZHUgJyd7MH0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHdvcmQgIm1ldGhvZCIgaGVyZSByZWZlcnMgdG8gYSBKYXZhIG1ldGhvZC4KLSAgICAgICAgICogUHJvY2Vzc2luZyB0aGUgc3R5bGVzaGVldCByZXF1aXJlZCBhIHJlZmVyZW5jZSB0byB0aGUgbWV0aG9kIG5hbWVkIGJ5Ci0gICAgICAgICAqIHRoZSBzdWJzdGl0dXRpb24gdGV4dCwgYnV0IGl0IGNvdWxkIG5vdCBiZSBmb3VuZC4gICJwdWJsaWMiIGlzIHRoZQotICAgICAgICAgKiBKYXZhIGtleXdvcmQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTUVUSE9EX05PVF9GT1VORF9FUlIsCi0gICAgICAgICJOaWUgamUgbW9cdTAxN2VuXHUwMGU5IG5cdTAwZTFqc1x1MDE2NSBleHRlcm5cdTAwZmEgbWV0XHUwMGYzZHUgJyd7MH0nJyAobXVzXHUwMGVkIGJ5XHUwMTY1IHZlcmVqblx1MDBlMSkuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSB3b3JkICJtZXRob2QiIGhlcmUgcmVmZXJzIHRvIGEgSmF2YSBtZXRob2QuCi0gICAgICAgICAqIFByb2Nlc3NpbmcgdGhlIHN0eWxlc2hlZXQgcmVxdWlyZWQgYSByZWZlcmVuY2UgdG8gdGhlIG1ldGhvZCBuYW1lZCBieQotICAgICAgICAgKiB0aGUgc3Vic3RpdHV0aW9uIHRleHQsIGJ1dCBubyBtZXRob2Qgd2l0aCB0aGUgcmVxdWlyZWQgdHlwZXMgb2YKLSAgICAgICAgICogYXJndW1lbnRzIG9yIHJldHVybiB0eXBlIGNvdWxkIGJlIGZvdW5kLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkFSR1VNRU5UX0NPTlZFUlNJT05fRVJSLAotICAgICAgICAiTmllIGplIG1vXHUwMTdlblx1MDBlOSBrb252ZXJ0b3ZhXHUwMTY1IHR5cCBhcmd1bWVudHUvblx1MDBlMXZyYXR1IHZvIHZvbGFuXHUwMGVkIG1ldFx1MDBmM2R5ICcnezB9JycifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZpbGUgb3IgVVJJIG5hbWVkIGluIHRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICAgKiBpcyBtaXNzaW5nLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkZJTEVfTk9UX0ZPVU5EX0VSUiwKLSAgICAgICAgIlNcdTAwZmFib3IgYWxlYm8gVVJJICcnezB9Jycgc2EgbmVuYVx1MDE2MWxpLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgZGlzcGxheWVkIHdoZW4gdGhlIFVSSQotICAgICAgICAgKiBtZW50aW9uZWQgaW4gdGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIG5vdCB3ZWxsLWZvcm1lZCBzeW50YWN0aWNhbGx5LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklOVkFMSURfVVJJX0VSUiwKLSAgICAgICAgIk5lcGxhdG5cdTAwZmQgVVJJICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmaWxlIG9yIFVSSSBuYW1lZCBpbiB0aGUgc3Vic3RpdHV0aW9uIHRleHQKLSAgICAgICAgICogZXhpc3RzIGJ1dCBjb3VsZCBub3QgYmUgb3BlbmVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkZJTEVfQUNDRVNTX0VSUiwKLSAgICAgICAgIk5pZSBqZSBtb1x1MDE3ZW5cdTAwZTkgb3R2b3JpXHUwMTY1IHNcdTAwZmFib3IgYWxlYm8gVVJJICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogPHhzbDpzdHlsZXNoZWV0PiBhbmQgPHhzbDp0cmFuc2Zvcm0+IGFyZQotICAgICAgICAgKiBrZXl3b3JkcyB0aGF0IHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5NSVNTSU5HX1JPT1RfRVJSLAotICAgICAgICAiT1x1MDEwZGFrXHUwMGUxdmEgc2EgZWxlbWVudCA8eHNsOnN0eWxlc2hlZXQ+IGFsZWJvIDx4c2w6dHJhbnNmb3JtPi4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN0eWxlc2hlZXQgY29udGFpbmVkIGEgcmVmZXJlbmNlIHRvIGEKLSAgICAgICAgICogbmFtZXNwYWNlIHByZWZpeCB0aGF0IHdhcyB1bmRlZmluZWQuICBUaGUgdmFsdWUgb2YgdGhlIHN1YnN0aXR1dGlvbgotICAgICAgICAgKiB0ZXh0IGlzIHRoZSBuYW1lIG9mIHRoZSBwcmVmaXguCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTkFNRVNQQUNFX1VOREVGX0VSUiwKLSAgICAgICAgIlByZWRwb25hIG5cdTAwZTF6dm92XHUwMGU5aG8gcHJpZXN0b3J1ICcnezB9JycgbmllIGplIGRla2xhcm92YW5cdTAwZTEuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBKYXZhIGZ1bmN0aW9uIG5hbWVkIGluIHRoZSBzdHlsZXNoZWV0IGNvdWxkCi0gICAgICAgICAqIG5vdCBiZSBmb3VuZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5GVU5DVElPTl9SRVNPTFZFX0VSUiwKLSAgICAgICAgIk5pZSBqZSBtb1x1MDE3ZW5cdTAwZTkgcm96bFx1MDBlZFx1MDE2MWlcdTAxNjUgdm9sYW5pZSBmdW5rY2llICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBhCi0gICAgICAgICAqIGZ1bmN0aW9uLiAgQSBsaXRlcmFsIHN0cmluZyBoZXJlIG1lYW5zIGEgY29uc3RhbnQgc3RyaW5nIHZhbHVlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk5FRURfTElURVJBTF9FUlIsCi0gICAgICAgICJBcmd1bWVudCBwcmUgJyd7MH0nJyBtdXNcdTAwZWQgYnlcdTAxNjUgcmVcdTAxNjVhemNvbSBsaXRlclx1MDBlMWx1LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaW5kaWNhdGVzIHRoZXJlIHdhcyBhIHN5bnRhY3RpYwotICAgICAgICAgKiBlcnJvciBpbiB0aGUgZm9ybSBvZiBhbiBYUGF0aCBleHByZXNzaW9uLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzCi0gICAgICAgICAqIHRoZSBleHByZXNzaW9uLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlhQQVRIX1BBUlNFUl9FUlIsCi0gICAgICAgICJDaHliYSBwcmkgYW5hbFx1MDBmZHplIHZcdTAwZmRyYXp1IFhQYXRoICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIGVsZW1lbnQgaW4gdGhlIHN0eWxlc2hlZXQgcmVxdWlyZXMgYQotICAgICAgICAgKiBwYXJ0aWN1bGFyIGF0dHJpYnV0ZSBuYW1lZCBieSB0aGUgc3Vic3RpdHV0aW9uIHRleHQsIGJ1dCB0aGF0Ci0gICAgICAgICAqIGF0dHJpYnV0ZSB3YXMgbm90IHNwZWNpZmllZCBpbiB0aGUgc3R5bGVzaGVldC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5SRVFVSVJFRF9BVFRSX0VSUiwKLSAgICAgICAgIkNoXHUwMGZkYmEgcG9cdTAxN2VhZG92YW5cdTAwZmQgYXRyaWJcdTAwZmF0ICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCBhIGNoYXJhY3RlciBub3QKLSAgICAgICAgICogcGVybWl0dGVkIGluIGFuIFhQYXRoIGV4cHJlc3Npb24gd2FzIGVuY291bnRlcmVkLiAgVGhlIHN1YnN0aXR1dGlvbgotICAgICAgICAgKiB0ZXh0IGlzIHRoZSBvZmZlbmRpbmcgY2hhcmFjdGVyLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfQ0hBUl9FUlIsCi0gICAgICAgICJOZXBsYXRuXHUwMGZkIHpuYWsgJyd7MH0nJyB2byB2XHUwMGZkcmF6ZSBYUGF0aC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQSBwcm9jZXNzaW5nIGluc3RydWN0aW9uIGlzIGEgbWFyay11cCBpdGVtIGluCi0gICAgICAgICAqIGFuIFhNTCBkb2N1bWVudCB0aGF0IHJlcXVlc3Qgc29tZSBiZWhhdmlvdXIgb2YgYW4gWE1MIHByb2Nlc3Nvci4gIFRoZQotICAgICAgICAgKiBmb3JtIG9mIHRoZSBuYW1lIG9mIHdhcyBpbnZhbGlkIGluIHRoaXMgY2FzZSwgYW5kIHRoZSBzdWJzdGl0dXRpb24KLSAgICAgICAgICogdGV4dCBpcyB0aGUgbmFtZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTExFR0FMX1BJX0VSUiwKLSAgICAgICAgIk5lcGxhdG5cdTAwZmQgblx1MDBlMXpvdiAnJ3swfScnIHByZSBpblx1MDE2MXRydWtjaXUgc3ByYWNvdmFuaWEuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyByZXBvcnRlZCBpZiB0aGUgc3R5bGVzaGVldAotICAgICAgICAgKiBiZWluZyBwcm9jZXNzZWQgYXR0ZW1wdGVkIHRvIGNvbnN0cnVjdCBhbiBYTUwgZG9jdW1lbnQgd2l0aCBhbgotICAgICAgICAgKiBhdHRyaWJ1dGUgaW4gYSBwbGFjZSBvdGhlciB0aGFuIG9uIGFuIGVsZW1lbnQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQKLSAgICAgICAgICogc3BlY2lmaWVzIHRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuU1RSQVlfQVRUUklCVVRFX0VSUiwKLSAgICAgICAgIkF0cmliXHUwMGZhdCAnJ3swfScnIG1pbW8gZWxlbWVudHUuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIGF0dHJpYnV0ZSB0aGF0IHdhc24ndCByZWNvZ25pemVkIHdhcwotICAgICAgICAgKiBzcGVjaWZpZWQgb24gYW4gZWxlbWVudCBpbiB0aGUgc3R5bGVzaGVldC4gIFRoZSBhdHRyaWJ1dGUgaXMgbmFtZWQKLSAgICAgICAgICogYnkgdGhlIHN1YnN0aXR1dGlvbgotICAgICAgICAgKiB0ZXh0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfQVRUUklCVVRFX0VSUiwKLSAgICAgICAgIk5lbGVnXHUwMGUxbG55IGF0cmliXHUwMGZhdCAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiaW1wb3J0IiBhbmQgImluY2x1ZGUiIGFyZSBrZXl3b3JkcyB0aGF0IHNob3VsZAotICAgICAgICAgKiBub3QgYmUgdHJhbnNsYXRlZC4gIFRoaXMgbWVzc2FnZXMgaW5kaWNhdGVzIHRoYXQgdGhlIHN0eWxlc2hlZXQKLSAgICAgICAgICogbmFtZWQgaW4gdGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGltcG9ydGVkIG9yIGluY2x1ZGVkIGl0c2VsZiBlaXRoZXIKLSAgICAgICAgICogZGlyZWN0bHkgb3IgaW5kaXJlY3RseS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5DSVJDVUxBUl9JTkNMVURFX0VSUiwKLSAgICAgICAgIkNpcmt1bFx1MDBlMXJueSBpbXBvcnQvemFocm51dGllLiBcdTAxNjB0XHUwMGZkbCBkb2t1bWVudHUgJyd7MH0nJyBqZSB1XHUwMTdlIHphdmVkZW5cdTAwZmQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEEgcmVzdWx0LXRyZWUgZnJhZ21lbnQgaXMgYSBwb3J0aW9uIG9mIGEKLSAgICAgICAgICogcmVzdWx0aW5nIFhNTCBkb2N1bWVudCByZXByZXNlbnRlZCBhcyBhIHRyZWUuICAiPHhzbDpzb3J0PiIgaXMgYQotICAgICAgICAgKiBrZXl3b3JkIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuUkVTVUxUX1RSRUVfU09SVF9FUlIsCi0gICAgICAgICJGcmFnbWVudHkgc3Ryb211IHZcdTAwZmRzbGVka292IG5lbW9cdTAxN2VubyB0cmllZGlcdTAxNjUgKGVsZW1lbnR5IDx4c2w6c29ydD4gc1x1MDBmYSBpZ25vcm92YW5cdTAwZTkpLiBLZVx1MDEwZiB2eXR2XHUwMGUxcmF0ZSB2XHUwMGZkc2xlZGtvdlx1MDBmZCBzdHJvbSwgbXVzXHUwMGVkdGUgdHJpZWRpXHUwMTY1IHV6bHkuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEEgbmFtZSBjYW4gYmUgZ2l2ZW4gdG8gYSBwYXJ0aWN1bGFyIHN0eWxlIHRvIGJlCi0gICAgICAgICAqIHVzZWQgdG8gZm9ybWF0IGRlY2ltYWwgdmFsdWVzLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGdpdmVzIHRoZSBuYW1lCi0gICAgICAgICAqIG9mIHN1Y2ggYSBzdHlsZSBmb3Igd2hpY2ggbW9yZSB0aGFuIG9uZSBkZWNsYXJhdGlvbiB3YXMgZW5jb3VudGVyZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuU1lNQk9MU19SRURFRl9FUlIsCi0gICAgICAgICJEZXNpYXRrb3ZcdTAwZTkgZm9ybVx1MDBlMXRvdmFuaWUgJyd7MH0nJyBqZSB1XHUwMTdlIGRlZmlub3Zhblx1MDBlOS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN0eWxlc2hlZXQgdmVyc2lvbiBuYW1lZCBpbiB0aGUKLSAgICAgICAgICogc3Vic3RpdHV0aW9uIHRleHQgaXMgbm90IHN1cHBvcnRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5YU0xfVkVSU0lPTl9FUlIsCi0gICAgICAgICJWZXJ6aWEgWFNMICcnezB9JycgbmllIGplIHBvZHBvcm92YW5cdTAwZTEgWFNMVEMuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBkZWZpbml0aW9ucyBvZiBvbmUgb3IgbW9yZSB2YXJpYWJsZXMgb3IKLSAgICAgICAgICogcGFyYW1ldGVycyBkZXBlbmQgb24gb25lIGFub3RoZXIuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuQ0lSQ1VMQVJfVkFSSUFCTEVfRVJSLAotICAgICAgICAiQ2lya3VsXHUwMGUxcm5hIHJlZmVyZW5jaWEgcHJlbWVubmVqL3BhcmFtZXRyYSB2ICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBvcGVyYXRvciBpbiBhbiBleHByZXNpb24gd2l0aCB0d28gb3BlcmFuZHMgd2FzCi0gICAgICAgICAqIG5vdCByZWNvZ25pemVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfQklOQVJZX09QX0VSUiwKLSAgICAgICAgIk5lem5cdTAwZTFteSBvcGVyXHUwMGUxdG9yIHByZSBiaW5cdTAwZTFybnkgdlx1MDBmZHJhei4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIHByb2R1Y2VkIGlmIGEgcmVmZXJlbmNlIHRvIGEKLSAgICAgICAgICogZnVuY3Rpb24gaGFzIHRvbyBtYW55IG9yIHRvbyBmZXcgYXJndW1lbnRzLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfQVJHX0VSUiwKLSAgICAgICAgIk5lcGxhdG5cdTAwZmQgYXJndW1lbnQoeSkgcHJlIHZvbGFuaWUgZnVua2NpZS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgImRvY3VtZW50KCkiIGlzIHRoZSBuYW1lIG9mIGZ1bmN0aW9uIGFuZCBtdXN0Ci0gICAgICAgICAqIG5vdCBiZSB0cmFuc2xhdGVkLiAgQSBub2RlLXNldCBpcyBhIHNldCBvZiB0aGUgbm9kZXMgaW4gdGhlIHRyZWUKLSAgICAgICAgICogcmVwcmVzZW50YXRpb24gb2YgYW4gWE1MIGRvY3VtZW50LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkRPQ1VNRU5UX0FSR19FUlIsCi0gICAgICAgICJEcnVoXHUwMGZkIGFyZ3VtZW50IHByZSBmdW5rY2l1IGRva3VtZW50dSgpIG11c1x1MDBlZCBieVx1MDE2NSBzYWRhIHV6bG92LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiPHhzbDp3aGVuPiIgYW5kICI8eHNsOmNob29zZT4iIGFyZSBrZXl3b3JkcwotICAgICAgICAgKiBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhpcyBtZXNzYWdlIGRlc2NyaWJlcyBhIHN5bnRheCBlcnJvcgotICAgICAgICAgKiBpbiB0aGUgc3R5bGVzaGVldC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5NSVNTSU5HX1dIRU5fRVJSLAotICAgICAgICAiViA8eHNsOmNob29zZT4gc2EgdnlcdTAxN2VhZHVqZSBuYWptZW5laiBqZWRlbiBlbGVtZW50IDx4c2w6d2hlbj4uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICI8eHNsOm90aGVyd2lzZT4iIGFuZCAiPHhzbDpjaG9vc2U+IiBhcmUKLSAgICAgICAgICoga2V5d29yZHMgYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoaXMgbWVzc2FnZSBkZXNjcmliZXMgYQotICAgICAgICAgKiBzeW50YXggZXJyb3IgaW4gdGhlIHN0eWxlc2hlZXQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTVVMVElQTEVfT1RIRVJXSVNFX0VSUiwKLSAgICAgICAgIlYgIDx4c2w6Y2hvb3NlPiBqZSBwb3ZvbGVuXHUwMGZkIGxlbiBqZWRlbiBlbGVtZW50IDx4c2w6b3RoZXJ3aXNlPi4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIjx4c2w6b3RoZXJ3aXNlPiIgYW5kICI8eHNsOmNob29zZT4iIGFyZQotICAgICAgICAgKiBrZXl3b3JkcyBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhpcyBtZXNzYWdlIGRlc2NyaWJlcyBhCi0gICAgICAgICAqIHN5bnRheCBlcnJvciBpbiB0aGUgc3R5bGVzaGVldC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5TVFJBWV9PVEhFUldJU0VfRVJSLAotICAgICAgICAiPHhzbDpvdGhlcndpc2U+IG1vXHUwMTdlbm8gcG91XHUwMTdlaVx1MDE2NSBsZW4gdiA8eHNsOmNob29zZT4uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICI8eHNsOndoZW4+IiBhbmQgIjx4c2w6Y2hvb3NlPiIgYXJlIGtleXdvcmRzCi0gICAgICAgICAqIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGlzIG1lc3NhZ2UgZGVzY3JpYmVzIGEgc3ludGF4IGVycm9yCi0gICAgICAgICAqIGluIHRoZSBzdHlsZXNoZWV0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlNUUkFZX1dIRU5fRVJSLAotICAgICAgICAiPHhzbDp3aGVuPiBtb1x1MDE3ZW5vIHBvdVx1MDE3ZWlcdTAxNjUgbGVuIHYgPHhzbDpjaG9vc2U+LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiPHhzbDp3aGVuPiIsICI8eHNsOm90aGVyd2lzZT4iIGFuZAotICAgICAgICAgKiAiPHhzbDpjaG9vc2U+IiBhcmUga2V5d29yZHMgYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoaXMKLSAgICAgICAgICogbWVzc2FnZSBkZXNjcmliZXMgYSBzeW50YXggZXJyb3IgaW4gdGhlIHN0eWxlc2hlZXQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuV0hFTl9FTEVNRU5UX0VSUiwKLSAgICAgICAgIlYgPHhzbDpjaG9vc2U+IHNcdTAwZmEgcG92b2xlblx1MDBlOSBsZW4gZWxlbWVudHkgPHhzbDp3aGVuPiBhIDx4c2w6b3RoZXJ3aXNlPi4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIjx4c2w6YXR0cmlidXRlLXNldD4iIGFuZCAibmFtZSIgYXJlIGtleXdvcmRzCi0gICAgICAgICAqIHRoYXQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlVOTkFNRURfQVRUUklCU0VUX0VSUiwKLSAgICAgICAgIjx4c2w6YXR0cmlidXRlLXNldD4gY2hcdTAwZmRiYSBhdHJpYlx1MDBmYXQgJ25hbWUnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBbiBlbGVtZW50IGluIHRoZSBzdHlsZXNoZWV0IGNvbnRhaW5lZCBhbgotICAgICAgICAgKiBlbGVtZW50IG9mIGEgdHlwZSB0aGF0IGl0IHdhcyBub3QgcGVybWl0dGVkIHRvIGNvbnRhaW4uCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSUxMRUdBTF9DSElMRF9FUlIsCi0gICAgICAgICJOZXBsYXRuXHUwMGZkIGVsZW1lbnQgcG90b21rYS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN0eWxlc2hlZXQgdHJpZWQgdG8gY3JlYXRlIGFuIGVsZW1lbnQgd2l0aAotICAgICAgICAgKiBhIG5hbWUgdGhhdCB3YXMgbm90IGEgdmFsaWQgWE1MIG5hbWUuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgY29udGFpbnMKLSAgICAgICAgICogdGhlIG5hbWUuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSUxMRUdBTF9FTEVNX05BTUVfRVJSLAotICAgICAgICAiTmVtXHUwMGY0XHUwMTdlZXRlIHZvbGFcdTAxNjUgZWxlbWVudCAnJ3swfScnIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IHRyaWVkIHRvIGNyZWF0ZSBhbiBhdHRyaWJ1dGUKLSAgICAgICAgICogd2l0aCBhIG5hbWUgdGhhdCB3YXMgbm90IGEgdmFsaWQgWE1MIG5hbWUuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQKLSAgICAgICAgICogY29udGFpbnMgdGhlIG5hbWUuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSUxMRUdBTF9BVFRSX05BTUVfRVJSLAotICAgICAgICAiTmVtXHUwMGY0XHUwMTdlZXRlIHZvbGFcdTAxNjUgYXRyaWJcdTAwZmF0ICcnezB9JycifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGNoaWxkcmVuIG9mIHRoZSBvdXRlcm1vc3QgZWxlbWVudCBvZiBhCi0gICAgICAgICAqIHN0eWxlc2hlZXQgYXJlIHJlZmVycmVkIHRvIGFzIHRvcC1sZXZlbCBlbGVtZW50cy4gIE5vIHRleHQgc2hvdWxkCi0gICAgICAgICAqIG9jY3VyIHdpdGhpbiB0aGF0IG91dGVybW9zdCBlbGVtZW50IHVubGVzcyBpdCBpcyB3aXRoaW4gYSB0b3AtbGV2ZWwKLSAgICAgICAgICogZWxlbWVudC4gIFRoaXMgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGF0IGNvbnN0cmFpbnQgd2FzIHZpb2xhdGVkLgotICAgICAgICAgKiAiPHhzbDpzdHlsZXNoZWV0PiIgaXMgYSBrZXl3b3JkIHRoYXQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfVEVYVF9OT0RFX0VSUiwKLSAgICAgICAgIlRleHRvdlx1MDBlOSBcdTAwZmFkYWplIHNcdTAwZmEgbWltbyBlbGVtZW50dSB2cmNobmVqIFx1MDBmYXJvdm5lIDx4c2w6c3R5bGVzaGVldD4uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEpBWFAgaXMgYW4gYWNyb255bSBmb3IgdGhlIEphdmEgQVBJIGZvciBYTUwKLSAgICAgICAgICogUHJvY2Vzc2luZy4gIFRoaXMgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUgWE1MIHBhcnNlciBwcm92aWRlZCB0bwotICAgICAgICAgKiBYU0xUQyB0byBwcm9jZXNzIHRoZSBYTUwgaW5wdXQgZG9jdW1lbnQgaGFkIGEgY29uZmlndXJhdGlvbiBwcm9ibGVtLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlNBWF9QQVJTRVJfQ09ORklHX0VSUiwKLSAgICAgICAgIkFuYWx5elx1MDBlMXRvciBKQVhQIG5pZSBqZSBzcHJcdTAwZTF2bmUgbmFrb25maWd1cm92YW5cdTAwZmQifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IG5hbWVzIHRoZSBpbnRlcm5hbCBlcnJvcgotICAgICAgICAgKiBlbmNvdW50ZXJlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTlRFUk5BTF9FUlIsCi0gICAgICAgICJOZW9kc3RyXHUwMGUxbml0ZVx1MDEzZW5cdTAwZTEgaW50ZXJuXHUwMGUxIGNoeWJhIFhTTFRDOiAnJ3swfScnIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IGNvbnRhaW5lZCBhbiBlbGVtZW50IHRoYXQgd2FzCi0gICAgICAgICAqIG5vdCByZWNvZ25pemVkIGFzIHBhcnQgb2YgdGhlIFhTTCBzeW50YXguICBUaGUgc3Vic3RpdHV0aW9uIHRleHQKLSAgICAgICAgICogZ2l2ZXMgdGhlIGVsZW1lbnQgbmFtZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5VTlNVUFBPUlRFRF9YU0xfRVJSLAotICAgICAgICAiTmVwb2Rwb3JvdmFuXHUwMGZkIGVsZW1lbnQgWFNMICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IHJlZmVycmVkIHRvIGFuIGV4dGVuc2lvbiB0byB0aGUKLSAgICAgICAgICogWFNMIHN5bnRheCBhbmQgaW5kaWNhdGVkIHRoYXQgaXQgd2FzIGRlZmluZWQgYnkgWFNMVEMsIGJ1dCBYU1RMQyBkb2VzCi0gICAgICAgICAqIG5vdCByZWNvZ25pemVkIHRoZSBwYXJ0aWN1bGFyIGV4dGVuc2lvbiBuYW1lZC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICAgKiBnaXZlcyB0aGUgZXh0ZW5zaW9uIG5hbWUuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVU5TVVBQT1JURURfRVhUX0VSUiwKLSAgICAgICAgIk5lcm96bFx1MDBlZFx1MDE2MWVuXHUwMGU5IHJvelx1MDE2MVx1MDBlZHJlbmllIFhTTFRDICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBYTUwgZG9jdW1lbnQgZ2l2ZW4gdG8gWFNMVEMgYXMgYSBzdHlsZXNoZWV0Ci0gICAgICAgICAqIHdhcyBub3QsIGluIGZhY3QsIGEgc3R5bGVzaGVldC4gIFhTTFRDIGlzIGFibGUgdG8gZGV0ZWN0IHRoYXQgaW4gdGhpcwotICAgICAgICAgKiBjYXNlIGJlY2F1c2UgdGhlIG91dGVybW9zdCBlbGVtZW50IGluIHRoZSBzdHlsZXNoZWV0IGhhcyB0byBiZQotICAgICAgICAgKiBkZWNsYXJlZCB3aXRoIHJlc3BlY3QgdG8gdGhlIFhTTCBuYW1lc3BhY2UgVVJJLCBidXQgbm8gZGVjbGFyYXRpb24KLSAgICAgICAgICogZm9yIHRoYXQgbmFtZXNwYWNlIHdhcyBzZWVuLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk1JU1NJTkdfWFNMVF9VUklfRVJSLAotICAgICAgICAiVnN0dXBuXHUwMGZkIGRva3VtZW50IG5pZSBqZSBcdTAxNjF0XHUwMGZkbG9tIGRva3VtZW50dSAoblx1MDBlMXp2b3ZcdTAwZmQgcHJpZXN0b3IgWFNMIG5pZSBqZSBkZWtsYXJvdmFuXHUwMGZkIHYga29yZVx1MDE0OG92b20gZWxlbWVudGUpLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBYU0xUQyBjb3VsZCBub3QgZmluZCB0aGUgc3R5bGVzaGVldCBkb2N1bWVudAotICAgICAgICAgKiB3aXRoIHRoZSBuYW1lIHNwZWNpZmllZCBieSB0aGUgc3Vic3RpdHV0aW9uIHRleHQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTUlTU0lOR19YU0xUX1RBUkdFVF9FUlIsCi0gICAgICAgICJOZWJvbG8gbW9cdTAxN2VuXHUwMGU5IG5cdTAwZTFqc1x1MDE2NSBjaWVcdTAxM2UgXHUwMTYxdFx1MDBmZGx1IGRva3VtZW50dSAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBhY2Nlc3MgdG8gdGhlIHN0eWxlc2hlZXQgdGFyZ2V0IGlzIGRlbmllZAotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkFDQ0VTU0lOR19YU0xUX1RBUkdFVF9FUlIsCi0gICAgICAgICJDb3VsZCBub3QgcmVhZCBzdHlsZXNoZWV0IHRhcmdldCAnJ3swfScnLCBiZWNhdXNlICcnezF9JycgYWNjZXNzIGlzIG5vdCBhbGxvd2VkLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgcmVwcmVzZW50cyBhbiBpbnRlcm5hbCBlcnJvciBpbgotICAgICAgICAgKiBjb25kaXRpb24gaW4gWFNMVEMuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIGNsYXNzIG5hbWUgaW4gWFNMVEMKLSAgICAgICAgICogdGhhdCBpcyBtaXNzaW5nIHNvbWUgZnVuY3Rpb25hbGl0eS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5OT1RfSU1QTEVNRU5URURfRVJSLAotICAgICAgICAiTmllIGplIGltcGxlbWVudG92YW5cdTAwZTk6ICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBYTUwgZG9jdW1lbnQgZ2l2ZW4gdG8gWFNMVEMgYXMgYSBzdHlsZXNoZWV0Ci0gICAgICAgICAqIHdhcyBub3QsIGluIGZhY3QsIGEgc3R5bGVzaGVldC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5OT1RfU1RZTEVTSEVFVF9FUlIsCi0gICAgICAgICJWc3R1cG5cdTAwZmQgZG9rdW1lbnQgbmVvYnNhaHVqZSBcdTAxNjF0XHUwMGZkbCBkb2t1bWVudHUgWFNMLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZWxlbWVudCBuYW1lZCBpbiB0aGUgc3Vic3RpdHV0aW9uIHRleHQgd2FzCi0gICAgICAgICAqIGVuY291bnRlcmVkIGluIHRoZSBzdHlsZXNoZWV0IGJ1dCBpcyBub3QgcmVjb2duaXplZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5FTEVNRU5UX1BBUlNFX0VSUiwKLSAgICAgICAgIk5lYm9sbyBtb1x1MDE3ZW5cdTAwZTkgYW5hbHl6b3ZhXHUwMTY1IGVsZW1lbnQgJyd7MH0nJyJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAidXNlIiwgIjxrZXk+IiwgIm5vZGUiLCAibm9kZS1zZXQiLCAic3RyaW5nIgotICAgICAgICAgKiBhbmQgIm51bWJlciIgYXJlIGtleXdvcmRzIGluIHRoaXMgY29udGV4dCBhbmQgc2hvdWxkIG5vdCBiZQotICAgICAgICAgKiB0cmFuc2xhdGVkLiAgVGhpcyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoZSB2YWx1ZSBvZiB0aGUgInVzZSIKLSAgICAgICAgICogYXR0cmlidXRlIHdhcyBub3Qgb25lIG9mIHRoZSBwZXJtaXR0ZWQgdmFsdWVzLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLktFWV9VU0VfQVRUUl9FUlIsCi0gICAgICAgICJBdHJpYlx1MDBmYXQgcG91XHUwMTdlaXRpYSA8a2V5PiBtdXNcdTAwZWQgYnlcdTAxNjUgdXpvbCwgc2FkYSB1emxvdiwgcmVcdTAxNjVhemVjIGFsZWJvIFx1MDEwZFx1MDBlZHNsby4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQW4gWE1MIGRvY3VtZW50IGNhbiBzcGVjaWZ5IHRoZSB2ZXJzaW9uIG9mIHRoZQotICAgICAgICAgKiBYTUwgc3BlY2lmaWNhdGlvbiB0byB3aGljaCBpdCBhZGhlcmVzLiAgVGhpcyBtZXNzYWdlIGluZGljYXRlcyB0aGF0Ci0gICAgICAgICAqIHRoZSB2ZXJzaW9uIHNwZWNpZmllZCBmb3IgdGhlIG91dHB1dCBkb2N1bWVudCB3YXMgbm90IHZhbGlkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk9VVFBVVF9WRVJTSU9OX0VSUiwKLSAgICAgICAgIlZlcnppYSB2XHUwMGZkc3R1cG5cdTAwZTlobyBkb2t1bWVudHUgWE1MIGJ5IG1hbGEgYnlcdTAxNjUgMS4wIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBvcGVyYXRvciBpbiBhIGNvbXBhcmlzb24gb3BlcmF0aW9uIHdhcwotICAgICAgICAgKiBub3QgcmVjb2duaXplZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTExFR0FMX1JFTEFUX09QX0VSUiwKLSAgICAgICAgIk5lem5cdTAwZTFteSBvcGVyXHUwMGUxdG9yIHByZSByZWxhXHUwMTBkblx1MDBmZCB2XHUwMGZkcmF6In0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIGF0dHJpYnV0ZSBzZXQgZGVmaW5lcyBhcyBhIHNldCBvZiBYTUwKLSAgICAgICAgICogYXR0cmlidXRlcyB0aGF0IGNhbiBiZSBhZGRlZCB0byBhbiBlbGVtZW50IGluIHRoZSBvdXRwdXQgWE1MIGRvY3VtZW50Ci0gICAgICAgICAqIGFzIGEgZ3JvdXAuICBUaGlzIG1lc3NhZ2UgaXMgcmVwb3J0ZWQgaWYgdGhlIG5hbWUgc3BlY2lmaWVkIHdhcyBub3QKLSAgICAgICAgICogdXNlZCB0byBkZWNsYXJlIGFuIGF0dHJpYnV0ZSBzZXQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUKLSAgICAgICAgICogdGhhdCBpcyBpbiBlcnJvci4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5BVFRSSUJTRVRfVU5ERUZfRVJSLAotICAgICAgICAiUG9rdXMgbyBwb3VcdTAxN2VpdGllIG5lZXhpc3R1alx1MDBmYWNlaiBzYWR5IGF0cmliXHUwMGZhdG92ICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSB0ZXJtICJhdHRyaWJ1dGUgdmFsdWUgdGVtcGxhdGUiIGlzIGEgdGVybQotICAgICAgICAgKiBkZWZpbmVkIGJ5IFhTTFQgd2hpY2ggZGVzY3JpYmVzIHRoZSB2YWx1ZSBvZiBhbiBhdHRyaWJ1dGUgdGhhdCBpcwotICAgICAgICAgKiBkZXRlcm1pbmVkIGJ5IGFuIFhQYXRoIGV4cHJlc3Npb24uICBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUKLSAgICAgICAgICogZXhwcmVzc2lvbiB3YXMgc3ludGFjdGljYWxseSBpbmNvcnJlY3Q7IHRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICAgKiBjb250YWlucyB0aGUgZXhwcmVzc2lvbiB0aGF0IHdhcyBpbiBlcnJvci4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5BVFRSX1ZBTF9URU1QTEFURV9FUlIsCi0gICAgICAgICJOaWUgamUgbW9cdTAxN2VuXHUwMGU5IGFuYWx5em92YVx1MDE2NSB2em9yIGhvZG5vdHkgYXRyaWJcdTAwZmF0dSAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICA/Pz8KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5VTktOT1dOX1NJR19UWVBFX0VSUiwKLSAgICAgICAgIk5lem5cdTAwZTFteSB0eXAgXHUwMGZhZGFqb3YgdiBwb2RwaXNlIHByZSB0cmllZHUgJyd7MH0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHJlZmVycyB0byBkYXRhIHR5cGVzLgotICAgICAgICAgKiBUaGUgbWVzc2FnZSBpcyBkaXNwbGF5ZWQgaWYgYSB2YWx1ZSBpbiBhIHBhcnRpY3VsYXIgY29udGV4dCBuZWVkcyB0bwotICAgICAgICAgKiBiZSBjb252ZXJ0ZWQgdG8gdHlwZSB7MX0sIGJ1dCB0aGF0J3Mgbm90IHBvc3NpYmxlIGZvciBhIHZhbHVlIG9mCi0gICAgICAgICAqIHR5cGUgezB9LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkRBVEFfQ09OVkVSU0lPTl9FUlIsCi0gICAgICAgICJOaWUgamUgbW9cdTAxN2VuXHUwMGU5IGtvbnZlcnRvdmFcdTAxNjUgdHlwIFx1MDBmYWRham92ICcnezB9JycgbmEgJyd7MX0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIlRlbXBsYXRlcyIgaXMgYSBKYXZhIGNsYXNzIG5hbWUgdGhhdCBzaG91bGQKLSAgICAgICAgICogbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTk9fVFJBTlNMRVRfQ0xBU1NfRVJSLAotICAgICAgICAiVGVudG8gdnpvciBuZW9ic2FodWplIHBsYXRuXHUwMGZhIGRlZmluXHUwMGVkY2l1IHRyaWVkeSB0cmFuc2xldHUuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJUZW1wbGF0ZXMiIGlzIGEgSmF2YSBjbGFzcyBuYW1lIHRoYXQgc2hvdWxkCi0gICAgICAgICAqIG5vdCBiZSB0cmFuc2xhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk5PX01BSU5fVFJBTlNMRVRfRVJSLAotICAgICAgICAiVGVudG8gdnpvciBuZW9ic2FodWplIHRyaWVkdSBzIG5cdTAwZTF6dm9tICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBhIGNsYXNzLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlRSQU5TTEVUX0NMQVNTX0VSUiwKLSAgICAgICAgIk5lYm9sbyBtb1x1MDE3ZW5cdTAwZTkgemF2aWVzXHUwMTY1IHRyaWVkdSB0cmFuc2xldHUgJyd7MH0nJy4ifSwKLQotICAgICAgICB7RXJyb3JNc2cuVFJBTlNMRVRfT0JKRUNUX0VSUiwKLSAgICAgICAgIlRyaWVkYSB0cmFuc2xldHUgemF2ZWRlblx1MDBlMSwgYWxlIG5pZSBqZSBtb1x1MDE3ZW5cdTAwZTkgdnl0dm9yaVx1MDE2NSBpblx1MDE2MXRhbmNpdSB0cmFuc2xldHUuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJFcnJvckxpc3RlbmVyIiBpcyBhIEphdmEgaW50ZXJmYWNlIG5hbWUgdGhhdAotICAgICAgICAgKiBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUgdXNlciB0cmllZAotICAgICAgICAgKiB0byBzZXQgYW4gRXJyb3JMaXN0ZW5lciBvYmplY3Qgb24gb2JqZWN0IG9mIHRoZSBjbGFzcyBuYW1lZCBpbiB0aGUKLSAgICAgICAgICogc3Vic3RpdHV0aW9uIHRleHQgd2l0aCAibnVsbCIgSmF2YSB2YWx1ZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5FUlJPUl9MSVNURU5FUl9OVUxMX0VSUiwKLSAgICAgICAgIlBva3VzIG8gbmFzdGF2ZW5pZSBFcnJvckxpc3RlbmVyIHByZSAnJ3swfScnIG5hIG51bGwifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgU3RyZWFtU291cmNlLCBTQVhTb3VyY2UgYW5kIERPTVNvdXJjZSBhcmUgSmF2YQotICAgICAgICAgKiBpbnRlcmZhY2UgbmFtZXMgdGhhdCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSkFYUF9VTktOT1dOX1NPVVJDRV9FUlIsCi0gICAgICAgICJYU0xUQyBwb2Rwb3J1amUgbGVuIFN0cmVhbVNvdXJjZSwgU0FYU291cmNlIGEgRE9NU291cmNlIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJTb3VyY2UiIGlzIGEgSmF2YSBjbGFzcyBuYW1lIHRoYXQgc2hvdWxkIG5vdAotICAgICAgICAgKiBiZSB0cmFuc2xhdGVkLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIEphdmEgbWV0aG9kLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfTk9fU09VUkNFX0VSUiwKLSAgICAgICAgIk9iamVrdCB6ZHJvamEgb2RvdnpkYW5cdTAwZmQgJyd7MH0nJyBuZW1cdTAwZTEgXHUwMTdlaWFkbnkgb2JzYWguIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBtZXNzYWdlIGluZGljYXRlcyB0aGF0IFhTTFRDIGZhaWxlZCB0bwotICAgICAgICAgKiBjb21waWxlIHRoZSBzdHlsZXNoZWV0IGludG8gYSB0cmFuc2xldCAoY2xhc3MgZmlsZSkuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSkFYUF9DT01QSUxFX0VSUiwKLSAgICAgICAgIk5lYm9sbyBtb1x1MDE3ZW5cdTAwZTkgc2tvbXBpbG92YVx1MDE2NSBcdTAxNjF0XHUwMGZkbCBkb2t1bWVudHUifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIlRyYW5zZm9ybWVyRmFjdG9yeSIgaXMgYSBjbGFzcyBuYW1lLiAgSW4gdGhpcwotICAgICAgICAgKiBjb250ZXh0LCBhbiBhdHRyaWJ1dGUgaXMgYSBwcm9wZXJ0eSBvciBzZXR0aW5nIG9mIHRoZQotICAgICAgICAgKiBUcmFuc2Zvcm1lckZhY3Rvcnkgb2JqZWN0LiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIHRoZQotICAgICAgICAgKiB1bnJlY29nbmlzZWQgYXR0cmlidXRlLiAgVGhlIG1ldGhvZCB1c2VkIHRvIHJldHJpZXZlIHRoZSBhdHRyaWJ1dGUgaXMKLSAgICAgICAgICogImdldEF0dHJpYnV0ZSIsIHNvIGl0J3Mgbm90IGNsZWFyIHdoZXRoZXIgaXQgd291bGQgYmUgYmVzdCB0bwotICAgICAgICAgKiB0cmFuc2xhdGUgdGhlIHRlcm0gImF0dHJpYnV0ZSIuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSkFYUF9JTlZBTElEX0FUVFJfRVJSLAotICAgICAgICAiVHJhbnNmb3JtZXJGYWN0b3J5IG5lcm96b3puXHUwMGUxdmEgYXRyaWJcdTAwZmF0ICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJzZXRSZXN1bHQoKSIgYW5kICJzdGFydERvY3VtZW50KCkiIGFyZSBKYXZhCi0gICAgICAgICAqIG1ldGhvZCBuYW1lcyB0aGF0IHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX1NFVF9SRVNVTFRfRVJSLAotICAgICAgICAic2V0UmVzdWx0KCkgc2EgbXVzXHUwMGVkIHZvbGFcdTAxNjUgcHJlZCBzdGFydERvY3VtZW50KCkuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJUcmFuc2Zvcm1lciIgaXMgYSBKYXZhIGludGVyZmFjZSBuYW1lIHRoYXQKLSAgICAgICAgICogc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgQSBUcmFuc2Zvcm1lciBvYmplY3Qgc2hvdWxkIGNvbnRhaW5lZCBhCi0gICAgICAgICAqIHJlZmVyZW5jZSB0byBhIHRyYW5zbGV0IG9iamVjdCBpbiBvcmRlciB0byBiZSB1c2VkIGZvcgotICAgICAgICAgKiB0cmFuc2Zvcm1hdGlvbnM7IHRoaXMgbWVzc2FnZSBpcyBwcm9kdWNlZCBpZiB0aGF0IHJlcXVpcmVtZW50IGlzIG5vdAotICAgICAgICAgKiBtZXQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSkFYUF9OT19UUkFOU0xFVF9FUlIsCi0gICAgICAgICJUcmFuc2Zvcm1cdTAwZTF0b3IgbmVtXHUwMGUxIFx1MDE3ZWlhZG55IHphcHV6ZHJlblx1MDBmZCBvYmpla3QgdHJhbnNsZXR1LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgWE1MIGRvY3VtZW50IHRoYXQgcmVzdWx0cyBmcm9tIGEKLSAgICAgICAgICogdHJhbnNmb3JtYXRpb24gbmVlZHMgdG8gYmUgc2VudCB0byBhbiBvdXRwdXQgaGFuZGxlciBvYmplY3Q7IHRoaXMKLSAgICAgICAgICogbWVzc2FnZSBpcyBwcm9kdWNlZCBpZiB0aGF0IHJlcXVpcmVtZW50IGlzIG5vdCBtZXQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSkFYUF9OT19IQU5ETEVSX0VSUiwKLSAgICAgICAgIlByZSB2XHUwMGZkc2xlZG9rIHRyYW5zZm9ybVx1MDBlMWNpZSBuZWJvbCBkZWZpbm92YW5cdTAwZmQgXHUwMTdlaWFkbnkgdlx1MDBmZHN0dXBuXHUwMGZkIGhhbmRsZXIuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJSZXN1bHQiIGlzIGEgSmF2YSBpbnRlcmZhY2UgbmFtZSBpbiB0aGlzCi0gICAgICAgICAqIGNvbnRleHQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgYSBtZXRob2QgbmFtZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX05PX1JFU1VMVF9FUlIsCi0gICAgICAgICJPYmpla3Qgdlx1MDBmZHNsZWRrdSBvZG92emRhblx1MDBmZCAnJ3swfScnIGplIG5lcGxhdG5cdTAwZmQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJUcmFuc2Zvcm1lciIgaXMgYSBKYXZhIGludGVyZmFjZSBuYW1lLiAgVGhlCi0gICAgICAgICAqIHVzZXIncyBwcm9ncmFtIGF0dGVtcHRlZCB0byBhY2Nlc3MgYW4gdW5yZWNvZ25pemVkIHByb3BlcnR5IHdpdGggdGhlCi0gICAgICAgICAqIG5hbWUgc3BlY2lmaWVkIGluIHRoZSBzdWJzdGl0dXRpb24gdGV4dC4gIFRoZSBtZXRob2QgdXNlZCB0byByZXRyaWV2ZQotICAgICAgICAgKiB0aGUgcHJvcGVydHkgaXMgImdldE91dHB1dFByb3BlcnR5Iiwgc28gaXQncyBub3QgY2xlYXIgd2hldGhlciBpdAotICAgICAgICAgKiB3b3VsZCBiZSBiZXN0IHRvIHRyYW5zbGF0ZSB0aGUgdGVybSAicHJvcGVydHkiLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfVU5LTk9XTl9QUk9QX0VSUiwKLSAgICAgICAgIlBva3VzIG8gcHJcdTAwZWRzdHVwIGsgbmVwbGF0blx1MDBlOW11IG1hamV0a3UgdHJhbnNmb3JtXHUwMGUxdG9yYSAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBTQVgyRE9NIGlzIHRoZSBuYW1lIG9mIGEgSmF2YSBjbGFzcyB0aGF0IHNob3VsZAotICAgICAgICAgKiBub3QgYmUgdHJhbnNsYXRlZC4gIFRoaXMgaXMgYW4gYWRhcHRlciBpbiB0aGUgc2Vuc2UgdGhhdCBpdCB0YWtlcyBhCi0gICAgICAgICAqIERPTSBvYmplY3QgYW5kIGNvbnZlcnRzIGl0IHRvIHNvbWV0aGluZyB0aGF0IHVzZXMgdGhlIFNBWCBBUEkuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuU0FYMkRPTV9BREFQVEVSX0VSUiwKLSAgICAgICAgIk5lYm9sbyBtb1x1MDE3ZW5cdTAwZTkgdnl0dm9yaVx1MDE2NSBhZGFwdFx1MDBlOXIgU0FYMkRPTTogJyd7MH0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIlhTTFRDU291cmNlLmJ1aWxkKCkiIGlzIGEgSmF2YSBtZXRob2QgbmFtZS4KLSAgICAgICAgICogInN5c3RlbUlkIiBpcyBhbiBYTUwgdGVybSB0aGF0IGlzIHNob3J0IGZvciAic3lzdGVtIGlkZW50aWZpY2F0aW9uIi4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5YU0xUQ19TT1VSQ0VfRVJSLAotICAgICAgICAiWFNMVENTb3VyY2UuYnVpbGQoKSBib2wgemF2b2xhblx1MDBmZCBiZXogbmFzdGF2ZW5cdTAwZTlobyBzeXN0ZW1JZC4ifSwKLQotCi0gICAgICAgIHtFcnJvck1zZy5DT01QSUxFX1NURElOX0VSUiwKLSAgICAgICAgIlZvXHUwMTNlYmEgLWkgc2EgbXVzXHUwMGVkIHBvdVx1MDE3ZVx1MDBlZHZhXHUwMTY1IHMgdm9cdTAxM2Vib3UgLW8uIn0sCi0KLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGNvbnRhaW5zIHVzYWdlIGluZm9ybWF0aW9uIGZvciBhCi0gICAgICAgICAqIG1lYW5zIG9mIGludm9raW5nIFhTTFRDIGZyb20gdGhlIGNvbW1hbmQtbGluZS4gIFRoZSBtZXNzYWdlIGlzCi0gICAgICAgICAqIGZvcm1hdHRlZCBmb3IgcHJlc2VudGF0aW9uIGluIEVuZ2xpc2guICBUaGUgc3RyaW5ncyA8b3V0cHV0PiwKLSAgICAgICAgICogPGRpcmVjdG9yeT4sIGV0Yy4gaW5kaWNhdGUgdXNlci1zcGVjaWZpZWQgYXJndW1lbnQgdmFsdWVzLCBhbmQgY2FuCi0gICAgICAgICAqIGJlIHRyYW5zbGF0ZWQgLSB0aGUgYXJndW1lbnQgPHBhY2thZ2U+IHJlZmVycyB0byBhIEphdmEgcGFja2FnZSwgc28KLSAgICAgICAgICogaXQgc2hvdWxkIGJlIGhhbmRsZWQgaW4gdGhlIHNhbWUgd2F5IHRoZSB0ZXJtIGlzIGhhbmRsZWQgZm9yIEpESwotICAgICAgICAgKiBkb2N1bWVudGF0aW9uLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkNPTVBJTEVfVVNBR0VfU1RSLAotICAgICAgICAiU1lOT1BTSVNcbiAgIGphdmEgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNtZGxpbmUuQ29tcGlsZSBbLW8gPG91dHB1dD5dXG4gICAgICBbLWQgPGRpcmVjdG9yeT5dIFstaiA8amFyZmlsZT5dIFstcCA8cGFja2FnZT5dXG4gICAgICBbLW5dIFsteF0gWy1zXSBbLXVdIFstdl0gWy1oXSB7IDxzdHlsZXNoZWV0PiB8IC1pIH1cblxuT1BUSU9OU1xuICAgLW8gPG91dHB1dD4gICAgcHJpcmFcdTAxMGZ1amUgblx1MDBlMXpvdiA8b3V0cHV0PiBnZW5lcm92YW5cdTAwZTltdSB0cmFuc2xldHUgXG4uIFx1MDE2MHRhbmRhcmRuZSBzYSBuXHUwMGUxem92IHRyYW5zbGV0dSBcbiBiZXJpZSB6IG5cdTAwZTF6dnUgPHN0eWxlc2hlZXQ+LiBUXHUwMGUxdG8gdm9cdTAxM2ViYSBzYSBpZ25vcnVqZSBwcmkga29tcGlsb3Zhblx1MDBlZCB2aWFjZXJcdTAwZmRjaCBcdTAxNjF0XHUwMGZkbG92IGRva3VtZW50b3ZcblxuLiAgIC1kIDxkaXJlY3Rvcnk+IHV2XHUwMGUxZHphIGNpZVx1MDEzZW92XHUwMGZkIGFkcmVzXHUwMGUxciBwcmUgdHJhbnNsZXRcbiAgIC1qIDxqYXJmaWxlPiAgIHBha3VqZSB0cmllZHkgdHJhbnNsZXRvdiBkbyBzXHUwMGZhYm9ydSBqYXIgblx1MDBlMXp2dSBcbiB1dmVkZW5cdTAwZTlobyBha28gPGphcmZpbGU+XG4gICAtcCA8cGFja2FnZT4gICB1dlx1MDBlMWR6YSBwcmVkcG9udSBuXHUwMGUxenZ1IGJhbFx1MDBlZGt1IHByZSB2XHUwMTYxZXRreSBnZW5lcm92YW5cdTAwZTkgdHJpZWR5IHRyYW5zbGV0dS5cblxuICAgLW4gICAgICAgICAgICAgcG92b1x1MDEzZXVqZSB6b3JhZGVuaWUgdnpvcm92IHYgcmlhZGt1IChcdTAxNjF0YW5kYXJkblx1MDBlOSBjaG92YW5pZSB2IHByaWVtZXJlIGxlcFx1MDE2MWllKS4gXG5cbiAgIC14ICAgICAgICAgICAgIHphcFx1MDBlZG5hICAgdlx1MDBmZHN0dXB5IHNwclx1MDBlMXYgbGFkZW5pYSBcbiAgIC1zICAgICAgICAgICAgIHpha2F6dWplIHZvbGFuaWUgU3lzdGVtLmV4aXRcbiAgIC11ICAgICAgICAgICAgIGludGVycHJldHVqZTxzdHlsZXNoZWV0PiBhcmd1bWVudHkgYWtvIFVSTFxuICAgLWkgICAgICAgICAgICAgblx1MDBmYXRpIGtvbXBpbFx1MDBlMXRvciBcdTAxMGRcdTAwZWR0YVx1MDE2NSBcdTAxNjF0XHUwMGZkbCBkb2t1bWVudHUgeiBzdGRpblxuICAgLXYgICAgICAgICAgICAgdGxhXHUwMTBkXHUwMGVkIHZlcnppdSBrb21waWxcdTAwZTF0b3JhXG4gICAtaCAgICAgICAgICAgICB0bGFcdTAxMGRcdTAwZWQgcHJcdTAwZWRrYXogdG9odG8gcG91XHUwMTdlaXRpYVxuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBjb250YWlucyB1c2FnZSBpbmZvcm1hdGlvbiBmb3IgYQotICAgICAgICAgKiBtZWFucyBvZiBpbnZva2luZyBYU0xUQyBmcm9tIHRoZSBjb21tYW5kLWxpbmUuICBUaGUgbWVzc2FnZSBpcwotICAgICAgICAgKiBmb3JtYXR0ZWQgZm9yIHByZXNlbnRhdGlvbiBpbiBFbmdsaXNoLiAgVGhlIHN0cmluZ3MgPGphcmZpbGU+LAotICAgICAgICAgKiA8ZG9jdW1lbnQ+LCBldGMuIGluZGljYXRlIHVzZXItc3BlY2lmaWVkIGFyZ3VtZW50IHZhbHVlcywgYW5kIGNhbgotICAgICAgICAgKiBiZSB0cmFuc2xhdGVkIC0gdGhlIGFyZ3VtZW50IDxjbGFzcz4gcmVmZXJzIHRvIGEgSmF2YSBjbGFzcywgc28gaXQKLSAgICAgICAgICogc2hvdWxkIGJlIGhhbmRsZWQgaW4gdGhlIHNhbWUgd2F5IHRoZSB0ZXJtIGlzIGhhbmRsZWQgZm9yIEpESwotICAgICAgICAgKiBkb2N1bWVudGF0aW9uLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlRSQU5TRk9STV9VU0FHRV9TVFIsCi0gICAgICAgICJTWU5PUFNJUyBcbiAgIGphdmEgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNtZGxpbmUuVHJhbnNmb3JtIFstaiA8amFyZmlsZT5dXG4gICAgICBbLXhdIFstc10gWy1uIDxpdGVyYXRpb25zPl0gey11IDxkb2N1bWVudF91cmw+IHwgPGRvY3VtZW50Pn1cbiAgICAgIDxjbGFzcz4gWzxwYXJhbTE+PTx2YWx1ZTE+IC4uLl1cblxuICAgcG91XHUwMTdlXHUwMGVkdmEgdHJhbnNsZXQgPGNsYXNzPiBuYSB0cmFuc2Zvcm1cdTAwZTFjaXUgZG9rdW1lbnR1IFhNTCBcbiAgIHV2ZWRlblx1MDBlOWhvIGFrbyA8ZG9jdW1lbnQ+LiA8Y2xhc3M+IHRyYW5zbGV0dSBqZSBidVx1MDEwZiB2IFxuIHVcdTAxN2VcdTAwZWR2YXRlXHUwMTNlb3ZlaiBDTEFTU1BBVEggYWxlYm8gdm8gdm9saXRlXHUwMTNlbmUgdXZlZGVub20gPGphcmZpbGU+LlxuVk9cdTAxM2RCWVxuICAgLWogPGphcmZpbGU+ICAgIHV2XHUwMGUxZHphIHNcdTAwZmFib3IgamFyLCB6IGt0b3JcdTAwZTlobyBzYSBtXHUwMGUxIHphdmllc1x1MDE2NSB0cmFuc2xldFxuICAgLXggICAgICAgICAgICAgIHphcFx1MDBlZG5hIFx1MDEwZmFsXHUwMTYxXHUwMGVkIHZcdTAwZmRzdHVwIHNwclx1MDBlMXYgbGFkZW5pYVxuICAgLXMgICAgICAgICAgICAgIHpha2F6dWplIHZvbGFuaWUgU3lzdGVtLmV4aXRcbiAgIC1uIDxpdGVyYXRpb25zPiBzcFx1MDBmYVx1MDE2MVx1MDE2NWEgdHJhbnNmb3JtXHUwMGUxY2l1IDxpdGVyYXRpb25zPiByXHUwMGUxeiBhIFxuICAgICAgICAgICAgICAgICAgIHpvYnJhenVqZSBpbmZvcm1cdTAwZTFjaWUgcHJvZmlsb3ZhbmlhXG4gICAtdSA8ZG9jdW1lbnRfdXJsPiB1dlx1MDBlMWR6YSB2c3R1cG5cdTAwZmQgZG9rdW1lbnQgWE1MIGFrbyBVUkxcbiJ9LAotCi0KLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIjx4c2w6c29ydD4iLCAiPHhzbDpmb3ItZWFjaD4iIGFuZAotICAgICAgICAgKiAiPHhzbDphcHBseS10ZW1wbGF0ZXM+IiBhcmUga2V5d29yZHMgdGhhdCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqIFRoZSBtZXNzYWdlIGluZGljYXRlcyB0aGF0IGFuIHhzbDpzb3J0IGVsZW1lbnQgbXVzdCBiZSBhIGNoaWxkIG9mCi0gICAgICAgICAqIG9uZSBvZiB0aGUgb3RoZXIga2luZHMgb2YgZWxlbWVudHMgbWVudGlvbmVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlNUUkFZX1NPUlRfRVJSLAotICAgICAgICAiPHhzbDpzb3J0PiBtb1x1MDE3ZW5vIHBvdVx1MDE3ZWlcdTAxNjUgbGVuIHYgPHhzbDpmb3ItZWFjaD4gYWxlYm8gPHhzbDphcHBseS10ZW1wbGF0ZXM+LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUgZW5jb2RpbmcKLSAgICAgICAgICogcmVxdWVzdGVkIGZvciB0aGUgb3V0cHV0IGRvY3VtZW50IHdhcyBvbiB0aGF0IHJlcXVpcmVzIHN1cHBvcnQgdGhhdAotICAgICAgICAgKiBpcyBub3QgYXZhaWxhYmxlIGZyb20gdGhlIEphdmEgVmlydHVhbCBNYWNoaW5lIGJlaW5nIHVzZWQgdG8gZXhlY3V0ZQotICAgICAgICAgKiB0aGUgcHJvZ3JhbS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5VTlNVUFBPUlRFRF9FTkNPRElORywKLSAgICAgICAgIlZcdTAwZmRzdHVwblx1MDBlOSBrXHUwMGYzZG92YW5pZSAnJ3swfScnIG5pZSBqZSB2IHRvbXRvIEpWTSBwb2Rwb3JvdmFuXHUwMGU5LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUgWFBhdGggZXhwcmVzc2lvbgotICAgICAgICAgKiBuYW1lZCBpbiB0aGUgc3Vic3RpdHV0aW9uIHRleHQgd2FzIG5vdCB3ZWxsIGZvcm1lZCBzeW50YWN0aWNhbGx5LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlNZTlRBWF9FUlIsCi0gICAgICAgICJDaHliYSBzeW50YXhlIHYgJyd7MH0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIGEgSmF2YQotICAgICAgICAgKiBjbGFzcy4gIFRoZSB0ZXJtICJjb25zdHJ1Y3RvciIgaGVyZSBpcyB0aGUgSmF2YSB0ZXJtLiAgVGhlIG1lc3NhZ2UgaXMKLSAgICAgICAgICogZGlzcGxheWVkIGlmIFhTTFRDIGNvdWxkIG5vdCBmaW5kIGEgY29uc3RydWN0b3IgZm9yIHRoZSBzcGVjaWZpZWQKLSAgICAgICAgICogY2xhc3MuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuQ09OU1RSVUNUT1JfTk9UX0ZPVU5ELAotICAgICAgICAiTmllIGplIG1vXHUwMTdlblx1MDBlOSBuXHUwMGUxanNcdTAxNjUgZXh0ZXJuXHUwMGZkIGtvblx1MDE2MXRydWt0b3IgJyd7MH0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgInN0YXRpYyIgaXMgdGhlIEphdmEga2V5d29yZC4gIFRoZSBzdWJzdGl0dXRpb24KLSAgICAgICAgICogdGV4dCBpcyB0aGUgbmFtZSBvZiBhIGZ1bmN0aW9uLiAgVGhlIGZpcnN0IGFyZ3VtZW50IG9mIHRoYXQgZnVuY3Rpb24KLSAgICAgICAgICogaXMgbm90IG9mIHRoZSByZXF1aXJlZCB0eXBlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk5PX0pBVkFfRlVOQ1RfVEhJU19SRUYsCi0gICAgICAgICJQcnZcdTAwZmQgYXJndW1lbnQgcHJlIG5lc3RhdGlja1x1MDBmYSBmdW5rY2l1IEphdmEgJyd7MH0nJyBuaWUgamUgcGxhdG5vdSByZWZlcmVuY2lvdSBvYmpla3R1LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBbiBYUGF0aCBleHByZXNzaW9uIHdhcyBub3Qgb2YgdGhlIHR5cGUKLSAgICAgICAgICogcmVxdWlyZWQgaW4gYSBwYXJ0aWN1bGFyIGNvbnRleHQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlCi0gICAgICAgICAqIGV4cHJlc3Npb24gdGhhdCB3YXMgaW4gZXJyb3IuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVFlQRV9DSEVDS19FUlIsCi0gICAgICAgICJDaHliYSBwcmkga29udHJvbGUgdHlwdSB2XHUwMGZkcmF6dSAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBbiBYUGF0aCBleHByZXNzaW9uIHdhcyBub3Qgb2YgdGhlIHR5cGUKLSAgICAgICAgICogcmVxdWlyZWQgaW4gYSBwYXJ0aWN1bGFyIGNvbnRleHQuICBIb3dldmVyLCB0aGUgbG9jYXRpb24gb2YgdGhlCi0gICAgICAgICAqIHByb2JsZW1hdGljIGV4cHJlc3Npb24gaXMgdW5rbm93bi4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5UWVBFX0NIRUNLX1VOS19MT0NfRVJSLAotICAgICAgICAiQ2h5YmEgcHJpIGtvbnRyb2xlIHR5cHUgdlx1MDBmZHJhenUgbmEgbmV6blx1MDBlMW1vbSBtaWVzdGUuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBhIGNvbW1hbmQtCi0gICAgICAgICAqIGxpbmUgb3B0aW9uIHRoYXQgd2FzIG5vdCByZWNvZ25pemVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfQ01ETElORV9PUFRJT05fRVJSLAotICAgICAgICAiVm9cdTAxM2ViYSBwclx1MDBlZGthem92XHUwMGU5aG8gcmlhZGthICcnezB9JycgamUgbmVwbGF0blx1MDBlMS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIGEgY29tbWFuZC0KLSAgICAgICAgICogbGluZSBvcHRpb24uCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuQ01ETElORV9PUFRfTUlTU0lOR19BUkdfRVJSLAotICAgICAgICAiVm9cdTAxM2ViZSBwclx1MDBlZGthem92XHUwMGU5aG8gcmlhZGthICcnezB9JycgY2hcdTAwZmRiYSBwb1x1MDE3ZWFkb3Zhblx1MDBmZCBhcmd1bWVudC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIHVzZWQgdG8gaW5kaWNhdGUgdGhlIHNldmVyaXR5Ci0gICAgICAgICAqIG9mIGFub3RoZXIgbWVzc2FnZS4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBjb250YWlucyB0d28gZXJyb3IKLSAgICAgICAgICogbWVzc2FnZXMuICBUaGUgc3BhY2luZyBiZWZvcmUgdGhlIHNlY29uZCBzdWJzdGl0dXRpb24gdGV4dCBpbmRlbnRzCi0gICAgICAgICAqIGl0IHRoZSBzYW1lIGFtb3VudCBhcyB0aGUgZmlyc3QgaW4gRW5nbGlzaC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5XQVJOSU5HX1BMVVNfV1JBUFBFRF9NU0csCi0gICAgICAgICJVUE9aT1JORU5JRTogICcnezB9JydcbiAgICAgICA6ezF9In0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyB1c2VkIHRvIGluZGljYXRlIHRoZSBzZXZlcml0eQotICAgICAgICAgKiBvZiBhbm90aGVyIG1lc3NhZ2UuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgYW4gZXJyb3IgbWVzc2FnZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5XQVJOSU5HX01TRywKLSAgICAgICAgIlVQT1pPUk5FTklFOiAgJyd7MH0nJyJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgdXNlZCB0byBpbmRpY2F0ZSB0aGUgc2V2ZXJpdHkKLSAgICAgICAgICogb2YgYW5vdGhlciBtZXNzYWdlLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGNvbnRhaW5zIHR3byBlcnJvcgotICAgICAgICAgKiBtZXNzYWdlcy4gIFRoZSBzcGFjaW5nIGJlZm9yZSB0aGUgc2Vjb25kIHN1YnN0aXR1dGlvbiB0ZXh0IGluZGVudHMKLSAgICAgICAgICogaXQgdGhlIHNhbWUgYW1vdW50IGFzIHRoZSBmaXJzdCBpbiBFbmdsaXNoLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkZBVEFMX0VSUl9QTFVTX1dSQVBQRURfTVNHLAotICAgICAgICAiS1JJVElDS1x1MDBjMSBDSFlCQTogICcnezB9JydcbiAgICAgICAgICAgOnsxfSJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgdXNlZCB0byBpbmRpY2F0ZSB0aGUgc2V2ZXJpdHkKLSAgICAgICAgICogb2YgYW5vdGhlciBtZXNzYWdlLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIGFuIGVycm9yIG1lc3NhZ2UuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuRkFUQUxfRVJSX01TRywKLSAgICAgICAgIktSSVRJQ0tcdTAwYzEgQ0hZQkE6ICAnJ3swfScnIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyB1c2VkIHRvIGluZGljYXRlIHRoZSBzZXZlcml0eQotICAgICAgICAgKiBvZiBhbm90aGVyIG1lc3NhZ2UuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgY29udGFpbnMgdHdvIGVycm9yCi0gICAgICAgICAqIG1lc3NhZ2VzLiAgVGhlIHNwYWNpbmcgYmVmb3JlIHRoZSBzZWNvbmQgc3Vic3RpdHV0aW9uIHRleHQgaW5kZW50cwotICAgICAgICAgKiBpdCB0aGUgc2FtZSBhbW91bnQgYXMgdGhlIGZpcnN0IGluIEVuZ2xpc2guCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuRVJST1JfUExVU19XUkFQUEVEX01TRywKLSAgICAgICAgIkNIWUJBOiAgJyd7MH0nJ1xuICAgICA6ezF9In0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyB1c2VkIHRvIGluZGljYXRlIHRoZSBzZXZlcml0eQotICAgICAgICAgKiBvZiBhbm90aGVyIG1lc3NhZ2UuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgYW4gZXJyb3IgbWVzc2FnZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5FUlJPUl9NU0csCi0gICAgICAgICJDSFlCQTogICcnezB9JycifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIGEgY2xhc3MuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVFJBTlNGT1JNX1dJVEhfVFJBTlNMRVRfU1RSLAotICAgICAgICAiVHJhbnNmb3JtXHUwMGUxY2lhIHBvbW9jb3UgdHJhbnNsZXR1ICcnezB9JycgIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmaXJzdCBzdWJzdGl0dXRpb24gaXMgdGhlIG5hbWUgb2YgYSBjbGFzcywKLSAgICAgICAgICogd2hpbGUgdGhlIHNlY29uZCBzdWJzdGl0dXRpb24gaXMgdGhlIG5hbWUgb2YgYSBqYXIgZmlsZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5UUkFOU0ZPUk1fV0lUSF9KQVJfU1RSLAotICAgICAgICAiVHJhbnNmb3JtXHUwMGUxY2lhIHBvbW9jb3UgdHJhbnNsZXR1ICcnezB9Jycgem8gc1x1MDBmYWJvcnUgamFyICcnezF9JycifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIlRyYW5zZm9ybWVyRmFjdG9yeSIgaXMgdGhlIG5hbWUgb2YgYSBKYXZhCi0gICAgICAgICAqIGludGVyZmFjZSBhbmQgbXVzdCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcwotICAgICAgICAgKiB0aGUgbmFtZSBvZiB0aGUgY2xhc3MgdGhhdCBjb3VsZCBub3QgYmUgaW5zdGFudGlhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkNPVUxEX05PVF9DUkVBVEVfVFJBTlNfRkFDVCwKLSAgICAgICAgIk5lYm9sbyBtb1x1MDE3ZW5cdTAwZTkgdnl0dm9yaVx1MDE2NSBpblx1MDE2MXRhbmNpdSB0cmllZHkgVHJhbnNmb3JtZXJGYWN0b3J5ICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBpcyB1c2VkIGFzIGEgaGVhZGVyLgotICAgICAgICAgKiBBbGwgdGhlIGVycm9yIG1lc3NhZ2VzIGFyZSBjb2xsZWN0ZWQgdG9nZXRoZXIgYW5kIGRpc3BsYXllZCBiZW5lYXRoCi0gICAgICAgICAqIHRoaXMgbWVzc2FnZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5DT01QSUxFUl9FUlJPUl9LRVksCi0gICAgICAgICJDaHlieSBwcmVrbGFkYVx1MDEwZGE6In0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBpcyB1c2VkIGFzIGEgaGVhZGVyLgotICAgICAgICAgKiBBbGwgdGhlIHdhcm5pbmcgbWVzc2FnZXMgYXJlIGNvbGxlY3RlZCB0b2dldGhlciBhbmQgZGlzcGxheWVkCi0gICAgICAgICAqIGJlbmVhdGggdGhpcyBtZXNzYWdlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkNPTVBJTEVSX1dBUk5JTkdfS0VZLAotICAgICAgICAiVXBvem9ybmVuaWEgcHJla2xhZGFcdTAxMGRhOiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgaXMgdXNlZCBhcyBhIGhlYWRlci4KLSAgICAgICAgICogQWxsIHRoZSBlcnJvciBtZXNzYWdlcyB0aGF0IGFyZSBwcm9kdWNlZCB3aGVuIHRoZSBzdHlsZXNoZWV0IGlzCi0gICAgICAgICAqIGFwcGxpZWQgdG8gYW4gaW5wdXQgZG9jdW1lbnQgYXJlIGNvbGxlY3RlZCB0b2dldGhlciBhbmQgZGlzcGxheWVkCi0gICAgICAgICAqIGJlbmVhdGggdGhpcyBtZXNzYWdlLiAgQSAndHJhbnNsZXQnIGlzIHRoZSBjb21waWxlZCBmb3JtIG9mIGEKLSAgICAgICAgICogc3R5bGVzaGVldCAoc2VlIGFib3ZlKS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5SVU5USU1FX0VSUk9SX0tFWSwKLSAgICAgICAgIkNoeWJ5IHRyYW5zbGV0dToifSwKLQotICAgICAgICB7RXJyb3JNc2cuSkFYUF9TRUNVUkVQUk9DRVNTSU5HX0ZFQVRVUkUsCi0gICAgICAgICJGRUFUVVJFX1NFQ1VSRV9QUk9DRVNTSU5HOiBDYW5ub3Qgc2V0IHRoZSBmZWF0dXJlIHRvIGZhbHNlIHdoZW4gc2VjdXJpdHkgbWFuYWdlciBpcyBwcmVzZW50LiJ9Ci0gICAgfTsKLQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvdXRpbC9FcnJvck1lc3NhZ2VzX3N2LmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL3V0aWwvRXJyb3JNZXNzYWdlc19zdi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwOTIwZjQ0Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvdXRpbC9FcnJvck1lc3NhZ2VzX3N2LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5NzQgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsOwotCi1pbXBvcnQgamF2YS51dGlsLkxpc3RSZXNvdXJjZUJ1bmRsZTsKLQotLyoqCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqLwotcHVibGljIGNsYXNzIEVycm9yTWVzc2FnZXNfc3YgZXh0ZW5kcyBMaXN0UmVzb3VyY2VCdW5kbGUgewotCi0vKgotICogWFNMVEMgY29tcGlsZS10aW1lIGVycm9yIG1lc3NhZ2VzLgotICoKLSAqIEdlbmVyYWwgbm90ZXMgdG8gdHJhbnNsYXRvcnMgYW5kIGRlZmluaXRpb25zOgotICoKLSAqICAgMSkgWFNMVEMgaXMgdGhlIG5hbWUgb2YgdGhlIHByb2R1Y3QuICBJdCBpcyBhbiBhY3JvbnltIGZvciAiWFNMVCBDb21waWxlciIuCi0gKiAgICAgIFhTTFQgaXMgYW4gYWNyb255bSBmb3IgIlhNTCBTdHlsZXNoZWV0IExhbmd1YWdlOiBUcmFuc2Zvcm1hdGlvbnMiLgotICoKLSAqICAgMikgQSBzdHlsZXNoZWV0IGlzIGEgZGVzY3JpcHRpb24gb2YgaG93IHRvIHRyYW5zZm9ybSBhbiBpbnB1dCBYTUwgZG9jdW1lbnQKLSAqICAgICAgaW50byBhIHJlc3VsdGFudCBYTUwgZG9jdW1lbnQgKG9yIEhUTUwgZG9jdW1lbnQgb3IgdGV4dCkuICBUaGUKLSAqICAgICAgc3R5bGVzaGVldCBpdHNlbGYgaXMgZGVzY3JpYmVkIGluIHRoZSBmb3JtIG9mIGFuIFhNTCBkb2N1bWVudC4KLSAqCi0gKiAgIDMpIEEgdGVtcGxhdGUgaXMgYSBjb21wb25lbnQgb2YgYSBzdHlsZXNoZWV0IHRoYXQgaXMgdXNlZCB0byBtYXRjaCBhCi0gKiAgICAgIHBhcnRpY3VsYXIgcG9ydGlvbiBvZiBhbiBpbnB1dCBkb2N1bWVudCBhbmQgc3BlY2lmaWVzIHRoZSBmb3JtIG9mIHRoZQotICogICAgICBjb3JyZXNwb25kaW5nIHBvcnRpb24gb2YgdGhlIG91dHB1dCBkb2N1bWVudC4KLSAqCi0gKiAgIDQpIEFuIGF4aXMgaXMgYSBwYXJ0aWN1bGFyICJkaW1lbnNpb24iIGluIGEgdHJlZSByZXByZXNlbnRhdGlvbiBvZiBhbiBYTUwKLSAqICAgICAgZG9jdW1lbnQ7IHRoZSBub2RlcyBpbiB0aGUgdHJlZSBhcmUgZGl2aWRlZCBhbG9uZyBkaWZmZXJlbnQgYXhlcy4KLSAqICAgICAgVHJhdmVyc2luZyB0aGUgImNoaWxkIiBheGlzLCBmb3IgaW5zdGFuY2UsIG1lYW5zIHRoYXQgdGhlIHByb2dyYW0KLSAqICAgICAgd291bGQgdmlzaXQgZWFjaCBjaGlsZCBvZiBhIHBhcnRpY3VsYXIgbm9kZTsgdHJhdmVyc2luZyB0aGUgImRlc2NlbmRhbnQiCi0gKiAgICAgIGF4aXMgbWVhbnMgdGhhdCB0aGUgcHJvZ3JhbSB3b3VsZCB2aXNpdCB0aGUgY2hpbGQgbm9kZXMgb2YgYSBwYXJ0aWN1bGFyCi0gKiAgICAgIG5vZGUsIHRoZWlyIGNoaWxkcmVuLCBhbmQgc28gb24gdW50aWwgdGhlIGxlYWYgbm9kZXMgb2YgdGhlIHRyZWUgYXJlCi0gKiAgICAgIHJlYWNoZWQuCi0gKgotICogICA1KSBBbiBpdGVyYXRvciBpcyBhbiBvYmplY3QgdGhhdCB0cmF2ZXJzZXMgbm9kZXMgaW4gYSB0cmVlIGFsb25nIGEKLSAqICAgICAgcGFydGljdWxhciBheGlzLCBvbmUgYXQgYSB0aW1lLgotICoKLSAqICAgNikgQW4gZWxlbWVudCBpcyBhIG1hcmstdXAgdGFnIGluIGFuIFhNTCBkb2N1bWVudDsgYW4gYXR0cmlidXRlIGlzIGEKLSAqICAgICAgbW9kaWZpZXIgb24gdGhlIHRhZy4gIEZvciBleGFtcGxlLCBpbiA8ZWxlbSBhdHRyPSd2YWwnIGF0dHIyPSd2YWwyJz4KLSAqICAgICAgImVsZW0iIGlzIGFuIGVsZW1lbnQgbmFtZSwgImF0dHIiIGFuZCAiYXR0cjIiIGFyZSBhdHRyaWJ1dGUgbmFtZXMgd2l0aAotICogICAgICB0aGUgdmFsdWVzICJ2YWwiIGFuZCAidmFsMiIsIHJlc3BlY3RpdmVseS4KLSAqCi0gKiAgIDcpIEEgbmFtZXNwYWNlIGRlY2xhcmF0aW9uIGlzIGEgc3BlY2lhbCBhdHRyaWJ1dGUgdGhhdCBpcyB1c2VkIHRvIGFzc29jaWF0ZQotICogICAgICBhIHByZWZpeCB3aXRoIGEgVVJJICh0aGUgbmFtZXNwYWNlKS4gIFRoZSBtZWFuaW5ncyBvZiBlbGVtZW50IG5hbWVzIGFuZAotICogICAgICBhdHRyaWJ1dGUgbmFtZXMgdGhhdCB1c2UgdGhhdCBwcmVmaXggYXJlIGRlZmluZWQgd2l0aCByZXNwZWN0IHRvIHRoYXQKLSAqICAgICAgbmFtZXNwYWNlLgotICoKLSAqICAgOCkgRE9NIGlzIGFuIGFjcm9ueW0gZm9yIERvY3VtZW50IE9iamVjdCBNb2RlbC4gIEl0IGlzIGEgdHJlZQotICogICAgICByZXByZXNlbnRhdGlvbiBvZiBhbiBYTUwgZG9jdW1lbnQuCi0gKgotICogICAgICBTQVggaXMgYW4gYWNyb255bSBmb3IgdGhlIFNpbXBsZSBBUEkgZm9yIFhNTCBwcm9jZXNzaW5nLiAgSXQgaXMgYW4gQVBJCi0gKiAgICAgIHVzZWQgaW5mb3JtIGFuIFhNTCBwcm9jZXNzb3IgKGluIHRoaXMgY2FzZSBYU0xUQykgb2YgdGhlIHN0cnVjdHVyZSBhbmQKLSAqICAgICAgY29udGVudCBvZiBhbiBYTUwgZG9jdW1lbnQuCi0gKgotICogICAgICBJbnB1dCB0byB0aGUgc3R5bGVzaGVldCBwcm9jZXNzb3IgY2FuIGNvbWUgZnJvbSBhbiBYTUwgcGFyc2VyIGluIHRoZQotICogICAgICBmb3JtIG9mIGEgRE9NIHRyZWUgb3IgdGhyb3VnaCB0aGUgU0FYIEFQSS4KLSAqCi0gKiAgIDkpIERURCBpcyBhIGRvY3VtZW50IHR5cGUgZGVjbGFyYXRpb24uICBJdCBpcyBhIHdheSBvZiBzcGVjaWZ5aW5nIHRoZQotICogICAgICBncmFtbWFyIGZvciBhbiBYTUwgZmlsZSwgdGhlIG5hbWVzIGFuZCB0eXBlcyBvZiBlbGVtZW50cywgYXR0cmlidXRlcywKLSAqICAgICAgZXRjLgotICoKLSAqICAxMCkgWFBhdGggaXMgYSBzcGVjaWZpY2F0aW9uIHRoYXQgZGVzY3JpYmVzIGEgbm90YXRpb24gZm9yIGlkZW50aWZ5aW5nCi0gKiAgICAgIG5vZGVzIGluIGEgdHJlZS1zdHJ1Y3R1cmVkIHJlcHJlc2VudGF0aW9uIG9mIGFuIFhNTCBkb2N1bWVudC4gIEFuCi0gKiAgICAgIGluc3RhbmNlIG9mIHRoYXQgbm90YXRpb24gaXMgcmVmZXJyZWQgdG8gYXMgYW4gWFBhdGggZXhwcmVzc2lvbi4KLSAqCi0gKiAgMTEpIFRyYW5zbGV0IGlzIGFuIGludmVudGVkIHRlcm0gdGhhdCByZWZlcnMgdG8gdGhlIGNsYXNzIGZpbGUgdGhhdCBjb250YWlucwotICogICAgICB0aGUgY29tcGlsZWQgZm9ybSBvZiBhIHN0eWxlc2hlZXQuCi0gKi8KLQotICAgIC8vIFRoZXNlIG1lc3NhZ2Ugc2hvdWxkIGJlIHJlYWQgZnJvbSBhIGxvY2FsZS1zcGVjaWZpYyByZXNvdXJjZSBidW5kbGUKLSAgICAvKiogR2V0IHRoZSBsb29rdXAgdGFibGUgZm9yIGVycm9yIG1lc3NhZ2VzLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgbWVzc2FnZSBsb29rdXAgdGFibGUuCi0gICAgICovCi0gICAgcHVibGljIE9iamVjdFtdW10gZ2V0Q29udGVudHMoKQotICAgIHsKLSAgICAgIHJldHVybiBuZXcgT2JqZWN0W11bXSB7Ci0gICAgICAgIHtFcnJvck1zZy5NVUxUSVBMRV9TVFlMRVNIRUVUX0VSUiwKLSAgICAgICAgIkZsZXIgXHUwMEU0biBlbiBmb3JtYXRtYWxsIGhhciBkZWZpbmllcmF0cyBpIHNhbW1hIGZpbC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIGEKLSAgICAgICAgICogdGVtcGxhdGUuICBUaGUgc2FtZSBuYW1lIHdhcyB1c2VkIG9uIHR3byBkaWZmZXJlbnQgdGVtcGxhdGVzIGluIHRoZQotICAgICAgICAgKiBzYW1lIHN0eWxlc2hlZXQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVEVNUExBVEVfUkVERUZfRVJSLAotICAgICAgICAiTWFsbGVuICcnezB9JycgaGFyIHJlZGFuIGRlZmluaWVyYXRzIGkgZGVubmEgZm9ybWF0bWFsbC4ifSwKLQotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYQotICAgICAgICAgKiB0ZW1wbGF0ZS4gIEEgcmVmZXJlbmNlIHRvIHRoZSB0ZW1wbGF0ZSBuYW1lIHdhcyBlbmNvdW50ZXJlZCwgYnV0IHRoZQotICAgICAgICAgKiB0ZW1wbGF0ZSBpcyB1bmRlZmluZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVEVNUExBVEVfVU5ERUZfRVJSLAotICAgICAgICAiTWFsbGVuICcnezB9JycgaGFyIGludGUgZGVmaW5pZXJhdHMgaSBkZW5uYSBmb3JtYXRtYWxsLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYSB2YXJpYWJsZQotICAgICAgICAgKiB0aGF0IHdhcyBkZWZpbmVkIG1vcmUgdGhhbiBvbmNlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlZBUklBQkxFX1JFREVGX0VSUiwKLSAgICAgICAgIlZhcmlhYmVsbiAnJ3swfScnIGhhciBkZWZpbmllcmF0cyBmbGVyYSBnXHUwMEU1bmdlciBpIHNhbW1hIG9tZmF0dG5pbmcuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBhIHZhcmlhYmxlCi0gICAgICAgICAqIG9yIHBhcmFtZXRlci4gIEEgcmVmZXJlbmNlIHRvIHRoZSB2YXJpYWJsZSBvciBwYXJhbWV0ZXIgd2FzIGZvdW5kLAotICAgICAgICAgKiBidXQgaXQgd2FzIG5ldmVyIGRlZmluZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVkFSSUFCTEVfVU5ERUZfRVJSLAotICAgICAgICAiVmFyaWFiZWxuIGVsbGVyIHBhcmFtZXRlcm4gJyd7MH0nJyBoYXIgaW50ZSBkZWZpbmllcmF0cy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHdvcmQgImNsYXNzIiBoZXJlIHJlZmVycyB0byBhIEphdmEgY2xhc3MuCi0gICAgICAgICAqIFByb2Nlc3NpbmcgdGhlIHN0eWxlc2hlZXQgcmVxdWlyZWQgYSBjbGFzcyB0byBiZSBsb2FkZWQsIGJ1dCBpdCBjb3VsZAotICAgICAgICAgKiBub3QgYmUgZm91bmQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgdGhlIGNsYXNzLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkNMQVNTX05PVF9GT1VORF9FUlIsCi0gICAgICAgICJIaXR0YXIgaW50ZSBrbGFzc2VuICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSB3b3JkICJtZXRob2QiIGhlcmUgcmVmZXJzIHRvIGEgSmF2YSBtZXRob2QuCi0gICAgICAgICAqIFByb2Nlc3NpbmcgdGhlIHN0eWxlc2hlZXQgcmVxdWlyZWQgYSByZWZlcmVuY2UgdG8gdGhlIG1ldGhvZCBuYW1lZCBieQotICAgICAgICAgKiB0aGUgc3Vic3RpdHV0aW9uIHRleHQsIGJ1dCBpdCBjb3VsZCBub3QgYmUgZm91bmQuICAicHVibGljIiBpcyB0aGUKLSAgICAgICAgICogSmF2YSBrZXl3b3JkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk1FVEhPRF9OT1RfRk9VTkRfRVJSLAotICAgICAgICAiSGl0dGFyIGludGUgZGVuIGV4dGVybmEgbWV0b2RlbiAnJ3swfScnIChtXHUwMEU1c3RlIHZhcmEgYWxsbVx1MDBFNG4pLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgd29yZCAibWV0aG9kIiBoZXJlIHJlZmVycyB0byBhIEphdmEgbWV0aG9kLgotICAgICAgICAgKiBQcm9jZXNzaW5nIHRoZSBzdHlsZXNoZWV0IHJlcXVpcmVkIGEgcmVmZXJlbmNlIHRvIHRoZSBtZXRob2QgbmFtZWQgYnkKLSAgICAgICAgICogdGhlIHN1YnN0aXR1dGlvbiB0ZXh0LCBidXQgbm8gbWV0aG9kIHdpdGggdGhlIHJlcXVpcmVkIHR5cGVzIG9mCi0gICAgICAgICAqIGFyZ3VtZW50cyBvciByZXR1cm4gdHlwZSBjb3VsZCBiZSBmb3VuZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5BUkdVTUVOVF9DT05WRVJTSU9OX0VSUiwKLSAgICAgICAgIkthbiBpbnRlIGtvbnZlcnRlcmEgYXJndW1lbnQvcmV0dXJ0eXAgdmlkIGFucm9wIHRpbGwgbWV0b2RlbiAnJ3swfScnIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmaWxlIG9yIFVSSSBuYW1lZCBpbiB0aGUgc3Vic3RpdHV0aW9uIHRleHQKLSAgICAgICAgICogaXMgbWlzc2luZy4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5GSUxFX05PVF9GT1VORF9FUlIsCi0gICAgICAgICJGaWwgZWxsZXIgVVJJICcnezB9JycgaGl0dGFkZXMgaW50ZS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIGRpc3BsYXllZCB3aGVuIHRoZSBVUkkKLSAgICAgICAgICogbWVudGlvbmVkIGluIHRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyBub3Qgd2VsbC1mb3JtZWQgc3ludGFjdGljYWxseS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTlZBTElEX1VSSV9FUlIsCi0gICAgICAgICJPZ2lsdGlnIFVSSSAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZmlsZSBvciBVUkkgbmFtZWQgaW4gdGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgICAqIGV4aXN0cyBidXQgY291bGQgbm90IGJlIG9wZW5lZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5GSUxFX0FDQ0VTU19FUlIsCi0gICAgICAgICJLYW4gaW50ZSBcdTAwRjZwcG5hIGZpbGVuIGVsbGVyIFVSSSAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6IDx4c2w6c3R5bGVzaGVldD4gYW5kIDx4c2w6dHJhbnNmb3JtPiBhcmUKLSAgICAgICAgICoga2V5d29yZHMgdGhhdCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTUlTU0lOR19ST09UX0VSUiwKLSAgICAgICAgIkZcdTAwRjZydlx1MDBFNG50YWRlIDx4c2w6c3R5bGVzaGVldD4tIGVsbGVyIDx4c2w6dHJhbnNmb3JtPi1lbGVtZW50LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3R5bGVzaGVldCBjb250YWluZWQgYSByZWZlcmVuY2UgdG8gYQotICAgICAgICAgKiBuYW1lc3BhY2UgcHJlZml4IHRoYXQgd2FzIHVuZGVmaW5lZC4gIFRoZSB2YWx1ZSBvZiB0aGUgc3Vic3RpdHV0aW9uCi0gICAgICAgICAqIHRleHQgaXMgdGhlIG5hbWUgb2YgdGhlIHByZWZpeC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5OQU1FU1BBQ0VfVU5ERUZfRVJSLAotICAgICAgICAiTmFtbnJ5bWRzcHJlZml4ZXQgJyd7MH0nJyBoYXIgaW50ZSBkZWtsYXJlcmF0cy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIEphdmEgZnVuY3Rpb24gbmFtZWQgaW4gdGhlIHN0eWxlc2hlZXQgY291bGQKLSAgICAgICAgICogbm90IGJlIGZvdW5kLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkZVTkNUSU9OX1JFU09MVkVfRVJSLAotICAgICAgICAiS2FuIGludGUgbWF0Y2hhIGFucm9wIHRpbGwgZnVua3Rpb25lbiAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYQotICAgICAgICAgKiBmdW5jdGlvbi4gIEEgbGl0ZXJhbCBzdHJpbmcgaGVyZSBtZWFucyBhIGNvbnN0YW50IHN0cmluZyB2YWx1ZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5ORUVEX0xJVEVSQUxfRVJSLAotICAgICAgICAiQXJndW1lbnQgdGlsbCAnJ3swfScnIG1cdTAwRTVzdGUgdmFyYSBlbiBsaXR0ZXJhbCBzdHJcdTAwRTRuZy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGluZGljYXRlcyB0aGVyZSB3YXMgYSBzeW50YWN0aWMKLSAgICAgICAgICogZXJyb3IgaW4gdGhlIGZvcm0gb2YgYW4gWFBhdGggZXhwcmVzc2lvbi4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcwotICAgICAgICAgKiB0aGUgZXhwcmVzc2lvbi4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5YUEFUSF9QQVJTRVJfRVJSLAotICAgICAgICAiRmVsIHZpZCB0b2xrbmluZyBhdiBYUGF0aC11dHRyeWNrZXQgJyd7MH0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQW4gZWxlbWVudCBpbiB0aGUgc3R5bGVzaGVldCByZXF1aXJlcyBhCi0gICAgICAgICAqIHBhcnRpY3VsYXIgYXR0cmlidXRlIG5hbWVkIGJ5IHRoZSBzdWJzdGl0dXRpb24gdGV4dCwgYnV0IHRoYXQKLSAgICAgICAgICogYXR0cmlidXRlIHdhcyBub3Qgc3BlY2lmaWVkIGluIHRoZSBzdHlsZXNoZWV0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlJFUVVJUkVEX0FUVFJfRVJSLAotICAgICAgICAiRGV0IG9ibGlnYXRvcmlza2EgYXR0cmlidXRldCAnJ3swfScnIHNha25hcy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IGEgY2hhcmFjdGVyIG5vdAotICAgICAgICAgKiBwZXJtaXR0ZWQgaW4gYW4gWFBhdGggZXhwcmVzc2lvbiB3YXMgZW5jb3VudGVyZWQuICBUaGUgc3Vic3RpdHV0aW9uCi0gICAgICAgICAqIHRleHQgaXMgdGhlIG9mZmVuZGluZyBjaGFyYWN0ZXIuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSUxMRUdBTF9DSEFSX0VSUiwKLSAgICAgICAgIk90aWxsXHUwMEU1dGV0IHRlY2tlbiAnJ3swfScnIGkgWFBhdGgtdXR0cnlja2V0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gaXMgYSBtYXJrLXVwIGl0ZW0gaW4KLSAgICAgICAgICogYW4gWE1MIGRvY3VtZW50IHRoYXQgcmVxdWVzdCBzb21lIGJlaGF2aW91ciBvZiBhbiBYTUwgcHJvY2Vzc29yLiAgVGhlCi0gICAgICAgICAqIGZvcm0gb2YgdGhlIG5hbWUgb2Ygd2FzIGludmFsaWQgaW4gdGhpcyBjYXNlLCBhbmQgdGhlIHN1YnN0aXR1dGlvbgotICAgICAgICAgKiB0ZXh0IGlzIHRoZSBuYW1lLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfUElfRVJSLAotICAgICAgICAiJyd7MH0nJyBcdTAwRTRyIGV0dCBvdGlsbFx1MDBFNXRldCBuYW1uIGkgYmVhcmJldG5pbmdzaW5zdHJ1a3Rpb24uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyByZXBvcnRlZCBpZiB0aGUgc3R5bGVzaGVldAotICAgICAgICAgKiBiZWluZyBwcm9jZXNzZWQgYXR0ZW1wdGVkIHRvIGNvbnN0cnVjdCBhbiBYTUwgZG9jdW1lbnQgd2l0aCBhbgotICAgICAgICAgKiBhdHRyaWJ1dGUgaW4gYSBwbGFjZSBvdGhlciB0aGFuIG9uIGFuIGVsZW1lbnQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQKLSAgICAgICAgICogc3BlY2lmaWVzIHRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuU1RSQVlfQVRUUklCVVRFX0VSUiwKLSAgICAgICAgIkF0dHJpYnV0ZXQgJyd7MH0nJyBmaW5ucyB1dGFuZlx1MDBGNnIgZWxlbWVudGV0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBbiBhdHRyaWJ1dGUgdGhhdCB3YXNuJ3QgcmVjb2duaXplZCB3YXMKLSAgICAgICAgICogc3BlY2lmaWVkIG9uIGFuIGVsZW1lbnQgaW4gdGhlIHN0eWxlc2hlZXQuICBUaGUgYXR0cmlidXRlIGlzIG5hbWVkCi0gICAgICAgICAqIGJ5IHRoZSBzdWJzdGl0dXRpb24KLSAgICAgICAgICogdGV4dC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTExFR0FMX0FUVFJJQlVURV9FUlIsCi0gICAgICAgICInJ3swfScnIFx1MDBFNHIgZXR0IG90aWxsXHUwMEU1dGV0IGF0dHJpYnV0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiaW1wb3J0IiBhbmQgImluY2x1ZGUiIGFyZSBrZXl3b3JkcyB0aGF0IHNob3VsZAotICAgICAgICAgKiBub3QgYmUgdHJhbnNsYXRlZC4gIFRoaXMgbWVzc2FnZXMgaW5kaWNhdGVzIHRoYXQgdGhlIHN0eWxlc2hlZXQKLSAgICAgICAgICogbmFtZWQgaW4gdGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGltcG9ydGVkIG9yIGluY2x1ZGVkIGl0c2VsZiBlaXRoZXIKLSAgICAgICAgICogZGlyZWN0bHkgb3IgaW5kaXJlY3RseS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5DSVJDVUxBUl9JTkNMVURFX0VSUiwKLSAgICAgICAgIkNpcmt1bFx1MDBFNHIgaW1wb3J0L2luY2x1ZGUuIEZvcm1hdG1hbGxlbiAnJ3swfScnIGhhciByZWRhbiBsYWRkYXRzLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBIHJlc3VsdC10cmVlIGZyYWdtZW50IGlzIGEgcG9ydGlvbiBvZiBhCi0gICAgICAgICAqIHJlc3VsdGluZyBYTUwgZG9jdW1lbnQgcmVwcmVzZW50ZWQgYXMgYSB0cmVlLiAgIjx4c2w6c29ydD4iIGlzIGEKLSAgICAgICAgICoga2V5d29yZCBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlJFU1VMVF9UUkVFX1NPUlRfRVJSLAotICAgICAgICAiUmVzdWx0YXR0clx1MDBFNGRmcmFnbWVudCBrYW4gaW50ZSBzb3J0ZXJhcyAoPHhzbDpzb3J0Pi1lbGVtZW50IGlnbm9yZXJhcykuIER1IG1cdTAwRTVzdGUgc29ydGVyYSBub2Rlcm5hIG5cdTAwRTRyIHJlc3VsdGF0dHJcdTAwRTRkZXQgc2thcGFzLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBIG5hbWUgY2FuIGJlIGdpdmVuIHRvIGEgcGFydGljdWxhciBzdHlsZSB0byBiZQotICAgICAgICAgKiB1c2VkIHRvIGZvcm1hdCBkZWNpbWFsIHZhbHVlcy4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBnaXZlcyB0aGUgbmFtZQotICAgICAgICAgKiBvZiBzdWNoIGEgc3R5bGUgZm9yIHdoaWNoIG1vcmUgdGhhbiBvbmUgZGVjbGFyYXRpb24gd2FzIGVuY291bnRlcmVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlNZTUJPTFNfUkVERUZfRVJSLAotICAgICAgICAiRGVjaW1hbGZvcm1hdGVyaW5nZW4gJyd7MH0nJyBoYXIgcmVkYW4gZGVmaW5pZXJhdHMuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IHZlcnNpb24gbmFtZWQgaW4gdGhlCi0gICAgICAgICAqIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIG5vdCBzdXBwb3J0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuWFNMX1ZFUlNJT05fRVJSLAotICAgICAgICAiWFNMLXZlcnNpb25lbiAnJ3swfScnIHVuZGVyc3RcdTAwRjZkcyBpbnRlIGkgWFNMVEMuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBkZWZpbml0aW9ucyBvZiBvbmUgb3IgbW9yZSB2YXJpYWJsZXMgb3IKLSAgICAgICAgICogcGFyYW1ldGVycyBkZXBlbmQgb24gb25lIGFub3RoZXIuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuQ0lSQ1VMQVJfVkFSSUFCTEVfRVJSLAotICAgICAgICAiQ2lya3VsXHUwMEU0ciB2YXJpYWJlbC0vcGFyYW1ldGVycmVmZXJlbnMgaSAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgb3BlcmF0b3IgaW4gYW4gZXhwcmVzaW9uIHdpdGggdHdvIG9wZXJhbmRzIHdhcwotICAgICAgICAgKiBub3QgcmVjb2duaXplZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTExFR0FMX0JJTkFSWV9PUF9FUlIsCi0gICAgICAgICJPa1x1MDBFNG5kIG9wZXJhdG9yIGZcdTAwRjZyIGJpblx1MDBFNHJ0IHV0dHJ5Y2suIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyBwcm9kdWNlZCBpZiBhIHJlZmVyZW5jZSB0byBhCi0gICAgICAgICAqIGZ1bmN0aW9uIGhhcyB0b28gbWFueSBvciB0b28gZmV3IGFyZ3VtZW50cy4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTExFR0FMX0FSR19FUlIsCi0gICAgICAgICJPdGlsbFx1MDBFNXRuYSBhcmd1bWVudCBmXHUwMEY2ciBmdW5rdGlvbnNhbnJvcC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgImRvY3VtZW50KCkiIGlzIHRoZSBuYW1lIG9mIGZ1bmN0aW9uIGFuZCBtdXN0Ci0gICAgICAgICAqIG5vdCBiZSB0cmFuc2xhdGVkLiAgQSBub2RlLXNldCBpcyBhIHNldCBvZiB0aGUgbm9kZXMgaW4gdGhlIHRyZWUKLSAgICAgICAgICogcmVwcmVzZW50YXRpb24gb2YgYW4gWE1MIGRvY3VtZW50LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkRPQ1VNRU5UX0FSR19FUlIsCi0gICAgICAgICJBbmRyYSBhcmd1bWVudGV0IGZcdTAwRjZyIGRvY3VtZW50KCktZnVua3Rpb24gbVx1MDBFNXN0ZSB2YXJhIGVuIG5vZHVwcHNcdTAwRTR0dG5pbmcuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICI8eHNsOndoZW4+IiBhbmQgIjx4c2w6Y2hvb3NlPiIgYXJlIGtleXdvcmRzCi0gICAgICAgICAqIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGlzIG1lc3NhZ2UgZGVzY3JpYmVzIGEgc3ludGF4IGVycm9yCi0gICAgICAgICAqIGluIHRoZSBzdHlsZXNoZWV0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk1JU1NJTkdfV0hFTl9FUlIsCi0gICAgICAgICJNaW5zdCBldHQgPHhzbDp3aGVuPi1lbGVtZW50IGtyXHUwMEU0dnMgaSA8eHNsOmNob29zZT4uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICI8eHNsOm90aGVyd2lzZT4iIGFuZCAiPHhzbDpjaG9vc2U+IiBhcmUKLSAgICAgICAgICoga2V5d29yZHMgYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoaXMgbWVzc2FnZSBkZXNjcmliZXMgYQotICAgICAgICAgKiBzeW50YXggZXJyb3IgaW4gdGhlIHN0eWxlc2hlZXQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTVVMVElQTEVfT1RIRVJXSVNFX0VSUiwKLSAgICAgICAgIkVuZGFzdCBldHQgPHhzbDpvdGhlcndpc2U+LWVsZW1lbnQgXHUwMEU0ciB0aWxsXHUwMEU1dGV0IGkgPHhzbDpjaG9vc2U+LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiPHhzbDpvdGhlcndpc2U+IiBhbmQgIjx4c2w6Y2hvb3NlPiIgYXJlCi0gICAgICAgICAqIGtleXdvcmRzIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGlzIG1lc3NhZ2UgZGVzY3JpYmVzIGEKLSAgICAgICAgICogc3ludGF4IGVycm9yIGluIHRoZSBzdHlsZXNoZWV0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlNUUkFZX09USEVSV0lTRV9FUlIsCi0gICAgICAgICI8eHNsOm90aGVyd2lzZT4gYW52XHUwMEU0bmRzIGVuZGFzdCBpbm9tIDx4c2w6Y2hvb3NlPi4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIjx4c2w6d2hlbj4iIGFuZCAiPHhzbDpjaG9vc2U+IiBhcmUga2V5d29yZHMKLSAgICAgICAgICogYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoaXMgbWVzc2FnZSBkZXNjcmliZXMgYSBzeW50YXggZXJyb3IKLSAgICAgICAgICogaW4gdGhlIHN0eWxlc2hlZXQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuU1RSQVlfV0hFTl9FUlIsCi0gICAgICAgICI8eHNsOndoZW4+IGFudlx1MDBFNG5kcyBlbmRhc3QgaW5vbSA8eHNsOmNob29zZT4uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICI8eHNsOndoZW4+IiwgIjx4c2w6b3RoZXJ3aXNlPiIgYW5kCi0gICAgICAgICAqICI8eHNsOmNob29zZT4iIGFyZSBrZXl3b3JkcyBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhpcwotICAgICAgICAgKiBtZXNzYWdlIGRlc2NyaWJlcyBhIHN5bnRheCBlcnJvciBpbiB0aGUgc3R5bGVzaGVldC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5XSEVOX0VMRU1FTlRfRVJSLAotICAgICAgICAiRW5kYXN0IDx4c2w6d2hlbj4tIG9jaCA8eHNsOm90aGVyd2lzZT4tZWxlbWVudCBcdTAwRTRyIHRpbGxcdTAwRTV0bmEgaSA8eHNsOmNob29zZT4uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICI8eHNsOmF0dHJpYnV0ZS1zZXQ+IiBhbmQgIm5hbWUiIGFyZSBrZXl3b3JkcwotICAgICAgICAgKiB0aGF0IHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5VTk5BTUVEX0FUVFJJQlNFVF9FUlIsCi0gICAgICAgICI8eHNsOmF0dHJpYnV0ZS1zZXQ+IHNha25hciAnbmFtZSctYXR0cmlidXQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIGVsZW1lbnQgaW4gdGhlIHN0eWxlc2hlZXQgY29udGFpbmVkIGFuCi0gICAgICAgICAqIGVsZW1lbnQgb2YgYSB0eXBlIHRoYXQgaXQgd2FzIG5vdCBwZXJtaXR0ZWQgdG8gY29udGFpbi4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTExFR0FMX0NISUxEX0VSUiwKLSAgICAgICAgIk90aWxsXHUwMEU1dGV0IHVuZGVyb3JkbmF0IGVsZW1lbnQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IHRyaWVkIHRvIGNyZWF0ZSBhbiBlbGVtZW50IHdpdGgKLSAgICAgICAgICogYSBuYW1lIHRoYXQgd2FzIG5vdCBhIHZhbGlkIFhNTCBuYW1lLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGNvbnRhaW5zCi0gICAgICAgICAqIHRoZSBuYW1lLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfRUxFTV9OQU1FX0VSUiwKLSAgICAgICAgIkR1IGthbiBpbnRlIGFucm9wYSBlbGVtZW50ZXQgJyd7MH0nJyJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3R5bGVzaGVldCB0cmllZCB0byBjcmVhdGUgYW4gYXR0cmlidXRlCi0gICAgICAgICAqIHdpdGggYSBuYW1lIHRoYXQgd2FzIG5vdCBhIHZhbGlkIFhNTCBuYW1lLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgICAqIGNvbnRhaW5zIHRoZSBuYW1lLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfQVRUUl9OQU1FX0VSUiwKLSAgICAgICAgIkR1IGthbiBpbnRlIGFucm9wYSBhdHRyaWJ1dGV0ICcnezB9JycifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGNoaWxkcmVuIG9mIHRoZSBvdXRlcm1vc3QgZWxlbWVudCBvZiBhCi0gICAgICAgICAqIHN0eWxlc2hlZXQgYXJlIHJlZmVycmVkIHRvIGFzIHRvcC1sZXZlbCBlbGVtZW50cy4gIE5vIHRleHQgc2hvdWxkCi0gICAgICAgICAqIG9jY3VyIHdpdGhpbiB0aGF0IG91dGVybW9zdCBlbGVtZW50IHVubGVzcyBpdCBpcyB3aXRoaW4gYSB0b3AtbGV2ZWwKLSAgICAgICAgICogZWxlbWVudC4gIFRoaXMgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGF0IGNvbnN0cmFpbnQgd2FzIHZpb2xhdGVkLgotICAgICAgICAgKiAiPHhzbDpzdHlsZXNoZWV0PiIgaXMgYSBrZXl3b3JkIHRoYXQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfVEVYVF9OT0RFX0VSUiwKLSAgICAgICAgIlRleHRkYXRhIHV0YW5mXHUwMEY2ciBkZXQgXHUwMEY2dmVyc3RhIGVsZW1lbnRldCA8eHNsOnN0eWxlc2hlZXQ+LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBKQVhQIGlzIGFuIGFjcm9ueW0gZm9yIHRoZSBKYXZhIEFQSSBmb3IgWE1MCi0gICAgICAgICAqIFByb2Nlc3NpbmcuICBUaGlzIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhlIFhNTCBwYXJzZXIgcHJvdmlkZWQgdG8KLSAgICAgICAgICogWFNMVEMgdG8gcHJvY2VzcyB0aGUgWE1MIGlucHV0IGRvY3VtZW50IGhhZCBhIGNvbmZpZ3VyYXRpb24gcHJvYmxlbS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5TQVhfUEFSU0VSX0NPTkZJR19FUlIsCi0gICAgICAgICJKQVhQLXBhcnNlciBoYXIgaW50ZSBrb25maWd1cmVyYXRzIGtvcnJla3QifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IG5hbWVzIHRoZSBpbnRlcm5hbCBlcnJvcgotICAgICAgICAgKiBlbmNvdW50ZXJlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTlRFUk5BTF9FUlIsCi0gICAgICAgICJPXHUwMEU1dGVya2FsbGVsaWd0IGludGVybnQgWFNMVEMtZmVsOiAnJ3swfScnIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IGNvbnRhaW5lZCBhbiBlbGVtZW50IHRoYXQgd2FzCi0gICAgICAgICAqIG5vdCByZWNvZ25pemVkIGFzIHBhcnQgb2YgdGhlIFhTTCBzeW50YXguICBUaGUgc3Vic3RpdHV0aW9uIHRleHQKLSAgICAgICAgICogZ2l2ZXMgdGhlIGVsZW1lbnQgbmFtZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5VTlNVUFBPUlRFRF9YU0xfRVJSLAotICAgICAgICAiWFNMLWVsZW1lbnRldCAnJ3swfScnIHN0XHUwMEY2ZHMgaW50ZS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN0eWxlc2hlZXQgcmVmZXJyZWQgdG8gYW4gZXh0ZW5zaW9uIHRvIHRoZQotICAgICAgICAgKiBYU0wgc3ludGF4IGFuZCBpbmRpY2F0ZWQgdGhhdCBpdCB3YXMgZGVmaW5lZCBieSBYU0xUQywgYnV0IFhTVExDIGRvZXMKLSAgICAgICAgICogbm90IHJlY29nbml6ZWQgdGhlIHBhcnRpY3VsYXIgZXh0ZW5zaW9uIG5hbWVkLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgICAqIGdpdmVzIHRoZSBleHRlbnNpb24gbmFtZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5VTlNVUFBPUlRFRF9FWFRfRVJSLAotICAgICAgICAiWFNMVEMtdGlsbFx1MDBFNGdnZXQgJyd7MH0nJyBcdTAwRTRyIG9rXHUwMEU0bnQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBYTUwgZG9jdW1lbnQgZ2l2ZW4gdG8gWFNMVEMgYXMgYSBzdHlsZXNoZWV0Ci0gICAgICAgICAqIHdhcyBub3QsIGluIGZhY3QsIGEgc3R5bGVzaGVldC4gIFhTTFRDIGlzIGFibGUgdG8gZGV0ZWN0IHRoYXQgaW4gdGhpcwotICAgICAgICAgKiBjYXNlIGJlY2F1c2UgdGhlIG91dGVybW9zdCBlbGVtZW50IGluIHRoZSBzdHlsZXNoZWV0IGhhcyB0byBiZQotICAgICAgICAgKiBkZWNsYXJlZCB3aXRoIHJlc3BlY3QgdG8gdGhlIFhTTCBuYW1lc3BhY2UgVVJJLCBidXQgbm8gZGVjbGFyYXRpb24KLSAgICAgICAgICogZm9yIHRoYXQgbmFtZXNwYWNlIHdhcyBzZWVuLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk1JU1NJTkdfWFNMVF9VUklfRVJSLAotICAgICAgICAiSW5kYXRhZG9rdW1lbnRldCBcdTAwRTRyIGluZ2VuIGZvcm1hdG1hbGwgKFhTTC1uYW1ucnltZGVuIGhhciBpbnRlIGRla2xhcmVyYXRzIGkgcm90ZWxlbWVudGV0KS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgWFNMVEMgY291bGQgbm90IGZpbmQgdGhlIHN0eWxlc2hlZXQgZG9jdW1lbnQKLSAgICAgICAgICogd2l0aCB0aGUgbmFtZSBzcGVjaWZpZWQgYnkgdGhlIHN1YnN0aXR1dGlvbiB0ZXh0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk1JU1NJTkdfWFNMVF9UQVJHRVRfRVJSLAotICAgICAgICAiSGl0dGFkZSBpbnRlIGZvcm1hdG1hbGxlbiAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBhY2Nlc3MgdG8gdGhlIHN0eWxlc2hlZXQgdGFyZ2V0IGlzIGRlbmllZAotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkFDQ0VTU0lOR19YU0xUX1RBUkdFVF9FUlIsCi0gICAgICAgICJLdW5kZSBpbnRlIGxcdTAwRTRzYSBmb3JtYXRtYWxsZW4gJyd7MH0nJywgZWZ0ZXJzb20gJyd7MX0nJy1cdTAwRTV0a29tc3QgaW50ZSB0aWxsXHUwMEU1dHMgcFx1MDBFNSBncnVuZCBhdiBiZWdyXHUwMEU0bnNuaW5nIHNvbSBhbmdlcyBhdiBlZ2Vuc2thcGVuIGFjY2Vzc0V4dGVybmFsU3R5bGVzaGVldC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIHJlcHJlc2VudHMgYW4gaW50ZXJuYWwgZXJyb3IgaW4KLSAgICAgICAgICogY29uZGl0aW9uIGluIFhTTFRDLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBjbGFzcyBuYW1lIGluIFhTTFRDCi0gICAgICAgICAqIHRoYXQgaXMgbWlzc2luZyBzb21lIGZ1bmN0aW9uYWxpdHkuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTk9UX0lNUExFTUVOVEVEX0VSUiwKLSAgICAgICAgIkludGUgaW1wbGVtZW50ZXJhZDogJyd7MH0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIFhNTCBkb2N1bWVudCBnaXZlbiB0byBYU0xUQyBhcyBhIHN0eWxlc2hlZXQKLSAgICAgICAgICogd2FzIG5vdCwgaW4gZmFjdCwgYSBzdHlsZXNoZWV0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk5PVF9TVFlMRVNIRUVUX0VSUiwKLSAgICAgICAgIkluZGF0YWRva3VtZW50ZXQgaW5uZWhcdTAwRTVsbGVyIGluZ2VuIFhTTC1mb3JtYXRtYWxsLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZWxlbWVudCBuYW1lZCBpbiB0aGUgc3Vic3RpdHV0aW9uIHRleHQgd2FzCi0gICAgICAgICAqIGVuY291bnRlcmVkIGluIHRoZSBzdHlsZXNoZWV0IGJ1dCBpcyBub3QgcmVjb2duaXplZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5FTEVNRU5UX1BBUlNFX0VSUiwKLSAgICAgICAgIkt1bmRlIGludGUgdG9sa2EgZWxlbWVudGV0ICcnezB9JycifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgInVzZSIsICI8a2V5PiIsICJub2RlIiwgIm5vZGUtc2V0IiwgInN0cmluZyIKLSAgICAgICAgICogYW5kICJudW1iZXIiIGFyZSBrZXl3b3JkcyBpbiB0aGlzIGNvbnRleHQgYW5kIHNob3VsZCBub3QgYmUKLSAgICAgICAgICogdHJhbnNsYXRlZC4gIFRoaXMgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUgdmFsdWUgb2YgdGhlICJ1c2UiCi0gICAgICAgICAqIGF0dHJpYnV0ZSB3YXMgbm90IG9uZSBvZiB0aGUgcGVybWl0dGVkIHZhbHVlcy4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5LRVlfVVNFX0FUVFJfRVJSLAotICAgICAgICAidXNlLWF0dHJpYnV0IGZcdTAwRjZyIDxrZXk+IG1cdTAwRTVzdGUgdmFyYSBub2RlLCBub2RlLXNldCwgc3RyaW5nIGVsbGVyIG51bWJlci4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQW4gWE1MIGRvY3VtZW50IGNhbiBzcGVjaWZ5IHRoZSB2ZXJzaW9uIG9mIHRoZQotICAgICAgICAgKiBYTUwgc3BlY2lmaWNhdGlvbiB0byB3aGljaCBpdCBhZGhlcmVzLiAgVGhpcyBtZXNzYWdlIGluZGljYXRlcyB0aGF0Ci0gICAgICAgICAqIHRoZSB2ZXJzaW9uIHNwZWNpZmllZCBmb3IgdGhlIG91dHB1dCBkb2N1bWVudCB3YXMgbm90IHZhbGlkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk9VVFBVVF9WRVJTSU9OX0VSUiwKLSAgICAgICAgIlhNTC1kb2t1bWVudGV0cyB1dGRhdGF2ZXJzaW9uIG1cdTAwRTVzdGUgdmFyYSAxLjAifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIG9wZXJhdG9yIGluIGEgY29tcGFyaXNvbiBvcGVyYXRpb24gd2FzCi0gICAgICAgICAqIG5vdCByZWNvZ25pemVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfUkVMQVRfT1BfRVJSLAotICAgICAgICAiT2tcdTAwRTRuZCBvcGVyYXRvciBmXHUwMEY2ciByZWxhdGlvbnN1dHRyeWNrIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIGF0dHJpYnV0ZSBzZXQgZGVmaW5lcyBhcyBhIHNldCBvZiBYTUwKLSAgICAgICAgICogYXR0cmlidXRlcyB0aGF0IGNhbiBiZSBhZGRlZCB0byBhbiBlbGVtZW50IGluIHRoZSBvdXRwdXQgWE1MIGRvY3VtZW50Ci0gICAgICAgICAqIGFzIGEgZ3JvdXAuICBUaGlzIG1lc3NhZ2UgaXMgcmVwb3J0ZWQgaWYgdGhlIG5hbWUgc3BlY2lmaWVkIHdhcyBub3QKLSAgICAgICAgICogdXNlZCB0byBkZWNsYXJlIGFuIGF0dHJpYnV0ZSBzZXQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUKLSAgICAgICAgICogdGhhdCBpcyBpbiBlcnJvci4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5BVFRSSUJTRVRfVU5ERUZfRVJSLAotICAgICAgICAiRlx1MDBGNnJzXHUwMEY2a2VyIGFudlx1MDBFNG5kYSBlbiBpY2tlLWJlZmludGxpZyBhdHRyaWJ1dHVwcHNcdTAwRTR0dG5pbmcgJyd7MH0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHRlcm0gImF0dHJpYnV0ZSB2YWx1ZSB0ZW1wbGF0ZSIgaXMgYSB0ZXJtCi0gICAgICAgICAqIGRlZmluZWQgYnkgWFNMVCB3aGljaCBkZXNjcmliZXMgdGhlIHZhbHVlIG9mIGFuIGF0dHJpYnV0ZSB0aGF0IGlzCi0gICAgICAgICAqIGRldGVybWluZWQgYnkgYW4gWFBhdGggZXhwcmVzc2lvbi4gIFRoZSBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoZQotICAgICAgICAgKiBleHByZXNzaW9uIHdhcyBzeW50YWN0aWNhbGx5IGluY29ycmVjdDsgdGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgICAqIGNvbnRhaW5zIHRoZSBleHByZXNzaW9uIHRoYXQgd2FzIGluIGVycm9yLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkFUVFJfVkFMX1RFTVBMQVRFX0VSUiwKLSAgICAgICAgIkthbiBpbnRlIHRvbGthIGF0dHJpYnV0dlx1MDBFNHJkZW1hbGxlbiAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICA/Pz8KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5VTktOT1dOX1NJR19UWVBFX0VSUiwKLSAgICAgICAgIk9rXHUwMEU0bmQgZGF0YXR5cCBpIHNpZ25hdHVyZW4gZlx1MDBGNnIga2xhc3NlbiAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgcmVmZXJzIHRvIGRhdGEgdHlwZXMuCi0gICAgICAgICAqIFRoZSBtZXNzYWdlIGlzIGRpc3BsYXllZCBpZiBhIHZhbHVlIGluIGEgcGFydGljdWxhciBjb250ZXh0IG5lZWRzIHRvCi0gICAgICAgICAqIGJlIGNvbnZlcnRlZCB0byB0eXBlIHsxfSwgYnV0IHRoYXQncyBub3QgcG9zc2libGUgZm9yIGEgdmFsdWUgb2YKLSAgICAgICAgICogdHlwZSB7MH0uCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuREFUQV9DT05WRVJTSU9OX0VSUiwKLSAgICAgICAgIkthbiBpbnRlIGtvbnZlcnRlcmEgZGF0YXR5cCAnJ3swfScnIHRpbGwgJyd7MX0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIlRlbXBsYXRlcyIgaXMgYSBKYXZhIGNsYXNzIG5hbWUgdGhhdCBzaG91bGQKLSAgICAgICAgICogbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTk9fVFJBTlNMRVRfQ0xBU1NfRVJSLAotICAgICAgICAiVGVtcGxhdGVzIGlubmVoXHUwMEU1bGxlciBpbnRlIG5cdTAwRTVnb24gZ2lsdGlnIGtsYXNzZGVmaW5pdGlvbiBmXHUwMEY2ciB0cmFuc2xldC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIlRlbXBsYXRlcyIgaXMgYSBKYXZhIGNsYXNzIG5hbWUgdGhhdCBzaG91bGQKLSAgICAgICAgICogbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTk9fTUFJTl9UUkFOU0xFVF9FUlIsCi0gICAgICAgICJUZW1wbGF0ZXMgaW5uZWhcdTAwRTVsbGVyIGludGUgblx1MDBFNWdvbiBrbGFzcyBtZWQgbmFtbmV0ICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBhIGNsYXNzLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlRSQU5TTEVUX0NMQVNTX0VSUiwKLSAgICAgICAgIkt1bmRlIGludGUgbGFkZGEgdHJhbnNsZXQta2xhc3NlbiAnJ3swfScnLiJ9LAotCi0gICAgICAgIHtFcnJvck1zZy5UUkFOU0xFVF9PQkpFQ1RfRVJSLAotICAgICAgICAiVHJhbnNsZXQta2xhc3NlbiBoYXIgbGFkZGF0cywgbWVuIGthbiBpbnRlIHNrYXBhIGluc3RhbnMgYXYgdHJhbnNsZXQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJFcnJvckxpc3RlbmVyIiBpcyBhIEphdmEgaW50ZXJmYWNlIG5hbWUgdGhhdAotICAgICAgICAgKiBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUgdXNlciB0cmllZAotICAgICAgICAgKiB0byBzZXQgYW4gRXJyb3JMaXN0ZW5lciBvYmplY3Qgb24gb2JqZWN0IG9mIHRoZSBjbGFzcyBuYW1lZCBpbiB0aGUKLSAgICAgICAgICogc3Vic3RpdHV0aW9uIHRleHQgd2l0aCAibnVsbCIgSmF2YSB2YWx1ZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5FUlJPUl9MSVNURU5FUl9OVUxMX0VSUiwKLSAgICAgICAgIkZcdTAwRjZyc1x1MDBGNmtlciBzdFx1MDBFNGxsYSBpbiBFcnJvckxpc3RlbmVyIGZcdTAwRjZyICcnezB9JycgcFx1MDBFNSBudWxsIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFN0cmVhbVNvdXJjZSwgU0FYU291cmNlIGFuZCBET01Tb3VyY2UgYXJlIEphdmEKLSAgICAgICAgICogaW50ZXJmYWNlIG5hbWVzIHRoYXQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfVU5LTk9XTl9TT1VSQ0VfRVJSLAotICAgICAgICAiRW5kYXN0IFN0cmVhbVNvdXJjZSwgU0FYU291cmNlIG9jaCBET01Tb3VyY2Ugc3RcdTAwRjZkcyBhdiBYU0xUQyJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiU291cmNlIiBpcyBhIEphdmEgY2xhc3MgbmFtZSB0aGF0IHNob3VsZCBub3QKLSAgICAgICAgICogYmUgdHJhbnNsYXRlZC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBKYXZhIG1ldGhvZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX05PX1NPVVJDRV9FUlIsCi0gICAgICAgICJTb3VyY2Utb2JqZWt0ZXQgc29tIFx1MDBGNnZlcmZcdTAwRjZyZGVzIHRpbGwgJyd7MH0nJyBzYWtuYXIgaW5uZWhcdTAwRTVsbC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgWFNMVEMgZmFpbGVkIHRvCi0gICAgICAgICAqIGNvbXBpbGUgdGhlIHN0eWxlc2hlZXQgaW50byBhIHRyYW5zbGV0IChjbGFzcyBmaWxlKS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX0NPTVBJTEVfRVJSLAotICAgICAgICAiS3VuZGUgaW50ZSBrb21waWxlcmEgZm9ybWF0bWFsbCJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiVHJhbnNmb3JtZXJGYWN0b3J5IiBpcyBhIGNsYXNzIG5hbWUuICBJbiB0aGlzCi0gICAgICAgICAqIGNvbnRleHQsIGFuIGF0dHJpYnV0ZSBpcyBhIHByb3BlcnR5IG9yIHNldHRpbmcgb2YgdGhlCi0gICAgICAgICAqIFRyYW5zZm9ybWVyRmFjdG9yeSBvYmplY3QuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgdGhlCi0gICAgICAgICAqIHVucmVjb2duaXNlZCBhdHRyaWJ1dGUuICBUaGUgbWV0aG9kIHVzZWQgdG8gcmV0cmlldmUgdGhlIGF0dHJpYnV0ZSBpcwotICAgICAgICAgKiAiZ2V0QXR0cmlidXRlIiwgc28gaXQncyBub3QgY2xlYXIgd2hldGhlciBpdCB3b3VsZCBiZSBiZXN0IHRvCi0gICAgICAgICAqIHRyYW5zbGF0ZSB0aGUgdGVybSAiYXR0cmlidXRlIi4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX0lOVkFMSURfQVRUUl9FUlIsCi0gICAgICAgICJUcmFuc2Zvcm1lckZhY3Rvcnkga1x1MDBFNG5uZXIgaW50ZSBpZ2VuIGF0dHJpYnV0ZXQgJyd7MH0nJy4ifSwKLQotICAgICAgICB7RXJyb3JNc2cuSkFYUF9JTlZBTElEX0FUVFJfVkFMVUVfRVJSLAotICAgICAgICAiRmVsIHZcdTAwRTRyZGUgaGFyIGFuZ2V0dHMgZlx1MDBGNnIgYXR0cmlidXRldCAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAic2V0UmVzdWx0KCkiIGFuZCAic3RhcnREb2N1bWVudCgpIiBhcmUgSmF2YQotICAgICAgICAgKiBtZXRob2QgbmFtZXMgdGhhdCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSkFYUF9TRVRfUkVTVUxUX0VSUiwKLSAgICAgICAgInNldFJlc3VsdCgpIG1cdTAwRTVzdGUgYW5yb3BhcyBmXHUwMEY2cmUgc3RhcnREb2N1bWVudCgpLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiVHJhbnNmb3JtZXIiIGlzIGEgSmF2YSBpbnRlcmZhY2UgbmFtZSB0aGF0Ci0gICAgICAgICAqIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIEEgVHJhbnNmb3JtZXIgb2JqZWN0IHNob3VsZCBjb250YWluZWQgYQotICAgICAgICAgKiByZWZlcmVuY2UgdG8gYSB0cmFuc2xldCBvYmplY3QgaW4gb3JkZXIgdG8gYmUgdXNlZCBmb3IKLSAgICAgICAgICogdHJhbnNmb3JtYXRpb25zOyB0aGlzIG1lc3NhZ2UgaXMgcHJvZHVjZWQgaWYgdGhhdCByZXF1aXJlbWVudCBpcyBub3QKLSAgICAgICAgICogbWV0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfTk9fVFJBTlNMRVRfRVJSLAotICAgICAgICAiVHJhbnNmb3JtZXIgc2FrbmFyIGlua2Fwc2xhdCBvYmpla3QgZlx1MDBGNnIgdHJhbnNsZXQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBYTUwgZG9jdW1lbnQgdGhhdCByZXN1bHRzIGZyb20gYQotICAgICAgICAgKiB0cmFuc2Zvcm1hdGlvbiBuZWVkcyB0byBiZSBzZW50IHRvIGFuIG91dHB1dCBoYW5kbGVyIG9iamVjdDsgdGhpcwotICAgICAgICAgKiBtZXNzYWdlIGlzIHByb2R1Y2VkIGlmIHRoYXQgcmVxdWlyZW1lbnQgaXMgbm90IG1ldC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX05PX0hBTkRMRVJfRVJSLAotICAgICAgICAiRGV0IGZpbm5zIGluZ2VuIGRlZmluaWVyYWQgdXRkYXRhaGFudGVyYXJlIGZcdTAwRjZyIHRyYW5zZm9ybWVyaW5nc3Jlc3VsdGF0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiUmVzdWx0IiBpcyBhIEphdmEgaW50ZXJmYWNlIG5hbWUgaW4gdGhpcwotICAgICAgICAgKiBjb250ZXh0LiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIGEgbWV0aG9kIG5hbWUuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSkFYUF9OT19SRVNVTFRfRVJSLAotICAgICAgICAiUmVzdWx0LW9iamVrdCBzb20gXHUwMEY2dmVyZlx1MDBGNnJkZXMgdGlsbCAnJ3swfScnIFx1MDBFNHIgb2dpbHRpZ3QuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJUcmFuc2Zvcm1lciIgaXMgYSBKYXZhIGludGVyZmFjZSBuYW1lLiAgVGhlCi0gICAgICAgICAqIHVzZXIncyBwcm9ncmFtIGF0dGVtcHRlZCB0byBhY2Nlc3MgYW4gdW5yZWNvZ25pemVkIHByb3BlcnR5IHdpdGggdGhlCi0gICAgICAgICAqIG5hbWUgc3BlY2lmaWVkIGluIHRoZSBzdWJzdGl0dXRpb24gdGV4dC4gIFRoZSBtZXRob2QgdXNlZCB0byByZXRyaWV2ZQotICAgICAgICAgKiB0aGUgcHJvcGVydHkgaXMgImdldE91dHB1dFByb3BlcnR5Iiwgc28gaXQncyBub3QgY2xlYXIgd2hldGhlciBpdAotICAgICAgICAgKiB3b3VsZCBiZSBiZXN0IHRvIHRyYW5zbGF0ZSB0aGUgdGVybSAicHJvcGVydHkiLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfVU5LTk9XTl9QUk9QX0VSUiwKLSAgICAgICAgIkZcdTAwRjZyc1x1MDBGNmtlciBmXHUwMEU1IFx1MDBFNXRrb21zdCB0aWxsIG9naWx0aWcgVHJhbnNmb3JtZXItZWdlbnNrYXAsICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFNBWDJET00gaXMgdGhlIG5hbWUgb2YgYSBKYXZhIGNsYXNzIHRoYXQgc2hvdWxkCi0gICAgICAgICAqIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhpcyBpcyBhbiBhZGFwdGVyIGluIHRoZSBzZW5zZSB0aGF0IGl0IHRha2VzIGEKLSAgICAgICAgICogRE9NIG9iamVjdCBhbmQgY29udmVydHMgaXQgdG8gc29tZXRoaW5nIHRoYXQgdXNlcyB0aGUgU0FYIEFQSS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5TQVgyRE9NX0FEQVBURVJfRVJSLAotICAgICAgICAiS3VuZGUgaW50ZSBza2FwYSBTQVgyRE9NLWFkYXB0ZXI6ICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJYU0xUQ1NvdXJjZS5idWlsZCgpIiBpcyBhIEphdmEgbWV0aG9kIG5hbWUuCi0gICAgICAgICAqICJzeXN0ZW1JZCIgaXMgYW4gWE1MIHRlcm0gdGhhdCBpcyBzaG9ydCBmb3IgInN5c3RlbSBpZGVudGlmaWNhdGlvbiIuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuWFNMVENfU09VUkNFX0VSUiwKLSAgICAgICAgIlhTTFRDU291cmNlLmJ1aWxkKCkgYW5yb3BhZGVzIHV0YW4gYW5naXZldCBzeXN0ZW1JZC4ifSwKLQotICAgICAgICB7IEVycm9yTXNnLkVSX1JFU1VMVF9OVUxMLAotICAgICAgICAgICAgIlJlc3VsdCBib3JkZSBpbnRlIHZhcmEgbnVsbCJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhlIHZhbHVlIGFyZ3VtZW50Ci0gICAgICAgICAqIG9mIHNldFBhcmFtZXRlciBtdXN0IGJlIGEgdmFsaWQgSmF2YSBPYmplY3QuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSkFYUF9JTlZBTElEX1NFVF9QQVJBTV9WQUxVRSwKLSAgICAgICAgIlBhcmFtZXRlcnZcdTAwRTRyZGV0IGZcdTAwRjZyIHswfSBtXHUwMEU1c3RlIHZhcmEgZ2lsdGlndCBKYXZhLW9iamVrdCJ9LAotCi0KLSAgICAgICAge0Vycm9yTXNnLkNPTVBJTEVfU1RESU5fRVJSLAotICAgICAgICAiQWx0ZXJuYXRpdmV0IC1pIG1cdTAwRTVzdGUgYW52XHUwMEU0bmRhcyBtZWQgYWx0ZXJuYXRpdmV0IC1vLiJ9LAotCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBjb250YWlucyB1c2FnZSBpbmZvcm1hdGlvbiBmb3IgYQotICAgICAgICAgKiBtZWFucyBvZiBpbnZva2luZyBYU0xUQyBmcm9tIHRoZSBjb21tYW5kLWxpbmUuICBUaGUgbWVzc2FnZSBpcwotICAgICAgICAgKiBmb3JtYXR0ZWQgZm9yIHByZXNlbnRhdGlvbiBpbiBFbmdsaXNoLiAgVGhlIHN0cmluZ3MgPG91dHB1dD4sCi0gICAgICAgICAqIDxkaXJlY3Rvcnk+LCBldGMuIGluZGljYXRlIHVzZXItc3BlY2lmaWVkIGFyZ3VtZW50IHZhbHVlcywgYW5kIGNhbgotICAgICAgICAgKiBiZSB0cmFuc2xhdGVkIC0gdGhlIGFyZ3VtZW50IDxwYWNrYWdlPiByZWZlcnMgdG8gYSBKYXZhIHBhY2thZ2UsIHNvCi0gICAgICAgICAqIGl0IHNob3VsZCBiZSBoYW5kbGVkIGluIHRoZSBzYW1lIHdheSB0aGUgdGVybSBpcyBoYW5kbGVkIGZvciBKREsKLSAgICAgICAgICogZG9jdW1lbnRhdGlvbi4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5DT01QSUxFX1VTQUdFX1NUUiwKLSAgICAgICAgIlNZTk9QU0lTXG4gICBqYXZhIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jbWRsaW5lLkNvbXBpbGUgWy1vIDx1dGRhdGE+XVxuICAgICAgWy1kIDxrYXRhbG9nPl0gWy1qIDxqYXJmaWxlPl0gWy1wIDxwYWtldD5dXG4gICAgICBbLW5dIFsteF0gWy11XSBbLXZdIFstaF0geyA8Zm9ybWF0bWFsbD4gfCAtaSB9XG5cbkFMVEVSTkFUSVZcbiAgIC1vIDx1dGRhdGE+ICAgIHRpbGxkZWxhciBuYW1uZXQgPHV0ZGF0YT4gdGlsbCBnZW5lcmVyYWRcbiAgICAgICAgICAgICAgICAgIHRyYW5zbGV0LiBTb20gc3RhbmRhcmQgdGFzIG5hbW5ldCBwXHUwMEU1IHRyYW5zbGV0XG4gICAgICAgICAgICAgICAgICBmclx1MDBFNW4gbmFtbmV0IHBcdTAwRTUgPGZvcm1hdG1hbGxlbj4uIEFsdGVybmF0aXZldFxuICAgICAgICAgICAgICAgICAgaWdub3JlcmFzIHZpZCBrb21waWxlcmluZyBhdiBmbGVyYSBmb3JtYXRtYWxsYXIuXG4gICAtZCA8a2F0YWxvZz4gYW5nZXIgZW4gZGVzdGluYXRpb25za2F0YWxvZyBmXHUwMEY2ciB0cmFuc2xldFxuICAgLWogPGphcmZpbGU+ICAgcGFrZXRlcmFyIHRyYW5zbGV0a2xhc3Nlcm5hIGkgZW4gamFyLWZpbCBtZWRcbiAgICAgICAgICAgICAgICAgIG5hbW5ldCA8amFyZmlsZT5cbiAgIC1wIDxwYWtldD4gICBhbmdlciBldHQgcGFrZXRuYW1ucHJlZml4IGZcdTAwRjZyIGFsbGEgZ2VuZXJlcmFkZVxuICAgICAgICAgICAgICAgICAgdHJhbnNsZXRrbGFzc2VyLlxuICAgLW4gICAgICAgICAgICAgYWt0aXZlcmFyIG1hbGxpbmZvZ25pbmcgKGdlciBldHQgYlx1MDBFNHR0cmUgZ2Vub21zbml0dGxpZ3RcbiAgICAgICAgICAgICAgICAgIHN0YW5kYXJkYmV0ZWVuZGUpLlxuICAgLXggICAgICAgICAgICAgZ2VyIHl0dGVybGlnYXJlIGZlbHNcdTAwRjZrbmluZ3NtZWRkZWxhbmRlblxuICAgLXUgICAgICAgICAgICAgdG9sa2FyIGFyZ3VtZW50IGkgPGZvcm1hdG1hbGw+IHNvbSBVUkw6ZXJcbiAgIC1pICAgICAgICAgICAgIHR2aW5nYXIga29tcGlsYXRvcm4gYXR0IGxcdTAwRTRzYSBmb3JtYXRtYWxsZW4gZnJcdTAwRTVuIHN0ZGluXG4gICAtdiAgICAgICAgICAgICBza3JpdmVyIHV0IGtvbXBpbGF0b3JucyB2ZXJzaW9uc251bW1lclxuICAgLWggICAgICAgICAgICAgc2tyaXZlciB1dCBkZW5uYSBzeW50YXhzYXRzXG4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGNvbnRhaW5zIHVzYWdlIGluZm9ybWF0aW9uIGZvciBhCi0gICAgICAgICAqIG1lYW5zIG9mIGludm9raW5nIFhTTFRDIGZyb20gdGhlIGNvbW1hbmQtbGluZS4gIFRoZSBtZXNzYWdlIGlzCi0gICAgICAgICAqIGZvcm1hdHRlZCBmb3IgcHJlc2VudGF0aW9uIGluIEVuZ2xpc2guICBUaGUgc3RyaW5ncyA8amFyZmlsZT4sCi0gICAgICAgICAqIDxkb2N1bWVudD4sIGV0Yy4gaW5kaWNhdGUgdXNlci1zcGVjaWZpZWQgYXJndW1lbnQgdmFsdWVzLCBhbmQgY2FuCi0gICAgICAgICAqIGJlIHRyYW5zbGF0ZWQgLSB0aGUgYXJndW1lbnQgPGNsYXNzPiByZWZlcnMgdG8gYSBKYXZhIGNsYXNzLCBzbyBpdAotICAgICAgICAgKiBzaG91bGQgYmUgaGFuZGxlZCBpbiB0aGUgc2FtZSB3YXkgdGhlIHRlcm0gaXMgaGFuZGxlZCBmb3IgSkRLCi0gICAgICAgICAqIGRvY3VtZW50YXRpb24uCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVFJBTlNGT1JNX1VTQUdFX1NUUiwKLSAgICAgICAgIlNZTk9QU0lTIFxuICAgamF2YSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY21kbGluZS5UcmFuc2Zvcm0gWy1qIDxqYXJmaWxlPl1cbiAgICAgIFsteF0gWy1uIDxpdGVyYXRpb25lcj5dIHstdSA8ZG9rdW1lbnRfdXJsPiB8IDxkb2t1bWVudD59XG4gICAgICA8a2xhc3M+IFs8cGFyYW0xPj08dlx1MDBFNHJkZTE+IC4uLl1cblxuICAgYW52XHUwMEU0bmRlciB0cmFuc2xldCA8a2xhc3M+IHZpZCB0cmFuc2Zvcm1lcmluZyBhdiBYTUwtZG9rdW1lbnQgXG4gICBhbmdpdm5hIHNvbSA8ZG9rdW1lbnQ+LiBUcmFuc2xldC08a2xhc3M+IGZpbm5zIGFudGluZ2VuIGlcbiAgIGFudlx1MDBFNG5kYXJlbnMgQ0xBU1NQQVRIIGVsbGVyIGkgdmFsZnJpdHQgYW5naXZlbiA8amFyZmlsZT4uXG5BTFRFUk5BVElWXG4gICAtaiA8amFyZmlsZT4gICAgYW5nZXIgZW4gamFyLWZpbCB2YXJpZnJcdTAwRTVuIHRyYW5zbGV0IGxhZGRhc1xuICAgLXggICAgICAgICAgICAgIGdlciB5dHRlcmxpZ2FyZSBmZWxzXHUwMEY2a25pbmdzbWVkZGVsYW5kZW5cbiAgIC1uIDxpdGVyYXRpb25lcj4ga1x1MDBGNnIgPGl0ZXJhdGlvbnM+LXRpZGVyIHZpZCB0cmFuc2Zvcm1lcmluZyBvY2hcbiAgICAgICAgICAgICAgICAgICB2aXNhciBwcm9maWxlcmluZ3NpbmZvcm1hdGlvblxuICAgLXUgPGRva3VtZW50X3VybD4gYW5nZXIgWE1MLWluZGF0YWRva3VtZW50IHNvbSBVUkxcbiJ9LAotCi0KLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIjx4c2w6c29ydD4iLCAiPHhzbDpmb3ItZWFjaD4iIGFuZAotICAgICAgICAgKiAiPHhzbDphcHBseS10ZW1wbGF0ZXM+IiBhcmUga2V5d29yZHMgdGhhdCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqIFRoZSBtZXNzYWdlIGluZGljYXRlcyB0aGF0IGFuIHhzbDpzb3J0IGVsZW1lbnQgbXVzdCBiZSBhIGNoaWxkIG9mCi0gICAgICAgICAqIG9uZSBvZiB0aGUgb3RoZXIga2luZHMgb2YgZWxlbWVudHMgbWVudGlvbmVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlNUUkFZX1NPUlRfRVJSLAotICAgICAgICAiPHhzbDpzb3J0PiBrYW4gYW52XHUwMEU0bmRhcyBlbmRhc3QgaSA8eHNsOmZvci1lYWNoPiBlbGxlciA8eHNsOmFwcGx5LXRlbXBsYXRlcz4uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoZSBlbmNvZGluZwotICAgICAgICAgKiByZXF1ZXN0ZWQgZm9yIHRoZSBvdXRwdXQgZG9jdW1lbnQgd2FzIG9uIHRoYXQgcmVxdWlyZXMgc3VwcG9ydCB0aGF0Ci0gICAgICAgICAqIGlzIG5vdCBhdmFpbGFibGUgZnJvbSB0aGUgSmF2YSBWaXJ0dWFsIE1hY2hpbmUgYmVpbmcgdXNlZCB0byBleGVjdXRlCi0gICAgICAgICAqIHRoZSBwcm9ncmFtLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlVOU1VQUE9SVEVEX0VOQ09ESU5HLAotICAgICAgICAiVXRkYXRha29kbmluZyAnJ3swfScnIHVuZGVyc3RcdTAwRjZkcyBpbnRlIGkgSlZNLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUgWFBhdGggZXhwcmVzc2lvbgotICAgICAgICAgKiBuYW1lZCBpbiB0aGUgc3Vic3RpdHV0aW9uIHRleHQgd2FzIG5vdCB3ZWxsIGZvcm1lZCBzeW50YWN0aWNhbGx5LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlNZTlRBWF9FUlIsCi0gICAgICAgICJTeW50YXhmZWwgaSAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYSBKYXZhCi0gICAgICAgICAqIGNsYXNzLiAgVGhlIHRlcm0gImNvbnN0cnVjdG9yIiBoZXJlIGlzIHRoZSBKYXZhIHRlcm0uICBUaGUgbWVzc2FnZSBpcwotICAgICAgICAgKiBkaXNwbGF5ZWQgaWYgWFNMVEMgY291bGQgbm90IGZpbmQgYSBjb25zdHJ1Y3RvciBmb3IgdGhlIHNwZWNpZmllZAotICAgICAgICAgKiBjbGFzcy4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5DT05TVFJVQ1RPUl9OT1RfRk9VTkQsCi0gICAgICAgICJIaXR0YXIgaW50ZSBkZW4gZXh0ZXJuYSBrb25zdHJ1a3Rvcm4gJyd7MH0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgInN0YXRpYyIgaXMgdGhlIEphdmEga2V5d29yZC4gIFRoZSBzdWJzdGl0dXRpb24KLSAgICAgICAgICogdGV4dCBpcyB0aGUgbmFtZSBvZiBhIGZ1bmN0aW9uLiAgVGhlIGZpcnN0IGFyZ3VtZW50IG9mIHRoYXQgZnVuY3Rpb24KLSAgICAgICAgICogaXMgbm90IG9mIHRoZSByZXF1aXJlZCB0eXBlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk5PX0pBVkFfRlVOQ1RfVEhJU19SRUYsCi0gICAgICAgICJEZXQgZlx1MDBGNnJzdGEgYXJndW1lbnRldCBmXHUwMEY2ciBkZW4gaWNrZS1zdGF0aXNrYSBKYXZhLWZ1bmt0aW9uZW4gJyd7MH0nJyBcdTAwRTRyIGludGUgblx1MDBFNWdvbiBnaWx0aWcgb2JqZWt0cmVmZXJlbnMuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIFhQYXRoIGV4cHJlc3Npb24gd2FzIG5vdCBvZiB0aGUgdHlwZQotICAgICAgICAgKiByZXF1aXJlZCBpbiBhIHBhcnRpY3VsYXIgY29udGV4dC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUKLSAgICAgICAgICogZXhwcmVzc2lvbiB0aGF0IHdhcyBpbiBlcnJvci4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5UWVBFX0NIRUNLX0VSUiwKLSAgICAgICAgIkZlbCB2aWQga29udHJvbGwgYXYgdHlwIGF2IHV0dHJ5Y2tldCAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBbiBYUGF0aCBleHByZXNzaW9uIHdhcyBub3Qgb2YgdGhlIHR5cGUKLSAgICAgICAgICogcmVxdWlyZWQgaW4gYSBwYXJ0aWN1bGFyIGNvbnRleHQuICBIb3dldmVyLCB0aGUgbG9jYXRpb24gb2YgdGhlCi0gICAgICAgICAqIHByb2JsZW1hdGljIGV4cHJlc3Npb24gaXMgdW5rbm93bi4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5UWVBFX0NIRUNLX1VOS19MT0NfRVJSLAotICAgICAgICAiRmVsIHZpZCBrb250cm9sbCBhdiB0eXAgYXYgZXR0IHV0dHJ5Y2sgcFx1MDBFNSBva1x1MDBFNG5kIHBsYXRzLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYSBjb21tYW5kLQotICAgICAgICAgKiBsaW5lIG9wdGlvbiB0aGF0IHdhcyBub3QgcmVjb2duaXplZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTExFR0FMX0NNRExJTkVfT1BUSU9OX0VSUiwKLSAgICAgICAgIk9naWx0aWd0IGtvbW1hbmRvcmFkc2FsdGVybmF0aXY6ICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBhIGNvbW1hbmQtCi0gICAgICAgICAqIGxpbmUgb3B0aW9uLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkNNRExJTkVfT1BUX01JU1NJTkdfQVJHX0VSUiwKLSAgICAgICAgIktvbW1hbmRvcmFkc2FsdGVybmF0aXZldCAnJ3swfScnIHNha25hciBvYmxpZ2F0b3Jpc2t0IGFyZ3VtZW50LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgdXNlZCB0byBpbmRpY2F0ZSB0aGUgc2V2ZXJpdHkKLSAgICAgICAgICogb2YgYW5vdGhlciBtZXNzYWdlLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGNvbnRhaW5zIHR3byBlcnJvcgotICAgICAgICAgKiBtZXNzYWdlcy4gIFRoZSBzcGFjaW5nIGJlZm9yZSB0aGUgc2Vjb25kIHN1YnN0aXR1dGlvbiB0ZXh0IGluZGVudHMKLSAgICAgICAgICogaXQgdGhlIHNhbWUgYW1vdW50IGFzIHRoZSBmaXJzdCBpbiBFbmdsaXNoLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLldBUk5JTkdfUExVU19XUkFQUEVEX01TRywKLSAgICAgICAgIldBUk5JTkc6ICAnJ3swfScnXG4gICAgICAgOnsxfSJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgdXNlZCB0byBpbmRpY2F0ZSB0aGUgc2V2ZXJpdHkKLSAgICAgICAgICogb2YgYW5vdGhlciBtZXNzYWdlLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIGFuIGVycm9yIG1lc3NhZ2UuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuV0FSTklOR19NU0csCi0gICAgICAgICJXQVJOSU5HOiAgJyd7MH0nJyJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgdXNlZCB0byBpbmRpY2F0ZSB0aGUgc2V2ZXJpdHkKLSAgICAgICAgICogb2YgYW5vdGhlciBtZXNzYWdlLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGNvbnRhaW5zIHR3byBlcnJvcgotICAgICAgICAgKiBtZXNzYWdlcy4gIFRoZSBzcGFjaW5nIGJlZm9yZSB0aGUgc2Vjb25kIHN1YnN0aXR1dGlvbiB0ZXh0IGluZGVudHMKLSAgICAgICAgICogaXQgdGhlIHNhbWUgYW1vdW50IGFzIHRoZSBmaXJzdCBpbiBFbmdsaXNoLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkZBVEFMX0VSUl9QTFVTX1dSQVBQRURfTVNHLAotICAgICAgICAiRkFUQUwgRVJST1I6ICAnJ3swfScnXG4gICAgICAgICAgIDp7MX0ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIHVzZWQgdG8gaW5kaWNhdGUgdGhlIHNldmVyaXR5Ci0gICAgICAgICAqIG9mIGFub3RoZXIgbWVzc2FnZS4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyBhbiBlcnJvciBtZXNzYWdlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkZBVEFMX0VSUl9NU0csCi0gICAgICAgICJGQVRBTCBFUlJPUjogICcnezB9JycifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIHVzZWQgdG8gaW5kaWNhdGUgdGhlIHNldmVyaXR5Ci0gICAgICAgICAqIG9mIGFub3RoZXIgbWVzc2FnZS4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBjb250YWlucyB0d28gZXJyb3IKLSAgICAgICAgICogbWVzc2FnZXMuICBUaGUgc3BhY2luZyBiZWZvcmUgdGhlIHNlY29uZCBzdWJzdGl0dXRpb24gdGV4dCBpbmRlbnRzCi0gICAgICAgICAqIGl0IHRoZSBzYW1lIGFtb3VudCBhcyB0aGUgZmlyc3QgaW4gRW5nbGlzaC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5FUlJPUl9QTFVTX1dSQVBQRURfTVNHLAotICAgICAgICAiRVJST1I6ICAnJ3swfScnXG4gICAgIDp7MX0ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIHVzZWQgdG8gaW5kaWNhdGUgdGhlIHNldmVyaXR5Ci0gICAgICAgICAqIG9mIGFub3RoZXIgbWVzc2FnZS4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyBhbiBlcnJvciBtZXNzYWdlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkVSUk9SX01TRywKLSAgICAgICAgIkVSUk9SOiAgJyd7MH0nJyJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYSBjbGFzcy4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5UUkFOU0ZPUk1fV0lUSF9UUkFOU0xFVF9TVFIsCi0gICAgICAgICJUcmFuc2Zvcm1lcmluZyB2aWEgdHJhbnNsZXQgJyd7MH0nJyAifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZpcnN0IHN1YnN0aXR1dGlvbiBpcyB0aGUgbmFtZSBvZiBhIGNsYXNzLAotICAgICAgICAgKiB3aGlsZSB0aGUgc2Vjb25kIHN1YnN0aXR1dGlvbiBpcyB0aGUgbmFtZSBvZiBhIGphciBmaWxlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlRSQU5TRk9STV9XSVRIX0pBUl9TVFIsCi0gICAgICAgICJUcmFuc2Zvcm1lcmluZyB2aWEgdHJhbnNsZXQgJyd7MH0nJyBmclx1MDBFNW4gamFyLWZpbGVuICcnezF9JycifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIlRyYW5zZm9ybWVyRmFjdG9yeSIgaXMgdGhlIG5hbWUgb2YgYSBKYXZhCi0gICAgICAgICAqIGludGVyZmFjZSBhbmQgbXVzdCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcwotICAgICAgICAgKiB0aGUgbmFtZSBvZiB0aGUgY2xhc3MgdGhhdCBjb3VsZCBub3QgYmUgaW5zdGFudGlhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkNPVUxEX05PVF9DUkVBVEVfVFJBTlNfRkFDVCwKLSAgICAgICAgIkt1bmRlIGludGUgc2thcGEgZW4gaW5zdGFucyBhdiBUcmFuc2Zvcm1lckZhY3Rvcnkta2xhc3NlbiAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgcHJvZHVjZWQgd2hlbiB0aGUgdXNlcgotICAgICAgICAgKiBzcGVjaWZpZWQgYSBuYW1lIGZvciB0aGUgdHJhbnNsZXQgY2xhc3MgdGhhdCBjb250YWlucyBjaGFyYWN0ZXJzCi0gICAgICAgICAqIHRoYXQgYXJlIG5vdCBwZXJtaXR0ZWQgaW4gYSBKYXZhIGNsYXNzIG5hbWUuICBUaGUgc3Vic3RpdHV0aW9uCi0gICAgICAgICAqIHRleHQgInswfSIgc3BlY2lmaWVzIHRoZSBuYW1lIHRoZSB1c2VyIHJlcXVlc3RlZCwgd2hpbGUgInsxfSIKLSAgICAgICAgICogc3BlY2lmaWVzIHRoZSBuYW1lIHRoZSBwcm9jZXNzb3IgdXNlZCBpbnN0ZWFkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlRSQU5TTEVUX05BTUVfSkFWQV9DT05GTElDVCwKLSAgICAgICAgICInJ3swfScnIGt1bmRlIGludGUgYW52XHUwMEU0bmRhcyBzb20gbmFtbiBwXHUwMEU1IHRyYW5zbGV0a2xhc3NlbiBlZnRlcnNvbSBkZXQgaW5uZWhcdTAwRTVsbGVyIG90aWxsXHUwMEU1dG5hIHRlY2tlbiBmXHUwMEY2ciBKYXZhLWtsYXNzbmFtbi4gTmFtbmV0ICcnezF9JycgYW52XHUwMEU0bmRlcyBpc3RcdTAwRTRsbGV0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgaXMgdXNlZCBhcyBhIGhlYWRlci4KLSAgICAgICAgICogQWxsIHRoZSBlcnJvciBtZXNzYWdlcyBhcmUgY29sbGVjdGVkIHRvZ2V0aGVyIGFuZCBkaXNwbGF5ZWQgYmVuZWF0aAotICAgICAgICAgKiB0aGlzIG1lc3NhZ2UuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuQ09NUElMRVJfRVJST1JfS0VZLAotICAgICAgICAiS29tcGlsZXJpbmdzZmVsOiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgaXMgdXNlZCBhcyBhIGhlYWRlci4KLSAgICAgICAgICogQWxsIHRoZSB3YXJuaW5nIG1lc3NhZ2VzIGFyZSBjb2xsZWN0ZWQgdG9nZXRoZXIgYW5kIGRpc3BsYXllZAotICAgICAgICAgKiBiZW5lYXRoIHRoaXMgbWVzc2FnZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5DT01QSUxFUl9XQVJOSU5HX0tFWSwKLSAgICAgICAgIktvbXBpbGVyaW5nc3Zhcm5pbmdhcjoifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIGlzIHVzZWQgYXMgYSBoZWFkZXIuCi0gICAgICAgICAqIEFsbCB0aGUgZXJyb3IgbWVzc2FnZXMgdGhhdCBhcmUgcHJvZHVjZWQgd2hlbiB0aGUgc3R5bGVzaGVldCBpcwotICAgICAgICAgKiBhcHBsaWVkIHRvIGFuIGlucHV0IGRvY3VtZW50IGFyZSBjb2xsZWN0ZWQgdG9nZXRoZXIgYW5kIGRpc3BsYXllZAotICAgICAgICAgKiBiZW5lYXRoIHRoaXMgbWVzc2FnZS4gIEEgJ3RyYW5zbGV0JyBpcyB0aGUgY29tcGlsZWQgZm9ybSBvZiBhCi0gICAgICAgICAqIHN0eWxlc2hlZXQgKHNlZSBhYm92ZSkuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuUlVOVElNRV9FUlJPUl9LRVksCi0gICAgICAgICJUcmFuc2xldGZlbDoifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQW4gYXR0cmlidXRlIHdob3NlIHZhbHVlIGlzIGNvbnN0cmFpbmVkIHRvCi0gICAgICAgICAqIGJlIGEgIlFOYW1lIiBvciBhIGxpc3Qgb2YgIlFOYW1lcyIgaGFkIGEgdmFsdWUgdGhhdCB3YXMgaW5jb3JyZWN0LgotICAgICAgICAgKiAnUU5hbWUnIGlzIGFuIFhNTCBzeW50YWN0aWMgdGVybSB0aGF0IG11c3Qgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGUKLSAgICAgICAgICogc3Vic3RpdHV0aW9uIHRleHQgY29udGFpbnMgdGhlIGFjdHVhbCB2YWx1ZSBvZiB0aGUgYXR0cmlidXRlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklOVkFMSURfUU5BTUVfRVJSLAotICAgICAgICAiRXR0IGF0dHJpYnV0IHZhcnMgdlx1MDBFNHJkZSBtXHUwMEU1c3RlIHZhcmEgZXR0IFFOYW1lIGVsbGVyIGVuIGJsYW5rdGVja2VuYXZnclx1MDBFNG5zYWQgbGlzdGEgbWVkIFFOYW1lcyBoYWRlIHZcdTAwRTRyZGV0ICcnezB9JycifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQW4gYXR0cmlidXRlIHdob3NlIHZhbHVlIGlzIHJlcXVpcmVkIHRvCi0gICAgICAgICAqIGJlIGFuICJOQ05hbWUiLgotICAgICAgICAgKiAnTkNOYW1lJyBpcyBhbiBYTUwgc3ludGFjdGljIHRlcm0gdGhhdCBtdXN0IG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhlCi0gICAgICAgICAqIHN1YnN0aXR1dGlvbiB0ZXh0IGNvbnRhaW5zIHRoZSBhY3R1YWwgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTlZBTElEX05DTkFNRV9FUlIsCi0gICAgICAgICJFdHQgYXR0cmlidXQgdmFycyB2XHUwMEU0cmRlIG1cdTAwRTVzdGUgdmFyYSBldHQgTkNOYW1lIGhhZGUgdlx1MDBFNHJkZXQgJyd7MH0nJyJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBbiBhdHRyaWJ1dGUgd2l0aCBhbiBpbmNvcnJlY3QgdmFsdWUgd2FzCi0gICAgICAgICAqIGVuY291bnRlcmVkLiAgVGhlIHBlcm1pdHRlZCB2YWx1ZSBpcyBvbmUgb2YgdGhlIGxpdGVyYWwgdmFsdWVzCi0gICAgICAgICAqICJ4bWwiLCAiaHRtbCIgb3IgInRleHQiOyBpdCBpcyBhbHNvIHBlcm1pdHRlZCB0byBoYXZlIHRoZSBmb3JtIG9mCi0gICAgICAgICAqIGEgUU5hbWUgdGhhdCBpcyBub3QgYWxzbyBhbiBOQ05hbWUuICBUaGUgdGVybXMgIm1ldGhvZCIsCi0gICAgICAgICAqICJ4c2w6b3V0cHV0IiwgInhtbCIsICJodG1sIiBhbmQgInRleHQiIGFyZSBrZXl3b3JkcyB0aGF0IG11c3Qgbm90Ci0gICAgICAgICAqIGJlIHRyYW5zbGF0ZWQuICBUaGUgdGVybSAicW5hbWUtYnV0LW5vdC1uY25hbWUiIGlzIGFuIFhNTCBzeW50YWN0aWMKLSAgICAgICAgICogdGVybS4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBjb250YWlucyB0aGUgYWN0dWFsIHZhbHVlIG9mIHRoZQotICAgICAgICAgKiBhdHRyaWJ1dGUuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSU5WQUxJRF9NRVRIT0RfSU5fT1VUUFVULAotICAgICAgICAiTWV0b2RhdHRyaWJ1dGV0IGZcdTAwRjZyIGV0dCA8eHNsOm91dHB1dD4tZWxlbWVudCBoYWRlIHZcdTAwRTRyZGV0ICcnezB9JycuIEVuZGFzdCBuXHUwMEU1Z290IGF2IGZcdTAwRjZsamFuZGUgdlx1MDBFNHJkZW4ga2FuIGFudlx1MDBFNG5kYXM6ICcneG1sJycsICcnaHRtbCcnLCAnJ3RleHQnJyBlbGxlciBxbmFtZS1idXQtbm90LW5jbmFtZSBpIFhNTCJ9LAotCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX0dFVF9GRUFUVVJFX05VTExfTkFNRSwKLSAgICAgICAgIkZ1bmt0aW9uc25hbW5ldCBrYW4gaW50ZSB2YXJhIG51bGwgaSBUcmFuc2Zvcm1lckZhY3RvcnkuZ2V0RmVhdHVyZShuYW1uIHBcdTAwRTUgc3RyXHUwMEU0bmcpLiJ9LAotCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX1NFVF9GRUFUVVJFX05VTExfTkFNRSwKLSAgICAgICAgIkZ1bmt0aW9uc25hbW5ldCBrYW4gaW50ZSB2YXJhIG51bGwgaSBUcmFuc2Zvcm1lckZhY3Rvcnkuc2V0RmVhdHVyZShuYW1uIHBcdTAwRTUgc3RyXHUwMEU0bmcsIGJvb2xlc2t0IHZcdTAwRTRyZGUpLiJ9LAotCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX1VOU1VQUE9SVEVEX0ZFQVRVUkUsCi0gICAgICAgICJLYW4gaW50ZSBzdFx1MDBFNGxsYSBpbiBmdW5rdGlvbmVuICcnezB9JycgaSBkZW5uYSBUcmFuc2Zvcm1lckZhY3RvcnkuIn0sCi0KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfU0VDVVJFUFJPQ0VTU0lOR19GRUFUVVJFLAotICAgICAgICAiRkVBVFVSRV9TRUNVUkVfUFJPQ0VTU0lORzogRnVua3Rpb25lbiBrYW4gaW50ZSBhbmdlcyB0aWxsIGZhbHNlIG9tIHNcdTAwRTRrZXJoZXRzaGFudGVyYXJlbiBhbnZcdTAwRTRuZHMuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBkZXNjcmliZXMgYW4gaW50ZXJuYWwgZXJyb3IgaW4gdGhlCi0gICAgICAgICAqIHByb2Nlc3Nvci4gIFRoZSB0ZXJtICJieXRlIGNvZGUiIGlzIGEgSmF2YSB0ZWNobmljYWwgdGVybSBmb3IgdGhlCi0gICAgICAgICAqIGV4ZWN1dGFibGUgY29kZSBpbiBhIEphdmEgbWV0aG9kLCBhbmQgInRyeS1jYXRjaC1maW5hbGx5IGJsb2NrIgotICAgICAgICAgKiByZWZlcnMgdG8gdGhlIEphdmEga2V5d29yZHMgd2l0aCB0aG9zZSBuYW1lcy4gICJPdXRsaW5lZCIgaXMgYQotICAgICAgICAgKiB0ZWNobmljYWwgdGVybSBpbnRlcm5hbCB0byBYU0xUQyBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk9VVExJTkVfRVJSX1RSWV9DQVRDSCwKLSAgICAgICAgICJJbnRlcm50IFhTTFRDLWZlbDogZGVuIGdlbmVyZXJhZGUgYnl0ZWtvZGVuIGlubmVoXHUwMEU1bGxlciBldHQgdHJ5LWNhdGNoLWZpbmFsbHktYmxvY2sgb2NoIGthbiBpbnRlIGdcdTAwRjZyYXMgdGlsbCBlbiBkaXNwb3NpdGlvbi4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGRlc2NyaWJlcyBhbiBpbnRlcm5hbCBlcnJvciBpbiB0aGUKLSAgICAgICAgICogcHJvY2Vzc29yLiAgVGhlIHRlcm1zICJPdXRsaW5lYWJsZUNodW5rU3RhcnQiIGFuZAotICAgICAgICAgKiAiT3V0bGluZWFibGVDaHVua0VuZCIgYXJlIHRoZSBuYW1lcyBvZiBjbGFzc2VzIGludGVybmFsIHRvIFhTTFRDIGFuZAotICAgICAgICAgKiBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCBmb3IgZXZlcnkKLSAgICAgICAgICogInN0YXJ0IiB0aGVyZSBtdXN0IGJlIGEgY29ycmVzcG9uZGluZyAiZW5kIiwgYW5kIHZpY2UgdmVyc2EsIGFuZAotICAgICAgICAgKiB0aGF0IGlmIG9uZSBvZiBhIHBhaXIgb2YgInN0YXJ0IiBhbmQgImVuZCIgYXBwZWFycyBiZXR3ZWVuIGFub3RoZXIKLSAgICAgICAgICogcGFpciBvZiBjb3JyZXNwb25kaW5nICJzdGFydCIgYW5kICJlbmQiLCB0aGVuIHRoZSBvdGhlciBoYWxmIG9mIHRoZQotICAgICAgICAgKiBwYWlyIG11c3QgYWxzbyBiZSBiZXR3ZWVuIHRoYXQgc2FtZSBlbmNsb3NpbmcgcGFpci4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5PVVRMSU5FX0VSUl9VTkJBTEFOQ0VEX01BUktFUlMsCi0gICAgICAgICAiSW50ZXJudCBYU0xUQy1mZWw6IG1hcmtcdTAwRjZyZXJuYSBPdXRsaW5lYWJsZUNodW5rU3RhcnQgb2NoIE91dGxpbmVhYmxlQ2h1bmtFbmQgbVx1MDBFNXN0ZSB2YXJhIGJhbGFuc2VyYWRlIG9jaCBrb3JyZWt0IGthcHNsYWRlLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgZGVzY3JpYmVzIGFuIGludGVybmFsIGVycm9yIGluIHRoZQotICAgICAgICAgKiBwcm9jZXNzb3IuICBUaGUgdGVybSAiYnl0ZSBjb2RlIiBpcyBhIEphdmEgdGVjaG5pY2FsIHRlcm0gZm9yIHRoZQotICAgICAgICAgKiBleGVjdXRhYmxlIGNvZGUgaW4gYSBKYXZhIG1ldGhvZC4gIFRoZSAibWV0aG9kIiB0aGF0IGlzIGJlaW5nCi0gICAgICAgICAqIHJlZmVycmVkIHRvIGlzIGEgSmF2YSBtZXRob2QgaW4gYSB0cmFuc2xldCB0aGF0IFhTTFRDIGlzIGdlbmVyYXRpbmcKLSAgICAgICAgICogaW4gcHJvY2Vzc2luZyBhIHN0eWxlc2hlZXQuICBUaGUgImluc3RydWN0aW9uIiB0aGF0IGlzIGJlaW5nCi0gICAgICAgICAqIHJlZmVycmVkIHRvIGlzIG9uZSBvZiB0aGUgaW5zdHJ1dGlvbnMgaW4gdGhlIEphdmEgYnl0ZSBjb2RlIGluIHRoYXQKLSAgICAgICAgICogbWV0aG9kLiAgIk91dGxpbmVkIiBpcyBhIHRlY2huaWNhbCB0ZXJtIGludGVybmFsIHRvIFhTTFRDIGFuZAotICAgICAgICAgKiBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuT1VUTElORV9FUlJfREVMRVRFRF9UQVJHRVQsCi0gICAgICAgICAiSW50ZXJudCBYU0xUQy1mZWw6IG9yaWdpbmFsbWV0b2RlbiByZWZlcmVyYXIgZm9ydGZhcmFuZGUgdGlsbCBlbiBpbnN0cnVrdGlvbiBzb20gdmFyIGVuIGRlbCBhdiBldHQgYnl0ZWtvZHNibG9jayBzb20gZ2pvcmRlcyB0aWxsIGVuIGRpc3Bvc2l0aW9uLiIKLSAgICAgICAgfSwKLQotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgZGVzY3JpYmVzIGFuIGludGVybmFsIGVycm9yIGluIHRoZQotICAgICAgICAgKiBwcm9jZXNzb3IuICBUaGUgIm1ldGhvZCIgdGhhdCBpcyBiZWluZyByZWZlcnJlZCB0byBpcyBhIEphdmEgbWV0aG9kCi0gICAgICAgICAqIGluIGEgdHJhbnNsZXQgdGhhdCBYU0xUQyBpcyBnZW5lcmF0aW5nLgotICAgICAgICAgKgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk9VVExJTkVfRVJSX01FVEhPRF9UT09fQklHLAotICAgICAgICAgIkludGVybnQgWFNMVEMtZmVsOiBlbiBtZXRvZCBpIHRyYW5zbGV0ZW4gXHUwMEY2dmVyc3RpZ2VyIEphdmEgVmlydHVhbCBNYWNoaW5lcyBsXHUwMEU0bmdkYmVnclx1MDBFNG5zbmluZyBmXHUwMEY2ciBlbiBtZXRvZCBwXHUwMEU1IDY0IGtpbG9ieXRlcy4gIERldCBoXHUwMEU0ciBvcnNha2FzIHZhbmxpZ2VuIGF2IG15Y2tldCBzdG9yYSBtYWxsYXIgaSBlbiBmb3JtYXRtYWxsLiBGXHUwMEY2cnNcdTAwRjZrIGF0dCBvbXN0cnVrdHVyZXJhIGZvcm1hdG1hbGxlbiBhdHQgYW52XHUwMEU0bmRhIG1pbmRyZSBtYWxsYXIuIgotICAgICAgICB9LAotCi0gICAgICAgICB7RXJyb3JNc2cuREVTRVJJQUxJWkVfVFJBTlNMRVRfRVJSLCAiTlx1MDBFNHIgSmF2YS1zXHUwMEU0a2VyaGV0ZW4gXHUwMEU0ciBha3RpdmVyYWQgXHUwMEU0ciBzdFx1MDBGNmRldCBmXHUwMEY2ciBhdnNlcmlhbGlzZXJpbmcgYXYgVGVtcGxhdGVzSW1wbCBhdmFrdGl2ZXJhdC4gRHUga2FuIFx1MDBFNXNpZG9zXHUwMEU0dHRhIGRldCBoXHUwMEU0ciBnZW5vbSBhdHQgc3RcdTAwRTRsbGEgaW4gc3lzdGVtZWdlbnNrYXBlbiBqZGsueG1sLmVuYWJsZVRlbXBsYXRlc0ltcGxEZXNlcmlhbGl6YXRpb24gdGlsbCBzYW50LiJ9Ci0KLSAgICB9OwotCi0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci91dGlsL0Vycm9yTWVzc2FnZXNfemhfQ04uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvdXRpbC9FcnJvck1lc3NhZ2VzX3poX0NOLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGNjNzU4ZTkuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci91dGlsL0Vycm9yTWVzc2FnZXNfemhfQ04uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDk3NCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWw7Ci0KLWltcG9ydCBqYXZhLnV0aWwuTGlzdFJlc291cmNlQnVuZGxlOwotCi0vKioKLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICovCi1wdWJsaWMgY2xhc3MgRXJyb3JNZXNzYWdlc196aF9DTiBleHRlbmRzIExpc3RSZXNvdXJjZUJ1bmRsZSB7Ci0KLS8qCi0gKiBYU0xUQyBjb21waWxlLXRpbWUgZXJyb3IgbWVzc2FnZXMuCi0gKgotICogR2VuZXJhbCBub3RlcyB0byB0cmFuc2xhdG9ycyBhbmQgZGVmaW5pdGlvbnM6Ci0gKgotICogICAxKSBYU0xUQyBpcyB0aGUgbmFtZSBvZiB0aGUgcHJvZHVjdC4gIEl0IGlzIGFuIGFjcm9ueW0gZm9yICJYU0xUIENvbXBpbGVyIi4KLSAqICAgICAgWFNMVCBpcyBhbiBhY3JvbnltIGZvciAiWE1MIFN0eWxlc2hlZXQgTGFuZ3VhZ2U6IFRyYW5zZm9ybWF0aW9ucyIuCi0gKgotICogICAyKSBBIHN0eWxlc2hlZXQgaXMgYSBkZXNjcmlwdGlvbiBvZiBob3cgdG8gdHJhbnNmb3JtIGFuIGlucHV0IFhNTCBkb2N1bWVudAotICogICAgICBpbnRvIGEgcmVzdWx0YW50IFhNTCBkb2N1bWVudCAob3IgSFRNTCBkb2N1bWVudCBvciB0ZXh0KS4gIFRoZQotICogICAgICBzdHlsZXNoZWV0IGl0c2VsZiBpcyBkZXNjcmliZWQgaW4gdGhlIGZvcm0gb2YgYW4gWE1MIGRvY3VtZW50LgotICoKLSAqICAgMykgQSB0ZW1wbGF0ZSBpcyBhIGNvbXBvbmVudCBvZiBhIHN0eWxlc2hlZXQgdGhhdCBpcyB1c2VkIHRvIG1hdGNoIGEKLSAqICAgICAgcGFydGljdWxhciBwb3J0aW9uIG9mIGFuIGlucHV0IGRvY3VtZW50IGFuZCBzcGVjaWZpZXMgdGhlIGZvcm0gb2YgdGhlCi0gKiAgICAgIGNvcnJlc3BvbmRpbmcgcG9ydGlvbiBvZiB0aGUgb3V0cHV0IGRvY3VtZW50LgotICoKLSAqICAgNCkgQW4gYXhpcyBpcyBhIHBhcnRpY3VsYXIgImRpbWVuc2lvbiIgaW4gYSB0cmVlIHJlcHJlc2VudGF0aW9uIG9mIGFuIFhNTAotICogICAgICBkb2N1bWVudDsgdGhlIG5vZGVzIGluIHRoZSB0cmVlIGFyZSBkaXZpZGVkIGFsb25nIGRpZmZlcmVudCBheGVzLgotICogICAgICBUcmF2ZXJzaW5nIHRoZSAiY2hpbGQiIGF4aXMsIGZvciBpbnN0YW5jZSwgbWVhbnMgdGhhdCB0aGUgcHJvZ3JhbQotICogICAgICB3b3VsZCB2aXNpdCBlYWNoIGNoaWxkIG9mIGEgcGFydGljdWxhciBub2RlOyB0cmF2ZXJzaW5nIHRoZSAiZGVzY2VuZGFudCIKLSAqICAgICAgYXhpcyBtZWFucyB0aGF0IHRoZSBwcm9ncmFtIHdvdWxkIHZpc2l0IHRoZSBjaGlsZCBub2RlcyBvZiBhIHBhcnRpY3VsYXIKLSAqICAgICAgbm9kZSwgdGhlaXIgY2hpbGRyZW4sIGFuZCBzbyBvbiB1bnRpbCB0aGUgbGVhZiBub2RlcyBvZiB0aGUgdHJlZSBhcmUKLSAqICAgICAgcmVhY2hlZC4KLSAqCi0gKiAgIDUpIEFuIGl0ZXJhdG9yIGlzIGFuIG9iamVjdCB0aGF0IHRyYXZlcnNlcyBub2RlcyBpbiBhIHRyZWUgYWxvbmcgYQotICogICAgICBwYXJ0aWN1bGFyIGF4aXMsIG9uZSBhdCBhIHRpbWUuCi0gKgotICogICA2KSBBbiBlbGVtZW50IGlzIGEgbWFyay11cCB0YWcgaW4gYW4gWE1MIGRvY3VtZW50OyBhbiBhdHRyaWJ1dGUgaXMgYQotICogICAgICBtb2RpZmllciBvbiB0aGUgdGFnLiAgRm9yIGV4YW1wbGUsIGluIDxlbGVtIGF0dHI9J3ZhbCcgYXR0cjI9J3ZhbDInPgotICogICAgICAiZWxlbSIgaXMgYW4gZWxlbWVudCBuYW1lLCAiYXR0ciIgYW5kICJhdHRyMiIgYXJlIGF0dHJpYnV0ZSBuYW1lcyB3aXRoCi0gKiAgICAgIHRoZSB2YWx1ZXMgInZhbCIgYW5kICJ2YWwyIiwgcmVzcGVjdGl2ZWx5LgotICoKLSAqICAgNykgQSBuYW1lc3BhY2UgZGVjbGFyYXRpb24gaXMgYSBzcGVjaWFsIGF0dHJpYnV0ZSB0aGF0IGlzIHVzZWQgdG8gYXNzb2NpYXRlCi0gKiAgICAgIGEgcHJlZml4IHdpdGggYSBVUkkgKHRoZSBuYW1lc3BhY2UpLiAgVGhlIG1lYW5pbmdzIG9mIGVsZW1lbnQgbmFtZXMgYW5kCi0gKiAgICAgIGF0dHJpYnV0ZSBuYW1lcyB0aGF0IHVzZSB0aGF0IHByZWZpeCBhcmUgZGVmaW5lZCB3aXRoIHJlc3BlY3QgdG8gdGhhdAotICogICAgICBuYW1lc3BhY2UuCi0gKgotICogICA4KSBET00gaXMgYW4gYWNyb255bSBmb3IgRG9jdW1lbnQgT2JqZWN0IE1vZGVsLiAgSXQgaXMgYSB0cmVlCi0gKiAgICAgIHJlcHJlc2VudGF0aW9uIG9mIGFuIFhNTCBkb2N1bWVudC4KLSAqCi0gKiAgICAgIFNBWCBpcyBhbiBhY3JvbnltIGZvciB0aGUgU2ltcGxlIEFQSSBmb3IgWE1MIHByb2Nlc3NpbmcuICBJdCBpcyBhbiBBUEkKLSAqICAgICAgdXNlZCBpbmZvcm0gYW4gWE1MIHByb2Nlc3NvciAoaW4gdGhpcyBjYXNlIFhTTFRDKSBvZiB0aGUgc3RydWN0dXJlIGFuZAotICogICAgICBjb250ZW50IG9mIGFuIFhNTCBkb2N1bWVudC4KLSAqCi0gKiAgICAgIElucHV0IHRvIHRoZSBzdHlsZXNoZWV0IHByb2Nlc3NvciBjYW4gY29tZSBmcm9tIGFuIFhNTCBwYXJzZXIgaW4gdGhlCi0gKiAgICAgIGZvcm0gb2YgYSBET00gdHJlZSBvciB0aHJvdWdoIHRoZSBTQVggQVBJLgotICoKLSAqICAgOSkgRFREIGlzIGEgZG9jdW1lbnQgdHlwZSBkZWNsYXJhdGlvbi4gIEl0IGlzIGEgd2F5IG9mIHNwZWNpZnlpbmcgdGhlCi0gKiAgICAgIGdyYW1tYXIgZm9yIGFuIFhNTCBmaWxlLCB0aGUgbmFtZXMgYW5kIHR5cGVzIG9mIGVsZW1lbnRzLCBhdHRyaWJ1dGVzLAotICogICAgICBldGMuCi0gKgotICogIDEwKSBYUGF0aCBpcyBhIHNwZWNpZmljYXRpb24gdGhhdCBkZXNjcmliZXMgYSBub3RhdGlvbiBmb3IgaWRlbnRpZnlpbmcKLSAqICAgICAgbm9kZXMgaW4gYSB0cmVlLXN0cnVjdHVyZWQgcmVwcmVzZW50YXRpb24gb2YgYW4gWE1MIGRvY3VtZW50LiAgQW4KLSAqICAgICAgaW5zdGFuY2Ugb2YgdGhhdCBub3RhdGlvbiBpcyByZWZlcnJlZCB0byBhcyBhbiBYUGF0aCBleHByZXNzaW9uLgotICoKLSAqICAxMSkgVHJhbnNsZXQgaXMgYW4gaW52ZW50ZWQgdGVybSB0aGF0IHJlZmVycyB0byB0aGUgY2xhc3MgZmlsZSB0aGF0IGNvbnRhaW5zCi0gKiAgICAgIHRoZSBjb21waWxlZCBmb3JtIG9mIGEgc3R5bGVzaGVldC4KLSAqLwotCi0gICAgLy8gVGhlc2UgbWVzc2FnZSBzaG91bGQgYmUgcmVhZCBmcm9tIGEgbG9jYWxlLXNwZWNpZmljIHJlc291cmNlIGJ1bmRsZQotICAgIC8qKiBHZXQgdGhlIGxvb2t1cCB0YWJsZSBmb3IgZXJyb3IgbWVzc2FnZXMuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBtZXNzYWdlIGxvb2t1cCB0YWJsZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0W11bXSBnZXRDb250ZW50cygpCi0gICAgewotICAgICAgcmV0dXJuIG5ldyBPYmplY3RbXVtdIHsKLSAgICAgICAge0Vycm9yTXNnLk1VTFRJUExFX1NUWUxFU0hFRVRfRVJSLAotICAgICAgICAiXHU1NDBDXHU0RTAwXHU2NTg3XHU0RUY2XHU0RTJEXHU1QjlBXHU0RTQ5XHU0RTg2XHU1OTFBXHU0RTJBXHU2ODM3XHU1RjBGXHU4ODY4XHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBhCi0gICAgICAgICAqIHRlbXBsYXRlLiAgVGhlIHNhbWUgbmFtZSB3YXMgdXNlZCBvbiB0d28gZGlmZmVyZW50IHRlbXBsYXRlcyBpbiB0aGUKLSAgICAgICAgICogc2FtZSBzdHlsZXNoZWV0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlRFTVBMQVRFX1JFREVGX0VSUiwKLSAgICAgICAgIlx1NURGMlx1NTcyOFx1NkI2NFx1NjgzN1x1NUYwRlx1ODg2OFx1NEUyRFx1NUI5QVx1NEU0OVx1NkEyMVx1Njc3RiAnJ3swfScnXHUzMDAyIn0sCi0KLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIGEKLSAgICAgICAgICogdGVtcGxhdGUuICBBIHJlZmVyZW5jZSB0byB0aGUgdGVtcGxhdGUgbmFtZSB3YXMgZW5jb3VudGVyZWQsIGJ1dCB0aGUKLSAgICAgICAgICogdGVtcGxhdGUgaXMgdW5kZWZpbmVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlRFTVBMQVRFX1VOREVGX0VSUiwKLSAgICAgICAgIlx1NjcyQVx1NTcyOFx1NkI2NFx1NjgzN1x1NUYwRlx1ODg2OFx1NEUyRFx1NUI5QVx1NEU0OVx1NkEyMVx1Njc3RiAnJ3swfScnXHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBhIHZhcmlhYmxlCi0gICAgICAgICAqIHRoYXQgd2FzIGRlZmluZWQgbW9yZSB0aGFuIG9uY2UuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVkFSSUFCTEVfUkVERUZfRVJSLAotICAgICAgICAiXHU1NDBDXHU0RTAwXHU0RjVDXHU3NTI4XHU1N0RGXHU0RTJEXHU1OTFBXHU2QjIxXHU1QjlBXHU0RTQ5XHU0RTg2XHU1M0Q4XHU5MUNGICcnezB9JydcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIGEgdmFyaWFibGUKLSAgICAgICAgICogb3IgcGFyYW1ldGVyLiAgQSByZWZlcmVuY2UgdG8gdGhlIHZhcmlhYmxlIG9yIHBhcmFtZXRlciB3YXMgZm91bmQsCi0gICAgICAgICAqIGJ1dCBpdCB3YXMgbmV2ZXIgZGVmaW5lZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5WQVJJQUJMRV9VTkRFRl9FUlIsCi0gICAgICAgICJcdTY3MkFcdTVCOUFcdTRFNDlcdTUzRDhcdTkxQ0ZcdTYyMTZcdTUzQzJcdTY1NzAgJyd7MH0nJ1x1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgd29yZCAiY2xhc3MiIGhlcmUgcmVmZXJzIHRvIGEgSmF2YSBjbGFzcy4KLSAgICAgICAgICogUHJvY2Vzc2luZyB0aGUgc3R5bGVzaGVldCByZXF1aXJlZCBhIGNsYXNzIHRvIGJlIGxvYWRlZCwgYnV0IGl0IGNvdWxkCi0gICAgICAgICAqIG5vdCBiZSBmb3VuZC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiB0aGUgY2xhc3MuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuQ0xBU1NfTk9UX0ZPVU5EX0VSUiwKLSAgICAgICAgIlx1NjI3RVx1NEUwRFx1NTIzMFx1N0M3QiAnJ3swfScnXHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSB3b3JkICJtZXRob2QiIGhlcmUgcmVmZXJzIHRvIGEgSmF2YSBtZXRob2QuCi0gICAgICAgICAqIFByb2Nlc3NpbmcgdGhlIHN0eWxlc2hlZXQgcmVxdWlyZWQgYSByZWZlcmVuY2UgdG8gdGhlIG1ldGhvZCBuYW1lZCBieQotICAgICAgICAgKiB0aGUgc3Vic3RpdHV0aW9uIHRleHQsIGJ1dCBpdCBjb3VsZCBub3QgYmUgZm91bmQuICAicHVibGljIiBpcyB0aGUKLSAgICAgICAgICogSmF2YSBrZXl3b3JkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk1FVEhPRF9OT1RfRk9VTkRfRVJSLAotICAgICAgICAiXHU2MjdFXHU0RTBEXHU1MjMwXHU1OTE2XHU5MEU4XHU2NUI5XHU2Q0Q1ICcnezB9JycgKFx1NUZDNVx1OTg3Qlx1NEUzQSBwdWJsaWMpXHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSB3b3JkICJtZXRob2QiIGhlcmUgcmVmZXJzIHRvIGEgSmF2YSBtZXRob2QuCi0gICAgICAgICAqIFByb2Nlc3NpbmcgdGhlIHN0eWxlc2hlZXQgcmVxdWlyZWQgYSByZWZlcmVuY2UgdG8gdGhlIG1ldGhvZCBuYW1lZCBieQotICAgICAgICAgKiB0aGUgc3Vic3RpdHV0aW9uIHRleHQsIGJ1dCBubyBtZXRob2Qgd2l0aCB0aGUgcmVxdWlyZWQgdHlwZXMgb2YKLSAgICAgICAgICogYXJndW1lbnRzIG9yIHJldHVybiB0eXBlIGNvdWxkIGJlIGZvdW5kLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkFSR1VNRU5UX0NPTlZFUlNJT05fRVJSLAotICAgICAgICAiXHU2NUUwXHU2Q0Q1XHU1NzI4XHU4QzAzXHU3NTI4XHU2NUI5XHU2Q0Q1ICcnezB9JycgXHU2NUY2XHU4RjZDXHU2MzYyXHU1M0MyXHU2NTcwL1x1OEZENFx1NTZERVx1N0M3Qlx1NTc4QiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZmlsZSBvciBVUkkgbmFtZWQgaW4gdGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgICAqIGlzIG1pc3NpbmcuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuRklMRV9OT1RfRk9VTkRfRVJSLAotICAgICAgICAiXHU2MjdFXHU0RTBEXHU1MjMwXHU2NTg3XHU0RUY2XHU2MjE2IFVSSSAnJ3swfScnXHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyBkaXNwbGF5ZWQgd2hlbiB0aGUgVVJJCi0gICAgICAgICAqIG1lbnRpb25lZCBpbiB0aGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgbm90IHdlbGwtZm9ybWVkIHN5bnRhY3RpY2FsbHkuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSU5WQUxJRF9VUklfRVJSLAotICAgICAgICAiVVJJICcnezB9JycgXHU2NUUwXHU2NTQ4XHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmaWxlIG9yIFVSSSBuYW1lZCBpbiB0aGUgc3Vic3RpdHV0aW9uIHRleHQKLSAgICAgICAgICogZXhpc3RzIGJ1dCBjb3VsZCBub3QgYmUgb3BlbmVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkZJTEVfQUNDRVNTX0VSUiwKLSAgICAgICAgIlx1NjVFMFx1NkNENVx1NjI1M1x1NUYwMFx1NjU4N1x1NEVGNlx1NjIxNiBVUkkgJyd7MH0nJ1x1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6IDx4c2w6c3R5bGVzaGVldD4gYW5kIDx4c2w6dHJhbnNmb3JtPiBhcmUKLSAgICAgICAgICoga2V5d29yZHMgdGhhdCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTUlTU0lOR19ST09UX0VSUiwKLSAgICAgICAgIlx1OTcwMFx1ODk4MSA8eHNsOnN0eWxlc2hlZXQ+IFx1NjIxNiA8eHNsOnRyYW5zZm9ybT4gXHU1MTQzXHU3RDIwXHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IGNvbnRhaW5lZCBhIHJlZmVyZW5jZSB0byBhCi0gICAgICAgICAqIG5hbWVzcGFjZSBwcmVmaXggdGhhdCB3YXMgdW5kZWZpbmVkLiAgVGhlIHZhbHVlIG9mIHRoZSBzdWJzdGl0dXRpb24KLSAgICAgICAgICogdGV4dCBpcyB0aGUgbmFtZSBvZiB0aGUgcHJlZml4LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk5BTUVTUEFDRV9VTkRFRl9FUlIsCi0gICAgICAgICJcdTY3MkFcdTU4RjBcdTY2MEVcdTU0MERcdTc5RjBcdTdBN0FcdTk1RjRcdTUyNERcdTdGMDAgJyd7MH0nJ1x1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgSmF2YSBmdW5jdGlvbiBuYW1lZCBpbiB0aGUgc3R5bGVzaGVldCBjb3VsZAotICAgICAgICAgKiBub3QgYmUgZm91bmQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuRlVOQ1RJT05fUkVTT0xWRV9FUlIsCi0gICAgICAgICJcdTY1RTBcdTZDRDVcdTg5RTNcdTY3OTBcdTVCRjlcdTUxRkRcdTY1NzAgJyd7MH0nJyBcdTc2ODRcdThDMDNcdTc1MjhcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIGEKLSAgICAgICAgICogZnVuY3Rpb24uICBBIGxpdGVyYWwgc3RyaW5nIGhlcmUgbWVhbnMgYSBjb25zdGFudCBzdHJpbmcgdmFsdWUuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTkVFRF9MSVRFUkFMX0VSUiwKLSAgICAgICAgIicnezB9JycgXHU3Njg0XHU1M0MyXHU2NTcwXHU1RkM1XHU5ODdCXHU2NjJGXHU2NTg3XHU1QjU3XHU1QjU3XHU3QjI2XHU0RTMyXHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpbmRpY2F0ZXMgdGhlcmUgd2FzIGEgc3ludGFjdGljCi0gICAgICAgICAqIGVycm9yIGluIHRoZSBmb3JtIG9mIGFuIFhQYXRoIGV4cHJlc3Npb24uICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMKLSAgICAgICAgICogdGhlIGV4cHJlc3Npb24uCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuWFBBVEhfUEFSU0VSX0VSUiwKLSAgICAgICAgIlx1ODlFM1x1Njc5MCBYUGF0aCBcdTg4NjhcdThGQkVcdTVGMEYgJyd7MH0nJyBcdTY1RjZcdTUxRkFcdTk1MTlcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQW4gZWxlbWVudCBpbiB0aGUgc3R5bGVzaGVldCByZXF1aXJlcyBhCi0gICAgICAgICAqIHBhcnRpY3VsYXIgYXR0cmlidXRlIG5hbWVkIGJ5IHRoZSBzdWJzdGl0dXRpb24gdGV4dCwgYnV0IHRoYXQKLSAgICAgICAgICogYXR0cmlidXRlIHdhcyBub3Qgc3BlY2lmaWVkIGluIHRoZSBzdHlsZXNoZWV0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlJFUVVJUkVEX0FUVFJfRVJSLAotICAgICAgICAiXHU3RjNBXHU1QzExXHU2MjQwXHU5NzAwXHU1QzVFXHU2MDI3ICcnezB9JydcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IGEgY2hhcmFjdGVyIG5vdAotICAgICAgICAgKiBwZXJtaXR0ZWQgaW4gYW4gWFBhdGggZXhwcmVzc2lvbiB3YXMgZW5jb3VudGVyZWQuICBUaGUgc3Vic3RpdHV0aW9uCi0gICAgICAgICAqIHRleHQgaXMgdGhlIG9mZmVuZGluZyBjaGFyYWN0ZXIuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSUxMRUdBTF9DSEFSX0VSUiwKLSAgICAgICAgIlhQYXRoIFx1ODg2OFx1OEZCRVx1NUYwRlx1NEUyRFx1NzY4NFx1NUI1N1x1N0IyNiAnJ3swfScnIFx1OTc1RVx1NkNENVx1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gaXMgYSBtYXJrLXVwIGl0ZW0gaW4KLSAgICAgICAgICogYW4gWE1MIGRvY3VtZW50IHRoYXQgcmVxdWVzdCBzb21lIGJlaGF2aW91ciBvZiBhbiBYTUwgcHJvY2Vzc29yLiAgVGhlCi0gICAgICAgICAqIGZvcm0gb2YgdGhlIG5hbWUgb2Ygd2FzIGludmFsaWQgaW4gdGhpcyBjYXNlLCBhbmQgdGhlIHN1YnN0aXR1dGlvbgotICAgICAgICAgKiB0ZXh0IGlzIHRoZSBuYW1lLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfUElfRVJSLAotICAgICAgICAicHJvY2Vzc2luZyBpbnN0cnVjdGlvbiBcdTc2ODRcdTU0MERcdTc5RjAgJyd7MH0nJyBcdTk3NUVcdTZDRDVcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIHJlcG9ydGVkIGlmIHRoZSBzdHlsZXNoZWV0Ci0gICAgICAgICAqIGJlaW5nIHByb2Nlc3NlZCBhdHRlbXB0ZWQgdG8gY29uc3RydWN0IGFuIFhNTCBkb2N1bWVudCB3aXRoIGFuCi0gICAgICAgICAqIGF0dHJpYnV0ZSBpbiBhIHBsYWNlIG90aGVyIHRoYW4gb24gYW4gZWxlbWVudC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICAgKiBzcGVjaWZpZXMgdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5TVFJBWV9BVFRSSUJVVEVfRVJSLAotICAgICAgICAiXHU1QzVFXHU2MDI3ICcnezB9JycgXHU1NzI4XHU1MTQzXHU3RDIwXHU1OTE2XHU5MEU4XHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIGF0dHJpYnV0ZSB0aGF0IHdhc24ndCByZWNvZ25pemVkIHdhcwotICAgICAgICAgKiBzcGVjaWZpZWQgb24gYW4gZWxlbWVudCBpbiB0aGUgc3R5bGVzaGVldC4gIFRoZSBhdHRyaWJ1dGUgaXMgbmFtZWQKLSAgICAgICAgICogYnkgdGhlIHN1YnN0aXR1dGlvbgotICAgICAgICAgKiB0ZXh0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfQVRUUklCVVRFX0VSUiwKLSAgICAgICAgIlx1NUM1RVx1NjAyNyAnJ3swfScnIFx1OTc1RVx1NkNENVx1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiaW1wb3J0IiBhbmQgImluY2x1ZGUiIGFyZSBrZXl3b3JkcyB0aGF0IHNob3VsZAotICAgICAgICAgKiBub3QgYmUgdHJhbnNsYXRlZC4gIFRoaXMgbWVzc2FnZXMgaW5kaWNhdGVzIHRoYXQgdGhlIHN0eWxlc2hlZXQKLSAgICAgICAgICogbmFtZWQgaW4gdGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGltcG9ydGVkIG9yIGluY2x1ZGVkIGl0c2VsZiBlaXRoZXIKLSAgICAgICAgICogZGlyZWN0bHkgb3IgaW5kaXJlY3RseS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5DSVJDVUxBUl9JTkNMVURFX0VSUiwKLSAgICAgICAgIlx1NUZBQVx1NzNBRiBpbXBvcnQvaW5jbHVkZVx1MzAwMlx1NURGMlx1NTJBMFx1OEY3RFx1NjgzN1x1NUYwRlx1ODg2OCAnJ3swfScnXHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEEgcmVzdWx0LXRyZWUgZnJhZ21lbnQgaXMgYSBwb3J0aW9uIG9mIGEKLSAgICAgICAgICogcmVzdWx0aW5nIFhNTCBkb2N1bWVudCByZXByZXNlbnRlZCBhcyBhIHRyZWUuICAiPHhzbDpzb3J0PiIgaXMgYQotICAgICAgICAgKiBrZXl3b3JkIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuUkVTVUxUX1RSRUVfU09SVF9FUlIsCi0gICAgICAgICJcdTY1RTBcdTZDRDVcdTVCRjlcdTdFRDNcdTY3OUNcdTY4MTFcdTcyNDdcdTZCQjVcdTYzOTJcdTVFOEYgKFx1NUZGRFx1NzU2NSA8eHNsOnNvcnQ+IFx1NTE0M1x1N0QyMClcdTMwMDJcdTVGQzVcdTk4N0JcdTU3MjhcdTUyMUJcdTVFRkFcdTdFRDNcdTY3OUNcdTY4MTFcdTY1RjZcdTVCRjlcdTgyODJcdTcwQjlcdThGREJcdTg4NENcdTYzOTJcdTVFOEZcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQSBuYW1lIGNhbiBiZSBnaXZlbiB0byBhIHBhcnRpY3VsYXIgc3R5bGUgdG8gYmUKLSAgICAgICAgICogdXNlZCB0byBmb3JtYXQgZGVjaW1hbCB2YWx1ZXMuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgZ2l2ZXMgdGhlIG5hbWUKLSAgICAgICAgICogb2Ygc3VjaCBhIHN0eWxlIGZvciB3aGljaCBtb3JlIHRoYW4gb25lIGRlY2xhcmF0aW9uIHdhcyBlbmNvdW50ZXJlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5TWU1CT0xTX1JFREVGX0VSUiwKLSAgICAgICAgIlx1NURGMlx1NUI5QVx1NEU0OVx1NTM0MVx1OEZEQlx1NTIzNlx1NjgzQ1x1NUYwRiAnJ3swfScnXHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IHZlcnNpb24gbmFtZWQgaW4gdGhlCi0gICAgICAgICAqIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIG5vdCBzdXBwb3J0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuWFNMX1ZFUlNJT05fRVJSLAotICAgICAgICAiWFNMVEMgXHU0RTBEXHU2NTJGXHU2MzAxIFhTTCBcdTcyNDhcdTY3MkMgJyd7MH0nJ1x1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZGVmaW5pdGlvbnMgb2Ygb25lIG9yIG1vcmUgdmFyaWFibGVzIG9yCi0gICAgICAgICAqIHBhcmFtZXRlcnMgZGVwZW5kIG9uIG9uZSBhbm90aGVyLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkNJUkNVTEFSX1ZBUklBQkxFX0VSUiwKLSAgICAgICAgIicnezB9JycgXHU0RTJEXHU1QjU4XHU1NzI4XHU1RkFBXHU3M0FGXHU1M0Q4XHU5MUNGL1x1NTNDMlx1NjU3MFx1NUYxNVx1NzUyOFx1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgb3BlcmF0b3IgaW4gYW4gZXhwcmVzaW9uIHdpdGggdHdvIG9wZXJhbmRzIHdhcwotICAgICAgICAgKiBub3QgcmVjb2duaXplZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTExFR0FMX0JJTkFSWV9PUF9FUlIsCi0gICAgICAgICJcdTRFOENcdThGREJcdTUyMzZcdTg4NjhcdThGQkVcdTVGMEZcdTc2ODRcdThGRDBcdTdCOTdcdTdCMjZcdTY3MkFcdTc3RTVcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIHByb2R1Y2VkIGlmIGEgcmVmZXJlbmNlIHRvIGEKLSAgICAgICAgICogZnVuY3Rpb24gaGFzIHRvbyBtYW55IG9yIHRvbyBmZXcgYXJndW1lbnRzLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfQVJHX0VSUiwKLSAgICAgICAgIlx1NTFGRFx1NjU3MFx1OEMwM1x1NzUyOFx1NzY4NFx1NTNDMlx1NjU3MFx1OTc1RVx1NkNENVx1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiZG9jdW1lbnQoKSIgaXMgdGhlIG5hbWUgb2YgZnVuY3Rpb24gYW5kIG11c3QKLSAgICAgICAgICogbm90IGJlIHRyYW5zbGF0ZWQuICBBIG5vZGUtc2V0IGlzIGEgc2V0IG9mIHRoZSBub2RlcyBpbiB0aGUgdHJlZQotICAgICAgICAgKiByZXByZXNlbnRhdGlvbiBvZiBhbiBYTUwgZG9jdW1lbnQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuRE9DVU1FTlRfQVJHX0VSUiwKLSAgICAgICAgImRvY3VtZW50KCkgXHU1MUZEXHU2NTcwXHU3Njg0XHU3QjJDXHU0RThDXHU0RTJBXHU1M0MyXHU2NTcwXHU1RkM1XHU5ODdCXHU2NjJGXHU4MjgyXHU3MEI5XHU5NkM2XHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICI8eHNsOndoZW4+IiBhbmQgIjx4c2w6Y2hvb3NlPiIgYXJlIGtleXdvcmRzCi0gICAgICAgICAqIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGlzIG1lc3NhZ2UgZGVzY3JpYmVzIGEgc3ludGF4IGVycm9yCi0gICAgICAgICAqIGluIHRoZSBzdHlsZXNoZWV0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk1JU1NJTkdfV0hFTl9FUlIsCi0gICAgICAgICI8eHNsOmNob29zZT4gXHU0RTJEXHU4MUYzXHU1QzExXHU5NzAwXHU4OTgxXHU0RTAwXHU0RTJBIDx4c2w6d2hlbj4gXHU1MTQzXHU3RDIwXHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICI8eHNsOm90aGVyd2lzZT4iIGFuZCAiPHhzbDpjaG9vc2U+IiBhcmUKLSAgICAgICAgICoga2V5d29yZHMgYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoaXMgbWVzc2FnZSBkZXNjcmliZXMgYQotICAgICAgICAgKiBzeW50YXggZXJyb3IgaW4gdGhlIHN0eWxlc2hlZXQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTVVMVElQTEVfT1RIRVJXSVNFX0VSUiwKLSAgICAgICAgIjx4c2w6Y2hvb3NlPiBcdTRFMkRcdTRFQzVcdTUxNDFcdThCQjhcdTRGN0ZcdTc1MjhcdTRFMDBcdTRFMkEgPHhzbDpvdGhlcndpc2U+IFx1NTE0M1x1N0QyMFx1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiPHhzbDpvdGhlcndpc2U+IiBhbmQgIjx4c2w6Y2hvb3NlPiIgYXJlCi0gICAgICAgICAqIGtleXdvcmRzIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGlzIG1lc3NhZ2UgZGVzY3JpYmVzIGEKLSAgICAgICAgICogc3ludGF4IGVycm9yIGluIHRoZSBzdHlsZXNoZWV0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlNUUkFZX09USEVSV0lTRV9FUlIsCi0gICAgICAgICI8eHNsOm90aGVyd2lzZT4gXHU1M0VBXHU4MEZEXHU1NzI4IDx4c2w6Y2hvb3NlPiBcdTRFMkRcdTRGN0ZcdTc1MjhcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIjx4c2w6d2hlbj4iIGFuZCAiPHhzbDpjaG9vc2U+IiBhcmUga2V5d29yZHMKLSAgICAgICAgICogYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoaXMgbWVzc2FnZSBkZXNjcmliZXMgYSBzeW50YXggZXJyb3IKLSAgICAgICAgICogaW4gdGhlIHN0eWxlc2hlZXQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuU1RSQVlfV0hFTl9FUlIsCi0gICAgICAgICI8eHNsOndoZW4+IFx1NTNFQVx1ODBGRFx1NTcyOCA8eHNsOmNob29zZT4gXHU0RTJEXHU0RjdGXHU3NTI4XHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICI8eHNsOndoZW4+IiwgIjx4c2w6b3RoZXJ3aXNlPiIgYW5kCi0gICAgICAgICAqICI8eHNsOmNob29zZT4iIGFyZSBrZXl3b3JkcyBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhpcwotICAgICAgICAgKiBtZXNzYWdlIGRlc2NyaWJlcyBhIHN5bnRheCBlcnJvciBpbiB0aGUgc3R5bGVzaGVldC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5XSEVOX0VMRU1FTlRfRVJSLAotICAgICAgICAiPHhzbDpjaG9vc2U+IFx1NEUyRFx1NEVDNVx1NTE0MVx1OEJCOFx1NEY3Rlx1NzUyOCA8eHNsOndoZW4+IFx1NTQ4QyA8eHNsOm90aGVyd2lzZT4gXHU1MTQzXHU3RDIwXHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICI8eHNsOmF0dHJpYnV0ZS1zZXQ+IiBhbmQgIm5hbWUiIGFyZSBrZXl3b3JkcwotICAgICAgICAgKiB0aGF0IHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5VTk5BTUVEX0FUVFJJQlNFVF9FUlIsCi0gICAgICAgICI8eHNsOmF0dHJpYnV0ZS1zZXQ+IFx1N0YzQVx1NUMxMSAnbmFtZScgXHU1QzVFXHU2MDI3XHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIGVsZW1lbnQgaW4gdGhlIHN0eWxlc2hlZXQgY29udGFpbmVkIGFuCi0gICAgICAgICAqIGVsZW1lbnQgb2YgYSB0eXBlIHRoYXQgaXQgd2FzIG5vdCBwZXJtaXR0ZWQgdG8gY29udGFpbi4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTExFR0FMX0NISUxEX0VSUiwKLSAgICAgICAgIlx1NUI1MFx1NTE0M1x1N0QyMFx1OTc1RVx1NkNENVx1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3R5bGVzaGVldCB0cmllZCB0byBjcmVhdGUgYW4gZWxlbWVudCB3aXRoCi0gICAgICAgICAqIGEgbmFtZSB0aGF0IHdhcyBub3QgYSB2YWxpZCBYTUwgbmFtZS4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBjb250YWlucwotICAgICAgICAgKiB0aGUgbmFtZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTExFR0FMX0VMRU1fTkFNRV9FUlIsCi0gICAgICAgICJcdTY1RTBcdTZDRDVcdThDMDNcdTc1MjhcdTUxNDNcdTdEMjAgJyd7MH0nJyJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3R5bGVzaGVldCB0cmllZCB0byBjcmVhdGUgYW4gYXR0cmlidXRlCi0gICAgICAgICAqIHdpdGggYSBuYW1lIHRoYXQgd2FzIG5vdCBhIHZhbGlkIFhNTCBuYW1lLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgICAqIGNvbnRhaW5zIHRoZSBuYW1lLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfQVRUUl9OQU1FX0VSUiwKLSAgICAgICAgIlx1NjVFMFx1NkNENVx1OEMwM1x1NzUyOFx1NUM1RVx1NjAyNyAnJ3swfScnIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBjaGlsZHJlbiBvZiB0aGUgb3V0ZXJtb3N0IGVsZW1lbnQgb2YgYQotICAgICAgICAgKiBzdHlsZXNoZWV0IGFyZSByZWZlcnJlZCB0byBhcyB0b3AtbGV2ZWwgZWxlbWVudHMuICBObyB0ZXh0IHNob3VsZAotICAgICAgICAgKiBvY2N1ciB3aXRoaW4gdGhhdCBvdXRlcm1vc3QgZWxlbWVudCB1bmxlc3MgaXQgaXMgd2l0aGluIGEgdG9wLWxldmVsCi0gICAgICAgICAqIGVsZW1lbnQuICBUaGlzIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhhdCBjb25zdHJhaW50IHdhcyB2aW9sYXRlZC4KLSAgICAgICAgICogIjx4c2w6c3R5bGVzaGVldD4iIGlzIGEga2V5d29yZCB0aGF0IHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTExFR0FMX1RFWFRfTk9ERV9FUlIsCi0gICAgICAgICJcdTY1ODdcdTY3MkNcdTY1NzBcdTYzNkVcdTRGNERcdTRFOEVcdTk4NzZcdTdFQTcgPHhzbDpzdHlsZXNoZWV0PiBcdTUxNDNcdTdEMjBcdTU5MTZcdTkwRThcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgSkFYUCBpcyBhbiBhY3JvbnltIGZvciB0aGUgSmF2YSBBUEkgZm9yIFhNTAotICAgICAgICAgKiBQcm9jZXNzaW5nLiAgVGhpcyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoZSBYTUwgcGFyc2VyIHByb3ZpZGVkIHRvCi0gICAgICAgICAqIFhTTFRDIHRvIHByb2Nlc3MgdGhlIFhNTCBpbnB1dCBkb2N1bWVudCBoYWQgYSBjb25maWd1cmF0aW9uIHByb2JsZW0uCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuU0FYX1BBUlNFUl9DT05GSUdfRVJSLAotICAgICAgICAiSkFYUCBcdTg5RTNcdTY3OTBcdTU2NjhcdTY3MkFcdTZCNjNcdTc4NkVcdTkxNERcdTdGNkUifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IG5hbWVzIHRoZSBpbnRlcm5hbCBlcnJvcgotICAgICAgICAgKiBlbmNvdW50ZXJlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTlRFUk5BTF9FUlIsCi0gICAgICAgICJcdTRFMERcdTUzRUZcdTYwNjJcdTU5MERcdTc2ODQgWFNMVEMgXHU1MTg1XHU5MEU4XHU5NTE5XHU4QkVGOiAnJ3swfScnIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IGNvbnRhaW5lZCBhbiBlbGVtZW50IHRoYXQgd2FzCi0gICAgICAgICAqIG5vdCByZWNvZ25pemVkIGFzIHBhcnQgb2YgdGhlIFhTTCBzeW50YXguICBUaGUgc3Vic3RpdHV0aW9uIHRleHQKLSAgICAgICAgICogZ2l2ZXMgdGhlIGVsZW1lbnQgbmFtZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5VTlNVUFBPUlRFRF9YU0xfRVJSLAotICAgICAgICAiWFNMIFx1NTE0M1x1N0QyMCAnJ3swfScnIFx1NEUwRFx1NTNEN1x1NjUyRlx1NjMwMVx1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3R5bGVzaGVldCByZWZlcnJlZCB0byBhbiBleHRlbnNpb24gdG8gdGhlCi0gICAgICAgICAqIFhTTCBzeW50YXggYW5kIGluZGljYXRlZCB0aGF0IGl0IHdhcyBkZWZpbmVkIGJ5IFhTTFRDLCBidXQgWFNUTEMgZG9lcwotICAgICAgICAgKiBub3QgcmVjb2duaXplZCB0aGUgcGFydGljdWxhciBleHRlbnNpb24gbmFtZWQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQKLSAgICAgICAgICogZ2l2ZXMgdGhlIGV4dGVuc2lvbiBuYW1lLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlVOU1VQUE9SVEVEX0VYVF9FUlIsCi0gICAgICAgICJYU0xUQyBcdTYyNjlcdTVDNTUgJyd7MH0nJyBcdTY1RTBcdTZDRDVcdThCQzZcdTUyMkJcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIFhNTCBkb2N1bWVudCBnaXZlbiB0byBYU0xUQyBhcyBhIHN0eWxlc2hlZXQKLSAgICAgICAgICogd2FzIG5vdCwgaW4gZmFjdCwgYSBzdHlsZXNoZWV0LiAgWFNMVEMgaXMgYWJsZSB0byBkZXRlY3QgdGhhdCBpbiB0aGlzCi0gICAgICAgICAqIGNhc2UgYmVjYXVzZSB0aGUgb3V0ZXJtb3N0IGVsZW1lbnQgaW4gdGhlIHN0eWxlc2hlZXQgaGFzIHRvIGJlCi0gICAgICAgICAqIGRlY2xhcmVkIHdpdGggcmVzcGVjdCB0byB0aGUgWFNMIG5hbWVzcGFjZSBVUkksIGJ1dCBubyBkZWNsYXJhdGlvbgotICAgICAgICAgKiBmb3IgdGhhdCBuYW1lc3BhY2Ugd2FzIHNlZW4uCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTUlTU0lOR19YU0xUX1VSSV9FUlIsCi0gICAgICAgICJcdThGOTNcdTUxNjVcdTY1ODdcdTY4NjNcdTRFMERcdTY2MkZcdTY4MzdcdTVGMEZcdTg4NjggKFx1NjcyQVx1NTcyOFx1NjgzOVx1NTE0M1x1N0QyMFx1NEUyRFx1NThGMFx1NjYwRSBYU0wgXHU1NDBEXHU3OUYwXHU3QTdBXHU5NUY0KVx1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBYU0xUQyBjb3VsZCBub3QgZmluZCB0aGUgc3R5bGVzaGVldCBkb2N1bWVudAotICAgICAgICAgKiB3aXRoIHRoZSBuYW1lIHNwZWNpZmllZCBieSB0aGUgc3Vic3RpdHV0aW9uIHRleHQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTUlTU0lOR19YU0xUX1RBUkdFVF9FUlIsCi0gICAgICAgICJcdTYyN0VcdTRFMERcdTUyMzBcdTY4MzdcdTVGMEZcdTg4NjhcdTc2RUVcdTY4MDcgJyd7MH0nJ1x1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBhY2Nlc3MgdG8gdGhlIHN0eWxlc2hlZXQgdGFyZ2V0IGlzIGRlbmllZAotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkFDQ0VTU0lOR19YU0xUX1RBUkdFVF9FUlIsCi0gICAgICAgICJcdTc1MzFcdTRFOEUgYWNjZXNzRXh0ZXJuYWxTdHlsZXNoZWV0IFx1NUM1RVx1NjAyN1x1OEJCRVx1N0Y2RVx1NzY4NFx1OTY1MFx1NTIzNlx1ODAwQ1x1NEUwRFx1NTE0MVx1OEJCOCAnJ3sxfScnIFx1OEJCRlx1OTVFRSwgXHU1NkUwXHU2QjY0XHU2NUUwXHU2Q0Q1XHU4QkZCXHU1M0Q2XHU2ODM3XHU1RjBGXHU4ODY4XHU3NkVFXHU2ODA3ICcnezB9JydcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIHJlcHJlc2VudHMgYW4gaW50ZXJuYWwgZXJyb3IgaW4KLSAgICAgICAgICogY29uZGl0aW9uIGluIFhTTFRDLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBjbGFzcyBuYW1lIGluIFhTTFRDCi0gICAgICAgICAqIHRoYXQgaXMgbWlzc2luZyBzb21lIGZ1bmN0aW9uYWxpdHkuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTk9UX0lNUExFTUVOVEVEX0VSUiwKLSAgICAgICAgIlx1NjcyQVx1NUI5RVx1NzNCMDogJyd7MH0nJ1x1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgWE1MIGRvY3VtZW50IGdpdmVuIHRvIFhTTFRDIGFzIGEgc3R5bGVzaGVldAotICAgICAgICAgKiB3YXMgbm90LCBpbiBmYWN0LCBhIHN0eWxlc2hlZXQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTk9UX1NUWUxFU0hFRVRfRVJSLAotICAgICAgICAiXHU4RjkzXHU1MTY1XHU2NTg3XHU2ODYzXHU0RTBEXHU1MzA1XHU1NDJCIFhTTCBcdTY4MzdcdTVGMEZcdTg4NjhcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGVsZW1lbnQgbmFtZWQgaW4gdGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHdhcwotICAgICAgICAgKiBlbmNvdW50ZXJlZCBpbiB0aGUgc3R5bGVzaGVldCBidXQgaXMgbm90IHJlY29nbml6ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuRUxFTUVOVF9QQVJTRV9FUlIsCi0gICAgICAgICJcdTY1RTBcdTZDRDVcdTg5RTNcdTY3OTBcdTUxNDNcdTdEMjAgJyd7MH0nJyJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAidXNlIiwgIjxrZXk+IiwgIm5vZGUiLCAibm9kZS1zZXQiLCAic3RyaW5nIgotICAgICAgICAgKiBhbmQgIm51bWJlciIgYXJlIGtleXdvcmRzIGluIHRoaXMgY29udGV4dCBhbmQgc2hvdWxkIG5vdCBiZQotICAgICAgICAgKiB0cmFuc2xhdGVkLiAgVGhpcyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoZSB2YWx1ZSBvZiB0aGUgInVzZSIKLSAgICAgICAgICogYXR0cmlidXRlIHdhcyBub3Qgb25lIG9mIHRoZSBwZXJtaXR0ZWQgdmFsdWVzLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLktFWV9VU0VfQVRUUl9FUlIsCi0gICAgICAgICI8a2V5PiBcdTc2ODQgdXNlIFx1NUM1RVx1NjAyN1x1NUZDNVx1OTg3Qlx1NjYyRiBub2RlLCBub2RlLXNldCwgc3RyaW5nIFx1NjIxNiBudW1iZXJcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQW4gWE1MIGRvY3VtZW50IGNhbiBzcGVjaWZ5IHRoZSB2ZXJzaW9uIG9mIHRoZQotICAgICAgICAgKiBYTUwgc3BlY2lmaWNhdGlvbiB0byB3aGljaCBpdCBhZGhlcmVzLiAgVGhpcyBtZXNzYWdlIGluZGljYXRlcyB0aGF0Ci0gICAgICAgICAqIHRoZSB2ZXJzaW9uIHNwZWNpZmllZCBmb3IgdGhlIG91dHB1dCBkb2N1bWVudCB3YXMgbm90IHZhbGlkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk9VVFBVVF9WRVJTSU9OX0VSUiwKLSAgICAgICAgIlx1OEY5M1x1NTFGQSBYTUwgXHU2NTg3XHU2ODYzXHU3MjQ4XHU2NzJDXHU1RTk0XHU0RTNBIDEuMCJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgb3BlcmF0b3IgaW4gYSBjb21wYXJpc29uIG9wZXJhdGlvbiB3YXMKLSAgICAgICAgICogbm90IHJlY29nbml6ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSUxMRUdBTF9SRUxBVF9PUF9FUlIsCi0gICAgICAgICJcdTUxNzNcdTdDRkJcdTg4NjhcdThGQkVcdTVGMEZcdTc2ODRcdThGRDBcdTdCOTdcdTdCMjZcdTY3MkFcdTc3RTUifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQW4gYXR0cmlidXRlIHNldCBkZWZpbmVzIGFzIGEgc2V0IG9mIFhNTAotICAgICAgICAgKiBhdHRyaWJ1dGVzIHRoYXQgY2FuIGJlIGFkZGVkIHRvIGFuIGVsZW1lbnQgaW4gdGhlIG91dHB1dCBYTUwgZG9jdW1lbnQKLSAgICAgICAgICogYXMgYSBncm91cC4gIFRoaXMgbWVzc2FnZSBpcyByZXBvcnRlZCBpZiB0aGUgbmFtZSBzcGVjaWZpZWQgd2FzIG5vdAotICAgICAgICAgKiB1c2VkIHRvIGRlY2xhcmUgYW4gYXR0cmlidXRlIHNldC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZQotICAgICAgICAgKiB0aGF0IGlzIGluIGVycm9yLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkFUVFJJQlNFVF9VTkRFRl9FUlIsCi0gICAgICAgICJcdTVDMURcdThCRDVcdTRGN0ZcdTc1MjhcdTRFMERcdTVCNThcdTU3MjhcdTc2ODRcdTVDNUVcdTYwMjdcdTk2QzYgJyd7MH0nJ1x1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgdGVybSAiYXR0cmlidXRlIHZhbHVlIHRlbXBsYXRlIiBpcyBhIHRlcm0KLSAgICAgICAgICogZGVmaW5lZCBieSBYU0xUIHdoaWNoIGRlc2NyaWJlcyB0aGUgdmFsdWUgb2YgYW4gYXR0cmlidXRlIHRoYXQgaXMKLSAgICAgICAgICogZGV0ZXJtaW5lZCBieSBhbiBYUGF0aCBleHByZXNzaW9uLiAgVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhlCi0gICAgICAgICAqIGV4cHJlc3Npb24gd2FzIHN5bnRhY3RpY2FsbHkgaW5jb3JyZWN0OyB0aGUgc3Vic3RpdHV0aW9uIHRleHQKLSAgICAgICAgICogY29udGFpbnMgdGhlIGV4cHJlc3Npb24gdGhhdCB3YXMgaW4gZXJyb3IuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuQVRUUl9WQUxfVEVNUExBVEVfRVJSLAotICAgICAgICAiXHU2NUUwXHU2Q0Q1XHU4OUUzXHU2NzkwXHU1QzVFXHU2MDI3XHU1MDNDXHU2QTIxXHU2NzdGICcnezB9JydcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgPz8/Ci0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVU5LTk9XTl9TSUdfVFlQRV9FUlIsCi0gICAgICAgICJcdTdDN0IgJyd7MH0nJyBcdTc2ODRcdTdCN0VcdTU0MERcdTRFMkRcdTc2ODRcdTY1NzBcdTYzNkVcdTdDN0JcdTU3OEJcdTY3MkFcdTc3RTVcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHJlZmVycyB0byBkYXRhIHR5cGVzLgotICAgICAgICAgKiBUaGUgbWVzc2FnZSBpcyBkaXNwbGF5ZWQgaWYgYSB2YWx1ZSBpbiBhIHBhcnRpY3VsYXIgY29udGV4dCBuZWVkcyB0bwotICAgICAgICAgKiBiZSBjb252ZXJ0ZWQgdG8gdHlwZSB7MX0sIGJ1dCB0aGF0J3Mgbm90IHBvc3NpYmxlIGZvciBhIHZhbHVlIG9mCi0gICAgICAgICAqIHR5cGUgezB9LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkRBVEFfQ09OVkVSU0lPTl9FUlIsCi0gICAgICAgICJcdTY1RTBcdTZDRDVcdTVDMDZcdTY1NzBcdTYzNkVcdTdDN0JcdTU3OEIgJyd7MH0nJyBcdThGNkNcdTYzNjJcdTRFM0EgJyd7MX0nJ1x1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiVGVtcGxhdGVzIiBpcyBhIEphdmEgY2xhc3MgbmFtZSB0aGF0IHNob3VsZAotICAgICAgICAgKiBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5OT19UUkFOU0xFVF9DTEFTU19FUlIsCi0gICAgICAgICJcdTZCNjQgVGVtcGxhdGVzIFx1NEUwRFx1NTMwNVx1NTQyQlx1NjcwOVx1NjU0OFx1NzY4NCB0cmFuc2xldCBcdTdDN0JcdTVCOUFcdTRFNDlcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIlRlbXBsYXRlcyIgaXMgYSBKYXZhIGNsYXNzIG5hbWUgdGhhdCBzaG91bGQKLSAgICAgICAgICogbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTk9fTUFJTl9UUkFOU0xFVF9FUlIsCi0gICAgICAgICJcdTZCNjQgVGVtcGxhdGVzIFx1NEUwRFx1NTMwNVx1NTQyQlx1NTQwRFx1NEUzQSAnJ3swfScnIFx1NzY4NFx1N0M3Qlx1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYSBjbGFzcy4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5UUkFOU0xFVF9DTEFTU19FUlIsCi0gICAgICAgICJcdTY1RTBcdTZDRDVcdTUyQTBcdThGN0QgdHJhbnNsZXQgXHU3QzdCICcnezB9JydcdTMwMDIifSwKLQotICAgICAgICB7RXJyb3JNc2cuVFJBTlNMRVRfT0JKRUNUX0VSUiwKLSAgICAgICAgIlx1NURGMlx1NTJBMFx1OEY3RCBUcmFuc2xldCBcdTdDN0IsIFx1NEY0Nlx1NjVFMFx1NkNENVx1NTIxQlx1NUVGQSB0cmFuc2xldCBcdTVCOUVcdTRGOEJcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIkVycm9yTGlzdGVuZXIiIGlzIGEgSmF2YSBpbnRlcmZhY2UgbmFtZSB0aGF0Ci0gICAgICAgICAqIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoZSBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoZSB1c2VyIHRyaWVkCi0gICAgICAgICAqIHRvIHNldCBhbiBFcnJvckxpc3RlbmVyIG9iamVjdCBvbiBvYmplY3Qgb2YgdGhlIGNsYXNzIG5hbWVkIGluIHRoZQotICAgICAgICAgKiBzdWJzdGl0dXRpb24gdGV4dCB3aXRoICJudWxsIiBKYXZhIHZhbHVlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkVSUk9SX0xJU1RFTkVSX05VTExfRVJSLAotICAgICAgICAiXHU1QzFEXHU4QkQ1XHU1QzA2ICcnezB9JycgXHU3Njg0IEVycm9yTGlzdGVuZXIgXHU4QkJFXHU3RjZFXHU0RTNBXHU3QTdBXHU1MDNDIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFN0cmVhbVNvdXJjZSwgU0FYU291cmNlIGFuZCBET01Tb3VyY2UgYXJlIEphdmEKLSAgICAgICAgICogaW50ZXJmYWNlIG5hbWVzIHRoYXQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfVU5LTk9XTl9TT1VSQ0VfRVJSLAotICAgICAgICAiWFNMVEMgXHU0RUM1XHU2NTJGXHU2MzAxIFN0cmVhbVNvdXJjZSwgU0FYU291cmNlIFx1NTQ4QyBET01Tb3VyY2UifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIlNvdXJjZSIgaXMgYSBKYXZhIGNsYXNzIG5hbWUgdGhhdCBzaG91bGQgbm90Ci0gICAgICAgICAqIGJlIHRyYW5zbGF0ZWQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgSmF2YSBtZXRob2QuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSkFYUF9OT19TT1VSQ0VfRVJSLAotICAgICAgICAiXHU0RjIwXHU5MDEyXHU1MjMwICcnezB9JycgXHU3Njg0IFNvdXJjZSBcdTVCRjlcdThDNjFcdTRFMERcdTUzMDVcdTU0MkJcdTRFRkJcdTRGNTVcdTUxODVcdTVCQjlcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgWFNMVEMgZmFpbGVkIHRvCi0gICAgICAgICAqIGNvbXBpbGUgdGhlIHN0eWxlc2hlZXQgaW50byBhIHRyYW5zbGV0IChjbGFzcyBmaWxlKS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX0NPTVBJTEVfRVJSLAotICAgICAgICAiXHU2NUUwXHU2Q0Q1XHU3RjE2XHU4QkQxXHU2ODM3XHU1RjBGXHU4ODY4In0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJUcmFuc2Zvcm1lckZhY3RvcnkiIGlzIGEgY2xhc3MgbmFtZS4gIEluIHRoaXMKLSAgICAgICAgICogY29udGV4dCwgYW4gYXR0cmlidXRlIGlzIGEgcHJvcGVydHkgb3Igc2V0dGluZyBvZiB0aGUKLSAgICAgICAgICogVHJhbnNmb3JtZXJGYWN0b3J5IG9iamVjdC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiB0aGUKLSAgICAgICAgICogdW5yZWNvZ25pc2VkIGF0dHJpYnV0ZS4gIFRoZSBtZXRob2QgdXNlZCB0byByZXRyaWV2ZSB0aGUgYXR0cmlidXRlIGlzCi0gICAgICAgICAqICJnZXRBdHRyaWJ1dGUiLCBzbyBpdCdzIG5vdCBjbGVhciB3aGV0aGVyIGl0IHdvdWxkIGJlIGJlc3QgdG8KLSAgICAgICAgICogdHJhbnNsYXRlIHRoZSB0ZXJtICJhdHRyaWJ1dGUiLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfSU5WQUxJRF9BVFRSX0VSUiwKLSAgICAgICAgIlRyYW5zZm9ybWVyRmFjdG9yeSBcdTY1RTBcdTZDRDVcdThCQzZcdTUyMkJcdTVDNUVcdTYwMjcgJyd7MH0nJ1x1MzAwMiJ9LAotCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX0lOVkFMSURfQVRUUl9WQUxVRV9FUlIsCi0gICAgICAgICJcdTRFM0EgJyd7MH0nJyBcdTVDNUVcdTYwMjdcdTYzMDdcdTVCOUFcdTc2ODRcdTUwM0NcdTRFMERcdTZCNjNcdTc4NkVcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgInNldFJlc3VsdCgpIiBhbmQgInN0YXJ0RG9jdW1lbnQoKSIgYXJlIEphdmEKLSAgICAgICAgICogbWV0aG9kIG5hbWVzIHRoYXQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfU0VUX1JFU1VMVF9FUlIsCi0gICAgICAgICJcdTVGQzVcdTk4N0JcdTUxNDhcdThDMDNcdTc1Mjggc2V0UmVzdWx0KCksIFx1NTE4RFx1OEMwM1x1NzUyOCBzdGFydERvY3VtZW50KClcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIlRyYW5zZm9ybWVyIiBpcyBhIEphdmEgaW50ZXJmYWNlIG5hbWUgdGhhdAotICAgICAgICAgKiBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBBIFRyYW5zZm9ybWVyIG9iamVjdCBzaG91bGQgY29udGFpbmVkIGEKLSAgICAgICAgICogcmVmZXJlbmNlIHRvIGEgdHJhbnNsZXQgb2JqZWN0IGluIG9yZGVyIHRvIGJlIHVzZWQgZm9yCi0gICAgICAgICAqIHRyYW5zZm9ybWF0aW9uczsgdGhpcyBtZXNzYWdlIGlzIHByb2R1Y2VkIGlmIHRoYXQgcmVxdWlyZW1lbnQgaXMgbm90Ci0gICAgICAgICAqIG1ldC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX05PX1RSQU5TTEVUX0VSUiwKLSAgICAgICAgIlRyYW5zZm9ybWVyIFx1NkNBMVx1NjcwOVx1NTE4NVx1NUQ0Q1x1NzY4NCB0cmFuc2xldCBcdTVCRjlcdThDNjFcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIFhNTCBkb2N1bWVudCB0aGF0IHJlc3VsdHMgZnJvbSBhCi0gICAgICAgICAqIHRyYW5zZm9ybWF0aW9uIG5lZWRzIHRvIGJlIHNlbnQgdG8gYW4gb3V0cHV0IGhhbmRsZXIgb2JqZWN0OyB0aGlzCi0gICAgICAgICAqIG1lc3NhZ2UgaXMgcHJvZHVjZWQgaWYgdGhhdCByZXF1aXJlbWVudCBpcyBub3QgbWV0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfTk9fSEFORExFUl9FUlIsCi0gICAgICAgICJcdThGNkNcdTYzNjJcdTdFRDNcdTY3OUNcdTZDQTFcdTY3MDlcdTVCOUFcdTRFNDlcdTc2ODRcdThGOTNcdTUxRkFcdTU5MDRcdTc0MDZcdTdBMEJcdTVFOEZcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIlJlc3VsdCIgaXMgYSBKYXZhIGludGVyZmFjZSBuYW1lIGluIHRoaXMKLSAgICAgICAgICogY29udGV4dC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyBhIG1ldGhvZCBuYW1lLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfTk9fUkVTVUxUX0VSUiwKLSAgICAgICAgIlx1NEYyMFx1OTAxMlx1NTIzMCAnJ3swfScnIFx1NzY4NCBSZXN1bHQgXHU1QkY5XHU4QzYxXHU2NUUwXHU2NTQ4XHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJUcmFuc2Zvcm1lciIgaXMgYSBKYXZhIGludGVyZmFjZSBuYW1lLiAgVGhlCi0gICAgICAgICAqIHVzZXIncyBwcm9ncmFtIGF0dGVtcHRlZCB0byBhY2Nlc3MgYW4gdW5yZWNvZ25pemVkIHByb3BlcnR5IHdpdGggdGhlCi0gICAgICAgICAqIG5hbWUgc3BlY2lmaWVkIGluIHRoZSBzdWJzdGl0dXRpb24gdGV4dC4gIFRoZSBtZXRob2QgdXNlZCB0byByZXRyaWV2ZQotICAgICAgICAgKiB0aGUgcHJvcGVydHkgaXMgImdldE91dHB1dFByb3BlcnR5Iiwgc28gaXQncyBub3QgY2xlYXIgd2hldGhlciBpdAotICAgICAgICAgKiB3b3VsZCBiZSBiZXN0IHRvIHRyYW5zbGF0ZSB0aGUgdGVybSAicHJvcGVydHkiLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfVU5LTk9XTl9QUk9QX0VSUiwKLSAgICAgICAgIlx1NUMxRFx1OEJENVx1OEJCRlx1OTVFRVx1NjVFMFx1NjU0OFx1NzY4NCBUcmFuc2Zvcm1lciBcdTVDNUVcdTYwMjcgJyd7MH0nJ1x1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBTQVgyRE9NIGlzIHRoZSBuYW1lIG9mIGEgSmF2YSBjbGFzcyB0aGF0IHNob3VsZAotICAgICAgICAgKiBub3QgYmUgdHJhbnNsYXRlZC4gIFRoaXMgaXMgYW4gYWRhcHRlciBpbiB0aGUgc2Vuc2UgdGhhdCBpdCB0YWtlcyBhCi0gICAgICAgICAqIERPTSBvYmplY3QgYW5kIGNvbnZlcnRzIGl0IHRvIHNvbWV0aGluZyB0aGF0IHVzZXMgdGhlIFNBWCBBUEkuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuU0FYMkRPTV9BREFQVEVSX0VSUiwKLSAgICAgICAgIlx1NjVFMFx1NkNENVx1NTIxQlx1NUVGQSBTQVgyRE9NIFx1OTAwMlx1OTE0RFx1NTY2ODogJyd7MH0nJ1x1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiWFNMVENTb3VyY2UuYnVpbGQoKSIgaXMgYSBKYXZhIG1ldGhvZCBuYW1lLgotICAgICAgICAgKiAic3lzdGVtSWQiIGlzIGFuIFhNTCB0ZXJtIHRoYXQgaXMgc2hvcnQgZm9yICJzeXN0ZW0gaWRlbnRpZmljYXRpb24iLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlhTTFRDX1NPVVJDRV9FUlIsCi0gICAgICAgICJcdThDMDNcdTc1MjggWFNMVENTb3VyY2UuYnVpbGQoKSBcdTY1RjZcdTY3MkFcdThCQkVcdTdGNkUgc3lzdGVtSWRcdTMwMDIifSwKLQotICAgICAgICB7IEVycm9yTXNnLkVSX1JFU1VMVF9OVUxMLAotICAgICAgICAgICAgIlJlc3VsdCBcdTRFMERcdTgwRkRcdTRFM0FcdTdBN0FcdTUwM0MifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoZSB2YWx1ZSBhcmd1bWVudAotICAgICAgICAgKiBvZiBzZXRQYXJhbWV0ZXIgbXVzdCBiZSBhIHZhbGlkIEphdmEgT2JqZWN0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfSU5WQUxJRF9TRVRfUEFSQU1fVkFMVUUsCi0gICAgICAgICJcdTUzQzJcdTY1NzAgezB9IFx1NzY4NFx1NTAzQ1x1NUZDNVx1OTg3Qlx1NjYyRlx1NjcwOVx1NjU0OCBKYXZhIFx1NUJGOVx1OEM2MSJ9LAotCi0KLSAgICAgICAge0Vycm9yTXNnLkNPTVBJTEVfU1RESU5fRVJSLAotICAgICAgICAiLWkgXHU5MDA5XHU5ODc5XHU1RkM1XHU5ODdCXHU0RTBFIC1vIFx1OTAwOVx1OTg3OVx1NEUwMFx1OEQ3N1x1NEY3Rlx1NzUyOFx1MzAwMiJ9LAotCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBjb250YWlucyB1c2FnZSBpbmZvcm1hdGlvbiBmb3IgYQotICAgICAgICAgKiBtZWFucyBvZiBpbnZva2luZyBYU0xUQyBmcm9tIHRoZSBjb21tYW5kLWxpbmUuICBUaGUgbWVzc2FnZSBpcwotICAgICAgICAgKiBmb3JtYXR0ZWQgZm9yIHByZXNlbnRhdGlvbiBpbiBFbmdsaXNoLiAgVGhlIHN0cmluZ3MgPG91dHB1dD4sCi0gICAgICAgICAqIDxkaXJlY3Rvcnk+LCBldGMuIGluZGljYXRlIHVzZXItc3BlY2lmaWVkIGFyZ3VtZW50IHZhbHVlcywgYW5kIGNhbgotICAgICAgICAgKiBiZSB0cmFuc2xhdGVkIC0gdGhlIGFyZ3VtZW50IDxwYWNrYWdlPiByZWZlcnMgdG8gYSBKYXZhIHBhY2thZ2UsIHNvCi0gICAgICAgICAqIGl0IHNob3VsZCBiZSBoYW5kbGVkIGluIHRoZSBzYW1lIHdheSB0aGUgdGVybSBpcyBoYW5kbGVkIGZvciBKREsKLSAgICAgICAgICogZG9jdW1lbnRhdGlvbi4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5DT01QSUxFX1VTQUdFX1NUUiwKLSAgICAgICAgIlx1NjNEMFx1ODk4MVxuICAgamF2YSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY21kbGluZS5Db21waWxlIFstbyA8XHU4RjkzXHU1MUZBPl1cbiAgICAgIFstZCA8XHU3NkVFXHU1RjU1Pl0gWy1qIDxqYXJmaWxlPl0gWy1wIDxcdTdBMEJcdTVFOEZcdTUzMDU+XVxuICAgICAgWy1uXSBbLXhdIFstdV0gWy12XSBbLWhdIHsgPFx1NjgzN1x1NUYwRlx1ODg2OD4gfCAtaSB9XG5cblx1OTAwOVx1OTg3OVxuICAgLW8gPFx1OEY5M1x1NTFGQT4gICAgXHU0RTNBXHU3NTFGXHU2MjEwXHU3Njg0IHRyYW5zbGV0IFx1NTIwNlx1OTE0RFxuICAgICAgICAgICAgICAgICAgXHU1NDBEXHU3OUYwIDxcdThGOTNcdTUxRkE+XHUzMDAyXHU5RUQ4XHU4QkE0XHU2MEM1XHU1MUI1XHU0RTBCLCB0cmFuc2xldCBcdTU0MERcdTc5RjBcbiAgICAgICAgICAgICAgICAgIFx1NkQzRVx1NzUxRlx1ODFFQSA8XHU2ODM3XHU1RjBGXHU4ODY4PiBcdTU0MERcdTc5RjBcdTMwMDJcdTU5ODJcdTY3OUNcdTg5ODFcdTdGMTZcdThCRDFcdTU5MUFcdTRFMkFcdTY4MzdcdTVGMEZcdTg4NjgsIFxuICAgICAgICAgICAgICAgICAgXHU1MjE5XHU1RkZEXHU3NTY1XHU2QjY0XHU5MDA5XHU5ODc5XHUzMDAyXG4gICAtZCA8XHU3NkVFXHU1RjU1PiBcdTYzMDdcdTVCOUEgdHJhbnNsZXQgXHU3Njg0XHU3NkVFXHU2ODA3XHU3NkVFXHU1RjU1XG4gICAtaiA8amFyZmlsZT4gICBcdTVDMDYgdHJhbnNsZXQgXHU3QzdCXHU2MjUzXHU1MzA1XHU1MjMwXHU1MTc3XHU2NzA5IDxqYXJmaWxlPlxuICAgICAgICAgICAgICAgICAgXHU2MzA3XHU1QjlBXHU3Njg0XHU1NDBEXHU3OUYwXHU3Njg0IGphciBcdTY1ODdcdTRFRjZcdTRFMkRcbiAgIC1wIDxcdTdBMEJcdTVFOEZcdTUzMDU+ICAgXHU0RTNBXHU3NTFGXHU2MjEwXHU3Njg0XHU2MjQwXHU2NzA5IHRyYW5zbGV0IFx1N0M3QlxuICAgICAgICAgICAgICAgICAgXHU2MzA3XHU1QjlBXHU3QTBCXHU1RThGXHU1MzA1XHU1NDBEXHU3OUYwXHU1MjREXHU3RjAwXHUzMDAyXG4gICAtbiAgICAgICAgICAgICBcdTU0MkZcdTc1MjhcdTZBMjFcdTY3N0ZcdTUxODVcdTVENEMgKFx1OUVEOFx1OEJBNFx1ODg0Q1x1NEUzQVxuICAgICAgICAgICAgICAgICAgXHU5MDFBXHU1RTM4XHU1M0VGXHU2M0QwXHU0RjlCXHU4RjgzXHU1OTdEXHU3Njg0XHU2MDI3XHU4MEZEKVx1MzAwMlxuICAgLXggICAgICAgICAgICAgXHU1NDJGXHU3NTI4XHU1MTc2XHU0RUQ2XHU4QzAzXHU4QkQ1XHU2RDg4XHU2MDZGXHU4RjkzXHU1MUZBXG4gICAtdSAgICAgICAgICAgICBcdTVDMDYgPFx1NjgzN1x1NUYwRlx1ODg2OD4gXHU1M0MyXHU2NTcwXHU4OUUzXHU5MUNBXHU0RTNBIFVSTFxuICAgLWkgICAgICAgICAgICAgXHU1RjNBXHU1MjM2XHU3RjE2XHU4QkQxXHU1NjY4XHU0RUNFIHN0ZGluIFx1OEJGQlx1NTNENlx1NjgzN1x1NUYwRlx1ODg2OFxuICAgLXYgICAgICAgICAgICAgXHU4RjkzXHU1MUZBXHU3RjE2XHU4QkQxXHU1NjY4XHU3Njg0XHU3MjQ4XHU2NzJDXG4gICAtaCAgICAgICAgICAgICBcdThGOTNcdTUxRkFcdTZCNjRcdTc1MjhcdTZDRDVcdThCRURcdTUzRTVcbiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgY29udGFpbnMgdXNhZ2UgaW5mb3JtYXRpb24gZm9yIGEKLSAgICAgICAgICogbWVhbnMgb2YgaW52b2tpbmcgWFNMVEMgZnJvbSB0aGUgY29tbWFuZC1saW5lLiAgVGhlIG1lc3NhZ2UgaXMKLSAgICAgICAgICogZm9ybWF0dGVkIGZvciBwcmVzZW50YXRpb24gaW4gRW5nbGlzaC4gIFRoZSBzdHJpbmdzIDxqYXJmaWxlPiwKLSAgICAgICAgICogPGRvY3VtZW50PiwgZXRjLiBpbmRpY2F0ZSB1c2VyLXNwZWNpZmllZCBhcmd1bWVudCB2YWx1ZXMsIGFuZCBjYW4KLSAgICAgICAgICogYmUgdHJhbnNsYXRlZCAtIHRoZSBhcmd1bWVudCA8Y2xhc3M+IHJlZmVycyB0byBhIEphdmEgY2xhc3MsIHNvIGl0Ci0gICAgICAgICAqIHNob3VsZCBiZSBoYW5kbGVkIGluIHRoZSBzYW1lIHdheSB0aGUgdGVybSBpcyBoYW5kbGVkIGZvciBKREsKLSAgICAgICAgICogZG9jdW1lbnRhdGlvbi4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5UUkFOU0ZPUk1fVVNBR0VfU1RSLAotICAgICAgICAiXHU2M0QwXHU4OTgxXG4gICBqYXZhIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jbWRsaW5lLlRyYW5zZm9ybSBbLWogPGphcmZpbGU+XVxuICAgICAgWy14XSBbLW4gPFx1OEZFRFx1NEVFM1x1NjU3MD5dIHstdSA8ZG9jdW1lbnRfdXJsPiB8IDxcdTY1ODdcdTY4NjM+fVxuICAgICAgPFx1N0M3Qj4gWzxwYXJhbTE+PTx2YWx1ZTE+IC4uLl1cblxuICAgXHU0RjdGXHU3NTI4IHRyYW5zbGV0IDxcdTdDN0I+IFx1OEY2Q1x1NjM2MlxuICAgPFx1NjU4N1x1Njg2Mz4gXHU2MzA3XHU1QjlBXHU3Njg0IFhNTCBcdTY1ODdcdTY4NjNcdTMwMDJ0cmFuc2xldCA8XHU3QzdCPiBcdTRGNERcdTRFOEVcbiAgIFx1NzUyOFx1NjIzN1x1NzY4NCBDTEFTU1BBVEggXHU2MjE2XHU5MDA5XHU2MkU5XHU2MDI3XHU2MzA3XHU1QjlBXHU3Njg0IDxqYXJmaWxlPiBcdTRFMkRcdTMwMDJcblx1OTAwOVx1OTg3OVxuICAgLWogPGphcmZpbGU+ICAgIFx1NjMwN1x1NUI5QVx1ODk4MVx1NEVDRVx1NEUyRFx1NTJBMFx1OEY3RCB0cmFuc2xldCBcdTc2ODQgamFyZmlsZVxuICAgLXggICAgICAgICAgICAgIFx1NTQyRlx1NzUyOFx1NTE3Nlx1NEVENlx1OEMwM1x1OEJENVx1NkQ4OFx1NjA2Rlx1OEY5M1x1NTFGQVxuICAgLW4gPFx1OEZFRFx1NEVFM1x1NjU3MD4gXHU4RkQwXHU4ODRDIDxcdThGRURcdTRFRTNcdTY1NzA+IFx1NkIyMVx1OEY2Q1x1NjM2Mlx1NUU3NlxuICAgICAgICAgICAgICAgICAgIFx1NjYzRVx1NzkzQVx1OTE0RFx1N0Y2RVx1NjU4N1x1NEVGNlx1NEZFMVx1NjA2RlxuICAgLXUgPGRvY3VtZW50X3VybD4gXHU0RUU1IFVSTCBcdTVGNjJcdTVGMEZcdTYzMDdcdTVCOUEgWE1MIFx1OEY5M1x1NTE2NVx1NjU4N1x1Njg2M1xuIn0sCi0KLQotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiPHhzbDpzb3J0PiIsICI8eHNsOmZvci1lYWNoPiIgYW5kCi0gICAgICAgICAqICI8eHNsOmFwcGx5LXRlbXBsYXRlcz4iIGFyZSBrZXl3b3JkcyB0aGF0IHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICAgICAgICogVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgYW4geHNsOnNvcnQgZWxlbWVudCBtdXN0IGJlIGEgY2hpbGQgb2YKLSAgICAgICAgICogb25lIG9mIHRoZSBvdGhlciBraW5kcyBvZiBlbGVtZW50cyBtZW50aW9uZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuU1RSQVlfU09SVF9FUlIsCi0gICAgICAgICI8eHNsOnNvcnQ+IFx1NTNFQVx1ODBGRFx1NTcyOCA8eHNsOmZvci1lYWNoPiBcdTYyMTYgPHhzbDphcHBseS10ZW1wbGF0ZXM+IFx1NEUyRFx1NEY3Rlx1NzUyOFx1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUgZW5jb2RpbmcKLSAgICAgICAgICogcmVxdWVzdGVkIGZvciB0aGUgb3V0cHV0IGRvY3VtZW50IHdhcyBvbiB0aGF0IHJlcXVpcmVzIHN1cHBvcnQgdGhhdAotICAgICAgICAgKiBpcyBub3QgYXZhaWxhYmxlIGZyb20gdGhlIEphdmEgVmlydHVhbCBNYWNoaW5lIGJlaW5nIHVzZWQgdG8gZXhlY3V0ZQotICAgICAgICAgKiB0aGUgcHJvZ3JhbS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5VTlNVUFBPUlRFRF9FTkNPRElORywKLSAgICAgICAgIlx1NkI2NCBKVk0gXHU0RTJEXHU0RTBEXHU2NTJGXHU2MzAxXHU4RjkzXHU1MUZBXHU3RjE2XHU3ODAxICcnezB9JydcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhlIFhQYXRoIGV4cHJlc3Npb24KLSAgICAgICAgICogbmFtZWQgaW4gdGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHdhcyBub3Qgd2VsbCBmb3JtZWQgc3ludGFjdGljYWxseS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5TWU5UQVhfRVJSLAotICAgICAgICAiJyd7MH0nJyBcdTRFMkRcdTc2ODRcdThCRURcdTZDRDVcdTk1MTlcdThCRUZcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIGEgSmF2YQotICAgICAgICAgKiBjbGFzcy4gIFRoZSB0ZXJtICJjb25zdHJ1Y3RvciIgaGVyZSBpcyB0aGUgSmF2YSB0ZXJtLiAgVGhlIG1lc3NhZ2UgaXMKLSAgICAgICAgICogZGlzcGxheWVkIGlmIFhTTFRDIGNvdWxkIG5vdCBmaW5kIGEgY29uc3RydWN0b3IgZm9yIHRoZSBzcGVjaWZpZWQKLSAgICAgICAgICogY2xhc3MuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuQ09OU1RSVUNUT1JfTk9UX0ZPVU5ELAotICAgICAgICAiXHU2MjdFXHU0RTBEXHU1MjMwXHU1OTE2XHU5MEU4XHU2Nzg0XHU5MDIwXHU1NjY4ICcnezB9JydcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgInN0YXRpYyIgaXMgdGhlIEphdmEga2V5d29yZC4gIFRoZSBzdWJzdGl0dXRpb24KLSAgICAgICAgICogdGV4dCBpcyB0aGUgbmFtZSBvZiBhIGZ1bmN0aW9uLiAgVGhlIGZpcnN0IGFyZ3VtZW50IG9mIHRoYXQgZnVuY3Rpb24KLSAgICAgICAgICogaXMgbm90IG9mIHRoZSByZXF1aXJlZCB0eXBlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk5PX0pBVkFfRlVOQ1RfVEhJU19SRUYsCi0gICAgICAgICJcdTk3NUUgc3RhdGljIEphdmEgXHU1MUZEXHU2NTcwICcnezB9JycgXHU3Njg0XHU3QjJDXHU0RTAwXHU0RTJBXHU1M0MyXHU2NTcwXHU0RTBEXHU2NjJGXHU2NzA5XHU2NTQ4XHU3Njg0XHU1QkY5XHU4QzYxXHU1RjE1XHU3NTI4XHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIFhQYXRoIGV4cHJlc3Npb24gd2FzIG5vdCBvZiB0aGUgdHlwZQotICAgICAgICAgKiByZXF1aXJlZCBpbiBhIHBhcnRpY3VsYXIgY29udGV4dC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUKLSAgICAgICAgICogZXhwcmVzc2lvbiB0aGF0IHdhcyBpbiBlcnJvci4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5UWVBFX0NIRUNLX0VSUiwKLSAgICAgICAgIlx1NjhDMFx1NjdFNVx1ODg2OFx1OEZCRVx1NUYwRiAnJ3swfScnIFx1NzY4NFx1N0M3Qlx1NTc4Qlx1NjVGNlx1NTFGQVx1OTUxOVx1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBbiBYUGF0aCBleHByZXNzaW9uIHdhcyBub3Qgb2YgdGhlIHR5cGUKLSAgICAgICAgICogcmVxdWlyZWQgaW4gYSBwYXJ0aWN1bGFyIGNvbnRleHQuICBIb3dldmVyLCB0aGUgbG9jYXRpb24gb2YgdGhlCi0gICAgICAgICAqIHByb2JsZW1hdGljIGV4cHJlc3Npb24gaXMgdW5rbm93bi4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5UWVBFX0NIRUNLX1VOS19MT0NfRVJSLAotICAgICAgICAiXHU2OEMwXHU2N0U1XHU2NzJBXHU3N0U1XHU0RjREXHU3RjZFXHU3Njg0XHU4ODY4XHU4RkJFXHU1RjBGXHU3QzdCXHU1NzhCXHU2NUY2XHU1MUZBXHU5NTE5XHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBhIGNvbW1hbmQtCi0gICAgICAgICAqIGxpbmUgb3B0aW9uIHRoYXQgd2FzIG5vdCByZWNvZ25pemVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfQ01ETElORV9PUFRJT05fRVJSLAotICAgICAgICAiXHU1NDdEXHU0RUU0XHU4ODRDXHU5MDA5XHU5ODc5ICcnezB9JycgXHU2NUUwXHU2NTQ4XHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBhIGNvbW1hbmQtCi0gICAgICAgICAqIGxpbmUgb3B0aW9uLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkNNRExJTkVfT1BUX01JU1NJTkdfQVJHX0VSUiwKLSAgICAgICAgIlx1NTQ3RFx1NEVFNFx1ODg0Q1x1OTAwOVx1OTg3OSAnJ3swfScnIFx1N0YzQVx1NUMxMVx1NjI0MFx1OTcwMFx1NTNDMlx1NjU3MFx1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgdXNlZCB0byBpbmRpY2F0ZSB0aGUgc2V2ZXJpdHkKLSAgICAgICAgICogb2YgYW5vdGhlciBtZXNzYWdlLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGNvbnRhaW5zIHR3byBlcnJvcgotICAgICAgICAgKiBtZXNzYWdlcy4gIFRoZSBzcGFjaW5nIGJlZm9yZSB0aGUgc2Vjb25kIHN1YnN0aXR1dGlvbiB0ZXh0IGluZGVudHMKLSAgICAgICAgICogaXQgdGhlIHNhbWUgYW1vdW50IGFzIHRoZSBmaXJzdCBpbiBFbmdsaXNoLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLldBUk5JTkdfUExVU19XUkFQUEVEX01TRywKLSAgICAgICAgIldBUk5JTkc6ICAnJ3swfScnXG4gICAgICAgOnsxfSJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgdXNlZCB0byBpbmRpY2F0ZSB0aGUgc2V2ZXJpdHkKLSAgICAgICAgICogb2YgYW5vdGhlciBtZXNzYWdlLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIGFuIGVycm9yIG1lc3NhZ2UuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuV0FSTklOR19NU0csCi0gICAgICAgICJXQVJOSU5HOiAgJyd7MH0nJyJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgdXNlZCB0byBpbmRpY2F0ZSB0aGUgc2V2ZXJpdHkKLSAgICAgICAgICogb2YgYW5vdGhlciBtZXNzYWdlLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGNvbnRhaW5zIHR3byBlcnJvcgotICAgICAgICAgKiBtZXNzYWdlcy4gIFRoZSBzcGFjaW5nIGJlZm9yZSB0aGUgc2Vjb25kIHN1YnN0aXR1dGlvbiB0ZXh0IGluZGVudHMKLSAgICAgICAgICogaXQgdGhlIHNhbWUgYW1vdW50IGFzIHRoZSBmaXJzdCBpbiBFbmdsaXNoLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkZBVEFMX0VSUl9QTFVTX1dSQVBQRURfTVNHLAotICAgICAgICAiRkFUQUwgRVJST1I6ICAnJ3swfScnXG4gICAgICAgICAgIDp7MX0ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIHVzZWQgdG8gaW5kaWNhdGUgdGhlIHNldmVyaXR5Ci0gICAgICAgICAqIG9mIGFub3RoZXIgbWVzc2FnZS4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyBhbiBlcnJvciBtZXNzYWdlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkZBVEFMX0VSUl9NU0csCi0gICAgICAgICJGQVRBTCBFUlJPUjogICcnezB9JycifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIHVzZWQgdG8gaW5kaWNhdGUgdGhlIHNldmVyaXR5Ci0gICAgICAgICAqIG9mIGFub3RoZXIgbWVzc2FnZS4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBjb250YWlucyB0d28gZXJyb3IKLSAgICAgICAgICogbWVzc2FnZXMuICBUaGUgc3BhY2luZyBiZWZvcmUgdGhlIHNlY29uZCBzdWJzdGl0dXRpb24gdGV4dCBpbmRlbnRzCi0gICAgICAgICAqIGl0IHRoZSBzYW1lIGFtb3VudCBhcyB0aGUgZmlyc3QgaW4gRW5nbGlzaC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5FUlJPUl9QTFVTX1dSQVBQRURfTVNHLAotICAgICAgICAiRVJST1I6ICAnJ3swfScnXG4gICAgIDp7MX0ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIHVzZWQgdG8gaW5kaWNhdGUgdGhlIHNldmVyaXR5Ci0gICAgICAgICAqIG9mIGFub3RoZXIgbWVzc2FnZS4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyBhbiBlcnJvciBtZXNzYWdlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkVSUk9SX01TRywKLSAgICAgICAgIkVSUk9SOiAgJyd7MH0nJyJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYSBjbGFzcy4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5UUkFOU0ZPUk1fV0lUSF9UUkFOU0xFVF9TVFIsCi0gICAgICAgICJcdTRGN0ZcdTc1MjggdHJhbnNsZXQgJyd7MH0nJyBcdThGREJcdTg4NENcdThGNkNcdTYzNjIgIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmaXJzdCBzdWJzdGl0dXRpb24gaXMgdGhlIG5hbWUgb2YgYSBjbGFzcywKLSAgICAgICAgICogd2hpbGUgdGhlIHNlY29uZCBzdWJzdGl0dXRpb24gaXMgdGhlIG5hbWUgb2YgYSBqYXIgZmlsZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5UUkFOU0ZPUk1fV0lUSF9KQVJfU1RSLAotICAgICAgICAiXHU0RjdGXHU3NTI4IHRyYW5zbGV0ICcnezB9JycgXHU0RUNFIGphciBcdTY1ODdcdTRFRjYgJyd7MX0nJyBcdThGREJcdTg4NENcdThGNkNcdTYzNjIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIlRyYW5zZm9ybWVyRmFjdG9yeSIgaXMgdGhlIG5hbWUgb2YgYSBKYXZhCi0gICAgICAgICAqIGludGVyZmFjZSBhbmQgbXVzdCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcwotICAgICAgICAgKiB0aGUgbmFtZSBvZiB0aGUgY2xhc3MgdGhhdCBjb3VsZCBub3QgYmUgaW5zdGFudGlhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkNPVUxEX05PVF9DUkVBVEVfVFJBTlNfRkFDVCwKLSAgICAgICAgIlx1NjVFMFx1NkNENVx1NTIxQlx1NUVGQSBUcmFuc2Zvcm1lckZhY3RvcnkgXHU3QzdCICcnezB9JycgXHU3Njg0XHU1QjlFXHU0RjhCXHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyBwcm9kdWNlZCB3aGVuIHRoZSB1c2VyCi0gICAgICAgICAqIHNwZWNpZmllZCBhIG5hbWUgZm9yIHRoZSB0cmFuc2xldCBjbGFzcyB0aGF0IGNvbnRhaW5zIGNoYXJhY3RlcnMKLSAgICAgICAgICogdGhhdCBhcmUgbm90IHBlcm1pdHRlZCBpbiBhIEphdmEgY2xhc3MgbmFtZS4gIFRoZSBzdWJzdGl0dXRpb24KLSAgICAgICAgICogdGV4dCAiezB9IiBzcGVjaWZpZXMgdGhlIG5hbWUgdGhlIHVzZXIgcmVxdWVzdGVkLCB3aGlsZSAiezF9IgotICAgICAgICAgKiBzcGVjaWZpZXMgdGhlIG5hbWUgdGhlIHByb2Nlc3NvciB1c2VkIGluc3RlYWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVFJBTlNMRVRfTkFNRV9KQVZBX0NPTkZMSUNULAotICAgICAgICAgIlx1NTQwRFx1NzlGMCAnJ3swfScnIFx1NTMwNVx1NTQyQlx1NEUwRFx1NTE0MVx1OEJCOFx1NTcyOCBKYXZhIFx1N0M3Qlx1NTQwRFx1NEUyRFx1NEY3Rlx1NzUyOFx1NzY4NFx1NUI1N1x1N0IyNiwgXHU1NkUwXHU2QjY0XHU2NUUwXHU2Q0Q1XHU1QzA2XHU2QjY0XHU1NDBEXHU3OUYwXHU3NTI4XHU0RjVDIHRyYW5zbGV0IFx1N0M3Qlx1NzY4NFx1NTQwRFx1NzlGMFx1MzAwMlx1NURGMlx1NjUzOVx1NzUyOFx1NTQwRFx1NzlGMCAnJ3sxfScnXHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBpcyB1c2VkIGFzIGEgaGVhZGVyLgotICAgICAgICAgKiBBbGwgdGhlIGVycm9yIG1lc3NhZ2VzIGFyZSBjb2xsZWN0ZWQgdG9nZXRoZXIgYW5kIGRpc3BsYXllZCBiZW5lYXRoCi0gICAgICAgICAqIHRoaXMgbWVzc2FnZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5DT01QSUxFUl9FUlJPUl9LRVksCi0gICAgICAgICJcdTdGMTZcdThCRDFcdTU2NjhcdTk1MTlcdThCRUY6In0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBpcyB1c2VkIGFzIGEgaGVhZGVyLgotICAgICAgICAgKiBBbGwgdGhlIHdhcm5pbmcgbWVzc2FnZXMgYXJlIGNvbGxlY3RlZCB0b2dldGhlciBhbmQgZGlzcGxheWVkCi0gICAgICAgICAqIGJlbmVhdGggdGhpcyBtZXNzYWdlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkNPTVBJTEVSX1dBUk5JTkdfS0VZLAotICAgICAgICAiXHU3RjE2XHU4QkQxXHU1NjY4XHU4QjY2XHU1NDRBOiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgaXMgdXNlZCBhcyBhIGhlYWRlci4KLSAgICAgICAgICogQWxsIHRoZSBlcnJvciBtZXNzYWdlcyB0aGF0IGFyZSBwcm9kdWNlZCB3aGVuIHRoZSBzdHlsZXNoZWV0IGlzCi0gICAgICAgICAqIGFwcGxpZWQgdG8gYW4gaW5wdXQgZG9jdW1lbnQgYXJlIGNvbGxlY3RlZCB0b2dldGhlciBhbmQgZGlzcGxheWVkCi0gICAgICAgICAqIGJlbmVhdGggdGhpcyBtZXNzYWdlLiAgQSAndHJhbnNsZXQnIGlzIHRoZSBjb21waWxlZCBmb3JtIG9mIGEKLSAgICAgICAgICogc3R5bGVzaGVldCAoc2VlIGFib3ZlKS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5SVU5USU1FX0VSUk9SX0tFWSwKLSAgICAgICAgIlRyYW5zbGV0IFx1OTUxOVx1OEJFRjoifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQW4gYXR0cmlidXRlIHdob3NlIHZhbHVlIGlzIGNvbnN0cmFpbmVkIHRvCi0gICAgICAgICAqIGJlIGEgIlFOYW1lIiBvciBhIGxpc3Qgb2YgIlFOYW1lcyIgaGFkIGEgdmFsdWUgdGhhdCB3YXMgaW5jb3JyZWN0LgotICAgICAgICAgKiAnUU5hbWUnIGlzIGFuIFhNTCBzeW50YWN0aWMgdGVybSB0aGF0IG11c3Qgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGUKLSAgICAgICAgICogc3Vic3RpdHV0aW9uIHRleHQgY29udGFpbnMgdGhlIGFjdHVhbCB2YWx1ZSBvZiB0aGUgYXR0cmlidXRlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklOVkFMSURfUU5BTUVfRVJSLAotICAgICAgICAiXHU1MTc2XHU1MDNDXHU1RkM1XHU5ODdCXHU0RTNBIFFOYW1lIFx1NjIxNlx1NzUzMVx1N0E3QVx1NjgzQ1x1NTIwNlx1OTY5NFx1NzY4NCBRTmFtZSBcdTUyMTdcdTg4NjhcdTc2ODRcdTVDNUVcdTYwMjdcdTUxNzdcdTY3MDlcdTUwM0MgJyd7MH0nJyJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBbiBhdHRyaWJ1dGUgd2hvc2UgdmFsdWUgaXMgcmVxdWlyZWQgdG8KLSAgICAgICAgICogYmUgYW4gIk5DTmFtZSIuCi0gICAgICAgICAqICdOQ05hbWUnIGlzIGFuIFhNTCBzeW50YWN0aWMgdGVybSB0aGF0IG11c3Qgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGUKLSAgICAgICAgICogc3Vic3RpdHV0aW9uIHRleHQgY29udGFpbnMgdGhlIGFjdHVhbCB2YWx1ZSBvZiB0aGUgYXR0cmlidXRlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklOVkFMSURfTkNOQU1FX0VSUiwKLSAgICAgICAgIlx1NTE3Nlx1NTAzQ1x1NUZDNVx1OTg3Qlx1NEUzQSBOQ05hbWUgXHU3Njg0XHU1QzVFXHU2MDI3XHU1MTc3XHU2NzA5XHU1MDNDICcnezB9JycifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQW4gYXR0cmlidXRlIHdpdGggYW4gaW5jb3JyZWN0IHZhbHVlIHdhcwotICAgICAgICAgKiBlbmNvdW50ZXJlZC4gIFRoZSBwZXJtaXR0ZWQgdmFsdWUgaXMgb25lIG9mIHRoZSBsaXRlcmFsIHZhbHVlcwotICAgICAgICAgKiAieG1sIiwgImh0bWwiIG9yICJ0ZXh0IjsgaXQgaXMgYWxzbyBwZXJtaXR0ZWQgdG8gaGF2ZSB0aGUgZm9ybSBvZgotICAgICAgICAgKiBhIFFOYW1lIHRoYXQgaXMgbm90IGFsc28gYW4gTkNOYW1lLiAgVGhlIHRlcm1zICJtZXRob2QiLAotICAgICAgICAgKiAieHNsOm91dHB1dCIsICJ4bWwiLCAiaHRtbCIgYW5kICJ0ZXh0IiBhcmUga2V5d29yZHMgdGhhdCBtdXN0IG5vdAotICAgICAgICAgKiBiZSB0cmFuc2xhdGVkLiAgVGhlIHRlcm0gInFuYW1lLWJ1dC1ub3QtbmNuYW1lIiBpcyBhbiBYTUwgc3ludGFjdGljCi0gICAgICAgICAqIHRlcm0uICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgY29udGFpbnMgdGhlIGFjdHVhbCB2YWx1ZSBvZiB0aGUKLSAgICAgICAgICogYXR0cmlidXRlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklOVkFMSURfTUVUSE9EX0lOX09VVFBVVCwKLSAgICAgICAgIjx4c2w6b3V0cHV0PiBcdTUxNDNcdTdEMjBcdTc2ODQgbWV0aG9kIFx1NUM1RVx1NjAyN1x1NTE3N1x1NjcwOVx1NTAzQyAnJ3swfScnXHUzMDAyXHU4QkU1XHU1MDNDXHU1RkM1XHU5ODdCXHU2NjJGICcneG1sJycsICcnaHRtbCcnLCAnJ3RleHQnJyBcdTYyMTYgcW5hbWUtYnV0LW5vdC1uY25hbWUgXHU0RTRCXHU0RTAwIn0sCi0KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfR0VUX0ZFQVRVUkVfTlVMTF9OQU1FLAotICAgICAgICAiVHJhbnNmb3JtZXJGYWN0b3J5LmdldEZlYXR1cmUoU3RyaW5nIG5hbWUpIFx1NEUyRFx1NzY4NFx1NTI5Rlx1ODBGRFx1NTQwRFx1NzlGMFx1NEUwRFx1ODBGRFx1NEUzQVx1N0E3QVx1NTAzQ1x1MzAwMiJ9LAotCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX1NFVF9GRUFUVVJFX05VTExfTkFNRSwKLSAgICAgICAgIlRyYW5zZm9ybWVyRmFjdG9yeS5zZXRGZWF0dXJlKFN0cmluZyBuYW1lLCBib29sZWFuIHZhbHVlKSBcdTRFMkRcdTc2ODRcdTUyOUZcdTgwRkRcdTU0MERcdTc5RjBcdTRFMERcdTgwRkRcdTRFM0FcdTdBN0FcdTUwM0NcdTMwMDIifSwKLQotICAgICAgICB7RXJyb3JNc2cuSkFYUF9VTlNVUFBPUlRFRF9GRUFUVVJFLAotICAgICAgICAiXHU2NUUwXHU2Q0Q1XHU1QkY5XHU2QjY0IFRyYW5zZm9ybWVyRmFjdG9yeSBcdThCQkVcdTdGNkVcdTUyOUZcdTgwRkQgJyd7MH0nJ1x1MzAwMiJ9LAotCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX1NFQ1VSRVBST0NFU1NJTkdfRkVBVFVSRSwKLSAgICAgICAgIkZFQVRVUkVfU0VDVVJFX1BST0NFU1NJTkc6IFx1NUI1OFx1NTcyOCBTZWN1cml0eSBNYW5hZ2VyIFx1NjVGNiwgXHU2NUUwXHU2Q0Q1XHU1QzA2XHU2QjY0XHU1MjlGXHU4MEZEXHU4QkJFXHU3RjZFXHU0RTNBXHUyMDFDXHU1MDQ3XHUyMDFEXHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBkZXNjcmliZXMgYW4gaW50ZXJuYWwgZXJyb3IgaW4gdGhlCi0gICAgICAgICAqIHByb2Nlc3Nvci4gIFRoZSB0ZXJtICJieXRlIGNvZGUiIGlzIGEgSmF2YSB0ZWNobmljYWwgdGVybSBmb3IgdGhlCi0gICAgICAgICAqIGV4ZWN1dGFibGUgY29kZSBpbiBhIEphdmEgbWV0aG9kLCBhbmQgInRyeS1jYXRjaC1maW5hbGx5IGJsb2NrIgotICAgICAgICAgKiByZWZlcnMgdG8gdGhlIEphdmEga2V5d29yZHMgd2l0aCB0aG9zZSBuYW1lcy4gICJPdXRsaW5lZCIgaXMgYQotICAgICAgICAgKiB0ZWNobmljYWwgdGVybSBpbnRlcm5hbCB0byBYU0xUQyBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk9VVExJTkVfRVJSX1RSWV9DQVRDSCwKLSAgICAgICAgICJcdTUxODVcdTkwRTggWFNMVEMgXHU5NTE5XHU4QkVGOiBcdTc1MUZcdTYyMTBcdTc2ODRcdTVCNTdcdTgyODJcdTRFRTNcdTc4MDFcdTUzMDVcdTU0MkIgdHJ5LWNhdGNoLWZpbmFsbHkgXHU1NzU3LCBcdTY1RTBcdTZDRDVcdThGREJcdTg4NEMgT3V0bGluZWRcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGRlc2NyaWJlcyBhbiBpbnRlcm5hbCBlcnJvciBpbiB0aGUKLSAgICAgICAgICogcHJvY2Vzc29yLiAgVGhlIHRlcm1zICJPdXRsaW5lYWJsZUNodW5rU3RhcnQiIGFuZAotICAgICAgICAgKiAiT3V0bGluZWFibGVDaHVua0VuZCIgYXJlIHRoZSBuYW1lcyBvZiBjbGFzc2VzIGludGVybmFsIHRvIFhTTFRDIGFuZAotICAgICAgICAgKiBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCBmb3IgZXZlcnkKLSAgICAgICAgICogInN0YXJ0IiB0aGVyZSBtdXN0IGJlIGEgY29ycmVzcG9uZGluZyAiZW5kIiwgYW5kIHZpY2UgdmVyc2EsIGFuZAotICAgICAgICAgKiB0aGF0IGlmIG9uZSBvZiBhIHBhaXIgb2YgInN0YXJ0IiBhbmQgImVuZCIgYXBwZWFycyBiZXR3ZWVuIGFub3RoZXIKLSAgICAgICAgICogcGFpciBvZiBjb3JyZXNwb25kaW5nICJzdGFydCIgYW5kICJlbmQiLCB0aGVuIHRoZSBvdGhlciBoYWxmIG9mIHRoZQotICAgICAgICAgKiBwYWlyIG11c3QgYWxzbyBiZSBiZXR3ZWVuIHRoYXQgc2FtZSBlbmNsb3NpbmcgcGFpci4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5PVVRMSU5FX0VSUl9VTkJBTEFOQ0VEX01BUktFUlMsCi0gICAgICAgICAiXHU1MTg1XHU5MEU4IFhTTFRDIFx1OTUxOVx1OEJFRjogT3V0bGluZWFibGVDaHVua1N0YXJ0IFx1NTQ4QyBPdXRsaW5lYWJsZUNodW5rRW5kIFx1NjgwN1x1OEJCMFx1NUZDNVx1OTg3Qlx1OTE0RFx1NUJGOVx1NUU3Nlx1NEUxNFx1NkI2M1x1Nzg2RVx1NUQ0Q1x1NTk1N1x1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgZGVzY3JpYmVzIGFuIGludGVybmFsIGVycm9yIGluIHRoZQotICAgICAgICAgKiBwcm9jZXNzb3IuICBUaGUgdGVybSAiYnl0ZSBjb2RlIiBpcyBhIEphdmEgdGVjaG5pY2FsIHRlcm0gZm9yIHRoZQotICAgICAgICAgKiBleGVjdXRhYmxlIGNvZGUgaW4gYSBKYXZhIG1ldGhvZC4gIFRoZSAibWV0aG9kIiB0aGF0IGlzIGJlaW5nCi0gICAgICAgICAqIHJlZmVycmVkIHRvIGlzIGEgSmF2YSBtZXRob2QgaW4gYSB0cmFuc2xldCB0aGF0IFhTTFRDIGlzIGdlbmVyYXRpbmcKLSAgICAgICAgICogaW4gcHJvY2Vzc2luZyBhIHN0eWxlc2hlZXQuICBUaGUgImluc3RydWN0aW9uIiB0aGF0IGlzIGJlaW5nCi0gICAgICAgICAqIHJlZmVycmVkIHRvIGlzIG9uZSBvZiB0aGUgaW5zdHJ1dGlvbnMgaW4gdGhlIEphdmEgYnl0ZSBjb2RlIGluIHRoYXQKLSAgICAgICAgICogbWV0aG9kLiAgIk91dGxpbmVkIiBpcyBhIHRlY2huaWNhbCB0ZXJtIGludGVybmFsIHRvIFhTTFRDIGFuZAotICAgICAgICAgKiBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuT1VUTElORV9FUlJfREVMRVRFRF9UQVJHRVQsCi0gICAgICAgICAiXHU1MTg1XHU5MEU4IFhTTFRDIFx1OTUxOVx1OEJFRjogXHU1QzVFXHU0RThFXHU1REYyXHU4RkRCXHU4ODRDIE91dGxpbmVkIFx1NzY4NFx1NUI1N1x1ODI4Mlx1NEVFM1x1NzgwMVx1NTc1N1x1NzY4NFx1NjMwN1x1NEVFNFx1NTcyOFx1NTM5Rlx1NTlDQlx1NjVCOVx1NkNENVx1NEUyRFx1NEVDRFx1ODhBQlx1NUYxNVx1NzUyOFx1MzAwMiIKLSAgICAgICAgfSwKLQotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgZGVzY3JpYmVzIGFuIGludGVybmFsIGVycm9yIGluIHRoZQotICAgICAgICAgKiBwcm9jZXNzb3IuICBUaGUgIm1ldGhvZCIgdGhhdCBpcyBiZWluZyByZWZlcnJlZCB0byBpcyBhIEphdmEgbWV0aG9kCi0gICAgICAgICAqIGluIGEgdHJhbnNsZXQgdGhhdCBYU0xUQyBpcyBnZW5lcmF0aW5nLgotICAgICAgICAgKgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk9VVExJTkVfRVJSX01FVEhPRF9UT09fQklHLAotICAgICAgICAgIlx1NTE4NVx1OTBFOCBYU0xUQyBcdTk1MTlcdThCRUY6IHRyYW5zbGV0IFx1NEUyRFx1NzY4NFx1NjVCOVx1NkNENVx1OEQ4NVx1OEZDN1x1NEU4NiBKYXZhIFx1ODY1QVx1NjJERlx1NjczQVx1NzY4NFx1NjVCOVx1NkNENVx1OTU3Rlx1NUVBNlx1OTY1MFx1NTIzNiA2NCBLQlx1MzAwMlx1OEZEOVx1OTAxQVx1NUUzOFx1NjYyRlx1NzUzMVx1NEU4RVx1NjgzN1x1NUYwRlx1ODg2OFx1NEUyRFx1NzY4NFx1NkEyMVx1Njc3Rlx1OTc1RVx1NUUzOFx1NTkyN1x1OTAyMFx1NjIxMFx1NzY4NFx1MzAwMlx1OEJGN1x1NUMxRFx1OEJENVx1NEY3Rlx1NzUyOFx1OEY4M1x1NUMwRlx1NzY4NFx1NkEyMVx1Njc3Rlx1OTFDRFx1NjVCMFx1Njc4NFx1NUVGQVx1NjgzN1x1NUYwRlx1ODg2OFx1MzAwMiIKLSAgICAgICAgfSwKLQotICAgICAgICAge0Vycm9yTXNnLkRFU0VSSUFMSVpFX1RSQU5TTEVUX0VSUiwgIlx1NTQyRlx1NzUyOFx1NEU4NiBKYXZhIFx1NUI4OVx1NTE2OFx1NjVGNiwgXHU1QzA2XHU3OTgxXHU3NTI4XHU1QkY5XHU1M0NEXHU1RThGXHU1MjE3XHU1MzE2IFRlbXBsYXRlc0ltcGwgXHU3Njg0XHU2NTJGXHU2MzAxXHUzMDAyXHU1M0VGXHU0RUU1XHU5MDFBXHU4RkM3XHU1QzA2IGpkay54bWwuZW5hYmxlVGVtcGxhdGVzSW1wbERlc2VyaWFsaXphdGlvbiBcdTdDRkJcdTdFREZcdTVDNUVcdTYwMjdcdThCQkVcdTdGNkVcdTRFM0FcdTIwMUNcdTc3MUZcdTIwMURcdTY3NjVcdTg5ODZcdTc2RDZcdTZCNjRcdThCQkVcdTdGNkVcdTMwMDIifQotCi0gICAgfTsKLQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvdXRpbC9FcnJvck1lc3NhZ2VzX3poX1RXLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL3V0aWwvRXJyb3JNZXNzYWdlc196aF9UVy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3Y2FlNjdhLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvdXRpbC9FcnJvck1lc3NhZ2VzX3poX1RXLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5NzQgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsOwotCi1pbXBvcnQgamF2YS51dGlsLkxpc3RSZXNvdXJjZUJ1bmRsZTsKLQotLyoqCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqLwotcHVibGljIGNsYXNzIEVycm9yTWVzc2FnZXNfemhfVFcgZXh0ZW5kcyBMaXN0UmVzb3VyY2VCdW5kbGUgewotCi0vKgotICogWFNMVEMgY29tcGlsZS10aW1lIGVycm9yIG1lc3NhZ2VzLgotICoKLSAqIEdlbmVyYWwgbm90ZXMgdG8gdHJhbnNsYXRvcnMgYW5kIGRlZmluaXRpb25zOgotICoKLSAqICAgMSkgWFNMVEMgaXMgdGhlIG5hbWUgb2YgdGhlIHByb2R1Y3QuICBJdCBpcyBhbiBhY3JvbnltIGZvciAiWFNMVCBDb21waWxlciIuCi0gKiAgICAgIFhTTFQgaXMgYW4gYWNyb255bSBmb3IgIlhNTCBTdHlsZXNoZWV0IExhbmd1YWdlOiBUcmFuc2Zvcm1hdGlvbnMiLgotICoKLSAqICAgMikgQSBzdHlsZXNoZWV0IGlzIGEgZGVzY3JpcHRpb24gb2YgaG93IHRvIHRyYW5zZm9ybSBhbiBpbnB1dCBYTUwgZG9jdW1lbnQKLSAqICAgICAgaW50byBhIHJlc3VsdGFudCBYTUwgZG9jdW1lbnQgKG9yIEhUTUwgZG9jdW1lbnQgb3IgdGV4dCkuICBUaGUKLSAqICAgICAgc3R5bGVzaGVldCBpdHNlbGYgaXMgZGVzY3JpYmVkIGluIHRoZSBmb3JtIG9mIGFuIFhNTCBkb2N1bWVudC4KLSAqCi0gKiAgIDMpIEEgdGVtcGxhdGUgaXMgYSBjb21wb25lbnQgb2YgYSBzdHlsZXNoZWV0IHRoYXQgaXMgdXNlZCB0byBtYXRjaCBhCi0gKiAgICAgIHBhcnRpY3VsYXIgcG9ydGlvbiBvZiBhbiBpbnB1dCBkb2N1bWVudCBhbmQgc3BlY2lmaWVzIHRoZSBmb3JtIG9mIHRoZQotICogICAgICBjb3JyZXNwb25kaW5nIHBvcnRpb24gb2YgdGhlIG91dHB1dCBkb2N1bWVudC4KLSAqCi0gKiAgIDQpIEFuIGF4aXMgaXMgYSBwYXJ0aWN1bGFyICJkaW1lbnNpb24iIGluIGEgdHJlZSByZXByZXNlbnRhdGlvbiBvZiBhbiBYTUwKLSAqICAgICAgZG9jdW1lbnQ7IHRoZSBub2RlcyBpbiB0aGUgdHJlZSBhcmUgZGl2aWRlZCBhbG9uZyBkaWZmZXJlbnQgYXhlcy4KLSAqICAgICAgVHJhdmVyc2luZyB0aGUgImNoaWxkIiBheGlzLCBmb3IgaW5zdGFuY2UsIG1lYW5zIHRoYXQgdGhlIHByb2dyYW0KLSAqICAgICAgd291bGQgdmlzaXQgZWFjaCBjaGlsZCBvZiBhIHBhcnRpY3VsYXIgbm9kZTsgdHJhdmVyc2luZyB0aGUgImRlc2NlbmRhbnQiCi0gKiAgICAgIGF4aXMgbWVhbnMgdGhhdCB0aGUgcHJvZ3JhbSB3b3VsZCB2aXNpdCB0aGUgY2hpbGQgbm9kZXMgb2YgYSBwYXJ0aWN1bGFyCi0gKiAgICAgIG5vZGUsIHRoZWlyIGNoaWxkcmVuLCBhbmQgc28gb24gdW50aWwgdGhlIGxlYWYgbm9kZXMgb2YgdGhlIHRyZWUgYXJlCi0gKiAgICAgIHJlYWNoZWQuCi0gKgotICogICA1KSBBbiBpdGVyYXRvciBpcyBhbiBvYmplY3QgdGhhdCB0cmF2ZXJzZXMgbm9kZXMgaW4gYSB0cmVlIGFsb25nIGEKLSAqICAgICAgcGFydGljdWxhciBheGlzLCBvbmUgYXQgYSB0aW1lLgotICoKLSAqICAgNikgQW4gZWxlbWVudCBpcyBhIG1hcmstdXAgdGFnIGluIGFuIFhNTCBkb2N1bWVudDsgYW4gYXR0cmlidXRlIGlzIGEKLSAqICAgICAgbW9kaWZpZXIgb24gdGhlIHRhZy4gIEZvciBleGFtcGxlLCBpbiA8ZWxlbSBhdHRyPSd2YWwnIGF0dHIyPSd2YWwyJz4KLSAqICAgICAgImVsZW0iIGlzIGFuIGVsZW1lbnQgbmFtZSwgImF0dHIiIGFuZCAiYXR0cjIiIGFyZSBhdHRyaWJ1dGUgbmFtZXMgd2l0aAotICogICAgICB0aGUgdmFsdWVzICJ2YWwiIGFuZCAidmFsMiIsIHJlc3BlY3RpdmVseS4KLSAqCi0gKiAgIDcpIEEgbmFtZXNwYWNlIGRlY2xhcmF0aW9uIGlzIGEgc3BlY2lhbCBhdHRyaWJ1dGUgdGhhdCBpcyB1c2VkIHRvIGFzc29jaWF0ZQotICogICAgICBhIHByZWZpeCB3aXRoIGEgVVJJICh0aGUgbmFtZXNwYWNlKS4gIFRoZSBtZWFuaW5ncyBvZiBlbGVtZW50IG5hbWVzIGFuZAotICogICAgICBhdHRyaWJ1dGUgbmFtZXMgdGhhdCB1c2UgdGhhdCBwcmVmaXggYXJlIGRlZmluZWQgd2l0aCByZXNwZWN0IHRvIHRoYXQKLSAqICAgICAgbmFtZXNwYWNlLgotICoKLSAqICAgOCkgRE9NIGlzIGFuIGFjcm9ueW0gZm9yIERvY3VtZW50IE9iamVjdCBNb2RlbC4gIEl0IGlzIGEgdHJlZQotICogICAgICByZXByZXNlbnRhdGlvbiBvZiBhbiBYTUwgZG9jdW1lbnQuCi0gKgotICogICAgICBTQVggaXMgYW4gYWNyb255bSBmb3IgdGhlIFNpbXBsZSBBUEkgZm9yIFhNTCBwcm9jZXNzaW5nLiAgSXQgaXMgYW4gQVBJCi0gKiAgICAgIHVzZWQgaW5mb3JtIGFuIFhNTCBwcm9jZXNzb3IgKGluIHRoaXMgY2FzZSBYU0xUQykgb2YgdGhlIHN0cnVjdHVyZSBhbmQKLSAqICAgICAgY29udGVudCBvZiBhbiBYTUwgZG9jdW1lbnQuCi0gKgotICogICAgICBJbnB1dCB0byB0aGUgc3R5bGVzaGVldCBwcm9jZXNzb3IgY2FuIGNvbWUgZnJvbSBhbiBYTUwgcGFyc2VyIGluIHRoZQotICogICAgICBmb3JtIG9mIGEgRE9NIHRyZWUgb3IgdGhyb3VnaCB0aGUgU0FYIEFQSS4KLSAqCi0gKiAgIDkpIERURCBpcyBhIGRvY3VtZW50IHR5cGUgZGVjbGFyYXRpb24uICBJdCBpcyBhIHdheSBvZiBzcGVjaWZ5aW5nIHRoZQotICogICAgICBncmFtbWFyIGZvciBhbiBYTUwgZmlsZSwgdGhlIG5hbWVzIGFuZCB0eXBlcyBvZiBlbGVtZW50cywgYXR0cmlidXRlcywKLSAqICAgICAgZXRjLgotICoKLSAqICAxMCkgWFBhdGggaXMgYSBzcGVjaWZpY2F0aW9uIHRoYXQgZGVzY3JpYmVzIGEgbm90YXRpb24gZm9yIGlkZW50aWZ5aW5nCi0gKiAgICAgIG5vZGVzIGluIGEgdHJlZS1zdHJ1Y3R1cmVkIHJlcHJlc2VudGF0aW9uIG9mIGFuIFhNTCBkb2N1bWVudC4gIEFuCi0gKiAgICAgIGluc3RhbmNlIG9mIHRoYXQgbm90YXRpb24gaXMgcmVmZXJyZWQgdG8gYXMgYW4gWFBhdGggZXhwcmVzc2lvbi4KLSAqCi0gKiAgMTEpIFRyYW5zbGV0IGlzIGFuIGludmVudGVkIHRlcm0gdGhhdCByZWZlcnMgdG8gdGhlIGNsYXNzIGZpbGUgdGhhdCBjb250YWlucwotICogICAgICB0aGUgY29tcGlsZWQgZm9ybSBvZiBhIHN0eWxlc2hlZXQuCi0gKi8KLQotICAgIC8vIFRoZXNlIG1lc3NhZ2Ugc2hvdWxkIGJlIHJlYWQgZnJvbSBhIGxvY2FsZS1zcGVjaWZpYyByZXNvdXJjZSBidW5kbGUKLSAgICAvKiogR2V0IHRoZSBsb29rdXAgdGFibGUgZm9yIGVycm9yIG1lc3NhZ2VzLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgbWVzc2FnZSBsb29rdXAgdGFibGUuCi0gICAgICovCi0gICAgcHVibGljIE9iamVjdFtdW10gZ2V0Q29udGVudHMoKQotICAgIHsKLSAgICAgIHJldHVybiBuZXcgT2JqZWN0W11bXSB7Ci0gICAgICAgIHtFcnJvck1zZy5NVUxUSVBMRV9TVFlMRVNIRUVUX0VSUiwKLSAgICAgICAgIlx1NzZGOFx1NTQwQ1x1NkE5NFx1Njg0OFx1NEUyRFx1NUI5QVx1N0ZBOVx1NEU4Nlx1OEQ4NVx1OTA0RVx1NEUwMFx1NTAwQlx1NkEyM1x1NUYwRlx1ODg2OFx1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYQotICAgICAgICAgKiB0ZW1wbGF0ZS4gIFRoZSBzYW1lIG5hbWUgd2FzIHVzZWQgb24gdHdvIGRpZmZlcmVudCB0ZW1wbGF0ZXMgaW4gdGhlCi0gICAgICAgICAqIHNhbWUgc3R5bGVzaGVldC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5URU1QTEFURV9SRURFRl9FUlIsCi0gICAgICAgICJcdTZBMjNcdTY3N0YgJyd7MH0nJyBcdTVERjJcdTdEOTNcdTVCOUFcdTdGQTlcdTU3MjhcdTZCNjRcdTZBMjNcdTVGMEZcdTg4NjhcdTRFMkRcdTMwMDIifSwKLQotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYQotICAgICAgICAgKiB0ZW1wbGF0ZS4gIEEgcmVmZXJlbmNlIHRvIHRoZSB0ZW1wbGF0ZSBuYW1lIHdhcyBlbmNvdW50ZXJlZCwgYnV0IHRoZQotICAgICAgICAgKiB0ZW1wbGF0ZSBpcyB1bmRlZmluZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVEVNUExBVEVfVU5ERUZfRVJSLAotICAgICAgICAiXHU2QTIzXHU2NzdGICcnezB9JycgXHU2NzJBXHU1QjlBXHU3RkE5XHU1NzI4XHU2QjY0XHU2QTIzXHU1RjBGXHU4ODY4XHU0RTJEXHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBhIHZhcmlhYmxlCi0gICAgICAgICAqIHRoYXQgd2FzIGRlZmluZWQgbW9yZSB0aGFuIG9uY2UuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVkFSSUFCTEVfUkVERUZfRVJSLAotICAgICAgICAiXHU4QjhBXHU2NTc4ICcnezB9JycgXHU1NzI4XHU3NkY4XHU1NDBDXHU3QkM0XHU1NzBEXHU0RTJEXHU1QjlBXHU3RkE5XHU1OTFBXHU2QjIxXHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBhIHZhcmlhYmxlCi0gICAgICAgICAqIG9yIHBhcmFtZXRlci4gIEEgcmVmZXJlbmNlIHRvIHRoZSB2YXJpYWJsZSBvciBwYXJhbWV0ZXIgd2FzIGZvdW5kLAotICAgICAgICAgKiBidXQgaXQgd2FzIG5ldmVyIGRlZmluZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVkFSSUFCTEVfVU5ERUZfRVJSLAotICAgICAgICAiXHU4QjhBXHU2NTc4XHU2MjE2XHU1M0MzXHU2NTc4ICcnezB9JycgXHU2NzJBXHU1QjlBXHU3RkE5XHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSB3b3JkICJjbGFzcyIgaGVyZSByZWZlcnMgdG8gYSBKYXZhIGNsYXNzLgotICAgICAgICAgKiBQcm9jZXNzaW5nIHRoZSBzdHlsZXNoZWV0IHJlcXVpcmVkIGEgY2xhc3MgdG8gYmUgbG9hZGVkLCBidXQgaXQgY291bGQKLSAgICAgICAgICogbm90IGJlIGZvdW5kLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIHRoZSBjbGFzcy4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5DTEFTU19OT1RfRk9VTkRfRVJSLAotICAgICAgICAiXHU2MjdFXHU0RTBEXHU1MjMwXHU5ODVFXHU1MjI1ICcnezB9JydcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHdvcmQgIm1ldGhvZCIgaGVyZSByZWZlcnMgdG8gYSBKYXZhIG1ldGhvZC4KLSAgICAgICAgICogUHJvY2Vzc2luZyB0aGUgc3R5bGVzaGVldCByZXF1aXJlZCBhIHJlZmVyZW5jZSB0byB0aGUgbWV0aG9kIG5hbWVkIGJ5Ci0gICAgICAgICAqIHRoZSBzdWJzdGl0dXRpb24gdGV4dCwgYnV0IGl0IGNvdWxkIG5vdCBiZSBmb3VuZC4gICJwdWJsaWMiIGlzIHRoZQotICAgICAgICAgKiBKYXZhIGtleXdvcmQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTUVUSE9EX05PVF9GT1VORF9FUlIsCi0gICAgICAgICJcdTYyN0VcdTRFMERcdTUyMzBcdTU5MTZcdTkwRThcdTY1QjlcdTZDRDUgJyd7MH0nJyAoXHU1RkM1XHU5ODA4XHU3MEJBXHU1MTZDXHU3NTI4KVx1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgd29yZCAibWV0aG9kIiBoZXJlIHJlZmVycyB0byBhIEphdmEgbWV0aG9kLgotICAgICAgICAgKiBQcm9jZXNzaW5nIHRoZSBzdHlsZXNoZWV0IHJlcXVpcmVkIGEgcmVmZXJlbmNlIHRvIHRoZSBtZXRob2QgbmFtZWQgYnkKLSAgICAgICAgICogdGhlIHN1YnN0aXR1dGlvbiB0ZXh0LCBidXQgbm8gbWV0aG9kIHdpdGggdGhlIHJlcXVpcmVkIHR5cGVzIG9mCi0gICAgICAgICAqIGFyZ3VtZW50cyBvciByZXR1cm4gdHlwZSBjb3VsZCBiZSBmb3VuZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5BUkdVTUVOVF9DT05WRVJTSU9OX0VSUiwKLSAgICAgICAgIlx1NzEyMVx1NkNENVx1OEY0OVx1NjNEQlx1NTQ3Q1x1NTNFQlx1NjVCOVx1NkNENSAnJ3swfScnIFx1NEUyRFx1NzY4NFx1NUYxNVx1NjU3OC9cdTUwQjNcdTU2REVcdTk4NUVcdTU3OEIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZpbGUgb3IgVVJJIG5hbWVkIGluIHRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICAgKiBpcyBtaXNzaW5nLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkZJTEVfTk9UX0ZPVU5EX0VSUiwKLSAgICAgICAgIlx1NjI3RVx1NEUwRFx1NTIzMFx1NkE5NFx1Njg0OFx1NjIxNiBVUkkgJyd7MH0nJ1x1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgZGlzcGxheWVkIHdoZW4gdGhlIFVSSQotICAgICAgICAgKiBtZW50aW9uZWQgaW4gdGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIG5vdCB3ZWxsLWZvcm1lZCBzeW50YWN0aWNhbGx5LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklOVkFMSURfVVJJX0VSUiwKLSAgICAgICAgIlx1NzEyMVx1NjU0OFx1NzY4NCBVUkkgJyd7MH0nJ1x1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZmlsZSBvciBVUkkgbmFtZWQgaW4gdGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgICAqIGV4aXN0cyBidXQgY291bGQgbm90IGJlIG9wZW5lZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5GSUxFX0FDQ0VTU19FUlIsCi0gICAgICAgICJcdTcxMjFcdTZDRDVcdTk1OEJcdTU1NUZcdTZBOTRcdTY4NDhcdTYyMTYgVVJJICcnezB9JydcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiA8eHNsOnN0eWxlc2hlZXQ+IGFuZCA8eHNsOnRyYW5zZm9ybT4gYXJlCi0gICAgICAgICAqIGtleXdvcmRzIHRoYXQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk1JU1NJTkdfUk9PVF9FUlIsCi0gICAgICAgICJcdTk4MTBcdTY3MUYgPHhzbDpzdHlsZXNoZWV0PiBcdTYyMTYgPHhzbDp0cmFuc2Zvcm0+IFx1NTE0M1x1N0QyMFx1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3R5bGVzaGVldCBjb250YWluZWQgYSByZWZlcmVuY2UgdG8gYQotICAgICAgICAgKiBuYW1lc3BhY2UgcHJlZml4IHRoYXQgd2FzIHVuZGVmaW5lZC4gIFRoZSB2YWx1ZSBvZiB0aGUgc3Vic3RpdHV0aW9uCi0gICAgICAgICAqIHRleHQgaXMgdGhlIG5hbWUgb2YgdGhlIHByZWZpeC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5OQU1FU1BBQ0VfVU5ERUZfRVJSLAotICAgICAgICAiXHU2NzJBXHU1QkEzXHU1NDRBXHU1NDdEXHU1NDBEXHU3QTdBXHU5NTkzXHU1MjREXHU3RjZFXHU3OEJDICcnezB9JydcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIEphdmEgZnVuY3Rpb24gbmFtZWQgaW4gdGhlIHN0eWxlc2hlZXQgY291bGQKLSAgICAgICAgICogbm90IGJlIGZvdW5kLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkZVTkNUSU9OX1JFU09MVkVfRVJSLAotICAgICAgICAiXHU3MTIxXHU2Q0Q1XHU4OUUzXHU2NzkwXHU1MUZEXHU2NTc4ICcnezB9JycgXHU3Njg0XHU1NDdDXHU1M0VCXHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBhCi0gICAgICAgICAqIGZ1bmN0aW9uLiAgQSBsaXRlcmFsIHN0cmluZyBoZXJlIG1lYW5zIGEgY29uc3RhbnQgc3RyaW5nIHZhbHVlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk5FRURfTElURVJBTF9FUlIsCi0gICAgICAgICInJ3swfScnIFx1NzY4NFx1NUYxNVx1NjU3OFx1NUZDNVx1OTgwOFx1NjYyRlx1NjU4N1x1NUI1N1x1NUI1N1x1NEUzMlx1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaW5kaWNhdGVzIHRoZXJlIHdhcyBhIHN5bnRhY3RpYwotICAgICAgICAgKiBlcnJvciBpbiB0aGUgZm9ybSBvZiBhbiBYUGF0aCBleHByZXNzaW9uLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzCi0gICAgICAgICAqIHRoZSBleHByZXNzaW9uLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlhQQVRIX1BBUlNFUl9FUlIsCi0gICAgICAgICJcdTUyNTZcdTY3OTAgWFBhdGggXHU4ODY4XHU3OTNBXHU1RjBGICcnezB9JycgXHU2NjQyXHU3NjdDXHU3NTFGXHU5MzJGXHU4QUE0XHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIGVsZW1lbnQgaW4gdGhlIHN0eWxlc2hlZXQgcmVxdWlyZXMgYQotICAgICAgICAgKiBwYXJ0aWN1bGFyIGF0dHJpYnV0ZSBuYW1lZCBieSB0aGUgc3Vic3RpdHV0aW9uIHRleHQsIGJ1dCB0aGF0Ci0gICAgICAgICAqIGF0dHJpYnV0ZSB3YXMgbm90IHNwZWNpZmllZCBpbiB0aGUgc3R5bGVzaGVldC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5SRVFVSVJFRF9BVFRSX0VSUiwKLSAgICAgICAgIlx1OTA3QVx1NkYwRlx1NUZDNVx1ODk4MVx1NzY4NFx1NUM2Q1x1NjAyNyAnJ3swfScnXHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCBhIGNoYXJhY3RlciBub3QKLSAgICAgICAgICogcGVybWl0dGVkIGluIGFuIFhQYXRoIGV4cHJlc3Npb24gd2FzIGVuY291bnRlcmVkLiAgVGhlIHN1YnN0aXR1dGlvbgotICAgICAgICAgKiB0ZXh0IGlzIHRoZSBvZmZlbmRpbmcgY2hhcmFjdGVyLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfQ0hBUl9FUlIsCi0gICAgICAgICJYUGF0aCBcdTg4NjhcdTc5M0FcdTVGMEZcdTRFMkRcdTcxMjFcdTY1NDhcdTc2ODRcdTVCNTdcdTUxNDMgJyd7MH0nJ1x1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gaXMgYSBtYXJrLXVwIGl0ZW0gaW4KLSAgICAgICAgICogYW4gWE1MIGRvY3VtZW50IHRoYXQgcmVxdWVzdCBzb21lIGJlaGF2aW91ciBvZiBhbiBYTUwgcHJvY2Vzc29yLiAgVGhlCi0gICAgICAgICAqIGZvcm0gb2YgdGhlIG5hbWUgb2Ygd2FzIGludmFsaWQgaW4gdGhpcyBjYXNlLCBhbmQgdGhlIHN1YnN0aXR1dGlvbgotICAgICAgICAgKiB0ZXh0IGlzIHRoZSBuYW1lLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfUElfRVJSLAotICAgICAgICAiXHU4NjU1XHU3NDA2XHU2MzA3XHU3OTNBXHU3Njg0XHU3MTIxXHU2NTQ4XHU1NDBEXHU3QTMxICcnezB9JydcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIHJlcG9ydGVkIGlmIHRoZSBzdHlsZXNoZWV0Ci0gICAgICAgICAqIGJlaW5nIHByb2Nlc3NlZCBhdHRlbXB0ZWQgdG8gY29uc3RydWN0IGFuIFhNTCBkb2N1bWVudCB3aXRoIGFuCi0gICAgICAgICAqIGF0dHJpYnV0ZSBpbiBhIHBsYWNlIG90aGVyIHRoYW4gb24gYW4gZWxlbWVudC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICAgKiBzcGVjaWZpZXMgdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5TVFJBWV9BVFRSSUJVVEVfRVJSLAotICAgICAgICAiXHU1QzZDXHU2MDI3ICcnezB9JycgXHU1NzI4XHU1MTQzXHU3RDIwXHU0RTRCXHU1OTE2XHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIGF0dHJpYnV0ZSB0aGF0IHdhc24ndCByZWNvZ25pemVkIHdhcwotICAgICAgICAgKiBzcGVjaWZpZWQgb24gYW4gZWxlbWVudCBpbiB0aGUgc3R5bGVzaGVldC4gIFRoZSBhdHRyaWJ1dGUgaXMgbmFtZWQKLSAgICAgICAgICogYnkgdGhlIHN1YnN0aXR1dGlvbgotICAgICAgICAgKiB0ZXh0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfQVRUUklCVVRFX0VSUiwKLSAgICAgICAgIlx1NzEyMVx1NjU0OFx1NzY4NFx1NUM2Q1x1NjAyNyAnJ3swfScnXHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJpbXBvcnQiIGFuZCAiaW5jbHVkZSIgYXJlIGtleXdvcmRzIHRoYXQgc2hvdWxkCi0gICAgICAgICAqIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhpcyBtZXNzYWdlcyBpbmRpY2F0ZXMgdGhhdCB0aGUgc3R5bGVzaGVldAotICAgICAgICAgKiBuYW1lZCBpbiB0aGUgc3Vic3RpdHV0aW9uIHRleHQgaW1wb3J0ZWQgb3IgaW5jbHVkZWQgaXRzZWxmIGVpdGhlcgotICAgICAgICAgKiBkaXJlY3RseSBvciBpbmRpcmVjdGx5LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkNJUkNVTEFSX0lOQ0xVREVfRVJSLAotICAgICAgICAiXHU1RkFBXHU3NEIwXHU1MzJGXHU1MTY1L1x1NTMwNVx1NTQyQlx1MzAwMlx1NURGMlx1N0Q5M1x1OEYwOVx1NTE2NVx1NkEyM1x1NUYwRlx1ODg2OCAnJ3swfScnXHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEEgcmVzdWx0LXRyZWUgZnJhZ21lbnQgaXMgYSBwb3J0aW9uIG9mIGEKLSAgICAgICAgICogcmVzdWx0aW5nIFhNTCBkb2N1bWVudCByZXByZXNlbnRlZCBhcyBhIHRyZWUuICAiPHhzbDpzb3J0PiIgaXMgYQotICAgICAgICAgKiBrZXl3b3JkIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuUkVTVUxUX1RSRUVfU09SVF9FUlIsCi0gICAgICAgICJcdTcxMjFcdTZDRDVcdTYzOTJcdTVFOEYgUmVzdWx0LXRyZWUgXHU3MjQ3XHU2QkI1IChcdTVGRkRcdTc1NjUgPHhzbDpzb3J0PiBcdTUxNDNcdTdEMjApXHUzMDAyXHU1RUZBXHU3QUNCXHU3RDUwXHU2NzlDXHU2QTM5XHU3MkMwXHU3RDUwXHU2OUNCXHU2NjQyXHVGRjBDXHU1RkM1XHU5ODA4XHU2MzkyXHU1RThGXHU3QkMwXHU5RURFXHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEEgbmFtZSBjYW4gYmUgZ2l2ZW4gdG8gYSBwYXJ0aWN1bGFyIHN0eWxlIHRvIGJlCi0gICAgICAgICAqIHVzZWQgdG8gZm9ybWF0IGRlY2ltYWwgdmFsdWVzLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGdpdmVzIHRoZSBuYW1lCi0gICAgICAgICAqIG9mIHN1Y2ggYSBzdHlsZSBmb3Igd2hpY2ggbW9yZSB0aGFuIG9uZSBkZWNsYXJhdGlvbiB3YXMgZW5jb3VudGVyZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuU1lNQk9MU19SRURFRl9FUlIsCi0gICAgICAgICJcdTVERjJcdTdEOTNcdTVCOUFcdTdGQTlcdTUzNDFcdTkwMzJcdTRGNERcdTY4M0NcdTVGMEYgJyd7MH0nJ1x1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3R5bGVzaGVldCB2ZXJzaW9uIG5hbWVkIGluIHRoZQotICAgICAgICAgKiBzdWJzdGl0dXRpb24gdGV4dCBpcyBub3Qgc3VwcG9ydGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlhTTF9WRVJTSU9OX0VSUiwKLSAgICAgICAgIlhTTFRDIFx1NEUwRFx1NjUyRlx1NjNGNCBYU0wgXHU3MjQ4XHU2NzJDICcnezB9JydcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGRlZmluaXRpb25zIG9mIG9uZSBvciBtb3JlIHZhcmlhYmxlcyBvcgotICAgICAgICAgKiBwYXJhbWV0ZXJzIGRlcGVuZCBvbiBvbmUgYW5vdGhlci4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5DSVJDVUxBUl9WQVJJQUJMRV9FUlIsCi0gICAgICAgICJcdTU3MjggJyd7MH0nJyBcdTRFMkRcdTY3MDlcdTVGQUFcdTc0QjBcdThCOEFcdTY1NzgvXHU1M0MzXHU2NTc4XHU1M0MzXHU3MTY3XHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBvcGVyYXRvciBpbiBhbiBleHByZXNpb24gd2l0aCB0d28gb3BlcmFuZHMgd2FzCi0gICAgICAgICAqIG5vdCByZWNvZ25pemVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfQklOQVJZX09QX0VSUiwKLSAgICAgICAgIlx1NEU4Q1x1OTAzMlx1NEY0RFx1ODg2OFx1NzkzQVx1NUYwRlx1NEUwRFx1NjYwRVx1NzY4NFx1OTA0Qlx1N0I5N1x1NUI1MFx1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgcHJvZHVjZWQgaWYgYSByZWZlcmVuY2UgdG8gYQotICAgICAgICAgKiBmdW5jdGlvbiBoYXMgdG9vIG1hbnkgb3IgdG9vIGZldyBhcmd1bWVudHMuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSUxMRUdBTF9BUkdfRVJSLAotICAgICAgICAiXHU1MUZEXHU2NTc4XHU1NDdDXHU1M0VCXHU3MTIxXHU2NTQ4XHU3Njg0XHU1RjE1XHU2NTc4XHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJkb2N1bWVudCgpIiBpcyB0aGUgbmFtZSBvZiBmdW5jdGlvbiBhbmQgbXVzdAotICAgICAgICAgKiBub3QgYmUgdHJhbnNsYXRlZC4gIEEgbm9kZS1zZXQgaXMgYSBzZXQgb2YgdGhlIG5vZGVzIGluIHRoZSB0cmVlCi0gICAgICAgICAqIHJlcHJlc2VudGF0aW9uIG9mIGFuIFhNTCBkb2N1bWVudC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5ET0NVTUVOVF9BUkdfRVJSLAotICAgICAgICAiZG9jdW1lbnQoKSBcdTUxRkRcdTY1NzhcdTc2ODRcdTdCMkNcdTRFOENcdTUwMEJcdTVGMTVcdTY1NzhcdTVGQzVcdTk4MDhcdTY2MkYgbm9kZS1zZXRcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIjx4c2w6d2hlbj4iIGFuZCAiPHhzbDpjaG9vc2U+IiBhcmUga2V5d29yZHMKLSAgICAgICAgICogYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoaXMgbWVzc2FnZSBkZXNjcmliZXMgYSBzeW50YXggZXJyb3IKLSAgICAgICAgICogaW4gdGhlIHN0eWxlc2hlZXQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTUlTU0lOR19XSEVOX0VSUiwKLSAgICAgICAgIlx1NTcyOCA8eHNsOmNob29zZT4gXHU0RTJEXHU4MUYzXHU1QzExXHU5NzAwXHU4OTgxXHU0RTAwXHU1MDBCIDx4c2w6d2hlbj4gXHU1MTQzXHU3RDIwXHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICI8eHNsOm90aGVyd2lzZT4iIGFuZCAiPHhzbDpjaG9vc2U+IiBhcmUKLSAgICAgICAgICoga2V5d29yZHMgYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoaXMgbWVzc2FnZSBkZXNjcmliZXMgYQotICAgICAgICAgKiBzeW50YXggZXJyb3IgaW4gdGhlIHN0eWxlc2hlZXQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTVVMVElQTEVfT1RIRVJXSVNFX0VSUiwKLSAgICAgICAgIlx1NTcyOCA8eHNsOmNob29zZT4gXHU0RTJEXHU1M0VBXHU1MTQxXHU4QTMxXHU0RTAwXHU1MDBCIDx4c2w6b3RoZXJ3aXNlPiBcdTUxNDNcdTdEMjBcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIjx4c2w6b3RoZXJ3aXNlPiIgYW5kICI8eHNsOmNob29zZT4iIGFyZQotICAgICAgICAgKiBrZXl3b3JkcyBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhpcyBtZXNzYWdlIGRlc2NyaWJlcyBhCi0gICAgICAgICAqIHN5bnRheCBlcnJvciBpbiB0aGUgc3R5bGVzaGVldC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5TVFJBWV9PVEhFUldJU0VfRVJSLAotICAgICAgICAiPHhzbDpvdGhlcndpc2U+IFx1NTNFQVx1ODBGRFx1NTcyOCA8eHNsOmNob29zZT4gXHU1MTY3XHU0RjdGXHU3NTI4XHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICI8eHNsOndoZW4+IiBhbmQgIjx4c2w6Y2hvb3NlPiIgYXJlIGtleXdvcmRzCi0gICAgICAgICAqIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGlzIG1lc3NhZ2UgZGVzY3JpYmVzIGEgc3ludGF4IGVycm9yCi0gICAgICAgICAqIGluIHRoZSBzdHlsZXNoZWV0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlNUUkFZX1dIRU5fRVJSLAotICAgICAgICAiPHhzbDp3aGVuPiBcdTUzRUFcdTgwRkRcdTU3MjggPHhzbDpjaG9vc2U+IFx1NTE2N1x1NEY3Rlx1NzUyOFx1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiPHhzbDp3aGVuPiIsICI8eHNsOm90aGVyd2lzZT4iIGFuZAotICAgICAgICAgKiAiPHhzbDpjaG9vc2U+IiBhcmUga2V5d29yZHMgYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoaXMKLSAgICAgICAgICogbWVzc2FnZSBkZXNjcmliZXMgYSBzeW50YXggZXJyb3IgaW4gdGhlIHN0eWxlc2hlZXQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuV0hFTl9FTEVNRU5UX0VSUiwKLSAgICAgICAgIlx1NTcyOCA8eHNsOmNob29zZT4gXHU0RTJEXHU1M0VBXHU1MTQxXHU4QTMxIDx4c2w6d2hlbj4gXHU4MjA3IDx4c2w6b3RoZXJ3aXNlPiBcdTUxNDNcdTdEMjBcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIjx4c2w6YXR0cmlidXRlLXNldD4iIGFuZCAibmFtZSIgYXJlIGtleXdvcmRzCi0gICAgICAgICAqIHRoYXQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlVOTkFNRURfQVRUUklCU0VUX0VSUiwKLSAgICAgICAgIjx4c2w6YXR0cmlidXRlLXNldD4gXHU5MDdBXHU2RjBGICduYW1lJyBcdTVDNkNcdTYwMjdcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQW4gZWxlbWVudCBpbiB0aGUgc3R5bGVzaGVldCBjb250YWluZWQgYW4KLSAgICAgICAgICogZWxlbWVudCBvZiBhIHR5cGUgdGhhdCBpdCB3YXMgbm90IHBlcm1pdHRlZCB0byBjb250YWluLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfQ0hJTERfRVJSLAotICAgICAgICAiXHU3MTIxXHU2NTQ4XHU3Njg0XHU1QjUwXHU5ODA1XHU1MTQzXHU3RDIwXHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IHRyaWVkIHRvIGNyZWF0ZSBhbiBlbGVtZW50IHdpdGgKLSAgICAgICAgICogYSBuYW1lIHRoYXQgd2FzIG5vdCBhIHZhbGlkIFhNTCBuYW1lLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGNvbnRhaW5zCi0gICAgICAgICAqIHRoZSBuYW1lLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfRUxFTV9OQU1FX0VSUiwKLSAgICAgICAgIlx1NjBBOFx1NzEyMVx1NkNENVx1NTQ3Q1x1NTNFQlx1NTE0M1x1N0QyMCAnJ3swfScnIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IHRyaWVkIHRvIGNyZWF0ZSBhbiBhdHRyaWJ1dGUKLSAgICAgICAgICogd2l0aCBhIG5hbWUgdGhhdCB3YXMgbm90IGEgdmFsaWQgWE1MIG5hbWUuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQKLSAgICAgICAgICogY29udGFpbnMgdGhlIG5hbWUuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSUxMRUdBTF9BVFRSX05BTUVfRVJSLAotICAgICAgICAiXHU2MEE4XHU3MTIxXHU2Q0Q1XHU1NDdDXHU1M0VCXHU1QzZDXHU2MDI3ICcnezB9JycifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGNoaWxkcmVuIG9mIHRoZSBvdXRlcm1vc3QgZWxlbWVudCBvZiBhCi0gICAgICAgICAqIHN0eWxlc2hlZXQgYXJlIHJlZmVycmVkIHRvIGFzIHRvcC1sZXZlbCBlbGVtZW50cy4gIE5vIHRleHQgc2hvdWxkCi0gICAgICAgICAqIG9jY3VyIHdpdGhpbiB0aGF0IG91dGVybW9zdCBlbGVtZW50IHVubGVzcyBpdCBpcyB3aXRoaW4gYSB0b3AtbGV2ZWwKLSAgICAgICAgICogZWxlbWVudC4gIFRoaXMgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGF0IGNvbnN0cmFpbnQgd2FzIHZpb2xhdGVkLgotICAgICAgICAgKiAiPHhzbDpzdHlsZXNoZWV0PiIgaXMgYSBrZXl3b3JkIHRoYXQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLklMTEVHQUxfVEVYVF9OT0RFX0VSUiwKLSAgICAgICAgIlx1NjcwMFx1NEUwQVx1NUM2NCA8eHNsOnN0eWxlc2hlZXQ+IFx1NTE0M1x1N0QyMFx1NEU0Qlx1NTkxNlx1NzY4NFx1NjU4N1x1NUI1N1x1OENDN1x1NjU5OVx1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBKQVhQIGlzIGFuIGFjcm9ueW0gZm9yIHRoZSBKYXZhIEFQSSBmb3IgWE1MCi0gICAgICAgICAqIFByb2Nlc3NpbmcuICBUaGlzIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhlIFhNTCBwYXJzZXIgcHJvdmlkZWQgdG8KLSAgICAgICAgICogWFNMVEMgdG8gcHJvY2VzcyB0aGUgWE1MIGlucHV0IGRvY3VtZW50IGhhZCBhIGNvbmZpZ3VyYXRpb24gcHJvYmxlbS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5TQVhfUEFSU0VSX0NPTkZJR19FUlIsCi0gICAgICAgICJcdTY3MkFcdTZCNjNcdTc4QkFcdThBMkRcdTVCOUEgSkFYUCBcdTUyNTZcdTY3OTBcdTU2NjgifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IG5hbWVzIHRoZSBpbnRlcm5hbCBlcnJvcgotICAgICAgICAgKiBlbmNvdW50ZXJlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTlRFUk5BTF9FUlIsCi0gICAgICAgICJcdTcxMjFcdTZDRDVcdTVGQTlcdTUzOUZcdTc2ODQgWFNMVEMtaW50ZXJuYWwgXHU5MzJGXHU4QUE0OiAnJ3swfScnIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IGNvbnRhaW5lZCBhbiBlbGVtZW50IHRoYXQgd2FzCi0gICAgICAgICAqIG5vdCByZWNvZ25pemVkIGFzIHBhcnQgb2YgdGhlIFhTTCBzeW50YXguICBUaGUgc3Vic3RpdHV0aW9uIHRleHQKLSAgICAgICAgICogZ2l2ZXMgdGhlIGVsZW1lbnQgbmFtZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5VTlNVUFBPUlRFRF9YU0xfRVJSLAotICAgICAgICAiXHU0RTBEXHU2NTJGXHU2M0Y0XHU3Njg0IFhTTCBcdTUxNDNcdTdEMjAgJyd7MH0nJ1x1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3R5bGVzaGVldCByZWZlcnJlZCB0byBhbiBleHRlbnNpb24gdG8gdGhlCi0gICAgICAgICAqIFhTTCBzeW50YXggYW5kIGluZGljYXRlZCB0aGF0IGl0IHdhcyBkZWZpbmVkIGJ5IFhTTFRDLCBidXQgWFNUTEMgZG9lcwotICAgICAgICAgKiBub3QgcmVjb2duaXplZCB0aGUgcGFydGljdWxhciBleHRlbnNpb24gbmFtZWQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQKLSAgICAgICAgICogZ2l2ZXMgdGhlIGV4dGVuc2lvbiBuYW1lLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlVOU1VQUE9SVEVEX0VYVF9FUlIsCi0gICAgICAgICJcdTcxMjFcdTZDRDVcdThGQThcdThCNThcdTc2ODQgWFNMVEMgXHU2NEY0XHU1MTQ1XHU1OTU3XHU0RUY2ICcnezB9JydcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIFhNTCBkb2N1bWVudCBnaXZlbiB0byBYU0xUQyBhcyBhIHN0eWxlc2hlZXQKLSAgICAgICAgICogd2FzIG5vdCwgaW4gZmFjdCwgYSBzdHlsZXNoZWV0LiAgWFNMVEMgaXMgYWJsZSB0byBkZXRlY3QgdGhhdCBpbiB0aGlzCi0gICAgICAgICAqIGNhc2UgYmVjYXVzZSB0aGUgb3V0ZXJtb3N0IGVsZW1lbnQgaW4gdGhlIHN0eWxlc2hlZXQgaGFzIHRvIGJlCi0gICAgICAgICAqIGRlY2xhcmVkIHdpdGggcmVzcGVjdCB0byB0aGUgWFNMIG5hbWVzcGFjZSBVUkksIGJ1dCBubyBkZWNsYXJhdGlvbgotICAgICAgICAgKiBmb3IgdGhhdCBuYW1lc3BhY2Ugd2FzIHNlZW4uCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTUlTU0lOR19YU0xUX1VSSV9FUlIsCi0gICAgICAgICJcdThGMzhcdTUxNjVcdTY1ODdcdTRFRjZcdTRFMERcdTY2MkZcdTZBMjNcdTVGMEZcdTg4NjggKFx1NjgzOVx1NTE0M1x1N0QyMFx1NEUyRFx1NjcyQVx1NUJBM1x1NTQ0QSBYU0wgXHU1NDdEXHU1NDBEXHU3QTdBXHU5NTkzKVx1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBYU0xUQyBjb3VsZCBub3QgZmluZCB0aGUgc3R5bGVzaGVldCBkb2N1bWVudAotICAgICAgICAgKiB3aXRoIHRoZSBuYW1lIHNwZWNpZmllZCBieSB0aGUgc3Vic3RpdHV0aW9uIHRleHQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTUlTU0lOR19YU0xUX1RBUkdFVF9FUlIsCi0gICAgICAgICJcdTYyN0VcdTRFMERcdTUyMzBcdTZBMjNcdTVGMEZcdTg4NjhcdTc2RUVcdTZBMTkgJyd7MH0nJ1x1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBhY2Nlc3MgdG8gdGhlIHN0eWxlc2hlZXQgdGFyZ2V0IGlzIGRlbmllZAotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkFDQ0VTU0lOR19YU0xUX1RBUkdFVF9FUlIsCi0gICAgICAgICJcdTcxMjFcdTZDRDVcdThCODBcdTUzRDZcdTZBMjNcdTVGMEZcdTg4NjhcdTc2RUVcdTZBMTkgJyd7MH0nJ1x1RkYwQ1x1NTZFMFx1NzBCQSBhY2Nlc3NFeHRlcm5hbFN0eWxlc2hlZXQgXHU1QzZDXHU2MDI3XHU4QTJEXHU1QjlBXHU3Njg0XHU5NjUwXHU1MjM2XHVGRjBDXHU2MjQwXHU0RUU1XHU0RTBEXHU1MTQxXHU4QTMxICcnezF9JycgXHU1QjU4XHU1M0Q2XHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSByZXByZXNlbnRzIGFuIGludGVybmFsIGVycm9yIGluCi0gICAgICAgICAqIGNvbmRpdGlvbiBpbiBYU0xUQy4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgY2xhc3MgbmFtZSBpbiBYU0xUQwotICAgICAgICAgKiB0aGF0IGlzIG1pc3Npbmcgc29tZSBmdW5jdGlvbmFsaXR5LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk5PVF9JTVBMRU1FTlRFRF9FUlIsCi0gICAgICAgICJcdTY3MkFcdTVCRTZcdTg4NEM6ICcnezB9JydcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIFhNTCBkb2N1bWVudCBnaXZlbiB0byBYU0xUQyBhcyBhIHN0eWxlc2hlZXQKLSAgICAgICAgICogd2FzIG5vdCwgaW4gZmFjdCwgYSBzdHlsZXNoZWV0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk5PVF9TVFlMRVNIRUVUX0VSUiwKLSAgICAgICAgIlx1OEYzOFx1NTE2NVx1NjU4N1x1NEVGNlx1NjcyQVx1NTMwNVx1NTQyQiBYU0wgXHU2QTIzXHU1RjBGXHU4ODY4XHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBlbGVtZW50IG5hbWVkIGluIHRoZSBzdWJzdGl0dXRpb24gdGV4dCB3YXMKLSAgICAgICAgICogZW5jb3VudGVyZWQgaW4gdGhlIHN0eWxlc2hlZXQgYnV0IGlzIG5vdCByZWNvZ25pemVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkVMRU1FTlRfUEFSU0VfRVJSLAotICAgICAgICAiXHU3MTIxXHU2Q0Q1XHU1MjU2XHU2NzkwXHU1MTQzXHU3RDIwICcnezB9JycifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgInVzZSIsICI8a2V5PiIsICJub2RlIiwgIm5vZGUtc2V0IiwgInN0cmluZyIKLSAgICAgICAgICogYW5kICJudW1iZXIiIGFyZSBrZXl3b3JkcyBpbiB0aGlzIGNvbnRleHQgYW5kIHNob3VsZCBub3QgYmUKLSAgICAgICAgICogdHJhbnNsYXRlZC4gIFRoaXMgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUgdmFsdWUgb2YgdGhlICJ1c2UiCi0gICAgICAgICAqIGF0dHJpYnV0ZSB3YXMgbm90IG9uZSBvZiB0aGUgcGVybWl0dGVkIHZhbHVlcy4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5LRVlfVVNFX0FUVFJfRVJSLAotICAgICAgICAiPGtleT4gXHU3Njg0XHU0RjdGXHU3NTI4XHU1QzZDXHU2MDI3XHU1RkM1XHU5ODA4XHU2NjJGXHU3QkMwXHU5RURFXHUzMDAxbm9kZS1zZXRcdTMwMDFcdTVCNTdcdTRFMzJcdTYyMTZcdTY1NzhcdTVCNTdcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQW4gWE1MIGRvY3VtZW50IGNhbiBzcGVjaWZ5IHRoZSB2ZXJzaW9uIG9mIHRoZQotICAgICAgICAgKiBYTUwgc3BlY2lmaWNhdGlvbiB0byB3aGljaCBpdCBhZGhlcmVzLiAgVGhpcyBtZXNzYWdlIGluZGljYXRlcyB0aGF0Ci0gICAgICAgICAqIHRoZSB2ZXJzaW9uIHNwZWNpZmllZCBmb3IgdGhlIG91dHB1dCBkb2N1bWVudCB3YXMgbm90IHZhbGlkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk9VVFBVVF9WRVJTSU9OX0VSUiwKLSAgICAgICAgIlx1OEYzOFx1NTFGQSBYTUwgXHU2NTg3XHU0RUY2XHU3MjQ4XHU2NzJDXHU2MUM5XHU3MEJBIDEuMCJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgb3BlcmF0b3IgaW4gYSBjb21wYXJpc29uIG9wZXJhdGlvbiB3YXMKLSAgICAgICAgICogbm90IHJlY29nbml6ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSUxMRUdBTF9SRUxBVF9PUF9FUlIsCi0gICAgICAgICJcdTk1RENcdTgwNkZcdTg4NjhcdTc5M0FcdTVGMEZcdTc2ODRcdTkwNEJcdTdCOTdcdTVCNTBcdTRFMERcdTY2MEUifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQW4gYXR0cmlidXRlIHNldCBkZWZpbmVzIGFzIGEgc2V0IG9mIFhNTAotICAgICAgICAgKiBhdHRyaWJ1dGVzIHRoYXQgY2FuIGJlIGFkZGVkIHRvIGFuIGVsZW1lbnQgaW4gdGhlIG91dHB1dCBYTUwgZG9jdW1lbnQKLSAgICAgICAgICogYXMgYSBncm91cC4gIFRoaXMgbWVzc2FnZSBpcyByZXBvcnRlZCBpZiB0aGUgbmFtZSBzcGVjaWZpZWQgd2FzIG5vdAotICAgICAgICAgKiB1c2VkIHRvIGRlY2xhcmUgYW4gYXR0cmlidXRlIHNldC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZQotICAgICAgICAgKiB0aGF0IGlzIGluIGVycm9yLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkFUVFJJQlNFVF9VTkRFRl9FUlIsCi0gICAgICAgICJcdTU2MTdcdThBNjZcdTRGN0ZcdTc1MjhcdTRFMERcdTVCNThcdTU3MjhcdTc2ODRcdTVDNkNcdTYwMjdcdTk2QzYgJyd7MH0nJ1x1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgdGVybSAiYXR0cmlidXRlIHZhbHVlIHRlbXBsYXRlIiBpcyBhIHRlcm0KLSAgICAgICAgICogZGVmaW5lZCBieSBYU0xUIHdoaWNoIGRlc2NyaWJlcyB0aGUgdmFsdWUgb2YgYW4gYXR0cmlidXRlIHRoYXQgaXMKLSAgICAgICAgICogZGV0ZXJtaW5lZCBieSBhbiBYUGF0aCBleHByZXNzaW9uLiAgVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhlCi0gICAgICAgICAqIGV4cHJlc3Npb24gd2FzIHN5bnRhY3RpY2FsbHkgaW5jb3JyZWN0OyB0aGUgc3Vic3RpdHV0aW9uIHRleHQKLSAgICAgICAgICogY29udGFpbnMgdGhlIGV4cHJlc3Npb24gdGhhdCB3YXMgaW4gZXJyb3IuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuQVRUUl9WQUxfVEVNUExBVEVfRVJSLAotICAgICAgICAiXHU3MTIxXHU2Q0Q1XHU1MjU2XHU2NzkwXHU1QzZDXHU2MDI3XHU1MDNDXHU2QTIzXHU2NzdGICcnezB9JydcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgPz8/Ci0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVU5LTk9XTl9TSUdfVFlQRV9FUlIsCi0gICAgICAgICJcdTk4NUVcdTUyMjUgJyd7MH0nJyBcdTdDM0RcdTdBRTBcdTY3MDlcdTRFMERcdTY2MEVcdTc2ODQgZGF0YS10eXBlXHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCByZWZlcnMgdG8gZGF0YSB0eXBlcy4KLSAgICAgICAgICogVGhlIG1lc3NhZ2UgaXMgZGlzcGxheWVkIGlmIGEgdmFsdWUgaW4gYSBwYXJ0aWN1bGFyIGNvbnRleHQgbmVlZHMgdG8KLSAgICAgICAgICogYmUgY29udmVydGVkIHRvIHR5cGUgezF9LCBidXQgdGhhdCdzIG5vdCBwb3NzaWJsZSBmb3IgYSB2YWx1ZSBvZgotICAgICAgICAgKiB0eXBlIHswfS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5EQVRBX0NPTlZFUlNJT05fRVJSLAotICAgICAgICAiXHU3MTIxXHU2Q0Q1XHU4RjQ5XHU2M0RCIGRhdGEtdHlwZSAnJ3swfScnIFx1NzBCQSAnJ3sxfScnXHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJUZW1wbGF0ZXMiIGlzIGEgSmF2YSBjbGFzcyBuYW1lIHRoYXQgc2hvdWxkCi0gICAgICAgICAqIG5vdCBiZSB0cmFuc2xhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk5PX1RSQU5TTEVUX0NMQVNTX0VSUiwKLSAgICAgICAgIlx1NkI2NFx1NkEyM1x1Njc3Rlx1NjcyQVx1NTMwNVx1NTQyQlx1NjcwOVx1NjU0OFx1NzY4NCB0cmFuc2xldCBcdTk4NUVcdTUyMjVcdTVCOUFcdTdGQTlcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIlRlbXBsYXRlcyIgaXMgYSBKYXZhIGNsYXNzIG5hbWUgdGhhdCBzaG91bGQKLSAgICAgICAgICogbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTk9fTUFJTl9UUkFOU0xFVF9FUlIsCi0gICAgICAgICJcdTZCNjRcdTZBMjNcdTY3N0ZcdTY3MkFcdTUzMDVcdTU0MkJcdTU0MERcdTdBMzFcdTcwQkEgJyd7MH0nJyBcdTc2ODRcdTk4NUVcdTUyMjVcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIGEgY2xhc3MuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVFJBTlNMRVRfQ0xBU1NfRVJSLAotICAgICAgICAiXHU3MTIxXHU2Q0Q1XHU4RjA5XHU1MTY1IHRyYW5zbGV0IFx1OTg1RVx1NTIyNSAnJ3swfScnXHUzMDAyIn0sCi0KLSAgICAgICAge0Vycm9yTXNnLlRSQU5TTEVUX09CSkVDVF9FUlIsCi0gICAgICAgICJcdTVERjJcdThGMDlcdTUxNjUgdHJhbnNsZXQgXHU5ODVFXHU1MjI1XHVGRjBDXHU0RjQ2XHU3MTIxXHU2Q0Q1XHU1RUZBXHU3QUNCIHRyYW5zbGV0IFx1NTdGN1x1ODg0Q1x1ODY1NVx1NzQwNlx1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiRXJyb3JMaXN0ZW5lciIgaXMgYSBKYXZhIGludGVyZmFjZSBuYW1lIHRoYXQKLSAgICAgICAgICogc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhlIHVzZXIgdHJpZWQKLSAgICAgICAgICogdG8gc2V0IGFuIEVycm9yTGlzdGVuZXIgb2JqZWN0IG9uIG9iamVjdCBvZiB0aGUgY2xhc3MgbmFtZWQgaW4gdGhlCi0gICAgICAgICAqIHN1YnN0aXR1dGlvbiB0ZXh0IHdpdGggIm51bGwiIEphdmEgdmFsdWUuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuRVJST1JfTElTVEVORVJfTlVMTF9FUlIsCi0gICAgICAgICJcdTU2MTdcdThBNjZcdTVDMDcgJyd7MH0nJyBcdTc2ODQgRXJyb3JMaXN0ZW5lciBcdThBMkRcdTVCOUFcdTcwQkFcdTdBN0FcdTUwM0MifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgU3RyZWFtU291cmNlLCBTQVhTb3VyY2UgYW5kIERPTVNvdXJjZSBhcmUgSmF2YQotICAgICAgICAgKiBpbnRlcmZhY2UgbmFtZXMgdGhhdCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSkFYUF9VTktOT1dOX1NPVVJDRV9FUlIsCi0gICAgICAgICJYU0xUQyBcdTUwQzVcdTY1MkZcdTYzRjQgU3RyZWFtU291cmNlXHUzMDAxU0FYU291cmNlIFx1ODIwNyBET01Tb3VyY2UifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIlNvdXJjZSIgaXMgYSBKYXZhIGNsYXNzIG5hbWUgdGhhdCBzaG91bGQgbm90Ci0gICAgICAgICAqIGJlIHRyYW5zbGF0ZWQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgSmF2YSBtZXRob2QuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSkFYUF9OT19TT1VSQ0VfRVJSLAotICAgICAgICAiXHU1MEIzXHU5MDAxXHU4MUYzICcnezB9JycgXHU3Njg0XHU0Rjg2XHU2RTkwXHU3MjY5XHU0RUY2XHU2QzkyXHU2NzA5XHU1MTY3XHU1QkI5XHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBtZXNzYWdlIGluZGljYXRlcyB0aGF0IFhTTFRDIGZhaWxlZCB0bwotICAgICAgICAgKiBjb21waWxlIHRoZSBzdHlsZXNoZWV0IGludG8gYSB0cmFuc2xldCAoY2xhc3MgZmlsZSkuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSkFYUF9DT01QSUxFX0VSUiwKLSAgICAgICAgIlx1NzEyMVx1NkNENVx1N0RFOFx1OEI2Rlx1NkEyM1x1NUYwRlx1ODg2OCJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiVHJhbnNmb3JtZXJGYWN0b3J5IiBpcyBhIGNsYXNzIG5hbWUuICBJbiB0aGlzCi0gICAgICAgICAqIGNvbnRleHQsIGFuIGF0dHJpYnV0ZSBpcyBhIHByb3BlcnR5IG9yIHNldHRpbmcgb2YgdGhlCi0gICAgICAgICAqIFRyYW5zZm9ybWVyRmFjdG9yeSBvYmplY3QuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgdGhlCi0gICAgICAgICAqIHVucmVjb2duaXNlZCBhdHRyaWJ1dGUuICBUaGUgbWV0aG9kIHVzZWQgdG8gcmV0cmlldmUgdGhlIGF0dHJpYnV0ZSBpcwotICAgICAgICAgKiAiZ2V0QXR0cmlidXRlIiwgc28gaXQncyBub3QgY2xlYXIgd2hldGhlciBpdCB3b3VsZCBiZSBiZXN0IHRvCi0gICAgICAgICAqIHRyYW5zbGF0ZSB0aGUgdGVybSAiYXR0cmlidXRlIi4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX0lOVkFMSURfQVRUUl9FUlIsCi0gICAgICAgICJUcmFuc2Zvcm1lckZhY3RvcnkgXHU3MTIxXHU2Q0Q1XHU4RkE4XHU4QjU4XHU1QzZDXHU2MDI3ICcnezB9JydcdTMwMDIifSwKLQotICAgICAgICB7RXJyb3JNc2cuSkFYUF9JTlZBTElEX0FUVFJfVkFMVUVfRVJSLAotICAgICAgICAiXHU3MEJBICcnezB9JycgXHU1QzZDXHU2MDI3XHU2MzA3XHU1QjlBXHU3Njg0XHU1MDNDXHU0RTBEXHU2QjYzXHU3OEJBXHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICJzZXRSZXN1bHQoKSIgYW5kICJzdGFydERvY3VtZW50KCkiIGFyZSBKYXZhCi0gICAgICAgICAqIG1ldGhvZCBuYW1lcyB0aGF0IHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX1NFVF9SRVNVTFRfRVJSLAotICAgICAgICAiXHU1NDdDXHU1M0VCIHN0YXJ0RG9jdW1lbnQoKSBcdTRFNEJcdTUyNERcdUZGMENcdTVGQzVcdTk4MDhcdTUxNDhcdTU0N0NcdTUzRUIgc2V0UmVzdWx0KClcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIlRyYW5zZm9ybWVyIiBpcyBhIEphdmEgaW50ZXJmYWNlIG5hbWUgdGhhdAotICAgICAgICAgKiBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuICBBIFRyYW5zZm9ybWVyIG9iamVjdCBzaG91bGQgY29udGFpbmVkIGEKLSAgICAgICAgICogcmVmZXJlbmNlIHRvIGEgdHJhbnNsZXQgb2JqZWN0IGluIG9yZGVyIHRvIGJlIHVzZWQgZm9yCi0gICAgICAgICAqIHRyYW5zZm9ybWF0aW9uczsgdGhpcyBtZXNzYWdlIGlzIHByb2R1Y2VkIGlmIHRoYXQgcmVxdWlyZW1lbnQgaXMgbm90Ci0gICAgICAgICAqIG1ldC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX05PX1RSQU5TTEVUX0VSUiwKLSAgICAgICAgIlx1OEY0OVx1NjNEQlx1NTY2OFx1NkM5Mlx1NjcwOVx1NUMwMVx1ODhERFx1NzY4NCB0cmFuc2xldCBcdTcyNjlcdTRFRjZcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIFhNTCBkb2N1bWVudCB0aGF0IHJlc3VsdHMgZnJvbSBhCi0gICAgICAgICAqIHRyYW5zZm9ybWF0aW9uIG5lZWRzIHRvIGJlIHNlbnQgdG8gYW4gb3V0cHV0IGhhbmRsZXIgb2JqZWN0OyB0aGlzCi0gICAgICAgICAqIG1lc3NhZ2UgaXMgcHJvZHVjZWQgaWYgdGhhdCByZXF1aXJlbWVudCBpcyBub3QgbWV0LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfTk9fSEFORExFUl9FUlIsCi0gICAgICAgICJcdThGNDlcdTYzREJcdTdENTBcdTY3OUNcdTZDOTJcdTY3MDlcdTVCOUFcdTdGQTlcdTc2ODRcdThGMzhcdTUxRkFcdTg2NTVcdTc0MDZcdTdBMEJcdTVGMEZcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIlJlc3VsdCIgaXMgYSBKYXZhIGludGVyZmFjZSBuYW1lIGluIHRoaXMKLSAgICAgICAgICogY29udGV4dC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyBhIG1ldGhvZCBuYW1lLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkpBWFBfTk9fUkVTVUxUX0VSUiwKLSAgICAgICAgIlx1NTBCM1x1OTAwMVx1ODFGMyAnJ3swfScnIFx1NzY4NFx1N0Q1MFx1Njc5Q1x1NzI2OVx1NEVGNlx1NzEyMVx1NjU0OFx1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiVHJhbnNmb3JtZXIiIGlzIGEgSmF2YSBpbnRlcmZhY2UgbmFtZS4gIFRoZQotICAgICAgICAgKiB1c2VyJ3MgcHJvZ3JhbSBhdHRlbXB0ZWQgdG8gYWNjZXNzIGFuIHVucmVjb2duaXplZCBwcm9wZXJ0eSB3aXRoIHRoZQotICAgICAgICAgKiBuYW1lIHNwZWNpZmllZCBpbiB0aGUgc3Vic3RpdHV0aW9uIHRleHQuICBUaGUgbWV0aG9kIHVzZWQgdG8gcmV0cmlldmUKLSAgICAgICAgICogdGhlIHByb3BlcnR5IGlzICJnZXRPdXRwdXRQcm9wZXJ0eSIsIHNvIGl0J3Mgbm90IGNsZWFyIHdoZXRoZXIgaXQKLSAgICAgICAgICogd291bGQgYmUgYmVzdCB0byB0cmFuc2xhdGUgdGhlIHRlcm0gInByb3BlcnR5Ii4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX1VOS05PV05fUFJPUF9FUlIsCi0gICAgICAgICJcdTU2MTdcdThBNjZcdTVCNThcdTUzRDZcdTcxMjFcdTY1NDhcdTc2ODRcdThGNDlcdTYzREJcdTU2NjhcdTVDNkNcdTYwMjcgJyd7MH0nJ1x1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBTQVgyRE9NIGlzIHRoZSBuYW1lIG9mIGEgSmF2YSBjbGFzcyB0aGF0IHNob3VsZAotICAgICAgICAgKiBub3QgYmUgdHJhbnNsYXRlZC4gIFRoaXMgaXMgYW4gYWRhcHRlciBpbiB0aGUgc2Vuc2UgdGhhdCBpdCB0YWtlcyBhCi0gICAgICAgICAqIERPTSBvYmplY3QgYW5kIGNvbnZlcnRzIGl0IHRvIHNvbWV0aGluZyB0aGF0IHVzZXMgdGhlIFNBWCBBUEkuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuU0FYMkRPTV9BREFQVEVSX0VSUiwKLSAgICAgICAgIlx1NzEyMVx1NkNENVx1NUVGQVx1N0FDQiBTQVgyRE9NIFx1OEY0OVx1NjNBNVx1NTY2ODogJyd7MH0nJ1x1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAiWFNMVENTb3VyY2UuYnVpbGQoKSIgaXMgYSBKYXZhIG1ldGhvZCBuYW1lLgotICAgICAgICAgKiAic3lzdGVtSWQiIGlzIGFuIFhNTCB0ZXJtIHRoYXQgaXMgc2hvcnQgZm9yICJzeXN0ZW0gaWRlbnRpZmljYXRpb24iLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlhTTFRDX1NPVVJDRV9FUlIsCi0gICAgICAgICJcdTY3MkFcdThBMkRcdTVCOUEgc3lzdGVtSWQgXHU4MDBDXHU1NDdDXHU1M0VCIFhTTFRDU291cmNlLmJ1aWxkKClcdTMwMDIifSwKLQotICAgICAgICB7IEVycm9yTXNnLkVSX1JFU1VMVF9OVUxMLAotICAgICAgICAgICAgIlx1N0Q1MFx1Njc5Q1x1NEUwRFx1NjFDOVx1NzBCQVx1N0E3QVx1NTAzQyJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhlIHZhbHVlIGFyZ3VtZW50Ci0gICAgICAgICAqIG9mIHNldFBhcmFtZXRlciBtdXN0IGJlIGEgdmFsaWQgSmF2YSBPYmplY3QuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSkFYUF9JTlZBTElEX1NFVF9QQVJBTV9WQUxVRSwKLSAgICAgICAgIlx1NTNDM1x1NjU3OCB7MH0gXHU3Njg0XHU1MDNDXHU1RkM1XHU5ODA4XHU2NjJGXHU2NzA5XHU2NTQ4XHU3Njg0IEphdmEgXHU3MjY5XHU0RUY2In0sCi0KLQotICAgICAgICB7RXJyb3JNc2cuQ09NUElMRV9TVERJTl9FUlIsCi0gICAgICAgICItaSBcdTkwNzhcdTk4MDVcdTVGQzVcdTk4MDhcdTgyMDcgLW8gXHU5MDc4XHU5ODA1XHU0RTAwXHU4RDc3XHU0RjdGXHU3NTI4XHUzMDAyIn0sCi0KLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGNvbnRhaW5zIHVzYWdlIGluZm9ybWF0aW9uIGZvciBhCi0gICAgICAgICAqIG1lYW5zIG9mIGludm9raW5nIFhTTFRDIGZyb20gdGhlIGNvbW1hbmQtbGluZS4gIFRoZSBtZXNzYWdlIGlzCi0gICAgICAgICAqIGZvcm1hdHRlZCBmb3IgcHJlc2VudGF0aW9uIGluIEVuZ2xpc2guICBUaGUgc3RyaW5ncyA8b3V0cHV0PiwKLSAgICAgICAgICogPGRpcmVjdG9yeT4sIGV0Yy4gaW5kaWNhdGUgdXNlci1zcGVjaWZpZWQgYXJndW1lbnQgdmFsdWVzLCBhbmQgY2FuCi0gICAgICAgICAqIGJlIHRyYW5zbGF0ZWQgLSB0aGUgYXJndW1lbnQgPHBhY2thZ2U+IHJlZmVycyB0byBhIEphdmEgcGFja2FnZSwgc28KLSAgICAgICAgICogaXQgc2hvdWxkIGJlIGhhbmRsZWQgaW4gdGhlIHNhbWUgd2F5IHRoZSB0ZXJtIGlzIGhhbmRsZWQgZm9yIEpESwotICAgICAgICAgKiBkb2N1bWVudGF0aW9uLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkNPTVBJTEVfVVNBR0VfU1RSLAotICAgICAgICAiXHU2OTgyXHU4OTgxXG4gICBqYXZhIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jbWRsaW5lLkNvbXBpbGUgWy1vIDxvdXRwdXQ+XVxuICAgICAgWy1kIDxkaXJlY3Rvcnk+XSBbLWogPGphcmZpbGU+XSBbLXAgPHBhY2thZ2U+XVxuICAgICAgWy1uXSBbLXhdIFstdV0gWy12XSBbLWhdIHsgPHN0eWxlc2hlZXQ+IHwgLWkgfVxuXG5cdTkwNzhcdTk4MDVcbiAgIC1vIDxvdXRwdXQ+ICAgIFx1NjMwN1x1NkQzRVx1NTQwRFx1N0EzMSA8b3V0cHV0PiBcdTgxRjNcdTc1MjJcdTc1MUZcdTc2ODRcbiAgICAgICAgICAgICAgICAgIHRyYW5zbGV0XHUzMDAyXHU2ODM5XHU2NERBXHU5ODEwXHU4QTJEXHVGRjBDdHJhbnNsZXQgXHU1NDBEXHU3QTMxXG4gICAgICAgICAgICAgICAgICBcdTg4NERcdTc1MUZcdTgxRUEgPHN0eWxlc2hlZXQ+IFx1NTQwRFx1N0EzMVx1MzAwMlx1ODJFNVx1N0RFOFx1OEI2RlxuICAgICAgICAgICAgICAgICAgXHU1OTFBXHU1MDBCXHU2QTIzXHU1RjBGXHU4ODY4XHVGRjBDXHU1QzA3XHU1RkZEXHU3NTY1XHU2QjY0XHU5MDc4XHU5ODA1XHUzMDAyXG4gICAtZCA8ZGlyZWN0b3J5PiBcdTYzMDdcdTVCOUEgdHJhbnNsZXQgXHU3Njg0XHU3NkVFXHU3Njg0XHU1NzMwXHU3NkVFXHU5MzA0XG4gICAtaiA8amFyZmlsZT4gICBcdTVDMDFcdTg4REQgdHJhbnNsZXQgXHU5ODVFXHU1MjI1XHU2MjEwXHU3MEJBIGphciBcdTZBOTRcdTY4NDhcdUZGMENcbiAgICAgICAgICAgICAgICAgIFx1NTQwRFx1N0EzMVx1NjMwN1x1NUI5QVx1NzBCQSA8amFyZmlsZT5cbiAgIC1wIDxwYWNrYWdlPiAgIFx1NjMwN1x1NUI5QVx1NjI0MFx1NjcwOVx1NzUyMlx1NzUxRlx1NzY4NCB0cmFuc2xldCBcdTk4NUVcdTUyMjVcdTc2ODRcdTU5NTdcdTg4RERcdTdBMEJcdTVGMEZcbiAgICAgICAgICAgICAgICAgIFx1NTQwRFx1N0EzMVx1NTI0RFx1N0Y2RVx1NzhCQ1x1MzAwMlxuICAgLW4gICAgICAgICAgICAgXHU1NTVGXHU3NTI4XHU2QTIzXHU2NzdGXHU1MTY3XHU1RDRDIChcdTk4MTBcdThBMkRcdTg4NENcdTcwQkFcdTRFMDBcdTgyMkNcdTgwMENcdThBMDBcbiAgICAgICAgICAgICAgICAgIFx1OEYwM1x1NEY3MylcdTMwMDJcbiAgIC14ICAgICAgICAgICAgIFx1OTU4Qlx1NTU1Rlx1OTg0RFx1NTkxNlx1NzY4NFx1OTY2NFx1OTMyRlx1OEEwQVx1NjA2Rlx1OEYzOFx1NTFGQVxuICAgLXUgICAgICAgICAgICAgXHU4OUUzXHU4QjZGIDxzdHlsZXNoZWV0PiBcdTVGMTVcdTY1NzhcdTcwQkEgVVJMXG4gICAtaSAgICAgICAgICAgICBcdTVGMzdcdTUyMzZcdTdERThcdThCNkZcdTU2NjhcdTVGOUUgc3RkaW4gXHU4QjgwXHU1M0Q2XHU2QTIzXHU1RjBGXHU4ODY4XG4gICAtdiAgICAgICAgICAgICBcdTUyMTdcdTUzNzBcdTdERThcdThCNkZcdTU2NjhcdTcyNDhcdTY3MkNcbiAgIC1oICAgICAgICAgICAgIFx1NTIxN1x1NTM3MFx1NkI2NFx1NzUyOFx1NkNENVx1NjU1OFx1OEZGMFxuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBjb250YWlucyB1c2FnZSBpbmZvcm1hdGlvbiBmb3IgYQotICAgICAgICAgKiBtZWFucyBvZiBpbnZva2luZyBYU0xUQyBmcm9tIHRoZSBjb21tYW5kLWxpbmUuICBUaGUgbWVzc2FnZSBpcwotICAgICAgICAgKiBmb3JtYXR0ZWQgZm9yIHByZXNlbnRhdGlvbiBpbiBFbmdsaXNoLiAgVGhlIHN0cmluZ3MgPGphcmZpbGU+LAotICAgICAgICAgKiA8ZG9jdW1lbnQ+LCBldGMuIGluZGljYXRlIHVzZXItc3BlY2lmaWVkIGFyZ3VtZW50IHZhbHVlcywgYW5kIGNhbgotICAgICAgICAgKiBiZSB0cmFuc2xhdGVkIC0gdGhlIGFyZ3VtZW50IDxjbGFzcz4gcmVmZXJzIHRvIGEgSmF2YSBjbGFzcywgc28gaXQKLSAgICAgICAgICogc2hvdWxkIGJlIGhhbmRsZWQgaW4gdGhlIHNhbWUgd2F5IHRoZSB0ZXJtIGlzIGhhbmRsZWQgZm9yIEpESwotICAgICAgICAgKiBkb2N1bWVudGF0aW9uLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlRSQU5TRk9STV9VU0FHRV9TVFIsCi0gICAgICAgICJcdTY5ODJcdTg5ODEgXG4gICBqYXZhIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jbWRsaW5lLlRyYW5zZm9ybSBbLWogPGphcmZpbGU+XVxuICAgICAgWy14XSBbLW4gPGl0ZXJhdGlvbnM+XSB7LXUgPGRvY3VtZW50X3VybD4gfCA8ZG9jdW1lbnQ+fVxuICAgICAgPGNsYXNzPiBbPHBhcmFtMT49PHZhbHVlMT4gLi4uXVxuXG4gICBcdTRGN0ZcdTc1MjggdHJhbnNsZXQgPGNsYXNzPiBcdThGNDlcdTYzREJcdTYzMDdcdTVCOUFcdTcwQkEgPGRvY3VtZW50PiBcbiAgIFx1NzY4NCBYTUwgXHU2NTg3XHU0RUY2XHUzMDAydHJhbnNsZXQgPGNsYXNzPiBcdTRGNERcdTY1QkNcbiAgIFx1NEY3Rlx1NzUyOFx1ODAwNVx1NzY4NFx1OTg1RVx1NTIyNVx1OERFRlx1NUY5MVx1RkYwQ1x1NjIxNlx1NjYyRlx1NTcyOFx1OTA3OFx1NjRDN1x1NjAyN1x1NjMwN1x1NUI5QVx1NzY4NCA8amFyZmlsZT4gXHU0RTJEXHUzMDAyXG5cdTkwNzhcdTk4MDVcbiAgIC1qIDxqYXJmaWxlPiAgICBcdTYzMDdcdTVCOUFcdThGMDlcdTUxNjUgdHJhbnNsZXQgXHU3Njg0XHU0Rjg2XHU2RTkwIGphcmZpbGVcbiAgIC14ICAgICAgICAgICAgICBcdTk1OEJcdTU1NUZcdTk4NERcdTU5MTZcdTc2ODRcdTk2NjRcdTkzMkZcdThBMEFcdTYwNkZcdThGMzhcdTUxRkFcbiAgIC1uIDxpdGVyYXRpb25zPiBcdTU3RjdcdTg4NENcdThGNDlcdTYzREIgPGl0ZXJhdGlvbnM+IFx1NkIyMVx1NjU3OFx1ODIwN1xuICAgICAgICAgICAgICAgICAgIFx1OTg2Rlx1NzkzQVx1NTIwNlx1Njc5MFx1OENDN1x1OEEwQVxuICAgLXUgPGRvY3VtZW50X3VybD4gXHU2MzA3XHU1QjlBIFhNTCBcdThGMzhcdTUxNjVcdTY1ODdcdTRFRjZcdTcwQkEgVVJMXG4ifSwKLQotCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogICI8eHNsOnNvcnQ+IiwgIjx4c2w6Zm9yLWVhY2g+IiBhbmQKLSAgICAgICAgICogIjx4c2w6YXBwbHktdGVtcGxhdGVzPiIgYXJlIGtleXdvcmRzIHRoYXQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLgotICAgICAgICAgKiBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCBhbiB4c2w6c29ydCBlbGVtZW50IG11c3QgYmUgYSBjaGlsZCBvZgotICAgICAgICAgKiBvbmUgb2YgdGhlIG90aGVyIGtpbmRzIG9mIGVsZW1lbnRzIG1lbnRpb25lZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5TVFJBWV9TT1JUX0VSUiwKLSAgICAgICAgIjx4c2w6c29ydD4gXHU1M0VBXHU4MEZEXHU1NzI4IDx4c2w6Zm9yLWVhY2g+IFx1NjIxNiA8eHNsOmFwcGx5LXRlbXBsYXRlcz4gXHU0RTJEXHU0RjdGXHU3NTI4XHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoZSBlbmNvZGluZwotICAgICAgICAgKiByZXF1ZXN0ZWQgZm9yIHRoZSBvdXRwdXQgZG9jdW1lbnQgd2FzIG9uIHRoYXQgcmVxdWlyZXMgc3VwcG9ydCB0aGF0Ci0gICAgICAgICAqIGlzIG5vdCBhdmFpbGFibGUgZnJvbSB0aGUgSmF2YSBWaXJ0dWFsIE1hY2hpbmUgYmVpbmcgdXNlZCB0byBleGVjdXRlCi0gICAgICAgICAqIHRoZSBwcm9ncmFtLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlVOU1VQUE9SVEVEX0VOQ09ESU5HLAotICAgICAgICAiXHU2QjY0IEpWTSBcdTRFMERcdTY1MkZcdTYzRjRcdThGMzhcdTUxRkFcdTdERThcdTc4QkMgJyd7MH0nJ1x1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUgWFBhdGggZXhwcmVzc2lvbgotICAgICAgICAgKiBuYW1lZCBpbiB0aGUgc3Vic3RpdHV0aW9uIHRleHQgd2FzIG5vdCB3ZWxsIGZvcm1lZCBzeW50YWN0aWNhbGx5LgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLlNZTlRBWF9FUlIsCi0gICAgICAgICInJ3swfScnIFx1NEUyRFx1NzY4NFx1OEE5RVx1NkNENVx1OTMyRlx1OEFBNFx1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYSBKYXZhCi0gICAgICAgICAqIGNsYXNzLiAgVGhlIHRlcm0gImNvbnN0cnVjdG9yIiBoZXJlIGlzIHRoZSBKYXZhIHRlcm0uICBUaGUgbWVzc2FnZSBpcwotICAgICAgICAgKiBkaXNwbGF5ZWQgaWYgWFNMVEMgY291bGQgbm90IGZpbmQgYSBjb25zdHJ1Y3RvciBmb3IgdGhlIHNwZWNpZmllZAotICAgICAgICAgKiBjbGFzcy4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5DT05TVFJVQ1RPUl9OT1RfRk9VTkQsCi0gICAgICAgICJcdTYyN0VcdTRFMERcdTUyMzBcdTU5MTZcdTkwRThcdTVFRkFcdTY5Q0JcdTVCNTAgJyd7MH0nJ1x1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICAic3RhdGljIiBpcyB0aGUgSmF2YSBrZXl3b3JkLiAgVGhlIHN1YnN0aXR1dGlvbgotICAgICAgICAgKiB0ZXh0IGlzIHRoZSBuYW1lIG9mIGEgZnVuY3Rpb24uICBUaGUgZmlyc3QgYXJndW1lbnQgb2YgdGhhdCBmdW5jdGlvbgotICAgICAgICAgKiBpcyBub3Qgb2YgdGhlIHJlcXVpcmVkIHR5cGUuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuTk9fSkFWQV9GVU5DVF9USElTX1JFRiwKLSAgICAgICAgIlx1OTc1RVx1OTc1Q1x1NjE0QiBKYXZhIFx1NTFGRFx1NjU3OCAnJ3swfScnIFx1NzY4NFx1N0IyQ1x1NEUwMFx1NTAwQlx1NUYxNVx1NjU3OFx1NEUwRFx1NjYyRlx1NjcwOVx1NjU0OFx1NzY4NFx1NzI2OVx1NEVGNlx1NTNDM1x1NzE2N1x1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBbiBYUGF0aCBleHByZXNzaW9uIHdhcyBub3Qgb2YgdGhlIHR5cGUKLSAgICAgICAgICogcmVxdWlyZWQgaW4gYSBwYXJ0aWN1bGFyIGNvbnRleHQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlCi0gICAgICAgICAqIGV4cHJlc3Npb24gdGhhdCB3YXMgaW4gZXJyb3IuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVFlQRV9DSEVDS19FUlIsCi0gICAgICAgICJcdTZBQTJcdTY3RTVcdTg4NjhcdTc5M0FcdTVGMEYgJyd7MH0nJyBcdTc2ODRcdTk4NUVcdTU3OEJcdTY2NDJcdTc2N0NcdTc1MUZcdTkzMkZcdThBQTRcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQW4gWFBhdGggZXhwcmVzc2lvbiB3YXMgbm90IG9mIHRoZSB0eXBlCi0gICAgICAgICAqIHJlcXVpcmVkIGluIGEgcGFydGljdWxhciBjb250ZXh0LiAgSG93ZXZlciwgdGhlIGxvY2F0aW9uIG9mIHRoZQotICAgICAgICAgKiBwcm9ibGVtYXRpYyBleHByZXNzaW9uIGlzIHVua25vd24uCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVFlQRV9DSEVDS19VTktfTE9DX0VSUiwKLSAgICAgICAgIlx1NkFBMlx1NjdFNVx1NEY0RFx1NjVCQ1x1NEUwRFx1NjYwRVx1NEY0RFx1N0Y2RVx1ODg2OFx1NzkzQVx1NUYwRlx1NzY4NFx1OTg1RVx1NTc4Qlx1NjY0Mlx1NzY3Q1x1NzUxRlx1OTMyRlx1OEFBNFx1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYSBjb21tYW5kLQotICAgICAgICAgKiBsaW5lIG9wdGlvbiB0aGF0IHdhcyBub3QgcmVjb2duaXplZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTExFR0FMX0NNRExJTkVfT1BUSU9OX0VSUiwKLSAgICAgICAgIlx1NTQ3RFx1NEVFNFx1ODg0Q1x1OTA3OFx1OTgwNSAnJ3swfScnIFx1NzEyMVx1NjU0OFx1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYSBjb21tYW5kLQotICAgICAgICAgKiBsaW5lIG9wdGlvbi4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5DTURMSU5FX09QVF9NSVNTSU5HX0FSR19FUlIsCi0gICAgICAgICJcdTU0N0RcdTRFRTRcdTg4NENcdTkwNzhcdTk4MDUgJyd7MH0nJyBcdTkwN0FcdTZGMEZcdTVGQzVcdTg5ODFcdTc2ODRcdTVGMTVcdTY1NzhcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIHVzZWQgdG8gaW5kaWNhdGUgdGhlIHNldmVyaXR5Ci0gICAgICAgICAqIG9mIGFub3RoZXIgbWVzc2FnZS4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBjb250YWlucyB0d28gZXJyb3IKLSAgICAgICAgICogbWVzc2FnZXMuICBUaGUgc3BhY2luZyBiZWZvcmUgdGhlIHNlY29uZCBzdWJzdGl0dXRpb24gdGV4dCBpbmRlbnRzCi0gICAgICAgICAqIGl0IHRoZSBzYW1lIGFtb3VudCBhcyB0aGUgZmlyc3QgaW4gRW5nbGlzaC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5XQVJOSU5HX1BMVVNfV1JBUFBFRF9NU0csCi0gICAgICAgICJXQVJOSU5HOiAgJyd7MH0nJ1xuICAgICAgIDp7MX0ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIHVzZWQgdG8gaW5kaWNhdGUgdGhlIHNldmVyaXR5Ci0gICAgICAgICAqIG9mIGFub3RoZXIgbWVzc2FnZS4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyBhbiBlcnJvciBtZXNzYWdlLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLldBUk5JTkdfTVNHLAotICAgICAgICAiV0FSTklORzogICcnezB9JycifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIHVzZWQgdG8gaW5kaWNhdGUgdGhlIHNldmVyaXR5Ci0gICAgICAgICAqIG9mIGFub3RoZXIgbWVzc2FnZS4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBjb250YWlucyB0d28gZXJyb3IKLSAgICAgICAgICogbWVzc2FnZXMuICBUaGUgc3BhY2luZyBiZWZvcmUgdGhlIHNlY29uZCBzdWJzdGl0dXRpb24gdGV4dCBpbmRlbnRzCi0gICAgICAgICAqIGl0IHRoZSBzYW1lIGFtb3VudCBhcyB0aGUgZmlyc3QgaW4gRW5nbGlzaC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5GQVRBTF9FUlJfUExVU19XUkFQUEVEX01TRywKLSAgICAgICAgIkZBVEFMIEVSUk9SOiAgJyd7MH0nJ1xuICAgICAgICAgICA6ezF9In0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyB1c2VkIHRvIGluZGljYXRlIHRoZSBzZXZlcml0eQotICAgICAgICAgKiBvZiBhbm90aGVyIG1lc3NhZ2UuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgYW4gZXJyb3IgbWVzc2FnZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5GQVRBTF9FUlJfTVNHLAotICAgICAgICAiRkFUQUwgRVJST1I6ICAnJ3swfScnIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyB1c2VkIHRvIGluZGljYXRlIHRoZSBzZXZlcml0eQotICAgICAgICAgKiBvZiBhbm90aGVyIG1lc3NhZ2UuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgY29udGFpbnMgdHdvIGVycm9yCi0gICAgICAgICAqIG1lc3NhZ2VzLiAgVGhlIHNwYWNpbmcgYmVmb3JlIHRoZSBzZWNvbmQgc3Vic3RpdHV0aW9uIHRleHQgaW5kZW50cwotICAgICAgICAgKiBpdCB0aGUgc2FtZSBhbW91bnQgYXMgdGhlIGZpcnN0IGluIEVuZ2xpc2guCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuRVJST1JfUExVU19XUkFQUEVEX01TRywKLSAgICAgICAgIkVSUk9SOiAgJyd7MH0nJ1xuICAgICA6ezF9In0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyB1c2VkIHRvIGluZGljYXRlIHRoZSBzZXZlcml0eQotICAgICAgICAgKiBvZiBhbm90aGVyIG1lc3NhZ2UuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgYW4gZXJyb3IgbWVzc2FnZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5FUlJPUl9NU0csCi0gICAgICAgICJFUlJPUjogICcnezB9JycifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIGEgY2xhc3MuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVFJBTlNGT1JNX1dJVEhfVFJBTlNMRVRfU1RSLAotICAgICAgICAiXHU0RjdGXHU3NTI4IHRyYW5zbGV0ICcnezB9JycgXHU4RjQ5XHU2M0RCIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmaXJzdCBzdWJzdGl0dXRpb24gaXMgdGhlIG5hbWUgb2YgYSBjbGFzcywKLSAgICAgICAgICogd2hpbGUgdGhlIHNlY29uZCBzdWJzdGl0dXRpb24gaXMgdGhlIG5hbWUgb2YgYSBqYXIgZmlsZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5UUkFOU0ZPUk1fV0lUSF9KQVJfU1RSLAotICAgICAgICAiXHU0RjdGXHU3NTI4XHU0Rjg2XHU4MUVBIGphciBcdTZBOTRcdTY4NDggJyd7MX0nJyBcdTc2ODQgdHJhbnNsZXQgJyd7MH0nJyBcdThGNDlcdTYzREIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgIlRyYW5zZm9ybWVyRmFjdG9yeSIgaXMgdGhlIG5hbWUgb2YgYSBKYXZhCi0gICAgICAgICAqIGludGVyZmFjZSBhbmQgbXVzdCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcwotICAgICAgICAgKiB0aGUgbmFtZSBvZiB0aGUgY2xhc3MgdGhhdCBjb3VsZCBub3QgYmUgaW5zdGFudGlhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLkNPVUxEX05PVF9DUkVBVEVfVFJBTlNfRkFDVCwKLSAgICAgICAgIlx1NzEyMVx1NkNENVx1NUVGQVx1N0FDQiBUcmFuc2Zvcm1lckZhY3RvcnkgXHU5ODVFXHU1MjI1ICcnezB9JycgXHU3Njg0XHU1N0Y3XHU4ODRDXHU4NjU1XHU3NDA2XHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyBwcm9kdWNlZCB3aGVuIHRoZSB1c2VyCi0gICAgICAgICAqIHNwZWNpZmllZCBhIG5hbWUgZm9yIHRoZSB0cmFuc2xldCBjbGFzcyB0aGF0IGNvbnRhaW5zIGNoYXJhY3RlcnMKLSAgICAgICAgICogdGhhdCBhcmUgbm90IHBlcm1pdHRlZCBpbiBhIEphdmEgY2xhc3MgbmFtZS4gIFRoZSBzdWJzdGl0dXRpb24KLSAgICAgICAgICogdGV4dCAiezB9IiBzcGVjaWZpZXMgdGhlIG5hbWUgdGhlIHVzZXIgcmVxdWVzdGVkLCB3aGlsZSAiezF9IgotICAgICAgICAgKiBzcGVjaWZpZXMgdGhlIG5hbWUgdGhlIHByb2Nlc3NvciB1c2VkIGluc3RlYWQuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuVFJBTlNMRVRfTkFNRV9KQVZBX0NPTkZMSUNULAotICAgICAgICAgIlx1NTQwRFx1N0EzMSAnJ3swfScnIFx1NzEyMVx1NkNENVx1NEY1Q1x1NzBCQSB0cmFuc2xldCBcdTk4NUVcdTUyMjVcdTc2ODRcdTU0MERcdTdBMzFcdUZGMENcdTU2RTBcdTcwQkFcdTVCODNcdTUzMDVcdTU0MkIgSmF2YSBcdTk4NUVcdTUyMjVcdTU0MERcdTdBMzFcdTRFMERcdTUxNDFcdThBMzFcdTc2ODRcdTVCNTdcdTUxNDNcdTMwMDJcdThBQ0JcdTY1MzlcdTc1MjhcdTU0MERcdTdBMzEgJyd7MX0nJ1x1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgaXMgdXNlZCBhcyBhIGhlYWRlci4KLSAgICAgICAgICogQWxsIHRoZSBlcnJvciBtZXNzYWdlcyBhcmUgY29sbGVjdGVkIHRvZ2V0aGVyIGFuZCBkaXNwbGF5ZWQgYmVuZWF0aAotICAgICAgICAgKiB0aGlzIG1lc3NhZ2UuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuQ09NUElMRVJfRVJST1JfS0VZLAotICAgICAgICAiXHU3REU4XHU4QjZGXHU1NjY4XHU5MzJGXHU4QUE0OiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgaXMgdXNlZCBhcyBhIGhlYWRlci4KLSAgICAgICAgICogQWxsIHRoZSB3YXJuaW5nIG1lc3NhZ2VzIGFyZSBjb2xsZWN0ZWQgdG9nZXRoZXIgYW5kIGRpc3BsYXllZAotICAgICAgICAgKiBiZW5lYXRoIHRoaXMgbWVzc2FnZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5DT01QSUxFUl9XQVJOSU5HX0tFWSwKLSAgICAgICAgIlx1N0RFOFx1OEI2Rlx1NTY2OFx1OEI2Nlx1NTQ0QToifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIGlzIHVzZWQgYXMgYSBoZWFkZXIuCi0gICAgICAgICAqIEFsbCB0aGUgZXJyb3IgbWVzc2FnZXMgdGhhdCBhcmUgcHJvZHVjZWQgd2hlbiB0aGUgc3R5bGVzaGVldCBpcwotICAgICAgICAgKiBhcHBsaWVkIHRvIGFuIGlucHV0IGRvY3VtZW50IGFyZSBjb2xsZWN0ZWQgdG9nZXRoZXIgYW5kIGRpc3BsYXllZAotICAgICAgICAgKiBiZW5lYXRoIHRoaXMgbWVzc2FnZS4gIEEgJ3RyYW5zbGV0JyBpcyB0aGUgY29tcGlsZWQgZm9ybSBvZiBhCi0gICAgICAgICAqIHN0eWxlc2hlZXQgKHNlZSBhYm92ZSkuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuUlVOVElNRV9FUlJPUl9LRVksCi0gICAgICAgICJUcmFuc2xldCBcdTkzMkZcdThBQTQ6In0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIGF0dHJpYnV0ZSB3aG9zZSB2YWx1ZSBpcyBjb25zdHJhaW5lZCB0bwotICAgICAgICAgKiBiZSBhICJRTmFtZSIgb3IgYSBsaXN0IG9mICJRTmFtZXMiIGhhZCBhIHZhbHVlIHRoYXQgd2FzIGluY29ycmVjdC4KLSAgICAgICAgICogJ1FOYW1lJyBpcyBhbiBYTUwgc3ludGFjdGljIHRlcm0gdGhhdCBtdXN0IG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhlCi0gICAgICAgICAqIHN1YnN0aXR1dGlvbiB0ZXh0IGNvbnRhaW5zIHRoZSBhY3R1YWwgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5JTlZBTElEX1FOQU1FX0VSUiwKLSAgICAgICAgIlx1NTAzQ1x1NUZDNVx1OTgwOFx1NzBCQSBRTmFtZSBcdTYyMTZcdTRGN0ZcdTc1MjhcdTdBN0FcdTY4M0NcdTUyQTBcdTRFRTVcdTUzNDBcdTk2OTRcdTc2ODQgUU5hbWVzIFx1NkUwNVx1NTVBRVx1NzY4NFx1NUM2Q1x1NjAyN1x1RkYwQ1x1NTE3N1x1NjcwOVx1NTAzQyAnJ3swfScnIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIGF0dHJpYnV0ZSB3aG9zZSB2YWx1ZSBpcyByZXF1aXJlZCB0bwotICAgICAgICAgKiBiZSBhbiAiTkNOYW1lIi4KLSAgICAgICAgICogJ05DTmFtZScgaXMgYW4gWE1MIHN5bnRhY3RpYyB0ZXJtIHRoYXQgbXVzdCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoZQotICAgICAgICAgKiBzdWJzdGl0dXRpb24gdGV4dCBjb250YWlucyB0aGUgYWN0dWFsIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSU5WQUxJRF9OQ05BTUVfRVJSLAotICAgICAgICAiXHU1MDNDXHU1RkM1XHU5ODA4XHU3MEJBIE5DTmFtZSBcdTc2ODRcdTVDNkNcdTYwMjdcdUZGMENcdTUxNzdcdTY3MDlcdTUwM0MgJyd7MH0nJyJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBbiBhdHRyaWJ1dGUgd2l0aCBhbiBpbmNvcnJlY3QgdmFsdWUgd2FzCi0gICAgICAgICAqIGVuY291bnRlcmVkLiAgVGhlIHBlcm1pdHRlZCB2YWx1ZSBpcyBvbmUgb2YgdGhlIGxpdGVyYWwgdmFsdWVzCi0gICAgICAgICAqICJ4bWwiLCAiaHRtbCIgb3IgInRleHQiOyBpdCBpcyBhbHNvIHBlcm1pdHRlZCB0byBoYXZlIHRoZSBmb3JtIG9mCi0gICAgICAgICAqIGEgUU5hbWUgdGhhdCBpcyBub3QgYWxzbyBhbiBOQ05hbWUuICBUaGUgdGVybXMgIm1ldGhvZCIsCi0gICAgICAgICAqICJ4c2w6b3V0cHV0IiwgInhtbCIsICJodG1sIiBhbmQgInRleHQiIGFyZSBrZXl3b3JkcyB0aGF0IG11c3Qgbm90Ci0gICAgICAgICAqIGJlIHRyYW5zbGF0ZWQuICBUaGUgdGVybSAicW5hbWUtYnV0LW5vdC1uY25hbWUiIGlzIGFuIFhNTCBzeW50YWN0aWMKLSAgICAgICAgICogdGVybS4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBjb250YWlucyB0aGUgYWN0dWFsIHZhbHVlIG9mIHRoZQotICAgICAgICAgKiBhdHRyaWJ1dGUuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuSU5WQUxJRF9NRVRIT0RfSU5fT1VUUFVULAotICAgICAgICAiPHhzbDpvdXRwdXQ+IFx1NTE0M1x1N0QyMFx1NzY4NFx1NjVCOVx1NkNENVx1NUM2Q1x1NjAyN1x1NTE3N1x1NjcwOVx1NTAzQyAnJ3swfScnXHUzMDAyXHU2QjY0XHU1MDNDXHU1RkM1XHU5ODA4XHU2NjJGICcneG1sJydcdTMwMDEnJ2h0bWwnJ1x1MzAwMScndGV4dCcnIFx1NjIxNiBxbmFtZS1idXQtbm90LW5jbmFtZSBcdTUxNzZcdTRFMkRcdTRFNEJcdTRFMDAifSwKLQotICAgICAgICB7RXJyb3JNc2cuSkFYUF9HRVRfRkVBVFVSRV9OVUxMX05BTUUsCi0gICAgICAgICJUcmFuc2Zvcm1lckZhY3RvcnkuZ2V0RmVhdHVyZShcdTVCNTdcdTRFMzJcdTU0MERcdTdBMzEpIFx1NEUyRFx1NzY4NFx1NTI5Rlx1ODBGRFx1NTQwRFx1N0EzMVx1NEUwRFx1NTNFRlx1NzBCQVx1N0E3QVx1NTAzQ1x1MzAwMiJ9LAotCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX1NFVF9GRUFUVVJFX05VTExfTkFNRSwKLSAgICAgICAgIlRyYW5zZm9ybWVyRmFjdG9yeS5zZXRGZWF0dXJlKFx1NUI1N1x1NEUzMlx1NTQwRFx1N0EzMSwgXHU1RTAzXHU2Nzk3XHU1MDNDKSBcdTRFMkRcdTc2ODRcdTUyOUZcdTgwRkRcdTU0MERcdTdBMzFcdTRFMERcdTUzRUZcdTcwQkFcdTdBN0FcdTUwM0NcdTMwMDIifSwKLQotICAgICAgICB7RXJyb3JNc2cuSkFYUF9VTlNVUFBPUlRFRF9GRUFUVVJFLAotICAgICAgICAiXHU3MTIxXHU2Q0Q1XHU1NzI4XHU2QjY0IFRyYW5zZm9ybWVyRmFjdG9yeSBcdTRFMEFcdThBMkRcdTVCOUFcdTUyOUZcdTgwRkQgJyd7MH0nJ1x1MzAwMiJ9LAotCi0gICAgICAgIHtFcnJvck1zZy5KQVhQX1NFQ1VSRVBST0NFU1NJTkdfRkVBVFVSRSwKLSAgICAgICAgIkZFQVRVUkVfU0VDVVJFX1BST0NFU1NJTkc6IFx1NUI4OVx1NTE2OFx1N0JBMVx1NzQwNlx1N0EwQlx1NUYwRlx1NUI1OFx1NTcyOFx1NjY0Mlx1RkYwQ1x1NzEyMVx1NkNENVx1NUMwN1x1NTI5Rlx1ODBGRFx1OEEyRFx1NzBCQVx1NTA3RFx1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgZGVzY3JpYmVzIGFuIGludGVybmFsIGVycm9yIGluIHRoZQotICAgICAgICAgKiBwcm9jZXNzb3IuICBUaGUgdGVybSAiYnl0ZSBjb2RlIiBpcyBhIEphdmEgdGVjaG5pY2FsIHRlcm0gZm9yIHRoZQotICAgICAgICAgKiBleGVjdXRhYmxlIGNvZGUgaW4gYSBKYXZhIG1ldGhvZCwgYW5kICJ0cnktY2F0Y2gtZmluYWxseSBibG9jayIKLSAgICAgICAgICogcmVmZXJzIHRvIHRoZSBKYXZhIGtleXdvcmRzIHdpdGggdGhvc2UgbmFtZXMuICAiT3V0bGluZWQiIGlzIGEKLSAgICAgICAgICogdGVjaG5pY2FsIHRlcm0gaW50ZXJuYWwgdG8gWFNMVEMgYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5PVVRMSU5FX0VSUl9UUllfQ0FUQ0gsCi0gICAgICAgICAiXHU1MTY3XHU5MEU4IFhTTFRDIFx1OTMyRlx1OEFBNDogIFx1NzUyMlx1NzUxRlx1NzY4NFx1NEY0RFx1NTE0M1x1N0Q0NFx1NzhCQ1x1NTMwNVx1NTQyQiB0cnktY2F0Y2gtZmluYWxseSBcdTUzNDBcdTU4NEFcdUZGMENcdTcxMjFcdTZDRDVcdTUyQTBcdTRFRTUgb3V0bGluZWQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBkZXNjcmliZXMgYW4gaW50ZXJuYWwgZXJyb3IgaW4gdGhlCi0gICAgICAgICAqIHByb2Nlc3Nvci4gIFRoZSB0ZXJtcyAiT3V0bGluZWFibGVDaHVua1N0YXJ0IiBhbmQKLSAgICAgICAgICogIk91dGxpbmVhYmxlQ2h1bmtFbmQiIGFyZSB0aGUgbmFtZXMgb2YgY2xhc3NlcyBpbnRlcm5hbCB0byBYU0xUQyBhbmQKLSAgICAgICAgICogc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgZm9yIGV2ZXJ5Ci0gICAgICAgICAqICJzdGFydCIgdGhlcmUgbXVzdCBiZSBhIGNvcnJlc3BvbmRpbmcgImVuZCIsIGFuZCB2aWNlIHZlcnNhLCBhbmQKLSAgICAgICAgICogdGhhdCBpZiBvbmUgb2YgYSBwYWlyIG9mICJzdGFydCIgYW5kICJlbmQiIGFwcGVhcnMgYmV0d2VlbiBhbm90aGVyCi0gICAgICAgICAqIHBhaXIgb2YgY29ycmVzcG9uZGluZyAic3RhcnQiIGFuZCAiZW5kIiwgdGhlbiB0aGUgb3RoZXIgaGFsZiBvZiB0aGUKLSAgICAgICAgICogcGFpciBtdXN0IGFsc28gYmUgYmV0d2VlbiB0aGF0IHNhbWUgZW5jbG9zaW5nIHBhaXIuCi0gICAgICAgICAqLwotICAgICAgICB7RXJyb3JNc2cuT1VUTElORV9FUlJfVU5CQUxBTkNFRF9NQVJLRVJTLAotICAgICAgICAgIlx1NTE2N1x1OTBFOCBYU0xUQyBcdTkzMkZcdThBQTQ6ICBPdXRsaW5lYWJsZUNodW5rU3RhcnQgXHU1NDhDIE91dGxpbmVhYmxlQ2h1bmtFbmQgXHU2QTE5XHU4QTE4XHU1RkM1XHU5ODA4XHU2MjEwXHU1QzBEXHU1MUZBXHU3M0ZFXHVGRjBDXHU0RTI2XHU0RjdGXHU3NTI4XHU2QjYzXHU3OEJBXHU3Njg0XHU1REUyXHU3MkMwXHU3RDUwXHU2OUNCXHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBkZXNjcmliZXMgYW4gaW50ZXJuYWwgZXJyb3IgaW4gdGhlCi0gICAgICAgICAqIHByb2Nlc3Nvci4gIFRoZSB0ZXJtICJieXRlIGNvZGUiIGlzIGEgSmF2YSB0ZWNobmljYWwgdGVybSBmb3IgdGhlCi0gICAgICAgICAqIGV4ZWN1dGFibGUgY29kZSBpbiBhIEphdmEgbWV0aG9kLiAgVGhlICJtZXRob2QiIHRoYXQgaXMgYmVpbmcKLSAgICAgICAgICogcmVmZXJyZWQgdG8gaXMgYSBKYXZhIG1ldGhvZCBpbiBhIHRyYW5zbGV0IHRoYXQgWFNMVEMgaXMgZ2VuZXJhdGluZwotICAgICAgICAgKiBpbiBwcm9jZXNzaW5nIGEgc3R5bGVzaGVldC4gIFRoZSAiaW5zdHJ1Y3Rpb24iIHRoYXQgaXMgYmVpbmcKLSAgICAgICAgICogcmVmZXJyZWQgdG8gaXMgb25lIG9mIHRoZSBpbnN0cnV0aW9ucyBpbiB0aGUgSmF2YSBieXRlIGNvZGUgaW4gdGhhdAotICAgICAgICAgKiBtZXRob2QuICAiT3V0bGluZWQiIGlzIGEgdGVjaG5pY2FsIHRlcm0gaW50ZXJuYWwgdG8gWFNMVEMgYW5kCi0gICAgICAgICAqIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtFcnJvck1zZy5PVVRMSU5FX0VSUl9ERUxFVEVEX1RBUkdFVCwKLSAgICAgICAgICJcdTUxNjdcdTkwRTggWFNMVEMgXHU5MzJGXHU4QUE0OiAgXHU1MzlGXHU1OUNCXHU2NUI5XHU2Q0Q1XHU0RTJEXHU0RUNEXHU3MTM2XHU1M0MzXHU3MTY3XHU1QzZDXHU2NUJDIG91dGxpbmVkIFx1NEY0RFx1NTE0M1x1N0Q0NFx1NzhCQ1x1NTM0MFx1NTg0QVx1NEUwMFx1OTBFOFx1NTIwNlx1NzY4NFx1NjMwN1x1NzkzQVx1MzAwMiIKLSAgICAgICAgfSwKLQotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgZGVzY3JpYmVzIGFuIGludGVybmFsIGVycm9yIGluIHRoZQotICAgICAgICAgKiBwcm9jZXNzb3IuICBUaGUgIm1ldGhvZCIgdGhhdCBpcyBiZWluZyByZWZlcnJlZCB0byBpcyBhIEphdmEgbWV0aG9kCi0gICAgICAgICAqIGluIGEgdHJhbnNsZXQgdGhhdCBYU0xUQyBpcyBnZW5lcmF0aW5nLgotICAgICAgICAgKgotICAgICAgICAgKi8KLSAgICAgICAge0Vycm9yTXNnLk9VVExJTkVfRVJSX01FVEhPRF9UT09fQklHLAotICAgICAgICAgIlx1NTE2N1x1OTBFOCBYU0xUQyBcdTkzMkZcdThBQTQ6ICB0cmFuc2xldCBcdTRFMkRcdTc2ODRcdTY1QjlcdTZDRDVcdThEODVcdTkwNEUgSmF2YSBcdTg2NUJcdTY0RUNcdTZBNUZcdTU2NjhcdTVDMERcdTY1QkNcdTY1QjlcdTZDRDVcdTk1NzdcdTVFQTYgNjQgS0IgXHU3Njg0XHU5NjUwXHU1MjM2XHUzMDAyXHU5MDE5XHU5MDFBXHU1RTM4XHU2NjJGXHU1NkUwXHU3MEJBXHU2QTIzXHU1RjBGXHU4ODY4XHU0RTJEXHU2NzA5XHU5NzVFXHU1RTM4XHU1OTI3XHU3Njg0XHU2QTIzXHU2NzdGXHUzMDAyXHU4QUNCXHU1NjE3XHU4QTY2XHU5MUNEXHU2NUIwXHU3RDQ0XHU3RTU0XHU2MEE4XHU3Njg0XHU2QTIzXHU1RjBGXHU4ODY4XHU0RUU1XHU0RjdGXHU3NTI4XHU4RjAzXHU1QzBGXHU3Njg0XHU2QTIzXHU2NzdGXHUzMDAyIgotICAgICAgICB9LAotCi0gICAgICAgICB7RXJyb3JNc2cuREVTRVJJQUxJWkVfVFJBTlNMRVRfRVJSLCAiXHU1NTVGXHU3NTI4IEphdmEgXHU1Qjg5XHU1MTY4XHU2NjQyXHVGRjBDXHU2NzAzXHU1MDVDXHU3NTI4XHU5MDg0XHU1MzlGXHU1RThGXHU1MjE3XHU1MzE2IFRlbXBsYXRlc0ltcGwgXHU3Njg0XHU2NTJGXHU2M0Y0XHUzMDAyXHU1QzA3IGpkay54bWwuZW5hYmxlVGVtcGxhdGVzSW1wbERlc2VyaWFsaXphdGlvbiBcdTdDRkJcdTdENzFcdTVDNkNcdTYwMjdcdThBMkRcdTcwQkFcdTc3MUZcdTUzNzNcdTUzRUZcdTg5ODZcdTVCRUJcdTZCNjRcdThBMkRcdTVCOUFcdTMwMDIifQotCi0gICAgfTsKLQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvdXRpbC9FcnJvck1zZy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci91dGlsL0Vycm9yTXNnLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDQxOTJjZjIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci91dGlsL0Vycm9yTXNnLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzMjYgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRXJyb3JNc2cuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNSAxMDoxODowMSBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbDsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC51dGlscy5TZWN1cml0eVN1cHBvcnQ7Ci1pbXBvcnQgamF2YS50ZXh0Lk1lc3NhZ2VGb3JtYXQ7Ci1pbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKLWltcG9ydCBqYXZhLnV0aWwuUmVzb3VyY2VCdW5kbGU7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIuU3R5bGVzaGVldDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIuU3ludGF4VHJlZU5vZGU7Ci0KLS8qKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICogQGF1dGhvciBHLiBUb2RkIE1pbGxlcgotICogQGF1dGhvciBFcndpbiBCb2x3aWR0IDxlamJAa2xvbXAub3JnPgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBFcnJvck1zZyB7Ci0KLSAgICBwcml2YXRlIFN0cmluZyBfY29kZTsKLSAgICBwcml2YXRlIGludCBfbGluZTsKLSAgICBwcml2YXRlIFN0cmluZyBfbWVzc2FnZSA9IG51bGw7Ci0gICAgcHJpdmF0ZSBTdHJpbmcgX3VybCA9IG51bGw7Ci0gICAgT2JqZWN0W10gX3BhcmFtcyA9IG51bGw7Ci0gICAgcHJpdmF0ZSBib29sZWFuIF9pc1dhcm5pbmdFcnJvcjsKLQotICAgIFRocm93YWJsZSBfY2F1c2U7Ci0KLSAgICAvLyBDb21waWxlciBlcnJvciBtZXNzYWdlcwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIE1VTFRJUExFX1NUWUxFU0hFRVRfRVJSID0gIk1VTFRJUExFX1NUWUxFU0hFRVRfRVJSIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBURU1QTEFURV9SRURFRl9FUlIgPSAiVEVNUExBVEVfUkVERUZfRVJSIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBURU1QTEFURV9VTkRFRl9FUlIgPSAiVEVNUExBVEVfVU5ERUZfRVJSIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBWQVJJQUJMRV9SRURFRl9FUlIgPSAiVkFSSUFCTEVfUkVERUZfRVJSIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBWQVJJQUJMRV9VTkRFRl9FUlIgPSAiVkFSSUFCTEVfVU5ERUZfRVJSIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBDTEFTU19OT1RfRk9VTkRfRVJSID0gIkNMQVNTX05PVF9GT1VORF9FUlIiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIE1FVEhPRF9OT1RfRk9VTkRfRVJSID0gIk1FVEhPRF9OT1RfRk9VTkRfRVJSIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBUkdVTUVOVF9DT05WRVJTSU9OX0VSUiA9ICJBUkdVTUVOVF9DT05WRVJTSU9OX0VSUiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRklMRV9OT1RfRk9VTkRfRVJSID0gIkZJTEVfTk9UX0ZPVU5EX0VSUiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSU5WQUxJRF9VUklfRVJSID0gIklOVkFMSURfVVJJX0VSUiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRklMRV9BQ0NFU1NfRVJSID0gIkZJTEVfQUNDRVNTX0VSUiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTUlTU0lOR19ST09UX0VSUiA9ICJNSVNTSU5HX1JPT1RfRVJSIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBOQU1FU1BBQ0VfVU5ERUZfRVJSID0gIk5BTUVTUEFDRV9VTkRFRl9FUlIiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEZVTkNUSU9OX1JFU09MVkVfRVJSID0gIkZVTkNUSU9OX1JFU09MVkVfRVJSIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBORUVEX0xJVEVSQUxfRVJSID0gIk5FRURfTElURVJBTF9FUlIiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFhQQVRIX1BBUlNFUl9FUlIgPSAiWFBBVEhfUEFSU0VSX0VSUiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgUkVRVUlSRURfQVRUUl9FUlIgPSAiUkVRVUlSRURfQVRUUl9FUlIiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIElMTEVHQUxfQ0hBUl9FUlIgPSAiSUxMRUdBTF9DSEFSX0VSUiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSUxMRUdBTF9QSV9FUlIgPSAiSUxMRUdBTF9QSV9FUlIiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFNUUkFZX0FUVFJJQlVURV9FUlIgPSAiU1RSQVlfQVRUUklCVVRFX0VSUiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSUxMRUdBTF9BVFRSSUJVVEVfRVJSID0gIklMTEVHQUxfQVRUUklCVVRFX0VSUiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ0lSQ1VMQVJfSU5DTFVERV9FUlIgPSAiQ0lSQ1VMQVJfSU5DTFVERV9FUlIiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFJFU1VMVF9UUkVFX1NPUlRfRVJSID0gIlJFU1VMVF9UUkVFX1NPUlRfRVJSIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBTWU1CT0xTX1JFREVGX0VSUiA9ICJTWU1CT0xTX1JFREVGX0VSUiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgWFNMX1ZFUlNJT05fRVJSID0gIlhTTF9WRVJTSU9OX0VSUiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ0lSQ1VMQVJfVkFSSUFCTEVfRVJSID0gIkNJUkNVTEFSX1ZBUklBQkxFX0VSUiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSUxMRUdBTF9CSU5BUllfT1BfRVJSID0gIklMTEVHQUxfQklOQVJZX09QX0VSUiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSUxMRUdBTF9BUkdfRVJSID0gIklMTEVHQUxfQVJHX0VSUiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRE9DVU1FTlRfQVJHX0VSUiA9ICJET0NVTUVOVF9BUkdfRVJSIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBNSVNTSU5HX1dIRU5fRVJSID0gIk1JU1NJTkdfV0hFTl9FUlIiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIE1VTFRJUExFX09USEVSV0lTRV9FUlIgPSAiTVVMVElQTEVfT1RIRVJXSVNFX0VSUiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1RSQVlfT1RIRVJXSVNFX0VSUiA9ICJTVFJBWV9PVEhFUldJU0VfRVJSIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBTVFJBWV9XSEVOX0VSUiA9ICJTVFJBWV9XSEVOX0VSUiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0hFTl9FTEVNRU5UX0VSUiA9ICJXSEVOX0VMRU1FTlRfRVJSIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBVTk5BTUVEX0FUVFJJQlNFVF9FUlIgPSAiVU5OQU1FRF9BVFRSSUJTRVRfRVJSIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBJTExFR0FMX0NISUxEX0VSUiA9ICJJTExFR0FMX0NISUxEX0VSUiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSUxMRUdBTF9FTEVNX05BTUVfRVJSID0gIklMTEVHQUxfRUxFTV9OQU1FX0VSUiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSUxMRUdBTF9BVFRSX05BTUVfRVJSID0gIklMTEVHQUxfQVRUUl9OQU1FX0VSUiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSUxMRUdBTF9URVhUX05PREVfRVJSID0gIklMTEVHQUxfVEVYVF9OT0RFX0VSUiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU0FYX1BBUlNFUl9DT05GSUdfRVJSID0gIlNBWF9QQVJTRVJfQ09ORklHX0VSUiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSU5URVJOQUxfRVJSID0gIklOVEVSTkFMX0VSUiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgVU5TVVBQT1JURURfWFNMX0VSUiA9ICJVTlNVUFBPUlRFRF9YU0xfRVJSIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBVTlNVUFBPUlRFRF9FWFRfRVJSID0gIlVOU1VQUE9SVEVEX0VYVF9FUlIiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIE1JU1NJTkdfWFNMVF9VUklfRVJSID0gIk1JU1NJTkdfWFNMVF9VUklfRVJSIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBNSVNTSU5HX1hTTFRfVEFSR0VUX0VSUiA9ICJNSVNTSU5HX1hTTFRfVEFSR0VUX0VSUiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQUNDRVNTSU5HX1hTTFRfVEFSR0VUX0VSUiA9ICJBQ0NFU1NJTkdfWFNMVF9UQVJHRVRfRVJSIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBOT1RfSU1QTEVNRU5URURfRVJSID0gIk5PVF9JTVBMRU1FTlRFRF9FUlIiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIE5PVF9TVFlMRVNIRUVUX0VSUiA9ICJOT1RfU1RZTEVTSEVFVF9FUlIiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVMRU1FTlRfUEFSU0VfRVJSID0gIkVMRU1FTlRfUEFSU0VfRVJSIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBLRVlfVVNFX0FUVFJfRVJSID0gIktFWV9VU0VfQVRUUl9FUlIiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIE9VVFBVVF9WRVJTSU9OX0VSUiA9ICJPVVRQVVRfVkVSU0lPTl9FUlIiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIElMTEVHQUxfUkVMQVRfT1BfRVJSID0gIklMTEVHQUxfUkVMQVRfT1BfRVJSIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRSSUJTRVRfVU5ERUZfRVJSID0gIkFUVFJJQlNFVF9VTkRFRl9FUlIiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEFUVFJfVkFMX1RFTVBMQVRFX0VSUiA9ICJBVFRSX1ZBTF9URU1QTEFURV9FUlIiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFVOS05PV05fU0lHX1RZUEVfRVJSID0gIlVOS05PV05fU0lHX1RZUEVfRVJSIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBEQVRBX0NPTlZFUlNJT05fRVJSID0gIkRBVEFfQ09OVkVSU0lPTl9FUlIiOwotCi0gICAgLy8gSkFYUC9UckFYIGVycm9yIG1lc3NhZ2VzCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTk9fVFJBTlNMRVRfQ0xBU1NfRVJSID0gIk5PX1RSQU5TTEVUX0NMQVNTX0VSUiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTk9fTUFJTl9UUkFOU0xFVF9FUlIgPSAiTk9fTUFJTl9UUkFOU0xFVF9FUlIiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFRSQU5TTEVUX0NMQVNTX0VSUiA9ICJUUkFOU0xFVF9DTEFTU19FUlIiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFRSQU5TTEVUX09CSkVDVF9FUlIgPSAiVFJBTlNMRVRfT0JKRUNUX0VSUiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJST1JfTElTVEVORVJfTlVMTF9FUlIgPSAiRVJST1JfTElTVEVORVJfTlVMTF9FUlIiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEpBWFBfVU5LTk9XTl9TT1VSQ0VfRVJSID0gIkpBWFBfVU5LTk9XTl9TT1VSQ0VfRVJSIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBKQVhQX05PX1NPVVJDRV9FUlIgPSAiSkFYUF9OT19TT1VSQ0VfRVJSIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBKQVhQX0NPTVBJTEVfRVJSID0gIkpBWFBfQ09NUElMRV9FUlIiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEpBWFBfSU5WQUxJRF9BVFRSX0VSUiA9ICJKQVhQX0lOVkFMSURfQVRUUl9FUlIiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEpBWFBfSU5WQUxJRF9BVFRSX1ZBTFVFX0VSUiA9ICJKQVhQX0lOVkFMSURfQVRUUl9WQUxVRV9FUlIiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEpBWFBfU0VUX1JFU1VMVF9FUlIgPSAiSkFYUF9TRVRfUkVTVUxUX0VSUiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSkFYUF9OT19UUkFOU0xFVF9FUlIgPSAiSkFYUF9OT19UUkFOU0xFVF9FUlIiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEpBWFBfTk9fSEFORExFUl9FUlIgPSAiSkFYUF9OT19IQU5ETEVSX0VSUiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSkFYUF9OT19SRVNVTFRfRVJSID0gIkpBWFBfTk9fUkVTVUxUX0VSUiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSkFYUF9VTktOT1dOX1BST1BfRVJSID0gIkpBWFBfVU5LTk9XTl9QUk9QX0VSUiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU0FYMkRPTV9BREFQVEVSX0VSUiA9ICJTQVgyRE9NX0FEQVBURVJfRVJSIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBYU0xUQ19TT1VSQ0VfRVJSID0gIlhTTFRDX1NPVVJDRV9FUlIiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1JFU1VMVF9OVUxMID0gIkVSX1JFU1VMVF9OVUxMIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBKQVhQX0lOVkFMSURfU0VUX1BBUkFNX1ZBTFVFID0gIkpBWFBfSU5WQUxJRF9TRVRfUEFSQU1fVkFMVUUiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEpBWFBfU0VUX0ZFQVRVUkVfTlVMTF9OQU1FID0gIkpBWFBfU0VUX0ZFQVRVUkVfTlVMTF9OQU1FIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBKQVhQX0dFVF9GRUFUVVJFX05VTExfTkFNRSA9ICJKQVhQX0dFVF9GRUFUVVJFX05VTExfTkFNRSI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSkFYUF9VTlNVUFBPUlRFRF9GRUFUVVJFID0gIkpBWFBfVU5TVVBQT1JURURfRkVBVFVSRSI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSkFYUF9TRUNVUkVQUk9DRVNTSU5HX0ZFQVRVUkUgPSAiSkFYUF9TRUNVUkVQUk9DRVNTSU5HX0ZFQVRVUkUiOwotCi0gICAgLy8gQ29tbWFuZC1saW5lIGVycm9yIG1lc3NhZ2VzCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ09NUElMRV9TVERJTl9FUlIgPSAiQ09NUElMRV9TVERJTl9FUlIiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIENPTVBJTEVfVVNBR0VfU1RSID0gIkNPTVBJTEVfVVNBR0VfU1RSIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBUUkFOU0ZPUk1fVVNBR0VfU1RSID0gIlRSQU5TRk9STV9VU0FHRV9TVFIiOwotCi0gICAgLy8gUmVjZW50bHkgYWRkZWQgZXJyb3IgbWVzc2FnZXMKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBTVFJBWV9TT1JUX0VSUiA9ICJTVFJBWV9TT1JUX0VSUiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgVU5TVVBQT1JURURfRU5DT0RJTkcgPSAiVU5TVVBQT1JURURfRU5DT0RJTkciOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFNZTlRBWF9FUlIgPSAiU1lOVEFYX0VSUiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ09OU1RSVUNUT1JfTk9UX0ZPVU5EID0gIkNPTlNUUlVDVE9SX05PVF9GT1VORCI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTk9fSkFWQV9GVU5DVF9USElTX1JFRiA9ICJOT19KQVZBX0ZVTkNUX1RISVNfUkVGIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBUWVBFX0NIRUNLX0VSUiA9ICJUWVBFX0NIRUNLX0VSUiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgVFlQRV9DSEVDS19VTktfTE9DX0VSUiA9ICJUWVBFX0NIRUNLX1VOS19MT0NfRVJSIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBJTExFR0FMX0NNRExJTkVfT1BUSU9OX0VSUiA9ICJJTExFR0FMX0NNRExJTkVfT1BUSU9OX0VSUiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ01ETElORV9PUFRfTUlTU0lOR19BUkdfRVJSID0gIkNNRExJTkVfT1BUX01JU1NJTkdfQVJHX0VSUiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0FSTklOR19QTFVTX1dSQVBQRURfTVNHID0gIldBUk5JTkdfUExVU19XUkFQUEVEX01TRyI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0FSTklOR19NU0cgPSAiV0FSTklOR19NU0ciOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEZBVEFMX0VSUl9QTFVTX1dSQVBQRURfTVNHID0gIkZBVEFMX0VSUl9QTFVTX1dSQVBQRURfTVNHIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBGQVRBTF9FUlJfTVNHID0gIkZBVEFMX0VSUl9NU0ciOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUk9SX1BMVVNfV1JBUFBFRF9NU0cgPSAiRVJST1JfUExVU19XUkFQUEVEX01TRyI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJST1JfTVNHID0gIkVSUk9SX01TRyI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgVFJBTlNGT1JNX1dJVEhfVFJBTlNMRVRfU1RSID0gIlRSQU5TRk9STV9XSVRIX1RSQU5TTEVUX1NUUiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgVFJBTlNGT1JNX1dJVEhfSkFSX1NUUiA9ICJUUkFOU0ZPUk1fV0lUSF9KQVJfU1RSIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBDT1VMRF9OT1RfQ1JFQVRFX1RSQU5TX0ZBQ1QgPSAiQ09VTERfTk9UX0NSRUFURV9UUkFOU19GQUNUIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBUUkFOU0xFVF9OQU1FX0pBVkFfQ09ORkxJQ1QgPQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJUUkFOU0xFVF9OQU1FX0pBVkFfQ09ORkxJQ1QiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIElOVkFMSURfUU5BTUVfRVJSID0gIklOVkFMSURfUU5BTUVfRVJSIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBJTlZBTElEX05DTkFNRV9FUlIgPSAiSU5WQUxJRF9OQ05BTUVfRVJSIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBJTlZBTElEX01FVEhPRF9JTl9PVVRQVVQgPSAiSU5WQUxJRF9NRVRIT0RfSU5fT1VUUFVUIjsKLQotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIE9VVExJTkVfRVJSX1RSWV9DQVRDSCA9ICJPVVRMSU5FX0VSUl9UUllfQ0FUQ0giOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIE9VVExJTkVfRVJSX1VOQkFMQU5DRURfTUFSS0VSUyA9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJPVVRMSU5FX0VSUl9VTkJBTEFOQ0VEX01BUktFUlMiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIE9VVExJTkVfRVJSX0RFTEVURURfVEFSR0VUID0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk9VVExJTkVfRVJSX0RFTEVURURfVEFSR0VUIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBPVVRMSU5FX0VSUl9NRVRIT0RfVE9PX0JJRyA9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJPVVRMSU5FX0VSUl9NRVRIT0RfVE9PX0JJRyI7Ci0KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBERVNFUklBTElaRV9UUkFOU0xFVF9FUlIgPSAiREVTRVJJQUxJWkVfVEVNUExBVEVTX0VSUiI7Ci0KLSAgICAvLyBBbGwgZXJyb3IgbWVzc2FnZXMgYXJlIGxvY2FsaXplZCBhbmQgYXJlIHN0b3JlZCBpbiByZXNvdXJjZSBidW5kbGVzLgotICAgIC8vIFRoaXMgYXJyYXkgYW5kIHRoZSBmb2xsb3dpbmcgNCBzdHJpbmdzIGFyZSByZWFkIGZyb20gdGhhdCBidW5kbGUuCi0gICAgcHJpdmF0ZSBzdGF0aWMgUmVzb3VyY2VCdW5kbGUgX2J1bmRsZTsKLQotICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgU3RyaW5nIEVSUk9SX01FU1NBR0VTX0tFWSAgID0gIkVSUk9SX01FU1NBR0VTX0tFWSI7Ci0gICAgcHVibGljIGZpbmFsIHN0YXRpYyBTdHJpbmcgQ09NUElMRVJfRVJST1JfS0VZICAgPSAiQ09NUElMRVJfRVJST1JfS0VZIjsKLSAgICBwdWJsaWMgZmluYWwgc3RhdGljIFN0cmluZyBDT01QSUxFUl9XQVJOSU5HX0tFWSA9ICJDT01QSUxFUl9XQVJOSU5HX0tFWSI7Ci0gICAgcHVibGljIGZpbmFsIHN0YXRpYyBTdHJpbmcgUlVOVElNRV9FUlJPUl9LRVkgICAgPSAiUlVOVElNRV9FUlJPUl9LRVkiOwotCi0gICAgc3RhdGljIHsKLSAgICAgICAgX2J1bmRsZSA9IFNlY3VyaXR5U3VwcG9ydC5nZXRSZXNvdXJjZUJ1bmRsZSgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgImNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkVycm9yTWVzc2FnZXMiLAotICAgICAgICAgICAgICAgICAgICAgICAgICBMb2NhbGUuZ2V0RGVmYXVsdCgpKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgRXJyb3JNc2coU3RyaW5nIGNvZGUpIHsKLSAgICAgICAgX2NvZGUgPSBjb2RlOwotICAgICAgICBfbGluZSA9IDA7Ci0gICAgfQotCi0gICAgcHVibGljIEVycm9yTXNnKFN0cmluZyBjb2RlLCBUaHJvd2FibGUgZSkgewotICAgICAgICBfY29kZSA9IGNvZGU7Ci0gICAgICAgIF9tZXNzYWdlID0gZS5nZXRNZXNzYWdlKCk7Ci0gICAgICAgIF9saW5lID0gMDsKLSAgICAgICAgX2NhdXNlID0gZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgRXJyb3JNc2coU3RyaW5nIG1lc3NhZ2UsIGludCBsaW5lKSB7Ci0gICAgICAgIF9jb2RlID0gbnVsbDsKLSAgICAgICAgX21lc3NhZ2UgPSBtZXNzYWdlOwotICAgICAgICBfbGluZSA9IGxpbmU7Ci0gICAgfQotCi0gICAgcHVibGljIEVycm9yTXNnKFN0cmluZyBjb2RlLCBpbnQgbGluZSwgT2JqZWN0IHBhcmFtKSB7Ci0gICAgICAgIF9jb2RlID0gY29kZTsKLSAgICAgICAgX2xpbmUgPSBsaW5lOwotICAgICAgICBfcGFyYW1zID0gbmV3IE9iamVjdFtdIHsgcGFyYW0gfTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgRXJyb3JNc2coU3RyaW5nIGNvZGUsIE9iamVjdCBwYXJhbSkgewotICAgICAgICB0aGlzKGNvZGUpOwotICAgICAgICBfcGFyYW1zID0gbmV3IE9iamVjdFsxXTsKLSAgICAgICAgX3BhcmFtc1swXSA9IHBhcmFtOwotICAgIH0KLQotICAgIHB1YmxpYyBFcnJvck1zZyhTdHJpbmcgY29kZSwgT2JqZWN0IHBhcmFtMSwgT2JqZWN0IHBhcmFtMikgewotICAgICAgICB0aGlzKGNvZGUpOwotICAgICAgICBfcGFyYW1zID0gbmV3IE9iamVjdFsyXTsKLSAgICAgICAgX3BhcmFtc1swXSA9IHBhcmFtMTsKLSAgICAgICAgX3BhcmFtc1sxXSA9IHBhcmFtMjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgRXJyb3JNc2coU3RyaW5nIGNvZGUsIFN5bnRheFRyZWVOb2RlIG5vZGUpIHsKLSAgICAgICAgX2NvZGUgPSBjb2RlOwotICAgICAgICBfdXJsICA9IGdldEZpbGVOYW1lKG5vZGUpOwotICAgICAgICBfbGluZSA9IG5vZGUuZ2V0TGluZU51bWJlcigpOwotICAgIH0KLQotICAgIHB1YmxpYyBFcnJvck1zZyhTdHJpbmcgY29kZSwgT2JqZWN0IHBhcmFtMSwgU3ludGF4VHJlZU5vZGUgbm9kZSkgewotICAgICAgICBfY29kZSA9IGNvZGU7Ci0gICAgICAgIF91cmwgID0gZ2V0RmlsZU5hbWUobm9kZSk7Ci0gICAgICAgIF9saW5lID0gbm9kZS5nZXRMaW5lTnVtYmVyKCk7Ci0gICAgICAgIF9wYXJhbXMgPSBuZXcgT2JqZWN0WzFdOwotICAgICAgICBfcGFyYW1zWzBdID0gcGFyYW0xOwotICAgIH0KLQotICAgIHB1YmxpYyBFcnJvck1zZyhTdHJpbmcgY29kZSwgT2JqZWN0IHBhcmFtMSwgT2JqZWN0IHBhcmFtMiwKLSAgICAgICAgICAgICAgICAgICAgU3ludGF4VHJlZU5vZGUgbm9kZSkgewotICAgICAgICBfY29kZSA9IGNvZGU7Ci0gICAgICAgIF91cmwgID0gZ2V0RmlsZU5hbWUobm9kZSk7Ci0gICAgICAgIF9saW5lID0gbm9kZS5nZXRMaW5lTnVtYmVyKCk7Ci0gICAgICAgIF9wYXJhbXMgPSBuZXcgT2JqZWN0WzJdOwotICAgICAgICBfcGFyYW1zWzBdID0gcGFyYW0xOwotICAgICAgICBfcGFyYW1zWzFdID0gcGFyYW0yOwotICAgIH0KLQotICAgIHB1YmxpYyBUaHJvd2FibGUgZ2V0Q2F1c2UoKSB7Ci0gICAgICAgIHJldHVybiBfY2F1c2U7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBTdHJpbmcgZ2V0RmlsZU5hbWUoU3ludGF4VHJlZU5vZGUgbm9kZSkgewotICAgICAgICBTdHlsZXNoZWV0IHN0eWxlc2hlZXQgPSBub2RlLmdldFN0eWxlc2hlZXQoKTsKLSAgICAgICAgaWYgKHN0eWxlc2hlZXQgIT0gbnVsbCkKLSAgICAgICAgICAgIHJldHVybiBzdHlsZXNoZWV0LmdldFN5c3RlbUlkKCk7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIHByaXZhdGUgU3RyaW5nIGZvcm1hdExpbmUoKSB7Ci0gICAgICAgIFN0cmluZ0J1ZmZlciByZXN1bHQgPSBuZXcgU3RyaW5nQnVmZmVyKCk7Ci0gICAgICAgIGlmIChfdXJsICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoX3VybCk7Ci0gICAgICAgICAgICByZXN1bHQuYXBwZW5kKCI6ICIpOwotICAgICAgICB9Ci0gICAgICAgIGlmIChfbGluZSA+IDApIHsKLSAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoImxpbmUgIik7Ci0gICAgICAgICAgICByZXN1bHQuYXBwZW5kKEludGVnZXIudG9TdHJpbmcoX2xpbmUpKTsKLSAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoIjogIik7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHJlc3VsdC50b1N0cmluZygpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgdmVyc2lvbiBvZiB0b1N0cmluZygpIHVzZXMgdGhlIF9wYXJhbXMgaW5zdGFuY2UgdmFyaWFibGUKLSAgICAgKiB0byBmb3JtYXQgdGhlIG1lc3NhZ2UuIElmIHRoZSA8Y29kZT5fY29kZTwvY29kZT4gaXMgbmVnYXRpdmUKLSAgICAgKiB0aGUgdXNlIF9tZXNzYWdlIGFzIHRoZSBlcnJvciBzdHJpbmcuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKLSAgICAgICAgU3RyaW5nIHN1ZmZpeCA9IChfcGFyYW1zID09IG51bGwpID8KLSAgICAgICAgICAgIChudWxsICE9IF9jb2RlID8gZ2V0RXJyb3JNZXNzYWdlKCkgOiBfbWVzc2FnZSkKLSAgICAgICAgICAgIDogTWVzc2FnZUZvcm1hdC5mb3JtYXQoZ2V0RXJyb3JNZXNzYWdlKCksIF9wYXJhbXMpOwotICAgICAgICByZXR1cm4gZm9ybWF0TGluZSgpICsgc3VmZml4OwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoT2JqZWN0IG9iaikgewotICAgICAgICBPYmplY3QgcGFyYW1zW10gPSBuZXcgT2JqZWN0WzFdOwotICAgICAgICBwYXJhbXNbMF0gPSBvYmoudG9TdHJpbmcoKTsKLSAgICAgICAgU3RyaW5nIHN1ZmZpeCA9IE1lc3NhZ2VGb3JtYXQuZm9ybWF0KGdldEVycm9yTWVzc2FnZSgpLCBwYXJhbXMpOwotICAgICAgICByZXR1cm4gZm9ybWF0TGluZSgpICsgc3VmZml4OwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoT2JqZWN0IG9iajAsIE9iamVjdCBvYmoxKSB7Ci0gICAgICAgIE9iamVjdCBwYXJhbXNbXSA9IG5ldyBPYmplY3RbMl07Ci0gICAgICAgIHBhcmFtc1swXSA9IG9iajAudG9TdHJpbmcoKTsKLSAgICAgICAgcGFyYW1zWzFdID0gb2JqMS50b1N0cmluZygpOwotICAgICAgICBTdHJpbmcgc3VmZml4ID0gTWVzc2FnZUZvcm1hdC5mb3JtYXQoZ2V0RXJyb3JNZXNzYWdlKCksIHBhcmFtcyk7Ci0gICAgICAgIHJldHVybiBmb3JtYXRMaW5lKCkgKyBzdWZmaXg7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIGFuIEVycm9yTWVzc2FnZXMgc3RyaW5nIGNvcnJlc3BvbmRpbmcgdG8gdGhlIF9jb2RlCi0gICAgICogVGhpcyBmdW5jdGlvbiBpcyB0ZW1wb3JhcnkgdW50aWwgdGhlIHRocmVlIHNwZWNpYWwtY2FzZWQga2V5cwotICAgICAqIGJlbG93IGFyZSBtb3ZlZCBpbnRvIEVycm9yTWVzc2FnZXMKLSAgICAgKgotICAgICAqIEByZXR1cm4gRXJyb3JNZXNzYWdlcyBzdHJpbmcKLSAgICAgKi8KLSAgICBwcml2YXRlIFN0cmluZyBnZXRFcnJvck1lc3NhZ2UoKSB7Ci0gICAgICByZXR1cm4gX2J1bmRsZS5nZXRTdHJpbmcoX2NvZGUpOwotICAgIH0KLQotICAgIC8vIElmIHRoZSBfaXNXYXJuaW5nRXJyb3IgZmxhZyBpcyB0cnVlLCB0aGUgZXJyb3IgaXMgdHJlYXRlZCBhcwotICAgIC8vIGEgd2FybmluZyBieSB0aGUgY29tcGlsZXIsIGJ1dCBzaG91bGQgYmUgcmVwb3J0ZWQgYXMgYW4gZXJyb3IKLSAgICAvLyB0byB0aGUgRXJyb3JMaXN0ZW5lci4gVGhpcyBpcyBhIHdvcmthcm91bmQgZm9yIHRoZSBUQ0sgZmFpbHVyZQotICAgIC8vIEVycm9yTGlzdGVuZXIuZXJyb3JUZXN0cy5lcnJvcjAwMS4KLSAgICBwdWJsaWMgdm9pZCBzZXRXYXJuaW5nRXJyb3IoYm9vbGVhbiBmbGFnKSB7Ci0gICAgICAgIF9pc1dhcm5pbmdFcnJvciA9IGZsYWc7Ci19Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBpc1dhcm5pbmdFcnJvcigpIHsKLSAgICAgICAgcmV0dXJuIF9pc1dhcm5pbmdFcnJvcjsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL3V0aWwvRmlsdGVyR2VuZXJhdG9yLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL3V0aWwvRmlsdGVyR2VuZXJhdG9yLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDk2ZjY4MGYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci91dGlsL0ZpbHRlckdlbmVyYXRvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNjYgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRmlsdGVyR2VuZXJhdG9yLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMDUgMTE6MTM6NTIgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWw7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkFMT0FEOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW5zdHJ1Y3Rpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLlN0eWxlc2hlZXQ7Ci0KLS8qKgotICogVGhpcyBjbGFzcyBpbXBsZW1lbnRzIGF1eGxpYXJ5IGNsYXNzZXMgbmVlZGVkIHRvIGNvbXBpbGUKLSAqIGZpbHRlcnMgKHByZWRpY2F0ZXMpLiBUaGVzZSBjbGFzc2VzIGRlZmluZWQgYSBzaW5nbGUgbWV0aG9kCi0gKiBvZiB0eXBlIDx0dD5UZXN0R2VuZXJhdG9yPC90dD4uCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBGaWx0ZXJHZW5lcmF0b3IgZXh0ZW5kcyBDbGFzc0dlbmVyYXRvciB7Ci0gICAgcHJpdmF0ZSBzdGF0aWMgaW50IFRSQU5TTEVUX0lOREVYID0gNTsgICAvLyB0cmFuc2xldAotICAgIHByaXZhdGUgZmluYWwgSW5zdHJ1Y3Rpb24gX2Fsb2FkVHJhbnNsZXQ7Ci0KLSAgICBwdWJsaWMgRmlsdGVyR2VuZXJhdG9yKFN0cmluZyBjbGFzc05hbWUsIFN0cmluZyBzdXBlckNsYXNzTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBmaWxlTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBhY2Nlc3NGbGFncywgU3RyaW5nW10gaW50ZXJmYWNlcywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0eWxlc2hlZXQgc3R5bGVzaGVldCkgewotICAgICAgICBzdXBlcihjbGFzc05hbWUsIHN1cGVyQ2xhc3NOYW1lLCBmaWxlTmFtZSwKLSAgICAgICAgICAgICAgYWNjZXNzRmxhZ3MsIGludGVyZmFjZXMsIHN0eWxlc2hlZXQpOwotCi0gICAgICAgIF9hbG9hZFRyYW5zbGV0ID0gbmV3IEFMT0FEKFRSQU5TTEVUX0lOREVYKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgaW5kZXggb2YgdGhlIHRyYW5zbGV0IHBvaW50ZXIgd2l0aGluIHRoZSBleGVjdXRpb24gb2YKLSAgICAgKiB0aGUgdGVzdCBtZXRob2QuCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIEluc3RydWN0aW9uIGxvYWRUcmFuc2xldCgpIHsKLSAgICAgICAgcmV0dXJuIF9hbG9hZFRyYW5zbGV0OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgPHR0PnRydWU8L3R0PiBzaW5jZSB0aGlzIGNsYXNzIGlzIGV4dGVybmFsIHRvIHRoZQotICAgICAqIHRyYW5zbGV0LgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzRXh0ZXJuYWwoKSB7Ci0gICAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvdXRpbC9JbnRUeXBlLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL3V0aWwvSW50VHlwZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyNDdlNmUyLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvdXRpbC9JbnRUeXBlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzMDIgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogSW50VHlwZS5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzA1IDExOjE0OjQ0IHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5CcmFuY2hIYW5kbGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5CcmFuY2hJbnN0cnVjdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkNIRUNLQ0FTVDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkNvbnN0YW50UG9vbEdlbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkdPVE87Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JRkVROwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSUZHRTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklGR1Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JRkxFOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSUZMVDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklGX0lDTVBHRTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklGX0lDTVBHVDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklGX0lDTVBMRTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklGX0lDTVBMVDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklMT0FEOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFU1BFQ0lBTDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklOVk9LRVNUQVRJQzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklOVk9LRVZJUlRVQUw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JU1RPUkU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JbnN0cnVjdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW5zdHJ1Y3Rpb25MaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuTkVXOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci5Db25zdGFudHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLkZsb3dMaXN0OwotCi0vKioKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIEludFR5cGUgZXh0ZW5kcyBOdW1iZXJUeXBlIHsKLSAgICBwcm90ZWN0ZWQgSW50VHlwZSgpIHt9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgICAgICByZXR1cm4gImludCI7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gaWRlbnRpY2FsVG8oVHlwZSBvdGhlcikgewotICAgICAgICByZXR1cm4gdGhpcyA9PSBvdGhlcjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIHRvU2lnbmF0dXJlKCkgewotICAgICAgICByZXR1cm4gIkkiOwotICAgIH0KLQotICAgIHB1YmxpYyBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlR5cGUgdG9KQ1R5cGUoKSB7Ci0gICAgICAgIHJldHVybiBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlR5cGUuSU5UOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgICAgIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGUjZGlzdGFuY2VUbwotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZGlzdGFuY2VUbyhUeXBlIHR5cGUpIHsKLSAgICAgICAgaWYgKHR5cGUgPT0gdGhpcykgewotICAgICAgICAgICAgcmV0dXJuIDA7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAodHlwZSA9PSBUeXBlLlJlYWwpIHsKLSAgICAgICAgICAgIHJldHVybiAxOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICAgIHJldHVybiBJbnRlZ2VyLk1BWF9WQUxVRTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGVzIGFuIGludGVnZXIgaW50byBhbiBvYmplY3Qgb2YgaW50ZXJuYWwgdHlwZSA8Y29kZT50eXBlPC9jb2RlPi4KLSAgICAgKgotICAgICAqIEBzZWUgICAgIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGUjdHJhbnNsYXRlVG8KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVUbyhDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBUeXBlIHR5cGUpIHsKLSAgICAgICAgaWYgKHR5cGUgPT0gVHlwZS5SZWFsKSB7Ci0gICAgICAgICAgICB0cmFuc2xhdGVUbyhjbGFzc0dlbiwgbWV0aG9kR2VuLCAoUmVhbFR5cGUpIHR5cGUpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKHR5cGUgPT0gVHlwZS5TdHJpbmcpIHsKLSAgICAgICAgICAgIHRyYW5zbGF0ZVRvKGNsYXNzR2VuLCBtZXRob2RHZW4sIChTdHJpbmdUeXBlKSB0eXBlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICh0eXBlID09IFR5cGUuQm9vbGVhbikgewotICAgICAgICAgICAgdHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgKEJvb2xlYW5UeXBlKSB0eXBlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICh0eXBlID09IFR5cGUuUmVmZXJlbmNlKSB7Ci0gICAgICAgICAgICB0cmFuc2xhdGVUbyhjbGFzc0dlbiwgbWV0aG9kR2VuLCAoUmVmZXJlbmNlVHlwZSkgdHlwZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBFcnJvck1zZyBlcnIgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuREFUQV9DT05WRVJTSU9OX0VSUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b1N0cmluZygpLCB0eXBlLnRvU3RyaW5nKCkpOwotICAgICAgICAgICAgY2xhc3NHZW4uZ2V0UGFyc2VyKCkucmVwb3J0RXJyb3IoQ29uc3RhbnRzLkZBVEFMLCBlcnIpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRXhwZWN0cyBhbiBpbnRlZ2VyIG9uIHRoZSBzdGFjayBhbmQgcHVzaGVzIGEgcmVhbC4KLSAgICAgKgotICAgICAqIEBzZWUgICAgIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGUjdHJhbnNsYXRlVG8KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVUbyhDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZWFsVHlwZSB0eXBlKSB7Ci0gICAgICAgIG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKS5hcHBlbmQoSTJEKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBFeHBlY3RzIGFuIGludGVnZXIgb24gdGhlIHN0YWNrIGFuZCBwdXNoZXMgaXRzIHN0cmluZyB2YWx1ZSBieSBjYWxsaW5nCi0gICAgICogPGNvZGU+SW50ZWdlci50b1N0cmluZyhpbnQgaSk8L2NvZGU+LgotICAgICAqCi0gICAgICogQHNlZSAgICAgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZSN0cmFuc2xhdGVUbwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZVRvKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1R5cGUgdHlwZSkgewotICAgICAgICBmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VTVEFUSUMoY3BnLmFkZE1ldGhvZHJlZihJTlRFR0VSX0NMQVNTLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0b1N0cmluZyIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIihJKSIgKyBTVFJJTkdfU0lHKSkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEV4cGVjdHMgYW4gaW50ZWdlciBvbiB0aGUgc3RhY2sgYW5kIHB1c2hlcyBhIDAgaWYgaXRzIHZhbHVlIGlzIDAgYW5kCi0gICAgICogYSAxIG90aGVyd2lzZS4KLSAgICAgKgotICAgICAqIEBzZWUgICAgIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGUjdHJhbnNsYXRlVG8KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVUbyhDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBCb29sZWFuVHlwZSB0eXBlKSB7Ci0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLSAgICAgICAgZmluYWwgQnJhbmNoSGFuZGxlIGZhbHNlYyA9IGlsLmFwcGVuZChuZXcgSUZFUShudWxsKSk7Ci0gICAgICAgIGlsLmFwcGVuZChJQ09OU1RfMSk7Ci0gICAgICAgIGZpbmFsIEJyYW5jaEhhbmRsZSB0cnVlYyA9IGlsLmFwcGVuZChuZXcgR09UTyhudWxsKSk7Ci0gICAgICAgIGZhbHNlYy5zZXRUYXJnZXQoaWwuYXBwZW5kKElDT05TVF8wKSk7Ci0gICAgICAgIHRydWVjLnNldFRhcmdldChpbC5hcHBlbmQoTk9QKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRXhwZWN0cyBhbiBpbnRlZ2VyIG9uIHRoZSBzdGFjayBhbmQgdHJhbnNsYXRlcyBpdCB0byBhIG5vbi1zeW50aGVzaXplZAotICAgICAqIGJvb2xlYW4uIEl0IGRvZXMgbm90IHB1c2ggYSAwIG9yIGEgMSBidXQgaW5zdGVhZCByZXR1cm5zIGJyYW5jaGhhbmRsZQotICAgICAqIGxpc3QgdG8gYmUgYXBwZW5kZWQgdG8gdGhlIGZhbHNlIGxpc3QuCi0gICAgICoKLSAgICAgKiBAc2VlICAgICBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlI3RyYW5zbGF0ZVRvRGVzeW50aGVzaXplZAotICAgICAqLwotICAgIHB1YmxpYyBGbG93TGlzdCB0cmFuc2xhdGVUb0Rlc3ludGhlc2l6ZWQoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQm9vbGVhblR5cGUgdHlwZSkgewotICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0gICAgICAgIHJldHVybiBuZXcgRmxvd0xpc3QoaWwuYXBwZW5kKG5ldyBJRkVRKG51bGwpKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRXhwZWN0cyBhbiBpbnRlZ2VyIG9uIHRoZSBzdGFjayBhbmQgcHVzaGVzIGEgYm94ZWQgaW50ZWdlci4KLSAgICAgKiBCb3hlZCBpbnRlZ2VycyBhcmUgcmVwcmVzZW50ZWQgYnkgYW4gaW5zdGFuY2Ugb2YKLSAgICAgKiA8Y29kZT5qYXZhLmxhbmcuSW50ZWdlcjwvY29kZT4uCi0gICAgICoKLSAgICAgKiBAc2VlICAgICBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlI3RyYW5zbGF0ZVRvCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlVG8oQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVmZXJlbmNlVHlwZSB0eXBlKSB7Ci0gICAgICAgIGZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotICAgICAgICBpbC5hcHBlbmQobmV3IE5FVyhjcGcuYWRkQ2xhc3MoSU5URUdFUl9DTEFTUykpKTsKLSAgICAgICAgaWwuYXBwZW5kKERVUF9YMSk7Ci0gICAgICAgIGlsLmFwcGVuZChTV0FQKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VTUEVDSUFMKGNwZy5hZGRNZXRob2RyZWYoSU5URUdFUl9DTEFTUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjxpbml0PiIsICIoSSlWIikpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGVzIGFuIGludGVnZXIgaW50byB0aGUgSmF2YSB0eXBlIGRlbm90ZWQgYnkgPGNvZGU+Y2xheno8L2NvZGU+LgotICAgICAqIEV4cGVjdHMgYW4gaW50ZWdlciBvbiB0aGUgc3RhY2sgYW5kIHB1c2hlcyBhIG51bWJlciBvZiB0aGUgYXBwcm9wcmlhdGUKLSAgICAgKiB0eXBlIGFmdGVyIGNvZXJjaW9uLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZVRvKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIENsYXNzIGNsYXp6KSB7Ci0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLSAgICAgICAgaWYgKGNsYXp6ID09IENoYXJhY3Rlci5UWVBFKSB7Ci0gICAgICAgICAgICBpbC5hcHBlbmQoSTJDKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChjbGF6eiA9PSBCeXRlLlRZUEUpIHsKLSAgICAgICAgICAgIGlsLmFwcGVuZChJMkIpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKGNsYXp6ID09IFNob3J0LlRZUEUpIHsKLSAgICAgICAgICAgIGlsLmFwcGVuZChJMlMpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKGNsYXp6ID09IEludGVnZXIuVFlQRSkgewotICAgICAgICAgICAgaWwuYXBwZW5kKE5PUCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoY2xhenogPT0gTG9uZy5UWVBFKSB7Ci0gICAgICAgICAgICBpbC5hcHBlbmQoSTJMKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChjbGF6eiA9PSBGbG9hdC5UWVBFKSB7Ci0gICAgICAgICAgICBpbC5hcHBlbmQoSTJGKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChjbGF6eiA9PSBEb3VibGUuVFlQRSkgewotICAgICAgICAgICAgaWwuYXBwZW5kKEkyRCk7Ci0gICAgICAgIH0KLSAgICAgICAgIC8vIElzIERvdWJsZSA8OiBjbGF6ej8gSS5lLiBjbGF6eiBpbiB7IERvdWJsZSwgTnVtYmVyLCBPYmplY3QgfQotICAgICAgIGVsc2UgaWYgKGNsYXp6LmlzQXNzaWduYWJsZUZyb20oamF2YS5sYW5nLkRvdWJsZS5jbGFzcykpIHsKLSAgICAgICAgICAgaWwuYXBwZW5kKEkyRCk7Ci0gICAgICAgICAgIFR5cGUuUmVhbC50cmFuc2xhdGVUbyhjbGFzc0dlbiwgbWV0aG9kR2VuLCBUeXBlLlJlZmVyZW5jZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBFcnJvck1zZyBlcnIgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuREFUQV9DT05WRVJTSU9OX0VSUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b1N0cmluZygpLCBjbGF6ei5nZXROYW1lKCkpOwotICAgICAgICAgICAgY2xhc3NHZW4uZ2V0UGFyc2VyKCkucmVwb3J0RXJyb3IoQ29uc3RhbnRzLkZBVEFMLCBlcnIpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhbnNsYXRlcyBhbiBvYmplY3Qgb2YgdGhpcyB0eXBlIHRvIGl0cyBib3hlZCByZXByZXNlbnRhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVCb3goQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLSAgICAgICAgdHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgVHlwZS5SZWZlcmVuY2UpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZXMgYW4gb2JqZWN0IG9mIHRoaXMgdHlwZSB0byBpdHMgdW5ib3hlZCByZXByZXNlbnRhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVVbkJveChDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0gICAgICAgIGZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotICAgICAgICBpbC5hcHBlbmQobmV3IENIRUNLQ0FTVChjcGcuYWRkQ2xhc3MoSU5URUdFUl9DTEFTUykpKTsKLSAgICAgICAgZmluYWwgaW50IGluZGV4ID0gY3BnLmFkZE1ldGhvZHJlZihJTlRFR0VSX0NMQVNTLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVF9WQUxVRSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlRfVkFMVUVfU0lHKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VWSVJUVUFMKGluZGV4KSk7Ci0gICAgfQotCi0gICAgcHVibGljIEluc3RydWN0aW9uIEFERCgpIHsKLSAgICAgICAgcmV0dXJuIEluc3RydWN0aW9uQ29uc3RhbnRzLklBREQ7Ci0gICAgfQotCi0gICAgcHVibGljIEluc3RydWN0aW9uIFNVQigpIHsKLSAgICAgICAgcmV0dXJuIEluc3RydWN0aW9uQ29uc3RhbnRzLklTVUI7Ci0gICAgfQotCi0gICAgcHVibGljIEluc3RydWN0aW9uIE1VTCgpIHsKLSAgICAgICAgcmV0dXJuIEluc3RydWN0aW9uQ29uc3RhbnRzLklNVUw7Ci0gICAgfQotCi0gICAgcHVibGljIEluc3RydWN0aW9uIERJVigpIHsKLSAgICAgICAgcmV0dXJuIEluc3RydWN0aW9uQ29uc3RhbnRzLklESVY7Ci0gICAgfQotCi0gICAgcHVibGljIEluc3RydWN0aW9uIFJFTSgpIHsKLSAgICAgICAgcmV0dXJuIEluc3RydWN0aW9uQ29uc3RhbnRzLklSRU07Ci0gICAgfQotCi0gICAgcHVibGljIEluc3RydWN0aW9uIE5FRygpIHsKLSAgICAgICAgcmV0dXJuIEluc3RydWN0aW9uQ29uc3RhbnRzLklORUc7Ci0gICAgfQotCi0gICAgcHVibGljIEluc3RydWN0aW9uIExPQUQoaW50IHNsb3QpIHsKLSAgICAgICAgcmV0dXJuIG5ldyBJTE9BRChzbG90KTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb24gU1RPUkUoaW50IHNsb3QpIHsKLSAgICAgICAgcmV0dXJuIG5ldyBJU1RPUkUoc2xvdCk7Ci0gICAgfQotCi0gICAgcHVibGljIEJyYW5jaEluc3RydWN0aW9uIEdUKGJvb2xlYW4gdG96ZXJvKSB7Ci0gICAgICAgIHJldHVybiB0b3plcm8gPyAoQnJhbmNoSW5zdHJ1Y3Rpb24pIG5ldyBJRkdUKG51bGwpIDoKLSAgICAgICAgICAgIChCcmFuY2hJbnN0cnVjdGlvbikgbmV3IElGX0lDTVBHVChudWxsKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgQnJhbmNoSW5zdHJ1Y3Rpb24gR0UoYm9vbGVhbiB0b3plcm8pIHsKLSAgICAgICAgcmV0dXJuIHRvemVybyA/IChCcmFuY2hJbnN0cnVjdGlvbikgbmV3IElGR0UobnVsbCkgOgotICAgICAgICAgICAgKEJyYW5jaEluc3RydWN0aW9uKSBuZXcgSUZfSUNNUEdFKG51bGwpOwotICAgIH0KLQotICAgIHB1YmxpYyBCcmFuY2hJbnN0cnVjdGlvbiBMVChib29sZWFuIHRvemVybykgewotICAgICAgICByZXR1cm4gdG96ZXJvID8gKEJyYW5jaEluc3RydWN0aW9uKSBuZXcgSUZMVChudWxsKSA6Ci0gICAgICAgICAgICAoQnJhbmNoSW5zdHJ1Y3Rpb24pIG5ldyBJRl9JQ01QTFQobnVsbCk7Ci0gICAgfQotCi0gICAgcHVibGljIEJyYW5jaEluc3RydWN0aW9uIExFKGJvb2xlYW4gdG96ZXJvKSB7Ci0gICAgICAgIHJldHVybiB0b3plcm8gPyAoQnJhbmNoSW5zdHJ1Y3Rpb24pIG5ldyBJRkxFKG51bGwpIDoKLSAgICAgICAgICAgIChCcmFuY2hJbnN0cnVjdGlvbikgbmV3IElGX0lDTVBMRShudWxsKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL3V0aWwvSW50ZXJuYWxFcnJvci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci91dGlsL0ludGVybmFsRXJyb3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMmJiMGMzZC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL3V0aWwvSW50ZXJuYWxFcnJvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzcgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi0vKgotICogJElkOiBJbnRlcm5hbEVycm9yLmphdmEsdiAxLjAgMjAxMS0wOC0xOCAwNDozNDoxOSBqb2VodyBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsOwotLyoqCi0gKiBNYXJrcyBhIGNsYXNzIG9mIGVycm9ycyBpbiB3aGljaCBYU0xUQyBoYXMgcmVhY2hlZCBzb21lIGluY29ycmVjdCBpbnRlcm5hbAotICogc3RhdGUgZnJvbSB3aGljaCBpdCBjYW5ub3QgcmVjb3Zlci4KLSAqLwotcHVibGljIGNsYXNzIEludGVybmFsRXJyb3IgZXh0ZW5kcyBFcnJvciB7Ci0gICAgLyoqCi0gICAgICogQ29uc3RydWN0IGFuIDxjb2RlPkludGVybmFsRXJyb3I8L2NvZGU+IHdpdGggdGhlIHNwZWNpZmllZCBlcnJvciBtZXNzYWdlLgotICAgICAqIEBwYXJhbSBtc2cgdGhlIGVycm9yIG1lc3NhZ2UKLSAgICAgKi8KLSAgICBwdWJsaWMgSW50ZXJuYWxFcnJvcihTdHJpbmcgbXNnKSB7Ci0gICAgICAgIHN1cGVyKG1zZyk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci91dGlsL01hcmtlckluc3RydWN0aW9uLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL3V0aWwvTWFya2VySW5zdHJ1Y3Rpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZTc2YTNmZS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL3V0aWwvTWFya2VySW5zdHJ1Y3Rpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDk4ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotLyoKLSAqICRJZDogTWV0aG9kR2VuZXJhdG9yLmphdmEsdiAxLjEwIDIwMTAtMTEtMDEgMDQ6MzQ6MTkgam9laHcgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbDsKLWltcG9ydCBqYXZhLmlvLkRhdGFPdXRwdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLkNvbnN0YW50czsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkNvbnN0YW50UG9vbEdlbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuVmlzaXRvcjsKLQotLyoqCi0gKiBBIHNwZWNpYWwgYWJzdHJhY3QgZHVtbXkgc3ViY2xhc3Mgb2YKLSAqIHtAbGluayBvcmcuYXBhY2hlLmJjZWwuZ2VuZXJpYy5JbnN0cnVjdGlvbn0gdXNlZCB0byBtYXJrIGxvY2F0aW9ucyBvZgotICogaW50ZXJlc3QgaW4gYW4ge0BsaW5rIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW5zdHJ1Y3Rpb25MaXN0fS4gIEl0IGFuZAotICogaXRzIHN1YmNsYXNzZXMgYXJlIG9ubHkgdXNlZCBhcyBwbGFjZWhvbGRlcnMsIGFuZCBkbyBub3QgY29udHJpYnV0ZSB0byB0aGUKLSAqIGFjdHVhbCBieXRlIGNvZGUgaW5zdHJ1Y3Rpb24gc3RyZWFtLgotICovCi1hYnN0cmFjdCBjbGFzcyBNYXJrZXJJbnN0cnVjdGlvbiBleHRlbmRzIEluc3RydWN0aW9uIHsKLSAgICAvKioKLSAgICAgKiBaZXJvLWFyZ3VtZW50IGNvbnN0cnVjdG9yLiAgU2V0cyB0aGUgb3Bjb2RlIHRvIGFuIGludmFsaWQgdmFsdWUgYW5kCi0gICAgICogc2V0cyB0aGUgbGVuZ3RoIHRvIHplcm8sIGFzIGl0IHdpbGwgbm90IGJlIHdyaXR0ZW4gYXMgcGFydCBvZiB0aGUKLSAgICAgKiBnZW5lcmF0ZWQgYnl0ZSBjb2RlLgotICAgICAqLwotICAgIHB1YmxpYyBNYXJrZXJJbnN0cnVjdGlvbigpIHsKLSAgICAgICAgc3VwZXIoQ29uc3RhbnRzLlVOREVGSU5FRCwgKHNob3J0KSAwKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiB7QGxpbmsgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5WaXNpdG9yfXMgd2lsbCBrbm93IG5vdGhpbmcgYWJvdXQgdGhpcwotICAgICAqIGtpbmQgb2Yge0BsaW5rIG9yZy5hcGNoZS5iY2VsLmdlbmVyaWMuSW5zdHJ1Y3Rpb259LCBzbyB0aGlzIG1ldGhvZCBkb2VzCi0gICAgICogbm90aGluZy4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhlIG51bWJlciBvZiBKVk0gc3RhY2sgZW50cmllcyBjb25zdW1lZCBieSB0aGUgaW5zdHJ1Y3Rpb24uCi0gICAgICogVGhpcyBpbnN0cnVjdGlvbiBpcyBqdXN0IGEgcGxhY2UgaG9sZGVyLCBzbyBpdCBkb2VzIG5vdCBjb25zdW1lIGFueQotICAgICAqIHN0YWNrIGVudHJpZXMuCi0gICAgICogQHBhcmFtIGNwZyBUaGUge0BsaW5rIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQ29uc3RhbnRQb29sR2VufSBmb3IgdGhlCi0gICAgICogY3VycmVudCB7QGxpbmsgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5DbGFzc0dlbn0KLSAgICAgKiBAcmV0dXJuIDxjb2RlPjA8L2NvZGU+IGFsd2F5cwotICAgICAqLwotICAgIGZpbmFsIHB1YmxpYyBpbnQgY29uc3VtZVN0YWNrKENvbnN0YW50UG9vbEdlbiBjcGcpIHsKLSAgICAgICAgcmV0dXJuIDA7Ci0gICAgfQotICAgIC8qKgotICAgICAqIFRoZSBudW1iZXIgb2YgSlZNIHN0YWNrIGVudHJpZXMgcHJvZHVjZWQgYnkgdGhlIGluc3RydWN0aW9uLgotICAgICAqIFRoaXMgaW5zdHJ1Y3Rpb24gaXMganVzdCBhIHBsYWNlIGhvbGRlciwgc28gaXQgZG9lcyBub3QgcHJvZHVjZSBhbnkKLSAgICAgKiBzdGFjayBlbnRyaWVzLgotICAgICAqIEBwYXJhbSBjcGcgVGhlIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkNvbnN0YW50UG9vbEdlbn0gZm9yIHRoZQotICAgICAqIGN1cnJlbnQge0BsaW5rIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQ2xhc3NHZW59Ci0gICAgICogQHJldHVybiA8Y29kZT4wPC9jb2RlPiBhbHdheXMKLSAgICAgKi8KLSAgICBmaW5hbCBwdWJsaWMgaW50IHByb2R1Y2VTdGFjayhDb25zdGFudFBvb2xHZW4gY3BnKSB7Ci0gICAgICAgIHJldHVybiAwOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFByb2R1Y2UgYSBjb3B5IG9mIHRoZSBpbnN0cnVjdGlvbi4gIEJ5IGRlZmF1bHQgYQotICAgICAqIHtAbGluayBNYXJrZXJJbnN0cnVjdGlvbn0gaGFzIG5vIHBhcmFtZXRlcnMsIHNvIHRoZSBiYXNlIGltcGxlbWVudGF0aW9uCi0gICAgICogb2Yge0BsaW5rICNjb3B5KCl9IHJldHVybnMgdGhlIGluc3RydWN0aW9uIGl0c2VsZi4KLSAgICAgKiBAcmV0dXJuIFRoZSBpbnN0cnVjdGlvbiBpdHNlbGYuCi0gICAgICovCi0gICAgcHVibGljIEluc3RydWN0aW9uIGNvcHkoKSB7Ci0gICAgICAgIHJldHVybiB0aGlzOwotICAgIH0KLSAgICAvKioKLSAgICAgKiBEdW1wIGluc3RydWN0aW9uIGFzIGJ5dGUgY29kZSB0byBzdHJlYW0gb3V0LiAgQSB7QGxpbmsgTWFya2VySW5zdHJ1Y3Rpb259Ci0gICAgICogaGFzIG5vIGVmZmVjdCBvbiB0aGUgZ2VuZXJhdGVkIGJ5dGUgY29kZSBzbyBpdCBpcyBuZXZlciBlbWl0dGVkIHRvIHRoZQotICAgICAqIG91dHB1dCBzdHJlYW0uCi0gICAgICogQHBhcmFtIG91dCBPdXRwdXQgc3RyZWFtCi0gICAgICovCi0gICAgZmluYWwgcHVibGljIHZvaWQgZHVtcChEYXRhT3V0cHV0U3RyZWFtIG91dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL3V0aWwvTWF0Y2hHZW5lcmF0b3IuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvdXRpbC9NYXRjaEdlbmVyYXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1OTcyYmViLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvdXRpbC9NYXRjaEdlbmVyYXRvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTA0ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IE1hdGNoR2VuZXJhdG9yLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMDUgMTE6MTU6MjEgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWw7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkFMT0FEOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQ29uc3RhbnRQb29sR2VuOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSUxPQUQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JU1RPUkU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JbnN0cnVjdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uTGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlR5cGU7Ci0KLS8qKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgTWF0Y2hHZW5lcmF0b3IgZXh0ZW5kcyBNZXRob2RHZW5lcmF0b3IgewotICAgIHByaXZhdGUgc3RhdGljIGludCBDVVJSRU5UX0lOREVYID0gMTsKLQotICAgIHByaXZhdGUgaW50IF9pdGVyYXRvckluZGV4ID0gSU5WQUxJRF9JTkRFWDsKLQotICAgIHByaXZhdGUgZmluYWwgSW5zdHJ1Y3Rpb24gX2lsb2FkQ3VycmVudDsKLSAgICBwcml2YXRlIGZpbmFsIEluc3RydWN0aW9uIF9pc3RvcmVDdXJyZW50OwotICAgIHByaXZhdGUgSW5zdHJ1Y3Rpb24gX2Fsb2FkRG9tOwotCi0gICAgcHVibGljIE1hdGNoR2VuZXJhdG9yKGludCBhY2Nlc3NfZmxhZ3MsIFR5cGUgcmV0dXJuX3R5cGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIFR5cGVbXSBhcmdfdHlwZXMsIFN0cmluZ1tdIGFyZ19uYW1lcywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG1ldGhvZF9uYW1lLCBTdHJpbmcgY2xhc3NfbmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgSW5zdHJ1Y3Rpb25MaXN0IGlsLCBDb25zdGFudFBvb2xHZW4gY3ApIHsKLSAgICAgICAgc3VwZXIoYWNjZXNzX2ZsYWdzLCByZXR1cm5fdHlwZSwgYXJnX3R5cGVzLCBhcmdfbmFtZXMsIG1ldGhvZF9uYW1lLAotICAgICAgICAgICAgICBjbGFzc19uYW1lLCBpbCwgY3ApOwotCi0gICAgICAgIF9pbG9hZEN1cnJlbnQgPSBuZXcgSUxPQUQoQ1VSUkVOVF9JTkRFWCk7Ci0gICAgICAgIF9pc3RvcmVDdXJyZW50ID0gbmV3IElTVE9SRShDVVJSRU5UX0lOREVYKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb24gbG9hZEN1cnJlbnROb2RlKCkgewotICAgICAgICByZXR1cm4gX2lsb2FkQ3VycmVudDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb24gc3RvcmVDdXJyZW50Tm9kZSgpIHsKLSAgICAgICAgcmV0dXJuIF9pc3RvcmVDdXJyZW50OwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgZ2V0SGFuZGxlckluZGV4KCkgewotICAgICAgICByZXR1cm4gSU5WQUxJRF9JTkRFWDsgICAgICAgICAgIC8vIG5vdCBhdmFpbGFibGUKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgaW5kZXggb2YgdGhlIHJlZ2lzdGVyIHdoZXJlIHRoZSBET00gaXMgc3RvcmVkLgotICAgICAqLwotICAgIHB1YmxpYyBJbnN0cnVjdGlvbiBsb2FkRE9NKCkgewotICAgICAgICByZXR1cm4gX2Fsb2FkRG9tOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldCBpbmRleCB3aGVyZSB0aGUgcmVmZXJlbmNlIHRvIHRoZSBET00gaXMgc3RvcmVkLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldERvbUluZGV4KGludCBkb21JbmRleCkgewotICAgICAgICBfYWxvYWREb20gPSBuZXcgQUxPQUQoZG9tSW5kZXgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCBpbmRleCBvZiB0aGUgcmVnaXN0ZXIgd2hlcmUgdGhlIGN1cnJlbnQgaXRlcmF0b3IgaXMgc3RvcmVkLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0SXRlcmF0b3JJbmRleCgpIHsKLSAgICAgICAgcmV0dXJuIF9pdGVyYXRvckluZGV4OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldCBpbmRleCBvZiB0aGUgcmVnaXN0ZXIgd2hlcmUgdGhlIGN1cnJlbnQgaXRlcmF0b3IgaXMgc3RvcmVkLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEl0ZXJhdG9ySW5kZXgoaW50IGl0ZXJhdG9ySW5kZXgpIHsKLSAgICAgICAgX2l0ZXJhdG9ySW5kZXggPSBpdGVyYXRvckluZGV4OwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgZ2V0TG9jYWxJbmRleChTdHJpbmcgbmFtZSkgewotICAgICAgICBpZiAobmFtZS5lcXVhbHMoImN1cnJlbnQiKSkgewotICAgICAgICAgICAgcmV0dXJuIENVUlJFTlRfSU5ERVg7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHN1cGVyLmdldExvY2FsSW5kZXgobmFtZSk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci91dGlsL01ldGhvZEdlbmVyYXRvci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci91dGlsL01ldGhvZEdlbmVyYXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0YTNlNzUzLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvdXRpbC9NZXRob2RHZW5lcmF0b3IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIxNDUgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAxNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqLwotLyoKLSAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQotICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCi0gKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCi0gKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAotICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKLSAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogTWV0aG9kR2VuZXJhdG9yLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMDUgMTE6MTY6NDcgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWw7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5Db25zdGFudHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuY2xhc3NmaWxlLkZpZWxkOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmNsYXNzZmlsZS5NZXRob2Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5BTE9BRDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkFTVE9SRTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkJyYW5jaEhhbmRsZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkJyYW5jaEluc3RydWN0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQ29uc3RhbnRQb29sR2VuOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuRExPQUQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5EU1RPUkU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5GTE9BRDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkZTVE9SRTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkdFVEZJRUxEOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuR09UTzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklDT05TVDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklMT0FEOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFSU5URVJGQUNFOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFU1BFQ0lBTDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklOVk9LRVNUQVRJQzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklOVk9LRVZJUlRVQUw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JU1RPUkU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JZkluc3RydWN0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW5kZXhlZEluc3RydWN0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW5zdHJ1Y3Rpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JbnN0cnVjdGlvbkNvbnN0YW50czsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uSGFuZGxlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW5zdHJ1Y3Rpb25MaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW5zdHJ1Y3Rpb25UYXJnZXRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkxMT0FEOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuTFNUT1JFOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuTG9jYWxWYXJpYWJsZUdlbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkxvY2FsVmFyaWFibGVJbnN0cnVjdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLk1ldGhvZEdlbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLk5FVzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlBVVEZJRUxEOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuUkVUOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuU2VsZWN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuVGFyZ2V0TG9zdEV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLlBhdHRlcm47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLlhTTFRDOwotaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7Ci1pbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOwotaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwotaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKLWltcG9ydCBqYXZhLnV0aWwuTWFwOwotaW1wb3J0IGphdmEudXRpbC5TdGFjazsKLQotLyoqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKi8KLXB1YmxpYyBjbGFzcyBNZXRob2RHZW5lcmF0b3IgZXh0ZW5kcyBNZXRob2RHZW4KLSAgICBpbXBsZW1lbnRzIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci5Db25zdGFudHMgewotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgaW50IElOVkFMSURfSU5ERVggICA9IC0xOwotCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFNUQVJUX0VMRU1FTlRfU0lHCi0gICAgICAgID0gIigiICsgU1RSSU5HX1NJRyArICIpViI7Ci0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEVORF9FTEVNRU5UX1NJRwotICAgICAgICA9IFNUQVJUX0VMRU1FTlRfU0lHOwotCi0gICAgcHJpdmF0ZSBJbnN0cnVjdGlvbkxpc3QgX21hcFR5cGVTdWI7Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgRE9NX0lOREVYICAgICAgID0gMTsKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgSVRFUkFUT1JfSU5ERVggID0gMjsKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgSEFORExFUl9JTkRFWCAgID0gMzsKLQotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBNQVhfTUVUSE9EX1NJWkUgPSA2NTUzNTsKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTUFYX0JSQU5DSF9UQVJHRVRfT0ZGU0VUID0gMzI3Njc7Ci0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE1JTl9CUkFOQ0hfVEFSR0VUX09GRlNFVCA9IC0zMjc2ODsKLQotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBUQVJHRVRfTUVUSE9EX1NJWkUgPSA2MDAwMDsKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTUlOSU1VTV9PVVRMSU5FQUJMRV9DSFVOS19TSVpFID0gMTAwMDsKLQotICAgIHByaXZhdGUgSW5zdHJ1Y3Rpb24gICAgICAgX2lsb2FkQ3VycmVudDsKLSAgICBwcml2YXRlIEluc3RydWN0aW9uICAgICAgIF9pc3RvcmVDdXJyZW50OwotICAgIHByaXZhdGUgZmluYWwgSW5zdHJ1Y3Rpb24gX2FzdG9yZUhhbmRsZXI7Ci0gICAgcHJpdmF0ZSBmaW5hbCBJbnN0cnVjdGlvbiBfYWxvYWRIYW5kbGVyOwotICAgIHByaXZhdGUgZmluYWwgSW5zdHJ1Y3Rpb24gX2FzdG9yZUl0ZXJhdG9yOwotICAgIHByaXZhdGUgZmluYWwgSW5zdHJ1Y3Rpb24gX2Fsb2FkSXRlcmF0b3I7Ci0gICAgcHJpdmF0ZSBmaW5hbCBJbnN0cnVjdGlvbiBfYWxvYWREb207Ci0gICAgcHJpdmF0ZSBmaW5hbCBJbnN0cnVjdGlvbiBfYXN0b3JlRG9tOwotCi0gICAgcHJpdmF0ZSBmaW5hbCBJbnN0cnVjdGlvbiBfc3RhcnRFbGVtZW50OwotICAgIHByaXZhdGUgZmluYWwgSW5zdHJ1Y3Rpb24gX2VuZEVsZW1lbnQ7Ci0gICAgcHJpdmF0ZSBmaW5hbCBJbnN0cnVjdGlvbiBfc3RhcnREb2N1bWVudDsKLSAgICBwcml2YXRlIGZpbmFsIEluc3RydWN0aW9uIF9lbmREb2N1bWVudDsKLSAgICBwcml2YXRlIGZpbmFsIEluc3RydWN0aW9uIF9hdHRyaWJ1dGU7Ci0gICAgcHJpdmF0ZSBmaW5hbCBJbnN0cnVjdGlvbiBfdW5pcXVlQXR0cmlidXRlOwotICAgIHByaXZhdGUgZmluYWwgSW5zdHJ1Y3Rpb24gX25hbWVzcGFjZTsKLQotICAgIHByaXZhdGUgZmluYWwgSW5zdHJ1Y3Rpb24gX3NldFN0YXJ0Tm9kZTsKLSAgICBwcml2YXRlIGZpbmFsIEluc3RydWN0aW9uIF9yZXNldDsKLSAgICBwcml2YXRlIGZpbmFsIEluc3RydWN0aW9uIF9uZXh0Tm9kZTsKLQotICAgIHByaXZhdGUgU2xvdEFsbG9jYXRvciBfc2xvdEFsbG9jYXRvcjsKLSAgICBwcml2YXRlIGJvb2xlYW4gX2FsbG9jYXRvckluaXQgPSBmYWxzZTsKLSAgICBwcml2YXRlIExvY2FsVmFyaWFibGVSZWdpc3RyeSBfbG9jYWxWYXJpYWJsZVJlZ2lzdHJ5OwotICAgICAgICAvKioKLSAgICAgICAgICAgICAgICAgKiBBIG1hcHBpbmcgYmV0d2VlbiBwYXR0ZXJucyBhbmQgaW5zdHJ1Y3Rpb24gbGlzdHMgdXNlZCBieQotICAgICAgICAgICAgICAgICAqIHRlc3Qgc2VxdWVuY2VzIHRvIGF2b2lkIGNvbXBpbGluZyB0aGUgc2FtZSBwYXR0ZXJuIG11bHRpcGxlCi0gICAgICAgICAgICAgICAgICogdGltZXMuIE5vdGUgdGhhdCBwYXR0ZXJucyB3aG9zZSBrZXJuZWxzIGFyZSAiKiIsICJub2RlKCkiCi0gICAgICAgICAgICAgICAgICogYW5kICJAKiIgY2FuIGJldHdlZW4gc2hhcmVkIGJ5IHRlc3Qgc2VxdWVuY2VzLgotICAgICAgICAgICAgICAgICAqLwotICAgICAgICBwcml2YXRlIE1hcDxQYXR0ZXJuLCBJbnN0cnVjdGlvbkxpc3Q+IF9wcmVDb21waWxlZCA9IG5ldyBIYXNoTWFwPD4oKTsKLQotCi0gICAgcHVibGljIE1ldGhvZEdlbmVyYXRvcihpbnQgYWNjZXNzX2ZsYWdzLCBUeXBlIHJldHVybl90eXBlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgVHlwZVtdIGFyZ190eXBlcywgU3RyaW5nW10gYXJnX25hbWVzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG1ldGhvZF9uYW1lLCBTdHJpbmcgY2xhc3NfbmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgIEluc3RydWN0aW9uTGlzdCBpbCwgQ29uc3RhbnRQb29sR2VuIGNwZykgewotICAgICAgICBzdXBlcihhY2Nlc3NfZmxhZ3MsIHJldHVybl90eXBlLCBhcmdfdHlwZXMsIGFyZ19uYW1lcywgbWV0aG9kX25hbWUsCi0gICAgICAgICAgICAgIGNsYXNzX25hbWUsIGlsLCBjcGcpOwotCi0gICAgICAgIF9hc3RvcmVIYW5kbGVyICA9IG5ldyBBU1RPUkUoSEFORExFUl9JTkRFWCk7Ci0gICAgICAgIF9hbG9hZEhhbmRsZXIgICA9IG5ldyBBTE9BRChIQU5ETEVSX0lOREVYKTsKLSAgICAgICAgX2FzdG9yZUl0ZXJhdG9yID0gbmV3IEFTVE9SRShJVEVSQVRPUl9JTkRFWCk7Ci0gICAgICAgIF9hbG9hZEl0ZXJhdG9yICA9IG5ldyBBTE9BRChJVEVSQVRPUl9JTkRFWCk7Ci0gICAgICAgIF9hbG9hZERvbSAgICAgICA9IG5ldyBBTE9BRChET01fSU5ERVgpOwotICAgICAgICBfYXN0b3JlRG9tICAgICAgPSBuZXcgQVNUT1JFKERPTV9JTkRFWCk7Ci0KLSAgICAgICAgZmluYWwgaW50IHN0YXJ0RWxlbWVudCA9Ci0gICAgICAgICAgICBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKFRSQU5TTEVUX09VVFBVVF9JTlRFUkZBQ0UsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJzdGFydEVsZW1lbnQiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTVEFSVF9FTEVNRU5UX1NJRyk7Ci0gICAgICAgIF9zdGFydEVsZW1lbnQgPSBuZXcgSU5WT0tFSU5URVJGQUNFKHN0YXJ0RWxlbWVudCwgMik7Ci0KLSAgICAgICAgZmluYWwgaW50IGVuZEVsZW1lbnQgPQotICAgICAgICAgICAgY3BnLmFkZEludGVyZmFjZU1ldGhvZHJlZihUUkFOU0xFVF9PVVRQVVRfSU5URVJGQUNFLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZW5kRWxlbWVudCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVORF9FTEVNRU5UX1NJRyk7Ci0gICAgICAgIF9lbmRFbGVtZW50ID0gbmV3IElOVk9LRUlOVEVSRkFDRShlbmRFbGVtZW50LCAyKTsKLQotICAgICAgICBmaW5hbCBpbnQgYXR0cmlidXRlID0KLSAgICAgICAgICAgIGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoVFJBTlNMRVRfT1VUUFVUX0lOVEVSRkFDRSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImFkZEF0dHJpYnV0ZSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIFNUUklOR19TSUcKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBTVFJJTkdfU0lHCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIilWIik7Ci0gICAgICAgIF9hdHRyaWJ1dGUgPSBuZXcgSU5WT0tFSU5URVJGQUNFKGF0dHJpYnV0ZSwgMyk7Ci0KLSAgICAgICAgZmluYWwgaW50IHVuaXF1ZUF0dHJpYnV0ZSA9Ci0gICAgICAgICAgICBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKFRSQU5TTEVUX09VVFBVVF9JTlRFUkZBQ0UsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJhZGRVbmlxdWVBdHRyaWJ1dGUiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKCIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBTVFJJTkdfU0lHCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgU1RSSU5HX1NJRwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICJJKVYiKTsKLSAgICAgICAgX3VuaXF1ZUF0dHJpYnV0ZSA9IG5ldyBJTlZPS0VJTlRFUkZBQ0UodW5pcXVlQXR0cmlidXRlLCA0KTsKLQotICAgICAgICBmaW5hbCBpbnQgbmFtZXNwYWNlID0KLSAgICAgICAgICAgIGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoVFJBTlNMRVRfT1VUUFVUX0lOVEVSRkFDRSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm5hbWVzcGFjZUFmdGVyU3RhcnRFbGVtZW50IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIigiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgU1RSSU5HX1NJRwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIFNUUklOR19TSUcKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiKVYiKTsKLSAgICAgICAgX25hbWVzcGFjZSA9IG5ldyBJTlZPS0VJTlRFUkZBQ0UobmFtZXNwYWNlLCAzKTsKLQotICAgICAgICBpbnQgaW5kZXggPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKFRSQU5TTEVUX09VVFBVVF9JTlRFUkZBQ0UsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInN0YXJ0RG9jdW1lbnQiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoKVYiKTsKLSAgICAgICAgX3N0YXJ0RG9jdW1lbnQgPSBuZXcgSU5WT0tFSU5URVJGQUNFKGluZGV4LCAxKTsKLQotICAgICAgICBpbmRleCA9IGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoVFJBTlNMRVRfT1VUUFVUX0lOVEVSRkFDRSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJlbmREb2N1bWVudCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKClWIik7Ci0gICAgICAgIF9lbmREb2N1bWVudCA9IG5ldyBJTlZPS0VJTlRFUkZBQ0UoaW5kZXgsIDEpOwotCi0KLSAgICAgICAgaW5kZXggPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKE5PREVfSVRFUkFUT1IsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTRVRfU1RBUlRfTk9ERSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNFVF9TVEFSVF9OT0RFX1NJRyk7Ci0gICAgICAgIF9zZXRTdGFydE5vZGUgPSBuZXcgSU5WT0tFSU5URVJGQUNFKGluZGV4LCAyKTsKLQotICAgICAgICBpbmRleCA9IGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoTk9ERV9JVEVSQVRPUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJyZXNldCIsICIoKSIrTk9ERV9JVEVSQVRPUl9TSUcpOwotICAgICAgICBfcmVzZXQgPSBuZXcgSU5WT0tFSU5URVJGQUNFKGluZGV4LCAxKTsKLQotICAgICAgICBpbmRleCA9IGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoTk9ERV9JVEVSQVRPUiwgTkVYVCwgTkVYVF9TSUcpOwotICAgICAgICBfbmV4dE5vZGUgPSBuZXcgSU5WT0tFSU5URVJGQUNFKGluZGV4LCAxKTsKLQotICAgICAgICBfc2xvdEFsbG9jYXRvciA9IG5ldyBTbG90QWxsb2NhdG9yKCk7Ci0gICAgICAgIF9zbG90QWxsb2NhdG9yLmluaXRpYWxpemUoZ2V0TG9jYWxWYXJpYWJsZVJlZ2lzdHJ5KCkuZ2V0TG9jYWxzKGZhbHNlKSk7Ci0gICAgICAgIF9hbGxvY2F0b3JJbml0ID0gdHJ1ZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBbGxvY2F0ZXMgYSBsb2NhbCB2YXJpYWJsZS4gSWYgdGhlIHNsb3QgYWxsb2NhdG9yIGhhcyBhbHJlYWR5IGJlZW4KLSAgICAgKiBpbml0aWFsaXplZCwgdGhlbiBjYWxsIGFkZExvY2FsVmFyaWFibGUyKCkgc28gdGhhdCB0aGUgbmV3IHZhcmlhYmxlCi0gICAgICogaXMga25vd24gdG8gdGhlIGFsbG9jYXRvci4gRmFpbGluZyB0byBkbyB0aGlzIG1heSBjYXVzZSB0aGUgYWxsb2NhdG9yCi0gICAgICogdG8gcmV0dXJuIGEgc2xvdCB0aGF0IGlzIGFscmVhZHkgaW4gdXNlLgotICAgICAqLwotICAgIHB1YmxpYyBMb2NhbFZhcmlhYmxlR2VuIGFkZExvY2FsVmFyaWFibGUoU3RyaW5nIG5hbWUsIFR5cGUgdHlwZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluc3RydWN0aW9uSGFuZGxlIHN0YXJ0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW5zdHJ1Y3Rpb25IYW5kbGUgZW5kKQotICAgIHsKLSAgICAgICAgTG9jYWxWYXJpYWJsZUdlbiBsdmc7Ci0KLSAgICAgICAgaWYgKF9hbGxvY2F0b3JJbml0KSB7Ci0gICAgICAgICAgICBsdmcgPSBhZGRMb2NhbFZhcmlhYmxlMihuYW1lLCB0eXBlLCBzdGFydCk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBsdmcgPSBzdXBlci5hZGRMb2NhbFZhcmlhYmxlKG5hbWUsIHR5cGUsIHN0YXJ0LCBlbmQpOwotICAgICAgICAgICAgZ2V0TG9jYWxWYXJpYWJsZVJlZ2lzdHJ5KCkucmVnaXN0ZXJMb2NhbFZhcmlhYmxlKGx2Zyk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGx2ZzsKLSAgICB9Ci0KLSAgICBwdWJsaWMgTG9jYWxWYXJpYWJsZUdlbiBhZGRMb2NhbFZhcmlhYmxlMihTdHJpbmcgbmFtZSwgVHlwZSB0eXBlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluc3RydWN0aW9uSGFuZGxlIHN0YXJ0KQotICAgIHsKLSAgICAgICAgTG9jYWxWYXJpYWJsZUdlbiBsdmcgPSBzdXBlci5hZGRMb2NhbFZhcmlhYmxlKG5hbWUsIHR5cGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3Nsb3RBbGxvY2F0b3IuYWxsb2NhdGVTbG90KHR5cGUpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0LCBudWxsKTsKLSAgICAgICAgZ2V0TG9jYWxWYXJpYWJsZVJlZ2lzdHJ5KCkucmVnaXN0ZXJMb2NhbFZhcmlhYmxlKGx2Zyk7Ci0gICAgICAgIHJldHVybiBsdmc7Ci0gICAgfQotICAgIHByaXZhdGUgTG9jYWxWYXJpYWJsZVJlZ2lzdHJ5IGdldExvY2FsVmFyaWFibGVSZWdpc3RyeSgpIHsKLSAgICAgICAgaWYgKF9sb2NhbFZhcmlhYmxlUmVnaXN0cnkgPT0gbnVsbCkgewotICAgICAgICAgICAgX2xvY2FsVmFyaWFibGVSZWdpc3RyeSA9IG5ldyBMb2NhbFZhcmlhYmxlUmVnaXN0cnkoKTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBfbG9jYWxWYXJpYWJsZVJlZ2lzdHJ5OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEtlZXBzIHRyYWNrIG9mIGFsbCBsb2NhbCB2YXJpYWJsZXMgdXNlZCBpbiB0aGUgbWV0aG9kLgotICAgICAqIDxwPlRoZQotICAgICAqIHtAbGluayBNZXRob2RHZW4jYWRkTG9jYWxWYXJpYWJsZShTdHJpbmcsVHlwZSxJbnN0cnVjdGlvbkhhbmRsZSxJbnN0cnVjdGlvbkhhbmRsZSl9PC9jb2RlPgotICAgICAqIGFuZAotICAgICAqIHtAbGluayBNZXRob2RHZW4jYWRkTG9jYWxWYXJpYWJsZShTdHJpbmcsVHlwZSxpbnQsSW5zdHJ1Y3Rpb25IYW5kbGUsSW5zdHJ1Y3Rpb25IYW5kbGUpfTwvY29kZT4KLSAgICAgKiBtZXRob2RzIG9mIHtAbGluayBNZXRob2RHZW59IHdpbGwgb25seSBrZWVwIHRyYWNrIG9mCi0gICAgICoge0BsaW5rIExvY2FsVmFyaWFibGVHZW59IG9iamVjdCB1bnRpbCBpdCdzcyByZW1vdmVkIGJ5IGEgY2FsbCB0bwotICAgICAqIHtAbGluayBNZXRob2RHZW4jcmVtb3ZlTG9jYWxWYXJpYWJsZShMb2NhbFZhcmlhYmxlR2VuKX0uPC9wPgotICAgICAqIDxwPkluIG9yZGVyIHRvIHN1cHBvcnQgZWZmaWNpZW50IGNvcHlpbmcgb2YgbG9jYWwgdmFyaWFibGVzIHRvIG91dGxpbmVkCi0gICAgICogbWV0aG9kcyBieQotICAgICAqIHtAbGluayAjb3V0bGluZShJbnN0cnVjdGlvbkhhbmRsZSxJbnN0cnVjdGlvbkhhbmRsZSxTdHJpbmcsQ2xhc3NHZW5lcmF0b3IpfSwKLSAgICAgKiB0aGlzIGNsYXNzIGtlZXBzIHRyYWNrIG9mIGFsbCBsb2NhbCB2YXJpYWJsZXMgZGVmaW5lZCBieSB0aGUgbWV0aG9kLjwvcD4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgY2xhc3MgTG9jYWxWYXJpYWJsZVJlZ2lzdHJ5IHsKLSAgICAgICAgLyoqCi0gICAgICAgICAqIDxwPkEgPGNvZGU+amF2YS5sYW5nLkFycmF5TGlzdDwvY29kZT4gb2YgYWxsCi0gICAgICAgICAqIHtAbGluayBMb2NhbFZhcmlhYmxlR2VufXMgY3JlYXRlZCBmb3IgdGhpcyBtZXRob2QsIGluZGV4ZWQgYnkgdGhlCi0gICAgICAgICAqIHNsb3QgbnVtYmVyIG9mIHRoZSBsb2NhbCB2YXJpYWJsZS4gIFRoZSBKVk0gc3RhY2sgZnJhbWUgb2YgbG9jYWwKLSAgICAgICAgICogdmFyaWFibGVzIGlzIGRpdmlkZWQgaW50byAic2xvdHMiLiAgQSBzaW5nbGUgc2xvdCBjYW4gYmUgdXNlZCB0bwotICAgICAgICAgKiBzdG9yZSBtb3JlIHRoYW4gb25lIHZhcmlhYmxlIGluIGEgbWV0aG9kLCB3aXRob3V0IHJlZ2FyZCB0byB0eXBlLCBzbwotICAgICAgICAgKiBsb25nIGFzIHRoZSBieXRlIGNvZGUga2VlcHMgdGhlIHJhbmdlcyBvZiB0aGUgdHdvIGRpc2pvaW50LjwvcD4KLSAgICAgICAgICogPHA+SWYgb25seSBvbmUgcmVnaXN0cmF0aW9uIG9mIHVzZSBvZiBhIHBhcnRpY3VsYXIgc2xvdCBvY2N1cnMsIHRoZQotICAgICAgICAgKiBjb3JyZXNwb25kaW5nIGVudHJ5IG9mIDxjb2RlPl92YXJpYWJsZXM8L2NvZGU+IGNvbnRhaW5zIHRoZQotICAgICAgICAgKiA8Y29kZT5Mb2NhbFZhcmlhYmxlR2VuPC9jb2RlPjsgaWYgbW9yZSB0aGFuIG9uZSBvY2N1cnMsIHRoZQotICAgICAgICAgKiBjb3JyZXNwb25kaW5nIGVudHJ5IGNvbnRhaW5zIGFsbCBzdWNoIDxjb2RlPkxvY2FsVmFyaWFibGVHZW48L2NvZGU+cwotICAgICAgICAgKiByZWdpc3RlcmVkIGZvciB0aGUgc2FtZSBzbG90OyBhbmQgaWYgbm9uZSBvY2N1cnMsIHRoZSBlbnRyeSB3aWxsIGJlCi0gICAgICAgICAqIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAgICAgKi8KLSAgICAgICAgcHJvdGVjdGVkIEFycmF5TGlzdCBfdmFyaWFibGVzID0gbmV3IEFycmF5TGlzdCgpOwotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBNYXBzIGEgbmFtZSB0byBhIHtAbGluayBMb2NhbFZhcmlhYmxlR2VufQotICAgICAgICAgKi8KLSAgICAgICAgcHJvdGVjdGVkIEhhc2hNYXAgX25hbWVUb0xWR01hcCA9IG5ldyBIYXNoTWFwKCk7Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFJlZ2lzdGVycyBhIHtAbGluayBvcmcuYXBhY2hlLmJjZWwuZ2VuZXJpYy5Mb2NhbFZhcmlhYmxlR2VufQotICAgICAgICAgKiBmb3IgdGhpcyBtZXRob2QuCi0gICAgICAgICAqIDxwPjxiPlByZWNvbmRpdGlvbnM6PC9iPgotICAgICAgICAgKiA8dWw+Ci0gICAgICAgICAqIDxsaT5UaGUgcmFuZ2Ugb2YgaW5zdHJ1Y3Rpb25zIGZvciA8Y29kZT5sdmc8L2NvZGU+IGRvZXMgbm90Ci0gICAgICAgICAqIG92ZXJsYXAgd2l0aCB0aGUgcmFuZ2Ugb2YgaW5zdHJ1Y3Rpb25zIGZvciBhbnkKLSAgICAgICAgICogPGNvZGU+TG9jYWxWYXJpYWJsZUdlbjwvY29kZT4gd2l0aCB0aGUgc2FtZSBzbG90IGluZGV4IHByZXZpb3VzbHkKLSAgICAgICAgICogcmVnaXN0ZXJlZCBmb3IgdGhpcyBtZXRob2QuICA8Yj48ZW0+KFVuY2hlY2tlZC4pPC9lbT48L2I+PC9saT4KLSAgICAgICAgICogPC91bD48L3A+Ci0gICAgICAgICAqIEBwYXJhbSBsdmcgVGhlIHZhcmlhYmxlIHRvIGJlIHJlZ2lzdGVyZWQKLSAgICAgICAgICovCi0gICAgICAgIHByb3RlY3RlZCB2b2lkIHJlZ2lzdGVyTG9jYWxWYXJpYWJsZShMb2NhbFZhcmlhYmxlR2VuIGx2ZykgewotICAgICAgICAgICAgaW50IHNsb3QgPSBsdmcuZ2V0SW5kZXgoKTsKLQotICAgICAgICAgICAgaW50IHJlZ2lzdHJ5U2l6ZSA9IF92YXJpYWJsZXMuc2l6ZSgpOwotCi0gICAgICAgICAgICAvLyBJZiB0aGUgTG9jYWxWYXJpYWJsZUdlbiB1c2VzIGEgc2xvdCBpbmRleCBiZXlvbmQgYW55IHByZXZpb3VzbHkKLSAgICAgICAgICAgIC8vIGVuY291bnRlcmVkLCBleHBhbmQgdGhlIF92YXJpYWJsZXMsIHBhZGRpbmcgd2l0aCBpbnRlcnZlbmluZyBudWxsCi0gICAgICAgICAgICAvLyBlbnRyaWVzIGFzIHJlcXVpcmVkLgotICAgICAgICAgICAgaWYgKHNsb3QgPj0gcmVnaXN0cnlTaXplKSB7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IHJlZ2lzdHJ5U2l6ZTsgaSA8IHNsb3Q7IGkrKykgewotICAgICAgICAgICAgICAgICAgICBfdmFyaWFibGVzLmFkZChudWxsKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgX3ZhcmlhYmxlcy5hZGQobHZnKTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgLy8gSWYgdGhlIExvY2FsVmFyaWFibGVHZW4gcmV1c2VzIGEgc2xvdCwgbWFrZSBzdXJlIHRoZSBlbnRyeQotICAgICAgICAgICAgICAgIC8vIGluIF92YXJpYWJsZXMgY29udGFpbnMgYW4gQXJyYXlMaXN0IGFuZCBhZGQgdGhlIG5ld2x5Ci0gICAgICAgICAgICAgICAgLy8gcmVnaXN0ZXJlZCBMb2NhbFZhcmlhYmxlR2VuIHRvIHRoZSBsaXN0LiAgSWYgdGhlIGVudHJ5IGluCi0gICAgICAgICAgICAgICAgLy8gX3ZhcmlhYmxlcyBqdXN0IGNvbnRhaW5zIG51bGwgcGFkZGluZywgc3RvcmUgdGhlCi0gICAgICAgICAgICAgICAgLy8gTG9jYWxWYXJpYWJsZUdlbiBkaXJlY3RseS4KLSAgICAgICAgICAgICAgICBPYmplY3QgbG9jYWxzSW5TbG90ID0gX3ZhcmlhYmxlcy5nZXQoc2xvdCk7Ci0gICAgICAgICAgICAgICAgaWYgKGxvY2Fsc0luU2xvdCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChsb2NhbHNJblNsb3QgaW5zdGFuY2VvZiBMb2NhbFZhcmlhYmxlR2VuKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBBcnJheUxpc3QgbGlzdE9mTG9jYWxzSW5TbG90ID0gbmV3IEFycmF5TGlzdCgpOwotICAgICAgICAgICAgICAgICAgICAgICAgbGlzdE9mTG9jYWxzSW5TbG90LmFkZChsb2NhbHNJblNsb3QpOwotICAgICAgICAgICAgICAgICAgICAgICAgbGlzdE9mTG9jYWxzSW5TbG90LmFkZChsdmcpOwotICAgICAgICAgICAgICAgICAgICAgICAgX3ZhcmlhYmxlcy5zZXQoc2xvdCwgbGlzdE9mTG9jYWxzSW5TbG90KTsKLSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICgoQXJyYXlMaXN0KSBsb2NhbHNJblNsb3QpLmFkZChsdmcpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgX3ZhcmlhYmxlcy5zZXQoc2xvdCwgbHZnKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIHJlZ2lzdGVyQnlOYW1lKGx2Zyk7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogPHA+RmluZCB3aGljaCB7QGxpbmsgTG9jYWxWYXJpYWJsZUdlbn0sIGlmIGFueSwgaXMgcmVnaXN0ZXJlZCBmb3IgYQotICAgICAgICAgKiBwYXJ0aWN1bGFyIEpWTSBsb2NhbCBzdGFjayBmcmFtZSBzbG90IGF0IGEgcGFydGljdWxhciBwb3NpdGlvbiBpbiB0aGUKLSAgICAgICAgICogYnl0ZSBjb2RlIGZvciB0aGUgbWV0aG9kLjwvcD4KLSAgICAgICAgICogPHA+PGI+UHJlY29uZGl0aW9uczo8L2I+Ci0gICAgICAgICAqIDx1bD4KLSAgICAgICAgICogPGxpPlRoZSB7QGxpbmsgSW5zdHJ1Y3Rpb25MaXN0I3NldFBvc2l0aW9ucygpfSBoYXMgYmVlbiBjYWxsZWQgZm9yCi0gICAgICAgICAqIHRoZSB7QGxpbmsgSW5zdHJ1Y3Rpb25MaXN0fSBhc3NvY2lhdGVkIHdpdGggdGhpcwotICAgICAgICAgKiB7QGxpbmsgTWV0aG9kR2VuZXJhdG9yfS48L2xpPgotICAgICAgICAgKiA8L3VsPjwvcD4KLSAgICAgICAgICogQHBhcmFtIHNsb3QgdGhlIEpWTSBsb2NhbCBzdGFjayBmcmFtZSBzbG90IG51bWJlcgotICAgICAgICAgKiBAcGFyYW0gb2Zmc2V0IHRoZSBwb3NpdGlvbiBpbiB0aGUgYnl0ZSBjb2RlCi0gICAgICAgICAqIEByZXR1cm4gdGhlIDxjb2RlPkxvY2FsVmFyaWFibGVHZW48L2NvZGU+IGZvciB0aGUgbG9jYWwgdmFyaWFibGUKLSAgICAgICAgICogc3RvcmVkIGluIHRoZSByZWxldmFudCBzbG90IGF0IHRoZSByZWxldmFudCBvZmZzZXQ7IDxjb2RlPm51bGw8L2NvZGU+Ci0gICAgICAgICAqIGlmIHRoZXJlIGlzIG5vbmUuCi0gICAgICAgICAqLwotICAgICAgICBwcm90ZWN0ZWQgTG9jYWxWYXJpYWJsZUdlbiBsb29rdXBSZWdpc3RlcmVkTG9jYWxWYXJpYWJsZShpbnQgc2xvdCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG9mZnNldCkgewotICAgICAgICAgICAgT2JqZWN0IGxvY2Fsc0luU2xvdCA9IChfdmFyaWFibGVzICE9IG51bGwpID8gX3ZhcmlhYmxlcy5nZXQoc2xvdCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IG51bGw7Ci0KLSAgICAgICAgICAgIC8vIElmIHRoaXMgc2xvdCBpbmRleCB3YXMgbmV2ZXIgdXNlZCwgX3ZhcmlhYmxlcy5nZXQgd2lsbCByZXR1cm4KLSAgICAgICAgICAgIC8vIG51bGw7IGlmIGl0IHdhcyB1c2VkIG9uY2UsIGl0IHdpbGwgcmV0dXJuIHRoZSBMb2NhbFZhcmlhYmxlR2VuOwotICAgICAgICAgICAgLy8gbW9yZSB0aGFuIG9uY2UgaXQgd2lsbCByZXR1cm4gYW4gQXJyYXlMaXN0IG9mIGFsbCB0aGUKLSAgICAgICAgICAgIC8vIExvY2FsVmFyaWFibGVHZW5zIGZvciB2YXJpYWJsZXMgc3RvcmVkIGluIHRoYXQgc2xvdC4gIEZvciBlYWNoCi0gICAgICAgICAgICAvLyBMb2NhbFZhcmlhYmxlR2VuLCBjaGVjayB3aGV0aGVyIGl0cyByYW5nZSBpbmNsdWRlcyB0aGUKLSAgICAgICAgICAgIC8vIHNwZWNpZmllZCBvZmZzZXQsIGFuZCByZXR1cm4gdGhlIGZpcnN0IHN1Y2ggZW5jb3VudGVyZWQuCi0gICAgICAgICAgICBpZiAobG9jYWxzSW5TbG90ICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBpZiAobG9jYWxzSW5TbG90IGluc3RhbmNlb2YgTG9jYWxWYXJpYWJsZUdlbikgewotICAgICAgICAgICAgICAgICAgICBMb2NhbFZhcmlhYmxlR2VuIGx2ZyA9IChMb2NhbFZhcmlhYmxlR2VuKWxvY2Fsc0luU2xvdDsKLSAgICAgICAgICAgICAgICAgICAgaWYgKG9mZnNldEluTG9jYWxWYXJpYWJsZUdlblJhbmdlKGx2Zywgb2Zmc2V0KSkgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGx2ZzsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIEFycmF5TGlzdCBsaXN0T2ZMb2NhbHNJblNsb3QgPSAoQXJyYXlMaXN0KSBsb2NhbHNJblNsb3Q7Ci0gICAgICAgICAgICAgICAgICAgIGludCBzaXplID0gbGlzdE9mTG9jYWxzSW5TbG90LnNpemUoKTsKLQotICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewotICAgICAgICAgICAgICAgICAgICAgICAgTG9jYWxWYXJpYWJsZUdlbiBsdmcgPQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIChMb2NhbFZhcmlhYmxlR2VuKWxpc3RPZkxvY2Fsc0luU2xvdC5nZXQoaSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAob2Zmc2V0SW5Mb2NhbFZhcmlhYmxlR2VuUmFuZ2UobHZnLCBvZmZzZXQpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGx2ZzsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gTm8gbG9jYWwgdmFyaWFibGUgc3RvcmVkIGluIHRoZSBzcGVjaWZpZWQgc2xvdCBhdCB0aGUgc3BlY2lmaWVkCi0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiA8cD5TZXQgdXAgYSBtYXBwaW5nIG9mIHRoZSBuYW1lIG9mIHRoZSBzcGVjaWZpZWQKLSAgICAgICAgICoge0BsaW5rIExvY2FsVmFyaWFibGVHZW59IG9iamVjdCB0byB0aGUgPGNvZGU+TG9jYWxWYXJpYWJsZUdlbjwvY29kZT4KLSAgICAgICAgICogaXRzZWxmLjwvcD4KLSAgICAgICAgICogPHA+VGhpcyBpcyBhIGJpdCBvZiBhIGhhY2suICBYU0xUQyBpcyByZWx5aW5nIG9uIHRoZSBmYWN0IHRoYXQgdGhlCi0gICAgICAgICAqIG5hbWUgdGhhdCBpcyBiZWluZyBsb29rZWQgdXAgd29uJ3QgYmUgZHVwbGljYXRlZCwgd2hpY2ggaXNuJ3QKLSAgICAgICAgICogZ3VhcmFudGVlZC4gIEl0IHJlcGxhY2VzIGNvZGUgd2hpY2ggdXNlZCB0byBjYWxsCi0gICAgICAgICAqIHtAbGluayBNZXRob2RHZW4jZ2V0TG9jYWxWYXJpYWJsZXMoKX0gYW5kIGxvb3BlZCB0aHJvdWdoIHRoZQotICAgICAgICAgKiA8Y29kZT5Mb2NhbFZhcmlhYmxlR2VuPC9jb2RlPiBvYmplY3RzIGl0IGNvbnRhaW5lZCB0byBmaW5kIHRoZSBvbmUKLSAgICAgICAgICogd2l0aCB0aGUgc3BlY2lmaWVkIG5hbWUuICBIb3dldmVyLCA8Y29kZT5nZXRMb2NhbFZhcmlhYmxlcygpPC9jb2RlPgotICAgICAgICAgKiBoYXMgdGhlIHNpZGUgZWZmZWN0IG9mIHNldHRpbmcgdGhlIHN0YXJ0IGFuZCBlbmQgZm9yIGFueQotICAgICAgICAgKiA8Y29kZT5Mb2NhbFZhcmlhYmxlR2VuPC9jb2RlPiB3aGljaCBkaWQgbm90IGFscmVhZHkgaGF2ZSB0aGVtCi0gICAgICAgICAqIHNldCwgd2hpY2ggY2F1c2VzIHByb2JsZW1zIGZvciBvdXRsaW5pbmcuLjwvcD4KLSAgICAgICAgICogPHA+U2VlIGFsc28ge0BsaW5rICNsb29rVXBCeU5hbWUoU3RyaW5nKX0gYW5kCi0gICAgICAgICAqIHtAbGluayAjcmVtb3ZlQnlOYW1lVHJhY2tpbmcoTG9jYWxWYXJpYWJsZUdlbil9PC9QCi0gICAgICAgICAqIEBwYXJhbSBsdmcgYSA8Y29kZT5Mb2NhbFZhcmlhYmxlR2VuPC9jb2RlPgotICAgICAgICAgKi8KLSAgICAgICAgcHJvdGVjdGVkIHZvaWQgcmVnaXN0ZXJCeU5hbWUoTG9jYWxWYXJpYWJsZUdlbiBsdmcpIHsKLSAgICAgICAgICAgIE9iamVjdCBkdXBsaWNhdGVOYW1lRW50cnkgPSBfbmFtZVRvTFZHTWFwLmdldChsdmcuZ2V0TmFtZSgpKTsKLQotICAgICAgICAgICAgaWYgKGR1cGxpY2F0ZU5hbWVFbnRyeSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgX25hbWVUb0xWR01hcC5wdXQobHZnLmdldE5hbWUoKSwgbHZnKTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgQXJyYXlMaXN0IHNhbWVOYW1lTGlzdDsKLQotICAgICAgICAgICAgICAgIGlmIChkdXBsaWNhdGVOYW1lRW50cnkgaW5zdGFuY2VvZiBBcnJheUxpc3QpIHsKLSAgICAgICAgICAgICAgICAgICAgc2FtZU5hbWVMaXN0ID0gKEFycmF5TGlzdCkgZHVwbGljYXRlTmFtZUVudHJ5OwotICAgICAgICAgICAgICAgICAgICBzYW1lTmFtZUxpc3QuYWRkKGx2Zyk7Ci0gICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgc2FtZU5hbWVMaXN0ID0gbmV3IEFycmF5TGlzdCgpOwotICAgICAgICAgICAgICAgICAgICBzYW1lTmFtZUxpc3QuYWRkKGR1cGxpY2F0ZU5hbWVFbnRyeSk7Ci0gICAgICAgICAgICAgICAgICAgIHNhbWVOYW1lTGlzdC5hZGQobHZnKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBfbmFtZVRvTFZHTWFwLnB1dChsdmcuZ2V0TmFtZSgpLCBzYW1lTmFtZUxpc3QpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFJlbW92ZSB0aGUgbWFwcGluZyBmcm9tIHRoZSBuYW1lIG9mIHRoZSBzcGVjaWZpZWQKLSAgICAgICAgICoge0BsaW5rIExvY2FsVmFyaWFibGVHZW59IHRvIGl0c2VsZi4KLSAgICAgICAgICogU2VlIGFsc28ge0BsaW5rICNyZWdpc3RlckJ5TmFtZShMb2NhbFZhcmlhYmxlR2VuKX0gYW5kCi0gICAgICAgICAqIHtAbGluayAjbG9va1VwQnlOYW1lKFN0cmluZyl9Ci0gICAgICAgICAqIEBwYXJhbSBsdmcgYSA8Y29kZT5Mb2NhbFZhcmlhYmxlR2VuPC9jb2RlPgotICAgICAgICAgKi8KLSAgICAgICAgcHJvdGVjdGVkIHZvaWQgcmVtb3ZlQnlOYW1lVHJhY2tpbmcoTG9jYWxWYXJpYWJsZUdlbiBsdmcpIHsKLSAgICAgICAgICAgIE9iamVjdCBkdXBsaWNhdGVOYW1lRW50cnkgPSBfbmFtZVRvTFZHTWFwLmdldChsdmcuZ2V0TmFtZSgpKTsKLQotICAgICAgICAgICAgaWYgKGR1cGxpY2F0ZU5hbWVFbnRyeSBpbnN0YW5jZW9mIEFycmF5TGlzdCkgewotICAgICAgICAgICAgICAgIEFycmF5TGlzdCBzYW1lTmFtZUxpc3QgPSAoQXJyYXlMaXN0KSBkdXBsaWNhdGVOYW1lRW50cnk7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzYW1lTmFtZUxpc3Quc2l6ZSgpOyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKHNhbWVOYW1lTGlzdC5nZXQoaSkgPT0gbHZnKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzYW1lTmFtZUxpc3QucmVtb3ZlKGkpOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIF9uYW1lVG9MVkdNYXAucmVtb3ZlKGx2Zyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogPHA+R2l2ZW4gdGhlIG5hbWUgb2YgYSB2YXJpYWJsZSwgZmluZHMgYSB7QGxpbmsgTG9jYWxWYXJpYWJsZUdlbn0KLSAgICAgICAgICogY29ycmVzcG9uZGluZyB0byBpdC48L3A+Ci0gICAgICAgICAqIDxwPlNlZSBhbHNvIHtAbGluayAjcmVnaXN0ZXJCeU5hbWUoTG9jYWxWYXJpYWJsZUdlbil9IGFuZAotICAgICAgICAgKiB7QGxpbmsgI3JlbW92ZUJ5TmFtZVRyYWNraW5nKExvY2FsVmFyaWFibGVHZW4pfTwvcD4KLSAgICAgICAgICogQHBhcmFtIG5hbWUKLSAgICAgICAgICogQHJldHVybgotICAgICAgICAgKi8KLSAgICAgICAgcHJvdGVjdGVkIExvY2FsVmFyaWFibGVHZW4gbG9va1VwQnlOYW1lKFN0cmluZyBuYW1lKSB7Ci0gICAgICAgICAgICBMb2NhbFZhcmlhYmxlR2VuIGx2ZyA9IG51bGw7Ci0gICAgICAgICAgICBPYmplY3QgZHVwbGljYXRlTmFtZUVudHJ5ID0gX25hbWVUb0xWR01hcC5nZXQobmFtZSk7Ci0KLSAgICAgICAgICAgIGlmIChkdXBsaWNhdGVOYW1lRW50cnkgaW5zdGFuY2VvZiBBcnJheUxpc3QpIHsKLSAgICAgICAgICAgICAgICBBcnJheUxpc3Qgc2FtZU5hbWVMaXN0ID0gKEFycmF5TGlzdCkgZHVwbGljYXRlTmFtZUVudHJ5OwotCi0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzYW1lTmFtZUxpc3Quc2l6ZSgpOyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgbHZnID0gKExvY2FsVmFyaWFibGVHZW4pc2FtZU5hbWVMaXN0LmdldChpKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGx2Zy5nZXROYW1lKCkgPT0gbmFtZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIGx2ZyA9IChMb2NhbFZhcmlhYmxlR2VuKSBkdXBsaWNhdGVOYW1lRW50cnk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIHJldHVybiBsdmc7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogPHA+R2V0cyBhbGwge0BsaW5rIExvY2FsVmFyaWFibGVHZW59IG9iamVjdHMgZm9yIHRoaXMgbWV0aG9kLjwvcD4KLSAgICAgICAgICogPHA+V2hlbiB0aGUgPGNvZGU+aW5jbHVkZVJlbW92ZWQ8L2NvZGU+IGFyZ3VtZW50IGhhcyB0aGUgdmFsdWUKLSAgICAgICAgICogPGNvZGU+ZmFsc2U8L2NvZGU+LCB0aGlzIG1ldGhvZCByZXBsYWNlcyB1c2VzIG9mCi0gICAgICAgICAqIHtAbGluayBNZXRob2RHZW4jZ2V0TG9jYWxWYXJpYWJsZXMoKX0gd2hpY2ggaGFzCi0gICAgICAgICAqIGEgc2lkZS1lZmZlY3Qgb2Ygc2V0dGluZyB0aGUgc3RhcnQgYW5kIGVuZCByYW5nZSBmb3IgYW55Ci0gICAgICAgICAqIDxjb2RlPkxvY2FsVmFyaWFibGVHZW48L2NvZGU+IGlmIGVpdGhlciB3YXMgPGNvZGU+bnVsbDwvY29kZT4uICBUaGF0Ci0gICAgICAgICAqIHNpZGUtZWZmZWN0IGNhdXNlcyBwcm9ibGVtcyBmb3Igb3V0bGluaW5nIG9mIGNvZGUgaW4gWFNMVEMuCi0gICAgICAgICAqIEBwYXJhbSBpbmNsdWRlUmVtb3ZlZCBTcGVjaWZpZXMgd2hldGhlciBhbGwgbG9jYWwgdmFyaWFibGVzIGV2ZXIKLSAgICAgICAgICogZGVjbGFyZWQgc2hvdWxkIGJlIHJldHVybmVkICg8Y29kZT50cnVlPC9jb2RlPikgb3Igb25seSB0aG9zZSBub3QKLSAgICAgICAgICogcmVtb3ZlZCAoPGNvZGU+ZmFsc2U8L2NvZGU+KQotICAgICAgICAgKiBAcmV0dXJuIGFuIGFycmF5IG9mIDxjb2RlPkxvY2FsVmFyaWFibGVHZW48L2NvZGU+IGNvbnRhaW5pbmcgYWxsIHRoZQotICAgICAgICAgKiBsb2NhbCB2YXJpYWJsZXMKLSAgICAgICAgICovCi0gICAgICAgIHByb3RlY3RlZCBMb2NhbFZhcmlhYmxlR2VuW10gZ2V0TG9jYWxzKGJvb2xlYW4gaW5jbHVkZVJlbW92ZWQpIHsKLSAgICAgICAgICAgIExvY2FsVmFyaWFibGVHZW5bXSBsb2NhbHMgPSBudWxsOwotICAgICAgICAgICAgQXJyYXlMaXN0IGFsbFZhcnNFdmVyRGVjbGFyZWQgPSBuZXcgQXJyYXlMaXN0KCk7Ci0KLSAgICAgICAgICAgIGlmIChpbmNsdWRlUmVtb3ZlZCkgewotICAgICAgICAgICAgICAgIGludCBzbG90Q291bnQgPSBhbGxWYXJzRXZlckRlY2xhcmVkLnNpemUoKTsKLQotICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc2xvdENvdW50OyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgT2JqZWN0IHNsb3RFbnRyaWVzID0gX3ZhcmlhYmxlcy5nZXQoaSk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChzbG90RW50cmllcyAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2xvdEVudHJpZXMgaW5zdGFuY2VvZiBBcnJheUxpc3QpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBBcnJheUxpc3Qgc2xvdExpc3QgPSAoQXJyYXlMaXN0KSBzbG90RW50cmllczsKLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgc2xvdExpc3Quc2l6ZSgpOyBqKyspIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxsVmFyc0V2ZXJEZWNsYXJlZC5hZGQoc2xvdExpc3QuZ2V0KGkpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsbFZhcnNFdmVyRGVjbGFyZWQuYWRkKHNsb3RFbnRyaWVzKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgSXRlcmF0b3IgbmFtZVZhcnNQYWlyc0l0ZXIgPSBfbmFtZVRvTFZHTWFwLmVudHJ5U2V0KCkuaXRlcmF0b3IoKTsKLQotICAgICAgICAgICAgICAgIHdoaWxlIChuYW1lVmFyc1BhaXJzSXRlci5oYXNOZXh0KCkpIHsKLSAgICAgICAgICAgICAgICAgICAgTWFwLkVudHJ5IG5hbWVWYXJzUGFpciA9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKE1hcC5FbnRyeSkgbmFtZVZhcnNQYWlyc0l0ZXIubmV4dCgpOwotICAgICAgICAgICAgICAgICAgICBPYmplY3QgdmFycyA9IG5hbWVWYXJzUGFpci5nZXRWYWx1ZSgpOwotICAgICAgICAgICAgICAgICAgICBpZiAodmFycyAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAodmFycyBpbnN0YW5jZW9mIEFycmF5TGlzdCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFycmF5TGlzdCB2YXJzTGlzdCA9IChBcnJheUxpc3QpIHZhcnM7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YXJzTGlzdC5zaXplKCk7IGkrKykgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbGxWYXJzRXZlckRlY2xhcmVkLmFkZCh2YXJzTGlzdC5nZXQoaSkpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxsVmFyc0V2ZXJEZWNsYXJlZC5hZGQodmFycyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGxvY2FscyA9IG5ldyBMb2NhbFZhcmlhYmxlR2VuW2FsbFZhcnNFdmVyRGVjbGFyZWQuc2l6ZSgpXTsKLSAgICAgICAgICAgIGFsbFZhcnNFdmVyRGVjbGFyZWQudG9BcnJheShsb2NhbHMpOwotCi0gICAgICAgICAgICByZXR1cm4gbG9jYWxzOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIGEgcGFydGljdWxhciB2YXJpYWJsZSBpcyBpbiB1c2UgYXQgYSBwYXJ0aWN1bGFyIG9mZnNldAotICAgICAqIGluIHRoZSBieXRlIGNvZGUgZm9yIHRoaXMgbWV0aG9kLgotICAgICAqIDxwPjxiPlByZWNvbmRpdGlvbnM6PC9iPgotICAgICAqIDx1bD4KLSAgICAgKiA8bGk+VGhlIHtAbGluayBJbnN0cnVjdGlvbkxpc3Qjc2V0UG9zaXRpb25zKCl9IGhhcyBiZWVuIGNhbGxlZCBmb3IgdGhlCi0gICAgICoge0BsaW5rIEluc3RydWN0aW9uTGlzdH0gYXNzb2NpYXRlZCB3aXRoIHRoaXMge0BsaW5rIE1ldGhvZEdlbmVyYXRvcn0uCi0gICAgICogPC9saT48L3VsPjwvcD4KLSAgICAgKiBAcGFyYW0gbHZnIHRoZSB7QGxpbmsgTG9jYWxWYXJpYWJsZUdlbn0gZm9yIHRoZSB2YXJpYWJsZQotICAgICAqIEBwYXJhbSBvZmZzZXQgdGhlIHBvc2l0aW9uIGluIHRoZSBieXRlIGNvZGUKLSAgICAgKiBAcmV0dXJuIDxjb2RlPnRydWU8L2NvZGU+IGlmIGFuZCBvbmx5IGlmIHRoZSBzcGVjaWZpZWQgdmFyaWFibGUgaXMgaW4KLSAgICAgKiB1c2UgYXQgdGhlIHBhcnRpY3VsYXIgYnl0ZSBjb2RlIG9mZnNldC4KLSAgICAgKi8KLSAgICBib29sZWFuIG9mZnNldEluTG9jYWxWYXJpYWJsZUdlblJhbmdlKExvY2FsVmFyaWFibGVHZW4gbHZnLCBpbnQgb2Zmc2V0KSB7Ci0gICAgICAgIEluc3RydWN0aW9uSGFuZGxlIGx2Z1N0YXJ0ID0gbHZnLmdldFN0YXJ0KCk7Ci0gICAgICAgIEluc3RydWN0aW9uSGFuZGxlIGx2Z0VuZCA9IGx2Zy5nZXRFbmQoKTsKLQotICAgICAgICAvLyBJZiBubyBzdGFydCBoYW5kbGUgaXMgcmVjb3JkZWQgZm9yIHRoZSBMb2NhbFZhcmlhYmxlR2VuLCBpdCBpcwotICAgICAgICAvLyBhc3N1bWVkIHRvIGJlIGluIHVzZSBmcm9tIHRoZSBiZWdpbm5pbmcgb2YgdGhlIG1ldGhvZC4KLSAgICAgICAgaWYgKGx2Z1N0YXJ0ID09IG51bGwpIHsKLSAgICAgICAgICAgIGx2Z1N0YXJ0ID0gZ2V0SW5zdHJ1Y3Rpb25MaXN0KCkuZ2V0U3RhcnQoKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIElmIG5vIGVuZCBoYW5kbGUgaXMgcmVjb3JkZWQgZm9yIHRoZSBMb2NhbFZhcmlhYmxlR2VuLCBpdCBpcyBhc3N1bWVkCi0gICAgICAgIC8vIHRvIGJlIGluIHVzZSB0byB0aGUgZW5kIG9mIHRoZSBtZXRob2QuCi0gICAgICAgIGlmIChsdmdFbmQgPT0gbnVsbCkgewotICAgICAgICAgICAgbHZnRW5kID0gZ2V0SW5zdHJ1Y3Rpb25MaXN0KCkuZ2V0RW5kKCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBEb2VzIHRoZSByYW5nZSBvZiB0aGUgaW5zdHJ1Y3Rpb24gaW5jbHVkZSB0aGUgc3BlY2lmaWVkIG9mZnNldD8KLSAgICAgICAgLy8gTm90ZSB0aGF0IHRoZSBJbnN0cnVjdGlvbkhhbmRsZS5nZXRQb3NpdGlvbiBtZXRob2QgcmV0dXJucyB0aGUKLSAgICAgICAgLy8gb2Zmc2V0IG9mIHRoZSBiZWdpbm5pbmcgb2YgYW4gaW5zdHJ1Y3Rpb24uICBBIExvY2FsVmFyaWFibGVHZW4ncwotICAgICAgICAvLyByYW5nZSBpbmNsdWRlcyB0aGUgZW5kIGluc3RydWN0aW9uIGl0c2VsZiwgc28gdGhhdCBpbnN0cnVjdGlvbidzCi0gICAgICAgIC8vIGxlbmd0aCBtdXN0IGJlIHRha2VuIGludG8gY29uc2lkZXJhdGlvbiBpbiBjb21wdXRpbmcgd2hldGhlciB0aGUKLSAgICAgICAgLy8gdmFyaWJsZSBpcyBpbiByYW5nZSBhdCBhIHBhcnRpY3VsYXIgb2Zmc2V0LgotICAgICAgICByZXR1cm4gKChsdmdTdGFydC5nZXRQb3NpdGlvbigpIDw9IG9mZnNldCkKLSAgICAgICAgICAgICAgICAgICAgJiYgKGx2Z0VuZC5nZXRQb3NpdGlvbigpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBsdmdFbmQuZ2V0SW5zdHJ1Y3Rpb24oKS5nZXRMZW5ndGgoKSA+PSBvZmZzZXQpKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCByZW1vdmVMb2NhbFZhcmlhYmxlKExvY2FsVmFyaWFibGVHZW4gbHZnKSB7Ci0gICAgICAgIF9zbG90QWxsb2NhdG9yLnJlbGVhc2VTbG90KGx2Zyk7Ci0gICAgICAgIGdldExvY2FsVmFyaWFibGVSZWdpc3RyeSgpLnJlbW92ZUJ5TmFtZVRyYWNraW5nKGx2Zyk7Ci0gICAgICAgIHN1cGVyLnJlbW92ZUxvY2FsVmFyaWFibGUobHZnKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb24gbG9hZERPTSgpIHsKLSAgICAgICAgcmV0dXJuIF9hbG9hZERvbTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb24gc3RvcmVET00oKSB7Ci0gICAgICAgIHJldHVybiBfYXN0b3JlRG9tOwotICAgIH0KLQotICAgIHB1YmxpYyBJbnN0cnVjdGlvbiBzdG9yZUhhbmRsZXIoKSB7Ci0gICAgICAgIHJldHVybiBfYXN0b3JlSGFuZGxlcjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb24gbG9hZEhhbmRsZXIoKSB7Ci0gICAgICAgIHJldHVybiBfYWxvYWRIYW5kbGVyOwotICAgIH0KLQotICAgIHB1YmxpYyBJbnN0cnVjdGlvbiBzdG9yZUl0ZXJhdG9yKCkgewotICAgICAgICByZXR1cm4gX2FzdG9yZUl0ZXJhdG9yOwotICAgIH0KLQotICAgIHB1YmxpYyBJbnN0cnVjdGlvbiBsb2FkSXRlcmF0b3IoKSB7Ci0gICAgICAgIHJldHVybiBfYWxvYWRJdGVyYXRvcjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgZmluYWwgSW5zdHJ1Y3Rpb24gc2V0U3RhcnROb2RlKCkgewotICAgICAgICByZXR1cm4gX3NldFN0YXJ0Tm9kZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgZmluYWwgSW5zdHJ1Y3Rpb24gcmVzZXQoKSB7Ci0gICAgICAgIHJldHVybiBfcmVzZXQ7Ci0gICAgfQotCi0gICAgcHVibGljIGZpbmFsIEluc3RydWN0aW9uIG5leHROb2RlKCkgewotICAgICAgICByZXR1cm4gX25leHROb2RlOwotICAgIH0KLQotICAgIHB1YmxpYyBmaW5hbCBJbnN0cnVjdGlvbiBzdGFydEVsZW1lbnQoKSB7Ci0gICAgICAgIHJldHVybiBfc3RhcnRFbGVtZW50OwotICAgIH0KLQotICAgIHB1YmxpYyBmaW5hbCBJbnN0cnVjdGlvbiBlbmRFbGVtZW50KCkgewotICAgICAgICByZXR1cm4gX2VuZEVsZW1lbnQ7Ci0gICAgfQotCi0gICAgcHVibGljIGZpbmFsIEluc3RydWN0aW9uIHN0YXJ0RG9jdW1lbnQoKSB7Ci0gICAgICAgIHJldHVybiBfc3RhcnREb2N1bWVudDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgZmluYWwgSW5zdHJ1Y3Rpb24gZW5kRG9jdW1lbnQoKSB7Ci0gICAgICAgIHJldHVybiBfZW5kRG9jdW1lbnQ7Ci0gICAgfQotCi0gICAgcHVibGljIGZpbmFsIEluc3RydWN0aW9uIGF0dHJpYnV0ZSgpIHsKLSAgICAgICAgcmV0dXJuIF9hdHRyaWJ1dGU7Ci0gICAgfQotCi0gICAgcHVibGljIGZpbmFsIEluc3RydWN0aW9uIHVuaXF1ZUF0dHJpYnV0ZSgpIHsKLSAgICAgICAgcmV0dXJuIF91bmlxdWVBdHRyaWJ1dGU7Ci0gICAgfQotCi0gICAgcHVibGljIGZpbmFsIEluc3RydWN0aW9uIG5hbWVzcGFjZSgpIHsKLSAgICAgICAgcmV0dXJuIF9uYW1lc3BhY2U7Ci0gICAgfQotCi0gICAgcHVibGljIEluc3RydWN0aW9uIGxvYWRDdXJyZW50Tm9kZSgpIHsKLSAgICAgICAgaWYgKF9pbG9hZEN1cnJlbnQgPT0gbnVsbCkgewotICAgICAgICAgICAgaW50IGlkeCA9IGdldExvY2FsSW5kZXgoImN1cnJlbnQiKTsKLSAgICAgICAgICAgIGlmIChpZHggPiAwKQotICAgICAgICAgICAgICAgIF9pbG9hZEN1cnJlbnQgPSBuZXcgSUxPQUQoaWR4KTsKLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICBfaWxvYWRDdXJyZW50ID0gbmV3IElDT05TVCgwKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gX2lsb2FkQ3VycmVudDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb24gc3RvcmVDdXJyZW50Tm9kZSgpIHsKLSAgICAgICAgcmV0dXJuIF9pc3RvcmVDdXJyZW50ICE9IG51bGwKLSAgICAgICAgICAgID8gX2lzdG9yZUN1cnJlbnQKLSAgICAgICAgICAgIDogKF9pc3RvcmVDdXJyZW50ID0gbmV3IElTVE9SRShnZXRMb2NhbEluZGV4KCJjdXJyZW50IikpKTsKLSAgICB9Ci0KLSAgICAvKiogYnkgZGVmYXVsdCBjb250ZXh0IG5vZGUgaXMgdGhlIHNhbWUgYXMgY3VycmVudCBub2RlLiBNSzQzNyAqLwotICAgIHB1YmxpYyBJbnN0cnVjdGlvbiBsb2FkQ29udGV4dE5vZGUoKSB7Ci0gICAgICAgIHJldHVybiBsb2FkQ3VycmVudE5vZGUoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb24gc3RvcmVDb250ZXh0Tm9kZSgpIHsKLSAgICAgICAgcmV0dXJuIHN0b3JlQ3VycmVudE5vZGUoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldExvY2FsSW5kZXgoU3RyaW5nIG5hbWUpIHsKLSAgICAgICAgcmV0dXJuIGdldExvY2FsVmFyaWFibGUobmFtZSkuZ2V0SW5kZXgoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgTG9jYWxWYXJpYWJsZUdlbiBnZXRMb2NhbFZhcmlhYmxlKFN0cmluZyBuYW1lKSB7Ci0gICAgICAgIHJldHVybiBnZXRMb2NhbFZhcmlhYmxlUmVnaXN0cnkoKS5sb29rVXBCeU5hbWUobmFtZSk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0TWF4TG9jYWxzKCkgewotCi0gICAgICAgIC8vIEdldCB0aGUgY3VycmVudCBudW1iZXIgb2YgbG9jYWwgdmFyaWFibGUgc2xvdHMKLSAgICAgICAgaW50IG1heExvY2FscyA9IHN1cGVyLmdldE1heExvY2FscygpOwotICAgICAgICBpbnQgcHJldkxvY2FscyA9IG1heExvY2FsczsKLQotICAgICAgICAvLyBHZXQgbnVtZXIgb2YgYWN0dWFsIHZhcmlhYmxlcwotICAgICAgICBmaW5hbCBMb2NhbFZhcmlhYmxlR2VuW10gbG9jYWxWYXJzID0gc3VwZXIuZ2V0TG9jYWxWYXJpYWJsZXMoKTsKLSAgICAgICAgaWYgKGxvY2FsVmFycyAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAobG9jYWxWYXJzLmxlbmd0aCA+IG1heExvY2FscykKLSAgICAgICAgICAgICAgICBtYXhMb2NhbHMgPSBsb2NhbFZhcnMubGVuZ3RoOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gV2Ugd2FudCBhdCBsZWFzdCA1IGxvY2FsIHZhcmlhYmxlIHNsb3RzIChmb3IgcGFyYW1ldGVycykKLSAgICAgICAgaWYgKG1heExvY2FscyA8IDUpIG1heExvY2FscyA9IDU7Ci0KLSAgICAgICAgc3VwZXIuc2V0TWF4TG9jYWxzKG1heExvY2Fscyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQWRkIGEgcHJlLWNvbXBpbGVkIHBhdHRlcm4gdG8gdGhpcyBtb2RlLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGFkZEluc3RydWN0aW9uTGlzdChQYXR0ZXJuIHBhdHRlcm4sIEluc3RydWN0aW9uTGlzdCBpbGlzdCkgewotICAgICAgICBfcHJlQ29tcGlsZWQucHV0KHBhdHRlcm4sIGlsaXN0KTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIGluc3RydWN0aW9uIGxpc3QgZm9yIGEgcHJlLWNvbXBpbGVkIHBhdHRlcm4uIFVzZWQgYnkKLSAgICAgKiB0ZXN0IHNlcXVlbmNlcyB0byBhdm9pZCBjb21waWxpbmcgcGF0dGVybnMgbW9yZSB0aGFuIG9uY2UuCi0gICAgICovCi0gICAgcHVibGljIEluc3RydWN0aW9uTGlzdCBnZXRJbnN0cnVjdGlvbkxpc3QoUGF0dGVybiBwYXR0ZXJuKSB7Ci0gICAgICAgIHJldHVybiBfcHJlQ29tcGlsZWQuZ2V0KHBhdHRlcm4pOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFVzZWQgdG8ga2VlcCB0cmFjayBvZiBhbiBvdXRsaW5lYWJsZSBjaHVuayBvZiBpbnN0cnVjdGlvbnMgaW4gdGhlCi0gICAgICogY3VycmVudCBtZXRob2QuICBTZWUge0BsaW5rIE91dGxpbmVhYmxlQ2h1bmtTdGFydH0gYW5kCi0gICAgICoge0BsaW5rIE91dGxpbmVhYmxlQ2h1bmtFbmR9IGZvciBtb3JlIGluZm9ybWF0aW9uLgotICAgICAqLwotICAgIHByaXZhdGUgY2xhc3MgQ2h1bmsgaW1wbGVtZW50cyBDb21wYXJhYmxlIHsKLSAgICAgICAgLyoqCi0gICAgICAgICAqIHtAbGluayBJbnN0cnVjdGlvbkhhbmRsZX0gb2YgdGhlIGZpcnN0IGluc3RydWN0aW9uIGluIHRoZSBvdXRsaW5lYWJsZQotICAgICAgICAgKiBjaHVuay4KLSAgICAgICAgICovCi0gICAgICAgIHByaXZhdGUgSW5zdHJ1Y3Rpb25IYW5kbGUgbV9zdGFydDsKLQotICAgICAgICAvKioKLSAgICAgICAgICoge0BsaW5rIG9yZy5hcGFjaGUuYmNlbC5nZW5lcmljLkluc3RydWN0aW9uSGFuZGxlfSBvZiB0aGUgZmlyc3QKLSAgICAgICAgICogaW5zdHJ1Y3Rpb24gaW4gdGhlIG91dGxpbmVhYmxlIGNodW5rLgotICAgICAgICAgKi8KLSAgICAgICAgcHJpdmF0ZSBJbnN0cnVjdGlvbkhhbmRsZSBtX2VuZDsKLQotICAgICAgICAvKioKLSAgICAgICAgICogTnVtYmVyIG9mIGJ5dGVzIGluIHRoZSBpbnN0cnVjdGlvbnMgY29udGFpbmVkIGluIHRoaXMgb3V0bGluZWFibGUKLSAgICAgICAgICogY2h1bmsuCi0gICAgICAgICAqLwotICAgICAgICBwcml2YXRlIGludCBtX3NpemU7Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIDxwPkNvbnN0cnVjdG9yIGZvciBhbiBvdXRsaW5lYWJsZSB7QGxpbmsgTWV0aG9kR2VuZXJhdG9yLkNodW5rfS48L3A+Ci0gICAgICAgICAqIDxwPjxiPlByZWNvbmRpdGlvbnM6PC9iPgotICAgICAgICAgKiA8dWw+Ci0gICAgICAgICAqIDxsaT5UaGUge0BsaW5rIEluc3RydWN0aW9uTGlzdCNzZXRQb3NpdGlvbnMoKX0gaGFzIGJlZW4gY2FsbGVkIGZvcgotICAgICAgICAgKiB0aGUge0BsaW5rIEluc3RydWN0aW9uTGlzdH0gYXNzb2NpYXRlZCB3aXRoIHRoaXMKLSAgICAgICAgICoge0BsaW5rIE1ldGhvZEdlbmVyYXRvcn0uPC9saT4KLSAgICAgICAgICogPC91bD48L3A+Ci0gICAgICAgICAqIEBwYXJhbSBzdGFydCBUaGUge0BsaW5rIEluc3RydWN0aW9uSGFuZGxlfSBvZiB0aGUgZmlyc3QKLSAgICAgICAgICogICAgICAgICAgICAgIGluc3RydWN0aW9uIGluIHRoZSBvdXRsaW5lYWJsZSBjaHVuay4KLSAgICAgICAgICogQHBhcmFtIGVuZCBUaGUge0BsaW5rIEluc3RydWN0aW9uSGFuZGxlfSBvZiB0aGUgbGFzdAotICAgICAgICAgKiAgICAgICAgICAgIGluc3RydWN0aW9uIGluIHRoZSBvdXRsaW5lYWJsZSBjaHVuay4KLSAgICAgICAgICovCi0gICAgICAgIENodW5rKEluc3RydWN0aW9uSGFuZGxlIHN0YXJ0LCBJbnN0cnVjdGlvbkhhbmRsZSBlbmQpIHsKLSAgICAgICAgICAgIG1fc3RhcnQgPSBzdGFydDsKLSAgICAgICAgICAgIG1fZW5kID0gZW5kOwotICAgICAgICAgICAgbV9zaXplID0gZW5kLmdldFBvc2l0aW9uKCkgLSBzdGFydC5nZXRQb3NpdGlvbigpOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIERldGVybWluZXMgd2hldGhlciB0aGlzIG91dGxpbmVhYmxlIHtAbGluayBNZXRob2RHZW5lcmF0b3IuQ2h1bmt9IGlzCi0gICAgICAgICAqIGZvbGxvd2VkIGltbWVkaWF0ZWx5IGJ5IHRoZSBhcmd1bWVudAotICAgICAgICAgKiA8Y29kZT5NZXRob2RHZW5lcmF0b3IuQ2h1bms8L2NvZGU+LCB3aXRoIG5vIG90aGVyIGludGVydmVuaW5nCi0gICAgICAgICAqIGluc3RydWN0aW9ucywgaW5jbHVkaW5nIHtAbGluayBPdXRsaW5lYWJsZUNodW5rU3RhcnR9IG9yCi0gICAgICAgICAqIHtAbGluayBPdXRsaW5lYWJsZUNodW5rRW5kfSBpbnN0cnVjdGlvbnMuCi0gICAgICAgICAqIEBwYXJhbSBuZWlnaGJvdXIgYW4gb3V0bGluZWFibGUge0BsaW5rIE1ldGhvZEdlbmVyYXRvci5DaHVua30KLSAgICAgICAgICogQHJldHVybiA8Y29kZT50cnVlPC9jb2RlPiBpZiBhbmQgb25seSBpZiB0aGUgYXJndW1lbnQgY2h1bmsKLSAgICAgICAgICogaW1tZWRpYXRlbHkgZm9sbG93cyA8Y29kZT50aGlzPC9jb2RlPiBjaHVuawotICAgICAgICAgKi8KLSAgICAgICAgYm9vbGVhbiBpc0FkamFjZW50VG8oQ2h1bmsgbmVpZ2hib3VyKSB7Ci0gICAgICAgICAgICByZXR1cm4gZ2V0Q2h1bmtFbmQoKS5nZXROZXh0KCkgPT0gbmVpZ2hib3VyLmdldENodW5rU3RhcnQoKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBHZXR0ZXIgbWV0aG9kIGZvciB0aGUgc3RhcnQgb2YgdGhpcyB7QGxpbmtlIE1ldGhvZEdlbmVyYXRvci5DaHVua30KLSAgICAgICAgICogQHJldHVybiB0aGUge0BsaW5rIG9yZy5hcGFjaGUuYmNlbC5nZW5lcmljLkluc3RydWN0aW9uSGFuZGxlfSBvZiB0aGUKLSAgICAgICAgICogc3RhcnQgb2YgdGhpcyBjaHVuawotICAgICAgICAgKi8KLSAgICAgICAgSW5zdHJ1Y3Rpb25IYW5kbGUgZ2V0Q2h1bmtTdGFydCgpIHsKLSAgICAgICAgICAgIHJldHVybiBtX3N0YXJ0OwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIEdldHRlciBtZXRob2QgZm9yIHRoZSBlbmQgb2YgdGhpcyB7QGxpbmsgTWV0aG9kR2VuZXJhdG9yLkNodW5rfQotICAgICAgICAgKiBAcmV0dXJuIHRoZSB7QGxpbmsgSW5zdHJ1Y3Rpb25IYW5kbGV9IG9mIHRoZSBzdGFydCBvZiB0aGlzIGNodW5rCi0gICAgICAgICAqLwotICAgICAgICBJbnN0cnVjdGlvbkhhbmRsZSBnZXRDaHVua0VuZCgpIHsKLSAgICAgICAgICAgIHJldHVybiBtX2VuZDsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBUaGUgc2l6ZSBvZiB0aGlzIHtAbGluayBNZXRob2RHZW5lcmF0b3IuQ2h1bmt9Ci0gICAgICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBieXRlcyBpbiB0aGUgYnl0ZSBjb2RlIHJlcHJlc2VudGVkIGJ5IHRoaXMKLSAgICAgICAgICogICAgICAgICBjaHVuay4KLSAgICAgICAgICovCi0gICAgICAgIGludCBnZXRDaHVua1NpemUoKSB7Ci0gICAgICAgICAgICByZXR1cm4gbV9zaXplOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIEltcGxlbWVudHMgdGhlIDxjb2RlPmphdmEudXRpbC5Db21wYXJhYmxlLmNvbXBhcmVUbyhPYmplY3QpPC9jb2RlPgotICAgICAgICAgKiBtZXRob2QuCi0gICAgICAgICAqIEByZXR1cm4KLSAgICAgICAgICogPHVsPgotICAgICAgICAgKiA8bGk+QSBwb3NpdGl2ZSA8Y29kZT5pbnQ8L2NvZGU+IGlmIHRoZSBsZW5ndGggb2YgPGNvZGU+dGhpczwvY29kZT4KLSAgICAgICAgICogY2h1bmsgaW4gYnl0ZXMgaXMgZ3JlYXRlciB0aGFuIHRoYXQgb2YgPGNvZGU+Y29tcGFyYW5kPC9jb2RlPjwvbGk+Ci0gICAgICAgICAqIDxsaT5BIG5lZ2F0aXZlIDxjb2RlPmludDwvY29kZT4gaWYgdGhlIGxlbmd0aCBvZiA8Y29kZT50aGlzPC9jb2RlPgotICAgICAgICAgKiBjaHVuayBpbiBieXRlcyBpcyBsZXNzIHRoYW4gdGhhdCBvZiA8Y29kZT5jb21wYXJhbmQ8L2NvZGU+PC9saT4KLSAgICAgICAgICogPGxpPlplcm8sIG90aGVyd2lzZS48L2xpPgotICAgICAgICAgKiA8L3VsPgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIGludCBjb21wYXJlVG8oT2JqZWN0IGNvbXBhcmFuZCkgewotICAgICAgICAgICAgcmV0dXJuIGdldENodW5rU2l6ZSgpIC0gKChDaHVuayljb21wYXJhbmQpLmdldENodW5rU2l6ZSgpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRmluZCB0aGUgb3V0bGluZWFibGUgY2h1bmtzIGluIHRoaXMgbWV0aG9kIHRoYXQgd291bGQgYmUgdGhlIGJlc3QgY2hvaWNlcwotICAgICAqIHRvIG91dGxpbmUsIGJhc2VkIG9uIHNpemUgYW5kIHBvc2l0aW9uIGluIHRoZSBtZXRob2QuCi0gICAgICogQHBhcmFtIGNsYXNzR2VuIFRoZSB7QGxpbmsgQ2xhc3NHZW59IHdpdGggd2hpY2ggdGhlIGdlbmVyYXRlZCBtZXRob2RzCi0gICAgICogICAgICAgICAgICAgICAgIHdpbGwgYmUgYXNzb2NpYXRlZAotICAgICAqIEBwYXJhbSB0b3RhbE1ldGhvZFNpemUgdGhlIHNpemUgb2YgdGhlIGJ5dGVjb2RlIGluIHRoZSBvcmlnaW5hbCBtZXRob2QKLSAgICAgKiBAcmV0dXJuIGEgPGNvZGU+amF2YS51dGlsLkFycmF5TGlzdDwvY29kZT4gY29udGFpbmluZyB0aGUKLSAgICAgKiAge0BsaW5rIE1ldGhvZEdlbmVyYXRvci5DaHVua31zIHRoYXQgbWF5IGJlIG91dGxpbmVkIGZyb20gdGhpcyBtZXRob2QKLSAgICAgKi8KLSAgICBwcml2YXRlIEFycmF5TGlzdCBnZXRDYW5kaWRhdGVDaHVua3MoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCB0b3RhbE1ldGhvZFNpemUpIHsKLSAgICAgICAgSXRlcmF0b3IgaW5zdHJ1Y3Rpb25zID0gZ2V0SW5zdHJ1Y3Rpb25MaXN0KCkuaXRlcmF0b3IoKTsKLSAgICAgICAgQXJyYXlMaXN0IGNhbmRpZGF0ZUNodW5rcyA9IG5ldyBBcnJheUxpc3QoKTsKLSAgICAgICAgQXJyYXlMaXN0IGN1cnJMZXZlbENodW5rcyA9IG5ldyBBcnJheUxpc3QoKTsKLSAgICAgICAgU3RhY2sgc3ViQ2h1bmtTdGFjayA9IG5ldyBTdGFjaygpOwotICAgICAgICBib29sZWFuIG9wZW5DaHVua0F0Q3VyckxldmVsID0gZmFsc2U7Ci0gICAgICAgIGJvb2xlYW4gZmlyc3RJbnN0cnVjdGlvbiA9IHRydWU7Ci0KLSAgICAgICAgSW5zdHJ1Y3Rpb25IYW5kbGUgY3VycmVudEhhbmRsZTsKLQotICAgICAgICBpZiAobV9vcGVuQ2h1bmtzICE9IDApIHsKLSAgICAgICAgICAgIFN0cmluZyBtc2cgPQotICAgICAgICAgICAgICAgIChuZXcgRXJyb3JNc2coRXJyb3JNc2cuT1VUTElORV9FUlJfVU5CQUxBTkNFRF9NQVJLRVJTKSkKLSAgICAgICAgICAgICAgICAgICAgLnRvU3RyaW5nKCk7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihtc2cpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gU2NhbiBpbnN0cnVjdGlvbnMgaW4gdGhlIG1ldGhvZCwga2VlcGluZyB0cmFjayBvZiB0aGUgbmVzdGluZyBsZXZlbAotICAgICAgICAvLyBvZiBvdXRsaW5lYWJsZSBjaHVua3MuCi0gICAgICAgIC8vCi0gICAgICAgIC8vIGN1cnJMZXZlbENodW5rcwotICAgICAgICAvLyAgICAga2VlcHMgdHJhY2sgb2YgdGhlIGNoaWxkIGNodW5rcyBvZiBhIGNodW5rLiAgRm9yIGVhY2ggY2h1bmssCi0gICAgICAgIC8vICAgICB0aGVyZSB3aWxsIGJlIGEgcGFpciBvZiBlbnRyaWVzOiAgdGhlIEluc3RydWN0aW9uSGFuZGxlcyBmb3IgdGhlCi0gICAgICAgIC8vICAgICBzdGFydCBhbmQgZm9yIHRoZSBlbmQgb2YgdGhlIGNodW5rCi0gICAgICAgIC8vIHN1YkNodW5rU3RhY2sKLSAgICAgICAgLy8gICAgIGEgc3RhY2sgY29udGFpbmluZyB0aGUgcGFydGlhbGx5IGFjY3VtdWxhdGVkIGN1cnJMZXZlbENodW5rcyBmb3IKLSAgICAgICAgLy8gICAgIGVhY2ggY2h1bmsgdGhhdCdzIHN0aWxsIG9wZW4gYXQgdGhlIGN1cnJlbnQgcG9zaXRpb24gaW4gdGhlCi0gICAgICAgIC8vICAgICBJbnN0cnVjdGlvbkxpc3QuCi0gICAgICAgIC8vIGNhbmRpZGF0ZUNodW5rcwotICAgICAgICAvLyAgICAgdGhlIGxpc3Qgb2YgY2h1bmtzIHdoaWNoIGhhdmUgYmVlbiBhY2NlcHRlZCBhcyBjYW5kaWRhdGVzIGNodW5rcwotICAgICAgICAvLyAgICAgZm9yIG91dGxpbmluZwotICAgICAgICBkbyB7Ci0gICAgICAgICAgICAvLyBHZXQgdGhlIG5leHQgaW5zdHJ1Y3Rpb24uICBUaGUgbG9vcCB3aWxsIHBlcmZvcm0gb25lIGV4dHJhCi0gICAgICAgICAgICAvLyBpdGVyYXRpb24gYWZ0ZXIgaXQgcmVhY2hlcyB0aGUgZW5kIG9mIHRoZSBJbnN0cnVjdGlvbkxpc3QsIHdpdGgKLSAgICAgICAgICAgIC8vIGN1cnJlbnRIYW5kbGUgc2V0IHRvIG51bGwuCi0gICAgICAgICAgICBjdXJyZW50SGFuZGxlID0gaW5zdHJ1Y3Rpb25zLmhhc05leHQoKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyAoSW5zdHJ1Y3Rpb25IYW5kbGUpIGluc3RydWN0aW9ucy5uZXh0KCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogbnVsbDsKLSAgICAgICAgICAgIEluc3RydWN0aW9uIGluc3QgPQotICAgICAgICAgICAgICAgICAgICAoY3VycmVudEhhbmRsZSAhPSBudWxsKSA/IGN1cnJlbnRIYW5kbGUuZ2V0SW5zdHJ1Y3Rpb24oKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IG51bGw7Ci0KLSAgICAgICAgICAgIC8vIEF0IHRoZSBmaXJzdCBpdGVyYXRpb24sIGNyZWF0ZSBhIGNodW5rIHJlcHJlc2VudGluZyBhbGwgdGhlCi0gICAgICAgICAgICAvLyBjb2RlIGluIHRoZSBtZXRob2QuICBUaGlzIGlzIGRvbmUganVzdCB0byBzaW1wbGlmeSB0aGUgbG9naWMgLQotICAgICAgICAgICAgLy8gdGhpcyBjaHVuayBjYW4gbmV2ZXIgYmUgb3V0bGluZWQgYmVjYXVzZSBpdCB3aWxsIGJlIHRvbyBiaWcuCi0gICAgICAgICAgICBpZiAoZmlyc3RJbnN0cnVjdGlvbikgewotICAgICAgICAgICAgICAgIG9wZW5DaHVua0F0Q3VyckxldmVsID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICBjdXJyTGV2ZWxDaHVua3MuYWRkKGN1cnJlbnRIYW5kbGUpOwotICAgICAgICAgICAgICAgIGZpcnN0SW5zdHJ1Y3Rpb24gPSBmYWxzZTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gRm91bmQgYSBuZXcgY2h1bmsKLSAgICAgICAgICAgIGlmIChpbnN0IGluc3RhbmNlb2YgT3V0bGluZWFibGVDaHVua1N0YXJ0KSB7Ci0gICAgICAgICAgICAgICAgLy8gSWYgbGFzdCBNYXJrZXJJbnN0cnVjdGlvbiBlbmNvdW50ZXJlZCB3YXMgYW4KLSAgICAgICAgICAgICAgICAvLyBPdXRsaW5lYWJsZUNodW5rU3RhcnQsIHRoaXMgcmVwcmVzZW50cyB0aGUgZmlyc3QgY2h1bmsKLSAgICAgICAgICAgICAgICAvLyBuZXN0ZWQgd2l0aGluIHRoYXQgcHJldmlvdXMgY2h1bmsgLSBwdXNoIHRoZSBsaXN0IG9mIGNodW5rcwotICAgICAgICAgICAgICAgIC8vIGZyb20gdGhlIG91dGVyIGxldmVsIG9udG8gdGhlIHN0YWNrCi0gICAgICAgICAgICAgICAgaWYgKG9wZW5DaHVua0F0Q3VyckxldmVsKSB7Ci0gICAgICAgICAgICAgICAgICAgIHN1YkNodW5rU3RhY2sucHVzaChjdXJyTGV2ZWxDaHVua3MpOwotICAgICAgICAgICAgICAgICAgICBjdXJyTGV2ZWxDaHVua3MgPSBuZXcgQXJyYXlMaXN0KCk7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgb3BlbkNodW5rQXRDdXJyTGV2ZWwgPSB0cnVlOwotICAgICAgICAgICAgICAgIGN1cnJMZXZlbENodW5rcy5hZGQoY3VycmVudEhhbmRsZSk7Ci0gICAgICAgICAgICAvLyBDbG9zZSBvZmYgYW4gb3BlbiBjaHVuawotICAgICAgICAgICAgfSBlbHNlIGlmIChjdXJyZW50SGFuZGxlID09IG51bGwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IGluc3QgaW5zdGFuY2VvZiBPdXRsaW5lYWJsZUNodW5rRW5kKSB7Ci0gICAgICAgICAgICAgICAgQXJyYXlMaXN0IG5lc3RlZFN1YkNodW5rcyA9IG51bGw7Ci0KLSAgICAgICAgICAgICAgICAvLyBJZiB0aGUgbGFzdCBNYXJrZXJJbnN0cnVjdGlvbiBlbmNvdW50ZXJlZCB3YXMgYW4KLSAgICAgICAgICAgICAgICAvLyBPdXRsaW5lYWJsZUNodW5rRW5kLCBpdCBtZWFucyB0aGF0IHRoZSBjdXJyZW50IGluc3RydWN0aW9uCi0gICAgICAgICAgICAgICAgLy8gbWFya3MgdGhlIGVuZCBvZiBhIGNodW5rIHRoYXQgY29udGFpbmVkIGNoaWxkIGNodW5rcy4KLSAgICAgICAgICAgICAgICAvLyBUaG9zZSBjaGlsZHJlbiBtaWdodCBuZWVkIHRvIGJlIGV4YW1pbmVkIGJlbG93IGluIGNhc2UgdGhleQotICAgICAgICAgICAgICAgIC8vIGFyZSBiZXR0ZXIgY2FuZGlkYXRlcyBmb3Igb3V0bGluaW5nIHRoYW4gdGhlIGN1cnJlbnQgY2h1bmsuCi0gICAgICAgICAgICAgICAgaWYgKCFvcGVuQ2h1bmtBdEN1cnJMZXZlbCkgewotICAgICAgICAgICAgICAgICAgICBuZXN0ZWRTdWJDaHVua3MgPSBjdXJyTGV2ZWxDaHVua3M7Ci0gICAgICAgICAgICAgICAgICAgIGN1cnJMZXZlbENodW5rcyA9IChBcnJheUxpc3Qpc3ViQ2h1bmtTdGFjay5wb3AoKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyBHZXQgdGhlIGhhbmRsZSBmb3IgdGhlIHN0YXJ0IG9mIHRoaXMgY2h1bmsgKHRoZSBsYXN0IGVudHJ5Ci0gICAgICAgICAgICAgICAgLy8gaW4gY3VyckxldmVsQ2h1bmtzKQotICAgICAgICAgICAgICAgIEluc3RydWN0aW9uSGFuZGxlIGNodW5rU3RhcnQgPQotICAgICAgICAgICAgICAgICAgICAgICAgKEluc3RydWN0aW9uSGFuZGxlKSBjdXJyTGV2ZWxDaHVua3MuZ2V0KAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VyckxldmVsQ2h1bmtzLnNpemUoKS0xKTsKLQotICAgICAgICAgICAgICAgIGludCBjaHVua0VuZFBvc2l0aW9uID0KLSAgICAgICAgICAgICAgICAgICAgICAgIChjdXJyZW50SGFuZGxlICE9IG51bGwpID8gY3VycmVudEhhbmRsZS5nZXRQb3NpdGlvbigpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IHRvdGFsTWV0aG9kU2l6ZTsKLSAgICAgICAgICAgICAgICBpbnQgY2h1bmtTaXplID0gY2h1bmtFbmRQb3NpdGlvbiAtIGNodW5rU3RhcnQuZ2V0UG9zaXRpb24oKTsKLQotICAgICAgICAgICAgICAgIC8vIFR3byByYW5nZXMgb2YgY2h1bmsgc2l6ZSB0byBjb25zaWRlcjoKLSAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgIC8vIDEuIFswLFRBUkdFVF9NRVRIT0RfU0laRV0KLSAgICAgICAgICAgICAgICAvLyAgICAgIEtlZXAgdGhpcyBjaHVuayBpbiBjb25zaWRlcmF0aW9uIGFzIGEgY2FuZGlkYXRlLAotICAgICAgICAgICAgICAgIC8vICAgICAgYW5kIGlnbm9yZSBpdHMgc3ViY2h1bmtzLCBpZiBhbnkgLSB0aGVyZSdzIG5vdGhpbmcgdG8gYmUKLSAgICAgICAgICAgICAgICAvLyAgICAgIGdhaW5lZCBieSBvdXRsaW5pbmcgYm90aCB0aGUgY3VycmVudCBjaHVuayBhbmQgaXRzCi0gICAgICAgICAgICAgICAgLy8gICAgICBjaGlsZHJlbiEKLSAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgIC8vIDIuIChUQVJHRVRfTUVUSE9EX1NJWkUsK2luZmluaXR5KQotICAgICAgICAgICAgICAgIC8vICAgICAgSWdub3JlIHRoaXMgY2h1bmsgLSBpdCdzIHRvbyBiaWcuICBBZGQgaXRzIHN1YmNodW5rcwotICAgICAgICAgICAgICAgIC8vICAgICAgYXMgY2FuZGlkYXRlcywgYWZ0ZXIgbWVyZ2luZyBhZGphY2VudCBjaHVua3MgdG8gcHJvZHVjZQotICAgICAgICAgICAgICAgIC8vICAgICAgY2h1bmtzIHRoYXQgYXJlIGFzIGxhcmdlIGFzIHBvc3NpYmxlCi0gICAgICAgICAgICAgICAgaWYgKGNodW5rU2l6ZSA8PSBUQVJHRVRfTUVUSE9EX1NJWkUpIHsKLSAgICAgICAgICAgICAgICAgICAgY3VyckxldmVsQ2h1bmtzLmFkZChjdXJyZW50SGFuZGxlKTsKLSAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICBpZiAoIW9wZW5DaHVua0F0Q3VyckxldmVsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpbnQgY2hpbGRDaHVua0NvdW50ID0gbmVzdGVkU3ViQ2h1bmtzLnNpemUoKSAvIDI7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2hpbGRDaHVua0NvdW50ID4gMCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIENodW5rW10gY2hpbGRDaHVua3MgPSBuZXcgQ2h1bmtbY2hpbGRDaHVua0NvdW50XTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEdhdGhlciBhbGwgdGhlIGNoaWxkIGNodW5rcyBvZiB0aGUgY3VycmVudCBjaHVuawotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY2hpbGRDaHVua0NvdW50OyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW5zdHJ1Y3Rpb25IYW5kbGUgc3RhcnQgPQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKEluc3RydWN0aW9uSGFuZGxlKSBuZXN0ZWRTdWJDaHVua3MKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXQoaSoyKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW5zdHJ1Y3Rpb25IYW5kbGUgZW5kID0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChJbnN0cnVjdGlvbkhhbmRsZSkgbmVzdGVkU3ViQ2h1bmtzCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0KGkqMisxKTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZENodW5rc1tpXSA9IG5ldyBDaHVuayhzdGFydCwgZW5kKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBNZXJnZSBhZGphY2VudCBzaWJsaW5ncwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFycmF5TGlzdCBtZXJnZWRDaGlsZENodW5rcyA9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVyZ2VBZGphY2VudENodW5rcyhjaGlsZENodW5rcyk7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBBZGQgY2h1bmtzIHRoYXQgbWVhbiBtaW5pbXVtIHNpemUgcmVxdWlyZW1lbnRzCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdG8gdGhlIGxpc3Qgb2YgY2FuZGlkYXRlIGNodW5rcyBmb3Igb3V0bGluaW5nCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtZXJnZWRDaGlsZENodW5rcy5zaXplKCk7IGkrKykgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDaHVuayBtZXJnZWRDaHVuayA9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoQ2h1bmspbWVyZ2VkQ2hpbGRDaHVua3MuZ2V0KGkpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbWVyZ2VkU2l6ZSA9IG1lcmdlZENodW5rLmdldENodW5rU2l6ZSgpOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtZXJnZWRTaXplID49IE1JTklNVU1fT1VUTElORUFCTEVfQ0hVTktfU0laRQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmIG1lcmdlZFNpemUgPD0gVEFSR0VUX01FVEhPRF9TSVpFKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYW5kaWRhdGVDaHVua3MuYWRkKG1lcmdlZENodW5rKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgIC8vIERyb3AgdGhlIGNodW5rIHdoaWNoIHdhcyB0b28gYmlnCi0gICAgICAgICAgICAgICAgICAgIGN1cnJMZXZlbENodW5rcy5yZW1vdmUoY3VyckxldmVsQ2h1bmtzLnNpemUoKSAtIDEpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8vIGN1cnJMZXZlbENodW5rcyBjb250YWlucyBwYWlycyBvZiBJbnN0cnVjdGlvbkhhbmRsZXMuICBJZgotICAgICAgICAgICAgICAgIC8vIGl0cyBzaXplIGlzIGFuIG9kZCBudW1iZXIsIHRoZSBsb29wIGhhcyBlbmNvdW50ZXJlZCB0aGUKLSAgICAgICAgICAgICAgICAvLyBzdGFydCBvZiBhIGNodW5rIGF0IHRoaXMgbGV2ZWwsIGJ1dCBub3QgaXRzIGVuZC4KLSAgICAgICAgICAgICAgICBvcGVuQ2h1bmtBdEN1cnJMZXZlbCA9ICgoY3VyckxldmVsQ2h1bmtzLnNpemUoKSAmIDB4MSkgPT0gMSk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgfSB3aGlsZSAoY3VycmVudEhhbmRsZSAhPSBudWxsKTsKLQotICAgICAgICByZXR1cm4gY2FuZGlkYXRlQ2h1bmtzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIE1lcmdlIGFkamFjZW50IHNpYmxpbmcgY2h1bmtzIHRvIHByb2R1Y2UgbGFyZ2VyIGNhbmRpZGF0ZSBjaHVua3MgZm9yCi0gICAgICogb3V0bGluaW5nCi0gICAgICogQHBhcmFtIGNodW5rcyBhcnJheSBvZiBzaWJsaW5nIHtAbGluayBNZXRob2RHZW5lcmF0b3IuQ2h1bmt9cyB0aGF0IGFyZQotICAgICAqICAgICAgICAgICAgICAgdW5kZXIgY29uc2lkZXJhdGlvbiBmb3Igb3V0bGluaW5nLiAgQ2h1bmtzIG11c3QgYmUgaW4KLSAgICAgKiAgICAgICAgICAgICAgIHRoZSBvcmRlciBlbmNvdW50ZXJlZCBpbiB0aGUge0BsaW5rIEluc3RydWN0aW9uTGlzdH0KLSAgICAgKiBAcmV0dXJuIGEgPGNvZGU+amF2YS51dGlsLkFycmF5TGlzdDwvY29kZT4gb2YKLSAgICAgKiAgICAgICAgIDxjb2RlPk1ldGhvZEdlbmVyYXRvci5DaHVuazwvY29kZT5zIG1heGltYWxseSBtZXJnZWQKLSAgICAgKi8KLSAgICBwcml2YXRlIEFycmF5TGlzdCBtZXJnZUFkamFjZW50Q2h1bmtzKENodW5rW10gY2h1bmtzKSB7Ci0gICAgICAgIGludFtdIGFkamFjZW5jeVJ1blN0YXJ0ID0gbmV3IGludFtjaHVua3MubGVuZ3RoXTsKLSAgICAgICAgaW50W10gYWRqYWNlbmN5UnVuTGVuZ3RoID0gbmV3IGludFtjaHVua3MubGVuZ3RoXTsKLSAgICAgICAgYm9vbGVhbltdIGNodW5rV2FzTWVyZ2VkID0gbmV3IGJvb2xlYW5bY2h1bmtzLmxlbmd0aF07Ci0KLSAgICAgICAgaW50IG1heGltdW1SdW5PZkNodW5rcyA9IDA7Ci0gICAgICAgIGludCBzdGFydE9mQ3VycmVudFJ1bjsKLSAgICAgICAgaW50IG51bUFkamFjZW50UnVucyA9IDA7Ci0KLSAgICAgICAgQXJyYXlMaXN0IG1lcmdlZENodW5rcyA9IG5ldyBBcnJheUxpc3QoKTsKLQotICAgICAgICBzdGFydE9mQ3VycmVudFJ1biA9IDA7Ci0KLSAgICAgICAgLy8gTG9vcCB0aHJvdWdoIGNodW5rcywgYW5kIHJlY29yZCBpbiBhZGphY2VuY3lSdW5TdGFydCB3aGVyZSBlYWNoCi0gICAgICAgIC8vIHJ1biBvZiBhZGphY2VudCBjaHVua3MgYmVnaW5zIGFuZCBob3cgbWFueSBhcmUgaW4gdGhhdCBydW4uICBGb3IKLSAgICAgICAgLy8gZXhhbXBsZSwgZ2l2ZW4gY2h1bmtzIEEgQiBDIEQgRSBGLCBpZiBBIGlzIGFkamFjZW50IHRvIEIsIGJ1dCBub3QKLSAgICAgICAgLy8gdG8gQywgYW5kIEMsIEQsIEUgYW5kIEYgYXJlIGFsbCBhZGphY2VudCwKLSAgICAgICAgLy8gICBhZGphY2VuY3lSdW5TdGFydFswXSA9PSAwOyBhZGphY2VuY3lSdW5MZW5ndGhbMF0gPT0gMgotICAgICAgICAvLyAgIGFkamFjZW5jeVJ1blN0YXJ0WzFdID09IDI7IGFkamFjZW5jeVJ1bkxlbmd0aFsxXSA9PSA0Ci0gICAgICAgIGZvciAoaW50IGkgPSAxOyBpIDwgY2h1bmtzLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICBpZiAoIWNodW5rc1tpLTFdLmlzQWRqYWNlbnRUbyhjaHVua3NbaV0pKSB7Ci0gICAgICAgICAgICAgICAgaW50IGxlbmd0aE9mUnVuID0gaSAtIHN0YXJ0T2ZDdXJyZW50UnVuOwotCi0gICAgICAgICAgICAgICAgLy8gVHJhY2sgdGhlIGxvbmdlc3QgcnVuIG9mIGNodW5rcyBmb3VuZAotICAgICAgICAgICAgICAgIGlmIChtYXhpbXVtUnVuT2ZDaHVua3MgPCBsZW5ndGhPZlJ1bikgewotICAgICAgICAgICAgICAgICAgICBtYXhpbXVtUnVuT2ZDaHVua3MgPSBsZW5ndGhPZlJ1bjsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBpZiAobGVuZ3RoT2ZSdW4gPiAxICkgewotICAgICAgICAgICAgICAgICAgICBhZGphY2VuY3lSdW5MZW5ndGhbbnVtQWRqYWNlbnRSdW5zXSA9IGxlbmd0aE9mUnVuOwotICAgICAgICAgICAgICAgICAgICBhZGphY2VuY3lSdW5TdGFydFtudW1BZGphY2VudFJ1bnNdID0gc3RhcnRPZkN1cnJlbnRSdW47Ci0gICAgICAgICAgICAgICAgICAgIG51bUFkamFjZW50UnVucysrOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIHN0YXJ0T2ZDdXJyZW50UnVuID0gaTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGlmIChjaHVua3MubGVuZ3RoIC0gc3RhcnRPZkN1cnJlbnRSdW4gPiAxKSB7Ci0gICAgICAgICAgICBpbnQgbGVuZ3RoT2ZSdW4gPSBjaHVua3MubGVuZ3RoIC0gc3RhcnRPZkN1cnJlbnRSdW47Ci0KLSAgICAgICAgICAgIC8vIFRyYWNrIHRoZSBsb25nZXN0IHJ1biBvZiBjaHVua3MgZm91bmQKLSAgICAgICAgICAgIGlmIChtYXhpbXVtUnVuT2ZDaHVua3MgPCBsZW5ndGhPZlJ1bikgewotICAgICAgICAgICAgICAgIG1heGltdW1SdW5PZkNodW5rcyA9IGxlbmd0aE9mUnVuOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBhZGphY2VuY3lSdW5MZW5ndGhbbnVtQWRqYWNlbnRSdW5zXSA9Ci0gICAgICAgICAgICAgICAgICAgICAgICBjaHVua3MubGVuZ3RoIC0gc3RhcnRPZkN1cnJlbnRSdW47Ci0gICAgICAgICAgICBhZGphY2VuY3lSdW5TdGFydFtudW1BZGphY2VudFJ1bnNdID0gc3RhcnRPZkN1cnJlbnRSdW47Ci0gICAgICAgICAgICBudW1BZGphY2VudFJ1bnMrKzsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIFRyeSBtZXJnaW5nIGFkamFjZW50IGNodW5rcyB0byBjb21lIHVwIHdpdGggYmV0dGVyIHNpemVkIGNodW5rcyBmb3IKLSAgICAgICAgLy8gb3V0bGluaW5nLiAgVGhpcyBhbGdvcml0aG0gaXMgbm90IG9wdGltYWwsIGJ1dCBpdCBzaG91bGQgYmUKLSAgICAgICAgLy8gcmVhc29uYWJseSBmYXN0LiAgQ29uc2lkZXIgYW4gZXhhbXBsZSBsaWtlIHRoaXMsIHdoZXJlIGZvdXIgY2h1bmtzCi0gICAgICAgIC8vIG9mIHRoZSBzaXplcyBzcGVjaWZpZWQgaW4gYnJhY2tldHMgYXJlIGFkamFjZW50LiAgVGhlIGJlc3Qgd2F5IG9mCi0gICAgICAgIC8vIGNvbWJpbmluZyB0aGVzZSBjaHVua3Mgd291bGQgYmUgdG8gbWVyZ2UgdGhlIGZpcnN0IHBhaXIgYW5kIG1lcmdlCi0gICAgICAgIC8vIHRoZSBsYXN0IHRocmVlIHRvIGZvcm0gdHdvIGNodW5rcywgYnV0IHRoZSBhbGdvcml0aG0gd2lsbCBtZXJnZSB0aGUKLSAgICAgICAgLy8gdGhyZWUgaW4gdGhlIG1pZGRsZSBpbnN0ZWFkLCBsZWF2aW5nIHRocmVlIGNodW5rcyBpbiBhbGwuCi0gICAgICAgIC8vICAgIFsyNTAwMF0gWzI1MDAwXSBbMjAwMDBdIFsxMDAwXSBbMjAwMDBdCi0KLSAgICAgICAgLy8gU3RhcnQgYnkgdHJ5aW5nIHRvIG1lcmdlIHRoZSBtYXhpbXVtIG51bWJlciBvZiBhZGphY2VudCBjaHVua3MsIGFuZAotICAgICAgICAvLyB3b3JrIGRvd24gZnJvbSB0aGVyZS4KLSAgICAgICAgZm9yIChpbnQgbnVtVG9NZXJnZSA9IG1heGltdW1SdW5PZkNodW5rczsgbnVtVG9NZXJnZT4xOyBudW1Ub01lcmdlLS0pIHsKLSAgICAgICAgICAgIC8vIExvb2sgYXQgZWFjaCBydW4gb2YgYWRqYWNlbnQgY2h1bmtzCi0gICAgICAgICAgICBmb3IgKGludCBydW4gPSAwOyBydW4gPCBudW1BZGphY2VudFJ1bnM7IHJ1bisrKSB7Ci0gICAgICAgICAgICAgICAgaW50IHJ1blN0YXJ0ID0gYWRqYWNlbmN5UnVuU3RhcnRbcnVuXTsKLSAgICAgICAgICAgICAgICBpbnQgcnVuRW5kID0gcnVuU3RhcnQgKyBhZGphY2VuY3lSdW5MZW5ndGhbcnVuXSAtIDE7Ci0KLSAgICAgICAgICAgICAgICBib29sZWFuIGZvdW5kQ2h1bmtzVG9NZXJnZSA9IGZhbHNlOwotCi0gICAgICAgICAgICAgICAgLy8gV2l0aGluIHRoZSBjdXJyZW50IHJ1biBvZiBhZGphY2VudCBjaHVua3MsIGxvb2sgYXQgYWxsCi0gICAgICAgICAgICAgICAgLy8gInN1YnJ1bnMiIG9mIGxlbmd0aCBudW1Ub01lcmdlLCB1bnRpbCB3ZSBydW4gb3V0IG9yIGZpbmQKLSAgICAgICAgICAgICAgICAvLyBhIHN1YnJ1biB0aGF0IGNhbiBiZSBtZXJnZWQuCi0gICAgICAgICAgICAgICAgZm9yIChpbnQgbWVyZ2VTdGFydCA9IHJ1blN0YXJ0OwotICAgICAgICAgICAgICAgICAgICAgbWVyZ2VTdGFydCtudW1Ub01lcmdlLTEgPD0gcnVuRW5kICYmICFmb3VuZENodW5rc1RvTWVyZ2U7Ci0gICAgICAgICAgICAgICAgICAgICBtZXJnZVN0YXJ0KyspIHsKLSAgICAgICAgICAgICAgICAgICAgaW50IG1lcmdlRW5kID0gbWVyZ2VTdGFydCArIG51bVRvTWVyZ2UgLSAxOwotICAgICAgICAgICAgICAgICAgICBpbnQgbWVyZ2VTaXplID0gMDsKLQotICAgICAgICAgICAgICAgICAgICAvLyBGaW5kIG91dCBob3cgYmlnIHRoZSBzdWJydW4gaXMKLSAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaiA9IG1lcmdlU3RhcnQ7IGogPD0gbWVyZ2VFbmQ7IGorKykgewotICAgICAgICAgICAgICAgICAgICAgICAgbWVyZ2VTaXplID0gbWVyZ2VTaXplICsgY2h1bmtzW2pdLmdldENodW5rU2l6ZSgpOwotICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgLy8gSWYgdGhlIGN1cnJlbnQgc3VicnVuIGlzIHNtYWxsIGVub3VnaCB0byBvdXRsaW5lLAotICAgICAgICAgICAgICAgICAgICAvLyBtZXJnZSBpdCwgYW5kIHNwbGl0IHRoZSByZW1haW5pbmcgY2h1bmtzIGluIHRoZSBydW4KLSAgICAgICAgICAgICAgICAgICAgaWYgKG1lcmdlU2l6ZSA8PSBUQVJHRVRfTUVUSE9EX1NJWkUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZvdW5kQ2h1bmtzVG9NZXJnZSA9IHRydWU7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGogPSBtZXJnZVN0YXJ0OyBqIDw9IG1lcmdlRW5kOyBqKyspIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaHVua1dhc01lcmdlZFtqXSA9IHRydWU7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIG1lcmdlZENodW5rcy5hZGQoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBDaHVuayhjaHVua3NbbWVyZ2VTdGFydF0uZ2V0Q2h1bmtTdGFydCgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2h1bmtzW21lcmdlRW5kXS5nZXRDaHVua0VuZCgpKSk7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIEFkanVzdCB0aGUgbGVuZ3RoIG9mIHRoZSBjdXJyZW50IHJ1biBvZiBhZGphY2VudAotICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2h1bmtzIHRvIGVuZCBhdCB0aGUgbmV3bHkgbWVyZ2VkIGNodW5rLi4uCi0gICAgICAgICAgICAgICAgICAgICAgICBhZGphY2VuY3lSdW5MZW5ndGhbcnVuXSA9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkamFjZW5jeVJ1blN0YXJ0W3J1bl0gLSBtZXJnZVN0YXJ0OwotCi0gICAgICAgICAgICAgICAgICAgICAgICBpbnQgdHJhaWxpbmdSdW5MZW5ndGggPSBydW5FbmQgLSBtZXJnZUVuZDsKLQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gYW5kIGFueSBjaHVua3MgdGhhdCBmb2xsb3cgdGhlIG5ld2x5IG1lcmdlZCBjaHVuawotICAgICAgICAgICAgICAgICAgICAgICAgLy8gaW4gdGhlIGN1cnJlbnQgcnVuIG9mIGFkamFjZW50IGNodW5rcyBmb3JtIGFub3RoZXIKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIG5ldyBydW4gb2YgYWRqYWNlbnQgY2h1bmtzCi0gICAgICAgICAgICAgICAgICAgICAgICBpZiAodHJhaWxpbmdSdW5MZW5ndGggPj0gMikgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkamFjZW5jeVJ1blN0YXJ0W251bUFkamFjZW50UnVuc10gPSBtZXJnZUVuZCArIDE7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRqYWNlbmN5UnVuTGVuZ3RoW251bUFkamFjZW50UnVuc10gPQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhaWxpbmdSdW5MZW5ndGg7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVtQWRqYWNlbnRSdW5zKys7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBNYWtlIGEgZmluYWwgcGFzcyBmb3IgYW55IGNodW5rIHRoYXQgd2Fzbid0IG1lcmdlZCB3aXRoIGEgc2libGluZwotICAgICAgICAvLyBhbmQgaW5jbHVkZSBpdCBpbiB0aGUgbGlzdCBvZiBjaHVua3MgYWZ0ZXIgbWVyZ2luZy4KLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjaHVua3MubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgIGlmICghY2h1bmtXYXNNZXJnZWRbaV0pIHsKLSAgICAgICAgICAgICAgICBtZXJnZWRDaHVua3MuYWRkKGNodW5rc1tpXSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gbWVyZ2VkQ2h1bmtzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEJyZWFrcyB1cCB0aGUgSUwgZm9yIHRoaXMge0BsaW5rIE1ldGhvZEdlbmVyYXRvcn0gaW50byBzZXBhcmF0ZQotICAgICAqIG91dGxpbmVkIG1ldGhvZHMgc28gdGhhdCBubyBtZXRob2QgZXhjZWVkcyB0aGUgNjRLQiBsaW1pdCBvbiB0aGUgbGVuZ3RoCi0gICAgICogb2YgdGhlIGJ5dGUgY29kZSBhc3NvY2lhdGVkIHdpdGggYSBtZXRob2QuCi0gICAgICogQHBhcmFtIGNsYXNzR2VuIFRoZSB7QGxpbmsgQ2xhc3NHZW59IHdpdGggd2hpY2ggdGhlIGdlbmVyYXRlZCBtZXRob2RzCi0gICAgICogICAgICAgICAgICAgICAgIHdpbGwgYmUgYXNzb2NpYXRlZAotICAgICAqIEBwYXJhbSBvcmlnaW5hbE1ldGhvZFNpemUgVGhlIG51bWJlciBvZiBieXRlcyBvZiBieXRlY29kZSByZXByZXNlbnRlZCBieQotICAgICAqICAgICAgICAgICAgICAgICB0aGUge0BsaW5rIEluc3RydWN0aW9uTGlzdH0gb2YgdGhpcyBtZXRob2QKLSAgICAgKiBAcmV0dXJuIGFuIGFycmF5IG9mIHRoZSBvdXRsaW5lZCA8Y29kZT5NZXRob2Q8L2NvZGU+cyBhbmQgdGhlIG9yaWdpbmFsCi0gICAgICogICAgICAgICBtZXRob2QgaXRzZWxmCi0gICAgICovCi0gICAgcHVibGljIE1ldGhvZFtdIG91dGxpbmVDaHVua3MoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG9yaWdpbmFsTWV0aG9kU2l6ZSkgewotICAgICAgICBBcnJheUxpc3QgbWV0aG9kc091dGxpbmVkID0gbmV3IEFycmF5TGlzdCgpOwotICAgICAgICBpbnQgY3VycmVudE1ldGhvZFNpemUgPSBvcmlnaW5hbE1ldGhvZFNpemU7Ci0KLSAgICAgICAgaW50IG91dGxpbmVkQ291bnQgPSAwOwotICAgICAgICBib29sZWFuIG1vcmVNZXRob2RzT3V0bGluZWQ7Ci0gICAgICAgIFN0cmluZyBvcmlnaW5hbE1ldGhvZE5hbWUgPSBnZXROYW1lKCk7Ci0KLSAgICAgICAgLy8gU3BlY2lhbCBoYW5kbGluZyBmb3IgaW5pdGlhbGl6YXRpb24gbWV0aG9kcy4gIE5vIG90aGVyIG1ldGhvZHMgY2FuCi0gICAgICAgIC8vIGluY2x1ZGUgdGhlIGxlc3MgdGhhbiBhbmQgZ3JlYXRlciB0aGFuIGNoYXJhY3RlcnMgaW4gdGhlaXIgbmFtZXMsCi0gICAgICAgIC8vIHNvIHdlIG11bmdlIHRoZSBuYW1lcyBoZXJlLgotICAgICAgICBpZiAob3JpZ2luYWxNZXRob2ROYW1lLmVxdWFscygiPGluaXQ+IikpIHsKLSAgICAgICAgICAgIG9yaWdpbmFsTWV0aG9kTmFtZSA9ICIkbHQkaW5pdCRndCQiOwotICAgICAgICB9IGVsc2UgaWYgKG9yaWdpbmFsTWV0aG9kTmFtZS5lcXVhbHMoIjxjbGluaXQ+IikpIHsKLSAgICAgICAgICAgIG9yaWdpbmFsTWV0aG9kTmFtZSA9ICIkbHQkY2xpbml0JGd0JCI7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBMb29wIHVudGlsIHRoZSBvcmlnaW5hbCBtZXRob2QgY29tZXMgaW4gdW5kZXIgdGhlIEpWTSBsaW1pdCBvcgotICAgICAgICAvLyB0aGUgbG9vcCB3YXMgdW5hYmxlIHRvIG91dGxpbmUgYW55IG1vcmUgbWV0aG9kcwotICAgICAgICBkbyB7Ci0gICAgICAgICAgICAvLyBHZXQgYWxsIHRoZSBiZXN0IGNhbmRpZGF0ZXMgZm9yIG91dGxpbmluZywgYW5kIHNvcnQgdGhlbSBpbgotICAgICAgICAgICAgLy8gYXNjZW5kaW5nIG9yZGVyIG9mIHNpemUKLSAgICAgICAgICAgIEFycmF5TGlzdCBjYW5kaWRhdGVDaHVua3MgPSBnZXRDYW5kaWRhdGVDaHVua3MoY2xhc3NHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRNZXRob2RTaXplKTsKLSAgICAgICAgICAgIENvbGxlY3Rpb25zLnNvcnQoY2FuZGlkYXRlQ2h1bmtzKTsKLQotICAgICAgICAgICAgbW9yZU1ldGhvZHNPdXRsaW5lZCA9IGZhbHNlOwotCi0gICAgICAgICAgICAvLyBMb29wIG92ZXIgdGhlIGNhbmRpZGF0ZXMgZm9yIG91dGxpbmluZywgZnJvbSB0aGUgbGFyZ2VzdCB0byB0aGUKLSAgICAgICAgICAgIC8vIHNtYWxsZXN0IGFuZCBvdXRsaW5lIHRoZW0gb25lIGF0IGEgdGltZSwgdW50aWwgdGhlIGxvb3AgaGFzCi0gICAgICAgICAgICAvLyBvdXRsaW5lZCBhbGwgb3IgdGhlIG9yaWdpbmFsIG1ldGhvZCBjb21lcyBpbiB1bmRlciB0aGUgSlZNCi0gICAgICAgICAgICAvLyBsaW1pdCBvbiB0aGUgc2l6ZSBvZiBhIG1ldGhvZC4KLSAgICAgICAgICAgIGZvciAoaW50IGkgPSBjYW5kaWRhdGVDaHVua3Muc2l6ZSgpLTE7Ci0gICAgICAgICAgICAgICAgIGkgPj0gMCAmJiBjdXJyZW50TWV0aG9kU2l6ZSA+IFRBUkdFVF9NRVRIT0RfU0laRTsKLSAgICAgICAgICAgICAgICAgaS0tKSB7Ci0gICAgICAgICAgICAgICAgQ2h1bmsgY2h1bmtUb091dGxpbmUgPSAoQ2h1bmspY2FuZGlkYXRlQ2h1bmtzLmdldChpKTsKLQotICAgICAgICAgICAgICAgIG1ldGhvZHNPdXRsaW5lZC5hZGQob3V0bGluZShjaHVua1RvT3V0bGluZS5nZXRDaHVua1N0YXJ0KCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNodW5rVG9PdXRsaW5lLmdldENodW5rRW5kKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yaWdpbmFsTWV0aG9kTmFtZSArICIkb3V0bGluZSQiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIG91dGxpbmVkQ291bnQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzR2VuKSk7Ci0gICAgICAgICAgICAgICAgb3V0bGluZWRDb3VudCsrOwotICAgICAgICAgICAgICAgIG1vcmVNZXRob2RzT3V0bGluZWQgPSB0cnVlOwotCi0gICAgICAgICAgICAgICAgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0gICAgICAgICAgICAgICAgSW5zdHJ1Y3Rpb25IYW5kbGUgbGFzdEluc3QgPSBpbC5nZXRFbmQoKTsKLSAgICAgICAgICAgICAgICBpbC5zZXRQb3NpdGlvbnMoKTsKLQotICAgICAgICAgICAgICAgIC8vIENoZWNrIHRoZSBzaXplIG9mIHRoZSBtZXRob2Qgbm93Ci0gICAgICAgICAgICAgICAgY3VycmVudE1ldGhvZFNpemUgPQotICAgICAgICAgICAgICAgICAgICAgICAgbGFzdEluc3QuZ2V0UG9zaXRpb24oKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGxhc3RJbnN0LmdldEluc3RydWN0aW9uKCkuZ2V0TGVuZ3RoKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gd2hpbGUgKG1vcmVNZXRob2RzT3V0bGluZWQgJiYgY3VycmVudE1ldGhvZFNpemUgPiBUQVJHRVRfTUVUSE9EX1NJWkUpOwotCi0gICAgICAgIC8vIE91dGxpbmluZyBmYWlsZWQgdG8gcmVkdWNlIHRoZSBzaXplIG9mIHRoZSBjdXJyZW50IG1ldGhvZAotICAgICAgICAvLyBzdWZmaWNpZW50bHkuICBUaHJvdyBhbiBpbnRlcm5hbCBlcnJvci4KLSAgICAgICAgaWYgKGN1cnJlbnRNZXRob2RTaXplID4gTUFYX01FVEhPRF9TSVpFKSB7Ci0gICAgICAgICAgICBTdHJpbmcgbXNnID0gKG5ldyBFcnJvck1zZyhFcnJvck1zZy5PVVRMSU5FX0VSUl9NRVRIT0RfVE9PX0JJRykpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnRvU3RyaW5nKCk7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihtc2cpOwotICAgICAgICB9Ci0KLSAgICAgICAgTWV0aG9kW10gbWV0aG9kc0FyciA9IG5ldyBNZXRob2RbbWV0aG9kc091dGxpbmVkLnNpemUoKSArIDFdOwotICAgICAgICBtZXRob2RzT3V0bGluZWQudG9BcnJheShtZXRob2RzQXJyKTsKLQotICAgICAgICBtZXRob2RzQXJyW21ldGhvZHNPdXRsaW5lZC5zaXplKCldID0gZ2V0VGhpc01ldGhvZCgpOwotCi0gICAgICAgIHJldHVybiBtZXRob2RzQXJyOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdpdmVuIGFuIG91dGxpbmVhYmxlIGNodW5rIG9mIGNvZGUgaW4gdGhlIGN1cnJlbnQge0BsaW5rIE1ldGhvZEdlbmVyYXRvcn0KLSAgICAgKiBtb3ZlICgib3V0bGluZSIpIHRoZSBjaHVuayB0byBhIG5ldyBtZXRob2QsIGFuZCByZXBsYWNlIHRoZSBjaHVuayBpbiB0aGUKLSAgICAgKiBvbGQgbWV0aG9kIHdpdGggYSByZWZlcmVuY2UgdG8gdGhhdCBuZXcgbWV0aG9kLiAgTm8KLSAgICAgKiB7QGxpbmsgT3V0bGluZWFibGVDaHVua1N0YXJ0fSBvciB7QGxpbmsgT3V0bGluZWFibGVDaHVua0VuZH0gaW5zdHJ1Y3Rpb25zCi0gICAgICogYXJlIGNvcGllZC4KLSAgICAgKiBAcGFyYW0gZmlyc3QgVGhlIHtAbGluayBJbnN0cnVjdGlvbkhhbmRsZX0gb2YgdGhlIGZpcnN0IGluc3RydWN0aW9uIGluCi0gICAgICogICAgICAgICAgICAgIHRoZSBjaHVuayB0byBvdXRsaW5lCi0gICAgICogQHBhcmFtIGxhc3QgVGhlIDxjb2RlPkluc3RydWN0aW9uSGFuZGxlPC9jb2RlPiBvZiB0aGUgbGFzdCBpbnN0cnVjdGlvbiBpbgotICAgICAqICAgICAgICAgICAgIHRoZSBjaHVuayB0byBvdXRsaW5lCi0gICAgICogQHBhcmFtIG91dGxpbmVkTWV0aG9kTmFtZSBUaGUgbmFtZSBvZiB0aGUgbmV3IG1ldGhvZAotICAgICAqIEBwYXJhbSBjbGFzc0dlbiBUaGUge0BsaW5rIENsYXNzR2VuZXJhdG9yfSBvZiB3aGljaCB0aGUgb3JpZ2luYWwKLSAgICAgKiAgICAgICAgICAgICAgYW5kIG5ldyBtZXRob2RzIHdpbGwgYmUgbWVtYmVycwotICAgICAqIEByZXR1cm4gVGhlIG5ldyB7QGxpbmsgTWV0aG9kfSBjb250YWluaW5nIHRoZSBvdXRsaW5lZCBjb2RlLgotICAgICAqLwotICAgIHByaXZhdGUgTWV0aG9kIG91dGxpbmUoSW5zdHJ1Y3Rpb25IYW5kbGUgZmlyc3QsIEluc3RydWN0aW9uSGFuZGxlIGxhc3QsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgb3V0bGluZWRNZXRob2ROYW1lLCBDbGFzc0dlbmVyYXRvciBjbGFzc0dlbikgewotICAgICAgICAvLyBXZSdyZSBub3QgZXF1aXBwZWQgdG8gZGVhbCB3aXRoIGV4Y2VwdGlvbiBoYW5kbGVycyB5ZXQuICBCYWlsIG91dCEKLSAgICAgICAgaWYgKGdldEV4Y2VwdGlvbkhhbmRsZXJzKCkubGVuZ3RoICE9IDApIHsKLSAgICAgICAgICAgIFN0cmluZyBtc2cgPSAobmV3IEVycm9yTXNnKEVycm9yTXNnLk9VVExJTkVfRVJSX1RSWV9DQVRDSCkpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnRvU3RyaW5nKCk7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihtc2cpOwotICAgICAgICB9Ci0KLSAgICAgICAgaW50IG91dGxpbmVDaHVua1N0YXJ0T2Zmc2V0ID0gZmlyc3QuZ2V0UG9zaXRpb24oKTsKLSAgICAgICAgaW50IG91dGxpbmVDaHVua0VuZE9mZnNldCA9IGxhc3QuZ2V0UG9zaXRpb24oKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgbGFzdC5nZXRJbnN0cnVjdGlvbigpLmdldExlbmd0aCgpOwotCi0gICAgICAgIENvbnN0YW50UG9vbEdlbiBjcGcgPSBnZXRDb25zdGFudFBvb2woKTsKLQotICAgICAgICAvLyBDcmVhdGUgbmV3IG91dGxpbmVkIG1ldGhvZCB3aXRoIHNpZ25hdHVyZToKLSAgICAgICAgLy8KLSAgICAgICAgLy8gICBwcml2YXRlIGZpbmFsIG91dGxpbmVkTWV0aG9kTmFtZShDb3B5TG9jYWxzIGNvcHlMb2NhbHMpOwotICAgICAgICAvLwotICAgICAgICAvLyBDb3B5TG9jYWxzIGlzIGFuIG9iamVjdCB0aGF0IGlzIHVzZWQgdG8gY29weS1pbi9jb3B5LW91dCBsb2NhbAotICAgICAgICAvLyB2YXJpYWJsZXMgdGhhdCBhcmUgdXNlZCBieSB0aGUgb3V0bGluZWQgbWV0aG9kLiAgIE9ubHkgbG9jYWxzIHdob3NlCi0gICAgICAgIC8vIHZhbHVlIGlzIHBvdGVudGlhbGx5IHNldCBvciByZWZlcmVuY2VkIG91dHNpZGUgdGhlIHJhbmdlIG9mIHRoZQotICAgICAgICAvLyBjaHVuayB0aGF0IGlzIGJlaW5nIG91dGxpbmVkIHdpbGwgYmUgcmVwcmVzZW50ZWQgaW4gQ29weUxvY2Fscy4gIFRoZQotICAgICAgICAvLyB0eXBlIG9mIHRoZSB2YXJpYWJsZSBmb3IgY29weWluZyBsb2NhbCB2YXJpYWJsZXMgaXMgYWN0dWFsbHkKLSAgICAgICAgLy8gZ2VuZXJhdGVkIHRvIGJlIHVuaXF1ZSAtIGl0IGlzIG5vdCBuYW1lZCBDb3B5TG9jYWxzLgotICAgICAgICAvLwotICAgICAgICAvLyBUaGUgb3V0bGluZWQgbWV0aG9kIG5ldmVyIG5lZWRzIHRvIGJlIHJlZmVyZW5jZWQgb3V0c2lkZSBvZiB0aGlzCi0gICAgICAgIC8vIGNsYXNzLCBhbmQgd2lsbCBuZXZlciBiZSBvdmVycmlkZGVuLCBzbyB3ZSBtYXJrIGl0IHByaXZhdGUgZmluYWwuCi0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBuZXdJTCA9IG5ldyBJbnN0cnVjdGlvbkxpc3QoKTsKLQotICAgICAgICBmaW5hbCBYU0xUQyAgeHNsdGMgPSBjbGFzc0dlbi5nZXRQYXJzZXIoKS5nZXRYU0xUQygpOwotICAgICAgICBmaW5hbCBTdHJpbmcgYXJnVHlwZU5hbWUgPSB4c2x0Yy5nZXRIZWxwZXJDbGFzc05hbWUoKTsKLSAgICAgICAgZmluYWwgVHlwZVtdIGFyZ1R5cGVzID0KLSAgICAgICAgICAgIG5ldyBUeXBlW10geyhuZXcgT2JqZWN0VHlwZShhcmdUeXBlTmFtZSkpLnRvSkNUeXBlKCl9OwotICAgICAgICBmaW5hbCBTdHJpbmcgYXJnTmFtZSA9ICJjb3B5TG9jYWxzIjsKLSAgICAgICAgZmluYWwgU3RyaW5nW10gYXJnTmFtZXMgPSBuZXcgU3RyaW5nW10ge2FyZ05hbWV9OwotCi0gICAgICAgIGludCBtZXRob2RBdHRyaWJ1dGVzID0gQUNDX1BSSVZBVEUgfCBBQ0NfRklOQUw7Ci0gICAgICAgIGZpbmFsIGJvb2xlYW4gaXNTdGF0aWNNZXRob2QgPSAoZ2V0QWNjZXNzRmxhZ3MoKSAmIEFDQ19TVEFUSUMpICE9IDA7Ci0KLSAgICAgICAgaWYgKGlzU3RhdGljTWV0aG9kKSB7Ci0gICAgICAgICAgICBtZXRob2RBdHRyaWJ1dGVzID0gbWV0aG9kQXR0cmlidXRlcyB8IEFDQ19TVEFUSUM7Ci0gICAgICAgIH0KLQotICAgICAgICBmaW5hbCBNZXRob2RHZW5lcmF0b3Igb3V0bGluZWRNZXRob2RHZW4gPQotICAgICAgICAgICAgbmV3IE1ldGhvZEdlbmVyYXRvcihtZXRob2RBdHRyaWJ1dGVzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlR5cGUuVk9JRCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJnVHlwZXMsIGFyZ05hbWVzLCBvdXRsaW5lZE1ldGhvZE5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldENsYXNzTmFtZSgpLCBuZXdJTCwgY3BnKTsKLQotICAgICAgICAvLyBDcmVhdGUgY2xhc3MgZm9yIGNvcHlpbmcgbG9jYWwgdmFyaWFibGVzIHRvIHRoZSBvdXRsaW5lZCBtZXRob2QuCi0gICAgICAgIC8vIFRoZSBmaWVsZHMgdGhlIGNsYXNzIHdpbGwgbmVlZCB0byBjb250YWluIHdpbGwgYmUgZGV0ZXJtaW5lZCBhcyB0aGUKLSAgICAgICAgLy8gY29kZSBpbiB0aGUgb3V0bGluZWFibGUgY2h1bmsgaXMgZXhhbWluZWQuCi0gICAgICAgIENsYXNzR2VuZXJhdG9yIGNvcHlBcmVhQ0cKLSAgICAgICAgICAgID0gbmV3IENsYXNzR2VuZXJhdG9yKGFyZ1R5cGVOYW1lLCBPQkpFQ1RfQ0xBU1MsIGFyZ1R5cGVOYW1lKyIuamF2YSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBQ0NfRklOQUwgfCBBQ0NfUFVCTElDIHwgQUNDX1NVUEVSLCBudWxsLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NHZW4uZ2V0U3R5bGVzaGVldCgpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgcHVibGljIGJvb2xlYW4gaXNFeHRlcm5hbCgpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgfTsKLSAgICAgICAgQ29uc3RhbnRQb29sR2VuIGNvcHlBcmVhQ1BHID0gY29weUFyZWFDRy5nZXRDb25zdGFudFBvb2woKTsKLSAgICAgICAgY29weUFyZWFDRy5hZGRFbXB0eUNvbnN0cnVjdG9yKEFDQ19QVUJMSUMpOwotCi0gICAgICAgIC8vIE51bWJlciBvZiBmaWVsZHMgaW4gdGhlIGNvcHkgY2xhc3MKLSAgICAgICAgaW50IGNvcHlBcmVhRmllbGRDb3VudCA9IDA7Ci0KLSAgICAgICAgLy8gVGhlIGhhbmRsZSBmb3IgdGhlIGluc3RydWN0aW9uIGFmdGVyIHRoZSBsYXN0IG9uZSB0byBiZSBvdXRsaW5lZC4KLSAgICAgICAgLy8gTm90ZSB0aGF0IHRoaXMgc2hvdWxkIG5ldmVyIGVuZCB1cCBiZWluZyBudWxsLiAgQW4gb3V0bGluZWFibGUgY2h1bmsKLSAgICAgICAgLy8gd29uJ3QgY29udGFpbiBhIFJFVFVSTiBpbnN0cnVjdGlvbiBvciBvdGhlciBicmFuY2ggb3V0IG9mIHRoZSBjaHVuaywKLSAgICAgICAgLy8gYW5kIHRoZSBKVk0gc3BlY2lmaWNhdGlvbiBwcm9oaWJpdHMgY29kZSBpbiBhIG1ldGhvZCBmcm9tIGp1c3QKLSAgICAgICAgLy8gImZhbGxpbmcgb2ZmIHRoZSBlbmQiIHNvIHRoaXMgc2hvdWxkIGFsd2F5cyBwb2ludCB0byBhIHZhbGlkIGhhbmRsZS4KLSAgICAgICAgSW5zdHJ1Y3Rpb25IYW5kbGUgbGltaXQgPSBsYXN0LmdldE5leHQoKTsKLQotICAgICAgICAvLyBJbnN0cnVjdGlvbkxpc3RzIGZvciBjb3B5aW5nIHZhbHVlcyBpbnRvIGFuZCBvdXQgb2YgYW4gaW5zdGFuY2Ugb2YKLSAgICAgICAgLy8gQ29weUxvY2FsczoKLSAgICAgICAgLy8gICAgICBvbGRNZXRoQ295cEluSUwgIC0gZnJvbSBsb2NhbHMgaW4gb2xkIG1ldGhvZCBpbnRvIGFuIGluc3RhbmNlCi0gICAgICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgIG9mIHRoZSBDb3B5TG9jYWxzIGNsYXNzIChvbGRNZXRoQ29weUluSUwpCi0gICAgICAgIC8vICAgICAgb2xkTWV0aENvcHlPdXRJTCAtIGZyb20gQ29weUxvY2FscyBiYWNrIGludG8gbG9jYWxzIGluIHRoZSBvbGQKLSAgICAgICAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kCi0gICAgICAgIC8vICAgICAgbmV3TWV0aENvcHlJbklMICAtIGZyb20gQ29weUxvY2FscyBpbnRvIGxvY2FscyBpbiB0aGUgbmV3Ci0gICAgICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZAotICAgICAgICAvLyAgICAgIG5ld01ldGhDb3B5T3V0SUwgLSBmcm9tIGxvY2FscyBpbiBuZXcgbWV0aG9kIGludG8gdGhlIGluc3RhbmNlCi0gICAgICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgIG9mIHRoZSBDb3B5TG9jYWxzIGNsYXNzCi0gICAgICAgIEluc3RydWN0aW9uTGlzdCBvbGRNZXRoQ29weUluSUwgID0gbmV3IEluc3RydWN0aW9uTGlzdCgpOwotICAgICAgICBJbnN0cnVjdGlvbkxpc3Qgb2xkTWV0aENvcHlPdXRJTCA9IG5ldyBJbnN0cnVjdGlvbkxpc3QoKTsKLSAgICAgICAgSW5zdHJ1Y3Rpb25MaXN0IG5ld01ldGhDb3B5SW5JTCAgPSBuZXcgSW5zdHJ1Y3Rpb25MaXN0KCk7Ci0gICAgICAgIEluc3RydWN0aW9uTGlzdCBuZXdNZXRoQ29weU91dElMID0gbmV3IEluc3RydWN0aW9uTGlzdCgpOwotCi0gICAgICAgIC8vIEFsbG9jYXRlIGluc3RhbmNlIG9mIGNsYXNzIGluIHdoaWNoIHdlJ2xsIGNvcHkgaW4gb3IgY29weSBvdXQgbG9jYWxzCi0gICAgICAgIC8vIGFuZCBtYWtlIHR3byBjb3BpZXM6ICBsYXN0IGNvcHkgaXMgdXNlZCB0byBpbnZva2UgY29uc3RydWN0b3I7Ci0gICAgICAgIC8vIG90aGVyIHR3byBhcmUgdXNlZCBmb3IgcmVmZXJlbmNlcyB0byBmaWVsZHMgaW4gdGhlIENvcHlMb2NhbHMgb2JqZWN0Ci0gICAgICAgIEluc3RydWN0aW9uSGFuZGxlIG91dGxpbmVkTWV0aG9kQ2FsbFNldHVwID0KLSAgICAgICAgICAgIG9sZE1ldGhDb3B5SW5JTC5hcHBlbmQobmV3IE5FVyhjcGcuYWRkQ2xhc3MoYXJnVHlwZU5hbWUpKSk7Ci0gICAgICAgIG9sZE1ldGhDb3B5SW5JTC5hcHBlbmQoSW5zdHJ1Y3Rpb25Db25zdGFudHMuRFVQKTsKLSAgICAgICAgb2xkTWV0aENvcHlJbklMLmFwcGVuZChJbnN0cnVjdGlvbkNvbnN0YW50cy5EVVApOwotICAgICAgICBvbGRNZXRoQ29weUluSUwuYXBwZW5kKAotICAgICAgICAgICAgbmV3IElOVk9LRVNQRUNJQUwoY3BnLmFkZE1ldGhvZHJlZihhcmdUeXBlTmFtZSwgIjxpbml0PiIsICIoKVYiKSkpOwotCi0gICAgICAgIC8vIEdlbmVyYXRlIGNvZGUgdG8gaW52b2tlIHRoZSBuZXcgb3V0bGluZWQgbWV0aG9kLCBhbmQgcGxhY2UgdGhlIGNvZGUKLSAgICAgICAgLy8gb24gb2xkTWV0aENvcHlPdXRJTAotICAgICAgICBJbnN0cnVjdGlvbkhhbmRsZSBvdXRsaW5lZE1ldGhvZFJlZjsKLQotICAgICAgICBpZiAoaXNTdGF0aWNNZXRob2QpIHsKLSAgICAgICAgICAgIG91dGxpbmVkTWV0aG9kUmVmID0KLSAgICAgICAgICAgICAgICBvbGRNZXRoQ29weU91dElMLmFwcGVuZCgKLSAgICAgICAgICAgICAgICAgICAgbmV3IElOVk9LRVNUQVRJQyhjcGcuYWRkTWV0aG9kcmVmKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NHZW4uZ2V0Q2xhc3NOYW1lKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdXRsaW5lZE1ldGhvZE5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdXRsaW5lZE1ldGhvZEdlbi5nZXRTaWduYXR1cmUoKSkpKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIG9sZE1ldGhDb3B5T3V0SUwuYXBwZW5kKEluc3RydWN0aW9uQ29uc3RhbnRzLlRISVMpOwotICAgICAgICAgICAgb2xkTWV0aENvcHlPdXRJTC5hcHBlbmQoSW5zdHJ1Y3Rpb25Db25zdGFudHMuU1dBUCk7Ci0gICAgICAgICAgICBvdXRsaW5lZE1ldGhvZFJlZiA9Ci0gICAgICAgICAgICAgICAgb2xkTWV0aENvcHlPdXRJTC5hcHBlbmQoCi0gICAgICAgICAgICAgICAgICAgIG5ldyBJTlZPS0VWSVJUVUFMKGNwZy5hZGRNZXRob2RyZWYoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzc0dlbi5nZXRDbGFzc05hbWUoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dGxpbmVkTWV0aG9kTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dGxpbmVkTWV0aG9kR2VuLmdldFNpZ25hdHVyZSgpKSkpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gVXNlZCB0byBrZWVwIHRyYWNrIG9mIHRoZSBmaXJzdCBpbiBhIHNlcXVlbmNlIG9mCi0gICAgICAgIC8vIE91dGxpbmVhYmxlQ2h1bmtTdGFydCBpbnN0cnVjdGlvbnMKLSAgICAgICAgYm9vbGVhbiBjaHVua1N0YXJ0VGFyZ2V0TWFwcGluZ3NQZW5kaW5nID0gZmFsc2U7Ci0gICAgICAgIEluc3RydWN0aW9uSGFuZGxlIHBlbmRpbmdUYXJnZXRNYXBwaW5nSGFuZGxlID0gbnVsbDsKLQotICAgICAgICAvLyBVc2VkIHRvIGtlZXAgdHJhY2sgb2YgdGhlIGxhc3QgaW5zdHJ1Y3Rpb24gdGhhdCB3YXMgY29waWVkCi0gICAgICAgIEluc3RydWN0aW9uSGFuZGxlIGxhc3RDb3B5SGFuZGxlID0gbnVsbDsKLQotICAgICAgICAvLyBLZWVwcyB0cmFjayBvZiB0aGUgbWFwcGluZyBmcm9tIGluc3RydWN0aW9uIGhhbmRsZXMgaW4gdGhlIG9sZAotICAgICAgICAvLyBtZXRob2QgdG8gaW5zdHJ1Y3Rpb24gaGFuZGxlcyBpbiB0aGUgb3V0bGluZWQgbWV0aG9kLiAgT25seSBuZWVkCi0gICAgICAgIC8vIHRvIHRyYWNrIGluc3RydWN0aW9ucyB0aGF0IGFyZSB0YXJnZXRlZCBieSBzb21ldGhpbmcgZWxzZSBpbiB0aGUKLSAgICAgICAgLy8gZ2VuZXJhdGVkIEJDRUwKLSAgICAgICAgSGFzaE1hcCB0YXJnZXRNYXAgICA9IG5ldyBIYXNoTWFwKCk7Ci0KLSAgICAgICAgLy8gS2VlcHMgdHJhY2sgb2YgdGhlIG1hcHBpbmcgZnJvbSBsb2NhbCB2YXJpYWJsZXMgaW4gdGhlIG9sZCBtZXRob2QKLSAgICAgICAgLy8gdG8gbG9jYWwgdmFyaWFibGVzIGluIHRoZSBvdXRsaW5lZCBtZXRob2QuCi0gICAgICAgIEhhc2hNYXAgbG9jYWxWYXJNYXAgPSBuZXcgSGFzaE1hcCgpOwotCi0gICAgICAgIEhhc2hNYXAgcmV2aXNlZExvY2FsVmFyU3RhcnQgPSBuZXcgSGFzaE1hcCgpOwotICAgICAgICBIYXNoTWFwIHJldmlzZWRMb2NhbFZhckVuZCA9IG5ldyBIYXNoTWFwKCk7Ci0KLSAgICAgICAgLy8gUGFzcyAxOiBNYWtlIGNvcGllcyBvZiBhbGwgaW5zdHJ1Y3Rpb25zLCBhcHBlbmQgdGhlbSB0byB0aGUgbmV3IGxpc3QKLSAgICAgICAgLy8gYW5kIGFzc29jaWF0ZSBvbGQgaW5zdHJ1Y3Rpb24gcmVmZXJlbmNlcyB3aXRoIHRoZSBuZXcgb25lcywgaS5lLiwKLSAgICAgICAgLy8gYSAxOjEgbWFwcGluZy4gIFRoZSBzcGVjaWFsIG1hcmtlciBpbnN0cnVjdGlvbnMgYXJlIG5vdCBjb3BpZWQuCi0gICAgICAgIC8vIEFsc28sIGlkZW50aWZ5IGxvY2FsIHZhcmlhYmxlcyB3aG9zZSB2YWx1ZXMgbmVlZCB0byBiZSBjb3BpZWQgaW50byBvcgotICAgICAgICAvLyBvdXQgb2YgdGhlIG5ldyBvdXRsaW5lZCBtZXRob2QsIGFuZCBidWlsZHMgdXAgdGFyZ2V0TWFwIGFuZAotICAgICAgICAvLyBsb2NhbFZhck1hcCBhcyBkZXNjcmliZWQgYWJvdmUuICBUaGUgY29kZSBpZGVudGlmaWVzIHRob3NlIGxvY2FsCi0gICAgICAgIC8vIHZhcmlhYmxlcyBmaXJzdCBzbyB0aGF0IHRoZXkgY2FuIGhhdmUgZml4ZWQgc2xvdHMgaW4gdGhlIHN0YWNrCi0gICAgICAgIC8vIGZyYW1lIGZvciB0aGUgb3V0bGluZWQgbWV0aG9kIGFzc2lnbmVkIHRoZW0gYWhlYWQgb2YgYWxsIHRob3NlCi0gICAgICAgIC8vIHZhcmlhYmxlcyB0aGF0IGRvbid0IG5lZWQgdG8gZXhpc3QgZm9yIHRoZSBlbnRpcmV0eSBvZiB0aGUgb3V0bGluZWQKLSAgICAgICAgLy8gbWV0aG9kIGludm9jYXRpb24uCi0gICAgICAgIGZvciAoSW5zdHJ1Y3Rpb25IYW5kbGUgaWggPSBmaXJzdDsgaWggIT0gbGltaXQ7IGloID0gaWguZ2V0TmV4dCgpKSB7Ci0gICAgICAgICAgICBJbnN0cnVjdGlvbiBpbnN0ID0gaWguZ2V0SW5zdHJ1Y3Rpb24oKTsKLQotICAgICAgICAgICAgLy8gTWFya2VySW5zdHJ1Y3Rpb25zIGFyZSBub3QgY29waWVkLCBzbyBpZiBzb21ldGhpbmcgZWxzZSB0YXJnZXRzCi0gICAgICAgICAgICAvLyBvbmUsIHRoZSB0YXJnZXRNYXAgd2lsbCBwb2ludCB0byB0aGUgbmVhcmVzdCBjb3BpZWQgc2libGluZwotICAgICAgICAgICAgLy8gSW5zdHJ1Y3Rpb25IYW5kbGU6ICBmb3IgYW4gT3V0bGluZWFibGVDaHVua0VuZCwgdGhlIG5lYXJlc3QKLSAgICAgICAgICAgIC8vIHByZWNlZGluZyBzaWJsaW5nOyBmb3IgYW4gT3V0bGluZWFibGVDaHVua1N0YXJ0LCB0aGUgbmVhcmVzdAotICAgICAgICAgICAgLy8gZm9sbG93aW5nIHNpYmxpbmcuCi0gICAgICAgICAgICBpZiAoaW5zdCBpbnN0YW5jZW9mIE1hcmtlckluc3RydWN0aW9uKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGloLmhhc1RhcmdldGVycygpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChpbnN0IGluc3RhbmNlb2YgT3V0bGluZWFibGVDaHVua0VuZCkgewotICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0TWFwLnB1dChpaCwgbGFzdENvcHlIYW5kbGUpOwotICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFjaHVua1N0YXJ0VGFyZ2V0TWFwcGluZ3NQZW5kaW5nKSAgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNodW5rU3RhcnRUYXJnZXRNYXBwaW5nc1BlbmRpbmcgPSB0cnVlOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBlbmRpbmdUYXJnZXRNYXBwaW5nSGFuZGxlID0gaWg7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIC8vIENvcHkgdGhlIGluc3RydWN0aW9uIGFuZCBhcHBlbmQgaXQgdG8gdGhlIG91dGxpbmVkIG1ldGhvZCdzCi0gICAgICAgICAgICAgICAgLy8gSW5zdHJ1Y3Rpb25MaXN0LgotICAgICAgICAgICAgICAgIEluc3RydWN0aW9uIGMgPSBpbnN0LmNvcHkoKTsgLy8gVXNlIGNsb25lIGZvciBzaGFsbG93IGNvcHkKLQotICAgICAgICAgICAgICAgIGlmIChjIGluc3RhbmNlb2YgQnJhbmNoSW5zdHJ1Y3Rpb24pIHsKLSAgICAgICAgICAgICAgICAgICAgbGFzdENvcHlIYW5kbGUgPSBuZXdJTC5hcHBlbmQoKEJyYW5jaEluc3RydWN0aW9uKWMpOwotICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIGxhc3RDb3B5SGFuZGxlID0gbmV3SUwuYXBwZW5kKGMpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIGlmIChjIGluc3RhbmNlb2YgTG9jYWxWYXJpYWJsZUluc3RydWN0aW9uCi0gICAgICAgICAgICAgICAgICAgICAgICB8fCBjIGluc3RhbmNlb2YgUkVUKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIEZvciBhbnkgaW5zdHJ1Y3Rpb24gdGhhdCB0b3VjaGVzIGEgbG9jYWwgdmFyaWFibGUsCi0gICAgICAgICAgICAgICAgICAgIC8vIGNoZWNrIHdoZXRoZXIgdGhlIGxvY2FsIHZhcmlhYmxlJ3MgdmFsdWUgbmVlZHMgdG8gYmUKLSAgICAgICAgICAgICAgICAgICAgLy8gY29waWVkIGludG8gb3Igb3V0IG9mIHRoZSBvdXRsaW5lZCBtZXRob2QuICBJZiBzbywKLSAgICAgICAgICAgICAgICAgICAgLy8gZ2VuZXJhdGUgdGhlIGNvZGUgdG8gcGVyZm9ybSB0aGUgbmVjZXNzYXJ5IGNvcHlpbmcsIGFuZAotICAgICAgICAgICAgICAgICAgICAvLyB1c2UgbG9jYWxWYXJNYXAgdG8gbWFwIHRoZSB2YXJpYWJsZSBpbiB0aGUgb3JpZ2luYWwKLSAgICAgICAgICAgICAgICAgICAgLy8gbWV0aG9kIHRvIHRoZSB2YXJpYWJsZSBpbiB0aGUgbmV3IG1ldGhvZC4KLSAgICAgICAgICAgICAgICAgICAgSW5kZXhlZEluc3RydWN0aW9uIGx2aSA9IChJbmRleGVkSW5zdHJ1Y3Rpb24pYzsKLSAgICAgICAgICAgICAgICAgICAgaW50IG9sZExvY2FsVmFySW5kZXggPSBsdmkuZ2V0SW5kZXgoKTsKLSAgICAgICAgICAgICAgICAgICAgTG9jYWxWYXJpYWJsZUdlbiBvbGRMVkcgPQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldExvY2FsVmFyaWFibGVSZWdpc3RyeSgpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5sb29rdXBSZWdpc3RlcmVkTG9jYWxWYXJpYWJsZShvbGRMb2NhbFZhckluZGV4LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpaC5nZXRQb3NpdGlvbigpKTsKLSAgICAgICAgICAgICAgICAgICAgTG9jYWxWYXJpYWJsZUdlbiBuZXdMVkcgPQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIChMb2NhbFZhcmlhYmxlR2VuKWxvY2FsVmFyTWFwLmdldChvbGRMVkcpOwotCi0gICAgICAgICAgICAgICAgICAgIC8vIEhhcyB0aGUgY29kZSBhbHJlYWR5IG1hcHBlZCB0aGlzIGxvY2FsIHZhcmlhYmxlIHRvIGEKLSAgICAgICAgICAgICAgICAgICAgLy8gbG9jYWwgaW4gdGhlIG5ldyBtZXRob2Q/Ci0gICAgICAgICAgICAgICAgICAgIGlmIChsb2NhbFZhck1hcC5nZXQob2xkTFZHKSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBEZXRlcm1pbmUgd2hldGhlciB0aGUgbG9jYWwgdmFyaWFibGUgbmVlZHMgdG8gYmUKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNvcGllZCBpbnRvIG9yIG91dCBvZiB0aGUgb3V0bGluZWQgYnkgY2hlY2tpbmcKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIHdoZXRoZXIgdGhlIHJhbmdlIG9mIGluc3RydWN0aW9ucyBpbiB3aGljaCB0aGUKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIHZhcmlhYmxlIGlzIGFjY2Vzc2libGUgaXMgb3V0c2lkZSB0aGUgcmFuZ2Ugb2YKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGluc3RydWN0aW9ucyBpbiB0aGUgb3V0bGluZWFibGUgY2h1bmsuCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBTcGVjaWFsIGNhc2UgYSBjaHVuayBzdGFydCBvZmZzZXQgb2YgemVybzogIGEgbG9jYWwKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIHZhcmlhYmxlIGxpdmUgYXQgdGhhdCBwb3NpdGlvbiBtdXN0IGJlIGEgbWV0aG9kCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBwYXJhbWV0ZXIsIHNvIHRoZSBjb2RlIGRvZXNuJ3QgbmVlZCB0byBjaGVjayB3aGV0aGVyCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGUgdmFyaWFibGUgaXMgbGl2ZSBiZWZvcmUgdGhhdCBwb2ludDsgYmVpbmcgbGl2ZQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gYXQgb2Zmc2V0IHplcm8gaXMgc3VmZmljaWVudCB0byBrbm93IHRoYXQgdGhlIHZhbHVlCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBtdXN0IGJlIGNvcGllZCBpbiB0byB0aGUgb3V0bGluZWQgbWV0aG9kLgotICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBjb3B5SW5Mb2NhbFZhbHVlID0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXRJbkxvY2FsVmFyaWFibGVHZW5SYW5nZShvbGRMVkcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAob3V0bGluZUNodW5rU3RhcnRPZmZzZXQgIT0gMCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IG91dGxpbmVDaHVua1N0YXJ0T2Zmc2V0LTEKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IDApOwotICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBjb3B5T3V0TG9jYWxWYWx1ZSA9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0SW5Mb2NhbFZhcmlhYmxlR2VuUmFuZ2Uob2xkTFZHLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3V0bGluZUNodW5rRW5kT2Zmc2V0KzEpOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBGb3IgYW55IHZhcmlhYmxlIHRoYXQgbmVlZHMgdG8gYmUgY29waWVkIGludG8gb3Igb3V0Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBvZiB0aGUgb3V0bGluZWQgbWV0aG9kLCBjcmVhdGUgYSBmaWVsZCBpbiB0aGUKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIENvcHlMb2NhbHMgY2xhc3MsIGFuZCBnZW5lcmF0ZSB0aGUgbmVjZXNzYXJ5IGNvZGUgZm9yCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBjb3B5aW5nIHRoZSB2YWx1ZS4KLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb3B5SW5Mb2NhbFZhbHVlIHx8IGNvcHlPdXRMb2NhbFZhbHVlKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHZhck5hbWUgPSBvbGRMVkcuZ2V0TmFtZSgpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFR5cGUgdmFyVHlwZSA9IG9sZExWRy5nZXRUeXBlKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3TFZHID0gb3V0bGluZWRNZXRob2RHZW4uYWRkTG9jYWxWYXJpYWJsZSh2YXJOYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyVHlwZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbmV3TG9jYWxWYXJJbmRleCA9IG5ld0xWRy5nZXRJbmRleCgpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyB2YXJTaWduYXR1cmUgPSB2YXJUeXBlLmdldFNpZ25hdHVyZSgpOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUmVjb3JkIHRoZSBtYXBwaW5nIGZyb20gdGhlIG9sZCBsb2NhbCB0byB0aGUgbmV3Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWxWYXJNYXAucHV0KG9sZExWRywgbmV3TFZHKTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvcHlBcmVhRmllbGRDb3VudCsrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBjb3B5QXJlYUZpZWxkTmFtZSA9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImZpZWxkIiArIGNvcHlBcmVhRmllbGRDb3VudDsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3B5QXJlYUNHLmFkZEZpZWxkKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgRmllbGQoQUNDX1BVQkxJQywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3B5QXJlYUNQRy5hZGRVdGY4KGNvcHlBcmVhRmllbGROYW1lKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3B5QXJlYUNQRy5hZGRVdGY4KHZhclNpZ25hdHVyZSksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwgY29weUFyZWFDUEcuZ2V0Q29uc3RhbnRQb29sKCkpKTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBmaWVsZFJlZiA9IGNwZy5hZGRGaWVsZHJlZihhcmdUeXBlTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29weUFyZWFGaWVsZE5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhclNpZ25hdHVyZSk7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29weUluTG9jYWxWYWx1ZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBHZW5lcmF0ZSBjb2RlIGZvciB0aGUgb2xkIG1ldGhvZCB0byBzdG9yZSB0aGUKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdmFsdWUgb2YgdGhlIGxvY2FsIGludG8gdGhlIGNvcnJlY3QgZmllbGQgaW4KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ29weUxvY2FscyBwcmlvciB0byBpbnZvY2F0aW9uIG9mIHRoZQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBvdXRsaW5lZCBtZXRob2QuCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9sZE1ldGhDb3B5SW5JTC5hcHBlbmQoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW5zdHJ1Y3Rpb25Db25zdGFudHMuRFVQKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW5zdHJ1Y3Rpb25IYW5kbGUgY29weUluTG9hZCA9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbGRNZXRoQ29weUluSUwuYXBwZW5kKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvYWRMb2NhbChvbGRMb2NhbFZhckluZGV4LCB2YXJUeXBlKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9sZE1ldGhDb3B5SW5JTC5hcHBlbmQobmV3IFBVVEZJRUxEKGZpZWxkUmVmKSk7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSWYgdGhlIGVuZCBvZiB0aGUgbGl2ZSByYW5nZSBvZiB0aGUgb2xkCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHZhcmlhYmxlIHdhcyBpbiB0aGUgbWlkZGxlIG9mIHRoZSBvdXRsaW5lZAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjaHVuay4gIE1ha2UgdGhlIGxvYWQgb2YgaXRzIHZhbHVlIHRoZSBuZXcKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZW5kIG9mIGl0cyByYW5nZS4KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFjb3B5T3V0TG9jYWxWYWx1ZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV2aXNlZExvY2FsVmFyRW5kLnB1dChvbGRMVkcsIGNvcHlJbkxvYWQpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gR2VuZXJhdGUgY29kZSBmb3Igc3RhcnQgb2YgdGhlIG91dGxpbmVkCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG1ldGhvZCB0byBjb3B5IHRoZSB2YWx1ZSBmcm9tIGEgZmllbGQgaW4KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ29weUxvY2FscyB0byB0aGUgbmV3IGxvY2FsIGluIHRoZSBvdXRsaW5lZAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBtZXRob2QKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3TWV0aENvcHlJbklMLmFwcGVuZCgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbnN0cnVjdGlvbkNvbnN0YW50cy5BTE9BRF8xKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3TWV0aENvcHlJbklMLmFwcGVuZChuZXcgR0VURklFTEQoZmllbGRSZWYpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3TWV0aENvcHlJbklMLmFwcGVuZCgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdG9yZUxvY2FsKG5ld0xvY2FsVmFySW5kZXgsIHZhclR5cGUpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29weU91dExvY2FsVmFsdWUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gR2VuZXJhdGUgY29kZSBmb3IgdGhlIGVuZCBvZiB0aGUgb3V0bGluZWQKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbWV0aG9kIHRvIGNvcHkgdGhlIHZhbHVlIGZyb20gdGhlIG5ldyBsb2NhbAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB2YXJpYWJsZSBpbnRvIGEgZmllbGQgaW4gQ29weUxvY2FscwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBtZXRob2QKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3TWV0aENvcHlPdXRJTC5hcHBlbmQoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW5zdHJ1Y3Rpb25Db25zdGFudHMuQUxPQURfMSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld01ldGhDb3B5T3V0SUwuYXBwZW5kKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvYWRMb2NhbChuZXdMb2NhbFZhckluZGV4LCB2YXJUeXBlKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld01ldGhDb3B5T3V0SUwuYXBwZW5kKG5ldyBQVVRGSUVMRChmaWVsZFJlZikpOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEdlbmVyYXRlIGNvZGUgdG8gY29weSB0aGUgdmFsdWUgZnJvbSBhIGZpZWxkCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGluIENvcHlMb2NhbHMgaW50byBhIGxvY2FsIGluIHRoZSBvcmlnaW5hbAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBtZXRob2QgZm9sbG93aW5nIGludm9jYXRpb24gb2YgdGhlIG91dGxpbmVkCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG1ldGhvZC4KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2xkTWV0aENvcHlPdXRJTC5hcHBlbmQoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW5zdHJ1Y3Rpb25Db25zdGFudHMuRFVQKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2xkTWV0aENvcHlPdXRJTC5hcHBlbmQobmV3IEdFVEZJRUxEKGZpZWxkUmVmKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluc3RydWN0aW9uSGFuZGxlIGNvcHlPdXRTdG9yZSA9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbGRNZXRoQ29weU91dElMLmFwcGVuZCgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdG9yZUxvY2FsKG9sZExvY2FsVmFySW5kZXgsIHZhclR5cGUpKTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJZiB0aGUgc3RhcnQgb2YgdGhlIGxpdmUgcmFuZ2Ugb2YgdGhlIG9sZAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB2YXJpYWJsZSB3YXMgaW4gdGhlIG1pZGRsZSBvZiB0aGUgb3V0bGluZWQKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2h1bmsuICBNYWtlIHRoaXMgc3RvcmUgaW50byBpdCB0aGUgbmV3IHN0YXJ0Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG9mIGl0cyByYW5nZS4KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFjb3B5SW5Mb2NhbFZhbHVlKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXZpc2VkTG9jYWxWYXJTdGFydC5wdXQob2xkTFZHLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvcHlPdXRTdG9yZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBpZiAoaWguaGFzVGFyZ2V0ZXJzKCkpIHsKLSAgICAgICAgICAgICAgICAgICAgdGFyZ2V0TWFwLnB1dChpaCwgbGFzdENvcHlIYW5kbGUpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8vIElmIHRoaXMgaXMgdGhlIGZpcnN0IGluc3RydWN0aW9uIGNvcGllZCBmb2xsb3dpbmcgYSBzZXF1ZW5jZQotICAgICAgICAgICAgICAgIC8vIG9mIE91dGxpbmVhYmxlQ2h1bmtTdGFydCBpbnN0cnVjdGlvbnMsIGluZGljYXRlIHRoYXQgdGhlCi0gICAgICAgICAgICAgICAgLy8gc2VxdWVuY2Ugb2Ygb2xkIGluc3RydWN0aW9uIGFsbCBtYXAgdG8gdGhpcyBuZXdseSBjcmVhdGVkCi0gICAgICAgICAgICAgICAgLy8gaW5zdHJ1Y3Rpb24KLSAgICAgICAgICAgICAgICBpZiAoY2h1bmtTdGFydFRhcmdldE1hcHBpbmdzUGVuZGluZykgewotICAgICAgICAgICAgICAgICAgICBkbyB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0TWFwLnB1dChwZW5kaW5nVGFyZ2V0TWFwcGluZ0hhbmRsZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RDb3B5SGFuZGxlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICBwZW5kaW5nVGFyZ2V0TWFwcGluZ0hhbmRsZSA9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwZW5kaW5nVGFyZ2V0TWFwcGluZ0hhbmRsZS5nZXROZXh0KCk7Ci0gICAgICAgICAgICAgICAgICAgIH0gd2hpbGUocGVuZGluZ1RhcmdldE1hcHBpbmdIYW5kbGUgIT0gaWgpOwotCi0gICAgICAgICAgICAgICAgICAgIGNodW5rU3RhcnRUYXJnZXRNYXBwaW5nc1BlbmRpbmcgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBQYXNzIDI6IFdhbGsgb2xkIGFuZCBuZXcgaW5zdHJ1Y3Rpb24gbGlzdHMsIHVwZGF0aW5nIGJyYW5jaCB0YXJnZXRzCi0gICAgICAgIC8vIGFuZCBsb2NhbCB2YXJpYWJsZSByZWZlcmVuY2VzIGluIHRoZSBuZXcgbGlzdAotICAgICAgICBJbnN0cnVjdGlvbkhhbmRsZSBpaCA9IGZpcnN0OwotICAgICAgICBJbnN0cnVjdGlvbkhhbmRsZSBjaCA9IG5ld0lMLmdldFN0YXJ0KCk7Ci0KLSAgICAgICAgd2hpbGUgKGNoICE9IG51bGwpIHsKLSAgICAgICAgICAgIC8vIGkgPT0gb2xkIGluc3RydWN0aW9uOyBjID09IGNvcGllZCBpbnN0cnVjdGlvbgotICAgICAgICAgICAgSW5zdHJ1Y3Rpb24gaSA9IGloLmdldEluc3RydWN0aW9uKCk7Ci0gICAgICAgICAgICBJbnN0cnVjdGlvbiBjID0gY2guZ2V0SW5zdHJ1Y3Rpb24oKTsKLQotICAgICAgICAgICAgaWYgKGkgaW5zdGFuY2VvZiBCcmFuY2hJbnN0cnVjdGlvbikgewotICAgICAgICAgICAgICAgIEJyYW5jaEluc3RydWN0aW9uIGJjICAgICAgPSAoQnJhbmNoSW5zdHJ1Y3Rpb24pYzsKLSAgICAgICAgICAgICAgICBCcmFuY2hJbnN0cnVjdGlvbiBiaSAgICAgID0gKEJyYW5jaEluc3RydWN0aW9uKWk7Ci0gICAgICAgICAgICAgICAgSW5zdHJ1Y3Rpb25IYW5kbGUgaXRhcmdldCA9IGJpLmdldFRhcmdldCgpOyAvLyBvbGQgdGFyZ2V0Ci0KLSAgICAgICAgICAgICAgICAvLyBOZXcgdGFyZ2V0IG11c3QgYmUgaW4gdGFyZ2V0TWFwCi0gICAgICAgICAgICAgICAgSW5zdHJ1Y3Rpb25IYW5kbGUgbmV3VGFyZ2V0ID0KLSAgICAgICAgICAgICAgICAgICAgKEluc3RydWN0aW9uSGFuZGxlKXRhcmdldE1hcC5nZXQoaXRhcmdldCk7Ci0KLSAgICAgICAgICAgICAgICBiYy5zZXRUYXJnZXQobmV3VGFyZ2V0KTsKLQotICAgICAgICAgICAgICAgIC8vIEhhbmRsZSBMT09LVVBTV0lUQ0ggb3IgVEFCTEVTV0lUQ0ggd2hpY2ggbWF5IGhhdmUgbWFueQotICAgICAgICAgICAgICAgIC8vIHRhcmdldCBpbnN0cnVjdGlvbnMKLSAgICAgICAgICAgICAgICBpZiAoYmkgaW5zdGFuY2VvZiBTZWxlY3QpIHsKLSAgICAgICAgICAgICAgICAgICAgSW5zdHJ1Y3Rpb25IYW5kbGVbXSBpdGFyZ2V0cyA9ICgoU2VsZWN0KWJpKS5nZXRUYXJnZXRzKCk7Ci0gICAgICAgICAgICAgICAgICAgIEluc3RydWN0aW9uSGFuZGxlW10gY3RhcmdldHMgPSAoKFNlbGVjdCliYykuZ2V0VGFyZ2V0cygpOwotCi0gICAgICAgICAgICAgICAgICAgIC8vIFVwZGF0ZSBhbGwgdGFyZ2V0cwotICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBqPTA7IGogPCBpdGFyZ2V0cy5sZW5ndGg7IGorKykgewotICAgICAgICAgICAgICAgICAgICAgICAgY3RhcmdldHNbal0gPQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIChJbnN0cnVjdGlvbkhhbmRsZSl0YXJnZXRNYXAuZ2V0KGl0YXJnZXRzW2pdKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0gIGVsc2UgaWYgKGkgaW5zdGFuY2VvZiBMb2NhbFZhcmlhYmxlSW5zdHJ1Y3Rpb24KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCBpIGluc3RhbmNlb2YgUkVUKSB7Ci0gICAgICAgICAgICAgICAgLy8gRm9yIGFueSBpbnN0cnVjdGlvbiB0aGF0IHRvdWNoZXMgYSBsb2NhbCB2YXJpYWJsZSwKLSAgICAgICAgICAgICAgICAvLyBtYXAgdGhlIGxvY2F0aW9uIG9mIHRoZSB2YXJpYWJsZSBpbiB0aGUgb3JpZ2luYWwKLSAgICAgICAgICAgICAgICAvLyBtZXRob2QgdG8gaXRzIGxvY2F0aW9uIGluIHRoZSBuZXcgbWV0aG9kLgotICAgICAgICAgICAgICAgIEluZGV4ZWRJbnN0cnVjdGlvbiBsdmkgPSAoSW5kZXhlZEluc3RydWN0aW9uKWM7Ci0gICAgICAgICAgICAgICAgaW50IG9sZExvY2FsVmFySW5kZXggPSBsdmkuZ2V0SW5kZXgoKTsKLSAgICAgICAgICAgICAgICBMb2NhbFZhcmlhYmxlR2VuIG9sZExWRyA9Ci0gICAgICAgICAgICAgICAgICAgICAgICBnZXRMb2NhbFZhcmlhYmxlUmVnaXN0cnkoKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAubG9va3VwUmVnaXN0ZXJlZExvY2FsVmFyaWFibGUob2xkTG9jYWxWYXJJbmRleCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWguZ2V0UG9zaXRpb24oKSk7Ci0gICAgICAgICAgICAgICAgTG9jYWxWYXJpYWJsZUdlbiBuZXdMVkcgPQotICAgICAgICAgICAgICAgICAgICAgICAgKExvY2FsVmFyaWFibGVHZW4pbG9jYWxWYXJNYXAuZ2V0KG9sZExWRyk7Ci0gICAgICAgICAgICAgICAgaW50IG5ld0xvY2FsVmFySW5kZXg7Ci0KLSAgICAgICAgICAgICAgICBpZiAobmV3TFZHID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gQ3JlYXRlIG5ldyB2YXJpYWJsZSBiYXNlZCBvbiBvbGQgdmFyaWFibGUgLSB1c2Ugc2FtZQotICAgICAgICAgICAgICAgICAgICAvLyBuYW1lIGFuZCB0eXBlLCBidXQgd2Ugd2lsbCBsZXQgdGhlIHZhcmlhYmxlIGJlIGFjdGl2ZQotICAgICAgICAgICAgICAgICAgICAvLyBmb3IgdGhlIGVudGlyZSBvdXRsaW5lZCBtZXRob2QuCi0gICAgICAgICAgICAgICAgICAgIC8vIExvY2FsVmFyaWFibGVHZW4gb2xkTG9jYWwgPSBvbGRMb2NhbHNbb2xkTG9jYWxWYXJJbmRleF07Ci0gICAgICAgICAgICAgICAgICAgIFN0cmluZyB2YXJOYW1lID0gb2xkTFZHLmdldE5hbWUoKTsKLSAgICAgICAgICAgICAgICAgICAgVHlwZSB2YXJUeXBlID0gb2xkTFZHLmdldFR5cGUoKTsKLSAgICAgICAgICAgICAgICAgICAgbmV3TFZHID0gb3V0bGluZWRNZXRob2RHZW4uYWRkTG9jYWxWYXJpYWJsZSh2YXJOYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhclR5cGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgbmV3TG9jYWxWYXJJbmRleCA9IG5ld0xWRy5nZXRJbmRleCgpOwotICAgICAgICAgICAgICAgICAgICBsb2NhbFZhck1hcC5wdXQob2xkTFZHLCBuZXdMVkcpOwotCi0gICAgICAgICAgICAgICAgICAgIC8vIFRoZSBvbGQgdmFyaWFibGUncyBsaXZlIHJhbmdlIHdhcyB3aG9sbHkgY29udGFpbmVkIGluCi0gICAgICAgICAgICAgICAgICAgIC8vIHRoZSBvdXRsaW5lZCBjaHVuay4gIFRoZXJlIHNob3VsZCBubyBsb25nZXIgYmUgc3RvcmVzCi0gICAgICAgICAgICAgICAgICAgIC8vIG9mIHZhbHVlcyBpbnRvIGl0IG9yIGxvYWRzIG9mIGl0cyB2YWx1ZSwgc28gd2UgY2FuIGp1c3QKLSAgICAgICAgICAgICAgICAgICAgLy8gbWFyayBpdHMgbGl2ZSByYW5nZSBhcyB0aGUgcmVmZXJlbmNlIHRvIHRoZSBvdXRsaW5lZAotICAgICAgICAgICAgICAgICAgICAvLyBtZXRob2QuCi0gICAgICAgICAgICAgICAgICAgIHJldmlzZWRMb2NhbFZhclN0YXJ0LnB1dChvbGRMVkcsIG91dGxpbmVkTWV0aG9kUmVmKTsKLSAgICAgICAgICAgICAgICAgICAgcmV2aXNlZExvY2FsVmFyRW5kLnB1dChvbGRMVkcsIG91dGxpbmVkTWV0aG9kUmVmKTsKLSAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICBuZXdMb2NhbFZhckluZGV4ID0gbmV3TFZHLmdldEluZGV4KCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGx2aS5zZXRJbmRleChuZXdMb2NhbFZhckluZGV4KTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gSWYgdGhlIG9sZCBpbnN0cnVjdGlvbiBtYXJrcyB0aGUgZW5kIG9mIHRoZSByYW5nZSBvZiBhIGxvY2FsCi0gICAgICAgICAgICAvLyB2YXJpYWJsZSwgbWFrZSBzdXJlIHRoYXQgYW55IHNsb3RzIG9uIHRoZSBzdGFjayByZXNlcnZlZCBmb3IKLSAgICAgICAgICAgIC8vIGxvY2FsIHZhcmlhYmxlcyBhcmUgbWFkZSBhdmFpbGFibGUgZm9yIHJldXNlIGJ5IGNhbGxpbmcKLSAgICAgICAgICAgIC8vIE1ldGhvZEdlbmVyYXRvci5yZW1vdmVMb2NhbFZhcmlhYmxlCi0gICAgICAgICAgICBpZiAoaWguaGFzVGFyZ2V0ZXJzKCkpIHsKLSAgICAgICAgICAgICAgICBJbnN0cnVjdGlvblRhcmdldGVyW10gdGFyZ2V0ZXJzID0gaWguZ2V0VGFyZ2V0ZXJzKCk7Ci0KLSAgICAgICAgICAgICAgICBmb3IgKGludCBpZHggPSAwOyBpZHggPCB0YXJnZXRlcnMubGVuZ3RoOyBpZHgrKykgewotICAgICAgICAgICAgICAgICAgICBJbnN0cnVjdGlvblRhcmdldGVyIHRhcmdldGVyID0gdGFyZ2V0ZXJzW2lkeF07Ci0KLSAgICAgICAgICAgICAgICAgICAgaWYgKHRhcmdldGVyIGluc3RhbmNlb2YgTG9jYWxWYXJpYWJsZUdlbgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmICgoTG9jYWxWYXJpYWJsZUdlbil0YXJnZXRlcikuZ2V0RW5kKCk9PWloKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBPYmplY3QgbmV3TFZHID0gbG9jYWxWYXJNYXAuZ2V0KHRhcmdldGVyKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuZXdMVkcgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dGxpbmVkTWV0aG9kR2VuLnJlbW92ZUxvY2FsVmFyaWFibGUoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChMb2NhbFZhcmlhYmxlR2VuKW5ld0xWRyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIElmIHRoZSBjdXJyZW50IGluc3RydWN0aW9uIGluIHRoZSBvcmlnaW5hbCBsaXN0IHdhcyBhIG1hcmtlciwKLSAgICAgICAgICAgIC8vIGl0IHdhc24ndCBjb3BpZWQsIHNvIGRvbid0IGFkdmFuY2UgdGhyb3VnaCB0aGUgbGlzdCBvZiBjb3BpZWQKLSAgICAgICAgICAgIC8vIGluc3RydWN0aW9ucyB5ZXQuCi0gICAgICAgICAgICBpZiAoIShpIGluc3RhbmNlb2YgTWFya2VySW5zdHJ1Y3Rpb24pKSB7Ci0gICAgICAgICAgICAgICAgY2ggPSBjaC5nZXROZXh0KCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpaCA9IGloLmdldE5leHQoKTsKLQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gUE9QIHRoZSByZWZlcmVuY2UgdG8gdGhlIENvcHlMb2NhbHMgb2JqZWN0IGZyb20gdGhlIHN0YWNrCi0gICAgICAgIG9sZE1ldGhDb3B5T3V0SUwuYXBwZW5kKEluc3RydWN0aW9uQ29uc3RhbnRzLlBPUCk7Ci0KLSAgICAgICAgLy8gTm93IHRoYXQgdGhlIGdlbmVyYXRpb24gb2YgdGhlIG91dGxpbmVkIGNvZGUgaXMgY29tcGxldGUsIHVwZGF0ZQotICAgICAgICAvLyB0aGUgb2xkIGxvY2FsIHZhcmlhYmxlcyB3aXRoIG5ldyBzdGFydCBhbmQgZW5kIHJhbmdlcywgYXMgcmVxdWlyZWQuCi0gICAgICAgIEl0ZXJhdG9yIHJldmlzZWRMb2NhbFZhclN0YXJ0UGFpckl0ZXIgPSByZXZpc2VkTG9jYWxWYXJTdGFydC5lbnRyeVNldCgpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5pdGVyYXRvcigpOwotICAgICAgICB3aGlsZSAocmV2aXNlZExvY2FsVmFyU3RhcnRQYWlySXRlci5oYXNOZXh0KCkpIHsKLSAgICAgICAgICAgIE1hcC5FbnRyeSBsdmdSYW5nZVN0YXJ0UGFpciA9Ci0gICAgICAgICAgICAgICAgICAgIChNYXAuRW50cnkpcmV2aXNlZExvY2FsVmFyU3RhcnRQYWlySXRlci5uZXh0KCk7Ci0gICAgICAgICAgICBMb2NhbFZhcmlhYmxlR2VuIGx2ZyA9IChMb2NhbFZhcmlhYmxlR2VuKWx2Z1JhbmdlU3RhcnRQYWlyLmdldEtleSgpOwotICAgICAgICAgICAgSW5zdHJ1Y3Rpb25IYW5kbGUgc3RhcnRJbnN0ID0KLSAgICAgICAgICAgICAgICAgICAgKEluc3RydWN0aW9uSGFuZGxlKWx2Z1JhbmdlU3RhcnRQYWlyLmdldFZhbHVlKCk7Ci0KLSAgICAgICAgICAgIGx2Zy5zZXRTdGFydChzdGFydEluc3QpOwotCi0gICAgICAgIH0KLQotICAgICAgICBJdGVyYXRvciByZXZpc2VkTG9jYWxWYXJFbmRQYWlySXRlciA9IHJldmlzZWRMb2NhbFZhckVuZC5lbnRyeVNldCgpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLml0ZXJhdG9yKCk7Ci0gICAgICAgIHdoaWxlIChyZXZpc2VkTG9jYWxWYXJFbmRQYWlySXRlci5oYXNOZXh0KCkpIHsKLSAgICAgICAgICAgIE1hcC5FbnRyeSBsdmdSYW5nZUVuZFBhaXIgPQotICAgICAgICAgICAgICAgICAgICAoTWFwLkVudHJ5KXJldmlzZWRMb2NhbFZhckVuZFBhaXJJdGVyLm5leHQoKTsKLSAgICAgICAgICAgIExvY2FsVmFyaWFibGVHZW4gbHZnID0gKExvY2FsVmFyaWFibGVHZW4pbHZnUmFuZ2VFbmRQYWlyLmdldEtleSgpOwotICAgICAgICAgICAgSW5zdHJ1Y3Rpb25IYW5kbGUgZW5kSW5zdCA9Ci0gICAgICAgICAgICAgICAgICAgIChJbnN0cnVjdGlvbkhhbmRsZSlsdmdSYW5nZUVuZFBhaXIuZ2V0VmFsdWUoKTsKLQotICAgICAgICAgICAgbHZnLnNldEVuZChlbmRJbnN0KTsKLSAgICAgICAgfQotCi0gICAgICAgIHhzbHRjLmR1bXBDbGFzcyhjb3B5QXJlYUNHLmdldEphdmFDbGFzcygpKTsKLQotICAgICAgICAvLyBBc3NlbWJsZSB0aGUgaW5zdHJ1Y3Rpb24gbGlzdHMgc28gdGhhdCB0aGUgb2xkIG1ldGhvZCBpbnZva2VzIHRoZQotICAgICAgICAvLyBuZXcgb3V0bGluZWQgbWV0aG9kCi0gICAgICAgIEluc3RydWN0aW9uTGlzdCBvbGRNZXRob2RJTCA9IGdldEluc3RydWN0aW9uTGlzdCgpOwotCi0gICAgICAgIG9sZE1ldGhvZElMLmluc2VydChmaXJzdCwgb2xkTWV0aENvcHlJbklMKTsKLSAgICAgICAgb2xkTWV0aG9kSUwuaW5zZXJ0KGZpcnN0LCBvbGRNZXRoQ29weU91dElMKTsKLQotICAgICAgICAvLyBJbnNlcnQgdGhlIGNvcHlpbmcgY29kZSBpbnRvIHRoZSBvdXRsaW5lZCBtZXRob2QKLSAgICAgICAgbmV3SUwuaW5zZXJ0KG5ld01ldGhDb3B5SW5JTCk7Ci0gICAgICAgIG5ld0lMLmFwcGVuZChuZXdNZXRoQ29weU91dElMKTsKLSAgICAgICAgbmV3SUwuYXBwZW5kKEluc3RydWN0aW9uQ29uc3RhbnRzLlJFVFVSTik7Ci0KLSAgICAgICAgLy8gRGlzY2FyZCBpbnN0cnVjdGlvbnMgaW4gb3V0bGluZWFibGUgY2h1bmsgZnJvbSBvbGQgbWV0aG9kCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBvbGRNZXRob2RJTC5kZWxldGUoZmlyc3QsIGxhc3QpOwotICAgICAgICB9IGNhdGNoIChUYXJnZXRMb3N0RXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIEluc3RydWN0aW9uSGFuZGxlW10gdGFyZ2V0cyA9IGUuZ2V0VGFyZ2V0cygpOwotICAgICAgICAgICAgLy8gSWYgdGhlcmUgd2VyZSBzdGlsbCByZWZlcmVuY2VzIHRvIG9sZCBpbnN0cnVjdGlvbnMgbGluZ2VyaW5nLAotICAgICAgICAgICAgLy8gY2xlYW4gdGhvc2UgdXAuICBUaGUgb25seSBpbnN0cnVjdGlvbnMgdGFyZ2V0dGluZyB0aGUgZGVsZXRlZAotICAgICAgICAgICAgLy8gaW5zdHJ1Y3Rpb25zIHNob3VsZCBoYXZlIGJlZW4gcGFydCBvZiB0aGUgY2h1bmsgdGhhdCB3YXMganVzdAotICAgICAgICAgICAgLy8gZGVsZXRlZCwgZXhjZXB0IHRoYXQgaW5zdHJ1Y3Rpb25zIG1pZ2h0IGJyYW5jaCB0byB0aGUgc3RhcnQgb2YKLSAgICAgICAgICAgIC8vIHRoZSBvdXRsaW5lZCBjaHVuazsgc2ltaWxhcmx5LCBhbGwgdGhlIGxpdmUgcmFuZ2VzIG9mIGxvY2FsCi0gICAgICAgICAgICAvLyB2YXJpYWJsZXMgc2hvdWxkIGhhdmUgYmVlbiBhZGp1c3RlZCwgZXhjZXB0IGZvciB1bnJlZmVyZW5jZWQKLSAgICAgICAgICAgIC8vIHZhcmlhYmxlcy4KLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdGFyZ2V0cy5sZW5ndGg7IGkrKykgewotICAgICAgICAgICAgICAgIEluc3RydWN0aW9uSGFuZGxlIGxvc3RUYXJnZXQgPSB0YXJnZXRzW2ldOwotICAgICAgICAgICAgICAgIEluc3RydWN0aW9uVGFyZ2V0ZXJbXSB0YXJnZXRlcnMgPSBsb3N0VGFyZ2V0LmdldFRhcmdldGVycygpOwotICAgICAgICAgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgdGFyZ2V0ZXJzLmxlbmd0aDsgaisrKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmICh0YXJnZXRlcnNbal0gaW5zdGFuY2VvZiBMb2NhbFZhcmlhYmxlR2VuKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBMb2NhbFZhcmlhYmxlR2VuIGx2Z1RhcmdldGVyID0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChMb2NhbFZhcmlhYmxlR2VuKSB0YXJnZXRlcnNbal07Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBJbiB0aGUgY2FzZSBvZiBhbnkgbGluZ2VyaW5nIHZhcmlhYmxlIHJlZmVyZW5jZXMsCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBqdXN0IG1ha2UgdGhlIGxpdmUgcmFuZ2UgcG9pbnQgdG8gdGhlIG91dGxpbmVkCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBmdW5jdGlvbiByZWZlcmVuY2UuICBTdWNoIHZhcmlhYmxlcyBzaG91bGQgYmUgdW51c2VkCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBhbnl3YXkuCi0gICAgICAgICAgICAgICAgICAgICAgICBpZiAobHZnVGFyZ2V0ZXIuZ2V0U3RhcnQoKSA9PSBsb3N0VGFyZ2V0KSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbHZnVGFyZ2V0ZXIuc2V0U3RhcnQob3V0bGluZWRNZXRob2RSZWYpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGx2Z1RhcmdldGVyLmdldEVuZCgpID09IGxvc3RUYXJnZXQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBsdmdUYXJnZXRlci5zZXRFbmQob3V0bGluZWRNZXRob2RSZWYpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0ZXJzW2pdLnVwZGF0ZVRhcmdldChsb3N0VGFyZ2V0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdXRsaW5lZE1ldGhvZENhbGxTZXR1cCk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBNYWtlIGEgY29weSBmb3IgdGhlIG5ldyBtZXRob2Qgb2YgYWxsIGV4Y2VwdGlvbnMgdGhhdCBtaWdodCBiZSB0aHJvd24KLSAgICAgICAgU3RyaW5nW10gZXhjZXB0aW9ucyA9IGdldEV4Y2VwdGlvbnMoKTsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBleGNlcHRpb25zLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICBvdXRsaW5lZE1ldGhvZEdlbi5hZGRFeGNlcHRpb24oZXhjZXB0aW9uc1tpXSk7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gb3V0bGluZWRNZXRob2RHZW4uZ2V0VGhpc01ldGhvZCgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEhlbHBlciBtZXRob2QgdG8gZ2VuZXJhdGUgYW4gaW5zdGFuY2Ugb2YgYSBzdWJjbGFzcyBvZgotICAgICAqIHtAbGluayBMb2FkSW5zdHJ1Y3Rpb259IGJhc2VkIG9uIHRoZSBzcGVjaWZpZWQge0BsaW5rIFR5cGV9IHRoYXQgd2lsbAotICAgICAqIGxvYWQgdGhlIHNwZWNpZmllZCBsb2NhbCB2YXJpYWJsZQotICAgICAqIEBwYXJhbSBpbmRleCB0aGUgSlZNIHN0YWNrIGZyYW1lIGluZGV4IG9mIHRoZSB2YXJpYWJsZSB0aGF0IGlzIHRvIGJlCi0gICAgICogbG9hZGVkCi0gICAgICogQHBhcmFtIHR5cGUgdGhlIHtAbGluayBUeXBlfSBvZiB0aGUgdmFyaWFibGUKLSAgICAgKiBAcmV0dXJuIHRoZSBnZW5lcmF0ZWQge0BsaW5rIExvYWRJbnN0cnVjdGlvbn0KLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBJbnN0cnVjdGlvbiBsb2FkTG9jYWwoaW50IGluZGV4LCBUeXBlIHR5cGUpIHsKLSAgICAgICAgaWYgKHR5cGUgPT0gVHlwZS5CT09MRUFOKSB7Ci0gICAgICAgICAgIHJldHVybiBuZXcgSUxPQUQoaW5kZXgpOwotICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT0gVHlwZS5JTlQpIHsKLSAgICAgICAgICAgcmV0dXJuIG5ldyBJTE9BRChpbmRleCk7Ci0gICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PSBUeXBlLlNIT1JUKSB7Ci0gICAgICAgICAgIHJldHVybiBuZXcgSUxPQUQoaW5kZXgpOwotICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT0gVHlwZS5MT05HKSB7Ci0gICAgICAgICAgIHJldHVybiBuZXcgTExPQUQoaW5kZXgpOwotICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT0gVHlwZS5CWVRFKSB7Ci0gICAgICAgICAgIHJldHVybiBuZXcgSUxPQUQoaW5kZXgpOwotICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT0gVHlwZS5DSEFSKSB7Ci0gICAgICAgICAgIHJldHVybiBuZXcgSUxPQUQoaW5kZXgpOwotICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT0gVHlwZS5GTE9BVCkgewotICAgICAgICAgICByZXR1cm4gbmV3IEZMT0FEKGluZGV4KTsKLSAgICAgICAgfSBlbHNlIGlmICh0eXBlID09IFR5cGUuRE9VQkxFKSB7Ci0gICAgICAgICAgIHJldHVybiBuZXcgRExPQUQoaW5kZXgpOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICByZXR1cm4gbmV3IEFMT0FEKGluZGV4KTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEhlbHBlciBtZXRob2QgdG8gZ2VuZXJhdGUgYW4gaW5zdGFuY2Ugb2YgYSBzdWJjbGFzcyBvZgotICAgICAqIHtAbGluayBTdG9yZUluc3RydWN0aW9ufSBiYXNlZCBvbiB0aGUgc3BlY2lmaWVkIHtAbGluayBUeXBlfSB0aGF0IHdpbGwKLSAgICAgKiBzdG9yZSBhIHZhbHVlIGluIHRoZSBzcGVjaWZpZWQgbG9jYWwgdmFyaWFibGUKLSAgICAgKiBAcGFyYW0gaW5kZXggdGhlIEpWTSBzdGFjayBmcmFtZSBpbmRleCBvZiB0aGUgdmFyaWFibGUgdGhhdCBpcyB0byBiZQotICAgICAqIHN0b3JlZAotICAgICAqIEBwYXJhbSB0eXBlIHRoZSB7QGxpbmsgVHlwZX0gb2YgdGhlIHZhcmlhYmxlCi0gICAgICogQHJldHVybiB0aGUgZ2VuZXJhdGVkIHtAbGluayBTdG9yZWRJbnN0cnVjdGlvbn0KLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBJbnN0cnVjdGlvbiBzdG9yZUxvY2FsKGludCBpbmRleCwgVHlwZSB0eXBlKSB7Ci0gICAgICAgIGlmICh0eXBlID09IFR5cGUuQk9PTEVBTikgewotICAgICAgICAgICByZXR1cm4gbmV3IElTVE9SRShpbmRleCk7Ci0gICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PSBUeXBlLklOVCkgewotICAgICAgICAgICByZXR1cm4gbmV3IElTVE9SRShpbmRleCk7Ci0gICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PSBUeXBlLlNIT1JUKSB7Ci0gICAgICAgICAgIHJldHVybiBuZXcgSVNUT1JFKGluZGV4KTsKLSAgICAgICAgfSBlbHNlIGlmICh0eXBlID09IFR5cGUuTE9ORykgewotICAgICAgICAgICByZXR1cm4gbmV3IExTVE9SRShpbmRleCk7Ci0gICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PSBUeXBlLkJZVEUpIHsKLSAgICAgICAgICAgcmV0dXJuIG5ldyBJU1RPUkUoaW5kZXgpOwotICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT0gVHlwZS5DSEFSKSB7Ci0gICAgICAgICAgIHJldHVybiBuZXcgSVNUT1JFKGluZGV4KTsKLSAgICAgICAgfSBlbHNlIGlmICh0eXBlID09IFR5cGUuRkxPQVQpIHsKLSAgICAgICAgICAgcmV0dXJuIG5ldyBGU1RPUkUoaW5kZXgpOwotICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT0gVHlwZS5ET1VCTEUpIHsKLSAgICAgICAgICAgcmV0dXJuIG5ldyBEU1RPUkUoaW5kZXgpOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICByZXR1cm4gbmV3IEFTVE9SRShpbmRleCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFjayB0aGUgbnVtYmVyIG9mIG91dGxpbmVhYmxlIGNodW5rcyBzZWVuLgotICAgICAqLwotICAgIHByaXZhdGUgaW50IG1fdG90YWxDaHVua3MgPSAwOwotCi0gICAgLyoqCi0gICAgICogVHJhY2sgdGhlIG51bWJlciBvZiBvdXRsaW5lYWJsZSBjaHVua3Mgc3RhcnRlZCBidXQgbm90IHlldCBlbmRlZC4gIFVzZWQKLSAgICAgKiB0byBkZXRlY3QgaW1iYWxhbmNlcyBpbiBieXRlIGNvZGUgZ2VuZXJhdGlvbi4KLSAgICAgKi8KLSAgICBwcml2YXRlIGludCBtX29wZW5DaHVua3MgPSAwOwotCi0gICAgLyoqCi0gICAgICogTWFyayB0aGUgZW5kIG9mIHRoZSBtZXRob2QncwotICAgICAqIHtAbGluayBJbnN0cnVjdGlvbkxpc3R9IGFzIHRoZSBzdGFydCBvZiBhbiBvdXRsaW5lYWJsZSBjaHVuayBvZiBjb2RlLgotICAgICAqIFRoZSBvdXRsaW5lYWJsZSBjaHVuayBiZWdpbnMgYWZ0ZXIgdGhlIHtAbGluayBJbnN0cnVjdGlvbkhhbmRsZX0gdGhhdCBpcwotICAgICAqIGF0IHRoZSBlbmQgb2YgdGhlIG1ldGhvZCdzIHtAbGluayBJbnN0cnVjdGlvbkxpc3R9LCBvciBhdCB0aGUgc3RhcnQgb2YKLSAgICAgKiB0aGUgbWV0aG9kIGlmIHRoZSA8Y29kZT5JbnN0cnVjdGlvbkxpc3Q8L2NvZGU+IGlzIGVtcHR5LgotICAgICAqIFNlZSB7QGxpbmsgT3V0bGluZWFibGVDaHVua1N0YXJ0fSBmb3IgbW9yZSBpbmZvcm1hdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBtYXJrQ2h1bmtTdGFydCgpIHsKLSAgICAgICAgLy8gbV9jaHVua1RyZWUubWFya0NodW5rU3RhcnQoKTsKLSAgICAgICAgZ2V0SW5zdHJ1Y3Rpb25MaXN0KCkKLSAgICAgICAgICAgICAgICAuYXBwZW5kKE91dGxpbmVhYmxlQ2h1bmtTdGFydC5PVVRMSU5FQUJMRUNIVU5LU1RBUlQpOwotICAgICAgICBtX3RvdGFsQ2h1bmtzKys7Ci0gICAgICAgIG1fb3BlbkNodW5rcysrOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIE1hcmsgdGhlIGVuZCBvZiBhbiBvdXRsaW5lYWJsZSBjaHVuayBvZiBjb2RlLiAgU2VlCi0gICAgICoge0BsaW5rIE91dGxpbmVhYmxlQ2h1bmtTdGFydH0gZm9yIG1vcmUgaW5mb3JtYXRpb24uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgbWFya0NodW5rRW5kKCkgewotICAgICAgICAvLyBtX2NodW5rVHJlZS5tYXJrQ2h1bmtFbmQoKTsKLSAgICAgICAgZ2V0SW5zdHJ1Y3Rpb25MaXN0KCkKLSAgICAgICAgICAgICAgICAuYXBwZW5kKE91dGxpbmVhYmxlQ2h1bmtFbmQuT1VUTElORUFCTEVDSFVOS0VORCk7Ci0gICAgICAgIG1fb3BlbkNodW5rcy0tOwotICAgICAgICBpZiAobV9vcGVuQ2h1bmtzIDwgMCkgewotICAgICAgICAgICAgU3RyaW5nIG1zZyA9IChuZXcgRXJyb3JNc2coRXJyb3JNc2cuT1VUTElORV9FUlJfVU5CQUxBTkNFRF9NQVJLRVJTKSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC50b1N0cmluZygpOwotICAgICAgICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IobXNnKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPkdldCBhbGwge0BsaW5rIE1ldGhvZH1zIGdlbmVyYXRlZCBieSB0aGlzIHtAbGluayBNZXRob2RHZW5lcmF0b3J9LgotICAgICAqIFRoZSB7QGxpbmsgTWV0aG9kR2VuI2dldE1ldGhvZCgpfSBvbmx5IHJldHVybnMgYSBzaW5nbGUKLSAgICAgKiA8Y29kZT5NZXRob2Q8L2NvZGU+IG9iamVjdC4gIFRoaXMgbWV0aG9kIHRha2VzIGludG8gYWNjb3VudCB0aGUgSmF2YQotICAgICAqIFZpcnR1YWwgTWFjaGluZSBTcGVjaWZpY2F0aW9uIGxpbWl0IG9mIDY0S0Igb24gdGhlIHNpemUgb2YgYSBtZXRob2QsIGFuZAotICAgICAqIG1heSByZXR1cm4gbW9yZSB0aGFuIG9uZSA8Y29kZT5NZXRob2Q8L2NvZGU+LjwvcD4KLSAgICAgKiA8cD5JZiB0aGUgY29kZSBhc3NvY2lhdGVkIHdpdGggdGhlIDxjb2RlPk1ldGhvZEdlbmVyYXRvcjwvY29kZT4gd291bGQKLSAgICAgKiBleGNlZWQgdGhlIDY0S0IgbGltaXQsIHRoaXMgbWV0aG9kIHdpbGwgYXR0ZW1wdCB0byBzcGxpdCB0aGUgY29kZSBpbgotICAgICAqIHRoZSB7QGxpbmsgSW5zdHJ1Y3Rpb25MaXN0fSBhc3NvY2lhdGVkIHdpdGggdGhpcwotICAgICAqIDxjb2RlPk1ldGhvZEdlbmVyYXRvcjwvY29kZT4gaW50byBzZXZlcmFsIG1ldGhvZHMuPC9wPgotICAgICAqIEBwYXJhbSBjbGFzc0dlbiB0aGUge0BsaW5rIENsYXNzR2VuZXJhdG9yfSBvZiB3aGljaCB0aGVzZSBtZXRob2RzIGFyZQotICAgICAqICAgICAgICAgICAgICAgICBtZW1iZXJzCi0gICAgICogQHJldHVybiBhbiBhcnJheSBvZiBhbGwgdGhlIDxjb2RlPk1ldGhvZDwvY29kZT5zIGdlbmVyYXRlZAotICAgICAqLwotICAgIE1ldGhvZFtdIGdldEdlbmVyYXRlZE1ldGhvZHMoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4pIHsKLSAgICAgICAgTWV0aG9kW10gZ2VuZXJhdGVkTWV0aG9kczsKLSAgICAgICAgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0gICAgICAgIEluc3RydWN0aW9uSGFuZGxlIGxhc3QgPSBpbC5nZXRFbmQoKTsKLQotICAgICAgICBpbC5zZXRQb3NpdGlvbnMoKTsKLQotICAgICAgICBpbnQgaW5zdHJ1Y3Rpb25MaXN0U2l6ZSA9Ci0gICAgICAgICAgICAgICAgICAgIGxhc3QuZ2V0UG9zaXRpb24oKSArIGxhc3QuZ2V0SW5zdHJ1Y3Rpb24oKS5nZXRMZW5ndGgoKTsKLQotICAgICAgICAvLyBOZWVkIHRvIGxvb2sgZm9yIGFueSBicmFuY2ggdGFyZ2V0IG9mZnNldHMgdGhhdCBleGNlZWQgdGhlIHJhbmdlCi0gICAgICAgIC8vIFstMzI3NjgsMzI3NjddCi0gICAgICAgIGlmIChpbnN0cnVjdGlvbkxpc3RTaXplID4gTUFYX0JSQU5DSF9UQVJHRVRfT0ZGU0VUKSB7Ci0gICAgICAgICAgICBib29sZWFuIGlsQ2hhbmdlZCA9IHdpZGVuQ29uZGl0aW9uYWxCcmFuY2hUYXJnZXRPZmZzZXRzKCk7Ci0KLSAgICAgICAgICAgIC8vIElmIGFueSBicmFuY2ggaW5zdHJ1Y3Rpb25zIG5lZWRlZCB3aWRlbmluZywgcmVjb21wdXRlIHRoZSBzaXplCi0gICAgICAgICAgICAvLyBvZiB0aGUgYnl0ZSBjb2RlIGZvciB0aGUgbWV0aG9kCi0gICAgICAgICAgICBpZiAoaWxDaGFuZ2VkKSB7Ci0gICAgICAgICAgICAgICAgaWwuc2V0UG9zaXRpb25zKCk7Ci0gICAgICAgICAgICAgICAgbGFzdCA9IGlsLmdldEVuZCgpOwotICAgICAgICAgICAgICAgIGluc3RydWN0aW9uTGlzdFNpemUgPQotICAgICAgICAgICAgICAgICAgICAgICAgbGFzdC5nZXRQb3NpdGlvbigpICsgbGFzdC5nZXRJbnN0cnVjdGlvbigpLmdldExlbmd0aCgpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKGluc3RydWN0aW9uTGlzdFNpemUgPiBNQVhfTUVUSE9EX1NJWkUpIHsKLSAgICAgICAgICAgIGdlbmVyYXRlZE1ldGhvZHMgPSBvdXRsaW5lQ2h1bmtzKGNsYXNzR2VuLCBpbnN0cnVjdGlvbkxpc3RTaXplKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIGdlbmVyYXRlZE1ldGhvZHMgPSBuZXcgTWV0aG9kW10ge2dldFRoaXNNZXRob2QoKX07Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGdlbmVyYXRlZE1ldGhvZHM7Ci0gICAgfQotCi0gICAgcHJvdGVjdGVkIE1ldGhvZCBnZXRUaGlzTWV0aG9kKCkgewotICAgICAgICBzdHJpcEF0dHJpYnV0ZXModHJ1ZSk7Ci0gICAgICAgIHNldE1heExvY2FscygpOwotICAgICAgICBzZXRNYXhTdGFjaygpOwotICAgICAgICByZW1vdmVOT1BzKCk7Ci0KLSAgICAgICAgcmV0dXJuIGdldE1ldGhvZCgpOwotICAgIH0KLSAgICAvKioKLSAgICAgKiA8cD5SZXdyaXRlcyBicmFuY2hlcyB0byBhdm9pZCB0aGUgSlZNIGxpbWl0cyBvZiByZWxhdGl2ZSBicmFuY2gKLSAgICAgKiBvZmZzZXRzLiAgVGhlcmUgaXMgbm8gbmVlZCB0byBpbnZva2UgdGhpcyBtZXRob2QgaWYgdGhlIGJ5dGVjb2RlIGZvciB0aGUKLSAgICAgKiB7QGxpbmsgTWV0aG9kR2VuZXJhdG9yfSBkb2VzIG5vdCBleGNlZWQgMzJLQi48L3A+Ci0gICAgICogPHA+VGhlIEphdmEgVmlydHVhbCBNYWNoaW5lIFNwZWNpZmljYXRpb24gcGVybWl0cyB0aGUgY29kZSBwb3J0aW9uIG9mIGEKLSAgICAgKiBtZXRob2QgdG8gYmUgdXAgdG8gNjRLQiBpbiBsZW5ndGguICBIb3dldmVyLCBzb21lIGNvbnRyb2wgdHJhbnNmZXIKLSAgICAgKiBpbnN0cnVjdGlvbnMgc3BlY2lmeSByZWxhdGl2ZSBvZmZzZXRzIGFzIGEgc2lnbmVkIDE2LWJpdCBxdWFudGl0eSwKLSAgICAgKiBsaW1pdGluZyB0aGUgcmFuZ2UgdG8gYSBzdWJzZXQgb2YgdGhlIGluc3RydWN0aW9ucyB0aGF0IG1pZ2h0IGJlIGluIGEKLSAgICAgKiBtZXRob2QuPC9wPgotICAgICAqIDxwPlRoZSA8Y29kZT5UQUJMRVNXSVRDSDwvY29kZT4gYW5kIDxjb2RlPkxPT0tVUFNXSVRDSDwvY29kZT4KLSAgICAgKiBpbnN0cnVjdGlvbnMgYWx3YXlzIHVzZSAzMi1iaXQgc2lnbmVkIHJlbGF0aXZlIG9mZnNldHMsIHNvIHRoZXkgYXJlCi0gICAgICogaW1tdW5lIHRvIHRoaXMgcHJvYmxlbS48L3A+Ci0gICAgICogPHA+VGhlIDxjb2RlPkdPVE88L2NvZGU+IGFuZCA8Y29kZT5KU1I8L2NvZGU+Ci0gICAgICogaW5zdHJ1Y3Rpb25zIGNvbWUgaW4gdHdvIGZvcm1zLCBvbmUgb2Ygd2hpY2ggdXNlcyAxNi1iaXQgcmVsYXRpdmUKLSAgICAgKiBvZmZzZXRzLCBhbmQgdGhlIG90aGVyIG9mIHdoaWNoIHVzZXMgMzItYml0IHJlbGF0aXZlIG9mZnNldHMuICBUaGUgQkNFTAotICAgICAqIGxpYnJhcnkgZGVjaWRlcyB3aGV0aGVyIHRvIHVzZSB0aGUgd2lkZSBmb3JtIG9mIDxjb2RlPkdPVE88L2NvZGU+IG9yCi0gICAgICogPGNvZGU+SlNSPC9jb2RlPmluc3RydWN0aW9ucyBiYXNlZCBvbiB0aGUgcmVsYXRpdmUgb2Zmc2V0IG9mIHRoZSB0YXJnZXQKLSAgICAgKiBvZiB0aGUgaW5zdHJ1Y3Rpb24gd2l0aG91dCBhbnkgaW50ZXJ2ZW50aW9uIGJ5IHRoZSB1c2VyIG9mIHRoZQotICAgICAqIGxpYnJhcnkuPC9wPgotICAgICAqIDxwPlRoaXMgbGVhdmVzIHRoZSB2YXJpb3VzIGNvbmRpdGlvbmFsIGJyYW5jaCBpbnN0cnVjdGlvbnMsCi0gICAgICogPGNvZGU+SUZFUTwvY29kZT4sIDxjb2RlPklGTlVMTDwvY29kZT4sIDxjb2RlPklGX0lDTVBFUTwvY29kZT4sCi0gICAgICogPGVtPmV0IGFsLjwvZW0+LCBhbGwgb2Ygd2hpY2ggdXNlIDE2LWJpdCBzaWduZWQgcmVsYXRpdmUgb2Zmc2V0cywgd2l0aCBubwotICAgICAqIDMyLWJpdCB3aWRlIGZvcm0gYXZhaWxhYmxlLjwvcD4KLSAgICAgKiA8cD5UaGlzIG1ldGhvZCBzY2FucyB0aGUge0BsaW5rIEluc3RydWN0aW9uTGlzdH0gYXNzb2NpYXRlZCB3aXRoIHRoaXMKLSAgICAgKiB7QGxpbmsgTWV0aG9kR2VuZXJhdG9yfSBhbmQgZmluZHMgYWxsIGNvbmRpdGlvbmFsIGJyYW5jaCBpbnN0cnVjdGlvbnMKLSAgICAgKiB0aGF0IG1pZ2h0IGV4Y2VlZCB0aGUgMTYtYml0IGxpbWl0YXRpb24gZm9yIHJlbGF0aXZlIGJyYW5jaCBvZmZzZXRzLgotICAgICAqIFRoZSBsb2dpYyBvZiBlYWNoIHN1Y2ggaW5zdHJ1Y3Rpb24gaXMgaW52ZXJ0ZWQsIGFuZCBtYWRlIHRvIHRhcmdldCB0aGUKLSAgICAgKiBpbnN0cnVjdGlvbiB3aGljaCBmb2xsb3dzIGl0LiAgQW4gdW5jb25kaXRpb25hbCBicmFuY2ggdG8gdGhlIG9yaWdpbmFsCi0gICAgICogdGFyZ2V0IG9mIHRoZSBpbnN0cnVjdGlvbiBpcyB0aGVuIGluc2VydGVkIGJldHdlZW4gdGhlIGNvbmRpdGlvbmFsCi0gICAgICogYnJhbmNoIGFuZCB0aGUgaW5zdHJ1Y3Rpb24gd2hpY2ggcHJldmlvdXNseSBmb2xsb3dlZCBpdC4gIFRoZQotICAgICAqIHVuY29uZGl0aW9uYWwgYnJhbmNoIGlzIHBlcm1pdHRlZCB0byBoYXZlIGEgMTYtYml0IG9yIGEgMzItYml0IHJlbGF0aXZlCi0gICAgICogb2Zmc2V0LCBhcyBkZXNjcmliZWQgYWJvdmUuICBGb3IgZXhhbXBsZSwKLSAgICAgKiA8Y29kZT4KLSAgICAgKiAxMjM0OiAgIE5PUAotICAgICAqICAgICAgICAgIC4uLgotICAgICAqIDU1Mjc4OiAgSUZFUSAtNTQwNDQKLSAgICAgKiA1NTI4MDogIE5PUAotICAgICAqIDwvY29kZT4KLSAgICAgKiBpcyByZXdyaXR0ZW4gYXMKLSAgICAgKiA8Y29kZT4KLSAgICAgKiAxMjM0OiAgIE5PUAotICAgICAqICAgICAgICAgIC4uLgotICAgICAqIDU1Mjc4OiAgSUZORSA3Ci0gICAgICogNTUyODA6ICBHT1RPX1cgLTU0MDQ2Ci0gICAgICogNTUyODU6ICBOT1AKLSAgICAgKiA8L2NvZGU+PC9wPgotICAgICAqIDxwPjxiPlByZWNvbmRpdGlvbnM6PC9iPgotICAgICAqIDx1bD48bGk+VGhlIHtAbGluayBJbnN0cnVjdGlvbkxpc3Qjc2V0UG9zaXRpb25zKCl9IGhhcyBiZWVuIGNhbGxlZCBmb3IKLSAgICAgKiB0aGUgPGNvZGU+SW5zdHJ1Y3Rpb25MaXN0PC9jb2RlPiBhc3NvY2lhdGVkIHdpdGggdGhpcwotICAgICAqIDxjb2RlPk1ldGhvZEdlbmVyYXRvcjwvY29kZT4uCi0gICAgICogPC9saT48L3VsPjwvcD4KLSAgICAgKiA8cD48Yj5Qb3N0Y29uZGl0aW9uczo8L2I+Ci0gICAgICogPHVsPjxsaT5BbnkgZnVydGhlciBjaGFuZ2VzIHRvIHRoZSA8Y29kZT5JbnN0cnVjdGlvbkxpc3Q8L2NvZGU+IGZvciB0aGlzCi0gICAgICogPGNvZGU+TWV0aG9kR2VuZXJhdG9yPC9jb2RlPiB3aWxsIGludmFsaWRhdGUgdGhlIGNoYW5nZXMgbWFkZSBieSB0aGlzCi0gICAgICogbWV0aG9kLjwvbGk+PC91bD4KLSAgICAgKiA8L3A+Ci0gICAgICogQHJldHVybiA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgPGNvZGU+SW5zdHJ1Y3Rpb25MaXN0PC9jb2RlPiB3YXMKLSAgICAgKiBtb2RpZmllZDsgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZQotICAgICAqIEBzZWUgVGhlIEphdmEgVmlydHVhbCBNYWNoaW5lIFNwZWNpZmljYXRpb24sIFNlY29uZCBFZGl0aW9uCi0gICAgICovCi0gICAgYm9vbGVhbiB3aWRlbkNvbmRpdGlvbmFsQnJhbmNoVGFyZ2V0T2Zmc2V0cygpIHsKLSAgICAgICAgYm9vbGVhbiBpbENoYW5nZWQgPSBmYWxzZTsKLSAgICAgICAgaW50IG1heE9mZnNldENoYW5nZSA9IDA7Ci0gICAgICAgIEluc3RydWN0aW9uTGlzdCBpbCA9IGdldEluc3RydWN0aW9uTGlzdCgpOwotCi0gICAgICAgIC8vIExvb3AgdGhyb3VnaCBhbGwgdGhlIGluc3RydWN0aW9ucywgZmluZGluZyB0aG9zZSB0aGF0IHdvdWxkIGJlCi0gICAgICAgIC8vIGFmZmVjdGVkIGJ5IGluc2VydGluZyBuZXcgaW5zdHJ1Y3Rpb25zIGluIHRoZSBJbnN0cnVjdGlvbkxpc3QsIGFuZAotICAgICAgICAvLyBjYWxjdWxhdGluZyB0aGUgbWF4aW11bSBhbW91bnQgYnkgd2hpY2ggdGhlIHJlbGF0aXZlIG9mZnNldCBiZXR3ZWVuCi0gICAgICAgIC8vIHR3byBpbnN0cnVjdGlvbnMgY291bGQgcG9zc2libHkgY2hhbmdlLgotICAgICAgICAvLyBJbiBwYXJ0IHRoaXMgbG9vcCBkdXBsaWNhdGVzIGNvZGUgaW4KLSAgICAgICAgLy8gb3JnLmFwYWNoZS5iY2VsLmdlbmVyaWMuSW5zdHJ1Y3Rpb25MaXN0LnNldFBvc2l0aW9uKCksIHdoaWNoIGRvZXMKLSAgICAgICAgLy8gdGhpcyB0byBkZXRlcm1pbmUgd2hldGhlciB0byB1c2UgMTYtYml0IG9yIDMyLWJpdCBvZmZzZXRzIGZvciBHT1RPCi0gICAgICAgIC8vIGFuZCBKU1IgaW5zdHJ1Y3Rpb25zLiAgSWRlYWxseSwgdGhhdCBtZXRob2Qgd291bGQgZG8gdGhlIHNhbWUgZm9yCi0gICAgICAgIC8vIGNvbmRpdGlvbmFsIGJyYW5jaCBpbnN0cnVjdGlvbnMsIGJ1dCBpdCBkb2Vzbid0LCBzbyB3ZSBkdXBsaWNhdGUgdGhlCi0gICAgICAgIC8vIHByb2Nlc3NpbmcgaGVyZS4KLSAgICAgICAgZm9yIChJbnN0cnVjdGlvbkhhbmRsZSBpaCA9IGlsLmdldFN0YXJ0KCk7Ci0gICAgICAgICAgICAgaWggIT0gbnVsbDsKLSAgICAgICAgICAgICBpaCA9IGloLmdldE5leHQoKSkgewotICAgICAgICAgICAgSW5zdHJ1Y3Rpb24gaW5zdCA9IGloLmdldEluc3RydWN0aW9uKCk7Ci0KLSAgICAgICAgICAgIHN3aXRjaCAoaW5zdC5nZXRPcGNvZGUoKSkgewotICAgICAgICAgICAgICAgIC8vIEluc3RydWN0aW9ucyB0aGF0IG1heSBoYXZlIDE2LWJpdCBvciAzMi1iaXQgYnJhbmNoIHRhcmdldHMuCi0gICAgICAgICAgICAgICAgLy8gVGhlIHNpemUgb2YgdGhlIGJyYW5jaCBvZmZzZXQgbWlnaHQgaW5jcmVhc2UgYnkgdHdvIGJ5dGVzLgotICAgICAgICAgICAgICAgIGNhc2UgQ29uc3RhbnRzLkdPVE86Ci0gICAgICAgICAgICAgICAgY2FzZSBDb25zdGFudHMuSlNSOgotICAgICAgICAgICAgICAgICAgICBtYXhPZmZzZXRDaGFuZ2UgPSBtYXhPZmZzZXRDaGFuZ2UgKyAyOwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAvLyBJbnN0cnVjdGlvbnMgdGhhdCBjb250YWluIHBhZGRpbmcgZm9yIGFsaWdubWVudCBwdXJwb3NlcwotICAgICAgICAgICAgICAgIC8vIFVwIHRvIHRocmVlIGJ5dGVzIG9mIHBhZGRpbmcgbWlnaHQgYmUgbmVlZGVkLiAgRm9yIGdyZWF0ZXIKLSAgICAgICAgICAgICAgICAvLyBhY2N1cmFjeSwgd2Ugc2hvdWxkIGJlIGFibGUgdG8gZGlzY291bnQgYW55IHBhZGRpbmcgYWxyZWFkeQotICAgICAgICAgICAgICAgIC8vIGFkZGVkIHRvIHRoZXNlIGluc3RydWN0aW9ucyBieSBJbnN0cnVjdGlvbkxpc3Quc2V0UG9zaXRpb24oKSwKLSAgICAgICAgICAgICAgICAvLyB0aGVpciBBUElzIGRvIG5vdCBleHBvc2UgdGhhdCBpbmZvcm1hdGlvbi4KLSAgICAgICAgICAgICAgICBjYXNlIENvbnN0YW50cy5UQUJMRVNXSVRDSDoKLSAgICAgICAgICAgICAgICBjYXNlIENvbnN0YW50cy5MT09LVVBTV0lUQ0g6Ci0gICAgICAgICAgICAgICAgICAgIG1heE9mZnNldENoYW5nZSA9IG1heE9mZnNldENoYW5nZSArIDM7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIC8vIEluc3RydWN0aW9ucyB0aGF0IG1pZ2h0IGJlIHJld3JpdHRlbiBieSB0aGlzIG1ldGhvZCBhcyBhCi0gICAgICAgICAgICAgICAgLy8gY29uZGl0aW9uYWwgYnJhbmNoIGZvbGxvd2VkIGJ5IGFuIHVuY29uZGl0aW9uYWwgYnJhbmNoLgotICAgICAgICAgICAgICAgIC8vIFRoZSB1bmNvbmRpdGlvbmFsIGJyYW5jaCB3b3VsZCByZXF1aXJlIGZpdmUgYnl0ZXMuCi0gICAgICAgICAgICAgICAgY2FzZSBDb25zdGFudHMuSUZfQUNNUEVROgotICAgICAgICAgICAgICAgIGNhc2UgQ29uc3RhbnRzLklGX0FDTVBORToKLSAgICAgICAgICAgICAgICBjYXNlIENvbnN0YW50cy5JRl9JQ01QRVE6Ci0gICAgICAgICAgICAgICAgY2FzZSBDb25zdGFudHMuSUZfSUNNUEdFOgotICAgICAgICAgICAgICAgIGNhc2UgQ29uc3RhbnRzLklGX0lDTVBHVDoKLSAgICAgICAgICAgICAgICBjYXNlIENvbnN0YW50cy5JRl9JQ01QTEU6Ci0gICAgICAgICAgICAgICAgY2FzZSBDb25zdGFudHMuSUZfSUNNUExUOgotICAgICAgICAgICAgICAgIGNhc2UgQ29uc3RhbnRzLklGX0lDTVBORToKLSAgICAgICAgICAgICAgICBjYXNlIENvbnN0YW50cy5JRkVROgotICAgICAgICAgICAgICAgIGNhc2UgQ29uc3RhbnRzLklGR0U6Ci0gICAgICAgICAgICAgICAgY2FzZSBDb25zdGFudHMuSUZHVDoKLSAgICAgICAgICAgICAgICBjYXNlIENvbnN0YW50cy5JRkxFOgotICAgICAgICAgICAgICAgIGNhc2UgQ29uc3RhbnRzLklGTFQ6Ci0gICAgICAgICAgICAgICAgY2FzZSBDb25zdGFudHMuSUZORToKLSAgICAgICAgICAgICAgICBjYXNlIENvbnN0YW50cy5JRk5PTk5VTEw6Ci0gICAgICAgICAgICAgICAgY2FzZSBDb25zdGFudHMuSUZOVUxMOgotICAgICAgICAgICAgICAgICAgICBtYXhPZmZzZXRDaGFuZ2UgPSBtYXhPZmZzZXRDaGFuZ2UgKyA1OwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIE5vdyB0aGF0IHRoZSBtYXhpbXVtIG51bWJlciBvZiBieXRlcyBieSB3aGljaCB0aGUgbWV0aG9kIG1pZ2h0IGdyb3cKLSAgICAgICAgLy8gaGFzIGJlZW4gZGV0ZXJtaW5lZCwgbG9vayBmb3IgY29uZGl0aW9uYWwgYnJhbmNoZXMgdG8gc2VlIHdoaWNoCi0gICAgICAgIC8vIG1pZ2h0IHBvc3NpYmx5IGV4Y2VlZCB0aGUgMTYtYml0IHJlbGF0aXZlIG9mZnNldC4KLSAgICAgICAgZm9yIChJbnN0cnVjdGlvbkhhbmRsZSBpaCA9IGlsLmdldFN0YXJ0KCk7Ci0gICAgICAgICAgICAgaWggIT0gbnVsbDsKLSAgICAgICAgICAgICBpaCA9IGloLmdldE5leHQoKSkgewotICAgICAgICAgICAgSW5zdHJ1Y3Rpb24gaW5zdCA9IGloLmdldEluc3RydWN0aW9uKCk7Ci0KLSAgICAgICAgICAgIGlmIChpbnN0IGluc3RhbmNlb2YgSWZJbnN0cnVjdGlvbikgewotICAgICAgICAgICAgICAgIElmSW5zdHJ1Y3Rpb24gb2xkSWZJbnN0ID0gKElmSW5zdHJ1Y3Rpb24paW5zdDsKLSAgICAgICAgICAgICAgICBCcmFuY2hIYW5kbGUgb2xkSWZIYW5kbGUgPSAoQnJhbmNoSGFuZGxlKWloOwotICAgICAgICAgICAgICAgIEluc3RydWN0aW9uSGFuZGxlIHRhcmdldCA9IG9sZElmSW5zdC5nZXRUYXJnZXQoKTsKLSAgICAgICAgICAgICAgICBpbnQgcmVsYXRpdmVUYXJnZXRPZmZzZXQgPSB0YXJnZXQuZ2V0UG9zaXRpb24oKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtIG9sZElmSGFuZGxlLmdldFBvc2l0aW9uKCk7Ci0KLSAgICAgICAgICAgICAgICAvLyBDb25zaWRlciB0aGUgd29yc3QgY2FzZSBzY2VuYXJpbyBpbiB3aGljaCB0aGUgY29uZGl0aW9uYWwKLSAgICAgICAgICAgICAgICAvLyBicmFuY2ggYW5kIGl0cyB0YXJnZXQgYXJlIHNlcGFyYXRlZCBieSBhbGwgdGhlIGluc3RydWN0aW9ucwotICAgICAgICAgICAgICAgIC8vIGluIHRoZSBtZXRob2QgdGhhdCBtaWdodCBpbmNyZWFzZSBpbiBzaXplLiAgSWYgdGhhdCByZXN1bHRzCi0gICAgICAgICAgICAgICAgLy8gaW4gYSByZWxhdGl2ZSBvZmZzZXQgdGhhdCBjYW5ub3QgYmUgcmVwcmVzZW50ZWQgYXMgYSAzMi1iaXQKLSAgICAgICAgICAgICAgICAvLyBzaWduZWQgcXVhbnRpdHksIHJld3JpdGUgdGhlIGluc3RydWN0aW9uIGFzIGRlc2NyaWJlZCBhYm92ZS4KLSAgICAgICAgICAgICAgICBpZiAoKHJlbGF0aXZlVGFyZ2V0T2Zmc2V0IC0gbWF4T2Zmc2V0Q2hhbmdlCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwgTUlOX0JSQU5DSF9UQVJHRVRfT0ZGU0VUKQotICAgICAgICAgICAgICAgICAgICAgICAgfHwgKHJlbGF0aXZlVGFyZ2V0T2Zmc2V0ICsgbWF4T2Zmc2V0Q2hhbmdlCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+IE1BWF9CUkFOQ0hfVEFSR0VUX09GRlNFVCkpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gSW52ZXJ0IHRoZSBsb2dpYyBvZiB0aGUgSUYgaW5zdHJ1Y3Rpb24sIGFuZCBhcHBlbmQKLSAgICAgICAgICAgICAgICAgICAgLy8gdGhhdCB0byB0aGUgSW5zdHJ1Y3Rpb25MaXN0IGZvbGxvd2luZyB0aGUgb3JpZ2luYWwgSUYKLSAgICAgICAgICAgICAgICAgICAgLy8gaW5zdHJ1Y3Rpb24KLSAgICAgICAgICAgICAgICAgICAgSW5zdHJ1Y3Rpb25IYW5kbGUgbmV4dEhhbmRsZSA9IG9sZElmSGFuZGxlLmdldE5leHQoKTsKLSAgICAgICAgICAgICAgICAgICAgSWZJbnN0cnVjdGlvbiBpbnZlcnRlZElmSW5zdCA9IG9sZElmSW5zdC5uZWdhdGUoKTsKLSAgICAgICAgICAgICAgICAgICAgQnJhbmNoSGFuZGxlIGludmVydGVkSWZIYW5kbGUgPSBpbC5hcHBlbmQob2xkSWZIYW5kbGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludmVydGVkSWZJbnN0KTsKLQotICAgICAgICAgICAgICAgICAgICAvLyBBcHBlbmQgYW4gdW5jb25kaXRpb25hbCBicmFuY2ggdG8gdGhlIHRhcmdldCBvZiB0aGUKLSAgICAgICAgICAgICAgICAgICAgLy8gb3JpZ2luYWwgSUYgaW5zdHJ1Y3Rpb24gYWZ0ZXIgdGhlIG5ldyBJRiBpbnN0cnVjdGlvbgotICAgICAgICAgICAgICAgICAgICBCcmFuY2hIYW5kbGUgZ290b0hhbmRsZSA9IGlsLmFwcGVuZChpbnZlcnRlZElmSGFuZGxlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgR09UTyh0YXJnZXQpKTsKLQotICAgICAgICAgICAgICAgICAgICAvLyBJZiB0aGUgb3JpZ2luYWwgSUYgd2FzIHRoZSBsYXN0IGluc3RydWN0aW9uIGluCi0gICAgICAgICAgICAgICAgICAgIC8vIEluc3RydWN0aW9uTGlzdCwgYWRkIGEgbmV3IG5vLW9wIHRvIGFjdCBhcyB0aGUgdGFyZ2V0Ci0gICAgICAgICAgICAgICAgICAgIC8vIG9mIHRoZSBuZXcgSUYKLSAgICAgICAgICAgICAgICAgICAgaWYgKG5leHRIYW5kbGUgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgbmV4dEhhbmRsZSA9IGlsLmFwcGVuZChnb3RvSGFuZGxlLCBOT1ApOwotICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgLy8gTWFrZSB0aGUgbmV3IElGIGluc3RydWN0aW9uIGJyYW5jaCBhcm91bmQgdGhlIEdPVE8KLSAgICAgICAgICAgICAgICAgICAgaW52ZXJ0ZWRJZkhhbmRsZS51cGRhdGVUYXJnZXQodGFyZ2V0LCBuZXh0SGFuZGxlKTsKLQotICAgICAgICAgICAgICAgICAgICAvLyBJZiBhbnl0aGluZyBzdGlsbCAicG9pbnRzIiB0byB0aGUgb2xkIElGIGluc3RydWN0aW9uLAotICAgICAgICAgICAgICAgICAgICAvLyBtYWtlIGFkanVzdG1lbnRzIHRvIHJlZmVyIHRvIGVpdGhlciB0aGUgbmV3IElGIG9yIEdPVE8KLSAgICAgICAgICAgICAgICAgICAgLy8gaW5zdHJ1Y3Rpb24KLSAgICAgICAgICAgICAgICAgICAgaWYgKG9sZElmSGFuZGxlLmhhc1RhcmdldGVycygpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBJbnN0cnVjdGlvblRhcmdldGVyW10gdGFyZ2V0ZXJzID0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2xkSWZIYW5kbGUuZ2V0VGFyZ2V0ZXJzKCk7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdGFyZ2V0ZXJzLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgSW5zdHJ1Y3Rpb25UYXJnZXRlciB0YXJnZXRlciA9IHRhcmdldGVyc1tpXTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJZGVhbGx5LCBvbmUgc2hvdWxkIHNpbXBseSBiZSBhYmxlIHRvIHVzZQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEluc3RydWN0aW9uVGFyZ2V0ZXIudXBkYXRlVGFyZ2V0IHRvIGNoYW5nZQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHJlZmVyZW5jZXMgdG8gdGhlIG9sZCBJRiBpbnN0cnVjdGlvbiB0byB0aGUgbmV3Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSUYgaW5zdHJ1Y3Rpb24uICBIb3dldmVyLCBpZiBhIExvY2FsVmFyaWFibGVHZW4KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpbmRpY2F0ZWQgdGhlIG9sZCBJRiBtYXJrZWQgdGhlIGVuZCBvZiB0aGUgcmFuZ2UKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpbiB3aGljaCB0aGUgSUYgdmFyaWFibGUgaXMgaW4gdXNlLCB0aGUgbGl2ZQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHJhbmdlIG9mIHRoZSB2YXJpYWJsZSBtdXN0IGV4dGVuZCB0byBpbmNsdWRlIHRoZQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG5ld2x5IGNyZWF0ZWQgR09UTyBpbnN0cnVjdGlvbi4gIFRoZSBuZWVkIGZvcgotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoaXMgc29ydCBvZiBzcGVjaWZpYyBrbm93bGVkZ2Ugb2YgYW4KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpbXBsZW1lbnRvciBvZiB0aGUgSW5zdHJ1Y3Rpb25UYXJnZXRlciBpbnRlcmZhY2UKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBtYWtlcyB0aGUgY29kZSBtb3JlIGZyYWdpbGUuICBGdXR1cmUgaW1wbGVtZW50b3JzCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gb2YgdGhlIGludGVyZmFjZSBtaWdodCBoYXZlIHNpbWlsYXIgcmVxdWlyZW1lbnRzCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gd2hpY2ggd291bGRuJ3QgYmUgYWNjb21tb2RhdGVkIHNlZW1sZXNzbHkuCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRhcmdldGVyIGluc3RhbmNlb2YgTG9jYWxWYXJpYWJsZUdlbikgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMb2NhbFZhcmlhYmxlR2VuIGx2ZyA9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKExvY2FsVmFyaWFibGVHZW4pIHRhcmdldGVyOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobHZnLmdldFN0YXJ0KCkgPT0gb2xkSWZIYW5kbGUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGx2Zy5zZXRTdGFydChpbnZlcnRlZElmSGFuZGxlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChsdmcuZ2V0RW5kKCkgPT0gb2xkSWZIYW5kbGUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGx2Zy5zZXRFbmQoZ290b0hhbmRsZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXRlci51cGRhdGVUYXJnZXQob2xkSWZIYW5kbGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnZlcnRlZElmSGFuZGxlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICAgICAgaWwuZGVsZXRlKG9sZElmSGFuZGxlKTsKLSAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoVGFyZ2V0TG9zdEV4Y2VwdGlvbiB0bGUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoaXMgY2FuIG5ldmVyIGhhcHBlbiAtIHdlIHVwZGF0ZWQgdGhlIGxpc3Qgb2YKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGluc3RydWN0aW9ucyB0aGF0IHRhcmdldCB0aGUgZGVsZXRlZCBpbnN0cnVjdGlvbgotICAgICAgICAgICAgICAgICAgICAgICAgLy8gcHJpb3IgdG8gZGVsZXRpbmcgaXQuCi0gICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbXNnID0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgRXJyb3JNc2coRXJyb3JNc2cuT1VUTElORV9FUlJfREVMRVRFRF9UQVJHRVQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRsZS5nZXRNZXNzYWdlKCkpLnRvU3RyaW5nKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihtc2cpOwotICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgLy8gQWRqdXN0IHRoZSBwb2ludGVyIGluIHRoZSBJbnN0cnVjdGlvbkxpc3QgdG8gcG9pbnQgYWZ0ZXIKLSAgICAgICAgICAgICAgICAgICAgLy8gdGhlIG5ld2x5IGluc2VydGVkIElGIGluc3RydWN0aW9uCi0gICAgICAgICAgICAgICAgICAgIGloID0gZ290b0hhbmRsZTsKLQotICAgICAgICAgICAgICAgICAgICAvLyBJbmRpY2F0ZSB0aGF0IHRoaXMgbWV0aG9kIHJld3JvdGUgYXQgbGVhc3Qgb25lIElGCi0gICAgICAgICAgICAgICAgICAgIGlsQ2hhbmdlZCA9IHRydWU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gRGlkIHRoaXMgbWV0aG9kIHJld3JpdGUgYW55IElGIGluc3RydWN0aW9ucz8KLSAgICAgICAgcmV0dXJuIGlsQ2hhbmdlZDsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL3V0aWwvTWV0aG9kVHlwZS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci91dGlsL01ldGhvZFR5cGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOGNkMDMwOC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL3V0aWwvTWV0aG9kVHlwZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTczICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IE1ldGhvZFR5cGUuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8wNSAxMToxODowNSBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbDsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLS8qKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgTWV0aG9kVHlwZSBleHRlbmRzIFR5cGUgewotICAgIHByaXZhdGUgZmluYWwgVHlwZSBfcmVzdWx0VHlwZTsKLSAgICBwcml2YXRlIGZpbmFsIFZlY3RvciBfYXJnc1R5cGU7Ci0KLSAgICBwdWJsaWMgTWV0aG9kVHlwZShUeXBlIHJlc3VsdFR5cGUpIHsKLSAgICAgICAgX2FyZ3NUeXBlID0gbnVsbDsKLSAgICAgICAgX3Jlc3VsdFR5cGUgPSByZXN1bHRUeXBlOwotICAgIH0KLQotICAgIHB1YmxpYyBNZXRob2RUeXBlKFR5cGUgcmVzdWx0VHlwZSwgVHlwZSBhcmcxKSB7Ci0gICAgICAgIGlmIChhcmcxICE9IFR5cGUuVm9pZCkgewotICAgICAgICAgICAgX2FyZ3NUeXBlID0gbmV3IFZlY3RvcigpOwotICAgICAgICAgICAgX2FyZ3NUeXBlLmFkZEVsZW1lbnQoYXJnMSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBfYXJnc1R5cGUgPSBudWxsOwotICAgICAgICB9Ci0gICAgICAgIF9yZXN1bHRUeXBlID0gcmVzdWx0VHlwZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgTWV0aG9kVHlwZShUeXBlIHJlc3VsdFR5cGUsIFR5cGUgYXJnMSwgVHlwZSBhcmcyKSB7Ci0gICAgICAgIF9hcmdzVHlwZSA9IG5ldyBWZWN0b3IoMik7Ci0gICAgICAgIF9hcmdzVHlwZS5hZGRFbGVtZW50KGFyZzEpOwotICAgICAgICBfYXJnc1R5cGUuYWRkRWxlbWVudChhcmcyKTsKLSAgICAgICAgX3Jlc3VsdFR5cGUgPSByZXN1bHRUeXBlOwotICAgIH0KLQotICAgIHB1YmxpYyBNZXRob2RUeXBlKFR5cGUgcmVzdWx0VHlwZSwgVHlwZSBhcmcxLCBUeXBlIGFyZzIsIFR5cGUgYXJnMykgewotICAgICAgICBfYXJnc1R5cGUgPSBuZXcgVmVjdG9yKDMpOwotICAgICAgICBfYXJnc1R5cGUuYWRkRWxlbWVudChhcmcxKTsKLSAgICAgICAgX2FyZ3NUeXBlLmFkZEVsZW1lbnQoYXJnMik7Ci0gICAgICAgIF9hcmdzVHlwZS5hZGRFbGVtZW50KGFyZzMpOwotICAgICAgICBfcmVzdWx0VHlwZSA9IHJlc3VsdFR5cGU7Ci0gICAgfQotCi0gICAgcHVibGljIE1ldGhvZFR5cGUoVHlwZSByZXN1bHRUeXBlLCBWZWN0b3IgYXJnc1R5cGUpIHsKLSAgICAgICAgX3Jlc3VsdFR5cGUgPSByZXN1bHRUeXBlOwotICAgICAgICBfYXJnc1R5cGUgPSBhcmdzVHlwZS5zaXplKCkgPiAwID8gYXJnc1R5cGUgOiBudWxsOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0gICAgICAgIFN0cmluZ0J1ZmZlciByZXN1bHQgPSBuZXcgU3RyaW5nQnVmZmVyKCJtZXRob2R7Iik7Ci0gICAgICAgIGlmIChfYXJnc1R5cGUgIT0gbnVsbCkgewotICAgICAgICAgICAgZmluYWwgaW50IGNvdW50ID0gX2FyZ3NUeXBlLnNpemUoKTsKLSAgICAgICAgICAgIGZvciAoaW50IGk9MDsgaTxjb3VudDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChfYXJnc1R5cGUuZWxlbWVudEF0KGkpKTsKLSAgICAgICAgICAgICAgICBpZiAoaSAhPSAoY291bnQtMSkpIHJlc3VsdC5hcHBlbmQoJywnKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoInZvaWQiKTsKLSAgICAgICAgfQotICAgICAgICByZXN1bHQuYXBwZW5kKCd9Jyk7Ci0gICAgICAgIHJldHVybiByZXN1bHQudG9TdHJpbmcoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIHRvU2lnbmF0dXJlKCkgewotICAgICAgICByZXR1cm4gdG9TaWduYXR1cmUoIiIpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIHNpZ25hdHVyZSBvZiB0aGlzIG1ldGhvZCB0aGF0IHJlc3VsdHMgYnkgYWRkaW5nCi0gICAgICogPGNvZGU+bGFzdEFyZ1NpZzwvY29kZT4gdG8gdGhlIGVuZCBvZiB0aGUgYXJndW1lbnQgbGlzdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIHRvU2lnbmF0dXJlKFN0cmluZyBsYXN0QXJnU2lnKSB7Ci0gICAgICAgIGZpbmFsIFN0cmluZ0J1ZmZlciBidWZmZXIgPSBuZXcgU3RyaW5nQnVmZmVyKCk7Ci0gICAgICAgIGJ1ZmZlci5hcHBlbmQoJygnKTsKLSAgICAgICAgaWYgKF9hcmdzVHlwZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmaW5hbCBpbnQgbiA9IF9hcmdzVHlwZS5zaXplKCk7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykgewotICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoKChUeXBlKV9hcmdzVHlwZS5lbGVtZW50QXQoaSkpLnRvU2lnbmF0dXJlKCkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBidWZmZXIKLSAgICAgICAgICAgIC5hcHBlbmQobGFzdEFyZ1NpZykKLSAgICAgICAgICAgIC5hcHBlbmQoJyknKQotICAgICAgICAgICAgLmFwcGVuZChfcmVzdWx0VHlwZS50b1NpZ25hdHVyZSgpKQotICAgICAgICAgICAgLnRvU3RyaW5nKCk7Ci0gICAgfQotCi0gICAgcHVibGljIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuVHlwZSB0b0pDVHlwZSgpIHsKLSAgICAgICAgcmV0dXJuIG51bGw7ICAgIC8vIHNob3VsZCBuZXZlciBiZSBjYWxsZWQKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBpZGVudGljYWxUbyhUeXBlIG90aGVyKSB7Ci0gICAgICAgIGJvb2xlYW4gcmVzdWx0ID0gZmFsc2U7Ci0gICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIE1ldGhvZFR5cGUpIHsKLSAgICAgICAgICAgIGZpbmFsIE1ldGhvZFR5cGUgdGVtcCA9IChNZXRob2RUeXBlKSBvdGhlcjsKLSAgICAgICAgICAgIGlmIChfcmVzdWx0VHlwZS5pZGVudGljYWxUbyh0ZW1wLl9yZXN1bHRUeXBlKSkgewotICAgICAgICAgICAgICAgIGZpbmFsIGludCBsZW4gPSBhcmdzQ291bnQoKTsKLSAgICAgICAgICAgICAgICByZXN1bHQgPSBsZW4gPT0gdGVtcC5hcmdzQ291bnQoKTsKLSAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbiAmJiByZXN1bHQ7IGkrKykgewotICAgICAgICAgICAgICAgICAgICBmaW5hbCBUeXBlIGFyZzEgPSAoVHlwZSlfYXJnc1R5cGUuZWxlbWVudEF0KGkpOwotICAgICAgICAgICAgICAgICAgICBmaW5hbCBUeXBlIGFyZzIgPSAoVHlwZSl0ZW1wLl9hcmdzVHlwZS5lbGVtZW50QXQoaSk7Ci0gICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IGFyZzEuaWRlbnRpY2FsVG8oYXJnMik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiByZXN1bHQ7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBkaXN0YW5jZVRvKFR5cGUgb3RoZXIpIHsKLSAgICAgICAgaW50IHJlc3VsdCA9IEludGVnZXIuTUFYX1ZBTFVFOwotICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBNZXRob2RUeXBlKSB7Ci0gICAgICAgICAgICBmaW5hbCBNZXRob2RUeXBlIG10eXBlID0gKE1ldGhvZFR5cGUpIG90aGVyOwotICAgICAgICAgICAgaWYgKF9hcmdzVHlwZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZmluYWwgaW50IGxlbiA9IF9hcmdzVHlwZS5zaXplKCk7Ci0gICAgICAgICAgICAgICAgaWYgKGxlbiA9PSBtdHlwZS5fYXJnc1R5cGUuc2l6ZSgpKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IDA7Ci0gICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIFR5cGUgYXJnMSA9IChUeXBlKSBfYXJnc1R5cGUuZWxlbWVudEF0KGkpOwotICAgICAgICAgICAgICAgICAgICAgICAgVHlwZSBhcmcyID0gKFR5cGUpIG10eXBlLl9hcmdzVHlwZS5lbGVtZW50QXQoaSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgdGVtcCA9IGFyZzEuZGlzdGFuY2VUbyhhcmcyKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0ZW1wID09IEludGVnZXIuTUFYX1ZBTFVFKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gdGVtcDsgIC8vIHJldHVybiBNQVhfVkFMVUUKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCArPSBhcmcxLmRpc3RhbmNlVG8oYXJnMik7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChtdHlwZS5fYXJnc1R5cGUgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJlc3VsdCA9IDA7ICAgLy8gYm90aCBtZXRob2RzIGhhdmUgbm8gYXJncwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiByZXN1bHQ7Ci0gICAgfQotCi0gICAgcHVibGljIFR5cGUgcmVzdWx0VHlwZSgpIHsKLSAgICAgICAgcmV0dXJuIF9yZXN1bHRUeXBlOwotICAgIH0KLQotICAgIHB1YmxpYyBWZWN0b3IgYXJnc1R5cGUoKSB7Ci0gICAgICAgIHJldHVybiBfYXJnc1R5cGU7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBhcmdzQ291bnQoKSB7Ci0gICAgICAgIHJldHVybiBfYXJnc1R5cGUgPT0gbnVsbCA/IDAgOiBfYXJnc1R5cGUuc2l6ZSgpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvdXRpbC9NdWx0aUhhc2h0YWJsZS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci91dGlsL011bHRpSGFzaHRhYmxlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDllZjE2YTAuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci91dGlsL011bHRpSGFzaHRhYmxlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5NCArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDE1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICovCi0vKgotICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCi0gKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKLSAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KLSAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCi0gKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAotICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBNdWx0aUhhc2h0YWJsZS5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzA1IDExOjE4OjUxIHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsOwotCi1pbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7Ci1pbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7Ci1pbXBvcnQgamF2YS51dGlsLk1hcDsKLWltcG9ydCBqYXZhLnV0aWwuU2V0OwotCi0vKioKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqIEBwYXJhbSA8Sz4KLSAqIEBwYXJhbSA8Vj4KLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIE11bHRpSGFzaHRhYmxlPEssVj4gewotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNjE1MTYwODI5MDUxMDAzMzU3Mkw7Ci0KLSAgICBwcml2YXRlIGZpbmFsIE1hcDxLLCBTZXQ8Vj4+IG1hcCA9IG5ldyBIYXNoTWFwPD4oKTsKLSAgICBwcml2YXRlIGJvb2xlYW4gbW9kaWZpYWJsZSA9IHRydWU7Ci0KLSAgICAvKioKLSAgICAgKiBBc3NvY2lhdGVzIHRoZSBzcGVjaWZpZWQga2V5IHdpdGggYSBzZXQgb2YgdmFsdWVzLiBJZiB0aGUgbWFwIHByZXZpb3VzbHkKLSAgICAgKiBjb250YWluZWQgYSBtYXBwaW5nIGZvciB0aGUga2V5LCB0aGUgdmFsdWUgaXMgYWRkZWQgdG8gdGhlIHNldC4KLSAgICAgKiBAcGFyYW0ga2V5IGtleSB3aXRoIHdoaWNoIHRoZSBzcGVjaWZpZWQgdmFsdWUgaXMgdG8gYmUgYXNzb2NpYXRlZAotICAgICAqIEBwYXJhbSB2YWx1ZSB2YWx1ZSB0byBiZSBhZGRlZCB0byBhIHNldCB0aGF0IGlzIGFzc29jaWF0ZWQgd2l0aCB0aGUgc3BlY2lmaWVkIGtleQotICAgICAqIEByZXR1cm4gdGhlIHNldCB0aGF0IGlzIGFzc29jaWF0ZWQgd2l0aCB0aGUgc3BlY2lmaWVkIGtleS4KLSAgICAgKiBAdGhyb3cgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gaXMgdGhlIE11bHRpSGFzaHRhYmxlIGlzIG5vdCBtb2RpZmlhYmxlLgotICAgICAqLwotICAgIHB1YmxpYyBTZXQ8Vj4gcHV0KEsga2V5LCBWIHZhbHVlKSB7Ci0gICAgICAgIGlmIChtb2RpZmlhYmxlKSB7Ci0gICAgICAgICAgICBTZXQ8Vj4gc2V0ID0gbWFwLmdldChrZXkpOwotICAgICAgICAgICAgaWYgKHNldCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgc2V0ID0gbmV3IEhhc2hTZXQ8PigpOwotICAgICAgICAgICAgICAgIG1hcC5wdXQoa2V5LCBzZXQpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgc2V0LmFkZCh2YWx1ZSk7Ci0gICAgICAgICAgICByZXR1cm4gc2V0OwotICAgICAgICB9Ci0gICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiVGhlIE11bHRpSGFzaHRhYmxlIGluc3RhbmNlIGlzIG5vdCBtb2RpZmlhYmxlLiIpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIE1hcHMgYSBrZXkgdG8gYSB2YWx1ZSBpbiBhIHNldCB0aGF0IGlzIGFzc29jaWF0ZWQgd2l0aCB0aGUgc3BlY2lmaWVkIGtleS4KLSAgICAgKiBUaGUgbWFwcGluZyBpcyBwZXJmb3JtZWQgYnkgZXZhbHVhdGluZyB3aGV0aGVyIGFuIGl0ZW0gaW4gdGhlIHNldCBlcXVhbHMKLSAgICAgKiB0aGUgc3BlY2lmaWVkIHZhbHVlLgotICAgICAqCi0gICAgICogQHBhcmFtIGtleSBrZXkgd2l0aCB3aGljaCB0aGUgc3BlY2lmaWVkIHZhbHVlIGlzIHRvIGJlIGFzc29jaWF0ZWQKLSAgICAgKiBAcGFyYW0gdmFsdWUgdmFsdWUgaW4gYSBzZXQgdGhhdCBpcyBhc3NvY2lhdGVkIHdpdGggdGhlIHNwZWNpZmllZCBrZXkKLSAgICAgKiBAcmV0dXJuIHRoZSBpdGVtIGluIHRoZSBzZXQgaWYgYSBtYXRjaCBpcyBmb3VuZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgViBtYXBzKEsga2V5LCBWIHZhbHVlKSB7Ci0gICAgICAgIGlmIChrZXkgPT0gbnVsbCkgcmV0dXJuIG51bGw7Ci0gICAgICAgIGZpbmFsIFNldDxWPiBzZXQgPSBtYXAuZ2V0KGtleSk7Ci0gICAgICAgIGlmIChzZXQgIT0gbnVsbCkgewotICAgICAgICAgICAgZm9yIChWIHYgOiBzZXQpIHsKLSAgICAgICAgICAgICAgICBpZiAodi5lcXVhbHModmFsdWUpKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiB2OwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBNYWtlcyB0aGUgTXVsdGlIYXNodGFibGUgdW5tb2RpZmlhYmxlLiAgVGhpcyBtZXRob2QgYWxsb3dzIG1vZHVsZXMgdG8gc2V0IHRoZSB0YWJsZQotICAgICAqIGFzICJyZWFkLW9ubHkiIHNvIHRoYXQgb25seSBxdWVyeSBvcGVyYXRpb24sIHRoYXQgaXMgbWFwcywgaXMgYWxsb3dlZC4gQW55IGF0dGVtcHRzCi0gICAgICogdG8gbW9kaWZ5IHRoZSByZXR1cm5lZCBtYXAgcmVzdWx0IGluIGFuIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIG1ha2VVbm1vZGlmaWFibGUoKSB7Ci0gICAgICAgIG1vZGlmaWFibGUgPSBmYWxzZTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL3V0aWwvTmFtZWRNZXRob2RHZW5lcmF0b3IuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvdXRpbC9OYW1lZE1ldGhvZEdlbmVyYXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwOTEzYTdiLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvdXRpbC9OYW1lZE1ldGhvZEdlbmVyYXRvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNjcgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogTmFtZWRNZXRob2RHZW5lcmF0b3IuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8wNSAxMToxOTo1NiBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbDsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQUxPQUQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5BU1RPUkU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5Db25zdGFudFBvb2xHZW47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JbnN0cnVjdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uTGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlR5cGU7Ci0KLS8qKgotICogVGhpcyBjbGFzcyBpcyB1c2VkIGZvciBuYW1lZCB0ZW1wbGF0ZXMuIE5hbWVkIHRlbXBsYXRlIG1ldGhvZHMgaGF2ZSBhY2Nlc3MKLSAqIHRvIHRoZSBET00sIHRoZSBjdXJyZW50IGl0ZXJhdG9yLCB0aGUgaGFuZGxlciBhbmQgdGhlIGN1cnJlbnQgbm9kZS4KLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIE5hbWVkTWV0aG9kR2VuZXJhdG9yIGV4dGVuZHMgTWV0aG9kR2VuZXJhdG9yIHsKLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBDVVJSRU5UX0lOREVYICA9IDQ7Ci0KLSAgICAvLyBUaGUgaW5kZXggb2YgdGhlIGZpcnN0IHBhcmFtZXRlciAoYWZ0ZXIgZG9tL2l0ZXJhdG9yL2hhbmRsZXIvY3VycmVudCkKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgUEFSQU1fU1RBUlRfSU5ERVggPSA1OwotCi0gICAgcHVibGljIE5hbWVkTWV0aG9kR2VuZXJhdG9yKGludCBhY2Nlc3NfZmxhZ3MsIFR5cGUgcmV0dXJuX3R5cGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFR5cGVbXSBhcmdfdHlwZXMsIFN0cmluZ1tdIGFyZ19uYW1lcywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG1ldGhvZF9uYW1lLCBTdHJpbmcgY2xhc3NfbmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW5zdHJ1Y3Rpb25MaXN0IGlsLCBDb25zdGFudFBvb2xHZW4gY3ApIHsKLSAgICAgICAgc3VwZXIoYWNjZXNzX2ZsYWdzLCByZXR1cm5fdHlwZSwgYXJnX3R5cGVzLCBhcmdfbmFtZXMsIG1ldGhvZF9uYW1lLAotICAgICAgICAgICAgICBjbGFzc19uYW1lLCBpbCwgY3ApOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgZ2V0TG9jYWxJbmRleChTdHJpbmcgbmFtZSkgewotICAgICAgICBpZiAobmFtZS5lcXVhbHMoImN1cnJlbnQiKSkgewotICAgICAgICAgICAgcmV0dXJuIENVUlJFTlRfSU5ERVg7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHN1cGVyLmdldExvY2FsSW5kZXgobmFtZSk7Ci0gICAgfQotCi0gICAgcHVibGljIEluc3RydWN0aW9uIGxvYWRQYXJhbWV0ZXIoaW50IGluZGV4KSB7Ci0gICAgICAgIHJldHVybiBuZXcgQUxPQUQoaW5kZXggKyBQQVJBTV9TVEFSVF9JTkRFWCk7Ci0gICAgfQotCi0gICAgcHVibGljIEluc3RydWN0aW9uIHN0b3JlUGFyYW1ldGVyKGludCBpbmRleCkgewotICAgICAgICByZXR1cm4gbmV3IEFTVE9SRShpbmRleCArIFBBUkFNX1NUQVJUX0lOREVYKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL3V0aWwvTm9kZUNvdW50ZXJHZW5lcmF0b3IuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvdXRpbC9Ob2RlQ291bnRlckdlbmVyYXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2OGRkYzg5Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvdXRpbC9Ob2RlQ291bnRlckdlbmVyYXRvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNzUgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogTm9kZUNvdW50ZXJHZW5lcmF0b3IuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8wNSAxMToyMDo0OCBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbDsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQUxPQUQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JbnN0cnVjdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIuU3R5bGVzaGVldDsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGltcGxlbWVudHMgYXV4aWxpYXJ5IGNsYXNzZXMgbmVlZGVkIHRvIGNvbXBpbGUKLSAqIHBhdHRlcm5zIGluIDx0dD54c2w6bnVtYmVyPC90dD4uIFRoZXNlIGNsYXNzZXMgaW5oZXJpdCBmcm9tCi0gKiB7QW55LFNpbmdsZSxNdWx0aXBsZX1Ob2RlQ291bnRlciBhbmQgb3ZlcnJpZGUgdGhlCi0gKiA8dHQ+bWF0Y2hGcm9tPC90dD4gYW5kIDx0dD5tYXRjaENvdW50PC90dD4gbWV0aG9kcy4KLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIE5vZGVDb3VudGVyR2VuZXJhdG9yIGV4dGVuZHMgQ2xhc3NHZW5lcmF0b3IgewotICAgIHByaXZhdGUgSW5zdHJ1Y3Rpb24gX2Fsb2FkVHJhbnNsZXQ7Ci0KLSAgICBwdWJsaWMgTm9kZUNvdW50ZXJHZW5lcmF0b3IoU3RyaW5nIGNsYXNzTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHN1cGVyQ2xhc3NOYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgZmlsZU5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBhY2Nlc3NGbGFncywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nW10gaW50ZXJmYWNlcywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3R5bGVzaGVldCBzdHlsZXNoZWV0KSB7Ci0gICAgICAgIHN1cGVyKGNsYXNzTmFtZSwgc3VwZXJDbGFzc05hbWUsIGZpbGVOYW1lLAotICAgICAgICAgICAgICBhY2Nlc3NGbGFncywgaW50ZXJmYWNlcywgc3R5bGVzaGVldCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSBpbmRleCBvZiB0aGUgcmVnaXN0ZXIgd2hlcmUgInRoaXMiICh0aGUgcG9pbnRlciB0bwotICAgICAqIHRoZSB0cmFuc2xldCkgaXMgc3RvcmVkLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFRyYW5zbGV0SW5kZXgoaW50IGluZGV4KSB7Ci0gICAgICAgIF9hbG9hZFRyYW5zbGV0ID0gbmV3IEFMT0FEKGluZGV4KTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgaW5kZXggb2YgdGhlIHRyYW5zbGV0IHBvaW50ZXIgd2l0aGluIHRoZSBleGVjdXRpb24gb2YKLSAgICAgKiBtYXRjaEZyb20gb3IgbWF0Y2hDb3VudC4KLSAgICAgKiBPdmVycmlkZGVuIGZyb20gQ2xhc3NHZW5lcmF0b3IuCi0gICAgICovCi0gICAgcHVibGljIEluc3RydWN0aW9uIGxvYWRUcmFuc2xldCgpIHsKLSAgICAgICAgcmV0dXJuIF9hbG9hZFRyYW5zbGV0OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgPHR0PnRydWU8L3R0PiBzaW5jZSB0aGlzIGNsYXNzIGlzIGV4dGVybmFsIHRvIHRoZQotICAgICAqIHRyYW5zbGV0LgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzRXh0ZXJuYWwoKSB7Ci0gICAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvdXRpbC9Ob2RlU2V0VHlwZS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci91dGlsL05vZGVTZXRUeXBlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDYxNmZkNzAuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci91dGlsL05vZGVTZXRUeXBlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzMzEgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogTm9kZVNldFR5cGUuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8wNSAxMToyMTo0NSBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbDsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQUxPQUQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5BU1RPUkU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5CcmFuY2hIYW5kbGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5Db25zdGFudFBvb2xHZW47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5HT1RPOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSUZMVDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklOVk9LRUlOVEVSRkFDRTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklOVk9LRVNUQVRJQzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW5zdHJ1Y3Rpb25MaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuUFVTSDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIuQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci5GbG93TGlzdDsKLQotLyoqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBOb2RlU2V0VHlwZSBleHRlbmRzIFR5cGUgewotICAgIHByb3RlY3RlZCBOb2RlU2V0VHlwZSgpIHt9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgICAgICByZXR1cm4gIm5vZGUtc2V0IjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBpZGVudGljYWxUbyhUeXBlIG90aGVyKSB7Ci0gICAgICAgIHJldHVybiB0aGlzID09IG90aGVyOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgdG9TaWduYXR1cmUoKSB7Ci0gICAgICAgIHJldHVybiBOT0RFX0lURVJBVE9SX1NJRzsKLSAgICB9Ci0KLSAgICBwdWJsaWMgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5UeXBlIHRvSkNUeXBlKCkgewotICAgICAgICByZXR1cm4gbmV3IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuT2JqZWN0VHlwZShOT0RFX0lURVJBVE9SKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGVzIGEgbm9kZS1zZXQgaW50byBhbiBvYmplY3Qgb2YgaW50ZXJuYWwgdHlwZQotICAgICAqIDxjb2RlPnR5cGU8L2NvZGU+LiBUaGUgdHJhbnNsYXRpb24gdG8gaW50IGlzIHVuZGVmaW5lZAotICAgICAqIHNpbmNlIG5vZGUtc2V0cyBhcmUgYWx3YXlzIGNvbnZlcnRlZCB0bwotICAgICAqIHJlYWxzIGluIGFyaXRobWV0aWMgZXhwcmVzc2lvbnMuCi0gICAgICoKLSAgICAgKiBAc2VlICAgICBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlI3RyYW5zbGF0ZVRvCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlVG8oQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgVHlwZSB0eXBlKSB7Ci0gICAgICAgIGlmICh0eXBlID09IFR5cGUuU3RyaW5nKSB7Ci0gICAgICAgICAgICB0cmFuc2xhdGVUbyhjbGFzc0dlbiwgbWV0aG9kR2VuLCAoU3RyaW5nVHlwZSkgdHlwZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAodHlwZSA9PSBUeXBlLkJvb2xlYW4pIHsKLSAgICAgICAgICAgIHRyYW5zbGF0ZVRvKGNsYXNzR2VuLCBtZXRob2RHZW4sIChCb29sZWFuVHlwZSkgdHlwZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAodHlwZSA9PSBUeXBlLlJlYWwpIHsKLSAgICAgICAgICAgIHRyYW5zbGF0ZVRvKGNsYXNzR2VuLCBtZXRob2RHZW4sIChSZWFsVHlwZSkgdHlwZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAodHlwZSA9PSBUeXBlLk5vZGUpIHsKLSAgICAgICAgICAgIHRyYW5zbGF0ZVRvKGNsYXNzR2VuLCBtZXRob2RHZW4sIChOb2RlVHlwZSkgdHlwZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAodHlwZSA9PSBUeXBlLlJlZmVyZW5jZSkgewotICAgICAgICAgICAgdHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgKFJlZmVyZW5jZVR5cGUpIHR5cGUpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKHR5cGUgPT0gVHlwZS5PYmplY3QpIHsKLSAgICAgICAgICAgIHRyYW5zbGF0ZVRvKGNsYXNzR2VuLCBtZXRob2RHZW4sIChPYmplY3RUeXBlKSB0eXBlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIEVycm9yTXNnIGVyciA9IG5ldyBFcnJvck1zZyhFcnJvck1zZy5EQVRBX0NPTlZFUlNJT05fRVJSLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvU3RyaW5nKCksIHR5cGUudG9TdHJpbmcoKSk7Ci0gICAgICAgICAgICBjbGFzc0dlbi5nZXRQYXJzZXIoKS5yZXBvcnRFcnJvcihDb25zdGFudHMuRkFUQUwsIGVycik7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGVzIGFuIGV4dGVybmFsIEphdmEgQ2xhc3MgaW50byBhbiBpbnRlcm5hbCB0eXBlLgotICAgICAqIEV4cGVjdHMgdGhlIEphdmEgb2JqZWN0IG9uIHRoZSBzdGFjaywgcHVzaGVzIHRoZSBpbnRlcm5hbCB0eXBlCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlRnJvbShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwKLSAgICAgICAgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwgQ2xhc3MgY2xhenopCi0gICAgewotCi0gICAgICAgIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLSAgICAgICAgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotICAgICAgICBpZiAoY2xhenouZ2V0TmFtZSgpLmVxdWFscygib3JnLnczYy5kb20uTm9kZUxpc3QiKSkgewotICAgICAgICAgICAvLyB3M2MgTm9kZUxpc3QgaXMgb24gdGhlIHN0YWNrIGZyb20gdGhlIGV4dGVybmFsIEphdmEgZnVuY3Rpb24gY2FsbC4KLSAgICAgICAgICAgLy8gY2FsbCBCYXNpc0Z1bmN0aW9uIHRvIGNvbnN1bWUgTm9kZUxpc3QgYW5kIGxlYXZlIEl0ZXJhdG9yIG9uCi0gICAgICAgICAgIC8vICAgIHRoZSBzdGFjay4KLSAgICAgICAgICAgaWwuYXBwZW5kKGNsYXNzR2VuLmxvYWRUcmFuc2xldCgpKTsgICAvLyBwdXNoIHRyYW5zbGV0IG9udG8gc3RhY2sKLSAgICAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkRE9NKCkpOyAgICAgICAvLyBwdXNoIERPTSBvbnRvIHN0YWNrCi0gICAgICAgICAgIGZpbmFsIGludCBjb252ZXJ0ID0gY3BnLmFkZE1ldGhvZHJlZihCQVNJU19MSUJSQVJZX0NMQVNTLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJub2RlTGlzdDJJdGVyYXRvciIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIigiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIkxvcmcvdzNjL2RvbS9Ob2RlTGlzdDsiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgVFJBTlNMRVRfSU5URl9TSUcKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBET01fSU5URl9TSUcKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiKSIgKyBOT0RFX0lURVJBVE9SX1NJRyApOwotICAgICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRVNUQVRJQyhjb252ZXJ0KSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoY2xhenouZ2V0TmFtZSgpLmVxdWFscygib3JnLnczYy5kb20uTm9kZSIpKSB7Ci0gICAgICAgICAgIC8vIHczYyBOb2RlIGlzIG9uIHRoZSBzdGFjayBmcm9tIHRoZSBleHRlcm5hbCBKYXZhIGZ1bmN0aW9uIGNhbGwuCi0gICAgICAgICAgIC8vIGNhbGwgQmFzaXNMaWJyYXJ5Lm5vZGUySXRlcmF0b3IoKSB0byBjb25zdW1lIE5vZGUgYW5kIGxlYXZlCi0gICAgICAgICAgIC8vIEl0ZXJhdG9yIG9uIHRoZSBzdGFjay4KLSAgICAgICAgICAgaWwuYXBwZW5kKGNsYXNzR2VuLmxvYWRUcmFuc2xldCgpKTsgICAvLyBwdXNoIHRyYW5zbGV0IG9udG8gc3RhY2sKLSAgICAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkRE9NKCkpOyAgICAgICAvLyBwdXNoIERPTSBvbnRvIHN0YWNrCi0gICAgICAgICAgIGZpbmFsIGludCBjb252ZXJ0ID0gY3BnLmFkZE1ldGhvZHJlZihCQVNJU19MSUJSQVJZX0NMQVNTLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJub2RlMkl0ZXJhdG9yIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKCIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiTG9yZy93M2MvZG9tL05vZGU7IgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIFRSQU5TTEVUX0lOVEZfU0lHCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgRE9NX0lOVEZfU0lHCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIikiICsgTk9ERV9JVEVSQVRPUl9TSUcgKTsKLSAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VTVEFUSUMoY29udmVydCkpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgRXJyb3JNc2cgZXJyID0gbmV3IEVycm9yTXNnKEVycm9yTXNnLkRBVEFfQ09OVkVSU0lPTl9FUlIsCi0gICAgICAgICAgICAgICAgdG9TdHJpbmcoKSwgY2xhenouZ2V0TmFtZSgpKTsKLSAgICAgICAgICAgIGNsYXNzR2VuLmdldFBhcnNlcigpLnJlcG9ydEVycm9yKENvbnN0YW50cy5GQVRBTCwgZXJyKTsKLSAgICAgICAgfQotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogVHJhbnNsYXRlcyBhIG5vZGUtc2V0IGludG8gYSBzeW50aGVzaXplZCBib29sZWFuLgotICAgICAqIFRoZSBib29sZWFuIHZhbHVlIG9mIGEgbm9kZS1zZXQgaXMgInRydWUiIGlmIG5vbi1lbXB0eQotICAgICAqIGFuZCAiZmFsc2UiIG90aGVyd2lzZS4gTm90aWNlIHRoYXQgdGhlCi0gICAgICogZnVuY3Rpb24gZ2V0Rmlyc3ROb2RlKCkgaXMgY2FsbGVkIGluIHRyYW5zbGF0ZVRvRGVzeW50aGVzaXplZCgpLgotICAgICAqCi0gICAgICogQHNlZSAgICAgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZSN0cmFuc2xhdGVUbwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZVRvKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJvb2xlYW5UeXBlIHR5cGUpIHsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotICAgICAgICBGbG93TGlzdCBmYWxzZWwgPSB0cmFuc2xhdGVUb0Rlc3ludGhlc2l6ZWQoY2xhc3NHZW4sIG1ldGhvZEdlbiwgdHlwZSk7Ci0gICAgICAgIGlsLmFwcGVuZChJQ09OU1RfMSk7Ci0gICAgICAgIGZpbmFsIEJyYW5jaEhhbmRsZSB0cnVlYyA9IGlsLmFwcGVuZChuZXcgR09UTyhudWxsKSk7Ci0gICAgICAgIGZhbHNlbC5iYWNrUGF0Y2goaWwuYXBwZW5kKElDT05TVF8wKSk7Ci0gICAgICAgIHRydWVjLnNldFRhcmdldChpbC5hcHBlbmQoTk9QKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhbnNsYXRlcyBhIG5vZGUtc2V0IGludG8gYSBzdHJpbmcuIFRoZSBzdHJpbmcgdmFsdWUgb2YgYSBub2RlLXNldCBpcwotICAgICAqIHZhbHVlIG9mIGl0cyBmaXJzdCBlbGVtZW50LgotICAgICAqCi0gICAgICogQHNlZSAgICAgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZSN0cmFuc2xhdGVUbwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZVRvKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1R5cGUgdHlwZSkgewotICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0gICAgICAgIGdldEZpcnN0Tm9kZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgaWwuYXBwZW5kKERVUCk7Ci0gICAgICAgIGZpbmFsIEJyYW5jaEhhbmRsZSBmYWxzZWMgPSBpbC5hcHBlbmQobmV3IElGTFQobnVsbCkpOwotICAgICAgICBUeXBlLk5vZGUudHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgdHlwZSk7Ci0gICAgICAgIGZpbmFsIEJyYW5jaEhhbmRsZSB0cnVlYyA9IGlsLmFwcGVuZChuZXcgR09UTyhudWxsKSk7Ci0gICAgICAgIGZhbHNlYy5zZXRUYXJnZXQoaWwuYXBwZW5kKFBPUCkpOwotICAgICAgICBpbC5hcHBlbmQobmV3IFBVU0goY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCksICIiKSk7Ci0gICAgICAgIHRydWVjLnNldFRhcmdldChpbC5hcHBlbmQoTk9QKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRXhwZWN0cyBhIG5vZGUtc2V0IG9uIHRoZSBzdGFjayBhbmQgcHVzaGVzIGEgcmVhbC4KLSAgICAgKiBGaXJzdCB0aGUgbm9kZS1zZXQgaXMgY29udmVydGVkIHRvIHN0cmluZywgYW5kIGZyb20gc3RyaW5nIHRvIHJlYWwuCi0gICAgICoKLSAgICAgKiBAc2VlICAgICBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlI3RyYW5zbGF0ZVRvCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlVG8oQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVhbFR5cGUgdHlwZSkgewotICAgICAgICB0cmFuc2xhdGVUbyhjbGFzc0dlbiwgbWV0aG9kR2VuLCBUeXBlLlN0cmluZyk7Ci0gICAgICAgIFR5cGUuU3RyaW5nLnRyYW5zbGF0ZVRvKGNsYXNzR2VuLCBtZXRob2RHZW4sIFR5cGUuUmVhbCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRXhwZWN0cyBhIG5vZGUtc2V0IG9uIHRoZSBzdGFjayBhbmQgcHVzaGVzIGEgbm9kZS4KLSAgICAgKgotICAgICAqIEBzZWUgICAgIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGUjdHJhbnNsYXRlVG8KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVUbyhDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBOb2RlVHlwZSB0eXBlKSB7Ci0gICAgICAgIGdldEZpcnN0Tm9kZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTdWJzdW1lIG5vZGUtc2V0IGludG8gT2JqZWN0VHlwZS4KLSAgICAgKgotICAgICAqIEBzZWUgICAgIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGUjdHJhbnNsYXRlVG8KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVUbyhDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBPYmplY3RUeXBlIHR5cGUpIHsKLSAgICAgICAgICAgIG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKS5hcHBlbmQoTk9QKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGVzIGEgbm9kZS1zZXQgaW50byBhIG5vbi1zeW50aGVzaXplZCBib29sZWFuLiBJdCBkb2VzIG5vdAotICAgICAqIHB1c2ggYSAwIG9yIGEgMSBidXQgaW5zdGVhZCByZXR1cm5zIGJyYW5jaGhhbmRsZSBsaXN0IHRvIGJlIGFwcGVuZGVkCi0gICAgICogdG8gdGhlIGZhbHNlIGxpc3QuCi0gICAgICoKLSAgICAgKiBAc2VlICAgICBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlI3RyYW5zbGF0ZVRvRGVzeW50aGVzaXplZAotICAgICAqLwotICAgIHB1YmxpYyBGbG93TGlzdCB0cmFuc2xhdGVUb0Rlc3ludGhlc2l6ZWQoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQm9vbGVhblR5cGUgdHlwZSkgewotICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0gICAgICAgIGdldEZpcnN0Tm9kZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICAgICAgcmV0dXJuIG5ldyBGbG93TGlzdChpbC5hcHBlbmQobmV3IElGTFQobnVsbCkpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBFeHBlY3RzIGEgbm9kZS1zZXQgb24gdGhlIHN0YWNrIGFuZCBwdXNoZXMgYSBib3hlZCBub2RlLXNldC4KLSAgICAgKiBOb2RlIHNldHMgYXJlIGFscmVhZHkgYm94ZWQgc28gdGhlIHRyYW5zbGF0aW9uIGlzIGp1c3QgYSBOT1AuCi0gICAgICoKLSAgICAgKiBAc2VlICAgICBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlI3RyYW5zbGF0ZVRvCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlVG8oQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVmZXJlbmNlVHlwZSB0eXBlKSB7Ci0gICAgICAgIG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKS5hcHBlbmQoTk9QKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGVzIGEgbm9kZS1zZXQgaW50byB0aGUgSmF2YSB0eXBlIGRlbm90ZWQgYnkgPGNvZGU+Y2xheno8L2NvZGU+LgotICAgICAqIEV4cGVjdHMgYSBub2RlLXNldCBvbiB0aGUgc3RhY2sgYW5kIHB1c2hlcyBhbiBvYmplY3Qgb2YgdGhlIGFwcHJvcHJpYXRlCi0gICAgICogdHlwZSBhZnRlciBjb2VyY2lvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVUbyhDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBDbGFzcyBjbGF6eikgewotICAgICAgICBmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLSAgICAgICAgZmluYWwgU3RyaW5nIGNsYXNzTmFtZSA9IGNsYXp6LmdldE5hbWUoKTsKLQotICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0gICAgICAgIGlsLmFwcGVuZChTV0FQKTsKLQotICAgICAgICBpZiAoY2xhc3NOYW1lLmVxdWFscygib3JnLnczYy5kb20uTm9kZSIpKSB7Ci0gICAgICAgICAgICBpbnQgaW5kZXggPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKERPTV9JTlRGLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNQUtFX05PREUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1BS0VfTk9ERV9TSUcyKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFSU5URVJGQUNFKGluZGV4LCAyKSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoY2xhc3NOYW1lLmVxdWFscygib3JnLnczYy5kb20uTm9kZUxpc3QiKSB8fAotICAgICAgICAgICAgICAgICBjbGFzc05hbWUuZXF1YWxzKCJqYXZhLmxhbmcuT2JqZWN0IikpIHsKLSAgICAgICAgICAgIGludCBpbmRleCA9IGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoRE9NX0lOVEYsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1BS0VfTk9ERV9MSVNULAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNQUtFX05PREVfTElTVF9TSUcyKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFSU5URVJGQUNFKGluZGV4LCAyKSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoY2xhc3NOYW1lLmVxdWFscygiamF2YS5sYW5nLlN0cmluZyIpKSB7Ci0gICAgICAgICAgICBpbnQgbmV4dCA9IGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoTk9ERV9JVEVSQVRPUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibmV4dCIsICIoKUkiKTsKLSAgICAgICAgICAgIGludCBpbmRleCA9IGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoRE9NX0lOVEYsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR0VUX05PREVfVkFMVUUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIihJKSIrU1RSSU5HX1NJRyk7Ci0KLSAgICAgICAgICAgIC8vIEdldCBuZXh0IG5vZGUgZnJvbSB0aGUgaXRlcmF0b3IKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFSU5URVJGQUNFKG5leHQsIDEpKTsKLSAgICAgICAgICAgIC8vIEdldCB0aGUgbm9kZSdzIHN0cmluZyB2YWx1ZSAoZnJvbSB0aGUgRE9NKQotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0UoaW5kZXgsIDIpKTsKLQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgRXJyb3JNc2cgZXJyID0gbmV3IEVycm9yTXNnKEVycm9yTXNnLkRBVEFfQ09OVkVSU0lPTl9FUlIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG9TdHJpbmcoKSwgY2xhc3NOYW1lKTsKLSAgICAgICAgICAgIGNsYXNzR2VuLmdldFBhcnNlcigpLnJlcG9ydEVycm9yKENvbnN0YW50cy5GQVRBTCwgZXJyKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNvbWUgdHlwZSBjb252ZXJzaW9ucyByZXF1aXJlIGdldHR0aW5nIHRoZSBmaXJzdCBub2RlIGZyb20gdGhlIG5vZGUtc2V0LgotICAgICAqIFRoaXMgZnVuY3Rpb24gaXMgZGVmaW5lZCB0byBhdm9pZCBjb2RlIHJlcGV0aXRpb24uCi0gICAgICovCi0gICAgcHJpdmF0ZSB2b2lkIGdldEZpcnN0Tm9kZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotICAgICAgICBmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0UoY3BnLmFkZEludGVyZmFjZU1ldGhvZHJlZihOT0RFX0lURVJBVE9SLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5FWFQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkVYVF9TSUcpLCAxKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhbnNsYXRlcyBhbiBvYmplY3Qgb2YgdGhpcyB0eXBlIHRvIGl0cyBib3hlZCByZXByZXNlbnRhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVCb3goQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLSAgICAgICAgdHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgVHlwZS5SZWZlcmVuY2UpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZXMgYW4gb2JqZWN0IG9mIHRoaXMgdHlwZSB0byBpdHMgdW5ib3hlZCByZXByZXNlbnRhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVVbkJveChDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0gICAgICAgIG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKS5hcHBlbmQoTk9QKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBjbGFzcyBuYW1lIG9mIGFuIGludGVybmFsIHR5cGUncyBleHRlcm5hbCByZXByZXNlbnRhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldENsYXNzTmFtZSgpIHsKLSAgICAgICAgcmV0dXJuKE5PREVfSVRFUkFUT1IpOwotICAgIH0KLQotCi0gICAgcHVibGljIEluc3RydWN0aW9uIExPQUQoaW50IHNsb3QpIHsKLSAgICAgICAgcmV0dXJuIG5ldyBBTE9BRChzbG90KTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb24gU1RPUkUoaW50IHNsb3QpIHsKLSAgICAgICAgcmV0dXJuIG5ldyBBU1RPUkUoc2xvdCk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci91dGlsL05vZGVTb3J0UmVjb3JkRmFjdEdlbmVyYXRvci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci91dGlsL05vZGVTb3J0UmVjb3JkRmFjdEdlbmVyYXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiYWNjY2FjLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvdXRpbC9Ob2RlU29ydFJlY29yZEZhY3RHZW5lcmF0b3IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQ5ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IE5vZGVTb3J0UmVjb3JkRmFjdEdlbmVyYXRvci5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzA1IDExOjIzOjA3IHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLlN0eWxlc2hlZXQ7Ci0KLS8qKgotICogR2VuZXJhdG9yIGZvciBzdWJjbGFzc2VzIG9mIE5vZGVTb3J0UmVjb3JkRmFjdG9yeS4KLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgTm9kZVNvcnRSZWNvcmRGYWN0R2VuZXJhdG9yIGV4dGVuZHMgQ2xhc3NHZW5lcmF0b3IgewotCi0gICAgcHVibGljIE5vZGVTb3J0UmVjb3JkRmFjdEdlbmVyYXRvcihTdHJpbmcgY2xhc3NOYW1lLCBTdHJpbmcgc3VwZXJDbGFzc05hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBmaWxlTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGFjY2Vzc0ZsYWdzLCBTdHJpbmdbXSBpbnRlcmZhY2VzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHlsZXNoZWV0IHN0eWxlc2hlZXQpIHsKLSAgICAgICAgc3VwZXIoY2xhc3NOYW1lLCBzdXBlckNsYXNzTmFtZSwgZmlsZU5hbWUsCi0gICAgICAgICAgICAgIGFjY2Vzc0ZsYWdzLCBpbnRlcmZhY2VzLCBzdHlsZXNoZWV0KTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIDx0dD50cnVlPC90dD4gc2luY2UgdGhpcyBjbGFzcyBpcyBleHRlcm5hbCB0byB0aGUKLSAgICAgKiB0cmFuc2xldC4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0V4dGVybmFsKCkgewotICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL3V0aWwvTm9kZVNvcnRSZWNvcmRHZW5lcmF0b3IuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvdXRpbC9Ob2RlU29ydFJlY29yZEdlbmVyYXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwZTUzMzM4Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvdXRpbC9Ob2RlU29ydFJlY29yZEdlbmVyYXRvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNjUgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogTm9kZVNvcnRSZWNvcmRHZW5lcmF0b3IuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8wNSAxMToyMzo0MiBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbDsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQUxPQUQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JbnN0cnVjdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIuU3R5bGVzaGVldDsKLQotLyoqCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBOb2RlU29ydFJlY29yZEdlbmVyYXRvciBleHRlbmRzIENsYXNzR2VuZXJhdG9yIHsKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgVFJBTlNMRVRfSU5ERVggPSA0OyAgIC8vIHRyYW5zbGV0Ci0gICAgcHJpdmF0ZSBmaW5hbCBJbnN0cnVjdGlvbiBfYWxvYWRUcmFuc2xldDsKLQotICAgIHB1YmxpYyBOb2RlU29ydFJlY29yZEdlbmVyYXRvcihTdHJpbmcgY2xhc3NOYW1lLCBTdHJpbmcgc3VwZXJDbGFzc05hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBmaWxlTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGFjY2Vzc0ZsYWdzLCBTdHJpbmdbXSBpbnRlcmZhY2VzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHlsZXNoZWV0IHN0eWxlc2hlZXQpIHsKLSAgICAgICAgc3VwZXIoY2xhc3NOYW1lLCBzdXBlckNsYXNzTmFtZSwgZmlsZU5hbWUsCi0gICAgICAgICAgICAgIGFjY2Vzc0ZsYWdzLCBpbnRlcmZhY2VzLCBzdHlsZXNoZWV0KTsKLSAgICAgICAgX2Fsb2FkVHJhbnNsZXQgPSBuZXcgQUxPQUQoVFJBTlNMRVRfSU5ERVgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoZSBpbmRleCBvZiB0aGUgdHJhbnNsZXQgcG9pbnRlciB3aXRoaW4gdGhlIGV4ZWN1dGlvbiBvZgotICAgICAqIHRoZSB0ZXN0IG1ldGhvZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb24gbG9hZFRyYW5zbGV0KCkgewotICAgICAgICByZXR1cm4gX2Fsb2FkVHJhbnNsZXQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyA8dHQ+dHJ1ZTwvdHQ+IHNpbmNlIHRoaXMgY2xhc3MgaXMgZXh0ZXJuYWwgdG8gdGhlCi0gICAgICogdHJhbnNsZXQuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNFeHRlcm5hbCgpIHsKLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL3V0aWwvTm9kZVR5cGUuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvdXRpbC9Ob2RlVHlwZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlNDhhMDkyLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvdXRpbC9Ob2RlVHlwZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzI0ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IE5vZGVUeXBlLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMDUgMTE6MjQ6MjUgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWw7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkJyYW5jaEhhbmRsZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkNIRUNLQ0FTVDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkNvbnN0YW50UG9vbEdlbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkdFVEZJRUxEOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuR09UTzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklGRVE7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JTE9BRDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklOVk9LRUlOVEVSRkFDRTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklOVk9LRVNQRUNJQUw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JU1RPUkU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JbnN0cnVjdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uTGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLk5FVzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlBVU0g7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLkNvbnN0YW50czsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIuRmxvd0xpc3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLk5vZGVUZXN0OwotCi0vKioKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIE5vZGVUeXBlIGV4dGVuZHMgVHlwZSB7Ci0gICAgcHJpdmF0ZSBmaW5hbCBpbnQgX3R5cGU7Ci0KLSAgICBwcm90ZWN0ZWQgTm9kZVR5cGUoKSB7Ci0gICAgICAgIHRoaXMoTm9kZVRlc3QuQU5PREUpOwotICAgIH0KLQotICAgIHByb3RlY3RlZCBOb2RlVHlwZShpbnQgdHlwZSkgewotICAgICAgICBfdHlwZSA9IHR5cGU7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBnZXRUeXBlKCkgewotICAgICAgICByZXR1cm4gX3R5cGU7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKLSAgICAgICAgcmV0dXJuICJub2RlLXR5cGUiOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGlkZW50aWNhbFRvKFR5cGUgb3RoZXIpIHsKLSAgICAgICAgcmV0dXJuIG90aGVyIGluc3RhbmNlb2YgTm9kZVR5cGU7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKLSAgICAgICAgcmV0dXJuIF90eXBlOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgdG9TaWduYXR1cmUoKSB7Ci0gICAgICAgIHJldHVybiAiSSI7Ci0gICAgfQotCi0gICAgcHVibGljIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuVHlwZSB0b0pDVHlwZSgpIHsKLSAgICAgICAgcmV0dXJuIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuVHlwZS5JTlQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhbnNsYXRlcyBhIG5vZGUgaW50byBhbiBvYmplY3Qgb2YgaW50ZXJuYWwgdHlwZSA8Y29kZT50eXBlPC9jb2RlPi4KLSAgICAgKiBUaGUgdHJhbnNsYXRpb24gdG8gaW50IGlzIHVuZGVmaW5lZCBzaW5jZSBub2RlcyBhcmUgYWx3YXlzIGNvbnZlcnRlZAotICAgICAqIHRvIHJlYWxzIGluIGFyaXRobWV0aWMgZXhwcmVzc2lvbnMuCi0gICAgICoKLSAgICAgKiBAc2VlICAgICBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlI3RyYW5zbGF0ZVRvCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlVG8oQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgVHlwZSB0eXBlKSB7Ci0gICAgICAgIGlmICh0eXBlID09IFR5cGUuU3RyaW5nKSB7Ci0gICAgICAgICAgICB0cmFuc2xhdGVUbyhjbGFzc0dlbiwgbWV0aG9kR2VuLCAoU3RyaW5nVHlwZSkgdHlwZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAodHlwZSA9PSBUeXBlLkJvb2xlYW4pIHsKLSAgICAgICAgICAgIHRyYW5zbGF0ZVRvKGNsYXNzR2VuLCBtZXRob2RHZW4sIChCb29sZWFuVHlwZSkgdHlwZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAodHlwZSA9PSBUeXBlLlJlYWwpIHsKLSAgICAgICAgICAgIHRyYW5zbGF0ZVRvKGNsYXNzR2VuLCBtZXRob2RHZW4sIChSZWFsVHlwZSkgdHlwZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAodHlwZSA9PSBUeXBlLk5vZGVTZXQpIHsKLSAgICAgICAgICAgIHRyYW5zbGF0ZVRvKGNsYXNzR2VuLCBtZXRob2RHZW4sIChOb2RlU2V0VHlwZSkgdHlwZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAodHlwZSA9PSBUeXBlLlJlZmVyZW5jZSkgewotICAgICAgICAgICAgdHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgKFJlZmVyZW5jZVR5cGUpIHR5cGUpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKHR5cGUgPT0gVHlwZS5PYmplY3QpIHsKLSAgICAgICAgICAgIHRyYW5zbGF0ZVRvKGNsYXNzR2VuLCBtZXRob2RHZW4sIChPYmplY3RUeXBlKSB0eXBlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIEVycm9yTXNnIGVyciA9IG5ldyBFcnJvck1zZyhFcnJvck1zZy5EQVRBX0NPTlZFUlNJT05fRVJSLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvU3RyaW5nKCksIHR5cGUudG9TdHJpbmcoKSk7Ci0gICAgICAgICAgICBjbGFzc0dlbi5nZXRQYXJzZXIoKS5yZXBvcnRFcnJvcihDb25zdGFudHMuRkFUQUwsIGVycik7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBFeHBlY3RzIGEgbm9kZSBvbiB0aGUgc3RhY2sgYW5kIHB1c2hlcyBpdHMgc3RyaW5nIHZhbHVlLgotICAgICAqCi0gICAgICogQHNlZSAgICAgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZSN0cmFuc2xhdGVUbwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZVRvKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1R5cGUgdHlwZSkgewotICAgICAgICBmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQotICAgICAgICBzd2l0Y2ggKF90eXBlKSB7Ci0gICAgICAgIGNhc2UgTm9kZVRlc3QuUk9PVDoKLSAgICAgICAgY2FzZSBOb2RlVGVzdC5FTEVNRU5UOgotICAgICAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkRE9NKCkpOwotICAgICAgICAgICAgaWwuYXBwZW5kKFNXQVApOyAvLyBkb20gcmVmIG11c3QgYmUgYmVsb3cgbm9kZSBpbmRleAotICAgICAgICAgICAgaW50IGluZGV4ID0gY3BnLmFkZEludGVyZmFjZU1ldGhvZHJlZihET01fSU5URiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR0VUX0VMRU1FTlRfVkFMVUUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdFVF9FTEVNRU5UX1ZBTFVFX1NJRyk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRUlOVEVSRkFDRShpbmRleCwgMikpOwotICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgY2FzZSBOb2RlVGVzdC5BTk9ERToKLSAgICAgICAgY2FzZSBOb2RlVGVzdC5DT01NRU5UOgotICAgICAgICBjYXNlIE5vZGVUZXN0LkFUVFJJQlVURToKLSAgICAgICAgY2FzZSBOb2RlVGVzdC5QSToKLSAgICAgICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChTV0FQKTsgLy8gZG9tIHJlZiBtdXN0IGJlIGJlbG93IG5vZGUgaW5kZXgKLSAgICAgICAgICAgIGluZGV4ID0gY3BnLmFkZEludGVyZmFjZU1ldGhvZHJlZihET01fSU5URiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHRVRfTk9ERV9WQUxVRSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHRVRfTk9ERV9WQUxVRV9TSUcpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0UoaW5kZXgsIDIpKTsKLSAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgIGRlZmF1bHQ6Ci0gICAgICAgICAgICBFcnJvck1zZyBlcnIgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuREFUQV9DT05WRVJTSU9OX0VSUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b1N0cmluZygpLCB0eXBlLnRvU3RyaW5nKCkpOwotICAgICAgICAgICAgY2xhc3NHZW4uZ2V0UGFyc2VyKCkucmVwb3J0RXJyb3IoQ29uc3RhbnRzLkZBVEFMLCBlcnIpOwotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGVzIGEgbm9kZSBpbnRvIGEgc3ludGhlc2l6ZWQgYm9vbGVhbi4KLSAgICAgKiBJZiB0aGUgZXhwcmVzc2lvbiBpcyAiQGF0dHIiLAotICAgICAqIHRoZW4gInRydWUiIGlzIHB1c2hlZCBpZmYgImF0dHIiIGlzIGFuIGF0dHJpYnV0ZSBvZiB0aGUgY3VycmVudCBub2RlLgotICAgICAqIElmIHRoZSBleHByZXNzaW9uIGlzICIuIiwgdGhlIHJlc3VsdCBpcyBhbHdheXMgInRydWUiLgotICAgICAqCi0gICAgICogQHNlZSAgICAgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZSN0cmFuc2xhdGVUbwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZVRvKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJvb2xlYW5UeXBlIHR5cGUpIHsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotICAgICAgICBGbG93TGlzdCBmYWxzZWwgPSB0cmFuc2xhdGVUb0Rlc3ludGhlc2l6ZWQoY2xhc3NHZW4sIG1ldGhvZEdlbiwgdHlwZSk7Ci0gICAgICAgIGlsLmFwcGVuZChJQ09OU1RfMSk7Ci0gICAgICAgIGZpbmFsIEJyYW5jaEhhbmRsZSB0cnVlYyA9IGlsLmFwcGVuZChuZXcgR09UTyhudWxsKSk7Ci0gICAgICAgIGZhbHNlbC5iYWNrUGF0Y2goaWwuYXBwZW5kKElDT05TVF8wKSk7Ci0gICAgICAgIHRydWVjLnNldFRhcmdldChpbC5hcHBlbmQoTk9QKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRXhwZWN0cyBhIG5vZGUgb24gdGhlIHN0YWNrIGFuZCBwdXNoZXMgYSByZWFsLgotICAgICAqIEZpcnN0IHRoZSBub2RlIGlzIGNvbnZlcnRlZCB0byBzdHJpbmcsIGFuZCBmcm9tIHN0cmluZyB0byByZWFsLgotICAgICAqCi0gICAgICogQHNlZSAgICAgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZSN0cmFuc2xhdGVUbwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZVRvKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlYWxUeXBlIHR5cGUpIHsKLSAgICAgICAgdHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgVHlwZS5TdHJpbmcpOwotICAgICAgICBUeXBlLlN0cmluZy50cmFuc2xhdGVUbyhjbGFzc0dlbiwgbWV0aG9kR2VuLCBUeXBlLlJlYWwpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEV4cGVjdHMgYSBub2RlIG9uIHRoZSBzdGFjayBhbmQgcHVzaGVzIGEgc2luZ2xldG9uIG5vZGUtc2V0LiBTaW5nbGV0b24KLSAgICAgKiBpdGVyYXRvcnMgYXJlIGFscmVhZHkgc3RhcnRlZCBhZnRlciBjb25zdHJ1Y3Rpb24uCi0gICAgICoKLSAgICAgKiBAc2VlICAgICBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlI3RyYW5zbGF0ZVRvCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlVG8oQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgTm9kZVNldFR5cGUgdHlwZSkgewotICAgICAgICBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgICAgIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQotICAgICAgICAvLyBDcmVhdGUgYSBuZXcgaW5zdGFuY2Ugb2YgU2luZ2xldG9uSXRlcmF0b3IKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBORVcoY3BnLmFkZENsYXNzKFNJTkdMRVRPTl9JVEVSQVRPUikpKTsKLSAgICAgICAgaWwuYXBwZW5kKERVUF9YMSk7Ci0gICAgICAgIGlsLmFwcGVuZChTV0FQKTsKLSAgICAgICAgZmluYWwgaW50IGluaXQgPSBjcGcuYWRkTWV0aG9kcmVmKFNJTkdMRVRPTl9JVEVSQVRPUiwgIjxpbml0PiIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKCIgKyBOT0RFX1NJRyArIilWIik7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFU1BFQ0lBTChpbml0KSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU3Vic3VtZSBOb2RlIGludG8gT2JqZWN0VHlwZS4KLSAgICAgKgotICAgICAqIEBzZWUgICAgIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGUjdHJhbnNsYXRlVG8KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVUbyhDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBPYmplY3RUeXBlIHR5cGUpIHsKLSAgICAgICAgICAgIG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKS5hcHBlbmQoTk9QKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGVzIGEgbm9kZSBpbnRvIGEgbm9uLXN5bnRoZXNpemVkIGJvb2xlYW4uIEl0IGRvZXMgbm90IHB1c2ggYQotICAgICAqIDAgb3IgYSAxIGJ1dCBpbnN0ZWFkIHJldHVybnMgYnJhbmNoaGFuZGxlIGxpc3QgdG8gYmUgYXBwZW5kZWQgdG8gdGhlCi0gICAgICogZmFsc2UgbGlzdC4KLSAgICAgKgotICAgICAqIEBzZWUgICAgIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGUjdHJhbnNsYXRlVG9EZXN5bnRoZXNpemVkCi0gICAgICovCi0gICAgcHVibGljIEZsb3dMaXN0IHRyYW5zbGF0ZVRvRGVzeW50aGVzaXplZChDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCb29sZWFuVHlwZSB0eXBlKSB7Ci0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLSAgICAgICAgcmV0dXJuIG5ldyBGbG93TGlzdChpbC5hcHBlbmQobmV3IElGRVEobnVsbCkpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBFeHBlY3RzIGEgbm9kZSBvbiB0aGUgc3RhY2sgYW5kIHB1c2hlcyBhIGJveGVkIG5vZGUuIEJveGVkIG5vZGVzCi0gICAgICogYXJlIHJlcHJlc2VudGVkIGJ5IGFuIGluc3RhbmNlIG9mIDxjb2RlPmNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5kb20uTm9kZTwvY29kZT4uCi0gICAgICoKLSAgICAgKiBAc2VlICAgICBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlI3RyYW5zbGF0ZVRvCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlVG8oQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVmZXJlbmNlVHlwZSB0eXBlKSB7Ci0gICAgICAgIGZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotICAgICAgICBpbC5hcHBlbmQobmV3IE5FVyhjcGcuYWRkQ2xhc3MoUlVOVElNRV9OT0RFX0NMQVNTKSkpOwotICAgICAgICBpbC5hcHBlbmQoRFVQX1gxKTsKLSAgICAgICAgaWwuYXBwZW5kKFNXQVApOwotICAgICAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBfdHlwZSkpOwotICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRVNQRUNJQUwoY3BnLmFkZE1ldGhvZHJlZihSVU5USU1FX05PREVfQ0xBU1MsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI8aW5pdD4iLCAiKElJKVYiKSkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZXMgYSBub2RlIGludG8gdGhlIEphdmEgdHlwZSBkZW5vdGVkIGJ5IDxjb2RlPmNsYXp6PC9jb2RlPi4KLSAgICAgKiBFeHBlY3RzIGEgbm9kZSBvbiB0aGUgc3RhY2sgYW5kIHB1c2hlcyBhbiBvYmplY3Qgb2YgdGhlIGFwcHJvcHJpYXRlCi0gICAgICogdHlwZSBhZnRlciBjb2VyY2lvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVUbyhDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBDbGFzcyBjbGF6eikgewotICAgICAgICBmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQotICAgICAgICBTdHJpbmcgY2xhc3NOYW1lID0gY2xhenouZ2V0TmFtZSgpOwotICAgICAgICBpZiAoY2xhc3NOYW1lLmVxdWFscygiamF2YS5sYW5nLlN0cmluZyIpKSB7Ci0gICAgICAgICAgIHRyYW5zbGF0ZVRvKGNsYXNzR2VuLCBtZXRob2RHZW4sIFR5cGUuU3RyaW5nKTsKLSAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0KLSAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkRE9NKCkpOwotICAgICAgICBpbC5hcHBlbmQoU1dBUCk7ICAgICAgICAgICAgICAgIC8vIGRvbSByZWYgbXVzdCBiZSBiZWxvdyBub2RlIGluZGV4Ci0KLSAgICAgICAgaWYgKGNsYXNzTmFtZS5lcXVhbHMoIm9yZy53M2MuZG9tLk5vZGUiKSB8fAotICAgICAgICAgICAgY2xhc3NOYW1lLmVxdWFscygiamF2YS5sYW5nLk9iamVjdCIpKSB7Ci0gICAgICAgICAgICBpbnQgaW5kZXggPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKERPTV9JTlRGLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNQUtFX05PREUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1BS0VfTk9ERV9TSUcpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0UoaW5kZXgsIDIpKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChjbGFzc05hbWUuZXF1YWxzKCJvcmcudzNjLmRvbS5Ob2RlTGlzdCIpKSB7Ci0gICAgICAgICAgICBpbnQgaW5kZXggPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKERPTV9JTlRGLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNQUtFX05PREVfTElTVCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTUFLRV9OT0RFX0xJU1RfU0lHKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFSU5URVJGQUNFKGluZGV4LCAyKSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBFcnJvck1zZyBlcnIgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuREFUQV9DT05WRVJTSU9OX0VSUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b1N0cmluZygpLCBjbGFzc05hbWUpOwotICAgICAgICAgICAgY2xhc3NHZW4uZ2V0UGFyc2VyKCkucmVwb3J0RXJyb3IoQ29uc3RhbnRzLkZBVEFMLCBlcnIpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhbnNsYXRlcyBhbiBvYmplY3Qgb2YgdGhpcyB0eXBlIHRvIGl0cyBib3hlZCByZXByZXNlbnRhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVCb3goQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLSAgICAgICAgdHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgVHlwZS5SZWZlcmVuY2UpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZXMgYW4gb2JqZWN0IG9mIHRoaXMgdHlwZSB0byBpdHMgdW5ib3hlZCByZXByZXNlbnRhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVVbkJveChDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0gICAgICAgIGZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotICAgICAgICBpbC5hcHBlbmQobmV3IENIRUNLQ0FTVChjcGcuYWRkQ2xhc3MoUlVOVElNRV9OT0RFX0NMQVNTKSkpOwotICAgICAgICBpbC5hcHBlbmQobmV3IEdFVEZJRUxEKGNwZy5hZGRGaWVsZHJlZihSVU5USU1FX05PREVfQ0xBU1MsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5PREVfRklFTEQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5PREVfRklFTERfU0lHKSkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIGNsYXNzIG5hbWUgb2YgYW4gaW50ZXJuYWwgdHlwZSdzIGV4dGVybmFsIHJlcHJlc2VudGF0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q2xhc3NOYW1lKCkgewotICAgICAgICByZXR1cm4oUlVOVElNRV9OT0RFX0NMQVNTKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb24gTE9BRChpbnQgc2xvdCkgewotICAgICAgICByZXR1cm4gbmV3IElMT0FEKHNsb3QpOwotICAgIH0KLQotICAgIHB1YmxpYyBJbnN0cnVjdGlvbiBTVE9SRShpbnQgc2xvdCkgewotICAgICAgICByZXR1cm4gbmV3IElTVE9SRShzbG90KTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL3V0aWwvTnVtYmVyVHlwZS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci91dGlsL051bWJlclR5cGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYzUwZTE1My4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL3V0aWwvTnVtYmVyVHlwZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzkgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogTnVtYmVyVHlwZS5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzA1IDExOjI1OjExIHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsOwotCi0KLS8qKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICovCi1wdWJsaWMgYWJzdHJhY3QgY2xhc3MgTnVtYmVyVHlwZSBleHRlbmRzIFR5cGUgewotICAgIHB1YmxpYyBib29sZWFuIGlzTnVtYmVyKCkgewotICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBpc1NpbXBsZSgpIHsKLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci91dGlsL09iamVjdFR5cGUuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvdXRpbC9PYmplY3RUeXBlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDIwNmI1OWUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci91dGlsL09iamVjdFR5cGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE3OSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBPYmplY3RUeXBlLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTIgMTE6NDU6NTQgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWw7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkFMT0FEOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQVNUT1JFOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQnJhbmNoSGFuZGxlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQ29uc3RhbnRQb29sR2VuOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuR09UTzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklGTlVMTDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklOVk9LRVZJUlRVQUw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JbnN0cnVjdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uTGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlBVU0g7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLkNvbnN0YW50czsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwudXRpbHMuT2JqZWN0RmFjdG9yeTsKLQotLyoqCi0gKiBAYXV0aG9yIFRvZGQgTWlsbGVyCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIE9iamVjdFR5cGUgZXh0ZW5kcyBUeXBlIHsKLQotICAgIHByaXZhdGUgU3RyaW5nIF9qYXZhQ2xhc3NOYW1lID0gImphdmEubGFuZy5PYmplY3QiOwotICAgIHByaXZhdGUgQ2xhc3MgIF9jbGF6eiA9IGphdmEubGFuZy5PYmplY3QuY2xhc3M7Ci0KLSAgICAvKioKLSAgICAgKiBVc2VkIHRvIHJlcHJlc2VudCBhIEphdmEgQ2xhc3MgdHlwZSBzdWNoIGlzIHJlcXVpcmVkIHRvIHN1cHBvcnQKLSAgICAgKiBub24tc3RhdGljIGphdmEgZnVuY3Rpb25zLgotICAgICAqIEBwYXJhbSBqYXZhQ2xhc3NOYW1lIG5hbWUgb2YgdGhlIGNsYXNzIHN1Y2ggYXMgJ2NvbS5mb28uUHJvY2Vzc29yJwotICAgICAqLwotICAgIHByb3RlY3RlZCBPYmplY3RUeXBlKFN0cmluZyBqYXZhQ2xhc3NOYW1lKSB7Ci0gICAgICAgIF9qYXZhQ2xhc3NOYW1lID0gamF2YUNsYXNzTmFtZTsKLQotICAgICAgICB0cnkgewotICAgICAgICAgIF9jbGF6eiA9IE9iamVjdEZhY3RvcnkuZmluZFByb3ZpZGVyQ2xhc3MoamF2YUNsYXNzTmFtZSwgdHJ1ZSk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gZSkgewotICAgICAgICAgIF9jbGF6eiA9IG51bGw7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwcm90ZWN0ZWQgT2JqZWN0VHlwZShDbGFzcyBjbGF6eikgewotICAgICAgICBfY2xhenogPSBjbGF6ejsKLSAgICAgICAgX2phdmFDbGFzc05hbWUgPSBjbGF6ei5nZXROYW1lKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogTXVzdCByZXR1cm4gdGhlIHNhbWUgdmFsdWUgZm9yIGFsbCBPYmplY3RUeXBlIGluc3RhbmNlcy4gVGhpcyBpcwotICAgICAqIG5lZWRlZCBpbiBDYXN0RXhwciB0byBlbnN1cmUgdGhlIG1hcHBpbmcgdGFibGUgaXMgdXNlZCBjb3JyZWN0bHkuCi0gICAgICovCi0gICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKLSAgICAgICAgcmV0dXJuIGphdmEubGFuZy5PYmplY3QuY2xhc3MuaGFzaENvZGUoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaikgewotICAgICAgICByZXR1cm4gKG9iaiBpbnN0YW5jZW9mIE9iamVjdFR5cGUpOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0SmF2YUNsYXNzTmFtZSgpIHsKLSAgICAgICAgcmV0dXJuIF9qYXZhQ2xhc3NOYW1lOwotICAgIH0KLQotICAgIHB1YmxpYyBDbGFzcyBnZXRKYXZhQ2xhc3MoKSB7Ci0gICAgICAgIHJldHVybiBfY2xheno7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKLSAgICAgICAgcmV0dXJuIF9qYXZhQ2xhc3NOYW1lOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGlkZW50aWNhbFRvKFR5cGUgb3RoZXIpIHsKLSAgICAgICAgcmV0dXJuIHRoaXMgPT0gb3RoZXI7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyB0b1NpZ25hdHVyZSgpIHsKLSAgICAgICAgZmluYWwgU3RyaW5nQnVmZmVyIHJlc3VsdCA9IG5ldyBTdHJpbmdCdWZmZXIoIkwiKTsKLSAgICAgICAgcmVzdWx0LmFwcGVuZChfamF2YUNsYXNzTmFtZS5yZXBsYWNlKCcuJywgJy8nKSkuYXBwZW5kKCc7Jyk7Ci0gICAgICAgIHJldHVybiByZXN1bHQudG9TdHJpbmcoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5UeXBlIHRvSkNUeXBlKCkgewotICAgICAgICByZXR1cm4gVXRpbC5nZXRKQ1JlZlR5cGUodG9TaWduYXR1cmUoKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhbnNsYXRlcyBhIHZvaWQgaW50byBhbiBvYmplY3Qgb2YgaW50ZXJuYWwgdHlwZSA8Y29kZT50eXBlPC9jb2RlPi4KLSAgICAgKiBUaGlzIHRyYW5zbGF0aW9uIGlzIG5lZWRlZCB3aGVuIGNhbGxpbmcgZXh0ZXJuYWwgZnVuY3Rpb25zCi0gICAgICogdGhhdCByZXR1cm4gdm9pZC4KLSAgICAgKgotICAgICAqIEBzZWUgICAgIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGUjdHJhbnNsYXRlVG8KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVUbyhDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlIHR5cGUpIHsKLSAgICAgICAgaWYgKHR5cGUgPT0gVHlwZS5TdHJpbmcpIHsKLSAgICAgICAgICAgIHRyYW5zbGF0ZVRvKGNsYXNzR2VuLCBtZXRob2RHZW4sIChTdHJpbmdUeXBlKSB0eXBlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIEVycm9yTXNnIGVyciA9IG5ldyBFcnJvck1zZyhFcnJvck1zZy5EQVRBX0NPTlZFUlNJT05fRVJSLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvU3RyaW5nKCksIHR5cGUudG9TdHJpbmcoKSk7Ci0gICAgICAgICAgICBjbGFzc0dlbi5nZXRQYXJzZXIoKS5yZXBvcnRFcnJvcihDb25zdGFudHMuRkFUQUwsIGVycik7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBFeHBlY3RzIGFuIGludGVnZXIgb24gdGhlIHN0YWNrIGFuZCBwdXNoZXMgaXRzIHN0cmluZyB2YWx1ZSBieSBjYWxsaW5nCi0gICAgICogPGNvZGU+SW50ZWdlci50b1N0cmluZyhpbnQgaSk8L2NvZGU+LgotICAgICAqCi0gICAgICogQHNlZSAgICAgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZSN0cmFuc2xhdGVUbwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZVRvKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1R5cGUgdHlwZSkgewotICAgICAgICBmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQotICAgICAgICBpbC5hcHBlbmQoRFVQKTsKLSAgICAgICAgZmluYWwgQnJhbmNoSGFuZGxlIGlmTnVsbCA9IGlsLmFwcGVuZChuZXcgSUZOVUxMKG51bGwpKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VWSVJUVUFMKGNwZy5hZGRNZXRob2RyZWYoX2phdmFDbGFzc05hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRvU3RyaW5nIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKCkiICsgU1RSSU5HX1NJRykpKTsKLSAgICAgICAgZmluYWwgQnJhbmNoSGFuZGxlIGdvdG9iaCA9IGlsLmFwcGVuZChuZXcgR09UTyhudWxsKSk7Ci0gICAgICAgIGlmTnVsbC5zZXRUYXJnZXQoaWwuYXBwZW5kKFBPUCkpOwotICAgICAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCAiIikpOwotICAgICAgICBnb3RvYmguc2V0VGFyZ2V0KGlsLmFwcGVuZChOT1ApKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGVzIGFuIG9iamVjdCBvZiB0aGlzIHR5cGUgdG8gdGhlIGV4dGVybmFsIChKYXZhKSB0eXBlIGRlbm90ZWQKLSAgICAgKiBieSA8Y29kZT5jbGF6ejwvY29kZT4uIFRoaXMgbWV0aG9kIGlzIHVzZWQgdG8gdHJhbnNsYXRlIHBhcmFtZXRlcnMKLSAgICAgKiB3aGVuIGV4dGVybmFsIGZ1bmN0aW9ucyBhcmUgY2FsbGVkLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZVRvKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIENsYXNzIGNsYXp6KSB7Ci0gICAgICAgIGlmIChjbGF6ei5pc0Fzc2lnbmFibGVGcm9tKF9jbGF6eikpCi0gICAgICAgICAgICBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCkuYXBwZW5kKE5PUCk7Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgRXJyb3JNc2cgZXJyID0gbmV3IEVycm9yTXNnKEVycm9yTXNnLkRBVEFfQ09OVkVSU0lPTl9FUlIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG9TdHJpbmcoKSwgY2xhenouZ2V0Q2xhc3MoKS50b1N0cmluZygpKTsKLSAgICAgICAgICAgIGNsYXNzR2VuLmdldFBhcnNlcigpLnJlcG9ydEVycm9yKENvbnN0YW50cy5GQVRBTCwgZXJyKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZXMgYW4gZXh0ZXJuYWwgSmF2YSB0eXBlIGludG8gYW4gT2JqZWN0IHR5cGUKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVGcm9tKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwgQ2xhc3MgY2xhenopIHsKLSAgICAgICAgbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpLmFwcGVuZChOT1ApOwotICAgIH0KLQotICAgIHB1YmxpYyBJbnN0cnVjdGlvbiBMT0FEKGludCBzbG90KSB7Ci0gICAgICAgIHJldHVybiBuZXcgQUxPQUQoc2xvdCk7Ci0gICAgfQotCi0gICAgcHVibGljIEluc3RydWN0aW9uIFNUT1JFKGludCBzbG90KSB7Ci0gICAgICAgIHJldHVybiBuZXcgQVNUT1JFKHNsb3QpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvdXRpbC9PdXRsaW5lYWJsZUNodW5rRW5kLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL3V0aWwvT3V0bGluZWFibGVDaHVua0VuZC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiMmRhZmYzLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvdXRpbC9PdXRsaW5lYWJsZUNodW5rRW5kLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3MCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLS8qCi0gKiAkSWQ6IE91dGxpbmVhYmxlQ2h1bmtFbmQuamF2YSx2IDEuMTAgMjAxMC0xMS0wMSAwNDozNDoxOSBqb2VodyBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW5zdHJ1Y3Rpb247Ci0vKioKLSAqIDxwPk1hcmtzIHRoZSBlbmQgb2YgYSByZWdpb24gb2YgYnl0ZSBjb2RlIHRoYXQgY2FuIGJlIGNvcGllZCBpbnRvIGEgbmV3Ci0gKiBtZXRob2QuICBTZWUgdGhlIHtAbGluayBPdXRsaW5lYWJsZUNodW5rU3RhcnR9IHBzZXVkby1pbnN0cnVjdGlvbiBmb3IKLSAqIGRldGFpbHMuPC9wPgotICovCi1jbGFzcyBPdXRsaW5lYWJsZUNodW5rRW5kIGV4dGVuZHMgTWFya2VySW5zdHJ1Y3Rpb24gewotICAgIC8qKgotICAgICAqIEEgY29uc3RhbnQgaW5zdGFuY2Ugb2Yge0BsaW5rIE91dGxpbmVhYmxlQ2h1bmtFbmR9LiAgQXMgaXQgaGFzIG5vIGZpZWxkcywKLSAgICAgKiB0aGVyZSBzaG91bGQgYmUgbm8gbmVlZCB0byBjcmVhdGUgYW4gaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcy4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEluc3RydWN0aW9uIE9VVExJTkVBQkxFQ0hVTktFTkQgPQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE91dGxpbmVhYmxlQ2h1bmtFbmQoKTsKLQotICAgIC8qKgotICAgICAqIFByaXZhdGUgZGVmYXVsdCBjb25zdHJ1Y3Rvci4gIEFzIGl0IGhhcyBubyBmaWVsZHMsCi0gICAgICogdGhlcmUgc2hvdWxkIGJlIG5vIG5lZWQgdG8gY3JlYXRlIGFuIGluc3RhbmNlIG9mIHRoaXMgY2xhc3MuICBTZWUKLSAgICAgKiB7QGxpbmsgT3V0bGluZWFibGVDaHVua0VuZCNPVVRMSU5FQUJMRUNIVU5LRU5EfS4KLSAgICAgKi8KLSAgICBwcml2YXRlIE91dGxpbmVhYmxlQ2h1bmtFbmQoKSB7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBuYW1lIG9mIHRoaXMgaW5zdHJ1Y3Rpb24uICBVc2VkIGZvciBkZWJ1Z2dpbmcuCi0gICAgICogQHJldHVybiB0aGUgaW5zdHJ1Y3Rpb24gbmFtZQotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpIHsKLSAgICAgICAgcmV0dXJuIE91dGxpbmVhYmxlQ2h1bmtFbmQuY2xhc3MuZ2V0TmFtZSgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgbmFtZSBvZiB0aGlzIGluc3RydWN0aW9uLiAgVXNlZCBmb3IgZGVidWdnaW5nLgotICAgICAqIEByZXR1cm4gdGhlIGluc3RydWN0aW9uIG5hbWUKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgICAgICByZXR1cm4gZ2V0TmFtZSgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgbmFtZSBvZiB0aGlzIGluc3RydWN0aW9uLiAgVXNlZCBmb3IgZGVidWdnaW5nLgotICAgICAqIEByZXR1cm4gdGhlIGluc3RydWN0aW9uIG5hbWUKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKGJvb2xlYW4gdmVyYm9zZSkgewotICAgICAgICByZXR1cm4gZ2V0TmFtZSgpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvdXRpbC9PdXRsaW5lYWJsZUNodW5rU3RhcnQuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvdXRpbC9PdXRsaW5lYWJsZUNodW5rU3RhcnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOWI1NGNhYy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL3V0aWwvT3V0bGluZWFibGVDaHVua1N0YXJ0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4MCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLS8qCi0gKiAkSWQ6IE1ldGhvZEdlbmVyYXRvci5qYXZhLHYgMS4xMCAyMDEwLTExLTAxIDA0OjM0OjE5IGpvZWh3IEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JbnN0cnVjdGlvbjsKLQotLyoqCi0gKiA8cD5UaGlzIHBzZXVkby1pbnN0cnVjdGlvbiBtYXJrcyB0aGUgYmVnaW5uaW5nIG9mIGEgcmVnaW9uIG9mIGJ5dGUgY29kZSB0aGF0Ci0gKiBjYW4gYmUgY29waWVkIGludG8gYSBuZXcgbWV0aG9kLCB0ZXJtZWQgYW4gIm91dGxpbmVhYmxlIiBjaHVuay4gIFRoZSBzaXplIG9mCi0gKiB0aGUgSmF2YSBzdGFjayBtdXN0IGJlIHRoZSBzYW1lIGF0IHRoZSBzdGFydCBvZiB0aGUgcmVnaW9uIGFzIGl0IGlzIGF0IHRoZQotICogZW5kIG9mIHRoZSByZWdpb24sIGFueSB2YWx1ZSBvbiB0aGUgc3RhY2sgYXQgdGhlIHN0YXJ0IG9mIHRoZSByZWdpb24gbXVzdCBub3QKLSAqIGJlIGNvbnN1bWVkIGJ5IGFuIGluc3RydWN0aW9uIGluIHRoZSByZWdpb24gb2YgY29kZSwgdGhlIHJlZ2lvbiBtdXN0IG5vdAotICogY29udGFpbiBhIHJldHVybiBpbnN0cnVjdGlvbiwgbm8gYnJhbmNoIGluc3RydWN0aW9uIGluIHRoZSByZWdpb24gaXMKLSAqIHBlcm1pdHRlZCB0byBoYXZlIGEgdGFyZ2V0IHRoYXQgaXMgb3V0c2lkZSB0aGUgcmVnaW9uLCBhbmQgbm8gYnJhbmNoCi0gKiBpbnN0cnVjdGlvbiBvdXRzaWRlIHRoZSByZWdpb24gaXMgcGVybWl0dGVkIHRvIGhhdmUgYSB0YXJnZXQgdGhhdCBpcyBpbnNpZGUKLSAqIHRoZSByZWdpb24uPC9wPgotICogPHA+VGhlIGVuZCBvZiB0aGUgcmVnaW9uIGlzIG1hcmtlZCBieSBhbiB7QGxpbmsgT3V0bGluZWFibGVDaHVua0VuZH0KLSAqIHBzZXVkby1pbnN0cnVjdGlvbi48L3A+Ci0gKiA8cD5TdWNoIGEgcmVnaW9uIG9mIGNvZGUgbWF5IGNvbnRhaW4gb3RoZXIgb3V0bGluZWFibGUgcmVnaW9ucy48L3A+Ci0gKi8KLWNsYXNzIE91dGxpbmVhYmxlQ2h1bmtTdGFydCBleHRlbmRzIE1hcmtlckluc3RydWN0aW9uIHsKLSAgICAvKioKLSAgICAgKiBBIGNvbnN0YW50IGluc3RhbmNlIG9mIHtAbGluayBPdXRsaW5lYWJsZUNodW5rU3RhcnR9LiAgQXMgaXQgaGFzIG5vIGZpZWxkcywKLSAgICAgKiB0aGVyZSBzaG91bGQgYmUgbm8gbmVlZCB0byBjcmVhdGUgYW4gaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcy4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEluc3RydWN0aW9uIE9VVExJTkVBQkxFQ0hVTktTVEFSVCA9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT3V0bGluZWFibGVDaHVua1N0YXJ0KCk7Ci0KLSAgICAvKioKLSAgICAgKiBQcml2YXRlIGRlZmF1bHQgY29uc3RydWN0b3IuICBBcyBpdCBoYXMgbm8gZmllbGRzLAotICAgICAqIHRoZXJlIHNob3VsZCBiZSBubyBuZWVkIHRvIGNyZWF0ZSBhbiBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzLiAgU2VlCi0gICAgICoge0BsaW5rIE91dGxpbmVhYmxlQ2h1bmtTdGFydCNPVVRMSU5FQUJMRUNIVU5LU1RBUlR9LgotICAgICAqLwotICAgIHByaXZhdGUgT3V0bGluZWFibGVDaHVua1N0YXJ0KCkgewotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgbmFtZSBvZiB0aGlzIGluc3RydWN0aW9uLiAgVXNlZCBmb3IgZGVidWdnaW5nLgotICAgICAqIEByZXR1cm4gdGhlIGluc3RydWN0aW9uIG5hbWUKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKSB7Ci0gICAgICAgIHJldHVybiBPdXRsaW5lYWJsZUNodW5rU3RhcnQuY2xhc3MuZ2V0TmFtZSgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgbmFtZSBvZiB0aGlzIGluc3RydWN0aW9uLiAgVXNlZCBmb3IgZGVidWdnaW5nLgotICAgICAqIEByZXR1cm4gdGhlIGluc3RydWN0aW9uIG5hbWUKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgICAgICByZXR1cm4gZ2V0TmFtZSgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgbmFtZSBvZiB0aGlzIGluc3RydWN0aW9uLiAgVXNlZCBmb3IgZGVidWdnaW5nLgotICAgICAqIEByZXR1cm4gdGhlIGluc3RydWN0aW9uIG5hbWUKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKGJvb2xlYW4gdmVyYm9zZSkgewotICAgICAgICByZXR1cm4gZ2V0TmFtZSgpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvdXRpbC9SZWFsVHlwZS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci91dGlsL1JlYWxUeXBlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGY3MGEyMTAuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci91dGlsL1JlYWxUeXBlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzNDMgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogUmVhbFR5cGUuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8wNSAxMToyODo0NSBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbDsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQnJhbmNoSGFuZGxlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQ0hFQ0tDQVNUOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQ29uc3RhbnRQb29sR2VuOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuRExPQUQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5EU1RPUkU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5HT1RPOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSUZFUTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklGTkU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JTlZPS0VTUEVDSUFMOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFU1RBVElDOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFVklSVFVBTDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW5zdHJ1Y3Rpb25Db25zdGFudHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JbnN0cnVjdGlvbkxpc3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5Mb2NhbFZhcmlhYmxlR2VuOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuTkVXOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci5Db25zdGFudHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLkZsb3dMaXN0OwotCi0vKioKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIFJlYWxUeXBlIGV4dGVuZHMgTnVtYmVyVHlwZSB7Ci0gICAgcHJvdGVjdGVkIFJlYWxUeXBlKCkge30KLQotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0gICAgICAgIHJldHVybiAicmVhbCI7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gaWRlbnRpY2FsVG8oVHlwZSBvdGhlcikgewotICAgICAgICByZXR1cm4gdGhpcyA9PSBvdGhlcjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIHRvU2lnbmF0dXJlKCkgewotICAgICAgICByZXR1cm4gIkQiOwotICAgIH0KLQotICAgIHB1YmxpYyBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlR5cGUgdG9KQ1R5cGUoKSB7Ci0gICAgICAgIHJldHVybiBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlR5cGUuRE9VQkxFOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgICAgIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGUjZGlzdGFuY2VUbwotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZGlzdGFuY2VUbyhUeXBlIHR5cGUpIHsKLSAgICAgICAgaWYgKHR5cGUgPT0gdGhpcykgewotICAgICAgICAgICAgcmV0dXJuIDA7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAodHlwZSA9PSBUeXBlLkludCkgewotICAgICAgICAgICAgcmV0dXJuIDE7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gSW50ZWdlci5NQVhfVkFMVUU7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGVzIGEgcmVhbCBpbnRvIGFuIG9iamVjdCBvZiBpbnRlcm5hbCB0eXBlIDxjb2RlPnR5cGU8L2NvZGU+LiBUaGUKLSAgICAgKiB0cmFuc2xhdGlvbiB0byBpbnQgaXMgdW5kZWZpbmVkIHNpbmNlIHJlYWxzIGFyZSBuZXZlciBjb252ZXJ0ZWQgdG8gaW50cy4KLSAgICAgKgotICAgICAqIEBzZWUgICAgIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGUjdHJhbnNsYXRlVG8KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVUbyhDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlIHR5cGUpIHsKLSAgICAgICAgaWYgKHR5cGUgPT0gVHlwZS5TdHJpbmcpIHsKLSAgICAgICAgICAgIHRyYW5zbGF0ZVRvKGNsYXNzR2VuLCBtZXRob2RHZW4sIChTdHJpbmdUeXBlKSB0eXBlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICh0eXBlID09IFR5cGUuQm9vbGVhbikgewotICAgICAgICAgICAgdHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgKEJvb2xlYW5UeXBlKSB0eXBlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICh0eXBlID09IFR5cGUuUmVmZXJlbmNlKSB7Ci0gICAgICAgICAgICB0cmFuc2xhdGVUbyhjbGFzc0dlbiwgbWV0aG9kR2VuLCAoUmVmZXJlbmNlVHlwZSkgdHlwZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAodHlwZSA9PSBUeXBlLkludCkgewotICAgICAgICAgICAgdHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgKEludFR5cGUpIHR5cGUpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgRXJyb3JNc2cgZXJyID0gbmV3IEVycm9yTXNnKEVycm9yTXNnLkRBVEFfQ09OVkVSU0lPTl9FUlIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG9TdHJpbmcoKSwgdHlwZS50b1N0cmluZygpKTsKLSAgICAgICAgICAgIGNsYXNzR2VuLmdldFBhcnNlcigpLnJlcG9ydEVycm9yKENvbnN0YW50cy5GQVRBTCwgZXJyKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEV4cGVjdHMgYSByZWFsIG9uIHRoZSBzdGFjayBhbmQgcHVzaGVzIGl0cyBzdHJpbmcgdmFsdWUgYnkgY2FsbGluZwotICAgICAqIDxjb2RlPkRvdWJsZS50b1N0cmluZyhkb3VibGUgZCk8L2NvZGU+LgotICAgICAqCi0gICAgICogQHNlZSAgICAgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZSN0cmFuc2xhdGVUbwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZVRvKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1R5cGUgdHlwZSkgewotICAgICAgICBmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VTVEFUSUMoY3BnLmFkZE1ldGhvZHJlZihCQVNJU19MSUJSQVJZX0NMQVNTLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJyZWFsVG9TdHJpbmciLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoRCkiICsgU1RSSU5HX1NJRykpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBFeHBlY3RzIGEgcmVhbCBvbiB0aGUgc3RhY2sgYW5kIHB1c2hlcyBhIDAgaWYgdGhhdCBudW1iZXIgaXMgMC4wIGFuZAotICAgICAqIGEgMSBvdGhlcndpc2UuCi0gICAgICoKLSAgICAgKiBAc2VlICAgICBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlI3RyYW5zbGF0ZVRvCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlVG8oQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgQm9vbGVhblR5cGUgdHlwZSkgewotICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0gICAgICAgIEZsb3dMaXN0IGZhbHNlbCA9IHRyYW5zbGF0ZVRvRGVzeW50aGVzaXplZChjbGFzc0dlbiwgbWV0aG9kR2VuLCB0eXBlKTsKLSAgICAgICAgaWwuYXBwZW5kKElDT05TVF8xKTsKLSAgICAgICAgZmluYWwgQnJhbmNoSGFuZGxlIHRydWVjID0gaWwuYXBwZW5kKG5ldyBHT1RPKG51bGwpKTsKLSAgICAgICAgZmFsc2VsLmJhY2tQYXRjaChpbC5hcHBlbmQoSUNPTlNUXzApKTsKLSAgICAgICAgdHJ1ZWMuc2V0VGFyZ2V0KGlsLmFwcGVuZChOT1ApKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBFeHBlY3RzIGEgcmVhbCBvbiB0aGUgc3RhY2sgYW5kIHB1c2hlcyBhIHRydW5jYXRlZCBpbnRlZ2VyIHZhbHVlCi0gICAgICoKLSAgICAgKiBAc2VlICAgICBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlI3RyYW5zbGF0ZVRvCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlVG8oQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgSW50VHlwZSB0eXBlKSB7Ci0gICAgICAgIGZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRVNUQVRJQyhjcGcuYWRkTWV0aG9kcmVmKEJBU0lTX0xJQlJBUllfQ0xBU1MsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInJlYWxUb0ludCIsIihEKUkiKSkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZXMgYSByZWFsIGludG8gYSBub24tc3ludGhlc2l6ZWQgYm9vbGVhbi4gSXQgZG9lcyBub3QgcHVzaCBhCi0gICAgICogMCBvciBhIDEgYnV0IGluc3RlYWQgcmV0dXJucyBicmFuY2hoYW5kbGUgbGlzdCB0byBiZSBhcHBlbmRlZCB0byB0aGUKLSAgICAgKiBmYWxzZSBsaXN0LiBBIE5hTiBtdXN0IGJlIGNvbnZlcnRlZCB0byAiZmFsc2UiLgotICAgICAqCi0gICAgICogQHNlZSAgICAgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZSN0cmFuc2xhdGVUb0Rlc3ludGhlc2l6ZWQKLSAgICAgKi8KLSAgICBwdWJsaWMgRmxvd0xpc3QgdHJhbnNsYXRlVG9EZXN5bnRoZXNpemVkKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJvb2xlYW5UeXBlIHR5cGUpIHsKLSAgICAgICAgTG9jYWxWYXJpYWJsZUdlbiBsb2NhbDsKLSAgICAgICAgZmluYWwgRmxvd0xpc3QgZmxvd2xpc3QgPSBuZXcgRmxvd0xpc3QoKTsKLSAgICAgICAgZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0KLSAgICAgICAgLy8gU3RvcmUgcmVhbCBpbnRvIGEgbG9jYWwgdmFyaWFibGUKLSAgICAgICAgaWwuYXBwZW5kKERVUDIpOwotICAgICAgICBsb2NhbCA9IG1ldGhvZEdlbi5hZGRMb2NhbFZhcmlhYmxlKCJyZWFsX3RvX2Jvb2xlYW5fdG1wIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlR5cGUuRE9VQkxFLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsIG51bGwpOwotICAgICAgICBsb2NhbC5zZXRTdGFydChpbC5hcHBlbmQobmV3IERTVE9SRShsb2NhbC5nZXRJbmRleCgpKSkpOwotCi0gICAgICAgIC8vIENvbXBhcmUgaXQgdG8gMC4wCi0gICAgICAgIGlsLmFwcGVuZChEQ09OU1RfMCk7Ci0gICAgICAgIGlsLmFwcGVuZChEQ01QRyk7Ci0gICAgICAgIGZsb3dsaXN0LmFkZChpbC5hcHBlbmQobmV3IElGRVEobnVsbCkpKTsKLQotICAgICAgICAvLyEhISBjYWxsIGlzTmFOCi0gICAgICAgIC8vIENvbXBhcmUgaXQgdG8gaXRzZWxmIHRvIHNlZSBpZiBOYU4KLSAgICAgICAgaWwuYXBwZW5kKG5ldyBETE9BRChsb2NhbC5nZXRJbmRleCgpKSk7Ci0gICAgICAgIGxvY2FsLnNldEVuZChpbC5hcHBlbmQobmV3IERMT0FEKGxvY2FsLmdldEluZGV4KCkpKSk7Ci0gICAgICAgIGlsLmFwcGVuZChEQ01QRyk7Ci0gICAgICAgIGZsb3dsaXN0LmFkZChpbC5hcHBlbmQobmV3IElGTkUobnVsbCkpKTsgICAgICAgIC8vIE5hTiAhPSBOYU4KLSAgICAgICAgcmV0dXJuIGZsb3dsaXN0OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEV4cGVjdHMgYSBkb3VibGUgb24gdGhlIHN0YWNrIGFuZCBwdXNoZXMgYSBib3hlZCBkb3VibGUuIEJveGVkCi0gICAgICogZG91YmxlIGFyZSByZXByZXNlbnRlZCBieSBhbiBpbnN0YW5jZSBvZiA8Y29kZT5qYXZhLmxhbmcuRG91YmxlPC9jb2RlPi4KLSAgICAgKgotICAgICAqIEBzZWUgICAgIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGUjdHJhbnNsYXRlVG8KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVUbyhDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZWZlcmVuY2VUeXBlIHR5cGUpIHsKLSAgICAgICAgZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgTkVXKGNwZy5hZGRDbGFzcyhET1VCTEVfQ0xBU1MpKSk7Ci0gICAgICAgIGlsLmFwcGVuZChEVVBfWDIpOwotICAgICAgICBpbC5hcHBlbmQoRFVQX1gyKTsKLSAgICAgICAgaWwuYXBwZW5kKFBPUCk7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFU1BFQ0lBTChjcGcuYWRkTWV0aG9kcmVmKERPVUJMRV9DTEFTUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjxpbml0PiIsICIoRClWIikpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGVzIGEgcmVhbCBpbnRvIHRoZSBKYXZhIHR5cGUgZGVub3RlZCBieSA8Y29kZT5jbGF6ejwvY29kZT4uCi0gICAgICogRXhwZWN0cyBhIHJlYWwgb24gdGhlIHN0YWNrIGFuZCBwdXNoZXMgYSBudW1iZXIgb2YgdGhlIGFwcHJvcHJpYXRlCi0gICAgICogdHlwZSBhZnRlciBjb2VyY2lvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVUbyhDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBDbGFzcyBjbGF6eikgewotICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0gICAgICAgIGlmIChjbGF6eiA9PSBDaGFyYWN0ZXIuVFlQRSkgewotICAgICAgICAgICAgaWwuYXBwZW5kKEQySSk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQoSTJDKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChjbGF6eiA9PSBCeXRlLlRZUEUpIHsKLSAgICAgICAgICAgIGlsLmFwcGVuZChEMkkpOwotICAgICAgICAgICAgaWwuYXBwZW5kKEkyQik7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoY2xhenogPT0gU2hvcnQuVFlQRSkgewotICAgICAgICAgICAgaWwuYXBwZW5kKEQySSk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQoSTJTKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChjbGF6eiA9PSBJbnRlZ2VyLlRZUEUpIHsKLSAgICAgICAgICAgIGlsLmFwcGVuZChEMkkpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKGNsYXp6ID09IExvbmcuVFlQRSkgewotICAgICAgICAgICAgaWwuYXBwZW5kKEQyTCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoY2xhenogPT0gRmxvYXQuVFlQRSkgewotICAgICAgICAgICAgaWwuYXBwZW5kKEQyRik7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoY2xhenogPT0gRG91YmxlLlRZUEUpIHsKLSAgICAgICAgICAgIGlsLmFwcGVuZChOT1ApOwotICAgICAgICB9Ci0gICAgICAgIC8vIElzIERvdWJsZSA8OiBjbGF6ej8gSS5lLiBjbGF6eiBpbiB7IERvdWJsZSwgTnVtYmVyLCBPYmplY3QgfQotICAgICAgICBlbHNlIGlmIChjbGF6ei5pc0Fzc2lnbmFibGVGcm9tKGphdmEubGFuZy5Eb3VibGUuY2xhc3MpKSB7Ci0gICAgICAgICAgICB0cmFuc2xhdGVUbyhjbGFzc0dlbiwgbWV0aG9kR2VuLCBUeXBlLlJlZmVyZW5jZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBFcnJvck1zZyBlcnIgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuREFUQV9DT05WRVJTSU9OX0VSUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b1N0cmluZygpLCBjbGF6ei5nZXROYW1lKCkpOwotICAgICAgICAgICAgY2xhc3NHZW4uZ2V0UGFyc2VyKCkucmVwb3J0RXJyb3IoQ29uc3RhbnRzLkZBVEFMLCBlcnIpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhbnNsYXRlcyBhbiBleHRlcm5hbCAocHJpbWl0aXZlKSBKYXZhIHR5cGUgaW50byBhIHJlYWwuIEV4cGVjdHMgYSBqYXZhCi0gICAgICogb2JqZWN0IG9uIHRoZSBzdGFjayBhbmQgcHVzaGVzIGEgcmVhbCAoaS5lLiwgYSBkb3VibGUpLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZUZyb20oQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDbGFzcyBjbGF6eikgewotICAgICAgICBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0KLSAgICAgICAgaWYgKGNsYXp6ID09IENoYXJhY3Rlci5UWVBFIHx8IGNsYXp6ID09IEJ5dGUuVFlQRSB8fAotICAgICAgICAgICAgY2xhenogPT0gU2hvcnQuVFlQRSB8fCBjbGF6eiA9PSBJbnRlZ2VyLlRZUEUpIHsKLSAgICAgICAgICAgIGlsLmFwcGVuZChJMkQpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKGNsYXp6ID09IExvbmcuVFlQRSkgewotICAgICAgICAgICAgaWwuYXBwZW5kKEwyRCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoY2xhenogPT0gRmxvYXQuVFlQRSkgewotICAgICAgICAgICAgaWwuYXBwZW5kKEYyRCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoY2xhenogPT0gRG91YmxlLlRZUEUpIHsKLSAgICAgICAgICAgIGlsLmFwcGVuZChOT1ApOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgRXJyb3JNc2cgZXJyID0gbmV3IEVycm9yTXNnKEVycm9yTXNnLkRBVEFfQ09OVkVSU0lPTl9FUlIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG9TdHJpbmcoKSwgY2xhenouZ2V0TmFtZSgpKTsKLSAgICAgICAgICAgIGNsYXNzR2VuLmdldFBhcnNlcigpLnJlcG9ydEVycm9yKENvbnN0YW50cy5GQVRBTCwgZXJyKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZXMgYW4gb2JqZWN0IG9mIHRoaXMgdHlwZSB0byBpdHMgYm94ZWQgcmVwcmVzZW50YXRpb24uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlQm94KENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0gICAgICAgIHRyYW5zbGF0ZVRvKGNsYXNzR2VuLCBtZXRob2RHZW4sIFR5cGUuUmVmZXJlbmNlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGVzIGFuIG9iamVjdCBvZiB0aGlzIHR5cGUgdG8gaXRzIHVuYm94ZWQgcmVwcmVzZW50YXRpb24uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlVW5Cb3goQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotICAgICAgICBmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBDSEVDS0NBU1QoY3BnLmFkZENsYXNzKERPVUJMRV9DTEFTUykpKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VWSVJUVUFMKGNwZy5hZGRNZXRob2RyZWYoRE9VQkxFX0NMQVNTLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBET1VCTEVfVkFMVUUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERPVUJMRV9WQUxVRV9TSUcpKSk7Ci0gICAgfQotCi0gICAgcHVibGljIEluc3RydWN0aW9uIEFERCgpIHsKLSAgICAgICAgcmV0dXJuIEluc3RydWN0aW9uQ29uc3RhbnRzLkRBREQ7Ci0gICAgfQotCi0gICAgcHVibGljIEluc3RydWN0aW9uIFNVQigpIHsKLSAgICAgICAgcmV0dXJuIEluc3RydWN0aW9uQ29uc3RhbnRzLkRTVUI7Ci0gICAgfQotCi0gICAgcHVibGljIEluc3RydWN0aW9uIE1VTCgpIHsKLSAgICAgICAgcmV0dXJuIEluc3RydWN0aW9uQ29uc3RhbnRzLkRNVUw7Ci0gICAgfQotCi0gICAgcHVibGljIEluc3RydWN0aW9uIERJVigpIHsKLSAgICAgICAgcmV0dXJuIEluc3RydWN0aW9uQ29uc3RhbnRzLkRESVY7Ci0gICAgfQotCi0gICAgcHVibGljIEluc3RydWN0aW9uIFJFTSgpIHsKLSAgICAgICAgcmV0dXJuIEluc3RydWN0aW9uQ29uc3RhbnRzLkRSRU07Ci0gICAgfQotCi0gICAgcHVibGljIEluc3RydWN0aW9uIE5FRygpIHsKLSAgICAgICAgcmV0dXJuIEluc3RydWN0aW9uQ29uc3RhbnRzLkRORUc7Ci0gICAgfQotCi0gICAgcHVibGljIEluc3RydWN0aW9uIExPQUQoaW50IHNsb3QpIHsKLSAgICAgICAgcmV0dXJuIG5ldyBETE9BRChzbG90KTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb24gU1RPUkUoaW50IHNsb3QpIHsKLSAgICAgICAgcmV0dXJuIG5ldyBEU1RPUkUoc2xvdCk7Ci0gICAgfQotCi0gICAgcHVibGljIEluc3RydWN0aW9uIFBPUCgpIHsKLSAgICAgICAgcmV0dXJuIFBPUDI7Ci0gICAgfQotCi0gICAgcHVibGljIEluc3RydWN0aW9uIENNUChib29sZWFuIGxlc3MpIHsKLSAgICAgICAgcmV0dXJuIGxlc3MgPyBJbnN0cnVjdGlvbkNvbnN0YW50cy5EQ01QRyA6IEluc3RydWN0aW9uQ29uc3RhbnRzLkRDTVBMOwotICAgIH0KLQotICAgIHB1YmxpYyBJbnN0cnVjdGlvbiBEVVAoKSB7Ci0gICAgICAgIHJldHVybiBEVVAyOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvdXRpbC9SZWZlcmVuY2VUeXBlLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL3V0aWwvUmVmZXJlbmNlVHlwZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxY2VjY2YyLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvdXRpbC9SZWZlcmVuY2VUeXBlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzNzkgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogUmVmZXJlbmNlVHlwZS5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzA1IDExOjI5OjEyIHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5QVVNIOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQUxPQUQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5BU1RPUkU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5Db25zdGFudFBvb2xHZW47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JRkVROwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSUxPQUQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JTlZPS0VJTlRFUkZBQ0U7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JTlZPS0VTVEFUSUM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JbnN0cnVjdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uTGlzdDsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci5Db25zdGFudHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLkZsb3dMaXN0OwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNOwotCi0vKioKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqIEBhdXRob3IgRXJ3aW4gQm9sd2lkdCA8ZWpiQGtsb21wLm9yZz4KLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIFJlZmVyZW5jZVR5cGUgZXh0ZW5kcyBUeXBlIHsKLSAgICBwcm90ZWN0ZWQgUmVmZXJlbmNlVHlwZSgpIHt9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgICAgICByZXR1cm4gInJlZmVyZW5jZSI7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gaWRlbnRpY2FsVG8oVHlwZSBvdGhlcikgewotICAgICAgICByZXR1cm4gdGhpcyA9PSBvdGhlcjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIHRvU2lnbmF0dXJlKCkgewotICAgICAgICByZXR1cm4gIkxqYXZhL2xhbmcvT2JqZWN0OyI7Ci0gICAgfQotCi0gICAgcHVibGljIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuVHlwZSB0b0pDVHlwZSgpIHsKLSAgICAgICAgcmV0dXJuIGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuVHlwZS5PQkpFQ1Q7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhbnNsYXRlcyBhIHJlZmVyZW5jZSB0byBhbiBvYmplY3Qgb2YgaW50ZXJuYWwgdHlwZSA8Y29kZT50eXBlPC9jb2RlPi4KLSAgICAgKiBUaGUgdHJhbnNsYXRpb24gdG8gaW50IGlzIHVuZGVmaW5lZCBzaW5jZSByZWZlcmVuY2VzCi0gICAgICogYXJlIGFsd2F5cyBjb252ZXJ0ZWQgdG8gcmVhbHMgaW4gYXJpdGhtZXRpYyBleHByZXNzaW9ucy4KLSAgICAgKgotICAgICAqIEBzZWUgICAgIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGUjdHJhbnNsYXRlVG8KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVUbyhDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlIHR5cGUpIHsKLSAgICAgICAgaWYgKHR5cGUgPT0gVHlwZS5TdHJpbmcpIHsKLSAgICAgICAgICAgIHRyYW5zbGF0ZVRvKGNsYXNzR2VuLCBtZXRob2RHZW4sIChTdHJpbmdUeXBlKSB0eXBlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICh0eXBlID09IFR5cGUuUmVhbCkgewotICAgICAgICAgICAgdHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgKFJlYWxUeXBlKSB0eXBlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICh0eXBlID09IFR5cGUuQm9vbGVhbikgewotICAgICAgICAgICAgdHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgKEJvb2xlYW5UeXBlKSB0eXBlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICh0eXBlID09IFR5cGUuTm9kZVNldCkgewotICAgICAgICAgICAgdHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgKE5vZGVTZXRUeXBlKSB0eXBlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICh0eXBlID09IFR5cGUuTm9kZSkgewotICAgICAgICAgICAgdHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgKE5vZGVUeXBlKSB0eXBlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICh0eXBlID09IFR5cGUuUmVzdWx0VHJlZSkgewotICAgICAgICAgICAgdHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgKFJlc3VsdFRyZWVUeXBlKSB0eXBlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICh0eXBlID09IFR5cGUuT2JqZWN0KSB7Ci0gICAgICAgICAgICB0cmFuc2xhdGVUbyhjbGFzc0dlbiwgbWV0aG9kR2VuLCAoT2JqZWN0VHlwZSkgdHlwZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAodHlwZSA9PSBUeXBlLlJlZmVyZW5jZSApIHsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIEVycm9yTXNnIGVyciA9IG5ldyBFcnJvck1zZyhFcnJvck1zZy5JTlRFUk5BTF9FUlIsIHR5cGUudG9TdHJpbmcoKSk7Ci0gICAgICAgICAgICBjbGFzc0dlbi5nZXRQYXJzZXIoKS5yZXBvcnRFcnJvcihDb25zdGFudHMuRkFUQUwsIGVycik7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGVzIHJlZmVyZW5jZSBpbnRvIG9iamVjdCBvZiBpbnRlcm5hbCB0eXBlIDxjb2RlPnR5cGU8L2NvZGU+LgotICAgICAqCi0gICAgICogQHNlZSAgICAgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZSN0cmFuc2xhdGVUbwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZVRvKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1R5cGUgdHlwZSkgewotICAgICAgICBmaW5hbCBpbnQgY3VycmVudCA9IG1ldGhvZEdlbi5nZXRMb2NhbEluZGV4KCJjdXJyZW50Iik7Ci0gICAgICAgIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLSAgICAgICAgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCi0gICAgICAgIC8vIElmIG5vIGN1cnJlbnQsIGNvbnZlcnNpb24gaXMgYSB0b3AtbGV2ZWwKLSAgICAgICAgaWYgKGN1cnJlbnQgPCAwKSB7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBEVE0uUk9PVF9OT0RFKSk7ICAvLyBwdXNoIHJvb3Qgbm9kZQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTE9BRChjdXJyZW50KSk7Ci0gICAgICAgIH0KLSAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkRE9NKCkpOwotICAgICAgICBmaW5hbCBpbnQgc3RyaW5nRiA9IGNwZy5hZGRNZXRob2RyZWYoQkFTSVNfTElCUkFSWV9DTEFTUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJzdHJpbmdGIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBPQkpFQ1RfU0lHCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIE5PREVfU0lHCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIERPTV9JTlRGX1NJRwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiKSIgKyBTVFJJTkdfU0lHKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VTVEFUSUMoc3RyaW5nRikpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZXMgYSByZWZlcmVuY2UgaW50byBhbiBvYmplY3Qgb2YgaW50ZXJuYWwgdHlwZSA8Y29kZT50eXBlPC9jb2RlPi4KLSAgICAgKgotICAgICAqIEBzZWUgICAgIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGUjdHJhbnNsYXRlVG8KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVUbyhDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZWFsVHlwZSB0eXBlKSB7Ci0gICAgICAgIGZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCi0gICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLSAgICAgICAgaW50IGluZGV4ID0gY3BnLmFkZE1ldGhvZHJlZihCQVNJU19MSUJSQVJZX0NMQVNTLCAibnVtYmVyRiIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIigiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBPQkpFQ1RfU0lHCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBET01fSU5URl9TSUcKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIpRCIpOwotICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRVNUQVRJQyhpbmRleCkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZXMgYSByZWZlcmVuY2UgdG8gYW4gb2JqZWN0IG9mIGludGVybmFsIHR5cGUgPGNvZGU+dHlwZTwvY29kZT4uCi0gICAgICoKLSAgICAgKiBAc2VlICAgICBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlI3RyYW5zbGF0ZVRvCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlVG8oQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgQm9vbGVhblR5cGUgdHlwZSkgewotICAgICAgICBmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQotICAgICAgICBpbnQgaW5kZXggPSBjcGcuYWRkTWV0aG9kcmVmKEJBU0lTX0xJQlJBUllfQ0xBU1MsICJib29sZWFuRiIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIigiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBPQkpFQ1RfU0lHCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiKVoiKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VTVEFUSUMoaW5kZXgpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDYXN0cyBhIHJlZmVyZW5jZSBpbnRvIGEgTm9kZUl0ZXJhdG9yLgotICAgICAqCi0gICAgICogQHNlZSAgICAgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZSN0cmFuc2xhdGVUbwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZVRvKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5vZGVTZXRUeXBlIHR5cGUpIHsKLSAgICAgICAgZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0gICAgICAgIGludCBpbmRleCA9IGNwZy5hZGRNZXRob2RyZWYoQkFTSVNfTElCUkFSWV9DTEFTUywgInJlZmVyZW5jZVRvTm9kZVNldCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIigiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBPQkpFQ1RfU0lHCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiKSIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIE5PREVfSVRFUkFUT1JfU0lHKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VTVEFUSUMoaW5kZXgpKTsKLQotICAgICAgICAvLyBSZXNldCB0aGlzIGl0ZXJhdG9yCi0gICAgICAgIGluZGV4ID0gY3BnLmFkZEludGVyZmFjZU1ldGhvZHJlZihOT0RFX0lURVJBVE9SLCBSRVNFVCwgUkVTRVRfU0lHKTsKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0UoaW5kZXgsIDEpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDYXN0cyBhIHJlZmVyZW5jZSBpbnRvIGEgTm9kZS4KLSAgICAgKgotICAgICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZSN0cmFuc2xhdGVUbwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZVRvKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5vZGVUeXBlIHR5cGUpIHsKLSAgICAgICAgdHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgVHlwZS5Ob2RlU2V0KTsKLSAgICAgICAgVHlwZS5Ob2RlU2V0LnRyYW5zbGF0ZVRvKGNsYXNzR2VuLCBtZXRob2RHZW4sIHR5cGUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENhc3RzIGEgcmVmZXJlbmNlIGludG8gYSBSZXN1bHRUcmVlLgotICAgICAqCi0gICAgICogQHNlZSAgICAgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZSN0cmFuc2xhdGVUbwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZVRvKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlc3VsdFRyZWVUeXBlIHR5cGUpIHsKLSAgICAgICAgZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0gICAgICAgIGludCBpbmRleCA9IGNwZy5hZGRNZXRob2RyZWYoQkFTSVNfTElCUkFSWV9DTEFTUywgInJlZmVyZW5jZVRvUmVzdWx0VHJlZSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIigiICsgT0JKRUNUX1NJRyArICIpIiArIERPTV9JTlRGX1NJRyk7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFU1RBVElDKGluZGV4KSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU3Vic3VtZSByZWZlcmVuY2UgaW50byBPYmplY3RUeXBlLgotICAgICAqCi0gICAgICogQHNlZSAgICAgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZSN0cmFuc2xhdGVUbwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZVRvKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9iamVjdFR5cGUgdHlwZSkgewotICAgICAgICBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCkuYXBwZW5kKE5PUCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhbnNsYXRlcyBhIHJlZmVyZW5jZSBpbnRvIHRoZSBKYXZhIHR5cGUgZGVub3RlZCBieSA8Y29kZT5jbGF6ejwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlVG8oQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2xhc3MgY2xhenopIHsKLSAgICAgICAgZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0KLSAgICAgICAgaW50IHJlZmVyZW5jZVRvTG9uZyA9IGNwZy5hZGRNZXRob2RyZWYoQkFTSVNfTElCUkFSWV9DTEFTUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInJlZmVyZW5jZVRvTG9uZyIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoIiArIE9CSkVDVF9TSUcgKyAiKUoiKTsKLSAgICAgICAgaW50IHJlZmVyZW5jZVRvRG91YmxlID0gY3BnLmFkZE1ldGhvZHJlZihCQVNJU19MSUJSQVJZX0NMQVNTLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJyZWZlcmVuY2VUb0RvdWJsZSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKCIgKyBPQkpFQ1RfU0lHICsgIilEIik7Ci0gICAgICAgIGludCByZWZlcmVuY2VUb0Jvb2xlYW4gPSBjcGcuYWRkTWV0aG9kcmVmKEJBU0lTX0xJQlJBUllfQ0xBU1MsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJyZWZlcmVuY2VUb0Jvb2xlYW4iLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoIiArIE9CSkVDVF9TSUcgKyAiKVoiKTsKLQotICAgICAgICBpZiAoY2xhenouZ2V0TmFtZSgpLmVxdWFscygiamF2YS5sYW5nLk9iamVjdCIpKSB7Ci0gICAgICAgICAgICBpbC5hcHBlbmQoTk9QKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChjbGF6eiA9PSBEb3VibGUuVFlQRSkgewotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VTVEFUSUMocmVmZXJlbmNlVG9Eb3VibGUpKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChjbGF6ei5nZXROYW1lKCkuZXF1YWxzKCJqYXZhLmxhbmcuRG91YmxlIikpIHsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFU1RBVElDKHJlZmVyZW5jZVRvRG91YmxlKSk7Ci0gICAgICAgICAgICBUeXBlLlJlYWwudHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgVHlwZS5SZWZlcmVuY2UpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKGNsYXp6ID09IEZsb2F0LlRZUEUpIHsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFU1RBVElDKHJlZmVyZW5jZVRvRG91YmxlKSk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQoRDJGKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChjbGF6ei5nZXROYW1lKCkuZXF1YWxzKCJqYXZhLmxhbmcuU3RyaW5nIikpIHsKLSAgICAgICAgICAgIGludCBpbmRleCA9IGNwZy5hZGRNZXRob2RyZWYoQkFTSVNfTElCUkFSWV9DTEFTUywgInJlZmVyZW5jZVRvU3RyaW5nIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIigiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgT0JKRUNUX1NJRwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIERPTV9JTlRGX1NJRwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIpIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICJMamF2YS9sYW5nL1N0cmluZzsiKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFU1RBVElDKGluZGV4KSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoY2xhenouZ2V0TmFtZSgpLmVxdWFscygib3JnLnczYy5kb20uTm9kZSIpKSB7Ci0gICAgICAgICAgICBpbnQgaW5kZXggPSBjcGcuYWRkTWV0aG9kcmVmKEJBU0lTX0xJQlJBUllfQ0xBU1MsICJyZWZlcmVuY2VUb05vZGUiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKCIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBPQkpFQ1RfU0lHCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgRE9NX0lOVEZfU0lHCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIikiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIkxvcmcvdzNjL2RvbS9Ob2RlOyIpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkRE9NKCkpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VTVEFUSUMoaW5kZXgpKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChjbGF6ei5nZXROYW1lKCkuZXF1YWxzKCJvcmcudzNjLmRvbS5Ob2RlTGlzdCIpKSB7Ci0gICAgICAgICAgICBpbnQgaW5kZXggPSBjcGcuYWRkTWV0aG9kcmVmKEJBU0lTX0xJQlJBUllfQ0xBU1MsICJyZWZlcmVuY2VUb05vZGVMaXN0IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIigiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgT0JKRUNUX1NJRwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIERPTV9JTlRGX1NJRwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIpIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICJMb3JnL3czYy9kb20vTm9kZUxpc3Q7Iik7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRVNUQVRJQyhpbmRleCkpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKGNsYXp6LmdldE5hbWUoKS5lcXVhbHMoImNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5ET00iKSkgewotICAgICAgICAgICAgdHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgVHlwZS5SZXN1bHRUcmVlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChjbGF6eiA9PSBMb25nLlRZUEUpIHsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFU1RBVElDKHJlZmVyZW5jZVRvTG9uZykpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKGNsYXp6ID09IEludGVnZXIuVFlQRSkgewotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VTVEFUSUMocmVmZXJlbmNlVG9Mb25nKSk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQoTDJJKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChjbGF6eiA9PSBTaG9ydC5UWVBFKSB7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRVNUQVRJQyhyZWZlcmVuY2VUb0xvbmcpKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChMMkkpOwotICAgICAgICAgICAgaWwuYXBwZW5kKEkyUyk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoY2xhenogPT0gQnl0ZS5UWVBFKSB7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRVNUQVRJQyhyZWZlcmVuY2VUb0xvbmcpKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChMMkkpOwotICAgICAgICAgICAgaWwuYXBwZW5kKEkyQik7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoY2xhenogPT0gQ2hhcmFjdGVyLlRZUEUpIHsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFU1RBVElDKHJlZmVyZW5jZVRvTG9uZykpOwotICAgICAgICAgICAgaWwuYXBwZW5kKEwySSk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQoSTJDKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChjbGF6eiA9PSBqYXZhLmxhbmcuQm9vbGVhbi5UWVBFKSB7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRVNUQVRJQyhyZWZlcmVuY2VUb0Jvb2xlYW4pKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChjbGF6ei5nZXROYW1lKCkuZXF1YWxzKCJqYXZhLmxhbmcuQm9vbGVhbiIpKSB7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRVNUQVRJQyhyZWZlcmVuY2VUb0Jvb2xlYW4pKTsKLSAgICAgICAgICAgIFR5cGUuQm9vbGVhbi50cmFuc2xhdGVUbyhjbGFzc0dlbiwgbWV0aG9kR2VuLCBUeXBlLlJlZmVyZW5jZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBFcnJvck1zZyBlcnIgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuREFUQV9DT05WRVJTSU9OX0VSUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b1N0cmluZygpLCBjbGF6ei5nZXROYW1lKCkpOwotICAgICAgICAgICAgY2xhc3NHZW4uZ2V0UGFyc2VyKCkucmVwb3J0RXJyb3IoQ29uc3RhbnRzLkZBVEFMLCBlcnIpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhbnNsYXRlcyBhbiBleHRlcm5hbCBKYXZhIHR5cGUgaW50byBhIHJlZmVyZW5jZS4gT25seSBjb252ZXJzaW9uCi0gICAgICogYWxsb3dlZCBpcyBmcm9tIGphdmEubGFuZy5PYmplY3QuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlRnJvbShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENsYXNzIGNsYXp6KSB7Ci0gICAgICAgIGlmIChjbGF6ei5nZXROYW1lKCkuZXF1YWxzKCJqYXZhLmxhbmcuT2JqZWN0IikpIHsKLSAgICAgICAgICAgIG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKS5hcHBlbmQoTk9QKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIEVycm9yTXNnIGVyciA9IG5ldyBFcnJvck1zZyhFcnJvck1zZy5EQVRBX0NPTlZFUlNJT05fRVJSLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b1N0cmluZygpLCBjbGF6ei5nZXROYW1lKCkpOwotICAgICAgICAgICAgY2xhc3NHZW4uZ2V0UGFyc2VyKCkucmVwb3J0RXJyb3IoQ29uc3RhbnRzLkZBVEFMLCBlcnIpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRXhwZWN0cyBhIHJlZmVyZW5jZSBvbiB0aGUgc3RhY2sgYW5kIHRyYW5zbGF0ZXMgaXQgdG8gYSBub24tc3ludGhlc2l6ZWQKLSAgICAgKiBib29sZWFuLiBJdCBkb2VzIG5vdCBwdXNoIGEgMCBvciBhIDEgYnV0IGluc3RlYWQgcmV0dXJucyBicmFuY2hoYW5kbGUKLSAgICAgKiBsaXN0IHRvIGJlIGFwcGVuZGVkIHRvIHRoZSBmYWxzZSBsaXN0LgotICAgICAqCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlI3RyYW5zbGF0ZVRvRGVzeW50aGVzaXplZAotICAgICAqLwotICAgIHB1YmxpYyBGbG93TGlzdCB0cmFuc2xhdGVUb0Rlc3ludGhlc2l6ZWQoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQm9vbGVhblR5cGUgdHlwZSkgewotICAgICAgICBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0gICAgICAgIHRyYW5zbGF0ZVRvKGNsYXNzR2VuLCBtZXRob2RHZW4sIHR5cGUpOwotICAgICAgICByZXR1cm4gbmV3IEZsb3dMaXN0KGlsLmFwcGVuZChuZXcgSUZFUShudWxsKSkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZXMgYW4gb2JqZWN0IG9mIHRoaXMgdHlwZSB0byBpdHMgYm94ZWQgcmVwcmVzZW50YXRpb24uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlQm94KENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhbnNsYXRlcyBhbiBvYmplY3Qgb2YgdGhpcyB0eXBlIHRvIGl0cyB1bmJveGVkIHJlcHJlc2VudGF0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZVVuQm94KENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLSAgICB9Ci0KLQotICAgIHB1YmxpYyBJbnN0cnVjdGlvbiBMT0FEKGludCBzbG90KSB7Ci0gICAgICAgIHJldHVybiBuZXcgQUxPQUQoc2xvdCk7Ci0gICAgfQotCi0gICAgcHVibGljIEluc3RydWN0aW9uIFNUT1JFKGludCBzbG90KSB7Ci0gICAgICAgIHJldHVybiBuZXcgQVNUT1JFKHNsb3QpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvdXRpbC9SZXN1bHRUcmVlVHlwZS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci91dGlsL1Jlc3VsdFRyZWVUeXBlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGU2MWY3Y2IuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci91dGlsL1Jlc3VsdFRyZWVUeXBlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0NjUgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogUmVzdWx0VHJlZVR5cGUuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8wNSAxMTozMDowMSBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbDsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQUxPQUQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5BU1RPUkU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5DSEVDS0NBU1Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5Db25zdGFudFBvb2xHZW47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5HRVRGSUVMRDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklGRVE7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JTlZPS0VJTlRFUkZBQ0U7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JTlZPS0VTUEVDSUFMOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFVklSVFVBTDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW5zdHJ1Y3Rpb25MaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuTG9jYWxWYXJpYWJsZUdlbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLk5FVzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlBVU0g7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLkNvbnN0YW50czsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIuRmxvd0xpc3Q7Ci0KLS8qKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBSZXN1bHRUcmVlVHlwZSBleHRlbmRzIFR5cGUgewotICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIF9tZXRob2ROYW1lOwotCi0gICAgcHJvdGVjdGVkIFJlc3VsdFRyZWVUeXBlKCkgewotICAgICAgICBfbWV0aG9kTmFtZSA9IG51bGw7Ci0gICAgfQotCi0gICAgcHVibGljIFJlc3VsdFRyZWVUeXBlKFN0cmluZyBtZXRob2ROYW1lKSB7Ci0gICAgICAgIF9tZXRob2ROYW1lID0gbWV0aG9kTmFtZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgICAgICByZXR1cm4gInJlc3VsdC10cmVlIjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBpZGVudGljYWxUbyhUeXBlIG90aGVyKSB7Ci0gICAgICAgIHJldHVybiAob3RoZXIgaW5zdGFuY2VvZiBSZXN1bHRUcmVlVHlwZSk7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyB0b1NpZ25hdHVyZSgpIHsKLSAgICAgICAgcmV0dXJuIERPTV9JTlRGX1NJRzsKLSAgICB9Ci0KLSAgICBwdWJsaWMgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5UeXBlIHRvSkNUeXBlKCkgewotICAgICAgICByZXR1cm4gVXRpbC5nZXRKQ1JlZlR5cGUodG9TaWduYXR1cmUoKSk7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRNZXRob2ROYW1lKCkgewotICAgICAgICByZXR1cm4gX21ldGhvZE5hbWU7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gaW1wbGVtZW50ZWRBc01ldGhvZCgpIHsKLSAgICAgICAgcmV0dXJuIF9tZXRob2ROYW1lICE9IG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhbnNsYXRlcyBhIHJlc3VsdCB0cmVlIHRvIG9iamVjdCBvZiBpbnRlcm5hbCB0eXBlIDxjb2RlPnR5cGU8L2NvZGU+LgotICAgICAqIFRoZSB0cmFuc2xhdGlvbiB0byBpbnQgaXMgdW5kZWZpbmVkIHNpbmNlIHJlc3VsdCB0cmVlcwotICAgICAqIGFyZSBhbHdheXMgY29udmVydGVkIHRvIHJlYWxzIGluIGFyaXRobWV0aWMgZXhwcmVzc2lvbnMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY2xhc3NHZW4gQSBCQ0VMIGNsYXNzIGdlbmVyYXRvcgotICAgICAqIEBwYXJhbSBtZXRob2RHZW4gQSBCQ0VMIG1ldGhvZCBnZW5lcmF0b3IKLSAgICAgKiBAcGFyYW0gdHlwZSBBbiBpbnN0YW5jZSBvZiB0aGUgdHlwZSB0byB0cmFuc2xhdGUgdGhlIHJlc3VsdCB0cmVlIHRvCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlI3RyYW5zbGF0ZVRvCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlVG8oQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgVHlwZSB0eXBlKSB7Ci0gICAgICAgIGlmICh0eXBlID09IFR5cGUuU3RyaW5nKSB7Ci0gICAgICAgICAgICB0cmFuc2xhdGVUbyhjbGFzc0dlbiwgbWV0aG9kR2VuLCAoU3RyaW5nVHlwZSl0eXBlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICh0eXBlID09IFR5cGUuQm9vbGVhbikgewotICAgICAgICAgICAgdHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgKEJvb2xlYW5UeXBlKXR5cGUpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKHR5cGUgPT0gVHlwZS5SZWFsKSB7Ci0gICAgICAgICAgICB0cmFuc2xhdGVUbyhjbGFzc0dlbiwgbWV0aG9kR2VuLCAoUmVhbFR5cGUpdHlwZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAodHlwZSA9PSBUeXBlLk5vZGVTZXQpIHsKLSAgICAgICAgICAgIHRyYW5zbGF0ZVRvKGNsYXNzR2VuLCBtZXRob2RHZW4sIChOb2RlU2V0VHlwZSl0eXBlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICh0eXBlID09IFR5cGUuUmVmZXJlbmNlKSB7Ci0gICAgICAgICAgICB0cmFuc2xhdGVUbyhjbGFzc0dlbiwgbWV0aG9kR2VuLCAoUmVmZXJlbmNlVHlwZSl0eXBlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICh0eXBlID09IFR5cGUuT2JqZWN0KSB7Ci0gICAgICAgICAgICB0cmFuc2xhdGVUbyhjbGFzc0dlbiwgbWV0aG9kR2VuLCAoT2JqZWN0VHlwZSkgdHlwZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBFcnJvck1zZyBlcnIgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuREFUQV9DT05WRVJTSU9OX0VSUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b1N0cmluZygpLCB0eXBlLnRvU3RyaW5nKCkpOwotICAgICAgICAgICAgY2xhc3NHZW4uZ2V0UGFyc2VyKCkucmVwb3J0RXJyb3IoQ29uc3RhbnRzLkZBVEFMLCBlcnIpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRXhwZWN0cyBhbiByZXN1bHQgdHJlZSBvbiB0aGUgc3RhY2sgYW5kIHB1c2hlcyBhIGJvb2xlYW4uCi0gICAgICogVHJhbnNsYXRlcyBhIHJlc3VsdCB0cmVlIHRvIGEgYm9vbGVhbiBieSBmaXJzdCBjb252ZXJ0aW5nIGl0IHRvIHN0cmluZy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjbGFzc0dlbiBBIEJDRUwgY2xhc3MgZ2VuZXJhdG9yCi0gICAgICogQHBhcmFtIG1ldGhvZEdlbiBBIEJDRUwgbWV0aG9kIGdlbmVyYXRvcgotICAgICAqIEBwYXJhbSB0eXBlIEFuIGluc3RhbmNlIG9mIEJvb2xlYW5UeXBlIChhbnkpCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlI3RyYW5zbGF0ZVRvCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlVG8oQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgQm9vbGVhblR5cGUgdHlwZSkgewotICAgICAgICAvLyBBIHJlc3VsdCB0cmVlIGlzIGFsd2F5cyAndHJ1ZScgd2hlbiBjb252ZXJ0ZWQgdG8gYSBib29sZWFuIHZhbHVlLAotICAgICAgICAvLyBzaW5jZSB0aGUgdHJlZSBhbHdheXMgaGFzIGF0IGxlYXN0IG9uZSBub2RlICh0aGUgcm9vdCkuCi0gICAgICAgIGZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotICAgICAgICBpbC5hcHBlbmQoUE9QKTsgICAgICAvLyBkb24ndCBuZWVkIHRoZSBET00gcmVmZXJlbmNlCi0gICAgICAgIGlsLmFwcGVuZChJQ09OU1RfMSk7IC8vIHB1c2ggJ3RydWUnIG9uIHRoZSBzdGFjawotICAgIH0KLQotICAgIC8qKgotICAgICAqIEV4cGVjdHMgYW4gcmVzdWx0IHRyZWUgb24gdGhlIHN0YWNrIGFuZCBwdXNoZXMgYSBzdHJpbmcuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY2xhc3NHZW4gQSBCQ0VMIGNsYXNzIGdlbmVyYXRvcgotICAgICAqIEBwYXJhbSBtZXRob2RHZW4gQSBCQ0VMIG1ldGhvZCBnZW5lcmF0b3IKLSAgICAgKiBAcGFyYW0gdHlwZSBBbiBpbnN0YW5jZSBvZiBTdHJpbmdUeXBlIChhbnkpCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlI3RyYW5zbGF0ZVRvCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlVG8oQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nVHlwZSB0eXBlKSB7Ci0gICAgICAgIGZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCi0gICAgICAgIGlmIChfbWV0aG9kTmFtZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBpbnQgaW5kZXggPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKERPTV9JTlRGLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZ2V0U3RyaW5nVmFsdWUiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKCkiK1NUUklOR19TSUcpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0UoaW5kZXgsIDEpKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIGZpbmFsIFN0cmluZyBjbGFzc05hbWUgPSBjbGFzc0dlbi5nZXRDbGFzc05hbWUoKTsKLSAgICAgICAgICAgIGZpbmFsIGludCBjdXJyZW50ID0gbWV0aG9kR2VuLmdldExvY2FsSW5kZXgoImN1cnJlbnQiKTsKLQotICAgICAgICAgICAgLy8gUHVzaCByZXF1aXJlZCBwYXJhbWV0ZXJzCi0gICAgICAgICAgICBpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpOwotICAgICAgICAgICAgaWYgKGNsYXNzR2VuLmlzRXh0ZXJuYWwoKSkgewotICAgICAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgQ0hFQ0tDQVNUKGNwZy5hZGRDbGFzcyhjbGFzc05hbWUpKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpbC5hcHBlbmQoRFVQKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgR0VURklFTEQoY3BnLmFkZEZpZWxkcmVmKGNsYXNzTmFtZSwgIl9kb20iLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRE9NX0lOVEZfU0lHKSkpOwotCi0gICAgICAgICAgICAvLyBDcmVhdGUgYSBuZXcgaW5zdGFuY2Ugb2YgYSBTdHJpbmdWYWx1ZUhhbmRsZXIKLSAgICAgICAgICAgIGludCBpbmRleCA9IGNwZy5hZGRNZXRob2RyZWYoU1RSSU5HX1ZBTFVFX0hBTkRMRVIsICI8aW5pdD4iLCAiKClWIik7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IE5FVyhjcGcuYWRkQ2xhc3MoU1RSSU5HX1ZBTFVFX0hBTkRMRVIpKSk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQoRFVQKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChEVVApOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VTUEVDSUFMKGluZGV4KSk7Ci0KLSAgICAgICAgICAgIC8vIFN0b3JlIG5ldyBIYW5kbGVyIGludG8gYSBsb2NhbCB2YXJpYWJsZQotICAgICAgICAgICAgZmluYWwgTG9jYWxWYXJpYWJsZUdlbiBoYW5kbGVyID0KLSAgICAgICAgICAgICAgICBtZXRob2RHZW4uYWRkTG9jYWxWYXJpYWJsZSgicnRfdG9fc3RyaW5nX2hhbmRsZXIiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFV0aWwuZ2V0SkNSZWZUeXBlKFNUUklOR19WQUxVRV9IQU5ETEVSX1NJRyksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwgbnVsbCk7Ci0gICAgICAgICAgICBoYW5kbGVyLnNldFN0YXJ0KGlsLmFwcGVuZChuZXcgQVNUT1JFKGhhbmRsZXIuZ2V0SW5kZXgoKSkpKTsKLQotICAgICAgICAgICAgLy8gQ2FsbCB0aGUgbWV0aG9kIHRoYXQgaW1wbGVtZW50cyB0aGlzIHJlc3VsdCB0cmVlCi0gICAgICAgICAgICBpbmRleCA9IGNwZy5hZGRNZXRob2RyZWYoY2xhc3NOYW1lLCBfbWV0aG9kTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKCIrRE9NX0lOVEZfU0lHK1RSQU5TTEVUX09VVFBVVF9TSUcrIilWIik7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRVZJUlRVQUwoaW5kZXgpKTsKLQotICAgICAgICAgICAgLy8gUmVzdG9yZSBuZXcgaGFuZGxlciBhbmQgY2FsbCBnZXRWYWx1ZSgpCi0gICAgICAgICAgICBoYW5kbGVyLnNldEVuZChpbC5hcHBlbmQobmV3IEFMT0FEKGhhbmRsZXIuZ2V0SW5kZXgoKSkpKTsKLSAgICAgICAgICAgIGluZGV4ID0gY3BnLmFkZE1ldGhvZHJlZihTVFJJTkdfVkFMVUVfSEFORExFUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZ2V0VmFsdWUiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoKSIgKyBTVFJJTkdfU0lHKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChpbmRleCkpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRXhwZWN0cyBhbiByZXN1bHQgdHJlZSBvbiB0aGUgc3RhY2sgYW5kIHB1c2hlcyBhIHJlYWwuCi0gICAgICogVHJhbnNsYXRlcyBhIHJlc3VsdCB0cmVlIGludG8gYSByZWFsIGJ5IGZpcnN0IGNvbnZlcnRpbmcgaXQgdG8gc3RyaW5nLgotICAgICAqCi0gICAgICogQHBhcmFtIGNsYXNzR2VuIEEgQkNFTCBjbGFzcyBnZW5lcmF0b3IKLSAgICAgKiBAcGFyYW0gbWV0aG9kR2VuIEEgQkNFTCBtZXRob2QgZ2VuZXJhdG9yCi0gICAgICogQHBhcmFtIHR5cGUgQW4gaW5zdGFuY2Ugb2YgUmVhbFR5cGUgKGFueSkKLSAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGUjdHJhbnNsYXRlVG8KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVUbyhDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZWFsVHlwZSB0eXBlKSB7Ci0gICAgICAgIHRyYW5zbGF0ZVRvKGNsYXNzR2VuLCBtZXRob2RHZW4sIFR5cGUuU3RyaW5nKTsKLSAgICAgICAgVHlwZS5TdHJpbmcudHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgVHlwZS5SZWFsKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBFeHBlY3RzIGEgcmVzdWx0IHRyZWUgb24gdGhlIHN0YWNrIGFuZCBwdXNoZXMgYSBib3hlZCByZXN1bHQgdHJlZS4KLSAgICAgKiBSZXN1bHQgdHJlZXMgYXJlIGFscmVhZHkgYm94ZWQgc28gdGhlIHRyYW5zbGF0aW9uIGlzIGp1c3QgYSBOT1AuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY2xhc3NHZW4gQSBCQ0VMIGNsYXNzIGdlbmVyYXRvcgotICAgICAqIEBwYXJhbSBtZXRob2RHZW4gQSBCQ0VMIG1ldGhvZCBnZW5lcmF0b3IKLSAgICAgKiBAcGFyYW0gdHlwZSBBbiBpbnN0YW5jZSBvZiBSZWZlcmVuY2VUeXBlIChhbnkpCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlI3RyYW5zbGF0ZVRvCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlVG8oQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVmZXJlbmNlVHlwZSB0eXBlKSB7Ci0gICAgICAgIGZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCi0gICAgICAgIGlmIChfbWV0aG9kTmFtZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBpbC5hcHBlbmQoTk9QKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIExvY2FsVmFyaWFibGVHZW4gZG9tQnVpbGRlciwgbmV3RG9tOwotICAgICAgICAgICAgZmluYWwgU3RyaW5nIGNsYXNzTmFtZSA9IGNsYXNzR2VuLmdldENsYXNzTmFtZSgpOwotICAgICAgICAgICAgZmluYWwgaW50IGN1cnJlbnQgPSBtZXRob2RHZW4uZ2V0TG9jYWxJbmRleCgiY3VycmVudCIpOwotCi0gICAgICAgICAgICAvLyBQdXNoIHJlcXVpcmVkIHBhcmFtZXRlcnMKLSAgICAgICAgICAgIGlsLmFwcGVuZChjbGFzc0dlbi5sb2FkVHJhbnNsZXQoKSk7Ci0gICAgICAgICAgICBpZiAoY2xhc3NHZW4uaXNFeHRlcm5hbCgpKSB7Ci0gICAgICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBDSEVDS0NBU1QoY3BnLmFkZENsYXNzKGNsYXNzTmFtZSkpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLQotICAgICAgICAgICAgLy8gQ3JlYXRlIG5ldyBpbnN0YW5jZSBvZiBET00gY2xhc3MgKHdpdGggUlRGX0lOSVRJQUxfU0laRSBub2RlcykKLSAgICAgICAgICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLSAgICAgICAgICAgIGludCBpbmRleCA9IGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoRE9NX0lOVEYsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZ2V0UmVzdWx0VHJlZUZyYWciLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIihJWikiICsgRE9NX0lOVEZfU0lHKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsIFJURl9JTklUSUFMX1NJWkUpKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsIGZhbHNlKSk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRUlOVEVSRkFDRShpbmRleCwzKSk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQoRFVQKTsKLQotICAgICAgICAgICAgLy8gU3RvcmUgbmV3IERPTSBpbnRvIGEgbG9jYWwgdmFyaWFibGUKLSAgICAgICAgICAgIG5ld0RvbSA9IG1ldGhvZEdlbi5hZGRMb2NhbFZhcmlhYmxlKCJydF90b19yZWZlcmVuY2VfZG9tIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFV0aWwuZ2V0SkNSZWZUeXBlKERPTV9JTlRGX1NJRyksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLCBudWxsKTsKLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgQ0hFQ0tDQVNUKGNwZy5hZGRDbGFzcyhET01fSU5URl9TSUcpKSk7Ci0gICAgICAgICAgICBuZXdEb20uc2V0U3RhcnQoaWwuYXBwZW5kKG5ldyBBU1RPUkUobmV3RG9tLmdldEluZGV4KCkpKSk7Ci0KLSAgICAgICAgICAgIC8vIE92ZXJ3cml0ZSBvbGQgaGFuZGxlciB3aXRoIERPTSBoYW5kbGVyCi0gICAgICAgICAgICBpbmRleCA9IGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoRE9NX0lOVEYsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZ2V0T3V0cHV0RG9tQnVpbGRlciIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKCkiICsgVFJBTlNMRVRfT1VUUFVUX1NJRyk7Ci0KLSAgICAgICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFSU5URVJGQUNFKGluZGV4LDEpKTsKLSAgICAgICAgICAgIC8vaW5kZXggPSBjcGcuYWRkTWV0aG9kcmVmKERPTV9JTVBMLAotICAgICAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgICAgICJnZXRPdXRwdXREb21CdWlsZGVyIiwKLSAgICAgICAgICAgICAgICAvLyAgICAgICAgICAgICAgICAgICAiKCkiICsgVFJBTlNMRVRfT1VUUFVUX1NJRyk7Ci0gICAgICAgICAgICAvL2lsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChpbmRleCkpOwotICAgICAgICAgICAgaWwuYXBwZW5kKERVUCk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQoRFVQKTsKLQotICAgICAgICAgICAgLy8gU3RvcmUgRE9NIGhhbmRsZXIgaW4gYSBsb2NhbCBpbiBvcmRlciB0byBjYWxsIGVuZERvY3VtZW50KCkKLSAgICAgICAgICAgIGRvbUJ1aWxkZXIgPQotICAgICAgICAgICAgICAgIG1ldGhvZEdlbi5hZGRMb2NhbFZhcmlhYmxlKCJydF90b19yZWZlcmVuY2VfaGFuZGxlciIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVXRpbC5nZXRKQ1JlZlR5cGUoVFJBTlNMRVRfT1VUUFVUX1NJRyksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwgbnVsbCk7Ci0gICAgICAgICAgICBkb21CdWlsZGVyLnNldFN0YXJ0KGlsLmFwcGVuZChuZXcgQVNUT1JFKGRvbUJ1aWxkZXIuZ2V0SW5kZXgoKSkpKTsKLQotICAgICAgICAgICAgLy8gQ2FsbCBzdGFydERvY3VtZW50IG9uIHRoZSBuZXcgaGFuZGxlcgotICAgICAgICAgICAgaW5kZXggPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKFRSQU5TTEVUX09VVFBVVF9JTlRFUkZBQ0UsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInN0YXJ0RG9jdW1lbnQiLCAiKClWIik7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRUlOVEVSRkFDRShpbmRleCwgMSkpOwotCi0gICAgICAgICAgICAvLyBDYWxsIHRoZSBtZXRob2QgdGhhdCBpbXBsZW1lbnRzIHRoaXMgcmVzdWx0IHRyZWUKLSAgICAgICAgICAgIGluZGV4ID0gY3BnLmFkZE1ldGhvZHJlZihjbGFzc05hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX21ldGhvZE5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIigiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBET01fSU5URl9TSUcKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIFRSQU5TTEVUX09VVFBVVF9TSUcKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIilWIik7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRVZJUlRVQUwoaW5kZXgpKTsKLQotICAgICAgICAgICAgLy8gQ2FsbCBlbmREb2N1bWVudCBvbiB0aGUgRE9NIGhhbmRsZXIKLSAgICAgICAgICAgIGRvbUJ1aWxkZXIuc2V0RW5kKGlsLmFwcGVuZChuZXcgQUxPQUQoZG9tQnVpbGRlci5nZXRJbmRleCgpKSkpOwotICAgICAgICAgICAgaW5kZXggPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKFRSQU5TTEVUX09VVFBVVF9JTlRFUkZBQ0UsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImVuZERvY3VtZW50IiwgIigpViIpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0UoaW5kZXgsIDEpKTsKLQotICAgICAgICAgICAgLy8gUHVzaCB0aGUgbmV3IERPTSBvbiB0aGUgc3RhY2sKLSAgICAgICAgICAgIG5ld0RvbS5zZXRFbmQoaWwuYXBwZW5kKG5ldyBBTE9BRChuZXdEb20uZ2V0SW5kZXgoKSkpKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEV4cGVjdHMgYSByZXN1bHQgdHJlZSBvbiB0aGUgc3RhY2sgYW5kIHB1c2hlcyBhIG5vZGUtc2V0IChpdGVyYXRvcikuCi0gICAgICogTm90ZSB0aGF0IHRoZSBwcm9kdWNlZCBpdGVyYXRvciBpcyBhbiBpdGVyYXRvciBmb3IgdGhlIERPTSB0aGF0Ci0gICAgICogY29udGFpbnMgdGhlIHJlc3VsdCB0cmVlLCBhbmQgbm90IHRoZSBET00gdGhhdCBpcyBjdXJyZW50bHkgaW4gdXNlLgotICAgICAqIFRoaXMgY29udmVyc2lvbiBoZXJlIHdpbGwgdGhlcmVmb3JlIG5vdCBkaXJlY3RseSB3b3JrIHdpdGggZWxlbWVudHMKLSAgICAgKiBzdWNoIGFzIDx4c2w6YXBwbHktdGVtcGxhdGVzPiBhbmQgPHhzbDpmb3ItZWFjaD4gd2l0aG91dCB0aGUgRE9NCi0gICAgICogcGFyYW1ldGVyL3ZhcmlhYmxlIGJlaW5nIHVwZGF0ZXMgYXMgd2VsbC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjbGFzc0dlbiBBIEJDRUwgY2xhc3MgZ2VuZXJhdG9yCi0gICAgICogQHBhcmFtIG1ldGhvZEdlbiBBIEJDRUwgbWV0aG9kIGdlbmVyYXRvcgotICAgICAqIEBwYXJhbSB0eXBlIEFuIGluc3RhbmNlIG9mIE5vZGVTZXRUeXBlIChhbnkpCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlI3RyYW5zbGF0ZVRvCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlVG8oQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgTm9kZVNldFR5cGUgdHlwZSkgewotICAgICAgICBmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQotICAgICAgICAvLyBQdXQgYW4gZXh0cmEgY29weSBvZiB0aGUgcmVzdWx0IHRyZWUgKERPTSkgb24gdGhlIHN0YWNrCi0gICAgICAgIGlsLmFwcGVuZChEVVApOwotCi0gICAgICAgIC8vIERPTSBhZGFwdGVycyBjb250YWluaW5nIGEgcmVzdWx0IHRyZWUgYXJlIG5vdCBpbml0aWFsaXNlZCB3aXRoCi0gICAgICAgIC8vIHRyYW5zbGV0LXR5cGUgdG8gRE9NLXR5cGUgbWFwcGluZy4gVGhpcyBtdXN0IGJlIGRvbmUgbm93IGZvcgotICAgICAgICAvLyBYUGF0aCBleHByZXNzaW9ucyBhbmQgcGF0dGVybnMgdG8gd29yayBmb3IgdGhlIGl0ZXJhdG9yIHdlIGNyZWF0ZS4KLSAgICAgICAgaWwuYXBwZW5kKGNsYXNzR2VuLmxvYWRUcmFuc2xldCgpKTsgLy8gZ2V0IG5hbWVzIGFycmF5Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgR0VURklFTEQoY3BnLmFkZEZpZWxkcmVmKFRSQU5TTEVUX0NMQVNTLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOQU1FU19JTkRFWCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkFNRVNfSU5ERVhfU0lHKSkpOwotICAgICAgICBpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpOyAvLyBnZXQgdXJpcyBhcnJheQotICAgICAgICBpbC5hcHBlbmQobmV3IEdFVEZJRUxEKGNwZy5hZGRGaWVsZHJlZihUUkFOU0xFVF9DTEFTUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVVJJU19JTkRFWCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVVJJU19JTkRFWF9TSUcpKSk7Ci0gICAgICAgIGlsLmFwcGVuZChjbGFzc0dlbi5sb2FkVHJhbnNsZXQoKSk7IC8vIGdldCB0eXBlcyBhcnJheQotICAgICAgICBpbC5hcHBlbmQobmV3IEdFVEZJRUxEKGNwZy5hZGRGaWVsZHJlZihUUkFOU0xFVF9DTEFTUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVFlQRVNfSU5ERVgsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRZUEVTX0lOREVYX1NJRykpKTsKLSAgICAgICAgaWwuYXBwZW5kKGNsYXNzR2VuLmxvYWRUcmFuc2xldCgpKTsgLy8gZ2V0IG5hbWVzcGFjZXMgYXJyYXkKLSAgICAgICAgaWwuYXBwZW5kKG5ldyBHRVRGSUVMRChjcGcuYWRkRmllbGRyZWYoVFJBTlNMRVRfQ0xBU1MsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5BTUVTUEFDRV9JTkRFWCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkFNRVNQQUNFX0lOREVYX1NJRykpKTsKLSAgICAgICAgLy8gUGFzcyB0aGUgdHlwZSBtYXBwaW5ncyB0byB0aGUgRE9NIGFkYXB0ZXIKLSAgICAgICAgZmluYWwgaW50IG1hcHBpbmcgPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKERPTV9JTlRGLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInNldHVwTWFwcGluZyIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKFsiK1NUUklOR19TSUcrCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiWyIrU1RSSU5HX1NJRysKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJbSSIgKwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlsiK1NUUklOR19TSUcrIilWIik7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFSU5URVJGQUNFKG1hcHBpbmcsIDUpKTsKLSAgICAgICAgaWwuYXBwZW5kKERVUCk7Ci0KLSAgICAgICAgLy8gQ3JlYXRlIGFuIGl0ZXJhdG9yIGZvciB0aGUgcm9vdCBub2RlIG9mIHRoZSBET00gYWRhcHRlcgotICAgICAgICBmaW5hbCBpbnQgaXRlciA9IGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoRE9NX0lOVEYsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZ2V0SXRlcmF0b3IiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIigpIitOT0RFX0lURVJBVE9SX1NJRyk7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFSU5URVJGQUNFKGl0ZXIsIDEpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTdWJzdW1lIHJlc3VsdCB0cmVlIGludG8gT2JqZWN0VHlwZS4KLSAgICAgKgotICAgICAqIEBzZWUgICAgIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGUjdHJhbnNsYXRlVG8KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVUbyhDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBPYmplY3RUeXBlIHR5cGUpIHsKLSAgICAgICAgbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpLmFwcGVuZChOT1ApOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZXMgYSByZXN1bHQgdHJlZSBpbnRvIGEgbm9uLXN5bnRoZXNpemVkIGJvb2xlYW4uCi0gICAgICogSXQgZG9lcyBub3QgcHVzaCBhIDAgb3IgYSAxIGJ1dCBpbnN0ZWFkIHJldHVybnMgYnJhbmNoaGFuZGxlIGxpc3QKLSAgICAgKiB0byBiZSBhcHBlbmRlZCB0byB0aGUgZmFsc2UgbGlzdC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjbGFzc0dlbiBBIEJDRUwgY2xhc3MgZ2VuZXJhdG9yCi0gICAgICogQHBhcmFtIG1ldGhvZEdlbiBBIEJDRUwgbWV0aG9kIGdlbmVyYXRvcgotICAgICAqIEBwYXJhbSB0eXBlIEFuIGluc3RhbmNlIG9mIEJvb2xlYW5UeXBlIChhbnkpCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlI3RyYW5zbGF0ZVRvRGVzeW50aGVzaXplZAotICAgICAqLwotICAgIHB1YmxpYyBGbG93TGlzdCB0cmFuc2xhdGVUb0Rlc3ludGhlc2l6ZWQoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQm9vbGVhblR5cGUgdHlwZSkgewotICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0gICAgICAgIHRyYW5zbGF0ZVRvKGNsYXNzR2VuLCBtZXRob2RHZW4sIFR5cGUuQm9vbGVhbik7Ci0gICAgICAgIHJldHVybiBuZXcgRmxvd0xpc3QoaWwuYXBwZW5kKG5ldyBJRkVRKG51bGwpKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhbnNsYXRlcyBhIHJlc3VsdCB0cmVlIHRvIGEgSmF2YSB0eXBlIGRlbm90ZWQgYnkgPGNvZGU+Y2xheno8L2NvZGU+LgotICAgICAqIEV4cGVjdHMgYSByZXN1bHQgdHJlZSBvbiB0aGUgc3RhY2sgYW5kIHB1c2hlcyBhbiBvYmplY3QKLSAgICAgKiBvZiB0aGUgYXBwcm9wcmlhdGUgdHlwZSBhZnRlciBjb2VyY2lvbi4gUmVzdWx0IHRyZWVzIGFyZSB0cmFuc2xhdGVkCi0gICAgICogdG8gVzNDIE5vZGUgb3IgVzNDIE5vZGVMaXN0IGFuZCB0aGUgdHJhbnNsYXRpb24gaXMgZG9uZQotICAgICAqIHZpYSBub2RlLXNldCB0eXBlLgotICAgICAqCi0gICAgICogQHBhcmFtIGNsYXNzR2VuIEEgQkNFTCBjbGFzcyBnZW5lcmF0b3IKLSAgICAgKiBAcGFyYW0gbWV0aG9kR2VuIEEgQkNFTCBtZXRob2QgZ2VuZXJhdG9yCi0gICAgICogQHBhcmFtIGNsYXp6IEFuIHJlZmVyZW5jZSB0byB0aGUgQ2xhc3MgdG8gdHJhbnNsYXRlIHRvCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlI3RyYW5zbGF0ZVRvCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlVG8oQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2xhc3MgY2xhenopIHsKLSAgICAgICAgZmluYWwgU3RyaW5nIGNsYXNzTmFtZSA9IGNsYXp6LmdldE5hbWUoKTsKLSAgICAgICAgZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0KLSAgICAgICAgaWYgKGNsYXNzTmFtZS5lcXVhbHMoIm9yZy53M2MuZG9tLk5vZGUiKSkgewotICAgICAgICAgICAgdHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgVHlwZS5Ob2RlU2V0KTsKLSAgICAgICAgICAgIGludCBpbmRleCA9IGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoRE9NX0lOVEYsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1BS0VfTk9ERSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTUFLRV9OT0RFX1NJRzIpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0UoaW5kZXgsIDIpKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChjbGFzc05hbWUuZXF1YWxzKCJvcmcudzNjLmRvbS5Ob2RlTGlzdCIpKSB7Ci0gICAgICAgICAgICB0cmFuc2xhdGVUbyhjbGFzc0dlbiwgbWV0aG9kR2VuLCBUeXBlLk5vZGVTZXQpOwotICAgICAgICAgICAgaW50IGluZGV4ID0gY3BnLmFkZEludGVyZmFjZU1ldGhvZHJlZihET01fSU5URiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTUFLRV9OT0RFX0xJU1QsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1BS0VfTk9ERV9MSVNUX1NJRzIpOwotICAgICAgICAgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0UoaW5kZXgsIDIpKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChjbGFzc05hbWUuZXF1YWxzKCJqYXZhLmxhbmcuT2JqZWN0IikpIHsKLSAgICAgICAgICAgIGlsLmFwcGVuZChOT1ApOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKGNsYXNzTmFtZS5lcXVhbHMoImphdmEubGFuZy5TdHJpbmciKSkgewotICAgICAgICAgICAgdHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgVHlwZS5TdHJpbmcpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgRXJyb3JNc2cgZXJyID0gbmV3IEVycm9yTXNnKEVycm9yTXNnLkRBVEFfQ09OVkVSU0lPTl9FUlIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG9TdHJpbmcoKSwgY2xhc3NOYW1lKTsKLSAgICAgICAgICAgIGNsYXNzR2VuLmdldFBhcnNlcigpLnJlcG9ydEVycm9yKENvbnN0YW50cy5GQVRBTCwgZXJyKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZXMgYW4gb2JqZWN0IG9mIHRoaXMgdHlwZSB0byBpdHMgYm94ZWQgcmVwcmVzZW50YXRpb24uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlQm94KENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0gICAgICAgIHRyYW5zbGF0ZVRvKGNsYXNzR2VuLCBtZXRob2RHZW4sIFR5cGUuUmVmZXJlbmNlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGVzIGFuIG9iamVjdCBvZiB0aGlzIHR5cGUgdG8gaXRzIHVuYm94ZWQgcmVwcmVzZW50YXRpb24uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlVW5Cb3goQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotICAgICAgICBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCkuYXBwZW5kKE5PUCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgY2xhc3MgbmFtZSBvZiBhbiBpbnRlcm5hbCB0eXBlJ3MgZXh0ZXJuYWwgcmVwcmVzZW50YXRpb24uCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRDbGFzc05hbWUoKSB7Ci0gICAgICAgIHJldHVybihET01fSU5URik7Ci0gICAgfQotCi0gICAgcHVibGljIEluc3RydWN0aW9uIExPQUQoaW50IHNsb3QpIHsKLSAgICAgICAgcmV0dXJuIG5ldyBBTE9BRChzbG90KTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb24gU1RPUkUoaW50IHNsb3QpIHsKLSAgICAgICAgcmV0dXJuIG5ldyBBU1RPUkUoc2xvdCk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci91dGlsL1J0TWV0aG9kR2VuZXJhdG9yLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL3V0aWwvUnRNZXRob2RHZW5lcmF0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYTMxZGVjNi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL3V0aWwvUnRNZXRob2RHZW5lcmF0b3IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDcwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFJ0TWV0aG9kR2VuZXJhdG9yLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMDUgMTE6MzA6NDkgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWw7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkFMT0FEOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQVNUT1JFOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQ29uc3RhbnRQb29sR2VuOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW5zdHJ1Y3Rpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JbnN0cnVjdGlvbkxpc3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5UeXBlOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgaXMgdXNlZCBmb3IgcmVzdWx0IHRyZWVzIGltcGxlbWVudGVkIGFzIG1ldGhvZHMuIFRoZXNlCi0gKiBtZXRob2RzIHRha2UgYSByZWZlcmVuY2UgdG8gdGhlIERPTSBhbmQgdG8gdGhlIGhhbmRsZXIgb25seS4KLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIFJ0TWV0aG9kR2VuZXJhdG9yIGV4dGVuZHMgTWV0aG9kR2VuZXJhdG9yIHsKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgSEFORExFUl9JTkRFWCA9IDI7Ci0gICAgcHJpdmF0ZSBmaW5hbCBJbnN0cnVjdGlvbiBfYXN0b3JlSGFuZGxlcjsKLSAgICBwcml2YXRlIGZpbmFsIEluc3RydWN0aW9uIF9hbG9hZEhhbmRsZXI7Ci0KLSAgICBwdWJsaWMgUnRNZXRob2RHZW5lcmF0b3IoaW50IGFjY2Vzc19mbGFncywgVHlwZSByZXR1cm5fdHlwZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHlwZVtdIGFyZ190eXBlcywgU3RyaW5nW10gYXJnX25hbWVzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbWV0aG9kX25hbWUsIFN0cmluZyBjbGFzc19uYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbnN0cnVjdGlvbkxpc3QgaWwsIENvbnN0YW50UG9vbEdlbiBjcCkgewotICAgICAgICBzdXBlcihhY2Nlc3NfZmxhZ3MsIHJldHVybl90eXBlLCBhcmdfdHlwZXMsIGFyZ19uYW1lcywgbWV0aG9kX25hbWUsCi0gICAgICAgICAgICAgIGNsYXNzX25hbWUsIGlsLCBjcCk7Ci0KLSAgICAgICAgX2FzdG9yZUhhbmRsZXIgPSBuZXcgQVNUT1JFKEhBTkRMRVJfSU5ERVgpOwotICAgICAgICBfYWxvYWRIYW5kbGVyICA9IG5ldyBBTE9BRChIQU5ETEVSX0lOREVYKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldEl0ZXJhdG9ySW5kZXgoKSB7Ci0gICAgICAgIHJldHVybiBJTlZBTElEX0lOREVYOyAgICAgICAgICAgLy8gbm90IGF2YWlsYWJsZQotICAgIH0KLQotICAgIHB1YmxpYyBmaW5hbCBJbnN0cnVjdGlvbiBzdG9yZUhhbmRsZXIoKSB7Ci0gICAgICAgIHJldHVybiBfYXN0b3JlSGFuZGxlcjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgZmluYWwgSW5zdHJ1Y3Rpb24gbG9hZEhhbmRsZXIoKSB7Ci0gICAgICAgIHJldHVybiBfYWxvYWRIYW5kbGVyOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgZ2V0TG9jYWxJbmRleChTdHJpbmcgbmFtZSkgewotICAgICAgICByZXR1cm4gSU5WQUxJRF9JTkRFWDsgICAgICAgICAgIC8vIG5vdCBhdmFpbGFibGUKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL3V0aWwvU2xvdEFsbG9jYXRvci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci91dGlsL1Nsb3RBbGxvY2F0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMGJkNzM4Ny4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL3V0aWwvU2xvdEFsbG9jYXRvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTAyICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFNsb3RBbGxvY2F0b3IuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8wNSAxMTozMjo1MSBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbDsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuTG9jYWxWYXJpYWJsZUdlbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlR5cGU7Ci0KLS8qKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqLwotZmluYWwgY2xhc3MgU2xvdEFsbG9jYXRvciB7Ci0KLSAgICBwcml2YXRlIGludCAgIF9maXJzdEF2YWlsYWJsZVNsb3Q7Ci0gICAgcHJpdmF0ZSBpbnQgICBfc2l6ZSA9IDg7Ci0gICAgcHJpdmF0ZSBpbnQgICBfZnJlZSA9IDA7Ci0gICAgcHJpdmF0ZSBpbnRbXSBfc2xvdHNUYWtlbiA9IG5ldyBpbnRbX3NpemVdOwotCi0gICAgcHVibGljIHZvaWQgaW5pdGlhbGl6ZShMb2NhbFZhcmlhYmxlR2VuW10gdmFycykgewotICAgICAgICBmaW5hbCBpbnQgbGVuZ3RoID0gdmFycy5sZW5ndGg7Ci0gICAgICAgIGludCBzbG90ID0gMCwgc2l6ZSwgaW5kZXg7Ci0KLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykgewotICAgICAgICAgICAgc2l6ZSAgPSB2YXJzW2ldLmdldFR5cGUoKS5nZXRTaXplKCk7Ci0gICAgICAgICAgICBpbmRleCA9IHZhcnNbaV0uZ2V0SW5kZXgoKTsKLSAgICAgICAgICAgIHNsb3QgID0gTWF0aC5tYXgoc2xvdCwgaW5kZXggKyBzaXplKTsKLSAgICAgICAgfQotICAgICAgICBfZmlyc3RBdmFpbGFibGVTbG90ID0gc2xvdDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGFsbG9jYXRlU2xvdChUeXBlIHR5cGUpIHsKLSAgICAgICAgZmluYWwgaW50IHNpemUgPSB0eXBlLmdldFNpemUoKTsKLSAgICAgICAgZmluYWwgaW50IGxpbWl0ID0gX2ZyZWU7Ci0gICAgICAgIGludCBzbG90ID0gX2ZpcnN0QXZhaWxhYmxlU2xvdCwgd2hlcmUgPSAwOwotCi0gICAgICAgIGlmIChfZnJlZSArIHNpemUgPiBfc2l6ZSkgewotICAgICAgICAgICAgZmluYWwgaW50W10gYXJyYXkgPSBuZXcgaW50W19zaXplICo9IDJdOwotICAgICAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBsaW1pdDsgaisrKQotICAgICAgICAgICAgICAgIGFycmF5W2pdID0gX3Nsb3RzVGFrZW5bal07Ci0gICAgICAgICAgICBfc2xvdHNUYWtlbiA9IGFycmF5OwotICAgICAgICB9Ci0KLSAgICAgICAgd2hpbGUgKHdoZXJlIDwgbGltaXQpIHsKLSAgICAgICAgICAgIGlmIChzbG90ICsgc2l6ZSA8PSBfc2xvdHNUYWtlblt3aGVyZV0pIHsKLSAgICAgICAgICAgICAgICAvLyBpbnNlcnQKLSAgICAgICAgICAgICAgICBmb3IgKGludCBqID0gbGltaXQgLSAxOyBqID49IHdoZXJlOyBqLS0pCi0gICAgICAgICAgICAgICAgICAgIF9zbG90c1Rha2VuW2ogKyBzaXplXSA9IF9zbG90c1Rha2VuW2pdOwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgc2xvdCA9IF9zbG90c1Rha2VuW3doZXJlKytdICsgMTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgc2l6ZTsgaisrKQotICAgICAgICAgICAgX3Nsb3RzVGFrZW5bd2hlcmUgKyBqXSA9IHNsb3QgKyBqOwotCi0gICAgICAgIF9mcmVlICs9IHNpemU7Ci0gICAgICAgIHJldHVybiBzbG90OwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHJlbGVhc2VTbG90KExvY2FsVmFyaWFibGVHZW4gbHZnKSB7Ci0gICAgICAgIGZpbmFsIGludCBzaXplID0gbHZnLmdldFR5cGUoKS5nZXRTaXplKCk7Ci0gICAgICAgIGZpbmFsIGludCBzbG90ID0gbHZnLmdldEluZGV4KCk7Ci0gICAgICAgIGZpbmFsIGludCBsaW1pdCA9IF9mcmVlOwotCi0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGltaXQ7IGkrKykgewotICAgICAgICAgICAgaWYgKF9zbG90c1Rha2VuW2ldID09IHNsb3QpIHsKLSAgICAgICAgICAgICAgICBpbnQgaiA9IGkgKyBzaXplOwotICAgICAgICAgICAgICAgIHdoaWxlIChqIDwgbGltaXQpIHsKLSAgICAgICAgICAgICAgICAgICAgX3Nsb3RzVGFrZW5baSsrXSA9IF9zbG90c1Rha2VuW2orK107Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIF9mcmVlIC09IHNpemU7Ci0gICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIFN0cmluZyBzdGF0ZSA9ICJWYXJpYWJsZSBzbG90IGFsbG9jYXRpb24gZXJyb3IiKwotICAgICAgICAgICAgICAgICAgICAgICAiKHNpemU9IitzaXplKyIsIHNsb3Q9IitzbG90KyIsIGxpbWl0PSIrbGltaXQrIikiOwotICAgICAgICBFcnJvck1zZyBlcnIgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuSU5URVJOQUxfRVJSLCBzdGF0ZSk7Ci0gICAgICAgIHRocm93IG5ldyBFcnJvcihlcnIudG9TdHJpbmcoKSk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci91dGlsL1N0cmluZ1N0YWNrLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL3V0aWwvU3RyaW5nU3RhY2suamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNGNkMmI1Ny4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL3V0aWwvU3RyaW5nU3RhY2suamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQ1ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFN0cmluZ1N0YWNrLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMDUgMTE6MzM6MzIgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWw7Ci0KLWltcG9ydCBqYXZhLnV0aWwuU3RhY2s7Ci0KLS8qKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgU3RyaW5nU3RhY2sgZXh0ZW5kcyBTdGFjayB7Ci0gICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC0xNTA2OTEwODc1NjQwMzE3ODk4TDsKLSAgICBwdWJsaWMgU3RyaW5nIHBlZWtTdHJpbmcoKSB7Ci0gICAgICAgIHJldHVybiAoU3RyaW5nKSBzdXBlci5wZWVrKCk7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBwb3BTdHJpbmcoKSB7Ci0gICAgICAgIHJldHVybiAoU3RyaW5nKSBzdXBlci5wb3AoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIHB1c2hTdHJpbmcoU3RyaW5nIHZhbCkgewotICAgICAgICByZXR1cm4gKFN0cmluZykgc3VwZXIucHVzaCh2YWwpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvdXRpbC9TdHJpbmdUeXBlLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL3V0aWwvU3RyaW5nVHlwZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3ODQ0ODJiLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvdXRpbC9TdHJpbmdUeXBlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMzEgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogU3RyaW5nVHlwZS5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzA1IDExOjM1OjU3IHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5BTE9BRDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkFTVE9SRTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkJyYW5jaEhhbmRsZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkNvbnN0YW50UG9vbEdlbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkdPVE87Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JRkVROwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSUZOT05OVUxMOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFU1RBVElDOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSU5WT0tFVklSVFVBTDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW5zdHJ1Y3Rpb25MaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuUFVTSDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIuQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci5GbG93TGlzdDsKLQotLyoqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKi8KLXB1YmxpYyBjbGFzcyBTdHJpbmdUeXBlIGV4dGVuZHMgVHlwZSB7Ci0gICAgcHJvdGVjdGVkIFN0cmluZ1R5cGUoKSB7fQotCi0gICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKLSAgICAgICAgcmV0dXJuICJzdHJpbmciOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGlkZW50aWNhbFRvKFR5cGUgb3RoZXIpIHsKLSAgICAgICAgcmV0dXJuIHRoaXMgPT0gb3RoZXI7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyB0b1NpZ25hdHVyZSgpIHsKLSAgICAgICAgcmV0dXJuICJMamF2YS9sYW5nL1N0cmluZzsiOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGlzU2ltcGxlKCkgewotICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5UeXBlIHRvSkNUeXBlKCkgewotICAgICAgICByZXR1cm4gY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5UeXBlLlNUUklORzsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGVzIGEgc3RyaW5nIGludG8gYW4gb2JqZWN0IG9mIGludGVybmFsIHR5cGUgPGNvZGU+dHlwZTwvY29kZT4uCi0gICAgICogVGhlIHRyYW5zbGF0aW9uIHRvIGludCBpcyB1bmRlZmluZWQgc2luY2Ugc3RyaW5ncyBhcmUgYWx3YXlzIGNvbnZlcnRlZAotICAgICAqIHRvIHJlYWxzIGluIGFyaXRobWV0aWMgZXhwcmVzc2lvbnMuCi0gICAgICoKLSAgICAgKiBAc2VlICAgICBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlI3RyYW5zbGF0ZVRvCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlVG8oQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgVHlwZSB0eXBlKSB7Ci0gICAgICAgIGlmICh0eXBlID09IFR5cGUuQm9vbGVhbikgewotICAgICAgICAgICAgdHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgKEJvb2xlYW5UeXBlKSB0eXBlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICh0eXBlID09IFR5cGUuUmVhbCkgewotICAgICAgICAgICAgdHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgKFJlYWxUeXBlKSB0eXBlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICh0eXBlID09IFR5cGUuUmVmZXJlbmNlKSB7Ci0gICAgICAgICAgICB0cmFuc2xhdGVUbyhjbGFzc0dlbiwgbWV0aG9kR2VuLCAoUmVmZXJlbmNlVHlwZSkgdHlwZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAodHlwZSA9PSBUeXBlLk9iamVjdFN0cmluZykgewotICAgICAgICAgICAgLy8gTk9QIC0+IHNhbWUgcmVwcmVzZW50YXRpb24KLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIEVycm9yTXNnIGVyciA9IG5ldyBFcnJvck1zZyhFcnJvck1zZy5EQVRBX0NPTlZFUlNJT05fRVJSLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvU3RyaW5nKCksIHR5cGUudG9TdHJpbmcoKSk7Ci0gICAgICAgICAgICBjbGFzc0dlbi5nZXRQYXJzZXIoKS5yZXBvcnRFcnJvcihDb25zdGFudHMuRkFUQUwsIGVycik7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGVzIGEgc3RyaW5nIGludG8gYSBzeW50aGVzaXplZCBib29sZWFuLgotICAgICAqCi0gICAgICogQHNlZSAgICAgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZSN0cmFuc2xhdGVUbwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZVRvKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJvb2xlYW5UeXBlIHR5cGUpIHsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotICAgICAgICBGbG93TGlzdCBmYWxzZWwgPSB0cmFuc2xhdGVUb0Rlc3ludGhlc2l6ZWQoY2xhc3NHZW4sIG1ldGhvZEdlbiwgdHlwZSk7Ci0gICAgICAgIGlsLmFwcGVuZChJQ09OU1RfMSk7Ci0gICAgICAgIGZpbmFsIEJyYW5jaEhhbmRsZSB0cnVlYyA9IGlsLmFwcGVuZChuZXcgR09UTyhudWxsKSk7Ci0gICAgICAgIGZhbHNlbC5iYWNrUGF0Y2goaWwuYXBwZW5kKElDT05TVF8wKSk7Ci0gICAgICAgIHRydWVjLnNldFRhcmdldChpbC5hcHBlbmQoTk9QKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhbnNsYXRlcyBhIHN0cmluZyBpbnRvIGEgcmVhbCBieSBjYWxsaW5nIHN0cmluZ1RvUmVhbCgpIGZyb20gdGhlCi0gICAgICogYmFzaXMgbGlicmFyeS4KLSAgICAgKgotICAgICAqIEBzZWUgICAgIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGUjdHJhbnNsYXRlVG8KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVUbyhDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZWFsVHlwZSB0eXBlKSB7Ci0gICAgICAgIGZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRVNUQVRJQyhjcGcuYWRkTWV0aG9kcmVmKEJBU0lTX0xJQlJBUllfQ0xBU1MsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU1RSSU5HX1RPX1JFQUwsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU1RSSU5HX1RPX1JFQUxfU0lHKSkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZXMgYSBzdHJpbmcgaW50byBhIG5vbi1zeW50aGVzaXplZCBib29sZWFuLiBJdCBkb2VzIG5vdCBwdXNoIGEKLSAgICAgKiAwIG9yIGEgMSBidXQgaW5zdGVhZCByZXR1cm5zIGJyYW5jaGhhbmRsZSBsaXN0IHRvIGJlIGFwcGVuZGVkIHRvIHRoZQotICAgICAqIGZhbHNlIGxpc3QuCi0gICAgICoKLSAgICAgKiBAc2VlICAgICBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlI3RyYW5zbGF0ZVRvRGVzeW50aGVzaXplZAotICAgICAqLwotICAgIHB1YmxpYyBGbG93TGlzdCB0cmFuc2xhdGVUb0Rlc3ludGhlc2l6ZWQoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQm9vbGVhblR5cGUgdHlwZSkgewotICAgICAgICBmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0gICAgICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQotICAgICAgICBpbC5hcHBlbmQobmV3IElOVk9LRVZJUlRVQUwoY3BnLmFkZE1ldGhvZHJlZihTVFJJTkdfQ0xBU1MsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJsZW5ndGgiLCAiKClJIikpKTsKLSAgICAgICAgcmV0dXJuIG5ldyBGbG93TGlzdChpbC5hcHBlbmQobmV3IElGRVEobnVsbCkpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBFeHBlY3RzIGEgc3RyaW5nIG9uIHRoZSBzdGFjayBhbmQgcHVzaGVzIGEgYm94ZWQgc3RyaW5nLgotICAgICAqIFN0cmluZ3MgYXJlIGFscmVhZHkgYm94ZWQgc28gdGhlIHRyYW5zbGF0aW9uIGlzIGp1c3QgYSBOT1AuCi0gICAgICoKLSAgICAgKiBAc2VlICAgICBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlI3RyYW5zbGF0ZVRvCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlVG8oQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVmZXJlbmNlVHlwZSB0eXBlKSB7Ci0gICAgICAgIG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKS5hcHBlbmQoTk9QKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGVzIGEgaW50ZXJuYWwgc3RyaW5nIGludG8gYW4gZXh0ZXJuYWwgKEphdmEpIHN0cmluZy4KLSAgICAgKgotICAgICAqIEBzZWUgICAgIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLlR5cGUjdHJhbnNsYXRlRnJvbQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZVRvKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIENsYXNzIGNsYXp6KQotICAgIHsKLSAgICAgICAgLy8gSXMgU3RyaW5nIDw6IGNsYXp6PyBJLmUuIGNsYXp6IGluIHsgU3RyaW5nLCBPYmplY3QgfQotICAgICAgICBpZiAoY2xhenouaXNBc3NpZ25hYmxlRnJvbShqYXZhLmxhbmcuU3RyaW5nLmNsYXNzKSkgewotICAgICAgICAgICAgbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpLmFwcGVuZChOT1ApOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgRXJyb3JNc2cgZXJyID0gbmV3IEVycm9yTXNnKEVycm9yTXNnLkRBVEFfQ09OVkVSU0lPTl9FUlIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG9TdHJpbmcoKSwgY2xhenouZ2V0TmFtZSgpKTsKLSAgICAgICAgICAgIGNsYXNzR2VuLmdldFBhcnNlcigpLnJlcG9ydEVycm9yKENvbnN0YW50cy5GQVRBTCwgZXJyKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZXMgYW4gZXh0ZXJuYWwgKHByaW1pdGl2ZSkgSmF2YSB0eXBlIGludG8gYSBzdHJpbmcuCi0gICAgICoKLSAgICAgKiBAc2VlICAgICBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlI3RyYW5zbGF0ZUZyb20KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVGcm9tKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotICAgICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLCBDbGFzcyBjbGF6eikKLSAgICB7Ci0gICAgICAgIGZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLSAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCi0gICAgICAgIGlmIChjbGF6ei5nZXROYW1lKCkuZXF1YWxzKCJqYXZhLmxhbmcuU3RyaW5nIikpIHsKLSAgICAgICAgICAgIC8vIHNhbWUgaW50ZXJuYWwgcmVwcmVzZW50YXRpb24sIGNvbnZlcnQgbnVsbCB0byAiIgotICAgICAgICAgICAgaWwuYXBwZW5kKERVUCk7Ci0gICAgICAgICAgICBmaW5hbCBCcmFuY2hIYW5kbGUgaWZOb25OdWxsID0gaWwuYXBwZW5kKG5ldyBJRk5PTk5VTEwobnVsbCkpOwotICAgICAgICAgICAgaWwuYXBwZW5kKFBPUCk7Ci0gICAgICAgICAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCAiIikpOwotICAgICAgICAgICAgaWZOb25OdWxsLnNldFRhcmdldChpbC5hcHBlbmQoTk9QKSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBFcnJvck1zZyBlcnIgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuREFUQV9DT05WRVJTSU9OX0VSUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b1N0cmluZygpLCBjbGF6ei5nZXROYW1lKCkpOwotICAgICAgICAgICAgY2xhc3NHZW4uZ2V0UGFyc2VyKCkucmVwb3J0RXJyb3IoQ29uc3RhbnRzLkZBVEFMLCBlcnIpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhbnNsYXRlcyBhbiBvYmplY3Qgb2YgdGhpcyB0eXBlIHRvIGl0cyBib3hlZCByZXByZXNlbnRhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVCb3goQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLSAgICAgICAgdHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgVHlwZS5SZWZlcmVuY2UpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZXMgYW4gb2JqZWN0IG9mIHRoaXMgdHlwZSB0byBpdHMgdW5ib3hlZCByZXByZXNlbnRhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVVbkJveChDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0gICAgICAgIG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKS5hcHBlbmQoTk9QKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBjbGFzcyBuYW1lIG9mIGFuIGludGVybmFsIHR5cGUncyBleHRlcm5hbCByZXByZXNlbnRhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldENsYXNzTmFtZSgpIHsKLSAgICAgICAgcmV0dXJuKFNUUklOR19DTEFTUyk7Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb24gTE9BRChpbnQgc2xvdCkgewotICAgICAgICByZXR1cm4gbmV3IEFMT0FEKHNsb3QpOwotICAgIH0KLQotICAgIHB1YmxpYyBJbnN0cnVjdGlvbiBTVE9SRShpbnQgc2xvdCkgewotICAgICAgICByZXR1cm4gbmV3IEFTVE9SRShzbG90KTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL3V0aWwvVGVzdEdlbmVyYXRvci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci91dGlsL1Rlc3RHZW5lcmF0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZjZhNjJjMC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL3V0aWwvVGVzdEdlbmVyYXRvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTE3ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFRlc3RHZW5lcmF0b3IuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8wNSAxMTozNjo0OSBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbDsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQUxPQUQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5BU1RPUkU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5Db25zdGFudFBvb2xHZW47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JTE9BRDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLklTVE9SRTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW5zdHJ1Y3Rpb25MaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuVHlwZTsKLQotLyoqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIFRlc3RHZW5lcmF0b3IgZXh0ZW5kcyBNZXRob2RHZW5lcmF0b3IgewotICAgIHByaXZhdGUgc3RhdGljIGludCBDT05URVhUX05PREVfSU5ERVggPSAxOwotICAgIHByaXZhdGUgc3RhdGljIGludCBDVVJSRU5UX05PREVfSU5ERVggPSA0OwotICAgIHByaXZhdGUgc3RhdGljIGludCBJVEVSQVRPUl9JTkRFWCA9IDY7Ci0KLSAgICBwcml2YXRlIEluc3RydWN0aW9uIF9hbG9hZERvbTsKLSAgICBwcml2YXRlIGZpbmFsIEluc3RydWN0aW9uIF9pbG9hZEN1cnJlbnQ7Ci0gICAgcHJpdmF0ZSBmaW5hbCBJbnN0cnVjdGlvbiBfaWxvYWRDb250ZXh0OwotICAgIHByaXZhdGUgZmluYWwgSW5zdHJ1Y3Rpb24gX2lzdG9yZUN1cnJlbnQ7Ci0gICAgcHJpdmF0ZSBmaW5hbCBJbnN0cnVjdGlvbiBfaXN0b3JlQ29udGV4dDsKLSAgICBwcml2YXRlIGZpbmFsIEluc3RydWN0aW9uIF9hc3RvcmVJdGVyYXRvcjsKLSAgICBwcml2YXRlIGZpbmFsIEluc3RydWN0aW9uIF9hbG9hZEl0ZXJhdG9yOwotCi0gICAgcHVibGljIFRlc3RHZW5lcmF0b3IoaW50IGFjY2Vzc19mbGFncywgVHlwZSByZXR1cm5fdHlwZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlW10gYXJnX3R5cGVzLCBTdHJpbmdbXSBhcmdfbmFtZXMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG1ldGhvZF9uYW1lLCBTdHJpbmcgY2xhc3NfbmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICBJbnN0cnVjdGlvbkxpc3QgaWwsIENvbnN0YW50UG9vbEdlbiBjcCkgewotICAgICAgICBzdXBlcihhY2Nlc3NfZmxhZ3MsIHJldHVybl90eXBlLCBhcmdfdHlwZXMsIGFyZ19uYW1lcywgbWV0aG9kX25hbWUsCi0gICAgICAgICAgICAgIGNsYXNzX25hbWUsIGlsLCBjcCk7Ci0KLSAgICAgICAgX2lsb2FkQ3VycmVudCAgPSBuZXcgSUxPQUQoQ1VSUkVOVF9OT0RFX0lOREVYKTsKLSAgICAgICAgX2lzdG9yZUN1cnJlbnQgPSBuZXcgSVNUT1JFKENVUlJFTlRfTk9ERV9JTkRFWCk7Ci0gICAgICAgIF9pbG9hZENvbnRleHQgID0gbmV3IElMT0FEKENPTlRFWFRfTk9ERV9JTkRFWCk7Ci0gICAgICAgIF9pc3RvcmVDb250ZXh0ICA9IG5ldyBJTE9BRChDT05URVhUX05PREVfSU5ERVgpOwotICAgICAgICBfYXN0b3JlSXRlcmF0b3IgPSBuZXcgQVNUT1JFKElURVJBVE9SX0lOREVYKTsKLSAgICAgICAgX2Fsb2FkSXRlcmF0b3IgID0gbmV3IEFMT0FEKElURVJBVE9SX0lOREVYKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldEhhbmRsZXJJbmRleCgpIHsKLSAgICAgICAgcmV0dXJuIElOVkFMSURfSU5ERVg7ICAgICAgICAgICAvLyBub3QgYXZhaWxhYmxlCi0gICAgfQotCi0gICAgcHVibGljIGludCBnZXRJdGVyYXRvckluZGV4KCkgewotICAgICAgICByZXR1cm4gSVRFUkFUT1JfSU5ERVg7ICAgICAgICAgIC8vIG5vdCBhdmFpbGFibGUKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXREb21JbmRleChpbnQgZG9tSW5kZXgpIHsKLSAgICAgICAgX2Fsb2FkRG9tID0gbmV3IEFMT0FEKGRvbUluZGV4KTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb24gbG9hZERPTSgpIHsKLSAgICAgICAgcmV0dXJuIF9hbG9hZERvbTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb24gbG9hZEN1cnJlbnROb2RlKCkgewotICAgICAgICByZXR1cm4gX2lsb2FkQ3VycmVudDsKLSAgICB9Ci0KLSAgICAvKiogYnkgZGVmYXVsdCBjb250ZXh0IG5vZGUgaXMgdGhlIHNhbWUgYXMgY3VycmVudCBub2RlLiBNSzQzNyAqLwotICAgIHB1YmxpYyBJbnN0cnVjdGlvbiBsb2FkQ29udGV4dE5vZGUoKSB7Ci0gICAgICAgIHJldHVybiBfaWxvYWRDb250ZXh0OwotICAgIH0KLQotICAgIHB1YmxpYyBJbnN0cnVjdGlvbiBzdG9yZUNvbnRleHROb2RlKCkgewotICAgICAgICByZXR1cm4gX2lzdG9yZUNvbnRleHQ7Ci0gICAgfQotCi0gICAgcHVibGljIEluc3RydWN0aW9uIHN0b3JlQ3VycmVudE5vZGUoKSB7Ci0gICAgICAgIHJldHVybiBfaXN0b3JlQ3VycmVudDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb24gc3RvcmVJdGVyYXRvcigpIHsKLSAgICAgICAgcmV0dXJuIF9hc3RvcmVJdGVyYXRvcjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb24gbG9hZEl0ZXJhdG9yKCkgewotICAgICAgICByZXR1cm4gX2Fsb2FkSXRlcmF0b3I7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBnZXRMb2NhbEluZGV4KFN0cmluZyBuYW1lKSB7Ci0gICAgICAgIGlmIChuYW1lLmVxdWFscygiY3VycmVudCIpKSB7Ci0gICAgICAgICAgICByZXR1cm4gQ1VSUkVOVF9OT0RFX0lOREVYOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmdldExvY2FsSW5kZXgobmFtZSk7Ci0gICAgICAgIH0KLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL3V0aWwvVHlwZS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci91dGlsL1R5cGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYjA4MjlkYy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL3V0aWwvVHlwZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjk4ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFR5cGUuamF2YSx2IDEuOCAyMDA3LzAzLzI4IDE2OjUxOjE5IGpvZWh3IEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbDsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuQnJhbmNoSW5zdHJ1Y3Rpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5JbnN0cnVjdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIuQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci5GbG93TGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIuTm9kZVRlc3Q7Ci0KLS8qKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKi8KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBUeXBlIGltcGxlbWVudHMgQ29uc3RhbnRzIHsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFR5cGUgSW50ICAgICAgICA9IG5ldyBJbnRUeXBlKCk7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBUeXBlIFJlYWwgICAgICAgPSBuZXcgUmVhbFR5cGUoKTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFR5cGUgQm9vbGVhbiAgICA9IG5ldyBCb29sZWFuVHlwZSgpOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVHlwZSBOb2RlU2V0ICAgID0gbmV3IE5vZGVTZXRUeXBlKCk7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBUeXBlIFN0cmluZyAgICAgPSBuZXcgU3RyaW5nVHlwZSgpOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVHlwZSBSZXN1bHRUcmVlID0gbmV3IFJlc3VsdFRyZWVUeXBlKCk7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBUeXBlIFJlZmVyZW5jZSAgPSBuZXcgUmVmZXJlbmNlVHlwZSgpOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVHlwZSBWb2lkICAgICAgID0gbmV3IFZvaWRUeXBlKCk7Ci0KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFR5cGUgT2JqZWN0ICAgICAgID0gbmV3IE9iamVjdFR5cGUoamF2YS5sYW5nLk9iamVjdC5jbGFzcyk7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBUeXBlIE9iamVjdFN0cmluZyA9IG5ldyBPYmplY3RUeXBlKGphdmEubGFuZy5TdHJpbmcuY2xhc3MpOwotCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBUeXBlIE5vZGUgICAgICAgPSBuZXcgTm9kZVR5cGUoTm9kZVRlc3QuQU5PREUpOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVHlwZSBSb290ICAgICAgID0gbmV3IE5vZGVUeXBlKE5vZGVUZXN0LlJPT1QpOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVHlwZSBFbGVtZW50ICAgID0gbmV3IE5vZGVUeXBlKE5vZGVUZXN0LkVMRU1FTlQpOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVHlwZSBBdHRyaWJ1dGUgID0gbmV3IE5vZGVUeXBlKE5vZGVUZXN0LkFUVFJJQlVURSk7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBUeXBlIFRleHQgICAgICAgPSBuZXcgTm9kZVR5cGUoTm9kZVRlc3QuVEVYVCk7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBUeXBlIENvbW1lbnQgICAgPSBuZXcgTm9kZVR5cGUoTm9kZVRlc3QuQ09NTUVOVCk7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBUeXBlIFByb2Nlc3NpbmdfSW5zdHJ1Y3Rpb24gPSBuZXcgTm9kZVR5cGUoTm9kZVRlc3QuUEkpOwotCi0gICAgLyoqCi0gICAgICogRmFjdG9yeSBtZXRob2QgdG8gaW5zdGFudGlhdGUgb2JqZWN0IHR5cGVzLiBSZXR1cm5zIGEgcHJlLWRlZmluZWQKLSAgICAgKiBpbnN0YW5jZSBmb3IgImphdmEubGFuZy5PYmplY3QiIGFuZCAiamF2YS5sYW5nLlN0cmluZyIuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBUeXBlIG5ld09iamVjdFR5cGUoU3RyaW5nIGphdmFDbGFzc05hbWUpIHsKLSAgICAgICAgaWYgKGphdmFDbGFzc05hbWUgPT0gImphdmEubGFuZy5PYmplY3QiKSB7Ci0gICAgICAgICAgICByZXR1cm4gVHlwZS5PYmplY3Q7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoamF2YUNsYXNzTmFtZSA9PSAiamF2YS5sYW5nLlN0cmluZyIpIHsKLSAgICAgICAgICAgIHJldHVybiBUeXBlLk9iamVjdFN0cmluZzsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICBqYXZhLnNlY3VyaXR5LkFjY2Vzc0NvbnRyb2xDb250ZXh0IGFjYyA9IGphdmEuc2VjdXJpdHkuQWNjZXNzQ29udHJvbGxlci5nZXRDb250ZXh0KCk7Ci0gICAgICAgICAgICBhY2MuY2hlY2tQZXJtaXNzaW9uKG5ldyBSdW50aW1lUGVybWlzc2lvbigiZ2V0Q29udGV4dENsYXNzTG9hZGVyIikpOwotICAgICAgICAgICAgcmV0dXJuIG5ldyBPYmplY3RUeXBlKGphdmFDbGFzc05hbWUpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAvKioKLSAgICAgKiBGYWN0b3J5IG1ldGhvZCB0byBpbnN0YW50aWF0ZSBvYmplY3QgdHlwZXMuIFJldHVybnMgYSBwcmUtZGVmaW5lZAotICAgICAqIGluc3RhbmNlIGZvciBqYXZhLmxhbmcuT2JqZWN0LmNsYXNzIGFuZCBqYXZhLmxhbmcuU3RyaW5nLmNsYXNzLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgVHlwZSBuZXdPYmplY3RUeXBlKENsYXNzIGNsYXp6KSB7Ci0gICAgICAgIGlmIChjbGF6eiA9PSBqYXZhLmxhbmcuT2JqZWN0LmNsYXNzKSB7Ci0gICAgICAgICAgICByZXR1cm4gVHlwZS5PYmplY3Q7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoY2xhenogPT0gamF2YS5sYW5nLlN0cmluZy5jbGFzcykgewotICAgICAgICAgICAgcmV0dXJuIFR5cGUuT2JqZWN0U3RyaW5nOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIG5ldyBPYmplY3RUeXBlKGNsYXp6KTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyB0eXBlLgotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCBTdHJpbmcgdG9TdHJpbmcoKTsKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGlzIGFuZCBvdGhlciBhcmUgaWRlbnRpY2FsIHR5cGVzLgotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGlkZW50aWNhbFRvKFR5cGUgb3RoZXIpOwotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIGlmIHRoaXMgdHlwZSBpcyBhIG51bWVyaWMgdHlwZS4gUmVkZWZpbmVkIGluIE51bWJlclR5cGUuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNOdW1iZXIoKSB7Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhpcyB0eXBlIGhhcyBubyBvYmplY3QgcmVwcmVzZW50YWlvbi4gUmVkZWZpbmVkIGluCi0gICAgICogUmVzdWx0VHJlZVR5cGUuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaW1wbGVtZW50ZWRBc01ldGhvZCgpIHsKLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGlzIHR5cGUgaXMgYSBzaW1wbGUgdHlwZS4gUmVkZWZpbmVkIGluIE51bWJlclR5cGUsCi0gICAgICogQm9vbGVhblR5cGUgYW5kIFN0cmluZ1R5cGUuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNTaW1wbGUoKSB7Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYWJzdHJhY3QgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5UeXBlIHRvSkNUeXBlKCk7Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBkaXN0YW5jZSBiZXR3ZWVuIHR3byB0eXBlcy4gVGhpcyBtZWFzdXJlIGlzIHVzZWQgdG8gc2VsZWN0Ci0gICAgICogb3ZlcmxvYWRlZCBmdW5jdGlvbnMvb3BlcmF0b3JzLiBUaGlzIG1ldGhvZCBpcyB0eXBpY2FsbHkgcmVkZWZpbmVkIGJ5Ci0gICAgICogdGhlIHN1YmNsYXNzZXMuCi0gICAgICovCi0gICAgcHVibGljIGludCBkaXN0YW5jZVRvKFR5cGUgdHlwZSkgewotICAgICAgICByZXR1cm4gdHlwZSA9PSB0aGlzID8gMCA6IEludGVnZXIuTUFYX1ZBTFVFOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIHNpZ25hdHVyZSBvZiBhbiBpbnRlcm5hbCB0eXBlJ3MgZXh0ZXJuYWwgcmVwcmVzZW50YXRpb24uCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IFN0cmluZyB0b1NpZ25hdHVyZSgpOwotCi0gICAgLyoqCi0gICAgICogVHJhbnNsYXRlcyBhbiBvYmplY3Qgb2YgdGhpcyB0eXBlIHRvIGFuIG9iamVjdCBvZiB0eXBlCi0gICAgICogPGNvZGU+dHlwZTwvY29kZT4uCi0gICAgICogRXhwZWN0cyBhbiBvYmplY3Qgb2YgdGhlIGZvcm1lciB0eXBlIGFuZCBwdXNoZXMgYW4gb2JqZWN0IG9mIHRoZSBsYXR0ZXIuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlVG8oQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgVHlwZSB0eXBlKSB7Ci0gICAgICAgIEVycm9yTXNnIGVyciA9IG5ldyBFcnJvck1zZyhFcnJvck1zZy5EQVRBX0NPTlZFUlNJT05fRVJSLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG9TdHJpbmcoKSwgdHlwZS50b1N0cmluZygpKTsKLSAgICAgICAgY2xhc3NHZW4uZ2V0UGFyc2VyKCkucmVwb3J0RXJyb3IoQ29uc3RhbnRzLkZBVEFMLCBlcnIpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZXMgb2JqZWN0IG9mIHRoaXMgdHlwZSB0byBhbiBvYmplY3Qgb2YgdHlwZSA8Y29kZT50eXBlPC9jb2RlPi4KLSAgICAgKiBFeHBlY3RzIGFuIG9iamVjdCBvZiB0aGUgZm9ybWVyIHR5cGUgYW5kIHB1c2hlcyBhbiBvYmplY3Qgb2YgdGhlIGxhdHRlcgotICAgICAqIGlmIG5vdCBib29sZWFuLiBJZiB0eXBlIDxjb2RlPnR5cGU8L2NvZGU+IGlzIGJvb2xlYW4gdGhlbiBhIGJyYW5jaGhhbmRsZQotICAgICAqIGxpc3QgKHRvIGJlIGFwcGVuZGVkIHRvIHRoZSBmYWxzZSBsaXN0KSBpcyByZXR1cm5lZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgRmxvd0xpc3QgdHJhbnNsYXRlVG9EZXN5bnRoZXNpemVkKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFR5cGUgdHlwZSkgewotICAgICAgICBGbG93TGlzdCBmbCA9IG51bGw7Ci0gICAgICAgIGlmICh0eXBlID09IFR5cGUuQm9vbGVhbikgewotICAgICAgICAgICAgZmwgPSB0cmFuc2xhdGVUb0Rlc3ludGhlc2l6ZWQoY2xhc3NHZW4sIG1ldGhvZEdlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChCb29sZWFuVHlwZSl0eXBlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHRyYW5zbGF0ZVRvKGNsYXNzR2VuLCBtZXRob2RHZW4sIHR5cGUpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGVzIGFuIG9iamVjdCBvZiB0aGlzIHR5cGUgdG8gYW4gbm9uLXN5bnRoZXNpemVkIGJvb2xlYW4uIEl0Ci0gICAgICogZG9lcyBub3QgcHVzaCBhIDAgb3IgYSAxIGJ1dCBpbnN0ZWFkIHJldHVybnMgYnJhbmNoaGFuZGxlIGxpc3QgdG8gYmUKLSAgICAgKiBhcHBlbmRlZCB0byB0aGUgZmFsc2UgbGlzdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgRmxvd0xpc3QgdHJhbnNsYXRlVG9EZXN5bnRoZXNpemVkKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJvb2xlYW5UeXBlIHR5cGUpIHsKLSAgICAgICAgRXJyb3JNc2cgZXJyID0gbmV3IEVycm9yTXNnKEVycm9yTXNnLkRBVEFfQ09OVkVSU0lPTl9FUlIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b1N0cmluZygpLCB0eXBlLnRvU3RyaW5nKCkpOwotICAgICAgICBjbGFzc0dlbi5nZXRQYXJzZXIoKS5yZXBvcnRFcnJvcihDb25zdGFudHMuRkFUQUwsIGVycik7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZXMgYW4gb2JqZWN0IG9mIHRoaXMgdHlwZSB0byB0aGUgZXh0ZXJuYWwgKEphdmEpIHR5cGUgZGVub3RlZAotICAgICAqIGJ5IDxjb2RlPmNsYXp6PC9jb2RlPi4gVGhpcyBtZXRob2QgaXMgdXNlZCB0byB0cmFuc2xhdGUgcGFyYW1ldGVycwotICAgICAqIHdoZW4gZXh0ZXJuYWwgZnVuY3Rpb25zIGFyZSBjYWxsZWQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlVG8oQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2xhc3MgY2xhenopIHsKLSAgICAgICAgRXJyb3JNc2cgZXJyID0gbmV3IEVycm9yTXNnKEVycm9yTXNnLkRBVEFfQ09OVkVSU0lPTl9FUlIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b1N0cmluZygpLCBjbGF6ei5nZXRDbGFzcygpLnRvU3RyaW5nKCkpOwotICAgICAgICBjbGFzc0dlbi5nZXRQYXJzZXIoKS5yZXBvcnRFcnJvcihDb25zdGFudHMuRkFUQUwsIGVycik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhbnNsYXRlcyBhbiBleHRlcm5hbCAoSmF2YSkgdHlwZSBkZW5vdGVkIGJ5IDxjb2RlPmNsYXp6PC9jb2RlPiB0bwotICAgICAqIGFuIG9iamVjdCBvZiB0aGlzIHR5cGUuIFRoaXMgbWV0aG9kIGlzIHVzZWQgdG8gdHJhbnNsYXRlIHJldHVybiB2YWx1ZXMKLSAgICAgKiB3aGVuIGV4dGVybmFsIGZ1bmN0aW9ucyBhcmUgY2FsbGVkLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZUZyb20oQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDbGFzcyBjbGF6eikgewotICAgICAgICBFcnJvck1zZyBlcnIgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuREFUQV9DT05WRVJTSU9OX0VSUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXp6LmdldENsYXNzKCkudG9TdHJpbmcoKSwgdG9TdHJpbmcoKSk7Ci0gICAgICAgIGNsYXNzR2VuLmdldFBhcnNlcigpLnJlcG9ydEVycm9yKENvbnN0YW50cy5GQVRBTCwgZXJyKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGVzIGFuIG9iamVjdCBvZiB0aGlzIHR5cGUgdG8gaXRzIGJveGVkIHJlcHJlc2VudGF0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZUJveChDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotICAgICAgICBFcnJvck1zZyBlcnIgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuREFUQV9DT05WRVJTSU9OX0VSUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvU3RyaW5nKCksICJbIit0b1N0cmluZygpKyJdIik7Ci0gICAgICAgIGNsYXNzR2VuLmdldFBhcnNlcigpLnJlcG9ydEVycm9yKENvbnN0YW50cy5GQVRBTCwgZXJyKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGVzIGFuIG9iamVjdCBvZiB0aGlzIHR5cGUgdG8gaXRzIHVuYm94ZWQgcmVwcmVzZW50YXRpb24uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlVW5Cb3goQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotICAgICAgICBFcnJvck1zZyBlcnIgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuREFUQV9DT05WRVJTSU9OX0VSUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJbIit0b1N0cmluZygpKyJdIiwgdG9TdHJpbmcoKSk7Ci0gICAgICAgIGNsYXNzR2VuLmdldFBhcnNlcigpLnJlcG9ydEVycm9yKENvbnN0YW50cy5GQVRBTCwgZXJyKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBjbGFzcyBuYW1lIG9mIGFuIGludGVybmFsIHR5cGUncyBleHRlcm5hbCByZXByZXNlbnRhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldENsYXNzTmFtZSgpIHsKLSAgICAgICAgcmV0dXJuKEVNUFRZU1RSSU5HKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb24gQUREKCkgewotICAgICAgICByZXR1cm4gbnVsbDsgICAgICAgICAgICAvLyBzaG91bGQgbmV2ZXIgYmUgY2FsbGVkCi0gICAgfQotCi0gICAgcHVibGljIEluc3RydWN0aW9uIFNVQigpIHsKLSAgICAgICAgcmV0dXJuIG51bGw7ICAgICAgICAgICAgLy8gc2hvdWxkIG5ldmVyIGJlIGNhbGxlZAotICAgIH0KLQotICAgIHB1YmxpYyBJbnN0cnVjdGlvbiBNVUwoKSB7Ci0gICAgICAgIHJldHVybiBudWxsOyAgICAgICAgICAgIC8vIHNob3VsZCBuZXZlciBiZSBjYWxsZWQKLSAgICB9Ci0KLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb24gRElWKCkgewotICAgICAgICByZXR1cm4gbnVsbDsgICAgICAgICAgICAvLyBzaG91bGQgbmV2ZXIgYmUgY2FsbGVkCi0gICAgfQotCi0gICAgcHVibGljIEluc3RydWN0aW9uIFJFTSgpIHsKLSAgICAgICAgcmV0dXJuIG51bGw7ICAgICAgICAgICAgLy8gc2hvdWxkIG5ldmVyIGJlIGNhbGxlZAotICAgIH0KLQotICAgIHB1YmxpYyBJbnN0cnVjdGlvbiBORUcoKSB7Ci0gICAgICAgIHJldHVybiBudWxsOyAgICAgICAgICAgIC8vIHNob3VsZCBuZXZlciBiZSBjYWxsZWQKLSAgICB9Ci0KLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb24gTE9BRChpbnQgc2xvdCkgewotICAgICAgICByZXR1cm4gbnVsbDsgICAgICAgICAgICAvLyBzaG91bGQgbmV2ZXIgYmUgY2FsbGVkCi0gICAgfQotCi0gICAgcHVibGljIEluc3RydWN0aW9uIFNUT1JFKGludCBzbG90KSB7Ci0gICAgICAgIHJldHVybiBudWxsOyAgICAgICAgICAgIC8vIHNob3VsZCBuZXZlciBiZSBjYWxsZWQKLSAgICB9Ci0KLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb24gUE9QKCkgewotICAgICAgICByZXR1cm4gUE9QOwotICAgIH0KLQotICAgIHB1YmxpYyBCcmFuY2hJbnN0cnVjdGlvbiBHVChib29sZWFuIHRvemVybykgewotICAgICAgICByZXR1cm4gbnVsbDsgICAgICAgICAgICAvLyBzaG91bGQgbmV2ZXIgYmUgY2FsbGVkCi0gICAgfQotCi0gICAgcHVibGljIEJyYW5jaEluc3RydWN0aW9uIEdFKGJvb2xlYW4gdG96ZXJvKSB7Ci0gICAgICAgIHJldHVybiBudWxsOyAgICAgICAgICAgIC8vIHNob3VsZCBuZXZlciBiZSBjYWxsZWQKLSAgICB9Ci0KLSAgICBwdWJsaWMgQnJhbmNoSW5zdHJ1Y3Rpb24gTFQoYm9vbGVhbiB0b3plcm8pIHsKLSAgICAgICAgcmV0dXJuIG51bGw7ICAgICAgICAgICAgLy8gc2hvdWxkIG5ldmVyIGJlIGNhbGxlZAotICAgIH0KLQotICAgIHB1YmxpYyBCcmFuY2hJbnN0cnVjdGlvbiBMRShib29sZWFuIHRvemVybykgewotICAgICAgICByZXR1cm4gbnVsbDsgICAgICAgICAgICAvLyBzaG91bGQgbmV2ZXIgYmUgY2FsbGVkCi0gICAgfQotCi0gICAgcHVibGljIEluc3RydWN0aW9uIENNUChib29sZWFuIGxlc3MpIHsKLSAgICAgICAgcmV0dXJuIG51bGw7ICAgICAgICAgICAgLy8gc2hvdWxkIG5ldmVyIGJlIGNhbGxlZAotICAgIH0KLQotICAgIHB1YmxpYyBJbnN0cnVjdGlvbiBEVVAoKSB7Ci0gICAgICAgIHJldHVybiBEVVA7ICAgICAvLyBkZWZhdWx0Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci91dGlsL1R5cGVDaGVja0Vycm9yLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL3V0aWwvVHlwZUNoZWNrRXJyb3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNzRhZWQ2NC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL3V0aWwvVHlwZUNoZWNrRXJyb3IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDc5ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFR5cGVDaGVja0Vycm9yLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMDUgMTE6NDI6NTcgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWw7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIuU3ludGF4VHJlZU5vZGU7Ci0KLS8qKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICovCi1wdWJsaWMgY2xhc3MgVHlwZUNoZWNrRXJyb3IgZXh0ZW5kcyBFeGNlcHRpb24gewotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAzMjQ2MjI0MjMzOTE3ODU0NjQwTDsKLSAgICBFcnJvck1zZyBfZXJyb3IgPSBudWxsOwotICAgIFN5bnRheFRyZWVOb2RlIF9ub2RlID0gbnVsbDsKLQotICAgIHB1YmxpYyBUeXBlQ2hlY2tFcnJvcihTeW50YXhUcmVlTm9kZSBub2RlKSB7Ci0gICAgICAgIHN1cGVyKCk7Ci0gICAgICAgIF9ub2RlID0gbm9kZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgVHlwZUNoZWNrRXJyb3IoRXJyb3JNc2cgZXJyb3IpIHsKLSAgICAgICAgc3VwZXIoKTsKLSAgICAgICAgX2Vycm9yID0gZXJyb3I7Ci0gICAgfQotCi0gICAgcHVibGljIFR5cGVDaGVja0Vycm9yKFN0cmluZyBjb2RlLCBPYmplY3QgcGFyYW0pIHsKLSAgICAgICAgc3VwZXIoKTsKLSAgICAgICAgX2Vycm9yID0gbmV3IEVycm9yTXNnKGNvZGUsIHBhcmFtKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgVHlwZUNoZWNrRXJyb3IoU3RyaW5nIGNvZGUsIE9iamVjdCBwYXJhbTEsIE9iamVjdCBwYXJhbTIpIHsKLSAgICAgICAgc3VwZXIoKTsKLSAgICAgICAgX2Vycm9yID0gbmV3IEVycm9yTXNnKGNvZGUsIHBhcmFtMSwgcGFyYW0yKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgRXJyb3JNc2cgZ2V0RXJyb3JNc2coKSB7Ci0gICAgICAgIHJldHVybiBfZXJyb3I7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRNZXNzYWdlKCkgewotICAgICAgICByZXR1cm4gdG9TdHJpbmcoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgICAgICBTdHJpbmcgcmVzdWx0OwotCi0gICAgICAgIGlmIChfZXJyb3IgPT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKF9ub2RlICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBfZXJyb3IgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuVFlQRV9DSEVDS19FUlIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9ub2RlLnRvU3RyaW5nKCkpOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBfZXJyb3IgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuVFlQRV9DSEVDS19VTktfTE9DX0VSUik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gX2Vycm9yLnRvU3RyaW5nKCk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci91dGlsL1V0aWwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvdXRpbC9VdGlsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGYxZjkyMjIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci91dGlsL1V0aWwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIwNCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBVdGlsLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTIgMTE6NDc6MTUgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWw7Ci0KLWltcG9ydCBqYXZhLnV0aWwuU3RyaW5nVG9rZW5pemVyOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy5UeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC51dGlscy5TZWN1cml0eVN1cHBvcnQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLkNvbnN0YW50czsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLlhNTDExQ2hhcjsKLQotLyoqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBVdGlsIHsKLSAgICBwcml2YXRlIHN0YXRpYyBjaGFyIGZpbGVzZXA7Ci0KLSAgICBzdGF0aWMgewotICAgICAgICBTdHJpbmcgdGVtcCA9IFNlY3VyaXR5U3VwcG9ydC5nZXRTeXN0ZW1Qcm9wZXJ0eSgiZmlsZS5zZXBhcmF0b3IiLCAiLyIpOwotICAgICAgICBmaWxlc2VwID0gdGVtcC5jaGFyQXQoMCk7Ci0gICAgfQotCi0gICAgcHVibGljIHN0YXRpYyBTdHJpbmcgbm9FeHROYW1lKFN0cmluZyBuYW1lKSB7Ci0gICAgICAgIGZpbmFsIGludCBpbmRleCA9IG5hbWUubGFzdEluZGV4T2YoJy4nKTsKLSAgICAgICAgcmV0dXJuIG5hbWUuc3Vic3RyaW5nKDAsIGluZGV4ID49IDAgPyBpbmRleCA6IG5hbWUubGVuZ3RoKCkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNlYXJjaCBmb3IgYm90aCBzbGFzaGVzIGluIG9yZGVyIHRvIHN1cHBvcnQgVVJMcyBhbmQKLSAgICAgKiBmaWxlcy4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBiYXNlTmFtZShTdHJpbmcgbmFtZSkgewotICAgICAgICBpbnQgaW5kZXggPSBuYW1lLmxhc3RJbmRleE9mKCdcXCcpOwotICAgICAgICBpZiAoaW5kZXggPCAwKSB7Ci0gICAgICAgICAgICBpbmRleCA9IG5hbWUubGFzdEluZGV4T2YoJy8nKTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChpbmRleCA+PSAwKQotICAgICAgICAgICAgcmV0dXJuIG5hbWUuc3Vic3RyaW5nKGluZGV4ICsgMSk7Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgaW50IGxhc3RDb2xvbkluZGV4ID0gbmFtZS5sYXN0SW5kZXhPZignOicpOwotICAgICAgICAgICAgaWYgKGxhc3RDb2xvbkluZGV4ID4gMCkKLSAgICAgICAgICAgICAgICByZXR1cm4gbmFtZS5zdWJzdHJpbmcobGFzdENvbG9uSW5kZXggKyAxKTsKLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICByZXR1cm4gbmFtZTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNlYXJjaCBmb3IgYm90aCBzbGFzaGVzIGluIG9yZGVyIHRvIHN1cHBvcnQgVVJMcyBhbmQKLSAgICAgKiBmaWxlcy4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBwYXRoTmFtZShTdHJpbmcgbmFtZSkgewotICAgICAgICBpbnQgaW5kZXggPSBuYW1lLmxhc3RJbmRleE9mKCcvJyk7Ci0gICAgICAgIGlmIChpbmRleCA8IDApIHsKLSAgICAgICAgICAgIGluZGV4ID0gbmFtZS5sYXN0SW5kZXhPZignXFwnKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbmFtZS5zdWJzdHJpbmcoMCwgaW5kZXggKyAxKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXBsYWNlIGFsbCBpbGxlZ2FsIEphdmEgY2hhcnMgYnkgJ18nLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHRvSmF2YU5hbWUoU3RyaW5nIG5hbWUpIHsKLSAgICAgICAgaWYgKG5hbWUubGVuZ3RoKCkgPiAwKSB7Ci0gICAgICAgICAgICBmaW5hbCBTdHJpbmdCdWZmZXIgcmVzdWx0ID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotCi0gICAgICAgICAgICBjaGFyIGNoID0gbmFtZS5jaGFyQXQoMCk7Ci0gICAgICAgICAgICByZXN1bHQuYXBwZW5kKENoYXJhY3Rlci5pc0phdmFJZGVudGlmaWVyU3RhcnQoY2gpID8gY2ggOiAnXycpOwotCi0gICAgICAgICAgICBmaW5hbCBpbnQgbiA9IG5hbWUubGVuZ3RoKCk7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMTsgaSA8IG47IGkrKykgewotICAgICAgICAgICAgICAgIGNoID0gbmFtZS5jaGFyQXQoaSk7Ci0gICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChDaGFyYWN0ZXIuaXNKYXZhSWRlbnRpZmllclBhcnQoY2gpICA/IGNoIDogJ18nKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiByZXN1bHQudG9TdHJpbmcoKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbmFtZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgc3RhdGljIFR5cGUgZ2V0SkNSZWZUeXBlKFN0cmluZyBzaWduYXR1cmUpIHsKLSAgICAgICAgcmV0dXJuIFR5cGUuZ2V0VHlwZShzaWduYXR1cmUpOwotICAgIH0KLQotICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGludGVybmFsTmFtZShTdHJpbmcgY25hbWUpIHsKLSAgICAgICAgcmV0dXJuIGNuYW1lLnJlcGxhY2UoJy4nLCBmaWxlc2VwKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgc3RhdGljIHZvaWQgcHJpbnRsbihTdHJpbmcgcykgewotICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4ocyk7Ci0gICAgfQotCi0gICAgcHVibGljIHN0YXRpYyB2b2lkIHByaW50bG4oY2hhciBjaCkgewotICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oY2gpOwotICAgIH0KLQotICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBUUkFDRTEoKSB7Ci0gICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiVFJBQ0UxIik7Ci0gICAgfQotCi0gICAgcHVibGljIHN0YXRpYyB2b2lkIFRSQUNFMigpIHsKLSAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJUUkFDRTIiKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgc3RhdGljIHZvaWQgVFJBQ0UzKCkgewotICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlRSQUNFMyIpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJlcGxhY2UgYSBjZXJ0YWluIGNoYXJhY3RlciBpbiBhIHN0cmluZyB3aXRoIGEgbmV3IHN1YnN0cmluZy4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFN0cmluZyByZXBsYWNlKFN0cmluZyBiYXNlLCBjaGFyIGNoLCBTdHJpbmcgc3RyKSB7Ci0gICAgICAgIHJldHVybiAoYmFzZS5pbmRleE9mKGNoKSA8IDApID8gYmFzZSA6Ci0gICAgICAgICAgICByZXBsYWNlKGJhc2UsIFN0cmluZy52YWx1ZU9mKGNoKSwgbmV3IFN0cmluZ1tdIHsgc3RyIH0pOwotICAgIH0KLQotICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHJlcGxhY2UoU3RyaW5nIGJhc2UsIFN0cmluZyBkZWxpbSwgU3RyaW5nW10gc3RyKSB7Ci0gICAgICAgIGZpbmFsIGludCBsZW4gPSBiYXNlLmxlbmd0aCgpOwotICAgICAgICBmaW5hbCBTdHJpbmdCdWZmZXIgcmVzdWx0ID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotCi0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKLSAgICAgICAgICAgIGZpbmFsIGNoYXIgY2ggPSBiYXNlLmNoYXJBdChpKTsKLSAgICAgICAgICAgIGZpbmFsIGludCBrID0gZGVsaW0uaW5kZXhPZihjaCk7Ci0KLSAgICAgICAgICAgIGlmIChrID49IDApIHsKLSAgICAgICAgICAgICAgICByZXN1bHQuYXBwZW5kKHN0cltrXSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICByZXN1bHQuYXBwZW5kKGNoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gcmVzdWx0LnRvU3RyaW5nKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmVwbGFjZSBvY2N1cmFuY2VzIG9mICcuJywgJy0nLCAnLycgYW5kICc6JwotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGVzY2FwZShTdHJpbmcgaW5wdXQpIHsKLSAgICAgICAgcmV0dXJuIHJlcGxhY2UoaW5wdXQsICIuLS86IiwKLSAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7ICIkZG90JCIsICIkZGFzaCQiLCAiJHNsYXNoJCIsICIkY29sb24kIiB9KTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBnZXRMb2NhbE5hbWUoU3RyaW5nIHFuYW1lKSB7Ci0gICAgICAgIGZpbmFsIGludCBpbmRleCA9IHFuYW1lLmxhc3RJbmRleE9mKCI6Iik7Ci0gICAgICAgIHJldHVybiAoaW5kZXggPiAwKSA/IHFuYW1lLnN1YnN0cmluZyhpbmRleCArIDEpIDogcW5hbWU7Ci0gICAgfQotCi0gICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0UHJlZml4KFN0cmluZyBxbmFtZSkgewotICAgICAgICBmaW5hbCBpbnQgaW5kZXggPSBxbmFtZS5sYXN0SW5kZXhPZigiOiIpOwotICAgICAgICByZXR1cm4gKGluZGV4ID4gMCkgPyBxbmFtZS5zdWJzdHJpbmcoMCwgaW5kZXgpIDoKLSAgICAgICAgICAgIENvbnN0YW50cy5FTVBUWVNUUklORzsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDaGVja3MgaWYgdGhlIHN0cmluZyBpcyBhIGxpdGVyYWwgKGkuZS4gbm90IGFuIEFWVCkgb3Igbm90LgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0xpdGVyYWwoU3RyaW5nIHN0cikgewotICAgICAgICBmaW5hbCBpbnQgbGVuZ3RoID0gc3RyLmxlbmd0aCgpOwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aCAtIDE7IGkrKykgewotICAgICAgICAgICAgaWYgKHN0ci5jaGFyQXQoaSkgPT0gJ3snICYmIHN0ci5jaGFyQXQoaSArIDEpICE9ICd7JykgewotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDaGVja3MgaWYgdGhlIHN0cmluZyBpcyB2YWxpZCBsaXN0IG9mIHFuYW1lcwotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc1ZhbGlkUU5hbWVzKFN0cmluZyBzdHIpIHsKLSAgICAgICAgaWYgKChzdHIgIT0gbnVsbCkgJiYgKCFzdHIuZXF1YWxzKENvbnN0YW50cy5FTVBUWVNUUklORykpKSB7Ci0gICAgICAgICAgICBmaW5hbCBTdHJpbmdUb2tlbml6ZXIgdG9rZW5zID0gbmV3IFN0cmluZ1Rva2VuaXplcihzdHIpOwotICAgICAgICAgICAgd2hpbGUgKHRva2Vucy5oYXNNb3JlVG9rZW5zKCkpIHsKLSAgICAgICAgICAgICAgICBpZiAoIVhNTDExQ2hhci5pc1hNTDExVmFsaWRRTmFtZSh0b2tlbnMubmV4dFRva2VuKCkpKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL3V0aWwvVm9pZFR5cGUuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvdXRpbC9Wb2lkVHlwZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjYjkwNGYxLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvdXRpbC9Wb2lkVHlwZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTAwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFZvaWRUeXBlLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMDUgMTE6NDU6MjYgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWw7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLkluc3RydWN0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuSW5zdHJ1Y3Rpb25MaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMuUFVTSDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIuQ29uc3RhbnRzOwotCi0vKioKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIFZvaWRUeXBlIGV4dGVuZHMgVHlwZSB7Ci0gICAgcHJvdGVjdGVkIFZvaWRUeXBlKCkge30KLQotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0gICAgICAgIHJldHVybiAidm9pZCI7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gaWRlbnRpY2FsVG8oVHlwZSBvdGhlcikgewotICAgICAgICByZXR1cm4gdGhpcyA9PSBvdGhlcjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIHRvU2lnbmF0dXJlKCkgewotICAgICAgICByZXR1cm4gIlYiOwotICAgIH0KLQotICAgIHB1YmxpYyBjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5nZW5lcmljLlR5cGUgdG9KQ1R5cGUoKSB7Ci0gICAgICAgIHJldHVybiBudWxsOyAgICAvLyBzaG91bGQgbmV2ZXIgYmUgY2FsbGVkCi0gICAgfQotCi0gICAgcHVibGljIEluc3RydWN0aW9uIFBPUCgpIHsKLSAgICAgICAgcmV0dXJuIE5PUDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGVzIGEgdm9pZCBpbnRvIGFuIG9iamVjdCBvZiBpbnRlcm5hbCB0eXBlIDxjb2RlPnR5cGU8L2NvZGU+LgotICAgICAqIFRoaXMgdHJhbnNsYXRpb24gaXMgbmVlZGVkIHdoZW4gY2FsbGluZyBleHRlcm5hbCBmdW5jdGlvbnMKLSAgICAgKiB0aGF0IHJldHVybiB2b2lkLgotICAgICAqCi0gICAgICogQHNlZSAgICAgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZSN0cmFuc2xhdGVUbwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZVRvKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFR5cGUgdHlwZSkgewotICAgICAgICBpZiAodHlwZSA9PSBUeXBlLlN0cmluZykgewotICAgICAgICAgICAgdHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgKFN0cmluZ1R5cGUpIHR5cGUpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgRXJyb3JNc2cgZXJyID0gbmV3IEVycm9yTXNnKEVycm9yTXNnLkRBVEFfQ09OVkVSU0lPTl9FUlIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG9TdHJpbmcoKSwgdHlwZS50b1N0cmluZygpKTsKLSAgICAgICAgICAgIGNsYXNzR2VuLmdldFBhcnNlcigpLnJlcG9ydEVycm9yKENvbnN0YW50cy5GQVRBTCwgZXJyKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZXMgYSB2b2lkIGludG8gYSBzdHJpbmcgYnkgcHVzaGluZyB0aGUgZW1wdHkgc3RyaW5nICcnLgotICAgICAqCi0gICAgICogQHNlZSAgICAgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZSN0cmFuc2xhdGVUbwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZVRvKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1R5cGUgdHlwZSkgewotICAgICAgICBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0gICAgICAgIGlsLmFwcGVuZChuZXcgUFVTSChjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKSwgIiIpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGVzIGFuIGV4dGVybmFsIChwcmltaXRpdmUpIEphdmEgdHlwZSBpbnRvIGEgdm9pZC4KLSAgICAgKiBPbmx5IGFuIGV4dGVybmFsICJ2b2lkIiBjYW4gYmUgY29udmVydGVkIHRvIHRoaXMgY2xhc3MuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlRnJvbShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENsYXNzIGNsYXp6KSB7Ci0gICAgICAgIGlmICghY2xhenouZ2V0TmFtZSgpLmVxdWFscygidm9pZCIpKSB7Ci0gICAgICAgICAgICBFcnJvck1zZyBlcnIgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuREFUQV9DT05WRVJTSU9OX0VSUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b1N0cmluZygpLCBjbGF6ei5nZXROYW1lKCkpOwotICAgICAgICAgICAgY2xhc3NHZW4uZ2V0UGFyc2VyKCkucmVwb3J0RXJyb3IoQ29uc3RhbnRzLkZBVEFMLCBlcnIpOwotICAgICAgICB9Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci94cGF0aC5jdXAgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL3hwYXRoLmN1cApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMTJiZmEyYS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2NvbXBpbGVyL3hwYXRoLmN1cAorKysgL2Rldi9udWxsCkBAIC0xLDExMTYgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi0vKgotICogJElkOiB4cGF0aC5jdXAsdiAxLjUxIDIwMDQvMTIvMTUgMTc6MzU6MzkganljbGkgRXhwICQKLSAqLwotCi0vKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKiBAYXV0aG9yIEcuIFRvZGQgTWlsbGVyCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBqYXZhLnV0aWwuU3RhY2s7Ci1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLWltcG9ydCBqYXZhLmlvLlN0cmluZ1JlYWRlcjsKLWltcG9ydCBjb20uc3VuLmphdmFfY3VwLmludGVybmFsLnJ1bnRpbWUuKjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuRE9NOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkF4aXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnJ1bnRpbWUuT3BlcmF0b3JzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkVycm9yTXNnOwotCi1wYXJzZXIgY29kZSB7OgotICAgIC8qKgotICAgICAqIFVzZWQgYnkgZnVuY3Rpb24gY2FsbHMgd2l0aCBubyBhcmdzLgotICAgICAqLwotICAgIHN0YXRpYyBwdWJsaWMgZmluYWwgVmVjdG9yIEVtcHR5QXJncyA9IG5ldyBWZWN0b3IoMCk7Ci0KLSAgICAvKioKLSAgICAgKiBSZWZlcmVuY2UgdG8gbm9uLWV4aXN0aW5nIHZhcmlhYmxlLgotICAgICAqLwotICAgIHN0YXRpYyBwdWJsaWMgZmluYWwgVmFyaWFibGVSZWYgRHVtbXlWYXJSZWYgPSBudWxsOwotCi0gICAgLyoqCi0gICAgICogUmVmZXJlbmNlIHRvIHRoZSBQYXJzZXIgY2xhc3MuCi0gICAgICovCi0gICAgcHJpdmF0ZSBQYXJzZXIgX3BhcnNlcjsKLSAgICBwcml2YXRlIFhTTFRDICBfeHNsdGM7Ci0KLSAgICAvKioKLSAgICAgKiBTdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGV4cHJlc3Npb24gYmVpbmcgcGFyc2VkLgotICAgICAqLwotICAgIHByaXZhdGUgU3RyaW5nIF9leHByZXNzaW9uOwotCi0gICAgLyoqCi0gICAgICogTGluZSBudW1iZXIgd2hlcmUgdGhpcyBleHByZXNzaW9uL3BhdHRlcm4gd2FzIGRlY2xhcmVkLgotICAgICAqLwotICAgIHByaXZhdGUgaW50IF9saW5lTnVtYmVyID0gMDsKLQotICAgIC8qKgotICAgICAqIFJlZmVyZW5jZSB0byB0aGUgc3ltYm9sIHRhYmxlLgotICAgICAqLwotICAgIHB1YmxpYyBTeW1ib2xUYWJsZSBfc3ltYm9sVGFibGU7Ci0KLSAgICBwdWJsaWMgWFBhdGhQYXJzZXIoUGFyc2VyIHBhcnNlcikgewotICAgICAgICBfcGFyc2VyID0gcGFyc2VyOwotCV94c2x0YyA9IHBhcnNlci5nZXRYU0xUQygpOwotICAgICAgICBfc3ltYm9sVGFibGUgPSBwYXJzZXIuZ2V0U3ltYm9sVGFibGUoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldExpbmVOdW1iZXIoKSB7Ci0gICAgICAgIHJldHVybiBfbGluZU51bWJlcjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgUU5hbWUgZ2V0UU5hbWVJZ25vcmVEZWZhdWx0TnMoU3RyaW5nIG5hbWUpIHsKLSAgICAgICAgICByZXR1cm4gX3BhcnNlci5nZXRRTmFtZUlnbm9yZURlZmF1bHROcyhuYW1lKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgUU5hbWUgZ2V0UU5hbWUoU3RyaW5nIG5hbWVzcGFjZSwgU3RyaW5nIHByZWZpeCwgU3RyaW5nIGxvY2FsbmFtZSkgewotICAgICAgICByZXR1cm4gX3BhcnNlci5nZXRRTmFtZShuYW1lc3BhY2UsIHByZWZpeCwgbG9jYWxuYW1lKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRNdWx0aURvY3VtZW50KGJvb2xlYW4gZmxhZykgewotICAgICAgICAgIF94c2x0Yy5zZXRNdWx0aURvY3VtZW50KGZsYWcpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldENhbGxzTm9kZXNldChib29sZWFuIGZsYWcpIHsKLSAgICAgICAgICBfeHNsdGMuc2V0Q2FsbHNOb2Rlc2V0KGZsYWcpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldEhhc0lkQ2FsbChib29sZWFuIGZsYWcpIHsKLSAgICAgICAgICBfeHNsdGMuc2V0SGFzSWRDYWxsKGZsYWcpOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgaXMgc2ltaWxhciB0byBmaW5kTm9kZVR5cGUoaW50LCBPYmplY3QpIGV4Y2VwdCB0aGF0IGl0Ci0gICAgICogY3JlYXRlcyBhIFN0ZXBQYXR0ZXJuIGluc3RlYWQgb2YganVzdCByZXR1cm5pbmcgYSBub2RlIHR5cGUuIEl0IGFsc28KLSAgICAgKiBkaWZmZXJzIGluIHRoZSB3YXkgaXQgaGFuZGxlcyAie3VyaX06KiIgYW5kICJ7dXJpfTpAKiIuIFRoZSBsYXN0IHR3bwotICAgICAqIHBhdHRlcm5zIGFyZSBleHBhbmRlZCBhcyAiKltuYW1lc3BhY2UtdXJpKCkgPSAndXJpJ10iIGFuZAotICAgICAqICJAKltuYW1lc3BhY2UtdXJpKCkgPSAndXJpJ10iLCByZXNwZWN0aXZlbHkuIFRoaXMgZXhwYW5zaW9uIGNvbnNpZGVyYWJseQotICAgICAqIHNpbXBsaWZpZXMgdGhlIGdyb3VwaW5nIG9mIHBhdHRlcm5zIGluIHRoZSBNb2RlIGNsYXNzLiBGb3IgdGhpcwotICAgICAqIGV4cGFuc2lvbiB0byBiZSBjb3JyZWN0LCB0aGUgcHJpb3JpdHkgb2YgdGhlIHBhdHRlcm4vdGVtcGxhdGUgbXVzdCBiZQotICAgICAqIHNldCB0byAtMC4yNSAod2hlbiBubyBvdGhlciBwcmVkaWNhdGVzIGFyZSBwcmVzZW50KS4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RlcFBhdHRlcm4gY3JlYXRlU3RlcFBhdHRlcm4oaW50IGF4aXMsIE9iamVjdCB0ZXN0LCBWZWN0b3IgcHJlZGljYXRlcykgewotCWludCBub2RlVHlwZTsKLQotCWlmICh0ZXN0ID09IG51bGwpIHsgIC8vICIqIgotCSAgICBub2RlVHlwZSA9IChheGlzID09IEF4aXMuQVRUUklCVVRFKSA/IE5vZGVUZXN0LkFUVFJJQlVURSA6Ci0JCShheGlzID09IEF4aXMuTkFNRVNQQUNFKSA/IC0xIDogTm9kZVRlc3QuRUxFTUVOVDsKLQotCSAgICByZXR1cm4gbmV3IFN0ZXBQYXR0ZXJuKGF4aXMsIG5vZGVUeXBlLCBwcmVkaWNhdGVzKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICh0ZXN0IGluc3RhbmNlb2YgSW50ZWdlcikgewotCSAgICBub2RlVHlwZSA9ICgoSW50ZWdlcikgdGVzdCkuaW50VmFsdWUoKTsKLQotCSAgICByZXR1cm4gbmV3IFN0ZXBQYXR0ZXJuKGF4aXMsIG5vZGVUeXBlLCBwcmVkaWNhdGVzKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLQkgICAgUU5hbWUgbmFtZSA9IChRTmFtZSl0ZXN0OwotCSAgICBib29sZWFuIHNldFByaW9yaXR5ID0gZmFsc2U7Ci0KLQkgICAgaWYgKGF4aXMgPT0gQXhpcy5OQU1FU1BBQ0UpIHsKLQkJbm9kZVR5cGUgPSAobmFtZS50b1N0cmluZygpLmVxdWFscygiKiIpKSA/IC0xCi0JCQkJOiBfeHNsdGMucmVnaXN0ZXJOYW1lc3BhY2VQcmVmaXgobmFtZSk7OwotICAgICAgICAgICAgfQotCSAgICBlbHNlIHsKLQkJZmluYWwgU3RyaW5nIHVyaSA9IG5hbWUuZ2V0TmFtZXNwYWNlKCk7Ci0JCWZpbmFsIFN0cmluZyBsb2NhbCA9IG5hbWUuZ2V0TG9jYWxQYXJ0KCk7Ci0JCWZpbmFsIFFOYW1lIG5hbWVzcGFjZV91cmkgPQotCQkgICAgX3BhcnNlci5nZXRRTmFtZUlnbm9yZURlZmF1bHROcygibmFtZXNwYWNlLXVyaSIpOwotCi0JCS8vIEV4cGFuZCB7dXJpfToqIHRvICpbbmFtZXNwYWNlLXVyaSgpID0gJ3VyaSddIC0gc2FtZSBmb3IgQCoKLQkJaWYgKHVyaSAhPSBudWxsICYmIChsb2NhbC5lcXVhbHMoIioiKSB8fCBsb2NhbC5lcXVhbHMoIkAqIikpKSB7Ci0JCSAgICBpZiAocHJlZGljYXRlcyA9PSBudWxsKSB7Ci0JCQlwcmVkaWNhdGVzID0gbmV3IFZlY3RvcigyKTsKLQkJICAgIH0KLQotCQkgICAgLy8gUHJpb3JpdHkgaXMgc2V0IGJ5IGhhbmQgaWYgbm8gb3RoZXIgcHJlZGljYXRlcyBleGlzdAotCQkgICAgc2V0UHJpb3JpdHkgPSAocHJlZGljYXRlcy5zaXplKCkgPT0gMCk7Ci0KLQkJICAgIHByZWRpY2F0ZXMuYWRkKAotCQkJbmV3IFByZWRpY2F0ZSgKLQkJCSAgICBuZXcgRXF1YWxpdHlFeHByKE9wZXJhdG9ycy5FUSwKLQkJCQluZXcgTmFtZXNwYWNlVXJpQ2FsbChuYW1lc3BhY2VfdXJpKSwKLQkJCQluZXcgTGl0ZXJhbEV4cHIodXJpKSkpKTsKLQkJfQotCi0JCWlmIChsb2NhbC5lcXVhbHMoIioiKSkgewotCQkgICAgbm9kZVR5cGUgPSAoYXhpcyA9PSBBeGlzLkFUVFJJQlVURSkgPyBOb2RlVGVzdC5BVFRSSUJVVEUKLQkJCTogTm9kZVRlc3QuRUxFTUVOVDsKLQkJfQotCQllbHNlIGlmIChsb2NhbC5lcXVhbHMoIkAqIikpIHsKLQkJICAgIG5vZGVUeXBlID0gTm9kZVRlc3QuQVRUUklCVVRFOwotCQl9Ci0JCWVsc2UgewotCQkgICAgbm9kZVR5cGUgPSAoYXhpcyA9PSBBeGlzLkFUVFJJQlVURSkgPyBfeHNsdGMucmVnaXN0ZXJBdHRyaWJ1dGUobmFtZSkKLQkJCTogX3hzbHRjLnJlZ2lzdGVyRWxlbWVudChuYW1lKTsKLQkJfQotCSAgICB9Ci0KLQkgICAgZmluYWwgU3RlcFBhdHRlcm4gcmVzdWx0ID0gbmV3IFN0ZXBQYXR0ZXJuKGF4aXMsIG5vZGVUeXBlLCBwcmVkaWNhdGVzKTsKLQotCSAgICAvLyBTZXQgcHJpb3JpdHkgZm9yIGNhc2UgcHJlZml4OiogYW5kIHByZWZpeDpAKiAobm8gcHJlZGljYXRlcykKLQkgICAgaWYgKHNldFByaW9yaXR5KSB7Ci0JCXJlc3VsdC5zZXRQcmlvcml0eSgtMC4yNSk7Ci0JICAgIH0KLQotCSAgICByZXR1cm4gcmVzdWx0OwotCX0KLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGZpbmROb2RlVHlwZShpbnQgYXhpcywgT2JqZWN0IHRlc3QpIHsKLQlpZiAodGVzdCA9PSBudWxsKSB7ICAvLyAqCi0JICAgIHJldHVybiAoYXhpcyA9PSBBeGlzLkFUVFJJQlVURSkgPwotCQlOb2RlVGVzdC5BVFRSSUJVVEUgOgotCQkoYXhpcyA9PSBBeGlzLk5BTUVTUEFDRSkgPyAtMSA6IE5vZGVUZXN0LkVMRU1FTlQ7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAodGVzdCBpbnN0YW5jZW9mIEludGVnZXIpIHsKLSAgICAgICAgICAgIHJldHVybiAoKEludGVnZXIpdGVzdCkuaW50VmFsdWUoKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLQkgICAgUU5hbWUgbmFtZSA9IChRTmFtZSl0ZXN0OwotCi0JICAgIGlmIChheGlzID09IEF4aXMuTkFNRVNQQUNFKSB7Ci0JCXJldHVybiAobmFtZS50b1N0cmluZygpLmVxdWFscygiKiIpKSA/IC0xCi0JCSAgICA6IF94c2x0Yy5yZWdpc3Rlck5hbWVzcGFjZVByZWZpeChuYW1lKTsKLSAgICAgICAgICAgIH0KLQotCSAgICBpZiAobmFtZS5nZXROYW1lc3BhY2UoKSA9PSBudWxsKSB7Ci0JCWZpbmFsIFN0cmluZyBsb2NhbCA9IG5hbWUuZ2V0TG9jYWxQYXJ0KCk7Ci0KLQkJaWYgKGxvY2FsLmVxdWFscygiKiIpKSB7Ci0JCSAgICByZXR1cm4gKGF4aXMgPT0gQXhpcy5BVFRSSUJVVEUpID8gTm9kZVRlc3QuQVRUUklCVVRFCi0JCQk6IE5vZGVUZXN0LkVMRU1FTlQ7Ci0JCX0KLQkJZWxzZSBpZiAobG9jYWwuZXF1YWxzKCJAKiIpKSB7Ci0JCSAgICByZXR1cm4gTm9kZVRlc3QuQVRUUklCVVRFOwotCQl9Ci0JICAgIH0KLQotCSAgICByZXR1cm4gKGF4aXMgPT0gQXhpcy5BVFRSSUJVVEUpID8gX3hzbHRjLnJlZ2lzdGVyQXR0cmlidXRlKG5hbWUpCi0JCTogX3hzbHRjLnJlZ2lzdGVyRWxlbWVudChuYW1lKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFBhcnNlIHRoZSBleHByZXNzaW9uIHBhc3NlZCB0byB0aGUgY3VycmVudCBzY2FubmVyLiBJZiB0aGlzCi0gICAgICogZXhwcmVzc2lvbiBjb250YWlucyByZWZlcmVuY2VzIHRvIGxvY2FsIHZhcmlhYmxlcyBhbmQgaXQgd2lsbCBiZQotICAgICAqIGNvbXBpbGVkIGluIGFuIGV4dGVybmFsIG1vZHVsZSAobm90IGluIHRoZSBtYWluIGNsYXNzKSByZXF1ZXN0Ci0gICAgICogdGhlIGN1cnJlbnQgdGVtcGxhdGUgdG8gY3JlYXRlIGEgbmV3IHZhcmlhYmxlIHN0YWNrIGZyYW1lLgotICAgICAqCi0gICAgICogQHBhcmFtIGxpbmVOdW1iZXIgTGluZSB3aGVyZSB0aGUgY3VycmVudCBleHByZXNzaW9uIGlzIGRlZmluZWQuCi0gICAgICogQHBhcmFtIGV4dGVybmFsICAgU2V0IHRvIDx0dD50cnVlPC90dD4gaWYgdGhpcyBleHByZXNzaW9uIGlzCi0gICAgICogICAgICAgICAgICAgICAgICAgY29tcGlsZWQgaW4gYSBzZXBhcmF0ZSBtb2R1bGUuCi0gICAgICoKLSAgICAgKi8KLSAgICBwdWJsaWMgU3ltYm9sIHBhcnNlKFN0cmluZyBleHByZXNzaW9uLCBpbnQgbGluZU51bWJlcikgdGhyb3dzIEV4Y2VwdGlvbiB7Ci0gICAgICAgIHRyeSB7Ci0JICAgIF9leHByZXNzaW9uID0gZXhwcmVzc2lvbjsKLQkgICAgX2xpbmVOdW1iZXIgPSBsaW5lTnVtYmVyOwotCSAgICByZXR1cm4gc3VwZXIucGFyc2UoKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoSWxsZWdhbENoYXJFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgRXJyb3JNc2cgZXJyID0gbmV3IEVycm9yTXNnKEVycm9yTXNnLklMTEVHQUxfQ0hBUl9FUlIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGluZU51bWJlciwgZS5nZXRNZXNzYWdlKCkpOwotICAgICAgICAgICAgX3BhcnNlci5yZXBvcnRFcnJvcihDb25zdGFudHMuRkFUQUwsIGVycik7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogTG9va3VwIGEgdmFyaWFibGUgb3IgcGFyYW1ldGVyIGluIHRoZSBzeW1ib2wgdGFibGUgZ2l2ZW4gaXRzIG5hbWUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSBOYW1lIG9mIHRoZSBzeW1ib2wgYmVpbmcgbG9va2VkIHVwLgotICAgICAqLwotICAgIGZpbmFsIFN5bnRheFRyZWVOb2RlIGxvb2t1cE5hbWUoUU5hbWUgbmFtZSkgewotICAgICAgICAvLyBJcyBpdCBhIGxvY2FsIHZhciBvciBwYXJhbSA/Ci0gICAgICAgIGZpbmFsIFN5bnRheFRyZWVOb2RlIHJlc3VsdCA9IF9wYXJzZXIubG9va3VwVmFyaWFibGUobmFtZSk7Ci0JaWYgKHJlc3VsdCAhPSBudWxsKQotICAgICAgICAgICAgcmV0dXJuKHJlc3VsdCk7Ci0gICAgICAgIGVsc2UKLQkgICAgcmV0dXJuKF9zeW1ib2xUYWJsZS5sb29rdXBOYW1lKG5hbWUpKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgZmluYWwgdm9pZCBhZGRFcnJvcihFcnJvck1zZyBlcnJvcikgewotCV9wYXJzZXIucmVwb3J0RXJyb3IoQ29uc3RhbnRzLkVSUk9SLCBlcnJvcik7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgcmVwb3J0X2Vycm9yKFN0cmluZyBtZXNzYWdlLCBPYmplY3QgaW5mbykgewotCWZpbmFsIEVycm9yTXNnIGVyciA9IG5ldyBFcnJvck1zZyhFcnJvck1zZy5TWU5UQVhfRVJSLCBfbGluZU51bWJlciwKLQkgICAgX2V4cHJlc3Npb24pOwotCV9wYXJzZXIucmVwb3J0RXJyb3IoQ29uc3RhbnRzLkZBVEFMLCBlcnIpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHJlcG9ydF9mYXRhbF9lcnJvcihTdHJpbmcgbWVzc2FnZSwgT2JqZWN0IGluZm8pIHsKLSAgICAgICAgLy8gZW1wdHkKLSAgICB9Ci0KLSAgICBwdWJsaWMgUmVsYXRpdmVMb2NhdGlvblBhdGggaW5zZXJ0U3RlcChTdGVwIHN0ZXAsIFJlbGF0aXZlTG9jYXRpb25QYXRoIHJscCkgewotCWlmIChybHAgaW5zdGFuY2VvZiBTdGVwKSB7Ci0JICAgIHJldHVybiBuZXcgUGFyZW50TG9jYXRpb25QYXRoKHN0ZXAsIChTdGVwKSBybHApOwotCX0KLQllbHNlIGlmIChybHAgaW5zdGFuY2VvZiBQYXJlbnRMb2NhdGlvblBhdGgpIHsKLQkgICAgZmluYWwgUGFyZW50TG9jYXRpb25QYXRoIHBscCA9IChQYXJlbnRMb2NhdGlvblBhdGgpIHJscDsKLQkgICAgZmluYWwgUmVsYXRpdmVMb2NhdGlvblBhdGggbmV3cmxwID0gaW5zZXJ0U3RlcChzdGVwLCBwbHAuZ2V0UGF0aCgpKTsKLQkgICAgcmV0dXJuIG5ldyBQYXJlbnRMb2NhdGlvblBhdGgobmV3cmxwLCBwbHAuZ2V0U3RlcCgpKTsKLQl9Ci0JZWxzZSB7Ci0JICAgIGFkZEVycm9yKG5ldyBFcnJvck1zZyhFcnJvck1zZy5JTlRFUk5BTF9FUlIsICJYUGF0aFBhcnNlci5pbnNlcnRTdGVwIikpOwotCSAgICByZXR1cm4gcmxwOwotCX0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIGF4aXMgYXBwbGllcyB0byBlbGVtZW50cyBvbmx5LiBUaGUgYXhlcwotICAgICAqIGNoaWxkLCBhdHRyaWJ1dGUsIG5hbWVzcGFjZSwgZGVzY2VuZGFudCByZXN1bHQgaW4gbm9uLWVtcHR5Ci0gICAgICogbm9kZXNldHMgb25seSBpZiB0aGUgY29udGV4dCBub2RlIGlzIG9mIHR5cGUgZWxlbWVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0VsZW1lbnRBeGlzKGludCBheGlzKSB7Ci0JcmV0dXJuIChheGlzID09IEF4aXMuQ0hJTEQgfHwgYXhpcyA9PSBBeGlzLkFUVFJJQlVURSB8fAotCQlheGlzID09IEF4aXMuTkFNRVNQQUNFIHx8IGF4aXMgPT0gQXhpcy5ERVNDRU5EQU5UKTsKLSAgICB9Ci06fQotCi10ZXJtaW5hbCBTTEFTSCwgRE9ULCBMQlJBQ0ssIFJCUkFDSywgVkJBUiwgTFBBUkVOLCBSUEFSRU4sIFNUQVIsIENPTU1BOwotdGVybWluYWwgRE9MTEFSLCBBVFNJR047Ci10ZXJtaW5hbCBERE9ULCBEQ09MT04sIERTTEFTSDsKLXRlcm1pbmFsIEVRLCBORTsKLXRlcm1pbmFsIExULCBHVCwgTEUsIEdFOwotdGVybWluYWwgUExVUywgTUlOVVMsIERJViwgTU9ELCBNVUxUOwotdGVybWluYWwgU3RyaW5nIExpdGVyYWw7Ci10ZXJtaW5hbCBTdHJpbmcgUU5BTUU7Ci10ZXJtaW5hbCBJRCwgS0VZLCBURVhULCBOT0RFLCBPUiwgQU5ELCBDT01NRU5ULCBQSSwgUElQQVJBTSwgUFJFQ0VESU5HU0lCTElORzsKLXRlcm1pbmFsIFNFTEYsIFBBUkVOVCwgQ0hJTEQsIEFUVFJJQlVURSwgQU5DRVNUT1IsIEFOQ0VTVE9ST1JTRUxGLCBERVNDRU5EQU5UOwotdGVybWluYWwgREVTQ0VOREFOVE9SU0VMRiwgRk9MTE9XSU5HLCBGT0xMT1dJTkdTSUJMSU5HLCBOQU1FU1BBQ0UsIFBSRUNFRElORzsKLXRlcm1pbmFsIERvdWJsZSBSRUFMOwotdGVybWluYWwgTG9uZyBJTlQ7Ci10ZXJtaW5hbCBQQVRURVJOLCBFWFBSRVNTSU9OOwotCi1ub24gdGVybWluYWwgU3ludGF4VHJlZU5vZGUgVG9wTGV2ZWw7Ci0KLW5vbiB0ZXJtaW5hbCBFeHByZXNzaW9uIEV4cHIsIEFyZ3VtZW50LCBMb2NhdGlvblBhdGg7Ci1ub24gdGVybWluYWwgRXhwcmVzc2lvbiBQcmVkaWNhdGUsIEZpbHRlckV4cHIsIFN0ZXA7Ci1ub24gdGVybWluYWwgRXhwcmVzc2lvbiBPckV4cHIsIEFuZEV4cHIsIEVxdWFsaXR5RXhwcjsKLW5vbiB0ZXJtaW5hbCBFeHByZXNzaW9uIFJlbGF0aW9uYWxFeHByLCBBZGRpdGl2ZUV4cHI7Ci1ub24gdGVybWluYWwgRXhwcmVzc2lvbiBNdWx0aXBsaWNhdGl2ZUV4cHIsIFVuYXJ5RXhwcjsKLW5vbiB0ZXJtaW5hbCBFeHByZXNzaW9uIFZhcmlhYmxlUmVmZXJlbmNlLCBGdW5jdGlvbkNhbGw7Ci1ub24gdGVybWluYWwgRXhwcmVzc2lvbiBQcmltYXJ5RXhwciwgVW5pb25FeHByLCBQYXRoRXhwciwgQWJicmV2aWF0ZWRTdGVwOwotbm9uIHRlcm1pbmFsIEV4cHJlc3Npb24gUmVsYXRpdmVMb2NhdGlvblBhdGgsIEFiYnJldmlhdGVkUmVsYXRpdmVMb2NhdGlvblBhdGg7Ci1ub24gdGVybWluYWwgRXhwcmVzc2lvbiBBYnNvbHV0ZUxvY2F0aW9uUGF0aCwgQWJicmV2aWF0ZWRBYnNvbHV0ZUxvY2F0aW9uUGF0aDsKLQotbm9uIHRlcm1pbmFsIE9iamVjdCBOb2RlVGVzdCwgTmFtZVRlc3Q7Ci0KLW5vbiB0ZXJtaW5hbCBJZEtleVBhdHRlcm4gSWRLZXlQYXR0ZXJuOwotbm9uIHRlcm1pbmFsIFBhdHRlcm4gUGF0dGVybjsKLW5vbiB0ZXJtaW5hbCBQYXR0ZXJuIExvY2F0aW9uUGF0aFBhdHRlcm47Ci1ub24gdGVybWluYWwgU3RlcFBhdHRlcm4gUHJvY2Vzc2luZ0luc3RydWN0aW9uUGF0dGVybjsKLW5vbiB0ZXJtaW5hbCBSZWxhdGl2ZVBhdGhQYXR0ZXJuIFJlbGF0aXZlUGF0aFBhdHRlcm47Ci1ub24gdGVybWluYWwgU3RlcFBhdHRlcm4gU3RlcFBhdHRlcm47Ci1ub24gdGVybWluYWwgT2JqZWN0IE5vZGVUZXN0UGF0dGVybiwgTmFtZVRlc3RQYXR0ZXJuOwotCi1ub24gdGVybWluYWwgVmVjdG9yIFByZWRpY2F0ZXMsIE5vbmVtcHR5QXJndW1lbnRMaXN0Owotbm9uIHRlcm1pbmFsIFFOYW1lIFFOYW1lLCBGdW5jdGlvbk5hbWUsIFZhcmlhYmxlTmFtZTsKLW5vbiB0ZXJtaW5hbCBJbnRlZ2VyIEF4aXNOYW1lLCBBeGlzU3BlY2lmaWVyOwotbm9uIHRlcm1pbmFsIEludGVnZXIgQ2hpbGRPckF0dHJpYnV0ZUF4aXNTcGVjaWZpZXI7Ci0KLXByZWNlZGVuY2UgbGVmdCBWQkFSOwotcHJlY2VkZW5jZSBsZWZ0IE9SOwotcHJlY2VkZW5jZSBsZWZ0IEFORDsKLXByZWNlZGVuY2Ugbm9uYXNzb2MgRVEsIE5FOwotcHJlY2VkZW5jZSBsZWZ0IExULCBHVCwgTEUsIEdFOwotCi1wcmVjZWRlbmNlIGxlZnQgUExVUywgTUlOVVM7Ci1wcmVjZWRlbmNlIGxlZnQgRElWLCBNT0QsIE1VTFQ7Ci1wcmVjZWRlbmNlIGxlZnQgRE9MTEFSOwotcHJlY2VkZW5jZSBsZWZ0IEFUU0lHTjsKLXByZWNlZGVuY2UgcmlnaHQgRENPTE9OOwotCi1zdGFydCB3aXRoIFRvcExldmVsOwotCi1Ub3BMZXZlbCA6Oj0gUEFUVEVSTiBQYXR0ZXJuOnBhdHRlcm4KLSAgICAgICAgICAgIHs6IFJFU1VMVCA9IHBhdHRlcm47IDp9Ci0KLSAgICAgICAgICAgIHwgRVhQUkVTU0lPTiBFeHByOmV4cHIKLSAgICAgICAgICAgIHs6IFJFU1VMVCA9IGV4cHI7IDp9OwotCi0vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gUGF0dGVybnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KLQotUGF0dGVybiA6Oj0gTG9jYXRpb25QYXRoUGF0dGVybjpscHAKLSAgICAgICAgICAgIHs6IFJFU1VMVCA9IGxwcDsgOn0KLQotICAgICAgICAgICAgfCBMb2NhdGlvblBhdGhQYXR0ZXJuOmxwcCBWQkFSIFBhdHRlcm46cAotICAgICAgICAgICAgezogUkVTVUxUID0gbmV3IEFsdGVybmF0aXZlUGF0dGVybihscHAsIHApOyAgOn07Ci0KLUxvY2F0aW9uUGF0aFBhdHRlcm4gOjo9IFNMQVNICi0gICAgICAgICAgICB7OiBSRVNVTFQgPSBuZXcgQWJzb2x1dGVQYXRoUGF0dGVybihudWxsKTsgOn0KLQotICAgICAgICAgICAgfCBTTEFTSCBSZWxhdGl2ZVBhdGhQYXR0ZXJuOnJwcAotICAgICAgICAgICAgezogUkVTVUxUID0gbmV3IEFic29sdXRlUGF0aFBhdHRlcm4ocnBwKTsgOn0KLQotICAgICAgICAgICAgfCBJZEtleVBhdHRlcm46aWtwCi0gICAgICAgICAgICB7OiBSRVNVTFQgPSBpa3A7IDp9Ci0KLSAgICAgICAgICAgIHwgSWRLZXlQYXR0ZXJuOmlrcCBTTEFTSCBSZWxhdGl2ZVBhdGhQYXR0ZXJuOnJwcAotICAgICAgICAgICAgezogUkVTVUxUID0gbmV3IFBhcmVudFBhdHRlcm4oaWtwLCBycHApOyA6fQotCi0gICAgICAgICAgICB8IElkS2V5UGF0dGVybjppa3AgRFNMQVNIIFJlbGF0aXZlUGF0aFBhdHRlcm46cnBwCi0gICAgICAgICAgICB7OiBSRVNVTFQgPSBuZXcgQW5jZXN0b3JQYXR0ZXJuKGlrcCwgcnBwKTsgOn0KLQotICAgICAgICAgICAgfCBEU0xBU0ggUmVsYXRpdmVQYXRoUGF0dGVybjpycHAKLSAgICAgICAgICAgIHs6IFJFU1VMVCA9IG5ldyBBbmNlc3RvclBhdHRlcm4ocnBwKTsgOn0KLQotICAgICAgICAgICAgfCBSZWxhdGl2ZVBhdGhQYXR0ZXJuOnJwcAotICAgICAgICAgICAgezogUkVTVUxUID0gcnBwOyA6fTsKLQotSWRLZXlQYXR0ZXJuIDo6PSBJRCBMUEFSRU4gTGl0ZXJhbDpsIFJQQVJFTgotICAgICAgICAgICAgezogUkVTVUxUID0gbmV3IElkUGF0dGVybihsKTsKLSAgICAgICAgICAgICAgIHBhcnNlci5zZXRIYXNJZENhbGwodHJ1ZSk7Ci0gICAgICAgICAgICA6fQotCi0gICAgICAgICAgICB8IEtFWSBMUEFSRU4gTGl0ZXJhbDpsMSBDT01NQSBMaXRlcmFsOmwyIFJQQVJFTgotICAgICAgICAgICAgezogUkVTVUxUID0gbmV3IEtleVBhdHRlcm4obDEsIGwyKTsgOn07Ci0KLVByb2Nlc3NpbmdJbnN0cnVjdGlvblBhdHRlcm4gOjo9IFBJUEFSQU0gTFBBUkVOIExpdGVyYWw6bCBSUEFSRU4KLSAgICAgICAgICAgIHs6IFJFU1VMVCA9IG5ldyBQcm9jZXNzaW5nSW5zdHJ1Y3Rpb25QYXR0ZXJuKGwpOyA6fTsKLQotUmVsYXRpdmVQYXRoUGF0dGVybiA6Oj0gU3RlcFBhdHRlcm46c3AKLSAgICAgICAgICAgIHs6IFJFU1VMVCA9IHNwOyA6fQotCi0gICAgICAgICAgICB8IFN0ZXBQYXR0ZXJuOnNwIFNMQVNIIFJlbGF0aXZlUGF0aFBhdHRlcm46cnBwCi0gICAgICAgICAgICB7OiBSRVNVTFQgPSBuZXcgUGFyZW50UGF0dGVybihzcCwgcnBwKTsgOn0KLQotICAgICAgICAgICAgfCBTdGVwUGF0dGVybjpzcCBEU0xBU0ggUmVsYXRpdmVQYXRoUGF0dGVybjpycHAKLSAgICAgICAgICAgIHs6IFJFU1VMVCA9IG5ldyBBbmNlc3RvclBhdHRlcm4oc3AsIHJwcCk7IDp9OwotCi1TdGVwUGF0dGVybiA6Oj0gTm9kZVRlc3RQYXR0ZXJuOm50Ci0gICAgICAgICAgICB7OgotCQlSRVNVTFQgPSBwYXJzZXIuY3JlYXRlU3RlcFBhdHRlcm4oQXhpcy5DSElMRCwgbnQsIG51bGwpOwotICAgICAgICAgICAgOn0KLQotICAgICAgICAgICAgfCBOb2RlVGVzdFBhdHRlcm46bnQgUHJlZGljYXRlczpwcAotICAgICAgICAgICAgezoKLQkJUkVTVUxUID0gcGFyc2VyLmNyZWF0ZVN0ZXBQYXR0ZXJuKEF4aXMuQ0hJTEQsIG50LCBwcCk7Ci0gICAgICAgICAgICA6fQotCi0gICAgICAgICAgICB8IFByb2Nlc3NpbmdJbnN0cnVjdGlvblBhdHRlcm46cGlwCi0gICAgICAgICAgICB7OiBSRVNVTFQgPSBwaXA7IDp9Ci0KLQkgICAgfCBQcm9jZXNzaW5nSW5zdHJ1Y3Rpb25QYXR0ZXJuOnBpcCBQcmVkaWNhdGVzOnBwCi0gICAgICAgICAgICB7OiBSRVNVTFQgPSAoUHJvY2Vzc2luZ0luc3RydWN0aW9uUGF0dGVybilwaXAuc2V0UHJlZGljYXRlcyhwcCk7IDp9Ci0KLSAgICAgICAgICAgIHwgQ2hpbGRPckF0dHJpYnV0ZUF4aXNTcGVjaWZpZXI6YXhpcyBOb2RlVGVzdFBhdHRlcm46bnQKLSAgICAgICAgICAgIHs6Ci0JICAgICAgIFJFU1VMVCA9IHBhcnNlci5jcmVhdGVTdGVwUGF0dGVybihheGlzLmludFZhbHVlKCksIG50LCBudWxsKTsKLSAgICAgICAgICAgIDp9Ci0KLQkgICAgfCBDaGlsZE9yQXR0cmlidXRlQXhpc1NwZWNpZmllcjpheGlzCi0JCSAgTm9kZVRlc3RQYXR0ZXJuOm50IFByZWRpY2F0ZXM6cHAKLSAgICAgICAgICAgIHs6Ci0JICAgICAgIFJFU1VMVCA9IHBhcnNlci5jcmVhdGVTdGVwUGF0dGVybihheGlzLmludFZhbHVlKCksIG50LCBwcCk7Ci0gICAgICAgICAgICA6fQotCi0gICAgICAgICAgICB8IENoaWxkT3JBdHRyaWJ1dGVBeGlzU3BlY2lmaWVyOmF4aXMgUHJvY2Vzc2luZ0luc3RydWN0aW9uUGF0dGVybjpwaXAKLSAgICAgICAgICAgIHs6Ci0JICAgICAgIFJFU1VMVCA9IHBpcDsgCS8vIFRPRE86IHJlcG9ydCBlcnJvciBpZiBheGlzIGlzIGF0dHJpYnV0ZQotCSAgICA6fQotCi0JICAgIHwgQ2hpbGRPckF0dHJpYnV0ZUF4aXNTcGVjaWZpZXI6YXhpcyBQcm9jZXNzaW5nSW5zdHJ1Y3Rpb25QYXR0ZXJuOnBpcAotCQlQcmVkaWNhdGVzOnBwCi0gICAgICAgICAgICB7OgotCSAgICAgICAvLyBUT0RPOiByZXBvcnQgZXJyb3IgaWYgYXhpcyBpcyBhdHRyaWJ1dGUKLQkgICAgICAgUkVTVUxUID0gKFByb2Nlc3NpbmdJbnN0cnVjdGlvblBhdHRlcm4pcGlwLnNldFByZWRpY2F0ZXMocHApOwotCSAgICA6fTsKLQotTm9kZVRlc3RQYXR0ZXJuIDo6PSBOYW1lVGVzdFBhdHRlcm46bnQKLSAgICAgICAgICAgIHs6IFJFU1VMVCA9IG50OyA6fQotCi0gICAgICAgICAgICB8IE5PREUKLSAgICAgICAgICAgIHs6IFJFU1VMVCA9IG5ldyBJbnRlZ2VyKE5vZGVUZXN0LkFOT0RFKTsgOn0KLQotICAgICAgICAgICAgfCBURVhUCi0gICAgICAgICAgICB7OiBSRVNVTFQgPSBuZXcgSW50ZWdlcihOb2RlVGVzdC5URVhUKTsgOn0KLQotICAgICAgICAgICAgfCBDT01NRU5UCi0gICAgICAgICAgICB7OiBSRVNVTFQgPSBuZXcgSW50ZWdlcihOb2RlVGVzdC5DT01NRU5UKTsgOn0KLQotICAgICAgICAgICAgfCBQSQotICAgICAgICAgICAgezogUkVTVUxUID0gbmV3IEludGVnZXIoTm9kZVRlc3QuUEkpOyA6fTsKLQotTmFtZVRlc3RQYXR0ZXJuIDo6PSBTVEFSCi0gICAgICAgICAgICB7OiBSRVNVTFQgPSBudWxsOyA6fQotCi0gICAgICAgICAgICB8IFFOYW1lOnFuCi0gICAgICAgICAgICB7OiBSRVNVTFQgPSBxbjsgOn07Ci0KLUNoaWxkT3JBdHRyaWJ1dGVBeGlzU3BlY2lmaWVyIDo6PSBBVFNJR04KLSAgICAgICAgICAgIHs6IFJFU1VMVCA9IG5ldyBJbnRlZ2VyKEF4aXMuQVRUUklCVVRFKTsgOn0KLQotICAgICAgICAgICAgfCBDSElMRCBEQ09MT04KLSAgICAgICAgICAgIHs6IFJFU1VMVCA9IG5ldyBJbnRlZ2VyKEF4aXMuQ0hJTEQpOyA6fQotCi0gICAgICAgICAgICB8IEFUVFJJQlVURSBEQ09MT04KLSAgICAgICAgICAgIHs6IFJFU1VMVCA9IG5ldyBJbnRlZ2VyKEF4aXMuQVRUUklCVVRFKTsgOn07Ci0KLVByZWRpY2F0ZXMgOjo9IFByZWRpY2F0ZTpwCi0gICAgICAgICAgICB7OgotCQlWZWN0b3IgdGVtcCA9IG5ldyBWZWN0b3IoKTsKLQkJdGVtcC5hZGRFbGVtZW50KHApOwotCQlSRVNVTFQgPSB0ZW1wOwotICAgICAgICAgICAgOn0KLQotICAgICAgICAgICAgfCBQcmVkaWNhdGU6cCBQcmVkaWNhdGVzOnBwCi0gICAgICAgICAgICB7OiBwcC5pbnNlcnRFbGVtZW50QXQocCwgMCk7IFJFU1VMVCA9IHBwOyA6fTsKLQotUHJlZGljYXRlIDo6PSAgTEJSQUNLIEV4cHI6ZSBSQlJBQ0sKLQkgICAgezoKLQkJUkVTVUxUID0gbmV3IFByZWRpY2F0ZShlKTsKLQkgICAgOn07Ci0KLS8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBFeHByZXNzaW9ucyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KLQotRXhwciA6Oj0gT3JFeHByOmV4Ci0gICAgICAgIHs6IFJFU1VMVCA9IGV4OyA6fTsKLQotT3JFeHByIDo6PSBBbmRFeHByOmFlCi0gICAgICAgIHs6IFJFU1VMVCA9IGFlOyA6fQotCi0gICAgICAgIHwgT3JFeHByOm9lIE9SIEFuZEV4cHI6YWUKLSAgICAgICAgezogUkVTVUxUID0gbmV3IExvZ2ljYWxFeHByKExvZ2ljYWxFeHByLk9SLCBvZSwgYWUpOyA6fTsKLQotQW5kRXhwciA6Oj0gRXF1YWxpdHlFeHByOmUKLSAgICAgICAgezogUkVTVUxUID0gZTsgOn0KLQotICAgICAgICB8IEFuZEV4cHI6YWUgQU5EIEVxdWFsaXR5RXhwcjplZQotICAgICAgICB7OiBSRVNVTFQgPSBuZXcgTG9naWNhbEV4cHIoTG9naWNhbEV4cHIuQU5ELCBhZSwgZWUpOyA6fTsKLQotRXF1YWxpdHlFeHByIDo6PSBSZWxhdGlvbmFsRXhwcjpyZQotICAgICAgICB7OiBSRVNVTFQgPSByZTsgOn0KLQotICAgICAgICB8IEVxdWFsaXR5RXhwcjplZSBFUSBSZWxhdGlvbmFsRXhwcjpyZQotICAgICAgICB7OiBSRVNVTFQgPSBuZXcgRXF1YWxpdHlFeHByKE9wZXJhdG9ycy5FUSwgZWUsIHJlKTsgOn0KLQotICAgICAgICB8IEVxdWFsaXR5RXhwcjplZSBORSBSZWxhdGlvbmFsRXhwcjpyZQotICAgICAgICB7OiBSRVNVTFQgPSBuZXcgRXF1YWxpdHlFeHByKE9wZXJhdG9ycy5ORSwgZWUsIHJlKTsgOn07Ci0KLVJlbGF0aW9uYWxFeHByIDo6PSBBZGRpdGl2ZUV4cHI6YWUKLSAgICAgICAgezogUkVTVUxUID0gYWU7IDp9Ci0KLSAgICAgICAgfCBSZWxhdGlvbmFsRXhwcjpyZSBMVCBBZGRpdGl2ZUV4cHI6YWUKLSAgICAgICAgezogUkVTVUxUID0gbmV3IFJlbGF0aW9uYWxFeHByKE9wZXJhdG9ycy5MVCwgcmUsIGFlKTsgOn0KLQotICAgICAgICB8IFJlbGF0aW9uYWxFeHByOnJlIEdUIEFkZGl0aXZlRXhwcjphZQotICAgICAgICB7OiBSRVNVTFQgPSBuZXcgUmVsYXRpb25hbEV4cHIoT3BlcmF0b3JzLkdULCByZSwgYWUpOyA6fQotCi0gICAgICAgIHwgUmVsYXRpb25hbEV4cHI6cmUgTEUgQWRkaXRpdmVFeHByOmFlCi0gICAgICAgIHs6IFJFU1VMVCA9IG5ldyBSZWxhdGlvbmFsRXhwcihPcGVyYXRvcnMuTEUsIHJlLCBhZSk7IDp9Ci0KLSAgICAgICAgfCBSZWxhdGlvbmFsRXhwcjpyZSBHRSBBZGRpdGl2ZUV4cHI6YWUKLSAgICAgICAgezogUkVTVUxUID0gbmV3IFJlbGF0aW9uYWxFeHByKE9wZXJhdG9ycy5HRSwgcmUsIGFlKTsgOn07Ci0KLUFkZGl0aXZlRXhwciA6Oj0gTXVsdGlwbGljYXRpdmVFeHByOm1lCi0gICAgICAgIHs6IFJFU1VMVCA9IG1lOyA6fQotCi0gICAgICAgIHwgQWRkaXRpdmVFeHByOmFlIFBMVVMgIE11bHRpcGxpY2F0aXZlRXhwcjptZQotICAgICAgICB7OiBSRVNVTFQgPSBuZXcgQmluT3BFeHByKEJpbk9wRXhwci5QTFVTLCBhZSwgbWUpOyA6fQotCi0gICAgICAgIHwgQWRkaXRpdmVFeHByOmFlIE1JTlVTIE11bHRpcGxpY2F0aXZlRXhwcjptZQotICAgICAgICB7OiBSRVNVTFQgPSBuZXcgQmluT3BFeHByKEJpbk9wRXhwci5NSU5VUywgYWUsIG1lKTsgOn07Ci0KLU11bHRpcGxpY2F0aXZlRXhwciA6Oj0gVW5hcnlFeHByOnVlCi0gICAgICAgIHs6IFJFU1VMVCA9IHVlOyA6fQotCi0gICAgICAgIHwgTXVsdGlwbGljYXRpdmVFeHByOm1lIE1VTFQgVW5hcnlFeHByOnVlCi0gICAgICAgIHs6IFJFU1VMVCA9IG5ldyBCaW5PcEV4cHIoQmluT3BFeHByLlRJTUVTLCBtZSwgdWUpOyA6fQotCi0gICAgICAgIHwgTXVsdGlwbGljYXRpdmVFeHByOm1lIERJViBVbmFyeUV4cHI6dWUKLSAgICAgICAgezogUkVTVUxUID0gbmV3IEJpbk9wRXhwcihCaW5PcEV4cHIuRElWLCBtZSwgdWUpOyA6fQotCi0gICAgICAgIHwgTXVsdGlwbGljYXRpdmVFeHByOm1lIE1PRCBVbmFyeUV4cHI6dWUKLSAgICAgICAgezogUkVTVUxUID0gbmV3IEJpbk9wRXhwcihCaW5PcEV4cHIuTU9ELCBtZSwgdWUpOyA6fTsKLQotVW5hcnlFeHByIDo6PSBVbmlvbkV4cHI6dWUKLSAgICAgICAgezogUkVTVUxUID0gdWU7IDp9Ci0KLSAgICAgICAgfCBNSU5VUyBVbmFyeUV4cHI6dWUKLSAgICAgICAgezogUkVTVUxUID0gbmV3IFVuYXJ5T3BFeHByKHVlKTsgOn07Ci0KLVVuaW9uRXhwciA6Oj0gUGF0aEV4cHI6cGUKLSAgICAgICAgezogUkVTVUxUID0gcGU7IDp9Ci0KLSAgICAgICAgfCBQYXRoRXhwcjpwZSBWQkFSIFVuaW9uRXhwcjpyZXN0Ci0gICAgICAgIHs6IFJFU1VMVCA9IG5ldyBVbmlvblBhdGhFeHByKHBlLCByZXN0KTsgOn07Ci0KLVBhdGhFeHByIDo6PSBMb2NhdGlvblBhdGg6bHAKLSAgICAgICAgezogUkVTVUxUID0gbHA7IDp9Ci0KLSAgICAgICAgfCBGaWx0ZXJFeHByOmZleHAKLSAgICAgICAgezogUkVTVUxUID0gZmV4cDsgOn0KLQotICAgICAgICB8IEZpbHRlckV4cHI6ZmV4cCBTTEFTSCBSZWxhdGl2ZUxvY2F0aW9uUGF0aDpybHAKLSAgICAgICAgezogUkVTVUxUID0gbmV3IEZpbHRlclBhcmVudFBhdGgoZmV4cCwgcmxwKTsgOn0KLQotICAgICAgICB8IEZpbHRlckV4cHI6ZmV4cCBEU0xBU0ggUmVsYXRpdmVMb2NhdGlvblBhdGg6cmxwCi0gICAgICAgIHs6Ci0gICAgICAgICAgIC8vCi0JICAgLy8gRXhwYW5kICcvLycgaW50byAnL2Rlc2NlbmRhbnQtb3Itc2VsZjo6bm9kZSgpLycgb3IKLQkgICAvLyBpbnRvIC9kZXNjZW5kYW50LW9yLXNlbGY6OiovCi0JICAgLy8KLQkgICBpbnQgbm9kZVR5cGUgPSBET00uTk9fVFlQRTsKLQkgICBpZiAocmxwIGluc3RhbmNlb2YgU3RlcCAmJgotCSAgICAgICBwYXJzZXIuaXNFbGVtZW50QXhpcygoKFN0ZXApIHJscCkuZ2V0QXhpcygpKSkKLQkgICB7Ci0JICAgICAgIG5vZGVUeXBlID0gRFRNLkVMRU1FTlRfTk9ERTsKLQkgICB9Ci0gICAgICAgICAgIGZpbmFsIFN0ZXAgc3RlcCA9IG5ldyBTdGVwKEF4aXMuREVTQ0VOREFOVE9SU0VMRiwgbm9kZVR5cGUsIG51bGwpOwotICAgICAgICAgICBGaWx0ZXJQYXJlbnRQYXRoIGZwcCA9IG5ldyBGaWx0ZXJQYXJlbnRQYXRoKGZleHAsIHN0ZXApOwotICAgICAgICAgICBmcHAgPSBuZXcgRmlsdGVyUGFyZW50UGF0aChmcHAsIHJscCk7Ci0gICAgICAgICAgIGlmIChmZXhwIGluc3RhbmNlb2YgS2V5Q2FsbCA9PSBmYWxzZSkgewotICAgICAgICAgICAgICAgZnBwLnNldERlc2NlbmRhbnRBeGlzKCk7Ci0JICAgfQotICAgICAgICAgICBSRVNVTFQgPSBmcHA7Ci0gICAgICAgIDp9OwotCi1Mb2NhdGlvblBhdGggOjo9IFJlbGF0aXZlTG9jYXRpb25QYXRoOnJscAotICAgICAgICB7OiBSRVNVTFQgPSBybHA7IDp9Ci0KLSAgICAgICAgfCBBYnNvbHV0ZUxvY2F0aW9uUGF0aDphbHAKLSAgICAgICAgezogUkVTVUxUID0gYWxwOyA6fTsKLQotUmVsYXRpdmVMb2NhdGlvblBhdGggOjo9IFN0ZXA6c3RlcAotICAgICAgICB7OiBSRVNVTFQgPSBzdGVwOyA6fQotCi0gICAgICAgIHwgUmVsYXRpdmVMb2NhdGlvblBhdGg6cmxwIFNMQVNIIFN0ZXA6c3RlcAotICAgICAgICB7OgotICAgICAgICBpZiAocmxwIGluc3RhbmNlb2YgU3RlcCAmJiAoKFN0ZXApIHJscCkuaXNBYmJyZXZpYXRlZERvdCgpKSB7Ci0gICAgICAgICAgICAgIFJFU1VMVCA9IHN0ZXA7ICAgICAgIC8vIFJlbW92ZSAnLi8nIGZyb20gdGhlIG1pZGRsZQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKCgoU3RlcCkgc3RlcCkuaXNBYmJyZXZpYXRlZERvdCgpKSB7Ci0gICAgICAgICAgICAgIFJFU1VMVCA9IHJscDsgICAgICAgIC8vIFJlbW92ZSAnLy4nIGZyb20gdGhlIGVuZAotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgIFJFU1VMVCA9Ci0gICAgICAgICAgICAgICAgbmV3IFBhcmVudExvY2F0aW9uUGF0aCgoUmVsYXRpdmVMb2NhdGlvblBhdGgpIHJscCwgc3RlcCk7Ci0gICAgICAgICAgIH0KLSAgICAgICAgOn0KLQotICAgICAgICB8IEFiYnJldmlhdGVkUmVsYXRpdmVMb2NhdGlvblBhdGg6YXJscAotICAgICAgICB7OiBSRVNVTFQgPSBhcmxwOyA6fTsKLQotQWJzb2x1dGVMb2NhdGlvblBhdGggOjo9IFNMQVNICi0gICAgICAgIHs6IFJFU1VMVCA9IG5ldyBBYnNvbHV0ZUxvY2F0aW9uUGF0aCgpOyA6fQotCi0gICAgICAgIHwgU0xBU0ggUmVsYXRpdmVMb2NhdGlvblBhdGg6cmxwCi0gICAgICAgIHs6IFJFU1VMVCA9IG5ldyBBYnNvbHV0ZUxvY2F0aW9uUGF0aChybHApOyA6fQotCi0gICAgICAgIHwgQWJicmV2aWF0ZWRBYnNvbHV0ZUxvY2F0aW9uUGF0aDphYWxwCi0gICAgICAgIHs6IFJFU1VMVCA9IGFhbHA7IDp9OwotCi1BYmJyZXZpYXRlZFJlbGF0aXZlTG9jYXRpb25QYXRoIDo6PSBSZWxhdGl2ZUxvY2F0aW9uUGF0aDpybHAgRFNMQVNIIFN0ZXA6c3RlcAotICAgICAgICB7OgotCSAgIGZpbmFsIFN0ZXAgcmlnaHQgID0gKFN0ZXApc3RlcDsKLSAgICAgICAgICAgZmluYWwgaW50ICBheGlzICAgPSByaWdodC5nZXRBeGlzKCk7Ci0gICAgICAgICAgIGZpbmFsIGludCAgdHlwZSAgID0gcmlnaHQuZ2V0Tm9kZVR5cGUoKTsKLSAgICAgICAgICAgZmluYWwgVmVjdG9yIHByZWRpY2F0ZXMgPSByaWdodC5nZXRQcmVkaWNhdGVzKCk7Ci0KLSAgICAgICAgICAgaWYgKChheGlzID09IEF4aXMuQ0hJTEQpICYmICh0eXBlICE9IE5vZGVUZXN0LkFUVFJJQlVURSkpIHsKLSAgICAgICAgICAgICAgIC8vIENvbXByZXNzICcuLy9jaGlsZDpFJyBpbnRvICdkZXNjZW5kYW50OjpFJyAtIGlmIHBvc3NpYmxlCi0gICAgICAgICAgICAgICBpZiAocHJlZGljYXRlcyA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgcmlnaHQuc2V0QXhpcyhBeGlzLkRFU0NFTkRBTlQpOwotICAgICAgICAgICAgICAgICAgIGlmIChybHAgaW5zdGFuY2VvZiBTdGVwICYmICgoU3RlcClybHApLmlzQWJicmV2aWF0ZWREb3QoKSkgewotCSAgICAgICAgICAgICAgIFJFU1VMVCA9IHJpZ2h0OwotICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgLy8gRXhwYW5kICdybHAvL2NoaWxkOjpFJyBpbnRvICdybHAvZGVzY2VuZGFudDo6RScKLSAgICAgICAgICAgICAgICAgICAgICAgUmVsYXRpdmVMb2NhdGlvblBhdGggbGVmdCA9IChSZWxhdGl2ZUxvY2F0aW9uUGF0aClybHA7Ci0JICAgICAgICAgICAgICAgUkVTVUxUID0gbmV3IFBhcmVudExvY2F0aW9uUGF0aChsZWZ0LCByaWdodCk7Ci0gICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgLy8gRXhwYW5kICcuLy9zdGVwJyAtPiAnZGVzY2VuZGFudC1vci1zZWxmOjoqL3N0ZXAnCi0gICAgICAgICAgICAgICAgICAgaWYgKHJscCBpbnN0YW5jZW9mIFN0ZXAgJiYgKChTdGVwKXJscCkuaXNBYmJyZXZpYXRlZERvdCgpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgIFN0ZXAgbGVmdCA9IG5ldyBTdGVwKEF4aXMuREVTQ0VOREFOVE9SU0VMRiwKLQkJCSAgICBEVE0uRUxFTUVOVF9OT0RFLCBudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgICAgUkVTVUxUID0gbmV3IFBhcmVudExvY2F0aW9uUGF0aChsZWZ0LCByaWdodCk7Ci0gICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAvLyBFeHBhbmQgJ3JscC8vc3RlcCcgLT4gJ3JscC9kZXNjZW5kYW50LW9yLXNlbGY6Oiovc3RlcCcKLSAgICAgICAgICAgICAgICAgICAgICAgUmVsYXRpdmVMb2NhdGlvblBhdGggbGVmdCA9IChSZWxhdGl2ZUxvY2F0aW9uUGF0aClybHA7Ci0gICAgICAgICAgICAgICAgICAgICAgIFN0ZXAgbWlkID0gbmV3IFN0ZXAoQXhpcy5ERVNDRU5EQU5UT1JTRUxGLAotCQkJICAgIERUTS5FTEVNRU5UX05PREUsIG51bGwpOwotICAgICAgICAgICAgICAgICAgICAgICBQYXJlbnRMb2NhdGlvblBhdGggcHBsID0gbmV3IFBhcmVudExvY2F0aW9uUGF0aChtaWQsIHJpZ2h0KTsKLSAgICAgICAgICAgICAgICAgICAgICAgUkVTVUxUID0gbmV3IFBhcmVudExvY2F0aW9uUGF0aChsZWZ0LCBwcGwpOwotICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgfQotICAgICAgICAgICBlbHNlIGlmICgoYXhpcyA9PSBBeGlzLkFUVFJJQlVURSkgfHwgKHR5cGUgPT0gTm9kZVRlc3QuQVRUUklCVVRFKSkgewotICAgICAgICAgICAgICAgLy8gRXhwYW5kICdybHAvL3N0ZXAnIC0+ICdybHAvZGVzY2VuZGFudC1vci1zZWxmOjoqL3N0ZXAnCi0gICAgICAgICAgICAgICBSZWxhdGl2ZUxvY2F0aW9uUGF0aCBsZWZ0ID0gKFJlbGF0aXZlTG9jYXRpb25QYXRoKXJscDsKLSAgICAgICAgICAgICAgIFN0ZXAgbWlkZGxlID0gbmV3IFN0ZXAoQXhpcy5ERVNDRU5EQU5UT1JTRUxGLAotCQkgICAgRFRNLkVMRU1FTlRfTk9ERSwgbnVsbCk7Ci0gICAgICAgICAgICAgICBQYXJlbnRMb2NhdGlvblBhdGggcHBsID0gbmV3IFBhcmVudExvY2F0aW9uUGF0aChtaWRkbGUsIHJpZ2h0KTsKLSAgICAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBQYXJlbnRMb2NhdGlvblBhdGgobGVmdCwgcHBsKTsKLQkgICB9Ci0JICAgZWxzZSB7Ci0JICAgICAgIC8vIEV4cGFuZCAncmxwLy9zdGVwJyAtPiAncmxwL2Rlc2NlbmRhbnQtb3Itc2VsZjo6bm9kZSgpL3N0ZXAnCi0gICAgICAgICAgICAgICBSZWxhdGl2ZUxvY2F0aW9uUGF0aCBsZWZ0ID0gKFJlbGF0aXZlTG9jYXRpb25QYXRoKXJscDsKLQkgICAgICAgU3RlcCBtaWRkbGUgPSBuZXcgU3RlcChBeGlzLkRFU0NFTkRBTlRPUlNFTEYsCi0JCSAgICBET00uTk9fVFlQRSwgbnVsbCk7Ci0gICAgICAgICAgICAgICBQYXJlbnRMb2NhdGlvblBhdGggcHBsID0gbmV3IFBhcmVudExvY2F0aW9uUGF0aChtaWRkbGUsIHJpZ2h0KTsKLQkgICAgICAgUkVTVUxUID0gbmV3IFBhcmVudExvY2F0aW9uUGF0aChsZWZ0LCBwcGwpOwotCSAgIH0KLSAgICAgICAgOn07Ci0KLQotQWJicmV2aWF0ZWRBYnNvbHV0ZUxvY2F0aW9uUGF0aCA6Oj0gRFNMQVNIIFJlbGF0aXZlTG9jYXRpb25QYXRoOnJscAotICAgICAgICB7OgotICAgICAgICAgICAvLwotCSAgIC8vIEV4cGFuZCAnLy8nIGludG8gJy9kZXNjZW5kYW50LW9yLXNlbGY6Om5vZGUoKS8nIG9yCi0JICAgLy8gaW50byAvZGVzY2VuZGFudC1vci1zZWxmOjoqLwotCSAgIC8vCi0JICAgaW50IG5vZGVUeXBlID0gRE9NLk5PX1RZUEU7Ci0JICAgaWYgKHJscCBpbnN0YW5jZW9mIFN0ZXAgJiYKLQkgICAgICAgcGFyc2VyLmlzRWxlbWVudEF4aXMoKChTdGVwKSBybHApLmdldEF4aXMoKSkpCi0JICAgewotCSAgICAgICBub2RlVHlwZSA9IERUTS5FTEVNRU5UX05PREU7Ci0JICAgfQotCSAgIGZpbmFsIFN0ZXAgc3RlcCA9IG5ldyBTdGVwKEF4aXMuREVTQ0VOREFOVE9SU0VMRiwgbm9kZVR5cGUsIG51bGwpOwotCSAgIFJFU1VMVCA9IG5ldyBBYnNvbHV0ZUxvY2F0aW9uUGF0aChwYXJzZXIuaW5zZXJ0U3RlcChzdGVwLAotCQkJCShSZWxhdGl2ZUxvY2F0aW9uUGF0aCkgcmxwKSk7Ci0JOn07Ci0KLVN0ZXAgOjo9IE5vZGVUZXN0Om50ZXN0Ci0gICAgICAgIHs6Ci0gICAgICAgICAgICBpZiAobnRlc3QgaW5zdGFuY2VvZiBTdGVwKSB7Ci0gICAgICAgICAgICAgICAgUkVTVUxUID0gKFN0ZXApbnRlc3Q7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLQkJUkVTVUxUID0gbmV3IFN0ZXAoQXhpcy5DSElMRCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2VyLmZpbmROb2RlVHlwZShBeGlzLkNISUxELCBudGVzdCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwpOwotICAgICAgICAgICAgfQotICAgICAgICA6fQotCi0gICAgICAgIHwgTm9kZVRlc3Q6bnRlc3QgUHJlZGljYXRlczpwcAotICAgICAgICB7OgotICAgICAgICAgICAgaWYgKG50ZXN0IGluc3RhbmNlb2YgU3RlcCkgewotICAgICAgICAgICAgICAgIFN0ZXAgc3RlcCA9IChTdGVwKW50ZXN0OwotICAgICAgICAgICAgICAgIHN0ZXAuYWRkUHJlZGljYXRlcyhwcCk7Ci0gICAgICAgICAgICAgICAgUkVTVUxUID0gKFN0ZXApbnRlc3Q7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBSRVNVTFQgPSBuZXcgU3RlcChBeGlzLkNISUxELAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJzZXIuZmluZE5vZGVUeXBlKEF4aXMuQ0hJTEQsIG50ZXN0KSwgcHApOwotICAgICAgICAgICAgfQotICAgICAgICA6fQotCi0gICAgICAgIHwgQXhpc1NwZWNpZmllcjpheGlzIE5vZGVUZXN0Om50ZXN0IFByZWRpY2F0ZXM6cHAKLSAgICAgICAgezogUkVTVUxUID0gbmV3IFN0ZXAoYXhpcy5pbnRWYWx1ZSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJzZXIuZmluZE5vZGVUeXBlKGF4aXMuaW50VmFsdWUoKSwgbnRlc3QpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcCk7Ci0gICAgICAgIDp9Ci0KLSAgICAgICAgfCBBeGlzU3BlY2lmaWVyOmF4aXMgTm9kZVRlc3Q6bnRlc3QKLSAgICAgICAgezogUkVTVUxUID0gbmV3IFN0ZXAoYXhpcy5pbnRWYWx1ZSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJzZXIuZmluZE5vZGVUeXBlKGF4aXMuaW50VmFsdWUoKSwgbnRlc3QpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsKTsKLSAgICAgICAgOn0KLQotICAgICAgICB8IEFiYnJldmlhdGVkU3RlcDphYmJyZXYKLSAgICAgICAgezogUkVTVUxUID0gYWJicmV2OyA6fTsKLQotQXhpc1NwZWNpZmllciA6Oj0gQXhpc05hbWU6YW4gRENPTE9OCi0gICAgICAgIHs6IFJFU1VMVCA9IGFuOyA6fQotCi0gICAgICAgIHwgQVRTSUdOCi0gICAgICAgIHs6IFJFU1VMVCA9IG5ldyBJbnRlZ2VyKEF4aXMuQVRUUklCVVRFKTsgOn07Ci0KLUF4aXNOYW1lIDo6PSAgICBBTkNFU1RPUgotICAgICAgICB7OiBSRVNVTFQgPSBuZXcgSW50ZWdlcihBeGlzLkFOQ0VTVE9SKTsgOn0KLQotICAgICAgICB8IEFOQ0VTVE9ST1JTRUxGCi0gICAgICAgIHs6IFJFU1VMVCA9IG5ldyBJbnRlZ2VyKEF4aXMuQU5DRVNUT1JPUlNFTEYpOyA6fQotCi0gICAgICAgIHwgQVRUUklCVVRFCi0gICAgICAgIHs6IFJFU1VMVCA9IG5ldyBJbnRlZ2VyKEF4aXMuQVRUUklCVVRFKTsgOn0KLQotICAgICAgICB8IENISUxECi0gICAgICAgIHs6IFJFU1VMVCA9IG5ldyBJbnRlZ2VyKEF4aXMuQ0hJTEQpOyA6fQotCi0gICAgICAgIHwgREVTQ0VOREFOVAotICAgICAgICB7OiBSRVNVTFQgPSBuZXcgSW50ZWdlcihBeGlzLkRFU0NFTkRBTlQpOyA6fQotCi0gICAgICAgIHwgREVTQ0VOREFOVE9SU0VMRgotICAgICAgICB7OiBSRVNVTFQgPSBuZXcgSW50ZWdlcihBeGlzLkRFU0NFTkRBTlRPUlNFTEYpOyA6fQotCi0gICAgICAgIHwgRk9MTE9XSU5HCi0gICAgICAgIHs6IFJFU1VMVCA9IG5ldyBJbnRlZ2VyKEF4aXMuRk9MTE9XSU5HKTsgOn0KLQotICAgICAgICB8IEZPTExPV0lOR1NJQkxJTkcKLSAgICAgICAgezogUkVTVUxUID0gbmV3IEludGVnZXIoQXhpcy5GT0xMT1dJTkdTSUJMSU5HKTsgOn0KLQotICAgICAgICB8IE5BTUVTUEFDRQotICAgICAgICB7OiBSRVNVTFQgPSBuZXcgSW50ZWdlcihBeGlzLk5BTUVTUEFDRSk7IDp9Ci0KLSAgICAgICAgfCBQQVJFTlQKLSAgICAgICAgezogUkVTVUxUID0gbmV3IEludGVnZXIoQXhpcy5QQVJFTlQpOyA6fQotCi0gICAgICAgIHwgUFJFQ0VESU5HCi0gICAgICAgIHs6IFJFU1VMVCA9IG5ldyBJbnRlZ2VyKEF4aXMuUFJFQ0VESU5HKTsgOn0KLQotICAgICAgICB8IFBSRUNFRElOR1NJQkxJTkcKLSAgICAgICAgezogUkVTVUxUID0gbmV3IEludGVnZXIoQXhpcy5QUkVDRURJTkdTSUJMSU5HKTsgOn0KLQotICAgICAgICB8IFNFTEYKLSAgICAgICAgezogUkVTVUxUID0gbmV3IEludGVnZXIoQXhpcy5TRUxGKTsgOn07Ci0KLUFiYnJldmlhdGVkU3RlcCA6Oj0gRE9UCi0gICAgICAgIHs6IFJFU1VMVCA9IG5ldyBTdGVwKEF4aXMuU0VMRiwgTm9kZVRlc3QuQU5PREUsIG51bGwpOyA6fQotCi0gICAgICAgIHwgRERPVAotICAgICAgICB7OiBSRVNVTFQgPSBuZXcgU3RlcChBeGlzLlBBUkVOVCwgTm9kZVRlc3QuQU5PREUsIG51bGwpOyA6fTsKLQotRmlsdGVyRXhwciA6Oj0gIFByaW1hcnlFeHByOnByaW1hcnkKLSAgICAgICAgezogUkVTVUxUID0gcHJpbWFyeTsgOn0KLQotICAgICAgICB8IFByaW1hcnlFeHByOnByaW1hcnkgUHJlZGljYXRlczpwcAotICAgICAgICB7OiBSRVNVTFQgPSBuZXcgRmlsdGVyRXhwcihwcmltYXJ5LCBwcCk7IDp9OwotCi1QcmltYXJ5RXhwciA6Oj0gVmFyaWFibGVSZWZlcmVuY2U6dnIKLSAgICAgICAgezogUkVTVUxUID0gdnI7IDp9Ci0KLSAgICAgICAgfCBMUEFSRU4gRXhwcjpleCBSUEFSRU4KLSAgICAgICAgezogUkVTVUxUID0gZXg7IDp9Ci0KLQl8IExpdGVyYWw6c3RyaW5nCi0JezoKLQkvKgotCSogSWYgdGhlIHN0cmluZyBhcHBlYXJzIHRvIGhhdmUgdGhlIHN5bnRheCBvZiBhIFFOYW1lLCBzdG9yZQotCSogbmFtZXNwYWNlIGluZm8gaW4gdGhlIGxpdGVyYWwgZXhwcmVzc2lvbi4gVGhpcyBpcyB1c2VkIGZvcgotCSogZWxlbWVudC1hdmFpbGFibGUgYW5kIGZ1bmN0aW9uLWF2YWlsYWJsZSBmdW5jdGlvbnMsIGFtb25nCi0JKiBvdGhlcnMuIEFsc28sIHRoZSBkZWZhdWx0IG5hbWVzcGFjZSBtdXN0IGJlIGlnbm9yZWQuCi0JKi8KLQlTdHJpbmcgbmFtZXNwYWNlID0gbnVsbDsKLQlmaW5hbCBpbnQgaW5kZXggPSBzdHJpbmcubGFzdEluZGV4T2YoJzonKTsKLQotCWlmIChpbmRleCA+IDApIHsKLQkgICAgZmluYWwgU3RyaW5nIHByZWZpeCA9IHN0cmluZy5zdWJzdHJpbmcoMCwgaW5kZXgpOwotCSAgICBuYW1lc3BhY2UgPSBwYXJzZXIuX3N5bWJvbFRhYmxlLmxvb2t1cE5hbWVzcGFjZShwcmVmaXgpOwotCX0KLQlSRVNVTFQgPSAobmFtZXNwYWNlID09IG51bGwpID8gbmV3IExpdGVyYWxFeHByKHN0cmluZykKLQkJICAgICA6IG5ldyBMaXRlcmFsRXhwcihzdHJpbmcsIG5hbWVzcGFjZSk7Ci0JOn0KLQotICAgICAgICB8IElOVDpudW0KLSAgICAgICAgezoKLQkgICBsb25nIHZhbHVlID0gbnVtLmxvbmdWYWx1ZSgpOwotCSAgIGlmICh2YWx1ZSA8IEludGVnZXIuTUlOX1ZBTFVFIHx8IHZhbHVlID4gSW50ZWdlci5NQVhfVkFMVUUpIHsKLQkJUkVTVUxUID0gbmV3IFJlYWxFeHByKHZhbHVlKTsKLQkgICB9Ci0JICAgZWxzZSB7Ci0gICAgICAgICAgICAgICBpZiAobnVtLmRvdWJsZVZhbHVlKCkgPT0gLTApCi0gICAgICAgICAgICAgICAgICAgUkVTVUxUID0gbmV3IFJlYWxFeHByKG51bS5kb3VibGVWYWx1ZSgpKTsKLSAgICAgICAgICAgICAgIGVsc2UgaWYgKG51bS5pbnRWYWx1ZSgpID09IDApCi0gICAgICAgICAgICAgICAgICAgUkVTVUxUID0gbmV3IEludEV4cHIobnVtLmludFZhbHVlKCkpOwotICAgICAgICAgICAgICAgZWxzZSBpZiAobnVtLmRvdWJsZVZhbHVlKCkgPT0gMC4wKQotICAgICAgICAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBSZWFsRXhwcihudW0uZG91YmxlVmFsdWUoKSk7Ci0gICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgUkVTVUxUID0gbmV3IEludEV4cHIobnVtLmludFZhbHVlKCkpOwotCSAgIH0KLSAgICAgICAgOn0KLQotICAgICAgICB8IFJFQUw6bnVtCi0gICAgICAgIHs6IFJFU1VMVCA9IG5ldyBSZWFsRXhwcihudW0uZG91YmxlVmFsdWUoKSk7IDp9Ci0KLSAgICAgICAgfCBGdW5jdGlvbkNhbGw6ZmMKLSAgICAgICAgezogUkVTVUxUID0gZmM7IDp9OwotCi1WYXJpYWJsZVJlZmVyZW5jZSA6Oj0gRE9MTEFSIFZhcmlhYmxlTmFtZTp2YXJOYW1lCi0gICAgICAgIHs6Ci0gICAgICAgICAgICAvLyBBbiBlbXB0eSBxbmFtZSBwcmVmaXggZm9yIGEgdmFyaWFibGUgb3IgcGFyYW1ldGVyIHJlZmVyZW5jZQotICAgICAgICAgICAgLy8gc2hvdWxkIG1hcCB0byB0aGUgbnVsbCBuYW1lc3BhY2UgYW5kIG5vdCB0aGUgZGVmYXVsdCBVUkkuCi0gICAgICAgICAgICBTeW50YXhUcmVlTm9kZSBub2RlID0gcGFyc2VyLmxvb2t1cE5hbWUodmFyTmFtZSk7Ci0KLSAgICAgICAgICAgIGlmIChub2RlICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBpZiAobm9kZSBpbnN0YW5jZW9mIFZhcmlhYmxlKSB7Ci0gICAgICAgICAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBWYXJpYWJsZVJlZigoVmFyaWFibGUpbm9kZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgaWYgKG5vZGUgaW5zdGFuY2VvZiBQYXJhbSkgewotICAgICAgICAgICAgICAgICAgICBSRVNVTFQgPSBuZXcgUGFyYW1ldGVyUmVmKChQYXJhbSlub2RlKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBVbnJlc29sdmVkUmVmKHZhck5hbWUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKG5vZGUgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBVbnJlc29sdmVkUmVmKHZhck5hbWUpOwotICAgICAgICAgICAgfQotICAgICAgICA6fTsKLQotRnVuY3Rpb25DYWxsIDo6PSBGdW5jdGlvbk5hbWU6Zm5hbWUgTFBBUkVOIFJQQVJFTgotICAgICAgICB7OgotCi0gICAgICAgICAgaWYgKHBhcnNlci5nZXRRTmFtZUlnbm9yZURlZmF1bHROcygiY3VycmVudCIpLmVxdWFscyhmbmFtZSkpIHsKLSAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBDdXJyZW50Q2FsbChmbmFtZSk7Ci0JICB9Ci0gICAgICAgICAgZWxzZSBpZiAocGFyc2VyLmdldFFOYW1lSWdub3JlRGVmYXVsdE5zKCJudW1iZXIiKS5lcXVhbHMoZm5hbWUpKSB7Ci0gICAgICAgICAgICBSRVNVTFQgPSBuZXcgTnVtYmVyQ2FsbChmbmFtZSwgcGFyc2VyLkVtcHR5QXJncyk7Ci0JICB9Ci0gICAgICAgICAgZWxzZSBpZiAocGFyc2VyLmdldFFOYW1lSWdub3JlRGVmYXVsdE5zKCJzdHJpbmciKS5lcXVhbHMoZm5hbWUpKSB7Ci0gICAgICAgICAgICBSRVNVTFQgPSBuZXcgU3RyaW5nQ2FsbChmbmFtZSwgcGFyc2VyLkVtcHR5QXJncyk7Ci0JICB9Ci0gICAgICAgICAgZWxzZSBpZiAocGFyc2VyLmdldFFOYW1lSWdub3JlRGVmYXVsdE5zKCJjb25jYXQiKS5lcXVhbHMoZm5hbWUpKSB7Ci0gICAgICAgICAgICBSRVNVTFQgPSBuZXcgQ29uY2F0Q2FsbChmbmFtZSwgcGFyc2VyLkVtcHR5QXJncyk7Ci0JICB9Ci0gICAgICAgICAgZWxzZSBpZiAocGFyc2VyLmdldFFOYW1lSWdub3JlRGVmYXVsdE5zKCJ0cnVlIikuZXF1YWxzKGZuYW1lKSkgewotICAgICAgICAgICAgUkVTVUxUID0gbmV3IEJvb2xlYW5FeHByKHRydWUpOwotCSAgfQotICAgICAgICAgIGVsc2UgaWYgKHBhcnNlci5nZXRRTmFtZUlnbm9yZURlZmF1bHROcygiZmFsc2UiKS5lcXVhbHMoZm5hbWUpKSB7Ci0gICAgICAgICAgICBSRVNVTFQgPSBuZXcgQm9vbGVhbkV4cHIoZmFsc2UpOwotCSAgfQotICAgICAgICAgIGVsc2UgaWYgKHBhcnNlci5nZXRRTmFtZUlnbm9yZURlZmF1bHROcygibmFtZSIpLmVxdWFscyhmbmFtZSkpIHsKLSAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBOYW1lQ2FsbChmbmFtZSk7Ci0JICB9Ci0gICAgICAgICAgZWxzZSBpZiAocGFyc2VyLmdldFFOYW1lSWdub3JlRGVmYXVsdE5zKCJnZW5lcmF0ZS1pZCIpLmVxdWFscyhmbmFtZSkpIHsKLSAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBHZW5lcmF0ZUlkQ2FsbChmbmFtZSwgcGFyc2VyLkVtcHR5QXJncyk7Ci0JICB9Ci0gICAgICAgICAgZWxzZSBpZiAocGFyc2VyLmdldFFOYW1lSWdub3JlRGVmYXVsdE5zKCJzdHJpbmctbGVuZ3RoIikuZXF1YWxzKGZuYW1lKSkgewotICAgICAgICAgICAgUkVTVUxUID0gbmV3IFN0cmluZ0xlbmd0aENhbGwoZm5hbWUsIHBhcnNlci5FbXB0eUFyZ3MpOwotCSAgfQotICAgICAgICAgIGVsc2UgaWYgKHBhcnNlci5nZXRRTmFtZUlnbm9yZURlZmF1bHROcygicG9zaXRpb24iKS5lcXVhbHMoZm5hbWUpKSB7Ci0gICAgICAgICAgICBSRVNVTFQgPSBuZXcgUG9zaXRpb25DYWxsKGZuYW1lKTsKLQkgIH0KLSAgICAgICAgICBlbHNlIGlmIChwYXJzZXIuZ2V0UU5hbWVJZ25vcmVEZWZhdWx0TnMoImxhc3QiKS5lcXVhbHMoZm5hbWUpKSB7Ci0gICAgICAgICAgICBSRVNVTFQgPSBuZXcgTGFzdENhbGwoZm5hbWUpOwotCSAgfQotICAgICAgICAgIGVsc2UgaWYgKHBhcnNlci5nZXRRTmFtZUlnbm9yZURlZmF1bHROcygibG9jYWwtbmFtZSIpLmVxdWFscyhmbmFtZSkpIHsKLSAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBMb2NhbE5hbWVDYWxsKGZuYW1lKTsKLQkgIH0KLSAgICAgICAgICBlbHNlIGlmIChwYXJzZXIuZ2V0UU5hbWVJZ25vcmVEZWZhdWx0TnMoIm5hbWVzcGFjZS11cmkiKS5lcXVhbHMoZm5hbWUpKSB7Ci0gICAgICAgICAgICBSRVNVTFQgPSBuZXcgTmFtZXNwYWNlVXJpQ2FsbChmbmFtZSk7Ci0JICB9Ci0gICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBSRVNVTFQgPSBuZXcgRnVuY3Rpb25DYWxsKGZuYW1lLCBwYXJzZXIuRW1wdHlBcmdzKTsKLQkgIH0KLSAgICAgICAgOn0KLQotICAgICAgICB8IEZ1bmN0aW9uTmFtZTpmbmFtZSBMUEFSRU4gTm9uZW1wdHlBcmd1bWVudExpc3Q6YXJnbCBSUEFSRU4KLSAgICAgICAgezoKLSAgICAgICAgICBpZiAocGFyc2VyLmdldFFOYW1lSWdub3JlRGVmYXVsdE5zKCJjb25jYXQiKS5lcXVhbHMoZm5hbWUpKSB7Ci0gICAgICAgICAgICBSRVNVTFQgPSBuZXcgQ29uY2F0Q2FsbChmbmFtZSwgYXJnbCk7Ci0JICB9Ci0gICAgICAgICAgZWxzZSBpZiAocGFyc2VyLmdldFFOYW1lSWdub3JlRGVmYXVsdE5zKCJudW1iZXIiKS5lcXVhbHMoZm5hbWUpKSB7Ci0gICAgICAgICAgICBSRVNVTFQgPSBuZXcgTnVtYmVyQ2FsbChmbmFtZSwgYXJnbCk7Ci0JICB9Ci0gICAgICAgICAgZWxzZSBpZiAocGFyc2VyLmdldFFOYW1lSWdub3JlRGVmYXVsdE5zKCJkb2N1bWVudCIpLmVxdWFscyhmbmFtZSkpIHsKLQkgICAgcGFyc2VyLnNldE11bHRpRG9jdW1lbnQodHJ1ZSk7Ci0gICAgICAgICAgICBSRVNVTFQgPSBuZXcgRG9jdW1lbnRDYWxsKGZuYW1lLCBhcmdsKTsKLQkgIH0KLSAgICAgICAgICBlbHNlIGlmIChwYXJzZXIuZ2V0UU5hbWVJZ25vcmVEZWZhdWx0TnMoInN0cmluZyIpLmVxdWFscyhmbmFtZSkpIHsKLSAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBTdHJpbmdDYWxsKGZuYW1lLCBhcmdsKTsKLQkgIH0KLSAgICAgICAgICBlbHNlIGlmIChwYXJzZXIuZ2V0UU5hbWVJZ25vcmVEZWZhdWx0TnMoImJvb2xlYW4iKS5lcXVhbHMoZm5hbWUpKSB7Ci0gICAgICAgICAgICBSRVNVTFQgPSBuZXcgQm9vbGVhbkNhbGwoZm5hbWUsIGFyZ2wpOwotCSAgfQotICAgICAgICAgIGVsc2UgaWYgKHBhcnNlci5nZXRRTmFtZUlnbm9yZURlZmF1bHROcygibmFtZSIpLmVxdWFscyhmbmFtZSkpIHsKLSAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBOYW1lQ2FsbChmbmFtZSwgYXJnbCk7Ci0JICB9Ci0gICAgICAgICAgZWxzZSBpZiAocGFyc2VyLmdldFFOYW1lSWdub3JlRGVmYXVsdE5zKCJnZW5lcmF0ZS1pZCIpLmVxdWFscyhmbmFtZSkpIHsKLSAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBHZW5lcmF0ZUlkQ2FsbChmbmFtZSwgYXJnbCk7Ci0JICB9Ci0gICAgICAgICAgZWxzZSBpZiAocGFyc2VyLmdldFFOYW1lSWdub3JlRGVmYXVsdE5zKCJub3QiKS5lcXVhbHMoZm5hbWUpKSB7Ci0gICAgICAgICAgICBSRVNVTFQgPSBuZXcgTm90Q2FsbChmbmFtZSwgYXJnbCk7Ci0JICB9Ci0gICAgICAgICAgZWxzZSBpZiAocGFyc2VyLmdldFFOYW1lSWdub3JlRGVmYXVsdE5zKCJmb3JtYXQtbnVtYmVyIikuZXF1YWxzKGZuYW1lKSkgewotICAgICAgICAgICAgUkVTVUxUID0gbmV3IEZvcm1hdE51bWJlckNhbGwoZm5hbWUsIGFyZ2wpOwotCSAgfQotICAgICAgICAgIGVsc2UgaWYgKHBhcnNlci5nZXRRTmFtZUlnbm9yZURlZmF1bHROcygidW5wYXJzZWQtZW50aXR5LXVyaSIpLmVxdWFscyhmbmFtZSkpIHsKLSAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBVbnBhcnNlZEVudGl0eVVyaUNhbGwoZm5hbWUsIGFyZ2wpOwotCSAgfQotICAgICAgICAgIGVsc2UgaWYgKHBhcnNlci5nZXRRTmFtZUlnbm9yZURlZmF1bHROcygia2V5IikuZXF1YWxzKGZuYW1lKSkgewotICAgICAgICAgICAgUkVTVUxUID0gbmV3IEtleUNhbGwoZm5hbWUsIGFyZ2wpOwotCSAgfQotICAgICAgICAgIGVsc2UgaWYgKHBhcnNlci5nZXRRTmFtZUlnbm9yZURlZmF1bHROcygiaWQiKS5lcXVhbHMoZm5hbWUpKSB7Ci0gICAgICAgICAgICBSRVNVTFQgPSBuZXcgS2V5Q2FsbChmbmFtZSwgYXJnbCk7Ci0gICAgICAgICAgICBwYXJzZXIuc2V0SGFzSWRDYWxsKHRydWUpOwotCSAgfQotICAgICAgICAgIGVsc2UgaWYgKHBhcnNlci5nZXRRTmFtZUlnbm9yZURlZmF1bHROcygiY2VpbGluZyIpLmVxdWFscyhmbmFtZSkpIHsKLSAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBDZWlsaW5nQ2FsbChmbmFtZSwgYXJnbCk7Ci0JICB9Ci0gICAgICAgICAgZWxzZSBpZiAocGFyc2VyLmdldFFOYW1lSWdub3JlRGVmYXVsdE5zKCJyb3VuZCIpLmVxdWFscyhmbmFtZSkpIHsKLSAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBSb3VuZENhbGwoZm5hbWUsIGFyZ2wpOwotCSAgfQotICAgICAgICAgIGVsc2UgaWYgKHBhcnNlci5nZXRRTmFtZUlnbm9yZURlZmF1bHROcygiZmxvb3IiKS5lcXVhbHMoZm5hbWUpKSB7Ci0gICAgICAgICAgICBSRVNVTFQgPSBuZXcgRmxvb3JDYWxsKGZuYW1lLCBhcmdsKTsKLQkgIH0KLSAgICAgICAgICBlbHNlIGlmIChwYXJzZXIuZ2V0UU5hbWVJZ25vcmVEZWZhdWx0TnMoImNvbnRhaW5zIikuZXF1YWxzKGZuYW1lKSkgewotICAgICAgICAgICAgUkVTVUxUID0gbmV3IENvbnRhaW5zQ2FsbChmbmFtZSwgYXJnbCk7Ci0JICB9Ci0gICAgICAgICAgZWxzZSBpZiAocGFyc2VyLmdldFFOYW1lSWdub3JlRGVmYXVsdE5zKCJzdHJpbmctbGVuZ3RoIikuZXF1YWxzKGZuYW1lKSkgewotICAgICAgICAgICAgUkVTVUxUID0gbmV3IFN0cmluZ0xlbmd0aENhbGwoZm5hbWUsIGFyZ2wpOwotCSAgfQotICAgICAgICAgIGVsc2UgaWYgKHBhcnNlci5nZXRRTmFtZUlnbm9yZURlZmF1bHROcygic3RhcnRzLXdpdGgiKS5lcXVhbHMoZm5hbWUpKSB7Ci0gICAgICAgICAgICBSRVNVTFQgPSBuZXcgU3RhcnRzV2l0aENhbGwoZm5hbWUsIGFyZ2wpOwotCSAgfQotICAgICAgICAgIGVsc2UgaWYgKHBhcnNlci5nZXRRTmFtZUlnbm9yZURlZmF1bHROcygiZnVuY3Rpb24tYXZhaWxhYmxlIikuZXF1YWxzKGZuYW1lKSkgewotICAgICAgICAgICAgUkVTVUxUID0gbmV3IEZ1bmN0aW9uQXZhaWxhYmxlQ2FsbChmbmFtZSwgYXJnbCk7Ci0JICB9Ci0gICAgICAgICAgZWxzZSBpZiAocGFyc2VyLmdldFFOYW1lSWdub3JlRGVmYXVsdE5zKCJlbGVtZW50LWF2YWlsYWJsZSIpLmVxdWFscyhmbmFtZSkpIHsKLSAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBFbGVtZW50QXZhaWxhYmxlQ2FsbChmbmFtZSwgYXJnbCk7Ci0JICB9Ci0gICAgICAgICAgZWxzZSBpZiAocGFyc2VyLmdldFFOYW1lSWdub3JlRGVmYXVsdE5zKCJsb2NhbC1uYW1lIikuZXF1YWxzKGZuYW1lKSkgewotICAgICAgICAgICAgUkVTVUxUID0gbmV3IExvY2FsTmFtZUNhbGwoZm5hbWUsIGFyZ2wpOwotCSAgfQotICAgICAgICAgIGVsc2UgaWYgKHBhcnNlci5nZXRRTmFtZUlnbm9yZURlZmF1bHROcygibGFuZyIpLmVxdWFscyhmbmFtZSkpIHsKLSAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBMYW5nQ2FsbChmbmFtZSwgYXJnbCk7Ci0JICB9Ci0gICAgICAgICAgZWxzZSBpZiAocGFyc2VyLmdldFFOYW1lSWdub3JlRGVmYXVsdE5zKCJuYW1lc3BhY2UtdXJpIikuZXF1YWxzKGZuYW1lKSkgewotICAgICAgICAgICAgUkVTVUxUID0gbmV3IE5hbWVzcGFjZVVyaUNhbGwoZm5hbWUsIGFyZ2wpOwotCSAgfQotICAgICAgICAgIGVsc2UgaWYgKHBhcnNlci5nZXRRTmFtZShDb25zdGFudHMuVFJBTlNMRVRfVVJJLCAieHNsdGMiLCAiY2FzdCIpLmVxdWFscyhmbmFtZSkpIHsKLSAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBDYXN0Q2FsbChmbmFtZSwgYXJnbCk7Ci0JICB9Ci0JICAvLyBTcGVjaWFsIGNhc2UgZm9yIGV4dGVuc2lvbiBmdW5jdGlvbiBub2Rlc2V0KCkKLSAgICAgICAgICBlbHNlIGlmIChmbmFtZS5nZXRMb2NhbFBhcnQoKS5lcXVhbHMoIm5vZGVzZXQiKSB8fCBmbmFtZS5nZXRMb2NhbFBhcnQoKS5lcXVhbHMoIm5vZGUtc2V0IikpIHsKLQkgICAgcGFyc2VyLnNldENhbGxzTm9kZXNldCh0cnVlKTsgIC8vIGltcGxpZXMgTXVsdGlET00KLSAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBGdW5jdGlvbkNhbGwoZm5hbWUsIGFyZ2wpOwotCSAgfQotICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgUkVTVUxUID0gbmV3IEZ1bmN0aW9uQ2FsbChmbmFtZSwgYXJnbCk7Ci0JICB9Ci0gICAgOn07Ci0KLU5vbmVtcHR5QXJndW1lbnRMaXN0IDo6PSBBcmd1bWVudDphcmcKLSAgICAgICAgezoKLSAgICAgICAgICAgIFZlY3RvciB0ZW1wID0gbmV3IFZlY3RvcigpOwotICAgICAgICAgICAgdGVtcC5hZGRFbGVtZW50KGFyZyk7Ci0gICAgICAgICAgICBSRVNVTFQgPSB0ZW1wOwotICAgICAgICA6fQotCi0gICAgICAgIHwgQXJndW1lbnQ6YXJnIENPTU1BIE5vbmVtcHR5QXJndW1lbnRMaXN0OmFyZ2wKLSAgICAgICAgezogYXJnbC5pbnNlcnRFbGVtZW50QXQoYXJnLCAwKTsgUkVTVUxUID0gYXJnbDsgOn07Ci0KLUZ1bmN0aW9uTmFtZSA6Oj0gUU5hbWU6Zm5hbWUKLSAgICAgICAgezoKLQkgICAgUkVTVUxUID0gZm5hbWU7Ci0JOn07Ci0KLVZhcmlhYmxlTmFtZSA6Oj0gUU5hbWU6dm5hbWUKLSAgICAgICAgezoKLQkgICAgUkVTVUxUID0gdm5hbWU7Ci0JOn07Ci0KLUFyZ3VtZW50IDo6PSBFeHByOmV4Ci0gICAgICAgIHs6IFJFU1VMVCA9IGV4OyA6fTsKLQotTm9kZVRlc3QgOjo9IE5hbWVUZXN0Om50Ci0gICAgICAgIHs6IFJFU1VMVCA9IG50OyA6fQotCi0gICAgICAgIHwgTk9ERQotICAgICAgICB7OiBSRVNVTFQgPSBuZXcgSW50ZWdlcihOb2RlVGVzdC5BTk9ERSk7IDp9Ci0KLSAgICAgICAgfCBURVhUCi0gICAgICAgIHs6IFJFU1VMVCA9IG5ldyBJbnRlZ2VyKE5vZGVUZXN0LlRFWFQpOyA6fQotCi0gICAgICAgIHwgQ09NTUVOVAotICAgICAgICB7OiBSRVNVTFQgPSBuZXcgSW50ZWdlcihOb2RlVGVzdC5DT01NRU5UKTsgOn0KLQotICAgICAgICB8IFBJUEFSQU0gTFBBUkVOIExpdGVyYWw6bCBSUEFSRU4KLSAgICAgICAgezoKLSAgICAgICAgICAgUU5hbWUgbmFtZSA9IHBhcnNlci5nZXRRTmFtZUlnbm9yZURlZmF1bHROcygibmFtZSIpOwotICAgICAgICAgICBFeHByZXNzaW9uIGV4cCA9IG5ldyBFcXVhbGl0eUV4cHIoT3BlcmF0b3JzLkVRLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE5hbWVDYWxsKG5hbWUpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IExpdGVyYWxFeHByKGwpKTsKLSAgICAgICAgICAgVmVjdG9yIHByZWRpY2F0ZXMgPSBuZXcgVmVjdG9yKCk7Ci0gICAgICAgICAgIHByZWRpY2F0ZXMuYWRkRWxlbWVudChuZXcgUHJlZGljYXRlKGV4cCkpOwotICAgICAgICAgICBSRVNVTFQgPSBuZXcgU3RlcChBeGlzLkNISUxELCBOb2RlVGVzdC5QSSwgcHJlZGljYXRlcyk7Ci0gICAgICAgIDp9Ci0KLSAgICAgICAgfCBQSQotICAgICAgICB7OiBSRVNVTFQgPSBuZXcgSW50ZWdlcihOb2RlVGVzdC5QSSk7IDp9OwotCi1OYW1lVGVzdCA6Oj0gU1RBUgotICAgICAgICAgICAgIHs6IFJFU1VMVCA9IG51bGw7IDp9Ci0KLSAgICAgICAgICAgICB8IFFOYW1lOnFuCi0gICAgICAgICAgICAgezogUkVTVUxUID0gcW47IDp9OwotCi1RTmFtZSA6Oj0gUU5BTUU6cW5hbWUKLSAgICAgICAgezogUkVTVUxUID0gcGFyc2VyLmdldFFOYW1lSWdub3JlRGVmYXVsdE5zKHFuYW1lKTsgOn0KLQotCXwgRElWCi0gICAgICAgIHs6IFJFU1VMVCA9IHBhcnNlci5nZXRRTmFtZUlnbm9yZURlZmF1bHROcygiZGl2Iik7IDp9Ci0KLSAgICAgICAgfCBNT0QKLSAgICAgICAgezogUkVTVUxUID0gcGFyc2VyLmdldFFOYW1lSWdub3JlRGVmYXVsdE5zKCJtb2QiKTsgOn0KLQotICAgICAgICB8IEtFWQotICAgICAgICB7OiBSRVNVTFQgPSBwYXJzZXIuZ2V0UU5hbWVJZ25vcmVEZWZhdWx0TnMoImtleSIpOyA6fQotCi0gICAgICAgIHwgQU5DRVNUT1IKLSAgICAgICAgezogUkVTVUxUID0gcGFyc2VyLmdldFFOYW1lSWdub3JlRGVmYXVsdE5zKCJjaGlsZCIpOyA6fQotCi0gICAgICAgIHwgQU5DRVNUT1JPUlNFTEYKLSAgICAgICAgezogUkVTVUxUID0gcGFyc2VyLmdldFFOYW1lSWdub3JlRGVmYXVsdE5zKCJhbmNlc3Rvci1vci1zZWxmIik7IDp9Ci0KLSAgICAgICAgfCBBVFRSSUJVVEUKLSAgICAgICAgezogUkVTVUxUID0gcGFyc2VyLmdldFFOYW1lSWdub3JlRGVmYXVsdE5zKCJhdHRyaWJ1dGUiKTsgOn0KLQotICAgICAgICB8IENISUxECi0gICAgICAgIHs6IFJFU1VMVCA9IHBhcnNlci5nZXRRTmFtZUlnbm9yZURlZmF1bHROcygiY2hpbGQiKTsgOn0KLQotICAgICAgICB8IERFU0NFTkRBTlQKLSAgICAgICAgezogUkVTVUxUID0gcGFyc2VyLmdldFFOYW1lSWdub3JlRGVmYXVsdE5zKCJkZWNlbmRhbnQiKTsgOn0KLQotICAgICAgICB8IERFU0NFTkRBTlRPUlNFTEYKLSAgICAgICAgezogUkVTVUxUID0gcGFyc2VyLmdldFFOYW1lSWdub3JlRGVmYXVsdE5zKCJkZWNlbmRhbnQtb3Itc2VsZiIpOyA6fQotCi0gICAgICAgIHwgRk9MTE9XSU5HCi0gICAgICAgIHs6IFJFU1VMVCA9IHBhcnNlci5nZXRRTmFtZUlnbm9yZURlZmF1bHROcygiZm9sbG93aW5nIik7IDp9Ci0KLSAgICAgICAgfCBGT0xMT1dJTkdTSUJMSU5HCi0gICAgICAgIHs6IFJFU1VMVCA9IHBhcnNlci5nZXRRTmFtZUlnbm9yZURlZmF1bHROcygiZm9sbG93aW5nLXNpYmxpbmciKTsgOn0KLQotICAgICAgICB8IE5BTUVTUEFDRQotICAgICAgICB7OiBSRVNVTFQgPSBwYXJzZXIuZ2V0UU5hbWVJZ25vcmVEZWZhdWx0TnMoIm5hbWVzcGFjZSIpOyA6fQotCi0gICAgICAgIHwgUEFSRU5UCi0gICAgICAgIHs6IFJFU1VMVCA9IHBhcnNlci5nZXRRTmFtZUlnbm9yZURlZmF1bHROcygicGFyZW50Iik7IDp9Ci0KLSAgICAgICAgfCBQUkVDRURJTkcKLSAgICAgICAgezogUkVTVUxUID0gcGFyc2VyLmdldFFOYW1lSWdub3JlRGVmYXVsdE5zKCJwcmVjZWRpbmciKTsgOn0KLQotICAgICAgICB8IFBSRUNFRElOR1NJQkxJTkcKLSAgICAgICAgezogUkVTVUxUID0gcGFyc2VyLmdldFFOYW1lSWdub3JlRGVmYXVsdE5zKCJwcmVjZWRpbmctc2libGluZyIpOyA6fQotCi0gICAgICAgIHwgU0VMRgotICAgICAgICB7OiBSRVNVTFQgPSBwYXJzZXIuZ2V0UU5hbWVJZ25vcmVEZWZhdWx0TnMoInNlbGYiKTsgOn0KLQotICAgICAgICB8IElECi0gICAgICAgIHs6IFJFU1VMVCA9IHBhcnNlci5nZXRRTmFtZUlnbm9yZURlZmF1bHROcygiaWQiKTsgOn07Ci0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIveHBhdGgubGV4IGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci94cGF0aC5sZXgKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGYxMDEzZjMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci94cGF0aC5sZXgKKysrIC9kZXYvbnVsbApAQCAtMSwyNjAgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogeHBhdGgubGV4LHYgMS4xMiAyMDA1LzA4LzAyIDAyOjU5OjAzIG1jbmFtYXJhIEV4cCAkCi0gKi8KLQotLyoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICoKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS5TeW1ib2w7Ci0lJQotJWN1cAotJXVuaWNvZGUKLSVjbGFzcyBYUGF0aExleGVyCi0leXllb2YKLQotJXsKLSAgICAgICAgaW50IGxhc3Q7Ci0KLSAgICAgICAgdm9pZCBpbml0aWFsaXplKCkgewotICAgICAgICAgICAgbGFzdCA9IC0xOwotICAgICAgICB9Ci0KLSAgICAgICAgc3RhdGljIGJvb2xlYW4gaXNXaGl0ZXNwYWNlKGludCBjKSB7Ci0gICAgICAgICAgICByZXR1cm4gKGMgPT0gJyAnIHx8IGMgPT0gJ1x0JyB8fCBjID09ICdccicgfHwgYyA9PSAnXG4nICB8fCBjID09ICdcZicpOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIElmIHN5bWJvbCBpcyBub3QgZm9sbG93ZWQgYnkgJzo6JyBvciAnKCcsIHRoZW4gdHJlYXQgaXQgYXMgYQotICAgICAgICAgKiBuYW1lIGluc3RlYWQgb2YgYW4gYXhpcyBvciBmdW5jdGlvbiAoSmlyYS0xOTEyKS4KLSAgICAgICAgICovCi0gICAgICAgIFN5bWJvbCBkaXNhbWJpZ3VhdGVBeGlzT3JGdW5jdGlvbihpbnQgc3MpIHRocm93cyBFeGNlcHRpb24gewotICAgICAgICAgICAgLy8gUGVlayBpbiB0aGUgaW5wdXQgYnVmZmVyIHdpdGhvdXQgY2hhbmdpbmcgdGhlIGludGVybmFsIHN0YXRlCi0gICAgICAgICAgICBpbnQgaW5kZXggPSB5eV9idWZmZXJfaW5kZXg7Ci0KLSAgICAgICAgICAgIC8vIFNraXAgd2hpdGVzcGFjZQotICAgICAgICAgICAgd2hpbGUgKGluZGV4IDwgeXlfYnVmZmVyX3JlYWQgJiYgaXNXaGl0ZXNwYWNlKHl5X2J1ZmZlcltpbmRleF0pKSB7Ci0gICAgICAgICAgICAgICAgaW5kZXgrKzsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gSWYgZW5kIG9mIGJ1ZmZlciwgY2FuJ3QgZGlzYW1iaWd1YXRlIDooCi0gICAgICAgICAgICBpZiAoaW5kZXggPj0geXlfYnVmZmVyX3JlYWQpIHsKLSAgICAgICAgICAgICAgICAvLyBDYW4ndCBkaXNhbWJpZ3VhdGUsIHNvIHJldHVybiBhcyBzeW1ib2wKLSAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFN5bWJvbChzcyk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIFJldHVybiBzeW1ib2wgaWYgbmV4dCB0b2tlbiBpcyAnOjonIG9yICcoJwotICAgICAgICAgICAgcmV0dXJuICh5eV9idWZmZXJbaW5kZXhdID09ICc6JyAmJiB5eV9idWZmZXJbaW5kZXgrMV0gPT0gJzonIHx8Ci0gICAgICAgICAgICAgICAgICAgIHl5X2J1ZmZlcltpbmRleF0gPT0gJygnKSA/Ci0gICAgICAgICAgICAgICAgICAgIG5ld1N5bWJvbChzcykgOiBuZXdTeW1ib2woc3ltLlFOQU1FLCB5eXRleHQoKSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogSWYgc3ltYm9sIGlzIGZpcnN0IHRva2VuIG9yIGlmIGl0IGZvbGxvd3MgYW55IG9mIHRoZSBvcGVyYXRvcnMKLSAgICAgICAgICogbGlzdGVkIGluIGh0dHA6Ly93d3cudzMub3JnL1RSL3hwYXRoI2V4cHJsZXggdGhlbiB0cmVhdCBhcyBhCi0gICAgICAgICAqIG5hbWUgaW5zdGVhZCBvZiBhIGtleXdvcmQgKEppcmEtMTkxMikuCi0gICAgICAgICAqLwotICAgICAgICBTeW1ib2wgZGlzYW1iaWd1YXRlT3BlcmF0b3IoaW50IHNzKSB0aHJvd3MgRXhjZXB0aW9uIHsKLSAgICAgICAgICAgIHN3aXRjaCAobGFzdCkgewotICAgICAgICAgICAgY2FzZSAtMTogICAgLy8gZmlyc3QgdG9rZW4KLSAgICAgICAgICAgIGNhc2Ugc3ltLkFUU0lHTjoKLSAgICAgICAgICAgIGNhc2Ugc3ltLkRDT0xPTjoKLSAgICAgICAgICAgIGNhc2Ugc3ltLkxQQVJFTjoKLSAgICAgICAgICAgIGNhc2Ugc3ltLkxCUkFDSzoKLSAgICAgICAgICAgIGNhc2Ugc3ltLkNPTU1BOgotICAgICAgICAgICAgY2FzZSBzeW0uQU5EOgotICAgICAgICAgICAgY2FzZSBzeW0uT1I6Ci0gICAgICAgICAgICBjYXNlIHN5bS5NT0Q6Ci0gICAgICAgICAgICBjYXNlIHN5bS5ESVY6Ci0gICAgICAgICAgICBjYXNlIHN5bS5NVUxUOgotICAgICAgICAgICAgY2FzZSBzeW0uU0xBU0g6Ci0gICAgICAgICAgICBjYXNlIHN5bS5EU0xBU0g6Ci0gICAgICAgICAgICBjYXNlIHN5bS5WQkFSOgotICAgICAgICAgICAgY2FzZSBzeW0uUExVUzoKLSAgICAgICAgICAgIGNhc2Ugc3ltLk1JTlVTOgotICAgICAgICAgICAgY2FzZSBzeW0uRVE6Ci0gICAgICAgICAgICBjYXNlIHN5bS5ORToKLSAgICAgICAgICAgIGNhc2Ugc3ltLkxUOgotICAgICAgICAgICAgY2FzZSBzeW0uTEU6Ci0gICAgICAgICAgICBjYXNlIHN5bS5HVDoKLSAgICAgICAgICAgIGNhc2Ugc3ltLkdFOgotICAgICAgICAgICAgICAgIHJldHVybiBuZXdTeW1ib2woc3ltLlFOQU1FLCB5eXRleHQoKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gbmV3U3ltYm9sKHNzKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBJZiBzeW1ib2wgaXMgZmlyc3QgdG9rZW4gb3IgaWYgaXQgZm9sbG93cyBhbnkgb2YgdGhlIG9wZXJhdG9ycwotICAgICAgICAgKiBsaXN0ZWQgaW4gaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGgjZXhwcmxleCB0aGVuIHRyZWF0IGFzIGEKLSAgICAgICAgICogd2lsZGNhcmQgaW5zdGVhZCBvZiBhIG11bHRpcGxpY2F0aW9uIG9wZXJhdG9yCi0gICAgICAgICAqLwotICAgICAgICBTeW1ib2wgZGlzYW1iaWd1YXRlU3RhcigpIHRocm93cyBFeGNlcHRpb24gewotICAgICAgICAgICAgc3dpdGNoIChsYXN0KSB7Ci0gICAgICAgICAgICBjYXNlIC0xOiAgICAvLyBmaXJzdCB0b2tlbgotICAgICAgICAgICAgY2FzZSBzeW0uQVRTSUdOOgotICAgICAgICAgICAgY2FzZSBzeW0uRENPTE9OOgotICAgICAgICAgICAgY2FzZSBzeW0uTFBBUkVOOgotICAgICAgICAgICAgY2FzZSBzeW0uTEJSQUNLOgotICAgICAgICAgICAgY2FzZSBzeW0uQ09NTUE6Ci0gICAgICAgICAgICBjYXNlIHN5bS5BTkQ6Ci0gICAgICAgICAgICBjYXNlIHN5bS5PUjoKLSAgICAgICAgICAgIGNhc2Ugc3ltLk1PRDoKLSAgICAgICAgICAgIGNhc2Ugc3ltLkRJVjoKLSAgICAgICAgICAgIGNhc2Ugc3ltLk1VTFQ6Ci0gICAgICAgICAgICBjYXNlIHN5bS5TTEFTSDoKLSAgICAgICAgICAgIGNhc2Ugc3ltLkRTTEFTSDoKLSAgICAgICAgICAgIGNhc2Ugc3ltLlZCQVI6Ci0gICAgICAgICAgICBjYXNlIHN5bS5QTFVTOgotICAgICAgICAgICAgY2FzZSBzeW0uTUlOVVM6Ci0gICAgICAgICAgICBjYXNlIHN5bS5FUToKLSAgICAgICAgICAgIGNhc2Ugc3ltLk5FOgotICAgICAgICAgICAgY2FzZSBzeW0uTFQ6Ci0gICAgICAgICAgICBjYXNlIHN5bS5MRToKLSAgICAgICAgICAgIGNhc2Ugc3ltLkdUOgotICAgICAgICAgICAgY2FzZSBzeW0uR0U6Ci0gICAgICAgICAgICAgICAgcmV0dXJuIG5ld1N5bWJvbChzeW0uU1RBUik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gbmV3U3ltYm9sKHN5bS5NVUxUKTsKLSAgICAgICAgfQotCi0gICAgICAgIFN5bWJvbCBuZXdTeW1ib2woaW50IHNzKSB7Ci0gICAgICAgICAgICBsYXN0ID0gc3M7Ci0gICAgICAgICAgICByZXR1cm4gbmV3IFN5bWJvbChzcyk7Ci0gICAgICAgIH0KLQotICAgICAgICBTeW1ib2wgbmV3U3ltYm9sKGludCBzcywgU3RyaW5nIHZhbHVlKSB7Ci0gICAgICAgICAgICBsYXN0ID0gc3M7Ci0gICAgICAgICAgICByZXR1cm4gbmV3IFN5bWJvbChzcywgdmFsdWUpOwotICAgICAgICB9Ci0KLSAgICAgICAgU3ltYm9sIG5ld1N5bWJvbChpbnQgc3MsIExvbmcgdmFsdWUpIHsKLSAgICAgICAgICAgIGxhc3QgPSBzczsKLSAgICAgICAgICAgIHJldHVybiBuZXcgU3ltYm9sKHNzLCB2YWx1ZSk7Ci0gICAgICAgIH0KLQotICAgICAgICBTeW1ib2wgbmV3U3ltYm9sKGludCBzcywgRG91YmxlIHZhbHVlKSB7Ci0gICAgICAgICAgICBsYXN0ID0gc3M7Ci0gICAgICAgICAgICByZXR1cm4gbmV3IFN5bWJvbChzcywgdmFsdWUpOwotICAgICAgICB9Ci0lfQotCi0lZW9mdmFsewotcmV0dXJuIG5ld1N5bWJvbChzeW0uRU9GKTsKLSVlb2Z2YWx9Ci0KLSV5eWxleHRocm93ewotRXhjZXB0aW9uCi0leXlsZXh0aHJvd30KLQotTGV0dGVyPXtCYXNlQ2hhcn18e0lkZW9ncmFwaGljfQotCi1CYXNlQ2hhcj1bXHUwMDQxLVx1MDA1QVx1MDA2MS1cdTAwN0FcdTAwQzAtXHUwMEQ2XHUwMEQ4LVx1MDBGNlx1MDBGOC1cdTAwRkZcdTAxMDAtXHUwMTMxXHUwMTM0LVx1MDEzRVx1MDE0MS1cdTAxNDhcdTAxNEEtXHUwMTdFXHUwMTgwLVx1MDFDM1x1MDFDRC1cdTAxRjBcdTAxRjQtXHUwMUY1XHUwMUZBLVx1MDIxN1x1MDI1MC1cdTAyQThcdTAyQkItXHUwMkMxXHUwMzg2XHUwMzg4LVx1MDM4QVx1MDM4Q1x1MDM4RS1cdTAzQTFcdTAzQTMtXHUwM0NFXHUwM0QwLVx1MDNENlx1MDNEQVx1MDNEQ1x1MDNERVx1MDNFMFx1MDNFMi1cdTAzRjNcdTA0MDEtXHUwNDBDXHUwNDBFLVx1MDQ0Rlx1MDQ1MS1cdTA0NUNcdTA0NUUtXHUwNDgxXHUwNDkwLVx1MDRDNFx1MDRDNy1cdTA0QzhcdTA0Q0ItXHUwNENDXHUwNEQwLVx1MDRFQlx1MDRFRS1cdTA0RjVcdTA0RjgtXHUwNEY5XHUwNTMxLVx1MDU1Nlx1MDU1OVx1MDU2MS1cdTA1ODZcdTA1RDAtXHUwNUVBXHUwNUYwLVx1MDVGMlx1MDYyMS1cdTA2M0FcdTA2NDEtXHUwNjRBXHUwNjcxLVx1MDZCN1x1MDZCQS1cdTA2QkVcdTA2QzAtXHUwNkNFXHUwNkQwLVx1MDZEM1x1MDZENVx1MDZFNS1cdTA2RTZcdTA5MDUtXHUwOTM5XHUwOTNEXHUwOTU4LVx1MDk2MVx1MDk4NS1cdTA5OENcdTA5OEYtXHUwOTkwXHUwOTkzLVx1MDlBOFx1MDlBQS1cdTA5QjBcdTA5QjJcdTA5QjYtXHUwOUI5XHUwOURDLVx1MDlERFx1MDlERi1cdTA5RTFcdTA5RjAtXHUwOUYxXHUwQTA1LVx1MEEwQVx1MEEwRi1cdTBBMTBcdTBBMTMtXHUwQTI4XHUwQTJBLVx1MEEzMFx1MEEzMi1cdTBBMzNcdTBBMzUtXHUwQTM2XHUwQTM4LVx1MEEzOVx1MEE1OS1cdTBBNUNcdTBBNUVcdTBBNzItXHUwQTc0XHUwQTg1LVx1MEE4Qlx1MEE4RFx1MEE4Ri1cdTBBOTFcdTBBOTMtXHUwQUE4XHUwQUFBLVx1MEFCMFx1MEFCMi1cdTBBQjNcdTBBQjUtXHUwQUI5XHUwQUJEXHUwQUUwXHUwQjA1LVx1MEIwQ1x1MEIwRi1cdTBCMTBcdTBCMTMtXHUwQjI4XHUwQjJBLVx1MEIzMFx1MEIzMi1cdTBCMzNcdTBCMzYtXHUwQjM5XHUwQjNEXHUwQjVDLVx1MEI1RFx1MEI1Ri1cdTBCNjFcdTBCODUtXHUwQjhBXHUwQjhFLVx1MEI5MFx1MEI5Mi1cdTBCOTVcdTBCOTktXHUwQjlBXHUwQjlDXHUwQjlFLVx1MEI5Rlx1MEJBMy1cdTBCQTRcdTBCQTgtXHUwQkFBXHUwQkFFLVx1MEJCNVx1MEJCNy1cdTBCQjlcdTBDMDUtXHUwQzBDXHUwQzBFLVx1MEMxMFx1MEMxMi1cdTBDMjhcdTBDMkEtXHUwQzMzXHUwQzM1LVx1MEMzOVx1MEM2MC1cdTBDNjFcdTBDODUtXHUwQzhDXHUwQzhFLVx1MEM5MFx1MEM5Mi1cdTBDQThcdTBDQUEtXHUwQ0IzXHUwQ0I1LVx1MENCOVx1MENERVx1MENFMC1cdTBDRTFcdTBEMDUtXHUwRDBDXHUwRDBFLVx1MEQxMFx1MEQxMi1cdTBEMjhcdTBEMkEtXHUwRDM5XHUwRDYwLVx1MEQ2MVx1MEUwMS1cdTBFMkVcdTBFMzBcdTBFMzItXHUwRTMzXHUwRTQwLVx1MEU0NVx1MEU4MS1cdTBFODJcdTBFODRcdTBFODctXHUwRTg4XHUwRThBXHUwRThEXHUwRTk0LVx1MEU5N1x1MEU5OS1cdTBFOUZcdTBFQTEtXHUwRUEzXHUwRUE1XHUwRUE3XHUwRUFBLVx1MEVBQlx1MEVBRC1cdTBFQUVcdTBFQjBcdTBFQjItXHUwRUIzXHUwRUJEXHUwRUMwLVx1MEVDNFx1MEY0MC1cdTBGNDdcdTBGNDktXHUwRjY5XHUxMEEwLVx1MTBDNVx1MTBEMC1cdTEwRjZcdTExMDBcdTExMDItXHUxMTAzXHUxMTA1LVx1MTEwN1x1MTEwOVx1MTEwQi1cdTExMENcdTExMEUtXHUxMTEyXHUxMTNDXHUxMTNFXHUxMTQwXHUxMTRDXHUxMTRFXHUxMTUwXHUxMTU0LVx1MTE1NVx1MTE1OVx1MTE1Ri1cdTExNjFcdTExNjNcdTExNjVcdTExNjdcdTExNjlcdTExNkQtXHUxMTZFXHUxMTcyLVx1MTE3M1x1MTE3NVx1MTE5RVx1MTFBOFx1MTFBQlx1MTFBRS1cdTExQUZcdTExQjctXHUxMUI4XHUxMUJBXHUxMUJDLVx1MTFDMlx1MTFFQlx1MTFGMFx1MTFGOVx1MUUwMC1cdTFFOUJcdTFFQTAtXHUxRUY5XHUxRjAwLVx1MUYxNVx1MUYxOC1cdTFGMURcdTFGMjAtXHUxRjQ1XHUxRjQ4LVx1MUY0RFx1MUY1MC1cdTFGNTdcdTFGNTlcdTFGNUJcdTFGNURcdTFGNUYtXHUxRjdEXHUxRjgwLVx1MUZCNFx1MUZCNi1cdTFGQkNcdTFGQkVcdTFGQzItXHUxRkM0XHUxRkM2LVx1MUZDQ1x1MUZEMC1cdTFGRDNcdTFGRDYtXHUxRkRCXHUxRkUwLVx1MUZFQ1x1MUZGMi1cdTFGRjRcdTFGRjYtXHUxRkZDXHUyMTI2XHUyMTJBLVx1MjEyQlx1MjEyRVx1MjE4MC1cdTIxODJcdTMwNDEtXHUzMDk0XHUzMEExLVx1MzBGQVx1MzEwNS1cdTMxMkNcdUFDMDAtXHVEN0EzXQotCi1JZGVvZ3JhcGhpYz1bXHU0RTAwLVx1OUZBNVx1MzAwN1x1MzAyMS1cdTMwMjldCi0KLUNvbWJpbmluZ0NoYXI9W1x1MDMwMC1cdTAzNDVcdTAzNjAtXHUwMzYxXHUwNDgzLVx1MDQ4Nlx1MDU5MS1cdTA1QTFcdTA1QTMtXHUwNUI5XHUwNUJCLVx1MDVCRFx1MDVCRlx1MDVDMS1cdTA1QzJcdTA1QzRcdTA2NEItXHUwNjUyXHUwNjcwXHUwNkQ2LVx1MDZEQ1x1MDZERC1cdTA2REZcdTA2RTAtXHUwNkU0XHUwNkU3LVx1MDZFOFx1MDZFQS1cdTA2RURcdTA5MDEtXHUwOTAzXHUwOTNDXHUwOTNFLVx1MDk0Q1x1MDk0RFx1MDk1MS1cdTA5NTRcdTA5NjItXHUwOTYzXHUwOTgxLVx1MDk4M1x1MDlCQ1x1MDlCRVx1MDlCRlx1MDlDMC1cdTA5QzRcdTA5QzctXHUwOUM4XHUwOUNCLVx1MDlDRFx1MDlEN1x1MDlFMi1cdTA5RTNcdTBBMDJcdTBBM0NcdTBBM0VcdTBBM0ZcdTBBNDAtXHUwQTQyXHUwQTQ3LVx1MEE0OFx1MEE0Qi1cdTBBNERcdTBBNzAtXHUwQTcxXHUwQTgxLVx1MEE4M1x1MEFCQ1x1MEFCRS1cdTBBQzVcdTBBQzctXHUwQUM5XHUwQUNCLVx1MEFDRFx1MEIwMS1cdTBCMDNcdTBCM0NcdTBCM0UtXHUwQjQzXHUwQjQ3LVx1MEI0OFx1MEI0Qi1cdTBCNERcdTBCNTYtXHUwQjU3XHUwQjgyLVx1MEI4M1x1MEJCRS1cdTBCQzJcdTBCQzYtXHUwQkM4XHUwQkNBLVx1MEJDRFx1MEJEN1x1MEMwMS1cdTBDMDNcdTBDM0UtXHUwQzQ0XHUwQzQ2LVx1MEM0OFx1MEM0QS1cdTBDNERcdTBDNTUtXHUwQzU2XHUwQzgyLVx1MEM4M1x1MENCRS1cdTBDQzRcdTBDQzYtXHUwQ0M4XHUwQ0NBLVx1MENDRFx1MENENS1cdTBDRDZcdTBEMDItXHUwRDAzXHUwRDNFLVx1MEQ0M1x1MEQ0Ni1cdTBENDhcdTBENEEtXHUwRDREXHUwRDU3XHUwRTMxXHUwRTM0LVx1MEUzQVx1MEU0Ny1cdTBFNEVcdTBFQjFcdTBFQjQtXHUwRUI5XHUwRUJCLVx1MEVCQ1x1MEVDOC1cdTBFQ0RcdTBGMTgtXHUwRjE5XHUwRjM1XHUwRjM3XHUwRjM5XHUwRjNFXHUwRjNGXHUwRjcxLVx1MEY4NFx1MEY4Ni1cdTBGOEJcdTBGOTAtXHUwRjk1XHUwRjk3XHUwRjk5LVx1MEZBRFx1MEZCMS1cdTBGQjdcdTBGQjlcdTIwRDAtXHUyMERDXHUyMEUxXHUzMDJBLVx1MzAyRlx1MzA5OVx1MzA5QV0KLQotRGlnaXQ9W1x1MDAzMC1cdTAwMzlcdTA2NjAtXHUwNjY5XHUwNkYwLVx1MDZGOVx1MDk2Ni1cdTA5NkZcdTA5RTYtXHUwOUVGXHUwQTY2LVx1MEE2Rlx1MEFFNi1cdTBBRUZcdTBCNjYtXHUwQjZGXHUwQkU3LVx1MEJFRlx1MEM2Ni1cdTBDNkZcdTBDRTYtXHUwQ0VGXHUwRDY2LVx1MEQ2Rlx1MEU1MC1cdTBFNTlcdTBFRDAtXHUwRUQ5XHUwRjIwLVx1MEYyOV0KLQotRXh0ZW5kZXI9W1x1MDBCN1x1MDJEMFx1MDJEMVx1MDM4N1x1MDY0MFx1MEU0Nlx1MEVDNlx1MzAwNVx1MzAzMS1cdTMwMzVcdTMwOUQtXHUzMDlFXHUzMEZDLVx1MzBGRV0KLQotTkNOYW1lPSh7TGV0dGVyfXwiXyJ8e05DTmFtZVN0YXJ0Q2hhcn0pKHtOQ05hbWVDaGFyfSkqCi0KLU5DTmFtZUNoYXI9e0xldHRlcn18e0RpZ2l0fXwiLiJ8Ii0ifCJfInx7Q29tYmluaW5nQ2hhcn18e0V4dGVuZGVyfXx7TkNOYW1lU3RhcnRDaGFyfXwgXHUwMEI3IHwgW1x1MDMwMC1cdTAzNkZdIHwgW1x1MjAzRi1cdTIwNDBdIHwgW1x1MDEzMC1cdTAxMzZdCi0KLU5DTmFtZVN0YXJ0Q2hhcj1bXHUwMDQxLVx1MDA1QVx1MDA2MS1cdTAwN0FcdTAwQzAtXHUwMEQ2XHUwMEQ4LVx1MDBGNlx1MDBGOC1cdTAyRkZcdTAzNzAtXHUwMzdEXHUwMzdGLVx1MUZGRlx1MjAwQy1cdTIwMERcdTIwNzAtXHUyMThGXHUyQzAwLVx1MkZFRlx1MzAwMS1cdUQ3RkZcdUY5MDAtXHVGRENGXHVGREYwLVx1RkZGRF0gfCBcdTAwNUYgfCh7SGlnaFN1cnJvZ2F0ZX17TG93U3Vycm9nYXRlfSkKLQotSGlnaFN1cnJvZ2F0ZT1bXHVEODAwLVx1REJGRl0KLQotTG93U3Vycm9nYXRlPVtcdURDMDAtXHVERkZGXQotCi0lJQotCi0iKiIgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gZGlzYW1iaWd1YXRlU3RhcigpOyB9Ci0iLyIgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5TTEFTSCk7IH0KLSIrIiAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLlBMVVMpOyB9Ci0iLSIgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5NSU5VUyk7IH0KLSJkaXYiICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBkaXNhbWJpZ3VhdGVPcGVyYXRvcihzeW0uRElWKTsgfQotIm1vZCIgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIGRpc2FtYmlndWF0ZU9wZXJhdG9yKHN5bS5NT0QpOyB9Ci0iOjoiICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5EQ09MT04pOyB9Ci0iLCIgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5DT01NQSk7IH0KLSJAIiAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLkFUU0lHTik7IH0KLSIuLiIgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLkRET1QpOyB9Ci0ifCIgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5WQkFSKTsgfQotIiQiICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uRE9MTEFSKTsgfQotIi8vIiAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uRFNMQVNIKTsgfQotIj0iICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uRVEpOyB9Ci0iIT0iICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5ORSk7IH0KLSI8IiAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLkxUKTsgfQotIj4iICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uR1QpOyB9Ci0iPD0iICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5MRSk7IH0KLSI+PSIgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLkdFKTsgfQotImlkIiAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIGRpc2FtYmlndWF0ZUF4aXNPckZ1bmN0aW9uKHN5bS5JRCk7IH0KLSJrZXkiICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBkaXNhbWJpZ3VhdGVBeGlzT3JGdW5jdGlvbihzeW0uS0VZKTsgfQotInRleHQoKSIgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uVEVYVCk7IH0KLSJ0ZXh0IitbIFx0XHJcblxmXSsiKCkiICB7IHJldHVybiBuZXdTeW1ib2woc3ltLlRFWFQpOyB9Ci0ibm9kZSgpIiAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5OT0RFKTsgfQotIm5vZGUiK1sgXHRcclxuXGZdKyIoKSIgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uTk9ERSk7IH0KLSJjb21tZW50KCkiICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXdTeW1ib2woc3ltLkNPTU1FTlQpOyB9Ci0iY29tbWVudCIrWyBcdFxyXG5cZl0rIigpIiAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5DT01NRU5UKTsgfQotInByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24iIHsgcmV0dXJuIGRpc2FtYmlndWF0ZUF4aXNPckZ1bmN0aW9uKHN5bS5QSVBBUkFNKTsgfQotInByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24oKSIgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5QSSk7IH0KLSJwcm9jZXNzaW5nLWluc3RydWN0aW9uIitbIFx0XHJcblxmXSsiKCkiIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uUEkpOyB9Ci0ib3IiICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gZGlzYW1iaWd1YXRlT3BlcmF0b3Ioc3ltLk9SKTsgfQotImFuZCIgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIGRpc2FtYmlndWF0ZU9wZXJhdG9yKHN5bS5BTkQpOyB9Ci0iY2hpbGQiICAgICAgICAgICAgICAgICAgeyByZXR1cm4gZGlzYW1iaWd1YXRlQXhpc09yRnVuY3Rpb24oc3ltLkNISUxEKTsgfQotImF0dHJpYnV0ZSIgICAgICAgICAgICAgIHsgcmV0dXJuIGRpc2FtYmlndWF0ZUF4aXNPckZ1bmN0aW9uKHN5bS5BVFRSSUJVVEUpOyB9Ci0iYW5jZXN0b3IiICAgICAgICAgICAgICAgeyByZXR1cm4gZGlzYW1iaWd1YXRlQXhpc09yRnVuY3Rpb24oc3ltLkFOQ0VTVE9SKTsgfQotImFuY2VzdG9yLW9yLXNlbGYiICAgICAgIHsgcmV0dXJuIGRpc2FtYmlndWF0ZUF4aXNPckZ1bmN0aW9uKHN5bS5BTkNFU1RPUk9SU0VMRik7IH0KLSJkZXNjZW5kYW50IiAgICAgICAgICAgICB7IHJldHVybiBkaXNhbWJpZ3VhdGVBeGlzT3JGdW5jdGlvbihzeW0uREVTQ0VOREFOVCk7IH0KLSJkZXNjZW5kYW50LW9yLXNlbGYiICAgICB7IHJldHVybiBkaXNhbWJpZ3VhdGVBeGlzT3JGdW5jdGlvbihzeW0uREVTQ0VOREFOVE9SU0VMRik7IH0KLSJmb2xsb3dpbmciICAgICAgICAgICAgICB7IHJldHVybiBkaXNhbWJpZ3VhdGVBeGlzT3JGdW5jdGlvbihzeW0uRk9MTE9XSU5HKTsgfQotImZvbGxvd2luZy1zaWJsaW5nIiAgICAgIHsgcmV0dXJuIGRpc2FtYmlndWF0ZUF4aXNPckZ1bmN0aW9uKHN5bS5GT0xMT1dJTkdTSUJMSU5HKTsgfQotIm5hbWVzcGFjZSIgICAgICAgICAgICAgIHsgcmV0dXJuIGRpc2FtYmlndWF0ZUF4aXNPckZ1bmN0aW9uKHN5bS5OQU1FU1BBQ0UpOyB9Ci0icGFyZW50IiAgICAgICAgICAgICAgICAgeyByZXR1cm4gZGlzYW1iaWd1YXRlQXhpc09yRnVuY3Rpb24oc3ltLlBBUkVOVCk7IH0KLSJwcmVjZWRpbmciICAgICAgICAgICAgICB7IHJldHVybiBkaXNhbWJpZ3VhdGVBeGlzT3JGdW5jdGlvbihzeW0uUFJFQ0VESU5HKTsgfQotInByZWNlZGluZy1zaWJsaW5nIiAgICAgIHsgcmV0dXJuIGRpc2FtYmlndWF0ZUF4aXNPckZ1bmN0aW9uKHN5bS5QUkVDRURJTkdTSUJMSU5HKTsgfQotInNlbGYiICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIGRpc2FtYmlndWF0ZUF4aXNPckZ1bmN0aW9uKHN5bS5TRUxGKTsgfQotIlsiICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uTEJSQUNLKTsgfQotIl0iICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uUkJSQUNLKTsgfQotIigiICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uTFBBUkVOKTsgfQotIikiICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uUlBBUkVOKTsgfQotIjxQQVRURVJOPiIgICAgICAgICAgICAgIHsgaW5pdGlhbGl6ZSgpOyByZXR1cm4gbmV3IFN5bWJvbChzeW0uUEFUVEVSTik7IH0KLSI8RVhQUkVTU0lPTj4iICAgICAgICAgICB7IGluaXRpYWxpemUoKTsgcmV0dXJuIG5ldyBTeW1ib2woc3ltLkVYUFJFU1NJT04pOyB9Ci1cIlteXCJdKlwiICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5MaXRlcmFsLAotCQkJICAgICAgeXl0ZXh0KCkuc3Vic3RyaW5nKDEsIHl5dGV4dCgpLmxlbmd0aCgpIC0gMSkpOyB9Ci1cJ1teXCddKlwnICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5MaXRlcmFsLAotCQkJICAgICAgeXl0ZXh0KCkuc3Vic3RyaW5nKDEsIHl5dGV4dCgpLmxlbmd0aCgpIC0gMSkpOyB9Ci17RGlnaXR9KyAgICAgICAgICAgICAgIAkgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5JTlQsIG5ldyBMb25nKHl5dGV4dCgpKSk7IH0KLXtEaWdpdH0rKCIuIntEaWdpdH0qKT8gCSB7IHJldHVybiBuZXdTeW1ib2woc3ltLlJFQUwsIG5ldyBEb3VibGUoeXl0ZXh0KCkpKTsgfQotIi4ie0RpZ2l0fSsgICAgICAgICAgICAJIHsgcmV0dXJuIG5ld1N5bWJvbChzeW0uUkVBTCwgbmV3IERvdWJsZSh5eXRleHQoKSkpOyB9Ci0iLiIgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5ET1QpOyB9Ci0oe05DTmFtZX0iOiIpP3tOQ05hbWV9ICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5RTkFNRSwgeXl0ZXh0KCkpOyB9Ci0oe05DTmFtZX0iOiIpPyIqIiAgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5RTkFNRSwgeXl0ZXh0KCkpOyB9Ci0oe05DTmFtZX0iOiIpPyJAKiIgICAgICAgeyByZXR1cm4gbmV3U3ltYm9sKHN5bS5RTkFNRSwgeXl0ZXh0KCkpOyB9Ci1bIFx0XHJcblxmXSAgICAgICAgICAgICAgeyAvKiBpZ25vcmUgd2hpdGUgc3BhY2UuICovIH0KLS4gICAgICAgICAgICAgICAgICAgICAgICB7IHRocm93IG5ldyBFeGNlcHRpb24oeXl0ZXh0KCkpOyB9CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2RvbS9BYnNvbHV0ZUl0ZXJhdG9yLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2RvbS9BYnNvbHV0ZUl0ZXJhdG9yLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGM3OTYyZTcuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vQWJzb2x1dGVJdGVyYXRvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTAxICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IEFic29sdXRlSXRlcmF0b3IuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8wNiAwNTo0Njo0NiBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuZG9tOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnJ1bnRpbWUuQmFzaXNMaWJyYXJ5OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTUF4aXNJdGVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5yZWYuRFRNQXhpc0l0ZXJhdG9yQmFzZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5yZWYuRFRNRGVmYXVsdEJhc2U7Ci0KLS8qKgotICogQWJzb2x1dGUgaXRlcmF0b3JzIGlnbm9yZSB0aGUgbm9kZSB0aGF0IGlzIHBhc3NlZCB0byBzZXRTdGFydE5vZGUoKS4KLSAqIEluc3RlYWQsIHRoZXkgYWx3YXlzIHN0YXJ0IGZyb20gdGhlIHJvb3Qgbm9kZS4gVGhlIG5vZGUgcGFzc2VkIHRvCi0gKiBzZXRTdGFydE5vZGUoKSBpcyBub3QgdG90YWxseSB1c2VsZXNzLCB0aG91Z2guIEl0IGlzIG5lZWRlZCB0byBvYnRhaW4gdGhlCi0gKiBET00gbWFzaywgaS5lLiB0aGUgaW5kZXggaW50byB0aGUgTXVsdGlET00gdGFibGUgdGhhdCBjb3JyZXNwb25kcyB0byB0aGUKLSAqIERPTSAib3duaW5nIiB0aGUgbm9kZS4KLSAqCi0gKiBUaGUgRE9NIG1hc2sgaXMgY2FjaGVkLCBzbyBzdWNjZXNzaXZlIGNhbGxzIHRvIHNldFN0YXJ0Tm9kZSgpIHBhc3NpbmcKLSAqIG5vZGVzIGZyb20gb3RoZXIgRE9NcyB3aWxsIGhhdmUgbm8gZWZmZWN0IChpLmUuIHRoaXMgaXRlcmF0b3IgY2Fubm90Ci0gKiBtaWdyYXRlIGJldHdlZW4gRE9NcykuCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBBYnNvbHV0ZUl0ZXJhdG9yIGV4dGVuZHMgRFRNQXhpc0l0ZXJhdG9yQmFzZSB7Ci0KLSAgICAvKioKLSAgICAgKiBTb3VyY2UgZm9yIHRoaXMgaXRlcmF0b3IuCi0gICAgICovCi0gICAgcHJpdmF0ZSBEVE1BeGlzSXRlcmF0b3IgX3NvdXJjZTsKLQotICAgIHB1YmxpYyBBYnNvbHV0ZUl0ZXJhdG9yKERUTUF4aXNJdGVyYXRvciBzb3VyY2UpIHsKLSAgICAgICAgX3NvdXJjZSA9IHNvdXJjZTsKLS8vIFN5c3RlbS5vdXQucHJpbnRsbigiQUkgc291cmNlID0gIiArIHNvdXJjZSArICIgdGhpcyA9ICIgKyB0aGlzKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRSZXN0YXJ0YWJsZShib29sZWFuIGlzUmVzdGFydGFibGUpIHsKLSAgICAgICAgX2lzUmVzdGFydGFibGUgPSBpc1Jlc3RhcnRhYmxlOwotICAgICAgICBfc291cmNlLnNldFJlc3RhcnRhYmxlKGlzUmVzdGFydGFibGUpOwotICAgIH0KLQotICAgIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3Igc2V0U3RhcnROb2RlKGludCBub2RlKSB7Ci0gICAgICAgIF9zdGFydE5vZGUgPSBEVE1EZWZhdWx0QmFzZS5ST09UTk9ERTsKLSAgICAgICAgaWYgKF9pc1Jlc3RhcnRhYmxlKSB7Ci0gICAgICAgICAgICBfc291cmNlLnNldFN0YXJ0Tm9kZShfc3RhcnROb2RlKTsKLSAgICAgICAgICAgIHJlc2V0UG9zaXRpb24oKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gdGhpczsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IG5leHQoKSB7Ci0gICAgICAgIHJldHVybiByZXR1cm5Ob2RlKF9zb3VyY2UubmV4dCgpKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIGNsb25lSXRlcmF0b3IoKSB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBmaW5hbCBBYnNvbHV0ZUl0ZXJhdG9yIGNsb25lID0gKEFic29sdXRlSXRlcmF0b3IpIHN1cGVyLmNsb25lKCk7Ci0gICAgICAgICAgICBjbG9uZS5fc291cmNlID0gX3NvdXJjZS5jbG9uZUl0ZXJhdG9yKCk7ICAgIC8vIHJlc2V0cyBzb3VyY2UKLSAgICAgICAgICAgIGNsb25lLnJlc2V0UG9zaXRpb24oKTsKLSAgICAgICAgICAgIGNsb25lLl9pc1Jlc3RhcnRhYmxlID0gZmFsc2U7Ci0gICAgICAgICAgICByZXR1cm4gY2xvbmU7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIEJhc2lzTGlicmFyeS5ydW5UaW1lRXJyb3IoQmFzaXNMaWJyYXJ5LklURVJBVE9SX0NMT05FX0VSUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZS50b1N0cmluZygpKTsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIERUTUF4aXNJdGVyYXRvciByZXNldCgpIHsKLSAgICAgICAgX3NvdXJjZS5yZXNldCgpOwotICAgICAgICByZXR1cm4gcmVzZXRQb3NpdGlvbigpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldE1hcmsoKSB7Ci0gICAgICAgIF9zb3VyY2Uuc2V0TWFyaygpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGdvdG9NYXJrKCkgewotICAgICAgICBfc291cmNlLmdvdG9NYXJrKCk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vQWRhcHRpdmVSZXN1bHRUcmVlSW1wbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vQWRhcHRpdmVSZXN1bHRUcmVlSW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjYjUwY2Y1Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvZG9tL0FkYXB0aXZlUmVzdWx0VHJlZUltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEzNDYgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAxNSwgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqLwotLyoKLSAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQotICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCi0gKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCi0gKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAotICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKLSAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmRvbTsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5ET007Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLlN0cmlwRmlsdGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5UcmFuc2xldEV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMucnVudGltZS5CYXNpc0xpYnJhcnk7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNQXhpc0l0ZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTUF4aXNUcmF2ZXJzZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNV1NGaWx0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyLlNlcmlhbGl6YXRpb25IYW5kbGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuWE1MU3RyaW5nOwotaW1wb3J0IGphdmEudXRpbC5NYXA7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2VMb2NhdG9yOwotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZUxpc3Q7Ci1pbXBvcnQgb3JnLnhtbC5zYXguQXR0cmlidXRlczsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguaGVscGVycy5BdHRyaWJ1dGVzSW1wbDsKLQotLyoqCi0gKiBBZGFwdGl2ZVJlc3VsdFRyZWVJbXBsIGlzIGEgYWRhcHRpdmUgRE9NIG1vZGVsIGZvciByZXN1bHQgdHJlZSBmcmFnbWVudHMgKFJURikuIEl0IGlzCi0gKiB1c2VkIGluIHRoZSBjYXNlIHdoZXJlIHRoZSBSVEYgaXMgbGlrZWx5IHRvIGJlIHB1cmUgdGV4dCB5ZXQgaXQgY2FuIHN0aWxsIGJlIGEgRE9NIHRyZWUuCi0gKiBJdCBpcyBkZXNpZ25lZCBmb3IgUlRGcyB3aGljaCBoYXZlICZsdDt4c2w6Y2FsbC10ZW1wbGF0ZSZndDsgb3IgJmx0O3hzbDphcHBseS10ZW1wbGF0ZXMmZ3Q7IGluCi0gKiB0aGUgY29udGVudHMuIEV4YW1wbGU6Ci0gKiA8cHJlPgotICogICAgJmx0O3hzbDp2YXJpYWJsZSBuYW1lID0gIngiJmd0OwotICogICAgICAmbHQ7eHNsOmNhbGwtdGVtcGxhdGUgbmFtZSA9ICJ0ZXN0IiZndDsKLSAqICAgICAgICAgJmx0O3hzbDp3aXRoLXBhcmFtIG5hbWU9ImEiIHNlbGVjdD0iLiIvJmd0OwotICogICAgICAmbHQ7L3hzbDpjYWxsLXRlbXBsYXRlJmd0OwotICogICAgJmx0Oy94c2w6dmFyaWFibGU+Ci0gKiA8L3ByZT4KLSAqIDxwPkluIHRoaXMgZXhhbXBsZSB0aGUgcmVzdWx0IHByb2R1Y2VkIGJ5IDx4c2w6Y2FsbC10ZW1wbGF0ZT4gaXMgbGlrZWx5IHRvIGJlIGEgc2luZ2xlCi0gKiBUZXh0IG5vZGUuIEJ1dCBpdCBjYW4gYWxzbyBiZSBhIERPTSB0cmVlLiBUaGlzIGtpbmQgb2YgUlRGIGNhbm5vdCBiZSBtb2RlbGxlZCBieQotICogU2ltcGxlUmVzdWx0VHJlZUltcGwuCi0gKiA8cD4KLSAqIEFkYXB0aXZlUmVzdWx0VHJlZUltcGwgY2FuIGJlIGNvbnNpZGVyZWQgYXMgYSBzbWFydCBzd2l0Y2hlciBiZXR3ZWVuIFNpbXBsZVJlc3VsdFRyZWVJbXBsCi0gKiBhbmQgU0FYSW1wbC4gSXQgdHJlYXRzIHRoZSBSVEYgYXMgc2ltcGxlIFRleHQgYW5kIHVzZXMgdGhlIFNpbXBsZVJlc3VsdFRyZWVJbXBsIG1vZGVsCi0gKiBhdCB0aGUgYmVnaW5uaW5nLiBIb3dldmVyLCBpZiBpdCByZWNlaXZlcyBhIGNhbGwgd2hpY2ggaW5kaWNhdGVzIHRoYXQgdGhpcyBpcyBhIERPTSB0cmVlCi0gKiAoZS5nLiBzdGFydEVsZW1lbnQpLCBpdCB3aWxsIGF1dG9tYXRpY2FsbHkgdHJhbnNmb3JtIGl0c2VsZiBpbnRvIGEgd3JhcHBlciBhcm91bmQgYQotICogU0FYSW1wbC4gSW4gdGhpcyB3YXkgd2UgY2FuIGhhdmUgYSBsaWdodC13ZWlnaHQgbW9kZWwgd2hlbiB0aGUgcmVzdWx0IG9ubHkgY29udGFpbnMKLSAqIHNpbXBsZSB0ZXh0LCB3aGlsZSBhdCB0aGUgc2FtZSB0aW1lIGl0IHN0aWxsIHdvcmtzIHdoZW4gdGhlIFJURiBpcyBhIERPTSB0cmVlLgotICogPHA+Ci0gKiBBbGwgbWV0aG9kcyBpbiB0aGlzIGNsYXNzIGFyZSBvdmVycmlkZGVuIHRvIGRlbGVnYXRlIHRoZSBhY3Rpb24gdG8gdGhlIHdyYXBwZWQgU0FYSW1wbCBvYmplY3QKLSAqIGlmIGl0IGlzIG5vbi1udWxsLCBvciBkZWxlZ2F0ZSB0aGUgYWN0aW9uIHRvIHRoZSBTaW1wbGVSZXN1bHRUcmVlSW1wbCBpZiB0aGVyZSBpcyBubwotICogd3JhcHBlZCBTQVhJbXBsLgotICogPHA+Ci0gKiAlUkVWSVNJVCUgQ2FuIHdlIGNvbWJpbmUgdGhpcyBjbGFzcyB3aXRoIFNpbXBsZVJlc3VsdFRyZWVJbXBsPyBJIHRoaW5rIGl0IGlzIHBvc3NpYmxlLCBidXQKLSAqIGl0IHdpbGwgbWFrZSBTaW1wbGVSZXN1bHRUcmVlSW1wbCBtb3JlIGV4cGVuc2l2ZS4gSSB3aWxsIHVzZSB0d28gc2VwYXJhdGUgY2xhc3NlcyBhdAotICogdGhpcyB0aW1lLgotICovCi1wdWJsaWMgY2xhc3MgQWRhcHRpdmVSZXN1bHRUcmVlSW1wbCBleHRlbmRzIFNpbXBsZVJlc3VsdFRyZWVJbXBsCi17Ci0KLSAgICAvLyBEb2N1bWVudCBVUkkgaW5kZXgsIHdoaWNoIGluY3JlYXNlcyBieSAxIGF0IGVhY2ggZ2V0RG9jdW1lbnRVUkkoKSBjYWxsLgotICAgIHByaXZhdGUgc3RhdGljIGludCBfZG9jdW1lbnRVUklJbmRleCA9IDA7Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRU1QVFlfU1RSSU5HID0gIiIuaW50ZXJuKCk7Ci0KLSAgICAvLyBUaGUgU0FYSW1wbCBvYmplY3Qgd3JhcHBlZCBieSB0aGlzIGNsYXNzLCBpZiB0aGUgUlRGIGlzIGEgdHJlZS4KLSAgICBwcml2YXRlIFNBWEltcGwgX2RvbTsKLQotICAgIC8qKiBUaGUgZm9sbG93aW5nIGZpZWxkcyBhcmUgb25seSB1c2VkIGZvciB0aGUgbmVzdGVkIFNBWEltcGwgKiovCi0KLSAgICAvLyBUaGUgd2hpdGVzcGFjZSBmaWx0ZXIKLSAgICBwcml2YXRlIERUTVdTRmlsdGVyIF93c2ZpbHRlcjsKLQotICAgIC8vIFRoZSBzaXplIG9mIHRoZSBSVEYKLSAgICBwcml2YXRlIGludCBfaW5pdFNpemU7Ci0KLSAgICAvLyBUcnVlIGlmIHdlIHdhbnQgdG8gYnVpbGQgdGhlIElEIGluZGV4IHRhYmxlCi0gICAgcHJpdmF0ZSBib29sZWFuIF9idWlsZElkSW5kZXg7Ci0KLSAgICAvLyBUaGUgQXR0cmlidXRlTGlzdAotICAgIHByaXZhdGUgZmluYWwgQXR0cmlidXRlc0ltcGwgX2F0dHJpYnV0ZXMgPSBuZXcgQXR0cmlidXRlc0ltcGwoKTsKLQotICAgIC8vIFRoZSBlbGVtZW50IG5hbWUKLSAgICBwcml2YXRlIFN0cmluZyBfb3BlbkVsZW1lbnROYW1lOwotCi0KLSAgICAvLyBDcmVhdGUgYSBBZGFwdGl2ZVJlc3VsdFRyZWVJbXBsCi0gICAgcHVibGljIEFkYXB0aXZlUmVzdWx0VHJlZUltcGwoWFNMVENEVE1NYW5hZ2VyIGR0bU1hbmFnZXIsIGludCBkb2N1bWVudElELAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERUTVdTRmlsdGVyIHdzZmlsdGVyLCBpbnQgaW5pdFNpemUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBidWlsZElkSW5kZXgpCi0gICAgewotICAgICAgICBzdXBlcihkdG1NYW5hZ2VyLCBkb2N1bWVudElEKTsKLQotICAgICAgICBfd3NmaWx0ZXIgPSB3c2ZpbHRlcjsKLSAgICAgICAgX2luaXRTaXplID0gaW5pdFNpemU7Ci0gICAgICAgIF9idWlsZElkSW5kZXggPSBidWlsZElkSW5kZXg7Ci0gICAgfQotCi0gICAgLy8gUmV0dXJuIHRoZSBET00gb2JqZWN0IHdyYXBwZWQgaW4gdGhpcyBvYmplY3QuCi0gICAgcHVibGljIERPTSBnZXROZXN0ZWRET00oKQotICAgIHsKLSAgICAgICAgcmV0dXJuIF9kb207Ci0gICAgfQotCi0gICAgLy8gUmV0dXJuIHRoZSBkb2N1bWVudCBJRAotICAgIHB1YmxpYyBpbnQgZ2V0RG9jdW1lbnQoKQotICAgIHsKLSAgICAgICAgaWYgKF9kb20gIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIF9kb20uZ2V0RG9jdW1lbnQoKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiBzdXBlci5nZXREb2N1bWVudCgpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLy8gUmV0dXJuIHRoZSBTdHJpbmcgdmFsdWUgb2YgdGhlIFJURgotICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3RyaW5nVmFsdWUoKQotICAgIHsKLSAgICAgICAgaWYgKF9kb20gIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIF9kb20uZ2V0U3RyaW5nVmFsdWUoKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiBzdXBlci5nZXRTdHJpbmdWYWx1ZSgpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIERUTUF4aXNJdGVyYXRvciBnZXRJdGVyYXRvcigpCi0gICAgewotICAgICAgICBpZiAoX2RvbSAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gX2RvbS5nZXRJdGVyYXRvcigpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmdldEl0ZXJhdG9yKCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIGdldENoaWxkcmVuKGZpbmFsIGludCBub2RlKQotICAgIHsKLSAgICAgICAgaWYgKF9kb20gIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIF9kb20uZ2V0Q2hpbGRyZW4obm9kZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gc3VwZXIuZ2V0Q2hpbGRyZW4obm9kZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIGdldFR5cGVkQ2hpbGRyZW4oZmluYWwgaW50IHR5cGUpCi0gICAgewotICAgICAgICBpZiAoX2RvbSAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gX2RvbS5nZXRUeXBlZENoaWxkcmVuKHR5cGUpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmdldFR5cGVkQ2hpbGRyZW4odHlwZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIGdldEF4aXNJdGVyYXRvcihmaW5hbCBpbnQgYXhpcykKLSAgICB7Ci0gICAgICAgIGlmIChfZG9tICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBfZG9tLmdldEF4aXNJdGVyYXRvcihheGlzKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiBzdXBlci5nZXRBeGlzSXRlcmF0b3IoYXhpcyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIGdldFR5cGVkQXhpc0l0ZXJhdG9yKGZpbmFsIGludCBheGlzLCBmaW5hbCBpbnQgdHlwZSkKLSAgICB7Ci0gICAgICAgIGlmIChfZG9tICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBfZG9tLmdldFR5cGVkQXhpc0l0ZXJhdG9yKGF4aXMsIHR5cGUpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmdldFR5cGVkQXhpc0l0ZXJhdG9yKGF4aXMsIHR5cGUpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIERUTUF4aXNJdGVyYXRvciBnZXROdGhEZXNjZW5kYW50KGludCBub2RlLCBpbnQgbiwgYm9vbGVhbiBpbmNsdWRlc2VsZikKLSAgICB7Ci0gICAgICAgIGlmIChfZG9tICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBfZG9tLmdldE50aERlc2NlbmRhbnQobm9kZSwgbiwgaW5jbHVkZXNlbGYpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmdldE50aERlc2NlbmRhbnQobm9kZSwgbiwgaW5jbHVkZXNlbGYpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIERUTUF4aXNJdGVyYXRvciBnZXROYW1lc3BhY2VBeGlzSXRlcmF0b3IoZmluYWwgaW50IGF4aXMsIGZpbmFsIGludCBucykKLSAgICB7Ci0gICAgICAgIGlmIChfZG9tICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBfZG9tLmdldE5hbWVzcGFjZUF4aXNJdGVyYXRvcihheGlzLCBucyk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gc3VwZXIuZ2V0TmFtZXNwYWNlQXhpc0l0ZXJhdG9yKGF4aXMsIG5zKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3IgZ2V0Tm9kZVZhbHVlSXRlcmF0b3IoRFRNQXhpc0l0ZXJhdG9yIGl0ZXIsIGludCByZXR1cm5UeXBlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHZhbHVlLCBib29sZWFuIG9wKQotICAgIHsKLSAgICAgICAgaWYgKF9kb20gIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIF9kb20uZ2V0Tm9kZVZhbHVlSXRlcmF0b3IoaXRlciwgcmV0dXJuVHlwZSwgdmFsdWUsIG9wKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiBzdXBlci5nZXROb2RlVmFsdWVJdGVyYXRvcihpdGVyLCByZXR1cm5UeXBlLCB2YWx1ZSwgb3ApOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIERUTUF4aXNJdGVyYXRvciBvcmRlck5vZGVzKERUTUF4aXNJdGVyYXRvciBzb3VyY2UsIGludCBub2RlKQotICAgIHsKLSAgICAgICAgaWYgKF9kb20gIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIF9kb20ub3JkZXJOb2Rlcyhzb3VyY2UsIG5vZGUpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIHN1cGVyLm9yZGVyTm9kZXMoc291cmNlLCBub2RlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Tm9kZU5hbWUoZmluYWwgaW50IG5vZGUpCi0gICAgewotICAgICAgICBpZiAoX2RvbSAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gX2RvbS5nZXROb2RlTmFtZShub2RlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiBzdXBlci5nZXROb2RlTmFtZShub2RlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Tm9kZU5hbWVYKGZpbmFsIGludCBub2RlKQotICAgIHsKLSAgICAgICAgaWYgKF9kb20gIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIF9kb20uZ2V0Tm9kZU5hbWVYKG5vZGUpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmdldE5vZGVOYW1lWChub2RlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZXNwYWNlTmFtZShmaW5hbCBpbnQgbm9kZSkKLSAgICB7Ci0gICAgICAgIGlmIChfZG9tICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBfZG9tLmdldE5hbWVzcGFjZU5hbWUobm9kZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gc3VwZXIuZ2V0TmFtZXNwYWNlTmFtZShub2RlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8vIFJldHVybiB0aGUgZXhwYW5kZWQgdHlwZSBpZCBvZiBhIGdpdmVuIG5vZGUKLSAgICBwdWJsaWMgaW50IGdldEV4cGFuZGVkVHlwZUlEKGZpbmFsIGludCBub2RlSGFuZGxlKQotICAgIHsKLSAgICAgICAgaWYgKF9kb20gIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIF9kb20uZ2V0RXhwYW5kZWRUeXBlSUQobm9kZUhhbmRsZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gc3VwZXIuZ2V0RXhwYW5kZWRUeXBlSUQobm9kZUhhbmRsZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldE5hbWVzcGFjZVR5cGUoZmluYWwgaW50IG5vZGUpCi0gICAgewotICAgICAgICBpZiAoX2RvbSAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gX2RvbS5nZXROYW1lc3BhY2VUeXBlKG5vZGUpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmdldE5hbWVzcGFjZVR5cGUobm9kZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldFBhcmVudChmaW5hbCBpbnQgbm9kZUhhbmRsZSkKLSAgICB7Ci0gICAgICAgIGlmIChfZG9tICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBfZG9tLmdldFBhcmVudChub2RlSGFuZGxlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiBzdXBlci5nZXRQYXJlbnQobm9kZUhhbmRsZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldEF0dHJpYnV0ZU5vZGUoZmluYWwgaW50IGdUeXBlLCBmaW5hbCBpbnQgZWxlbWVudCkKLSAgICB7Ci0gICAgICAgIGlmIChfZG9tICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBfZG9tLmdldEF0dHJpYnV0ZU5vZGUoZ1R5cGUsIGVsZW1lbnQpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmdldEF0dHJpYnV0ZU5vZGUoZ1R5cGUsIGVsZW1lbnQpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRTdHJpbmdWYWx1ZVgoZmluYWwgaW50IG5vZGVIYW5kbGUpCi0gICAgewotICAgICAgICBpZiAoX2RvbSAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gX2RvbS5nZXRTdHJpbmdWYWx1ZVgobm9kZUhhbmRsZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gc3VwZXIuZ2V0U3RyaW5nVmFsdWVYKG5vZGVIYW5kbGUpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgY29weShmaW5hbCBpbnQgbm9kZSwgU2VyaWFsaXphdGlvbkhhbmRsZXIgaGFuZGxlcikKLSAgICAgICAgdGhyb3dzIFRyYW5zbGV0RXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAoX2RvbSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBfZG9tLmNvcHkobm9kZSwgaGFuZGxlcik7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBzdXBlci5jb3B5KG5vZGUsIGhhbmRsZXIpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgY29weShEVE1BeGlzSXRlcmF0b3Igbm9kZXMsIFNlcmlhbGl6YXRpb25IYW5kbGVyIGhhbmRsZXIpCi0gICAgICAgIHRocm93cyBUcmFuc2xldEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaWYgKF9kb20gIT0gbnVsbCkgewotICAgICAgICAgICAgX2RvbS5jb3B5KG5vZGVzLCBoYW5kbGVyKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHN1cGVyLmNvcHkobm9kZXMsIGhhbmRsZXIpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBzaGFsbG93Q29weShmaW5hbCBpbnQgbm9kZSwgU2VyaWFsaXphdGlvbkhhbmRsZXIgaGFuZGxlcikKLSAgICAgICAgdGhyb3dzIFRyYW5zbGV0RXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAoX2RvbSAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gX2RvbS5zaGFsbG93Q29weShub2RlLCBoYW5kbGVyKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiBzdXBlci5zaGFsbG93Q29weShub2RlLCBoYW5kbGVyKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGxlc3NUaGFuKGZpbmFsIGludCBub2RlMSwgZmluYWwgaW50IG5vZGUyKQotICAgIHsKLSAgICAgICAgaWYgKF9kb20gIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIF9kb20ubGVzc1RoYW4obm9kZTEsIG5vZGUyKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiBzdXBlci5sZXNzVGhhbihub2RlMSwgbm9kZTIpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRGlzcGF0Y2ggdGhlIGNoYXJhY3RlciBjb250ZW50IG9mIGEgbm9kZSB0byBhbiBvdXRwdXQgaGFuZGxlci4KLSAgICAgKgotICAgICAqIFRoZSBlc2NhcGUgc2V0dGluZyBzaG91bGQgYmUgdGFrZW4gY2FyZSBvZiB3aGVuIG91dHB1dHRpbmcgdG8KLSAgICAgKiBhIGhhbmRsZXIuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY2hhcmFjdGVycyhmaW5hbCBpbnQgbm9kZSwgU2VyaWFsaXphdGlvbkhhbmRsZXIgaGFuZGxlcikKLSAgICAgICAgdGhyb3dzIFRyYW5zbGV0RXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAoX2RvbSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBfZG9tLmNoYXJhY3RlcnMobm9kZSwgaGFuZGxlcik7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBzdXBlci5jaGFyYWN0ZXJzKG5vZGUsIGhhbmRsZXIpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIE5vZGUgbWFrZU5vZGUoaW50IGluZGV4KQotICAgIHsKLSAgICAgICAgaWYgKF9kb20gIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIF9kb20ubWFrZU5vZGUoaW5kZXgpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIHN1cGVyLm1ha2VOb2RlKGluZGV4KTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyBOb2RlIG1ha2VOb2RlKERUTUF4aXNJdGVyYXRvciBpdGVyKQotICAgIHsKLSAgICAgICAgaWYgKF9kb20gIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIF9kb20ubWFrZU5vZGUoaXRlcik7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gc3VwZXIubWFrZU5vZGUoaXRlcik7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgTm9kZUxpc3QgbWFrZU5vZGVMaXN0KGludCBpbmRleCkKLSAgICB7Ci0gICAgICAgIGlmIChfZG9tICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBfZG9tLm1ha2VOb2RlTGlzdChpbmRleCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gc3VwZXIubWFrZU5vZGVMaXN0KGluZGV4KTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyBOb2RlTGlzdCBtYWtlTm9kZUxpc3QoRFRNQXhpc0l0ZXJhdG9yIGl0ZXIpCi0gICAgewotICAgICAgICBpZiAoX2RvbSAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gX2RvbS5tYWtlTm9kZUxpc3QoaXRlcik7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gc3VwZXIubWFrZU5vZGVMaXN0KGl0ZXIpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRMYW5ndWFnZShpbnQgbm9kZSkKLSAgICB7Ci0gICAgICAgIGlmIChfZG9tICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBfZG9tLmdldExhbmd1YWdlKG5vZGUpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmdldExhbmd1YWdlKG5vZGUpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIGludCBnZXRTaXplKCkKLSAgICB7Ci0gICAgICAgIGlmIChfZG9tICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBfZG9tLmdldFNpemUoKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiBzdXBlci5nZXRTaXplKCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldERvY3VtZW50VVJJKGludCBub2RlKQotICAgIHsKLSAgICAgICAgaWYgKF9kb20gIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIF9kb20uZ2V0RG9jdW1lbnRVUkkobm9kZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gImFkYXB0aXZlX3J0ZiIgKyBfZG9jdW1lbnRVUklJbmRleCsrOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0RmlsdGVyKFN0cmlwRmlsdGVyIGZpbHRlcikKLSAgICB7Ci0gICAgICAgIGlmIChfZG9tICE9IG51bGwpIHsKLSAgICAgICAgICAgIF9kb20uc2V0RmlsdGVyKGZpbHRlcik7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBzdXBlci5zZXRGaWx0ZXIoZmlsdGVyKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldHVwTWFwcGluZyhTdHJpbmdbXSBuYW1lcywgU3RyaW5nW10gdXJpcywgaW50W10gdHlwZXMsIFN0cmluZ1tdIG5hbWVzcGFjZXMpCi0gICAgewotICAgICAgICBpZiAoX2RvbSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBfZG9tLnNldHVwTWFwcGluZyhuYW1lcywgdXJpcywgdHlwZXMsIG5hbWVzcGFjZXMpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgc3VwZXIuc2V0dXBNYXBwaW5nKG5hbWVzLCB1cmlzLCB0eXBlcywgbmFtZXNwYWNlcyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0VsZW1lbnQoZmluYWwgaW50IG5vZGUpCi0gICAgewotICAgICAgICBpZiAoX2RvbSAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gX2RvbS5pc0VsZW1lbnQobm9kZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gc3VwZXIuaXNFbGVtZW50KG5vZGUpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gaXNBdHRyaWJ1dGUoZmluYWwgaW50IG5vZGUpCi0gICAgewotICAgICAgICBpZiAoX2RvbSAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gX2RvbS5pc0F0dHJpYnV0ZShub2RlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiBzdXBlci5pc0F0dHJpYnV0ZShub2RlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgbG9va3VwTmFtZXNwYWNlKGludCBub2RlLCBTdHJpbmcgcHJlZml4KQotICAgICAgICB0aHJvd3MgVHJhbnNsZXRFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGlmIChfZG9tICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBfZG9tLmxvb2t1cE5hbWVzcGFjZShub2RlLCBwcmVmaXgpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmxvb2t1cE5hbWVzcGFjZShub2RlLCBwcmVmaXgpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSBub2RlIGlkZW50aXR5IGZyb20gYSBub2RlIGhhbmRsZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgZmluYWwgaW50IGdldE5vZGVJZGVudChmaW5hbCBpbnQgbm9kZWhhbmRsZSkKLSAgICB7Ci0gICAgICAgIGlmIChfZG9tICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBfZG9tLmdldE5vZGVJZGVudChub2RlaGFuZGxlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiBzdXBlci5nZXROb2RlSWRlbnQobm9kZWhhbmRsZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIG5vZGUgaGFuZGxlIGZyb20gYSBub2RlIGlkZW50aXR5LgotICAgICAqLwotICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0Tm9kZUhhbmRsZShmaW5hbCBpbnQgbm9kZUlkKQotICAgIHsKLSAgICAgICAgaWYgKF9kb20gIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIF9kb20uZ2V0Tm9kZUhhbmRsZShub2RlSWQpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmdldE5vZGVIYW5kbGUobm9kZUlkKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyBET00gZ2V0UmVzdWx0VHJlZUZyYWcoaW50IGluaXRpYWxTaXplLCBpbnQgcnRmVHlwZSkKLSAgICB7Ci0gICAgICAgIGlmIChfZG9tICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBfZG9tLmdldFJlc3VsdFRyZWVGcmFnKGluaXRpYWxTaXplLCBydGZUeXBlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiBzdXBlci5nZXRSZXN1bHRUcmVlRnJhZyhpbml0aWFsU2l6ZSwgcnRmVHlwZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgU2VyaWFsaXphdGlvbkhhbmRsZXIgZ2V0T3V0cHV0RG9tQnVpbGRlcigpCi0gICAgewotICAgICAgICByZXR1cm4gdGhpczsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldE5TVHlwZShpbnQgbm9kZSkKLSAgICB7Ci0gICAgICAgIGlmIChfZG9tICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBfZG9tLmdldE5TVHlwZShub2RlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiBzdXBlci5nZXROU1R5cGUobm9kZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldFVucGFyc2VkRW50aXR5VVJJKFN0cmluZyBuYW1lKQotICAgIHsKLSAgICAgICAgaWYgKF9kb20gIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIF9kb20uZ2V0VW5wYXJzZWRFbnRpdHlVUkkobmFtZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gc3VwZXIuZ2V0VW5wYXJzZWRFbnRpdHlVUkkobmFtZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgTWFwPFN0cmluZywgSW50ZWdlcj4gZ2V0RWxlbWVudHNXaXRoSURzKCkKLSAgICB7Ci0gICAgICAgIGlmIChfZG9tICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBfZG9tLmdldEVsZW1lbnRzV2l0aElEcygpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmdldEVsZW1lbnRzV2l0aElEcygpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqIEltcGxlbWVudGF0aW9uIG9mIHRoZSBTZXJpYWxpemF0aW9uSGFuZGxlciBpbnRlcmZhY2VzICoqLwotCi0gICAgLyoqIFRoZSBjb2RlIGluIHNvbWUgb2YgdGhlIGZvbGxvd2luZyBpbnRlcmZhY2VzIGFyZSBjb3BpZWQgZnJvbSBTQVhBZGFwdGVyLiAqKi8KLQotICAgIHByaXZhdGUgdm9pZCBtYXliZUVtaXRTdGFydEVsZW1lbnQoKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAoX29wZW5FbGVtZW50TmFtZSAhPSBudWxsKSB7Ci0KLSAgICAgICAgICAgaW50IGluZGV4OwotICAgICAgICAgICBpZiAoKGluZGV4ID1fb3BlbkVsZW1lbnROYW1lLmluZGV4T2YoIjoiKSkgPCAwKQotICAgICAgICAgICAgICAgX2RvbS5zdGFydEVsZW1lbnQobnVsbCwgX29wZW5FbGVtZW50TmFtZSwgX29wZW5FbGVtZW50TmFtZSwgX2F0dHJpYnV0ZXMpOwotICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgdXJpID1fZG9tLmdldE5hbWVzcGFjZVVSSShfb3BlbkVsZW1lbnROYW1lLnN1YnN0cmluZygwLGluZGV4KSk7Ci0gICAgICAgICAgICAgICAgX2RvbS5zdGFydEVsZW1lbnQodXJpLCBfb3BlbkVsZW1lbnROYW1lLnN1YnN0cmluZyhpbmRleCsxKSwgX29wZW5FbGVtZW50TmFtZSwgX2F0dHJpYnV0ZXMpOwotICAgICAgICAgICB9Ci0KLQotICAgICAgICAgICAgX29wZW5FbGVtZW50TmFtZSA9IG51bGw7Ci0gICAgICAgIH0KLQotICAgIH0KLQotICAgIC8vIENyZWF0ZSBhbmQgaW5pdGlhbGl6ZSB0aGUgd3JhcHBlZCBTQVhJbXBsIG9iamVjdAotICAgIHByaXZhdGUgdm9pZCBwcmVwYXJlTmV3RE9NKCkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgX2RvbSA9IChTQVhJbXBsKV9kdG1NYW5hZ2VyLmdldERUTShudWxsLCB0cnVlLCBfd3NmaWx0ZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ1ZSwgZmFsc2UsIGZhbHNlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9pbml0U2l6ZSwgX2J1aWxkSWRJbmRleCk7Ci0gICAgICAgIF9kb20uc3RhcnREb2N1bWVudCgpOwotICAgICAgICAvLyBGbHVzaCBwZW5kaW5nIFRleHQgbm9kZXMgdG8gU0FYSW1wbAotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IF9zaXplOyBpKyspIHsKLSAgICAgICAgICAgIFN0cmluZyBzdHIgPSBfdGV4dEFycmF5W2ldOwotICAgICAgICAgICAgX2RvbS5jaGFyYWN0ZXJzKHN0ci50b0NoYXJBcnJheSgpLCAwLCBzdHIubGVuZ3RoKCkpOwotICAgICAgICB9Ci0gICAgICAgIF9zaXplID0gMDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzdGFydERvY3VtZW50KCkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBlbmREb2N1bWVudCgpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGlmIChfZG9tICE9IG51bGwpIHsKLSAgICAgICAgICAgIF9kb20uZW5kRG9jdW1lbnQoKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHN1cGVyLmVuZERvY3VtZW50KCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBjaGFyYWN0ZXJzKFN0cmluZyBzdHIpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGlmIChfZG9tICE9IG51bGwpIHsKLSAgICAgICAgICAgIGNoYXJhY3RlcnMoc3RyLnRvQ2hhckFycmF5KCksIDAsIHN0ci5sZW5ndGgoKSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBzdXBlci5jaGFyYWN0ZXJzKHN0cik7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBjaGFyYWN0ZXJzKGNoYXJbXSBjaCwgaW50IG9mZnNldCwgaW50IGxlbmd0aCkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaWYgKF9kb20gIT0gbnVsbCkgewotICAgICAgICAgICAgbWF5YmVFbWl0U3RhcnRFbGVtZW50KCk7Ci0gICAgICAgICAgICBfZG9tLmNoYXJhY3RlcnMoY2gsIG9mZnNldCwgbGVuZ3RoKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHN1cGVyLmNoYXJhY3RlcnMoY2gsIG9mZnNldCwgbGVuZ3RoKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIHNldEVzY2FwaW5nKGJvb2xlYW4gZXNjYXBlKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAoX2RvbSAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gX2RvbS5zZXRFc2NhcGluZyhlc2NhcGUpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnNldEVzY2FwaW5nKGVzY2FwZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQoU3RyaW5nIGVsZW1lbnROYW1lKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAoX2RvbSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBwcmVwYXJlTmV3RE9NKCk7Ci0gICAgICAgIH0KLQotICAgICAgICBtYXliZUVtaXRTdGFydEVsZW1lbnQoKTsKLSAgICAgICAgX29wZW5FbGVtZW50TmFtZSA9IGVsZW1lbnROYW1lOwotICAgICAgICBfYXR0cmlidXRlcy5jbGVhcigpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudChTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxOYW1lLCBTdHJpbmcgcU5hbWUpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIHN0YXJ0RWxlbWVudChxTmFtZSk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc3RhcnRFbGVtZW50KFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUsIFN0cmluZyBxTmFtZSwgQXR0cmlidXRlcyBhdHRyaWJ1dGVzKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBzdGFydEVsZW1lbnQocU5hbWUpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGVuZEVsZW1lbnQoU3RyaW5nIGVsZW1lbnROYW1lKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBtYXliZUVtaXRTdGFydEVsZW1lbnQoKTsKLSAgICAgICAgX2RvbS5lbmRFbGVtZW50KG51bGwsIG51bGwsIGVsZW1lbnROYW1lKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBlbmRFbGVtZW50KFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUsIFN0cmluZyBxTmFtZSkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgZW5kRWxlbWVudChxTmFtZSk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgYWRkQXR0cmlidXRlKFN0cmluZyBxTmFtZSwgU3RyaW5nIHZhbHVlKQotICAgIHsKLSAgICAgICAgLy8gInByZWZpeDpsb2NhbHBhcnQiIG9yICJsb2NhbHBhcnQiCi0gICAgICAgIGludCBjb2xvbnBvcyA9IHFOYW1lLmluZGV4T2YoIjoiKTsKLSAgICAgICAgU3RyaW5nIHVyaSA9IEVNUFRZX1NUUklORzsKLSAgICAgICAgU3RyaW5nIGxvY2FsTmFtZSA9IHFOYW1lOwotICAgICAgICBpZiAoY29sb25wb3MgPjApCi0gICAgICAgIHsKLSAgICAgICAgICAgIFN0cmluZyBwcmVmaXggPSBxTmFtZS5zdWJzdHJpbmcoMCwgY29sb25wb3MpOwotICAgICAgICAgICAgbG9jYWxOYW1lID0gcU5hbWUuc3Vic3RyaW5nKGNvbG9ucG9zKzEpOwotICAgICAgICAgICAgdXJpID0gX2RvbS5nZXROYW1lc3BhY2VVUkkocHJlZml4KTsKLSAgICAgICAgfQotCi0gICAgICAgIGFkZEF0dHJpYnV0ZSh1cmksIGxvY2FsTmFtZSwgcU5hbWUsICJDREFUQSIsIHZhbHVlKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBhZGRVbmlxdWVBdHRyaWJ1dGUoU3RyaW5nIHFOYW1lLCBTdHJpbmcgdmFsdWUsIGludCBmbGFncykKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgYWRkQXR0cmlidXRlKHFOYW1lLCB2YWx1ZSk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgYWRkQXR0cmlidXRlKFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUsIFN0cmluZyBxbmFtZSwKLSAgICAgICAgICAgIFN0cmluZyB0eXBlLCBTdHJpbmcgdmFsdWUpCi0gICAgewotICAgICAgICBpZiAoX29wZW5FbGVtZW50TmFtZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBfYXR0cmlidXRlcy5hZGRBdHRyaWJ1dGUodXJpLCBsb2NhbE5hbWUsIHFuYW1lLCB0eXBlLCB2YWx1ZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBCYXNpc0xpYnJhcnkucnVuVGltZUVycm9yKEJhc2lzTGlicmFyeS5TVFJBWV9BVFRSSUJVVEVfRVJSLCBxbmFtZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBuYW1lc3BhY2VBZnRlclN0YXJ0RWxlbWVudChTdHJpbmcgcHJlZml4LCBTdHJpbmcgdXJpKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAoX2RvbSA9PSBudWxsKSB7Ci0gICAgICAgICAgIHByZXBhcmVOZXdET00oKTsKLSAgICAgICAgfQotCi0gICAgICAgIF9kb20uc3RhcnRQcmVmaXhNYXBwaW5nKHByZWZpeCwgdXJpKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBjb21tZW50KFN0cmluZyBjb21tZW50KSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAoX2RvbSA9PSBudWxsKSB7Ci0gICAgICAgICAgIHByZXBhcmVOZXdET00oKTsKLSAgICAgICAgfQotCi0gICAgICAgIG1heWJlRW1pdFN0YXJ0RWxlbWVudCgpOwotICAgICAgICBjaGFyW10gY2hhcnMgPSBjb21tZW50LnRvQ2hhckFycmF5KCk7Ci0gICAgICAgIF9kb20uY29tbWVudChjaGFycywgMCwgY2hhcnMubGVuZ3RoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBjb21tZW50KGNoYXJbXSBjaGFycywgaW50IG9mZnNldCwgaW50IGxlbmd0aCkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaWYgKF9kb20gPT0gbnVsbCkgewotICAgICAgICAgICBwcmVwYXJlTmV3RE9NKCk7Ci0gICAgICAgIH0KLQotICAgICAgICBtYXliZUVtaXRTdGFydEVsZW1lbnQoKTsKLSAgICAgICAgX2RvbS5jb21tZW50KGNoYXJzLCBvZmZzZXQsIGxlbmd0aCk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgcHJvY2Vzc2luZ0luc3RydWN0aW9uKFN0cmluZyB0YXJnZXQsIFN0cmluZyBkYXRhKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAoX2RvbSA9PSBudWxsKSB7Ci0gICAgICAgICAgIHByZXBhcmVOZXdET00oKTsKLSAgICAgICAgfQotCi0gICAgICAgIG1heWJlRW1pdFN0YXJ0RWxlbWVudCgpOwotICAgICAgICBfZG9tLnByb2Nlc3NpbmdJbnN0cnVjdGlvbih0YXJnZXQsIGRhdGEpOwotICAgIH0KLQotICAgIC8qKiBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgRFRNIGludGVyZmFjZXMgKiovCi0KLSAgICBwdWJsaWMgdm9pZCBzZXRGZWF0dXJlKFN0cmluZyBmZWF0dXJlSWQsIGJvb2xlYW4gc3RhdGUpCi0gICAgewotICAgICAgICBpZiAoX2RvbSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBfZG9tLnNldEZlYXR1cmUoZmVhdHVyZUlkLCBzdGF0ZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRQcm9wZXJ0eShTdHJpbmcgcHJvcGVydHksIE9iamVjdCB2YWx1ZSkKLSAgICB7Ci0gICAgICAgIGlmIChfZG9tICE9IG51bGwpIHsKLSAgICAgICAgICAgIF9kb20uc2V0UHJvcGVydHkocHJvcGVydHksIHZhbHVlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyBEVE1BeGlzVHJhdmVyc2VyIGdldEF4aXNUcmF2ZXJzZXIoZmluYWwgaW50IGF4aXMpCi0gICAgewotICAgICAgICBpZiAoX2RvbSAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gX2RvbS5nZXRBeGlzVHJhdmVyc2VyKGF4aXMpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmdldEF4aXNUcmF2ZXJzZXIoYXhpcyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBoYXNDaGlsZE5vZGVzKGludCBub2RlSGFuZGxlKQotICAgIHsKLSAgICAgICAgaWYgKF9kb20gIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIF9kb20uaGFzQ2hpbGROb2Rlcyhub2RlSGFuZGxlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiBzdXBlci5oYXNDaGlsZE5vZGVzKG5vZGVIYW5kbGUpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIGludCBnZXRGaXJzdENoaWxkKGludCBub2RlSGFuZGxlKQotICAgIHsKLSAgICAgICAgaWYgKF9kb20gIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIF9kb20uZ2V0Rmlyc3RDaGlsZChub2RlSGFuZGxlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiBzdXBlci5nZXRGaXJzdENoaWxkKG5vZGVIYW5kbGUpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIGludCBnZXRMYXN0Q2hpbGQoaW50IG5vZGVIYW5kbGUpCi0gICAgewotICAgICAgICBpZiAoX2RvbSAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gX2RvbS5nZXRMYXN0Q2hpbGQobm9kZUhhbmRsZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gc3VwZXIuZ2V0TGFzdENoaWxkKG5vZGVIYW5kbGUpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIGludCBnZXRBdHRyaWJ1dGVOb2RlKGludCBlbGVtZW50SGFuZGxlLCBTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgbmFtZSkKLSAgICB7Ci0gICAgICAgIGlmIChfZG9tICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBfZG9tLmdldEF0dHJpYnV0ZU5vZGUoZWxlbWVudEhhbmRsZSwgbmFtZXNwYWNlVVJJLCBuYW1lKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiBzdXBlci5nZXRBdHRyaWJ1dGVOb2RlKGVsZW1lbnRIYW5kbGUsIG5hbWVzcGFjZVVSSSwgbmFtZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldEZpcnN0QXR0cmlidXRlKGludCBub2RlSGFuZGxlKQotICAgIHsKLSAgICAgICAgaWYgKF9kb20gIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIF9kb20uZ2V0Rmlyc3RBdHRyaWJ1dGUobm9kZUhhbmRsZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gc3VwZXIuZ2V0Rmlyc3RBdHRyaWJ1dGUobm9kZUhhbmRsZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldEZpcnN0TmFtZXNwYWNlTm9kZShpbnQgbm9kZUhhbmRsZSwgYm9vbGVhbiBpblNjb3BlKQotICAgIHsKLSAgICAgICAgaWYgKF9kb20gIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIF9kb20uZ2V0Rmlyc3ROYW1lc3BhY2VOb2RlKG5vZGVIYW5kbGUsIGluU2NvcGUpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmdldEZpcnN0TmFtZXNwYWNlTm9kZShub2RlSGFuZGxlLCBpblNjb3BlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgZ2V0TmV4dFNpYmxpbmcoaW50IG5vZGVIYW5kbGUpCi0gICAgewotICAgICAgICBpZiAoX2RvbSAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gX2RvbS5nZXROZXh0U2libGluZyhub2RlSGFuZGxlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiBzdXBlci5nZXROZXh0U2libGluZyhub2RlSGFuZGxlKTsKLSAgICAgICAgfQotICAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldFByZXZpb3VzU2libGluZyhpbnQgbm9kZUhhbmRsZSkKLSAgICB7Ci0gICAgICAgIGlmIChfZG9tICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBfZG9tLmdldFByZXZpb3VzU2libGluZyhub2RlSGFuZGxlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiBzdXBlci5nZXRQcmV2aW91c1NpYmxpbmcobm9kZUhhbmRsZSk7Ci0gICAgICAgIH0KLSAgICAgfQotCi0gICAgcHVibGljIGludCBnZXROZXh0QXR0cmlidXRlKGludCBub2RlSGFuZGxlKQotICAgIHsKLSAgICAgICAgaWYgKF9kb20gIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIF9kb20uZ2V0TmV4dEF0dHJpYnV0ZShub2RlSGFuZGxlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiBzdXBlci5nZXROZXh0QXR0cmlidXRlKG5vZGVIYW5kbGUpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIGludCBnZXROZXh0TmFtZXNwYWNlTm9kZShpbnQgYmFzZUhhbmRsZSwgaW50IG5hbWVzcGFjZUhhbmRsZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGluU2NvcGUpCi0gICAgewotICAgICAgICBpZiAoX2RvbSAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gX2RvbS5nZXROZXh0TmFtZXNwYWNlTm9kZShiYXNlSGFuZGxlLCBuYW1lc3BhY2VIYW5kbGUsIGluU2NvcGUpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmdldE5leHROYW1lc3BhY2VOb2RlKGJhc2VIYW5kbGUsIG5hbWVzcGFjZUhhbmRsZSwgaW5TY29wZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldE93bmVyRG9jdW1lbnQoaW50IG5vZGVIYW5kbGUpCi0gICAgewotICAgICAgICBpZiAoX2RvbSAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gX2RvbS5nZXRPd25lckRvY3VtZW50KG5vZGVIYW5kbGUpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmdldE93bmVyRG9jdW1lbnQobm9kZUhhbmRsZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldERvY3VtZW50Um9vdChpbnQgbm9kZUhhbmRsZSkKLSAgICB7Ci0gICAgICAgIGlmIChfZG9tICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBfZG9tLmdldERvY3VtZW50Um9vdChub2RlSGFuZGxlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiBzdXBlci5nZXREb2N1bWVudFJvb3Qobm9kZUhhbmRsZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgWE1MU3RyaW5nIGdldFN0cmluZ1ZhbHVlKGludCBub2RlSGFuZGxlKQotICAgIHsKLSAgICAgICAgaWYgKF9kb20gIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIF9kb20uZ2V0U3RyaW5nVmFsdWUobm9kZUhhbmRsZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gc3VwZXIuZ2V0U3RyaW5nVmFsdWUobm9kZUhhbmRsZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldFN0cmluZ1ZhbHVlQ2h1bmtDb3VudChpbnQgbm9kZUhhbmRsZSkKLSAgICB7Ci0gICAgICAgIGlmIChfZG9tICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBfZG9tLmdldFN0cmluZ1ZhbHVlQ2h1bmtDb3VudChub2RlSGFuZGxlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiBzdXBlci5nZXRTdHJpbmdWYWx1ZUNodW5rQ291bnQobm9kZUhhbmRsZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgY2hhcltdIGdldFN0cmluZ1ZhbHVlQ2h1bmsoaW50IG5vZGVIYW5kbGUsIGludCBjaHVua0luZGV4LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50W10gc3RhcnRBbmRMZW4pCi0gICAgewotICAgICAgICBpZiAoX2RvbSAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gX2RvbS5nZXRTdHJpbmdWYWx1ZUNodW5rKG5vZGVIYW5kbGUsIGNodW5rSW5kZXgsIHN0YXJ0QW5kTGVuKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiBzdXBlci5nZXRTdHJpbmdWYWx1ZUNodW5rKG5vZGVIYW5kbGUsIGNodW5rSW5kZXgsIHN0YXJ0QW5kTGVuKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgZ2V0RXhwYW5kZWRUeXBlSUQoU3RyaW5nIG5hbWVzcGFjZSwgU3RyaW5nIGxvY2FsTmFtZSwgaW50IHR5cGUpCi0gICAgewotICAgICAgICBpZiAoX2RvbSAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gX2RvbS5nZXRFeHBhbmRlZFR5cGVJRChuYW1lc3BhY2UsIGxvY2FsTmFtZSwgdHlwZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gc3VwZXIuZ2V0RXhwYW5kZWRUeXBlSUQobmFtZXNwYWNlLCBsb2NhbE5hbWUsIHR5cGUpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRMb2NhbE5hbWVGcm9tRXhwYW5kZWROYW1lSUQoaW50IEV4cGFuZGVkTmFtZUlEKQotICAgIHsKLSAgICAgICAgaWYgKF9kb20gIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIF9kb20uZ2V0TG9jYWxOYW1lRnJvbUV4cGFuZGVkTmFtZUlEKEV4cGFuZGVkTmFtZUlEKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiBzdXBlci5nZXRMb2NhbE5hbWVGcm9tRXhwYW5kZWROYW1lSUQoRXhwYW5kZWROYW1lSUQpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXROYW1lc3BhY2VGcm9tRXhwYW5kZWROYW1lSUQoaW50IEV4cGFuZGVkTmFtZUlEKQotICAgIHsKLSAgICAgICAgaWYgKF9kb20gIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIF9kb20uZ2V0TmFtZXNwYWNlRnJvbUV4cGFuZGVkTmFtZUlEKEV4cGFuZGVkTmFtZUlEKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiBzdXBlci5nZXROYW1lc3BhY2VGcm9tRXhwYW5kZWROYW1lSUQoRXhwYW5kZWROYW1lSUQpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRMb2NhbE5hbWUoaW50IG5vZGVIYW5kbGUpCi0gICAgewotICAgICAgICBpZiAoX2RvbSAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gX2RvbS5nZXRMb2NhbE5hbWUobm9kZUhhbmRsZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gc3VwZXIuZ2V0TG9jYWxOYW1lKG5vZGVIYW5kbGUpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRQcmVmaXgoaW50IG5vZGVIYW5kbGUpCi0gICAgewotICAgICAgICBpZiAoX2RvbSAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gX2RvbS5nZXRQcmVmaXgobm9kZUhhbmRsZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gc3VwZXIuZ2V0UHJlZml4KG5vZGVIYW5kbGUpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXROYW1lc3BhY2VVUkkoaW50IG5vZGVIYW5kbGUpCi0gICAgewotICAgICAgICBpZiAoX2RvbSAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gX2RvbS5nZXROYW1lc3BhY2VVUkkobm9kZUhhbmRsZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gc3VwZXIuZ2V0TmFtZXNwYWNlVVJJKG5vZGVIYW5kbGUpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXROb2RlVmFsdWUoaW50IG5vZGVIYW5kbGUpCi0gICAgewotICAgICAgICBpZiAoX2RvbSAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gX2RvbS5nZXROb2RlVmFsdWUobm9kZUhhbmRsZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gc3VwZXIuZ2V0Tm9kZVZhbHVlKG5vZGVIYW5kbGUpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHNob3J0IGdldE5vZGVUeXBlKGludCBub2RlSGFuZGxlKQotICAgIHsKLSAgICAgICAgaWYgKF9kb20gIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIF9kb20uZ2V0Tm9kZVR5cGUobm9kZUhhbmRsZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gc3VwZXIuZ2V0Tm9kZVR5cGUobm9kZUhhbmRsZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgc2hvcnQgZ2V0TGV2ZWwoaW50IG5vZGVIYW5kbGUpCi0gICAgewotICAgICAgICBpZiAoX2RvbSAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gX2RvbS5nZXRMZXZlbChub2RlSGFuZGxlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiBzdXBlci5nZXRMZXZlbChub2RlSGFuZGxlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGlzU3VwcG9ydGVkKFN0cmluZyBmZWF0dXJlLCBTdHJpbmcgdmVyc2lvbikKLSAgICB7Ci0gICAgICAgIGlmIChfZG9tICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBfZG9tLmlzU3VwcG9ydGVkKGZlYXR1cmUsIHZlcnNpb24pOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmlzU3VwcG9ydGVkKGZlYXR1cmUsIHZlcnNpb24pOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXREb2N1bWVudEJhc2VVUkkoKQotICAgIHsKLSAgICAgICAgaWYgKF9kb20gIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIF9kb20uZ2V0RG9jdW1lbnRCYXNlVVJJKCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gc3VwZXIuZ2V0RG9jdW1lbnRCYXNlVVJJKCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXREb2N1bWVudEJhc2VVUkkoU3RyaW5nIGJhc2VVUkkpCi0gICAgewotICAgICAgICBpZiAoX2RvbSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBfZG9tLnNldERvY3VtZW50QmFzZVVSSShiYXNlVVJJKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHN1cGVyLnNldERvY3VtZW50QmFzZVVSSShiYXNlVVJJKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0RG9jdW1lbnRTeXN0ZW1JZGVudGlmaWVyKGludCBub2RlSGFuZGxlKQotICAgIHsKLSAgICAgICAgaWYgKF9kb20gIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIF9kb20uZ2V0RG9jdW1lbnRTeXN0ZW1JZGVudGlmaWVyKG5vZGVIYW5kbGUpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmdldERvY3VtZW50U3lzdGVtSWRlbnRpZmllcihub2RlSGFuZGxlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0RG9jdW1lbnRFbmNvZGluZyhpbnQgbm9kZUhhbmRsZSkKLSAgICB7Ci0gICAgICAgIGlmIChfZG9tICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBfZG9tLmdldERvY3VtZW50RW5jb2Rpbmcobm9kZUhhbmRsZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gc3VwZXIuZ2V0RG9jdW1lbnRFbmNvZGluZyhub2RlSGFuZGxlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0RG9jdW1lbnRTdGFuZGFsb25lKGludCBub2RlSGFuZGxlKQotICAgIHsKLSAgICAgICAgaWYgKF9kb20gIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIF9kb20uZ2V0RG9jdW1lbnRTdGFuZGFsb25lKG5vZGVIYW5kbGUpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmdldERvY3VtZW50U3RhbmRhbG9uZShub2RlSGFuZGxlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0RG9jdW1lbnRWZXJzaW9uKGludCBkb2N1bWVudEhhbmRsZSkKLSAgICB7Ci0gICAgICAgIGlmIChfZG9tICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBfZG9tLmdldERvY3VtZW50VmVyc2lvbihkb2N1bWVudEhhbmRsZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gc3VwZXIuZ2V0RG9jdW1lbnRWZXJzaW9uKGRvY3VtZW50SGFuZGxlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGdldERvY3VtZW50QWxsRGVjbGFyYXRpb25zUHJvY2Vzc2VkKCkKLSAgICB7Ci0gICAgICAgIGlmIChfZG9tICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBfZG9tLmdldERvY3VtZW50QWxsRGVjbGFyYXRpb25zUHJvY2Vzc2VkKCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gc3VwZXIuZ2V0RG9jdW1lbnRBbGxEZWNsYXJhdGlvbnNQcm9jZXNzZWQoKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0RG9jdW1lbnRUeXBlRGVjbGFyYXRpb25TeXN0ZW1JZGVudGlmaWVyKCkKLSAgICB7Ci0gICAgICAgIGlmIChfZG9tICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBfZG9tLmdldERvY3VtZW50VHlwZURlY2xhcmF0aW9uU3lzdGVtSWRlbnRpZmllcigpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmdldERvY3VtZW50VHlwZURlY2xhcmF0aW9uU3lzdGVtSWRlbnRpZmllcigpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXREb2N1bWVudFR5cGVEZWNsYXJhdGlvblB1YmxpY0lkZW50aWZpZXIoKQotICAgIHsKLSAgICAgICAgaWYgKF9kb20gIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIF9kb20uZ2V0RG9jdW1lbnRUeXBlRGVjbGFyYXRpb25QdWJsaWNJZGVudGlmaWVyKCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gc3VwZXIuZ2V0RG9jdW1lbnRUeXBlRGVjbGFyYXRpb25QdWJsaWNJZGVudGlmaWVyKCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldEVsZW1lbnRCeUlkKFN0cmluZyBlbGVtZW50SWQpCi0gICAgewotICAgICAgICBpZiAoX2RvbSAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gX2RvbS5nZXRFbGVtZW50QnlJZChlbGVtZW50SWQpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmdldEVsZW1lbnRCeUlkKGVsZW1lbnRJZCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBzdXBwb3J0c1ByZVN0cmlwcGluZygpCi0gICAgewotICAgICAgICBpZiAoX2RvbSAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gX2RvbS5zdXBwb3J0c1ByZVN0cmlwcGluZygpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnN1cHBvcnRzUHJlU3RyaXBwaW5nKCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBpc05vZGVBZnRlcihpbnQgZmlyc3ROb2RlSGFuZGxlLCBpbnQgc2Vjb25kTm9kZUhhbmRsZSkKLSAgICB7Ci0gICAgICAgIGlmIChfZG9tICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBfZG9tLmlzTm9kZUFmdGVyKGZpcnN0Tm9kZUhhbmRsZSwgc2Vjb25kTm9kZUhhbmRsZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gc3VwZXIuaXNOb2RlQWZ0ZXIoZmlyc3ROb2RlSGFuZGxlLCBzZWNvbmROb2RlSGFuZGxlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGlzQ2hhcmFjdGVyRWxlbWVudENvbnRlbnRXaGl0ZXNwYWNlKGludCBub2RlSGFuZGxlKQotICAgIHsKLSAgICAgICAgaWYgKF9kb20gIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIF9kb20uaXNDaGFyYWN0ZXJFbGVtZW50Q29udGVudFdoaXRlc3BhY2Uobm9kZUhhbmRsZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gc3VwZXIuaXNDaGFyYWN0ZXJFbGVtZW50Q29udGVudFdoaXRlc3BhY2Uobm9kZUhhbmRsZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0RvY3VtZW50QWxsRGVjbGFyYXRpb25zUHJvY2Vzc2VkKGludCBkb2N1bWVudEhhbmRsZSkKLSAgICB7Ci0gICAgICAgIGlmIChfZG9tICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBfZG9tLmlzRG9jdW1lbnRBbGxEZWNsYXJhdGlvbnNQcm9jZXNzZWQoZG9jdW1lbnRIYW5kbGUpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmlzRG9jdW1lbnRBbGxEZWNsYXJhdGlvbnNQcm9jZXNzZWQoZG9jdW1lbnRIYW5kbGUpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gaXNBdHRyaWJ1dGVTcGVjaWZpZWQoaW50IGF0dHJpYnV0ZUhhbmRsZSkKLSAgICB7Ci0gICAgICAgIGlmIChfZG9tICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBfZG9tLmlzQXR0cmlidXRlU3BlY2lmaWVkKGF0dHJpYnV0ZUhhbmRsZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gc3VwZXIuaXNBdHRyaWJ1dGVTcGVjaWZpZWQoYXR0cmlidXRlSGFuZGxlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGRpc3BhdGNoQ2hhcmFjdGVyc0V2ZW50cyhpbnQgbm9kZUhhbmRsZSwgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIgY2gsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gbm9ybWFsaXplKQotICAgICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGlmIChfZG9tICE9IG51bGwpIHsKLSAgICAgICAgICAgIF9kb20uZGlzcGF0Y2hDaGFyYWN0ZXJzRXZlbnRzKG5vZGVIYW5kbGUsICBjaCwgbm9ybWFsaXplKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHN1cGVyLmRpc3BhdGNoQ2hhcmFjdGVyc0V2ZW50cyhub2RlSGFuZGxlLCBjaCwgbm9ybWFsaXplKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGRpc3BhdGNoVG9FdmVudHMoaW50IG5vZGVIYW5kbGUsIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyIGNoKQotICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaWYgKF9kb20gIT0gbnVsbCkgewotICAgICAgICAgICAgX2RvbS5kaXNwYXRjaFRvRXZlbnRzKG5vZGVIYW5kbGUsICBjaCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBzdXBlci5kaXNwYXRjaFRvRXZlbnRzKG5vZGVIYW5kbGUsIGNoKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyBvcmcudzNjLmRvbS5Ob2RlIGdldE5vZGUoaW50IG5vZGVIYW5kbGUpCi0gICAgewotICAgICAgICBpZiAoX2RvbSAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gX2RvbS5nZXROb2RlKG5vZGVIYW5kbGUpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmdldE5vZGUobm9kZUhhbmRsZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBuZWVkc1R3b1RocmVhZHMoKQotICAgIHsKLSAgICAgICAgaWYgKF9kb20gIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIF9kb20ubmVlZHNUd29UaHJlYWRzKCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gc3VwZXIubmVlZHNUd29UaHJlYWRzKCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIgZ2V0Q29udGVudEhhbmRsZXIoKQotICAgIHsKLSAgICAgICAgaWYgKF9kb20gIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIF9kb20uZ2V0Q29udGVudEhhbmRsZXIoKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiBzdXBlci5nZXRDb250ZW50SGFuZGxlcigpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIG9yZy54bWwuc2F4LmV4dC5MZXhpY2FsSGFuZGxlciBnZXRMZXhpY2FsSGFuZGxlcigpCi0gICAgewotICAgICAgICBpZiAoX2RvbSAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gX2RvbS5nZXRMZXhpY2FsSGFuZGxlcigpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmdldExleGljYWxIYW5kbGVyKCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgb3JnLnhtbC5zYXguRW50aXR5UmVzb2x2ZXIgZ2V0RW50aXR5UmVzb2x2ZXIoKQotICAgIHsKLSAgICAgICAgaWYgKF9kb20gIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIF9kb20uZ2V0RW50aXR5UmVzb2x2ZXIoKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiBzdXBlci5nZXRFbnRpdHlSZXNvbHZlcigpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIG9yZy54bWwuc2F4LkRUREhhbmRsZXIgZ2V0RFRESGFuZGxlcigpCi0gICAgewotICAgICAgICBpZiAoX2RvbSAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gX2RvbS5nZXREVERIYW5kbGVyKCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gc3VwZXIuZ2V0RFRESGFuZGxlcigpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIG9yZy54bWwuc2F4LkVycm9ySGFuZGxlciBnZXRFcnJvckhhbmRsZXIoKQotICAgIHsKLSAgICAgICAgaWYgKF9kb20gIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIF9kb20uZ2V0RXJyb3JIYW5kbGVyKCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gc3VwZXIuZ2V0RXJyb3JIYW5kbGVyKCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgb3JnLnhtbC5zYXguZXh0LkRlY2xIYW5kbGVyIGdldERlY2xIYW5kbGVyKCkKLSAgICB7Ci0gICAgICAgIGlmIChfZG9tICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBfZG9tLmdldERlY2xIYW5kbGVyKCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gc3VwZXIuZ2V0RGVjbEhhbmRsZXIoKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGFwcGVuZENoaWxkKGludCBuZXdDaGlsZCwgYm9vbGVhbiBjbG9uZSwgYm9vbGVhbiBjbG9uZURlcHRoKQotICAgIHsKLSAgICAgICAgaWYgKF9kb20gIT0gbnVsbCkgewotICAgICAgICAgICAgX2RvbS5hcHBlbmRDaGlsZChuZXdDaGlsZCwgY2xvbmUsIGNsb25lRGVwdGgpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgc3VwZXIuYXBwZW5kQ2hpbGQobmV3Q2hpbGQsIGNsb25lLCBjbG9uZURlcHRoKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGFwcGVuZFRleHRDaGlsZChTdHJpbmcgc3RyKQotICAgIHsKLSAgICAgICAgaWYgKF9kb20gIT0gbnVsbCkgewotICAgICAgICAgICAgX2RvbS5hcHBlbmRUZXh0Q2hpbGQoc3RyKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHN1cGVyLmFwcGVuZFRleHRDaGlsZChzdHIpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIFNvdXJjZUxvY2F0b3IgZ2V0U291cmNlTG9jYXRvckZvcihpbnQgbm9kZSkKLSAgICB7Ci0gICAgICAgIGlmIChfZG9tICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBfZG9tLmdldFNvdXJjZUxvY2F0b3JGb3Iobm9kZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gc3VwZXIuZ2V0U291cmNlTG9jYXRvckZvcihub2RlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGRvY3VtZW50UmVnaXN0cmF0aW9uKCkKLSAgICB7Ci0gICAgICAgIGlmIChfZG9tICE9IG51bGwpIHsKLSAgICAgICAgICAgIF9kb20uZG9jdW1lbnRSZWdpc3RyYXRpb24oKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHN1cGVyLmRvY3VtZW50UmVnaXN0cmF0aW9uKCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBkb2N1bWVudFJlbGVhc2UoKQotICAgIHsKLSAgICAgICAgaWYgKF9kb20gIT0gbnVsbCkgewotICAgICAgICAgICAgX2RvbS5kb2N1bWVudFJlbGVhc2UoKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHN1cGVyLmRvY3VtZW50UmVsZWFzZSgpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgcmVsZWFzZSgpIHsKLSAgICAgICAgaWYgKF9kb20gIT0gbnVsbCkgewotICAgICAgICAgICAgX2RvbS5yZWxlYXNlKCk7Ci0gICAgICAgICAgICBfZG9tID0gbnVsbDsKLSAgICAgICAgfQotICAgICAgICBzdXBlci5yZWxlYXNlKCk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vQW55Tm9kZUNvdW50ZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvZG9tL0FueU5vZGVDb3VudGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGViYWU2M2QuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vQW55Tm9kZUNvdW50ZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEzMSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBBbnlOb2RlQ291bnRlci5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzA2IDA1OjU0OjUzIHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5kb207Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuRE9NOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5UcmFuc2xldDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1BeGlzSXRlcmF0b3I7Ci0KLS8qKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICovCi1wdWJsaWMgYWJzdHJhY3QgY2xhc3MgQW55Tm9kZUNvdW50ZXIgZXh0ZW5kcyBOb2RlQ291bnRlciB7Ci0gICAgcHVibGljIEFueU5vZGVDb3VudGVyKFRyYW5zbGV0IHRyYW5zbGV0LAotICAgICAgICAgICAgICAgICAgICAgICAgICBET00gZG9jdW1lbnQsIERUTUF4aXNJdGVyYXRvciBpdGVyYXRvcikgewotICAgICAgICBzdXBlcih0cmFuc2xldCwgZG9jdW1lbnQsIGl0ZXJhdG9yKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgQW55Tm9kZUNvdW50ZXIoVHJhbnNsZXQgdHJhbnNsZXQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIERPTSBkb2N1bWVudCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgRFRNQXhpc0l0ZXJhdG9yIGl0ZXJhdG9yLAotICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGhhc0Zyb20pIHsKLSAgICAgICAgc3VwZXIodHJhbnNsZXQsIGRvY3VtZW50LCBpdGVyYXRvciwgaGFzRnJvbSk7Ci0gICAgfQotCi0gICAgcHVibGljIE5vZGVDb3VudGVyIHNldFN0YXJ0Tm9kZShpbnQgbm9kZSkgewotICAgICAgICBfbm9kZSA9IG5vZGU7Ci0gICAgICAgIF9ub2RlVHlwZSA9IF9kb2N1bWVudC5nZXRFeHBhbmRlZFR5cGVJRChub2RlKTsKLSAgICAgICAgcmV0dXJuIHRoaXM7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRDb3VudGVyKCkgewotICAgICAgICBpbnQgcmVzdWx0OwotICAgICAgICBpZiAoX3ZhbHVlICE9IEludGVnZXIuTUlOX1ZBTFVFKSB7Ci0gICAgICAgICAgICAvL1NlZSBFcnJhdGEgRTI0Ci0gICAgICAgICAgICBpZiAoX3ZhbHVlID09IDApIHJldHVybiAiMCI7Ci0gICAgICAgICAgICBlbHNlIGlmIChEb3VibGUuaXNOYU4oX3ZhbHVlKSkgcmV0dXJuICJOYU4iOwotICAgICAgICAgICAgZWxzZSBpZiAoX3ZhbHVlIDwgMCAmJiBEb3VibGUuaXNJbmZpbml0ZShfdmFsdWUpKSByZXR1cm4gIi1JbmZpbml0eSI7Ci0gICAgICAgICAgICBlbHNlIGlmIChEb3VibGUuaXNJbmZpbml0ZShfdmFsdWUpKSByZXR1cm4gIkluZmluaXR5IjsKLSAgICAgICAgICAgIGVsc2UgcmV0dXJuIGZvcm1hdE51bWJlcnMoKGludClfdmFsdWUpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgaW50IG5leHQgPSBfbm9kZTsKLSAgICAgICAgICAgIGZpbmFsIGludCByb290ID0gX2RvY3VtZW50LmdldERvY3VtZW50KCk7Ci0gICAgICAgICAgICByZXN1bHQgPSAwOwotICAgICAgICAgICAgd2hpbGUgKG5leHQgPj0gcm9vdCAmJiAhbWF0Y2hlc0Zyb20obmV4dCkpIHsKLSAgICAgICAgICAgICAgICBpZiAobWF0Y2hlc0NvdW50KG5leHQpKSB7Ci0gICAgICAgICAgICAgICAgICAgICsrcmVzdWx0OwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBuZXh0LS07Ci0vLyVIWiU6ICBJcyB0aGlzIHRoZSBiZXN0IHdheSBvZiBmaW5kaW5nIHRoZSByb290PyAgSXMgaXQgYmV0dGVyIHRvIGNoZWNrCi0vLyVIWiU6ICBwYXJlbnQobmV4dCk/Ci0gICAgICAgICAgICAgICAgLyoKLSAgICAgICAgICAgICAgICBpZiAobmV4dCA9PSByb290KSB7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgLS1uZXh0OwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAqLwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmb3JtYXROdW1iZXJzKHJlc3VsdCk7Ci0gICAgfQotCi0gICAgcHVibGljIHN0YXRpYyBOb2RlQ291bnRlciBnZXREZWZhdWx0Tm9kZUNvdW50ZXIoVHJhbnNsZXQgdHJhbnNsZXQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRE9NIGRvY3VtZW50LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERUTUF4aXNJdGVyYXRvciBpdGVyYXRvcikgewotICAgICAgICByZXR1cm4gbmV3IERlZmF1bHRBbnlOb2RlQ291bnRlcih0cmFuc2xldCwgZG9jdW1lbnQsIGl0ZXJhdG9yKTsKLSAgICB9Ci0KLSAgICBzdGF0aWMgY2xhc3MgRGVmYXVsdEFueU5vZGVDb3VudGVyIGV4dGVuZHMgQW55Tm9kZUNvdW50ZXIgewotICAgICAgICBwdWJsaWMgRGVmYXVsdEFueU5vZGVDb3VudGVyKFRyYW5zbGV0IHRyYW5zbGV0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERPTSBkb2N1bWVudCwgRFRNQXhpc0l0ZXJhdG9yIGl0ZXJhdG9yKSB7Ci0gICAgICAgICAgICBzdXBlcih0cmFuc2xldCwgZG9jdW1lbnQsIGl0ZXJhdG9yKTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q291bnRlcigpIHsKLSAgICAgICAgICAgIGludCByZXN1bHQ7Ci0gICAgICAgICAgICBpZiAoX3ZhbHVlICE9IEludGVnZXIuTUlOX1ZBTFVFKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vU2VlIEVycmF0YSBFMjQKLSAgICAgICAgICAgICAgICAgICAgaWYgKF92YWx1ZSA9PSAwKSByZXR1cm4gIjAiOwotICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChEb3VibGUuaXNOYU4oX3ZhbHVlKSkgcmV0dXJuICJOYU4iOwotICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChfdmFsdWUgPCAwICYmIERvdWJsZS5pc0luZmluaXRlKF92YWx1ZSkpIHJldHVybiAiLUluZmluaXR5IjsKLSAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoRG91YmxlLmlzSW5maW5pdGUoX3ZhbHVlKSkgcmV0dXJuICJJbmZpbml0eSI7Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UgcmVzdWx0ID0gKGludCkgX3ZhbHVlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgaW50IG5leHQgPSBfbm9kZTsKLSAgICAgICAgICAgICAgICByZXN1bHQgPSAwOwotICAgICAgICAgICAgICAgIGZpbmFsIGludCBudHlwZSA9IF9kb2N1bWVudC5nZXRFeHBhbmRlZFR5cGVJRChfbm9kZSk7Ci0gICAgICAgICAgICAgICAgZmluYWwgaW50IHJvb3QgPSBfZG9jdW1lbnQuZ2V0RG9jdW1lbnQoKTsKLSAgICAgICAgICAgICAgICB3aGlsZSAobmV4dCA+PSAwKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChudHlwZSA9PSBfZG9jdW1lbnQuZ2V0RXhwYW5kZWRUeXBlSUQobmV4dCkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCsrOwotICAgICAgICAgICAgICAgICAgICB9Ci0vLyVIWiU6ICBJcyB0aGlzIHRoZSBiZXN0IHdheSBvZiBmaW5kaW5nIHRoZSByb290PyAgSXMgaXQgYmV0dGVyIHRvIGNoZWNrCi0vLyVIWiU6ICBwYXJlbnQobmV4dCk/Ci0gICAgICAgICAgICAgICAgICAgIGlmIChuZXh0ID09IHJvb3QpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgLS1uZXh0OwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIGZvcm1hdE51bWJlcnMocmVzdWx0KTsKLSAgICAgICAgfQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvZG9tL0FycmF5Tm9kZUxpc3RJdGVyYXRvci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vQXJyYXlOb2RlTGlzdEl0ZXJhdG9yLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGQ3Y2YzYTUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vQXJyYXlOb2RlTGlzdEl0ZXJhdG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5MSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLS8qCi0gKiAkSWQ6IEFycmF5Tm9kZUxpc3RJdGVyYXRvci5qYXZhLHYgMS4wIDIwMDktMTEtMjUgMDQ6MzQ6MjQgam9laHcgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuZG9tOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNQXhpc0l0ZXJhdG9yOwotCi1wdWJsaWMgY2xhc3MgQXJyYXlOb2RlTGlzdEl0ZXJhdG9yIGltcGxlbWVudHMgRFRNQXhpc0l0ZXJhdG9yICB7Ci0KLSAgICBwcml2YXRlIGludCBfcG9zID0gMDsKLQotICAgIHByaXZhdGUgaW50IF9tYXJrID0gMDsKLQotICAgIHByaXZhdGUgaW50IF9ub2Rlc1tdOwotCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50W10gRU1QVFkgPSB7IH07Ci0KLSAgICBwdWJsaWMgQXJyYXlOb2RlTGlzdEl0ZXJhdG9yKGludFtdIG5vZGVzKSB7Ci0gICAgICAgIF9ub2RlcyA9IG5vZGVzOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgbmV4dCgpIHsKLSAgICAgICAgcmV0dXJuIF9wb3MgPCBfbm9kZXMubGVuZ3RoID8gX25vZGVzW19wb3MrK10gOiBFTkQ7Ci0gICAgfQotCi0gICAgcHVibGljIERUTUF4aXNJdGVyYXRvciByZXNldCgpIHsKLSAgICAgICAgX3BvcyA9IDA7Ci0gICAgICAgIHJldHVybiB0aGlzOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgZ2V0TGFzdCgpIHsKLSAgICAgICAgcmV0dXJuIF9ub2Rlcy5sZW5ndGg7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBnZXRQb3NpdGlvbigpIHsKLSAgICAgICAgcmV0dXJuIF9wb3M7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0TWFyaygpIHsKLSAgICAgICAgX21hcmsgPSBfcG9zOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGdvdG9NYXJrKCkgewotICAgICAgICBfcG9zID0gX21hcms7Ci0gICAgfQotCi0gICAgcHVibGljIERUTUF4aXNJdGVyYXRvciBzZXRTdGFydE5vZGUoaW50IG5vZGUpIHsKLSAgICAgICAgaWYgKG5vZGUgPT0gRU5EKSBfbm9kZXMgPSBFTVBUWTsKLSAgICAgICAgcmV0dXJuIHRoaXM7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBnZXRTdGFydE5vZGUoKSB7Ci0gICAgICAgIHJldHVybiBFTkQ7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gaXNSZXZlcnNlKCkgewotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgcHVibGljIERUTUF4aXNJdGVyYXRvciBjbG9uZUl0ZXJhdG9yKCkgewotICAgICAgICByZXR1cm4gbmV3IEFycmF5Tm9kZUxpc3RJdGVyYXRvcihfbm9kZXMpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldFJlc3RhcnRhYmxlKGJvb2xlYW4gaXNSZXN0YXJ0YWJsZSkgewotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgZ2V0Tm9kZUJ5UG9zaXRpb24oaW50IHBvc2l0aW9uKSB7Ci0gICAgICAgIHJldHVybiBfbm9kZXNbcG9zaXRpb24gLSAxXTsKLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvZG9tL0JpdEFycmF5LmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2RvbS9CaXRBcnJheS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhYWRmYjU0Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvZG9tL0JpdEFycmF5LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyNjggKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogQml0QXJyYXkuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8wNiAwNTo1Njo1MiBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuZG9tOwotCi1pbXBvcnQgamF2YS5pby5FeHRlcm5hbGl6YWJsZTsKLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotaW1wb3J0IGphdmEuaW8uT2JqZWN0SW5wdXQ7Ci1pbXBvcnQgamF2YS5pby5PYmplY3RPdXRwdXQ7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1BeGlzSXRlcmF0b3I7Ci0KLQotLyoqCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqLwotcHVibGljIGNsYXNzIEJpdEFycmF5IGltcGxlbWVudHMgRXh0ZXJuYWxpemFibGUgewotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNDg3NjAxOTg4MDcwODM3NzY2M0w7Ci0KLSAgICBwcml2YXRlIGludFtdIF9iaXRzOwotICAgIHByaXZhdGUgaW50ICAgX2JpdFNpemU7Ci0gICAgcHJpdmF0ZSBpbnQgICBfaW50U2l6ZTsKLSAgICBwcml2YXRlIGludCAgIF9tYXNrOwotCi0gICAgLy8gVGhpcyB0YWJsZSBpcyB1c2VkIHRvIHByZXZlbnQgZXhwZW5zaXZlIHNoaWZ0IG9wZXJhdGlvbnMKLSAgICAvLyAoVGhlc2Ugb3BlcmF0aW9ucyBhcmUgaW5leHBlbnNpdmUgb24gQ1BVcyBidXQgdmVyeSBleHBlbnNpdmUgb24gSlZNcy4pCi0gICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgaW50W10gX21hc2tzID0gewotICAgICAgICAweDgwMDAwMDAwLCAweDQwMDAwMDAwLCAweDIwMDAwMDAwLCAweDEwMDAwMDAwLAotICAgICAgICAweDA4MDAwMDAwLCAweDA0MDAwMDAwLCAweDAyMDAwMDAwLCAweDAxMDAwMDAwLAotICAgICAgICAweDAwODAwMDAwLCAweDAwNDAwMDAwLCAweDAwMjAwMDAwLCAweDAwMTAwMDAwLAotICAgICAgICAweDAwMDgwMDAwLCAweDAwMDQwMDAwLCAweDAwMDIwMDAwLCAweDAwMDEwMDAwLAotICAgICAgICAweDAwMDA4MDAwLCAweDAwMDA0MDAwLCAweDAwMDAyMDAwLCAweDAwMDAxMDAwLAotICAgICAgICAweDAwMDAwODAwLCAweDAwMDAwNDAwLCAweDAwMDAwMjAwLCAweDAwMDAwMTAwLAotICAgICAgICAweDAwMDAwMDgwLCAweDAwMDAwMDQwLCAweDAwMDAwMDIwLCAweDAwMDAwMDEwLAotICAgICAgICAweDAwMDAwMDA4LCAweDAwMDAwMDA0LCAweDAwMDAwMDAyLCAweDAwMDAwMDAxIH07Ci0KLSAgICBwcml2YXRlIGZpbmFsIHN0YXRpYyBib29sZWFuIERFQlVHX0FTU0VSVElPTlMgPSBmYWxzZTsKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdG9yLiBEZWZpbmVzIHRoZSBpbml0aWFsIHNpemUgb2YgdGhlIGJpdCBhcnJheSAoaW4gYml0cykuCi0gICAgICovCi0gICAgcHVibGljIEJpdEFycmF5KCkgewotICAgICAgICB0aGlzKDMyKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgQml0QXJyYXkoaW50IHNpemUpIHsKLSAgICAgICAgaWYgKHNpemUgPCAzMikgc2l6ZSA9IDMyOwotICAgICAgICBfYml0U2l6ZSA9IHNpemU7Ci0gICAgICAgIF9pbnRTaXplID0gKF9iaXRTaXplID4+PiA1KSArIDE7Ci0gICAgICAgIF9iaXRzID0gbmV3IGludFtfaW50U2l6ZSArIDFdOwotICAgIH0KLQotICAgIHB1YmxpYyBCaXRBcnJheShpbnQgc2l6ZSwgaW50W10gYml0cykgewotICAgICAgICBpZiAoc2l6ZSA8IDMyKSBzaXplID0gMzI7Ci0gICAgICAgIF9iaXRTaXplID0gc2l6ZTsKLSAgICAgICAgX2ludFNpemUgPSAoX2JpdFNpemUgPj4+IDUpICsgMTsKLSAgICAgICAgX2JpdHMgPSBiaXRzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldCB0aGUgbWFzayBmb3IgdGhpcyBiaXQgYXJyYXkuIFRoZSB1cHBlciA4IGJpdHMgb2YgdGhpcyBtYXNrCi0gICAgICogaW5kaWNhdGUgdGhlIERPTSBpbiB3aGljaCB0aGUgbm9kZXMgaW4gdGhpcyBhcnJheSBiZWxvbmcuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0TWFzayhpbnQgbWFzaykgewotICAgICAgICBfbWFzayA9IG1hc2s7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2VlIHNldE1hc2soKQotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0TWFzaygpIHsKLSAgICAgICAgcmV0dXJuKF9tYXNrKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBzaXplIG9mIHRoaXMgYml0IGFycmF5IChpbiBiaXRzKS4KLSAgICAgKi8KLSAgICBwdWJsaWMgZmluYWwgaW50IHNpemUoKSB7Ci0gICAgICAgIHJldHVybihfYml0U2l6ZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiBiaXQgaXMgc2V0Ci0gICAgICovCi0gICAgcHVibGljIGZpbmFsIGJvb2xlYW4gZ2V0Qml0KGludCBiaXQpIHsKLSAgICAgICAgaWYgKERFQlVHX0FTU0VSVElPTlMpIHsKLSAgICAgICAgICAgIGlmIChiaXQgPj0gX2JpdFNpemUpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICJQcm9ncmFtbWVyJ3MgYXNzZXJ0aW9uIGluICBCaXRBcnJheS5nZXRCaXQiKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybigoX2JpdHNbYml0Pj4+NV0gJiBfbWFza3NbYml0JTMyXSkgIT0gMCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgbmV4dCBzZXQgYml0IGZyb20gYSBnaXZlbiBwb3NpdGlvbgotICAgICAqLwotICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0TmV4dEJpdChpbnQgc3RhcnRCaXQpIHsKLSAgICAgICAgZm9yIChpbnQgaSA9IChzdGFydEJpdCA+Pj4gNSkgOyBpPD1faW50U2l6ZTsgaSsrKSB7Ci0gICAgICAgICAgICBpbnQgYml0cyA9IF9iaXRzW2ldOwotICAgICAgICAgICAgaWYgKGJpdHMgIT0gMCkgewotICAgICAgICAgICAgICAgIGZvciAoaW50IGIgPSAoc3RhcnRCaXQgJSAzMik7IGI8MzI7IGIrKykgewotICAgICAgICAgICAgICAgICAgICBpZiAoKGJpdHMgJiBfbWFza3NbYl0pICE9IDApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybigoaSA8PCA1KSArIGIpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgc3RhcnRCaXQgPSAwOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybihEVE1BeGlzSXRlcmF0b3IuRU5EKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCByZXR1cm5zIHRoZSBOdGggYml0IHRoYXQgaXMgc2V0IGluIHRoZSBiaXQgYXJyYXkuIFRoZQotICAgICAqIGN1cnJlbnQgcG9zaXRpb24gaXMgY2FjaGVkIGluIHRoZSBmb2xsb3dpbmcgNCB2YXJpYWJsZXMgYW5kIHdpbGwKLSAgICAgKiBoZWxwIHNwZWVkIHVwIGEgc2VxdWVuY2Ugb2YgbmV4dCgpIGNhbGwgaW4gYW4gaW5kZXggaXRlcmF0b3IuIFRoaXMKLSAgICAgKiBtZXRob2QgaXMgYSBtZXNzLCBidXQgaXQgaXMgZmFzdCBhbmQgaXQgd29ya3MsIHNvIGRvbid0IGZ1Y2sgd2l0aCBpdC4KLSAgICAgKi8KLSAgICBwcml2YXRlIGludCBfcG9zID0gSW50ZWdlci5NQVhfVkFMVUU7Ci0gICAgcHJpdmF0ZSBpbnQgX25vZGUgPSAwOwotICAgIHByaXZhdGUgaW50IF9pbnQgPSAwOwotICAgIHByaXZhdGUgaW50IF9iaXQgPSAwOwotCi0gICAgcHVibGljIGZpbmFsIGludCBnZXRCaXROdW1iZXIoaW50IHBvcykgewotCi0gICAgICAgIC8vIFJldHVybiBsYXN0IG5vZGUgaWYgcG9zaXRpb24gd2UncmUgbG9va2luZyBmb3IgaXMgdGhlIHNhbWUKLSAgICAgICAgaWYgKHBvcyA9PSBfcG9zKSByZXR1cm4oX25vZGUpOwotCi0gICAgICAgIC8vIFN0YXJ0IGZyb20gYmVnaW5uaW5nIG9mIHBvc2l0aW9uIHdlJ3JlIGxvb2tpbmcgZm9yIGlzIGJlZm9yZQotICAgICAgICAvLyB0aGUgcG9pbnQgd2hlcmUgd2UgbGVmdCBvZmYgdGhlIGxhc3QgdGltZS4KLSAgICAgICAgaWYgKHBvcyA8IF9wb3MpIHsKLSAgICAgICAgICAgIF9pbnQgPSBfYml0ID0gX3BvcyA9IDA7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBTY2FuIHRocm91Z2ggdGhlIGJpdCBhcnJheSAtIHNraXAgaW50ZWdlcnMgdGhhdCBoYXZlIG5vIGJpdHMgc2V0Ci0gICAgICAgIGZvciAoIDsgX2ludCA8PSBfaW50U2l6ZTsgX2ludCsrKSB7Ci0gICAgICAgICAgICBpbnQgYml0cyA9IF9iaXRzW19pbnRdOwotICAgICAgICAgICAgaWYgKGJpdHMgIT0gMCkgeyAvLyBBbnkgYml0cyBzZXQ/Ci0gICAgICAgICAgICAgICAgZm9yICggOyBfYml0IDwgMzI7IF9iaXQrKykgewotICAgICAgICAgICAgICAgICAgICBpZiAoKGJpdHMgJiBfbWFza3NbX2JpdF0pICE9IDApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmICgrK19wb3MgPT0gcG9zKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgX25vZGUgPSAoKF9pbnQgPDwgNSkgKyBfYml0KSAtIDE7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChfbm9kZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgX2JpdCA9IDA7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuKDApOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIGludGVnZXIgYXJyYXkgaW4gd2hpY2ggdGhlIGJpdCBhcnJheSBpcyBjb250YWluZWQKLSAgICAgKi8KLSAgICBwdWJsaWMgZmluYWwgaW50W10gZGF0YSgpIHsKLSAgICAgICAgcmV0dXJuKF9iaXRzKTsKLSAgICB9Ci0KLSAgICBpbnQgX2ZpcnN0ID0gSW50ZWdlci5NQVhfVkFMVUU7IC8vIFRoZSBpbmRleCB3aGVyZSBmaXJzdCBzZXQgYml0IGlzCi0gICAgaW50IF9sYXN0ICA9IEludGVnZXIuTUlOX1ZBTFVFOyAvLyBUaGUgX0lOVEVHRVIgSU5ERVhfIHdoZXJlIGxhc3Qgc2V0IGJpdCBpcwotCi0gICAgLyoqCi0gICAgICogU2V0cyBhIGdpdmVuIGJpdAotICAgICAqLwotICAgIHB1YmxpYyBmaW5hbCB2b2lkIHNldEJpdChpbnQgYml0KSB7Ci0gICAgICAgIGlmIChERUJVR19BU1NFUlRJT05TKSB7Ci0gICAgICAgICAgICBpZiAoYml0ID49IF9iaXRTaXplKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUHJvZ3JhbW1lcidzIGFzc2VydGlvbiBpbiAgQml0QXJyYXkuZ2V0Qml0Iik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoYml0ID49IF9iaXRTaXplKSByZXR1cm47Ci0gICAgICAgIGZpbmFsIGludCBpID0gKGJpdCA+Pj4gNSk7Ci0gICAgICAgIGlmIChpIDwgX2ZpcnN0KSBfZmlyc3QgPSBpOwotICAgICAgICBpZiAoaSA+IF9sYXN0KSBfbGFzdCA9IGk7Ci0gICAgICAgIF9iaXRzW2ldIHw9IF9tYXNrc1tiaXQgJSAzMl07Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogTWVyZ2UgdHdvIGJpdCBhcnJheXMuIFRoaXMgY3VycmVudGx5IG9ubHkgd29ya3MgZm9yIG5vZGVzIGZyb20KLSAgICAgKiBhIHNpbmdsZSBET00gKGJlY2F1c2UgdGhlcmUgaXMgb25seSBvbmUgX21hc2sgcGVyIGFycmF5KS4KLSAgICAgKi8KLSAgICBwdWJsaWMgZmluYWwgQml0QXJyYXkgbWVyZ2UoQml0QXJyYXkgb3RoZXIpIHsKLSAgICAgICAgLy8gVGFrZSBvdGhlciBhcnJheSdzIGJpdHMgaWYgd2UgaGF2ZSBub2RlIHNldAotICAgICAgICBpZiAoX2xhc3QgPT0gLTEpIHsKLSAgICAgICAgICAgIF9iaXRzID0gb3RoZXIuX2JpdHM7Ci0gICAgICAgIH0KLSAgICAgICAgLy8gT25seSBtZXJnZSBpZiBvdGhlciBhcnJheSBoYXMgYW55IGJpdHMgc2V0Ci0gICAgICAgIGVsc2UgaWYgKG90aGVyLl9sYXN0ICE9IC0xKSB7Ci0gICAgICAgICAgICBpbnQgc3RhcnQgPSAoX2ZpcnN0IDwgb3RoZXIuX2ZpcnN0KSA/IF9maXJzdCA6IG90aGVyLl9maXJzdDsKLSAgICAgICAgICAgIGludCBzdG9wICA9IChfbGFzdCA+IG90aGVyLl9sYXN0KSA/IF9sYXN0IDogb3RoZXIuX2xhc3Q7Ci0KLSAgICAgICAgICAgIC8vIE1lcmdlIHRoZXNlIGJpdHMgaW50byBvdGhlciBhcnJheSBpZiBvdGhlciBhcnJheSBpcyBsYXJnZXIKLSAgICAgICAgICAgIGlmIChvdGhlci5faW50U2l6ZSA+IF9pbnRTaXplKSB7Ci0gICAgICAgICAgICAgICAgaWYgKHN0b3AgPiBfaW50U2l6ZSkgc3RvcCA9IF9pbnRTaXplOwotICAgICAgICAgICAgICAgIGZvciAoaW50IGk9c3RhcnQ7IGk8PXN0b3A7IGkrKykKLSAgICAgICAgICAgICAgICAgICAgb3RoZXIuX2JpdHNbaV0gfD0gX2JpdHNbaV07Ci0gICAgICAgICAgICAgICAgX2JpdHMgPSBvdGhlci5fYml0czsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIE1lcmdlIG90aGVyIGJpdHMgaW50byB0aGlzIGFycmF5IGlmIHRoaXMgYXJyYWkgaXMgbGFyZ2UvZXF1YWwuCi0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBpZiAoc3RvcCA+IG90aGVyLl9pbnRTaXplKSBzdG9wID0gb3RoZXIuX2ludFNpemU7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaT1zdGFydDsgaTw9c3RvcDsgaSsrKQotICAgICAgICAgICAgICAgICAgICBfYml0c1tpXSB8PSBvdGhlci5fYml0c1tpXTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4odGhpcyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmVzaXplcyB0aGUgYml0IGFycmF5IC0gdHJ5IHRvIGF2b2lkIHVzaW5nIHRoaXMgbWV0aG9kISEhCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIHZvaWQgcmVzaXplKGludCBuZXdTaXplKSB7Ci0gICAgICAgIGlmIChuZXdTaXplID4gX2JpdFNpemUpIHsKLSAgICAgICAgICAgIF9pbnRTaXplID0gKG5ld1NpemUgPj4+IDUpICsgMTsKLSAgICAgICAgICAgIGZpbmFsIGludFtdIG5ld0JpdHMgPSBuZXcgaW50W19pbnRTaXplICsgMV07Ci0gICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KF9iaXRzLCAwLCBuZXdCaXRzLCAwLCAoX2JpdFNpemU+Pj41KSArIDEpOwotICAgICAgICAgICAgX2JpdHMgPSBuZXdCaXRzOwotICAgICAgICAgICAgX2JpdFNpemUgPSBuZXdTaXplOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIEJpdEFycmF5IGNsb25lQXJyYXkoKSB7Ci0gICAgICAgIHJldHVybihuZXcgQml0QXJyYXkoX2ludFNpemUsIF9iaXRzKSk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgd3JpdGVFeHRlcm5hbChPYmplY3RPdXRwdXQgb3V0KSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgICAgICBvdXQud3JpdGVJbnQoX2JpdFNpemUpOwotICAgICAgICBvdXQud3JpdGVJbnQoX21hc2spOwotICAgICAgICBvdXQud3JpdGVPYmplY3QoX2JpdHMpOwotICAgICAgICBvdXQuZmx1c2goKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZWFkIHRoZSB3aG9sZSB0cmVlIGZyb20gYSBmaWxlIChzZXJpYWxpemVkKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHJlYWRFeHRlcm5hbChPYmplY3RJbnB1dCBpbikKLSAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHsKLSAgICAgICAgX2JpdFNpemUgPSBpbi5yZWFkSW50KCk7Ci0gICAgICAgIF9pbnRTaXplID0gKF9iaXRTaXplID4+PiA1KSArIDE7Ci0gICAgICAgIF9tYXNrICAgID0gaW4ucmVhZEludCgpOwotICAgICAgICBfYml0cyAgICA9IChpbnRbXSlpbi5yZWFkT2JqZWN0KCk7Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2RvbS9DYWNoZWROb2RlTGlzdEl0ZXJhdG9yLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2RvbS9DYWNoZWROb2RlTGlzdEl0ZXJhdG9yLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDNhM2VkOTMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vQ2FjaGVkTm9kZUxpc3RJdGVyYXRvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTE1ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IENhY2hlZE5vZGVMaXN0SXRlcmF0b3IuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8wNiAwNTo1Nzo0NyBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuZG9tOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNQXhpc0l0ZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLnJlZi5EVE1BeGlzSXRlcmF0b3JCYXNlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy51dGlsLkludGVnZXJBcnJheTsKLQotLyoqCi0gKiBDYWNoZWROb2RlTGlzdEl0ZXJhdG9yIGlzIHVzZWQgZm9yIHNlbGVjdCBleHByZXNzaW9ucyBpbiBhCi0gKiB2YXJpYWJsZSBvciBwYXJhbWV0ZXIuIFRoaXMgaXRlcmF0b3IgY2FjaGVzIGFsbCBub2RlcyBpbiBhbgotICogSW50ZWdlckFycmF5LiBJdHMgY2xvbmVJdGVyYXRvcigpIG1ldGhvZCBpcyBvdmVycmlkZGVuIHRvCi0gKiByZXR1cm4gYW4gb2JqZWN0IG9mIENsb25lZE5vZGVMaXN0SXRlcmF0b3IuCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBDYWNoZWROb2RlTGlzdEl0ZXJhdG9yIGV4dGVuZHMgRFRNQXhpc0l0ZXJhdG9yQmFzZSB7Ci0KLSAgICAvKioKLSAgICAgKiBTb3VyY2UgZm9yIHRoaXMgaXRlcmF0b3IuCi0gICAgICovCi0gICAgcHJpdmF0ZSBEVE1BeGlzSXRlcmF0b3IgX3NvdXJjZTsKLSAgICBwcml2YXRlIEludGVnZXJBcnJheSBfbm9kZXMgPSBuZXcgSW50ZWdlckFycmF5KCk7Ci0gICAgcHJpdmF0ZSBpbnQgX251bUNhY2hlZE5vZGVzID0gMDsKLSAgICBwcml2YXRlIGludCBfaW5kZXggPSAwOwotICAgIHByaXZhdGUgYm9vbGVhbiBfaXNFbmRlZCA9IGZhbHNlOwotCi0gICAgcHVibGljIENhY2hlZE5vZGVMaXN0SXRlcmF0b3IoRFRNQXhpc0l0ZXJhdG9yIHNvdXJjZSkgewotICAgICAgICBfc291cmNlID0gc291cmNlOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldFJlc3RhcnRhYmxlKGJvb2xlYW4gaXNSZXN0YXJ0YWJsZSkgewotICAgICAgICAvL19pc1Jlc3RhcnRhYmxlID0gaXNSZXN0YXJ0YWJsZTsKLSAgICAgICAgLy9fc291cmNlLnNldFJlc3RhcnRhYmxlKGlzUmVzdGFydGFibGUpOwotICAgIH0KLQotICAgIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3Igc2V0U3RhcnROb2RlKGludCBub2RlKSB7Ci0gICAgICAgIGlmIChfaXNSZXN0YXJ0YWJsZSkgewotICAgICAgICAgICAgX3N0YXJ0Tm9kZSA9IG5vZGU7Ci0gICAgICAgICAgICBfc291cmNlLnNldFN0YXJ0Tm9kZShub2RlKTsKLSAgICAgICAgICAgIHJlc2V0UG9zaXRpb24oKTsKLQotICAgICAgICAgICAgX2lzUmVzdGFydGFibGUgPSBmYWxzZTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gdGhpczsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IG5leHQoKSB7Ci0gICAgICAgIHJldHVybiBnZXROb2RlKF9pbmRleCsrKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldFBvc2l0aW9uKCkgewotICAgICAgICByZXR1cm4gX2luZGV4ID09IDAgPyAxIDogX2luZGV4OwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgZ2V0Tm9kZUJ5UG9zaXRpb24oaW50IHBvcykgewotICAgICAgICByZXR1cm4gZ2V0Tm9kZShwb3MpOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgZ2V0Tm9kZShpbnQgaW5kZXgpIHsKLSAgICAgICAgaWYgKGluZGV4IDwgX251bUNhY2hlZE5vZGVzKSB7Ci0gICAgICAgICAgICByZXR1cm4gX25vZGVzLmF0KGluZGV4KTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICghX2lzRW5kZWQpewotICAgICAgICAgICAgaW50IG5vZGUgPSBfc291cmNlLm5leHQoKTsKLSAgICAgICAgICAgIGlmIChub2RlICE9IEVORCkgewotICAgICAgICAgICAgICAgIF9ub2Rlcy5hZGQobm9kZSk7Ci0gICAgICAgICAgICAgICAgX251bUNhY2hlZE5vZGVzKys7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBfaXNFbmRlZCA9IHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gbm9kZTsKLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgICAgICByZXR1cm4gRU5EOwotICAgIH0KLQotICAgIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3IgY2xvbmVJdGVyYXRvcigpIHsKLSAgICAgICAgQ2xvbmVkTm9kZUxpc3RJdGVyYXRvciBjbG9uZSA9IG5ldyBDbG9uZWROb2RlTGlzdEl0ZXJhdG9yKHRoaXMpOwotICAgICAgICByZXR1cm4gY2xvbmU7Ci0gICAgfQotCi0gICAgcHVibGljIERUTUF4aXNJdGVyYXRvciByZXNldCgpIHsKLSAgICAgICAgX2luZGV4ID0gMDsKLSAgICAgICAgcmV0dXJuIHRoaXM7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0TWFyaygpIHsKLSAgICAgICAgX3NvdXJjZS5zZXRNYXJrKCk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgZ290b01hcmsoKSB7Ci0gICAgICAgIF9zb3VyY2UuZ290b01hcmsoKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2RvbS9DbG9uZWROb2RlTGlzdEl0ZXJhdG9yLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2RvbS9DbG9uZWROb2RlTGlzdEl0ZXJhdG9yLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDcxZDU5NDkuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vQ2xvbmVkTm9kZUxpc3RJdGVyYXRvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsODMgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogQ2xvbmVkTm9kZUxpc3RJdGVyYXRvci5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzA2IDA2OjAyOjEyIHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5kb207Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1BeGlzSXRlcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0ucmVmLkRUTUF4aXNJdGVyYXRvckJhc2U7Ci0KLS8qKgotICogQSBDbG9uZWROb2RlTGlzdEl0ZXJhdG9yIGlzIHJldHVybmVkIGJ5IHRoZSBjbG9uZUl0ZXJhdG9yKCkgbWV0aG9kCi0gKiBvZiBhIENhY2hlZE5vZGVMaXN0SXRlcmF0b3IuIEl0cyBuZXh0KCkgbWV0aG9kIHJldHJpZXZlcyB0aGUgbm9kZXMgZnJvbQotICogdGhlIGNhY2hlIG9mIHRoZSBDYWNoZWROb2RlTGlzdEl0ZXJhdG9yLgotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgQ2xvbmVkTm9kZUxpc3RJdGVyYXRvciBleHRlbmRzIERUTUF4aXNJdGVyYXRvckJhc2UgewotCi0gICAgLyoqCi0gICAgICogU291cmNlIGZvciB0aGlzIGl0ZXJhdG9yLgotICAgICAqLwotICAgIHByaXZhdGUgQ2FjaGVkTm9kZUxpc3RJdGVyYXRvciBfc291cmNlOwotICAgIHByaXZhdGUgaW50IF9pbmRleCA9IDA7Ci0KLSAgICBwdWJsaWMgQ2xvbmVkTm9kZUxpc3RJdGVyYXRvcihDYWNoZWROb2RlTGlzdEl0ZXJhdG9yIHNvdXJjZSkgewotICAgICAgICBfc291cmNlID0gc291cmNlOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldFJlc3RhcnRhYmxlKGJvb2xlYW4gaXNSZXN0YXJ0YWJsZSkgewotICAgICAgICAvL19pc1Jlc3RhcnRhYmxlID0gaXNSZXN0YXJ0YWJsZTsKLSAgICAgICAgLy9fc291cmNlLnNldFJlc3RhcnRhYmxlKGlzUmVzdGFydGFibGUpOwotICAgIH0KLQotICAgIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3Igc2V0U3RhcnROb2RlKGludCBub2RlKSB7Ci0gICAgICAgIHJldHVybiB0aGlzOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgbmV4dCgpIHsKLSAgICAgICAgcmV0dXJuIF9zb3VyY2UuZ2V0Tm9kZShfaW5kZXgrKyk7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBnZXRQb3NpdGlvbigpIHsKLSAgICAgICAgcmV0dXJuIF9pbmRleCA9PSAwID8gMSA6IF9pbmRleDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldE5vZGVCeVBvc2l0aW9uKGludCBwb3MpIHsKLSAgICAgICAgcmV0dXJuIF9zb3VyY2UuZ2V0Tm9kZShwb3MpOwotICAgIH0KLQotICAgIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3IgY2xvbmVJdGVyYXRvcigpIHsKLSAgICAgICAgcmV0dXJuIF9zb3VyY2UuY2xvbmVJdGVyYXRvcigpOwotICAgIH0KLQotICAgIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3IgcmVzZXQoKSB7Ci0gICAgICAgIF9pbmRleCA9IDA7Ci0gICAgICAgIHJldHVybiB0aGlzOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldE1hcmsoKSB7Ci0gICAgICAgIF9zb3VyY2Uuc2V0TWFyaygpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGdvdG9NYXJrKCkgewotICAgICAgICBfc291cmNlLmdvdG9NYXJrKCk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vQ29sbGF0b3JGYWN0b3J5QmFzZS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vQ29sbGF0b3JGYWN0b3J5QmFzZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4M2QzOTRlLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvZG9tL0NvbGxhdG9yRmFjdG9yeUJhc2UuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDUyICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IENvbGxhdG9yRmFjdG9yeUJhc2UuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8wNiAwNjowMzowOCBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuZG9tOwotCi1pbXBvcnQgamF2YS50ZXh0LkNvbGxhdG9yOwotaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuQ29sbGF0b3JGYWN0b3J5OwotCi0vKioKLSAqIEBhdXRob3IgVy4gRWxpb3QgS2ltYmVyIChlbGlvdEBpc29nZW4uY29tKQotICovCi1wdWJsaWMgY2xhc3MgQ29sbGF0b3JGYWN0b3J5QmFzZSBpbXBsZW1lbnRzIENvbGxhdG9yRmFjdG9yeSB7Ci0KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIExvY2FsZSBERUZBVUxUX0xPQ0FMRSA9IExvY2FsZS5nZXREZWZhdWx0KCk7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBDb2xsYXRvciBERUZBVUxUX0NPTExBVE9SID0gQ29sbGF0b3IuZ2V0SW5zdGFuY2UoKTsKLQotICAgIHB1YmxpYyBDb2xsYXRvckZhY3RvcnlCYXNlKCkgewotICAgIH0KLQotICAgIHB1YmxpYyBDb2xsYXRvciBnZXRDb2xsYXRvcihTdHJpbmcgbGFuZywgU3RyaW5nIGNvdW50cnkpIHsKLSAgICAgICAgcmV0dXJuIENvbGxhdG9yLmdldEluc3RhbmNlKG5ldyBMb2NhbGUobGFuZywgY291bnRyeSkpOwotICAgIH0KLQotICAgIHB1YmxpYyBDb2xsYXRvciBnZXRDb2xsYXRvcihMb2NhbGUgbG9jYWxlKSB7Ci0gICAgICAgIGlmIChsb2NhbGUgPT0gREVGQVVMVF9MT0NBTEUpCi0gICAgICAgICAgICByZXR1cm4gREVGQVVMVF9DT0xMQVRPUjsKLSAgICAgICAgZWxzZQotICAgICAgICAgICAgcmV0dXJuIENvbGxhdG9yLmdldEluc3RhbmNlKGxvY2FsZSk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vQ3VycmVudE5vZGVMaXN0RmlsdGVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2RvbS9DdXJyZW50Tm9kZUxpc3RGaWx0ZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNTQ1N2JlNS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2RvbS9DdXJyZW50Tm9kZUxpc3RGaWx0ZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDM3ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IEN1cnJlbnROb2RlTGlzdEZpbHRlci5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzA2IDA2OjA0OjA2IHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5kb207Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMucnVudGltZS5BYnN0cmFjdFRyYW5zbGV0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTUF4aXNJdGVyYXRvcjsKLQotLyoqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqLwotcHVibGljIGludGVyZmFjZSBDdXJyZW50Tm9kZUxpc3RGaWx0ZXIgewotICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIHRlc3QoaW50IG5vZGUsIGludCBwb3NpdGlvbiwgaW50IGxhc3QsIGludCBjdXJyZW50LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQWJzdHJhY3RUcmFuc2xldCB0cmFuc2xldCwgRFRNQXhpc0l0ZXJhdG9yIGl0ZXIpOwotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vQ3VycmVudE5vZGVMaXN0SXRlcmF0b3IuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvZG9tL0N1cnJlbnROb2RlTGlzdEl0ZXJhdG9yLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDUxMmUxZTkuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vQ3VycmVudE5vZGVMaXN0SXRlcmF0b3IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIwMSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBDdXJyZW50Tm9kZUxpc3RJdGVyYXRvci5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzA2IDA2OjA0OjQ1IHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5kb207Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMucnVudGltZS5BYnN0cmFjdFRyYW5zbGV0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5ydW50aW1lLkJhc2lzTGlicmFyeTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMudXRpbC5JbnRlZ2VyQXJyYXk7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNQXhpc0l0ZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLnJlZi5EVE1BeGlzSXRlcmF0b3JCYXNlOwotCi0vKioKLSAqIEl0ZXJhdG9ycyBvZiB0aGlzIGtpbmQgdXNlIGEgQ3VycmVudE5vZGVMaXN0RmlsdGVyIHRvIGZpbHRlciBhIHN1YnNldCBvZgotICogbm9kZXMgZnJvbSBhIHNvdXJjZSBpdGVyYXRvci4gRm9yIGVhY2ggbm9kZSBmcm9tIHRoZSBzb3VyY2UsIHRoZSBib29sZWFuCi0gKiBtZXRob2QgQ3VycmVudE5vZGVMaXN0RmlsdGVyLnRlc3QoKSBpcyBjYWxsZWQuCi0gKgotICogQWxsIG5vZGVzIGZyb20gdGhlIHNvdXJjZSBhcmUgcmVhZCBpbnRvIGFuIGFycmF5IHVwb24gY2FsbGluZyBzZXRTdGFydE5vZGUoKQotICogKHRoaXMgaXMgbmVlZGVkIHRvIGRldGVybWluZSB0aGUgdmFsdWUgb2YgbGFzdCwgYSBwYXJhbWV0ZXIgdG8KLSAqIEN1cnJlbnROb2RlTGlzdEZpbHRlci50ZXN0KCkpLiBUaGUgbWV0aG9kIGdldExhc3QoKSByZXR1cm5zIHRoZSBsYXN0IGVsZW1lbnQKLSAqIGFmdGVyIGFwcGx5aW5nIHRoZSBmaWx0ZXIuCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqLwotCi1wdWJsaWMgZmluYWwgY2xhc3MgQ3VycmVudE5vZGVMaXN0SXRlcmF0b3IgZXh0ZW5kcyBEVE1BeGlzSXRlcmF0b3JCYXNlIHsKLSAgICAvKioKLSAgICAgKiBBIGZsYWcgaW5kaWNhdGluZyBpZiBub2RlcyBhcmUgcmV0dXJuZWQgaW4gZG9jdW1lbnQgb3JkZXIuCi0gICAgICovCi0gICAgcHJpdmF0ZSBib29sZWFuIF9kb2NPcmRlcjsKLQotICAgIC8qKgotICAgICAqIFRoZSBzb3VyY2UgZm9yIHRoaXMgaXRlcmF0b3IuCi0gICAgICovCi0gICAgcHJpdmF0ZSBEVE1BeGlzSXRlcmF0b3IgX3NvdXJjZTsKLQotICAgIC8qKgotICAgICAqIEEgcmVmZXJlbmNlIHRvIGEgZmlsdGVyIG9iamVjdC4KLSAgICAgKi8KLSAgICBwcml2YXRlIGZpbmFsIEN1cnJlbnROb2RlTGlzdEZpbHRlciBfZmlsdGVyOwotCi0gICAgLyoqCi0gICAgICogQW4gaW50ZWdlciBhcnJheSB0byBzdG9yZSBub2RlcyBmcm9tIHNvdXJjZSBpdGVyYXRvci4KLSAgICAgKi8KLSAgICBwcml2YXRlIEludGVnZXJBcnJheSBfbm9kZXMgPSBuZXcgSW50ZWdlckFycmF5KCk7Ci0KLSAgICAvKioKLSAgICAgKiBJbmRleCBpbiBfbm9kZXMgb2YgdGhlIG5leHQgbm9kZSB0byBmaWx0ZXIuCi0gICAgICovCi0gICAgcHJpdmF0ZSBpbnQgX2N1cnJlbnRJbmRleDsKLQotICAgIC8qKgotICAgICAqIFRoZSBjdXJyZW50IG5vZGUgaW4gdGhlIHN0eWxlc2hlZXQgYXQgdGhlIHRpbWUgb2YgZXZhbHVhdGlvbi4KLSAgICAgKi8KLSAgICBwcml2YXRlIGZpbmFsIGludCBfY3VycmVudE5vZGU7Ci0KLSAgICAvKioKLSAgICAgKiBBIHJlZmVyZW5jZSB0byB0aGUgdHJhbnNsZXQuCi0gICAgICovCi0gICAgcHJpdmF0ZSBBYnN0cmFjdFRyYW5zbGV0IF90cmFuc2xldDsKLQotICAgIHB1YmxpYyBDdXJyZW50Tm9kZUxpc3RJdGVyYXRvcihEVE1BeGlzSXRlcmF0b3Igc291cmNlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDdXJyZW50Tm9kZUxpc3RGaWx0ZXIgZmlsdGVyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgY3VycmVudE5vZGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFic3RyYWN0VHJhbnNsZXQgdHJhbnNsZXQpCi0gICAgewotICAgICAgICB0aGlzKHNvdXJjZSwgIXNvdXJjZS5pc1JldmVyc2UoKSwgZmlsdGVyLCBjdXJyZW50Tm9kZSwgdHJhbnNsZXQpOwotICAgIH0KLQotICAgIHB1YmxpYyBDdXJyZW50Tm9kZUxpc3RJdGVyYXRvcihEVE1BeGlzSXRlcmF0b3Igc291cmNlLCBib29sZWFuIGRvY09yZGVyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDdXJyZW50Tm9kZUxpc3RGaWx0ZXIgZmlsdGVyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgY3VycmVudE5vZGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFic3RyYWN0VHJhbnNsZXQgdHJhbnNsZXQpCi0gICAgewotICAgICAgICBfc291cmNlID0gc291cmNlOwotICAgICAgICBfZmlsdGVyID0gZmlsdGVyOwotICAgICAgICBfdHJhbnNsZXQgPSB0cmFuc2xldDsKLSAgICAgICAgX2RvY09yZGVyID0gZG9jT3JkZXI7Ci0gICAgICAgIF9jdXJyZW50Tm9kZSA9IGN1cnJlbnROb2RlOwotICAgIH0KLQotICAgIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3IgZm9yY2VOYXR1cmFsT3JkZXIoKSB7Ci0gICAgICAgIF9kb2NPcmRlciA9IHRydWU7Ci0gICAgICAgIHJldHVybiB0aGlzOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldFJlc3RhcnRhYmxlKGJvb2xlYW4gaXNSZXN0YXJ0YWJsZSkgewotICAgICAgICBfaXNSZXN0YXJ0YWJsZSA9IGlzUmVzdGFydGFibGU7Ci0gICAgICAgIF9zb3VyY2Uuc2V0UmVzdGFydGFibGUoaXNSZXN0YXJ0YWJsZSk7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gaXNSZXZlcnNlKCkgewotICAgICAgICByZXR1cm4gIV9kb2NPcmRlcjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIGNsb25lSXRlcmF0b3IoKSB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBmaW5hbCBDdXJyZW50Tm9kZUxpc3RJdGVyYXRvciBjbG9uZSA9Ci0gICAgICAgICAgICAgICAgKEN1cnJlbnROb2RlTGlzdEl0ZXJhdG9yKSBzdXBlci5jbG9uZSgpOwotICAgICAgICAgICAgY2xvbmUuX25vZGVzID0gKEludGVnZXJBcnJheSkgX25vZGVzLmNsb25lKCk7Ci0gICAgICAgICAgICBjbG9uZS5fc291cmNlID0gX3NvdXJjZS5jbG9uZUl0ZXJhdG9yKCk7Ci0gICAgICAgICAgICBjbG9uZS5faXNSZXN0YXJ0YWJsZSA9IGZhbHNlOwotICAgICAgICAgICAgcmV0dXJuIGNsb25lLnJlc2V0KCk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIEJhc2lzTGlicmFyeS5ydW5UaW1lRXJyb3IoQmFzaXNMaWJyYXJ5LklURVJBVE9SX0NMT05FX0VSUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZS50b1N0cmluZygpKTsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIERUTUF4aXNJdGVyYXRvciByZXNldCgpIHsKLSAgICAgICAgX2N1cnJlbnRJbmRleCA9IDA7Ci0gICAgICAgIHJldHVybiByZXNldFBvc2l0aW9uKCk7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBuZXh0KCkgewotICAgICAgICBmaW5hbCBpbnQgbGFzdCA9IF9ub2Rlcy5jYXJkaW5hbGl0eSgpOwotICAgICAgICBmaW5hbCBpbnQgY3VycmVudE5vZGUgPSBfY3VycmVudE5vZGU7Ci0gICAgICAgIGZpbmFsIEFic3RyYWN0VHJhbnNsZXQgdHJhbnNsZXQgPSBfdHJhbnNsZXQ7Ci0KLSAgICAgICAgZm9yIChpbnQgaW5kZXggPSBfY3VycmVudEluZGV4OyBpbmRleCA8IGxhc3Q7ICkgewotICAgICAgICAgICAgZmluYWwgaW50IHBvc2l0aW9uID0gX2RvY09yZGVyID8gaW5kZXggKyAxIDogbGFzdCAtIGluZGV4OwotICAgICAgICAgICAgZmluYWwgaW50IG5vZGUgPSBfbm9kZXMuYXQoaW5kZXgrKyk7ICAgICAgICAvLyBub3RlIGluY3JlbWVudAotCi0gICAgICAgICAgICBpZiAoX2ZpbHRlci50ZXN0KG5vZGUsIHBvc2l0aW9uLCBsYXN0LCBjdXJyZW50Tm9kZSwgdHJhbnNsZXQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMpKSB7Ci0gICAgICAgICAgICAgICAgX2N1cnJlbnRJbmRleCA9IGluZGV4OwotICAgICAgICAgICAgICAgIHJldHVybiByZXR1cm5Ob2RlKG5vZGUpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBFTkQ7Ci0gICAgfQotCi0gICAgcHVibGljIERUTUF4aXNJdGVyYXRvciBzZXRTdGFydE5vZGUoaW50IG5vZGUpIHsKLSAgICAgICAgaWYgKF9pc1Jlc3RhcnRhYmxlKSB7Ci0gICAgICAgICAgICBfc291cmNlLnNldFN0YXJ0Tm9kZShfc3RhcnROb2RlID0gbm9kZSk7Ci0KLSAgICAgICAgICAgIF9ub2Rlcy5jbGVhcigpOwotICAgICAgICAgICAgd2hpbGUgKChub2RlID0gX3NvdXJjZS5uZXh0KCkpICE9IEVORCkgewotICAgICAgICAgICAgICAgIF9ub2Rlcy5hZGQobm9kZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBfY3VycmVudEluZGV4ID0gMDsKLSAgICAgICAgICAgIHJlc2V0UG9zaXRpb24oKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gdGhpczsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldExhc3QoKSB7Ci0gICAgICAgIGlmIChfbGFzdCA9PSAtMSkgewotICAgICAgICAgICAgX2xhc3QgPSBjb21wdXRlUG9zaXRpb25PZkxhc3QoKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gX2xhc3Q7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0TWFyaygpIHsKLSAgICAgICAgX21hcmtlZE5vZGUgPSBfY3VycmVudEluZGV4OwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGdvdG9NYXJrKCkgewotICAgICAgICBfY3VycmVudEluZGV4ID0gX21hcmtlZE5vZGU7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBpbnQgY29tcHV0ZVBvc2l0aW9uT2ZMYXN0KCkgewotICAgICAgICBmaW5hbCBpbnQgbGFzdCA9IF9ub2Rlcy5jYXJkaW5hbGl0eSgpOwotICAgICAgICBmaW5hbCBpbnQgY3Vyck5vZGUgPSBfY3VycmVudE5vZGU7Ci0gICAgICAgIGZpbmFsIEFic3RyYWN0VHJhbnNsZXQgdHJhbnNsZXQgPSBfdHJhbnNsZXQ7Ci0KLSAgICAgICAgaW50IGxhc3RQb3NpdGlvbiA9IF9wb3NpdGlvbjsKLSAgICAgICAgZm9yIChpbnQgaW5kZXggPSBfY3VycmVudEluZGV4OyBpbmRleCA8IGxhc3Q7ICkgewotICAgICAgICAgICAgZmluYWwgaW50IHBvc2l0aW9uID0gX2RvY09yZGVyID8gaW5kZXggKyAxIDogbGFzdCAtIGluZGV4OwotICAgICAgICAgICAgaW50IG5vZGVJbmRleCA9IF9ub2Rlcy5hdChpbmRleCsrKTsgICAgICAgICAvLyBub3RlIGluY3JlbWVudAotCi0gICAgICAgICAgICBpZiAoX2ZpbHRlci50ZXN0KG5vZGVJbmRleCwgcG9zaXRpb24sIGxhc3QsIGN1cnJOb2RlLCB0cmFuc2xldCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcykpIHsKLSAgICAgICAgICAgICAgICBsYXN0UG9zaXRpb24rKzsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbGFzdFBvc2l0aW9uOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvZG9tL0RPTUFkYXB0ZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvZG9tL0RPTUFkYXB0ZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNGY0NGFlMS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2RvbS9ET01BZGFwdGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0NjQgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAxNSwgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqLwotLyoKLSAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQotICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCi0gKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCi0gKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAotICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKLSAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmRvbTsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5ET007Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLkRPTUVuaGFuY2VkRm9yRFRNOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5TdHJpcEZpbHRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuVHJhbnNsZXRFeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTUF4aXNJdGVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXIuU2VyaWFsaXphdGlvbkhhbmRsZXI7Ci1pbXBvcnQgamF2YS51dGlsLk1hcDsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGVMaXN0OwotCi0vKioKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIERPTUFkYXB0ZXIgaW1wbGVtZW50cyBET00gewotCi0gICAgLy8gTXV0dWFsbHkgZXhjbHVzaXZlIGNhc3Rpbmcgb2YgRE9NIGludGVyZmFjZSB0byBrbm93biBpbXBsZW1lbnRhdGlvbnMKLSAgICBwcml2YXRlIERPTUVuaGFuY2VkRm9yRFRNIF9lbmhhbmNlZERPTTsKLQotICAgIHByaXZhdGUgRE9NIF9kb207Ci0KLSAgICBwcml2YXRlIFN0cmluZ1tdIF9uYW1lc0FycmF5OwotICAgIHByaXZhdGUgU3RyaW5nW10gX3VyaXNBcnJheTsKLSAgICBwcml2YXRlIGludFtdICAgIF90eXBlc0FycmF5OwotICAgIHByaXZhdGUgU3RyaW5nW10gX25hbWVzcGFjZUFycmF5OwotCi0gICAgLy8gQ2FjaGVkIG1hcHBpbmdzCi0gICAgcHJpdmF0ZSBzaG9ydFtdIF9tYXBwaW5nID0gbnVsbDsKLSAgICBwcml2YXRlIGludFtdICAgX3JldmVyc2UgPSBudWxsOwotICAgIHByaXZhdGUgc2hvcnRbXSBfTlNtYXBwaW5nID0gbnVsbDsKLSAgICBwcml2YXRlIHNob3J0W10gX05TcmV2ZXJzZSA9IG51bGw7Ci0KLSAgICBwcml2YXRlIGludCBfbXVsdGlET01NYXNrOwotCi0gICAgcHVibGljIERPTUFkYXB0ZXIoRE9NIGRvbSwKLSAgICAgICAgICAgICAgICAgICAgICBTdHJpbmdbXSBuYW1lc0FycmF5LAotICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1tdIHVyaXNBcnJheSwKLSAgICAgICAgICAgICAgICAgICAgICBpbnRbXSB0eXBlc0FycmF5LAotICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1tdIG5hbWVzcGFjZUFycmF5KSB7Ci0gICAgICAgIGlmIChkb20gaW5zdGFuY2VvZiBET01FbmhhbmNlZEZvckRUTSl7Ci0gICAgICAgICAgICBfZW5oYW5jZWRET00gPSAoRE9NRW5oYW5jZWRGb3JEVE0pIGRvbTsKLSAgICAgICAgfQotCi0gICAgICAgIF9kb20gPSBkb207Ci0gICAgICAgIF9uYW1lc0FycmF5ID0gbmFtZXNBcnJheTsKLSAgICAgICAgX3VyaXNBcnJheSA9IHVyaXNBcnJheTsKLSAgICAgICAgX3R5cGVzQXJyYXkgPSB0eXBlc0FycmF5OwotICAgICAgICBfbmFtZXNwYWNlQXJyYXkgPSBuYW1lc3BhY2VBcnJheTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXR1cE1hcHBpbmcoU3RyaW5nW10gbmFtZXMsIFN0cmluZ1tdIHVyaXNBcnJheSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50W10gdHlwZXNBcnJheSwgU3RyaW5nW10gbmFtZXNwYWNlcykgewotICAgICAgICBfbmFtZXNBcnJheSA9IG5hbWVzOwotICAgICAgICBfdXJpc0FycmF5ID0gdXJpc0FycmF5OwotICAgICAgICBfdHlwZXNBcnJheSA9IHR5cGVzQXJyYXk7Ci0gICAgICAgIF9uYW1lc3BhY2VBcnJheSA9IG5hbWVzcGFjZXM7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZ1tdIGdldE5hbWVzQXJyYXkoKSB7Ci0gICAgICAgIHJldHVybiBfbmFtZXNBcnJheTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nW10gZ2V0VXJpc0FycmF5KCkgewotICAgICAgICByZXR1cm4gX3VyaXNBcnJheTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50W10gZ2V0VHlwZXNBcnJheSgpIHsKLSAgICAgICAgcmV0dXJuIF90eXBlc0FycmF5OwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmdbXSBnZXROYW1lc3BhY2VBcnJheSgpIHsKLSAgICAgICAgcmV0dXJuIF9uYW1lc3BhY2VBcnJheTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgRE9NIGdldERPTUltcGwoKSB7Ci0gICAgICAgIHJldHVybiBfZG9tOwotICAgIH0KLQotICAgIHByaXZhdGUgc2hvcnRbXSBnZXRNYXBwaW5nKCkgewotICAgICAgICBpZiAoX21hcHBpbmcgPT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKF9lbmhhbmNlZERPTSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgX21hcHBpbmcgPSBfZW5oYW5jZWRET00uZ2V0TWFwcGluZyhfbmFtZXNBcnJheSwgX3VyaXNBcnJheSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF90eXBlc0FycmF5KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gX21hcHBpbmc7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBpbnRbXSBnZXRSZXZlcnNlKCkgewotICAgICAgICBpZiAoX3JldmVyc2UgPT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKF9lbmhhbmNlZERPTSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgX3JldmVyc2UgPSBfZW5oYW5jZWRET00uZ2V0UmV2ZXJzZU1hcHBpbmcoX25hbWVzQXJyYXksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3VyaXNBcnJheSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdHlwZXNBcnJheSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIF9yZXZlcnNlOwotICAgIH0KLQotICAgIHByaXZhdGUgc2hvcnRbXSBnZXROU01hcHBpbmcoKSB7Ci0gICAgICAgIGlmIChfTlNtYXBwaW5nID09IG51bGwpIHsKLSAgICAgICAgICAgIGlmIChfZW5oYW5jZWRET00gIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIF9OU21hcHBpbmcgPSBfZW5oYW5jZWRET00uZ2V0TmFtZXNwYWNlTWFwcGluZyhfbmFtZXNwYWNlQXJyYXkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBfTlNtYXBwaW5nOwotICAgIH0KLQotICAgIHByaXZhdGUgc2hvcnRbXSBnZXROU1JldmVyc2UoKSB7Ci0gICAgICAgIGlmIChfTlNyZXZlcnNlID09IG51bGwpIHsKLSAgICAgICAgICAgIGlmIChfZW5oYW5jZWRET00gIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIF9OU3JldmVyc2UgPSBfZW5oYW5jZWRET00KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0UmV2ZXJzZU5hbWVzcGFjZU1hcHBpbmcoX25hbWVzcGFjZUFycmF5KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gX05TcmV2ZXJzZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgICogUmV0dXJucyBzaW5nbGV0b24gaXRlcmF0b3IgY29udGFpbmcgdGhlIGRvY3VtZW50IHJvb3QKLSAgICAgICovCi0gICAgcHVibGljIERUTUF4aXNJdGVyYXRvciBnZXRJdGVyYXRvcigpIHsKLSAgICAgICAgcmV0dXJuIF9kb20uZ2V0SXRlcmF0b3IoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldFN0cmluZ1ZhbHVlKCkgewotICAgICAgICByZXR1cm4gX2RvbS5nZXRTdHJpbmdWYWx1ZSgpOwotICAgIH0KLQotICAgIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3IgZ2V0Q2hpbGRyZW4oZmluYWwgaW50IG5vZGUpIHsKLSAgICAgICAgaWYgKF9lbmhhbmNlZERPTSAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gX2VuaGFuY2VkRE9NLmdldENoaWxkcmVuKG5vZGUpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgRFRNQXhpc0l0ZXJhdG9yIGl0ZXJhdG9yID0gX2RvbS5nZXRDaGlsZHJlbihub2RlKTsKLSAgICAgICAgICAgIHJldHVybiBpdGVyYXRvci5zZXRTdGFydE5vZGUobm9kZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRGaWx0ZXIoU3RyaXBGaWx0ZXIgZmlsdGVyKSB7fQotCi0gICAgcHVibGljIERUTUF4aXNJdGVyYXRvciBnZXRUeXBlZENoaWxkcmVuKGZpbmFsIGludCB0eXBlKSB7Ci0gICAgICAgIGZpbmFsIGludFtdIHJldmVyc2UgPSBnZXRSZXZlcnNlKCk7Ci0KLSAgICAgICAgaWYgKF9lbmhhbmNlZERPTSAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gX2VuaGFuY2VkRE9NLmdldFR5cGVkQ2hpbGRyZW4ocmV2ZXJzZVt0eXBlXSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gX2RvbS5nZXRUeXBlZENoaWxkcmVuKHR5cGUpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIERUTUF4aXNJdGVyYXRvciBnZXROYW1lc3BhY2VBeGlzSXRlcmF0b3IoZmluYWwgaW50IGF4aXMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IG5zKSB7Ci0gICAgICAgIHJldHVybiBfZG9tLmdldE5hbWVzcGFjZUF4aXNJdGVyYXRvcihheGlzLCBnZXROU1JldmVyc2UoKVtuc10pOwotICAgIH0KLQotICAgIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3IgZ2V0QXhpc0l0ZXJhdG9yKGZpbmFsIGludCBheGlzKSB7Ci0gICAgICAgIGlmIChfZW5oYW5jZWRET00gIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIF9lbmhhbmNlZERPTS5nZXRBeGlzSXRlcmF0b3IoYXhpcyk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gX2RvbS5nZXRBeGlzSXRlcmF0b3IoYXhpcyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIGdldFR5cGVkQXhpc0l0ZXJhdG9yKGZpbmFsIGludCBheGlzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IHR5cGUpIHsKLSAgICAgICAgZmluYWwgaW50W10gcmV2ZXJzZSA9IGdldFJldmVyc2UoKTsKLSAgICAgICAgaWYgKF9lbmhhbmNlZERPTSAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gX2VuaGFuY2VkRE9NLmdldFR5cGVkQXhpc0l0ZXJhdG9yKGF4aXMsIHJldmVyc2VbdHlwZV0pOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIF9kb20uZ2V0VHlwZWRBeGlzSXRlcmF0b3IoYXhpcywgdHlwZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldE11bHRpRE9NTWFzaygpIHsKLSAgICAgICAgcmV0dXJuIF9tdWx0aURPTU1hc2s7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0TXVsdGlET01NYXNrKGludCBtYXNrKSB7Ci0gICAgICAgIF9tdWx0aURPTU1hc2sgPSBtYXNrOwotICAgIH0KLQotICAgIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3IgZ2V0TnRoRGVzY2VuZGFudChpbnQgdHlwZSwgaW50IG4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gaW5jbHVkZXNlbGYpIHsKLSAgICAgICAgcmV0dXJuIF9kb20uZ2V0TnRoRGVzY2VuZGFudChnZXRSZXZlcnNlKClbdHlwZV0sIG4sIGluY2x1ZGVzZWxmKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIGdldE5vZGVWYWx1ZUl0ZXJhdG9yKERUTUF4aXNJdGVyYXRvciBpdGVyYXRvciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCB0eXBlLCBTdHJpbmcgdmFsdWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIG9wKSB7Ci0gICAgICAgIHJldHVybiBfZG9tLmdldE5vZGVWYWx1ZUl0ZXJhdG9yKGl0ZXJhdG9yLCB0eXBlLCB2YWx1ZSwgb3ApOwotICAgIH0KLQotICAgIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3Igb3JkZXJOb2RlcyhEVE1BeGlzSXRlcmF0b3Igc291cmNlLCBpbnQgbm9kZSkgewotICAgICAgICByZXR1cm4gX2RvbS5vcmRlck5vZGVzKHNvdXJjZSwgbm9kZSk7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBnZXRFeHBhbmRlZFR5cGVJRChmaW5hbCBpbnQgbm9kZSkgewotICAgICAgICBmaW5hbCBzaG9ydFtdIG1hcHBpbmcgPSBnZXRNYXBwaW5nKCk7Ci0gICAgICAgIGZpbmFsIGludCB0eXBlOwotICAgICAgICBpZiAoX2VuaGFuY2VkRE9NICE9IG51bGwpIHsKLSAgICAgICAgICAgIHR5cGUgPSBtYXBwaW5nW19lbmhhbmNlZERPTS5nZXRFeHBhbmRlZFR5cGVJRDIobm9kZSldOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIGlmKG51bGwgIT0gbWFwcGluZykKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgdHlwZSA9IG1hcHBpbmdbX2RvbS5nZXRFeHBhbmRlZFR5cGVJRChub2RlKV07Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICB0eXBlID0gX2RvbS5nZXRFeHBhbmRlZFR5cGVJRChub2RlKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHR5cGU7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBnZXROYW1lc3BhY2VUeXBlKGZpbmFsIGludCBub2RlKSB7Ci0gICAgICAgIHJldHVybiBnZXROU01hcHBpbmcoKVtfZG9tLmdldE5TVHlwZShub2RlKV07Ci0gICAgfQotCi0gICAgcHVibGljIGludCBnZXROU1R5cGUoaW50IG5vZGUpIHsKLSAgICAgICAgcmV0dXJuIF9kb20uZ2V0TlNUeXBlKG5vZGUpOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgZ2V0UGFyZW50KGZpbmFsIGludCBub2RlKSB7Ci0gICAgICAgIHJldHVybiBfZG9tLmdldFBhcmVudChub2RlKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldEF0dHJpYnV0ZU5vZGUoZmluYWwgaW50IHR5cGUsIGZpbmFsIGludCBlbGVtZW50KSB7Ci0gICAgICAgIHJldHVybiBfZG9tLmdldEF0dHJpYnV0ZU5vZGUoZ2V0UmV2ZXJzZSgpW3R5cGVdLCBlbGVtZW50KTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldE5vZGVOYW1lKGZpbmFsIGludCBub2RlKSB7Ci0gICAgICAgIGlmIChub2RlID09IERUTS5OVUxMKSB7Ci0gICAgICAgICAgICByZXR1cm4gIiI7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIF9kb20uZ2V0Tm9kZU5hbWUobm9kZSk7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXROb2RlTmFtZVgoZmluYWwgaW50IG5vZGUpCi0gICAgewotICAgICAgICBpZiAobm9kZSA9PSBEVE0uTlVMTCkgewotICAgICAgICAgICAgcmV0dXJuICIiOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBfZG9tLmdldE5vZGVOYW1lWChub2RlKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWVzcGFjZU5hbWUoZmluYWwgaW50IG5vZGUpCi0gICAgewotICAgICAgICBpZiAobm9kZSA9PSBEVE0uTlVMTCkgewotICAgICAgICAgICAgcmV0dXJuICIiOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBfZG9tLmdldE5hbWVzcGFjZU5hbWUobm9kZSk7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRTdHJpbmdWYWx1ZVgoZmluYWwgaW50IG5vZGUpCi0gICAgewotICAgICAgICBpZiAoX2VuaGFuY2VkRE9NICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBfZW5oYW5jZWRET00uZ2V0U3RyaW5nVmFsdWVYKG5vZGUpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgaWYgKG5vZGUgPT0gRFRNLk5VTEwpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gIiI7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gX2RvbS5nZXRTdHJpbmdWYWx1ZVgobm9kZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBjb3B5KGZpbmFsIGludCBub2RlLCBTZXJpYWxpemF0aW9uSGFuZGxlciBoYW5kbGVyKQotICAgICAgICB0aHJvd3MgVHJhbnNsZXRFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIF9kb20uY29weShub2RlLCBoYW5kbGVyKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBjb3B5KERUTUF4aXNJdGVyYXRvciBub2RlcyxTZXJpYWxpemF0aW9uSGFuZGxlciBoYW5kbGVyKQotICAgICAgICB0aHJvd3MgVHJhbnNsZXRFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIF9kb20uY29weShub2RlcywgaGFuZGxlcik7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBzaGFsbG93Q29weShmaW5hbCBpbnQgbm9kZSwgU2VyaWFsaXphdGlvbkhhbmRsZXIgaGFuZGxlcikKLSAgICAgICAgdGhyb3dzIFRyYW5zbGV0RXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAoX2VuaGFuY2VkRE9NICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBfZW5oYW5jZWRET00uc2hhbGxvd0NvcHkobm9kZSwgaGFuZGxlcik7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gX2RvbS5zaGFsbG93Q29weShub2RlLCBoYW5kbGVyKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGxlc3NUaGFuKGZpbmFsIGludCBub2RlMSwgZmluYWwgaW50IG5vZGUyKQotICAgIHsKLSAgICAgICAgcmV0dXJuIF9kb20ubGVzc1RoYW4obm9kZTEsIG5vZGUyKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBjaGFyYWN0ZXJzKGZpbmFsIGludCB0ZXh0Tm9kZSwgU2VyaWFsaXphdGlvbkhhbmRsZXIgaGFuZGxlcikKLSAgICAgIHRocm93cyBUcmFuc2xldEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaWYgKF9lbmhhbmNlZERPTSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBfZW5oYW5jZWRET00uY2hhcmFjdGVycyh0ZXh0Tm9kZSwgaGFuZGxlcik7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBfZG9tLmNoYXJhY3RlcnModGV4dE5vZGUsIGhhbmRsZXIpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIE5vZGUgbWFrZU5vZGUoaW50IGluZGV4KQotICAgIHsKLSAgICAgICAgcmV0dXJuIF9kb20ubWFrZU5vZGUoaW5kZXgpOwotICAgIH0KLQotICAgIHB1YmxpYyBOb2RlIG1ha2VOb2RlKERUTUF4aXNJdGVyYXRvciBpdGVyKQotICAgIHsKLSAgICAgICAgcmV0dXJuIF9kb20ubWFrZU5vZGUoaXRlcik7Ci0gICAgfQotCi0gICAgcHVibGljIE5vZGVMaXN0IG1ha2VOb2RlTGlzdChpbnQgaW5kZXgpCi0gICAgewotICAgICAgICByZXR1cm4gX2RvbS5tYWtlTm9kZUxpc3QoaW5kZXgpOwotICAgIH0KLQotICAgIHB1YmxpYyBOb2RlTGlzdCBtYWtlTm9kZUxpc3QoRFRNQXhpc0l0ZXJhdG9yIGl0ZXIpCi0gICAgewotICAgICAgICByZXR1cm4gX2RvbS5tYWtlTm9kZUxpc3QoaXRlcik7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRMYW5ndWFnZShpbnQgbm9kZSkKLSAgICB7Ci0gICAgICAgIHJldHVybiBfZG9tLmdldExhbmd1YWdlKG5vZGUpOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgZ2V0U2l6ZSgpCi0gICAgewotICAgICAgICByZXR1cm4gX2RvbS5nZXRTaXplKCk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0RG9jdW1lbnRVUkkoU3RyaW5nIHVyaSkKLSAgICB7Ci0gICAgICAgIGlmIChfZW5oYW5jZWRET00gIT0gbnVsbCkgewotICAgICAgICAgICAgX2VuaGFuY2VkRE9NLnNldERvY3VtZW50VVJJKHVyaSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldERvY3VtZW50VVJJKCkKLSAgICB7Ci0gICAgICAgIGlmIChfZW5oYW5jZWRET00gIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIF9lbmhhbmNlZERPTS5nZXREb2N1bWVudFVSSSgpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgcmV0dXJuICIiOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXREb2N1bWVudFVSSShpbnQgbm9kZSkKLSAgICB7Ci0gICAgICAgIHJldHVybiBfZG9tLmdldERvY3VtZW50VVJJKG5vZGUpOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgZ2V0RG9jdW1lbnQoKQotICAgIHsKLSAgICAgICAgcmV0dXJuIF9kb20uZ2V0RG9jdW1lbnQoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0VsZW1lbnQoZmluYWwgaW50IG5vZGUpCi0gICAgewotICAgICAgICByZXR1cm4oX2RvbS5pc0VsZW1lbnQobm9kZSkpOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGlzQXR0cmlidXRlKGZpbmFsIGludCBub2RlKQotICAgIHsKLSAgICAgICAgcmV0dXJuKF9kb20uaXNBdHRyaWJ1dGUobm9kZSkpOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgZ2V0Tm9kZUlkZW50KGludCBub2RlSGFuZGxlKQotICAgIHsKLSAgICAgICAgcmV0dXJuIF9kb20uZ2V0Tm9kZUlkZW50KG5vZGVIYW5kbGUpOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgZ2V0Tm9kZUhhbmRsZShpbnQgbm9kZUlkKQotICAgIHsKLSAgICAgICAgcmV0dXJuIF9kb20uZ2V0Tm9kZUhhbmRsZShub2RlSWQpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybiBhIGluc3RhbmNlIG9mIGEgRE9NIGNsYXNzIHRvIGJlIHVzZWQgYXMgYW4gUlRGCi0gICAgICovCi0gICAgcHVibGljIERPTSBnZXRSZXN1bHRUcmVlRnJhZyhpbnQgaW5pdFNpemUsIGludCBydGZUeXBlKQotICAgIHsKLSAgICAgICAgaWYgKF9lbmhhbmNlZERPTSAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gX2VuaGFuY2VkRE9NLmdldFJlc3VsdFRyZWVGcmFnKGluaXRTaXplLCBydGZUeXBlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiBfZG9tLmdldFJlc3VsdFRyZWVGcmFnKGluaXRTaXplLCBydGZUeXBlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybiBhIGluc3RhbmNlIG9mIGEgRE9NIGNsYXNzIHRvIGJlIHVzZWQgYXMgYW4gUlRGCi0gICAgICovCi0gICAgcHVibGljIERPTSBnZXRSZXN1bHRUcmVlRnJhZyhpbnQgaW5pdFNpemUsIGludCBydGZUeXBlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBhZGRUb01hbmFnZXIpCi0gICAgewotICAgICAgICBpZiAoX2VuaGFuY2VkRE9NICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBfZW5oYW5jZWRET00uZ2V0UmVzdWx0VHJlZUZyYWcoaW5pdFNpemUsIHJ0ZlR5cGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZFRvTWFuYWdlcik7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gX2RvbS5nZXRSZXN1bHRUcmVlRnJhZyhpbml0U2l6ZSwgcnRmVHlwZSwgYWRkVG9NYW5hZ2VyKTsKLSAgICAgICAgfQotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhIFNlcmlhbGl6YXRpb25IYW5kbGVyIGNsYXNzIHdyYXBwZWQgaW4gYSBTQVggYWRhcHRlci4KLSAgICAgKi8KLSAgICBwdWJsaWMgU2VyaWFsaXphdGlvbkhhbmRsZXIgZ2V0T3V0cHV0RG9tQnVpbGRlcigpCi0gICAgewotICAgICAgICByZXR1cm4gX2RvbS5nZXRPdXRwdXREb21CdWlsZGVyKCk7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBsb29rdXBOYW1lc3BhY2UoaW50IG5vZGUsIFN0cmluZyBwcmVmaXgpCi0gICAgICAgIHRocm93cyBUcmFuc2xldEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgcmV0dXJuIF9kb20ubG9va3VwTmFtZXNwYWNlKG5vZGUsIHByZWZpeCk7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRVbnBhcnNlZEVudGl0eVVSSShTdHJpbmcgZW50aXR5KSB7Ci0gICAgICAgIHJldHVybiBfZG9tLmdldFVucGFyc2VkRW50aXR5VVJJKGVudGl0eSk7Ci0gICAgfQotCi0gICAgcHVibGljIE1hcDxTdHJpbmcsIEludGVnZXI+IGdldEVsZW1lbnRzV2l0aElEcygpIHsKLSAgICAgICAgcmV0dXJuIF9kb20uZ2V0RWxlbWVudHNXaXRoSURzKCk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgcmVsZWFzZSgpIHsKLSAgICAgICAgX2RvbS5yZWxlYXNlKCk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vRE9NQnVpbGRlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vRE9NQnVpbGRlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0ZjE2MzY2Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvZG9tL0RPTUJ1aWxkZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI5ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IERPTUJ1aWxkZXIuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8wNiAwNjowODoyMyBwdmVkdWxhIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmRvbTsKLQotCi0vKioKLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICovCi1wdWJsaWMgaW50ZXJmYWNlIERPTUJ1aWxkZXIgZXh0ZW5kcyAgRXh0ZW5kZWRTQVggeyB9CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2RvbS9ET01XU0ZpbHRlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vRE9NV1NGaWx0ZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNTRmZTg0MS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2RvbS9ET01XU0ZpbHRlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTMzICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKi8KLS8qCi0gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKLSAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAotICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgotICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKLSAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCi0gKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRE9NV1NGaWx0ZXIuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8wNiAwNjoxNDozMSBwdmVkdWxhIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmRvbTsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5ET007Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLkRPTUVuaGFuY2VkRm9yRFRNOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5TdHJpcEZpbHRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMucnVudGltZS5BYnN0cmFjdFRyYW5zbGV0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1XU0ZpbHRlcjsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKLWltcG9ydCBqYXZhLnV0aWwuTWFwOwotCi0vKioKLSAqIEEgd3JhcHBlciBjbGFzcyB0aGF0IGFkYXB0cyB0aGUKLSAqIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1XU0ZpbHRlciBEVE1XU0ZpbHRlcn0gaW50ZXJmYWNlIHRvIHRoZSBYU0xUQwotICogRE9NIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuU3RyaXBGaWx0ZXIgU3RyaXBGaWx0ZXJ9IGludGVyZmFjZS4KLSAqLwotcHVibGljIGNsYXNzIERPTVdTRmlsdGVyIGltcGxlbWVudHMgRFRNV1NGaWx0ZXIgewotCi0gICAgcHJpdmF0ZSBBYnN0cmFjdFRyYW5zbGV0IG1fdHJhbnNsZXQ7Ci0gICAgcHJpdmF0ZSBTdHJpcEZpbHRlciBtX2ZpbHRlcjsKLQotICAgIC8vIFRoZSBNYXAgZm9yIERUTSB0byBtYXBwaW5nIGFycmF5Ci0gICAgcHJpdmF0ZSBNYXA8RFRNLCBzaG9ydFtdPiBtX21hcHBpbmdzOwotCi0gICAgLy8gQ2FjaGUgdGhlIERUTSBhbmQgbWFwcGluZyB0aGF0IGFyZSB1c2VkIGxhc3QgdGltZQotICAgIHByaXZhdGUgRFRNIG1fY3VycmVudERUTTsKLSAgICBwcml2YXRlIHNob3J0W10gbV9jdXJyZW50TWFwcGluZzsKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdCBhbiBhZGFwdGVyIGNvbm5lY3RpbmcgdGhlIDxjb2RlPkRUTVdTRmlsdGVyPC9jb2RlPiBpbnRlcmZhY2UKLSAgICAgKiB0byB0aGUgPGNvZGU+U3RyaXBGaWx0ZXI8L2NvZGU+IGludGVyZmFjZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSB0cmFuc2xldCBBIHRyYW5zbGV0IHRoYXQgYWxzbyBpbXBsZW1lbnRzIHRoZSBTdHJpcEZpbHRlcgotICAgICAqIGludGVyZmFjZS4KLSAgICAgKgotICAgICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNV1NGaWx0ZXIKLSAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5TdHJpcEZpbHRlcgotICAgICAqLwotICAgIHB1YmxpYyBET01XU0ZpbHRlcihBYnN0cmFjdFRyYW5zbGV0IHRyYW5zbGV0KSB7Ci0gICAgICAgIG1fdHJhbnNsZXQgPSB0cmFuc2xldDsKLSAgICAgICAgbV9tYXBwaW5ncyA9IG5ldyBIYXNoTWFwPD4oKTsKLQotICAgICAgICBpZiAodHJhbnNsZXQgaW5zdGFuY2VvZiBTdHJpcEZpbHRlcikgewotICAgICAgICAgICAgbV9maWx0ZXIgPSAoU3RyaXBGaWx0ZXIpIHRyYW5zbGV0OwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGVzdCB3aGV0aGVyIHdoaXRlc3BhY2Utb25seSB0ZXh0IG5vZGVzIGFyZSB2aXNpYmxlIGluIHRoZSBsb2dpY2FsCi0gICAgICogdmlldyBvZiA8Y29kZT5EVE08L2NvZGU+LiBOb3JtYWxseSwgdGhpcyBmdW5jdGlvbgotICAgICAqIHdpbGwgYmUgY2FsbGVkIGJ5IHRoZSBpbXBsZW1lbnRhdGlvbiBvZiA8Y29kZT5EVE08L2NvZGU+OwotICAgICAqIGl0IGlzIG5vdCBub3JtYWxseSBjYWxsZWQgZGlyZWN0bHkgZnJvbQotICAgICAqIHVzZXIgY29kZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBub2RlIGludCBoYW5kbGUgb2YgdGhlIG5vZGUuCi0gICAgICogQHBhcmFtIGR0bSB0aGUgRFRNIHRoYXQgb3ducyB0aGlzIG5vZGUKLSAgICAgKiBAcmV0dXJuIG9uZSBvZiA8Y29kZT5OT1RTVFJJUDwvY29kZT4sIDxjb2RlPlNUUklQPC9jb2RlPiBvcgotICAgICAqIDxjb2RlPklOSEVSSVQ8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBzaG9ydCBnZXRTaG91bGRTdHJpcFNwYWNlKGludCBub2RlLCBEVE0gZHRtKSB7Ci0gICAgICAgIGlmIChtX2ZpbHRlciAhPSBudWxsICYmIGR0bSBpbnN0YW5jZW9mIERPTSkgewotICAgICAgICAgICAgRE9NIGRvbSA9IChET00pZHRtOwotICAgICAgICAgICAgaW50IHR5cGUgPSAwOwotCi0gICAgICAgICAgICBpZiAoZHRtIGluc3RhbmNlb2YgRE9NRW5oYW5jZWRGb3JEVE0pIHsKLSAgICAgICAgICAgICAgICBET01FbmhhbmNlZEZvckRUTSBtYXBwYWJsZURPTSA9IChET01FbmhhbmNlZEZvckRUTSlkdG07Ci0KLSAgICAgICAgICAgICAgICBzaG9ydFtdIG1hcHBpbmc7Ci0gICAgICAgICAgICAgICAgaWYgKGR0bSA9PSBtX2N1cnJlbnREVE0pIHsKLSAgICAgICAgICAgICAgICAgICAgbWFwcGluZyA9IG1fY3VycmVudE1hcHBpbmc7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICBtYXBwaW5nID0gbV9tYXBwaW5ncy5nZXQoZHRtKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKG1hcHBpbmcgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgbWFwcGluZyA9IG1hcHBhYmxlRE9NLmdldE1hcHBpbmcoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbV90cmFuc2xldC5nZXROYW1lc0FycmF5KCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbV90cmFuc2xldC5nZXRVcmlzQXJyYXkoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX3RyYW5zbGV0LmdldFR5cGVzQXJyYXkoKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBtX21hcHBpbmdzLnB1dChkdG0sIG1hcHBpbmcpOwotICAgICAgICAgICAgICAgICAgICAgICAgbV9jdXJyZW50RFRNID0gZHRtOwotICAgICAgICAgICAgICAgICAgICAgICAgbV9jdXJyZW50TWFwcGluZyA9IG1hcHBpbmc7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBpbnQgZXhwVHlwZSA9IG1hcHBhYmxlRE9NLmdldEV4cGFuZGVkVHlwZUlEKG5vZGUpOwotCi0gICAgICAgICAgICAgICAgLy8gJU9QVCUgVGhlIG1hcHBpbmcgYXJyYXkgZG9lcyBub3QgaGF2ZSBpbmZvcm1hdGlvbiBhYm91dCBhbGwgdGhlCi0gICAgICAgICAgICAgICAgLy8gZXhwdHlwZXMuIEhvd2V2ZXIgaXQgZG9lcyBjb250YWluIGVub3VnaCBpbmZvcm1hdGlvbiBhYm91dCBhbGwgbmFtZXMKLSAgICAgICAgICAgICAgICAvLyBpbiB0aGUgdHJhbnNsZXQncyBuYW1lc0FycmF5LiBJZiB0aGUgZXhwVHlwZSBkb2VzIG5vdCBmYWxsIGludG8gdGhlCi0gICAgICAgICAgICAgICAgLy8gcmFuZ2Ugb2YgdGhlIG1hcHBpbmcgYXJyYXksIGl0IG1lYW5zIHRoYXQgdGhlIGV4cFR5cGUgaXMgbm90IGZvciBvbmUKLSAgICAgICAgICAgICAgICAvLyBvZiB0aGUgcmVjb2duaXplZCBuYW1lcy4gSW4gdGhpcyBjYXNlIHdlIGNhbiBqdXN0IHNldCB0aGUgdHlwZSB0byAtMS4KLSAgICAgICAgICAgICAgICBpZiAoZXhwVHlwZSA+PSAwICYmIGV4cFR5cGUgPCBtYXBwaW5nLmxlbmd0aCkKLSAgICAgICAgICAgICAgICAgIHR5cGUgPSBtYXBwaW5nW2V4cFR5cGVdOwotICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgIHR5cGUgPSAtMTsKLQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIElOSEVSSVQ7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmIChtX2ZpbHRlci5zdHJpcFNwYWNlKGRvbSwgbm9kZSwgdHlwZSkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gU1RSSVA7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIHJldHVybiBOT1RTVFJJUDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiBOT1RTVFJJUDsKLSAgICAgICAgfQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvZG9tL0RvY3VtZW50Q2FjaGUuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvZG9tL0RvY3VtZW50Q2FjaGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggY2I5MTI0Yi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2RvbS9Eb2N1bWVudENhY2hlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzMzggKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAxNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqLwotLyoKLSAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQotICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCi0gKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCi0gKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAotICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKLSAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBEb2N1bWVudENhY2hlLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMDYgMDY6MTU6MjIgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmRvbTsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5ET007Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLkRPTUNhY2hlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5ET01FbmhhbmNlZEZvckRUTTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuVHJhbnNsZXQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnJ1bnRpbWUuQWJzdHJhY3RUcmFuc2xldDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMucnVudGltZS5CYXNpc0xpYnJhcnk7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnJ1bnRpbWUuQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuU3lzdGVtSURSZXNvbHZlcjsKLWltcG9ydCBqYXZhLmlvLkZpbGU7Ci1pbXBvcnQgamF2YS5pby5QcmludFdyaXRlcjsKLWltcG9ydCBqYXZhLm5ldC5VUkw7Ci1pbXBvcnQgamF2YS5uZXQuVVJMQ29ubmVjdGlvbjsKLWltcG9ydCBqYXZhLm5ldC5VUkxEZWNvZGVyOwotaW1wb3J0IGphdmEudXRpbC5EYXRlOwotaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwotaW1wb3J0IGphdmEudXRpbC5NYXA7Ci1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXI7Ci1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyRmFjdG9yeTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlNBWFNvdXJjZTsKLWltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguWE1MUmVhZGVyOwotCi0vKioKLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgRG9jdW1lbnRDYWNoZSBpbXBsZW1lbnRzIERPTUNhY2hlIHsKLQotICAgIHByaXZhdGUgaW50ICAgICAgIF9zaXplOwotICAgIHByaXZhdGUgTWFwPFN0cmluZywgQ2FjaGVkRG9jdW1lbnQ+IF9yZWZlcmVuY2VzOwotICAgIHByaXZhdGUgU3RyaW5nW10gIF9VUklzOwotICAgIHByaXZhdGUgaW50ICAgICAgIF9jb3VudDsKLSAgICBwcml2YXRlIGludCAgICAgICBfY3VycmVudDsKLSAgICBwcml2YXRlIFNBWFBhcnNlciBfcGFyc2VyOwotICAgIHByaXZhdGUgWE1MUmVhZGVyIF9yZWFkZXI7Ci0gICAgcHJpdmF0ZSBYU0xUQ0RUTU1hbmFnZXIgX2R0bU1hbmFnZXI7Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgUkVGUkVTSF9JTlRFUlZBTCA9IDEwMDA7Ci0KLSAgICAvKgotICAgICAqIElubmVyIGNsYXNzIGNvbnRhaW5pbmcgYSBET01JbXBsIG9iamVjdCBhbmQgRFREIGhhbmRsZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgZmluYWwgY2xhc3MgQ2FjaGVkRG9jdW1lbnQgewotCi0gICAgICAgIC8vIFN0YXRpc3RpY3MgZGF0YQotICAgICAgICBwcml2YXRlIGxvbmcgX2ZpcnN0UmVmZXJlbmNlZDsKLSAgICAgICAgcHJpdmF0ZSBsb25nIF9sYXN0UmVmZXJlbmNlZDsKLSAgICAgICAgcHJpdmF0ZSBsb25nIF9hY2Nlc3NDb3VudDsKLSAgICAgICAgcHJpdmF0ZSBsb25nIF9sYXN0TW9kaWZpZWQ7Ci0gICAgICAgIHByaXZhdGUgbG9uZyBfbGFzdENoZWNrZWQ7Ci0gICAgICAgIHByaXZhdGUgbG9uZyBfYnVpbGRUaW1lOwotCi0gICAgICAgIC8vIERPTSBhbmQgRFREIGhhbmRsZXIgcmVmZXJlbmNlcwotICAgICAgICBwcml2YXRlIERPTUVuaGFuY2VkRm9yRFRNIF9kb20gPSBudWxsOwotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBDb25zdHJ1Y3RvciAtIGxvYWQgZG9jdW1lbnQgYW5kIGluaXRpYWxpc2Ugc3RhdGlzdGljcwotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIENhY2hlZERvY3VtZW50KFN0cmluZyB1cmkpIHsKLSAgICAgICAgICAgIC8vIEluaXRpYWxpc2Ugc3RhdGlzdGljcyB2YXJpYWJsZXMKLSAgICAgICAgICAgIGZpbmFsIGxvbmcgc3RhbXAgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKLSAgICAgICAgICAgIF9maXJzdFJlZmVyZW5jZWQgPSBzdGFtcDsKLSAgICAgICAgICAgIF9sYXN0UmVmZXJlbmNlZCAgPSBzdGFtcDsKLSAgICAgICAgICAgIF9hY2Nlc3NDb3VudCAgICAgPSAwOwotICAgICAgICAgICAgbG9hZERvY3VtZW50KHVyaSk7Ci0KLSAgICAgICAgICAgIF9idWlsZFRpbWUgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSAtIHN0YW1wOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIExvYWRzIHRoZSBkb2N1bWVudCBhbmQgdXBkYXRlcyBidWlsZC10aW1lIChsYXRlbmN5KSBzdGF0aXN0aWNzCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgdm9pZCBsb2FkRG9jdW1lbnQoU3RyaW5nIHVyaSkgewotCi0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIGZpbmFsIGxvbmcgc3RhbXAgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKLSAgICAgICAgICAgICAgICBfZG9tID0gKERPTUVuaGFuY2VkRm9yRFRNKV9kdG1NYW5hZ2VyLmdldERUTSgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBTQVhTb3VyY2UoX3JlYWRlciwgbmV3IElucHV0U291cmNlKHVyaSkpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UsIG51bGwsIHRydWUsIGZhbHNlKTsKLSAgICAgICAgICAgICAgICBfZG9tLnNldERvY3VtZW50VVJJKHVyaSk7Ci0KLSAgICAgICAgICAgICAgICAvLyBUaGUgYnVpbGQgdGltZSBjYW4gYmUgdXNlZCBmb3Igc3RhdGlzdGljcyBmb3IgYSBiZXR0ZXIKLSAgICAgICAgICAgICAgICAvLyBwcmlvcml0eSBhbGdvcml0aG0gKGN1cnJlbnRseSByb3VuZCByb2JpbikuCi0gICAgICAgICAgICAgICAgZmluYWwgbG9uZyB0aGlzVGltZSA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpIC0gc3RhbXA7Ci0gICAgICAgICAgICAgICAgaWYgKF9idWlsZFRpbWUgPiAwKQotICAgICAgICAgICAgICAgICAgICBfYnVpbGRUaW1lID0gKF9idWlsZFRpbWUgKyB0aGlzVGltZSkgPj4+IDE7Ci0gICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICBfYnVpbGRUaW1lID0gdGhpc1RpbWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICBfZG9tID0gbnVsbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyBET00gZ2V0RG9jdW1lbnQoKSAgICAgICB7IHJldHVybihfZG9tKTsgfQotCi0gICAgICAgIHB1YmxpYyBsb25nIGdldEZpcnN0UmVmZXJlbmNlZCgpICAgeyByZXR1cm4oX2ZpcnN0UmVmZXJlbmNlZCk7IH0KLQotICAgICAgICBwdWJsaWMgbG9uZyBnZXRMYXN0UmVmZXJlbmNlZCgpICAgIHsgcmV0dXJuKF9sYXN0UmVmZXJlbmNlZCk7IH0KLQotICAgICAgICBwdWJsaWMgbG9uZyBnZXRBY2Nlc3NDb3VudCgpICAgICAgIHsgcmV0dXJuKF9hY2Nlc3NDb3VudCk7IH0KLQotICAgICAgICBwdWJsaWMgdm9pZCBpbmNBY2Nlc3NDb3VudCgpICAgICAgIHsgX2FjY2Vzc0NvdW50Kys7IH0KLQotICAgICAgICBwdWJsaWMgbG9uZyBnZXRMYXN0TW9kaWZpZWQoKSAgICAgIHsgcmV0dXJuKF9sYXN0TW9kaWZpZWQpOyB9Ci0KLSAgICAgICAgcHVibGljIHZvaWQgc2V0TGFzdE1vZGlmaWVkKGxvbmcgdCl7IF9sYXN0TW9kaWZpZWQgPSB0OyB9Ci0KLSAgICAgICAgcHVibGljIGxvbmcgZ2V0TGF0ZW5jeSgpICAgICAgICAgICB7IHJldHVybihfYnVpbGRUaW1lKTsgfQotCi0gICAgICAgIHB1YmxpYyBsb25nIGdldExhc3RDaGVja2VkKCkgICAgICAgeyByZXR1cm4oX2xhc3RDaGVja2VkKTsgfQotCi0gICAgICAgIHB1YmxpYyB2b2lkIHNldExhc3RDaGVja2VkKGxvbmcgdCkgeyBfbGFzdENoZWNrZWQgPSB0OyB9Ci0KLSAgICAgICAgcHVibGljIGxvbmcgZ2V0RXN0aW1hdGVkU2l6ZSgpIHsKLSAgICAgICAgICAgIGlmIChfZG9tICE9IG51bGwpCi0gICAgICAgICAgICAgICAgcmV0dXJuKF9kb20uZ2V0U2l6ZSgpIDw8IDUpOyAvLyA/Pz8KLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICByZXR1cm4oMCk7Ci0gICAgICAgIH0KLQotICAgIH0KLQotICAgIC8qKgotICAgICAqIERvY3VtZW50Q2FjaGUgY29uc3RydWN0b3IKLSAgICAgKi8KLSAgICBwdWJsaWMgRG9jdW1lbnRDYWNoZShpbnQgc2l6ZSkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0gICAgICAgIHRoaXMoc2l6ZSwgbnVsbCk7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBfZHRtTWFuYWdlciA9IFhTTFRDRFRNTWFuYWdlci5jcmVhdGVOZXdEVE1NYW5hZ2VySW5zdGFuY2UoKTsKLSAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBEb2N1bWVudENhY2hlIGNvbnN0cnVjdG9yCi0gICAgICovCi0gICAgcHVibGljIERvY3VtZW50Q2FjaGUoaW50IHNpemUsIFhTTFRDRFRNTWFuYWdlciBkdG1NYW5hZ2VyKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICAgICAgX2R0bU1hbmFnZXIgPSBkdG1NYW5hZ2VyOwotICAgICAgICBfY291bnQgPSAwOwotICAgICAgICBfY3VycmVudCA9IDA7Ci0gICAgICAgIF9zaXplICA9IHNpemU7Ci0gICAgICAgIF9yZWZlcmVuY2VzID0gbmV3IEhhc2hNYXA8Pihfc2l6ZSsyKTsKLSAgICAgICAgX1VSSXMgPSBuZXcgU3RyaW5nW19zaXplXTsKLQotICAgICAgICB0cnkgewotICAgICAgICAgICAgLy8gQ3JlYXRlIGEgU0FYIHBhcnNlciBhbmQgZ2V0IHRoZSBYTUxSZWFkZXIgb2JqZWN0IGl0IHVzZXMKLSAgICAgICAgICAgIGZpbmFsIFNBWFBhcnNlckZhY3RvcnkgZmFjdG9yeSA9IFNBWFBhcnNlckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgZmFjdG9yeS5zZXRGZWF0dXJlKENvbnN0YW50cy5OQU1FU1BBQ0VfRkVBVFVSRSx0cnVlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgIGZhY3Rvcnkuc2V0TmFtZXNwYWNlQXdhcmUodHJ1ZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBfcGFyc2VyID0gZmFjdG9yeS5uZXdTQVhQYXJzZXIoKTsKLSAgICAgICAgICAgIF9yZWFkZXIgPSBfcGFyc2VyLmdldFhNTFJlYWRlcigpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIEJhc2lzTGlicmFyeS5ydW5UaW1lRXJyb3IoQmFzaXNMaWJyYXJ5Lk5BTUVTUEFDRVNfU1VQUE9SVF9FUlIpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgdGltZS1zdGFtcCBmb3IgYSBkb2N1bWVudCdzIGxhc3QgdXBkYXRlCi0gICAgICovCi0gICAgcHJpdmF0ZSBmaW5hbCBsb25nIGdldExhc3RNb2RpZmllZChTdHJpbmcgdXJpKSB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBVUkwgdXJsID0gbmV3IFVSTCh1cmkpOwotICAgICAgICAgICAgVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uID0gdXJsLm9wZW5Db25uZWN0aW9uKCk7Ci0gICAgICAgICAgICBsb25nIHRpbWVzdGFtcCA9IGNvbm5lY3Rpb24uZ2V0TGFzdE1vZGlmaWVkKCk7Ci0gICAgICAgICAgICAvLyBDaGVjayBmb3IgYSAiZmlsZToiIFVSSSAoY291cnRlc3kgb2YgQnJpYW4gRXdpbnMpCi0gICAgICAgICAgICBpZiAodGltZXN0YW1wID09IDApeyAvLyBnZXQgMCBmb3IgbG9jYWwgVVJJCi0gICAgICAgICAgICAgICAgaWYgKCJmaWxlIi5lcXVhbHModXJsLmdldFByb3RvY29sKCkpKXsKLSAgICAgICAgICAgICAgICAgICAgRmlsZSBsb2NhbGZpbGUgPSBuZXcgRmlsZShVUkxEZWNvZGVyLmRlY29kZSh1cmwuZ2V0RmlsZSgpKSk7Ci0gICAgICAgICAgICAgICAgICAgIHRpbWVzdGFtcCA9IGxvY2FsZmlsZS5sYXN0TW9kaWZpZWQoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4odGltZXN0YW1wKTsKLSAgICAgICAgfQotICAgICAgICAvLyBCcnV0YWwgaGFuZGxpbmcgb2YgYWxsIGV4Y2VwdGlvbnMKLSAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICByZXR1cm4oU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICoKLSAgICAgKi8KLSAgICBwcml2YXRlIENhY2hlZERvY3VtZW50IGxvb2t1cERvY3VtZW50KFN0cmluZyB1cmkpIHsKLSAgICAgICAgcmV0dXJuKF9yZWZlcmVuY2VzLmdldCh1cmkpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKgotICAgICAqLwotICAgIHByaXZhdGUgc3luY2hyb25pemVkIHZvaWQgaW5zZXJ0RG9jdW1lbnQoU3RyaW5nIHVyaSwgQ2FjaGVkRG9jdW1lbnQgZG9jKSB7Ci0gICAgICAgIGlmIChfY291bnQgPCBfc2l6ZSkgewotICAgICAgICAgICAgLy8gSW5zZXJ0IG91dCBVUkkgaW4gY2lyY3VsYXIgYnVmZmVyCi0gICAgICAgICAgICBfVVJJc1tfY291bnQrK10gPSB1cmk7Ci0gICAgICAgICAgICBfY3VycmVudCA9IDA7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAvLyBSZW1vdmUgb2xkZXN0IFVSSSBmcm9tIHJlZmVyZW5jZSBtYXAKLSAgICAgICAgICAgIF9yZWZlcmVuY2VzLnJlbW92ZShfVVJJc1tfY3VycmVudF0pOwotICAgICAgICAgICAgLy8gSW5zZXJ0IG91ciBVUkkgaW4gY2lyY3VsYXIgYnVmZmVyCi0gICAgICAgICAgICBfVVJJc1tfY3VycmVudF0gPSB1cmk7Ci0gICAgICAgICAgICBpZiAoKytfY3VycmVudCA+PSBfc2l6ZSkgX2N1cnJlbnQgPSAwOwotICAgICAgICB9Ci0gICAgICAgIF9yZWZlcmVuY2VzLnB1dCh1cmksIGRvYyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICoKLSAgICAgKi8KLSAgICBwcml2YXRlIHN5bmNocm9uaXplZCB2b2lkIHJlcGxhY2VEb2N1bWVudChTdHJpbmcgdXJpLCBDYWNoZWREb2N1bWVudCBkb2MpIHsKLSAgICAgICAgaWYgKGRvYyA9PSBudWxsKQotICAgICAgICAgICAgaW5zZXJ0RG9jdW1lbnQodXJpLCBkb2MpOwotICAgICAgICBlbHNlCi0gICAgICAgICAgICBfcmVmZXJlbmNlcy5wdXQodXJpLCBkb2MpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYSBkb2N1bWVudCBlaXRoZXIgYnkgZmluZGluZyBpdCBpbiB0aGUgY2FjaGUgb3IKLSAgICAgKiBkb3dubG9hZGluZyBpdCBhbmQgcHV0dGluZyBpdCBpbiB0aGUgY2FjaGUuCi0gICAgICovCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIERPTSByZXRyaWV2ZURvY3VtZW50KFN0cmluZyBiYXNlVVJJLCBTdHJpbmcgaHJlZiwgVHJhbnNsZXQgdHJzKSB7Ci0gICAgICAgIENhY2hlZERvY3VtZW50IGRvYzsKLQotICAgIFN0cmluZyB1cmkgPSBocmVmOwotICAgIGlmIChiYXNlVVJJICE9IG51bGwgJiYgIWJhc2VVUkkuZXF1YWxzKCIiKSkgewotICAgICAgICB0cnkgewotICAgICAgICAgICAgdXJpID0gU3lzdGVtSURSZXNvbHZlci5nZXRBYnNvbHV0ZVVSSSh1cmksIGJhc2VVUkkpOwotICAgICAgICB9IGNhdGNoIChUcmFuc2Zvcm1lckV4Y2VwdGlvbiB0ZSkgewotICAgICAgICAgICAgLy8gaWdub3JlCi0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAgICAgLy8gVHJ5IHRvIGdldCB0aGUgZG9jdW1lbnQgZnJvbSB0aGUgY2FjaGUgZmlyc3QKLSAgICAgICAgaWYgKChkb2MgPSBsb29rdXBEb2N1bWVudCh1cmkpKSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBkb2MgPSBuZXcgQ2FjaGVkRG9jdW1lbnQodXJpKTsKLSAgICAgICAgICAgIGlmIChkb2MgPT0gbnVsbCkgcmV0dXJuIG51bGw7IC8vIGJldHRlciBlcnJvciBoYW5kbGluZyBuZWVkZWQhISEKLSAgICAgICAgICAgIGRvYy5zZXRMYXN0TW9kaWZpZWQoZ2V0TGFzdE1vZGlmaWVkKHVyaSkpOwotICAgICAgICAgICAgaW5zZXJ0RG9jdW1lbnQodXJpLCBkb2MpOwotICAgICAgICB9Ci0gICAgICAgIC8vIElmIHRoZSBkb2N1bWVudCBpcyBpbiB0aGUgY2FjaGUgd2UgbXVzdCBjaGVjayBpZiBpdCBpcyBzdGlsbCB2YWxpZAotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIGxvbmcgbm93ID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7Ci0gICAgICAgICAgICBsb25nIGNoayA9IGRvYy5nZXRMYXN0Q2hlY2tlZCgpOwotICAgICAgICAgICAgZG9jLnNldExhc3RDaGVja2VkKG5vdyk7Ci0gICAgICAgICAgICAvLyBIYXMgdGhlIG1vZGlmaWNhdGlvbiB0aW1lIGZvciB0aGlzIGZpbGUgYmVlbiBjaGVja2VkIGxhdGVseT8KLSAgICAgICAgICAgIGlmIChub3cgPiAoY2hrICsgUkVGUkVTSF9JTlRFUlZBTCkpIHsKLSAgICAgICAgICAgICAgICBkb2Muc2V0TGFzdENoZWNrZWQobm93KTsKLSAgICAgICAgICAgICAgICBsb25nIGxhc3QgPSBnZXRMYXN0TW9kaWZpZWQodXJpKTsKLSAgICAgICAgICAgICAgICAvLyBSZWxvYWQgZG9jdW1lbnQgaWYgaXQgaGFzIGJlZW4gbW9kaWZpZWQgc2luY2UgbGFzdCBkb3dubG9hZAotICAgICAgICAgICAgICAgIGlmIChsYXN0ID4gZG9jLmdldExhc3RNb2RpZmllZCgpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGRvYyA9IG5ldyBDYWNoZWREb2N1bWVudCh1cmkpOwotICAgICAgICAgICAgICAgICAgICBpZiAoZG9jID09IG51bGwpIHJldHVybiBudWxsOwotICAgICAgICAgICAgICAgICAgICBkb2Muc2V0TGFzdE1vZGlmaWVkKGdldExhc3RNb2RpZmllZCh1cmkpKTsKLSAgICAgICAgICAgICAgICAgICAgcmVwbGFjZURvY3VtZW50KHVyaSwgZG9jKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIEdldCB0aGUgcmVmZXJlbmNlcyB0byB0aGUgYWN0dWFsIERPTSBhbmQgRFREIGhhbmRsZXIKLSAgICAgICAgZmluYWwgRE9NIGRvbSA9IGRvYy5nZXREb2N1bWVudCgpOwotCi0gICAgICAgIC8vIFRoZSBkb20gcmVmZXJlbmNlIG1heSBiZSBudWxsIGlmIHRoZSBVUkwgcG9pbnRlZCB0byBhCi0gICAgICAgIC8vIG5vbi1leGlzdGluZyBkb2N1bWVudAotICAgICAgICBpZiAoZG9tID09IG51bGwpIHJldHVybiBudWxsOwotCi0gICAgICAgIGRvYy5pbmNBY2Nlc3NDb3VudCgpOyAvLyBGb3Igc3RhdGlzdGljcwotCi0gICAgICAgIGZpbmFsIEFic3RyYWN0VHJhbnNsZXQgdHJhbnNsZXQgPSAoQWJzdHJhY3RUcmFuc2xldCl0cnM7Ci0KLSAgICAgICAgLy8gR2l2ZSB0aGUgdHJhbnNsZXQgYW4gZWFybHkgb3Bwb3J0dW5pdHkgdG8gZXh0cmFjdCBhbnkKLSAgICAgICAgLy8gaW5mb3JtYXRpb24gZnJvbSB0aGUgRE9NIG9iamVjdCB0aGF0IGl0IHdvdWxkIGxpa2UuCi0gICAgICAgIHRyYW5zbGV0LnByZXBhc3NEb2N1bWVudChkb20pOwotCi0gICAgICAgIHJldHVybihkb2MuZ2V0RG9jdW1lbnQoKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogT3V0cHV0cyB0aGUgY2FjaGUgc3RhdGlzdGljcwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGdldFN0YXRpc3RpY3MoUHJpbnRXcml0ZXIgb3V0KSB7Ci0gICAgICAgIG91dC5wcmludGxuKCI8aDI+RE9NIGNhY2hlIHN0YXRpc3RpY3M8L2gyPjxjZW50ZXI+PHRhYmxlIGJvcmRlcj1cIjJcIj4iKwotICAgICAgICAgICAgICAgICAgICAiPHRyPjx0ZD48Yj5Eb2N1bWVudCBVUkk8L2I+PC90ZD4iKwotICAgICAgICAgICAgICAgICAgICAiPHRkPjxjZW50ZXI+PGI+QnVpbGQgdGltZTwvYj48L2NlbnRlcj48L3RkPiIrCi0gICAgICAgICAgICAgICAgICAgICI8dGQ+PGNlbnRlcj48Yj5BY2Nlc3MgY291bnQ8L2I+PC9jZW50ZXI+PC90ZD4iKwotICAgICAgICAgICAgICAgICAgICAiPHRkPjxjZW50ZXI+PGI+TGFzdCBhY2Nlc3NlZDwvYj48L2NlbnRlcj48L3RkPiIrCi0gICAgICAgICAgICAgICAgICAgICI8dGQ+PGNlbnRlcj48Yj5MYXN0IG1vZGlmaWVkPC9iPjwvY2VudGVyPjwvdGQ+PC90cj4iKTsKLQotICAgICAgICBmb3IgKGludCBpPTA7IGk8X2NvdW50OyBpKyspIHsKLSAgICAgICAgICAgIENhY2hlZERvY3VtZW50IGRvYyA9IF9yZWZlcmVuY2VzLmdldChfVVJJc1tpXSk7Ci0gICAgICAgICAgICBvdXQucHJpbnQoIjx0cj48dGQ+PGEgaHJlZj1cIiIrX1VSSXNbaV0rIlwiPiIrCi0gICAgICAgICAgICAgICAgICAgICAgIjxmb250IHNpemU9LTE+IitfVVJJc1tpXSsiPC9mb250PjwvYT48L3RkPiIpOwotICAgICAgICAgICAgb3V0LnByaW50KCI8dGQ+PGNlbnRlcj4iK2RvYy5nZXRMYXRlbmN5KCkrIm1zPC9jZW50ZXI+PC90ZD4iKTsKLSAgICAgICAgICAgIG91dC5wcmludCgiPHRkPjxjZW50ZXI+Iitkb2MuZ2V0QWNjZXNzQ291bnQoKSsiPC9jZW50ZXI+PC90ZD4iKTsKLSAgICAgICAgICAgIG91dC5wcmludCgiPHRkPjxjZW50ZXI+IisobmV3IERhdGUoZG9jLmdldExhc3RSZWZlcmVuY2VkKCkpKSsKLSAgICAgICAgICAgICAgICAgICAgICAiPC9jZW50ZXI+PC90ZD4iKTsKLSAgICAgICAgICAgIG91dC5wcmludCgiPHRkPjxjZW50ZXI+IisobmV3IERhdGUoZG9jLmdldExhc3RNb2RpZmllZCgpKSkrCi0gICAgICAgICAgICAgICAgICAgICAgIjwvY2VudGVyPjwvdGQ+Iik7Ci0gICAgICAgICAgICBvdXQucHJpbnRsbigiPC90cj4iKTsKLSAgICAgICAgfQotCi0gICAgICAgIG91dC5wcmludGxuKCI8L3RhYmxlPjwvY2VudGVyPiIpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvZG9tL0R1cEZpbHRlckl0ZXJhdG9yLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2RvbS9EdXBGaWx0ZXJJdGVyYXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4YmEwMGY0Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvZG9tL0R1cEZpbHRlckl0ZXJhdG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNjYgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRHVwRmlsdGVySXRlcmF0b3IuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8wNiAwNjoxNjoxMSBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuZG9tOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnJ1bnRpbWUuQmFzaXNMaWJyYXJ5OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy51dGlsLkludGVnZXJBcnJheTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1BeGlzSXRlcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0ucmVmLkRUTUF4aXNJdGVyYXRvckJhc2U7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0ucmVmLkRUTURlZmF1bHRCYXNlOwotCi0vKioKLSAqIFJlbW92ZXMgZHVwbGljYXRlcyBhbmQgc29ydHMgYSBzb3VyY2UgaXRlcmF0b3IuIFRoZSBub2RlcyBmcm9tIHRoZQotICogc291cmNlIGFyZSBjb2xsZWN0ZWQgaW4gYW4gYXJyYXkgdXBvbiBjYWxsaW5nIHNldFN0YXJ0Tm9kZSgpLiBUaGlzCi0gKiBhcnJheSBpcyBsYXRlciBzb3J0ZWQgYW5kIGR1cGxpY2F0ZXMgYXJlIGlnbm9yZWQgaW4gbmV4dCgpLgotICogQGF1dGhvciBHLiBUb2RkIE1pbGxlcgotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgRHVwRmlsdGVySXRlcmF0b3IgZXh0ZW5kcyBEVE1BeGlzSXRlcmF0b3JCYXNlIHsKLQotICAgIC8qKgotICAgICAqIFJlZmVyZW5jZSB0byBzb3VyY2UgaXRlcmF0b3IuCi0gICAgICovCi0gICAgcHJpdmF0ZSBEVE1BeGlzSXRlcmF0b3IgX3NvdXJjZTsKLQotICAgIC8qKgotICAgICAqIEFycmF5IHRvIGNhY2hlIGFsbCBub2RlcyBmcm9tIHNvdXJjZS4KLSAgICAgKi8KLSAgICBwcml2YXRlIEludGVnZXJBcnJheSBfbm9kZXMgPSBuZXcgSW50ZWdlckFycmF5KCk7Ci0KLSAgICAvKioKLSAgICAgKiBJbmRleCBpbiBfbm9kZXMgYXJyYXkgdG8gY3VycmVudCBub2RlLgotICAgICAqLwotICAgIHByaXZhdGUgaW50IF9jdXJyZW50ID0gMDsKLQotICAgIC8qKgotICAgICAqIENhcmRpbmFsaXR5IG9mIF9ub2RlcyBhcnJheS4KLSAgICAgKi8KLSAgICBwcml2YXRlIGludCBfbm9kZXNTaXplID0gMDsKLQotICAgIC8qKgotICAgICAqIExhc3QgdmFsdWUgcmV0dXJuZWQgYnkgbmV4dCgpLgotICAgICAqLwotICAgIHByaXZhdGUgaW50IF9sYXN0TmV4dCA9IEVORDsKLQotICAgIC8qKgotICAgICAqIFRlbXBvcmFyeSB2YXJpYWJsZSB0byBzdG9yZSBfbGFzdE5leHQuCi0gICAgICovCi0gICAgcHJpdmF0ZSBpbnQgX21hcmtlZExhc3ROZXh0ID0gRU5EOwotCi0gICAgcHVibGljIER1cEZpbHRlckl0ZXJhdG9yKERUTUF4aXNJdGVyYXRvciBzb3VyY2UpIHsKLSAgICAgICAgX3NvdXJjZSA9IHNvdXJjZTsKLS8vIFN5c3RlbS5vdXQucHJpbnRsbigiREZJIHNvdXJjZSA9ICIgKyBzb3VyY2UgKyAiIHRoaXMgPSAiICsgdGhpcyk7Ci0KLSAgICAgICAgLy8gQ2FjaGUgY29udGVudHMgb2YgaWQoKSBvciBrZXkoKSBpbmRleCByaWdodCBhd2F5LiBOZWNlc3NhcnkgZm9yCi0gICAgICAgIC8vIHVuaW9uIGV4cHJlc3Npb25zIGNvbnRhaW5pbmcgbXVsdGlwbGUgY2FsbHMgdG8gdGhlIHNhbWUgaW5kZXgsIGFuZAotICAgICAgICAvLyBjb3JyZWN0IGFzIHdlbGwgc2luY2Ugc3RhcnQtbm9kZSBpcyBpcnJlbGV2YW50IGZvciBpZCgpL2tleSgpIGV4cnAuCi0gICAgICAgIGlmIChzb3VyY2UgaW5zdGFuY2VvZiBLZXlJbmRleCkgewotICAgICAgICAgICAgc2V0U3RhcnROb2RlKERUTURlZmF1bHRCYXNlLlJPT1ROT0RFKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldCB0aGUgc3RhcnQgbm9kZSBmb3IgdGhpcyBpdGVyYXRvcgotICAgICAqIEBwYXJhbSBub2RlIFRoZSBzdGFydCBub2RlCi0gICAgICogQHJldHVybiBBIHJlZmVyZW5jZSB0byB0aGlzIG5vZGUgaXRlcmF0b3IKLSAgICAgKi8KLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIHNldFN0YXJ0Tm9kZShpbnQgbm9kZSkgewotICAgICAgICBpZiAoX2lzUmVzdGFydGFibGUpIHsKLSAgICAgICAgICAgIC8vIEtleUluZGV4IGl0ZXJhdG9ycyBhcmUgYWx3YXlzIHJlbGF0aXZlIHRvIHRoZSByb290IG5vZGUsIHNvIHRoZXJlCi0gICAgICAgICAgICAvLyBpcyBuZXZlciBhbnkgcG9pbnQgaW4gcmUtcmVhZGluZyB0aGUgaXRlcmF0b3IgKGFuZCB3ZSBTSE9VTEQgTk9UKS4KLSAgICAgICAgICAgIGJvb2xlYW4gc291cmNlSXNLZXlJbmRleCA9IF9zb3VyY2UgaW5zdGFuY2VvZiBLZXlJbmRleDsKLQotICAgICAgICAgICAgaWYgKHNvdXJjZUlzS2V5SW5kZXgKLSAgICAgICAgICAgICAgICAgICAgJiYgX3N0YXJ0Tm9kZSA9PSBEVE1EZWZhdWx0QmFzZS5ST09UTk9ERSkgewotICAgICAgICAgICAgICAgIHJldHVybiB0aGlzOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAobm9kZSAhPSBfc3RhcnROb2RlKSB7Ci0gICAgICAgICAgICAgICAgX3NvdXJjZS5zZXRTdGFydE5vZGUoX3N0YXJ0Tm9kZSA9IG5vZGUpOwotCi0gICAgICAgICAgICAgICAgX25vZGVzLmNsZWFyKCk7Ci0gICAgICAgICAgICAgICAgd2hpbGUgKChub2RlID0gX3NvdXJjZS5uZXh0KCkpICE9IEVORCkgewotICAgICAgICAgICAgICAgICAgICBfbm9kZXMuYWRkKG5vZGUpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8vIE5vZGVzIHByb2R1Y2VkIGJ5IEtleUluZGV4IGFyZSBrbm93biB0byBiZSBpbiBkb2N1bWVudCBvcmRlci4KLSAgICAgICAgICAgICAgICAvLyBUYWtlIGFkdmFudGFnZSBvZiBpdC4KLSAgICAgICAgICAgICAgICBpZiAoIXNvdXJjZUlzS2V5SW5kZXgpIHsKLSAgICAgICAgICAgICAgICAgICAgX25vZGVzLnNvcnQoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgX25vZGVzU2l6ZSA9IF9ub2Rlcy5jYXJkaW5hbGl0eSgpOwotICAgICAgICAgICAgICAgIF9jdXJyZW50ID0gMDsKLSAgICAgICAgICAgICAgICBfbGFzdE5leHQgPSBFTkQ7Ci0gICAgICAgICAgICAgICAgcmVzZXRQb3NpdGlvbigpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiB0aGlzOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgbmV4dCgpIHsKLSAgICAgICAgd2hpbGUgKF9jdXJyZW50IDwgX25vZGVzU2l6ZSkgewotICAgICAgICAgICAgZmluYWwgaW50IG5leHQgPSBfbm9kZXMuYXQoX2N1cnJlbnQrKyk7Ci0gICAgICAgICAgICBpZiAobmV4dCAhPSBfbGFzdE5leHQpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gcmV0dXJuTm9kZShfbGFzdE5leHQgPSBuZXh0KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gRU5EOwotICAgIH0KLQotICAgIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3IgY2xvbmVJdGVyYXRvcigpIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGZpbmFsIER1cEZpbHRlckl0ZXJhdG9yIGNsb25lID0KLSAgICAgICAgICAgICAgICAoRHVwRmlsdGVySXRlcmF0b3IpIHN1cGVyLmNsb25lKCk7Ci0gICAgICAgICAgICBjbG9uZS5fbm9kZXMgPSAoSW50ZWdlckFycmF5KSBfbm9kZXMuY2xvbmUoKTsKLSAgICAgICAgICAgIGNsb25lLl9zb3VyY2UgPSBfc291cmNlLmNsb25lSXRlcmF0b3IoKTsKLSAgICAgICAgICAgIGNsb25lLl9pc1Jlc3RhcnRhYmxlID0gZmFsc2U7Ci0gICAgICAgICAgICByZXR1cm4gY2xvbmUucmVzZXQoKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgQmFzaXNMaWJyYXJ5LnJ1blRpbWVFcnJvcihCYXNpc0xpYnJhcnkuSVRFUkFUT1JfQ0xPTkVfRVJSLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlLnRvU3RyaW5nKCkpOwotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRSZXN0YXJ0YWJsZShib29sZWFuIGlzUmVzdGFydGFibGUpIHsKLSAgICAgICAgX2lzUmVzdGFydGFibGUgPSBpc1Jlc3RhcnRhYmxlOwotICAgICAgICBfc291cmNlLnNldFJlc3RhcnRhYmxlKGlzUmVzdGFydGFibGUpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldE1hcmsoKSB7Ci0gICAgICAgIF9tYXJrZWROb2RlID0gX2N1cnJlbnQ7Ci0gICAgICAgIF9tYXJrZWRMYXN0TmV4dCA9IF9sYXN0TmV4dDsgICAgLy8gQnVnemlsbGEgMjU5MjQKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBnb3RvTWFyaygpIHsKLSAgICAgICAgX2N1cnJlbnQgPSBfbWFya2VkTm9kZTsKLSAgICAgICAgX2xhc3ROZXh0ID0gX21hcmtlZExhc3ROZXh0OyAgICAvLyBCdWd6aWxsYSAyNTkyNAotICAgIH0KLQotICAgIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3IgcmVzZXQoKSB7Ci0gICAgICAgIF9jdXJyZW50ID0gMDsKLSAgICAgICAgX2xhc3ROZXh0ID0gRU5EOwotICAgICAgICByZXR1cm4gcmVzZXRQb3NpdGlvbigpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvZG9tL0VtcHR5RmlsdGVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2RvbS9FbXB0eUZpbHRlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1NzQyMGZmLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvZG9tL0VtcHR5RmlsdGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzNCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBFbXB0eUZpbHRlci5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzA2IDA2OjE3OjA1IHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5kb207Ci0KLS8qKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgRW1wdHlGaWx0ZXIgaW1wbGVtZW50cyBGaWx0ZXIgewotICAgIHB1YmxpYyBib29sZWFuIHRlc3QoaW50IG5vZGUpIHsKLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vRXh0ZW5kZWRTQVguamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvZG9tL0V4dGVuZGVkU0FYLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDJlYjkyN2QuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vRXh0ZW5kZWRTQVguamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDM2ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IEV4dGVuZGVkU0FYLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMDYgMDY6MTc6NDYgcHZlZHVsYSBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5kb207Ci0KLWltcG9ydCBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5EVERIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LmV4dC5EZWNsSGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXI7Ci0KLS8qKgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgRXh0ZW5kZWRTQVggZXh0ZW5kcyBDb250ZW50SGFuZGxlciwgTGV4aWNhbEhhbmRsZXIsIERUREhhbmRsZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGVjbEhhbmRsZXIKLXsKLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvZG9tL0ZpbHRlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vRmlsdGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDI0NWViZmYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vRmlsdGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzMiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBGaWx0ZXIuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8wNiAwNjoxODo1OCBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuZG9tOwotCi0vKioKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqLwotcHVibGljIGludGVyZmFjZSBGaWx0ZXIgewotICAgIHB1YmxpYyBib29sZWFuIHRlc3QoaW50IG5vZGUpOwotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vRmlsdGVySXRlcmF0b3IuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvZG9tL0ZpbHRlckl0ZXJhdG9yLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGQyN2M3NTkuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vRmlsdGVySXRlcmF0b3IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEyMCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBGaWx0ZXJJdGVyYXRvci5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzA2IDA2OjIxOjEwIHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5kb207Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMucnVudGltZS5CYXNpc0xpYnJhcnk7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNQXhpc0l0ZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTUZpbHRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1JdGVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5yZWYuRFRNQXhpc0l0ZXJhdG9yQmFzZTsKLQotLyoqCi0gKiBTaW1pbGFyIHRvIGEgQ3VycmVudE5vZGVMaXN0SXRlcmF0b3IgZXhjZXB0IHRoYXQgdGhlIGZpbHRlciBoYXMgYQotICogc2ltcGxlciBpbnRlcmZhY2UgKG9ubHkgbmVlZHMgdGhlIG5vZGUsIG5vIHBvc2l0aW9uLCBsYXN0LCBldGMuKQotICogSXQgdGFrZXMgYSBzb3VyY2UgaXRlcmF0b3IgYW5kIGEgRmlsdGVyIG9iamVjdCBhbmQgcmV0dXJucyBub2RlcwotICogZnJvbSB0aGUgc291cmNlIGFmdGVyIGZpbHRlcmluZyB0aGVtIGJ5IGNhbGxpbmcgZmlsdGVyLnRlc3Qobm9kZSkuCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBGaWx0ZXJJdGVyYXRvciBleHRlbmRzIERUTUF4aXNJdGVyYXRvckJhc2UgewotCi0gICAgLyoqCi0gICAgICogUmVmZXJlbmNlIHRvIHNvdXJjZSBpdGVyYXRvci4KLSAgICAgKi8KLSAgICBwcml2YXRlIERUTUF4aXNJdGVyYXRvciBfc291cmNlOwotCi0gICAgLyoqCi0gICAgICogUmVmZXJlbmNlIHRvIGEgZmlsdGVyIG9iamVjdCB0aGF0IHRvIGJlIGFwcGxpZWQgdG8gZWFjaCBub2RlLgotICAgICAqLwotICAgIHByaXZhdGUgZmluYWwgRFRNRmlsdGVyIF9maWx0ZXI7Ci0KLSAgICAvKioKLSAgICAgKiBBIGZsYWcgaW5kaWNhdGluZyBpZiBwb3NpdGlvbiBpcyByZXZlcnNlZC4KLSAgICAgKi8KLSAgICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gX2lzUmV2ZXJzZTsKLQotICAgIHB1YmxpYyBGaWx0ZXJJdGVyYXRvcihEVE1BeGlzSXRlcmF0b3Igc291cmNlLCBEVE1GaWx0ZXIgZmlsdGVyKSB7Ci0gICAgICAgIF9zb3VyY2UgPSBzb3VyY2U7Ci0vLyBTeXN0ZW0ub3V0LnByaW50bG4oIkZJIHNvdWNlID0gIiArIHNvdXJjZSArICIgdGhpcyA9ICIgKyB0aGlzKTsKLSAgICAgICAgX2ZpbHRlciA9IGZpbHRlcjsKLSAgICAgICAgX2lzUmV2ZXJzZSA9IHNvdXJjZS5pc1JldmVyc2UoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBpc1JldmVyc2UoKSB7Ci0gICAgICAgIHJldHVybiBfaXNSZXZlcnNlOwotICAgIH0KLQotCi0gICAgcHVibGljIHZvaWQgc2V0UmVzdGFydGFibGUoYm9vbGVhbiBpc1Jlc3RhcnRhYmxlKSB7Ci0gICAgICAgIF9pc1Jlc3RhcnRhYmxlID0gaXNSZXN0YXJ0YWJsZTsKLSAgICAgICAgX3NvdXJjZS5zZXRSZXN0YXJ0YWJsZShpc1Jlc3RhcnRhYmxlKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIGNsb25lSXRlcmF0b3IoKSB7Ci0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGZpbmFsIEZpbHRlckl0ZXJhdG9yIGNsb25lID0gKEZpbHRlckl0ZXJhdG9yKSBzdXBlci5jbG9uZSgpOwotICAgICAgICAgICAgY2xvbmUuX3NvdXJjZSA9IF9zb3VyY2UuY2xvbmVJdGVyYXRvcigpOwotICAgICAgICAgICAgY2xvbmUuX2lzUmVzdGFydGFibGUgPSBmYWxzZTsKLSAgICAgICAgICAgIHJldHVybiBjbG9uZS5yZXNldCgpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICBCYXNpc0xpYnJhcnkucnVuVGltZUVycm9yKEJhc2lzTGlicmFyeS5JVEVSQVRPUl9DTE9ORV9FUlIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGUudG9TdHJpbmcoKSk7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3IgcmVzZXQoKSB7Ci0gICAgICAgIF9zb3VyY2UucmVzZXQoKTsKLSAgICAgICAgcmV0dXJuIHJlc2V0UG9zaXRpb24oKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IG5leHQoKSB7Ci0gICAgICAgIGludCBub2RlOwotICAgICAgICB3aGlsZSAoKG5vZGUgPSBfc291cmNlLm5leHQoKSkgIT0gRU5EKSB7Ci0gICAgICAgICAgICBpZiAoX2ZpbHRlci5hY2NlcHROb2RlKG5vZGUsIERUTUZpbHRlci5TSE9XX0FMTCkgPT0gRFRNSXRlcmF0b3IuRklMVEVSX0FDQ0VQVCkgewotICAgICAgICAgICAgICAgIHJldHVybiByZXR1cm5Ob2RlKG5vZGUpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBFTkQ7Ci0gICAgfQotCi0gICAgcHVibGljIERUTUF4aXNJdGVyYXRvciBzZXRTdGFydE5vZGUoaW50IG5vZGUpIHsKLSAgICAgICAgaWYgKF9pc1Jlc3RhcnRhYmxlKSB7Ci0gICAgICAgICAgICBfc291cmNlLnNldFN0YXJ0Tm9kZShfc3RhcnROb2RlID0gbm9kZSk7Ci0gICAgICAgICAgICByZXR1cm4gcmVzZXRQb3NpdGlvbigpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiB0aGlzOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldE1hcmsoKSB7Ci0gICAgICAgIF9zb3VyY2Uuc2V0TWFyaygpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGdvdG9NYXJrKCkgewotICAgICAgICBfc291cmNlLmdvdG9NYXJrKCk7Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2RvbS9GaWx0ZXJlZFN0ZXBJdGVyYXRvci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vRmlsdGVyZWRTdGVwSXRlcmF0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNzA0ZWJiNC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2RvbS9GaWx0ZXJlZFN0ZXBJdGVyYXRvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTYgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRmlsdGVyZWRTdGVwSXRlcmF0b3IuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8wNiAwNjoyMDoxMyBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuZG9tOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNQXhpc0l0ZXJhdG9yOwotCi0vKioKLSAqIEV4dGVuZHMgYSBTdGVwSXRlcmF0b3IgYnkgYWRkaW5nIHRoZSBhYmlsaXR5IHRvIGZpbHRlciBub2Rlcy4gSXQKLSAqIHVzZXMgZmlsdGVycyBzaW1pbGFyIHRvIHRob3NlIG9mIGEgRmlsdGVySXRlcmF0b3IuCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIEZpbHRlcmVkU3RlcEl0ZXJhdG9yIGV4dGVuZHMgU3RlcEl0ZXJhdG9yIHsKLQotICAgIHByaXZhdGUgRmlsdGVyIF9maWx0ZXI7Ci0KLSAgICBwdWJsaWMgRmlsdGVyZWRTdGVwSXRlcmF0b3IoRFRNQXhpc0l0ZXJhdG9yIHNvdXJjZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFRNQXhpc0l0ZXJhdG9yIGl0ZXJhdG9yLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWx0ZXIgZmlsdGVyKSB7Ci0gICAgICAgIHN1cGVyKHNvdXJjZSwgaXRlcmF0b3IpOwotICAgICAgICBfZmlsdGVyID0gZmlsdGVyOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgbmV4dCgpIHsKLSAgICAgICAgaW50IG5vZGU7Ci0gICAgICAgIHdoaWxlICgobm9kZSA9IHN1cGVyLm5leHQoKSkgIT0gRU5EKSB7Ci0gICAgICAgICAgICBpZiAoX2ZpbHRlci50ZXN0KG5vZGUpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHJldHVybk5vZGUobm9kZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG5vZGU7Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2RvbS9Gb3J3YXJkUG9zaXRpb25JdGVyYXRvci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vRm9yd2FyZFBvc2l0aW9uSXRlcmF0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZjkwMmRmOS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2RvbS9Gb3J3YXJkUG9zaXRpb25JdGVyYXRvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTA5ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IEZvcndhcmRQb3NpdGlvbkl0ZXJhdG9yLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMDYgMDY6MjI6MDUgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmRvbTsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5ydW50aW1lLkJhc2lzTGlicmFyeTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1BeGlzSXRlcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0ucmVmLkRUTUF4aXNJdGVyYXRvckJhc2U7Ci0KLS8qKgotICogVGhpcyBpdGVyYXRvciBpcyBhIHdyYXBwZXIgdGhhdCBhbHdheXMgcmV0dXJucyB0aGUgcG9zaXRpb24gb2YKLSAqIGEgbm9kZSBpbiBkb2N1bWVudCBvcmRlci4gSXQgaXMgbmVlZGVkIGZvciB0aGUgY2FzZSB3aGVyZQotICogYSBjYWxsIHRvIHBvc2l0aW9uKCkgb2NjdXJzIGluIHRoZSBjb250ZXh0IG9mIGFuIFhTTFQgZWxlbWVudAotICogc3VjaCBhcyB4c2w6Zm9yLWVhY2gsIHhzbDphcHBseS10ZW1wbGF0ZXMsIGV0Yy4KLSAqCi0gKiBUaGUgZ2V0UG9zaXRpb24oKSBtZXRob2RzIGluIERUTUF4aXNJdGVyYXRvcnMgZGVmaW5lZAotICogaW4gRFRNRGVmYXVsdEJhc2VJdGVyYXRvcnMgYWx3YXlzIHJldHVybiB0aGUgcG9zaXRpb24KLSAqIGluIGRvY3VtZW50IG9yZGVyLCB3aGljaCBpcyBiYWNrd2FyZHMgZm9yIFhQYXRoIGluIHRoZQotICogY2FzZSBvZiB0aGUgYW5jZXN0b3IsIGFuY2VzdG9yLW9yLXNlbGYsIHByZXZpb3VzIGFuZAotICogcHJldmlvdXMtc2libGluZy4KLSAqCi0gKiBYU0xUQyBpbXBsZW1lbnRzIHBvc2l0aW9uKCkgd2l0aCB0aGUKLSAqIEJhc2lzTGlicmFyeS5wb3NpdGlvbkYoKSBtZXRob2QsIGFuZCB1c2VzIHRoZQotICogRFRNQXhpc0l0ZXJhdG9yLmlzUmV2ZXJzZSgpIG1ldGhvZCB0byBkZXRlcm1pbmUKLSAqIHdoZXRoZXIgdGhlIHJlc3VsdCBvZiBnZXRQb3NpdGlvbigpIHNob3VsZCBiZQotICogaW50ZXJwcmV0ZWQgYXMgYmVpbmcgZXF1YWwgdG8gcG9zaXRpb24oKS4KLSAqIEJ1dCB3aGVuIHRoZSBleHByZXNzaW9uIGFwcGVhcnMgaW4gYXBwbHktdGVtcGxhdGVzIG9mCi0gKiBmb3ItZWFjaCwgdGhlIHBvc2l0aW9uKCkgZnVuY3Rpb24gb3BlcmF0ZXMgaW4gZG9jdW1lbnQKLSAqIG9yZGVyLgotICoKLSAqIFRoZSBvbmx5IGVmZmVjdCBvZiB0aGUgRm9yd2FyZFBvc2l0aW9uSXRlcmF0b3IgaXMgdG8gZm9yY2UKLSAqIHRoZSByZXN1bHQgb2YgaXNSZXZlcnNlKCkgdG8gZmFsc2UsIHNvIHRoYXQKLSAqIEJhc2lzTGlicmFyeS5wb3NpdGlvbkYoKSBjYWxjdWxhdGVzIHBvc2l0aW9uKCkgaW4gYSB3YXkKLSAqIHRoYXQncyBjb25zaXN0ZW50IHdpdGggdGhlIGNvbnRleHQgaW4gd2hpY2ggdGhlCi0gKiBpdGVyYXRvciBpcyBiZWluZyB1c2VkLiIKLSAqCi0gKiAoQXBwYXJlbnRseSB0aGUgY29ycmVjdGlvbiBvZiBpc1JldmVyc2UoKSBvY2N1cnMKLSAqIGltcGxpY2l0bHksIGJ5IGluaGVyaXRhbmNlLiBUaGlzIGNsYXNzIGFsc28gYXBwZWFycwotICogdG8gbWFpbnRhaW4gaXRzIG93biBwb3NpdGlvbiBjb3VudGVyLCB3aGljaCBzZWVtcwotICogcmVkdW5kYW50LikKLSAqCi0gKiBAZGVwcmVjYXRlZCBUaGlzIGNsYXNzIGV4aXN0cyBvbmx5IGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eSB3aXRoIG9sZAotICogICAgICAgICAgICAgdHJhbnNsZXRzLiAgTmV3IGNvZGUgc2hvdWxkIG5vdCByZWZlcmVuY2UgaXQuCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBGb3J3YXJkUG9zaXRpb25JdGVyYXRvciBleHRlbmRzIERUTUF4aXNJdGVyYXRvckJhc2UgewotCi0gICAgcHJpdmF0ZSBEVE1BeGlzSXRlcmF0b3IgX3NvdXJjZTsKLQotICAgIHB1YmxpYyBGb3J3YXJkUG9zaXRpb25JdGVyYXRvcihEVE1BeGlzSXRlcmF0b3Igc291cmNlKSB7Ci0gICAgICAgIF9zb3VyY2UgPSBzb3VyY2U7Ci0gICAgfQotCi0gICAgcHVibGljIERUTUF4aXNJdGVyYXRvciBjbG9uZUl0ZXJhdG9yKCkgewotICAgICAgICB0cnkgewotICAgICAgICAgICAgZmluYWwgRm9yd2FyZFBvc2l0aW9uSXRlcmF0b3IgY2xvbmUgPQotICAgICAgICAgICAgICAgIChGb3J3YXJkUG9zaXRpb25JdGVyYXRvcikgc3VwZXIuY2xvbmUoKTsKLSAgICAgICAgICAgIGNsb25lLl9zb3VyY2UgPSBfc291cmNlLmNsb25lSXRlcmF0b3IoKTsKLSAgICAgICAgICAgIGNsb25lLl9pc1Jlc3RhcnRhYmxlID0gZmFsc2U7Ci0gICAgICAgICAgICByZXR1cm4gY2xvbmUucmVzZXQoKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgQmFzaXNMaWJyYXJ5LnJ1blRpbWVFcnJvcihCYXNpc0xpYnJhcnkuSVRFUkFUT1JfQ0xPTkVfRVJSLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlLnRvU3RyaW5nKCkpOwotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IG5leHQoKSB7Ci0gICAgICAgIHJldHVybiByZXR1cm5Ob2RlKF9zb3VyY2UubmV4dCgpKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIHNldFN0YXJ0Tm9kZShpbnQgbm9kZSkgewotICAgICAgICBfc291cmNlLnNldFN0YXJ0Tm9kZShub2RlKTsKLSAgICAgICAgcmV0dXJuIHRoaXM7Ci0gICAgfQotCi0gICAgcHVibGljIERUTUF4aXNJdGVyYXRvciByZXNldCgpIHsKLSAgICAgICAgX3NvdXJjZS5yZXNldCgpOwotICAgICAgICByZXR1cm4gcmVzZXRQb3NpdGlvbigpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldE1hcmsoKSB7Ci0gICAgICAgIF9zb3VyY2Uuc2V0TWFyaygpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGdvdG9NYXJrKCkgewotICAgICAgICBfc291cmNlLmdvdG9NYXJrKCk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vS2V5SW5kZXguamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvZG9tL0tleUluZGV4LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDVlYjE3ZDcuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vS2V5SW5kZXguamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDkwMCArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDA3LCAyMDE1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICovCi0vKgotICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCi0gKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKLSAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KLSAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCi0gKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAotICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IEtleUluZGV4LmphdmEsdiAxLjYgMjAwNi8wNi8xOSAxOTo0OTowMiBzcGVyaWNhcyBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmRvbTsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5ET007Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLkRPTUVuaGFuY2VkRm9yRFRNOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5ydW50aW1lLkJhc2lzTGlicmFyeTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMudXRpbC5JbnRlZ2VyQXJyYXk7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uQXhpczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE07Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNQXhpc0l0ZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLnJlZi5EVE1BeGlzSXRlcmF0b3JCYXNlOwotaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwotaW1wb3J0IGphdmEudXRpbC5NYXA7Ci1pbXBvcnQgamF2YS51dGlsLlN0cmluZ1Rva2VuaXplcjsKLQotLyoqCi0gKiBTdG9yZXMgbWFwcGluZ3Mgb2Yga2V5IHZhbHVlcyBvciBJRHMgdG8gRFRNIG5vZGVzLgotICogPGVtPlVzZSBvZiBhbiBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIGFzIGEge0BsaW5rIERUTUF4aXNJdGVyYXRvcn0gaXMKLSAqIDxiPmRlcHJlY2F0ZWQuPC9iPjwvZW0+Ci0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICovCi1wdWJsaWMgY2xhc3MgS2V5SW5kZXggZXh0ZW5kcyBEVE1BeGlzSXRlcmF0b3JCYXNlIHsKLQotICAgIC8qKgotICAgICAqIEEgbWFwcGluZyBiZXR3ZWVuIHZhbHVlcyBhbmQgbm9kZXNldHMgZm9yIHRoZSBjdXJyZW50IGRvY3VtZW50LiAgVXNlZAotICAgICAqIG9ubHkgd2hpbGUgYnVpbGRpbmcga2V5cy4KLSAgICAgKi8KLSAgICBwcml2YXRlIE1hcDxTdHJpbmcsIEludGVnZXJBcnJheT4gX2luZGV4OwotCi0gICAgLyoqCi0gICAgICogVGhlIGRvY3VtZW50IG5vZGUgY3VycmVudGx5IGJlaW5nIHByb2Nlc3NlZC4gIFVzZWQgb25seSB3aGlsZSBidWlsZGluZwotICAgICAqIGtleXMuCi0gICAgICovCi0gICAgcHJpdmF0ZSBpbnQgX2N1cnJlbnREb2N1bWVudE5vZGUgPSBEVE0uTlVMTDsKLQotICAgIC8qKgotICAgICAqIEEgbWFwcGluZyBmcm9tIGEgZG9jdW1lbnQgbm9kZSB0byB0aGUgbWFwcGluZyBiZXR3ZWVuIHZhbHVlcyBhbmQgbm9kZXNldHMKLSAgICAgKi8KLSAgICBwcml2YXRlIE1hcDxJbnRlZ2VyLCBNYXA+IF9yb290VG9JbmRleE1hcCA9IG5ldyBIYXNoTWFwPD4oKTsKLQotICAgIC8qKgotICAgICAqIFRoZSBub2RlIHNldCBhc3NvY2lhdGVkIHRvIHRoZSBjdXJyZW50IHZhbHVlIHBhc3NlZAotICAgICAqIHRvIGxvb2t1cEtleSgpOwotICAgICAqLwotICAgIHByaXZhdGUgSW50ZWdlckFycmF5IF9ub2RlcyA9IG51bGw7Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgWFNMVEMgRE9NIG9iamVjdCBpZiB0aGlzIEtleUluZGV4IGlzIGJlaW5nIHVzZWQgdG8gaW1wbGVtZW50IHRoZQotICAgICAqIGlkKCkgZnVuY3Rpb24uCi0gICAgICovCi0gICAgcHJpdmF0ZSBET00gICAgICAgIF9kb207Ci0KLSAgICBwcml2YXRlIERPTUVuaGFuY2VkRm9yRFRNICAgIF9lbmhhbmNlZERPTTsKLQotICAgIC8qKgotICAgICAqIFN0b3JlIHBvc2l0aW9uIGFmdGVyIGNhbGwgdG8gc2V0TWFyaygpCi0gICAgICovCi0gICAgcHJpdmF0ZSBpbnQgX21hcmtlZFBvc2l0aW9uID0gMDsKLQotICAgIHB1YmxpYyBLZXlJbmRleChpbnQgZHVtbXkpIHsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRSZXN0YXJ0YWJsZShib29sZWFuIGZsYWcpIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBZGRzIGEgbm9kZSB0byB0aGUgbm9kZSBsaXN0IGZvciBhIGdpdmVuIHZhbHVlLiBOb2RlcyB3aWxsCi0gICAgICogYWx3YXlzIGJlIGFkZGVkIGluIGRvY3VtZW50IG9yZGVyLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGFkZChTdHJpbmcgdmFsdWUsIGludCBub2RlLCBpbnQgcm9vdE5vZGUpIHsKLSAgICAgICAgaWYgKF9jdXJyZW50RG9jdW1lbnROb2RlICE9IHJvb3ROb2RlKSB7Ci0gICAgICAgICAgICBfY3VycmVudERvY3VtZW50Tm9kZSA9IHJvb3ROb2RlOwotICAgICAgICAgICAgX2luZGV4ID0gbmV3IEhhc2hNYXA8PigpOwotICAgICAgICAgICAgX3Jvb3RUb0luZGV4TWFwLnB1dChyb290Tm9kZSwgX2luZGV4KTsKLSAgICAgICAgfQotCi0gICAgICAgIEludGVnZXJBcnJheSBub2RlcyA9IF9pbmRleC5nZXQodmFsdWUpOwotCi0gICAgICAgIGlmIChub2RlcyA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgbm9kZXMgPSBuZXcgSW50ZWdlckFycmF5KCk7Ci0gICAgICAgICAgICBfaW5kZXgucHV0KHZhbHVlLCBub2Rlcyk7Ci0gICAgICAgICAgICBub2Rlcy5hZGQobm9kZSk7Ci0KLSAgICAgICAgLy8gQmVjYXVzZSBub2RlcyBhcmUgYWRkZWQgaW4gZG9jdW1lbnQgb3JkZXIsCi0gICAgICAgIC8vIGR1cGxpY2F0ZXMgY2FuIGJlIGVsaW1pbmF0ZWQgZWFzaWx5IGF0IHRoaXMgc3RhZ2UuCi0gICAgICAgIH0gZWxzZSBpZiAobm9kZSAhPSBub2Rlcy5hdChub2Rlcy5jYXJkaW5hbGl0eSgpIC0gMSkpIHsKLSAgICAgICAgICAgIG5vZGVzLmFkZChub2RlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIE1lcmdlIHRoZSBjdXJyZW50IHZhbHVlJ3Mgbm9kZXNldCBzZXQgYnkgbG9va3VwS2V5KCkgd2l0aCBfbm9kZXMuCi0gICAgICogQGRlcHJlY2F0ZWQKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBtZXJnZShLZXlJbmRleCBvdGhlcikgewotICAgICAgICBpZiAob3RoZXIgPT0gbnVsbCkgcmV0dXJuOwotCi0gICAgICAgIGlmIChvdGhlci5fbm9kZXMgIT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKF9ub2RlcyA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgX25vZGVzID0gKEludGVnZXJBcnJheSlvdGhlci5fbm9kZXMuY2xvbmUoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIF9ub2Rlcy5tZXJnZShvdGhlci5fbm9kZXMpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgbXVzdCBiZSBjYWxsZWQgYnkgdGhlIGNvZGUgZ2VuZXJhdGVkIGJ5IHRoZSBpZCgpIGZ1bmN0aW9uCi0gICAgICogcHJpb3IgdG8gcmV0dXJuaW5nIHRoZSBub2RlIGl0ZXJhdG9yLiBUaGUgbG9va3VwIGNvZGUgZm9yIGtleSgpIGFuZAotICAgICAqIGlkKCkgZGlmZmVyIGluIHRoZSB3YXkgdGhlIGxvb2t1cCB2YWx1ZSBjYW4gYmUgd2hpdGVzcGFjZSBzZXBhcmF0ZWQKLSAgICAgKiBsaXN0IG9mIHRva2VucyBmb3IgdGhlIGlkKCkgZnVuY3Rpb24sIGJ1dCBhIHNpbmdsZSBzdHJpbmcgZm9yIHRoZQotICAgICAqIGtleSgpIGZ1bmN0aW9uLgotICAgICAqIEBkZXByZWNhdGVkCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgbG9va3VwSWQoT2JqZWN0IHZhbHVlKSB7Ci0gICAgICAgIC8vIENsZWFyIF9ub2RlcyBhcnJheQotICAgICAgICBfbm9kZXMgPSBudWxsOwotCi0gICAgICAgIGZpbmFsIFN0cmluZ1Rva2VuaXplciB2YWx1ZXMgPSBuZXcgU3RyaW5nVG9rZW5pemVyKChTdHJpbmcpIHZhbHVlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIFxuXHQiKTsKLSAgICAgICAgd2hpbGUgKHZhbHVlcy5oYXNNb3JlRWxlbWVudHMoKSkgewotICAgICAgICAgICAgZmluYWwgU3RyaW5nIHRva2VuID0gKFN0cmluZykgdmFsdWVzLm5leHRFbGVtZW50KCk7Ci0gICAgICAgICAgICBJbnRlZ2VyQXJyYXkgbm9kZXMgPSBfaW5kZXguZ2V0KHRva2VuKTsKLQotICAgICAgICAgICAgaWYgKG5vZGVzID09IG51bGwgJiYgX2VuaGFuY2VkRE9NICE9IG51bGwKLSAgICAgICAgICAgICAgICAmJiBfZW5oYW5jZWRET00uaGFzRE9NU291cmNlKCkpIHsKLSAgICAgICAgICAgICAgICBub2RlcyA9IGdldERPTU5vZGVCeUlkKHRva2VuKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKG5vZGVzID09IG51bGwpIGNvbnRpbnVlOwotCi0gICAgICAgICAgICBpZiAoX25vZGVzID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgbm9kZXMgPSAoSW50ZWdlckFycmF5KW5vZGVzLmNsb25lKCk7Ci0gICAgICAgICAgICAgICAgX25vZGVzID0gbm9kZXM7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBfbm9kZXMubWVyZ2Uobm9kZXMpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIGFuIEludGVnZXJBcnJheSBmb3IgdGhlIERPTSBOb2RlIHdoaWNoIGhhcyB0aGUgZ2l2ZW4gaWQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaWQgVGhlIGlkCi0gICAgICogQHJldHVybiBBIEludGVnZXJBcnJheSByZXByZXNlbnRpbmcgdGhlIE5vZGUgd2hvc2UgaWQgaXMgdGhlIGdpdmVuIHZhbHVlLgotICAgICAqLwotICAgIHB1YmxpYyBJbnRlZ2VyQXJyYXkgZ2V0RE9NTm9kZUJ5SWQoU3RyaW5nIGlkKSB7Ci0gICAgICAgIEludGVnZXJBcnJheSBub2RlcyA9IG51bGw7Ci0KLSAgICAgICAgaWYgKF9lbmhhbmNlZERPTSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpbnQgaWRlbnQgPSBfZW5oYW5jZWRET00uZ2V0RWxlbWVudEJ5SWQoaWQpOwotCi0gICAgICAgICAgICBpZiAoaWRlbnQgIT0gRFRNLk5VTEwpIHsKLSAgICAgICAgICAgICAgICBJbnRlZ2VyIHJvb3QgPSBuZXcgSW50ZWdlcihfZW5oYW5jZWRET00uZ2V0RG9jdW1lbnQoKSk7Ci0gICAgICAgICAgICAgICAgTWFwPFN0cmluZywgSW50ZWdlckFycmF5PiBpbmRleCA9IF9yb290VG9JbmRleE1hcC5nZXQocm9vdCk7Ci0KLSAgICAgICAgICAgICAgICBpZiAoaW5kZXggPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBpbmRleCA9IG5ldyBIYXNoTWFwPD4oKTsKLSAgICAgICAgICAgICAgICAgICAgX3Jvb3RUb0luZGV4TWFwLnB1dChyb290LCBpbmRleCk7Ci0gICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgbm9kZXMgPSBpbmRleC5nZXQoaWQpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIGlmIChub2RlcyA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIG5vZGVzID0gbmV3IEludGVnZXJBcnJheSgpOwotICAgICAgICAgICAgICAgICAgICBpbmRleC5wdXQoaWQsIG5vZGVzKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBub2Rlcy5hZGQoX2VuaGFuY2VkRE9NLmdldE5vZGVIYW5kbGUoaWRlbnQpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBub2RlczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5UaGlzIG1ldGhvZCBtdXN0IGJlIGNhbGxlZCBieSB0aGUgY29kZSBnZW5lcmF0ZWQgYnkgdGhlIGtleSgpIGZ1bmN0aW9uCi0gICAgICogcHJpb3IgdG8gcmV0dXJuaW5nIHRoZSBub2RlIGl0ZXJhdG9yLjwvcD4KLSAgICAgKiA8cD48ZW0+VXNlIG9mIGFuIGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgYXMgYSB7QGxpbmsgRFRNQXhpc0l0ZXJhdG9yfSBpcwotICAgICAqIDxiPmRlcHJlY2F0ZWQuPC9iPjwvZW0+PC9wPgotICAgICAqIEBkZXByZWNhdGVkCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgbG9va3VwS2V5KE9iamVjdCB2YWx1ZSkgewotICAgICAgICBJbnRlZ2VyQXJyYXkgbm9kZXMgPSBfaW5kZXguZ2V0KHZhbHVlKTsKLSAgICAgICAgX25vZGVzID0gKG5vZGVzICE9IG51bGwpID8gKEludGVnZXJBcnJheSkgbm9kZXMuY2xvbmUoKSA6IG51bGw7Ci0gICAgICAgIF9wb3NpdGlvbiA9IDA7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+Q2FsbGVycyBzaG91bGQgbm90IGNhbGwgbmV4dCgpIGFmdGVyIGl0IHJldHVybnMgRU5ELjwvcD4KLSAgICAgKiA8cD48ZW0+VXNlIG9mIGFuIGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgYXMgYSB7QGxpbmsgRFRNQXhpc0l0ZXJhdG9yfSBpcwotICAgICAqIDxiPmRlcHJlY2F0ZWQuPC9iPjwvZW0+PC9wPgotICAgICAqIEBkZXByZWNhdGVkCi0gICAgICovCi0gICAgcHVibGljIGludCBuZXh0KCkgewotICAgICAgICBpZiAoX25vZGVzID09IG51bGwpIHJldHVybiBEVE1BeGlzSXRlcmF0b3IuRU5EOwotCi0gICAgICAgIHJldHVybiAoX3Bvc2l0aW9uIDwgX25vZGVzLmNhcmRpbmFsaXR5KCkpID8KLSAgICAgICAgICAgIF9kb20uZ2V0Tm9kZUhhbmRsZShfbm9kZXMuYXQoX3Bvc2l0aW9uKyspKSA6IERUTUF4aXNJdGVyYXRvci5FTkQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2l2ZW4gYSBjb250ZXh0IG5vZGUgYW5kIHRoZSBhcmd1bWVudCB0byB0aGUgWFBhdGggPGNvZGU+aWQ8L2NvZGU+Ci0gICAgICogZnVuY3Rpb24sIGNoZWNrcyB3aGV0aGVyIHRoZSBjb250ZXh0IG5vZGUgaXMgaW4gdGhlIHNldCBvZiBub2RlcyB0aGF0Ci0gICAgICogcmVzdWx0cyBmcm9tIHRoYXQgcmVmZXJlbmNlIHRvIHRoZSA8Y29kZT5pZDwvY29kZT4gZnVuY3Rpb24uICBUaGlzIGlzCi0gICAgICogdXNlZCBpbiB0aGUgaW1wbGVtZW50YXRpb24gb2YgPGNvZGU+aWQ8L2NvZGU+IHBhdHRlcm5zLgotICAgICAqCi0gICAgICogQHBhcmFtIG5vZGUgVGhlIGNvbnRleHQgbm9kZQotICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYXJndW1lbnQgdG8gdGhlIDxjb2RlPmlkPC9jb2RlPiBmdW5jdGlvbgotICAgICAqIEByZXR1cm4gPGNvZGU+MTwvY29kZT4gaWYgdGhlIGNvbnRleHQgbm9kZSBpcyBpbiB0aGUgc2V0IG9mIG5vZGVzCi0gICAgICogICAgICAgICByZXR1cm5lZCBieSB0aGUgcmVmZXJlbmNlIHRvIHRoZSA8Y29kZT5pZDwvY29kZT4gZnVuY3Rpb247Ci0gICAgICogICAgICAgICA8Y29kZT4wPC9jb2RlPiwgb3RoZXJ3aXNlCi0gICAgICovCi0gICAgcHVibGljIGludCBjb250YWluc0lEKGludCBub2RlLCBPYmplY3QgdmFsdWUpIHsKLSAgICAgICAgZmluYWwgU3RyaW5nIHN0cmluZyA9IChTdHJpbmcpdmFsdWU7Ci0gICAgICAgIGludCByb290SGFuZGxlID0gX2RvbS5nZXRBeGlzSXRlcmF0b3IoQXhpcy5ST09UKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnNldFN0YXJ0Tm9kZShub2RlKS5uZXh0KCk7Ci0KLSAgICAgICAgLy8gR2V0IHRoZSBtYXBwaW5nIHRhYmxlIGZvciB0aGUgZG9jdW1lbnQgY29udGFpbmluZyB0aGUgY29udGV4dCBub2RlCi0gICAgICAgIE1hcDxTdHJpbmcsIEludGVnZXJBcnJheT4gaW5kZXggPQotICAgICAgICAgICAgX3Jvb3RUb0luZGV4TWFwLmdldChyb290SGFuZGxlKTsKLQotICAgICAgICAvLyBTcGxpdCBhcmd1bWVudCB0byBpZCBmdW5jdGlvbiBpbnRvIFhNTCB3aGl0ZXNwYWNlIHNlcGFyYXRlZCB0b2tlbnMKLSAgICAgICAgZmluYWwgU3RyaW5nVG9rZW5pemVyIHZhbHVlcyA9IG5ldyBTdHJpbmdUb2tlbml6ZXIoc3RyaW5nLCAiIFxuXHQiKTsKLQotICAgICAgICB3aGlsZSAodmFsdWVzLmhhc01vcmVFbGVtZW50cygpKSB7Ci0gICAgICAgICAgICBmaW5hbCBTdHJpbmcgdG9rZW4gPSAoU3RyaW5nKSB2YWx1ZXMubmV4dEVsZW1lbnQoKTsKLSAgICAgICAgICAgIEludGVnZXJBcnJheSBub2RlcyA9IG51bGw7Ci0KLSAgICAgICAgICAgIGlmIChpbmRleCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgbm9kZXMgPSBpbmRleC5nZXQodG9rZW4pOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBJZiBpbnB1dCB3YXMgZnJvbSBXM0MgRE9NLCB1c2UgRE9NJ3MgZ2V0RWxlbWVudEJ5SWQgdG8gZG8KLSAgICAgICAgICAgIC8vIHRoZSBsb29rLXVwLgotICAgICAgICAgICAgaWYgKG5vZGVzID09IG51bGwgJiYgX2VuaGFuY2VkRE9NICE9IG51bGwKLSAgICAgICAgICAgICAgICAmJiBfZW5oYW5jZWRET00uaGFzRE9NU291cmNlKCkpIHsKLSAgICAgICAgICAgICAgICBub2RlcyA9IGdldERPTU5vZGVCeUlkKHRva2VuKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gRGlkIHdlIGZpbmQgdGhlIGNvbnRleHQgbm9kZSBpbiB0aGUgc2V0IG9mIG5vZGVzPwotICAgICAgICAgICAgaWYgKG5vZGVzICE9IG51bGwgJiYgbm9kZXMuaW5kZXhPZihub2RlKSA+PSAwKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIDE7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBEaWRuJ3QgZmluZCB0aGUgY29udGV4dCBub2RlIGluIHRoZSBzZXQgb2Ygbm9kZXMgcmV0dXJuZWQgYnkgaWQKLSAgICAgICAgcmV0dXJuIDA7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+R2l2ZW4gYSBjb250ZXh0IG5vZGUgYW5kIHRoZSBzZWNvbmQgYXJndW1lbnQgdG8gdGhlIFhTTFQKLSAgICAgKiA8Y29kZT5rZXk8L2NvZGU+IGZ1bmN0aW9uLCBjaGVja3Mgd2hldGhlciB0aGUgY29udGV4dCBub2RlIGlzIGluIHRoZQotICAgICAqIHNldCBvZiBub2RlcyB0aGF0IHJlc3VsdHMgZnJvbSB0aGF0IHJlZmVyZW5jZSB0byB0aGUgPGNvZGU+a2V5PC9jb2RlPgotICAgICAqIGZ1bmN0aW9uLiAgVGhpcyBpcyB1c2VkIGluIHRoZSBpbXBsZW1lbnRhdGlvbiBvZiBrZXkgcGF0dGVybnMuPC9wPgotICAgICAqIDxwPlRoaXMgcGFydGljdWxhciB7QGxpbmsgS2V5SW5kZXh9IG9iamVjdCBpcyB0aGUgcmVzdWx0IGV2YWx1YXRpbmcgdGhlCi0gICAgICogZmlyc3QgYXJndW1lbnQgdG8gdGhlIDxjb2RlPmtleTwvY29kZT4gZnVuY3Rpb24sIHNvIGl0J3Mgbm90IHRha2VuIGludG8KLSAgICAgKiBhbnkgZnVydGhlciBhY2NvdW50LjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBub2RlIFRoZSBjb250ZXh0IG5vZGUKLSAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHNlY29uZCBhcmd1bWVudCB0byB0aGUgPGNvZGU+a2V5PC9jb2RlPiBmdW5jdGlvbgotICAgICAqIEByZXR1cm4gPGNvZGU+MTwvY29kZT4gaWYgYW5kIG9ubHkgaWYgdGhlIGNvbnRleHQgbm9kZSBpcyBpbiB0aGUgc2V0IG9mCi0gICAgICogICAgICAgICBub2RlcyByZXR1cm5lZCBieSB0aGUgcmVmZXJlbmNlIHRvIHRoZSA8Y29kZT5rZXk8L2NvZGU+IGZ1bmN0aW9uOwotICAgICAqICAgICAgICAgPGNvZGU+MDwvY29kZT4sIG90aGVyd2lzZQotICAgICAqLwotICAgIHB1YmxpYyBpbnQgY29udGFpbnNLZXkoaW50IG5vZGUsIE9iamVjdCB2YWx1ZSkgewotICAgICAgICBpbnQgcm9vdEhhbmRsZSA9IF9kb20uZ2V0QXhpc0l0ZXJhdG9yKEF4aXMuUk9PVCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5zZXRTdGFydE5vZGUobm9kZSkubmV4dCgpOwotCi0gICAgICAgIC8vIEdldCB0aGUgbWFwcGluZyB0YWJsZSBmb3IgdGhlIGRvY3VtZW50IGNvbnRhaW5pbmcgdGhlIGNvbnRleHQgbm9kZQotICAgICAgICBNYXA8U3RyaW5nLEludGVnZXJBcnJheT4gaW5kZXggPQotICAgICAgICAgICAgICAgICAgICBfcm9vdFRvSW5kZXhNYXAuZ2V0KG5ldyBJbnRlZ2VyKHJvb3RIYW5kbGUpKTsKLQotICAgICAgICAvLyBDaGVjayB3aGV0aGVyIHRoZSBjb250ZXh0IG5vZGUgaXMgcHJlc2VudCBpbiB0aGUgc2V0IG9mIG5vZGVzCi0gICAgICAgIC8vIHJldHVybmVkIGJ5IHRoZSBrZXkgZnVuY3Rpb24KLSAgICAgICAgaWYgKGluZGV4ICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZpbmFsIEludGVnZXJBcnJheSBub2RlcyA9IGluZGV4LmdldCh2YWx1ZSk7Ci0gICAgICAgICAgICByZXR1cm4gKG5vZGVzICE9IG51bGwgJiYgbm9kZXMuaW5kZXhPZihub2RlKSA+PSAwKSA/IDEgOiAwOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gVGhlIHBhcnRpY3VsYXIga2V5IG5hbWUgaWRlbnRpZmllcyBubyBub2RlcyBpbiB0aGlzIGRvY3VtZW50Ci0gICAgICAgIHJldHVybiAwOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPlJlc2V0cyB0aGUgaXRlcmF0b3IgdG8gdGhlIGxhc3Qgc3RhcnQgbm9kZS48L3A+Ci0gICAgICogPHA+PGVtPlVzZSBvZiBhbiBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIGFzIGEge0BsaW5rIERUTUF4aXNJdGVyYXRvcn0gaXMKLSAgICAgKiA8Yj5kZXByZWNhdGVkLjwvYj48L2VtPjwvcD4KLSAgICAgKiBAZGVwcmVjYXRlZAotICAgICAqLwotICAgIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3IgcmVzZXQoKSB7Ci0gICAgICAgIF9wb3NpdGlvbiA9IDA7Ci0gICAgICAgIHJldHVybiB0aGlzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPlJldHVybnMgdGhlIG51bWJlciBvZiBlbGVtZW50cyBpbiB0aGlzIGl0ZXJhdG9yLjwvcD4KLSAgICAgKiA8cD48ZW0+VXNlIG9mIGFuIGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgYXMgYSB7QGxpbmsgRFRNQXhpc0l0ZXJhdG9yfSBpcwotICAgICAqIDxiPmRlcHJlY2F0ZWQuPC9iPjwvZW0+PC9wPgotICAgICAqIEBkZXByZWNhdGVkCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRMYXN0KCkgewotICAgICAgICByZXR1cm4gKF9ub2RlcyA9PSBudWxsKSA/IDAgOiBfbm9kZXMuY2FyZGluYWxpdHkoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5SZXR1cm5zIHRoZSBwb3NpdGlvbiBvZiB0aGUgY3VycmVudCBub2RlIGluIHRoZSBzZXQuPC9wPgotICAgICAqIDxwPjxlbT5Vc2Ugb2YgYW4gaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcyBhcyBhIHtAbGluayBEVE1BeGlzSXRlcmF0b3J9IGlzCi0gICAgICogPGI+ZGVwcmVjYXRlZC48L2I+PC9lbT48L3A+Ci0gICAgICogQGRlcHJlY2F0ZWQKLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldFBvc2l0aW9uKCkgewotICAgICAgICByZXR1cm4gX3Bvc2l0aW9uOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPlJlbWVtYmVycyB0aGUgY3VycmVudCBub2RlIGZvciB0aGUgbmV4dCBjYWxsIHRvIGdvdG9NYXJrKCkuPC9wPgotICAgICAqIDxwPjxlbT5Vc2Ugb2YgYW4gaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcyBhcyBhIHtAbGluayBEVE1BeGlzSXRlcmF0b3J9IGlzCi0gICAgICogPGI+ZGVwcmVjYXRlZC48L2I+PC9lbT48L3A+Ci0gICAgICogQGRlcHJlY2F0ZWQKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRNYXJrKCkgewotICAgICAgICBfbWFya2VkUG9zaXRpb24gPSBfcG9zaXRpb247Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+UmVzdG9yZXMgdGhlIGN1cnJlbnQgbm9kZSByZW1lbWJlcmVkIGJ5IHNldE1hcmsoKS48L3A+Ci0gICAgICogPHA+PGVtPlVzZSBvZiBhbiBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIGFzIGEge0BsaW5rIERUTUF4aXNJdGVyYXRvcn0gaXMKLSAgICAgKiA8Yj5kZXByZWNhdGVkLjwvYj48L2VtPjwvcD4KLSAgICAgKiBAZGVwcmVjYXRlZAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGdvdG9NYXJrKCkgewotICAgICAgICBfcG9zaXRpb24gPSBfbWFya2VkUG9zaXRpb247Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+U2V0IHN0YXJ0IHRvIEVORCBzaG91bGQgJ2Nsb3NlJyB0aGUgaXRlcmF0b3IsCi0gICAgICogaS5lLiBzdWJzZXF1ZW50IGNhbGwgdG8gbmV4dCgpIHNob3VsZCByZXR1cm4gRU5ELjwvcD4KLSAgICAgKiA8cD48ZW0+VXNlIG9mIGFuIGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgYXMgYSB7QGxpbmsgRFRNQXhpc0l0ZXJhdG9yfSBpcwotICAgICAqIDxiPmRlcHJlY2F0ZWQuPC9iPjwvZW0+PC9wPgotICAgICAqIEBkZXByZWNhdGVkCi0gICAgICovCi0gICAgcHVibGljIERUTUF4aXNJdGVyYXRvciBzZXRTdGFydE5vZGUoaW50IHN0YXJ0KSB7Ci0gICAgICAgIGlmIChzdGFydCA9PSBEVE1BeGlzSXRlcmF0b3IuRU5EKSB7Ci0gICAgICAgICAgICBfbm9kZXMgPSBudWxsOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKF9ub2RlcyAhPSBudWxsKSB7Ci0gICAgICAgICAgICBfcG9zaXRpb24gPSAwOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiAoRFRNQXhpc0l0ZXJhdG9yKSB0aGlzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPkdldCBzdGFydCB0byBFTkQgc2hvdWxkICdjbG9zZScgdGhlIGl0ZXJhdG9yLAotICAgICAqIGkuZS4gc3Vic2VxdWVudCBjYWxsIHRvIG5leHQoKSBzaG91bGQgcmV0dXJuIEVORC48L3A+Ci0gICAgICogPHA+PGVtPlVzZSBvZiBhbiBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIGFzIGEge0BsaW5rIERUTUF4aXNJdGVyYXRvcn0gaXMKLSAgICAgKiA8Yj5kZXByZWNhdGVkLjwvYj48L2VtPjwvcD4KLSAgICAgKiBAZGVwcmVjYXRlZAotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0U3RhcnROb2RlKCkgewotICAgICAgICByZXR1cm4gMDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5UcnVlIGlmIHRoaXMgaXRlcmF0b3IgaGFzIGEgcmV2ZXJzZWQgYXhpcy48L3A+Ci0gICAgICogPHA+PGVtPlVzZSBvZiBhbiBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIGFzIGEge0BsaW5rIERUTUF4aXNJdGVyYXRvcn0gaXMKLSAgICAgKiA8Yj5kZXByZWNhdGVkLjwvYj48L2VtPjwvcD4KLSAgICAgKiBAZGVwcmVjYXRlZAotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzUmV2ZXJzZSgpIHsKLSAgICAgICAgcmV0dXJuKGZhbHNlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5SZXR1cm5zIGEgZGVlcCBjb3B5IG9mIHRoaXMgaXRlcmF0b3IuPC9wPgotICAgICAqIDxwPjxlbT5Vc2Ugb2YgYW4gaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcyBhcyBhIHtAbGluayBEVE1BeGlzSXRlcmF0b3J9IGlzCi0gICAgICogPGI+ZGVwcmVjYXRlZC48L2I+PC9lbT48L3A+Ci0gICAgICogQGRlcHJlY2F0ZWQKLSAgICAgKi8KLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIGNsb25lSXRlcmF0b3IoKSB7Ci0gICAgICAgIEtleUluZGV4IG90aGVyID0gbmV3IEtleUluZGV4KDApOwotICAgICAgICBvdGhlci5faW5kZXggPSBfaW5kZXg7Ci0gICAgICAgIG90aGVyLl9yb290VG9JbmRleE1hcCA9IF9yb290VG9JbmRleE1hcDsKLSAgICAgICAgb3RoZXIuX25vZGVzID0gX25vZGVzOwotICAgICAgICBvdGhlci5fcG9zaXRpb24gPSBfcG9zaXRpb247Ci0gICAgICAgIHJldHVybiAoRFRNQXhpc0l0ZXJhdG9yKSBvdGhlcjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXREb20oRE9NIGRvbSwgaW50IG5vZGUpIHsKLSAgICAgICAgX2RvbSA9IGRvbTsKLQotICAgICAgICAvLyBJZiBhIE11bHRpRE9NLCBlbnN1cmUgX2VuaGFuY2VkRE9NIGlzIGNvcnJlY3RseSBzZXQKLSAgICAgICAgLy8gc28gdGhhdCBnZXRFbGVtZW50QnlJZCgpIHdvcmtzIGluIGxvb2t1cE5vZGVzIGJlbG93Ci0gICAgICAgIGlmIChkb20gaW5zdGFuY2VvZiBNdWx0aURPTSkgewotICAgICAgICAgICAgZG9tID0gKChNdWx0aURPTSkgZG9tKS5nZXREVE0obm9kZSk7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoZG9tIGluc3RhbmNlb2YgRE9NRW5oYW5jZWRGb3JEVE0pIHsKLSAgICAgICAgICAgIF9lbmhhbmNlZERPTSA9IChET01FbmhhbmNlZEZvckRUTSlkb207Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoZG9tIGluc3RhbmNlb2YgRE9NQWRhcHRlcikgewotICAgICAgICAgICAgRE9NIGlkb20gPSAoKERPTUFkYXB0ZXIpZG9tKS5nZXRET01JbXBsKCk7Ci0gICAgICAgICAgICBpZiAoaWRvbSBpbnN0YW5jZW9mIERPTUVuaGFuY2VkRm9yRFRNKSB7Ci0gICAgICAgICAgICAgICAgX2VuaGFuY2VkRE9NID0gKERPTUVuaGFuY2VkRm9yRFRNKWlkb207Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGUgYSB7QGxpbmsgS2V5SW5kZXhJdGVyYXRvcn0gdGhhdCBpdGVyYXRlcyBvdmVyIHRoZSBub2RlcyB0aGF0Ci0gICAgICogcmVzdWx0IGZyb20gYSByZWZlcmVuY2UgdG8gdGhlIFhTTFQgPGNvZGU+a2V5PC9jb2RlPiBmdW5jdGlvbiBvcgotICAgICAqIFhQYXRoIDxjb2RlPmlkPC9jb2RlPiBmdW5jdGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBrZXlWYWx1ZSBBIHN0cmluZyBvciBpdGVyYXRvciByZXByZXNlbnRpbmcgdGhlIGtleSB2YWx1ZXMgb3IgaWQKLSAgICAgKiAgICAgICAgICAgICAgICAgcmVmZXJlbmNlcwotICAgICAqIEBwYXJhbSBpc0tleUNhbGwgQSA8Y29kZT5ib29sZWFuPC9jb2RlPiBpbmRpY2F0aW5nIHdoZXRoZXIgdGhlIGl0ZXJhdG9yCi0gICAgICogICAgICAgICAgICAgICAgIGlzIGJlaW5nIGNyZWF0ZWQgZm9yIGEgcmVmZXJlbmNlIDxjb2RlPmtleTwvY29kZT4gb3IKLSAgICAgKiAgICAgICAgICAgICAgICAgPGNvZGU+aWQ8L2NvZGU+Ci0gICAgICovCi0gICAgcHVibGljIEtleUluZGV4SXRlcmF0b3IgZ2V0S2V5SW5kZXhJdGVyYXRvcihPYmplY3Qga2V5VmFsdWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGlzS2V5Q2FsbCkgewotICAgICAgICBpZiAoa2V5VmFsdWUgaW5zdGFuY2VvZiBEVE1BeGlzSXRlcmF0b3IpIHsKLSAgICAgICAgICAgIHJldHVybiBnZXRLZXlJbmRleEl0ZXJhdG9yKChEVE1BeGlzSXRlcmF0b3IpIGtleVZhbHVlLCBpc0tleUNhbGwpOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIGdldEtleUluZGV4SXRlcmF0b3IoQmFzaXNMaWJyYXJ5LnN0cmluZ0Yoa2V5VmFsdWUsIF9kb20pLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNLZXlDYWxsKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIENyZWF0ZSBhIHtAbGluayBLZXlJbmRleEl0ZXJhdG9yfSB0aGF0IGl0ZXJhdGVzIG92ZXIgdGhlIG5vZGVzIHRoYXQKLSAgICAgKiByZXN1bHQgZnJvbSBhIHJlZmVyZW5jZSB0byB0aGUgWFNMVCA8Y29kZT5rZXk8L2NvZGU+IGZ1bmN0aW9uIG9yCi0gICAgICogWFBhdGggPGNvZGU+aWQ8L2NvZGU+IGZ1bmN0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIGtleVZhbHVlIEEgc3RyaW5nIHJlcHJlc2VudGluZyB0aGUga2V5IHZhbHVlcyBvciBpZAotICAgICAqICAgICAgICAgICAgICAgICByZWZlcmVuY2VzCi0gICAgICogQHBhcmFtIGlzS2V5Q2FsbCBBIDxjb2RlPmJvb2xlYW48L2NvZGU+IGluZGljYXRpbmcgd2hldGhlciB0aGUgaXRlcmF0b3IKLSAgICAgKiAgICAgICAgICAgICAgICAgaXMgYmVpbmcgY3JlYXRlZCBmb3IgYSByZWZlcmVuY2UgPGNvZGU+a2V5PC9jb2RlPiBvcgotICAgICAqICAgICAgICAgICAgICAgICA8Y29kZT5pZDwvY29kZT4KLSAgICAgKi8KLSAgICBwdWJsaWMgS2V5SW5kZXhJdGVyYXRvciBnZXRLZXlJbmRleEl0ZXJhdG9yKFN0cmluZyBrZXlWYWx1ZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gaXNLZXlDYWxsKSB7Ci0gICAgICAgIHJldHVybiBuZXcgS2V5SW5kZXhJdGVyYXRvcihrZXlWYWx1ZSwgaXNLZXlDYWxsKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGUgYSB7QGxpbmsgS2V5SW5kZXhJdGVyYXRvcn0gdGhhdCBpdGVyYXRlcyBvdmVyIHRoZSBub2RlcyB0aGF0Ci0gICAgICogcmVzdWx0IGZyb20gYSByZWZlcmVuY2UgdG8gdGhlIFhTTFQgPGNvZGU+a2V5PC9jb2RlPiBmdW5jdGlvbiBvcgotICAgICAqIFhQYXRoIDxjb2RlPmlkPC9jb2RlPiBmdW5jdGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBrZXlWYWx1ZSBBbiBpdGVyYXRvciByZXByZXNlbnRpbmcgdGhlIGtleSB2YWx1ZXMgb3IgaWQKLSAgICAgKiAgICAgICAgICAgICAgICAgcmVmZXJlbmNlcwotICAgICAqIEBwYXJhbSBpc0tleUNhbGwgQSA8Y29kZT5ib29sZWFuPC9jb2RlPiBpbmRpY2F0aW5nIHdoZXRoZXIgdGhlIGl0ZXJhdG9yCi0gICAgICogICAgICAgICAgICAgICAgIGlzIGJlaW5nIGNyZWF0ZWQgZm9yIGEgcmVmZXJlbmNlIDxjb2RlPmtleTwvY29kZT4gb3IKLSAgICAgKiAgICAgICAgICAgICAgICAgPGNvZGU+aWQ8L2NvZGU+Ci0gICAgICovCi0gICAgcHVibGljIEtleUluZGV4SXRlcmF0b3IgZ2V0S2V5SW5kZXhJdGVyYXRvcihEVE1BeGlzSXRlcmF0b3Iga2V5VmFsdWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGlzS2V5Q2FsbCkgewotICAgICAgICByZXR1cm4gbmV3IEtleUluZGV4SXRlcmF0b3Ioa2V5VmFsdWUsIGlzS2V5Q2FsbCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVXNlZCB0byByZXByZXNlbnQgYW4gZW1wdHkgbm9kZSBzZXQuCi0gICAgICovCi0gICAgZmluYWwgcHJpdmF0ZSBzdGF0aWMgSW50ZWdlckFycmF5IEVNUFRZX05PREVTID0gbmV3IEludGVnZXJBcnJheSgwKTsKLQotCi0gICAgLyoqCi0gICAgICogQW4gaXRlcmF0b3IgcmVwcmVzZW50aW5nIHRoZSByZXN1bHQgb2YgYSByZWZlcmVuY2UgdG8gZWl0aGVyIHRoZQotICAgICAqIFhTTFQgPGNvZGU+a2V5PC9jb2RlPiBmdW5jdGlvbiBvciB0aGUgWFBhdGggPGNvZGU+aWQ8L2NvZGU+IGZ1bmN0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBjbGFzcyBLZXlJbmRleEl0ZXJhdG9yIGV4dGVuZHMgTXVsdGlWYWx1ZWROb2RlSGVhcEl0ZXJhdG9yIHsKLQotICAgICAgICAvKioKLSAgICAgICAgICogPHA+QSByZWZlcmVuY2UgdG8gdGhlIDxjb2RlPmtleTwvY29kZT4gZnVuY3Rpb24gdGhhdCBvbmx5IGhhcyBvbmUKLSAgICAgICAgICoga2V5IHZhbHVlIG9yIHRvIHRoZSA8Y29kZT5pZDwvY29kZT4gZnVuY3Rpb24gdGhhdCBoYXMgb25seSBvbmUgc3RyaW5nCi0gICAgICAgICAqIGFyZ3VtZW50IGNhbiBiZSBvcHRpbWl6ZWQgdG8gaWdub3JlIHRoZSBtdWx0aS12YWx1ZWQgaGVhcC4gIFRoaXMKLSAgICAgICAgICogZmllbGQgd2lsbCBiZSA8Y29kZT5udWxsPC9jb2RlPiBvdGhlcndpc2UuCi0gICAgICAgICAqLwotICAgICAgICBwcml2YXRlIEludGVnZXJBcnJheSBfbm9kZXM7Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIDxwPlRoaXMgZmllbGQgY29udGFpbnMgdGhlIGl0ZXJhdG9yIHJlcHJlc2VudGluZyBhIG5vZGUgc2V0IGtleSB2YWx1ZQotICAgICAgICAgKiBhcmd1bWVudCB0byB0aGUgPGNvZGU+a2V5PC9jb2RlPiBmdW5jdGlvbiBvciBhIG5vZGUgc2V0IGFyZ3VtZW50Ci0gICAgICAgICAqIHRvIHRoZSA8Y29kZT5pZDwvY29kZT4gZnVuY3Rpb24uPC9wPgotICAgICAgICAgKgotICAgICAgICAgKiA8cD5FeGFjdGx5IG9uZSBvZiB0aGlzIGZpZWxkIGFuZCB7QGxpbmsgI19rZXlWYWx1ZX0gbXVzdCBiZQotICAgICAgICAgKiA8Y29kZT5udWxsPC9jb2RlPi48L3A+Ci0gICAgICAgICAqLwotICAgICAgICBwcml2YXRlIERUTUF4aXNJdGVyYXRvciBfa2V5VmFsdWVJdGVyYXRvcjsKLQotICAgICAgICAvKioKLSAgICAgICAgICogPHA+VGhpcyBmaWVsZCBjb250YWlucyB0aGUgaXRlcmF0b3IgcmVwcmVzZW50aW5nIGEgbm9uLW5vZGUtc2V0IGtleQotICAgICAgICAgKiB2YWx1ZSBhcmd1bWVudCB0byB0aGUgPGNvZGU+a2V5PC9jb2RlPiBmdW5jdGlvbiBvciBhIG5vbi1ub2RlLXNldAotICAgICAgICAgKiBhcmd1bWVudCB0byB0aGUgPGNvZGU+aWQ8L2NvZGU+IGZ1bmN0aW9uLjwvcD4KLSAgICAgICAgICoKLSAgICAgICAgICogPHA+RXhhY3RseSBvbmUgb2YgdGhpcyBmaWVsZCBhbmQge0BsaW5rICNfa2V5VmFsdWVJdGVyYXRvcn0gbXVzdCBiZQotICAgICAgICAgKiA8Y29kZT5udWxsPC9jb2RlPi48L3A+Ci0gICAgICAgICAqLwotICAgICAgICBwcml2YXRlIFN0cmluZyBfa2V5VmFsdWU7Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoaXMgb2JqZWN0IHJlcHJlc2VudHMgdGhlIHJlc3VsdCBvZiBhIHJlZmVyZW5jZQotICAgICAgICAgKiB0byB0aGUgPGNvZGU+a2V5PC9jb2RlPiBmdW5jdGlvbiAoPGNvZGU+dHJ1ZTwvY29kZT4pIG9yIHRoZQotICAgICAgICAgKiA8Y29kZT5pZDwvY29kZT4gZnVuY3Rpb24gKDxjb2RlPmZhbHNlPC9jb2RlPikuCi0gICAgICAgICAqLwotICAgICAgICBwcml2YXRlIGJvb2xlYW4gX2lzS2V5SXRlcmF0b3I7Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFJlcHJlc2VudHMgdGhlIERUTSBub2RlcyByZXRyaWV2ZWQgZm9yIG9uZSBrZXkgdmFsdWUgb3Igb25lIHN0cmluZwotICAgICAgICAgKiBhcmd1bWVudCB0byA8Y29kZT5pZDwvY29kZT4gZm9yIHVzZSBhcyBvbmUgaGVhcCBub2RlIGluIGEKLSAgICAgICAgICoge0BsaW5rIE11bHRpVmFsdWVkTm9kZUhlYXBJdGVyYXRvcn0uCi0gICAgICAgICAqLwotICAgICAgICBwcm90ZWN0ZWQgY2xhc3MgS2V5SW5kZXhIZWFwTm9kZQotICAgICAgICAgICAgICAgIGV4dGVuZHMgTXVsdGlWYWx1ZWROb2RlSGVhcEl0ZXJhdG9yLkhlYXBOb2RlCi0gICAgICAgIHsKLSAgICAgICAgICAgIC8qKgotICAgICAgICAgICAgICoge0BsaW5rIEludGVnZXJBcnJheX0gb2YgRFRNIG5vZGVzIHJldHJpZXZlZCBmb3Igb25lIGtleSB2YWx1ZS4KLSAgICAgICAgICAgICAqIE11c3QgY29udGFpbiBubyBkdXBsaWNhdGVzIGFuZCBiZSBzdG9yZWQgaW4gZG9jdW1lbnQgb3JkZXIuCi0gICAgICAgICAgICAgKi8KLSAgICAgICAgICAgIHByaXZhdGUgSW50ZWdlckFycmF5IF9ub2RlczsKLQotICAgICAgICAgICAgLyoqCi0gICAgICAgICAgICAgKiBQb3NpdGlvbiBpbiB7QGxpbmsgI19ub2Rlc30gYXJyYXkgb2YgbmV4dCBub2RlIHRvIHJldHVybiBmcm9tCi0gICAgICAgICAgICAgKiB0aGlzIGhlYXAgbm9kZS4KLSAgICAgICAgICAgICAqLwotICAgICAgICAgICAgcHJpdmF0ZSBpbnQgX3Bvc2l0aW9uID0gMDsKLQotICAgICAgICAgICAgLyoqCi0gICAgICAgICAgICAgKiBNYXJrZWQgcG9zaXRpb24uICBVc2VkIGJ5IHtAbGluayAjc2V0TWFyaygpfSBhbmQKLSAgICAgICAgICAgICAqIHtAbGluayAjZ290b01hcmsoKX0KLSAgICAgICAgICAgICAqLwotICAgICAgICAgICAgcHJpdmF0ZSBpbnQgX21hcmtQb3NpdGlvbiA9IC0xOwotCi0gICAgICAgICAgICAvKioKLSAgICAgICAgICAgICAqIENyZWF0ZSBhIGhlYXAgbm9kZSByZXByZXNlbnRpbmcgRFRNIG5vZGVzIHJldHJpZXZlZCBmb3Igb25lCi0gICAgICAgICAgICAgKiBrZXkgdmFsdWUgaW4gYSByZWZlcmVuY2UgdG8gdGhlIDxjb2RlPmtleTwvY29kZT4gZnVuY3Rpb24KLSAgICAgICAgICAgICAqIG9yIHN0cmluZyBhcmd1bWVudCB0byB0aGUgPGNvZGU+aWQ8L2NvZGU+IGZ1bmN0aW9uLgotICAgICAgICAgICAgICovCi0gICAgICAgICAgICBLZXlJbmRleEhlYXBOb2RlKEludGVnZXJBcnJheSBub2RlcykgewotICAgICAgICAgICAgICAgIF9ub2RlcyA9IG5vZGVzOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvKioKLSAgICAgICAgICAgICAqIEFkdmFuY2UgdG8gdGhlIG5leHQgbm9kZSByZXByZXNlbnRlZCBieSB0aGlzIHtAbGluayBIZWFwTm9kZX0KLSAgICAgICAgICAgICAqCi0gICAgICAgICAgICAgKiBAcmV0dXJuIHRoZSBuZXh0IERUTSBub2RlLgotICAgICAgICAgICAgICovCi0gICAgICAgICAgICBwdWJsaWMgaW50IHN0ZXAoKSB7Ci0gICAgICAgICAgICAgICAgaWYgKF9wb3NpdGlvbiA8IF9ub2Rlcy5jYXJkaW5hbGl0eSgpKSB7Ci0gICAgICAgICAgICAgICAgICAgIF9ub2RlID0gX25vZGVzLmF0KF9wb3NpdGlvbik7Ci0gICAgICAgICAgICAgICAgICAgIF9wb3NpdGlvbisrOwotICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIF9ub2RlID0gRFRNQXhpc0l0ZXJhdG9yLkVORDsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICByZXR1cm4gX25vZGU7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8qKgotICAgICAgICAgICAgICogQ3JlYXRlcyBhIGRlZXAgY29weSBvZiB0aGlzIHtAbGluayBIZWFwTm9kZX0uICBUaGUgY2xvbmUgaXMgbm90Ci0gICAgICAgICAgICAgKiByZXNldCBmcm9tIHRoZSBjdXJyZW50IHBvc2l0aW9uIG9mIHRoZSBvcmlnaW5hbC4KLSAgICAgICAgICAgICAqCi0gICAgICAgICAgICAgKiBAcmV0dXJuIHRoZSBjbG9uZWQgaGVhcCBub2RlCi0gICAgICAgICAgICAgKi8KLSAgICAgICAgICAgIHB1YmxpYyBIZWFwTm9kZSBjbG9uZUhlYXBOb2RlKCkgewotICAgICAgICAgICAgICAgIEtleUluZGV4SGVhcE5vZGUgY2xvbmUgPQotICAgICAgICAgICAgICAgICAgICAgICAgKEtleUluZGV4SGVhcE5vZGUpIHN1cGVyLmNsb25lSGVhcE5vZGUoKTsKLQotICAgICAgICAgICAgICAgIGNsb25lLl9ub2RlcyA9IF9ub2RlczsKLSAgICAgICAgICAgICAgICBjbG9uZS5fcG9zaXRpb24gPSBfcG9zaXRpb247Ci0gICAgICAgICAgICAgICAgY2xvbmUuX21hcmtQb3NpdGlvbiA9IF9tYXJrUG9zaXRpb247Ci0KLSAgICAgICAgICAgICAgICByZXR1cm4gY2xvbmU7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8qKgotICAgICAgICAgICAgICogUmVtZW1iZXJzIHRoZSBjdXJyZW50IG5vZGUgZm9yIHRoZSBuZXh0IGNhbGwgdG8KLSAgICAgICAgICAgICAqIHtAbGluayAjZ290b01hcmsoKX0uCi0gICAgICAgICAgICAgKi8KLSAgICAgICAgICAgIHB1YmxpYyB2b2lkIHNldE1hcmsoKSB7Ci0gICAgICAgICAgICAgICAgX21hcmtQb3NpdGlvbiA9IF9wb3NpdGlvbjsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLyoqCi0gICAgICAgICAgICAgKiBSZXN0b3JlcyB0aGUgY3VycmVudCBub2RlIHJlbWVtYmVyZWQgYnkge0BsaW5rICNzZXRNYXJrKCl9LgotICAgICAgICAgICAgICovCi0gICAgICAgICAgICBwdWJsaWMgdm9pZCBnb3RvTWFyaygpIHsKLSAgICAgICAgICAgICAgICBfcG9zaXRpb24gPSBfbWFya1Bvc2l0aW9uOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvKioKLSAgICAgICAgICAgICAqIFBlcmZvcm1zIGEgY29tcGFyaXNvbiBvZiB0aGUgdHdvIGhlYXAgbm9kZXMKLSAgICAgICAgICAgICAqCi0gICAgICAgICAgICAgKiBAcGFyYW0gaGVhcE5vZGUgdGhlIGhlYXAgbm9kZSBhZ2FpbnN0IHdoaWNoIHRvIGNvbXBhcmUKLSAgICAgICAgICAgICAqIEByZXR1cm4gPGNvZGU+dHJ1ZTwvY29kZT4gaWYgYW5kIG9ubHkgaWYgdGhlIGN1cnJlbnQgbm9kZSBmb3IKLSAgICAgICAgICAgICAqICAgICAgICAgdGhpcyBoZWFwIG5vZGUgaXMgYmVmb3JlIHRoZSBjdXJyZW50IG5vZGUgb2YgdGhlCi0gICAgICAgICAgICAgKiAgICAgICAgIGFyZ3VtZW50IGhlYXAgbm9kZSBpbiBkb2N1bWVudCBvcmRlci4KLSAgICAgICAgICAgICAqLwotICAgICAgICAgICAgcHVibGljIGJvb2xlYW4gaXNMZXNzVGhhbihIZWFwTm9kZSBoZWFwTm9kZSkgewotICAgICAgICAgICAgICAgIHJldHVybiBfbm9kZSA8IGhlYXBOb2RlLl9ub2RlOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvKioKLSAgICAgICAgICAgICAqIDxwPlNldHMgY29udGV4dCB3aXRoIHJlc3BlY3QgdG8gd2hpY2ggdGhpcyBoZWFwIG5vZGUgaXMKLSAgICAgICAgICAgICAqIGV2YWx1YXRlZC48L3A+Ci0gICAgICAgICAgICAgKiA8cD5UaGlzIGhhcyBubyByZWFsIGVmZmVjdCBvbiB0aGlzIGtpbmQgb2YgaGVhcCBub2RlLiAgSW5zdGVhZCwKLSAgICAgICAgICAgICAqIHRoZSB7QGxpbmsgS2V5SW5kZXhJdGVyYXRvciNzZXRTdGFydE5vZGUoaW50KX0gbWV0aG9kIHNob3VsZAotICAgICAgICAgICAgICogY3JlYXRlIG5ldyBpbnN0YW5jZXMgb2YgdGhpcyBjbGFzcyB0byByZXByZXNlbnQgdGhlIGVmZmVjdCBvZgotICAgICAgICAgICAgICogY2hhbmdpbmcgdGhlIGNvbnRleHQuPC9wPgotICAgICAgICAgICAgICovCi0gICAgICAgICAgICBwdWJsaWMgSGVhcE5vZGUgc2V0U3RhcnROb2RlKGludCBub2RlKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8qKgotICAgICAgICAgICAgICogUmVzZXQgdGhlIGhlYXAgbm9kZSBiYWNrIHRvIGl0cyBiZWdpbm5pbmcuCi0gICAgICAgICAgICAgKi8KLSAgICAgICAgICAgIHB1YmxpYyBIZWFwTm9kZSByZXNldCgpIHsKLSAgICAgICAgICAgICAgICBfcG9zaXRpb24gPSAwOwotICAgICAgICAgICAgICAgIHJldHVybiB0aGlzOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIENvbnN0cnVjdG9yIHVzZWQgd2hlbiB0aGUgYXJndW1lbnQgdG8gPGNvZGU+a2V5PC9jb2RlPiBvcgotICAgICAgICAgKiA8Y29kZT5pZDwvY29kZT4gaXMgbm90IGEgbm9kZSBzZXQuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBrZXlWYWx1ZSB0aGUgYXJndW1lbnQgdG8gPGNvZGU+a2V5PC9jb2RlPiBvciA8Y29kZT5pZDwvY29kZT4KLSAgICAgICAgICogICAgICAgICAgICAgICAgIGNhc3QgdG8gYSA8Y29kZT5TdHJpbmc8L2NvZGU+Ci0gICAgICAgICAqIEBwYXJhbSBpc0tleUl0ZXJhdG9yIGluZGljYXRlcyB3aGV0aGVyIHRoZSBjb25zdHJ1Y3RlZCBpdGVyYXRvcgotICAgICAgICAgKiAgICAgICAgICAgICAgICByZXByZXNlbnRzIGEgcmVmZXJlbmNlIHRvIDxjb2RlPmtleTwvY29kZT4gb3IKLSAgICAgICAgICogICAgICAgICAgICAgICAgPGNvZGU+aWQ8L2NvZGU+LgotICAgICAgICAgKi8KLSAgICAgICAgS2V5SW5kZXhJdGVyYXRvcihTdHJpbmcga2V5VmFsdWUsIGJvb2xlYW4gaXNLZXlJdGVyYXRvcikgewotICAgICAgICAgICAgX2lzS2V5SXRlcmF0b3IgPSBpc0tleUl0ZXJhdG9yOwotICAgICAgICAgICAgX2tleVZhbHVlID0ga2V5VmFsdWU7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogQ29uc3RydWN0b3IgdXNlZCB3aGVuIHRoZSBhcmd1bWVudCB0byA8Y29kZT5rZXk8L2NvZGU+IG9yCi0gICAgICAgICAqIDxjb2RlPmlkPC9jb2RlPiBpcyBhIG5vZGUgc2V0LgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0ga2V5VmFsdWVzIHRoZSBhcmd1bWVudCB0byA8Y29kZT5rZXk8L2NvZGU+IG9yIDxjb2RlPmlkPC9jb2RlPgotICAgICAgICAgKiBAcGFyYW0gaXNLZXlJdGVyYXRvciBpbmRpY2F0ZXMgd2hldGhlciB0aGUgY29uc3RydWN0ZWQgaXRlcmF0b3IKLSAgICAgICAgICogICAgICAgICAgICAgICAgcmVwcmVzZW50cyBhIHJlZmVyZW5jZSB0byA8Y29kZT5rZXk8L2NvZGU+IG9yCi0gICAgICAgICAqICAgICAgICAgICAgICAgIDxjb2RlPmlkPC9jb2RlPi4KLSAgICAgICAgICovCi0gICAgICAgIEtleUluZGV4SXRlcmF0b3IoRFRNQXhpc0l0ZXJhdG9yIGtleVZhbHVlcywgYm9vbGVhbiBpc0tleUl0ZXJhdG9yKSB7Ci0gICAgICAgICAgICBfa2V5VmFsdWVJdGVyYXRvciA9IGtleVZhbHVlczsKLSAgICAgICAgICAgIF9pc0tleUl0ZXJhdG9yID0gaXNLZXlJdGVyYXRvcjsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBSZXRyaWV2ZSBub2RlcyBmb3IgYSBwYXJ0aWN1bGFyIGtleSB2YWx1ZSBvciBhIHBhcnRpY3VsYXIgaWQKLSAgICAgICAgICogYXJndW1lbnQgdmFsdWUuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSByb290IFRoZSByb290IG5vZGUgb2YgdGhlIGRvY3VtZW50IGNvbnRhaW5pbmcgdGhlIGNvbnRleHQgbm9kZQotICAgICAgICAgKiBAcGFyYW0ga2V5VmFsdWUgVGhlIGtleSB2YWx1ZSBvZiBpZCBzdHJpbmcgYXJndW1lbnQgdmFsdWUKLSAgICAgICAgICogQHJldHVybiBhbiB7QGxpbmsgSW50ZWdlckFycmF5fSBvZiB0aGUgcmVzdWx0aW5nIG5vZGVzCi0gICAgICAgICAqLwotICAgICAgICBwcm90ZWN0ZWQgSW50ZWdlckFycmF5IGxvb2t1cE5vZGVzKGludCByb290LCBTdHJpbmcga2V5VmFsdWUpIHsKLSAgICAgICAgICAgIEludGVnZXJBcnJheSByZXN1bHQgPSBudWxsOwotCi0gICAgICAgICAgICAvLyBHZXQgbWFwcGluZyBmcm9tIGtleSB2YWx1ZXMvSURzIHRvIERUTSBub2RlcyBmb3IgdGhpcyBkb2N1bWVudAotICAgICAgICAgICAgTWFwPFN0cmluZywgSW50ZWdlckFycmF5PiBpbmRleCA9IF9yb290VG9JbmRleE1hcC5nZXQocm9vdCk7Ci0KLSAgICAgICAgICAgIGlmICghX2lzS2V5SXRlcmF0b3IpIHsKLSAgICAgICAgICAgICAgICAvLyBGb3IgaWQgZnVuY3Rpb24sIHRva2VuaXplIGFyZ3VtZW50IGFzIHdoaXRlc3BhY2Ugc2VwYXJhdGVkCi0gICAgICAgICAgICAgICAgLy8gbGlzdCBvZiB2YWx1ZXMgYW5kIGxvb2sgdXAgbm9kZXMgaWRlbnRpZmllZCBieSBlYWNoIElELgotICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZ1Rva2VuaXplciB2YWx1ZXMgPQotICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFN0cmluZ1Rva2VuaXplcihrZXlWYWx1ZSwgIiBcblx0Iik7Ci0KLSAgICAgICAgICAgICAgICB3aGlsZSAodmFsdWVzLmhhc01vcmVFbGVtZW50cygpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyB0b2tlbiA9IChTdHJpbmcpIHZhbHVlcy5uZXh0RWxlbWVudCgpOwotICAgICAgICAgICAgICAgICAgICBJbnRlZ2VyQXJyYXkgbm9kZXMgPSBudWxsOwotCi0gICAgICAgICAgICAgICAgICAgIC8vIERvZXMgdGhlIElEIG1hcCB0byBhbnkgbm9kZSBpbiB0aGUgZG9jdW1lbnQ/Ci0gICAgICAgICAgICAgICAgICAgIGlmIChpbmRleCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBub2RlcyA9IGluZGV4LmdldCh0b2tlbik7Ci0gICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAvLyBJZiBpbnB1dCB3YXMgZnJvbSBXM0MgRE9NLCB1c2UgRE9NJ3MgZ2V0RWxlbWVudEJ5SWQgdG8gZG8KLSAgICAgICAgICAgICAgICAgICAgLy8gdGhlIGxvb2stdXAuCi0gICAgICAgICAgICAgICAgICAgIGlmIChub2RlcyA9PSBudWxsICYmIF9lbmhhbmNlZERPTSAhPSBudWxsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgX2VuaGFuY2VkRE9NLmhhc0RPTVNvdXJjZSgpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBub2RlcyA9IGdldERPTU5vZGVCeUlkKHRva2VuKTsKLSAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgIC8vIElmIHdlIGZvdW5kIGFueSBub2RlcywgbWVyZ2UgdGhlbSBpbnRvIHRoZSBjdW11bGF0aXZlCi0gICAgICAgICAgICAgICAgICAgIC8vIHJlc3VsdAotICAgICAgICAgICAgICAgICAgICBpZiAobm9kZXMgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gKEludGVnZXJBcnJheSlub2Rlcy5jbG9uZSgpOwotICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQubWVyZ2Uobm9kZXMpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfSBlbHNlIGlmIChpbmRleCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgLy8gRm9yIGtleSBmdW5jdGlvbiwgbWFwIGtleSB2YWx1ZSB0byBub2RlcwotICAgICAgICAgICAgICAgIHJlc3VsdCA9IGluZGV4LmdldChrZXlWYWx1ZSk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIHJldHVybiByZXN1bHQ7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogU2V0IGNvbnRleHQgbm9kZSBmb3IgdGhlIGl0ZXJhdG9yLiAgVGhpcyB3aWxsIGNhdXNlIHRoZSBpdGVyYXRvcgotICAgICAgICAgKiB0byByZXNldCBpdHNlbGYsIHJlZXZhbHVhdGUgYXJndW1lbnRzIHRvIHRoZSBmdW5jdGlvbiwgbG9vayB1cAotICAgICAgICAgKiBub2RlcyBpbiB0aGUgaW5wdXQgYW5kIHJlaW5pdGlhbGl6ZSBpdHMgaW50ZXJuYWwgaGVhcC4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIG5vZGUgdGhlIGNvbnRleHQgbm9kZQotICAgICAgICAgKiBAcmV0dXJuIEEge0BsaW5rIERUTUF4aXNJdGVyYXRvcn0gc2V0IHRvIHRoZSBzdGFydCBvZiB0aGUgaXRlcmF0aW9uLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIERUTUF4aXNJdGVyYXRvciBzZXRTdGFydE5vZGUoaW50IG5vZGUpIHsKLSAgICAgICAgICAgIF9zdGFydE5vZGUgPSBub2RlOwotCi0gICAgICAgICAgICAvLyBJZiB0aGUgYXJ1Z21lbnQgdG8gdGhlIGZ1bmN0aW9uIGlzIGEgbm9kZSBzZXQsIHNldCB0aGUKLSAgICAgICAgICAgIC8vIGNvbnRleHQgbm9kZSBvbiBpdC4KLSAgICAgICAgICAgIGlmIChfa2V5VmFsdWVJdGVyYXRvciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgX2tleVZhbHVlSXRlcmF0b3IgPSBfa2V5VmFsdWVJdGVyYXRvci5zZXRTdGFydE5vZGUobm9kZSk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGluaXQoKTsKLQotICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnNldFN0YXJ0Tm9kZShub2RlKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBHZXQgdGhlIG5leHQgbm9kZSBpbiB0aGUgaXRlcmF0aW9uLgotICAgICAgICAgKgotICAgICAgICAgKiBAcmV0dXJuIFRoZSBuZXh0IG5vZGUgaGFuZGxlIGluIHRoZSBpdGVyYXRpb24sIG9yIEVORC4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBpbnQgbmV4dCgpIHsKLSAgICAgICAgICAgIGludCBub2RlSGFuZGxlOwotCi0gICAgICAgICAgICAvLyBJZiBhdCBtb3N0IG9uZSBrZXkgdmFsdWUgb3IgYXQgbW9zdCBvbmUgc3RyaW5nIGFyZ3VtZW50IHRvIGlkCi0gICAgICAgICAgICAvLyByZXN1bHRlZCBpbiBub2RlcyBiZWluZyByZXR1cm5lZCwgdXNlIHRoZSBJbnRlZ2VyQXJyYXkKLSAgICAgICAgICAgIC8vIHN0b3JlZCBhdCBfbm9kZXMgZGlyZWN0bHkuICBUaGlzIHJlbGllcyBvbiB0aGUgZmFjdCB0aGF0IHRoZQotICAgICAgICAgICAgLy8gSW50ZWdlckFycmF5IG5ldmVyIGluY2x1ZGVzIGR1cGxpY2F0ZSBub2RlcyBhbmQgaXMgYWx3YXlzIHN0b3JlZAotICAgICAgICAgICAgLy8gaW4gZG9jdW1lbnQgb3JkZXIuCi0gICAgICAgICAgICBpZiAoX25vZGVzICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBpZiAoX3Bvc2l0aW9uIDwgX25vZGVzLmNhcmRpbmFsaXR5KCkpIHsKLSAgICAgICAgICAgICAgICAgICAgbm9kZUhhbmRsZSA9IHJldHVybk5vZGUoX25vZGVzLmF0KF9wb3NpdGlvbikpOwotICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIG5vZGVIYW5kbGUgPSBEVE1BeGlzSXRlcmF0b3IuRU5EOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgbm9kZUhhbmRsZSA9IHN1cGVyLm5leHQoKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgcmV0dXJuIG5vZGVIYW5kbGU7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogUmVzZXRzIHRoZSBpdGVyYXRvciB0byB0aGUgbGFzdCBzdGFydCBub2RlLgotICAgICAgICAgKgotICAgICAgICAgKiBAcmV0dXJuIEEgRFRNQXhpc0l0ZXJhdG9yLCB3aGljaCBtYXkgb3IgbWF5IG5vdCBiZSB0aGUgc2FtZSBhcyB0aGlzCi0gICAgICAgICAqICAgICAgICAgaXRlcmF0b3IuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIHJlc2V0KCkgewotICAgICAgICAgICAgaWYgKF9ub2RlcyA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgaW5pdCgpOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBzdXBlci5yZXNldCgpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICByZXR1cm4gcmVzZXRQb3NpdGlvbigpOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIEV2YWx1YXRlIHRoZSByZWZlcmVuY2UgdG8gdGhlIDxjb2RlPmtleTwvY29kZT4gb3IgPGNvZGU+aWQ8L2NvZGU+Ci0gICAgICAgICAqIGZ1bmN0aW9uIHdpdGggdGhlIGNvbnRleHQgc3BlY2lmaWVkIGJ5IHtAbGluayAjc2V0U3RhcnROb2RlKGludCl9Ci0gICAgICAgICAqIGFuZCBzZXQgdXAgdGhpcyBpdGVyYXRvciB0byBpdGVyYXRlIG92ZXIgdGhlIERUTSBub2RlcyB0aGF0IGFyZQotICAgICAgICAgKiB0byBiZSByZXR1cm5lZC4KLSAgICAgICAgICovCi0gICAgICAgIHByb3RlY3RlZCB2b2lkIGluaXQoKSB7Ci0gICAgICAgICAgICBzdXBlci5pbml0KCk7Ci0gICAgICAgICAgICBfcG9zaXRpb24gPSAwOwotCi0gICAgICAgICAgICAvLyBBbGwgbm9kZXMgcmV0cmlldmVkIGFyZSBpbiB0aGUgc2FtZSBkb2N1bWVudAotICAgICAgICAgICAgaW50IHJvb3RIYW5kbGUgPSBfZG9tLmdldEF4aXNJdGVyYXRvcihBeGlzLlJPT1QpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5zZXRTdGFydE5vZGUoX3N0YXJ0Tm9kZSkubmV4dCgpOwotCi0gICAgICAgICAgICAvLyBJcyB0aGUgYXJndW1lbnQgbm90IGEgbm9kZSBzZXQ/Ci0gICAgICAgICAgICBpZiAoX2tleVZhbHVlSXRlcmF0b3IgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIC8vIExvb2sgdXAgbm9kZXMgcmV0dXJuZWQgZm9yIHRoZSBzaW5nbGUgc3RyaW5nIGFyZ3VtZW50Ci0gICAgICAgICAgICAgICAgX25vZGVzID0gbG9va3VwTm9kZXMocm9vdEhhbmRsZSwgX2tleVZhbHVlKTsKLQotICAgICAgICAgICAgICAgIGlmIChfbm9kZXMgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBfbm9kZXMgPSBFTVBUWV9OT0RFUzsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIERUTUF4aXNJdGVyYXRvciBrZXlWYWx1ZXMgPSBfa2V5VmFsdWVJdGVyYXRvci5yZXNldCgpOwotICAgICAgICAgICAgICAgIGludCByZXRyaWV2ZWRLZXlWYWx1ZUlkeCA9IDA7Ci0gICAgICAgICAgICAgICAgYm9vbGVhbiBmb3VuZE5vZGVzID0gZmFsc2U7Ci0KLSAgICAgICAgICAgICAgICBfbm9kZXMgPSBudWxsOwotCi0gICAgICAgICAgICAgICAgLy8gRm9yIGVhY2ggbm9kZSBpbiB0aGUgbm9kZSBzZXQgYXJndW1lbnQsIGdldCB0aGUgc3RyaW5nIHZhbHVlCi0gICAgICAgICAgICAgICAgLy8gYW5kIGxvb2sgdXAgdGhlIG5vZGVzIHJldHVybmVkIGJ5IGtleSBvciBpZCBmb3IgdGhhdCBzdHJpbmcKLSAgICAgICAgICAgICAgICAvLyB2YWx1ZS4gIElmIGF0IG1vc3Qgb25lIHN0cmluZyB2YWx1ZSBoYXMgbm9kZXMgYXNzb2NpYXRlZCwKLSAgICAgICAgICAgICAgICAvLyB0aGUgbm9kZXMgd2lsbCBiZSBzdG9yZWQgaW4gX25vZGVzOyBvdGhlcndpc2UsIHRoZSBub2RlcwotICAgICAgICAgICAgICAgIC8vIHdpbGwgYmUgcGxhY2VkIGluIGEgaGVhcC4KLSAgICAgICAgICAgICAgICBmb3IgKGludCBrZXlWYWx1ZU5vZGUgPSBrZXlWYWx1ZXMubmV4dCgpOwotICAgICAgICAgICAgICAgICAgICAga2V5VmFsdWVOb2RlICE9IERUTUF4aXNJdGVyYXRvci5FTkQ7Ci0gICAgICAgICAgICAgICAgICAgICBrZXlWYWx1ZU5vZGUgPSBrZXlWYWx1ZXMubmV4dCgpKSB7Ci0KLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGtleVZhbHVlID0gQmFzaXNMaWJyYXJ5LnN0cmluZ0Yoa2V5VmFsdWVOb2RlLCBfZG9tKTsKLQotICAgICAgICAgICAgICAgICAgICBJbnRlZ2VyQXJyYXkgbm9kZXMgPSBsb29rdXBOb2Rlcyhyb290SGFuZGxlLCBrZXlWYWx1ZSk7Ci0KLSAgICAgICAgICAgICAgICAgICAgaWYgKG5vZGVzICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmICghZm91bmROb2RlcykgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9ub2RlcyA9IG5vZGVzOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvdW5kTm9kZXMgPSB0cnVlOwotICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX25vZGVzICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkSGVhcE5vZGUobmV3IEtleUluZGV4SGVhcE5vZGUoX25vZGVzKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9ub2RlcyA9IG51bGw7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZEhlYXBOb2RlKG5ldyBLZXlJbmRleEhlYXBOb2RlKG5vZGVzKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBpZiAoIWZvdW5kTm9kZXMpIHsKLSAgICAgICAgICAgICAgICAgICAgX25vZGVzID0gRU1QVFlfTk9ERVM7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFJldHVybnMgdGhlIG51bWJlciBvZiBub2RlcyBpbiB0aGlzIGl0ZXJhdG9yLgotICAgICAgICAgKgotICAgICAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2Ygbm9kZXMKLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBpbnQgZ2V0TGFzdCgpIHsKLSAgICAgICAgICAgIC8vIElmIG5vZGVzIGFyZSBzdG9yZWQgaW4gX25vZGVzLCB0YWtlIGFkdmFudGFnZSBvZiB0aGUgZmFjdCB0aGF0Ci0gICAgICAgICAgICAvLyB0aGVyZSBhcmUgbm8gZHVwbGljYXRlcy4gIE90aGVyd2lzZSwgZmFsbCBiYWNrIHRvIHRoZSBiYXNlIGhlYXAKLSAgICAgICAgICAgIC8vIGltcGxlbWVudGFpdG9uIGFuZCBob3BlIGl0IGRvZXMgYSBnb29kIGpvYiB3aXRoIHRoaXMuCi0gICAgICAgICAgICByZXR1cm4gKF9ub2RlcyAhPSBudWxsKSA/IF9ub2Rlcy5jYXJkaW5hbGl0eSgpIDogc3VwZXIuZ2V0TGFzdCgpOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFJldHVybiB0aGUgbm9kZSBhdCB0aGUgZ2l2ZW4gcG9zaXRpb24uCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBwb3NpdGlvbiBUaGUgcG9zaXRpb24KLSAgICAgICAgICogQHJldHVybiBUaGUgbm9kZSBhdCB0aGUgZ2l2ZW4gcG9zaXRpb24uCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgaW50IGdldE5vZGVCeVBvc2l0aW9uKGludCBwb3NpdGlvbikgewotICAgICAgICAgICAgaW50IG5vZGUgPSBEVE1BeGlzSXRlcmF0b3IuRU5EOwotCi0gICAgICAgICAgICAvLyBJZiBub2RlcyBhcmUgc3RvcmVkIGluIF9ub2RlcywgdGFrZSBhZHZhbnRhZ2Ugb2YgdGhlIGZhY3QgdGhhdAotICAgICAgICAgICAgLy8gdGhlcmUgYXJlIG5vIGR1cGxpY2F0ZXMgYW5kIHRoZXkgYXJlIHN0b3JlZCBpbiBkb2N1bWVudCBvcmRlci4KLSAgICAgICAgICAgIC8vIE90aGVyd2lzZSwgZmFsbCBiYWNrIHRvIHRoZSBiYXNlIGhlYXAgaW1wbGVtZW50YXRpb24gdG8gZG8gYQotICAgICAgICAgICAgLy8gZ29vZCBqb2Igd2l0aCB0aGlzLgotICAgICAgICAgICAgaWYgKF9ub2RlcyAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgaWYgKHBvc2l0aW9uID4gMCkgewotICAgICAgICAgICAgICAgICAgICBpZiAocG9zaXRpb24gPD0gX25vZGVzLmNhcmRpbmFsaXR5KCkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIF9wb3NpdGlvbiA9IHBvc2l0aW9uOwotICAgICAgICAgICAgICAgICAgICAgICAgbm9kZSA9IF9ub2Rlcy5hdChwb3NpdGlvbi0xKTsKLSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIF9wb3NpdGlvbiA9IF9ub2Rlcy5jYXJkaW5hbGl0eSgpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBub2RlID0gc3VwZXIuZ2V0Tm9kZUJ5UG9zaXRpb24ocG9zaXRpb24pOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICByZXR1cm4gbm9kZTsKLSAgICAgICAgfQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvZG9tL0xvYWREb2N1bWVudC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vTG9hZERvY3VtZW50LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGYzZTI4NzkuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vTG9hZERvY3VtZW50LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzMDUgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogTG9hZERvY3VtZW50LmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMDYgMDc6MTQ6MTIgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmRvbTsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC5YYWxhbkNvbnN0YW50czsKLWltcG9ydCBqYXZhLmlvLkZpbGVOb3RGb3VuZEV4Y2VwdGlvbjsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc3RyZWFtLlN0cmVhbVNvdXJjZTsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5ET007Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLkRPTUNhY2hlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5ET01FbmhhbmNlZEZvckRUTTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuVHJhbnNsZXRFeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuRXJyb3JNc2c7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnJ1bnRpbWUuQWJzdHJhY3RUcmFuc2xldDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMudHJheC5UZW1wbGF0ZXNJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC51dGlscy5TZWN1cml0eVN1cHBvcnQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTUF4aXNJdGVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1NYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLnJlZi5EVE1EZWZhdWx0QmFzZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5yZWYuRW1wdHlJdGVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLlN5c3RlbUlEUmVzb2x2ZXI7Ci0KLWltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKLWltcG9ydCBvcmcueG1sLnNheC5YTUxSZWFkZXI7Ci0KLS8qKgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBMb2FkRG9jdW1lbnQgewotCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIE5BTUVTUEFDRV9GRUFUVVJFID0KLSAgICAgICAiaHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL25hbWVzcGFjZXMiOwotCi0gICAgLyoqCi0gICAgICogSW50ZXJwcmV0cyB0aGUgYXJndW1lbnRzIHBhc3NlZCBmcm9tIHRoZSBkb2N1bWVudCgpIGZ1bmN0aW9uIChzZWUKLSAgICAgKiBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvY29tcGlsZXIvRG9jdW1lbnRDYWxsLmphdmEpIGFuZCByZXR1cm5zIGFuCi0gICAgICogaXRlcmF0b3IgY29udGFpbmluZyB0aGUgcmVxdWVzdGVkIG5vZGVzLiBCdWlsZHMgYSB1bmlvbi1pdGVyYXRvciBpZgotICAgICAqIHNldmVyYWwgZG9jdW1lbnRzIGFyZSByZXF1ZXN0ZWQuCi0gICAgICogMiBhcmd1bWVudHMgYXJnMSBhbmQgYXJnMi4gIGRvY3VtZW50KE9iaiwgbm9kZS1zZXQpIGNhbGwKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIERUTUF4aXNJdGVyYXRvciBkb2N1bWVudEYoT2JqZWN0IGFyZzEsIERUTUF4aXNJdGVyYXRvciBhcmcyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyB4c2xVUkksIEFic3RyYWN0VHJhbnNsZXQgdHJhbnNsZXQsIERPTSBkb20pCi0gICAgdGhyb3dzIFRyYW5zbGV0RXhjZXB0aW9uIHsKLSAgICAgICAgU3RyaW5nIGJhc2VVUkkgPSBudWxsOwotICAgICAgICBmaW5hbCBpbnQgYXJnMkZpcnN0Tm9kZSA9IGFyZzIubmV4dCgpOwotICAgICAgICBpZiAoYXJnMkZpcnN0Tm9kZSA9PSBEVE1BeGlzSXRlcmF0b3IuRU5EKSB7Ci0gICAgICAgICAgICAvLyAgdGhlIHNlY29uZCBhcmd1bWVudCBub2RlLXNldCBpcyBlbXB0eQotICAgICAgICAgICAgcmV0dXJuIEVtcHR5SXRlcmF0b3IuZ2V0SW5zdGFuY2UoKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIC8vU3lzdGVtLmVyci5wcmludGxuKCJhcmcyRmlyc3ROb2RlIG5hbWU6ICIKLSAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgICAgICsgZG9tLmdldE5vZGVOYW1lKGFyZzJGaXJzdE5vZGUgKSsiWyIKLSAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgICAgICtJbnRlZ2VyLnRvSGV4U3RyaW5nKGFyZzJGaXJzdE5vZGUgKSsiXSIpOwotICAgICAgICAgICAgYmFzZVVSSSA9IGRvbS5nZXREb2N1bWVudFVSSShhcmcyRmlyc3ROb2RlKTsKLSAgICAgICAgICAgIGlmICghU3lzdGVtSURSZXNvbHZlci5pc0Fic29sdXRlVVJJKGJhc2VVUkkpKQotICAgICAgICAgICAgICAgYmFzZVVSSSA9IFN5c3RlbUlEUmVzb2x2ZXIuZ2V0QWJzb2x1dGVVUklGcm9tUmVsYXRpdmUoYmFzZVVSSSk7Ci0gICAgICAgIH0KLQotICAgICAgICB0cnkgewotICAgICAgICAgICAgaWYgKGFyZzEgaW5zdGFuY2VvZiBTdHJpbmcpIHsKLSAgICAgICAgICAgICAgICBpZiAoKChTdHJpbmcpYXJnMSkubGVuZ3RoKCkgPT0gMCkgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gZG9jdW1lbnQoeHNsVVJJLCAiIiwgdHJhbnNsZXQsIGRvbSk7Ci0gICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRvY3VtZW50KChTdHJpbmcpYXJnMSwgYmFzZVVSSSwgdHJhbnNsZXQsIGRvbSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfSBlbHNlIGlmIChhcmcxIGluc3RhbmNlb2YgRFRNQXhpc0l0ZXJhdG9yKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGRvY3VtZW50KChEVE1BeGlzSXRlcmF0b3IpYXJnMSwgYmFzZVVSSSwgdHJhbnNsZXQsIGRvbSk7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBlcnIgPSAiZG9jdW1lbnQoIithcmcxLnRvU3RyaW5nKCkrIikiOwotICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oZXJyKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBUcmFuc2xldEV4Y2VwdGlvbihlKTsKLSAgICAgICAgfQotICAgIH0KLSAgICAvKioKLSAgICAgKiBJbnRlcnByZXRzIHRoZSBhcmd1bWVudHMgcGFzc2VkIGZyb20gdGhlIGRvY3VtZW50KCkgZnVuY3Rpb24gKHNlZQotICAgICAqIGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9jb21waWxlci9Eb2N1bWVudENhbGwuamF2YSkgYW5kIHJldHVybnMgYW4KLSAgICAgKiBpdGVyYXRvciBjb250YWluaW5nIHRoZSByZXF1ZXN0ZWQgbm9kZXMuIEJ1aWxkcyBhIHVuaW9uLWl0ZXJhdG9yIGlmCi0gICAgICogc2V2ZXJhbCBkb2N1bWVudHMgYXJlIHJlcXVlc3RlZC4KLSAgICAgKiAxIGFyZ3VtZW50cyBhcmcuICBkb2N1bWVudChPYmopIGNhbGwKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIERUTUF4aXNJdGVyYXRvciBkb2N1bWVudEYoT2JqZWN0IGFyZywgU3RyaW5nIHhzbFVSSSwKLSAgICAgICAgICAgICAgICAgICAgQWJzdHJhY3RUcmFuc2xldCB0cmFuc2xldCwgRE9NIGRvbSkKLSAgICB0aHJvd3MgVHJhbnNsZXRFeGNlcHRpb24gewotICAgICAgICB0cnkgewotICAgICAgICAgICAgaWYgKGFyZyBpbnN0YW5jZW9mIFN0cmluZykgewotICAgICAgICAgICAgICAgIGlmICh4c2xVUkkgPT0gbnVsbCApCi0gICAgICAgICAgICAgICAgICAgIHhzbFVSSSA9ICIiOwotCi0gICAgICAgICAgICAgICAgU3RyaW5nIGJhc2VVUkkgPSB4c2xVUkk7Ci0gICAgICAgICAgICAgICAgaWYgKCFTeXN0ZW1JRFJlc29sdmVyLmlzQWJzb2x1dGVVUkkoeHNsVVJJKSkKLSAgICAgICAgICAgICAgICAgICBiYXNlVVJJID0gU3lzdGVtSURSZXNvbHZlci5nZXRBYnNvbHV0ZVVSSUZyb21SZWxhdGl2ZSh4c2xVUkkpOwotCi0gICAgICAgICAgICAgICAgU3RyaW5nIGhyZWYgPSAoU3RyaW5nKWFyZzsKLSAgICAgICAgICAgICAgICBpZiAoaHJlZi5sZW5ndGgoKSA9PSAwKSB7Ci0gICAgICAgICAgICAgICAgICAgIGhyZWYgPSAiIjsKLSAgICAgICAgICAgICAgICAgICAgLy8gJU9QVCUgT3B0aW1pemF0aW9uIHRvIGNhY2hlIHRoZSBzdHlsZXNoZWV0IERPTS4KLSAgICAgICAgICAgICAgICAgICAgLy8gVGhlIHN0eWxlc2hlZXQgRE9NIGlzIGJ1aWx0IG9uY2UgYW5kIGNhY2hlZAotICAgICAgICAgICAgICAgICAgICAvLyBpbiB0aGUgVGVtcGxhdGVzIG9iamVjdC4KLSAgICAgICAgICAgICAgICAgICAgVGVtcGxhdGVzSW1wbCB0ZW1wbGF0ZXMgPSAoVGVtcGxhdGVzSW1wbCl0cmFuc2xldC5nZXRUZW1wbGF0ZXMoKTsKLSAgICAgICAgICAgICAgICAgICAgRE9NIHNkb20gPSBudWxsOwotICAgICAgICAgICAgICAgICAgICBpZiAodGVtcGxhdGVzICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHNkb20gPSB0ZW1wbGF0ZXMuZ2V0U3R5bGVzaGVldERPTSgpOwotICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgLy8gSWYgdGhlIGNhY2hlZCBkb20gZXhpc3RzLCB3ZSBuZWVkIHRvIG1pZ3JhdGUgaXQKLSAgICAgICAgICAgICAgICAgICAgLy8gdG8gdGhlIG5ldyBEVE1NYW5hZ2VyIGFuZCBjcmVhdGUgYSBEVE1BeGlzSXRlcmF0b3IKLSAgICAgICAgICAgICAgICAgICAgLy8gZm9yIHRoZSBkb2N1bWVudC4KLSAgICAgICAgICAgICAgICAgICAgaWYgKHNkb20gIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRvY3VtZW50KHNkb20sIHRyYW5zbGV0LCBkb20pOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRvY3VtZW50KGhyZWYsIGJhc2VVUkksIHRyYW5zbGV0LCBkb20sIHRydWUpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gZG9jdW1lbnQoaHJlZiwgYmFzZVVSSSwgdHJhbnNsZXQsIGRvbSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfSBlbHNlIGlmIChhcmcgaW5zdGFuY2VvZiBEVE1BeGlzSXRlcmF0b3IpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZG9jdW1lbnQoKERUTUF4aXNJdGVyYXRvcilhcmcsIG51bGwsIHRyYW5zbGV0LCBkb20pOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgZXJyID0gImRvY3VtZW50KCIrYXJnLnRvU3RyaW5nKCkrIikiOwotICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oZXJyKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBUcmFuc2xldEV4Y2VwdGlvbihlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHByaXZhdGUgc3RhdGljIERUTUF4aXNJdGVyYXRvciBkb2N1bWVudChTdHJpbmcgdXJpLCBTdHJpbmcgYmFzZSwKLSAgICAgICAgICAgICAgICAgICAgQWJzdHJhY3RUcmFuc2xldCB0cmFuc2xldCwgRE9NIGRvbSkKLSAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgcmV0dXJuIGRvY3VtZW50KHVyaSwgYmFzZSwgdHJhbnNsZXQsIGRvbSwgZmFsc2UpOwotICAgIH0KLQotICAgIHByaXZhdGUgc3RhdGljIERUTUF4aXNJdGVyYXRvciBkb2N1bWVudChTdHJpbmcgdXJpLCBTdHJpbmcgYmFzZSwKLSAgICAgICAgICAgICAgICAgICAgQWJzdHJhY3RUcmFuc2xldCB0cmFuc2xldCwgRE9NIGRvbSwKLSAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBjYWNoZURPTSkKLSAgICB0aHJvd3MgRXhjZXB0aW9uCi0gICAgewotICAgICAgICB0cnkgewotICAgICAgICBmaW5hbCBTdHJpbmcgb3JpZ2luYWxVcmkgPSB1cmk7Ci0gICAgICAgIE11bHRpRE9NIG11bHRpcGxleGVyID0gKE11bHRpRE9NKWRvbTsKLQotICAgICAgICAvLyBQcmVwZW5kIFVSSSBiYXNlIHRvIFVSSSAoZnJvbSBjb250ZXh0KQotICAgICAgICBpZiAoYmFzZSAhPSBudWxsICYmICFiYXNlLmVxdWFscygiIikpIHsKLSAgICAgICAgICAgIHVyaSA9IFN5c3RlbUlEUmVzb2x2ZXIuZ2V0QWJzb2x1dGVVUkkodXJpLCBiYXNlKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIFJldHVybiBhbiBlbXB0eSBpdGVyYXRvciBpZiB0aGUgVVJJIGlzIGNsZWFybHkgaW52YWxpZAotICAgICAgICAvLyAodG8gcHJldmVudCBzb21lIHVubmNlc3NhcnkgTWFsZm9ybWVkVVJMIGV4Y2VwdGlvbnMpLgotICAgICAgICBpZiAodXJpID09IG51bGwgfHwgdXJpLmVxdWFscygiIikpIHsKLSAgICAgICAgICAgIHJldHVybihFbXB0eUl0ZXJhdG9yLmdldEluc3RhbmNlKCkpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gQ2hlY2sgaWYgdGhpcyBET00gaGFzIGFscmVhZHkgYmVlbiBhZGRlZCB0byB0aGUgbXVsdGlwbGV4ZXIKLSAgICAgICAgaW50IG1hc2sgPSBtdWx0aXBsZXhlci5nZXREb2N1bWVudE1hc2sodXJpKTsKLSAgICAgICAgaWYgKG1hc2sgIT0gLTEpIHsKLSAgICAgICAgICAgIERPTSBuZXdEb20gPSAoKERPTUFkYXB0ZXIpbXVsdGlwbGV4ZXIuZ2V0RE9NQWRhcHRlcih1cmkpKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmdldERPTUltcGwoKTsKLSAgICAgICAgICAgIGlmIChuZXdEb20gaW5zdGFuY2VvZiBET01FbmhhbmNlZEZvckRUTSkgewotICAgICAgICAgICAgICAgIHJldHVybiBuZXcgU2luZ2xldG9uSXRlcmF0b3IoKChET01FbmhhbmNlZEZvckRUTSluZXdEb20pCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0RG9jdW1lbnQoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gQ2hlY2sgaWYgd2UgY2FuIGdldCB0aGUgRE9NIGZyb20gYSBET01DYWNoZQotICAgICAgICBET01DYWNoZSBjYWNoZSA9IHRyYW5zbGV0LmdldERPTUNhY2hlKCk7Ci0gICAgICAgIERPTSBuZXdkb207Ci0KLSAgICAgICAgbWFzayA9IG11bHRpcGxleGVyLm5leHRNYXNrKCk7IC8vIHBlZWsKLQotICAgICAgICBpZiAoY2FjaGUgIT0gbnVsbCkgewotICAgICAgICAgICAgbmV3ZG9tID0gY2FjaGUucmV0cmlldmVEb2N1bWVudChiYXNlLCBvcmlnaW5hbFVyaSwgdHJhbnNsZXQpOwotICAgICAgICAgICAgaWYgKG5ld2RvbSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZmluYWwgRXhjZXB0aW9uIGUgPSBuZXcgRmlsZU5vdEZvdW5kRXhjZXB0aW9uKG9yaWdpbmFsVXJpKTsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNsZXRFeGNlcHRpb24oZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBTdHJpbmcgYWNjZXNzRXJyb3IgPSBTZWN1cml0eVN1cHBvcnQuY2hlY2tBY2Nlc3ModXJpLCB0cmFuc2xldC5nZXRBbGxvd2VkUHJvdG9jb2xzKCksIFhhbGFuQ29uc3RhbnRzLkFDQ0VTU19FWFRFUk5BTF9BTEwpOwotICAgICAgICAgICAgaWYgKGFjY2Vzc0Vycm9yICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBFcnJvck1zZyBtc2cgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuQUNDRVNTSU5HX1hTTFRfVEFSR0VUX0VSUiwKLSAgICAgICAgICAgICAgICAgICAgICAgIFNlY3VyaXR5U3VwcG9ydC5zYW5pdGl6ZVBhdGgodXJpKSwgYWNjZXNzRXJyb3IpOwotICAgICAgICAgICAgICAgIHRocm93IG5ldyBFeGNlcHRpb24obXNnLnRvU3RyaW5nKCkpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBQYXJzZSB0aGUgaW5wdXQgZG9jdW1lbnQgYW5kIGNvbnN0cnVjdCBET00gb2JqZWN0Ci0gICAgICAgICAgICAvLyBUcnVzdCB0aGUgRFRNTWFuYWdlciB0byBwaWNrIHRoZSByaWdodCBwYXJzZXIgYW5kCi0gICAgICAgICAgICAvLyBzZXQgdXAgdGhlIERPTSBjb3JyZWN0bHkuCi0gICAgICAgICAgICBYU0xUQ0RUTU1hbmFnZXIgZHRtTWFuYWdlciA9IChYU0xUQ0RUTU1hbmFnZXIpbXVsdGlwbGV4ZXIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmdldERUTU1hbmFnZXIoKTsKLSAgICAgICAgICAgIERPTUVuaGFuY2VkRm9yRFRNIGVuaGFuY2VkRE9NID0KLSAgICAgICAgICAgICAgICAgICAgKERPTUVuaGFuY2VkRm9yRFRNKSBkdG1NYW5hZ2VyLmdldERUTShuZXcgU3RyZWFtU291cmNlKHVyaSksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlLCBudWxsLCB0cnVlLCBmYWxzZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNsZXQuaGFzSWRDYWxsKCksIGNhY2hlRE9NKTsKLSAgICAgICAgICAgIG5ld2RvbSA9IGVuaGFuY2VkRE9NOwotCi0gICAgICAgICAgICAvLyBDYWNoZSB0aGUgc3R5bGVzaGVldCBET00gaW4gdGhlIFRlbXBsYXRlcyBvYmplY3QKLSAgICAgICAgICAgIGlmIChjYWNoZURPTSkgewotICAgICAgICAgICAgICAgIFRlbXBsYXRlc0ltcGwgdGVtcGxhdGVzID0gKFRlbXBsYXRlc0ltcGwpdHJhbnNsZXQuZ2V0VGVtcGxhdGVzKCk7Ci0gICAgICAgICAgICAgICAgaWYgKHRlbXBsYXRlcyAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIHRlbXBsYXRlcy5zZXRTdHlsZXNoZWV0RE9NKGVuaGFuY2VkRE9NKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIHRyYW5zbGV0LnByZXBhc3NEb2N1bWVudChlbmhhbmNlZERPTSk7Ci0gICAgICAgICAgICBlbmhhbmNlZERPTS5zZXREb2N1bWVudFVSSSh1cmkpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gV3JhcCB0aGUgRE9NIG9iamVjdCBpbiBhIERPTSBhZGFwdGVyIGFuZCBhZGQgdG8gbXVsdGlwbGV4ZXIKLSAgICAgICAgZmluYWwgRE9NQWRhcHRlciBkb21BZGFwdGVyID0gdHJhbnNsZXQubWFrZURPTUFkYXB0ZXIobmV3ZG9tKTsKLSAgICAgICAgbXVsdGlwbGV4ZXIuYWRkRE9NQWRhcHRlcihkb21BZGFwdGVyKTsKLQotICAgICAgICAvLyBDcmVhdGUgaW5kZXggZm9yIGFueSBrZXkgZWxlbWVudHMKLSAgICAgICAgdHJhbnNsZXQuYnVpbGRLZXlzKGRvbUFkYXB0ZXIsIG51bGwsIG51bGwsIG5ld2RvbS5nZXREb2N1bWVudCgpKTsKLQotICAgICAgICAvLyBSZXR1cm4gYSBzaW5nbGV0b24gaXRlcmF0b3IgY29udGFpbmluZyB0aGUgcm9vdCBub2RlCi0gICAgICAgIHJldHVybiBuZXcgU2luZ2xldG9uSXRlcmF0b3IobmV3ZG9tLmdldERvY3VtZW50KCksIHRydWUpOwotICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgdGhyb3cgZTsKLSAgICAgICAgfQotICAgIH0KLQotCi0gICAgcHJpdmF0ZSBzdGF0aWMgRFRNQXhpc0l0ZXJhdG9yIGRvY3VtZW50KERUTUF4aXNJdGVyYXRvciBhcmcxLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgYmFzZVVSSSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQWJzdHJhY3RUcmFuc2xldCB0cmFuc2xldCwgRE9NIGRvbSkKLSAgICB0aHJvd3MgRXhjZXB0aW9uCi0gICAgewotICAgICAgICBVbmlvbkl0ZXJhdG9yIHVuaW9uID0gbmV3IFVuaW9uSXRlcmF0b3IoZG9tKTsKLSAgICAgICAgaW50IG5vZGUgPSBEVE0uTlVMTDsKLQotICAgICAgICB3aGlsZSAoKG5vZGUgPSBhcmcxLm5leHQoKSkgIT0gRFRNLk5VTEwpIHsKLSAgICAgICAgICAgIFN0cmluZyB1cmkgPSBkb20uZ2V0U3RyaW5nVmFsdWVYKG5vZGUpOwotICAgICAgICAgICAgLy9kb2N1bWVudChub2RlLXNldCkgaWYgdHJ1ZTsgIGRvY3VtZW50KG5vZGUtc2V0LG5vZGUtc2V0KSBpZiBmYWxzZQotICAgICAgICAgICAgaWYgKGJhc2VVUkkgID09IG51bGwpIHsKLSAgICAgICAgICAgICAgIGJhc2VVUkkgPSBkb20uZ2V0RG9jdW1lbnRVUkkobm9kZSk7Ci0gICAgICAgICAgICAgICBpZiAoIVN5c3RlbUlEUmVzb2x2ZXIuaXNBYnNvbHV0ZVVSSShiYXNlVVJJKSkKLSAgICAgICAgICAgICAgICAgICAgYmFzZVVSSSA9IFN5c3RlbUlEUmVzb2x2ZXIuZ2V0QWJzb2x1dGVVUklGcm9tUmVsYXRpdmUoYmFzZVVSSSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICB1bmlvbi5hZGRJdGVyYXRvcihkb2N1bWVudCh1cmksIGJhc2VVUkksIHRyYW5zbGV0LCBkb20pKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4odW5pb24pOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENyZWF0ZSBhIERUTUF4aXNJdGVyYXRvciBmb3IgdGhlIG5ld2RvbS4gVGhpcyBpcyBjdXJyZW50bHkgb25seQotICAgICAqIHVzZWQgdG8gY3JlYXRlIGFuIGl0ZXJhdG9yIGZvciB0aGUgY2FjaGVkIHN0eWxlc2hlZXQgRE9NLgotICAgICAqCi0gICAgICogQHBhcmFtIG5ld2RvbSB0aGUgY2FjaGVkIHN0eWxlc2hlZXQgRE9NCi0gICAgICogQHBhcmFtIHRyYW5zbGV0IHRoZSB0cmFuc2xldAotICAgICAqIEBwYXJhbSB0aGUgbWFpbiBkb20gKHNob3VsZCBiZSBhIE11bHRpRE9NKQotICAgICAqIEByZXR1cm4gYSBEVE1BeGlzSXRlcmF0b3IgZnJvbSB0aGUgZG9jdW1lbnQgcm9vdAotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIERUTUF4aXNJdGVyYXRvciBkb2N1bWVudChET00gbmV3ZG9tLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBYnN0cmFjdFRyYW5zbGV0IHRyYW5zbGV0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBET00gZG9tKQotICAgICAgICB0aHJvd3MgRXhjZXB0aW9uCi0gICAgewotICAgICAgICBEVE1NYW5hZ2VyIGR0bU1hbmFnZXIgPSAoKE11bHRpRE9NKWRvbSkuZ2V0RFRNTWFuYWdlcigpOwotICAgICAgICAvLyBOZWVkIHRvIG1pZ3JhdGUgdGhlIGNhY2hlZCBEVE0gdG8gdGhlIG5ldyBEVE1NYW5hZ2VyCi0gICAgICAgIGlmIChkdG1NYW5hZ2VyICE9IG51bGwgJiYgbmV3ZG9tIGluc3RhbmNlb2YgRFRNKSB7Ci0gICAgICAgICAgICAoKERUTSluZXdkb20pLm1pZ3JhdGVUbyhkdG1NYW5hZ2VyKTsKLSAgICAgICAgfQotCi0gICAgICAgIHRyYW5zbGV0LnByZXBhc3NEb2N1bWVudChuZXdkb20pOwotCi0gICAgICAgIC8vIFdyYXAgdGhlIERPTSBvYmplY3QgaW4gYSBET00gYWRhcHRlciBhbmQgYWRkIHRvIG11bHRpcGxleGVyCi0gICAgICAgIGZpbmFsIERPTUFkYXB0ZXIgZG9tQWRhcHRlciA9IHRyYW5zbGV0Lm1ha2VET01BZGFwdGVyKG5ld2RvbSk7Ci0gICAgICAgICgoTXVsdGlET00pZG9tKS5hZGRET01BZGFwdGVyKGRvbUFkYXB0ZXIpOwotCi0gICAgICAgIC8vIENyZWF0ZSBpbmRleCBmb3IgYW55IGtleSBlbGVtZW50cwotICAgICAgICB0cmFuc2xldC5idWlsZEtleXMoZG9tQWRhcHRlciwgbnVsbCwgbnVsbCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld2RvbS5nZXREb2N1bWVudCgpKTsKLQotICAgICAgICAvLyBSZXR1cm4gYSBzaW5nbGV0b24gaXRlcmF0b3IgY29udGFpbmluZyB0aGUgcm9vdCBub2RlCi0gICAgICAgIHJldHVybiBuZXcgU2luZ2xldG9uSXRlcmF0b3IobmV3ZG9tLmdldERvY3VtZW50KCksIHRydWUpOwotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vTWF0Y2hpbmdJdGVyYXRvci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vTWF0Y2hpbmdJdGVyYXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkMGJjMzljLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvZG9tL01hdGNoaW5nSXRlcmF0b3IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEyOSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBNYXRjaGluZ0l0ZXJhdG9yLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMDYgMDk6MjI6MDcgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmRvbTsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5ydW50aW1lLkJhc2lzTGlicmFyeTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1BeGlzSXRlcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0ucmVmLkRUTUF4aXNJdGVyYXRvckJhc2U7Ci0KLS8qKgotICogVGhpcyBpcyBhIHNwZWNpYWwga2luZCBvZiBpdGVyYXRvciB0aGF0IHRha2VzIGEgc291cmNlIGl0ZXJhdG9yIGFuZCBhCi0gKiBub2RlIE4uIElmIGluaXRpYWxpemVkIHdpdGggYSBub2RlIE0gKHRoZSBwYXJlbnQgb2YgTikgaXQgY29tcHV0ZXMgdGhlCi0gKiBwb3NpdGlvbiBvZiBOIGFtb25nc3QgdGhlIGNoaWxkcmVuIG9mIE0uIFRoaXMgcG9zaXRpb24gY2FuIGJlIG9idGFpbmVkCi0gKiBieSBjYWxsaW5nIGdldFBvc2l0aW9uKCkuCi0gKiBJdCBpcyBhbiBpdGVyYXRvciBldmVuIHRob3VnaCBuZXh0KCkgd2lsbCBuZXZlciBiZSBjYWxsZWQuIEl0IGlzIHVzZWQgdG8KLSAqIG1hdGNoIHBhdHRlcm5zIHdpdGggYSBzaW5nbGUgcHJlZGljYXRlIGxpa2U6Ci0gKgotICogICAgQk9PS1twb3NpdGlvbigpID0gbGFzdCgpXQotICoKLSAqIEluIHRoaXMgZXhhbXBsZSwgdGhlIHNvdXJjZSBpdGVyYXRvciB3aWxsIHJldHVybiBlbGVtZW50cyBvZiB0eXBlIEJPT0ssCi0gKiBhIGNhbGwgdG8gcG9zaXRpb24oKSB3aWxsIHJldHVybiB0aGUgcG9zaXRpb24gb2YgTi4gTm90aWNlIHRoYXQgYmVjYXVzZQotICogb2YgdGhlIHdheSB0aGUgcGF0dGVybiBtYXRjaGluZyBpcyBpbXBsZW1lbnRlZCwgTiB3aWxsIGFsd2F5cyBiZSBhIG5vZGUKLSAqIGluIHRoZSBzb3VyY2Ugc2luY2UgKGkpIGl0IGlzIGEgQk9PSyBvciB0aGUgdGVzdCBzZXF1ZW5jZSB3b3VsZCBub3QgYmUKLSAqIGNvbnNpZGVyZWQgYW5kIChpaSkgdGhlIHNvdXJjZSBpdGVyYXRvciBpcyBpbml0aWFsaXplZCB3aXRoIE0gd2hpY2ggaXMKLSAqIHRoZSBwYXJlbnQgb2YgTi4gQWxzbywgYW5kIHN0aWxsIGluIHRoaXMgZXhhbXBsZSwgYSBjYWxsIHRvIGxhc3QoKSB3aWxsCi0gKiByZXR1cm4gdGhlIG51bWJlciBvZiBlbGVtZW50cyBpbiB0aGUgc291cmNlIChpLmUuIHRoZSBudW1iZXIgb2YgQk9PS3MpLgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgTWF0Y2hpbmdJdGVyYXRvciBleHRlbmRzIERUTUF4aXNJdGVyYXRvckJhc2UgewotCi0gICAgLyoqCi0gICAgICogQSByZWZlcmVuY2UgdG8gYSBzb3VyY2UgaXRlcmF0b3IuCi0gICAgICovCi0gICAgcHJpdmF0ZSBEVE1BeGlzSXRlcmF0b3IgX3NvdXJjZTsKLQotICAgIC8qKgotICAgICAqIFRoZSBub2RlIHRvIG1hdGNoLgotICAgICAqLwotICAgIHByaXZhdGUgZmluYWwgaW50IF9tYXRjaDsKLQotICAgIHB1YmxpYyBNYXRjaGluZ0l0ZXJhdG9yKGludCBtYXRjaCwgRFRNQXhpc0l0ZXJhdG9yIHNvdXJjZSkgewotICAgICAgICBfc291cmNlID0gc291cmNlOwotICAgICAgICBfbWF0Y2ggPSBtYXRjaDsKLSAgICB9Ci0KLQotICAgIHB1YmxpYyB2b2lkIHNldFJlc3RhcnRhYmxlKGJvb2xlYW4gaXNSZXN0YXJ0YWJsZSkgewotICAgICAgICBfaXNSZXN0YXJ0YWJsZSA9IGlzUmVzdGFydGFibGU7Ci0gICAgICAgIF9zb3VyY2Uuc2V0UmVzdGFydGFibGUoaXNSZXN0YXJ0YWJsZSk7Ci0gICAgfQotCi0gICAgcHVibGljIERUTUF4aXNJdGVyYXRvciBjbG9uZUl0ZXJhdG9yKCkgewotCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBmaW5hbCBNYXRjaGluZ0l0ZXJhdG9yIGNsb25lID0gKE1hdGNoaW5nSXRlcmF0b3IpIHN1cGVyLmNsb25lKCk7Ci0gICAgICAgICAgICBjbG9uZS5fc291cmNlID0gX3NvdXJjZS5jbG9uZUl0ZXJhdG9yKCk7Ci0gICAgICAgICAgICBjbG9uZS5faXNSZXN0YXJ0YWJsZSA9IGZhbHNlOwotICAgICAgICAgICAgcmV0dXJuIGNsb25lLnJlc2V0KCk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIEJhc2lzTGlicmFyeS5ydW5UaW1lRXJyb3IoQmFzaXNMaWJyYXJ5LklURVJBVE9SX0NMT05FX0VSUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZS50b1N0cmluZygpKTsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIERUTUF4aXNJdGVyYXRvciBzZXRTdGFydE5vZGUoaW50IG5vZGUpIHsKLSAgICAgICAgaWYgKF9pc1Jlc3RhcnRhYmxlKSB7Ci0gICAgICAgICAgICAvLyBpdGVyYXRvciBpcyBub3QgYSBjbG9uZQotICAgICAgICAgICAgX3NvdXJjZS5zZXRTdGFydE5vZGUobm9kZSk7Ci0KLSAgICAgICAgICAgIC8vIENhbGN1bGF0ZSB0aGUgcG9zaXRpb24gb2YgdGhlIG5vZGUgaW4gdGhlIHNldAotICAgICAgICAgICAgX3Bvc2l0aW9uID0gMTsKLSAgICAgICAgICAgIHdoaWxlICgobm9kZSA9IF9zb3VyY2UubmV4dCgpKSAhPSBFTkQgJiYgbm9kZSAhPSBfbWF0Y2gpIHsKLSAgICAgICAgICAgICAgICBfcG9zaXRpb24rKzsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gdGhpczsKLSAgICB9Ci0KLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIHJlc2V0KCkgewotICAgICAgICBfc291cmNlLnJlc2V0KCk7Ci0gICAgICAgIHJldHVybiByZXNldFBvc2l0aW9uKCk7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBuZXh0KCkgewotICAgICAgICByZXR1cm4gX3NvdXJjZS5uZXh0KCk7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBnZXRMYXN0KCkgewotICAgICAgICBpZiAoX2xhc3QgPT0gLTEpIHsKLSAgICAgICAgICAgIF9sYXN0ID0gX3NvdXJjZS5nZXRMYXN0KCk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIF9sYXN0OwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgZ2V0UG9zaXRpb24oKSB7Ci0gICAgICAgIHJldHVybiBfcG9zaXRpb247Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0TWFyaygpIHsKLSAgICAgICAgX3NvdXJjZS5zZXRNYXJrKCk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgZ290b01hcmsoKSB7Ci0gICAgICAgIF9zb3VyY2UuZ290b01hcmsoKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2RvbS9NdWx0aURPTS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vTXVsdGlET00uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOTJlY2E5MS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2RvbS9NdWx0aURPTS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNzIwICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMTUsIDIwMTYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKi8KLS8qCi0gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKLSAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAotICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgotICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKLSAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCi0gKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5kb207Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuRE9NOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5TdHJpcEZpbHRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuVHJhbnNsZXRFeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnJ1bnRpbWUuQmFzaXNMaWJyYXJ5OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkF4aXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTUF4aXNJdGVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1NYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLnJlZi5EVE1BeGlzSXRlcmF0b3JCYXNlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLnJlZi5EVE1BeGlzSXRlck5vZGVMaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLnJlZi5EVE1EZWZhdWx0QmFzZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXIuU2VyaWFsaXphdGlvbkhhbmRsZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5TdWJhbGxvY2F0ZWRJbnRWZWN0b3I7Ci1pbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7Ci1pbXBvcnQgamF2YS51dGlsLk1hcDsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGVMaXN0OwotCi0vKioKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqIEBhdXRob3IgRXJ3aW4gQm9sd2lkdCA8ZWpiQGtsb21wLm9yZz4KLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIE11bHRpRE9NIGltcGxlbWVudHMgRE9NIHsKLQotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBOT19UWVBFID0gRE9NLkZJUlNUX1RZUEUgLSAyOwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBJTklUSUFMX1NJWkUgPSA0OwotCi0gICAgcHJpdmF0ZSBET01bXSBfYWRhcHRlcnM7Ci0gICAgcHJpdmF0ZSBET01BZGFwdGVyIF9tYWluOwotICAgIHByaXZhdGUgRFRNTWFuYWdlciBfZHRtTWFuYWdlcjsKLSAgICBwcml2YXRlIGludCBfZnJlZTsKLSAgICBwcml2YXRlIGludCBfc2l6ZTsKLQotICAgIHByaXZhdGUgTWFwPFN0cmluZywgSW50ZWdlcj4gX2RvY3VtZW50cyA9IG5ldyBIYXNoTWFwPD4oKTsKLQotICAgIHByaXZhdGUgZmluYWwgY2xhc3MgQXhpc0l0ZXJhdG9yIGV4dGVuZHMgRFRNQXhpc0l0ZXJhdG9yQmFzZSB7Ci0gICAgICAgIC8vIGNvbnN0aXR1dGl2ZSBkYXRhCi0gICAgICAgIHByaXZhdGUgZmluYWwgaW50IF9heGlzOwotICAgICAgICBwcml2YXRlIGZpbmFsIGludCBfdHlwZTsKLSAgICAgICAgLy8gaW1wbGVtZW50YXRpb24gbWVjaGFuaXNtCi0gICAgICAgIHByaXZhdGUgRFRNQXhpc0l0ZXJhdG9yIF9zb3VyY2U7Ci0gICAgICAgIHByaXZhdGUgaW50IF9kdG1JZCA9IC0xOwotCi0gICAgICAgIHB1YmxpYyBBeGlzSXRlcmF0b3IoZmluYWwgaW50IGF4aXMsIGZpbmFsIGludCB0eXBlKSB7Ci0gICAgICAgICAgICBfYXhpcyA9IGF4aXM7Ci0gICAgICAgICAgICBfdHlwZSA9IHR5cGU7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgaW50IG5leHQoKSB7Ci0gICAgICAgICAgICBpZiAoX3NvdXJjZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuKEVORCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gX3NvdXJjZS5uZXh0KCk7Ci0gICAgICAgIH0KLQotCi0gICAgICAgIHB1YmxpYyB2b2lkIHNldFJlc3RhcnRhYmxlKGJvb2xlYW4gZmxhZykgewotICAgICAgICAgICAgaWYgKF9zb3VyY2UgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIF9zb3VyY2Uuc2V0UmVzdGFydGFibGUoZmxhZyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIHNldFN0YXJ0Tm9kZShmaW5hbCBpbnQgbm9kZSkgewotICAgICAgICAgICAgaWYgKG5vZGUgPT0gRFRNLk5VTEwpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gdGhpczsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaW50IGRvbSA9IG5vZGUgPj4+IERUTU1hbmFnZXIuSURFTlRfRFRNX05PREVfQklUUzsKLQotICAgICAgICAgICAgLy8gR2V0IGEgbmV3IHNvdXJjZSBmaXJzdCB0aW1lIGFuZCB3aGVuIG1hc2sgY2hhbmdlcwotICAgICAgICAgICAgaWYgKF9zb3VyY2UgPT0gbnVsbCB8fCBfZHRtSWQgIT0gZG9tKSB7Ci0gICAgICAgICAgICAgICAgaWYgKF90eXBlID09IE5PX1RZUEUpIHsKLSAgICAgICAgICAgICAgICAgICAgX3NvdXJjZSA9IF9hZGFwdGVyc1tkb21dLmdldEF4aXNJdGVyYXRvcihfYXhpcyk7Ci0gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChfYXhpcyA9PSBBeGlzLkNISUxEKSB7Ci0gICAgICAgICAgICAgICAgICAgIF9zb3VyY2UgPSBfYWRhcHRlcnNbZG9tXS5nZXRUeXBlZENoaWxkcmVuKF90eXBlKTsKLSAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICBfc291cmNlID0gX2FkYXB0ZXJzW2RvbV0uZ2V0VHlwZWRBeGlzSXRlcmF0b3IoX2F4aXMsIF90eXBlKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIF9kdG1JZCA9IGRvbTsKLSAgICAgICAgICAgIF9zb3VyY2Uuc2V0U3RhcnROb2RlKG5vZGUpOwotICAgICAgICAgICAgcmV0dXJuIHRoaXM7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIHJlc2V0KCkgewotICAgICAgICAgICAgaWYgKF9zb3VyY2UgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIF9zb3VyY2UucmVzZXQoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiB0aGlzOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIGludCBnZXRMYXN0KCkgewotICAgICAgICAgICAgaWYgKF9zb3VyY2UgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJldHVybiBfc291cmNlLmdldExhc3QoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIHJldHVybiBFTkQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgaW50IGdldFBvc2l0aW9uKCkgewotICAgICAgICAgICAgaWYgKF9zb3VyY2UgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJldHVybiBfc291cmNlLmdldFBvc2l0aW9uKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gRU5EOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIGJvb2xlYW4gaXNSZXZlcnNlKCkgewotICAgICAgICAgICAgcmV0dXJuIEF4aXMuaXNSZXZlcnNlKF9heGlzKTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyB2b2lkIHNldE1hcmsoKSB7Ci0gICAgICAgICAgICBpZiAoX3NvdXJjZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgX3NvdXJjZS5zZXRNYXJrKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCBnb3RvTWFyaygpIHsKLSAgICAgICAgICAgIGlmIChfc291cmNlICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBfc291cmNlLmdvdG9NYXJrKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIGNsb25lSXRlcmF0b3IoKSB7Ci0gICAgICAgICAgICBmaW5hbCBBeGlzSXRlcmF0b3IgY2xvbmUgPSBuZXcgQXhpc0l0ZXJhdG9yKF9heGlzLCBfdHlwZSk7Ci0gICAgICAgICAgICBpZiAoX3NvdXJjZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgY2xvbmUuX3NvdXJjZSA9IF9zb3VyY2UuY2xvbmVJdGVyYXRvcigpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2xvbmUuX2R0bUlkID0gX2R0bUlkOwotICAgICAgICAgICAgcmV0dXJuIGNsb25lOwotICAgICAgICB9Ci0gICAgfSAvLyBlbmQgb2YgQXhpc0l0ZXJhdG9yCi0KLQotICAgIC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgotICAgICAqIFRoaXMgaXMgYSBzcGVjaWFsaXNlZCBpdGVyYXRvciBmb3IgcHJlZGljYXRlcyBjb21wYXJpbmcgbm9kZSBvcgotICAgICAqIGF0dHJpYnV0ZSB2YWx1ZXMgdG8gdmFyaWFibGUgb3IgcGFyYW1ldGVyIHZhbHVlcy4KLSAgICAgKi8KLSAgICBwcml2YXRlIGZpbmFsIGNsYXNzIE5vZGVWYWx1ZUl0ZXJhdG9yIGV4dGVuZHMgRFRNQXhpc0l0ZXJhdG9yQmFzZSB7Ci0KLSAgICAgICAgcHJpdmF0ZSBEVE1BeGlzSXRlcmF0b3IgX3NvdXJjZTsKLSAgICAgICAgcHJpdmF0ZSBTdHJpbmcgX3ZhbHVlOwotICAgICAgICBwcml2YXRlIGJvb2xlYW4gX29wOwotICAgICAgICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gX2lzUmV2ZXJzZTsKLSAgICAgICAgcHJpdmF0ZSBpbnQgX3JldHVyblR5cGUgPSBSRVRVUk5fUEFSRU5UOwotCi0gICAgICAgIHB1YmxpYyBOb2RlVmFsdWVJdGVyYXRvcihEVE1BeGlzSXRlcmF0b3Igc291cmNlLCBpbnQgcmV0dXJuVHlwZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyB2YWx1ZSwgYm9vbGVhbiBvcCkgewotICAgICAgICAgICAgX3NvdXJjZSA9IHNvdXJjZTsKLSAgICAgICAgICAgIF9yZXR1cm5UeXBlID0gcmV0dXJuVHlwZTsKLSAgICAgICAgICAgIF92YWx1ZSA9IHZhbHVlOwotICAgICAgICAgICAgX29wID0gb3A7Ci0gICAgICAgICAgICBfaXNSZXZlcnNlID0gc291cmNlLmlzUmV2ZXJzZSgpOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIGJvb2xlYW4gaXNSZXZlcnNlKCkgewotICAgICAgICAgICAgcmV0dXJuIF9pc1JldmVyc2U7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIGNsb25lSXRlcmF0b3IoKSB7Ci0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIE5vZGVWYWx1ZUl0ZXJhdG9yIGNsb25lID0gKE5vZGVWYWx1ZUl0ZXJhdG9yKXN1cGVyLmNsb25lKCk7Ci0gICAgICAgICAgICAgICAgY2xvbmUuX3NvdXJjZSA9IF9zb3VyY2UuY2xvbmVJdGVyYXRvcigpOwotICAgICAgICAgICAgICAgIGNsb25lLnNldFJlc3RhcnRhYmxlKGZhbHNlKTsKLSAgICAgICAgICAgICAgICByZXR1cm4gY2xvbmUucmVzZXQoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhdGNoIChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgQmFzaXNMaWJyYXJ5LnJ1blRpbWVFcnJvcihCYXNpc0xpYnJhcnkuSVRFUkFUT1JfQ0xPTkVfRVJSLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZS50b1N0cmluZygpKTsKLSAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0KLSAgICAgICAgcHVibGljIHZvaWQgc2V0UmVzdGFydGFibGUoYm9vbGVhbiBpc1Jlc3RhcnRhYmxlKSB7Ci0gICAgICAgICAgICBfaXNSZXN0YXJ0YWJsZSA9IGlzUmVzdGFydGFibGU7Ci0gICAgICAgICAgICBfc291cmNlLnNldFJlc3RhcnRhYmxlKGlzUmVzdGFydGFibGUpOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIERUTUF4aXNJdGVyYXRvciByZXNldCgpIHsKLSAgICAgICAgICAgIF9zb3VyY2UucmVzZXQoKTsKLSAgICAgICAgICAgIHJldHVybiByZXNldFBvc2l0aW9uKCk7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgaW50IG5leHQoKSB7Ci0KLSAgICAgICAgICAgIGludCBub2RlOwotICAgICAgICAgICAgd2hpbGUgKChub2RlID0gX3NvdXJjZS5uZXh0KCkpICE9IEVORCkgewotICAgICAgICAgICAgICAgIFN0cmluZyB2YWwgPSBnZXRTdHJpbmdWYWx1ZVgobm9kZSk7Ci0gICAgICAgICAgICAgICAgaWYgKF92YWx1ZS5lcXVhbHModmFsKSA9PSBfb3ApIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKF9yZXR1cm5UeXBlID09IFJFVFVSTl9DVVJSRU5UKQotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJldHVybk5vZGUobm9kZSk7Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXR1cm5Ob2RlKGdldFBhcmVudChub2RlKSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIEVORDsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3Igc2V0U3RhcnROb2RlKGludCBub2RlKSB7Ci0gICAgICAgICAgICBpZiAoX2lzUmVzdGFydGFibGUpIHsKLSAgICAgICAgICAgICAgICBfc291cmNlLnNldFN0YXJ0Tm9kZShfc3RhcnROb2RlID0gbm9kZSk7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHJlc2V0UG9zaXRpb24oKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiB0aGlzOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIHZvaWQgc2V0TWFyaygpIHsKLSAgICAgICAgICAgIF9zb3VyY2Uuc2V0TWFyaygpOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIHZvaWQgZ290b01hcmsoKSB7Ci0gICAgICAgICAgICBfc291cmNlLmdvdG9NYXJrKCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgTXVsdGlET00oRE9NIG1haW4pIHsKLSAgICAgICAgX3NpemUgPSBJTklUSUFMX1NJWkU7Ci0gICAgICAgIF9mcmVlID0gMTsKLSAgICAgICAgX2FkYXB0ZXJzID0gbmV3IERPTVtJTklUSUFMX1NJWkVdOwotICAgICAgICBET01BZGFwdGVyIGFkYXB0ZXIgPSAoRE9NQWRhcHRlciltYWluOwotICAgICAgICBfYWRhcHRlcnNbMF0gPSBhZGFwdGVyOwotICAgICAgICBfbWFpbiA9IGFkYXB0ZXI7Ci0gICAgICAgIERPTSBkb20gPSBhZGFwdGVyLmdldERPTUltcGwoKTsKLSAgICAgICAgaWYgKGRvbSBpbnN0YW5jZW9mIERUTURlZmF1bHRCYXNlKSB7Ci0gICAgICAgICAgICBfZHRtTWFuYWdlciA9ICgoRFRNRGVmYXVsdEJhc2UpZG9tKS5nZXRNYW5hZ2VyKCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyAlSFolICVSRVZJU0lUJSBJcyB0aGlzIHRoZSByaWdodCB0aGluZyB0byBkbyBoZXJlPyAgSW4gdGhlIG9sZAotICAgICAgICAvLyAlSFolICVSRVZJU0lUJSB2ZXJzaW9uLCB0aGUgbWFpbiBkb2N1bWVudCBkaWQgbm90IGdldCBhZGRlZCB0aHJvdWdoCi0gICAgICAgIC8vICVIWiUgJVJFVklTSVQlIGEgY2FsbCB0byBhZGRET01BZGFwdGVyLCB3aGljaCBtZWFudCBpdCBjb3VsZG4ndCBiZQotICAgICAgICAvLyAlSFolICVSRVZJU0lUJSBmb3VuZCBieSBhIGNhbGwgdG8gZ2V0RG9jdW1lbnRNYXNrLiAgVGhlIHByb2JsZW0gaXMKLSAgICAgICAgLy8gJUhaJSAlUkVWSVNJVCUgVHJhbnNmb3JtZXJIYW5kbGVyIGlzIHR5cGljYWxseSBjb25zdHJ1Y3RlZCB3aXRoIGEKLSAgICAgICAgLy8gJUhaJSAlUkVWSVNJVCUgc3lzdGVtIElEIGVxdWFsIHRvIHRoZSBzdHlsZXNoZWV0J3MgVVJJOyB3aXRoIFNBWAotICAgICAgICAvLyAlSFolICVSRVZJU0lUJSBpbnB1dCwgaXQgZW5kcyB1cCBnaXZpbmcgdGhhdCBVUkkgdG8gdGhlIGRvY3VtZW50LgotICAgICAgICAvLyAlSFolICVSRVZJU0lUJSBUaGVuLCBhbnkgcmVmZXJlbmNlcyB0byBkb2N1bWVudCgnJykgYXJlIHJlc29sdmVkCi0gICAgICAgIC8vICVIWiUgJVJFVklTSVQlIHVzaW5nIHRoZSBzdHlsZXNoZWV0J3MgVVJJLgotICAgICAgICAvLyAlSFolICVSRVZJU0lUJSBNdWx0aURPTS5nZXREb2N1bWVudE1hc2sgaXMgY2FsbGVkIHRvIHZlcmlmeSB0aGF0Ci0gICAgICAgIC8vICVIWiUgJVJFVklTSVQlIGEgZG9jdW1lbnQgYXNzb2NpYXRlZCB3aXRoIHRoYXQgVVJJIGhhcyBub3QgYmVlbgotICAgICAgICAvLyAlSFolICVSRVZJU0lUJSBlbmNvdW50ZXJlZCwgYW5kIHRoYXQgbWV0aG9kIGVuZHMgdXAgcmV0dXJuaW5nIHRoZQotICAgICAgICAvLyAlSFolICVSRVZJU0lUJSBtYXNrIG9mIHRoZSBtYWluIGRvY3VtZW50LCB3aGVuIHdoYXQgd2UgcmVhbGx5IHdoYXQKLSAgICAgICAgLy8gJUhaJSAlUkVWSVNJVCUgaXMgdG8gcmVhZCB0aGUgc3R5bGVzaGVldCBpdHNlbGYhCi0gICAgICAgIGFkZERPTUFkYXB0ZXIoYWRhcHRlciwgZmFsc2UpOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgbmV4dE1hc2soKSB7Ci0gICAgICAgIHJldHVybiBfZnJlZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXR1cE1hcHBpbmcoU3RyaW5nW10gbmFtZXMsIFN0cmluZ1tdIHVyaXMsIGludFtdIHR5cGVzLCBTdHJpbmdbXSBuYW1lc3BhY2VzKSB7Ci0gICAgICAgIC8vIFRoaXMgbWV0aG9kIG9ubHkgaGFzIGEgZnVuY3Rpb24gaW4gRE9NIGFkYXB0ZXJzCi0gICAgfQotCi0gICAgcHVibGljIGludCBhZGRET01BZGFwdGVyKERPTUFkYXB0ZXIgYWRhcHRlcikgewotICAgICAgICByZXR1cm4gYWRkRE9NQWRhcHRlcihhZGFwdGVyLCB0cnVlKTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIGludCBhZGRET01BZGFwdGVyKERPTUFkYXB0ZXIgYWRhcHRlciwgYm9vbGVhbiBpbmRleEJ5VVJJKSB7Ci0gICAgICAgIC8vIEFkZCB0aGUgRE9NIGFkYXB0ZXIgdG8gdGhlIGFycmF5IG9mIERPTXMKLSAgICAgICAgRE9NIGRvbSA9IGFkYXB0ZXIuZ2V0RE9NSW1wbCgpOwotCi0gICAgICAgIGludCBkb21ObyA9IDE7Ci0gICAgICAgIGludCBkdG1TaXplID0gMTsKLSAgICAgICAgU3ViYWxsb2NhdGVkSW50VmVjdG9yIGR0bUlkcyA9IG51bGw7Ci0gICAgICAgIGlmIChkb20gaW5zdGFuY2VvZiBEVE1EZWZhdWx0QmFzZSkgewotICAgICAgICAgICAgRFRNRGVmYXVsdEJhc2UgZHRtZGIgPSAoRFRNRGVmYXVsdEJhc2UpZG9tOwotICAgICAgICAgICAgZHRtSWRzID0gZHRtZGIuZ2V0RFRNSURzKCk7Ci0gICAgICAgICAgICBkdG1TaXplID0gZHRtSWRzLnNpemUoKTsKLSAgICAgICAgICAgIGRvbU5vID0gZHRtSWRzLmVsZW1lbnRBdChkdG1TaXplLTEpID4+PiBEVE1NYW5hZ2VyLklERU5UX0RUTV9OT0RFX0JJVFM7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoZG9tIGluc3RhbmNlb2YgU2ltcGxlUmVzdWx0VHJlZUltcGwpIHsKLSAgICAgICAgICAgIFNpbXBsZVJlc3VsdFRyZWVJbXBsIHNpbXBsZVJURiA9IChTaW1wbGVSZXN1bHRUcmVlSW1wbClkb207Ci0gICAgICAgICAgICBkb21ObyA9IHNpbXBsZVJURi5nZXREb2N1bWVudCgpID4+PiBEVE1NYW5hZ2VyLklERU5UX0RUTV9OT0RFX0JJVFM7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoZG9tTm8gPj0gX3NpemUpIHsKLSAgICAgICAgICAgIGludCBvbGRTaXplID0gX3NpemU7Ci0gICAgICAgICAgICBkbyB7Ci0gICAgICAgICAgICAgICAgX3NpemUgKj0gMjsKLSAgICAgICAgICAgIH0gd2hpbGUgKF9zaXplIDw9IGRvbU5vKTsKLQotICAgICAgICAgICAgZmluYWwgRE9NQWRhcHRlcltdIG5ld0FycmF5ID0gbmV3IERPTUFkYXB0ZXJbX3NpemVdOwotICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShfYWRhcHRlcnMsIDAsIG5ld0FycmF5LCAwLCBvbGRTaXplKTsKLSAgICAgICAgICAgIF9hZGFwdGVycyA9IG5ld0FycmF5OwotICAgICAgICB9Ci0KLSAgICAgICAgX2ZyZWUgPSBkb21ObyArIDE7Ci0KLSAgICAgICAgaWYgKGR0bVNpemUgPT0gMSkgewotICAgICAgICAgICAgX2FkYXB0ZXJzW2RvbU5vXSA9IGFkYXB0ZXI7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoZHRtSWRzICE9IG51bGwpIHsKLSAgICAgICAgICAgIGludCBkb21Qb3MgPSAwOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IGR0bVNpemUgLSAxOyBpID49IDA7IGktLSkgewotICAgICAgICAgICAgICAgIGRvbVBvcyA9IGR0bUlkcy5lbGVtZW50QXQoaSkgPj4+IERUTU1hbmFnZXIuSURFTlRfRFRNX05PREVfQklUUzsKLSAgICAgICAgICAgICAgICBfYWRhcHRlcnNbZG9tUG9zXSA9IGFkYXB0ZXI7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBkb21ObyA9IGRvbVBvczsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIFN0b3JlIHJlZmVyZW5jZSB0byBkb2N1bWVudCAoVVJJKSBpbiB0aGUgTWFwCi0gICAgICAgIGlmIChpbmRleEJ5VVJJKSB7Ci0gICAgICAgICAgICBTdHJpbmcgdXJpID0gYWRhcHRlci5nZXREb2N1bWVudFVSSSgwKTsKLSAgICAgICAgICAgIF9kb2N1bWVudHMucHV0KHVyaSwgZG9tTm8pOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gSWYgdGhlIGRvbSBpcyBhbiBBZGFwdGl2ZVJlc3VsdFRyZWVJbXBsLCB3ZSBuZWVkIHRvIGNyZWF0ZSBhCi0gICAgICAgIC8vIERPTUFkYXB0ZXIgYXJvdW5kIGl0cyBuZXN0ZWQgZG9tIG9iamVjdCAoaWYgaXQgaXMgbm9uLW51bGwpIGFuZAotICAgICAgICAvLyBhZGQgdGhlIERPTUFkYXB0ZXIgdG8gdGhlIGxpc3QuCi0gICAgICAgIGlmIChkb20gaW5zdGFuY2VvZiBBZGFwdGl2ZVJlc3VsdFRyZWVJbXBsKSB7Ci0gICAgICAgICAgICBBZGFwdGl2ZVJlc3VsdFRyZWVJbXBsIGFkYXB0aXZlUlRGID0gKEFkYXB0aXZlUmVzdWx0VHJlZUltcGwpZG9tOwotICAgICAgICAgICAgRE9NIG5lc3RlZERvbSA9IGFkYXB0aXZlUlRGLmdldE5lc3RlZERPTSgpOwotICAgICAgICAgICAgaWYgKG5lc3RlZERvbSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgRE9NQWRhcHRlciBuZXdBZGFwdGVyID0gbmV3IERPTUFkYXB0ZXIobmVzdGVkRG9tLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkYXB0ZXIuZ2V0TmFtZXNBcnJheSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkYXB0ZXIuZ2V0VXJpc0FycmF5KCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRhcHRlci5nZXRUeXBlc0FycmF5KCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRhcHRlci5nZXROYW1lc3BhY2VBcnJheSgpKTsKLSAgICAgICAgICAgICAgICBhZGRET01BZGFwdGVyKG5ld0FkYXB0ZXIpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIGRvbU5vOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgZ2V0RG9jdW1lbnRNYXNrKFN0cmluZyB1cmkpIHsKLSAgICAgICAgSW50ZWdlciBkb21JZHggPSBfZG9jdW1lbnRzLmdldCh1cmkpOwotICAgICAgICBpZiAoZG9tSWR4ID09IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybigtMSk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gZG9tSWR4LmludFZhbHVlKCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgRE9NIGdldERPTUFkYXB0ZXIoU3RyaW5nIHVyaSkgewotICAgICAgICBJbnRlZ2VyIGRvbUlkeCA9IF9kb2N1bWVudHMuZ2V0KHVyaSk7Ci0gICAgICAgIGlmIChkb21JZHggPT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuKG51bGwpOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgcmV0dXJuKF9hZGFwdGVyc1tkb21JZHguaW50VmFsdWUoKV0pOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIGludCBnZXREb2N1bWVudCgpCi0gICAgewotICAgICAgICByZXR1cm4gX21haW4uZ2V0RG9jdW1lbnQoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgRFRNTWFuYWdlciBnZXREVE1NYW5hZ2VyKCkgewotICAgICAgICByZXR1cm4gX2R0bU1hbmFnZXI7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICAqIFJldHVybnMgc2luZ2xldG9uIGl0ZXJhdG9yIGNvbnRhaW5pbmcgdGhlIGRvY3VtZW50IHJvb3QKLSAgICAgICovCi0gICAgcHVibGljIERUTUF4aXNJdGVyYXRvciBnZXRJdGVyYXRvcigpIHsKLSAgICAgICAgLy8gbWFpbiBzb3VyY2UgZG9jdW1lbnQgQCAwCi0gICAgICAgIHJldHVybiBfbWFpbi5nZXRJdGVyYXRvcigpOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3RyaW5nVmFsdWUoKSB7Ci0gICAgICAgIHJldHVybiBfbWFpbi5nZXRTdHJpbmdWYWx1ZSgpOwotICAgIH0KLQotICAgIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3IgZ2V0Q2hpbGRyZW4oZmluYWwgaW50IG5vZGUpIHsKLSAgICAgICAgcmV0dXJuIF9hZGFwdGVyc1tnZXREVE1JZChub2RlKV0uZ2V0Q2hpbGRyZW4obm9kZSk7Ci0gICAgfQotCi0gICAgcHVibGljIERUTUF4aXNJdGVyYXRvciBnZXRUeXBlZENoaWxkcmVuKGZpbmFsIGludCB0eXBlKSB7Ci0gICAgICAgIHJldHVybiBuZXcgQXhpc0l0ZXJhdG9yKEF4aXMuQ0hJTEQsIHR5cGUpOwotICAgIH0KLQotICAgIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3IgZ2V0QXhpc0l0ZXJhdG9yKGZpbmFsIGludCBheGlzKSB7Ci0gICAgICAgIHJldHVybiBuZXcgQXhpc0l0ZXJhdG9yKGF4aXMsIE5PX1RZUEUpOwotICAgIH0KLQotICAgIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3IgZ2V0VHlwZWRBeGlzSXRlcmF0b3IoZmluYWwgaW50IGF4aXMsIGZpbmFsIGludCB0eXBlKQotICAgIHsKLSAgICAgICAgcmV0dXJuIG5ldyBBeGlzSXRlcmF0b3IoYXhpcywgdHlwZSk7Ci0gICAgfQotCi0gICAgcHVibGljIERUTUF4aXNJdGVyYXRvciBnZXROdGhEZXNjZW5kYW50KGludCBub2RlLCBpbnQgbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBpbmNsdWRlc2VsZikKLSAgICB7Ci0gICAgICAgIHJldHVybiBfYWRhcHRlcnNbZ2V0RFRNSWQobm9kZSldLmdldE50aERlc2NlbmRhbnQobm9kZSwgbiwgaW5jbHVkZXNlbGYpOwotICAgIH0KLQotICAgIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3IgZ2V0Tm9kZVZhbHVlSXRlcmF0b3IoRFRNQXhpc0l0ZXJhdG9yIGl0ZXJhdG9yLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHR5cGUsIFN0cmluZyB2YWx1ZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gb3ApCi0gICAgewotICAgICAgICByZXR1cm4obmV3IE5vZGVWYWx1ZUl0ZXJhdG9yKGl0ZXJhdG9yLCB0eXBlLCB2YWx1ZSwgb3ApKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIGdldE5hbWVzcGFjZUF4aXNJdGVyYXRvcihmaW5hbCBpbnQgYXhpcywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgbnMpCi0gICAgewotICAgICAgICBEVE1BeGlzSXRlcmF0b3IgaXRlcmF0b3IgPSBfbWFpbi5nZXROYW1lc3BhY2VBeGlzSXRlcmF0b3IoYXhpcywgbnMpOwotICAgICAgICByZXR1cm4oaXRlcmF0b3IpOwotICAgIH0KLQotICAgIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3Igb3JkZXJOb2RlcyhEVE1BeGlzSXRlcmF0b3Igc291cmNlLCBpbnQgbm9kZSkgewotICAgICAgICByZXR1cm4gX2FkYXB0ZXJzW2dldERUTUlkKG5vZGUpXS5vcmRlck5vZGVzKHNvdXJjZSwgbm9kZSk7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBnZXRFeHBhbmRlZFR5cGVJRChmaW5hbCBpbnQgbm9kZSkgewotICAgICAgICBpZiAobm9kZSAhPSBEVE0uTlVMTCkgewotICAgICAgICAgICAgcmV0dXJuIF9hZGFwdGVyc1tub2RlID4+PiBEVE1NYW5hZ2VyLklERU5UX0RUTV9OT0RFX0JJVFNdLmdldEV4cGFuZGVkVHlwZUlEKG5vZGUpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIERUTS5OVUxMOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIGludCBnZXROYW1lc3BhY2VUeXBlKGZpbmFsIGludCBub2RlKSB7Ci0gICAgICAgIHJldHVybiBfYWRhcHRlcnNbZ2V0RFRNSWQobm9kZSldLmdldE5hbWVzcGFjZVR5cGUobm9kZSk7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBnZXROU1R5cGUoaW50IG5vZGUpCi0gICB7Ci0gICAgICAgIHJldHVybiBfYWRhcHRlcnNbZ2V0RFRNSWQobm9kZSldLmdldE5TVHlwZShub2RlKTsKLSAgIH0KLQotICAgIHB1YmxpYyBpbnQgZ2V0UGFyZW50KGZpbmFsIGludCBub2RlKSB7Ci0gICAgICAgIGlmIChub2RlID09IERUTS5OVUxMKSB7Ci0gICAgICAgICAgICByZXR1cm4gRFRNLk5VTEw7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIF9hZGFwdGVyc1tub2RlID4+PiBEVE1NYW5hZ2VyLklERU5UX0RUTV9OT0RFX0JJVFNdLmdldFBhcmVudChub2RlKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldEF0dHJpYnV0ZU5vZGUoZmluYWwgaW50IHR5cGUsIGZpbmFsIGludCBlbCkgewotICAgICAgICBpZiAoZWwgPT0gRFRNLk5VTEwpIHsKLSAgICAgICAgICAgIHJldHVybiBEVE0uTlVMTDsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gX2FkYXB0ZXJzW2VsID4+PiBEVE1NYW5hZ2VyLklERU5UX0RUTV9OT0RFX0JJVFNdLmdldEF0dHJpYnV0ZU5vZGUodHlwZSwgZWwpOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Tm9kZU5hbWUoZmluYWwgaW50IG5vZGUpIHsKLSAgICAgICAgaWYgKG5vZGUgPT0gRFRNLk5VTEwpIHsKLSAgICAgICAgICAgIHJldHVybiAiIjsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gX2FkYXB0ZXJzW25vZGUgPj4+IERUTU1hbmFnZXIuSURFTlRfRFRNX05PREVfQklUU10uZ2V0Tm9kZU5hbWUobm9kZSk7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXROb2RlTmFtZVgoZmluYWwgaW50IG5vZGUpIHsKLSAgICAgICAgaWYgKG5vZGUgPT0gRFRNLk5VTEwpIHsKLSAgICAgICAgICAgIHJldHVybiAiIjsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gX2FkYXB0ZXJzW25vZGUgPj4+IERUTU1hbmFnZXIuSURFTlRfRFRNX05PREVfQklUU10uZ2V0Tm9kZU5hbWVYKG5vZGUpOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZXNwYWNlTmFtZShmaW5hbCBpbnQgbm9kZSkgewotICAgICAgICBpZiAobm9kZSA9PSBEVE0uTlVMTCkgewotICAgICAgICAgICAgcmV0dXJuICIiOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBfYWRhcHRlcnNbbm9kZSA+Pj4gRFRNTWFuYWdlci5JREVOVF9EVE1fTk9ERV9CSVRTXS5nZXROYW1lc3BhY2VOYW1lKG5vZGUpOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3RyaW5nVmFsdWVYKGZpbmFsIGludCBub2RlKSB7Ci0gICAgICAgIGlmIChub2RlID09IERUTS5OVUxMKSB7Ci0gICAgICAgICAgICByZXR1cm4gIiI7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIF9hZGFwdGVyc1tub2RlID4+PiBEVE1NYW5hZ2VyLklERU5UX0RUTV9OT0RFX0JJVFNdLmdldFN0cmluZ1ZhbHVlWChub2RlKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBjb3B5KGZpbmFsIGludCBub2RlLCBTZXJpYWxpemF0aW9uSGFuZGxlciBoYW5kbGVyKQotICAgICAgICB0aHJvd3MgVHJhbnNsZXRFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGlmIChub2RlICE9IERUTS5OVUxMKSB7Ci0gICAgICAgICAgICBfYWRhcHRlcnNbbm9kZSA+Pj4gRFRNTWFuYWdlci5JREVOVF9EVE1fTk9ERV9CSVRTXS5jb3B5KG5vZGUsIGhhbmRsZXIpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgY29weShEVE1BeGlzSXRlcmF0b3Igbm9kZXMsIFNlcmlhbGl6YXRpb25IYW5kbGVyIGhhbmRsZXIpCi0gICAgICAgICAgICB0aHJvd3MgVHJhbnNsZXRFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGludCBub2RlOwotICAgICAgICB3aGlsZSAoKG5vZGUgPSBub2Rlcy5uZXh0KCkpICE9IERUTS5OVUxMKSB7Ci0gICAgICAgICAgICBfYWRhcHRlcnNbbm9kZSA+Pj4gRFRNTWFuYWdlci5JREVOVF9EVE1fTk9ERV9CSVRTXS5jb3B5KG5vZGUsIGhhbmRsZXIpOwotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgU3RyaW5nIHNoYWxsb3dDb3B5KGZpbmFsIGludCBub2RlLCBTZXJpYWxpemF0aW9uSGFuZGxlciBoYW5kbGVyKQotICAgICAgICAgICAgdGhyb3dzIFRyYW5zbGV0RXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAobm9kZSA9PSBEVE0uTlVMTCkgewotICAgICAgICAgICAgcmV0dXJuICIiOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBfYWRhcHRlcnNbbm9kZSA+Pj4gRFRNTWFuYWdlci5JREVOVF9EVE1fTk9ERV9CSVRTXS5zaGFsbG93Q29weShub2RlLCBoYW5kbGVyKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBsZXNzVGhhbihmaW5hbCBpbnQgbm9kZTEsIGZpbmFsIGludCBub2RlMikgewotICAgICAgICBpZiAobm9kZTEgPT0gRFRNLk5VTEwpIHsKLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0gICAgICAgIGlmIChub2RlMiA9PSBEVE0uTlVMTCkgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0gICAgICAgIGZpbmFsIGludCBkb20xID0gZ2V0RFRNSWQobm9kZTEpOwotICAgICAgICBmaW5hbCBpbnQgZG9tMiA9IGdldERUTUlkKG5vZGUyKTsKLSAgICAgICAgcmV0dXJuIGRvbTEgPT0gZG9tMiA/IF9hZGFwdGVyc1tkb20xXS5sZXNzVGhhbihub2RlMSwgbm9kZTIpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBkb20xIDwgZG9tMjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBjaGFyYWN0ZXJzKGZpbmFsIGludCB0ZXh0Tm9kZSwgU2VyaWFsaXphdGlvbkhhbmRsZXIgaGFuZGxlcikKLSAgICAgICAgICAgICAgICAgdGhyb3dzIFRyYW5zbGV0RXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAodGV4dE5vZGUgIT0gRFRNLk5VTEwpIHsKLSAgICAgICAgICAgIF9hZGFwdGVyc1t0ZXh0Tm9kZSA+Pj4gRFRNTWFuYWdlci5JREVOVF9EVE1fTk9ERV9CSVRTXS5jaGFyYWN0ZXJzKHRleHROb2RlLCBoYW5kbGVyKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldEZpbHRlcihTdHJpcEZpbHRlciBmaWx0ZXIpIHsKLSAgICAgICAgZm9yIChpbnQgZG9tPTA7IGRvbTxfZnJlZTsgZG9tKyspIHsKLSAgICAgICAgICAgIGlmIChfYWRhcHRlcnNbZG9tXSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgX2FkYXB0ZXJzW2RvbV0uc2V0RmlsdGVyKGZpbHRlcik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgTm9kZSBtYWtlTm9kZShpbnQgaW5kZXgpIHsKLSAgICAgICAgaWYgKGluZGV4ID09IERUTS5OVUxMKSB7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gX2FkYXB0ZXJzW2dldERUTUlkKGluZGV4KV0ubWFrZU5vZGUoaW5kZXgpOwotICAgIH0KLQotICAgIHB1YmxpYyBOb2RlIG1ha2VOb2RlKERUTUF4aXNJdGVyYXRvciBpdGVyKSB7Ci0gICAgICAgIC8vIFRPRE86IGdhdGhlciBub2RlcyBmcm9tIGFsbCBET01zID8KLSAgICAgICAgcmV0dXJuIF9tYWluLm1ha2VOb2RlKGl0ZXIpOwotICAgIH0KLQotICAgIHB1YmxpYyBOb2RlTGlzdCBtYWtlTm9kZUxpc3QoaW50IGluZGV4KSB7Ci0gICAgICAgIGlmIChpbmRleCA9PSBEVE0uTlVMTCkgewotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIF9hZGFwdGVyc1tnZXREVE1JZChpbmRleCldLm1ha2VOb2RlTGlzdChpbmRleCk7Ci0gICAgfQotCi0gICAgcHVibGljIE5vZGVMaXN0IG1ha2VOb2RlTGlzdChEVE1BeGlzSXRlcmF0b3IgaXRlcikgewotICAgICAgICBpbnQgaW5kZXggPSBpdGVyLm5leHQoKTsKLSAgICAgICAgaWYgKGluZGV4ID09IERUTS5OVUxMKSB7Ci0gICAgICAgICAgICByZXR1cm4gbmV3IERUTUF4aXNJdGVyTm9kZUxpc3QobnVsbCwgbnVsbCk7Ci0gICAgICAgIH0KLSAgICAgICAgaXRlci5yZXNldCgpOwotICAgICAgICByZXR1cm4gX2FkYXB0ZXJzW2dldERUTUlkKGluZGV4KV0ubWFrZU5vZGVMaXN0KGl0ZXIpOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TGFuZ3VhZ2UoaW50IG5vZGUpIHsKLSAgICAgICAgcmV0dXJuIF9hZGFwdGVyc1tnZXREVE1JZChub2RlKV0uZ2V0TGFuZ3VhZ2Uobm9kZSk7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBnZXRTaXplKCkgewotICAgICAgICBpbnQgc2l6ZSA9IDA7Ci0gICAgICAgIGZvciAoaW50IGk9MDsgaTxfc2l6ZTsgaSsrKSB7Ci0gICAgICAgICAgICBzaXplICs9IF9hZGFwdGVyc1tpXS5nZXRTaXplKCk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuKHNpemUpOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0RG9jdW1lbnRVUkkoaW50IG5vZGUpIHsKLSAgICAgICAgaWYgKG5vZGUgPT0gRFRNLk5VTEwpIHsKLSAgICAgICAgICAgIG5vZGUgPSBET00uTlVMTDsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gX2FkYXB0ZXJzW25vZGUgPj4+IERUTU1hbmFnZXIuSURFTlRfRFRNX05PREVfQklUU10uZ2V0RG9jdW1lbnRVUkkoMCk7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gaXNFbGVtZW50KGZpbmFsIGludCBub2RlKSB7Ci0gICAgICAgIGlmIChub2RlID09IERUTS5OVUxMKSB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuKF9hZGFwdGVyc1tub2RlID4+PiBEVE1NYW5hZ2VyLklERU5UX0RUTV9OT0RFX0JJVFNdLmlzRWxlbWVudChub2RlKSk7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gaXNBdHRyaWJ1dGUoZmluYWwgaW50IG5vZGUpIHsKLSAgICAgICAgaWYgKG5vZGUgPT0gRFRNLk5VTEwpIHsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4oX2FkYXB0ZXJzW25vZGUgPj4+IERUTU1hbmFnZXIuSURFTlRfRFRNX05PREVfQklUU10uaXNBdHRyaWJ1dGUobm9kZSkpOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgZ2V0RFRNSWQoaW50IG5vZGVIYW5kbGUpCi0gICAgewotICAgICAgICBpZiAobm9kZUhhbmRsZSA9PSBEVE0uTlVMTCkKLSAgICAgICAgICAgIHJldHVybiAwOwotCi0gICAgICAgIGludCBpZCA9IG5vZGVIYW5kbGUgPj4+IERUTU1hbmFnZXIuSURFTlRfRFRNX05PREVfQklUUzsKLSAgICAgICAgd2hpbGUgKGlkID49IDIgJiYgX2FkYXB0ZXJzW2lkXSA9PSBfYWRhcHRlcnNbaWQtMV0pIHsKLSAgICAgICAgICAgIGlkLS07Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGlkOwotICAgIH0KLQotICAgIHB1YmxpYyBET00gZ2V0RFRNKGludCBub2RlSGFuZGxlKSB7Ci0gICAgICAgIHJldHVybiBfYWRhcHRlcnNbZ2V0RFRNSWQobm9kZUhhbmRsZSldOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgZ2V0Tm9kZUlkZW50KGludCBub2RlSGFuZGxlKQotICAgIHsKLSAgICAgICAgcmV0dXJuIF9hZGFwdGVyc1tub2RlSGFuZGxlID4+PiBEVE1NYW5hZ2VyLklERU5UX0RUTV9OT0RFX0JJVFNdLmdldE5vZGVJZGVudChub2RlSGFuZGxlKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldE5vZGVIYW5kbGUoaW50IG5vZGVJZCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBfbWFpbi5nZXROb2RlSGFuZGxlKG5vZGVJZCk7Ci0gICAgfQotCi0gICAgcHVibGljIERPTSBnZXRSZXN1bHRUcmVlRnJhZyhpbnQgaW5pdFNpemUsIGludCBydGZUeXBlKQotICAgIHsKLSAgICAgICAgcmV0dXJuIF9tYWluLmdldFJlc3VsdFRyZWVGcmFnKGluaXRTaXplLCBydGZUeXBlKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgRE9NIGdldFJlc3VsdFRyZWVGcmFnKGludCBpbml0U2l6ZSwgaW50IHJ0ZlR5cGUsIGJvb2xlYW4gYWRkVG9NYW5hZ2VyKQotICAgIHsKLSAgICAgICAgcmV0dXJuIF9tYWluLmdldFJlc3VsdFRyZWVGcmFnKGluaXRTaXplLCBydGZUeXBlLCBhZGRUb01hbmFnZXIpOwotICAgIH0KLQotICAgIHB1YmxpYyBET00gZ2V0TWFpbigpCi0gICAgewotICAgICAgICByZXR1cm4gX21haW47Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhIERPTUJ1aWxkZXIgY2xhc3Mgd3JhcHBlZCBpbiBhIFNBWCBhZGFwdGVyLgotICAgICAqLwotICAgIHB1YmxpYyBTZXJpYWxpemF0aW9uSGFuZGxlciBnZXRPdXRwdXREb21CdWlsZGVyKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBfbWFpbi5nZXRPdXRwdXREb21CdWlsZGVyKCk7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBsb29rdXBOYW1lc3BhY2UoaW50IG5vZGUsIFN0cmluZyBwcmVmaXgpCi0gICAgICAgIHRocm93cyBUcmFuc2xldEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgcmV0dXJuIF9tYWluLmxvb2t1cE5hbWVzcGFjZShub2RlLCBwcmVmaXgpOwotICAgIH0KLQotICAgIC8vICVIWiUgRG9lcyB0aGlzIG1ldGhvZCBtYWtlIGFueSBzZW5zZSBoZXJlPz8/Ci0gICAgcHVibGljIFN0cmluZyBnZXRVbnBhcnNlZEVudGl0eVVSSShTdHJpbmcgZW50aXR5KSB7Ci0gICAgICAgIHJldHVybiBfbWFpbi5nZXRVbnBhcnNlZEVudGl0eVVSSShlbnRpdHkpOwotICAgIH0KLQotICAgIC8vICVIWiUgRG9lcyB0aGlzIG1ldGhvZCBtYWtlIGFueSBzZW5zZSBoZXJlPz8/Ci0gICAgcHVibGljIE1hcDxTdHJpbmcsIEludGVnZXI+IGdldEVsZW1lbnRzV2l0aElEcygpIHsKLSAgICAgICAgcmV0dXJuIF9tYWluLmdldEVsZW1lbnRzV2l0aElEcygpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHJlbGVhc2UoKSB7Ci0gICAgICAgIF9tYWluLnJlbGVhc2UoKTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIGJvb2xlYW4gaXNNYXRjaGluZ0FkYXB0ZXJFbnRyeShET00gZW50cnksIERPTUFkYXB0ZXIgYWRhcHRlcikgewotICAgICAgICBET00gZG9tID0gYWRhcHRlci5nZXRET01JbXBsKCk7Ci0KLSAgICAgICAgcmV0dXJuIChlbnRyeSA9PSBhZGFwdGVyKSB8fCAoCi0gICAgICAgICAgICAvKgotICAgICAgICAgICAgICogTWV0aG9kIGFkZERPTUFkYXB0ZXIgb3ZlcndyaXRlcyBmb3IgQWRhcHRpdmVSZXN1bHRUcmVlSW1wbAotICAgICAgICAgICAgICogb2JqZWN0cyB0aGUgdXN1YWwgZW50cnkgd2l0aCBhbiBhZGFwdGVyIHRvIHRoZSBuZXN0ZWQKLSAgICAgICAgICAgICAqIERPTSwgc28gd2UgbXVzdCBjaGVjayB0aGlzIGhlcmUuIFNlZSBsYXN0ICdpZicgc3RhdGVtZW50Ci0gICAgICAgICAgICAgKiBvZiBhZGRET01BZGFwdGVyLgotICAgICAgICAgICAgICovCi0gICAgICAgICAgICAoZG9tIGluc3RhbmNlb2YgQWRhcHRpdmVSZXN1bHRUcmVlSW1wbCkgJiYKLSAgICAgICAgICAgIChlbnRyeSBpbnN0YW5jZW9mIERPTUFkYXB0ZXIpICYmCi0gICAgICAgICAgICAoKChBZGFwdGl2ZVJlc3VsdFRyZWVJbXBsKWRvbSkuZ2V0TmVzdGVkRE9NKCkgPT0gKChET01BZGFwdGVyKWVudHJ5KS5nZXRET01JbXBsKCkpCi0gICAgICAgICk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgcmVtb3ZlRE9NQWRhcHRlcihET01BZGFwdGVyIGFkYXB0ZXIpIHsKLSAgICAgICAgX2RvY3VtZW50cy5yZW1vdmUoYWRhcHRlci5nZXREb2N1bWVudFVSSSgwKSk7Ci0gICAgICAgIERPTSBkb20gPSBhZGFwdGVyLmdldERPTUltcGwoKTsKLQotICAgICAgICBpZiAoZG9tIGluc3RhbmNlb2YgRFRNRGVmYXVsdEJhc2UpIHsKLSAgICAgICAgICAgIFN1YmFsbG9jYXRlZEludFZlY3RvciBpZHMgPSAoKERUTURlZmF1bHRCYXNlKSBkb20pLmdldERUTUlEcygpOwotICAgICAgICAgICAgaW50IGlkc1NpemUgPSBpZHMuc2l6ZSgpOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBpZHNTaXplOyBpKyspIHsKLSAgICAgICAgICAgICAgICBfYWRhcHRlcnNbaWRzLmVsZW1lbnRBdChpKSA+Pj4gRFRNTWFuYWdlci5JREVOVF9EVE1fTk9ERV9CSVRTXSA9IG51bGw7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBpbnQgaWQgPSBkb20uZ2V0RG9jdW1lbnQoKSA+Pj4gRFRNTWFuYWdlci5JREVOVF9EVE1fTk9ERV9CSVRTOwotICAgICAgICAgICAgaWYgKChpZCA+IDApICYmIChpZCA8IF9hZGFwdGVycy5sZW5ndGgpICYmIGlzTWF0Y2hpbmdBZGFwdGVyRW50cnkoX2FkYXB0ZXJzW2lkXSwgYWRhcHRlcikpIHsKLSAgICAgICAgICAgICAgICBfYWRhcHRlcnNbaWRdID0gbnVsbDsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgYm9vbGVhbiBmb3VuZCA9IGZhbHNlOwotICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgX2FkYXB0ZXJzLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChpc01hdGNoaW5nQWRhcHRlckVudHJ5KF9hZGFwdGVyc1tpZF0sIGFkYXB0ZXIpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBfYWRhcHRlcnNbaV0gPSBudWxsOwotICAgICAgICAgICAgICAgICAgICAgICAgZm91bmQgPSB0cnVlOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2RvbS9NdWx0aVZhbHVlZE5vZGVIZWFwSXRlcmF0b3IuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvZG9tL011bHRpVmFsdWVkTm9kZUhlYXBJdGVyYXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlZmMyMjUxLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvZG9tL011bHRpVmFsdWVkTm9kZUhlYXBJdGVyYXRvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjk2ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNiBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFVuaW9uSXRlcmF0b3IuamF2YSAzMzc4NzQgMjAwNC0wMi0xNiAyMzowNjo1M1ogbWluY2hhdSAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuZG9tOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLkRPTTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMucnVudGltZS5CYXNpc0xpYnJhcnk7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNQXhpc0l0ZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLnJlZi5EVE1BeGlzSXRlcmF0b3JCYXNlOwotCi0vKioKLSAqIDxwPjxjb2RlPk11bHRpVmFsdWVkTm9kZUhlYXBJdGVyYXRvcjwvY29kZT4gdGFrZXMgYSBzZXQgb2YgbXVsdGktdmFsdWVkCi0gKiBoZWFwIG5vZGVzIGFuZCBwcm9kdWNlcyBhIG1lcmdlZCBOb2RlU2V0IGluIGRvY3VtZW50IG9yZGVyIHdpdGggZHVwbGljYXRlcwotICogcmVtb3ZlZC48L3A+Ci0gKiA8cD5FYWNoIG11bHRpLXZhbHVlZCBoZWFwIG5vZGUgKHdoaWNoIG1pZ2h0IGJlIGEKLSAqIHtAbGluayBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNQXhpc0l0ZXJhdG9yfSwgYnV0IHRoYXQncyAgbm90IG5lY2Vzc2FyeSkKLSAqIGdlbmVyYXRlcyBEVE0gbm9kZSBoYW5kbGVzIGluIGRvY3VtZW50IG9yZGVyLiAgVGhlIGNsYXNzCi0gKiBtYWludGFpbnMgdGhlIG11bHRpLXZhbHVlZCBoZWFwIG5vZGVzIGluIGEgaGVhcCwgbm90IHN1cnByaXNpbmdseSwgc29ydGVkIGJ5Ci0gKiB0aGUgbmV4dCBEVE0gbm9kZSBoYW5kbGUgYXZhaWxhYmxlIGZvcm0gdGhlIGhlYXAgbm9kZS48L3A+Ci0gKiA8cD5BZnRlciBhIERUTSBub2RlIGlzIHB1bGxlZCBmcm9tIHRoZSBoZWFwIG5vZGUgdGhhdCdzIGF0IHRoZSB0b3Agb2YgdGhlCi0gKiBoZWFwLCB0aGUgaGVhcCBub2RlIGlzIGFkdmFuY2VkIHRvIHRoZSBuZXh0IERUTSBub2RlIGhhbmRsZSBpdCBtYWtlcwotICogYXZhaWxhYmxlLCBhbmQgdGhlIGhlYXAgbmF0dXJlIG9mIHRoZSBoZWFwIGlzIHJlc3RvcmVkIHRvIGVuc3VyZSB0aGUgbmV4dAotICogRFRNIG5vZGUgaGFuZGxlIHB1bGxlZCBpcyBuZXh0IGluIGRvY3VtZW50IG9yZGVyIG92ZXJhbGwuCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICovCi1wdWJsaWMgYWJzdHJhY3QgY2xhc3MgTXVsdGlWYWx1ZWROb2RlSGVhcEl0ZXJhdG9yIGV4dGVuZHMgRFRNQXhpc0l0ZXJhdG9yQmFzZSB7Ci0gICAgLyoqIHdyYXBwZXIgZm9yIE5vZGVJdGVyYXRvcnMgdG8gc3VwcG9ydCBpdGVyYXRvcgotICAgICAgICBjb21wYXJpc29uIG9uIHRoZSB2YWx1ZSBvZiB0aGVpciBuZXh0KCkgbWV0aG9kCi0gICAgKi8KLQotICAgIC8qKgotICAgICAqIEFuIGFic3RyYWN0IHJlcHJlc2VudGF0aW9uIG9mIGEgc2V0IG9mIG5vZGVzIHRoYXQgd2lsbCBiZSByZXRyaWV2ZWQgaW4KLSAgICAgKiBkb2N1bWVudCBvcmRlci4KLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3QgY2xhc3MgSGVhcE5vZGUgaW1wbGVtZW50cyBDbG9uZWFibGUgewotICAgICAgICBwcm90ZWN0ZWQgaW50IF9ub2RlLCBfbWFya2VkTm9kZTsKLSAgICAgICAgcHJvdGVjdGVkIGJvb2xlYW4gX2lzU3RhcnRTZXQgPSBmYWxzZTsKLQotICAgICAgICAvKioKLSAgICAgICAgICogQWR2YW5jZSB0byB0aGUgbmV4dCBub2RlIHJlcHJlc2VudGVkIGJ5IHRoaXMge0BsaW5rIEhlYXBOb2RlfQotICAgICAgICAgKgotICAgICAgICAgKiBAcmV0dXJuIHRoZSBuZXh0IERUTSBub2RlLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIGFic3RyYWN0IGludCBzdGVwKCk7Ci0KLQotICAgICAgICAvKioKLSAgICAgICAgICogQ3JlYXRlcyBhIGRlZXAgY29weSBvZiB0aGlzIHtAbGluayBIZWFwTm9kZX0uICBUaGUgY2xvbmUgaXMgbm90Ci0gICAgICAgICAqIHJlc2V0IGZyb20gdGhlIGN1cnJlbnQgcG9zaXRpb24gb2YgdGhlIG9yaWdpbmFsLgotICAgICAgICAgKgotICAgICAgICAgKiBAcmV0dXJuIHRoZSBjbG9uZWQgaGVhcCBub2RlCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgSGVhcE5vZGUgY2xvbmVIZWFwTm9kZSgpIHsKLSAgICAgICAgICAgIEhlYXBOb2RlIGNsb25lOwotCi0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIGNsb25lID0gKEhlYXBOb2RlKSBzdXBlci5jbG9uZSgpOwotICAgICAgICAgICAgfSBjYXRjaCAoQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgIEJhc2lzTGlicmFyeS5ydW5UaW1lRXJyb3IoQmFzaXNMaWJyYXJ5LklURVJBVE9SX0NMT05FX0VSUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGUudG9TdHJpbmcoKSk7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGNsb25lLl9ub2RlID0gX25vZGU7Ci0gICAgICAgICAgICBjbG9uZS5fbWFya2VkTm9kZSA9IF9ub2RlOwotCi0gICAgICAgICAgICByZXR1cm4gY2xvbmU7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogUmVtZW1iZXJzIHRoZSBjdXJyZW50IG5vZGUgZm9yIHRoZSBuZXh0IGNhbGwgdG8ge0BsaW5rICNnb3RvTWFyaygpfS4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyB2b2lkIHNldE1hcmsoKSB7Ci0gICAgICAgICAgICBfbWFya2VkTm9kZSA9IF9ub2RlOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFJlc3RvcmVzIHRoZSBjdXJyZW50IG5vZGUgcmVtZW1iZXJlZCBieSB7QGxpbmsgI3NldE1hcmsoKX0uCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgdm9pZCBnb3RvTWFyaygpIHsKLSAgICAgICAgICAgIF9ub2RlID0gX21hcmtlZE5vZGU7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogUGVyZm9ybXMgYSBjb21wYXJpc29uIG9mIHRoZSB0d28gaGVhcCBub2RlcwotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gaGVhcE5vZGUgdGhlIGhlYXAgbm9kZSBhZ2FpbnN0IHdoaWNoIHRvIGNvbXBhcmUKLSAgICAgICAgICogQHJldHVybiA8Y29kZT50cnVlPC9jb2RlPiBpZiBhbmQgb25seSBpZiB0aGUgY3VycmVudCBub2RlIGZvciB0aGlzCi0gICAgICAgICAqICAgICAgICAgaGVhcCBub2RlIGlzIGJlZm9yZSB0aGUgY3VycmVudCBub2RlIG9mIHRoZSBhcmd1bWVudCBoZWFwCi0gICAgICAgICAqICAgICAgICAgbm9kZSBpbiBkb2N1bWVudCBvcmRlci4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGlzTGVzc1RoYW4oSGVhcE5vZGUgaGVhcE5vZGUpOwotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBTZXRzIGNvbnRleHQgd2l0aCByZXNwZWN0IHRvIHdoaWNoIHRoaXMgaGVhcCBub2RlIGlzIGV2YWx1YXRlZC4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIG5vZGUgVGhlIG5ldyBjb250ZXh0IG5vZGUKLSAgICAgICAgICogQHJldHVybiBhIHtAbGluayBIZWFwTm9kZX0gd2hpY2ggbWF5IG9yIG1heSBub3QgYmUgdGhlIHNhbWUgYXMKLSAgICAgICAgICogICAgICAgICB0aGlzIDxjb2RlPkhlYXBOb2RlPC9jb2RlPi4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBhYnN0cmFjdCBIZWFwTm9kZSBzZXRTdGFydE5vZGUoaW50IG5vZGUpOwotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBSZXNldCB0aGUgaGVhcCBub2RlIGJhY2sgdG8gaXRzIGJlZ2lubmluZy4KLSAgICAgICAgICoKLSAgICAgICAgICogQHJldHVybiBhIHtAbGluayBIZWFwTm9kZX0gd2hpY2ggbWF5IG9yIG1heSBub3QgYmUgdGhlIHNhbWUgYXMKLSAgICAgICAgICogICAgICAgICB0aGlzIDxjb2RlPkhlYXBOb2RlPC9jb2RlPi4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBhYnN0cmFjdCBIZWFwTm9kZSByZXNldCgpOwotICAgIH0gLy8gZW5kIG9mIEhlYXBOb2RlCi0KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgSW5pdFNpemUgPSA4OwotCi0gICAgcHJpdmF0ZSBpbnQgICAgICAgIF9oZWFwU2l6ZSA9IDA7Ci0gICAgcHJpdmF0ZSBpbnQgICAgICAgIF9zaXplID0gSW5pdFNpemU7Ci0gICAgcHJpdmF0ZSBIZWFwTm9kZVtdIF9oZWFwID0gbmV3IEhlYXBOb2RlW0luaXRTaXplXTsKLSAgICBwcml2YXRlIGludCAgICAgICAgX2ZyZWUgPSAwOwotCi0gICAgLy8gTGFzdCBub2RlIHJldHVybmVkIGJ5IHRoaXMgTXVsdGlWYWx1ZWROb2RlSGVhcEl0ZXJhdG9yIHRvIHRoZSBjYWxsZXIgb2YKLSAgICAvLyBuZXh0OyB1c2VkIHRvIHBydW5lIGR1cGxpY2F0ZXMKLSAgICBwcml2YXRlIGludCBfcmV0dXJuZWRMYXN0OwotCi0gICAgLy8gY2FjaGVkIHJldHVybmVkIGxhc3QgZm9yIHVzZSBpbiBnb3RvTWFyawotICAgIHByaXZhdGUgaW50IF9jYWNoZWRSZXR1cm5lZExhc3QgPSBFTkQ7Ci0KLSAgICAvLyBjYWNoZWQgaGVhcCBzaXplIGZvciB1c2UgaW4gZ290b01hcmsKLSAgICBwcml2YXRlIGludCBfY2FjaGVkSGVhcFNpemU7Ci0KLQotICAgIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3IgY2xvbmVJdGVyYXRvcigpIHsKLSAgICAgICAgX2lzUmVzdGFydGFibGUgPSBmYWxzZTsKLSAgICAgICAgZmluYWwgSGVhcE5vZGVbXSBoZWFwQ29weSA9IG5ldyBIZWFwTm9kZVtfaGVhcC5sZW5ndGhdOwotICAgICAgICB0cnkgewotICAgICAgICAgICAgTXVsdGlWYWx1ZWROb2RlSGVhcEl0ZXJhdG9yIGNsb25lID0KLSAgICAgICAgICAgICAgICAgICAgKE11bHRpVmFsdWVkTm9kZUhlYXBJdGVyYXRvcilzdXBlci5jbG9uZSgpOwotCi0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IF9mcmVlOyBpKyspIHsKLSAgICAgICAgICAgICAgICBoZWFwQ29weVtpXSA9IF9oZWFwW2ldLmNsb25lSGVhcE5vZGUoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNsb25lLnNldFJlc3RhcnRhYmxlKGZhbHNlKTsKLSAgICAgICAgICAgIGNsb25lLl9oZWFwID0gaGVhcENvcHk7Ci0gICAgICAgICAgICByZXR1cm4gY2xvbmUucmVzZXQoKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgQmFzaXNMaWJyYXJ5LnJ1blRpbWVFcnJvcihCYXNpc0xpYnJhcnkuSVRFUkFUT1JfQ0xPTkVfRVJSLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlLnRvU3RyaW5nKCkpOwotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwcm90ZWN0ZWQgdm9pZCBhZGRIZWFwTm9kZShIZWFwTm9kZSBub2RlKSB7Ci0gICAgICAgIGlmIChfZnJlZSA9PSBfc2l6ZSkgewotICAgICAgICAgICAgSGVhcE5vZGVbXSBuZXdBcnJheSA9IG5ldyBIZWFwTm9kZVtfc2l6ZSAqPSAyXTsKLSAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoX2hlYXAsIDAsIG5ld0FycmF5LCAwLCBfZnJlZSk7Ci0gICAgICAgICAgICBfaGVhcCA9IG5ld0FycmF5OwotICAgICAgICB9Ci0gICAgICAgIF9oZWFwU2l6ZSsrOwotICAgICAgICBfaGVhcFtfZnJlZSsrXSA9IG5vZGU7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBuZXh0KCkgewotICAgICAgICB3aGlsZSAoX2hlYXBTaXplID4gMCkgewotICAgICAgICAgICAgZmluYWwgaW50IHNtYWxsZXN0ID0gX2hlYXBbMF0uX25vZGU7Ci0gICAgICAgICAgICBpZiAoc21hbGxlc3QgPT0gRU5EKSB7IC8vIGl0ZXJhdG9yIF9oZWFwWzBdIGlzIGRvbmUKLSAgICAgICAgICAgICAgICBpZiAoX2hlYXBTaXplID4gMSkgewotICAgICAgICAgICAgICAgICAgICAvLyBTd2FwIGZpcnN0IGFuZCBsYXN0IChpdGVyYXRvciBtdXN0IGJlIHJlc3RhcnRhYmxlKQotICAgICAgICAgICAgICAgICAgICBmaW5hbCBIZWFwTm9kZSB0ZW1wID0gX2hlYXBbMF07Ci0gICAgICAgICAgICAgICAgICAgIF9oZWFwWzBdID0gX2hlYXBbLS1faGVhcFNpemVdOwotICAgICAgICAgICAgICAgICAgICBfaGVhcFtfaGVhcFNpemVdID0gdGVtcDsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBFTkQ7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoc21hbGxlc3QgPT0gX3JldHVybmVkTGFzdCkgeyAgICAgICAvLyBkdXBsaWNhdGUKLSAgICAgICAgICAgICAgICBfaGVhcFswXS5zdGVwKCk7IC8vIHZhbHVlIGNvbnN1bWVkCi0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBfaGVhcFswXS5zdGVwKCk7IC8vIHZhbHVlIGNvbnN1bWVkCi0gICAgICAgICAgICAgICAgaGVhcGlmeSgwKTsKLSAgICAgICAgICAgICAgICByZXR1cm4gcmV0dXJuTm9kZShfcmV0dXJuZWRMYXN0ID0gc21hbGxlc3QpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gZmFsbHRocm91Z2ggaWYgbm90IHJldHVybmVkIGFib3ZlCi0gICAgICAgICAgICBoZWFwaWZ5KDApOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBFTkQ7Ci0gICAgfQotCi0gICAgcHVibGljIERUTUF4aXNJdGVyYXRvciBzZXRTdGFydE5vZGUoaW50IG5vZGUpIHsKLSAgICAgICAgaWYgKF9pc1Jlc3RhcnRhYmxlKSB7Ci0gICAgICAgICAgICBfc3RhcnROb2RlID0gbm9kZTsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgX2ZyZWU7IGkrKykgewotICAgICAgICAgICAgICAgIGlmKCFfaGVhcFtpXS5faXNTdGFydFNldCl7Ci0gICAgICAgICAgICAgICAgICAgX2hlYXBbaV0uc2V0U3RhcnROb2RlKG5vZGUpOwotICAgICAgICAgICAgICAgICAgIF9oZWFwW2ldLnN0ZXAoKTsgICAgIC8vIHRvIGdldCB0aGUgZmlyc3Qgbm9kZQotICAgICAgICAgICAgICAgICAgIF9oZWFwW2ldLl9pc1N0YXJ0U2V0ID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyBidWlsZCBoZWFwCi0gICAgICAgICAgICBmb3IgKGludCBpID0gKF9oZWFwU2l6ZSA9IF9mcmVlKS8yOyBpID49IDA7IGktLSkgewotICAgICAgICAgICAgICAgIGhlYXBpZnkoaSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBfcmV0dXJuZWRMYXN0ID0gRU5EOwotICAgICAgICAgICAgcmV0dXJuIHJlc2V0UG9zaXRpb24oKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gdGhpczsKLSAgICB9Ci0KLSAgICBwcm90ZWN0ZWQgdm9pZCBpbml0KCkgewotICAgICAgICBmb3IgKGludCBpID0wOyBpIDwgX2ZyZWU7IGkrKykgewotICAgICAgICAgICAgX2hlYXBbaV0gPSBudWxsOwotICAgICAgICB9Ci0KLSAgICAgICAgX2hlYXBTaXplID0gMDsKLSAgICAgICAgX2ZyZWUgPSAwOwotICAgIH0KLQotICAgIC8qIEJ1aWxkIGEgaGVhcCBpbiBkb2N1bWVudCBvcmRlci4gcHV0IHRoZSBzbWFsbGVzdCBub2RlIG9uIHRoZSB0b3AuCi0gICAgICogInNtYWxsZXN0IG5vZGUiIG1lYW5zIHRoZSBub2RlIGJlZm9yZSBvdGhlciBub2RlcyBpbiBkb2N1bWVudCBvcmRlcgotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCBoZWFwaWZ5KGludCBpKSB7Ci0gICAgICAgIGZvciAoaW50IHIsIGwsIHNtYWxsZXN0OzspIHsKLSAgICAgICAgICAgIHIgPSAoaSArIDEpIDw8IDE7IGwgPSByIC0gMTsKLSAgICAgICAgICAgIHNtYWxsZXN0ID0gbCA8IF9oZWFwU2l6ZQotICAgICAgICAgICAgICAgICYmIF9oZWFwW2xdLmlzTGVzc1RoYW4oX2hlYXBbaV0pID8gbCA6IGk7Ci0gICAgICAgICAgICBpZiAociA8IF9oZWFwU2l6ZSAmJiBfaGVhcFtyXS5pc0xlc3NUaGFuKF9oZWFwW3NtYWxsZXN0XSkpIHsKLSAgICAgICAgICAgICAgICBzbWFsbGVzdCA9IHI7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoc21hbGxlc3QgIT0gaSkgewotICAgICAgICAgICAgICAgIGZpbmFsIEhlYXBOb2RlIHRlbXAgPSBfaGVhcFtzbWFsbGVzdF07Ci0gICAgICAgICAgICAgICAgX2hlYXBbc21hbGxlc3RdID0gX2hlYXBbaV07Ci0gICAgICAgICAgICAgICAgX2hlYXBbaV0gPSB0ZW1wOwotICAgICAgICAgICAgICAgIGkgPSBzbWFsbGVzdDsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRNYXJrKCkgewotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IF9mcmVlOyBpKyspIHsKLSAgICAgICAgICAgIF9oZWFwW2ldLnNldE1hcmsoKTsKLSAgICAgICAgfQotICAgICAgICBfY2FjaGVkUmV0dXJuZWRMYXN0ID0gX3JldHVybmVkTGFzdDsKLSAgICAgICAgX2NhY2hlZEhlYXBTaXplID0gX2hlYXBTaXplOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGdvdG9NYXJrKCkgewotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IF9mcmVlOyBpKyspIHsKLSAgICAgICAgICAgIF9oZWFwW2ldLmdvdG9NYXJrKCk7Ci0gICAgICAgIH0KLSAgICAgICAgLy8gcmVidWlsZCBoZWFwIGFmdGVyIGNhbGwgbGFzdCgpIGZ1bmN0aW9uLiBmaXggZm9yIGJ1ZyAyMDkxMwotICAgICAgICBmb3IgKGludCBpID0gKF9oZWFwU2l6ZSA9IF9jYWNoZWRIZWFwU2l6ZSkvMjsgaSA+PSAwOyBpLS0pIHsKLSAgICAgICAgICAgIGhlYXBpZnkoaSk7Ci0gICAgICAgIH0KLSAgICAgICAgX3JldHVybmVkTGFzdCA9IF9jYWNoZWRSZXR1cm5lZExhc3Q7Ci0gICAgfQotCi0gICAgcHVibGljIERUTUF4aXNJdGVyYXRvciByZXNldCgpIHsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBfZnJlZTsgaSsrKSB7Ci0gICAgICAgICAgICBfaGVhcFtpXS5yZXNldCgpOwotICAgICAgICAgICAgX2hlYXBbaV0uc3RlcCgpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gYnVpbGQgaGVhcAotICAgICAgICBmb3IgKGludCBpID0gKF9oZWFwU2l6ZSA9IF9mcmVlKS8yOyBpID49IDA7IGktLSkgewotICAgICAgICAgICAgaGVhcGlmeShpKTsKLSAgICAgICAgfQotCi0gICAgICAgIF9yZXR1cm5lZExhc3QgPSBFTkQ7Ci0gICAgICAgIHJldHVybiByZXNldFBvc2l0aW9uKCk7Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2RvbS9NdWx0aXBsZU5vZGVDb3VudGVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2RvbS9NdWx0aXBsZU5vZGVDb3VudGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDQ0ZmY2MmMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vTXVsdGlwbGVOb2RlQ291bnRlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTIwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IE11bHRpcGxlTm9kZUNvdW50ZXIuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xMiAxMTo0OTo1NiBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuZG9tOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLkRPTTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuVHJhbnNsZXQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnV0aWwuSW50ZWdlckFycmF5OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTUF4aXNJdGVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5BeGlzOwotCi0vKioKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqLwotcHVibGljIGFic3RyYWN0IGNsYXNzIE11bHRpcGxlTm9kZUNvdW50ZXIgZXh0ZW5kcyBOb2RlQ291bnRlciB7Ci0gICAgcHJpdmF0ZSBEVE1BeGlzSXRlcmF0b3IgX3ByZWNTaWJsaW5ncyA9IG51bGw7Ci0KLSAgICBwdWJsaWMgTXVsdGlwbGVOb2RlQ291bnRlcihUcmFuc2xldCB0cmFuc2xldCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBET00gZG9jdW1lbnQsIERUTUF4aXNJdGVyYXRvciBpdGVyYXRvcikgewotICAgICAgICBzdXBlcih0cmFuc2xldCwgZG9jdW1lbnQsIGl0ZXJhdG9yKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgTXVsdGlwbGVOb2RlQ291bnRlcihUcmFuc2xldCB0cmFuc2xldCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBET00gZG9jdW1lbnQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFRNQXhpc0l0ZXJhdG9yIGl0ZXJhdG9yLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gaGFzRnJvbSkgewotICAgICAgICBzdXBlcih0cmFuc2xldCwgZG9jdW1lbnQsIGl0ZXJhdG9yLCBoYXNGcm9tKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgTm9kZUNvdW50ZXIgc2V0U3RhcnROb2RlKGludCBub2RlKSB7Ci0gICAgICAgIF9ub2RlID0gbm9kZTsKLSAgICAgICAgX25vZGVUeXBlID0gX2RvY3VtZW50LmdldEV4cGFuZGVkVHlwZUlEKG5vZGUpOwotICAgIF9wcmVjU2libGluZ3MgPSBfZG9jdW1lbnQuZ2V0QXhpc0l0ZXJhdG9yKEF4aXMuUFJFQ0VESU5HU0lCTElORyk7Ci0gICAgICAgIHJldHVybiB0aGlzOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q291bnRlcigpIHsKLSAgICAgICAgaWYgKF92YWx1ZSAhPSBJbnRlZ2VyLk1JTl9WQUxVRSkgewotICAgICAgICAgICAgLy9TZWUgRXJyYXRhIEUyNAotICAgICAgICAgICAgaWYgKF92YWx1ZSA9PSAwKSByZXR1cm4gIjAiOwotICAgICAgICAgICAgZWxzZSBpZiAoRG91YmxlLmlzTmFOKF92YWx1ZSkpIHJldHVybiAiTmFOIjsKLSAgICAgICAgICAgIGVsc2UgaWYgKF92YWx1ZSA8IDAgJiYgRG91YmxlLmlzSW5maW5pdGUoX3ZhbHVlKSkgcmV0dXJuICItSW5maW5pdHkiOwotICAgICAgICAgICAgZWxzZSBpZiAoRG91YmxlLmlzSW5maW5pdGUoX3ZhbHVlKSkgcmV0dXJuICJJbmZpbml0eSI7Ci0gICAgICAgICAgICBlbHNlIHJldHVybiBmb3JtYXROdW1iZXJzKChpbnQpX3ZhbHVlKTsKLSAgICAgICAgfQotCi0gICAgICAgIEludGVnZXJBcnJheSBhbmNlc3RvcnMgPSBuZXcgSW50ZWdlckFycmF5KCk7Ci0KLSAgICAgICAgLy8gR2F0aGVyIGFsbCBhbmNlc3RvcnMgdGhhdCBkbyBub3QgbWF0Y2ggZnJvbSBwYXR0ZXJuCi0gICAgICAgIGludCBuZXh0ID0gX25vZGU7Ci0gICAgICAgIGFuY2VzdG9ycy5hZGQobmV4dCk7ICAgICAgICAgICAgLy8gaW5jbHVkZSBzZWxmCi0gICAgICAgIHdoaWxlICgobmV4dCA9IF9kb2N1bWVudC5nZXRQYXJlbnQobmV4dCkpID4gRU5EICYmCi0gICAgICAgICAgICAgICAhbWF0Y2hlc0Zyb20obmV4dCkpIHsKLSAgICAgICAgICAgIGFuY2VzdG9ycy5hZGQobmV4dCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBDcmVhdGUgYW4gYXJyYXkgb2YgY291bnRlcnMKLSAgICAgICAgZmluYWwgaW50IG5BbmNlc3RvcnMgPSBhbmNlc3RvcnMuY2FyZGluYWxpdHkoKTsKLSAgICAgICAgZmluYWwgaW50W10gY291bnRlcnMgPSBuZXcgaW50W25BbmNlc3RvcnNdOwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG5BbmNlc3RvcnM7IGkrKykgewotICAgICAgICAgICAgY291bnRlcnNbaV0gPSBJbnRlZ2VyLk1JTl9WQUxVRTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIEluY3JlbWVudCBhcnJheSBvZiBjb3VudGVycyBhY2NvcmRpbmcgdG8gc2VtYW50aWNzCi0gICAgICAgIGZvciAoaW50IGogPSAwLCBpID0gbkFuY2VzdG9ycyAtIDE7IGkgPj0gMCA7IGktLSwgaisrKSB7Ci0gICAgICAgICAgICBmaW5hbCBpbnQgY291bnRlciA9IGNvdW50ZXJzW2pdOwotICAgICAgICAgICAgZmluYWwgaW50IGFuY2VzdG9yID0gYW5jZXN0b3JzLmF0KGkpOwotCi0gICAgICAgICAgICBpZiAobWF0Y2hlc0NvdW50KGFuY2VzdG9yKSkgewotICAgICAgICAgICAgICAgIF9wcmVjU2libGluZ3Muc2V0U3RhcnROb2RlKGFuY2VzdG9yKTsKLSAgICAgICAgICAgICAgICB3aGlsZSAoKG5leHQgPSBfcHJlY1NpYmxpbmdzLm5leHQoKSkgIT0gRU5EKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChtYXRjaGVzQ291bnQobmV4dCkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50ZXJzW2pdID0gKGNvdW50ZXJzW2pdID09IEludGVnZXIuTUlOX1ZBTFVFKSA/IDEKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IGNvdW50ZXJzW2pdICsgMTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvLyBDb3VudCB0aGUgbm9kZSBpdHNlbGYKLSAgICAgICAgICAgICAgICBjb3VudGVyc1tqXSA9IGNvdW50ZXJzW2pdID09IEludGVnZXIuTUlOX1ZBTFVFCi0gICAgICAgICAgICAgICAgICAgID8gMQotICAgICAgICAgICAgICAgICAgICA6IGNvdW50ZXJzW2pdICsgMTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZm9ybWF0TnVtYmVycyhjb3VudGVycyk7Ci0gICAgfQotCi0gICAgcHVibGljIHN0YXRpYyBOb2RlQ291bnRlciBnZXREZWZhdWx0Tm9kZUNvdW50ZXIoVHJhbnNsZXQgdHJhbnNsZXQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRE9NIGRvY3VtZW50LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERUTUF4aXNJdGVyYXRvciBpdGVyYXRvcikgewotICAgICAgICByZXR1cm4gbmV3IERlZmF1bHRNdWx0aXBsZU5vZGVDb3VudGVyKHRyYW5zbGV0LCBkb2N1bWVudCwgaXRlcmF0b3IpOwotICAgIH0KLQotICAgIHN0YXRpYyBjbGFzcyBEZWZhdWx0TXVsdGlwbGVOb2RlQ291bnRlciBleHRlbmRzIE11bHRpcGxlTm9kZUNvdW50ZXIgewotICAgICAgICBwdWJsaWMgRGVmYXVsdE11bHRpcGxlTm9kZUNvdW50ZXIoVHJhbnNsZXQgdHJhbnNsZXQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBET00gZG9jdW1lbnQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEVE1BeGlzSXRlcmF0b3IgaXRlcmF0b3IpIHsKLSAgICAgICAgICAgIHN1cGVyKHRyYW5zbGV0LCBkb2N1bWVudCwgaXRlcmF0b3IpOwotICAgICAgICB9Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vTm9kZUNvdW50ZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvZG9tL05vZGVDb3VudGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGNhZDAyZjUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vTm9kZUNvdW50ZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQxNiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBOb2RlQ291bnRlci5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzEyIDExOjUyOjM2IHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5kb207Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLkRPTTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuVHJhbnNsZXQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTUF4aXNJdGVyYXRvcjsKLQotLyoqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqLwotcHVibGljIGFic3RyYWN0IGNsYXNzIE5vZGVDb3VudGVyIHsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTkQgPSBEVE0uTlVMTDsKLQotICAgIHByb3RlY3RlZCBpbnQgX25vZGUgPSBFTkQ7Ci0gICAgcHJvdGVjdGVkIGludCBfbm9kZVR5cGUgPSBET00uRklSU1RfVFlQRSAtIDE7Ci0gICAgcHJvdGVjdGVkIGRvdWJsZSBfdmFsdWUgPSBJbnRlZ2VyLk1JTl9WQUxVRTsKLQotICAgIHB1YmxpYyBmaW5hbCBET00gICAgICAgICAgX2RvY3VtZW50OwotICAgIHB1YmxpYyBmaW5hbCBEVE1BeGlzSXRlcmF0b3IgX2l0ZXJhdG9yOwotICAgIHB1YmxpYyBmaW5hbCBUcmFuc2xldCAgICAgX3RyYW5zbGV0OwotCi0gICAgcHJvdGVjdGVkIFN0cmluZyBfZm9ybWF0OwotICAgIHByb3RlY3RlZCBTdHJpbmcgX2xhbmc7Ci0gICAgcHJvdGVjdGVkIFN0cmluZyBfbGV0dGVyVmFsdWU7Ci0gICAgcHJvdGVjdGVkIFN0cmluZyBfZ3JvdXBTZXA7Ci0gICAgcHJvdGVjdGVkIGludCAgICBfZ3JvdXBTaXplOwotCi0gICAgcHJpdmF0ZSBib29sZWFuIF9zZXBhckZpcnN0ID0gdHJ1ZTsKLSAgICBwcml2YXRlIGJvb2xlYW4gX3NlcGFyTGFzdCA9IGZhbHNlOwotICAgIHByaXZhdGUgVmVjdG9yIF9zZXBhclRva3MgPSBuZXcgVmVjdG9yKCk7Ci0gICAgcHJpdmF0ZSBWZWN0b3IgX2Zvcm1hdFRva3MgPSBuZXcgVmVjdG9yKCk7Ci0gICAgcHJpdmF0ZSBpbnQgX25TZXBhcnMgID0gMDsKLSAgICBwcml2YXRlIGludCBfbkZvcm1hdHMgPSAwOwotCi0gICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgU3RyaW5nW10gVGhvdXNhbmRzID0KLSAgICAgICAgeyIiLCAibSIsICJtbSIsICJtbW0iIH07Ci0gICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgU3RyaW5nW10gSHVuZHJlZHMgPQotICAgIHsiIiwgImMiLCAiY2MiLCAiY2NjIiwgImNkIiwgImQiLCAiZGMiLCAiZGNjIiwgImRjY2MiLCAiY20ifTsKLSAgICBwcml2YXRlIGZpbmFsIHN0YXRpYyBTdHJpbmdbXSBUZW5zID0KLSAgICB7IiIsICJ4IiwgInh4IiwgInh4eCIsICJ4bCIsICJsIiwgImx4IiwgImx4eCIsICJseHh4IiwgInhjIn07Ci0gICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgU3RyaW5nW10gT25lcyA9Ci0gICAgeyIiLCAiaSIsICJpaSIsICJpaWkiLCAiaXYiLCAidiIsICJ2aSIsICJ2aWkiLCAidmlpaSIsICJpeCJ9OwotCi0gICAgcHJpdmF0ZSBTdHJpbmdCdWlsZGVyIF90ZW1wQnVmZmVyID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKLQotICAgIC8qKgotICAgICAqIEluZGljYXRlcyBpZiB0aGlzIGluc3RhbmNlIG9mIHhzbDpudW1iZXIgaGFzIGEgZnJvbSBwYXR0ZXJuLgotICAgICAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIF9oYXNGcm9tOwotCi0gICAgcHJvdGVjdGVkIE5vZGVDb3VudGVyKFRyYW5zbGV0IHRyYW5zbGV0LAotICAgICAgICAgICAgICBET00gZG9jdW1lbnQsIERUTUF4aXNJdGVyYXRvciBpdGVyYXRvcikgewotICAgIF90cmFuc2xldCA9IHRyYW5zbGV0OwotICAgIF9kb2N1bWVudCA9IGRvY3VtZW50OwotICAgIF9pdGVyYXRvciA9IGl0ZXJhdG9yOwotICAgIH0KLQotICAgIHByb3RlY3RlZCBOb2RlQ291bnRlcihUcmFuc2xldCB0cmFuc2xldCwKLSAgICAgICAgICAgICAgRE9NIGRvY3VtZW50LCBEVE1BeGlzSXRlcmF0b3IgaXRlcmF0b3IsIGJvb2xlYW4gaGFzRnJvbSkgewotICAgICAgICBfdHJhbnNsZXQgPSB0cmFuc2xldDsKLSAgICAgICAgX2RvY3VtZW50ID0gZG9jdW1lbnQ7Ci0gICAgICAgIF9pdGVyYXRvciA9IGl0ZXJhdG9yOwotICAgICAgICBfaGFzRnJvbSA9IGhhc0Zyb207Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSBzdGFydCBub2RlIGZvciB0aGlzIGNvdW50ZXIuIFRoZSBzYW1lIDx0dD5Ob2RlQ291bnRlcjwvdHQ+Ci0gICAgICogb2JqZWN0IGNhbiBiZSB1c2VkIG11bHRpcGxlIHRpbWVzIGJ5IHJlc2V0dGluZyB0aGUgc3RhcnRpbmcgbm9kZS4KLSAgICAgKi8KLSAgICBhYnN0cmFjdCBwdWJsaWMgTm9kZUNvdW50ZXIgc2V0U3RhcnROb2RlKGludCBub2RlKTsKLQotICAgIC8qKgotICAgICAqIElmIHRoZSB1c2VyIHNwZWNpZmllZCBhIHZhbHVlIGF0dHJpYnV0ZSwgdXNlIHRoaXMgaW5zdGVhZCBvZgotICAgICAqIGNvdW50aW5nIG5vZGVzLgotICAgICAqLwotICAgIHB1YmxpYyBOb2RlQ291bnRlciBzZXRWYWx1ZShkb3VibGUgdmFsdWUpIHsKLSAgICBfdmFsdWUgPSB2YWx1ZTsKLSAgICByZXR1cm4gdGhpczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXRzIGZvcm1hdHRpbmcgZmllbGRzIGJlZm9yZSBjYWxsaW5nIGZvcm1hdE51bWJlcnMoKS4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCBzZXRGb3JtYXR0aW5nKFN0cmluZyBmb3JtYXQsIFN0cmluZyBsYW5nLCBTdHJpbmcgbGV0dGVyVmFsdWUsCi0gICAgICAgICAgICAgICAgIFN0cmluZyBncm91cFNlcCwgU3RyaW5nIGdyb3VwU2l6ZSkgewotICAgIF9sYW5nID0gbGFuZzsKLSAgICBfZ3JvdXBTZXAgPSBncm91cFNlcDsKLSAgICBfbGV0dGVyVmFsdWUgPSBsZXR0ZXJWYWx1ZTsKLSAgICBfZ3JvdXBTaXplID0gcGFyc2VTdHJpbmdUb0FuSW50KGdyb3VwU2l6ZSk7Ci0gICAgc2V0VG9rZW5zKGZvcm1hdCk7Ci0KLSB9Ci0KLSAgICAvKioKLSAgICAgKiBFZmZlY3RpdmVseSBkb2VzIHRoZSBzYW1lIHRoaW5nIGFzIEludGVnZXIucGFyc2VJbnQoU3RyaW5nIHMpIGV4Y2VwdAotICAgICAqIGluc3RlYWQgb2YgdGhyb3dpbmcgYSBOdW1iZXJGb3JtYXRFeGNlcHRpb24sIGl0IHJldHVybnMgMC4gIFRoaXMgbWV0aG9kCi0gICAgICogaXMgdXNlZCBpbnN0ZWFkIG9mIEludGVnZXIucGFyc2VJbnQoKSBzaW5jZSBpdCBkb2VzIG5vdCBpbmN1ciB0aGUKLSAgICAgKiBvdmVyaGVhZCBvZiB0aHJvd2luZyBhbiBFeGNlcHRpb24gd2hpY2ggaXMgZXhwZW5zaXZlLgotICAgICAqCi0gICAgICogQHBhcmFtIHMgIEEgU3RyaW5nIHRvIGJlIHBhcnNlZCBpbnRvIGFuIGludC4KLSAgICAgKiBAcmV0dXJuICBFaXRoZXIgYW4gaW50IHJlcHJlc2VudGVkIGJ5IHRoZSBpbmNvbWluZyBTdHJpbmcgcywgb3IgMCBpZgotICAgICAqICAgICAgICAgIHRoZSBwYXJzaW5nIGlzIG5vdCBzdWNjZXNzZnVsLgotICAgICAqLwotICAgIHByaXZhdGUgaW50IHBhcnNlU3RyaW5nVG9BbkludChTdHJpbmcgcykgewotICAgICAgICBpZiAocyA9PSBudWxsKQotICAgICAgICAgICAgcmV0dXJuIDA7Ci0KLSAgICAgICAgaW50IHJlc3VsdCA9IDA7Ci0gICAgICAgIGJvb2xlYW4gbmVnYXRpdmUgPSBmYWxzZTsKLSAgICAgICAgaW50IHJhZGl4ID0gMTAsIGkgPSAwLCBtYXggPSBzLmxlbmd0aCgpOwotICAgICAgICBpbnQgbGltaXQsIG11bHRtaW4sIGRpZ2l0OwotCi0gICAgICAgIGlmIChtYXggPiAwKSB7Ci0gICAgICAgICAgICBpZiAocy5jaGFyQXQoMCkgPT0gJy0nKSB7Ci0gICAgICAgICAgICAgICAgbmVnYXRpdmUgPSB0cnVlOwotICAgICAgICAgICAgICAgIGxpbWl0ID0gSW50ZWdlci5NSU5fVkFMVUU7Ci0gICAgICAgICAgICAgICAgaSsrOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBsaW1pdCA9IC1JbnRlZ2VyLk1BWF9WQUxVRTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIG11bHRtaW4gPSBsaW1pdCAvIHJhZGl4OwotICAgICAgICAgICAgaWYgKGkgPCBtYXgpIHsKLSAgICAgICAgICAgICAgICBkaWdpdCA9IENoYXJhY3Rlci5kaWdpdChzLmNoYXJBdChpKyspLCByYWRpeCk7Ci0gICAgICAgICAgICAgICAgaWYgKGRpZ2l0IDwgMCkKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDA7Ci0gICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSAtZGlnaXQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICB3aGlsZSAoaSA8IG1heCkgewotICAgICAgICAgICAgICAgIC8vIEFjY3VtdWxhdGluZyBuZWdhdGl2ZWx5IGF2b2lkcyBzdXJwcmlzZXMgbmVhciBNQVhfVkFMVUUKLSAgICAgICAgICAgICAgICBkaWdpdCA9IENoYXJhY3Rlci5kaWdpdChzLmNoYXJBdChpKyspLCByYWRpeCk7Ci0gICAgICAgICAgICAgICAgaWYgKGRpZ2l0IDwgMCkKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDA7Ci0gICAgICAgICAgICAgICAgaWYgKHJlc3VsdCA8IG11bHRtaW4pCi0gICAgICAgICAgICAgICAgICAgIHJldHVybiAwOwotICAgICAgICAgICAgICAgIHJlc3VsdCAqPSByYWRpeDsKLSAgICAgICAgICAgICAgICBpZiAocmVzdWx0IDwgbGltaXQgKyBkaWdpdCkKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDA7Ci0gICAgICAgICAgICAgICAgcmVzdWx0IC09IGRpZ2l0OwotICAgICAgICAgICAgfQotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIDA7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKG5lZ2F0aXZlKSB7Ci0gICAgICAgICAgICBpZiAoaSA+IDEpCi0gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKLSAgICAgICAgICAgIGVsc2UgLyogT25seSBnb3QgIi0iICovCi0gICAgICAgICAgICAgICAgcmV0dXJuIDA7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gLXJlc3VsdDsKLSAgICAgICAgfQotICAgIH0KLQotICAvLyBmb3JtYXQgPT0gbnVsbCBhc3N1bWVkIGhlcmUKLSBwcml2YXRlIGZpbmFsIHZvaWQgc2V0VG9rZW5zKGZpbmFsIFN0cmluZyBmb3JtYXQpewotICAgICBpZiggKF9mb3JtYXQhPW51bGwpICYmKGZvcm1hdC5lcXVhbHMoX2Zvcm1hdCkpICl7Ly8gaGFzIGFscmVhZHkgYmVlbiBzZXQKLSAgICAgICAgcmV0dXJuOwotICAgICB9Ci0gICAgIF9mb3JtYXQgPSBmb3JtYXQ7Ci0gICAgIC8vIHJlc2V0Ci0gICAgIGZpbmFsIGludCBsZW5ndGggPSBfZm9ybWF0Lmxlbmd0aCgpOwotICAgICBib29sZWFuIGlzRmlyc3QgPSB0cnVlOwotICAgICBfc2VwYXJGaXJzdCA9IHRydWU7Ci0gICAgIF9zZXBhckxhc3QgPSBmYWxzZTsKLSAgICAgX25TZXBhcnMgID0gMDsKLSAgICAgX25Gb3JtYXRzID0gMDsKLSAgICAgX3NlcGFyVG9rcy5jbGVhcigpIDsKLSAgICAgX2Zvcm1hdFRva3MuY2xlYXIoKTsKLQotICAgICAgICAgLyoKLSAgICAgICAgICAqIFRva2VuaXplIHRoZSBmb3JtYXQgc3RyaW5nIGludG8gYWxwaGFudW1lcmljIGFuZCBub24tYWxwaGFudW1lcmljCi0gICAgICAgICAgKiB0b2tlbnMgYXMgZGVzY3JpYmVkIGluIE0uIEtheSBwYWdlIDI0MS4KLSAgICAgICAgICAqLwotICAgICAgICAgZm9yIChpbnQgaiA9IDAsIGkgPSAwOyBpIDwgbGVuZ3RoOykgewotICAgICAgICAgICAgICAgICBjaGFyIGMgPSBmb3JtYXQuY2hhckF0KGkpOwotICAgICAgICAgICAgICAgICBmb3IgKGogPSBpOyBDaGFyYWN0ZXIuaXNMZXR0ZXJPckRpZ2l0KGMpOykgewotICAgICAgICAgICAgICAgICAgICAgaWYgKCsraSA9PSBsZW5ndGgpIGJyZWFrOwotICAgICAgICAgICAgIGMgPSBmb3JtYXQuY2hhckF0KGkpOwotICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgIGlmIChpID4gaikgewotICAgICAgICAgICAgICAgICAgICAgaWYgKGlzRmlyc3QpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICBfc2VwYXJUb2tzLmFkZEVsZW1lbnQoIi4iKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICBpc0ZpcnN0ID0gX3NlcGFyRmlyc3QgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgIF9mb3JtYXRUb2tzLmFkZEVsZW1lbnQoZm9ybWF0LnN1YnN0cmluZyhqLCBpKSk7Ci0gICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICBpZiAoaSA9PSBsZW5ndGgpIGJyZWFrOwotCi0gICAgICAgICAgICAgICAgIGMgPSBmb3JtYXQuY2hhckF0KGkpOwotICAgICAgICAgICAgICAgICBmb3IgKGogPSBpOyAhQ2hhcmFjdGVyLmlzTGV0dGVyT3JEaWdpdChjKTspIHsKLSAgICAgICAgICAgICAgICAgICAgIGlmICgrK2kgPT0gbGVuZ3RoKSBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgIGMgPSBmb3JtYXQuY2hhckF0KGkpOwotICAgICAgICAgICAgICAgICAgICAgaXNGaXJzdCA9IGZhbHNlOwotICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgIGlmIChpID4gaikgewotICAgICAgICAgICAgICAgICAgICAgX3NlcGFyVG9rcy5hZGRFbGVtZW50KGZvcm1hdC5zdWJzdHJpbmcoaiwgaSkpOwotICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgfQotCi0gICAgICAgICBfblNlcGFycyA9IF9zZXBhclRva3Muc2l6ZSgpOwotICAgICAgICAgX25Gb3JtYXRzID0gX2Zvcm1hdFRva3Muc2l6ZSgpOwotICAgICAgICAgaWYgKF9uU2VwYXJzID4gX25Gb3JtYXRzKSBfc2VwYXJMYXN0ID0gdHJ1ZTsKLQotICAgICAgICAgaWYgKF9zZXBhckZpcnN0KSBfblNlcGFycy0tOwotICAgICAgICAgaWYgKF9zZXBhckxhc3QpIF9uU2VwYXJzLS07Ci0gICAgICAgICBpZiAoX25TZXBhcnMgPT0gMCkgewotICAgICAgICAgICAgIF9zZXBhclRva3MuaW5zZXJ0RWxlbWVudEF0KCIuIiwgMSk7Ci0gICAgICAgICAgICAgX25TZXBhcnMrKzsKLSAgICAgICAgIH0KLSAgICAgICAgIGlmIChfc2VwYXJGaXJzdCkgX25TZXBhcnMgKys7Ci0KLSB9Ci0gICAgLyoqCi0gICAgICogU2V0cyBmb3JtYXR0aW5nIGZpZWxkcyB0byB0aGVpciBkZWZhdWx0IHZhbHVlcy4KLSAgICAgKi8KLSAgICBwdWJsaWMgTm9kZUNvdW50ZXIgc2V0RGVmYXVsdEZvcm1hdHRpbmcoKSB7Ci0gICAgc2V0Rm9ybWF0dGluZygiMSIsICJlbiIsICJhbHBoYWJldGljIiwgbnVsbCwgbnVsbCk7Ci0gICAgcmV0dXJuIHRoaXM7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgcG9zaXRpb24gb2YgPHR0Pm5vZGU8L3R0PiBhY2NvcmRpbmcgdG8gdGhlIGxldmVsIGFuZAotICAgICAqIHRoZSBmcm9tIGFuZCBjb3VudCBwYXR0ZXJucy4KLSAgICAgKi8KLSAgICBhYnN0cmFjdCBwdWJsaWMgU3RyaW5nIGdldENvdW50ZXIoKTsKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIHBvc2l0aW9uIG9mIDx0dD5ub2RlPC90dD4gYWNjb3JkaW5nIHRvIHRoZSBsZXZlbCBhbmQKLSAgICAgKiB0aGUgZnJvbSBhbmQgY291bnQgcGF0dGVybnMuIFRoaXMgcG9zaXRpb24gaXMgY29udmVydGVkIGludG8gYQotICAgICAqIHN0cmluZyBiYXNlZCBvbiB0aGUgYXJndW1lbnRzIHBhc3NlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldENvdW50ZXIoU3RyaW5nIGZvcm1hdCwgU3RyaW5nIGxhbmcsIFN0cmluZyBsZXR0ZXJWYWx1ZSwKLSAgICAgICAgICAgICAgICBTdHJpbmcgZ3JvdXBTZXAsIFN0cmluZyBncm91cFNpemUpIHsKLSAgICBzZXRGb3JtYXR0aW5nKGZvcm1hdCwgbGFuZywgbGV0dGVyVmFsdWUsIGdyb3VwU2VwLCBncm91cFNpemUpOwotICAgIHJldHVybiBnZXRDb3VudGVyKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIGlmIDx0dD5ub2RlPC90dD4gbWF0Y2hlcyB0aGUgY291bnQgcGF0dGVybi4gQnkKLSAgICAgKiBkZWZhdWx0IGEgbm9kZSBtYXRjaGVzIHRoZSBjb3VudCBwYXR0ZXJucyBpZiBpdCBpcyBvZiB0aGUKLSAgICAgKiBzYW1lIHR5cGUgYXMgdGhlIHN0YXJ0aW5nIG5vZGUuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gbWF0Y2hlc0NvdW50KGludCBub2RlKSB7Ci0gICAgcmV0dXJuIF9ub2RlVHlwZSA9PSBfZG9jdW1lbnQuZ2V0RXhwYW5kZWRUeXBlSUQobm9kZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIGlmIDx0dD5ub2RlPC90dD4gbWF0Y2hlcyB0aGUgZnJvbSBwYXR0ZXJuLiBCeSBkZWZhdWx0LAotICAgICAqIG5vIG5vZGUgbWF0Y2hlcyB0aGUgZnJvbSBwYXR0ZXJuLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIG1hdGNoZXNGcm9tKGludCBub2RlKSB7Ci0gICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEZvcm1hdCBhIHNpbmdsZSB2YWx1ZSBhY2NvcmRpbmcgdG8gdGhlIGZvcm1hdCBwYXJhbWV0ZXJzLgotICAgICAqLwotICAgIHByb3RlY3RlZCBTdHJpbmcgZm9ybWF0TnVtYmVycyhpbnQgdmFsdWUpIHsKLSAgICByZXR1cm4gZm9ybWF0TnVtYmVycyhuZXcgaW50W10geyB2YWx1ZSB9KTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBGb3JtYXQgYSBzZXF1ZW5jZSBvZiB2YWx1ZXMgYWNjb3JkaW5nIHRvIHRoZSBmb3JtYXQgcGFyYW1hdGVycwotICAgICAqIHNldCBieSBjYWxsaW5nIHNldEZvcm1hdHRpbmcoKS4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgU3RyaW5nIGZvcm1hdE51bWJlcnMoaW50W10gdmFsdWVzKSB7Ci0gICAgZmluYWwgaW50IG5WYWx1ZXMgPSB2YWx1ZXMubGVuZ3RoOwotCi0gICAgYm9vbGVhbiBpc0VtcHR5ID0gdHJ1ZTsKLSAgICBmb3IgKGludCBpID0gMDsgaSA8IG5WYWx1ZXM7IGkrKykKLSAgICAgICAgaWYgKHZhbHVlc1tpXSAhPSBJbnRlZ2VyLk1JTl9WQUxVRSkKLSAgICAgICAgaXNFbXB0eSA9IGZhbHNlOwotICAgIGlmIChpc0VtcHR5KSByZXR1cm4oIiIpOwotCi0gICAgLy8gRm9ybWF0IHRoZSBvdXRwdXQgc3RyaW5nIHVzaW5nIHRoZSB2YWx1ZXMgYXJyYXkgYW5kIHRoZSBmbXQuIHRva2VucwotICAgIGJvb2xlYW4gaXNGaXJzdCA9IHRydWU7Ci0gICAgaW50IHQgPSAwLCBuID0gMCwgcyA9IDE7Ci0gIF90ZW1wQnVmZmVyLnNldExlbmd0aCgwKTsKLSAgICBmaW5hbCBTdHJpbmdCdWlsZGVyIGJ1ZmZlciA9IF90ZW1wQnVmZmVyOwotCi0gICAgLy8gQXBwZW5kIHNlcGFyYXRpb24gdG9rZW4gYmVmb3JlIGZpcnN0IGRpZ2l0L2xldHRlci9udW1lcmFsCi0gICAgaWYgKF9zZXBhckZpcnN0KSBidWZmZXIuYXBwZW5kKChTdHJpbmcpX3NlcGFyVG9rcy5lbGVtZW50QXQoMCkpOwotCi0gICAgLy8gQXBwZW5kIG5leHQgZGlnaXQvbGV0dGVyL251bWVyYWwgYW5kIHNlcGFyYXRpb24gdG9rZW4KLSAgICB3aGlsZSAobiA8IG5WYWx1ZXMpIHsKLSAgICAgICAgZmluYWwgaW50IHZhbHVlID0gdmFsdWVzW25dOwotICAgICAgICBpZiAodmFsdWUgIT0gSW50ZWdlci5NSU5fVkFMVUUpIHsKLSAgICAgICAgaWYgKCFpc0ZpcnN0KSBidWZmZXIuYXBwZW5kKChTdHJpbmcpIF9zZXBhclRva3MuZWxlbWVudEF0KHMrKykpOwotICAgICAgICBmb3JtYXRWYWx1ZSh2YWx1ZSwgKFN0cmluZylfZm9ybWF0VG9rcy5lbGVtZW50QXQodCsrKSwgYnVmZmVyKTsKLSAgICAgICAgaWYgKHQgPT0gX25Gb3JtYXRzKSB0LS07Ci0gICAgICAgIGlmIChzID49IF9uU2VwYXJzKSBzLS07Ci0gICAgICAgIGlzRmlyc3QgPSBmYWxzZTsKLSAgICAgICAgfQotICAgICAgICBuKys7Ci0gICAgfQotCi0gICAgLy8gQXBwZW5kIHNlcGFyYXRpb24gdG9rZW4gYWZ0ZXIgbGFzdCBkaWdpdC9sZXR0ZXIvbnVtZXJhbAotICAgIGlmIChfc2VwYXJMYXN0KSBidWZmZXIuYXBwZW5kKChTdHJpbmcpX3NlcGFyVG9rcy5sYXN0RWxlbWVudCgpKTsKLSAgICByZXR1cm4gYnVmZmVyLnRvU3RyaW5nKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRm9ybWF0IGEgc2luZ2xlIHZhbHVlIGJhc2VkIG9uIHRoZSBhcHByb3ByaWF0ZSBmb3JtYXR0aW5nIHRva2VuLgotICAgICAqIFRoaXMgbWV0aG9kIGlzIGJhc2VkIG9uIHNheG9uIChNaWNoYWVsIEtheSkgYW5kIG9ubHkgaW1wbGVtZW50cwotICAgICAqIGxhbmc9ImVuIi4KLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgZm9ybWF0VmFsdWUoaW50IHZhbHVlLCBTdHJpbmcgZm9ybWF0LCBTdHJpbmdCdWlsZGVyIGJ1ZmZlcikgewotICAgICAgICBjaGFyIGMgPSBmb3JtYXQuY2hhckF0KDApOwotCi0gICAgICAgIGlmIChDaGFyYWN0ZXIuaXNEaWdpdChjKSkgewotICAgICAgICAgICAgY2hhciB6ZXJvID0gKGNoYXIpKGMgLSBDaGFyYWN0ZXIuZ2V0TnVtZXJpY1ZhbHVlKGMpKTsKLQotICAgICAgICAgICAgU3RyaW5nQnVpbGRlciB0ZW1wID0gYnVmZmVyOwotICAgICAgICAgICAgaWYgKF9ncm91cFNpemUgPiAwKSB7Ci0gICAgICAgICAgICAgICAgdGVtcCA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBTdHJpbmcgcyA9ICIiOwotICAgICAgICAgICAgaW50IG4gPSB2YWx1ZTsKLSAgICAgICAgICAgIHdoaWxlIChuID4gMCkgewotICAgICAgICAgICAgICAgIHMgPSAoY2hhcikgKChpbnQpIHplcm8gKyAobiAlIDEwKSkgKyBzOwotICAgICAgICAgICAgICAgIG4gPSBuIC8gMTA7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZm9ybWF0Lmxlbmd0aCgpIC0gcy5sZW5ndGgoKTsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgdGVtcC5hcHBlbmQoemVybyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICB0ZW1wLmFwcGVuZChzKTsKLQotICAgICAgICAgICAgaWYgKF9ncm91cFNpemUgPiAwKSB7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB0ZW1wLmxlbmd0aCgpOyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGkgIT0gMCAmJiAoKHRlbXAubGVuZ3RoKCkgLSBpKSAlIF9ncm91cFNpemUpID09IDApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoX2dyb3VwU2VwKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKHRlbXAuY2hhckF0KGkpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICBlbHNlIGlmIChjID09ICdpJyAmJiAhX2xldHRlclZhbHVlLmVxdWFscygiYWxwaGFiZXRpYyIpKSB7Ci0gICAgICAgICAgICBidWZmZXIuYXBwZW5kKHJvbWFuVmFsdWUodmFsdWUpKTsKLSAgICAgICAgfQotICAgIGVsc2UgaWYgKGMgPT0gJ0knICYmICFfbGV0dGVyVmFsdWUuZXF1YWxzKCJhbHBoYWJldGljIikpIHsKLSAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQocm9tYW5WYWx1ZSh2YWx1ZSkudG9VcHBlckNhc2UoKSk7Ci0gICAgICAgIH0KLSAgICBlbHNlIHsKLSAgICAgICAgaW50IG1pbiA9IChpbnQpIGM7Ci0gICAgICAgIGludCBtYXggPSAoaW50KSBjOwotCi0gICAgICAgIC8vIFNwZWNpYWwgY2FzZSBmb3IgR3JlZWsgYWxwaGFiZXQKLSAgICAgICAgaWYgKGMgPj0gMHgzYjEgJiYgYyA8PSAweDNjOSkgewotICAgICAgICBtYXggPSAweDNjOTsgICAgLy8gb21lZ2EKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgLy8gR2VuZXJhbCBjYXNlOiBzZWFyY2ggZm9yIGVuZCBvZiBncm91cAotICAgICAgICB3aGlsZSAoQ2hhcmFjdGVyLmlzTGV0dGVyT3JEaWdpdCgoY2hhcikgKG1heCArIDEpKSkgewotICAgICAgICAgICAgbWF4Kys7Ci0gICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICAgICAgYnVmZmVyLmFwcGVuZChhbHBoYVZhbHVlKHZhbHVlLCBtaW4sIG1heCkpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBTdHJpbmcgYWxwaGFWYWx1ZShpbnQgdmFsdWUsIGludCBtaW4sIGludCBtYXgpIHsKLSAgICAgICAgaWYgKHZhbHVlIDw9IDApIHsKLSAgICAgICAgcmV0dXJuICIiICsgdmFsdWU7Ci0gICAgfQotCi0gICAgICAgIGludCByYW5nZSA9IG1heCAtIG1pbiArIDE7Ci0gICAgICAgIGNoYXIgbGFzdCA9IChjaGFyKSgoKHZhbHVlLTEpICUgcmFuZ2UpICsgbWluKTsKLSAgICAgICAgaWYgKHZhbHVlID4gcmFuZ2UpIHsKLSAgICAgICAgICAgIHJldHVybiBhbHBoYVZhbHVlKCh2YWx1ZS0xKSAvIHJhbmdlLCBtaW4sIG1heCkgKyBsYXN0OwotICAgICAgICB9Ci0gICAgZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gIiIgKyBsYXN0OwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBTdHJpbmcgcm9tYW5WYWx1ZShpbnQgbikgewotICAgICAgICBpZiAobiA8PSAwIHx8IG4gPiA0MDAwKSB7Ci0gICAgICAgIHJldHVybiAiIiArIG47Ci0gICAgfQotICAgICAgICByZXR1cm4KLSAgICAgICAgVGhvdXNhbmRzW24gLyAxMDAwXSArCi0gICAgICAgIEh1bmRyZWRzWyhuIC8gMTAwKSAlIDEwXSArCi0gICAgICAgIFRlbnNbKG4vMTApICUgMTBdICsKLSAgICAgICAgT25lc1tuICUgMTBdOwotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vTm9kZUl0ZXJhdG9yQmFzZS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vTm9kZUl0ZXJhdG9yQmFzZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkNTEzNTRhLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvZG9tL05vZGVJdGVyYXRvckJhc2UuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE3MiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBOb2RlSXRlcmF0b3JCYXNlLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMDYgMDk6Mzc6MDIgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmRvbTsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5Ob2RlSXRlcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnJ1bnRpbWUuQmFzaXNMaWJyYXJ5OwotCi0vKioKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICovCi1wdWJsaWMgYWJzdHJhY3QgY2xhc3MgTm9kZUl0ZXJhdG9yQmFzZSBpbXBsZW1lbnRzIE5vZGVJdGVyYXRvciB7Ci0KLSAgICAvKioKLSAgICAgKiBDYWNoZWQgY29tcHV0ZWQgdmFsdWUgb2YgbGFzdCgpLgotICAgICAqLwotICAgIHByb3RlY3RlZCBpbnQgX2xhc3QgPSAtMTsKLQotICAgIC8qKgotICAgICAqIFZhbHVlIG9mIHBvc2l0aW9uKCkgaW4gdGhpcyBpdGVyYXRvci4gSW5jcmVtZW50ZWQgaW4KLSAgICAgKiByZXR1cm5Ob2RlKCkuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGludCBfcG9zaXRpb24gPSAwOwotCi0gICAgLyoqCi0gICAgICogU3RvcmUgbm9kZSBpbiBjYWxsIHRvIHNldE1hcmsoKS4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgaW50IF9tYXJrZWROb2RlOwotCi0gICAgLyoqCi0gICAgICogU3RvcmUgbm9kZSBpbiBjYWxsIHRvIHNldFN0YXJ0Tm9kZSgpLgotICAgICAqLwotICAgIHByb3RlY3RlZCBpbnQgX3N0YXJ0Tm9kZSA9IE5vZGVJdGVyYXRvci5FTkQ7Ci0KLSAgICAvKioKLSAgICAgKiBGbGFnIGluZGljYXRpbmcgaWYgInNlbGYiIHNob3VsZCBiZSByZXR1cm5lZC4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBfaW5jbHVkZVNlbGYgPSBmYWxzZTsKLQotICAgIC8qKgotICAgICAqIEZsYWcgaW5kaWNhdGluZyBpZiBpdGVyYXRvciBjYW4gYmUgcmVzdGFydGVkLgotICAgICAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIF9pc1Jlc3RhcnRhYmxlID0gdHJ1ZTsKLQotICAgIC8qKgotICAgICAqIFNldHRlciBmb3IgX2lzUmVzdGFydGFibGUgZmxhZy4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRSZXN0YXJ0YWJsZShib29sZWFuIGlzUmVzdGFydGFibGUpIHsKLSAgICAgICAgX2lzUmVzdGFydGFibGUgPSBpc1Jlc3RhcnRhYmxlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEluaXRpYWxpemUgaXRlcmF0b3IgdXNpbmcgYSBub2RlLiBJZiBpdGVyYXRvciBpcyBub3QKLSAgICAgKiByZXN0YXJ0YWJsZSwgdGhlbiBkbyBub3RoaW5nLiBJZiBub2RlIGlzIGVxdWFsIHRvIEVORCB0aGVuCi0gICAgICogc3Vic2VxdWVudCBjYWxscyB0byBuZXh0KCkgbXVzdCByZXR1cm4gRU5ELgotICAgICAqLwotICAgIGFic3RyYWN0IHB1YmxpYyBOb2RlSXRlcmF0b3Igc2V0U3RhcnROb2RlKGludCBub2RlKTsKLQotICAgIC8qKgotICAgICAqIFJlc2V0IHRoaXMgaXRlcmF0b3IgdXNpbmcgc3RhdGUgZnJvbSBsYXN0IGNhbGwgdG8KLSAgICAgKiBzZXRTdGFydE5vZGUoKS4KLSAgICAgKi8KLSAgICBwdWJsaWMgTm9kZUl0ZXJhdG9yIHJlc2V0KCkgewotICAgICAgICBmaW5hbCBib29sZWFuIHRlbXAgPSBfaXNSZXN0YXJ0YWJsZTsKLSAgICAgICAgX2lzUmVzdGFydGFibGUgPSB0cnVlOwotICAgICAgICAvLyBNdXN0IGFkanVzdCBfc3RhcnROb2RlIGlmIHNlbGYgaXMgaW5jbHVkZWQKLSAgICAgICAgc2V0U3RhcnROb2RlKF9pbmNsdWRlU2VsZiA/IF9zdGFydE5vZGUgKyAxIDogX3N0YXJ0Tm9kZSk7Ci0gICAgICAgIF9pc1Jlc3RhcnRhYmxlID0gdGVtcDsKLSAgICAgICAgcmV0dXJuIHRoaXM7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0dGVyIGZvciBfaW5jbHVkZVNlbGYgZmxhZy4KLSAgICAgKi8KLSAgICBwdWJsaWMgTm9kZUl0ZXJhdG9yIGluY2x1ZGVTZWxmKCkgewotICAgICAgICBfaW5jbHVkZVNlbGYgPSB0cnVlOwotICAgICAgICByZXR1cm4gdGhpczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBEZWZhdWx0IGltcGxlbWVudGF0aW9uIG9mIGdldExhc3QoKS4gU3RvcmVzIGN1cnJlbnQgcG9zaXRpb24KLSAgICAgKiBhbmQgY3VycmVudCBub2RlLCByZXNldHMgdGhlIGl0ZXJhdG9yLCBjb3VudHMgYWxsIG5vZGVzIGFuZAotICAgICAqIHJlc3RvcmVzIGl0ZXJhdG9yIHRvIG9yaWdpbmFsIHN0YXRlLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0TGFzdCgpIHsKLSAgICAgICAgaWYgKF9sYXN0ID09IC0xKSB7Ci0gICAgICAgICAgICBmaW5hbCBpbnQgdGVtcCA9IF9wb3NpdGlvbjsKLSAgICAgICAgICAgIHNldE1hcmsoKTsKLSAgICAgICAgICAgIHJlc2V0KCk7Ci0gICAgICAgICAgICBkbyB7Ci0gICAgICAgICAgICAgICAgX2xhc3QrKzsKLSAgICAgICAgICAgIH0gd2hpbGUgKG5leHQoKSAhPSBFTkQpOwotICAgICAgICAgICAgZ290b01hcmsoKTsKLSAgICAgICAgICAgIF9wb3NpdGlvbiA9IHRlbXA7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIF9sYXN0OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIHBvc2l0aW9uKCkgaW4gdGhpcyBpdGVyYXRvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldFBvc2l0aW9uKCkgewotICAgICAgICByZXR1cm4gX3Bvc2l0aW9uID09IDAgPyAxIDogX3Bvc2l0aW9uOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEluZGljYXRlcyBpZiBwb3NpdGlvbiBpbiB0aGlzIGl0ZXJhdG9yIGlzIGNvbXB1dGVkIGluIHJldmVyc2UKLSAgICAgKiBkb2N1bWVudCBvcmRlci4gTm90ZSB0aGF0IG5vZGVzIGFyZSBhbHdheXMgcmV0dXJuZWQgaW4gZG9jdW1lbnQKLSAgICAgKiBvcmRlci4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc1JldmVyc2UoKSB7Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDbG9uZXMgYW5kIHJlc2V0cyB0aGlzIGl0ZXJhdG9yLiBOb3RlIHRoYXQgdGhlIGNsb25lZCBpdGVyYXRvciBpcwotICAgICAqIG5vdCByZXN0YXJ0YWJsZS4gVGhpcyBpcyBiZWNhdXNlIGNsb25pbmcgaXMgbmVlZGVkIGZvciB2YXJpYWJsZQotICAgICAqIHJlZmVyZW5jZXMsIGFuZCB0aGUgY29udGV4dCBub2RlIG9mIHRoZSBvcmlnaW5hbCB2YXJpYWJsZQotICAgICAqIGRlY2xhcmF0aW9uIG11c3QgYmUgcHJlc2VydmVkLgotICAgICAqLwotICAgIHB1YmxpYyBOb2RlSXRlcmF0b3IgY2xvbmVJdGVyYXRvcigpIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGZpbmFsIE5vZGVJdGVyYXRvckJhc2UgY2xvbmUgPSAoTm9kZUl0ZXJhdG9yQmFzZSlzdXBlci5jbG9uZSgpOwotICAgICAgICAgICAgY2xvbmUuX2lzUmVzdGFydGFibGUgPSBmYWxzZTsKLSAgICAgICAgICAgIHJldHVybiBjbG9uZS5yZXNldCgpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICBCYXNpc0xpYnJhcnkucnVuVGltZUVycm9yKEJhc2lzTGlicmFyeS5JVEVSQVRPUl9DTE9ORV9FUlIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGUudG9TdHJpbmcoKSk7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFV0aWxpdHkgbWV0aG9kIHRoYXQgaW5jcmVtZW50cyBwb3NpdGlvbiBhbmQgcmV0dXJucyBpdHMKLSAgICAgKiBhcmd1bWVudC4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgZmluYWwgaW50IHJldHVybk5vZGUoZmluYWwgaW50IG5vZGUpIHsKLSAgICAgICAgX3Bvc2l0aW9uKys7Ci0gICAgICAgIHJldHVybiBub2RlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJlc2V0IHRoZSBwb3NpdGlvbiBpbiB0aGlzIGl0ZXJhdG9yLgotICAgICAqLwotICAgIHByb3RlY3RlZCBmaW5hbCBOb2RlSXRlcmF0b3IgcmVzZXRQb3NpdGlvbigpIHsKLSAgICAgICAgX3Bvc2l0aW9uID0gMDsKLSAgICAgICAgcmV0dXJuIHRoaXM7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vTm9kZVNvcnRSZWNvcmQuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvZG9tL05vZGVTb3J0UmVjb3JkLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGFhZjk5N2EuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vTm9kZVNvcnRSZWNvcmQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI1MiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBOb2RlU29ydFJlY29yZC5qYXZhLHYgMS41IDIwMDUvMDkvMjggMTM6NDg6MzYgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmRvbTsKLQotaW1wb3J0IGphdmEudGV4dC5Db2xsYXRpb25LZXk7Ci1pbXBvcnQgamF2YS50ZXh0LkNvbGxhdG9yOwotaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuQ29sbGF0b3JGYWN0b3J5OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5ET007Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLlRyYW5zbGV0RXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5ydW50aW1lLkFic3RyYWN0VHJhbnNsZXQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5TdHJpbmdDb21wYXJhYmxlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC51dGlscy5PYmplY3RGYWN0b3J5OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC51dGlscy5TZWN1cml0eVN1cHBvcnQ7Ci0KLS8qKgotICogQmFzZSBjbGFzcyBmb3Igc29ydCByZWNvcmRzIGNvbnRhaW5pbmcgYXBwbGljYXRpb24gc3BlY2lmaWMgc29ydCBrZXlzCi0gKi8KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBOb2RlU29ydFJlY29yZCB7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ09NUEFSRV9TVFJJTkcgICAgID0gMDsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDT01QQVJFX05VTUVSSUMgICAgPSAxOwotCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ09NUEFSRV9BU0NFTkRJTkcgID0gMDsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDT01QQVJFX0RFU0NFTkRJTkcgPSAxOwotCi0gICAgLyoqCi0gICAgICogQSByZWZlcmVuY2UgdG8gYSBjb2xsYXRvci4gTWF5IGJlIHVwZGF0ZWQgYnkgc3ViY2xhc3MgaWYgdGhlIHN0eWxlc2hlZXQKLSAgICAgKiBzcGVjaWZpZXMgYSBkaWZmZXJlbnQgbGFuZ3VhZ2UgKHdpbGwgYmUgdXBkYXRlZCBpZmYgX2xvY2FsZSBpcyB1cGRhdGVkKS4KLSAgICAgKiBAZGVwcmVjYXRlZCBUaGlzIGZpZWxkIGNvbnRpbnVlcyB0byBleGlzdCBmb3IgYmluYXJ5IGNvbXBhdGliaWxpdHkuCi0gICAgICogICAgICAgICAgICAgTmV3IGNvZGUgc2hvdWxkIG5vdCByZWZlciB0byBpdC4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBDb2xsYXRvciBERUZBVUxUX0NPTExBVE9SID0gQ29sbGF0b3IuZ2V0SW5zdGFuY2UoKTsKLQotICAgIC8qKgotICAgICAqIEEgcmVmZXJlbmNlIHRvIHRoZSBmaXJzdCBDb2xsYXRvcgotICAgICAqIEBkZXByZWNhdGVkIFRoaXMgZmllbGQgY29udGludWVzIHRvIGV4aXN0IGZvciBiaW5hcnkgY29tcGF0aWJpbGl0eS4KLSAgICAgKiAgICAgICAgICAgICBOZXcgY29kZSBzaG91bGQgbm90IHJlZmVyIHRvIGl0LgotICAgICAqLwotICAgIHByb3RlY3RlZCBDb2xsYXRvciBfY29sbGF0b3IgPSBERUZBVUxUX0NPTExBVE9SOwotICAgIHByb3RlY3RlZCBDb2xsYXRvcltdIF9jb2xsYXRvcnM7Ci0KLSAgICAvKioKLSAgICAgKiBBIGxvY2FsZSBmaWVsZCB0aGF0IG1pZ2h0IGJlIHNldCBieSBhbiBpbnN0YW5jZSBvZiBhIHN1YmNsYXNzLgotICAgICAqIEBkZXByZWNhdGVkIFRoaXMgZmllbGQgY29udGludWVzIHRvIGV4aXN0IGZvciBiaW5hcnkgY29tcGF0aWJpbGl0eS4KLSAgICAgKiAgICAgICAgICAgICBOZXcgY29kZSBzaG91bGQgbm90IHJlZmVyIHRvIGl0LgotICAgICAqLwotICAgIHByb3RlY3RlZCBMb2NhbGUgX2xvY2FsZTsKLQotICAgIHByb3RlY3RlZCBDb2xsYXRvckZhY3RvcnkgX2NvbGxhdG9yRmFjdG9yeTsKLQotICAgIHByb3RlY3RlZCBTb3J0U2V0dGluZ3MgX3NldHRpbmdzOwotCi0gICAgcHJpdmF0ZSBET00gICAgX2RvbSA9IG51bGw7Ci0gICAgcHJpdmF0ZSBpbnQgICAgX25vZGU7ICAgICAgICAgICAvLyBUaGUgcG9zaXRpb24gaW4gdGhlIGN1cnJlbnQgaXRlcmF0b3IKLSAgICBwcml2YXRlIGludCAgICBfbGFzdCA9IDA7ICAgICAgIC8vIE51bWJlciBvZiBub2RlcyBpbiB0aGUgY3VycmVudCBpdGVyYXRvcgotICAgIHByaXZhdGUgaW50ICAgIF9zY2FubmVkID0gMDsgICAgLy8gTnVtYmVyIG9mIGtleSBsZXZlbHMgZXh0cmFjdGVkIGZyb20gRE9NCi0KLSAgICBwcml2YXRlIE9iamVjdFtdIF92YWx1ZXM7IC8vIENvbnRhaW5zIENvbXBhcmFibGUgIG9iamVjdHMKLQotICAgIC8qKgotICAgICAqIFRoaXMgY29uc3RydWN0b3IgaXMgcnVuIGJ5IGEgY2FsbCB0byBDbGFzc0xvYWRlciBpbiB0aGUKLSAgICAgKiBtYWtlTm9kZVNvcnRSZWNvcmQgbWV0aG9kIGluIHRoZSBOb2RlU29ydFJlY29yZEZhY3RvcnkgY2xhc3MuIFNpbmNlIHdlCi0gICAgICogY2Fubm90IHBhc3MgYW55IHBhcmFtZXRlcnMgdG8gdGhlIGNvbnN0cnVjdG9yIGluIHRoYXQgY2FzZSB3ZSBqdXN0IHNldAotICAgICAqIHRoZSBkZWZhdWx0IHZhbHVlcyBoZXJlIGFuZCB3YWl0IGZvciBuZXcgdmFsdWVzIHRocm91Z2ggaW5pdGlhbGl6ZSgpLgotICAgICAqLwotICAgIHB1YmxpYyBOb2RlU29ydFJlY29yZChpbnQgbm9kZSkgewotICAgICAgICBfbm9kZSA9IG5vZGU7Ci0gICAgfQotCi0gICAgcHVibGljIE5vZGVTb3J0UmVjb3JkKCkgewotICAgICAgICB0aGlzKDApOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIGFsbG93cyB0aGUgY2FsbGVyIHRvIHNldCB0aGUgdmFsdWVzIHRoYXQgY291bGQgbm90IGJlIHBhc3NlZAotICAgICAqIHRvIHRoZSBkZWZhdWx0IGNvbnN0cnVjdG9yLgotICAgICAqLwotICAgIHB1YmxpYyBmaW5hbCB2b2lkIGluaXRpYWxpemUoaW50IG5vZGUsIGludCBsYXN0LCBET00gZG9tLAotICAgICAgICAgU29ydFNldHRpbmdzIHNldHRpbmdzKQotICAgICAgICB0aHJvd3MgVHJhbnNsZXRFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIF9kb20gPSBkb207Ci0gICAgICAgIF9ub2RlID0gbm9kZTsKLSAgICAgICAgX2xhc3QgPSBsYXN0OwotICAgICAgICBfc2V0dGluZ3MgPSBzZXR0aW5nczsKLQotICAgICAgICBpbnQgbGV2ZWxzID0gc2V0dGluZ3MuZ2V0U29ydE9yZGVycygpLmxlbmd0aDsKLSAgICAgICAgX3ZhbHVlcyA9IG5ldyBPYmplY3RbbGV2ZWxzXTsKLQotICAgICAgICBTdHJpbmcgY29sRmFjdENsYXNzbmFtZSA9IG51bGw7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAvLyAtLSBXLiBFbGlvdCBLaW1iZXIgKGVsaW90QGlzb2dlbi5jb20pCi0gICAgICAgICAgICBjb2xGYWN0Q2xhc3NuYW1lID0KLSAgICAgICAgICAgICAgICBTZWN1cml0eVN1cHBvcnQuZ2V0U3lzdGVtUHJvcGVydHkoImNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5DT0xMQVRPUl9GQUNUT1JZIik7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIC8vIElmIHdlIGNhbid0IHJlYWQgdGhlIHByb3BlcnksIGp1c3QgdXNlIGRlZmF1bHQgY29sbGF0b3IKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChjb2xGYWN0Q2xhc3NuYW1lICE9IG51bGwpIHsKLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgT2JqZWN0IGNhbmRPYmogPSBPYmplY3RGYWN0b3J5LmZpbmRQcm92aWRlckNsYXNzKGNvbEZhY3RDbGFzc25hbWUsIHRydWUpOwotICAgICAgICAgICAgICAgIF9jb2xsYXRvckZhY3RvcnkgPSAoQ29sbGF0b3JGYWN0b3J5KWNhbmRPYmo7Ci0gICAgICAgICAgICB9IGNhdGNoIChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNsZXRFeGNlcHRpb24oZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBMb2NhbGVbXSBsb2NhbGVzID0gc2V0dGluZ3MuZ2V0TG9jYWxlcygpOwotICAgICAgICAgICAgX2NvbGxhdG9ycyA9IG5ldyBDb2xsYXRvcltsZXZlbHNdOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZXZlbHM7IGkrKyl7Ci0gICAgICAgICAgICAgICAgX2NvbGxhdG9yc1tpXSA9IF9jb2xsYXRvckZhY3RvcnkuZ2V0Q29sbGF0b3IobG9jYWxlc1tpXSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBfY29sbGF0b3IgPSBfY29sbGF0b3JzWzBdOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgX2NvbGxhdG9ycyA9IHNldHRpbmdzLmdldENvbGxhdG9ycygpOwotICAgICAgICAgICAgX2NvbGxhdG9yID0gX2NvbGxhdG9yc1swXTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIG5vZGUgZm9yIHRoaXMgc29ydCBvYmplY3QKLSAgICAgKi8KLSAgICBwdWJsaWMgZmluYWwgaW50IGdldE5vZGUoKSB7Ci0gICAgICAgIHJldHVybiBfbm9kZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKgotICAgICAqLwotICAgIHB1YmxpYyBmaW5hbCBpbnQgY29tcGFyZURvY09yZGVyKE5vZGVTb3J0UmVjb3JkIG90aGVyKSB7Ci0gICAgICAgIHJldHVybiBfbm9kZSAtIG90aGVyLl9ub2RlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgc3RyaW5nIG9yIG51bWVyaWMgdmFsdWUgb2YgYSBzcGVjaWZpYyBsZXZlbCBrZXkgZm9yIHRoaXMgc29ydAotICAgICAqIGVsZW1lbnQuIFRoZSB2YWx1ZSBpcyBleHRyYWN0ZWQgZnJvbSB0aGUgRE9NIGlmIGl0IGlzIG5vdCBhbHJlYWR5IGluCi0gICAgICogb3VyIHNvcnQga2V5IHZlY3Rvci4KLSAgICAgKi8KLSAgICBwcml2YXRlIGZpbmFsIENvbXBhcmFibGUgc3RyaW5nVmFsdWUoaW50IGxldmVsKSB7Ci0gICAgICAgIC8vIEdldCB2YWx1ZSBmcm9tIG91ciBhcnJheSBpZiBwb3NzaWJsZQotICAgICAgICBpZiAoX3NjYW5uZWQgPD0gbGV2ZWwpIHsKLSAgICAgICAgICAgIEFic3RyYWN0VHJhbnNsZXQgdHJhbnNsZXQgPSBfc2V0dGluZ3MuZ2V0VHJhbnNsZXQoKTsKLSAgICAgICAgICAgIExvY2FsZVtdIGxvY2FsZXMgPSBfc2V0dGluZ3MuZ2V0TG9jYWxlcygpOwotICAgICAgICAgICAgU3RyaW5nW10gY2FzZU9yZGVyID0gX3NldHRpbmdzLmdldENhc2VPcmRlcnMoKTsKLQotICAgICAgICAgICAgLy8gR2V0IHZhbHVlIGZyb20gRE9NIGlmIGFjY2Vzc2VkIGZvciB0aGUgZmlyc3QgdGltZQotICAgICAgICAgICAgZmluYWwgU3RyaW5nIHN0ciA9IGV4dHJhY3RWYWx1ZUZyb21ET00oX2RvbSwgX25vZGUsIGxldmVsLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNsZXQsIF9sYXN0KTsKLSAgICAgICAgICAgIGZpbmFsIENvbXBhcmFibGUga2V5ID0KLSAgICAgICAgICAgICAgICBTdHJpbmdDb21wYXJhYmxlLmdldENvbXBhcmF0b3Ioc3RyLCBsb2NhbGVzW2xldmVsXSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2NvbGxhdG9yc1tsZXZlbF0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2VPcmRlcltsZXZlbF0pOwotICAgICAgICAgICAgX3ZhbHVlc1tfc2Nhbm5lZCsrXSA9IGtleTsKLSAgICAgICAgICAgIHJldHVybihrZXkpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybigoQ29tcGFyYWJsZSlfdmFsdWVzW2xldmVsXSk7Ci0gIH0KLQotICAgIHByaXZhdGUgZmluYWwgRG91YmxlIG51bWVyaWNWYWx1ZShpbnQgbGV2ZWwpIHsKLSAgICAgICAgLy8gR2V0IHZhbHVlIGZyb20gb3VyIHZlY3RvciBpZiBwb3NzaWJsZQotICAgICAgICBpZiAoX3NjYW5uZWQgPD0gbGV2ZWwpIHsKLSAgICAgICAgICAgIEFic3RyYWN0VHJhbnNsZXQgdHJhbnNsZXQgPSBfc2V0dGluZ3MuZ2V0VHJhbnNsZXQoKTsKLQotICAgICAgICAgICAgLy8gR2V0IHZhbHVlIGZyb20gRE9NIGlmIGFjY2Vzc2VkIGZvciB0aGUgZmlyc3QgdGltZQotICAgICAgICAgICAgZmluYWwgU3RyaW5nIHN0ciA9IGV4dHJhY3RWYWx1ZUZyb21ET00oX2RvbSwgX25vZGUsIGxldmVsLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNsZXQsIF9sYXN0KTsKLSAgICAgICAgICAgIERvdWJsZSBudW07Ci0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIG51bSA9IG5ldyBEb3VibGUoc3RyKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIFRyZWF0IG51bWJlciBhcyBOYU4gaWYgaXQgY2Fubm90IGJlIHBhcnNlZCBhcyBhIGRvdWJsZQotICAgICAgICAgICAgY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgbnVtID0gbmV3IERvdWJsZShEb3VibGUuTkVHQVRJVkVfSU5GSU5JVFkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgX3ZhbHVlc1tfc2Nhbm5lZCsrXSA9IG51bTsKLSAgICAgICAgICAgIHJldHVybihudW0pOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybigoRG91YmxlKV92YWx1ZXNbbGV2ZWxdKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb21wYXJlIHRoaXMgc29ydCBlbGVtZW50IHRvIGFub3RoZXIuIFRoZSBmaXJzdCBsZXZlbCBpcyBjaGVja2VkIGZpcnN0LAotICAgICAqIGFuZCB3ZSBwcm9jZWVkIHRvIHRoZSBuZXh0IGxldmVsIG9ubHkgaWYgdGhlIGZpcnN0IGxldmVsIGtleXMgYXJlCi0gICAgICogaWRlbnRpY2FsIChhbmQgc28gdGhlIGtleSB2YWx1ZXMgbWF5IG5vdCBldmVuIGJlIGV4dHJhY3RlZCBmcm9tIHRoZSBET00pCi0gICAgICoKLSAgICAgKiAhISEhTVVTVCBPUFRJTUlTRSAtIFRISVMgSVMgUkVBTExZLCBSRUFMTFkgU0xPVyEhISEKLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGNvbXBhcmVUbyhOb2RlU29ydFJlY29yZCBvdGhlcikgewotICAgICAgICBpbnQgY21wLCBsZXZlbDsKLSAgICAgICAgaW50W10gc29ydE9yZGVyID0gX3NldHRpbmdzLmdldFNvcnRPcmRlcnMoKTsKLSAgICAgICAgaW50IGxldmVscyA9IF9zZXR0aW5ncy5nZXRTb3J0T3JkZXJzKCkubGVuZ3RoOwotICAgICAgICBpbnRbXSBjb21wYXJlVHlwZXMgPSBfc2V0dGluZ3MuZ2V0VHlwZXMoKTsKLQotICAgICAgICBmb3IgKGxldmVsID0gMDsgbGV2ZWwgPCBsZXZlbHM7IGxldmVsKyspIHsKLSAgICAgICAgICAgIC8vIENvbXBhcmUgdGhlIHR3byBub2RlcyBlaXRoZXIgYXMgbnVtZXJpYyBvciB0ZXh0IHZhbHVlcwotICAgICAgICAgICAgaWYgKGNvbXBhcmVUeXBlc1tsZXZlbF0gPT0gQ09NUEFSRV9OVU1FUklDKSB7Ci0gICAgICAgICAgICAgICAgZmluYWwgRG91YmxlIG91ciA9IG51bWVyaWNWYWx1ZShsZXZlbCk7Ci0gICAgICAgICAgICAgICAgZmluYWwgRG91YmxlIHRoZWlyID0gb3RoZXIubnVtZXJpY1ZhbHVlKGxldmVsKTsKLSAgICAgICAgICAgICAgICBjbXAgPSBvdXIuY29tcGFyZVRvKHRoZWlyKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIGZpbmFsIENvbXBhcmFibGUgb3VyID0gc3RyaW5nVmFsdWUobGV2ZWwpOwotICAgICAgICAgICAgICAgIGZpbmFsIENvbXBhcmFibGUgdGhlaXIgPSBvdGhlci5zdHJpbmdWYWx1ZShsZXZlbCk7Ci0gICAgICAgICAgICAgICAgY21wID0gb3VyLmNvbXBhcmVUbyh0aGVpcik7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIFJldHVybiBpbnZlcnNlIGNvbXBhcmUgdmFsdWUgaWYgaW52ZXJzZSBzb3J0IG9yZGVyCi0gICAgICAgICAgICBpZiAoY21wICE9IDApIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gc29ydE9yZGVyW2xldmVsXSA9PSBDT01QQVJFX0RFU0NFTkRJTkcgPyAwIC0gY21wIDogY21wOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIC8vIENvbXBhcmUgYmFzZWQgb24gZG9jdW1lbnQgb3JkZXIgaWYgYWxsIHNvcnQga2V5cyBhcmUgZXF1YWwKLSAgICAgICAgcmV0dXJuKF9ub2RlIC0gb3RoZXIuX25vZGUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIGFycmF5IG9mIENvbGxhdG9ycyB1c2VkIGZvciB0ZXh0IGNvbXBhcmlzb25zIGluIHRoaXMgb2JqZWN0LgotICAgICAqIE1heSBiZSBvdmVycmlkZGVuIGJ5IGluaGVyaXRpbmcgY2xhc3NlcwotICAgICAqLwotICAgIHB1YmxpYyBDb2xsYXRvcltdIGdldENvbGxhdG9yKCkgewotICAgICAgICByZXR1cm4gX2NvbGxhdG9yczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBFeHRyYWN0IHRoZSBzb3J0IHZhbHVlIGZvciBhIGxldmVsIG9mIHRoaXMga2V5LgotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCBTdHJpbmcgZXh0cmFjdFZhbHVlRnJvbURPTShET00gZG9tLCBpbnQgY3VycmVudCwgaW50IGxldmVsLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBYnN0cmFjdFRyYW5zbGV0IHRyYW5zbGV0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbGFzdCk7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvZG9tL05vZGVTb3J0UmVjb3JkRmFjdG9yeS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vTm9kZVNvcnRSZWNvcmRGYWN0b3J5LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDFjYzQ2NGMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vTm9kZVNvcnRSZWNvcmRGYWN0b3J5LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNjYgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogTm9kZVNvcnRSZWNvcmRGYWN0b3J5LmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMDYgMDk6NTM6NDAgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmRvbTsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5ET007Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLlRyYW5zbGV0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5UcmFuc2xldEV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMucnVudGltZS5BYnN0cmFjdFRyYW5zbGV0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuTG9jYWxlVXRpbGl0eTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwudXRpbHMuT2JqZWN0RmFjdG9yeTsKLWltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwotaW1wb3J0IGphdmEudGV4dC5Db2xsYXRvcjsKLQotcHVibGljIGNsYXNzIE5vZGVTb3J0UmVjb3JkRmFjdG9yeSB7Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBpbnQgREVTQ0VORElORyA9ICJkZXNjZW5kaW5nIi5sZW5ndGgoKTsKLSAgICBwcml2YXRlIHN0YXRpYyBpbnQgTlVNQkVSICAgICA9ICJudW1iZXIiLmxlbmd0aCgpOwotCi0gICAgcHJpdmF0ZSBmaW5hbCBET00gICAgICBfZG9tOwotICAgIHByaXZhdGUgZmluYWwgU3RyaW5nICAgX2NsYXNzTmFtZTsKLSAgICBwcml2YXRlIENsYXNzIF9jbGFzczsKLSAgICBwcml2YXRlIFNvcnRTZXR0aW5ncyBfc29ydFNldHRpbmdzOwotCi0gICAgLyoqCi0gICAgICoKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgQ29sbGF0b3IgX2NvbGxhdG9yOwotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlcyBhIE5vZGVTb3J0UmVjb3JkIHByb2R1Y2luZyBvYmplY3QuIFRoZSBET00gc3BlY2lmaWVzIHdoaWNoIHRyZWUKLSAgICAgKiB0byBnZXQgdGhlIG5vZGVzIHRvIHNvcnQgZnJvbSwgdGhlIGNsYXNzIG5hbWUgc3BlY2lmaWVzIHdoYXQgYXV4aWxsYXJ5Ci0gICAgICogY2xhc3MgdG8gdXNlIHRvIHNvcnQgdGhlIG5vZGVzICh0aGlzIGNsYXNzIGlzIGdlbmVyYXRlZCBieSB0aGUgU29ydAotICAgICAqIGNsYXNzKSwgYW5kIHRoZSB0cmFuc2xldCBwYXJhbWV0ZXIgaXMgbmVlZGVkIGZvciBtZXRob2RzIGNhbGxlZCBieQotICAgICAqIHRoaXMgb2JqZWN0LgotICAgICAqCi0gICAgICogQGRlcHJlY2F0ZWQgVGhpcyBjb25zdHJ1Y3RvciBpcyBubyBsb25nZXIgdXNlZCBpbiBnZW5lcmF0ZWQgY29kZS4gIEl0Ci0gICAgICogICAgICAgICAgICAgZXhpc3RzIG9ubHkgZm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5LgotICAgICAqLwotICAgICBwdWJsaWMgTm9kZVNvcnRSZWNvcmRGYWN0b3J5KERPTSBkb20sIFN0cmluZyBjbGFzc05hbWUsIFRyYW5zbGV0IHRyYW5zbGV0LAotICAgICAgICAgICAgICAgICBTdHJpbmcgb3JkZXJbXSwgU3RyaW5nIHR5cGVbXSkKLSAgICAgICAgIHRocm93cyBUcmFuc2xldEV4Y2VwdGlvbgotICAgICB7Ci0gICAgICAgICB0aGlzKGRvbSwgY2xhc3NOYW1lLCB0cmFuc2xldCwgb3JkZXIsIHR5cGUsIG51bGwsIG51bGwpOwotICAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGVzIGEgTm9kZVNvcnRSZWNvcmQgcHJvZHVjaW5nIG9iamVjdC4gVGhlIERPTSBzcGVjaWZpZXMgd2hpY2ggdHJlZQotICAgICAqIHRvIGdldCB0aGUgbm9kZXMgdG8gc29ydCBmcm9tLCB0aGUgY2xhc3MgbmFtZSBzcGVjaWZpZXMgd2hhdCBhdXhpbGxhcnkKLSAgICAgKiBjbGFzcyB0byB1c2UgdG8gc29ydCB0aGUgbm9kZXMgKHRoaXMgY2xhc3MgaXMgZ2VuZXJhdGVkIGJ5IHRoZSBTb3J0Ci0gICAgICogY2xhc3MpLCBhbmQgdGhlIHRyYW5zbGV0IHBhcmFtZXRlciBpcyBuZWVkZWQgZm9yIG1ldGhvZHMgY2FsbGVkIGJ5Ci0gICAgICogdGhpcyBvYmplY3QuCi0gICAgICovCi0gICAgIHB1YmxpYyBOb2RlU29ydFJlY29yZEZhY3RvcnkoRE9NIGRvbSwgU3RyaW5nIGNsYXNzTmFtZSwgVHJhbnNsZXQgdHJhbnNsZXQsCi0gICAgICAgICAgICAgICAgIFN0cmluZyBvcmRlcltdLCBTdHJpbmcgdHlwZVtdLCBTdHJpbmcgbGFuZ1tdLAotICAgICAgICAgICAgICAgICBTdHJpbmcgY2FzZU9yZGVyW10pCi0gICAgICAgICB0aHJvd3MgVHJhbnNsZXRFeGNlcHRpb24KLSAgICAgewotICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICBfZG9tID0gZG9tOwotICAgICAgICAgICAgIF9jbGFzc05hbWUgPSBjbGFzc05hbWU7Ci0gICAgICAgICAgICAgLy8gVGhpcyBzaG91bGQgcmV0dXJuIGEgQ2xhc3MgZGVmaW5pdGlvbiBpZiB1c2luZyBUckFYCi0gICAgICAgICAgICAgX2NsYXNzID0gdHJhbnNsZXQuZ2V0QXV4aWxpYXJ5Q2xhc3MoY2xhc3NOYW1lKTsKLSAgICAgICAgICAgICAvLyBUaGlzIGNvZGUgaXMgb25seSBydW4gd2hlbiB0aGUgbmF0aXZlIEFQSSBpcyB1c2VkCi0gICAgICAgICAgICAgaWYgKF9jbGFzcyA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgIF9jbGFzcyA9IE9iamVjdEZhY3RvcnkuZmluZFByb3ZpZGVyQ2xhc3MoY2xhc3NOYW1lLCB0cnVlKTsKLSAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICBpbnQgbGV2ZWxzID0gb3JkZXIubGVuZ3RoOwotICAgICAgICAgICAgIGludFtdIGlPcmRlciA9IG5ldyBpbnRbbGV2ZWxzXTsKLSAgICAgICAgICAgICBpbnRbXSBpVHlwZSA9IG5ldyBpbnRbbGV2ZWxzXTsKLSAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxldmVsczsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgICBpZiAob3JkZXJbaV0ubGVuZ3RoKCkgPT0gREVTQ0VORElORykgewotICAgICAgICAgICAgICAgICAgICAgIGlPcmRlcltpXSA9IE5vZGVTb3J0UmVjb3JkLkNPTVBBUkVfREVTQ0VORElORzsKLSAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgIGlmICh0eXBlW2ldLmxlbmd0aCgpID09IE5VTUJFUikgewotICAgICAgICAgICAgICAgICAgICAgIGlUeXBlW2ldID0gTm9kZVNvcnRSZWNvcmQuQ09NUEFSRV9OVU1FUklDOwotICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgIC8vIE9sZCBOb2RlU29ydFJlY29yZEZhY3RvcnkgY29uc3RydWN0b3IgaGFkIG5vIGxhbmcgb3IgY2FzZV9vcmRlcgotICAgICAgICAgICAgIC8vIGFyZ3VtZW50cy4gIFByb3ZpZGUgZGVmYXVsdCB2YWx1ZXMgaW4gdGhhdCBjYXNlIGZvciBiaW5hcnkKLSAgICAgICAgICAgICAvLyBjb21wYXRpYmlsaXR5LgotICAgICAgICAgICAgIFN0cmluZ1tdIGVtcHR5U3RyaW5nQXJyYXkgPSBudWxsOwotICAgICAgICAgICAgIGlmIChsYW5nID09IG51bGwgfHwgY2FzZU9yZGVyID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgaW50IG51bVNvcnRLZXlzID0gb3JkZXIubGVuZ3RoOwotICAgICAgICAgICAgICAgICBlbXB0eVN0cmluZ0FycmF5ID0gbmV3IFN0cmluZ1tudW1Tb3J0S2V5c107Ci0KLSAgICAgICAgICAgICAgICAgLy8gU2V0IHVwIGFycmF5IG9mIHplcm8tbGVuZ3RoIHN0cmluZ3MgYXMgZGVmYXVsdCB2YWx1ZXMKLSAgICAgICAgICAgICAgICAgLy8gb2YgbGFuZyBhbmQgY2FzZV9vcmRlcgotICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bVNvcnRLZXlzOyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgIGVtcHR5U3RyaW5nQXJyYXlbaV0gPSAiIjsKLSAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgIGlmIChsYW5nID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgbGFuZyA9IGVtcHR5U3RyaW5nQXJyYXk7Ci0gICAgICAgICAgICAgfQotICAgICAgICAgICAgIGlmIChjYXNlT3JkZXIgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICBjYXNlT3JkZXIgPSBlbXB0eVN0cmluZ0FycmF5OwotICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgIGZpbmFsIGludCBsZW5ndGggPSBsYW5nLmxlbmd0aDsKLSAgICAgICAgICAgICBMb2NhbGVbXSBsb2NhbGVzID0gbmV3IExvY2FsZVtsZW5ndGhdOwotICAgICAgICAgICAgIENvbGxhdG9yW10gY29sbGF0b3JzID0gbmV3IENvbGxhdG9yW2xlbmd0aF07Ci0gICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGk8IGxlbmd0aDsgaSsrKXsKLSAgICAgICAgICAgICAgICAgbG9jYWxlc1tpXSA9IExvY2FsZVV0aWxpdHkubGFuZ1RvTG9jYWxlKGxhbmdbaV0pOwotICAgICAgICAgICAgICAgICBjb2xsYXRvcnNbaV0gPSBDb2xsYXRvci5nZXRJbnN0YW5jZShsb2NhbGVzW2ldKTsKLSAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICBfc29ydFNldHRpbmdzID0gbmV3IFNvcnRTZXR0aW5ncygoQWJzdHJhY3RUcmFuc2xldCkgdHJhbnNsZXQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaU9yZGVyLCBpVHlwZSwgbG9jYWxlcywgY29sbGF0b3JzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2VPcmRlcik7Ci0gICAgICAgIH0gY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFRyYW5zbGV0RXhjZXB0aW9uKGUpOwotICAgICAgICB9Ci0gICAgfQotCi0KLQotICAgIC8qKgotICAgICAqIENyZWF0ZSBhbiBpbnN0YW5jZSBvZiBhIHN1Yi1jbGFzcyBvZiBOb2RlU29ydFJlY29yZC4gVGhlIG5hbWUgb2YgdGhpcwotICAgICAqIHN1Yi1jbGFzcyBpcyBwYXNzZWQgdG8gdXMgaW4gdGhlIGNvbnN0cnVjdG9yLgotICAgICAqLwotICAgIHB1YmxpYyBOb2RlU29ydFJlY29yZCBtYWtlTm9kZVNvcnRSZWNvcmQoaW50IG5vZGUsIGludCBsYXN0KQotICAgICAgICB0aHJvd3MgRXhjZXB0aW9uSW5Jbml0aWFsaXplckVycm9yLAotICAgICAgICAgICAgICAgTGlua2FnZUVycm9yLAotICAgICAgICAgICAgICAgSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiwKLSAgICAgICAgICAgICAgIEluc3RhbnRpYXRpb25FeGNlcHRpb24sCi0gICAgICAgICAgICAgICBTZWN1cml0eUV4Y2VwdGlvbiwKLSAgICAgICAgICAgICAgIFRyYW5zbGV0RXhjZXB0aW9uIHsKLQotICAgICAgICBmaW5hbCBOb2RlU29ydFJlY29yZCBzb3J0UmVjb3JkID0KLSAgICAgICAgICAgIChOb2RlU29ydFJlY29yZClfY2xhc3MubmV3SW5zdGFuY2UoKTsKLSAgICAgICAgc29ydFJlY29yZC5pbml0aWFsaXplKG5vZGUsIGxhc3QsIF9kb20sIF9zb3J0U2V0dGluZ3MpOwotICAgICAgICByZXR1cm4gc29ydFJlY29yZDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldENsYXNzTmFtZSgpIHsKLSAgICAgICAgcmV0dXJuIF9jbGFzc05hbWU7Ci0gICAgfQotCi0gICBwcml2YXRlIGZpbmFsIHZvaWQgc2V0TGFuZyhmaW5hbCBTdHJpbmcgbGFuZ1tdKXsKLQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvZG9tL050aEl0ZXJhdG9yLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2RvbS9OdGhJdGVyYXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2MTIxODhmLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvZG9tL050aEl0ZXJhdG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMTcgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogTnRoSXRlcmF0b3IuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8wNiAwOTo1NzowNCBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuZG9tOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnJ1bnRpbWUuQmFzaXNMaWJyYXJ5OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTUF4aXNJdGVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5yZWYuRFRNQXhpc0l0ZXJhdG9yQmFzZTsKLQotLyoqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBOdGhJdGVyYXRvciBleHRlbmRzIERUTUF4aXNJdGVyYXRvckJhc2UgewotICAgIC8vIC4uLltOXQotICAgIHByaXZhdGUgRFRNQXhpc0l0ZXJhdG9yIF9zb3VyY2U7Ci0gICAgcHJpdmF0ZSBmaW5hbCBpbnQgX3Bvc2l0aW9uOwotICAgIHByaXZhdGUgYm9vbGVhbiBfcmVhZHk7Ci0KLSAgICBwdWJsaWMgTnRoSXRlcmF0b3IoRFRNQXhpc0l0ZXJhdG9yIHNvdXJjZSwgaW50IG4pIHsKLSAgICAgICAgX3NvdXJjZSA9IHNvdXJjZTsKLSAgICAgICAgX3Bvc2l0aW9uID0gbjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRSZXN0YXJ0YWJsZShib29sZWFuIGlzUmVzdGFydGFibGUpIHsKLSAgICAgICAgX2lzUmVzdGFydGFibGUgPSBpc1Jlc3RhcnRhYmxlOwotICAgICAgICBfc291cmNlLnNldFJlc3RhcnRhYmxlKGlzUmVzdGFydGFibGUpOwotICAgIH0KLQotICAgIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3IgY2xvbmVJdGVyYXRvcigpIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGZpbmFsIE50aEl0ZXJhdG9yIGNsb25lID0gKE50aEl0ZXJhdG9yKSBzdXBlci5jbG9uZSgpOwotICAgICAgICAgICAgY2xvbmUuX3NvdXJjZSA9IF9zb3VyY2UuY2xvbmVJdGVyYXRvcigpOyAgICAvLyByZXNldHMgc291cmNlCi0gICAgICAgICAgICBjbG9uZS5faXNSZXN0YXJ0YWJsZSA9IGZhbHNlOwotICAgICAgICAgICAgcmV0dXJuIGNsb25lOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICBCYXNpc0xpYnJhcnkucnVuVGltZUVycm9yKEJhc2lzTGlicmFyeS5JVEVSQVRPUl9DTE9ORV9FUlIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGUudG9TdHJpbmcoKSk7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgbmV4dCgpIHsKLSAgICAgICAgaWYgKF9yZWFkeSkgewotICAgICAgICAgICAgX3JlYWR5ID0gZmFsc2U7Ci0gICAgICAgICAgICByZXR1cm4gX3NvdXJjZS5nZXROb2RlQnlQb3NpdGlvbihfcG9zaXRpb24pOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBEVE1BeGlzSXRlcmF0b3IuRU5EOwotICAgICAgICAvKgotICAgICAgICBpZiAoX3JlYWR5ICYmIF9wb3NpdGlvbiA+IDApIHsKLSAgICAgICAgICAgIGZpbmFsIGludCBwb3MgPSBfc291cmNlLmlzUmV2ZXJzZSgpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IF9zb3VyY2UuZ2V0TGFzdCgpIC0gX3Bvc2l0aW9uICsgMQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBfcG9zaXRpb247Ci0KLSAgICAgICAgICAgIF9yZWFkeSA9IGZhbHNlOwotICAgICAgICAgICAgaW50IG5vZGU7Ci0gICAgICAgICAgICB3aGlsZSAoKG5vZGUgPSBfc291cmNlLm5leHQoKSkgIT0gRFRNQXhpc0l0ZXJhdG9yLkVORCkgewotICAgICAgICAgICAgICAgIGlmIChwb3MgPT0gX3NvdXJjZS5nZXRQb3NpdGlvbigpKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBub2RlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gRFRNQXhpc0l0ZXJhdG9yLkVORDsKLSAgICAgICAgKi8KLSAgICB9Ci0KLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIHNldFN0YXJ0Tm9kZShmaW5hbCBpbnQgbm9kZSkgewotICAgICAgICBpZiAoX2lzUmVzdGFydGFibGUpIHsKLSAgICAgICAgICAgIF9zb3VyY2Uuc2V0U3RhcnROb2RlKG5vZGUpOwotICAgICAgICAgICAgX3JlYWR5ID0gdHJ1ZTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gdGhpczsKLSAgICB9Ci0KLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIHJlc2V0KCkgewotICAgICAgICBfc291cmNlLnJlc2V0KCk7Ci0gICAgICAgIF9yZWFkeSA9IHRydWU7Ci0gICAgICAgIHJldHVybiB0aGlzOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgZ2V0TGFzdCgpIHsKLSAgICAgICAgcmV0dXJuIDE7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBnZXRQb3NpdGlvbigpIHsKLSAgICAgICAgcmV0dXJuIDE7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0TWFyaygpIHsKLSAgICAgICAgX3NvdXJjZS5zZXRNYXJrKCk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgZ290b01hcmsoKSB7Ci0gICAgICAgIF9zb3VyY2UuZ290b01hcmsoKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2RvbS9TQVhJbXBsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2RvbS9TQVhJbXBsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDI5MTliOWIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vU0FYSW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTg4MiArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDE1LCAyMDE2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICovCi0vKgotICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCi0gKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKLSAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KLSAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCi0gKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAotICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuZG9tOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLkRPTTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuRE9NRW5oYW5jZWRGb3JEVE07Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLlN0cmlwRmlsdGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5UcmFuc2xldEV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMucnVudGltZS5CYXNpc0xpYnJhcnk7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uQXhpczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE07Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNQXhpc0l0ZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTU1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNV1NGaWx0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0ucmVmLkRUTUF4aXNJdGVyTm9kZUxpc3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0ucmVmLkRUTURlZmF1bHRCYXNlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLnJlZi5EVE1Ob2RlUHJveHk7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0ucmVmLkVtcHR5SXRlcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0ucmVmLnNheDJkdG0uU0FYMkRUTTI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyLlNlcmlhbGl6YXRpb25IYW5kbGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplci5Ub1hNTFNBWEhhbmRsZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5TeXN0ZW1JRFJlc29sdmVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuWE1MU3RyaW5nRmFjdG9yeTsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKLWltcG9ydCBqYXZhLnV0aWwuTWFwOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uU291cmNlOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uZG9tLkRPTVNvdXJjZTsKLWltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKLWltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudFR5cGU7Ci1pbXBvcnQgb3JnLnczYy5kb20uRW50aXR5OwotaW1wb3J0IG9yZy53M2MuZG9tLk5hbWVkTm9kZU1hcDsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGVMaXN0OwotaW1wb3J0IG9yZy54bWwuc2F4LkF0dHJpYnV0ZXM7Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotCi0KLS8qKgotICogU0FYSW1wbCBpcyB0aGUgY29yZSBtb2RlbCBmb3IgU0FYIGlucHV0IHNvdXJjZS4gU0FYSW1wbCBvYmplY3RzIGFyZQotICogdXN1YWxseSBjcmVhdGVkIGZyb20gYW4gWFNMVENEVE1NYW5hZ2VyLgotICoKLSAqIDxwPkRPTVNvdXJjZSBpbnB1dHMgYXJlIGhhbmRsZWQgdXNpbmcgRE9NMlNBWCArIFNBWEltcGwuIFNBWEltcGwgaGFzIGEKLSAqIGZldyBzcGVjaWZpYyBmaWVsZHMgKGUuZy4gX25vZGUySWRzLCBfZG9jdW1lbnQpIHRvIGtlZXAgRE9NLXJlbGF0ZWQKLSAqIGluZm9ybWF0aW9uLiBUaGV5IGFyZSB1c2VkIHdoZW4gdGhlIHByb2Nlc3NpbmcgYmVoYXZpb3IgYmV0d2VlbiBET00gYW5kCi0gKiBTQVggaGFzIHRvIGJlIGRpZmZlcmVudC4gRXhhbXBsZXMgb2YgdGhlc2UgaW5jbHVkZSBpZCBmdW5jdGlvbiBhbmQKLSAqIHVucGFyc2VkIGVudGl0eS4KLSAqCi0gKiA8cD5TQVhJbXBsIGV4dGVuZHMgU0FYMkRUTTIgaW5zdGVhZCBvZiBTQVgyRFRNIGZvciBiZXR0ZXIgcGVyZm9ybWFuY2UuCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqIEBhdXRob3IgRG91Z2xhcyBTZWxsZXJzIDxkb3VnbGFzanNlbGxlcnNAaG90bWFpbC5jb20+Ci0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBTQVhJbXBsIGV4dGVuZHMgU0FYMkRUTTIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgIGltcGxlbWVudHMgRE9NRW5oYW5jZWRGb3JEVE0sIERPTUJ1aWxkZXIKLXsKLQotICAgIC8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KLSAgICAvKiBET01CdWlsZGVyIGZpZWxkcyBCRUdJTiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi0gICAgLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwotCi0gICAgLy8gTmFtZXNwYWNlIHByZWZpeC10by11cmkgbWFwcGluZyBzdHVmZgotICAgIHByaXZhdGUgaW50ICAgICAgIF91cmlDb3VudCAgICAgPSAwOwotICAgIC8vIHByaXZhdGUgaW50ICAgICAgIF9wcmVmaXhDb3VudCAgPSAwOwotCi0gICAgLy8gU3RhY2sgdXNlZCB0byBrZWVwIHRyYWNrIG9mIHdoYXQgd2hpdGVzcGFjZSB0ZXh0IG5vZGVzIGFyZSBwcm90ZWN0ZWQKLSAgICAvLyBieSB4bWw6c3BhY2U9InByZXNlcnZlIiBhdHRyaWJ1dGVzIGFuZCB3aGljaCBub2RlcyB0aGF0IGFyZSBub3QuCi0gICAgcHJpdmF0ZSBpbnRbXSAgIF94bWxTcGFjZVN0YWNrOwotICAgIHByaXZhdGUgaW50ICAgICBfaWR4ID0gMTsKLSAgICBwcml2YXRlIGJvb2xlYW4gX3ByZXNlcnZlID0gZmFsc2U7Ci0KLSAgICAvLyBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MX1NUUklORyA9ICJ4bWw6IjsKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MX1BSRUZJWCAgID0gInhtbCI7Ci0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFhNTFNQQUNFX1NUUklORyA9ICJ4bWw6c3BhY2UiOwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBQUkVTRVJWRV9TVFJJTkcgPSAicHJlc2VydmUiOwotICAgIC8vIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxOU19QUkVGSVggPSAieG1sbnMiOwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxfVVJJID0gImh0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZSI7Ci0KLSAgICBwcml2YXRlIGJvb2xlYW4gX2VzY2FwaW5nID0gdHJ1ZTsKLSAgICBwcml2YXRlIGJvb2xlYW4gX2Rpc2FibGVFc2NhcGluZyA9IGZhbHNlOwotICAgIHByaXZhdGUgaW50IF90ZXh0Tm9kZVRvUHJvY2VzcyA9IERUTS5OVUxMOwotCi0gICAgLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwotICAgIC8qIERPTUJ1aWxkZXIgZmllbGRzIEVORCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLSAgICAvKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCi0KLSAgICAvLyBlbXB0eSBTdHJpbmcgZm9yIG51bGwgYXR0cmlidXRlIHZhbHVlcwotICAgIHByaXZhdGUgZmluYWwgc3RhdGljIFN0cmluZyBFTVBUWVNUUklORyA9ICIiOwotCi0gICAgLy8gZW1wdHkgaXRlcmF0b3IgdG8gYmUgcmV0dXJuZWQgd2hlbiB0aGVyZSBhcmUgbm8gY2hpbGRyZW4KLSAgICBwcml2YXRlIGZpbmFsIHN0YXRpYyBEVE1BeGlzSXRlcmF0b3IgRU1QVFlJVEVSQVRPUiA9IEVtcHR5SXRlcmF0b3IuZ2V0SW5zdGFuY2UoKTsKLSAgICAvLyBUaGUgbnVtYmVyIG9mIGV4cGFuZGVkIG5hbWVzCi0gICAgcHJpdmF0ZSBpbnQgX25hbWVzU2l6ZSA9IC0xOwotCi0gICAgLy8gTmFtZXNwYWNlIHJlbGF0ZWQgc3R1ZmYKLSAgICBwcml2YXRlIE1hcDxJbnRlZ2VyLCBJbnRlZ2VyPiBfbnNJbmRleCA9IG5ldyBIYXNoTWFwPD4oKTsKLQotICAgIC8vIFRoZSBpbml0aWFsIHNpemUgb2YgdGhlIHRleHQgYnVmZmVyCi0gICAgcHJpdmF0ZSBpbnQgX3NpemUgPSAwOwotCi0gICAgLy8gVHJhY2tzIHdoaWNoIHRleHRub2RlcyBhcmUgbm90IGVzY2FwZWQKLSAgICBwcml2YXRlIEJpdEFycmF5ICBfZG9udEVzY2FwZSA9IG51bGw7Ci0KLSAgICAvLyBUaGUgVVJJIHRvIHRoaXMgZG9jdW1lbnQKLSAgICAvLyBwcml2YXRlIFN0cmluZyBfZG9jdW1lbnRVUkkgPSBudWxsOwotICAgIHN0YXRpYyBwcml2YXRlIGludCBfZG9jdW1lbnRVUklJbmRleCA9IDA7Ci0KLSAgICAvLyBUaGUgb3duZXIgRG9jdW1lbnQgd2hlbiB0aGUgaW5wdXQgc291cmNlIGlzIERPTVNvdXJjZS4KLSAgICBwcml2YXRlIERvY3VtZW50IF9kb2N1bWVudDsKLQotICAgIC8vIFRoZSBNYXAgZm9yIG9yZy53M2MuZG9tLk5vZGUgdG8gbm9kZSBpZCBtYXBwaW5nLgotICAgIC8vIFRoaXMgaXMgb25seSB1c2VkIHdoZW4gdGhlIGlucHV0IGlzIGEgRE9NU291cmNlIGFuZCB0aGUKLSAgICAvLyBidWlsZElkSW5kZXggZmxhZyBpcyB0cnVlLgotICAgIHByaXZhdGUgTWFwPE5vZGUsIEludGVnZXI+IF9ub2RlMklkcyA9IG51bGw7Ci0KLSAgICAvLyBUcnVlIGlmIHRoZSBpbnB1dCBzb3VyY2UgaXMgYSBET01Tb3VyY2UuCi0gICAgcHJpdmF0ZSBib29sZWFuIF9oYXNET01Tb3VyY2UgPSBmYWxzZTsKLQotICAgIC8vIFRoZSBEVE1NYW5hZ2VyCi0gICAgcHJpdmF0ZSBYU0xUQ0RUTU1hbmFnZXIgX2R0bU1hbmFnZXI7Ci0KLSAgICAvLyBTdXBwb3J0IGZvciBhY2Nlc3MvbmF2aWdhdGlvbiB0aHJvdWdoIG9yZy53M2MuZG9tIEFQSQotICAgIHByaXZhdGUgTm9kZVtdIF9ub2RlczsKLSAgICBwcml2YXRlIE5vZGVMaXN0W10gX25vZGVMaXN0czsKLSAgICAvLyBwcml2YXRlIGZpbmFsIHN0YXRpYyBTdHJpbmcgWE1MX0xBTkdfQVRUUklCVVRFID0gImh0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZTpAbGFuZyI7Ci0KLSAgICAvKioKLSAgICAgKiBEZWZpbmUgdGhlIG9yaWdpbiBvZiB0aGUgZG9jdW1lbnQgZnJvbSB3aGljaCB0aGUgdHJlZSB3YXMgYnVpbHQKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXREb2N1bWVudFVSSShTdHJpbmcgdXJpKSB7Ci0gICAgICAgIGlmICh1cmkgIT0gbnVsbCkgewotICAgICAgICAgICAgc2V0RG9jdW1lbnRCYXNlVVJJKFN5c3RlbUlEUmVzb2x2ZXIuZ2V0QWJzb2x1dGVVUkkodXJpKSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBvcmlnaW4gb2YgdGhlIGRvY3VtZW50IGZyb20gd2hpY2ggdGhlIHRyZWUgd2FzIGJ1aWx0Ci0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXREb2N1bWVudFVSSSgpIHsKLSAgICAgICAgU3RyaW5nIGJhc2VVUkkgPSBnZXREb2N1bWVudEJhc2VVUkkoKTsKLSAgICAgICAgcmV0dXJuIChiYXNlVVJJICE9IG51bGwpID8gYmFzZVVSSSA6ICJydGYiICsgX2RvY3VtZW50VVJJSW5kZXgrKzsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldERvY3VtZW50VVJJKGludCBub2RlKSB7Ci0gICAgICAgIHJldHVybiBnZXREb2N1bWVudFVSSSgpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldHVwTWFwcGluZyhTdHJpbmdbXSBuYW1lcywgU3RyaW5nW10gdXJpc0FycmF5LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnRbXSB0eXBlc0FycmF5LCBTdHJpbmdbXSBuYW1lc3BhY2VzKSB7Ci0gICAgICAgIC8vIFRoaXMgbWV0aG9kIG9ubHkgaGFzIGEgZnVuY3Rpb24gaW4gRE9NIGFkYXB0ZXJzCi0gICAgfQotCi0gICAgLyoqCi0gICAgICogTG9va3VwIGEgbmFtZXNwYWNlIFVSSSBmcm9tIGEgcHJlZml4IHN0YXJ0aW5nIGF0IG5vZGUuIFRoaXMgbWV0aG9kCi0gICAgICogaXMgdXNlZCBpbiB0aGUgZXhlY3V0aW9uIG9mIHhzbDplbGVtZW50IHdoZW4gdGhlIHByZWZpeCBpcyBub3Qga25vd24KLSAgICAgKiBhdCBjb21waWxlIHRpbWUuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBsb29rdXBOYW1lc3BhY2UoaW50IG5vZGUsIFN0cmluZyBwcmVmaXgpCi0gICAgICAgIHRocm93cyBUcmFuc2xldEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaW50IGFub2RlLCBuc25vZGU7Ci0gICAgICAgIGZpbmFsIEFuY2VzdG9ySXRlcmF0b3IgYW5jZXN0b3JzID0gbmV3IEFuY2VzdG9ySXRlcmF0b3IoKTsKLQotICAgICAgICBpZiAoaXNFbGVtZW50KG5vZGUpKSB7Ci0gICAgICAgICAgICBhbmNlc3RvcnMuaW5jbHVkZVNlbGYoKTsKLSAgICAgICAgfQotCi0gICAgICAgIGFuY2VzdG9ycy5zZXRTdGFydE5vZGUobm9kZSk7Ci0gICAgICAgIHdoaWxlICgoYW5vZGUgPSBhbmNlc3RvcnMubmV4dCgpKSAhPSBEVE0uTlVMTCkgewotICAgICAgICAgICAgZmluYWwgTmFtZXNwYWNlSXRlcmF0b3IgbmFtZXNwYWNlcyA9IG5ldyBOYW1lc3BhY2VJdGVyYXRvcigpOwotCi0gICAgICAgICAgICBuYW1lc3BhY2VzLnNldFN0YXJ0Tm9kZShhbm9kZSk7Ci0gICAgICAgICAgICB3aGlsZSAoKG5zbm9kZSA9IG5hbWVzcGFjZXMubmV4dCgpKSAhPSBEVE0uTlVMTCkgewotICAgICAgICAgICAgICAgIGlmIChnZXRMb2NhbE5hbWUobnNub2RlKS5lcXVhbHMocHJlZml4KSkgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gZ2V0Tm9kZVZhbHVlKG5zbm9kZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgQmFzaXNMaWJyYXJ5LnJ1blRpbWVFcnJvcihCYXNpc0xpYnJhcnkuTkFNRVNQQUNFX1BSRUZJWF9FUlIsIHByZWZpeCk7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgJ3RydWUnIGlmIGEgc3BlY2lmaWMgbm9kZSBpcyBhbiBlbGVtZW50IChvZiBhbnkgdHlwZSkKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0VsZW1lbnQoZmluYWwgaW50IG5vZGUpIHsKLSAgICAgICAgcmV0dXJuIGdldE5vZGVUeXBlKG5vZGUpID09IERUTS5FTEVNRU5UX05PREU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyAndHJ1ZScgaWYgYSBzcGVjaWZpYyBub2RlIGlzIGFuIGF0dHJpYnV0ZSAob2YgYW55IHR5cGUpCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNBdHRyaWJ1dGUoZmluYWwgaW50IG5vZGUpIHsKLSAgICAgICAgcmV0dXJuIGdldE5vZGVUeXBlKG5vZGUpID09IERUTS5BVFRSSUJVVEVfTk9ERTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2Ygbm9kZXMgaW4gdGhlIHRyZWUgKHVzZWQgZm9yIGluZGV4aW5nKQotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0U2l6ZSgpIHsKLSAgICAgICAgcmV0dXJuIGdldE51bWJlck9mTm9kZXMoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBQYXJ0IG9mIHRoZSBET00gaW50ZXJmYWNlIC0gbm8gZnVuY3Rpb24gaGVyZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRGaWx0ZXIoU3RyaXBGaWx0ZXIgZmlsdGVyKSB7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRydWUgaWYgbm9kZTEgY29tZXMgYmVmb3JlIG5vZGUyIGluIGRvY3VtZW50IG9yZGVyCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gbGVzc1RoYW4oaW50IG5vZGUxLCBpbnQgbm9kZTIpIHsKLSAgICAgICAgaWYgKG5vZGUxID09IERUTS5OVUxMKSB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAobm9kZTIgPT0gRFRNLk5VTEwpIHsKLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIChub2RlMSA8IG5vZGUyKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGUgYW4gb3JnLnczYy5kb20uTm9kZSBmcm9tIGEgbm9kZSBpbiB0aGUgdHJlZQotICAgICAqLwotICAgIHB1YmxpYyBOb2RlIG1ha2VOb2RlKGludCBpbmRleCkgewotICAgICAgICBpZiAoX25vZGVzID09IG51bGwpIHsKLSAgICAgICAgICAgIF9ub2RlcyA9IG5ldyBOb2RlW19uYW1lc1NpemVdOwotICAgICAgICB9Ci0KLSAgICAgICAgaW50IG5vZGVJRCA9IG1ha2VOb2RlSWRlbnRpdHkoaW5kZXgpOwotICAgICAgICBpZiAobm9kZUlEIDwgMCkgewotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAobm9kZUlEIDwgX25vZGVzLmxlbmd0aCkgewotICAgICAgICAgICAgcmV0dXJuIChfbm9kZXNbbm9kZUlEXSAhPSBudWxsKSA/IF9ub2Rlc1tub2RlSURdCi0gICAgICAgICAgICAgICAgOiAoX25vZGVzW25vZGVJRF0gPSBuZXcgRFRNTm9kZVByb3h5KChEVE0pdGhpcywgaW5kZXgpKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiBuZXcgRFRNTm9kZVByb3h5KChEVE0pdGhpcywgaW5kZXgpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlIGFuIG9yZy53M2MuZG9tLk5vZGUgZnJvbSBhIG5vZGUgaW4gYW4gaXRlcmF0b3IKLSAgICAgKiBUaGUgaXRlcmF0b3IgbW9zdCBiZSBzdGFydGVkIGJlZm9yZSB0aGlzIG1ldGhvZCBpcyBjYWxsZWQKLSAgICAgKi8KLSAgICBwdWJsaWMgTm9kZSBtYWtlTm9kZShEVE1BeGlzSXRlcmF0b3IgaXRlcikgewotICAgICAgICByZXR1cm4gbWFrZU5vZGUoaXRlci5uZXh0KCkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENyZWF0ZSBhbiBvcmcudzNjLmRvbS5Ob2RlTGlzdCBmcm9tIGEgbm9kZSBpbiB0aGUgdHJlZQotICAgICAqLwotICAgIHB1YmxpYyBOb2RlTGlzdCBtYWtlTm9kZUxpc3QoaW50IGluZGV4KSB7Ci0gICAgICAgIGlmIChfbm9kZUxpc3RzID09IG51bGwpIHsKLSAgICAgICAgICAgIF9ub2RlTGlzdHMgPSBuZXcgTm9kZUxpc3RbX25hbWVzU2l6ZV07Ci0gICAgICAgIH0KLQotICAgICAgICBpbnQgbm9kZUlEID0gbWFrZU5vZGVJZGVudGl0eShpbmRleCk7Ci0gICAgICAgIGlmIChub2RlSUQgPCAwKSB7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChub2RlSUQgPCBfbm9kZUxpc3RzLmxlbmd0aCkgewotICAgICAgICAgICAgcmV0dXJuIChfbm9kZUxpc3RzW25vZGVJRF0gIT0gbnVsbCkgPyBfbm9kZUxpc3RzW25vZGVJRF0KLSAgICAgICAgICAgICAgICAgICA6IChfbm9kZUxpc3RzW25vZGVJRF0gPSBuZXcgRFRNQXhpc0l0ZXJOb2RlTGlzdCh0aGlzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBTaW5nbGV0b25JdGVyYXRvcihpbmRleCkpKTsKLSAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIG5ldyBEVE1BeGlzSXRlck5vZGVMaXN0KHRoaXMsIG5ldyBTaW5nbGV0b25JdGVyYXRvcihpbmRleCkpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlIGFuIG9yZy53M2MuZG9tLk5vZGVMaXN0IGZyb20gYSBub2RlIGl0ZXJhdG9yCi0gICAgICogVGhlIGl0ZXJhdG9yIG1vc3QgYmUgc3RhcnRlZCBiZWZvcmUgdGhpcyBtZXRob2QgaXMgY2FsbGVkCi0gICAgICovCi0gICAgcHVibGljIE5vZGVMaXN0IG1ha2VOb2RlTGlzdChEVE1BeGlzSXRlcmF0b3IgaXRlcikgewotICAgICAgICByZXR1cm4gbmV3IERUTUF4aXNJdGVyTm9kZUxpc3QodGhpcywgaXRlcik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSXRlcmF0b3IgdGhhdCByZXR1cm5zIHRoZSBuYW1lc3BhY2Ugbm9kZXMgYXMgZGVmaW5lZCBieSB0aGUgWFBhdGggZGF0YQotICAgICAqIG1vZGVsIGZvciBhIGdpdmVuIG5vZGUsIGZpbHRlcmVkIGJ5IGV4dGVuZGVkIHR5cGUgSUQuCi0gICAgICovCi0gICAgcHVibGljIGNsYXNzIFR5cGVkTmFtZXNwYWNlSXRlcmF0b3IgZXh0ZW5kcyBOYW1lc3BhY2VJdGVyYXRvciB7Ci0KLSAgICAgICAgcHJpdmF0ZSAgU3RyaW5nIF9uc1ByZWZpeDsKLQotICAgICAgICAvKioKLSAgICAgICAgICogQ29uc3RydWN0b3IgVHlwZWRDaGlsZHJlbkl0ZXJhdG9yCi0gICAgICAgICAqCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBub2RlVHlwZSBUaGUgZXh0ZW5kZWQgdHlwZSBJRCBiZWluZyByZXF1ZXN0ZWQuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgVHlwZWROYW1lc3BhY2VJdGVyYXRvcihpbnQgbm9kZVR5cGUpIHsKLSAgICAgICAgICAgIHN1cGVyKCk7Ci0gICAgICAgICAgICBpZihtX2V4cGFuZGVkTmFtZVRhYmxlICE9IG51bGwpewotICAgICAgICAgICAgICAgIF9uc1ByZWZpeCA9IG1fZXhwYW5kZWROYW1lVGFibGUuZ2V0TG9jYWxOYW1lKG5vZGVUeXBlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgLyoqCi0gICAgICAgICogR2V0IHRoZSBuZXh0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbi4KLSAgICAgICAgKgotICAgICAgICAqIEByZXR1cm4gVGhlIG5leHQgbm9kZSBoYW5kbGUgaW4gdGhlIGl0ZXJhdGlvbiwgb3IgRU5ELgotICAgICAgICAqLwotICAgICAgICBwdWJsaWMgaW50IG5leHQoKSB7Ci0gICAgICAgICAgICBpZiAoKF9uc1ByZWZpeCA9PSBudWxsKSB8fChfbnNQcmVmaXgubGVuZ3RoKCkgPT0gMCkgKXsKLSAgICAgICAgICAgICAgICByZXR1cm4gKEVORCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpbnQgbm9kZSA9IEVORDsKLSAgICAgICAgICAgIGZvciAobm9kZSA9IHN1cGVyLm5leHQoKTsgbm9kZSAhPSBFTkQ7IG5vZGUgPSBzdXBlci5uZXh0KCkpIHsKLSAgICAgICAgICAgICAgICBpZiAoX25zUHJlZml4LmNvbXBhcmVUbyhnZXRMb2NhbE5hbWUobm9kZSkpPT0gMCkgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmV0dXJuTm9kZShub2RlKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gKEVORCk7Ci0gICAgICAgIH0KLSAgICB9ICAvLyBlbmQgb2YgVHlwZWROYW1lc3BhY2VJdGVyYXRvcgotCi0KLQotICAgIC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgotICAgICAqIFRoaXMgaXMgYSBzcGVjaWFsaXNlZCBpdGVyYXRvciBmb3IgcHJlZGljYXRlcyBjb21wYXJpbmcgbm9kZSBvcgotICAgICAqIGF0dHJpYnV0ZSB2YWx1ZXMgdG8gdmFyaWFibGUgb3IgcGFyYW1ldGVyIHZhbHVlcy4KLSAgICAgKi8KLSAgICBwcml2YXRlIGZpbmFsIGNsYXNzIE5vZGVWYWx1ZUl0ZXJhdG9yIGV4dGVuZHMgSW50ZXJuYWxBeGlzSXRlcmF0b3JCYXNlCi0gICAgewotCi0gICAgICAgIHByaXZhdGUgRFRNQXhpc0l0ZXJhdG9yIF9zb3VyY2U7Ci0gICAgICAgIHByaXZhdGUgU3RyaW5nIF92YWx1ZTsKLSAgICAgICAgcHJpdmF0ZSBib29sZWFuIF9vcDsKLSAgICAgICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIF9pc1JldmVyc2U7Ci0gICAgICAgIHByaXZhdGUgaW50IF9yZXR1cm5UeXBlID0gUkVUVVJOX1BBUkVOVDsKLQotICAgICAgICBwdWJsaWMgTm9kZVZhbHVlSXRlcmF0b3IoRFRNQXhpc0l0ZXJhdG9yIHNvdXJjZSwgaW50IHJldHVyblR5cGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdmFsdWUsIGJvb2xlYW4gb3ApCi0gICAgICAgIHsKLSAgICAgICAgICAgIF9zb3VyY2UgPSBzb3VyY2U7Ci0gICAgICAgICAgICBfcmV0dXJuVHlwZSA9IHJldHVyblR5cGU7Ci0gICAgICAgICAgICBfdmFsdWUgPSB2YWx1ZTsKLSAgICAgICAgICAgIF9vcCA9IG9wOwotICAgICAgICAgICAgX2lzUmV2ZXJzZSA9IHNvdXJjZS5pc1JldmVyc2UoKTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyBib29sZWFuIGlzUmV2ZXJzZSgpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHJldHVybiBfaXNSZXZlcnNlOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIERUTUF4aXNJdGVyYXRvciBjbG9uZUl0ZXJhdG9yKCkKLSAgICAgICAgewotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICBOb2RlVmFsdWVJdGVyYXRvciBjbG9uZSA9IChOb2RlVmFsdWVJdGVyYXRvcilzdXBlci5jbG9uZSgpOwotICAgICAgICAgICAgICAgIGNsb25lLl9pc1Jlc3RhcnRhYmxlID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgY2xvbmUuX3NvdXJjZSA9IF9zb3VyY2UuY2xvbmVJdGVyYXRvcigpOwotICAgICAgICAgICAgICAgIGNsb25lLl92YWx1ZSA9IF92YWx1ZTsKLSAgICAgICAgICAgICAgICBjbG9uZS5fb3AgPSBfb3A7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGNsb25lLnJlc2V0KCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXRjaCAoQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgIEJhc2lzTGlicmFyeS5ydW5UaW1lRXJyb3IoQmFzaXNMaWJyYXJ5LklURVJBVE9SX0NMT05FX0VSUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGUudG9TdHJpbmcoKSk7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCBzZXRSZXN0YXJ0YWJsZShib29sZWFuIGlzUmVzdGFydGFibGUpCi0gICAgICAgIHsKLSAgICAgICAgICAgIF9pc1Jlc3RhcnRhYmxlID0gaXNSZXN0YXJ0YWJsZTsKLSAgICAgICAgICAgIF9zb3VyY2Uuc2V0UmVzdGFydGFibGUoaXNSZXN0YXJ0YWJsZSk7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIHJlc2V0KCkKLSAgICAgICAgewotICAgICAgICAgICAgX3NvdXJjZS5yZXNldCgpOwotICAgICAgICAgICAgcmV0dXJuIHJlc2V0UG9zaXRpb24oKTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyBpbnQgbmV4dCgpCi0gICAgICAgIHsKLSAgICAgICAgICAgIGludCBub2RlOwotICAgICAgICAgICAgd2hpbGUgKChub2RlID0gX3NvdXJjZS5uZXh0KCkpICE9IEVORCkgewotICAgICAgICAgICAgICAgIFN0cmluZyB2YWwgPSBnZXRTdHJpbmdWYWx1ZVgobm9kZSk7Ci0gICAgICAgICAgICAgICAgaWYgKF92YWx1ZS5lcXVhbHModmFsKSA9PSBfb3ApIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKF9yZXR1cm5UeXBlID09IFJFVFVSTl9DVVJSRU5UKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmV0dXJuTm9kZShub2RlKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXR1cm5Ob2RlKGdldFBhcmVudChub2RlKSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gRU5EOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIERUTUF4aXNJdGVyYXRvciBzZXRTdGFydE5vZGUoaW50IG5vZGUpCi0gICAgICAgIHsKLSAgICAgICAgICAgIGlmIChfaXNSZXN0YXJ0YWJsZSkgewotICAgICAgICAgICAgICAgIF9zb3VyY2Uuc2V0U3RhcnROb2RlKF9zdGFydE5vZGUgPSBub2RlKTsKLSAgICAgICAgICAgICAgICByZXR1cm4gcmVzZXRQb3NpdGlvbigpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIHRoaXM7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCBzZXRNYXJrKCkKLSAgICAgICAgewotICAgICAgICAgICAgX3NvdXJjZS5zZXRNYXJrKCk7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCBnb3RvTWFyaygpCi0gICAgICAgIHsKLSAgICAgICAgICAgIF9zb3VyY2UuZ290b01hcmsoKTsKLSAgICAgICAgfQotICAgIH0gLy8gZW5kIE5vZGVWYWx1ZUl0ZXJhdG9yCi0KLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIGdldE5vZGVWYWx1ZUl0ZXJhdG9yKERUTUF4aXNJdGVyYXRvciBpdGVyYXRvciwgaW50IHR5cGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdmFsdWUsIGJvb2xlYW4gb3ApCi0gICAgewotICAgICAgICByZXR1cm4oRFRNQXhpc0l0ZXJhdG9yKShuZXcgTm9kZVZhbHVlSXRlcmF0b3IoaXRlcmF0b3IsIHR5cGUsIHZhbHVlLCBvcCkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEVuY2Fwc3VsYXRlcyBhbiBpdGVyYXRvciBpbiBhbiBPcmRlcmVkSXRlcmF0b3IgdG8gZW5zdXJlIG5vZGUgb3JkZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIG9yZGVyTm9kZXMoRFRNQXhpc0l0ZXJhdG9yIHNvdXJjZSwgaW50IG5vZGUpCi0gICAgewotICAgICAgICByZXR1cm4gbmV3IER1cEZpbHRlckl0ZXJhdG9yKHNvdXJjZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBzaW5nbGV0b24gaXRlcmF0b3IgY29udGFpbmcgdGhlIGRvY3VtZW50IHJvb3QKLSAgICAgKiBXb3JrcyBmb3IgdGhlbSBtYWluIGRvY3VtZW50IChtYXJrID09IDApLiAgSXQgY2Fubm90IGJlIG1hZGUKLSAgICAgKiB0byBwb2ludCB0byBhbnkgb3RoZXIgbm9kZSB0aHJvdWdoIHNldFN0YXJ0Tm9kZSgpLgotICAgICAqLwotICAgIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3IgZ2V0SXRlcmF0b3IoKQotICAgIHsKLSAgICAgICAgcmV0dXJuIG5ldyBTaW5nbGV0b25JdGVyYXRvcihnZXREb2N1bWVudCgpLCB0cnVlKTsKLSAgICB9Ci0KLSAgICAgLyoqCi0gICAgICogR2V0IG1hcHBpbmcgZnJvbSBET00gbmFtZXNwYWNlIHR5cGVzIHRvIGV4dGVybmFsIG5hbWVzcGFjZSB0eXBlcwotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0TlNUeXBlKGludCBub2RlKQotICAgIHsKLSAgICAgICAgU3RyaW5nIHMgPSBnZXROYW1lc3BhY2VVUkkobm9kZSk7Ci0gICAgICAgIGlmIChzID09IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiAwOwotICAgICAgICB9Ci0gICAgICAgIGludCBlVHlwZSA9IGdldElkRm9yTmFtZXNwYWNlKHMpOwotICAgICAgICByZXR1cm4gX25zSW5kZXguZ2V0KG5ldyBJbnRlZ2VyKGVUeXBlKSk7Ci0gICAgfQotCi0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIG5hbWVzcGFjZSB0eXBlIG9mIGEgc3BlY2lmaWMgbm9kZQotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0TmFtZXNwYWNlVHlwZShmaW5hbCBpbnQgbm9kZSkKLSAgICB7Ci0gICAgICAgIHJldHVybiBzdXBlci5nZXROYW1lc3BhY2VUeXBlKG5vZGUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldHMgdXAgYSB0cmFuc2xldC10by1kb20gdHlwZSBtYXBwaW5nIHRhYmxlCi0gICAgICovCi0gICAgLyoKLSAgICBwcml2YXRlIGludFtdIHNldHVwTWFwcGluZyhTdHJpbmdbXSBuYW1lcywgU3RyaW5nW10gdXJpcywgaW50W10gdHlwZXMsIGludCBuTmFtZXMpIHsKLSAgICAgICAgLy8gUGFkZGluZyB3aXRoIG51bWJlciBvZiBuYW1lcywgYmVjYXVzZSB0aGV5Ci0gICAgICAgIC8vIG1heSBuZWVkIHRvIGJlIGFkZGVkLCBpLmUgZm9yIFJURnMuIFNlZSBjb3B5MDMKLSAgICAgICAgZmluYWwgaW50W10gcmVzdWx0ID0gbmV3IGludFttX2V4cGFuZGVkTmFtZVRhYmxlLmdldFNpemUoKV07Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbk5hbWVzOyBpKyspICAgICAgewotICAgICAgICAgICAgLy9pbnQgdHlwZSA9IGdldEdlbmVyYWxpemVkVHlwZShuYW1lc0FycmF5W2ldKTsKLSAgICAgICAgICAgIGludCB0eXBlID0gbV9leHBhbmRlZE5hbWVUYWJsZS5nZXRFeHBhbmRlZFR5cGVJRCh1cmlzW2ldLCBuYW1lc1tpXSwgdHlwZXNbaV0sIGZhbHNlKTsKLSAgICAgICAgICAgIHJlc3VsdFt0eXBlXSA9IHR5cGU7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHJlc3VsdDsKLSAgICB9Ci0gICAgKi8KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIGludGVybmFsIHR5cGUgYXNzb2NpYXRlZCB3aXRoIGFuIGV4cGFuZGVkIFFOYW1lCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRHZW5lcmFsaXplZFR5cGUoZmluYWwgU3RyaW5nIG5hbWUpIHsKLSAgICAgICAgcmV0dXJuIGdldEdlbmVyYWxpemVkVHlwZShuYW1lLCB0cnVlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBpbnRlcm5hbCB0eXBlIGFzc29jaWF0ZWQgd2l0aCBhbiBleHBhbmRlZCBRTmFtZQotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0R2VuZXJhbGl6ZWRUeXBlKGZpbmFsIFN0cmluZyBuYW1lLCBib29sZWFuIHNlYXJjaE9ubHkpIHsKLSAgICAgICAgU3RyaW5nIGxOYW1lLCBucyA9IG51bGw7Ci0gICAgICAgIGludCBpbmRleCA9IC0xOwotICAgICAgICBpbnQgY29kZTsKLQotICAgICAgICAvLyBJcyB0aGVyZSBhIHByZWZpeD8KLSAgICAgICAgaWYgKChpbmRleCA9IG5hbWUubGFzdEluZGV4T2YoIjoiKSk+IC0xKSB7Ci0gICAgICAgICAgICBucyA9IG5hbWUuc3Vic3RyaW5nKDAsIGluZGV4KTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIExvY2FsIHBhcnQgb2YgbmFtZSBpcyBhZnRlciBjb2xvbi4gIGxhc3RJbmRleE9mIHJldHVybnMgLTEgaWYKLSAgICAgICAgLy8gdGhlcmUgaXMgbm8gY29sb24sIHNvIGxOYW1lU3RhcnRJZHggd2lsbCBiZSB6ZXJvIGluIHRoYXQgY2FzZS4KLSAgICAgICAgaW50IGxOYW1lU3RhcnRJZHggPSBpbmRleCsxOwotCi0gICAgICAgIC8vIERpc3Rpbmd1aXNoIGF0dHJpYnV0ZSBhbmQgZWxlbWVudCBuYW1lcy4gIEF0dHJpYnV0ZSBoYXMgQCBiZWZvcmUKLSAgICAgICAgLy8gbG9jYWwgcGFydCBvZiBuYW1lLgotICAgICAgICBpZiAobmFtZS5jaGFyQXQobE5hbWVTdGFydElkeCkgPT0gJ0AnKSB7Ci0gICAgICAgICAgICBjb2RlID0gRFRNLkFUVFJJQlVURV9OT0RFOwotICAgICAgICAgICAgbE5hbWVTdGFydElkeCsrOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgY29kZSA9IERUTS5FTEVNRU5UX05PREU7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBFeHRyYWN0IGxvY2FsIG5hbWUKLSAgICAgICAgbE5hbWUgPSAobE5hbWVTdGFydElkeCA9PSAwKSA/IG5hbWUgOiBuYW1lLnN1YnN0cmluZyhsTmFtZVN0YXJ0SWR4KTsKLQotICAgICAgICByZXR1cm4gbV9leHBhbmRlZE5hbWVUYWJsZS5nZXRFeHBhbmRlZFR5cGVJRChucywgbE5hbWUsIGNvZGUsIHNlYXJjaE9ubHkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCBtYXBwaW5nIGZyb20gRE9NIGVsZW1lbnQvYXR0cmlidXRlIHR5cGVzIHRvIGV4dGVybmFsIHR5cGVzCi0gICAgICovCi0gICAgcHVibGljIHNob3J0W10gZ2V0TWFwcGluZyhTdHJpbmdbXSBuYW1lcywgU3RyaW5nW10gdXJpcywgaW50W10gdHlwZXMpCi0gICAgewotICAgICAgICAvLyBEZWxlZ2F0ZSB0aGUgd29yayB0byBnZXRNYXBwaW5nMiBpZiB0aGUgZG9jdW1lbnQgaXMgbm90IGZ1bGx5IGJ1aWx0LgotICAgICAgICAvLyBTb21lIG9mIHRoZSBwcm9jZXNzaW5nIGhhcyB0byBiZSBkaWZmZXJlbnQgaW4gdGhpcyBjYXNlLgotICAgICAgICBpZiAoX25hbWVzU2l6ZSA8IDApIHsKLSAgICAgICAgICAgIHJldHVybiBnZXRNYXBwaW5nMihuYW1lcywgdXJpcywgdHlwZXMpOwotICAgICAgICB9Ci0KLSAgICAgICAgaW50IGk7Ci0gICAgICAgIGZpbmFsIGludCBuYW1lc0xlbmd0aCA9IG5hbWVzLmxlbmd0aDsKLSAgICAgICAgZmluYWwgaW50IGV4TGVuZ3RoID0gbV9leHBhbmRlZE5hbWVUYWJsZS5nZXRTaXplKCk7Ci0KLSAgICAgICAgZmluYWwgc2hvcnRbXSByZXN1bHQgPSBuZXcgc2hvcnRbZXhMZW5ndGhdOwotCi0gICAgICAgIC8vIHByaW1pdGl2ZSB0eXBlcyBtYXAgdG8gdGhlbXNlbHZlcwotICAgICAgICBmb3IgKGkgPSAwOyBpIDwgRFRNLk5UWVBFUzsgaSsrKSB7Ci0gICAgICAgICAgICByZXN1bHRbaV0gPSAoc2hvcnQpaTsKLSAgICAgICAgfQotCi0gICAgICAgIGZvciAoaSA9IE5UWVBFUzsgaSA8IGV4TGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgIHJlc3VsdFtpXSA9IG1fZXhwYW5kZWROYW1lVGFibGUuZ2V0VHlwZShpKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIGFjdHVhbCBtYXBwaW5nIG9mIGNhbGxlciByZXF1ZXN0ZWQgbmFtZXMKLSAgICAgICAgZm9yIChpID0gMDsgaSA8IG5hbWVzTGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgIGludCBnZW5UeXBlID0gbV9leHBhbmRlZE5hbWVUYWJsZS5nZXRFeHBhbmRlZFR5cGVJRCh1cmlzW2ldLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzW2ldLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVzW2ldLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUpOwotICAgICAgICAgICAgaWYgKGdlblR5cGUgPj0gMCAmJiBnZW5UeXBlIDwgZXhMZW5ndGgpIHsKLSAgICAgICAgICAgICAgICByZXN1bHRbZ2VuVHlwZV0gPSAoc2hvcnQpKGkgKyBEVE0uTlRZUEVTKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiByZXN1bHQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IG1hcHBpbmcgZnJvbSBleHRlcm5hbCBlbGVtZW50L2F0dHJpYnV0ZSB0eXBlcyB0byBET00gdHlwZXMKLSAgICAgKi8KLSAgICBwdWJsaWMgaW50W10gZ2V0UmV2ZXJzZU1hcHBpbmcoU3RyaW5nW10gbmFtZXMsIFN0cmluZ1tdIHVyaXMsIGludFtdIHR5cGVzKQotICAgIHsKLSAgICAgICAgaW50IGk7Ci0gICAgICAgIGZpbmFsIGludFtdIHJlc3VsdCA9IG5ldyBpbnRbbmFtZXMubGVuZ3RoICsgRFRNLk5UWVBFU107Ci0KLSAgICAgICAgLy8gcHJpbWl0aXZlIHR5cGVzIG1hcCB0byB0aGVtc2VsdmVzCi0gICAgICAgIGZvciAoaSA9IDA7IGkgPCBEVE0uTlRZUEVTOyBpKyspIHsKLSAgICAgICAgICAgIHJlc3VsdFtpXSA9IGk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBjYWxsZXIncyB0eXBlcyBtYXAgaW50byBhcHByb3ByaWF0ZSBkb20gdHlwZXMKLSAgICAgICAgZm9yIChpID0gMDsgaSA8IG5hbWVzLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICBpbnQgdHlwZSA9IG1fZXhwYW5kZWROYW1lVGFibGUuZ2V0RXhwYW5kZWRUeXBlSUQodXJpc1tpXSwgbmFtZXNbaV0sIHR5cGVzW2ldLCB0cnVlKTsKLSAgICAgICAgICAgIHJlc3VsdFtpK0RUTS5OVFlQRVNdID0gdHlwZTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4ocmVzdWx0KTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgbWFwcGluZyBmcm9tIERPTSBlbGVtZW50L2F0dHJpYnV0ZSB0eXBlcyB0byBleHRlcm5hbCB0eXBlcy4KLSAgICAgKiBUaGlzIG1ldGhvZCBpcyB1c2VkIHdoZW4gdGhlIGRvY3VtZW50IGlzIG5vdCBmdWxseSBidWlsdC4KLSAgICAgKi8KLSAgICBwcml2YXRlIHNob3J0W10gZ2V0TWFwcGluZzIoU3RyaW5nW10gbmFtZXMsIFN0cmluZ1tdIHVyaXMsIGludFtdIHR5cGVzKQotICAgIHsKLSAgICAgICAgaW50IGk7Ci0gICAgICAgIGZpbmFsIGludCBuYW1lc0xlbmd0aCA9IG5hbWVzLmxlbmd0aDsKLSAgICAgICAgZmluYWwgaW50IGV4TGVuZ3RoID0gbV9leHBhbmRlZE5hbWVUYWJsZS5nZXRTaXplKCk7Ci0gICAgICAgIGludFtdIGdlbmVyYWxpemVkVHlwZXMgPSBudWxsOwotICAgICAgICBpZiAobmFtZXNMZW5ndGggPiAwKSB7Ci0gICAgICAgICAgICBnZW5lcmFsaXplZFR5cGVzID0gbmV3IGludFtuYW1lc0xlbmd0aF07Ci0gICAgICAgIH0KLQotICAgICAgICBpbnQgcmVzdWx0TGVuZ3RoID0gZXhMZW5ndGg7Ci0KLSAgICAgICAgZm9yIChpID0gMDsgaSA8IG5hbWVzTGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgIC8vIFdoZW4gdGhlIGRvY3VtZW50IGlzIG5vdCBmdWxseSBidWlsdCwgdGhlIHNlYXJjaE9ubHkKLSAgICAgICAgICAgIC8vIGZsYWcgc2hvdWxkIGJlIHNldCB0byBmYWxzZS4gVGhhdCBtZWFucyB3ZSBzaG91bGQgYWRkCi0gICAgICAgICAgICAvLyB0aGUgdHlwZSBpZiBpdCBpcyBub3QgYWxyZWFkeSBpbiB0aGUgZXhwYW5kZWQgbmFtZSB0YWJsZS4KLSAgICAgICAgICAgIC8vZ2VuZXJhbGl6ZWRUeXBlc1tpXSA9IGdldEdlbmVyYWxpemVkVHlwZShuYW1lc1tpXSwgZmFsc2UpOwotICAgICAgICAgICAgZ2VuZXJhbGl6ZWRUeXBlc1tpXSA9Ci0gICAgICAgICAgICAgICAgbV9leHBhbmRlZE5hbWVUYWJsZS5nZXRFeHBhbmRlZFR5cGVJRCh1cmlzW2ldLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXNbaV0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlc1tpXSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlKTsKLSAgICAgICAgICAgIGlmIChfbmFtZXNTaXplIDwgMCAmJiBnZW5lcmFsaXplZFR5cGVzW2ldID49IHJlc3VsdExlbmd0aCkgewotICAgICAgICAgICAgICAgIHJlc3VsdExlbmd0aCA9IGdlbmVyYWxpemVkVHlwZXNbaV0gKyAxOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgZmluYWwgc2hvcnRbXSByZXN1bHQgPSBuZXcgc2hvcnRbcmVzdWx0TGVuZ3RoXTsKLQotICAgICAgICAvLyBwcmltaXRpdmUgdHlwZXMgbWFwIHRvIHRoZW1zZWx2ZXMKLSAgICAgICAgZm9yIChpID0gMDsgaSA8IERUTS5OVFlQRVM7IGkrKykgewotICAgICAgICAgICAgcmVzdWx0W2ldID0gKHNob3J0KWk7Ci0gICAgICAgIH0KLQotICAgICAgICBmb3IgKGkgPSBOVFlQRVM7IGkgPCBleExlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICByZXN1bHRbaV0gPSBtX2V4cGFuZGVkTmFtZVRhYmxlLmdldFR5cGUoaSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBhY3R1YWwgbWFwcGluZyBvZiBjYWxsZXIgcmVxdWVzdGVkIG5hbWVzCi0gICAgICAgIGZvciAoaSA9IDA7IGkgPCBuYW1lc0xlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICBpbnQgZ2VuVHlwZSA9IGdlbmVyYWxpemVkVHlwZXNbaV07Ci0gICAgICAgICAgICBpZiAoZ2VuVHlwZSA+PSAwICYmIGdlblR5cGUgPCByZXN1bHRMZW5ndGgpIHsKLSAgICAgICAgICAgICAgICByZXN1bHRbZ2VuVHlwZV0gPSAoc2hvcnQpKGkgKyBEVE0uTlRZUEVTKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybihyZXN1bHQpOwotICAgIH0KLSAgICAvKioKLSAgICAgKiBHZXQgbWFwcGluZyBmcm9tIERPTSBuYW1lc3BhY2UgdHlwZXMgdG8gZXh0ZXJuYWwgbmFtZXNwYWNlIHR5cGVzCi0gICAgICovCi0gICAgcHVibGljIHNob3J0W10gZ2V0TmFtZXNwYWNlTWFwcGluZyhTdHJpbmdbXSBuYW1lc3BhY2VzKQotICAgIHsKLSAgICAgICAgaW50IGk7Ci0gICAgICAgIGZpbmFsIGludCBuc0xlbmd0aCA9IG5hbWVzcGFjZXMubGVuZ3RoOwotICAgICAgICBmaW5hbCBpbnQgbWFwcGluZ0xlbmd0aCA9IF91cmlDb3VudDsKLQotICAgICAgICBmaW5hbCBzaG9ydFtdIHJlc3VsdCA9IG5ldyBzaG9ydFttYXBwaW5nTGVuZ3RoXTsKLQotICAgICAgICAvLyBJbml0aWFsaXplIGFsbCBlbnRyaWVzIHRvIC0xCi0gICAgICAgIGZvciAoaT0wOyBpPG1hcHBpbmdMZW5ndGg7IGkrKykgewotICAgICAgICAgICAgcmVzdWx0W2ldID0gKHNob3J0KSgtMSk7Ci0gICAgICAgIH0KLQotICAgICAgICBmb3IgKGk9MDsgaTxuc0xlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICBpbnQgZVR5cGUgPSBnZXRJZEZvck5hbWVzcGFjZShuYW1lc3BhY2VzW2ldKTsKLSAgICAgICAgICAgIEludGVnZXIgdHlwZSA9IF9uc0luZGV4LmdldChlVHlwZSk7Ci0gICAgICAgICAgICBpZiAodHlwZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgcmVzdWx0W3R5cGVdID0gKHNob3J0KWk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4ocmVzdWx0KTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgbWFwcGluZyBmcm9tIGV4dGVybmFsIG5hbWVzcGFjZSB0eXBlcyB0byBET00gbmFtZXNwYWNlIHR5cGVzCi0gICAgICovCi0gICAgcHVibGljIHNob3J0W10gZ2V0UmV2ZXJzZU5hbWVzcGFjZU1hcHBpbmcoU3RyaW5nW10gbmFtZXNwYWNlcykKLSAgICB7Ci0gICAgICAgIGludCBpOwotICAgICAgICBmaW5hbCBpbnQgbGVuZ3RoID0gbmFtZXNwYWNlcy5sZW5ndGg7Ci0gICAgICAgIGZpbmFsIHNob3J0W10gcmVzdWx0ID0gbmV3IHNob3J0W2xlbmd0aF07Ci0KLSAgICAgICAgZm9yIChpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICBpbnQgZVR5cGUgPSBnZXRJZEZvck5hbWVzcGFjZShuYW1lc3BhY2VzW2ldKTsKLSAgICAgICAgICAgIEludGVnZXIgdHlwZSA9IF9uc0luZGV4LmdldChlVHlwZSk7Ci0gICAgICAgICAgICByZXN1bHRbaV0gPSAodHlwZSA9PSBudWxsKSA/IC0xIDogdHlwZS5zaG9ydFZhbHVlKCk7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gcmVzdWx0OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdCBhIFNBWEltcGwgb2JqZWN0IHVzaW5nIHRoZSBkZWZhdWx0IGJsb2NrIHNpemUuCi0gICAgICovCi0gICAgcHVibGljIFNBWEltcGwoWFNMVENEVE1NYW5hZ2VyIG1nciwgU291cmNlIHNvdXJjZSwKLSAgICAgICAgICAgICAgICAgICBpbnQgZHRtSWRlbnRpdHksIERUTVdTRmlsdGVyIHdoaXRlU3BhY2VGaWx0ZXIsCi0gICAgICAgICAgICAgICAgICAgWE1MU3RyaW5nRmFjdG9yeSB4c3RyaW5nZmFjdG9yeSwKLSAgICAgICAgICAgICAgICAgICBib29sZWFuIGRvSW5kZXhpbmcsIGJvb2xlYW4gYnVpbGRJZEluZGV4KQotICAgIHsKLSAgICAgICAgdGhpcyhtZ3IsIHNvdXJjZSwgZHRtSWRlbnRpdHksIHdoaXRlU3BhY2VGaWx0ZXIsIHhzdHJpbmdmYWN0b3J5LAotICAgICAgICAgICAgZG9JbmRleGluZywgREVGQVVMVF9CTE9DS1NJWkUsIGJ1aWxkSWRJbmRleCwgZmFsc2UpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdCBhIFNBWEltcGwgb2JqZWN0IHVzaW5nIHRoZSBnaXZlbiBibG9jayBzaXplLgotICAgICAqLwotICAgIHB1YmxpYyBTQVhJbXBsKFhTTFRDRFRNTWFuYWdlciBtZ3IsIFNvdXJjZSBzb3VyY2UsCi0gICAgICAgICAgICAgICAgICAgaW50IGR0bUlkZW50aXR5LCBEVE1XU0ZpbHRlciB3aGl0ZVNwYWNlRmlsdGVyLAotICAgICAgICAgICAgICAgICAgIFhNTFN0cmluZ0ZhY3RvcnkgeHN0cmluZ2ZhY3RvcnksCi0gICAgICAgICAgICAgICAgICAgYm9vbGVhbiBkb0luZGV4aW5nLCBpbnQgYmxvY2tzaXplLAotICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gYnVpbGRJZEluZGV4LAotICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gbmV3TmFtZVRhYmxlKQotICAgIHsKLSAgICAgICAgc3VwZXIobWdyLCBzb3VyY2UsIGR0bUlkZW50aXR5LCB3aGl0ZVNwYWNlRmlsdGVyLCB4c3RyaW5nZmFjdG9yeSwKLSAgICAgICAgICAgIGRvSW5kZXhpbmcsIGJsb2Nrc2l6ZSwgZmFsc2UsIGJ1aWxkSWRJbmRleCwgbmV3TmFtZVRhYmxlKTsKLQotICAgICAgICBfZHRtTWFuYWdlciA9IG1ncjsKLSAgICAgICAgX3NpemUgPSBibG9ja3NpemU7Ci0KLSAgICAgICAgLy8gVXNlIGEgc21hbGxlciBzaXplIGZvciB0aGUgc3BhY2Ugc3RhY2sgaWYgdGhlIGJsb2Nrc2l6ZSBpcyBzbWFsbAotICAgICAgICBfeG1sU3BhY2VTdGFjayA9IG5ldyBpbnRbYmxvY2tzaXplIDw9IDY0ID8gNCA6IDY0XTsKLQotICAgICAgICAvKiBGcm9tIERPTUJ1aWxkZXIgKi8KLSAgICAgICAgX3htbFNwYWNlU3RhY2tbMF0gPSBEVE1EZWZhdWx0QmFzZS5ST09UTk9ERTsKLQotICAgICAgICAvLyBJZiB0aGUgaW5wdXQgc291cmNlIGlzIERPTVNvdXJjZSwgc2V0IHRoZSBfZG9jdW1lbnQgZmllbGQgYW5kCi0gICAgICAgIC8vIGNyZWF0ZSB0aGUgbm9kZTJJZHMgdGFibGUuCi0gICAgICAgIGlmIChzb3VyY2UgaW5zdGFuY2VvZiBET01Tb3VyY2UpIHsKLSAgICAgICAgICAgIF9oYXNET01Tb3VyY2UgPSB0cnVlOwotICAgICAgICAgICAgRE9NU291cmNlIGRvbXNyYyA9IChET01Tb3VyY2Upc291cmNlOwotICAgICAgICAgICAgTm9kZSBub2RlID0gZG9tc3JjLmdldE5vZGUoKTsKLSAgICAgICAgICAgIGlmIChub2RlIGluc3RhbmNlb2YgRG9jdW1lbnQpIHsKLSAgICAgICAgICAgICAgICBfZG9jdW1lbnQgPSAoRG9jdW1lbnQpbm9kZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIF9kb2N1bWVudCA9IG5vZGUuZ2V0T3duZXJEb2N1bWVudCgpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgX25vZGUySWRzID0gbmV3IEhhc2hNYXA8PigpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgKiBNaWdyYXRlIGEgRFRNIGJ1aWx0IHdpdGggYW4gb2xkIERUTU1hbmFnZXIgdG8gYSBuZXcgRFRNTWFuYWdlci4KLSAgICAqIEFmdGVyIHRoZSBtaWdyYXRpb24sIHRoZSBuZXcgRFRNTWFuYWdlciB3aWxsIHRyZWF0IHRoZSBEVE0gYXMKLSAgICAqIG9uZSB0aGF0IGlzIGJ1aWx0IGJ5IGl0c2VsZi4KLSAgICAqIFRoaXMgaXMgdXNlZCB0byBzdXBwb3J0IERUTSBzaGFyaW5nIGJldHdlZW4gbXVsdGlwbGUgdHJhbnNmb3JtYXRpb25zLgotICAgICogQHBhcmFtIG1hbmFnZXIgdGhlIERUTU1hbmFnZXIKLSAgICAqLwotICAgIHB1YmxpYyB2b2lkIG1pZ3JhdGVUbyhEVE1NYW5hZ2VyIG1hbmFnZXIpIHsKLSAgICAgICAgc3VwZXIubWlncmF0ZVRvKG1hbmFnZXIpOwotICAgICAgICBpZiAobWFuYWdlciBpbnN0YW5jZW9mIFhTTFRDRFRNTWFuYWdlcikgewotICAgICAgICAgICAgX2R0bU1hbmFnZXIgPSAoWFNMVENEVE1NYW5hZ2VyKW1hbmFnZXI7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIG5vZGUgaWRlbnRpdHkgZm9yIGEgZ2l2ZW4gaWQgU3RyaW5nCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaWRTdHJpbmcgVGhlIGlkIFN0cmluZwotICAgICAqIEByZXR1cm4gVGhlIGlkZW50aXR5IG9mIHRoZSBub2RlIHdob3NlIGlkIGlzIHRoZSBnaXZlbiBTdHJpbmcuCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRFbGVtZW50QnlJZChTdHJpbmcgaWRTdHJpbmcpCi0gICAgewotICAgICAgICBOb2RlIG5vZGUgPSBfZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWRTdHJpbmcpOwotICAgICAgICBpZiAobm9kZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBJbnRlZ2VyIGlkID0gX25vZGUySWRzLmdldChub2RlKTsKLSAgICAgICAgICAgIHJldHVybiAoaWQgIT0gbnVsbCkgPyBpZCA6IERUTS5OVUxMOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIERUTS5OVUxMOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRydWUgaWYgdGhlIGlucHV0IHNvdXJjZSBpcyBET01Tb3VyY2UuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaGFzRE9NU291cmNlKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBfaGFzRE9NU291cmNlOwotICAgIH0KLQotICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KLSAgICAvKiBET01CdWlsZGVyIG1ldGhvZHMgYmVnaW4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi0gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwotCi0gICAgLyoqCi0gICAgICogQ2FsbCB0aGlzIHdoZW4gYW4geG1sOnNwYWNlIGF0dHJpYnV0ZSBpcyBlbmNvdW50ZXJlZCB0bwotICAgICAqIGRlZmluZSB0aGUgd2hpdGVzcGFjZSBzdHJpcC9wcmVzZXJ2ZSBzZXR0aW5ncy4KLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgeG1sU3BhY2VEZWZpbmUoU3RyaW5nIHZhbCwgZmluYWwgaW50IG5vZGUpCi0gICAgewotICAgICAgICBmaW5hbCBib29sZWFuIHNldHRpbmcgPSB2YWwuZXF1YWxzKFBSRVNFUlZFX1NUUklORyk7Ci0gICAgICAgIGlmIChzZXR0aW5nICE9IF9wcmVzZXJ2ZSkgewotICAgICAgICAgICAgX3htbFNwYWNlU3RhY2tbX2lkeCsrXSA9IG5vZGU7Ci0gICAgICAgICAgICBfcHJlc2VydmUgPSBzZXR0aW5nOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ2FsbCB0aGlzIGZyb20gZW5kRWxlbWVudCgpIHRvIHJldmVydCBzdHJpcC9wcmVzZXJ2ZSBzZXR0aW5nCi0gICAgICogdG8gd2hhdGV2ZXIgaXQgd2FzIGJlZm9yZSB0aGUgY29ycmVzcG9uZGluZyBzdGFydEVsZW1lbnQoKS4KLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgeG1sU3BhY2VSZXZlcnQoZmluYWwgaW50IG5vZGUpCi0gICAgewotICAgICAgICBpZiAobm9kZSA9PSBfeG1sU3BhY2VTdGFja1tfaWR4IC0gMV0pIHsKLSAgICAgICAgICAgIF9pZHgtLTsKLSAgICAgICAgICAgIF9wcmVzZXJ2ZSA9ICFfcHJlc2VydmU7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBGaW5kIG91dCB3aGV0aGVyIG9yIG5vdCB0byBzdHJpcCB3aGl0ZXNwYWNlIG5vZGVzLgotICAgICAqCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHdoZXRoZXIgb3Igbm90IHRvIHN0cmlwIHdoaXRlc3BhY2Ugbm9kZXMuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZ2V0U2hvdWxkU3RyaXBXaGl0ZXNwYWNlKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBfcHJlc2VydmUgPyBmYWxzZSA6IHN1cGVyLmdldFNob3VsZFN0cmlwV2hpdGVzcGFjZSgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENyZWF0ZXMgYSB0ZXh0LW5vZGUgYW5kIGNoZWNrcyBpZiBpdCBpcyBhIHdoaXRlc3BhY2Ugbm9kZS4KLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgaGFuZGxlVGV4dEVzY2FwaW5nKCkgewotICAgICAgICBpZiAoX2Rpc2FibGVFc2NhcGluZyAmJiBfdGV4dE5vZGVUb1Byb2Nlc3MgIT0gRFRNLk5VTEwKLSAgICAgICAgICAgICYmIF90eXBlKF90ZXh0Tm9kZVRvUHJvY2VzcykgPT0gRFRNLlRFWFRfTk9ERSkgewotICAgICAgICAgICAgaWYgKF9kb250RXNjYXBlID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBfZG9udEVzY2FwZSA9IG5ldyBCaXRBcnJheShfc2l6ZSk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIFJlc2l6ZSB0aGUgX2RvbnRFc2NhcGUgQml0QXJyYXkgaWYgbmVjZXNzYXJ5LgotICAgICAgICAgICAgaWYgKF90ZXh0Tm9kZVRvUHJvY2VzcyA+PSBfZG9udEVzY2FwZS5zaXplKCkpIHsKLSAgICAgICAgICAgICAgICBfZG9udEVzY2FwZS5yZXNpemUoX2RvbnRFc2NhcGUuc2l6ZSgpICogMik7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIF9kb250RXNjYXBlLnNldEJpdChfdGV4dE5vZGVUb1Byb2Nlc3MpOwotICAgICAgICAgICAgX2Rpc2FibGVFc2NhcGluZyA9IGZhbHNlOwotICAgICAgICB9Ci0gICAgICAgIF90ZXh0Tm9kZVRvUHJvY2VzcyA9IERUTS5OVUxMOwotICAgIH0KLQotCi0gICAgLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi0gICAgLyogICAgICAgICAgICAgICBTQVggSW50ZXJmYWNlIFN0YXJ0cyBIZXJlICAgICAgICAgICAgICAgICAgICAgICovCi0gICAgLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi0KLSAgICAvKioKLSAgICAgKiBTQVgyOiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBjaGFyYWN0ZXIgZGF0YS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBjaGFyYWN0ZXJzKGNoYXJbXSBjaCwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBzdXBlci5jaGFyYWN0ZXJzKGNoLCBzdGFydCwgbGVuZ3RoKTsKLQotICAgICAgICBfZGlzYWJsZUVzY2FwaW5nID0gIV9lc2NhcGluZzsKLSAgICAgICAgX3RleHROb2RlVG9Qcm9jZXNzID0gZ2V0TnVtYmVyT2ZOb2RlcygpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNBWDI6IFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIHRoZSBiZWdpbm5pbmcgb2YgYSBkb2N1bWVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydERvY3VtZW50KCkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgc3VwZXIuc3RhcnREb2N1bWVudCgpOwotCi0gICAgICAgIF9uc0luZGV4LnB1dCgwLCBfdXJpQ291bnQrKyk7Ci0gICAgICAgIGRlZmluZVByZWZpeEFuZFVyaShYTUxfUFJFRklYLCBYTUxfVVJJKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTQVgyOiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiB0aGUgZW5kIG9mIGEgZG9jdW1lbnQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kRG9jdW1lbnQoKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBzdXBlci5lbmREb2N1bWVudCgpOwotCi0gICAgICAgIGhhbmRsZVRleHRFc2NhcGluZygpOwotICAgICAgICBfbmFtZXNTaXplID0gbV9leHBhbmRlZE5hbWVUYWJsZS5nZXRTaXplKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU3BlY2lhbGl6ZWQgaW50ZXJmYWNlIHVzZWQgYnkgRE9NMlNBWC4gVGhpcyBvbmUgaGFzIGFuIGV4dHJhIE5vZGUKLSAgICAgKiBwYXJhbWV0ZXIgdG8gYnVpbGQgdGhlIE5vZGUgLT4gaWQgbWFwLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudChTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxOYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcW5hbWUsIEF0dHJpYnV0ZXMgYXR0cmlidXRlcywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTm9kZSBub2RlKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICB0aGlzLnN0YXJ0RWxlbWVudCh1cmksIGxvY2FsTmFtZSwgcW5hbWUsIGF0dHJpYnV0ZXMpOwotCi0gICAgICAgIGlmIChtX2J1aWxkSWRJbmRleCkgewotICAgICAgICAgICAgX25vZGUySWRzLnB1dChub2RlLCBuZXcgSW50ZWdlcihtX3BhcmVudHMucGVlaygpKSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTQVgyOiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiB0aGUgYmVnaW5uaW5nIG9mIGFuIGVsZW1lbnQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnRFbGVtZW50KFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUsCi0gICAgICAgICAgICAgICAgIFN0cmluZyBxbmFtZSwgQXR0cmlidXRlcyBhdHRyaWJ1dGVzKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBzdXBlci5zdGFydEVsZW1lbnQodXJpLCBsb2NhbE5hbWUsIHFuYW1lLCBhdHRyaWJ1dGVzKTsKLQotICAgICAgICBoYW5kbGVUZXh0RXNjYXBpbmcoKTsKLQotICAgICAgICBpZiAobV93c2ZpbHRlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAvLyBMb29rIGZvciBhbnkgeG1sOnNwYWNlIGF0dHJpYnV0ZXMKLSAgICAgICAgICAgIC8vIERlcGVuZGluZyBvbiB0aGUgaW1wbGVtZW50YXRpb24gb2YgYXR0cmlidXRlcywgdGhpcwotICAgICAgICAgICAgLy8gbWlnaHQgYmUgZmFzdGVyIHRoYW4gbG9vcGluZyB0aHJvdWdoIGFsbCBhdHRyaWJ1dGVzLiBJTEVORQotICAgICAgICAgICAgZmluYWwgaW50IGluZGV4ID0gYXR0cmlidXRlcy5nZXRJbmRleChYTUxTUEFDRV9TVFJJTkcpOwotICAgICAgICAgICAgaWYgKGluZGV4ID49IDApIHsKLSAgICAgICAgICAgICAgICB4bWxTcGFjZURlZmluZShhdHRyaWJ1dGVzLmdldFZhbHVlKGluZGV4KSwgbV9wYXJlbnRzLnBlZWsoKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTQVgyOiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiB0aGUgZW5kIG9mIGFuIGVsZW1lbnQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kRWxlbWVudChTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgbG9jYWxOYW1lLCBTdHJpbmcgcW5hbWUpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIHN1cGVyLmVuZEVsZW1lbnQobmFtZXNwYWNlVVJJLCBsb2NhbE5hbWUsIHFuYW1lKTsKLQotICAgICAgICBoYW5kbGVUZXh0RXNjYXBpbmcoKTsKLQotICAgICAgICAvLyBSZXZlcnQgdG8gc3RyaXAvcHJlc2VydmUtc3BhY2Ugc2V0dGluZyBmcm9tIGJlZm9yZSB0aGlzIGVsZW1lbnQKLSAgICAgICAgaWYgKG1fd3NmaWx0ZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgeG1sU3BhY2VSZXZlcnQobV9wcmV2aW91cyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTQVgyOiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBhIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcHJvY2Vzc2luZ0luc3RydWN0aW9uKFN0cmluZyB0YXJnZXQsIFN0cmluZyBkYXRhKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBzdXBlci5wcm9jZXNzaW5nSW5zdHJ1Y3Rpb24odGFyZ2V0LCBkYXRhKTsKLSAgICAgICAgaGFuZGxlVGV4dEVzY2FwaW5nKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU0FYMjogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgaWdub3JhYmxlIHdoaXRlc3BhY2UgaW4gZWxlbWVudAotICAgICAqIGNvbnRlbnQuIFNpbWlsYXIgdG8gY2hhcmFjdGVycyhjaGFyW10sIGludCwgaW50KS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBpZ25vcmFibGVXaGl0ZXNwYWNlKGNoYXJbXSBjaCwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBzdXBlci5pZ25vcmFibGVXaGl0ZXNwYWNlKGNoLCBzdGFydCwgbGVuZ3RoKTsKLSAgICAgICAgX3RleHROb2RlVG9Qcm9jZXNzID0gZ2V0TnVtYmVyT2ZOb2RlcygpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNBWDI6IEJlZ2luIHRoZSBzY29wZSBvZiBhIHByZWZpeC1VUkkgTmFtZXNwYWNlIG1hcHBpbmcuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnRQcmVmaXhNYXBwaW5nKFN0cmluZyBwcmVmaXgsIFN0cmluZyB1cmkpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIHN1cGVyLnN0YXJ0UHJlZml4TWFwcGluZyhwcmVmaXgsIHVyaSk7Ci0gICAgICAgIGhhbmRsZVRleHRFc2NhcGluZygpOwotCi0gICAgICAgIGRlZmluZVByZWZpeEFuZFVyaShwcmVmaXgsIHVyaSk7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIGRlZmluZVByZWZpeEFuZFVyaShTdHJpbmcgcHJlZml4LCBTdHJpbmcgdXJpKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICAvLyBDaGVjayBpZiB0aGUgVVJJIGFscmVhZHkgZXhpc3RzIGJlZm9yZSBwdXNoaW5nIG9uIHN0YWNrCi0gICAgICAgIEludGVnZXIgZVR5cGUgPSBuZXcgSW50ZWdlcihnZXRJZEZvck5hbWVzcGFjZSh1cmkpKTsKLSAgICAgICAgaWYgKF9uc0luZGV4LmdldChlVHlwZSkgPT0gbnVsbCkgewotICAgICAgICAgICAgX25zSW5kZXgucHV0KGVUeXBlLCBfdXJpQ291bnQrKyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTQVgyOiBSZXBvcnQgYW4gWE1MIGNvbW1lbnQgYW55d2hlcmUgaW4gdGhlIGRvY3VtZW50LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGNvbW1lbnQoY2hhcltdIGNoLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIHN1cGVyLmNvbW1lbnQoY2gsIHN0YXJ0LCBsZW5ndGgpOwotICAgICAgICBoYW5kbGVUZXh0RXNjYXBpbmcoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBzZXRFc2NhcGluZyhib29sZWFuIHZhbHVlKSB7Ci0gICAgICAgIGZpbmFsIGJvb2xlYW4gdGVtcCA9IF9lc2NhcGluZzsKLSAgICAgICAgX2VzY2FwaW5nID0gdmFsdWU7Ci0gICAgICAgIHJldHVybiB0ZW1wOwotICAgIH0KLQotICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwotICAgLyogRE9NQnVpbGRlciBtZXRob2RzIGVuZCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwotICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwotCi0gICAgLyoqCi0gICAgICogUHJpbnRzIHRoZSB3aG9sZSB0cmVlIHRvIHN0YW5kYXJkIG91dHB1dAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHByaW50KGludCBub2RlLCBpbnQgbGV2ZWwpCi0gICAgewotICAgICAgICBzd2l0Y2goZ2V0Tm9kZVR5cGUobm9kZSkpCi0gICAgICAgIHsKLSAgICAgICAgICAgIGNhc2UgRFRNLlJPT1RfTk9ERToKLSAgICAgICAgICAgIGNhc2UgRFRNLkRPQ1VNRU5UX05PREU6Ci0gICAgICAgICAgICAgICAgcHJpbnQoZ2V0Rmlyc3RDaGlsZChub2RlKSwgbGV2ZWwpOwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgY2FzZSBEVE0uVEVYVF9OT0RFOgotICAgICAgICAgICAgY2FzZSBEVE0uQ09NTUVOVF9OT0RFOgotICAgICAgICAgICAgY2FzZSBEVE0uUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFOgotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoZ2V0U3RyaW5nVmFsdWVYKG5vZGUpKTsKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIGRlZmF1bHQ6Ci0gICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIG5hbWUgPSBnZXROb2RlTmFtZShub2RlKTsKLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCI8IiArIG5hbWUpOwotICAgICAgICAgICAgICAgIGZvciAoaW50IGEgPSBnZXRGaXJzdEF0dHJpYnV0ZShub2RlKTsgYSAhPSBEVE0uTlVMTDsgYSA9IGdldE5leHRBdHRyaWJ1dGUoYSkpCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCJcbiIgKyBnZXROb2RlTmFtZShhKSArICI9XCIiICsgZ2V0U3RyaW5nVmFsdWVYKGEpICsgIlwiIik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoJz4nKTsKLSAgICAgICAgICAgICAgICBmb3IgKGludCBjaGlsZCA9IGdldEZpcnN0Q2hpbGQobm9kZSk7IGNoaWxkICE9IERUTS5OVUxMOwotICAgICAgICAgICAgICAgICAgICBjaGlsZCA9IGdldE5leHRTaWJsaW5nKGNoaWxkKSkgewotICAgICAgICAgICAgICAgICAgICBwcmludChjaGlsZCwgbGV2ZWwgKyAxKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCI8LyIgKyBuYW1lICsgJz4nKTsKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIG5hbWUgb2YgYSBub2RlIChhdHRyaWJ1dGUgb3IgZWxlbWVudCkuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXROb2RlTmFtZShmaW5hbCBpbnQgbm9kZSkKLSAgICB7Ci0gICAgICAgIC8vIEdldCB0aGUgbm9kZSB0eXBlIGFuZCBtYWtlIHN1cmUgdGhhdCBpdCBpcyB3aXRoaW4gbGltaXRzCi0gICAgICAgIGludCBub2RlaCA9IG5vZGU7Ci0gICAgICAgIGZpbmFsIHNob3J0IHR5cGUgPSBnZXROb2RlVHlwZShub2RlaCk7Ci0gICAgICAgIHN3aXRjaCh0eXBlKQotICAgICAgICB7Ci0gICAgICAgICAgICBjYXNlIERUTS5ST09UX05PREU6Ci0gICAgICAgICAgICBjYXNlIERUTS5ET0NVTUVOVF9OT0RFOgotICAgICAgICAgICAgY2FzZSBEVE0uVEVYVF9OT0RFOgotICAgICAgICAgICAgY2FzZSBEVE0uQ09NTUVOVF9OT0RFOgotICAgICAgICAgICAgICAgIHJldHVybiBFTVBUWVNUUklORzsKLSAgICAgICAgICAgIGNhc2UgRFRNLk5BTUVTUEFDRV9OT0RFOgotICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldExvY2FsTmFtZShub2RlaCk7Ci0gICAgICAgICAgICBkZWZhdWx0OgotICAgICAgICAgICAgICAgIHJldHVybiBzdXBlci5nZXROb2RlTmFtZShub2RlaCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBuYW1lc3BhY2UgVVJJIHRvIHdoaWNoIGEgbm9kZSBiZWxvbmdzCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXROYW1lc3BhY2VOYW1lKGZpbmFsIGludCBub2RlKQotICAgIHsKLSAgICAgICAgaWYgKG5vZGUgPT0gRFRNLk5VTEwpIHsKLSAgICAgICAgICAgIHJldHVybiAiIjsKLSAgICAgICAgfQotCi0gICAgICAgIFN0cmluZyBzOwotICAgICAgICByZXR1cm4gKHMgPSBnZXROYW1lc3BhY2VVUkkobm9kZSkpID09IG51bGwgPyBFTVBUWVNUUklORyA6IHM7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBhdHRyaWJ1dGUgbm9kZSBvZiBhIGdpdmVuIHR5cGUgKGlmIGFueSkgZm9yIGFuIGVsZW1lbnQKLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldEF0dHJpYnV0ZU5vZGUoZmluYWwgaW50IHR5cGUsIGZpbmFsIGludCBlbGVtZW50KQotICAgIHsKLSAgICAgICAgZm9yIChpbnQgYXR0ciA9IGdldEZpcnN0QXR0cmlidXRlKGVsZW1lbnQpOwotICAgICAgICAgICBhdHRyICE9IERUTS5OVUxMOwotICAgICAgICAgICBhdHRyID0gZ2V0TmV4dEF0dHJpYnV0ZShhdHRyKSkKLSAgICAgICAgewotICAgICAgICAgICAgaWYgKGdldEV4cGFuZGVkVHlwZUlEKGF0dHIpID09IHR5cGUpIHJldHVybiBhdHRyOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBEVE0uTlVMTDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiBhIGdpdmVuIGF0dHJpYnV0ZSB0eXBlIG9mIGEgZ2l2ZW4gZWxlbWVudAotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0QXR0cmlidXRlVmFsdWUoZmluYWwgaW50IHR5cGUsIGZpbmFsIGludCBlbGVtZW50KQotICAgIHsKLSAgICAgICAgZmluYWwgaW50IGF0dHIgPSBnZXRBdHRyaWJ1dGVOb2RlKHR5cGUsIGVsZW1lbnQpOwotICAgICAgICByZXR1cm4gKGF0dHIgIT0gRFRNLk5VTEwpID8gZ2V0U3RyaW5nVmFsdWVYKGF0dHIpIDogRU1QVFlTVFJJTkc7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgaXMgZm9yIHRlc3RpbmcvZGVidWdnaW5nIG9ubHkKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEF0dHJpYnV0ZVZhbHVlKGZpbmFsIFN0cmluZyBuYW1lLCBmaW5hbCBpbnQgZWxlbWVudCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBnZXRBdHRyaWJ1dGVWYWx1ZShnZXRHZW5lcmFsaXplZFR5cGUobmFtZSksIGVsZW1lbnQpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYW4gaXRlcmF0b3Igd2l0aCBhbGwgdGhlIGNoaWxkcmVuIG9mIGEgZ2l2ZW4gbm9kZQotICAgICAqLwotICAgIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3IgZ2V0Q2hpbGRyZW4oZmluYWwgaW50IG5vZGUpCi0gICAgewotICAgICAgICByZXR1cm4gKG5ldyBDaGlsZHJlbkl0ZXJhdG9yKCkpLnNldFN0YXJ0Tm9kZShub2RlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGFuIGl0ZXJhdG9yIHdpdGggYWxsIGNoaWxkcmVuIG9mIGEgc3BlY2lmaWMgdHlwZQotICAgICAqIGZvciBhIGdpdmVuIG5vZGUgKGVsZW1lbnQpCi0gICAgICovCi0gICAgcHVibGljIERUTUF4aXNJdGVyYXRvciBnZXRUeXBlZENoaWxkcmVuKGZpbmFsIGludCB0eXBlKQotICAgIHsKLSAgICAgICAgcmV0dXJuKG5ldyBUeXBlZENoaWxkcmVuSXRlcmF0b3IodHlwZSkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgaXMgYSBzaG9ydGN1dCB0byB0aGUgaXRlcmF0b3JzIHRoYXQgaW1wbGVtZW50IHRoZQotICAgICAqIHN1cHBvcnRlZCBYUGF0aCBheGVzIChvbmx5IG5hbWVzcGFjZTo6KSBpcyBub3Qgc3VwcG9ydGVkLgotICAgICAqIFJldHVybnMgYSBiYXJlLWJvbmVzIGl0ZXJhdG9yIHRoYXQgbXVzdCBiZSBpbml0aWFsaXplZAotICAgICAqIHdpdGggYSBzdGFydCBub2RlICh1c2luZyBpdGVyYXRvci5zZXRTdGFydE5vZGUoKSkuCi0gICAgICovCi0gICAgcHVibGljIERUTUF4aXNJdGVyYXRvciBnZXRBeGlzSXRlcmF0b3IoZmluYWwgaW50IGF4aXMpCi0gICAgewotICAgICAgICBzd2l0Y2ggKGF4aXMpCi0gICAgICAgIHsKLSAgICAgICAgICAgIGNhc2UgQXhpcy5TRUxGOgotICAgICAgICAgICAgICAgIHJldHVybiBuZXcgU2luZ2xldG9uSXRlcmF0b3IoKTsKLSAgICAgICAgICAgIGNhc2UgQXhpcy5DSElMRDoKLSAgICAgICAgICAgICAgICByZXR1cm4gbmV3IENoaWxkcmVuSXRlcmF0b3IoKTsKLSAgICAgICAgICAgIGNhc2UgQXhpcy5QQVJFTlQ6Ci0gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBQYXJlbnRJdGVyYXRvcigpOwotICAgICAgICAgICAgY2FzZSBBeGlzLkFOQ0VTVE9SOgotICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQW5jZXN0b3JJdGVyYXRvcigpOwotICAgICAgICAgICAgY2FzZSBBeGlzLkFOQ0VTVE9ST1JTRUxGOgotICAgICAgICAgICAgICAgIHJldHVybiAobmV3IEFuY2VzdG9ySXRlcmF0b3IoKSkuaW5jbHVkZVNlbGYoKTsKLSAgICAgICAgICAgIGNhc2UgQXhpcy5BVFRSSUJVVEU6Ci0gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBBdHRyaWJ1dGVJdGVyYXRvcigpOwotICAgICAgICAgICAgY2FzZSBBeGlzLkRFU0NFTkRBTlQ6Ci0gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBEZXNjZW5kYW50SXRlcmF0b3IoKTsKLSAgICAgICAgICAgIGNhc2UgQXhpcy5ERVNDRU5EQU5UT1JTRUxGOgotICAgICAgICAgICAgICAgIHJldHVybiAobmV3IERlc2NlbmRhbnRJdGVyYXRvcigpKS5pbmNsdWRlU2VsZigpOwotICAgICAgICAgICAgY2FzZSBBeGlzLkZPTExPV0lORzoKLSAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEZvbGxvd2luZ0l0ZXJhdG9yKCk7Ci0gICAgICAgICAgICBjYXNlIEF4aXMuUFJFQ0VESU5HOgotICAgICAgICAgICAgICAgIHJldHVybiBuZXcgUHJlY2VkaW5nSXRlcmF0b3IoKTsKLSAgICAgICAgICAgIGNhc2UgQXhpcy5GT0xMT1dJTkdTSUJMSU5HOgotICAgICAgICAgICAgICAgIHJldHVybiBuZXcgRm9sbG93aW5nU2libGluZ0l0ZXJhdG9yKCk7Ci0gICAgICAgICAgICBjYXNlIEF4aXMuUFJFQ0VESU5HU0lCTElORzoKLSAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFByZWNlZGluZ1NpYmxpbmdJdGVyYXRvcigpOwotICAgICAgICAgICAgY2FzZSBBeGlzLk5BTUVTUEFDRToKLSAgICAgICAgICAgICAgICByZXR1cm4gbmV3IE5hbWVzcGFjZUl0ZXJhdG9yKCk7Ci0gICAgICAgICAgICBjYXNlIEF4aXMuUk9PVDoKLSAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFJvb3RJdGVyYXRvcigpOwotICAgICAgICAgICAgZGVmYXVsdDoKLSAgICAgICAgICAgICAgICBCYXNpc0xpYnJhcnkucnVuVGltZUVycm9yKEJhc2lzTGlicmFyeS5BWElTX1NVUFBPUlRfRVJSLAotICAgICAgICAgICAgICAgICAgICAgICAgQXhpcy5nZXROYW1lcyhheGlzKSk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2ltaWxhciB0byBnZXRBeGlzSXRlcmF0b3IsIGJ1dCB0aGlzIG9uZSByZXR1cm5zIGFuIGl0ZXJhdG9yCi0gICAgICogY29udGFpbmluZyBub2RlcyBvZiBhIHR5cGVkIGF4aXMgKGV4LjogY2hpbGQ6OmZvbykKLSAgICAgKi8KLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIGdldFR5cGVkQXhpc0l0ZXJhdG9yKGludCBheGlzLCBpbnQgdHlwZSkKLSAgICB7Ci0gICAgICAgIC8vIE1vc3QgY29tbW9uIGNhc2UgaGFuZGxlZCBmaXJzdAotICAgICAgICBpZiAoYXhpcyA9PSBBeGlzLkNISUxEKSB7Ci0gICAgICAgICAgICByZXR1cm4gbmV3IFR5cGVkQ2hpbGRyZW5JdGVyYXRvcih0eXBlKTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmICh0eXBlID09IE5PX1RZUEUpIHsKLSAgICAgICAgICAgIHJldHVybihFTVBUWUlURVJBVE9SKTsKLSAgICAgICAgfQotCi0gICAgICAgIHN3aXRjaCAoYXhpcykKLSAgICAgICAgewotICAgICAgICAgICAgY2FzZSBBeGlzLlNFTEY6Ci0gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBUeXBlZFNpbmdsZXRvbkl0ZXJhdG9yKHR5cGUpOwotICAgICAgICAgICAgY2FzZSBBeGlzLkNISUxEOgotICAgICAgICAgICAgICAgIHJldHVybiBuZXcgVHlwZWRDaGlsZHJlbkl0ZXJhdG9yKHR5cGUpOwotICAgICAgICAgICAgY2FzZSBBeGlzLlBBUkVOVDoKLSAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFBhcmVudEl0ZXJhdG9yKCkuc2V0Tm9kZVR5cGUodHlwZSk7Ci0gICAgICAgICAgICBjYXNlIEF4aXMuQU5DRVNUT1I6Ci0gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBUeXBlZEFuY2VzdG9ySXRlcmF0b3IodHlwZSk7Ci0gICAgICAgICAgICBjYXNlIEF4aXMuQU5DRVNUT1JPUlNFTEY6Ci0gICAgICAgICAgICAgICAgcmV0dXJuIChuZXcgVHlwZWRBbmNlc3Rvckl0ZXJhdG9yKHR5cGUpKS5pbmNsdWRlU2VsZigpOwotICAgICAgICAgICAgY2FzZSBBeGlzLkFUVFJJQlVURToKLSAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFR5cGVkQXR0cmlidXRlSXRlcmF0b3IodHlwZSk7Ci0gICAgICAgICAgICBjYXNlIEF4aXMuREVTQ0VOREFOVDoKLSAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFR5cGVkRGVzY2VuZGFudEl0ZXJhdG9yKHR5cGUpOwotICAgICAgICAgICAgY2FzZSBBeGlzLkRFU0NFTkRBTlRPUlNFTEY6Ci0gICAgICAgICAgICAgICAgcmV0dXJuIChuZXcgVHlwZWREZXNjZW5kYW50SXRlcmF0b3IodHlwZSkpLmluY2x1ZGVTZWxmKCk7Ci0gICAgICAgICAgICBjYXNlIEF4aXMuRk9MTE9XSU5HOgotICAgICAgICAgICAgICAgIHJldHVybiBuZXcgVHlwZWRGb2xsb3dpbmdJdGVyYXRvcih0eXBlKTsKLSAgICAgICAgICAgIGNhc2UgQXhpcy5QUkVDRURJTkc6Ci0gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBUeXBlZFByZWNlZGluZ0l0ZXJhdG9yKHR5cGUpOwotICAgICAgICAgICAgY2FzZSBBeGlzLkZPTExPV0lOR1NJQkxJTkc6Ci0gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBUeXBlZEZvbGxvd2luZ1NpYmxpbmdJdGVyYXRvcih0eXBlKTsKLSAgICAgICAgICAgIGNhc2UgQXhpcy5QUkVDRURJTkdTSUJMSU5HOgotICAgICAgICAgICAgICAgIHJldHVybiBuZXcgVHlwZWRQcmVjZWRpbmdTaWJsaW5nSXRlcmF0b3IodHlwZSk7Ci0gICAgICAgICAgICBjYXNlIEF4aXMuTkFNRVNQQUNFOgotICAgICAgICAgICAgICAgIHJldHVybiAgbmV3IFR5cGVkTmFtZXNwYWNlSXRlcmF0b3IodHlwZSk7Ci0gICAgICAgICAgICBjYXNlIEF4aXMuUk9PVDoKLSAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFR5cGVkUm9vdEl0ZXJhdG9yKHR5cGUpOwotICAgICAgICAgICAgZGVmYXVsdDoKLSAgICAgICAgICAgICAgICBCYXNpc0xpYnJhcnkucnVuVGltZUVycm9yKEJhc2lzTGlicmFyeS5UWVBFRF9BWElTX1NVUFBPUlRfRVJSLAotICAgICAgICAgICAgICAgICAgICAgICAgQXhpcy5nZXROYW1lcyhheGlzKSk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRG8gbm90IHRoaW5rIHRoYXQgdGhpcyByZXR1cm5zIGFuIGl0ZXJhdG9yIGZvciB0aGUgbmFtZXNwYWNlIGF4aXMuCi0gICAgICogSXQgcmV0dXJucyBhbiBpdGVyYXRvciB3aXRoIG5vZGVzIHRoYXQgYmVsb25nIGluIGEgY2VydGFpbiBuYW1lc3BhY2UsCi0gICAgICogc3VjaCBhcyB3aXRoIDx4c2w6YXBwbHktdGVtcGxhdGVzIHNlbGVjdD0iYmxvYi9mb286KiIvPgotICAgICAqIFRoZSAnYXhpcycgc3BlY2lmaWVzIHRoZSBheGlzIGZvciB0aGUgYmFzZSBpdGVyYXRvciBmcm9tIHdoaWNoIHRoZQotICAgICAqIG5vZGVzIGFyZSB0YWtlbiwgd2hpbGUgJ25zJyBzcGVjaWZpZXMgdGhlIG5hbWVzcGFjZSBVUkkgdHlwZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIGdldE5hbWVzcGFjZUF4aXNJdGVyYXRvcihpbnQgYXhpcywgaW50IG5zKQotICAgIHsKLSAgICAgICAgaWYgKG5zID09IE5PX1RZUEUpIHsKLSAgICAgICAgICAgIHJldHVybiBFTVBUWUlURVJBVE9SOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgc3dpdGNoIChheGlzKSB7Ci0gICAgICAgICAgICAgICAgY2FzZSBBeGlzLkNISUxEOgotICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IE5hbWVzcGFjZUNoaWxkcmVuSXRlcmF0b3IobnMpOwotICAgICAgICAgICAgICAgIGNhc2UgQXhpcy5BVFRSSUJVVEU6Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgTmFtZXNwYWNlQXR0cmlidXRlSXRlcmF0b3IobnMpOwotICAgICAgICAgICAgICAgIGRlZmF1bHQ6Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgTmFtZXNwYWNlV2lsZGNhcmRJdGVyYXRvcihheGlzLCBucyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJdGVyYXRvciB0aGF0IGhhbmRsZXMgbm9kZSB0ZXN0cyB0aGF0IHRlc3QgZm9yIGEgbmFtZXNwYWNlLCBidXQgaGF2ZQotICAgICAqIGEgd2lsZCBjYXJkIGZvciB0aGUgbG9jYWwgbmFtZSBvZiB0aGUgbm9kZSwgaS5lLiwgbm9kZSB0ZXN0cyBvZiB0aGUKLSAgICAgKiBmb3JtIDxheGlzPjo6PHByZWZpeD46KgotICAgICAqLwotICAgIHB1YmxpYyBmaW5hbCBjbGFzcyBOYW1lc3BhY2VXaWxkY2FyZEl0ZXJhdG9yCi0gICAgICAgIGV4dGVuZHMgSW50ZXJuYWxBeGlzSXRlcmF0b3JCYXNlCi0gICAgewotICAgICAgICAvKioKLSAgICAgICAgICogVGhlIG5hbWVzcGFjZSB0eXBlIGluZGV4LgotICAgICAgICAgKi8KLSAgICAgICAgcHJvdGVjdGVkIGludCBtX25zVHlwZTsKLQotICAgICAgICAvKioKLSAgICAgICAgICogQSBuZXN0ZWQgdHlwZWQgYXhpcyBpdGVyYXRvciB0aGF0IHJldHJpZXZlcyBub2RlcyBvZiB0aGUgcHJpbmNpcGFsCi0gICAgICAgICAqIG5vZGUga2luZCBmb3IgdGhhdCBheGlzLgotICAgICAgICAgKi8KLSAgICAgICAgcHJvdGVjdGVkIERUTUF4aXNJdGVyYXRvciBtX2Jhc2VJdGVyYXRvcjsKLQotICAgICAgICAvKioKLSAgICAgICAgICogQ29uc3RydWN0b3IgTmFtZXNwYWNlV2lsZGNhcmQKLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIGF4aXMgVGhlIGF4aXMgdGhhdCB0aGlzIGl0ZXJhdG9yIHdpbGwgdHJhdmVyc2UKLSAgICAgICAgICogQHBhcmFtIG5zVHlwZSBUaGUgbmFtZXNwYWNlIHR5cGUgaW5kZXgKLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBOYW1lc3BhY2VXaWxkY2FyZEl0ZXJhdG9yKGludCBheGlzLCBpbnQgbnNUeXBlKSB7Ci0gICAgICAgICAgICBtX25zVHlwZSA9IG5zVHlwZTsKLQotICAgICAgICAgICAgLy8gQ3JlYXRlIGEgbmVzdGVkIGl0ZXJhdG9yIHRoYXQgd2lsbCBzZWxlY3Qgbm9kZXMgb2YKLSAgICAgICAgICAgIC8vIHRoZSBwcmluY2lwYWwgbm9kZSBraW5kIGZvciB0aGUgc2VsZWN0ZWQgYXhpcy4KLSAgICAgICAgICAgIHN3aXRjaCAoYXhpcykgewotICAgICAgICAgICAgICAgIGNhc2UgQXhpcy5BVFRSSUJVVEU6IHsKLSAgICAgICAgICAgICAgICAgICAgLy8gRm9yICJhdHRyaWJ1dGU6OnA6KiIsIHRoZSBwcmluY2lwYWwgbm9kZSBraW5kIGlzCi0gICAgICAgICAgICAgICAgICAgIC8vIGF0dHJpYnV0ZQotICAgICAgICAgICAgICAgICAgICBtX2Jhc2VJdGVyYXRvciA9IGdldEF4aXNJdGVyYXRvcihheGlzKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgY2FzZSBBeGlzLk5BTUVTUEFDRTogewotICAgICAgICAgICAgICAgICAgICAvLyBUaGlzIGNvdmVycyAibmFtZXNwYWNlOjpwOioiLiAgSXQgaXMgc3ludGFjdGljYWxseQotICAgICAgICAgICAgICAgICAgICAvLyBjb3JyZWN0LCB0aG91Z2ggaXQgZG9lc24ndCBtYWtlIG11Y2ggc2Vuc2UuCi0gICAgICAgICAgICAgICAgICAgIG1fYmFzZUl0ZXJhdG9yID0gZ2V0QXhpc0l0ZXJhdG9yKGF4aXMpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBkZWZhdWx0OiB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIEluIGFsbCBvdGhlciBjYXNlcywgdGhlIHByaW5jaXBhbCBub2RlIGtpbmQgaXMKLSAgICAgICAgICAgICAgICAgICAgLy8gZWxlbWVudAotICAgICAgICAgICAgICAgICAgICBtX2Jhc2VJdGVyYXRvciA9IGdldFR5cGVkQXhpc0l0ZXJhdG9yKGF4aXMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFRNLkVMRU1FTlRfTk9ERSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFNldCBzdGFydCB0byBFTkQgc2hvdWxkICdjbG9zZScgdGhlIGl0ZXJhdG9yLAotICAgICAgICAgKiBpLmUuIHN1YnNlcXVlbnQgY2FsbCB0byBuZXh0KCkgc2hvdWxkIHJldHVybiBFTkQuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBub2RlIFNldHMgdGhlIHJvb3Qgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgICAgICoKLSAgICAgICAgICogQHJldHVybiBBIERUTUF4aXNJdGVyYXRvciBzZXQgdG8gdGhlIHN0YXJ0IG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIHNldFN0YXJ0Tm9kZShpbnQgbm9kZSkgewotICAgICAgICAgICAgaWYgKF9pc1Jlc3RhcnRhYmxlKSB7Ci0gICAgICAgICAgICAgICAgX3N0YXJ0Tm9kZSA9IG5vZGU7Ci0gICAgICAgICAgICAgICAgbV9iYXNlSXRlcmF0b3Iuc2V0U3RhcnROb2RlKG5vZGUpOwotICAgICAgICAgICAgICAgIHJlc2V0UG9zaXRpb24oKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiB0aGlzOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIEdldCB0aGUgbmV4dCBub2RlIGluIHRoZSBpdGVyYXRpb24uCi0gICAgICAgICAqCi0gICAgICAgICAqIEByZXR1cm4gVGhlIG5leHQgbm9kZSBoYW5kbGUgaW4gdGhlIGl0ZXJhdGlvbiwgb3IgRU5ELgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIGludCBuZXh0KCkgewotICAgICAgICAgICAgaW50IG5vZGU7Ci0KLSAgICAgICAgICAgIHdoaWxlICgobm9kZSA9IG1fYmFzZUl0ZXJhdG9yLm5leHQoKSkgIT0gRU5EKSB7Ci0gICAgICAgICAgICAgICAgLy8gUmV0dXJuIG9ubHkgbm9kZXMgdGhhdCBhcmUgaW4gdGhlIHNlbGVjdGVkIG5hbWVzcGFjZQotICAgICAgICAgICAgICAgIGlmIChnZXROU1R5cGUobm9kZSkgPT0gbV9uc1R5cGUpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJldHVybk5vZGUobm9kZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICByZXR1cm4gRU5EOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFJldHVybnMgYSBkZWVwIGNvcHkgb2YgdGhpcyBpdGVyYXRvci4gIFRoZSBjbG9uZWQgaXRlcmF0b3IgaXMgbm90Ci0gICAgICAgICAqIHJlc2V0LgotICAgICAgICAgKgotICAgICAgICAgKiBAcmV0dXJuIGEgZGVlcCBjb3B5IG9mIHRoaXMgaXRlcmF0b3IuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIGNsb25lSXRlcmF0b3IoKSB7Ci0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIERUTUF4aXNJdGVyYXRvciBuZXN0ZWRDbG9uZSA9IG1fYmFzZUl0ZXJhdG9yLmNsb25lSXRlcmF0b3IoKTsKLSAgICAgICAgICAgICAgICBOYW1lc3BhY2VXaWxkY2FyZEl0ZXJhdG9yIGNsb25lID0KLSAgICAgICAgICAgICAgICAgICAgKE5hbWVzcGFjZVdpbGRjYXJkSXRlcmF0b3IpIHN1cGVyLmNsb25lKCk7Ci0KLSAgICAgICAgICAgICAgICBjbG9uZS5tX2Jhc2VJdGVyYXRvciA9IG5lc3RlZENsb25lOwotICAgICAgICAgICAgICAgIGNsb25lLm1fbnNUeXBlID0gbV9uc1R5cGU7Ci0gICAgICAgICAgICAgICAgY2xvbmUuX2lzUmVzdGFydGFibGUgPSBmYWxzZTsKLQotICAgICAgICAgICAgICAgIHJldHVybiBjbG9uZTsKLSAgICAgICAgICAgIH0gY2F0Y2ggKENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICBCYXNpc0xpYnJhcnkucnVuVGltZUVycm9yKEJhc2lzTGlicmFyeS5JVEVSQVRPUl9DTE9ORV9FUlIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlLnRvU3RyaW5nKCkpOwotICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFRydWUgaWYgdGhpcyBpdGVyYXRvciBoYXMgYSByZXZlcnNlZCBheGlzLgotICAgICAgICAgKgotICAgICAgICAgKiBAcmV0dXJuIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoaXMgaXRlcmF0b3IgaXMgYSByZXZlcnNlZCBheGlzLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIGJvb2xlYW4gaXNSZXZlcnNlKCkgewotICAgICAgICAgICAgcmV0dXJuIG1fYmFzZUl0ZXJhdG9yLmlzUmV2ZXJzZSgpOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIHZvaWQgc2V0TWFyaygpIHsKLSAgICAgICAgICAgIG1fYmFzZUl0ZXJhdG9yLnNldE1hcmsoKTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyB2b2lkIGdvdG9NYXJrKCkgewotICAgICAgICAgICAgbV9iYXNlSXRlcmF0b3IuZ290b01hcmsoKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEl0ZXJhdG9yIHRoYXQgcmV0dXJucyBjaGlsZHJlbiB3aXRoaW4gYSBnaXZlbiBuYW1lc3BhY2UgZm9yIGEKLSAgICAgKiBnaXZlbiBub2RlLiBUaGUgZnVuY3Rpb25hbGl0eSBjaG91bGQgYmUgYWNoaWV2ZWQgYnkgcHV0dGluZyBhCi0gICAgICogZmlsdGVyIG9uIHRvcCBvZiBhIGJhc2ljIGNoaWxkIGl0ZXJhdG9yLCBidXQgYSBzcGVjaWFsaXNlZAotICAgICAqIGl0ZXJhdG9yIGlzIHVzZWQgZm9yIGVmZmljaWVuY3kgKGJvdGggc3BlZWQgYW5kIHNpemUgb2YgdHJhbnNsZXQpLgotICAgICAqLwotICAgIHB1YmxpYyBmaW5hbCBjbGFzcyBOYW1lc3BhY2VDaGlsZHJlbkl0ZXJhdG9yCi0gICAgICAgIGV4dGVuZHMgSW50ZXJuYWxBeGlzSXRlcmF0b3JCYXNlCi0gICAgewotCi0gICAgICAgIC8qKiBUaGUgZXh0ZW5kZWQgdHlwZSBJRCBiZWluZyByZXF1ZXN0ZWQuICovCi0gICAgICAgIHByaXZhdGUgZmluYWwgaW50IF9uc1R5cGU7Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIENvbnN0cnVjdG9yIE5hbWVzcGFjZUNoaWxkcmVuSXRlcmF0b3IKLSAgICAgICAgICoKLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIHR5cGUgVGhlIGV4dGVuZGVkIHR5cGUgSUQgYmVpbmcgcmVxdWVzdGVkLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIE5hbWVzcGFjZUNoaWxkcmVuSXRlcmF0b3IoZmluYWwgaW50IHR5cGUpIHsKLSAgICAgICAgICAgIF9uc1R5cGUgPSB0eXBlOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFNldCBzdGFydCB0byBFTkQgc2hvdWxkICdjbG9zZScgdGhlIGl0ZXJhdG9yLAotICAgICAgICAgKiBpLmUuIHN1YnNlcXVlbnQgY2FsbCB0byBuZXh0KCkgc2hvdWxkIHJldHVybiBFTkQuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBub2RlIFNldHMgdGhlIHJvb3Qgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgICAgICoKLSAgICAgICAgICogQHJldHVybiBBIERUTUF4aXNJdGVyYXRvciBzZXQgdG8gdGhlIHN0YXJ0IG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIHNldFN0YXJ0Tm9kZShpbnQgbm9kZSkgewotICAgICAgICAgICAgLy8lSFolOiBBZGRlZCByZWZlcmVuY2UgdG8gRFRNRGVmYXVsdEJhc2UuUk9PVE5PREUgYmFjayBpbiwgdGVtcG9yYXJpbHkKLSAgICAgICAgICAgIGlmIChub2RlID09IERUTURlZmF1bHRCYXNlLlJPT1ROT0RFKSB7Ci0gICAgICAgICAgICAgICAgbm9kZSA9IGdldERvY3VtZW50KCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmIChfaXNSZXN0YXJ0YWJsZSkgewotICAgICAgICAgICAgICAgIF9zdGFydE5vZGUgPSBub2RlOwotICAgICAgICAgICAgICAgIF9jdXJyZW50Tm9kZSA9IChub2RlID09IERUTS5OVUxMKSA/IERUTS5OVUxMIDogTk9UUFJPQ0VTU0VEOwotCi0gICAgICAgICAgICAgICAgcmV0dXJuIHJlc2V0UG9zaXRpb24oKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgcmV0dXJuIHRoaXM7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogR2V0IHRoZSBuZXh0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbi4KLSAgICAgICAgICoKLSAgICAgICAgICogQHJldHVybiBUaGUgbmV4dCBub2RlIGhhbmRsZSBpbiB0aGUgaXRlcmF0aW9uLCBvciBFTkQuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgaW50IG5leHQoKSB7Ci0gICAgICAgICAgICBpZiAoX2N1cnJlbnROb2RlICE9IERUTS5OVUxMKSB7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgbm9kZSA9IChOT1RQUk9DRVNTRUQgPT0gX2N1cnJlbnROb2RlKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gX2ZpcnN0Y2gobWFrZU5vZGVJZGVudGl0eShfc3RhcnROb2RlKSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IF9uZXh0c2liKF9jdXJyZW50Tm9kZSk7Ci0gICAgICAgICAgICAgICAgICAgICBub2RlICE9IEVORDsKLSAgICAgICAgICAgICAgICAgICAgIG5vZGUgPSBfbmV4dHNpYihub2RlKSkgewotICAgICAgICAgICAgICAgICAgICBpbnQgbm9kZUhhbmRsZSA9IG1ha2VOb2RlSGFuZGxlKG5vZGUpOwotCi0gICAgICAgICAgICAgICAgICAgIGlmIChnZXROU1R5cGUobm9kZUhhbmRsZSkgPT0gX25zVHlwZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgX2N1cnJlbnROb2RlID0gbm9kZTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJldHVybk5vZGUobm9kZUhhbmRsZSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIHJldHVybiBFTkQ7Ci0gICAgICAgIH0KLSAgICB9ICAvLyBlbmQgb2YgTmFtZXNwYWNlQ2hpbGRyZW5JdGVyYXRvcgotCi0gICAgLyoqCi0gICAgICogSXRlcmF0b3IgdGhhdCByZXR1cm5zIGF0dHJpYnV0ZXMgd2l0aGluIGEgZ2l2ZW4gbmFtZXNwYWNlIGZvciBhIG5vZGUuCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIGNsYXNzIE5hbWVzcGFjZUF0dHJpYnV0ZUl0ZXJhdG9yCi0gICAgICAgICAgICBleHRlbmRzIEludGVybmFsQXhpc0l0ZXJhdG9yQmFzZQotICAgIHsKLQotICAgICAgICAvKiogVGhlIGV4dGVuZGVkIHR5cGUgSUQgYmVpbmcgcmVxdWVzdGVkLiAqLwotICAgICAgICBwcml2YXRlIGZpbmFsIGludCBfbnNUeXBlOwotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBDb25zdHJ1Y3RvciBOYW1lc3BhY2VBdHRyaWJ1dGVJdGVyYXRvcgotICAgICAgICAgKgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gbnNUeXBlIFRoZSBleHRlbmRlZCB0eXBlIElEIGJlaW5nIHJlcXVlc3RlZC4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBOYW1lc3BhY2VBdHRyaWJ1dGVJdGVyYXRvcihpbnQgbnNUeXBlKSB7Ci0gICAgICAgICAgICBzdXBlcigpOwotCi0gICAgICAgICAgICBfbnNUeXBlID0gbnNUeXBlOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFNldCBzdGFydCB0byBFTkQgc2hvdWxkICdjbG9zZScgdGhlIGl0ZXJhdG9yLAotICAgICAgICAgKiBpLmUuIHN1YnNlcXVlbnQgY2FsbCB0byBuZXh0KCkgc2hvdWxkIHJldHVybiBFTkQuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBub2RlIFNldHMgdGhlIHJvb3Qgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgICAgICoKLSAgICAgICAgICogQHJldHVybiBBIERUTUF4aXNJdGVyYXRvciBzZXQgdG8gdGhlIHN0YXJ0IG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIHNldFN0YXJ0Tm9kZShpbnQgbm9kZSkgewotICAgICAgICAgICAgLy8lSFolOiBBZGRlZCByZWZlcmVuY2UgdG8gRFRNRGVmYXVsdEJhc2UuUk9PVE5PREUgYmFjayBpbiwgdGVtcG9yYXJpbHkKLSAgICAgICAgICAgIGlmIChub2RlID09IERUTURlZmF1bHRCYXNlLlJPT1ROT0RFKSB7Ci0gICAgICAgICAgICAgICAgbm9kZSA9IGdldERvY3VtZW50KCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmIChfaXNSZXN0YXJ0YWJsZSkgewotICAgICAgICAgICAgICAgIGludCBuc1R5cGUgPSBfbnNUeXBlOwotCi0gICAgICAgICAgICAgICAgX3N0YXJ0Tm9kZSA9IG5vZGU7Ci0KLSAgICAgICAgICAgICAgICBmb3IgKG5vZGUgPSBnZXRGaXJzdEF0dHJpYnV0ZShub2RlKTsKLSAgICAgICAgICAgICAgICAgICAgIG5vZGUgIT0gRU5EOwotICAgICAgICAgICAgICAgICAgICAgbm9kZSA9IGdldE5leHRBdHRyaWJ1dGUobm9kZSkpIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGdldE5TVHlwZShub2RlKSA9PSBuc1R5cGUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgX2N1cnJlbnROb2RlID0gbm9kZTsKLSAgICAgICAgICAgICAgICByZXR1cm4gcmVzZXRQb3NpdGlvbigpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICByZXR1cm4gdGhpczsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBHZXQgdGhlIG5leHQgbm9kZSBpbiB0aGUgaXRlcmF0aW9uLgotICAgICAgICAgKgotICAgICAgICAgKiBAcmV0dXJuIFRoZSBuZXh0IG5vZGUgaGFuZGxlIGluIHRoZSBpdGVyYXRpb24sIG9yIEVORC4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBpbnQgbmV4dCgpIHsKLSAgICAgICAgICAgIGludCBub2RlID0gX2N1cnJlbnROb2RlOwotICAgICAgICAgICAgaW50IG5zVHlwZSA9IF9uc1R5cGU7Ci0gICAgICAgICAgICBpbnQgbmV4dE5vZGU7Ci0KLSAgICAgICAgICAgIGlmIChub2RlID09IEVORCkgewotICAgICAgICAgICAgICAgIHJldHVybiBFTkQ7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGZvciAobmV4dE5vZGUgPSBnZXROZXh0QXR0cmlidXRlKG5vZGUpOwotICAgICAgICAgICAgICAgICBuZXh0Tm9kZSAhPSBFTkQ7Ci0gICAgICAgICAgICAgICAgIG5leHROb2RlID0gZ2V0TmV4dEF0dHJpYnV0ZShuZXh0Tm9kZSkpIHsKLSAgICAgICAgICAgICAgICBpZiAoZ2V0TlNUeXBlKG5leHROb2RlKSA9PSBuc1R5cGUpIHsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBfY3VycmVudE5vZGUgPSBuZXh0Tm9kZTsKLQotICAgICAgICAgICAgcmV0dXJuIHJldHVybk5vZGUobm9kZSk7Ci0gICAgICAgIH0KLSAgICB9ICAvLyBlbmQgb2YgTmFtZXNwYWNlQXR0cmlidXRlSXRlcmF0b3IKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYW4gaXRlcmF0b3Igd2l0aCBhbGwgZGVzY2VuZGFudHMgb2YgYSBub2RlIHRoYXQgYXJlIG9mCi0gICAgICogYSBnaXZlbiB0eXBlLgotICAgICAqLwotICAgIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3IgZ2V0VHlwZWREZXNjZW5kYW50SXRlcmF0b3IoaW50IHR5cGUpCi0gICAgewotICAgICAgICByZXR1cm4gbmV3IFR5cGVkRGVzY2VuZGFudEl0ZXJhdG9yKHR5cGUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIG50aCBkZXNjZW5kYW50IG9mIGEgbm9kZQotICAgICAqLwotICAgIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3IgZ2V0TnRoRGVzY2VuZGFudChpbnQgdHlwZSwgaW50IG4sIGJvb2xlYW4gaW5jbHVkZXNlbGYpCi0gICAgewotICAgICAgICByZXR1cm4gbmV3IE50aERlc2NlbmRhbnRJdGVyYXRvcihuKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb3B5IHRoZSBzdHJpbmcgdmFsdWUgb2YgYSBub2RlIGRpcmVjdGx5IHRvIGFuIG91dHB1dCBoYW5kbGVyCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY2hhcmFjdGVycyhmaW5hbCBpbnQgbm9kZSwgU2VyaWFsaXphdGlvbkhhbmRsZXIgaGFuZGxlcikKLSAgICAgICAgdGhyb3dzIFRyYW5zbGV0RXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAobm9kZSAhPSBEVE0uTlVMTCkgewotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICBkaXNwYXRjaENoYXJhY3RlcnNFdmVudHMobm9kZSwgaGFuZGxlciwgZmFsc2UpOwotICAgICAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNsZXRFeGNlcHRpb24oZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb3B5IGEgbm9kZS1zZXQgdG8gYW4gb3V0cHV0IGhhbmRsZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBjb3B5KERUTUF4aXNJdGVyYXRvciBub2RlcywgU2VyaWFsaXphdGlvbkhhbmRsZXIgaGFuZGxlcikKLSAgICAgICAgdGhyb3dzIFRyYW5zbGV0RXhjZXB0aW9uCi0gICAgewotICAgICAgICBpbnQgbm9kZTsKLSAgICAgICAgd2hpbGUgKChub2RlID0gbm9kZXMubmV4dCgpKSAhPSBEVE0uTlVMTCkgewotICAgICAgICAgICAgY29weShub2RlLCBoYW5kbGVyKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvcHkgdGhlIHdob2xlIHRyZWUgdG8gYW4gb3V0cHV0IGhhbmRsZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBjb3B5KFNlcmlhbGl6YXRpb25IYW5kbGVyIGhhbmRsZXIpIHRocm93cyBUcmFuc2xldEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgY29weShnZXREb2N1bWVudCgpLCBoYW5kbGVyKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBQZXJmb3JtcyBhIGRlZXAgY29weSAocmVmLiBYU0xzIGNvcHktb2YoKSkKLSAgICAgKgotICAgICAqIFRPRE86IENvcHkgbmFtZXNwYWNlIGRlY2xhcmF0aW9ucy4gQ2FuJ3QgYmUgZG9uZSB1bnRpbCB3ZQotICAgICAqICAgICAgIGFkZCBuYW1lc3BhY2Ugbm9kZXMgYW5kIGtlZXAgdHJhY2sgb2YgTlMgcHJlZml4ZXMKLSAgICAgKiBUT0RPOiBDb3B5IGNvbW1lbnQgbm9kZXMKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBjb3B5KGZpbmFsIGludCBub2RlLCBTZXJpYWxpemF0aW9uSGFuZGxlciBoYW5kbGVyKQotICAgICAgICB0aHJvd3MgVHJhbnNsZXRFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGNvcHkobm9kZSwgaGFuZGxlciwgZmFsc2UgKTsKLSAgICB9Ci0KLQotIHByaXZhdGUgZmluYWwgdm9pZCBjb3B5KGZpbmFsIGludCBub2RlLCBTZXJpYWxpemF0aW9uSGFuZGxlciBoYW5kbGVyLCBib29sZWFuIGlzQ2hpbGQpCi0gICAgICAgIHRocm93cyBUcmFuc2xldEV4Y2VwdGlvbgotICAgIHsKLSAgICAgaW50IG5vZGVJRCA9IG1ha2VOb2RlSWRlbnRpdHkobm9kZSk7Ci0gICAgICAgIGludCBlVHlwZSA9IF9leHB0eXBlMihub2RlSUQpOwotICAgICAgICBpbnQgdHlwZSA9IF9leHB0eXBlMlR5cGUoZVR5cGUpOwotCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBzd2l0Y2godHlwZSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBjYXNlIERUTS5ST09UX05PREU6Ci0gICAgICAgICAgICAgICAgY2FzZSBEVE0uRE9DVU1FTlRfTk9ERToKLSAgICAgICAgICAgICAgICAgICAgZm9yKGludCBjID0gX2ZpcnN0Y2gyKG5vZGVJRCk7IGMgIT0gRFRNLk5VTEw7IGMgPSBfbmV4dHNpYjIoYykpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGNvcHkobWFrZU5vZGVIYW5kbGUoYyksIGhhbmRsZXIsIHRydWUpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGNhc2UgRFRNLlBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERToKLSAgICAgICAgICAgICAgICAgICAgY29weVBJKG5vZGUsIGhhbmRsZXIpOwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICBjYXNlIERUTS5DT01NRU5UX05PREU6Ci0gICAgICAgICAgICAgICAgICAgIGhhbmRsZXIuY29tbWVudChnZXRTdHJpbmdWYWx1ZVgobm9kZSkpOwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICBjYXNlIERUTS5URVhUX05PREU6Ci0gICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gb2xkRXNjYXBlU2V0dGluZyA9IGZhbHNlOwotICAgICAgICAgICAgICAgICAgICBib29sZWFuIGVzY2FwZUJpdCA9IGZhbHNlOwotCi0gICAgICAgICAgICAgICAgICAgIGlmIChfZG9udEVzY2FwZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBlc2NhcGVCaXQgPSBfZG9udEVzY2FwZS5nZXRCaXQoZ2V0Tm9kZUlkZW50KG5vZGUpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlc2NhcGVCaXQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbGRFc2NhcGVTZXR0aW5nID0gaGFuZGxlci5zZXRFc2NhcGluZyhmYWxzZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICBjb3B5VGV4dE5vZGUobm9kZUlELCBoYW5kbGVyKTsKLQotICAgICAgICAgICAgICAgICAgICBpZiAoZXNjYXBlQml0KSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVyLnNldEVzY2FwaW5nKG9sZEVzY2FwZVNldHRpbmcpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGNhc2UgRFRNLkFUVFJJQlVURV9OT0RFOgotICAgICAgICAgICAgICAgICAgICBjb3B5QXR0cmlidXRlKG5vZGVJRCwgZVR5cGUsIGhhbmRsZXIpOwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICBjYXNlIERUTS5OQU1FU1BBQ0VfTk9ERToKLSAgICAgICAgICAgICAgICAgICAgaGFuZGxlci5uYW1lc3BhY2VBZnRlclN0YXJ0RWxlbWVudChnZXROb2RlTmFtZVgobm9kZSksIGdldE5vZGVWYWx1ZShub2RlKSk7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGRlZmF1bHQ6Ci0gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlID09IERUTS5FTEVNRU5UX05PREUpCi0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIFN0YXJ0IGVsZW1lbnQgZGVmaW5pdGlvbgotICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIG5hbWUgPSBjb3B5RWxlbWVudChub2RlSUQsIGVUeXBlLCBoYW5kbGVyKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vaWYoaXNDaGlsZCkgPT4gbm90IHRvIGNvcHkgYW55IG5hbWVzcGFjZXMgIGZyb20gcGFyZW50cwotICAgICAgICAgICAgICAgICAgICAgICAgLy8gZWxzZSBjb3B5IGFsbCBuYW1lc3BhY2VzIGluIHNjb3BlCi0gICAgICAgICAgICAgICAgICAgICAgICBjb3B5TlMobm9kZUlELCBoYW5kbGVyLCFpc0NoaWxkKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGNvcHlBdHRyaWJ1dGVzKG5vZGVJRCwgaGFuZGxlcik7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBDb3B5IGVsZW1lbnQgY2hpbGRyZW4KLSAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGMgPSBfZmlyc3RjaDIobm9kZUlEKTsgYyAhPSBEVE0uTlVMTDsgYyA9IF9uZXh0c2liMihjKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvcHkobWFrZU5vZGVIYW5kbGUoYyksIGhhbmRsZXIsIHRydWUpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBDbG9zZSBlbGVtZW50IGRlZmluaXRpb24KLSAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZXIuZW5kRWxlbWVudChuYW1lKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAvLyBTaGFsbG93IGNvcHkgb2YgYXR0cmlidXRlIHRvIG91dHB1dCBoYW5kbGVyCi0gICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIHVyaSA9IGdldE5hbWVzcGFjZU5hbWUobm9kZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAodXJpLmxlbmd0aCgpICE9IDApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgcHJlZml4ID0gZ2V0UHJlZml4KG5vZGUpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZXIubmFtZXNwYWNlQWZ0ZXJTdGFydEVsZW1lbnQocHJlZml4LCB1cmkpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlci5hZGRBdHRyaWJ1dGUoZ2V0Tm9kZU5hbWUobm9kZSksIGdldE5vZGVWYWx1ZShub2RlKSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNsZXRFeGNlcHRpb24oZSk7Ci0gICAgICAgIH0KLQotICAgIH0KLSAgICAvKioKLSAgICAgKiBDb3BpZXMgYSBwcm9jZXNzaW5nIGluc3RydWN0aW9uIG5vZGUgdG8gYW4gb3V0cHV0IGhhbmRsZXIKLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgY29weVBJKGZpbmFsIGludCBub2RlLCBTZXJpYWxpemF0aW9uSGFuZGxlciBoYW5kbGVyKQotICAgICAgICB0aHJvd3MgVHJhbnNsZXRFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGZpbmFsIFN0cmluZyB0YXJnZXQgPSBnZXROb2RlTmFtZShub2RlKTsKLSAgICAgICAgZmluYWwgU3RyaW5nIHZhbHVlID0gZ2V0U3RyaW5nVmFsdWVYKG5vZGUpOwotCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBoYW5kbGVyLnByb2Nlc3NpbmdJbnN0cnVjdGlvbih0YXJnZXQsIHZhbHVlKTsKLSAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBUcmFuc2xldEV4Y2VwdGlvbihlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFBlcmZvcm1zIGEgc2hhbGxvdyBjb3B5IChyZWYuIFhTTHMgY29weSgpKQotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgc2hhbGxvd0NvcHkoZmluYWwgaW50IG5vZGUsIFNlcmlhbGl6YXRpb25IYW5kbGVyIGhhbmRsZXIpCi0gICAgICAgIHRocm93cyBUcmFuc2xldEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaW50IG5vZGVJRCA9IG1ha2VOb2RlSWRlbnRpdHkobm9kZSk7Ci0gICAgICAgIGludCBleHB0eXBlID0gX2V4cHR5cGUyKG5vZGVJRCk7Ci0gICAgICAgIGludCB0eXBlID0gX2V4cHR5cGUyVHlwZShleHB0eXBlKTsKLQotICAgICAgICB0cnkgewotICAgICAgICAgICAgc3dpdGNoKHR5cGUpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgY2FzZSBEVE0uRUxFTUVOVF9OT0RFOgotICAgICAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgbmFtZSA9IGNvcHlFbGVtZW50KG5vZGVJRCwgZXhwdHlwZSwgaGFuZGxlcik7Ci0gICAgICAgICAgICAgICAgICAgIGNvcHlOUyhub2RlSUQsIGhhbmRsZXIsIHRydWUpOwotICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmFtZTsKLSAgICAgICAgICAgICAgICBjYXNlIERUTS5ST09UX05PREU6Ci0gICAgICAgICAgICAgICAgY2FzZSBEVE0uRE9DVU1FTlRfTk9ERToKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEVNUFRZU1RSSU5HOwotICAgICAgICAgICAgICAgIGNhc2UgRFRNLlRFWFRfTk9ERToKLSAgICAgICAgICAgICAgICAgICAgY29weVRleHROb2RlKG5vZGVJRCwgaGFuZGxlcik7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICAgICAgICAgIGNhc2UgRFRNLlBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERToKLSAgICAgICAgICAgICAgICAgICAgY29weVBJKG5vZGUsIGhhbmRsZXIpOwotICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgICAgICAgICBjYXNlIERUTS5DT01NRU5UX05PREU6Ci0gICAgICAgICAgICAgICAgICAgIGhhbmRsZXIuY29tbWVudChnZXRTdHJpbmdWYWx1ZVgobm9kZSkpOwotICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgICAgICAgICBjYXNlIERUTS5OQU1FU1BBQ0VfTk9ERToKLSAgICAgICAgICAgICAgICAgICAgaGFuZGxlci5uYW1lc3BhY2VBZnRlclN0YXJ0RWxlbWVudChnZXROb2RlTmFtZVgobm9kZSksIGdldE5vZGVWYWx1ZShub2RlKSk7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICAgICAgICAgIGNhc2UgRFRNLkFUVFJJQlVURV9OT0RFOgotICAgICAgICAgICAgICAgICAgICBjb3B5QXR0cmlidXRlKG5vZGVJRCwgZXhwdHlwZSwgaGFuZGxlcik7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICAgICAgICAgIGRlZmF1bHQ6Ci0gICAgICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyB1cmkxID0gZ2V0TmFtZXNwYWNlTmFtZShub2RlKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKHVyaTEubGVuZ3RoKCkgIT0gMCkgewotICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIHByZWZpeCA9IGdldFByZWZpeChub2RlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZXIubmFtZXNwYWNlQWZ0ZXJTdGFydEVsZW1lbnQocHJlZml4LCB1cmkxKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBoYW5kbGVyLmFkZEF0dHJpYnV0ZShnZXROb2RlTmFtZShub2RlKSwgZ2V0Tm9kZVZhbHVlKG5vZGUpKTsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNsZXRFeGNlcHRpb24oZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGEgbm9kZScgZGVmaW5lZCBsYW5ndWFnZSBmb3IgYSBub2RlIChpZiBhbnkpCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRMYW5ndWFnZShpbnQgbm9kZSkKLSAgICB7Ci0gICAgICAgIGludCBwYXJlbnQgPSBub2RlOwotICAgICAgICB3aGlsZSAoRFRNLk5VTEwgIT0gcGFyZW50KSB7Ci0gICAgICAgICAgICBpZiAoRFRNLkVMRU1FTlRfTk9ERSA9PSBnZXROb2RlVHlwZShwYXJlbnQpKSB7Ci0gICAgICAgICAgICAgICAgaW50IGxhbmdBdHRyID0gZ2V0QXR0cmlidXRlTm9kZShwYXJlbnQsICJodHRwOi8vd3d3LnczLm9yZy9YTUwvMTk5OC9uYW1lc3BhY2UiLCAibGFuZyIpOwotCi0gICAgICAgICAgICAgICAgaWYgKERUTS5OVUxMICE9IGxhbmdBdHRyKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBnZXROb2RlVmFsdWUobGFuZ0F0dHIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgcGFyZW50ID0gZ2V0UGFyZW50KHBhcmVudCk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuKG51bGwpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYW4gaW5zdGFuY2Ugb2YgdGhlIERPTUJ1aWxkZXIgaW5uZXIgY2xhc3MKLSAgICAgKiBUaGlzIGNsYXNzIHdpbGwgY29uc3VtZSB0aGUgaW5wdXQgZG9jdW1lbnQgdGhyb3VnaCBhIFNBWDIKLSAgICAgKiBpbnRlcmZhY2UgYW5kIHBvcHVsYXRlIHRoZSB0cmVlLgotICAgICAqLwotICAgIHB1YmxpYyBET01CdWlsZGVyIGdldEJ1aWxkZXIoKQotICAgIHsKLSAgICAgICAgcmV0dXJuIHRoaXM7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIGEgU2VyaWFsaXphdGlvbkhhbmRsZXIgZm9yIG91dHB1dCBoYW5kbGluZy4KLSAgICAgKiBUaGlzIG1ldGhvZCBpcyB1c2VkIGJ5IFJlc3VsdCBUcmVlIEZyYWdtZW50cy4KLSAgICAgKi8KLSAgICBwdWJsaWMgU2VyaWFsaXphdGlvbkhhbmRsZXIgZ2V0T3V0cHV0RG9tQnVpbGRlcigpCi0gICAgewotICAgICAgICByZXR1cm4gbmV3IFRvWE1MU0FYSGFuZGxlcih0aGlzLCAiVVRGLTgiKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gYSBpbnN0YW5jZSBvZiBhIERPTSBjbGFzcyB0byBiZSB1c2VkIGFzIGFuIFJURgotICAgICAqLwotICAgIHB1YmxpYyBET00gZ2V0UmVzdWx0VHJlZUZyYWcoaW50IGluaXRTaXplLCBpbnQgcnRmVHlwZSkKLSAgICB7Ci0gICAgICAgIHJldHVybiBnZXRSZXN1bHRUcmVlRnJhZyhpbml0U2l6ZSwgcnRmVHlwZSwgdHJ1ZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIGEgaW5zdGFuY2Ugb2YgYSBET00gY2xhc3MgdG8gYmUgdXNlZCBhcyBhbiBSVEYKLSAgICAgKgotICAgICAqIEBwYXJhbSBpbml0U2l6ZSBUaGUgaW5pdGlhbCBzaXplIG9mIHRoZSBET00uCi0gICAgICogQHBhcmFtIHJ0ZlR5cGUgVGhlIHR5cGUgb2YgdGhlIFJURgotICAgICAqIEBwYXJhbSBhZGRUb01hbmFnZXIgdHJ1ZSBpZiB0aGUgUlRGIHNob3VsZCBiZSByZWdpc3RlcmVkIHdpdGggdGhlIERUTU1hbmFnZXIuCi0gICAgICogQHJldHVybiBUaGUgRE9NIG9iamVjdCB3aGljaCByZXByZXNlbnRzIHRoZSBSVEYuCi0gICAgICovCi0gICAgcHVibGljIERPTSBnZXRSZXN1bHRUcmVlRnJhZyhpbnQgaW5pdFNpemUsIGludCBydGZUeXBlLCBib29sZWFuIGFkZFRvTWFuYWdlcikKLSAgICB7Ci0gICAgICAgIGlmIChydGZUeXBlID09IERPTS5TSU1QTEVfUlRGKSB7Ci0gICAgICAgICAgICBpZiAoYWRkVG9NYW5hZ2VyKSB7Ci0gICAgICAgICAgICAgICAgaW50IGR0bVBvcyA9IF9kdG1NYW5hZ2VyLmdldEZpcnN0RnJlZURUTUlEKCk7Ci0gICAgICAgICAgICAgICAgU2ltcGxlUmVzdWx0VHJlZUltcGwgcnRmID0gbmV3IFNpbXBsZVJlc3VsdFRyZWVJbXBsKF9kdG1NYW5hZ2VyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR0bVBvcyA8PCBEVE1NYW5hZ2VyLklERU5UX0RUTV9OT0RFX0JJVFMpOwotICAgICAgICAgICAgICAgIF9kdG1NYW5hZ2VyLmFkZERUTShydGYsIGR0bVBvcywgMCk7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHJ0ZjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIHJldHVybiBuZXcgU2ltcGxlUmVzdWx0VHJlZUltcGwoX2R0bU1hbmFnZXIsIDApOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKHJ0ZlR5cGUgPT0gRE9NLkFEQVBUSVZFX1JURikgewotICAgICAgICAgICAgaWYgKGFkZFRvTWFuYWdlcikgewotICAgICAgICAgICAgICAgIGludCBkdG1Qb3MgPSBfZHRtTWFuYWdlci5nZXRGaXJzdEZyZWVEVE1JRCgpOwotICAgICAgICAgICAgICAgIEFkYXB0aXZlUmVzdWx0VHJlZUltcGwgcnRmID0gbmV3IEFkYXB0aXZlUmVzdWx0VHJlZUltcGwoX2R0bU1hbmFnZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkdG1Qb3MgPDwgRFRNTWFuYWdlci5JREVOVF9EVE1fTk9ERV9CSVRTLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbV93c2ZpbHRlciwgaW5pdFNpemUsIG1fYnVpbGRJZEluZGV4KTsKLSAgICAgICAgICAgICAgICBfZHRtTWFuYWdlci5hZGREVE0ocnRmLCBkdG1Qb3MsIDApOwotICAgICAgICAgICAgICAgIHJldHVybiBydGY7Ci0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQWRhcHRpdmVSZXN1bHRUcmVlSW1wbChfZHRtTWFuYWdlciwgMCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fd3NmaWx0ZXIsIGluaXRTaXplLCBtX2J1aWxkSWRJbmRleCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gKERPTSkgX2R0bU1hbmFnZXIuZ2V0RFRNKG51bGwsIHRydWUsIG1fd3NmaWx0ZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUsIGZhbHNlLCBmYWxzZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5pdFNpemUsIG1fYnVpbGRJZEluZGV4KTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybiB0aGUgYXR0cmlidXRlcyBtYXAuCi0gICAgICogQHJldHVybiB0aGUgYXR0cmlidXRlcyBtYXAuCi0gICAgICovCi0gICAgcHVibGljIE1hcDxTdHJpbmcsIEludGVnZXI+IGdldEVsZW1lbnRzV2l0aElEcygpIHsKLSAgICAgICAgcmV0dXJuIG1faWRBdHRyaWJ1dGVzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoZSBnZXRVbnBhcnNlZEVudGl0eVVSSSBmdW5jdGlvbiByZXR1cm5zIHRoZSBVUkkgb2YgdGhlIHVucGFyc2VkCi0gICAgICogZW50aXR5IHdpdGggdGhlIHNwZWNpZmllZCBuYW1lIGluIHRoZSBzYW1lIGRvY3VtZW50IGFzIHRoZSBjb250ZXh0Ci0gICAgICogbm9kZSAoc2VlIFszLjMgVW5wYXJzZWQgRW50aXRpZXNdKS4gSXQgcmV0dXJucyB0aGUgZW1wdHkgc3RyaW5nIGlmCi0gICAgICogdGhlcmUgaXMgbm8gc3VjaCBlbnRpdHkuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRVbnBhcnNlZEVudGl0eVVSSShTdHJpbmcgbmFtZSkKLSAgICB7Ci0gICAgICAgIC8vIFNwZWNpYWwgaGFuZGxpbmcgZm9yIERPTSBpbnB1dAotICAgICAgICBpZiAoX2RvY3VtZW50ICE9IG51bGwpIHsKLSAgICAgICAgICAgIFN0cmluZyB1cmkgPSAiIjsKLSAgICAgICAgICAgIERvY3VtZW50VHlwZSBkb2N0eXBlID0gX2RvY3VtZW50LmdldERvY3R5cGUoKTsKLSAgICAgICAgICAgIGlmIChkb2N0eXBlICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBOYW1lZE5vZGVNYXAgZW50aXRpZXMgPSBkb2N0eXBlLmdldEVudGl0aWVzKCk7Ci0KLSAgICAgICAgICAgICAgICBpZiAoZW50aXRpZXMgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gdXJpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIEVudGl0eSBlbnRpdHkgPSAoRW50aXR5KSBlbnRpdGllcy5nZXROYW1lZEl0ZW0obmFtZSk7Ci0KLSAgICAgICAgICAgICAgICBpZiAoZW50aXR5ID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHVyaTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBTdHJpbmcgbm90YXRpb25OYW1lID0gZW50aXR5LmdldE5vdGF0aW9uTmFtZSgpOwotICAgICAgICAgICAgICAgIGlmIChub3RhdGlvbk5hbWUgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICB1cmkgPSBlbnRpdHkuZ2V0U3lzdGVtSWQoKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKHVyaSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICB1cmkgPSBlbnRpdHkuZ2V0UHVibGljSWQoKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiB1cmk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gc3VwZXIuZ2V0VW5wYXJzZWRFbnRpdHlVUkkobmFtZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCByZWxlYXNlKCkgewotICAgICAgICBfZHRtTWFuYWdlci5yZWxlYXNlKHRoaXMsIHRydWUpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvZG9tL1NpbXBsZVJlc3VsdFRyZWVJbXBsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2RvbS9TaW1wbGVSZXN1bHRUcmVlSW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzZDcxYzZkLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvZG9tL1NpbXBsZVJlc3VsdFRyZWVJbXBsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMDI0ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMTUsIDIwMTYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKi8KLS8qCi0gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKLSAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAotICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgotICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKLSAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCi0gKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogU2ltcGxlUmVzdWx0VHJlZUltcGwuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8wNiAxMDowOToyNSBwdmVkdWxhIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmRvbTsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5ET007Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLlN0cmlwRmlsdGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5UcmFuc2xldEV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5BeGlzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1BeGlzSXRlcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNQXhpc1RyYXZlcnNlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1NYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLnJlZi5EVE1BeGlzSXRlcmF0b3JCYXNlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLnJlZi5EVE1NYW5hZ2VyRGVmYXVsdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXIuRW1wdHlTZXJpYWxpemVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplci5TZXJpYWxpemF0aW9uSGFuZGxlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLlhNTFN0cmluZzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLlhNTFN0cmluZ0RlZmF1bHQ7Ci1pbXBvcnQgamF2YS51dGlsLk1hcDsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlNvdXJjZUxvY2F0b3I7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlTGlzdDsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci0KLS8qKgotICogVGhpcyBjbGFzcyByZXByZXNlbnRzIGEgbGlnaHQtd2VpZ2h0IERPTSBtb2RlbCBmb3Igc2ltcGxlIHJlc3VsdCB0cmVlIGZyYWdtZW50KFJURikuCi0gKiBBIHNpbXBsZSBSVEYgaXMgYW4gUlRGIHRoYXQgaGFzIG9ubHkgb25lIFRleHQgbm9kZS4gVGhlIFRleHQgbm9kZSBjYW4gYmUgcHJvZHVjZWQgYnkgYQotICogY29tYmluYXRpb24gb2YgVGV4dCwgeHNsOnZhbHVlLW9mIGFuZCB4c2w6bnVtYmVyIGluc3RydWN0aW9ucy4gSXQgY2FuIGFsc28gYmUgcHJvZHVjZWQKLSAqIGJ5IGEgY29udHJvbCBzdHJ1Y3R1cmUgKHhzbDppZiBvciB4c2w6Y2hvb3NlKSB3aG9zZSBib2R5IGlzIHB1cmUgVGV4dC4KLSAqIDxwPgotICogQSBTaW1wbGVSZXN1bHRUcmVlSW1wbCBoYXMgb25seSB0d28gbm9kZXMsIGkuZS4gdGhlIFJPT1Qgbm9kZSBhbmQgaXRzIFRleHQgY2hpbGQuIEFsbCBET00KLSAqIGludGVyZmFjZXMgYXJlIG92ZXJyaWRkZW4gd2l0aCB0aGlzIGluIG1pbmQuIEZvciBleGFtcGxlLCB0aGUgZ2V0U3RyaW5nVmFsdWUoKSBpbnRlcmZhY2UKLSAqIHJldHVybnMgdGhlIHZhbHVlIG9mIHRoZSBUZXh0IG5vZGUuIFRoaXMgY2xhc3MgcmVjZWl2ZXMgdGhlIGNoYXJhY3RlciBkYXRhIGZyb20gdGhlCi0gKiBjaGFyYWN0ZXJzKCkgaW50ZXJmYWNlLgotICogPHA+Ci0gKiBUaGlzIGNsYXNzIGltcGxlbWVudHMgRE9NIGFuZCBTZXJpYWxpemF0aW9uSGFuZGxlci4gSXQgYWxzbyBpbXBsZW1lbnRzIHRoZSBEVE0gaW50ZXJmYWNlCi0gKiBmb3Igc3VwcG9ydCBpbiBNdWx0aURPTS4gVGhlIG5lc3RlZCBpdGVyYXRvcnMgKFNpbXBsZUl0ZXJhdG9yIGFuZCBTaW5nbGV0b25JdGVyYXRvcikgYXJlCi0gKiB1c2VkIHRvIHN1cHBvcnQgdGhlIG5vZGVzZXQoKSBleHRlbnNpb24gZnVuY3Rpb24uCi0gKi8KLXB1YmxpYyBjbGFzcyBTaW1wbGVSZXN1bHRUcmVlSW1wbCBleHRlbmRzIEVtcHR5U2VyaWFsaXplciBpbXBsZW1lbnRzIERPTSwgRFRNCi17Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgU2ltcGxlSXRlcmF0b3IgaXMgZGVzaWduZWQgdG8gc3VwcG9ydCB0aGUgbm9kZXNldCgpIGV4dGVuc2lvbiBmdW5jdGlvbi4gSXQgaGFzCi0gICAgICogYSB0cmF2ZXJzYWwgZGlyZWN0aW9uIHBhcmFtZXRlci4gVGhlIERPV04gZGlyZWN0aW9uIGlzIHVzZWQgZm9yIGNoaWxkIGFuZCBkZXNjZW5kYW50Ci0gICAgICogYXhlcywgd2hpbGUgdGhlIFVQIGRpcmVjdGlvbiBpcyB1c2VkIGZvciBwYXJlbnQgYW5kIGFuY2VzdG9yIGF4ZXMuCi0gICAgICoKLSAgICAgKiBUaGlzIGl0ZXJhdG9yIG9ubHkgaGFuZGxlcyB0d28gbm9kZXMgKFJURl9ST09UIGFuZCBSVEZfVEVYVCkuIElmIHRoZSB0eXBlIGlzIHNldCwKLSAgICAgKiBpdCB3aWxsIGFsc28gbWF0Y2ggdGhlIG5vZGUgdHlwZSB3aXRoIHRoZSBnaXZlbiB0eXBlLgotICAgICAqLwotICAgIHB1YmxpYyBmaW5hbCBjbGFzcyBTaW1wbGVJdGVyYXRvciBleHRlbmRzIERUTUF4aXNJdGVyYXRvckJhc2UKLSAgICB7Ci0gICAgICAgIHN0YXRpYyBmaW5hbCBpbnQgRElSRUNUSU9OX1VQID0gMDsKLSAgICAgICAgc3RhdGljIGZpbmFsIGludCBESVJFQ1RJT05fRE9XTiA9IDE7Ci0gICAgICAgIHN0YXRpYyBmaW5hbCBpbnQgTk9fVFlQRSA9IC0xOwotCi0gICAgICAgIC8vIFRoZSBkaXJlY3Rpb24gb2YgdHJhdmVyc2FsIChkZWZhdWx0IHRvIERPV04pLgotICAgICAgICAvLyBET1dOIGlzIGZvciBjaGlsZCBhbmQgZGVzY2VuZGFudC4gVVAgaXMgZm9yIHBhcmVudCBhbmQgYW5jZXN0b3IuCi0gICAgICAgIGludCBfZGlyZWN0aW9uID0gRElSRUNUSU9OX0RPV047Ci0KLSAgICAgICAgaW50IF90eXBlID0gTk9fVFlQRTsKLSAgICAgICAgaW50IF9jdXJyZW50Tm9kZTsKLQotICAgICAgICBwdWJsaWMgU2ltcGxlSXRlcmF0b3IoKQotICAgICAgICB7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgU2ltcGxlSXRlcmF0b3IoaW50IGRpcmVjdGlvbikKLSAgICAgICAgewotICAgICAgICAgICAgX2RpcmVjdGlvbiA9IGRpcmVjdGlvbjsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyBTaW1wbGVJdGVyYXRvcihpbnQgZGlyZWN0aW9uLCBpbnQgdHlwZSkKLSAgICAgICAgewotICAgICAgICAgICAgIF9kaXJlY3Rpb24gPSBkaXJlY3Rpb247Ci0gICAgICAgICAgICAgX3R5cGUgPSB0eXBlOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIGludCBuZXh0KCkKLSAgICAgICAgewotICAgICAgICAgICAgLy8gSW5jcmVhc2UgdGhlIG5vZGUgSUQgZm9yIGRvd24gdHJhdmVyc2FsLiBBbHNvIG1hdGNoIHRoZSBub2RlIHR5cGUKLSAgICAgICAgICAgIC8vIGlmIHRoZSB0eXBlIGlzIGdpdmVuLgotICAgICAgICAgICAgaWYgKF9kaXJlY3Rpb24gPT0gRElSRUNUSU9OX0RPV04pIHsKLSAgICAgICAgICAgICAgICB3aGlsZSAoX2N1cnJlbnROb2RlIDwgTlVNQkVSX09GX05PREVTKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChfdHlwZSAhPSBOT19UWVBFKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoKF9jdXJyZW50Tm9kZSA9PSBSVEZfUk9PVCAmJiBfdHlwZSA9PSBEVE0uUk9PVF9OT0RFKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IChfY3VycmVudE5vZGUgPT0gUlRGX1RFWFQgJiYgX3R5cGUgPT0gRFRNLlRFWFRfTk9ERSkpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJldHVybk5vZGUoZ2V0Tm9kZUhhbmRsZShfY3VycmVudE5vZGUrKykpOwotICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9jdXJyZW50Tm9kZSsrOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXR1cm5Ob2RlKGdldE5vZGVIYW5kbGUoX2N1cnJlbnROb2RlKyspKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICByZXR1cm4gRU5EOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gRGVjcmVhc2UgdGhlIG5vZGUgSUQgZm9yIHVwIHRyYXZlcnNhbC4KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIHdoaWxlIChfY3VycmVudE5vZGUgPj0gMCkgewotICAgICAgICAgICAgICAgICAgICBpZiAoX3R5cGUgIT0gTk9fVFlQRSkgewotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChfY3VycmVudE5vZGUgPT0gUlRGX1JPT1QgJiYgX3R5cGUgPT0gRFRNLlJPT1RfTk9ERSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCAoX2N1cnJlbnROb2RlID09IFJURl9URVhUICYmIF90eXBlID09IERUTS5URVhUX05PREUpKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXR1cm5Ob2RlKGdldE5vZGVIYW5kbGUoX2N1cnJlbnROb2RlLS0pKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBfY3VycmVudE5vZGUtLTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmV0dXJuTm9kZShnZXROb2RlSGFuZGxlKF9jdXJyZW50Tm9kZS0tKSk7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgcmV0dXJuIEVORDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3Igc2V0U3RhcnROb2RlKGludCBub2RlSGFuZGxlKQotICAgICAgICB7Ci0gICAgICAgICAgICBpbnQgbm9kZUlEID0gZ2V0Tm9kZUlkZW50KG5vZGVIYW5kbGUpOwotICAgICAgICAgICAgX3N0YXJ0Tm9kZSA9IG5vZGVJRDsKLQotICAgICAgICAgICAgLy8gSW5jcmVhc2UgdGhlIG5vZGUgSUQgYnkgMSBpZiBzZWxmIGlzIG5vdCBpbmNsdWRlZC4KLSAgICAgICAgICAgIGlmICghX2luY2x1ZGVTZWxmICYmIG5vZGVJRCAhPSBEVE0uTlVMTCkgewotICAgICAgICAgICAgICAgIGlmIChfZGlyZWN0aW9uID09IERJUkVDVElPTl9ET1dOKQotICAgICAgICAgICAgICAgICAgICBub2RlSUQrKzsKLSAgICAgICAgICAgICAgICBlbHNlIGlmIChfZGlyZWN0aW9uID09IERJUkVDVElPTl9VUCkKLSAgICAgICAgICAgICAgICAgICAgbm9kZUlELS07Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIF9jdXJyZW50Tm9kZSA9IG5vZGVJRDsKLSAgICAgICAgICAgIHJldHVybiB0aGlzOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIHZvaWQgc2V0TWFyaygpCi0gICAgICAgIHsKLSAgICAgICAgICAgIF9tYXJrZWROb2RlID0gX2N1cnJlbnROb2RlOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIHZvaWQgZ290b01hcmsoKQotICAgICAgICB7Ci0gICAgICAgICAgICBfY3VycmVudE5vZGUgPSBfbWFya2VkTm9kZTsKLSAgICAgICAgfQotCi0gICAgfSAvLyBFTkQgb2YgU2ltcGxlSXRlcmF0b3IKLQotICAgIC8qKgotICAgICAqIFRoZSBTaW5nbGV0b25JdGVyYXRvciBpcyB1c2VkIGZvciB0aGUgc2VsZiBheGlzLgotICAgICAqLwotICAgIHB1YmxpYyBmaW5hbCBjbGFzcyBTaW5nbGV0b25JdGVyYXRvciBleHRlbmRzIERUTUF4aXNJdGVyYXRvckJhc2UKLSAgICB7Ci0gICAgICAgIHN0YXRpYyBmaW5hbCBpbnQgTk9fVFlQRSA9IC0xOwotICAgICAgICBpbnQgX3R5cGUgPSBOT19UWVBFOwotICAgICAgICBpbnQgX2N1cnJlbnROb2RlOwotCi0gICAgICAgIHB1YmxpYyBTaW5nbGV0b25JdGVyYXRvcigpCi0gICAgICAgIHsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyBTaW5nbGV0b25JdGVyYXRvcihpbnQgdHlwZSkKLSAgICAgICAgewotICAgICAgICAgICAgX3R5cGUgPSB0eXBlOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIHZvaWQgc2V0TWFyaygpCi0gICAgICAgIHsKLSAgICAgICAgICAgIF9tYXJrZWROb2RlID0gX2N1cnJlbnROb2RlOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIHZvaWQgZ290b01hcmsoKQotICAgICAgICB7Ci0gICAgICAgICAgICBfY3VycmVudE5vZGUgPSBfbWFya2VkTm9kZTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3Igc2V0U3RhcnROb2RlKGludCBub2RlSGFuZGxlKQotICAgICAgICB7Ci0gICAgICAgICAgICBfY3VycmVudE5vZGUgPSBfc3RhcnROb2RlID0gZ2V0Tm9kZUlkZW50KG5vZGVIYW5kbGUpOwotICAgICAgICAgICAgcmV0dXJuIHRoaXM7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgaW50IG5leHQoKQotICAgICAgICB7Ci0gICAgICAgICAgICBpZiAoX2N1cnJlbnROb2RlID09IEVORCkKLSAgICAgICAgICAgICAgICByZXR1cm4gRU5EOwotCi0gICAgICAgICAgICBfY3VycmVudE5vZGUgPSBFTkQ7Ci0KLSAgICAgICAgICAgIGlmIChfdHlwZSAhPSBOT19UWVBFKSB7Ci0gICAgICAgICAgICAgICAgaWYgKChfY3VycmVudE5vZGUgPT0gUlRGX1JPT1QgJiYgX3R5cGUgPT0gRFRNLlJPT1RfTk9ERSkKLSAgICAgICAgICAgICAgICAgICAgfHwgKF9jdXJyZW50Tm9kZSA9PSBSVEZfVEVYVCAmJiBfdHlwZSA9PSBEVE0uVEVYVF9OT0RFKSkKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGdldE5vZGVIYW5kbGUoX2N1cnJlbnROb2RlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICByZXR1cm4gZ2V0Tm9kZUhhbmRsZShfY3VycmVudE5vZGUpOwotCi0gICAgICAgICAgICByZXR1cm4gRU5EOwotICAgICAgICB9Ci0KLSAgICB9ICAvLyBFTkQgb2YgU2luZ2xldG9uSXRlcmF0b3IKLQotICAgIC8vIGVtcHR5IGl0ZXJhdG9yIHRvIGJlIHJldHVybmVkIHdoZW4gdGhlcmUgYXJlIG5vIGNoaWxkcmVuCi0gICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgRFRNQXhpc0l0ZXJhdG9yIEVNUFRZX0lURVJBVE9SID0KLSAgICAgICAgbmV3IERUTUF4aXNJdGVyYXRvckJhc2UoKSB7Ci0gICAgICAgICAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIHJlc2V0KCkgeyByZXR1cm4gdGhpczsgfQotICAgICAgICAgICAgcHVibGljIERUTUF4aXNJdGVyYXRvciBzZXRTdGFydE5vZGUoaW50IG5vZGUpIHsgcmV0dXJuIHRoaXM7IH0KLSAgICAgICAgICAgIHB1YmxpYyBpbnQgbmV4dCgpIHsgcmV0dXJuIERUTS5OVUxMOyB9Ci0gICAgICAgICAgICBwdWJsaWMgdm9pZCBzZXRNYXJrKCkge30KLSAgICAgICAgICAgIHB1YmxpYyB2b2lkIGdvdG9NYXJrKCkge30KLSAgICAgICAgICAgIHB1YmxpYyBpbnQgZ2V0TGFzdCgpIHsgcmV0dXJuIDA7IH0KLSAgICAgICAgICAgIHB1YmxpYyBpbnQgZ2V0UG9zaXRpb24oKSB7IHJldHVybiAwOyB9Ci0gICAgICAgICAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIGNsb25lSXRlcmF0b3IoKSB7IHJldHVybiB0aGlzOyB9Ci0gICAgICAgICAgICBwdWJsaWMgdm9pZCBzZXRSZXN0YXJ0YWJsZShib29sZWFuIGlzUmVzdGFydGFibGUpIHsgfQotICAgICAgICB9OwotCi0KLSAgICAvLyBUaGUgcm9vdCBub2RlIGlkIG9mIHRoZSBzaW1wbGUgUlRGCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUlRGX1JPT1QgPSAwOwotCi0gICAgLy8gVGhlIFRleHQgbm9kZSBpZCBvZiB0aGUgc2ltcGxlIFJURiAoc2ltcGxlIFJURiBoYXMgb25seSBvbmUgVGV4dCBub2RlKS4KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSVEZfVEVYVCA9IDE7Ci0KLSAgICAvLyBUaGUgbnVtYmVyIG9mIG5vZGVzLgotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE5VTUJFUl9PRl9OT0RFUyA9IDI7Ci0KLSAgICAvLyBEb2N1bWVudCBVUkkgaW5kZXgsIHdoaWNoIGluY3JlYXNlcyBieSAxIGF0IGVhY2ggZ2V0RG9jdW1lbnRVUkkoKSBjYWxsLgotICAgIHByaXZhdGUgc3RhdGljIGludCBfZG9jdW1lbnRVUklJbmRleCA9IDA7Ci0KLSAgICAvLyBDb25zdGFudCBmb3IgZW1wdHkgU3RyaW5nCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEVNUFRZX1NUUiA9ICIiOwotCi0gICAgLy8gVGhlIFN0cmluZyB2YWx1ZSBvZiB0aGUgVGV4dCBub2RlLgotICAgIC8vIFRoaXMgaXMgc2V0IGF0IHRoZSBlbmREb2N1bWVudCgpIGNhbGwuCi0gICAgcHJpdmF0ZSBTdHJpbmcgX3RleHQ7Ci0KLSAgICAvLyBUaGUgYXJyYXkgb2YgVGV4dCBpdGVtcywgd2hpY2ggaXMgYnVpbHQgYnkgdGhlIGNoYXJhY3RlcnMoKSBjYWxsLgotICAgIC8vIFRoZSBjaGFyYWN0ZXJzKCkgaW50ZXJmYWNlIGNhbiBiZSBjYWxsZWQgbXVsdGlwbGUgdGltZXMuIEVhY2ggY2hhcmFjdGVyIGl0ZW0KLSAgICAvLyBjYW4gaGF2ZSBkaWZmZXJlbnQgZXNjYXBlIHNldHRpbmdzLgotICAgIHByb3RlY3RlZCBTdHJpbmdbXSBfdGV4dEFycmF5OwotCi0gICAgLy8gVGhlIERUTU1hbmFnZXIKLSAgICBwcm90ZWN0ZWQgWFNMVENEVE1NYW5hZ2VyIF9kdG1NYW5hZ2VyOwotCi0gICAgLy8gTnVtYmVyIG9mIGNoYXJhY3RlciBpdGVtcwotICAgIHByb3RlY3RlZCBpbnQgX3NpemUgPSAwOwotCi0gICAgLy8gVGhlIGRvY3VtZW50IElECi0gICAgcHJpdmF0ZSBpbnQgX2RvY3VtZW50SUQ7Ci0KLSAgICAvLyBBIEJpdEFycmF5LCBlYWNoIGJpdCBob2xkaW5nIHRoZSBlc2NhcGUgc2V0dGluZyBmb3IgYSBjaGFyYWN0ZXIgaXRlbS4KLSAgICBwcml2YXRlIEJpdEFycmF5IF9kb250RXNjYXBlID0gbnVsbDsKLQotICAgIC8vIFRoZSBjdXJyZW50IGVzY2FwZSBzZXR0aW5nCi0gICAgcHJpdmF0ZSBib29sZWFuIF9lc2NhcGluZyA9IHRydWU7Ci0KLSAgICAvLyBDcmVhdGUgYSBTaW1wbGVSZXN1bHRUcmVlSW1wbCBmcm9tIGEgRFRNTWFuYWdlciBhbmQgYSBkb2N1bWVudCBJRC4KLSAgICBwdWJsaWMgU2ltcGxlUmVzdWx0VHJlZUltcGwoWFNMVENEVE1NYW5hZ2VyIGR0bU1hbmFnZXIsIGludCBkb2N1bWVudElEKQotICAgIHsKLSAgICAgICAgX2R0bU1hbmFnZXIgPSBkdG1NYW5hZ2VyOwotICAgICAgICBfZG9jdW1lbnRJRCA9IGRvY3VtZW50SUQ7Ci0gICAgICAgIF90ZXh0QXJyYXkgPSBuZXcgU3RyaW5nWzRdOwotICAgIH0KLQotICAgIHB1YmxpYyBEVE1NYW5hZ2VyRGVmYXVsdCBnZXREVE1NYW5hZ2VyKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBfZHRtTWFuYWdlcjsKLSAgICB9Ci0KLSAgICAvLyBSZXR1cm4gdGhlIGRvY3VtZW50IElECi0gICAgcHVibGljIGludCBnZXREb2N1bWVudCgpCi0gICAgewotICAgICAgICByZXR1cm4gX2RvY3VtZW50SUQ7Ci0gICAgfQotCi0gICAgLy8gUmV0dXJuIHRoZSBTdHJpbmcgdmFsdWUgb2YgdGhlIFJURgotICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3RyaW5nVmFsdWUoKQotICAgIHsKLSAgICAgICAgcmV0dXJuIF90ZXh0OwotICAgIH0KLQotICAgIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3IgZ2V0SXRlcmF0b3IoKQotICAgIHsKLSAgICAgICAgcmV0dXJuIG5ldyBTaW5nbGV0b25JdGVyYXRvcihnZXREb2N1bWVudCgpKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIGdldENoaWxkcmVuKGZpbmFsIGludCBub2RlKQotICAgIHsKLSAgICAgICAgcmV0dXJuIG5ldyBTaW1wbGVJdGVyYXRvcigpLnNldFN0YXJ0Tm9kZShub2RlKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIGdldFR5cGVkQ2hpbGRyZW4oZmluYWwgaW50IHR5cGUpCi0gICAgewotICAgICAgICByZXR1cm4gbmV3IFNpbXBsZUl0ZXJhdG9yKFNpbXBsZUl0ZXJhdG9yLkRJUkVDVElPTl9ET1dOLCB0eXBlKTsKLSAgICB9Ci0KLSAgICAvLyBSZXR1cm4gdGhlIGF4aXMgaXRlcmF0b3IgZm9yIGEgZ2l2ZW4gYXhpcy4KLSAgICAvLyBUaGUgU2ltcGxlSXRlcmF0b3IgaXMgdXNlZCBmb3IgdGhlIGNoaWxkLCBkZXNjZW5kYW50LCBwYXJlbnQgYW5kIGFuY2VzdG9yIGF4ZXMuCi0gICAgcHVibGljIERUTUF4aXNJdGVyYXRvciBnZXRBeGlzSXRlcmF0b3IoZmluYWwgaW50IGF4aXMpCi0gICAgewotICAgICAgICBzd2l0Y2ggKGF4aXMpCi0gICAgICAgIHsKLSAgICAgICAgICAgIGNhc2UgQXhpcy5DSElMRDoKLSAgICAgICAgICAgIGNhc2UgQXhpcy5ERVNDRU5EQU5UOgotICAgICAgICAgICAgICAgIHJldHVybiBuZXcgU2ltcGxlSXRlcmF0b3IoU2ltcGxlSXRlcmF0b3IuRElSRUNUSU9OX0RPV04pOwotICAgICAgICAgICAgY2FzZSBBeGlzLlBBUkVOVDoKLSAgICAgICAgICAgIGNhc2UgQXhpcy5BTkNFU1RPUjoKLSAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFNpbXBsZUl0ZXJhdG9yKFNpbXBsZUl0ZXJhdG9yLkRJUkVDVElPTl9VUCk7Ci0gICAgICAgICAgICBjYXNlIEF4aXMuQU5DRVNUT1JPUlNFTEY6Ci0gICAgICAgICAgICAgICAgcmV0dXJuIChuZXcgU2ltcGxlSXRlcmF0b3IoU2ltcGxlSXRlcmF0b3IuRElSRUNUSU9OX1VQKSkuaW5jbHVkZVNlbGYoKTsKLSAgICAgICAgICAgIGNhc2UgQXhpcy5ERVNDRU5EQU5UT1JTRUxGOgotICAgICAgICAgICAgICAgIHJldHVybiAobmV3IFNpbXBsZUl0ZXJhdG9yKFNpbXBsZUl0ZXJhdG9yLkRJUkVDVElPTl9ET1dOKSkuaW5jbHVkZVNlbGYoKTsKLSAgICAgICAgICAgIGNhc2UgQXhpcy5TRUxGOgotICAgICAgICAgICAgICAgIHJldHVybiBuZXcgU2luZ2xldG9uSXRlcmF0b3IoKTsKLSAgICAgICAgICAgIGRlZmF1bHQ6Ci0gICAgICAgICAgICAgICAgcmV0dXJuIEVNUFRZX0lURVJBVE9SOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIERUTUF4aXNJdGVyYXRvciBnZXRUeXBlZEF4aXNJdGVyYXRvcihmaW5hbCBpbnQgYXhpcywgZmluYWwgaW50IHR5cGUpCi0gICAgewotICAgICAgICBzd2l0Y2ggKGF4aXMpCi0gICAgICAgIHsKLSAgICAgICAgICAgIGNhc2UgQXhpcy5DSElMRDoKLSAgICAgICAgICAgIGNhc2UgQXhpcy5ERVNDRU5EQU5UOgotICAgICAgICAgICAgICAgIHJldHVybiBuZXcgU2ltcGxlSXRlcmF0b3IoU2ltcGxlSXRlcmF0b3IuRElSRUNUSU9OX0RPV04sIHR5cGUpOwotICAgICAgICAgICAgY2FzZSBBeGlzLlBBUkVOVDoKLSAgICAgICAgICAgIGNhc2UgQXhpcy5BTkNFU1RPUjoKLSAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFNpbXBsZUl0ZXJhdG9yKFNpbXBsZUl0ZXJhdG9yLkRJUkVDVElPTl9VUCwgdHlwZSk7Ci0gICAgICAgICAgICBjYXNlIEF4aXMuQU5DRVNUT1JPUlNFTEY6Ci0gICAgICAgICAgICAgICAgcmV0dXJuIChuZXcgU2ltcGxlSXRlcmF0b3IoU2ltcGxlSXRlcmF0b3IuRElSRUNUSU9OX1VQLCB0eXBlKSkuaW5jbHVkZVNlbGYoKTsKLSAgICAgICAgICAgIGNhc2UgQXhpcy5ERVNDRU5EQU5UT1JTRUxGOgotICAgICAgICAgICAgICAgIHJldHVybiAobmV3IFNpbXBsZUl0ZXJhdG9yKFNpbXBsZUl0ZXJhdG9yLkRJUkVDVElPTl9ET1dOLCB0eXBlKSkuaW5jbHVkZVNlbGYoKTsKLSAgICAgICAgICAgIGNhc2UgQXhpcy5TRUxGOgotICAgICAgICAgICAgICAgIHJldHVybiBuZXcgU2luZ2xldG9uSXRlcmF0b3IodHlwZSk7Ci0gICAgICAgICAgICBkZWZhdWx0OgotICAgICAgICAgICAgICAgIHJldHVybiBFTVBUWV9JVEVSQVRPUjsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8vICVSRVZJU0lUJSBDYW4gdGhpcyBvbmUgZXZlciBnZXQgdXNlZD8KLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIGdldE50aERlc2NlbmRhbnQoaW50IG5vZGUsIGludCBuLCBib29sZWFuIGluY2x1ZGVzZWxmKQotICAgIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgcHVibGljIERUTUF4aXNJdGVyYXRvciBnZXROYW1lc3BhY2VBeGlzSXRlcmF0b3IoZmluYWwgaW50IGF4aXMsIGZpbmFsIGludCBucykKLSAgICB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8vICVSRVZJU0lUJSBDYW4gdGhpcyBvbmUgZXZlciBnZXQgdXNlZD8KLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIGdldE5vZGVWYWx1ZUl0ZXJhdG9yKERUTUF4aXNJdGVyYXRvciBpdGVyLCBpbnQgcmV0dXJuVHlwZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyB2YWx1ZSwgYm9vbGVhbiBvcCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3Igb3JkZXJOb2RlcyhEVE1BeGlzSXRlcmF0b3Igc291cmNlLCBpbnQgbm9kZSkKLSAgICB7Ci0gICAgICAgIHJldHVybiBzb3VyY2U7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXROb2RlTmFtZShmaW5hbCBpbnQgbm9kZSkKLSAgICB7Ci0gICAgICAgIGlmIChnZXROb2RlSWRlbnQobm9kZSkgPT0gUlRGX1RFWFQpCi0gICAgICAgICAgICByZXR1cm4gIiN0ZXh0IjsKLSAgICAgICAgZWxzZQotICAgICAgICAgICAgcmV0dXJuIEVNUFRZX1NUUjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldE5vZGVOYW1lWChmaW5hbCBpbnQgbm9kZSkKLSAgICB7Ci0gICAgICAgIHJldHVybiBFTVBUWV9TVFI7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXROYW1lc3BhY2VOYW1lKGZpbmFsIGludCBub2RlKQotICAgIHsKLSAgICAgICAgcmV0dXJuIEVNUFRZX1NUUjsKLSAgICB9Ci0KLSAgICAvLyBSZXR1cm4gdGhlIGV4cGFuZGVkIHR5cGUgaWQgb2YgYSBnaXZlbiBub2RlCi0gICAgcHVibGljIGludCBnZXRFeHBhbmRlZFR5cGVJRChmaW5hbCBpbnQgbm9kZUhhbmRsZSkKLSAgICB7Ci0gICAgICAgIGludCBub2RlSUQgPSBnZXROb2RlSWRlbnQobm9kZUhhbmRsZSk7Ci0gICAgICAgIGlmIChub2RlSUQgPT0gUlRGX1RFWFQpCi0gICAgICAgICAgICByZXR1cm4gRFRNLlRFWFRfTk9ERTsKLSAgICAgICAgZWxzZSBpZiAobm9kZUlEID09IFJURl9ST09UKQotICAgICAgICAgICAgcmV0dXJuIERUTS5ST09UX05PREU7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICAgIHJldHVybiBEVE0uTlVMTDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldE5hbWVzcGFjZVR5cGUoZmluYWwgaW50IG5vZGUpCi0gICAgewotICAgICAgICByZXR1cm4gMDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldFBhcmVudChmaW5hbCBpbnQgbm9kZUhhbmRsZSkKLSAgICB7Ci0gICAgICAgIGludCBub2RlSUQgPSBnZXROb2RlSWRlbnQobm9kZUhhbmRsZSk7Ci0gICAgICAgIHJldHVybiAobm9kZUlEID09IFJURl9URVhUKSA/IGdldE5vZGVIYW5kbGUoUlRGX1JPT1QpIDogRFRNLk5VTEw7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBnZXRBdHRyaWJ1dGVOb2RlKGZpbmFsIGludCBnVHlwZSwgZmluYWwgaW50IGVsZW1lbnQpCi0gICAgewotICAgICAgICByZXR1cm4gRFRNLk5VTEw7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRTdHJpbmdWYWx1ZVgoZmluYWwgaW50IG5vZGVIYW5kbGUpCi0gICAgewotICAgICAgICBpbnQgbm9kZUlEID0gZ2V0Tm9kZUlkZW50KG5vZGVIYW5kbGUpOwotICAgICAgICBpZiAobm9kZUlEID09IFJURl9ST09UIHx8IG5vZGVJRCA9PSBSVEZfVEVYVCkKLSAgICAgICAgICAgIHJldHVybiBfdGV4dDsKLSAgICAgICAgZWxzZQotICAgICAgICAgICAgcmV0dXJuIEVNUFRZX1NUUjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBjb3B5KGZpbmFsIGludCBub2RlLCBTZXJpYWxpemF0aW9uSGFuZGxlciBoYW5kbGVyKQotICAgICAgICB0aHJvd3MgVHJhbnNsZXRFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGNoYXJhY3RlcnMobm9kZSwgaGFuZGxlcik7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgY29weShEVE1BeGlzSXRlcmF0b3Igbm9kZXMsIFNlcmlhbGl6YXRpb25IYW5kbGVyIGhhbmRsZXIpCi0gICAgICAgIHRocm93cyBUcmFuc2xldEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaW50IG5vZGU7Ci0gICAgICAgIHdoaWxlICgobm9kZSA9IG5vZGVzLm5leHQoKSkgIT0gRFRNLk5VTEwpCi0gICAgICAgIHsKLSAgICAgICAgICAgIGNvcHkobm9kZSwgaGFuZGxlcik7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIHNoYWxsb3dDb3B5KGZpbmFsIGludCBub2RlLCBTZXJpYWxpemF0aW9uSGFuZGxlciBoYW5kbGVyKQotICAgICAgICB0aHJvd3MgVHJhbnNsZXRFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGNoYXJhY3RlcnMobm9kZSwgaGFuZGxlcik7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGxlc3NUaGFuKGZpbmFsIGludCBub2RlMSwgZmluYWwgaW50IG5vZGUyKQotICAgIHsKLSAgICAgICAgaWYgKG5vZGUxID09IERUTS5OVUxMKSB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAobm9kZTIgPT0gRFRNLk5VTEwpIHsKLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICAgIHJldHVybiAobm9kZTEgPCBub2RlMik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRGlzcGF0Y2ggdGhlIGNoYXJhY3RlciBjb250ZW50IG9mIGEgbm9kZSB0byBhbiBvdXRwdXQgaGFuZGxlci4KLSAgICAgKgotICAgICAqIFRoZSBlc2NhcGUgc2V0dGluZyBzaG91bGQgYmUgdGFrZW4gY2FyZSBvZiB3aGVuIG91dHB1dHRpbmcgdG8KLSAgICAgKiBhIGhhbmRsZXIuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY2hhcmFjdGVycyhmaW5hbCBpbnQgbm9kZSwgU2VyaWFsaXphdGlvbkhhbmRsZXIgaGFuZGxlcikKLSAgICAgICAgdGhyb3dzIFRyYW5zbGV0RXhjZXB0aW9uCi0gICAgewotICAgICAgICBpbnQgbm9kZUlEID0gZ2V0Tm9kZUlkZW50KG5vZGUpOwotICAgICAgICBpZiAobm9kZUlEID09IFJURl9ST09UIHx8IG5vZGVJRCA9PSBSVEZfVEVYVCkgewotICAgICAgICAgICAgYm9vbGVhbiBlc2NhcGVCaXQgPSBmYWxzZTsKLSAgICAgICAgICAgIGJvb2xlYW4gb2xkRXNjYXBlU2V0dGluZyA9IGZhbHNlOwotCi0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgX3NpemU7IGkrKykgewotCi0gICAgICAgICAgICAgICAgICAgIGlmIChfZG9udEVzY2FwZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBlc2NhcGVCaXQgPSBfZG9udEVzY2FwZS5nZXRCaXQoaSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXNjYXBlQml0KSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgb2xkRXNjYXBlU2V0dGluZyA9IGhhbmRsZXIuc2V0RXNjYXBpbmcoZmFsc2UpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgaGFuZGxlci5jaGFyYWN0ZXJzKF90ZXh0QXJyYXlbaV0pOwotCi0gICAgICAgICAgICAgICAgICAgIGlmIChlc2NhcGVCaXQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZXIuc2V0RXNjYXBpbmcob2xkRXNjYXBlU2V0dGluZyk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBUcmFuc2xldEV4Y2VwdGlvbihlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIC8vICVSRVZJU0lUJSBDYW4gdGhlIG1ha2VOb2RlKCkgYW5kIG1ha2VOb2RlTGlzdCgpIGludGVyZmFjZXMgZXZlciBnZXQgdXNlZD8KLSAgICBwdWJsaWMgTm9kZSBtYWtlTm9kZShpbnQgaW5kZXgpCi0gICAgewotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgTm9kZSBtYWtlTm9kZShEVE1BeGlzSXRlcmF0b3IgaXRlcikKLSAgICB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIHB1YmxpYyBOb2RlTGlzdCBtYWtlTm9kZUxpc3QoaW50IGluZGV4KQotICAgIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgcHVibGljIE5vZGVMaXN0IG1ha2VOb2RlTGlzdChEVE1BeGlzSXRlcmF0b3IgaXRlcikKLSAgICB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TGFuZ3VhZ2UoaW50IG5vZGUpCi0gICAgewotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldFNpemUoKQotICAgIHsKLSAgICAgICAgcmV0dXJuIDI7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXREb2N1bWVudFVSSShpbnQgbm9kZSkKLSAgICB7Ci0gICAgICAgIHJldHVybiAic2ltcGxlX3J0ZiIgKyBfZG9jdW1lbnRVUklJbmRleCsrOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldEZpbHRlcihTdHJpcEZpbHRlciBmaWx0ZXIpCi0gICAgewotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldHVwTWFwcGluZyhTdHJpbmdbXSBuYW1lcywgU3RyaW5nW10gdXJpcywgaW50W10gdHlwZXMsIFN0cmluZ1tdIG5hbWVzcGFjZXMpCi0gICAgewotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGlzRWxlbWVudChmaW5hbCBpbnQgbm9kZSkKLSAgICB7Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0F0dHJpYnV0ZShmaW5hbCBpbnQgbm9kZSkKLSAgICB7Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGxvb2t1cE5hbWVzcGFjZShpbnQgbm9kZSwgU3RyaW5nIHByZWZpeCkKLSAgICAgICAgdGhyb3dzIFRyYW5zbGV0RXhjZXB0aW9uCi0gICAgewotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIG5vZGUgaWRlbnRpdHkgZnJvbSBhIG5vZGUgaGFuZGxlLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0Tm9kZUlkZW50KGZpbmFsIGludCBub2RlaGFuZGxlKQotICAgIHsKLSAgICAgICAgcmV0dXJuIChub2RlaGFuZGxlICE9IERUTS5OVUxMKSA/IChub2RlaGFuZGxlIC0gX2RvY3VtZW50SUQpIDogRFRNLk5VTEw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSBub2RlIGhhbmRsZSBmcm9tIGEgbm9kZSBpZGVudGl0eS4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldE5vZGVIYW5kbGUoZmluYWwgaW50IG5vZGVJZCkKLSAgICB7Ci0gICAgICAgIHJldHVybiAobm9kZUlkICE9IERUTS5OVUxMKSA/IChub2RlSWQgKyBfZG9jdW1lbnRJRCkgOiBEVE0uTlVMTDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgRE9NIGdldFJlc3VsdFRyZWVGcmFnKGludCBpbml0aWFsU2l6ZSwgaW50IHJ0ZlR5cGUpCi0gICAgewotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgRE9NIGdldFJlc3VsdFRyZWVGcmFnKGludCBpbml0aWFsU2l6ZSwgaW50IHJ0ZlR5cGUsIGJvb2xlYW4gYWRkVG9NYW5hZ2VyKQotICAgIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgcHVibGljIFNlcmlhbGl6YXRpb25IYW5kbGVyIGdldE91dHB1dERvbUJ1aWxkZXIoKQotICAgIHsKLSAgICAgICAgcmV0dXJuIHRoaXM7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBnZXROU1R5cGUoaW50IG5vZGUpCi0gICAgewotICAgICAgICByZXR1cm4gMDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldFVucGFyc2VkRW50aXR5VVJJKFN0cmluZyBuYW1lKQotICAgIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgcHVibGljIE1hcDxTdHJpbmcsIEludGVnZXI+IGdldEVsZW1lbnRzV2l0aElEcygpCi0gICAgewotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICAvKiogSW1wbGVtZW50YXRpb24gb2YgdGhlIFNlcmlhbGl6YXRpb25IYW5kbGVyIGludGVyZmFjZXMgKiovCi0KLSAgICAvKioKLSAgICAgKiBXZSBvbmx5IG5lZWQgdG8gb3ZlcnJpZGUgdGhlIGVuZERvY3VtZW50LCBjaGFyYWN0ZXJzLCBhbmQKLSAgICAgKiBzZXRFc2NhcGluZyBpbnRlcmZhY2VzLiBBIHNpbXBsZSBSVEYgZG9lcyBub3QgaGF2ZSBlbGVtZW50Ci0gICAgICogbm9kZXMuIFdlIGRvIG5vdCBuZWVkIHRvIHRvdWNoIHN0YXJ0RWxlbWVudCBhbmQgZW5kRWxlbWVudC4KLSAgICAgKi8KLQotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RG9jdW1lbnQoKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotCi0gICAgfQotCi0gICAgcHVibGljIHZvaWQgZW5kRG9jdW1lbnQoKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICAvLyBTZXQgdGhlIFN0cmluZyB2YWx1ZSB3aGVuIHRoZSBkb2N1bWVudCBpcyBidWlsdC4KLSAgICAgICAgaWYgKF9zaXplID09IDEpCi0gICAgICAgICAgICBfdGV4dCA9IF90ZXh0QXJyYXlbMF07Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgU3RyaW5nQnVmZmVyIGJ1ZmZlciA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgX3NpemU7IGkrKykgewotICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoX3RleHRBcnJheVtpXSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBfdGV4dCA9IGJ1ZmZlci50b1N0cmluZygpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgY2hhcmFjdGVycyhTdHJpbmcgc3RyKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICAvLyBSZXNpemUgdGhlIHRleHQgYXJyYXkgaWYgbmVjZXNzYXJ5Ci0gICAgICAgIGlmIChfc2l6ZSA+PSBfdGV4dEFycmF5Lmxlbmd0aCkgewotICAgICAgICAgICAgU3RyaW5nW10gbmV3VGV4dEFycmF5ID0gbmV3IFN0cmluZ1tfdGV4dEFycmF5Lmxlbmd0aCAqIDJdOwotICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShfdGV4dEFycmF5LCAwLCBuZXdUZXh0QXJyYXksIDAsIF90ZXh0QXJyYXkubGVuZ3RoKTsKLSAgICAgICAgICAgIF90ZXh0QXJyYXkgPSBuZXdUZXh0QXJyYXk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBJZiB0aGUgZXNjYXBlIHNldHRpbmcgaXMgZmFsc2UsIHNldCB0aGUgY29ycmVzcG9uZGluZyBiaXQgaW4KLSAgICAgICAgLy8gdGhlIF9kb250RXNjYXBlIEJpdEFycmF5LgotICAgICAgICBpZiAoIV9lc2NhcGluZykgewotICAgICAgICAgICAgLy8gVGhlIF9kb250RXNjYXBlIGFycmF5IGlzIG9ubHkgY3JlYXRlZCB3aGVuIG5lZWRlZC4KLSAgICAgICAgICAgIGlmIChfZG9udEVzY2FwZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgX2RvbnRFc2NhcGUgPSBuZXcgQml0QXJyYXkoOCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIFJlc2l6ZSB0aGUgX2RvbnRFc2NhcGUgYXJyYXkgaWYgbmVjZXNzYXJ5Ci0gICAgICAgICAgICBpZiAoX3NpemUgPj0gX2RvbnRFc2NhcGUuc2l6ZSgpKQotICAgICAgICAgICAgICAgIF9kb250RXNjYXBlLnJlc2l6ZShfZG9udEVzY2FwZS5zaXplKCkgKiAyKTsKLQotICAgICAgICAgICAgX2RvbnRFc2NhcGUuc2V0Qml0KF9zaXplKTsKLSAgICAgICAgfQotCi0gICAgICAgIF90ZXh0QXJyYXlbX3NpemUrK10gPSBzdHI7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgY2hhcmFjdGVycyhjaGFyW10gY2gsIGludCBvZmZzZXQsIGludCBsZW5ndGgpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGlmIChfc2l6ZSA+PSBfdGV4dEFycmF5Lmxlbmd0aCkgewotICAgICAgICAgICAgU3RyaW5nW10gbmV3VGV4dEFycmF5ID0gbmV3IFN0cmluZ1tfdGV4dEFycmF5Lmxlbmd0aCAqIDJdOwotICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShfdGV4dEFycmF5LCAwLCBuZXdUZXh0QXJyYXksIDAsIF90ZXh0QXJyYXkubGVuZ3RoKTsKLSAgICAgICAgICAgIF90ZXh0QXJyYXkgPSBuZXdUZXh0QXJyYXk7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoIV9lc2NhcGluZykgewotICAgICAgICAgICAgaWYgKF9kb250RXNjYXBlID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBfZG9udEVzY2FwZSA9IG5ldyBCaXRBcnJheSg4KTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKF9zaXplID49IF9kb250RXNjYXBlLnNpemUoKSkKLSAgICAgICAgICAgICAgICBfZG9udEVzY2FwZS5yZXNpemUoX2RvbnRFc2NhcGUuc2l6ZSgpICogMik7Ci0KLSAgICAgICAgICAgIF9kb250RXNjYXBlLnNldEJpdChfc2l6ZSk7Ci0gICAgICAgIH0KLQotICAgICAgICBfdGV4dEFycmF5W19zaXplKytdID0gbmV3IFN0cmluZyhjaCwgb2Zmc2V0LCBsZW5ndGgpOwotCi0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gc2V0RXNjYXBpbmcoYm9vbGVhbiBlc2NhcGUpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGZpbmFsIGJvb2xlYW4gdGVtcCA9IF9lc2NhcGluZzsKLSAgICAgICAgX2VzY2FwaW5nID0gZXNjYXBlOwotICAgICAgICByZXR1cm4gdGVtcDsKLSAgICB9Ci0KLSAgICAvKiogSW1wbGVtZW50YXRpb24gb2YgdGhlIERUTSBpbnRlcmZhY2VzICoqLwotCi0gICAgLyoqCi0gICAgICogVGhlIERUTSBpbnRlcmZhY2VzIGFyZSBub3QgdXNlZCBpbiB0aGlzIGNsYXNzLiBJbXBsZW1lbnRpbmcgdGhlIERUTQotICAgICAqIGludGVyZmFjZSBpcyBhIHJlcXVpcmVtZW50IGZyb20gTXVsdGlET00uIElmIHdlIGhhdmUgYSBiZXR0ZXIgd2F5Ci0gICAgICogb2YgaGFuZGxpbmcgbXVsdGlwbGUgZG9jdW1lbnRzLCB3ZSBjYW4gZ2V0IHJpZCBvZiB0aGUgRFRNIGRlcGVuZGVuY3kuCi0gICAgICoKLSAgICAgKiBUaGUgZm9sbG93aW5nIGludGVyZmFjZXMgYXJlIGp1c3QgcGxhY2Vob2xkZXJzLiBUaGUgaW1wbGVtZW50YXRpb24KLSAgICAgKiBkb2VzIG5vdCBoYXZlIGFuIGltcGFjdCBiZWNhdXNlIHRoZXkgd2lsbCBub3QgYmUgdXNlZC4KLSAgICAgKi8KLQotICAgIHB1YmxpYyB2b2lkIHNldEZlYXR1cmUoU3RyaW5nIGZlYXR1cmVJZCwgYm9vbGVhbiBzdGF0ZSkKLSAgICB7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0UHJvcGVydHkoU3RyaW5nIHByb3BlcnR5LCBPYmplY3QgdmFsdWUpCi0gICAgewotICAgIH0KLQotICAgIHB1YmxpYyBEVE1BeGlzVHJhdmVyc2VyIGdldEF4aXNUcmF2ZXJzZXIoZmluYWwgaW50IGF4aXMpCi0gICAgewotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBoYXNDaGlsZE5vZGVzKGludCBub2RlSGFuZGxlKQotICAgIHsKLSAgICAgICAgcmV0dXJuIChnZXROb2RlSWRlbnQobm9kZUhhbmRsZSkgPT0gUlRGX1JPT1QpOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgZ2V0Rmlyc3RDaGlsZChpbnQgbm9kZUhhbmRsZSkKLSAgICB7Ci0gICAgICAgIGludCBub2RlSUQgPSBnZXROb2RlSWRlbnQobm9kZUhhbmRsZSk7Ci0gICAgICAgIGlmIChub2RlSUQgPT0gUlRGX1JPT1QpCi0gICAgICAgICAgICByZXR1cm4gZ2V0Tm9kZUhhbmRsZShSVEZfVEVYVCk7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICAgIHJldHVybiBEVE0uTlVMTDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldExhc3RDaGlsZChpbnQgbm9kZUhhbmRsZSkKLSAgICB7Ci0gICAgICAgIHJldHVybiBnZXRGaXJzdENoaWxkKG5vZGVIYW5kbGUpOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgZ2V0QXR0cmlidXRlTm9kZShpbnQgZWxlbWVudEhhbmRsZSwgU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIG5hbWUpCi0gICAgewotICAgICAgICByZXR1cm4gRFRNLk5VTEw7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBnZXRGaXJzdEF0dHJpYnV0ZShpbnQgbm9kZUhhbmRsZSkKLSAgICB7Ci0gICAgICAgIHJldHVybiBEVE0uTlVMTDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldEZpcnN0TmFtZXNwYWNlTm9kZShpbnQgbm9kZUhhbmRsZSwgYm9vbGVhbiBpblNjb3BlKQotICAgIHsKLSAgICAgICAgcmV0dXJuIERUTS5OVUxMOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgZ2V0TmV4dFNpYmxpbmcoaW50IG5vZGVIYW5kbGUpCi0gICAgewotICAgICAgICByZXR1cm4gRFRNLk5VTEw7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBnZXRQcmV2aW91c1NpYmxpbmcoaW50IG5vZGVIYW5kbGUpCi0gICAgewotICAgICAgICByZXR1cm4gRFRNLk5VTEw7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBnZXROZXh0QXR0cmlidXRlKGludCBub2RlSGFuZGxlKQotICAgIHsKLSAgICAgICAgcmV0dXJuIERUTS5OVUxMOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgZ2V0TmV4dE5hbWVzcGFjZU5vZGUoaW50IGJhc2VIYW5kbGUsIGludCBuYW1lc3BhY2VIYW5kbGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBpblNjb3BlKQotICAgIHsKLSAgICAgICAgcmV0dXJuIERUTS5OVUxMOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgZ2V0T3duZXJEb2N1bWVudChpbnQgbm9kZUhhbmRsZSkKLSAgICB7Ci0gICAgICAgIHJldHVybiBnZXREb2N1bWVudCgpOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgZ2V0RG9jdW1lbnRSb290KGludCBub2RlSGFuZGxlKQotICAgIHsKLSAgICAgICAgcmV0dXJuIGdldERvY3VtZW50KCk7Ci0gICAgfQotCi0gICAgcHVibGljIFhNTFN0cmluZyBnZXRTdHJpbmdWYWx1ZShpbnQgbm9kZUhhbmRsZSkKLSAgICB7Ci0gICAgICAgIHJldHVybiBuZXcgWE1MU3RyaW5nRGVmYXVsdChnZXRTdHJpbmdWYWx1ZVgobm9kZUhhbmRsZSkpOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgZ2V0U3RyaW5nVmFsdWVDaHVua0NvdW50KGludCBub2RlSGFuZGxlKQotICAgIHsKLSAgICAgICAgcmV0dXJuIDA7Ci0gICAgfQotCi0gICAgcHVibGljIGNoYXJbXSBnZXRTdHJpbmdWYWx1ZUNodW5rKGludCBub2RlSGFuZGxlLCBpbnQgY2h1bmtJbmRleCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludFtdIHN0YXJ0QW5kTGVuKQotICAgIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBnZXRFeHBhbmRlZFR5cGVJRChTdHJpbmcgbmFtZXNwYWNlLCBTdHJpbmcgbG9jYWxOYW1lLCBpbnQgdHlwZSkKLSAgICB7Ci0gICAgICAgIHJldHVybiBEVE0uTlVMTDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldExvY2FsTmFtZUZyb21FeHBhbmRlZE5hbWVJRChpbnQgRXhwYW5kZWROYW1lSUQpCi0gICAgewotICAgICAgICByZXR1cm4gRU1QVFlfU1RSOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZXNwYWNlRnJvbUV4cGFuZGVkTmFtZUlEKGludCBFeHBhbmRlZE5hbWVJRCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBFTVBUWV9TVFI7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRMb2NhbE5hbWUoaW50IG5vZGVIYW5kbGUpCi0gICAgewotICAgICAgICByZXR1cm4gRU1QVFlfU1RSOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0UHJlZml4KGludCBub2RlSGFuZGxlKQotICAgIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXROYW1lc3BhY2VVUkkoaW50IG5vZGVIYW5kbGUpCi0gICAgewotICAgICAgICByZXR1cm4gRU1QVFlfU1RSOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Tm9kZVZhbHVlKGludCBub2RlSGFuZGxlKQotICAgIHsKLSAgICAgICAgcmV0dXJuIChnZXROb2RlSWRlbnQobm9kZUhhbmRsZSkgPT0gUlRGX1RFWFQpID8gX3RleHQgOiBudWxsOwotICAgIH0KLQotICAgIHB1YmxpYyBzaG9ydCBnZXROb2RlVHlwZShpbnQgbm9kZUhhbmRsZSkKLSAgICB7Ci0gICAgICAgIGludCBub2RlSUQgPSBnZXROb2RlSWRlbnQobm9kZUhhbmRsZSk7Ci0gICAgICAgIGlmIChub2RlSUQgPT0gUlRGX1RFWFQpCi0gICAgICAgICAgICByZXR1cm4gRFRNLlRFWFRfTk9ERTsKLSAgICAgICAgZWxzZSBpZiAobm9kZUlEID09IFJURl9ST09UKQotICAgICAgICAgICAgcmV0dXJuIERUTS5ST09UX05PREU7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICAgIHJldHVybiBEVE0uTlVMTDsKLQotICAgIH0KLQotICAgIHB1YmxpYyBzaG9ydCBnZXRMZXZlbChpbnQgbm9kZUhhbmRsZSkKLSAgICB7Ci0gICAgICAgIGludCBub2RlSUQgPSBnZXROb2RlSWRlbnQobm9kZUhhbmRsZSk7Ci0gICAgICAgIGlmIChub2RlSUQgPT0gUlRGX1RFWFQpCi0gICAgICAgICAgICByZXR1cm4gMjsKLSAgICAgICAgZWxzZSBpZiAobm9kZUlEID09IFJURl9ST09UKQotICAgICAgICAgICAgcmV0dXJuIDE7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICAgIHJldHVybiBEVE0uTlVMTDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBpc1N1cHBvcnRlZChTdHJpbmcgZmVhdHVyZSwgU3RyaW5nIHZlcnNpb24pCi0gICAgewotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXREb2N1bWVudEJhc2VVUkkoKQotICAgIHsKLSAgICAgICAgcmV0dXJuIEVNUFRZX1NUUjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXREb2N1bWVudEJhc2VVUkkoU3RyaW5nIGJhc2VVUkkpCi0gICAgewotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0RG9jdW1lbnRTeXN0ZW1JZGVudGlmaWVyKGludCBub2RlSGFuZGxlKQotICAgIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXREb2N1bWVudEVuY29kaW5nKGludCBub2RlSGFuZGxlKQotICAgIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXREb2N1bWVudFN0YW5kYWxvbmUoaW50IG5vZGVIYW5kbGUpCi0gICAgewotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldERvY3VtZW50VmVyc2lvbihpbnQgZG9jdW1lbnRIYW5kbGUpCi0gICAgewotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXREb2N1bWVudEFsbERlY2xhcmF0aW9uc1Byb2Nlc3NlZCgpCi0gICAgewotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXREb2N1bWVudFR5cGVEZWNsYXJhdGlvblN5c3RlbUlkZW50aWZpZXIoKQotICAgIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXREb2N1bWVudFR5cGVEZWNsYXJhdGlvblB1YmxpY0lkZW50aWZpZXIoKQotICAgIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBnZXRFbGVtZW50QnlJZChTdHJpbmcgZWxlbWVudElkKQotICAgIHsKLSAgICAgICAgcmV0dXJuIERUTS5OVUxMOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIHN1cHBvcnRzUHJlU3RyaXBwaW5nKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBpc05vZGVBZnRlcihpbnQgZmlyc3ROb2RlSGFuZGxlLCBpbnQgc2Vjb25kTm9kZUhhbmRsZSkKLSAgICB7Ci0gICAgICAgIHJldHVybiBsZXNzVGhhbihmaXJzdE5vZGVIYW5kbGUsIHNlY29uZE5vZGVIYW5kbGUpOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGlzQ2hhcmFjdGVyRWxlbWVudENvbnRlbnRXaGl0ZXNwYWNlKGludCBub2RlSGFuZGxlKQotICAgIHsKLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGlzRG9jdW1lbnRBbGxEZWNsYXJhdGlvbnNQcm9jZXNzZWQoaW50IGRvY3VtZW50SGFuZGxlKQotICAgIHsKLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGlzQXR0cmlidXRlU3BlY2lmaWVkKGludCBhdHRyaWJ1dGVIYW5kbGUpCi0gICAgewotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgZGlzcGF0Y2hDaGFyYWN0ZXJzRXZlbnRzKAotICAgICAgICBpbnQgbm9kZUhhbmRsZSwKLSAgICAgICAgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIgY2gsCi0gICAgICAgIGJvb2xlYW4gbm9ybWFsaXplKQotICAgICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgZGlzcGF0Y2hUb0V2ZW50cyhpbnQgbm9kZUhhbmRsZSwgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIgY2gpCi0gICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAgewotICAgIH0KLQotICAgIHB1YmxpYyBvcmcudzNjLmRvbS5Ob2RlIGdldE5vZGUoaW50IG5vZGVIYW5kbGUpCi0gICAgewotICAgICAgICByZXR1cm4gbWFrZU5vZGUobm9kZUhhbmRsZSk7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gbmVlZHNUd29UaHJlYWRzKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIgZ2V0Q29udGVudEhhbmRsZXIoKQotICAgIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgcHVibGljIG9yZy54bWwuc2F4LmV4dC5MZXhpY2FsSGFuZGxlciBnZXRMZXhpY2FsSGFuZGxlcigpCi0gICAgewotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgb3JnLnhtbC5zYXguRW50aXR5UmVzb2x2ZXIgZ2V0RW50aXR5UmVzb2x2ZXIoKQotICAgIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgcHVibGljIG9yZy54bWwuc2F4LkRUREhhbmRsZXIgZ2V0RFRESGFuZGxlcigpCi0gICAgewotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgb3JnLnhtbC5zYXguRXJyb3JIYW5kbGVyIGdldEVycm9ySGFuZGxlcigpCi0gICAgewotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgb3JnLnhtbC5zYXguZXh0LkRlY2xIYW5kbGVyIGdldERlY2xIYW5kbGVyKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGFwcGVuZENoaWxkKGludCBuZXdDaGlsZCwgYm9vbGVhbiBjbG9uZSwgYm9vbGVhbiBjbG9uZURlcHRoKQotICAgIHsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBhcHBlbmRUZXh0Q2hpbGQoU3RyaW5nIHN0cikKLSAgICB7Ci0gICAgfQotCi0gICAgcHVibGljIFNvdXJjZUxvY2F0b3IgZ2V0U291cmNlTG9jYXRvckZvcihpbnQgbm9kZSkKLSAgICB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGRvY3VtZW50UmVnaXN0cmF0aW9uKCkKLSAgICB7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgZG9jdW1lbnRSZWxlYXNlKCkKLSAgICB7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgbWlncmF0ZVRvKERUTU1hbmFnZXIgbWFuYWdlcikKLSAgICB7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgcmVsZWFzZSgpCi0gICAgewotICAgICAgICBpZiAoX2RvY3VtZW50SUQgIT0gMCkgewotICAgICAgICAgICAgX2R0bU1hbmFnZXIucmVsZWFzZSh0aGlzLCB0cnVlKTsKLSAgICAgICAgICAgIF9kb2N1bWVudElEID0gMDsKLSAgICAgICAgfQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvZG9tL1NpbmdsZU5vZGVDb3VudGVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2RvbS9TaW5nbGVOb2RlQ291bnRlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyMDQyZTRhLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvZG9tL1NpbmdsZU5vZGVDb3VudGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNTggKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogU2luZ2xlTm9kZUNvdW50ZXIuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xMiAxMTo1ODoyMyBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuZG9tOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLkRPTTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuVHJhbnNsZXQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNQXhpc0l0ZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkF4aXM7Ci0KLQotLyoqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKi8KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBTaW5nbGVOb2RlQ291bnRlciBleHRlbmRzIE5vZGVDb3VudGVyIHsKLSAgICBzdGF0aWMgcHJpdmF0ZSBmaW5hbCBpbnRbXSBFbXB0eUFycmF5ID0gbmV3IGludFtdIHsgfTsKLSAgICBEVE1BeGlzSXRlcmF0b3IgX2NvdW50U2libGluZ3MgPSBudWxsOwotCi0gICAgcHVibGljIFNpbmdsZU5vZGVDb3VudGVyKFRyYW5zbGV0IHRyYW5zbGV0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBET00gZG9jdW1lbnQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIERUTUF4aXNJdGVyYXRvciBpdGVyYXRvcikgewotICAgICAgICBzdXBlcih0cmFuc2xldCwgZG9jdW1lbnQsIGl0ZXJhdG9yKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU2luZ2xlTm9kZUNvdW50ZXIoVHJhbnNsZXQgdHJhbnNsZXQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIERPTSBkb2N1bWVudCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFRNQXhpc0l0ZXJhdG9yIGl0ZXJhdG9yLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGhhc0Zyb20pIHsKLSAgICAgICAgc3VwZXIodHJhbnNsZXQsIGRvY3VtZW50LCBpdGVyYXRvciwgaGFzRnJvbSk7Ci0gICAgfQotCi0gICAgcHVibGljIE5vZGVDb3VudGVyIHNldFN0YXJ0Tm9kZShpbnQgbm9kZSkgewotICAgICAgICBfbm9kZSA9IG5vZGU7Ci0gICAgICAgIF9ub2RlVHlwZSA9IF9kb2N1bWVudC5nZXRFeHBhbmRlZFR5cGVJRChub2RlKTsKLSAgICBfY291bnRTaWJsaW5ncyA9IF9kb2N1bWVudC5nZXRBeGlzSXRlcmF0b3IoQXhpcy5QUkVDRURJTkdTSUJMSU5HKTsKLSAgICAgICAgcmV0dXJuIHRoaXM7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRDb3VudGVyKCkgewotICAgICAgICBpbnQgcmVzdWx0OwotICAgICAgICBpZiAoX3ZhbHVlICE9IEludGVnZXIuTUlOX1ZBTFVFKSB7Ci0gICAgICAgICAgICAgICAgLy9TZWUgRXJyYXRhIEUyNAotICAgICAgICAgICAgICAgIGlmIChfdmFsdWUgPT0gMCkgcmV0dXJuICIwIjsKLSAgICAgICAgICAgICAgICBlbHNlIGlmIChEb3VibGUuaXNOYU4oX3ZhbHVlKSkgcmV0dXJuICJOYU4iOwotICAgICAgICAgICAgICAgIGVsc2UgaWYgKF92YWx1ZSA8IDAgJiYgRG91YmxlLmlzSW5maW5pdGUoX3ZhbHVlKSkgcmV0dXJuICItSW5maW5pdHkiOwotICAgICAgICAgICAgICAgIGVsc2UgaWYgKERvdWJsZS5pc0luZmluaXRlKF92YWx1ZSkpIHJldHVybiAiSW5maW5pdHkiOwotICAgICAgICAgICAgICAgIGVsc2UgcmVzdWx0ID0gKGludCkgX3ZhbHVlOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgaW50IG5leHQgPSBfbm9kZTsKLSAgICAgICAgICAgIHJlc3VsdCA9IDA7Ci0gICAgICAgICAgICBib29sZWFuIG1hdGNoZXNDb3VudCA9IG1hdGNoZXNDb3VudChuZXh0KTsKLQotICAgICAgICAgICAgaWYgKCFtYXRjaGVzQ291bnQpIHsKLSAgICAgICAgICAgICAgICB3aGlsZSAoKG5leHQgPSBfZG9jdW1lbnQuZ2V0UGFyZW50KG5leHQpKSA+IEVORCkgewotICAgICAgICAgICAgICAgICAgICBpZiAobWF0Y2hlc0NvdW50KG5leHQpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsgICAgICAgICAgLy8gZm91bmQgdGFyZ2V0Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgaWYgKG1hdGNoZXNGcm9tKG5leHQpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBuZXh0ID0gRU5EOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7ICAgICAgICAgIC8vIG5vIHRhcmdldCBmb3VuZAotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAobmV4dCAhPSBFTkQpIHsKLSAgICAgICAgICAgICAgICBpbnQgZnJvbSA9IG5leHQ7Ci0KLSAgICAgICAgICAgICAgICBpZiAoIW1hdGNoZXNDb3VudCAmJiBfaGFzRnJvbSkgewotICAgICAgICAgICAgICAgICAgICAvLyBUYXJnZXQgZm91bmQsIGJ1dCBuZWVkIHRvIGNoZWNrIGlmIGFuY2VzdG9yIG1hdGNoZXMgZnJvbQotICAgICAgICAgICAgICAgICAgICB3aGlsZSAoKGZyb20gPSBfZG9jdW1lbnQuZ2V0UGFyZW50KGZyb20pKSA+IEVORCkgewotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1hdGNoZXNGcm9tKGZyb20pKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7ICAgICAgICAgIC8vIGZvdW5kIGZyb20KLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8vIEhhdmUgd2UgZm91bmQgYW5jZXN0b3IgbWF0Y2hpbmcgZnJvbT8KLSAgICAgICAgICAgICAgICBpZiAoZnJvbSAhPSBFTkQpIHsKLSAgICAgICAgICAgICAgICAgICAgX2NvdW50U2libGluZ3Muc2V0U3RhcnROb2RlKG5leHQpOwotICAgICAgICAgICAgICAgICAgICBkbyB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAobWF0Y2hlc0NvdW50KG5leHQpKSByZXN1bHQrKzsKLSAgICAgICAgICAgICAgICAgICAgfSB3aGlsZSAoKG5leHQgPSBfY291bnRTaWJsaW5ncy5uZXh0KCkpICE9IEVORCk7Ci0KLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZvcm1hdE51bWJlcnMocmVzdWx0KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIElmIG5vIHRhcmdldCBmb3VuZCB0aGVuIHBhc3MgdGhlIGVtcHR5IGxpc3QKLSAgICAgICAgICAgIHJldHVybiBmb3JtYXROdW1iZXJzKEVtcHR5QXJyYXkpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmb3JtYXROdW1iZXJzKHJlc3VsdCk7Ci0gICAgfQotCi0gICAgcHVibGljIHN0YXRpYyBOb2RlQ291bnRlciBnZXREZWZhdWx0Tm9kZUNvdW50ZXIoVHJhbnNsZXQgdHJhbnNsZXQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRE9NIGRvY3VtZW50LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERUTUF4aXNJdGVyYXRvciBpdGVyYXRvcikgewotICAgICAgICByZXR1cm4gbmV3IERlZmF1bHRTaW5nbGVOb2RlQ291bnRlcih0cmFuc2xldCwgZG9jdW1lbnQsIGl0ZXJhdG9yKTsKLSAgICB9Ci0KLSAgICBzdGF0aWMgY2xhc3MgRGVmYXVsdFNpbmdsZU5vZGVDb3VudGVyIGV4dGVuZHMgU2luZ2xlTm9kZUNvdW50ZXIgewotICAgICAgICBwdWJsaWMgRGVmYXVsdFNpbmdsZU5vZGVDb3VudGVyKFRyYW5zbGV0IHRyYW5zbGV0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERPTSBkb2N1bWVudCwgRFRNQXhpc0l0ZXJhdG9yIGl0ZXJhdG9yKSB7Ci0gICAgICAgICAgICBzdXBlcih0cmFuc2xldCwgZG9jdW1lbnQsIGl0ZXJhdG9yKTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyBOb2RlQ291bnRlciBzZXRTdGFydE5vZGUoaW50IG5vZGUpIHsKLSAgICAgICAgICAgIF9ub2RlID0gbm9kZTsKLSAgICAgICAgICAgIF9ub2RlVHlwZSA9IF9kb2N1bWVudC5nZXRFeHBhbmRlZFR5cGVJRChub2RlKTsKLSAgICAgICAgICAgIF9jb3VudFNpYmxpbmdzID0KLSAgICAgICAgX2RvY3VtZW50LmdldFR5cGVkQXhpc0l0ZXJhdG9yKEF4aXMuUFJFQ0VESU5HU0lCTElORywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2RvY3VtZW50LmdldEV4cGFuZGVkVHlwZUlEKG5vZGUpKTsKLSAgICAgICAgICAgIHJldHVybiB0aGlzOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIFN0cmluZyBnZXRDb3VudGVyKCkgewotICAgICAgICAgICAgaW50IHJlc3VsdDsKLSAgICAgICAgICAgIGlmIChfdmFsdWUgIT0gSW50ZWdlci5NSU5fVkFMVUUpIHsKLSAgICAgICAgICAgICAgICAvL1NlZSBFcnJhdGEgRTI0Ci0gICAgICAgICAgICAgICAgaWYgKF92YWx1ZSA9PSAwKSByZXR1cm4gIjAiOwotICAgICAgICAgICAgICAgIGVsc2UgaWYgKERvdWJsZS5pc05hTihfdmFsdWUpKSByZXR1cm4gIk5hTiI7Ci0gICAgICAgICAgICAgICAgZWxzZSBpZiAoX3ZhbHVlIDwgMCAmJiBEb3VibGUuaXNJbmZpbml0ZShfdmFsdWUpKSByZXR1cm4gIi1JbmZpbml0eSI7Ci0gICAgICAgICAgICAgICAgZWxzZSBpZiAoRG91YmxlLmlzSW5maW5pdGUoX3ZhbHVlKSkgcmV0dXJuICJJbmZpbml0eSI7Ci0gICAgICAgICAgICAgICAgZWxzZSByZXN1bHQgPSAoaW50KSBfdmFsdWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBpbnQgbmV4dDsKLSAgICAgICAgICAgICAgICByZXN1bHQgPSAxOwotICAgICAgICAgICAgICAgIF9jb3VudFNpYmxpbmdzLnNldFN0YXJ0Tm9kZShfbm9kZSk7Ci0gICAgICAgICAgICAgICAgd2hpbGUgKChuZXh0ID0gX2NvdW50U2libGluZ3MubmV4dCgpKSAhPSBFTkQpIHsKLSAgICAgICAgICAgICAgICAgICAgcmVzdWx0Kys7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIGZvcm1hdE51bWJlcnMocmVzdWx0KTsKLSAgICAgICAgfQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvZG9tL1NpbmdsZXRvbkl0ZXJhdG9yLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2RvbS9TaW5nbGV0b25JdGVyYXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwZThkYWNhLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvZG9tL1NpbmdsZXRvbkl0ZXJhdG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5NCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBTaW5nbGV0b25JdGVyYXRvci5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzA2IDEwOjE1OjE4IHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5kb207Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1BeGlzSXRlcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0ucmVmLkRUTUF4aXNJdGVyYXRvckJhc2U7Ci0KLS8qKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICovCi1wdWJsaWMgY2xhc3MgU2luZ2xldG9uSXRlcmF0b3IgZXh0ZW5kcyBEVE1BeGlzSXRlcmF0b3JCYXNlIHsKLSAgICBwcml2YXRlIGludCBfbm9kZTsKLSAgICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gX2lzQ29uc3RhbnQ7Ci0KLSAgICBwdWJsaWMgU2luZ2xldG9uSXRlcmF0b3IoKSB7Ci0gICAgICAgIHRoaXMoSW50ZWdlci5NSU5fVkFMVUUsIGZhbHNlKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU2luZ2xldG9uSXRlcmF0b3IoaW50IG5vZGUpIHsKLSAgICAgICAgdGhpcyhub2RlLCBmYWxzZSk7Ci0gICAgfQotCi0gICAgcHVibGljIFNpbmdsZXRvbkl0ZXJhdG9yKGludCBub2RlLCBib29sZWFuIGNvbnN0YW50KSB7Ci0gICAgICAgIF9ub2RlID0gX3N0YXJ0Tm9kZSA9IG5vZGU7Ci0gICAgICAgIF9pc0NvbnN0YW50ID0gY29uc3RhbnQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogT3ZlcnJpZGUgdGhlIHZhbHVlIG9mIDx0dD5fbm9kZTwvdHQ+IG9ubHkgd2hlbiB0aGlzCi0gICAgICogb2JqZWN0IHdhcyBjb25zdHJ1Y3RlZCB1c2luZyB0aGUgZW1wdHkgY29uc3RydWN0b3IuCi0gICAgICovCi0gICAgcHVibGljIERUTUF4aXNJdGVyYXRvciBzZXRTdGFydE5vZGUoaW50IG5vZGUpIHsKLSAgICAgICAgaWYgKF9pc0NvbnN0YW50KSB7Ci0gICAgICAgICAgICBfbm9kZSA9IF9zdGFydE5vZGU7Ci0gICAgICAgICAgICByZXR1cm4gcmVzZXRQb3NpdGlvbigpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKF9pc1Jlc3RhcnRhYmxlKSB7Ci0gICAgICAgICAgICBpZiAoX25vZGUgPD0gMCkKLSAgICAgICAgICAgICAgICBfbm9kZSA9IF9zdGFydE5vZGUgPSBub2RlOwotICAgICAgICAgICAgcmV0dXJuIHJlc2V0UG9zaXRpb24oKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gdGhpczsKLSAgICB9Ci0KLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIHJlc2V0KCkgewotICAgICAgICBpZiAoX2lzQ29uc3RhbnQpIHsKLSAgICAgICAgICAgIF9ub2RlID0gX3N0YXJ0Tm9kZTsKLSAgICAgICAgICAgIHJldHVybiByZXNldFBvc2l0aW9uKCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBmaW5hbCBib29sZWFuIHRlbXAgPSBfaXNSZXN0YXJ0YWJsZTsKLSAgICAgICAgICAgIF9pc1Jlc3RhcnRhYmxlID0gdHJ1ZTsKLSAgICAgICAgICAgIHNldFN0YXJ0Tm9kZShfc3RhcnROb2RlKTsKLSAgICAgICAgICAgIF9pc1Jlc3RhcnRhYmxlID0gdGVtcDsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gdGhpczsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IG5leHQoKSB7Ci0gICAgICAgIGZpbmFsIGludCByZXN1bHQgPSBfbm9kZTsKLSAgICAgICAgX25vZGUgPSBEVE1BeGlzSXRlcmF0b3IuRU5EOwotICAgICAgICByZXR1cm4gcmV0dXJuTm9kZShyZXN1bHQpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldE1hcmsoKSB7Ci0gICAgICAgIF9tYXJrZWROb2RlID0gX25vZGU7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgZ290b01hcmsoKSB7Ci0gICAgICAgIF9ub2RlID0gX21hcmtlZE5vZGU7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vU29ydFNldHRpbmdzLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2RvbS9Tb3J0U2V0dGluZ3MuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNjMxYzVlNy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2RvbS9Tb3J0U2V0dGluZ3MuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE0MCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBTb3J0U2V0dGluZ3MuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8wNiAxMDoxOToyMiBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuZG9tOwotCi1pbXBvcnQgamF2YS50ZXh0LkNvbGxhdG9yOwotaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMucnVudGltZS5BYnN0cmFjdFRyYW5zbGV0OwotCi0vKioKLSAqIENsYXNzIGZvciBjYXJyeWluZyBzZXR0aW5ncyB0aGF0IGFyZSB0byBiZSB1c2VkIGZvciBhIHBhcnRpY3VsYXIgc2V0Ci0gKiBvZiA8Y29kZT54c2w6c29ydDwvY29kZT4gZWxlbWVudHMuCi0gKi8KLWZpbmFsIGNsYXNzIFNvcnRTZXR0aW5ncyB7Ci0gICAgLyoqCi0gICAgICogQSByZWZlcmVuY2UgdG8gdGhlIHRyYW5zbGV0IG9iamVjdCBmb3IgdGhlIHRyYW5zZm9ybWF0aW9uLgotICAgICAqLwotICAgIHByaXZhdGUgQWJzdHJhY3RUcmFuc2xldCBfdHJhbnNsZXQ7Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgc29ydCBvcmRlciAoYXNjZW5kaW5nIG9yIGRlc2NlbmRpbmcpIGZvciBlYWNoIGxldmVsIG9mCi0gICAgICogPGNvZGU+eHNsOnNvcnQ8L2NvZGU+Ci0gICAgICovCi0gICAgcHJpdmF0ZSBpbnRbXSBfc29ydE9yZGVyczsKLQotICAgIC8qKgotICAgICAqIFRoZSB0eXBlIG9mIGNvbXBhcmlzb24gKHRleHQgb3IgbnVtYmVyKSBmb3IgZWFjaCBsZXZlbCBvZgotICAgICAqIDxjb2RlPnhzbDpzb3J0PC9jb2RlPgotICAgICAqLwotICAgIHByaXZhdGUgaW50W10gX3R5cGVzOwotCi0gICAgLyoqCi0gICAgICogVGhlIExvY2FsZSBmb3IgZWFjaCBsZXZlbCBvZiA8Y29kZT54c2w6c29ydDwvY29kZT4sIGJhc2VkIG9uIGFueSBsYW5nCi0gICAgICogYXR0cmlidXRlIG9yIHRoZSBkZWZhdWx0IExvY2FsZS4KLSAgICAgKi8KLSAgICBwcml2YXRlIExvY2FsZVtdIF9sb2NhbGVzOwotCi0gICAgLyoqCi0gICAgICogVGhlIENvbGxhdG9yIG9iamVjdCBpbiBlZmZlY3QgZm9yIGVhY2ggbGV2ZWwgb2YgPGNvZGU+eHNsOnNvcnQ8L2NvZGU+Ci0gICAgICovCi0gICAgcHJpdmF0ZSBDb2xsYXRvcltdIF9jb2xsYXRvcnM7Ci0KLSAgICAvKioKLSAgICAgKiBDYXNlIG9yZGVyaW5nIGZvciBlYWNoIGxldmVsIG9mIDxjb2RlPnhzbDpzb3J0PC9jb2RlPi4KLSAgICAgKi8KLSAgICBwcml2YXRlIFN0cmluZ1tdIF9jYXNlT3JkZXJzOwotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlIGFuIGluc3RhbmNlIG9mIDxjb2RlPlNvcnRTZXR0aW5nczwvY29kZT4uCi0gICAgICogQHBhcmFtIHRyYW5zbGV0IHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMucnVudGltZS5BYnN0cmFjdFRyYW5zbGV0fQotICAgICAqICAgICAgICAgICAgICAgICBvYmplY3QgZm9yIHRoZSB0cmFuc2Zvcm1hdGlvbgotICAgICAqIEBwYXJhbSBzb3J0T3JkZXJzIGFuIGFycmF5IHNwZWNpZnlpbmcgdGhlIHNvcnQgb3JkZXIgZm9yIGVhY2ggc29ydCBsZXZlbAotICAgICAqIEBwYXJhbSB0eXBlcyBhbiBhcnJheSBzcGVjaWZ5aW5nIHRoZSB0eXBlIG9mIGNvbXBhcmlzb24gZm9yIGVhY2ggc29ydAotICAgICAqICAgICAgICAgICAgICBsZXZlbCAodGV4dCBvciBudW1iZXIpCi0gICAgICogQHBhcmFtIGxvY2FsZXMgYW4gYXJyYXkgc3BlY2lmeWluZyB0aGUgTG9jYWxlIGZvciBlYWNoIHNvcnQgbGV2ZWwKLSAgICAgKiBAcGFyYW0gY29sbGF0b3JzIGFuIGFycmF5IHNwZWNpZnlpbmcgdGhlIENvbGxhdGlvbiBpbiBlZmZlY3QgZm9yIGVhY2gKLSAgICAgKiAgICAgICAgICAgICAgICAgIHNvcnQgbGV2ZWwKLSAgICAgKiBAcGFyYW0gY2FzZU9yZGVycyBhbiBhcnJheSBzcGVjaWZ5aW5nIHdoZXRoZXIgdXBwZXItY2FzZSwgbG93ZXItY2FzZQotICAgICAqICAgICAgICAgICAgICAgICAgIG9yIG5laXRoZXIgaXMgdG8gdGFrZSBwcmVjZWRlbmNlIGZvciBlYWNoIHNvcnQgbGV2ZWwuCi0gICAgICogICAgICAgICAgICAgICAgICAgVGhlIHZhbHVlIG9mIGVhY2ggZWxlbWVudCBpcyBlcXVhbCB0byBvbmUgb2YKLSAgICAgKiAgICAgICAgICAgICAgICAgICA8Y29kZT4idXBwZXItZmlyc3QiLCAibG93ZXItZmlyc3QiLCBvciAiIjwvY29kZT4uCi0gICAgICovCi0gICAgU29ydFNldHRpbmdzKEFic3RyYWN0VHJhbnNsZXQgdHJhbnNsZXQsIGludFtdIHNvcnRPcmRlcnMsIGludFtdIHR5cGVzLAotICAgICAgICAgICAgICAgICBMb2NhbGVbXSBsb2NhbGVzLCBDb2xsYXRvcltdIGNvbGxhdG9ycywgU3RyaW5nW10gY2FzZU9yZGVycykgewotICAgICAgICBfdHJhbnNsZXQgPSB0cmFuc2xldDsKLSAgICAgICAgX3NvcnRPcmRlcnMgPSBzb3J0T3JkZXJzOwotICAgICAgICBfdHlwZXMgPSB0eXBlczsKLSAgICAgICAgX2xvY2FsZXMgPSBsb2NhbGVzOwotICAgICAgICBfY29sbGF0b3JzID0gY29sbGF0b3JzOwotICAgICAgICBfY2FzZU9yZGVycyA9IGNhc2VPcmRlcnM7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHJldHVybiBBIHJlZmVyZW5jZSB0byB0aGUgdHJhbnNsZXQgb2JqZWN0IGZvciB0aGUgdHJhbnNmb3JtYXRpb24uCi0gICAgICovCi0gICAgQWJzdHJhY3RUcmFuc2xldCBnZXRUcmFuc2xldCgpIHsKLSAgICAgICAgcmV0dXJuIF90cmFuc2xldDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAcmV0dXJuIEFuIGFycmF5IGNvbnRhaW5pbmcgdGhlIHNvcnQgb3JkZXIgKGFzY2VuZGluZyBvciBkZXNjZW5kaW5nKQotICAgICAqICAgICAgICAgZm9yIGVhY2ggbGV2ZWwgb2YgPGNvZGU+eHNsOnNvcnQ8L2NvZGU+Ci0gICAgICovCi0gICAgaW50W10gZ2V0U29ydE9yZGVycygpIHsKLSAgICAgICAgcmV0dXJuIF9zb3J0T3JkZXJzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEByZXR1cm4gQW4gYXJyYXkgY29udGFpbmluZyB0aGUgdHlwZSBvZiBjb21wYXJpc29uICh0ZXh0IG9yIG51bWJlcikKLSAgICAgKiAgICAgICAgIHRvIHBlcmZvcm0gZm9yIGVhY2ggbGV2ZWwgb2YgPGNvZGU+eHNsOnNvcnQ8L2NvZGU+Ci0gICAgICovCi0gICAgaW50W10gZ2V0VHlwZXMoKSB7Ci0gICAgICAgIHJldHVybiBfdHlwZXM7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHJldHVybiBBbiBhcnJheSBjb250YWluaW5nIHRoZSBMb2NhbGUgb2JqZWN0IGluIGVmZmVjdCBmb3IgZWFjaCBsZXZlbAotICAgICAqICAgICAgICAgb2YgPGNvZGU+eHNsOnNvcnQ8L2NvZGU+Ci0gICAgICovCi0gICAgTG9jYWxlW10gZ2V0TG9jYWxlcygpIHsKLSAgICAgICAgcmV0dXJuIF9sb2NhbGVzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEByZXR1cm4gQW4gYXJyYXkgY29udGFpbmluZyB0aGUgQ29sbGF0b3Igb2JqZWN0IGluIGVmZmVjdCBmb3IgZWFjaCBsZXZlbAotICAgICAqICAgICAgICAgb2YgPGNvZGU+eHNsOnNvcnQ8L2NvZGU+Ci0gICAgICovCi0gICAgQ29sbGF0b3JbXSBnZXRDb2xsYXRvcnMoKSB7Ci0gICAgICAgIHJldHVybiBfY29sbGF0b3JzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEByZXR1cm4gQW4gYXJyYXkgc3BlY2lmeWluZyB0aGUgY2FzZSBvcmRlcmluZyBmb3IgZWFjaCBsZXZlbCBvZgotICAgICAqICAgICAgICAgPGNvZGU+eHNsOnNvcnQ8L2NvZGU+LgotICAgICAqLwotICAgIFN0cmluZ1tdIGdldENhc2VPcmRlcnMoKSB7Ci0gICAgICAgIHJldHVybiBfY2FzZU9yZGVyczsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2RvbS9Tb3J0aW5nSXRlcmF0b3IuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvZG9tL1NvcnRpbmdJdGVyYXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlZmYyNjNhLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvZG9tL1NvcnRpbmdJdGVyYXRvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTUxICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFNvcnRpbmdJdGVyYXRvci5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzA2IDEwOjIzOjMyIHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5kb207Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMucnVudGltZS5CYXNpc0xpYnJhcnk7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNQXhpc0l0ZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLnJlZi5EVE1BeGlzSXRlcmF0b3JCYXNlOwotCi0vKioKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgU29ydGluZ0l0ZXJhdG9yIGV4dGVuZHMgRFRNQXhpc0l0ZXJhdG9yQmFzZSB7Ci0gICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgaW50IElOSVRfREFUQV9TSVpFID0gMTY7Ci0KLSAgICBwcml2YXRlIERUTUF4aXNJdGVyYXRvciBfc291cmNlOwotICAgIHByaXZhdGUgTm9kZVNvcnRSZWNvcmRGYWN0b3J5IF9mYWN0b3J5OwotCi0gICAgcHJpdmF0ZSBOb2RlU29ydFJlY29yZFtdIF9kYXRhOwotICAgIHByaXZhdGUgaW50IF9mcmVlID0gMDsKLSAgICBwcml2YXRlIGludCBfY3VycmVudDsgICAgICAgLy8gaW5kZXggaW4gX25vZGVzIG9mIHRoZSBuZXh0IG5vZGUgdG8gdHJ5Ci0KLSAgICBwdWJsaWMgU29ydGluZ0l0ZXJhdG9yKERUTUF4aXNJdGVyYXRvciBzb3VyY2UsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICBOb2RlU29ydFJlY29yZEZhY3RvcnkgZmFjdG9yeSkgewotICAgICAgICBfc291cmNlID0gc291cmNlOwotICAgICAgICBfZmFjdG9yeSA9IGZhY3Rvcnk7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBuZXh0KCkgewotICAgICAgICByZXR1cm4gX2N1cnJlbnQgPCBfZnJlZSA/IF9kYXRhW19jdXJyZW50KytdLmdldE5vZGUoKSA6IEVORDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIHNldFN0YXJ0Tm9kZShpbnQgbm9kZSkgewotICAgICAgICB0cnkgewotICAgICAgICAgICAgX3NvdXJjZS5zZXRTdGFydE5vZGUoX3N0YXJ0Tm9kZSA9IG5vZGUpOwotICAgICAgICAgICAgX2RhdGEgPSBuZXcgTm9kZVNvcnRSZWNvcmRbSU5JVF9EQVRBX1NJWkVdOwotICAgICAgICAgICAgX2ZyZWUgPSAwOwotCi0gICAgICAgICAgICAvLyBnYXRoZXIgYWxsIG5vZGVzIGZyb20gdGhlIHNvdXJjZSBpdGVyYXRvcgotICAgICAgICAgICAgd2hpbGUgKChub2RlID0gX3NvdXJjZS5uZXh0KCkpICE9IEVORCkgewotICAgICAgICAgICAgICAgIGFkZFJlY29yZChfZmFjdG9yeS5tYWtlTm9kZVNvcnRSZWNvcmQobm9kZSxfZnJlZSkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gbm93IHNvcnQgdGhlIHJlY29yZHMKLSAgICAgICAgICAgIHF1aWNrc29ydCgwLCBfZnJlZSAtIDEpOwotCi0gICAgICAgICAgICBfY3VycmVudCA9IDA7Ci0gICAgICAgICAgICByZXR1cm4gdGhpczsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIHJldHVybiB0aGlzOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIGludCBnZXRQb3NpdGlvbigpIHsKLSAgICAgICAgcmV0dXJuIF9jdXJyZW50ID09IDAgPyAxIDogX2N1cnJlbnQ7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBnZXRMYXN0KCkgewotICAgICAgICByZXR1cm4gX2ZyZWU7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0TWFyaygpIHsKLSAgICAgICAgX3NvdXJjZS5zZXRNYXJrKCk7Ci0gICAgICAgIF9tYXJrZWROb2RlID0gX2N1cnJlbnQ7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgZ290b01hcmsoKSB7Ci0gICAgICAgIF9zb3VyY2UuZ290b01hcmsoKTsKLSAgICAgICAgX2N1cnJlbnQgPSBfbWFya2VkTm9kZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDbG9uZSBhIDxjb2RlPlNvcnRpbmdJdGVyYXRvcjwvY29kZT4gYnkgY2xvbmluZyBpdHMgc291cmNlCi0gICAgICogaXRlcmF0b3IgYW5kIHRoZW4gc2hhcmluZyB0aGUgZmFjdG9yeSBhbmQgdGhlIGFycmF5IG9mCi0gICAgICogPGNvZGU+Tm9kZVNvcnRSZWNvcmRzPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIGNsb25lSXRlcmF0b3IoKSB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBmaW5hbCBTb3J0aW5nSXRlcmF0b3IgY2xvbmUgPSAoU29ydGluZ0l0ZXJhdG9yKSBzdXBlci5jbG9uZSgpOwotICAgICAgICAgICAgY2xvbmUuX3NvdXJjZSA9IF9zb3VyY2UuY2xvbmVJdGVyYXRvcigpOwotICAgICAgICAgICAgY2xvbmUuX2ZhY3RvcnkgPSBfZmFjdG9yeTsgICAgICAgICAgLy8gc2hhcmVkIGJldHdlZW4gY2xvbmVzCi0gICAgICAgICAgICBjbG9uZS5fZGF0YSA9IF9kYXRhOyAgICAgICAgICAgICAgICAvLyBzaGFyZWQgYmV0d2VlbiBjbG9uZXMKLSAgICAgICAgICAgIGNsb25lLl9mcmVlID0gX2ZyZWU7Ci0gICAgICAgICAgICBjbG9uZS5fY3VycmVudCA9IF9jdXJyZW50OwotICAgICAgICAgICAgY2xvbmUuc2V0UmVzdGFydGFibGUoZmFsc2UpOwotICAgICAgICAgICAgcmV0dXJuIGNsb25lLnJlc2V0KCk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIEJhc2lzTGlicmFyeS5ydW5UaW1lRXJyb3IoQmFzaXNMaWJyYXJ5LklURVJBVE9SX0NMT05FX0VSUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZS50b1N0cmluZygpKTsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIGFkZFJlY29yZChOb2RlU29ydFJlY29yZCByZWNvcmQpIHsKLSAgICAgICAgaWYgKF9mcmVlID09IF9kYXRhLmxlbmd0aCkgewotICAgICAgICAgICAgTm9kZVNvcnRSZWNvcmRbXSBuZXdBcnJheSA9IG5ldyBOb2RlU29ydFJlY29yZFtfZGF0YS5sZW5ndGggKiAyXTsKLSAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoX2RhdGEsIDAsIG5ld0FycmF5LCAwLCBfZnJlZSk7Ci0gICAgICAgICAgICBfZGF0YSA9IG5ld0FycmF5OwotICAgICAgICB9Ci0gICAgICAgIF9kYXRhW19mcmVlKytdID0gcmVjb3JkOwotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBxdWlja3NvcnQoaW50IHAsIGludCByKSB7Ci0gICAgICAgIHdoaWxlIChwIDwgcikgewotICAgICAgICAgICAgZmluYWwgaW50IHEgPSBwYXJ0aXRpb24ocCwgcik7Ci0gICAgICAgICAgICBxdWlja3NvcnQocCwgcSk7Ci0gICAgICAgICAgICBwID0gcSArIDE7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwcml2YXRlIGludCBwYXJ0aXRpb24oaW50IHAsIGludCByKSB7Ci0gICAgICAgIGZpbmFsIE5vZGVTb3J0UmVjb3JkIHggPSBfZGF0YVsocCArIHIpID4+PiAxXTsKLSAgICAgICAgaW50IGkgPSBwIC0gMTsKLSAgICAgICAgaW50IGogPSByICsgMTsKLSAgICAgICAgd2hpbGUgKHRydWUpIHsKLSAgICAgICAgICAgIHdoaWxlICh4LmNvbXBhcmVUbyhfZGF0YVstLWpdKSA8IDApOwotICAgICAgICAgICAgd2hpbGUgKHguY29tcGFyZVRvKF9kYXRhWysraV0pID4gMCk7Ci0gICAgICAgICAgICBpZiAoaSA8IGopIHsKLSAgICAgICAgICAgICAgICBmaW5hbCBOb2RlU29ydFJlY29yZCB0ID0gX2RhdGFbaV07Ci0gICAgICAgICAgICAgICAgX2RhdGFbaV0gPSBfZGF0YVtqXTsKLSAgICAgICAgICAgICAgICBfZGF0YVtqXSA9IHQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICByZXR1cm4oaik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2RvbS9TdGVwSXRlcmF0b3IuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvZG9tL1N0ZXBJdGVyYXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzYWNlYzc0Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvZG9tL1N0ZXBJdGVyYXRvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTQwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFN0ZXBJdGVyYXRvci5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzA2IDEwOjI2OjQ3IHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5kb207Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMucnVudGltZS5CYXNpc0xpYnJhcnk7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNQXhpc0l0ZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLnJlZi5EVE1BeGlzSXRlcmF0b3JCYXNlOwotCi0vKioKLSAqIEEgc3RlcCBpdGVyYXRvciBpcyB1c2VkIHRvIGV2YWx1YXRlIGV4cHJlc3Npb25zIGxpa2UgIkJPT0svVElUTEUiLgotICogQSBiZXR0ZXIgbmFtZSBmb3IgdGhpcyBpdGVyYXRvciB3b3VsZCBoYXZlIGJlZW4gUGFyZW50SXRlcmF0b3Igc2luY2UKLSAqIGJvdGggIkJPT0siIGFuZCAiVElUTEUiIGFyZSBzdGVwcyBpbiBYUGF0aCBsaW5nby4gU3RlcCBpdGVyYXRvcnMgYXJlCi0gKiBjb25zdHJ1Y3RlZCBmcm9tIHR3byBvdGhlciBpdGVyYXRvcnMgd2hpY2ggd2UgYXJlIGdvaW5nIHRvIHJlZmVyIHRvCi0gKiBhcyAib3V0ZXIiIGFuZCAiaW5uZXIiLiBFdmVyeSBub2RlIGZyb20gdGhlIG91dGVyIGl0ZXJhdG9yICh0aGUgb25lCi0gKiBmb3IgQk9PSyBpbiBvdXIgZXhhbXBsZSkgaXMgdXNlZCB0byBpbml0aWFsaXplIHRoZSBpbm5lciBpdGVyYXRvci4KLSAqIEFmdGVyIHRoaXMgaW5pdGlhbGl6YXRpb24sIGV2ZXJ5IG5vZGUgZnJvbSB0aGUgaW5uZXIgaXRlcmF0b3IgaXMKLSAqIHJldHVybmVkIChpbiBlc3NlbmNlLCBpbXBsZW1lbnRpbmcgYSAibmVzdGVkIGxvb3AiKS4KLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqIEBhdXRob3IgRXJ3aW4gQm9sd2lkdCA8ZWpiQGtsb21wLm9yZz4KLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICovCi1wdWJsaWMgY2xhc3MgU3RlcEl0ZXJhdG9yIGV4dGVuZHMgRFRNQXhpc0l0ZXJhdG9yQmFzZSB7Ci0KLSAgICAvKioKLSAgICAgKiBBIHJlZmVyZW5jZSB0byB0aGUgIm91dGVyIiBpdGVyYXRvci4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgRFRNQXhpc0l0ZXJhdG9yIF9zb3VyY2U7Ci0KLSAgICAvKioKLSAgICAgKiBBIHJlZmVyZW5jZSB0byB0aGUgImlubmVyIiBpdGVyYXRvci4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgRFRNQXhpc0l0ZXJhdG9yIF9pdGVyYXRvcjsKLQotICAgIC8qKgotICAgICAqIFRlbXAgdmFyaWFibGUgdG8gc3RvcmUgYSBtYXJrZWQgcG9zaXRpb24uCi0gICAgICovCi0gICAgcHJpdmF0ZSBpbnQgX3BvcyA9IC0xOwotCi0gICAgcHVibGljIFN0ZXBJdGVyYXRvcihEVE1BeGlzSXRlcmF0b3Igc291cmNlLCBEVE1BeGlzSXRlcmF0b3IgaXRlcmF0b3IpIHsKLSAgICAgICAgX3NvdXJjZSA9IHNvdXJjZTsKLSAgICAgICAgX2l0ZXJhdG9yID0gaXRlcmF0b3I7Ci0vLyBTeXN0ZW0ub3V0LnByaW50bG4oIlNJIHNvdXJjZSA9ICIgKyBzb3VyY2UgKyAiIHRoaXMgPSAiICsgdGhpcyk7Ci0vLyBTeXN0ZW0ub3V0LnByaW50bG4oIlNJIGl0ZXJhdG9yID0gIiArIGl0ZXJhdG9yICsgIiB0aGlzID0gIiArIHRoaXMpOwotICAgIH0KLQotCi0gICAgcHVibGljIHZvaWQgc2V0UmVzdGFydGFibGUoYm9vbGVhbiBpc1Jlc3RhcnRhYmxlKSB7Ci0gICAgICAgIF9pc1Jlc3RhcnRhYmxlID0gaXNSZXN0YXJ0YWJsZTsKLSAgICAgICAgX3NvdXJjZS5zZXRSZXN0YXJ0YWJsZShpc1Jlc3RhcnRhYmxlKTsKLSAgICAgICAgX2l0ZXJhdG9yLnNldFJlc3RhcnRhYmxlKHRydWUpOyAgICAgICAgIC8vIG11c3QgYmUgcmVzdGFydGFibGUKLSAgICB9Ci0KLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIGNsb25lSXRlcmF0b3IoKSB7Ci0gICAgICAgIF9pc1Jlc3RhcnRhYmxlID0gZmFsc2U7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBmaW5hbCBTdGVwSXRlcmF0b3IgY2xvbmUgPSAoU3RlcEl0ZXJhdG9yKSBzdXBlci5jbG9uZSgpOwotICAgICAgICAgICAgY2xvbmUuX3NvdXJjZSA9IF9zb3VyY2UuY2xvbmVJdGVyYXRvcigpOwotICAgICAgICAgICAgY2xvbmUuX2l0ZXJhdG9yID0gX2l0ZXJhdG9yLmNsb25lSXRlcmF0b3IoKTsKLSAgICAgICAgICAgIGNsb25lLl9pdGVyYXRvci5zZXRSZXN0YXJ0YWJsZSh0cnVlKTsgICAgICAgLy8gbXVzdCBiZSByZXN0YXJ0YWJsZQotICAgICAgICAgICAgY2xvbmUuX2lzUmVzdGFydGFibGUgPSBmYWxzZTsKLSAgICAgICAgICAgIHJldHVybiBjbG9uZS5yZXNldCgpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICBCYXNpc0xpYnJhcnkucnVuVGltZUVycm9yKEJhc2lzTGlicmFyeS5JVEVSQVRPUl9DTE9ORV9FUlIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGUudG9TdHJpbmcoKSk7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3Igc2V0U3RhcnROb2RlKGludCBub2RlKSB7Ci0gICAgICAgIGlmIChfaXNSZXN0YXJ0YWJsZSkgewotICAgICAgICAgICAgLy8gU2V0IHN0YXJ0IG5vZGUgZm9yIGxlZnQtaGFuZCBpdGVyYXRvci4uLgotICAgICAgICAgICAgX3NvdXJjZS5zZXRTdGFydE5vZGUoX3N0YXJ0Tm9kZSA9IG5vZGUpOwotCi0gICAgICAgICAgICAvLyAuLi4gYW5kIGdldCBzdGFydCBub2RlIGZvciByaWdodC1oYW5kIGl0ZXJhdG9yIGZyb20gbGVmdC1oYW5kLAotICAgICAgICAgICAgLy8gd2l0aCBzcGVjaWFsIGNhc2UgZm9yIC8vKiBwYXRoIC0gc2VlIFBhcmVudExvY2F0aW9uUGF0aAotICAgICAgICAgICAgX2l0ZXJhdG9yLnNldFN0YXJ0Tm9kZShfaW5jbHVkZVNlbGYgPyBfc3RhcnROb2RlIDogX3NvdXJjZS5uZXh0KCkpOwotICAgICAgICAgICAgcmV0dXJuIHJlc2V0UG9zaXRpb24oKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gdGhpczsKLSAgICB9Ci0KLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIHJlc2V0KCkgewotICAgICAgICBfc291cmNlLnJlc2V0KCk7Ci0gICAgICAgIC8vIFNwZWNpYWwgY2FzZSBmb3IgLy8qIHBhdGggLSBzZWUgUGFyZW50TG9jYXRpb25QYXRoCi0gICAgICAgIF9pdGVyYXRvci5zZXRTdGFydE5vZGUoX2luY2x1ZGVTZWxmID8gX3N0YXJ0Tm9kZSA6IF9zb3VyY2UubmV4dCgpKTsKLSAgICAgICAgcmV0dXJuIHJlc2V0UG9zaXRpb24oKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IG5leHQoKSB7Ci0gICAgICAgIGZvciAoaW50IG5vZGU7OykgewotICAgICAgICAgICAgLy8gVHJ5IHRvIGdldCBhbm90aGVyIG5vZGUgZnJvbSB0aGUgcmlnaHQtaGFuZCBpdGVyYXRvcgotICAgICAgICAgICAgaWYgKChub2RlID0gX2l0ZXJhdG9yLm5leHQoKSkgIT0gRU5EKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHJldHVybk5vZGUobm9kZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyBJZiBub3QsIGdldCB0aGUgbmV4dCBzdGFydGluZyBwb2ludCBmcm9tIGxlZnQtaGFuZCBpdGVyYXRvci4uLgotICAgICAgICAgICAgZWxzZSBpZiAoKG5vZGUgPSBfc291cmNlLm5leHQoKSkgPT0gRU5EKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIEVORDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIC4uLmFuZCBwYXNzIGl0IG9uIHRvIHRoZSByaWdodC1oYW5kIGl0ZXJhdG9yCi0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBfaXRlcmF0b3Iuc2V0U3RhcnROb2RlKG5vZGUpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0TWFyaygpIHsKLSAgICAgICAgX3NvdXJjZS5zZXRNYXJrKCk7Ci0gICAgICAgIF9pdGVyYXRvci5zZXRNYXJrKCk7Ci0gICAgICAgIC8vX3BvcyA9IF9wb3NpdGlvbjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBnb3RvTWFyaygpIHsKLSAgICAgICAgX3NvdXJjZS5nb3RvTWFyaygpOwotICAgICAgICBfaXRlcmF0b3IuZ290b01hcmsoKTsKLSAgICAgICAgLy9fcG9zaXRpb24gPSBfcG9zOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvZG9tL1N0cmlwV2hpdGVzcGFjZUZpbHRlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vU3RyaXBXaGl0ZXNwYWNlRmlsdGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDgyMTgwMDkuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vU3RyaXBXaGl0ZXNwYWNlRmlsdGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzNCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBTdHJpcFdoaXRlc3BhY2VGaWx0ZXIuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8wNiAxMDozMjowNSBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuZG9tOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLkRPTTsKLQotLyoqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgU3RyaXBXaGl0ZXNwYWNlRmlsdGVyIHsKLSAgICBwdWJsaWMgYm9vbGVhbiBzdHJpcFNwYWNlKERPTSBkb20sIGludCBub2RlLCBpbnQgdHlwZSk7Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2RvbS9Vbmlvbkl0ZXJhdG9yLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL2RvbS9Vbmlvbkl0ZXJhdG9yLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGQwNTRjN2UuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vVW5pb25JdGVyYXRvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTAwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNiBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFVuaW9uSXRlcmF0b3IuamF2YSx2IDEuNSAyMDA1LzA5LzI4IDEzOjQ4OjM4IHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5kb207Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuRE9NOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5ydW50aW1lLkJhc2lzTGlicmFyeTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1BeGlzSXRlcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0ucmVmLkRUTUF4aXNJdGVyYXRvckJhc2U7Ci0KLS8qKgotICogVW5pb25JdGVyYXRvciB0YWtlcyBhIHNldCBvZiBOb2RlSXRlcmF0b3JzIGFuZCBwcm9kdWNlcwotICogYSBtZXJnZWQgTm9kZVNldCBpbiBkb2N1bWVudCBvcmRlciB3aXRoIGR1cGxpY2F0ZXMgcmVtb3ZlZAotICogVGhlIGluZGl2aWR1YWwgaXRlcmF0b3JzIGFyZSBzdXBwb3NlZCB0byBnZW5lcmF0ZSBub2RlcwotICogaW4gZG9jdW1lbnQgb3JkZXIKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIFVuaW9uSXRlcmF0b3IgZXh0ZW5kcyBNdWx0aVZhbHVlZE5vZGVIZWFwSXRlcmF0b3IgewotICAgIC8qKiB3cmFwcGVyIGZvciBOb2RlSXRlcmF0b3JzIHRvIHN1cHBvcnQgaXRlcmF0b3IKLSAgICAgICAgY29tcGFyaXNvbiBvbiB0aGUgdmFsdWUgb2YgdGhlaXIgbmV4dCgpIG1ldGhvZAotICAgICovCi0gICAgZmluYWwgcHJpdmF0ZSBET00gX2RvbTsKLQotICAgIHByaXZhdGUgZmluYWwgY2xhc3MgTG9va0FoZWFkSXRlcmF0b3IKLSAgICAgICAgICAgIGV4dGVuZHMgTXVsdGlWYWx1ZWROb2RlSGVhcEl0ZXJhdG9yLkhlYXBOb2RlCi0gICAgewotICAgICAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIGl0ZXJhdG9yOwotCi0gICAgICAgIHB1YmxpYyBMb29rQWhlYWRJdGVyYXRvcihEVE1BeGlzSXRlcmF0b3IgaXRlcmF0b3IpIHsKLSAgICAgICAgICAgIHN1cGVyKCk7Ci0gICAgICAgICAgICB0aGlzLml0ZXJhdG9yID0gaXRlcmF0b3I7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgaW50IHN0ZXAoKSB7Ci0gICAgICAgICAgICBfbm9kZSA9IGl0ZXJhdG9yLm5leHQoKTsKLSAgICAgICAgICAgIHJldHVybiBfbm9kZTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyBIZWFwTm9kZSBjbG9uZUhlYXBOb2RlKCkgewotICAgICAgICAgICAgTG9va0FoZWFkSXRlcmF0b3IgY2xvbmUgPSAoTG9va0FoZWFkSXRlcmF0b3IpIHN1cGVyLmNsb25lSGVhcE5vZGUoKTsKLSAgICAgICAgICAgIGNsb25lLml0ZXJhdG9yID0gaXRlcmF0b3IuY2xvbmVJdGVyYXRvcigpOwotICAgICAgICAgICAgcmV0dXJuIGNsb25lOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIHZvaWQgc2V0TWFyaygpIHsKLSAgICAgICAgICAgIHN1cGVyLnNldE1hcmsoKTsKLSAgICAgICAgICAgIGl0ZXJhdG9yLnNldE1hcmsoKTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyB2b2lkIGdvdG9NYXJrKCkgewotICAgICAgICAgICAgc3VwZXIuZ290b01hcmsoKTsKLSAgICAgICAgICAgIGl0ZXJhdG9yLmdvdG9NYXJrKCk7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc0xlc3NUaGFuKEhlYXBOb2RlIGhlYXBOb2RlKSB7Ci0gICAgICAgICAgICBMb29rQWhlYWRJdGVyYXRvciBjb21wYXJhbmQgPSAoTG9va0FoZWFkSXRlcmF0b3IpIGhlYXBOb2RlOwotICAgICAgICAgICAgcmV0dXJuIF9kb20ubGVzc1RoYW4oX25vZGUsIGhlYXBOb2RlLl9ub2RlKTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyBIZWFwTm9kZSBzZXRTdGFydE5vZGUoaW50IG5vZGUpIHsKLSAgICAgICAgICAgIGl0ZXJhdG9yLnNldFN0YXJ0Tm9kZShub2RlKTsKLSAgICAgICAgICAgIHJldHVybiB0aGlzOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIEhlYXBOb2RlIHJlc2V0KCkgewotICAgICAgICAgICAgaXRlcmF0b3IucmVzZXQoKTsKLSAgICAgICAgICAgIHJldHVybiB0aGlzOwotICAgICAgICB9Ci0gICAgfSAvLyBlbmQgb2YgTG9va0FoZWFkSXRlcmF0b3IKLQotICAgIHB1YmxpYyBVbmlvbkl0ZXJhdG9yKERPTSBkb20pIHsKLSAgICAgICAgX2RvbSA9IGRvbTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgVW5pb25JdGVyYXRvciBhZGRJdGVyYXRvcihEVE1BeGlzSXRlcmF0b3IgaXRlcmF0b3IpIHsKLSAgICAgICAgYWRkSGVhcE5vZGUobmV3IExvb2tBaGVhZEl0ZXJhdG9yKGl0ZXJhdG9yKSk7Ci0gICAgICAgIHJldHVybiB0aGlzOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvZG9tL1hTTFRDRFRNTWFuYWdlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vWFNMVENEVE1NYW5hZ2VyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDBjYzZkMDcuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9kb20vWFNMVENEVE1NYW5hZ2VyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0NDggKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogWFNMVENEVE1NYW5hZ2VyLmphdmEsdiAxLjIgMjAwNS8wOC8xNiAyMjozMjo1NCBqZWZmc3V0dG9yIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmRvbTsKLQotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uWE1MRXZlbnRSZWFkZXI7Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5YTUxTdHJlYW1SZWFkZXI7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2U7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5kb20uRE9NU291cmNlOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlNBWFNvdXJjZTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbS5TdHJlYW1Tb3VyY2U7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zdGF4LlN0QVhTb3VyY2U7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE07Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0ucmVmLkRUTURlZmF1bHRCYXNlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTUV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1XU0ZpbHRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5yZWYuRFRNTWFuYWdlckRlZmF1bHQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXMuWE1MRXJyb3JSZXNvdXJjZXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXMuWE1MTWVzc2FnZXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5TeXN0ZW1JRFJlc29sdmVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy50cmF4LkRPTTJTQVg7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnRyYXguU3RBWEV2ZW50MlNBWDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMudHJheC5TdEFYU3RyZWFtMlNBWDsKLQotaW1wb3J0IG9yZy54bWwuc2F4LklucHV0U291cmNlOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LlhNTFJlYWRlcjsKLQotLyoqCi0gKiBUaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBmb3IgdGhlIERUTU1hbmFnZXIuCi0gKi8KLXB1YmxpYyBjbGFzcyBYU0xUQ0RUTU1hbmFnZXIgZXh0ZW5kcyBEVE1NYW5hZ2VyRGVmYXVsdAotewotCi0gICAgLyoqIFNldCB0aGlzIHRvIHRydWUgaWYgeW91IHdhbnQgYSBkdW1wIG9mIHRoZSBEVE0gYWZ0ZXIgY3JlYXRpb24gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIERVTVBUUkVFID0gZmFsc2U7Ci0KLSAgICAvKiogU2V0IHRoaXMgdG8gdHJ1ZSBpZiB5b3Ugd2FudCBiYXNpYyBkaWFnbm9zdGljcyAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW4gREVCVUcgPSBmYWxzZTsKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdG9yIERUTU1hbmFnZXJEZWZhdWx0Ci0gICAgICoKLSAgICAgKi8KLSAgICBwdWJsaWMgWFNMVENEVE1NYW5hZ2VyKCkKLSAgICB7Ci0gICAgICAgIHN1cGVyKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogT2J0YWluIGEgbmV3IGluc3RhbmNlIG9mIGEgPGNvZGU+RFRNTWFuYWdlcjwvY29kZT4uCi0gICAgICogVGhpcyBzdGF0aWMgbWV0aG9kIGNyZWF0ZXMgYSBuZXcgZmFjdG9yeSBpbnN0YW5jZS4KLSAgICAgKiBUaGUgY3VycmVudCBpbXBsZW1lbnRhdGlvbiBqdXN0IHJldHVybnMgYSBuZXcgWFNMVENEVE1NYW5hZ2VyIGluc3RhbmNlLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgWFNMVENEVE1NYW5hZ2VyIG5ld0luc3RhbmNlKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBuZXcgWFNMVENEVE1NYW5hZ2VyKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiB0aGUgWFNMVEMgRFRNIE1hbmFnZXIgc2VydmljZS4KLSAgICAgKiBDcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIHRoZSBkZWZhdWx0IGNsYXNzCi0gICAgICogPGNvZGU+Y29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmRvbS5YU0xUQ0RUTU1hbmFnZXI8L2NvZGU+LgotICAgICAqLwotICAgICAgcHVibGljIHN0YXRpYyBYU0xUQ0RUTU1hbmFnZXIgY3JlYXRlTmV3RFRNTWFuYWdlckluc3RhbmNlKCkgewotICAgICAgICAgcmV0dXJuIG5ld0luc3RhbmNlKCk7Ci0gICAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgYW4gaW5zdGFuY2Ugb2YgYSBEVE0sIGxvYWRlZCB3aXRoIHRoZSBjb250ZW50IGZyb20gdGhlCi0gICAgICogc3BlY2lmaWVkIHNvdXJjZS4gIElmIHRoZSB1bmlxdWUgZmxhZyBpcyB0cnVlLCBhIG5ldyBpbnN0YW5jZSB3aWxsCi0gICAgICogYWx3YXlzIGJlIHJldHVybmVkLiAgT3RoZXJ3aXNlIGl0IGlzIHVwIHRvIHRoZSBEVE1NYW5hZ2VyIHRvIHJldHVybiBhCi0gICAgICogbmV3IGluc3RhbmNlIG9yIGFuIGluc3RhbmNlIHRoYXQgaXQgYWxyZWFkeSBjcmVhdGVkIGFuZCBtYXkgYmUgYmVpbmcgdXNlZAotICAgICAqIGJ5IHNvbWVvbmUgZWxzZS4KLSAgICAgKiAoSSB0aGluayBtb3JlIHBhcmFtZXRlcnMgd2lsbCBuZWVkIHRvIGJlIGFkZGVkIGZvciBlcnJvciBoYW5kbGluZywgYW5kCi0gICAgICogZW50aXR5IHJlc29sdXRpb24pLgotICAgICAqCi0gICAgICogQHBhcmFtIHNvdXJjZSB0aGUgc3BlY2lmaWNhdGlvbiBvZiB0aGUgc291cmNlIG9iamVjdC4KLSAgICAgKiBAcGFyYW0gdW5pcXVlIHRydWUgaWYgdGhlIHJldHVybmVkIERUTSBtdXN0IGJlIHVuaXF1ZSwgcHJvYmFibHkgYmVjYXVzZSBpdAotICAgICAqIGlzIGdvaW5nIHRvIGJlIG11dGF0ZWQuCi0gICAgICogQHBhcmFtIHdoaXRlU3BhY2VGaWx0ZXIgRW5hYmxlcyBmaWx0ZXJpbmcgb2Ygd2hpdGVzcGFjZSBub2RlcywgYW5kIG1heQotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIGJlIG51bGwuCi0gICAgICogQHBhcmFtIGluY3JlbWVudGFsIHRydWUgaWYgdGhlIERUTSBzaG91bGQgYmUgYnVpbHQgaW5jcmVtZW50YWxseSwgaWYKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgcG9zc2libGUuCi0gICAgICogQHBhcmFtIGRvSW5kZXhpbmcgdHJ1ZSBpZiB0aGUgY2FsbGVyIGNvbnNpZGVycyBpdCB3b3J0aCBpdCB0byB1c2UKLSAgICAgKiAgICAgICAgICAgICAgICAgICBpbmRleGluZyBzY2hlbWVzLgotICAgICAqCi0gICAgICogQHJldHVybiBhIG5vbi1udWxsIERUTSByZWZlcmVuY2UuCi0gICAgICovCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIERUTSBnZXREVE0oU291cmNlIHNvdXJjZSwgYm9vbGVhbiB1bmlxdWUsCi0gICAgICAgICAgICAgICAgICAgICAgRFRNV1NGaWx0ZXIgd2hpdGVTcGFjZUZpbHRlciwgYm9vbGVhbiBpbmNyZW1lbnRhbCwKLSAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGRvSW5kZXhpbmcpCi0gICAgewotICAgICAgICByZXR1cm4gZ2V0RFRNKHNvdXJjZSwgdW5pcXVlLCB3aGl0ZVNwYWNlRmlsdGVyLCBpbmNyZW1lbnRhbCwKLSAgICAgICAgICAgICAgICAgICAgICBkb0luZGV4aW5nLCBmYWxzZSwgMCwgdHJ1ZSwgZmFsc2UpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCBhbiBpbnN0YW5jZSBvZiBhIERUTSwgbG9hZGVkIHdpdGggdGhlIGNvbnRlbnQgZnJvbSB0aGUKLSAgICAgKiBzcGVjaWZpZWQgc291cmNlLiAgSWYgdGhlIHVuaXF1ZSBmbGFnIGlzIHRydWUsIGEgbmV3IGluc3RhbmNlIHdpbGwKLSAgICAgKiBhbHdheXMgYmUgcmV0dXJuZWQuICBPdGhlcndpc2UgaXQgaXMgdXAgdG8gdGhlIERUTU1hbmFnZXIgdG8gcmV0dXJuIGEKLSAgICAgKiBuZXcgaW5zdGFuY2Ugb3IgYW4gaW5zdGFuY2UgdGhhdCBpdCBhbHJlYWR5IGNyZWF0ZWQgYW5kIG1heSBiZSBiZWluZyB1c2VkCi0gICAgICogYnkgc29tZW9uZSBlbHNlLgotICAgICAqIChJIHRoaW5rIG1vcmUgcGFyYW1ldGVycyB3aWxsIG5lZWQgdG8gYmUgYWRkZWQgZm9yIGVycm9yIGhhbmRsaW5nLCBhbmQKLSAgICAgKiBlbnRpdHkgcmVzb2x1dGlvbikuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc291cmNlIHRoZSBzcGVjaWZpY2F0aW9uIG9mIHRoZSBzb3VyY2Ugb2JqZWN0LgotICAgICAqIEBwYXJhbSB1bmlxdWUgdHJ1ZSBpZiB0aGUgcmV0dXJuZWQgRFRNIG11c3QgYmUgdW5pcXVlLCBwcm9iYWJseSBiZWNhdXNlIGl0Ci0gICAgICogaXMgZ29pbmcgdG8gYmUgbXV0YXRlZC4KLSAgICAgKiBAcGFyYW0gd2hpdGVTcGFjZUZpbHRlciBFbmFibGVzIGZpbHRlcmluZyBvZiB3aGl0ZXNwYWNlIG5vZGVzLCBhbmQgbWF5Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgYmUgbnVsbC4KLSAgICAgKiBAcGFyYW0gaW5jcmVtZW50YWwgdHJ1ZSBpZiB0aGUgRFRNIHNob3VsZCBiZSBidWlsdCBpbmNyZW1lbnRhbGx5LCBpZgotICAgICAqICAgICAgICAgICAgICAgICAgICBwb3NzaWJsZS4KLSAgICAgKiBAcGFyYW0gZG9JbmRleGluZyB0cnVlIGlmIHRoZSBjYWxsZXIgY29uc2lkZXJzIGl0IHdvcnRoIGl0IHRvIHVzZQotICAgICAqICAgICAgICAgICAgICAgICAgIGluZGV4aW5nIHNjaGVtZXMuCi0gICAgICogQHBhcmFtIGJ1aWxkSWRJbmRleCB0cnVlIGlmIHRoZSBpZCBpbmRleCB0YWJsZSBzaG91bGQgYmUgYnVpbHQuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIGEgbm9uLW51bGwgRFRNIHJlZmVyZW5jZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgRFRNIGdldERUTShTb3VyY2Ugc291cmNlLCBib29sZWFuIHVuaXF1ZSwKLSAgICAgICAgICAgICAgICAgICAgICBEVE1XU0ZpbHRlciB3aGl0ZVNwYWNlRmlsdGVyLCBib29sZWFuIGluY3JlbWVudGFsLAotICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gZG9JbmRleGluZywgYm9vbGVhbiBidWlsZElkSW5kZXgpCi0gICAgewotICAgICAgICByZXR1cm4gZ2V0RFRNKHNvdXJjZSwgdW5pcXVlLCB3aGl0ZVNwYWNlRmlsdGVyLCBpbmNyZW1lbnRhbCwKLSAgICAgICAgICAgICAgICAgICAgICBkb0luZGV4aW5nLCBmYWxzZSwgMCwgYnVpbGRJZEluZGV4LCBmYWxzZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IGFuIGluc3RhbmNlIG9mIGEgRFRNLCBsb2FkZWQgd2l0aCB0aGUgY29udGVudCBmcm9tIHRoZQotICAgICAqIHNwZWNpZmllZCBzb3VyY2UuICBJZiB0aGUgdW5pcXVlIGZsYWcgaXMgdHJ1ZSwgYSBuZXcgaW5zdGFuY2Ugd2lsbAotICAgICAqIGFsd2F5cyBiZSByZXR1cm5lZC4gIE90aGVyd2lzZSBpdCBpcyB1cCB0byB0aGUgRFRNTWFuYWdlciB0byByZXR1cm4gYQotICAgICAqIG5ldyBpbnN0YW5jZSBvciBhbiBpbnN0YW5jZSB0aGF0IGl0IGFscmVhZHkgY3JlYXRlZCBhbmQgbWF5IGJlIGJlaW5nIHVzZWQKLSAgICAgKiBieSBzb21lb25lIGVsc2UuCi0gICAgICogKEkgdGhpbmsgbW9yZSBwYXJhbWV0ZXJzIHdpbGwgbmVlZCB0byBiZSBhZGRlZCBmb3IgZXJyb3IgaGFuZGxpbmcsIGFuZAotICAgICAqIGVudGl0eSByZXNvbHV0aW9uKS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzb3VyY2UgdGhlIHNwZWNpZmljYXRpb24gb2YgdGhlIHNvdXJjZSBvYmplY3QuCi0gICAgICogQHBhcmFtIHVuaXF1ZSB0cnVlIGlmIHRoZSByZXR1cm5lZCBEVE0gbXVzdCBiZSB1bmlxdWUsIHByb2JhYmx5IGJlY2F1c2UgaXQKLSAgICAgKiBpcyBnb2luZyB0byBiZSBtdXRhdGVkLgotICAgICAqIEBwYXJhbSB3aGl0ZVNwYWNlRmlsdGVyIEVuYWJsZXMgZmlsdGVyaW5nIG9mIHdoaXRlc3BhY2Ugbm9kZXMsIGFuZCBtYXkKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBiZSBudWxsLgotICAgICAqIEBwYXJhbSBpbmNyZW1lbnRhbCB0cnVlIGlmIHRoZSBEVE0gc2hvdWxkIGJlIGJ1aWx0IGluY3JlbWVudGFsbHksIGlmCi0gICAgICogICAgICAgICAgICAgICAgICAgIHBvc3NpYmxlLgotICAgICAqIEBwYXJhbSBkb0luZGV4aW5nIHRydWUgaWYgdGhlIGNhbGxlciBjb25zaWRlcnMgaXQgd29ydGggaXQgdG8gdXNlCi0gICAgICogICAgICAgICAgICAgICAgICAgaW5kZXhpbmcgc2NoZW1lcy4KLSAgICAgKiBAcGFyYW0gYnVpbGRJZEluZGV4IHRydWUgaWYgdGhlIGlkIGluZGV4IHRhYmxlIHNob3VsZCBiZSBidWlsdC4KLSAgICAgKiBAcGFyYW0gbmV3TmFtZVRhYmxlIHRydWUgaWYgd2Ugd2FudCB0byB1c2UgYSBzZXBhcmF0ZSBFeHBhbmRlZE5hbWVUYWJsZQotICAgICAqICAgICAgICAgICAgICAgICAgICAgZm9yIHRoaXMgRFRNLgotICAgICAqCi0gICAgICogQHJldHVybiBhIG5vbi1udWxsIERUTSByZWZlcmVuY2UuCi0gICAgICovCi0gIHB1YmxpYyBEVE0gZ2V0RFRNKFNvdXJjZSBzb3VyY2UsIGJvb2xlYW4gdW5pcXVlLAotICAgICAgICAgICAgICAgICAgICBEVE1XU0ZpbHRlciB3aGl0ZVNwYWNlRmlsdGVyLCBib29sZWFuIGluY3JlbWVudGFsLAotICAgICAgICAgICAgICAgICAgICBib29sZWFuIGRvSW5kZXhpbmcsIGJvb2xlYW4gYnVpbGRJZEluZGV4LAotICAgICAgICAgICAgICAgICAgICBib29sZWFuIG5ld05hbWVUYWJsZSkKLSAgewotICAgIHJldHVybiBnZXREVE0oc291cmNlLCB1bmlxdWUsIHdoaXRlU3BhY2VGaWx0ZXIsIGluY3JlbWVudGFsLAotICAgICAgICAgICAgICAgICAgZG9JbmRleGluZywgZmFsc2UsIDAsIGJ1aWxkSWRJbmRleCwgbmV3TmFtZVRhYmxlKTsKLSAgfQotCi0gIC8qKgotICAgICAqIEdldCBhbiBpbnN0YW5jZSBvZiBhIERUTSwgbG9hZGVkIHdpdGggdGhlIGNvbnRlbnQgZnJvbSB0aGUKLSAgICAgKiBzcGVjaWZpZWQgc291cmNlLiAgSWYgdGhlIHVuaXF1ZSBmbGFnIGlzIHRydWUsIGEgbmV3IGluc3RhbmNlIHdpbGwKLSAgICAgKiBhbHdheXMgYmUgcmV0dXJuZWQuICBPdGhlcndpc2UgaXQgaXMgdXAgdG8gdGhlIERUTU1hbmFnZXIgdG8gcmV0dXJuIGEKLSAgICAgKiBuZXcgaW5zdGFuY2Ugb3IgYW4gaW5zdGFuY2UgdGhhdCBpdCBhbHJlYWR5IGNyZWF0ZWQgYW5kIG1heSBiZSBiZWluZyB1c2VkCi0gICAgICogYnkgc29tZW9uZSBlbHNlLgotICAgICAqIChJIHRoaW5rIG1vcmUgcGFyYW1ldGVycyB3aWxsIG5lZWQgdG8gYmUgYWRkZWQgZm9yIGVycm9yIGhhbmRsaW5nLCBhbmQKLSAgICAgKiBlbnRpdHkgcmVzb2x1dGlvbikuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc291cmNlIHRoZSBzcGVjaWZpY2F0aW9uIG9mIHRoZSBzb3VyY2Ugb2JqZWN0LgotICAgICAqIEBwYXJhbSB1bmlxdWUgdHJ1ZSBpZiB0aGUgcmV0dXJuZWQgRFRNIG11c3QgYmUgdW5pcXVlLCBwcm9iYWJseSBiZWNhdXNlIGl0Ci0gICAgICogaXMgZ29pbmcgdG8gYmUgbXV0YXRlZC4KLSAgICAgKiBAcGFyYW0gd2hpdGVTcGFjZUZpbHRlciBFbmFibGVzIGZpbHRlcmluZyBvZiB3aGl0ZXNwYWNlIG5vZGVzLCBhbmQgbWF5Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgYmUgbnVsbC4KLSAgICAgKiBAcGFyYW0gaW5jcmVtZW50YWwgdHJ1ZSBpZiB0aGUgRFRNIHNob3VsZCBiZSBidWlsdCBpbmNyZW1lbnRhbGx5LCBpZgotICAgICAqICAgICAgICAgICAgICAgICAgICBwb3NzaWJsZS4KLSAgICAgKiBAcGFyYW0gZG9JbmRleGluZyB0cnVlIGlmIHRoZSBjYWxsZXIgY29uc2lkZXJzIGl0IHdvcnRoIGl0IHRvIHVzZQotICAgICAqICAgICAgICAgICAgICAgICAgIGluZGV4aW5nIHNjaGVtZXMuCi0gICAgICogQHBhcmFtIGhhc1VzZXJSZWFkZXIgdHJ1ZSBpZiA8Y29kZT5zb3VyY2U8L2NvZGU+IGlzIGEKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICA8Y29kZT5TQVhTb3VyY2U8L2NvZGU+IG9iamVjdCB0aGF0IGhhcyBhbgotICAgICAqICAgICAgICAgICAgICAgICAgICAgIDxjb2RlPlhNTFJlYWRlcjwvY29kZT4sIHRoYXQgd2FzIHNwZWNpZmllZCBieSB0aGUKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICB1c2VyLgotICAgICAqIEBwYXJhbSBzaXplICBTcGVjaWZpZXMgaW5pdGlhbCBzaXplIG9mIHRhYmxlcyB0aGF0IHJlcHJlc2VudCB0aGUgRFRNCi0gICAgICogQHBhcmFtIGJ1aWxkSWRJbmRleCB0cnVlIGlmIHRoZSBpZCBpbmRleCB0YWJsZSBzaG91bGQgYmUgYnVpbHQuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIGEgbm9uLW51bGwgRFRNIHJlZmVyZW5jZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgRFRNIGdldERUTShTb3VyY2Ugc291cmNlLCBib29sZWFuIHVuaXF1ZSwKLSAgICAgICAgICAgICAgICAgICAgICBEVE1XU0ZpbHRlciB3aGl0ZVNwYWNlRmlsdGVyLCBib29sZWFuIGluY3JlbWVudGFsLAotICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gZG9JbmRleGluZywgYm9vbGVhbiBoYXNVc2VyUmVhZGVyLCBpbnQgc2l6ZSwKLSAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGJ1aWxkSWRJbmRleCkKLSAgICB7Ci0gICAgICByZXR1cm4gZ2V0RFRNKHNvdXJjZSwgdW5pcXVlLCB3aGl0ZVNwYWNlRmlsdGVyLCBpbmNyZW1lbnRhbCwKLSAgICAgICAgICAgICAgICAgICAgZG9JbmRleGluZywgaGFzVXNlclJlYWRlciwgc2l6ZSwKLSAgICAgICAgICAgICAgICAgICAgYnVpbGRJZEluZGV4LCBmYWxzZSk7Ci0gIH0KLQotICAvKioKLSAgICAgKiBHZXQgYW4gaW5zdGFuY2Ugb2YgYSBEVE0sIGxvYWRlZCB3aXRoIHRoZSBjb250ZW50IGZyb20gdGhlCi0gICAgICogc3BlY2lmaWVkIHNvdXJjZS4gIElmIHRoZSB1bmlxdWUgZmxhZyBpcyB0cnVlLCBhIG5ldyBpbnN0YW5jZSB3aWxsCi0gICAgICogYWx3YXlzIGJlIHJldHVybmVkLiAgT3RoZXJ3aXNlIGl0IGlzIHVwIHRvIHRoZSBEVE1NYW5hZ2VyIHRvIHJldHVybiBhCi0gICAgICogbmV3IGluc3RhbmNlIG9yIGFuIGluc3RhbmNlIHRoYXQgaXQgYWxyZWFkeSBjcmVhdGVkIGFuZCBtYXkgYmUgYmVpbmcgdXNlZAotICAgICAqIGJ5IHNvbWVvbmUgZWxzZS4KLSAgICAgKiAoSSB0aGluayBtb3JlIHBhcmFtZXRlcnMgd2lsbCBuZWVkIHRvIGJlIGFkZGVkIGZvciBlcnJvciBoYW5kbGluZywgYW5kCi0gICAgICogZW50aXR5IHJlc29sdXRpb24pLgotICAgICAqCi0gICAgICogQHBhcmFtIHNvdXJjZSB0aGUgc3BlY2lmaWNhdGlvbiBvZiB0aGUgc291cmNlIG9iamVjdC4KLSAgICAgKiBAcGFyYW0gdW5pcXVlIHRydWUgaWYgdGhlIHJldHVybmVkIERUTSBtdXN0IGJlIHVuaXF1ZSwgcHJvYmFibHkgYmVjYXVzZSBpdAotICAgICAqIGlzIGdvaW5nIHRvIGJlIG11dGF0ZWQuCi0gICAgICogQHBhcmFtIHdoaXRlU3BhY2VGaWx0ZXIgRW5hYmxlcyBmaWx0ZXJpbmcgb2Ygd2hpdGVzcGFjZSBub2RlcywgYW5kIG1heQotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIGJlIG51bGwuCi0gICAgICogQHBhcmFtIGluY3JlbWVudGFsIHRydWUgaWYgdGhlIERUTSBzaG91bGQgYmUgYnVpbHQgaW5jcmVtZW50YWxseSwgaWYKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgcG9zc2libGUuCi0gICAgICogQHBhcmFtIGRvSW5kZXhpbmcgdHJ1ZSBpZiB0aGUgY2FsbGVyIGNvbnNpZGVycyBpdCB3b3J0aCBpdCB0byB1c2UKLSAgICAgKiAgICAgICAgICAgICAgICAgICBpbmRleGluZyBzY2hlbWVzLgotICAgICAqIEBwYXJhbSBoYXNVc2VyUmVhZGVyIHRydWUgaWYgPGNvZGU+c291cmNlPC9jb2RlPiBpcyBhCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgPGNvZGU+U0FYU291cmNlPC9jb2RlPiBvYmplY3QgdGhhdCBoYXMgYW4KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICA8Y29kZT5YTUxSZWFkZXI8L2NvZGU+LCB0aGF0IHdhcyBzcGVjaWZpZWQgYnkgdGhlCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgdXNlci4KLSAgICAgKiBAcGFyYW0gc2l6ZSAgU3BlY2lmaWVzIGluaXRpYWwgc2l6ZSBvZiB0YWJsZXMgdGhhdCByZXByZXNlbnQgdGhlIERUTQotICAgICAqIEBwYXJhbSBidWlsZElkSW5kZXggdHJ1ZSBpZiB0aGUgaWQgaW5kZXggdGFibGUgc2hvdWxkIGJlIGJ1aWx0LgotICAgICAqIEBwYXJhbSBuZXdOYW1lVGFibGUgdHJ1ZSBpZiB3ZSB3YW50IHRvIHVzZSBhIHNlcGFyYXRlIEV4cGFuZGVkTmFtZVRhYmxlCi0gICAgICogICAgICAgICAgICAgICAgICAgICBmb3IgdGhpcyBEVE0uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIGEgbm9uLW51bGwgRFRNIHJlZmVyZW5jZS4KLSAgICAgKi8KLSAgcHVibGljIERUTSBnZXREVE0oU291cmNlIHNvdXJjZSwgYm9vbGVhbiB1bmlxdWUsCi0gICAgICAgICAgICAgICAgICAgIERUTVdTRmlsdGVyIHdoaXRlU3BhY2VGaWx0ZXIsIGJvb2xlYW4gaW5jcmVtZW50YWwsCi0gICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gZG9JbmRleGluZywgYm9vbGVhbiBoYXNVc2VyUmVhZGVyLCBpbnQgc2l6ZSwKLSAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBidWlsZElkSW5kZXgsIGJvb2xlYW4gbmV3TmFtZVRhYmxlKQotICB7Ci0gICAgICAgIGlmKERFQlVHICYmIG51bGwgIT0gc291cmNlKSB7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlN0YXJ0aW5nICIrCi0gICAgICAgICAgICAgICAgICAgICAgICAgKHVuaXF1ZSA/ICJVTklRVUUiIDogInNoYXJlZCIpKwotICAgICAgICAgICAgICAgICAgICAgICAgICIgc291cmNlOiAiK3NvdXJjZS5nZXRTeXN0ZW1JZCgpKTsKLSAgICAgICAgfQotCi0gICAgICAgIGludCBkdG1Qb3MgPSBnZXRGaXJzdEZyZWVEVE1JRCgpOwotICAgICAgICBpbnQgZG9jdW1lbnRJRCA9IGR0bVBvcyA8PCBJREVOVF9EVE1fTk9ERV9CSVRTOwotCi0gICAgICAgIGlmICgobnVsbCAhPSBzb3VyY2UpICYmIHNvdXJjZSBpbnN0YW5jZW9mIFN0QVhTb3VyY2UpIHsKLSAgICAgICAgICAgIGZpbmFsIFN0QVhTb3VyY2Ugc3RheFNvdXJjZSA9IChTdEFYU291cmNlKXNvdXJjZTsKLSAgICAgICAgICAgIFN0QVhFdmVudDJTQVggc3RheGV2ZW50MnNheCA9IG51bGw7Ci0gICAgICAgICAgICBTdEFYU3RyZWFtMlNBWCBzdGF4U3RyZWFtMlNBWCA9IG51bGw7Ci0gICAgICAgICAgICBpZiAoc3RheFNvdXJjZS5nZXRYTUxFdmVudFJlYWRlcigpICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmaW5hbCBYTUxFdmVudFJlYWRlciB4bWxFdmVudFJlYWRlciA9IHN0YXhTb3VyY2UuZ2V0WE1MRXZlbnRSZWFkZXIoKTsKLSAgICAgICAgICAgICAgICBzdGF4ZXZlbnQyc2F4ID0gbmV3IFN0QVhFdmVudDJTQVgoeG1sRXZlbnRSZWFkZXIpOwotICAgICAgICAgICAgfSBlbHNlIGlmIChzdGF4U291cmNlLmdldFhNTFN0cmVhbVJlYWRlcigpICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmaW5hbCBYTUxTdHJlYW1SZWFkZXIgeG1sU3RyZWFtUmVhZGVyID0gc3RheFNvdXJjZS5nZXRYTUxTdHJlYW1SZWFkZXIoKTsKLSAgICAgICAgICAgICAgICBzdGF4U3RyZWFtMlNBWCA9IG5ldyBTdEFYU3RyZWFtMlNBWCh4bWxTdHJlYW1SZWFkZXIpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBTQVhJbXBsIGR0bTsKLQotICAgICAgICAgICAgaWYgKHNpemUgPD0gMCkgewotICAgICAgICAgICAgICAgIGR0bSA9IG5ldyBTQVhJbXBsKHRoaXMsIHNvdXJjZSwgZG9jdW1lbnRJRCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGl0ZVNwYWNlRmlsdGVyLCBudWxsLCBkb0luZGV4aW5nLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERUTURlZmF1bHRCYXNlLkRFRkFVTFRfQkxPQ0tTSVpFLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1aWxkSWRJbmRleCwgbmV3TmFtZVRhYmxlKTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgZHRtID0gbmV3IFNBWEltcGwodGhpcywgc291cmNlLCBkb2N1bWVudElELAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaXRlU3BhY2VGaWx0ZXIsIG51bGwsIGRvSW5kZXhpbmcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZSwgYnVpbGRJZEluZGV4LCBuZXdOYW1lVGFibGUpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBkdG0uc2V0RG9jdW1lbnRVUkkoc291cmNlLmdldFN5c3RlbUlkKCkpOwotCi0gICAgICAgICAgICBhZGREVE0oZHRtLCBkdG1Qb3MsIDApOwotCi0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIGlmIChzdGF4ZXZlbnQyc2F4ICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgc3RheGV2ZW50MnNheC5zZXRDb250ZW50SGFuZGxlcihkdG0pOwotICAgICAgICAgICAgICAgICAgICBzdGF4ZXZlbnQyc2F4LnBhcnNlKCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgaWYgKHN0YXhTdHJlYW0yU0FYICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgc3RheFN0cmVhbTJTQVguc2V0Q29udGVudEhhbmRsZXIoZHRtKTsKLSAgICAgICAgICAgICAgICAgICAgc3RheFN0cmVhbTJTQVgucGFyc2UoKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIHJlKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgcmU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5XcmFwcGVkUnVudGltZUV4Y2VwdGlvbihlKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgcmV0dXJuIGR0bTsKLSAgICAgICAgfWVsc2UgaWYgKChudWxsICE9IHNvdXJjZSkgJiYgc291cmNlIGluc3RhbmNlb2YgRE9NU291cmNlKSB7Ci0gICAgICAgICAgICBmaW5hbCBET01Tb3VyY2UgZG9tc3JjID0gKERPTVNvdXJjZSkgc291cmNlOwotICAgICAgICAgICAgZmluYWwgb3JnLnczYy5kb20uTm9kZSBub2RlID0gZG9tc3JjLmdldE5vZGUoKTsKLSAgICAgICAgICAgIGZpbmFsIERPTTJTQVggZG9tMnNheCA9IG5ldyBET00yU0FYKG5vZGUpOwotCi0gICAgICAgICAgICBTQVhJbXBsIGR0bTsKLQotICAgICAgICAgICAgaWYgKHNpemUgPD0gMCkgewotICAgICAgICAgICAgICAgIGR0bSA9IG5ldyBTQVhJbXBsKHRoaXMsIHNvdXJjZSwgZG9jdW1lbnRJRCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGl0ZVNwYWNlRmlsdGVyLCBudWxsLCBkb0luZGV4aW5nLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERUTURlZmF1bHRCYXNlLkRFRkFVTFRfQkxPQ0tTSVpFLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1aWxkSWRJbmRleCwgbmV3TmFtZVRhYmxlKTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgZHRtID0gbmV3IFNBWEltcGwodGhpcywgc291cmNlLCBkb2N1bWVudElELAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaXRlU3BhY2VGaWx0ZXIsIG51bGwsIGRvSW5kZXhpbmcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZSwgYnVpbGRJZEluZGV4LCBuZXdOYW1lVGFibGUpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBkdG0uc2V0RG9jdW1lbnRVUkkoc291cmNlLmdldFN5c3RlbUlkKCkpOwotCi0gICAgICAgICAgICBhZGREVE0oZHRtLCBkdG1Qb3MsIDApOwotCi0gICAgICAgICAgICBkb20yc2F4LnNldENvbnRlbnRIYW5kbGVyKGR0bSk7Ci0KLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgZG9tMnNheC5wYXJzZSgpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gcmUpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyByZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLldyYXBwZWRSdW50aW1lRXhjZXB0aW9uKGUpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICByZXR1cm4gZHRtOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotICAgICAgICAgICAgYm9vbGVhbiBpc1NBWFNvdXJjZSA9IChudWxsICE9IHNvdXJjZSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IChzb3VyY2UgaW5zdGFuY2VvZiBTQVhTb3VyY2UpIDogdHJ1ZTsKLSAgICAgICAgICAgIGJvb2xlYW4gaXNTdHJlYW1Tb3VyY2UgPSAobnVsbCAhPSBzb3VyY2UpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyAoc291cmNlIGluc3RhbmNlb2YgU3RyZWFtU291cmNlKSA6IGZhbHNlOwotCi0gICAgICAgICAgICBpZiAoaXNTQVhTb3VyY2UgfHwgaXNTdHJlYW1Tb3VyY2UpIHsKLSAgICAgICAgICAgICAgICBYTUxSZWFkZXIgcmVhZGVyOwotICAgICAgICAgICAgICAgIElucHV0U291cmNlIHhtbFNvdXJjZTsKLQotICAgICAgICAgICAgICAgIGlmIChudWxsID09IHNvdXJjZSkgewotICAgICAgICAgICAgICAgICAgICB4bWxTb3VyY2UgPSBudWxsOwotICAgICAgICAgICAgICAgICAgICByZWFkZXIgPSBudWxsOwotICAgICAgICAgICAgICAgICAgICBoYXNVc2VyUmVhZGVyID0gZmFsc2U7ICAvLyBNYWtlIHN1cmUgdGhlIHVzZXIgZGlkbid0IGxpZQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgcmVhZGVyID0gZ2V0WE1MUmVhZGVyKHNvdXJjZSk7Ci0gICAgICAgICAgICAgICAgICAgIHhtbFNvdXJjZSA9IFNBWFNvdXJjZS5zb3VyY2VUb0lucHV0U291cmNlKHNvdXJjZSk7Ci0KLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHVybE9mU291cmNlID0geG1sU291cmNlLmdldFN5c3RlbUlkKCk7Ci0KLSAgICAgICAgICAgICAgICAgICAgaWYgKG51bGwgIT0gdXJsT2ZTb3VyY2UpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgdXJsT2ZTb3VyY2UgPSBTeXN0ZW1JRFJlc29sdmVyLmdldEFic29sdXRlVVJJKHVybE9mU291cmNlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICVSRVZJRVclIElzIHRoZXJlIGEgYmV0dGVyIHdheSB0byBzZW5kIGEgd2FybmluZz8KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIkNhbiBub3QgYWJzb2x1dGl6ZSBVUkw6ICIgKyB1cmxPZlNvdXJjZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNvdXJjZS5zZXRTeXN0ZW1JZCh1cmxPZlNvdXJjZSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyBDcmVhdGUgdGhlIGJhc2ljIFNBWDJEVE0uCi0gICAgICAgICAgICAgICAgU0FYSW1wbCBkdG07Ci0gICAgICAgICAgICAgICAgaWYgKHNpemUgPD0gMCkgewotICAgICAgICAgICAgICAgICAgICBkdG0gPSBuZXcgU0FYSW1wbCh0aGlzLCBzb3VyY2UsIGRvY3VtZW50SUQsIHdoaXRlU3BhY2VGaWx0ZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsIGRvSW5kZXhpbmcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERUTURlZmF1bHRCYXNlLkRFRkFVTFRfQkxPQ0tTSVpFLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBidWlsZElkSW5kZXgsIG5ld05hbWVUYWJsZSk7Ci0gICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgZHRtID0gbmV3IFNBWEltcGwodGhpcywgc291cmNlLCBkb2N1bWVudElELCB3aGl0ZVNwYWNlRmlsdGVyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsIGRvSW5kZXhpbmcsIHNpemUsIGJ1aWxkSWRJbmRleCwgbmV3TmFtZVRhYmxlKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyBHbyBhaGVhZCBhbmQgYWRkIHRoZSBEVE0gdG8gdGhlIGxvb2t1cCB0YWJsZS4gIFRoaXMgbmVlZHMgdG8gYmUKLSAgICAgICAgICAgICAgICAvLyBkb25lIGJlZm9yZSBhbnkgcGFyc2luZyBvY2N1cnMuIE5vdGUgb2Zmc2V0IDAsIHNpbmNlIHdlJ3ZlIGp1c3QKLSAgICAgICAgICAgICAgICAvLyBjcmVhdGVkIGEgbmV3IERUTS4KLSAgICAgICAgICAgICAgICBhZGREVE0oZHRtLCBkdG1Qb3MsIDApOwotCi0gICAgICAgICAgICAgICAgaWYgKG51bGwgPT0gcmVhZGVyKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIFRoZW4gdGhlIHVzZXIgd2lsbCBjb25zdHJ1Y3QgaXQgdGhlbXNlbHZlcy4KLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGR0bTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICByZWFkZXIuc2V0Q29udGVudEhhbmRsZXIoZHRtLmdldEJ1aWxkZXIoKSk7Ci0KLSAgICAgICAgICAgICAgICBpZiAoIWhhc1VzZXJSZWFkZXIgfHwgbnVsbCA9PSByZWFkZXIuZ2V0RFRESGFuZGxlcigpKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJlYWRlci5zZXREVERIYW5kbGVyKGR0bSk7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgaWYoIWhhc1VzZXJSZWFkZXIgfHwgbnVsbCA9PSByZWFkZXIuZ2V0RXJyb3JIYW5kbGVyKCkpIHsKLSAgICAgICAgICAgICAgICAgICAgcmVhZGVyLnNldEVycm9ySGFuZGxlcihkdG0pOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgIHJlYWRlci5zZXRQcm9wZXJ0eSgiaHR0cDovL3htbC5vcmcvc2F4L3Byb3BlcnRpZXMvbGV4aWNhbC1oYW5kbGVyIiwgZHRtKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgY2F0Y2ggKFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24gZSl7fQotICAgICAgICAgICAgICAgIGNhdGNoIChTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gZSl7fQotCi0gICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgcmVhZGVyLnBhcnNlKHhtbFNvdXJjZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIHJlKSB7Ci0gICAgICAgICAgICAgICAgICAgIHRocm93IHJlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuV3JhcHBlZFJ1bnRpbWVFeGNlcHRpb24oZSk7Ci0gICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKCFoYXNVc2VyUmVhZGVyKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZWxlYXNlWE1MUmVhZGVyKHJlYWRlcik7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBpZiAoRFVNUFRSRUUpIHsKLSAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJEdW1waW5nIFNBWDJET00iKTsKLSAgICAgICAgICAgICAgICAgICAgZHRtLmR1bXBEVE0oU3lzdGVtLmVycik7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgcmV0dXJuIGR0bTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIC8vIEl0IHNob3VsZCBoYXZlIGJlZW4gaGFuZGxlZCBieSBhIGRlcml2ZWQgY2xhc3Mgb3IgdGhlIGNhbGxlcgotICAgICAgICAgICAgICAgIC8vIG1hZGUgYSBtaXN0YWtlLgotICAgICAgICAgICAgICAgIHRocm93IG5ldyBEVE1FeGNlcHRpb24oWE1MTWVzc2FnZXMuY3JlYXRlWE1MTWVzc2FnZShYTUxFcnJvclJlc291cmNlcy5FUl9OT1RfU1VQUE9SVEVELCBuZXcgT2JqZWN0W117c291cmNlfSkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9qYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRmFjdG9yeSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckZhY3RvcnkKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGE2MDc4OTEuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9qYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRmFjdG9yeQorKysgL2Rldi9udWxsCkBAIC0xICswLDAgQEAKLWNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy50cmF4LlRyYW5zZm9ybWVyRmFjdG9yeUltcGwKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0LmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvQWJzdHJhY3RUcmFuc2xldC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmZDhlNTIxLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3OTggKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAxNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqLwotLyoKLSAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQotICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCi0gKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCi0gKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAotICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKLSAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotLyoKLSAqICRJZDogQWJzdHJhY3RUcmFuc2xldC5qYXZhLHYgMS42IDIwMDYvMDYvMTkgMTk6NDk6MDMgc3BlcmljYXMgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5ydW50aW1lOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLlhhbGFuQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC51dGlscy5GYWN0b3J5SW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuRE9NOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5ET01DYWNoZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuRE9NRW5oYW5jZWRGb3JEVE07Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLlRyYW5zbGV0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5UcmFuc2xldEV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuZG9tLkRPTUFkYXB0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmRvbS5LZXlJbmRleDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMucnVudGltZS5vdXRwdXQuVHJhbnNsZXRPdXRwdXRIYW5kbGVyRmFjdG9yeTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE07Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNQXhpc0l0ZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplci5TZXJpYWxpemF0aW9uSGFuZGxlcjsKLWltcG9ydCBqYXZhLmlvLkJ1ZmZlcmVkT3V0cHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uRmlsZTsKLWltcG9ydCBqYXZhLmlvLkZpbGVPdXRwdXRTdHJlYW07Ci1pbXBvcnQgamF2YS50ZXh0LkRlY2ltYWxGb3JtYXQ7Ci1pbXBvcnQgamF2YS50ZXh0LkRlY2ltYWxGb3JtYXRTeW1ib2xzOwotaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7Ci1pbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7Ci1pbXBvcnQgamF2YS51dGlsLk1hcDsKLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlckZhY3Rvcnk7Ci1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRlbXBsYXRlczsKLWltcG9ydCBvcmcudzNjLmRvbS5ET01JbXBsZW1lbnRhdGlvbjsKLWltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKLQotLyoqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqIEBhdXRob3IgRy4gVG9kZCBNaWxsZXIKLSAqIEBhdXRob3IgSm9obiBIb3dhcmQsIEpvaG5IQHNjaGVtYXNvZnQuY29tCi0gKi8KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBBYnN0cmFjdFRyYW5zbGV0IGltcGxlbWVudHMgVHJhbnNsZXQgewotCi0gICAgLy8gVGhlc2UgYXR0cmlidXRlcyBhcmUgZXh0cmFjdGVkIGZyb20gdGhlIHhzbDpvdXRwdXQgZWxlbWVudC4gVGhleSBhbHNvCi0gICAgLy8gYXBwZWFyIGFzIGZpZWxkcyAod2l0aCB0aGUgc2FtZSB0eXBlLCBvbmx5IHB1YmxpYykgaW4gT3V0cHV0LmphdmEKLSAgICBwdWJsaWMgU3RyaW5nICBfdmVyc2lvbiA9ICIxLjAiOwotICAgIHB1YmxpYyBTdHJpbmcgIF9tZXRob2QgPSBudWxsOwotICAgIHB1YmxpYyBTdHJpbmcgIF9lbmNvZGluZyA9ICJVVEYtOCI7Ci0gICAgcHVibGljIGJvb2xlYW4gX29taXRIZWFkZXIgPSBmYWxzZTsKLSAgICBwdWJsaWMgU3RyaW5nICBfc3RhbmRhbG9uZSA9IG51bGw7Ci0gICAgLy9zZWUgT3V0cHV0UHJvcGVydGllc0ZhY3RvcnkuT1JBQ0xFX0lTX1NUQU5EQUxPTkUKLSAgICBwdWJsaWMgYm9vbGVhbiAgX2lzU3RhbmRhbG9uZSA9IGZhbHNlOwotICAgIHB1YmxpYyBTdHJpbmcgIF9kb2N0eXBlUHVibGljID0gbnVsbDsKLSAgICBwdWJsaWMgU3RyaW5nICBfZG9jdHlwZVN5c3RlbSA9IG51bGw7Ci0gICAgcHVibGljIGJvb2xlYW4gX2luZGVudCA9IGZhbHNlOwotICAgIHB1YmxpYyBTdHJpbmcgIF9tZWRpYVR5cGUgPSBudWxsOwotICAgIHB1YmxpYyBWZWN0b3IgX2NkYXRhID0gbnVsbDsKLSAgICBwdWJsaWMgaW50IF9pbmRlbnRhbW91bnQgPSAtMTsKLQotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJUlNUX1RSQU5TTEVUX1ZFUlNJT04gPSAxMDA7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVkVSX1NQTElUX05BTUVTX0FSUkFZID0gMTAxOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENVUlJFTlRfVFJBTlNMRVRfVkVSU0lPTiA9IFZFUl9TUExJVF9OQU1FU19BUlJBWTsKLQotICAgIC8vIEluaXRpYWxpemUgVHJhbnNsZXQgdmVyc2lvbiBmaWVsZCB0byBiYXNlIHZhbHVlLiAgQSBjbGFzcyB0aGF0IGV4dGVuZHMKLSAgICAvLyBBYnN0cmFjdFRyYW5zbGV0IG1heSBvdmVycmlkZSB0aGlzIHZhbHVlIHRvIGEgbW9yZSByZWNlbnQgdHJhbnNsZXQKLSAgICAvLyB2ZXJzaW9uOyBpZiBpdCBkb2Vzbid0IG92ZXJyaWRlIHRoZSB2YWx1ZSAoYmVjYXVzZSBpdCB3YXMgY29tcGlsZWQKLSAgICAvLyBiZWZvcmUgdGhlIG5vdGlvbiBvZiBhIHRyYW5zbGV0IHZlcnNpb24gd2FzIGludHJvZHVjZWQsIGl0IHdpbGwgZ2V0Ci0gICAgLy8gdGhpcyBkZWZhdWx0IHZhbHVlKS4KLSAgICBwcm90ZWN0ZWQgaW50IHRyYW5zbGV0VmVyc2lvbiA9IEZJUlNUX1RSQU5TTEVUX1ZFUlNJT047Ci0KLSAgICAvLyBET00vdHJhbnNsZXQgaGFuZHNoYWtpbmcgLSB0aGUgYXJyYXlzIGFyZSBzZXQgYnkgdGhlIGNvbXBpbGVkIHRyYW5zbGV0Ci0gICAgcHJvdGVjdGVkIFN0cmluZ1tdIG5hbWVzQXJyYXk7Ci0gICAgcHJvdGVjdGVkIFN0cmluZ1tdIHVyaXNBcnJheTsKLSAgICBwcm90ZWN0ZWQgaW50W10gICAgdHlwZXNBcnJheTsKLSAgICBwcm90ZWN0ZWQgU3RyaW5nW10gbmFtZXNwYWNlQXJyYXk7Ci0KLSAgICAvLyBUaGUgVGVtcGxhdGVzIG9iamVjdCB0aGF0IGlzIHVzZWQgdG8gY3JlYXRlIHRoaXMgVHJhbnNsZXQgaW5zdGFuY2UKLSAgICBwcm90ZWN0ZWQgVGVtcGxhdGVzIF90ZW1wbGF0ZXMgPSBudWxsOwotCi0gICAgLy8gQm9vbGVhbiBmbGFnIHRvIGluZGljYXRlIHdoZXRoZXIgdGhpcyB0cmFuc2xldCBoYXMgaWQgZnVuY3Rpb25zLgotICAgIHByb3RlY3RlZCBib29sZWFuIF9oYXNJZENhbGwgPSBmYWxzZTsKLQotICAgIC8vIFRPRE8gLSB0aGVzZSBzaG91bGQgb25seSBiZSBpbnN0YW5jaWF0ZWQgd2hlbiBuZWVkZWQKLSAgICBwcm90ZWN0ZWQgU3RyaW5nVmFsdWVIYW5kbGVyIHN0cmluZ1ZhbHVlSGFuZGxlciA9IG5ldyBTdHJpbmdWYWx1ZUhhbmRsZXIoKTsKLQotICAgIC8vIFVzZSBvbmUgZW1wdHkgc3RyaW5nIGluc3RlYWQgb2YgY29uc3RhbnRseSBpbnN0YW5jaWF0aW5nIFN0cmluZygiIik7Ci0gICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgU3RyaW5nIEVNUFRZU1RSSU5HID0gIiI7Ci0KLSAgICAvLyBUaGlzIGlzIHRoZSBuYW1lIG9mIHRoZSBpbmRleCB1c2VkIGZvciBJRCBhdHRyaWJ1dGVzCi0gICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgU3RyaW5nIElEX0lOREVYX05BTUUgPSAiIyNpZCI7Ci0KLSAgICBwcml2YXRlIGJvb2xlYW4gX3VzZVNlcnZpY2VzTWVjaGFuaXNtOwotCi0gICAgLyoqCi0gICAgICogcHJvdG9jb2xzIGFsbG93ZWQgZm9yIGV4dGVybmFsIHJlZmVyZW5jZXMgc2V0IGJ5IHRoZSBzdHlsZXNoZWV0IHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24sIERvY3VtZW50KCkgZnVuY3Rpb24sIEltcG9ydCBhbmQgSW5jbHVkZSBlbGVtZW50LgotICAgICAqLwotICAgIHByaXZhdGUgU3RyaW5nIF9hY2Nlc3NFeHRlcm5hbFN0eWxlc2hlZXQgPSBYYWxhbkNvbnN0YW50cy5FWFRFUk5BTF9BQ0NFU1NfREVGQVVMVDsKLQotICAgIC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLSAgICAgKiBEZWJ1Z2dpbmcKLSAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwotICAgIHB1YmxpYyB2b2lkIHByaW50SW50ZXJuYWxTdGF0ZSgpIHsKLSAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCItLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIik7Ci0gICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiQWJzdHJhY3RUcmFuc2xldCB0aGlzID0gIiArIHRoaXMpOwotICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oInBiYXNlID0gIiArIHBiYXNlKTsKLSAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJ2ZnJhbWUgPSAiICsgcGZyYW1lKTsKLSAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJwYXJhbXNTdGFjay5zaXplKCkgPSAiICsgcGFyYW1zU3RhY2suc2l6ZSgpKTsKLSAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJuYW1lc0FycmF5LnNpemUgPSAiICsgbmFtZXNBcnJheS5sZW5ndGgpOwotICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIm5hbWVzcGFjZUFycmF5LnNpemUgPSAiICsgbmFtZXNwYWNlQXJyYXkubGVuZ3RoKTsKLSAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCIiKTsKLSAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJUb3RhbCBtZW1vcnkgPSAiICsgUnVudGltZS5nZXRSdW50aW1lKCkudG90YWxNZW1vcnkoKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogV3JhcCB0aGUgaW5pdGlhbCBpbnB1dCBET00gaW4gYSBkb20gYWRhcHRlci4gVGhpcyBhZGFwdGVyIGlzIHdyYXBwZWQgaW4KLSAgICAgKiBhIERPTSBtdWx0aXBsZXhlciBpZiB0aGUgZG9jdW1lbnQoKSBmdW5jdGlvbiBpcyB1c2VkIChoYW5kbGVkIGJ5IGNvbXBpbGVkCi0gICAgICogY29kZSBpbiB0aGUgdHJhbnNsZXQgLSBzZWUgY29tcGlsZXIvU3R5bGVzaGVldC5jb21waWxlVHJhbnNmb3JtKCkpLgotICAgICAqLwotICAgIHB1YmxpYyBmaW5hbCBET01BZGFwdGVyIG1ha2VET01BZGFwdGVyKERPTSBkb20pCi0gICAgICAgIHRocm93cyBUcmFuc2xldEV4Y2VwdGlvbiB7Ci0gICAgICAgIHNldFJvb3RGb3JLZXlzKGRvbS5nZXREb2N1bWVudCgpKTsKLSAgICAgICAgcmV0dXJuIG5ldyBET01BZGFwdGVyKGRvbSwgbmFtZXNBcnJheSwgdXJpc0FycmF5LCB0eXBlc0FycmF5LCBuYW1lc3BhY2VBcnJheSk7Ci0gICAgfQotCi0gICAgLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgotICAgICAqIFBhcmFtZXRlciBoYW5kbGluZwotICAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi0KLSAgICAvLyBQYXJhbWV0ZXIncyBzdGFjazogPHR0PnBiYXNlPC90dD4gYW5kIDx0dD5wZnJhbWU8L3R0PiBhcmUgdXNlZAotICAgIC8vIHRvIGRlbm90ZSB0aGUgY3VycmVudCBwYXJhbWV0ZXIgZnJhbWUuCi0gICAgcHJvdGVjdGVkIGludCBwYmFzZSA9IDAsIHBmcmFtZSA9IDA7Ci0gICAgcHJvdGVjdGVkIEFycmF5TGlzdCBwYXJhbXNTdGFjayA9IG5ldyBBcnJheUxpc3QoKTsKLQotICAgIC8qKgotICAgICAqIFB1c2ggYSBuZXcgcGFyYW1ldGVyIGZyYW1lLgotICAgICAqLwotICAgIHB1YmxpYyBmaW5hbCB2b2lkIHB1c2hQYXJhbUZyYW1lKCkgewotICAgICAgICBwYXJhbXNTdGFjay5hZGQocGZyYW1lLCBuZXcgSW50ZWdlcihwYmFzZSkpOwotICAgICAgICBwYmFzZSA9ICsrcGZyYW1lOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFBvcCB0aGUgdG9wbW9zdCBwYXJhbWV0ZXIgZnJhbWUuCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIHZvaWQgcG9wUGFyYW1GcmFtZSgpIHsKLSAgICAgICAgaWYgKHBiYXNlID4gMCkgewotICAgICAgICAgICAgZmluYWwgaW50IG9sZHBiYXNlID0gKChJbnRlZ2VyKXBhcmFtc1N0YWNrLmdldCgtLXBiYXNlKSkuaW50VmFsdWUoKTsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSBwZnJhbWUgLSAxOyBpID49IHBiYXNlOyBpLS0pIHsKLSAgICAgICAgICAgICAgICBwYXJhbXNTdGFjay5yZW1vdmUoaSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBwZnJhbWUgPSBwYmFzZTsgcGJhc2UgPSBvbGRwYmFzZTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEFkZCBhIG5ldyBnbG9iYWwgcGFyYW1ldGVyIGlmIG5vdCBhbHJlYWR5IGluIHRoZSBjdXJyZW50IGZyYW1lLgotICAgICAqIFRvIHNldFBhcmFtZXRlcnMgb2YgdGhlIGZvcm0ge2h0dHA6Ly9mb28uYmFyfXh5egotICAgICAqIFRoaXMgbmVlZHMgdG8gZ2V0IG1hcHBlZCB0byBhbiBpbnN0YW5jZSB2YXJpYWJsZSBpbiB0aGUgY2xhc3MKLSAgICAgKiBUaGUgbWFwcGluZyAgY3JlYXRlZCBzbyB0aGF0Ci0gICAgICogdGhlIGdsb2JhbCB2YXJpYWJsZXMgaW4gdGhlIGdlbmVyYXRlZCBjbGFzcyBiZWNvbWUKLSAgICAgKiBodHRwJGNvbG9uJCRmbGFzaCQkZmxhc2gkZm9vJGRvdCRiYXIkY29sb24keHl6Ci0gICAgICovCi0gICAgcHVibGljIGZpbmFsIE9iamVjdCBhZGRQYXJhbWV0ZXIoU3RyaW5nIG5hbWUsIE9iamVjdCB2YWx1ZSkgewotICAgICAgICBuYW1lID0gQmFzaXNMaWJyYXJ5Lm1hcFFOYW1lVG9KYXZhTmFtZSAobmFtZSk7Ci0gICAgICAgIHJldHVybiBhZGRQYXJhbWV0ZXIobmFtZSwgdmFsdWUsIGZhbHNlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBZGQgYSBuZXcgZ2xvYmFsIG9yIGxvY2FsIHBhcmFtZXRlciBpZiBub3QgYWxyZWFkeSBpbiB0aGUgY3VycmVudCBmcmFtZS4KLSAgICAgKiBUaGUgJ2lzRGVmYXVsdCcgcGFyYW1ldGVyIGlzIHNldCB0byB0cnVlIGlmIHRoZSB2YWx1ZSBwYXNzZWQgaXMgdGhlCi0gICAgICogZGVmYXVsdCB2YWx1ZSBmcm9tIHRoZSA8eHNsOnBhcmFtZXRlcj4gZWxlbWVudCdzIHNlbGVjdCBhdHRyaWJ1dGUgb3IKLSAgICAgKiBlbGVtZW50IGJvZHkuCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIE9iamVjdCBhZGRQYXJhbWV0ZXIoU3RyaW5nIG5hbWUsIE9iamVjdCB2YWx1ZSwKLSAgICAgICAgYm9vbGVhbiBpc0RlZmF1bHQpCi0gICAgewotICAgICAgICAvLyBMb2NhbCBwYXJhbWV0ZXJzIG5lZWQgdG8gYmUgcmUtZXZhbHVhdGVkIGZvciBlYWNoIGl0ZXJhdGlvbgotICAgICAgICBmb3IgKGludCBpID0gcGZyYW1lIC0gMTsgaSA+PSBwYmFzZTsgaS0tKSB7Ci0gICAgICAgICAgICBmaW5hbCBQYXJhbWV0ZXIgcGFyYW0gPSAoUGFyYW1ldGVyKSBwYXJhbXNTdGFjay5nZXQoaSk7Ci0KLSAgICAgICAgICAgIGlmIChwYXJhbS5fbmFtZS5lcXVhbHMobmFtZSkpIHsKLSAgICAgICAgICAgICAgICAvLyBPbmx5IG92ZXJ3cml0ZSBpZiBjdXJyZW50IHZhbHVlIGlzIHRoZSBkZWZhdWx0IHZhbHVlIGFuZAotICAgICAgICAgICAgICAgIC8vIHRoZSBuZXcgdmFsdWUgaXMgX05PVF8gdGhlIGRlZmF1bHQgdmFsdWUuCi0gICAgICAgICAgICAgICAgaWYgKHBhcmFtLl9pc0RlZmF1bHQgfHwgIWlzRGVmYXVsdCkgewotICAgICAgICAgICAgICAgICAgICBwYXJhbS5fdmFsdWUgPSB2YWx1ZTsKLSAgICAgICAgICAgICAgICAgICAgcGFyYW0uX2lzRGVmYXVsdCA9IGlzRGVmYXVsdDsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICByZXR1cm4gcGFyYW0uX3ZhbHVlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gQWRkIG5ldyBwYXJhbWV0ZXIgdG8gcGFyYW1ldGVyIHN0YWNrCi0gICAgICAgIHBhcmFtc1N0YWNrLmFkZChwZnJhbWUrKywgbmV3IFBhcmFtZXRlcihuYW1lLCB2YWx1ZSwgaXNEZWZhdWx0KSk7Ci0gICAgICAgIHJldHVybiB2YWx1ZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDbGVhcnMgdGhlIHBhcmFtZXRlciBzdGFjay4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBjbGVhclBhcmFtZXRlcnMoKSB7Ci0gICAgICAgIHBiYXNlID0gcGZyYW1lID0gMDsKLSAgICAgICAgcGFyYW1zU3RhY2suY2xlYXIoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIHZhbHVlIG9mIGEgcGFyYW1ldGVyIGZyb20gdGhlIGN1cnJlbnQgZnJhbWUgb3IKLSAgICAgKiA8dHQ+bnVsbDwvdHQ+IGlmIHVuZGVmaW5lZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgZmluYWwgT2JqZWN0IGdldFBhcmFtZXRlcihTdHJpbmcgbmFtZSkgewotCi0gICAgICAgIG5hbWUgPSBCYXNpc0xpYnJhcnkubWFwUU5hbWVUb0phdmFOYW1lIChuYW1lKTsKLQotICAgICAgICBmb3IgKGludCBpID0gcGZyYW1lIC0gMTsgaSA+PSBwYmFzZTsgaS0tKSB7Ci0gICAgICAgICAgICBmaW5hbCBQYXJhbWV0ZXIgcGFyYW0gPSAoUGFyYW1ldGVyKXBhcmFtc1N0YWNrLmdldChpKTsKLSAgICAgICAgICAgIGlmIChwYXJhbS5fbmFtZS5lcXVhbHMobmFtZSkpIHJldHVybiBwYXJhbS5fdmFsdWU7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgotICAgICAqIE1lc3NhZ2UgaGFuZGxpbmcgLSBpbXBsZW1lbnRhdGlvbiBvZiA8eHNsOm1lc3NhZ2U+Ci0gICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLQotICAgIC8vIEhvbGRzIHRoZSB0cmFuc2xldCdzIG1lc3NhZ2UgaGFuZGxlciAtIHVzZWQgZm9yIDx4c2w6bWVzc2FnZT4uCi0gICAgLy8gVGhlIGRlYXVsdCBtZXNzYWdlIGhhbmRsZXIgZHVtcHMgYSBzdHJpbmcgc3Rkb3V0LCBidXQgYW55dGhpbmcgY2FuIGJlCi0gICAgLy8gdXNlZCwgc3VjaCBhcyBhIGRpYWxvZyBib3ggZm9yIGFwcGxldHMsIGV0Yy4KLSAgICBwcml2YXRlIE1lc3NhZ2VIYW5kbGVyIF9tc2dIYW5kbGVyID0gbnVsbDsKLQotICAgIC8qKgotICAgICAqIFNldCB0aGUgdHJhbnNsZXQncyBtZXNzYWdlIGhhbmRsZXIgLSBtdXN0IGltcGxlbWVudCBNZXNzYWdlSGFuZGxlcgotICAgICAqLwotICAgIHB1YmxpYyBmaW5hbCB2b2lkIHNldE1lc3NhZ2VIYW5kbGVyKE1lc3NhZ2VIYW5kbGVyIGhhbmRsZXIpIHsKLSAgICAgICAgX21zZ0hhbmRsZXIgPSBoYW5kbGVyOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFBhc3MgYSBtZXNzYWdlIHRvIHRoZSBtZXNzYWdlIGhhbmRsZXIgLSB1c2VkIGJ5IE1lc3NhZ2UgY2xhc3MuCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIHZvaWQgZGlzcGxheU1lc3NhZ2UoU3RyaW5nIG1zZykgewotICAgICAgICBpZiAoX21zZ0hhbmRsZXIgPT0gbnVsbCkgewotICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKG1zZyk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBfbXNnSGFuZGxlci5kaXNwbGF5TWVzc2FnZShtc2cpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgotICAgICAqIERlY2ltYWwgbnVtYmVyIGZvcm1hdCBzeW1ib2wgaGFuZGxpbmcKLSAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwotCi0gICAgLy8gQ29udGFpbnMgZGVjaW1hbCBudW1iZXIgZm9ybWF0dGluZyBzeW1ib2xzIHVzZWQgYnkgRm9ybWF0TnVtYmVyQ2FsbAotICAgIHB1YmxpYyBNYXA8U3RyaW5nLCBEZWNpbWFsRm9ybWF0PiBfZm9ybWF0U3ltYm9scyA9IG51bGw7Ci0KLSAgICAvKioKLSAgICAgKiBBZGRzIGEgRGVjaW1hbEZvcm1hdCBvYmplY3QgdG8gdGhlIF9mb3JtYXRTeW1ib2xzIG1hcC4KLSAgICAgKiBUaGUgZW50cnkgaXMgY3JlYXRlZCB3aXRoIHRoZSBpbnB1dCBEZWNpbWFsRm9ybWF0U3ltYm9scy4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBhZGREZWNpbWFsRm9ybWF0KFN0cmluZyBuYW1lLCBEZWNpbWFsRm9ybWF0U3ltYm9scyBzeW1ib2xzKSB7Ci0gICAgICAgIC8vIEluc3RhbmNpYXRlIG1hcCBmb3IgZm9ybWF0dGluZyBzeW1ib2xzIGlmIG5lZWRlZAotICAgICAgICBpZiAoX2Zvcm1hdFN5bWJvbHMgPT0gbnVsbCkgX2Zvcm1hdFN5bWJvbHMgPSBuZXcgSGFzaE1hcDw+KCk7Ci0KLSAgICAgICAgLy8gVGhlIG5hbWUgY2Fubm90IGJlIG51bGwgLSB1c2UgZW1wdHkgc3RyaW5nIGluc3RlYWQKLSAgICAgICAgaWYgKG5hbWUgPT0gbnVsbCkgbmFtZSA9IEVNUFRZU1RSSU5HOwotCi0gICAgICAgIC8vIENvbnN0cnVjdCBhIERlY2ltYWxGb3JtYXQgb2JqZWN0IGNvbnRhaW5pbmcgdGhlIHN5bWJvbHMgd2UgZ290Ci0gICAgICAgIGZpbmFsIERlY2ltYWxGb3JtYXQgZGYgPSBuZXcgRGVjaW1hbEZvcm1hdCgpOwotICAgICAgICBpZiAoc3ltYm9scyAhPSBudWxsKSB7Ci0gICAgICAgICAgICBkZi5zZXREZWNpbWFsRm9ybWF0U3ltYm9scyhzeW1ib2xzKTsKLSAgICAgICAgfQotICAgICAgICBfZm9ybWF0U3ltYm9scy5wdXQobmFtZSwgZGYpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHJpZXZlcyBhIG5hbWVkIERlY2ltYWxGb3JtYXQgb2JqZWN0IGZyb20gdGhlIF9mb3JtYXRTeW1ib2xzIG1hcC4KLSAgICAgKi8KLSAgICBwdWJsaWMgZmluYWwgRGVjaW1hbEZvcm1hdCBnZXREZWNpbWFsRm9ybWF0KFN0cmluZyBuYW1lKSB7Ci0KLSAgICAgICAgaWYgKF9mb3JtYXRTeW1ib2xzICE9IG51bGwpIHsKLSAgICAgICAgICAgIC8vIFRoZSBuYW1lIGNhbm5vdCBiZSBudWxsIC0gdXNlIGVtcHR5IHN0cmluZyBpbnN0ZWFkCi0gICAgICAgICAgICBpZiAobmFtZSA9PSBudWxsKSBuYW1lID0gRU1QVFlTVFJJTkc7Ci0KLSAgICAgICAgICAgIERlY2ltYWxGb3JtYXQgZGYgPSBfZm9ybWF0U3ltYm9scy5nZXQobmFtZSk7Ci0gICAgICAgICAgICBpZiAoZGYgPT0gbnVsbCkgZGYgPSBfZm9ybWF0U3ltYm9scy5nZXQoRU1QVFlTVFJJTkcpOwotICAgICAgICAgICAgcmV0dXJuIGRmOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybihudWxsKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHaXZlIHRoZSB0cmFuc2xldCBhbiBvcHBvcnR1bml0eSB0byBwZXJmb3JtIGEgcHJlcGFzcyBvbiB0aGUgZG9jdW1lbnQKLSAgICAgKiB0byBleHRyYWN0IGFueSBpbmZvcm1hdGlvbiB0aGF0IGl0IGNhbiBzdG9yZSBpbiBhbiBvcHRpbWl6ZWQgZm9ybS4KLSAgICAgKgotICAgICAqIEN1cnJlbnRseSwgaXQgb25seSBleHRyYWN0cyBpbmZvcm1hdGlvbiBhYm91dCBhdHRyaWJ1dGVzIG9mIHR5cGUgSUQuCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIHZvaWQgcHJlcGFzc0RvY3VtZW50KERPTSBkb2N1bWVudCkgewotICAgICAgICBzZXRJbmRleFNpemUoZG9jdW1lbnQuZ2V0U2l6ZSgpKTsKLSAgICAgICAgYnVpbGRJREluZGV4KGRvY3VtZW50KTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBMZXZlcmFnZXMgdGhlIEtleSBDbGFzcyB0byBpbXBsZW1lbnQgdGhlIFhTTFQgaWQoKSBmdW5jdGlvbi4KLSAgICAgKiBidWlsZElkSW5kZXggY3JlYXRlcyB0aGUgaW5kZXggKCMjaWQpIHRoYXQgS2V5IENsYXNzIHVzZXMuCi0gICAgICogVGhlIGluZGV4IGNvbnRhaW5zIHRoZSBlbGVtZW50IG5vZGUgaW5kZXggKGludCkgYW5kIElkIHZhbHVlIChTdHJpbmcpLgotICAgICAqLwotICAgIHByaXZhdGUgZmluYWwgdm9pZCBidWlsZElESW5kZXgoRE9NIGRvY3VtZW50KSB7Ci0gICAgICAgIHNldFJvb3RGb3JLZXlzKGRvY3VtZW50LmdldERvY3VtZW50KCkpOwotCi0gICAgICAgIGlmIChkb2N1bWVudCBpbnN0YW5jZW9mIERPTUVuaGFuY2VkRm9yRFRNKSB7Ci0gICAgICAgICAgICBET01FbmhhbmNlZEZvckRUTSBlbmhhbmNlZERPTSA9IChET01FbmhhbmNlZEZvckRUTSlkb2N1bWVudDsKLQotICAgICAgICAgICAgLy8gSWYgdGhlIGlucHV0IHNvdXJjZSBpcyBET01Tb3VyY2UsIHRoZSBLZXlJbmRleCB0YWJsZSBpcyBub3QKLSAgICAgICAgICAgIC8vIGJ1aWx0IGF0IHRoaXMgdGltZS4gSXQgd2lsbCBiZSBidWlsdCBsYXRlciBieSB0aGUgbG9va3VwSWQoKQotICAgICAgICAgICAgLy8gYW5kIGNvbnRhaW5zSWQoKSBtZXRob2RzIG9mIHRoZSBLZXlJbmRleCBjbGFzcy4KLSAgICAgICAgICAgIGlmIChlbmhhbmNlZERPTS5oYXNET01Tb3VyY2UoKSkgewotICAgICAgICAgICAgICAgIGJ1aWxkS2V5SW5kZXgoSURfSU5ERVhfTkFNRSwgZG9jdW1lbnQpOwotICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIGZpbmFsIE1hcDxTdHJpbmcsIEludGVnZXI+IGVsZW1lbnRzQnlJRCA9IGVuaGFuY2VkRE9NLmdldEVsZW1lbnRzV2l0aElEcygpOwotCi0gICAgICAgICAgICAgICAgaWYgKGVsZW1lbnRzQnlJRCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyBHaXZlbiBhIE1hcCBvZiBEVE0gbm9kZXMgaW5kZXhlZCBieSBJRCBhdHRyaWJ1dGUgdmFsdWVzLAotICAgICAgICAgICAgICAgIC8vIGxvb3AgdGhyb3VnaCB0aGUgdGFibGUgY29weWluZyBpbmZvcm1hdGlvbiB0byBhIEtleUluZGV4Ci0gICAgICAgICAgICAgICAgLy8gZm9yIHRoZSBtYXBwaW5nIGZyb20gSUQgYXR0cmlidXRlIHZhbHVlIHRvIERUTSBub2RlCi0gICAgICAgICAgICAgICAgYm9vbGVhbiBoYXNJRFZhbHVlcyA9IGZhbHNlOwotICAgICAgICAgICAgICAgIGZvciAoTWFwLkVudHJ5PFN0cmluZywgSW50ZWdlcj4gZW50cnkgOiBlbGVtZW50c0J5SUQuZW50cnlTZXQoKSkgewotICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgZWxlbWVudCA9IGRvY3VtZW50LmdldE5vZGVIYW5kbGUoZW50cnkuZ2V0VmFsdWUoKSk7Ci0gICAgICAgICAgICAgICAgICAgIGJ1aWxkS2V5SW5kZXgoSURfSU5ERVhfTkFNRSwgZWxlbWVudCwgZW50cnkuZ2V0S2V5KCkpOwotICAgICAgICAgICAgICAgICAgICBoYXNJRFZhbHVlcyA9IHRydWU7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgaWYgKGhhc0lEVmFsdWVzKSB7Ci0gICAgICAgICAgICAgICAgICAgIHNldEtleUluZGV4RG9tKElEX0lOREVYX05BTUUsIGRvY3VtZW50KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBZnRlciBjb25zdHJ1Y3RpbmcgdGhlIHRyYW5zbGV0IG9iamVjdCwgdGhpcyBtZXRob2QgbXVzdCBiZSBjYWxsZWQgdG8KLSAgICAgKiBwZXJmb3JtIGFueSB2ZXJzaW9uLXNwZWNpZmljIHBvc3QtaW5pdGlhbGl6YXRpb24gdGhhdCdzIHJlcXVpcmVkLgotICAgICAqLwotICAgIHB1YmxpYyBmaW5hbCB2b2lkIHBvc3RJbml0aWFsaXphdGlvbigpIHsKLSAgICAgICAgLy8gSWYgdGhlIHZlcnNpb24gb2YgdGhlIHRyYW5zbGV0IGhhZCBqdXN0IG9uZSBuYW1lc0FycmF5LCBzcGxpdAotICAgICAgICAvLyBpdCBpbnRvIG11bHRpcGxlIGZpZWxkcy4KLSAgICAgICAgaWYgKHRyYW5zbGV0VmVyc2lvbiA8IFZFUl9TUExJVF9OQU1FU19BUlJBWSkgewotICAgICAgICAgICAgaW50IGFycmF5U2l6ZSA9IG5hbWVzQXJyYXkubGVuZ3RoOwotICAgICAgICAgICAgU3RyaW5nW10gbmV3VVJJc0FycmF5ID0gbmV3IFN0cmluZ1thcnJheVNpemVdOwotICAgICAgICAgICAgU3RyaW5nW10gbmV3TmFtZXNBcnJheSA9IG5ldyBTdHJpbmdbYXJyYXlTaXplXTsKLSAgICAgICAgICAgIGludFtdIG5ld1R5cGVzQXJyYXkgPSBuZXcgaW50W2FycmF5U2l6ZV07Ci0KLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYXJyYXlTaXplOyBpKyspIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgbmFtZSA9IG5hbWVzQXJyYXlbaV07Ci0gICAgICAgICAgICAgICAgaW50IGNvbG9uSW5kZXggPSBuYW1lLmxhc3RJbmRleE9mKCc6Jyk7Ci0gICAgICAgICAgICAgICAgaW50IGxOYW1lU3RhcnRJZHggPSBjb2xvbkluZGV4KzE7Ci0KLSAgICAgICAgICAgICAgICBpZiAoY29sb25JbmRleCA+IC0xKSB7Ci0gICAgICAgICAgICAgICAgICAgIG5ld1VSSXNBcnJheVtpXSA9IG5hbWUuc3Vic3RyaW5nKDAsIGNvbG9uSW5kZXgpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgLy8gRGlzdGluZ3Vpc2ggYXR0cmlidXRlIGFuZCBlbGVtZW50IG5hbWVzLiAgQXR0cmlidXRlIGhhcwotICAgICAgICAgICAgICAgLy8gQCBiZWZvcmUgbG9jYWwgcGFydCBvZiBuYW1lLgotICAgICAgICAgICAgICAgaWYgKG5hbWUuY2hhckF0KGxOYW1lU3RhcnRJZHgpID09ICdAJykgewotICAgICAgICAgICAgICAgICAgIGxOYW1lU3RhcnRJZHgrKzsKLSAgICAgICAgICAgICAgICAgICBuZXdUeXBlc0FycmF5W2ldID0gRFRNLkFUVFJJQlVURV9OT0RFOwotICAgICAgICAgICAgICAgfSBlbHNlIGlmIChuYW1lLmNoYXJBdChsTmFtZVN0YXJ0SWR4KSA9PSAnPycpIHsKLSAgICAgICAgICAgICAgICAgICBsTmFtZVN0YXJ0SWR4Kys7Ci0gICAgICAgICAgICAgICAgICAgbmV3VHlwZXNBcnJheVtpXSA9IERUTS5OQU1FU1BBQ0VfTk9ERTsKLSAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgbmV3VHlwZXNBcnJheVtpXSA9IERUTS5FTEVNRU5UX05PREU7Ci0gICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICBuZXdOYW1lc0FycmF5W2ldID0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgKGxOYW1lU3RhcnRJZHggPT0gMCkgPyBuYW1lCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogbmFtZS5zdWJzdHJpbmcobE5hbWVTdGFydElkeCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIG5hbWVzQXJyYXkgPSBuZXdOYW1lc0FycmF5OwotICAgICAgICAgICAgdXJpc0FycmF5ICA9IG5ld1VSSXNBcnJheTsKLSAgICAgICAgICAgIHR5cGVzQXJyYXkgPSBuZXdUeXBlc0FycmF5OwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gV2FzIHRyYW5zbGV0IGNvbXBpbGVkIHVzaW5nIGEgbW9yZSByZWNlbnQgdmVyc2lvbiBvZiB0aGUgWFNMVEMKLSAgICAgICAgLy8gY29tcGlsZXIgdGhhbiBpcyBrbm93biBieSB0aGUgQWJzdHJhY3RUcmFuc2xldCBjbGFzcz8gIElmLCBzbwotICAgICAgICAvLyBhbmQgd2UndmUgbWFkZSBpdCB0aGlzIGZhciAod2hpY2ggaXMgZG91YnRmdWwpLCB3ZSBzaG91bGQgZ2l2ZSB1cC4KLSAgICAgICAgaWYgKHRyYW5zbGV0VmVyc2lvbiA+IENVUlJFTlRfVFJBTlNMRVRfVkVSU0lPTikgewotICAgICAgICAgICAgQmFzaXNMaWJyYXJ5LnJ1blRpbWVFcnJvcihCYXNpc0xpYnJhcnkuVU5LTk9XTl9UUkFOU0xFVF9WRVJTSU9OX0VSUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5nZXRDbGFzcygpLmdldE5hbWUoKSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0gICAgICogSW5kZXgoZXMpIGZvciA8eHNsOmtleT4gLyBrZXkoKSAvIGlkKCkKLSAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwotCi0gICAgLy8gQ29udGFpbmVyIGZvciBhbGwgaW5kZXhlcyBmb3IgeHNsOmtleSBlbGVtZW50cwotICAgIHByaXZhdGUgTWFwPFN0cmluZywgS2V5SW5kZXg+IF9rZXlJbmRleGVzID0gbnVsbDsKLSAgICBwcml2YXRlIEtleUluZGV4ICBfZW1wdHlLZXlJbmRleCA9IG51bGw7Ci0gICAgcHJpdmF0ZSBpbnQgICAgICAgX2luZGV4U2l6ZSA9IDA7Ci0gICAgcHJpdmF0ZSBpbnQgICAgICAgX2N1cnJlbnRSb290Rm9yS2V5cyA9IDA7Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBpcyB1c2VkIHRvIHBhc3MgdGhlIGxhcmdlc3QgRE9NIHNpemUgdG8gdGhlIHRyYW5zbGV0LgotICAgICAqIE5lZWRlZCB0byBtYWtlIHN1cmUgdGhhdCB0aGUgdHJhbnNsZXQgY2FuIGluZGV4IHRoZSB3aG9sZSBET00uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0SW5kZXhTaXplKGludCBzaXplKSB7Ci0gICAgICAgIGlmIChzaXplID4gX2luZGV4U2l6ZSkgX2luZGV4U2l6ZSA9IHNpemU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlcyBhIEtleUluZGV4IG9iamVjdCBvZiB0aGUgZGVzaXJlZCBzaXplIC0gZG9uJ3Qgd2FudCB0byByZXNpemUhISEKLSAgICAgKi8KLSAgICBwdWJsaWMgS2V5SW5kZXggY3JlYXRlS2V5SW5kZXgoKSB7Ci0gICAgICAgIHJldHVybihuZXcgS2V5SW5kZXgoX2luZGV4U2l6ZSkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEFkZHMgYSB2YWx1ZSB0byBhIGtleS9pZCBpbmRleAotICAgICAqICAgQHBhcmFtIG5hbWUgaXMgdGhlIG5hbWUgb2YgdGhlIGluZGV4ICh0aGUga2V5IG9yICMjaWQpCi0gICAgICogICBAcGFyYW0gbm9kZSBpcyB0aGUgbm9kZSBoYW5kbGUgb2YgdGhlIG5vZGUgdG8gaW5zZXJ0Ci0gICAgICogICBAcGFyYW0gdmFsdWUgaXMgdGhlIHZhbHVlIHRoYXQgd2lsbCBsb29rIHVwIHRoZSBub2RlIGluIHRoZSBnaXZlbiBpbmRleAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGJ1aWxkS2V5SW5kZXgoU3RyaW5nIG5hbWUsIGludCBub2RlLCBTdHJpbmcgdmFsdWUpIHsKLSAgICAgICAgS2V5SW5kZXggaW5kZXggPSBidWlsZEtleUluZGV4SGVscGVyKG5hbWUpOwotICAgICAgICBpbmRleC5hZGQodmFsdWUsIG5vZGUsIF9jdXJyZW50Um9vdEZvcktleXMpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENyZWF0ZSBhbiBlbXB0eSBLZXlJbmRleCBpbiB0aGUgRE9NIGNhc2UKLSAgICAgKiAgIEBwYXJhbSBuYW1lIGlzIHRoZSBuYW1lIG9mIHRoZSBpbmRleCAodGhlIGtleSBvciAjI2lkKQotICAgICAqICAgQHBhcmFtIGRvbSBpcyB0aGUgRE9NCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgYnVpbGRLZXlJbmRleChTdHJpbmcgbmFtZSwgRE9NIGRvbSkgewotICAgICAgICBLZXlJbmRleCBpbmRleCA9IGJ1aWxkS2V5SW5kZXhIZWxwZXIobmFtZSk7Ci0gICAgICAgIGluZGV4LnNldERvbShkb20sIGRvbS5nZXREb2N1bWVudCgpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gS2V5SW5kZXggZm9yIHRoZSBidWlsZEtleUluZGV4IG1ldGhvZHMuIE5vdGUgdGhlIGRpZmZlcmVuY2UgZnJvbSB0aGUKLSAgICAgKiBwdWJsaWMgZ2V0S2V5SW5kZXggbWV0aG9kLCB0aGlzIG1ldGhvZCBjcmVhdGVzIGEgbmV3IE1hcCBpZiBrZXlJbmRleGVzIGRvZXMKLSAgICAgKiBub3QgZXhpc3QuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSB0aGUgbmFtZSBvZiB0aGUgaW5kZXggKHRoZSBrZXkgb3IgIyNpZCkKLSAgICAgKiBAcmV0dXJuIGEgS2V5SW5kZXguCi0gICAgICovCi0gICAgcHJpdmF0ZSBLZXlJbmRleCBidWlsZEtleUluZGV4SGVscGVyKFN0cmluZyBuYW1lKSB7Ci0gICAgICAgIGlmIChfa2V5SW5kZXhlcyA9PSBudWxsKSBfa2V5SW5kZXhlcyA9IG5ldyBIYXNoTWFwPD4oKTsKLQotICAgICAgICBLZXlJbmRleCBpbmRleCA9IF9rZXlJbmRleGVzLmdldChuYW1lKTsKLSAgICAgICAgaWYgKGluZGV4ID09IG51bGwpIHsKLSAgICAgICAgICAgIF9rZXlJbmRleGVzLnB1dChuYW1lLCBpbmRleCA9IG5ldyBLZXlJbmRleChfaW5kZXhTaXplKSk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGluZGV4OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIGluZGV4IGZvciBhIGdpdmVuIGtleSAob3IgaWQpLgotICAgICAqIFRoZSBpbmRleCBpbXBsZW1lbnRzIG91ciBpbnRlcm5hbCBpdGVyYXRvciBpbnRlcmZhY2UKLSAgICAgKiBAcGFyYW0gbmFtZSB0aGUgbmFtZSBvZiB0aGUgaW5kZXggKHRoZSBrZXkgb3IgIyNpZCkKLSAgICAgKiBAcmV0dXJuIGEgS2V5SW5kZXguCi0gICAgICovCi0gICAgcHVibGljIEtleUluZGV4IGdldEtleUluZGV4KFN0cmluZyBuYW1lKSB7Ci0gICAgICAgIC8vIFJldHVybiBhbiBlbXB0eSBrZXkgaW5kZXggaXRlcmF0b3IgaWYgbm9uZSBhcmUgZGVmaW5lZAotICAgICAgICBpZiAoX2tleUluZGV4ZXMgPT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIChfZW1wdHlLZXlJbmRleCAhPSBudWxsKQotICAgICAgICAgICAgICAgID8gX2VtcHR5S2V5SW5kZXgKLSAgICAgICAgICAgICAgICA6IChfZW1wdHlLZXlJbmRleCA9IG5ldyBLZXlJbmRleCgxKSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBMb29rIHVwIHRoZSByZXF1ZXN0ZWQga2V5IGluZGV4Ci0gICAgICAgIGZpbmFsIEtleUluZGV4IGluZGV4ID0gX2tleUluZGV4ZXMuZ2V0KG5hbWUpOwotCi0gICAgICAgIC8vIFJldHVybiBhbiBlbXB0eSBrZXkgaW5kZXggaXRlcmF0b3IgaWYgdGhlIHJlcXVlc3RlZCBpbmRleCBub3QgZm91bmQKLSAgICAgICAgaWYgKGluZGV4ID09IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiAoX2VtcHR5S2V5SW5kZXggIT0gbnVsbCkKLSAgICAgICAgICAgICAgICA/IF9lbXB0eUtleUluZGV4Ci0gICAgICAgICAgICAgICAgOiAoX2VtcHR5S2V5SW5kZXggPSBuZXcgS2V5SW5kZXgoMSkpOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuKGluZGV4KTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgc2V0Um9vdEZvcktleXMoaW50IHJvb3QpIHsKLSAgICAgICAgX2N1cnJlbnRSb290Rm9yS2V5cyA9IHJvb3Q7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgYnVpbGRzIGtleSBpbmRleGVzIC0gaXQgaXMgb3ZlcnJpZGRlbiBpbiB0aGUgY29tcGlsZWQKLSAgICAgKiB0cmFuc2xldCBpbiBjYXNlcyB3aGVyZSB0aGUgPHhzbDprZXk+IGVsZW1lbnQgaXMgdXNlZAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGJ1aWxkS2V5cyhET00gZG9jdW1lbnQsIERUTUF4aXNJdGVyYXRvciBpdGVyYXRvciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgU2VyaWFsaXphdGlvbkhhbmRsZXIgaGFuZGxlciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHJvb3QpIHRocm93cyBUcmFuc2xldEV4Y2VwdGlvbiB7Ci0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBidWlsZHMga2V5IGluZGV4ZXMgLSBpdCBpcyBvdmVycmlkZGVuIGluIHRoZSBjb21waWxlZAotICAgICAqIHRyYW5zbGV0IGluIGNhc2VzIHdoZXJlIHRoZSA8eHNsOmtleT4gZWxlbWVudCBpcyB1c2VkCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0S2V5SW5kZXhEb20oU3RyaW5nIG5hbWUsIERPTSBkb2N1bWVudCkgewotICAgICAgICBnZXRLZXlJbmRleChuYW1lKS5zZXREb20oZG9jdW1lbnQsIGRvY3VtZW50LmdldERvY3VtZW50KCkpOwotICAgIH0KLQotICAgIC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLSAgICAgKiBET00gY2FjaGUgaGFuZGxpbmcKLSAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwotCi0gICAgLy8gSG9sZCB0aGUgRE9NIGNhY2hlIChpZiBhbnkpIHVzZWQgd2l0aCB0aGlzIHRyYW5zbGV0Ci0gICAgcHJpdmF0ZSBET01DYWNoZSBfZG9tQ2FjaGUgPSBudWxsOwotCi0gICAgLyoqCi0gICAgICogU2V0cyB0aGUgRE9NIGNhY2hlIHVzZWQgZm9yIGFkZGl0aW9uYWwgZG9jdW1lbnRzIGxvYWRlZCB1c2luZyB0aGUKLSAgICAgKiBkb2N1bWVudCgpIGZ1bmN0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldERPTUNhY2hlKERPTUNhY2hlIGNhY2hlKSB7Ci0gICAgICAgIF9kb21DYWNoZSA9IGNhY2hlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIERPTSBjYWNoZSB1c2VkIGZvciB0aGlzIHRyYW5zbGV0LiBVc2VkIGJ5IHRoZSBMb2FkRG9jdW1lbnQKLSAgICAgKiBjbGFzcyAoaWYgcHJlc2VudCkgd2hlbiB0aGUgZG9jdW1lbnQoKSBmdW5jdGlvbiBpcyB1c2VkLgotICAgICAqLwotICAgIHB1YmxpYyBET01DYWNoZSBnZXRET01DYWNoZSgpIHsKLSAgICAgICAgcmV0dXJuKF9kb21DYWNoZSk7Ci0gICAgfQotCi0gICAgLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgotICAgICAqIE11bHRpcGxlIG91dHB1dCBkb2N1bWVudCBleHRlbnNpb24uCi0gICAgICogU2VlIGNvbXBpbGVyL1RyYW5zbGV0T3V0cHV0IGZvciBhY3R1YWwgaW1wbGVtZW50YXRpb24uCi0gICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLQotICAgIHB1YmxpYyBTZXJpYWxpemF0aW9uSGFuZGxlciBvcGVuT3V0cHV0SGFuZGxlcihTdHJpbmcgZmlsZW5hbWUsIGJvb2xlYW4gYXBwZW5kKQotICAgICAgICB0aHJvd3MgVHJhbnNsZXRFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBmaW5hbCBUcmFuc2xldE91dHB1dEhhbmRsZXJGYWN0b3J5IGZhY3RvcnkKLSAgICAgICAgICAgICAgICA9IFRyYW5zbGV0T3V0cHV0SGFuZGxlckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKLQotICAgICAgICAgICAgU3RyaW5nIGRpclN0ciA9IG5ldyBGaWxlKGZpbGVuYW1lKS5nZXRQYXJlbnQoKTsKLSAgICAgICAgICAgIGlmICgobnVsbCAhPSBkaXJTdHIpICYmIChkaXJTdHIubGVuZ3RoKCkgPiAwKSkgewotICAgICAgICAgICAgICAgRmlsZSBkaXIgPSBuZXcgRmlsZShkaXJTdHIpOwotICAgICAgICAgICAgICAgZGlyLm1rZGlycygpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBmYWN0b3J5LnNldEVuY29kaW5nKF9lbmNvZGluZyk7Ci0gICAgICAgICAgICBmYWN0b3J5LnNldE91dHB1dE1ldGhvZChfbWV0aG9kKTsKLSAgICAgICAgICAgIGZhY3Rvcnkuc2V0T3V0cHV0U3RyZWFtKG5ldyBCdWZmZXJlZE91dHB1dFN0cmVhbShuZXcgRmlsZU91dHB1dFN0cmVhbShmaWxlbmFtZSwgYXBwZW5kKSkpOwotICAgICAgICAgICAgZmFjdG9yeS5zZXRPdXRwdXRUeXBlKFRyYW5zbGV0T3V0cHV0SGFuZGxlckZhY3RvcnkuU1RSRUFNKTsKLQotICAgICAgICAgICAgZmluYWwgU2VyaWFsaXphdGlvbkhhbmRsZXIgaGFuZGxlcgotICAgICAgICAgICAgICAgID0gZmFjdG9yeS5nZXRTZXJpYWxpemF0aW9uSGFuZGxlcigpOwotCi0gICAgICAgICAgICB0cmFuc2Zlck91dHB1dFNldHRpbmdzKGhhbmRsZXIpOwotICAgICAgICAgICAgaGFuZGxlci5zdGFydERvY3VtZW50KCk7Ci0gICAgICAgICAgICByZXR1cm4gaGFuZGxlcjsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBUcmFuc2xldEV4Y2VwdGlvbihlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyBTZXJpYWxpemF0aW9uSGFuZGxlciBvcGVuT3V0cHV0SGFuZGxlcihTdHJpbmcgZmlsZW5hbWUpCi0gICAgICAgdGhyb3dzIFRyYW5zbGV0RXhjZXB0aW9uCi0gICAgewotICAgICAgIHJldHVybiBvcGVuT3V0cHV0SGFuZGxlcihmaWxlbmFtZSwgZmFsc2UpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGNsb3NlT3V0cHV0SGFuZGxlcihTZXJpYWxpemF0aW9uSGFuZGxlciBoYW5kbGVyKSB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBoYW5kbGVyLmVuZERvY3VtZW50KCk7Ci0gICAgICAgICAgICBoYW5kbGVyLmNsb3NlKCk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAvLyB3aGF0IGNhbiB5b3UgZG8/Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0gICAgICogTmF0aXZlIEFQSSB0cmFuc2Zvcm1hdGlvbiBtZXRob2RzIC0gX05PVF8gSkFYUC9UckFYCi0gICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLQotICAgIC8qKgotICAgICAqIE1haW4gdHJhbnNmb3JtKCkgbWV0aG9kIC0gdGhpcyBpcyBvdmVycmlkZGVuIGJ5IHRoZSBjb21waWxlZCB0cmFuc2xldAotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHRyYW5zZm9ybShET00gZG9jdW1lbnQsIERUTUF4aXNJdGVyYXRvciBpdGVyYXRvciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU2VyaWFsaXphdGlvbkhhbmRsZXIgaGFuZGxlcikKLSAgICAgICAgdGhyb3dzIFRyYW5zbGV0RXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogQ2FsbHMgdHJhbnNmb3JtKCkgd2l0aCBhIGdpdmVuIG91dHB1dCBoYW5kbGVyCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIHZvaWQgdHJhbnNmb3JtKERPTSBkb2N1bWVudCwgU2VyaWFsaXphdGlvbkhhbmRsZXIgaGFuZGxlcikKLSAgICAgICAgdGhyb3dzIFRyYW5zbGV0RXhjZXB0aW9uIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIHRyYW5zZm9ybShkb2N1bWVudCwgZG9jdW1lbnQuZ2V0SXRlcmF0b3IoKSwgaGFuZGxlcik7Ci0gICAgICAgIH0gZmluYWxseSB7Ci0gICAgICAgICAgICBfa2V5SW5kZXhlcyA9IG51bGw7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBVc2VkIGJ5IHNvbWUgY29tcGlsZWQgY29kZSBhcyBhIHNob3J0Y3V0IGZvciBwYXNzaW5nIHN0cmluZ3MgdG8gdGhlCi0gICAgICogb3V0cHV0IGhhbmRsZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgZmluYWwgdm9pZCBjaGFyYWN0ZXJzKGZpbmFsIFN0cmluZyBzdHJpbmcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZXJpYWxpemF0aW9uSGFuZGxlciBoYW5kbGVyKQotICAgICAgICB0aHJvd3MgVHJhbnNsZXRFeGNlcHRpb24gewotICAgICAgICBpZiAoc3RyaW5nICE9IG51bGwpIHsKLSAgICAgICAgICAgLy9maW5hbCBpbnQgbGVuZ3RoID0gc3RyaW5nLmxlbmd0aCgpOwotICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgaGFuZGxlci5jaGFyYWN0ZXJzKHN0cmluZyk7Ci0gICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNsZXRFeGNlcHRpb24oZSk7Ci0gICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEFkZCdzIGEgbmFtZSBvZiBhbiBlbGVtZW50IHdob3NlIHRleHQgY29udGVudHMgc2hvdWxkIGJlIG91dHB1dCBhcyBDREFUQQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGFkZENkYXRhRWxlbWVudChTdHJpbmcgbmFtZSkgewotICAgICAgICBpZiAoX2NkYXRhID09IG51bGwpIHsKLSAgICAgICAgICAgIF9jZGF0YSA9IG5ldyBWZWN0b3IoKTsKLSAgICAgICAgfQotCi0gICAgICAgIGludCBsYXN0Q29sb24gPSBuYW1lLmxhc3RJbmRleE9mKCc6Jyk7Ci0KLSAgICAgICAgaWYgKGxhc3RDb2xvbiA+IDApIHsKLSAgICAgICAgICAgIFN0cmluZyB1cmkgPSBuYW1lLnN1YnN0cmluZygwLCBsYXN0Q29sb24pOwotICAgICAgICAgICAgU3RyaW5nIGxvY2FsTmFtZSA9IG5hbWUuc3Vic3RyaW5nKGxhc3RDb2xvbisxKTsKLSAgICAgICAgICAgIF9jZGF0YS5hZGRFbGVtZW50KHVyaSk7Ci0gICAgICAgICAgICBfY2RhdGEuYWRkRWxlbWVudChsb2NhbE5hbWUpOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgX2NkYXRhLmFkZEVsZW1lbnQobnVsbCk7Ci0gICAgICAgICAgICBfY2RhdGEuYWRkRWxlbWVudChuYW1lKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zZmVyIHRoZSBvdXRwdXQgc2V0dGluZ3MgdG8gdGhlIG91dHB1dCBwb3N0LXByb2Nlc3NvcgotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIHRyYW5zZmVyT3V0cHV0U2V0dGluZ3MoU2VyaWFsaXphdGlvbkhhbmRsZXIgaGFuZGxlcikgewotICAgICAgICBpZiAoX21ldGhvZCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAoX21ldGhvZC5lcXVhbHMoInhtbCIpKSB7Ci0gICAgICAgICAgICAgICAgaWYgKF9zdGFuZGFsb25lICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgaGFuZGxlci5zZXRTdGFuZGFsb25lKF9zdGFuZGFsb25lKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaWYgKF9vbWl0SGVhZGVyKSB7Ci0gICAgICAgICAgICAgICAgICAgIGhhbmRsZXIuc2V0T21pdFhNTERlY2xhcmF0aW9uKHRydWUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBoYW5kbGVyLnNldENkYXRhU2VjdGlvbkVsZW1lbnRzKF9jZGF0YSk7Ci0gICAgICAgICAgICAgICAgaWYgKF92ZXJzaW9uICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgaGFuZGxlci5zZXRWZXJzaW9uKF92ZXJzaW9uKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaGFuZGxlci5zZXRJbmRlbnQoX2luZGVudCk7Ci0gICAgICAgICAgICAgICAgaGFuZGxlci5zZXRJbmRlbnRBbW91bnQoX2luZGVudGFtb3VudCk7Ci0gICAgICAgICAgICAgICAgaWYgKF9kb2N0eXBlU3lzdGVtICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgaGFuZGxlci5zZXREb2N0eXBlKF9kb2N0eXBlU3lzdGVtLCBfZG9jdHlwZVB1YmxpYyk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGhhbmRsZXIuc2V0SXNTdGFuZGFsb25lKF9pc1N0YW5kYWxvbmUpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoX21ldGhvZC5lcXVhbHMoImh0bWwiKSkgewotICAgICAgICAgICAgICAgIGhhbmRsZXIuc2V0SW5kZW50KF9pbmRlbnQpOwotICAgICAgICAgICAgICAgIGhhbmRsZXIuc2V0RG9jdHlwZShfZG9jdHlwZVN5c3RlbSwgX2RvY3R5cGVQdWJsaWMpOwotICAgICAgICAgICAgICAgIGlmIChfbWVkaWFUeXBlICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgaGFuZGxlci5zZXRNZWRpYVR5cGUoX21lZGlhVHlwZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgaGFuZGxlci5zZXRDZGF0YVNlY3Rpb25FbGVtZW50cyhfY2RhdGEpOwotICAgICAgICAgICAgaWYgKF92ZXJzaW9uICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBoYW5kbGVyLnNldFZlcnNpb24oX3ZlcnNpb24pOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKF9zdGFuZGFsb25lICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBoYW5kbGVyLnNldFN0YW5kYWxvbmUoX3N0YW5kYWxvbmUpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKF9vbWl0SGVhZGVyKSB7Ci0gICAgICAgICAgICAgICAgaGFuZGxlci5zZXRPbWl0WE1MRGVjbGFyYXRpb24odHJ1ZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBoYW5kbGVyLnNldEluZGVudChfaW5kZW50KTsKLSAgICAgICAgICAgIGhhbmRsZXIuc2V0RG9jdHlwZShfZG9jdHlwZVN5c3RlbSwgX2RvY3R5cGVQdWJsaWMpOwotICAgICAgICAgICAgaGFuZGxlci5zZXRJc1N0YW5kYWxvbmUoX2lzU3RhbmRhbG9uZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwcml2YXRlIE1hcDxTdHJpbmcsIENsYXNzPD8+PiBfYXV4Q2xhc3NlcyA9IG51bGw7Ci0KLSAgICBwdWJsaWMgdm9pZCBhZGRBdXhpbGlhcnlDbGFzcyhDbGFzcyBhdXhDbGFzcykgewotICAgICAgICBpZiAoX2F1eENsYXNzZXMgPT0gbnVsbCkgX2F1eENsYXNzZXMgPSBuZXcgSGFzaE1hcDw+KCk7Ci0gICAgICAgIF9hdXhDbGFzc2VzLnB1dChhdXhDbGFzcy5nZXROYW1lKCksIGF1eENsYXNzKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRBdXhpbGlhcnlDbGFzc2VzKE1hcDxTdHJpbmcsIENsYXNzPD8+PiBhdXhDbGFzc2VzKSB7Ci0gICAgICAgIF9hdXhDbGFzc2VzID0gYXV4Q2xhc3NlczsKLSAgICB9Ci0KLSAgICBwdWJsaWMgQ2xhc3MgZ2V0QXV4aWxpYXJ5Q2xhc3MoU3RyaW5nIGNsYXNzTmFtZSkgewotICAgICAgICBpZiAoX2F1eENsYXNzZXMgPT0gbnVsbCkgcmV0dXJuIG51bGw7Ci0gICAgICAgIHJldHVybigoQ2xhc3MpX2F1eENsYXNzZXMuZ2V0KGNsYXNzTmFtZSkpOwotICAgIH0KLQotICAgIC8vIEdUTSBhZGRlZCAoc2VlIHBnIDExMCkKLSAgICBwdWJsaWMgU3RyaW5nW10gZ2V0TmFtZXNBcnJheSgpIHsKLSAgICAgICAgcmV0dXJuIG5hbWVzQXJyYXk7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZ1tdIGdldFVyaXNBcnJheSgpIHsKLSAgICAgICAgcmV0dXJuIHVyaXNBcnJheTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50W10gZ2V0VHlwZXNBcnJheSgpIHsKLSAgICAgICAgcmV0dXJuIHR5cGVzQXJyYXk7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZ1tdIGdldE5hbWVzcGFjZUFycmF5KCkgewotICAgICAgICByZXR1cm4gbmFtZXNwYWNlQXJyYXk7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gaGFzSWRDYWxsKCkgewotICAgICAgICByZXR1cm4gX2hhc0lkQ2FsbDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgVGVtcGxhdGVzIGdldFRlbXBsYXRlcygpIHsKLSAgICAgICAgcmV0dXJuIF90ZW1wbGF0ZXM7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0VGVtcGxhdGVzKFRlbXBsYXRlcyB0ZW1wbGF0ZXMpIHsKLSAgICAgICAgX3RlbXBsYXRlcyA9IHRlbXBsYXRlczsKLSAgICB9Ci0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSBzdGF0ZSBvZiB0aGUgc2VydmljZXMgbWVjaGFuaXNtIGZlYXR1cmUuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gdXNlU2VydmljZXNNZWNobmlzbSgpIHsKLSAgICAgICAgcmV0dXJuIF91c2VTZXJ2aWNlc01lY2hhbmlzbTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIHN0YXRlIG9mIHRoZSBzZXJ2aWNlcyBtZWNoYW5pc20gZmVhdHVyZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRTZXJ2aWNlc01lY2huaXNtKGJvb2xlYW4gZmxhZykgewotICAgICAgICBfdXNlU2VydmljZXNNZWNoYW5pc20gPSBmbGFnOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybiBhbGxvd2VkIHByb3RvY29scyBmb3IgYWNjZXNzaW5nIGV4dGVybmFsIHN0eWxlc2hlZXQuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRBbGxvd2VkUHJvdG9jb2xzKCkgewotICAgICAgICByZXR1cm4gX2FjY2Vzc0V4dGVybmFsU3R5bGVzaGVldDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgYWxsb3dlZCBwcm90b2NvbHMgZm9yIGFjY2Vzc2luZyBleHRlcm5hbCBzdHlsZXNoZWV0LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEFsbG93ZWRQcm90b2NvbHMoU3RyaW5nIHByb3RvY29scykgewotICAgICAgICBfYWNjZXNzRXh0ZXJuYWxTdHlsZXNoZWV0ID0gcHJvdG9jb2xzOwotICAgIH0KLQotICAgIC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLSAgICAgKiBET01JbXBsZW1lbnRhdGlvbiBjYWNoaW5nIGZvciBiYXNpcyBsaWJyYXJ5Ci0gICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLSAgICBwcm90ZWN0ZWQgRE9NSW1wbGVtZW50YXRpb24gX2RvbUltcGxlbWVudGF0aW9uID0gbnVsbDsKLQotICAgIHB1YmxpYyBEb2N1bWVudCBuZXdEb2N1bWVudChTdHJpbmcgdXJpLCBTdHJpbmcgcW5hbWUpCi0gICAgICAgIHRocm93cyBQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAoX2RvbUltcGxlbWVudGF0aW9uID09IG51bGwpIHsKLSAgICAgICAgICAgIERvY3VtZW50QnVpbGRlckZhY3RvcnkgZGJmID0gRmFjdG9yeUltcGwuZ2V0RE9NRmFjdG9yeShfdXNlU2VydmljZXNNZWNoYW5pc20pOwotICAgICAgICAgICAgX2RvbUltcGxlbWVudGF0aW9uID0gZGJmLm5ld0RvY3VtZW50QnVpbGRlcigpLmdldERPTUltcGxlbWVudGF0aW9uKCk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIF9kb21JbXBsZW1lbnRhdGlvbi5jcmVhdGVEb2N1bWVudCh1cmksIHFuYW1lLCBudWxsKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvQXR0cmlidXRlcy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ydW50aW1lL0F0dHJpYnV0ZXMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNjJlNTdhNi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvQXR0cmlidXRlcy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNjUgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogQXR0cmlidXRlcy5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzA2IDEwOjUzOjA0IHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5ydW50aW1lOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLkRPTTsKLWltcG9ydCBvcmcueG1sLnNheC5BdHRyaWJ1dGVMaXN0OwotCi0vKioKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIEF0dHJpYnV0ZXMgaW1wbGVtZW50cyBBdHRyaWJ1dGVMaXN0IHsKLSAgICBwcml2YXRlIGludCBfZWxlbWVudDsKLSAgICBwcml2YXRlIERPTSBfZG9jdW1lbnQ7Ci0KLSAgICBwdWJsaWMgQXR0cmlidXRlcyhET00gZG9jdW1lbnQsIGludCBlbGVtZW50KSB7Ci0gICAgICAgIF9lbGVtZW50ID0gZWxlbWVudDsKLSAgICAgICAgX2RvY3VtZW50ID0gZG9jdW1lbnQ7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBnZXRMZW5ndGgoKSB7Ci0gICAgICAgIHJldHVybiAwOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZShpbnQgaSkgewotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldFR5cGUoaW50IGkpIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRUeXBlKFN0cmluZyBuYW1lKSB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VmFsdWUoaW50IGkpIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRWYWx1ZShTdHJpbmcgbmFtZSkgewotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvQmFzaXNMaWJyYXJ5LmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvQmFzaXNMaWJyYXJ5LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDgwNGIxNTQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ydW50aW1lL0Jhc2lzTGlicmFyeS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTY4OCArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDA3LCAyMDE2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICovCi0vKgotICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCi0gKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKLSAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KLSAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCi0gKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAotICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IEJhc2lzTGlicmFyeS5qYXZhLHYgMS42IDIwMDYvMDYvMjAgMjE6NTE6NTggc3BlcmljYXMgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5ydW50aW1lOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnV0aWxzLlNlY3VyaXR5U3VwcG9ydDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuRE9NOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5UcmFuc2xldDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuZG9tLkFic29sdXRlSXRlcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmRvbS5BcnJheU5vZGVMaXN0SXRlcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmRvbS5ET01BZGFwdGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5kb20uTXVsdGlET007Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmRvbS5TaW5nbGV0b25JdGVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuZG9tLlN0ZXBJdGVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5BeGlzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1BeGlzSXRlcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNTWFuYWdlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5yZWYuRFRNRGVmYXVsdEJhc2U7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0ucmVmLkRUTU5vZGVQcm94eTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXIuTmFtZXNwYWNlTWFwcGluZ3M7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyLlNlcmlhbGl6YXRpb25IYW5kbGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuWE1MMTFDaGFyOwotaW1wb3J0IGphdmEudGV4dC5EZWNpbWFsRm9ybWF0OwotaW1wb3J0IGphdmEudGV4dC5EZWNpbWFsRm9ybWF0U3ltYm9sczsKLWltcG9ydCBqYXZhLnRleHQuRmllbGRQb3NpdGlvbjsKLWltcG9ydCBqYXZhLnRleHQuTWVzc2FnZUZvcm1hdDsKLWltcG9ydCBqYXZhLnRleHQuTnVtYmVyRm9ybWF0OwotaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7Ci1pbXBvcnQgamF2YS51dGlsLlJlc291cmNlQnVuZGxlOwotaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LmF0b21pYy5BdG9taWNJbnRlZ2VyOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uZG9tLkRPTVNvdXJjZTsKLWltcG9ydCBvcmcudzNjLmRvbS5BdHRyOwotaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLkVsZW1lbnQ7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZUxpc3Q7Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotCi0vKioKLSAqIFN0YW5kYXJkIFhTTFQgZnVuY3Rpb25zLiBBbGwgc3RhbmRhcmQgZnVuY3Rpb25zIGV4cGVjdCB0aGUgY3VycmVudCBub2RlCi0gKiBhbmQgdGhlIERPTSBhcyB0aGVpciBsYXN0IHR3byBhcmd1bWVudHMuCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBCYXNpc0xpYnJhcnkgewotCi0gICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgU3RyaW5nIEVNUFRZU1RSSU5HID0gIiI7Ci0KLSAgICAvKioKLSAgICAgKiBSZS11c2UgYSBzaW5nbGUgaW5zdGFuY2Ugb2YgU3RyaW5nQnVmZmVyIChwZXIgdGhyZWFkKSBpbiB0aGUgYmFzaXMgbGlicmFyeS4KLSAgICAgKiBTdHJpbmdCdWlsZGVyIGlzIGJldHRlciwgaG93ZXZlciwgRGVjaW1hbEZvcm1hdCBvbmx5IGFjY2VwdCBTdHJpbmdCdWZmZXIKLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBUaHJlYWRMb2NhbDxTdHJpbmdCdWlsZGVyPiB0aHJlYWRMb2NhbFN0cmluZ0J1aWxkZXIgPQotICAgICAgICBuZXcgVGhyZWFkTG9jYWw8U3RyaW5nQnVpbGRlcj4gKCkgewotICAgICAgICAgICAgQE92ZXJyaWRlIHByb3RlY3RlZCBTdHJpbmdCdWlsZGVyIGluaXRpYWxWYWx1ZSgpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFN0cmluZ0J1aWxkZXIoKTsKLSAgICAgICAgICAgIH0KLSAgICB9OwotCi0gICAgLyoqCi0gICAgICogVGhyZWFkTG9jYWwgZm9yIFN0cmluZ0J1ZmZlciB1c2VkCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVGhyZWFkTG9jYWw8U3RyaW5nQnVmZmVyPiB0aHJlYWRMb2NhbFN0cmluZ0J1ZmZlciA9Ci0gICAgICAgIG5ldyBUaHJlYWRMb2NhbDxTdHJpbmdCdWZmZXI+ICgpIHsKLSAgICAgICAgICAgIEBPdmVycmlkZSBwcm90ZWN0ZWQgU3RyaW5nQnVmZmVyIGluaXRpYWxWYWx1ZSgpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFN0cmluZ0J1ZmZlcigpOwotICAgICAgICAgICAgfQotICAgIH07Ci0KLSAgICAvKioKLSAgICAgKiBTdGFuZGFyZCBmdW5jdGlvbiBjb3VudChub2RlLXNldCkKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGludCBjb3VudEYoRFRNQXhpc0l0ZXJhdG9yIGl0ZXJhdG9yKSB7Ci0gICAgICAgIHJldHVybihpdGVyYXRvci5nZXRMYXN0KCkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFN0YW5kYXJkIGZ1bmN0aW9uIHBvc2l0aW9uKCkKLSAgICAgKiBAZGVwcmVjYXRlZCBUaGlzIG1ldGhvZCBleGlzdHMgb25seSBmb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHkgd2l0aCBvbGQKLSAgICAgKiAgICAgICAgICAgICB0cmFuc2xldHMuICBOZXcgY29kZSBzaG91bGQgbm90IHJlZmVyZW5jZSBpdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGludCBwb3NpdGlvbkYoRFRNQXhpc0l0ZXJhdG9yIGl0ZXJhdG9yKSB7Ci0gICAgICAgIHJldHVybiBpdGVyYXRvci5pc1JldmVyc2UoKQotICAgICAgICAgICAgICAgICAgICAgPyBpdGVyYXRvci5nZXRMYXN0KCkgLSBpdGVyYXRvci5nZXRQb3NpdGlvbigpICsgMQotICAgICAgICAgICAgICAgICAgICAgOiBpdGVyYXRvci5nZXRQb3NpdGlvbigpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFhTTFQgU3RhbmRhcmQgZnVuY3Rpb24gc3VtKG5vZGUtc2V0KS4KLSAgICAgKiBzdHJpbmdUb0RvdWJsZSBpcyBpbmxpbmVkCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBkb3VibGUgc3VtRihEVE1BeGlzSXRlcmF0b3IgaXRlcmF0b3IsIERPTSBkb20pIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGRvdWJsZSByZXN1bHQgPSAwLjA7Ci0gICAgICAgICAgICBpbnQgbm9kZTsKLSAgICAgICAgICAgIHdoaWxlICgobm9kZSA9IGl0ZXJhdG9yLm5leHQoKSkgIT0gRFRNQXhpc0l0ZXJhdG9yLkVORCkgewotICAgICAgICAgICAgICAgIHJlc3VsdCArPSBEb3VibGUucGFyc2VEb3VibGUoZG9tLmdldFN0cmluZ1ZhbHVlWChub2RlKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gcmVzdWx0OwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgcmV0dXJuIERvdWJsZS5OYU47Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBYU0xUIFN0YW5kYXJkIGZ1bmN0aW9uIHN0cmluZygpCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBTdHJpbmcgc3RyaW5nRihpbnQgbm9kZSwgRE9NIGRvbSkgewotICAgICAgICByZXR1cm4gZG9tLmdldFN0cmluZ1ZhbHVlWChub2RlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBYU0xUIFN0YW5kYXJkIGZ1bmN0aW9uIHN0cmluZyh2YWx1ZSkKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBzdHJpbmdGKE9iamVjdCBvYmosIERPTSBkb20pIHsKLSAgICAgICAgaWYgKG9iaiBpbnN0YW5jZW9mIERUTUF4aXNJdGVyYXRvcikgewotICAgICAgICAgICAgcmV0dXJuIGRvbS5nZXRTdHJpbmdWYWx1ZVgoKChEVE1BeGlzSXRlcmF0b3Ipb2JqKS5yZXNldCgpLm5leHQoKSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAob2JqIGluc3RhbmNlb2YgTm9kZSkgewotICAgICAgICAgICAgcmV0dXJuIGRvbS5nZXRTdHJpbmdWYWx1ZVgoKChOb2RlKW9iaikubm9kZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAob2JqIGluc3RhbmNlb2YgRE9NKSB7Ci0gICAgICAgICAgICByZXR1cm4gKChET00pb2JqKS5nZXRTdHJpbmdWYWx1ZSgpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIG9iai50b1N0cmluZygpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogWFNMVCBTdGFuZGFyZCBmdW5jdGlvbiBzdHJpbmcodmFsdWUpCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBTdHJpbmcgc3RyaW5nRihPYmplY3Qgb2JqLCBpbnQgbm9kZSwgRE9NIGRvbSkgewotICAgICAgICBpZiAob2JqIGluc3RhbmNlb2YgRFRNQXhpc0l0ZXJhdG9yKSB7Ci0gICAgICAgICAgICByZXR1cm4gZG9tLmdldFN0cmluZ1ZhbHVlWCgoKERUTUF4aXNJdGVyYXRvcilvYmopLnJlc2V0KCkubmV4dCgpKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChvYmogaW5zdGFuY2VvZiBOb2RlKSB7Ci0gICAgICAgICAgICByZXR1cm4gZG9tLmdldFN0cmluZ1ZhbHVlWCgoKE5vZGUpb2JqKS5ub2RlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChvYmogaW5zdGFuY2VvZiBET00pIHsKLSAgICAgICAgICAgIC8vIFdoZW4gdGhlIGZpcnN0IGFyZ3VtZW50IGlzIGEgRE9NIHdlIHdhbnQgdGhlIHdob2xlCi0gICAgICAgICAgICAvLyBET00gYW5kIG5vdCBqdXN0IGEgc2luZ2xlIG5vZGUgLSB0aGF0IHdvdWxkIG5vdCBtYWtlIHNlbnNlLgotICAgICAgICAgICAgLy9yZXR1cm4gKChET00pb2JqKS5nZXRTdHJpbmdWYWx1ZVgobm9kZSk7Ci0gICAgICAgICAgICByZXR1cm4gKChET00pb2JqKS5nZXRTdHJpbmdWYWx1ZSgpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKG9iaiBpbnN0YW5jZW9mIERvdWJsZSkgewotICAgICAgICAgICAgRG91YmxlIGQgPSAoRG91YmxlKW9iajsKLSAgICAgICAgICAgIGZpbmFsIFN0cmluZyByZXN1bHQgPSBkLnRvU3RyaW5nKCk7Ci0gICAgICAgICAgICBmaW5hbCBpbnQgbGVuZ3RoID0gcmVzdWx0Lmxlbmd0aCgpOwotICAgICAgICAgICAgaWYgKChyZXN1bHQuY2hhckF0KGxlbmd0aC0yKT09Jy4nKSAmJgotICAgICAgICAgICAgICAgIChyZXN1bHQuY2hhckF0KGxlbmd0aC0xKSA9PSAnMCcpKQotICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQuc3Vic3RyaW5nKDAsIGxlbmd0aC0yKTsKLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0OwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIG9iaiAhPSBudWxsID8gb2JqLnRvU3RyaW5nKCkgOiAiIjsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFhTTFQgU3RhbmRhcmQgZnVuY3Rpb24gbnVtYmVyKCkKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGRvdWJsZSBudW1iZXJGKGludCBub2RlLCBET00gZG9tKSB7Ci0gICAgICAgIHJldHVybiBzdHJpbmdUb1JlYWwoZG9tLmdldFN0cmluZ1ZhbHVlWChub2RlKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogWFNMVCBTdGFuZGFyZCBmdW5jdGlvbiBudW1iZXIodmFsdWUpCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBkb3VibGUgbnVtYmVyRihPYmplY3Qgb2JqLCBET00gZG9tKSB7Ci0gICAgICAgIGlmIChvYmogaW5zdGFuY2VvZiBEb3VibGUpIHsKLSAgICAgICAgICAgIHJldHVybiAoKERvdWJsZSkgb2JqKS5kb3VibGVWYWx1ZSgpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKG9iaiBpbnN0YW5jZW9mIEludGVnZXIpIHsKLSAgICAgICAgICAgIHJldHVybiAoKEludGVnZXIpIG9iaikuZG91YmxlVmFsdWUoKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChvYmogaW5zdGFuY2VvZiBCb29sZWFuKSB7Ci0gICAgICAgICAgICByZXR1cm4gICgoQm9vbGVhbikgb2JqKS5ib29sZWFuVmFsdWUoKSA/IDEuMCA6IDAuMDsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChvYmogaW5zdGFuY2VvZiBTdHJpbmcpIHsKLSAgICAgICAgICAgIHJldHVybiBzdHJpbmdUb1JlYWwoKFN0cmluZykgb2JqKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChvYmogaW5zdGFuY2VvZiBEVE1BeGlzSXRlcmF0b3IpIHsKLSAgICAgICAgICAgIERUTUF4aXNJdGVyYXRvciBpdGVyID0gKERUTUF4aXNJdGVyYXRvcikgb2JqOwotICAgICAgICAgICAgcmV0dXJuIHN0cmluZ1RvUmVhbChkb20uZ2V0U3RyaW5nVmFsdWVYKGl0ZXIucmVzZXQoKS5uZXh0KCkpKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChvYmogaW5zdGFuY2VvZiBOb2RlKSB7Ci0gICAgICAgICAgICByZXR1cm4gc3RyaW5nVG9SZWFsKGRvbS5nZXRTdHJpbmdWYWx1ZVgoKChOb2RlKSBvYmopLm5vZGUpKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChvYmogaW5zdGFuY2VvZiBET00pIHsKLSAgICAgICAgICAgIHJldHVybiBzdHJpbmdUb1JlYWwoKChET00pIG9iaikuZ2V0U3RyaW5nVmFsdWUoKSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBmaW5hbCBTdHJpbmcgY2xhc3NOYW1lID0gb2JqLmdldENsYXNzKCkuZ2V0TmFtZSgpOwotICAgICAgICAgICAgcnVuVGltZUVycm9yKElOVkFMSURfQVJHVU1FTlRfRVJSLCBjbGFzc05hbWUsICJudW1iZXIoKSIpOwotICAgICAgICAgICAgcmV0dXJuIDAuMDsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFhTTFQgU3RhbmRhcmQgZnVuY3Rpb24gcm91bmQoKQotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZG91YmxlIHJvdW5kRihkb3VibGUgZCkgewotICAgICAgICAgICAgcmV0dXJuIChkPC0wLjUgfHwgZD4wLjApP01hdGguZmxvb3IoZCswLjUpOigoZD09MC4wKT8KLSAgICAgICAgICAgICAgICAgICAgICAgIGQ6KERvdWJsZS5pc05hTihkKT9Eb3VibGUuTmFOOi0wLjApKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBYU0xUIFN0YW5kYXJkIGZ1bmN0aW9uIGJvb2xlYW4oKQotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBib29sZWFuRihPYmplY3Qgb2JqKSB7Ci0gICAgICAgIGlmIChvYmogaW5zdGFuY2VvZiBEb3VibGUpIHsKLSAgICAgICAgICAgIGZpbmFsIGRvdWJsZSB0ZW1wID0gKChEb3VibGUpIG9iaikuZG91YmxlVmFsdWUoKTsKLSAgICAgICAgICAgIHJldHVybiB0ZW1wICE9IDAuMCAmJiAhRG91YmxlLmlzTmFOKHRlbXApOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKG9iaiBpbnN0YW5jZW9mIEludGVnZXIpIHsKLSAgICAgICAgICAgIHJldHVybiAoKEludGVnZXIpIG9iaikuZG91YmxlVmFsdWUoKSAhPSAwOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKG9iaiBpbnN0YW5jZW9mIEJvb2xlYW4pIHsKLSAgICAgICAgICAgIHJldHVybiAgKChCb29sZWFuKSBvYmopLmJvb2xlYW5WYWx1ZSgpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKG9iaiBpbnN0YW5jZW9mIFN0cmluZykgewotICAgICAgICAgICAgcmV0dXJuICEoKFN0cmluZykgb2JqKS5lcXVhbHMoRU1QVFlTVFJJTkcpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKG9iaiBpbnN0YW5jZW9mIERUTUF4aXNJdGVyYXRvcikgewotICAgICAgICAgICAgRFRNQXhpc0l0ZXJhdG9yIGl0ZXIgPSAoRFRNQXhpc0l0ZXJhdG9yKSBvYmo7Ci0gICAgICAgICAgICByZXR1cm4gaXRlci5yZXNldCgpLm5leHQoKSAhPSBEVE1BeGlzSXRlcmF0b3IuRU5EOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKG9iaiBpbnN0YW5jZW9mIE5vZGUpIHsKLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKG9iaiBpbnN0YW5jZW9mIERPTSkgewotICAgICAgICAgICAgU3RyaW5nIHRlbXAgPSAoKERPTSkgb2JqKS5nZXRTdHJpbmdWYWx1ZSgpOwotICAgICAgICAgICAgcmV0dXJuICF0ZW1wLmVxdWFscyhFTVBUWVNUUklORyk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBmaW5hbCBTdHJpbmcgY2xhc3NOYW1lID0gb2JqLmdldENsYXNzKCkuZ2V0TmFtZSgpOwotICAgICAgICAgICAgcnVuVGltZUVycm9yKElOVkFMSURfQVJHVU1FTlRfRVJSLCBjbGFzc05hbWUsICJib29sZWFuKCkiKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogWFNMVCBTdGFuZGFyZCBmdW5jdGlvbiBzdWJzdHJpbmcoKS4gTXVzdCB0YWtlIGEgZG91YmxlIGJlY2F1c2Ugb2YKLSAgICAgKiBjb252ZXJzaW9ucyByZXN1bHRpbmcgaW50byBOYU5zIGFuZCByb3VuZGluZy4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBzdWJzdHJpbmdGKFN0cmluZyB2YWx1ZSwgZG91YmxlIHN0YXJ0KSB7Ci0gICAgICAgIGlmIChEb3VibGUuaXNOYU4oc3RhcnQpKQotICAgICAgICAgICAgcmV0dXJuKEVNUFRZU1RSSU5HKTsKLQotICAgICAgICBmaW5hbCBpbnQgc3RybGVuID0gZ2V0U3RyaW5nTGVuZ3RoKHZhbHVlKTsKLSAgICAgICAgaW50IGlzdGFydCA9IChpbnQpTWF0aC5yb3VuZChzdGFydCkgLSAxOwotCi0gICAgICAgIGlmIChpc3RhcnQgPiBzdHJsZW4pCi0gICAgICAgICAgICByZXR1cm4oRU1QVFlTVFJJTkcpOwotICAgICAgICBpZiAoaXN0YXJ0IDwgMSkKLSAgICAgICAgICAgIGlzdGFydCA9IDA7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBpc3RhcnQgPSB2YWx1ZS5vZmZzZXRCeUNvZGVQb2ludHMoMCwgaXN0YXJ0KTsKLSAgICAgICAgICAgIHJldHVybiB2YWx1ZS5zdWJzdHJpbmcoaXN0YXJ0KTsKLSAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICBydW5UaW1lRXJyb3IoUlVOX1RJTUVfSU5URVJOQUxfRVJSLCAic3Vic3RyaW5nKCkiKTsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogWFNMVCBTdGFuZGFyZCBmdW5jdGlvbiBzdWJzdHJpbmcoKS4gTXVzdCB0YWtlIGEgZG91YmxlIGJlY2F1c2Ugb2YKLSAgICAgKiBjb252ZXJzaW9ucyByZXN1bHRpbmcgaW50byBOYU5zIGFuZCByb3VuZGluZy4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBzdWJzdHJpbmdGKFN0cmluZyB2YWx1ZSwgZG91YmxlIHN0YXJ0LCBkb3VibGUgbGVuZ3RoKSB7Ci0gICAgICAgIGlmIChEb3VibGUuaXNJbmZpbml0ZShzdGFydCkgfHwKLSAgICAgICAgICAgIERvdWJsZS5pc05hTihzdGFydCkgfHwKLSAgICAgICAgICAgIERvdWJsZS5pc05hTihsZW5ndGgpIHx8Ci0gICAgICAgICAgICBsZW5ndGggPCAwKQotICAgICAgICAgICAgcmV0dXJuKEVNUFRZU1RSSU5HKTsKLQotICAgICAgICBpbnQgaXN0YXJ0ID0gKGludClNYXRoLnJvdW5kKHN0YXJ0KSAtIDE7Ci0gICAgICAgIGludCBpbGVuZ3RoID0gKGludClNYXRoLnJvdW5kKGxlbmd0aCk7Ci0gICAgICAgIGZpbmFsIGludCBpc3VtOwotICAgICAgICBpZiAoRG91YmxlLmlzSW5maW5pdGUobGVuZ3RoKSkKLSAgICAgICAgICAgIGlzdW0gPSBJbnRlZ2VyLk1BWF9WQUxVRTsKLSAgICAgICAgZWxzZQotICAgICAgICAgICAgaXN1bSA9IGlzdGFydCArIGlsZW5ndGg7Ci0KLSAgICAgICAgZmluYWwgaW50IHN0cmxlbiA9IGdldFN0cmluZ0xlbmd0aCh2YWx1ZSk7Ci0gICAgICAgIGlmIChpc3VtIDwgMCB8fCBpc3RhcnQgPiBzdHJsZW4pCi0gICAgICAgICAgICAgICAgcmV0dXJuKEVNUFRZU1RSSU5HKTsKLQotICAgICAgICBpZiAoaXN0YXJ0IDwgMCkgewotICAgICAgICAgICAgaWxlbmd0aCArPSBpc3RhcnQ7Ci0gICAgICAgICAgICBpc3RhcnQgPSAwOwotICAgICAgICB9Ci0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGlzdGFydCA9IHZhbHVlLm9mZnNldEJ5Q29kZVBvaW50cygwLCBpc3RhcnQpOwotICAgICAgICAgICAgaWYgKGlzdW0gPiBzdHJsZW4pIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWUuc3Vic3RyaW5nKGlzdGFydCk7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIGludCBvZmZzZXQgPSB2YWx1ZS5vZmZzZXRCeUNvZGVQb2ludHMoaXN0YXJ0LCBpbGVuZ3RoKTsKLSAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWUuc3Vic3RyaW5nKGlzdGFydCwgb2Zmc2V0KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICBydW5UaW1lRXJyb3IoUlVOX1RJTUVfSU5URVJOQUxfRVJSLCAic3Vic3RyaW5nKCkiKTsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogWFNMVCBTdGFuZGFyZCBmdW5jdGlvbiBzdWJzdHJpbmctYWZ0ZXIoKS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBzdWJzdHJpbmdfYWZ0ZXJGKFN0cmluZyB2YWx1ZSwgU3RyaW5nIHN1YnN0cmluZykgewotICAgICAgICBmaW5hbCBpbnQgaW5kZXggPSB2YWx1ZS5pbmRleE9mKHN1YnN0cmluZyk7Ci0gICAgICAgIGlmIChpbmRleCA+PSAwKQotICAgICAgICAgICAgcmV0dXJuIHZhbHVlLnN1YnN0cmluZyhpbmRleCArIHN1YnN0cmluZy5sZW5ndGgoKSk7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICAgIHJldHVybiBFTVBUWVNUUklORzsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBYU0xUIFN0YW5kYXJkIGZ1bmN0aW9uIHN1YnN0cmluZy1iZWZvcmUoKS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBzdWJzdHJpbmdfYmVmb3JlRihTdHJpbmcgdmFsdWUsIFN0cmluZyBzdWJzdHJpbmcpIHsKLSAgICAgICAgZmluYWwgaW50IGluZGV4ID0gdmFsdWUuaW5kZXhPZihzdWJzdHJpbmcpOwotICAgICAgICBpZiAoaW5kZXggPj0gMCkKLSAgICAgICAgICAgIHJldHVybiB2YWx1ZS5zdWJzdHJpbmcoMCwgaW5kZXgpOwotICAgICAgICBlbHNlCi0gICAgICAgICAgICByZXR1cm4gRU1QVFlTVFJJTkc7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogWFNMVCBTdGFuZGFyZCBmdW5jdGlvbiB0cmFuc2xhdGUoKS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFN0cmluZyB0cmFuc2xhdGVGKFN0cmluZyB2YWx1ZSwgU3RyaW5nIGZyb20sIFN0cmluZyB0bykgewotICAgICAgICBmaW5hbCBpbnQgdG9sID0gdG8ubGVuZ3RoKCk7Ci0gICAgICAgIGZpbmFsIGludCBmcm9tbCA9IGZyb20ubGVuZ3RoKCk7Ci0gICAgICAgIGZpbmFsIGludCB2YWx1ZWwgPSB2YWx1ZS5sZW5ndGgoKTsKLQotICAgICAgICBmaW5hbCBTdHJpbmdCdWlsZGVyIHJlc3VsdCA9IHRocmVhZExvY2FsU3RyaW5nQnVpbGRlci5nZXQoKTsKLSAgICByZXN1bHQuc2V0TGVuZ3RoKDApOwotICAgICAgICBmb3IgKGludCBqLCBpID0gMDsgaSA8IHZhbHVlbDsgaSsrKSB7Ci0gICAgICAgICAgICBmaW5hbCBjaGFyIGNoID0gdmFsdWUuY2hhckF0KGkpOwotICAgICAgICAgICAgZm9yIChqID0gMDsgaiA8IGZyb21sOyBqKyspIHsKLSAgICAgICAgICAgICAgICBpZiAoY2ggPT0gZnJvbS5jaGFyQXQoaikpIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGogPCB0b2wpCi0gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQuYXBwZW5kKHRvLmNoYXJBdChqKSk7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChqID09IGZyb21sKQotICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoY2gpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiByZXN1bHQudG9TdHJpbmcoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBYU0xUIFN0YW5kYXJkIGZ1bmN0aW9uIG5vcm1hbGl6ZS1zcGFjZSgpLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIG5vcm1hbGl6ZV9zcGFjZUYoaW50IG5vZGUsIERPTSBkb20pIHsKLSAgICAgICAgcmV0dXJuIG5vcm1hbGl6ZV9zcGFjZUYoZG9tLmdldFN0cmluZ1ZhbHVlWChub2RlKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogWFNMVCBTdGFuZGFyZCBmdW5jdGlvbiBub3JtYWxpemUtc3BhY2Uoc3RyaW5nKS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBub3JtYWxpemVfc3BhY2VGKFN0cmluZyB2YWx1ZSkgewotICAgICAgICBpbnQgaSA9IDAsIG4gPSB2YWx1ZS5sZW5ndGgoKTsKLSAgICAgICAgU3RyaW5nQnVpbGRlciByZXN1bHQgPSB0aHJlYWRMb2NhbFN0cmluZ0J1aWxkZXIuZ2V0KCk7Ci0gICAgcmVzdWx0LnNldExlbmd0aCgwKTsKLQotICAgICAgICB3aGlsZSAoaSA8IG4gJiYgaXNXaGl0ZVNwYWNlKHZhbHVlLmNoYXJBdChpKSkpCi0gICAgICAgICAgICBpKys7Ci0KLSAgICAgICAgd2hpbGUgKHRydWUpIHsKLSAgICAgICAgICAgIHdoaWxlIChpIDwgbiAmJiAhaXNXaGl0ZVNwYWNlKHZhbHVlLmNoYXJBdChpKSkpIHsKLSAgICAgICAgICAgICAgICByZXN1bHQuYXBwZW5kKHZhbHVlLmNoYXJBdChpKyspKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChpID09IG4pCi0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB3aGlsZSAoaSA8IG4gJiYgaXNXaGl0ZVNwYWNlKHZhbHVlLmNoYXJBdChpKSkpIHsKLSAgICAgICAgICAgICAgICBpKys7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoaSA8IG4pCi0gICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZCgnICcpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiByZXN1bHQudG9TdHJpbmcoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBYU0xUIFN0YW5kYXJkIGZ1bmN0aW9uIGdlbmVyYXRlLWlkKCkuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZ2VuZXJhdGVfaWRGKGludCBub2RlKSB7Ci0gICAgICAgIGlmIChub2RlID4gMCkKLSAgICAgICAgICAgIC8vIE9ubHkgZ2VuZXJhdGUgSUQgaWYgbm9kZSBleGlzdHMKLSAgICAgICAgICAgIHJldHVybiAiTiIgKyBub2RlOwotICAgICAgICBlbHNlCi0gICAgICAgICAgICAvLyBPdGhlcndpc2UgcmV0dXJuIGFuIGVtcHR5IHN0cmluZwotICAgICAgICAgICAgcmV0dXJuIEVNUFRZU1RSSU5HOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIHV0aWxpdHkgZnVuY3Rpb24gZm9yIGNhbGxzIHRvIGxvY2FsLW5hbWUoKS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBnZXRMb2NhbE5hbWUoU3RyaW5nIHZhbHVlKSB7Ci0gICAgICAgIGludCBpZHggPSB2YWx1ZS5sYXN0SW5kZXhPZignOicpOwotICAgICAgICBpZiAoaWR4ID49IDApIHZhbHVlID0gdmFsdWUuc3Vic3RyaW5nKGlkeCArIDEpOwotICAgICAgICBpZHggPSB2YWx1ZS5sYXN0SW5kZXhPZignQCcpOwotICAgICAgICBpZiAoaWR4ID49IDApIHZhbHVlID0gdmFsdWUuc3Vic3RyaW5nKGlkeCArIDEpOwotICAgICAgICByZXR1cm4odmFsdWUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEV4dGVybmFsIGZ1bmN0aW9ucyB0aGF0IGNhbm5vdCBiZSByZXNvbHZlZCBhcmUgcmVwbGFjZWQgd2l0aCBhIGNhbGwKLSAgICAgKiB0byB0aGlzIG1ldGhvZC4gVGhpcyBtZXRob2Qgd2lsbCBnZW5lcmF0ZSBhIHJ1bnRpbWUgZXJyb3JzLiBBIGdvb2QKLSAgICAgKiBzdHlsZXNoZWV0IGNoZWNrcyB3aGV0aGVyIHRoZSBmdW5jdGlvbiBleGlzdHMgdXNpbmcgY29uZGl0aW9uYWwKLSAgICAgKiBjb25zdHJ1Y3RzLCBhbmQgbmV2ZXIgcmVhbGx5IHRyaWVzIHRvIGNhbGwgaXQgaWYgaXQgZG9lc24ndCBleGlzdC4KLSAgICAgKiBCdXQgc2ltcGxlIHN0eWxlc2hlZXRzIG1heSByZXN1bHQgaW4gYSBjYWxsIHRvIHRoaXMgbWV0aG9kLgotICAgICAqIFRoZSBjb21waWxlciBzaG91bGQgZ2VuZXJhdGUgYSB3YXJuaW5nIGlmIGl0IGVuY291bnRlcnMgYSBjYWxsIHRvCi0gICAgICogYW4gdW5yZXNvbHZlZCBleHRlcm5hbCBmdW5jdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIHZvaWQgdW5yZXNvbHZlZF9leHRlcm5hbEYoU3RyaW5nIG5hbWUpIHsKLSAgICAgICAgcnVuVGltZUVycm9yKEVYVEVSTkFMX0ZVTkNfRVJSLCBuYW1lKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBVdGlsaXR5IGZ1bmN0aW9uIHRvIHRocm93IGEgcnVudGltZSBlcnJvciBvbiB0aGUgdXNlIG9mIGFuIGV4dGVuc2lvbgotICAgICAqIGZ1bmN0aW9uIHdoZW4gdGhlIHNlY3VyZSBwcm9jZXNzaW5nIGZlYXR1cmUgaXMgc2V0IHRvIHRydWUuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyB2b2lkIHVuYWxsb3dlZF9leHRlbnNpb25fZnVuY3Rpb25GKFN0cmluZyBuYW1lKSB7Ci0gICAgICAgIHJ1blRpbWVFcnJvcihVTkFMTE9XRURfRVhURU5TSU9OX0ZVTkNUSU9OX0VSUiwgbmFtZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVXRpbGl0eSBmdW5jdGlvbiB0byB0aHJvdyBhIHJ1bnRpbWUgZXJyb3Igb24gdGhlIHVzZSBvZiBhbiBleHRlbnNpb24KLSAgICAgKiBlbGVtZW50IHdoZW4gdGhlIHNlY3VyZSBwcm9jZXNzaW5nIGZlYXR1cmUgaXMgc2V0IHRvIHRydWUuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyB2b2lkIHVuYWxsb3dlZF9leHRlbnNpb25fZWxlbWVudEYoU3RyaW5nIG5hbWUpIHsKLSAgICAgICAgcnVuVGltZUVycm9yKFVOQUxMT1dFRF9FWFRFTlNJT05fRUxFTUVOVF9FUlIsIG5hbWUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFV0aWxpdHkgZnVuY3Rpb24gdG8gdGhyb3cgYSBydW50aW1lIGVycm9yIGZvciBhbiB1bnN1cHBvcnRlZCBlbGVtZW50LgotICAgICAqCi0gICAgICogVGhpcyBpcyBvbmx5IHVzZWQgaW4gZm9yd2FyZC1jb21wYXRpYmlsaXR5IG1vZGUsIHdoZW4gdGhlIGNvbnRyb2wgZmxvdwotICAgICAqIGNhbm5vdCBiZSBkZXRlcm1pbmVkLiBJbiAxLjAgbW9kZSwgdGhlIGVycm9yIG1lc3NhZ2UgaXMgZW1pdHRlZCBhdAotICAgICAqIGNvbXBpbGUgdGltZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIHZvaWQgdW5zdXBwb3J0ZWRfRWxlbWVudEYoU3RyaW5nIHFuYW1lLCBib29sZWFuIGlzRXh0ZW5zaW9uKSB7Ci0gICAgICAgIGlmIChpc0V4dGVuc2lvbikKLSAgICAgICAgICAgIHJ1blRpbWVFcnJvcihVTlNVUFBPUlRFRF9FWFRfRVJSLCBxbmFtZSk7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICAgIHJ1blRpbWVFcnJvcihVTlNVUFBPUlRFRF9YU0xfRVJSLCBxbmFtZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogWFNMVCBTdGFuZGFyZCBmdW5jdGlvbiBuYW1lc3BhY2UtdXJpKG5vZGUtc2V0KS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBuYW1lc3BhY2VfdXJpRihEVE1BeGlzSXRlcmF0b3IgaXRlciwgRE9NIGRvbSkgewotICAgICAgICByZXR1cm4gbmFtZXNwYWNlX3VyaUYoaXRlci5uZXh0KCksIGRvbSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogWFNMVCBTdGFuZGFyZCBmdW5jdGlvbiBzeXN0ZW0tcHJvcGVydHkobmFtZSkKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBzeXN0ZW1fcHJvcGVydHlGKFN0cmluZyBuYW1lKSB7Ci0gICAgICAgIGlmIChuYW1lLmVxdWFscygieHNsOnZlcnNpb24iKSkKLSAgICAgICAgICAgIHJldHVybigiMS4wIik7Ci0gICAgICAgIGlmIChuYW1lLmVxdWFscygieHNsOnZlbmRvciIpKQotICAgICAgICAgICAgcmV0dXJuKCJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoWGFsYW4gWFNMVEMpIik7Ci0gICAgICAgIGlmIChuYW1lLmVxdWFscygieHNsOnZlbmRvci11cmwiKSkKLSAgICAgICAgICAgIHJldHVybigiaHR0cDovL3htbC5hcGFjaGUub3JnL3hhbGFuLWoiKTsKLQotICAgICAgICBydW5UaW1lRXJyb3IoSU5WQUxJRF9BUkdVTUVOVF9FUlIsIG5hbWUsICJzeXN0ZW0tcHJvcGVydHkoKSIpOwotICAgICAgICByZXR1cm4oRU1QVFlTVFJJTkcpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFhTTFQgU3RhbmRhcmQgZnVuY3Rpb24gbmFtZXNwYWNlLXVyaSgpLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIG5hbWVzcGFjZV91cmlGKGludCBub2RlLCBET00gZG9tKSB7Ci0gICAgICAgIGZpbmFsIFN0cmluZyB2YWx1ZSA9IGRvbS5nZXROb2RlTmFtZShub2RlKTsKLSAgICAgICAgZmluYWwgaW50IGNvbG9uID0gdmFsdWUubGFzdEluZGV4T2YoJzonKTsKLSAgICAgICAgaWYgKGNvbG9uID49IDApCi0gICAgICAgICAgICByZXR1cm4gdmFsdWUuc3Vic3RyaW5nKDAsIGNvbG9uKTsKLSAgICAgICAgZWxzZQotICAgICAgICAgICAgcmV0dXJuIEVNUFRZU1RSSU5HOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEltcGxlbWVudHMgdGhlIG9iamVjdC10eXBlKCkgZXh0ZW5zaW9uIGZ1bmN0aW9uLgotICAgICAqCi0gICAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LmV4c2x0Lm9yZy8iPkVYU0xUPC9hPgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIG9iamVjdFR5cGVGKE9iamVjdCBvYmopCi0gICAgewotICAgICAgaWYgKG9iaiBpbnN0YW5jZW9mIFN0cmluZykKLSAgICAgICAgcmV0dXJuICJzdHJpbmciOwotICAgICAgZWxzZSBpZiAob2JqIGluc3RhbmNlb2YgQm9vbGVhbikKLSAgICAgICAgcmV0dXJuICJib29sZWFuIjsKLSAgICAgIGVsc2UgaWYgKG9iaiBpbnN0YW5jZW9mIE51bWJlcikKLSAgICAgICAgcmV0dXJuICJudW1iZXIiOwotICAgICAgZWxzZSBpZiAob2JqIGluc3RhbmNlb2YgRE9NKQotICAgICAgICByZXR1cm4gIlJURiI7Ci0gICAgICBlbHNlIGlmIChvYmogaW5zdGFuY2VvZiBEVE1BeGlzSXRlcmF0b3IpCi0gICAgICAgIHJldHVybiAibm9kZS1zZXQiOwotICAgICAgZWxzZQotICAgICAgICByZXR1cm4gInVua25vd24iOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEltcGxlbWVudHMgdGhlIG5vZGVzZXQoKSBleHRlbnNpb24gZnVuY3Rpb24uCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBEVE1BeGlzSXRlcmF0b3Igbm9kZXNldEYoT2JqZWN0IG9iaikgewotICAgICAgICBpZiAob2JqIGluc3RhbmNlb2YgRE9NKSB7Ci0gICAgICAgICAgIC8vZmluYWwgRE9NQWRhcHRlciBhZGFwdGVyID0gKERPTUFkYXB0ZXIpIG9iajsKLSAgICAgICAgICAgZmluYWwgRE9NIGRvbSA9IChET00pb2JqOwotICAgICAgICAgICByZXR1cm4gbmV3IFNpbmdsZXRvbkl0ZXJhdG9yKGRvbS5nZXREb2N1bWVudCgpLCB0cnVlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChvYmogaW5zdGFuY2VvZiBEVE1BeGlzSXRlcmF0b3IpIHsKLSAgICAgICAgICAgcmV0dXJuIChEVE1BeGlzSXRlcmF0b3IpIG9iajsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIGZpbmFsIFN0cmluZyBjbGFzc05hbWUgPSBvYmouZ2V0Q2xhc3MoKS5nZXROYW1lKCk7Ci0gICAgICAgICAgICBydW5UaW1lRXJyb3IoREFUQV9DT05WRVJTSU9OX0VSUiwgIm5vZGUtc2V0IiwgY2xhc3NOYW1lKTsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLy8tLSBCZWdpbiB1dGlsaXR5IGZ1bmN0aW9ucwotCi0gICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBpc1doaXRlU3BhY2UoY2hhciBjaCkgewotICAgICAgICByZXR1cm4gY2ggPT0gJyAnIHx8IGNoID09ICdcdCcgfHwgY2ggPT0gJ1xuJyB8fCBjaCA9PSAnXHInOwotICAgIH0KLQotICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gY29tcGFyZVN0cmluZ3MoU3RyaW5nIGxzdHJpbmcsIFN0cmluZyByc3RyaW5nLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG9wLCBET00gZG9tKSB7Ci0gICAgICAgIHN3aXRjaCAob3ApIHsKLSAgICBjYXNlIE9wZXJhdG9ycy5FUToKLSAgICAgICAgICAgIHJldHVybiBsc3RyaW5nLmVxdWFscyhyc3RyaW5nKTsKLQotICAgIGNhc2UgT3BlcmF0b3JzLk5FOgotICAgICAgICAgICAgcmV0dXJuICFsc3RyaW5nLmVxdWFscyhyc3RyaW5nKTsKLQotICAgIGNhc2UgT3BlcmF0b3JzLkdUOgotICAgICAgICAgICAgcmV0dXJuIG51bWJlckYobHN0cmluZywgZG9tKSA+IG51bWJlckYocnN0cmluZywgZG9tKTsKLQotICAgIGNhc2UgT3BlcmF0b3JzLkxUOgotICAgICAgICAgICAgcmV0dXJuIG51bWJlckYobHN0cmluZywgZG9tKSA8IG51bWJlckYocnN0cmluZywgZG9tKTsKLQotICAgIGNhc2UgT3BlcmF0b3JzLkdFOgotICAgICAgICAgICAgcmV0dXJuIG51bWJlckYobHN0cmluZywgZG9tKSA+PSBudW1iZXJGKHJzdHJpbmcsIGRvbSk7Ci0KLSAgICBjYXNlIE9wZXJhdG9ycy5MRToKLSAgICAgICAgICAgIHJldHVybiBudW1iZXJGKGxzdHJpbmcsIGRvbSkgPD0gbnVtYmVyRihyc3RyaW5nLCBkb20pOwotCi0gICAgICAgIGRlZmF1bHQ6Ci0gICAgICAgICAgICBydW5UaW1lRXJyb3IoUlVOX1RJTUVfSU5URVJOQUxfRVJSLCAiY29tcGFyZSgpIik7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBVdGlsaXR5IGZ1bmN0aW9uOiBub2RlLXNldC9ub2RlLXNldCBjb21wYXJlLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBjb21wYXJlKERUTUF4aXNJdGVyYXRvciBsZWZ0LCBEVE1BeGlzSXRlcmF0b3IgcmlnaHQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG9wLCBET00gZG9tKSB7Ci0gICAgICAgIGludCBsbm9kZTsKLSAgICAgICAgbGVmdC5yZXNldCgpOwotCi0gICAgICAgIHdoaWxlICgobG5vZGUgPSBsZWZ0Lm5leHQoKSkgIT0gRFRNQXhpc0l0ZXJhdG9yLkVORCkgewotICAgICAgICAgICAgZmluYWwgU3RyaW5nIGx2YWx1ZSA9IGRvbS5nZXRTdHJpbmdWYWx1ZVgobG5vZGUpOwotCi0gICAgICAgICAgICBpbnQgcm5vZGU7Ci0gICAgICAgICAgICByaWdodC5yZXNldCgpOwotICAgICAgICAgICAgd2hpbGUgKChybm9kZSA9IHJpZ2h0Lm5leHQoKSkgIT0gRFRNQXhpc0l0ZXJhdG9yLkVORCkgewotICAgICAgICAgICAgICAgIC8vIFN0cmluZyB2YWx1ZSBtdXN0IGJlIHRoZSBzYW1lIGlmIGJvdGggbm9kZXMgYXJlIHRoZSBzYW1lCi0gICAgICAgICAgICAgICAgaWYgKGxub2RlID09IHJub2RlKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChvcCA9PSBPcGVyYXRvcnMuRVEpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG9wID09IE9wZXJhdG9ycy5ORSkgewotICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaWYgKGNvbXBhcmVTdHJpbmdzKGx2YWx1ZSwgZG9tLmdldFN0cmluZ1ZhbHVlWChybm9kZSksIG9wLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb20pKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgcHVibGljIHN0YXRpYyBib29sZWFuIGNvbXBhcmUoaW50IG5vZGUsIERUTUF4aXNJdGVyYXRvciBpdGVyYXRvciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgb3AsIERPTSBkb20pIHsKLSAgICAgICAgLy9pdGVyYXRvci5yZXNldCgpOwotCi0gICAgICAgIGludCBybm9kZTsKLSAgICAgICAgU3RyaW5nIHZhbHVlOwotCi0gICAgICAgIHN3aXRjaChvcCkgewotICAgIGNhc2UgT3BlcmF0b3JzLkVROgotICAgICAgICAgICAgcm5vZGUgPSBpdGVyYXRvci5uZXh0KCk7Ci0gICAgICAgICAgICBpZiAocm5vZGUgIT0gRFRNQXhpc0l0ZXJhdG9yLkVORCkgewotICAgICAgICAgICAgICAgIHZhbHVlID0gZG9tLmdldFN0cmluZ1ZhbHVlWChub2RlKTsKLSAgICAgICAgICAgICAgICBkbyB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChub2RlID09IHJub2RlCi0gICAgICAgICAgICAgICAgICAgICAgICAgIHx8IHZhbHVlLmVxdWFscyhkb20uZ2V0U3RyaW5nVmFsdWVYKHJub2RlKSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9IHdoaWxlICgocm5vZGUgPSBpdGVyYXRvci5uZXh0KCkpICE9IERUTUF4aXNJdGVyYXRvci5FTkQpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgYnJlYWs7Ci0gICAgY2FzZSBPcGVyYXRvcnMuTkU6Ci0gICAgICAgICAgICBybm9kZSA9IGl0ZXJhdG9yLm5leHQoKTsKLSAgICAgICAgICAgIGlmIChybm9kZSAhPSBEVE1BeGlzSXRlcmF0b3IuRU5EKSB7Ci0gICAgICAgICAgICAgICAgdmFsdWUgPSBkb20uZ2V0U3RyaW5nVmFsdWVYKG5vZGUpOwotICAgICAgICAgICAgICAgIGRvIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKG5vZGUgIT0gcm5vZGUKLSAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgIXZhbHVlLmVxdWFscyhkb20uZ2V0U3RyaW5nVmFsdWVYKHJub2RlKSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfSB3aGlsZSAoKHJub2RlID0gaXRlcmF0b3IubmV4dCgpKSAhPSBEVE1BeGlzSXRlcmF0b3IuRU5EKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGJyZWFrOwotICAgIGNhc2UgT3BlcmF0b3JzLkxUOgotICAgICAgICAgICAgLy8gQXNzdW1lIHdlJ3JlIGNvbXBhcmluZyBkb2N1bWVudCBvcmRlciBoZXJlCi0gICAgICAgICAgICB3aGlsZSAoKHJub2RlID0gaXRlcmF0b3IubmV4dCgpKSAhPSBEVE1BeGlzSXRlcmF0b3IuRU5EKSB7Ci0gICAgICAgICAgICAgICAgaWYgKHJub2RlID4gbm9kZSkgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBicmVhazsKLSAgICBjYXNlIE9wZXJhdG9ycy5HVDoKLSAgICAgICAgICAgIC8vIEFzc3VtZSB3ZSdyZSBjb21wYXJpbmcgZG9jdW1lbnQgb3JkZXIgaGVyZQotICAgICAgICAgICAgd2hpbGUgKChybm9kZSA9IGl0ZXJhdG9yLm5leHQoKSkgIT0gRFRNQXhpc0l0ZXJhdG9yLkVORCkgewotICAgICAgICAgICAgICAgIGlmIChybm9kZSA8IG5vZGUpIHJldHVybiB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuKGZhbHNlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBVdGlsaXR5IGZ1bmN0aW9uOiBub2RlLXNldC9udW1iZXIgY29tcGFyZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gY29tcGFyZShEVE1BeGlzSXRlcmF0b3IgbGVmdCwgZmluYWwgZG91YmxlIHJudW1iZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IG9wLCBET00gZG9tKSB7Ci0gICAgICAgIGludCBub2RlOwotICAgICAgICAvL2xlZnQucmVzZXQoKTsKLQotICAgICAgICBzd2l0Y2ggKG9wKSB7Ci0gICAgY2FzZSBPcGVyYXRvcnMuRVE6Ci0gICAgICAgICAgICB3aGlsZSAoKG5vZGUgPSBsZWZ0Lm5leHQoKSkgIT0gRFRNQXhpc0l0ZXJhdG9yLkVORCkgewotICAgICAgICAgICAgICAgIGlmIChudW1iZXJGKGRvbS5nZXRTdHJpbmdWYWx1ZVgobm9kZSksIGRvbSkgPT0gcm51bWJlcikKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBicmVhazsKLQotICAgIGNhc2UgT3BlcmF0b3JzLk5FOgotICAgICAgICAgICAgd2hpbGUgKChub2RlID0gbGVmdC5uZXh0KCkpICE9IERUTUF4aXNJdGVyYXRvci5FTkQpIHsKLSAgICAgICAgICAgICAgICBpZiAobnVtYmVyRihkb20uZ2V0U3RyaW5nVmFsdWVYKG5vZGUpLCBkb20pICE9IHJudW1iZXIpCi0gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICBjYXNlIE9wZXJhdG9ycy5HVDoKLSAgICAgICAgICAgIHdoaWxlICgobm9kZSA9IGxlZnQubmV4dCgpKSAhPSBEVE1BeGlzSXRlcmF0b3IuRU5EKSB7Ci0gICAgICAgICAgICAgICAgaWYgKG51bWJlckYoZG9tLmdldFN0cmluZ1ZhbHVlWChub2RlKSwgZG9tKSA+IHJudW1iZXIpCi0gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICBjYXNlIE9wZXJhdG9ycy5MVDoKLSAgICAgICAgICAgIHdoaWxlICgobm9kZSA9IGxlZnQubmV4dCgpKSAhPSBEVE1BeGlzSXRlcmF0b3IuRU5EKSB7Ci0gICAgICAgICAgICAgICAgaWYgKG51bWJlckYoZG9tLmdldFN0cmluZ1ZhbHVlWChub2RlKSwgZG9tKSA8IHJudW1iZXIpCi0gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICBjYXNlIE9wZXJhdG9ycy5HRToKLSAgICAgICAgICAgIHdoaWxlICgobm9kZSA9IGxlZnQubmV4dCgpKSAhPSBEVE1BeGlzSXRlcmF0b3IuRU5EKSB7Ci0gICAgICAgICAgICAgICAgaWYgKG51bWJlckYoZG9tLmdldFN0cmluZ1ZhbHVlWChub2RlKSwgZG9tKSA+PSBybnVtYmVyKQotICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGJyZWFrOwotCi0gICAgY2FzZSBPcGVyYXRvcnMuTEU6Ci0gICAgICAgICAgICB3aGlsZSAoKG5vZGUgPSBsZWZ0Lm5leHQoKSkgIT0gRFRNQXhpc0l0ZXJhdG9yLkVORCkgewotICAgICAgICAgICAgICAgIGlmIChudW1iZXJGKGRvbS5nZXRTdHJpbmdWYWx1ZVgobm9kZSksIGRvbSkgPD0gcm51bWJlcikKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBicmVhazsKLQotICAgICAgICBkZWZhdWx0OgotICAgICAgICAgICAgcnVuVGltZUVycm9yKFJVTl9USU1FX0lOVEVSTkFMX0VSUiwgImNvbXBhcmUoKSIpOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFV0aWxpdHkgZnVuY3Rpb246IG5vZGUtc2V0L3N0cmluZyBjb21wYXJpc29uLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBjb21wYXJlKERUTUF4aXNJdGVyYXRvciBsZWZ0LCBmaW5hbCBTdHJpbmcgcnN0cmluZywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgb3AsIERPTSBkb20pIHsKLSAgICAgICAgaW50IG5vZGU7Ci0gICAgICAgIC8vbGVmdC5yZXNldCgpOwotICAgICAgICB3aGlsZSAoKG5vZGUgPSBsZWZ0Lm5leHQoKSkgIT0gRFRNQXhpc0l0ZXJhdG9yLkVORCkgewotICAgICAgICAgICAgaWYgKGNvbXBhcmVTdHJpbmdzKGRvbS5nZXRTdHJpbmdWYWx1ZVgobm9kZSksIHJzdHJpbmcsIG9wLCBkb20pKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotCi0gICAgcHVibGljIHN0YXRpYyBib29sZWFuIGNvbXBhcmUoT2JqZWN0IGxlZnQsIE9iamVjdCByaWdodCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgb3AsIERPTSBkb20pCi0gICAgewotICAgICAgICBib29sZWFuIHJlc3VsdCA9IGZhbHNlOwotICAgICAgICBib29sZWFuIGhhc1NpbXBsZUFyZ3MgPSBoYXNTaW1wbGVUeXBlKGxlZnQpICYmIGhhc1NpbXBsZVR5cGUocmlnaHQpOwotCi0gICAgaWYgKG9wICE9IE9wZXJhdG9ycy5FUSAmJiBvcCAhPSBPcGVyYXRvcnMuTkUpIHsKLSAgICAgICAgICAgIC8vIElmIG5vZGUtYm9vbGVhbiBjb21wYXJpc29uIC0+IGNvbnZlcnQgbm9kZSB0byBib29sZWFuCi0gICAgICAgICAgICBpZiAobGVmdCBpbnN0YW5jZW9mIE5vZGUgfHwgcmlnaHQgaW5zdGFuY2VvZiBOb2RlKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGxlZnQgaW5zdGFuY2VvZiBCb29sZWFuKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJpZ2h0ID0gbmV3IEJvb2xlYW4oYm9vbGVhbkYocmlnaHQpKTsKLSAgICAgICAgICAgICAgICAgICAgaGFzU2ltcGxlQXJncyA9IHRydWU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGlmIChyaWdodCBpbnN0YW5jZW9mIEJvb2xlYW4pIHsKLSAgICAgICAgICAgICAgICAgICAgbGVmdCA9IG5ldyBCb29sZWFuKGJvb2xlYW5GKGxlZnQpKTsKLSAgICAgICAgICAgICAgICAgICAgaGFzU2ltcGxlQXJncyA9IHRydWU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAoaGFzU2ltcGxlQXJncykgewotICAgICAgICAgICAgICAgIHN3aXRjaCAob3ApIHsKLSAgICAgICAgY2FzZSBPcGVyYXRvcnMuR1Q6Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBudW1iZXJGKGxlZnQsIGRvbSkgPiBudW1iZXJGKHJpZ2h0LCBkb20pOwotCi0gICAgICAgIGNhc2UgT3BlcmF0b3JzLkxUOgotICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVtYmVyRihsZWZ0LCBkb20pIDwgbnVtYmVyRihyaWdodCwgZG9tKTsKLQotICAgICAgICBjYXNlIE9wZXJhdG9ycy5HRToKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bWJlckYobGVmdCwgZG9tKSA+PSBudW1iZXJGKHJpZ2h0LCBkb20pOwotCi0gICAgICAgIGNhc2UgT3BlcmF0b3JzLkxFOgotICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVtYmVyRihsZWZ0LCBkb20pIDw9IG51bWJlckYocmlnaHQsIGRvbSk7Ci0KLSAgICAgICAgZGVmYXVsdDoKLSAgICAgICAgICAgICAgICAgICAgcnVuVGltZUVycm9yKFJVTl9USU1FX0lOVEVSTkFMX0VSUiwgImNvbXBhcmUoKSIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIGZhbGxzIHRocm91Z2gKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChoYXNTaW1wbGVBcmdzKSB7Ci0gICAgICAgICAgICBpZiAobGVmdCBpbnN0YW5jZW9mIEJvb2xlYW4gfHwgcmlnaHQgaW5zdGFuY2VvZiBCb29sZWFuKSB7Ci0gICAgICAgICAgICAgICAgcmVzdWx0ID0gYm9vbGVhbkYobGVmdCkgPT0gYm9vbGVhbkYocmlnaHQpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAobGVmdCBpbnN0YW5jZW9mIERvdWJsZSB8fCByaWdodCBpbnN0YW5jZW9mIERvdWJsZSB8fAotICAgICAgICAgICAgICAgICAgICAgbGVmdCBpbnN0YW5jZW9mIEludGVnZXIgfHwgcmlnaHQgaW5zdGFuY2VvZiBJbnRlZ2VyKSB7Ci0gICAgICAgICAgICAgICAgcmVzdWx0ID0gbnVtYmVyRihsZWZ0LCBkb20pID09IG51bWJlckYocmlnaHQsIGRvbSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsgLy8gY29tcGFyZSB0aGVtIGFzIHN0cmluZ3MKLSAgICAgICAgICAgICAgICByZXN1bHQgPSBzdHJpbmdGKGxlZnQsIGRvbSkuZXF1YWxzKHN0cmluZ0YocmlnaHQsIGRvbSkpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAob3AgPT0gT3BlcmF0b3JzLk5FKSB7Ci0gICAgICAgICAgICAgICAgcmVzdWx0ID0gIXJlc3VsdDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIGlmIChsZWZ0IGluc3RhbmNlb2YgTm9kZSkgewotICAgICAgICAgICAgICAgIGxlZnQgPSBuZXcgU2luZ2xldG9uSXRlcmF0b3IoKChOb2RlKWxlZnQpLm5vZGUpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKHJpZ2h0IGluc3RhbmNlb2YgTm9kZSkgewotICAgICAgICAgICAgICAgIHJpZ2h0ID0gbmV3IFNpbmdsZXRvbkl0ZXJhdG9yKCgoTm9kZSlyaWdodCkubm9kZSk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmIChoYXNTaW1wbGVUeXBlKGxlZnQpIHx8Ci0gICAgICAgICAgICAgICAgbGVmdCBpbnN0YW5jZW9mIERPTSAmJiByaWdodCBpbnN0YW5jZW9mIERUTUF4aXNJdGVyYXRvcikgewotICAgICAgICAgICAgICAgIC8vIHN3YXAgb3BlcmFuZHMgYW5kIG9wZXJhdG9yCi0gICAgICAgICAgICAgICAgZmluYWwgT2JqZWN0IHRlbXAgPSByaWdodDsgcmlnaHQgPSBsZWZ0OyBsZWZ0ID0gdGVtcDsKLSAgICAgICAgICAgICAgICBvcCA9IE9wZXJhdG9ycy5zd2FwT3Aob3ApOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAobGVmdCBpbnN0YW5jZW9mIERPTSkgewotICAgICAgICAgICAgICAgIGlmIChyaWdodCBpbnN0YW5jZW9mIEJvb2xlYW4pIHsKLSAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gKChCb29sZWFuKXJpZ2h0KS5ib29sZWFuVmFsdWUoKTsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdCA9PSAob3AgPT0gT3BlcmF0b3JzLkVRKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgc2xlZnQgPSAoKERPTSlsZWZ0KS5nZXRTdHJpbmdWYWx1ZSgpOwotCi0gICAgICAgICAgICAgICAgaWYgKHJpZ2h0IGluc3RhbmNlb2YgTnVtYmVyKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9ICgoTnVtYmVyKXJpZ2h0KS5kb3VibGVWYWx1ZSgpID09Ci0gICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmdUb1JlYWwoc2xlZnQpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIGlmIChyaWdodCBpbnN0YW5jZW9mIFN0cmluZykgewotICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBzbGVmdC5lcXVhbHMoKFN0cmluZylyaWdodCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgaWYgKHJpZ2h0IGluc3RhbmNlb2YgRE9NKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IHNsZWZ0LmVxdWFscygoKERPTSlyaWdodCkuZ2V0U3RyaW5nVmFsdWUoKSk7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgaWYgKG9wID09IE9wZXJhdG9ycy5ORSkgewotICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSAhcmVzdWx0OwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0OwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBOZXh0LCBub2RlLXNldC90IGZvciB0IGluIHtyZWFsLCBzdHJpbmcsIG5vZGUtc2V0LCByZXN1bHQtdHJlZX0KLQotICAgICAgICAgICAgRFRNQXhpc0l0ZXJhdG9yIGl0ZXIgPSAoKERUTUF4aXNJdGVyYXRvcilsZWZ0KS5yZXNldCgpOwotCi0gICAgICAgICAgICBpZiAocmlnaHQgaW5zdGFuY2VvZiBEVE1BeGlzSXRlcmF0b3IpIHsKLSAgICAgICAgICAgICAgICByZXN1bHQgPSBjb21wYXJlKGl0ZXIsIChEVE1BeGlzSXRlcmF0b3IpcmlnaHQsIG9wLCBkb20pOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAocmlnaHQgaW5zdGFuY2VvZiBTdHJpbmcpIHsKLSAgICAgICAgICAgICAgICByZXN1bHQgPSBjb21wYXJlKGl0ZXIsIChTdHJpbmcpcmlnaHQsIG9wLCBkb20pOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAocmlnaHQgaW5zdGFuY2VvZiBOdW1iZXIpIHsKLSAgICAgICAgICAgICAgICBmaW5hbCBkb3VibGUgdGVtcCA9ICgoTnVtYmVyKXJpZ2h0KS5kb3VibGVWYWx1ZSgpOwotICAgICAgICAgICAgICAgIHJlc3VsdCA9IGNvbXBhcmUoaXRlciwgdGVtcCwgb3AsIGRvbSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChyaWdodCBpbnN0YW5jZW9mIEJvb2xlYW4pIHsKLSAgICAgICAgICAgICAgICBib29sZWFuIHRlbXAgPSAoKEJvb2xlYW4pcmlnaHQpLmJvb2xlYW5WYWx1ZSgpOwotICAgICAgICAgICAgICAgIHJlc3VsdCA9IChpdGVyLnJlc2V0KCkubmV4dCgpICE9IERUTUF4aXNJdGVyYXRvci5FTkQpID09IHRlbXA7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChyaWdodCBpbnN0YW5jZW9mIERPTSkgewotICAgICAgICAgICAgICAgIHJlc3VsdCA9IGNvbXBhcmUoaXRlciwgKChET00pcmlnaHQpLmdldFN0cmluZ1ZhbHVlKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcCwgZG9tKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKHJpZ2h0ID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4oZmFsc2UpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIGNsYXNzTmFtZSA9IHJpZ2h0LmdldENsYXNzKCkuZ2V0TmFtZSgpOwotICAgICAgICAgICAgICAgIHJ1blRpbWVFcnJvcihJTlZBTElEX0FSR1VNRU5UX0VSUiwgY2xhc3NOYW1lLCAiY29tcGFyZSgpIik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHJlc3VsdDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBVdGlsaXR5IGZ1bmN0aW9uOiB1c2VkIHRvIHRlc3QgY29udGV4dCBub2RlJ3MgbGFuZ3VhZ2UKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gdGVzdExhbmd1YWdlKFN0cmluZyB0ZXN0TGFuZywgRE9NIGRvbSwgaW50IG5vZGUpIHsKLSAgICAgICAgLy8gbGFuZ3VhZ2UgZm9yIGNvbnRleHQgbm9kZSAoaWYgYW55KQotICAgICAgICBTdHJpbmcgbm9kZUxhbmcgPSBkb20uZ2V0TGFuZ3VhZ2Uobm9kZSk7Ci0gICAgICAgIGlmIChub2RlTGFuZyA9PSBudWxsKQotICAgICAgICAgICAgcmV0dXJuKGZhbHNlKTsKLSAgICAgICAgZWxzZQotICAgICAgICAgICAgbm9kZUxhbmcgPSBub2RlTGFuZy50b0xvd2VyQ2FzZSgpOwotCi0gICAgICAgIC8vIGNvbXBhcmUgY29udGV4dCBub2RlJ3MgbGFuZ3VhZ2UgYWdhaW5zIHRlc3QgbGFuZ3VhZ2UKLSAgICAgICAgdGVzdExhbmcgPSB0ZXN0TGFuZy50b0xvd2VyQ2FzZSgpOwotICAgICAgICBpZiAodGVzdExhbmcubGVuZ3RoKCkgPT0gMikgewotICAgICAgICAgICAgcmV0dXJuKG5vZGVMYW5nLnN0YXJ0c1dpdGgodGVzdExhbmcpKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybihub2RlTGFuZy5lcXVhbHModGVzdExhbmcpKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaGFzU2ltcGxlVHlwZShPYmplY3Qgb2JqKSB7Ci0gICAgICAgIHJldHVybiBvYmogaW5zdGFuY2VvZiBCb29sZWFuIHx8IG9iaiBpbnN0YW5jZW9mIERvdWJsZSB8fAotICAgICAgICAgICAgb2JqIGluc3RhbmNlb2YgSW50ZWdlciB8fCBvYmogaW5zdGFuY2VvZiBTdHJpbmcgfHwKLSAgICAgICAgICAgIG9iaiBpbnN0YW5jZW9mIE5vZGUgfHwgb2JqIGluc3RhbmNlb2YgRE9NOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFV0aWxpdHkgZnVuY3Rpb246IHVzZWQgaW4gU3RyaW5nVHlwZSB0byBjb252ZXJ0IGEgc3RyaW5nIHRvIGEgcmVhbC4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGRvdWJsZSBzdHJpbmdUb1JlYWwoU3RyaW5nIHMpIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIHJldHVybiBEb3VibGUudmFsdWVPZihzKS5kb3VibGVWYWx1ZSgpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgcmV0dXJuIERvdWJsZS5OYU47Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBVdGlsaXR5IGZ1bmN0aW9uOiB1c2VkIGluIFN0cmluZ1R5cGUgdG8gY29udmVydCBhIHN0cmluZyB0byBhbiBpbnQuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBpbnQgc3RyaW5nVG9JbnQoU3RyaW5nIHMpIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIHJldHVybiBJbnRlZ2VyLnBhcnNlSW50KHMpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgcmV0dXJuKC0xKTsgLy8gPz8/Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgRE9VQkxFX0ZSQUNUSU9OX0RJR0lUUyA9IDM0MDsKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBkb3VibGUgbG93ZXJCb3VuZHMgPSAwLjAwMTsKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBkb3VibGUgdXBwZXJCb3VuZHMgPSAxMDAwMDAwMDsKLSAgICBwcml2YXRlIHN0YXRpYyBEZWNpbWFsRm9ybWF0IGRlZmF1bHRGb3JtYXR0ZXIsIHhwYXRoRm9ybWF0dGVyOwotICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBkZWZhdWx0UGF0dGVybiA9ICIiOwotCi0gICAgc3RhdGljIHsKLSAgICAgICAgTnVtYmVyRm9ybWF0IGYgPSBOdW1iZXJGb3JtYXQuZ2V0SW5zdGFuY2UoTG9jYWxlLmdldERlZmF1bHQoKSk7Ci0gICAgICAgIGRlZmF1bHRGb3JtYXR0ZXIgPSAoZiBpbnN0YW5jZW9mIERlY2ltYWxGb3JtYXQpID8KLSAgICAgICAgICAgIChEZWNpbWFsRm9ybWF0KSBmIDogbmV3IERlY2ltYWxGb3JtYXQoKTsKLSAgICAgICAgLy8gU2V0IG1heCBmcmFjdGlvbiBkaWdpdHMgc28gdGhhdCB0cnVuY2F0aW9uIGRvZXMgbm90IG9jY3VyLiBTZXR0aW5nCi0gICAgICAgIC8vIHRoZSBtYXggdG8gSW50ZWdlci5NQVhfVkFMVUUgbWF5IGNhdXNlIHByb2JsZW1zIHdpdGggc29tZSBKREsncy4KLSAgICAgICAgZGVmYXVsdEZvcm1hdHRlci5zZXRNYXhpbXVtRnJhY3Rpb25EaWdpdHMoRE9VQkxFX0ZSQUNUSU9OX0RJR0lUUyk7Ci0gICAgICAgIGRlZmF1bHRGb3JtYXR0ZXIuc2V0TWluaW11bUZyYWN0aW9uRGlnaXRzKDApOwotICAgICAgICBkZWZhdWx0Rm9ybWF0dGVyLnNldE1pbmltdW1JbnRlZ2VyRGlnaXRzKDEpOwotICAgICAgICBkZWZhdWx0Rm9ybWF0dGVyLnNldEdyb3VwaW5nVXNlZChmYWxzZSk7Ci0KLSAgICAgICAgLy8gVGhpcyBmb3JtYXR0ZXIgaXMgdXNlZCB0byBjb252ZXJ0IG51bWJlcnMgYWNjb3JkaW5nIHRvIHRoZSBYUGF0aAotICAgICAgICAvLyAxLjAgc3ludGF4IHdoaWNoIGlnbm9yZXMgbG9jYWxlcyAoaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGgjTlQtTnVtYmVyKQotICAgICAgICB4cGF0aEZvcm1hdHRlciA9IG5ldyBEZWNpbWFsRm9ybWF0KCIiLAotICAgICAgICAgICAgbmV3IERlY2ltYWxGb3JtYXRTeW1ib2xzKExvY2FsZS5VUykpOwotICAgICAgICB4cGF0aEZvcm1hdHRlci5zZXRNYXhpbXVtRnJhY3Rpb25EaWdpdHMoRE9VQkxFX0ZSQUNUSU9OX0RJR0lUUyk7Ci0gICAgICAgIHhwYXRoRm9ybWF0dGVyLnNldE1pbmltdW1GcmFjdGlvbkRpZ2l0cygwKTsKLSAgICAgICAgeHBhdGhGb3JtYXR0ZXIuc2V0TWluaW11bUludGVnZXJEaWdpdHMoMSk7Ci0gICAgICAgIHhwYXRoRm9ybWF0dGVyLnNldEdyb3VwaW5nVXNlZChmYWxzZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVXRpbGl0eSBmdW5jdGlvbjogdXNlZCBpbiBSZWFsVHlwZSB0byBjb252ZXJ0IGEgcmVhbCB0byBhIHN0cmluZy4KLSAgICAgKiBSZW1vdmVzIHRoZSBkZWNpbWFsIGlmIG51bGwuIFVzZXMgYSBzcGVjaWFsaXplZCBmb3JtYXR0ZXIgb2JqZWN0Ci0gICAgICogZm9yIHZlcnkgbGFyZ2UgYW5kIHZlcnkgc21hbGwgbnVtYmVycyB0aGF0IGlnbm9yZXMgbG9jYWxlcywgdGh1cwotICAgICAqIHVzaW5nIGFsd2F5cyB1c2luZyAiLiIgYXMgYSBkZWNpbWFsIHNlcGFyYXRvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFN0cmluZyByZWFsVG9TdHJpbmcoZG91YmxlIGQpIHsKLSAgICAgICAgZmluYWwgZG91YmxlIG0gPSBNYXRoLmFicyhkKTsKLSAgICAgICAgaWYgKChtID49IGxvd2VyQm91bmRzKSAmJiAobSA8IHVwcGVyQm91bmRzKSkgewotICAgICAgICAgICAgZmluYWwgU3RyaW5nIHJlc3VsdCA9IERvdWJsZS50b1N0cmluZyhkKTsKLSAgICAgICAgICAgIGZpbmFsIGludCBsZW5ndGggPSByZXN1bHQubGVuZ3RoKCk7Ci0gICAgICAgICAgICAvLyBSZW1vdmUgbGVhZGluZyB6ZXJvcy4KLSAgICAgICAgICAgIGlmICgocmVzdWx0LmNoYXJBdChsZW5ndGgtMikgPT0gJy4nKSAmJgotICAgICAgICAgICAgICAgIChyZXN1bHQuY2hhckF0KGxlbmd0aC0xKSA9PSAnMCcpKQotICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQuc3Vic3RyaW5nKDAsIGxlbmd0aC0yKTsKLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0OwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgaWYgKERvdWJsZS5pc05hTihkKSB8fCBEb3VibGUuaXNJbmZpbml0ZShkKSkKLSAgICAgICAgICAgICAgICByZXR1cm4oRG91YmxlLnRvU3RyaW5nKGQpKTsKLQotICAgICAgICAgICAgLy9Db252ZXJ0IC0wLjAgdG8gKzAuMCBvdGhlciB2YWx1ZXMgcmVtYWlucyB0aGUgc2FtZQotICAgICAgICAgICAgZCA9IGQgKyAwLjA7Ci0KLSAgICAgICAgICAgIC8vIFVzZSB0aGUgWFBhdGggZm9ybWF0dGVyIHRvIGlnbm9yZSBsb2NhbGVzCi0gICAgICAgICAgICBTdHJpbmdCdWZmZXIgcmVzdWx0ID0gdGhyZWFkTG9jYWxTdHJpbmdCdWZmZXIuZ2V0KCk7Ci0gICAgICAgICAgICByZXN1bHQuc2V0TGVuZ3RoKDApOwotICAgICAgICAgICAgeHBhdGhGb3JtYXR0ZXIuZm9ybWF0KGQsIHJlc3VsdCwgX2ZpZWxkUG9zaXRpb24pOwotICAgICAgICAgICAgcmV0dXJuIHJlc3VsdC50b1N0cmluZygpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVXRpbGl0eSBmdW5jdGlvbjogdXNlZCBpbiBSZWFsVHlwZSB0byBjb252ZXJ0IGEgcmVhbCB0byBhbiBpbnRlZ2VyCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBpbnQgcmVhbFRvSW50KGRvdWJsZSBkKSB7Ci0gICAgICAgIHJldHVybiAoaW50KWQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVXRpbGl0eSBmdW5jdGlvbjogdXNlZCB0byBmb3JtYXQvYWRqdXN0ICBhIGRvdWJsZSB0byBhIHN0cmluZy4gVGhlCi0gICAgICogRGVjaW1hbEZvcm1hdCBvYmplY3QgY29tZXMgZnJvbSB0aGUgJ2Zvcm1hdFN5bWJvbHMnIG1hcCBpbgotICAgICAqIEFic3RyYWN0VHJhbnNsZXQuCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgRmllbGRQb3NpdGlvbiBfZmllbGRQb3NpdGlvbiA9IG5ldyBGaWVsZFBvc2l0aW9uKDApOwotCi0gICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZm9ybWF0TnVtYmVyKGRvdWJsZSBudW1iZXIsIFN0cmluZyBwYXR0ZXJuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEZWNpbWFsRm9ybWF0IGZvcm1hdHRlcikgewotICAgICAgICAvLyBidWd6aWxsYSBmaXggMTI4MTMKLSAgICAgICAgaWYgKGZvcm1hdHRlciA9PSBudWxsKSB7Ci0gICAgICAgICAgICBmb3JtYXR0ZXIgPSBkZWZhdWx0Rm9ybWF0dGVyOwotICAgICAgICB9Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBTdHJpbmdCdWZmZXIgcmVzdWx0ID0gdGhyZWFkTG9jYWxTdHJpbmdCdWZmZXIuZ2V0KCk7Ci0gICAgICAgIHJlc3VsdC5zZXRMZW5ndGgoMCk7Ci0gICAgICAgICAgICBpZiAocGF0dGVybiAhPSBkZWZhdWx0UGF0dGVybikgewotICAgICAgICAgICAgICAgIGZvcm1hdHRlci5hcHBseUxvY2FsaXplZFBhdHRlcm4ocGF0dGVybik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIGZvcm1hdHRlci5mb3JtYXQobnVtYmVyLCByZXN1bHQsIF9maWVsZFBvc2l0aW9uKTsKLSAgICAgICAgICAgIHJldHVybiByZXN1bHQudG9TdHJpbmcoKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIHJ1blRpbWVFcnJvcihGT1JNQVRfTlVNQkVSX0VSUiwgRG91YmxlLnRvU3RyaW5nKG51bWJlciksIHBhdHRlcm4pOwotICAgICAgICAgICAgcmV0dXJuKEVNUFRZU1RSSU5HKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFV0aWxpdHkgZnVuY3Rpb246IHVzZWQgdG8gY29udmVydCByZWZlcmVuY2VzIHRvIG5vZGUtc2V0cy4gSWYgdGhlCi0gICAgICogb2JqIGlzIGFuIGluc3RhbmNlb2YgTm9kZSB0aGVuIGNyZWF0ZSBhIHNpbmdsZXRvbiBpdGVyYXRvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIERUTUF4aXNJdGVyYXRvciByZWZlcmVuY2VUb05vZGVTZXQoT2JqZWN0IG9iaikgewotICAgICAgICAvLyBDb252ZXJ0IHZhci9wYXJhbSAtPiBub2RlCi0gICAgICAgIGlmIChvYmogaW5zdGFuY2VvZiBOb2RlKSB7Ci0gICAgICAgICAgICByZXR1cm4obmV3IFNpbmdsZXRvbkl0ZXJhdG9yKCgoTm9kZSlvYmopLm5vZGUpKTsKLSAgICAgICAgfQotICAgICAgICAvLyBDb252ZXJ0IHZhci9wYXJhbSAtPiBub2RlLXNldAotICAgICAgICBlbHNlIGlmIChvYmogaW5zdGFuY2VvZiBEVE1BeGlzSXRlcmF0b3IpIHsKLSAgICAgICAgICAgIHJldHVybigoKERUTUF4aXNJdGVyYXRvcilvYmopLmNsb25lSXRlcmF0b3IoKS5yZXNldCgpKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIGZpbmFsIFN0cmluZyBjbGFzc05hbWUgPSBvYmouZ2V0Q2xhc3MoKS5nZXROYW1lKCk7Ci0gICAgICAgICAgICBydW5UaW1lRXJyb3IoREFUQV9DT05WRVJTSU9OX0VSUiwgY2xhc3NOYW1lLCAibm9kZS1zZXQiKTsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVXRpbGl0eSBmdW5jdGlvbjogdXNlZCB0byBjb252ZXJ0IHJlZmVyZW5jZSB0byBvcmcudzNjLmRvbS5Ob2RlTGlzdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIE5vZGVMaXN0IHJlZmVyZW5jZVRvTm9kZUxpc3QoT2JqZWN0IG9iaiwgRE9NIGRvbSkgewotICAgICAgICBpZiAob2JqIGluc3RhbmNlb2YgTm9kZSB8fCBvYmogaW5zdGFuY2VvZiBEVE1BeGlzSXRlcmF0b3IpIHsKLSAgICAgICAgICAgIERUTUF4aXNJdGVyYXRvciBpdGVyID0gcmVmZXJlbmNlVG9Ob2RlU2V0KG9iaik7Ci0gICAgICAgICAgICByZXR1cm4gZG9tLm1ha2VOb2RlTGlzdChpdGVyKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChvYmogaW5zdGFuY2VvZiBET00pIHsKLSAgICAgICAgICBkb20gPSAoRE9NKW9iajsKLSAgICAgICAgICByZXR1cm4gZG9tLm1ha2VOb2RlTGlzdChEVE1EZWZhdWx0QmFzZS5ST09UTk9ERSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBmaW5hbCBTdHJpbmcgY2xhc3NOYW1lID0gb2JqLmdldENsYXNzKCkuZ2V0TmFtZSgpOwotICAgICAgICAgICAgcnVuVGltZUVycm9yKERBVEFfQ09OVkVSU0lPTl9FUlIsIGNsYXNzTmFtZSwKLSAgICAgICAgICAgICAgICAib3JnLnczYy5kb20uTm9kZUxpc3QiKTsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVXRpbGl0eSBmdW5jdGlvbjogdXNlZCB0byBjb252ZXJ0IHJlZmVyZW5jZSB0byBvcmcudzNjLmRvbS5Ob2RlLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgb3JnLnczYy5kb20uTm9kZSByZWZlcmVuY2VUb05vZGUoT2JqZWN0IG9iaiwgRE9NIGRvbSkgewotICAgICAgICBpZiAob2JqIGluc3RhbmNlb2YgTm9kZSB8fCBvYmogaW5zdGFuY2VvZiBEVE1BeGlzSXRlcmF0b3IpIHsKLSAgICAgICAgICAgIERUTUF4aXNJdGVyYXRvciBpdGVyID0gcmVmZXJlbmNlVG9Ob2RlU2V0KG9iaik7Ci0gICAgICAgICAgICByZXR1cm4gZG9tLm1ha2VOb2RlKGl0ZXIpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKG9iaiBpbnN0YW5jZW9mIERPTSkgewotICAgICAgICAgIGRvbSA9IChET00pb2JqOwotICAgICAgICAgIERUTUF4aXNJdGVyYXRvciBpdGVyID0gZG9tLmdldENoaWxkcmVuKERUTURlZmF1bHRCYXNlLlJPT1ROT0RFKTsKLSAgICAgICAgICByZXR1cm4gZG9tLm1ha2VOb2RlKGl0ZXIpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgZmluYWwgU3RyaW5nIGNsYXNzTmFtZSA9IG9iai5nZXRDbGFzcygpLmdldE5hbWUoKTsKLSAgICAgICAgICAgIHJ1blRpbWVFcnJvcihEQVRBX0NPTlZFUlNJT05fRVJSLCBjbGFzc05hbWUsICJvcmcudzNjLmRvbS5Ob2RlIik7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFV0aWxpdHkgZnVuY3Rpb246IHVzZWQgdG8gY29udmVydCByZWZlcmVuY2UgdG8gbG9uZy4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGxvbmcgcmVmZXJlbmNlVG9Mb25nKE9iamVjdCBvYmopIHsKLSAgICAgICAgaWYgKG9iaiBpbnN0YW5jZW9mIE51bWJlcikgewotICAgICAgICAgICAgcmV0dXJuICgoTnVtYmVyKSBvYmopLmxvbmdWYWx1ZSgpOyAgICAvLyBoYW5kbGVzIEludGVnZXIgYW5kIERvdWJsZQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgZmluYWwgU3RyaW5nIGNsYXNzTmFtZSA9IG9iai5nZXRDbGFzcygpLmdldE5hbWUoKTsKLSAgICAgICAgICAgIHJ1blRpbWVFcnJvcihEQVRBX0NPTlZFUlNJT05fRVJSLCBjbGFzc05hbWUsIExvbmcuVFlQRSk7Ci0gICAgICAgICAgICByZXR1cm4gMDsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFV0aWxpdHkgZnVuY3Rpb246IHVzZWQgdG8gY29udmVydCByZWZlcmVuY2UgdG8gZG91YmxlLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZG91YmxlIHJlZmVyZW5jZVRvRG91YmxlKE9iamVjdCBvYmopIHsKLSAgICAgICAgaWYgKG9iaiBpbnN0YW5jZW9mIE51bWJlcikgewotICAgICAgICAgICAgcmV0dXJuICgoTnVtYmVyKSBvYmopLmRvdWJsZVZhbHVlKCk7ICAgLy8gaGFuZGxlcyBJbnRlZ2VyIGFuZCBEb3VibGUKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIGZpbmFsIFN0cmluZyBjbGFzc05hbWUgPSBvYmouZ2V0Q2xhc3MoKS5nZXROYW1lKCk7Ci0gICAgICAgICAgICBydW5UaW1lRXJyb3IoREFUQV9DT05WRVJTSU9OX0VSUiwgY2xhc3NOYW1lLCBEb3VibGUuVFlQRSk7Ci0gICAgICAgICAgICByZXR1cm4gMDsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFV0aWxpdHkgZnVuY3Rpb246IHVzZWQgdG8gY29udmVydCByZWZlcmVuY2UgdG8gYm9vbGVhbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gcmVmZXJlbmNlVG9Cb29sZWFuKE9iamVjdCBvYmopIHsKLSAgICAgICAgaWYgKG9iaiBpbnN0YW5jZW9mIEJvb2xlYW4pIHsKLSAgICAgICAgICAgIHJldHVybiAoKEJvb2xlYW4pIG9iaikuYm9vbGVhblZhbHVlKCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBmaW5hbCBTdHJpbmcgY2xhc3NOYW1lID0gb2JqLmdldENsYXNzKCkuZ2V0TmFtZSgpOwotICAgICAgICAgICAgcnVuVGltZUVycm9yKERBVEFfQ09OVkVSU0lPTl9FUlIsIGNsYXNzTmFtZSwgQm9vbGVhbi5UWVBFKTsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFV0aWxpdHkgZnVuY3Rpb246IHVzZWQgdG8gY29udmVydCByZWZlcmVuY2UgdG8gU3RyaW5nLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHJlZmVyZW5jZVRvU3RyaW5nKE9iamVjdCBvYmosIERPTSBkb20pIHsKLSAgICAgICAgaWYgKG9iaiBpbnN0YW5jZW9mIFN0cmluZykgewotICAgICAgICAgICAgcmV0dXJuIChTdHJpbmcpIG9iajsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChvYmogaW5zdGFuY2VvZiBEVE1BeGlzSXRlcmF0b3IpIHsKLSAgICAgICAgICAgIHJldHVybiBkb20uZ2V0U3RyaW5nVmFsdWVYKCgoRFRNQXhpc0l0ZXJhdG9yKW9iaikucmVzZXQoKS5uZXh0KCkpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKG9iaiBpbnN0YW5jZW9mIE5vZGUpIHsKLSAgICAgICAgICAgIHJldHVybiBkb20uZ2V0U3RyaW5nVmFsdWVYKCgoTm9kZSlvYmopLm5vZGUpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKG9iaiBpbnN0YW5jZW9mIERPTSkgewotICAgICAgICAgICAgcmV0dXJuICgoRE9NKSBvYmopLmdldFN0cmluZ1ZhbHVlKCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBmaW5hbCBTdHJpbmcgY2xhc3NOYW1lID0gb2JqLmdldENsYXNzKCkuZ2V0TmFtZSgpOwotICAgICAgICAgICAgcnVuVGltZUVycm9yKERBVEFfQ09OVkVSU0lPTl9FUlIsIGNsYXNzTmFtZSwgU3RyaW5nLmNsYXNzKTsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVXRpbGl0eSBmdW5jdGlvbiB1c2VkIHRvIGNvbnZlcnQgYSB3M2MgTm9kZSBpbnRvIGFuIGludGVybmFsIERPTSBpdGVyYXRvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIERUTUF4aXNJdGVyYXRvciBub2RlMkl0ZXJhdG9yKG9yZy53M2MuZG9tLk5vZGUgbm9kZSwKLSAgICAgICAgVHJhbnNsZXQgdHJhbnNsZXQsIERPTSBkb20pCi0gICAgewotICAgICAgICBmaW5hbCBvcmcudzNjLmRvbS5Ob2RlIGluTm9kZSA9IG5vZGU7Ci0gICAgICAgIC8vIENyZWF0ZSBhIGR1bW15IE5vZGVMaXN0IHdoaWNoIG9ubHkgY29udGFpbnMgdGhlIGdpdmVuIG5vZGUgdG8gbWFrZQotICAgICAgICAvLyB1c2Ugb2YgdGhlIG5vZGVMaXN0Mkl0ZXJhdG9yKCkgaW50ZXJmYWNlLgotICAgICAgICBvcmcudzNjLmRvbS5Ob2RlTGlzdCBub2RlbGlzdCA9IG5ldyBvcmcudzNjLmRvbS5Ob2RlTGlzdCgpIHsKLSAgICAgICAgICAgIHB1YmxpYyBpbnQgZ2V0TGVuZ3RoKCkgewotICAgICAgICAgICAgICAgIHJldHVybiAxOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBwdWJsaWMgb3JnLnczYy5kb20uTm9kZSBpdGVtKGludCBpbmRleCkgewotICAgICAgICAgICAgICAgIGlmIChpbmRleCA9PSAwKQotICAgICAgICAgICAgICAgICAgICByZXR1cm4gaW5Ob2RlOwotICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH07Ci0KLSAgICAgICAgcmV0dXJuIG5vZGVMaXN0Mkl0ZXJhdG9yKG5vZGVsaXN0LCB0cmFuc2xldCwgZG9tKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJbiBhIHBlcmZlY3Qgd29ybGQsIHRoaXMgd291bGQgYmUgdGhlIGltcGxlbWVudGF0aW9uIGZvcgotICAgICAqIG5vZGVMaXN0Mkl0ZXJhdG9yLiBJbiByZWFsaXR5LCB0aG91Z2gsIHRoaXMgY2F1c2VzIGEKLSAgICAgKiBDbGFzc0Nhc3RFeGNlcHRpb24gaW4gZ2V0RFRNSGFuZGxlRnJvbU5vZGUgYmVjYXVzZSBTQVhJbXBsIGlzCi0gICAgICogbm90IGFuIGluc3RhbmNlIG9mIERPTTJEVE0uIFNvIHdlIHVzZSB0aGUgbW9yZSBsZW5ndGh5Ci0gICAgICogaW1wbGVtZW50YXRpb24gYmVsb3cgdW50aWwgdGhpcyBpc3N1ZSBoYXMgYmVlbiBhZGRyZXNzZWQuCi0gICAgICoKLSAgICAgKiBAc2VlIG9yZy5hcGFjaGUueG1sLmR0bS5yZWYuRFRNTWFuYWdlckRlZmF1bHQjZ2V0RFRNSGFuZGxlRnJvbU5vZGUKLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBEVE1BeGlzSXRlcmF0b3Igbm9kZUxpc3QySXRlcmF0b3JVc2luZ0hhbmRsZUZyb21Ob2RlKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yZy53M2MuZG9tLk5vZGVMaXN0IG5vZGVMaXN0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRyYW5zbGV0IHRyYW5zbGV0LCBET00gZG9tKQotICAgIHsKLSAgICAgICAgZmluYWwgaW50IG4gPSBub2RlTGlzdC5nZXRMZW5ndGgoKTsKLSAgICAgICAgZmluYWwgaW50W10gZHRtSGFuZGxlcyA9IG5ldyBpbnRbbl07Ci0gICAgICAgIERUTU1hbmFnZXIgZHRtTWFuYWdlciA9IG51bGw7Ci0gICAgICAgIGlmIChkb20gaW5zdGFuY2VvZiBNdWx0aURPTSkKLSAgICAgICAgICAgIGR0bU1hbmFnZXIgPSAoKE11bHRpRE9NKSBkb20pLmdldERUTU1hbmFnZXIoKTsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyArK2kpIHsKLSAgICAgICAgICAgIG9yZy53M2MuZG9tLk5vZGUgbm9kZSA9IG5vZGVMaXN0Lml0ZW0oaSk7Ci0gICAgICAgICAgICBpbnQgaGFuZGxlOwotICAgICAgICAgICAgaWYgKGR0bU1hbmFnZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGhhbmRsZSA9IGR0bU1hbmFnZXIuZ2V0RFRNSGFuZGxlRnJvbU5vZGUobm9kZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChub2RlIGluc3RhbmNlb2YgRFRNTm9kZVByb3h5Ci0gICAgICAgICAgICAgICAgICAgICAmJiAoKERUTU5vZGVQcm94eSkgbm9kZSkuZ2V0RFRNKCkgPT0gZG9tKSB7Ci0gICAgICAgICAgICAgICAgaGFuZGxlID0gKChEVE1Ob2RlUHJveHkpIG5vZGUpLmdldERUTU5vZGVOdW1iZXIoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIHJ1blRpbWVFcnJvcihSVU5fVElNRV9JTlRFUk5BTF9FUlIsICJuZWVkIE11bHRpRE9NIik7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBkdG1IYW5kbGVzW2ldID0gaGFuZGxlOwotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJOb2RlICIgKyBpICsgIiBoYXMgaGFuZGxlIDB4IiArCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW50ZWdlci50b1N0cmluZyhoYW5kbGUsIDE2KSk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG5ldyBBcnJheU5vZGVMaXN0SXRlcmF0b3IoZHRtSGFuZGxlcyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVXRpbGl0eSBmdW5jdGlvbiB1c2VkIHRvIGNvbnZlcnQgYSB3M2MgTm9kZUxpc3QgaW50byBhIGludGVybmFsCi0gICAgICogRE9NIGl0ZXJhdG9yLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgRFRNQXhpc0l0ZXJhdG9yIG5vZGVMaXN0Mkl0ZXJhdG9yKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yZy53M2MuZG9tLk5vZGVMaXN0IG5vZGVMaXN0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRyYW5zbGV0IHRyYW5zbGV0LCBET00gZG9tKQotICAgIHsKLSAgICAgICAgLy8gRmlyc3QgcGFzczogYnVpbGQgdzNjIERPTSBmb3IgYWxsIG5vZGVzIG5vdCBwcm94aWVkIGZyb20gb3VyIERPTS4KLSAgICAgICAgLy8KLSAgICAgICAgLy8gTm90aWNlOiB0aGlzIGxvb3NlcyBzb21lIChlc3AuIHBhcmVudCkgY29udGV4dCBmb3IgdGhlc2Ugbm9kZXMsCi0gICAgICAgIC8vIHNvIHNvbWUgd2F5IHRvIHdyYXAgdGhlIG9yaWdpbmFsIG5vZGVzIGluc2lkZSBhIERUTUF4aXNJdGVyYXRvcgotICAgICAgICAvLyBtaWdodCBiZSBwcmVmZXJhYmxlIGluIHRoZSBsb25nIHJ1bi4KLSAgICAgICAgaW50IG4gPSAwOyAvLyBhbGxvdyBmb3IgY2hhbmdlIGluIGxpc3QgbGVuZ3RoLCBqdXN0IGluIGNhc2UuCi0gICAgICAgIERvY3VtZW50IGRvYyA9IG51bGw7Ci0gICAgICAgIERUTU1hbmFnZXIgZHRtTWFuYWdlciA9IG51bGw7Ci0gICAgICAgIGludFtdIHByb3h5Tm9kZXMgPSBuZXcgaW50W25vZGVMaXN0LmdldExlbmd0aCgpXTsKLSAgICAgICAgaWYgKGRvbSBpbnN0YW5jZW9mIE11bHRpRE9NKQotICAgICAgICAgICAgZHRtTWFuYWdlciA9ICgoTXVsdGlET00pIGRvbSkuZ2V0RFRNTWFuYWdlcigpOwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG5vZGVMaXN0LmdldExlbmd0aCgpOyArK2kpIHsKLSAgICAgICAgICAgIG9yZy53M2MuZG9tLk5vZGUgbm9kZSA9IG5vZGVMaXN0Lml0ZW0oaSk7Ci0gICAgICAgICAgICBpZiAobm9kZSBpbnN0YW5jZW9mIERUTU5vZGVQcm94eSkgewotICAgICAgICAgICAgICAgIERUTU5vZGVQcm94eSBwcm94eSA9IChEVE1Ob2RlUHJveHkpbm9kZTsKLSAgICAgICAgICAgICAgICBEVE0gbm9kZURUTSA9IHByb3h5LmdldERUTSgpOwotICAgICAgICAgICAgICAgIGludCBoYW5kbGUgPSBwcm94eS5nZXREVE1Ob2RlTnVtYmVyKCk7Ci0gICAgICAgICAgICAgICAgYm9vbGVhbiBpc091ckRPTSA9IChub2RlRFRNID09IGRvbSk7Ci0gICAgICAgICAgICAgICAgaWYgKCFpc091ckRPTSAmJiBkdG1NYW5hZ2VyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlzT3VyRE9NID0gKG5vZGVEVE0gPT0gZHRtTWFuYWdlci5nZXREVE0oaGFuZGxlKSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgY2F0Y2ggKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBpbnZhbGlkIG5vZGUgaGFuZGxlLCBzbyBkZWZpbml0ZWx5IG5vdCBvdXIgZG9jCi0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaWYgKGlzT3VyRE9NKSB7Ci0gICAgICAgICAgICAgICAgICAgIHByb3h5Tm9kZXNbaV0gPSBoYW5kbGU7Ci0gICAgICAgICAgICAgICAgICAgICsrbjsKLSAgICAgICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgcHJveHlOb2Rlc1tpXSA9IERUTS5OVUxMOwotICAgICAgICAgICAgaW50IG5vZGVUeXBlID0gbm9kZS5nZXROb2RlVHlwZSgpOwotICAgICAgICAgICAgaWYgKGRvYyA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGRvbSBpbnN0YW5jZW9mIE11bHRpRE9NID09IGZhbHNlKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJ1blRpbWVFcnJvcihSVU5fVElNRV9JTlRFUk5BTF9FUlIsICJuZWVkIE11bHRpRE9NIik7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICBBYnN0cmFjdFRyYW5zbGV0IGF0ID0gKEFic3RyYWN0VHJhbnNsZXQpIHRyYW5zbGV0OwotICAgICAgICAgICAgICAgICAgICBkb2MgPSBhdC5uZXdEb2N1bWVudCgiIiwgIl9fdG9wX18iKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgY2F0Y2ggKGphdmF4LnhtbC5wYXJzZXJzLlBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgICAgICBydW5UaW1lRXJyb3IoUlVOX1RJTUVfSU5URVJOQUxfRVJSLCBlLmdldE1lc3NhZ2UoKSk7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIFVzZSBvbmUgZHVtbXkgZWxlbWVudCBhcyBjb250YWluZXIgZm9yIGVhY2ggbm9kZSBvZiB0aGUKLSAgICAgICAgICAgIC8vIGxpc3QuIFRoYXQgd2F5LCBpdCBpcyBlYXNpZXIgdG8gZGV0ZWN0IHJlc3AuIGF2b2lkCi0gICAgICAgICAgICAvLyBmdW5ueSB0aGluZ3Mgd2hpY2ggY2hhbmdlIHRoZSBudW1iZXIgb2Ygbm9kZXMsCi0gICAgICAgICAgICAvLyBlLmcuIGF1dG8tY29uY2F0ZW5hdGlvbiBvZiB0ZXh0IG5vZGVzLgotICAgICAgICAgICAgRWxlbWVudCBtaWQ7Ci0gICAgICAgICAgICBzd2l0Y2ggKG5vZGVUeXBlKSB7Ci0gICAgICAgICAgICAgICAgY2FzZSBvcmcudzNjLmRvbS5Ob2RlLkVMRU1FTlRfTk9ERToKLSAgICAgICAgICAgICAgICBjYXNlIG9yZy53M2MuZG9tLk5vZGUuVEVYVF9OT0RFOgotICAgICAgICAgICAgICAgIGNhc2Ugb3JnLnczYy5kb20uTm9kZS5DREFUQV9TRUNUSU9OX05PREU6Ci0gICAgICAgICAgICAgICAgY2FzZSBvcmcudzNjLmRvbS5Ob2RlLkNPTU1FTlRfTk9ERToKLSAgICAgICAgICAgICAgICBjYXNlIG9yZy53M2MuZG9tLk5vZGUuRU5USVRZX1JFRkVSRU5DRV9OT0RFOgotICAgICAgICAgICAgICAgIGNhc2Ugb3JnLnczYy5kb20uTm9kZS5QUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREU6Ci0gICAgICAgICAgICAgICAgICAgIG1pZCA9IGRvYy5jcmVhdGVFbGVtZW50TlMobnVsbCwgIl9fZHVtbXlfXyIpOwotICAgICAgICAgICAgICAgICAgICBtaWQuYXBwZW5kQ2hpbGQoZG9jLmltcG9ydE5vZGUobm9kZSwgdHJ1ZSkpOwotICAgICAgICAgICAgICAgICAgICBkb2MuZ2V0RG9jdW1lbnRFbGVtZW50KCkuYXBwZW5kQ2hpbGQobWlkKTsKLSAgICAgICAgICAgICAgICAgICAgKytuOwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICBjYXNlIG9yZy53M2MuZG9tLk5vZGUuQVRUUklCVVRFX05PREU6Ci0gICAgICAgICAgICAgICAgICAgIC8vIFRoZSBtaWQgZWxlbWVudCBhbHNvIHNlcnZlcyBhcyBhIGNvbnRhaW5lciBmb3IKLSAgICAgICAgICAgICAgICAgICAgLy8gYXR0cmlidXRlcywgYXZvaWRpbmcgcHJvYmxlbXMgd2l0aCBjb25mbGljdGluZwotICAgICAgICAgICAgICAgICAgICAvLyBhdHRyaWJ1dGVzIG9yIG5vZGUgb3JkZXIuCi0gICAgICAgICAgICAgICAgICAgIG1pZCA9IGRvYy5jcmVhdGVFbGVtZW50TlMobnVsbCwgIl9fZHVtbXlfXyIpOwotICAgICAgICAgICAgICAgICAgICBtaWQuc2V0QXR0cmlidXRlTm9kZU5TKChBdHRyKWRvYy5pbXBvcnROb2RlKG5vZGUsIHRydWUpKTsKLSAgICAgICAgICAgICAgICAgICAgZG9jLmdldERvY3VtZW50RWxlbWVudCgpLmFwcGVuZENoaWxkKG1pZCk7Ci0gICAgICAgICAgICAgICAgICAgICsrbjsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgZGVmYXVsdDoKLSAgICAgICAgICAgICAgICAgICAgLy8gQmV0dGVyIHBsYXkgaXQgc2FmZSBmb3IgYWxsIHR5cGVzIHdlIGFyZW4ndCBzdXJlIHdlIGtub3cKLSAgICAgICAgICAgICAgICAgICAgLy8gaG93IHRvIGRlYWwgd2l0aC4KLSAgICAgICAgICAgICAgICAgICAgcnVuVGltZUVycm9yKFJVTl9USU1FX0lOVEVSTkFMX0VSUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJEb24ndCBrbm93IGhvdyB0byBjb252ZXJ0IG5vZGUgdHlwZSAiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIG5vZGVUeXBlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIHczY0RPTSAtPiBEVE0gLT4gRE9NSW1wbAotICAgICAgICBEVE1BeGlzSXRlcmF0b3IgaXRlciA9IG51bGwsIGNoaWxkSXRlciA9IG51bGwsIGF0dHJJdGVyID0gbnVsbDsKLSAgICAgICAgaWYgKGRvYyAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmaW5hbCBNdWx0aURPTSBtdWx0aURPTSA9IChNdWx0aURPTSkgZG9tOwotICAgICAgICAgICAgRE9NIGlkb20gPSAoRE9NKWR0bU1hbmFnZXIuZ2V0RFRNKG5ldyBET01Tb3VyY2UoZG9jKSwgZmFsc2UsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwgdHJ1ZSwgZmFsc2UpOwotICAgICAgICAgICAgLy8gQ3JlYXRlIERPTUFkYXB0ZXIgYW5kIHJlZ2lzdGVyIHdpdGggTXVsdGlET00KLSAgICAgICAgICAgIERPTUFkYXB0ZXIgZG9tQWRhcHRlciA9IG5ldyBET01BZGFwdGVyKGlkb20sCi0gICAgICAgICAgICAgICAgdHJhbnNsZXQuZ2V0TmFtZXNBcnJheSgpLAotICAgICAgICAgICAgICAgIHRyYW5zbGV0LmdldFVyaXNBcnJheSgpLAotICAgICAgICAgICAgICAgIHRyYW5zbGV0LmdldFR5cGVzQXJyYXkoKSwKLSAgICAgICAgICAgICAgICB0cmFuc2xldC5nZXROYW1lc3BhY2VBcnJheSgpKTsKLSAgICAgICAgICAgIG11bHRpRE9NLmFkZERPTUFkYXB0ZXIoZG9tQWRhcHRlcik7Ci0KLSAgICAgICAgICAgIERUTUF4aXNJdGVyYXRvciBpdGVyMSA9IGlkb20uZ2V0QXhpc0l0ZXJhdG9yKEF4aXMuQ0hJTEQpOwotICAgICAgICAgICAgRFRNQXhpc0l0ZXJhdG9yIGl0ZXIyID0gaWRvbS5nZXRBeGlzSXRlcmF0b3IoQXhpcy5DSElMRCk7Ci0gICAgICAgICAgICBpdGVyID0gbmV3IEFic29sdXRlSXRlcmF0b3IoCi0gICAgICAgICAgICAgICAgbmV3IFN0ZXBJdGVyYXRvcihpdGVyMSwgaXRlcjIpKTsKLQotICAgICAgICAgICAgaXRlci5zZXRTdGFydE5vZGUoRFRNRGVmYXVsdEJhc2UuUk9PVE5PREUpOwotCi0gICAgICAgICAgICBjaGlsZEl0ZXIgPSBpZG9tLmdldEF4aXNJdGVyYXRvcihBeGlzLkNISUxEKTsKLSAgICAgICAgICAgIGF0dHJJdGVyID0gaWRvbS5nZXRBeGlzSXRlcmF0b3IoQXhpcy5BVFRSSUJVVEUpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gU2Vjb25kIHBhc3M6IGZpbmQgRFRNIGhhbmRsZXMgZm9yIGV2ZXJ5IG5vZGUgaW4gdGhlIGxpc3QuCi0gICAgICAgIGludFtdIGR0bUhhbmRsZXMgPSBuZXcgaW50W25dOwotICAgICAgICBuID0gMDsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBub2RlTGlzdC5nZXRMZW5ndGgoKTsgKytpKSB7Ci0gICAgICAgICAgICBpZiAocHJveHlOb2Rlc1tpXSAhPSBEVE0uTlVMTCkgewotICAgICAgICAgICAgICAgIGR0bUhhbmRsZXNbbisrXSA9IHByb3h5Tm9kZXNbaV07Ci0gICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBvcmcudzNjLmRvbS5Ob2RlIG5vZGUgPSBub2RlTGlzdC5pdGVtKGkpOwotICAgICAgICAgICAgRFRNQXhpc0l0ZXJhdG9yIGl0ZXIzID0gbnVsbDsKLSAgICAgICAgICAgIGludCBub2RlVHlwZSA9IG5vZGUuZ2V0Tm9kZVR5cGUoKTsKLSAgICAgICAgICAgIHN3aXRjaCAobm9kZVR5cGUpIHsKLSAgICAgICAgICAgICAgICBjYXNlIG9yZy53M2MuZG9tLk5vZGUuRUxFTUVOVF9OT0RFOgotICAgICAgICAgICAgICAgIGNhc2Ugb3JnLnczYy5kb20uTm9kZS5URVhUX05PREU6Ci0gICAgICAgICAgICAgICAgY2FzZSBvcmcudzNjLmRvbS5Ob2RlLkNEQVRBX1NFQ1RJT05fTk9ERToKLSAgICAgICAgICAgICAgICBjYXNlIG9yZy53M2MuZG9tLk5vZGUuQ09NTUVOVF9OT0RFOgotICAgICAgICAgICAgICAgIGNhc2Ugb3JnLnczYy5kb20uTm9kZS5FTlRJVFlfUkVGRVJFTkNFX05PREU6Ci0gICAgICAgICAgICAgICAgY2FzZSBvcmcudzNjLmRvbS5Ob2RlLlBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERToKLSAgICAgICAgICAgICAgICAgICAgaXRlcjMgPSBjaGlsZEl0ZXI7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGNhc2Ugb3JnLnczYy5kb20uTm9kZS5BVFRSSUJVVEVfTk9ERToKLSAgICAgICAgICAgICAgICAgICAgaXRlcjMgPSBhdHRySXRlcjsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgZGVmYXVsdDoKLSAgICAgICAgICAgICAgICAgICAgLy8gU2hvdWxkIG5vdCBoYXBwZW4sIGFzIGZpcnN0IHJ1biBzaG91bGQgaGF2ZSBnb3QgYWxsIHRoZXNlCi0gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnRlcm5hbFJ1bnRpbWVFcnJvcigiTWlzbWF0Y2hlZCBjYXNlcyIpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKGl0ZXIzICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBpdGVyMy5zZXRTdGFydE5vZGUoaXRlci5uZXh0KCkpOwotICAgICAgICAgICAgICAgIGR0bUhhbmRsZXNbbl0gPSBpdGVyMy5uZXh0KCk7Ci0gICAgICAgICAgICAgICAgLy8gRm9yIG5vdywgcGxheSBpdCBzZWxmIGFuZCBwZXJmb3JtIGV4dHJhIGNoZWNrczoKLSAgICAgICAgICAgICAgICBpZiAoZHRtSGFuZGxlc1tuXSA9PSBEVE1BeGlzSXRlcmF0b3IuRU5EKQotICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW50ZXJuYWxSdW50aW1lRXJyb3IoIkV4cGVjdGVkIGVsZW1lbnQgbWlzc2luZyBhdCAiICsgaSk7Ci0gICAgICAgICAgICAgICAgaWYgKGl0ZXIzLm5leHQoKSAhPSBEVE1BeGlzSXRlcmF0b3IuRU5EKQotICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW50ZXJuYWxSdW50aW1lRXJyb3IoIlRvbyBtYW55IGVsZW1lbnRzIGF0ICIgKyBpKTsKLSAgICAgICAgICAgICAgICArK247Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKG4gIT0gZHRtSGFuZGxlcy5sZW5ndGgpCi0gICAgICAgICAgICB0aHJvdyBuZXcgSW50ZXJuYWxSdW50aW1lRXJyb3IoIk5vZGVzIGxvc3QgaW4gc2Vjb25kIHBhc3MiKTsKLQotICAgICAgICByZXR1cm4gbmV3IEFycmF5Tm9kZUxpc3RJdGVyYXRvcihkdG1IYW5kbGVzKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBVdGlsaXR5IGZ1bmN0aW9uIHVzZWQgdG8gY29udmVydCByZWZlcmVuY2VzIHRvIERPTXMuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBET00gcmVmZXJlbmNlVG9SZXN1bHRUcmVlKE9iamVjdCBvYmopIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIHJldHVybiAoKERPTSkgb2JqKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIGZpbmFsIFN0cmluZyBjbGFzc05hbWUgPSBvYmouZ2V0Q2xhc3MoKS5nZXROYW1lKCk7Ci0gICAgICAgICAgICBydW5UaW1lRXJyb3IoREFUQV9DT05WRVJTSU9OX0VSUiwgInJlZmVyZW5jZSIsIGNsYXNzTmFtZSk7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFV0aWxpdHkgZnVuY3Rpb246IHVzZWQgd2l0aCBudGggcG9zaXRpb24gZmlsdGVycyB0byBjb252ZXJ0IGEgc2VxdWVuY2UKLSAgICAgKiBvZiBub2RlcyB0byBqdXN0IG9uZSBzaW5nbGUgbm9kZSAodGhlIG9uZSBhdCBwb3NpdGlvbiBuKS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIERUTUF4aXNJdGVyYXRvciBnZXRTaW5nbGVOb2RlKERUTUF4aXNJdGVyYXRvciBpdGVyYXRvcikgewotICAgICAgICBpbnQgbm9kZSA9IGl0ZXJhdG9yLm5leHQoKTsKLSAgICAgICAgcmV0dXJuKG5ldyBTaW5nbGV0b25JdGVyYXRvcihub2RlKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVXRpbGl0eSBmdW5jdGlvbjogdXNlZCBpbiB4c2w6Y29weS4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBjaGFyW10gX2NoYXJhY3RlckFycmF5ID0gbmV3IGNoYXJbMzJdOwotCi0gICAgcHVibGljIHN0YXRpYyB2b2lkIGNvcHkoT2JqZWN0IG9iaiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZXJpYWxpemF0aW9uSGFuZGxlciBoYW5kbGVyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBub2RlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIERPTSBkb20pIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGlmIChvYmogaW5zdGFuY2VvZiBEVE1BeGlzSXRlcmF0b3IpCi0gICAgICB7Ci0gICAgICAgICAgICAgICAgRFRNQXhpc0l0ZXJhdG9yIGl0ZXIgPSAoRFRNQXhpc0l0ZXJhdG9yKSBvYmo7Ci0gICAgICAgICAgICAgICAgZG9tLmNvcHkoaXRlci5yZXNldCgpLCBoYW5kbGVyKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKG9iaiBpbnN0YW5jZW9mIE5vZGUpIHsKLSAgICAgICAgICAgICAgICBkb20uY29weSgoKE5vZGUpIG9iaikubm9kZSwgaGFuZGxlcik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChvYmogaW5zdGFuY2VvZiBET00pIHsKLSAgICAgICAgICAgICAgICAvLygoRE9NKW9iaikuY29weSgoKGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLnJlZi5EVE1EZWZhdWx0QmFzZSkoKERPTUFkYXB0ZXIpb2JqKS5nZXRET01JbXBsKCkpLmdldERvY3VtZW50KCksIGhhbmRsZXIpOwotICAgICAgICAgICAgICAgIERPTSBuZXdEb20gPSAoRE9NKW9iajsKLSAgICAgICAgICAgICAgICBuZXdEb20uY29weShuZXdEb20uZ2V0RG9jdW1lbnQoKSwgaGFuZGxlcik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgc3RyaW5nID0gb2JqLnRvU3RyaW5nKCk7ICAgICAgICAgLy8gb3IgY2FsbCBzdHJpbmdGKCkKLSAgICAgICAgICAgICAgICBmaW5hbCBpbnQgbGVuZ3RoID0gc3RyaW5nLmxlbmd0aCgpOwotICAgICAgICAgICAgICAgIGlmIChsZW5ndGggPiBfY2hhcmFjdGVyQXJyYXkubGVuZ3RoKQotICAgICAgICAgICAgICAgICAgICBfY2hhcmFjdGVyQXJyYXkgPSBuZXcgY2hhcltsZW5ndGhdOwotICAgICAgICAgICAgICAgIHN0cmluZy5nZXRDaGFycygwLCBsZW5ndGgsIF9jaGFyYWN0ZXJBcnJheSwgMCk7Ci0gICAgICAgICAgICAgICAgaGFuZGxlci5jaGFyYWN0ZXJzKF9jaGFyYWN0ZXJBcnJheSwgMCwgbGVuZ3RoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIHJ1blRpbWVFcnJvcihSVU5fVElNRV9DT1BZX0VSUik7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBVdGlsaXR5IGZ1bmN0aW9uIHRvIGNoZWNrIGlmIHhzbDphdHRyaWJ1dGUgaGFzIGEgdmFsaWQgcW5hbWUKLSAgICAgKiBUaGlzIG1ldGhvZCBzaG91bGQgb25seSBiZSBpbnZva2VkIGlmIHRoZSBuYW1lIGF0dHJpYnV0ZSBpcyBhbiBBVlQKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIHZvaWQgY2hlY2tBdHRyaWJRTmFtZShTdHJpbmcgbmFtZSkgewotICAgICAgICBmaW5hbCBpbnQgZmlyc3RPY2N1ciA9IG5hbWUuaW5kZXhPZigiOiIpOwotICAgICAgICBmaW5hbCBpbnQgbGFzdE9jY3VyID0gbmFtZS5sYXN0SW5kZXhPZigiOiIpOwotICAgICAgICBmaW5hbCBTdHJpbmcgbG9jYWxOYW1lID0gbmFtZS5zdWJzdHJpbmcobGFzdE9jY3VyICsgMSk7Ci0KLSAgICAgICAgaWYgKGZpcnN0T2NjdXIgPiAwKSB7Ci0gICAgICAgICAgICBmaW5hbCBTdHJpbmcgbmV3UHJlZml4ID0gbmFtZS5zdWJzdHJpbmcoMCwgZmlyc3RPY2N1cik7Ci0KLSAgICAgICAgICAgIGlmIChmaXJzdE9jY3VyICE9IGxhc3RPY2N1cikgewotICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIG9yaVByZWZpeCA9IG5hbWUuc3Vic3RyaW5nKGZpcnN0T2NjdXIrMSwgbGFzdE9jY3VyKTsKLSAgICAgICAgICAgICAgICBpZiAoIVhNTDExQ2hhci5pc1hNTDExVmFsaWROQ05hbWUob3JpUHJlZml4KSkgewotICAgICAgICAgICAgICAgICAgICAvLyBldmVuIHRob3VnaCB0aGUgb3JpZ25hbCBwcmVmaXggaXMgaWdub3JlZCwgaXQgc2hvdWxkIHN0aWxsIGdldCBjaGVja2VkIGZvciB2YWxpZCBOQ05hbWUKLSAgICAgICAgICAgICAgICAgICAgcnVuVGltZUVycm9yKElOVkFMSURfUU5BTUVfRVJSLG9yaVByZWZpeCsiOiIrbG9jYWxOYW1lKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIHByZWZpeCBtdXN0IGJlIGEgdmFsaWQgTkNOYW1lCi0gICAgICAgICAgICBpZiAoIVhNTDExQ2hhci5pc1hNTDExVmFsaWROQ05hbWUobmV3UHJlZml4KSkgewotICAgICAgICAgICAgICAgIHJ1blRpbWVFcnJvcihJTlZBTElEX1FOQU1FX0VSUixuZXdQcmVmaXgrIjoiK2xvY2FsTmFtZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBsb2NhbCBuYW1lIG11c3QgYmUgYSB2YWxpZCBOQ05hbWUgYW5kIG11c3Qgbm90IGJlIFhNTE5TCi0gICAgICAgIGlmICgoIVhNTDExQ2hhci5pc1hNTDExVmFsaWROQ05hbWUobG9jYWxOYW1lKSl8fChsb2NhbE5hbWUuZXF1YWxzKENvbnN0YW50cy5YTUxOU19QUkVGSVgpKSkgewotICAgICAgICAgICAgcnVuVGltZUVycm9yKElOVkFMSURfUU5BTUVfRVJSLGxvY2FsTmFtZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBVdGlsaXR5IGZ1bmN0aW9uIHRvIGNoZWNrIGlmIGEgbmFtZSBpcyBhIHZhbGlkIG5jbmFtZQotICAgICAqIFRoaXMgbWV0aG9kIHNob3VsZCBvbmx5IGJlIGludm9rZWQgaWYgdGhlIGF0dHJpYnV0ZSB2YWx1ZSBpcyBhbiBBVlQKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIHZvaWQgY2hlY2tOQ05hbWUoU3RyaW5nIG5hbWUpIHsKLSAgICAgICAgaWYgKCFYTUwxMUNoYXIuaXNYTUwxMVZhbGlkTkNOYW1lKG5hbWUpKSB7Ci0gICAgICAgICAgICBydW5UaW1lRXJyb3IoSU5WQUxJRF9OQ05BTUVfRVJSLG5hbWUpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVXRpbGl0eSBmdW5jdGlvbiB0byBjaGVjayBpZiBhIG5hbWUgaXMgYSB2YWxpZCBxbmFtZQotICAgICAqIFRoaXMgbWV0aG9kIHNob3VsZCBvbmx5IGJlIGludm9rZWQgaWYgdGhlIGF0dHJpYnV0ZSB2YWx1ZSBpcyBhbiBBVlQKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIHZvaWQgY2hlY2tRTmFtZShTdHJpbmcgbmFtZSkgewotICAgICAgICBpZiAoIVhNTDExQ2hhci5pc1hNTDExVmFsaWRRTmFtZShuYW1lKSkgewotICAgICAgICAgICAgcnVuVGltZUVycm9yKElOVkFMSURfUU5BTUVfRVJSLG5hbWUpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVXRpbGl0eSBmdW5jdGlvbiBmb3IgdGhlIGltcGxlbWVudGF0aW9uIG9mIHhzbDplbGVtZW50LgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHN0YXJ0WHNsRWxlbWVudChTdHJpbmcgcW5hbWUsIFN0cmluZyBuYW1lc3BhY2UsCi0gICAgICAgIFNlcmlhbGl6YXRpb25IYW5kbGVyIGhhbmRsZXIsIERPTSBkb20sIGludCBub2RlKQotICAgIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIC8vIEdldCBwcmVmaXggZnJvbSBxbmFtZQotICAgICAgICAgICAgU3RyaW5nIHByZWZpeDsKLSAgICAgICAgICAgIGZpbmFsIGludCBpbmRleCA9IHFuYW1lLmluZGV4T2YoJzonKTsKLQotICAgICAgICAgICAgaWYgKGluZGV4ID4gMCkgewotICAgICAgICAgICAgICAgIHByZWZpeCA9IHFuYW1lLnN1YnN0cmluZygwLCBpbmRleCk7Ci0KLSAgICAgICAgICAgICAgICAvLyBIYW5kbGUgY2FzZSB3aGVuIHByZWZpeCBpcyBub3Qga25vd24gYXQgY29tcGlsZSB0aW1lCi0gICAgICAgICAgICAgICAgaWYgKG5hbWVzcGFjZSA9PSBudWxsIHx8IG5hbWVzcGFjZS5sZW5ndGgoKSA9PSAwKSB7Ci0gICAgICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBub3Qgc3VyZSBpZiB0aGlzIGxpbmUgb2YgY29kZSBldmVyIHdvcmtzCi0gICAgICAgICAgICAgICAgICAgICAgICBuYW1lc3BhY2UgPSBkb20ubG9va3VwTmFtZXNwYWNlKG5vZGUsIHByZWZpeCk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgY2F0Y2goUnVudGltZUV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVyLmZsdXNoUGVuZGluZygpOyAgLy8gbmVlZCB0byBmbHVzaCBvciBlbHNlIGNhbid0IGdldCBuYW1lc3BhY2VtYXBwaW5ncwotICAgICAgICAgICAgICAgICAgICAgICAgTmFtZXNwYWNlTWFwcGluZ3Mgbm0gPSBoYW5kbGVyLmdldE5hbWVzcGFjZU1hcHBpbmdzKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBuYW1lc3BhY2UgPSBubS5sb29rdXBOYW1lc3BhY2UocHJlZml4KTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuYW1lc3BhY2UgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJ1blRpbWVFcnJvcihOQU1FU1BBQ0VfUFJFRklYX0VSUixwcmVmaXgpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgaGFuZGxlci5zdGFydEVsZW1lbnQobmFtZXNwYWNlLCBxbmFtZS5zdWJzdHJpbmcoaW5kZXgrMSksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHFuYW1lKTsKLSAgICAgICAgICAgICAgICBoYW5kbGVyLm5hbWVzcGFjZUFmdGVyU3RhcnRFbGVtZW50KHByZWZpeCwgbmFtZXNwYWNlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIC8vIE5lZWQgdG8gZ2VuZXJhdGUgYSBwcmVmaXg/Ci0gICAgICAgICAgICAgICAgaWYgKG5hbWVzcGFjZSAhPSBudWxsICYmIG5hbWVzcGFjZS5sZW5ndGgoKSA+IDApIHsKLSAgICAgICAgICAgICAgICAgICAgcHJlZml4ID0gZ2VuZXJhdGVQcmVmaXgoKTsKLSAgICAgICAgICAgICAgICAgICAgcW5hbWUgPSBwcmVmaXggKyAnOicgKyBxbmFtZTsKLSAgICAgICAgICAgICAgICAgICAgaGFuZGxlci5zdGFydEVsZW1lbnQobmFtZXNwYWNlLCBxbmFtZSwgcW5hbWUpOwotICAgICAgICAgICAgICAgICAgICBoYW5kbGVyLm5hbWVzcGFjZUFmdGVyU3RhcnRFbGVtZW50KHByZWZpeCwgbmFtZXNwYWNlKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIGhhbmRsZXIuc3RhcnRFbGVtZW50KG51bGwsIG51bGwsIHFuYW1lKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihlLmdldE1lc3NhZ2UoKSk7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gcW5hbWU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBmdW5jdGlvbiBpcyB1c2VkIGluIHRoZSBleGVjdXRpb24gb2YgeHNsOmVsZW1lbnQKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBnZXRQcmVmaXgoU3RyaW5nIHFuYW1lKSB7Ci0gICAgICAgIGZpbmFsIGludCBpbmRleCA9IHFuYW1lLmluZGV4T2YoJzonKTsKLSAgICAgICAgcmV0dXJuIChpbmRleCA+IDApID8gcW5hbWUuc3Vic3RyaW5nKDAsIGluZGV4KSA6IG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhlc2UgZnVuY3Rpb25zIGFyZSB1c2VkIGluIHRoZSBleGVjdXRpb24gb2YgeHNsOmVsZW1lbnQgdG8gZ2VuZXJhdGUKLSAgICAgKiBhbmQgcmVzZXQgbmFtZXNwYWNlIHByZWZpeCBpbmRleCBsb2NhbCB0byBjdXJyZW50IHRyYW5zZm9ybWF0aW9uIHByb2Nlc3MKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBnZW5lcmF0ZVByZWZpeCgpIHsKLSAgICAgICAgcmV0dXJuICgibnMiICsgdGhyZWFkTG9jYWxQcmVmaXhJbmRleC5nZXQoKS5nZXRBbmRJbmNyZW1lbnQoKSk7Ci0gICAgfQotCi0gICAgcHVibGljIHN0YXRpYyB2b2lkIHJlc2V0UHJlZml4SW5kZXgoKSB7Ci0gICAgICAgIHRocmVhZExvY2FsUHJlZml4SW5kZXguZ2V0KCkuc2V0KDApOwotICAgIH0KLQotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRocmVhZExvY2FsPEF0b21pY0ludGVnZXI+IHRocmVhZExvY2FsUHJlZml4SW5kZXggPQotICAgICAgICBuZXcgVGhyZWFkTG9jYWw8QXRvbWljSW50ZWdlcj4oKSB7Ci0gICAgICAgICAgICBAT3ZlcnJpZGUKLSAgICAgICAgICAgIHByb3RlY3RlZCBBdG9taWNJbnRlZ2VyIGluaXRpYWxWYWx1ZSgpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEF0b21pY0ludGVnZXIoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfTsKLQotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFJVTl9USU1FX0lOVEVSTkFMX0VSUiA9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlJVTl9USU1FX0lOVEVSTkFMX0VSUiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgUlVOX1RJTUVfQ09QWV9FUlIgPQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJSVU5fVElNRV9DT1BZX0VSUiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgREFUQV9DT05WRVJTSU9OX0VSUiA9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkRBVEFfQ09OVkVSU0lPTl9FUlIiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVYVEVSTkFMX0ZVTkNfRVJSID0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRVhURVJOQUxfRlVOQ19FUlIiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVRVUFMSVRZX0VYUFJfRVJSID0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRVFVQUxJVFlfRVhQUl9FUlIiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIElOVkFMSURfQVJHVU1FTlRfRVJSID0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiSU5WQUxJRF9BUkdVTUVOVF9FUlIiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEZPUk1BVF9OVU1CRVJfRVJSID0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRk9STUFUX05VTUJFUl9FUlIiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIElURVJBVE9SX0NMT05FX0VSUiA9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIklURVJBVE9SX0NMT05FX0VSUiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVhJU19TVVBQT1JUX0VSUiA9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkFYSVNfU1VQUE9SVF9FUlIiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFRZUEVEX0FYSVNfU1VQUE9SVF9FUlIgPQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJUWVBFRF9BWElTX1NVUFBPUlRfRVJSIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBTVFJBWV9BVFRSSUJVVEVfRVJSID0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU1RSQVlfQVRUUklCVVRFX0VSUiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1RSQVlfTkFNRVNQQUNFX0VSUiA9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNUUkFZX05BTUVTUEFDRV9FUlIiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIE5BTUVTUEFDRV9QUkVGSVhfRVJSID0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTkFNRVNQQUNFX1BSRUZJWF9FUlIiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIERPTV9BREFQVEVSX0lOSVRfRVJSID0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRE9NX0FEQVBURVJfSU5JVF9FUlIiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFBBUlNFUl9EVERfU1VQUE9SVF9FUlIgPQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJQQVJTRVJfRFREX1NVUFBPUlRfRVJSIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBOQU1FU1BBQ0VTX1NVUFBPUlRfRVJSID0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTkFNRVNQQUNFU19TVVBQT1JUX0VSUiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ0FOVF9SRVNPTFZFX1JFTEFUSVZFX1VSSV9FUlIgPQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDQU5UX1JFU09MVkVfUkVMQVRJVkVfVVJJX0VSUiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgVU5TVVBQT1JURURfWFNMX0VSUiA9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlVOU1VQUE9SVEVEX1hTTF9FUlIiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFVOU1VQUE9SVEVEX0VYVF9FUlIgPQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJVTlNVUFBPUlRFRF9FWFRfRVJSIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBVTktOT1dOX1RSQU5TTEVUX1ZFUlNJT05fRVJSID0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVU5LTk9XTl9UUkFOU0xFVF9WRVJTSU9OX0VSUiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSU5WQUxJRF9RTkFNRV9FUlIgPSAiSU5WQUxJRF9RTkFNRV9FUlIiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIElOVkFMSURfTkNOQU1FX0VSUiA9ICJJTlZBTElEX05DTkFNRV9FUlIiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFVOQUxMT1dFRF9FWFRFTlNJT05fRlVOQ1RJT05fRVJSID0gIlVOQUxMT1dFRF9FWFRFTlNJT05fRlVOQ1RJT05fRVJSIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBVTkFMTE9XRURfRVhURU5TSU9OX0VMRU1FTlRfRVJSID0gIlVOQUxMT1dFRF9FWFRFTlNJT05fRUxFTUVOVF9FUlIiOwotCi0gICAgLy8gQWxsIGVycm9yIG1lc3NhZ2VzIGFyZSBsb2NhbGl6ZWQgYW5kIGFyZSBzdG9yZWQgaW4gcmVzb3VyY2UgYnVuZGxlcy4KLSAgICBwcml2YXRlIHN0YXRpYyBSZXNvdXJjZUJ1bmRsZSBtX2J1bmRsZTsKLQotICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgU3RyaW5nIEVSUk9SX01FU1NBR0VTX0tFWSA9ICJlcnJvci1tZXNzYWdlcyI7Ci0KLSAgICBzdGF0aWMgewotICAgICAgICBTdHJpbmcgcmVzb3VyY2UgPSAiY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnJ1bnRpbWUuRXJyb3JNZXNzYWdlcyI7Ci0gICAgICAgIG1fYnVuZGxlID0gU2VjdXJpdHlTdXBwb3J0LmdldFJlc291cmNlQnVuZGxlKHJlc291cmNlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBQcmludCBhIHJ1bi10aW1lIGVycm9yIG1lc3NhZ2UuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyB2b2lkIHJ1blRpbWVFcnJvcihTdHJpbmcgY29kZSkgewotICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihtX2J1bmRsZS5nZXRTdHJpbmcoY29kZSkpOwotICAgIH0KLQotICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBydW5UaW1lRXJyb3IoU3RyaW5nIGNvZGUsIE9iamVjdFtdIGFyZ3MpIHsKLSAgICAgICAgZmluYWwgU3RyaW5nIG1lc3NhZ2UgPSBNZXNzYWdlRm9ybWF0LmZvcm1hdChtX2J1bmRsZS5nZXRTdHJpbmcoY29kZSksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJncyk7Ci0gICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKG1lc3NhZ2UpOwotICAgIH0KLQotICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBydW5UaW1lRXJyb3IoU3RyaW5nIGNvZGUsIE9iamVjdCBhcmcwKSB7Ci0gICAgICAgIHJ1blRpbWVFcnJvcihjb2RlLCBuZXcgT2JqZWN0W117IGFyZzAgfSApOwotICAgIH0KLQotICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBydW5UaW1lRXJyb3IoU3RyaW5nIGNvZGUsIE9iamVjdCBhcmcwLCBPYmplY3QgYXJnMSkgewotICAgICAgICBydW5UaW1lRXJyb3IoY29kZSwgbmV3IE9iamVjdFtdeyBhcmcwLCBhcmcxIH0gKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgc3RhdGljIHZvaWQgY29uc29sZU91dHB1dChTdHJpbmcgbXNnKSB7Ci0gICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbihtc2cpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJlcGxhY2UgYSBjZXJ0YWluIGNoYXJhY3RlciBpbiBhIHN0cmluZyB3aXRoIGEgbmV3IHN1YnN0cmluZy4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFN0cmluZyByZXBsYWNlKFN0cmluZyBiYXNlLCBjaGFyIGNoLCBTdHJpbmcgc3RyKSB7Ci0gICAgICAgIHJldHVybiAoYmFzZS5pbmRleE9mKGNoKSA8IDApID8gYmFzZSA6Ci0gICAgICAgICAgICByZXBsYWNlKGJhc2UsIFN0cmluZy52YWx1ZU9mKGNoKSwgbmV3IFN0cmluZ1tdIHsgc3RyIH0pOwotICAgIH0KLQotICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHJlcGxhY2UoU3RyaW5nIGJhc2UsIFN0cmluZyBkZWxpbSwgU3RyaW5nW10gc3RyKSB7Ci0gICAgICAgIGZpbmFsIGludCBsZW4gPSBiYXNlLmxlbmd0aCgpOwotICAgICAgICBmaW5hbCBTdHJpbmdCdWlsZGVyIHJlc3VsdCA9IHRocmVhZExvY2FsU3RyaW5nQnVpbGRlci5nZXQoKTsKLSAgICAgICAgcmVzdWx0LnNldExlbmd0aCgwKTsKLQotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbjsgaSsrKSB7Ci0gICAgICAgICAgICBmaW5hbCBjaGFyIGNoID0gYmFzZS5jaGFyQXQoaSk7Ci0gICAgICAgICAgICBmaW5hbCBpbnQgayA9IGRlbGltLmluZGV4T2YoY2gpOwotCi0gICAgICAgICAgICBpZiAoayA+PSAwKSB7Ci0gICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChzdHJba10pOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChjaCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHJlc3VsdC50b1N0cmluZygpOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogVXRpbGl0eSBtZXRob2QgdG8gYWxsb3cgc2V0dGluZyBwYXJhbWV0ZXJzIG9mIHRoZSBmb3JtCi0gICAgICoge25hbWVzcGFjZXVyaX1sb2NhbE5hbWUKLSAgICAgKiB3aGljaCBnZXQgbWFwcGVkIHRvIGFuIGluc3RhbmNlIHZhcmlhYmxlIGluIHRoZSBjbGFzcwotICAgICAqIEhlbmNlICBhIHBhcmFtZXRlciBvZiB0aGUgZm9ybSAie2h0dHA6Ly9mb28uYmFyfXh5eiIKLSAgICAgKiB3aWxsIGJlIHJlcGxhY2VkIHdpdGggdGhlIGNvcnJlc3BvbmRpbmcgdmFsdWVzCi0gICAgICogYnkgdGhlIEJhc2lzTGlicmFyeSdzIHV0aWxpdHkgbWV0aG9kIG1hcFFOYW1ldG9KYXZhTmFtZQotICAgICAqIGFuZCB0aHVzIGdldCBtYXBwZWQgdG8gbGVnYWwgamF2YSB2YXJpYWJsZSBuYW1lcwotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIG1hcFFOYW1lVG9KYXZhTmFtZSAoU3RyaW5nIGJhc2UgKSB7Ci0gICAgICAgcmV0dXJuIHJlcGxhY2UoYmFzZSwgIi4tOi97fT8jJSoiLAotICAgICAgICAgICAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7ICIkZG90JCIsICIkZGFzaCQiICwiJGNvbG9uJCIsICIkc2xhc2gkIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIiwiJGNvbG9uJCIsIiRxdWVzJCIsIiRoYXNoJCIsIiRwZXIkIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiJGFzdGVyJCJ9KTsKLQotICAgIH0KLQotICAgIC8qKgotICAgICAqICBVdGlsaXR5IG1ldGhvZCB0byBjYWxjdWxhdGUgc3RyaW5nLWxlbmd0aCBhcyBhIG51bWJlciBvZiBjb2RlIHBvaW50cywKLSAgICAgKiAgdG8gYXZvaWQgcG9zc2libGUgZXJyb3JzIHdpdGggc3RyaW5nIHRoYXQgY29udGFpbnMKLSAgICAgKiAgY29tcGxlbWVudGFyeSBjaGFyYWN0ZXJzCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBpbnQgZ2V0U3RyaW5nTGVuZ3RoKFN0cmluZyBzdHIpIHsKLSAgICAgICAgcmV0dXJuIHN0ci5jb2RlUG9pbnRDb3VudCgwLHN0ci5sZW5ndGgoKSk7Ci0gICAgfQotCi0gICAgLy8tLSBFbmQgdXRpbGl0eSBmdW5jdGlvbnMKLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9Db25zdGFudHMuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9Db25zdGFudHMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNzRhODdhNy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvQ29uc3RhbnRzLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw1MyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBDb25zdGFudHMuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8wNiAxMTowMToyOSBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMucnVudGltZTsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTTsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGRlZmluZXMgY29uc3RhbnRzIHVzZWQgYnkgYm90aCB0aGUgY29tcGlsZXIgYW5kIHRoZQotICogcnVudGltZSBzeXN0ZW0uCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgQ29uc3RhbnRzIHsKLQotICAgIGZpbmFsIHN0YXRpYyBpbnQgQU5ZICAgICAgID0gLTE7Ci0gICAgZmluYWwgc3RhdGljIGludCBBVFRSSUJVVEUgPSAtMjsKLSAgICBmaW5hbCBzdGF0aWMgaW50IFJPT1QgICAgICA9IERUTS5ST09UX05PREU7Ci0gICAgZmluYWwgc3RhdGljIGludCBURVhUICAgICAgPSBEVE0uVEVYVF9OT0RFOwotICAgIGZpbmFsIHN0YXRpYyBpbnQgRUxFTUVOVCAgID0gRFRNLkVMRU1FTlRfTk9ERTsKLSAgICBmaW5hbCBzdGF0aWMgaW50IENPTU1FTlQgICA9IERUTS5DT01NRU5UX05PREU7Ci0gICAgZmluYWwgc3RhdGljIGludCBQUk9DRVNTSU5HX0lOU1RSVUNUSU9OID0gRFRNLlBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERTsKLQotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFhTTFRfVVJJID0gImh0dHA6Ly93d3cudzMub3JnLzE5OTkvWFNML1RyYW5zZm9ybSI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTkFNRVNQQUNFX0ZFQVRVUkUgPQotICAgICAgICAiaHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL25hbWVzcGFjZXMiOwotCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRU1QVFlTVFJJTkcgPSAiIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxfUFJFRklYID0gInhtbCI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MTlNfUFJFRklYID0gInhtbG5zIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxOU19TVFJJTkcgPSAieG1sbnM6IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxOU19VUkkgPSAiaHR0cDovL3d3dy53My5vcmcvMjAwMC94bWxucy8iOwotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ydW50aW1lL0Vycm9yTWVzc2FnZXMuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9FcnJvck1lc3NhZ2VzLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGZlOThhZTkuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ydW50aW1lL0Vycm9yTWVzc2FnZXMuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI4NCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnJ1bnRpbWU7Ci0KLWltcG9ydCBqYXZhLnV0aWwuTGlzdFJlc291cmNlQnVuZGxlOwotCi0vKioKLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICovCi1wdWJsaWMgY2xhc3MgRXJyb3JNZXNzYWdlcyBleHRlbmRzIExpc3RSZXNvdXJjZUJ1bmRsZSB7Ci0KLS8qCi0gKiBYU0xUQyBydW4tdGltZSBlcnJvciBtZXNzYWdlcy4KLSAqCi0gKiBHZW5lcmFsIG5vdGVzIHRvIHRyYW5zbGF0b3JzIGFuZCBkZWZpbml0aW9uczoKLSAqCi0gKiAgIDEpIFhTTFRDIGlzIHRoZSBuYW1lIG9mIHRoZSBwcm9kdWN0LiAgSXQgaXMgYW4gYWNyb255bSBmb3IgWE1MIFN0eWxlc2hlZXQ6Ci0gKiAgICAgIFRyYW5zZm9ybWF0aW9ucyBDb21waWxlcgotICoKLSAqICAgMikgQSBzdHlsZXNoZWV0IGlzIGEgZGVzY3JpcHRpb24gb2YgaG93IHRvIHRyYW5zZm9ybSBhbiBpbnB1dCBYTUwgZG9jdW1lbnQKLSAqICAgICAgaW50byBhIHJlc3VsdGFudCBvdXRwdXQgWE1MIGRvY3VtZW50IChvciBIVE1MIGRvY3VtZW50IG9yIHRleHQpCi0gKgotICogICAzKSBBbiBheGlzIGlzIGEgcGFydGljdWxhciAiZGltZW5zaW9uIiBpbiBhIHRyZWUgcmVwcmVzZW50YXRpb24gb2YgYW4gWE1MCi0gKiAgICAgIGRvY3VtZW50OyB0aGUgbm9kZXMgaW4gdGhlIHRyZWUgYXJlIGRpdmlkZWQgYWxvbmcgZGlmZmVyZW50IGF4ZXMuCi0gKiAgICAgIFRyYXZlcnNpbmcgdGhlICJjaGlsZCIgYXhpcywgZm9yIGluc3RhbmNlLCBtZWFucyB0aGF0IHRoZSBwcm9ncmFtCi0gKiAgICAgIHdvdWxkIHZpc2l0IGVhY2ggY2hpbGQgb2YgYSBwYXJ0aWN1bGFyIG5vZGU7IHRyYXZlcnNpbmcgdGhlICJkZXNjZW5kYW50IgotICogICAgICBheGlzIG1lYW5zIHRoYXQgdGhlIHByb2dyYW0gd291bGQgdmlzaXQgdGhlIGNoaWxkIG5vZGVzIG9mIGEgcGFydGljdWxhcgotICogICAgICBub2RlLCB0aGVpciBjaGlsZHJlbiwgYW5kIHNvIG9uIHVudGlsIHRoZSBsZWFmIG5vZGVzIG9mIHRoZSB0cmVlIGFyZQotICogICAgICByZWFjaGVkLgotICoKLSAqICAgNCkgQW4gaXRlcmF0b3IgaXMgYW4gb2JqZWN0IHRoYXQgdHJhdmVyc2VzIG5vZGVzIGluIGEgdHJlZSBhbG9uZyBhCi0gKiAgICAgIHBhcnRpY3VsYXIgYXhpcywgb25lIGF0IGEgdGltZS4KLSAqCi0gKiAgIDUpIEFuIGVsZW1lbnQgaXMgYSBtYXJrLXVwIHRhZyBpbiBhbiBYTUwgZG9jdW1lbnQ7IGFuIGF0dHJpYnV0ZSBpcyBhCi0gKiAgICAgIG1vZGlmaWVyIG9uIHRoZSB0YWcuICBGb3IgZXhhbXBsZSwgaW4gPGVsZW0gYXR0cj0ndmFsJyBhdHRyMj0ndmFsMic+Ci0gKiAgICAgICJlbGVtIiBpcyBhbiBlbGVtZW50IG5hbWUsICJhdHRyIiBhbmQgImF0dHIyIiBhcmUgYXR0cmlidXRlIG5hbWVzIHdpdGgKLSAqICAgICAgdGhlIHZhbHVlcyAidmFsIiBhbmQgInZhbDIiLCByZXNwZWN0aXZlbHkuCi0gKgotICogICA2KSBBIG5hbWVzcGFjZSBkZWNsYXJhdGlvbiBpcyBhIHNwZWNpYWwgYXR0cmlidXRlIHRoYXQgaXMgdXNlZCB0byBhc3NvY2lhdGUKLSAqICAgICAgYSBwcmVmaXggd2l0aCBhIFVSSSAodGhlIG5hbWVzcGFjZSkuICBUaGUgbWVhbmluZ3Mgb2YgZWxlbWVudCBuYW1lcyBhbmQKLSAqICAgICAgYXR0cmlidXRlIG5hbWVzIHRoYXQgdXNlIHRoYXQgcHJlZml4IGFyZSBkZWZpbmVkIHdpdGggcmVzcGVjdCB0byB0aGF0Ci0gKiAgICAgIG5hbWVzcGFjZS4KLSAqCi0gKiAgIDcpIERPTSBpcyBhbiBhY3JvbnltIGZvciBEb2N1bWVudCBPYmplY3QgTW9kZWwuICBJdCBpcyBhIHRyZWUKLSAqICAgICAgcmVwcmVzZW50YXRpb24gb2YgYW4gWE1MIGRvY3VtZW50LgotICoKLSAqICAgICAgU0FYIGlzIGFuIGFjcm9ueW0gZm9yIHRoZSBTaW1wbGUgQVBJIGZvciBYTUwgcHJvY2Vzc2luZy4gIEl0IGlzIGFuIEFQSQotICogICAgICB1c2VkIGluZm9ybSBhbiBYTUwgcHJvY2Vzc29yIChpbiB0aGlzIGNhc2UgWFNMVEMpIG9mIHRoZSBzdHJ1Y3R1cmUgYW5kCi0gKiAgICAgIGNvbnRlbnQgb2YgYW4gWE1MIGRvY3VtZW50LgotICoKLSAqICAgICAgSW5wdXQgdG8gdGhlIHN0eWxlc2hlZXQgcHJvY2Vzc29yIGNhbiBjb21lIGZyb20gYW4gWE1MIHBhcnNlciBpbiB0aGUKLSAqICAgICAgZm9ybSBvZiBhIERPTSB0cmVlIG9yIHRocm91Z2ggdGhlIFNBWCBBUEkuCi0gKgotICogICA4KSBEVEQgaXMgYSBkb2N1bWVudCB0eXBlIGRlY2xhcmF0aW9uLiAgSXQgaXMgYSB3YXkgb2Ygc3BlY2lmeWluZyB0aGUKLSAqICAgICAgZ3JhbW1hciBmb3IgYW4gWE1MIGZpbGUsIHRoZSBuYW1lcyBhbmQgdHlwZXMgb2YgZWxlbWVudHMsIGF0dHJpYnV0ZXMsCi0gKiAgICAgIGV0Yy4KLSAqCi0gKiAgIDkpIFRyYW5zbGV0IGlzIGFuIGludmVudGVkIHRlcm0gdGhhdCByZWZlcnMgdG8gdGhlIGNsYXNzIGZpbGUgdGhhdCBjb250YWlucwotICogICAgICB0aGUgY29tcGlsZWQgZm9ybSBvZiBhIHN0eWxlc2hlZXQuCi0gKi8KLQotICAgIC8vIFRoZXNlIG1lc3NhZ2Ugc2hvdWxkIGJlIHJlYWQgZnJvbSBhIGxvY2FsZS1zcGVjaWZpYyByZXNvdXJjZSBidW5kbGUKLSAgICAvKiogR2V0IHRoZSBsb29rdXAgdGFibGUgZm9yIGVycm9yIG1lc3NhZ2VzLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgbWVzc2FnZSBsb29rdXAgdGFibGUuCi0gICAgICovCi0gICAgcHVibGljIE9iamVjdFtdW10gZ2V0Q29udGVudHMoKQotICAgIHsKLSAgICAgICAgcmV0dXJuIG5ldyBPYmplY3RbXVtdIHsKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgdGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGluIHRoZSBmb2xsb3dpbmcgbWVzc2FnZQotICAgICAgICAgKiBpcyBhIGNsYXNzIG5hbWUuICBVc2VkIGZvciBpbnRlcm5hbCBlcnJvcnMgaW4gdGhlIHByb2Nlc3Nvci4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuUlVOX1RJTUVfSU5URVJOQUxfRVJSLAotICAgICAgICAiUnVuLXRpbWUgaW50ZXJuYWwgZXJyb3IgaW4gJyd7MH0nJyJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICA8eHNsOmNvcHk+IGlzIGEga2V5d29yZCB0aGF0IHNob3VsZCBub3QgYmUKLSAgICAgICAgICogdHJhbnNsYXRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuUlVOX1RJTUVfQ09QWV9FUlIsCi0gICAgICAgICJSdW4tdGltZSBlcnJvciB3aGVuIGV4ZWN1dGluZyA8eHNsOmNvcHk+LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgcmVmZXJzIHRvIGRhdGEgdHlwZXMuCi0gICAgICAgICAqIFRoZSBtZXNzYWdlIGlzIGRpc3BsYXllZCBpZiBhIHZhbHVlIGluIGEgcGFydGljdWxhciBjb250ZXh0IG5lZWRzIHRvCi0gICAgICAgICAqIGJlIGNvbnZlcnRlZCB0byB0eXBlIHsxfSwgYnV0IHRoYXQncyBub3QgcG9zc2libGUgZm9yIGEgdmFsdWUgb2YgdHlwZQotICAgICAgICAgKiB7MH0uCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LkRBVEFfQ09OVkVSU0lPTl9FUlIsCi0gICAgICAgICJJbnZhbGlkIGNvbnZlcnNpb24gZnJvbSAnJ3swfScnIHRvICcnezF9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyBkaXNwbGF5ZWQgaWYgdGhlIGZ1bmN0aW9uIG5hbWVkCi0gICAgICAgICAqIGJ5IHRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyBub3QgYSBmdW5jdGlvbiB0aGF0IGlzIHN1cHBvcnRlZC4gIFhTTFRDCi0gICAgICAgICAqIGlzIHRoZSBhY3JvbnltIG5hbWluZyB0aGUgcHJvZHVjdC4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuRVhURVJOQUxfRlVOQ19FUlIsCi0gICAgICAgICJFeHRlcm5hbCBmdW5jdGlvbiAnJ3swfScnIG5vdCBzdXBwb3J0ZWQgYnkgWFNMVEMuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyBkaXNwbGF5ZWQgaWYgdHdvIHZhbHVlcyBhcmUKLSAgICAgICAgICogY29tcGFyZWQgZm9yIGVxdWFsaXR5LCBidXQgdGhlIGRhdGEgdHlwZSBvZiBvbmUgb2YgdGhlIHZhbHVlcyBpcwotICAgICAgICAgKiB1bmtub3duLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5FUVVBTElUWV9FWFBSX0VSUiwKLSAgICAgICAgIlVua25vd24gYXJndW1lbnQgdHlwZSBpbiBlcXVhbGl0eSBleHByZXNzaW9uLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgZm9yIHswfSB3aWxsIGJlIGEgZGF0YQotICAgICAgICAgKiB0eXBlOyB0aGUgc3Vic3RpdHV0aW9uIHRleHQgZm9yIHsxfSB3aWxsIGJlIHRoZSBuYW1lIG9mIGEgZnVuY3Rpb24uCi0gICAgICAgICAqIFRoaXMgaXMgZGlzcGxheWVkIGlmIGFuIGFyZ3VtZW50IG9mIHRoZSBwYXJ0aWN1bGFyIGRhdGEgdHlwZSBpcyBub3QKLSAgICAgICAgICogcGVybWl0dGVkIGZvciBhIGNhbGwgdG8gdGhpcyBmdW5jdGlvbi4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuSU5WQUxJRF9BUkdVTUVOVF9FUlIsCi0gICAgICAgICJJbnZhbGlkIGFyZ3VtZW50IHR5cGUgJyd7MH0nJyBpbiBjYWxsIHRvICcnezF9JycifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlcmUgaXMgd2F5IG9mIHNwZWNpZnlpbmcgYSBmb3JtYXQgZm9yIGEKLSAgICAgICAgICogbnVtYmVyIHVzaW5nIGEgcGF0dGVybjsgdGhlIHByb2Nlc3NvciB3YXMgdW5hYmxlIHRvIGZvcm1hdCB0aGUKLSAgICAgICAgICogcGFydGljdWxhciB2YWx1ZSB1c2luZyB0aGUgc3BlY2lmaWVkIHBhdHRlcm4uCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LkZPUk1BVF9OVU1CRVJfRVJSLAotICAgICAgICAiQXR0ZW1wdGluZyB0byBmb3JtYXQgbnVtYmVyICcnezB9JycgdXNpbmcgcGF0dGVybiAnJ3sxfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIHJlcHJlc2VudHMgYW4gaW50ZXJuYWwgZXJyb3IKLSAgICAgICAgICogc2l0dWF0aW9uIGluIFhTTFRDLiAgVGhlIHByb2Nlc3NvciB3YXMgdW5hYmxlIHRvIGNyZWF0ZSBhIGNvcHkgb2YgYW4KLSAgICAgICAgICogaXRlcmF0b3IuICAoU2VlIGRlZmluaXRpb24gb2YgaXRlcmF0b3IgYWJvdmUuKQotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5JVEVSQVRPUl9DTE9ORV9FUlIsCi0gICAgICAgICJDYW5ub3QgY2xvbmUgaXRlcmF0b3IgJyd7MH0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyByZXByZXNlbnRzIGFuIGludGVybmFsIGVycm9yCi0gICAgICAgICAqIHNpdHVhdGlvbiBpbiBYU0xUQy4gIFRoZSBwcm9jZXNzb3IgYXR0ZW1wdGVkIHRvIGNyZWF0ZSBhbiBpdGVyYXRvcgotICAgICAgICAgKiBmb3IgYSBwYXJ0aWN1bGFyIGF4aXMgKHNlZSBkZWZpbml0aW9uIGFib3ZlKSB0aGF0IGl0IGRvZXMgbm90Ci0gICAgICAgICAqIHN1cHBvcnQuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LkFYSVNfU1VQUE9SVF9FUlIsCi0gICAgICAgICJJdGVyYXRvciBmb3IgYXhpcyAnJ3swfScnIG5vdCBzdXBwb3J0ZWQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgcmVwcmVzZW50cyBhbiBpbnRlcm5hbCBlcnJvcgotICAgICAgICAgKiBzaXR1YXRpb24gaW4gWFNMVEMuICBUaGUgcHJvY2Vzc29yIGF0dGVtcHRlZCB0byBjcmVhdGUgYW4gaXRlcmF0b3IKLSAgICAgICAgICogZm9yIGEgcGFydGljdWxhciBheGlzIChzZWUgZGVmaW5pdGlvbiBhYm92ZSkgdGhhdCBpdCBkb2VzIG5vdAotICAgICAgICAgKiBzdXBwb3J0LgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5UWVBFRF9BWElTX1NVUFBPUlRfRVJSLAotICAgICAgICAiSXRlcmF0b3IgZm9yIHR5cGVkIGF4aXMgJyd7MH0nJyBub3Qgc3VwcG9ydGVkLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgcmVwb3J0ZWQgaWYgdGhlIHN0eWxlc2hlZXQKLSAgICAgICAgICogYmVpbmcgcHJvY2Vzc2VkIGF0dGVtcHRlZCB0byBjb25zdHJ1Y3QgYW4gWE1MIGRvY3VtZW50IHdpdGggYW4KLSAgICAgICAgICogYXR0cmlidXRlIGluIGEgcGxhY2Ugb3RoZXIgdGhhbiBvbiBhbiBlbGVtZW50LiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgICAqIHNwZWNpZmllcyB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5TVFJBWV9BVFRSSUJVVEVfRVJSLAotICAgICAgICAiQXR0cmlidXRlICcnezB9Jycgb3V0c2lkZSBvZiBlbGVtZW50LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBcyB3aXRoIHRoZSBwcmVjZWRpbmcgbWVzc2FnZSwgYSBuYW1lc3BhY2UKLSAgICAgICAgICogZGVjbGFyYXRpb24gaGFzIHRoZSBmb3JtIG9mIGFuIGF0dHJpYnV0ZSBhbmQgaXMgb25seSBwZXJtaXR0ZWQgdG8KLSAgICAgICAgICogYXBwZWFyIG9uIGFuIGVsZW1lbnQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgezB9IGlzIHRoZSBuYW1lc3BhY2UKLSAgICAgICAgICogcHJlZml4IGFuZCB7MX0gaXMgdGhlIFVSSSB0aGF0IHdhcyBiZWluZyB1c2VkIGluIHRoZSBlcnJvbmVvdXMKLSAgICAgICAgICogbmFtZXNwYWNlIGRlY2xhcmF0aW9uLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5TVFJBWV9OQU1FU1BBQ0VfRVJSLAotICAgICAgICAiTmFtZXNwYWNlIGRlY2xhcmF0aW9uICcnezB9Jyc9Jyd7MX0nJyBvdXRzaWRlIG9mIGVsZW1lbnQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IGNvbnRhaW5lZCBhIHJlZmVyZW5jZSB0byBhCi0gICAgICAgICAqIG5hbWVzcGFjZSBwcmVmaXggdGhhdCB3YXMgdW5kZWZpbmVkLiAgVGhlIHZhbHVlIG9mIHRoZSBzdWJzdGl0dXRpb24KLSAgICAgICAgICogdGV4dCBpcyB0aGUgbmFtZSBvZiB0aGUgcHJlZml4LgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5OQU1FU1BBQ0VfUFJFRklYX0VSUiwKLSAgICAgICAgIk5hbWVzcGFjZSBmb3IgcHJlZml4ICcnezB9JycgaGFzIG5vdCBiZWVuIGRlY2xhcmVkLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIHJlcHJlc2VudHMgYW4gaW50ZXJuYWwgZXJyb3IuCi0gICAgICAgICAqIERPTUFkYXB0ZXIgaXMgYSBKYXZhIGNsYXNzIGluIFhTTFRDLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5ET01fQURBUFRFUl9JTklUX0VSUiwKLSAgICAgICAgIkRPTUFkYXB0ZXIgY3JlYXRlZCB1c2luZyB3cm9uZyB0eXBlIG9mIHNvdXJjZSBET00uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUgWE1MCi0gICAgICAgICAqIHBhcnNlciB0aGF0IGlzIHByb3ZpZGluZyBpbnB1dCB0byBYU0xUQyBjYW5ub3QgYmUgdXNlZCBiZWNhdXNlIGl0Ci0gICAgICAgICAqIGRvZXMgbm90IGRlc2NyaWJlIHRvIFhTTFRDIHRoZSBzdHJ1Y3R1cmUgb2YgdGhlIGlucHV0IFhNTCBkb2N1bWVudCdzCi0gICAgICAgICAqIERURC4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuUEFSU0VSX0RURF9TVVBQT1JUX0VSUiwKLSAgICAgICAgIlRoZSBTQVggcGFyc2VyIHlvdSBhcmUgdXNpbmcgZG9lcyBub3QgaGFuZGxlIERURCBkZWNsYXJhdGlvbiBldmVudHMuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUgWE1MCi0gICAgICAgICAqIHBhcnNlciB0aGF0IGlzIHByb3ZpZGluZyBpbnB1dCB0byBYU0xUQyBjYW5ub3QgYmUgdXNlZCBiZWNhdXNlIGl0Ci0gICAgICAgICAqIGRvZXMgbm90IGRpc3Rpbmd1aXNoIGJldHdlZW4gb3JkaW5hcnkgWE1MIGF0dHJpYnV0ZXMgYW5kIG5hbWVzcGFjZQotICAgICAgICAgKiBkZWNsYXJhdGlvbnMuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5Lk5BTUVTUEFDRVNfU1VQUE9SVF9FUlIsCi0gICAgICAgICJUaGUgU0FYIHBhcnNlciB5b3UgYXJlIHVzaW5nIGRvZXMgbm90IGhhdmUgc3VwcG9ydCBmb3IgWE1MIE5hbWVzcGFjZXMuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgVVJJIHRoYXQgd2FzIGluCi0gICAgICAgICAqIGVycm9yLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5DQU5UX1JFU09MVkVfUkVMQVRJVkVfVVJJX0VSUiwKLSAgICAgICAgIkNvdWxkIG5vdCByZXNvbHZlIHRoZSBVUkkgcmVmZXJlbmNlICcnezB9JycuIn0sCi0KLSAgICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3R5bGVzaGVldCBjb250YWluZWQgYW4gZWxlbWVudCB0aGF0IHdhcwotICAgICAgICAgKiBub3QgcmVjb2duaXplZCBhcyBwYXJ0IG9mIHRoZSBYU0wgc3ludGF4LiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgICAqIGdpdmVzIHRoZSBlbGVtZW50IG5hbWUuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LlVOU1VQUE9SVEVEX1hTTF9FUlIsCi0gICAgICAgICJVbnN1cHBvcnRlZCBYU0wgZWxlbWVudCAnJ3swfScnIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IHJlZmVycmVkIHRvIGFuIGV4dGVuc2lvbiB0byB0aGUKLSAgICAgICAgICogWFNMIHN5bnRheCBhbmQgaW5kaWNhdGVkIHRoYXQgaXQgd2FzIGRlZmluZWQgYnkgWFNMVEMsIGJ1dCBYU0xUQyBkb2VzCi0gICAgICAgICAqIG5vdCByZWNvZ25pemUgdGhlIHBhcnRpY3VsYXIgZXh0ZW5zaW9uIG5hbWVkLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgICAqIGdpdmVzIHRoZSBleHRlbnNpb24gbmFtZS4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuVU5TVVBQT1JURURfRVhUX0VSUiwKLSAgICAgICAgIlVucmVjb2duaXplZCBYU0xUQyBleHRlbnNpb24gJyd7MH0nJyJ9LAotCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgZXJyb3IgbWVzc2FnZSBpcyBwcm9kdWNlZCBpZiB0aGUgdHJhbnNsZXQKLSAgICAgICAgICogY2xhc3Mgd2FzIGNvbXBpbGVkIHVzaW5nIGEgbmV3ZXIgdmVyc2lvbiBvZiBYU0xUQyBhbmQgZGVwbG95ZWQgZm9yCi0gICAgICAgICAqIGV4ZWN1dGlvbiB3aXRoIGFuIG9sZGVyIHZlcnNpb24gb2YgWFNMVEMuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMKLSAgICAgICAgICogdGhlIG5hbWUgb2YgdGhlIHRyYW5zbGV0IGNsYXNzLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5VTktOT1dOX1RSQU5TTEVUX1ZFUlNJT05fRVJSLAotICAgICAgICAiVGhlIHNwZWNpZmllZCB0cmFuc2xldCwgJyd7MH0nJywgd2FzIGNyZWF0ZWQgdXNpbmcgYSB2ZXJzaW9uIG9mIFhTTFRDIG1vcmUgcmVjZW50IHRoYW4gdGhlIHZlcnNpb24gb2YgdGhlIFhTTFRDIHJ1bi10aW1lIHRoYXQgaXMgaW4gdXNlLiAgWW91IG11c3QgcmVjb21waWxlIHRoZSBzdHlsZXNoZWV0IG9yIHVzZSBhIG1vcmUgcmVjZW50IHZlcnNpb24gb2YgWFNMVEMgdG8gcnVuIHRoaXMgdHJhbnNsZXQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIGF0dHJpYnV0ZSB3aG9zZSBlZmZlY3RpdmUgdmFsdWUgaXMgcmVxdWlyZWQKLSAgICAgICAgICogdG8gYmUgYSAiUU5hbWUiIGhhZCBhIHZhbHVlIHRoYXQgd2FzIGluY29ycmVjdC4KLSAgICAgICAgICogJ1FOYW1lJyBpcyBhbiBYTUwgc3ludGFjdGljIHRlcm0gdGhhdCBtdXN0IG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhlCi0gICAgICAgICAqIHN1YnN0aXR1dGlvbiB0ZXh0IGNvbnRhaW5zIHRoZSBhY3R1YWwgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuSU5WQUxJRF9RTkFNRV9FUlIsCi0gICAgICAgICJBbiBhdHRyaWJ1dGUgd2hvc2UgdmFsdWUgbXVzdCBiZSBhIFFOYW1lIGhhZCB0aGUgdmFsdWUgJyd7MH0nJyJ9LAotCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIGF0dHJpYnV0ZSB3aG9zZSBlZmZlY3RpdmUgdmFsdWUgaXMgcmVxdWlyZWQKLSAgICAgICAgICogdG8gYmUgYSAiTkNOYW1lIiBoYWQgYSB2YWx1ZSB0aGF0IHdhcyBpbmNvcnJlY3QuCi0gICAgICAgICAqICdOQ05hbWUnIGlzIGFuIFhNTCBzeW50YWN0aWMgdGVybSB0aGF0IG11c3Qgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGUKLSAgICAgICAgICogc3Vic3RpdHV0aW9uIHRleHQgY29udGFpbnMgdGhlIGFjdHVhbCB2YWx1ZSBvZiB0aGUgYXR0cmlidXRlLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5JTlZBTElEX05DTkFNRV9FUlIsCi0gICAgICAgICJBbiBhdHRyaWJ1dGUgd2hvc2UgdmFsdWUgbXVzdCBiZSBhbiBOQ05hbWUgaGFkIHRoZSB2YWx1ZSAnJ3swfScnIn0sCi0KLSAgICAgICAge0Jhc2lzTGlicmFyeS5VTkFMTE9XRURfRVhURU5TSU9OX0ZVTkNUSU9OX0VSUiwKLSAgICAgICAgIlVzZSBvZiB0aGUgZXh0ZW5zaW9uIGZ1bmN0aW9uICcnezB9JycgaXMgbm90IGFsbG93ZWQgd2hlbiB0aGUgc2VjdXJlIHByb2Nlc3NpbmcgZmVhdHVyZSBpcyBzZXQgdG8gdHJ1ZS4ifSwKLQotICAgICAgICB7QmFzaXNMaWJyYXJ5LlVOQUxMT1dFRF9FWFRFTlNJT05fRUxFTUVOVF9FUlIsCi0gICAgICAgICJVc2Ugb2YgdGhlIGV4dGVuc2lvbiBlbGVtZW50ICcnezB9JycgaXMgbm90IGFsbG93ZWQgd2hlbiB0aGUgc2VjdXJlIHByb2Nlc3NpbmcgZmVhdHVyZSBpcyBzZXQgdG8gdHJ1ZS4ifSwKLSAgICB9OwotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ydW50aW1lL0Vycm9yTWVzc2FnZXNfY2EuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9FcnJvck1lc3NhZ2VzX2NhLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGEyYjJiYTEuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ydW50aW1lL0Vycm9yTWVzc2FnZXNfY2EuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIzNCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBFcnJvck1lc3NhZ2VzX2NhLmphdmEsdiAxLjEuNi4xIDIwMDUvMDkvMDYgMTA6NDU6MzcgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnJ1bnRpbWU7Ci0KLWltcG9ydCBqYXZhLnV0aWwuTGlzdFJlc291cmNlQnVuZGxlOwotCi0vKioKLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICovCi1wdWJsaWMgY2xhc3MgRXJyb3JNZXNzYWdlc19jYSBleHRlbmRzIExpc3RSZXNvdXJjZUJ1bmRsZSB7Ci0KLS8qCi0gKiBYU0xUQyBydW4tdGltZSBlcnJvciBtZXNzYWdlcy4KLSAqCi0gKiBHZW5lcmFsIG5vdGVzIHRvIHRyYW5zbGF0b3JzIGFuZCBkZWZpbml0aW9uczoKLSAqCi0gKiAgIDEpIFhTTFRDIGlzIHRoZSBuYW1lIG9mIHRoZSBwcm9kdWN0LiAgSXQgaXMgYW4gYWNyb255bSBmb3IgWE1MIFN0eWxlc2hlZXQ6Ci0gKiAgICAgIFRyYW5zZm9ybWF0aW9ucyBDb21waWxlcgotICoKLSAqICAgMikgQSBzdHlsZXNoZWV0IGlzIGEgZGVzY3JpcHRpb24gb2YgaG93IHRvIHRyYW5zZm9ybSBhbiBpbnB1dCBYTUwgZG9jdW1lbnQKLSAqICAgICAgaW50byBhIHJlc3VsdGFudCBvdXRwdXQgWE1MIGRvY3VtZW50IChvciBIVE1MIGRvY3VtZW50IG9yIHRleHQpCi0gKgotICogICAzKSBBbiBheGlzIGlzIGEgcGFydGljdWxhciAiZGltZW5zaW9uIiBpbiBhIHRyZWUgcmVwcmVzZW50YXRpb24gb2YgYW4gWE1MCi0gKiAgICAgIGRvY3VtZW50OyB0aGUgbm9kZXMgaW4gdGhlIHRyZWUgYXJlIGRpdmlkZWQgYWxvbmcgZGlmZmVyZW50IGF4ZXMuCi0gKiAgICAgIFRyYXZlcnNpbmcgdGhlICJjaGlsZCIgYXhpcywgZm9yIGluc3RhbmNlLCBtZWFucyB0aGF0IHRoZSBwcm9ncmFtCi0gKiAgICAgIHdvdWxkIHZpc2l0IGVhY2ggY2hpbGQgb2YgYSBwYXJ0aWN1bGFyIG5vZGU7IHRyYXZlcnNpbmcgdGhlICJkZXNjZW5kYW50IgotICogICAgICBheGlzIG1lYW5zIHRoYXQgdGhlIHByb2dyYW0gd291bGQgdmlzaXQgdGhlIGNoaWxkIG5vZGVzIG9mIGEgcGFydGljdWxhcgotICogICAgICBub2RlLCB0aGVpciBjaGlsZHJlbiwgYW5kIHNvIG9uIHVudGlsIHRoZSBsZWFmIG5vZGVzIG9mIHRoZSB0cmVlIGFyZQotICogICAgICByZWFjaGVkLgotICoKLSAqICAgNCkgQW4gaXRlcmF0b3IgaXMgYW4gb2JqZWN0IHRoYXQgdHJhdmVyc2VzIG5vZGVzIGluIGEgdHJlZSBhbG9uZyBhCi0gKiAgICAgIHBhcnRpY3VsYXIgYXhpcywgb25lIGF0IGEgdGltZS4KLSAqCi0gKiAgIDUpIEFuIGVsZW1lbnQgaXMgYSBtYXJrLXVwIHRhZyBpbiBhbiBYTUwgZG9jdW1lbnQ7IGFuIGF0dHJpYnV0ZSBpcyBhCi0gKiAgICAgIG1vZGlmaWVyIG9uIHRoZSB0YWcuICBGb3IgZXhhbXBsZSwgaW4gPGVsZW0gYXR0cj0ndmFsJyBhdHRyMj0ndmFsMic+Ci0gKiAgICAgICJlbGVtIiBpcyBhbiBlbGVtZW50IG5hbWUsICJhdHRyIiBhbmQgImF0dHIyIiBhcmUgYXR0cmlidXRlIG5hbWVzIHdpdGgKLSAqICAgICAgdGhlIHZhbHVlcyAidmFsIiBhbmQgInZhbDIiLCByZXNwZWN0aXZlbHkuCi0gKgotICogICA2KSBBIG5hbWVzcGFjZSBkZWNsYXJhdGlvbiBpcyBhIHNwZWNpYWwgYXR0cmlidXRlIHRoYXQgaXMgdXNlZCB0byBhc3NvY2lhdGUKLSAqICAgICAgYSBwcmVmaXggd2l0aCBhIFVSSSAodGhlIG5hbWVzcGFjZSkuICBUaGUgbWVhbmluZ3Mgb2YgZWxlbWVudCBuYW1lcyBhbmQKLSAqICAgICAgYXR0cmlidXRlIG5hbWVzIHRoYXQgdXNlIHRoYXQgcHJlZml4IGFyZSBkZWZpbmVkIHdpdGggcmVzcGVjdCB0byB0aGF0Ci0gKiAgICAgIG5hbWVzcGFjZS4KLSAqCi0gKiAgIDcpIERPTSBpcyBhbiBhY3JvbnltIGZvciBEb2N1bWVudCBPYmplY3QgTW9kZWwuICBJdCBpcyBhIHRyZWUKLSAqICAgICAgcmVwcmVzZW50YXRpb24gb2YgYW4gWE1MIGRvY3VtZW50LgotICoKLSAqICAgICAgU0FYIGlzIGFuIGFjcm9ueW0gZm9yIHRoZSBTaW1wbGUgQVBJIGZvciBYTUwgcHJvY2Vzc2luZy4gIEl0IGlzIGFuIEFQSQotICogICAgICB1c2VkIGluZm9ybSBhbiBYTUwgcHJvY2Vzc29yIChpbiB0aGlzIGNhc2UgWFNMVEMpIG9mIHRoZSBzdHJ1Y3R1cmUgYW5kCi0gKiAgICAgIGNvbnRlbnQgb2YgYW4gWE1MIGRvY3VtZW50LgotICoKLSAqICAgICAgSW5wdXQgdG8gdGhlIHN0eWxlc2hlZXQgcHJvY2Vzc29yIGNhbiBjb21lIGZyb20gYW4gWE1MIHBhcnNlciBpbiB0aGUKLSAqICAgICAgZm9ybSBvZiBhIERPTSB0cmVlIG9yIHRocm91Z2ggdGhlIFNBWCBBUEkuCi0gKgotICogICA4KSBEVEQgaXMgYSBkb2N1bWVudCB0eXBlIGRlY2xhcmF0aW9uLiAgSXQgaXMgYSB3YXkgb2Ygc3BlY2lmeWluZyB0aGUKLSAqICAgICAgZ3JhbW1hciBmb3IgYW4gWE1MIGZpbGUsIHRoZSBuYW1lcyBhbmQgdHlwZXMgb2YgZWxlbWVudHMsIGF0dHJpYnV0ZXMsCi0gKiAgICAgIGV0Yy4KLSAqCi0gKi8KLQotICAgIC8vIFRoZXNlIG1lc3NhZ2Ugc2hvdWxkIGJlIHJlYWQgZnJvbSBhIGxvY2FsZS1zcGVjaWZpYyByZXNvdXJjZSBidW5kbGUKLSAgICAvKiogR2V0IHRoZSBsb29rdXAgdGFibGUgZm9yIGVycm9yIG1lc3NhZ2VzLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgbWVzc2FnZSBsb29rdXAgdGFibGUuCi0gICAgICovCi0gICAgcHVibGljIE9iamVjdFtdW10gZ2V0Q29udGVudHMoKQotICAgIHsKLSAgICAgICAgcmV0dXJuIG5ldyBPYmplY3RbXVtdIHsKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgdGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGluIHRoZSBmb2xsb3dpbmcgbWVzc2FnZQotICAgICAgICAgKiBpcyBhIGNsYXNzIG5hbWUuICBVc2VkIGZvciBpbnRlcm5hbCBlcnJvcnMgaW4gdGhlIHByb2Nlc3Nvci4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuUlVOX1RJTUVfSU5URVJOQUxfRVJSLAotICAgICAgICAiUycnaGEgcHJvZHVcdTAwZWZ0IHVuIGVycm9yIGludGVybiBkZSB0ZW1wcyBkJydleGVjdWNpXHUwMGYzIGEgJyd7MH0nJyJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICA8eHNsOmNvcHk+IGlzIGEga2V5d29yZCB0aGF0IHNob3VsZCBub3QgYmUKLSAgICAgICAgICogdHJhbnNsYXRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuUlVOX1RJTUVfQ09QWV9FUlIsCi0gICAgICAgICJFcyBwcm9kdWVpeCB1biBlcnJvciBkZSB0ZW1wcyBkJ2V4ZWN1Y2lcdTAwZjMgZW4gZXhlY3V0YXIgPHhzbDpjb3B5Pi4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHJlZmVycyB0byBkYXRhIHR5cGVzLgotICAgICAgICAgKiBUaGUgbWVzc2FnZSBpcyBkaXNwbGF5ZWQgaWYgYSB2YWx1ZSBpbiBhIHBhcnRpY3VsYXIgY29udGV4dCBuZWVkcyB0bwotICAgICAgICAgKiBiZSBjb252ZXJ0ZWQgdG8gdHlwZSB7MX0sIGJ1dCB0aGF0J3Mgbm90IHBvc3NpYmxlIGZvciBhIHZhbHVlIG9mIHR5cGUKLSAgICAgICAgICogezB9LgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5EQVRBX0NPTlZFUlNJT05fRVJSLAotICAgICAgICAiTGEgY29udmVyc2lcdTAwZjMgZGUgJyd7MH0nJyBhICcnezF9Jycgbm8gXHUwMGU5cyB2XHUwMGUwbGlkYS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIGRpc3BsYXllZCBpZiB0aGUgZnVuY3Rpb24gbmFtZWQKLSAgICAgICAgICogYnkgdGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIG5vdCBhIGZ1bmN0aW9uIHRoYXQgaXMgc3VwcG9ydGVkLiAgWFNMVEMKLSAgICAgICAgICogaXMgdGhlIGFjcm9ueW0gbmFtaW5nIHRoZSBwcm9kdWN0LgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5FWFRFUk5BTF9GVU5DX0VSUiwKLSAgICAgICAgIlhTTFRDIG5vIGRcdTAwZjNuYSBzdXBvcnQgYSBsYSBmdW5jaVx1MDBmMyBleHRlcm5hICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyBkaXNwbGF5ZWQgaWYgdHdvIHZhbHVlcyBhcmUKLSAgICAgICAgICogY29tcGFyZWQgZm9yIGVxdWFsaXR5LCBidXQgdGhlIGRhdGEgdHlwZSBvZiBvbmUgb2YgdGhlIHZhbHVlcyBpcwotICAgICAgICAgKiB1bmtub3duLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5FUVVBTElUWV9FWFBSX0VSUiwKLSAgICAgICAgIkwnZXhwcmVzc2lcdTAwZjMgZCdpZ3VhbHRhdCBjb250XHUwMGU5IHVuIHRpcHVzIGQnYXJndW1lbnQgZGVzY29uZWd1dC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGZvciB7MH0gd2lsbCBiZSBhIGRhdGEKLSAgICAgICAgICogdHlwZTsgdGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGZvciB7MX0gd2lsbCBiZSB0aGUgbmFtZSBvZiBhIGZ1bmN0aW9uLgotICAgICAgICAgKiBUaGlzIGlzIGRpc3BsYXllZCBpZiBhbiBhcmd1bWVudCBvZiB0aGUgcGFydGljdWxhciBkYXRhIHR5cGUgaXMgbm90Ci0gICAgICAgICAqIHBlcm1pdHRlZCBmb3IgYSBjYWxsIHRvIHRoaXMgZnVuY3Rpb24uCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LklOVkFMSURfQVJHVU1FTlRfRVJSLAotICAgICAgICAiTGEgY3JpZGEgYSAnJ3sxfScnIGNvbnRcdTAwZTkgdW4gdGlwdXMgZCcnYXJndW1lbnQgJyd7MH0nJyBubyB2XHUwMGUwbGlkLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGVyZSBpcyB3YXkgb2Ygc3BlY2lmeWluZyBhIGZvcm1hdCBmb3IgYQotICAgICAgICAgKiBudW1iZXIgdXNpbmcgYSBwYXR0ZXJuOyB0aGUgcHJvY2Vzc29yIHdhcyB1bmFibGUgdG8gZm9ybWF0IHRoZQotICAgICAgICAgKiBwYXJ0aWN1bGFyIHZhbHVlIHVzaW5nIHRoZSBzcGVjaWZpZWQgcGF0dGVybi4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuRk9STUFUX05VTUJFUl9FUlIsCi0gICAgICAgICJTJydoYSBpbnRlbnRhdCBkb25hciBmb3JtYXQgYWwgblx1MDBmYW1lcm8gJyd7MH0nJyBtaXRqYW5cdTAwZTdhbnQgZWwgcGF0clx1MDBmMyAnJ3sxfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIHJlcHJlc2VudHMgYW4gaW50ZXJuYWwgZXJyb3IKLSAgICAgICAgICogc2l0dWF0aW9uIGluIFhTTFRDLiAgVGhlIHByb2Nlc3NvciB3YXMgdW5hYmxlIHRvIGNyZWF0ZSBhIGNvcHkgb2YgYW4KLSAgICAgICAgICogaXRlcmF0b3IuICAoU2VlIGRlZmluaXRpb24gb2YgaXRlcmF0b3IgYWJvdmUuKQotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5JVEVSQVRPUl9DTE9ORV9FUlIsCi0gICAgICAgICJObyBlcyBwb3QgY2xvbmFyIGwnJ2l0ZXJhZG9yICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgcmVwcmVzZW50cyBhbiBpbnRlcm5hbCBlcnJvcgotICAgICAgICAgKiBzaXR1YXRpb24gaW4gWFNMVEMuICBUaGUgcHJvY2Vzc29yIGF0dGVtcHRlZCB0byBjcmVhdGUgYW4gaXRlcmF0b3IKLSAgICAgICAgICogZm9yIGEgcGFydGljdWxhciBheGlzIChzZWUgZGVmaW5pdGlvbiBhYm92ZSkgdGhhdCBpdCBkb2VzIG5vdAotICAgICAgICAgKiBzdXBwb3J0LgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5BWElTX1NVUFBPUlRfRVJSLAotICAgICAgICAiTCcnaXRlcmFkb3IgZGUgbCcnZWl4ICcnezB9Jycgbm8gdFx1MDBlOSBzdXBvcnQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgcmVwcmVzZW50cyBhbiBpbnRlcm5hbCBlcnJvcgotICAgICAgICAgKiBzaXR1YXRpb24gaW4gWFNMVEMuICBUaGUgcHJvY2Vzc29yIGF0dGVtcHRlZCB0byBjcmVhdGUgYW4gaXRlcmF0b3IKLSAgICAgICAgICogZm9yIGEgcGFydGljdWxhciBheGlzIChzZWUgZGVmaW5pdGlvbiBhYm92ZSkgdGhhdCBpdCBkb2VzIG5vdAotICAgICAgICAgKiBzdXBwb3J0LgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5UWVBFRF9BWElTX1NVUFBPUlRfRVJSLAotICAgICAgICAiTCcnaXRlcmFkb3IgZGUgbCcnZWl4IGVzY3JpdCAnJ3swfScnIG5vIHRcdTAwZTkgc3Vwb3J0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgcmVwb3J0ZWQgaWYgdGhlIHN0eWxlc2hlZXQKLSAgICAgICAgICogYmVpbmcgcHJvY2Vzc2VkIGF0dGVtcHRlZCB0byBjb25zdHJ1Y3QgYW4gWE1MIGRvY3VtZW50IHdpdGggYW4KLSAgICAgICAgICogYXR0cmlidXRlIGluIGEgcGxhY2Ugb3RoZXIgdGhhbiBvbiBhbiBlbGVtZW50LiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgICAqIHNwZWNpZmllcyB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5TVFJBWV9BVFRSSUJVVEVfRVJSLAotICAgICAgICAiTCcnYXRyaWJ1dCAnJ3swfScnIGVzIHRyb2JhIGZvcmEgZGUgbCcnZWxlbWVudC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQXMgd2l0aCB0aGUgcHJlY2VkaW5nIG1lc3NhZ2UsIGEgbmFtZXNwYWNlCi0gICAgICAgICAqIGRlY2xhcmF0aW9uIGhhcyB0aGUgZm9ybSBvZiBhbiBhdHRyaWJ1dGUgYW5kIGlzIG9ubHkgcGVybWl0dGVkIHRvCi0gICAgICAgICAqIGFwcGVhciBvbiBhbiBlbGVtZW50LiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHswfSBpcyB0aGUgbmFtZXNwYWNlCi0gICAgICAgICAqIHByZWZpeCBhbmQgezF9IGlzIHRoZSBVUkkgdGhhdCB3YXMgYmVpbmcgdXNlZCBpbiB0aGUgZXJyb25lb3VzCi0gICAgICAgICAqIG5hbWVzcGFjZSBkZWNsYXJhdGlvbi4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuU1RSQVlfTkFNRVNQQUNFX0VSUiwKLSAgICAgICAgIkxhIGRlY2xhcmFjaVx1MDBmMyBkJydlc3BhaSBkZSBub21zICcnezB9Jyc9Jyd7MX0nJyBlcyB0cm9iYSBmb3JhIGRlIGwnJ2VsZW1lbnQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IGNvbnRhaW5lZCBhIHJlZmVyZW5jZSB0byBhCi0gICAgICAgICAqIG5hbWVzcGFjZSBwcmVmaXggdGhhdCB3YXMgdW5kZWZpbmVkLiAgVGhlIHZhbHVlIG9mIHRoZSBzdWJzdGl0dXRpb24KLSAgICAgICAgICogdGV4dCBpcyB0aGUgbmFtZSBvZiB0aGUgcHJlZml4LgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5OQU1FU1BBQ0VfUFJFRklYX0VSUiwKLSAgICAgICAgIkwnJ2VzcGFpIGRlIG5vbXMgZGVsIHByZWZpeCAnJ3swfScnIG5vIHMnJ2hhIGRlY2xhcmF0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIHJlcHJlc2VudHMgYW4gaW50ZXJuYWwgZXJyb3IuCi0gICAgICAgICAqIERPTUFkYXB0ZXIgaXMgYSBKYXZhIGNsYXNzIGluIFhTTFRDLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5ET01fQURBUFRFUl9JTklUX0VSUiwKLSAgICAgICAgIkRPTUFkYXB0ZXIgcydoYSBjcmVhdCBtaXRqYW5cdTAwZTdhbnQgdW4gdGlwdXMgaW5jb3JyZWN0ZSBkZSBET00gZCdvcmlnZW4uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUgWE1MCi0gICAgICAgICAqIHBhcnNlciB0aGF0IGlzIHByb3ZpZGluZyBpbnB1dCB0byBYU0xUQyBjYW5ub3QgYmUgdXNlZCBiZWNhdXNlIGl0Ci0gICAgICAgICAqIGRvZXMgbm90IGRlc2NyaWJlIHRvIFhTTFRDIHRoZSBzdHJ1Y3R1cmUgb2YgdGhlIGlucHV0IFhNTCBkb2N1bWVudCdzCi0gICAgICAgICAqIERURC4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuUEFSU0VSX0RURF9TVVBQT1JUX0VSUiwKLSAgICAgICAgIkwnYW5hbGl0emFkb3IgU0FYIHF1ZSBmZXUgc2VydmlyIG5vIGdlc3Rpb25hIGVzZGV2ZW5pbWVudHMgZGUgZGVjbGFyYWNpXHUwMGYzIGRlIERURC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoZSBYTUwKLSAgICAgICAgICogcGFyc2VyIHRoYXQgaXMgcHJvdmlkaW5nIGlucHV0IHRvIFhTTFRDIGNhbm5vdCBiZSB1c2VkIGJlY2F1c2UgaXQKLSAgICAgICAgICogZG9lcyBub3QgZGlzdGluZ3Vpc2ggYmV0d2VlbiBvcmRpbmFyeSBYTUwgYXR0cmlidXRlcyBhbmQgbmFtZXNwYWNlCi0gICAgICAgICAqIGRlY2xhcmF0aW9ucy4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuTkFNRVNQQUNFU19TVVBQT1JUX0VSUiwKLSAgICAgICAgIkwnYW5hbGl0emFkb3IgU0FYIHF1ZSBmZXUgc2VydmlyIG5vIGRcdTAwZjNuYSBzdXBvcnQgYSBlc3BhaXMgZGUgbm9tcyBYTUwuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgVVJJIHRoYXQgd2FzIGluCi0gICAgICAgICAqIGVycm9yLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5DQU5UX1JFU09MVkVfUkVMQVRJVkVfVVJJX0VSUiwKLSAgICAgICAgIk5vIHMnJ2hhIHBvZ3V0IHJlc29sZHJlIGxhIHJlZmVyXHUwMGU4bmNpYSBkJydVUkkgJyd7MH0nJy4ifQotICAgIH07Ci0KLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9FcnJvck1lc3NhZ2VzX2NzLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvRXJyb3JNZXNzYWdlc19jcy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4ODQwOWUxLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9FcnJvck1lc3NhZ2VzX2NzLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMzQgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRXJyb3JNZXNzYWdlc19jcy5qYXZhLHYgMS4xLjYuMSAyMDA1LzA5LzA2IDEwOjQ1OjM3IHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5ydW50aW1lOwotCi1pbXBvcnQgamF2YS51dGlsLkxpc3RSZXNvdXJjZUJ1bmRsZTsKLQotLyoqCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqLwotcHVibGljIGNsYXNzIEVycm9yTWVzc2FnZXNfY3MgZXh0ZW5kcyBMaXN0UmVzb3VyY2VCdW5kbGUgewotCi0vKgotICogWFNMVEMgcnVuLXRpbWUgZXJyb3IgbWVzc2FnZXMuCi0gKgotICogR2VuZXJhbCBub3RlcyB0byB0cmFuc2xhdG9ycyBhbmQgZGVmaW5pdGlvbnM6Ci0gKgotICogICAxKSBYU0xUQyBpcyB0aGUgbmFtZSBvZiB0aGUgcHJvZHVjdC4gIEl0IGlzIGFuIGFjcm9ueW0gZm9yIFhNTCBTdHlsZXNoZWV0OgotICogICAgICBUcmFuc2Zvcm1hdGlvbnMgQ29tcGlsZXIKLSAqCi0gKiAgIDIpIEEgc3R5bGVzaGVldCBpcyBhIGRlc2NyaXB0aW9uIG9mIGhvdyB0byB0cmFuc2Zvcm0gYW4gaW5wdXQgWE1MIGRvY3VtZW50Ci0gKiAgICAgIGludG8gYSByZXN1bHRhbnQgb3V0cHV0IFhNTCBkb2N1bWVudCAob3IgSFRNTCBkb2N1bWVudCBvciB0ZXh0KQotICoKLSAqICAgMykgQW4gYXhpcyBpcyBhIHBhcnRpY3VsYXIgImRpbWVuc2lvbiIgaW4gYSB0cmVlIHJlcHJlc2VudGF0aW9uIG9mIGFuIFhNTAotICogICAgICBkb2N1bWVudDsgdGhlIG5vZGVzIGluIHRoZSB0cmVlIGFyZSBkaXZpZGVkIGFsb25nIGRpZmZlcmVudCBheGVzLgotICogICAgICBUcmF2ZXJzaW5nIHRoZSAiY2hpbGQiIGF4aXMsIGZvciBpbnN0YW5jZSwgbWVhbnMgdGhhdCB0aGUgcHJvZ3JhbQotICogICAgICB3b3VsZCB2aXNpdCBlYWNoIGNoaWxkIG9mIGEgcGFydGljdWxhciBub2RlOyB0cmF2ZXJzaW5nIHRoZSAiZGVzY2VuZGFudCIKLSAqICAgICAgYXhpcyBtZWFucyB0aGF0IHRoZSBwcm9ncmFtIHdvdWxkIHZpc2l0IHRoZSBjaGlsZCBub2RlcyBvZiBhIHBhcnRpY3VsYXIKLSAqICAgICAgbm9kZSwgdGhlaXIgY2hpbGRyZW4sIGFuZCBzbyBvbiB1bnRpbCB0aGUgbGVhZiBub2RlcyBvZiB0aGUgdHJlZSBhcmUKLSAqICAgICAgcmVhY2hlZC4KLSAqCi0gKiAgIDQpIEFuIGl0ZXJhdG9yIGlzIGFuIG9iamVjdCB0aGF0IHRyYXZlcnNlcyBub2RlcyBpbiBhIHRyZWUgYWxvbmcgYQotICogICAgICBwYXJ0aWN1bGFyIGF4aXMsIG9uZSBhdCBhIHRpbWUuCi0gKgotICogICA1KSBBbiBlbGVtZW50IGlzIGEgbWFyay11cCB0YWcgaW4gYW4gWE1MIGRvY3VtZW50OyBhbiBhdHRyaWJ1dGUgaXMgYQotICogICAgICBtb2RpZmllciBvbiB0aGUgdGFnLiAgRm9yIGV4YW1wbGUsIGluIDxlbGVtIGF0dHI9J3ZhbCcgYXR0cjI9J3ZhbDInPgotICogICAgICAiZWxlbSIgaXMgYW4gZWxlbWVudCBuYW1lLCAiYXR0ciIgYW5kICJhdHRyMiIgYXJlIGF0dHJpYnV0ZSBuYW1lcyB3aXRoCi0gKiAgICAgIHRoZSB2YWx1ZXMgInZhbCIgYW5kICJ2YWwyIiwgcmVzcGVjdGl2ZWx5LgotICoKLSAqICAgNikgQSBuYW1lc3BhY2UgZGVjbGFyYXRpb24gaXMgYSBzcGVjaWFsIGF0dHJpYnV0ZSB0aGF0IGlzIHVzZWQgdG8gYXNzb2NpYXRlCi0gKiAgICAgIGEgcHJlZml4IHdpdGggYSBVUkkgKHRoZSBuYW1lc3BhY2UpLiAgVGhlIG1lYW5pbmdzIG9mIGVsZW1lbnQgbmFtZXMgYW5kCi0gKiAgICAgIGF0dHJpYnV0ZSBuYW1lcyB0aGF0IHVzZSB0aGF0IHByZWZpeCBhcmUgZGVmaW5lZCB3aXRoIHJlc3BlY3QgdG8gdGhhdAotICogICAgICBuYW1lc3BhY2UuCi0gKgotICogICA3KSBET00gaXMgYW4gYWNyb255bSBmb3IgRG9jdW1lbnQgT2JqZWN0IE1vZGVsLiAgSXQgaXMgYSB0cmVlCi0gKiAgICAgIHJlcHJlc2VudGF0aW9uIG9mIGFuIFhNTCBkb2N1bWVudC4KLSAqCi0gKiAgICAgIFNBWCBpcyBhbiBhY3JvbnltIGZvciB0aGUgU2ltcGxlIEFQSSBmb3IgWE1MIHByb2Nlc3NpbmcuICBJdCBpcyBhbiBBUEkKLSAqICAgICAgdXNlZCBpbmZvcm0gYW4gWE1MIHByb2Nlc3NvciAoaW4gdGhpcyBjYXNlIFhTTFRDKSBvZiB0aGUgc3RydWN0dXJlIGFuZAotICogICAgICBjb250ZW50IG9mIGFuIFhNTCBkb2N1bWVudC4KLSAqCi0gKiAgICAgIElucHV0IHRvIHRoZSBzdHlsZXNoZWV0IHByb2Nlc3NvciBjYW4gY29tZSBmcm9tIGFuIFhNTCBwYXJzZXIgaW4gdGhlCi0gKiAgICAgIGZvcm0gb2YgYSBET00gdHJlZSBvciB0aHJvdWdoIHRoZSBTQVggQVBJLgotICoKLSAqICAgOCkgRFREIGlzIGEgZG9jdW1lbnQgdHlwZSBkZWNsYXJhdGlvbi4gIEl0IGlzIGEgd2F5IG9mIHNwZWNpZnlpbmcgdGhlCi0gKiAgICAgIGdyYW1tYXIgZm9yIGFuIFhNTCBmaWxlLCB0aGUgbmFtZXMgYW5kIHR5cGVzIG9mIGVsZW1lbnRzLCBhdHRyaWJ1dGVzLAotICogICAgICBldGMuCi0gKgotICovCi0KLSAgICAvLyBUaGVzZSBtZXNzYWdlIHNob3VsZCBiZSByZWFkIGZyb20gYSBsb2NhbGUtc3BlY2lmaWMgcmVzb3VyY2UgYnVuZGxlCi0gICAgLyoqIEdldCB0aGUgbG9va3VwIHRhYmxlIGZvciBlcnJvciBtZXNzYWdlcy4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIG1lc3NhZ2UgbG9va3VwIHRhYmxlLgotICAgICAqLwotICAgIHB1YmxpYyBPYmplY3RbXVtdIGdldENvbnRlbnRzKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBuZXcgT2JqZWN0W11bXSB7Ci0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIHRoZSBzdWJzdGl0dXRpb24gdGV4dCBpbiB0aGUgZm9sbG93aW5nIG1lc3NhZ2UKLSAgICAgICAgICogaXMgYSBjbGFzcyBuYW1lLiAgVXNlZCBmb3IgaW50ZXJuYWwgZXJyb3JzIGluIHRoZSBwcm9jZXNzb3IuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LlJVTl9USU1FX0lOVEVSTkFMX0VSUiwKLSAgICAgICAgIlZuaXRcdTAxNTluXHUwMGVkIGJcdTAxMWJob3ZcdTAwZTEgY2h5YmEgdiAnJ3swfScnIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIDx4c2w6Y29weT4gaXMgYSBrZXl3b3JkIHRoYXQgc2hvdWxkIG5vdCBiZQotICAgICAgICAgKiB0cmFuc2xhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5SVU5fVElNRV9DT1BZX0VSUiwKLSAgICAgICAgIlZuaXRcdTAxNTluXHUwMGVkIGJcdTAxMWJob3ZcdTAwZTEgY2h5YmEgcFx1MDE1OWkgcHJvdlx1MDBlMWRcdTAxMWJuXHUwMGVkIGZ1bmtjZSA8eHNsOmNvcHk+LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgcmVmZXJzIHRvIGRhdGEgdHlwZXMuCi0gICAgICAgICAqIFRoZSBtZXNzYWdlIGlzIGRpc3BsYXllZCBpZiBhIHZhbHVlIGluIGEgcGFydGljdWxhciBjb250ZXh0IG5lZWRzIHRvCi0gICAgICAgICAqIGJlIGNvbnZlcnRlZCB0byB0eXBlIHsxfSwgYnV0IHRoYXQncyBub3QgcG9zc2libGUgZm9yIGEgdmFsdWUgb2YgdHlwZQotICAgICAgICAgKiB7MH0uCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LkRBVEFfQ09OVkVSU0lPTl9FUlIsCi0gICAgICAgICJOZXBsYXRuXHUwMGUxIGtvbnZlcnplIHogJyd7MH0nJyBkbyAnJ3sxfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgZGlzcGxheWVkIGlmIHRoZSBmdW5jdGlvbiBuYW1lZAotICAgICAgICAgKiBieSB0aGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgbm90IGEgZnVuY3Rpb24gdGhhdCBpcyBzdXBwb3J0ZWQuICBYU0xUQwotICAgICAgICAgKiBpcyB0aGUgYWNyb255bSBuYW1pbmcgdGhlIHByb2R1Y3QuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LkVYVEVSTkFMX0ZVTkNfRVJSLAotICAgICAgICAiRXh0ZXJuXHUwMGVkIGZ1bmtjZSAnJ3swfScnIG5lblx1MDBlZCBwb2Rwb3Jvdlx1MDBlMW5hIHByb2R1a3RlbSBTTFRDLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgZGlzcGxheWVkIGlmIHR3byB2YWx1ZXMgYXJlCi0gICAgICAgICAqIGNvbXBhcmVkIGZvciBlcXVhbGl0eSwgYnV0IHRoZSBkYXRhIHR5cGUgb2Ygb25lIG9mIHRoZSB2YWx1ZXMgaXMKLSAgICAgICAgICogdW5rbm93bi4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuRVFVQUxJVFlfRVhQUl9FUlIsCi0gICAgICAgICJOZXpuXHUwMGUxbVx1MDBmZCB0eXAgYXJndW1lbnR1IHZlIHZcdTAwZmRyYXp1IHJvdm5vc3RpLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgZm9yIHswfSB3aWxsIGJlIGEgZGF0YQotICAgICAgICAgKiB0eXBlOyB0aGUgc3Vic3RpdHV0aW9uIHRleHQgZm9yIHsxfSB3aWxsIGJlIHRoZSBuYW1lIG9mIGEgZnVuY3Rpb24uCi0gICAgICAgICAqIFRoaXMgaXMgZGlzcGxheWVkIGlmIGFuIGFyZ3VtZW50IG9mIHRoZSBwYXJ0aWN1bGFyIGRhdGEgdHlwZSBpcyBub3QKLSAgICAgICAgICogcGVybWl0dGVkIGZvciBhIGNhbGwgdG8gdGhpcyBmdW5jdGlvbi4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuSU5WQUxJRF9BUkdVTUVOVF9FUlIsCi0gICAgICAgICJOZXBsYXRuXHUwMGZkIHR5cCBhcmd1bWVudHUgJyd7MH0nJyBwXHUwMTU5aSB2b2xcdTAwZTFuXHUwMGVkICcnezF9JycifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlcmUgaXMgd2F5IG9mIHNwZWNpZnlpbmcgYSBmb3JtYXQgZm9yIGEKLSAgICAgICAgICogbnVtYmVyIHVzaW5nIGEgcGF0dGVybjsgdGhlIHByb2Nlc3NvciB3YXMgdW5hYmxlIHRvIGZvcm1hdCB0aGUKLSAgICAgICAgICogcGFydGljdWxhciB2YWx1ZSB1c2luZyB0aGUgc3BlY2lmaWVkIHBhdHRlcm4uCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LkZPUk1BVF9OVU1CRVJfRVJSLAotICAgICAgICAiUG9rdXMgZm9ybVx1MDBlMXRvdmF0IFx1MDEwZFx1MDBlZHNsbyAnJ3swfScnIHBvdVx1MDE3ZWl0XHUwMGVkbSB2em9ya3UgJyd7MX0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyByZXByZXNlbnRzIGFuIGludGVybmFsIGVycm9yCi0gICAgICAgICAqIHNpdHVhdGlvbiBpbiBYU0xUQy4gIFRoZSBwcm9jZXNzb3Igd2FzIHVuYWJsZSB0byBjcmVhdGUgYSBjb3B5IG9mIGFuCi0gICAgICAgICAqIGl0ZXJhdG9yLiAgKFNlZSBkZWZpbml0aW9uIG9mIGl0ZXJhdG9yIGFib3ZlLikKLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuSVRFUkFUT1JfQ0xPTkVfRVJSLAotICAgICAgICAiTmVsemUga2xvbm92YXQgaXRlclx1MDBlMXRvciAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIHJlcHJlc2VudHMgYW4gaW50ZXJuYWwgZXJyb3IKLSAgICAgICAgICogc2l0dWF0aW9uIGluIFhTTFRDLiAgVGhlIHByb2Nlc3NvciBhdHRlbXB0ZWQgdG8gY3JlYXRlIGFuIGl0ZXJhdG9yCi0gICAgICAgICAqIGZvciBhIHBhcnRpY3VsYXIgYXhpcyAoc2VlIGRlZmluaXRpb24gYWJvdmUpIHRoYXQgaXQgZG9lcyBub3QKLSAgICAgICAgICogc3VwcG9ydC4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuQVhJU19TVVBQT1JUX0VSUiwKLSAgICAgICAgIkl0ZXJcdTAwZTF0b3IgcHJvIG9zdSAnJ3swfScnIG5lblx1MDBlZCBwb2Rwb3Jvdlx1MDBlMW4uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgcmVwcmVzZW50cyBhbiBpbnRlcm5hbCBlcnJvcgotICAgICAgICAgKiBzaXR1YXRpb24gaW4gWFNMVEMuICBUaGUgcHJvY2Vzc29yIGF0dGVtcHRlZCB0byBjcmVhdGUgYW4gaXRlcmF0b3IKLSAgICAgICAgICogZm9yIGEgcGFydGljdWxhciBheGlzIChzZWUgZGVmaW5pdGlvbiBhYm92ZSkgdGhhdCBpdCBkb2VzIG5vdAotICAgICAgICAgKiBzdXBwb3J0LgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5UWVBFRF9BWElTX1NVUFBPUlRfRVJSLAotICAgICAgICAiSXRlclx1MDBlMXRvciBwcm8gdHlwaXpvdmFub3Ugb3N1ICcnezB9JycgbmVuXHUwMGVkIHBvZHBvcm92XHUwMGUxbi4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIHJlcG9ydGVkIGlmIHRoZSBzdHlsZXNoZWV0Ci0gICAgICAgICAqIGJlaW5nIHByb2Nlc3NlZCBhdHRlbXB0ZWQgdG8gY29uc3RydWN0IGFuIFhNTCBkb2N1bWVudCB3aXRoIGFuCi0gICAgICAgICAqIGF0dHJpYnV0ZSBpbiBhIHBsYWNlIG90aGVyIHRoYW4gb24gYW4gZWxlbWVudC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICAgKiBzcGVjaWZpZXMgdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuU1RSQVlfQVRUUklCVVRFX0VSUiwKLSAgICAgICAgIkF0cmlidXQgJyd7MH0nJyBqZSB2blx1MDExYiBwcnZrdS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQXMgd2l0aCB0aGUgcHJlY2VkaW5nIG1lc3NhZ2UsIGEgbmFtZXNwYWNlCi0gICAgICAgICAqIGRlY2xhcmF0aW9uIGhhcyB0aGUgZm9ybSBvZiBhbiBhdHRyaWJ1dGUgYW5kIGlzIG9ubHkgcGVybWl0dGVkIHRvCi0gICAgICAgICAqIGFwcGVhciBvbiBhbiBlbGVtZW50LiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHswfSBpcyB0aGUgbmFtZXNwYWNlCi0gICAgICAgICAqIHByZWZpeCBhbmQgezF9IGlzIHRoZSBVUkkgdGhhdCB3YXMgYmVpbmcgdXNlZCBpbiB0aGUgZXJyb25lb3VzCi0gICAgICAgICAqIG5hbWVzcGFjZSBkZWNsYXJhdGlvbi4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuU1RSQVlfTkFNRVNQQUNFX0VSUiwKLSAgICAgICAgIkRla2xhcmFjZSBvYm9ydSBuXHUwMGUxenZcdTAxNmYgJyd7MH0nJz0nJ3sxfScnIGplIHZuXHUwMTFiIHBydmt1LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3R5bGVzaGVldCBjb250YWluZWQgYSByZWZlcmVuY2UgdG8gYQotICAgICAgICAgKiBuYW1lc3BhY2UgcHJlZml4IHRoYXQgd2FzIHVuZGVmaW5lZC4gIFRoZSB2YWx1ZSBvZiB0aGUgc3Vic3RpdHV0aW9uCi0gICAgICAgICAqIHRleHQgaXMgdGhlIG5hbWUgb2YgdGhlIHByZWZpeC4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuTkFNRVNQQUNFX1BSRUZJWF9FUlIsCi0gICAgICAgICJPYm9yIG5cdTAwZTF6dlx1MDE2ZiBwcm8gcFx1MDE1OWVkcG9udSAnJ3swfScnIG5lYnlsIGRla2xhcm92XHUwMGUxbi4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyByZXByZXNlbnRzIGFuIGludGVybmFsIGVycm9yLgotICAgICAgICAgKiBET01BZGFwdGVyIGlzIGEgSmF2YSBjbGFzcyBpbiBYU0xUQy4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuRE9NX0FEQVBURVJfSU5JVF9FUlIsCi0gICAgICAgICJET01BZGFwdGVyIGJ5bCB2eXR2b1x1MDE1OWVuIHMgcG91XHUwMTdlaXRcdTAwZWRtIGNoeWJuXHUwMGU5aG8gdHlwdSB6ZHJvamUgRE9NLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhlIFhNTAotICAgICAgICAgKiBwYXJzZXIgdGhhdCBpcyBwcm92aWRpbmcgaW5wdXQgdG8gWFNMVEMgY2Fubm90IGJlIHVzZWQgYmVjYXVzZSBpdAotICAgICAgICAgKiBkb2VzIG5vdCBkZXNjcmliZSB0byBYU0xUQyB0aGUgc3RydWN0dXJlIG9mIHRoZSBpbnB1dCBYTUwgZG9jdW1lbnQncwotICAgICAgICAgKiBEVEQuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LlBBUlNFUl9EVERfU1VQUE9SVF9FUlIsCi0gICAgICAgICJQb3VcdTAxN2VpdFx1MDBmZCBhbmFseXpcdTAwZTF0b3IgU0FYIG5lbVx1MDE2Zlx1MDE3ZWUgbWFuaXB1bG92YXQgcyBkZWtsYXJhXHUwMTBkblx1MDBlZG1pIHVkXHUwMGUxbG9zdG1pIERURC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoZSBYTUwKLSAgICAgICAgICogcGFyc2VyIHRoYXQgaXMgcHJvdmlkaW5nIGlucHV0IHRvIFhTTFRDIGNhbm5vdCBiZSB1c2VkIGJlY2F1c2UgaXQKLSAgICAgICAgICogZG9lcyBub3QgZGlzdGluZ3Vpc2ggYmV0d2VlbiBvcmRpbmFyeSBYTUwgYXR0cmlidXRlcyBhbmQgbmFtZXNwYWNlCi0gICAgICAgICAqIGRlY2xhcmF0aW9ucy4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuTkFNRVNQQUNFU19TVVBQT1JUX0VSUiwKLSAgICAgICAgIlBvdVx1MDE3ZWl0XHUwMGZkIGFuYWx5elx1MDBlMXRvciBTQVggbmVtXHUwMTZmXHUwMTdlZSBwb2Rwb3JvdmF0IG9ib3J5IG5cdTAwZTF6dlx1MDE2ZiBwcm8gWE1MLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIFVSSSB0aGF0IHdhcyBpbgotICAgICAgICAgKiBlcnJvci4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuQ0FOVF9SRVNPTFZFX1JFTEFUSVZFX1VSSV9FUlIsCi0gICAgICAgICJOZWx6ZSBwXHUwMTU5ZWxvXHUwMTdlaXQgb2RrYXp5IFVSSSAnJ3swfScnLiJ9Ci0gICAgfTsKLQotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ydW50aW1lL0Vycm9yTWVzc2FnZXNfZGUuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9FcnJvck1lc3NhZ2VzX2RlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGI4NmU3ZGUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ydW50aW1lL0Vycm9yTWVzc2FnZXNfZGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI4NCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnJ1bnRpbWU7Ci0KLWltcG9ydCBqYXZhLnV0aWwuTGlzdFJlc291cmNlQnVuZGxlOwotCi0vKioKLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICovCi1wdWJsaWMgY2xhc3MgRXJyb3JNZXNzYWdlc19kZSBleHRlbmRzIExpc3RSZXNvdXJjZUJ1bmRsZSB7Ci0KLS8qCi0gKiBYU0xUQyBydW4tdGltZSBlcnJvciBtZXNzYWdlcy4KLSAqCi0gKiBHZW5lcmFsIG5vdGVzIHRvIHRyYW5zbGF0b3JzIGFuZCBkZWZpbml0aW9uczoKLSAqCi0gKiAgIDEpIFhTTFRDIGlzIHRoZSBuYW1lIG9mIHRoZSBwcm9kdWN0LiAgSXQgaXMgYW4gYWNyb255bSBmb3IgWE1MIFN0eWxlc2hlZXQ6Ci0gKiAgICAgIFRyYW5zZm9ybWF0aW9ucyBDb21waWxlcgotICoKLSAqICAgMikgQSBzdHlsZXNoZWV0IGlzIGEgZGVzY3JpcHRpb24gb2YgaG93IHRvIHRyYW5zZm9ybSBhbiBpbnB1dCBYTUwgZG9jdW1lbnQKLSAqICAgICAgaW50byBhIHJlc3VsdGFudCBvdXRwdXQgWE1MIGRvY3VtZW50IChvciBIVE1MIGRvY3VtZW50IG9yIHRleHQpCi0gKgotICogICAzKSBBbiBheGlzIGlzIGEgcGFydGljdWxhciAiZGltZW5zaW9uIiBpbiBhIHRyZWUgcmVwcmVzZW50YXRpb24gb2YgYW4gWE1MCi0gKiAgICAgIGRvY3VtZW50OyB0aGUgbm9kZXMgaW4gdGhlIHRyZWUgYXJlIGRpdmlkZWQgYWxvbmcgZGlmZmVyZW50IGF4ZXMuCi0gKiAgICAgIFRyYXZlcnNpbmcgdGhlICJjaGlsZCIgYXhpcywgZm9yIGluc3RhbmNlLCBtZWFucyB0aGF0IHRoZSBwcm9ncmFtCi0gKiAgICAgIHdvdWxkIHZpc2l0IGVhY2ggY2hpbGQgb2YgYSBwYXJ0aWN1bGFyIG5vZGU7IHRyYXZlcnNpbmcgdGhlICJkZXNjZW5kYW50IgotICogICAgICBheGlzIG1lYW5zIHRoYXQgdGhlIHByb2dyYW0gd291bGQgdmlzaXQgdGhlIGNoaWxkIG5vZGVzIG9mIGEgcGFydGljdWxhcgotICogICAgICBub2RlLCB0aGVpciBjaGlsZHJlbiwgYW5kIHNvIG9uIHVudGlsIHRoZSBsZWFmIG5vZGVzIG9mIHRoZSB0cmVlIGFyZQotICogICAgICByZWFjaGVkLgotICoKLSAqICAgNCkgQW4gaXRlcmF0b3IgaXMgYW4gb2JqZWN0IHRoYXQgdHJhdmVyc2VzIG5vZGVzIGluIGEgdHJlZSBhbG9uZyBhCi0gKiAgICAgIHBhcnRpY3VsYXIgYXhpcywgb25lIGF0IGEgdGltZS4KLSAqCi0gKiAgIDUpIEFuIGVsZW1lbnQgaXMgYSBtYXJrLXVwIHRhZyBpbiBhbiBYTUwgZG9jdW1lbnQ7IGFuIGF0dHJpYnV0ZSBpcyBhCi0gKiAgICAgIG1vZGlmaWVyIG9uIHRoZSB0YWcuICBGb3IgZXhhbXBsZSwgaW4gPGVsZW0gYXR0cj0ndmFsJyBhdHRyMj0ndmFsMic+Ci0gKiAgICAgICJlbGVtIiBpcyBhbiBlbGVtZW50IG5hbWUsICJhdHRyIiBhbmQgImF0dHIyIiBhcmUgYXR0cmlidXRlIG5hbWVzIHdpdGgKLSAqICAgICAgdGhlIHZhbHVlcyAidmFsIiBhbmQgInZhbDIiLCByZXNwZWN0aXZlbHkuCi0gKgotICogICA2KSBBIG5hbWVzcGFjZSBkZWNsYXJhdGlvbiBpcyBhIHNwZWNpYWwgYXR0cmlidXRlIHRoYXQgaXMgdXNlZCB0byBhc3NvY2lhdGUKLSAqICAgICAgYSBwcmVmaXggd2l0aCBhIFVSSSAodGhlIG5hbWVzcGFjZSkuICBUaGUgbWVhbmluZ3Mgb2YgZWxlbWVudCBuYW1lcyBhbmQKLSAqICAgICAgYXR0cmlidXRlIG5hbWVzIHRoYXQgdXNlIHRoYXQgcHJlZml4IGFyZSBkZWZpbmVkIHdpdGggcmVzcGVjdCB0byB0aGF0Ci0gKiAgICAgIG5hbWVzcGFjZS4KLSAqCi0gKiAgIDcpIERPTSBpcyBhbiBhY3JvbnltIGZvciBEb2N1bWVudCBPYmplY3QgTW9kZWwuICBJdCBpcyBhIHRyZWUKLSAqICAgICAgcmVwcmVzZW50YXRpb24gb2YgYW4gWE1MIGRvY3VtZW50LgotICoKLSAqICAgICAgU0FYIGlzIGFuIGFjcm9ueW0gZm9yIHRoZSBTaW1wbGUgQVBJIGZvciBYTUwgcHJvY2Vzc2luZy4gIEl0IGlzIGFuIEFQSQotICogICAgICB1c2VkIGluZm9ybSBhbiBYTUwgcHJvY2Vzc29yIChpbiB0aGlzIGNhc2UgWFNMVEMpIG9mIHRoZSBzdHJ1Y3R1cmUgYW5kCi0gKiAgICAgIGNvbnRlbnQgb2YgYW4gWE1MIGRvY3VtZW50LgotICoKLSAqICAgICAgSW5wdXQgdG8gdGhlIHN0eWxlc2hlZXQgcHJvY2Vzc29yIGNhbiBjb21lIGZyb20gYW4gWE1MIHBhcnNlciBpbiB0aGUKLSAqICAgICAgZm9ybSBvZiBhIERPTSB0cmVlIG9yIHRocm91Z2ggdGhlIFNBWCBBUEkuCi0gKgotICogICA4KSBEVEQgaXMgYSBkb2N1bWVudCB0eXBlIGRlY2xhcmF0aW9uLiAgSXQgaXMgYSB3YXkgb2Ygc3BlY2lmeWluZyB0aGUKLSAqICAgICAgZ3JhbW1hciBmb3IgYW4gWE1MIGZpbGUsIHRoZSBuYW1lcyBhbmQgdHlwZXMgb2YgZWxlbWVudHMsIGF0dHJpYnV0ZXMsCi0gKiAgICAgIGV0Yy4KLSAqCi0gKiAgIDkpIFRyYW5zbGV0IGlzIGFuIGludmVudGVkIHRlcm0gdGhhdCByZWZlcnMgdG8gdGhlIGNsYXNzIGZpbGUgdGhhdCBjb250YWlucwotICogICAgICB0aGUgY29tcGlsZWQgZm9ybSBvZiBhIHN0eWxlc2hlZXQuCi0gKi8KLQotICAgIC8vIFRoZXNlIG1lc3NhZ2Ugc2hvdWxkIGJlIHJlYWQgZnJvbSBhIGxvY2FsZS1zcGVjaWZpYyByZXNvdXJjZSBidW5kbGUKLSAgICAvKiogR2V0IHRoZSBsb29rdXAgdGFibGUgZm9yIGVycm9yIG1lc3NhZ2VzLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgbWVzc2FnZSBsb29rdXAgdGFibGUuCi0gICAgICovCi0gICAgcHVibGljIE9iamVjdFtdW10gZ2V0Q29udGVudHMoKQotICAgIHsKLSAgICAgICAgcmV0dXJuIG5ldyBPYmplY3RbXVtdIHsKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgdGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGluIHRoZSBmb2xsb3dpbmcgbWVzc2FnZQotICAgICAgICAgKiBpcyBhIGNsYXNzIG5hbWUuICBVc2VkIGZvciBpbnRlcm5hbCBlcnJvcnMgaW4gdGhlIHByb2Nlc3Nvci4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuUlVOX1RJTUVfSU5URVJOQUxfRVJSLAotICAgICAgICAiSW50ZXJuZXIgTGF1ZnplaXRmZWhsZXIgaW4gXCJ7MH1cIiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICA8eHNsOmNvcHk+IGlzIGEga2V5d29yZCB0aGF0IHNob3VsZCBub3QgYmUKLSAgICAgICAgICogdHJhbnNsYXRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuUlVOX1RJTUVfQ09QWV9FUlIsCi0gICAgICAgICJMYXVmemVpdGZlaGxlciBiZWltIEF1c2ZcdTAwRkNocmVuIHZvbiA8eHNsOmNvcHk+LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgcmVmZXJzIHRvIGRhdGEgdHlwZXMuCi0gICAgICAgICAqIFRoZSBtZXNzYWdlIGlzIGRpc3BsYXllZCBpZiBhIHZhbHVlIGluIGEgcGFydGljdWxhciBjb250ZXh0IG5lZWRzIHRvCi0gICAgICAgICAqIGJlIGNvbnZlcnRlZCB0byB0eXBlIHsxfSwgYnV0IHRoYXQncyBub3QgcG9zc2libGUgZm9yIGEgdmFsdWUgb2YgdHlwZQotICAgICAgICAgKiB7MH0uCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LkRBVEFfQ09OVkVSU0lPTl9FUlIsCi0gICAgICAgICJVbmdcdTAwRkNsdGlnZSBLb252ZXJ0aWVydW5nIHZvbiBcInswfVwiIGluIFwiezF9XCIuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyBkaXNwbGF5ZWQgaWYgdGhlIGZ1bmN0aW9uIG5hbWVkCi0gICAgICAgICAqIGJ5IHRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyBub3QgYSBmdW5jdGlvbiB0aGF0IGlzIHN1cHBvcnRlZC4gIFhTTFRDCi0gICAgICAgICAqIGlzIHRoZSBhY3JvbnltIG5hbWluZyB0aGUgcHJvZHVjdC4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuRVhURVJOQUxfRlVOQ19FUlIsCi0gICAgICAgICJFeHRlcm5lIEZ1bmt0aW9uIFwiezB9XCIgbmljaHQgdW50ZXJzdFx1MDBGQ3R6dCB2b24gWFNMVEMuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyBkaXNwbGF5ZWQgaWYgdHdvIHZhbHVlcyBhcmUKLSAgICAgICAgICogY29tcGFyZWQgZm9yIGVxdWFsaXR5LCBidXQgdGhlIGRhdGEgdHlwZSBvZiBvbmUgb2YgdGhlIHZhbHVlcyBpcwotICAgICAgICAgKiB1bmtub3duLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5FUVVBTElUWV9FWFBSX0VSUiwKLSAgICAgICAgIlVuYmVrYW5udGVyIEFyZ3VtZW50dHlwIGluIEdsZWljaGhlaXRzYXVzZHJ1Y2suIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBmb3IgezB9IHdpbGwgYmUgYSBkYXRhCi0gICAgICAgICAqIHR5cGU7IHRoZSBzdWJzdGl0dXRpb24gdGV4dCBmb3IgezF9IHdpbGwgYmUgdGhlIG5hbWUgb2YgYSBmdW5jdGlvbi4KLSAgICAgICAgICogVGhpcyBpcyBkaXNwbGF5ZWQgaWYgYW4gYXJndW1lbnQgb2YgdGhlIHBhcnRpY3VsYXIgZGF0YSB0eXBlIGlzIG5vdAotICAgICAgICAgKiBwZXJtaXR0ZWQgZm9yIGEgY2FsbCB0byB0aGlzIGZ1bmN0aW9uLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5JTlZBTElEX0FSR1VNRU5UX0VSUiwKLSAgICAgICAgIlVuZ1x1MDBGQ2x0aWdlciBBcmd1bWVudHR5cCBcInswfVwiIGluIEF1ZnJ1ZiB2b24gXCJ7MX1cIiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGVyZSBpcyB3YXkgb2Ygc3BlY2lmeWluZyBhIGZvcm1hdCBmb3IgYQotICAgICAgICAgKiBudW1iZXIgdXNpbmcgYSBwYXR0ZXJuOyB0aGUgcHJvY2Vzc29yIHdhcyB1bmFibGUgdG8gZm9ybWF0IHRoZQotICAgICAgICAgKiBwYXJ0aWN1bGFyIHZhbHVlIHVzaW5nIHRoZSBzcGVjaWZpZWQgcGF0dGVybi4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuRk9STUFUX05VTUJFUl9FUlIsCi0gICAgICAgICJWZXJzdWNoLCBaYWhsIFwiezB9XCIgbWl0IE11c3RlciBcInsxfVwiIHp1IGZvcm1hdGllcmVuLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIHJlcHJlc2VudHMgYW4gaW50ZXJuYWwgZXJyb3IKLSAgICAgICAgICogc2l0dWF0aW9uIGluIFhTTFRDLiAgVGhlIHByb2Nlc3NvciB3YXMgdW5hYmxlIHRvIGNyZWF0ZSBhIGNvcHkgb2YgYW4KLSAgICAgICAgICogaXRlcmF0b3IuICAoU2VlIGRlZmluaXRpb24gb2YgaXRlcmF0b3IgYWJvdmUuKQotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5JVEVSQVRPUl9DTE9ORV9FUlIsCi0gICAgICAgICJJdGVyYXRvciBcInswfVwiIGthbm4gbmljaHQgZ2VjbG9udCB3ZXJkZW4uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgcmVwcmVzZW50cyBhbiBpbnRlcm5hbCBlcnJvcgotICAgICAgICAgKiBzaXR1YXRpb24gaW4gWFNMVEMuICBUaGUgcHJvY2Vzc29yIGF0dGVtcHRlZCB0byBjcmVhdGUgYW4gaXRlcmF0b3IKLSAgICAgICAgICogZm9yIGEgcGFydGljdWxhciBheGlzIChzZWUgZGVmaW5pdGlvbiBhYm92ZSkgdGhhdCBpdCBkb2VzIG5vdAotICAgICAgICAgKiBzdXBwb3J0LgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5BWElTX1NVUFBPUlRfRVJSLAotICAgICAgICAiSXRlcmF0b3IgZlx1MDBGQ3IgQWNoc2UgXCJ7MH1cIiBuaWNodCB1bnRlcnN0XHUwMEZDdHp0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIHJlcHJlc2VudHMgYW4gaW50ZXJuYWwgZXJyb3IKLSAgICAgICAgICogc2l0dWF0aW9uIGluIFhTTFRDLiAgVGhlIHByb2Nlc3NvciBhdHRlbXB0ZWQgdG8gY3JlYXRlIGFuIGl0ZXJhdG9yCi0gICAgICAgICAqIGZvciBhIHBhcnRpY3VsYXIgYXhpcyAoc2VlIGRlZmluaXRpb24gYWJvdmUpIHRoYXQgaXQgZG9lcyBub3QKLSAgICAgICAgICogc3VwcG9ydC4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuVFlQRURfQVhJU19TVVBQT1JUX0VSUiwKLSAgICAgICAgIkl0ZXJhdG9yIGZcdTAwRkNyIHR5cGlzaWVydGUgQWNoc2UgXCJ7MH1cIiBuaWNodCB1bnRlcnN0XHUwMEZDdHp0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgcmVwb3J0ZWQgaWYgdGhlIHN0eWxlc2hlZXQKLSAgICAgICAgICogYmVpbmcgcHJvY2Vzc2VkIGF0dGVtcHRlZCB0byBjb25zdHJ1Y3QgYW4gWE1MIGRvY3VtZW50IHdpdGggYW4KLSAgICAgICAgICogYXR0cmlidXRlIGluIGEgcGxhY2Ugb3RoZXIgdGhhbiBvbiBhbiBlbGVtZW50LiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgICAqIHNwZWNpZmllcyB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5TVFJBWV9BVFRSSUJVVEVfRVJSLAotICAgICAgICAiQXR0cmlidXQgXCJ7MH1cIiBhdVx1MDBERmVyaGFsYiBkZXMgRWxlbWVudHMuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFzIHdpdGggdGhlIHByZWNlZGluZyBtZXNzYWdlLCBhIG5hbWVzcGFjZQotICAgICAgICAgKiBkZWNsYXJhdGlvbiBoYXMgdGhlIGZvcm0gb2YgYW4gYXR0cmlidXRlIGFuZCBpcyBvbmx5IHBlcm1pdHRlZCB0bwotICAgICAgICAgKiBhcHBlYXIgb24gYW4gZWxlbWVudC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCB7MH0gaXMgdGhlIG5hbWVzcGFjZQotICAgICAgICAgKiBwcmVmaXggYW5kIHsxfSBpcyB0aGUgVVJJIHRoYXQgd2FzIGJlaW5nIHVzZWQgaW4gdGhlIGVycm9uZW91cwotICAgICAgICAgKiBuYW1lc3BhY2UgZGVjbGFyYXRpb24uCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LlNUUkFZX05BTUVTUEFDRV9FUlIsCi0gICAgICAgICJOYW1lc3BhY2UtRGVrbGFyYXRpb24gezB9PXsxfSBhdVx1MDBERmVyaGFsYiBkZXMgRWxlbWVudHMuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IGNvbnRhaW5lZCBhIHJlZmVyZW5jZSB0byBhCi0gICAgICAgICAqIG5hbWVzcGFjZSBwcmVmaXggdGhhdCB3YXMgdW5kZWZpbmVkLiAgVGhlIHZhbHVlIG9mIHRoZSBzdWJzdGl0dXRpb24KLSAgICAgICAgICogdGV4dCBpcyB0aGUgbmFtZSBvZiB0aGUgcHJlZml4LgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5OQU1FU1BBQ0VfUFJFRklYX0VSUiwKLSAgICAgICAgIk5hbWVzcGFjZSBmXHUwMEZDciBQclx1MDBFNGZpeCBcInswfVwiIHd1cmRlIG5pY2h0IGRla2xhcmllcnQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgcmVwcmVzZW50cyBhbiBpbnRlcm5hbCBlcnJvci4KLSAgICAgICAgICogRE9NQWRhcHRlciBpcyBhIEphdmEgY2xhc3MgaW4gWFNMVEMuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LkRPTV9BREFQVEVSX0lOSVRfRVJSLAotICAgICAgICAiRE9NQWRhcHRlciBtaXQgZmFsc2NoZW0gVHlwIHZvbiBRdWVsbC1ET00gZXJzdGVsbHQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUgWE1MCi0gICAgICAgICAqIHBhcnNlciB0aGF0IGlzIHByb3ZpZGluZyBpbnB1dCB0byBYU0xUQyBjYW5ub3QgYmUgdXNlZCBiZWNhdXNlIGl0Ci0gICAgICAgICAqIGRvZXMgbm90IGRlc2NyaWJlIHRvIFhTTFRDIHRoZSBzdHJ1Y3R1cmUgb2YgdGhlIGlucHV0IFhNTCBkb2N1bWVudCdzCi0gICAgICAgICAqIERURC4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuUEFSU0VSX0RURF9TVVBQT1JUX0VSUiwKLSAgICAgICAgIkRlciB2ZXJ3ZW5kZXRlIFNBWC1QYXJzZXIgdmVyYXJiZWl0ZXQga2VpbmUgRFRELURla2xhcmF0aW9uc2VyZWlnbmlzc2UuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUgWE1MCi0gICAgICAgICAqIHBhcnNlciB0aGF0IGlzIHByb3ZpZGluZyBpbnB1dCB0byBYU0xUQyBjYW5ub3QgYmUgdXNlZCBiZWNhdXNlIGl0Ci0gICAgICAgICAqIGRvZXMgbm90IGRpc3Rpbmd1aXNoIGJldHdlZW4gb3JkaW5hcnkgWE1MIGF0dHJpYnV0ZXMgYW5kIG5hbWVzcGFjZQotICAgICAgICAgKiBkZWNsYXJhdGlvbnMuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5Lk5BTUVTUEFDRVNfU1VQUE9SVF9FUlIsCi0gICAgICAgICJEZXIgdmVyd2VuZGV0ZSBTQVgtUGFyc2VyIHVudGVyc3RcdTAwRkN0enQga2VpbmUgWE1MLU5hbWVzcGFjZXMuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgVVJJIHRoYXQgd2FzIGluCi0gICAgICAgICAqIGVycm9yLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5DQU5UX1JFU09MVkVfUkVMQVRJVkVfVVJJX0VSUiwKLSAgICAgICAgIlVSSS1SZWZlcmVueiBcInswfVwiIGtvbm50ZSBuaWNodCBhdWZnZWxcdTAwRjZzdCB3ZXJkZW4uIn0sCi0KLSAgICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3R5bGVzaGVldCBjb250YWluZWQgYW4gZWxlbWVudCB0aGF0IHdhcwotICAgICAgICAgKiBub3QgcmVjb2duaXplZCBhcyBwYXJ0IG9mIHRoZSBYU0wgc3ludGF4LiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgICAqIGdpdmVzIHRoZSBlbGVtZW50IG5hbWUuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LlVOU1VQUE9SVEVEX1hTTF9FUlIsCi0gICAgICAgICJOaWNodCB1bnRlcnN0XHUwMEZDdHp0ZXMgWFNMLUVsZW1lbnQgXCJ7MH1cIiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3R5bGVzaGVldCByZWZlcnJlZCB0byBhbiBleHRlbnNpb24gdG8gdGhlCi0gICAgICAgICAqIFhTTCBzeW50YXggYW5kIGluZGljYXRlZCB0aGF0IGl0IHdhcyBkZWZpbmVkIGJ5IFhTTFRDLCBidXQgWFNMVEMgZG9lcwotICAgICAgICAgKiBub3QgcmVjb2duaXplIHRoZSBwYXJ0aWN1bGFyIGV4dGVuc2lvbiBuYW1lZC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICAgKiBnaXZlcyB0aGUgZXh0ZW5zaW9uIG5hbWUuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LlVOU1VQUE9SVEVEX0VYVF9FUlIsCi0gICAgICAgICJVbmJla2FubnRlIFhTTFRDLUVyd2VpdGVydW5nIFwiezB9XCIifSwKLQotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIGVycm9yIG1lc3NhZ2UgaXMgcHJvZHVjZWQgaWYgdGhlIHRyYW5zbGV0Ci0gICAgICAgICAqIGNsYXNzIHdhcyBjb21waWxlZCB1c2luZyBhIG5ld2VyIHZlcnNpb24gb2YgWFNMVEMgYW5kIGRlcGxveWVkIGZvcgotICAgICAgICAgKiBleGVjdXRpb24gd2l0aCBhbiBvbGRlciB2ZXJzaW9uIG9mIFhTTFRDLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzCi0gICAgICAgICAqIHRoZSBuYW1lIG9mIHRoZSB0cmFuc2xldCBjbGFzcy4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuVU5LTk9XTl9UUkFOU0xFVF9WRVJTSU9OX0VSUiwKLSAgICAgICAgIkRhcyBhbmdlZ2ViZW5lIFRyYW5zbGV0IFwiezB9XCIgd3VyZGUgbWl0IGVpbmVyIG5ldWVyZW4gVmVyc2lvbiB2b24gWFNMVEMgYWxzIGRpZSB2ZXJ3ZW5kZXRlIFZlcnNpb24gZGVyIFhTTFRDLUxhdWZ6ZWl0IGVyc3RlbGx0LiBTaWUgbVx1MDBGQ3NzZW4gZGFzIFN0eWxlc2hlZXQgbmV1IGtvbXBpbGllcmVuIG9kZXIgZWluZSBha3R1ZWxsZXJlIFZlcnNpb24gdm9uIFhTTFRDIHZlcndlbmRlbiwgdW0gZGllc2VzIFRyYW5zbGV0IGF1c3p1Zlx1MDBGQ2hyZW4uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIGF0dHJpYnV0ZSB3aG9zZSBlZmZlY3RpdmUgdmFsdWUgaXMgcmVxdWlyZWQKLSAgICAgICAgICogdG8gYmUgYSAiUU5hbWUiIGhhZCBhIHZhbHVlIHRoYXQgd2FzIGluY29ycmVjdC4KLSAgICAgICAgICogJ1FOYW1lJyBpcyBhbiBYTUwgc3ludGFjdGljIHRlcm0gdGhhdCBtdXN0IG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhlCi0gICAgICAgICAqIHN1YnN0aXR1dGlvbiB0ZXh0IGNvbnRhaW5zIHRoZSBhY3R1YWwgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuSU5WQUxJRF9RTkFNRV9FUlIsCi0gICAgICAgICJFaW4gQXR0cmlidXQsIGRlc3NlbiBXZXJ0IGVpbiBRTmFtZSBzZWluIG11c3MsIGhhdHRlIGRlbiBXZXJ0IFwiezB9XCIifSwKLQotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBbiBhdHRyaWJ1dGUgd2hvc2UgZWZmZWN0aXZlIHZhbHVlIGlzIHJlcXVpcmVkCi0gICAgICAgICAqIHRvIGJlIGEgIk5DTmFtZSIgaGFkIGEgdmFsdWUgdGhhdCB3YXMgaW5jb3JyZWN0LgotICAgICAgICAgKiAnTkNOYW1lJyBpcyBhbiBYTUwgc3ludGFjdGljIHRlcm0gdGhhdCBtdXN0IG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhlCi0gICAgICAgICAqIHN1YnN0aXR1dGlvbiB0ZXh0IGNvbnRhaW5zIHRoZSBhY3R1YWwgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuSU5WQUxJRF9OQ05BTUVfRVJSLAotICAgICAgICAiRWluIEF0dHJpYnV0LCBkZXNzZW4gV2VydCBlaW4gTkNOYW1lIHNlaW4gbXVzcywgaGF0dGUgZGVuIFdlcnQgXCJ7MH1cIiJ9LAotCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuVU5BTExPV0VEX0VYVEVOU0lPTl9GVU5DVElPTl9FUlIsCi0gICAgICAgICJWZXJ3ZW5kdW5nIGRlciBFcndlaXRlcnVuZ3NmdW5rdGlvbiBcInswfVwiIGlzdCBuaWNodCB6dWxcdTAwRTRzc2lnLCB3ZW5uIGRhcyBGZWF0dXJlIGZcdTAwRkNyIGRpZSBzaWNoZXJlIFZlcmFyYmVpdHVuZyBhdWYgXCJ0cnVlXCIgZ2VzZXR6dCBpc3QuIn0sCi0KLSAgICAgICAge0Jhc2lzTGlicmFyeS5VTkFMTE9XRURfRVhURU5TSU9OX0VMRU1FTlRfRVJSLAotICAgICAgICAiVmVyd2VuZHVuZyBkZXMgRXJ3ZWl0ZXJ1bmdzZWxlbWVudHMgXCJ7MH1cIiBpc3QgbmljaHQgenVsXHUwMEU0c3NpZywgd2VubiBkYXMgRmVhdHVyZSBmXHUwMEZDciBkaWUgc2ljaGVyZSBWZXJhcmJlaXR1bmcgYXVmIFwidHJ1ZVwiIGdlc2V0enQgaXN0LiJ9LAotICAgIH07Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvRXJyb3JNZXNzYWdlc19lcy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ydW50aW1lL0Vycm9yTWVzc2FnZXNfZXMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMzUwZDc1Zi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvRXJyb3JNZXNzYWdlc19lcy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjg0ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMucnVudGltZTsKLQotaW1wb3J0IGphdmEudXRpbC5MaXN0UmVzb3VyY2VCdW5kbGU7Ci0KLS8qKgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKi8KLXB1YmxpYyBjbGFzcyBFcnJvck1lc3NhZ2VzX2VzIGV4dGVuZHMgTGlzdFJlc291cmNlQnVuZGxlIHsKLQotLyoKLSAqIFhTTFRDIHJ1bi10aW1lIGVycm9yIG1lc3NhZ2VzLgotICoKLSAqIEdlbmVyYWwgbm90ZXMgdG8gdHJhbnNsYXRvcnMgYW5kIGRlZmluaXRpb25zOgotICoKLSAqICAgMSkgWFNMVEMgaXMgdGhlIG5hbWUgb2YgdGhlIHByb2R1Y3QuICBJdCBpcyBhbiBhY3JvbnltIGZvciBYTUwgU3R5bGVzaGVldDoKLSAqICAgICAgVHJhbnNmb3JtYXRpb25zIENvbXBpbGVyCi0gKgotICogICAyKSBBIHN0eWxlc2hlZXQgaXMgYSBkZXNjcmlwdGlvbiBvZiBob3cgdG8gdHJhbnNmb3JtIGFuIGlucHV0IFhNTCBkb2N1bWVudAotICogICAgICBpbnRvIGEgcmVzdWx0YW50IG91dHB1dCBYTUwgZG9jdW1lbnQgKG9yIEhUTUwgZG9jdW1lbnQgb3IgdGV4dCkKLSAqCi0gKiAgIDMpIEFuIGF4aXMgaXMgYSBwYXJ0aWN1bGFyICJkaW1lbnNpb24iIGluIGEgdHJlZSByZXByZXNlbnRhdGlvbiBvZiBhbiBYTUwKLSAqICAgICAgZG9jdW1lbnQ7IHRoZSBub2RlcyBpbiB0aGUgdHJlZSBhcmUgZGl2aWRlZCBhbG9uZyBkaWZmZXJlbnQgYXhlcy4KLSAqICAgICAgVHJhdmVyc2luZyB0aGUgImNoaWxkIiBheGlzLCBmb3IgaW5zdGFuY2UsIG1lYW5zIHRoYXQgdGhlIHByb2dyYW0KLSAqICAgICAgd291bGQgdmlzaXQgZWFjaCBjaGlsZCBvZiBhIHBhcnRpY3VsYXIgbm9kZTsgdHJhdmVyc2luZyB0aGUgImRlc2NlbmRhbnQiCi0gKiAgICAgIGF4aXMgbWVhbnMgdGhhdCB0aGUgcHJvZ3JhbSB3b3VsZCB2aXNpdCB0aGUgY2hpbGQgbm9kZXMgb2YgYSBwYXJ0aWN1bGFyCi0gKiAgICAgIG5vZGUsIHRoZWlyIGNoaWxkcmVuLCBhbmQgc28gb24gdW50aWwgdGhlIGxlYWYgbm9kZXMgb2YgdGhlIHRyZWUgYXJlCi0gKiAgICAgIHJlYWNoZWQuCi0gKgotICogICA0KSBBbiBpdGVyYXRvciBpcyBhbiBvYmplY3QgdGhhdCB0cmF2ZXJzZXMgbm9kZXMgaW4gYSB0cmVlIGFsb25nIGEKLSAqICAgICAgcGFydGljdWxhciBheGlzLCBvbmUgYXQgYSB0aW1lLgotICoKLSAqICAgNSkgQW4gZWxlbWVudCBpcyBhIG1hcmstdXAgdGFnIGluIGFuIFhNTCBkb2N1bWVudDsgYW4gYXR0cmlidXRlIGlzIGEKLSAqICAgICAgbW9kaWZpZXIgb24gdGhlIHRhZy4gIEZvciBleGFtcGxlLCBpbiA8ZWxlbSBhdHRyPSd2YWwnIGF0dHIyPSd2YWwyJz4KLSAqICAgICAgImVsZW0iIGlzIGFuIGVsZW1lbnQgbmFtZSwgImF0dHIiIGFuZCAiYXR0cjIiIGFyZSBhdHRyaWJ1dGUgbmFtZXMgd2l0aAotICogICAgICB0aGUgdmFsdWVzICJ2YWwiIGFuZCAidmFsMiIsIHJlc3BlY3RpdmVseS4KLSAqCi0gKiAgIDYpIEEgbmFtZXNwYWNlIGRlY2xhcmF0aW9uIGlzIGEgc3BlY2lhbCBhdHRyaWJ1dGUgdGhhdCBpcyB1c2VkIHRvIGFzc29jaWF0ZQotICogICAgICBhIHByZWZpeCB3aXRoIGEgVVJJICh0aGUgbmFtZXNwYWNlKS4gIFRoZSBtZWFuaW5ncyBvZiBlbGVtZW50IG5hbWVzIGFuZAotICogICAgICBhdHRyaWJ1dGUgbmFtZXMgdGhhdCB1c2UgdGhhdCBwcmVmaXggYXJlIGRlZmluZWQgd2l0aCByZXNwZWN0IHRvIHRoYXQKLSAqICAgICAgbmFtZXNwYWNlLgotICoKLSAqICAgNykgRE9NIGlzIGFuIGFjcm9ueW0gZm9yIERvY3VtZW50IE9iamVjdCBNb2RlbC4gIEl0IGlzIGEgdHJlZQotICogICAgICByZXByZXNlbnRhdGlvbiBvZiBhbiBYTUwgZG9jdW1lbnQuCi0gKgotICogICAgICBTQVggaXMgYW4gYWNyb255bSBmb3IgdGhlIFNpbXBsZSBBUEkgZm9yIFhNTCBwcm9jZXNzaW5nLiAgSXQgaXMgYW4gQVBJCi0gKiAgICAgIHVzZWQgaW5mb3JtIGFuIFhNTCBwcm9jZXNzb3IgKGluIHRoaXMgY2FzZSBYU0xUQykgb2YgdGhlIHN0cnVjdHVyZSBhbmQKLSAqICAgICAgY29udGVudCBvZiBhbiBYTUwgZG9jdW1lbnQuCi0gKgotICogICAgICBJbnB1dCB0byB0aGUgc3R5bGVzaGVldCBwcm9jZXNzb3IgY2FuIGNvbWUgZnJvbSBhbiBYTUwgcGFyc2VyIGluIHRoZQotICogICAgICBmb3JtIG9mIGEgRE9NIHRyZWUgb3IgdGhyb3VnaCB0aGUgU0FYIEFQSS4KLSAqCi0gKiAgIDgpIERURCBpcyBhIGRvY3VtZW50IHR5cGUgZGVjbGFyYXRpb24uICBJdCBpcyBhIHdheSBvZiBzcGVjaWZ5aW5nIHRoZQotICogICAgICBncmFtbWFyIGZvciBhbiBYTUwgZmlsZSwgdGhlIG5hbWVzIGFuZCB0eXBlcyBvZiBlbGVtZW50cywgYXR0cmlidXRlcywKLSAqICAgICAgZXRjLgotICoKLSAqICAgOSkgVHJhbnNsZXQgaXMgYW4gaW52ZW50ZWQgdGVybSB0aGF0IHJlZmVycyB0byB0aGUgY2xhc3MgZmlsZSB0aGF0IGNvbnRhaW5zCi0gKiAgICAgIHRoZSBjb21waWxlZCBmb3JtIG9mIGEgc3R5bGVzaGVldC4KLSAqLwotCi0gICAgLy8gVGhlc2UgbWVzc2FnZSBzaG91bGQgYmUgcmVhZCBmcm9tIGEgbG9jYWxlLXNwZWNpZmljIHJlc291cmNlIGJ1bmRsZQotICAgIC8qKiBHZXQgdGhlIGxvb2t1cCB0YWJsZSBmb3IgZXJyb3IgbWVzc2FnZXMuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBtZXNzYWdlIGxvb2t1cCB0YWJsZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0W11bXSBnZXRDb250ZW50cygpCi0gICAgewotICAgICAgICByZXR1cm4gbmV3IE9iamVjdFtdW10gewotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICB0aGUgc3Vic3RpdHV0aW9uIHRleHQgaW4gdGhlIGZvbGxvd2luZyBtZXNzYWdlCi0gICAgICAgICAqIGlzIGEgY2xhc3MgbmFtZS4gIFVzZWQgZm9yIGludGVybmFsIGVycm9ycyBpbiB0aGUgcHJvY2Vzc29yLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5SVU5fVElNRV9JTlRFUk5BTF9FUlIsCi0gICAgICAgICJFcnJvciBpbnRlcm5vIGRlIHRpZW1wbyBkZSBlamVjdWNpXHUwMEYzbiBlbiAnJ3swfScnIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIDx4c2w6Y29weT4gaXMgYSBrZXl3b3JkIHRoYXQgc2hvdWxkIG5vdCBiZQotICAgICAgICAgKiB0cmFuc2xhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5SVU5fVElNRV9DT1BZX0VSUiwKLSAgICAgICAgIkVycm9yIGRlIHRpZW1wbyBkZSBlamVjdWNpXHUwMEYzbiBhbCBlamVjdXRhciA8eHNsOmNvcHk+LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgcmVmZXJzIHRvIGRhdGEgdHlwZXMuCi0gICAgICAgICAqIFRoZSBtZXNzYWdlIGlzIGRpc3BsYXllZCBpZiBhIHZhbHVlIGluIGEgcGFydGljdWxhciBjb250ZXh0IG5lZWRzIHRvCi0gICAgICAgICAqIGJlIGNvbnZlcnRlZCB0byB0eXBlIHsxfSwgYnV0IHRoYXQncyBub3QgcG9zc2libGUgZm9yIGEgdmFsdWUgb2YgdHlwZQotICAgICAgICAgKiB7MH0uCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LkRBVEFfQ09OVkVSU0lPTl9FUlIsCi0gICAgICAgICJDb252ZXJzaVx1MDBGM24gbm8gdlx1MDBFMWxpZGEgZGUgJyd7MH0nJyBhICcnezF9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyBkaXNwbGF5ZWQgaWYgdGhlIGZ1bmN0aW9uIG5hbWVkCi0gICAgICAgICAqIGJ5IHRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyBub3QgYSBmdW5jdGlvbiB0aGF0IGlzIHN1cHBvcnRlZC4gIFhTTFRDCi0gICAgICAgICAqIGlzIHRoZSBhY3JvbnltIG5hbWluZyB0aGUgcHJvZHVjdC4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuRVhURVJOQUxfRlVOQ19FUlIsCi0gICAgICAgICJGdW5jaVx1MDBGM24gZXh0ZXJuYSAnJ3swfScnIG5vIHNvcG9ydGFkYSBwb3IgWFNMVEMuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyBkaXNwbGF5ZWQgaWYgdHdvIHZhbHVlcyBhcmUKLSAgICAgICAgICogY29tcGFyZWQgZm9yIGVxdWFsaXR5LCBidXQgdGhlIGRhdGEgdHlwZSBvZiBvbmUgb2YgdGhlIHZhbHVlcyBpcwotICAgICAgICAgKiB1bmtub3duLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5FUVVBTElUWV9FWFBSX0VSUiwKLSAgICAgICAgIlRpcG8gZGUgYXJndW1lbnRvIGRlc2Nvbm9jaWRvIGVuIGxhIGV4cHJlc2lcdTAwRjNuIGRlIGlndWFsZGFkLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgZm9yIHswfSB3aWxsIGJlIGEgZGF0YQotICAgICAgICAgKiB0eXBlOyB0aGUgc3Vic3RpdHV0aW9uIHRleHQgZm9yIHsxfSB3aWxsIGJlIHRoZSBuYW1lIG9mIGEgZnVuY3Rpb24uCi0gICAgICAgICAqIFRoaXMgaXMgZGlzcGxheWVkIGlmIGFuIGFyZ3VtZW50IG9mIHRoZSBwYXJ0aWN1bGFyIGRhdGEgdHlwZSBpcyBub3QKLSAgICAgICAgICogcGVybWl0dGVkIGZvciBhIGNhbGwgdG8gdGhpcyBmdW5jdGlvbi4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuSU5WQUxJRF9BUkdVTUVOVF9FUlIsCi0gICAgICAgICJUaXBvIGRlIGFyZ3VtZW50byAnJ3swfScnIG5vIHZcdTAwRTFsaWRvIGVuIGxhIGxsYW1hZGEgYSAnJ3sxfScnIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZXJlIGlzIHdheSBvZiBzcGVjaWZ5aW5nIGEgZm9ybWF0IGZvciBhCi0gICAgICAgICAqIG51bWJlciB1c2luZyBhIHBhdHRlcm47IHRoZSBwcm9jZXNzb3Igd2FzIHVuYWJsZSB0byBmb3JtYXQgdGhlCi0gICAgICAgICAqIHBhcnRpY3VsYXIgdmFsdWUgdXNpbmcgdGhlIHNwZWNpZmllZCBwYXR0ZXJuLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5GT1JNQVRfTlVNQkVSX0VSUiwKLSAgICAgICAgIkludGVudGFuZG8gZm9ybWF0ZWFyIG5cdTAwRkFtZXJvICcnezB9JycgbWVkaWFudGUgZWwgcGF0clx1MDBGM24gJyd7MX0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyByZXByZXNlbnRzIGFuIGludGVybmFsIGVycm9yCi0gICAgICAgICAqIHNpdHVhdGlvbiBpbiBYU0xUQy4gIFRoZSBwcm9jZXNzb3Igd2FzIHVuYWJsZSB0byBjcmVhdGUgYSBjb3B5IG9mIGFuCi0gICAgICAgICAqIGl0ZXJhdG9yLiAgKFNlZSBkZWZpbml0aW9uIG9mIGl0ZXJhdG9yIGFib3ZlLikKLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuSVRFUkFUT1JfQ0xPTkVfRVJSLAotICAgICAgICAiTm8gc2UgcHVlZGUgY2xvbmFyIGVsIGl0ZXJhZG9yICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgcmVwcmVzZW50cyBhbiBpbnRlcm5hbCBlcnJvcgotICAgICAgICAgKiBzaXR1YXRpb24gaW4gWFNMVEMuICBUaGUgcHJvY2Vzc29yIGF0dGVtcHRlZCB0byBjcmVhdGUgYW4gaXRlcmF0b3IKLSAgICAgICAgICogZm9yIGEgcGFydGljdWxhciBheGlzIChzZWUgZGVmaW5pdGlvbiBhYm92ZSkgdGhhdCBpdCBkb2VzIG5vdAotICAgICAgICAgKiBzdXBwb3J0LgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5BWElTX1NVUFBPUlRfRVJSLAotICAgICAgICAiRWwgaXRlcmFkb3IgcGFyYSBlbCBlamUgJyd7MH0nJyBubyBlc3RcdTAwRTEgc29wb3J0YWRvLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIHJlcHJlc2VudHMgYW4gaW50ZXJuYWwgZXJyb3IKLSAgICAgICAgICogc2l0dWF0aW9uIGluIFhTTFRDLiAgVGhlIHByb2Nlc3NvciBhdHRlbXB0ZWQgdG8gY3JlYXRlIGFuIGl0ZXJhdG9yCi0gICAgICAgICAqIGZvciBhIHBhcnRpY3VsYXIgYXhpcyAoc2VlIGRlZmluaXRpb24gYWJvdmUpIHRoYXQgaXQgZG9lcyBub3QKLSAgICAgICAgICogc3VwcG9ydC4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuVFlQRURfQVhJU19TVVBQT1JUX0VSUiwKLSAgICAgICAgIkVsIGl0ZXJhZG9yIHBhcmEgZWwgZWplIGludHJvZHVjaWRvICcnezB9Jycgbm8gZXN0XHUwMEUxIHNvcG9ydGFkby4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIHJlcG9ydGVkIGlmIHRoZSBzdHlsZXNoZWV0Ci0gICAgICAgICAqIGJlaW5nIHByb2Nlc3NlZCBhdHRlbXB0ZWQgdG8gY29uc3RydWN0IGFuIFhNTCBkb2N1bWVudCB3aXRoIGFuCi0gICAgICAgICAqIGF0dHJpYnV0ZSBpbiBhIHBsYWNlIG90aGVyIHRoYW4gb24gYW4gZWxlbWVudC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICAgKiBzcGVjaWZpZXMgdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuU1RSQVlfQVRUUklCVVRFX0VSUiwKLSAgICAgICAgIkVsIGF0cmlidXRvICcnezB9JycgZXN0XHUwMEUxIGZ1ZXJhIGRlbCBlbGVtZW50by4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQXMgd2l0aCB0aGUgcHJlY2VkaW5nIG1lc3NhZ2UsIGEgbmFtZXNwYWNlCi0gICAgICAgICAqIGRlY2xhcmF0aW9uIGhhcyB0aGUgZm9ybSBvZiBhbiBhdHRyaWJ1dGUgYW5kIGlzIG9ubHkgcGVybWl0dGVkIHRvCi0gICAgICAgICAqIGFwcGVhciBvbiBhbiBlbGVtZW50LiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHswfSBpcyB0aGUgbmFtZXNwYWNlCi0gICAgICAgICAqIHByZWZpeCBhbmQgezF9IGlzIHRoZSBVUkkgdGhhdCB3YXMgYmVpbmcgdXNlZCBpbiB0aGUgZXJyb25lb3VzCi0gICAgICAgICAqIG5hbWVzcGFjZSBkZWNsYXJhdGlvbi4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuU1RSQVlfTkFNRVNQQUNFX0VSUiwKLSAgICAgICAgIkRlY2xhcmFjaVx1MDBGM24gZGVsIGVzcGFjaW8gZGUgbm9tYnJlcyAnJ3swfScnPScnezF9JycgZnVlcmEgZGVsIGVsZW1lbnRvLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3R5bGVzaGVldCBjb250YWluZWQgYSByZWZlcmVuY2UgdG8gYQotICAgICAgICAgKiBuYW1lc3BhY2UgcHJlZml4IHRoYXQgd2FzIHVuZGVmaW5lZC4gIFRoZSB2YWx1ZSBvZiB0aGUgc3Vic3RpdHV0aW9uCi0gICAgICAgICAqIHRleHQgaXMgdGhlIG5hbWUgb2YgdGhlIHByZWZpeC4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuTkFNRVNQQUNFX1BSRUZJWF9FUlIsCi0gICAgICAgICJObyBzZSBoYSBkZWNsYXJhZG8gZWwgZXNwYWNpbyBkZSBub21icmVzIHBhcmEgZWwgcHJlZmlqbyAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIHJlcHJlc2VudHMgYW4gaW50ZXJuYWwgZXJyb3IuCi0gICAgICAgICAqIERPTUFkYXB0ZXIgaXMgYSBKYXZhIGNsYXNzIGluIFhTTFRDLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5ET01fQURBUFRFUl9JTklUX0VSUiwKLSAgICAgICAgIlNlIGhhIGNyZWFkbyBET01BZGFwdGVyIG1lZGlhbnRlIHVuIHRpcG8gaW5jb3JyZWN0byBkZSBET00gZGUgb3JpZ2VuLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhlIFhNTAotICAgICAgICAgKiBwYXJzZXIgdGhhdCBpcyBwcm92aWRpbmcgaW5wdXQgdG8gWFNMVEMgY2Fubm90IGJlIHVzZWQgYmVjYXVzZSBpdAotICAgICAgICAgKiBkb2VzIG5vdCBkZXNjcmliZSB0byBYU0xUQyB0aGUgc3RydWN0dXJlIG9mIHRoZSBpbnB1dCBYTUwgZG9jdW1lbnQncwotICAgICAgICAgKiBEVEQuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LlBBUlNFUl9EVERfU1VQUE9SVF9FUlIsCi0gICAgICAgICJFbCBhbmFsaXphZG9yIFNBWCBxdWUgZXN0XHUwMEUxIHV0aWxpemFuZG8gbm8gbWFuZWphIGxvcyBldmVudG9zIGRlIGRlY2xhcmFjaVx1MDBGM24gRFRELiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhlIFhNTAotICAgICAgICAgKiBwYXJzZXIgdGhhdCBpcyBwcm92aWRpbmcgaW5wdXQgdG8gWFNMVEMgY2Fubm90IGJlIHVzZWQgYmVjYXVzZSBpdAotICAgICAgICAgKiBkb2VzIG5vdCBkaXN0aW5ndWlzaCBiZXR3ZWVuIG9yZGluYXJ5IFhNTCBhdHRyaWJ1dGVzIGFuZCBuYW1lc3BhY2UKLSAgICAgICAgICogZGVjbGFyYXRpb25zLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5OQU1FU1BBQ0VTX1NVUFBPUlRfRVJSLAotICAgICAgICAiRWwgYW5hbGl6YWRvciBTQVggcXVlIGVzdFx1MDBFMSB1dGlsaXphbmRvIG5vIHNvcG9ydGEgbG9zIGVzcGFjaW9zIGRlIG5vbWJyZXMgWE1MLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIFVSSSB0aGF0IHdhcyBpbgotICAgICAgICAgKiBlcnJvci4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuQ0FOVF9SRVNPTFZFX1JFTEFUSVZFX1VSSV9FUlIsCi0gICAgICAgICJObyBzZSBoYSBwb2RpZG8gcmVzb2x2ZXIgbGEgcmVmZXJlbmNpYSBhbCBVUkkgJyd7MH0nJy4ifSwKLQotICAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IGNvbnRhaW5lZCBhbiBlbGVtZW50IHRoYXQgd2FzCi0gICAgICAgICAqIG5vdCByZWNvZ25pemVkIGFzIHBhcnQgb2YgdGhlIFhTTCBzeW50YXguICBUaGUgc3Vic3RpdHV0aW9uIHRleHQKLSAgICAgICAgICogZ2l2ZXMgdGhlIGVsZW1lbnQgbmFtZS4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuVU5TVVBQT1JURURfWFNMX0VSUiwKLSAgICAgICAgIkVsZW1lbnRvICcnezB9JycgZGUgWFNMIG5vIHNvcG9ydGFkbyJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3R5bGVzaGVldCByZWZlcnJlZCB0byBhbiBleHRlbnNpb24gdG8gdGhlCi0gICAgICAgICAqIFhTTCBzeW50YXggYW5kIGluZGljYXRlZCB0aGF0IGl0IHdhcyBkZWZpbmVkIGJ5IFhTTFRDLCBidXQgWFNMVEMgZG9lcwotICAgICAgICAgKiBub3QgcmVjb2duaXplIHRoZSBwYXJ0aWN1bGFyIGV4dGVuc2lvbiBuYW1lZC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICAgKiBnaXZlcyB0aGUgZXh0ZW5zaW9uIG5hbWUuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LlVOU1VQUE9SVEVEX0VYVF9FUlIsCi0gICAgICAgICJFeHRlbnNpXHUwMEYzbiAnJ3swfScnIGRlIFhTTFRDIG5vIHJlY29ub2NpZGEifSwKLQotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIGVycm9yIG1lc3NhZ2UgaXMgcHJvZHVjZWQgaWYgdGhlIHRyYW5zbGV0Ci0gICAgICAgICAqIGNsYXNzIHdhcyBjb21waWxlZCB1c2luZyBhIG5ld2VyIHZlcnNpb24gb2YgWFNMVEMgYW5kIGRlcGxveWVkIGZvcgotICAgICAgICAgKiBleGVjdXRpb24gd2l0aCBhbiBvbGRlciB2ZXJzaW9uIG9mIFhTTFRDLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzCi0gICAgICAgICAqIHRoZSBuYW1lIG9mIHRoZSB0cmFuc2xldCBjbGFzcy4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuVU5LTk9XTl9UUkFOU0xFVF9WRVJTSU9OX0VSUiwKLSAgICAgICAgIkVsIHRyYW5zbGV0IGVzcGVjaWZpY2FkbywgJyd7MH0nJyBzZSBoYSBjcmVhZG8gY29uIHVuYSB2ZXJzaVx1MDBGM24gZGUgWFNMVEMgbVx1MDBFMXMgcmVjaWVudGUgcXVlIGxhIHZlcnNpXHUwMEYzbiBkZWwgdGllbXBvIGRlIGVqZWN1Y2lcdTAwRjNuIGRlIFhTTFRDIHF1ZSBzZSBlc3RcdTAwRTEgdXRpbGl6YW5kby4gRGViZSB2b2x2ZXIgYSBjb21waWxhciBsYSBob2phIGRlIGVzdGlsbyBvIHV0aWxpemFyIHVuYSB2ZXJzaVx1MDBGM24gbVx1MDBFMXMgcmVjaWVudGUgZGUgWFNMVEMgcGFyYSBlamVjdXRhciBlc3RlIHRyYW5zbGV0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBbiBhdHRyaWJ1dGUgd2hvc2UgZWZmZWN0aXZlIHZhbHVlIGlzIHJlcXVpcmVkCi0gICAgICAgICAqIHRvIGJlIGEgIlFOYW1lIiBoYWQgYSB2YWx1ZSB0aGF0IHdhcyBpbmNvcnJlY3QuCi0gICAgICAgICAqICdRTmFtZScgaXMgYW4gWE1MIHN5bnRhY3RpYyB0ZXJtIHRoYXQgbXVzdCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoZQotICAgICAgICAgKiBzdWJzdGl0dXRpb24gdGV4dCBjb250YWlucyB0aGUgYWN0dWFsIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LklOVkFMSURfUU5BTUVfRVJSLAotICAgICAgICAiVW4gYXRyaWJ1dG8gY3V5byB2YWxvciBkZWJlIHNlciB1biBRTmFtZSB0ZW5cdTAwRURhIGVsIHZhbG9yICcnezB9JycifSwKLQotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBbiBhdHRyaWJ1dGUgd2hvc2UgZWZmZWN0aXZlIHZhbHVlIGlzIHJlcXVpcmVkCi0gICAgICAgICAqIHRvIGJlIGEgIk5DTmFtZSIgaGFkIGEgdmFsdWUgdGhhdCB3YXMgaW5jb3JyZWN0LgotICAgICAgICAgKiAnTkNOYW1lJyBpcyBhbiBYTUwgc3ludGFjdGljIHRlcm0gdGhhdCBtdXN0IG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhlCi0gICAgICAgICAqIHN1YnN0aXR1dGlvbiB0ZXh0IGNvbnRhaW5zIHRoZSBhY3R1YWwgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuSU5WQUxJRF9OQ05BTUVfRVJSLAotICAgICAgICAiVW4gYXRyaWJ1dG8gY3V5byB2YWxvciBkZWJlIHNlciB1biBOQ05hbWUgdGVuXHUwMEVEYSBlbCB2YWxvciAnJ3swfScnIn0sCi0KLSAgICAgICAge0Jhc2lzTGlicmFyeS5VTkFMTE9XRURfRVhURU5TSU9OX0ZVTkNUSU9OX0VSUiwKLSAgICAgICAgIkVsIHVzbyBkZSBsYSBmdW5jaVx1MDBGM24gZGUgZXh0ZW5zaVx1MDBGM24gJyd7MH0nJyBubyBlc3RcdTAwRTEgcGVybWl0aWRvIGN1YW5kbyBsYSBmdW5jaVx1MDBGM24gZGUgcHJvY2VzYW1pZW50byBzZWd1cm8gc2UgaGEgZGVmaW5pZG8gZW4gdHJ1ZS4ifSwKLQotICAgICAgICB7QmFzaXNMaWJyYXJ5LlVOQUxMT1dFRF9FWFRFTlNJT05fRUxFTUVOVF9FUlIsCi0gICAgICAgICJFbCB1c28gZGVsIGVsZW1lbnRvIGRlIGV4dGVuc2lcdTAwRjNuICcnezB9Jycgbm8gZXN0XHUwMEUxIHBlcm1pdGlkbyBjdWFuZG8gbGEgZnVuY2lcdTAwRjNuIGRlIHByb2Nlc2FtaWVudG8gc2VndXJvIHNlIGhhIGRlZmluaWRvIGVuIHRydWUuIn0sCi0gICAgfTsKLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9FcnJvck1lc3NhZ2VzX2ZyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvRXJyb3JNZXNzYWdlc19mci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmNjBmMmE1Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9FcnJvck1lc3NhZ2VzX2ZyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyODQgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5ydW50aW1lOwotCi1pbXBvcnQgamF2YS51dGlsLkxpc3RSZXNvdXJjZUJ1bmRsZTsKLQotLyoqCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqLwotcHVibGljIGNsYXNzIEVycm9yTWVzc2FnZXNfZnIgZXh0ZW5kcyBMaXN0UmVzb3VyY2VCdW5kbGUgewotCi0vKgotICogWFNMVEMgcnVuLXRpbWUgZXJyb3IgbWVzc2FnZXMuCi0gKgotICogR2VuZXJhbCBub3RlcyB0byB0cmFuc2xhdG9ycyBhbmQgZGVmaW5pdGlvbnM6Ci0gKgotICogICAxKSBYU0xUQyBpcyB0aGUgbmFtZSBvZiB0aGUgcHJvZHVjdC4gIEl0IGlzIGFuIGFjcm9ueW0gZm9yIFhNTCBTdHlsZXNoZWV0OgotICogICAgICBUcmFuc2Zvcm1hdGlvbnMgQ29tcGlsZXIKLSAqCi0gKiAgIDIpIEEgc3R5bGVzaGVldCBpcyBhIGRlc2NyaXB0aW9uIG9mIGhvdyB0byB0cmFuc2Zvcm0gYW4gaW5wdXQgWE1MIGRvY3VtZW50Ci0gKiAgICAgIGludG8gYSByZXN1bHRhbnQgb3V0cHV0IFhNTCBkb2N1bWVudCAob3IgSFRNTCBkb2N1bWVudCBvciB0ZXh0KQotICoKLSAqICAgMykgQW4gYXhpcyBpcyBhIHBhcnRpY3VsYXIgImRpbWVuc2lvbiIgaW4gYSB0cmVlIHJlcHJlc2VudGF0aW9uIG9mIGFuIFhNTAotICogICAgICBkb2N1bWVudDsgdGhlIG5vZGVzIGluIHRoZSB0cmVlIGFyZSBkaXZpZGVkIGFsb25nIGRpZmZlcmVudCBheGVzLgotICogICAgICBUcmF2ZXJzaW5nIHRoZSAiY2hpbGQiIGF4aXMsIGZvciBpbnN0YW5jZSwgbWVhbnMgdGhhdCB0aGUgcHJvZ3JhbQotICogICAgICB3b3VsZCB2aXNpdCBlYWNoIGNoaWxkIG9mIGEgcGFydGljdWxhciBub2RlOyB0cmF2ZXJzaW5nIHRoZSAiZGVzY2VuZGFudCIKLSAqICAgICAgYXhpcyBtZWFucyB0aGF0IHRoZSBwcm9ncmFtIHdvdWxkIHZpc2l0IHRoZSBjaGlsZCBub2RlcyBvZiBhIHBhcnRpY3VsYXIKLSAqICAgICAgbm9kZSwgdGhlaXIgY2hpbGRyZW4sIGFuZCBzbyBvbiB1bnRpbCB0aGUgbGVhZiBub2RlcyBvZiB0aGUgdHJlZSBhcmUKLSAqICAgICAgcmVhY2hlZC4KLSAqCi0gKiAgIDQpIEFuIGl0ZXJhdG9yIGlzIGFuIG9iamVjdCB0aGF0IHRyYXZlcnNlcyBub2RlcyBpbiBhIHRyZWUgYWxvbmcgYQotICogICAgICBwYXJ0aWN1bGFyIGF4aXMsIG9uZSBhdCBhIHRpbWUuCi0gKgotICogICA1KSBBbiBlbGVtZW50IGlzIGEgbWFyay11cCB0YWcgaW4gYW4gWE1MIGRvY3VtZW50OyBhbiBhdHRyaWJ1dGUgaXMgYQotICogICAgICBtb2RpZmllciBvbiB0aGUgdGFnLiAgRm9yIGV4YW1wbGUsIGluIDxlbGVtIGF0dHI9J3ZhbCcgYXR0cjI9J3ZhbDInPgotICogICAgICAiZWxlbSIgaXMgYW4gZWxlbWVudCBuYW1lLCAiYXR0ciIgYW5kICJhdHRyMiIgYXJlIGF0dHJpYnV0ZSBuYW1lcyB3aXRoCi0gKiAgICAgIHRoZSB2YWx1ZXMgInZhbCIgYW5kICJ2YWwyIiwgcmVzcGVjdGl2ZWx5LgotICoKLSAqICAgNikgQSBuYW1lc3BhY2UgZGVjbGFyYXRpb24gaXMgYSBzcGVjaWFsIGF0dHJpYnV0ZSB0aGF0IGlzIHVzZWQgdG8gYXNzb2NpYXRlCi0gKiAgICAgIGEgcHJlZml4IHdpdGggYSBVUkkgKHRoZSBuYW1lc3BhY2UpLiAgVGhlIG1lYW5pbmdzIG9mIGVsZW1lbnQgbmFtZXMgYW5kCi0gKiAgICAgIGF0dHJpYnV0ZSBuYW1lcyB0aGF0IHVzZSB0aGF0IHByZWZpeCBhcmUgZGVmaW5lZCB3aXRoIHJlc3BlY3QgdG8gdGhhdAotICogICAgICBuYW1lc3BhY2UuCi0gKgotICogICA3KSBET00gaXMgYW4gYWNyb255bSBmb3IgRG9jdW1lbnQgT2JqZWN0IE1vZGVsLiAgSXQgaXMgYSB0cmVlCi0gKiAgICAgIHJlcHJlc2VudGF0aW9uIG9mIGFuIFhNTCBkb2N1bWVudC4KLSAqCi0gKiAgICAgIFNBWCBpcyBhbiBhY3JvbnltIGZvciB0aGUgU2ltcGxlIEFQSSBmb3IgWE1MIHByb2Nlc3NpbmcuICBJdCBpcyBhbiBBUEkKLSAqICAgICAgdXNlZCBpbmZvcm0gYW4gWE1MIHByb2Nlc3NvciAoaW4gdGhpcyBjYXNlIFhTTFRDKSBvZiB0aGUgc3RydWN0dXJlIGFuZAotICogICAgICBjb250ZW50IG9mIGFuIFhNTCBkb2N1bWVudC4KLSAqCi0gKiAgICAgIElucHV0IHRvIHRoZSBzdHlsZXNoZWV0IHByb2Nlc3NvciBjYW4gY29tZSBmcm9tIGFuIFhNTCBwYXJzZXIgaW4gdGhlCi0gKiAgICAgIGZvcm0gb2YgYSBET00gdHJlZSBvciB0aHJvdWdoIHRoZSBTQVggQVBJLgotICoKLSAqICAgOCkgRFREIGlzIGEgZG9jdW1lbnQgdHlwZSBkZWNsYXJhdGlvbi4gIEl0IGlzIGEgd2F5IG9mIHNwZWNpZnlpbmcgdGhlCi0gKiAgICAgIGdyYW1tYXIgZm9yIGFuIFhNTCBmaWxlLCB0aGUgbmFtZXMgYW5kIHR5cGVzIG9mIGVsZW1lbnRzLCBhdHRyaWJ1dGVzLAotICogICAgICBldGMuCi0gKgotICogICA5KSBUcmFuc2xldCBpcyBhbiBpbnZlbnRlZCB0ZXJtIHRoYXQgcmVmZXJzIHRvIHRoZSBjbGFzcyBmaWxlIHRoYXQgY29udGFpbnMKLSAqICAgICAgdGhlIGNvbXBpbGVkIGZvcm0gb2YgYSBzdHlsZXNoZWV0LgotICovCi0KLSAgICAvLyBUaGVzZSBtZXNzYWdlIHNob3VsZCBiZSByZWFkIGZyb20gYSBsb2NhbGUtc3BlY2lmaWMgcmVzb3VyY2UgYnVuZGxlCi0gICAgLyoqIEdldCB0aGUgbG9va3VwIHRhYmxlIGZvciBlcnJvciBtZXNzYWdlcy4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIG1lc3NhZ2UgbG9va3VwIHRhYmxlLgotICAgICAqLwotICAgIHB1YmxpYyBPYmplY3RbXVtdIGdldENvbnRlbnRzKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBuZXcgT2JqZWN0W11bXSB7Ci0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIHRoZSBzdWJzdGl0dXRpb24gdGV4dCBpbiB0aGUgZm9sbG93aW5nIG1lc3NhZ2UKLSAgICAgICAgICogaXMgYSBjbGFzcyBuYW1lLiAgVXNlZCBmb3IgaW50ZXJuYWwgZXJyb3JzIGluIHRoZSBwcm9jZXNzb3IuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LlJVTl9USU1FX0lOVEVSTkFMX0VSUiwKLSAgICAgICAgIkVycmV1ciBpbnRlcm5lIGQnJ2V4XHUwMEU5Y3V0aW9uIGRhbnMgJyd7MH0nJyJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICA8eHNsOmNvcHk+IGlzIGEga2V5d29yZCB0aGF0IHNob3VsZCBub3QgYmUKLSAgICAgICAgICogdHJhbnNsYXRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuUlVOX1RJTUVfQ09QWV9FUlIsCi0gICAgICAgICJFcnJldXIgZCdleFx1MDBFOWN1dGlvbiBkZSA8eHNsOmNvcHk+LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgcmVmZXJzIHRvIGRhdGEgdHlwZXMuCi0gICAgICAgICAqIFRoZSBtZXNzYWdlIGlzIGRpc3BsYXllZCBpZiBhIHZhbHVlIGluIGEgcGFydGljdWxhciBjb250ZXh0IG5lZWRzIHRvCi0gICAgICAgICAqIGJlIGNvbnZlcnRlZCB0byB0eXBlIHsxfSwgYnV0IHRoYXQncyBub3QgcG9zc2libGUgZm9yIGEgdmFsdWUgb2YgdHlwZQotICAgICAgICAgKiB7MH0uCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LkRBVEFfQ09OVkVSU0lPTl9FUlIsCi0gICAgICAgICJDb252ZXJzaW9uIGRlICcnezB9JycgXHUwMEUwICcnezF9Jycgbm9uIHZhbGlkZS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIGRpc3BsYXllZCBpZiB0aGUgZnVuY3Rpb24gbmFtZWQKLSAgICAgICAgICogYnkgdGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIG5vdCBhIGZ1bmN0aW9uIHRoYXQgaXMgc3VwcG9ydGVkLiAgWFNMVEMKLSAgICAgICAgICogaXMgdGhlIGFjcm9ueW0gbmFtaW5nIHRoZSBwcm9kdWN0LgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5FWFRFUk5BTF9GVU5DX0VSUiwKLSAgICAgICAgIkZvbmN0aW9uIGV4dGVybmUgJyd7MH0nJyBub24gcHJpc2UgZW4gY2hhcmdlIHBhciBYU0xUQy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIGRpc3BsYXllZCBpZiB0d28gdmFsdWVzIGFyZQotICAgICAgICAgKiBjb21wYXJlZCBmb3IgZXF1YWxpdHksIGJ1dCB0aGUgZGF0YSB0eXBlIG9mIG9uZSBvZiB0aGUgdmFsdWVzIGlzCi0gICAgICAgICAqIHVua25vd24uCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LkVRVUFMSVRZX0VYUFJfRVJSLAotICAgICAgICAiVHlwZSBkJ2FyZ3VtZW50IGluY29ubnUgZGFucyBsJ2V4cHJlc3Npb24gZCdcdTAwRTlnYWxpdFx1MDBFOS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGZvciB7MH0gd2lsbCBiZSBhIGRhdGEKLSAgICAgICAgICogdHlwZTsgdGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGZvciB7MX0gd2lsbCBiZSB0aGUgbmFtZSBvZiBhIGZ1bmN0aW9uLgotICAgICAgICAgKiBUaGlzIGlzIGRpc3BsYXllZCBpZiBhbiBhcmd1bWVudCBvZiB0aGUgcGFydGljdWxhciBkYXRhIHR5cGUgaXMgbm90Ci0gICAgICAgICAqIHBlcm1pdHRlZCBmb3IgYSBjYWxsIHRvIHRoaXMgZnVuY3Rpb24uCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LklOVkFMSURfQVJHVU1FTlRfRVJSLAotICAgICAgICAiVHlwZSBkJydhcmd1bWVudCAnJ3swfScnIG5vbiB2YWxpZGUgZGFucyBsJydhcHBlbCBkZSAnJ3sxfScnIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZXJlIGlzIHdheSBvZiBzcGVjaWZ5aW5nIGEgZm9ybWF0IGZvciBhCi0gICAgICAgICAqIG51bWJlciB1c2luZyBhIHBhdHRlcm47IHRoZSBwcm9jZXNzb3Igd2FzIHVuYWJsZSB0byBmb3JtYXQgdGhlCi0gICAgICAgICAqIHBhcnRpY3VsYXIgdmFsdWUgdXNpbmcgdGhlIHNwZWNpZmllZCBwYXR0ZXJuLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5GT1JNQVRfTlVNQkVSX0VSUiwKLSAgICAgICAgIlRlbnRhdGl2ZSBkZSBmb3JtYXRhZ2UgZHUgbm9tYnJlICcnezB9JycgXHUwMEUwIGwnJ2FpZGUgZHUgbW9kXHUwMEU4bGUgJyd7MX0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyByZXByZXNlbnRzIGFuIGludGVybmFsIGVycm9yCi0gICAgICAgICAqIHNpdHVhdGlvbiBpbiBYU0xUQy4gIFRoZSBwcm9jZXNzb3Igd2FzIHVuYWJsZSB0byBjcmVhdGUgYSBjb3B5IG9mIGFuCi0gICAgICAgICAqIGl0ZXJhdG9yLiAgKFNlZSBkZWZpbml0aW9uIG9mIGl0ZXJhdG9yIGFib3ZlLikKLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuSVRFUkFUT1JfQ0xPTkVfRVJSLAotICAgICAgICAiSW1wb3NzaWJsZSBkZSBjbG9uZXIgbCcnaXRcdTAwRTlyYXRldXIgJyd7MH0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyByZXByZXNlbnRzIGFuIGludGVybmFsIGVycm9yCi0gICAgICAgICAqIHNpdHVhdGlvbiBpbiBYU0xUQy4gIFRoZSBwcm9jZXNzb3IgYXR0ZW1wdGVkIHRvIGNyZWF0ZSBhbiBpdGVyYXRvcgotICAgICAgICAgKiBmb3IgYSBwYXJ0aWN1bGFyIGF4aXMgKHNlZSBkZWZpbml0aW9uIGFib3ZlKSB0aGF0IGl0IGRvZXMgbm90Ci0gICAgICAgICAqIHN1cHBvcnQuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LkFYSVNfU1VQUE9SVF9FUlIsCi0gICAgICAgICJJdFx1MDBFOXJhdGV1ciBkZSBsJydheGUgJyd7MH0nJyBub24gcHJpcyBlbiBjaGFyZ2UuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgcmVwcmVzZW50cyBhbiBpbnRlcm5hbCBlcnJvcgotICAgICAgICAgKiBzaXR1YXRpb24gaW4gWFNMVEMuICBUaGUgcHJvY2Vzc29yIGF0dGVtcHRlZCB0byBjcmVhdGUgYW4gaXRlcmF0b3IKLSAgICAgICAgICogZm9yIGEgcGFydGljdWxhciBheGlzIChzZWUgZGVmaW5pdGlvbiBhYm92ZSkgdGhhdCBpdCBkb2VzIG5vdAotICAgICAgICAgKiBzdXBwb3J0LgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5UWVBFRF9BWElTX1NVUFBPUlRfRVJSLAotICAgICAgICAiSXRcdTAwRTlyYXRldXIgZGUgbCcnYXhlIHNhaXNpICcnezB9Jycgbm9uIHByaXMgZW4gY2hhcmdlLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgcmVwb3J0ZWQgaWYgdGhlIHN0eWxlc2hlZXQKLSAgICAgICAgICogYmVpbmcgcHJvY2Vzc2VkIGF0dGVtcHRlZCB0byBjb25zdHJ1Y3QgYW4gWE1MIGRvY3VtZW50IHdpdGggYW4KLSAgICAgICAgICogYXR0cmlidXRlIGluIGEgcGxhY2Ugb3RoZXIgdGhhbiBvbiBhbiBlbGVtZW50LiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgICAqIHNwZWNpZmllcyB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5TVFJBWV9BVFRSSUJVVEVfRVJSLAotICAgICAgICAiQXR0cmlidXQgJyd7MH0nJyBlbiBkZWhvcnMgZGUgbCcnXHUwMEU5bFx1MDBFOW1lbnQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFzIHdpdGggdGhlIHByZWNlZGluZyBtZXNzYWdlLCBhIG5hbWVzcGFjZQotICAgICAgICAgKiBkZWNsYXJhdGlvbiBoYXMgdGhlIGZvcm0gb2YgYW4gYXR0cmlidXRlIGFuZCBpcyBvbmx5IHBlcm1pdHRlZCB0bwotICAgICAgICAgKiBhcHBlYXIgb24gYW4gZWxlbWVudC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCB7MH0gaXMgdGhlIG5hbWVzcGFjZQotICAgICAgICAgKiBwcmVmaXggYW5kIHsxfSBpcyB0aGUgVVJJIHRoYXQgd2FzIGJlaW5nIHVzZWQgaW4gdGhlIGVycm9uZW91cwotICAgICAgICAgKiBuYW1lc3BhY2UgZGVjbGFyYXRpb24uCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LlNUUkFZX05BTUVTUEFDRV9FUlIsCi0gICAgICAgICJMYSBkXHUwMEU5Y2xhcmF0aW9uIGQnJ2VzcGFjZSBkZSBub21zICcnezB9Jyc9Jyd7MX0nJyBlc3QgXHUwMEUwIGwnJ2V4dFx1MDBFOXJpZXVyIGRlIGwnJ1x1MDBFOWxcdTAwRTltZW50LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3R5bGVzaGVldCBjb250YWluZWQgYSByZWZlcmVuY2UgdG8gYQotICAgICAgICAgKiBuYW1lc3BhY2UgcHJlZml4IHRoYXQgd2FzIHVuZGVmaW5lZC4gIFRoZSB2YWx1ZSBvZiB0aGUgc3Vic3RpdHV0aW9uCi0gICAgICAgICAqIHRleHQgaXMgdGhlIG5hbWUgb2YgdGhlIHByZWZpeC4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuTkFNRVNQQUNFX1BSRUZJWF9FUlIsCi0gICAgICAgICJMJydlc3BhY2UgZGUgbm9tcyBkdSBwclx1MDBFOWZpeGUgJyd7MH0nJyBuJydhIHBhcyBcdTAwRTl0XHUwMEU5IGRcdTAwRTljbGFyXHUwMEU5LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIHJlcHJlc2VudHMgYW4gaW50ZXJuYWwgZXJyb3IuCi0gICAgICAgICAqIERPTUFkYXB0ZXIgaXMgYSBKYXZhIGNsYXNzIGluIFhTTFRDLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5ET01fQURBUFRFUl9JTklUX0VSUiwKLSAgICAgICAgIkRPTUFkYXB0ZXIgY3JcdTAwRTlcdTAwRTkgYXZlYyBsZSBtYXV2YWlzIHR5cGUgZGUgRE9NIHNvdXJjZS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoZSBYTUwKLSAgICAgICAgICogcGFyc2VyIHRoYXQgaXMgcHJvdmlkaW5nIGlucHV0IHRvIFhTTFRDIGNhbm5vdCBiZSB1c2VkIGJlY2F1c2UgaXQKLSAgICAgICAgICogZG9lcyBub3QgZGVzY3JpYmUgdG8gWFNMVEMgdGhlIHN0cnVjdHVyZSBvZiB0aGUgaW5wdXQgWE1MIGRvY3VtZW50J3MKLSAgICAgICAgICogRFRELgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5QQVJTRVJfRFREX1NVUFBPUlRfRVJSLAotICAgICAgICAiTCdhbmFseXNldXIgU0FYIHF1ZSB2b3VzIHV0aWxpc2V6IG5lIGdcdTAwRThyZSBwYXMgbGVzIFx1MDBFOXZcdTAwRTluZW1lbnRzIGRlIGRcdTAwRTljbGFyYXRpb24gRFRELiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhlIFhNTAotICAgICAgICAgKiBwYXJzZXIgdGhhdCBpcyBwcm92aWRpbmcgaW5wdXQgdG8gWFNMVEMgY2Fubm90IGJlIHVzZWQgYmVjYXVzZSBpdAotICAgICAgICAgKiBkb2VzIG5vdCBkaXN0aW5ndWlzaCBiZXR3ZWVuIG9yZGluYXJ5IFhNTCBhdHRyaWJ1dGVzIGFuZCBuYW1lc3BhY2UKLSAgICAgICAgICogZGVjbGFyYXRpb25zLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5OQU1FU1BBQ0VTX1NVUFBPUlRfRVJSLAotICAgICAgICAiTCdhbmFseXNldXIgU0FYIHF1ZSB2b3VzIHV0aWxpc2V6IG5lIHByZW5kIHBhcyBlbiBjaGFyZ2UgbGVzIGVzcGFjZXMgZGUgbm9tcyBYTUwuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgVVJJIHRoYXQgd2FzIGluCi0gICAgICAgICAqIGVycm9yLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5DQU5UX1JFU09MVkVfUkVMQVRJVkVfVVJJX0VSUiwKLSAgICAgICAgIkltcG9zc2libGUgZGUgclx1MDBFOXNvdWRyZSBsYSByXHUwMEU5Zlx1MDBFOXJlbmNlIGQnJ1VSSSAnJ3swfScnLiJ9LAotCi0gICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN0eWxlc2hlZXQgY29udGFpbmVkIGFuIGVsZW1lbnQgdGhhdCB3YXMKLSAgICAgICAgICogbm90IHJlY29nbml6ZWQgYXMgcGFydCBvZiB0aGUgWFNMIHN5bnRheC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICAgKiBnaXZlcyB0aGUgZWxlbWVudCBuYW1lLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5VTlNVUFBPUlRFRF9YU0xfRVJSLAotICAgICAgICAiRWxcdTAwRTltZW50IFhTTCAnJ3swfScnIG5vbiBwcmlzIGVuIGNoYXJnZSJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3R5bGVzaGVldCByZWZlcnJlZCB0byBhbiBleHRlbnNpb24gdG8gdGhlCi0gICAgICAgICAqIFhTTCBzeW50YXggYW5kIGluZGljYXRlZCB0aGF0IGl0IHdhcyBkZWZpbmVkIGJ5IFhTTFRDLCBidXQgWFNMVEMgZG9lcwotICAgICAgICAgKiBub3QgcmVjb2duaXplIHRoZSBwYXJ0aWN1bGFyIGV4dGVuc2lvbiBuYW1lZC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICAgKiBnaXZlcyB0aGUgZXh0ZW5zaW9uIG5hbWUuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LlVOU1VQUE9SVEVEX0VYVF9FUlIsCi0gICAgICAgICJFeHRlbnNpb24gWFNMVEMgJyd7MH0nJyBub24gcmVjb25udWUifSwKLQotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIGVycm9yIG1lc3NhZ2UgaXMgcHJvZHVjZWQgaWYgdGhlIHRyYW5zbGV0Ci0gICAgICAgICAqIGNsYXNzIHdhcyBjb21waWxlZCB1c2luZyBhIG5ld2VyIHZlcnNpb24gb2YgWFNMVEMgYW5kIGRlcGxveWVkIGZvcgotICAgICAgICAgKiBleGVjdXRpb24gd2l0aCBhbiBvbGRlciB2ZXJzaW9uIG9mIFhTTFRDLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzCi0gICAgICAgICAqIHRoZSBuYW1lIG9mIHRoZSB0cmFuc2xldCBjbGFzcy4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuVU5LTk9XTl9UUkFOU0xFVF9WRVJTSU9OX0VSUiwKLSAgICAgICAgIkxlIHRyYW5zbGV0IHNwXHUwMEU5Y2lmaVx1MDBFOSwgJyd7MH0nJywgYSBcdTAwRTl0XHUwMEU5IGNyXHUwMEU5XHUwMEU5IFx1MDBFMCBsJydhaWRlIGQnJ3VuZSB2ZXJzaW9uIGRlIFhTTFRDIHBsdXMgclx1MDBFOWNlbnRlIHF1ZSBsYSB2ZXJzaW9uIGRlIGwnJ2V4XHUwMEU5Y3V0aW9uIFhTTFRDIHV0aWxpc1x1MDBFOWUuIFZvdXMgZGV2ZXogcmVjb21waWxlciBsYSBmZXVpbGxlIGRlIHN0eWxlIG91IHV0aWxpc2VyIHVuZSB2ZXJzaW9uIHBsdXMgclx1MDBFOWNlbnRlIGRlIFhTTFRDIHBvdXIgZXhcdTAwRTljdXRlciBjZSB0cmFuc2xldC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQW4gYXR0cmlidXRlIHdob3NlIGVmZmVjdGl2ZSB2YWx1ZSBpcyByZXF1aXJlZAotICAgICAgICAgKiB0byBiZSBhICJRTmFtZSIgaGFkIGEgdmFsdWUgdGhhdCB3YXMgaW5jb3JyZWN0LgotICAgICAgICAgKiAnUU5hbWUnIGlzIGFuIFhNTCBzeW50YWN0aWMgdGVybSB0aGF0IG11c3Qgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGUKLSAgICAgICAgICogc3Vic3RpdHV0aW9uIHRleHQgY29udGFpbnMgdGhlIGFjdHVhbCB2YWx1ZSBvZiB0aGUgYXR0cmlidXRlLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5JTlZBTElEX1FOQU1FX0VSUiwKLSAgICAgICAgIlVuIGF0dHJpYnV0IGRvbnQgbGEgdmFsZXVyIGRvaXQgXHUwMEVBdHJlIHVuIFFOYW1lIGF2YWl0IGxhIHZhbGV1ciAnJ3swfScnIn0sCi0KLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQW4gYXR0cmlidXRlIHdob3NlIGVmZmVjdGl2ZSB2YWx1ZSBpcyByZXF1aXJlZAotICAgICAgICAgKiB0byBiZSBhICJOQ05hbWUiIGhhZCBhIHZhbHVlIHRoYXQgd2FzIGluY29ycmVjdC4KLSAgICAgICAgICogJ05DTmFtZScgaXMgYW4gWE1MIHN5bnRhY3RpYyB0ZXJtIHRoYXQgbXVzdCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoZQotICAgICAgICAgKiBzdWJzdGl0dXRpb24gdGV4dCBjb250YWlucyB0aGUgYWN0dWFsIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LklOVkFMSURfTkNOQU1FX0VSUiwKLSAgICAgICAgIlVuIGF0dHJpYnV0IGRvbnQgbGEgdmFsZXVyIGRvaXQgXHUwMEVBdHJlIHVuIE5DTmFtZSBhdmFpdCBsYSB2YWxldXIgJyd7MH0nJyJ9LAotCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuVU5BTExPV0VEX0VYVEVOU0lPTl9GVU5DVElPTl9FUlIsCi0gICAgICAgICJMJyd1dGlsaXNhdGlvbiBkZSBsYSBmb25jdGlvbiBkJydleHRlbnNpb24gJyd7MH0nJyBuJydlc3QgcGFzIGF1dG9yaXNcdTAwRTllIGxvcnNxdWUgbGEgZm9uY3Rpb25uYWxpdFx1MDBFOSBkZSB0cmFpdGVtZW50IHNcdTAwRTljdXJpc1x1MDBFOSBlc3QgZFx1MDBFOWZpbmllIHN1ciBUcnVlLiJ9LAotCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuVU5BTExPV0VEX0VYVEVOU0lPTl9FTEVNRU5UX0VSUiwKLSAgICAgICAgIkwnJ3V0aWxpc2F0aW9uIGRlIGwnJ1x1MDBFOWxcdTAwRTltZW50IGQnJ2V4dGVuc2lvbiAnJ3swfScnIG4nJ2VzdCBwYXMgYXV0b3Jpc1x1MDBFOWUgbG9yc3F1ZSBsYSBmb25jdGlvbm5hbGl0XHUwMEU5IGRlIHRyYWl0ZW1lbnQgc1x1MDBFOWN1cmlzXHUwMEU5IGVzdCBkXHUwMEU5ZmluaWUgc3VyIFRydWUuIn0sCi0gICAgfTsKLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9FcnJvck1lc3NhZ2VzX2l0LmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvRXJyb3JNZXNzYWdlc19pdC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlNGE3YjJkLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9FcnJvck1lc3NhZ2VzX2l0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyODQgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5ydW50aW1lOwotCi1pbXBvcnQgamF2YS51dGlsLkxpc3RSZXNvdXJjZUJ1bmRsZTsKLQotLyoqCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqLwotcHVibGljIGNsYXNzIEVycm9yTWVzc2FnZXNfaXQgZXh0ZW5kcyBMaXN0UmVzb3VyY2VCdW5kbGUgewotCi0vKgotICogWFNMVEMgcnVuLXRpbWUgZXJyb3IgbWVzc2FnZXMuCi0gKgotICogR2VuZXJhbCBub3RlcyB0byB0cmFuc2xhdG9ycyBhbmQgZGVmaW5pdGlvbnM6Ci0gKgotICogICAxKSBYU0xUQyBpcyB0aGUgbmFtZSBvZiB0aGUgcHJvZHVjdC4gIEl0IGlzIGFuIGFjcm9ueW0gZm9yIFhNTCBTdHlsZXNoZWV0OgotICogICAgICBUcmFuc2Zvcm1hdGlvbnMgQ29tcGlsZXIKLSAqCi0gKiAgIDIpIEEgc3R5bGVzaGVldCBpcyBhIGRlc2NyaXB0aW9uIG9mIGhvdyB0byB0cmFuc2Zvcm0gYW4gaW5wdXQgWE1MIGRvY3VtZW50Ci0gKiAgICAgIGludG8gYSByZXN1bHRhbnQgb3V0cHV0IFhNTCBkb2N1bWVudCAob3IgSFRNTCBkb2N1bWVudCBvciB0ZXh0KQotICoKLSAqICAgMykgQW4gYXhpcyBpcyBhIHBhcnRpY3VsYXIgImRpbWVuc2lvbiIgaW4gYSB0cmVlIHJlcHJlc2VudGF0aW9uIG9mIGFuIFhNTAotICogICAgICBkb2N1bWVudDsgdGhlIG5vZGVzIGluIHRoZSB0cmVlIGFyZSBkaXZpZGVkIGFsb25nIGRpZmZlcmVudCBheGVzLgotICogICAgICBUcmF2ZXJzaW5nIHRoZSAiY2hpbGQiIGF4aXMsIGZvciBpbnN0YW5jZSwgbWVhbnMgdGhhdCB0aGUgcHJvZ3JhbQotICogICAgICB3b3VsZCB2aXNpdCBlYWNoIGNoaWxkIG9mIGEgcGFydGljdWxhciBub2RlOyB0cmF2ZXJzaW5nIHRoZSAiZGVzY2VuZGFudCIKLSAqICAgICAgYXhpcyBtZWFucyB0aGF0IHRoZSBwcm9ncmFtIHdvdWxkIHZpc2l0IHRoZSBjaGlsZCBub2RlcyBvZiBhIHBhcnRpY3VsYXIKLSAqICAgICAgbm9kZSwgdGhlaXIgY2hpbGRyZW4sIGFuZCBzbyBvbiB1bnRpbCB0aGUgbGVhZiBub2RlcyBvZiB0aGUgdHJlZSBhcmUKLSAqICAgICAgcmVhY2hlZC4KLSAqCi0gKiAgIDQpIEFuIGl0ZXJhdG9yIGlzIGFuIG9iamVjdCB0aGF0IHRyYXZlcnNlcyBub2RlcyBpbiBhIHRyZWUgYWxvbmcgYQotICogICAgICBwYXJ0aWN1bGFyIGF4aXMsIG9uZSBhdCBhIHRpbWUuCi0gKgotICogICA1KSBBbiBlbGVtZW50IGlzIGEgbWFyay11cCB0YWcgaW4gYW4gWE1MIGRvY3VtZW50OyBhbiBhdHRyaWJ1dGUgaXMgYQotICogICAgICBtb2RpZmllciBvbiB0aGUgdGFnLiAgRm9yIGV4YW1wbGUsIGluIDxlbGVtIGF0dHI9J3ZhbCcgYXR0cjI9J3ZhbDInPgotICogICAgICAiZWxlbSIgaXMgYW4gZWxlbWVudCBuYW1lLCAiYXR0ciIgYW5kICJhdHRyMiIgYXJlIGF0dHJpYnV0ZSBuYW1lcyB3aXRoCi0gKiAgICAgIHRoZSB2YWx1ZXMgInZhbCIgYW5kICJ2YWwyIiwgcmVzcGVjdGl2ZWx5LgotICoKLSAqICAgNikgQSBuYW1lc3BhY2UgZGVjbGFyYXRpb24gaXMgYSBzcGVjaWFsIGF0dHJpYnV0ZSB0aGF0IGlzIHVzZWQgdG8gYXNzb2NpYXRlCi0gKiAgICAgIGEgcHJlZml4IHdpdGggYSBVUkkgKHRoZSBuYW1lc3BhY2UpLiAgVGhlIG1lYW5pbmdzIG9mIGVsZW1lbnQgbmFtZXMgYW5kCi0gKiAgICAgIGF0dHJpYnV0ZSBuYW1lcyB0aGF0IHVzZSB0aGF0IHByZWZpeCBhcmUgZGVmaW5lZCB3aXRoIHJlc3BlY3QgdG8gdGhhdAotICogICAgICBuYW1lc3BhY2UuCi0gKgotICogICA3KSBET00gaXMgYW4gYWNyb255bSBmb3IgRG9jdW1lbnQgT2JqZWN0IE1vZGVsLiAgSXQgaXMgYSB0cmVlCi0gKiAgICAgIHJlcHJlc2VudGF0aW9uIG9mIGFuIFhNTCBkb2N1bWVudC4KLSAqCi0gKiAgICAgIFNBWCBpcyBhbiBhY3JvbnltIGZvciB0aGUgU2ltcGxlIEFQSSBmb3IgWE1MIHByb2Nlc3NpbmcuICBJdCBpcyBhbiBBUEkKLSAqICAgICAgdXNlZCBpbmZvcm0gYW4gWE1MIHByb2Nlc3NvciAoaW4gdGhpcyBjYXNlIFhTTFRDKSBvZiB0aGUgc3RydWN0dXJlIGFuZAotICogICAgICBjb250ZW50IG9mIGFuIFhNTCBkb2N1bWVudC4KLSAqCi0gKiAgICAgIElucHV0IHRvIHRoZSBzdHlsZXNoZWV0IHByb2Nlc3NvciBjYW4gY29tZSBmcm9tIGFuIFhNTCBwYXJzZXIgaW4gdGhlCi0gKiAgICAgIGZvcm0gb2YgYSBET00gdHJlZSBvciB0aHJvdWdoIHRoZSBTQVggQVBJLgotICoKLSAqICAgOCkgRFREIGlzIGEgZG9jdW1lbnQgdHlwZSBkZWNsYXJhdGlvbi4gIEl0IGlzIGEgd2F5IG9mIHNwZWNpZnlpbmcgdGhlCi0gKiAgICAgIGdyYW1tYXIgZm9yIGFuIFhNTCBmaWxlLCB0aGUgbmFtZXMgYW5kIHR5cGVzIG9mIGVsZW1lbnRzLCBhdHRyaWJ1dGVzLAotICogICAgICBldGMuCi0gKgotICogICA5KSBUcmFuc2xldCBpcyBhbiBpbnZlbnRlZCB0ZXJtIHRoYXQgcmVmZXJzIHRvIHRoZSBjbGFzcyBmaWxlIHRoYXQgY29udGFpbnMKLSAqICAgICAgdGhlIGNvbXBpbGVkIGZvcm0gb2YgYSBzdHlsZXNoZWV0LgotICovCi0KLSAgICAvLyBUaGVzZSBtZXNzYWdlIHNob3VsZCBiZSByZWFkIGZyb20gYSBsb2NhbGUtc3BlY2lmaWMgcmVzb3VyY2UgYnVuZGxlCi0gICAgLyoqIEdldCB0aGUgbG9va3VwIHRhYmxlIGZvciBlcnJvciBtZXNzYWdlcy4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIG1lc3NhZ2UgbG9va3VwIHRhYmxlLgotICAgICAqLwotICAgIHB1YmxpYyBPYmplY3RbXVtdIGdldENvbnRlbnRzKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBuZXcgT2JqZWN0W11bXSB7Ci0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIHRoZSBzdWJzdGl0dXRpb24gdGV4dCBpbiB0aGUgZm9sbG93aW5nIG1lc3NhZ2UKLSAgICAgICAgICogaXMgYSBjbGFzcyBuYW1lLiAgVXNlZCBmb3IgaW50ZXJuYWwgZXJyb3JzIGluIHRoZSBwcm9jZXNzb3IuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LlJVTl9USU1FX0lOVEVSTkFMX0VSUiwKLSAgICAgICAgIkVycm9yZSBpbnRlcm5vIGluIGZhc2UgZGkgZXNlY3V6aW9uZSBpbiAnJ3swfScnIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIDx4c2w6Y29weT4gaXMgYSBrZXl3b3JkIHRoYXQgc2hvdWxkIG5vdCBiZQotICAgICAgICAgKiB0cmFuc2xhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5SVU5fVElNRV9DT1BZX0VSUiwKLSAgICAgICAgIkVycm9yZSBpbiBmYXNlIGRpIGVzZWN1emlvbmUgZHVyYW50ZSBsJ2VzZWN1emlvbmUgZGkgPHhzbDpjb3B5Pi4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHJlZmVycyB0byBkYXRhIHR5cGVzLgotICAgICAgICAgKiBUaGUgbWVzc2FnZSBpcyBkaXNwbGF5ZWQgaWYgYSB2YWx1ZSBpbiBhIHBhcnRpY3VsYXIgY29udGV4dCBuZWVkcyB0bwotICAgICAgICAgKiBiZSBjb252ZXJ0ZWQgdG8gdHlwZSB7MX0sIGJ1dCB0aGF0J3Mgbm90IHBvc3NpYmxlIGZvciBhIHZhbHVlIG9mIHR5cGUKLSAgICAgICAgICogezB9LgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5EQVRBX0NPTlZFUlNJT05fRVJSLAotICAgICAgICAiQ29udmVyc2lvbmUgbm9uIHZhbGlkYSBkYSAnJ3swfScnIGEgJyd7MX0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIGRpc3BsYXllZCBpZiB0aGUgZnVuY3Rpb24gbmFtZWQKLSAgICAgICAgICogYnkgdGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIG5vdCBhIGZ1bmN0aW9uIHRoYXQgaXMgc3VwcG9ydGVkLiAgWFNMVEMKLSAgICAgICAgICogaXMgdGhlIGFjcm9ueW0gbmFtaW5nIHRoZSBwcm9kdWN0LgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5FWFRFUk5BTF9GVU5DX0VSUiwKLSAgICAgICAgIkZ1bnppb25lIGVzdGVybmEgJyd7MH0nJyBub24gc3VwcG9ydGF0YSBkYSBYU0xUQy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIGRpc3BsYXllZCBpZiB0d28gdmFsdWVzIGFyZQotICAgICAgICAgKiBjb21wYXJlZCBmb3IgZXF1YWxpdHksIGJ1dCB0aGUgZGF0YSB0eXBlIG9mIG9uZSBvZiB0aGUgdmFsdWVzIGlzCi0gICAgICAgICAqIHVua25vd24uCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LkVRVUFMSVRZX0VYUFJfRVJSLAotICAgICAgICAiVGlwbyBkaSBhcmdvbWVudG8gc2Nvbm9zY2l1dG8gbmVsbCdlc3ByZXNzaW9uZSBkaSB1Z3VhZ2xpYW56YS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGZvciB7MH0gd2lsbCBiZSBhIGRhdGEKLSAgICAgICAgICogdHlwZTsgdGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGZvciB7MX0gd2lsbCBiZSB0aGUgbmFtZSBvZiBhIGZ1bmN0aW9uLgotICAgICAgICAgKiBUaGlzIGlzIGRpc3BsYXllZCBpZiBhbiBhcmd1bWVudCBvZiB0aGUgcGFydGljdWxhciBkYXRhIHR5cGUgaXMgbm90Ci0gICAgICAgICAqIHBlcm1pdHRlZCBmb3IgYSBjYWxsIHRvIHRoaXMgZnVuY3Rpb24uCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LklOVkFMSURfQVJHVU1FTlRfRVJSLAotICAgICAgICAiVGlwbyBkaSBhcmdvbWVudG8gJyd7MH0nJyBub24gdmFsaWRvIG5lbGxhIGNoaWFtYXRhIGEgJyd7MX0nJyJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGVyZSBpcyB3YXkgb2Ygc3BlY2lmeWluZyBhIGZvcm1hdCBmb3IgYQotICAgICAgICAgKiBudW1iZXIgdXNpbmcgYSBwYXR0ZXJuOyB0aGUgcHJvY2Vzc29yIHdhcyB1bmFibGUgdG8gZm9ybWF0IHRoZQotICAgICAgICAgKiBwYXJ0aWN1bGFyIHZhbHVlIHVzaW5nIHRoZSBzcGVjaWZpZWQgcGF0dGVybi4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuRk9STUFUX05VTUJFUl9FUlIsCi0gICAgICAgICJUZW50YXRpdm8gZGkgZm9ybWF0dGFyZSBpbCBudW1lcm8gJyd7MH0nJyBtZWRpYW50ZSBpbCBwYXR0ZXJuICcnezF9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgcmVwcmVzZW50cyBhbiBpbnRlcm5hbCBlcnJvcgotICAgICAgICAgKiBzaXR1YXRpb24gaW4gWFNMVEMuICBUaGUgcHJvY2Vzc29yIHdhcyB1bmFibGUgdG8gY3JlYXRlIGEgY29weSBvZiBhbgotICAgICAgICAgKiBpdGVyYXRvci4gIChTZWUgZGVmaW5pdGlvbiBvZiBpdGVyYXRvciBhYm92ZS4pCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LklURVJBVE9SX0NMT05FX0VSUiwKLSAgICAgICAgIkltcG9zc2liaWxlIGR1cGxpY2FyZSBsJydpdGVyYXRvcmUgJyd7MH0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyByZXByZXNlbnRzIGFuIGludGVybmFsIGVycm9yCi0gICAgICAgICAqIHNpdHVhdGlvbiBpbiBYU0xUQy4gIFRoZSBwcm9jZXNzb3IgYXR0ZW1wdGVkIHRvIGNyZWF0ZSBhbiBpdGVyYXRvcgotICAgICAgICAgKiBmb3IgYSBwYXJ0aWN1bGFyIGF4aXMgKHNlZSBkZWZpbml0aW9uIGFib3ZlKSB0aGF0IGl0IGRvZXMgbm90Ci0gICAgICAgICAqIHN1cHBvcnQuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LkFYSVNfU1VQUE9SVF9FUlIsCi0gICAgICAgICJJdGVyYXRvcmUgcGVyIGwnJ2Fzc2UgJyd7MH0nJyBub24gc3VwcG9ydGF0by4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyByZXByZXNlbnRzIGFuIGludGVybmFsIGVycm9yCi0gICAgICAgICAqIHNpdHVhdGlvbiBpbiBYU0xUQy4gIFRoZSBwcm9jZXNzb3IgYXR0ZW1wdGVkIHRvIGNyZWF0ZSBhbiBpdGVyYXRvcgotICAgICAgICAgKiBmb3IgYSBwYXJ0aWN1bGFyIGF4aXMgKHNlZSBkZWZpbml0aW9uIGFib3ZlKSB0aGF0IGl0IGRvZXMgbm90Ci0gICAgICAgICAqIHN1cHBvcnQuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LlRZUEVEX0FYSVNfU1VQUE9SVF9FUlIsCi0gICAgICAgICJJdGVyYXRvcmUgcGVyIGwnJ2Fzc2UgaW1tZXNzbyAnJ3swfScnIG5vbiBzdXBwb3J0YXRvLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgcmVwb3J0ZWQgaWYgdGhlIHN0eWxlc2hlZXQKLSAgICAgICAgICogYmVpbmcgcHJvY2Vzc2VkIGF0dGVtcHRlZCB0byBjb25zdHJ1Y3QgYW4gWE1MIGRvY3VtZW50IHdpdGggYW4KLSAgICAgICAgICogYXR0cmlidXRlIGluIGEgcGxhY2Ugb3RoZXIgdGhhbiBvbiBhbiBlbGVtZW50LiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgICAqIHNwZWNpZmllcyB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5TVFJBWV9BVFRSSUJVVEVfRVJSLAotICAgICAgICAiQXR0cmlidXRvICcnezB9JycgYWwgZGkgZnVvcmkgZGVsbCcnZWxlbWVudG8uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFzIHdpdGggdGhlIHByZWNlZGluZyBtZXNzYWdlLCBhIG5hbWVzcGFjZQotICAgICAgICAgKiBkZWNsYXJhdGlvbiBoYXMgdGhlIGZvcm0gb2YgYW4gYXR0cmlidXRlIGFuZCBpcyBvbmx5IHBlcm1pdHRlZCB0bwotICAgICAgICAgKiBhcHBlYXIgb24gYW4gZWxlbWVudC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCB7MH0gaXMgdGhlIG5hbWVzcGFjZQotICAgICAgICAgKiBwcmVmaXggYW5kIHsxfSBpcyB0aGUgVVJJIHRoYXQgd2FzIGJlaW5nIHVzZWQgaW4gdGhlIGVycm9uZW91cwotICAgICAgICAgKiBuYW1lc3BhY2UgZGVjbGFyYXRpb24uCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LlNUUkFZX05BTUVTUEFDRV9FUlIsCi0gICAgICAgICJEaWNoaWFyYXppb25lIGRlbGxvIHNwYXppbyBkaSBub21pICcnezB9Jyc9Jyd7MX0nJyBhbCBkaSBmdW9yaSBkZWxsJydlbGVtZW50by4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN0eWxlc2hlZXQgY29udGFpbmVkIGEgcmVmZXJlbmNlIHRvIGEKLSAgICAgICAgICogbmFtZXNwYWNlIHByZWZpeCB0aGF0IHdhcyB1bmRlZmluZWQuICBUaGUgdmFsdWUgb2YgdGhlIHN1YnN0aXR1dGlvbgotICAgICAgICAgKiB0ZXh0IGlzIHRoZSBuYW1lIG9mIHRoZSBwcmVmaXguCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5Lk5BTUVTUEFDRV9QUkVGSVhfRVJSLAotICAgICAgICAiTG8gc3BhemlvIGRpIG5vbWkgcGVyIGlsIHByZWZpc3NvICcnezB9Jycgbm9uIFx1MDBFOCBzdGF0byBkaWNoaWFyYXRvLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIHJlcHJlc2VudHMgYW4gaW50ZXJuYWwgZXJyb3IuCi0gICAgICAgICAqIERPTUFkYXB0ZXIgaXMgYSBKYXZhIGNsYXNzIGluIFhTTFRDLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5ET01fQURBUFRFUl9JTklUX0VSUiwKLSAgICAgICAgIkRPTUFkYXB0ZXIgY3JlYXRvIHV0aWxpenphbmRvIGlsIHRpcG8gZXJyYXRvIGRpIERPTSBkaSBvcmlnaW5lLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhlIFhNTAotICAgICAgICAgKiBwYXJzZXIgdGhhdCBpcyBwcm92aWRpbmcgaW5wdXQgdG8gWFNMVEMgY2Fubm90IGJlIHVzZWQgYmVjYXVzZSBpdAotICAgICAgICAgKiBkb2VzIG5vdCBkZXNjcmliZSB0byBYU0xUQyB0aGUgc3RydWN0dXJlIG9mIHRoZSBpbnB1dCBYTUwgZG9jdW1lbnQncwotICAgICAgICAgKiBEVEQuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LlBBUlNFUl9EVERfU1VQUE9SVF9FUlIsCi0gICAgICAgICJJbCBwYXJzZXIgU0FYIGluIHVzbyBub24gZ2VzdGlzY2UgZ2xpIGV2ZW50aSBkaSBkaWNoaWFyYXppb25lIERURC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoZSBYTUwKLSAgICAgICAgICogcGFyc2VyIHRoYXQgaXMgcHJvdmlkaW5nIGlucHV0IHRvIFhTTFRDIGNhbm5vdCBiZSB1c2VkIGJlY2F1c2UgaXQKLSAgICAgICAgICogZG9lcyBub3QgZGlzdGluZ3Vpc2ggYmV0d2VlbiBvcmRpbmFyeSBYTUwgYXR0cmlidXRlcyBhbmQgbmFtZXNwYWNlCi0gICAgICAgICAqIGRlY2xhcmF0aW9ucy4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuTkFNRVNQQUNFU19TVVBQT1JUX0VSUiwKLSAgICAgICAgIklsIHBhcnNlciBTQVggaW4gdXNvIG5vbiBzdXBwb3J0YSBnbGkgc3BhemkgZGkgbm9taSBYTUwuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgVVJJIHRoYXQgd2FzIGluCi0gICAgICAgICAqIGVycm9yLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5DQU5UX1JFU09MVkVfUkVMQVRJVkVfVVJJX0VSUiwKLSAgICAgICAgIkltcG9zc2liaWxlIHJpc29sdmVyZSBpbCByaWZlcmltZW50byBVUkkgJyd7MH0nJy4ifSwKLQotICAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IGNvbnRhaW5lZCBhbiBlbGVtZW50IHRoYXQgd2FzCi0gICAgICAgICAqIG5vdCByZWNvZ25pemVkIGFzIHBhcnQgb2YgdGhlIFhTTCBzeW50YXguICBUaGUgc3Vic3RpdHV0aW9uIHRleHQKLSAgICAgICAgICogZ2l2ZXMgdGhlIGVsZW1lbnQgbmFtZS4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuVU5TVVBQT1JURURfWFNMX0VSUiwKLSAgICAgICAgIkVsZW1lbnRvIFhTTCBcInswfVwiIG5vbiBzdXBwb3J0YXRvIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IHJlZmVycmVkIHRvIGFuIGV4dGVuc2lvbiB0byB0aGUKLSAgICAgICAgICogWFNMIHN5bnRheCBhbmQgaW5kaWNhdGVkIHRoYXQgaXQgd2FzIGRlZmluZWQgYnkgWFNMVEMsIGJ1dCBYU0xUQyBkb2VzCi0gICAgICAgICAqIG5vdCByZWNvZ25pemUgdGhlIHBhcnRpY3VsYXIgZXh0ZW5zaW9uIG5hbWVkLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgICAqIGdpdmVzIHRoZSBleHRlbnNpb24gbmFtZS4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuVU5TVVBQT1JURURfRVhUX0VSUiwKLSAgICAgICAgIkVzdGVuc2lvbmUgWFNMVEMgJyd7MH0nJyBub24gcmljb25vc2NpdXRhIn0sCi0KLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBlcnJvciBtZXNzYWdlIGlzIHByb2R1Y2VkIGlmIHRoZSB0cmFuc2xldAotICAgICAgICAgKiBjbGFzcyB3YXMgY29tcGlsZWQgdXNpbmcgYSBuZXdlciB2ZXJzaW9uIG9mIFhTTFRDIGFuZCBkZXBsb3llZCBmb3IKLSAgICAgICAgICogZXhlY3V0aW9uIHdpdGggYW4gb2xkZXIgdmVyc2lvbiBvZiBYU0xUQy4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcwotICAgICAgICAgKiB0aGUgbmFtZSBvZiB0aGUgdHJhbnNsZXQgY2xhc3MuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LlVOS05PV05fVFJBTlNMRVRfVkVSU0lPTl9FUlIsCi0gICAgICAgICJJbCB0cmFuc2xldCBzcGVjaWZpY2F0byAnJ3swfScnIFx1MDBFOCBzdGF0byBjcmVhdG8gdXRpbGl6emFuZG8gdW5hIHZlcnNpb25lIGRpIFhTTFRDIHBpXHUwMEY5IHJlY2VudGUgZGkgcXVlbGxhIGRlbGxhIGZhc2UgZGkgZXNlY3V6aW9uZSBYU0xUQyBpbiB1c28uIFJpY29tcGlsYXJlIGlsIGZvZ2xpbyBkaSBzdGlsZSBvIHV0aWxpenphcmUgdW5hIHZlcnNpb25lIHBpXHUwMEY5IHJlY2VudGUgZGkgWFNMVEMgcGVyIGVzZWd1aXJlIHF1ZXN0byB0cmFuc2xldC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQW4gYXR0cmlidXRlIHdob3NlIGVmZmVjdGl2ZSB2YWx1ZSBpcyByZXF1aXJlZAotICAgICAgICAgKiB0byBiZSBhICJRTmFtZSIgaGFkIGEgdmFsdWUgdGhhdCB3YXMgaW5jb3JyZWN0LgotICAgICAgICAgKiAnUU5hbWUnIGlzIGFuIFhNTCBzeW50YWN0aWMgdGVybSB0aGF0IG11c3Qgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGUKLSAgICAgICAgICogc3Vic3RpdHV0aW9uIHRleHQgY29udGFpbnMgdGhlIGFjdHVhbCB2YWx1ZSBvZiB0aGUgYXR0cmlidXRlLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5JTlZBTElEX1FOQU1FX0VSUiwKLSAgICAgICAgIlVuIGF0dHJpYnV0byBpbCBjdWkgdmFsb3JlIGRldmUgZXNzZXJlIHVuIFFOYW1lIGNvbnRpZW5lIGlsIHZhbG9yZSAnJ3swfScnIn0sCi0KLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQW4gYXR0cmlidXRlIHdob3NlIGVmZmVjdGl2ZSB2YWx1ZSBpcyByZXF1aXJlZAotICAgICAgICAgKiB0byBiZSBhICJOQ05hbWUiIGhhZCBhIHZhbHVlIHRoYXQgd2FzIGluY29ycmVjdC4KLSAgICAgICAgICogJ05DTmFtZScgaXMgYW4gWE1MIHN5bnRhY3RpYyB0ZXJtIHRoYXQgbXVzdCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoZQotICAgICAgICAgKiBzdWJzdGl0dXRpb24gdGV4dCBjb250YWlucyB0aGUgYWN0dWFsIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LklOVkFMSURfTkNOQU1FX0VSUiwKLSAgICAgICAgIlVuIGF0dHJpYnV0byBpbCBjdWkgdmFsb3JlIGRldmUgZXNzZXJlIHVuIE5DTmFtZSBjb250aWVuZSBpbCB2YWxvcmUgJyd7MH0nJyJ9LAotCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuVU5BTExPV0VEX0VYVEVOU0lPTl9GVU5DVElPTl9FUlIsCi0gICAgICAgICJOb24gXHUwMEU4IGNvbnNlbnRpdG8gdXRpbGl6emFyZSBsYSBmdW56aW9uZSBkaSBlc3RlbnNpb25lICcnezB9Jycgc2UgbGEgZnVuemlvbmUgZGkgZWxhYm9yYXppb25lIHNpY3VyYSBcdTAwRTggaW1wb3N0YXRhIHN1IHRydWUuIn0sCi0KLSAgICAgICAge0Jhc2lzTGlicmFyeS5VTkFMTE9XRURfRVhURU5TSU9OX0VMRU1FTlRfRVJSLAotICAgICAgICAiTm9uIFx1MDBFOCBjb25zZW50aXRvIHV0aWxpenphcmUgbCcnZWxlbWVudG8gZGkgZXN0ZW5zaW9uZSAnJ3swfScnIHNlIGxhIGZ1bnppb25lIGRpIGVsYWJvcmF6aW9uZSBzaWN1cmEgXHUwMEU4IGltcG9zdGF0YSBzdSB0cnVlLiJ9LAotICAgIH07Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvRXJyb3JNZXNzYWdlc19qYS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ydW50aW1lL0Vycm9yTWVzc2FnZXNfamEuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggM2NkMzcxMi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvRXJyb3JNZXNzYWdlc19qYS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjg0ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMucnVudGltZTsKLQotaW1wb3J0IGphdmEudXRpbC5MaXN0UmVzb3VyY2VCdW5kbGU7Ci0KLS8qKgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKi8KLXB1YmxpYyBjbGFzcyBFcnJvck1lc3NhZ2VzX2phIGV4dGVuZHMgTGlzdFJlc291cmNlQnVuZGxlIHsKLQotLyoKLSAqIFhTTFRDIHJ1bi10aW1lIGVycm9yIG1lc3NhZ2VzLgotICoKLSAqIEdlbmVyYWwgbm90ZXMgdG8gdHJhbnNsYXRvcnMgYW5kIGRlZmluaXRpb25zOgotICoKLSAqICAgMSkgWFNMVEMgaXMgdGhlIG5hbWUgb2YgdGhlIHByb2R1Y3QuICBJdCBpcyBhbiBhY3JvbnltIGZvciBYTUwgU3R5bGVzaGVldDoKLSAqICAgICAgVHJhbnNmb3JtYXRpb25zIENvbXBpbGVyCi0gKgotICogICAyKSBBIHN0eWxlc2hlZXQgaXMgYSBkZXNjcmlwdGlvbiBvZiBob3cgdG8gdHJhbnNmb3JtIGFuIGlucHV0IFhNTCBkb2N1bWVudAotICogICAgICBpbnRvIGEgcmVzdWx0YW50IG91dHB1dCBYTUwgZG9jdW1lbnQgKG9yIEhUTUwgZG9jdW1lbnQgb3IgdGV4dCkKLSAqCi0gKiAgIDMpIEFuIGF4aXMgaXMgYSBwYXJ0aWN1bGFyICJkaW1lbnNpb24iIGluIGEgdHJlZSByZXByZXNlbnRhdGlvbiBvZiBhbiBYTUwKLSAqICAgICAgZG9jdW1lbnQ7IHRoZSBub2RlcyBpbiB0aGUgdHJlZSBhcmUgZGl2aWRlZCBhbG9uZyBkaWZmZXJlbnQgYXhlcy4KLSAqICAgICAgVHJhdmVyc2luZyB0aGUgImNoaWxkIiBheGlzLCBmb3IgaW5zdGFuY2UsIG1lYW5zIHRoYXQgdGhlIHByb2dyYW0KLSAqICAgICAgd291bGQgdmlzaXQgZWFjaCBjaGlsZCBvZiBhIHBhcnRpY3VsYXIgbm9kZTsgdHJhdmVyc2luZyB0aGUgImRlc2NlbmRhbnQiCi0gKiAgICAgIGF4aXMgbWVhbnMgdGhhdCB0aGUgcHJvZ3JhbSB3b3VsZCB2aXNpdCB0aGUgY2hpbGQgbm9kZXMgb2YgYSBwYXJ0aWN1bGFyCi0gKiAgICAgIG5vZGUsIHRoZWlyIGNoaWxkcmVuLCBhbmQgc28gb24gdW50aWwgdGhlIGxlYWYgbm9kZXMgb2YgdGhlIHRyZWUgYXJlCi0gKiAgICAgIHJlYWNoZWQuCi0gKgotICogICA0KSBBbiBpdGVyYXRvciBpcyBhbiBvYmplY3QgdGhhdCB0cmF2ZXJzZXMgbm9kZXMgaW4gYSB0cmVlIGFsb25nIGEKLSAqICAgICAgcGFydGljdWxhciBheGlzLCBvbmUgYXQgYSB0aW1lLgotICoKLSAqICAgNSkgQW4gZWxlbWVudCBpcyBhIG1hcmstdXAgdGFnIGluIGFuIFhNTCBkb2N1bWVudDsgYW4gYXR0cmlidXRlIGlzIGEKLSAqICAgICAgbW9kaWZpZXIgb24gdGhlIHRhZy4gIEZvciBleGFtcGxlLCBpbiA8ZWxlbSBhdHRyPSd2YWwnIGF0dHIyPSd2YWwyJz4KLSAqICAgICAgImVsZW0iIGlzIGFuIGVsZW1lbnQgbmFtZSwgImF0dHIiIGFuZCAiYXR0cjIiIGFyZSBhdHRyaWJ1dGUgbmFtZXMgd2l0aAotICogICAgICB0aGUgdmFsdWVzICJ2YWwiIGFuZCAidmFsMiIsIHJlc3BlY3RpdmVseS4KLSAqCi0gKiAgIDYpIEEgbmFtZXNwYWNlIGRlY2xhcmF0aW9uIGlzIGEgc3BlY2lhbCBhdHRyaWJ1dGUgdGhhdCBpcyB1c2VkIHRvIGFzc29jaWF0ZQotICogICAgICBhIHByZWZpeCB3aXRoIGEgVVJJICh0aGUgbmFtZXNwYWNlKS4gIFRoZSBtZWFuaW5ncyBvZiBlbGVtZW50IG5hbWVzIGFuZAotICogICAgICBhdHRyaWJ1dGUgbmFtZXMgdGhhdCB1c2UgdGhhdCBwcmVmaXggYXJlIGRlZmluZWQgd2l0aCByZXNwZWN0IHRvIHRoYXQKLSAqICAgICAgbmFtZXNwYWNlLgotICoKLSAqICAgNykgRE9NIGlzIGFuIGFjcm9ueW0gZm9yIERvY3VtZW50IE9iamVjdCBNb2RlbC4gIEl0IGlzIGEgdHJlZQotICogICAgICByZXByZXNlbnRhdGlvbiBvZiBhbiBYTUwgZG9jdW1lbnQuCi0gKgotICogICAgICBTQVggaXMgYW4gYWNyb255bSBmb3IgdGhlIFNpbXBsZSBBUEkgZm9yIFhNTCBwcm9jZXNzaW5nLiAgSXQgaXMgYW4gQVBJCi0gKiAgICAgIHVzZWQgaW5mb3JtIGFuIFhNTCBwcm9jZXNzb3IgKGluIHRoaXMgY2FzZSBYU0xUQykgb2YgdGhlIHN0cnVjdHVyZSBhbmQKLSAqICAgICAgY29udGVudCBvZiBhbiBYTUwgZG9jdW1lbnQuCi0gKgotICogICAgICBJbnB1dCB0byB0aGUgc3R5bGVzaGVldCBwcm9jZXNzb3IgY2FuIGNvbWUgZnJvbSBhbiBYTUwgcGFyc2VyIGluIHRoZQotICogICAgICBmb3JtIG9mIGEgRE9NIHRyZWUgb3IgdGhyb3VnaCB0aGUgU0FYIEFQSS4KLSAqCi0gKiAgIDgpIERURCBpcyBhIGRvY3VtZW50IHR5cGUgZGVjbGFyYXRpb24uICBJdCBpcyBhIHdheSBvZiBzcGVjaWZ5aW5nIHRoZQotICogICAgICBncmFtbWFyIGZvciBhbiBYTUwgZmlsZSwgdGhlIG5hbWVzIGFuZCB0eXBlcyBvZiBlbGVtZW50cywgYXR0cmlidXRlcywKLSAqICAgICAgZXRjLgotICoKLSAqICAgOSkgVHJhbnNsZXQgaXMgYW4gaW52ZW50ZWQgdGVybSB0aGF0IHJlZmVycyB0byB0aGUgY2xhc3MgZmlsZSB0aGF0IGNvbnRhaW5zCi0gKiAgICAgIHRoZSBjb21waWxlZCBmb3JtIG9mIGEgc3R5bGVzaGVldC4KLSAqLwotCi0gICAgLy8gVGhlc2UgbWVzc2FnZSBzaG91bGQgYmUgcmVhZCBmcm9tIGEgbG9jYWxlLXNwZWNpZmljIHJlc291cmNlIGJ1bmRsZQotICAgIC8qKiBHZXQgdGhlIGxvb2t1cCB0YWJsZSBmb3IgZXJyb3IgbWVzc2FnZXMuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBtZXNzYWdlIGxvb2t1cCB0YWJsZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0W11bXSBnZXRDb250ZW50cygpCi0gICAgewotICAgICAgICByZXR1cm4gbmV3IE9iamVjdFtdW10gewotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICB0aGUgc3Vic3RpdHV0aW9uIHRleHQgaW4gdGhlIGZvbGxvd2luZyBtZXNzYWdlCi0gICAgICAgICAqIGlzIGEgY2xhc3MgbmFtZS4gIFVzZWQgZm9yIGludGVybmFsIGVycm9ycyBpbiB0aGUgcHJvY2Vzc29yLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5SVU5fVElNRV9JTlRFUk5BTF9FUlIsCi0gICAgICAgICInJ3swfScnXHU1MTg1XHUzMDZFXHUzMEU5XHUzMEYzXHUzMEJGXHUzMEE0XHUzMEUwXHU1MTg1XHU5MEU4XHUzMEE4XHUzMEU5XHUzMEZDXHUzMDY3XHUzMDU5In0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIDx4c2w6Y29weT4gaXMgYSBrZXl3b3JkIHRoYXQgc2hvdWxkIG5vdCBiZQotICAgICAgICAgKiB0cmFuc2xhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5SVU5fVElNRV9DT1BZX0VSUiwKLSAgICAgICAgIjx4c2w6Y29weT5cdTMwNkVcdTVCOUZcdTg4NENcdTRFMkRcdTMwNkVcdTMwRTlcdTMwRjNcdTMwQkZcdTMwQTRcdTMwRTBcdTMwRkJcdTMwQThcdTMwRTlcdTMwRkNcdTMwNjdcdTMwNTlcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHJlZmVycyB0byBkYXRhIHR5cGVzLgotICAgICAgICAgKiBUaGUgbWVzc2FnZSBpcyBkaXNwbGF5ZWQgaWYgYSB2YWx1ZSBpbiBhIHBhcnRpY3VsYXIgY29udGV4dCBuZWVkcyB0bwotICAgICAgICAgKiBiZSBjb252ZXJ0ZWQgdG8gdHlwZSB7MX0sIGJ1dCB0aGF0J3Mgbm90IHBvc3NpYmxlIGZvciBhIHZhbHVlIG9mIHR5cGUKLSAgICAgICAgICogezB9LgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5EQVRBX0NPTlZFUlNJT05fRVJSLAotICAgICAgICAiJyd7MH0nJ1x1MzA0Qlx1MzA4OScnezF9JydcdTMwNzhcdTMwNkVcdTU5MDlcdTYzREJcdTMwNENcdTcxMjFcdTUyQjlcdTMwNjdcdTMwNTlcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIGRpc3BsYXllZCBpZiB0aGUgZnVuY3Rpb24gbmFtZWQKLSAgICAgICAgICogYnkgdGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIG5vdCBhIGZ1bmN0aW9uIHRoYXQgaXMgc3VwcG9ydGVkLiAgWFNMVEMKLSAgICAgICAgICogaXMgdGhlIGFjcm9ueW0gbmFtaW5nIHRoZSBwcm9kdWN0LgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5FWFRFUk5BTF9GVU5DX0VSUiwKLSAgICAgICAgIlx1NTkxNlx1OTBFOFx1OTVBMlx1NjU3MCcnezB9JydcdTMwNkZYU0xUQ1x1MzA2Qlx1MzA4OFx1MzA2M1x1MzA2Nlx1MzBCNVx1MzBERFx1MzBGQ1x1MzBDOFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgZGlzcGxheWVkIGlmIHR3byB2YWx1ZXMgYXJlCi0gICAgICAgICAqIGNvbXBhcmVkIGZvciBlcXVhbGl0eSwgYnV0IHRoZSBkYXRhIHR5cGUgb2Ygb25lIG9mIHRoZSB2YWx1ZXMgaXMKLSAgICAgICAgICogdW5rbm93bi4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuRVFVQUxJVFlfRVhQUl9FUlIsCi0gICAgICAgICJcdTdCNDlcdTRGQTFcdTVGMEZcdTMwNkJcdTRFMERcdTY2MEVcdTMwNkFcdTVGMTVcdTY1NzBcdTMwQkZcdTMwQTRcdTMwRDdcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGZvciB7MH0gd2lsbCBiZSBhIGRhdGEKLSAgICAgICAgICogdHlwZTsgdGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGZvciB7MX0gd2lsbCBiZSB0aGUgbmFtZSBvZiBhIGZ1bmN0aW9uLgotICAgICAgICAgKiBUaGlzIGlzIGRpc3BsYXllZCBpZiBhbiBhcmd1bWVudCBvZiB0aGUgcGFydGljdWxhciBkYXRhIHR5cGUgaXMgbm90Ci0gICAgICAgICAqIHBlcm1pdHRlZCBmb3IgYSBjYWxsIHRvIHRoaXMgZnVuY3Rpb24uCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LklOVkFMSURfQVJHVU1FTlRfRVJSLAotICAgICAgICAiJyd7MX0nJ1x1MzA2RVx1NTQ3Q1x1NTFGQVx1MzA1N1x1MzA2RVx1NUYxNVx1NjU3MFx1MzBCRlx1MzBBNFx1MzBENycnezB9JydcdTMwNENcdTcxMjFcdTUyQjlcdTMwNjdcdTMwNTkifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlcmUgaXMgd2F5IG9mIHNwZWNpZnlpbmcgYSBmb3JtYXQgZm9yIGEKLSAgICAgICAgICogbnVtYmVyIHVzaW5nIGEgcGF0dGVybjsgdGhlIHByb2Nlc3NvciB3YXMgdW5hYmxlIHRvIGZvcm1hdCB0aGUKLSAgICAgICAgICogcGFydGljdWxhciB2YWx1ZSB1c2luZyB0aGUgc3BlY2lmaWVkIHBhdHRlcm4uCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LkZPUk1BVF9OVU1CRVJfRVJSLAotICAgICAgICAiXHUzMEQxXHUzMEJGXHUzMEZDXHUzMEYzJyd7MX0nJ1x1MzA5Mlx1NEY3Rlx1NzUyOFx1MzA1N1x1MzA2Nlx1NjU3MFx1NTAyNCcnezB9JydcdTMwOTJcdTMwRDVcdTMwQTlcdTMwRkNcdTMwREVcdTMwQzNcdTMwQzhcdTMwNTdcdTMwODhcdTMwNDZcdTMwNjhcdTMwNTdcdTMwN0VcdTMwNTdcdTMwNUZcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyByZXByZXNlbnRzIGFuIGludGVybmFsIGVycm9yCi0gICAgICAgICAqIHNpdHVhdGlvbiBpbiBYU0xUQy4gIFRoZSBwcm9jZXNzb3Igd2FzIHVuYWJsZSB0byBjcmVhdGUgYSBjb3B5IG9mIGFuCi0gICAgICAgICAqIGl0ZXJhdG9yLiAgKFNlZSBkZWZpbml0aW9uIG9mIGl0ZXJhdG9yIGFib3ZlLikKLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuSVRFUkFUT1JfQ0xPTkVfRVJSLAotICAgICAgICAiXHUzMEE0XHUzMEM2XHUzMEVDXHUzMEZDXHUzMEJGJyd7MH0nJ1x1MzA2RVx1MzBBRlx1MzBFRFx1MzBGQ1x1MzBGM1x1MzA5Mlx1NEY1Q1x1NjIxMFx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIHJlcHJlc2VudHMgYW4gaW50ZXJuYWwgZXJyb3IKLSAgICAgICAgICogc2l0dWF0aW9uIGluIFhTTFRDLiAgVGhlIHByb2Nlc3NvciBhdHRlbXB0ZWQgdG8gY3JlYXRlIGFuIGl0ZXJhdG9yCi0gICAgICAgICAqIGZvciBhIHBhcnRpY3VsYXIgYXhpcyAoc2VlIGRlZmluaXRpb24gYWJvdmUpIHRoYXQgaXQgZG9lcyBub3QKLSAgICAgICAgICogc3VwcG9ydC4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuQVhJU19TVVBQT1JUX0VSUiwKLSAgICAgICAgIlx1OEVGOCcnezB9JydcdTMwNkVcdTMwQTRcdTMwQzZcdTMwRUNcdTMwRkNcdTMwQkZcdTMwNkZcdTMwQjVcdTMwRERcdTMwRkNcdTMwQzhcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyByZXByZXNlbnRzIGFuIGludGVybmFsIGVycm9yCi0gICAgICAgICAqIHNpdHVhdGlvbiBpbiBYU0xUQy4gIFRoZSBwcm9jZXNzb3IgYXR0ZW1wdGVkIHRvIGNyZWF0ZSBhbiBpdGVyYXRvcgotICAgICAgICAgKiBmb3IgYSBwYXJ0aWN1bGFyIGF4aXMgKHNlZSBkZWZpbml0aW9uIGFib3ZlKSB0aGF0IGl0IGRvZXMgbm90Ci0gICAgICAgICAqIHN1cHBvcnQuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LlRZUEVEX0FYSVNfU1VQUE9SVF9FUlIsCi0gICAgICAgICJcdTU3OEJcdTYzMDdcdTVCOUFcdTMwNTVcdTMwOENcdTMwNUZcdThFRjgnJ3swfScnXHUzMDZFXHUzMEE0XHUzMEM2XHUzMEVDXHUzMEZDXHUzMEJGXHUzMDZGXHUzMEI1XHUzMEREXHUzMEZDXHUzMEM4XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyByZXBvcnRlZCBpZiB0aGUgc3R5bGVzaGVldAotICAgICAgICAgKiBiZWluZyBwcm9jZXNzZWQgYXR0ZW1wdGVkIHRvIGNvbnN0cnVjdCBhbiBYTUwgZG9jdW1lbnQgd2l0aCBhbgotICAgICAgICAgKiBhdHRyaWJ1dGUgaW4gYSBwbGFjZSBvdGhlciB0aGFuIG9uIGFuIGVsZW1lbnQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQKLSAgICAgICAgICogc3BlY2lmaWVzIHRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LlNUUkFZX0FUVFJJQlVURV9FUlIsCi0gICAgICAgICJcdTVDNUVcdTYwMjcnJ3swfScnXHUzMDRDXHU4OTgxXHU3RDIwXHUzMDZFXHU1OTE2XHU1MDc0XHUzMDZCXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFzIHdpdGggdGhlIHByZWNlZGluZyBtZXNzYWdlLCBhIG5hbWVzcGFjZQotICAgICAgICAgKiBkZWNsYXJhdGlvbiBoYXMgdGhlIGZvcm0gb2YgYW4gYXR0cmlidXRlIGFuZCBpcyBvbmx5IHBlcm1pdHRlZCB0bwotICAgICAgICAgKiBhcHBlYXIgb24gYW4gZWxlbWVudC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCB7MH0gaXMgdGhlIG5hbWVzcGFjZQotICAgICAgICAgKiBwcmVmaXggYW5kIHsxfSBpcyB0aGUgVVJJIHRoYXQgd2FzIGJlaW5nIHVzZWQgaW4gdGhlIGVycm9uZW91cwotICAgICAgICAgKiBuYW1lc3BhY2UgZGVjbGFyYXRpb24uCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LlNUUkFZX05BTUVTUEFDRV9FUlIsCi0gICAgICAgICJcdTMwQ0RcdTMwRkNcdTMwRTBcdTMwQjlcdTMwREFcdTMwRkNcdTMwQjlcdTVCQTNcdThBMDAnJ3swfScnPScnezF9JydcdTMwNENcdTg5ODFcdTdEMjBcdTMwNkVcdTU5MTZcdTUwNzRcdTMwNkJcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN0eWxlc2hlZXQgY29udGFpbmVkIGEgcmVmZXJlbmNlIHRvIGEKLSAgICAgICAgICogbmFtZXNwYWNlIHByZWZpeCB0aGF0IHdhcyB1bmRlZmluZWQuICBUaGUgdmFsdWUgb2YgdGhlIHN1YnN0aXR1dGlvbgotICAgICAgICAgKiB0ZXh0IGlzIHRoZSBuYW1lIG9mIHRoZSBwcmVmaXguCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5Lk5BTUVTUEFDRV9QUkVGSVhfRVJSLAotICAgICAgICAiXHU2M0E1XHU5ODJEXHU4RjlFJyd7MH0nJ1x1MzA2RVx1MzBDRFx1MzBGQ1x1MzBFMFx1MzBCOVx1MzBEQVx1MzBGQ1x1MzBCOVx1MzA0Q1x1NUJBM1x1OEEwMFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIHJlcHJlc2VudHMgYW4gaW50ZXJuYWwgZXJyb3IuCi0gICAgICAgICAqIERPTUFkYXB0ZXIgaXMgYSBKYXZhIGNsYXNzIGluIFhTTFRDLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5ET01fQURBUFRFUl9JTklUX0VSUiwKLSAgICAgICAgIkRPTUFkYXB0ZXJcdTMwNENcdTk1OTNcdTkwNTVcdTMwNjNcdTMwNUZcdTMwQkZcdTMwQTRcdTMwRDdcdTMwNkVcdTMwQkRcdTMwRkNcdTMwQjlET01cdTMwOTJcdTRGN0ZcdTc1MjhcdTMwNTdcdTMwNjZcdTRGNUNcdTYyMTBcdTMwNTVcdTMwOENcdTMwN0VcdTMwNTdcdTMwNUZcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoZSBYTUwKLSAgICAgICAgICogcGFyc2VyIHRoYXQgaXMgcHJvdmlkaW5nIGlucHV0IHRvIFhTTFRDIGNhbm5vdCBiZSB1c2VkIGJlY2F1c2UgaXQKLSAgICAgICAgICogZG9lcyBub3QgZGVzY3JpYmUgdG8gWFNMVEMgdGhlIHN0cnVjdHVyZSBvZiB0aGUgaW5wdXQgWE1MIGRvY3VtZW50J3MKLSAgICAgICAgICogRFRELgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5QQVJTRVJfRFREX1NVUFBPUlRfRVJSLAotICAgICAgICAiXHU0RjdGXHU3NTI4XHU0RTJEXHUzMDZFU0FYXHUzMEQxXHUzMEZDXHUzMEI1XHUzMEZDXHUzMDZGRFREXHU1QkEzXHU4QTAwXHUzMEE0XHUzMEQ5XHUzMEYzXHUzMEM4XHUzMDkyXHU1MUU2XHU3NDA2XHUzMDU3XHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUgWE1MCi0gICAgICAgICAqIHBhcnNlciB0aGF0IGlzIHByb3ZpZGluZyBpbnB1dCB0byBYU0xUQyBjYW5ub3QgYmUgdXNlZCBiZWNhdXNlIGl0Ci0gICAgICAgICAqIGRvZXMgbm90IGRpc3Rpbmd1aXNoIGJldHdlZW4gb3JkaW5hcnkgWE1MIGF0dHJpYnV0ZXMgYW5kIG5hbWVzcGFjZQotICAgICAgICAgKiBkZWNsYXJhdGlvbnMuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5Lk5BTUVTUEFDRVNfU1VQUE9SVF9FUlIsCi0gICAgICAgICJcdTRGN0ZcdTc1MjhcdTRFMkRcdTMwNkVTQVhcdTMwRDFcdTMwRkNcdTMwQjVcdTMwRkNcdTMwNkJcdTMwNkZYTUxcdTMwQ0RcdTMwRkNcdTMwRTBcdTMwQjlcdTMwREFcdTMwRkNcdTMwQjlcdTMwNkVcdTMwQjVcdTMwRERcdTMwRkNcdTMwQzhcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBVUkkgdGhhdCB3YXMgaW4KLSAgICAgICAgICogZXJyb3IuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LkNBTlRfUkVTT0xWRV9SRUxBVElWRV9VUklfRVJSLAotICAgICAgICAiVVJJXHU1M0MyXHU3MTY3Jyd7MH0nJ1x1MzA5Mlx1ODlFM1x1NkM3QVx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzA2N1x1MzA1N1x1MzA1Rlx1MzAwMiJ9LAotCi0gICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN0eWxlc2hlZXQgY29udGFpbmVkIGFuIGVsZW1lbnQgdGhhdCB3YXMKLSAgICAgICAgICogbm90IHJlY29nbml6ZWQgYXMgcGFydCBvZiB0aGUgWFNMIHN5bnRheC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICAgKiBnaXZlcyB0aGUgZWxlbWVudCBuYW1lLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5VTlNVUFBPUlRFRF9YU0xfRVJSLAotICAgICAgICAiXHUzMEI1XHUzMEREXHUzMEZDXHUzMEM4XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDZBXHUzMDQ0WFNMXHU4OTgxXHU3RDIwJyd7MH0nJyJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3R5bGVzaGVldCByZWZlcnJlZCB0byBhbiBleHRlbnNpb24gdG8gdGhlCi0gICAgICAgICAqIFhTTCBzeW50YXggYW5kIGluZGljYXRlZCB0aGF0IGl0IHdhcyBkZWZpbmVkIGJ5IFhTTFRDLCBidXQgWFNMVEMgZG9lcwotICAgICAgICAgKiBub3QgcmVjb2duaXplIHRoZSBwYXJ0aWN1bGFyIGV4dGVuc2lvbiBuYW1lZC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICAgKiBnaXZlcyB0aGUgZXh0ZW5zaW9uIG5hbWUuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LlVOU1VQUE9SVEVEX0VYVF9FUlIsCi0gICAgICAgICJcdThBOERcdThCNThcdTMwNTVcdTMwOENcdTMwNkFcdTMwNDRYU0xUQ1x1NjJFMVx1NUYzNScnezB9JycifSwKLQotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIGVycm9yIG1lc3NhZ2UgaXMgcHJvZHVjZWQgaWYgdGhlIHRyYW5zbGV0Ci0gICAgICAgICAqIGNsYXNzIHdhcyBjb21waWxlZCB1c2luZyBhIG5ld2VyIHZlcnNpb24gb2YgWFNMVEMgYW5kIGRlcGxveWVkIGZvcgotICAgICAgICAgKiBleGVjdXRpb24gd2l0aCBhbiBvbGRlciB2ZXJzaW9uIG9mIFhTTFRDLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzCi0gICAgICAgICAqIHRoZSBuYW1lIG9mIHRoZSB0cmFuc2xldCBjbGFzcy4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuVU5LTk9XTl9UUkFOU0xFVF9WRVJTSU9OX0VSUiwKLSAgICAgICAgIlx1NjMwN1x1NUI5QVx1MzA1NVx1MzA4Q1x1MzA1RnRyYW5zbGV0XHUzMDZFJyd7MH0nJ1x1MzA2Rlx1MzAwMVx1NEY3Rlx1NzUyOFx1NEUyRFx1MzA2RVhTTFRDXHUzMEU5XHUzMEYzXHUzMEJGXHUzMEE0XHUzMEUwXHUzMDZFXHUzMEQwXHUzMEZDXHUzMEI4XHUzMEU3XHUzMEYzXHUzMDg4XHUzMDhBXHUzMDgyXHU2NUIwXHUzMDU3XHUzMDQ0WFNMVENcdTMwNkVcdTMwRDBcdTMwRkNcdTMwQjhcdTMwRTdcdTMwRjNcdTMwOTJcdTRGN0ZcdTc1MjhcdTMwNTdcdTMwNjZcdTRGNUNcdTYyMTBcdTMwNTVcdTMwOENcdTMwNUZcdTMwODJcdTMwNkVcdTMwNjdcdTMwNTlcdTMwMDJcdTMwNTNcdTMwNkV0cmFuc2xldFx1MzA5Mlx1NUI5Rlx1ODg0Q1x1MzA1OVx1MzA4Qlx1MzA2Qlx1MzA2Rlx1MzAwMVx1MzBCOVx1MzBCRlx1MzBBNFx1MzBFQlx1MzBCN1x1MzBGQ1x1MzBDOFx1MzA5Mlx1NTE4RFx1MzBCM1x1MzBGM1x1MzBEMVx1MzBBNFx1MzBFQlx1MzA1OVx1MzA4Qlx1MzA0Qlx1MzAwMVx1MzA4OFx1MzA4QVx1NjVCMFx1MzA1N1x1MzA0NFx1MzBEMFx1MzBGQ1x1MzBCOFx1MzBFN1x1MzBGM1x1MzA2RVhTTFRDXHUzMDkyXHU0RjdGXHU3NTI4XHUzMDU5XHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIGF0dHJpYnV0ZSB3aG9zZSBlZmZlY3RpdmUgdmFsdWUgaXMgcmVxdWlyZWQKLSAgICAgICAgICogdG8gYmUgYSAiUU5hbWUiIGhhZCBhIHZhbHVlIHRoYXQgd2FzIGluY29ycmVjdC4KLSAgICAgICAgICogJ1FOYW1lJyBpcyBhbiBYTUwgc3ludGFjdGljIHRlcm0gdGhhdCBtdXN0IG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhlCi0gICAgICAgICAqIHN1YnN0aXR1dGlvbiB0ZXh0IGNvbnRhaW5zIHRoZSBhY3R1YWwgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuSU5WQUxJRF9RTkFNRV9FUlIsCi0gICAgICAgICJcdTUwMjRcdTMwNENRTmFtZVx1MzA2N1x1MzA0Mlx1MzA4Qlx1MzA1M1x1MzA2OFx1MzA0Q1x1NUZDNVx1ODk4MVx1MzA2QVx1NUM1RVx1NjAyN1x1MzA2RVx1NTAyNFx1MzA0QycnezB9JydcdTMwNjdcdTMwNTdcdTMwNUYifSwKLQotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBbiBhdHRyaWJ1dGUgd2hvc2UgZWZmZWN0aXZlIHZhbHVlIGlzIHJlcXVpcmVkCi0gICAgICAgICAqIHRvIGJlIGEgIk5DTmFtZSIgaGFkIGEgdmFsdWUgdGhhdCB3YXMgaW5jb3JyZWN0LgotICAgICAgICAgKiAnTkNOYW1lJyBpcyBhbiBYTUwgc3ludGFjdGljIHRlcm0gdGhhdCBtdXN0IG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhlCi0gICAgICAgICAqIHN1YnN0aXR1dGlvbiB0ZXh0IGNvbnRhaW5zIHRoZSBhY3R1YWwgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuSU5WQUxJRF9OQ05BTUVfRVJSLAotICAgICAgICAiXHU1MDI0XHUzMDRDTkNOYW1lXHUzMDY3XHUzMDQyXHUzMDhCXHUzMDUzXHUzMDY4XHUzMDRDXHU1RkM1XHU4OTgxXHUzMDZBXHU1QzVFXHU2MDI3XHUzMDZFXHU1MDI0XHUzMDRDJyd7MH0nJ1x1MzA2N1x1MzA1N1x1MzA1RiJ9LAotCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuVU5BTExPV0VEX0VYVEVOU0lPTl9GVU5DVElPTl9FUlIsCi0gICAgICAgICJcdTMwQkJcdTMwQURcdTMwRTVcdTMwQTJcdTUxRTZcdTc0MDZcdTZBNUZcdTgwRkRcdTMwNEN0cnVlXHUzMDZCXHU4QTJEXHU1QjlBXHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDhCXHUzMDY4XHUzMDREXHUzMDAxXHU2MkUxXHU1RjM1XHU5NUEyXHU2NTcwJyd7MH0nJ1x1MzA2RVx1NEY3Rlx1NzUyOFx1MzA2Rlx1OEEzMVx1NTNFRlx1MzA1NVx1MzA4Q1x1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMiJ9LAotCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuVU5BTExPV0VEX0VYVEVOU0lPTl9FTEVNRU5UX0VSUiwKLSAgICAgICAgIlx1MzBCQlx1MzBBRFx1MzBFNVx1MzBBMlx1NTFFNlx1NzQwNlx1NkE1Rlx1ODBGRFx1MzA0Q3RydWVcdTMwNkJcdThBMkRcdTVCOUFcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwOEJcdTMwNjhcdTMwNERcdTMwMDFcdTYyRTFcdTVGMzVcdTg5ODFcdTdEMjAnJ3swfScnXHUzMDZFXHU0RjdGXHU3NTI4XHUzMDZGXHU4QTMxXHU1M0VGXHUzMDU1XHUzMDhDXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyIn0sCi0gICAgfTsKLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9FcnJvck1lc3NhZ2VzX2tvLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvRXJyb3JNZXNzYWdlc19rby5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlMjRhN2MxLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9FcnJvck1lc3NhZ2VzX2tvLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyODQgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5ydW50aW1lOwotCi1pbXBvcnQgamF2YS51dGlsLkxpc3RSZXNvdXJjZUJ1bmRsZTsKLQotLyoqCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqLwotcHVibGljIGNsYXNzIEVycm9yTWVzc2FnZXNfa28gZXh0ZW5kcyBMaXN0UmVzb3VyY2VCdW5kbGUgewotCi0vKgotICogWFNMVEMgcnVuLXRpbWUgZXJyb3IgbWVzc2FnZXMuCi0gKgotICogR2VuZXJhbCBub3RlcyB0byB0cmFuc2xhdG9ycyBhbmQgZGVmaW5pdGlvbnM6Ci0gKgotICogICAxKSBYU0xUQyBpcyB0aGUgbmFtZSBvZiB0aGUgcHJvZHVjdC4gIEl0IGlzIGFuIGFjcm9ueW0gZm9yIFhNTCBTdHlsZXNoZWV0OgotICogICAgICBUcmFuc2Zvcm1hdGlvbnMgQ29tcGlsZXIKLSAqCi0gKiAgIDIpIEEgc3R5bGVzaGVldCBpcyBhIGRlc2NyaXB0aW9uIG9mIGhvdyB0byB0cmFuc2Zvcm0gYW4gaW5wdXQgWE1MIGRvY3VtZW50Ci0gKiAgICAgIGludG8gYSByZXN1bHRhbnQgb3V0cHV0IFhNTCBkb2N1bWVudCAob3IgSFRNTCBkb2N1bWVudCBvciB0ZXh0KQotICoKLSAqICAgMykgQW4gYXhpcyBpcyBhIHBhcnRpY3VsYXIgImRpbWVuc2lvbiIgaW4gYSB0cmVlIHJlcHJlc2VudGF0aW9uIG9mIGFuIFhNTAotICogICAgICBkb2N1bWVudDsgdGhlIG5vZGVzIGluIHRoZSB0cmVlIGFyZSBkaXZpZGVkIGFsb25nIGRpZmZlcmVudCBheGVzLgotICogICAgICBUcmF2ZXJzaW5nIHRoZSAiY2hpbGQiIGF4aXMsIGZvciBpbnN0YW5jZSwgbWVhbnMgdGhhdCB0aGUgcHJvZ3JhbQotICogICAgICB3b3VsZCB2aXNpdCBlYWNoIGNoaWxkIG9mIGEgcGFydGljdWxhciBub2RlOyB0cmF2ZXJzaW5nIHRoZSAiZGVzY2VuZGFudCIKLSAqICAgICAgYXhpcyBtZWFucyB0aGF0IHRoZSBwcm9ncmFtIHdvdWxkIHZpc2l0IHRoZSBjaGlsZCBub2RlcyBvZiBhIHBhcnRpY3VsYXIKLSAqICAgICAgbm9kZSwgdGhlaXIgY2hpbGRyZW4sIGFuZCBzbyBvbiB1bnRpbCB0aGUgbGVhZiBub2RlcyBvZiB0aGUgdHJlZSBhcmUKLSAqICAgICAgcmVhY2hlZC4KLSAqCi0gKiAgIDQpIEFuIGl0ZXJhdG9yIGlzIGFuIG9iamVjdCB0aGF0IHRyYXZlcnNlcyBub2RlcyBpbiBhIHRyZWUgYWxvbmcgYQotICogICAgICBwYXJ0aWN1bGFyIGF4aXMsIG9uZSBhdCBhIHRpbWUuCi0gKgotICogICA1KSBBbiBlbGVtZW50IGlzIGEgbWFyay11cCB0YWcgaW4gYW4gWE1MIGRvY3VtZW50OyBhbiBhdHRyaWJ1dGUgaXMgYQotICogICAgICBtb2RpZmllciBvbiB0aGUgdGFnLiAgRm9yIGV4YW1wbGUsIGluIDxlbGVtIGF0dHI9J3ZhbCcgYXR0cjI9J3ZhbDInPgotICogICAgICAiZWxlbSIgaXMgYW4gZWxlbWVudCBuYW1lLCAiYXR0ciIgYW5kICJhdHRyMiIgYXJlIGF0dHJpYnV0ZSBuYW1lcyB3aXRoCi0gKiAgICAgIHRoZSB2YWx1ZXMgInZhbCIgYW5kICJ2YWwyIiwgcmVzcGVjdGl2ZWx5LgotICoKLSAqICAgNikgQSBuYW1lc3BhY2UgZGVjbGFyYXRpb24gaXMgYSBzcGVjaWFsIGF0dHJpYnV0ZSB0aGF0IGlzIHVzZWQgdG8gYXNzb2NpYXRlCi0gKiAgICAgIGEgcHJlZml4IHdpdGggYSBVUkkgKHRoZSBuYW1lc3BhY2UpLiAgVGhlIG1lYW5pbmdzIG9mIGVsZW1lbnQgbmFtZXMgYW5kCi0gKiAgICAgIGF0dHJpYnV0ZSBuYW1lcyB0aGF0IHVzZSB0aGF0IHByZWZpeCBhcmUgZGVmaW5lZCB3aXRoIHJlc3BlY3QgdG8gdGhhdAotICogICAgICBuYW1lc3BhY2UuCi0gKgotICogICA3KSBET00gaXMgYW4gYWNyb255bSBmb3IgRG9jdW1lbnQgT2JqZWN0IE1vZGVsLiAgSXQgaXMgYSB0cmVlCi0gKiAgICAgIHJlcHJlc2VudGF0aW9uIG9mIGFuIFhNTCBkb2N1bWVudC4KLSAqCi0gKiAgICAgIFNBWCBpcyBhbiBhY3JvbnltIGZvciB0aGUgU2ltcGxlIEFQSSBmb3IgWE1MIHByb2Nlc3NpbmcuICBJdCBpcyBhbiBBUEkKLSAqICAgICAgdXNlZCBpbmZvcm0gYW4gWE1MIHByb2Nlc3NvciAoaW4gdGhpcyBjYXNlIFhTTFRDKSBvZiB0aGUgc3RydWN0dXJlIGFuZAotICogICAgICBjb250ZW50IG9mIGFuIFhNTCBkb2N1bWVudC4KLSAqCi0gKiAgICAgIElucHV0IHRvIHRoZSBzdHlsZXNoZWV0IHByb2Nlc3NvciBjYW4gY29tZSBmcm9tIGFuIFhNTCBwYXJzZXIgaW4gdGhlCi0gKiAgICAgIGZvcm0gb2YgYSBET00gdHJlZSBvciB0aHJvdWdoIHRoZSBTQVggQVBJLgotICoKLSAqICAgOCkgRFREIGlzIGEgZG9jdW1lbnQgdHlwZSBkZWNsYXJhdGlvbi4gIEl0IGlzIGEgd2F5IG9mIHNwZWNpZnlpbmcgdGhlCi0gKiAgICAgIGdyYW1tYXIgZm9yIGFuIFhNTCBmaWxlLCB0aGUgbmFtZXMgYW5kIHR5cGVzIG9mIGVsZW1lbnRzLCBhdHRyaWJ1dGVzLAotICogICAgICBldGMuCi0gKgotICogICA5KSBUcmFuc2xldCBpcyBhbiBpbnZlbnRlZCB0ZXJtIHRoYXQgcmVmZXJzIHRvIHRoZSBjbGFzcyBmaWxlIHRoYXQgY29udGFpbnMKLSAqICAgICAgdGhlIGNvbXBpbGVkIGZvcm0gb2YgYSBzdHlsZXNoZWV0LgotICovCi0KLSAgICAvLyBUaGVzZSBtZXNzYWdlIHNob3VsZCBiZSByZWFkIGZyb20gYSBsb2NhbGUtc3BlY2lmaWMgcmVzb3VyY2UgYnVuZGxlCi0gICAgLyoqIEdldCB0aGUgbG9va3VwIHRhYmxlIGZvciBlcnJvciBtZXNzYWdlcy4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIG1lc3NhZ2UgbG9va3VwIHRhYmxlLgotICAgICAqLwotICAgIHB1YmxpYyBPYmplY3RbXVtdIGdldENvbnRlbnRzKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBuZXcgT2JqZWN0W11bXSB7Ci0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIHRoZSBzdWJzdGl0dXRpb24gdGV4dCBpbiB0aGUgZm9sbG93aW5nIG1lc3NhZ2UKLSAgICAgICAgICogaXMgYSBjbGFzcyBuYW1lLiAgVXNlZCBmb3IgaW50ZXJuYWwgZXJyb3JzIGluIHRoZSBwcm9jZXNzb3IuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LlJVTl9USU1FX0lOVEVSTkFMX0VSUiwKLSAgICAgICAgIicnezB9JydcdUM1RDAgXHVCN0YwXHVEMEMwXHVDNzg0IFx1QjBCNFx1QkQ4MCBcdUM2MjRcdUI5NThcdUFDMDAgXHVDNzg4XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICA8eHNsOmNvcHk+IGlzIGEga2V5d29yZCB0aGF0IHNob3VsZCBub3QgYmUKLSAgICAgICAgICogdHJhbnNsYXRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuUlVOX1RJTUVfQ09QWV9FUlIsCi0gICAgICAgICI8eHNsOmNvcHk+XHVCOTdDIFx1QzJFNFx1RDU4OVx1RDU1OFx1QjI5NCBcdUM5MTEgXHVCN0YwXHVEMEMwXHVDNzg0IFx1QzYyNFx1Qjk1OFx1QUMwMCBcdUJDMUNcdUMwRERcdUQ1ODhcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCByZWZlcnMgdG8gZGF0YSB0eXBlcy4KLSAgICAgICAgICogVGhlIG1lc3NhZ2UgaXMgZGlzcGxheWVkIGlmIGEgdmFsdWUgaW4gYSBwYXJ0aWN1bGFyIGNvbnRleHQgbmVlZHMgdG8KLSAgICAgICAgICogYmUgY29udmVydGVkIHRvIHR5cGUgezF9LCBidXQgdGhhdCdzIG5vdCBwb3NzaWJsZSBmb3IgYSB2YWx1ZSBvZiB0eXBlCi0gICAgICAgICAqIHswfS4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuREFUQV9DT05WRVJTSU9OX0VSUiwKLSAgICAgICAgIicnezB9JydcdUM1RDBcdUMxMUMgJyd7MX0nJyhcdUM3M0MpXHVCODVDXHVDNzU4IFx1QkNDMFx1RDY1OFx1Qzc3NCBcdUJEODBcdUM4MDFcdUQ1NjlcdUQ1NjlcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyBkaXNwbGF5ZWQgaWYgdGhlIGZ1bmN0aW9uIG5hbWVkCi0gICAgICAgICAqIGJ5IHRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyBub3QgYSBmdW5jdGlvbiB0aGF0IGlzIHN1cHBvcnRlZC4gIFhTTFRDCi0gICAgICAgICAqIGlzIHRoZSBhY3JvbnltIG5hbWluZyB0aGUgcHJvZHVjdC4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuRVhURVJOQUxfRlVOQ19FUlIsCi0gICAgICAgICJYU0xUQ1x1QjI5NCBcdUM2NzhcdUJEODAgXHVENTY4XHVDMjE4ICcnezB9JydcdUM3NDQoXHVCOTdDKSBcdUM5QzBcdUM2RDBcdUQ1NThcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgZGlzcGxheWVkIGlmIHR3byB2YWx1ZXMgYXJlCi0gICAgICAgICAqIGNvbXBhcmVkIGZvciBlcXVhbGl0eSwgYnV0IHRoZSBkYXRhIHR5cGUgb2Ygb25lIG9mIHRoZSB2YWx1ZXMgaXMKLSAgICAgICAgICogdW5rbm93bi4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuRVFVQUxJVFlfRVhQUl9FUlIsCi0gICAgICAgICJcdUIzRDlcdUI0RjFcdUMxMzEgXHVENDVDXHVENjA0XHVDMkREXHVDNUQwIFx1QzU0QyBcdUMyMTggXHVDNUM2XHVCMjk0IFx1Qzc3OFx1QzIxOCBcdUM3MjBcdUQ2MTVcdUM3NzQgXHVDNzg4XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgZm9yIHswfSB3aWxsIGJlIGEgZGF0YQotICAgICAgICAgKiB0eXBlOyB0aGUgc3Vic3RpdHV0aW9uIHRleHQgZm9yIHsxfSB3aWxsIGJlIHRoZSBuYW1lIG9mIGEgZnVuY3Rpb24uCi0gICAgICAgICAqIFRoaXMgaXMgZGlzcGxheWVkIGlmIGFuIGFyZ3VtZW50IG9mIHRoZSBwYXJ0aWN1bGFyIGRhdGEgdHlwZSBpcyBub3QKLSAgICAgICAgICogcGVybWl0dGVkIGZvciBhIGNhbGwgdG8gdGhpcyBmdW5jdGlvbi4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuSU5WQUxJRF9BUkdVTUVOVF9FUlIsCi0gICAgICAgICInJ3sxfScnXHVDNUQwIFx1QjMwMFx1RDU1QyBcdUQ2MzhcdUNEOUNcdUM1RDAgXHVCRDgwXHVDODAxXHVENTY5XHVENTVDIFx1Qzc3OFx1QzIxOCBcdUM3MjBcdUQ2MTUgJyd7MH0nJ1x1Qzc3NChcdUFDMDApIFx1Qzc4OFx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlcmUgaXMgd2F5IG9mIHNwZWNpZnlpbmcgYSBmb3JtYXQgZm9yIGEKLSAgICAgICAgICogbnVtYmVyIHVzaW5nIGEgcGF0dGVybjsgdGhlIHByb2Nlc3NvciB3YXMgdW5hYmxlIHRvIGZvcm1hdCB0aGUKLSAgICAgICAgICogcGFydGljdWxhciB2YWx1ZSB1c2luZyB0aGUgc3BlY2lmaWVkIHBhdHRlcm4uCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LkZPUk1BVF9OVU1CRVJfRVJSLAotICAgICAgICAiJyd7MX0nJyBcdUQzMjhcdUQxMzRcdUM3NDQgXHVDMEFDXHVDNkE5XHVENTU4XHVDNUVDICcnezB9JycgXHVDMjJCXHVDNzkwXHVDNzU4IFx1RDYxNVx1QzJERFx1Qzc0NCBcdUM5QzBcdUM4MTVcdUQ1NThcdUI4MjRcdUFDRTAgXHVDMkRDXHVCM0M0XHVENTU4XHVCMjk0IFx1QzkxMVx1Qzc4NVx1QjJDOFx1QjJFNC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyByZXByZXNlbnRzIGFuIGludGVybmFsIGVycm9yCi0gICAgICAgICAqIHNpdHVhdGlvbiBpbiBYU0xUQy4gIFRoZSBwcm9jZXNzb3Igd2FzIHVuYWJsZSB0byBjcmVhdGUgYSBjb3B5IG9mIGFuCi0gICAgICAgICAqIGl0ZXJhdG9yLiAgKFNlZSBkZWZpbml0aW9uIG9mIGl0ZXJhdG9yIGFib3ZlLikKLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuSVRFUkFUT1JfQ0xPTkVfRVJSLAotICAgICAgICAiJyd7MH0nJyBcdUM3NzRcdUQxMzBcdUI4MDhcdUM3NzRcdUQxMzBcdUI5N0MgXHVCQ0Y1XHVDODFDXHVENTYwIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgcmVwcmVzZW50cyBhbiBpbnRlcm5hbCBlcnJvcgotICAgICAgICAgKiBzaXR1YXRpb24gaW4gWFNMVEMuICBUaGUgcHJvY2Vzc29yIGF0dGVtcHRlZCB0byBjcmVhdGUgYW4gaXRlcmF0b3IKLSAgICAgICAgICogZm9yIGEgcGFydGljdWxhciBheGlzIChzZWUgZGVmaW5pdGlvbiBhYm92ZSkgdGhhdCBpdCBkb2VzIG5vdAotICAgICAgICAgKiBzdXBwb3J0LgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5BWElTX1NVUFBPUlRfRVJSLAotICAgICAgICAiJyd7MH0nJyBcdUNEOTVcdUM1RDAgXHVCMzAwXHVENTVDIFx1Qzc3NFx1RDEzMFx1QjgwOFx1Qzc3NFx1RDEzMFx1QjI5NCBcdUM5QzBcdUM2RDBcdUI0MThcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIHJlcHJlc2VudHMgYW4gaW50ZXJuYWwgZXJyb3IKLSAgICAgICAgICogc2l0dWF0aW9uIGluIFhTTFRDLiAgVGhlIHByb2Nlc3NvciBhdHRlbXB0ZWQgdG8gY3JlYXRlIGFuIGl0ZXJhdG9yCi0gICAgICAgICAqIGZvciBhIHBhcnRpY3VsYXIgYXhpcyAoc2VlIGRlZmluaXRpb24gYWJvdmUpIHRoYXQgaXQgZG9lcyBub3QKLSAgICAgICAgICogc3VwcG9ydC4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuVFlQRURfQVhJU19TVVBQT1JUX0VSUiwKLSAgICAgICAgIlx1Qzc4NVx1QjgyNVx1QjQxQyBcdUNEOTUgJyd7MH0nJ1x1QzVEMCBcdUIzMDBcdUQ1NUMgXHVDNzc0XHVEMTMwXHVCODA4XHVDNzc0XHVEMTMwXHVCMjk0IFx1QzlDMFx1QzZEMFx1QjQxOFx1QzlDMCBcdUM1NEFcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyByZXBvcnRlZCBpZiB0aGUgc3R5bGVzaGVldAotICAgICAgICAgKiBiZWluZyBwcm9jZXNzZWQgYXR0ZW1wdGVkIHRvIGNvbnN0cnVjdCBhbiBYTUwgZG9jdW1lbnQgd2l0aCBhbgotICAgICAgICAgKiBhdHRyaWJ1dGUgaW4gYSBwbGFjZSBvdGhlciB0aGFuIG9uIGFuIGVsZW1lbnQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQKLSAgICAgICAgICogc3BlY2lmaWVzIHRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LlNUUkFZX0FUVFJJQlVURV9FUlIsCi0gICAgICAgICInJ3swfScnIFx1QzE4RFx1QzEzMVx1Qzc3NCBcdUM2OTRcdUMxOENcdUM1RDAgXHVEM0VDXHVENTY4XHVCNDE4XHVDNUI0IFx1Qzc4OFx1QzlDMCBcdUM1NEFcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFzIHdpdGggdGhlIHByZWNlZGluZyBtZXNzYWdlLCBhIG5hbWVzcGFjZQotICAgICAgICAgKiBkZWNsYXJhdGlvbiBoYXMgdGhlIGZvcm0gb2YgYW4gYXR0cmlidXRlIGFuZCBpcyBvbmx5IHBlcm1pdHRlZCB0bwotICAgICAgICAgKiBhcHBlYXIgb24gYW4gZWxlbWVudC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCB7MH0gaXMgdGhlIG5hbWVzcGFjZQotICAgICAgICAgKiBwcmVmaXggYW5kIHsxfSBpcyB0aGUgVVJJIHRoYXQgd2FzIGJlaW5nIHVzZWQgaW4gdGhlIGVycm9uZW91cwotICAgICAgICAgKiBuYW1lc3BhY2UgZGVjbGFyYXRpb24uCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LlNUUkFZX05BTUVTUEFDRV9FUlIsCi0gICAgICAgICJcdUIxMjRcdUM3ODRcdUMyQTRcdUQzOThcdUM3NzRcdUMyQTQgXHVDMTIwXHVDNUI4ICcnezB9Jyc9Jyd7MX0nJ1x1Qzc3NChcdUFDMDApIFx1QzY5NFx1QzE4Q1x1QzVEMCBcdUQzRUNcdUQ1NjhcdUI0MThcdUM1QjQgXHVDNzg4XHVDOUMwIFx1QzU0QVx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN0eWxlc2hlZXQgY29udGFpbmVkIGEgcmVmZXJlbmNlIHRvIGEKLSAgICAgICAgICogbmFtZXNwYWNlIHByZWZpeCB0aGF0IHdhcyB1bmRlZmluZWQuICBUaGUgdmFsdWUgb2YgdGhlIHN1YnN0aXR1dGlvbgotICAgICAgICAgKiB0ZXh0IGlzIHRoZSBuYW1lIG9mIHRoZSBwcmVmaXguCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5Lk5BTUVTUEFDRV9QUkVGSVhfRVJSLAotICAgICAgICAiJyd7MH0nJyBcdUM4MTFcdUI0NTBcdUM1QjRcdUM1RDAgXHVCMzAwXHVENTVDIFx1QjEyNFx1Qzc4NFx1QzJBNFx1RDM5OFx1Qzc3NFx1QzJBNFx1QUMwMCBcdUMxMjBcdUM1QjhcdUI0MThcdUM5QzAgXHVDNTRBXHVDNTU4XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIHJlcHJlc2VudHMgYW4gaW50ZXJuYWwgZXJyb3IuCi0gICAgICAgICAqIERPTUFkYXB0ZXIgaXMgYSBKYXZhIGNsYXNzIGluIFhTTFRDLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5ET01fQURBUFRFUl9JTklUX0VSUiwKLSAgICAgICAgIlx1QzE4Q1x1QzJBNCBET01cdUM3NTggXHVDNzk4XHVCQUJCXHVCNDFDIFx1QzcyMFx1RDYxNVx1Qzc0NCBcdUMwQUNcdUM2QTlcdUQ1NThcdUM1RUMgRE9NQWRhcHRlclx1QUMwMCBcdUMwRERcdUMxMzFcdUI0MThcdUM1QzhcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUgWE1MCi0gICAgICAgICAqIHBhcnNlciB0aGF0IGlzIHByb3ZpZGluZyBpbnB1dCB0byBYU0xUQyBjYW5ub3QgYmUgdXNlZCBiZWNhdXNlIGl0Ci0gICAgICAgICAqIGRvZXMgbm90IGRlc2NyaWJlIHRvIFhTTFRDIHRoZSBzdHJ1Y3R1cmUgb2YgdGhlIGlucHV0IFhNTCBkb2N1bWVudCdzCi0gICAgICAgICAqIERURC4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuUEFSU0VSX0RURF9TVVBQT1JUX0VSUiwKLSAgICAgICAgIlx1QzBBQ1x1QzZBOSBcdUM5MTFcdUM3NzggU0FYIFx1QUQ2Q1x1QkIzOCBcdUJEODRcdUMxMURcdUFFMzBcdUFDMDAgRFREIFx1QzEyMFx1QzVCOCBcdUM3NzRcdUJDQTRcdUQyQjhcdUI5N0MgXHVDQzk4XHVCOUFDXHVENTU4XHVDOUMwIFx1QzU0QVx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoZSBYTUwKLSAgICAgICAgICogcGFyc2VyIHRoYXQgaXMgcHJvdmlkaW5nIGlucHV0IHRvIFhTTFRDIGNhbm5vdCBiZSB1c2VkIGJlY2F1c2UgaXQKLSAgICAgICAgICogZG9lcyBub3QgZGlzdGluZ3Vpc2ggYmV0d2VlbiBvcmRpbmFyeSBYTUwgYXR0cmlidXRlcyBhbmQgbmFtZXNwYWNlCi0gICAgICAgICAqIGRlY2xhcmF0aW9ucy4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuTkFNRVNQQUNFU19TVVBQT1JUX0VSUiwKLSAgICAgICAgIlx1QzBBQ1x1QzZBOSBcdUM5MTFcdUM3NzggU0FYIFx1QUQ2Q1x1QkIzOCBcdUJEODRcdUMxMURcdUFFMzBcdUFDMDAgWE1MIFx1QjEyNFx1Qzc4NFx1QzJBNFx1RDM5OFx1Qzc3NFx1QzJBNFx1Qjk3QyBcdUM5QzBcdUM2RDBcdUQ1NThcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIFVSSSB0aGF0IHdhcyBpbgotICAgICAgICAgKiBlcnJvci4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuQ0FOVF9SRVNPTFZFX1JFTEFUSVZFX1VSSV9FUlIsCi0gICAgICAgICJVUkkgXHVDQzM4XHVDODcwICcnezB9JydcdUM3NDQoXHVCOTdDKSBcdUJEODRcdUMxMURcdUQ1NjAgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IGNvbnRhaW5lZCBhbiBlbGVtZW50IHRoYXQgd2FzCi0gICAgICAgICAqIG5vdCByZWNvZ25pemVkIGFzIHBhcnQgb2YgdGhlIFhTTCBzeW50YXguICBUaGUgc3Vic3RpdHV0aW9uIHRleHQKLSAgICAgICAgICogZ2l2ZXMgdGhlIGVsZW1lbnQgbmFtZS4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuVU5TVVBQT1JURURfWFNMX0VSUiwKLSAgICAgICAgIicnezB9JydcdUM3NDAoXHVCMjk0KSBcdUM5QzBcdUM2RDBcdUI0MThcdUM5QzAgXHVDNTRBXHVCMjk0IFhTTCBcdUM2OTRcdUMxOENcdUM3ODVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IHJlZmVycmVkIHRvIGFuIGV4dGVuc2lvbiB0byB0aGUKLSAgICAgICAgICogWFNMIHN5bnRheCBhbmQgaW5kaWNhdGVkIHRoYXQgaXQgd2FzIGRlZmluZWQgYnkgWFNMVEMsIGJ1dCBYU0xUQyBkb2VzCi0gICAgICAgICAqIG5vdCByZWNvZ25pemUgdGhlIHBhcnRpY3VsYXIgZXh0ZW5zaW9uIG5hbWVkLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgICAqIGdpdmVzIHRoZSBleHRlbnNpb24gbmFtZS4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuVU5TVVBQT1JURURfRVhUX0VSUiwKLSAgICAgICAgIicnezB9JydcdUM3NDAoXHVCMjk0KSBcdUM1NEMgXHVDMjE4IFx1QzVDNlx1QjI5NCBYU0xUQyBcdUQ2NTVcdUM3QTVcdUM3ODVcdUIyQzhcdUIyRTQuIn0sCi0KLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBlcnJvciBtZXNzYWdlIGlzIHByb2R1Y2VkIGlmIHRoZSB0cmFuc2xldAotICAgICAgICAgKiBjbGFzcyB3YXMgY29tcGlsZWQgdXNpbmcgYSBuZXdlciB2ZXJzaW9uIG9mIFhTTFRDIGFuZCBkZXBsb3llZCBmb3IKLSAgICAgICAgICogZXhlY3V0aW9uIHdpdGggYW4gb2xkZXIgdmVyc2lvbiBvZiBYU0xUQy4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcwotICAgICAgICAgKiB0aGUgbmFtZSBvZiB0aGUgdHJhbnNsZXQgY2xhc3MuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LlVOS05PV05fVFJBTlNMRVRfVkVSU0lPTl9FUlIsCi0gICAgICAgICJcdUM5QzBcdUM4MTVcdUI0MUMgdHJhbnNsZXQgJyd7MH0nJ1x1Qzc3NChcdUFDMDApIFx1QzBBQ1x1QzZBOSBcdUM5MTFcdUM3NzggWFNMVEMgXHVCN0YwXHVEMEMwXHVDNzg0IFx1QkM4NFx1QzgwNFx1QkNGNFx1QjJFNCBcdUNENUNcdUMyRTBcdUM3NTggWFNMVEMgXHVCQzg0XHVDODA0XHVDNzQ0IFx1QzBBQ1x1QzZBOVx1RDU1OFx1QzVFQyBcdUMwRERcdUMxMzFcdUI0MThcdUM1QzhcdUMyQjVcdUIyQzhcdUIyRTQuIFx1Qzc3NCB0cmFuc2xldFx1Qzc0NCBcdUMyRTRcdUQ1ODlcdUQ1NThcdUI4MjRcdUJBNzQgXHVDMkE0XHVEMEMwXHVDNzdDXHVDMkRDXHVEMkI4XHVCOTdDIFx1QzdBQ1x1Q0VGNFx1RDMwQ1x1Qzc3Q1x1RDU1OFx1QUM3MFx1QjA5OCBcdUNENUNcdUMyRTAgWFNMVEMgXHVCQzg0XHVDODA0XHVDNzQ0IFx1QzBBQ1x1QzZBOVx1RDU3NFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIGF0dHJpYnV0ZSB3aG9zZSBlZmZlY3RpdmUgdmFsdWUgaXMgcmVxdWlyZWQKLSAgICAgICAgICogdG8gYmUgYSAiUU5hbWUiIGhhZCBhIHZhbHVlIHRoYXQgd2FzIGluY29ycmVjdC4KLSAgICAgICAgICogJ1FOYW1lJyBpcyBhbiBYTUwgc3ludGFjdGljIHRlcm0gdGhhdCBtdXN0IG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhlCi0gICAgICAgICAqIHN1YnN0aXR1dGlvbiB0ZXh0IGNvbnRhaW5zIHRoZSBhY3R1YWwgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuSU5WQUxJRF9RTkFNRV9FUlIsCi0gICAgICAgICJcdUFDMTJcdUM3NzQgUU5hbWVcdUM3NzRcdUM1QjRcdUM1N0MgXHVENTU4XHVCMjk0IFx1QzE4RFx1QzEzMVx1Qzc1OCBcdUFDMTJcdUM3NzQgJyd7MH0nJ1x1Qzc4NVx1QjJDOFx1QjJFNC4ifSwKLQotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBbiBhdHRyaWJ1dGUgd2hvc2UgZWZmZWN0aXZlIHZhbHVlIGlzIHJlcXVpcmVkCi0gICAgICAgICAqIHRvIGJlIGEgIk5DTmFtZSIgaGFkIGEgdmFsdWUgdGhhdCB3YXMgaW5jb3JyZWN0LgotICAgICAgICAgKiAnTkNOYW1lJyBpcyBhbiBYTUwgc3ludGFjdGljIHRlcm0gdGhhdCBtdXN0IG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhlCi0gICAgICAgICAqIHN1YnN0aXR1dGlvbiB0ZXh0IGNvbnRhaW5zIHRoZSBhY3R1YWwgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuSU5WQUxJRF9OQ05BTUVfRVJSLAotICAgICAgICAiXHVBQzEyXHVDNzc0IE5DTmFtZVx1Qzc3NFx1QzVCNFx1QzU3QyBcdUQ1NThcdUIyOTQgXHVDMThEXHVDMTMxXHVDNzU4IFx1QUMxMlx1Qzc3NCAnJ3swfScnXHVDNzg1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuVU5BTExPV0VEX0VYVEVOU0lPTl9GVU5DVElPTl9FUlIsCi0gICAgICAgICJcdUJDRjRcdUM1NDggXHVDQzk4XHVCOUFDIFx1QUUzMFx1QjJBNVx1Qzc3NCB0cnVlXHVCODVDIFx1QzEyNFx1QzgxNVx1QjQxQyBcdUFDQkRcdUM2QjAgXHVENjU1XHVDN0E1IFx1RDU2OFx1QzIxOCAnJ3swfScnXHVDNzQ0KFx1Qjk3QykgXHVDMEFDXHVDNkE5XHVENTYwIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICAgICAge0Jhc2lzTGlicmFyeS5VTkFMTE9XRURfRVhURU5TSU9OX0VMRU1FTlRfRVJSLAotICAgICAgICAiXHVCQ0Y0XHVDNTQ4IFx1Q0M5OFx1QjlBQyBcdUFFMzBcdUIyQTVcdUM3NzQgdHJ1ZVx1Qjg1QyBcdUMxMjRcdUM4MTVcdUI0MUMgXHVBQ0JEXHVDNkIwIFx1RDY1NVx1QzdBNSBcdUM2OTRcdUMxOEMgJyd7MH0nJ1x1Qzc0NChcdUI5N0MpIFx1QzBBQ1x1QzZBOVx1RDU2MCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotICAgIH07Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvRXJyb3JNZXNzYWdlc19wdF9CUi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ydW50aW1lL0Vycm9yTWVzc2FnZXNfcHRfQlIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNDVlMjY1NC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvRXJyb3JNZXNzYWdlc19wdF9CUi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjg0ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMucnVudGltZTsKLQotaW1wb3J0IGphdmEudXRpbC5MaXN0UmVzb3VyY2VCdW5kbGU7Ci0KLS8qKgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKi8KLXB1YmxpYyBjbGFzcyBFcnJvck1lc3NhZ2VzX3B0X0JSIGV4dGVuZHMgTGlzdFJlc291cmNlQnVuZGxlIHsKLQotLyoKLSAqIFhTTFRDIHJ1bi10aW1lIGVycm9yIG1lc3NhZ2VzLgotICoKLSAqIEdlbmVyYWwgbm90ZXMgdG8gdHJhbnNsYXRvcnMgYW5kIGRlZmluaXRpb25zOgotICoKLSAqICAgMSkgWFNMVEMgaXMgdGhlIG5hbWUgb2YgdGhlIHByb2R1Y3QuICBJdCBpcyBhbiBhY3JvbnltIGZvciBYTUwgU3R5bGVzaGVldDoKLSAqICAgICAgVHJhbnNmb3JtYXRpb25zIENvbXBpbGVyCi0gKgotICogICAyKSBBIHN0eWxlc2hlZXQgaXMgYSBkZXNjcmlwdGlvbiBvZiBob3cgdG8gdHJhbnNmb3JtIGFuIGlucHV0IFhNTCBkb2N1bWVudAotICogICAgICBpbnRvIGEgcmVzdWx0YW50IG91dHB1dCBYTUwgZG9jdW1lbnQgKG9yIEhUTUwgZG9jdW1lbnQgb3IgdGV4dCkKLSAqCi0gKiAgIDMpIEFuIGF4aXMgaXMgYSBwYXJ0aWN1bGFyICJkaW1lbnNpb24iIGluIGEgdHJlZSByZXByZXNlbnRhdGlvbiBvZiBhbiBYTUwKLSAqICAgICAgZG9jdW1lbnQ7IHRoZSBub2RlcyBpbiB0aGUgdHJlZSBhcmUgZGl2aWRlZCBhbG9uZyBkaWZmZXJlbnQgYXhlcy4KLSAqICAgICAgVHJhdmVyc2luZyB0aGUgImNoaWxkIiBheGlzLCBmb3IgaW5zdGFuY2UsIG1lYW5zIHRoYXQgdGhlIHByb2dyYW0KLSAqICAgICAgd291bGQgdmlzaXQgZWFjaCBjaGlsZCBvZiBhIHBhcnRpY3VsYXIgbm9kZTsgdHJhdmVyc2luZyB0aGUgImRlc2NlbmRhbnQiCi0gKiAgICAgIGF4aXMgbWVhbnMgdGhhdCB0aGUgcHJvZ3JhbSB3b3VsZCB2aXNpdCB0aGUgY2hpbGQgbm9kZXMgb2YgYSBwYXJ0aWN1bGFyCi0gKiAgICAgIG5vZGUsIHRoZWlyIGNoaWxkcmVuLCBhbmQgc28gb24gdW50aWwgdGhlIGxlYWYgbm9kZXMgb2YgdGhlIHRyZWUgYXJlCi0gKiAgICAgIHJlYWNoZWQuCi0gKgotICogICA0KSBBbiBpdGVyYXRvciBpcyBhbiBvYmplY3QgdGhhdCB0cmF2ZXJzZXMgbm9kZXMgaW4gYSB0cmVlIGFsb25nIGEKLSAqICAgICAgcGFydGljdWxhciBheGlzLCBvbmUgYXQgYSB0aW1lLgotICoKLSAqICAgNSkgQW4gZWxlbWVudCBpcyBhIG1hcmstdXAgdGFnIGluIGFuIFhNTCBkb2N1bWVudDsgYW4gYXR0cmlidXRlIGlzIGEKLSAqICAgICAgbW9kaWZpZXIgb24gdGhlIHRhZy4gIEZvciBleGFtcGxlLCBpbiA8ZWxlbSBhdHRyPSd2YWwnIGF0dHIyPSd2YWwyJz4KLSAqICAgICAgImVsZW0iIGlzIGFuIGVsZW1lbnQgbmFtZSwgImF0dHIiIGFuZCAiYXR0cjIiIGFyZSBhdHRyaWJ1dGUgbmFtZXMgd2l0aAotICogICAgICB0aGUgdmFsdWVzICJ2YWwiIGFuZCAidmFsMiIsIHJlc3BlY3RpdmVseS4KLSAqCi0gKiAgIDYpIEEgbmFtZXNwYWNlIGRlY2xhcmF0aW9uIGlzIGEgc3BlY2lhbCBhdHRyaWJ1dGUgdGhhdCBpcyB1c2VkIHRvIGFzc29jaWF0ZQotICogICAgICBhIHByZWZpeCB3aXRoIGEgVVJJICh0aGUgbmFtZXNwYWNlKS4gIFRoZSBtZWFuaW5ncyBvZiBlbGVtZW50IG5hbWVzIGFuZAotICogICAgICBhdHRyaWJ1dGUgbmFtZXMgdGhhdCB1c2UgdGhhdCBwcmVmaXggYXJlIGRlZmluZWQgd2l0aCByZXNwZWN0IHRvIHRoYXQKLSAqICAgICAgbmFtZXNwYWNlLgotICoKLSAqICAgNykgRE9NIGlzIGFuIGFjcm9ueW0gZm9yIERvY3VtZW50IE9iamVjdCBNb2RlbC4gIEl0IGlzIGEgdHJlZQotICogICAgICByZXByZXNlbnRhdGlvbiBvZiBhbiBYTUwgZG9jdW1lbnQuCi0gKgotICogICAgICBTQVggaXMgYW4gYWNyb255bSBmb3IgdGhlIFNpbXBsZSBBUEkgZm9yIFhNTCBwcm9jZXNzaW5nLiAgSXQgaXMgYW4gQVBJCi0gKiAgICAgIHVzZWQgaW5mb3JtIGFuIFhNTCBwcm9jZXNzb3IgKGluIHRoaXMgY2FzZSBYU0xUQykgb2YgdGhlIHN0cnVjdHVyZSBhbmQKLSAqICAgICAgY29udGVudCBvZiBhbiBYTUwgZG9jdW1lbnQuCi0gKgotICogICAgICBJbnB1dCB0byB0aGUgc3R5bGVzaGVldCBwcm9jZXNzb3IgY2FuIGNvbWUgZnJvbSBhbiBYTUwgcGFyc2VyIGluIHRoZQotICogICAgICBmb3JtIG9mIGEgRE9NIHRyZWUgb3IgdGhyb3VnaCB0aGUgU0FYIEFQSS4KLSAqCi0gKiAgIDgpIERURCBpcyBhIGRvY3VtZW50IHR5cGUgZGVjbGFyYXRpb24uICBJdCBpcyBhIHdheSBvZiBzcGVjaWZ5aW5nIHRoZQotICogICAgICBncmFtbWFyIGZvciBhbiBYTUwgZmlsZSwgdGhlIG5hbWVzIGFuZCB0eXBlcyBvZiBlbGVtZW50cywgYXR0cmlidXRlcywKLSAqICAgICAgZXRjLgotICoKLSAqICAgOSkgVHJhbnNsZXQgaXMgYW4gaW52ZW50ZWQgdGVybSB0aGF0IHJlZmVycyB0byB0aGUgY2xhc3MgZmlsZSB0aGF0IGNvbnRhaW5zCi0gKiAgICAgIHRoZSBjb21waWxlZCBmb3JtIG9mIGEgc3R5bGVzaGVldC4KLSAqLwotCi0gICAgLy8gVGhlc2UgbWVzc2FnZSBzaG91bGQgYmUgcmVhZCBmcm9tIGEgbG9jYWxlLXNwZWNpZmljIHJlc291cmNlIGJ1bmRsZQotICAgIC8qKiBHZXQgdGhlIGxvb2t1cCB0YWJsZSBmb3IgZXJyb3IgbWVzc2FnZXMuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBtZXNzYWdlIGxvb2t1cCB0YWJsZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0W11bXSBnZXRDb250ZW50cygpCi0gICAgewotICAgICAgICByZXR1cm4gbmV3IE9iamVjdFtdW10gewotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICB0aGUgc3Vic3RpdHV0aW9uIHRleHQgaW4gdGhlIGZvbGxvd2luZyBtZXNzYWdlCi0gICAgICAgICAqIGlzIGEgY2xhc3MgbmFtZS4gIFVzZWQgZm9yIGludGVybmFsIGVycm9ycyBpbiB0aGUgcHJvY2Vzc29yLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5SVU5fVElNRV9JTlRFUk5BTF9FUlIsCi0gICAgICAgICJFcnJvIGludGVybm8gZGUgcnVudGltZSBlbSAnJ3swfScnIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIDx4c2w6Y29weT4gaXMgYSBrZXl3b3JkIHRoYXQgc2hvdWxkIG5vdCBiZQotICAgICAgICAgKiB0cmFuc2xhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5SVU5fVElNRV9DT1BZX0VSUiwKLSAgICAgICAgIkVycm8gZGUgcnVudGltZSBhbyBleGVjdXRhciA8eHNsOmNvcHk+LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgcmVmZXJzIHRvIGRhdGEgdHlwZXMuCi0gICAgICAgICAqIFRoZSBtZXNzYWdlIGlzIGRpc3BsYXllZCBpZiBhIHZhbHVlIGluIGEgcGFydGljdWxhciBjb250ZXh0IG5lZWRzIHRvCi0gICAgICAgICAqIGJlIGNvbnZlcnRlZCB0byB0eXBlIHsxfSwgYnV0IHRoYXQncyBub3QgcG9zc2libGUgZm9yIGEgdmFsdWUgb2YgdHlwZQotICAgICAgICAgKiB7MH0uCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LkRBVEFfQ09OVkVSU0lPTl9FUlIsCi0gICAgICAgICJDb252ZXJzXHUwMEUzbyBpbnZcdTAwRTFsaWRhIGRlICcnezB9JycgcGFyYSAnJ3sxfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgZGlzcGxheWVkIGlmIHRoZSBmdW5jdGlvbiBuYW1lZAotICAgICAgICAgKiBieSB0aGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgbm90IGEgZnVuY3Rpb24gdGhhdCBpcyBzdXBwb3J0ZWQuICBYU0xUQwotICAgICAgICAgKiBpcyB0aGUgYWNyb255bSBuYW1pbmcgdGhlIHByb2R1Y3QuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LkVYVEVSTkFMX0ZVTkNfRVJSLAotICAgICAgICAiRnVuXHUwMEU3XHUwMEUzbyBleHRlcm5hICcnezB9Jycgblx1MDBFM28gc3Vwb3J0YWRhIHBvciBYU0xUQy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIGRpc3BsYXllZCBpZiB0d28gdmFsdWVzIGFyZQotICAgICAgICAgKiBjb21wYXJlZCBmb3IgZXF1YWxpdHksIGJ1dCB0aGUgZGF0YSB0eXBlIG9mIG9uZSBvZiB0aGUgdmFsdWVzIGlzCi0gICAgICAgICAqIHVua25vd24uCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LkVRVUFMSVRZX0VYUFJfRVJSLAotICAgICAgICAiVGlwbyBkZSBhcmd1bWVudG8gZGVzY29uaGVjaWRvIG5hIGV4cHJlc3NcdTAwRTNvIGRlIGlndWFsZGFkZS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGZvciB7MH0gd2lsbCBiZSBhIGRhdGEKLSAgICAgICAgICogdHlwZTsgdGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGZvciB7MX0gd2lsbCBiZSB0aGUgbmFtZSBvZiBhIGZ1bmN0aW9uLgotICAgICAgICAgKiBUaGlzIGlzIGRpc3BsYXllZCBpZiBhbiBhcmd1bWVudCBvZiB0aGUgcGFydGljdWxhciBkYXRhIHR5cGUgaXMgbm90Ci0gICAgICAgICAqIHBlcm1pdHRlZCBmb3IgYSBjYWxsIHRvIHRoaXMgZnVuY3Rpb24uCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LklOVkFMSURfQVJHVU1FTlRfRVJSLAotICAgICAgICAiVGlwbyBkZSBhcmd1bWVudG8gaW52XHUwMEUxbGlkbyAnJ3swfScnIG5hIGNoYW1hZGEgcGFyYSAnJ3sxfScnIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZXJlIGlzIHdheSBvZiBzcGVjaWZ5aW5nIGEgZm9ybWF0IGZvciBhCi0gICAgICAgICAqIG51bWJlciB1c2luZyBhIHBhdHRlcm47IHRoZSBwcm9jZXNzb3Igd2FzIHVuYWJsZSB0byBmb3JtYXQgdGhlCi0gICAgICAgICAqIHBhcnRpY3VsYXIgdmFsdWUgdXNpbmcgdGhlIHNwZWNpZmllZCBwYXR0ZXJuLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5GT1JNQVRfTlVNQkVSX0VSUiwKLSAgICAgICAgIlRlbnRhdGl2YSBkZSBmb3JtYXRhciBvIG5cdTAwRkFtZXJvICcnezB9JycgdXNhbmRvIG8gcGFkclx1MDBFM28gJyd7MX0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyByZXByZXNlbnRzIGFuIGludGVybmFsIGVycm9yCi0gICAgICAgICAqIHNpdHVhdGlvbiBpbiBYU0xUQy4gIFRoZSBwcm9jZXNzb3Igd2FzIHVuYWJsZSB0byBjcmVhdGUgYSBjb3B5IG9mIGFuCi0gICAgICAgICAqIGl0ZXJhdG9yLiAgKFNlZSBkZWZpbml0aW9uIG9mIGl0ZXJhdG9yIGFib3ZlLikKLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuSVRFUkFUT1JfQ0xPTkVfRVJSLAotICAgICAgICAiTlx1MDBFM28gXHUwMEU5IHBvc3NcdTAwRUR2ZWwgY2xvbmFyIG8gaXRlcmFkb3IgJyd7MH0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyByZXByZXNlbnRzIGFuIGludGVybmFsIGVycm9yCi0gICAgICAgICAqIHNpdHVhdGlvbiBpbiBYU0xUQy4gIFRoZSBwcm9jZXNzb3IgYXR0ZW1wdGVkIHRvIGNyZWF0ZSBhbiBpdGVyYXRvcgotICAgICAgICAgKiBmb3IgYSBwYXJ0aWN1bGFyIGF4aXMgKHNlZSBkZWZpbml0aW9uIGFib3ZlKSB0aGF0IGl0IGRvZXMgbm90Ci0gICAgICAgICAqIHN1cHBvcnQuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LkFYSVNfU1VQUE9SVF9FUlIsCi0gICAgICAgICJJdGVyYWRvciBkbyBlaXhvICcnezB9Jycgblx1MDBFM28gc3Vwb3J0YWRvLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIHJlcHJlc2VudHMgYW4gaW50ZXJuYWwgZXJyb3IKLSAgICAgICAgICogc2l0dWF0aW9uIGluIFhTTFRDLiAgVGhlIHByb2Nlc3NvciBhdHRlbXB0ZWQgdG8gY3JlYXRlIGFuIGl0ZXJhdG9yCi0gICAgICAgICAqIGZvciBhIHBhcnRpY3VsYXIgYXhpcyAoc2VlIGRlZmluaXRpb24gYWJvdmUpIHRoYXQgaXQgZG9lcyBub3QKLSAgICAgICAgICogc3VwcG9ydC4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuVFlQRURfQVhJU19TVVBQT1JUX0VSUiwKLSAgICAgICAgIkl0ZXJhZG9yIGRvIGVpeG8gZGlnaXRhZG8gJyd7MH0nJyBuXHUwMEUzbyBzdXBvcnRhZG8uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyByZXBvcnRlZCBpZiB0aGUgc3R5bGVzaGVldAotICAgICAgICAgKiBiZWluZyBwcm9jZXNzZWQgYXR0ZW1wdGVkIHRvIGNvbnN0cnVjdCBhbiBYTUwgZG9jdW1lbnQgd2l0aCBhbgotICAgICAgICAgKiBhdHRyaWJ1dGUgaW4gYSBwbGFjZSBvdGhlciB0aGFuIG9uIGFuIGVsZW1lbnQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQKLSAgICAgICAgICogc3BlY2lmaWVzIHRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LlNUUkFZX0FUVFJJQlVURV9FUlIsCi0gICAgICAgICJBdHJpYnV0byAnJ3swfScnIGZvcmEgZG8gZWxlbWVudG8uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFzIHdpdGggdGhlIHByZWNlZGluZyBtZXNzYWdlLCBhIG5hbWVzcGFjZQotICAgICAgICAgKiBkZWNsYXJhdGlvbiBoYXMgdGhlIGZvcm0gb2YgYW4gYXR0cmlidXRlIGFuZCBpcyBvbmx5IHBlcm1pdHRlZCB0bwotICAgICAgICAgKiBhcHBlYXIgb24gYW4gZWxlbWVudC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCB7MH0gaXMgdGhlIG5hbWVzcGFjZQotICAgICAgICAgKiBwcmVmaXggYW5kIHsxfSBpcyB0aGUgVVJJIHRoYXQgd2FzIGJlaW5nIHVzZWQgaW4gdGhlIGVycm9uZW91cwotICAgICAgICAgKiBuYW1lc3BhY2UgZGVjbGFyYXRpb24uCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LlNUUkFZX05BTUVTUEFDRV9FUlIsCi0gICAgICAgICJEZWNsYXJhXHUwMEU3XHUwMEUzbyBkZSBuYW1lc3BhY2UgJyd7MH0nJz0nJ3sxfScnIGZvcmEgZG8gZWxlbWVudG8uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IGNvbnRhaW5lZCBhIHJlZmVyZW5jZSB0byBhCi0gICAgICAgICAqIG5hbWVzcGFjZSBwcmVmaXggdGhhdCB3YXMgdW5kZWZpbmVkLiAgVGhlIHZhbHVlIG9mIHRoZSBzdWJzdGl0dXRpb24KLSAgICAgICAgICogdGV4dCBpcyB0aGUgbmFtZSBvZiB0aGUgcHJlZml4LgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5OQU1FU1BBQ0VfUFJFRklYX0VSUiwKLSAgICAgICAgIk8gbmFtZXNwYWNlIGRvIHByZWZpeG8gJyd7MH0nJyBuXHUwMEUzbyBmb2kgZGVjbGFyYWRvLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIHJlcHJlc2VudHMgYW4gaW50ZXJuYWwgZXJyb3IuCi0gICAgICAgICAqIERPTUFkYXB0ZXIgaXMgYSBKYXZhIGNsYXNzIGluIFhTTFRDLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5ET01fQURBUFRFUl9JTklUX0VSUiwKLSAgICAgICAgIkRPTUFkYXB0ZXIgY3JpYWRvIHVzYW5kbyBvIHRpcG8gaW5jb3JyZXRvIGRlIERPTSBkZSBvcmlnZW0uIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUgWE1MCi0gICAgICAgICAqIHBhcnNlciB0aGF0IGlzIHByb3ZpZGluZyBpbnB1dCB0byBYU0xUQyBjYW5ub3QgYmUgdXNlZCBiZWNhdXNlIGl0Ci0gICAgICAgICAqIGRvZXMgbm90IGRlc2NyaWJlIHRvIFhTTFRDIHRoZSBzdHJ1Y3R1cmUgb2YgdGhlIGlucHV0IFhNTCBkb2N1bWVudCdzCi0gICAgICAgICAqIERURC4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuUEFSU0VSX0RURF9TVVBQT1JUX0VSUiwKLSAgICAgICAgIk8gcGFyc2VyIFNBWCBxdWUgdm9jXHUwMEVBIGVzdFx1MDBFMSB1c2FuZG8gblx1MDBFM28gdHJhdGEgZXZlbnRvcyBkZSBkZWNsYXJhXHUwMEU3XHUwMEUzbyBkZSBEVEQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUgWE1MCi0gICAgICAgICAqIHBhcnNlciB0aGF0IGlzIHByb3ZpZGluZyBpbnB1dCB0byBYU0xUQyBjYW5ub3QgYmUgdXNlZCBiZWNhdXNlIGl0Ci0gICAgICAgICAqIGRvZXMgbm90IGRpc3Rpbmd1aXNoIGJldHdlZW4gb3JkaW5hcnkgWE1MIGF0dHJpYnV0ZXMgYW5kIG5hbWVzcGFjZQotICAgICAgICAgKiBkZWNsYXJhdGlvbnMuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5Lk5BTUVTUEFDRVNfU1VQUE9SVF9FUlIsCi0gICAgICAgICJPIHBhcnNlciBTQVggcXVlIHZvY1x1MDBFQSBlc3RcdTAwRTEgdXNhbmRvIG5cdTAwRTNvIHRlbSBzdXBvcnRlIHBhcmEgb3MgTmFtZXNwYWNlcyBkZSBYTUwuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgVVJJIHRoYXQgd2FzIGluCi0gICAgICAgICAqIGVycm9yLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5DQU5UX1JFU09MVkVfUkVMQVRJVkVfVVJJX0VSUiwKLSAgICAgICAgIk5cdTAwRTNvIGZvaSBwb3NzXHUwMEVEdmVsIHJlc29sdmVyIGEgcmVmZXJcdTAwRUFuY2lhIGRvIFVSSSAnJ3swfScnLiJ9LAotCi0gICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN0eWxlc2hlZXQgY29udGFpbmVkIGFuIGVsZW1lbnQgdGhhdCB3YXMKLSAgICAgICAgICogbm90IHJlY29nbml6ZWQgYXMgcGFydCBvZiB0aGUgWFNMIHN5bnRheC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICAgKiBnaXZlcyB0aGUgZWxlbWVudCBuYW1lLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5VTlNVUFBPUlRFRF9YU0xfRVJSLAotICAgICAgICAiRWxlbWVudG8gWFNMICcnezB9Jycgblx1MDBFM28gc3Vwb3J0YWRvIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IHJlZmVycmVkIHRvIGFuIGV4dGVuc2lvbiB0byB0aGUKLSAgICAgICAgICogWFNMIHN5bnRheCBhbmQgaW5kaWNhdGVkIHRoYXQgaXQgd2FzIGRlZmluZWQgYnkgWFNMVEMsIGJ1dCBYU0xUQyBkb2VzCi0gICAgICAgICAqIG5vdCByZWNvZ25pemUgdGhlIHBhcnRpY3VsYXIgZXh0ZW5zaW9uIG5hbWVkLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgICAqIGdpdmVzIHRoZSBleHRlbnNpb24gbmFtZS4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuVU5TVVBQT1JURURfRVhUX0VSUiwKLSAgICAgICAgIkV4dGVuc1x1MDBFM28gJyd7MH0nJyBkZSBYU0xUQyBuXHUwMEUzbyByZWNvbmhlY2lkYSJ9LAotCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgZXJyb3IgbWVzc2FnZSBpcyBwcm9kdWNlZCBpZiB0aGUgdHJhbnNsZXQKLSAgICAgICAgICogY2xhc3Mgd2FzIGNvbXBpbGVkIHVzaW5nIGEgbmV3ZXIgdmVyc2lvbiBvZiBYU0xUQyBhbmQgZGVwbG95ZWQgZm9yCi0gICAgICAgICAqIGV4ZWN1dGlvbiB3aXRoIGFuIG9sZGVyIHZlcnNpb24gb2YgWFNMVEMuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMKLSAgICAgICAgICogdGhlIG5hbWUgb2YgdGhlIHRyYW5zbGV0IGNsYXNzLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5VTktOT1dOX1RSQU5TTEVUX1ZFUlNJT05fRVJSLAotICAgICAgICAiTyB0cmFuc2xldCBlc3BlY2lmaWNhZG8sICcnezB9JycsIGZvaSBjcmlhZG8gdXNhbmRvIHVtYSB2ZXJzXHUwMEUzbyBkbyBYU0xUQyBtYWlzIHJlY2VudGUgcXVlIGEgdmVyc1x1MDBFM28gZGUgcnVudGltZSBkZSBYU0xUQyBlbSB1c28uIFJlY29tcGlsZSBhIGZvbGhhIGRlIGVzdGlsb3Mgb3UgdXNlIHVtYSB2ZXJzXHUwMEUzbyBtYWlzIHJlY2VudGUgZGUgWFNMVEMgcGFyYSBleGVjdXRhciBlc3RlIHRyYW5zbGV0LiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBbiBhdHRyaWJ1dGUgd2hvc2UgZWZmZWN0aXZlIHZhbHVlIGlzIHJlcXVpcmVkCi0gICAgICAgICAqIHRvIGJlIGEgIlFOYW1lIiBoYWQgYSB2YWx1ZSB0aGF0IHdhcyBpbmNvcnJlY3QuCi0gICAgICAgICAqICdRTmFtZScgaXMgYW4gWE1MIHN5bnRhY3RpYyB0ZXJtIHRoYXQgbXVzdCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoZQotICAgICAgICAgKiBzdWJzdGl0dXRpb24gdGV4dCBjb250YWlucyB0aGUgYWN0dWFsIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LklOVkFMSURfUU5BTUVfRVJSLAotICAgICAgICAiVW0gYXRyaWJ1dG8gY3VqbyB2YWxvciBkZXZlIHNlciB1bSBRTmFtZSB0aW5oYSBvIHZhbG9yICcnezB9JycifSwKLQotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBbiBhdHRyaWJ1dGUgd2hvc2UgZWZmZWN0aXZlIHZhbHVlIGlzIHJlcXVpcmVkCi0gICAgICAgICAqIHRvIGJlIGEgIk5DTmFtZSIgaGFkIGEgdmFsdWUgdGhhdCB3YXMgaW5jb3JyZWN0LgotICAgICAgICAgKiAnTkNOYW1lJyBpcyBhbiBYTUwgc3ludGFjdGljIHRlcm0gdGhhdCBtdXN0IG5vdCBiZSB0cmFuc2xhdGVkLiAgVGhlCi0gICAgICAgICAqIHN1YnN0aXR1dGlvbiB0ZXh0IGNvbnRhaW5zIHRoZSBhY3R1YWwgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuSU5WQUxJRF9OQ05BTUVfRVJSLAotICAgICAgICAiVW0gYXRyaWJ1dG8gY3VqbyB2YWxvciBkZXZlIHNlciB1bSBOQ05hbWUgdGluaGEgbyB2YWxvciAnJ3swfScnIn0sCi0KLSAgICAgICAge0Jhc2lzTGlicmFyeS5VTkFMTE9XRURfRVhURU5TSU9OX0ZVTkNUSU9OX0VSUiwKLSAgICAgICAgIk8gdXNvIGRhIGZ1blx1MDBFN1x1MDBFM28gZGEgZXh0ZW5zXHUwMEUzbyAnJ3swfScnIG5cdTAwRTNvIHNlclx1MDBFMSBwZXJtaXRpZG8gcXVhbmRvIG8gcmVjdXJzbyBkZSBwcm9jZXNzYW1lbnRvIHNlZ3VybyBmb3IgZGVmaW5pZG8gY29tbyB2ZXJkYWRlaXJvLiJ9LAotCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuVU5BTExPV0VEX0VYVEVOU0lPTl9FTEVNRU5UX0VSUiwKLSAgICAgICAgIk8gdXNvIGRvIGVsZW1lbnRvIGRhIGV4dGVuc1x1MDBFM28gJyd7MH0nJyBuXHUwMEUzbyBzZXJcdTAwRTEgcGVybWl0aWRvIHF1YW5kbyBvIHJlY3Vyc28gZGUgcHJvY2Vzc2FtZW50byBzZWd1cm8gZm9yIGRlZmluaWRvIGNvbW8gdmVyZGFkZWlyby4ifSwKLSAgICB9OwotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ydW50aW1lL0Vycm9yTWVzc2FnZXNfc2suamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9FcnJvck1lc3NhZ2VzX3NrLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDZlZTU4YjcuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ydW50aW1lL0Vycm9yTWVzc2FnZXNfc2suamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIzNCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBFcnJvck1lc3NhZ2VzX3NrLmphdmEsdiAxLjEuNi4xIDIwMDUvMDkvMDYgMTA6NDU6MzkgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnJ1bnRpbWU7Ci0KLWltcG9ydCBqYXZhLnV0aWwuTGlzdFJlc291cmNlQnVuZGxlOwotCi0vKioKLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICovCi1wdWJsaWMgY2xhc3MgRXJyb3JNZXNzYWdlc19zayBleHRlbmRzIExpc3RSZXNvdXJjZUJ1bmRsZSB7Ci0KLS8qCi0gKiBYU0xUQyBydW4tdGltZSBlcnJvciBtZXNzYWdlcy4KLSAqCi0gKiBHZW5lcmFsIG5vdGVzIHRvIHRyYW5zbGF0b3JzIGFuZCBkZWZpbml0aW9uczoKLSAqCi0gKiAgIDEpIFhTTFRDIGlzIHRoZSBuYW1lIG9mIHRoZSBwcm9kdWN0LiAgSXQgaXMgYW4gYWNyb255bSBmb3IgWE1MIFN0eWxlc2hlZXQ6Ci0gKiAgICAgIFRyYW5zZm9ybWF0aW9ucyBDb21waWxlcgotICoKLSAqICAgMikgQSBzdHlsZXNoZWV0IGlzIGEgZGVzY3JpcHRpb24gb2YgaG93IHRvIHRyYW5zZm9ybSBhbiBpbnB1dCBYTUwgZG9jdW1lbnQKLSAqICAgICAgaW50byBhIHJlc3VsdGFudCBvdXRwdXQgWE1MIGRvY3VtZW50IChvciBIVE1MIGRvY3VtZW50IG9yIHRleHQpCi0gKgotICogICAzKSBBbiBheGlzIGlzIGEgcGFydGljdWxhciAiZGltZW5zaW9uIiBpbiBhIHRyZWUgcmVwcmVzZW50YXRpb24gb2YgYW4gWE1MCi0gKiAgICAgIGRvY3VtZW50OyB0aGUgbm9kZXMgaW4gdGhlIHRyZWUgYXJlIGRpdmlkZWQgYWxvbmcgZGlmZmVyZW50IGF4ZXMuCi0gKiAgICAgIFRyYXZlcnNpbmcgdGhlICJjaGlsZCIgYXhpcywgZm9yIGluc3RhbmNlLCBtZWFucyB0aGF0IHRoZSBwcm9ncmFtCi0gKiAgICAgIHdvdWxkIHZpc2l0IGVhY2ggY2hpbGQgb2YgYSBwYXJ0aWN1bGFyIG5vZGU7IHRyYXZlcnNpbmcgdGhlICJkZXNjZW5kYW50IgotICogICAgICBheGlzIG1lYW5zIHRoYXQgdGhlIHByb2dyYW0gd291bGQgdmlzaXQgdGhlIGNoaWxkIG5vZGVzIG9mIGEgcGFydGljdWxhcgotICogICAgICBub2RlLCB0aGVpciBjaGlsZHJlbiwgYW5kIHNvIG9uIHVudGlsIHRoZSBsZWFmIG5vZGVzIG9mIHRoZSB0cmVlIGFyZQotICogICAgICByZWFjaGVkLgotICoKLSAqICAgNCkgQW4gaXRlcmF0b3IgaXMgYW4gb2JqZWN0IHRoYXQgdHJhdmVyc2VzIG5vZGVzIGluIGEgdHJlZSBhbG9uZyBhCi0gKiAgICAgIHBhcnRpY3VsYXIgYXhpcywgb25lIGF0IGEgdGltZS4KLSAqCi0gKiAgIDUpIEFuIGVsZW1lbnQgaXMgYSBtYXJrLXVwIHRhZyBpbiBhbiBYTUwgZG9jdW1lbnQ7IGFuIGF0dHJpYnV0ZSBpcyBhCi0gKiAgICAgIG1vZGlmaWVyIG9uIHRoZSB0YWcuICBGb3IgZXhhbXBsZSwgaW4gPGVsZW0gYXR0cj0ndmFsJyBhdHRyMj0ndmFsMic+Ci0gKiAgICAgICJlbGVtIiBpcyBhbiBlbGVtZW50IG5hbWUsICJhdHRyIiBhbmQgImF0dHIyIiBhcmUgYXR0cmlidXRlIG5hbWVzIHdpdGgKLSAqICAgICAgdGhlIHZhbHVlcyAidmFsIiBhbmQgInZhbDIiLCByZXNwZWN0aXZlbHkuCi0gKgotICogICA2KSBBIG5hbWVzcGFjZSBkZWNsYXJhdGlvbiBpcyBhIHNwZWNpYWwgYXR0cmlidXRlIHRoYXQgaXMgdXNlZCB0byBhc3NvY2lhdGUKLSAqICAgICAgYSBwcmVmaXggd2l0aCBhIFVSSSAodGhlIG5hbWVzcGFjZSkuICBUaGUgbWVhbmluZ3Mgb2YgZWxlbWVudCBuYW1lcyBhbmQKLSAqICAgICAgYXR0cmlidXRlIG5hbWVzIHRoYXQgdXNlIHRoYXQgcHJlZml4IGFyZSBkZWZpbmVkIHdpdGggcmVzcGVjdCB0byB0aGF0Ci0gKiAgICAgIG5hbWVzcGFjZS4KLSAqCi0gKiAgIDcpIERPTSBpcyBhbiBhY3JvbnltIGZvciBEb2N1bWVudCBPYmplY3QgTW9kZWwuICBJdCBpcyBhIHRyZWUKLSAqICAgICAgcmVwcmVzZW50YXRpb24gb2YgYW4gWE1MIGRvY3VtZW50LgotICoKLSAqICAgICAgU0FYIGlzIGFuIGFjcm9ueW0gZm9yIHRoZSBTaW1wbGUgQVBJIGZvciBYTUwgcHJvY2Vzc2luZy4gIEl0IGlzIGFuIEFQSQotICogICAgICB1c2VkIGluZm9ybSBhbiBYTUwgcHJvY2Vzc29yIChpbiB0aGlzIGNhc2UgWFNMVEMpIG9mIHRoZSBzdHJ1Y3R1cmUgYW5kCi0gKiAgICAgIGNvbnRlbnQgb2YgYW4gWE1MIGRvY3VtZW50LgotICoKLSAqICAgICAgSW5wdXQgdG8gdGhlIHN0eWxlc2hlZXQgcHJvY2Vzc29yIGNhbiBjb21lIGZyb20gYW4gWE1MIHBhcnNlciBpbiB0aGUKLSAqICAgICAgZm9ybSBvZiBhIERPTSB0cmVlIG9yIHRocm91Z2ggdGhlIFNBWCBBUEkuCi0gKgotICogICA4KSBEVEQgaXMgYSBkb2N1bWVudCB0eXBlIGRlY2xhcmF0aW9uLiAgSXQgaXMgYSB3YXkgb2Ygc3BlY2lmeWluZyB0aGUKLSAqICAgICAgZ3JhbW1hciBmb3IgYW4gWE1MIGZpbGUsIHRoZSBuYW1lcyBhbmQgdHlwZXMgb2YgZWxlbWVudHMsIGF0dHJpYnV0ZXMsCi0gKiAgICAgIGV0Yy4KLSAqCi0gKi8KLQotICAgIC8vIFRoZXNlIG1lc3NhZ2Ugc2hvdWxkIGJlIHJlYWQgZnJvbSBhIGxvY2FsZS1zcGVjaWZpYyByZXNvdXJjZSBidW5kbGUKLSAgICAvKiogR2V0IHRoZSBsb29rdXAgdGFibGUgZm9yIGVycm9yIG1lc3NhZ2VzLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgbWVzc2FnZSBsb29rdXAgdGFibGUuCi0gICAgICovCi0gICAgcHVibGljIE9iamVjdFtdW10gZ2V0Q29udGVudHMoKQotICAgIHsKLSAgICAgICAgcmV0dXJuIG5ldyBPYmplY3RbXVtdIHsKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgdGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGluIHRoZSBmb2xsb3dpbmcgbWVzc2FnZQotICAgICAgICAgKiBpcyBhIGNsYXNzIG5hbWUuICBVc2VkIGZvciBpbnRlcm5hbCBlcnJvcnMgaW4gdGhlIHByb2Nlc3Nvci4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuUlVOX1RJTUVfSU5URVJOQUxfRVJSLAotICAgICAgICAiSW50ZXJuXHUwMGUxIGNoeWJhIFx1MDEwZGFzdSBzcHVzdGVuaWEgdiAnJ3swfScnIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIDx4c2w6Y29weT4gaXMgYSBrZXl3b3JkIHRoYXQgc2hvdWxkIG5vdCBiZQotICAgICAgICAgKiB0cmFuc2xhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5SVU5fVElNRV9DT1BZX0VSUiwKLSAgICAgICAgIkNoeWJhIFx1MDEwZGFzdSBzcHVzdGVuaWEgcHJpIHNwXHUwMGZhXHUwMTYxXHUwMTY1YW5cdTAwZWQgPHhzbDpjb3B5Pi4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHJlZmVycyB0byBkYXRhIHR5cGVzLgotICAgICAgICAgKiBUaGUgbWVzc2FnZSBpcyBkaXNwbGF5ZWQgaWYgYSB2YWx1ZSBpbiBhIHBhcnRpY3VsYXIgY29udGV4dCBuZWVkcyB0bwotICAgICAgICAgKiBiZSBjb252ZXJ0ZWQgdG8gdHlwZSB7MX0sIGJ1dCB0aGF0J3Mgbm90IHBvc3NpYmxlIGZvciBhIHZhbHVlIG9mIHR5cGUKLSAgICAgICAgICogezB9LgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5EQVRBX0NPTlZFUlNJT05fRVJSLAotICAgICAgICAiTmVwbGF0blx1MDBlMSBrb252ZXJ6aWEgeiAnJ3swfScnIG5hICcnezF9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyBkaXNwbGF5ZWQgaWYgdGhlIGZ1bmN0aW9uIG5hbWVkCi0gICAgICAgICAqIGJ5IHRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyBub3QgYSBmdW5jdGlvbiB0aGF0IGlzIHN1cHBvcnRlZC4gIFhTTFRDCi0gICAgICAgICAqIGlzIHRoZSBhY3JvbnltIG5hbWluZyB0aGUgcHJvZHVjdC4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuRVhURVJOQUxfRlVOQ19FUlIsCi0gICAgICAgICJYU0xUQyBuZXBvZHBvcnVqZSBleHRlcm5cdTAwZmEgZnVua2NpdSAnJ3swfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgZGlzcGxheWVkIGlmIHR3byB2YWx1ZXMgYXJlCi0gICAgICAgICAqIGNvbXBhcmVkIGZvciBlcXVhbGl0eSwgYnV0IHRoZSBkYXRhIHR5cGUgb2Ygb25lIG9mIHRoZSB2YWx1ZXMgaXMKLSAgICAgICAgICogdW5rbm93bi4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuRVFVQUxJVFlfRVhQUl9FUlIsCi0gICAgICAgICJOZXpuXHUwMGUxbXkgdHlwIGFyZ3VtZW50dSBqZSB2XHUwMGZkcmF6b20gcm92bm9zdGkuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBmb3IgezB9IHdpbGwgYmUgYSBkYXRhCi0gICAgICAgICAqIHR5cGU7IHRoZSBzdWJzdGl0dXRpb24gdGV4dCBmb3IgezF9IHdpbGwgYmUgdGhlIG5hbWUgb2YgYSBmdW5jdGlvbi4KLSAgICAgICAgICogVGhpcyBpcyBkaXNwbGF5ZWQgaWYgYW4gYXJndW1lbnQgb2YgdGhlIHBhcnRpY3VsYXIgZGF0YSB0eXBlIGlzIG5vdAotICAgICAgICAgKiBwZXJtaXR0ZWQgZm9yIGEgY2FsbCB0byB0aGlzIGZ1bmN0aW9uLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5JTlZBTElEX0FSR1VNRU5UX0VSUiwKLSAgICAgICAgIk5lcGxhdG5cdTAwZmQgdHlwIGFyZ3VtZW50dSAnJ3swfScnIHZvIHZvbGFuXHUwMGVkIGRvICcnezF9JycifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlcmUgaXMgd2F5IG9mIHNwZWNpZnlpbmcgYSBmb3JtYXQgZm9yIGEKLSAgICAgICAgICogbnVtYmVyIHVzaW5nIGEgcGF0dGVybjsgdGhlIHByb2Nlc3NvciB3YXMgdW5hYmxlIHRvIGZvcm1hdCB0aGUKLSAgICAgICAgICogcGFydGljdWxhciB2YWx1ZSB1c2luZyB0aGUgc3BlY2lmaWVkIHBhdHRlcm4uCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LkZPUk1BVF9OVU1CRVJfRVJSLAotICAgICAgICAiUG9rdXMgbyBmb3JtXHUwMGUxdG92YW5pZSBcdTAxMGRcdTAwZWRzbGEgJyd7MH0nJyBwb21vY291IHZ6b3J1ICcnezF9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgcmVwcmVzZW50cyBhbiBpbnRlcm5hbCBlcnJvcgotICAgICAgICAgKiBzaXR1YXRpb24gaW4gWFNMVEMuICBUaGUgcHJvY2Vzc29yIHdhcyB1bmFibGUgdG8gY3JlYXRlIGEgY29weSBvZiBhbgotICAgICAgICAgKiBpdGVyYXRvci4gIChTZWUgZGVmaW5pdGlvbiBvZiBpdGVyYXRvciBhYm92ZS4pCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LklURVJBVE9SX0NMT05FX0VSUiwKLSAgICAgICAgIk5pZSBqZSBtb1x1MDE3ZW5cdTAwZTkga2xvbm92YVx1MDE2NSBpdGVyXHUwMGUxdG9yICcnezB9JycuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgcmVwcmVzZW50cyBhbiBpbnRlcm5hbCBlcnJvcgotICAgICAgICAgKiBzaXR1YXRpb24gaW4gWFNMVEMuICBUaGUgcHJvY2Vzc29yIGF0dGVtcHRlZCB0byBjcmVhdGUgYW4gaXRlcmF0b3IKLSAgICAgICAgICogZm9yIGEgcGFydGljdWxhciBheGlzIChzZWUgZGVmaW5pdGlvbiBhYm92ZSkgdGhhdCBpdCBkb2VzIG5vdAotICAgICAgICAgKiBzdXBwb3J0LgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5BWElTX1NVUFBPUlRfRVJSLAotICAgICAgICAiSXRlclx1MDBlMXRvciBwcmUgb3MgJyd7MH0nJyBuaWUgamUgcG9kcG9yb3Zhblx1MDBmZC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyByZXByZXNlbnRzIGFuIGludGVybmFsIGVycm9yCi0gICAgICAgICAqIHNpdHVhdGlvbiBpbiBYU0xUQy4gIFRoZSBwcm9jZXNzb3IgYXR0ZW1wdGVkIHRvIGNyZWF0ZSBhbiBpdGVyYXRvcgotICAgICAgICAgKiBmb3IgYSBwYXJ0aWN1bGFyIGF4aXMgKHNlZSBkZWZpbml0aW9uIGFib3ZlKSB0aGF0IGl0IGRvZXMgbm90Ci0gICAgICAgICAqIHN1cHBvcnQuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LlRZUEVEX0FYSVNfU1VQUE9SVF9FUlIsCi0gICAgICAgICJJdGVyXHUwMGUxdG9yIHByZSBuYXBcdTAwZWRzYW5cdTAwZmEgb3MgJyd7MH0nJyBuaWUgamUgcG9kcG9yb3Zhblx1MDBmZC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIHJlcG9ydGVkIGlmIHRoZSBzdHlsZXNoZWV0Ci0gICAgICAgICAqIGJlaW5nIHByb2Nlc3NlZCBhdHRlbXB0ZWQgdG8gY29uc3RydWN0IGFuIFhNTCBkb2N1bWVudCB3aXRoIGFuCi0gICAgICAgICAqIGF0dHJpYnV0ZSBpbiBhIHBsYWNlIG90aGVyIHRoYW4gb24gYW4gZWxlbWVudC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICAgKiBzcGVjaWZpZXMgdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuU1RSQVlfQVRUUklCVVRFX0VSUiwKLSAgICAgICAgIkF0cmliXHUwMGZhdCAnJ3swfScnIGplIG1pbW8gZWxlbWVudHUuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFzIHdpdGggdGhlIHByZWNlZGluZyBtZXNzYWdlLCBhIG5hbWVzcGFjZQotICAgICAgICAgKiBkZWNsYXJhdGlvbiBoYXMgdGhlIGZvcm0gb2YgYW4gYXR0cmlidXRlIGFuZCBpcyBvbmx5IHBlcm1pdHRlZCB0bwotICAgICAgICAgKiBhcHBlYXIgb24gYW4gZWxlbWVudC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCB7MH0gaXMgdGhlIG5hbWVzcGFjZQotICAgICAgICAgKiBwcmVmaXggYW5kIHsxfSBpcyB0aGUgVVJJIHRoYXQgd2FzIGJlaW5nIHVzZWQgaW4gdGhlIGVycm9uZW91cwotICAgICAgICAgKiBuYW1lc3BhY2UgZGVjbGFyYXRpb24uCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LlNUUkFZX05BTUVTUEFDRV9FUlIsCi0gICAgICAgICJEZWtsYXJcdTAwZTFjaWEgblx1MDBlMXp2b3ZcdTAwZTlobyBwcmllc3RvcnUgJyd7MH0nJz0nJ3sxfScnIGplIG1pbW8gZWxlbWVudHUuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IGNvbnRhaW5lZCBhIHJlZmVyZW5jZSB0byBhCi0gICAgICAgICAqIG5hbWVzcGFjZSBwcmVmaXggdGhhdCB3YXMgdW5kZWZpbmVkLiAgVGhlIHZhbHVlIG9mIHRoZSBzdWJzdGl0dXRpb24KLSAgICAgICAgICogdGV4dCBpcyB0aGUgbmFtZSBvZiB0aGUgcHJlZml4LgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5OQU1FU1BBQ0VfUFJFRklYX0VSUiwKLSAgICAgICAgIk5cdTAwZTF6dm92XHUwMGZkIHByaWVzdG9yIHByZSBwcmVkcG9udSAnJ3swfScnIG5lYm9sIGRla2xhcm92YW5cdTAwZmQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgcmVwcmVzZW50cyBhbiBpbnRlcm5hbCBlcnJvci4KLSAgICAgICAgICogRE9NQWRhcHRlciBpcyBhIEphdmEgY2xhc3MgaW4gWFNMVEMuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LkRPTV9BREFQVEVSX0lOSVRfRVJSLAotICAgICAgICAiRE9NQWRhcHRlciBib2wgdnl0dm9yZW5cdTAwZmQgcG9tb2NvdSBuZXNwclx1MDBlMXZuZWhvIHR5cHUgemRyb2pvdlx1MDBlOWhvIERPTS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoZSBYTUwKLSAgICAgICAgICogcGFyc2VyIHRoYXQgaXMgcHJvdmlkaW5nIGlucHV0IHRvIFhTTFRDIGNhbm5vdCBiZSB1c2VkIGJlY2F1c2UgaXQKLSAgICAgICAgICogZG9lcyBub3QgZGVzY3JpYmUgdG8gWFNMVEMgdGhlIHN0cnVjdHVyZSBvZiB0aGUgaW5wdXQgWE1MIGRvY3VtZW50J3MKLSAgICAgICAgICogRFRELgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5QQVJTRVJfRFREX1NVUFBPUlRfRVJSLAotICAgICAgICAiQW5hbHl6XHUwMGUxdG9yIFNBWCwga3Rvclx1MDBmZCBwb3VcdTAxN2VcdTAwZWR2YXRlLCBuZXNwcmFjXHUwMGZhdmEgdWRhbG9zdGkgZGVrbGFyXHUwMGUxY2llIERURC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoZSBYTUwKLSAgICAgICAgICogcGFyc2VyIHRoYXQgaXMgcHJvdmlkaW5nIGlucHV0IHRvIFhTTFRDIGNhbm5vdCBiZSB1c2VkIGJlY2F1c2UgaXQKLSAgICAgICAgICogZG9lcyBub3QgZGlzdGluZ3Vpc2ggYmV0d2VlbiBvcmRpbmFyeSBYTUwgYXR0cmlidXRlcyBhbmQgbmFtZXNwYWNlCi0gICAgICAgICAqIGRlY2xhcmF0aW9ucy4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuTkFNRVNQQUNFU19TVVBQT1JUX0VSUiwKLSAgICAgICAgIkFuYWx5elx1MDBlMXRvciBTQVgsIGt0b3JcdTAwZmQgcG91XHUwMTdlXHUwMGVkdmF0ZSwgbmVtXHUwMGUxIHBvZHBvcnUgcHJlIG5cdTAwZTF6dm92XHUwMGU5IHByaWVzdG9yeSBYTUwuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgVVJJIHRoYXQgd2FzIGluCi0gICAgICAgICAqIGVycm9yLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5DQU5UX1JFU09MVkVfUkVMQVRJVkVfVVJJX0VSUiwKLSAgICAgICAgIk5lYm9sbyBtb1x1MDE3ZW5cdTAwZTkgcm96bFx1MDBlZFx1MDE2MWlcdTAxNjUgcmVmZXJlbmNpdSBVUkkgJyd7MH0nJy4ifQotICAgIH07Ci0KLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9FcnJvck1lc3NhZ2VzX3N2LmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvRXJyb3JNZXNzYWdlc19zdi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyYzJiNDBlLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9FcnJvck1lc3NhZ2VzX3N2LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyODQgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5ydW50aW1lOwotCi1pbXBvcnQgamF2YS51dGlsLkxpc3RSZXNvdXJjZUJ1bmRsZTsKLQotLyoqCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqLwotcHVibGljIGNsYXNzIEVycm9yTWVzc2FnZXNfc3YgZXh0ZW5kcyBMaXN0UmVzb3VyY2VCdW5kbGUgewotCi0vKgotICogWFNMVEMgcnVuLXRpbWUgZXJyb3IgbWVzc2FnZXMuCi0gKgotICogR2VuZXJhbCBub3RlcyB0byB0cmFuc2xhdG9ycyBhbmQgZGVmaW5pdGlvbnM6Ci0gKgotICogICAxKSBYU0xUQyBpcyB0aGUgbmFtZSBvZiB0aGUgcHJvZHVjdC4gIEl0IGlzIGFuIGFjcm9ueW0gZm9yIFhNTCBTdHlsZXNoZWV0OgotICogICAgICBUcmFuc2Zvcm1hdGlvbnMgQ29tcGlsZXIKLSAqCi0gKiAgIDIpIEEgc3R5bGVzaGVldCBpcyBhIGRlc2NyaXB0aW9uIG9mIGhvdyB0byB0cmFuc2Zvcm0gYW4gaW5wdXQgWE1MIGRvY3VtZW50Ci0gKiAgICAgIGludG8gYSByZXN1bHRhbnQgb3V0cHV0IFhNTCBkb2N1bWVudCAob3IgSFRNTCBkb2N1bWVudCBvciB0ZXh0KQotICoKLSAqICAgMykgQW4gYXhpcyBpcyBhIHBhcnRpY3VsYXIgImRpbWVuc2lvbiIgaW4gYSB0cmVlIHJlcHJlc2VudGF0aW9uIG9mIGFuIFhNTAotICogICAgICBkb2N1bWVudDsgdGhlIG5vZGVzIGluIHRoZSB0cmVlIGFyZSBkaXZpZGVkIGFsb25nIGRpZmZlcmVudCBheGVzLgotICogICAgICBUcmF2ZXJzaW5nIHRoZSAiY2hpbGQiIGF4aXMsIGZvciBpbnN0YW5jZSwgbWVhbnMgdGhhdCB0aGUgcHJvZ3JhbQotICogICAgICB3b3VsZCB2aXNpdCBlYWNoIGNoaWxkIG9mIGEgcGFydGljdWxhciBub2RlOyB0cmF2ZXJzaW5nIHRoZSAiZGVzY2VuZGFudCIKLSAqICAgICAgYXhpcyBtZWFucyB0aGF0IHRoZSBwcm9ncmFtIHdvdWxkIHZpc2l0IHRoZSBjaGlsZCBub2RlcyBvZiBhIHBhcnRpY3VsYXIKLSAqICAgICAgbm9kZSwgdGhlaXIgY2hpbGRyZW4sIGFuZCBzbyBvbiB1bnRpbCB0aGUgbGVhZiBub2RlcyBvZiB0aGUgdHJlZSBhcmUKLSAqICAgICAgcmVhY2hlZC4KLSAqCi0gKiAgIDQpIEFuIGl0ZXJhdG9yIGlzIGFuIG9iamVjdCB0aGF0IHRyYXZlcnNlcyBub2RlcyBpbiBhIHRyZWUgYWxvbmcgYQotICogICAgICBwYXJ0aWN1bGFyIGF4aXMsIG9uZSBhdCBhIHRpbWUuCi0gKgotICogICA1KSBBbiBlbGVtZW50IGlzIGEgbWFyay11cCB0YWcgaW4gYW4gWE1MIGRvY3VtZW50OyBhbiBhdHRyaWJ1dGUgaXMgYQotICogICAgICBtb2RpZmllciBvbiB0aGUgdGFnLiAgRm9yIGV4YW1wbGUsIGluIDxlbGVtIGF0dHI9J3ZhbCcgYXR0cjI9J3ZhbDInPgotICogICAgICAiZWxlbSIgaXMgYW4gZWxlbWVudCBuYW1lLCAiYXR0ciIgYW5kICJhdHRyMiIgYXJlIGF0dHJpYnV0ZSBuYW1lcyB3aXRoCi0gKiAgICAgIHRoZSB2YWx1ZXMgInZhbCIgYW5kICJ2YWwyIiwgcmVzcGVjdGl2ZWx5LgotICoKLSAqICAgNikgQSBuYW1lc3BhY2UgZGVjbGFyYXRpb24gaXMgYSBzcGVjaWFsIGF0dHJpYnV0ZSB0aGF0IGlzIHVzZWQgdG8gYXNzb2NpYXRlCi0gKiAgICAgIGEgcHJlZml4IHdpdGggYSBVUkkgKHRoZSBuYW1lc3BhY2UpLiAgVGhlIG1lYW5pbmdzIG9mIGVsZW1lbnQgbmFtZXMgYW5kCi0gKiAgICAgIGF0dHJpYnV0ZSBuYW1lcyB0aGF0IHVzZSB0aGF0IHByZWZpeCBhcmUgZGVmaW5lZCB3aXRoIHJlc3BlY3QgdG8gdGhhdAotICogICAgICBuYW1lc3BhY2UuCi0gKgotICogICA3KSBET00gaXMgYW4gYWNyb255bSBmb3IgRG9jdW1lbnQgT2JqZWN0IE1vZGVsLiAgSXQgaXMgYSB0cmVlCi0gKiAgICAgIHJlcHJlc2VudGF0aW9uIG9mIGFuIFhNTCBkb2N1bWVudC4KLSAqCi0gKiAgICAgIFNBWCBpcyBhbiBhY3JvbnltIGZvciB0aGUgU2ltcGxlIEFQSSBmb3IgWE1MIHByb2Nlc3NpbmcuICBJdCBpcyBhbiBBUEkKLSAqICAgICAgdXNlZCBpbmZvcm0gYW4gWE1MIHByb2Nlc3NvciAoaW4gdGhpcyBjYXNlIFhTTFRDKSBvZiB0aGUgc3RydWN0dXJlIGFuZAotICogICAgICBjb250ZW50IG9mIGFuIFhNTCBkb2N1bWVudC4KLSAqCi0gKiAgICAgIElucHV0IHRvIHRoZSBzdHlsZXNoZWV0IHByb2Nlc3NvciBjYW4gY29tZSBmcm9tIGFuIFhNTCBwYXJzZXIgaW4gdGhlCi0gKiAgICAgIGZvcm0gb2YgYSBET00gdHJlZSBvciB0aHJvdWdoIHRoZSBTQVggQVBJLgotICoKLSAqICAgOCkgRFREIGlzIGEgZG9jdW1lbnQgdHlwZSBkZWNsYXJhdGlvbi4gIEl0IGlzIGEgd2F5IG9mIHNwZWNpZnlpbmcgdGhlCi0gKiAgICAgIGdyYW1tYXIgZm9yIGFuIFhNTCBmaWxlLCB0aGUgbmFtZXMgYW5kIHR5cGVzIG9mIGVsZW1lbnRzLCBhdHRyaWJ1dGVzLAotICogICAgICBldGMuCi0gKgotICogICA5KSBUcmFuc2xldCBpcyBhbiBpbnZlbnRlZCB0ZXJtIHRoYXQgcmVmZXJzIHRvIHRoZSBjbGFzcyBmaWxlIHRoYXQgY29udGFpbnMKLSAqICAgICAgdGhlIGNvbXBpbGVkIGZvcm0gb2YgYSBzdHlsZXNoZWV0LgotICovCi0KLSAgICAvLyBUaGVzZSBtZXNzYWdlIHNob3VsZCBiZSByZWFkIGZyb20gYSBsb2NhbGUtc3BlY2lmaWMgcmVzb3VyY2UgYnVuZGxlCi0gICAgLyoqIEdldCB0aGUgbG9va3VwIHRhYmxlIGZvciBlcnJvciBtZXNzYWdlcy4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIG1lc3NhZ2UgbG9va3VwIHRhYmxlLgotICAgICAqLwotICAgIHB1YmxpYyBPYmplY3RbXVtdIGdldENvbnRlbnRzKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBuZXcgT2JqZWN0W11bXSB7Ci0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIHRoZSBzdWJzdGl0dXRpb24gdGV4dCBpbiB0aGUgZm9sbG93aW5nIG1lc3NhZ2UKLSAgICAgICAgICogaXMgYSBjbGFzcyBuYW1lLiAgVXNlZCBmb3IgaW50ZXJuYWwgZXJyb3JzIGluIHRoZSBwcm9jZXNzb3IuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LlJVTl9USU1FX0lOVEVSTkFMX0VSUiwKLSAgICAgICAgIkludGVybnQgZXhla3ZlcmluZ3NmZWwgaSAnJ3swfScnIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIDx4c2w6Y29weT4gaXMgYSBrZXl3b3JkIHRoYXQgc2hvdWxkIG5vdCBiZQotICAgICAgICAgKiB0cmFuc2xhdGVkLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5SVU5fVElNRV9DT1BZX0VSUiwKLSAgICAgICAgIkV4ZWt2ZXJpbmdzZXhla3ZlcmluZ3NmZWwgYXYgPHhzbDpjb3B5Pi4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHJlZmVycyB0byBkYXRhIHR5cGVzLgotICAgICAgICAgKiBUaGUgbWVzc2FnZSBpcyBkaXNwbGF5ZWQgaWYgYSB2YWx1ZSBpbiBhIHBhcnRpY3VsYXIgY29udGV4dCBuZWVkcyB0bwotICAgICAgICAgKiBiZSBjb252ZXJ0ZWQgdG8gdHlwZSB7MX0sIGJ1dCB0aGF0J3Mgbm90IHBvc3NpYmxlIGZvciBhIHZhbHVlIG9mIHR5cGUKLSAgICAgICAgICogezB9LgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5EQVRBX0NPTlZFUlNJT05fRVJSLAotICAgICAgICAiT2dpbHRpZyBrb252ZXJ0ZXJpbmcgZnJcdTAwRTVuICcnezB9JycgdGlsbCAnJ3sxfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgZGlzcGxheWVkIGlmIHRoZSBmdW5jdGlvbiBuYW1lZAotICAgICAgICAgKiBieSB0aGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgbm90IGEgZnVuY3Rpb24gdGhhdCBpcyBzdXBwb3J0ZWQuICBYU0xUQwotICAgICAgICAgKiBpcyB0aGUgYWNyb255bSBuYW1pbmcgdGhlIHByb2R1Y3QuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LkVYVEVSTkFMX0ZVTkNfRVJSLAotICAgICAgICAiRGVuIGV4dGVybmEgZnVua3Rpb25lbiAnJ3swfScnIHVuZGVyc3RcdTAwRjZkcyBpbnRlIGkgWFNMVEMuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyBkaXNwbGF5ZWQgaWYgdHdvIHZhbHVlcyBhcmUKLSAgICAgICAgICogY29tcGFyZWQgZm9yIGVxdWFsaXR5LCBidXQgdGhlIGRhdGEgdHlwZSBvZiBvbmUgb2YgdGhlIHZhbHVlcyBpcwotICAgICAgICAgKiB1bmtub3duLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5FUVVBTElUWV9FWFBSX0VSUiwKLSAgICAgICAgIk9rXHUwMEU0bmQgYXJndW1lbnR0eXAgaSBsaWtoZXRzdXR0cnljay4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGZvciB7MH0gd2lsbCBiZSBhIGRhdGEKLSAgICAgICAgICogdHlwZTsgdGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGZvciB7MX0gd2lsbCBiZSB0aGUgbmFtZSBvZiBhIGZ1bmN0aW9uLgotICAgICAgICAgKiBUaGlzIGlzIGRpc3BsYXllZCBpZiBhbiBhcmd1bWVudCBvZiB0aGUgcGFydGljdWxhciBkYXRhIHR5cGUgaXMgbm90Ci0gICAgICAgICAqIHBlcm1pdHRlZCBmb3IgYSBjYWxsIHRvIHRoaXMgZnVuY3Rpb24uCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LklOVkFMSURfQVJHVU1FTlRfRVJSLAotICAgICAgICAiQXJndW1lbnR0eXAgJyd7MH0nJyBpIGFucm9wIHRpbGwgJyd7MX0nJyBcdTAwRTRyIGludGUgZ2lsdGlnIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZXJlIGlzIHdheSBvZiBzcGVjaWZ5aW5nIGEgZm9ybWF0IGZvciBhCi0gICAgICAgICAqIG51bWJlciB1c2luZyBhIHBhdHRlcm47IHRoZSBwcm9jZXNzb3Igd2FzIHVuYWJsZSB0byBmb3JtYXQgdGhlCi0gICAgICAgICAqIHBhcnRpY3VsYXIgdmFsdWUgdXNpbmcgdGhlIHNwZWNpZmllZCBwYXR0ZXJuLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5GT1JNQVRfTlVNQkVSX0VSUiwKLSAgICAgICAgIkZcdTAwRjZyc1x1MDBGNmtlciBmb3JtYXRlcmEgdGFsZXQgJyd7MH0nJyBtZWQgbVx1MDBGNm5zdHJldCAnJ3sxfScnLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIHJlcHJlc2VudHMgYW4gaW50ZXJuYWwgZXJyb3IKLSAgICAgICAgICogc2l0dWF0aW9uIGluIFhTTFRDLiAgVGhlIHByb2Nlc3NvciB3YXMgdW5hYmxlIHRvIGNyZWF0ZSBhIGNvcHkgb2YgYW4KLSAgICAgICAgICogaXRlcmF0b3IuICAoU2VlIGRlZmluaXRpb24gb2YgaXRlcmF0b3IgYWJvdmUuKQotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5JVEVSQVRPUl9DTE9ORV9FUlIsCi0gICAgICAgICJLYW4gaW50ZSBrbG9uYSBpdGVyYXRvcm4gJyd7MH0nJy4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyByZXByZXNlbnRzIGFuIGludGVybmFsIGVycm9yCi0gICAgICAgICAqIHNpdHVhdGlvbiBpbiBYU0xUQy4gIFRoZSBwcm9jZXNzb3IgYXR0ZW1wdGVkIHRvIGNyZWF0ZSBhbiBpdGVyYXRvcgotICAgICAgICAgKiBmb3IgYSBwYXJ0aWN1bGFyIGF4aXMgKHNlZSBkZWZpbml0aW9uIGFib3ZlKSB0aGF0IGl0IGRvZXMgbm90Ci0gICAgICAgICAqIHN1cHBvcnQuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LkFYSVNfU1VQUE9SVF9FUlIsCi0gICAgICAgICJJdGVyYXRvcm4gZlx1MDBGNnIgYXhlbG4gJyd7MH0nJyB1bmRlcnN0XHUwMEY2ZHMgaW50ZS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyByZXByZXNlbnRzIGFuIGludGVybmFsIGVycm9yCi0gICAgICAgICAqIHNpdHVhdGlvbiBpbiBYU0xUQy4gIFRoZSBwcm9jZXNzb3IgYXR0ZW1wdGVkIHRvIGNyZWF0ZSBhbiBpdGVyYXRvcgotICAgICAgICAgKiBmb3IgYSBwYXJ0aWN1bGFyIGF4aXMgKHNlZSBkZWZpbml0aW9uIGFib3ZlKSB0aGF0IGl0IGRvZXMgbm90Ci0gICAgICAgICAqIHN1cHBvcnQuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LlRZUEVEX0FYSVNfU1VQUE9SVF9FUlIsCi0gICAgICAgICJJdGVyYXRvcm4gZlx1MDBGNnIgZGVuIHR5cGFkZSBheGVsbiAnJ3swfScnIHVuZGVyc3RcdTAwRjZkcyBpbnRlLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgcmVwb3J0ZWQgaWYgdGhlIHN0eWxlc2hlZXQKLSAgICAgICAgICogYmVpbmcgcHJvY2Vzc2VkIGF0dGVtcHRlZCB0byBjb25zdHJ1Y3QgYW4gWE1MIGRvY3VtZW50IHdpdGggYW4KLSAgICAgICAgICogYXR0cmlidXRlIGluIGEgcGxhY2Ugb3RoZXIgdGhhbiBvbiBhbiBlbGVtZW50LiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgICAqIHNwZWNpZmllcyB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5TVFJBWV9BVFRSSUJVVEVfRVJSLAotICAgICAgICAiQXR0cmlidXRldCAnJ3swfScnIGZpbm5zIHV0YW5mXHUwMEY2ciBlbGVtZW50ZXQuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFzIHdpdGggdGhlIHByZWNlZGluZyBtZXNzYWdlLCBhIG5hbWVzcGFjZQotICAgICAgICAgKiBkZWNsYXJhdGlvbiBoYXMgdGhlIGZvcm0gb2YgYW4gYXR0cmlidXRlIGFuZCBpcyBvbmx5IHBlcm1pdHRlZCB0bwotICAgICAgICAgKiBhcHBlYXIgb24gYW4gZWxlbWVudC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCB7MH0gaXMgdGhlIG5hbWVzcGFjZQotICAgICAgICAgKiBwcmVmaXggYW5kIHsxfSBpcyB0aGUgVVJJIHRoYXQgd2FzIGJlaW5nIHVzZWQgaW4gdGhlIGVycm9uZW91cwotICAgICAgICAgKiBuYW1lc3BhY2UgZGVjbGFyYXRpb24uCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LlNUUkFZX05BTUVTUEFDRV9FUlIsCi0gICAgICAgICJOYW1ucnltZHNkZWtsYXJhdGlvbmVuICcnezB9Jyc9Jyd7MX0nJyBmaW5ucyB1dGFuZlx1MDBGNnIgZWxlbWVudC4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN0eWxlc2hlZXQgY29udGFpbmVkIGEgcmVmZXJlbmNlIHRvIGEKLSAgICAgICAgICogbmFtZXNwYWNlIHByZWZpeCB0aGF0IHdhcyB1bmRlZmluZWQuICBUaGUgdmFsdWUgb2YgdGhlIHN1YnN0aXR1dGlvbgotICAgICAgICAgKiB0ZXh0IGlzIHRoZSBuYW1lIG9mIHRoZSBwcmVmaXguCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5Lk5BTUVTUEFDRV9QUkVGSVhfRVJSLAotICAgICAgICAiTmFtbnJ5bWQgZlx1MDBGNnIgcHJlZml4ICcnezB9JycgaGFyIGludGUgZGVrbGFyZXJhdHMuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgcmVwcmVzZW50cyBhbiBpbnRlcm5hbCBlcnJvci4KLSAgICAgICAgICogRE9NQWRhcHRlciBpcyBhIEphdmEgY2xhc3MgaW4gWFNMVEMuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LkRPTV9BREFQVEVSX0lOSVRfRVJSLAotICAgICAgICAiRE9NQWRhcHRlciBoYXIgc2thcGF0cyBtZWQgZmVsIHR5cCBhdiBET00ta1x1MDBFNGxsYS4ifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoZSBYTUwKLSAgICAgICAgICogcGFyc2VyIHRoYXQgaXMgcHJvdmlkaW5nIGlucHV0IHRvIFhTTFRDIGNhbm5vdCBiZSB1c2VkIGJlY2F1c2UgaXQKLSAgICAgICAgICogZG9lcyBub3QgZGVzY3JpYmUgdG8gWFNMVEMgdGhlIHN0cnVjdHVyZSBvZiB0aGUgaW5wdXQgWE1MIGRvY3VtZW50J3MKLSAgICAgICAgICogRFRELgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5QQVJTRVJfRFREX1NVUFBPUlRfRVJSLAotICAgICAgICAiRGVuIFNBWC1wYXJzZXIgc29tIGR1IGFudlx1MDBFNG5kZXIgaGFudGVyYXIgaW5nYSBEVEQtZGVrbGFyYXRpb25zaFx1MDBFNG5kZWxzZXIuIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUgWE1MCi0gICAgICAgICAqIHBhcnNlciB0aGF0IGlzIHByb3ZpZGluZyBpbnB1dCB0byBYU0xUQyBjYW5ub3QgYmUgdXNlZCBiZWNhdXNlIGl0Ci0gICAgICAgICAqIGRvZXMgbm90IGRpc3Rpbmd1aXNoIGJldHdlZW4gb3JkaW5hcnkgWE1MIGF0dHJpYnV0ZXMgYW5kIG5hbWVzcGFjZQotICAgICAgICAgKiBkZWNsYXJhdGlvbnMuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5Lk5BTUVTUEFDRVNfU1VQUE9SVF9FUlIsCi0gICAgICAgICJEZW4gU0FYLXBhcnNlciBzb20gZHUgYW52XHUwMEU0bmRlciBzYWtuYXIgc3RcdTAwRjZkIGZcdTAwRjZyIFhNTC1uYW1ucnltZGVyLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIFVSSSB0aGF0IHdhcyBpbgotICAgICAgICAgKiBlcnJvci4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuQ0FOVF9SRVNPTFZFX1JFTEFUSVZFX1VSSV9FUlIsCi0gICAgICAgICJLdW5kZSBpbnRlIG1hdGNoYSBVUkktcmVmZXJlbnNlbiAnJ3swfScnLiJ9LAotCi0gICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN0eWxlc2hlZXQgY29udGFpbmVkIGFuIGVsZW1lbnQgdGhhdCB3YXMKLSAgICAgICAgICogbm90IHJlY29nbml6ZWQgYXMgcGFydCBvZiB0aGUgWFNMIHN5bnRheC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICAgKiBnaXZlcyB0aGUgZWxlbWVudCBuYW1lLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5VTlNVUFBPUlRFRF9YU0xfRVJSLAotICAgICAgICAiWFNMLWVsZW1lbnRldCAnJ3swfScnIHN0XHUwMEY2ZHMgaW50ZSJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3R5bGVzaGVldCByZWZlcnJlZCB0byBhbiBleHRlbnNpb24gdG8gdGhlCi0gICAgICAgICAqIFhTTCBzeW50YXggYW5kIGluZGljYXRlZCB0aGF0IGl0IHdhcyBkZWZpbmVkIGJ5IFhTTFRDLCBidXQgWFNMVEMgZG9lcwotICAgICAgICAgKiBub3QgcmVjb2duaXplIHRoZSBwYXJ0aWN1bGFyIGV4dGVuc2lvbiBuYW1lZC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICAgKiBnaXZlcyB0aGUgZXh0ZW5zaW9uIG5hbWUuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LlVOU1VQUE9SVEVEX0VYVF9FUlIsCi0gICAgICAgICJYU0xUQy10aWxsXHUwMEU0Z2dldCAnJ3swfScnIFx1MDBFNHIgb2tcdTAwRTRudCJ9LAotCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgZXJyb3IgbWVzc2FnZSBpcyBwcm9kdWNlZCBpZiB0aGUgdHJhbnNsZXQKLSAgICAgICAgICogY2xhc3Mgd2FzIGNvbXBpbGVkIHVzaW5nIGEgbmV3ZXIgdmVyc2lvbiBvZiBYU0xUQyBhbmQgZGVwbG95ZWQgZm9yCi0gICAgICAgICAqIGV4ZWN1dGlvbiB3aXRoIGFuIG9sZGVyIHZlcnNpb24gb2YgWFNMVEMuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMKLSAgICAgICAgICogdGhlIG5hbWUgb2YgdGhlIHRyYW5zbGV0IGNsYXNzLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5VTktOT1dOX1RSQU5TTEVUX1ZFUlNJT05fRVJSLAotICAgICAgICAiQW5naXZlbiB0cmFuc2xldCwgJyd7MH0nJywgaGFyIHNrYXBhdHMgbWVkIGVuIFhTTFRDLXZlcnNpb24gc29tIFx1MDBFNHIgc2VuYXJlIFx1MDBFNG4gZGVuIFhTTFRDLWtcdTAwRjZybmluZyBpIGJydWsuIEZcdTAwRjZyIGF0dCBrdW5uYSBrXHUwMEY2cmEgZGVubmEgdHJhbnNsZXQgbVx1MDBFNXN0ZSBkdSBvbWtvbXBpbGVyYSBmb3JtYXRtYWxsZW4gZWxsZXIgYW52XHUwMEU0bmRhIGVuIHNlbmFyZSB2ZXJzaW9uIGF2IFhTTFRDLiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBbiBhdHRyaWJ1dGUgd2hvc2UgZWZmZWN0aXZlIHZhbHVlIGlzIHJlcXVpcmVkCi0gICAgICAgICAqIHRvIGJlIGEgIlFOYW1lIiBoYWQgYSB2YWx1ZSB0aGF0IHdhcyBpbmNvcnJlY3QuCi0gICAgICAgICAqICdRTmFtZScgaXMgYW4gWE1MIHN5bnRhY3RpYyB0ZXJtIHRoYXQgbXVzdCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoZQotICAgICAgICAgKiBzdWJzdGl0dXRpb24gdGV4dCBjb250YWlucyB0aGUgYWN0dWFsIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LklOVkFMSURfUU5BTUVfRVJSLAotICAgICAgICAiRXR0IGF0dHJpYnV0IHZhcnMgdlx1MDBFNHJkZSBtXHUwMEU1c3RlIHZhcmEgZXR0IFFOYW1lIGhhZGUgdlx1MDBFNHJkZXQgJyd7MH0nJyJ9LAotCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFuIGF0dHJpYnV0ZSB3aG9zZSBlZmZlY3RpdmUgdmFsdWUgaXMgcmVxdWlyZWQKLSAgICAgICAgICogdG8gYmUgYSAiTkNOYW1lIiBoYWQgYSB2YWx1ZSB0aGF0IHdhcyBpbmNvcnJlY3QuCi0gICAgICAgICAqICdOQ05hbWUnIGlzIGFuIFhNTCBzeW50YWN0aWMgdGVybSB0aGF0IG11c3Qgbm90IGJlIHRyYW5zbGF0ZWQuICBUaGUKLSAgICAgICAgICogc3Vic3RpdHV0aW9uIHRleHQgY29udGFpbnMgdGhlIGFjdHVhbCB2YWx1ZSBvZiB0aGUgYXR0cmlidXRlLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5JTlZBTElEX05DTkFNRV9FUlIsCi0gICAgICAgICJFdHQgYXR0cmlidXQgdmFycyB2XHUwMEU0cmRlIG1cdTAwRTVzdGUgdmFyYSBldHQgTkNOYW1lIGhhZGUgdlx1MDBFNHJkZXQgJyd7MH0nJyJ9LAotCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuVU5BTExPV0VEX0VYVEVOU0lPTl9GVU5DVElPTl9FUlIsCi0gICAgICAgICJBbnZcdTAwRTRuZG5pbmcgYXYgdGlsbFx1MDBFNGdnc2Z1bmt0aW9uZW4gJyd7MH0nJyBcdTAwRTRyIGludGUgdGlsbFx1MDBFNXRldCBuXHUwMEU0ciBzXHUwMEU0a2VyIGJlYXJiZXRuaW5nIHRpbGxcdTAwRTRtcGFzLiJ9LAotCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuVU5BTExPV0VEX0VYVEVOU0lPTl9FTEVNRU5UX0VSUiwKLSAgICAgICAgIkFudlx1MDBFNG5kbmluZyBhdiB0aWxsXHUwMEU0Z2dzZWxlbWVudGV0ICcnezB9JycgXHUwMEU0ciBpbnRlIHRpbGxcdTAwRTV0ZXQgblx1MDBFNHIgc1x1MDBFNGtlciBiZWFyYmV0bmluZyB0aWxsXHUwMEU0bXBhcy4ifSwKLSAgICB9OwotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ydW50aW1lL0Vycm9yTWVzc2FnZXNfemhfQ04uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9FcnJvck1lc3NhZ2VzX3poX0NOLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGEzNGQ0MmMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ydW50aW1lL0Vycm9yTWVzc2FnZXNfemhfQ04uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI4NCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnJ1bnRpbWU7Ci0KLWltcG9ydCBqYXZhLnV0aWwuTGlzdFJlc291cmNlQnVuZGxlOwotCi0vKioKLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICovCi1wdWJsaWMgY2xhc3MgRXJyb3JNZXNzYWdlc196aF9DTiBleHRlbmRzIExpc3RSZXNvdXJjZUJ1bmRsZSB7Ci0KLS8qCi0gKiBYU0xUQyBydW4tdGltZSBlcnJvciBtZXNzYWdlcy4KLSAqCi0gKiBHZW5lcmFsIG5vdGVzIHRvIHRyYW5zbGF0b3JzIGFuZCBkZWZpbml0aW9uczoKLSAqCi0gKiAgIDEpIFhTTFRDIGlzIHRoZSBuYW1lIG9mIHRoZSBwcm9kdWN0LiAgSXQgaXMgYW4gYWNyb255bSBmb3IgWE1MIFN0eWxlc2hlZXQ6Ci0gKiAgICAgIFRyYW5zZm9ybWF0aW9ucyBDb21waWxlcgotICoKLSAqICAgMikgQSBzdHlsZXNoZWV0IGlzIGEgZGVzY3JpcHRpb24gb2YgaG93IHRvIHRyYW5zZm9ybSBhbiBpbnB1dCBYTUwgZG9jdW1lbnQKLSAqICAgICAgaW50byBhIHJlc3VsdGFudCBvdXRwdXQgWE1MIGRvY3VtZW50IChvciBIVE1MIGRvY3VtZW50IG9yIHRleHQpCi0gKgotICogICAzKSBBbiBheGlzIGlzIGEgcGFydGljdWxhciAiZGltZW5zaW9uIiBpbiBhIHRyZWUgcmVwcmVzZW50YXRpb24gb2YgYW4gWE1MCi0gKiAgICAgIGRvY3VtZW50OyB0aGUgbm9kZXMgaW4gdGhlIHRyZWUgYXJlIGRpdmlkZWQgYWxvbmcgZGlmZmVyZW50IGF4ZXMuCi0gKiAgICAgIFRyYXZlcnNpbmcgdGhlICJjaGlsZCIgYXhpcywgZm9yIGluc3RhbmNlLCBtZWFucyB0aGF0IHRoZSBwcm9ncmFtCi0gKiAgICAgIHdvdWxkIHZpc2l0IGVhY2ggY2hpbGQgb2YgYSBwYXJ0aWN1bGFyIG5vZGU7IHRyYXZlcnNpbmcgdGhlICJkZXNjZW5kYW50IgotICogICAgICBheGlzIG1lYW5zIHRoYXQgdGhlIHByb2dyYW0gd291bGQgdmlzaXQgdGhlIGNoaWxkIG5vZGVzIG9mIGEgcGFydGljdWxhcgotICogICAgICBub2RlLCB0aGVpciBjaGlsZHJlbiwgYW5kIHNvIG9uIHVudGlsIHRoZSBsZWFmIG5vZGVzIG9mIHRoZSB0cmVlIGFyZQotICogICAgICByZWFjaGVkLgotICoKLSAqICAgNCkgQW4gaXRlcmF0b3IgaXMgYW4gb2JqZWN0IHRoYXQgdHJhdmVyc2VzIG5vZGVzIGluIGEgdHJlZSBhbG9uZyBhCi0gKiAgICAgIHBhcnRpY3VsYXIgYXhpcywgb25lIGF0IGEgdGltZS4KLSAqCi0gKiAgIDUpIEFuIGVsZW1lbnQgaXMgYSBtYXJrLXVwIHRhZyBpbiBhbiBYTUwgZG9jdW1lbnQ7IGFuIGF0dHJpYnV0ZSBpcyBhCi0gKiAgICAgIG1vZGlmaWVyIG9uIHRoZSB0YWcuICBGb3IgZXhhbXBsZSwgaW4gPGVsZW0gYXR0cj0ndmFsJyBhdHRyMj0ndmFsMic+Ci0gKiAgICAgICJlbGVtIiBpcyBhbiBlbGVtZW50IG5hbWUsICJhdHRyIiBhbmQgImF0dHIyIiBhcmUgYXR0cmlidXRlIG5hbWVzIHdpdGgKLSAqICAgICAgdGhlIHZhbHVlcyAidmFsIiBhbmQgInZhbDIiLCByZXNwZWN0aXZlbHkuCi0gKgotICogICA2KSBBIG5hbWVzcGFjZSBkZWNsYXJhdGlvbiBpcyBhIHNwZWNpYWwgYXR0cmlidXRlIHRoYXQgaXMgdXNlZCB0byBhc3NvY2lhdGUKLSAqICAgICAgYSBwcmVmaXggd2l0aCBhIFVSSSAodGhlIG5hbWVzcGFjZSkuICBUaGUgbWVhbmluZ3Mgb2YgZWxlbWVudCBuYW1lcyBhbmQKLSAqICAgICAgYXR0cmlidXRlIG5hbWVzIHRoYXQgdXNlIHRoYXQgcHJlZml4IGFyZSBkZWZpbmVkIHdpdGggcmVzcGVjdCB0byB0aGF0Ci0gKiAgICAgIG5hbWVzcGFjZS4KLSAqCi0gKiAgIDcpIERPTSBpcyBhbiBhY3JvbnltIGZvciBEb2N1bWVudCBPYmplY3QgTW9kZWwuICBJdCBpcyBhIHRyZWUKLSAqICAgICAgcmVwcmVzZW50YXRpb24gb2YgYW4gWE1MIGRvY3VtZW50LgotICoKLSAqICAgICAgU0FYIGlzIGFuIGFjcm9ueW0gZm9yIHRoZSBTaW1wbGUgQVBJIGZvciBYTUwgcHJvY2Vzc2luZy4gIEl0IGlzIGFuIEFQSQotICogICAgICB1c2VkIGluZm9ybSBhbiBYTUwgcHJvY2Vzc29yIChpbiB0aGlzIGNhc2UgWFNMVEMpIG9mIHRoZSBzdHJ1Y3R1cmUgYW5kCi0gKiAgICAgIGNvbnRlbnQgb2YgYW4gWE1MIGRvY3VtZW50LgotICoKLSAqICAgICAgSW5wdXQgdG8gdGhlIHN0eWxlc2hlZXQgcHJvY2Vzc29yIGNhbiBjb21lIGZyb20gYW4gWE1MIHBhcnNlciBpbiB0aGUKLSAqICAgICAgZm9ybSBvZiBhIERPTSB0cmVlIG9yIHRocm91Z2ggdGhlIFNBWCBBUEkuCi0gKgotICogICA4KSBEVEQgaXMgYSBkb2N1bWVudCB0eXBlIGRlY2xhcmF0aW9uLiAgSXQgaXMgYSB3YXkgb2Ygc3BlY2lmeWluZyB0aGUKLSAqICAgICAgZ3JhbW1hciBmb3IgYW4gWE1MIGZpbGUsIHRoZSBuYW1lcyBhbmQgdHlwZXMgb2YgZWxlbWVudHMsIGF0dHJpYnV0ZXMsCi0gKiAgICAgIGV0Yy4KLSAqCi0gKiAgIDkpIFRyYW5zbGV0IGlzIGFuIGludmVudGVkIHRlcm0gdGhhdCByZWZlcnMgdG8gdGhlIGNsYXNzIGZpbGUgdGhhdCBjb250YWlucwotICogICAgICB0aGUgY29tcGlsZWQgZm9ybSBvZiBhIHN0eWxlc2hlZXQuCi0gKi8KLQotICAgIC8vIFRoZXNlIG1lc3NhZ2Ugc2hvdWxkIGJlIHJlYWQgZnJvbSBhIGxvY2FsZS1zcGVjaWZpYyByZXNvdXJjZSBidW5kbGUKLSAgICAvKiogR2V0IHRoZSBsb29rdXAgdGFibGUgZm9yIGVycm9yIG1lc3NhZ2VzLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgbWVzc2FnZSBsb29rdXAgdGFibGUuCi0gICAgICovCi0gICAgcHVibGljIE9iamVjdFtdW10gZ2V0Q29udGVudHMoKQotICAgIHsKLSAgICAgICAgcmV0dXJuIG5ldyBPYmplY3RbXVtdIHsKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgdGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGluIHRoZSBmb2xsb3dpbmcgbWVzc2FnZQotICAgICAgICAgKiBpcyBhIGNsYXNzIG5hbWUuICBVc2VkIGZvciBpbnRlcm5hbCBlcnJvcnMgaW4gdGhlIHByb2Nlc3Nvci4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuUlVOX1RJTUVfSU5URVJOQUxfRVJSLAotICAgICAgICAiJyd7MH0nJyBcdTRFMkRcdTc2ODRcdThGRDBcdTg4NENcdTY1RjZcdTUxODVcdTkwRThcdTk1MTlcdThCRUYifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgPHhzbDpjb3B5PiBpcyBhIGtleXdvcmQgdGhhdCBzaG91bGQgbm90IGJlCi0gICAgICAgICAqIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LlJVTl9USU1FX0NPUFlfRVJSLAotICAgICAgICAiXHU2MjY3XHU4ODRDIDx4c2w6Y29weT4gXHU2NUY2XHU1MUZBXHU3M0IwXHU4RkQwXHU4ODRDXHU2NUY2XHU5NTE5XHU4QkVGXHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCByZWZlcnMgdG8gZGF0YSB0eXBlcy4KLSAgICAgICAgICogVGhlIG1lc3NhZ2UgaXMgZGlzcGxheWVkIGlmIGEgdmFsdWUgaW4gYSBwYXJ0aWN1bGFyIGNvbnRleHQgbmVlZHMgdG8KLSAgICAgICAgICogYmUgY29udmVydGVkIHRvIHR5cGUgezF9LCBidXQgdGhhdCdzIG5vdCBwb3NzaWJsZSBmb3IgYSB2YWx1ZSBvZiB0eXBlCi0gICAgICAgICAqIHswfS4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuREFUQV9DT05WRVJTSU9OX0VSUiwKLSAgICAgICAgIlx1NEVDRSAnJ3swfScnIFx1NTIzMCAnJ3sxfScnIFx1NzY4NFx1OEY2Q1x1NjM2Mlx1NjVFMFx1NjU0OFx1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgZGlzcGxheWVkIGlmIHRoZSBmdW5jdGlvbiBuYW1lZAotICAgICAgICAgKiBieSB0aGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgbm90IGEgZnVuY3Rpb24gdGhhdCBpcyBzdXBwb3J0ZWQuICBYU0xUQwotICAgICAgICAgKiBpcyB0aGUgYWNyb255bSBuYW1pbmcgdGhlIHByb2R1Y3QuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LkVYVEVSTkFMX0ZVTkNfRVJSLAotICAgICAgICAiWFNMVEMgXHU0RTBEXHU2NTJGXHU2MzAxXHU1OTE2XHU5MEU4XHU1MUZEXHU2NTcwICcnezB9JydcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIGRpc3BsYXllZCBpZiB0d28gdmFsdWVzIGFyZQotICAgICAgICAgKiBjb21wYXJlZCBmb3IgZXF1YWxpdHksIGJ1dCB0aGUgZGF0YSB0eXBlIG9mIG9uZSBvZiB0aGUgdmFsdWVzIGlzCi0gICAgICAgICAqIHVua25vd24uCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LkVRVUFMSVRZX0VYUFJfRVJSLAotICAgICAgICAiXHU3QjQ5XHU1RjBGXHU4ODY4XHU4RkJFXHU1RjBGXHU0RTJEXHU3Njg0XHU1M0MyXHU2NTcwXHU3QzdCXHU1NzhCXHU2NzJBXHU3N0U1XHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBmb3IgezB9IHdpbGwgYmUgYSBkYXRhCi0gICAgICAgICAqIHR5cGU7IHRoZSBzdWJzdGl0dXRpb24gdGV4dCBmb3IgezF9IHdpbGwgYmUgdGhlIG5hbWUgb2YgYSBmdW5jdGlvbi4KLSAgICAgICAgICogVGhpcyBpcyBkaXNwbGF5ZWQgaWYgYW4gYXJndW1lbnQgb2YgdGhlIHBhcnRpY3VsYXIgZGF0YSB0eXBlIGlzIG5vdAotICAgICAgICAgKiBwZXJtaXR0ZWQgZm9yIGEgY2FsbCB0byB0aGlzIGZ1bmN0aW9uLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5JTlZBTElEX0FSR1VNRU5UX0VSUiwKLSAgICAgICAgIlx1OEMwM1x1NzUyOCAnJ3sxfScnIFx1NjVGNlx1NzY4NFx1NTNDMlx1NjU3MFx1N0M3Qlx1NTc4QiAnJ3swfScnIFx1NjVFMFx1NjU0OCJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGVyZSBpcyB3YXkgb2Ygc3BlY2lmeWluZyBhIGZvcm1hdCBmb3IgYQotICAgICAgICAgKiBudW1iZXIgdXNpbmcgYSBwYXR0ZXJuOyB0aGUgcHJvY2Vzc29yIHdhcyB1bmFibGUgdG8gZm9ybWF0IHRoZQotICAgICAgICAgKiBwYXJ0aWN1bGFyIHZhbHVlIHVzaW5nIHRoZSBzcGVjaWZpZWQgcGF0dGVybi4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuRk9STUFUX05VTUJFUl9FUlIsCi0gICAgICAgICJcdTVDMURcdThCRDVcdTRGN0ZcdTc1MjhcdTZBMjFcdTVGMEYgJyd7MX0nJyBcdThCQkVcdTdGNkVcdTY1NzBcdTVCNTcgJyd7MH0nJyBcdTc2ODRcdTY4M0NcdTVGMEZcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyByZXByZXNlbnRzIGFuIGludGVybmFsIGVycm9yCi0gICAgICAgICAqIHNpdHVhdGlvbiBpbiBYU0xUQy4gIFRoZSBwcm9jZXNzb3Igd2FzIHVuYWJsZSB0byBjcmVhdGUgYSBjb3B5IG9mIGFuCi0gICAgICAgICAqIGl0ZXJhdG9yLiAgKFNlZSBkZWZpbml0aW9uIG9mIGl0ZXJhdG9yIGFib3ZlLikKLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuSVRFUkFUT1JfQ0xPTkVfRVJSLAotICAgICAgICAiXHU2NUUwXHU2Q0Q1XHU1MTRCXHU5Njg2XHU4RkVEXHU0RUUzXHU1NjY4ICcnezB9JydcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyByZXByZXNlbnRzIGFuIGludGVybmFsIGVycm9yCi0gICAgICAgICAqIHNpdHVhdGlvbiBpbiBYU0xUQy4gIFRoZSBwcm9jZXNzb3IgYXR0ZW1wdGVkIHRvIGNyZWF0ZSBhbiBpdGVyYXRvcgotICAgICAgICAgKiBmb3IgYSBwYXJ0aWN1bGFyIGF4aXMgKHNlZSBkZWZpbml0aW9uIGFib3ZlKSB0aGF0IGl0IGRvZXMgbm90Ci0gICAgICAgICAqIHN1cHBvcnQuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LkFYSVNfU1VQUE9SVF9FUlIsCi0gICAgICAgICJcdTRFMERcdTY1MkZcdTYzMDFcdThGNzQgJyd7MH0nJyBcdTc2ODRcdThGRURcdTRFRTNcdTU2NjhcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyByZXByZXNlbnRzIGFuIGludGVybmFsIGVycm9yCi0gICAgICAgICAqIHNpdHVhdGlvbiBpbiBYU0xUQy4gIFRoZSBwcm9jZXNzb3IgYXR0ZW1wdGVkIHRvIGNyZWF0ZSBhbiBpdGVyYXRvcgotICAgICAgICAgKiBmb3IgYSBwYXJ0aWN1bGFyIGF4aXMgKHNlZSBkZWZpbml0aW9uIGFib3ZlKSB0aGF0IGl0IGRvZXMgbm90Ci0gICAgICAgICAqIHN1cHBvcnQuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LlRZUEVEX0FYSVNfU1VQUE9SVF9FUlIsCi0gICAgICAgICJcdTRFMERcdTY1MkZcdTYzMDFcdTdDN0JcdTU3OEJcdTUzMTZcdThGNzQgJyd7MH0nJyBcdTc2ODRcdThGRURcdTRFRTNcdTU2NjhcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIHJlcG9ydGVkIGlmIHRoZSBzdHlsZXNoZWV0Ci0gICAgICAgICAqIGJlaW5nIHByb2Nlc3NlZCBhdHRlbXB0ZWQgdG8gY29uc3RydWN0IGFuIFhNTCBkb2N1bWVudCB3aXRoIGFuCi0gICAgICAgICAqIGF0dHJpYnV0ZSBpbiBhIHBsYWNlIG90aGVyIHRoYW4gb24gYW4gZWxlbWVudC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICAgKiBzcGVjaWZpZXMgdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuU1RSQVlfQVRUUklCVVRFX0VSUiwKLSAgICAgICAgIlx1NUM1RVx1NjAyNyAnJ3swfScnIFx1NTcyOFx1NTE0M1x1N0QyMFx1NTkxNlx1OTBFOFx1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBcyB3aXRoIHRoZSBwcmVjZWRpbmcgbWVzc2FnZSwgYSBuYW1lc3BhY2UKLSAgICAgICAgICogZGVjbGFyYXRpb24gaGFzIHRoZSBmb3JtIG9mIGFuIGF0dHJpYnV0ZSBhbmQgaXMgb25seSBwZXJtaXR0ZWQgdG8KLSAgICAgICAgICogYXBwZWFyIG9uIGFuIGVsZW1lbnQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgezB9IGlzIHRoZSBuYW1lc3BhY2UKLSAgICAgICAgICogcHJlZml4IGFuZCB7MX0gaXMgdGhlIFVSSSB0aGF0IHdhcyBiZWluZyB1c2VkIGluIHRoZSBlcnJvbmVvdXMKLSAgICAgICAgICogbmFtZXNwYWNlIGRlY2xhcmF0aW9uLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5TVFJBWV9OQU1FU1BBQ0VfRVJSLAotICAgICAgICAiXHU1NDBEXHU3OUYwXHU3QTdBXHU5NUY0XHU1OEYwXHU2NjBFICcnezB9Jyc9Jyd7MX0nJyBcdTU3MjhcdTUxNDNcdTdEMjBcdTU5MTZcdTkwRThcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN0eWxlc2hlZXQgY29udGFpbmVkIGEgcmVmZXJlbmNlIHRvIGEKLSAgICAgICAgICogbmFtZXNwYWNlIHByZWZpeCB0aGF0IHdhcyB1bmRlZmluZWQuICBUaGUgdmFsdWUgb2YgdGhlIHN1YnN0aXR1dGlvbgotICAgICAgICAgKiB0ZXh0IGlzIHRoZSBuYW1lIG9mIHRoZSBwcmVmaXguCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5Lk5BTUVTUEFDRV9QUkVGSVhfRVJSLAotICAgICAgICAiXHU2Q0ExXHU2NzA5XHU4QkY0XHU2NjBFXHU1NDBEXHU3OUYwXHU3QTdBXHU5NUY0XHU1MjREXHU3RjAwICcnezB9JydcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyByZXByZXNlbnRzIGFuIGludGVybmFsIGVycm9yLgotICAgICAgICAgKiBET01BZGFwdGVyIGlzIGEgSmF2YSBjbGFzcyBpbiBYU0xUQy4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuRE9NX0FEQVBURVJfSU5JVF9FUlIsCi0gICAgICAgICJcdTRGN0ZcdTc1MjhcdTk1MTlcdThCRUZcdTdDN0JcdTU3OEJcdTc2ODRcdTZFOTAgRE9NIFx1NTIxQlx1NUVGQVx1NEU4NiBET01BZGFwdGVyXHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUgWE1MCi0gICAgICAgICAqIHBhcnNlciB0aGF0IGlzIHByb3ZpZGluZyBpbnB1dCB0byBYU0xUQyBjYW5ub3QgYmUgdXNlZCBiZWNhdXNlIGl0Ci0gICAgICAgICAqIGRvZXMgbm90IGRlc2NyaWJlIHRvIFhTTFRDIHRoZSBzdHJ1Y3R1cmUgb2YgdGhlIGlucHV0IFhNTCBkb2N1bWVudCdzCi0gICAgICAgICAqIERURC4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuUEFSU0VSX0RURF9TVVBQT1JUX0VSUiwKLSAgICAgICAgIlx1NEY3Rlx1NzUyOFx1NzY4NCBTQVggXHU4OUUzXHU2NzkwXHU1NjY4XHU0RTBEXHU0RjFBXHU1OTA0XHU3NDA2IERURCBcdTU4RjBcdTY2MEVcdTRFOEJcdTRFRjZcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoZSBYTUwKLSAgICAgICAgICogcGFyc2VyIHRoYXQgaXMgcHJvdmlkaW5nIGlucHV0IHRvIFhTTFRDIGNhbm5vdCBiZSB1c2VkIGJlY2F1c2UgaXQKLSAgICAgICAgICogZG9lcyBub3QgZGlzdGluZ3Vpc2ggYmV0d2VlbiBvcmRpbmFyeSBYTUwgYXR0cmlidXRlcyBhbmQgbmFtZXNwYWNlCi0gICAgICAgICAqIGRlY2xhcmF0aW9ucy4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuTkFNRVNQQUNFU19TVVBQT1JUX0VSUiwKLSAgICAgICAgIlx1NEY3Rlx1NzUyOFx1NzY4NCBTQVggXHU4OUUzXHU2NzkwXHU1NjY4XHU0RTBEXHU2NTJGXHU2MzAxIFhNTCBcdTU0MERcdTc5RjBcdTdBN0FcdTk1RjRcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBVUkkgdGhhdCB3YXMgaW4KLSAgICAgICAgICogZXJyb3IuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LkNBTlRfUkVTT0xWRV9SRUxBVElWRV9VUklfRVJSLAotICAgICAgICAiXHU2NUUwXHU2Q0Q1XHU4OUUzXHU2NzkwIFVSSSBcdTVGMTVcdTc1MjggJyd7MH0nJ1x1MzAwMiJ9LAotCi0gICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN0eWxlc2hlZXQgY29udGFpbmVkIGFuIGVsZW1lbnQgdGhhdCB3YXMKLSAgICAgICAgICogbm90IHJlY29nbml6ZWQgYXMgcGFydCBvZiB0aGUgWFNMIHN5bnRheC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICAgKiBnaXZlcyB0aGUgZWxlbWVudCBuYW1lLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5VTlNVUFBPUlRFRF9YU0xfRVJSLAotICAgICAgICAiWFNMIFx1NTE0M1x1N0QyMCAnJ3swfScnIFx1NEUwRFx1NTNEN1x1NjUyRlx1NjMwMSJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3R5bGVzaGVldCByZWZlcnJlZCB0byBhbiBleHRlbnNpb24gdG8gdGhlCi0gICAgICAgICAqIFhTTCBzeW50YXggYW5kIGluZGljYXRlZCB0aGF0IGl0IHdhcyBkZWZpbmVkIGJ5IFhTTFRDLCBidXQgWFNMVEMgZG9lcwotICAgICAgICAgKiBub3QgcmVjb2duaXplIHRoZSBwYXJ0aWN1bGFyIGV4dGVuc2lvbiBuYW1lZC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICAgKiBnaXZlcyB0aGUgZXh0ZW5zaW9uIG5hbWUuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LlVOU1VQUE9SVEVEX0VYVF9FUlIsCi0gICAgICAgICJYU0xUQyBcdTYyNjlcdTVDNTUgJyd7MH0nJyBcdTY1RTBcdTZDRDVcdThCQzZcdTUyMkIifSwKLQotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIGVycm9yIG1lc3NhZ2UgaXMgcHJvZHVjZWQgaWYgdGhlIHRyYW5zbGV0Ci0gICAgICAgICAqIGNsYXNzIHdhcyBjb21waWxlZCB1c2luZyBhIG5ld2VyIHZlcnNpb24gb2YgWFNMVEMgYW5kIGRlcGxveWVkIGZvcgotICAgICAgICAgKiBleGVjdXRpb24gd2l0aCBhbiBvbGRlciB2ZXJzaW9uIG9mIFhTTFRDLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzCi0gICAgICAgICAqIHRoZSBuYW1lIG9mIHRoZSB0cmFuc2xldCBjbGFzcy4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuVU5LTk9XTl9UUkFOU0xFVF9WRVJTSU9OX0VSUiwKLSAgICAgICAgIlx1NTIxQlx1NUVGQVx1NjMwN1x1NUI5QSB0cmFuc2xldCAnJ3swfScnIFx1NjVGNlx1NEY3Rlx1NzUyOFx1NzY4NCBYU0xUQyBcdTc2ODRcdTcyNDhcdTY3MkNcdTlBRDhcdTRFOEVcdTZCNjNcdTU3MjhcdTRGN0ZcdTc1MjhcdTc2ODQgWFNMVEMgXHU4RkQwXHU4ODRDXHU2NUY2XHU3Njg0XHU3MjQ4XHU2NzJDXHUzMDAyXHU1RkM1XHU5ODdCXHU5MUNEXHU2NUIwXHU3RjE2XHU4QkQxXHU2ODM3XHU1RjBGXHU4ODY4XHU2MjE2XHU0RjdGXHU3NTI4XHU4RjgzXHU2NUIwXHU3Njg0IFhTTFRDIFx1NzI0OFx1NjcyQ1x1OEZEMFx1ODg0Q1x1NkI2NCB0cmFuc2xldFx1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBbiBhdHRyaWJ1dGUgd2hvc2UgZWZmZWN0aXZlIHZhbHVlIGlzIHJlcXVpcmVkCi0gICAgICAgICAqIHRvIGJlIGEgIlFOYW1lIiBoYWQgYSB2YWx1ZSB0aGF0IHdhcyBpbmNvcnJlY3QuCi0gICAgICAgICAqICdRTmFtZScgaXMgYW4gWE1MIHN5bnRhY3RpYyB0ZXJtIHRoYXQgbXVzdCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoZQotICAgICAgICAgKiBzdWJzdGl0dXRpb24gdGV4dCBjb250YWlucyB0aGUgYWN0dWFsIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LklOVkFMSURfUU5BTUVfRVJSLAotICAgICAgICAiXHU1MTc2XHU1MDNDXHU1RkM1XHU5ODdCXHU0RTNBIFFOYW1lIFx1NzY4NFx1NUM1RVx1NjAyN1x1NTE3N1x1NjcwOVx1NTAzQyAnJ3swfScnIn0sCi0KLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQW4gYXR0cmlidXRlIHdob3NlIGVmZmVjdGl2ZSB2YWx1ZSBpcyByZXF1aXJlZAotICAgICAgICAgKiB0byBiZSBhICJOQ05hbWUiIGhhZCBhIHZhbHVlIHRoYXQgd2FzIGluY29ycmVjdC4KLSAgICAgICAgICogJ05DTmFtZScgaXMgYW4gWE1MIHN5bnRhY3RpYyB0ZXJtIHRoYXQgbXVzdCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoZQotICAgICAgICAgKiBzdWJzdGl0dXRpb24gdGV4dCBjb250YWlucyB0aGUgYWN0dWFsIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LklOVkFMSURfTkNOQU1FX0VSUiwKLSAgICAgICAgIlx1NTE3Nlx1NTAzQ1x1NUZDNVx1OTg3Qlx1NEUzQSBOQ05hbWUgXHU3Njg0XHU1QzVFXHU2MDI3XHU1MTc3XHU2NzA5XHU1MDNDICcnezB9JycifSwKLQotICAgICAgICB7QmFzaXNMaWJyYXJ5LlVOQUxMT1dFRF9FWFRFTlNJT05fRlVOQ1RJT05fRVJSLAotICAgICAgICAiXHU1RjUzXHU1Qjg5XHU1MTY4XHU1OTA0XHU3NDA2XHU1MjlGXHU4MEZEXHU4QkJFXHU3RjZFXHU0RTNBXHUyMDFDXHU3NzFGXHUyMDFEXHU2NUY2LCBcdTRFMERcdTUxNDFcdThCQjhcdTRGN0ZcdTc1MjhcdTYyNjlcdTVDNTVcdTUxRkRcdTY1NzAgJyd7MH0nJ1x1MzAwMiJ9LAotCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuVU5BTExPV0VEX0VYVEVOU0lPTl9FTEVNRU5UX0VSUiwKLSAgICAgICAgIlx1NUY1M1x1NUI4OVx1NTE2OFx1NTkwNFx1NzQwNlx1NTI5Rlx1ODBGRFx1OEJCRVx1N0Y2RVx1NEUzQVx1MjAxQ1x1NzcxRlx1MjAxRFx1NjVGNiwgXHU0RTBEXHU1MTQxXHU4QkI4XHU0RjdGXHU3NTI4XHU2MjY5XHU1QzU1XHU1MTQzXHU3RDIwICcnezB9JydcdTMwMDIifSwKLSAgICB9OwotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ydW50aW1lL0Vycm9yTWVzc2FnZXNfemhfVFcuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9FcnJvck1lc3NhZ2VzX3poX1RXLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDY3ZTM4MzEuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ydW50aW1lL0Vycm9yTWVzc2FnZXNfemhfVFcuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI4NCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnJ1bnRpbWU7Ci0KLWltcG9ydCBqYXZhLnV0aWwuTGlzdFJlc291cmNlQnVuZGxlOwotCi0vKioKLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICovCi1wdWJsaWMgY2xhc3MgRXJyb3JNZXNzYWdlc196aF9UVyBleHRlbmRzIExpc3RSZXNvdXJjZUJ1bmRsZSB7Ci0KLS8qCi0gKiBYU0xUQyBydW4tdGltZSBlcnJvciBtZXNzYWdlcy4KLSAqCi0gKiBHZW5lcmFsIG5vdGVzIHRvIHRyYW5zbGF0b3JzIGFuZCBkZWZpbml0aW9uczoKLSAqCi0gKiAgIDEpIFhTTFRDIGlzIHRoZSBuYW1lIG9mIHRoZSBwcm9kdWN0LiAgSXQgaXMgYW4gYWNyb255bSBmb3IgWE1MIFN0eWxlc2hlZXQ6Ci0gKiAgICAgIFRyYW5zZm9ybWF0aW9ucyBDb21waWxlcgotICoKLSAqICAgMikgQSBzdHlsZXNoZWV0IGlzIGEgZGVzY3JpcHRpb24gb2YgaG93IHRvIHRyYW5zZm9ybSBhbiBpbnB1dCBYTUwgZG9jdW1lbnQKLSAqICAgICAgaW50byBhIHJlc3VsdGFudCBvdXRwdXQgWE1MIGRvY3VtZW50IChvciBIVE1MIGRvY3VtZW50IG9yIHRleHQpCi0gKgotICogICAzKSBBbiBheGlzIGlzIGEgcGFydGljdWxhciAiZGltZW5zaW9uIiBpbiBhIHRyZWUgcmVwcmVzZW50YXRpb24gb2YgYW4gWE1MCi0gKiAgICAgIGRvY3VtZW50OyB0aGUgbm9kZXMgaW4gdGhlIHRyZWUgYXJlIGRpdmlkZWQgYWxvbmcgZGlmZmVyZW50IGF4ZXMuCi0gKiAgICAgIFRyYXZlcnNpbmcgdGhlICJjaGlsZCIgYXhpcywgZm9yIGluc3RhbmNlLCBtZWFucyB0aGF0IHRoZSBwcm9ncmFtCi0gKiAgICAgIHdvdWxkIHZpc2l0IGVhY2ggY2hpbGQgb2YgYSBwYXJ0aWN1bGFyIG5vZGU7IHRyYXZlcnNpbmcgdGhlICJkZXNjZW5kYW50IgotICogICAgICBheGlzIG1lYW5zIHRoYXQgdGhlIHByb2dyYW0gd291bGQgdmlzaXQgdGhlIGNoaWxkIG5vZGVzIG9mIGEgcGFydGljdWxhcgotICogICAgICBub2RlLCB0aGVpciBjaGlsZHJlbiwgYW5kIHNvIG9uIHVudGlsIHRoZSBsZWFmIG5vZGVzIG9mIHRoZSB0cmVlIGFyZQotICogICAgICByZWFjaGVkLgotICoKLSAqICAgNCkgQW4gaXRlcmF0b3IgaXMgYW4gb2JqZWN0IHRoYXQgdHJhdmVyc2VzIG5vZGVzIGluIGEgdHJlZSBhbG9uZyBhCi0gKiAgICAgIHBhcnRpY3VsYXIgYXhpcywgb25lIGF0IGEgdGltZS4KLSAqCi0gKiAgIDUpIEFuIGVsZW1lbnQgaXMgYSBtYXJrLXVwIHRhZyBpbiBhbiBYTUwgZG9jdW1lbnQ7IGFuIGF0dHJpYnV0ZSBpcyBhCi0gKiAgICAgIG1vZGlmaWVyIG9uIHRoZSB0YWcuICBGb3IgZXhhbXBsZSwgaW4gPGVsZW0gYXR0cj0ndmFsJyBhdHRyMj0ndmFsMic+Ci0gKiAgICAgICJlbGVtIiBpcyBhbiBlbGVtZW50IG5hbWUsICJhdHRyIiBhbmQgImF0dHIyIiBhcmUgYXR0cmlidXRlIG5hbWVzIHdpdGgKLSAqICAgICAgdGhlIHZhbHVlcyAidmFsIiBhbmQgInZhbDIiLCByZXNwZWN0aXZlbHkuCi0gKgotICogICA2KSBBIG5hbWVzcGFjZSBkZWNsYXJhdGlvbiBpcyBhIHNwZWNpYWwgYXR0cmlidXRlIHRoYXQgaXMgdXNlZCB0byBhc3NvY2lhdGUKLSAqICAgICAgYSBwcmVmaXggd2l0aCBhIFVSSSAodGhlIG5hbWVzcGFjZSkuICBUaGUgbWVhbmluZ3Mgb2YgZWxlbWVudCBuYW1lcyBhbmQKLSAqICAgICAgYXR0cmlidXRlIG5hbWVzIHRoYXQgdXNlIHRoYXQgcHJlZml4IGFyZSBkZWZpbmVkIHdpdGggcmVzcGVjdCB0byB0aGF0Ci0gKiAgICAgIG5hbWVzcGFjZS4KLSAqCi0gKiAgIDcpIERPTSBpcyBhbiBhY3JvbnltIGZvciBEb2N1bWVudCBPYmplY3QgTW9kZWwuICBJdCBpcyBhIHRyZWUKLSAqICAgICAgcmVwcmVzZW50YXRpb24gb2YgYW4gWE1MIGRvY3VtZW50LgotICoKLSAqICAgICAgU0FYIGlzIGFuIGFjcm9ueW0gZm9yIHRoZSBTaW1wbGUgQVBJIGZvciBYTUwgcHJvY2Vzc2luZy4gIEl0IGlzIGFuIEFQSQotICogICAgICB1c2VkIGluZm9ybSBhbiBYTUwgcHJvY2Vzc29yIChpbiB0aGlzIGNhc2UgWFNMVEMpIG9mIHRoZSBzdHJ1Y3R1cmUgYW5kCi0gKiAgICAgIGNvbnRlbnQgb2YgYW4gWE1MIGRvY3VtZW50LgotICoKLSAqICAgICAgSW5wdXQgdG8gdGhlIHN0eWxlc2hlZXQgcHJvY2Vzc29yIGNhbiBjb21lIGZyb20gYW4gWE1MIHBhcnNlciBpbiB0aGUKLSAqICAgICAgZm9ybSBvZiBhIERPTSB0cmVlIG9yIHRocm91Z2ggdGhlIFNBWCBBUEkuCi0gKgotICogICA4KSBEVEQgaXMgYSBkb2N1bWVudCB0eXBlIGRlY2xhcmF0aW9uLiAgSXQgaXMgYSB3YXkgb2Ygc3BlY2lmeWluZyB0aGUKLSAqICAgICAgZ3JhbW1hciBmb3IgYW4gWE1MIGZpbGUsIHRoZSBuYW1lcyBhbmQgdHlwZXMgb2YgZWxlbWVudHMsIGF0dHJpYnV0ZXMsCi0gKiAgICAgIGV0Yy4KLSAqCi0gKiAgIDkpIFRyYW5zbGV0IGlzIGFuIGludmVudGVkIHRlcm0gdGhhdCByZWZlcnMgdG8gdGhlIGNsYXNzIGZpbGUgdGhhdCBjb250YWlucwotICogICAgICB0aGUgY29tcGlsZWQgZm9ybSBvZiBhIHN0eWxlc2hlZXQuCi0gKi8KLQotICAgIC8vIFRoZXNlIG1lc3NhZ2Ugc2hvdWxkIGJlIHJlYWQgZnJvbSBhIGxvY2FsZS1zcGVjaWZpYyByZXNvdXJjZSBidW5kbGUKLSAgICAvKiogR2V0IHRoZSBsb29rdXAgdGFibGUgZm9yIGVycm9yIG1lc3NhZ2VzLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgbWVzc2FnZSBsb29rdXAgdGFibGUuCi0gICAgICovCi0gICAgcHVibGljIE9iamVjdFtdW10gZ2V0Q29udGVudHMoKQotICAgIHsKLSAgICAgICAgcmV0dXJuIG5ldyBPYmplY3RbXVtdIHsKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgdGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGluIHRoZSBmb2xsb3dpbmcgbWVzc2FnZQotICAgICAgICAgKiBpcyBhIGNsYXNzIG5hbWUuICBVc2VkIGZvciBpbnRlcm5hbCBlcnJvcnMgaW4gdGhlIHByb2Nlc3Nvci4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuUlVOX1RJTUVfSU5URVJOQUxfRVJSLAotICAgICAgICAiJyd7MH0nJyBcdTRFMkRcdTc2ODRcdTU3RjdcdTg4NENcdTk2OEVcdTZCQjVcdTUxNjdcdTkwRThcdTkzMkZcdThBQTQifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgPHhzbDpjb3B5PiBpcyBhIGtleXdvcmQgdGhhdCBzaG91bGQgbm90IGJlCi0gICAgICAgICAqIHRyYW5zbGF0ZWQuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LlJVTl9USU1FX0NPUFlfRVJSLAotICAgICAgICAiXHU1N0Y3XHU4ODRDIDx4c2w6Y29weT4gXHU2NjQyXHU3NjdDXHU3NTFGXHU1N0Y3XHU4ODRDXHU5NjhFXHU2QkI1XHU5MzJGXHU4QUE0In0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCByZWZlcnMgdG8gZGF0YSB0eXBlcy4KLSAgICAgICAgICogVGhlIG1lc3NhZ2UgaXMgZGlzcGxheWVkIGlmIGEgdmFsdWUgaW4gYSBwYXJ0aWN1bGFyIGNvbnRleHQgbmVlZHMgdG8KLSAgICAgICAgICogYmUgY29udmVydGVkIHRvIHR5cGUgezF9LCBidXQgdGhhdCdzIG5vdCBwb3NzaWJsZSBmb3IgYSB2YWx1ZSBvZiB0eXBlCi0gICAgICAgICAqIHswfS4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuREFUQV9DT05WRVJTSU9OX0VSUiwKLSAgICAgICAgIlx1NUY5RSAnJ3swfScnIFx1ODFGMyAnJ3sxfScnIFx1NzY4NFx1OEY0OVx1NjNEQlx1NzEyMVx1NjU0OFx1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgZGlzcGxheWVkIGlmIHRoZSBmdW5jdGlvbiBuYW1lZAotICAgICAgICAgKiBieSB0aGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgbm90IGEgZnVuY3Rpb24gdGhhdCBpcyBzdXBwb3J0ZWQuICBYU0xUQwotICAgICAgICAgKiBpcyB0aGUgYWNyb255bSBuYW1pbmcgdGhlIHByb2R1Y3QuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LkVYVEVSTkFMX0ZVTkNfRVJSLAotICAgICAgICAiWFNMVEMgXHU0RTBEXHU2NTJGXHU2M0Y0XHU1OTE2XHU5MEU4XHU1MUZEXHU2NTc4ICcnezB9JydcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIGRpc3BsYXllZCBpZiB0d28gdmFsdWVzIGFyZQotICAgICAgICAgKiBjb21wYXJlZCBmb3IgZXF1YWxpdHksIGJ1dCB0aGUgZGF0YSB0eXBlIG9mIG9uZSBvZiB0aGUgdmFsdWVzIGlzCi0gICAgICAgICAqIHVua25vd24uCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LkVRVUFMSVRZX0VYUFJfRVJSLAotICAgICAgICAiXHU3NkY4XHU3QjQ5XHU2MDI3XHU4ODY4XHU3OTNBXHU1RjBGXHU0RTJEXHU3Njg0XHU1RjE1XHU2NTc4XHU5ODVFXHU1NzhCXHU0RTBEXHU2NjBFXHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBmb3IgezB9IHdpbGwgYmUgYSBkYXRhCi0gICAgICAgICAqIHR5cGU7IHRoZSBzdWJzdGl0dXRpb24gdGV4dCBmb3IgezF9IHdpbGwgYmUgdGhlIG5hbWUgb2YgYSBmdW5jdGlvbi4KLSAgICAgICAgICogVGhpcyBpcyBkaXNwbGF5ZWQgaWYgYW4gYXJndW1lbnQgb2YgdGhlIHBhcnRpY3VsYXIgZGF0YSB0eXBlIGlzIG5vdAotICAgICAgICAgKiBwZXJtaXR0ZWQgZm9yIGEgY2FsbCB0byB0aGlzIGZ1bmN0aW9uLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5JTlZBTElEX0FSR1VNRU5UX0VSUiwKLSAgICAgICAgIlx1NTQ3Q1x1NTNFQiAnJ3sxfScnIFx1NEUyRFx1NzY4NFx1NUYxNVx1NjU3OFx1OTg1RVx1NTc4QiAnJ3swfScnIFx1NzEyMVx1NjU0OCJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGVyZSBpcyB3YXkgb2Ygc3BlY2lmeWluZyBhIGZvcm1hdCBmb3IgYQotICAgICAgICAgKiBudW1iZXIgdXNpbmcgYSBwYXR0ZXJuOyB0aGUgcHJvY2Vzc29yIHdhcyB1bmFibGUgdG8gZm9ybWF0IHRoZQotICAgICAgICAgKiBwYXJ0aWN1bGFyIHZhbHVlIHVzaW5nIHRoZSBzcGVjaWZpZWQgcGF0dGVybi4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuRk9STUFUX05VTUJFUl9FUlIsCi0gICAgICAgICJcdTU2MTdcdThBNjZcdTRGN0ZcdTc1MjhcdTZBMjNcdTVGMEYgJyd7MX0nJyBcdTY4M0NcdTVGMEZcdTUzMTZcdTY1NzhcdTVCNTcgJyd7MH0nJ1x1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIHJlcHJlc2VudHMgYW4gaW50ZXJuYWwgZXJyb3IKLSAgICAgICAgICogc2l0dWF0aW9uIGluIFhTTFRDLiAgVGhlIHByb2Nlc3NvciB3YXMgdW5hYmxlIHRvIGNyZWF0ZSBhIGNvcHkgb2YgYW4KLSAgICAgICAgICogaXRlcmF0b3IuICAoU2VlIGRlZmluaXRpb24gb2YgaXRlcmF0b3IgYWJvdmUuKQotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5JVEVSQVRPUl9DTE9ORV9FUlIsCi0gICAgICAgICJcdTcxMjFcdTZDRDVcdTg5MDdcdTg4RkRcdTkxQ0RcdTg5MDdcdTdBMEJcdTVGMEYgJyd7MH0nJ1x1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIHJlcHJlc2VudHMgYW4gaW50ZXJuYWwgZXJyb3IKLSAgICAgICAgICogc2l0dWF0aW9uIGluIFhTTFRDLiAgVGhlIHByb2Nlc3NvciBhdHRlbXB0ZWQgdG8gY3JlYXRlIGFuIGl0ZXJhdG9yCi0gICAgICAgICAqIGZvciBhIHBhcnRpY3VsYXIgYXhpcyAoc2VlIGRlZmluaXRpb24gYWJvdmUpIHRoYXQgaXQgZG9lcyBub3QKLSAgICAgICAgICogc3VwcG9ydC4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuQVhJU19TVVBQT1JUX0VSUiwKLSAgICAgICAgIlx1NEUwRFx1NjUyRlx1NjNGNFx1OEVGOCAnJ3swfScnIFx1NzY4NFx1OTFDRFx1ODkwN1x1N0EwQlx1NUYwRlx1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgZm9sbG93aW5nIHJlcHJlc2VudHMgYW4gaW50ZXJuYWwgZXJyb3IKLSAgICAgICAgICogc2l0dWF0aW9uIGluIFhTTFRDLiAgVGhlIHByb2Nlc3NvciBhdHRlbXB0ZWQgdG8gY3JlYXRlIGFuIGl0ZXJhdG9yCi0gICAgICAgICAqIGZvciBhIHBhcnRpY3VsYXIgYXhpcyAoc2VlIGRlZmluaXRpb24gYWJvdmUpIHRoYXQgaXQgZG9lcyBub3QKLSAgICAgICAgICogc3VwcG9ydC4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuVFlQRURfQVhJU19TVVBQT1JUX0VSUiwKLSAgICAgICAgIlx1NEUwRFx1NjUyRlx1NjNGNFx1OTg1RVx1NTc4Qlx1OEVGOCAnJ3swfScnIFx1NzY4NFx1OTFDRFx1ODkwN1x1N0EwQlx1NUYwRlx1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgcmVwb3J0ZWQgaWYgdGhlIHN0eWxlc2hlZXQKLSAgICAgICAgICogYmVpbmcgcHJvY2Vzc2VkIGF0dGVtcHRlZCB0byBjb25zdHJ1Y3QgYW4gWE1MIGRvY3VtZW50IHdpdGggYW4KLSAgICAgICAgICogYXR0cmlidXRlIGluIGEgcGxhY2Ugb3RoZXIgdGhhbiBvbiBhbiBlbGVtZW50LiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgICAqIHNwZWNpZmllcyB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5TVFJBWV9BVFRSSUJVVEVfRVJSLAotICAgICAgICAiXHU1QzZDXHU2MDI3ICcnezB9JycgXHU1NzI4XHU1MTQzXHU3RDIwXHU0RTRCXHU1OTE2XHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFzIHdpdGggdGhlIHByZWNlZGluZyBtZXNzYWdlLCBhIG5hbWVzcGFjZQotICAgICAgICAgKiBkZWNsYXJhdGlvbiBoYXMgdGhlIGZvcm0gb2YgYW4gYXR0cmlidXRlIGFuZCBpcyBvbmx5IHBlcm1pdHRlZCB0bwotICAgICAgICAgKiBhcHBlYXIgb24gYW4gZWxlbWVudC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCB7MH0gaXMgdGhlIG5hbWVzcGFjZQotICAgICAgICAgKiBwcmVmaXggYW5kIHsxfSBpcyB0aGUgVVJJIHRoYXQgd2FzIGJlaW5nIHVzZWQgaW4gdGhlIGVycm9uZW91cwotICAgICAgICAgKiBuYW1lc3BhY2UgZGVjbGFyYXRpb24uCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LlNUUkFZX05BTUVTUEFDRV9FUlIsCi0gICAgICAgICJcdTU0N0RcdTU0MERcdTdBN0FcdTk1OTNcdTVCQTNcdTU0NEEgJyd7MH0nJz0nJ3sxfScnIFx1OEQ4NVx1NTFGQVx1NTE0M1x1N0QyMFx1NTkxNlx1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3R5bGVzaGVldCBjb250YWluZWQgYSByZWZlcmVuY2UgdG8gYQotICAgICAgICAgKiBuYW1lc3BhY2UgcHJlZml4IHRoYXQgd2FzIHVuZGVmaW5lZC4gIFRoZSB2YWx1ZSBvZiB0aGUgc3Vic3RpdHV0aW9uCi0gICAgICAgICAqIHRleHQgaXMgdGhlIG5hbWUgb2YgdGhlIHByZWZpeC4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuTkFNRVNQQUNFX1BSRUZJWF9FUlIsCi0gICAgICAgICJcdTVCNTdcdTk5OTYgJyd7MH0nJyBcdTc2ODRcdTU0N0RcdTU0MERcdTdBN0FcdTk1OTNcdTVDMUFcdTY3MkFcdTVCQTNcdTU0NEFcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyByZXByZXNlbnRzIGFuIGludGVybmFsIGVycm9yLgotICAgICAgICAgKiBET01BZGFwdGVyIGlzIGEgSmF2YSBjbGFzcyBpbiBYU0xUQy4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuRE9NX0FEQVBURVJfSU5JVF9FUlIsCi0gICAgICAgICJcdTRGN0ZcdTc1MjhcdTkzMkZcdThBQTRcdTc2ODRcdTRGODZcdTZFOTAgRE9NIFx1OTg1RVx1NTc4Qlx1NUVGQVx1N0FDQiBET01BZGFwdGVyXHUzMDAyIn0sCi0KLSAgICAgICAgLyoKLSAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBmb2xsb3dpbmcgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUgWE1MCi0gICAgICAgICAqIHBhcnNlciB0aGF0IGlzIHByb3ZpZGluZyBpbnB1dCB0byBYU0xUQyBjYW5ub3QgYmUgdXNlZCBiZWNhdXNlIGl0Ci0gICAgICAgICAqIGRvZXMgbm90IGRlc2NyaWJlIHRvIFhTTFRDIHRoZSBzdHJ1Y3R1cmUgb2YgdGhlIGlucHV0IFhNTCBkb2N1bWVudCdzCi0gICAgICAgICAqIERURC4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuUEFSU0VSX0RURF9TVVBQT1JUX0VSUiwKLSAgICAgICAgIlx1NjBBOFx1NkI2M1x1NTcyOFx1NEY3Rlx1NzUyOFx1NzY4NCBTQVggXHU1MjU2XHU2NzkwXHU1NjY4XHU0RTBEXHU2NzAzXHU4NjU1XHU3NDA2IERURCBcdTVCQTNcdTU0NEFcdTRFOEJcdTRFRjZcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIGZvbGxvd2luZyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoZSBYTUwKLSAgICAgICAgICogcGFyc2VyIHRoYXQgaXMgcHJvdmlkaW5nIGlucHV0IHRvIFhTTFRDIGNhbm5vdCBiZSB1c2VkIGJlY2F1c2UgaXQKLSAgICAgICAgICogZG9lcyBub3QgZGlzdGluZ3Vpc2ggYmV0d2VlbiBvcmRpbmFyeSBYTUwgYXR0cmlidXRlcyBhbmQgbmFtZXNwYWNlCi0gICAgICAgICAqIGRlY2xhcmF0aW9ucy4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuTkFNRVNQQUNFU19TVVBQT1JUX0VSUiwKLSAgICAgICAgIlx1NjBBOFx1NkI2M1x1NTcyOFx1NEY3Rlx1NzUyOFx1NzY4NCBTQVggXHU1MjU2XHU2NzkwXHU1NjY4XHU0RTBEXHU2NTJGXHU2M0Y0IFhNTCBcdTU0N0RcdTU0MERcdTdBN0FcdTk1OTNcdTMwMDIifSwKLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBVUkkgdGhhdCB3YXMgaW4KLSAgICAgICAgICogZXJyb3IuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LkNBTlRfUkVTT0xWRV9SRUxBVElWRV9VUklfRVJSLAotICAgICAgICAiXHU3MTIxXHU2Q0Q1XHU4OUUzXHU2NzkwIFVSSSBcdTUzQzNcdTcxNjcgJyd7MH0nJ1x1MzAwMiJ9LAotCi0gICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN0eWxlc2hlZXQgY29udGFpbmVkIGFuIGVsZW1lbnQgdGhhdCB3YXMKLSAgICAgICAgICogbm90IHJlY29nbml6ZWQgYXMgcGFydCBvZiB0aGUgWFNMIHN5bnRheC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICAgKiBnaXZlcyB0aGUgZWxlbWVudCBuYW1lLgotICAgICAgICAgKi8KLSAgICAgICAge0Jhc2lzTGlicmFyeS5VTlNVUFBPUlRFRF9YU0xfRVJSLAotICAgICAgICAiXHU0RTBEXHU2NTJGXHU2M0Y0XHU3Njg0IFhTTCBcdTUxNDNcdTdEMjAgJyd7MH0nJyJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3R5bGVzaGVldCByZWZlcnJlZCB0byBhbiBleHRlbnNpb24gdG8gdGhlCi0gICAgICAgICAqIFhTTCBzeW50YXggYW5kIGluZGljYXRlZCB0aGF0IGl0IHdhcyBkZWZpbmVkIGJ5IFhTTFRDLCBidXQgWFNMVEMgZG9lcwotICAgICAgICAgKiBub3QgcmVjb2duaXplIHRoZSBwYXJ0aWN1bGFyIGV4dGVuc2lvbiBuYW1lZC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICAgKiBnaXZlcyB0aGUgZXh0ZW5zaW9uIG5hbWUuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LlVOU1VQUE9SVEVEX0VYVF9FUlIsCi0gICAgICAgICJcdTcxMjFcdTZDRDVcdThGQThcdThCNThcdTc2ODQgWFNMVEMgXHU2NEY0XHU1MTQ1XHU1OTU3XHU0RUY2ICcnezB9JycifSwKLQotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIGVycm9yIG1lc3NhZ2UgaXMgcHJvZHVjZWQgaWYgdGhlIHRyYW5zbGV0Ci0gICAgICAgICAqIGNsYXNzIHdhcyBjb21waWxlZCB1c2luZyBhIG5ld2VyIHZlcnNpb24gb2YgWFNMVEMgYW5kIGRlcGxveWVkIGZvcgotICAgICAgICAgKiBleGVjdXRpb24gd2l0aCBhbiBvbGRlciB2ZXJzaW9uIG9mIFhTTFRDLiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzCi0gICAgICAgICAqIHRoZSBuYW1lIG9mIHRoZSB0cmFuc2xldCBjbGFzcy4KLSAgICAgICAgICovCi0gICAgICAgIHtCYXNpc0xpYnJhcnkuVU5LTk9XTl9UUkFOU0xFVF9WRVJTSU9OX0VSUiwKLSAgICAgICAgIlx1NUVGQVx1N0FDQlx1NjMwN1x1NUI5QSB0cmFuc2xldCAnJ3swfScnIFx1NzY4NCBYU0xUQyBcdTcyNDhcdTY3MkNcdTZCRDRcdTRGN0ZcdTc1MjhcdTRFMkQgWFNMVEMgXHU1N0Y3XHU4ODRDXHU5NjhFXHU2QkI1XHU3Njg0XHU3MjQ4XHU2NzJDXHU4RjAzXHU2NUIwXHUzMDAyXHU2MEE4XHU1RkM1XHU5ODA4XHU5MUNEXHU2NUIwXHU3REU4XHU4QjZGXHU2QTIzXHU1RjBGXHU4ODY4XHVGRjBDXHU2MjE2XHU0RjdGXHU3NTI4XHU4RjAzXHU2NUIwXHU3Njg0IFhTTFRDIFx1NzI0OFx1NjcyQ1x1NEY4Nlx1NTdGN1x1ODg0Q1x1NkI2NCB0cmFuc2xldFx1MzAwMiJ9LAotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBbiBhdHRyaWJ1dGUgd2hvc2UgZWZmZWN0aXZlIHZhbHVlIGlzIHJlcXVpcmVkCi0gICAgICAgICAqIHRvIGJlIGEgIlFOYW1lIiBoYWQgYSB2YWx1ZSB0aGF0IHdhcyBpbmNvcnJlY3QuCi0gICAgICAgICAqICdRTmFtZScgaXMgYW4gWE1MIHN5bnRhY3RpYyB0ZXJtIHRoYXQgbXVzdCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoZQotICAgICAgICAgKiBzdWJzdGl0dXRpb24gdGV4dCBjb250YWlucyB0aGUgYWN0dWFsIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LklOVkFMSURfUU5BTUVfRVJSLAotICAgICAgICAiXHU1MDNDXHU1RkM1XHU5ODA4XHU3MEJBIFFOYW1lIFx1NzY4NFx1NUM2Q1x1NjAyN1x1RkYwQ1x1NTE3N1x1NjcwOVx1NTAzQyAnJ3swfScnIn0sCi0KLQotICAgICAgICAvKgotICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQW4gYXR0cmlidXRlIHdob3NlIGVmZmVjdGl2ZSB2YWx1ZSBpcyByZXF1aXJlZAotICAgICAgICAgKiB0byBiZSBhICJOQ05hbWUiIGhhZCBhIHZhbHVlIHRoYXQgd2FzIGluY29ycmVjdC4KLSAgICAgICAgICogJ05DTmFtZScgaXMgYW4gWE1MIHN5bnRhY3RpYyB0ZXJtIHRoYXQgbXVzdCBub3QgYmUgdHJhbnNsYXRlZC4gIFRoZQotICAgICAgICAgKiBzdWJzdGl0dXRpb24gdGV4dCBjb250YWlucyB0aGUgYWN0dWFsIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUuCi0gICAgICAgICAqLwotICAgICAgICB7QmFzaXNMaWJyYXJ5LklOVkFMSURfTkNOQU1FX0VSUiwKLSAgICAgICAgIlx1NTAzQ1x1NUZDNVx1OTgwOFx1NzBCQSBOQ05hbWUgXHU3Njg0XHU1QzZDXHU2MDI3XHVGRjBDXHU1MTc3XHU2NzA5XHU1MDNDICcnezB9JycifSwKLQotICAgICAgICB7QmFzaXNMaWJyYXJ5LlVOQUxMT1dFRF9FWFRFTlNJT05fRlVOQ1RJT05fRVJSLAotICAgICAgICAiXHU3NTc2XHU1Qjg5XHU1MTY4XHU4NjU1XHU3NDA2XHU1MjlGXHU4MEZEXHU4QTJEXHU3MEJBXHU3NzFGXHU2NjQyXHVGRjBDXHU0RTBEXHU1MTQxXHU4QTMxXHU0RjdGXHU3NTI4XHU2NEY0XHU1MTQ1XHU1OTU3XHU0RUY2XHU1MUZEXHU2NTc4ICcnezB9JydcdTMwMDIifSwKLQotICAgICAgICB7QmFzaXNMaWJyYXJ5LlVOQUxMT1dFRF9FWFRFTlNJT05fRUxFTUVOVF9FUlIsCi0gICAgICAgICJcdTc1NzZcdTVCODlcdTUxNjhcdTg2NTVcdTc0MDZcdTUyOUZcdTgwRkRcdThBMkRcdTcwQkFcdTc3MUZcdTY2NDJcdUZGMENcdTRFMERcdTUxNDFcdThBMzFcdTRGN0ZcdTc1MjhcdTY0RjRcdTUxNDVcdTU5NTdcdTRFRjZcdTUxNDNcdTdEMjAgJyd7MH0nJ1x1MzAwMiJ9LAotICAgIH07Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvSW50ZXJuYWxSdW50aW1lRXJyb3IuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9JbnRlcm5hbFJ1bnRpbWVFcnJvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxZjExNzg4Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9JbnRlcm5hbFJ1bnRpbWVFcnJvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzYgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi0vKgotICogJElkOiBJbnRlcm5hbFJ1bnRpbWVFcnJvci5qYXZhLHYgMS4wIDIwMDktMTEtMjUgMDQ6MzQ6Mjggam9laHcgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMucnVudGltZTsKLQotLyoqCi0gKiBDbGFzcyB0byBleHByZXNzIGZhaWxlZCBhc3NlcnRpb25zIGFuZCBzaW1pbGFyIGZvciB0aGUgeHNsdGMgcnVudGltZS4KLSAqIEFzIGphdmEubGFuZy5Bc3NlcnRpb25FcnJvciB3YXMgaW50cm9kdWNlZCBpbiBKREsgMS40IHdlIGNhbid0IHVzZSB0aGF0IHlldC4KLSAqLwotcHVibGljIGNsYXNzIEludGVybmFsUnVudGltZUVycm9yIGV4dGVuZHMgRXJyb3IgewotCi0gICAgcHVibGljIEludGVybmFsUnVudGltZUVycm9yKFN0cmluZyBtZXNzYWdlKSB7Ci0gICAgICAgIHN1cGVyKG1lc3NhZ2UpOwotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ydW50aW1lL01lc3NhZ2VIYW5kbGVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvTWVzc2FnZUhhbmRsZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZGEyMjdmNS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvTWVzc2FnZUhhbmRsZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDMzICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IE1lc3NhZ2VIYW5kbGVyLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMDYgMTE6MDY6NDkgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnJ1bnRpbWU7Ci0KLS8qKgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKi8KLXB1YmxpYyBjbGFzcyBNZXNzYWdlSGFuZGxlciB7Ci0gICAgcHVibGljIHZvaWQgZGlzcGxheU1lc3NhZ2UoU3RyaW5nIG1zZykgewotICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4obXNnKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvTm9kZS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ydW50aW1lL05vZGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYWRkNDExNC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvTm9kZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDAgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogTm9kZS5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzA2IDExOjEwOjI5IHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5ydW50aW1lOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgaXMgdXNlZCBhcyAid3JhcHBlciIgZm9yIGRvbSBub2Rlcy4gV3JhcHBlcnMgYXJlIG5lZWRlZCB3aGVuCi0gKiBhIG5vZGUgaXMgcGFzc2VkIGFzIGEgcGFyYW1ldGVyIHRvIGEgdGVtcGxhdGUuCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKi8KLXB1YmxpYyBjbGFzcyBOb2RlIHsKLSAgICBwdWJsaWMgaW50IG5vZGU7Ci0gICAgcHVibGljIGludCB0eXBlOwotCi0gICAgcHVibGljIE5vZGUoaW50IG4sIGludCB0KSB7Ci0gICAgICAgIG5vZGUgPSBuOwotICAgICAgICB0eXBlID0gdDsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvT3BlcmF0b3JzLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvT3BlcmF0b3JzLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGRhNzFmOGMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ydW50aW1lL09wZXJhdG9ycy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNjAgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogT3BlcmF0b3JzLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTIgMTI6MDI6MTUgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnJ1bnRpbWU7Ci0KLS8qKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgT3BlcmF0b3JzIHsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUSA9IDA7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTkUgPSAxOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEdUID0gMjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMVCA9IDM7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgR0UgPSA0OwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExFID0gNTsKLQotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZ1tdIG5hbWVzID0gewotICAgICI9IiwgIiE9IiwgIj4iLCAiPCIsICI+PSIsICI8PSIKLSAgICB9OwotCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgZ2V0T3BOYW1lcyhpbnQgb3BlcmF0b3IpIHsKLSAgICAgICAgICByZXR1cm4gbmFtZXNbb3BlcmF0b3JdOwotICAgIH0KLQotLy8gIFN3YXAgb3BlcmF0b3IgYXJyYXkKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnRbXSBzd2FwT3BBcnJheSA9IHsKLSAgICAgICAgRVEsICAgICAvLyBFUQotICAgICAgICBORSwgICAgIC8vIE5FCi0gICAgICAgIExULCAgICAgLy8gR1QKLSAgICAgICAgR1QsICAgICAvLyBMVAotICAgICAgICBMRSwgICAgIC8vIEdFCi0gICAgICAgIEdFICAgICAgLy8gTEUKLSAgICB9OwotCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgc3dhcE9wKGludCBvcGVyYXRvcikgewotICAgICAgICAgIHJldHVybiBzd2FwT3BBcnJheVtvcGVyYXRvcl07Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvUGFyYW1ldGVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvUGFyYW1ldGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGUzYjY4MmQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ydW50aW1lL1BhcmFtZXRlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDggKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogUGFyYW1ldGVyLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMDYgMTE6MjE6NTggcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnJ1bnRpbWU7Ci0KLS8qKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKi8KLXB1YmxpYyBjbGFzcyBQYXJhbWV0ZXIgewotCi0gICAgcHVibGljIFN0cmluZyAgX25hbWU7Ci0gICAgcHVibGljIE9iamVjdCAgX3ZhbHVlOwotICAgIHB1YmxpYyBib29sZWFuIF9pc0RlZmF1bHQ7Ci0KLSAgICBwdWJsaWMgUGFyYW1ldGVyKFN0cmluZyBuYW1lLCBPYmplY3QgdmFsdWUpIHsKLSAgICAgICAgX25hbWUgPSBuYW1lOwotICAgICAgICBfdmFsdWUgPSB2YWx1ZTsKLSAgICAgICAgX2lzRGVmYXVsdCA9IHRydWU7Ci0gICAgfQotCi0gICAgcHVibGljIFBhcmFtZXRlcihTdHJpbmcgbmFtZSwgT2JqZWN0IHZhbHVlLCBib29sZWFuIGlzRGVmYXVsdCkgewotICAgICAgICBfbmFtZSA9IG5hbWU7Ci0gICAgICAgIF92YWx1ZSA9IHZhbHVlOwotICAgICAgICBfaXNEZWZhdWx0ID0gaXNEZWZhdWx0OwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9TdHJpbmdWYWx1ZUhhbmRsZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9TdHJpbmdWYWx1ZUhhbmRsZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggODMwODM1Mi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvU3RyaW5nVmFsdWVIYW5kbGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMjcgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogU3RyaW5nVmFsdWVIYW5kbGVyLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMDYgMTE6MzM6MjUgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnJ1bnRpbWU7Ci0KLWltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXIuRW1wdHlTZXJpYWxpemVyOwotCi0vKioKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgU3RyaW5nVmFsdWVIYW5kbGVyIGV4dGVuZHMgRW1wdHlTZXJpYWxpemVyIHsKLQotICAgIHByaXZhdGUgU3RyaW5nQnVpbGRlciBfYnVmZmVyID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKLSAgICBwcml2YXRlIFN0cmluZyBfc3RyID0gbnVsbDsKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRU1QVFlfU1RSID0gIiI7Ci0gICAgcHJpdmF0ZSBib29sZWFuIG1fZXNjYXBpbmcgPSBmYWxzZTsKLSAgICBwcml2YXRlIGludCBfbmVzdGVkTGV2ZWwgPSAwOwotCi0gICAgcHVibGljIHZvaWQgY2hhcmFjdGVycyhjaGFyW10gY2gsIGludCBvZmYsIGludCBsZW4pCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGlmIChfbmVzdGVkTGV2ZWwgPiAwKQotICAgICAgICAgICAgcmV0dXJuOwotCi0gICAgICAgIGlmIChfc3RyICE9IG51bGwpIHsKLSAgICAgICAgICAgIF9idWZmZXIuYXBwZW5kKF9zdHIpOwotICAgICAgICAgICAgX3N0ciA9IG51bGw7Ci0gICAgICAgIH0KLSAgICAgICAgX2J1ZmZlci5hcHBlbmQoY2gsIG9mZiwgbGVuKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldFZhbHVlKCkgewotICAgICAgICBpZiAoX2J1ZmZlci5sZW5ndGgoKSAhPSAwKSB7Ci0gICAgICAgICAgICBTdHJpbmcgcmVzdWx0ID0gX2J1ZmZlci50b1N0cmluZygpOwotICAgICAgICAgICAgX2J1ZmZlci5zZXRMZW5ndGgoMCk7Ci0gICAgICAgICAgICByZXR1cm4gcmVzdWx0OwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgU3RyaW5nIHJlc3VsdCA9IF9zdHI7Ci0gICAgICAgICAgICBfc3RyID0gbnVsbDsKLSAgICAgICAgICAgIHJldHVybiAocmVzdWx0ICE9IG51bGwpID8gcmVzdWx0IDogRU1QVFlfU1RSOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgY2hhcmFjdGVycyhTdHJpbmcgY2hhcmFjdGVycykgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChfbmVzdGVkTGV2ZWwgPiAwKQotICAgICAgICAgICAgcmV0dXJuOwotCi0gICAgICAgIGlmIChfc3RyID09IG51bGwgJiYgX2J1ZmZlci5sZW5ndGgoKSA9PSAwKSB7Ci0gICAgICAgICAgICBfc3RyID0gY2hhcmFjdGVyczsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIGlmIChfc3RyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBfYnVmZmVyLmFwcGVuZChfc3RyKTsKLSAgICAgICAgICAgICAgICBfc3RyID0gbnVsbDsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgX2J1ZmZlci5hcHBlbmQoY2hhcmFjdGVycyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQoU3RyaW5nIHFuYW1lKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICAgICAgX25lc3RlZExldmVsKys7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgZW5kRWxlbWVudChTdHJpbmcgcW5hbWUpIHRocm93cyBTQVhFeGNlcHRpb24gewotICAgICAgICBfbmVzdGVkTGV2ZWwtLTsKLSAgICB9Ci0KLSAgICAvLyBPdmVycmlkZSB0aGUgc2V0RXNjYXBpbmcgbWV0aG9kIGp1c3QgdG8gaW5kaWNhdGUgdGhhdCB0aGlzIGNsYXNzIGlzCi0gICAgLy8gYXdhcmUgdGhhdCB0aGF0IG1ldGhvZCBtaWdodCBiZSBjYWxsZWQuCi0gICAgcHVibGljIGJvb2xlYW4gc2V0RXNjYXBpbmcoYm9vbGVhbiBib29sKSB7Ci0gICAgICAgIGJvb2xlYW4gb2xkRXNjYXBpbmcgPSBtX2VzY2FwaW5nOwotICAgICAgICBtX2VzY2FwaW5nID0gYm9vbDsKLQotICAgICAgICByZXR1cm4gYm9vbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgdmFsdWUgb2YgYSBQSSBtdXN0IG5vdCBjb250YWluIHRoZSBzdWJzdHJpbmcgIj8+Ii4gU2hvdWxkCi0gICAgICogdGhhdCBzdWJzdHJpbmcgYmUgcHJlc2VudCwgcmVwbGFjZSBpdCBieSAiPyA+Ii4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFZhbHVlT2ZQSSgpIHsKLSAgICAgICAgZmluYWwgU3RyaW5nIHZhbHVlID0gZ2V0VmFsdWUoKTsKLQotICAgICAgICBpZiAodmFsdWUuaW5kZXhPZigiPz4iKSA+IDApIHsKLSAgICAgICAgICAgIGZpbmFsIGludCBuID0gdmFsdWUubGVuZ3RoKCk7Ci0gICAgICAgICAgICBmaW5hbCBTdHJpbmdCdWlsZGVyIHZhbHVlT2ZQSSA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7Ci0KLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjspIHsKLSAgICAgICAgICAgICAgICBmaW5hbCBjaGFyIGNoID0gdmFsdWUuY2hhckF0KGkrKyk7Ci0gICAgICAgICAgICAgICAgaWYgKGNoID09ICc/JyAmJiB2YWx1ZS5jaGFyQXQoaSkgPT0gJz4nKSB7Ci0gICAgICAgICAgICAgICAgICAgIHZhbHVlT2ZQSS5hcHBlbmQoIj8gPiIpOyBpKys7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICB2YWx1ZU9mUEkuYXBwZW5kKGNoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gdmFsdWVPZlBJLnRvU3RyaW5nKCk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHZhbHVlOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9vdXRwdXQvT3V0cHV0QnVmZmVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvb3V0cHV0L091dHB1dEJ1ZmZlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMWYxY2E5Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9vdXRwdXQvT3V0cHV0QnVmZmVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzNiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBPdXRwdXRCdWZmZXIuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8wNiAxMTozNToyMyBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMucnVudGltZS5vdXRwdXQ7Ci0KLS8qKgotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKi8KLWludGVyZmFjZSBPdXRwdXRCdWZmZXIgewotCi0gICAgcHVibGljIFN0cmluZyBjbG9zZSgpOwotICAgIHB1YmxpYyBPdXRwdXRCdWZmZXIgYXBwZW5kKGNoYXIgY2gpOwotICAgIHB1YmxpYyBPdXRwdXRCdWZmZXIgYXBwZW5kKFN0cmluZyBzKTsKLSAgICBwdWJsaWMgT3V0cHV0QnVmZmVyIGFwcGVuZChjaGFyW10gcywgaW50IGZyb20sIGludCB0byk7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9vdXRwdXQvU3RyaW5nT3V0cHV0QnVmZmVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvb3V0cHV0L1N0cmluZ091dHB1dEJ1ZmZlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyZjljNDNlLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9vdXRwdXQvU3RyaW5nT3V0cHV0QnVmZmVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw1NSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBTdHJpbmdPdXRwdXRCdWZmZXIuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8wNiAxMTozNjoxNiBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMucnVudGltZS5vdXRwdXQ7Ci0KLQotLyoqCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqLwotY2xhc3MgU3RyaW5nT3V0cHV0QnVmZmVyIGltcGxlbWVudHMgT3V0cHV0QnVmZmVyIHsKLSAgICBwcml2YXRlIFN0cmluZ0J1ZmZlciBfYnVmZmVyOwotCi0gICAgcHVibGljIFN0cmluZ091dHB1dEJ1ZmZlcigpIHsKLSAgICAgICAgX2J1ZmZlciA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGNsb3NlKCkgewotICAgICAgICByZXR1cm4gX2J1ZmZlci50b1N0cmluZygpOwotICAgIH0KLQotICAgIHB1YmxpYyBPdXRwdXRCdWZmZXIgYXBwZW5kKFN0cmluZyBzKSB7Ci0gICAgICAgIF9idWZmZXIuYXBwZW5kKHMpOwotICAgICAgICByZXR1cm4gdGhpczsKLSAgICB9Ci0KLSAgICBwdWJsaWMgT3V0cHV0QnVmZmVyIGFwcGVuZChjaGFyW10gcywgaW50IGZyb20sIGludCB0bykgewotICAgICAgICBfYnVmZmVyLmFwcGVuZChzLCBmcm9tLCB0byk7Ci0gICAgICAgIHJldHVybiB0aGlzOwotICAgIH0KLQotICAgIHB1YmxpYyBPdXRwdXRCdWZmZXIgYXBwZW5kKGNoYXIgY2gpIHsKLSAgICAgICAgX2J1ZmZlci5hcHBlbmQoY2gpOwotICAgICAgICByZXR1cm4gdGhpczsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvb3V0cHV0L1RyYW5zbGV0T3V0cHV0SGFuZGxlckZhY3RvcnkuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9vdXRwdXQvVHJhbnNsZXRPdXRwdXRIYW5kbGVyRmFjdG9yeS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4Yjc2ZjNhLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9vdXRwdXQvVHJhbnNsZXRPdXRwdXRIYW5kbGVyRmFjdG9yeS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjcyICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFRyYW5zbGV0T3V0cHV0SGFuZGxlckZhY3RvcnkuamF2YSx2IDEuMi40LjIgMjAwNS8wOS8xNSAxOToxMjowNSBqZWZmc3V0dG9yIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMucnVudGltZS5vdXRwdXQ7Ci0KLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uV3JpdGVyOwotCi1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLlhNTEV2ZW50V3JpdGVyOwotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0udXRpbC5YTUxFdmVudENvbnN1bWVyOwotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uWE1MU3RyZWFtV3JpdGVyOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnRyYXguU0FYMkRPTTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMudHJheC5TQVgyU3RBWEV2ZW50V3JpdGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy50cmF4LlNBWDJTdEFYU3RyZWFtV3JpdGVyOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyLlRvSFRNTFNBWEhhbmRsZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyLlRvSFRNTFN0cmVhbTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXIuVG9UZXh0U0FYSGFuZGxlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXIuVG9UZXh0U3RyZWFtOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplci5Ub1Vua25vd25TdHJlYW07Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyLlRvWE1MU0FYSGFuZGxlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXIuVG9YTUxTdHJlYW07Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyLlNlcmlhbGl6YXRpb25IYW5kbGVyOwotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci0KLWltcG9ydCBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXI7Ci0KLS8qKgotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKi8KLXB1YmxpYyBjbGFzcyBUcmFuc2xldE91dHB1dEhhbmRsZXJGYWN0b3J5IHsKLQotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNUUkVBTSA9IDA7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0FYICAgID0gMTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBET00gICAgPSAyOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNUQVggICA9IDM7Ci0KLSAgICBwcml2YXRlIFN0cmluZyBfZW5jb2RpbmcgICAgICAgICAgICAgICAgICAgICAgICA9ICJ1dGYtOCI7Ci0gICAgcHJpdmF0ZSBTdHJpbmcgX21ldGhvZCAgICAgICAgICAgICAgICAgICAgICAgICAgPSBudWxsOwotICAgIHByaXZhdGUgaW50ICAgIF9vdXRwdXRUeXBlICAgICAgICAgICAgICAgICAgICAgID0gU1RSRUFNOwotICAgIHByaXZhdGUgT3V0cHV0U3RyZWFtIF9vc3RyZWFtICAgICAgICAgICAgICAgICAgID0gU3lzdGVtLm91dDsKLSAgICBwcml2YXRlIFdyaXRlciBfd3JpdGVyICAgICAgICAgICAgICAgICAgICAgICAgICA9IG51bGw7Ci0gICAgcHJpdmF0ZSBOb2RlIF9ub2RlICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSBudWxsOwotICAgIHByaXZhdGUgTm9kZSAgIF9uZXh0U2libGluZyAgICAgICAgICAgICAgICAgICAgID0gbnVsbDsKLSAgICBwcml2YXRlIFhNTEV2ZW50V3JpdGVyIF94bWxTdEFYRXZlbnRXcml0ZXIgICAgICA9IG51bGw7Ci0gICAgcHJpdmF0ZSBYTUxTdHJlYW1Xcml0ZXIgX3htbFN0QVhTdHJlYW1Xcml0ZXIgICAgPSBudWxsOwotICAgIHByaXZhdGUgaW50IF9pbmRlbnROdW1iZXIgICAgICAgICAgICAgICAgICAgICAgID0gLTE7Ci0gICAgcHJpdmF0ZSBDb250ZW50SGFuZGxlciBfaGFuZGxlciAgICAgICAgICAgICAgICAgPSBudWxsOwotICAgIHByaXZhdGUgTGV4aWNhbEhhbmRsZXIgX2xleEhhbmRsZXIgICAgICAgICAgICAgID0gbnVsbDsKLQotICAgIHByaXZhdGUgYm9vbGVhbiBfdXNlU2VydmljZXNNZWNoYW5pc207Ci0KLSAgICBzdGF0aWMgcHVibGljIFRyYW5zbGV0T3V0cHV0SGFuZGxlckZhY3RvcnkgbmV3SW5zdGFuY2UoKSB7Ci0gICAgICAgIHJldHVybiBuZXcgVHJhbnNsZXRPdXRwdXRIYW5kbGVyRmFjdG9yeSh0cnVlKTsKLSAgICB9Ci0gICAgc3RhdGljIHB1YmxpYyBUcmFuc2xldE91dHB1dEhhbmRsZXJGYWN0b3J5IG5ld0luc3RhbmNlKGJvb2xlYW4gdXNlU2VydmljZXNNZWNoYW5pc20pIHsKLSAgICAgICAgcmV0dXJuIG5ldyBUcmFuc2xldE91dHB1dEhhbmRsZXJGYWN0b3J5KHVzZVNlcnZpY2VzTWVjaGFuaXNtKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgVHJhbnNsZXRPdXRwdXRIYW5kbGVyRmFjdG9yeShib29sZWFuIHVzZVNlcnZpY2VzTWVjaGFuaXNtKSB7Ci0gICAgICAgIF91c2VTZXJ2aWNlc01lY2hhbmlzbSA9IHVzZVNlcnZpY2VzTWVjaGFuaXNtOwotICAgIH0KLSAgICBwdWJsaWMgdm9pZCBzZXRPdXRwdXRUeXBlKGludCBvdXRwdXRUeXBlKSB7Ci0gICAgICAgIF9vdXRwdXRUeXBlID0gb3V0cHV0VHlwZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRFbmNvZGluZyhTdHJpbmcgZW5jb2RpbmcpIHsKLSAgICAgICAgaWYgKGVuY29kaW5nICE9IG51bGwpIHsKLSAgICAgICAgICAgIF9lbmNvZGluZyA9IGVuY29kaW5nOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0T3V0cHV0TWV0aG9kKFN0cmluZyBtZXRob2QpIHsKLSAgICAgICAgX21ldGhvZCA9IG1ldGhvZDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRPdXRwdXRTdHJlYW0oT3V0cHV0U3RyZWFtIG9zdHJlYW0pIHsKLSAgICAgICAgX29zdHJlYW0gPSBvc3RyZWFtOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldFdyaXRlcihXcml0ZXIgd3JpdGVyKSB7Ci0gICAgICAgIF93cml0ZXIgPSB3cml0ZXI7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0SGFuZGxlcihDb250ZW50SGFuZGxlciBoYW5kbGVyKSB7Ci0gICAgICAgIF9oYW5kbGVyID0gaGFuZGxlcjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRMZXhpY2FsSGFuZGxlcihMZXhpY2FsSGFuZGxlciBsZXgpIHsKLSAgICAgICAgX2xleEhhbmRsZXIgPSBsZXg7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0Tm9kZShOb2RlIG5vZGUpIHsKLSAgICAgICAgX25vZGUgPSBub2RlOwotICAgIH0KLQotICAgIHB1YmxpYyBOb2RlIGdldE5vZGUoKSB7Ci0gICAgICAgIHJldHVybiAoX2hhbmRsZXIgaW5zdGFuY2VvZiBTQVgyRE9NKSA/ICgoU0FYMkRPTSlfaGFuZGxlcikuZ2V0RE9NKCkKLSAgICAgICAgICAgOiBudWxsOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldE5leHRTaWJsaW5nKE5vZGUgbmV4dFNpYmxpbmcpIHsKLSAgICAgICAgX25leHRTaWJsaW5nID0gbmV4dFNpYmxpbmc7Ci0gICAgfQotCi0gICAgcHVibGljIFhNTEV2ZW50V3JpdGVyIGdldFhNTEV2ZW50V3JpdGVyKCkgewotICAgICAgICByZXR1cm4gKF9oYW5kbGVyIGluc3RhbmNlb2YgU0FYMlN0QVhFdmVudFdyaXRlcikgPyAoKFNBWDJTdEFYRXZlbnRXcml0ZXIpIF9oYW5kbGVyKS5nZXRFdmVudFdyaXRlcigpIDogbnVsbDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRYTUxFdmVudFdyaXRlcihYTUxFdmVudFdyaXRlciBldmVudFdyaXRlcikgewotICAgICAgICBfeG1sU3RBWEV2ZW50V3JpdGVyID0gZXZlbnRXcml0ZXI7Ci0gICAgfQotCi0gICAgcHVibGljIFhNTFN0cmVhbVdyaXRlciBnZXRYTUxTdHJlYW1Xcml0ZXIoKSB7Ci0gICAgICAgIHJldHVybiAoX2hhbmRsZXIgaW5zdGFuY2VvZiBTQVgyU3RBWFN0cmVhbVdyaXRlcikgPyAoKFNBWDJTdEFYU3RyZWFtV3JpdGVyKSBfaGFuZGxlcikuZ2V0U3RyZWFtV3JpdGVyKCkgOiBudWxsOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldFhNTFN0cmVhbVdyaXRlcihYTUxTdHJlYW1Xcml0ZXIgc3RyZWFtV3JpdGVyKSB7Ci0gICAgICAgIF94bWxTdEFYU3RyZWFtV3JpdGVyID0gc3RyZWFtV3JpdGVyOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldEluZGVudE51bWJlcihpbnQgdmFsdWUpIHsKLSAgICAgICAgX2luZGVudE51bWJlciA9IHZhbHVlOwotICAgIH0KLQotICAgIHB1YmxpYyBTZXJpYWxpemF0aW9uSGFuZGxlciBnZXRTZXJpYWxpemF0aW9uSGFuZGxlcigpCi0gICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgU2VyaWFsaXphdGlvbkhhbmRsZXIgcmVzdWx0ID0gbnVsbDsKLSAgICAgICAgc3dpdGNoIChfb3V0cHV0VHlwZSkKLSAgICAgICAgewotICAgICAgICAgICAgY2FzZSBTVFJFQU0gOgotCi0gICAgICAgICAgICAgICAgaWYgKF9tZXRob2QgPT0gbnVsbCkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IG5ldyBUb1Vua25vd25TdHJlYW0oKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSBpZiAoX21ldGhvZC5lcXVhbHNJZ25vcmVDYXNlKCJ4bWwiKSkKLSAgICAgICAgICAgICAgICB7Ci0KLSAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gbmV3IFRvWE1MU3RyZWFtKCk7Ci0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSBpZiAoX21ldGhvZC5lcXVhbHNJZ25vcmVDYXNlKCJodG1sIikpCi0gICAgICAgICAgICAgICAgewotCi0gICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IG5ldyBUb0hUTUxTdHJlYW0oKTsKLQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIGlmIChfbWV0aG9kLmVxdWFsc0lnbm9yZUNhc2UoInRleHQiKSkKLSAgICAgICAgICAgICAgICB7Ci0KLSAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gbmV3IFRvVGV4dFN0cmVhbSgpOwotCi0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgaWYgKHJlc3VsdCAhPSBudWxsICYmIF9pbmRlbnROdW1iZXIgPj0gMCkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIHJlc3VsdC5zZXRJbmRlbnRBbW91bnQoX2luZGVudE51bWJlcik7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgcmVzdWx0LnNldEVuY29kaW5nKF9lbmNvZGluZyk7Ci0KLSAgICAgICAgICAgICAgICBpZiAoX3dyaXRlciAhPSBudWxsKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgcmVzdWx0LnNldFdyaXRlcihfd3JpdGVyKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgcmVzdWx0LnNldE91dHB1dFN0cmVhbShfb3N0cmVhbSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7Ci0KLSAgICAgICAgICAgIGNhc2UgRE9NIDoKLSAgICAgICAgICAgICAgICBfaGFuZGxlciA9IChfbm9kZSAhPSBudWxsKSA/IG5ldyBTQVgyRE9NKF9ub2RlLCBfbmV4dFNpYmxpbmcsIF91c2VTZXJ2aWNlc01lY2hhbmlzbSkgOiBuZXcgU0FYMkRPTShfdXNlU2VydmljZXNNZWNoYW5pc20pOwotICAgICAgICAgICAgICAgIF9sZXhIYW5kbGVyID0gKExleGljYWxIYW5kbGVyKSBfaGFuZGxlcjsKLSAgICAgICAgICAgICAgICAvLyBmYWxscyB0aHJvdWdoCi0gICAgICAgICAgICBjYXNlIFNUQVggOgotICAgICAgICAgICAgICAgIGlmIChfeG1sU3RBWEV2ZW50V3JpdGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgX2hhbmRsZXIgPSAgbmV3IFNBWDJTdEFYRXZlbnRXcml0ZXIoX3htbFN0QVhFdmVudFdyaXRlcik7Ci0gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChfeG1sU3RBWFN0cmVhbVdyaXRlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIF9oYW5kbGVyID0gIG5ldyBTQVgyU3RBWFN0cmVhbVdyaXRlcihfeG1sU3RBWFN0cmVhbVdyaXRlcik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIF9sZXhIYW5kbGVyID0gKExleGljYWxIYW5kbGVyKSBfaGFuZGxlcjsKLSAgICAgICAgICAgICAgICAvLyBhZ2FpbiBmYWxscyB0aHJvdWdoIC0gUGFkbWFqYSBWZWR1bGEKLSAgICAgICAgICAgIGNhc2UgU0FYIDoKLSAgICAgICAgICAgICAgICBpZiAoX21ldGhvZCA9PSBudWxsKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgX21ldGhvZCA9ICJ4bWwiOyAvLyBkZWZhdWx0IGNhc2UKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBpZiAoX21ldGhvZC5lcXVhbHNJZ25vcmVDYXNlKCJ4bWwiKSkKLSAgICAgICAgICAgICAgICB7Ci0KLSAgICAgICAgICAgICAgICAgICAgaWYgKF9sZXhIYW5kbGVyID09IG51bGwpCi0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IG5ldyBUb1hNTFNBWEhhbmRsZXIoX2hhbmRsZXIsIF9lbmNvZGluZyk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBUb1hNTFNBWEhhbmRsZXIoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9oYW5kbGVyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfbGV4SGFuZGxlciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2VuY29kaW5nKTsKLSAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgaWYgKF9tZXRob2QuZXF1YWxzSWdub3JlQ2FzZSgiaHRtbCIpKQotICAgICAgICAgICAgICAgIHsKLQotICAgICAgICAgICAgICAgICAgICBpZiAoX2xleEhhbmRsZXIgPT0gbnVsbCkKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gbmV3IFRvSFRNTFNBWEhhbmRsZXIoX2hhbmRsZXIsIF9lbmNvZGluZyk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBUb0hUTUxTQVhIYW5kbGVyKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfaGFuZGxlciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2xleEhhbmRsZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9lbmNvZGluZyk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIGlmIChfbWV0aG9kLmVxdWFsc0lnbm9yZUNhc2UoInRleHQiKSkKLSAgICAgICAgICAgICAgICB7Ci0KLSAgICAgICAgICAgICAgICAgICAgaWYgKF9sZXhIYW5kbGVyID09IG51bGwpCi0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IG5ldyBUb1RleHRTQVhIYW5kbGVyKF9oYW5kbGVyLCBfZW5jb2RpbmcpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgVG9UZXh0U0FYSGFuZGxlcigKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2hhbmRsZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9sZXhIYW5kbGVyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfZW5jb2RpbmcpOwotICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9vdXRwdXQvV3JpdGVyT3V0cHV0QnVmZmVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvb3V0cHV0L1dyaXRlck91dHB1dEJ1ZmZlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyYjA0ZTAxLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9vdXRwdXQvV3JpdGVyT3V0cHV0QnVmZmVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5NyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBXcml0ZXJPdXRwdXRCdWZmZXIuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8wNiAxMTo0MzowMSBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMucnVudGltZS5vdXRwdXQ7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwudXRpbHMuU2VjdXJpdHlTdXBwb3J0OwotaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRXcml0ZXI7Ci1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLldyaXRlcjsKLQotLyoqCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqLwotY2xhc3MgV3JpdGVyT3V0cHV0QnVmZmVyIGltcGxlbWVudHMgT3V0cHV0QnVmZmVyIHsKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgS0IgPSAxMDI0OwotICAgIHByaXZhdGUgc3RhdGljIGludCBCVUZGRVJfU0laRSA9IDQgKiBLQjsKLQotICAgIHN0YXRpYyB7Ci0gICAgICAgIC8vIFNldCBhIGxhcmdlciBidWZmZXIgc2l6ZSBmb3IgU29sYXJpcwotICAgICAgICBmaW5hbCBTdHJpbmcgb3NOYW1lID0gU2VjdXJpdHlTdXBwb3J0LmdldFN5c3RlbVByb3BlcnR5KCJvcy5uYW1lIik7Ci0gICAgICAgIGlmIChvc05hbWUuZXF1YWxzSWdub3JlQ2FzZSgic29sYXJpcyIpKSB7Ci0gICAgICAgICAgICBCVUZGRVJfU0laRSA9IDMyICogS0I7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwcml2YXRlIFdyaXRlciBfd3JpdGVyOwotCi0gICAgLyoqCi0gICAgICogSW5pdGlhbGl6ZXMgYSBXcml0ZXJPdXRwdXRCdWZmZXIgYnkgY3JlYXRpbmcgYW4gaW5zdGFuY2Ugb2YgYQotICAgICAqIEJ1ZmZlcmVkV3JpdGVyLiBUaGUgc2l6ZSBvZiB0aGUgYnVmZmVyIGluIHRoaXMgd3JpdGVyIG1heSBoYXZlCi0gICAgICogYSBzaWduaWZpY2FudCBpbXBhY3Qgb24gdGhyb3VnaHB1dC4gU29sYXJpcyBwcmVmZXJzIGEgbGFyZ2VyCi0gICAgICogYnVmZmVyLCB3aGlsZSBMaW51eCB3b3JrcyBiZXR0ZXIgd2l0aCBhIHNtYWxsZXIgb25lLgotICAgICAqLwotICAgIHB1YmxpYyBXcml0ZXJPdXRwdXRCdWZmZXIoV3JpdGVyIHdyaXRlcikgewotICAgICAgICBfd3JpdGVyID0gbmV3IEJ1ZmZlcmVkV3JpdGVyKHdyaXRlciwgQlVGRkVSX1NJWkUpOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgY2xvc2UoKSB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBfd3JpdGVyLmZsdXNoKCk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUudG9TdHJpbmcoKSk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuICIiOwotICAgIH0KLQotICAgIHB1YmxpYyBPdXRwdXRCdWZmZXIgYXBwZW5kKFN0cmluZyBzKSB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBfd3JpdGVyLndyaXRlKHMpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihlLnRvU3RyaW5nKCkpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiB0aGlzOwotICAgIH0KLQotICAgIHB1YmxpYyBPdXRwdXRCdWZmZXIgYXBwZW5kKGNoYXJbXSBzLCBpbnQgZnJvbSwgaW50IHRvKSB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBfd3JpdGVyLndyaXRlKHMsIGZyb20sIHRvKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZS50b1N0cmluZygpKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gdGhpczsKLSAgICB9Ci0KLSAgICBwdWJsaWMgT3V0cHV0QnVmZmVyIGFwcGVuZChjaGFyIGNoKSB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBfd3JpdGVyLndyaXRlKGNoKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZS50b1N0cmluZygpKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gdGhpczsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3RyYXgvRE9NMlNBWC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy90cmF4L0RPTTJTQVguamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMGVkOTgwMC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3RyYXgvRE9NMlNBWC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDg0ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKi8KLS8qCi0gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKLSAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAotICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgotICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKLSAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCi0gKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRE9NMlNBWC5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzA2IDExOjUyOjQ2IHB2ZWR1bGEgRXhwICQKLSAqLwotCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnRyYXg7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuZG9tLlNBWEltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnJ1bnRpbWUuQmFzaXNMaWJyYXJ5OwotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci1pbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7Ci1pbXBvcnQgamF2YS51dGlsLk1hcDsKLWltcG9ydCBqYXZhLnV0aWwuU3RhY2s7Ci1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLWltcG9ydCBvcmcudzNjLmRvbS5OYW1lZE5vZGVNYXA7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5EVERIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LkVudGl0eVJlc29sdmVyOwotaW1wb3J0IG9yZy54bWwuc2F4LkVycm9ySGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKLWltcG9ydCBvcmcueG1sLnNheC5Mb2NhdG9yOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5YTUxSZWFkZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguZXh0LkxleGljYWxIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LmhlbHBlcnMuQXR0cmlidXRlc0ltcGw7Ci0KLS8qKgotICogQGF1dGhvciBHLiBUb2RkIE1pbGxlcgotICovCi1wdWJsaWMgY2xhc3MgRE9NMlNBWCBpbXBsZW1lbnRzIFhNTFJlYWRlciwgTG9jYXRvciB7Ci0KLSAgICBwcml2YXRlIGZpbmFsIHN0YXRpYyBTdHJpbmcgRU1QVFlTVFJJTkcgPSAiIjsKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MTlNfUFJFRklYID0gInhtbG5zIjsKLQotICAgIHByaXZhdGUgTm9kZSBfZG9tID0gbnVsbDsKLSAgICBwcml2YXRlIENvbnRlbnRIYW5kbGVyIF9zYXggPSBudWxsOwotICAgIHByaXZhdGUgTGV4aWNhbEhhbmRsZXIgX2xleCA9IG51bGw7Ci0gICAgcHJpdmF0ZSBTQVhJbXBsIF9zYXhJbXBsID0gbnVsbDsKLSAgICBwcml2YXRlIE1hcDxTdHJpbmcsIFN0YWNrPiBfbnNQcmVmaXhlcyA9IG5ldyBIYXNoTWFwPD4oKTsKLQotICAgIHB1YmxpYyBET00yU0FYKE5vZGUgcm9vdCkgewotICAgICAgICBfZG9tID0gcm9vdDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgQ29udGVudEhhbmRsZXIgZ2V0Q29udGVudEhhbmRsZXIoKSB7Ci0gICAgICAgIHJldHVybiBfc2F4OwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldENvbnRlbnRIYW5kbGVyKENvbnRlbnRIYW5kbGVyIGhhbmRsZXIpIHRocm93cwotICAgICAgICBOdWxsUG9pbnRlckV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgX3NheCA9IGhhbmRsZXI7Ci0gICAgICAgIGlmIChoYW5kbGVyIGluc3RhbmNlb2YgTGV4aWNhbEhhbmRsZXIpIHsKLSAgICAgICAgICAgIF9sZXggPSAoTGV4aWNhbEhhbmRsZXIpIGhhbmRsZXI7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoaGFuZGxlciBpbnN0YW5jZW9mIFNBWEltcGwpIHsKLSAgICAgICAgICAgIF9zYXhJbXBsID0gKFNBWEltcGwpaGFuZGxlcjsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEJlZ2luIHRoZSBzY29wZSBvZiBuYW1lc3BhY2UgcHJlZml4LiBGb3J3YXJkIHRoZSBldmVudCB0byB0aGUKLSAgICAgKiBTQVggaGFuZGxlciBvbmx5IGlmIHRoZSBwcmVmaXggaXMgdW5rbm93biBvciBpdCBpcyBtYXBwZWQgdG8gYQotICAgICAqIGRpZmZlcmVudCBVUkkuCi0gICAgICovCi0gICAgcHJpdmF0ZSBib29sZWFuIHN0YXJ0UHJlZml4TWFwcGluZyhTdHJpbmcgcHJlZml4LCBTdHJpbmcgdXJpKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBib29sZWFuIHB1c2hlZCA9IHRydWU7Ci0gICAgICAgIFN0YWNrIHVyaVN0YWNrID0gX25zUHJlZml4ZXMuZ2V0KHByZWZpeCk7Ci0KLSAgICAgICAgaWYgKHVyaVN0YWNrICE9IG51bGwpIHsKLSAgICAgICAgICAgIGlmICh1cmlTdGFjay5pc0VtcHR5KCkpIHsKLSAgICAgICAgICAgICAgICBfc2F4LnN0YXJ0UHJlZml4TWFwcGluZyhwcmVmaXgsIHVyaSk7Ci0gICAgICAgICAgICAgICAgdXJpU3RhY2sucHVzaCh1cmkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIGxhc3RVcmkgPSAoU3RyaW5nKSB1cmlTdGFjay5wZWVrKCk7Ci0gICAgICAgICAgICAgICAgaWYgKCFsYXN0VXJpLmVxdWFscyh1cmkpKSB7Ci0gICAgICAgICAgICAgICAgICAgIF9zYXguc3RhcnRQcmVmaXhNYXBwaW5nKHByZWZpeCwgdXJpKTsKLSAgICAgICAgICAgICAgICAgICAgdXJpU3RhY2sucHVzaCh1cmkpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgcHVzaGVkID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgX3NheC5zdGFydFByZWZpeE1hcHBpbmcocHJlZml4LCB1cmkpOwotICAgICAgICAgICAgX25zUHJlZml4ZXMucHV0KHByZWZpeCwgdXJpU3RhY2sgPSBuZXcgU3RhY2soKSk7Ci0gICAgICAgICAgICB1cmlTdGFjay5wdXNoKHVyaSk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHB1c2hlZDsKLSAgICB9Ci0KLSAgICAvKgotICAgICAqIEVuZCB0aGUgc2NvcGUgb2YgYSBuYW1lIHByZWZpeCBieSBwb3BwaW5nIGl0IGZyb20gdGhlIHN0YWNrIGFuZAotICAgICAqIHBhc3NpbmcgdGhlIGV2ZW50IHRvIHRoZSBTQVggSGFuZGxlci4KLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgZW5kUHJlZml4TWFwcGluZyhTdHJpbmcgcHJlZml4KQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBmaW5hbCBTdGFjayB1cmlTdGFjayA9IF9uc1ByZWZpeGVzLmdldChwcmVmaXgpOwotCi0gICAgICAgIGlmICh1cmlTdGFjayAhPSBudWxsKSB7Ci0gICAgICAgICAgICBfc2F4LmVuZFByZWZpeE1hcHBpbmcocHJlZml4KTsKLSAgICAgICAgICAgIHVyaVN0YWNrLnBvcCgpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSWYgdGhlIERPTSB3YXMgY3JlYXRlZCB1c2luZyBhIERPTSAxLjAgQVBJLCB0aGUgbG9jYWwgbmFtZSBtYXkgYmUKLSAgICAgKiBudWxsLiBJZiBzbywgZ2V0IHRoZSBsb2NhbCBuYW1lIGZyb20gdGhlIHF1YWxpZmllZCBuYW1lIGJlZm9yZQotICAgICAqIGdlbmVyYXRpbmcgdGhlIFNBWCBldmVudC4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgZ2V0TG9jYWxOYW1lKE5vZGUgbm9kZSkgewotICAgICAgICBmaW5hbCBTdHJpbmcgbG9jYWxOYW1lID0gbm9kZS5nZXRMb2NhbE5hbWUoKTsKLQotICAgICAgICBpZiAobG9jYWxOYW1lID09IG51bGwpIHsKLSAgICAgICAgICAgIGZpbmFsIFN0cmluZyBxbmFtZSA9IG5vZGUuZ2V0Tm9kZU5hbWUoKTsKLSAgICAgICAgICAgIGZpbmFsIGludCBjb2wgPSBxbmFtZS5sYXN0SW5kZXhPZignOicpOwotICAgICAgICAgICAgcmV0dXJuIChjb2wgPiAwKSA/IHFuYW1lLnN1YnN0cmluZyhjb2wgKyAxKSA6IHFuYW1lOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBsb2NhbE5hbWU7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgcGFyc2UoSW5wdXRTb3VyY2UgdW51c2VkKSB0aHJvd3MgSU9FeGNlcHRpb24sIFNBWEV4Y2VwdGlvbiB7Ci0gICAgICAgIHBhcnNlKF9kb20pOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHBhcnNlKCkgdGhyb3dzIElPRXhjZXB0aW9uLCBTQVhFeGNlcHRpb24gewotICAgICAgICBpZiAoX2RvbSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBib29sZWFuIGlzSW5jb21wbGV0ZSA9Ci0gICAgICAgICAgICAgICAgKF9kb20uZ2V0Tm9kZVR5cGUoKSAhPSBvcmcudzNjLmRvbS5Ob2RlLkRPQ1VNRU5UX05PREUpOwotCi0gICAgICAgICAgICBpZiAoaXNJbmNvbXBsZXRlKSB7Ci0gICAgICAgICAgICAgICAgX3NheC5zdGFydERvY3VtZW50KCk7Ci0gICAgICAgICAgICAgICAgcGFyc2UoX2RvbSk7Ci0gICAgICAgICAgICAgICAgX3NheC5lbmREb2N1bWVudCgpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgcGFyc2UoX2RvbSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmF2ZXJzZSB0aGUgRE9NIGFuZCBnZW5lcmF0ZSBTQVggZXZlbnRzIGZvciBhIGhhbmRsZXIuIEEKLSAgICAgKiBzdGFydEVsZW1lbnQoKSBldmVudCBwYXNzZXMgYWxsIGF0dHJpYnV0ZXMsIGluY2x1ZGluZyBuYW1lc3BhY2UKLSAgICAgKiBkZWNsYXJhdGlvbnMuCi0gICAgICovCi0gICAgcHJpdmF0ZSB2b2lkIHBhcnNlKE5vZGUgbm9kZSkgdGhyb3dzIElPRXhjZXB0aW9uLCBTQVhFeGNlcHRpb24gewotICAgICAgICBOb2RlIGZpcnN0ID0gbnVsbDsKLSAgICAgICAgaWYgKG5vZGUgPT0gbnVsbCkgcmV0dXJuOwotCi0gICAgICAgIHN3aXRjaCAobm9kZS5nZXROb2RlVHlwZSgpKSB7Ci0gICAgICAgIGNhc2UgTm9kZS5BVFRSSUJVVEVfTk9ERTogICAgICAgICAvLyBoYW5kbGVkIGJ5IEVMRU1FTlRfTk9ERQotICAgICAgICBjYXNlIE5vZGUuRE9DVU1FTlRfRlJBR01FTlRfTk9ERToKLSAgICAgICAgY2FzZSBOb2RlLkRPQ1VNRU5UX1RZUEVfTk9ERSA6Ci0gICAgICAgIGNhc2UgTm9kZS5FTlRJVFlfTk9ERSA6Ci0gICAgICAgIGNhc2UgTm9kZS5FTlRJVFlfUkVGRVJFTkNFX05PREU6Ci0gICAgICAgIGNhc2UgTm9kZS5OT1RBVElPTl9OT0RFIDoKLSAgICAgICAgICAgIC8vIFRoZXNlIG5vZGUgdHlwZXMgYXJlIGlnbm9yZWQhISEKLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICBjYXNlIE5vZGUuQ0RBVEFfU0VDVElPTl9OT0RFOgotICAgICAgICAgICAgZmluYWwgU3RyaW5nIGNkYXRhID0gbm9kZS5nZXROb2RlVmFsdWUoKTsKLSAgICAgICAgICAgIGlmIChfbGV4ICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBfbGV4LnN0YXJ0Q0RBVEEoKTsKLSAgICAgICAgICAgICAgICBfc2F4LmNoYXJhY3RlcnMoY2RhdGEudG9DaGFyQXJyYXkoKSwgMCwgY2RhdGEubGVuZ3RoKCkpOwotICAgICAgICAgICAgICAgIF9sZXguZW5kQ0RBVEEoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIC8vIGluIHRoZSBjYXNlIHdoZXJlIHRoZXJlIGlzIG5vIGxleCBoYW5kbGVyLCB3ZSBzdGlsbAotICAgICAgICAgICAgICAgIC8vIHdhbnQgdGhlIHRleHQgb2YgdGhlIGNkYXRlIHRvIG1ha2UgaXRzIHdheSB0aHJvdWdoLgotICAgICAgICAgICAgICAgIF9zYXguY2hhcmFjdGVycyhjZGF0YS50b0NoYXJBcnJheSgpLCAwLCBjZGF0YS5sZW5ndGgoKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBicmVhazsKLQotICAgICAgICBjYXNlIE5vZGUuQ09NTUVOVF9OT0RFOiAgICAgICAgICAgLy8gc2hvdWxkIGJlIGhhbmRsZWQhISEKLSAgICAgICAgICAgIGlmIChfbGV4ICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgdmFsdWUgPSBub2RlLmdldE5vZGVWYWx1ZSgpOwotICAgICAgICAgICAgICAgIF9sZXguY29tbWVudCh2YWx1ZS50b0NoYXJBcnJheSgpLCAwLCB2YWx1ZS5sZW5ndGgoKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBOb2RlLkRPQ1VNRU5UX05PREU6Ci0gICAgICAgICAgICBfc2F4LnNldERvY3VtZW50TG9jYXRvcih0aGlzKTsKLQotICAgICAgICAgICAgX3NheC5zdGFydERvY3VtZW50KCk7Ci0gICAgICAgICAgICBOb2RlIG5leHQgPSBub2RlLmdldEZpcnN0Q2hpbGQoKTsKLSAgICAgICAgICAgIHdoaWxlIChuZXh0ICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBwYXJzZShuZXh0KTsKLSAgICAgICAgICAgICAgICBuZXh0ID0gbmV4dC5nZXROZXh0U2libGluZygpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgX3NheC5lbmREb2N1bWVudCgpOwotICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgY2FzZSBOb2RlLkVMRU1FTlRfTk9ERToKLSAgICAgICAgICAgIFN0cmluZyBwcmVmaXg7Ci0gICAgICAgICAgICBWZWN0b3IgcHVzaGVkUHJlZml4ZXMgPSBuZXcgVmVjdG9yKCk7Ci0gICAgICAgICAgICBmaW5hbCBBdHRyaWJ1dGVzSW1wbCBhdHRycyA9IG5ldyBBdHRyaWJ1dGVzSW1wbCgpOwotICAgICAgICAgICAgZmluYWwgTmFtZWROb2RlTWFwIG1hcCA9IG5vZGUuZ2V0QXR0cmlidXRlcygpOwotICAgICAgICAgICAgZmluYWwgaW50IGxlbmd0aCA9IG1hcC5nZXRMZW5ndGgoKTsKLQotICAgICAgICAgICAgLy8gUHJvY2VzcyBhbGwgbmFtZXNwYWNlIGRlY2xhcmF0aW9ucwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykgewotICAgICAgICAgICAgICAgIGZpbmFsIE5vZGUgYXR0ciA9IG1hcC5pdGVtKGkpOwotICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBxbmFtZUF0dHIgPSBhdHRyLmdldE5vZGVOYW1lKCk7Ci0KLSAgICAgICAgICAgICAgICAvLyBJZ25vcmUgZXZlcnl0aGluZyBidXQgTlMgZGVjbGFyYXRpb25zIGhlcmUKLSAgICAgICAgICAgICAgICBpZiAocW5hbWVBdHRyLnN0YXJ0c1dpdGgoWE1MTlNfUFJFRklYKSkgewotICAgICAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgdXJpQXR0ciA9IGF0dHIuZ2V0Tm9kZVZhbHVlKCk7Ci0gICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCBjb2xvbiA9IHFuYW1lQXR0ci5sYXN0SW5kZXhPZignOicpOwotICAgICAgICAgICAgICAgICAgICBwcmVmaXggPSAoY29sb24gPiAwKSA/IHFuYW1lQXR0ci5zdWJzdHJpbmcoY29sb24gKyAxKSA6IEVNUFRZU1RSSU5HOwotICAgICAgICAgICAgICAgICAgICBpZiAoc3RhcnRQcmVmaXhNYXBwaW5nKHByZWZpeCwgdXJpQXR0cikpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHB1c2hlZFByZWZpeGVzLmFkZEVsZW1lbnQocHJlZml4KTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gUHJvY2VzcyBhbGwgb3RoZXIgYXR0cmlidXRlcwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykgewotICAgICAgICAgICAgICAgIGZpbmFsIE5vZGUgYXR0ciA9IG1hcC5pdGVtKGkpOwotICAgICAgICAgICAgICAgIFN0cmluZyBxbmFtZUF0dHIgPSBhdHRyLmdldE5vZGVOYW1lKCk7Ci0KLSAgICAgICAgICAgICAgICAvLyBJZ25vcmUgTlMgZGVjbGFyYXRpb25zIGhlcmUKLSAgICAgICAgICAgICAgICBpZiAoIXFuYW1lQXR0ci5zdGFydHNXaXRoKFhNTE5TX1BSRUZJWCkpIHsKLSAgICAgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIHVyaUF0dHIgPSBhdHRyLmdldE5hbWVzcGFjZVVSSSgpOwotICAgICAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgbG9jYWxOYW1lQXR0ciA9IGdldExvY2FsTmFtZShhdHRyKTsKLQotICAgICAgICAgICAgICAgICAgICAvLyBVcmkgbWF5IGJlIGltcGxpY2l0bHkgZGVjbGFyZWQKLSAgICAgICAgICAgICAgICAgICAgaWYgKHVyaUF0dHIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IGNvbG9uID0gcW5hbWVBdHRyLmxhc3RJbmRleE9mKCc6Jyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29sb24gPiAwKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJlZml4ID0gcW5hbWVBdHRyLnN1YnN0cmluZygwLCBjb2xvbik7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJZiBubyBwcmVmaXggZm9yIHRoaXMgYXR0ciwgd2UgbmVlZCB0byBjcmVhdGUKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBvbmUgYmVjYXVzZSB3ZSBjYW5ub3QgdXNlIHRoZSBkZWZhdWx0IG5zCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJlZml4ID0gQmFzaXNMaWJyYXJ5LmdlbmVyYXRlUHJlZml4KCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcW5hbWVBdHRyID0gcHJlZml4ICsgJzonICsgcW5hbWVBdHRyOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0YXJ0UHJlZml4TWFwcGluZyhwcmVmaXgsIHVyaUF0dHIpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVzaGVkUHJlZml4ZXMuYWRkRWxlbWVudChwcmVmaXgpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgLy8gQWRkIGF0dHJpYnV0ZSB0byBsaXN0Ci0gICAgICAgICAgICAgICAgICAgIGF0dHJzLmFkZEF0dHJpYnV0ZShhdHRyLmdldE5hbWVzcGFjZVVSSSgpLCBnZXRMb2NhbE5hbWUoYXR0ciksCi0gICAgICAgICAgICAgICAgICAgICAgICBxbmFtZUF0dHIsICJDREFUQSIsIGF0dHIuZ2V0Tm9kZVZhbHVlKCkpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gTm93IHByb2Nlc3MgdGhlIGVsZW1lbnQgaXRzZWxmCi0gICAgICAgICAgICBmaW5hbCBTdHJpbmcgcW5hbWUgPSBub2RlLmdldE5vZGVOYW1lKCk7Ci0gICAgICAgICAgICBmaW5hbCBTdHJpbmcgdXJpID0gbm9kZS5nZXROYW1lc3BhY2VVUkkoKTsKLSAgICAgICAgICAgIGZpbmFsIFN0cmluZyBsb2NhbE5hbWUgPSBnZXRMb2NhbE5hbWUobm9kZSk7Ci0KLSAgICAgICAgICAgIC8vIFVyaSBtYXkgYmUgaW1wbGljaXRseSBkZWNsYXJlZAotICAgICAgICAgICAgaWYgKHVyaSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZmluYWwgaW50IGNvbG9uID0gcW5hbWUubGFzdEluZGV4T2YoJzonKTsKLSAgICAgICAgICAgICAgICBwcmVmaXggPSAoY29sb24gPiAwKSA/IHFuYW1lLnN1YnN0cmluZygwLCBjb2xvbikgOiBFTVBUWVNUUklORzsKLSAgICAgICAgICAgICAgICBpZiAoc3RhcnRQcmVmaXhNYXBwaW5nKHByZWZpeCwgdXJpKSkgewotICAgICAgICAgICAgICAgICAgICBwdXNoZWRQcmVmaXhlcy5hZGRFbGVtZW50KHByZWZpeCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBHZW5lcmF0ZSBTQVggZXZlbnQgdG8gc3RhcnQgZWxlbWVudAotICAgICAgICAgICAgaWYgKF9zYXhJbXBsICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBfc2F4SW1wbC5zdGFydEVsZW1lbnQodXJpLCBsb2NhbE5hbWUsIHFuYW1lLCBhdHRycywgbm9kZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBfc2F4LnN0YXJ0RWxlbWVudCh1cmksIGxvY2FsTmFtZSwgcW5hbWUsIGF0dHJzKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gVHJhdmVyc2UgYWxsIGNoaWxkIG5vZGVzIG9mIHRoZSBlbGVtZW50IChpZiBhbnkpCi0gICAgICAgICAgICBuZXh0ID0gbm9kZS5nZXRGaXJzdENoaWxkKCk7Ci0gICAgICAgICAgICB3aGlsZSAobmV4dCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgcGFyc2UobmV4dCk7Ci0gICAgICAgICAgICAgICAgbmV4dCA9IG5leHQuZ2V0TmV4dFNpYmxpbmcoKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gR2VuZXJhdGUgU0FYIGV2ZW50IHRvIGNsb3NlIGVsZW1lbnQKLSAgICAgICAgICAgIF9zYXguZW5kRWxlbWVudCh1cmksIGxvY2FsTmFtZSwgcW5hbWUpOwotCi0gICAgICAgICAgICAvLyBHZW5lcmF0ZSBlbmRQcmVmaXhNYXBwaW5nKCkgZm9yIGFsbCBwdXNoZWQgcHJlZml4ZXMKLSAgICAgICAgICAgIGZpbmFsIGludCBuUHVzaGVkUHJlZml4ZXMgPSBwdXNoZWRQcmVmaXhlcy5zaXplKCk7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG5QdXNoZWRQcmVmaXhlczsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgZW5kUHJlZml4TWFwcGluZygoU3RyaW5nKSBwdXNoZWRQcmVmaXhlcy5lbGVtZW50QXQoaSkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgY2FzZSBOb2RlLlBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERToKLSAgICAgICAgICAgIF9zYXgucHJvY2Vzc2luZ0luc3RydWN0aW9uKG5vZGUuZ2V0Tm9kZU5hbWUoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUuZ2V0Tm9kZVZhbHVlKCkpOwotICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgY2FzZSBOb2RlLlRFWFRfTk9ERToKLSAgICAgICAgICAgIGZpbmFsIFN0cmluZyBkYXRhID0gbm9kZS5nZXROb2RlVmFsdWUoKTsKLSAgICAgICAgICAgIF9zYXguY2hhcmFjdGVycyhkYXRhLnRvQ2hhckFycmF5KCksIDAsIGRhdGEubGVuZ3RoKCkpOwotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIGNsYXNzIGlzIG9ubHkgdXNlZCBpbnRlcm5hbGx5IHNvIHRoaXMgbWV0aG9kIHNob3VsZCBuZXZlcgotICAgICAqIGJlIGNhbGxlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgRFRESGFuZGxlciBnZXREVERIYW5kbGVyKCkgewotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIGNsYXNzIGlzIG9ubHkgdXNlZCBpbnRlcm5hbGx5IHNvIHRoaXMgbWV0aG9kIHNob3VsZCBuZXZlcgotICAgICAqIGJlIGNhbGxlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgRXJyb3JIYW5kbGVyIGdldEVycm9ySGFuZGxlcigpIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBjbGFzcyBpcyBvbmx5IHVzZWQgaW50ZXJuYWxseSBzbyB0aGlzIG1ldGhvZCBzaG91bGQgbmV2ZXIKLSAgICAgKiBiZSBjYWxsZWQuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0RmVhdHVyZShTdHJpbmcgbmFtZSkgdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sCi0gICAgICAgIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgY2xhc3MgaXMgb25seSB1c2VkIGludGVybmFsbHkgc28gdGhpcyBtZXRob2Qgc2hvdWxkIG5ldmVyCi0gICAgICogYmUgY2FsbGVkLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEZlYXR1cmUoU3RyaW5nIG5hbWUsIGJvb2xlYW4gdmFsdWUpIHRocm93cwotICAgICAgICBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uLCBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24KLSAgICB7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBjbGFzcyBpcyBvbmx5IHVzZWQgaW50ZXJuYWxseSBzbyB0aGlzIG1ldGhvZCBzaG91bGQgbmV2ZXIKLSAgICAgKiBiZSBjYWxsZWQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcGFyc2UoU3RyaW5nIHN5c0lkKSB0aHJvd3MgSU9FeGNlcHRpb24sIFNBWEV4Y2VwdGlvbiB7Ci0gICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiVGhpcyBtZXRob2QgaXMgbm90IHlldCBpbXBsZW1lbnRlZC4iKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIGNsYXNzIGlzIG9ubHkgdXNlZCBpbnRlcm5hbGx5IHNvIHRoaXMgbWV0aG9kIHNob3VsZCBuZXZlcgotICAgICAqIGJlIGNhbGxlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXREVERIYW5kbGVyKERUREhhbmRsZXIgaGFuZGxlcikgdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIGNsYXNzIGlzIG9ubHkgdXNlZCBpbnRlcm5hbGx5IHNvIHRoaXMgbWV0aG9kIHNob3VsZCBuZXZlcgotICAgICAqIGJlIGNhbGxlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRFbnRpdHlSZXNvbHZlcihFbnRpdHlSZXNvbHZlciByZXNvbHZlcikgdGhyb3dzCi0gICAgICAgIE51bGxQb2ludGVyRXhjZXB0aW9uCi0gICAgewotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgY2xhc3MgaXMgb25seSB1c2VkIGludGVybmFsbHkgc28gdGhpcyBtZXRob2Qgc2hvdWxkIG5ldmVyCi0gICAgICogYmUgY2FsbGVkLgotICAgICAqLwotICAgIHB1YmxpYyBFbnRpdHlSZXNvbHZlciBnZXRFbnRpdHlSZXNvbHZlcigpIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBjbGFzcyBpcyBvbmx5IHVzZWQgaW50ZXJuYWxseSBzbyB0aGlzIG1ldGhvZCBzaG91bGQgbmV2ZXIKLSAgICAgKiBiZSBjYWxsZWQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RXJyb3JIYW5kbGVyKEVycm9ySGFuZGxlciBoYW5kbGVyKSB0aHJvd3MKLSAgICAgICAgTnVsbFBvaW50ZXJFeGNlcHRpb24KLSAgICB7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBjbGFzcyBpcyBvbmx5IHVzZWQgaW50ZXJuYWxseSBzbyB0aGlzIG1ldGhvZCBzaG91bGQgbmV2ZXIKLSAgICAgKiBiZSBjYWxsZWQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0UHJvcGVydHkoU3RyaW5nIG5hbWUsIE9iamVjdCB2YWx1ZSkgdGhyb3dzCi0gICAgICAgIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiB7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBjbGFzcyBpcyBvbmx5IHVzZWQgaW50ZXJuYWxseSBzbyB0aGlzIG1ldGhvZCBzaG91bGQgbmV2ZXIKLSAgICAgKiBiZSBjYWxsZWQuCi0gICAgICovCi0gICAgcHVibGljIE9iamVjdCBnZXRQcm9wZXJ0eShTdHJpbmcgbmFtZSkgdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sCi0gICAgICAgIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBjbGFzcyBpcyBvbmx5IHVzZWQgaW50ZXJuYWxseSBzbyB0aGlzIG1ldGhvZCBzaG91bGQgbmV2ZXIKLSAgICAgKiBiZSBjYWxsZWQuCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRDb2x1bW5OdW1iZXIoKSB7Ci0gICAgICAgIHJldHVybiAwOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgY2xhc3MgaXMgb25seSB1c2VkIGludGVybmFsbHkgc28gdGhpcyBtZXRob2Qgc2hvdWxkIG5ldmVyCi0gICAgICogYmUgY2FsbGVkLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0TGluZU51bWJlcigpIHsKLSAgICAgICAgcmV0dXJuIDA7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBjbGFzcyBpcyBvbmx5IHVzZWQgaW50ZXJuYWxseSBzbyB0aGlzIG1ldGhvZCBzaG91bGQgbmV2ZXIKLSAgICAgKiBiZSBjYWxsZWQuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRQdWJsaWNJZCgpIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBjbGFzcyBpcyBvbmx5IHVzZWQgaW50ZXJuYWxseSBzbyB0aGlzIG1ldGhvZCBzaG91bGQgbmV2ZXIKLSAgICAgKiBiZSBjYWxsZWQuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRTeXN0ZW1JZCgpIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLy8gRGVidWdnaW5nCi0gICAgcHJpdmF0ZSBTdHJpbmcgZ2V0Tm9kZVR5cGVGcm9tQ29kZShzaG9ydCBjb2RlKSB7Ci0gICAgICAgIFN0cmluZyByZXR2YWwgPSBudWxsOwotICAgICAgICBzd2l0Y2ggKGNvZGUpIHsKLSAgICAgICAgY2FzZSBOb2RlLkFUVFJJQlVURV9OT0RFIDoKLSAgICAgICAgICAgIHJldHZhbCA9ICJBVFRSSUJVVEVfTk9ERSI7IGJyZWFrOwotICAgICAgICBjYXNlIE5vZGUuQ0RBVEFfU0VDVElPTl9OT0RFIDoKLSAgICAgICAgICAgIHJldHZhbCA9ICJDREFUQV9TRUNUSU9OX05PREUiOyBicmVhazsKLSAgICAgICAgY2FzZSBOb2RlLkNPTU1FTlRfTk9ERSA6Ci0gICAgICAgICAgICByZXR2YWwgPSAiQ09NTUVOVF9OT0RFIjsgYnJlYWs7Ci0gICAgICAgIGNhc2UgTm9kZS5ET0NVTUVOVF9GUkFHTUVOVF9OT0RFIDoKLSAgICAgICAgICAgIHJldHZhbCA9ICJET0NVTUVOVF9GUkFHTUVOVF9OT0RFIjsgYnJlYWs7Ci0gICAgICAgIGNhc2UgTm9kZS5ET0NVTUVOVF9OT0RFIDoKLSAgICAgICAgICAgIHJldHZhbCA9ICJET0NVTUVOVF9OT0RFIjsgYnJlYWs7Ci0gICAgICAgIGNhc2UgTm9kZS5ET0NVTUVOVF9UWVBFX05PREUgOgotICAgICAgICAgICAgcmV0dmFsID0gIkRPQ1VNRU5UX1RZUEVfTk9ERSI7IGJyZWFrOwotICAgICAgICBjYXNlIE5vZGUuRUxFTUVOVF9OT0RFIDoKLSAgICAgICAgICAgIHJldHZhbCA9ICJFTEVNRU5UX05PREUiOyBicmVhazsKLSAgICAgICAgY2FzZSBOb2RlLkVOVElUWV9OT0RFIDoKLSAgICAgICAgICAgIHJldHZhbCA9ICJFTlRJVFlfTk9ERSI7IGJyZWFrOwotICAgICAgICBjYXNlIE5vZGUuRU5USVRZX1JFRkVSRU5DRV9OT0RFIDoKLSAgICAgICAgICAgIHJldHZhbCA9ICJFTlRJVFlfUkVGRVJFTkNFX05PREUiOyBicmVhazsKLSAgICAgICAgY2FzZSBOb2RlLk5PVEFUSU9OX05PREUgOgotICAgICAgICAgICAgcmV0dmFsID0gIk5PVEFUSU9OX05PREUiOyBicmVhazsKLSAgICAgICAgY2FzZSBOb2RlLlBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERSA6Ci0gICAgICAgICAgICByZXR2YWwgPSAiUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFIjsgYnJlYWs7Ci0gICAgICAgIGNhc2UgTm9kZS5URVhUX05PREU6Ci0gICAgICAgICAgICByZXR2YWwgPSAiVEVYVF9OT0RFIjsgYnJlYWs7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHJldHZhbDsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3RyYXgvRE9NMlRPLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3RyYXgvRE9NMlRPLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDA1Mzc3M2QuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy90cmF4L0RPTTJUTy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDM2ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IERPTTJUTy5qYXZhLHYgMS41IDIwMDUvMDkvMjggMTM6NDg6NDQgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnRyYXg7Ci0KLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotCi1pbXBvcnQgb3JnLnczYy5kb20uTmFtZWROb2RlTWFwOwotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci1pbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyLlNlcmlhbGl6YXRpb25IYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LkRUREhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguRW50aXR5UmVzb2x2ZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguRXJyb3JIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LklucHV0U291cmNlOwotaW1wb3J0IG9yZy54bWwuc2F4LmV4dC5Mb2NhdG9yMjsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguWE1MUmVhZGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplci5OYW1lc3BhY2VNYXBwaW5nczsKLQotLyoqCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqIEBhdXRob3IgU3VuaXRoYSBSZWRkeQotICovCi1wdWJsaWMgY2xhc3MgRE9NMlRPIGltcGxlbWVudHMgWE1MUmVhZGVyLCBMb2NhdG9yMiB7Ci0KLSAgICBwcml2YXRlIGZpbmFsIHN0YXRpYyBTdHJpbmcgRU1QVFlTVFJJTkcgPSAiIjsKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MTlNfUFJFRklYID0gInhtbG5zIjsKLQotICAgIC8qKgotICAgICAqIEEgcmVmZXJlbmNlIHRvIHRoZSBET00gdG8gYmUgdHJhdmVyc2VkLgotICAgICAqLwotICAgIHByaXZhdGUgTm9kZSBfZG9tOwotCi0gICAgLyoqCi0gICAgICogQSByZWZlcmVuY2UgdG8gdGhlIG91dHB1dCBoYW5kbGVyIHJlY2VpdmluZyB0aGUgZXZlbnRzLgotICAgICAqLwotICAgIHByaXZhdGUgU2VyaWFsaXphdGlvbkhhbmRsZXIgX2hhbmRsZXI7Ci0KLQotICAgIHByaXZhdGUgU3RyaW5nIHhtbFZlcnNpb24gPSBudWxsOwotCi0gICAgcHJpdmF0ZSBTdHJpbmcgeG1sRW5jb2RpbmcgPSBudWxsOwotCi0KLSAgICBwdWJsaWMgRE9NMlRPKE5vZGUgcm9vdCwgU2VyaWFsaXphdGlvbkhhbmRsZXIgaGFuZGxlcikgewotICAgICAgICBfZG9tID0gcm9vdDsKLSAgICAgICAgX2hhbmRsZXIgPSBoYW5kbGVyOwotICAgIH0KLQotICAgIHB1YmxpYyBDb250ZW50SGFuZGxlciBnZXRDb250ZW50SGFuZGxlcigpIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0Q29udGVudEhhbmRsZXIoQ29udGVudEhhbmRsZXIgaGFuZGxlcikgewotICAgICAgICAvLyBFbXB0eQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHBhcnNlKElucHV0U291cmNlIHVudXNlZCkgdGhyb3dzIElPRXhjZXB0aW9uLCBTQVhFeGNlcHRpb24gewotICAgICAgICBwYXJzZShfZG9tKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBwYXJzZSgpIHRocm93cyBJT0V4Y2VwdGlvbiwgU0FYRXhjZXB0aW9uIHsKLQotICAgICAgICBpZiAoX2RvbSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBib29sZWFuIGlzSW5jb21wbGV0ZSA9Ci0gICAgICAgICAgICAgICAgKF9kb20uZ2V0Tm9kZVR5cGUoKSAhPSBvcmcudzNjLmRvbS5Ob2RlLkRPQ1VNRU5UX05PREUpOwotCi0gICAgICAgICAgICBpZiAoaXNJbmNvbXBsZXRlKSB7Ci0gICAgICAgICAgICAgICAgX2hhbmRsZXIuc3RhcnREb2N1bWVudCgpOwotICAgICAgICAgICAgICAgIHBhcnNlKF9kb20pOwotICAgICAgICAgICAgICAgIF9oYW5kbGVyLmVuZERvY3VtZW50KCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBwYXJzZShfZG9tKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYXZlcnNlIHRoZSBET00gYW5kIGdlbmVyYXRlIFRPIGV2ZW50cyBmb3IgYSBoYW5kbGVyLiBOb3RpY2UgdGhhdAotICAgICAqIHdlIG5lZWQgdG8gaGFuZGxlIGltcGxpY2l0IG5hbWVzcGFjZSBkZWNsYXJhdGlvbnMgdG9vLgotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCBwYXJzZShOb2RlIG5vZGUpCi0gICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAobm9kZSA9PSBudWxsKSByZXR1cm47Ci0KLSAgICAgICAgc3dpdGNoIChub2RlLmdldE5vZGVUeXBlKCkpIHsKLSAgICAgICAgY2FzZSBOb2RlLkFUVFJJQlVURV9OT0RFOiAgICAgICAgIC8vIGhhbmRsZWQgYnkgRUxFTUVOVF9OT0RFCi0gICAgICAgIGNhc2UgTm9kZS5ET0NVTUVOVF9UWVBFX05PREUgOgotICAgICAgICBjYXNlIE5vZGUuRU5USVRZX05PREUgOgotICAgICAgICBjYXNlIE5vZGUuRU5USVRZX1JFRkVSRU5DRV9OT0RFOgotICAgICAgICBjYXNlIE5vZGUuTk9UQVRJT05fTk9ERSA6Ci0gICAgICAgICAgICAvLyBUaGVzZSBub2RlIHR5cGVzIGFyZSBpZ25vcmVkISEhCi0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBOb2RlLkNEQVRBX1NFQ1RJT05fTk9ERToKLSAgICAgICAgICAgIF9oYW5kbGVyLnN0YXJ0Q0RBVEEoKTsKLSAgICAgICAgICAgIF9oYW5kbGVyLmNoYXJhY3RlcnMobm9kZS5nZXROb2RlVmFsdWUoKSk7Ci0gICAgICAgICAgICBfaGFuZGxlci5lbmRDREFUQSgpOwotICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgY2FzZSBOb2RlLkNPTU1FTlRfTk9ERTogICAgICAgICAgIC8vIHNob3VsZCBiZSBoYW5kbGVkISEhCi0gICAgICAgICAgICBfaGFuZGxlci5jb21tZW50KG5vZGUuZ2V0Tm9kZVZhbHVlKCkpOwotICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgY2FzZSBOb2RlLkRPQ1VNRU5UX05PREU6Ci0gICAgICAgICAgICAgc2V0RG9jdW1lbnRJbmZvKChEb2N1bWVudClub2RlKTsKLSAgICAgICAgICAgICBfaGFuZGxlci5zZXREb2N1bWVudExvY2F0b3IodGhpcyk7Ci0gICAgICAgICAgICAgX2hhbmRsZXIuc3RhcnREb2N1bWVudCgpOwotICAgICAgICAgICAgTm9kZSBuZXh0ID0gbm9kZS5nZXRGaXJzdENoaWxkKCk7Ci0gICAgICAgICAgICB3aGlsZSAobmV4dCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgcGFyc2UobmV4dCk7Ci0gICAgICAgICAgICAgICAgbmV4dCA9IG5leHQuZ2V0TmV4dFNpYmxpbmcoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIF9oYW5kbGVyLmVuZERvY3VtZW50KCk7Ci0gICAgICAgICAgICBicmVhazsKLQotICAgICAgICBjYXNlIE5vZGUuRE9DVU1FTlRfRlJBR01FTlRfTk9ERToKLSAgICAgICAgICAgIG5leHQgPSBub2RlLmdldEZpcnN0Q2hpbGQoKTsKLSAgICAgICAgICAgIHdoaWxlIChuZXh0ICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBwYXJzZShuZXh0KTsKLSAgICAgICAgICAgICAgICBuZXh0ID0gbmV4dC5nZXROZXh0U2libGluZygpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgY2FzZSBOb2RlLkVMRU1FTlRfTk9ERToKLSAgICAgICAgICAgIC8vIEdlbmVyYXRlIFNBWCBldmVudCB0byBzdGFydCBlbGVtZW50Ci0gICAgICAgICAgICBmaW5hbCBTdHJpbmcgcW5hbWUgPSBub2RlLmdldE5vZGVOYW1lKCk7Ci0gICAgICAgICAgICBfaGFuZGxlci5zdGFydEVsZW1lbnQobnVsbCwgbnVsbCwgcW5hbWUpOwotCi0gICAgICAgICAgICBpbnQgY29sb247Ci0gICAgICAgICAgICBTdHJpbmcgcHJlZml4OwotICAgICAgICAgICAgZmluYWwgTmFtZWROb2RlTWFwIG1hcCA9IG5vZGUuZ2V0QXR0cmlidXRlcygpOwotICAgICAgICAgICAgZmluYWwgaW50IGxlbmd0aCA9IG1hcC5nZXRMZW5ndGgoKTsKLQotICAgICAgICAgICAgLy8gUHJvY2VzcyBhbGwgbmFtZXNwYWNlIGF0dHJpYnV0ZXMgZmlyc3QKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgICAgICBmaW5hbCBOb2RlIGF0dHIgPSBtYXAuaXRlbShpKTsKLSAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgcW5hbWVBdHRyID0gYXR0ci5nZXROb2RlTmFtZSgpOwotCi0gICAgICAgICAgICAgICAgLy8gSXMgdGhpcyBhIG5hbWVzcGFjZSBkZWNsYXJhdGlvbj8KLSAgICAgICAgICAgICAgICBpZiAocW5hbWVBdHRyLnN0YXJ0c1dpdGgoWE1MTlNfUFJFRklYKSkgewotICAgICAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgdXJpQXR0ciA9IGF0dHIuZ2V0Tm9kZVZhbHVlKCk7Ci0gICAgICAgICAgICAgICAgICAgIGNvbG9uID0gcW5hbWVBdHRyLmxhc3RJbmRleE9mKCc6Jyk7Ci0gICAgICAgICAgICAgICAgICAgIHByZWZpeCA9IChjb2xvbiA+IDApID8gcW5hbWVBdHRyLnN1YnN0cmluZyhjb2xvbiArIDEpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogRU1QVFlTVFJJTkc7Ci0gICAgICAgICAgICAgICAgICAgIF9oYW5kbGVyLm5hbWVzcGFjZUFmdGVyU3RhcnRFbGVtZW50KHByZWZpeCwgdXJpQXR0cik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBQcm9jZXNzIGFsbCBub24tbmFtZXNwYWNlIGF0dHJpYnV0ZXMgbmV4dAotICAgICAgICAgICAgTmFtZXNwYWNlTWFwcGluZ3Mgbm0gPSBuZXcgTmFtZXNwYWNlTWFwcGluZ3MoKTsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgICAgICBmaW5hbCBOb2RlIGF0dHIgPSBtYXAuaXRlbShpKTsKLSAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgcW5hbWVBdHRyID0gYXR0ci5nZXROb2RlTmFtZSgpOwotCi0gICAgICAgICAgICAgICAgLy8gSXMgdGhpcyBhIHJlZ3VsYXIgYXR0cmlidXRlPwotICAgICAgICAgICAgICAgIGlmICghcW5hbWVBdHRyLnN0YXJ0c1dpdGgoWE1MTlNfUFJFRklYKSkgewotICAgICAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgdXJpQXR0ciA9IGF0dHIuZ2V0TmFtZXNwYWNlVVJJKCk7Ci0gICAgICAgICAgICAgICAgICAgIC8vIFVyaSBtYXkgYmUgaW1wbGljaXRseSBkZWNsYXJlZAotICAgICAgICAgICAgICAgICAgICBpZiAodXJpQXR0ciAhPSBudWxsICYmICF1cmlBdHRyLmVxdWFscyhFTVBUWVNUUklORykgKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBjb2xvbiA9IHFuYW1lQXR0ci5sYXN0SW5kZXhPZignOicpOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBGaXggZm9yIGJ1ZyAyNjMxOQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gRm9yIGF0dHJpYnV0ZXMgbm90IGdpdmVuIGFuIHByZWZpeCBleHBsaWN0bHkKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGJ1dCBoYXZpbmcgYSBuYW1lc3BhY2UgdXJpIHdlIG5lZWQKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRvIGV4cGxpY2l0bHkgZ2VuZXJhdGUgdGhlIHByZWZpeAotICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG5ld1ByZWZpeCA9IG5tLmxvb2t1cFByZWZpeCh1cmlBdHRyKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuZXdQcmVmaXggPT0gbnVsbCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdQcmVmaXggPSBubS5nZW5lcmF0ZU5leHRQcmVmaXgoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHByZWZpeCA9IChjb2xvbiA+IDApID8gcW5hbWVBdHRyLnN1YnN0cmluZygwLCBjb2xvbikKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IG5ld1ByZWZpeDsKLSAgICAgICAgICAgICAgICAgICAgICAgIF9oYW5kbGVyLm5hbWVzcGFjZUFmdGVyU3RhcnRFbGVtZW50KHByZWZpeCwgdXJpQXR0cik7Ci0gICAgICAgICAgICAgICAgICAgICAgICBfaGFuZGxlci5hZGRBdHRyaWJ1dGUoKHByZWZpeCArICI6IiArIHFuYW1lQXR0ciksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0ci5nZXROb2RlVmFsdWUoKSk7Ci0gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgX2hhbmRsZXIuYWRkQXR0cmlidXRlKHFuYW1lQXR0ciwgYXR0ci5nZXROb2RlVmFsdWUoKSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIE5vdyBlbGVtZW50IG5hbWVzcGFjZSBhbmQgY2hpbGRyZW4KLSAgICAgICAgICAgIGZpbmFsIFN0cmluZyB1cmkgPSBub2RlLmdldE5hbWVzcGFjZVVSSSgpOwotICAgICAgICAgICAgZmluYWwgU3RyaW5nIGxvY2FsTmFtZSA9IG5vZGUuZ2V0TG9jYWxOYW1lKCk7Ci0KLSAgICAgICAgICAgIC8vIFVyaSBtYXkgYmUgaW1wbGljaXRseSBkZWNsYXJlZAotICAgICAgICAgICAgaWYgKHVyaSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgY29sb24gPSBxbmFtZS5sYXN0SW5kZXhPZignOicpOwotICAgICAgICAgICAgICAgIHByZWZpeCA9IChjb2xvbiA+IDApID8gcW5hbWUuc3Vic3RyaW5nKDAsIGNvbG9uKSA6IEVNUFRZU1RSSU5HOwotICAgICAgICAgICAgICAgIF9oYW5kbGVyLm5hbWVzcGFjZUFmdGVyU3RhcnRFbGVtZW50KHByZWZpeCwgdXJpKTsKLSAgICAgICAgICAgIH1lbHNlIHsKLSAgICAgICAgICAgICAgICAgIC8vIEZpeCBmb3IgYnVnIDI2MzE5Ci0gICAgICAgICAgICAgICAgICAvLyBJZiBhbiBlbGVtZW50IGZvbyBpcyBjcmVhdGVkIHVzaW5nCi0gICAgICAgICAgICAgICAgICAvLyBjcmVhdGVFbGVtZW50TlMobnVsbCxsb2NOYW1lKQotICAgICAgICAgICAgICAgICAgLy8gdGhlbiB0aGUgIGVsZW1lbnQgc2hvdWxkIGJlIHNlcmlhbGl6ZWQKLSAgICAgICAgICAgICAgICAgIC8vIDxmb28geG1sbnM9IiAiLz4KLSAgICAgICAgICAgICAgICAgIGlmICh1cmkgPT0gbnVsbCAgJiYgbG9jYWxOYW1lICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgIHByZWZpeCA9IEVNUFRZU1RSSU5HOwotICAgICAgICAgICAgICAgICAgICAgX2hhbmRsZXIubmFtZXNwYWNlQWZ0ZXJTdGFydEVsZW1lbnQocHJlZml4LCBFTVBUWVNUUklORyk7Ci0gICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gVHJhdmVyc2UgYWxsIGNoaWxkIG5vZGVzIG9mIHRoZSBlbGVtZW50IChpZiBhbnkpCi0gICAgICAgICAgICBuZXh0ID0gbm9kZS5nZXRGaXJzdENoaWxkKCk7Ci0gICAgICAgICAgICB3aGlsZSAobmV4dCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgcGFyc2UobmV4dCk7Ci0gICAgICAgICAgICAgICAgbmV4dCA9IG5leHQuZ2V0TmV4dFNpYmxpbmcoKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gR2VuZXJhdGUgU0FYIGV2ZW50IHRvIGNsb3NlIGVsZW1lbnQKLSAgICAgICAgICAgIF9oYW5kbGVyLmVuZEVsZW1lbnQocW5hbWUpOwotICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgY2FzZSBOb2RlLlBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERToKLSAgICAgICAgICAgIF9oYW5kbGVyLnByb2Nlc3NpbmdJbnN0cnVjdGlvbihub2RlLmdldE5vZGVOYW1lKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZS5nZXROb2RlVmFsdWUoKSk7Ci0gICAgICAgICAgICBicmVhazsKLQotICAgICAgICBjYXNlIE5vZGUuVEVYVF9OT0RFOgotICAgICAgICAgICAgX2hhbmRsZXIuY2hhcmFjdGVycyhub2RlLmdldE5vZGVWYWx1ZSgpKTsKLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBjbGFzcyBpcyBvbmx5IHVzZWQgaW50ZXJuYWxseSBzbyB0aGlzIG1ldGhvZCBzaG91bGQgbmV2ZXIKLSAgICAgKiBiZSBjYWxsZWQuCi0gICAgICovCi0gICAgcHVibGljIERUREhhbmRsZXIgZ2V0RFRESGFuZGxlcigpIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBjbGFzcyBpcyBvbmx5IHVzZWQgaW50ZXJuYWxseSBzbyB0aGlzIG1ldGhvZCBzaG91bGQgbmV2ZXIKLSAgICAgKiBiZSBjYWxsZWQuCi0gICAgICovCi0gICAgcHVibGljIEVycm9ySGFuZGxlciBnZXRFcnJvckhhbmRsZXIoKSB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgY2xhc3MgaXMgb25seSB1c2VkIGludGVybmFsbHkgc28gdGhpcyBtZXRob2Qgc2hvdWxkIG5ldmVyCi0gICAgICogYmUgY2FsbGVkLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGdldEZlYXR1cmUoU3RyaW5nIG5hbWUpIHRocm93cyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uLAotICAgICAgICBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIGNsYXNzIGlzIG9ubHkgdXNlZCBpbnRlcm5hbGx5IHNvIHRoaXMgbWV0aG9kIHNob3VsZCBuZXZlcgotICAgICAqIGJlIGNhbGxlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRGZWF0dXJlKFN0cmluZyBuYW1lLCBib29sZWFuIHZhbHVlKSB0aHJvd3MKLSAgICAgICAgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiwgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uCi0gICAgewotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgY2xhc3MgaXMgb25seSB1c2VkIGludGVybmFsbHkgc28gdGhpcyBtZXRob2Qgc2hvdWxkIG5ldmVyCi0gICAgICogYmUgY2FsbGVkLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHBhcnNlKFN0cmluZyBzeXNJZCkgdGhyb3dzIElPRXhjZXB0aW9uLCBTQVhFeGNlcHRpb24gewotICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlRoaXMgbWV0aG9kIGlzIG5vdCB5ZXQgaW1wbGVtZW50ZWQuIik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBjbGFzcyBpcyBvbmx5IHVzZWQgaW50ZXJuYWxseSBzbyB0aGlzIG1ldGhvZCBzaG91bGQgbmV2ZXIKLSAgICAgKiBiZSBjYWxsZWQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RFRESGFuZGxlcihEVERIYW5kbGVyIGhhbmRsZXIpIHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiB7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBjbGFzcyBpcyBvbmx5IHVzZWQgaW50ZXJuYWxseSBzbyB0aGlzIG1ldGhvZCBzaG91bGQgbmV2ZXIKLSAgICAgKiBiZSBjYWxsZWQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RW50aXR5UmVzb2x2ZXIoRW50aXR5UmVzb2x2ZXIgcmVzb2x2ZXIpIHRocm93cwotICAgICAgICBOdWxsUG9pbnRlckV4Y2VwdGlvbgotICAgIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIGNsYXNzIGlzIG9ubHkgdXNlZCBpbnRlcm5hbGx5IHNvIHRoaXMgbWV0aG9kIHNob3VsZCBuZXZlcgotICAgICAqIGJlIGNhbGxlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgRW50aXR5UmVzb2x2ZXIgZ2V0RW50aXR5UmVzb2x2ZXIoKSB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgY2xhc3MgaXMgb25seSB1c2VkIGludGVybmFsbHkgc28gdGhpcyBtZXRob2Qgc2hvdWxkIG5ldmVyCi0gICAgICogYmUgY2FsbGVkLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEVycm9ySGFuZGxlcihFcnJvckhhbmRsZXIgaGFuZGxlcikgdGhyb3dzCi0gICAgICAgIE51bGxQb2ludGVyRXhjZXB0aW9uCi0gICAgewotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgY2xhc3MgaXMgb25seSB1c2VkIGludGVybmFsbHkgc28gdGhpcyBtZXRob2Qgc2hvdWxkIG5ldmVyCi0gICAgICogYmUgY2FsbGVkLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFByb3BlcnR5KFN0cmluZyBuYW1lLCBPYmplY3QgdmFsdWUpIHRocm93cwotICAgICAgICBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uLCBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gewotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgY2xhc3MgaXMgb25seSB1c2VkIGludGVybmFsbHkgc28gdGhpcyBtZXRob2Qgc2hvdWxkIG5ldmVyCi0gICAgICogYmUgY2FsbGVkLgotICAgICAqLwotICAgIHB1YmxpYyBPYmplY3QgZ2V0UHJvcGVydHkoU3RyaW5nIG5hbWUpIHRocm93cyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uLAotICAgICAgICBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgY2xhc3MgaXMgb25seSB1c2VkIGludGVybmFsbHkgc28gdGhpcyBtZXRob2Qgc2hvdWxkIG5ldmVyCi0gICAgICogYmUgY2FsbGVkLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0Q29sdW1uTnVtYmVyKCkgewotICAgICAgICByZXR1cm4gMDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIGNsYXNzIGlzIG9ubHkgdXNlZCBpbnRlcm5hbGx5IHNvIHRoaXMgbWV0aG9kIHNob3VsZCBuZXZlcgotICAgICAqIGJlIGNhbGxlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldExpbmVOdW1iZXIoKSB7Ci0gICAgICAgIHJldHVybiAwOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgY2xhc3MgaXMgb25seSB1c2VkIGludGVybmFsbHkgc28gdGhpcyBtZXRob2Qgc2hvdWxkIG5ldmVyCi0gICAgICogYmUgY2FsbGVkLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0UHVibGljSWQoKSB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgY2xhc3MgaXMgb25seSB1c2VkIGludGVybmFsbHkgc28gdGhpcyBtZXRob2Qgc2hvdWxkIG5ldmVyCi0gICAgICogYmUgY2FsbGVkLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3lzdGVtSWQoKSB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotCi0gICAgcHJpdmF0ZSB2b2lkIHNldERvY3VtZW50SW5mbyhEb2N1bWVudCBkb2N1bWVudCkgewotICAgICAgICBpZiAoIWRvY3VtZW50LmdldFhtbFN0YW5kYWxvbmUoKSkKLSAgICAgICAgICAgIF9oYW5kbGVyLnNldFN0YW5kYWxvbmUoQm9vbGVhbi50b1N0cmluZyhkb2N1bWVudC5nZXRYbWxTdGFuZGFsb25lKCkpKTsKLSAgICAgICAgc2V0WE1MVmVyc2lvbihkb2N1bWVudC5nZXRYbWxWZXJzaW9uKCkpOwotICAgICAgICBzZXRFbmNvZGluZyhkb2N1bWVudC5nZXRYbWxFbmNvZGluZygpKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldFhNTFZlcnNpb24oKSB7Ci0gICAgICAgIHJldHVybiB4bWxWZXJzaW9uOwotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBzZXRYTUxWZXJzaW9uKFN0cmluZyB2ZXJzaW9uKSB7Ci0gICAgICAgIGlmICh2ZXJzaW9uICE9IG51bGwpIHsKLSAgICAgICAgICAgIHhtbFZlcnNpb24gPSB2ZXJzaW9uOwotICAgICAgICAgICAgX2hhbmRsZXIuc2V0VmVyc2lvbih4bWxWZXJzaW9uKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0RW5jb2RpbmcoKSB7Ci0gICAgICAgIHJldHVybiB4bWxFbmNvZGluZzsKLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgc2V0RW5jb2RpbmcoU3RyaW5nIGVuY29kaW5nKSB7Ci0gICAgICAgIGlmIChlbmNvZGluZyAhPSBudWxsKSB7Ci0gICAgICAgICAgICB4bWxFbmNvZGluZyA9IGVuY29kaW5nOwotICAgICAgICAgICAgX2hhbmRsZXIuc2V0RW5jb2RpbmcoZW5jb2RpbmcpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLy8gRGVidWdnaW5nCi0gICAgcHJpdmF0ZSBTdHJpbmcgZ2V0Tm9kZVR5cGVGcm9tQ29kZShzaG9ydCBjb2RlKSB7Ci0gICAgICAgIFN0cmluZyByZXR2YWwgPSBudWxsOwotICAgICAgICBzd2l0Y2ggKGNvZGUpIHsKLSAgICAgICAgY2FzZSBOb2RlLkFUVFJJQlVURV9OT0RFIDoKLSAgICAgICAgICAgIHJldHZhbCA9ICJBVFRSSUJVVEVfTk9ERSI7IGJyZWFrOwotICAgICAgICBjYXNlIE5vZGUuQ0RBVEFfU0VDVElPTl9OT0RFIDoKLSAgICAgICAgICAgIHJldHZhbCA9ICJDREFUQV9TRUNUSU9OX05PREUiOyBicmVhazsKLSAgICAgICAgY2FzZSBOb2RlLkNPTU1FTlRfTk9ERSA6Ci0gICAgICAgICAgICByZXR2YWwgPSAiQ09NTUVOVF9OT0RFIjsgYnJlYWs7Ci0gICAgICAgIGNhc2UgTm9kZS5ET0NVTUVOVF9GUkFHTUVOVF9OT0RFIDoKLSAgICAgICAgICAgIHJldHZhbCA9ICJET0NVTUVOVF9GUkFHTUVOVF9OT0RFIjsgYnJlYWs7Ci0gICAgICAgIGNhc2UgTm9kZS5ET0NVTUVOVF9OT0RFIDoKLSAgICAgICAgICAgIHJldHZhbCA9ICJET0NVTUVOVF9OT0RFIjsgYnJlYWs7Ci0gICAgICAgIGNhc2UgTm9kZS5ET0NVTUVOVF9UWVBFX05PREUgOgotICAgICAgICAgICAgcmV0dmFsID0gIkRPQ1VNRU5UX1RZUEVfTk9ERSI7IGJyZWFrOwotICAgICAgICBjYXNlIE5vZGUuRUxFTUVOVF9OT0RFIDoKLSAgICAgICAgICAgIHJldHZhbCA9ICJFTEVNRU5UX05PREUiOyBicmVhazsKLSAgICAgICAgY2FzZSBOb2RlLkVOVElUWV9OT0RFIDoKLSAgICAgICAgICAgIHJldHZhbCA9ICJFTlRJVFlfTk9ERSI7IGJyZWFrOwotICAgICAgICBjYXNlIE5vZGUuRU5USVRZX1JFRkVSRU5DRV9OT0RFIDoKLSAgICAgICAgICAgIHJldHZhbCA9ICJFTlRJVFlfUkVGRVJFTkNFX05PREUiOyBicmVhazsKLSAgICAgICAgY2FzZSBOb2RlLk5PVEFUSU9OX05PREUgOgotICAgICAgICAgICAgcmV0dmFsID0gIk5PVEFUSU9OX05PREUiOyBicmVhazsKLSAgICAgICAgY2FzZSBOb2RlLlBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERSA6Ci0gICAgICAgICAgICByZXR2YWwgPSAiUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFIjsgYnJlYWs7Ci0gICAgICAgIGNhc2UgTm9kZS5URVhUX05PREU6Ci0gICAgICAgICAgICByZXR2YWwgPSAiVEVYVF9OT0RFIjsgYnJlYWs7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHJldHZhbDsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3RyYXgvT3V0cHV0U2V0dGluZ3MuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvdHJheC9PdXRwdXRTZXR0aW5ncy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjZDMwZGYzLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvdHJheC9PdXRwdXRTZXR0aW5ncy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDkgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogT3V0cHV0U2V0dGluZ3MuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8wNiAxMTo1OToxMSBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMudHJheDsKLQotaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0aWVzOwotCi0vKioKLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgT3V0cHV0U2V0dGluZ3MgewotCi0gICAgcHJpdmF0ZSBTdHJpbmcgX2NkYXRhX3NlY3Rpb25fZWxlbWVudHMgPSBudWxsOwotICAgIHByaXZhdGUgU3RyaW5nIF9kb2N0eXBlX3B1YmxpYyA9IG51bGw7Ci0gICAgcHJpdmF0ZSBTdHJpbmcgX2VuY29kaW5nID0gbnVsbDsKLSAgICBwcml2YXRlIFN0cmluZyBfaW5kZW50ID0gbnVsbDsKLSAgICBwcml2YXRlIFN0cmluZyBfbWVkaWFfdHlwZSA9IG51bGw7Ci0gICAgcHJpdmF0ZSBTdHJpbmcgX21ldGhvZCA9IG51bGw7Ci0gICAgcHJpdmF0ZSBTdHJpbmcgX29taXRfeG1sX2RlY2xhcmF0aW9uID0gbnVsbDsKLSAgICBwcml2YXRlIFN0cmluZyBfc3RhbmRhbG9uZSA9IG51bGw7Ci0gICAgcHJpdmF0ZSBTdHJpbmcgX3ZlcnNpb24gPSBudWxsOwotCi0gICAgcHVibGljIFByb3BlcnRpZXMgZ2V0UHJvcGVydGllcygpIHsKLSAgICAgICAgUHJvcGVydGllcyBwcm9wZXJ0aWVzID0gbmV3IFByb3BlcnRpZXMoKTsKLSAgICAgICAgcmV0dXJuKHByb3BlcnRpZXMpOwotICAgIH0KLQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3RyYXgvU0FYMkRPTS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy90cmF4L1NBWDJET00uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOGNmNjJjMC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3RyYXgvU0FYMkRPTS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzM3ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFNBWDJET00uamF2YSx2IDEuOC4yLjEgMjAwNi8xMi8wNCAxODo0NTo0MSBzcGVyaWNhcyBFeHAgJAotICovCi0KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMudHJheDsKLQotaW1wb3J0IGphdmEudXRpbC5TdGFjazsKLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlcjsKLQotaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlckZhY3Rvcnk7Ci1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5ydW50aW1lLkNvbnN0YW50czsKLQotaW1wb3J0IG9yZy53M2MuZG9tLkNvbW1lbnQ7Ci1pbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7Ci1pbXBvcnQgb3JnLnczYy5kb20uRWxlbWVudDsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotaW1wb3J0IG9yZy53M2MuZG9tLlRleHQ7Ci1pbXBvcnQgb3JnLnczYy5kb20uUHJvY2Vzc2luZ0luc3RydWN0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LkF0dHJpYnV0ZXM7Ci1pbXBvcnQgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguTG9jYXRvcjsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguZXh0LkxleGljYWxIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LmV4dC5Mb2NhdG9yMjsKLQotLyoqCi0gKiBAYXV0aG9yIEcuIFRvZGQgTWlsbGVyCi0gKiBAYXV0aG9yIFN1bml0aGEgUmVkZHkKLSAqIEBhdXRob3IgSHVpemhlIFdhbmcKLSAqLwotcHVibGljIGNsYXNzIFNBWDJET00gaW1wbGVtZW50cyBDb250ZW50SGFuZGxlciwgTGV4aWNhbEhhbmRsZXIsIENvbnN0YW50cyB7Ci0KLSAgICBwcml2YXRlIE5vZGUgX3Jvb3QgPSBudWxsOwotICAgIHByaXZhdGUgRG9jdW1lbnQgX2RvY3VtZW50ID0gbnVsbDsKLSAgICBwcml2YXRlIE5vZGUgX25leHRTaWJsaW5nID0gbnVsbDsKLSAgICBwcml2YXRlIFN0YWNrIF9ub2RlU3RrID0gbmV3IFN0YWNrKCk7Ci0gICAgcHJpdmF0ZSBWZWN0b3IgX25hbWVzcGFjZURlY2xzID0gbnVsbDsKLSAgICBwcml2YXRlIE5vZGUgX2xhc3RTaWJsaW5nID0gbnVsbDsKLSAgICBwcml2YXRlIExvY2F0b3IgbG9jYXRvciA9IG51bGw7Ci0gICAgcHJpdmF0ZSBib29sZWFuIG5lZWRUb1NldERvY3VtZW50SW5mbyA9IHRydWU7Ci0KLSAgICAvL1JlcGxhY2UgU3RyaW5nQnVmZmVyIHdpdGggU3RyaW5nQnVpbGRlciBub3cgdGhhdCB3ZSBubyBsb25nIHN1cHBvcnQgamRrMS40Ci0gICAgcHJpdmF0ZSBTdHJpbmdCdWlsZGVyIF90ZXh0QnVmZmVyID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKLSAgICBwcml2YXRlIE5vZGUgX25leHRTaWJsaW5nQ2FjaGUgPSBudWxsOwotICAgIC8qKgotICAgICAqIEpBWFAgZG9jdW1lbnQgYnVpbGRlciBmYWN0b3J5LiBDcmVhdGUgYSBzaW5nbGUgaW5zdGFuY2UgYW5kIHVzZQotICAgICAqIHN5bmNocm9uaXphdGlvbiBiZWNhdXNlIHRoZSBKYXZhZG9jIGlzIG5vdCBleHBsaWNpdCBhYm91dAotICAgICAqIHRocmVhZCBzYWZldHkuCi0gICAgICovCi0gICAgcHJpdmF0ZSBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5IF9mYWN0b3J5ID0KLSAgICAgICAgICAgIERvY3VtZW50QnVpbGRlckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKLSAgICBwcml2YXRlIGJvb2xlYW4gX2ludGVybmFsID0gdHJ1ZTsKLQotICAgIHB1YmxpYyBTQVgyRE9NKGJvb2xlYW4gdXNlU2VydmljZXNNZWNoYW5pc20pIHRocm93cyBQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIHsKLSAgICAgICAgX2RvY3VtZW50ID0gY3JlYXRlRG9jdW1lbnQodXNlU2VydmljZXNNZWNoYW5pc20pOwotICAgICAgICBfcm9vdCA9IF9kb2N1bWVudDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU0FYMkRPTShOb2RlIHJvb3QsIE5vZGUgbmV4dFNpYmxpbmcsIGJvb2xlYW4gdXNlU2VydmljZXNNZWNoYW5pc20pIHRocm93cyBQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIHsKLSAgICAgICAgX3Jvb3QgPSByb290OwotICAgICAgICBpZiAocm9vdCBpbnN0YW5jZW9mIERvY3VtZW50KSB7Ci0gICAgICAgICAgX2RvY3VtZW50ID0gKERvY3VtZW50KXJvb3Q7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAocm9vdCAhPSBudWxsKSB7Ci0gICAgICAgICAgX2RvY3VtZW50ID0gcm9vdC5nZXRPd25lckRvY3VtZW50KCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgX2RvY3VtZW50ID0gY3JlYXRlRG9jdW1lbnQodXNlU2VydmljZXNNZWNoYW5pc20pOwotICAgICAgICAgIF9yb290ID0gX2RvY3VtZW50OwotICAgICAgICB9Ci0KLSAgICAgICAgX25leHRTaWJsaW5nID0gbmV4dFNpYmxpbmc7Ci0gICAgfQotCi0gICAgcHVibGljIFNBWDJET00oTm9kZSByb290LCBib29sZWFuIHVzZVNlcnZpY2VzTWVjaGFuaXNtKSB0aHJvd3MgUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiB7Ci0gICAgICAgIHRoaXMocm9vdCwgbnVsbCwgdXNlU2VydmljZXNNZWNoYW5pc20pOwotICAgIH0KLQotICAgIHB1YmxpYyBOb2RlIGdldERPTSgpIHsKLSAgICAgICAgcmV0dXJuIF9yb290OwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGNoYXJhY3RlcnMoY2hhcltdIGNoLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpIHsKLSAgICAgICAgLy8gSWdub3JlIHRleHQgbm9kZXMgb2YgbGVuZ3RoIDAKLSAgICAgICAgaWYgKGxlbmd0aCA9PSAwKSB7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLQotICAgICAgICBmaW5hbCBOb2RlIGxhc3QgPSAoTm9kZSlfbm9kZVN0ay5wZWVrKCk7Ci0KLSAgICAgICAgLy8gTm8gdGV4dCBub2RlcyBjYW4gYmUgY2hpbGRyZW4gb2Ygcm9vdCAoRE9NMDA2IGV4Y2VwdGlvbikKLSAgICAgICAgaWYgKGxhc3QgIT0gX2RvY3VtZW50KSB7Ci0gICAgICAgICAgICBfbmV4dFNpYmxpbmdDYWNoZSA9IF9uZXh0U2libGluZzsKLSAgICAgICAgICAgIF90ZXh0QnVmZmVyLmFwcGVuZChjaCwgc3RhcnQsIGxlbmd0aCk7Ci0gICAgICAgIH0KLSAgICB9Ci0gICAgcHJpdmF0ZSB2b2lkIGFwcGVuZFRleHROb2RlKCkgewotICAgICAgICBpZiAoX3RleHRCdWZmZXIubGVuZ3RoKCkgPiAwKSB7Ci0gICAgICAgICAgICBmaW5hbCBOb2RlIGxhc3QgPSAoTm9kZSlfbm9kZVN0ay5wZWVrKCk7Ci0gICAgICAgICAgICBpZiAobGFzdCA9PSBfcm9vdCAmJiBfbmV4dFNpYmxpbmdDYWNoZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgX2xhc3RTaWJsaW5nID0gbGFzdC5pbnNlcnRCZWZvcmUoX2RvY3VtZW50LmNyZWF0ZVRleHROb2RlKF90ZXh0QnVmZmVyLnRvU3RyaW5nKCkpLCBfbmV4dFNpYmxpbmdDYWNoZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBfbGFzdFNpYmxpbmcgPSBsYXN0LmFwcGVuZENoaWxkKF9kb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShfdGV4dEJ1ZmZlci50b1N0cmluZygpKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBfdGV4dEJ1ZmZlci5zZXRMZW5ndGgoMCk7Ci0gICAgICAgIH0KLSAgICB9Ci0gICAgcHVibGljIHZvaWQgc3RhcnREb2N1bWVudCgpIHsKLSAgICAgICAgX25vZGVTdGsucHVzaChfcm9vdCk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgZW5kRG9jdW1lbnQoKSB7Ci0gICAgICAgIF9ub2RlU3RrLnBvcCgpOwotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBzZXREb2N1bWVudEluZm8oKSB7Ci0gICAgICAgIC8vdHJ5IHRvIHNldCBkb2N1bWVudCB2ZXJzaW9uCi0gICAgICAgIGlmIChsb2NhdG9yID09IG51bGwpIHJldHVybjsKLSAgICAgICAgdHJ5ewotICAgICAgICAgICAgX2RvY3VtZW50LnNldFhtbFZlcnNpb24oKChMb2NhdG9yMilsb2NhdG9yKS5nZXRYTUxWZXJzaW9uKCkpOwotICAgICAgICB9Y2F0Y2goQ2xhc3NDYXN0RXhjZXB0aW9uIGUpe30KLQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudChTdHJpbmcgbmFtZXNwYWNlLCBTdHJpbmcgbG9jYWxOYW1lLCBTdHJpbmcgcU5hbWUsCi0gICAgICAgIEF0dHJpYnV0ZXMgYXR0cnMpCi0gICAgewotICAgICAgICBhcHBlbmRUZXh0Tm9kZSgpOwotICAgICAgICBpZiAobmVlZFRvU2V0RG9jdW1lbnRJbmZvKSB7Ci0gICAgICAgICAgICBzZXREb2N1bWVudEluZm8oKTsKLSAgICAgICAgICAgIG5lZWRUb1NldERvY3VtZW50SW5mbyA9IGZhbHNlOwotICAgICAgICB9Ci0KLSAgICAgICAgZmluYWwgRWxlbWVudCB0bXAgPSAoRWxlbWVudClfZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKG5hbWVzcGFjZSwgcU5hbWUpOwotCi0gICAgICAgIC8vIEFkZCBuYW1lc3BhY2UgZGVjbGFyYXRpb25zIGZpcnN0Ci0gICAgICAgIGlmIChfbmFtZXNwYWNlRGVjbHMgIT0gbnVsbCkgewotICAgICAgICAgICAgZmluYWwgaW50IG5EZWNscyA9IF9uYW1lc3BhY2VEZWNscy5zaXplKCk7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG5EZWNsczsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIHByZWZpeCA9IChTdHJpbmcpIF9uYW1lc3BhY2VEZWNscy5lbGVtZW50QXQoaSsrKTsKLQotICAgICAgICAgICAgICAgIGlmIChwcmVmaXggPT0gbnVsbCB8fCBwcmVmaXguZXF1YWxzKEVNUFRZU1RSSU5HKSkgewotICAgICAgICAgICAgICAgICAgICB0bXAuc2V0QXR0cmlidXRlTlMoWE1MTlNfVVJJLCBYTUxOU19QUkVGSVgsCi0gICAgICAgICAgICAgICAgICAgICAgICAoU3RyaW5nKSBfbmFtZXNwYWNlRGVjbHMuZWxlbWVudEF0KGkpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIHRtcC5zZXRBdHRyaWJ1dGVOUyhYTUxOU19VUkksIFhNTE5TX1NUUklORyArIHByZWZpeCwKLSAgICAgICAgICAgICAgICAgICAgICAgIChTdHJpbmcpIF9uYW1lc3BhY2VEZWNscy5lbGVtZW50QXQoaSkpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIF9uYW1lc3BhY2VEZWNscy5jbGVhcigpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gQWRkIGF0dHJpYnV0ZXMgdG8gZWxlbWVudAotLyogICAgICBmaW5hbCBpbnQgbmF0dHJzID0gYXR0cnMuZ2V0TGVuZ3RoKCk7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbmF0dHJzOyBpKyspIHsKLSAgICAgICAgICAgIGlmIChhdHRycy5nZXRMb2NhbE5hbWUoaSkgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHRtcC5zZXRBdHRyaWJ1dGUoYXR0cnMuZ2V0UU5hbWUoaSksIGF0dHJzLmdldFZhbHVlKGkpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIHRtcC5zZXRBdHRyaWJ1dGVOUyhhdHRycy5nZXRVUkkoaSksIGF0dHJzLmdldFFOYW1lKGkpLAotICAgICAgICAgICAgICAgICAgICBhdHRycy5nZXRWYWx1ZShpKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gKi8KLQotCi0gICAgICAgIC8vIEFkZCBhdHRyaWJ1dGVzIHRvIGVsZW1lbnQKLSAgICAgICAgZmluYWwgaW50IG5hdHRycyA9IGF0dHJzLmdldExlbmd0aCgpOwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG5hdHRyczsgaSsrKSB7Ci0gICAgICAgICAgICAvLyBjaGVja2luZyBpZiBOYW1lc3BhY2UgcHJvY2Vzc2luZyBpcyBiZWluZyBkb25lCi0gICAgICAgICAgICBTdHJpbmcgYXR0UU5hbWUgPSBhdHRycy5nZXRRTmFtZShpKTsKLSAgICAgICAgICAgIFN0cmluZyBhdHRVUkkgPSBhdHRycy5nZXRVUkkoaSk7Ci0gICAgICAgICAgICBpZiAoYXR0cnMuZ2V0TG9jYWxOYW1lKGkpLmVxdWFscygiIikpIHsKLSAgICAgICAgICAgICAgICB0bXAuc2V0QXR0cmlidXRlKGF0dFFOYW1lLCBhdHRycy5nZXRWYWx1ZShpKSk7Ci0gICAgICAgICAgICAgICAgaWYgKGF0dHJzLmdldFR5cGUoaSkuZXF1YWxzKCJJRCIpKSB7Ci0gICAgICAgICAgICAgICAgICAgIHRtcC5zZXRJZEF0dHJpYnV0ZShhdHRRTmFtZSwgdHJ1ZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICB0bXAuc2V0QXR0cmlidXRlTlMoYXR0VVJJLCBhdHRRTmFtZSwgYXR0cnMuZ2V0VmFsdWUoaSkpOwotICAgICAgICAgICAgICAgIGlmIChhdHRycy5nZXRUeXBlKGkpLmVxdWFscygiSUQiKSkgewotICAgICAgICAgICAgICAgICAgICB0bXAuc2V0SWRBdHRyaWJ1dGVOUyhhdHRVUkksIGF0dHJzLmdldExvY2FsTmFtZShpKSwgdHJ1ZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLQotICAgICAgICAvLyBBcHBlbmQgdGhpcyBuZXcgbm9kZSBvbnRvIGN1cnJlbnQgc3RhY2sgbm9kZQotICAgICAgICBOb2RlIGxhc3QgPSAoTm9kZSlfbm9kZVN0ay5wZWVrKCk7Ci0KLSAgICAgICAgLy8gSWYgdGhlIFNBWDJET00gaXMgY3JlYXRlZCB3aXRoIGEgbm9uLW51bGwgbmV4dCBzaWJsaW5nIG5vZGUsCi0gICAgICAgIC8vIGluc2VydCB0aGUgcmVzdWx0IG5vZGVzIGJlZm9yZSB0aGUgbmV4dCBzaWJsaW5nIHVuZGVyIHRoZSByb290LgotICAgICAgICBpZiAobGFzdCA9PSBfcm9vdCAmJiBfbmV4dFNpYmxpbmcgIT0gbnVsbCkKLSAgICAgICAgICAgIGxhc3QuaW5zZXJ0QmVmb3JlKHRtcCwgX25leHRTaWJsaW5nKTsKLSAgICAgICAgZWxzZQotICAgICAgICAgICAgbGFzdC5hcHBlbmRDaGlsZCh0bXApOwotCi0gICAgICAgIC8vIFB1c2ggdGhpcyBub2RlIG9udG8gc3RhY2sKLSAgICAgICAgX25vZGVTdGsucHVzaCh0bXApOwotICAgICAgICBfbGFzdFNpYmxpbmcgPSBudWxsOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGVuZEVsZW1lbnQoU3RyaW5nIG5hbWVzcGFjZSwgU3RyaW5nIGxvY2FsTmFtZSwgU3RyaW5nIHFOYW1lKSB7Ci0gICAgICAgIGFwcGVuZFRleHROb2RlKCk7Ci0gICAgICAgIF9ub2RlU3RrLnBvcCgpOwotICAgICAgICBfbGFzdFNpYmxpbmcgPSBudWxsOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHN0YXJ0UHJlZml4TWFwcGluZyhTdHJpbmcgcHJlZml4LCBTdHJpbmcgdXJpKSB7Ci0gICAgICAgIGlmIChfbmFtZXNwYWNlRGVjbHMgPT0gbnVsbCkgewotICAgICAgICAgICAgX25hbWVzcGFjZURlY2xzID0gbmV3IFZlY3RvcigyKTsKLSAgICAgICAgfQotICAgICAgICBfbmFtZXNwYWNlRGVjbHMuYWRkRWxlbWVudChwcmVmaXgpOwotICAgICAgICBfbmFtZXNwYWNlRGVjbHMuYWRkRWxlbWVudCh1cmkpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGVuZFByZWZpeE1hcHBpbmcoU3RyaW5nIHByZWZpeCkgewotICAgICAgICAvLyBkbyBub3RoaW5nCi0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBjbGFzcyBpcyBvbmx5IHVzZWQgaW50ZXJuYWxseSBzbyB0aGlzIG1ldGhvZCBzaG91bGQgbmV2ZXIKLSAgICAgKiBiZSBjYWxsZWQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgaWdub3JhYmxlV2hpdGVzcGFjZShjaGFyW10gY2gsIGludCBzdGFydCwgaW50IGxlbmd0aCkgewotICAgIH0KLQotICAgIC8qKgotICAgICAqIGFkZHMgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiBub2RlIHRvIERPTS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oU3RyaW5nIHRhcmdldCwgU3RyaW5nIGRhdGEpIHsKLSAgICAgICAgYXBwZW5kVGV4dE5vZGUoKTsKLSAgICAgICAgZmluYWwgTm9kZSBsYXN0ID0gKE5vZGUpX25vZGVTdGsucGVlaygpOwotICAgICAgICBQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24gcGkgPSBfZG9jdW1lbnQuY3JlYXRlUHJvY2Vzc2luZ0luc3RydWN0aW9uKAotICAgICAgICAgICAgICAgIHRhcmdldCwgZGF0YSk7Ci0gICAgICAgIGlmIChwaSAhPSBudWxsKXsKLSAgICAgICAgICBpZiAobGFzdCA9PSBfcm9vdCAmJiBfbmV4dFNpYmxpbmcgIT0gbnVsbCkKLSAgICAgICAgICAgICAgbGFzdC5pbnNlcnRCZWZvcmUocGksIF9uZXh0U2libGluZyk7Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgICAgICBsYXN0LmFwcGVuZENoaWxkKHBpKTsKLQotICAgICAgICAgIF9sYXN0U2libGluZyA9IHBpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBjbGFzcyBpcyBvbmx5IHVzZWQgaW50ZXJuYWxseSBzbyB0aGlzIG1ldGhvZCBzaG91bGQgbmV2ZXIKLSAgICAgKiBiZSBjYWxsZWQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RG9jdW1lbnRMb2NhdG9yKExvY2F0b3IgbG9jYXRvcikgewotICAgICAgICB0aGlzLmxvY2F0b3IgPSBsb2NhdG9yOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgY2xhc3MgaXMgb25seSB1c2VkIGludGVybmFsbHkgc28gdGhpcyBtZXRob2Qgc2hvdWxkIG5ldmVyCi0gICAgICogYmUgY2FsbGVkLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNraXBwZWRFbnRpdHkoU3RyaW5nIG5hbWUpIHsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIExleGljYWwgSGFuZGxlciBtZXRob2QgdG8gY3JlYXRlIGNvbW1lbnQgbm9kZSBpbiBET00gdHJlZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBjb21tZW50KGNoYXJbXSBjaCwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKSB7Ci0gICAgICAgIGFwcGVuZFRleHROb2RlKCk7Ci0gICAgICAgIGZpbmFsIE5vZGUgbGFzdCA9IChOb2RlKV9ub2RlU3RrLnBlZWsoKTsKLSAgICAgICAgQ29tbWVudCBjb21tZW50ID0gX2RvY3VtZW50LmNyZWF0ZUNvbW1lbnQobmV3IFN0cmluZyhjaCxzdGFydCxsZW5ndGgpKTsKLSAgICAgICAgaWYgKGNvbW1lbnQgIT0gbnVsbCl7Ci0gICAgICAgICAgaWYgKGxhc3QgPT0gX3Jvb3QgJiYgX25leHRTaWJsaW5nICE9IG51bGwpCi0gICAgICAgICAgICAgIGxhc3QuaW5zZXJ0QmVmb3JlKGNvbW1lbnQsIF9uZXh0U2libGluZyk7Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgICAgICBsYXN0LmFwcGVuZENoaWxkKGNvbW1lbnQpOwotCi0gICAgICAgICAgX2xhc3RTaWJsaW5nID0gY29tbWVudDsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8vIExleGljYWwgSGFuZGxlciBtZXRob2RzLSBub3QgaW1wbGVtZW50ZWQKLSAgICBwdWJsaWMgdm9pZCBzdGFydENEQVRBKCkgeyB9Ci0gICAgcHVibGljIHZvaWQgZW5kQ0RBVEEoKSB7IH0KLSAgICBwdWJsaWMgdm9pZCBzdGFydEVudGl0eShqYXZhLmxhbmcuU3RyaW5nIG5hbWUpIHsgfQotICAgIHB1YmxpYyB2b2lkIGVuZERURCgpIHsgfQotICAgIHB1YmxpYyB2b2lkIGVuZEVudGl0eShTdHJpbmcgbmFtZSkgeyB9Ci0gICAgcHVibGljIHZvaWQgc3RhcnREVEQoU3RyaW5nIG5hbWUsIFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uIHt9Ci0KLSAgICBwcml2YXRlIERvY3VtZW50IGNyZWF0ZURvY3VtZW50KGJvb2xlYW4gdXNlU2VydmljZXNNZWNoYW5pc20pIHRocm93cyBQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKF9mYWN0b3J5ID09IG51bGwpIHsKLSAgICAgICAgICAgIGlmICh1c2VTZXJ2aWNlc01lY2hhbmlzbSkgewotICAgICAgICAgICAgICAgIF9mYWN0b3J5ID0gRG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5uZXdJbnN0YW5jZSgpOwotICAgICAgICAgICAgICAgIGlmICghKF9mYWN0b3J5IGluc3RhbmNlb2YgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5qYXhwLkRvY3VtZW50QnVpbGRlckZhY3RvcnlJbXBsKSkgewotICAgICAgICAgICAgICAgICAgICBfaW50ZXJuYWwgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIF9mYWN0b3J5ID0gRG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5uZXdJbnN0YW5jZSgKLSAgICAgICAgICAgICAgICAgICJjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmpheHAuRG9jdW1lbnRCdWlsZGVyRmFjdG9yeUltcGwiLAotICAgICAgICAgICAgICAgICAgU0FYMkRPTS5jbGFzcy5nZXRDbGFzc0xvYWRlcigpCi0gICAgICAgICAgICAgICAgICApOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIERvY3VtZW50IGRvYzsKLSAgICAgICAgaWYgKF9pbnRlcm5hbCkgewotICAgICAgICAgICAgLy9kZWZhdWx0IGltcGxlbWVudGF0aW9uIGlzIHRocmVhZCBzYWZlCi0gICAgICAgICAgICBkb2MgPSBfZmFjdG9yeS5uZXdEb2N1bWVudEJ1aWxkZXIoKS5uZXdEb2N1bWVudCgpOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgc3luY2hyb25pemVkKFNBWDJET00uY2xhc3MpIHsKLSAgICAgICAgICAgICAgICBkb2MgPSBfZmFjdG9yeS5uZXdEb2N1bWVudEJ1aWxkZXIoKS5uZXdEb2N1bWVudCgpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBkb2M7Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3RyYXgvU0FYMlN0QVhCYXNlV3JpdGVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3RyYXgvU0FYMlN0QVhCYXNlV3JpdGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDJmY2Y0ZGMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy90cmF4L1NBWDJTdEFYQmFzZVdyaXRlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjQ4ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnRyYXg7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5Mb2NhdGlvbjsKLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLlhNTFJlcG9ydGVyOwotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uWE1MU3RyZWFtRXhjZXB0aW9uOwotCi1pbXBvcnQgb3JnLnhtbC5zYXguQXR0cmlidXRlczsKLWltcG9ydCBvcmcueG1sLnNheC5Mb2NhdG9yOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhQYXJzZUV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguaGVscGVycy5EZWZhdWx0SGFuZGxlcjsKLQotCi1wdWJsaWMgYWJzdHJhY3QgY2xhc3MgU0FYMlN0QVhCYXNlV3JpdGVyIGV4dGVuZHMgRGVmYXVsdEhhbmRsZXIKLSAgICAgICAgICAgICAgICBpbXBsZW1lbnRzCi0gICAgICAgICAgICAgICAgICAgICAgICBMZXhpY2FsSGFuZGxlciB7Ci0KLQotICAgICAgICBwcm90ZWN0ZWQgYm9vbGVhbiBpc0NEQVRBOwotCi0gICAgICAgIHByb3RlY3RlZCBTdHJpbmdCdWZmZXIgQ0RBVEFCdWZmZXI7Ci0KLSAgICAgICAgcHJvdGVjdGVkIFZlY3RvciBuYW1lc3BhY2VzOwotCi0gICAgICAgIHByb3RlY3RlZCBMb2NhdG9yIGRvY0xvY2F0b3I7Ci0KLSAgICAgICAgcHJvdGVjdGVkIFhNTFJlcG9ydGVyIHJlcG9ydGVyOwotCi0gICAgICAgIHB1YmxpYyBTQVgyU3RBWEJhc2VXcml0ZXIoKSB7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgU0FYMlN0QVhCYXNlV3JpdGVyKFhNTFJlcG9ydGVyIHJlcG9ydGVyKSB7Ci0gICAgICAgICAgICAgICAgdGhpcy5yZXBvcnRlciA9IHJlcG9ydGVyOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIHZvaWQgc2V0WE1MUmVwb3J0ZXIoWE1MUmVwb3J0ZXIgcmVwb3J0ZXIpIHsKLSAgICAgICAgICAgICAgICB0aGlzLnJlcG9ydGVyID0gcmVwb3J0ZXI7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCBzZXREb2N1bWVudExvY2F0b3IoTG9jYXRvciBsb2NhdG9yKSB7Ci0gICAgICAgICAgICAgICAgdGhpcy5kb2NMb2NhdG9yID0gbG9jYXRvcjsKLSAgICAgICAgfQotCi0KLSAgICAgICAgcHVibGljIExvY2F0aW9uIGdldEN1cnJlbnRMb2NhdGlvbigpIHsKLSAgICAgICAgICAgICAgICBpZiAoZG9jTG9jYXRvciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFNBWExvY2F0aW9uKGRvY0xvY2F0b3IpOwotICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyB2b2lkIGVycm9yKFNBWFBhcnNlRXhjZXB0aW9uIGUpIHRocm93cyBTQVhFeGNlcHRpb24gewotICAgICAgICAgICAgICAgIHJlcG9ydEV4Y2VwdGlvbigiRVJST1IiLCBlKTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyB2b2lkIGZhdGFsRXJyb3IoU0FYUGFyc2VFeGNlcHRpb24gZSkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICAgICAgcmVwb3J0RXhjZXB0aW9uKCJGQVRBTCIsIGUpOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIHZvaWQgd2FybmluZyhTQVhQYXJzZUV4Y2VwdGlvbiBlKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICAgICAgICAgICAgICByZXBvcnRFeGNlcHRpb24oIldBUk5JTkciLCBlKTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyB2b2lkIHN0YXJ0RG9jdW1lbnQoKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICAgICAgICAgICAgICAgICAgbmFtZXNwYWNlcyA9IG5ldyBWZWN0b3IoMik7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCBlbmREb2N1bWVudCgpIHRocm93cyBTQVhFeGNlcHRpb24gewotICAgICAgICAgICAgICAgIG5hbWVzcGFjZXMgPSBudWxsOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIHZvaWQgc3RhcnRFbGVtZW50KFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUsIFN0cmluZyBxTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgIEF0dHJpYnV0ZXMgYXR0cmlidXRlcykgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBuYW1lc3BhY2VzID0gbnVsbDsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyB2b2lkIGVuZEVsZW1lbnQoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSwgU3RyaW5nIHFOYW1lKQotICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICAgICAgbmFtZXNwYWNlcyA9IG51bGw7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCBzdGFydFByZWZpeE1hcHBpbmcoU3RyaW5nIHByZWZpeCwgU3RyaW5nIHVyaSkKLSAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24gewotCi0gICAgICAgICAgICAgICAgaWYgKHByZWZpeCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBwcmVmaXggPSAiIjsKLSAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHByZWZpeC5lcXVhbHMoInhtbCIpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgaWYgKG5hbWVzcGFjZXMgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBuYW1lc3BhY2VzID0gbmV3IFZlY3RvcigyKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgbmFtZXNwYWNlcy5hZGRFbGVtZW50KHByZWZpeCk7Ci0gICAgICAgICAgICAgICAgbmFtZXNwYWNlcy5hZGRFbGVtZW50KHVyaSk7Ci0gICAgICAgIH0KLQotCi0gICAgICAgIHB1YmxpYyB2b2lkIGVuZFByZWZpeE1hcHBpbmcoU3RyaW5nIHByZWZpeCkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCBzdGFydENEQVRBKCkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICAgICAgaXNDREFUQSA9IHRydWU7Ci0gICAgICAgICAgICAgICAgaWYgKENEQVRBQnVmZmVyID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIENEQVRBQnVmZmVyID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBDREFUQUJ1ZmZlci5zZXRMZW5ndGgoMCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIHZvaWQgY2hhcmFjdGVycyhjaGFyW10gY2gsIGludCBzdGFydCwgaW50IGxlbmd0aCkKLSAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24gewotICAgICAgICAgICAgICAgIGlmIChpc0NEQVRBKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBDREFUQUJ1ZmZlci5hcHBlbmQoY2gsIHN0YXJ0LCBsZW5ndGgpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyB2b2lkIGVuZENEQVRBKCkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICAgICAgaXNDREFUQSA9IGZhbHNlOwotICAgICAgICAgICAgICAgIENEQVRBQnVmZmVyLnNldExlbmd0aCgwKTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyB2b2lkIGNvbW1lbnQoY2hhcltdIGNoLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpIHRocm93cyBTQVhFeGNlcHRpb24gewotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIHZvaWQgZW5kRFREKCkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCBlbmRFbnRpdHkoU3RyaW5nIG5hbWUpIHRocm93cyBTQVhFeGNlcHRpb24gewotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIHZvaWQgc3RhcnREVEQoU3RyaW5nIG5hbWUsIFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkKQotICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCBzdGFydEVudGl0eShTdHJpbmcgbmFtZSkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogVXNlZCB0byByZXBvcnQgYSB7QGxpbmsgU0FYRXhjZXB0aW9ufXRvIHRoZSB7QGxpbmsgWE1MUmVwb3J0ZXJ9Ci0gICAgICAgICAqIHJlZ2lzdGVyZWQgd2l0aCB0aGlzIGhhbmRsZXIuCi0gICAgICAgICAqLwotICAgICAgICBwcm90ZWN0ZWQgdm9pZCByZXBvcnRFeGNlcHRpb24oU3RyaW5nIHR5cGUsIFNBWEV4Y2VwdGlvbiBlKQotICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgICAgICAgICBpZiAocmVwb3J0ZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0ZXIucmVwb3J0KGUuZ2V0TWVzc2FnZSgpLCB0eXBlLCBlLCBnZXRDdXJyZW50TG9jYXRpb24oKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChYTUxTdHJlYW1FeGNlcHRpb24gZTEpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbihlMSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFBhcnNlcyBhbiBYTUwgcXVhbGlmaWVkIG5hbWUsIGFuZCBwbGFjZXMgdGhlIHJlc3VsdGluZyBwcmVmaXggYW5kIGxvY2FsCi0gICAgICAgICAqIG5hbWUgaW4gdGhlIHByb3ZpZGVkIFN0cmluZyBhcnJheS4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIHFOYW1lIFRoZSBxdWFsaWZpZWQgbmFtZSB0byBwYXJzZS4KLSAgICAgICAgICogQHBhcmFtIHJlc3VsdHMgQW4gYXJyYXkgd2hlcmUgcGFyc2UgcmVzdWx0cyB3aWxsIGJlIHBsYWNlZC4gVGhlIHByZWZpeAotICAgICAgICAgKiAgICAgICAgICAgIHdpbGwgYmUgcGxhY2VkIGF0IDxjb2RlPnJlc3VsdHNbMF08L2NvZGU+LCBhbmQgdGhlIGxvY2FsCi0gICAgICAgICAqICAgICAgICAgICAgcGFydCBhdCA8Y29kZT5yZXN1bHRzWzFdPC9jb2RlPgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCB2b2lkIHBhcnNlUU5hbWUoU3RyaW5nIHFOYW1lLCBTdHJpbmdbXSByZXN1bHRzKSB7Ci0KLSAgICAgICAgICAgICAgICBTdHJpbmcgcHJlZml4LCBsb2NhbDsKLSAgICAgICAgICAgICAgICBpbnQgaWR4ID0gcU5hbWUuaW5kZXhPZignOicpOwotICAgICAgICAgICAgICAgIGlmIChpZHggPj0gMCkgewotICAgICAgICAgICAgICAgICAgICAgICAgcHJlZml4ID0gcU5hbWUuc3Vic3RyaW5nKDAsIGlkeCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBsb2NhbCA9IHFOYW1lLnN1YnN0cmluZyhpZHggKyAxKTsKLSAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgcHJlZml4ID0gIiI7Ci0gICAgICAgICAgICAgICAgICAgICAgICBsb2NhbCA9IHFOYW1lOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICByZXN1bHRzWzBdID0gcHJlZml4OwotICAgICAgICAgICAgICAgIHJlc3VsdHNbMV0gPSBsb2NhbDsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiB7QExpbmsgTG9jYXRpb259aW1wbGVtZW50YXRpb24gdXNlZCB0byBleHBvc2UgZGV0YWlscyBmcm9tIGEgU0FYCi0gICAgICAgICAqIHtAbGluayBMb2NhdG9yfS4KLSAgICAgICAgICoKLSAgICAgICAgICogQGF1dGhvciBjaHJpc3RpYW4KLSAgICAgICAgICovCi0gICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIFNBWExvY2F0aW9uIGltcGxlbWVudHMgTG9jYXRpb24gewotCi0gICAgICAgICAgICAgICAgcHJpdmF0ZSBpbnQgbGluZU51bWJlcjsKLSAgICAgICAgICAgICAgICBwcml2YXRlIGludCBjb2x1bW5OdW1iZXI7Ci0gICAgICAgICAgICAgICAgcHJpdmF0ZSBTdHJpbmcgcHVibGljSWQ7Ci0gICAgICAgICAgICAgICAgcHJpdmF0ZSBTdHJpbmcgc3lzdGVtSWQ7Ci0gICAgICAgICAgICAgICAgcHJpdmF0ZSBTQVhMb2NhdGlvbihMb2NhdG9yIGxvY2F0b3IpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGxpbmVOdW1iZXIgPSBsb2NhdG9yLmdldExpbmVOdW1iZXIoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGNvbHVtbk51bWJlciA9IGxvY2F0b3IuZ2V0Q29sdW1uTnVtYmVyKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBwdWJsaWNJZCA9IGxvY2F0b3IuZ2V0UHVibGljSWQoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHN5c3RlbUlkID0gbG9jYXRvci5nZXRTeXN0ZW1JZCgpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIHB1YmxpYyBpbnQgZ2V0TGluZU51bWJlcigpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBsaW5lTnVtYmVyOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIHB1YmxpYyBpbnQgZ2V0Q29sdW1uTnVtYmVyKCkgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNvbHVtbk51bWJlcjsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBwdWJsaWMgaW50IGdldENoYXJhY3Rlck9mZnNldCgpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAtMTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFB1YmxpY0lkKCkgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHB1YmxpY0lkOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3lzdGVtSWQoKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3lzdGVtSWQ7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3RyYXgvU0FYMlN0QVhFdmVudFdyaXRlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy90cmF4L1NBWDJTdEFYRXZlbnRXcml0ZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYzc3ZWE4My4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3RyYXgvU0FYMlN0QVhFdmVudFdyaXRlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDIwICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMDYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnRyYXg7Ci0KLWltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwotaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOwotaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKLWltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7Ci1pbXBvcnQgamF2YS51dGlsLkxpc3Q7Ci1pbXBvcnQgamF2YS51dGlsLk1hcDsKLQotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uWE1MRXZlbnRGYWN0b3J5OwotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uWE1MU3RyZWFtRXhjZXB0aW9uOwotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uZXZlbnRzLio7Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5YTUxFdmVudFdyaXRlcjsKLQotaW1wb3J0IG9yZy54bWwuc2F4LkF0dHJpYnV0ZXM7Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LmV4dC5Mb2NhdG9yMjsKLQotLyoqCi0gKiBAYXV0aG9yIFN1bml0aGEgUmVkZHkKLSAqLwotcHVibGljIGNsYXNzIFNBWDJTdEFYRXZlbnRXcml0ZXIgZXh0ZW5kcyBTQVgyU3RBWEJhc2VXcml0ZXIgewotCi0KLSAgICBwcml2YXRlIFhNTEV2ZW50V3JpdGVyIHdyaXRlcjsKLQotCi0gICAgcHJpdmF0ZSBYTUxFdmVudEZhY3RvcnkgZXZlbnRGYWN0b3J5OwotCi0KLSAgICBwcml2YXRlIExpc3QgbmFtZXNwYWNlU3RhY2sgPSBuZXcgQXJyYXlMaXN0KCk7Ci0KLQotICAgIHByaXZhdGUgYm9vbGVhbiBuZWVkVG9DYWxsU3RhcnREb2N1bWVudCA9IGZhbHNlOwotCi0KLSAgICBwdWJsaWMgU0FYMlN0QVhFdmVudFdyaXRlcigpIHsKLQotICAgICAgICBldmVudEZhY3RvcnkgPSBYTUxFdmVudEZhY3RvcnkubmV3SW5zdGFuY2UoKTsKLQotICAgIH0KLQotCi0gICAgcHVibGljIFNBWDJTdEFYRXZlbnRXcml0ZXIoWE1MRXZlbnRXcml0ZXIgd3JpdGVyKSB7Ci0KLSAgICAgICAgdGhpcy53cml0ZXIgPSB3cml0ZXI7Ci0gICAgICAgIGV2ZW50RmFjdG9yeSA9IFhNTEV2ZW50RmFjdG9yeS5uZXdJbnN0YW5jZSgpOwotCi0gICAgfQotCi0gICAgcHVibGljIFNBWDJTdEFYRXZlbnRXcml0ZXIoWE1MRXZlbnRXcml0ZXIgd3JpdGVyLAotICAgICAgICAgICAgWE1MRXZlbnRGYWN0b3J5IGZhY3RvcnkpIHsKLQotICAgICAgICB0aGlzLndyaXRlciA9IHdyaXRlcjsKLSAgICAgICAgaWYgKGZhY3RvcnkgIT0gbnVsbCkgewotCi0gICAgICAgICAgICB0aGlzLmV2ZW50RmFjdG9yeSA9IGZhY3Rvcnk7Ci0KLSAgICAgICAgfSBlbHNlIHsKLQotICAgICAgICAgICAgZXZlbnRGYWN0b3J5ID0gWE1MRXZlbnRGYWN0b3J5Lm5ld0luc3RhbmNlKCk7Ci0KLSAgICAgICAgfQotCi0gICAgfQotCi0gICAgcHVibGljIFhNTEV2ZW50V3JpdGVyIGdldEV2ZW50V3JpdGVyKCkgewotCi0gICAgICAgIHJldHVybiB3cml0ZXI7Ci0KLSAgICB9Ci0KLQotICAgIHB1YmxpYyB2b2lkIHNldEV2ZW50V3JpdGVyKFhNTEV2ZW50V3JpdGVyIHdyaXRlcikgewotCi0gICAgICAgIHRoaXMud3JpdGVyID0gd3JpdGVyOwotCi0gICAgfQotCi0KLSAgICBwdWJsaWMgWE1MRXZlbnRGYWN0b3J5IGdldEV2ZW50RmFjdG9yeSgpIHsKLQotICAgICAgICByZXR1cm4gZXZlbnRGYWN0b3J5OwotCi0gICAgfQotCi0KLSAgICBwdWJsaWMgdm9pZCBzZXRFdmVudEZhY3RvcnkoWE1MRXZlbnRGYWN0b3J5IGZhY3RvcnkpIHsKLQotICAgICAgICB0aGlzLmV2ZW50RmFjdG9yeSA9IGZhY3Rvcnk7Ci0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzdGFydERvY3VtZW50KCkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgc3VwZXIuc3RhcnREb2N1bWVudCgpOwotCi0gICAgICAgIG5hbWVzcGFjZVN0YWNrLmNsZWFyKCk7Ci0KLSAgICAgICAgZXZlbnRGYWN0b3J5LnNldExvY2F0aW9uKGdldEN1cnJlbnRMb2NhdGlvbigpKTsKLQotICAgICAgICAvLyBFbmNvZGluZyBhbmQgdmVyc2lvbiBpbmZvIHdpbGwgYmUgYXZhaWxhYmxlIG9ubHkgYWZ0ZXIgc3RhcnRFbGVtZW50Ci0gICAgICAgIC8vIGlzIGNhbGxlZCBmb3IgZmlyc3QgdGltZS4gU28sIGRlZmVyIFNUQVJUX0RPQ1VNRU5UIGV2ZW50IG9mIFN0QVggdGlsbAotICAgICAgICAvLyB0aGF0IHBvaW50IG9mIHRpbWUuCi0gICAgICAgIG5lZWRUb0NhbGxTdGFydERvY3VtZW50ID0gdHJ1ZTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgd3JpdGVTdGFydERvY3VtZW50KCkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBpZiAoZG9jTG9jYXRvciA9PSBudWxsKQotICAgICAgICAgICAgICAgIHdyaXRlci5hZGQoZXZlbnRGYWN0b3J5LmNyZWF0ZVN0YXJ0RG9jdW1lbnQoKSk7Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICB0cnl7Ci0gICAgICAgICAgICAgICAgICAgIHdyaXRlci5hZGQoZXZlbnRGYWN0b3J5LmNyZWF0ZVN0YXJ0RG9jdW1lbnQoKChMb2NhdG9yMilkb2NMb2NhdG9yKS5nZXRFbmNvZGluZygpLCgoTG9jYXRvcjIpZG9jTG9jYXRvcikuZ2V0WE1MVmVyc2lvbigpKSk7Ci0gICAgICAgICAgICAgICAgfSBjYXRjaChDbGFzc0Nhc3RFeGNlcHRpb24gZSl7Ci0gICAgICAgICAgICAgICAgICAgIHdyaXRlci5hZGQoZXZlbnRGYWN0b3J5LmNyZWF0ZVN0YXJ0RG9jdW1lbnQoKSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9IGNhdGNoIChYTUxTdHJlYW1FeGNlcHRpb24gZSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbihlKTsKLSAgICAgICAgfQotICAgICAgICBuZWVkVG9DYWxsU3RhcnREb2N1bWVudCA9IGZhbHNlOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGVuZERvY3VtZW50KCkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgZXZlbnRGYWN0b3J5LnNldExvY2F0aW9uKGdldEN1cnJlbnRMb2NhdGlvbigpKTsKLQotICAgICAgICB0cnkgewotCi0gICAgICAgICAgICB3cml0ZXIuYWRkKGV2ZW50RmFjdG9yeS5jcmVhdGVFbmREb2N1bWVudCgpKTsKLQotICAgICAgICB9IGNhdGNoIChYTUxTdHJlYW1FeGNlcHRpb24gZSkgewotCi0gICAgICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKGUpOwotCi0gICAgICAgIH0KLQotICAgICAgICBzdXBlci5lbmREb2N1bWVudCgpOwotCi0gICAgICAgIC8vIGNsZWFyIHRoZSBuYW1lc3BhY2VzCi0gICAgICAgIG5hbWVzcGFjZVN0YWNrLmNsZWFyKCk7Ci0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSwgU3RyaW5nIHFOYW1lLCBBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMpIHRocm93cyBTQVhFeGNlcHRpb24gewotCi0gICAgICAgIGlmIChuZWVkVG9DYWxsU3RhcnREb2N1bWVudCkgewotICAgICAgICAgICAgd3JpdGVTdGFydERvY3VtZW50KCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBzZXQgZG9jdW1lbnQgbG9jYXRpb24KLSAgICAgICAgZXZlbnRGYWN0b3J5LnNldExvY2F0aW9uKGdldEN1cnJlbnRMb2NhdGlvbigpKTsKLQotICAgICAgICAvLyBjcmVhdGUgYXR0cmlidXRlIGFuZCBuYW1lc3BhY2UgZXZlbnRzCi0gICAgICAgIENvbGxlY3Rpb25bXSBldmVudHMgPSB7bnVsbCwgbnVsbH07Ci0gICAgICAgIGNyZWF0ZVN0YXJ0RXZlbnRzKGF0dHJpYnV0ZXMsIGV2ZW50cyk7Ci0KLSAgICAgICAgbmFtZXNwYWNlU3RhY2suYWRkKGV2ZW50c1swXSk7Ci0KLSAgICAgICAgdHJ5IHsKLQotICAgICAgICAgICAgU3RyaW5nW10gcW5hbWUgPSB7bnVsbCwgbnVsbH07Ci0gICAgICAgICAgICBwYXJzZVFOYW1lKHFOYW1lLCBxbmFtZSk7Ci0KLSAgICAgICAgICAgIHdyaXRlci5hZGQoZXZlbnRGYWN0b3J5LmNyZWF0ZVN0YXJ0RWxlbWVudChxbmFtZVswXSwgdXJpLAotICAgICAgICAgICAgICAgICAgICBxbmFtZVsxXSwgZXZlbnRzWzFdLml0ZXJhdG9yKCksIGV2ZW50c1swXS5pdGVyYXRvcigpKSk7Ci0KLSAgICAgICAgfSBjYXRjaCAoWE1MU3RyZWFtRXhjZXB0aW9uIGUpIHsKLQotICAgICAgICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbihlKTsKLQotICAgICAgICB9IGZpbmFsbHkgewotCi0gICAgICAgICAgICBzdXBlci5zdGFydEVsZW1lbnQodXJpLCBsb2NhbE5hbWUsIHFOYW1lLCBhdHRyaWJ1dGVzKTsKLQotICAgICAgICB9Ci0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBlbmRFbGVtZW50KFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUsIFN0cmluZyBxTmFtZSkKLSAgICAgICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24gewotCi0gICAgICAgIHN1cGVyLmVuZEVsZW1lbnQodXJpLCBsb2NhbE5hbWUsIHFOYW1lKTsKLQotICAgICAgICBldmVudEZhY3Rvcnkuc2V0TG9jYXRpb24oZ2V0Q3VycmVudExvY2F0aW9uKCkpOwotCi0gICAgICAgIC8vIHBhcnNlIG5hbWUKLSAgICAgICAgU3RyaW5nW10gcW5hbWUgPSB7bnVsbCwgbnVsbH07Ci0gICAgICAgIHBhcnNlUU5hbWUocU5hbWUsIHFuYW1lKTsKLQotICAgICAgICAvLyBnZXQgbmFtZXNwYWNlcwotICAgICAgICBDb2xsZWN0aW9uIG5zTGlzdCA9IChDb2xsZWN0aW9uKSBuYW1lc3BhY2VTdGFjay5yZW1vdmUobmFtZXNwYWNlU3RhY2suc2l6ZSgpIC0gMSk7Ci0gICAgICAgIEl0ZXJhdG9yIG5zSXRlciA9IG5zTGlzdC5pdGVyYXRvcigpOwotCi0gICAgICAgIHRyeSB7Ci0KLSAgICAgICAgICAgIHdyaXRlci5hZGQoZXZlbnRGYWN0b3J5LmNyZWF0ZUVuZEVsZW1lbnQocW5hbWVbMF0sIHVyaSwgcW5hbWVbMV0sCi0gICAgICAgICAgICAgICAgICAgIG5zSXRlcikpOwotCi0gICAgICAgIH0gY2F0Y2ggKFhNTFN0cmVhbUV4Y2VwdGlvbiBlKSB7Ci0KLSAgICAgICAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oZSk7Ci0KLSAgICAgICAgfQotCi0gICAgfQotCi0gICAgcHVibGljIHZvaWQgY29tbWVudChjaGFyW10gY2gsIGludCBzdGFydCwgaW50IGxlbmd0aCkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChuZWVkVG9DYWxsU3RhcnREb2N1bWVudCkgewotICAgICAgICAgICAgLy8gRHJhdC4gV2Ugd2VyZSB0cnlpbmcgdG8gcG9zdHBvbmUgdGhpcyB1bnRpbCB0aGUgZmlyc3QgZWxlbWVudCBzbyB0aGF0IHdlIGNvdWxkIGdldAotICAgICAgICAgICAgLy8gdGhlIGxvY2F0b3IsIGJ1dCB3ZSBjYW4ndCBvdXRwdXQgYSBjb21tZW50IGJlZm9yZSB0aGUgc3RhcnQgZG9jdW1lbnQsIHNvIHdlJ3JlIGp1c3QKLSAgICAgICAgICAgIC8vIGdvaW5nIHRvIGhhdmUgdG8gZG8gd2l0aG91dCB0aGUgbG9jYXRvciBpZiBpdCBoYXNuJ3QgYmVlbiBzZXQgeWV0LgotICAgICAgICAgICAgd3JpdGVTdGFydERvY3VtZW50KCk7Ci0gICAgICAgIH0KLQotICAgICAgICBzdXBlci5jb21tZW50KGNoLCBzdGFydCwgbGVuZ3RoKTsKLQotICAgICAgICBldmVudEZhY3Rvcnkuc2V0TG9jYXRpb24oZ2V0Q3VycmVudExvY2F0aW9uKCkpOwotICAgICAgICB0cnkgewotCi0gICAgICAgICAgICB3cml0ZXIuYWRkKGV2ZW50RmFjdG9yeS5jcmVhdGVDb21tZW50KG5ldyBTdHJpbmcoY2gsIHN0YXJ0LAotICAgICAgICAgICAgICAgICAgICBsZW5ndGgpKSk7Ci0KLSAgICAgICAgfSBjYXRjaCAoWE1MU3RyZWFtRXhjZXB0aW9uIGUpIHsKLQotICAgICAgICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbihlKTsKLQotICAgICAgICB9Ci0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBjaGFyYWN0ZXJzKGNoYXJbXSBjaCwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKQotICAgICAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgc3VwZXIuY2hhcmFjdGVycyhjaCwgc3RhcnQsIGxlbmd0aCk7Ci0KLSAgICAgICAgdHJ5IHsKLQotICAgICAgICAgICAgaWYgKCFpc0NEQVRBKSB7Ci0KLSAgICAgICAgICAgICAgICBldmVudEZhY3Rvcnkuc2V0TG9jYXRpb24oZ2V0Q3VycmVudExvY2F0aW9uKCkpOwotICAgICAgICAgICAgICAgIHdyaXRlci5hZGQoZXZlbnRGYWN0b3J5LmNyZWF0ZUNoYXJhY3RlcnMobmV3IFN0cmluZyhjaCwKLSAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0LCBsZW5ndGgpKSk7Ci0KLSAgICAgICAgICAgIH0KLQotICAgICAgICB9IGNhdGNoIChYTUxTdHJlYW1FeGNlcHRpb24gZSkgewotCi0gICAgICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKGUpOwotCi0gICAgICAgIH0KLQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGlnbm9yYWJsZVdoaXRlc3BhY2UoY2hhcltdIGNoLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpCi0gICAgICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLQotICAgICAgICBzdXBlci5pZ25vcmFibGVXaGl0ZXNwYWNlKGNoLCBzdGFydCwgbGVuZ3RoKTsKLSAgICAgICAgY2hhcmFjdGVycyhjaCwgc3RhcnQsIGxlbmd0aCk7Ci0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oU3RyaW5nIHRhcmdldCwgU3RyaW5nIGRhdGEpCi0gICAgICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLQotICAgICAgICBpZiAobmVlZFRvQ2FsbFN0YXJ0RG9jdW1lbnQpIHsKLSAgICAgICAgICAgIC8vIERyYXQuIFdlIHdlcmUgdHJ5aW5nIHRvIHBvc3Rwb25lIHRoaXMgdW50aWwgdGhlIGZpcnN0IGVsZW1lbnQgc28gdGhhdCB3ZSBjb3VsZCBnZXQKLSAgICAgICAgICAgIC8vIHRoZSBsb2NhdG9yLCBidXQgd2UgY2FuJ3Qgb3V0cHV0IGEgUEkgYmVmb3JlIHRoZSBzdGFydCBkb2N1bWVudCwgc28gd2UncmUganVzdAotICAgICAgICAgICAgLy8gZ29pbmcgdG8gaGF2ZSB0byBkbyB3aXRob3V0IHRoZSBsb2NhdG9yIGlmIGl0IGhhc24ndCBiZWVuIHNldCB5ZXQuCi0gICAgICAgICAgICB3cml0ZVN0YXJ0RG9jdW1lbnQoKTsKLSAgICAgICAgfQotCi0gICAgICAgIHN1cGVyLnByb2Nlc3NpbmdJbnN0cnVjdGlvbih0YXJnZXQsIGRhdGEpOwotICAgICAgICB0cnkgewotCi0gICAgICAgICAgICB3cml0ZXIuYWRkKGV2ZW50RmFjdG9yeS5jcmVhdGVQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24odGFyZ2V0LCBkYXRhKSk7Ci0KLSAgICAgICAgfSBjYXRjaCAoWE1MU3RyZWFtRXhjZXB0aW9uIGUpIHsKLQotICAgICAgICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbihlKTsKLQotICAgICAgICB9Ci0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBlbmRDREFUQSgpIHRocm93cyBTQVhFeGNlcHRpb24gewotCi0gICAgICAgIGV2ZW50RmFjdG9yeS5zZXRMb2NhdGlvbihnZXRDdXJyZW50TG9jYXRpb24oKSk7Ci0gICAgICAgIHRyeSB7Ci0KLSAgICAgICAgICAgIHdyaXRlci5hZGQoZXZlbnRGYWN0b3J5LmNyZWF0ZUNEYXRhKENEQVRBQnVmZmVyLnRvU3RyaW5nKCkpKTsKLQotICAgICAgICB9IGNhdGNoIChYTUxTdHJlYW1FeGNlcHRpb24gZSkgewotCi0gICAgICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKGUpOwotCi0gICAgICAgIH0KLQotICAgICAgICBzdXBlci5lbmRDREFUQSgpOwotCi0gICAgfQotCi0KLSAgICBwcm90ZWN0ZWQgdm9pZCBjcmVhdGVTdGFydEV2ZW50cyhBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMsIENvbGxlY3Rpb25bXSBldmVudHMpIHsKLQotICAgICAgICBNYXAgbnNNYXAgPSBudWxsOwotICAgICAgICBMaXN0IGF0dHJzID0gbnVsbDsKLQotICAgICAgICAvLyBjcmVhdGUgbmFtZXNwYWNlcwotICAgICAgICBpZiAobmFtZXNwYWNlcyAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmaW5hbCBpbnQgbkRlY2xzID0gbmFtZXNwYWNlcy5zaXplKCk7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG5EZWNsczsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIHByZWZpeCA9IChTdHJpbmcpIG5hbWVzcGFjZXMuZWxlbWVudEF0KGkrKyk7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIHVyaSA9IChTdHJpbmcpIG5hbWVzcGFjZXMuZWxlbWVudEF0KGkpOwotICAgICAgICAgICAgICAgIE5hbWVzcGFjZSBucyA9IGNyZWF0ZU5hbWVzcGFjZShwcmVmaXgsIHVyaSk7Ci0gICAgICAgICAgICAgICAgaWYgKG5zTWFwID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgbnNNYXAgPSBuZXcgSGFzaE1hcCgpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBuc01hcC5wdXQocHJlZml4LCBucyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBjcmVhdGUgYXR0cmlidXRlcwotICAgICAgICBTdHJpbmdbXSBxbmFtZSA9IHtudWxsLCBudWxsfTsKLSAgICAgICAgZm9yIChpbnQgaSA9IDAsIHMgPSBhdHRyaWJ1dGVzLmdldExlbmd0aCgpOyBpIDwgczsgaSsrKSB7Ci0KLSAgICAgICAgICAgIHBhcnNlUU5hbWUoYXR0cmlidXRlcy5nZXRRTmFtZShpKSwgcW5hbWUpOwotCi0gICAgICAgICAgICBTdHJpbmcgYXR0clByZWZpeCA9IHFuYW1lWzBdOwotICAgICAgICAgICAgU3RyaW5nIGF0dHJMb2NhbCA9IHFuYW1lWzFdOwotCi0gICAgICAgICAgICBTdHJpbmcgYXR0clFOYW1lID0gYXR0cmlidXRlcy5nZXRRTmFtZShpKTsKLSAgICAgICAgICAgIFN0cmluZyBhdHRyVmFsdWUgPSBhdHRyaWJ1dGVzLmdldFZhbHVlKGkpOwotICAgICAgICAgICAgU3RyaW5nIGF0dHJVUkkgPSBhdHRyaWJ1dGVzLmdldFVSSShpKTsKLQotICAgICAgICAgICAgaWYgKCJ4bWxucyIuZXF1YWxzKGF0dHJRTmFtZSkgfHwgInhtbG5zIi5lcXVhbHMoYXR0clByZWZpeCkpIHsKLSAgICAgICAgICAgICAgICAvLyBuYW1lc3BhY2UgZGVjbGFyYXRpb24gZGlzZ3Vpc2VkIGFzIGFuIGF0dHJpYnV0ZS4gSWYgdGhlCi0gICAgICAgICAgICAgICAgLy8gbmFtZXNwYWNlIGhhcyBhbHJlYWR5IGJlZW4gZGVjbGFyZWQsIHNraXAgaXQsIG90aGVyd2lzZQotICAgICAgICAgICAgICAgIC8vIHdyaXRlIGl0IGFzIGFuIG5hbWVzcGFjZQotICAgICAgICAgICAgICAgIGlmIChuc01hcCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIG5zTWFwID0gbmV3IEhhc2hNYXAoKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBpZiAoIW5zTWFwLmNvbnRhaW5zS2V5KGF0dHJMb2NhbCkpIHsKLSAgICAgICAgICAgICAgICAgICAgTmFtZXNwYWNlIG5zID0gY3JlYXRlTmFtZXNwYWNlKGF0dHJMb2NhbCwgYXR0clZhbHVlKTsKLSAgICAgICAgICAgICAgICAgICAgbnNNYXAucHV0KGF0dHJMb2NhbCwgbnMpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgfSBlbHNlIHsKLQotICAgICAgICAgICAgICAgIEF0dHJpYnV0ZSBhdHRyaWJ1dGU7Ci0gICAgICAgICAgICAgICAgaWYgKGF0dHJQcmVmaXgubGVuZ3RoKCkgPiAwKSB7Ci0KLSAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlID0gZXZlbnRGYWN0b3J5LmNyZWF0ZUF0dHJpYnV0ZShhdHRyUHJlZml4LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJVUkksIGF0dHJMb2NhbCwgYXR0clZhbHVlKTsKLQotICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0KLSAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlID0gZXZlbnRGYWN0b3J5LmNyZWF0ZUF0dHJpYnV0ZShhdHRyTG9jYWwsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0clZhbHVlKTsKLQotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIGlmIChhdHRycyA9PSBudWxsKSB7Ci0KLSAgICAgICAgICAgICAgICAgICAgYXR0cnMgPSBuZXcgQXJyYXlMaXN0KCk7Ci0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgYXR0cnMuYWRkKGF0dHJpYnV0ZSk7Ci0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGV2ZW50c1swXSA9IChuc01hcCA9PSBudWxsID8gQ29sbGVjdGlvbnMuRU1QVFlfTElTVCA6IG5zTWFwLnZhbHVlcygpKTsKLSAgICAgICAgZXZlbnRzWzFdID0gKGF0dHJzID09IG51bGwgPyBDb2xsZWN0aW9ucy5FTVBUWV9MSVNUIDogYXR0cnMpOwotCi0gICAgfQotCi0gICAgcHJvdGVjdGVkIE5hbWVzcGFjZSBjcmVhdGVOYW1lc3BhY2UoU3RyaW5nIHByZWZpeCwgU3RyaW5nIHVyaSkgewotCi0gICAgICAgIGlmIChwcmVmaXggPT0gbnVsbCB8fCBwcmVmaXgubGVuZ3RoKCkgPT0gMCkgewotCi0gICAgICAgICAgICByZXR1cm4gZXZlbnRGYWN0b3J5LmNyZWF0ZU5hbWVzcGFjZSh1cmkpOwotCi0gICAgICAgIH0gZWxzZSB7Ci0KLSAgICAgICAgICAgIHJldHVybiBldmVudEZhY3RvcnkuY3JlYXRlTmFtZXNwYWNlKHByZWZpeCwgdXJpKTsKLQotICAgICAgICB9Ci0KLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvdHJheC9TQVgyU3RBWFN0cmVhbVdyaXRlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy90cmF4L1NBWDJTdEFYU3RyZWFtV3JpdGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGQwNGQzNTcuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy90cmF4L1NBWDJTdEFYU3RyZWFtV3JpdGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzMDIgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAwNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMudHJheDsKLQotaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKLQotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uWE1MU3RyZWFtRXhjZXB0aW9uOwotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uWE1MU3RyZWFtV3JpdGVyOwotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uWE1MRXZlbnRXcml0ZXI7Ci0KLWltcG9ydCBvcmcueG1sLnNheC5BdHRyaWJ1dGVzOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5leHQuTG9jYXRvcjI7Ci0KLS8qKgotICogQGF1dGhvciBTdW5pdGhhIFJlZGR5Ci0gKi8KLQotcHVibGljIGNsYXNzIFNBWDJTdEFYU3RyZWFtV3JpdGVyIGV4dGVuZHMgU0FYMlN0QVhCYXNlV3JpdGVyIHsKLQotCi0gICAgICAgIHByaXZhdGUgWE1MU3RyZWFtV3JpdGVyIHdyaXRlcjsKLQotICAgICAgICBwcml2YXRlIGJvb2xlYW4gbmVlZFRvQ2FsbFN0YXJ0RG9jdW1lbnQgPSBmYWxzZTsKLQotICAgICAgICBwdWJsaWMgU0FYMlN0QVhTdHJlYW1Xcml0ZXIoKSB7Ci0KLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyBTQVgyU3RBWFN0cmVhbVdyaXRlcihYTUxTdHJlYW1Xcml0ZXIgd3JpdGVyKSB7Ci0KLSAgICAgICAgICAgICAgICB0aGlzLndyaXRlciA9IHdyaXRlcjsKLQotICAgICAgICB9Ci0KLQotICAgICAgICBwdWJsaWMgWE1MU3RyZWFtV3JpdGVyIGdldFN0cmVhbVdyaXRlcigpIHsKLQotICAgICAgICAgICAgICAgIHJldHVybiB3cml0ZXI7Ci0KLSAgICAgICAgfQotCi0KLSAgICAgICAgcHVibGljIHZvaWQgc2V0U3RyZWFtV3JpdGVyKFhNTFN0cmVhbVdyaXRlciB3cml0ZXIpIHsKLQotICAgICAgICAgICAgICAgIHRoaXMud3JpdGVyID0gd3JpdGVyOwotCi0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCBzdGFydERvY3VtZW50KCkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgICAgICAgICBzdXBlci5zdGFydERvY3VtZW50KCk7Ci0gICAgICAgICAgICAgICAgLy8gRW5jb2RpbmcgYW5kIHZlcnNpb24gaW5mbyB3aWxsIGJlIGF2YWlsYWJsZSBvbmx5IGFmdGVyIHN0YXJ0RWxlbWVudAotICAgICAgICAgICAgICAgIC8vIGlzIGNhbGxlZCBmb3IgZmlyc3QgdGltZS4gU28sIGRlZmVyIFNUQVJUX0RPQ1VNRU5UIGV2ZW50IG9mIFN0QVggdGlsbAotICAgICAgICAgICAgICAgIC8vIHRoYXQgcG9pbnQgb2YgdGltZS4KLSAgICAgICAgICAgICAgICBuZWVkVG9DYWxsU3RhcnREb2N1bWVudCA9IHRydWU7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCBlbmREb2N1bWVudCgpIHRocm93cyBTQVhFeGNlcHRpb24gewotCi0gICAgICAgICAgICAgICAgdHJ5IHsKLQotICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlRW5kRG9jdW1lbnQoKTsKLQotICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFhNTFN0cmVhbUV4Y2VwdGlvbiBlKSB7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oZSk7Ci0KLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBzdXBlci5lbmREb2N1bWVudCgpOwotCi0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSwgU3RyaW5nIHFOYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgQXR0cmlidXRlcyBhdHRyaWJ1dGVzKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLQotICAgICAgICAgICAgICAgIGlmIChuZWVkVG9DYWxsU3RhcnREb2N1bWVudCkgewotICAgICAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRvY0xvY2F0b3IgPT0gbnVsbCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGVTdGFydERvY3VtZW50KCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnl7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZVN0YXJ0RG9jdW1lbnQoKChMb2NhdG9yMilkb2NMb2NhdG9yKS5nZXRYTUxWZXJzaW9uKCkpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1jYXRjaChDbGFzc0Nhc3RFeGNlcHRpb24gZSl7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZVN0YXJ0RG9jdW1lbnQoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoWE1MU3RyZWFtRXhjZXB0aW9uIGUpIHsKLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oZSk7Ci0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBuZWVkVG9DYWxsU3RhcnREb2N1bWVudCA9IGZhbHNlOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIHRyeSB7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1tdIHFuYW1lID0ge251bGwsIG51bGx9OwotICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2VRTmFtZShxTmFtZSwgcW5hbWUpOwotICAgICAgICAgICAgICAgICAgICAgICAgLy9EbyBub3QgY2FsbCB3cml0ZVN0YXJ0RWxlbWVudCB3aXRoIHByZWZpeCBhbmQgbmFtZXNwYWNlVVJJLCBhcyBpdCB3cml0ZXMgb3V0Ci0gICAgICAgICAgICAgICAgICAgICAgICAvL25hbWVzcGFjZSBkZWNsYXJhdGlvbi4KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vd3JpdGVyLndyaXRlU3RhcnRFbGVtZW50KHFuYW1lWzBdLCBxbmFtZVsxXSwgdXJpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZVN0YXJ0RWxlbWVudChxTmFtZSk7Ci0KLQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gTm8gbmVlZCB0byB3cml0ZSBuYW1lc3BhY2VzLCBhcyB0aGV5IGFyZSB3cml0dGVuIGFzIHBhcnQgb2YgYXR0cmlidXRlcy4KLSAgICAgICAgICAgICAgICAgICAgICAgIC8qaWYgKG5hbWVzcGFjZXMgIT0gbnVsbCkgewotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IG5EZWNscyA9IG5hbWVzcGFjZXMuc2l6ZSgpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbkRlY2xzOyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIHByZWZpeCA9IChTdHJpbmcpIG5hbWVzcGFjZXMuZWxlbWVudEF0KGkpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocHJlZml4Lmxlbmd0aCgpID09IDApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlci5zZXREZWZhdWx0TmFtZXNwYWNlKChTdHJpbmcpbmFtZXNwYWNlcy5lbGVtZW50QXQoKytpKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cml0ZXIuc2V0UHJlZml4KHByZWZpeCwgKFN0cmluZykgbmFtZXNwYWNlcy5lbGVtZW50QXQoKytpKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGVOYW1lc3BhY2UocHJlZml4LCAoU3RyaW5nKW5hbWVzcGFjZXMuZWxlbWVudEF0KGkpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0KLQotICAgICAgICAgICAgICAgICAgICAgICAgfSovCi0KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIHdyaXRlIGF0dHJpYnV0ZXMKLSAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwLCBzID0gYXR0cmlidXRlcy5nZXRMZW5ndGgoKTsgaSA8IHM7IGkrKykgewotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcnNlUU5hbWUoYXR0cmlidXRlcy5nZXRRTmFtZShpKSwgcW5hbWUpOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBhdHRyUHJlZml4ID0gcW5hbWVbMF07Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBhdHRyTG9jYWwgPSBxbmFtZVsxXTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgYXR0clFOYW1lID0gYXR0cmlidXRlcy5nZXRRTmFtZShpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGF0dHJWYWx1ZSA9IGF0dHJpYnV0ZXMuZ2V0VmFsdWUoaSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBhdHRyVVJJID0gYXR0cmlidXRlcy5nZXRVUkkoaSk7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCJ4bWxucyIuZXF1YWxzKGF0dHJQcmVmaXgpIHx8ICJ4bWxucyIuZXF1YWxzKGF0dHJRTmFtZSkpIHsKLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG5hbWVzcGFjZSBkZWNsYXJhdGlvbiBkaXNndWlzZWQgYXMgYW4gYXR0cmlidXRlLgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHdyaXRlIGl0IGFzIGFuIG5hbWVzcGFjZQotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGF0dHJMb2NhbC5sZW5ndGgoKSA9PSAwKSB7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVyLnNldERlZmF1bHROYW1lc3BhY2UoYXR0clZhbHVlKTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVyLnNldFByZWZpeChhdHRyTG9jYWwsIGF0dHJWYWx1ZSk7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGVOYW1lc3BhY2UoYXR0ckxvY2FsLCBhdHRyVmFsdWUpOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYXR0clByZWZpeC5sZW5ndGgoKSA+IDApIHsKLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZUF0dHJpYnV0ZShhdHRyUHJlZml4LCBhdHRyVVJJLCBhdHRyTG9jYWwsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJWYWx1ZSk7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGVBdHRyaWJ1dGUoYXR0clFOYW1lLCBhdHRyVmFsdWUpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFhNTFN0cmVhbUV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKGUpOwotCi0gICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKLQotICAgICAgICAgICAgICAgICAgICAgICAgc3VwZXIuc3RhcnRFbGVtZW50KHVyaSwgbG9jYWxOYW1lLCBxTmFtZSwgYXR0cmlidXRlcyk7Ci0KLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyB2b2lkIGVuZEVsZW1lbnQoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSwgU3RyaW5nIHFOYW1lKQotICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgICAgICAgICB0cnkgewotCi0gICAgICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGVFbmRFbGVtZW50KCk7Ci0KLSAgICAgICAgICAgICAgICB9IGNhdGNoIChYTUxTdHJlYW1FeGNlcHRpb24gZSkgewotCi0gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKGUpOwotCi0gICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKLQotICAgICAgICAgICAgICAgICAgICAgICAgc3VwZXIuZW5kRWxlbWVudCh1cmksIGxvY2FsTmFtZSwgcU5hbWUpOwotCi0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCBjb21tZW50KGNoYXJbXSBjaCwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLQotICAgICAgICAgICAgICAgIHN1cGVyLmNvbW1lbnQoY2gsIHN0YXJ0LCBsZW5ndGgpOwotICAgICAgICAgICAgICAgIHRyeSB7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZUNvbW1lbnQobmV3IFN0cmluZyhjaCwgc3RhcnQsIGxlbmd0aCkpOwotCi0gICAgICAgICAgICAgICAgfSBjYXRjaCAoWE1MU3RyZWFtRXhjZXB0aW9uIGUpIHsKLQotICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbihlKTsKLQotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIHZvaWQgY2hhcmFjdGVycyhjaGFyW10gY2gsIGludCBzdGFydCwgaW50IGxlbmd0aCkKLSAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24gewotCi0gICAgICAgICAgICAgICAgc3VwZXIuY2hhcmFjdGVycyhjaCwgc3RhcnQsIGxlbmd0aCk7Ci0gICAgICAgICAgICAgICAgdHJ5IHsKLQotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFpc0NEQVRBKSB7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlQ2hhcmFjdGVycyhjaCwgc3RhcnQsIGxlbmd0aCk7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFhNTFN0cmVhbUV4Y2VwdGlvbiBlKSB7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oZSk7Ci0KLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyB2b2lkIGVuZENEQVRBKCkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgICAgICAgICB0cnkgewotCi0gICAgICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGVDRGF0YShDREFUQUJ1ZmZlci50b1N0cmluZygpKTsKLQotICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFhNTFN0cmVhbUV4Y2VwdGlvbiBlKSB7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oZSk7Ci0KLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBzdXBlci5lbmRDREFUQSgpOwotCi0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCBpZ25vcmFibGVXaGl0ZXNwYWNlKGNoYXJbXSBjaCwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKQotICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgICAgICAgICBzdXBlci5pZ25vcmFibGVXaGl0ZXNwYWNlKGNoLCBzdGFydCwgbGVuZ3RoKTsKLSAgICAgICAgICAgICAgICB0cnkgewotCi0gICAgICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGVDaGFyYWN0ZXJzKGNoLCBzdGFydCwgbGVuZ3RoKTsKLQotICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFhNTFN0cmVhbUV4Y2VwdGlvbiBlKSB7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oZSk7Ci0KLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyB2b2lkIHByb2Nlc3NpbmdJbnN0cnVjdGlvbihTdHJpbmcgdGFyZ2V0LCBTdHJpbmcgZGF0YSkKLSAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24gewotCi0gICAgICAgICAgICAgICAgc3VwZXIucHJvY2Vzc2luZ0luc3RydWN0aW9uKHRhcmdldCwgZGF0YSk7Ci0gICAgICAgICAgICAgICAgdHJ5IHsKLQotICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlUHJvY2Vzc2luZ0luc3RydWN0aW9uKHRhcmdldCwgZGF0YSk7Ci0KLSAgICAgICAgICAgICAgICB9IGNhdGNoIChYTUxTdHJlYW1FeGNlcHRpb24gZSkgewotCi0gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKGUpOwotCi0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy90cmF4L1NtYXJ0VHJhbnNmb3JtZXJGYWN0b3J5SW1wbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy90cmF4L1NtYXJ0VHJhbnNmb3JtZXJGYWN0b3J5SW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0NjM3ZGNlLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvdHJheC9TbWFydFRyYW5zZm9ybWVyRmFjdG9yeUltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQ1NSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBTbWFydFRyYW5zZm9ybWVyRmFjdG9yeUltcGwuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNCAwOTo1NzoxMyBwdmVkdWxhIEV4cCAkCi0gKi8KLQotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy50cmF4OwotCi1pbXBvcnQgamF2YXgueG1sLlhNTENvbnN0YW50czsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLkVycm9yTGlzdGVuZXI7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2U7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UZW1wbGF0ZXM7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lcjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVVJJUmVzb2x2ZXI7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5kb20uRE9NUmVzdWx0OwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uZG9tLkRPTVNvdXJjZTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnNheC5TQVhSZXN1bHQ7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zYXguU0FYU291cmNlOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlNBWFRyYW5zZm9ybWVyRmFjdG9yeTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnNheC5UZW1wbGF0ZXNIYW5kbGVyOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlRyYW5zZm9ybWVySGFuZGxlcjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbS5TdHJlYW1SZXN1bHQ7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zdHJlYW0uU3RyZWFtU291cmNlOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuRXJyb3JNc2c7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnV0aWxzLk9iamVjdEZhY3Rvcnk7Ci1pbXBvcnQgb3JnLnhtbC5zYXguWE1MRmlsdGVyOwotCi0vKioKLSAqIEltcGxlbWVudGF0aW9uIG9mIGEgdHJhbnNmb3JtZXIgZmFjdG9yeSB0aGF0IHVzZXMgYW4gWFNMVEMKLSAqIHRyYW5zZm9ybWVyIGZhY3RvcnkgZm9yIHRoZSBjcmVhdGlvbiBvZiBUZW1wbGF0ZXMgb2JqZWN0cwotICogYW5kIHVzZXMgdGhlIFhhbGFuIHByb2Nlc3NvciB0cmFuc2Zvcm1lciBmYWN0b3J5IGZvciB0aGUKLSAqIGNyZWF0aW9uIG9mIFRyYW5zZm9ybWVyIG9iamVjdHMuCi0gKiBAYXV0aG9yIEcuIFRvZGQgTWlsbGVyCi0gKi8KLXB1YmxpYyBjbGFzcyBTbWFydFRyYW5zZm9ybWVyRmFjdG9yeUltcGwgZXh0ZW5kcyBTQVhUcmFuc2Zvcm1lckZhY3RvcnkKLXsKLSAgICAvKioKLSAgICAgKiA8cD5OYW1lIG9mIGNsYXNzIGFzIGEgY29uc3RhbnQgdG8gdXNlIGZvciBkZWJ1Z2dpbmcuPC9wPgotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBDTEFTU19OQU1FID0gIlNtYXJ0VHJhbnNmb3JtZXJGYWN0b3J5SW1wbCI7Ci0KLSAgICBwcml2YXRlIFNBWFRyYW5zZm9ybWVyRmFjdG9yeSBfeHNsdGNGYWN0b3J5ID0gbnVsbDsKLSAgICBwcml2YXRlIFNBWFRyYW5zZm9ybWVyRmFjdG9yeSBfeGFsYW5GYWN0b3J5ID0gbnVsbDsKLSAgICBwcml2YXRlIFNBWFRyYW5zZm9ybWVyRmFjdG9yeSBfY3VyckZhY3RvcnkgPSBudWxsOwotICAgIHByaXZhdGUgRXJyb3JMaXN0ZW5lciAgICAgIF9lcnJvcmxpc3RlbmVyID0gbnVsbDsKLSAgICBwcml2YXRlIFVSSVJlc29sdmVyICAgICAgICBfdXJpcmVzb2x2ZXIgPSBudWxsOwotCi0gICAgLyoqCi0gICAgICogPHA+U3RhdGUgb2Ygc2VjdXJlIHByb2Nlc3NpbmcgZmVhdHVyZS48L3A+Ci0gICAgICovCi0gICAgcHJpdmF0ZSBib29sZWFuIGZlYXR1cmVTZWN1cmVQcm9jZXNzaW5nID0gZmFsc2U7Ci0KLSAgICAvKioKLSAgICAgKiBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgU21hcnRUcmFuc2Zvcm1lckZhY3RvcnkuIFRoaXMgZmFjdG9yeQotICAgICAqIHVzZXMgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnRyYXguVHJhbnNmb3JtZXJGYWN0b3J5Ci0gICAgICogdG8gcmV0dXJuIFRlbXBsYXRlcyBvYmplY3RzOyBhbmQgdXNlcwotICAgICAqIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC5wcm9jZXNzb3IuVHJhbnNmb3JtZXJGYWN0b3J5Ci0gICAgICogdG8gcmV0dXJuIFRyYW5zZm9ybWVyIG9iamVjdHMuCi0gICAgICovCi0gICAgcHVibGljIFNtYXJ0VHJhbnNmb3JtZXJGYWN0b3J5SW1wbCgpIHsgfQotCi0gICAgcHJpdmF0ZSB2b2lkIGNyZWF0ZVhTTFRDVHJhbnNmb3JtZXJGYWN0b3J5KCkgewotICAgICAgICBfeHNsdGNGYWN0b3J5ID0gbmV3IFRyYW5zZm9ybWVyRmFjdG9yeUltcGwoKTsKLSAgICAgICAgX2N1cnJGYWN0b3J5ID0gX3hzbHRjRmFjdG9yeTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgY3JlYXRlWGFsYW5UcmFuc2Zvcm1lckZhY3RvcnkoKSB7Ci0gICAgICAgIGZpbmFsIFN0cmluZyB4YWxhbk1lc3NhZ2UgPQotICAgICAgICAgICAgImNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy50cmF4LlNtYXJ0VHJhbnNmb3JtZXJGYWN0b3J5SW1wbCAiKwotICAgICAgICAgICAgImNvdWxkIG5vdCBjcmVhdGUgYW4gIisKLSAgICAgICAgICAgICJjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwucHJvY2Vzc29yLlRyYW5zZm9ybWVyRmFjdG9yeUltcGwuIjsKLSAgICAgICAgLy8gdHJ5IHRvIGNyZWF0ZSBpbnN0YW5jZSBvZiBYYWxhbiBmYWN0b3J5Li4uCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBDbGFzcyB4YWxhbkZhY3RDbGFzcyA9IE9iamVjdEZhY3RvcnkuZmluZFByb3ZpZGVyQ2xhc3MoCi0gICAgICAgICAgICAgICAgImNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC5wcm9jZXNzb3IuVHJhbnNmb3JtZXJGYWN0b3J5SW1wbCIsCi0gICAgICAgICAgICAgICAgdHJ1ZSk7Ci0gICAgICAgICAgICBfeGFsYW5GYWN0b3J5ID0gKFNBWFRyYW5zZm9ybWVyRmFjdG9yeSkKLSAgICAgICAgICAgICAgICB4YWxhbkZhY3RDbGFzcy5uZXdJbnN0YW5jZSgpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbih4YWxhbk1lc3NhZ2UpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChJbnN0YW50aWF0aW9uRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbih4YWxhbk1lc3NhZ2UpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbih4YWxhbk1lc3NhZ2UpOwotICAgICAgICB9Ci0gICAgICAgIF9jdXJyRmFjdG9yeSA9IF94YWxhbkZhY3Rvcnk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0RXJyb3JMaXN0ZW5lcihFcnJvckxpc3RlbmVyIGxpc3RlbmVyKQotICAgICAgICB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCi0gICAgewotICAgICAgICBfZXJyb3JsaXN0ZW5lciA9IGxpc3RlbmVyOwotICAgIH0KLQotICAgIHB1YmxpYyBFcnJvckxpc3RlbmVyIGdldEVycm9yTGlzdGVuZXIoKSB7Ci0gICAgICAgIHJldHVybiBfZXJyb3JsaXN0ZW5lcjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgT2JqZWN0IGdldEF0dHJpYnV0ZShTdHJpbmcgbmFtZSkKLSAgICAgICAgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgLy8gR1RNOiBOQjogJ2RlYnVnJyBzaG91bGQgY2hhbmdlIHRvIHNvbWV0aGluZyBtb3JlIHVuaXF1ZS4uLgotICAgICAgICBpZiAoKG5hbWUuZXF1YWxzKCJ0cmFuc2xldC1uYW1lIikpIHx8IChuYW1lLmVxdWFscygiZGVidWciKSkpIHsKLSAgICAgICAgICAgIGlmIChfeHNsdGNGYWN0b3J5ID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBjcmVhdGVYU0xUQ1RyYW5zZm9ybWVyRmFjdG9yeSgpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIF94c2x0Y0ZhY3RvcnkuZ2V0QXR0cmlidXRlKG5hbWUpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgaWYgKF94YWxhbkZhY3RvcnkgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGNyZWF0ZVhhbGFuVHJhbnNmb3JtZXJGYWN0b3J5KCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gX3hhbGFuRmFjdG9yeS5nZXRBdHRyaWJ1dGUobmFtZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRBdHRyaWJ1dGUoU3RyaW5nIG5hbWUsIE9iamVjdCB2YWx1ZSkKLSAgICAgICAgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7Ci0gICAgICAgIC8vIEdUTTogTkI6ICdkZWJ1Zycgc2hvdWxkIGNoYW5nZSB0byBzb21ldGhpbmcgbW9yZSB1bmlxdWUuLi4KLSAgICAgICAgaWYgKChuYW1lLmVxdWFscygidHJhbnNsZXQtbmFtZSIpKSB8fCAobmFtZS5lcXVhbHMoImRlYnVnIikpKSB7Ci0gICAgICAgICAgICBpZiAoX3hzbHRjRmFjdG9yeSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgY3JlYXRlWFNMVENUcmFuc2Zvcm1lckZhY3RvcnkoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIF94c2x0Y0ZhY3Rvcnkuc2V0QXR0cmlidXRlKG5hbWUsIHZhbHVlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIGlmIChfeGFsYW5GYWN0b3J5ID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBjcmVhdGVYYWxhblRyYW5zZm9ybWVyRmFjdG9yeSgpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgX3hhbGFuRmFjdG9yeS5zZXRBdHRyaWJ1dGUobmFtZSwgdmFsdWUpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+U2V0IGEgZmVhdHVyZSBmb3IgdGhpcyA8Y29kZT5TbWFydFRyYW5zZm9ybWVyRmFjdG9yeTwvY29kZT4gYW5kIDxjb2RlPlRyYW5zZm9ybWVyPC9jb2RlPnMKLSAgICAgKiBvciA8Y29kZT5UZW1wbGF0ZTwvY29kZT5zIGNyZWF0ZWQgYnkgdGhpcyBmYWN0b3J5LjwvcD4KLSAgICAgKgotICAgICAqIDxwPgotICAgICAqIEZlYXR1cmUgbmFtZXMgYXJlIGZ1bGx5IHF1YWxpZmllZCB7QGxpbmsgamF2YS5uZXQuVVJJfXMuCi0gICAgICogSW1wbGVtZW50YXRpb25zIG1heSBkZWZpbmUgdGhlaXIgb3duIGZlYXR1cmVzLgotICAgICAqIEFuIHtAbGluayBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb259IGlzIHRocm93biBpZiB0aGlzIDxjb2RlPlRyYW5zZm9ybWVyRmFjdG9yeTwvY29kZT4gb3IgdGhlCi0gICAgICogPGNvZGU+VHJhbnNmb3JtZXI8L2NvZGU+cyBvciA8Y29kZT5UZW1wbGF0ZTwvY29kZT5zIGl0IGNyZWF0ZXMgY2Fubm90IHN1cHBvcnQgdGhlIGZlYXR1cmUuCi0gICAgICogSXQgaXMgcG9zc2libGUgZm9yIGFuIDxjb2RlPlRyYW5zZm9ybWVyRmFjdG9yeTwvY29kZT4gdG8gZXhwb3NlIGEgZmVhdHVyZSB2YWx1ZSBidXQgYmUgdW5hYmxlIHRvIGNoYW5nZSBpdHMgc3RhdGUuCi0gICAgICogPC9wPgotICAgICAqCi0gICAgICogPHA+U2VlIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRmFjdG9yeX0gZm9yIGZ1bGwgZG9jdW1lbnRhdGlvbiBvZiBzcGVjaWZpYyBmZWF0dXJlcy48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSBGZWF0dXJlIG5hbWUuCi0gICAgICogQHBhcmFtIHZhbHVlIElzIGZlYXR1cmUgc3RhdGUgPGNvZGU+dHJ1ZTwvY29kZT4gb3IgPGNvZGU+ZmFsc2U8L2NvZGU+LgotICAgICAqCi0gICAgICogQHRocm93cyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gaWYgdGhpcyA8Y29kZT5UcmFuc2Zvcm1lckZhY3Rvcnk8L2NvZGU+Ci0gICAgICogICBvciB0aGUgPGNvZGU+VHJhbnNmb3JtZXI8L2NvZGU+cyBvciA8Y29kZT5UZW1wbGF0ZTwvY29kZT5zIGl0IGNyZWF0ZXMgY2Fubm90IHN1cHBvcnQgdGhpcyBmZWF0dXJlLgotICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gSWYgdGhlIDxjb2RlPm5hbWU8L2NvZGU+IHBhcmFtZXRlciBpcyBudWxsLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEZlYXR1cmUoU3RyaW5nIG5hbWUsIGJvb2xlYW4gdmFsdWUpCi0gICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gewotCi0gICAgICAgIC8vIGZlYXR1cmUgbmFtZSBjYW5ub3QgYmUgbnVsbAotICAgICAgICBpZiAobmFtZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBFcnJvck1zZyBlcnIgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuSkFYUF9TRVRfRkVBVFVSRV9OVUxMX05BTUUpOwotICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKGVyci50b1N0cmluZygpKTsKLSAgICAgICAgfQotICAgICAgICAvLyBzZWN1cmUgcHJvY2Vzc2luZz8KLSAgICAgICAgZWxzZSBpZiAobmFtZS5lcXVhbHMoWE1MQ29uc3RhbnRzLkZFQVRVUkVfU0VDVVJFX1BST0NFU1NJTkcpKSB7Ci0gICAgICAgICAgICBmZWF0dXJlU2VjdXJlUHJvY2Vzc2luZyA9IHZhbHVlOwotICAgICAgICAgICAgLy8gYWxsIGRvbmUgcHJvY2Vzc2luZyBmZWF0dXJlCi0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAvLyB1bmtub3duIGZlYXR1cmUKLSAgICAgICAgICAgIEVycm9yTXNnIGVyciA9IG5ldyBFcnJvck1zZyhFcnJvck1zZy5KQVhQX1VOU1VQUE9SVEVEX0ZFQVRVUkUsIG5hbWUpOwotICAgICAgICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbihlcnIudG9TdHJpbmcoKSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBqYXZheC54bWwudHJhbnNmb3JtLnNheC5UcmFuc2Zvcm1lckZhY3RvcnkgaW1wbGVtZW50YXRpb24uCi0gICAgICogTG9vayB1cCB0aGUgdmFsdWUgb2YgYSBmZWF0dXJlICh0byBzZWUgaWYgaXQgaXMgc3VwcG9ydGVkKS4KLSAgICAgKiBUaGlzIG1ldGhvZCBtdXN0IGJlIHVwZGF0ZWQgYXMgdGhlIHZhcmlvdXMgbWV0aG9kcyBhbmQgZmVhdHVyZXMgb2YgdGhpcwotICAgICAqIGNsYXNzIGFyZSBpbXBsZW1lbnRlZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBmZWF0dXJlIG5hbWUKLSAgICAgKiBAcmV0dXJuICd0cnVlJyBpZiBmZWF0dXJlIGlzIHN1cHBvcnRlZCwgJ2ZhbHNlJyBpZiBub3QKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXRGZWF0dXJlKFN0cmluZyBuYW1lKSB7Ci0gICAgICAgIC8vIEFsbCBzdXBwb3J0ZWQgZmVhdHVyZXMgc2hvdWxkIGJlIGxpc3RlZCBoZXJlCi0gICAgICAgIFN0cmluZ1tdIGZlYXR1cmVzID0gewotICAgICAgICAgICAgRE9NU291cmNlLkZFQVRVUkUsCi0gICAgICAgICAgICBET01SZXN1bHQuRkVBVFVSRSwKLSAgICAgICAgICAgIFNBWFNvdXJjZS5GRUFUVVJFLAotICAgICAgICAgICAgU0FYUmVzdWx0LkZFQVRVUkUsCi0gICAgICAgICAgICBTdHJlYW1Tb3VyY2UuRkVBVFVSRSwKLSAgICAgICAgICAgIFN0cmVhbVJlc3VsdC5GRUFUVVJFCi0gICAgICAgIH07Ci0KLSAgICAgICAgLy8gZmVhdHVyZSBuYW1lIGNhbm5vdCBiZSBudWxsCi0gICAgICAgIGlmIChuYW1lID09IG51bGwpIHsKLSAgICAgICAgICAgIEVycm9yTXNnIGVyciA9IG5ldyBFcnJvck1zZyhFcnJvck1zZy5KQVhQX0dFVF9GRUFUVVJFX05VTExfTkFNRSk7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oZXJyLnRvU3RyaW5nKCkpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gSW5lZmZpY2llbnQsIGJ1dCBpdCByZWFsbHkgZG9lcyBub3QgbWF0dGVyIGluIGEgZnVuY3Rpb24gbGlrZSB0aGlzCi0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmVhdHVyZXMubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgIGlmIChuYW1lLmVxdWFscyhmZWF0dXJlc1tpXSkpCi0gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBzZWN1cmUgcHJvY2Vzc2luZz8KLSAgICAgICAgaWYgKG5hbWUuZXF1YWxzKFhNTENvbnN0YW50cy5GRUFUVVJFX1NFQ1VSRV9QUk9DRVNTSU5HKSkgewotICAgICAgICAgICAgcmV0dXJuIGZlYXR1cmVTZWN1cmVQcm9jZXNzaW5nOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gdW5rbm93biBmZWF0dXJlCi0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgVVJJUmVzb2x2ZXIgZ2V0VVJJUmVzb2x2ZXIoKSB7Ci0gICAgICAgIHJldHVybiBfdXJpcmVzb2x2ZXI7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0VVJJUmVzb2x2ZXIoVVJJUmVzb2x2ZXIgcmVzb2x2ZXIpIHsKLSAgICAgICAgX3VyaXJlc29sdmVyID0gcmVzb2x2ZXI7Ci0gICAgfQotCi0gICAgcHVibGljIFNvdXJjZSBnZXRBc3NvY2lhdGVkU3R5bGVzaGVldChTb3VyY2Ugc291cmNlLCBTdHJpbmcgbWVkaWEsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdGl0bGUsIFN0cmluZyBjaGFyc2V0KQotICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAoX2N1cnJGYWN0b3J5ID09IG51bGwpIHsKLSAgICAgICAgICAgIGNyZWF0ZVhTTFRDVHJhbnNmb3JtZXJGYWN0b3J5KCk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIF9jdXJyRmFjdG9yeS5nZXRBc3NvY2lhdGVkU3R5bGVzaGVldChzb3VyY2UsIG1lZGlhLAotICAgICAgICAgICAgICAgIHRpdGxlLCBjaGFyc2V0KTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGUgYSBUcmFuc2Zvcm1lciBvYmplY3QgdGhhdCBjb3BpZXMgdGhlIGlucHV0IGRvY3VtZW50IHRvIHRoZQotICAgICAqIHJlc3VsdC4gVXNlcyB0aGUgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnByb2Nlc3Nvci5UcmFuc2Zvcm1lckZhY3RvcnkuCi0gICAgICogQHJldHVybiBBIFRyYW5zZm9ybWVyIG9iamVjdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgVHJhbnNmb3JtZXIgbmV3VHJhbnNmb3JtZXIoKQotICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAoX3hhbGFuRmFjdG9yeSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBjcmVhdGVYYWxhblRyYW5zZm9ybWVyRmFjdG9yeSgpOwotICAgICAgICB9Ci0gICAgICAgIGlmIChfZXJyb3JsaXN0ZW5lciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBfeGFsYW5GYWN0b3J5LnNldEVycm9yTGlzdGVuZXIoX2Vycm9ybGlzdGVuZXIpOwotICAgICAgICB9Ci0gICAgICAgIGlmIChfdXJpcmVzb2x2ZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgX3hhbGFuRmFjdG9yeS5zZXRVUklSZXNvbHZlcihfdXJpcmVzb2x2ZXIpOwotICAgICAgICB9Ci0gICAgICAgIF9jdXJyRmFjdG9yeSA9IF94YWxhbkZhY3Rvcnk7Ci0gICAgICAgIHJldHVybiBfY3VyckZhY3RvcnkubmV3VHJhbnNmb3JtZXIoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGUgYSBUcmFuc2Zvcm1lciBvYmplY3QgdGhhdCBmcm9tIHRoZSBpbnB1dCBzdHlsZXNoZWV0Ci0gICAgICogVXNlcyB0aGUgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnByb2Nlc3Nvci5UcmFuc2Zvcm1lckZhY3RvcnkuCi0gICAgICogQHBhcmFtIHNvdXJjZSB0aGUgc3R5bGVzaGVldC4KLSAgICAgKiBAcmV0dXJuIEEgVHJhbnNmb3JtZXIgb2JqZWN0LgotICAgICAqLwotICAgIHB1YmxpYyBUcmFuc2Zvcm1lciBuZXdUcmFuc2Zvcm1lcihTb3VyY2Ugc291cmNlKSB0aHJvd3MKLSAgICAgICAgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAoX3hhbGFuRmFjdG9yeSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBjcmVhdGVYYWxhblRyYW5zZm9ybWVyRmFjdG9yeSgpOwotICAgICAgICB9Ci0gICAgICAgIGlmIChfZXJyb3JsaXN0ZW5lciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBfeGFsYW5GYWN0b3J5LnNldEVycm9yTGlzdGVuZXIoX2Vycm9ybGlzdGVuZXIpOwotICAgICAgICB9Ci0gICAgICAgIGlmIChfdXJpcmVzb2x2ZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgX3hhbGFuRmFjdG9yeS5zZXRVUklSZXNvbHZlcihfdXJpcmVzb2x2ZXIpOwotICAgICAgICB9Ci0gICAgICAgIF9jdXJyRmFjdG9yeSA9IF94YWxhbkZhY3Rvcnk7Ci0gICAgICAgIHJldHVybiBfY3VyckZhY3RvcnkubmV3VHJhbnNmb3JtZXIoc291cmNlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGUgYSBUZW1wbGF0ZXMgb2JqZWN0IHRoYXQgZnJvbSB0aGUgaW5wdXQgc3R5bGVzaGVldAotICAgICAqIFVzZXMgdGhlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy50cmF4LlRyYW5zZm9ybWVyRmFjdG9yeS4KLSAgICAgKiBAcGFyYW0gc291cmNlIHRoZSBzdHlsZXNoZWV0LgotICAgICAqIEByZXR1cm4gQSBUZW1wbGF0ZXMgb2JqZWN0LgotICAgICAqLwotICAgIHB1YmxpYyBUZW1wbGF0ZXMgbmV3VGVtcGxhdGVzKFNvdXJjZSBzb3VyY2UpCi0gICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGlmIChfeHNsdGNGYWN0b3J5ID09IG51bGwpIHsKLSAgICAgICAgICAgIGNyZWF0ZVhTTFRDVHJhbnNmb3JtZXJGYWN0b3J5KCk7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKF9lcnJvcmxpc3RlbmVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIF94c2x0Y0ZhY3Rvcnkuc2V0RXJyb3JMaXN0ZW5lcihfZXJyb3JsaXN0ZW5lcik7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKF91cmlyZXNvbHZlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBfeHNsdGNGYWN0b3J5LnNldFVSSVJlc29sdmVyKF91cmlyZXNvbHZlcik7Ci0gICAgICAgIH0KLSAgICAgICAgX2N1cnJGYWN0b3J5ID0gX3hzbHRjRmFjdG9yeTsKLSAgICAgICAgcmV0dXJuIF9jdXJyRmFjdG9yeS5uZXdUZW1wbGF0ZXMoc291cmNlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgYSBUZW1wbGF0ZXNIYW5kbGVyIG9iamVjdCB0aGF0IGNhbiBwcm9jZXNzIFNBWCBDb250ZW50SGFuZGxlcgotICAgICAqIGV2ZW50cyBpbnRvIGEgVGVtcGxhdGVzIG9iamVjdC4gVXNlcyB0aGUKLSAgICAgKiBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMudHJheC5UcmFuc2Zvcm1lckZhY3RvcnkuCi0gICAgICovCi0gICAgcHVibGljIFRlbXBsYXRlc0hhbmRsZXIgbmV3VGVtcGxhdGVzSGFuZGxlcigpCi0gICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGlmIChfeHNsdGNGYWN0b3J5ID09IG51bGwpIHsKLSAgICAgICAgICAgIGNyZWF0ZVhTTFRDVHJhbnNmb3JtZXJGYWN0b3J5KCk7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKF9lcnJvcmxpc3RlbmVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIF94c2x0Y0ZhY3Rvcnkuc2V0RXJyb3JMaXN0ZW5lcihfZXJyb3JsaXN0ZW5lcik7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKF91cmlyZXNvbHZlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBfeHNsdGNGYWN0b3J5LnNldFVSSVJlc29sdmVyKF91cmlyZXNvbHZlcik7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIF94c2x0Y0ZhY3RvcnkubmV3VGVtcGxhdGVzSGFuZGxlcigpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCBhIFRyYW5zZm9ybWVySGFuZGxlciBvYmplY3QgdGhhdCBjYW4gcHJvY2VzcyBTQVggQ29udGVudEhhbmRsZXIKLSAgICAgKiBldmVudHMgYmFzZWQgb24gYSBjb3B5IHRyYW5zZm9ybWVyLgotICAgICAqIFVzZXMgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnByb2Nlc3Nvci5UcmFuc2Zvcm1lckZhY3RvcnkuCi0gICAgICovCi0gICAgcHVibGljIFRyYW5zZm9ybWVySGFuZGxlciBuZXdUcmFuc2Zvcm1lckhhbmRsZXIoKQotICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAoX3hhbGFuRmFjdG9yeSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBjcmVhdGVYYWxhblRyYW5zZm9ybWVyRmFjdG9yeSgpOwotICAgICAgICB9Ci0gICAgICAgIGlmIChfZXJyb3JsaXN0ZW5lciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBfeGFsYW5GYWN0b3J5LnNldEVycm9yTGlzdGVuZXIoX2Vycm9ybGlzdGVuZXIpOwotICAgICAgICB9Ci0gICAgICAgIGlmIChfdXJpcmVzb2x2ZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgX3hhbGFuRmFjdG9yeS5zZXRVUklSZXNvbHZlcihfdXJpcmVzb2x2ZXIpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBfeGFsYW5GYWN0b3J5Lm5ld1RyYW5zZm9ybWVySGFuZGxlcigpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCBhIFRyYW5zZm9ybWVySGFuZGxlciBvYmplY3QgdGhhdCBjYW4gcHJvY2VzcyBTQVggQ29udGVudEhhbmRsZXIKLSAgICAgKiBldmVudHMgYmFzZWQgb24gYSB0cmFuc2Zvcm1lciBzcGVjaWZpZWQgYnkgdGhlIHN0eWxlc2hlZXQgU291cmNlLgotICAgICAqIFVzZXMgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnByb2Nlc3Nvci5UcmFuc2Zvcm1lckZhY3RvcnkuCi0gICAgICovCi0gICAgcHVibGljIFRyYW5zZm9ybWVySGFuZGxlciBuZXdUcmFuc2Zvcm1lckhhbmRsZXIoU291cmNlIHNyYykKLSAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaWYgKF94YWxhbkZhY3RvcnkgPT0gbnVsbCkgewotICAgICAgICAgICAgY3JlYXRlWGFsYW5UcmFuc2Zvcm1lckZhY3RvcnkoKTsKLSAgICAgICAgfQotICAgICAgICBpZiAoX2Vycm9ybGlzdGVuZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgX3hhbGFuRmFjdG9yeS5zZXRFcnJvckxpc3RlbmVyKF9lcnJvcmxpc3RlbmVyKTsKLSAgICAgICAgfQotICAgICAgICBpZiAoX3VyaXJlc29sdmVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIF94YWxhbkZhY3Rvcnkuc2V0VVJJUmVzb2x2ZXIoX3VyaXJlc29sdmVyKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gX3hhbGFuRmFjdG9yeS5uZXdUcmFuc2Zvcm1lckhhbmRsZXIoc3JjKTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIEdldCBhIFRyYW5zZm9ybWVySGFuZGxlciBvYmplY3QgdGhhdCBjYW4gcHJvY2VzcyBTQVggQ29udGVudEhhbmRsZXIKLSAgICAgKiBldmVudHMgYmFzZWQgb24gYSB0cmFuc2Zvcm1lciBzcGVjaWZpZWQgYnkgdGhlIHN0eWxlc2hlZXQgU291cmNlLgotICAgICAqIFVzZXMgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnRyYXguVHJhbnNmb3JtZXJGYWN0b3J5LgotICAgICAqLwotICAgIHB1YmxpYyBUcmFuc2Zvcm1lckhhbmRsZXIgbmV3VHJhbnNmb3JtZXJIYW5kbGVyKFRlbXBsYXRlcyB0ZW1wbGF0ZXMpCi0gICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGlmIChfeHNsdGNGYWN0b3J5ID09IG51bGwpIHsKLSAgICAgICAgICAgIGNyZWF0ZVhTTFRDVHJhbnNmb3JtZXJGYWN0b3J5KCk7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKF9lcnJvcmxpc3RlbmVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIF94c2x0Y0ZhY3Rvcnkuc2V0RXJyb3JMaXN0ZW5lcihfZXJyb3JsaXN0ZW5lcik7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKF91cmlyZXNvbHZlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBfeHNsdGNGYWN0b3J5LnNldFVSSVJlc29sdmVyKF91cmlyZXNvbHZlcik7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIF94c2x0Y0ZhY3RvcnkubmV3VHJhbnNmb3JtZXJIYW5kbGVyKHRlbXBsYXRlcyk7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBDcmVhdGUgYW4gWE1MRmlsdGVyIHRoYXQgdXNlcyB0aGUgZ2l2ZW4gc291cmNlIGFzIHRoZQotICAgICAqIHRyYW5zZm9ybWF0aW9uIGluc3RydWN0aW9ucy4gVXNlcwotICAgICAqIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy50cmF4LlRyYW5zZm9ybWVyRmFjdG9yeS4KLSAgICAgKi8KLSAgICBwdWJsaWMgWE1MRmlsdGVyIG5ld1hNTEZpbHRlcihTb3VyY2Ugc3JjKQotICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKF94c2x0Y0ZhY3RvcnkgPT0gbnVsbCkgewotICAgICAgICAgICAgY3JlYXRlWFNMVENUcmFuc2Zvcm1lckZhY3RvcnkoKTsKLSAgICAgICAgfQotICAgICAgICBpZiAoX2Vycm9ybGlzdGVuZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgX3hzbHRjRmFjdG9yeS5zZXRFcnJvckxpc3RlbmVyKF9lcnJvcmxpc3RlbmVyKTsKLSAgICAgICAgfQotICAgICAgICBpZiAoX3VyaXJlc29sdmVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIF94c2x0Y0ZhY3Rvcnkuc2V0VVJJUmVzb2x2ZXIoX3VyaXJlc29sdmVyKTsKLSAgICAgICAgfQotICAgICAgICBUZW1wbGF0ZXMgdGVtcGxhdGVzID0gX3hzbHRjRmFjdG9yeS5uZXdUZW1wbGF0ZXMoc3JjKTsKLSAgICAgICAgaWYgKHRlbXBsYXRlcyA9PSBudWxsICkgcmV0dXJuIG51bGw7Ci0gICAgICAgIHJldHVybiBuZXdYTUxGaWx0ZXIodGVtcGxhdGVzKTsKLSAgICB9Ci0KLSAgICAvKgotICAgICAqIENyZWF0ZSBhbiBYTUxGaWx0ZXIgdGhhdCB1c2VzIHRoZSBnaXZlbiBzb3VyY2UgYXMgdGhlCi0gICAgICogdHJhbnNmb3JtYXRpb24gaW5zdHJ1Y3Rpb25zLiBVc2VzCi0gICAgICogY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnRyYXguVHJhbnNmb3JtZXJGYWN0b3J5LgotICAgICAqLwotICAgIHB1YmxpYyBYTUxGaWx0ZXIgbmV3WE1MRmlsdGVyKFRlbXBsYXRlcyB0ZW1wbGF0ZXMpCi0gICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gewotICAgICAgICB0cnkgewotICAgICAgICAgICAgcmV0dXJuIG5ldyBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMudHJheC5UckFYRmlsdGVyKHRlbXBsYXRlcyk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2goVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIGUxKSB7Ci0gICAgICAgICAgICBpZiAoX3hzbHRjRmFjdG9yeSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgY3JlYXRlWFNMVENUcmFuc2Zvcm1lckZhY3RvcnkoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIEVycm9yTGlzdGVuZXIgZXJyb3JMaXN0ZW5lciA9IF94c2x0Y0ZhY3RvcnkuZ2V0RXJyb3JMaXN0ZW5lcigpOwotICAgICAgICAgICAgaWYoZXJyb3JMaXN0ZW5lciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgZXJyb3JMaXN0ZW5lci5mYXRhbEVycm9yKGUxKTsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGNhdGNoKCBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBlMikgewotICAgICAgICAgICAgICAgICAgICBuZXcgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uKGUyKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICB0aHJvdyBlMTsKLSAgICAgICAgfQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvdHJheC9TdEFYRXZlbnQyU0FYLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3RyYXgvU3RBWEV2ZW50MlNBWC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2MmJiOTBmLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvdHJheC9TdEFYRXZlbnQyU0FYLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw2MDAgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMudHJheDsKLQotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci1pbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOwotCi1pbXBvcnQgb3JnLnhtbC5zYXguQXR0cmlidXRlczsKLWltcG9ydCBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5EVERIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LkVudGl0eVJlc29sdmVyOwotaW1wb3J0IG9yZy54bWwuc2F4LkVycm9ySGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKLWltcG9ydCBvcmcueG1sLnNheC5Mb2NhdG9yOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5YTUxSZWFkZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguZXh0LkxleGljYWxIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LmhlbHBlcnMuQXR0cmlidXRlc0ltcGw7Ci1pbXBvcnQgb3JnLnhtbC5zYXguZXh0LkxvY2F0b3IyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5kb20uU0FYSW1wbDsKLQotaW1wb3J0IGphdmF4LnhtbC5uYW1lc3BhY2UuUU5hbWU7Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5YTUxFdmVudFJlYWRlcjsKLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLlhNTFN0cmVhbUNvbnN0YW50czsKLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLlhNTFN0cmVhbUV4Y2VwdGlvbjsKLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLmV2ZW50cy5BdHRyaWJ1dGU7Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5ldmVudHMuQ2hhcmFjdGVyczsKLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLmV2ZW50cy5FbmRFbGVtZW50OwotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uZXZlbnRzLk5hbWVzcGFjZTsKLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLmV2ZW50cy5Qcm9jZXNzaW5nSW5zdHJ1Y3Rpb247Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5ldmVudHMuU3RhcnRFbGVtZW50OwotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uZXZlbnRzLlhNTEV2ZW50OwotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uZXZlbnRzLlN0YXJ0RG9jdW1lbnQ7Ci0KLQotLyoqCi0gKiBAYXV0aG9yIFN1cmVzaCBLdW1hcgotICogQGF1dGhvciBTdW5pdGhhIFJlZGR5Ci0gKiBAc2luY2UgMS42Ci0gKi8KLXB1YmxpYyBjbGFzcyBTdEFYRXZlbnQyU0FYIGltcGxlbWVudHMgWE1MUmVhZGVyLCBMb2NhdG9yIHsKLQotICAgIC8vcHJpdmF0ZSBmaW5hbCBzdGF0aWMgU3RyaW5nIEVNUFRZU1RSSU5HID0gIiI7Ci0gICAgLy9wcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MTlNfUFJFRklYID0gInhtbG5zIjsKLQotICAgIC8vIFN0QVggZXZlbnQgc291cmNlCi0gICAgcHJpdmF0ZSBmaW5hbCBYTUxFdmVudFJlYWRlciBzdGF4RXZlbnRSZWFkZXI7Ci0KLSAgICAvL3ByaXZhdGUgTm9kZSBfZG9tID0gbnVsbDsKLSAgICBwcml2YXRlIENvbnRlbnRIYW5kbGVyIF9zYXggPSBudWxsOwotICAgIHByaXZhdGUgTGV4aWNhbEhhbmRsZXIgX2xleCA9IG51bGw7Ci0gICAgcHJpdmF0ZSBTQVhJbXBsIF9zYXhJbXBsID0gbnVsbDsKLSAgICBwcml2YXRlIFN0cmluZyB2ZXJzaW9uID0gbnVsbDsKLSAgICBwcml2YXRlIFN0cmluZyBlbmNvZGluZyA9IG51bGw7Ci0KLQotICAgIHB1YmxpYyBTdEFYRXZlbnQyU0FYKFhNTEV2ZW50UmVhZGVyIHN0YXhDb3JlKSB7Ci0gICAgICAgIHN0YXhFdmVudFJlYWRlciA9IHN0YXhDb3JlOwotICAgIH0KLQotICAgIHB1YmxpYyBDb250ZW50SGFuZGxlciBnZXRDb250ZW50SGFuZGxlcigpIHsKLSAgICAgICAgcmV0dXJuIF9zYXg7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0Q29udGVudEhhbmRsZXIoQ29udGVudEhhbmRsZXIgaGFuZGxlcikgdGhyb3dzCi0gICAgICAgIE51bGxQb2ludGVyRXhjZXB0aW9uCi0gICAgewotICAgICAgICBfc2F4ID0gaGFuZGxlcjsKLSAgICAgICAgaWYgKGhhbmRsZXIgaW5zdGFuY2VvZiBMZXhpY2FsSGFuZGxlcikgewotICAgICAgICAgICAgX2xleCA9IChMZXhpY2FsSGFuZGxlcikgaGFuZGxlcjsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChoYW5kbGVyIGluc3RhbmNlb2YgU0FYSW1wbCkgewotICAgICAgICAgICAgX3NheEltcGwgPSAoU0FYSW1wbCloYW5kbGVyOwotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgdm9pZCBwYXJzZShJbnB1dFNvdXJjZSB1bnVzZWQpIHRocm93cyBJT0V4Y2VwdGlvbiwgU0FYRXhjZXB0aW9uIHsKLSAgICAgICB0cnkgewotICAgICAgICAgICAgYnJpZGdlKCk7Ci0gICAgICAgIH0gY2F0Y2ggKFhNTFN0cmVhbUV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKGUpOwotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICAvL01haW4gV29yayBTdGFydHMgSGVyZS4KLSAgICBwdWJsaWMgdm9pZCBwYXJzZSgpIHRocm93cyBJT0V4Y2VwdGlvbiwgU0FYRXhjZXB0aW9uLCBYTUxTdHJlYW1FeGNlcHRpb24gewotICAgICAgICBicmlkZ2UoKTsKLSAgICB9Ci0KLQotICAgIC8qICBwdWJsaWMgdm9pZCBwYXJzZSgpIHRocm93cyBJT0V4Y2VwdGlvbiwgU0FYRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKF9kb20gIT0gbnVsbCkgewotICAgICAgICAgICAgYm9vbGVhbiBpc0luY29tcGxldGUgPQotICAgICAgICAgICAgICAgIChfZG9tLmdldE5vZGVUeXBlKCkgIT0gb3JnLnczYy5kb20uTm9kZS5ET0NVTUVOVF9OT0RFKTsKLQotICAgICAgICAgICAgaWYgKGlzSW5jb21wbGV0ZSkgewotICAgICAgICAgICAgICAgIF9zYXguc3RhcnREb2N1bWVudCgpOwotICAgICAgICAgICAgICAgIHBhcnNlKF9kb20pOwotICAgICAgICAgICAgICAgIF9zYXguZW5kRG9jdW1lbnQoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIHBhcnNlKF9kb20pOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotICAgICovCi0KLSAgICAvKgotICAgICAqIEBzZWUgU3RBWFJlYWRlclRvQ29udGVudEhhbmRsZXIjYnJpZGdlKCkKLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgYnJpZGdlKCkgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIC8vIHJlbWVtYmVycyB0aGUgbmVzdCBsZXZlbCBvZiBlbGVtZW50cyB0byBrbm93IHdoZW4gd2UgYXJlIGRvbmUuCi0gICAgICAgICAgICBpbnQgZGVwdGg9MDsKLSAgICAgICAgICAgIGJvb2xlYW4gc3RhcnRlZEF0RG9jdW1lbnQgPSBmYWxzZTsKLQotICAgICAgICAgICAgWE1MRXZlbnQgZXZlbnQgPSBzdGF4RXZlbnRSZWFkZXIucGVlaygpOwotCi0gICAgICAgICAgICBpZiAoIWV2ZW50LmlzU3RhcnREb2N1bWVudCgpICYmICFldmVudC5pc1N0YXJ0RWxlbWVudCgpKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAoZXZlbnQuZ2V0RXZlbnRUeXBlKCkgPT0gWE1MU3RyZWFtQ29uc3RhbnRzLlNUQVJUX0RPQ1VNRU5UKXsKLSAgICAgICAgICAgICAgICBzdGFydGVkQXREb2N1bWVudCA9IHRydWU7Ci0gICAgICAgICAgICAgICAgdmVyc2lvbiA9ICgoU3RhcnREb2N1bWVudClldmVudCkuZ2V0VmVyc2lvbigpOwotICAgICAgICAgICAgICAgIGlmICgoKFN0YXJ0RG9jdW1lbnQpZXZlbnQpLmVuY29kaW5nU2V0KCkpCi0gICAgICAgICAgICAgICAgICAgIGVuY29kaW5nID0gKChTdGFydERvY3VtZW50KWV2ZW50KS5nZXRDaGFyYWN0ZXJFbmNvZGluZ1NjaGVtZSgpOwotICAgICAgICAgICAgICAgIGV2ZW50PXN0YXhFdmVudFJlYWRlci5uZXh0RXZlbnQoKTsgLy8gdGhhdCBnZXRzIHRoZSBvbmUgd2UgcGVla2VkIGF0Ci0gICAgICAgICAgICAgICAgZXZlbnQ9c3RheEV2ZW50UmVhZGVyLm5leHRFdmVudCgpOyAvLyB0aGF0IHJlYWxseSBnZXRzIHRoZSBuZXh0IG9uZQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBoYW5kbGVTdGFydERvY3VtZW50KGV2ZW50KTsKLQotICAgICAgICAgICAgLy8gSGFuZGxlIHRoZSBwcm9sb2c6IGh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy14bWwvI05ULXByb2xvZwotICAgICAgICAgICAgd2hpbGUgKGV2ZW50LmdldEV2ZW50VHlwZSgpICE9IFhNTFN0cmVhbUNvbnN0YW50cy5TVEFSVF9FTEVNRU5UKSB7Ci0gICAgICAgICAgICAgICAgc3dpdGNoIChldmVudC5nZXRFdmVudFR5cGUoKSkgewotICAgICAgICAgICAgICAgICAgICBjYXNlIFhNTFN0cmVhbUNvbnN0YW50cy5DSEFSQUNURVJTIDoKLSAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZUNoYXJhY3RlcnMoZXZlbnQuYXNDaGFyYWN0ZXJzKCkpOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgWE1MU3RyZWFtQ29uc3RhbnRzLlBST0NFU1NJTkdfSU5TVFJVQ1RJT04gOgotICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlUEkoKFByb2Nlc3NpbmdJbnN0cnVjdGlvbilldmVudCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgY2FzZSBYTUxTdHJlYW1Db25zdGFudHMuQ09NTUVOVCA6Ci0gICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVDb21tZW50KCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgY2FzZSBYTUxTdHJlYW1Db25zdGFudHMuRFREIDoKLSAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZURURCgpOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgWE1MU3RyZWFtQ29uc3RhbnRzLlNQQUNFIDoKLSAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZVNwYWNlKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgZGVmYXVsdCA6Ci0gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcigicHJvY2Vzc2luZyBwcm9sb2cgZXZlbnQ6ICIgKyBldmVudCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGV2ZW50PXN0YXhFdmVudFJlYWRlci5uZXh0RXZlbnQoKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gUHJvY2VzcyB0aGUgKGRvY3VtZW50KSBlbGVtZW50Ci0gICAgICAgICAgICBkbyB7Ci0gICAgICAgICAgICAgICAgLy8gVGhlc2UgYXJlIGFsbCBvZiB0aGUgZXZlbnRzIGxpc3RlZCBpbiB0aGUgamF2YWRvYyBmb3IKLSAgICAgICAgICAgICAgICAvLyBYTUxFdmVudC4KLSAgICAgICAgICAgICAgICAvLyBUaGUgc3BlYyBvbmx5IHJlYWxseSBkZXNjcmliZXMgMTEgb2YgdGhlbS4KLSAgICAgICAgICAgICAgICBzd2l0Y2ggKGV2ZW50LmdldEV2ZW50VHlwZSgpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgWE1MU3RyZWFtQ29uc3RhbnRzLlNUQVJUX0VMRU1FTlQgOgotICAgICAgICAgICAgICAgICAgICAgICAgZGVwdGgrKzsKLSAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZVN0YXJ0RWxlbWVudChldmVudC5hc1N0YXJ0RWxlbWVudCgpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICBjYXNlIFhNTFN0cmVhbUNvbnN0YW50cy5FTkRfRUxFTUVOVCA6Ci0gICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVFbmRFbGVtZW50KGV2ZW50LmFzRW5kRWxlbWVudCgpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGRlcHRoLS07Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgY2FzZSBYTUxTdHJlYW1Db25zdGFudHMuQ0hBUkFDVEVSUyA6Ci0gICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVDaGFyYWN0ZXJzKGV2ZW50LmFzQ2hhcmFjdGVycygpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICBjYXNlIFhNTFN0cmVhbUNvbnN0YW50cy5FTlRJVFlfUkVGRVJFTkNFIDoKLSAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZUVudGl0eVJlZmVyZW5jZSgpOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgWE1MU3RyZWFtQ29uc3RhbnRzLlBST0NFU1NJTkdfSU5TVFJVQ1RJT04gOgotICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlUEkoKFByb2Nlc3NpbmdJbnN0cnVjdGlvbilldmVudCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgY2FzZSBYTUxTdHJlYW1Db25zdGFudHMuQ09NTUVOVCA6Ci0gICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVDb21tZW50KCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgY2FzZSBYTUxTdHJlYW1Db25zdGFudHMuRFREIDoKLSAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZURURCgpOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgWE1MU3RyZWFtQ29uc3RhbnRzLkFUVFJJQlVURSA6Ci0gICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVBdHRyaWJ1dGUoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICBjYXNlIFhNTFN0cmVhbUNvbnN0YW50cy5OQU1FU1BBQ0UgOgotICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlTmFtZXNwYWNlKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgY2FzZSBYTUxTdHJlYW1Db25zdGFudHMuQ0RBVEEgOgotICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlQ0RBVEEoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICBjYXNlIFhNTFN0cmVhbUNvbnN0YW50cy5FTlRJVFlfREVDTEFSQVRJT04gOgotICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlRW50aXR5RGVjbCgpOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgWE1MU3RyZWFtQ29uc3RhbnRzLk5PVEFUSU9OX0RFQ0xBUkFUSU9OIDoKLSAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZU5vdGF0aW9uRGVjbCgpOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgWE1MU3RyZWFtQ29uc3RhbnRzLlNQQUNFIDoKLSAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZVNwYWNlKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgZGVmYXVsdCA6Ci0gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcigicHJvY2Vzc2luZyBldmVudDogIiArIGV2ZW50KTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBldmVudD1zdGF4RXZlbnRSZWFkZXIubmV4dEV2ZW50KCk7Ci0gICAgICAgICAgICB9IHdoaWxlIChkZXB0aCE9MCk7Ci0KLSAgICAgICAgICAgIGlmIChzdGFydGVkQXREb2N1bWVudCkgewotICAgICAgICAgICAgICAgIC8vIEhhbmRsZSB0aGUgTWlzYyAoaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLXhtbC8jTlQtTWlzYykgdGhhdCBjYW4gZm9sbG93IHRoZSBkb2N1bWVudCBlbGVtZW50Ci0gICAgICAgICAgICAgICAgd2hpbGUgKGV2ZW50LmdldEV2ZW50VHlwZSgpICE9IFhNTFN0cmVhbUNvbnN0YW50cy5FTkRfRE9DVU1FTlQpIHsKLSAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChldmVudC5nZXRFdmVudFR5cGUoKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBYTUxTdHJlYW1Db25zdGFudHMuQ0hBUkFDVEVSUyA6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlQ2hhcmFjdGVycyhldmVudC5hc0NoYXJhY3RlcnMoKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFhNTFN0cmVhbUNvbnN0YW50cy5QUk9DRVNTSU5HX0lOU1RSVUNUSU9OIDoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVQSSgoUHJvY2Vzc2luZ0luc3RydWN0aW9uKWV2ZW50KTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgWE1MU3RyZWFtQ29uc3RhbnRzLkNPTU1FTlQgOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZUNvbW1lbnQoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgWE1MU3RyZWFtQ29uc3RhbnRzLlNQQUNFIDoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVTcGFjZSgpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdCA6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoInByb2Nlc3NpbmcgbWlzYyBldmVudCBhZnRlciBkb2N1bWVudCBlbGVtZW50OiAiICsgZXZlbnQpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGV2ZW50PXN0YXhFdmVudFJlYWRlci5uZXh0RXZlbnQoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGhhbmRsZUVuZERvY3VtZW50KCk7Ci0gICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWE1MU3RyZWFtRXhjZXB0aW9uKGUpOwotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICBwcml2YXRlIHZvaWQgaGFuZGxlRW5kRG9jdW1lbnQoKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICAgICAgX3NheC5lbmREb2N1bWVudCgpOwotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBoYW5kbGVTdGFydERvY3VtZW50KGZpbmFsIFhNTEV2ZW50IGV2ZW50KSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICAgICAgX3NheC5zZXREb2N1bWVudExvY2F0b3IobmV3IExvY2F0b3IyKCkgewotICAgICAgICAgICAgcHVibGljIGludCBnZXRDb2x1bW5OdW1iZXIoKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGV2ZW50LmdldExvY2F0aW9uKCkuZ2V0Q29sdW1uTnVtYmVyKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBwdWJsaWMgaW50IGdldExpbmVOdW1iZXIoKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGV2ZW50LmdldExvY2F0aW9uKCkuZ2V0TGluZU51bWJlcigpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcHVibGljIFN0cmluZyBnZXRQdWJsaWNJZCgpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZXZlbnQuZ2V0TG9jYXRpb24oKS5nZXRQdWJsaWNJZCgpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcHVibGljIFN0cmluZyBnZXRTeXN0ZW1JZCgpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZXZlbnQuZ2V0TG9jYXRpb24oKS5nZXRTeXN0ZW1JZCgpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcHVibGljIFN0cmluZyBnZXRYTUxWZXJzaW9uKCl7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHZlcnNpb247Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBwdWJsaWMgU3RyaW5nIGdldEVuY29kaW5nKCl7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGVuY29kaW5nOwotICAgICAgICAgICAgfQotCi0gICAgICAgIH0pOwotICAgICAgICBfc2F4LnN0YXJ0RG9jdW1lbnQoKTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgaGFuZGxlUEkoUHJvY2Vzc2luZ0luc3RydWN0aW9uIGV2ZW50KQotICAgICAgICB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIF9zYXgucHJvY2Vzc2luZ0luc3RydWN0aW9uKAotICAgICAgICAgICAgICAgIGV2ZW50LmdldFRhcmdldCgpLAotICAgICAgICAgICAgICAgIGV2ZW50LmdldERhdGEoKSk7Ci0gICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWE1MU3RyZWFtRXhjZXB0aW9uKGUpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIGhhbmRsZUNoYXJhY3RlcnMoQ2hhcmFjdGVycyBldmVudCkgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbiB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBfc2F4LmNoYXJhY3RlcnMoCi0gICAgICAgICAgICAgICAgZXZlbnQuZ2V0RGF0YSgpLnRvQ2hhckFycmF5KCksCi0gICAgICAgICAgICAgICAgMCwKLSAgICAgICAgICAgICAgICBldmVudC5nZXREYXRhKCkubGVuZ3RoKCkpOwotICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFhNTFN0cmVhbUV4Y2VwdGlvbihlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBoYW5kbGVFbmRFbGVtZW50KEVuZEVsZW1lbnQgZXZlbnQpIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24gewotICAgICAgICBRTmFtZSBxTmFtZSA9IGV2ZW50LmdldE5hbWUoKTsKLQotICAgICAgICAvL2NvbnN0cnVjdCBwcmVmaXg6bG9jYWxOYW1lIGZyb20gcU5hbWUKLSAgICAgICAgU3RyaW5nIHFuYW1lID0gIiI7Ci0gICAgICAgIGlmIChxTmFtZS5nZXRQcmVmaXgoKSAhPSBudWxsICYmIHFOYW1lLmdldFByZWZpeCgpLnRyaW0oKS5sZW5ndGgoKSAhPSAwKXsKLSAgICAgICAgICAgIHFuYW1lID0gcU5hbWUuZ2V0UHJlZml4KCkgKyAiOiI7Ci0gICAgICAgIH0KLSAgICAgICAgcW5hbWUgKz0gcU5hbWUuZ2V0TG9jYWxQYXJ0KCk7Ci0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIC8vIGZpcmUgZW5kRWxlbWVudAotICAgICAgICAgICAgX3NheC5lbmRFbGVtZW50KAotICAgICAgICAgICAgICAgIHFOYW1lLmdldE5hbWVzcGFjZVVSSSgpLAotICAgICAgICAgICAgICAgIHFOYW1lLmdldExvY2FsUGFydCgpLAotICAgICAgICAgICAgICAgIHFuYW1lKTsKLQotICAgICAgICAgICAgLy8gZW5kIG5hbWVzcGFjZSBiaW5kaW5ncwotICAgICAgICAgICAgZm9yKCBJdGVyYXRvciBpID0gZXZlbnQuZ2V0TmFtZXNwYWNlcygpOyBpLmhhc05leHQoKTspIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgcHJlZml4ID0gKFN0cmluZylpLm5leHQoKTsKLSAgICAgICAgICAgICAgICBpZiggcHJlZml4ID09IG51bGwgKSB7IC8vIHRydWUgZm9yIGRlZmF1bHQgbmFtZXNwYWNlCi0gICAgICAgICAgICAgICAgICAgIHByZWZpeCA9ICIiOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBfc2F4LmVuZFByZWZpeE1hcHBpbmcocHJlZml4KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBYTUxTdHJlYW1FeGNlcHRpb24oZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgaGFuZGxlU3RhcnRFbGVtZW50KFN0YXJ0RWxlbWVudCBldmVudCkKLSAgICAgICAgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbiB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAvLyBzdGFydCBuYW1lc3BhY2UgYmluZGluZ3MKLSAgICAgICAgICAgIGZvciAoSXRlcmF0b3IgaSA9IGV2ZW50LmdldE5hbWVzcGFjZXMoKTsgaS5oYXNOZXh0KCk7KSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIHByZWZpeCA9ICgoTmFtZXNwYWNlKWkubmV4dCgpKS5nZXRQcmVmaXgoKTsKLSAgICAgICAgICAgICAgICBpZiAocHJlZml4ID09IG51bGwpIHsgLy8gdHJ1ZSBmb3IgZGVmYXVsdCBuYW1lc3BhY2UKLSAgICAgICAgICAgICAgICAgICAgcHJlZml4ID0gIiI7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIF9zYXguc3RhcnRQcmVmaXhNYXBwaW5nKAotICAgICAgICAgICAgICAgICAgICBwcmVmaXgsCi0gICAgICAgICAgICAgICAgICAgIGV2ZW50LmdldE5hbWVzcGFjZVVSSShwcmVmaXgpKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gZmlyZSBzdGFydEVsZW1lbnQKLSAgICAgICAgICAgIFFOYW1lIHFOYW1lID0gZXZlbnQuZ2V0TmFtZSgpOwotICAgICAgICAgICAgU3RyaW5nIHByZWZpeCA9IHFOYW1lLmdldFByZWZpeCgpOwotICAgICAgICAgICAgU3RyaW5nIHJhd25hbWU7Ci0gICAgICAgICAgICBpZiAocHJlZml4ID09IG51bGwgfHwgcHJlZml4Lmxlbmd0aCgpID09IDApIHsKLSAgICAgICAgICAgICAgICByYXduYW1lID0gcU5hbWUuZ2V0TG9jYWxQYXJ0KCk7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIHJhd25hbWUgPSBwcmVmaXggKyAnOicgKyBxTmFtZS5nZXRMb2NhbFBhcnQoKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgQXR0cmlidXRlcyBzYXhBdHRycyA9IGdldEF0dHJpYnV0ZXMoZXZlbnQpOwotICAgICAgICAgICAgX3NheC5zdGFydEVsZW1lbnQoCi0gICAgICAgICAgICAgICAgcU5hbWUuZ2V0TmFtZXNwYWNlVVJJKCksCi0gICAgICAgICAgICAgICAgcU5hbWUuZ2V0TG9jYWxQYXJ0KCksCi0gICAgICAgICAgICAgICAgcmF3bmFtZSwKLSAgICAgICAgICAgICAgICBzYXhBdHRycyk7Ci0gICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWE1MU3RyZWFtRXhjZXB0aW9uKGUpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBhdHRyaWJ1dGVzIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gU1RBUlRfRUxFTUVOVCBTdEFYZXZlbnQuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRoZSBTdEFYIGF0dHJpYnV0ZXMgY29udmVydGVkIHRvIGFuIG9yZy54bWwuc2F4LkF0dHJpYnV0ZXMKLSAgICAgKi8KLSAgICBwcml2YXRlIEF0dHJpYnV0ZXMgZ2V0QXR0cmlidXRlcyhTdGFydEVsZW1lbnQgZXZlbnQpIHsKLSAgICAgICAgQXR0cmlidXRlc0ltcGwgYXR0cnMgPSBuZXcgQXR0cmlidXRlc0ltcGwoKTsKLQotICAgICAgICBpZiAoICFldmVudC5pc1N0YXJ0RWxlbWVudCgpICkgewotICAgICAgICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoCi0gICAgICAgICAgICAgICAgImdldEF0dHJpYnV0ZXMoKSBhdHRlbXB0aW5nIHRvIHByb2Nlc3M6ICIgKyBldmVudCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBpbiBTQVgsIG5hbWVzcGFjZSBkZWNsYXJhdGlvbnMgYXJlIG5vdCBwYXJ0IG9mIGF0dHJpYnV0ZXMgYnkgZGVmYXVsdC4KLSAgICAgICAgLy8gKHRoZXJlJ3MgYSBwcm9wZXJ0eSB0byBjb250cm9sIHRoYXQsIGJ1dCBhcyBmYXIgYXMgd2UgYXJlIGNvbmNlcm5lZAotICAgICAgICAvLyB3ZSBkb24ndCB1c2UgaXQuKSBTbyBkb24ndCBhZGQgeG1sbnM6KiB0byBhdHRyaWJ1dGVzLgotCi0gICAgICAgIC8vIGdhdGhlciBub24tbmFtZXNwYWNlIGF0dHJzCi0gICAgICAgIGZvciAoSXRlcmF0b3IgaSA9IGV2ZW50LmdldEF0dHJpYnV0ZXMoKTsgaS5oYXNOZXh0KCk7KSB7Ci0gICAgICAgICAgICBBdHRyaWJ1dGUgc3RheEF0dHIgPSAoamF2YXgueG1sLnN0cmVhbS5ldmVudHMuQXR0cmlidXRlKWkubmV4dCgpOwotCi0gICAgICAgICAgICBTdHJpbmcgdXJpID0gc3RheEF0dHIuZ2V0TmFtZSgpLmdldE5hbWVzcGFjZVVSSSgpOwotICAgICAgICAgICAgaWYgKHVyaSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgdXJpID0gIiI7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBTdHJpbmcgbG9jYWxOYW1lID0gc3RheEF0dHIuZ2V0TmFtZSgpLmdldExvY2FsUGFydCgpOwotICAgICAgICAgICAgU3RyaW5nIHByZWZpeCA9IHN0YXhBdHRyLmdldE5hbWUoKS5nZXRQcmVmaXgoKTsKLSAgICAgICAgICAgIFN0cmluZyBxTmFtZTsKLSAgICAgICAgICAgIGlmIChwcmVmaXggPT0gbnVsbCB8fCBwcmVmaXgubGVuZ3RoKCkgPT0gMCkgewotICAgICAgICAgICAgICAgIHFOYW1lID0gbG9jYWxOYW1lOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBxTmFtZSA9IHByZWZpeCArICc6JyArIGxvY2FsTmFtZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIFN0cmluZyB0eXBlID0gc3RheEF0dHIuZ2V0RFREVHlwZSgpOwotICAgICAgICAgICAgU3RyaW5nIHZhbHVlID0gc3RheEF0dHIuZ2V0VmFsdWUoKTsKLQotICAgICAgICAgICAgYXR0cnMuYWRkQXR0cmlidXRlKHVyaSwgbG9jYWxOYW1lLCBxTmFtZSwgdHlwZSwgdmFsdWUpOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIGF0dHJzOwotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBoYW5kbGVOYW1lc3BhY2UoKSB7Ci0gICAgICAgIC8vIG5vLW9wID8/PwotICAgICAgICAvLyBuYW1lc3BhY2UgZXZlbnRzIGRvbid0IG5vcm1hbGx5IG9jY3VyIG91dHNpZGUgb2YgYSBzdGFydEVsZW1lbnQKLSAgICAgICAgLy8gb3IgZW5kRWxlbWVudAotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBoYW5kbGVBdHRyaWJ1dGUoKSB7Ci0gICAgICAgIC8vIG5vLW9wID8/PwotICAgICAgICAvLyBhdHRyaWJ1dGUgZXZlbnRzIGRvbid0IG5vcm1hbGx5IG9jY3VyIG91dHNpZGUgb2YgYSBzdGFydEVsZW1lbnQKLSAgICAgICAgLy8gb3IgZW5kRWxlbWVudAotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBoYW5kbGVEVEQoKSB7Ci0gICAgICAgIC8vIG5vLW9wID8/PwotICAgICAgICAvLyBpdCBzZWVtcyBsaWtlIHdlIG5lZWQgdG8gcGFzcyB0aGlzIGluZm8gYWxvbmcsIGJ1dCBob3c/Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIGhhbmRsZUNvbW1lbnQoKSB7Ci0gICAgICAgIC8vIG5vLW9wID8/PwotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBoYW5kbGVFbnRpdHlSZWZlcmVuY2UoKSB7Ci0gICAgICAgIC8vIG5vLW9wID8/PwotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBoYW5kbGVTcGFjZSgpIHsKLSAgICAgICAgLy8gbm8tb3AgPz8/Ci0gICAgICAgIC8vIHRoaXMgZXZlbnQgaXMgbGlzdGVkIGluIHRoZSBqYXZhZG9jLCBidXQgbm90IGluIHRoZSBzcGVjLgotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBoYW5kbGVOb3RhdGlvbkRlY2woKSB7Ci0gICAgICAgIC8vIG5vLW9wID8/PwotICAgICAgICAvLyB0aGlzIGV2ZW50IGlzIGxpc3RlZCBpbiB0aGUgamF2YWRvYywgYnV0IG5vdCBpbiB0aGUgc3BlYy4KLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgaGFuZGxlRW50aXR5RGVjbCgpIHsKLSAgICAgICAgLy8gbm8tb3AgPz8/Ci0gICAgICAgIC8vIHRoaXMgZXZlbnQgaXMgbGlzdGVkIGluIHRoZSBqYXZhZG9jLCBidXQgbm90IGluIHRoZSBzcGVjLgotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBoYW5kbGVDREFUQSgpIHsKLSAgICAgICAgLy8gbm8tb3AgPz8/Ci0gICAgICAgIC8vIHRoaXMgZXZlbnQgaXMgbGlzdGVkIGluIHRoZSBqYXZhZG9jLCBidXQgbm90IGluIHRoZSBzcGVjLgotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogVGhpcyBjbGFzcyBpcyBvbmx5IHVzZWQgaW50ZXJuYWxseSBzbyB0aGlzIG1ldGhvZCBzaG91bGQgbmV2ZXIKLSAgICAgKiBiZSBjYWxsZWQuCi0gICAgICovCi0gICAgcHVibGljIERUREhhbmRsZXIgZ2V0RFRESGFuZGxlcigpIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBjbGFzcyBpcyBvbmx5IHVzZWQgaW50ZXJuYWxseSBzbyB0aGlzIG1ldGhvZCBzaG91bGQgbmV2ZXIKLSAgICAgKiBiZSBjYWxsZWQuCi0gICAgICovCi0gICAgcHVibGljIEVycm9ySGFuZGxlciBnZXRFcnJvckhhbmRsZXIoKSB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgY2xhc3MgaXMgb25seSB1c2VkIGludGVybmFsbHkgc28gdGhpcyBtZXRob2Qgc2hvdWxkIG5ldmVyCi0gICAgICogYmUgY2FsbGVkLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGdldEZlYXR1cmUoU3RyaW5nIG5hbWUpIHRocm93cyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uLAotICAgICAgICBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIGNsYXNzIGlzIG9ubHkgdXNlZCBpbnRlcm5hbGx5IHNvIHRoaXMgbWV0aG9kIHNob3VsZCBuZXZlcgotICAgICAqIGJlIGNhbGxlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRGZWF0dXJlKFN0cmluZyBuYW1lLCBib29sZWFuIHZhbHVlKSB0aHJvd3MKLSAgICAgICAgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiwgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uCi0gICAgewotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgY2xhc3MgaXMgb25seSB1c2VkIGludGVybmFsbHkgc28gdGhpcyBtZXRob2Qgc2hvdWxkIG5ldmVyCi0gICAgICogYmUgY2FsbGVkLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHBhcnNlKFN0cmluZyBzeXNJZCkgdGhyb3dzIElPRXhjZXB0aW9uLCBTQVhFeGNlcHRpb24gewotICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlRoaXMgbWV0aG9kIGlzIG5vdCB5ZXQgaW1wbGVtZW50ZWQuIik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBjbGFzcyBpcyBvbmx5IHVzZWQgaW50ZXJuYWxseSBzbyB0aGlzIG1ldGhvZCBzaG91bGQgbmV2ZXIKLSAgICAgKiBiZSBjYWxsZWQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RFRESGFuZGxlcihEVERIYW5kbGVyIGhhbmRsZXIpIHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiB7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBjbGFzcyBpcyBvbmx5IHVzZWQgaW50ZXJuYWxseSBzbyB0aGlzIG1ldGhvZCBzaG91bGQgbmV2ZXIKLSAgICAgKiBiZSBjYWxsZWQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RW50aXR5UmVzb2x2ZXIoRW50aXR5UmVzb2x2ZXIgcmVzb2x2ZXIpIHRocm93cwotICAgICAgICBOdWxsUG9pbnRlckV4Y2VwdGlvbgotICAgIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIGNsYXNzIGlzIG9ubHkgdXNlZCBpbnRlcm5hbGx5IHNvIHRoaXMgbWV0aG9kIHNob3VsZCBuZXZlcgotICAgICAqIGJlIGNhbGxlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgRW50aXR5UmVzb2x2ZXIgZ2V0RW50aXR5UmVzb2x2ZXIoKSB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgY2xhc3MgaXMgb25seSB1c2VkIGludGVybmFsbHkgc28gdGhpcyBtZXRob2Qgc2hvdWxkIG5ldmVyCi0gICAgICogYmUgY2FsbGVkLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEVycm9ySGFuZGxlcihFcnJvckhhbmRsZXIgaGFuZGxlcikgdGhyb3dzCi0gICAgICAgIE51bGxQb2ludGVyRXhjZXB0aW9uCi0gICAgewotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgY2xhc3MgaXMgb25seSB1c2VkIGludGVybmFsbHkgc28gdGhpcyBtZXRob2Qgc2hvdWxkIG5ldmVyCi0gICAgICogYmUgY2FsbGVkLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFByb3BlcnR5KFN0cmluZyBuYW1lLCBPYmplY3QgdmFsdWUpIHRocm93cwotICAgICAgICBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uLCBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gewotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgY2xhc3MgaXMgb25seSB1c2VkIGludGVybmFsbHkgc28gdGhpcyBtZXRob2Qgc2hvdWxkIG5ldmVyCi0gICAgICogYmUgY2FsbGVkLgotICAgICAqLwotICAgIHB1YmxpYyBPYmplY3QgZ2V0UHJvcGVydHkoU3RyaW5nIG5hbWUpIHRocm93cyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uLAotICAgICAgICBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgY2xhc3MgaXMgb25seSB1c2VkIGludGVybmFsbHkgc28gdGhpcyBtZXRob2Qgc2hvdWxkIG5ldmVyCi0gICAgICogYmUgY2FsbGVkLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0Q29sdW1uTnVtYmVyKCkgewotICAgICAgICByZXR1cm4gMDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIGNsYXNzIGlzIG9ubHkgdXNlZCBpbnRlcm5hbGx5IHNvIHRoaXMgbWV0aG9kIHNob3VsZCBuZXZlcgotICAgICAqIGJlIGNhbGxlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldExpbmVOdW1iZXIoKSB7Ci0gICAgICAgIHJldHVybiAwOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgY2xhc3MgaXMgb25seSB1c2VkIGludGVybmFsbHkgc28gdGhpcyBtZXRob2Qgc2hvdWxkIG5ldmVyCi0gICAgICogYmUgY2FsbGVkLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0UHVibGljSWQoKSB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgY2xhc3MgaXMgb25seSB1c2VkIGludGVybmFsbHkgc28gdGhpcyBtZXRob2Qgc2hvdWxkIG5ldmVyCi0gICAgICogYmUgY2FsbGVkLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3lzdGVtSWQoKSB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvdHJheC9TdEFYU3RyZWFtMlNBWC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy90cmF4L1N0QVhTdHJlYW0yU0FYLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDMxOGI0ZDkuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy90cmF4L1N0QVhTdHJlYW0yU0FYLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw1MzMgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMudHJheDsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5kb20uU0FYSW1wbDsKLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotaW1wb3J0IGphdmF4LnhtbC5uYW1lc3BhY2UuUU5hbWU7Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5YTUxTdHJlYW1Db25zdGFudHM7Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5YTUxTdHJlYW1FeGNlcHRpb247Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5YTUxTdHJlYW1SZWFkZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguQXR0cmlidXRlczsKLWltcG9ydCBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5EVERIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LkVudGl0eVJlc29sdmVyOwotaW1wb3J0IG9yZy54bWwuc2F4LkVycm9ySGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKLWltcG9ydCBvcmcueG1sLnNheC5Mb2NhdG9yOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5YTUxSZWFkZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguZXh0LkxleGljYWxIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LmV4dC5Mb2NhdG9yMjsKLWltcG9ydCBvcmcueG1sLnNheC5oZWxwZXJzLkF0dHJpYnV0ZXNJbXBsOwotCi0KLQotLyoqCi0gKiBAYXV0aG9yIFBhZG1hamEgVmVkdWxhCi0gKiBAYXV0aG9yIFN1bml0aGEgUmVkZHkKLSAqLwotcHVibGljIGNsYXNzIFN0QVhTdHJlYW0yU0FYIGltcGxlbWVudHMgWE1MUmVhZGVyLCBMb2NhdG9yIHsKLQotICAgIC8vcHJpdmF0ZSBmaW5hbCBzdGF0aWMgU3RyaW5nIEVNUFRZU1RSSU5HID0gIiI7Ci0gICAgLy9wcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MTlNfUFJFRklYID0gInhtbG5zIjsKLQotICAgIC8vIFN0QVggU3RyZWFtIHNvdXJjZQotICAgIHByaXZhdGUgZmluYWwgWE1MU3RyZWFtUmVhZGVyIHN0YXhTdHJlYW1SZWFkZXI7Ci0KLSAgICAvL3ByaXZhdGUgTm9kZSBfZG9tID0gbnVsbDsKLSAgICBwcml2YXRlIENvbnRlbnRIYW5kbGVyIF9zYXggPSBudWxsOwotICAgIHByaXZhdGUgTGV4aWNhbEhhbmRsZXIgX2xleCA9IG51bGw7Ci0gICAgcHJpdmF0ZSBTQVhJbXBsIF9zYXhJbXBsID0gbnVsbDsKLQotICAgIHB1YmxpYyBTdEFYU3RyZWFtMlNBWChYTUxTdHJlYW1SZWFkZXIgc3RheFNyYykgewotICAgICAgICAgICAgc3RheFN0cmVhbVJlYWRlciA9IHN0YXhTcmM7Ci0gICAgfQotCi0gICAgcHVibGljIENvbnRlbnRIYW5kbGVyIGdldENvbnRlbnRIYW5kbGVyKCkgewotICAgICAgICByZXR1cm4gX3NheDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRDb250ZW50SGFuZGxlcihDb250ZW50SGFuZGxlciBoYW5kbGVyKSB0aHJvd3MKLSAgICAgICAgTnVsbFBvaW50ZXJFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIF9zYXggPSBoYW5kbGVyOwotICAgICAgICBpZiAoaGFuZGxlciBpbnN0YW5jZW9mIExleGljYWxIYW5kbGVyKSB7Ci0gICAgICAgICAgICBfbGV4ID0gKExleGljYWxIYW5kbGVyKSBoYW5kbGVyOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKGhhbmRsZXIgaW5zdGFuY2VvZiBTQVhJbXBsKSB7Ci0gICAgICAgICAgICBfc2F4SW1wbCA9IChTQVhJbXBsKWhhbmRsZXI7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIHB1YmxpYyB2b2lkIHBhcnNlKElucHV0U291cmNlIHVudXNlZCkgdGhyb3dzIElPRXhjZXB0aW9uLCBTQVhFeGNlcHRpb24gewotICAgICAgICB0cnkgewotICAgICAgICAgICAgYnJpZGdlKCk7Ci0gICAgICAgIH0gY2F0Y2ggKFhNTFN0cmVhbUV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKGUpOwotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICAvL01haW4gV29yayBTdGFydHMgSGVyZS4KLSAgICBwdWJsaWMgdm9pZCBwYXJzZSgpIHRocm93cyBJT0V4Y2VwdGlvbiwgU0FYRXhjZXB0aW9uLCBYTUxTdHJlYW1FeGNlcHRpb24gewotICAgICAgICBicmlkZ2UoKTsKLSAgICB9Ci0KLQotICAgLyoqCi0gICAgICogVGhpcyBjbGFzcyBpcyBvbmx5IHVzZWQgaW50ZXJuYWxseSBzbyB0aGlzIG1ldGhvZCBzaG91bGQgbmV2ZXIKLSAgICAgKiBiZSBjYWxsZWQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcGFyc2UoU3RyaW5nIHN5c0lkKSB0aHJvd3MgSU9FeGNlcHRpb24sIFNBWEV4Y2VwdGlvbiB7Ci0gICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiVGhpcyBtZXRob2QgaXMgbm90IHlldCBpbXBsZW1lbnRlZC4iKTsKLSAgICB9Ci0KLQotICAgcHVibGljIHZvaWQgYnJpZGdlKCkgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIC8vIHJlbWVtYmVycyB0aGUgbmVzdCBsZXZlbCBvZiBlbGVtZW50cyB0byBrbm93IHdoZW4gd2UgYXJlIGRvbmUuCi0gICAgICAgICAgICBpbnQgZGVwdGg9MDsKLQotICAgICAgICAgICAgLy8gc2tpcCBvdmVyIFNUQVJUX0RPQ1VNRU5UCi0gICAgICAgICAgICBpbnQgZXZlbnQgPSBzdGF4U3RyZWFtUmVhZGVyLmdldEV2ZW50VHlwZSgpOwotICAgICAgICAgICAgaWYgKGV2ZW50ID09IFhNTFN0cmVhbUNvbnN0YW50cy5TVEFSVF9ET0NVTUVOVCkgewotICAgICAgICAgICAgICAgIGV2ZW50ID0gc3RheFN0cmVhbVJlYWRlci5uZXh0KCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIElmIG5vdCBhIFNUQVJUX0VMRU1FTlQgKGUuZy4sIGEgRFREKSwgc2tpcCB0byBuZXh0IHRhZwotICAgICAgICAgICAgaWYgKGV2ZW50ICE9IFhNTFN0cmVhbUNvbnN0YW50cy5TVEFSVF9FTEVNRU5UKSB7Ci0gICAgICAgICAgICAgICAgZXZlbnQgPSBzdGF4U3RyZWFtUmVhZGVyLm5leHRUYWcoKTsKLSAgICAgICAgICAgICAgICAvLyBBbiBlcnJvciBpZiBhIFNUQVJUX0VMRU1FTlQgaXNuJ3QgZm91bmQgbm93Ci0gICAgICAgICAgICAgICAgaWYgKGV2ZW50ICE9IFhNTFN0cmVhbUNvbnN0YW50cy5TVEFSVF9FTEVNRU5UKSB7Ci0gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oIlRoZSBjdXJyZW50IGV2ZW50IGlzICIgKwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICJub3QgU1RBUlRfRUxFTUVOVFxuIGJ1dCIgKyBldmVudCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBoYW5kbGVTdGFydERvY3VtZW50KCk7Ci0KLSAgICAgICAgICAgIGRvIHsKLSAgICAgICAgICAgICAgICAvLyBUaGVzZSBhcmUgYWxsIG9mIHRoZSBldmVudHMgbGlzdGVkIGluIHRoZSBqYXZhZG9jIGZvcgotICAgICAgICAgICAgICAgIC8vIFhNTEV2ZW50LgotICAgICAgICAgICAgICAgIC8vIFRoZSBzcGVjIG9ubHkgcmVhbGx5IGRlc2NyaWJlcyAxMSBvZiB0aGVtLgotICAgICAgICAgICAgICAgIHN3aXRjaCAoZXZlbnQpIHsKLSAgICAgICAgICAgICAgICAgICAgY2FzZSBYTUxTdHJlYW1Db25zdGFudHMuU1RBUlRfRUxFTUVOVCA6Ci0gICAgICAgICAgICAgICAgICAgICAgICBkZXB0aCsrOwotICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlU3RhcnRFbGVtZW50KCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgY2FzZSBYTUxTdHJlYW1Db25zdGFudHMuRU5EX0VMRU1FTlQgOgotICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlRW5kRWxlbWVudCgpOwotICAgICAgICAgICAgICAgICAgICAgICAgZGVwdGgtLTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICBjYXNlIFhNTFN0cmVhbUNvbnN0YW50cy5DSEFSQUNURVJTIDoKLSAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZUNoYXJhY3RlcnMoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICBjYXNlIFhNTFN0cmVhbUNvbnN0YW50cy5FTlRJVFlfUkVGRVJFTkNFIDoKLSAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZUVudGl0eVJlZmVyZW5jZSgpOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgWE1MU3RyZWFtQ29uc3RhbnRzLlBST0NFU1NJTkdfSU5TVFJVQ1RJT04gOgotICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlUEkoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICBjYXNlIFhNTFN0cmVhbUNvbnN0YW50cy5DT01NRU5UIDoKLSAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZUNvbW1lbnQoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICBjYXNlIFhNTFN0cmVhbUNvbnN0YW50cy5EVEQgOgotICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlRFREKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgY2FzZSBYTUxTdHJlYW1Db25zdGFudHMuQVRUUklCVVRFIDoKLSAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZUF0dHJpYnV0ZSgpOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgWE1MU3RyZWFtQ29uc3RhbnRzLk5BTUVTUEFDRSA6Ci0gICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVOYW1lc3BhY2UoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICBjYXNlIFhNTFN0cmVhbUNvbnN0YW50cy5DREFUQSA6Ci0gICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVDREFUQSgpOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgWE1MU3RyZWFtQ29uc3RhbnRzLkVOVElUWV9ERUNMQVJBVElPTiA6Ci0gICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVFbnRpdHlEZWNsKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgY2FzZSBYTUxTdHJlYW1Db25zdGFudHMuTk9UQVRJT05fREVDTEFSQVRJT04gOgotICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlTm90YXRpb25EZWNsKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgY2FzZSBYTUxTdHJlYW1Db25zdGFudHMuU1BBQ0UgOgotICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlU3BhY2UoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICBkZWZhdWx0IDoKLSAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKCJwcm9jZXNzaW5nIGV2ZW50OiAiICsgZXZlbnQpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIGV2ZW50PXN0YXhTdHJlYW1SZWFkZXIubmV4dCgpOwotICAgICAgICAgICAgfSB3aGlsZSAoZGVwdGghPTApOwotCi0gICAgICAgICAgICBoYW5kbGVFbmREb2N1bWVudCgpOwotICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFhNTFN0cmVhbUV4Y2VwdGlvbihlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBoYW5kbGVFbmREb2N1bWVudCgpIHRocm93cyBTQVhFeGNlcHRpb24gewotICAgICAgICBfc2F4LmVuZERvY3VtZW50KCk7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIGhhbmRsZVN0YXJ0RG9jdW1lbnQoKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICAgICAgX3NheC5zZXREb2N1bWVudExvY2F0b3IobmV3IExvY2F0b3IyKCkgewotICAgICAgICAgICAgcHVibGljIGludCBnZXRDb2x1bW5OdW1iZXIoKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHN0YXhTdHJlYW1SZWFkZXIuZ2V0TG9jYXRpb24oKS5nZXRDb2x1bW5OdW1iZXIoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHB1YmxpYyBpbnQgZ2V0TGluZU51bWJlcigpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gc3RheFN0cmVhbVJlYWRlci5nZXRMb2NhdGlvbigpLmdldExpbmVOdW1iZXIoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0UHVibGljSWQoKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHN0YXhTdHJlYW1SZWFkZXIuZ2V0TG9jYXRpb24oKS5nZXRQdWJsaWNJZCgpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcHVibGljIFN0cmluZyBnZXRTeXN0ZW1JZCgpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gc3RheFN0cmVhbVJlYWRlci5nZXRMb2NhdGlvbigpLmdldFN5c3RlbUlkKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFhNTFZlcnNpb24oKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHN0YXhTdHJlYW1SZWFkZXIuZ2V0VmVyc2lvbigpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcHVibGljIFN0cmluZyBnZXRFbmNvZGluZygpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gc3RheFN0cmVhbVJlYWRlci5nZXRFbmNvZGluZygpOwotICAgICAgICAgICAgfQotICAgICAgICAgfSk7Ci0gICAgICAgIF9zYXguc3RhcnREb2N1bWVudCgpOwotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBoYW5kbGVQSSgpIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24gewotICAgICAgICB0cnkgewotICAgICAgICAgICAgX3NheC5wcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oCi0gICAgICAgICAgICAgICAgc3RheFN0cmVhbVJlYWRlci5nZXRQSVRhcmdldCgpLAotICAgICAgICAgICAgICAgIHN0YXhTdHJlYW1SZWFkZXIuZ2V0UElEYXRhKCkpOwotICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFhNTFN0cmVhbUV4Y2VwdGlvbihlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBoYW5kbGVDaGFyYWN0ZXJzKCkgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy8gd29ya2Fyb3VuZCBmb3IgYnVnaWQgNTA0NjMxOSAtIHN3aXRjaCBvdmVyIHRvIGNvbW1lbnRlZCBzZWN0aW9uCi0gICAgICAgIC8vIGJlbG93IHdoZW4gaXQgaXMgZml4ZWQuCi0gICAgICAgIGludCB0ZXh0TGVuZ3RoID0gc3RheFN0cmVhbVJlYWRlci5nZXRUZXh0TGVuZ3RoKCk7Ci0gICAgICAgIGNoYXJbXSBjaGFycyA9IG5ldyBjaGFyW3RleHRMZW5ndGhdOwotCi0gICAgICAgIHN0YXhTdHJlYW1SZWFkZXIuZ2V0VGV4dENoYXJhY3RlcnMoMCwgY2hhcnMsIDAsIHRleHRMZW5ndGgpOwotCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBfc2F4LmNoYXJhY3RlcnMoY2hhcnMsIDAsIGNoYXJzLmxlbmd0aCk7Ci0gICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWE1MU3RyZWFtRXhjZXB0aW9uKGUpOwotICAgICAgICB9Ci0KLQotLy8gICAgICAgIGludCBzdGFydCA9IDA7Ci0vLyAgICAgICAgaW50IGxlbjsKLS8vICAgICAgICBkbyB7Ci0vLyAgICAgICAgICAgIGxlbiA9IHN0YXhTdHJlYW1SZWFkZXIuZ2V0VGV4dENoYXJhY3RlcnMoc3RhcnQsIGJ1ZiwgMCwgYnVmLmxlbmd0aCk7Ci0vLyAgICAgICAgICAgIHN0YXJ0ICs9IGxlbjsKLS8vICAgICAgICAgICAgdHJ5IHsKLS8vICAgICAgICAgICAgICAgIF9zYXguY2hhcmFjdGVycyhidWYsIDAsIGxlbik7Ci0vLyAgICAgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7Ci0vLyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWE1MU3RyZWFtRXhjZXB0aW9uKGUpOwotLy8gICAgICAgICAgICB9Ci0vLyAgICAgICAgfSB3aGlsZSAobGVuID09IGJ1Zi5sZW5ndGgpOwotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBoYW5kbGVFbmRFbGVtZW50KCkgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbiB7Ci0gICAgICAgIFFOYW1lIHFOYW1lID0gc3RheFN0cmVhbVJlYWRlci5nZXROYW1lKCk7Ci0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIC8vY29uc3RydWN0IHByZWZpeDpsb2NhbE5hbWUgZnJvbSBxTmFtZQotICAgICAgICAgICAgU3RyaW5nIHFuYW1lID0gIiI7Ci0gICAgICAgICAgICBpZiAocU5hbWUuZ2V0UHJlZml4KCkgIT0gbnVsbCAmJiBxTmFtZS5nZXRQcmVmaXgoKS50cmltKCkubGVuZ3RoKCkgIT0gMCl7Ci0gICAgICAgICAgICAgICAgcW5hbWUgPSBxTmFtZS5nZXRQcmVmaXgoKSArICI6IjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHFuYW1lICs9IHFOYW1lLmdldExvY2FsUGFydCgpOwotCi0gICAgICAgICAgICAvLyBmaXJlIGVuZEVsZW1lbnQKLSAgICAgICAgICAgIF9zYXguZW5kRWxlbWVudCgKLSAgICAgICAgICAgICAgICBxTmFtZS5nZXROYW1lc3BhY2VVUkkoKSwKLSAgICAgICAgICAgICAgICBxTmFtZS5nZXRMb2NhbFBhcnQoKSwKLSAgICAgICAgICAgICAgICBxbmFtZSk7Ci0KLSAgICAgICAgICAgIC8vIGVuZCBuYW1lc3BhY2UgYmluZGluZ3MKLSAgICAgICAgICAgIGludCBuc0NvdW50ID0gc3RheFN0cmVhbVJlYWRlci5nZXROYW1lc3BhY2VDb3VudCgpOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IG5zQ291bnQgLSAxOyBpID49IDA7IGktLSkgewotICAgICAgICAgICAgICAgIFN0cmluZyBwcmVmaXggPSBzdGF4U3RyZWFtUmVhZGVyLmdldE5hbWVzcGFjZVByZWZpeChpKTsKLSAgICAgICAgICAgICAgICBpZiAocHJlZml4ID09IG51bGwpIHsgLy8gdHJ1ZSBmb3IgZGVmYXVsdCBuYW1lc3BhY2UKLSAgICAgICAgICAgICAgICAgICAgcHJlZml4ID0gIiI7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIF9zYXguZW5kUHJlZml4TWFwcGluZyhwcmVmaXgpOwotICAgICAgICAgICAgfQotICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFhNTFN0cmVhbUV4Y2VwdGlvbihlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBoYW5kbGVTdGFydEVsZW1lbnQoKSB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uIHsKLQotICAgICAgICB0cnkgewotICAgICAgICAgICAgLy8gc3RhcnQgbmFtZXNwYWNlIGJpbmRpbmdzCi0gICAgICAgICAgICBpbnQgbnNDb3VudCA9IHN0YXhTdHJlYW1SZWFkZXIuZ2V0TmFtZXNwYWNlQ291bnQoKTsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnNDb3VudDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIHByZWZpeCA9IHN0YXhTdHJlYW1SZWFkZXIuZ2V0TmFtZXNwYWNlUHJlZml4KGkpOwotICAgICAgICAgICAgICAgIGlmIChwcmVmaXggPT0gbnVsbCkgeyAvLyB0cnVlIGZvciBkZWZhdWx0IG5hbWVzcGFjZQotICAgICAgICAgICAgICAgICAgICBwcmVmaXggPSAiIjsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgX3NheC5zdGFydFByZWZpeE1hcHBpbmcoCi0gICAgICAgICAgICAgICAgICAgIHByZWZpeCwKLSAgICAgICAgICAgICAgICAgICAgc3RheFN0cmVhbVJlYWRlci5nZXROYW1lc3BhY2VVUkkoaSkpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBmaXJlIHN0YXJ0RWxlbWVudAotICAgICAgICAgICAgUU5hbWUgcU5hbWUgPSBzdGF4U3RyZWFtUmVhZGVyLmdldE5hbWUoKTsKLSAgICAgICAgICAgIFN0cmluZyBwcmVmaXggPSBxTmFtZS5nZXRQcmVmaXgoKTsKLSAgICAgICAgICAgIFN0cmluZyByYXduYW1lOwotICAgICAgICAgICAgaWYocHJlZml4PT1udWxsIHx8IHByZWZpeC5sZW5ndGgoKT09MCkKLSAgICAgICAgICAgICAgICByYXduYW1lID0gcU5hbWUuZ2V0TG9jYWxQYXJ0KCk7Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgcmF3bmFtZSA9IHByZWZpeCArICc6JyArIHFOYW1lLmdldExvY2FsUGFydCgpOwotICAgICAgICAgICAgQXR0cmlidXRlcyBhdHRycyA9IGdldEF0dHJpYnV0ZXMoKTsKLSAgICAgICAgICAgIF9zYXguc3RhcnRFbGVtZW50KAotICAgICAgICAgICAgICAgIHFOYW1lLmdldE5hbWVzcGFjZVVSSSgpLAotICAgICAgICAgICAgICAgIHFOYW1lLmdldExvY2FsUGFydCgpLAotICAgICAgICAgICAgICAgIHJhd25hbWUsCi0gICAgICAgICAgICAgICAgYXR0cnMpOwotICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFhNTFN0cmVhbUV4Y2VwdGlvbihlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgYXR0cmlidXRlcyBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIFNUQVJUX0VMRU1FTlQgb3IgQVRUUklCVVRFCi0gICAgICogU3RBWGV2ZW50LgotICAgICAqCi0gICAgICogQHJldHVybiB0aGUgU3RBWCBhdHRyaWJ1dGVzIGNvbnZlcnRlZCB0byBhbiBvcmcueG1sLnNheC5BdHRyaWJ1dGVzCi0gICAgICovCi0gICAgcHJpdmF0ZSBBdHRyaWJ1dGVzIGdldEF0dHJpYnV0ZXMoKSB7Ci0gICAgICAgIEF0dHJpYnV0ZXNJbXBsIGF0dHJzID0gbmV3IEF0dHJpYnV0ZXNJbXBsKCk7Ci0KLSAgICAgICAgaW50IGV2ZW50VHlwZSA9IHN0YXhTdHJlYW1SZWFkZXIuZ2V0RXZlbnRUeXBlKCk7Ci0gICAgICAgIGlmIChldmVudFR5cGUgIT0gWE1MU3RyZWFtQ29uc3RhbnRzLkFUVFJJQlVURQotICAgICAgICAgICAgJiYgZXZlbnRUeXBlICE9IFhNTFN0cmVhbUNvbnN0YW50cy5TVEFSVF9FTEVNRU5UKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcigKLSAgICAgICAgICAgICAgICAiZ2V0QXR0cmlidXRlcygpIGF0dGVtcHRpbmcgdG8gcHJvY2VzczogIiArIGV2ZW50VHlwZSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBpbiBTQVgsIG5hbWVzcGFjZSBkZWNsYXJhdGlvbnMgYXJlIG5vdCBwYXJ0IG9mIGF0dHJpYnV0ZXMgYnkgZGVmYXVsdC4KLSAgICAgICAgLy8gKHRoZXJlJ3MgYSBwcm9wZXJ0eSB0byBjb250cm9sIHRoYXQsIGJ1dCBhcyBmYXIgYXMgd2UgYXJlIGNvbmNlcm5lZAotICAgICAgICAvLyB3ZSBkb24ndCB1c2UgaXQuKSBTbyBkb24ndCBhZGQgeG1sbnM6KiB0byBhdHRyaWJ1dGVzLgotCi0gICAgICAgIC8vIGdhdGhlciBub24tbmFtZXNwYWNlIGF0dHJzCi0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc3RheFN0cmVhbVJlYWRlci5nZXRBdHRyaWJ1dGVDb3VudCgpOyBpKyspIHsKLSAgICAgICAgICAgIFN0cmluZyB1cmkgPSBzdGF4U3RyZWFtUmVhZGVyLmdldEF0dHJpYnV0ZU5hbWVzcGFjZShpKTsKLSAgICAgICAgICAgIGlmKHVyaT09bnVsbCkgICB1cmk9IiI7Ci0gICAgICAgICAgICBTdHJpbmcgbG9jYWxOYW1lID0gc3RheFN0cmVhbVJlYWRlci5nZXRBdHRyaWJ1dGVMb2NhbE5hbWUoaSk7Ci0gICAgICAgICAgICBTdHJpbmcgcHJlZml4ID0gc3RheFN0cmVhbVJlYWRlci5nZXRBdHRyaWJ1dGVQcmVmaXgoaSk7Ci0gICAgICAgICAgICBTdHJpbmcgcU5hbWU7Ci0gICAgICAgICAgICBpZihwcmVmaXg9PW51bGwgfHwgcHJlZml4Lmxlbmd0aCgpPT0wKQotICAgICAgICAgICAgICAgIHFOYW1lID0gbG9jYWxOYW1lOwotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIHFOYW1lID0gcHJlZml4ICsgJzonICsgbG9jYWxOYW1lOwotICAgICAgICAgICAgU3RyaW5nIHR5cGUgPSBzdGF4U3RyZWFtUmVhZGVyLmdldEF0dHJpYnV0ZVR5cGUoaSk7Ci0gICAgICAgICAgICBTdHJpbmcgdmFsdWUgPSBzdGF4U3RyZWFtUmVhZGVyLmdldEF0dHJpYnV0ZVZhbHVlKGkpOwotCi0gICAgICAgICAgICBhdHRycy5hZGRBdHRyaWJ1dGUodXJpLCBsb2NhbE5hbWUsIHFOYW1lLCB0eXBlLCB2YWx1ZSk7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gYXR0cnM7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIGhhbmRsZU5hbWVzcGFjZSgpIHsKLSAgICAgICAgLy8gbm8tb3AgPz8/Ci0gICAgICAgIC8vIG5hbWVzcGFjZSBldmVudHMgZG9uJ3Qgbm9ybWFsbHkgb2NjdXIgb3V0c2lkZSBvZiBhIHN0YXJ0RWxlbWVudAotICAgICAgICAvLyBvciBlbmRFbGVtZW50Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIGhhbmRsZUF0dHJpYnV0ZSgpIHsKLSAgICAgICAgLy8gbm8tb3AgPz8/Ci0gICAgICAgIC8vIGF0dHJpYnV0ZSBldmVudHMgZG9uJ3Qgbm9ybWFsbHkgb2NjdXIgb3V0c2lkZSBvZiBhIHN0YXJ0RWxlbWVudAotICAgICAgICAvLyBvciBlbmRFbGVtZW50Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIGhhbmRsZURURCgpIHsKLSAgICAgICAgLy8gbm8tb3AgPz8/Ci0gICAgICAgIC8vIGl0IHNlZW1zIGxpa2Ugd2UgbmVlZCB0byBwYXNzIHRoaXMgaW5mbyBhbG9uZywgYnV0IGhvdz8KLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgaGFuZGxlQ29tbWVudCgpIHsKLSAgICAgICAgLy8gbm8tb3AgPz8/Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIGhhbmRsZUVudGl0eVJlZmVyZW5jZSgpIHsKLSAgICAgICAgLy8gbm8tb3AgPz8/Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIGhhbmRsZVNwYWNlKCkgewotICAgICAgICAvLyBuby1vcCA/Pz8KLSAgICAgICAgLy8gdGhpcyBldmVudCBpcyBsaXN0ZWQgaW4gdGhlIGphdmFkb2MsIGJ1dCBub3QgaW4gdGhlIHNwZWMuCi0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIGhhbmRsZU5vdGF0aW9uRGVjbCgpIHsKLSAgICAgICAgLy8gbm8tb3AgPz8/Ci0gICAgICAgIC8vIHRoaXMgZXZlbnQgaXMgbGlzdGVkIGluIHRoZSBqYXZhZG9jLCBidXQgbm90IGluIHRoZSBzcGVjLgotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBoYW5kbGVFbnRpdHlEZWNsKCkgewotICAgICAgICAvLyBuby1vcCA/Pz8KLSAgICAgICAgLy8gdGhpcyBldmVudCBpcyBsaXN0ZWQgaW4gdGhlIGphdmFkb2MsIGJ1dCBub3QgaW4gdGhlIHNwZWMuCi0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIGhhbmRsZUNEQVRBKCkgewotICAgICAgICAvLyBuby1vcCA/Pz8KLSAgICAgICAgLy8gdGhpcyBldmVudCBpcyBsaXN0ZWQgaW4gdGhlIGphdmFkb2MsIGJ1dCBub3QgaW4gdGhlIHNwZWMuCi0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBUaGlzIGNsYXNzIGlzIG9ubHkgdXNlZCBpbnRlcm5hbGx5IHNvIHRoaXMgbWV0aG9kIHNob3VsZCBuZXZlcgotICAgICAqIGJlIGNhbGxlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgRFRESGFuZGxlciBnZXREVERIYW5kbGVyKCkgewotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIGNsYXNzIGlzIG9ubHkgdXNlZCBpbnRlcm5hbGx5IHNvIHRoaXMgbWV0aG9kIHNob3VsZCBuZXZlcgotICAgICAqIGJlIGNhbGxlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgRXJyb3JIYW5kbGVyIGdldEVycm9ySGFuZGxlcigpIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBjbGFzcyBpcyBvbmx5IHVzZWQgaW50ZXJuYWxseSBzbyB0aGlzIG1ldGhvZCBzaG91bGQgbmV2ZXIKLSAgICAgKiBiZSBjYWxsZWQuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0RmVhdHVyZShTdHJpbmcgbmFtZSkgdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sCi0gICAgICAgIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgY2xhc3MgaXMgb25seSB1c2VkIGludGVybmFsbHkgc28gdGhpcyBtZXRob2Qgc2hvdWxkIG5ldmVyCi0gICAgICogYmUgY2FsbGVkLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEZlYXR1cmUoU3RyaW5nIG5hbWUsIGJvb2xlYW4gdmFsdWUpIHRocm93cwotICAgICAgICBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uLCBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24KLSAgICB7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBjbGFzcyBpcyBvbmx5IHVzZWQgaW50ZXJuYWxseSBzbyB0aGlzIG1ldGhvZCBzaG91bGQgbmV2ZXIKLSAgICAgKiBiZSBjYWxsZWQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RFRESGFuZGxlcihEVERIYW5kbGVyIGhhbmRsZXIpIHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiB7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBjbGFzcyBpcyBvbmx5IHVzZWQgaW50ZXJuYWxseSBzbyB0aGlzIG1ldGhvZCBzaG91bGQgbmV2ZXIKLSAgICAgKiBiZSBjYWxsZWQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RW50aXR5UmVzb2x2ZXIoRW50aXR5UmVzb2x2ZXIgcmVzb2x2ZXIpIHRocm93cwotICAgICAgICBOdWxsUG9pbnRlckV4Y2VwdGlvbgotICAgIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIGNsYXNzIGlzIG9ubHkgdXNlZCBpbnRlcm5hbGx5IHNvIHRoaXMgbWV0aG9kIHNob3VsZCBuZXZlcgotICAgICAqIGJlIGNhbGxlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgRW50aXR5UmVzb2x2ZXIgZ2V0RW50aXR5UmVzb2x2ZXIoKSB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgY2xhc3MgaXMgb25seSB1c2VkIGludGVybmFsbHkgc28gdGhpcyBtZXRob2Qgc2hvdWxkIG5ldmVyCi0gICAgICogYmUgY2FsbGVkLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEVycm9ySGFuZGxlcihFcnJvckhhbmRsZXIgaGFuZGxlcikgdGhyb3dzCi0gICAgICAgIE51bGxQb2ludGVyRXhjZXB0aW9uCi0gICAgewotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgY2xhc3MgaXMgb25seSB1c2VkIGludGVybmFsbHkgc28gdGhpcyBtZXRob2Qgc2hvdWxkIG5ldmVyCi0gICAgICogYmUgY2FsbGVkLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFByb3BlcnR5KFN0cmluZyBuYW1lLCBPYmplY3QgdmFsdWUpIHRocm93cwotICAgICAgICBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uLCBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gewotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgY2xhc3MgaXMgb25seSB1c2VkIGludGVybmFsbHkgc28gdGhpcyBtZXRob2Qgc2hvdWxkIG5ldmVyCi0gICAgICogYmUgY2FsbGVkLgotICAgICAqLwotICAgIHB1YmxpYyBPYmplY3QgZ2V0UHJvcGVydHkoU3RyaW5nIG5hbWUpIHRocm93cyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uLAotICAgICAgICBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgY2xhc3MgaXMgb25seSB1c2VkIGludGVybmFsbHkgc28gdGhpcyBtZXRob2Qgc2hvdWxkIG5ldmVyCi0gICAgICogYmUgY2FsbGVkLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0Q29sdW1uTnVtYmVyKCkgewotICAgICAgICByZXR1cm4gMDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIGNsYXNzIGlzIG9ubHkgdXNlZCBpbnRlcm5hbGx5IHNvIHRoaXMgbWV0aG9kIHNob3VsZCBuZXZlcgotICAgICAqIGJlIGNhbGxlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldExpbmVOdW1iZXIoKSB7Ci0gICAgICAgIHJldHVybiAwOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgY2xhc3MgaXMgb25seSB1c2VkIGludGVybmFsbHkgc28gdGhpcyBtZXRob2Qgc2hvdWxkIG5ldmVyCi0gICAgICogYmUgY2FsbGVkLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0UHVibGljSWQoKSB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgY2xhc3MgaXMgb25seSB1c2VkIGludGVybmFsbHkgc28gdGhpcyBtZXRob2Qgc2hvdWxkIG5ldmVyCi0gICAgICogYmUgY2FsbGVkLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3lzdGVtSWQoKSB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy90cmF4L1RlbXBsYXRlc0hhbmRsZXJJbXBsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3RyYXgvVGVtcGxhdGVzSGFuZGxlckltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYmNlMmMzYS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3RyYXgvVGVtcGxhdGVzSGFuZGxlckltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDM0NyArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDA3LCAyMDE2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICovCi0vKgotICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCi0gKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKLSAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KLSAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCi0gKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAotICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMudHJheDsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC5YYWxhbkNvbnN0YW50czsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIuQ29tcGlsZXJFeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLlBhcnNlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIuU291cmNlTG9hZGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci5TdHlsZXNoZWV0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci5TeW50YXhUcmVlTm9kZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIuWFNMVEM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuRXJyb3JNc2c7Ci1pbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKLWltcG9ydCBqYXZheC54bWwuWE1MQ29uc3RhbnRzOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uU291cmNlOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVGVtcGxhdGVzOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5VUklSZXNvbHZlcjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnNheC5UZW1wbGF0ZXNIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LklucHV0U291cmNlOwotaW1wb3J0IG9yZy54bWwuc2F4LkxvY2F0b3I7Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LkF0dHJpYnV0ZXM7Ci0KLS8qKgotICogSW1wbGVtZW50YXRpb24gb2YgYSBKQVhQMS4xIFRlbXBsYXRlc0hhbmRsZXIKLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKi8KLXB1YmxpYyBjbGFzcyBUZW1wbGF0ZXNIYW5kbGVySW1wbAotICAgIGltcGxlbWVudHMgQ29udGVudEhhbmRsZXIsIFRlbXBsYXRlc0hhbmRsZXIsIFNvdXJjZUxvYWRlcgotewotICAgIC8qKgotICAgICAqIFN5c3RlbSBJRCBmb3IgdGhpcyBzdHlsZXNoZWV0LgotICAgICAqLwotICAgIHByaXZhdGUgU3RyaW5nIF9zeXN0ZW1JZDsKLQotICAgIC8qKgotICAgICAqIE51bWJlciBvZiBzcGFjZXMgdG8gYWRkIGZvciBvdXRwdXQgaW5kZW50YXRpb24uCi0gICAgICovCi0gICAgcHJpdmF0ZSBpbnQgX2luZGVudE51bWJlcjsKLQotICAgIC8qKgotICAgICAqIFRoaXMgVVJJUmVzb2x2ZXIgaXMgcGFzc2VkIHRvIGFsbCBUcmFuc2Zvcm1lcnMuCi0gICAgICovCi0gICAgcHJpdmF0ZSBVUklSZXNvbHZlciBfdXJpUmVzb2x2ZXIgPSBudWxsOwotCi0gICAgLyoqCi0gICAgICogQSByZWZlcmVuY2UgdG8gdGhlIHRyYW5zZm9ybWVyIGZhY3RvcnkgdGhhdCB0aGlzIHRlbXBsYXRlcwotICAgICAqIG9iamVjdCBiZWxvbmdzIHRvLgotICAgICAqLwotICAgIHByaXZhdGUgVHJhbnNmb3JtZXJGYWN0b3J5SW1wbCBfdGZhY3RvcnkgPSBudWxsOwotCi0gICAgLyoqCi0gICAgICogQSByZWZlcmVuY2UgdG8gWFNMVEMncyBwYXJzZXIgb2JqZWN0LgotICAgICAqLwotICAgIHByaXZhdGUgUGFyc2VyIF9wYXJzZXIgPSBudWxsOwotCi0gICAgLyoqCi0gICAgICogVGhlIGNyZWF0ZWQgVGVtcGxhdGVzIG9iamVjdC4KLSAgICAgKi8KLSAgICBwcml2YXRlIFRlbXBsYXRlc0ltcGwgX3RlbXBsYXRlcyA9IG51bGw7Ci0KLSAgICAvKioKLSAgICAgKiBEZWZhdWx0IGNvbnN0cnVjdG9yCi0gICAgICovCi0gICAgcHJvdGVjdGVkIFRlbXBsYXRlc0hhbmRsZXJJbXBsKGludCBpbmRlbnROdW1iZXIsCi0gICAgICAgIFRyYW5zZm9ybWVyRmFjdG9yeUltcGwgdGZhY3RvcnkpCi0gICAgewotICAgICAgICBfaW5kZW50TnVtYmVyID0gaW5kZW50TnVtYmVyOwotICAgICAgICBfdGZhY3RvcnkgPSB0ZmFjdG9yeTsKLQotICAgICAgICAvLyBJbnN0YW50aWF0ZSBYU0xUQyBhbmQgZ2V0IHJlZmVyZW5jZSB0byBwYXJzZXIgb2JqZWN0Ci0gICAgICAgIFhTTFRDIHhzbHRjID0gbmV3IFhTTFRDKHRmYWN0b3J5LnVzZVNlcnZpY2VzTWVjaG5pc20oKSwgdGZhY3RvcnkuZ2V0RmVhdHVyZU1hbmFnZXIoKSk7Ci0gICAgICAgIGlmICh0ZmFjdG9yeS5nZXRGZWF0dXJlKFhNTENvbnN0YW50cy5GRUFUVVJFX1NFQ1VSRV9QUk9DRVNTSU5HKSkKLSAgICAgICAgICAgIHhzbHRjLnNldFNlY3VyZVByb2Nlc3NpbmcodHJ1ZSk7Ci0KLSAgICAgICAgeHNsdGMuc2V0UHJvcGVydHkoWE1MQ29uc3RhbnRzLkFDQ0VTU19FWFRFUk5BTF9TVFlMRVNIRUVULAotICAgICAgICAgICAgICAgIChTdHJpbmcpdGZhY3RvcnkuZ2V0QXR0cmlidXRlKFhNTENvbnN0YW50cy5BQ0NFU1NfRVhURVJOQUxfU1RZTEVTSEVFVCkpOwotICAgICAgICB4c2x0Yy5zZXRQcm9wZXJ0eShYTUxDb25zdGFudHMuQUNDRVNTX0VYVEVSTkFMX0RURCwKLSAgICAgICAgICAgICAgICAoU3RyaW5nKXRmYWN0b3J5LmdldEF0dHJpYnV0ZShYTUxDb25zdGFudHMuQUNDRVNTX0VYVEVSTkFMX0RURCkpOwotICAgICAgICB4c2x0Yy5zZXRQcm9wZXJ0eShYYWxhbkNvbnN0YW50cy5TRUNVUklUWV9NQU5BR0VSLAotICAgICAgICAgICAgICAgIHRmYWN0b3J5LmdldEF0dHJpYnV0ZShYYWxhbkNvbnN0YW50cy5TRUNVUklUWV9NQU5BR0VSKSk7Ci0KLQotICAgICAgICBpZiAoInRydWUiLmVxdWFscyh0ZmFjdG9yeS5nZXRBdHRyaWJ1dGUoVHJhbnNmb3JtZXJGYWN0b3J5SW1wbC5FTkFCTEVfSU5MSU5JTkcpKSkKLSAgICAgICAgICAgIHhzbHRjLnNldFRlbXBsYXRlSW5saW5pbmcodHJ1ZSk7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICAgIHhzbHRjLnNldFRlbXBsYXRlSW5saW5pbmcoZmFsc2UpOwotCi0gICAgICAgIF9wYXJzZXIgPSB4c2x0Yy5nZXRQYXJzZXIoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJbXBsZW1lbnRzIGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlRlbXBsYXRlc0hhbmRsZXIuZ2V0U3lzdGVtSWQoKQotICAgICAqIEdldCB0aGUgYmFzZSBJRCAoVVJJIG9yIHN5c3RlbSBJRCkgZnJvbSB3aGVyZSByZWxhdGl2ZSBVUkxzIHdpbGwgYmUKLSAgICAgKiByZXNvbHZlZC4KLSAgICAgKiBAcmV0dXJuIFRoZSBzeXN0ZW1JRCB0aGF0IHdhcyBzZXQgd2l0aCBzZXRTeXN0ZW1JZChTdHJpbmcgaWQpCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRTeXN0ZW1JZCgpIHsKLSAgICAgICAgcmV0dXJuIF9zeXN0ZW1JZDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJbXBsZW1lbnRzIGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlRlbXBsYXRlc0hhbmRsZXIuc2V0U3lzdGVtSWQoKQotICAgICAqIEdldCB0aGUgYmFzZSBJRCAoVVJJIG9yIHN5c3RlbSBJRCkgZnJvbSB3aGVyZSByZWxhdGl2ZSBVUkxzIHdpbGwgYmUKLSAgICAgKiByZXNvbHZlZC4KLSAgICAgKiBAcGFyYW0gaWQgQmFzZSBVUkkgZm9yIHRoaXMgc3R5bGVzaGVldAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFN5c3RlbUlkKFN0cmluZyBpZCkgewotICAgICAgICBfc3lzdGVtSWQgPSBpZDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTdG9yZSBVUklSZXNvbHZlciBuZWVkZWQgZm9yIFRyYW5zZm9ybWVycy4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRVUklSZXNvbHZlcihVUklSZXNvbHZlciByZXNvbHZlcikgewotICAgICAgICBfdXJpUmVzb2x2ZXIgPSByZXNvbHZlcjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJbXBsZW1lbnRzIGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlRlbXBsYXRlc0hhbmRsZXIuZ2V0VGVtcGxhdGVzKCkKLSAgICAgKiBXaGVuIGEgVGVtcGxhdGVzSGFuZGxlciBvYmplY3QgaXMgdXNlZCBhcyBhIENvbnRlbnRIYW5kbGVyIG9yCi0gICAgICogRG9jdW1lbnRIYW5kbGVyIGZvciB0aGUgcGFyc2luZyBvZiB0cmFuc2Zvcm1hdGlvbiBpbnN0cnVjdGlvbnMsIGl0Ci0gICAgICogY3JlYXRlcyBhIFRlbXBsYXRlcyBvYmplY3QsIHdoaWNoIHRoZSBjYWxsZXIgY2FuIGdldCBvbmNlIHRoZSBTQVgKLSAgICAgKiBldmVudHMgaGF2ZSBiZWVuIGNvbXBsZXRlZC4KLSAgICAgKiBAcmV0dXJuIFRoZSBUZW1wbGF0ZXMgb2JqZWN0IHRoYXQgd2FzIGNyZWF0ZWQgZHVyaW5nIHRoZSBTQVggZXZlbnQKLSAgICAgKiAgICAgICAgIHByb2Nlc3MsIG9yIG51bGwgaWYgbm8gVGVtcGxhdGVzIG9iamVjdCBoYXMgYmVlbiBjcmVhdGVkLgotICAgICAqLwotICAgIHB1YmxpYyBUZW1wbGF0ZXMgZ2V0VGVtcGxhdGVzKCkgewotICAgICAgICByZXR1cm4gX3RlbXBsYXRlczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBpbXBsZW1lbnRzIFhTTFRDJ3MgU291cmNlTG9hZGVyIGludGVyZmFjZS4gSXQgaXMgdXNlZCB0bwotICAgICAqIGdsdWUgYSBUckFYIFVSSVJlc29sdmVyIHRvIHRoZSBYU0xUQyBjb21waWxlcidzIElucHV0IGFuZCBJbXBvcnQgY2xhc3Nlcy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBocmVmIFRoZSBVUkkgb2YgdGhlIGRvY3VtZW50IHRvIGxvYWQKLSAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgVVJJIG9mIHRoZSBjdXJyZW50bHkgbG9hZGVkIGRvY3VtZW50Ci0gICAgICogQHBhcmFtIHhzbHRjIFRoZSBjb21waWxlciB0aGF0IHJlc3Vlc3RzIHRoZSBkb2N1bWVudAotICAgICAqIEByZXR1cm4gQW4gSW5wdXRTb3VyY2Ugd2l0aCB0aGUgbG9hZGVkIGRvY3VtZW50Ci0gICAgICovCi0gICAgcHVibGljIElucHV0U291cmNlIGxvYWRTb3VyY2UoU3RyaW5nIGhyZWYsIFN0cmluZyBjb250ZXh0LCBYU0xUQyB4c2x0YykgewotICAgICAgICB0cnkgewotICAgICAgICAgICAgLy8gQSBfdXJpUmVzb2x2ZXIgbXVzdCBiZSBzZXQgaWYgdGhpcyBtZXRob2QgaXMgY2FsbGVkCi0gICAgICAgICAgICBmaW5hbCBTb3VyY2Ugc291cmNlID0gX3VyaVJlc29sdmVyLnJlc29sdmUoaHJlZiwgY29udGV4dCk7Ci0gICAgICAgICAgICBpZiAoc291cmNlICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gVXRpbC5nZXRJbnB1dFNvdXJjZSh4c2x0Yywgc291cmNlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoVHJhbnNmb3JtZXJFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgLy8gRmFsbHMgdGhyb3VnaAotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8vIC0tIENvbnRlbnRIYW5kbGVyIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0KLSAgICAvKioKLSAgICAgKiBSZS1pbml0aWFsaXplIHBhcnNlciBhbmQgZm9yd2FyZCBTQVgyIGV2ZW50LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RG9jdW1lbnQoKSB7Ci0gICAgICAgIFhTTFRDIHhzbHRjID0gX3BhcnNlci5nZXRYU0xUQygpOwotICAgICAgICB4c2x0Yy5pbml0KCk7ICAgLy8gY2FsbHMgX3BhcnNlci5pbml0KCkKLSAgICAgICAgeHNsdGMuc2V0T3V0cHV0VHlwZShYU0xUQy5CWVRFQVJSQVlfT1VUUFVUKTsKLSAgICAgICAgX3BhcnNlci5zdGFydERvY3VtZW50KCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSnVzdCBmb3J3YXJkIFNBWDIgZXZlbnQgdG8gcGFyc2VyIG9iamVjdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbmREb2N1bWVudCgpIHRocm93cyBTQVhFeGNlcHRpb24gewotICAgICAgICBfcGFyc2VyLmVuZERvY3VtZW50KCk7Ci0KLSAgICAgICAgLy8gY3JlYXRlIHRoZSB0ZW1wbGF0ZXMKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIFhTTFRDIHhzbHRjID0gX3BhcnNlci5nZXRYU0xUQygpOwotCi0gICAgICAgICAgICAvLyBTZXQgdGhlIHRyYW5zbGV0IGNsYXNzIG5hbWUgaWYgbm90IGFscmVhZHkgc2V0Ci0gICAgICAgICAgICBTdHJpbmcgdHJhbnNsZXROYW1lOwotICAgICAgICAgICAgaWYgKF9zeXN0ZW1JZCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgdHJhbnNsZXROYW1lID0gVXRpbC5iYXNlTmFtZShfc3lzdGVtSWQpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgdHJhbnNsZXROYW1lID0gKFN0cmluZylfdGZhY3RvcnkuZ2V0QXR0cmlidXRlKCJ0cmFuc2xldC1uYW1lIik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICB4c2x0Yy5zZXRDbGFzc05hbWUodHJhbnNsZXROYW1lKTsKLQotICAgICAgICAgICAgLy8gR2V0IGphdmEtbGVnYWwgY2xhc3MgbmFtZSBmcm9tIFhTTFRDIG1vZHVsZQotICAgICAgICAgICAgdHJhbnNsZXROYW1lID0geHNsdGMuZ2V0Q2xhc3NOYW1lKCk7Ci0KLSAgICAgICAgICAgIFN0eWxlc2hlZXQgc3R5bGVzaGVldCA9IG51bGw7Ci0gICAgICAgICAgICBTeW50YXhUcmVlTm9kZSByb290ID0gX3BhcnNlci5nZXREb2N1bWVudFJvb3QoKTsKLQotICAgICAgICAgICAgLy8gQ29tcGlsZSB0aGUgdHJhbnNsZXQgLSB0aGlzIGlzIHdoZXJlIHRoZSB3b3JrIGlzIGRvbmUhCi0gICAgICAgICAgICBpZiAoIV9wYXJzZXIuZXJyb3JzRm91bmQoKSAmJiByb290ICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAvLyBDcmVhdGUgYSBTdHlsZXNoZWV0IGVsZW1lbnQgZnJvbSB0aGUgcm9vdCBub2RlCi0gICAgICAgICAgICAgICAgc3R5bGVzaGVldCA9IF9wYXJzZXIubWFrZVN0eWxlc2hlZXQocm9vdCk7Ci0gICAgICAgICAgICAgICAgc3R5bGVzaGVldC5zZXRTeXN0ZW1JZChfc3lzdGVtSWQpOwotICAgICAgICAgICAgICAgIHN0eWxlc2hlZXQuc2V0UGFyZW50U3R5bGVzaGVldChudWxsKTsKLQotICAgICAgICAgICAgICAgIGlmICh4c2x0Yy5nZXRUZW1wbGF0ZUlubGluaW5nKCkpCi0gICAgICAgICAgICAgICAgICAgc3R5bGVzaGVldC5zZXRUZW1wbGF0ZUlubGluaW5nKHRydWUpOwotICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgICBzdHlsZXNoZWV0LnNldFRlbXBsYXRlSW5saW5pbmcoZmFsc2UpOwotCi0gICAgICAgICAgICAgICAgLy8gU2V0IGEgZG9jdW1lbnQgbG9hZGVyIChmb3IgeHNsOmluY2x1ZGUvaW1wb3J0KSBpZiBkZWZpbmVkCi0gICAgICAgICAgICAgICAgaWYgKF91cmlSZXNvbHZlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIHN0eWxlc2hlZXQuc2V0U291cmNlTG9hZGVyKHRoaXMpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIF9wYXJzZXIuc2V0Q3VycmVudFN0eWxlc2hlZXQoc3R5bGVzaGVldCk7Ci0KLSAgICAgICAgICAgICAgICAvLyBTZXQgaXQgYXMgdG9wLWxldmVsIGluIHRoZSBYU0xUQyBvYmplY3QKLSAgICAgICAgICAgICAgICB4c2x0Yy5zZXRTdHlsZXNoZWV0KHN0eWxlc2hlZXQpOwotCi0gICAgICAgICAgICAgICAgLy8gQ3JlYXRlIEFTVCB1bmRlciB0aGUgU3R5bGVzaGVldCBlbGVtZW50Ci0gICAgICAgICAgICAgICAgX3BhcnNlci5jcmVhdGVBU1Qoc3R5bGVzaGVldCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIEdlbmVyYXRlIHRoZSBieXRlY29kZXMgYW5kIG91dHB1dCB0aGUgdHJhbnNsZXQgY2xhc3MoZXMpCi0gICAgICAgICAgICBpZiAoIV9wYXJzZXIuZXJyb3JzRm91bmQoKSAmJiBzdHlsZXNoZWV0ICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBzdHlsZXNoZWV0LnNldE11bHRpRG9jdW1lbnQoeHNsdGMuaXNNdWx0aURvY3VtZW50KCkpOwotICAgICAgICAgICAgICAgIHN0eWxlc2hlZXQuc2V0SGFzSWRDYWxsKHhzbHRjLmhhc0lkQ2FsbCgpKTsKLQotICAgICAgICAgICAgICAgIC8vIENsYXNzIHN5bmNocm9uaXphdGlvbiBpcyBuZWVkZWQgZm9yIEJDRUwKLSAgICAgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKHhzbHRjLmdldENsYXNzKCkpIHsKLSAgICAgICAgICAgICAgICAgICAgc3R5bGVzaGVldC50cmFuc2xhdGUoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmICghX3BhcnNlci5lcnJvcnNGb3VuZCgpKSB7Ci0gICAgICAgICAgICAgICAgLy8gQ2hlY2sgdGhhdCB0aGUgdHJhbnNmb3JtYXRpb24gd2VudCB3ZWxsIGJlZm9yZSByZXR1cm5pbmcKLSAgICAgICAgICAgICAgICBmaW5hbCBieXRlW11bXSBieXRlY29kZXMgPSB4c2x0Yy5nZXRCeXRlY29kZXMoKTsKLSAgICAgICAgICAgICAgICBpZiAoYnl0ZWNvZGVzICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgX3RlbXBsYXRlcyA9Ci0gICAgICAgICAgICAgICAgICAgIG5ldyBUZW1wbGF0ZXNJbXBsKHhzbHRjLmdldEJ5dGVjb2RlcygpLCB0cmFuc2xldE5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICBfcGFyc2VyLmdldE91dHB1dFByb3BlcnRpZXMoKSwgX2luZGVudE51bWJlciwgX3RmYWN0b3J5KTsKLQotICAgICAgICAgICAgICAgICAgICAvLyBTZXQgVVJJUmVzb2x2ZXIgb24gdGVtcGxhdGVzIG9iamVjdAotICAgICAgICAgICAgICAgICAgICBpZiAoX3VyaVJlc29sdmVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIF90ZW1wbGF0ZXMuc2V0VVJJUmVzb2x2ZXIoX3VyaVJlc29sdmVyKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIFN0cmluZ0J1aWxkZXIgZXJyb3JNZXNzYWdlID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKLSAgICAgICAgICAgICAgICBBcnJheUxpc3Q8RXJyb3JNc2c+IGVycm9ycyA9IF9wYXJzZXIuZ2V0RXJyb3JzKCk7Ci0gICAgICAgICAgICAgICAgZmluYWwgaW50IGNvdW50ID0gZXJyb3JzLnNpemUoKTsKLSAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yTWVzc2FnZS5sZW5ndGgoKSA+IDApCi0gICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UuYXBwZW5kKCdcbicpOwotICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UuYXBwZW5kKGVycm9ycy5nZXQoaSkudG9TdHJpbmcoKSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oRXJyb3JNc2cuSkFYUF9DT01QSUxFX0VSUiwgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKGVycm9yTWVzc2FnZS50b1N0cmluZygpKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKENvbXBpbGVyRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oRXJyb3JNc2cuSkFYUF9DT01QSUxFX0VSUiwgZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBKdXN0IGZvcndhcmQgU0FYMiBldmVudCB0byBwYXJzZXIgb2JqZWN0LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0UHJlZml4TWFwcGluZyhTdHJpbmcgcHJlZml4LCBTdHJpbmcgdXJpKSB7Ci0gICAgICAgIF9wYXJzZXIuc3RhcnRQcmVmaXhNYXBwaW5nKHByZWZpeCwgdXJpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBKdXN0IGZvcndhcmQgU0FYMiBldmVudCB0byBwYXJzZXIgb2JqZWN0LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZFByZWZpeE1hcHBpbmcoU3RyaW5nIHByZWZpeCkgewotICAgICAgICBfcGFyc2VyLmVuZFByZWZpeE1hcHBpbmcocHJlZml4KTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBKdXN0IGZvcndhcmQgU0FYMiBldmVudCB0byBwYXJzZXIgb2JqZWN0LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudChTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxuYW1lLCBTdHJpbmcgcW5hbWUsCi0gICAgICAgIEF0dHJpYnV0ZXMgYXR0cmlidXRlcykgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgX3BhcnNlci5zdGFydEVsZW1lbnQodXJpLCBsb2NhbG5hbWUsIHFuYW1lLCBhdHRyaWJ1dGVzKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBKdXN0IGZvcndhcmQgU0FYMiBldmVudCB0byBwYXJzZXIgb2JqZWN0LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZEVsZW1lbnQoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsbmFtZSwgU3RyaW5nIHFuYW1lKSB7Ci0gICAgICAgIF9wYXJzZXIuZW5kRWxlbWVudCh1cmksIGxvY2FsbmFtZSwgcW5hbWUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEp1c3QgZm9yd2FyZCBTQVgyIGV2ZW50IHRvIHBhcnNlciBvYmplY3QuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY2hhcmFjdGVycyhjaGFyW10gY2gsIGludCBzdGFydCwgaW50IGxlbmd0aCkgewotICAgICAgICBfcGFyc2VyLmNoYXJhY3RlcnMoY2gsIHN0YXJ0LCBsZW5ndGgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEp1c3QgZm9yd2FyZCBTQVgyIGV2ZW50IHRvIHBhcnNlciBvYmplY3QuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcHJvY2Vzc2luZ0luc3RydWN0aW9uKFN0cmluZyBuYW1lLCBTdHJpbmcgdmFsdWUpIHsKLSAgICAgICAgX3BhcnNlci5wcm9jZXNzaW5nSW5zdHJ1Y3Rpb24obmFtZSwgdmFsdWUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEp1c3QgZm9yd2FyZCBTQVgyIGV2ZW50IHRvIHBhcnNlciBvYmplY3QuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgaWdub3JhYmxlV2hpdGVzcGFjZShjaGFyW10gY2gsIGludCBzdGFydCwgaW50IGxlbmd0aCkgewotICAgICAgICBfcGFyc2VyLmlnbm9yYWJsZVdoaXRlc3BhY2UoY2gsIHN0YXJ0LCBsZW5ndGgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEp1c3QgZm9yd2FyZCBTQVgyIGV2ZW50IHRvIHBhcnNlciBvYmplY3QuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2tpcHBlZEVudGl0eShTdHJpbmcgbmFtZSkgewotICAgICAgICBfcGFyc2VyLnNraXBwZWRFbnRpdHkobmFtZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0IGludGVybmFsIHN5c3RlbSBJZCBhbmQgZm9yd2FyZCBTQVgyIGV2ZW50IHRvIHBhcnNlciBvYmplY3QuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RG9jdW1lbnRMb2NhdG9yKExvY2F0b3IgbG9jYXRvcikgewotICAgICAgICBzZXRTeXN0ZW1JZChsb2NhdG9yLmdldFN5c3RlbUlkKCkpOwotICAgICAgICBfcGFyc2VyLnNldERvY3VtZW50TG9jYXRvcihsb2NhdG9yKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3RyYXgvVGVtcGxhdGVzSW1wbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy90cmF4L1RlbXBsYXRlc0ltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZTBlZTZmYi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3RyYXgvVGVtcGxhdGVzSW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTI3ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDcsIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKi8KLS8qCi0gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKLSAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAotICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgotICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKLSAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCi0gKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFRlbXBsYXRlc0ltcGwuamF2YSx2IDEuOCAyMDA3LzAzLzI2IDIwOjEyOjI3IHNwZXJpY2FzIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMudHJheDsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC5YYWxhbkNvbnN0YW50czsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwudXRpbHMuT2JqZWN0RmFjdG9yeTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwudXRpbHMuU2VjdXJpdHlTdXBwb3J0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5ET007Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLlRyYW5zbGV0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkVycm9yTXNnOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5ydW50aW1lLkFic3RyYWN0VHJhbnNsZXQ7Ci1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLk5vdFNlcmlhbGl6YWJsZUV4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uT2JqZWN0T3V0cHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uT2JqZWN0U3RyZWFtRmllbGQ7Ci1pbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7Ci1pbXBvcnQgamF2YS5zZWN1cml0eS5BY2Nlc3NDb250cm9sbGVyOwotaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpdmlsZWdlZEFjdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKLWltcG9ydCBqYXZhLnV0aWwuTWFwOwotaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0aWVzOwotaW1wb3J0IGphdmF4LnhtbC5YTUxDb25zdGFudHM7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UZW1wbGF0ZXM7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lcjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlVSSVJlc29sdmVyOwotCi0vKioKLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICogQGF1dGhvciBHLiBUb2RkIE1pbGxlcmoKLSAqIEBhdXRob3IgSm9jaGVuIENvcmRlcyA8Sm9jaGVuLkNvcmRlc0B0LW9ubGluZS5kZT4KLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgVGVtcGxhdGVzSW1wbCBpbXBsZW1lbnRzIFRlbXBsYXRlcywgU2VyaWFsaXphYmxlIHsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNjczMDk0MzYxNTE5MjcwNzA3TDsKLSAgICBwdWJsaWMgZmluYWwgc3RhdGljIFN0cmluZyBERVNFUklBTElaRV9UUkFOU0xFVCA9ICJqZGsueG1sLmVuYWJsZVRlbXBsYXRlc0ltcGxEZXNlcmlhbGl6YXRpb24iOwotCi0gICAgLyoqCi0gICAgICogTmFtZSBvZiB0aGUgc3VwZXJjbGFzcyBvZiBhbGwgdHJhbnNsZXRzLiBUaGlzIGlzIG5lZWRlZCB0bwotICAgICAqIGRldGVybWluZSB3aGljaCwgYW1vbmcgYWxsIGNsYXNzZXMgY29tcHJpc2luZyBhIHRyYW5zbGV0LAotICAgICAqIGlzIHRoZSBtYWluIG9uZS4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgQUJTVFJBQ1RfVFJBTlNMRVQKLSAgICAgICAgPSAiY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnJ1bnRpbWUuQWJzdHJhY3RUcmFuc2xldCI7Ci0KLSAgICAvKioKLSAgICAgKiBOYW1lIG9mIHRoZSBtYWluIGNsYXNzIG9yIGRlZmF1bHQgbmFtZSBpZiB1bmtub3duLgotICAgICAqLwotICAgIHByaXZhdGUgU3RyaW5nIF9uYW1lID0gbnVsbDsKLQotICAgIC8qKgotICAgICAqIENvbnRhaW5zIHRoZSBhY3R1YWwgY2xhc3MgZGVmaW5pdGlvbiBmb3IgdGhlIHRyYW5zbGV0IGNsYXNzIGFuZAotICAgICAqIGFueSBhdXhpbGlhcnkgY2xhc3Nlcy4KLSAgICAgKi8KLSAgICBwcml2YXRlIGJ5dGVbXVtdIF9ieXRlY29kZXMgPSBudWxsOwotCi0gICAgLyoqCi0gICAgICogQ29udGFpbnMgdGhlIHRyYW5zbGV0IGNsYXNzIGRlZmluaXRpb24ocykuIFRoZXNlIGFyZSBjcmVhdGVkIHdoZW4KLSAgICAgKiB0aGlzIFRlbXBsYXRlcyBpcyBjcmVhdGVkIG9yIHdoZW4gaXQgaXMgcmVhZCBiYWNrIGZyb20gZGlzay4KLSAgICAgKi8KLSAgICBwcml2YXRlIENsYXNzW10gX2NsYXNzID0gbnVsbDsKLQotICAgIC8qKgotICAgICAqIFRoZSBpbmRleCBvZiB0aGUgbWFpbiB0cmFuc2xldCBjbGFzcyBpbiB0aGUgYXJyYXlzIF9jbGFzc1tdIGFuZAotICAgICAqIF9ieXRlY29kZXMuCi0gICAgICovCi0gICAgcHJpdmF0ZSBpbnQgX3RyYW5zbGV0SW5kZXggPSAtMTsKLQotICAgIC8qKgotICAgICAqIENvbnRhaW5zIHRoZSBsaXN0IG9mIGF1eGlsaWFyeSBjbGFzcyBkZWZpbml0aW9ucy4KLSAgICAgKi8KLSAgICBwcml2YXRlIHRyYW5zaWVudCBNYXA8U3RyaW5nLCBDbGFzczw/Pj4gX2F1eENsYXNzZXMgPSBudWxsOwotCi0gICAgLyoqCi0gICAgICogT3V0cHV0IHByb3BlcnRpZXMgb2YgdGhpcyB0cmFuc2xldC4KLSAgICAgKi8KLSAgICBwcml2YXRlIFByb3BlcnRpZXMgX291dHB1dFByb3BlcnRpZXM7Ci0KLSAgICAvKioKLSAgICAgKiBOdW1iZXIgb2Ygc3BhY2VzIHRvIGFkZCBmb3Igb3V0cHV0IGluZGVudGF0aW9uLgotICAgICAqLwotICAgIHByaXZhdGUgaW50IF9pbmRlbnROdW1iZXI7Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIFVSSVJlc29sdmVyIGlzIHBhc3NlZCB0byBhbGwgVHJhbnNmb3JtZXJzLgotICAgICAqIERlY2xhcmluZyBpdCB0cmFuc2llbnQgdG8gZml4IGJ1ZyAyMjQzOAotICAgICAqLwotICAgIHByaXZhdGUgdHJhbnNpZW50IFVSSVJlc29sdmVyIF91cmlSZXNvbHZlciA9IG51bGw7Ci0KLSAgICAvKioKLSAgICAgKiBDYWNoZSB0aGUgRFRNIGZvciB0aGUgc3R5bGVzaGVldCBpbiBhIHRocmVhZCBsb2NhbCB2YXJpYWJsZSwKLSAgICAgKiB3aGljaCBpcyB1c2VkIGJ5IHRoZSBkb2N1bWVudCgnJykgZnVuY3Rpb24uCi0gICAgICogVXNlIFRocmVhZExvY2FsIGJlY2F1c2UgYSBEVE0gY2Fubm90IGJlIHNoYXJlZCBiZXR3ZWVuCi0gICAgICogbXVsdGlwbGUgdGhyZWFkcy4KLSAgICAgKiBEZWNsYXJpbmcgaXQgdHJhbnNpZW50IHRvIGZpeCBidWcgMjI0MzgKLSAgICAgKi8KLSAgICBwcml2YXRlIHRyYW5zaWVudCBUaHJlYWRMb2NhbCBfc2RvbSA9IG5ldyBUaHJlYWRMb2NhbCgpOwotCi0gICAgLyoqCi0gICAgICogQSByZWZlcmVuY2UgdG8gdGhlIHRyYW5zZm9ybWVyIGZhY3RvcnkgdGhhdCB0aGlzIHRlbXBsYXRlcwotICAgICAqIG9iamVjdCBiZWxvbmdzIHRvLgotICAgICAqLwotICAgIHByaXZhdGUgdHJhbnNpZW50IFRyYW5zZm9ybWVyRmFjdG9yeUltcGwgX3RmYWN0b3J5ID0gbnVsbDsKLQotICAgIC8qKgotICAgICAqIEEgZmxhZyB0byBkZXRlcm1pbmUgd2hldGhlciB0aGUgU2VydmljZSBNZWNoYW5pc20gaXMgdXNlZAotICAgICAqLwotICAgIHByaXZhdGUgdHJhbnNpZW50IGJvb2xlYW4gX3VzZVNlcnZpY2VzTWVjaGFuaXNtOwotCi0gICAgLyoqCi0gICAgICogcHJvdG9jb2xzIGFsbG93ZWQgZm9yIGV4dGVybmFsIHJlZmVyZW5jZXMgc2V0IGJ5IHRoZSBzdHlsZXNoZWV0IHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24sIEltcG9ydCBhbmQgSW5jbHVkZSBlbGVtZW50LgotICAgICAqLwotICAgIHByaXZhdGUgdHJhbnNpZW50IFN0cmluZyBfYWNjZXNzRXh0ZXJuYWxTdHlsZXNoZWV0ID0gWGFsYW5Db25zdGFudHMuRVhURVJOQUxfQUNDRVNTX0RFRkFVTFQ7Ci0KLSAgICAvKioKLSAgICAgKiBAc2VyaWFsRmllbGQgX25hbWUgU3RyaW5nIFRoZSBOYW1lIG9mIHRoZSBtYWluIGNsYXNzCi0gICAgICogQHNlcmlhbEZpZWxkIF9ieXRlY29kZXMgYnl0ZVtdW10gQ2xhc3MgZGVmaW5pdGlvbgotICAgICAqIEBzZXJpYWxGaWVsZCBfY2xhc3MgQ2xhc3NbXSBUaGUgdHJhbnNsZXQgY2xhc3MgZGVmaW5pdGlvbihzKS4KLSAgICAgKiBAc2VyaWFsRmllbGQgX3RyYW5zbGV0SW5kZXggaW50IFRoZSBpbmRleCBvZiB0aGUgbWFpbiB0cmFuc2xldCBjbGFzcwotICAgICAqIEBzZXJpYWxGaWVsZCBfb3V0cHV0UHJvcGVydGllcyBQcm9wZXJ0aWVzIE91dHB1dCBwcm9wZXJ0aWVzIG9mIHRoaXMgdHJhbnNsZXQuCi0gICAgICogQHNlcmlhbEZpZWxkIF9pbmRlbnROdW1iZXIgaW50IE51bWJlciBvZiBzcGFjZXMgdG8gYWRkIGZvciBvdXRwdXQgaW5kZW50YXRpb24uCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgT2JqZWN0U3RyZWFtRmllbGRbXSBzZXJpYWxQZXJzaXN0ZW50RmllbGRzID0KLSAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkW10gewotICAgICAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJfbmFtZSIsIFN0cmluZy5jbGFzcyksCi0gICAgICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoIl9ieXRlY29kZXMiLCBieXRlW11bXS5jbGFzcyksCi0gICAgICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoIl9jbGFzcyIsIENsYXNzW10uY2xhc3MpLAotICAgICAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJfdHJhbnNsZXRJbmRleCIsIGludC5jbGFzcyksCi0gICAgICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoIl9vdXRwdXRQcm9wZXJ0aWVzIiwgUHJvcGVydGllcy5jbGFzcyksCi0gICAgICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoIl9pbmRlbnROdW1iZXIiLCBpbnQuY2xhc3MpLAotICAgICAgICB9OwotCi0gICAgc3RhdGljIGZpbmFsIGNsYXNzIFRyYW5zbGV0Q2xhc3NMb2FkZXIgZXh0ZW5kcyBDbGFzc0xvYWRlciB7Ci0gICAgICAgIHByaXZhdGUgZmluYWwgTWFwPFN0cmluZyxDbGFzcz4gX2xvYWRlZEV4dGVybmFsRXh0ZW5zaW9uRnVuY3Rpb25zOwotCi0gICAgICAgICBUcmFuc2xldENsYXNzTG9hZGVyKENsYXNzTG9hZGVyIHBhcmVudCkgewotICAgICAgICAgICAgIHN1cGVyKHBhcmVudCk7Ci0gICAgICAgICAgICBfbG9hZGVkRXh0ZXJuYWxFeHRlbnNpb25GdW5jdGlvbnMgPSBudWxsOwotICAgICAgICB9Ci0KLSAgICAgICAgVHJhbnNsZXRDbGFzc0xvYWRlcihDbGFzc0xvYWRlciBwYXJlbnQsTWFwPFN0cmluZywgQ2xhc3M+IG1hcEVGKSB7Ci0gICAgICAgICAgICBzdXBlcihwYXJlbnQpOwotICAgICAgICAgICAgX2xvYWRlZEV4dGVybmFsRXh0ZW5zaW9uRnVuY3Rpb25zID0gbWFwRUY7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgQ2xhc3M8Pz4gbG9hZENsYXNzKFN0cmluZyBuYW1lKSB0aHJvd3MgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICBDbGFzczw/PiByZXQgPSBudWxsOwotICAgICAgICAgICAgLy8gVGhlIF9sb2FkZWRFeHRlcm5hbEV4dGVuc2lvbkZ1bmN0aW9ucyB3aWxsIGJlIGVtcHR5IHdoZW4gdGhlCi0gICAgICAgICAgICAvLyBTZWN1cml0eU1hbmFnZXIgaXMgbm90IHNldCBhbmQgdGhlIEZTUCBpcyB0dXJuZWQgb2ZmCi0gICAgICAgICAgICBpZiAoX2xvYWRlZEV4dGVybmFsRXh0ZW5zaW9uRnVuY3Rpb25zICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICByZXQgPSBfbG9hZGVkRXh0ZXJuYWxFeHRlbnNpb25GdW5jdGlvbnMuZ2V0KG5hbWUpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKHJldCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgcmV0ID0gc3VwZXIubG9hZENsYXNzKG5hbWUpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIHJldDsKLSAgICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogQWNjZXNzIHRvIGZpbmFsIHByb3RlY3RlZCBzdXBlcmNsYXNzIG1lbWJlciBmcm9tIG91dGVyIGNsYXNzLgotICAgICAgICAgKi8KLSAgICAgICAgQ2xhc3MgZGVmaW5lQ2xhc3MoZmluYWwgYnl0ZVtdIGIpIHsKLSAgICAgICAgICAgIHJldHVybiBkZWZpbmVDbGFzcyhudWxsLCBiLCAwLCBiLmxlbmd0aCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIENyZWF0ZSBhbiBYU0xUQyB0ZW1wbGF0ZSBvYmplY3QgZnJvbSB0aGUgYnl0ZWNvZGVzLgotICAgICAqIFRoZSBieXRlY29kZXMgZm9yIHRoZSB0cmFuc2xldCBhbmQgYXV4aWxpYXJ5IGNsYXNzZXMsIHBsdXMgdGhlIG5hbWUgb2YKLSAgICAgKiB0aGUgbWFpbiB0cmFuc2xldCBjbGFzcywgbXVzdCBiZSBzdXBwbGllZC4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgVGVtcGxhdGVzSW1wbChieXRlW11bXSBieXRlY29kZXMsIFN0cmluZyB0cmFuc2xldE5hbWUsCi0gICAgICAgIFByb3BlcnRpZXMgb3V0cHV0UHJvcGVydGllcywgaW50IGluZGVudE51bWJlciwKLSAgICAgICAgVHJhbnNmb3JtZXJGYWN0b3J5SW1wbCB0ZmFjdG9yeSkKLSAgICB7Ci0gICAgICAgIF9ieXRlY29kZXMgPSBieXRlY29kZXM7Ci0gICAgICAgIGluaXQodHJhbnNsZXROYW1lLCBvdXRwdXRQcm9wZXJ0aWVzLCBpbmRlbnROdW1iZXIsIHRmYWN0b3J5KTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGUgYW4gWFNMVEMgdGVtcGxhdGUgb2JqZWN0IGZyb20gdGhlIHRyYW5zbGV0IGNsYXNzIGRlZmluaXRpb24ocykuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIFRlbXBsYXRlc0ltcGwoQ2xhc3NbXSB0cmFuc2xldENsYXNzZXMsIFN0cmluZyB0cmFuc2xldE5hbWUsCi0gICAgICAgIFByb3BlcnRpZXMgb3V0cHV0UHJvcGVydGllcywgaW50IGluZGVudE51bWJlciwKLSAgICAgICAgVHJhbnNmb3JtZXJGYWN0b3J5SW1wbCB0ZmFjdG9yeSkKLSAgICB7Ci0gICAgICAgIF9jbGFzcyAgICAgPSB0cmFuc2xldENsYXNzZXM7Ci0gICAgICAgIF90cmFuc2xldEluZGV4ID0gMDsKLSAgICAgICAgaW5pdCh0cmFuc2xldE5hbWUsIG91dHB1dFByb3BlcnRpZXMsIGluZGVudE51bWJlciwgdGZhY3RvcnkpOwotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBpbml0KFN0cmluZyB0cmFuc2xldE5hbWUsCi0gICAgICAgIFByb3BlcnRpZXMgb3V0cHV0UHJvcGVydGllcywgaW50IGluZGVudE51bWJlciwKLSAgICAgICAgVHJhbnNmb3JtZXJGYWN0b3J5SW1wbCB0ZmFjdG9yeSkgewotICAgICAgICBfbmFtZSAgICAgID0gdHJhbnNsZXROYW1lOwotICAgICAgICBfb3V0cHV0UHJvcGVydGllcyA9IG91dHB1dFByb3BlcnRpZXM7Ci0gICAgICAgIF9pbmRlbnROdW1iZXIgPSBpbmRlbnROdW1iZXI7Ci0gICAgICAgIF90ZmFjdG9yeSA9IHRmYWN0b3J5OwotICAgICAgICBfdXNlU2VydmljZXNNZWNoYW5pc20gPSB0ZmFjdG9yeS51c2VTZXJ2aWNlc01lY2huaXNtKCk7Ci0gICAgICAgIF9hY2Nlc3NFeHRlcm5hbFN0eWxlc2hlZXQgPSAoU3RyaW5nKSB0ZmFjdG9yeS5nZXRBdHRyaWJ1dGUoWE1MQ29uc3RhbnRzLkFDQ0VTU19FWFRFUk5BTF9TVFlMRVNIRUVUKTsKLSAgICB9Ci0gICAgLyoqCi0gICAgICogTmVlZCBmb3IgZGUtc2VyaWFsaXphdGlvbiwgc2VlIHJlYWRPYmplY3QoKS4KLSAgICAgKi8KLSAgICBwdWJsaWMgVGVtcGxhdGVzSW1wbCgpIHsgfQotCi0gICAgLyoqCi0gICAgICogIE92ZXJyaWRlcyB0aGUgZGVmYXVsdCByZWFkT2JqZWN0IGltcGxlbWVudGF0aW9uIHNpbmNlIHdlIGRlY2lkZWQKLSAgICAgKiAgaXQgd291bGQgYmUgY2xlYW5lciBub3QgdG8gc2VyaWFsaXplIHRoZSBlbnRpcmUgdHJhbmZvcm1lcgotICAgICAqICBmYWN0b3J5LiAgWyByZWYgYnVnemlsbGEgMTIzMTcgXQotICAgICAqICBXZSBuZWVkIHRvIGNoZWNrIGlmIHRoZSB1c2VyIGRlZmluZWQgY2xhc3MgZm9yIFVSSVJlc29sdmVyIGFsc28KLSAgICAgKiAgaW1wbGVtZW50ZWQgU2VyaWFsaXphYmxlCi0gICAgICogIGlmIHllcyB0aGVuIHdlIG5lZWQgdG8gZGVzZXJpYWxpemUgdGhlIFVSSVJlc29sdmVyCi0gICAgICogIEZpeCBmb3IgYnVnemlsbGEgYnVnIDIyNDM4Ci0gICAgICovCi0gICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCi0gICAgcHJpdmF0ZSB2b2lkICByZWFkT2JqZWN0KE9iamVjdElucHV0U3RyZWFtIGlzKQotICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBDbGFzc05vdEZvdW5kRXhjZXB0aW9uCi0gICAgewotICAgICAgICBTZWN1cml0eU1hbmFnZXIgc2VjdXJpdHkgPSBTeXN0ZW0uZ2V0U2VjdXJpdHlNYW5hZ2VyKCk7Ci0gICAgICAgIGlmIChzZWN1cml0eSAhPSBudWxsKXsKLSAgICAgICAgICAgIFN0cmluZyB0ZW1wID0gU2VjdXJpdHlTdXBwb3J0LmdldFN5c3RlbVByb3BlcnR5KERFU0VSSUFMSVpFX1RSQU5TTEVUKTsKLSAgICAgICAgICAgIGlmICh0ZW1wID09IG51bGwgfHwgISh0ZW1wLmxlbmd0aCgpPT0wIHx8IHRlbXAuZXF1YWxzSWdub3JlQ2FzZSgidHJ1ZSIpKSkgewotICAgICAgICAgICAgICAgIEVycm9yTXNnIGVyciA9IG5ldyBFcnJvck1zZyhFcnJvck1zZy5ERVNFUklBTElaRV9UUkFOU0xFVF9FUlIpOwotICAgICAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbihlcnIudG9TdHJpbmcoKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBXZSBoYXZlIHRvIHJlYWQgc2VyaWFsaXplZCBmaWVsZHMgZmlyc3QuCi0gICAgICAgIE9iamVjdElucHV0U3RyZWFtLkdldEZpZWxkIGdmID0gaXMucmVhZEZpZWxkcygpOwotICAgICAgICBfbmFtZSA9IChTdHJpbmcpZ2YuZ2V0KCJfbmFtZSIsIG51bGwpOwotICAgICAgICBfYnl0ZWNvZGVzID0gKGJ5dGVbXVtdKWdmLmdldCgiX2J5dGVjb2RlcyIsIG51bGwpOwotICAgICAgICBfY2xhc3MgPSAoQ2xhc3NbXSlnZi5nZXQoIl9jbGFzcyIsIG51bGwpOwotICAgICAgICBfdHJhbnNsZXRJbmRleCA9IGdmLmdldCgiX3RyYW5zbGV0SW5kZXgiLCAtMSk7Ci0KLSAgICAgICAgX291dHB1dFByb3BlcnRpZXMgPSAoUHJvcGVydGllcylnZi5nZXQoIl9vdXRwdXRQcm9wZXJ0aWVzIiwgbnVsbCk7Ci0gICAgICAgIF9pbmRlbnROdW1iZXIgPSBnZi5nZXQoIl9pbmRlbnROdW1iZXIiLCAwKTsKLQotICAgICAgICBpZiAoaXMucmVhZEJvb2xlYW4oKSkgewotICAgICAgICAgICAgX3VyaVJlc29sdmVyID0gKFVSSVJlc29sdmVyKSBpcy5yZWFkT2JqZWN0KCk7Ci0gICAgICAgIH0KLQotICAgICAgICBfdGZhY3RvcnkgPSBuZXcgVHJhbnNmb3JtZXJGYWN0b3J5SW1wbCgpOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogIFRoaXMgaXMgdG8gZml4IGJ1Z3ppbGxhIGJ1ZyAyMjQzOAotICAgICAqICBJZiB0aGUgdXNlciBkZWZpbmVkIGNsYXNzIGltcGxlbWVudHMgVVJJUmVzb2x2ZXIgYW5kIFNlcmlhbGl6YWJsZQotICAgICAqICB0aGVuIHdlIHdhbnQgaXQgdG8gZ2V0IHNlcmlhbGl6ZWQKLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgd3JpdGVPYmplY3QoT2JqZWN0T3V0cHV0U3RyZWFtIG9zKQotICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIENsYXNzTm90Rm91bmRFeGNlcHRpb24gewotICAgICAgICBpZiAoX2F1eENsYXNzZXMgIT0gbnVsbCkgewotICAgICAgICAgICAgLy90aHJvdyB3aXRoIHRoZSBzYW1lIG1lc3NhZ2UgYXMgd2hlbiBIYXNodGFibGUgd2FzIHVzZWQgZm9yIGNvbXBhdGliaWxpdHkuCi0gICAgICAgICAgICB0aHJvdyBuZXcgTm90U2VyaWFsaXphYmxlRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICAiY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnJ1bnRpbWUuSGFzaHRhYmxlIik7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBXcml0ZSBzZXJpYWxpemVkIGZpZWxkcwotICAgICAgICBPYmplY3RPdXRwdXRTdHJlYW0uUHV0RmllbGQgcGYgPSBvcy5wdXRGaWVsZHMoKTsKLSAgICAgICAgcGYucHV0KCJfbmFtZSIsIF9uYW1lKTsKLSAgICAgICAgcGYucHV0KCJfYnl0ZWNvZGVzIiwgX2J5dGVjb2Rlcyk7Ci0gICAgICAgIHBmLnB1dCgiX2NsYXNzIiwgX2NsYXNzKTsKLSAgICAgICAgcGYucHV0KCJfdHJhbnNsZXRJbmRleCIsIF90cmFuc2xldEluZGV4KTsKLSAgICAgICAgcGYucHV0KCJfb3V0cHV0UHJvcGVydGllcyIsIF9vdXRwdXRQcm9wZXJ0aWVzKTsKLSAgICAgICAgcGYucHV0KCJfaW5kZW50TnVtYmVyIiwgX2luZGVudE51bWJlcik7Ci0gICAgICAgIG9zLndyaXRlRmllbGRzKCk7Ci0KLSAgICAgICAgaWYgKF91cmlSZXNvbHZlciBpbnN0YW5jZW9mIFNlcmlhbGl6YWJsZSkgewotICAgICAgICAgICAgb3Mud3JpdGVCb29sZWFuKHRydWUpOwotICAgICAgICAgICAgb3Mud3JpdGVPYmplY3QoKFNlcmlhbGl6YWJsZSkgX3VyaVJlc29sdmVyKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIG9zLndyaXRlQm9vbGVhbihmYWxzZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIHN0YXRlIG9mIHRoZSBzZXJ2aWNlcyBtZWNoYW5pc20gZmVhdHVyZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiB1c2VTZXJ2aWNlc01lY2huaXNtKCkgewotICAgICAgICByZXR1cm4gX3VzZVNlcnZpY2VzTWVjaGFuaXNtOwotICAgIH0KLQotICAgICAvKioKLSAgICAgKiBTdG9yZSBVUklSZXNvbHZlciBuZWVkZWQgZm9yIFRyYW5zZm9ybWVycy4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgc2V0VVJJUmVzb2x2ZXIoVVJJUmVzb2x2ZXIgcmVzb2x2ZXIpIHsKLSAgICAgICAgX3VyaVJlc29sdmVyID0gcmVzb2x2ZXI7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhlIFRyYW5zZm9ybWVyRmFjdG9yeSBtdXN0IHBhc3MgdXMgdGhlIHRyYW5zbGV0IGJ5dGVjb2RlcyB1c2luZyB0aGlzCi0gICAgICogbWV0aG9kIGJlZm9yZSB3ZSBjYW4gY3JlYXRlIGFueSB0cmFuc2xldCBpbnN0YW5jZXMKLSAgICAgKgotICAgICAqIE5vdGU6IFRoaXMgbWV0aG9kIGlzIHByaXZhdGUgZm9yIHNlY3VyaXR5IHJlYXNvbnMuIFNlZQotICAgICAqIENSIDY1Mzc4OTguIFdoZW4gbWVyZ2luZyB3aXRoIEFwYWNoZSwgd2UgbXVzdCBlbnN1cmUKLSAgICAgKiB0aGF0IHRoZSBwcml2YXRlbmVzcyBvZiB0aGlzIG1ldGhvZCBpcyBtYWludGFpbmVkICh0aGF0Ci0gICAgICogaXMgd2h5IGl0IHdhc24ndCByZW1vdmVkKS4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN5bmNocm9uaXplZCB2b2lkIHNldFRyYW5zbGV0Qnl0ZWNvZGVzKGJ5dGVbXVtdIGJ5dGVjb2RlcykgewotICAgICAgICBfYnl0ZWNvZGVzID0gYnl0ZWNvZGVzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIHRyYW5zbGV0IGJ5dGVjb2RlcyBzdG9yZWQgaW4gdGhpcyB0ZW1wbGF0ZQotICAgICAqCi0gICAgICogTm90ZTogVGhpcyBtZXRob2QgaXMgcHJpdmF0ZSBmb3Igc2VjdXJpdHkgcmVhc29ucy4gU2VlCi0gICAgICogQ1IgNjUzNzg5OC4gV2hlbiBtZXJnaW5nIHdpdGggQXBhY2hlLCB3ZSBtdXN0IGVuc3VyZQotICAgICAqIHRoYXQgdGhlIHByaXZhdGVuZXNzIG9mIHRoaXMgbWV0aG9kIGlzIG1haW50YWluZWQgKHRoYXQKLSAgICAgKiBpcyB3aHkgaXQgd2Fzbid0IHJlbW92ZWQpLgotICAgICAqLwotICAgIHByaXZhdGUgc3luY2hyb25pemVkIGJ5dGVbXVtdIGdldFRyYW5zbGV0Qnl0ZWNvZGVzKCkgewotICAgICAgICByZXR1cm4gX2J5dGVjb2RlczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSB0cmFuc2xldCBieXRlY29kZXMgc3RvcmVkIGluIHRoaXMgdGVtcGxhdGUKLSAgICAgKgotICAgICAqIE5vdGU6IFRoaXMgbWV0aG9kIGlzIHByaXZhdGUgZm9yIHNlY3VyaXR5IHJlYXNvbnMuIFNlZQotICAgICAqIENSIDY1Mzc4OTguIFdoZW4gbWVyZ2luZyB3aXRoIEFwYWNoZSwgd2UgbXVzdCBlbnN1cmUKLSAgICAgKiB0aGF0IHRoZSBwcml2YXRlbmVzcyBvZiB0aGlzIG1ldGhvZCBpcyBtYWludGFpbmVkICh0aGF0Ci0gICAgICogaXMgd2h5IGl0IHdhc24ndCByZW1vdmVkKS4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN5bmNocm9uaXplZCBDbGFzc1tdIGdldFRyYW5zbGV0Q2xhc3NlcygpIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGlmIChfY2xhc3MgPT0gbnVsbCkgZGVmaW5lVHJhbnNsZXRDbGFzc2VzKCk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAvLyBGYWxscyB0aHJvdWdoCi0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIF9jbGFzczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbWFpbiBjbGFzcyBpbiBhcnJheSBvZiBieXRlY29kZXMKLSAgICAgKi8KLSAgICBwdWJsaWMgc3luY2hyb25pemVkIGludCBnZXRUcmFuc2xldEluZGV4KCkgewotICAgICAgICB0cnkgewotICAgICAgICAgICAgaWYgKF9jbGFzcyA9PSBudWxsKSBkZWZpbmVUcmFuc2xldENsYXNzZXMoKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIC8vIEZhbGxzIHRocm91Z2gKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gX3RyYW5zbGV0SW5kZXg7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhlIFRyYW5zZm9ybWVyRmFjdG9yeSBzaG91bGQgY2FsbCB0aGlzIG1ldGhvZCB0byBzZXQgdGhlIHRyYW5zbGV0IG5hbWUKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgc3luY2hyb25pemVkIHZvaWQgc2V0VHJhbnNsZXROYW1lKFN0cmluZyBuYW1lKSB7Ci0gICAgICAgIF9uYW1lID0gbmFtZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSBtYWluIHRyYW5zbGV0IGNsYXNzIHN0b3JlZCBpbiB0aGlzIHRlbXBsYXRlCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHN5bmNocm9uaXplZCBTdHJpbmcgZ2V0VHJhbnNsZXROYW1lKCkgewotICAgICAgICByZXR1cm4gX25hbWU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRGVmaW5lcyB0aGUgdHJhbnNsZXQgY2xhc3MgYW5kIGF1eGlsaWFyeSBjbGFzc2VzLgotICAgICAqIFJldHVybnMgYSByZWZlcmVuY2UgdG8gdGhlIENsYXNzIG9iamVjdCB0aGF0IGRlZmluZXMgdGhlIG1haW4gY2xhc3MKLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgZGVmaW5lVHJhbnNsZXRDbGFzc2VzKCkKLSAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgaWYgKF9ieXRlY29kZXMgPT0gbnVsbCkgewotICAgICAgICAgICAgRXJyb3JNc2cgZXJyID0gbmV3IEVycm9yTXNnKEVycm9yTXNnLk5PX1RSQU5TTEVUX0NMQVNTX0VSUik7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uKGVyci50b1N0cmluZygpKTsKLSAgICAgICAgfQotCi0gICAgICAgIFRyYW5zbGV0Q2xhc3NMb2FkZXIgbG9hZGVyID0gKFRyYW5zbGV0Q2xhc3NMb2FkZXIpCi0gICAgICAgICAgICBBY2Nlc3NDb250cm9sbGVyLmRvUHJpdmlsZWdlZChuZXcgUHJpdmlsZWdlZEFjdGlvbigpIHsKLSAgICAgICAgICAgICAgICBwdWJsaWMgT2JqZWN0IHJ1bigpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBUcmFuc2xldENsYXNzTG9hZGVyKE9iamVjdEZhY3RvcnkuZmluZENsYXNzTG9hZGVyKCksX3RmYWN0b3J5LmdldEV4dGVybmFsRXh0ZW5zaW9uc01hcCgpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9KTsKLQotICAgICAgICB0cnkgewotICAgICAgICAgICAgZmluYWwgaW50IGNsYXNzQ291bnQgPSBfYnl0ZWNvZGVzLmxlbmd0aDsKLSAgICAgICAgICAgIF9jbGFzcyA9IG5ldyBDbGFzc1tjbGFzc0NvdW50XTsKLQotICAgICAgICAgICAgaWYgKGNsYXNzQ291bnQgPiAxKSB7Ci0gICAgICAgICAgICAgICAgX2F1eENsYXNzZXMgPSBuZXcgSGFzaE1hcDw+KCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY2xhc3NDb3VudDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgX2NsYXNzW2ldID0gbG9hZGVyLmRlZmluZUNsYXNzKF9ieXRlY29kZXNbaV0pOwotICAgICAgICAgICAgICAgIGZpbmFsIENsYXNzIHN1cGVyQ2xhc3MgPSBfY2xhc3NbaV0uZ2V0U3VwZXJjbGFzcygpOwotCi0gICAgICAgICAgICAgICAgLy8gQ2hlY2sgaWYgdGhpcyBpcyB0aGUgbWFpbiBjbGFzcwotICAgICAgICAgICAgICAgIGlmIChzdXBlckNsYXNzLmdldE5hbWUoKS5lcXVhbHMoQUJTVFJBQ1RfVFJBTlNMRVQpKSB7Ci0gICAgICAgICAgICAgICAgICAgIF90cmFuc2xldEluZGV4ID0gaTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIF9hdXhDbGFzc2VzLnB1dChfY2xhc3NbaV0uZ2V0TmFtZSgpLCBfY2xhc3NbaV0pOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKF90cmFuc2xldEluZGV4IDwgMCkgewotICAgICAgICAgICAgICAgIEVycm9yTXNnIGVycj0gbmV3IEVycm9yTXNnKEVycm9yTXNnLk5PX01BSU5fVFJBTlNMRVRfRVJSLCBfbmFtZSk7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbihlcnIudG9TdHJpbmcoKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKENsYXNzRm9ybWF0RXJyb3IgZSkgewotICAgICAgICAgICAgRXJyb3JNc2cgZXJyID0gbmV3IEVycm9yTXNnKEVycm9yTXNnLlRSQU5TTEVUX0NMQVNTX0VSUiwgX25hbWUpOwotICAgICAgICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbihlcnIudG9TdHJpbmcoKSk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKExpbmthZ2VFcnJvciBlKSB7Ci0gICAgICAgICAgICBFcnJvck1zZyBlcnIgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuVFJBTlNMRVRfT0JKRUNUX0VSUiwgX25hbWUpOwotICAgICAgICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbihlcnIudG9TdHJpbmcoKSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBnZW5lcmF0ZXMgYW4gaW5zdGFuY2Ugb2YgdGhlIHRyYW5zbGV0IGNsYXNzIHRoYXQgaXMKLSAgICAgKiB3cmFwcGVkIGluc2lkZSB0aGlzIFRlbXBsYXRlLiBUaGUgdHJhbnNsZXQgaW5zdGFuY2Ugd2lsbCBsYXRlcgotICAgICAqIGJlIHdyYXBwZWQgaW5zaWRlIGEgVHJhbnNmb3JtZXIgb2JqZWN0LgotICAgICAqLwotICAgIHByaXZhdGUgVHJhbnNsZXQgZ2V0VHJhbnNsZXRJbnN0YW5jZSgpCi0gICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gewotICAgICAgICB0cnkgewotICAgICAgICAgICAgaWYgKF9uYW1lID09IG51bGwpIHJldHVybiBudWxsOwotCi0gICAgICAgICAgICBpZiAoX2NsYXNzID09IG51bGwpIGRlZmluZVRyYW5zbGV0Q2xhc3NlcygpOwotCi0gICAgICAgICAgICAvLyBUaGUgdHJhbnNsZXQgbmVlZHMgdG8ga2VlcCBhIHJlZmVyZW5jZSB0byBhbGwgaXRzIGF1eGlsaWFyeQotICAgICAgICAgICAgLy8gY2xhc3MgdG8gcHJldmVudCB0aGUgR0MgZnJvbSBjb2xsZWN0aW5nIHRoZW0KLSAgICAgICAgICAgIEFic3RyYWN0VHJhbnNsZXQgdHJhbnNsZXQgPSAoQWJzdHJhY3RUcmFuc2xldCkgX2NsYXNzW190cmFuc2xldEluZGV4XS5uZXdJbnN0YW5jZSgpOwotICAgICAgICAgICAgdHJhbnNsZXQucG9zdEluaXRpYWxpemF0aW9uKCk7Ci0gICAgICAgICAgICB0cmFuc2xldC5zZXRUZW1wbGF0ZXModGhpcyk7Ci0gICAgICAgICAgICB0cmFuc2xldC5zZXRTZXJ2aWNlc01lY2huaXNtKF91c2VTZXJ2aWNlc01lY2hhbmlzbSk7Ci0gICAgICAgICAgICB0cmFuc2xldC5zZXRBbGxvd2VkUHJvdG9jb2xzKF9hY2Nlc3NFeHRlcm5hbFN0eWxlc2hlZXQpOwotICAgICAgICAgICAgaWYgKF9hdXhDbGFzc2VzICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICB0cmFuc2xldC5zZXRBdXhpbGlhcnlDbGFzc2VzKF9hdXhDbGFzc2VzKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgcmV0dXJuIHRyYW5zbGV0OwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChJbnN0YW50aWF0aW9uRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIEVycm9yTXNnIGVyciA9IG5ldyBFcnJvck1zZyhFcnJvck1zZy5UUkFOU0xFVF9PQkpFQ1RfRVJSLCBfbmFtZSk7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uKGVyci50b1N0cmluZygpKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICBFcnJvck1zZyBlcnIgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuVFJBTlNMRVRfT0JKRUNUX0VSUiwgX25hbWUpOwotICAgICAgICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbihlcnIudG9TdHJpbmcoKSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJbXBsZW1lbnRzIEpBWFAncyBUZW1wbGF0ZXMubmV3VHJhbnNmb3JtZXIoKQotICAgICAqCi0gICAgICogQHRocm93cyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgc3luY2hyb25pemVkIFRyYW5zZm9ybWVyIG5ld1RyYW5zZm9ybWVyKCkKLSAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgVHJhbnNmb3JtZXJJbXBsIHRyYW5zZm9ybWVyOwotCi0gICAgICAgIHRyYW5zZm9ybWVyID0gbmV3IFRyYW5zZm9ybWVySW1wbChnZXRUcmFuc2xldEluc3RhbmNlKCksIF9vdXRwdXRQcm9wZXJ0aWVzLAotICAgICAgICAgICAgX2luZGVudE51bWJlciwgX3RmYWN0b3J5KTsKLQotICAgICAgICBpZiAoX3VyaVJlc29sdmVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIHRyYW5zZm9ybWVyLnNldFVSSVJlc29sdmVyKF91cmlSZXNvbHZlcik7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoX3RmYWN0b3J5LmdldEZlYXR1cmUoWE1MQ29uc3RhbnRzLkZFQVRVUkVfU0VDVVJFX1BST0NFU1NJTkcpKSB7Ci0gICAgICAgICAgICB0cmFuc2Zvcm1lci5zZXRTZWN1cmVQcm9jZXNzaW5nKHRydWUpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiB0cmFuc2Zvcm1lcjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJbXBsZW1lbnRzIEpBWFAncyBUZW1wbGF0ZXMuZ2V0T3V0cHV0UHJvcGVydGllcygpLiBXZSBuZWVkIHRvCi0gICAgICogaW5zdGFuY2lhdGUgYSB0cmFuc2xldCB0byBnZXQgdGhlIG91dHB1dCBzZXR0aW5ncywgc28KLSAgICAgKiB3ZSBtaWdodCBhcyB3ZWxsIGp1c3QgaW5zdGFuY2lhdGUgYSBUcmFuc2Zvcm1lciBhbmQgdXNlIGl0cwotICAgICAqIGltcGxlbWVudGF0aW9uIG9mIHRoaXMgbWV0aG9kLgotICAgICAqLwotICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgUHJvcGVydGllcyBnZXRPdXRwdXRQcm9wZXJ0aWVzKCkgewotICAgICAgICB0cnkgewotICAgICAgICAgICAgcmV0dXJuIG5ld1RyYW5zZm9ybWVyKCkuZ2V0T3V0cHV0UHJvcGVydGllcygpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gZSkgewotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIHRocmVhZCBsb2NhbCBjb3B5IG9mIHRoZSBzdHlsZXNoZWV0IERPTS4KLSAgICAgKi8KLSAgICBwdWJsaWMgRE9NIGdldFN0eWxlc2hlZXRET00oKSB7Ci0gICAgICAgIHJldHVybiAoRE9NKV9zZG9tLmdldCgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldCB0aGUgdGhyZWFkIGxvY2FsIGNvcHkgb2YgdGhlIHN0eWxlc2hlZXQgRE9NLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFN0eWxlc2hlZXRET00oRE9NIHNkb20pIHsKLSAgICAgICAgX3Nkb20uc2V0KHNkb20pOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvdHJheC9UckFYRmlsdGVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3RyYXgvVHJBWEZpbHRlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxNzI5MDdlLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvdHJheC9UckFYRmlsdGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNDggKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogVHJBWEZpbHRlci5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzA2IDEyOjIzOjE5IHB2ZWR1bGEgRXhwICQKLSAqLwotCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnRyYXg7Ci0KLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotCi1pbXBvcnQgamF2YXgueG1sLlhNTENvbnN0YW50czsKLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy5GYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yOwotaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLlBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyOwotaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLlNBWFBhcnNlckZhY3Rvcnk7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5FcnJvckxpc3RlbmVyOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVGVtcGxhdGVzOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXI7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zYXguU0FYUmVzdWx0OwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5YTUxSZWFkZXJNYW5hZ2VyOwotCi1pbXBvcnQgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguSW5wdXRTb3VyY2U7Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LlhNTFJlYWRlcjsKLWltcG9ydCBvcmcueG1sLnNheC5oZWxwZXJzLlhNTEZpbHRlckltcGw7Ci1pbXBvcnQgb3JnLnhtbC5zYXguaGVscGVycy5YTUxSZWFkZXJGYWN0b3J5OwotCi0vKioKLSAqIHNrZWxldG9uIGV4dGVuc2lvbiBvZiBYTUxGaWx0ZXJJbXBsIGZvciBub3cuCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqIEBhdXRob3IgRy4gVG9kZCBNaWxsZXIKLSAqLwotcHVibGljIGNsYXNzIFRyQVhGaWx0ZXIgZXh0ZW5kcyBYTUxGaWx0ZXJJbXBsIHsKLSAgICBwcml2YXRlIFRlbXBsYXRlcyAgICAgICAgICAgICAgX3RlbXBsYXRlczsKLSAgICBwcml2YXRlIFRyYW5zZm9ybWVySW1wbCAgICAgICAgX3RyYW5zZm9ybWVyOwotICAgIHByaXZhdGUgVHJhbnNmb3JtZXJIYW5kbGVySW1wbCBfdHJhbnNmb3JtZXJIYW5kbGVyOwotICAgIHByaXZhdGUgYm9vbGVhbiBfdXNlU2VydmljZXNNZWNoYW5pc20gPSB0cnVlOwotCi0gICAgcHVibGljIFRyQVhGaWx0ZXIoVGVtcGxhdGVzIHRlbXBsYXRlcykgIHRocm93cwotICAgICAgICBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIF90ZW1wbGF0ZXMgPSB0ZW1wbGF0ZXM7Ci0gICAgICAgIF90cmFuc2Zvcm1lciA9IChUcmFuc2Zvcm1lckltcGwpIHRlbXBsYXRlcy5uZXdUcmFuc2Zvcm1lcigpOwotICAgICAgICBfdHJhbnNmb3JtZXJIYW5kbGVyID0gbmV3IFRyYW5zZm9ybWVySGFuZGxlckltcGwoX3RyYW5zZm9ybWVyKTsKLSAgICAgICAgX3VzZVNlcnZpY2VzTWVjaGFuaXNtID0gX3RyYW5zZm9ybWVyLnVzZVNlcnZpY2VzTWVjaG5pc20oKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgVHJhbnNmb3JtZXIgZ2V0VHJhbnNmb3JtZXIoKSB7Ci0gICAgICAgIHJldHVybiBfdHJhbnNmb3JtZXI7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIGNyZWF0ZVBhcmVudCgpIHRocm93cyBTQVhFeGNlcHRpb24gewotICAgICAgICBYTUxSZWFkZXIgcGFyZW50ID0gbnVsbDsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIFNBWFBhcnNlckZhY3RvcnkgcGZhY3RvcnkgPSBTQVhQYXJzZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCk7Ci0gICAgICAgICAgICBwZmFjdG9yeS5zZXROYW1lc3BhY2VBd2FyZSh0cnVlKTsKLQotICAgICAgICAgICAgaWYgKF90cmFuc2Zvcm1lci5pc1NlY3VyZVByb2Nlc3NpbmcoKSkgewotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgIHBmYWN0b3J5LnNldEZlYXR1cmUoWE1MQ29uc3RhbnRzLkZFQVRVUkVfU0VDVVJFX1BST0NFU1NJTkcsIHRydWUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHt9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIFNBWFBhcnNlciBzYXhwYXJzZXIgPSBwZmFjdG9yeS5uZXdTQVhQYXJzZXIoKTsKLSAgICAgICAgICAgIHBhcmVudCA9IHNheHBhcnNlci5nZXRYTUxSZWFkZXIoKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKGUpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yIGUpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oZS50b1N0cmluZygpKTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChwYXJlbnQgPT0gbnVsbCkgewotICAgICAgICAgICAgcGFyZW50ID0gWE1MUmVhZGVyRmFjdG9yeS5jcmVhdGVYTUxSZWFkZXIoKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIG1ha2UgdGhpcyBYTUxSZWFkZXIgdGhlIHBhcmVudCBvZiB0aGlzIGZpbHRlcgotICAgICAgICBzZXRQYXJlbnQocGFyZW50KTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBwYXJzZSAoSW5wdXRTb3VyY2UgaW5wdXQpIHRocm93cyBTQVhFeGNlcHRpb24sIElPRXhjZXB0aW9uCi0gICAgewotICAgICAgICBYTUxSZWFkZXIgbWFuYWdlZFJlYWRlciA9IG51bGw7Ci0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGlmIChnZXRQYXJlbnQoKSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgbWFuYWdlZFJlYWRlciA9IFhNTFJlYWRlck1hbmFnZXIuZ2V0SW5zdGFuY2UoX3VzZVNlcnZpY2VzTWVjaGFuaXNtKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRYTUxSZWFkZXIoKTsKLSAgICAgICAgICAgICAgICAgICAgc2V0UGFyZW50KG1hbmFnZWRSZWFkZXIpOwotICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiAgZSkgewotICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKGUudG9TdHJpbmcoKSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBjYWxsIHBhcnNlIG9uIHRoZSBwYXJlbnQKLSAgICAgICAgICAgIGdldFBhcmVudCgpLnBhcnNlKGlucHV0KTsKLSAgICAgICAgfSBmaW5hbGx5IHsKLSAgICAgICAgICAgIGlmIChtYW5hZ2VkUmVhZGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBYTUxSZWFkZXJNYW5hZ2VyLmdldEluc3RhbmNlKF91c2VTZXJ2aWNlc01lY2hhbmlzbSkucmVsZWFzZVhNTFJlYWRlcihtYW5hZ2VkUmVhZGVyKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHBhcnNlIChTdHJpbmcgc3lzdGVtSWQpIHRocm93cyBTQVhFeGNlcHRpb24sIElPRXhjZXB0aW9uCi0gICAgewotICAgICAgICBwYXJzZShuZXcgSW5wdXRTb3VyY2Uoc3lzdGVtSWQpKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRDb250ZW50SGFuZGxlciAoQ29udGVudEhhbmRsZXIgaGFuZGxlcikKLSAgICB7Ci0gICAgICAgIF90cmFuc2Zvcm1lckhhbmRsZXIuc2V0UmVzdWx0KG5ldyBTQVhSZXN1bHQoaGFuZGxlcikpOwotICAgICAgICBpZiAoZ2V0UGFyZW50KCkgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgIGNyZWF0ZVBhcmVudCgpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBjYXRjaCAoU0FYRXhjZXB0aW9uICBlKSB7Ci0gICAgICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBnZXRQYXJlbnQoKS5zZXRDb250ZW50SGFuZGxlcihfdHJhbnNmb3JtZXJIYW5kbGVyKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRFcnJvckxpc3RlbmVyIChFcnJvckxpc3RlbmVyIGhhbmRsZXIpIHsgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy90cmF4L1RyYW5zZm9ybWVyRmFjdG9yeUltcGwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvdHJheC9UcmFuc2Zvcm1lckZhY3RvcnlJbXBsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGUzMGZmZmQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy90cmF4L1RyYW5zZm9ybWVyRmFjdG9yeUltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE2MTMgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwNywgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqLwotLyoKLSAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQotICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCi0gKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCi0gKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAotICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKLSAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnRyYXg7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwuWGFsYW5Db25zdGFudHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnV0aWxzLkZhY3RvcnlJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC51dGlscy5GZWF0dXJlTWFuYWdlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwudXRpbHMuRmVhdHVyZVByb3BlcnR5QmFzZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwudXRpbHMuRmVhdHVyZVByb3BlcnR5QmFzZS5TdGF0ZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwudXRpbHMuT2JqZWN0RmFjdG9yeTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwudXRpbHMuU2VjdXJpdHlTdXBwb3J0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC51dGlscy5YTUxTZWN1cml0eU1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnV0aWxzLlhNTFNlY3VyaXR5UHJvcGVydHlNYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC51dGlscy5YTUxTZWN1cml0eVByb3BlcnR5TWFuYWdlci5Qcm9wZXJ0eTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIuQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci5Tb3VyY2VMb2FkZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLlhTTFRDOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkVycm9yTXNnOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5kb20uWFNMVENEVE1NYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuU3RvcFBhcnNlRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuU3R5bGVzaGVldFBJSGFuZGxlcjsKLWltcG9ydCBqYXZhLmlvLkZpbGU7Ci1pbXBvcnQgamF2YS5pby5GaWxlSW5wdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5pby5GaWxlTm90Rm91bmRFeGNlcHRpb247Ci1pbXBvcnQgamF2YS5pby5GaWxlbmFtZUZpbHRlcjsKLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5uZXQuTWFsZm9ybWVkVVJMRXhjZXB0aW9uOwotaW1wb3J0IGphdmEubmV0LlVSTDsKLWltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwotaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuTWFwOwotaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0aWVzOwotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci1pbXBvcnQgamF2YS51dGlsLnppcC5aaXBFbnRyeTsKLWltcG9ydCBqYXZhLnV0aWwuemlwLlppcEZpbGU7Ci1pbXBvcnQgamF2YXgueG1sLlhNTENvbnN0YW50czsKLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXI7Ci1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyRmFjdG9yeTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLkVycm9yTGlzdGVuZXI7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2U7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UZW1wbGF0ZXM7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lcjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJGYWN0b3J5OwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVVJJUmVzb2x2ZXI7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5kb20uRE9NUmVzdWx0OwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uZG9tLkRPTVNvdXJjZTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnNheC5TQVhSZXN1bHQ7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zYXguU0FYU291cmNlOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlNBWFRyYW5zZm9ybWVyRmFjdG9yeTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnNheC5UZW1wbGF0ZXNIYW5kbGVyOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlRyYW5zZm9ybWVySGFuZGxlcjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnN0YXguU3RBWFJlc3VsdDsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnN0YXguU3RBWFNvdXJjZTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbS5TdHJlYW1SZXN1bHQ7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zdHJlYW0uU3RyZWFtU291cmNlOwotaW1wb3J0IG9yZy54bWwuc2F4LklucHV0U291cmNlOwotaW1wb3J0IG9yZy54bWwuc2F4LlhNTEZpbHRlcjsKLWltcG9ydCBvcmcueG1sLnNheC5YTUxSZWFkZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguaGVscGVycy5YTUxSZWFkZXJGYWN0b3J5OwotCi0vKioKLSAqIEltcGxlbWVudGF0aW9uIG9mIGEgSkFYUDEuMSBUcmFuc2Zvcm1lckZhY3RvcnkgZm9yIFRyYW5zbGV0cy4KLSAqIEBhdXRob3IgRy4gVG9kZCBNaWxsZXIKLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKi8KLXB1YmxpYyBjbGFzcyBUcmFuc2Zvcm1lckZhY3RvcnlJbXBsCi0gICAgZXh0ZW5kcyBTQVhUcmFuc2Zvcm1lckZhY3RvcnkgaW1wbGVtZW50cyBTb3VyY2VMb2FkZXIsIEVycm9yTGlzdGVuZXIKLXsKLSAgICAvLyBQdWJsaWMgY29uc3RhbnRzIGZvciBhdHRyaWJ1dGVzIHN1cHBvcnRlZCBieSB0aGUgWFNMVEMgVHJhbnNmb3JtZXJGYWN0b3J5LgotICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgU3RyaW5nIFRSQU5TTEVUX05BTUUgPSAidHJhbnNsZXQtbmFtZSI7Ci0gICAgcHVibGljIGZpbmFsIHN0YXRpYyBTdHJpbmcgREVTVElOQVRJT05fRElSRUNUT1JZID0gImRlc3RpbmF0aW9uLWRpcmVjdG9yeSI7Ci0gICAgcHVibGljIGZpbmFsIHN0YXRpYyBTdHJpbmcgUEFDS0FHRV9OQU1FID0gInBhY2thZ2UtbmFtZSI7Ci0gICAgcHVibGljIGZpbmFsIHN0YXRpYyBTdHJpbmcgSkFSX05BTUUgPSAiamFyLW5hbWUiOwotICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgU3RyaW5nIEdFTkVSQVRFX1RSQU5TTEVUID0gImdlbmVyYXRlLXRyYW5zbGV0IjsKLSAgICBwdWJsaWMgZmluYWwgc3RhdGljIFN0cmluZyBBVVRPX1RSQU5TTEVUID0gImF1dG8tdHJhbnNsZXQiOwotICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgU3RyaW5nIFVTRV9DTEFTU1BBVEggPSAidXNlLWNsYXNzcGF0aCI7Ci0gICAgcHVibGljIGZpbmFsIHN0YXRpYyBTdHJpbmcgREVCVUcgPSAiZGVidWciOwotICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgU3RyaW5nIEVOQUJMRV9JTkxJTklORyA9ICJlbmFibGUtaW5saW5pbmciOwotICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgU3RyaW5nIElOREVOVF9OVU1CRVIgPSAiaW5kZW50LW51bWJlciI7Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIGVycm9yIGxpc3RlbmVyIGlzIHVzZWQgb25seSBmb3IgdGhpcyBmYWN0b3J5IGFuZCBpcyBub3QgcGFzc2VkIHRvCi0gICAgICogdGhlIFRlbXBsYXRlcyBvciBUcmFuc2Zvcm1lciBvYmplY3RzIHRoYXQgd2UgY3JlYXRlLgotICAgICAqLwotICAgIHByaXZhdGUgRXJyb3JMaXN0ZW5lciBfZXJyb3JMaXN0ZW5lciA9IHRoaXM7Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIFVSSVJlc29sdmVyIGlzIHBhc3NlZCB0byBhbGwgY3JlYXRlZCBUZW1wbGF0ZXMgYW5kIFRyYW5zZm9ybWVycwotICAgICAqLwotICAgIHByaXZhdGUgVVJJUmVzb2x2ZXIgX3VyaVJlc29sdmVyID0gbnVsbDsKLQotICAgIC8qKgotICAgICAqIEFzIEdyZWdvciBTYW1zYSBhd29rZSBvbmUgbW9ybmluZyBmcm9tIHVuZWFzeSBkcmVhbXMgaGUgZm91bmQgaGltc2VsZgotICAgICAqIHRyYW5zZm9ybWVkIGluIGhpcyBiZWQgaW50byBhIGdpZ2FudGljIGluc2VjdC4gSGUgd2FzIGx5aW5nIG9uIGhpcyBoYXJkLAotICAgICAqIGFzIGl0IHdlcmUgYXJtb3VyIHBsYXRlZCwgYmFjaywgYW5kIGlmIGhlIGxpZnRlZCBoaXMgaGVhZCBhIGxpdHRsZSBoZQotICAgICAqIGNvdWxkIHNlZSBoaXMgYmlnLCBicm93biBiZWxseSBkaXZpZGVkIGludG8gc3RpZmYsIGFyY2hlZCBzZWdtZW50cywgb24KLSAgICAgKiB0b3Agb2Ygd2hpY2ggdGhlIGJlZCBxdWlsdCBjb3VsZCBoYXJkbHkga2VlcCBpbiBwb3NpdGlvbiBhbmQgd2FzIGFib3V0Ci0gICAgICogdG8gc2xpZGUgb2ZmIGNvbXBsZXRlbHkuIEhpcyBudW1lcm91cyBsZWdzLCB3aGljaCB3ZXJlIHBpdGlmdWxseSB0aGluCi0gICAgICogY29tcGFyZWQgdG8gdGhlIHJlc3Qgb2YgaGlzIGJ1bGssIHdhdmVkIGhlbHBsZXNzbHkgYmVmb3JlIGhpcyBleWVzLgotICAgICAqICJXaGF0IGhhcyBoYXBwZW5lZCB0byBtZT8iLCBoZSB0aG91Z2h0LiBJdCB3YXMgbm8gZHJlYW0uLi4uCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGZpbmFsIHN0YXRpYyBTdHJpbmcgREVGQVVMVF9UUkFOU0xFVF9OQU1FID0gIkdyZWdvclNhbXNhIjsKLQotICAgIC8qKgotICAgICAqIFRoZSBjbGFzcyBuYW1lIG9mIHRoZSB0cmFuc2xldAotICAgICAqLwotICAgIHByaXZhdGUgU3RyaW5nIF90cmFuc2xldE5hbWUgPSBERUZBVUxUX1RSQU5TTEVUX05BTUU7Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgZGVzdGluYXRpb24gZGlyZWN0b3J5IGZvciB0aGUgdHJhbnNsZXQKLSAgICAgKi8KLSAgICBwcml2YXRlIFN0cmluZyBfZGVzdGluYXRpb25EaXJlY3RvcnkgPSBudWxsOwotCi0gICAgLyoqCi0gICAgICogVGhlIHBhY2thZ2UgbmFtZSBwcmVmaXggZm9yIGFsbCBnZW5lcmF0ZWQgdHJhbnNsZXQgY2xhc3NlcwotICAgICAqLwotICAgIHByaXZhdGUgU3RyaW5nIF9wYWNrYWdlTmFtZSA9IG51bGw7Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgamFyIGZpbGUgbmFtZSB3aGljaCB0aGUgdHJhbnNsZXQgY2xhc3NlcyBhcmUgcGFja2FnZWQgaW50bwotICAgICAqLwotICAgIHByaXZhdGUgU3RyaW5nIF9qYXJGaWxlTmFtZSA9IG51bGw7Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIE1hcCBpcyB1c2VkIHRvIHN0b3JlIHBhcmFtZXRlcnMgZm9yIGxvY2F0aW5nCi0gICAgICogPD94bWwtc3R5bGVzaGVldCAuLi4/PiBwcm9jZXNzaW5nIGluc3RydWN0aW9ucyBpbiBYTUwgZG9jcy4KLSAgICAgKi8KLSAgICBwcml2YXRlIE1hcDxTb3VyY2UsIFBJUGFyYW1XcmFwcGVyPiBfcGlQYXJhbXMgPSBudWxsOwotCi0gICAgLyoqCi0gICAgICogVGhlIGFib3ZlIE1hcCBzdG9yZXMgb2JqZWN0cyBvZiB0aGlzIGNsYXNzLgotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIFBJUGFyYW1XcmFwcGVyIHsKLSAgICAgICAgcHVibGljIFN0cmluZyBfbWVkaWEgPSBudWxsOwotICAgICAgICBwdWJsaWMgU3RyaW5nIF90aXRsZSA9IG51bGw7Ci0gICAgICAgIHB1YmxpYyBTdHJpbmcgX2NoYXJzZXQgPSBudWxsOwotCi0gICAgICAgIHB1YmxpYyBQSVBhcmFtV3JhcHBlcihTdHJpbmcgbWVkaWEsIFN0cmluZyB0aXRsZSwgU3RyaW5nIGNoYXJzZXQpIHsKLSAgICAgICAgICAgIF9tZWRpYSA9IG1lZGlhOwotICAgICAgICAgICAgX3RpdGxlID0gdGl0bGU7Ci0gICAgICAgICAgICBfY2hhcnNldCA9IGNoYXJzZXQ7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgdG8gPGNvZGU+dHJ1ZTwvY29kZT4gd2hlbiBkZWJ1Z2dpbmcgaXMgZW5hYmxlZC4KLSAgICAgKi8KLSAgICBwcml2YXRlIGJvb2xlYW4gX2RlYnVnID0gZmFsc2U7Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgdG8gPGNvZGU+dHJ1ZTwvY29kZT4gd2hlbiB0ZW1wbGF0ZXMgYXJlIGlubGluZWQuCi0gICAgICovCi0gICAgcHJpdmF0ZSBib29sZWFuIF9lbmFibGVJbmxpbmluZyA9IGZhbHNlOwotCi0gICAgLyoqCi0gICAgICogU2V0IHRvIDxjb2RlPnRydWU8L2NvZGU+IHdoZW4gd2Ugd2FudCB0byBnZW5lcmF0ZQotICAgICAqIHRyYW5zbGV0IGNsYXNzZXMgZnJvbSB0aGUgc3R5bGVzaGVldC4KLSAgICAgKi8KLSAgICBwcml2YXRlIGJvb2xlYW4gX2dlbmVyYXRlVHJhbnNsZXQgPSBmYWxzZTsKLQotICAgIC8qKgotICAgICAqIElmIHRoaXMgaXMgc2V0IHRvIDxjb2RlPnRydWU8L2NvZGU+LCB3ZSBhdHRlbXB0IHRvIHVzZSB0cmFuc2xldCBjbGFzc2VzCi0gICAgICogZm9yIHRyYW5zZm9ybWF0aW9uIGlmIHBvc3NpYmxlIHdpdGhvdXQgY29tcGlsaW5nIHRoZSBzdHlsZXNoZWV0LiBUaGUKLSAgICAgKiB0cmFuc2xldCBjbGFzcyBpcyBvbmx5IHVzZWQgaWYgaXRzIHRpbWVzdGFtcCBpcyBuZXdlciB0aGFuIHRoZSB0aW1lc3RhbXAKLSAgICAgKiBvZiB0aGUgc3R5bGVzaGVldC4KLSAgICAgKi8KLSAgICBwcml2YXRlIGJvb2xlYW4gX2F1dG9UcmFuc2xldCA9IGZhbHNlOwotCi0gICAgLyoqCi0gICAgICogSWYgdGhpcyBpcyBzZXQgdG8gPGNvZGU+dHJ1ZTwvY29kZT4sIHdlIGF0dGVtcHQgdG8gbG9hZCB0aGUgdHJhbnNsZXQKLSAgICAgKiBmcm9tIHRoZSBDTEFTU1BBVEguCi0gICAgICovCi0gICAgcHJpdmF0ZSBib29sZWFuIF91c2VDbGFzc3BhdGggPSBmYWxzZTsKLQotICAgIC8qKgotICAgICAqIE51bWJlciBvZiBpbmRlbnQgc3BhY2VzIHdoZW4gaW5kZW50YXRpb24gaXMgdHVybmVkIG9uLgotICAgICAqLwotICAgIHByaXZhdGUgaW50IF9pbmRlbnROdW1iZXIgPSAtMTsKLQotICAgIC8qKgotICAgICAqIDxwPlN0YXRlIG9mIHNlY3VyZSBwcm9jZXNzaW5nIGZlYXR1cmUuPC9wPgotICAgICAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBfaXNOb3RTZWN1cmVQcm9jZXNzaW5nID0gdHJ1ZTsKLSAgICAvKioKLSAgICAgKiA8cD5TdGF0ZSBvZiBzZWN1cmUgbW9kZS48L3A+Ci0gICAgICovCi0gICAgcHJpdmF0ZSBib29sZWFuIF9pc1NlY3VyZU1vZGUgPSBmYWxzZTsKLQotICAgIC8qKgotICAgICAqIEluZGljYXRlcyB3aGV0aGVyIGltcGxlbWVudGF0aW9uIHBhcnRzIHNob3VsZCB1c2UKLSAgICAgKiAgIHNlcnZpY2UgbG9hZGVyIChvciBzaW1pbGFyKS4KLSAgICAgKiBOb3RlIHRoZSBkZWZhdWx0IHZhbHVlIChmYWxzZSkgaXMgdGhlIHNhZmUgb3B0aW9uLi4KLSAgICAgKi8KLSAgICBwcml2YXRlIGJvb2xlYW4gX3VzZVNlcnZpY2VzTWVjaGFuaXNtOwotCi0gICAgLyoqCi0gICAgICogcHJvdG9jb2xzIGFsbG93ZWQgZm9yIGV4dGVybmFsIHJlZmVyZW5jZXMgc2V0IGJ5IHRoZSBzdHlsZXNoZWV0IHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24sIEltcG9ydCBhbmQgSW5jbHVkZSBlbGVtZW50LgotICAgICAqLwotICAgIHByaXZhdGUgU3RyaW5nIF9hY2Nlc3NFeHRlcm5hbFN0eWxlc2hlZXQgPSBYYWxhbkNvbnN0YW50cy5FWFRFUk5BTF9BQ0NFU1NfREVGQVVMVDsKLSAgICAgLyoqCi0gICAgICogcHJvdG9jb2xzIGFsbG93ZWQgZm9yIGV4dGVybmFsIERURCByZWZlcmVuY2VzIGluIHNvdXJjZSBmaWxlIGFuZC9vciBzdHlsZXNoZWV0LgotICAgICAqLwotICAgIHByaXZhdGUgU3RyaW5nIF9hY2Nlc3NFeHRlcm5hbERURCA9IFhhbGFuQ29uc3RhbnRzLkVYVEVSTkFMX0FDQ0VTU19ERUZBVUxUOwotCi0gICAgcHJpdmF0ZSBYTUxTZWN1cml0eVByb3BlcnR5TWFuYWdlciBfeG1sU2VjdXJpdHlQcm9wZXJ0eU1ncjsKLSAgICBwcml2YXRlIFhNTFNlY3VyaXR5TWFuYWdlciBfeG1sU2VjdXJpdHlNYW5hZ2VyOwotCi0gICAgcHJpdmF0ZSBmaW5hbCBGZWF0dXJlTWFuYWdlciBfZmVhdHVyZU1hbmFnZXI7Ci0KLSAgICBwcml2YXRlIENsYXNzTG9hZGVyIF9leHRlbnNpb25DbGFzc0xvYWRlciA9IG51bGw7Ci0KLSAgICAvLyBVbm1vZGlmaWFibGUgdmlldyBvZiBleHRlcm5hbCBleHRlbnNpb24gZnVuY3Rpb24gZnJvbSB4c2x0IGNvbXBpbGVyCi0gICAgLy8gSXQgd2lsbCBiZSBwb3B1bGF0ZWQgYnkgdXNlci1zcGVjaWZpZWQgZXh0ZW5zaW9uIGZ1bmN0aW9ucyBkdXJpbmcgdGhlCi0gICAgLy8gdHlwZSBjaGVja2luZwotICAgIHByaXZhdGUgTWFwPFN0cmluZywgQ2xhc3M+IF94c2x0Y0V4dGVuc2lvbkZ1bmN0aW9uczsKLQotICAgIC8qKgotICAgICAqIGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlRyYW5zZm9ybWVyRmFjdG9yeSBpbXBsZW1lbnRhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgVHJhbnNmb3JtZXJGYWN0b3J5SW1wbCgpIHsKLSAgICAgICAgdGhpcyh0cnVlKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgc3RhdGljIFRyYW5zZm9ybWVyRmFjdG9yeSBuZXdUcmFuc2Zvcm1lckZhY3RvcnlOb1NlcnZpY2VMb2FkZXIoKSB7Ci0gICAgICAgIHJldHVybiBuZXcgVHJhbnNmb3JtZXJGYWN0b3J5SW1wbChmYWxzZSk7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBUcmFuc2Zvcm1lckZhY3RvcnlJbXBsKGJvb2xlYW4gdXNlU2VydmljZXNNZWNoYW5pc20pIHsKLSAgICAgICAgdGhpcy5fdXNlU2VydmljZXNNZWNoYW5pc20gPSB1c2VTZXJ2aWNlc01lY2hhbmlzbTsKLSAgICAgICAgX2ZlYXR1cmVNYW5hZ2VyID0gbmV3IEZlYXR1cmVNYW5hZ2VyKCk7Ci0KLSAgICAgICAgaWYgKFN5c3RlbS5nZXRTZWN1cml0eU1hbmFnZXIoKSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBfaXNTZWN1cmVNb2RlID0gdHJ1ZTsKLSAgICAgICAgICAgIF9pc05vdFNlY3VyZVByb2Nlc3NpbmcgPSBmYWxzZTsKLSAgICAgICAgICAgIF9mZWF0dXJlTWFuYWdlci5zZXRWYWx1ZShGZWF0dXJlTWFuYWdlci5GZWF0dXJlLk9SQUNMRV9FTkFCTEVfRVhURU5TSU9OX0ZVTkNUSU9OLAotICAgICAgICAgICAgICAgICAgICBGZWF0dXJlUHJvcGVydHlCYXNlLlN0YXRlLkZTUCwgWGFsYW5Db25zdGFudHMuRkVBVFVSRV9GQUxTRSk7Ci0gICAgICAgIH0KLQotICAgICAgICBfeG1sU2VjdXJpdHlQcm9wZXJ0eU1nciA9IG5ldyBYTUxTZWN1cml0eVByb3BlcnR5TWFuYWdlcigpOwotICAgICAgICBfYWNjZXNzRXh0ZXJuYWxEVEQgPSBfeG1sU2VjdXJpdHlQcm9wZXJ0eU1nci5nZXRWYWx1ZSgKLSAgICAgICAgICAgICAgICBQcm9wZXJ0eS5BQ0NFU1NfRVhURVJOQUxfRFREKTsKLSAgICAgICAgX2FjY2Vzc0V4dGVybmFsU3R5bGVzaGVldCA9IF94bWxTZWN1cml0eVByb3BlcnR5TWdyLmdldFZhbHVlKAotICAgICAgICAgICAgICAgIFByb3BlcnR5LkFDQ0VTU19FWFRFUk5BTF9TVFlMRVNIRUVUKTsKLQotICAgICAgICAvL1BhcnNlcidzIHNlY3VyaXR5IG1hbmFnZXIKLSAgICAgICAgX3htbFNlY3VyaXR5TWFuYWdlciA9IG5ldyBYTUxTZWN1cml0eU1hbmFnZXIodHJ1ZSk7Ci0gICAgICAgIC8vVW5tb2RpZmlhYmxlIGhhc2ggbWFwIHdpdGggbG9hZGVkIGV4dGVybmFsIGV4dGVuc2lvbiBmdW5jdGlvbnMKLSAgICAgICAgX3hzbHRjRXh0ZW5zaW9uRnVuY3Rpb25zID0gbnVsbDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgTWFwPFN0cmluZyxDbGFzcz4gZ2V0RXh0ZXJuYWxFeHRlbnNpb25zTWFwKCkgewotICAgICAgICByZXR1cm4gX3hzbHRjRXh0ZW5zaW9uRnVuY3Rpb25zOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlRyYW5zZm9ybWVyRmFjdG9yeSBpbXBsZW1lbnRhdGlvbi4KLSAgICAgKiBTZXQgdGhlIGVycm9yIGV2ZW50IGxpc3RlbmVyIGZvciB0aGUgVHJhbnNmb3JtZXJGYWN0b3J5LCB3aGljaCBpcyB1c2VkCi0gICAgICogZm9yIHRoZSBwcm9jZXNzaW5nIG9mIHRyYW5zZm9ybWF0aW9uIGluc3RydWN0aW9ucywgYW5kIG5vdCBmb3IgdGhlCi0gICAgICogdHJhbnNmb3JtYXRpb24gaXRzZWxmLgotICAgICAqCi0gICAgICogQHBhcmFtIGxpc3RlbmVyIFRoZSBlcnJvciBsaXN0ZW5lciB0byB1c2Ugd2l0aCB0aGUgVHJhbnNmb3JtZXJGYWN0b3J5Ci0gICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KLSAgICAgKi8KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgdm9pZCBzZXRFcnJvckxpc3RlbmVyKEVycm9yTGlzdGVuZXIgbGlzdGVuZXIpCi0gICAgICAgIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGlmIChsaXN0ZW5lciA9PSBudWxsKSB7Ci0gICAgICAgICAgICBFcnJvck1zZyBlcnIgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuRVJST1JfTElTVEVORVJfTlVMTF9FUlIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlRyYW5zZm9ybWVyRmFjdG9yeSIpOwotICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihlcnIudG9TdHJpbmcoKSk7Ci0gICAgICAgIH0KLSAgICAgICAgX2Vycm9yTGlzdGVuZXIgPSBsaXN0ZW5lcjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBqYXZheC54bWwudHJhbnNmb3JtLnNheC5UcmFuc2Zvcm1lckZhY3RvcnkgaW1wbGVtZW50YXRpb24uCi0gICAgICogR2V0IHRoZSBlcnJvciBldmVudCBoYW5kbGVyIGZvciB0aGUgVHJhbnNmb3JtZXJGYWN0b3J5LgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgZXJyb3IgbGlzdGVuZXIgdXNlZCB3aXRoIHRoZSBUcmFuc2Zvcm1lckZhY3RvcnkKLSAgICAgKi8KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgRXJyb3JMaXN0ZW5lciBnZXRFcnJvckxpc3RlbmVyKCkgewotICAgICAgICByZXR1cm4gX2Vycm9yTGlzdGVuZXI7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogamF2YXgueG1sLnRyYW5zZm9ybS5zYXguVHJhbnNmb3JtZXJGYWN0b3J5IGltcGxlbWVudGF0aW9uLgotICAgICAqIFJldHVybnMgdGhlIHZhbHVlIHNldCBmb3IgYSBUcmFuc2Zvcm1lckZhY3RvcnkgYXR0cmlidXRlCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgYXR0cmlidXRlIG5hbWUKLSAgICAgKiBAcmV0dXJuIEFuIG9iamVjdCByZXByZXNlbnRpbmcgdGhlIGF0dHJpYnV0ZSB2YWx1ZQotICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCi0gICAgICovCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIE9iamVjdCBnZXRBdHRyaWJ1dGUoU3RyaW5nIG5hbWUpCi0gICAgICAgIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIC8vIFJldHVybiB2YWx1ZSBmb3IgYXR0cmlidXRlICd0cmFuc2xldC1uYW1lJwotICAgICAgICBpZiAobmFtZS5lcXVhbHMoVFJBTlNMRVRfTkFNRSkpIHsKLSAgICAgICAgICAgIHJldHVybiBfdHJhbnNsZXROYW1lOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzKEdFTkVSQVRFX1RSQU5TTEVUKSkgewotICAgICAgICAgICAgcmV0dXJuIG5ldyBCb29sZWFuKF9nZW5lcmF0ZVRyYW5zbGV0KTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFscyhBVVRPX1RSQU5TTEVUKSkgewotICAgICAgICAgICAgcmV0dXJuIG5ldyBCb29sZWFuKF9hdXRvVHJhbnNsZXQpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzKEVOQUJMRV9JTkxJTklORykpIHsKLSAgICAgICAgICAgIGlmIChfZW5hYmxlSW5saW5pbmcpCi0gICAgICAgICAgICAgIHJldHVybiBCb29sZWFuLlRSVUU7Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgIHJldHVybiBCb29sZWFuLkZBTFNFOwotICAgICAgICB9IGVsc2UgaWYgKG5hbWUuZXF1YWxzKFhhbGFuQ29uc3RhbnRzLlNFQ1VSSVRZX01BTkFHRVIpKSB7Ci0gICAgICAgICAgICByZXR1cm4gX3htbFNlY3VyaXR5TWFuYWdlcjsKLSAgICAgICAgfSBlbHNlIGlmIChuYW1lLmVxdWFscyhYYWxhbkNvbnN0YW50cy5KREtfRVhURU5TSU9OX0NMQVNTTE9BREVSKSkgewotICAgICAgICAgICByZXR1cm4gX2V4dGVuc2lvbkNsYXNzTG9hZGVyOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqIENoZWNrIHRvIHNlZSBpZiB0aGUgcHJvcGVydHkgaXMgbWFuYWdlZCBieSB0aGUgc2VjdXJpdHkgbWFuYWdlciAqKi8KLSAgICAgICAgU3RyaW5nIHByb3BlcnR5VmFsdWUgPSAoX3htbFNlY3VyaXR5TWFuYWdlciAhPSBudWxsKSA/Ci0gICAgICAgICAgICAgICAgX3htbFNlY3VyaXR5TWFuYWdlci5nZXRMaW1pdEFzU3RyaW5nKG5hbWUpIDogbnVsbDsKLSAgICAgICAgaWYgKHByb3BlcnR5VmFsdWUgIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIHByb3BlcnR5VmFsdWU7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBwcm9wZXJ0eVZhbHVlID0gKF94bWxTZWN1cml0eVByb3BlcnR5TWdyICE9IG51bGwpID8KLSAgICAgICAgICAgICAgICBfeG1sU2VjdXJpdHlQcm9wZXJ0eU1nci5nZXRWYWx1ZShuYW1lKSA6IG51bGw7Ci0gICAgICAgICAgICBpZiAocHJvcGVydHlWYWx1ZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHByb3BlcnR5VmFsdWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBUaHJvdyBhbiBleGNlcHRpb24gZm9yIGFsbCBvdGhlciBhdHRyaWJ1dGVzCi0gICAgICAgIEVycm9yTXNnIGVyciA9IG5ldyBFcnJvck1zZyhFcnJvck1zZy5KQVhQX0lOVkFMSURfQVRUUl9FUlIsIG5hbWUpOwotICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKGVyci50b1N0cmluZygpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBqYXZheC54bWwudHJhbnNmb3JtLnNheC5UcmFuc2Zvcm1lckZhY3RvcnkgaW1wbGVtZW50YXRpb24uCi0gICAgICogU2V0cyB0aGUgdmFsdWUgZm9yIGEgVHJhbnNmb3JtZXJGYWN0b3J5IGF0dHJpYnV0ZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBhdHRyaWJ1dGUgbmFtZQotICAgICAqIEBwYXJhbSB2YWx1ZSBBbiBvYmplY3QgcmVwcmVzZW50aW5nIHRoZSBhdHRyaWJ1dGUgdmFsdWUKLSAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgotICAgICAqLwotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyB2b2lkIHNldEF0dHJpYnV0ZShTdHJpbmcgbmFtZSwgT2JqZWN0IHZhbHVlKQotICAgICAgICB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCi0gICAgewotICAgICAgICAvLyBTZXQgdGhlIGRlZmF1bHQgdHJhbnNsZXQgbmFtZSAoaWUuIGNsYXNzIG5hbWUpLCB3aGljaCB3aWxsIGJlIHVzZWQKLSAgICAgICAgLy8gZm9yIHRyYW5zbGV0cyB0aGF0IGNhbm5vdCBiZSBnaXZlbiBhIG5hbWUgZnJvbSB0aGVpciBzeXN0ZW0taWQuCi0gICAgICAgIGlmIChuYW1lLmVxdWFscyhUUkFOU0xFVF9OQU1FKSAmJiB2YWx1ZSBpbnN0YW5jZW9mIFN0cmluZykgewotICAgICAgICAgICAgX3RyYW5zbGV0TmFtZSA9IChTdHJpbmcpIHZhbHVlOwotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzKERFU1RJTkFUSU9OX0RJUkVDVE9SWSkgJiYgdmFsdWUgaW5zdGFuY2VvZiBTdHJpbmcpIHsKLSAgICAgICAgICAgIF9kZXN0aW5hdGlvbkRpcmVjdG9yeSA9IChTdHJpbmcpIHZhbHVlOwotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzKFBBQ0tBR0VfTkFNRSkgJiYgdmFsdWUgaW5zdGFuY2VvZiBTdHJpbmcpIHsKLSAgICAgICAgICAgIF9wYWNrYWdlTmFtZSA9IChTdHJpbmcpIHZhbHVlOwotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzKEpBUl9OQU1FKSAmJiB2YWx1ZSBpbnN0YW5jZW9mIFN0cmluZykgewotICAgICAgICAgICAgX2phckZpbGVOYW1lID0gKFN0cmluZykgdmFsdWU7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAobmFtZS5lcXVhbHMoR0VORVJBVEVfVFJBTlNMRVQpKSB7Ci0gICAgICAgICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBCb29sZWFuKSB7Ci0gICAgICAgICAgICAgICAgX2dlbmVyYXRlVHJhbnNsZXQgPSAoKEJvb2xlYW4pIHZhbHVlKS5ib29sZWFuVmFsdWUoKTsKLSAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmICh2YWx1ZSBpbnN0YW5jZW9mIFN0cmluZykgewotICAgICAgICAgICAgICAgIF9nZW5lcmF0ZVRyYW5zbGV0ID0gKChTdHJpbmcpIHZhbHVlKS5lcXVhbHNJZ25vcmVDYXNlKCJ0cnVlIik7Ci0gICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzKEFVVE9fVFJBTlNMRVQpKSB7Ci0gICAgICAgICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBCb29sZWFuKSB7Ci0gICAgICAgICAgICAgICAgX2F1dG9UcmFuc2xldCA9ICgoQm9vbGVhbikgdmFsdWUpLmJvb2xlYW5WYWx1ZSgpOwotICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKHZhbHVlIGluc3RhbmNlb2YgU3RyaW5nKSB7Ci0gICAgICAgICAgICAgICAgX2F1dG9UcmFuc2xldCA9ICgoU3RyaW5nKSB2YWx1ZSkuZXF1YWxzSWdub3JlQ2FzZSgidHJ1ZSIpOwotICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFscyhVU0VfQ0xBU1NQQVRIKSkgewotICAgICAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgQm9vbGVhbikgewotICAgICAgICAgICAgICAgIF91c2VDbGFzc3BhdGggPSAoKEJvb2xlYW4pIHZhbHVlKS5ib29sZWFuVmFsdWUoKTsKLSAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmICh2YWx1ZSBpbnN0YW5jZW9mIFN0cmluZykgewotICAgICAgICAgICAgICAgIF91c2VDbGFzc3BhdGggPSAoKFN0cmluZykgdmFsdWUpLmVxdWFsc0lnbm9yZUNhc2UoInRydWUiKTsKLSAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAobmFtZS5lcXVhbHMoREVCVUcpKSB7Ci0gICAgICAgICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBCb29sZWFuKSB7Ci0gICAgICAgICAgICAgICAgX2RlYnVnID0gKChCb29sZWFuKSB2YWx1ZSkuYm9vbGVhblZhbHVlKCk7Ci0gICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAodmFsdWUgaW5zdGFuY2VvZiBTdHJpbmcpIHsKLSAgICAgICAgICAgICAgICBfZGVidWcgPSAoKFN0cmluZykgdmFsdWUpLmVxdWFsc0lnbm9yZUNhc2UoInRydWUiKTsKLSAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAobmFtZS5lcXVhbHMoRU5BQkxFX0lOTElOSU5HKSkgewotICAgICAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgQm9vbGVhbikgewotICAgICAgICAgICAgICAgIF9lbmFibGVJbmxpbmluZyA9ICgoQm9vbGVhbikgdmFsdWUpLmJvb2xlYW5WYWx1ZSgpOwotICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKHZhbHVlIGluc3RhbmNlb2YgU3RyaW5nKSB7Ci0gICAgICAgICAgICAgICAgX2VuYWJsZUlubGluaW5nID0gKChTdHJpbmcpIHZhbHVlKS5lcXVhbHNJZ25vcmVDYXNlKCJ0cnVlIik7Ci0gICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzKElOREVOVF9OVU1CRVIpKSB7Ci0gICAgICAgICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBTdHJpbmcpIHsKLSAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICBfaW5kZW50TnVtYmVyID0gSW50ZWdlci5wYXJzZUludCgoU3RyaW5nKSB2YWx1ZSk7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIEZhbGxzIHRocm91Z2gKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmICh2YWx1ZSBpbnN0YW5jZW9mIEludGVnZXIpIHsKLSAgICAgICAgICAgICAgICBfaW5kZW50TnVtYmVyID0gKChJbnRlZ2VyKSB2YWx1ZSkuaW50VmFsdWUoKTsKLSAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoIG5hbWUuZXF1YWxzKFhhbGFuQ29uc3RhbnRzLkpES19FWFRFTlNJT05fQ0xBU1NMT0FERVIpKSB7Ci0gICAgICAgICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBDbGFzc0xvYWRlcikgewotICAgICAgICAgICAgICAgIF9leHRlbnNpb25DbGFzc0xvYWRlciA9IChDbGFzc0xvYWRlcikgdmFsdWU7Ci0gICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBmaW5hbCBFcnJvck1zZyBlcnIKLSAgICAgICAgICAgICAgICAgICAgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuSkFYUF9JTlZBTElEX0FUVFJfVkFMVUVfRVJSLCAiRXh0ZW5zaW9uIEZ1bmN0aW9ucyBDbGFzc0xvYWRlciIpOwotICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oZXJyLnRvU3RyaW5nKCkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKF94bWxTZWN1cml0eU1hbmFnZXIgIT0gbnVsbCAmJgotICAgICAgICAgICAgICAgIF94bWxTZWN1cml0eU1hbmFnZXIuc2V0TGltaXQobmFtZSwgWE1MU2VjdXJpdHlNYW5hZ2VyLlN0YXRlLkFQSVBST1BFUlRZLCB2YWx1ZSkpIHsKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChfeG1sU2VjdXJpdHlQcm9wZXJ0eU1nciAhPSBudWxsICYmCi0gICAgICAgICAgICBfeG1sU2VjdXJpdHlQcm9wZXJ0eU1nci5zZXRWYWx1ZShuYW1lLCBYTUxTZWN1cml0eVByb3BlcnR5TWFuYWdlci5TdGF0ZS5BUElQUk9QRVJUWSwgdmFsdWUpKSB7Ci0gICAgICAgICAgICBfYWNjZXNzRXh0ZXJuYWxEVEQgPSBfeG1sU2VjdXJpdHlQcm9wZXJ0eU1nci5nZXRWYWx1ZSgKLSAgICAgICAgICAgICAgICAgICAgUHJvcGVydHkuQUNDRVNTX0VYVEVSTkFMX0RURCk7Ci0gICAgICAgICAgICBfYWNjZXNzRXh0ZXJuYWxTdHlsZXNoZWV0ID0gX3htbFNlY3VyaXR5UHJvcGVydHlNZ3IuZ2V0VmFsdWUoCi0gICAgICAgICAgICAgICAgICAgIFByb3BlcnR5LkFDQ0VTU19FWFRFUk5BTF9TVFlMRVNIRUVUKTsKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIFRocm93IGFuIGV4Y2VwdGlvbiBmb3IgYWxsIG90aGVyIGF0dHJpYnV0ZXMKLSAgICAgICAgZmluYWwgRXJyb3JNc2cgZXJyCi0gICAgICAgICAgICA9IG5ldyBFcnJvck1zZyhFcnJvck1zZy5KQVhQX0lOVkFMSURfQVRUUl9FUlIsIG5hbWUpOwotICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKGVyci50b1N0cmluZygpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5TZXQgYSBmZWF0dXJlIGZvciB0aGlzIDxjb2RlPlRyYW5zZm9ybWVyRmFjdG9yeTwvY29kZT4gYW5kIDxjb2RlPlRyYW5zZm9ybWVyPC9jb2RlPnMKLSAgICAgKiBvciA8Y29kZT5UZW1wbGF0ZTwvY29kZT5zIGNyZWF0ZWQgYnkgdGhpcyBmYWN0b3J5LjwvcD4KLSAgICAgKgotICAgICAqIDxwPgotICAgICAqIEZlYXR1cmUgbmFtZXMgYXJlIGZ1bGx5IHF1YWxpZmllZCB7QGxpbmsgamF2YS5uZXQuVVJJfXMuCi0gICAgICogSW1wbGVtZW50YXRpb25zIG1heSBkZWZpbmUgdGhlaXIgb3duIGZlYXR1cmVzLgotICAgICAqIEFuIHtAbGluayBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb259IGlzIHRocm93biBpZiB0aGlzIDxjb2RlPlRyYW5zZm9ybWVyRmFjdG9yeTwvY29kZT4gb3IgdGhlCi0gICAgICogPGNvZGU+VHJhbnNmb3JtZXI8L2NvZGU+cyBvciA8Y29kZT5UZW1wbGF0ZTwvY29kZT5zIGl0IGNyZWF0ZXMgY2Fubm90IHN1cHBvcnQgdGhlIGZlYXR1cmUuCi0gICAgICogSXQgaXMgcG9zc2libGUgZm9yIGFuIDxjb2RlPlRyYW5zZm9ybWVyRmFjdG9yeTwvY29kZT4gdG8gZXhwb3NlIGEgZmVhdHVyZSB2YWx1ZSBidXQgYmUgdW5hYmxlIHRvIGNoYW5nZSBpdHMgc3RhdGUuCi0gICAgICogPC9wPgotICAgICAqCi0gICAgICogPHA+U2VlIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRmFjdG9yeX0gZm9yIGZ1bGwgZG9jdW1lbnRhdGlvbiBvZiBzcGVjaWZpYyBmZWF0dXJlcy48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSBGZWF0dXJlIG5hbWUuCi0gICAgICogQHBhcmFtIHZhbHVlIElzIGZlYXR1cmUgc3RhdGUgPGNvZGU+dHJ1ZTwvY29kZT4gb3IgPGNvZGU+ZmFsc2U8L2NvZGU+LgotICAgICAqCi0gICAgICogQHRocm93cyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gaWYgdGhpcyA8Y29kZT5UcmFuc2Zvcm1lckZhY3Rvcnk8L2NvZGU+Ci0gICAgICogICBvciB0aGUgPGNvZGU+VHJhbnNmb3JtZXI8L2NvZGU+cyBvciA8Y29kZT5UZW1wbGF0ZTwvY29kZT5zIGl0IGNyZWF0ZXMgY2Fubm90IHN1cHBvcnQgdGhpcyBmZWF0dXJlLgotICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gSWYgdGhlIDxjb2RlPm5hbWU8L2NvZGU+IHBhcmFtZXRlciBpcyBudWxsLgotICAgICAqLwotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyB2b2lkIHNldEZlYXR1cmUoU3RyaW5nIG5hbWUsIGJvb2xlYW4gdmFsdWUpCi0gICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gewotCi0gICAgICAgIC8vIGZlYXR1cmUgbmFtZSBjYW5ub3QgYmUgbnVsbAotICAgICAgICBpZiAobmFtZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBFcnJvck1zZyBlcnIgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuSkFYUF9TRVRfRkVBVFVSRV9OVUxMX05BTUUpOwotICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKGVyci50b1N0cmluZygpKTsKLSAgICAgICAgfQotICAgICAgICAvLyBzZWN1cmUgcHJvY2Vzc2luZz8KLSAgICAgICAgZWxzZSBpZiAobmFtZS5lcXVhbHMoWE1MQ29uc3RhbnRzLkZFQVRVUkVfU0VDVVJFX1BST0NFU1NJTkcpKSB7Ci0gICAgICAgICAgICBpZiAoKF9pc1NlY3VyZU1vZGUpICYmICghdmFsdWUpKSB7Ci0gICAgICAgICAgICAgICAgRXJyb3JNc2cgZXJyID0gbmV3IEVycm9yTXNnKEVycm9yTXNnLkpBWFBfU0VDVVJFUFJPQ0VTU0lOR19GRUFUVVJFKTsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uKGVyci50b1N0cmluZygpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIF9pc05vdFNlY3VyZVByb2Nlc3NpbmcgPSAhdmFsdWU7Ci0gICAgICAgICAgICBfeG1sU2VjdXJpdHlNYW5hZ2VyLnNldFNlY3VyZVByb2Nlc3NpbmcodmFsdWUpOwotCi0gICAgICAgICAgICAvLyBzZXQgZXh0ZXJuYWwgYWNjZXNzIHJlc3RyaWN0aW9uIHdoZW4gRlNQIGlzIGV4cGxpY2l0bHkgc2V0Ci0gICAgICAgICAgICBpZiAodmFsdWUgJiYgWGFsYW5Db25zdGFudHMuSVNfSkRLOF9PUl9BQk9WRSkgewotICAgICAgICAgICAgICAgIF94bWxTZWN1cml0eVByb3BlcnR5TWdyLnNldFZhbHVlKFByb3BlcnR5LkFDQ0VTU19FWFRFUk5BTF9EVEQsCi0gICAgICAgICAgICAgICAgICAgICAgICBTdGF0ZS5GU1AsIFhhbGFuQ29uc3RhbnRzLkVYVEVSTkFMX0FDQ0VTU19ERUZBVUxUX0ZTUCk7Ci0gICAgICAgICAgICAgICAgX3htbFNlY3VyaXR5UHJvcGVydHlNZ3Iuc2V0VmFsdWUoUHJvcGVydHkuQUNDRVNTX0VYVEVSTkFMX1NUWUxFU0hFRVQsCi0gICAgICAgICAgICAgICAgICAgICAgICBTdGF0ZS5GU1AsIFhhbGFuQ29uc3RhbnRzLkVYVEVSTkFMX0FDQ0VTU19ERUZBVUxUX0ZTUCk7Ci0gICAgICAgICAgICAgICAgX2FjY2Vzc0V4dGVybmFsRFREID0gX3htbFNlY3VyaXR5UHJvcGVydHlNZ3IuZ2V0VmFsdWUoCi0gICAgICAgICAgICAgICAgICAgICAgICBQcm9wZXJ0eS5BQ0NFU1NfRVhURVJOQUxfRFREKTsKLSAgICAgICAgICAgICAgICBfYWNjZXNzRXh0ZXJuYWxTdHlsZXNoZWV0ID0gX3htbFNlY3VyaXR5UHJvcGVydHlNZ3IuZ2V0VmFsdWUoCi0gICAgICAgICAgICAgICAgICAgICAgICBQcm9wZXJ0eS5BQ0NFU1NfRVhURVJOQUxfU1RZTEVTSEVFVCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmICh2YWx1ZSAmJiBfZmVhdHVyZU1hbmFnZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIF9mZWF0dXJlTWFuYWdlci5zZXRWYWx1ZShGZWF0dXJlTWFuYWdlci5GZWF0dXJlLk9SQUNMRV9FTkFCTEVfRVhURU5TSU9OX0ZVTkNUSU9OLAotICAgICAgICAgICAgICAgICAgICAgICAgRmVhdHVyZVByb3BlcnR5QmFzZS5TdGF0ZS5GU1AsIFhhbGFuQ29uc3RhbnRzLkZFQVRVUkVfRkFMU0UpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzKFhhbGFuQ29uc3RhbnRzLk9SQUNMRV9GRUFUVVJFX1NFUlZJQ0VfTUVDSEFOSVNNKSkgewotICAgICAgICAgICAgLy9pbiBzZWN1cmUgbW9kZSwgbGV0IF91c2VTZXJ2aWNlc01lY2hhbmlzbSBiZSBkZXRlcm1pbmVkIGJ5IHRoZSBjb25zdHJ1Y3RvcgotICAgICAgICAgICAgaWYgKCFfaXNTZWN1cmVNb2RlKQotICAgICAgICAgICAgICAgIF91c2VTZXJ2aWNlc01lY2hhbmlzbSA9IHZhbHVlOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgaWYgKF9mZWF0dXJlTWFuYWdlciAhPSBudWxsICYmCi0gICAgICAgICAgICAgICAgICAgIF9mZWF0dXJlTWFuYWdlci5zZXRWYWx1ZShuYW1lLCBTdGF0ZS5BUElQUk9QRVJUWSwgdmFsdWUpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyB1bmtub3duIGZlYXR1cmUKLSAgICAgICAgICAgIEVycm9yTXNnIGVyciA9IG5ldyBFcnJvck1zZyhFcnJvck1zZy5KQVhQX1VOU1VQUE9SVEVEX0ZFQVRVUkUsIG5hbWUpOwotICAgICAgICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbihlcnIudG9TdHJpbmcoKSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBqYXZheC54bWwudHJhbnNmb3JtLnNheC5UcmFuc2Zvcm1lckZhY3RvcnkgaW1wbGVtZW50YXRpb24uCi0gICAgICogTG9vayB1cCB0aGUgdmFsdWUgb2YgYSBmZWF0dXJlICh0byBzZWUgaWYgaXQgaXMgc3VwcG9ydGVkKS4KLSAgICAgKiBUaGlzIG1ldGhvZCBtdXN0IGJlIHVwZGF0ZWQgYXMgdGhlIHZhcmlvdXMgbWV0aG9kcyBhbmQgZmVhdHVyZXMgb2YgdGhpcwotICAgICAqIGNsYXNzIGFyZSBpbXBsZW1lbnRlZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBmZWF0dXJlIG5hbWUKLSAgICAgKiBAcmV0dXJuICd0cnVlJyBpZiBmZWF0dXJlIGlzIHN1cHBvcnRlZCwgJ2ZhbHNlJyBpZiBub3QKLSAgICAgKi8KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgYm9vbGVhbiBnZXRGZWF0dXJlKFN0cmluZyBuYW1lKSB7Ci0gICAgICAgIC8vIEFsbCBzdXBwb3J0ZWQgZmVhdHVyZXMgc2hvdWxkIGJlIGxpc3RlZCBoZXJlCi0gICAgICAgIFN0cmluZ1tdIGZlYXR1cmVzID0gewotICAgICAgICAgICAgRE9NU291cmNlLkZFQVRVUkUsCi0gICAgICAgICAgICBET01SZXN1bHQuRkVBVFVSRSwKLSAgICAgICAgICAgIFNBWFNvdXJjZS5GRUFUVVJFLAotICAgICAgICAgICAgU0FYUmVzdWx0LkZFQVRVUkUsCi0gICAgICAgICAgICBTdEFYU291cmNlLkZFQVRVUkUsCi0gICAgICAgICAgICBTdEFYUmVzdWx0LkZFQVRVUkUsCi0gICAgICAgICAgICBTdHJlYW1Tb3VyY2UuRkVBVFVSRSwKLSAgICAgICAgICAgIFN0cmVhbVJlc3VsdC5GRUFUVVJFLAotICAgICAgICAgICAgU0FYVHJhbnNmb3JtZXJGYWN0b3J5LkZFQVRVUkUsCi0gICAgICAgICAgICBTQVhUcmFuc2Zvcm1lckZhY3RvcnkuRkVBVFVSRV9YTUxGSUxURVIsCi0gICAgICAgICAgICBYYWxhbkNvbnN0YW50cy5PUkFDTEVfRkVBVFVSRV9TRVJWSUNFX01FQ0hBTklTTQotICAgICAgICB9OwotCi0gICAgICAgIC8vIGZlYXR1cmUgbmFtZSBjYW5ub3QgYmUgbnVsbAotICAgICAgICBpZiAobmFtZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBFcnJvck1zZyBlcnIgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuSkFYUF9HRVRfRkVBVFVSRV9OVUxMX05BTUUpOwotICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKGVyci50b1N0cmluZygpKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIEluZWZmaWNpZW50LCBidXQgYXJyYXkgaXMgc21hbGwKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmZWF0dXJlcy5sZW5ndGg7IGkrKykgewotICAgICAgICAgICAgaWYgKG5hbWUuZXF1YWxzKGZlYXR1cmVzW2ldKSkgewotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIC8vIHNlY3VyZSBwcm9jZXNzaW5nPwotICAgICAgICBpZiAobmFtZS5lcXVhbHMoWE1MQ29uc3RhbnRzLkZFQVRVUkVfU0VDVVJFX1BST0NFU1NJTkcpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuICFfaXNOb3RTZWN1cmVQcm9jZXNzaW5nOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqIENoZWNrIHRvIHNlZSBpZiB0aGUgcHJvcGVydHkgaXMgbWFuYWdlZCBieSB0aGUgc2VjdXJpdHkgbWFuYWdlciAqKi8KLSAgICAgICAgU3RyaW5nIHByb3BlcnR5VmFsdWUgPSAoX2ZlYXR1cmVNYW5hZ2VyICE9IG51bGwpID8KLSAgICAgICAgICAgICAgICBfZmVhdHVyZU1hbmFnZXIuZ2V0VmFsdWVBc1N0cmluZyhuYW1lKSA6IG51bGw7Ci0gICAgICAgIGlmIChwcm9wZXJ0eVZhbHVlICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBCb29sZWFuLnBhcnNlQm9vbGVhbihwcm9wZXJ0eVZhbHVlKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIEZlYXR1cmUgbm90IHN1cHBvcnRlZAotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotICAgIC8qKgotICAgICAqIFJldHVybiB0aGUgc3RhdGUgb2YgdGhlIHNlcnZpY2VzIG1lY2hhbmlzbSBmZWF0dXJlLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIHVzZVNlcnZpY2VzTWVjaG5pc20oKSB7Ci0gICAgICAgIHJldHVybiBfdXNlU2VydmljZXNNZWNoYW5pc207Ci0gICAgfQotCi0gICAgIC8qKgotICAgICAqIEByZXR1cm4gdGhlIGZlYXR1cmUgbWFuYWdlcgotICAgICAqLwotICAgIHB1YmxpYyBGZWF0dXJlTWFuYWdlciBnZXRGZWF0dXJlTWFuYWdlcigpIHsKLSAgICAgICAgcmV0dXJuIF9mZWF0dXJlTWFuYWdlcjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBqYXZheC54bWwudHJhbnNmb3JtLnNheC5UcmFuc2Zvcm1lckZhY3RvcnkgaW1wbGVtZW50YXRpb24uCi0gICAgICogR2V0IHRoZSBvYmplY3QgdGhhdCBpcyB1c2VkIGJ5IGRlZmF1bHQgZHVyaW5nIHRoZSB0cmFuc2Zvcm1hdGlvbiB0bwotICAgICAqIHJlc29sdmUgVVJJcyB1c2VkIGluIGRvY3VtZW50KCksIHhzbDppbXBvcnQsIG9yIHhzbDppbmNsdWRlLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgVVJMUmVzb2x2ZXIgdXNlZCBmb3IgdGhpcyBUcmFuc2Zvcm1lckZhY3RvcnkgYW5kIGFsbAotICAgICAqIFRlbXBsYXRlcyBhbmQgVHJhbnNmb3JtZXIgb2JqZWN0cyBjcmVhdGVkIHVzaW5nIHRoaXMgZmFjdG9yeQotICAgICAqLwotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyBVUklSZXNvbHZlciBnZXRVUklSZXNvbHZlcigpIHsKLSAgICAgICAgcmV0dXJuIF91cmlSZXNvbHZlcjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBqYXZheC54bWwudHJhbnNmb3JtLnNheC5UcmFuc2Zvcm1lckZhY3RvcnkgaW1wbGVtZW50YXRpb24uCi0gICAgICogU2V0IHRoZSBvYmplY3QgdGhhdCBpcyB1c2VkIGJ5IGRlZmF1bHQgZHVyaW5nIHRoZSB0cmFuc2Zvcm1hdGlvbiB0bwotICAgICAqIHJlc29sdmUgVVJJcyB1c2VkIGluIGRvY3VtZW50KCksIHhzbDppbXBvcnQsIG9yIHhzbDppbmNsdWRlLiBOb3RlIHRoYXQKLSAgICAgKiB0aGlzIGRvZXMgbm90IGFmZmVjdCBUZW1wbGF0ZXMgYW5kIFRyYW5zZm9ybWVycyB0aGF0IGFyZSBhbHJlYWR5Ci0gICAgICogY3JlYXRlZCB3aXRoIHRoaXMgZmFjdG9yeS4KLSAgICAgKgotICAgICAqIEBwYXJhbSByZXNvbHZlciBUaGUgVVJMUmVzb2x2ZXIgdXNlZCBmb3IgdGhpcyBUcmFuc2Zvcm1lckZhY3RvcnkgYW5kIGFsbAotICAgICAqIFRlbXBsYXRlcyBhbmQgVHJhbnNmb3JtZXIgb2JqZWN0cyBjcmVhdGVkIHVzaW5nIHRoaXMgZmFjdG9yeQotICAgICAqLwotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyB2b2lkIHNldFVSSVJlc29sdmVyKFVSSVJlc29sdmVyIHJlc29sdmVyKSB7Ci0gICAgICAgIF91cmlSZXNvbHZlciA9IHJlc29sdmVyOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlRyYW5zZm9ybWVyRmFjdG9yeSBpbXBsZW1lbnRhdGlvbi4KLSAgICAgKiBHZXQgdGhlIHN0eWxlc2hlZXQgc3BlY2lmaWNhdGlvbihzKSBhc3NvY2lhdGVkIHZpYSB0aGUgeG1sLXN0eWxlc2hlZXQKLSAgICAgKiBwcm9jZXNzaW5nIGluc3RydWN0aW9uIChzZWUgaHR0cDovL3d3dy53My5vcmcvVFIveG1sLXN0eWxlc2hlZXQvKSB3aXRoCi0gICAgICogdGhlIGRvY3VtZW50IGRvY3VtZW50IHNwZWNpZmllZCBpbiB0aGUgc291cmNlIHBhcmFtZXRlciwgYW5kIHRoYXQgbWF0Y2gKLSAgICAgKiB0aGUgZ2l2ZW4gY3JpdGVyaWEuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc291cmNlIFRoZSBYTUwgc291cmNlIGRvY3VtZW50LgotICAgICAqIEBwYXJhbSBtZWRpYSBUaGUgbWVkaWEgYXR0cmlidXRlIHRvIGJlIG1hdGNoZWQuIE1heSBiZSBudWxsLCBpbiB3aGljaAotICAgICAqIGNhc2UgdGhlIHByZWZlcmVkIHRlbXBsYXRlcyB3aWxsIGJlIHVzZWQgKGkuZS4gYWx0ZXJuYXRlID0gbm8pLgotICAgICAqIEBwYXJhbSB0aXRsZSBUaGUgdmFsdWUgb2YgdGhlIHRpdGxlIGF0dHJpYnV0ZSB0byBtYXRjaC4gTWF5IGJlIG51bGwuCi0gICAgICogQHBhcmFtIGNoYXJzZXQgVGhlIHZhbHVlIG9mIHRoZSBjaGFyc2V0IGF0dHJpYnV0ZSB0byBtYXRjaC4gTWF5IGJlIG51bGwuCi0gICAgICogQHJldHVybiBBIFNvdXJjZSBvYmplY3Qgc3VpdGFibGUgZm9yIHBhc3NpbmcgdG8gdGhlIFRyYW5zZm9ybWVyRmFjdG9yeS4KLSAgICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbgotICAgICAqLwotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyBTb3VyY2UgIGdldEFzc29jaWF0ZWRTdHlsZXNoZWV0KFNvdXJjZSBzb3VyY2UsIFN0cmluZyBtZWRpYSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyB0aXRsZSwgU3RyaW5nIGNoYXJzZXQpCi0gICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gewotCi0gICAgICAgIFN0cmluZyBiYXNlSWQ7Ci0gICAgICAgIFhNTFJlYWRlciByZWFkZXI7Ci0gICAgICAgIElucHV0U291cmNlIGlzb3VyY2U7Ci0KLQotICAgICAgICAvKioKLSAgICAgICAgICogRml4IGZvciBidWd6aWxsYSBidWcgMjQxODcKLSAgICAgICAgICovCi0gICAgICAgIFN0eWxlc2hlZXRQSUhhbmRsZXIgX3N0eWxlc2hlZXRQSUhhbmRsZXIgPSBuZXcgU3R5bGVzaGVldFBJSGFuZGxlcihudWxsLG1lZGlhLHRpdGxlLGNoYXJzZXQpOwotCi0gICAgICAgIHRyeSB7Ci0KLSAgICAgICAgICAgIGlmIChzb3VyY2UgaW5zdGFuY2VvZiBET01Tb3VyY2UgKSB7Ci0gICAgICAgICAgICAgICAgZmluYWwgRE9NU291cmNlIGRvbXNyYyA9IChET01Tb3VyY2UpIHNvdXJjZTsKLSAgICAgICAgICAgICAgICBiYXNlSWQgPSBkb21zcmMuZ2V0U3lzdGVtSWQoKTsKLSAgICAgICAgICAgICAgICBmaW5hbCBvcmcudzNjLmRvbS5Ob2RlIG5vZGUgPSBkb21zcmMuZ2V0Tm9kZSgpOwotICAgICAgICAgICAgICAgIGZpbmFsIERPTTJTQVggZG9tMnNheCA9IG5ldyBET00yU0FYKG5vZGUpOwotCi0gICAgICAgICAgICAgICAgX3N0eWxlc2hlZXRQSUhhbmRsZXIuc2V0QmFzZUlkKGJhc2VJZCk7Ci0KLSAgICAgICAgICAgICAgICBkb20yc2F4LnNldENvbnRlbnRIYW5kbGVyKCBfc3R5bGVzaGVldFBJSGFuZGxlcik7Ci0gICAgICAgICAgICAgICAgZG9tMnNheC5wYXJzZSgpOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBpc291cmNlID0gU0FYU291cmNlLnNvdXJjZVRvSW5wdXRTb3VyY2Uoc291cmNlKTsKLSAgICAgICAgICAgICAgICBiYXNlSWQgPSBpc291cmNlLmdldFN5c3RlbUlkKCk7Ci0KLSAgICAgICAgICAgICAgICBTQVhQYXJzZXJGYWN0b3J5IGZhY3RvcnkgPSBGYWN0b3J5SW1wbC5nZXRTQVhGYWN0b3J5KF91c2VTZXJ2aWNlc01lY2hhbmlzbSk7Ci0gICAgICAgICAgICAgICAgZmFjdG9yeS5zZXROYW1lc3BhY2VBd2FyZSh0cnVlKTsKLQotICAgICAgICAgICAgICAgIGlmICghX2lzTm90U2VjdXJlUHJvY2Vzc2luZykgewotICAgICAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICAgICAgZmFjdG9yeS5zZXRGZWF0dXJlKFhNTENvbnN0YW50cy5GRUFUVVJFX1NFQ1VSRV9QUk9DRVNTSU5HLCB0cnVlKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBjYXRjaCAob3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIGUpIHt9Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgU0FYUGFyc2VyIGpheHBQYXJzZXIgPSBmYWN0b3J5Lm5ld1NBWFBhcnNlcigpOwotCi0gICAgICAgICAgICAgICAgcmVhZGVyID0gamF4cFBhcnNlci5nZXRYTUxSZWFkZXIoKTsKLSAgICAgICAgICAgICAgICBpZiAocmVhZGVyID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgcmVhZGVyID0gWE1MUmVhZGVyRmFjdG9yeS5jcmVhdGVYTUxSZWFkZXIoKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBfc3R5bGVzaGVldFBJSGFuZGxlci5zZXRCYXNlSWQoYmFzZUlkKTsKLSAgICAgICAgICAgICAgICByZWFkZXIuc2V0Q29udGVudEhhbmRsZXIoX3N0eWxlc2hlZXRQSUhhbmRsZXIpOwotICAgICAgICAgICAgICAgIHJlYWRlci5wYXJzZShpc291cmNlKTsKLQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAoX3VyaVJlc29sdmVyICE9IG51bGwgKSB7Ci0gICAgICAgICAgICAgICAgX3N0eWxlc2hlZXRQSUhhbmRsZXIuc2V0VVJJUmVzb2x2ZXIoX3VyaVJlc29sdmVyKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICB9IGNhdGNoIChTdG9wUGFyc2VFeGNlcHRpb24gZSApIHsKLSAgICAgICAgICAvLyBzdGFydEVsZW1lbnQgZW5jb3VudGVyZWQgc28gZG8gbm90IHBhcnNlIGZ1cnRoZXIKLQotICAgICAgICB9IGNhdGNoIChqYXZheC54bWwucGFyc2Vycy5QYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIGUpIHsKLQotICAgICAgICAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24oCi0gICAgICAgICAgICAgImdldEFzc29jaWF0ZWRTdHlsZXNoZWV0cyBmYWlsZWQiLCBlKTsKLQotICAgICAgICB9IGNhdGNoIChvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gc2UpIHsKLQotICAgICAgICAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24oCi0gICAgICAgICAgICAgImdldEFzc29jaWF0ZWRTdHlsZXNoZWV0cyBmYWlsZWQiLCBzZSk7Ci0KLQotICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBpb2UgKSB7Ci0gICAgICAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24oCi0gICAgICAgICAgICJnZXRBc3NvY2lhdGVkU3R5bGVzaGVldHMgZmFpbGVkIiwgaW9lKTsKLQotICAgICAgICB9Ci0KLSAgICAgICAgIHJldHVybiBfc3R5bGVzaGVldFBJSGFuZGxlci5nZXRBc3NvY2lhdGVkU3R5bGVzaGVldCgpOwotCi0gICAgfQotCi0gICAgLyoqCi0gICAgICogamF2YXgueG1sLnRyYW5zZm9ybS5zYXguVHJhbnNmb3JtZXJGYWN0b3J5IGltcGxlbWVudGF0aW9uLgotICAgICAqIENyZWF0ZSBhIFRyYW5zZm9ybWVyIG9iamVjdCB0aGF0IGNvcGllcyB0aGUgaW5wdXQgZG9jdW1lbnQgdG8gdGhlIHJlc3VsdC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gQSBUcmFuc2Zvcm1lciBvYmplY3QgdGhhdCBzaW1wbHkgY29waWVzIHRoZSBzb3VyY2UgdG8gdGhlIHJlc3VsdC4KLSAgICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbgotICAgICAqLwotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyBUcmFuc2Zvcm1lciBuZXdUcmFuc2Zvcm1lcigpCi0gICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIFRyYW5zZm9ybWVySW1wbCByZXN1bHQgPSBuZXcgVHJhbnNmb3JtZXJJbXBsKG5ldyBQcm9wZXJ0aWVzKCksCi0gICAgICAgICAgICBfaW5kZW50TnVtYmVyLCB0aGlzKTsKLSAgICAgICAgaWYgKF91cmlSZXNvbHZlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXN1bHQuc2V0VVJJUmVzb2x2ZXIoX3VyaVJlc29sdmVyKTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmICghX2lzTm90U2VjdXJlUHJvY2Vzc2luZykgewotICAgICAgICAgICAgcmVzdWx0LnNldFNlY3VyZVByb2Nlc3NpbmcodHJ1ZSk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHJlc3VsdDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBqYXZheC54bWwudHJhbnNmb3JtLnNheC5UcmFuc2Zvcm1lckZhY3RvcnkgaW1wbGVtZW50YXRpb24uCi0gICAgICogUHJvY2VzcyB0aGUgU291cmNlIGludG8gYSBUZW1wbGF0ZXMgb2JqZWN0LCB3aGljaCBpcyBhIGEgY29tcGlsZWQKLSAgICAgKiByZXByZXNlbnRhdGlvbiBvZiB0aGUgc291cmNlLiBOb3RlIHRoYXQgdGhpcyBtZXRob2Qgc2hvdWxkIG5vdCBiZQotICAgICAqIHVzZWQgd2l0aCBYU0xUQywgYXMgdGhlIHRpbWUtY29uc3VtaW5nIGNvbXBpbGF0aW9uIGlzIGRvbmUgZm9yIGVhY2gKLSAgICAgKiBhbmQgZXZlcnkgdHJhbnNmb3JtYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIEEgVGVtcGxhdGVzIG9iamVjdCB0aGF0IGNhbiBiZSB1c2VkIHRvIGNyZWF0ZSBUcmFuc2Zvcm1lcnMuCi0gICAgICogQHRocm93cyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24KLSAgICAgKi8KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgVHJhbnNmb3JtZXIgbmV3VHJhbnNmb3JtZXIoU291cmNlIHNvdXJjZSkgdGhyb3dzCi0gICAgICAgIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgZmluYWwgVGVtcGxhdGVzIHRlbXBsYXRlcyA9IG5ld1RlbXBsYXRlcyhzb3VyY2UpOwotICAgICAgICBmaW5hbCBUcmFuc2Zvcm1lciB0cmFuc2Zvcm1lciA9IHRlbXBsYXRlcy5uZXdUcmFuc2Zvcm1lcigpOwotICAgICAgICBpZiAoX3VyaVJlc29sdmVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIHRyYW5zZm9ybWVyLnNldFVSSVJlc29sdmVyKF91cmlSZXNvbHZlcik7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuKHRyYW5zZm9ybWVyKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBQYXNzIHdhcm5pbmcgbWVzc2FnZXMgZnJvbSB0aGUgY29tcGlsZXIgdG8gdGhlIGVycm9yIGxpc3RlbmVyCi0gICAgICovCi0gICAgcHJpdmF0ZSB2b2lkIHBhc3NXYXJuaW5nc1RvTGlzdGVuZXIoQXJyYXlMaXN0PEVycm9yTXNnPiBtZXNzYWdlcykKLSAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAoX2Vycm9yTGlzdGVuZXIgPT0gbnVsbCB8fCBtZXNzYWdlcyA9PSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLSAgICAgICAgLy8gUGFzcyBtZXNzYWdlcyB0byBsaXN0ZW5lciwgb25lIGJ5IG9uZQotICAgICAgICBmaW5hbCBpbnQgY291bnQgPSBtZXNzYWdlcy5zaXplKCk7Ci0gICAgICAgIGZvciAoaW50IHBvcyA9IDA7IHBvcyA8IGNvdW50OyBwb3MrKykgewotICAgICAgICAgICAgRXJyb3JNc2cgbXNnID0gbWVzc2FnZXMuZ2V0KHBvcyk7Ci0gICAgICAgICAgICAvLyBXb3JrYXJvdW5kIGZvciB0aGUgVENLIGZhaWx1cmUgRXJyb3JMaXN0ZW5lci5lcnJvclRlc3RzLmVycm9yMDAxLgotICAgICAgICAgICAgaWYgKG1zZy5pc1dhcm5pbmdFcnJvcigpKQotICAgICAgICAgICAgICAgIF9lcnJvckxpc3RlbmVyLmVycm9yKAotICAgICAgICAgICAgICAgICAgICBuZXcgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uKG1zZy50b1N0cmluZygpKSk7Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgX2Vycm9yTGlzdGVuZXIud2FybmluZygKLSAgICAgICAgICAgICAgICAgICAgbmV3IFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbihtc2cudG9TdHJpbmcoKSkpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUGFzcyBlcnJvciBtZXNzYWdlcyBmcm9tIHRoZSBjb21waWxlciB0byB0aGUgZXJyb3IgbGlzdGVuZXIKLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgcGFzc0Vycm9yc1RvTGlzdGVuZXIoQXJyYXlMaXN0PEVycm9yTXNnPiBtZXNzYWdlcykgewotICAgICAgICB0cnkgewotICAgICAgICAgICAgaWYgKF9lcnJvckxpc3RlbmVyID09IG51bGwgfHwgbWVzc2FnZXMgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIFBhc3MgbWVzc2FnZXMgdG8gbGlzdGVuZXIsIG9uZSBieSBvbmUKLSAgICAgICAgICAgIGZpbmFsIGludCBjb3VudCA9IG1lc3NhZ2VzLnNpemUoKTsKLSAgICAgICAgICAgIGZvciAoaW50IHBvcyA9IDA7IHBvcyA8IGNvdW50OyBwb3MrKykgewotICAgICAgICAgICAgICAgIFN0cmluZyBtZXNzYWdlID0gbWVzc2FnZXMuZ2V0KHBvcykudG9TdHJpbmcoKTsKLSAgICAgICAgICAgICAgICBfZXJyb3JMaXN0ZW5lci5lcnJvcihuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24obWVzc2FnZSkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChUcmFuc2Zvcm1lckV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAvLyBuYWRhCi0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBqYXZheC54bWwudHJhbnNmb3JtLnNheC5UcmFuc2Zvcm1lckZhY3RvcnkgaW1wbGVtZW50YXRpb24uCi0gICAgICogUHJvY2VzcyB0aGUgU291cmNlIGludG8gYSBUZW1wbGF0ZXMgb2JqZWN0LCB3aGljaCBpcyBhIGEgY29tcGlsZWQKLSAgICAgKiByZXByZXNlbnRhdGlvbiBvZiB0aGUgc291cmNlLgotICAgICAqCi0gICAgICogQHBhcmFtIHNvdXJjZSBUaGUgaW5wdXQgc3R5bGVzaGVldCAtIERPTVNvdXJjZSBub3Qgc3VwcG9ydGVkISEhCi0gICAgICogQHJldHVybiBBIFRlbXBsYXRlcyBvYmplY3QgdGhhdCBjYW4gYmUgdXNlZCB0byBjcmVhdGUgVHJhbnNmb3JtZXJzLgotICAgICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uCi0gICAgICovCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIFRlbXBsYXRlcyBuZXdUZW1wbGF0ZXMoU291cmNlIHNvdXJjZSkKLSAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgLy8gSWYgdGhlIF91c2VDbGFzc3BhdGggYXR0cmlidXRlIGlzIHRydWUsIHRyeSB0byBsb2FkIHRoZSB0cmFuc2xldCBmcm9tCi0gICAgICAgIC8vIHRoZSBDTEFTU1BBVEggYW5kIGNyZWF0ZSBhIHRlbXBsYXRlIG9iamVjdCB1c2luZyB0aGUgbG9hZGVkCi0gICAgICAgIC8vIHRyYW5zbGV0LgotICAgICAgICBpZiAoX3VzZUNsYXNzcGF0aCkgewotICAgICAgICAgICAgU3RyaW5nIHRyYW5zbGV0TmFtZSA9IGdldFRyYW5zbGV0QmFzZU5hbWUoc291cmNlKTsKLQotICAgICAgICAgICAgaWYgKF9wYWNrYWdlTmFtZSAhPSBudWxsKQotICAgICAgICAgICAgICAgIHRyYW5zbGV0TmFtZSA9IF9wYWNrYWdlTmFtZSArICIuIiArIHRyYW5zbGV0TmFtZTsKLQotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICBmaW5hbCBDbGFzcyBjbGF6eiA9IE9iamVjdEZhY3RvcnkuZmluZFByb3ZpZGVyQ2xhc3ModHJhbnNsZXROYW1lLCB0cnVlKTsKLSAgICAgICAgICAgICAgICByZXNldFRyYW5zaWVudEF0dHJpYnV0ZXMoKTsKLQotICAgICAgICAgICAgICAgIHJldHVybiBuZXcgVGVtcGxhdGVzSW1wbChuZXcgQ2xhc3NbXXtjbGF6en0sIHRyYW5zbGV0TmFtZSwgbnVsbCwgX2luZGVudE51bWJlciwgdGhpcyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBjbmZlKSB7Ci0gICAgICAgICAgICAgICAgRXJyb3JNc2cgZXJyID0gbmV3IEVycm9yTXNnKEVycm9yTXNnLkNMQVNTX05PVF9GT1VORF9FUlIsIHRyYW5zbGV0TmFtZSk7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbihlcnIudG9TdHJpbmcoKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICBFcnJvck1zZyBlcnIgPSBuZXcgRXJyb3JNc2coCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IEVycm9yTXNnKEVycm9yTXNnLlJVTlRJTUVfRVJST1JfS0VZKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgZS5nZXRNZXNzYWdlKCkpOwotICAgICAgICAgICAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24oZXJyLnRvU3RyaW5nKCkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gSWYgX2F1dG9UcmFuc2xldCBpcyB0cnVlLCB3ZSB3aWxsIHRyeSB0byBsb2FkIHRoZSBieXRlY29kZXMKLSAgICAgICAgLy8gZnJvbSB0aGUgdHJhbnNsZXQgY2xhc3NlcyB3aXRob3V0IGNvbXBpbGluZyB0aGUgc3R5bGVzaGVldC4KLSAgICAgICAgaWYgKF9hdXRvVHJhbnNsZXQpICB7Ci0gICAgICAgICAgICBieXRlW11bXSBieXRlY29kZXM7Ci0gICAgICAgICAgICBTdHJpbmcgdHJhbnNsZXRDbGFzc05hbWUgPSBnZXRUcmFuc2xldEJhc2VOYW1lKHNvdXJjZSk7Ci0KLSAgICAgICAgICAgIGlmIChfcGFja2FnZU5hbWUgIT0gbnVsbCkKLSAgICAgICAgICAgICAgICB0cmFuc2xldENsYXNzTmFtZSA9IF9wYWNrYWdlTmFtZSArICIuIiArIHRyYW5zbGV0Q2xhc3NOYW1lOwotCi0gICAgICAgICAgICBpZiAoX2phckZpbGVOYW1lICE9IG51bGwpCi0gICAgICAgICAgICAgICAgYnl0ZWNvZGVzID0gZ2V0Qnl0ZWNvZGVzRnJvbUphcihzb3VyY2UsIHRyYW5zbGV0Q2xhc3NOYW1lKTsKLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICBieXRlY29kZXMgPSBnZXRCeXRlY29kZXNGcm9tQ2xhc3Nlcyhzb3VyY2UsIHRyYW5zbGV0Q2xhc3NOYW1lKTsKLQotICAgICAgICAgICAgaWYgKGJ5dGVjb2RlcyAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgaWYgKF9kZWJ1ZykgewotICAgICAgICAgICAgICAgICAgICBpZiAoX2phckZpbGVOYW1lICE9IG51bGwpCi0gICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4obmV3IEVycm9yTXNnKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVycm9yTXNnLlRSQU5TRk9STV9XSVRIX0pBUl9TVFIsIHRyYW5zbGV0Q2xhc3NOYW1lLCBfamFyRmlsZU5hbWUpKTsKLSAgICAgICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKG5ldyBFcnJvck1zZygKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBFcnJvck1zZy5UUkFOU0ZPUk1fV0lUSF9UUkFOU0xFVF9TVFIsIHRyYW5zbGV0Q2xhc3NOYW1lKSk7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgLy8gUmVzZXQgdGhlIHBlci1zZXNzaW9uIGF0dHJpYnV0ZXMgdG8gdGhlaXIgZGVmYXVsdCB2YWx1ZXMKLSAgICAgICAgICAgICAgICAvLyBhZnRlciBlYWNoIG5ld1RlbXBsYXRlcygpIGNhbGwuCi0gICAgICAgICAgICAgICAgcmVzZXRUcmFuc2llbnRBdHRyaWJ1dGVzKCk7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBUZW1wbGF0ZXNJbXBsKGJ5dGVjb2RlcywgdHJhbnNsZXRDbGFzc05hbWUsIG51bGwsIF9pbmRlbnROdW1iZXIsIHRoaXMpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gQ3JlYXRlIGFuZCBpbml0aWFsaXplIGEgc3R5bGVzaGVldCBjb21waWxlcgotICAgICAgICBmaW5hbCBYU0xUQyB4c2x0YyA9IG5ldyBYU0xUQyhfdXNlU2VydmljZXNNZWNoYW5pc20sIF9mZWF0dXJlTWFuYWdlcik7Ci0gICAgICAgIGlmIChfZGVidWcpIHhzbHRjLnNldERlYnVnKHRydWUpOwotICAgICAgICBpZiAoX2VuYWJsZUlubGluaW5nKQotICAgICAgICAgICAgICAgIHhzbHRjLnNldFRlbXBsYXRlSW5saW5pbmcodHJ1ZSk7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICB4c2x0Yy5zZXRUZW1wbGF0ZUlubGluaW5nKGZhbHNlKTsKLQotICAgICAgICBpZiAoIV9pc05vdFNlY3VyZVByb2Nlc3NpbmcpIHhzbHRjLnNldFNlY3VyZVByb2Nlc3NpbmcodHJ1ZSk7Ci0gICAgICAgIHhzbHRjLnNldFByb3BlcnR5KFhNTENvbnN0YW50cy5BQ0NFU1NfRVhURVJOQUxfU1RZTEVTSEVFVCwgX2FjY2Vzc0V4dGVybmFsU3R5bGVzaGVldCk7Ci0gICAgICAgIHhzbHRjLnNldFByb3BlcnR5KFhNTENvbnN0YW50cy5BQ0NFU1NfRVhURVJOQUxfRFRELCBfYWNjZXNzRXh0ZXJuYWxEVEQpOwotICAgICAgICB4c2x0Yy5zZXRQcm9wZXJ0eShYYWxhbkNvbnN0YW50cy5TRUNVUklUWV9NQU5BR0VSLCBfeG1sU2VjdXJpdHlNYW5hZ2VyKTsKLSAgICAgICAgeHNsdGMuc2V0UHJvcGVydHkoWGFsYW5Db25zdGFudHMuSkRLX0VYVEVOU0lPTl9DTEFTU0xPQURFUiwgX2V4dGVuc2lvbkNsYXNzTG9hZGVyKTsKLSAgICAgICAgeHNsdGMuaW5pdCgpOwotICAgICAgICBpZiAoIV9pc05vdFNlY3VyZVByb2Nlc3NpbmcpCi0gICAgICAgICAgICBfeHNsdGNFeHRlbnNpb25GdW5jdGlvbnMgPSB4c2x0Yy5nZXRFeHRlcm5hbEV4dGVuc2lvbkZ1bmN0aW9ucygpOwotICAgICAgICAvLyBTZXQgYSBkb2N1bWVudCBsb2FkZXIgKGZvciB4c2w6aW5jbHVkZS9pbXBvcnQpIGlmIGRlZmluZWQKLSAgICAgICAgaWYgKF91cmlSZXNvbHZlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICB4c2x0Yy5zZXRTb3VyY2VMb2FkZXIodGhpcyk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBQYXNzIHBhcmFtZXRlcnMgdG8gdGhlIFBhcnNlciB0byBtYWtlIHN1cmUgaXQgbG9jYXRlcyB0aGUgY29ycmVjdAotICAgICAgICAvLyA8P3htbC1zdHlsZXNoZWV0IC4uLj8+IFBJIGluIGFuIFhNTCBpbnB1dCBkb2N1bWVudAotICAgICAgICBpZiAoKF9waVBhcmFtcyAhPSBudWxsKSAmJiAoX3BpUGFyYW1zLmdldChzb3VyY2UpICE9IG51bGwpKSB7Ci0gICAgICAgICAgICAvLyBHZXQgdGhlIHBhcmFtZXRlcnMgZm9yIHRoaXMgU291cmNlIG9iamVjdAotICAgICAgICAgICAgUElQYXJhbVdyYXBwZXIgcCA9IF9waVBhcmFtcy5nZXQoc291cmNlKTsKLSAgICAgICAgICAgIC8vIFBhc3MgdGhlbSBvbiB0byB0aGUgY29tcGlsZXIgKHdoaWNoIHdpbGwgcGFzcyB0aGVuIHRvIHRoZSBwYXJzZXIpCi0gICAgICAgICAgICBpZiAocCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgeHNsdGMuc2V0UElQYXJhbWV0ZXJzKHAuX21lZGlhLCBwLl90aXRsZSwgcC5fY2hhcnNldCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBTZXQgdGhlIGF0dHJpYnV0ZXMgZm9yIHRyYW5zbGV0IGdlbmVyYXRpb24KLSAgICAgICAgaW50IG91dHB1dFR5cGUgPSBYU0xUQy5CWVRFQVJSQVlfT1VUUFVUOwotICAgICAgICBpZiAoX2dlbmVyYXRlVHJhbnNsZXQgfHwgX2F1dG9UcmFuc2xldCkgewotICAgICAgICAgICAgLy8gU2V0IHRoZSB0cmFuc2xldCBuYW1lCi0gICAgICAgICAgICB4c2x0Yy5zZXRDbGFzc05hbWUoZ2V0VHJhbnNsZXRCYXNlTmFtZShzb3VyY2UpKTsKLQotICAgICAgICAgICAgaWYgKF9kZXN0aW5hdGlvbkRpcmVjdG9yeSAhPSBudWxsKQotICAgICAgICAgICAgICAgIHhzbHRjLnNldERlc3REaXJlY3RvcnkoX2Rlc3RpbmF0aW9uRGlyZWN0b3J5KTsKLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIFN0cmluZyB4c2xOYW1lID0gZ2V0U3R5bGVzaGVldEZpbGVOYW1lKHNvdXJjZSk7Ci0gICAgICAgICAgICAgICAgaWYgKHhzbE5hbWUgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBGaWxlIHhzbEZpbGUgPSBuZXcgRmlsZSh4c2xOYW1lKTsKLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHhzbERpciA9IHhzbEZpbGUuZ2V0UGFyZW50KCk7Ci0KLSAgICAgICAgICAgICAgICAgICAgaWYgKHhzbERpciAhPSBudWxsKQotICAgICAgICAgICAgICAgICAgICAgICAgeHNsdGMuc2V0RGVzdERpcmVjdG9yeSh4c2xEaXIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKF9wYWNrYWdlTmFtZSAhPSBudWxsKQotICAgICAgICAgICAgICAgIHhzbHRjLnNldFBhY2thZ2VOYW1lKF9wYWNrYWdlTmFtZSk7Ci0KLSAgICAgICAgICAgIGlmIChfamFyRmlsZU5hbWUgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHhzbHRjLnNldEphckZpbGVOYW1lKF9qYXJGaWxlTmFtZSk7Ci0gICAgICAgICAgICAgICAgb3V0cHV0VHlwZSA9IFhTTFRDLkJZVEVBUlJBWV9BTkRfSkFSX09VVFBVVDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICBvdXRwdXRUeXBlID0gWFNMVEMuQllURUFSUkFZX0FORF9GSUxFX09VVFBVVDsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIENvbXBpbGUgdGhlIHN0eWxlc2hlZXQKLSAgICAgICAgZmluYWwgSW5wdXRTb3VyY2UgaW5wdXQgPSBVdGlsLmdldElucHV0U291cmNlKHhzbHRjLCBzb3VyY2UpOwotICAgICAgICBieXRlW11bXSBieXRlY29kZXMgPSB4c2x0Yy5jb21waWxlKG51bGwsIGlucHV0LCBvdXRwdXRUeXBlKTsKLSAgICAgICAgZmluYWwgU3RyaW5nIHRyYW5zbGV0TmFtZSA9IHhzbHRjLmdldENsYXNzTmFtZSgpOwotCi0gICAgICAgIC8vIE91dHB1dCB0byB0aGUgamFyIGZpbGUgaWYgdGhlIGphciBmaWxlIG5hbWUgaXMgc2V0LgotICAgICAgICBpZiAoKF9nZW5lcmF0ZVRyYW5zbGV0IHx8IF9hdXRvVHJhbnNsZXQpCi0gICAgICAgICAgICAgICAgJiYgYnl0ZWNvZGVzICE9IG51bGwgJiYgX2phckZpbGVOYW1lICE9IG51bGwpIHsKLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgeHNsdGMub3V0cHV0VG9KYXIoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gUmVzZXQgdGhlIHBlci1zZXNzaW9uIGF0dHJpYnV0ZXMgdG8gdGhlaXIgZGVmYXVsdCB2YWx1ZXMKLSAgICAgICAgLy8gYWZ0ZXIgZWFjaCBuZXdUZW1wbGF0ZXMoKSBjYWxsLgotICAgICAgICByZXNldFRyYW5zaWVudEF0dHJpYnV0ZXMoKTsKLQotICAgICAgICAvLyBQYXNzIGNvbXBpbGVyIHdhcm5pbmdzIHRvIHRoZSBlcnJvciBsaXN0ZW5lcgotICAgICAgICBpZiAoX2Vycm9yTGlzdGVuZXIgIT0gdGhpcykgewotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICBwYXNzV2FybmluZ3NUb0xpc3RlbmVyKHhzbHRjLmdldFdhcm5pbmdzKCkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2F0Y2ggKFRyYW5zZm9ybWVyRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uKGUpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgeHNsdGMucHJpbnRXYXJuaW5ncygpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gQ2hlY2sgdGhhdCB0aGUgdHJhbnNmb3JtYXRpb24gd2VudCB3ZWxsIGJlZm9yZSByZXR1cm5pbmcKLSAgICAgICAgaWYgKGJ5dGVjb2RlcyA9PSBudWxsKSB7Ci0gICAgICAgICAgICBBcnJheUxpc3Q8RXJyb3JNc2c+IGVycnMgPSB4c2x0Yy5nZXRFcnJvcnMoKTsKLSAgICAgICAgICAgIEVycm9yTXNnIGVycjsKLSAgICAgICAgICAgIGlmIChlcnJzICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBlcnIgPSBlcnJzLmdldChlcnJzLnNpemUoKSAtIDEpOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBlcnIgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuSkFYUF9DT01QSUxFX0VSUik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBUaHJvd2FibGUgY2F1c2UgPSBlcnIuZ2V0Q2F1c2UoKTsKLSAgICAgICAgICAgIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBleGM7Ci0gICAgICAgICAgICBpZiAoY2F1c2UgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGV4YyA9ICBuZXcgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uKGNhdXNlLmdldE1lc3NhZ2UoKSwgY2F1c2UpOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBleGMgPSAgbmV3IFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbihlcnIudG9TdHJpbmcoKSk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIFBhc3MgY29tcGlsZXIgZXJyb3JzIHRvIHRoZSBlcnJvciBsaXN0ZW5lcgotICAgICAgICAgICAgaWYgKF9lcnJvckxpc3RlbmVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBwYXNzRXJyb3JzVG9MaXN0ZW5lcih4c2x0Yy5nZXRFcnJvcnMoKSk7Ci0KLSAgICAgICAgICAgICAgICAvLyBBcyByZXF1aXJlZCBieSBUQ0sgMS4yLCBzZW5kIGEgZmF0YWxFcnJvciB0byB0aGUKLSAgICAgICAgICAgICAgICAvLyBlcnJvciBsaXN0ZW5lciBiZWNhdXNlIGNvbXBpbGF0aW9uIG9mIHRoZSBzdHlsZXNoZWV0Ci0gICAgICAgICAgICAgICAgLy8gZmFpbGVkIGFuZCBubyBmdXJ0aGVyIHByb2Nlc3Npbmcgd2lsbCBiZSBwb3NzaWJsZS4KLSAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICBfZXJyb3JMaXN0ZW5lci5mYXRhbEVycm9yKGV4Yyk7Ci0gICAgICAgICAgICAgICAgfSBjYXRjaCAoVHJhbnNmb3JtZXJFeGNlcHRpb24gdGUpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gd2VsbCwgd2UgdHJpZWQuCi0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICB4c2x0Yy5wcmludEVycm9ycygpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgdGhyb3cgZXhjOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIG5ldyBUZW1wbGF0ZXNJbXBsKGJ5dGVjb2RlcywgdHJhbnNsZXROYW1lLAotICAgICAgICAgICAgeHNsdGMuZ2V0T3V0cHV0UHJvcGVydGllcygpLCBfaW5kZW50TnVtYmVyLCB0aGlzKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBqYXZheC54bWwudHJhbnNmb3JtLnNheC5TQVhUcmFuc2Zvcm1lckZhY3RvcnkgaW1wbGVtZW50YXRpb24uCi0gICAgICogR2V0IGEgVGVtcGxhdGVzSGFuZGxlciBvYmplY3QgdGhhdCBjYW4gcHJvY2VzcyBTQVggQ29udGVudEhhbmRsZXIKLSAgICAgKiBldmVudHMgaW50byBhIFRlbXBsYXRlcyBvYmplY3QuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIEEgVGVtcGxhdGVzSGFuZGxlciBvYmplY3QgdGhhdCBjYW4gaGFuZGxlIFNBWCBldmVudHMKLSAgICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbgotICAgICAqLwotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyBUZW1wbGF0ZXNIYW5kbGVyIG5ld1RlbXBsYXRlc0hhbmRsZXIoKQotICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uCi0gICAgewotICAgICAgICBmaW5hbCBUZW1wbGF0ZXNIYW5kbGVySW1wbCBoYW5kbGVyID0KLSAgICAgICAgICAgIG5ldyBUZW1wbGF0ZXNIYW5kbGVySW1wbChfaW5kZW50TnVtYmVyLCB0aGlzKTsKLSAgICAgICAgaWYgKF91cmlSZXNvbHZlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBoYW5kbGVyLnNldFVSSVJlc29sdmVyKF91cmlSZXNvbHZlcik7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGhhbmRsZXI7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogamF2YXgueG1sLnRyYW5zZm9ybS5zYXguU0FYVHJhbnNmb3JtZXJGYWN0b3J5IGltcGxlbWVudGF0aW9uLgotICAgICAqIEdldCBhIFRyYW5zZm9ybWVySGFuZGxlciBvYmplY3QgdGhhdCBjYW4gcHJvY2VzcyBTQVggQ29udGVudEhhbmRsZXIKLSAgICAgKiBldmVudHMgaW50byBhIFJlc3VsdC4gVGhpcyBtZXRob2Qgd2lsbCByZXR1cm4gYSBwdXJlIGNvcHkgdHJhbnNmb3JtZXIuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIEEgVHJhbnNmb3JtZXJIYW5kbGVyIG9iamVjdCB0aGF0IGNhbiBoYW5kbGUgU0FYIGV2ZW50cwotICAgICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uCi0gICAgICovCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIFRyYW5zZm9ybWVySGFuZGxlciBuZXdUcmFuc2Zvcm1lckhhbmRsZXIoKQotICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uCi0gICAgewotICAgICAgICBmaW5hbCBUcmFuc2Zvcm1lciB0cmFuc2Zvcm1lciA9IG5ld1RyYW5zZm9ybWVyKCk7Ci0gICAgICAgIGlmIChfdXJpUmVzb2x2ZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgdHJhbnNmb3JtZXIuc2V0VVJJUmVzb2x2ZXIoX3VyaVJlc29sdmVyKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbmV3IFRyYW5zZm9ybWVySGFuZGxlckltcGwoKFRyYW5zZm9ybWVySW1wbCkgdHJhbnNmb3JtZXIpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlNBWFRyYW5zZm9ybWVyRmFjdG9yeSBpbXBsZW1lbnRhdGlvbi4KLSAgICAgKiBHZXQgYSBUcmFuc2Zvcm1lckhhbmRsZXIgb2JqZWN0IHRoYXQgY2FuIHByb2Nlc3MgU0FYIENvbnRlbnRIYW5kbGVyCi0gICAgICogZXZlbnRzIGludG8gYSBSZXN1bHQsIGJhc2VkIG9uIHRoZSB0cmFuc2Zvcm1hdGlvbiBpbnN0cnVjdGlvbnMKLSAgICAgKiBzcGVjaWZpZWQgYnkgdGhlIGFyZ3VtZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIHNyYyBUaGUgc291cmNlIG9mIHRoZSB0cmFuc2Zvcm1hdGlvbiBpbnN0cnVjdGlvbnMuCi0gICAgICogQHJldHVybiBBIFRyYW5zZm9ybWVySGFuZGxlciBvYmplY3QgdGhhdCBjYW4gaGFuZGxlIFNBWCBldmVudHMKLSAgICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbgotICAgICAqLwotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyBUcmFuc2Zvcm1lckhhbmRsZXIgbmV3VHJhbnNmb3JtZXJIYW5kbGVyKFNvdXJjZSBzcmMpCi0gICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGZpbmFsIFRyYW5zZm9ybWVyIHRyYW5zZm9ybWVyID0gbmV3VHJhbnNmb3JtZXIoc3JjKTsKLSAgICAgICAgaWYgKF91cmlSZXNvbHZlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICB0cmFuc2Zvcm1lci5zZXRVUklSZXNvbHZlcihfdXJpUmVzb2x2ZXIpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBuZXcgVHJhbnNmb3JtZXJIYW5kbGVySW1wbCgoVHJhbnNmb3JtZXJJbXBsKSB0cmFuc2Zvcm1lcik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogamF2YXgueG1sLnRyYW5zZm9ybS5zYXguU0FYVHJhbnNmb3JtZXJGYWN0b3J5IGltcGxlbWVudGF0aW9uLgotICAgICAqIEdldCBhIFRyYW5zZm9ybWVySGFuZGxlciBvYmplY3QgdGhhdCBjYW4gcHJvY2VzcyBTQVggQ29udGVudEhhbmRsZXIKLSAgICAgKiBldmVudHMgaW50byBhIFJlc3VsdCwgYmFzZWQgb24gdGhlIHRyYW5zZm9ybWF0aW9uIGluc3RydWN0aW9ucwotICAgICAqIHNwZWNpZmllZCBieSB0aGUgYXJndW1lbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdGVtcGxhdGVzIFJlcHJlc2VudHMgYSBwcmUtcHJvY2Vzc2VkIHN0eWxlc2hlZXQKLSAgICAgKiBAcmV0dXJuIEEgVHJhbnNmb3JtZXJIYW5kbGVyIG9iamVjdCB0aGF0IGNhbiBoYW5kbGUgU0FYIGV2ZW50cwotICAgICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uCi0gICAgICovCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIFRyYW5zZm9ybWVySGFuZGxlciBuZXdUcmFuc2Zvcm1lckhhbmRsZXIoVGVtcGxhdGVzIHRlbXBsYXRlcykKLSAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgZmluYWwgVHJhbnNmb3JtZXIgdHJhbnNmb3JtZXIgPSB0ZW1wbGF0ZXMubmV3VHJhbnNmb3JtZXIoKTsKLSAgICAgICAgZmluYWwgVHJhbnNmb3JtZXJJbXBsIGludGVybmFsID0gKFRyYW5zZm9ybWVySW1wbCl0cmFuc2Zvcm1lcjsKLSAgICAgICAgcmV0dXJuIG5ldyBUcmFuc2Zvcm1lckhhbmRsZXJJbXBsKGludGVybmFsKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBqYXZheC54bWwudHJhbnNmb3JtLnNheC5TQVhUcmFuc2Zvcm1lckZhY3RvcnkgaW1wbGVtZW50YXRpb24uCi0gICAgICogQ3JlYXRlIGFuIFhNTEZpbHRlciB0aGF0IHVzZXMgdGhlIGdpdmVuIHNvdXJjZSBhcyB0aGUKLSAgICAgKiB0cmFuc2Zvcm1hdGlvbiBpbnN0cnVjdGlvbnMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc3JjIFRoZSBzb3VyY2Ugb2YgdGhlIHRyYW5zZm9ybWF0aW9uIGluc3RydWN0aW9ucy4KLSAgICAgKiBAcmV0dXJuIEFuIFhNTEZpbHRlciBvYmplY3QsIG9yIG51bGwgaWYgdGhpcyBmZWF0dXJlIGlzIG5vdCBzdXBwb3J0ZWQuCi0gICAgICogQHRocm93cyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24KLSAgICAgKi8KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgWE1MRmlsdGVyIG5ld1hNTEZpbHRlcihTb3VyY2Ugc3JjKQotICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uCi0gICAgewotICAgICAgICBUZW1wbGF0ZXMgdGVtcGxhdGVzID0gbmV3VGVtcGxhdGVzKHNyYyk7Ci0gICAgICAgIGlmICh0ZW1wbGF0ZXMgPT0gbnVsbCkgcmV0dXJuIG51bGw7Ci0gICAgICAgIHJldHVybiBuZXdYTUxGaWx0ZXIodGVtcGxhdGVzKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBqYXZheC54bWwudHJhbnNmb3JtLnNheC5TQVhUcmFuc2Zvcm1lckZhY3RvcnkgaW1wbGVtZW50YXRpb24uCi0gICAgICogQ3JlYXRlIGFuIFhNTEZpbHRlciB0aGF0IHVzZXMgdGhlIGdpdmVuIHNvdXJjZSBhcyB0aGUKLSAgICAgKiB0cmFuc2Zvcm1hdGlvbiBpbnN0cnVjdGlvbnMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdGVtcGxhdGVzIFRoZSBzb3VyY2Ugb2YgdGhlIHRyYW5zZm9ybWF0aW9uIGluc3RydWN0aW9ucy4KLSAgICAgKiBAcmV0dXJuIEFuIFhNTEZpbHRlciBvYmplY3QsIG9yIG51bGwgaWYgdGhpcyBmZWF0dXJlIGlzIG5vdCBzdXBwb3J0ZWQuCi0gICAgICogQHRocm93cyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24KLSAgICAgKi8KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgWE1MRmlsdGVyIG5ld1hNTEZpbHRlcihUZW1wbGF0ZXMgdGVtcGxhdGVzKQotICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uCi0gICAgewotICAgICAgICB0cnkgewotICAgICAgICAgICAgcmV0dXJuIG5ldyBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMudHJheC5UckFYRmlsdGVyKHRlbXBsYXRlcyk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBlMSkgewotICAgICAgICAgICAgaWYgKF9lcnJvckxpc3RlbmVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICBfZXJyb3JMaXN0ZW5lci5mYXRhbEVycm9yKGUxKTsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGNhdGNoIChUcmFuc2Zvcm1lckV4Y2VwdGlvbiBlMikgewotICAgICAgICAgICAgICAgICAgICBuZXcgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uKGUyKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICB0aHJvdyBlMTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGEgcmVjb3ZlcmFibGUgZXJyb3IuCi0gICAgICogVGhlIHRyYW5zZm9ybWVyIG11c3QgY29udGludWUgdG8gcHJvdmlkZSBub3JtYWwgcGFyc2luZyBldmVudHMgYWZ0ZXIKLSAgICAgKiBpbnZva2luZyB0aGlzIG1ldGhvZC4gSXQgc2hvdWxkIHN0aWxsIGJlIHBvc3NpYmxlIGZvciB0aGUgYXBwbGljYXRpb24KLSAgICAgKiB0byBwcm9jZXNzIHRoZSBkb2N1bWVudCB0aHJvdWdoIHRvIHRoZSBlbmQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZSBUaGUgd2FybmluZyBpbmZvcm1hdGlvbiBlbmNhcHN1bGF0ZWQgaW4gYSB0cmFuc2Zvcm1lcgotICAgICAqIGV4Y2VwdGlvbi4KLSAgICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uIGlmIHRoZSBhcHBsaWNhdGlvbiBjaG9vc2VzIHRvIGRpc2NvbnRpbnVlCi0gICAgICogdGhlIHRyYW5zZm9ybWF0aW9uIChhbHdheXMgZG9lcyBpbiBvdXIgY2FzZSkuCi0gICAgICovCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIHZvaWQgZXJyb3IoVHJhbnNmb3JtZXJFeGNlcHRpb24gZSkKLSAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAgewotICAgICAgICBUaHJvd2FibGUgd3JhcHBlZCA9IGUuZ2V0RXhjZXB0aW9uKCk7Ci0gICAgICAgIGlmICh3cmFwcGVkICE9IG51bGwpIHsKLSAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbihuZXcgRXJyb3JNc2coRXJyb3JNc2cuRVJST1JfUExVU19XUkFQUEVEX01TRywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZS5nZXRNZXNzYWdlQW5kTG9jYXRpb24oKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd3JhcHBlZC5nZXRNZXNzYWdlKCkpKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbihuZXcgRXJyb3JNc2coRXJyb3JNc2cuRVJST1JfTVNHLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlLmdldE1lc3NhZ2VBbmRMb2NhdGlvbigpKSk7Ci0gICAgICAgIH0KLSAgICAgICAgdGhyb3cgZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBhIG5vbi1yZWNvdmVyYWJsZSBlcnJvci4KLSAgICAgKiBUaGUgYXBwbGljYXRpb24gbXVzdCBhc3N1bWUgdGhhdCB0aGUgdHJhbnNmb3JtYXRpb24gY2Fubm90IGNvbnRpbnVlCi0gICAgICogYWZ0ZXIgdGhlIFRyYW5zZm9ybWVyIGhhcyBpbnZva2VkIHRoaXMgbWV0aG9kLCBhbmQgc2hvdWxkIGNvbnRpbnVlCi0gICAgICogKGlmIGF0IGFsbCkgb25seSB0byBjb2xsZWN0IGFkZGl0aW9uIGVycm9yIG1lc3NhZ2VzLiBJbiBmYWN0LAotICAgICAqIFRyYW5zZm9ybWVycyBhcmUgZnJlZSB0byBzdG9wIHJlcG9ydGluZyBldmVudHMgb25jZSB0aGlzIG1ldGhvZCBoYXMKLSAgICAgKiBiZWVuIGludm9rZWQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZSB3YXJuaW5nIGluZm9ybWF0aW9uIGVuY2Fwc3VsYXRlZCBpbiBhIHRyYW5zZm9ybWVyCi0gICAgICogZXhjZXB0aW9uLgotICAgICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24gaWYgdGhlIGFwcGxpY2F0aW9uIGNob29zZXMgdG8gZGlzY29udGludWUKLSAgICAgKiB0aGUgdHJhbnNmb3JtYXRpb24gKGFsd2F5cyBkb2VzIGluIG91ciBjYXNlKS4KLSAgICAgKi8KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgdm9pZCBmYXRhbEVycm9yKFRyYW5zZm9ybWVyRXhjZXB0aW9uIGUpCi0gICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgVGhyb3dhYmxlIHdyYXBwZWQgPSBlLmdldEV4Y2VwdGlvbigpOwotICAgICAgICBpZiAod3JhcHBlZCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4obmV3IEVycm9yTXNnKEVycm9yTXNnLkZBVEFMX0VSUl9QTFVTX1dSQVBQRURfTVNHLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlLmdldE1lc3NhZ2VBbmRMb2NhdGlvbigpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cmFwcGVkLmdldE1lc3NhZ2UoKSkpOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKG5ldyBFcnJvck1zZyhFcnJvck1zZy5GQVRBTF9FUlJfTVNHLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlLmdldE1lc3NhZ2VBbmRMb2NhdGlvbigpKSk7Ci0gICAgICAgIH0KLSAgICAgICAgdGhyb3cgZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBhIHdhcm5pbmcuCi0gICAgICogVHJhbnNmb3JtZXJzIGNhbiB1c2UgdGhpcyBtZXRob2QgdG8gcmVwb3J0IGNvbmRpdGlvbnMgdGhhdCBhcmUgbm90Ci0gICAgICogZXJyb3JzIG9yIGZhdGFsIGVycm9ycy4gVGhlIGRlZmF1bHQgYmVoYXZpb3VyIGlzIHRvIHRha2Ugbm8gYWN0aW9uLgotICAgICAqIEFmdGVyIGludm9raW5nIHRoaXMgbWV0aG9kLCB0aGUgVHJhbnNmb3JtZXIgbXVzdCBjb250aW51ZSB3aXRoIHRoZQotICAgICAqIHRyYW5zZm9ybWF0aW9uLiBJdCBzaG91bGQgc3RpbGwgYmUgcG9zc2libGUgZm9yIHRoZSBhcHBsaWNhdGlvbiB0bwotICAgICAqIHByb2Nlc3MgdGhlIGRvY3VtZW50IHRocm91Z2ggdG8gdGhlIGVuZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlIFRoZSB3YXJuaW5nIGluZm9ybWF0aW9uIGVuY2Fwc3VsYXRlZCBpbiBhIHRyYW5zZm9ybWVyCi0gICAgICogZXhjZXB0aW9uLgotICAgICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24gaWYgdGhlIGFwcGxpY2F0aW9uIGNob29zZXMgdG8gZGlzY29udGludWUKLSAgICAgKiB0aGUgdHJhbnNmb3JtYXRpb24gKG5ldmVyIGRvZXMgaW4gb3VyIGNhc2UpLgotICAgICAqLwotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyB2b2lkIHdhcm5pbmcoVHJhbnNmb3JtZXJFeGNlcHRpb24gZSkKLSAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAgewotICAgICAgICBUaHJvd2FibGUgd3JhcHBlZCA9IGUuZ2V0RXhjZXB0aW9uKCk7Ci0gICAgICAgIGlmICh3cmFwcGVkICE9IG51bGwpIHsKLSAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbihuZXcgRXJyb3JNc2coRXJyb3JNc2cuV0FSTklOR19QTFVTX1dSQVBQRURfTVNHLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlLmdldE1lc3NhZ2VBbmRMb2NhdGlvbigpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cmFwcGVkLmdldE1lc3NhZ2UoKSkpOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKG5ldyBFcnJvck1zZyhFcnJvck1zZy5XQVJOSU5HX01TRywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZS5nZXRNZXNzYWdlQW5kTG9jYXRpb24oKSkpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgaW1wbGVtZW50cyBYU0xUQydzIFNvdXJjZUxvYWRlciBpbnRlcmZhY2UuIEl0IGlzIHVzZWQgdG8KLSAgICAgKiBnbHVlIGEgVHJBWCBVUklSZXNvbHZlciB0byB0aGUgWFNMVEMgY29tcGlsZXIncyBJbnB1dCBhbmQgSW1wb3J0IGNsYXNzZXMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaHJlZiBUaGUgVVJJIG9mIHRoZSBkb2N1bWVudCB0byBsb2FkCi0gICAgICogQHBhcmFtIGNvbnRleHQgVGhlIFVSSSBvZiB0aGUgY3VycmVudGx5IGxvYWRlZCBkb2N1bWVudAotICAgICAqIEBwYXJhbSB4c2x0YyBUaGUgY29tcGlsZXIgdGhhdCByZXN1ZXN0cyB0aGUgZG9jdW1lbnQKLSAgICAgKiBAcmV0dXJuIEFuIElucHV0U291cmNlIHdpdGggdGhlIGxvYWRlZCBkb2N1bWVudAotICAgICAqLwotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyBJbnB1dFNvdXJjZSBsb2FkU291cmNlKFN0cmluZyBocmVmLCBTdHJpbmcgY29udGV4dCwgWFNMVEMgeHNsdGMpIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGlmIChfdXJpUmVzb2x2ZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZpbmFsIFNvdXJjZSBzb3VyY2UgPSBfdXJpUmVzb2x2ZXIucmVzb2x2ZShocmVmLCBjb250ZXh0KTsKLSAgICAgICAgICAgICAgICBpZiAoc291cmNlICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFV0aWwuZ2V0SW5wdXRTb3VyY2UoeHNsdGMsIHNvdXJjZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChUcmFuc2Zvcm1lckV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAvLyBzaG91bGQgY2F0Y2ggaXQgd2hlbiB0aGUgcmVzb2x2ZXIgZXhwbGljaXRseSB0aHJvd3MgdGhlIGV4Y2VwdGlvbgotICAgICAgICAgICAgZmluYWwgRXJyb3JNc2cgbXNnID0gbmV3IEVycm9yTXNnKEVycm9yTXNnLklOVkFMSURfVVJJX0VSUiwgaHJlZiArICJcbiIgKyBlLmdldE1lc3NhZ2UoKSwgdGhpcyk7Ci0gICAgICAgICAgICB4c2x0Yy5nZXRQYXJzZXIoKS5yZXBvcnRFcnJvcihDb25zdGFudHMuRkFUQUwsIG1zZyk7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXNldCB0aGUgcGVyLXNlc3Npb24gYXR0cmlidXRlcyB0byB0aGVpciBkZWZhdWx0IHZhbHVlcwotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCByZXNldFRyYW5zaWVudEF0dHJpYnV0ZXMoKSB7Ci0gICAgICAgIF90cmFuc2xldE5hbWUgPSBERUZBVUxUX1RSQU5TTEVUX05BTUU7Ci0gICAgICAgIF9kZXN0aW5hdGlvbkRpcmVjdG9yeSA9IG51bGw7Ci0gICAgICAgIF9wYWNrYWdlTmFtZSA9IG51bGw7Ci0gICAgICAgIF9qYXJGaWxlTmFtZSA9IG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogTG9hZCB0aGUgdHJhbnNsZXQgY2xhc3NlcyBmcm9tIGxvY2FsIC5jbGFzcyBmaWxlcyBhbmQgcmV0dXJuCi0gICAgICogdGhlIGJ5dGVjb2RlIGFycmF5LgotICAgICAqCi0gICAgICogQHBhcmFtIHNvdXJjZSBUaGUgeHNsIHNvdXJjZQotICAgICAqIEBwYXJhbSBmdWxsQ2xhc3NOYW1lIFRoZSBmdWxsIG5hbWUgb2YgdGhlIHRyYW5zbGV0Ci0gICAgICogQHJldHVybiBUaGUgYnl0ZWNvZGUgYXJyYXkKLSAgICAgKi8KLSAgICBwcml2YXRlIGJ5dGVbXVtdIGdldEJ5dGVjb2Rlc0Zyb21DbGFzc2VzKFNvdXJjZSBzb3VyY2UsIFN0cmluZyBmdWxsQ2xhc3NOYW1lKQotICAgIHsKLSAgICAgICAgaWYgKGZ1bGxDbGFzc05hbWUgPT0gbnVsbCkKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotCi0gICAgICAgIFN0cmluZyB4c2xGaWxlTmFtZSA9IGdldFN0eWxlc2hlZXRGaWxlTmFtZShzb3VyY2UpOwotICAgICAgICBGaWxlIHhzbEZpbGUgPSBudWxsOwotICAgICAgICBpZiAoeHNsRmlsZU5hbWUgIT0gbnVsbCkKLSAgICAgICAgICAgIHhzbEZpbGUgPSBuZXcgRmlsZSh4c2xGaWxlTmFtZSk7Ci0KLSAgICAgICAgLy8gRmluZCB0aGUgYmFzZSBuYW1lIG9mIHRoZSB0cmFuc2xldAotICAgICAgICBmaW5hbCBTdHJpbmcgdHJhbnNsZXROYW1lOwotICAgICAgICBpbnQgbGFzdERvdEluZGV4ID0gZnVsbENsYXNzTmFtZS5sYXN0SW5kZXhPZignLicpOwotICAgICAgICBpZiAobGFzdERvdEluZGV4ID4gMCkKLSAgICAgICAgICAgIHRyYW5zbGV0TmFtZSA9IGZ1bGxDbGFzc05hbWUuc3Vic3RyaW5nKGxhc3REb3RJbmRleCsxKTsKLSAgICAgICAgZWxzZQotICAgICAgICAgICAgdHJhbnNsZXROYW1lID0gZnVsbENsYXNzTmFtZTsKLQotICAgICAgICAvLyBDb25zdHJ1Y3QgdGhlIHBhdGggbmFtZSBmb3IgdGhlIHRyYW5zbGV0IGNsYXNzIGZpbGUKLSAgICAgICAgU3RyaW5nIHRyYW5zbGV0UGF0aCA9IGZ1bGxDbGFzc05hbWUucmVwbGFjZSgnLicsICcvJyk7Ci0gICAgICAgIGlmIChfZGVzdGluYXRpb25EaXJlY3RvcnkgIT0gbnVsbCkgewotICAgICAgICAgICAgdHJhbnNsZXRQYXRoID0gX2Rlc3RpbmF0aW9uRGlyZWN0b3J5ICsgIi8iICsgdHJhbnNsZXRQYXRoICsgIi5jbGFzcyI7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBpZiAoeHNsRmlsZSAhPSBudWxsICYmIHhzbEZpbGUuZ2V0UGFyZW50KCkgIT0gbnVsbCkKLSAgICAgICAgICAgICAgICB0cmFuc2xldFBhdGggPSB4c2xGaWxlLmdldFBhcmVudCgpICsgIi8iICsgdHJhbnNsZXRQYXRoICsgIi5jbGFzcyI7Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgdHJhbnNsZXRQYXRoID0gdHJhbnNsZXRQYXRoICsgIi5jbGFzcyI7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBSZXR1cm4gbnVsbCBpZiB0aGUgdHJhbnNsZXQgY2xhc3MgZmlsZSBkb2VzIG5vdCBleGlzdC4KLSAgICAgICAgRmlsZSB0cmFuc2xldEZpbGUgPSBuZXcgRmlsZSh0cmFuc2xldFBhdGgpOwotICAgICAgICBpZiAoIXRyYW5zbGV0RmlsZS5leGlzdHMoKSkKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotCi0gICAgICAgIC8vIENvbXBhcmUgdGhlIHRpbWVzdGFtcHMgb2YgdGhlIHRyYW5zbGV0IGFuZCB0aGUgeHNsIGZpbGUuCi0gICAgICAgIC8vIElmIHRoZSB0cmFuc2xldCBpcyBvbGRlciB0aGFuIHRoZSB4c2wgZmlsZSwgcmV0dXJuIG51bGwKLSAgICAgICAgLy8gc28gdGhhdCB0aGUgeHNsIGZpbGUgaXMgdXNlZCBmb3IgdGhlIHRyYW5zZm9ybWF0aW9uIGFuZAotICAgICAgICAvLyB0aGUgdHJhbnNsZXQgaXMgcmVnZW5lcmF0ZWQuCi0gICAgICAgIGlmICh4c2xGaWxlICE9IG51bGwgJiYgeHNsRmlsZS5leGlzdHMoKSkgewotICAgICAgICAgICAgbG9uZyB4c2xUaW1lc3RhbXAgPSB4c2xGaWxlLmxhc3RNb2RpZmllZCgpOwotICAgICAgICAgICAgbG9uZyB0cmFuc2xldFRpbWVzdGFtcCA9IHRyYW5zbGV0RmlsZS5sYXN0TW9kaWZpZWQoKTsKLSAgICAgICAgICAgIGlmICh0cmFuc2xldFRpbWVzdGFtcCA8IHhzbFRpbWVzdGFtcCkKLSAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIExvYWQgdGhlIHRyYW5zbGV0IGludG8gYSBieXRlY29kZSBhcnJheS4KLSAgICAgICAgVmVjdG9yIGJ5dGVjb2RlcyA9IG5ldyBWZWN0b3IoKTsKLSAgICAgICAgaW50IGZpbGVMZW5ndGggPSAoaW50KXRyYW5zbGV0RmlsZS5sZW5ndGgoKTsKLSAgICAgICAgaWYgKGZpbGVMZW5ndGggPiAwKSB7Ci0gICAgICAgICAgICBGaWxlSW5wdXRTdHJlYW0gaW5wdXQ7Ci0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIGlucHV0ID0gbmV3IEZpbGVJbnB1dFN0cmVhbSh0cmFuc2xldEZpbGUpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2F0Y2ggKEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGJ5dGVbXSBieXRlcyA9IG5ldyBieXRlW2ZpbGVMZW5ndGhdOwotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICByZWFkRnJvbUlucHV0U3RyZWFtKGJ5dGVzLCBpbnB1dCwgZmlsZUxlbmd0aCk7Ci0gICAgICAgICAgICAgICAgaW5wdXQuY2xvc2UoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGJ5dGVjb2Rlcy5hZGRFbGVtZW50KGJ5dGVzKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLQotICAgICAgICAvLyBGaW5kIHRoZSBwYXJlbnQgZGlyZWN0b3J5IG9mIHRoZSB0cmFuc2xldC4KLSAgICAgICAgU3RyaW5nIHRyYW5zbGV0UGFyZW50RGlyID0gdHJhbnNsZXRGaWxlLmdldFBhcmVudCgpOwotICAgICAgICBpZiAodHJhbnNsZXRQYXJlbnREaXIgPT0gbnVsbCkKLSAgICAgICAgICAgIHRyYW5zbGV0UGFyZW50RGlyID0gU2VjdXJpdHlTdXBwb3J0LmdldFN5c3RlbVByb3BlcnR5KCJ1c2VyLmRpciIpOwotCi0gICAgICAgIEZpbGUgdHJhbnNsZXRQYXJlbnRGaWxlID0gbmV3IEZpbGUodHJhbnNsZXRQYXJlbnREaXIpOwotCi0gICAgICAgIC8vIEZpbmQgYWxsIHRoZSBhdXhpbGlhcnkgZmlsZXMgd2hpY2ggaGF2ZSBhIG5hbWUgcGF0dGVybiBvZiAidHJhbnNsZXRDbGFzcyRubm4uY2xhc3MiLgotICAgICAgICBmaW5hbCBTdHJpbmcgdHJhbnNsZXRBdXhQcmVmaXggPSB0cmFuc2xldE5hbWUgKyAiJCI7Ci0gICAgICAgIEZpbGVbXSBhdXhmaWxlcyA9IHRyYW5zbGV0UGFyZW50RmlsZS5saXN0RmlsZXMobmV3IEZpbGVuYW1lRmlsdGVyKCkgewotICAgICAgICAgICAgICAgIEBPdmVycmlkZQotICAgICAgICAgICAgICAgIHB1YmxpYyBib29sZWFuIGFjY2VwdChGaWxlIGRpciwgU3RyaW5nIG5hbWUpCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gKG5hbWUuZW5kc1dpdGgoIi5jbGFzcyIpICYmIG5hbWUuc3RhcnRzV2l0aCh0cmFuc2xldEF1eFByZWZpeCkpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgfSk7Ci0KLSAgICAgICAgLy8gTG9hZCB0aGUgYXV4aWxpYXJ5IGNsYXNzIGZpbGVzIGFuZCBhZGQgdGhlbSB0byB0aGUgYnl0ZWNvZGUgYXJyYXkuCi0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYXV4ZmlsZXMubGVuZ3RoOyBpKyspCi0gICAgICAgIHsKLSAgICAgICAgICAgIEZpbGUgYXV4ZmlsZSA9IGF1eGZpbGVzW2ldOwotICAgICAgICAgICAgaW50IGF1eGxlbmd0aCA9IChpbnQpYXV4ZmlsZS5sZW5ndGgoKTsKLSAgICAgICAgICAgIGlmIChhdXhsZW5ndGggPiAwKSB7Ci0gICAgICAgICAgICAgICAgRmlsZUlucHV0U3RyZWFtIGF1eGlucHV0ID0gbnVsbDsKLSAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICBhdXhpbnB1dCA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oYXV4ZmlsZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGNhdGNoIChGaWxlTm90Rm91bmRFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBieXRlW10gYnl0ZXMgPSBuZXcgYnl0ZVthdXhsZW5ndGhdOwotCi0gICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgcmVhZEZyb21JbnB1dFN0cmVhbShieXRlcywgYXV4aW5wdXQsIGF1eGxlbmd0aCk7Ci0gICAgICAgICAgICAgICAgICAgIGF1eGlucHV0LmNsb3NlKCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIGJ5dGVjb2Rlcy5hZGRFbGVtZW50KGJ5dGVzKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIENvbnZlcnQgdGhlIFZlY3RvciBvZiBieXRlW10gdG8gYnl0ZVtdW10uCi0gICAgICAgIGZpbmFsIGludCBjb3VudCA9IGJ5dGVjb2Rlcy5zaXplKCk7Ci0gICAgICAgIGlmICggY291bnQgPiAwKSB7Ci0gICAgICAgICAgICBmaW5hbCBieXRlW11bXSByZXN1bHQgPSBuZXcgYnl0ZVtjb3VudF1bMV07Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKLSAgICAgICAgICAgICAgICByZXN1bHRbaV0gPSAoYnl0ZVtdKWJ5dGVjb2Rlcy5lbGVtZW50QXQoaSk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIHJldHVybiByZXN1bHQ7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogTG9hZCB0aGUgdHJhbnNsZXQgY2xhc3NlcyBmcm9tIHRoZSBqYXIgZmlsZSBhbmQgcmV0dXJuIHRoZSBieXRlY29kZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzb3VyY2UgVGhlIHhzbCBzb3VyY2UKLSAgICAgKiBAcGFyYW0gZnVsbENsYXNzTmFtZSBUaGUgZnVsbCBuYW1lIG9mIHRoZSB0cmFuc2xldAotICAgICAqIEByZXR1cm4gVGhlIGJ5dGVjb2RlIGFycmF5Ci0gICAgICovCi0gICAgcHJpdmF0ZSBieXRlW11bXSBnZXRCeXRlY29kZXNGcm9tSmFyKFNvdXJjZSBzb3VyY2UsIFN0cmluZyBmdWxsQ2xhc3NOYW1lKQotICAgIHsKLSAgICAgICAgU3RyaW5nIHhzbEZpbGVOYW1lID0gZ2V0U3R5bGVzaGVldEZpbGVOYW1lKHNvdXJjZSk7Ci0gICAgICAgIEZpbGUgeHNsRmlsZSA9IG51bGw7Ci0gICAgICAgIGlmICh4c2xGaWxlTmFtZSAhPSBudWxsKQotICAgICAgICAgICAgeHNsRmlsZSA9IG5ldyBGaWxlKHhzbEZpbGVOYW1lKTsKLQotICAgICAgICAvLyBDb25zdHJ1Y3QgdGhlIHBhdGggZm9yIHRoZSBqYXIgZmlsZQotICAgICAgICBTdHJpbmcgamFyUGF0aDsKLSAgICAgICAgaWYgKF9kZXN0aW5hdGlvbkRpcmVjdG9yeSAhPSBudWxsKQotICAgICAgICAgICAgamFyUGF0aCA9IF9kZXN0aW5hdGlvbkRpcmVjdG9yeSArICIvIiArIF9qYXJGaWxlTmFtZTsKLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBpZiAoeHNsRmlsZSAhPSBudWxsICYmIHhzbEZpbGUuZ2V0UGFyZW50KCkgIT0gbnVsbCkKLSAgICAgICAgICAgICAgICBqYXJQYXRoID0geHNsRmlsZS5nZXRQYXJlbnQoKSArICIvIiArIF9qYXJGaWxlTmFtZTsKLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICBqYXJQYXRoID0gX2phckZpbGVOYW1lOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gUmV0dXJuIG51bGwgaWYgdGhlIGphciBmaWxlIGRvZXMgbm90IGV4aXN0LgotICAgICAgICBGaWxlIGZpbGUgPSBuZXcgRmlsZShqYXJQYXRoKTsKLSAgICAgICAgaWYgKCFmaWxlLmV4aXN0cygpKQotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0KLSAgICAgICAgLy8gQ29tcGFyZSB0aGUgdGltZXN0YW1wcyBvZiB0aGUgamFyIGZpbGUgYW5kIHRoZSB4c2wgZmlsZS4gUmV0dXJuIG51bGwKLSAgICAgICAgLy8gaWYgdGhlIHhzbCBmaWxlIGlzIG5ld2VyIHRoYW4gdGhlIGphciBmaWxlLgotICAgICAgICBpZiAoeHNsRmlsZSAhPSBudWxsICYmIHhzbEZpbGUuZXhpc3RzKCkpIHsKLSAgICAgICAgICAgIGxvbmcgeHNsVGltZXN0YW1wID0geHNsRmlsZS5sYXN0TW9kaWZpZWQoKTsKLSAgICAgICAgICAgIGxvbmcgdHJhbnNsZXRUaW1lc3RhbXAgPSBmaWxlLmxhc3RNb2RpZmllZCgpOwotICAgICAgICAgICAgaWYgKHRyYW5zbGV0VGltZXN0YW1wIDwgeHNsVGltZXN0YW1wKQotICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gQ3JlYXRlIGEgWmlwRmlsZSBvYmplY3QgZm9yIHRoZSBqYXIgZmlsZQotICAgICAgICBaaXBGaWxlIGphckZpbGU7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBqYXJGaWxlID0gbmV3IFppcEZpbGUoZmlsZSk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0KLSAgICAgICAgU3RyaW5nIHRyYW5zbGV0UGF0aCA9IGZ1bGxDbGFzc05hbWUucmVwbGFjZSgnLicsICcvJyk7Ci0gICAgICAgIFN0cmluZyB0cmFuc2xldEF1eFByZWZpeCA9IHRyYW5zbGV0UGF0aCArICIkIjsKLSAgICAgICAgU3RyaW5nIHRyYW5zbGV0RnVsbE5hbWUgPSB0cmFuc2xldFBhdGggKyAiLmNsYXNzIjsKLQotICAgICAgICBWZWN0b3IgYnl0ZWNvZGVzID0gbmV3IFZlY3RvcigpOwotCi0gICAgICAgIC8vIEl0ZXJhdGUgdGhyb3VnaCBhbGwgZW50cmllcyBpbiB0aGUgamFyIGZpbGUgdG8gZmluZCB0aGUKLSAgICAgICAgLy8gdHJhbnNsZXQgYW5kIGF1eGlsaWFyeSBjbGFzc2VzLgotICAgICAgICBFbnVtZXJhdGlvbiBlbnRyaWVzID0gamFyRmlsZS5lbnRyaWVzKCk7Ci0gICAgICAgIHdoaWxlIChlbnRyaWVzLmhhc01vcmVFbGVtZW50cygpKQotICAgICAgICB7Ci0gICAgICAgICAgICBaaXBFbnRyeSBlbnRyeSA9IChaaXBFbnRyeSllbnRyaWVzLm5leHRFbGVtZW50KCk7Ci0gICAgICAgICAgICBTdHJpbmcgZW50cnlOYW1lID0gZW50cnkuZ2V0TmFtZSgpOwotICAgICAgICAgICAgaWYgKGVudHJ5LmdldFNpemUoKSA+IDAgJiYKLSAgICAgICAgICAgICAgICAgIChlbnRyeU5hbWUuZXF1YWxzKHRyYW5zbGV0RnVsbE5hbWUpIHx8Ci0gICAgICAgICAgICAgICAgICAoZW50cnlOYW1lLmVuZHNXaXRoKCIuY2xhc3MiKSAmJgotICAgICAgICAgICAgICAgICAgICAgIGVudHJ5TmFtZS5zdGFydHNXaXRoKHRyYW5zbGV0QXV4UHJlZml4KSkpKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgIElucHV0U3RyZWFtIGlucHV0ID0gamFyRmlsZS5nZXRJbnB1dFN0cmVhbShlbnRyeSk7Ci0gICAgICAgICAgICAgICAgICAgIGludCBzaXplID0gKGludCllbnRyeS5nZXRTaXplKCk7Ci0gICAgICAgICAgICAgICAgICAgIGJ5dGVbXSBieXRlcyA9IG5ldyBieXRlW3NpemVdOwotICAgICAgICAgICAgICAgICAgICByZWFkRnJvbUlucHV0U3RyZWFtKGJ5dGVzLCBpbnB1dCwgc2l6ZSk7Ci0gICAgICAgICAgICAgICAgICAgIGlucHV0LmNsb3NlKCk7Ci0gICAgICAgICAgICAgICAgICAgIGJ5dGVjb2Rlcy5hZGRFbGVtZW50KGJ5dGVzKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gQ29udmVydCB0aGUgVmVjdG9yIG9mIGJ5dGVbXSB0byBieXRlW11bXS4KLSAgICAgICAgZmluYWwgaW50IGNvdW50ID0gYnl0ZWNvZGVzLnNpemUoKTsKLSAgICAgICAgaWYgKGNvdW50ID4gMCkgewotICAgICAgICAgICAgZmluYWwgYnl0ZVtdW10gcmVzdWx0ID0gbmV3IGJ5dGVbY291bnRdWzFdOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgcmVzdWx0W2ldID0gKGJ5dGVbXSlieXRlY29kZXMuZWxlbWVudEF0KGkpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICByZXR1cm4gcmVzdWx0OwotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJlYWQgYSBnaXZlbiBudW1iZXIgb2YgYnl0ZXMgZnJvbSB0aGUgSW5wdXRTdHJlYW0gaW50byBhIGJ5dGUgYXJyYXkuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYnl0ZXMgVGhlIGJ5dGUgYXJyYXkgdG8gc3RvcmUgdGhlIGlucHV0IGNvbnRlbnQuCi0gICAgICogQHBhcmFtIGlucHV0IFRoZSBpbnB1dCBzdHJlYW0uCi0gICAgICogQHBhcmFtIHNpemUgVGhlIG51bWJlciBvZiBieXRlcyB0byByZWFkLgotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCByZWFkRnJvbUlucHV0U3RyZWFtKGJ5dGVbXSBieXRlcywgSW5wdXRTdHJlYW0gaW5wdXQsIGludCBzaXplKQotICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24KLSAgICB7Ci0gICAgICBpbnQgbiA9IDA7Ci0gICAgICBpbnQgb2Zmc2V0ID0gMDsKLSAgICAgIGludCBsZW5ndGggPSBzaXplOwotICAgICAgd2hpbGUgKGxlbmd0aCA+IDAgJiYgKG4gPSBpbnB1dC5yZWFkKGJ5dGVzLCBvZmZzZXQsIGxlbmd0aCkpID4gMCkgewotICAgICAgICAgIG9mZnNldCA9IG9mZnNldCArIG47Ci0gICAgICAgICAgbGVuZ3RoID0gbGVuZ3RoIC0gbjsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIGJhc2UgY2xhc3MgbmFtZSBvZiB0aGUgdHJhbnNsZXQuCi0gICAgICogVGhlIHRyYW5zbGV0IG5hbWUgaXMgcmVzb2x2ZWQgdXNpbmcgdGhlIGZvbGxvd2luZyBydWxlczoKLSAgICAgKiAxLiBpZiB0aGUgX3RyYW5zbGV0TmFtZSBhdHRyaWJ1dGUgaXMgc2V0IGFuZCBpdHMgdmFsdWUgaXMgbm90ICJHcmVnb3JTYW1zYSIsCi0gICAgICogICAgdGhlbiBfdHJhbnNsZXROYW1lIGlzIHJldHVybmVkLgotICAgICAqIDIuIG90aGVyd2lzZSBnZXQgdGhlIHRyYW5zbGV0IG5hbWUgZnJvbSB0aGUgYmFzZSBuYW1lIG9mIHRoZSBzeXN0ZW0gSUQKLSAgICAgKiAzLiByZXR1cm4gIkdyZWdvclNhbXNhIiBpZiB0aGUgcmVzdWx0IGZyb20gc3RlcCAyIGlzIG51bGwuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc291cmNlIFRoZSBpbnB1dCBTb3VyY2UKLSAgICAgKiBAcmV0dXJuIFRoZSBuYW1lIG9mIHRoZSB0cmFuc2xldCBjbGFzcwotICAgICAqLwotICAgIHByaXZhdGUgU3RyaW5nIGdldFRyYW5zbGV0QmFzZU5hbWUoU291cmNlIHNvdXJjZSkKLSAgICB7Ci0gICAgICAgIFN0cmluZyB0cmFuc2xldEJhc2VOYW1lID0gbnVsbDsKLSAgICAgICAgaWYgKCFfdHJhbnNsZXROYW1lLmVxdWFscyhERUZBVUxUX1RSQU5TTEVUX05BTUUpKQotICAgICAgICAgICAgcmV0dXJuIF90cmFuc2xldE5hbWU7Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgU3RyaW5nIHN5c3RlbUlkID0gc291cmNlLmdldFN5c3RlbUlkKCk7Ci0gICAgICAgICAgICBpZiAoc3lzdGVtSWQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIFN0cmluZyBiYXNlTmFtZSA9IFV0aWwuYmFzZU5hbWUoc3lzdGVtSWQpOwotICAgICAgICAgICAgICAgIGlmIChiYXNlTmFtZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGJhc2VOYW1lID0gVXRpbC5ub0V4dE5hbWUoYmFzZU5hbWUpOwotICAgICAgICAgICAgICAgICAgICB0cmFuc2xldEJhc2VOYW1lID0gVXRpbC50b0phdmFOYW1lKGJhc2VOYW1lKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gKHRyYW5zbGV0QmFzZU5hbWUgIT0gbnVsbCkgPyB0cmFuc2xldEJhc2VOYW1lIDogREVGQVVMVF9UUkFOU0xFVF9OQU1FOwotICAgIH0KLQotICAgIC8qKgotICAgICAqICBSZXR1cm4gdGhlIGxvY2FsIGZpbGUgbmFtZSBmcm9tIHRoZSBzeXN0ZW1JZCBvZiB0aGUgU291cmNlIG9iamVjdAotICAgICAqCi0gICAgICogQHBhcmFtIHNvdXJjZSBUaGUgU291cmNlCi0gICAgICogQHJldHVybiBUaGUgZmlsZSBuYW1lIGluIHRoZSBsb2NhbCBmaWxlc3lzdGVtLCBvciBudWxsIGlmIHRoZQotICAgICAqIHN5c3RlbUlkIGRvZXMgbm90IHJlcHJlc2VudCBhIGxvY2FsIGZpbGUuCi0gICAgICovCi0gICAgcHJpdmF0ZSBTdHJpbmcgZ2V0U3R5bGVzaGVldEZpbGVOYW1lKFNvdXJjZSBzb3VyY2UpCi0gICAgewotICAgICAgICBTdHJpbmcgc3lzdGVtSWQgPSBzb3VyY2UuZ2V0U3lzdGVtSWQoKTsKLSAgICAgICAgaWYgKHN5c3RlbUlkICE9IG51bGwpIHsKLSAgICAgICAgICAgIEZpbGUgZmlsZSA9IG5ldyBGaWxlKHN5c3RlbUlkKTsKLSAgICAgICAgICAgIGlmIChmaWxlLmV4aXN0cygpKQotICAgICAgICAgICAgICAgIHJldHVybiBzeXN0ZW1JZDsKLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIFVSTCB1cmw7Ci0gICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgdXJsID0gbmV3IFVSTChzeXN0ZW1JZCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGNhdGNoIChNYWxmb3JtZWRVUkxFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBpZiAoImZpbGUiLmVxdWFscyh1cmwuZ2V0UHJvdG9jb2woKSkpCi0gICAgICAgICAgICAgICAgICAgIHJldHVybiB1cmwuZ2V0RmlsZSgpOwotICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhIG5ldyBpbnN0YW5jZSBvZiB0aGUgWFNMVEMgRFRNIE1hbmFnZXIgc2VydmljZS4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgZmluYWwgWFNMVENEVE1NYW5hZ2VyIGNyZWF0ZU5ld0RUTU1hbmFnZXJJbnN0YW5jZSgpIHsKLSAgICAgICAgcmV0dXJuIFhTTFRDRFRNTWFuYWdlci5jcmVhdGVOZXdEVE1NYW5hZ2VySW5zdGFuY2UoKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3RyYXgvVHJhbnNmb3JtZXJIYW5kbGVySW1wbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy90cmF4L1RyYW5zZm9ybWVySGFuZGxlckltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggY2Q0YjRiZS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3RyYXgvVHJhbnNmb3JtZXJIYW5kbGVySW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTEzICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFRyYW5zZm9ybWVySGFuZGxlckltcGwuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNSAwNjoyNToxMiBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMudHJheDsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uUmVzdWx0OwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXI7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnNheC5UcmFuc2Zvcm1lckhhbmRsZXI7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5kb20uRE9NUmVzdWx0OwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLlN0cmlwRmlsdGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkVycm9yTXNnOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5kb20uRE9NV1NGaWx0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmRvbS5TQVhJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5kb20uWFNMVENEVE1NYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5ydW50aW1lLkFic3RyYWN0VHJhbnNsZXQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNV1NGaWx0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyLlNlcmlhbGl6YXRpb25IYW5kbGVyOwotCi1pbXBvcnQgb3JnLnhtbC5zYXguQXR0cmlidXRlczsKLWltcG9ydCBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5EVERIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LkxvY2F0b3I7Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LmV4dC5EZWNsSGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguaGVscGVycy5EZWZhdWx0SGFuZGxlcjsKLQotLyoqCi0gKiBJbXBsZW1lbnRhdGlvbiBvZiBhIEpBWFAxLjEgVHJhbnNmb3JtZXJIYW5kbGVyCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqLwotcHVibGljIGNsYXNzIFRyYW5zZm9ybWVySGFuZGxlckltcGwgaW1wbGVtZW50cyBUcmFuc2Zvcm1lckhhbmRsZXIsIERlY2xIYW5kbGVyIHsKLQotICAgIHByaXZhdGUgVHJhbnNmb3JtZXJJbXBsICBfdHJhbnNmb3JtZXI7Ci0gICAgcHJpdmF0ZSBBYnN0cmFjdFRyYW5zbGV0IF90cmFuc2xldCA9IG51bGw7Ci0gICAgcHJpdmF0ZSBTdHJpbmcgICAgICAgICAgIF9zeXN0ZW1JZDsKLSAgICBwcml2YXRlIFNBWEltcGwgICAgICAgICAgX2RvbSA9IG51bGw7Ci0gICAgcHJpdmF0ZSBDb250ZW50SGFuZGxlciAgIF9oYW5kbGVyID0gbnVsbDsKLSAgICBwcml2YXRlIExleGljYWxIYW5kbGVyICAgX2xleEhhbmRsZXIgPSBudWxsOwotICAgIHByaXZhdGUgRFRESGFuZGxlciAgICAgICBfZHRkSGFuZGxlciA9IG51bGw7Ci0gICAgcHJpdmF0ZSBEZWNsSGFuZGxlciAgICAgIF9kZWNsSGFuZGxlciA9IG51bGw7Ci0gICAgcHJpdmF0ZSBSZXN1bHQgICAgICAgICAgIF9yZXN1bHQgPSBudWxsOwotICAgIHByaXZhdGUgTG9jYXRvciAgICAgICAgICBfbG9jYXRvciA9IG51bGw7Ci0KLSAgICBwcml2YXRlIGJvb2xlYW4gICAgICAgICAgX2RvbmUgPSBmYWxzZTsgLy8gU2V0IGluIGVuZERvY3VtZW50KCkKLQotICAgIC8qKgotICAgICAqIEEgZmxhZyBpbmRpY2F0aW5nIHdoZXRoZXIgdGhpcyB0cmFuc2Zvcm1lciBoYW5kbGVyIGltcGxlbWVudHMgdGhlCi0gICAgICogaWRlbnRpdHkgdHJhbnNmb3JtLgotICAgICAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBfaXNJZGVudGl0eSA9IGZhbHNlOwotCi0gICAgLyoqCi0gICAgICogQ29zbnRydWN0b3IgLSBwYXNzIGluIHJlZmVyZW5jZSB0byBhIFRyYW5zZm9ybWVySW1wbCBvYmplY3QKLSAgICAgKi8KLSAgICBwdWJsaWMgVHJhbnNmb3JtZXJIYW5kbGVySW1wbChUcmFuc2Zvcm1lckltcGwgdHJhbnNmb3JtZXIpIHsKLSAgICAgICAgLy8gU2F2ZSB0aGUgcmVmZXJlbmNlIHRvIHRoZSB0cmFuc2Zvcm1lcgotICAgICAgICBfdHJhbnNmb3JtZXIgPSB0cmFuc2Zvcm1lcjsKLQotICAgICAgICBpZiAodHJhbnNmb3JtZXIuaXNJZGVudGl0eSgpKSB7Ci0gICAgICAgICAgICAvLyBTZXQgaW5pdGlhbCBoYW5kbGVyIHRvIHRoZSBlbXB0eSBoYW5kbGVyCi0gICAgICAgICAgICBfaGFuZGxlciA9IG5ldyBEZWZhdWx0SGFuZGxlcigpOwotICAgICAgICAgICAgX2lzSWRlbnRpdHkgPSB0cnVlOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgLy8gR2V0IGEgcmVmZXJlbmNlIHRvIHRoZSB0cmFuc2xldCB3cmFwcGVkIGluc2lkZSB0aGUgdHJhbnNmb3JtZXIKLSAgICAgICAgICAgIF90cmFuc2xldCA9IF90cmFuc2Zvcm1lci5nZXRUcmFuc2xldCgpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSW1wbGVtZW50cyBqYXZheC54bWwudHJhbnNmb3JtLnNheC5UcmFuc2Zvcm1lckhhbmRsZXIuZ2V0U3lzdGVtSWQoKQotICAgICAqIEdldCB0aGUgYmFzZSBJRCAoVVJJIG9yIHN5c3RlbSBJRCkgZnJvbSB3aGVyZSByZWxhdGl2ZSBVUkxzIHdpbGwgYmUKLSAgICAgKiByZXNvbHZlZC4KLSAgICAgKiBAcmV0dXJuIFRoZSBzeXN0ZW1JRCB0aGF0IHdhcyBzZXQgd2l0aCBzZXRTeXN0ZW1JZChTdHJpbmcgaWQpCi0gICAgICovCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIFN0cmluZyBnZXRTeXN0ZW1JZCgpIHsKLSAgICAgICAgcmV0dXJuIF9zeXN0ZW1JZDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJbXBsZW1lbnRzIGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlRyYW5zZm9ybWVySGFuZGxlci5zZXRTeXN0ZW1JZCgpCi0gICAgICogR2V0IHRoZSBiYXNlIElEIChVUkkgb3Igc3lzdGVtIElEKSBmcm9tIHdoZXJlIHJlbGF0aXZlIFVSTHMgd2lsbCBiZQotICAgICAqIHJlc29sdmVkLgotICAgICAqIEBwYXJhbSBpZCBCYXNlIFVSSSBmb3IgdGhpcyBzdHlsZXNoZWV0Ci0gICAgICovCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIHZvaWQgc2V0U3lzdGVtSWQoU3RyaW5nIGlkKSB7Ci0gICAgICAgIF9zeXN0ZW1JZCA9IGlkOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEltcGxlbWVudHMgamF2YXgueG1sLnRyYW5zZm9ybS5zYXguVHJhbnNmb3JtZXJIYW5kbGVyLmdldFRyYW5zZm9ybWVyKCkKLSAgICAgKiBHZXQgdGhlIFRyYW5zZm9ybWVyIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGhhbmRsZXIsIHdoaWNoIGlzIG5lZWRlZCBpbgotICAgICAqIG9yZGVyIHRvIHNldCBwYXJhbWV0ZXJzIGFuZCBvdXRwdXQgcHJvcGVydGllcy4KLSAgICAgKiBAcmV0dXJuIFRoZSBUcmFuc2Zvcm1lciBvYmplY3QKLSAgICAgKi8KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgVHJhbnNmb3JtZXIgZ2V0VHJhbnNmb3JtZXIoKSB7Ci0gICAgICAgIHJldHVybiBfdHJhbnNmb3JtZXI7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSW1wbGVtZW50cyBqYXZheC54bWwudHJhbnNmb3JtLnNheC5UcmFuc2Zvcm1lckhhbmRsZXIuc2V0UmVzdWx0KCkKLSAgICAgKiBFbmFibGVzIHRoZSB1c2VyIG9mIHRoZSBUcmFuc2Zvcm1lckhhbmRsZXIgdG8gc2V0IHRoZSB0byBzZXQgdGhlIFJlc3VsdAotICAgICAqIGZvciB0aGUgdHJhbnNmb3JtYXRpb24uCi0gICAgICogQHBhcmFtIHJlc3VsdCBBIFJlc3VsdCBpbnN0YW5jZSwgc2hvdWxkIG5vdCBiZSBudWxsCi0gICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgcmVzdWx0IGlzIGludmFsaWQgZm9yIHNvbWUgcmVhc29uCi0gICAgICovCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIHZvaWQgc2V0UmVzdWx0KFJlc3VsdCByZXN1bHQpIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gewotICAgICAgICBfcmVzdWx0ID0gcmVzdWx0OwotCi0gICAgaWYgKG51bGwgPT0gcmVzdWx0KSB7Ci0gICAgICAgRXJyb3JNc2cgZXJyID0gbmV3IEVycm9yTXNnKEVycm9yTXNnLkVSX1JFU1VMVF9OVUxMKTsKLSAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKGVyci50b1N0cmluZygpKTsgLy8icmVzdWx0IHNob3VsZCBub3QgYmUgbnVsbCIpOwotICAgIH0KLQotICAgICAgICBpZiAoX2lzSWRlbnRpdHkpIHsKLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgLy8gQ29ubmVjdCB0aGlzIG9iamVjdCB3aXRoIG91dHB1dCBzeXN0ZW0gZGlyZWN0bHkKLSAgICAgICAgICAgICAgICBTZXJpYWxpemF0aW9uSGFuZGxlciBvdXRwdXRIYW5kbGVyID0KLSAgICAgICAgICAgICAgICAgICAgX3RyYW5zZm9ybWVyLmdldE91dHB1dEhhbmRsZXIocmVzdWx0KTsKLSAgICAgICAgICAgICAgICBfdHJhbnNmb3JtZXIudHJhbnNmZXJPdXRwdXRQcm9wZXJ0aWVzKG91dHB1dEhhbmRsZXIpOwotCi0gICAgICAgICAgICAgICAgX2hhbmRsZXIgPSBvdXRwdXRIYW5kbGVyOwotICAgICAgICAgICAgICAgIF9sZXhIYW5kbGVyID0gb3V0cHV0SGFuZGxlcjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhdGNoIChUcmFuc2Zvcm1lckV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgX3Jlc3VsdCA9IG51bGw7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoX2RvbmUpIHsKLSAgICAgICAgICAgIC8vIFJ1biB0aGUgdHJhbnNmb3JtYXRpb24gbm93LCBpZiBub3QgYWxyZWFkeSBkb25lCi0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIF90cmFuc2Zvcm1lci5zZXRET00oX2RvbSk7Ci0gICAgICAgICAgICAgICAgX3RyYW5zZm9ybWVyLnRyYW5zZm9ybShudWxsLCBfcmVzdWx0KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhdGNoIChUcmFuc2Zvcm1lckV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgLy8gV2hhdCB0aGUgaGVsbCBhcmUgd2Ugc3VwcG9zZWQgdG8gZG8gd2l0aCB0aGlzPz8/Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihlLmdldE1lc3NhZ2UoKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJbXBsZW1lbnRzIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyLmNoYXJhY3RlcnMoKQotICAgICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGNoYXJhY3RlciBkYXRhLgotICAgICAqLwotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyB2b2lkIGNoYXJhY3RlcnMoY2hhcltdIGNoLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIF9oYW5kbGVyLmNoYXJhY3RlcnMoY2gsIHN0YXJ0LCBsZW5ndGgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEltcGxlbWVudHMgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIuc3RhcnREb2N1bWVudCgpCi0gICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIGJlZ2lubmluZyBvZiBhIGRvY3VtZW50LgotICAgICAqLwotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RG9jdW1lbnQoKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICAgICAgLy8gTWFrZSBzdXJlIHNldFJlc3VsdCgpIHdhcyBjYWxsZWQgYmVmb3JlIHRoZSBmaXJzdCBTQVggZXZlbnQKLSAgICAgICAgaWYgKF9yZXN1bHQgPT0gbnVsbCkgewotICAgICAgICAgICAgRXJyb3JNc2cgZXJyID0gbmV3IEVycm9yTXNnKEVycm9yTXNnLkpBWFBfU0VUX1JFU1VMVF9FUlIpOwotICAgICAgICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbihlcnIudG9TdHJpbmcoKSk7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoIV9pc0lkZW50aXR5KSB7Ci0gICAgICAgICAgICBib29sZWFuIGhhc0lkQ2FsbCA9IChfdHJhbnNsZXQgIT0gbnVsbCkgPyBfdHJhbnNsZXQuaGFzSWRDYWxsKCkgOiBmYWxzZTsKLSAgICAgICAgICAgIFhTTFRDRFRNTWFuYWdlciBkdG1NYW5hZ2VyID0gbnVsbDsKLQotICAgICAgICAgICAgLy8gQ3JlYXRlIGFuIGludGVybmFsIERPTSAobm90IFczQykgYW5kIGdldCBTQVgyIGlucHV0IGhhbmRsZXIKLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgZHRtTWFuYWdlciA9IF90cmFuc2Zvcm1lci5nZXRUcmFuc2Zvcm1lckZhY3RvcnkoKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY3JlYXRlTmV3RFRNTWFuYWdlckluc3RhbmNlKCk7Ci0gICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oZSk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIERUTVdTRmlsdGVyIHdzRmlsdGVyOwotICAgICAgICAgICAgaWYgKF90cmFuc2xldCAhPSBudWxsICYmIF90cmFuc2xldCBpbnN0YW5jZW9mIFN0cmlwRmlsdGVyKSB7Ci0gICAgICAgICAgICAgICAgd3NGaWx0ZXIgPSBuZXcgRE9NV1NGaWx0ZXIoX3RyYW5zbGV0KTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgd3NGaWx0ZXIgPSBudWxsOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBDb25zdHJ1Y3QgdGhlIERUTSB1c2luZyB0aGUgU0FYIGV2ZW50cyB0aGF0IGNvbWUgdGhyb3VnaAotICAgICAgICAgICAgX2RvbSA9IChTQVhJbXBsKWR0bU1hbmFnZXIuZ2V0RFRNKG51bGwsIGZhbHNlLCB3c0ZpbHRlciwgdHJ1ZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSwgaGFzSWRDYWxsKTsKLQotICAgICAgICAgICAgX2hhbmRsZXIgPSBfZG9tLmdldEJ1aWxkZXIoKTsKLSAgICAgICAgICAgIF9sZXhIYW5kbGVyID0gKExleGljYWxIYW5kbGVyKSBfaGFuZGxlcjsKLSAgICAgICAgICAgIF9kdGRIYW5kbGVyID0gKERUREhhbmRsZXIpIF9oYW5kbGVyOwotICAgICAgICAgICAgX2RlY2xIYW5kbGVyID0gKERlY2xIYW5kbGVyKSBfaGFuZGxlcjsKLQotCi0gICAgICAgICAgICAvLyBTZXQgZG9jdW1lbnQgVVJJCi0gICAgICAgICAgICBfZG9tLnNldERvY3VtZW50VVJJKF9zeXN0ZW1JZCk7Ci0KLSAgICAgICAgICAgIGlmIChfbG9jYXRvciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgX2hhbmRsZXIuc2V0RG9jdW1lbnRMb2NhdG9yKF9sb2NhdG9yKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIFByb3h5IGNhbGwKLSAgICAgICAgX2hhbmRsZXIuc3RhcnREb2N1bWVudCgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEltcGxlbWVudHMgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIuZW5kRG9jdW1lbnQoKQotICAgICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIHRoZSBlbmQgb2YgYSBkb2N1bWVudC4KLSAgICAgKi8KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgdm9pZCBlbmREb2N1bWVudCgpIHRocm93cyBTQVhFeGNlcHRpb24gewotICAgICAgICAvLyBTaWduYWwgdG8gdGhlIERPTUJ1aWxkZXIgdGhhdCB0aGUgZG9jdW1lbnQgaXMgY29tcGxldGUKLSAgICAgICAgX2hhbmRsZXIuZW5kRG9jdW1lbnQoKTsKLQotICAgICAgICBpZiAoIV9pc0lkZW50aXR5KSB7Ci0gICAgICAgICAgICAvLyBSdW4gdGhlIHRyYW5zZm9ybWF0aW9uIG5vdyBpZiB3ZSBoYXZlIGEgcmVmZXJlbmNlIHRvIGEgUmVzdWx0IG9iamVjdAotICAgICAgICAgICAgaWYgKF9yZXN1bHQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgIF90cmFuc2Zvcm1lci5zZXRET00oX2RvbSk7Ci0gICAgICAgICAgICAgICAgICAgIF90cmFuc2Zvcm1lci50cmFuc2Zvcm0obnVsbCwgX3Jlc3VsdCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGNhdGNoIChUcmFuc2Zvcm1lckV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gU2lnbmFsIHRoYXQgdGhlIGludGVybmFsIERPTSBpcyBidWlsdCAoc2VlICdzZXRSZXN1bHQoKScpLgotICAgICAgICAgICAgX2RvbmUgPSB0cnVlOwotCi0gICAgICAgICAgICAvLyBTZXQgdGhpcyBET00gYXMgdGhlIHRyYW5zZm9ybWVyJ3MgRE9NCi0gICAgICAgICAgICBfdHJhbnNmb3JtZXIuc2V0RE9NKF9kb20pOwotICAgICAgICB9Ci0gICAgICAgIGlmIChfaXNJZGVudGl0eSAmJiBfcmVzdWx0IGluc3RhbmNlb2YgRE9NUmVzdWx0KSB7Ci0gICAgICAgICAgICAoKERPTVJlc3VsdClfcmVzdWx0KS5zZXROb2RlKF90cmFuc2Zvcm1lci5nZXRUcmFuc2xldE91dHB1dEhhbmRsZXJGYWN0b3J5KCkuZ2V0Tm9kZSgpKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEltcGxlbWVudHMgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIuc3RhcnRFbGVtZW50KCkKLSAgICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiB0aGUgYmVnaW5uaW5nIG9mIGFuIGVsZW1lbnQuCi0gICAgICovCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIHZvaWQgc3RhcnRFbGVtZW50KFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBxbmFtZSwgQXR0cmlidXRlcyBhdHRyaWJ1dGVzKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBfaGFuZGxlci5zdGFydEVsZW1lbnQodXJpLCBsb2NhbE5hbWUsIHFuYW1lLCBhdHRyaWJ1dGVzKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJbXBsZW1lbnRzIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyLmVuZEVsZW1lbnQoKQotICAgICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIHRoZSBlbmQgb2YgYW4gZWxlbWVudC4KLSAgICAgKi8KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgdm9pZCBlbmRFbGVtZW50KFN0cmluZyBuYW1lc3BhY2VVUkksIFN0cmluZyBsb2NhbE5hbWUsIFN0cmluZyBxbmFtZSkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgX2hhbmRsZXIuZW5kRWxlbWVudChuYW1lc3BhY2VVUkksIGxvY2FsTmFtZSwgcW5hbWUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEltcGxlbWVudHMgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIucHJvY2Vzc2luZ0luc3RydWN0aW9uKCkKLSAgICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBhIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24uCi0gICAgICovCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIHZvaWQgcHJvY2Vzc2luZ0luc3RydWN0aW9uKFN0cmluZyB0YXJnZXQsIFN0cmluZyBkYXRhKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBfaGFuZGxlci5wcm9jZXNzaW5nSW5zdHJ1Y3Rpb24odGFyZ2V0LCBkYXRhKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJbXBsZW1lbnRzIG9yZy54bWwuc2F4LmV4dC5MZXhpY2FsSGFuZGxlci5zdGFydENEQVRBKCkKLSAgICAgKi8KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgdm9pZCBzdGFydENEQVRBKCkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChfbGV4SGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBfbGV4SGFuZGxlci5zdGFydENEQVRBKCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJbXBsZW1lbnRzIG9yZy54bWwuc2F4LmV4dC5MZXhpY2FsSGFuZGxlci5lbmRDREFUQSgpCi0gICAgICovCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIHZvaWQgZW5kQ0RBVEEoKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKF9sZXhIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIF9sZXhIYW5kbGVyLmVuZENEQVRBKCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJbXBsZW1lbnRzIG9yZy54bWwuc2F4LmV4dC5MZXhpY2FsSGFuZGxlci5jb21tZW50KCkKLSAgICAgKiBSZWNlaWV2ZSBub3RpZmljYXRpb24gb2YgYSBjb21tZW50Ci0gICAgICovCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIHZvaWQgY29tbWVudChjaGFyW10gY2gsIGludCBzdGFydCwgaW50IGxlbmd0aCkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaWYgKF9sZXhIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIF9sZXhIYW5kbGVyLmNvbW1lbnQoY2gsIHN0YXJ0LCBsZW5ndGgpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSW1wbGVtZW50cyBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlci5pZ25vcmFibGVXaGl0ZXNwYWNlKCkKLSAgICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBpZ25vcmFibGUgd2hpdGVzcGFjZSBpbiBlbGVtZW50Ci0gICAgICogY29udGVudC4gU2ltaWxhciB0byBjaGFyYWN0ZXJzKGNoYXJbXSwgaW50LCBpbnQpLgotICAgICAqLwotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyB2b2lkIGlnbm9yYWJsZVdoaXRlc3BhY2UoY2hhcltdIGNoLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIF9oYW5kbGVyLmlnbm9yYWJsZVdoaXRlc3BhY2UoY2gsIHN0YXJ0LCBsZW5ndGgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEltcGxlbWVudHMgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIuc2V0RG9jdW1lbnRMb2NhdG9yKCkKLSAgICAgKiBSZWNlaXZlIGFuIG9iamVjdCBmb3IgbG9jYXRpbmcgdGhlIG9yaWdpbiBvZiBTQVggZG9jdW1lbnQgZXZlbnRzLgotICAgICAqLwotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyB2b2lkIHNldERvY3VtZW50TG9jYXRvcihMb2NhdG9yIGxvY2F0b3IpIHsKLSAgICAgICAgX2xvY2F0b3IgPSBsb2NhdG9yOwotCi0gICAgICAgIGlmIChfaGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBfaGFuZGxlci5zZXREb2N1bWVudExvY2F0b3IobG9jYXRvcik7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJbXBsZW1lbnRzIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyLnNraXBwZWRFbnRpdHkoKQotICAgICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGEgc2tpcHBlZCBlbnRpdHkuCi0gICAgICovCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIHZvaWQgc2tpcHBlZEVudGl0eShTdHJpbmcgbmFtZSkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0gICAgICAgIF9oYW5kbGVyLnNraXBwZWRFbnRpdHkobmFtZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSW1wbGVtZW50cyBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlci5zdGFydFByZWZpeE1hcHBpbmcoKQotICAgICAqIEJlZ2luIHRoZSBzY29wZSBvZiBhIHByZWZpeC1VUkkgTmFtZXNwYWNlIG1hcHBpbmcuCi0gICAgICovCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIHZvaWQgc3RhcnRQcmVmaXhNYXBwaW5nKFN0cmluZyBwcmVmaXgsIFN0cmluZyB1cmkpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24gewotICAgICAgICBfaGFuZGxlci5zdGFydFByZWZpeE1hcHBpbmcocHJlZml4LCB1cmkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEltcGxlbWVudHMgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIuZW5kUHJlZml4TWFwcGluZygpCi0gICAgICogRW5kIHRoZSBzY29wZSBvZiBhIHByZWZpeC1VUkkgTmFtZXNwYWNlIG1hcHBpbmcuCi0gICAgICovCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIHZvaWQgZW5kUHJlZml4TWFwcGluZyhTdHJpbmcgcHJlZml4KSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICAgICAgX2hhbmRsZXIuZW5kUHJlZml4TWFwcGluZyhwcmVmaXgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEltcGxlbWVudHMgb3JnLnhtbC5zYXguZXh0LkxleGljYWxIYW5kbGVyLnN0YXJ0RFREKCkKLSAgICAgKi8KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgdm9pZCBzdGFydERURChTdHJpbmcgbmFtZSwgU3RyaW5nIHB1YmxpY0lkLCBTdHJpbmcgc3lzdGVtSWQpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGlmIChfbGV4SGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBfbGV4SGFuZGxlci5zdGFydERURChuYW1lLCBwdWJsaWNJZCwgc3lzdGVtSWQpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSW1wbGVtZW50cyBvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXIuZW5kRFREKCkKLSAgICAgKi8KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgdm9pZCBlbmREVEQoKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKF9sZXhIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIF9sZXhIYW5kbGVyLmVuZERURCgpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSW1wbGVtZW50cyBvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXIuc3RhcnRFbnRpdHkoKQotICAgICAqLwotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RW50aXR5KFN0cmluZyBuYW1lKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKF9sZXhIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIF9sZXhIYW5kbGVyLnN0YXJ0RW50aXR5KG5hbWUpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSW1wbGVtZW50cyBvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXIuZW5kRW50aXR5KCkKLSAgICAgKi8KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgdm9pZCBlbmRFbnRpdHkoU3RyaW5nIG5hbWUpIHRocm93cyBTQVhFeGNlcHRpb24gewotICAgICAgICBpZiAoX2xleEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgX2xleEhhbmRsZXIuZW5kRW50aXR5KG5hbWUpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSW1wbGVtZW50cyBvcmcueG1sLnNheC5EVERIYW5kbGVyLnVucGFyc2VkRW50aXR5RGVjbCgpCi0gICAgICovCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIHZvaWQgdW5wYXJzZWRFbnRpdHlEZWNsKFN0cmluZyBuYW1lLCBTdHJpbmcgcHVibGljSWQsCi0gICAgICAgIFN0cmluZyBzeXN0ZW1JZCwgU3RyaW5nIG5vdGF0aW9uTmFtZSkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaWYgKF9kdGRIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIF9kdGRIYW5kbGVyLnVucGFyc2VkRW50aXR5RGVjbChuYW1lLCBwdWJsaWNJZCwgc3lzdGVtSWQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm90YXRpb25OYW1lKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEltcGxlbWVudHMgb3JnLnhtbC5zYXguRFRESGFuZGxlci5ub3RhdGlvbkRlY2woKQotICAgICAqLwotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyB2b2lkIG5vdGF0aW9uRGVjbChTdHJpbmcgbmFtZSwgU3RyaW5nIHB1YmxpY0lkLCBTdHJpbmcgc3lzdGVtSWQpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGlmIChfZHRkSGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBfZHRkSGFuZGxlci5ub3RhdGlvbkRlY2wobmFtZSwgcHVibGljSWQsIHN5c3RlbUlkKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEltcGxlbWVudHMgb3JnLnhtbC5zYXguZXh0LkRlY2xIYW5kbGVyLmF0dHJpYnV0ZURlY2woKQotICAgICAqLwotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyB2b2lkIGF0dHJpYnV0ZURlY2woU3RyaW5nIGVOYW1lLCBTdHJpbmcgYU5hbWUsIFN0cmluZyB0eXBlLAotICAgICAgICBTdHJpbmcgdmFsdWVEZWZhdWx0LCBTdHJpbmcgdmFsdWUpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGlmIChfZGVjbEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgX2RlY2xIYW5kbGVyLmF0dHJpYnV0ZURlY2woZU5hbWUsIGFOYW1lLCB0eXBlLCB2YWx1ZURlZmF1bHQsIHZhbHVlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEltcGxlbWVudHMgb3JnLnhtbC5zYXguZXh0LkRlY2xIYW5kbGVyLmVsZW1lbnREZWNsKCkKLSAgICAgKi8KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgdm9pZCBlbGVtZW50RGVjbChTdHJpbmcgbmFtZSwgU3RyaW5nIG1vZGVsKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAoX2RlY2xIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIF9kZWNsSGFuZGxlci5lbGVtZW50RGVjbChuYW1lLCBtb2RlbCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJbXBsZW1lbnRzIG9yZy54bWwuc2F4LmV4dC5EZWNsSGFuZGxlci5leHRlcm5hbEVudGl0eURlY2woKQotICAgICAqLwotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyB2b2lkIGV4dGVybmFsRW50aXR5RGVjbChTdHJpbmcgbmFtZSwgU3RyaW5nIHB1YmxpY0lkLCBTdHJpbmcgc3lzdGVtSWQpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGlmIChfZGVjbEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgX2RlY2xIYW5kbGVyLmV4dGVybmFsRW50aXR5RGVjbChuYW1lLCBwdWJsaWNJZCwgc3lzdGVtSWQpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSW1wbGVtZW50cyBvcmcueG1sLnNheC5leHQuRGVjbEhhbmRsZXIuZXh0ZXJuYWxFbnRpdHlEZWNsKCkKLSAgICAgKi8KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgdm9pZCBpbnRlcm5hbEVudGl0eURlY2woU3RyaW5nIG5hbWUsIFN0cmluZyB2YWx1ZSkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaWYgKF9kZWNsSGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBfZGVjbEhhbmRsZXIuaW50ZXJuYWxFbnRpdHlEZWNsKG5hbWUsIHZhbHVlKTsKLSAgICAgICAgfQotICAgIH0KLQotCi0gICAvKiogSW1wbGVtZW50YXRpb24gb2YgdGhlIHJlc2V0KCkgbWV0aG9kCi0gICAgKgotICAgICovCi0gICBwdWJsaWMgdm9pZCByZXNldCgpIHsKLSAgICAgICBfc3lzdGVtSWQgPSBudWxsOwotICAgICAgIF9kb20gPSBudWxsOwotICAgICAgIF9oYW5kbGVyID0gbnVsbDsKLSAgICAgICBfbGV4SGFuZGxlciA9IG51bGw7Ci0gICAgICAgX2R0ZEhhbmRsZXIgPSBudWxsOwotICAgICAgIF9kZWNsSGFuZGxlciA9IG51bGw7Ci0gICAgICAgX3Jlc3VsdCA9IG51bGw7Ci0gICAgICAgX2xvY2F0b3IgPSBudWxsOwotICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy90cmF4L1RyYW5zZm9ybWVySW1wbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy90cmF4L1RyYW5zZm9ybWVySW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyZGRkYWM1Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvdHJheC9UcmFuc2Zvcm1lckltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE0MTIgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwNywgMjAxNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqLwotLyoKLSAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQotICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCi0gKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCi0gKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAotICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKLSAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBUcmFuc2Zvcm1lckltcGwuamF2YSx2IDEuMTAgMjAwNy8wNi8xMyAwMTo1NzowOSBqb2VodyBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnRyYXg7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwuWGFsYW5Db25zdGFudHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnV0aWxzLkZhY3RvcnlJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC51dGlscy5YTUxTZWN1cml0eU1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLkRPTTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuRE9NQ2FjaGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLlN0cmlwRmlsdGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5UcmFuc2xldDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuVHJhbnNsZXRFeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuRXJyb3JNc2c7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmRvbS5ET01XU0ZpbHRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuZG9tLlNBWEltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmRvbS5YU0xUQ0RUTU1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnJ1bnRpbWUuQWJzdHJhY3RUcmFuc2xldDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMucnVudGltZS5vdXRwdXQuVHJhbnNsZXRPdXRwdXRIYW5kbGVyRmFjdG9yeTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1XU0ZpbHRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXIuT3V0cHV0UHJvcGVydGllc0ZhY3Rvcnk7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyLlNlcmlhbGl6YXRpb25IYW5kbGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuU3lzdGVtSURSZXNvbHZlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLlhNTFJlYWRlck1hbmFnZXI7Ci1pbXBvcnQgamF2YS5pby5GaWxlOwotaW1wb3J0IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbTsKLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5pby5SZWFkZXI7Ci1pbXBvcnQgamF2YS5pby5Xcml0ZXI7Ci1pbXBvcnQgamF2YS5uZXQuVVJJOwotaW1wb3J0IGphdmEubmV0LlVSTDsKLWltcG9ydCBqYXZhLm5ldC5VUkxDb25uZWN0aW9uOwotaW1wb3J0IGphdmEubmV0LlVua25vd25TZXJ2aWNlRXhjZXB0aW9uOwotaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKLWltcG9ydCBqYXZhLnV0aWwuTWFwOwotaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0aWVzOwotaW1wb3J0IGphdmEudXRpbC5TdHJpbmdUb2tlbml6ZXI7Ci1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLWltcG9ydCBqYXZheC54bWwuWE1MQ29uc3RhbnRzOwotaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlcjsKLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5OwotaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLlBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5YTUxFdmVudFJlYWRlcjsKLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLlhNTFN0cmVhbVJlYWRlcjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLkVycm9yTGlzdGVuZXI7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5PdXRwdXRLZXlzOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uUmVzdWx0OwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uU291cmNlOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXI7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlVSSVJlc29sdmVyOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uZG9tLkRPTVJlc3VsdDsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLmRvbS5ET01Tb3VyY2U7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zYXguU0FYUmVzdWx0OwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlNBWFNvdXJjZTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnN0YXguU3RBWFJlc3VsdDsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnN0YXguU3RBWFNvdXJjZTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbS5TdHJlYW1SZXN1bHQ7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zdHJlYW0uU3RyZWFtU291cmNlOwotaW1wb3J0IG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LklucHV0U291cmNlOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5YTUxSZWFkZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguZXh0LkxleGljYWxIYW5kbGVyOwotCi0vKioKLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICogQGF1dGhvciBHLiBUb2RkIE1pbGxlcgotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBUcmFuc2Zvcm1lckltcGwgZXh0ZW5kcyBUcmFuc2Zvcm1lcgotICAgIGltcGxlbWVudHMgRE9NQ2FjaGUsIEVycm9yTGlzdGVuZXIKLXsKLQotICAgIHByaXZhdGUgZmluYWwgc3RhdGljIFN0cmluZyBMRVhJQ0FMX0hBTkRMRVJfUFJPUEVSVFkgPQotICAgICAgICAiaHR0cDovL3htbC5vcmcvc2F4L3Byb3BlcnRpZXMvbGV4aWNhbC1oYW5kbGVyIjsKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgTkFNRVNQQUNFX0ZFQVRVUkUgPQotICAgICAgICAiaHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL25hbWVzcGFjZXMiOwotCi0gICAgLyoqCi0gICAgICogTmFtZXNwYWNlIHByZWZpeGVzIGZlYXR1cmUgZm9yIHtAbGluayBYTUxSZWFkZXJ9LgotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBOQU1FU1BBQ0VfUFJFRklYRVNfRkVBVFVSRSA9Ci0gICAgICAgICJodHRwOi8veG1sLm9yZy9zYXgvZmVhdHVyZXMvbmFtZXNwYWNlLXByZWZpeGVzIjsKLQotICAgIC8qKgotICAgICAqIEEgcmVmZXJlbmNlIHRvIHRoZSB0cmFuc2xldCBvciBudWxsIGlmIHRoZSBpZGVudGl0eSB0cmFuc2Zvcm0uCi0gICAgICovCi0gICAgcHJpdmF0ZSBBYnN0cmFjdFRyYW5zbGV0IF90cmFuc2xldCA9IG51bGw7Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgb3V0cHV0IG1ldGhvZCBvZiB0aGlzIHRyYW5zZm9ybWF0aW9uLgotICAgICAqLwotICAgIHByaXZhdGUgU3RyaW5nIF9tZXRob2QgPSBudWxsOwotCi0gICAgLyoqCi0gICAgICogVGhlIG91dHB1dCBlbmNvZGluZyBvZiB0aGlzIHRyYW5zZm9ybWF0aW9uLgotICAgICAqLwotICAgIHByaXZhdGUgU3RyaW5nIF9lbmNvZGluZyA9IG51bGw7Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgc3lzdGVtSWQgc2V0IGluIGlucHV0IHNvdXJjZS4KLSAgICAgKi8KLSAgICBwcml2YXRlIFN0cmluZyBfc291cmNlU3lzdGVtSWQgPSBudWxsOwotCi0gICAgLyoqCi0gICAgICogQW4gZXJyb3IgbGlzdGVuZXIgZm9yIHJ1bnRpbWUgZXJyb3JzLgotICAgICAqLwotICAgIHByaXZhdGUgRXJyb3JMaXN0ZW5lciBfZXJyb3JMaXN0ZW5lciA9IHRoaXM7Ci0KLSAgICAvKioKLSAgICAgKiBBIHJlZmVyZW5jZSB0byBhIFVSSSByZXNvbHZlciBmb3IgY2FsbHMgdG8gZG9jdW1lbnQoKS4KLSAgICAgKi8KLSAgICBwcml2YXRlIFVSSVJlc29sdmVyIF91cmlSZXNvbHZlciA9IG51bGw7Ci0KLSAgICAvKioKLSAgICAgKiBPdXRwdXQgcHJvcGVydGllcyBvZiB0aGlzIHRyYW5zZm9ybWVyIGluc3RhbmNlLgotICAgICAqLwotICAgIHByaXZhdGUgUHJvcGVydGllcyBfcHJvcGVydGllcywgX3Byb3BlcnRpZXNDbG9uZTsKLQotICAgIC8qKgotICAgICAqIEEgcmVmZXJlbmNlIHRvIGFuIG91dHB1dCBoYW5kbGVyIGZhY3RvcnkuCi0gICAgICovCi0gICAgcHJpdmF0ZSBUcmFuc2xldE91dHB1dEhhbmRsZXJGYWN0b3J5IF90b2hGYWN0b3J5ID0gbnVsbDsKLQotICAgIC8qKgotICAgICAqIEEgcmVmZXJlbmNlIHRvIGEgaW50ZXJuYWwgRE9NIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBpbnB1dC4KLSAgICAgKi8KLSAgICBwcml2YXRlIERPTSBfZG9tID0gbnVsbDsKLQotICAgIC8qKgotICAgICAqIE51bWJlciBvZiBpbmRlbnQgc3BhY2VzIHRvIGFkZCB3aGVuIGluZGVudGF0aW9uIGlzIG9uLgotICAgICAqLwotICAgIHByaXZhdGUgaW50IF9pbmRlbnROdW1iZXI7Ci0KLSAgICAvKioKLSAgICAgKiBBIHJlZmVyZW5jZSB0byB0aGUgdHJhbnNmb3JtZXIgZmFjdG9yeSB0aGF0IHRoaXMgdGVtcGxhdGVzCi0gICAgICogb2JqZWN0IGJlbG9uZ3MgdG8uCi0gICAgICovCi0gICAgcHJpdmF0ZSBUcmFuc2Zvcm1lckZhY3RvcnlJbXBsIF90ZmFjdG9yeSA9IG51bGw7Ci0KLSAgICAvKioKLSAgICAgKiBBIHJlZmVyZW5jZSB0byB0aGUgb3V0cHV0IHN0cmVhbSwgaWYgd2UgY3JlYXRlIG9uZSBpbiBvdXIgY29kZS4KLSAgICAgKi8KLSAgICBwcml2YXRlIE91dHB1dFN0cmVhbSBfb3N0cmVhbSA9IG51bGw7Ci0KLSAgICAvKioKLSAgICAgKiBBIHJlZmVyZW5jZSB0byB0aGUgWFNMVENEVE1NYW5hZ2VyIHdoaWNoIGlzIHVzZWQgdG8gYnVpbGQgdGhlIERPTS9EVE0KLSAgICAgKiBmb3IgdGhpcyB0cmFuc2Zvcm1lci4KLSAgICAgKi8KLSAgICBwcml2YXRlIFhTTFRDRFRNTWFuYWdlciBfZHRtTWFuYWdlciA9IG51bGw7Ci0KLSAgICAvKioKLSAgICAgKiBBIHJlZmVyZW5jZSB0byBhbiBvYmplY3QgdGhhdCBjcmVhdGVzIGFuZCBjYWNoZXMgWE1MUmVhZGVyIG9iamVjdHMuCi0gICAgICovCi0gICAgcHJpdmF0ZSBYTUxSZWFkZXJNYW5hZ2VyIF9yZWFkZXJNYW5hZ2VyOwotCi0gICAgLyoqCi0gICAgICogQSBmbGFnIGluZGljYXRpbmcgd2hldGhlciB3ZSB1c2UgaW5jcmVtZW50YWwgYnVpbGRpbmcgb2YgdGhlIERUTS4KLSAgICAgKi8KLSAgICAvL3ByaXZhdGUgYm9vbGVhbiBfaXNJbmNyZW1lbnRhbCA9IGZhbHNlOwotCi0gICAgLyoqCi0gICAgICogQSBmbGFnIGluZGljYXRpbmcgd2hldGhlciB0aGlzIHRyYW5zZm9ybWVyIGltcGxlbWVudHMgdGhlIGlkZW50aXR5Ci0gICAgICogdHJhbnNmb3JtLgotICAgICAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBfaXNJZGVudGl0eSA9IGZhbHNlOwotCi0gICAgLyoqCi0gICAgICogU3RhdGUgb2YgdGhlIHNlY3VyZSBwcm9jZXNzaW5nIGZlYXR1cmUuCi0gICAgICovCi0gICAgcHJpdmF0ZSBib29sZWFuIF9pc1NlY3VyZVByb2Nlc3NpbmcgPSBmYWxzZTsKLQotICAgIC8qKgotICAgICAqIEluZGljYXRlcyB3aGV0aGVyIGltcGxlbWVudGF0aW9uIHBhcnRzIHNob3VsZCB1c2UKLSAgICAgKiAgIHNlcnZpY2UgbG9hZGVyIChvciBzaW1pbGFyKS4KLSAgICAgKiBOb3RlIHRoZSBkZWZhdWx0IHZhbHVlIChmYWxzZSkgaXMgdGhlIHNhZmUgb3B0aW9uLi4KLSAgICAgKi8KLSAgICBwcml2YXRlIGJvb2xlYW4gX3VzZVNlcnZpY2VzTWVjaGFuaXNtOwotICAgIC8qKgotICAgICAqIHByb3RvY29scyBhbGxvd2VkIGZvciBleHRlcm5hbCByZWZlcmVuY2VzIHNldCBieSB0aGUgc3R5bGVzaGVldCBwcm9jZXNzaW5nIGluc3RydWN0aW9uLCBJbXBvcnQgYW5kIEluY2x1ZGUgZWxlbWVudC4KLSAgICAgKi8KLSAgICBwcml2YXRlIFN0cmluZyBfYWNjZXNzRXh0ZXJuYWxTdHlsZXNoZWV0ID0gWGFsYW5Db25zdGFudHMuRVhURVJOQUxfQUNDRVNTX0RFRkFVTFQ7Ci0gICAgIC8qKgotICAgICAqIHByb3RvY29scyBhbGxvd2VkIGZvciBleHRlcm5hbCBEVEQgcmVmZXJlbmNlcyBpbiBzb3VyY2UgZmlsZSBhbmQvb3Igc3R5bGVzaGVldC4KLSAgICAgKi8KLSAgICBwcml2YXRlIFN0cmluZyBfYWNjZXNzRXh0ZXJuYWxEVEQgPSBYYWxhbkNvbnN0YW50cy5FWFRFUk5BTF9BQ0NFU1NfREVGQVVMVDsKLQotICAgIHByaXZhdGUgWE1MU2VjdXJpdHlNYW5hZ2VyIF9zZWN1cml0eU1hbmFnZXI7Ci0gICAgLyoqCi0gICAgICogQSBtYXAgdG8gc3RvcmUgcGFyYW1ldGVycyBmb3IgdGhlIGlkZW50aXR5IHRyYW5zZm9ybS4gVGhlc2UKLSAgICAgKiBhcmUgbm90IG5lZWRlZCBkdXJpbmcgdGhlIHRyYW5zZm9ybWF0aW9uLCBidXQgd2UgbXVzdCBrZWVwIHRyYWNrIG9mCi0gICAgICogdGhlbSB0byBiZSBmdWxseSBjb21wbGFpbnQgd2l0aCB0aGUgSkFYUCBBUEkuCi0gICAgICovCi0gICAgcHJpdmF0ZSBNYXA8U3RyaW5nLCBPYmplY3Q+IF9wYXJhbWV0ZXJzID0gbnVsbDsKLQotICAgIC8qKgotICAgICAqIFRoaXMgY2xhc3Mgd3JhcHMgYW4gRXJyb3JMaXN0ZW5lciBpbnRvIGEgTWVzc2FnZUhhbmRsZXIgaW4gb3JkZXIgdG8KLSAgICAgKiBjYXB0dXJlIG1lc3NhZ2VzIHJlcG9ydGVkIHZpYSB4c2w6bWVzc2FnZS4KLSAgICAgKi8KLSAgICBzdGF0aWMgY2xhc3MgTWVzc2FnZUhhbmRsZXIKLSAgICAgICAgICAgZXh0ZW5kcyBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMucnVudGltZS5NZXNzYWdlSGFuZGxlcgotICAgIHsKLSAgICAgICAgcHJpdmF0ZSBFcnJvckxpc3RlbmVyIF9lcnJvckxpc3RlbmVyOwotCi0gICAgICAgIHB1YmxpYyBNZXNzYWdlSGFuZGxlcihFcnJvckxpc3RlbmVyIGVycm9yTGlzdGVuZXIpIHsKLSAgICAgICAgICAgIF9lcnJvckxpc3RlbmVyID0gZXJyb3JMaXN0ZW5lcjsKLSAgICAgICAgfQotCi0gICAgICAgIEBPdmVycmlkZQotICAgICAgICBwdWJsaWMgdm9pZCBkaXNwbGF5TWVzc2FnZShTdHJpbmcgbXNnKSB7Ci0gICAgICAgICAgICBpZihfZXJyb3JMaXN0ZW5lciA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKG1zZyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICBfZXJyb3JMaXN0ZW5lci53YXJuaW5nKG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihtc2cpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgY2F0Y2ggKFRyYW5zZm9ybWVyRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gaWdub3JlZAotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIHByb3RlY3RlZCBUcmFuc2Zvcm1lckltcGwoUHJvcGVydGllcyBvdXRwdXRQcm9wZXJ0aWVzLCBpbnQgaW5kZW50TnVtYmVyLAotICAgICAgICBUcmFuc2Zvcm1lckZhY3RvcnlJbXBsIHRmYWN0b3J5KQotICAgIHsKLSAgICAgICAgdGhpcyhudWxsLCBvdXRwdXRQcm9wZXJ0aWVzLCBpbmRlbnROdW1iZXIsIHRmYWN0b3J5KTsKLSAgICAgICAgX2lzSWRlbnRpdHkgPSB0cnVlOwotICAgICAgICAvLyBfcHJvcGVydGllcy5wdXQoT3V0cHV0S2V5cy5NRVRIT0QsICJ4bWwiKTsKLSAgICB9Ci0KLSAgICBwcm90ZWN0ZWQgVHJhbnNmb3JtZXJJbXBsKFRyYW5zbGV0IHRyYW5zbGV0LCBQcm9wZXJ0aWVzIG91dHB1dFByb3BlcnRpZXMsCi0gICAgICAgIGludCBpbmRlbnROdW1iZXIsIFRyYW5zZm9ybWVyRmFjdG9yeUltcGwgdGZhY3RvcnkpCi0gICAgewotICAgICAgICBfdHJhbnNsZXQgPSAoQWJzdHJhY3RUcmFuc2xldCkgdHJhbnNsZXQ7Ci0gICAgICAgIF9wcm9wZXJ0aWVzID0gY3JlYXRlT3V0cHV0UHJvcGVydGllcyhvdXRwdXRQcm9wZXJ0aWVzKTsKLSAgICAgICAgX3Byb3BlcnRpZXNDbG9uZSA9IChQcm9wZXJ0aWVzKSBfcHJvcGVydGllcy5jbG9uZSgpOwotICAgICAgICBfaW5kZW50TnVtYmVyID0gaW5kZW50TnVtYmVyOwotICAgICAgICBfdGZhY3RvcnkgPSB0ZmFjdG9yeTsKLSAgICAgICAgX3VzZVNlcnZpY2VzTWVjaGFuaXNtID0gX3RmYWN0b3J5LnVzZVNlcnZpY2VzTWVjaG5pc20oKTsKLSAgICAgICAgX2FjY2Vzc0V4dGVybmFsU3R5bGVzaGVldCA9IChTdHJpbmcpX3RmYWN0b3J5LmdldEF0dHJpYnV0ZShYTUxDb25zdGFudHMuQUNDRVNTX0VYVEVSTkFMX1NUWUxFU0hFRVQpOwotICAgICAgICBfYWNjZXNzRXh0ZXJuYWxEVEQgPSAoU3RyaW5nKV90ZmFjdG9yeS5nZXRBdHRyaWJ1dGUoWE1MQ29uc3RhbnRzLkFDQ0VTU19FWFRFUk5BTF9EVEQpOwotICAgICAgICBfc2VjdXJpdHlNYW5hZ2VyID0gKFhNTFNlY3VyaXR5TWFuYWdlcilfdGZhY3RvcnkuZ2V0QXR0cmlidXRlKFhhbGFuQ29uc3RhbnRzLlNFQ1VSSVRZX01BTkFHRVIpOwotICAgICAgICBfcmVhZGVyTWFuYWdlciA9IFhNTFJlYWRlck1hbmFnZXIuZ2V0SW5zdGFuY2UoX3VzZVNlcnZpY2VzTWVjaGFuaXNtKTsKLSAgICAgICAgX3JlYWRlck1hbmFnZXIuc2V0UHJvcGVydHkoWE1MQ29uc3RhbnRzLkFDQ0VTU19FWFRFUk5BTF9EVEQsIF9hY2Nlc3NFeHRlcm5hbERURCk7Ci0gICAgICAgIF9yZWFkZXJNYW5hZ2VyLnNldEZlYXR1cmUoWE1MQ29uc3RhbnRzLkZFQVRVUkVfU0VDVVJFX1BST0NFU1NJTkcsIF9pc1NlY3VyZVByb2Nlc3NpbmcpOwotICAgICAgICBfcmVhZGVyTWFuYWdlci5zZXRQcm9wZXJ0eShYYWxhbkNvbnN0YW50cy5TRUNVUklUWV9NQU5BR0VSLCBfc2VjdXJpdHlNYW5hZ2VyKTsKLSAgICAgICAgLy9faXNJbmNyZW1lbnRhbCA9IHRmYWN0b3J5Ll9pbmNyZW1lbnRhbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIHN0YXRlIG9mIHRoZSBzZWN1cmUgcHJvY2Vzc2luZyBmZWF0dXJlLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzU2VjdXJlUHJvY2Vzc2luZygpIHsKLSAgICAgICAgcmV0dXJuIF9pc1NlY3VyZVByb2Nlc3Npbmc7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSBzdGF0ZSBvZiB0aGUgc2VjdXJlIHByb2Nlc3NpbmcgZmVhdHVyZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRTZWN1cmVQcm9jZXNzaW5nKGJvb2xlYW4gZmxhZykgewotICAgICAgICBfaXNTZWN1cmVQcm9jZXNzaW5nID0gZmxhZzsKLSAgICAgICAgX3JlYWRlck1hbmFnZXIuc2V0RmVhdHVyZShYTUxDb25zdGFudHMuRkVBVFVSRV9TRUNVUkVfUFJPQ0VTU0lORywgX2lzU2VjdXJlUHJvY2Vzc2luZyk7Ci0gICAgfQotICAgIC8qKgotICAgICAqIFJldHVybiB0aGUgc3RhdGUgb2YgdGhlIHNlcnZpY2VzIG1lY2hhbmlzbSBmZWF0dXJlLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIHVzZVNlcnZpY2VzTWVjaG5pc20oKSB7Ci0gICAgICAgIHJldHVybiBfdXNlU2VydmljZXNNZWNoYW5pc207Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSBzdGF0ZSBvZiB0aGUgc2VydmljZXMgbWVjaGFuaXNtIGZlYXR1cmUuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0U2VydmljZXNNZWNobmlzbShib29sZWFuIGZsYWcpIHsKLSAgICAgICAgX3VzZVNlcnZpY2VzTWVjaGFuaXNtID0gZmxhZzsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSB0cmFuc2xldCB3cmFwcGVkIGluc2lkZSB0aGlzIFRyYW5zZm9ybWVyIG9yCi0gICAgICogbnVsbCBpZiB0aGlzIGlzIHRoZSBpZGVudGl0eSB0cmFuc2Zvcm0uCi0gICAgICovCi0gICAgcHJvdGVjdGVkIEFic3RyYWN0VHJhbnNsZXQgZ2V0VHJhbnNsZXQoKSB7Ci0gICAgICAgIHJldHVybiBfdHJhbnNsZXQ7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gaXNJZGVudGl0eSgpIHsKLSAgICAgICAgcmV0dXJuIF9pc0lkZW50aXR5OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEltcGxlbWVudHMgSkFYUCdzIFRyYW5zZm9ybWVyLnRyYW5zZm9ybSgpCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc291cmNlIENvbnRhaW5zIHRoZSBpbnB1dCBYTUwgZG9jdW1lbnQKLSAgICAgKiBAcGFyYW0gcmVzdWx0IFdpbGwgY29udGFpbiB0aGUgb3V0cHV0IGZyb20gdGhlIHRyYW5zZm9ybWF0aW9uCi0gICAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgICAqLwotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyB2b2lkIHRyYW5zZm9ybShTb3VyY2Ugc291cmNlLCBSZXN1bHQgcmVzdWx0KQotICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGlmICghX2lzSWRlbnRpdHkpIHsKLSAgICAgICAgICAgIGlmIChfdHJhbnNsZXQgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIEVycm9yTXNnIGVyciA9IG5ldyBFcnJvck1zZyhFcnJvck1zZy5KQVhQX05PX1RSQU5TTEVUX0VSUik7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKGVyci50b1N0cmluZygpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIFBhc3Mgb3V0cHV0IHByb3BlcnRpZXMgdG8gdGhlIHRyYW5zbGV0Ci0gICAgICAgICAgICB0cmFuc2Zlck91dHB1dFByb3BlcnRpZXMoX3RyYW5zbGV0KTsKLSAgICAgICAgfQotCi0gICAgICAgIGZpbmFsIFNlcmlhbGl6YXRpb25IYW5kbGVyIHRvSGFuZGxlciA9IGdldE91dHB1dEhhbmRsZXIocmVzdWx0KTsKLSAgICAgICAgaWYgKHRvSGFuZGxlciA9PSBudWxsKSB7Ci0gICAgICAgICAgICBFcnJvck1zZyBlcnIgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuSkFYUF9OT19IQU5ETEVSX0VSUik7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oZXJyLnRvU3RyaW5nKCkpOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKF91cmlSZXNvbHZlciAhPSBudWxsICYmICFfaXNJZGVudGl0eSkgewotICAgICAgICAgICAgX3RyYW5zbGV0LnNldERPTUNhY2hlKHRoaXMpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gUGFzcyBvdXRwdXQgcHJvcGVydGllcyB0byBoYW5kbGVyIGlmIGlkZW50aXR5Ci0gICAgICAgIGlmIChfaXNJZGVudGl0eSkgewotICAgICAgICAgICAgdHJhbnNmZXJPdXRwdXRQcm9wZXJ0aWVzKHRvSGFuZGxlcik7Ci0gICAgICAgIH0KLQotICAgICAgICB0cmFuc2Zvcm0oc291cmNlLCB0b0hhbmRsZXIsIF9lbmNvZGluZyk7Ci0gICAgICAgIHRyeXsKLSAgICAgICAgICAgIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBET01SZXN1bHQpIHsKLSAgICAgICAgICAgICAgICAoKERPTVJlc3VsdClyZXN1bHQpLnNldE5vZGUoX3RvaEZhY3RvcnkuZ2V0Tm9kZSgpKTsKLSAgICAgICAgICAgIH0gZWxzZSBpZiAocmVzdWx0IGluc3RhbmNlb2YgU3RBWFJlc3VsdCkgewotICAgICAgICAgICAgICAgICAgaWYgKCgoU3RBWFJlc3VsdCkgcmVzdWx0KS5nZXRYTUxFdmVudFdyaXRlcigpICE9IG51bGwpCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAoX3RvaEZhY3RvcnkuZ2V0WE1MRXZlbnRXcml0ZXIoKSkuZmx1c2goKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSBpZiAoKChTdEFYUmVzdWx0KSByZXN1bHQpLmdldFhNTFN0cmVhbVdyaXRlcigpICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgKF90b2hGYWN0b3J5LmdldFhNTFN0cmVhbVdyaXRlcigpKS5mbHVzaCgpOwotICAgICAgICAgICAgICAgICAgICAvL3Jlc3VsdCA9IG5ldyBTdEFYUmVzdWx0KF90b2hGYWN0b3J5LmdldFhNTFN0cmVhbVdyaXRlcigpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlJlc3VsdCB3cml0aW5nIGVycm9yIik7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGUgYW4gb3V0cHV0IGhhbmRsZXIgZm9yIHRoZSB0cmFuc2Zvcm1hdGlvbiBvdXRwdXQgYmFzZWQgb24KLSAgICAgKiB0aGUgdHlwZSBhbmQgY29udGVudHMgb2YgdGhlIFRyQVggUmVzdWx0IG9iamVjdCBwYXNzZWQgdG8gdGhlCi0gICAgICogdHJhbnNmb3JtKCkgbWV0aG9kLgotICAgICAqLwotICAgIHB1YmxpYyBTZXJpYWxpemF0aW9uSGFuZGxlciBnZXRPdXRwdXRIYW5kbGVyKFJlc3VsdCByZXN1bHQpCi0gICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgLy8gR2V0IG91dHB1dCBtZXRob2QgdXNpbmcgZ2V0KCkgdG8gaWdub3JlIGRlZmF1bHRzCi0gICAgICAgIF9tZXRob2QgPSAoU3RyaW5nKSBfcHJvcGVydGllcy5nZXQoT3V0cHV0S2V5cy5NRVRIT0QpOwotCi0gICAgICAgIC8vIEdldCBlbmNvZGluZyB1c2luZyBnZXRQcm9wZXJ0eSgpIHRvIHVzZSBkZWZhdWx0cwotICAgICAgICBfZW5jb2RpbmcgPSAoU3RyaW5nKSBfcHJvcGVydGllcy5nZXRQcm9wZXJ0eShPdXRwdXRLZXlzLkVOQ09ESU5HKTsKLQotICAgICAgICBfdG9oRmFjdG9yeSA9IFRyYW5zbGV0T3V0cHV0SGFuZGxlckZhY3RvcnkubmV3SW5zdGFuY2UoX3VzZVNlcnZpY2VzTWVjaGFuaXNtKTsKLSAgICAgICAgX3RvaEZhY3Rvcnkuc2V0RW5jb2RpbmcoX2VuY29kaW5nKTsKLSAgICAgICAgaWYgKF9tZXRob2QgIT0gbnVsbCkgewotICAgICAgICAgICAgX3RvaEZhY3Rvcnkuc2V0T3V0cHV0TWV0aG9kKF9tZXRob2QpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gU2V0IGluZGVudGF0aW9uIG51bWJlciBpbiB0aGUgZmFjdG9yeQotICAgICAgICBpZiAoX2luZGVudE51bWJlciA+PSAwKSB7Ci0gICAgICAgICAgICBfdG9oRmFjdG9yeS5zZXRJbmRlbnROdW1iZXIoX2luZGVudE51bWJlcik7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBSZXR1cm4gdGhlIGNvbnRlbnQgaGFuZGxlciBmb3IgdGhpcyBSZXN1bHQgb2JqZWN0Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAvLyBSZXN1bHQgb2JqZWN0IGNvdWxkIGJlIFNBWFJlc3VsdCwgRE9NUmVzdWx0LCBvciBTdHJlYW1SZXN1bHQKLSAgICAgICAgICAgIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBTQVhSZXN1bHQpIHsKLSAgICAgICAgICAgICAgICBmaW5hbCBTQVhSZXN1bHQgdGFyZ2V0ID0gKFNBWFJlc3VsdClyZXN1bHQ7Ci0gICAgICAgICAgICAgICAgZmluYWwgQ29udGVudEhhbmRsZXIgaGFuZGxlciA9IHRhcmdldC5nZXRIYW5kbGVyKCk7Ci0KLSAgICAgICAgICAgICAgICBfdG9oRmFjdG9yeS5zZXRIYW5kbGVyKGhhbmRsZXIpOwotCi0gICAgICAgICAgICAgICAgLyoqCi0gICAgICAgICAgICAgICAgICogRml4IGZvciBidWcgMjQ0MTQKLSAgICAgICAgICAgICAgICAgKiBJZiB0aGUgbGV4aWNhbEhhbmRsZXIgaXMgc2V0IHRoZW4gd2UgbmVlZCB0byBnZXQgdGhhdAotICAgICAgICAgICAgICAgICAqIGZvciBvYnRhaW5pbmcgdGhlIGxleGljYWwgaW5mb3JtYXRpb24KLSAgICAgICAgICAgICAgICAgKi8KLSAgICAgICAgICAgICAgICBMZXhpY2FsSGFuZGxlciBsZXhpY2FsSGFuZGxlciA9IHRhcmdldC5nZXRMZXhpY2FsSGFuZGxlcigpOwotCi0gICAgICAgICAgICAgICAgaWYgKGxleGljYWxIYW5kbGVyICE9IG51bGwgKSB7Ci0gICAgICAgICAgICAgICAgICAgIF90b2hGYWN0b3J5LnNldExleGljYWxIYW5kbGVyKGxleGljYWxIYW5kbGVyKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBfdG9oRmFjdG9yeS5zZXRPdXRwdXRUeXBlKFRyYW5zbGV0T3V0cHV0SGFuZGxlckZhY3RvcnkuU0FYKTsKLSAgICAgICAgICAgICAgICByZXR1cm4gX3RvaEZhY3RvcnkuZ2V0U2VyaWFsaXphdGlvbkhhbmRsZXIoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIFN0QVhSZXN1bHQpIHsKLSAgICAgICAgICAgICAgICBpZiAoKChTdEFYUmVzdWx0KSByZXN1bHQpLmdldFhNTEV2ZW50V3JpdGVyKCkgIT0gbnVsbCkKLSAgICAgICAgICAgICAgICAgICAgX3RvaEZhY3Rvcnkuc2V0WE1MRXZlbnRXcml0ZXIoKChTdEFYUmVzdWx0KSByZXN1bHQpLmdldFhNTEV2ZW50V3JpdGVyKCkpOwotICAgICAgICAgICAgICAgIGVsc2UgaWYgKCgoU3RBWFJlc3VsdCkgcmVzdWx0KS5nZXRYTUxTdHJlYW1Xcml0ZXIoKSAhPSBudWxsKQotICAgICAgICAgICAgICAgICAgICBfdG9oRmFjdG9yeS5zZXRYTUxTdHJlYW1Xcml0ZXIoKChTdEFYUmVzdWx0KSByZXN1bHQpLmdldFhNTFN0cmVhbVdyaXRlcigpKTsKLSAgICAgICAgICAgICAgICBfdG9oRmFjdG9yeS5zZXRPdXRwdXRUeXBlKFRyYW5zbGV0T3V0cHV0SGFuZGxlckZhY3RvcnkuU1RBWCk7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIF90b2hGYWN0b3J5LmdldFNlcmlhbGl6YXRpb25IYW5kbGVyKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBET01SZXN1bHQpIHsKLSAgICAgICAgICAgICAgICBfdG9oRmFjdG9yeS5zZXROb2RlKCgoRE9NUmVzdWx0KSByZXN1bHQpLmdldE5vZGUoKSk7Ci0gICAgICAgICAgICAgICAgX3RvaEZhY3Rvcnkuc2V0TmV4dFNpYmxpbmcoKChET01SZXN1bHQpIHJlc3VsdCkuZ2V0TmV4dFNpYmxpbmcoKSk7Ci0gICAgICAgICAgICAgICAgX3RvaEZhY3Rvcnkuc2V0T3V0cHV0VHlwZShUcmFuc2xldE91dHB1dEhhbmRsZXJGYWN0b3J5LkRPTSk7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIF90b2hGYWN0b3J5LmdldFNlcmlhbGl6YXRpb25IYW5kbGVyKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBTdHJlYW1SZXN1bHQpIHsKLSAgICAgICAgICAgICAgICAvLyBHZXQgU3RyZWFtUmVzdWx0Ci0gICAgICAgICAgICAgICAgZmluYWwgU3RyZWFtUmVzdWx0IHRhcmdldCA9IChTdHJlYW1SZXN1bHQpIHJlc3VsdDsKLQotICAgICAgICAgICAgICAgIC8vIFN0cmVhbVJlc3VsdCBtYXkgaGF2ZSBiZWVuIGNyZWF0ZWQgd2l0aCBhIGphdmEuaW8uRmlsZSwKLSAgICAgICAgICAgICAgICAvLyBqYXZhLmlvLldyaXRlciwgamF2YS5pby5PdXRwdXRTdHJlYW0gb3IganVzdCBhIFN0cmluZwotICAgICAgICAgICAgICAgIC8vIHN5c3RlbUlkLgotCi0gICAgICAgICAgICAgICAgX3RvaEZhY3Rvcnkuc2V0T3V0cHV0VHlwZShUcmFuc2xldE91dHB1dEhhbmRsZXJGYWN0b3J5LlNUUkVBTSk7Ci0KLSAgICAgICAgICAgICAgICAvLyB0cnkgdG8gZ2V0IGEgV3JpdGVyIGZyb20gUmVzdWx0IG9iamVjdAotICAgICAgICAgICAgICAgIGZpbmFsIFdyaXRlciB3cml0ZXIgPSB0YXJnZXQuZ2V0V3JpdGVyKCk7Ci0gICAgICAgICAgICAgICAgaWYgKHdyaXRlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIF90b2hGYWN0b3J5LnNldFdyaXRlcih3cml0ZXIpOwotICAgICAgICAgICAgICAgICAgICByZXR1cm4gX3RvaEZhY3RvcnkuZ2V0U2VyaWFsaXphdGlvbkhhbmRsZXIoKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyBvciB0cnkgdG8gZ2V0IGFuIE91dHB1dFN0cmVhbSBmcm9tIFJlc3VsdCBvYmplY3QKLSAgICAgICAgICAgICAgICBmaW5hbCBPdXRwdXRTdHJlYW0gb3N0cmVhbSA9IHRhcmdldC5nZXRPdXRwdXRTdHJlYW0oKTsKLSAgICAgICAgICAgICAgICBpZiAob3N0cmVhbSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIF90b2hGYWN0b3J5LnNldE91dHB1dFN0cmVhbShvc3RyZWFtKTsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF90b2hGYWN0b3J5LmdldFNlcmlhbGl6YXRpb25IYW5kbGVyKCk7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgLy8gb3IgdHJ5IHRvIGdldCBqdXN0IGEgc3lzdGVtSWQgc3RyaW5nIGZyb20gUmVzdWx0IG9iamVjdAotICAgICAgICAgICAgICAgIFN0cmluZyBzeXN0ZW1JZCA9IHJlc3VsdC5nZXRTeXN0ZW1JZCgpOwotICAgICAgICAgICAgICAgIGlmIChzeXN0ZW1JZCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIEVycm9yTXNnIGVyciA9IG5ldyBFcnJvck1zZyhFcnJvck1zZy5KQVhQX05PX1JFU1VMVF9FUlIpOwotICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oZXJyLnRvU3RyaW5nKCkpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8vIFN5c3RlbSBJZCBtYXkgYmUgaW4gb25lIG9mIHNldmVyYWwgZm9ybXMsICgxKSBhIHVyaQotICAgICAgICAgICAgICAgIC8vIHRoYXQgc3RhcnRzIHdpdGggJ2ZpbGU6JywgKDIpIHVyaSB0aGF0IHN0YXJ0cyB3aXRoICdodHRwOicKLSAgICAgICAgICAgICAgICAvLyBvciAoMykganVzdCBhIGZpbGVuYW1lIG9uIHRoZSBsb2NhbCBzeXN0ZW0uCi0gICAgICAgICAgICAgICAgVVJMIHVybDsKLSAgICAgICAgICAgICAgICBpZiAoc3lzdGVtSWQuc3RhcnRzV2l0aCgiZmlsZToiKSkgewotICAgICAgICAgICAgICAgICAgICAvLyBpZiBTdHJlYW1SZXN1bHQoRmlsZSkgb3Igc2V0U3lzdGVtSUQoRmlsZSkgd2FzIHVzZWQsCi0gICAgICAgICAgICAgICAgICAgIC8vIHRoZSBzeXN0ZW1JZCB3aWxsIGJlIFVSSSBlbmNvZGVkIGFzIGEgcmVzdWx0IG9mIEZpbGUudG9VUkkoKSwKLSAgICAgICAgICAgICAgICAgICAgLy8gaXQgbXVzdCBiZSBkZWNvZGVkIGZvciB1c2UgYnkgVVJMCi0gICAgICAgICAgICAgICAgICAgIHRyeXsKLSAgICAgICAgICAgICAgICAgICAgICAgIFVSSSB1cmkgPSBuZXcgVVJJKHN5c3RlbUlkKSA7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzeXN0ZW1JZCA9ICJmaWxlOiI7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBob3N0ID0gdXJpLmdldEhvc3QoKTsgLy8gZGVjb2RlZCBTdHJpbmcKLSAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBwYXRoID0gdXJpLmdldFBhdGgoKTsgLy9kZWNvZGVkIFN0cmluZwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBhdGggPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgIHBhdGggPSAiIjsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWYgaG9zdCAoVVJJIGF1dGhvcml0eSkgdGhlbiBmaWxlOi8vICsgaG9zdCArIHBhdGgKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGVsc2UganVzdCBwYXRoIChtYXkgYmUgYWJzb2x1dGUgb3IgcmVsYXRpdmUpCi0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaG9zdCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgc3lzdGVtSWQgKz0gIi8vIiArIGhvc3QgKyBwYXRoOwotICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICBzeXN0ZW1JZCArPSAiLy8iICsgcGF0aDsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBjYXRjaCAoRXhjZXB0aW9uICBleGNlcHRpb24pIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIFVSSSBleGNlcHRpb24gd2hpY2ggbWVhbnMgbm90aGluZyBjYW4gYmUgZG9uZSBzbyBPSyB0byBpZ25vcmUKLSAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgIHVybCA9IG5ldyBVUkwoc3lzdGVtSWQpOwotICAgICAgICAgICAgICAgICAgICBfb3N0cmVhbSA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKHVybC5nZXRGaWxlKCkpOwotICAgICAgICAgICAgICAgICAgICBfdG9oRmFjdG9yeS5zZXRPdXRwdXRTdHJlYW0oX29zdHJlYW0pOwotICAgICAgICAgICAgICAgICAgICByZXR1cm4gX3RvaEZhY3RvcnkuZ2V0U2VyaWFsaXphdGlvbkhhbmRsZXIoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSBpZiAoc3lzdGVtSWQuc3RhcnRzV2l0aCgiaHR0cDoiKSkgewotICAgICAgICAgICAgICAgICAgICB1cmwgPSBuZXcgVVJMKHN5c3RlbUlkKTsKLSAgICAgICAgICAgICAgICAgICAgZmluYWwgVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uID0gdXJsLm9wZW5Db25uZWN0aW9uKCk7Ci0gICAgICAgICAgICAgICAgICAgIF90b2hGYWN0b3J5LnNldE91dHB1dFN0cmVhbShfb3N0cmVhbSA9IGNvbm5lY3Rpb24uZ2V0T3V0cHV0U3RyZWFtKCkpOwotICAgICAgICAgICAgICAgICAgICByZXR1cm4gX3RvaEZhY3RvcnkuZ2V0U2VyaWFsaXphdGlvbkhhbmRsZXIoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIHN5c3RlbSBpZCBpcyBqdXN0IGEgZmlsZW5hbWUKLSAgICAgICAgICAgICAgICAgICAgX3RvaEZhY3Rvcnkuc2V0T3V0cHV0U3RyZWFtKAotICAgICAgICAgICAgICAgICAgICAgICAgX29zdHJlYW0gPSBuZXcgRmlsZU91dHB1dFN0cmVhbShuZXcgRmlsZShzeXN0ZW1JZCkpKTsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF90b2hGYWN0b3J5LmdldFNlcmlhbGl6YXRpb25IYW5kbGVyKCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIC8vIElmIHdlIGNhbm5vdCB3cml0ZSB0byB0aGUgbG9jYXRpb24gc3BlY2lmaWVkIGJ5IHRoZSBTeXN0ZW1JZAotICAgICAgICBjYXRjaCAoVW5rbm93blNlcnZpY2VFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKGUpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihlKTsKLSAgICAgICAgfQotICAgICAgICAvLyBJZiB3ZSBjYW5ub3QgY3JlYXRlIHRoZSBmaWxlIHNwZWNpZmllZCBieSB0aGUgU3lzdGVtSWQKLSAgICAgICAgY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihlKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIGludGVybmFsIERPTSB0aGF0IHdpbGwgYmUgdXNlZCBmb3IgdGhlIG5leHQgdHJhbnNmb3JtYXRpb24KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCBzZXRET00oRE9NIGRvbSkgewotICAgICAgICBfZG9tID0gZG9tOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEJ1aWxkcyBhbiBpbnRlcm5hbCBET00gZnJvbSBhIFRyQVggU291cmNlIG9iamVjdAotICAgICAqLwotICAgIHByaXZhdGUgRE9NIGdldERPTShTb3VyY2Ugc291cmNlKSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24gewotICAgICAgICB0cnkgewotICAgICAgICAgICAgRE9NIGRvbTsKLQotICAgICAgICAgICAgaWYgKHNvdXJjZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgRFRNV1NGaWx0ZXIgd3NmaWx0ZXI7Ci0gICAgICAgICAgICAgICAgaWYgKF90cmFuc2xldCAhPSBudWxsICYmIF90cmFuc2xldCBpbnN0YW5jZW9mIFN0cmlwRmlsdGVyKSB7Ci0gICAgICAgICAgICAgICAgICAgIHdzZmlsdGVyID0gbmV3IERPTVdTRmlsdGVyKF90cmFuc2xldCk7Ci0gICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIHdzZmlsdGVyID0gbnVsbDsKLSAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgIGJvb2xlYW4gaGFzSWRDYWxsID0gKF90cmFuc2xldCAhPSBudWxsKSA/IF90cmFuc2xldC5oYXNJZENhbGwoKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBmYWxzZTsKLQotICAgICAgICAgICAgICAgICBpZiAoX2R0bU1hbmFnZXIgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgX2R0bU1hbmFnZXIgPQotICAgICAgICAgICAgICAgICAgICAgICAgIF90ZmFjdG9yeS5jcmVhdGVOZXdEVE1NYW5hZ2VySW5zdGFuY2UoKTsKLSAgICAgICAgICAgICAgICAgICAgIF9kdG1NYW5hZ2VyLnNldFNlcnZpY2VzTWVjaG5pc20oX3VzZVNlcnZpY2VzTWVjaGFuaXNtKTsKLSAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICBkb20gPSAoRE9NKV9kdG1NYW5hZ2VyLmdldERUTShzb3VyY2UsIGZhbHNlLCB3c2ZpbHRlciwgdHJ1ZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSwgZmFsc2UsIDAsIGhhc0lkQ2FsbCk7Ci0gICAgICAgICAgICB9IGVsc2UgaWYgKF9kb20gIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICBkb20gPSBfZG9tOwotICAgICAgICAgICAgICAgICBfZG9tID0gbnVsbDsgIC8vIHVzZSBvbmx5IG9uY2UsIHNvIHJlc2V0IHRvICdudWxsJwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmICghX2lzSWRlbnRpdHkpIHsKLSAgICAgICAgICAgICAgICAvLyBHaXZlIHRoZSB0cmFuc2xldCB0aGUgb3Bwb3J0dW5pdHkgdG8gbWFrZSBhIHByZXBhc3Mgb2YKLSAgICAgICAgICAgICAgICAvLyB0aGUgZG9jdW1lbnQsIGluIGNhc2UgaXQgY2FuIGV4dHJhY3QgdXNlZnVsIGluZm9ybWF0aW9uIGVhcmx5Ci0gICAgICAgICAgICAgICAgX3RyYW5zbGV0LnByZXBhc3NEb2N1bWVudChkb20pOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICByZXR1cm4gZG9tOwotCi0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICBpZiAoX2Vycm9yTGlzdGVuZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHBvc3RFcnJvclRvTGlzdGVuZXIoZS5nZXRNZXNzYWdlKCkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKGUpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUge0BsaW5rIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy50cmF4LlRyYW5zZm9ybWVyRmFjdG9yeUltcGx9Ci0gICAgICogb2JqZWN0IHRoYXQgY3JlYXRlIHRoaXMgPGNvZGU+VHJhbnNmb3JtZXI8L2NvZGU+LgotICAgICAqLwotICAgIHByb3RlY3RlZCBUcmFuc2Zvcm1lckZhY3RvcnlJbXBsIGdldFRyYW5zZm9ybWVyRmFjdG9yeSgpIHsKLSAgICAgICAgcmV0dXJuIF90ZmFjdG9yeTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSB7QGxpbmsgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnJ1bnRpbWUub3V0cHV0LlRyYW5zbGV0T3V0cHV0SGFuZGxlckZhY3Rvcnl9Ci0gICAgICogb2JqZWN0IHRoYXQgY3JlYXRlIHRoZSA8Y29kZT5UcmFuc2xldE91dHB1dEhhbmRsZXI8L2NvZGU+LgotICAgICAqLwotICAgIHByb3RlY3RlZCBUcmFuc2xldE91dHB1dEhhbmRsZXJGYWN0b3J5IGdldFRyYW5zbGV0T3V0cHV0SGFuZGxlckZhY3RvcnkoKSB7Ci0gICAgICAgIHJldHVybiBfdG9oRmFjdG9yeTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgdHJhbnNmb3JtSWRlbnRpdHkoU291cmNlIHNvdXJjZSwgU2VyaWFsaXphdGlvbkhhbmRsZXIgaGFuZGxlcikKLSAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgLy8gR2V0IHN5c3RlbUlkIGZyb20gc291cmNlCi0gICAgICAgIGlmIChzb3VyY2UgIT0gbnVsbCkgewotICAgICAgICAgICAgX3NvdXJjZVN5c3RlbUlkID0gc291cmNlLmdldFN5c3RlbUlkKCk7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoc291cmNlIGluc3RhbmNlb2YgU3RyZWFtU291cmNlKSB7Ci0gICAgICAgICAgICBmaW5hbCBTdHJlYW1Tb3VyY2Ugc3RyZWFtID0gKFN0cmVhbVNvdXJjZSkgc291cmNlOwotICAgICAgICAgICAgZmluYWwgSW5wdXRTdHJlYW0gc3RyZWFtSW5wdXQgPSBzdHJlYW0uZ2V0SW5wdXRTdHJlYW0oKTsKLSAgICAgICAgICAgIGZpbmFsIFJlYWRlciBzdHJlYW1SZWFkZXIgPSBzdHJlYW0uZ2V0UmVhZGVyKCk7Ci0gICAgICAgICAgICBmaW5hbCBYTUxSZWFkZXIgcmVhZGVyID0gX3JlYWRlck1hbmFnZXIuZ2V0WE1MUmVhZGVyKCk7Ci0KLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgLy8gSG9vayB1cCByZWFkZXIgYW5kIG91dHB1dCBoYW5kbGVyCi0gICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgcmVhZGVyLnNldFByb3BlcnR5KExFWElDQUxfSEFORExFUl9QUk9QRVJUWSwgaGFuZGxlcik7Ci0gICAgICAgICAgICAgICAgICAgIHJlYWRlci5zZXRGZWF0dXJlKE5BTUVTUEFDRV9QUkVGSVhFU19GRUFUVVJFLCB0cnVlKTsKLSAgICAgICAgICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgICAgICAvLyBGYWxscyB0aHJvdWdoCi0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHJlYWRlci5zZXRDb250ZW50SGFuZGxlcihoYW5kbGVyKTsKLQotICAgICAgICAgICAgICAgIC8vIENyZWF0ZSBpbnB1dCBzb3VyY2UgZnJvbSBzb3VyY2UKLSAgICAgICAgICAgICAgICBJbnB1dFNvdXJjZSBpbnB1dDsKLSAgICAgICAgICAgICAgICBpZiAoc3RyZWFtSW5wdXQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBpbnB1dCA9IG5ldyBJbnB1dFNvdXJjZShzdHJlYW1JbnB1dCk7Ci0gICAgICAgICAgICAgICAgICAgIGlucHV0LnNldFN5c3RlbUlkKF9zb3VyY2VTeXN0ZW1JZCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgaWYgKHN0cmVhbVJlYWRlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlucHV0ID0gbmV3IElucHV0U291cmNlKHN0cmVhbVJlYWRlcik7Ci0gICAgICAgICAgICAgICAgICAgIGlucHV0LnNldFN5c3RlbUlkKF9zb3VyY2VTeXN0ZW1JZCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgaWYgKF9zb3VyY2VTeXN0ZW1JZCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlucHV0ID0gbmV3IElucHV0U291cmNlKF9zb3VyY2VTeXN0ZW1JZCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICBFcnJvck1zZyBlcnIgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuSkFYUF9OT19TT1VSQ0VfRVJSKTsKLSAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKGVyci50b1N0cmluZygpKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyBTdGFydCBwdXNoaW5nIFNBWCBldmVudHMKLSAgICAgICAgICAgICAgICByZWFkZXIucGFyc2UoaW5wdXQpOwotICAgICAgICAgICAgfSBmaW5hbGx5IHsKLSAgICAgICAgICAgICAgICBfcmVhZGVyTWFuYWdlci5yZWxlYXNlWE1MUmVhZGVyKHJlYWRlcik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gZWxzZSBpZiAoc291cmNlIGluc3RhbmNlb2YgU0FYU291cmNlKSB7Ci0gICAgICAgICAgICBmaW5hbCBTQVhTb3VyY2Ugc2F4ID0gKFNBWFNvdXJjZSkgc291cmNlOwotICAgICAgICAgICAgWE1MUmVhZGVyIHJlYWRlciA9IHNheC5nZXRYTUxSZWFkZXIoKTsKLSAgICAgICAgICAgIGZpbmFsIElucHV0U291cmNlIGlucHV0ID0gc2F4LmdldElucHV0U291cmNlKCk7Ci0gICAgICAgICAgICBib29sZWFuIHVzZXJSZWFkZXIgPSB0cnVlOwotCi0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIC8vIENyZWF0ZSBhIHJlYWRlciBpZiBub3Qgc2V0IGJ5IHVzZXIKLSAgICAgICAgICAgICAgICBpZiAocmVhZGVyID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgcmVhZGVyID0gX3JlYWRlck1hbmFnZXIuZ2V0WE1MUmVhZGVyKCk7Ci0gICAgICAgICAgICAgICAgICAgIHVzZXJSZWFkZXIgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyBIb29rIHVwIHJlYWRlciBhbmQgb3V0cHV0IGhhbmRsZXIKLSAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICByZWFkZXIuc2V0UHJvcGVydHkoTEVYSUNBTF9IQU5ETEVSX1BST1BFUlRZLCBoYW5kbGVyKTsKLSAgICAgICAgICAgICAgICAgICAgcmVhZGVyLnNldEZlYXR1cmUoTkFNRVNQQUNFX1BSRUZJWEVTX0ZFQVRVUkUsIHRydWUpOwotICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIEZhbGxzIHRocm91Z2gKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgcmVhZGVyLnNldENvbnRlbnRIYW5kbGVyKGhhbmRsZXIpOwotCi0gICAgICAgICAgICAgICAgLy8gU3RhcnQgcHVzaGluZyBTQVggZXZlbnRzCi0gICAgICAgICAgICAgICAgcmVhZGVyLnBhcnNlKGlucHV0KTsKLSAgICAgICAgICAgIH0gZmluYWxseSB7Ci0gICAgICAgICAgICAgICAgaWYgKCF1c2VyUmVhZGVyKSB7Ci0gICAgICAgICAgICAgICAgICAgIF9yZWFkZXJNYW5hZ2VyLnJlbGVhc2VYTUxSZWFkZXIocmVhZGVyKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gZWxzZSBpZiAoc291cmNlIGluc3RhbmNlb2YgU3RBWFNvdXJjZSkgewotICAgICAgICAgICAgZmluYWwgU3RBWFNvdXJjZSBzdGF4U291cmNlID0gKFN0QVhTb3VyY2Upc291cmNlOwotICAgICAgICAgICAgU3RBWEV2ZW50MlNBWCBzdGF4ZXZlbnQyc2F4OwotICAgICAgICAgICAgU3RBWFN0cmVhbTJTQVggc3RheFN0cmVhbTJTQVg7Ci0gICAgICAgICAgICBpZiAoc3RheFNvdXJjZS5nZXRYTUxFdmVudFJlYWRlcigpICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmaW5hbCBYTUxFdmVudFJlYWRlciB4bWxFdmVudFJlYWRlciA9IHN0YXhTb3VyY2UuZ2V0WE1MRXZlbnRSZWFkZXIoKTsKLSAgICAgICAgICAgICAgICBzdGF4ZXZlbnQyc2F4ID0gbmV3IFN0QVhFdmVudDJTQVgoeG1sRXZlbnRSZWFkZXIpOwotICAgICAgICAgICAgICAgIHN0YXhldmVudDJzYXguc2V0Q29udGVudEhhbmRsZXIoaGFuZGxlcik7Ci0gICAgICAgICAgICAgICAgc3RheGV2ZW50MnNheC5wYXJzZSgpOwotICAgICAgICAgICAgICAgIGhhbmRsZXIuZmx1c2hQZW5kaW5nKCk7Ci0gICAgICAgICAgICB9IGVsc2UgaWYgKHN0YXhTb3VyY2UuZ2V0WE1MU3RyZWFtUmVhZGVyKCkgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZpbmFsIFhNTFN0cmVhbVJlYWRlciB4bWxTdHJlYW1SZWFkZXIgPSBzdGF4U291cmNlLmdldFhNTFN0cmVhbVJlYWRlcigpOwotICAgICAgICAgICAgICAgIHN0YXhTdHJlYW0yU0FYID0gbmV3IFN0QVhTdHJlYW0yU0FYKHhtbFN0cmVhbVJlYWRlcik7Ci0gICAgICAgICAgICAgICAgc3RheFN0cmVhbTJTQVguc2V0Q29udGVudEhhbmRsZXIoaGFuZGxlcik7Ci0gICAgICAgICAgICAgICAgc3RheFN0cmVhbTJTQVgucGFyc2UoKTsKLSAgICAgICAgICAgICAgICBoYW5kbGVyLmZsdXNoUGVuZGluZygpOwotICAgICAgICAgICAgfQotICAgICAgICB9IGVsc2UgaWYgKHNvdXJjZSBpbnN0YW5jZW9mIERPTVNvdXJjZSkgewotICAgICAgICAgICAgZmluYWwgRE9NU291cmNlIGRvbXNyYyA9IChET01Tb3VyY2UpIHNvdXJjZTsKLSAgICAgICAgICAgIG5ldyBET00yVE8oZG9tc3JjLmdldE5vZGUoKSwgaGFuZGxlcikucGFyc2UoKTsKLSAgICAgICAgfSBlbHNlIGlmIChzb3VyY2UgaW5zdGFuY2VvZiBYU0xUQ1NvdXJjZSkgewotICAgICAgICAgICAgZmluYWwgRE9NIGRvbSA9ICgoWFNMVENTb3VyY2UpIHNvdXJjZSkuZ2V0RE9NKG51bGwsIF90cmFuc2xldCk7Ci0gICAgICAgICAgICAoKFNBWEltcGwpZG9tKS5jb3B5KGhhbmRsZXIpOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgRXJyb3JNc2cgZXJyID0gbmV3IEVycm9yTXNnKEVycm9yTXNnLkpBWFBfTk9fU09VUkNFX0VSUik7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oZXJyLnRvU3RyaW5nKCkpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSW50ZXJuYWwgdHJhbnNmb3JtYXRpb24gbWV0aG9kIC0gdXNlcyB0aGUgaW50ZXJuYWwgQVBJcyBvZiBYU0xUQwotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCB0cmFuc2Zvcm0oU291cmNlIHNvdXJjZSwgU2VyaWFsaXphdGlvbkhhbmRsZXIgaGFuZGxlciwKLSAgICAgICAgU3RyaW5nIGVuY29kaW5nKSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAvKgotICAgICAgICAgICAgICogQWNjb3JkaW5nIHRvIEpBWFAxLjIsIG5ldyBTQVhTb3VyY2UoKS9TdHJlYW1Tb3VyY2UoKQotICAgICAgICAgICAgICogc2hvdWxkIGNyZWF0ZSBhbiBlbXB0eSBpbnB1dCB0cmVlLCB3aXRoIGEgZGVmYXVsdCByb290IG5vZGUuCi0gICAgICAgICAgICAgKiBuZXcgRE9NU291cmNlKCljcmVhdGVzIGFuIGVtcHR5IGRvY3VtZW50IHVzaW5nIERvY3VtZW50QnVpbGRlci4KLSAgICAgICAgICAgICAqIG5ld0RvY3VtZW50KCk7IFVzZSBEb2N1bWVudEJ1aWxkZXIubmV3RG9jdW1lbnQoKSBmb3IgYWxsIDMKLSAgICAgICAgICAgICAqIHNpdHVhdGlvbnMsIHNpbmNlIHRoZXJlIGlzIG5vIGNsZWFyIHNwZWMuIGhvdyB0byBjcmVhdGUKLSAgICAgICAgICAgICAqIGFuIGVtcHR5IHRyZWUgd2hlbiBib3RoIFNBWFNvdXJjZSgpIGFuZCBTdHJlYW1Tb3VyY2UoKSBhcmUgdXNlZC4KLSAgICAgICAgICAgICAqLwotICAgICAgICAgICAgaWYgKChzb3VyY2UgaW5zdGFuY2VvZiBTdHJlYW1Tb3VyY2UgJiYgc291cmNlLmdldFN5c3RlbUlkKCk9PW51bGwKLSAgICAgICAgICAgICAgICAmJiAoKFN0cmVhbVNvdXJjZSlzb3VyY2UpLmdldElucHV0U3RyZWFtKCk9PW51bGwgJiYKLSAgICAgICAgICAgICAgICAoKFN0cmVhbVNvdXJjZSlzb3VyY2UpLmdldFJlYWRlcigpPT1udWxsKXx8Ci0gICAgICAgICAgICAgICAgKHNvdXJjZSBpbnN0YW5jZW9mIFNBWFNvdXJjZSAmJgotICAgICAgICAgICAgICAgICgoU0FYU291cmNlKXNvdXJjZSkuZ2V0SW5wdXRTb3VyY2UoKT09bnVsbCAmJgotICAgICAgICAgICAgICAgICgoU0FYU291cmNlKXNvdXJjZSkuZ2V0WE1MUmVhZGVyKCk9PW51bGwgKXx8Ci0gICAgICAgICAgICAgICAgKHNvdXJjZSBpbnN0YW5jZW9mIERPTVNvdXJjZSAmJgotICAgICAgICAgICAgICAgICgoRE9NU291cmNlKXNvdXJjZSkuZ2V0Tm9kZSgpPT1udWxsKSl7Ci0gICAgICAgICAgICAgICAgICAgICAgICBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGJ1aWxkZXJGID0gRmFjdG9yeUltcGwuZ2V0RE9NRmFjdG9yeShfdXNlU2VydmljZXNNZWNoYW5pc20pOwotICAgICAgICAgICAgICAgICAgICAgICAgRG9jdW1lbnRCdWlsZGVyIGJ1aWxkZXIgPSBidWlsZGVyRi5uZXdEb2N1bWVudEJ1aWxkZXIoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBzeXN0ZW1JRCA9IHNvdXJjZS5nZXRTeXN0ZW1JZCgpOwotICAgICAgICAgICAgICAgICAgICAgICAgc291cmNlID0gbmV3IERPTVNvdXJjZShidWlsZGVyLm5ld0RvY3VtZW50KCkpOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBDb3B5IHN5c3RlbSBJRCBmcm9tIG9yaWdpbmFsLCBlbXB0eSBTb3VyY2UgdG8gbmV3Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3lzdGVtSUQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICBzb3VyY2Uuc2V0U3lzdGVtSWQoc3lzdGVtSUQpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKF9pc0lkZW50aXR5KSB7Ci0gICAgICAgICAgICAgICAgdHJhbnNmb3JtSWRlbnRpdHkoc291cmNlLCBoYW5kbGVyKTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgX3RyYW5zbGV0LnRyYW5zZm9ybShnZXRET00oc291cmNlKSwgaGFuZGxlcik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gY2F0Y2ggKFRyYW5zbGV0RXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIGlmIChfZXJyb3JMaXN0ZW5lciAhPSBudWxsKSBwb3N0RXJyb3JUb0xpc3RlbmVyKGUuZ2V0TWVzc2FnZSgpKTsKLSAgICAgICAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihlKTsKLSAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICBpZiAoX2Vycm9yTGlzdGVuZXIgIT0gbnVsbCkgcG9zdEVycm9yVG9MaXN0ZW5lcihlLmdldE1lc3NhZ2UoKSk7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oZSk7Ci0gICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICBpZiAoX2Vycm9yTGlzdGVuZXIgIT0gbnVsbCkgcG9zdEVycm9yVG9MaXN0ZW5lcihlLmdldE1lc3NhZ2UoKSk7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oZSk7Ci0gICAgICAgIH0gZmluYWxseSB7Ci0gICAgICAgICAgICBfZHRtTWFuYWdlciA9IG51bGw7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBJZiB3ZSBjcmVhdGUgYW4gb3V0cHV0IHN0cmVhbSBmb3IgdGhlIFJlc3VsdCwgd2UgbmVlZCB0byBjbG9zZSBpdCBhZnRlciB0aGUgdHJhbnNmb3JtYXRpb24uCi0gICAgICAgIGlmIChfb3N0cmVhbSAhPSBudWxsKSB7Ci0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIF9vc3RyZWFtLmNsb3NlKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXRjaCAoSU9FeGNlcHRpb24gZSkge30KLSAgICAgICAgICAgIF9vc3RyZWFtID0gbnVsbDsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEltcGxlbWVudHMgSkFYUCdzIFRyYW5zZm9ybWVyLmdldEVycm9yTGlzdGVuZXIoKQotICAgICAqIEdldCB0aGUgZXJyb3IgZXZlbnQgaGFuZGxlciBpbiBlZmZlY3QgZm9yIHRoZSB0cmFuc2Zvcm1hdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIGVycm9yIGV2ZW50IGhhbmRsZXIgY3VycmVudGx5IGluIGVmZmVjdAotICAgICAqLwotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyBFcnJvckxpc3RlbmVyIGdldEVycm9yTGlzdGVuZXIoKSB7Ci0gICAgICAgIHJldHVybiBfZXJyb3JMaXN0ZW5lcjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJbXBsZW1lbnRzIEpBWFAncyBUcmFuc2Zvcm1lci5zZXRFcnJvckxpc3RlbmVyKCkKLSAgICAgKiBTZXQgdGhlIGVycm9yIGV2ZW50IGxpc3RlbmVyIGluIGVmZmVjdCBmb3IgdGhlIHRyYW5zZm9ybWF0aW9uLgotICAgICAqIFJlZ2lzdGVyIGEgbWVzc2FnZSBoYW5kbGVyIGluIHRoZSB0cmFuc2xldCBpbiBvcmRlciB0byBmb3J3YXJkCi0gICAgICogeHNsOm1lc3NhZ2VzIHRvIGVycm9yIGxpc3RlbmVyLgotICAgICAqCi0gICAgICogQHBhcmFtIGxpc3RlbmVyIFRoZSBlcnJvciBldmVudCBsaXN0ZW5lciB0byB1c2UKLSAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgotICAgICAqLwotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyB2b2lkIHNldEVycm9yTGlzdGVuZXIoRXJyb3JMaXN0ZW5lciBsaXN0ZW5lcikKLSAgICAgICAgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChsaXN0ZW5lciA9PSBudWxsKSB7Ci0gICAgICAgICAgICBFcnJvck1zZyBlcnIgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuRVJST1JfTElTVEVORVJfTlVMTF9FUlIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlRyYW5zZm9ybWVyIik7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKGVyci50b1N0cmluZygpKTsKLSAgICAgICAgfQotICAgICAgICBfZXJyb3JMaXN0ZW5lciA9IGxpc3RlbmVyOwotCi0gICAgICAgIC8vIFJlZ2lzdGVyIGEgbWVzc2FnZSBoYW5kbGVyIHRvIHJlcG9ydCB4c2w6bWVzc2FnZXMKLSAgICBpZiAoX3RyYW5zbGV0ICE9IG51bGwpCi0gICAgICAgIF90cmFuc2xldC5zZXRNZXNzYWdlSGFuZGxlcihuZXcgTWVzc2FnZUhhbmRsZXIoX2Vycm9yTGlzdGVuZXIpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJbmZvcm0gVHJBWCBlcnJvciBsaXN0ZW5lciBvZiBhbiBlcnJvcgotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCBwb3N0RXJyb3JUb0xpc3RlbmVyKFN0cmluZyBtZXNzYWdlKSB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBfZXJyb3JMaXN0ZW5lci5lcnJvcihuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24obWVzc2FnZSkpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChUcmFuc2Zvcm1lckV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAvLyBpZ25vcmVkIC0gdHJhbnNmb3JtYXRpb24gY2Fubm90IGJlIGNvbnRpbnVlZAotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSW5mb3JtIFRyQVggZXJyb3IgbGlzdGVuZXIgb2YgYSB3YXJuaW5nCi0gICAgICovCi0gICAgcHJpdmF0ZSB2b2lkIHBvc3RXYXJuaW5nVG9MaXN0ZW5lcihTdHJpbmcgbWVzc2FnZSkgewotICAgICAgICB0cnkgewotICAgICAgICAgICAgX2Vycm9yTGlzdGVuZXIud2FybmluZyhuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24obWVzc2FnZSkpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChUcmFuc2Zvcm1lckV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAvLyBpZ25vcmVkIC0gdHJhbnNmb3JtYXRpb24gY2Fubm90IGJlIGNvbnRpbnVlZAotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSW1wbGVtZW50cyBKQVhQJ3MgVHJhbnNmb3JtZXIuZ2V0T3V0cHV0UHJvcGVydGllcygpLgotICAgICAqIFJldHVybnMgYSBjb3B5IG9mIHRoZSBvdXRwdXQgcHJvcGVydGllcyBmb3IgdGhlIHRyYW5zZm9ybWF0aW9uLiBUaGlzIGlzCi0gICAgICogYSBzZXQgb2YgbGF5ZXJlZCBwcm9wZXJ0aWVzLiBUaGUgZmlyc3QgbGF5ZXIgY29udGFpbnMgcHJvcGVydGllcyBzZXQgYnkKLSAgICAgKiBjYWxscyB0byBzZXRPdXRwdXRQcm9wZXJ0eSgpIGFuZCBzZXRPdXRwdXRQcm9wZXJ0aWVzKCkgb24gdGhpcyBjbGFzcywKLSAgICAgKiBhbmQgdGhlIG91dHB1dCBzZXR0aW5ncyBkZWZpbmVkIGluIHRoZSBzdHlsZXNoZWV0J3MgPHhzbDpvdXRwdXQ+Ci0gICAgICogZWxlbWVudCBtYWtlcyB1cCB0aGUgc2Vjb25kIGxldmVsLCB3aGlsZSB0aGUgZGVmYXVsdCBYU0xUIG91dHB1dAotICAgICAqIHNldHRpbmdzIGFyZSByZXR1cm5lZCBvbiB0aGUgdGhpcmQgbGV2ZWwuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFByb3BlcnRpZXMgaW4gZWZmZWN0IGZvciB0aGlzIFRyYW5zZm9ybWVyCi0gICAgICovCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIFByb3BlcnRpZXMgZ2V0T3V0cHV0UHJvcGVydGllcygpIHsKLSAgICAgICAgcmV0dXJuIChQcm9wZXJ0aWVzKSBfcHJvcGVydGllcy5jbG9uZSgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEltcGxlbWVudHMgSkFYUCdzIFRyYW5zZm9ybWVyLmdldE91dHB1dFByb3BlcnR5KCkuCi0gICAgICogR2V0IGFuIG91dHB1dCBwcm9wZXJ0eSB0aGF0IGlzIGluIGVmZmVjdCBmb3IgdGhlIHRyYW5zZm9ybWF0aW9uLiBUaGUKLSAgICAgKiBwcm9wZXJ0eSBzcGVjaWZpZWQgbWF5IGJlIGEgcHJvcGVydHkgdGhhdCB3YXMgc2V0IHdpdGggc2V0T3V0cHV0UHJvcGVydHksCi0gICAgICogb3IgaXQgbWF5IGJlIGEgcHJvcGVydHkgc3BlY2lmaWVkIGluIHRoZSBzdHlsZXNoZWV0LgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgQSBub24tbnVsbCBzdHJpbmcgdGhhdCBjb250YWlucyB0aGUgbmFtZSBvZiB0aGUgcHJvcGVydHkKLSAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgcHJvcGVydHkgbmFtZSBpcyBub3Qga25vd24KLSAgICAgKi8KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgU3RyaW5nIGdldE91dHB1dFByb3BlcnR5KFN0cmluZyBuYW1lKQotICAgICAgICB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAoIXZhbGlkT3V0cHV0UHJvcGVydHkobmFtZSkpIHsKLSAgICAgICAgICAgIEVycm9yTXNnIGVyciA9IG5ldyBFcnJvck1zZyhFcnJvck1zZy5KQVhQX1VOS05PV05fUFJPUF9FUlIsIG5hbWUpOwotICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihlcnIudG9TdHJpbmcoKSk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIF9wcm9wZXJ0aWVzLmdldFByb3BlcnR5KG5hbWUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEltcGxlbWVudHMgSkFYUCdzIFRyYW5zZm9ybWVyLnNldE91dHB1dFByb3BlcnRpZXMoKS4KLSAgICAgKiBTZXQgdGhlIG91dHB1dCBwcm9wZXJ0aWVzIGZvciB0aGUgdHJhbnNmb3JtYXRpb24uIFRoZXNlIHByb3BlcnRpZXMKLSAgICAgKiB3aWxsIG92ZXJyaWRlIHByb3BlcnRpZXMgc2V0IGluIHRoZSBUZW1wbGF0ZXMgd2l0aCB4c2w6b3V0cHV0LgotICAgICAqIFVucmVjb2duaXNlZCBwcm9wZXJ0aWVzIHdpbGwgYmUgcXVpdGVseSBpZ25vcmVkLgotICAgICAqCi0gICAgICogQHBhcmFtIHByb3BlcnRpZXMgVGhlIHByb3BlcnRpZXMgdG8gdXNlIGZvciB0aGUgVHJhbnNmb3JtZXIKLSAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBOZXZlciwgZXJyb3JzIGFyZSBpZ25vcmVkCi0gICAgICovCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIHZvaWQgc2V0T3V0cHV0UHJvcGVydGllcyhQcm9wZXJ0aWVzIHByb3BlcnRpZXMpCi0gICAgICAgIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGlmIChwcm9wZXJ0aWVzICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZpbmFsIEVudW1lcmF0aW9uIG5hbWVzID0gcHJvcGVydGllcy5wcm9wZXJ0eU5hbWVzKCk7Ci0KLSAgICAgICAgICAgIHdoaWxlIChuYW1lcy5oYXNNb3JlRWxlbWVudHMoKSkgewotICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBuYW1lID0gKFN0cmluZykgbmFtZXMubmV4dEVsZW1lbnQoKTsKLQotICAgICAgICAgICAgICAgIC8vIElnbm9yZSBsb3dlciBsYXllciBwcm9wZXJ0aWVzCi0gICAgICAgICAgICAgICAgaWYgKGlzRGVmYXVsdFByb3BlcnR5KG5hbWUsIHByb3BlcnRpZXMpKSBjb250aW51ZTsKLQotICAgICAgICAgICAgICAgIGlmICh2YWxpZE91dHB1dFByb3BlcnR5KG5hbWUpKSB7Ci0gICAgICAgICAgICAgICAgICAgIF9wcm9wZXJ0aWVzLnNldFByb3BlcnR5KG5hbWUsIHByb3BlcnRpZXMuZ2V0UHJvcGVydHkobmFtZSkpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgRXJyb3JNc2cgZXJyID0gbmV3IEVycm9yTXNnKEVycm9yTXNnLkpBWFBfVU5LTk9XTl9QUk9QX0VSUiwgbmFtZSk7Ci0gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oZXJyLnRvU3RyaW5nKCkpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIF9wcm9wZXJ0aWVzID0gX3Byb3BlcnRpZXNDbG9uZTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEltcGxlbWVudHMgSkFYUCdzIFRyYW5zZm9ybWVyLnNldE91dHB1dFByb3BlcnR5KCkuCi0gICAgICogR2V0IGFuIG91dHB1dCBwcm9wZXJ0eSB0aGF0IGlzIGluIGVmZmVjdCBmb3IgdGhlIHRyYW5zZm9ybWF0aW9uLiBUaGUKLSAgICAgKiBwcm9wZXJ0eSBzcGVjaWZpZWQgbWF5IGJlIGEgcHJvcGVydHkgdGhhdCB3YXMgc2V0IHdpdGgKLSAgICAgKiBzZXRPdXRwdXRQcm9wZXJ0eSgpLCBvciBpdCBtYXkgYmUgYSBwcm9wZXJ0eSBzcGVjaWZpZWQgaW4gdGhlIHN0eWxlc2hlZXQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgcHJvcGVydHkgdG8gc2V0Ci0gICAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZSB0byBhc3NpZ24gdG8gdGhlIHByb3BlcnR5Ci0gICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gTmV2ZXIsIGVycm9ycyBhcmUgaWdub3JlZAotICAgICAqLwotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyB2b2lkIHNldE91dHB1dFByb3BlcnR5KFN0cmluZyBuYW1lLCBTdHJpbmcgdmFsdWUpCi0gICAgICAgIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGlmICghdmFsaWRPdXRwdXRQcm9wZXJ0eShuYW1lKSkgewotICAgICAgICAgICAgRXJyb3JNc2cgZXJyID0gbmV3IEVycm9yTXNnKEVycm9yTXNnLkpBWFBfVU5LTk9XTl9QUk9QX0VSUiwgbmFtZSk7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKGVyci50b1N0cmluZygpKTsKLSAgICAgICAgfQotICAgICAgICBfcHJvcGVydGllcy5zZXRQcm9wZXJ0eShuYW1lLCB2YWx1ZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSW50ZXJuYWwgbWV0aG9kIHRvIHBhc3MgYW55IHByb3BlcnRpZXMgdG8gdGhlIHRyYW5zbGV0IHByaW9yIHRvCi0gICAgICogaW5pdGlhdGluZyB0aGUgdHJhbnNmb3JtYXRpb24KLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgdHJhbnNmZXJPdXRwdXRQcm9wZXJ0aWVzKEFic3RyYWN0VHJhbnNsZXQgdHJhbnNsZXQpCi0gICAgewotICAgICAgICAvLyBSZXR1cm4gcmlnaHQgbm93IGlmIG5vIHByb3BlcnRpZXMgYXJlIHNldAotICAgICAgICBpZiAoX3Byb3BlcnRpZXMgPT0gbnVsbCkgcmV0dXJuOwotCi0gICAgICAgIC8vIEdldCBhIGxpc3Qgb2YgYWxsIHRoZSBkZWZpbmVkIHByb3BlcnRpZXMKLSAgICAgICAgRW51bWVyYXRpb24gbmFtZXMgPSBfcHJvcGVydGllcy5wcm9wZXJ0eU5hbWVzKCk7Ci0gICAgICAgIHdoaWxlIChuYW1lcy5oYXNNb3JlRWxlbWVudHMoKSkgewotICAgICAgICAgICAgLy8gTm90ZSB0aGUgdXNlIG9mIGdldCgpIGluc3RlYWQgb2YgZ2V0UHJvcGVydHkoKQotICAgICAgICAgICAgU3RyaW5nIG5hbWUgID0gKFN0cmluZykgbmFtZXMubmV4dEVsZW1lbnQoKTsKLSAgICAgICAgICAgIFN0cmluZyB2YWx1ZSA9IChTdHJpbmcpIF9wcm9wZXJ0aWVzLmdldChuYW1lKTsKLQotICAgICAgICAgICAgLy8gSWdub3JlIGRlZmF1bHQgcHJvcGVydGllcwotICAgICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIGNvbnRpbnVlOwotCi0gICAgICAgICAgICAvLyBQYXNzIHByb3BlcnR5IHZhbHVlIHRvIHRyYW5zbGV0IC0gb3ZlcnJpZGUgcHJldmlvdXMgc2V0dGluZwotICAgICAgICAgICAgaWYgKG5hbWUuZXF1YWxzKE91dHB1dEtleXMuRU5DT0RJTkcpKSB7Ci0gICAgICAgICAgICAgICAgdHJhbnNsZXQuX2VuY29kaW5nID0gdmFsdWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFscyhPdXRwdXRLZXlzLk1FVEhPRCkpIHsKLSAgICAgICAgICAgICAgICB0cmFuc2xldC5fbWV0aG9kID0gdmFsdWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFscyhPdXRwdXRLZXlzLkRPQ1RZUEVfUFVCTElDKSkgewotICAgICAgICAgICAgICAgIHRyYW5zbGV0Ll9kb2N0eXBlUHVibGljID0gdmFsdWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFscyhPdXRwdXRLZXlzLkRPQ1RZUEVfU1lTVEVNKSkgewotICAgICAgICAgICAgICAgIHRyYW5zbGV0Ll9kb2N0eXBlU3lzdGVtID0gdmFsdWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFscyhPdXRwdXRLZXlzLk1FRElBX1RZUEUpKSB7Ci0gICAgICAgICAgICAgICAgdHJhbnNsZXQuX21lZGlhVHlwZSA9IHZhbHVlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAobmFtZS5lcXVhbHMoT3V0cHV0S2V5cy5TVEFOREFMT05FKSkgewotICAgICAgICAgICAgICAgIHRyYW5zbGV0Ll9zdGFuZGFsb25lID0gdmFsdWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFscyhPdXRwdXRLZXlzLlZFUlNJT04pKSB7Ci0gICAgICAgICAgICAgICAgdHJhbnNsZXQuX3ZlcnNpb24gPSB2YWx1ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzKE91dHB1dEtleXMuT01JVF9YTUxfREVDTEFSQVRJT04pKSB7Ci0gICAgICAgICAgICAgICAgdHJhbnNsZXQuX29taXRIZWFkZXIgPQotICAgICAgICAgICAgICAgICAgICAodmFsdWUgIT0gbnVsbCAmJiB2YWx1ZS50b0xvd2VyQ2FzZSgpLmVxdWFscygieWVzIikpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAobmFtZS5lcXVhbHMoT3V0cHV0S2V5cy5JTkRFTlQpKSB7Ci0gICAgICAgICAgICAgICAgdHJhbnNsZXQuX2luZGVudCA9Ci0gICAgICAgICAgICAgICAgICAgICh2YWx1ZSAhPSBudWxsICYmIHZhbHVlLnRvTG93ZXJDYXNlKCkuZXF1YWxzKCJ5ZXMiKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFscyhPdXRwdXRQcm9wZXJ0aWVzRmFjdG9yeS5TX0JVSUxUSU5fT0xEX0VYVEVOU0lPTlNfVU5JVkVSU0FMICsiaW5kZW50LWFtb3VudCIpKSB7Ci0gICAgICAgICAgICAgICAgIGlmICh2YWx1ZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICB0cmFuc2xldC5faW5kZW50YW1vdW50ID0gSW50ZWdlci5wYXJzZUludCh2YWx1ZSk7Ci0gICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzKE91dHB1dFByb3BlcnRpZXNGYWN0b3J5LlNfQlVJTFRJTl9FWFRFTlNJT05TX1VOSVZFUlNBTCArImluZGVudC1hbW91bnQiKSkgewotICAgICAgICAgICAgICAgICBpZiAodmFsdWUgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgdHJhbnNsZXQuX2luZGVudGFtb3VudCA9IEludGVnZXIucGFyc2VJbnQodmFsdWUpOwotICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFscyhPdXRwdXRLZXlzLkNEQVRBX1NFQ1RJT05fRUxFTUVOVFMpKSB7Ci0gICAgICAgICAgICAgICAgaWYgKHZhbHVlICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgdHJhbnNsZXQuX2NkYXRhID0gbnVsbDsgLy8gY2xlYXIgcHJldmlvdXMgc2V0dGluZwotICAgICAgICAgICAgICAgICAgICBTdHJpbmdUb2tlbml6ZXIgZSA9IG5ldyBTdHJpbmdUb2tlbml6ZXIodmFsdWUpOwotICAgICAgICAgICAgICAgICAgICB3aGlsZSAoZS5oYXNNb3JlVG9rZW5zKCkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zbGV0LmFkZENkYXRhRWxlbWVudChlLm5leHRUb2tlbigpKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzKE91dHB1dFByb3BlcnRpZXNGYWN0b3J5Lk9SQUNMRV9JU19TVEFOREFMT05FKSkgewotICAgICAgICAgICAgICAgICBpZiAodmFsdWUgIT0gbnVsbCAmJiB2YWx1ZS5lcXVhbHMoInllcyIpKSB7Ci0gICAgICAgICAgICAgICAgICAgICB0cmFuc2xldC5faXNTdGFuZGFsb25lID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgaXMgdXNlZCB0byBwYXNzIGFueSBwcm9wZXJ0aWVzIHRvIHRoZSBvdXRwdXQgaGFuZGxlcgotICAgICAqIHdoZW4gcnVubmluZyB0aGUgaWRlbnRpdHkgdHJhbnNmb3JtLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zZmVyT3V0cHV0UHJvcGVydGllcyhTZXJpYWxpemF0aW9uSGFuZGxlciBoYW5kbGVyKQotICAgIHsKLSAgICAgICAgLy8gUmV0dXJuIHJpZ2h0IG5vdyBpZiBubyBwcm9wZXJ0aWVzIGFyZSBzZXQKLSAgICAgICAgaWYgKF9wcm9wZXJ0aWVzID09IG51bGwpIHJldHVybjsKLQotICAgICAgICBTdHJpbmcgZG9jdHlwZVB1YmxpYyA9IG51bGw7Ci0gICAgICAgIFN0cmluZyBkb2N0eXBlU3lzdGVtID0gbnVsbDsKLQotICAgICAgICAvLyBHZXQgYSBsaXN0IG9mIGFsbCB0aGUgZGVmaW5lZCBwcm9wZXJ0aWVzCi0gICAgICAgIEVudW1lcmF0aW9uIG5hbWVzID0gX3Byb3BlcnRpZXMucHJvcGVydHlOYW1lcygpOwotICAgICAgICB3aGlsZSAobmFtZXMuaGFzTW9yZUVsZW1lbnRzKCkpIHsKLSAgICAgICAgICAgIC8vIE5vdGUgdGhlIHVzZSBvZiBnZXQoKSBpbnN0ZWFkIG9mIGdldFByb3BlcnR5KCkKLSAgICAgICAgICAgIFN0cmluZyBuYW1lICA9IChTdHJpbmcpIG5hbWVzLm5leHRFbGVtZW50KCk7Ci0gICAgICAgICAgICBTdHJpbmcgdmFsdWUgPSAoU3RyaW5nKSBfcHJvcGVydGllcy5nZXQobmFtZSk7Ci0KLSAgICAgICAgICAgIC8vIElnbm9yZSBkZWZhdWx0IHByb3BlcnRpZXMKLSAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSBjb250aW51ZTsKLQotICAgICAgICAgICAgLy8gUGFzcyBwcm9wZXJ0eSB2YWx1ZSB0byB0cmFuc2xldCAtIG92ZXJyaWRlIHByZXZpb3VzIHNldHRpbmcKLSAgICAgICAgICAgIGlmIChuYW1lLmVxdWFscyhPdXRwdXRLZXlzLkRPQ1RZUEVfUFVCTElDKSkgewotICAgICAgICAgICAgICAgIGRvY3R5cGVQdWJsaWMgPSB2YWx1ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzKE91dHB1dEtleXMuRE9DVFlQRV9TWVNURU0pKSB7Ci0gICAgICAgICAgICAgICAgZG9jdHlwZVN5c3RlbSA9IHZhbHVlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAobmFtZS5lcXVhbHMoT3V0cHV0S2V5cy5NRURJQV9UWVBFKSkgewotICAgICAgICAgICAgICAgIGhhbmRsZXIuc2V0TWVkaWFUeXBlKHZhbHVlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzKE91dHB1dEtleXMuU1RBTkRBTE9ORSkpIHsKLSAgICAgICAgICAgICAgICBoYW5kbGVyLnNldFN0YW5kYWxvbmUodmFsdWUpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAobmFtZS5lcXVhbHMoT3V0cHV0S2V5cy5WRVJTSU9OKSkgewotICAgICAgICAgICAgICAgIGhhbmRsZXIuc2V0VmVyc2lvbih2YWx1ZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFscyhPdXRwdXRLZXlzLk9NSVRfWE1MX0RFQ0xBUkFUSU9OKSkgewotICAgICAgICAgICAgICAgIGhhbmRsZXIuc2V0T21pdFhNTERlY2xhcmF0aW9uKAotICAgICAgICAgICAgICAgICAgICB2YWx1ZSAhPSBudWxsICYmIHZhbHVlLnRvTG93ZXJDYXNlKCkuZXF1YWxzKCJ5ZXMiKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFscyhPdXRwdXRLZXlzLklOREVOVCkpIHsKLSAgICAgICAgICAgICAgICBoYW5kbGVyLnNldEluZGVudCgKLSAgICAgICAgICAgICAgICAgICAgdmFsdWUgIT0gbnVsbCAmJiB2YWx1ZS50b0xvd2VyQ2FzZSgpLmVxdWFscygieWVzIikpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAobmFtZS5lcXVhbHMoT3V0cHV0UHJvcGVydGllc0ZhY3RvcnkuU19CVUlMVElOX09MRF9FWFRFTlNJT05TX1VOSVZFUlNBTCArImluZGVudC1hbW91bnQiKSkgewotICAgICAgICAgICAgICAgIGlmICh2YWx1ZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGhhbmRsZXIuc2V0SW5kZW50QW1vdW50KEludGVnZXIucGFyc2VJbnQodmFsdWUpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFscyhPdXRwdXRQcm9wZXJ0aWVzRmFjdG9yeS5TX0JVSUxUSU5fRVhURU5TSU9OU19VTklWRVJTQUwgKyJpbmRlbnQtYW1vdW50IikpIHsKLSAgICAgICAgICAgICAgICBpZiAodmFsdWUgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBoYW5kbGVyLnNldEluZGVudEFtb3VudChJbnRlZ2VyLnBhcnNlSW50KHZhbHVlKSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAobmFtZS5lcXVhbHMoT3V0cHV0UHJvcGVydGllc0ZhY3RvcnkuT1JBQ0xFX0lTX1NUQU5EQUxPTkUpKSB7Ci0gICAgICAgICAgICAgICAgaWYgKHZhbHVlICE9IG51bGwgJiYgdmFsdWUuZXF1YWxzKCJ5ZXMiKSkgewotICAgICAgICAgICAgICAgICAgICBoYW5kbGVyLnNldElzU3RhbmRhbG9uZSh0cnVlKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFscyhPdXRwdXRLZXlzLkNEQVRBX1NFQ1RJT05fRUxFTUVOVFMpKSB7Ci0gICAgICAgICAgICAgICAgaWYgKHZhbHVlICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nVG9rZW5pemVyIGUgPSBuZXcgU3RyaW5nVG9rZW5pemVyKHZhbHVlKTsKLSAgICAgICAgICAgICAgICAgICAgVmVjdG9yIHVyaUFuZExvY2FsTmFtZXMgPSBudWxsOwotICAgICAgICAgICAgICAgICAgICB3aGlsZSAoZS5oYXNNb3JlVG9rZW5zKCkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyB0b2tlbiA9IGUubmV4dFRva2VuKCk7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGxvb2sgZm9yIHRoZSBsYXN0IGNvbG9uLCBhcyB0aGUgU3RyaW5nIG1heSBiZQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gc29tZXRoaW5nIGxpa2UgImh0dHA6Ly9hYmMuY29tOmxvY2FsIgotICAgICAgICAgICAgICAgICAgICAgICAgaW50IGxhc3Rjb2xvbiA9IHRva2VuLmxhc3RJbmRleE9mKCc6Jyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdXJpOwotICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGxvY2FsTmFtZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsYXN0Y29sb24gPiAwKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgdXJpID0gdG9rZW4uc3Vic3RyaW5nKDAsIGxhc3Rjb2xvbik7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWxOYW1lID0gdG9rZW4uc3Vic3RyaW5nKGxhc3Rjb2xvbisxKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbm8gY29sb24gYXQgYWxsLCBsZXRzIGhvcGUgdGhpcyBpcyB0aGUKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBsb2NhbCBuYW1lIGl0c2VsZiB0aGVuCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgdXJpID0gbnVsbDsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhbE5hbWUgPSB0b2tlbjsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHVyaUFuZExvY2FsTmFtZXMgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVyaUFuZExvY2FsTmFtZXMgPSBuZXcgVmVjdG9yKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBhZGQgdGhlIHVyaS9sb2NhbE5hbWUgYXMgYSBwYWlyLCBpbiB0aGF0IG9yZGVyCi0gICAgICAgICAgICAgICAgICAgICAgICB1cmlBbmRMb2NhbE5hbWVzLmFkZEVsZW1lbnQodXJpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHVyaUFuZExvY2FsTmFtZXMuYWRkRWxlbWVudChsb2NhbE5hbWUpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGhhbmRsZXIuc2V0Q2RhdGFTZWN0aW9uRWxlbWVudHModXJpQW5kTG9jYWxOYW1lcyk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gQ2FsbCBzZXREb2N0eXBlKCkgaWYgbmVlZGVkCi0gICAgICAgIGlmIChkb2N0eXBlUHVibGljICE9IG51bGwgfHwgZG9jdHlwZVN5c3RlbSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBoYW5kbGVyLnNldERvY3R5cGUoZG9jdHlwZVN5c3RlbSwgZG9jdHlwZVB1YmxpYyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJbnRlcm5hbCBtZXRob2QgdG8gY3JlYXRlIHRoZSBpbml0aWFsIHNldCBvZiBwcm9wZXJ0aWVzLiBUaGVyZQotICAgICAqIGFyZSB0d28gbGF5ZXJzIG9mIHByb3BlcnRpZXM6IHRoZSBkZWZhdWx0IGxheWVyIGFuZCB0aGUgYmFzZSBsYXllci4KLSAgICAgKiBUaGUgbGF0dGVyIGNvbnRhaW5zIHByb3BlcnRpZXMgZGVmaW5lZCBpbiB0aGUgc3R5bGVzaGVldCBvciBieQotICAgICAqIHRoZSB1c2VyIHVzaW5nIHRoaXMgQVBJLgotICAgICAqLwotICAgIHByaXZhdGUgUHJvcGVydGllcyBjcmVhdGVPdXRwdXRQcm9wZXJ0aWVzKFByb3BlcnRpZXMgb3V0cHV0UHJvcGVydGllcykgewotICAgICAgICBmaW5hbCBQcm9wZXJ0aWVzIGRlZmF1bHRzID0gbmV3IFByb3BlcnRpZXMoKTsKLSAgICAgICAgc2V0RGVmYXVsdHMoZGVmYXVsdHMsICJ4bWwiKTsKLQotICAgICAgICAvLyBDb3B5IHByb3BldGllcyBzZXQgaW4gc3R5bGVzaGVldCB0byBiYXNlCi0gICAgICAgIGZpbmFsIFByb3BlcnRpZXMgYmFzZSA9IG5ldyBQcm9wZXJ0aWVzKGRlZmF1bHRzKTsKLSAgICAgICAgaWYgKG91dHB1dFByb3BlcnRpZXMgIT0gbnVsbCkgewotICAgICAgICAgICAgZmluYWwgRW51bWVyYXRpb24gbmFtZXMgPSBvdXRwdXRQcm9wZXJ0aWVzLnByb3BlcnR5TmFtZXMoKTsKLSAgICAgICAgICAgIHdoaWxlIChuYW1lcy5oYXNNb3JlRWxlbWVudHMoKSkgewotICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBuYW1lID0gKFN0cmluZykgbmFtZXMubmV4dEVsZW1lbnQoKTsKLSAgICAgICAgICAgICAgICBiYXNlLnNldFByb3BlcnR5KG5hbWUsIG91dHB1dFByb3BlcnRpZXMuZ2V0UHJvcGVydHkobmFtZSkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgYmFzZS5zZXRQcm9wZXJ0eShPdXRwdXRLZXlzLkVOQ09ESU5HLCBfdHJhbnNsZXQuX2VuY29kaW5nKTsKLSAgICAgICAgICAgIGlmIChfdHJhbnNsZXQuX21ldGhvZCAhPSBudWxsKQotICAgICAgICAgICAgICAgIGJhc2Uuc2V0UHJvcGVydHkoT3V0cHV0S2V5cy5NRVRIT0QsIF90cmFuc2xldC5fbWV0aG9kKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIFVwZGF0ZSBkZWZhdWx0cyBiYXNlZCBvbiBvdXRwdXQgbWV0aG9kCi0gICAgICAgIGZpbmFsIFN0cmluZyBtZXRob2QgPSBiYXNlLmdldFByb3BlcnR5KE91dHB1dEtleXMuTUVUSE9EKTsKLSAgICAgICAgaWYgKG1ldGhvZCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAobWV0aG9kLmVxdWFscygiaHRtbCIpKSB7Ci0gICAgICAgICAgICAgICAgc2V0RGVmYXVsdHMoZGVmYXVsdHMsImh0bWwiKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKG1ldGhvZC5lcXVhbHMoInRleHQiKSkgewotICAgICAgICAgICAgICAgIHNldERlZmF1bHRzKGRlZmF1bHRzLCJ0ZXh0Iik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gYmFzZTsKLSAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIEludGVybmFsIG1ldGhvZCB0byBnZXQgdGhlIGRlZmF1bHQgcHJvcGVydGllcyBmcm9tIHRoZQotICAgICAgICAgKiBzZXJpYWxpemVyIGZhY3RvcnkgYW5kIHNldCB0aGVtIG9uIHRoZSBwcm9wZXJ0eSBvYmplY3QuCi0gICAgICAgICAqIEBwYXJhbSBwcm9wcyBhIGphdmEudXRpbC5Qcm9wZXJ0eSBvYmplY3Qgb24gd2hpY2ggdGhlIHByb3BlcnRpZXMgYXJlIHNldC4KLSAgICAgICAgICogQHBhcmFtIG1ldGhvZCBUaGUgb3V0cHV0IG1ldGhvZCB0eXBlLCBvbmUgb2YgInhtbCIsICJ0ZXh0IiwgImh0bWwiIC4uLgotICAgICAgICAgKi8KLSAgICAgICAgcHJpdmF0ZSB2b2lkIHNldERlZmF1bHRzKFByb3BlcnRpZXMgcHJvcHMsIFN0cmluZyBtZXRob2QpCi0gICAgICAgIHsKLSAgICAgICAgICAgICAgICBmaW5hbCBQcm9wZXJ0aWVzIG1ldGhvZF9wcm9wcyA9Ci0gICAgICAgICAgICAgICAgICAgICAgICBPdXRwdXRQcm9wZXJ0aWVzRmFjdG9yeS5nZXREZWZhdWx0TWV0aG9kUHJvcGVydGllcyhtZXRob2QpOwotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIEVudW1lcmF0aW9uIG5hbWVzID0gbWV0aG9kX3Byb3BzLnByb3BlcnR5TmFtZXMoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChuYW1lcy5oYXNNb3JlRWxlbWVudHMoKSkKLSAgICAgICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIG5hbWUgPSAoU3RyaW5nKW5hbWVzLm5leHRFbGVtZW50KCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb3BzLnNldFByb3BlcnR5KG5hbWUsIG1ldGhvZF9wcm9wcy5nZXRQcm9wZXJ0eShuYW1lKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgLyoqCi0gICAgICogVmVyaWZpZXMgaWYgYSBnaXZlbiBvdXRwdXQgcHJvcGVydHkgbmFtZSBpcyBhIHByb3BlcnR5IGRlZmluZWQgaW4KLSAgICAgKiB0aGUgSkFYUCAxLjEgLyBUckFYIHNwZWMKLSAgICAgKi8KLSAgICBwcml2YXRlIGJvb2xlYW4gdmFsaWRPdXRwdXRQcm9wZXJ0eShTdHJpbmcgbmFtZSkgewotICAgICAgICByZXR1cm4gKG5hbWUuZXF1YWxzKE91dHB1dEtleXMuRU5DT0RJTkcpIHx8Ci0gICAgICAgICAgICAgICAgbmFtZS5lcXVhbHMoT3V0cHV0S2V5cy5NRVRIT0QpIHx8Ci0gICAgICAgICAgICAgICAgbmFtZS5lcXVhbHMoT3V0cHV0S2V5cy5JTkRFTlQpIHx8Ci0gICAgICAgICAgICAgICAgbmFtZS5lcXVhbHMoT3V0cHV0S2V5cy5ET0NUWVBFX1BVQkxJQykgfHwKLSAgICAgICAgICAgICAgICBuYW1lLmVxdWFscyhPdXRwdXRLZXlzLkRPQ1RZUEVfU1lTVEVNKSB8fAotICAgICAgICAgICAgICAgIG5hbWUuZXF1YWxzKE91dHB1dEtleXMuQ0RBVEFfU0VDVElPTl9FTEVNRU5UUykgfHwKLSAgICAgICAgICAgICAgICBuYW1lLmVxdWFscyhPdXRwdXRLZXlzLk1FRElBX1RZUEUpIHx8Ci0gICAgICAgICAgICAgICAgbmFtZS5lcXVhbHMoT3V0cHV0S2V5cy5PTUlUX1hNTF9ERUNMQVJBVElPTikgICB8fAotICAgICAgICAgICAgICAgIG5hbWUuZXF1YWxzKE91dHB1dEtleXMuU1RBTkRBTE9ORSkgfHwKLSAgICAgICAgICAgICAgICBuYW1lLmVxdWFscyhPdXRwdXRLZXlzLlZFUlNJT04pIHx8Ci0gICAgICAgICAgICAgICAgbmFtZS5lcXVhbHMoT3V0cHV0UHJvcGVydGllc0ZhY3RvcnkuT1JBQ0xFX0lTX1NUQU5EQUxPTkUpIHx8Ci0gICAgICAgICAgICAgICAgbmFtZS5jaGFyQXQoMCkgPT0gJ3snKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDaGVja3MgaWYgYSBnaXZlbiBvdXRwdXQgcHJvcGVydHkgaXMgZGVmYXVsdCAoMm5kIGxheWVyIG9ubHkpCi0gICAgICovCi0gICAgcHJpdmF0ZSBib29sZWFuIGlzRGVmYXVsdFByb3BlcnR5KFN0cmluZyBuYW1lLCBQcm9wZXJ0aWVzIHByb3BlcnRpZXMpIHsKLSAgICAgICAgcmV0dXJuIChwcm9wZXJ0aWVzLmdldChuYW1lKSA9PSBudWxsKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJbXBsZW1lbnRzIEpBWFAncyBUcmFuc2Zvcm1lci5zZXRQYXJhbWV0ZXIoKQotICAgICAqIEFkZCBhIHBhcmFtZXRlciBmb3IgdGhlIHRyYW5zZm9ybWF0aW9uLiBUaGUgcGFyYW1ldGVyIGlzIHNpbXBseSBwYXNzZWQKLSAgICAgKiBvbiB0byB0aGUgdHJhbnNsZXQgLSBubyB2YWxpZGF0aW9uIGlzIHBlcmZvcm1lZCAtIHNvIGFueSB1bnVzZWQKLSAgICAgKiBwYXJhbWV0ZXJzIGFyZSBxdWl0ZWx5IGlnbm9yZWQgYnkgdGhlIHRyYW5zbGV0LgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIHBhcmFtZXRlcgotICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUgdG8gYXNzaWduIHRvIHRoZSBwYXJhbWV0ZXIKLSAgICAgKi8KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgdm9pZCBzZXRQYXJhbWV0ZXIoU3RyaW5nIG5hbWUsIE9iamVjdCB2YWx1ZSkgewotCi0gICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBFcnJvck1zZyBlcnIgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuSkFYUF9JTlZBTElEX1NFVF9QQVJBTV9WQUxVRSwgbmFtZSk7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKGVyci50b1N0cmluZygpKTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChfaXNJZGVudGl0eSkgewotICAgICAgICAgICAgaWYgKF9wYXJhbWV0ZXJzID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBfcGFyYW1ldGVycyA9IG5ldyBIYXNoTWFwPD4oKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIF9wYXJhbWV0ZXJzLnB1dChuYW1lLCB2YWx1ZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBfdHJhbnNsZXQuYWRkUGFyYW1ldGVyKG5hbWUsIHZhbHVlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEltcGxlbWVudHMgSkFYUCdzIFRyYW5zZm9ybWVyLmNsZWFyUGFyYW1ldGVycygpCi0gICAgICogQ2xlYXIgYWxsIHBhcmFtZXRlcnMgc2V0IHdpdGggc2V0UGFyYW1ldGVyLiBDbGVhcnMgdGhlIHRyYW5zbGV0J3MKLSAgICAgKiBwYXJhbWV0ZXIgc3RhY2suCi0gICAgICovCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIHZvaWQgY2xlYXJQYXJhbWV0ZXJzKCkgewotICAgICAgICBpZiAoX2lzSWRlbnRpdHkgJiYgX3BhcmFtZXRlcnMgIT0gbnVsbCkgewotICAgICAgICAgICAgX3BhcmFtZXRlcnMuY2xlYXIoKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIF90cmFuc2xldC5jbGVhclBhcmFtZXRlcnMoKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEltcGxlbWVudHMgSkFYUCdzIFRyYW5zZm9ybWVyLmdldFBhcmFtZXRlcigpCi0gICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgYSBnaXZlbiBwYXJhbWV0ZXIuIE5vdGUgdGhhdCB0aGUgdHJhbnNsZXQgd2lsbCBub3QKLSAgICAgKiBrZWVwIHZhbHVlcyBmb3IgcGFyYW1ldGVycyB0aGF0IHdlcmUgbm90IGRlZmluZWQgaW4gdGhlIHN0eWxlc2hlZXQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgcGFyYW1ldGVyCi0gICAgICogQHJldHVybiBBbiBvYmplY3QgdGhhdCBjb250YWlucyB0aGUgdmFsdWUgYXNzaWduZWQgdG8gdGhlIHBhcmFtZXRlcgotICAgICAqLwotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyBmaW5hbCBPYmplY3QgZ2V0UGFyYW1ldGVyKFN0cmluZyBuYW1lKSB7Ci0gICAgICAgIGlmIChfaXNJZGVudGl0eSkgewotICAgICAgICAgICAgcmV0dXJuIChfcGFyYW1ldGVycyAhPSBudWxsKSA/IF9wYXJhbWV0ZXJzLmdldChuYW1lKSA6IG51bGw7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gX3RyYW5zbGV0LmdldFBhcmFtZXRlcihuYW1lKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEltcGxlbWVudHMgSkFYUCdzIFRyYW5zZm9ybWVyLmdldFVSSVJlc29sdmVyKCkKLSAgICAgKiBTZXQgdGhlIG9iamVjdCBjdXJyZW50bHkgdXNlZCB0byByZXNvbHZlIFVSSXMgdXNlZCBpbiBkb2N1bWVudCgpLgotICAgICAqCi0gICAgICogQHJldHVybiAgVGhlIFVSTFJlc29sdmVyIG9iamVjdCBjdXJyZW50bHkgaW4gdXNlCi0gICAgICovCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIFVSSVJlc29sdmVyIGdldFVSSVJlc29sdmVyKCkgewotICAgICAgICByZXR1cm4gX3VyaVJlc29sdmVyOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEltcGxlbWVudHMgSkFYUCdzIFRyYW5zZm9ybWVyLnNldFVSSVJlc29sdmVyKCkKLSAgICAgKiBTZXQgYW4gb2JqZWN0IHRoYXQgd2lsbCBiZSB1c2VkIHRvIHJlc29sdmUgVVJJcyB1c2VkIGluIGRvY3VtZW50KCkuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcmVzb2x2ZXIgVGhlIFVSSVJlc29sdmVyIHRvIHVzZSBpbiBkb2N1bWVudCgpCi0gICAgICovCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIHZvaWQgc2V0VVJJUmVzb2x2ZXIoVVJJUmVzb2x2ZXIgcmVzb2x2ZXIpIHsKLSAgICAgICAgX3VyaVJlc29sdmVyID0gcmVzb2x2ZXI7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBjbGFzcyBzaG91bGQgb25seSBiZSB1c2VkIGFzIGEgRE9NQ2FjaGUgZm9yIHRoZSB0cmFuc2xldCBpZiB0aGUKLSAgICAgKiBVUklSZXNvbHZlciBoYXMgYmVlbiBzZXQuCi0gICAgICoKLSAgICAgKiBUaGUgbWV0aG9kIGltcGxlbWVudHMgWFNMVEMncyBET01DYWNoZSBpbnRlcmZhY2UsIHdoaWNoIGlzIHVzZWQgdG8KLSAgICAgKiBwbHVnIGluIGFuIGV4dGVybmFsIGRvY3VtZW50IGxvYWRlciBpbnRvIGEgdHJhbnNsZXQuIFRoaXMgbWV0aG9kIGFjdHMKLSAgICAgKiBhcyBhbiBhZGFwdGVyIGJldHdlZW4gVHJBWCdzIFVSSVJlc29sdmVyIGludGVyZmFjZSBhbmQgWFNMVEMncwotICAgICAqIERPTUNhY2hlIGludGVyZmFjZS4gVGhpcyBhcHByb2FjaCBpcyBzaW1wbGUsIGJ1dCByZW1vdmVzIHRoZQotICAgICAqIHBvc3NpYmlsaXR5IG9mIHVzaW5nIGV4dGVybmFsIGRvY3VtZW50IGNhY2hlcyB3aXRoIFhTTFRDLgotICAgICAqCi0gICAgICogQHBhcmFtIGJhc2VVUkkgVGhlIGJhc2UgVVJJIHVzZWQgYnkgdGhlIGRvY3VtZW50IGNhbGwuCi0gICAgICogQHBhcmFtIGhyZWYgVGhlIGhyZWYgYXJndW1lbnQgcGFzc2VkIHRvIHRoZSBkb2N1bWVudCBmdW5jdGlvbi4KLSAgICAgKiBAcGFyYW0gdHJhbnNsZXQgQSByZWZlcmVuY2UgdG8gdGhlIHRyYW5zbGV0IHJlcXVlc3RpbmcgdGhlIGRvY3VtZW50Ci0gICAgICovCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIERPTSByZXRyaWV2ZURvY3VtZW50KFN0cmluZyBiYXNlVVJJLCBTdHJpbmcgaHJlZiwgVHJhbnNsZXQgdHJhbnNsZXQpIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIC8vIEFyZ3VtZW50IHRvIGRvY3VtZW50IGZ1bmN0aW9uIHdhczogZG9jdW1lbnQoJycpOwotICAgICAgICAgICAgaWYgKGhyZWYubGVuZ3RoKCkgPT0gMCkgewotICAgICAgICAgICAgICAgIGhyZWYgPSBiYXNlVVJJOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvKgotICAgICAgICAgICAgICogIEZpeCBmb3IgYnVnIDI0MTg4Ci0gICAgICAgICAgICAgKiAgSW5jYXNlIHRoZSBfdXJpUmVzb2x2ZXIucmVzb2x2ZShocmVmLGJhc2UpIGlzIG51bGwKLSAgICAgICAgICAgICAqICB0cnkgdG8gc3RpbGwgIHJldHJpZXZlIHRoZSBkb2N1bWVudCBiZWZvcmUgcmV0dXJuaW5nIG51bGwKLSAgICAgICAgICAgICAqICBhbmQgdGhyb3dpbmcgdGhlIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiBpbgotICAgICAgICAgICAgICogIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5kb20uTG9hZERvY3VtZW50Ci0gICAgICAgICAgICAgKgotICAgICAgICAgICAgICovCi0gICAgICAgICAgICBTb3VyY2UgcmVzb2x2ZWRTb3VyY2UgPSBfdXJpUmVzb2x2ZXIucmVzb2x2ZShocmVmLCBiYXNlVVJJKTsKLSAgICAgICAgICAgIGlmIChyZXNvbHZlZFNvdXJjZSA9PSBudWxsKSAgewotICAgICAgICAgICAgICAgIFN0cmVhbVNvdXJjZSBzdHJlYW1Tb3VyY2UgPSBuZXcgU3RyZWFtU291cmNlKAotICAgICAgICAgICAgICAgICAgICAgU3lzdGVtSURSZXNvbHZlci5nZXRBYnNvbHV0ZVVSSShocmVmLCBiYXNlVVJJKSk7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGdldERPTShzdHJlYW1Tb3VyY2UpIDsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgcmV0dXJuIGdldERPTShyZXNvbHZlZFNvdXJjZSk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKFRyYW5zZm9ybWVyRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIGlmIChfZXJyb3JMaXN0ZW5lciAhPSBudWxsKQotICAgICAgICAgICAgICAgIHBvc3RFcnJvclRvTGlzdGVuZXIoIkZpbGUgbm90IGZvdW5kOiAiICsgZS5nZXRNZXNzYWdlKCkpOwotICAgICAgICAgICAgcmV0dXJuKG51bGwpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgYSByZWNvdmVyYWJsZSBlcnJvci4KLSAgICAgKiBUaGUgdHJhbnNmb3JtZXIgbXVzdCBjb250aW51ZSB0byBwcm92aWRlIG5vcm1hbCBwYXJzaW5nIGV2ZW50cyBhZnRlcgotICAgICAqIGludm9raW5nIHRoaXMgbWV0aG9kLiBJdCBzaG91bGQgc3RpbGwgYmUgcG9zc2libGUgZm9yIHRoZSBhcHBsaWNhdGlvbgotICAgICAqIHRvIHByb2Nlc3MgdGhlIGRvY3VtZW50IHRocm91Z2ggdG8gdGhlIGVuZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlIFRoZSB3YXJuaW5nIGluZm9ybWF0aW9uIGVuY2Fwc3VsYXRlZCBpbiBhIHRyYW5zZm9ybWVyCi0gICAgICogZXhjZXB0aW9uLgotICAgICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24gaWYgdGhlIGFwcGxpY2F0aW9uIGNob29zZXMgdG8gZGlzY29udGludWUKLSAgICAgKiB0aGUgdHJhbnNmb3JtYXRpb24gKGFsd2F5cyBkb2VzIGluIG91ciBjYXNlKS4KLSAgICAgKi8KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgdm9pZCBlcnJvcihUcmFuc2Zvcm1lckV4Y2VwdGlvbiBlKQotICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIFRocm93YWJsZSB3cmFwcGVkID0gZS5nZXRFeGNlcHRpb24oKTsKLSAgICAgICAgaWYgKHdyYXBwZWQgIT0gbnVsbCkgewotICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKG5ldyBFcnJvck1zZyhFcnJvck1zZy5FUlJPUl9QTFVTX1dSQVBQRURfTVNHLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlLmdldE1lc3NhZ2VBbmRMb2NhdGlvbigpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cmFwcGVkLmdldE1lc3NhZ2UoKSkpOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKG5ldyBFcnJvck1zZyhFcnJvck1zZy5FUlJPUl9NU0csCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGUuZ2V0TWVzc2FnZUFuZExvY2F0aW9uKCkpKTsKLSAgICAgICAgfQotICAgICAgICB0aHJvdyBlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGEgbm9uLXJlY292ZXJhYmxlIGVycm9yLgotICAgICAqIFRoZSBhcHBsaWNhdGlvbiBtdXN0IGFzc3VtZSB0aGF0IHRoZSB0cmFuc2Zvcm1hdGlvbiBjYW5ub3QgY29udGludWUKLSAgICAgKiBhZnRlciB0aGUgVHJhbnNmb3JtZXIgaGFzIGludm9rZWQgdGhpcyBtZXRob2QsIGFuZCBzaG91bGQgY29udGludWUKLSAgICAgKiAoaWYgYXQgYWxsKSBvbmx5IHRvIGNvbGxlY3QgYWRkaXRpb24gZXJyb3IgbWVzc2FnZXMuIEluIGZhY3QsCi0gICAgICogVHJhbnNmb3JtZXJzIGFyZSBmcmVlIHRvIHN0b3AgcmVwb3J0aW5nIGV2ZW50cyBvbmNlIHRoaXMgbWV0aG9kIGhhcwotICAgICAqIGJlZW4gaW52b2tlZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlIFRoZSB3YXJuaW5nIGluZm9ybWF0aW9uIGVuY2Fwc3VsYXRlZCBpbiBhIHRyYW5zZm9ybWVyCi0gICAgICogZXhjZXB0aW9uLgotICAgICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24gaWYgdGhlIGFwcGxpY2F0aW9uIGNob29zZXMgdG8gZGlzY29udGludWUKLSAgICAgKiB0aGUgdHJhbnNmb3JtYXRpb24gKGFsd2F5cyBkb2VzIGluIG91ciBjYXNlKS4KLSAgICAgKi8KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgdm9pZCBmYXRhbEVycm9yKFRyYW5zZm9ybWVyRXhjZXB0aW9uIGUpCi0gICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgVGhyb3dhYmxlIHdyYXBwZWQgPSBlLmdldEV4Y2VwdGlvbigpOwotICAgICAgICBpZiAod3JhcHBlZCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4obmV3IEVycm9yTXNnKEVycm9yTXNnLkZBVEFMX0VSUl9QTFVTX1dSQVBQRURfTVNHLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlLmdldE1lc3NhZ2VBbmRMb2NhdGlvbigpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cmFwcGVkLmdldE1lc3NhZ2UoKSkpOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKG5ldyBFcnJvck1zZyhFcnJvck1zZy5GQVRBTF9FUlJfTVNHLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlLmdldE1lc3NhZ2VBbmRMb2NhdGlvbigpKSk7Ci0gICAgICAgIH0KLSAgICAgICAgdGhyb3cgZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBhIHdhcm5pbmcuCi0gICAgICogVHJhbnNmb3JtZXJzIGNhbiB1c2UgdGhpcyBtZXRob2QgdG8gcmVwb3J0IGNvbmRpdGlvbnMgdGhhdCBhcmUgbm90Ci0gICAgICogZXJyb3JzIG9yIGZhdGFsIGVycm9ycy4gVGhlIGRlZmF1bHQgYmVoYXZpb3VyIGlzIHRvIHRha2Ugbm8gYWN0aW9uLgotICAgICAqIEFmdGVyIGludm9raW5nIHRoaXMgbWV0aG9kLCB0aGUgVHJhbnNmb3JtZXIgbXVzdCBjb250aW51ZSB3aXRoIHRoZQotICAgICAqIHRyYW5zZm9ybWF0aW9uLiBJdCBzaG91bGQgc3RpbGwgYmUgcG9zc2libGUgZm9yIHRoZSBhcHBsaWNhdGlvbiB0bwotICAgICAqIHByb2Nlc3MgdGhlIGRvY3VtZW50IHRocm91Z2ggdG8gdGhlIGVuZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlIFRoZSB3YXJuaW5nIGluZm9ybWF0aW9uIGVuY2Fwc3VsYXRlZCBpbiBhIHRyYW5zZm9ybWVyCi0gICAgICogZXhjZXB0aW9uLgotICAgICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24gaWYgdGhlIGFwcGxpY2F0aW9uIGNob29zZXMgdG8gZGlzY29udGludWUKLSAgICAgKiB0aGUgdHJhbnNmb3JtYXRpb24gKG5ldmVyIGRvZXMgaW4gb3VyIGNhc2UpLgotICAgICAqLwotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyB2b2lkIHdhcm5pbmcoVHJhbnNmb3JtZXJFeGNlcHRpb24gZSkKLSAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAgewotICAgICAgICBUaHJvd2FibGUgd3JhcHBlZCA9IGUuZ2V0RXhjZXB0aW9uKCk7Ci0gICAgICAgIGlmICh3cmFwcGVkICE9IG51bGwpIHsKLSAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbihuZXcgRXJyb3JNc2coRXJyb3JNc2cuV0FSTklOR19QTFVTX1dSQVBQRURfTVNHLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlLmdldE1lc3NhZ2VBbmRMb2NhdGlvbigpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cmFwcGVkLmdldE1lc3NhZ2UoKSkpOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKG5ldyBFcnJvck1zZyhFcnJvck1zZy5XQVJOSU5HX01TRywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZS5nZXRNZXNzYWdlQW5kTG9jYXRpb24oKSkpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgcmVzZXRzICB0aGUgVHJhbnNmb3JtZXIgdG8gaXRzIG9yaWdpbmFsIGNvbmZpZ3VyYXRpb24KLSAgICAgKiBUcmFuc2Zvcm1lciBjb2RlIGlzIHJlc2V0IHRvIHRoZSBzYW1lIHN0YXRlIGl0IHdhcyB3aGVuIGl0IHdhcwotICAgICAqIGNyZWF0ZWQKLSAgICAgKiBAc2luY2UgMS41Ci0gICAgICovCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIHZvaWQgcmVzZXQoKSB7Ci0KLSAgICAgICAgX21ldGhvZCA9IG51bGw7Ci0gICAgICAgIF9lbmNvZGluZyA9IG51bGw7Ci0gICAgICAgIF9zb3VyY2VTeXN0ZW1JZCA9IG51bGw7Ci0gICAgICAgIF9lcnJvckxpc3RlbmVyID0gdGhpczsKLSAgICAgICAgX3VyaVJlc29sdmVyID0gbnVsbDsKLSAgICAgICAgX2RvbSA9IG51bGw7Ci0gICAgICAgIF9wYXJhbWV0ZXJzID0gbnVsbDsKLSAgICAgICAgX2luZGVudE51bWJlciA9IDA7Ci0gICAgICAgIHNldE91dHB1dFByb3BlcnRpZXMgKG51bGwpOwotICAgICAgICBfdG9oRmFjdG9yeSA9IG51bGw7Ci0gICAgICAgIF9vc3RyZWFtID0gbnVsbDsKLQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvdHJheC9VdGlsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3RyYXgvVXRpbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiZDMyODRkLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvdHJheC9VdGlsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyNTcgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogVXRpbC5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE0IDA5OjM3OjM0IHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy50cmF4OwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLlhhbGFuQ29uc3RhbnRzOwotaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5pby5SZWFkZXI7Ci0KLWltcG9ydCBqYXZheC54bWwuWE1MQ29uc3RhbnRzOwotaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLlBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyRmFjdG9yeTsKLQotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uWE1MRXZlbnRSZWFkZXI7Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5YTUxTdHJlYW1SZWFkZXI7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlNvdXJjZTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLmRvbS5ET01Tb3VyY2U7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zYXguU0FYU291cmNlOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc3RheC5TdEFYU291cmNlOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc3RyZWFtLlN0cmVhbVNvdXJjZTsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC51dGlscy5GYWN0b3J5SW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwudXRpbHMuWE1MU2VjdXJpdHlNYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci5YU0xUQzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5FcnJvck1zZzsKLQotaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OwotCi1pbXBvcnQgb3JnLnhtbC5zYXguSW5wdXRTb3VyY2U7Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LlhNTFJlYWRlcjsKLWltcG9ydCBvcmcueG1sLnNheC5oZWxwZXJzLlhNTFJlYWRlckZhY3Rvcnk7Ci0KLS8qKgotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBVdGlsIHsKLQotICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGJhc2VOYW1lKFN0cmluZyBuYW1lKSB7Ci0gICAgICAgIHJldHVybiBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIudXRpbC5VdGlsLmJhc2VOYW1lKG5hbWUpOwotICAgIH0KLQotICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIG5vRXh0TmFtZShTdHJpbmcgbmFtZSkgewotICAgICAgICByZXR1cm4gY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVXRpbC5ub0V4dE5hbWUobmFtZSk7Ci0gICAgfQotCi0gICAgcHVibGljIHN0YXRpYyBTdHJpbmcgdG9KYXZhTmFtZShTdHJpbmcgbmFtZSkgewotICAgICAgICByZXR1cm4gY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuVXRpbC50b0phdmFOYW1lKG5hbWUpOwotICAgIH0KLQotCi0KLQotICAgIC8qKgotICAgICAqIENyZWF0ZXMgYSBTQVgyIElucHV0U291cmNlIG9iamVjdCBmcm9tIGEgVHJBWCBTb3VyY2Ugb2JqZWN0Ci0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBJbnB1dFNvdXJjZSBnZXRJbnB1dFNvdXJjZShYU0xUQyB4c2x0YywgU291cmNlIHNvdXJjZSkKLSAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgSW5wdXRTb3VyY2UgaW5wdXQgPSBudWxsOwotCi0gICAgICAgIFN0cmluZyBzeXN0ZW1JZCA9IHNvdXJjZS5nZXRTeXN0ZW1JZCgpOwotCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAvLyBUcnkgdG8gZ2V0IElucHV0U291cmNlIGZyb20gU0FYU291cmNlIGlucHV0Ci0gICAgICAgICAgICBpZiAoc291cmNlIGluc3RhbmNlb2YgU0FYU291cmNlKSB7Ci0gICAgICAgICAgICAgICAgZmluYWwgU0FYU291cmNlIHNheCA9IChTQVhTb3VyY2Upc291cmNlOwotICAgICAgICAgICAgICAgIGlucHV0ID0gc2F4LmdldElucHV0U291cmNlKCk7Ci0gICAgICAgICAgICAgICAgLy8gUGFzcyB0aGUgU0FYIHBhcnNlciB0byB0aGUgY29tcGlsZXIKLSAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICBYTUxSZWFkZXIgcmVhZGVyID0gc2F4LmdldFhNTFJlYWRlcigpOwotCi0gICAgICAgICAgICAgICAgICAgICAvKgotICAgICAgICAgICAgICAgICAgICAgICogRml4IGZvciBidWcgMjQ2OTUKLSAgICAgICAgICAgICAgICAgICAgICAqIEFjY29yZGluZyB0byBKQVhQIDEuMiBzcGVjaWZpY2F0aW9uIGlmIGEgU0FYU291cmNlCi0gICAgICAgICAgICAgICAgICAgICAgKiBpcyBjcmVhdGVkIHVzaW5nIGEgU0FYIElucHV0U291cmNlIHRoZSBUcmFuc2Zvcm1lciBvcgotICAgICAgICAgICAgICAgICAgICAgICogVHJhbnNmb3JtZXJGYWN0b3J5IGNyZWF0ZXMgYSByZWFkZXIgdmlhIHRoZQotICAgICAgICAgICAgICAgICAgICAgICogWE1MUmVhZGVyRmFjdG9yeSBpZiBzZXRYTUxSZWFkZXIgaXMgbm90IHVzZWQKLSAgICAgICAgICAgICAgICAgICAgICAqLwotCi0gICAgICAgICAgICAgICAgICAgIGlmIChyZWFkZXIgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhZGVyPSBYTUxSZWFkZXJGYWN0b3J5LmNyZWF0ZVhNTFJlYWRlcigpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhZGVyLnNldEZlYXR1cmUoWE1MQ29uc3RhbnRzLkZFQVRVUkVfU0VDVVJFX1BST0NFU1NJTkcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhzbHRjLmlzU2VjdXJlUHJvY2Vzc2luZygpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxTZWN1cml0eU1hbmFnZXIucHJpbnRXYXJuaW5nKHJlYWRlci5nZXRDbGFzcygpLmdldE5hbWUoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxDb25zdGFudHMuRkVBVFVSRV9TRUNVUkVfUFJPQ0VTU0lORywgZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlICkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vSW5jYXNlIHRoZXJlIGlzIGFuIGV4Y2VwdGlvbiB0aHJvd24KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyByZXNvcnQgdG8gSkFYUAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNBWFBhcnNlckZhY3RvcnkgcGFyc2VyRmFjdG9yeSA9IEZhY3RvcnlJbXBsLmdldFNBWEZhY3RvcnkoeHNsdGMudXNlU2VydmljZXNNZWNobmlzbSgpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJzZXJGYWN0b3J5LnNldE5hbWVzcGFjZUF3YXJlKHRydWUpOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHhzbHRjLmlzU2VjdXJlUHJvY2Vzc2luZygpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2VyRmFjdG9yeS5zZXRGZWF0dXJlKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MQ29uc3RhbnRzLkZFQVRVUkVfU0VDVVJFX1BST0NFU1NJTkcsIHRydWUpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXRjaCAob3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIHNlKSB7fQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlYWRlciA9IHBhcnNlckZhY3RvcnkubmV3U0FYUGFyc2VyKCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0WE1MUmVhZGVyKCk7Ci0KLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBwY2UgKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCJQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIiAscGNlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIHJlYWRlci5zZXRGZWF0dXJlCi0gICAgICAgICAgICAgICAgICAgICAgICAoImh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy9uYW1lc3BhY2VzIix0cnVlKTsKLSAgICAgICAgICAgICAgICAgICAgcmVhZGVyLnNldEZlYXR1cmUKLSAgICAgICAgICAgICAgICAgICAgICAgICgiaHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL25hbWVzcGFjZS1wcmVmaXhlcyIsZmFsc2UpOwotCi0gICAgICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZWFkZXIuc2V0UHJvcGVydHkoWE1MQ29uc3RhbnRzLkFDQ0VTU19FWFRFUk5BTF9EVEQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhzbHRjLmdldFByb3BlcnR5KFhNTENvbnN0YW50cy5BQ0NFU1NfRVhURVJOQUxfRFREKSk7Ci0gICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgWE1MU2VjdXJpdHlNYW5hZ2VyLnByaW50V2FybmluZyhyZWFkZXIuZ2V0Q2xhc3MoKS5nZXROYW1lKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTENvbnN0YW50cy5BQ0NFU1NfRVhURVJOQUxfRFRELCBlKTsKLSAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgIFN0cmluZyBsYXN0UHJvcGVydHkgPSAiIjsKLSAgICAgICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgICAgIFhNTFNlY3VyaXR5TWFuYWdlciBzZWN1cml0eU1hbmFnZXIgPQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoWE1MU2VjdXJpdHlNYW5hZ2VyKXhzbHRjLmdldFByb3BlcnR5KFhhbGFuQ29uc3RhbnRzLlNFQ1VSSVRZX01BTkFHRVIpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNlY3VyaXR5TWFuYWdlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChYTUxTZWN1cml0eU1hbmFnZXIuTGltaXQgbGltaXQgOiBYTUxTZWN1cml0eU1hbmFnZXIuTGltaXQudmFsdWVzKCkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFzdFByb3BlcnR5ID0gbGltaXQuYXBpUHJvcGVydHkoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhZGVyLnNldFByb3BlcnR5KGxhc3RQcm9wZXJ0eSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWN1cml0eU1hbmFnZXIuZ2V0TGltaXRWYWx1ZUFzU3RyaW5nKGxpbWl0KSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZWN1cml0eU1hbmFnZXIucHJpbnRFbnRpdHlDb3VudEluZm8oKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYXN0UHJvcGVydHkgPSBYYWxhbkNvbnN0YW50cy5KREtfRU5USVRZX0NPVU5UX0lORk87Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlYWRlci5zZXRQcm9wZXJ0eShYYWxhbkNvbnN0YW50cy5KREtfRU5USVRZX0NPVU5UX0lORk8sIFhhbGFuQ29uc3RhbnRzLkpES19ZRVMpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIHNlKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBYTUxTZWN1cml0eU1hbmFnZXIucHJpbnRXYXJuaW5nKHJlYWRlci5nZXRDbGFzcygpLmdldE5hbWUoKSwgbGFzdFByb3BlcnR5LCBzZSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgeHNsdGMuc2V0WE1MUmVhZGVyKHJlYWRlcik7Ci0gICAgICAgICAgICAgICAgfWNhdGNoIChTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIHNucmUgKSB7Ci0gICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uCi0gICAgICAgICAgICAgICAgICAgICAgICgiU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiAiLHNucmUpOwotICAgICAgICAgICAgICAgIH1jYXRjaCAoU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIHNuc2UgKSB7Ci0gICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uCi0gICAgICAgICAgICAgICAgICAgICAgICgiU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uICIsc25zZSk7Ci0gICAgICAgICAgICAgICAgfWNhdGNoIChTQVhFeGNlcHRpb24gc2UgKSB7Ci0gICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uCi0gICAgICAgICAgICAgICAgICAgICAgICgiU0FYRXhjZXB0aW9uICIsc2UpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gaGFuZGxlICBET01Tb3VyY2UKLSAgICAgICAgICAgIGVsc2UgaWYgKHNvdXJjZSBpbnN0YW5jZW9mIERPTVNvdXJjZSkgewotICAgICAgICAgICAgICAgIGZpbmFsIERPTVNvdXJjZSBkb21zcmMgPSAoRE9NU291cmNlKXNvdXJjZTsKLSAgICAgICAgICAgICAgICBmaW5hbCBEb2N1bWVudCBkb20gPSAoRG9jdW1lbnQpZG9tc3JjLmdldE5vZGUoKTsKLSAgICAgICAgICAgICAgICBmaW5hbCBET00yU0FYIGRvbTJzYXggPSBuZXcgRE9NMlNBWChkb20pOwotICAgICAgICAgICAgICAgIHhzbHRjLnNldFhNTFJlYWRlcihkb20yc2F4KTsKLQotICAgICAgICAgICAgICAgIC8vIFRyeSB0byBnZXQgU0FYIElucHV0U291cmNlIGZyb20gRE9NIFNvdXJjZS4KLSAgICAgICAgICAgICAgICBpbnB1dCA9IFNBWFNvdXJjZS5zb3VyY2VUb0lucHV0U291cmNlKHNvdXJjZSk7Ci0gICAgICAgICAgICAgICAgaWYgKGlucHV0ID09IG51bGwpewotICAgICAgICAgICAgICAgICAgICBpbnB1dCA9IG5ldyBJbnB1dFNvdXJjZShkb21zcmMuZ2V0U3lzdGVtSWQoKSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBoYW5kbGUgU3RBWFNvdXJjZQotICAgICAgICAgICAgZWxzZSBpZiAoc291cmNlIGluc3RhbmNlb2YgU3RBWFNvdXJjZSkgewotICAgICAgICAgICAgICAgIGZpbmFsIFN0QVhTb3VyY2Ugc3RheFNvdXJjZSA9IChTdEFYU291cmNlKXNvdXJjZTsKLSAgICAgICAgICAgICAgICBTdEFYRXZlbnQyU0FYIHN0YXhldmVudDJzYXggPSBudWxsOwotICAgICAgICAgICAgICAgIFN0QVhTdHJlYW0yU0FYIHN0YXhTdHJlYW0yU0FYID0gbnVsbDsKLSAgICAgICAgICAgICAgICBpZiAoc3RheFNvdXJjZS5nZXRYTUxFdmVudFJlYWRlcigpICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgZmluYWwgWE1MRXZlbnRSZWFkZXIgeG1sRXZlbnRSZWFkZXIgPSBzdGF4U291cmNlLmdldFhNTEV2ZW50UmVhZGVyKCk7Ci0gICAgICAgICAgICAgICAgICAgIHN0YXhldmVudDJzYXggPSBuZXcgU3RBWEV2ZW50MlNBWCh4bWxFdmVudFJlYWRlcik7Ci0gICAgICAgICAgICAgICAgICAgIHhzbHRjLnNldFhNTFJlYWRlcihzdGF4ZXZlbnQyc2F4KTsKLSAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHN0YXhTb3VyY2UuZ2V0WE1MU3RyZWFtUmVhZGVyKCkgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBmaW5hbCBYTUxTdHJlYW1SZWFkZXIgeG1sU3RyZWFtUmVhZGVyID0gc3RheFNvdXJjZS5nZXRYTUxTdHJlYW1SZWFkZXIoKTsKLSAgICAgICAgICAgICAgICAgICAgc3RheFN0cmVhbTJTQVggPSBuZXcgU3RBWFN0cmVhbTJTQVgoeG1sU3RyZWFtUmVhZGVyKTsKLSAgICAgICAgICAgICAgICAgICAgeHNsdGMuc2V0WE1MUmVhZGVyKHN0YXhTdHJlYW0yU0FYKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyBnZXQgc2F4IElucHV0U291cmNlIGZyb20gU3RBWFNvdXJjZQotICAgICAgICAgICAgICAgIGlucHV0ID0gU0FYU291cmNlLnNvdXJjZVRvSW5wdXRTb3VyY2Uoc291cmNlKTsKLSAgICAgICAgICAgICAgICBpZiAoaW5wdXQgPT0gbnVsbCl7Ci0gICAgICAgICAgICAgICAgICAgIGlucHV0ID0gbmV3IElucHV0U291cmNlKHN0YXhTb3VyY2UuZ2V0U3lzdGVtSWQoKSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBUcnkgdG8gZ2V0IElucHV0U3RyZWFtIG9yIFJlYWRlciBmcm9tIFN0cmVhbVNvdXJjZQotICAgICAgICAgICAgZWxzZSBpZiAoc291cmNlIGluc3RhbmNlb2YgU3RyZWFtU291cmNlKSB7Ci0gICAgICAgICAgICAgICAgZmluYWwgU3RyZWFtU291cmNlIHN0cmVhbSA9IChTdHJlYW1Tb3VyY2Upc291cmNlOwotICAgICAgICAgICAgICAgIGZpbmFsIElucHV0U3RyZWFtIGlzdHJlYW0gPSBzdHJlYW0uZ2V0SW5wdXRTdHJlYW0oKTsKLSAgICAgICAgICAgICAgICBmaW5hbCBSZWFkZXIgcmVhZGVyID0gc3RyZWFtLmdldFJlYWRlcigpOwotICAgICAgICAgICAgICAgIHhzbHRjLnNldFhNTFJlYWRlcihudWxsKTsgICAgIC8vIENsZWFyIG9sZCBYTUwgcmVhZGVyCi0KLSAgICAgICAgICAgICAgICAvLyBDcmVhdGUgSW5wdXRTb3VyY2UgZnJvbSBSZWFkZXIgb3IgSW5wdXRTdHJlYW0gaW4gU291cmNlCi0gICAgICAgICAgICAgICAgaWYgKGlzdHJlYW0gIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBpbnB1dCA9IG5ldyBJbnB1dFNvdXJjZShpc3RyZWFtKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSBpZiAocmVhZGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgaW5wdXQgPSBuZXcgSW5wdXRTb3VyY2UocmVhZGVyKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIGlucHV0ID0gbmV3IElucHV0U291cmNlKHN5c3RlbUlkKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBFcnJvck1zZyBlcnIgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuSkFYUF9VTktOT1dOX1NPVVJDRV9FUlIpOwotICAgICAgICAgICAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24oZXJyLnRvU3RyaW5nKCkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaW5wdXQuc2V0U3lzdGVtSWQoc3lzdGVtSWQpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICBFcnJvck1zZyBlcnIgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuSkFYUF9OT19TT1VSQ0VfRVJSLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJUcmFuc2Zvcm1lckZhY3RvcnkubmV3VGVtcGxhdGVzKCkiKTsKLSAgICAgICAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24oZXJyLnRvU3RyaW5nKCkpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICBFcnJvck1zZyBlcnIgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuRklMRV9BQ0NFU1NfRVJSLCBzeXN0ZW1JZCk7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uKGVyci50b1N0cmluZygpKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gaW5wdXQ7Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3RyYXgvWFNMVENTb3VyY2UuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvdHJheC9YU0xUQ1NvdXJjZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0ZDk2YjU5Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvdHJheC9YU0xUQ1NvdXJjZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTQyICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogWFNMVENTb3VyY2UuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8wNiAxMjo0MzoyOCBwdmVkdWxhIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMudHJheDsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uU291cmNlOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc3RyZWFtLlN0cmVhbVNvdXJjZTsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5ET007Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLlN0cmlwRmlsdGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsLkVycm9yTXNnOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5kb20uRE9NV1NGaWx0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmRvbS5TQVhJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5kb20uWFNMVENEVE1NYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5ydW50aW1lLkFic3RyYWN0VHJhbnNsZXQ7Ci0KLWltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci0KLS8qKgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBYU0xUQ1NvdXJjZSBpbXBsZW1lbnRzIFNvdXJjZSB7Ci0KLSAgICBwcml2YXRlIFN0cmluZyAgICAgX3N5c3RlbUlkID0gbnVsbDsKLSAgICBwcml2YXRlIFNvdXJjZSAgICAgX3NvdXJjZSAgID0gbnVsbDsKLSAgICBwcml2YXRlIFRocmVhZExvY2FsIF9kb20gICAgID0gbmV3IFRocmVhZExvY2FsKCk7Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGUgYSBuZXcgWFNMVEMtc3BlY2lmaWMgc291cmNlIGZyb20gYSBzeXN0ZW0gSUQKLSAgICAgKi8KLSAgICBwdWJsaWMgWFNMVENTb3VyY2UoU3RyaW5nIHN5c3RlbUlkKQotICAgIHsKLSAgICAgICAgX3N5c3RlbUlkID0gc3lzdGVtSWQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlIGEgbmV3IFhTTFRDLXNwZWNpZmljIHNvdXJjZSBmcm9tIGEgSkFYUCBTb3VyY2UKLSAgICAgKi8KLSAgICBwdWJsaWMgWFNMVENTb3VyY2UoU291cmNlIHNvdXJjZSkKLSAgICB7Ci0gICAgICAgIF9zb3VyY2UgPSBzb3VyY2U7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSW1wbGVtZW50cyBqYXZheC54bWwudHJhbnNmb3JtLlNvdXJjZS5zZXRTeXN0ZW1JZCgpCi0gICAgICogU2V0IHRoZSBzeXN0ZW0gaWRlbnRpZmllciBmb3IgdGhpcyBTb3VyY2UuCi0gICAgICogVGhpcyBTb3VyY2UgY2FuIGdldCBpdHMgaW5wdXQgZWl0aGVyIGRpcmVjdGx5IGZyb20gYSBmaWxlIChpbiB0aGlzIGNhc2UKLSAgICAgKiBpdCB3aWxsIGluc3RhbmNpYXRlIGFuZCB1c2UgYSBKQVhQIHBhcnNlcikgb3IgaXQgY2FuIHJlY2VpdmUgaXQgdGhyb3VnaAotICAgICAqIENvbnRlbnRIYW5kbGVyL0xleGljYWxIYW5kbGVyIGludGVyZmFjZXMuCi0gICAgICogQHBhcmFtIHN5c3RlbUlkIFRoZSBzeXN0ZW0gSWQgZm9yIHRoaXMgU291cmNlCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0U3lzdGVtSWQoU3RyaW5nIHN5c3RlbUlkKSB7Ci0gICAgICAgIF9zeXN0ZW1JZCA9IHN5c3RlbUlkOwotICAgICAgICBpZiAoX3NvdXJjZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBfc291cmNlLnNldFN5c3RlbUlkKHN5c3RlbUlkKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEltcGxlbWVudHMgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2UuZ2V0U3lzdGVtSWQoKQotICAgICAqIEdldCB0aGUgc3lzdGVtIGlkZW50aWZpZXIgdGhhdCB3YXMgc2V0IHdpdGggc2V0U3lzdGVtSWQuCi0gICAgICogQHJldHVybiBUaGUgc3lzdGVtIGlkZW50aWZpZXIgdGhhdCB3YXMgc2V0IHdpdGggc2V0U3lzdGVtSWQsCi0gICAgICogICAgICAgICBvciBudWxsIGlmIHNldFN5c3RlbUlkIHdhcyBub3QgY2FsbGVkLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3lzdGVtSWQoKSB7Ci0gICAgICAgIGlmIChfc291cmNlICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBfc291cmNlLmdldFN5c3RlbUlkKCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4oX3N5c3RlbUlkKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEludGVybmFsIGludGVyZmFjZSB3aGljaCByZXR1cm5zIGEgRE9NIGZvciBhIGdpdmVuIERUTU1hbmFnZXIgYW5kIHRyYW5zbGV0LgotICAgICAqLwotICAgIHByb3RlY3RlZCBET00gZ2V0RE9NKFhTTFRDRFRNTWFuYWdlciBkdG1NYW5hZ2VyLCBBYnN0cmFjdFRyYW5zbGV0IHRyYW5zbGV0KQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBTQVhJbXBsIGlkb20gPSAoU0FYSW1wbClfZG9tLmdldCgpOwotCi0gICAgICAgIGlmIChpZG9tICE9IG51bGwpIHsKLSAgICAgICAgICAgIGlmIChkdG1NYW5hZ2VyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBpZG9tLm1pZ3JhdGVUbyhkdG1NYW5hZ2VyKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIFNvdXJjZSBzb3VyY2UgPSBfc291cmNlOwotICAgICAgICAgICAgaWYgKHNvdXJjZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgaWYgKF9zeXN0ZW1JZCAhPSBudWxsICYmIF9zeXN0ZW1JZC5sZW5ndGgoKSA+IDApIHsKLSAgICAgICAgICAgICAgICAgICAgc291cmNlID0gbmV3IFN0cmVhbVNvdXJjZShfc3lzdGVtSWQpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgRXJyb3JNc2cgZXJyID0gbmV3IEVycm9yTXNnKEVycm9yTXNnLlhTTFRDX1NPVVJDRV9FUlIpOwotICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKGVyci50b1N0cmluZygpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIERPTVdTRmlsdGVyIHdzZmlsdGVyID0gbnVsbDsKLSAgICAgICAgICAgIGlmICh0cmFuc2xldCAhPSBudWxsICYmIHRyYW5zbGV0IGluc3RhbmNlb2YgU3RyaXBGaWx0ZXIpIHsKLSAgICAgICAgICAgICAgICB3c2ZpbHRlciA9IG5ldyBET01XU0ZpbHRlcih0cmFuc2xldCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGJvb2xlYW4gaGFzSWRDYWxsID0gKHRyYW5zbGV0ICE9IG51bGwpID8gdHJhbnNsZXQuaGFzSWRDYWxsKCkgOiBmYWxzZTsKLQotICAgICAgICAgICAgaWYgKGR0bU1hbmFnZXIgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGR0bU1hbmFnZXIgPSBYU0xUQ0RUTU1hbmFnZXIubmV3SW5zdGFuY2UoKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWRvbSA9IChTQVhJbXBsKWR0bU1hbmFnZXIuZ2V0RFRNKHNvdXJjZSwgdHJ1ZSwgd3NmaWx0ZXIsIGZhbHNlLCBmYWxzZSwgaGFzSWRDYWxsKTsKLQotICAgICAgICAgICAgU3RyaW5nIHN5c3RlbUlkID0gZ2V0U3lzdGVtSWQoKTsKLSAgICAgICAgICAgIGlmIChzeXN0ZW1JZCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgaWRvbS5zZXREb2N1bWVudFVSSShzeXN0ZW1JZCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBfZG9tLnNldChpZG9tKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gaWRvbTsKLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvdXRpbC9JbnRlZ2VyQXJyYXkuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvdXRpbC9JbnRlZ2VyQXJyYXkuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNGI5ZDM0MS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3V0aWwvSW50ZWdlckFycmF5LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMjggKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogSW50ZWdlckFycmF5LmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMDYgMTE6NDQ6NTYgcHZlZHVsYSBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnV0aWw7Ci0KLS8qKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIEludGVnZXJBcnJheSB7Ci0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEluaXRpYWxTaXplID0gMzI7Ci0KLSAgICBwcml2YXRlIGludFtdIF9hcnJheTsKLSAgICBwcml2YXRlIGludCAgIF9zaXplOwotICAgIHByaXZhdGUgaW50ICAgX2ZyZWUgPSAwOwotCi0gICAgcHVibGljIEludGVnZXJBcnJheSgpIHsKLSAgICAgICAgdGhpcyhJbml0aWFsU2l6ZSk7Ci0gICAgfQotCi0gICAgcHVibGljIEludGVnZXJBcnJheShpbnQgc2l6ZSkgewotICAgICAgICBfYXJyYXkgPSBuZXcgaW50W19zaXplID0gc2l6ZV07Ci0gICAgfQotCi0gICAgcHVibGljIEludGVnZXJBcnJheShpbnRbXSBhcnJheSkgewotICAgICAgICB0aGlzKGFycmF5Lmxlbmd0aCk7Ci0gICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYXJyYXksIDAsIF9hcnJheSwgMCwgX2ZyZWUgPSBfc2l6ZSk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgY2xlYXIoKSB7Ci0gICAgICAgIF9mcmVlID0gMDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgT2JqZWN0IGNsb25lKCkgewotICAgICAgICBmaW5hbCBJbnRlZ2VyQXJyYXkgY2xvbmUgPSBuZXcgSW50ZWdlckFycmF5KF9mcmVlID4gMCA/IF9mcmVlIDogMSk7Ci0gICAgICAgIFN5c3RlbS5hcnJheWNvcHkoX2FycmF5LCAwLCBjbG9uZS5fYXJyYXksIDAsIF9mcmVlKTsKLSAgICAgICAgY2xvbmUuX2ZyZWUgPSBfZnJlZTsKLSAgICAgICAgcmV0dXJuIGNsb25lOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnRbXSB0b0ludEFycmF5KCkgewotICAgICAgICBmaW5hbCBpbnRbXSByZXN1bHQgPSBuZXcgaW50W2NhcmRpbmFsaXR5KCldOwotICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KF9hcnJheSwgMCwgcmVzdWx0LCAwLCBjYXJkaW5hbGl0eSgpKTsKLSAgICAgICAgcmV0dXJuIHJlc3VsdDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgZmluYWwgaW50IGF0KGludCBpbmRleCkgewotICAgICAgICByZXR1cm4gX2FycmF5W2luZGV4XTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgZmluYWwgdm9pZCBzZXQoaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKLSAgICAgICAgX2FycmF5W2luZGV4XSA9IHZhbHVlOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgaW5kZXhPZihpbnQgbikgewotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IF9mcmVlOyBpKyspIHsKLSAgICAgICAgICAgIGlmIChuID09IF9hcnJheVtpXSkgcmV0dXJuIGk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIC0xOwotICAgIH0KLQotICAgIHB1YmxpYyBmaW5hbCB2b2lkIGFkZChpbnQgdmFsdWUpIHsKLSAgICAgICAgaWYgKF9mcmVlID09IF9zaXplKSB7Ci0gICAgICAgICAgICBncm93QXJyYXkoX3NpemUgKiAyKTsKLSAgICAgICAgfQotICAgICAgICBfYXJyYXlbX2ZyZWUrK10gPSB2YWx1ZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBZGRzIG5ldyBpbnQgYXQgdGhlIGVuZCBpZiBub3QgYWxyZWFkeSBwcmVzZW50LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGFkZE5ldyhpbnQgdmFsdWUpIHsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBfZnJlZTsgaSsrKSB7Ci0gICAgICAgICAgICBpZiAoX2FycmF5W2ldID09IHZhbHVlKSByZXR1cm47ICAvLyBhbHJlYWR5IGluIGFycmF5Ci0gICAgICAgIH0KLSAgICAgICAgYWRkKHZhbHVlKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCByZXZlcnNlKCkgewotICAgICAgICBpbnQgbGVmdCA9IDA7Ci0gICAgICAgIGludCByaWdodCA9IF9mcmVlIC0gMTsKLQotICAgICAgICB3aGlsZSAobGVmdCA8IHJpZ2h0KSB7Ci0gICAgICAgICAgICBpbnQgdGVtcCA9IF9hcnJheVtsZWZ0XTsKLSAgICAgICAgICAgIF9hcnJheVtsZWZ0KytdID0gX2FycmF5W3JpZ2h0XTsKLSAgICAgICAgICAgIF9hcnJheVtyaWdodC0tXSA9IHRlbXA7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBNZXJnZSB0d28gc29ydGVkIGFycmF5cyBhbmQgZWxpbWluYXRlIGR1cGxpY2F0ZXMuCi0gICAgICogRWxlbWVudHMgb2YgdGhlIG90aGVyIEludGVnZXJBcnJheSBtdXN0IG5vdCBiZSBjaGFuZ2VkLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIG1lcmdlKGZpbmFsIEludGVnZXJBcnJheSBvdGhlcikgewotICAgICAgICBmaW5hbCBpbnQgbmV3U2l6ZSA9IF9mcmVlICsgb3RoZXIuX2ZyZWU7Ci0vLyBTeXN0ZW0ub3V0LnByaW50bG4oIkludGVnZXJBcnJheS5tZXJnZSgpIGJlZ2luIG5ld1NpemUgPSAiICsgbmV3U2l6ZSk7Ci0gICAgICAgIGludFtdIG5ld0FycmF5ID0gbmV3IGludFtuZXdTaXplXTsKLQotICAgICAgICAvLyBNZXJnZSB0aGUgdHdvIGFycmF5cwotICAgICAgICBpbnQgaSA9IDAsIGogPSAwLCBrOwotICAgICAgICBmb3IgKGsgPSAwOyBpIDwgX2ZyZWUgJiYgaiA8IG90aGVyLl9mcmVlOyBrKyspIHsKLSAgICAgICAgICAgIGludCB4ID0gX2FycmF5W2ldOwotICAgICAgICAgICAgaW50IHkgPSBvdGhlci5fYXJyYXlbal07Ci0KLSAgICAgICAgICAgIGlmICh4IDwgeSkgewotICAgICAgICAgICAgICAgIG5ld0FycmF5W2tdID0geDsKLSAgICAgICAgICAgICAgICBpKys7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmICh4ID4geSkgewotICAgICAgICAgICAgICAgIG5ld0FycmF5W2tdID0geTsKLSAgICAgICAgICAgICAgICBqKys7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBuZXdBcnJheVtrXSA9IHg7Ci0gICAgICAgICAgICAgICAgaSsrOyBqKys7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBDb3B5IHRoZSByZXN0IGlmIG9mIGRpZmZlcmVudCBsZW5ndGhzCi0gICAgICAgIGlmIChpID49IF9mcmVlKSB7Ci0gICAgICAgICAgICB3aGlsZSAoaiA8IG90aGVyLl9mcmVlKSB7Ci0gICAgICAgICAgICAgICAgbmV3QXJyYXlbaysrXSA9IG90aGVyLl9hcnJheVtqKytdOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgd2hpbGUgKGkgPCBfZnJlZSkgewotICAgICAgICAgICAgICAgIG5ld0FycmF5W2srK10gPSBfYXJyYXlbaSsrXTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIFVwZGF0ZSByZWZlcmVuY2UgdG8gdGhpcyBhcnJheQotICAgICAgICBfYXJyYXkgPSBuZXdBcnJheTsKLSAgICAgICAgX2ZyZWUgPSBfc2l6ZSA9IG5ld1NpemU7Ci0vLyBTeXN0ZW0ub3V0LnByaW50bG4oIkludGVnZXJBcnJheS5tZXJnZSgpIGVuZCIpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNvcnQoKSB7Ci0gICAgICAgIHF1aWNrc29ydChfYXJyYXksIDAsIF9mcmVlIC0gMSk7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBxdWlja3NvcnQoaW50W10gYXJyYXksIGludCBwLCBpbnQgcikgewotICAgICAgICBpZiAocCA8IHIpIHsKLSAgICAgICAgICAgIGZpbmFsIGludCBxID0gcGFydGl0aW9uKGFycmF5LCBwLCByKTsKLSAgICAgICAgICAgIHF1aWNrc29ydChhcnJheSwgcCwgcSk7Ci0gICAgICAgICAgICBxdWlja3NvcnQoYXJyYXksIHEgKyAxLCByKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHByaXZhdGUgc3RhdGljIGludCBwYXJ0aXRpb24oaW50W10gYXJyYXksIGludCBwLCBpbnQgcikgewotICAgICAgICBmaW5hbCBpbnQgeCA9IGFycmF5WyhwICsgcikgPj4+IDFdOwotICAgICAgICBpbnQgaSA9IHAgLSAxOyBpbnQgaiA9IHIgKyAxOwotCi0gICAgICAgIHdoaWxlICh0cnVlKSB7Ci0gICAgICAgICAgICB3aGlsZSAoeCA8IGFycmF5Wy0tal0pOwotICAgICAgICAgICAgd2hpbGUgKHggPiBhcnJheVsrK2ldKTsKLSAgICAgICAgICAgIGlmIChpIDwgaikgewotICAgICAgICAgICAgICAgIGludCB0ZW1wID0gYXJyYXlbaV07Ci0gICAgICAgICAgICAgICAgYXJyYXlbaV0gPSBhcnJheVtqXTsKLSAgICAgICAgICAgICAgICBhcnJheVtqXSA9IHRlbXA7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gajsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBncm93QXJyYXkoaW50IHNpemUpIHsKLSAgICAgICAgZmluYWwgaW50W10gbmV3QXJyYXkgPSBuZXcgaW50W19zaXplID0gc2l6ZV07Ci0gICAgICAgIFN5c3RlbS5hcnJheWNvcHkoX2FycmF5LCAwLCBuZXdBcnJheSwgMCwgX2ZyZWUpOwotICAgICAgICBfYXJyYXkgPSBuZXdBcnJheTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IHBvcExhc3QoKSB7Ci0gICAgICAgIHJldHVybiBfYXJyYXlbLS1fZnJlZV07Ci0gICAgfQotCi0gICAgcHVibGljIGludCBsYXN0KCkgewotICAgICAgICByZXR1cm4gX2FycmF5W19mcmVlIC0gMV07Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0TGFzdChpbnQgbikgewotICAgICAgICBfYXJyYXlbX2ZyZWUgLSAxXSA9IG47Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgcG9wKCkgewotICAgICAgICBfZnJlZS0tOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHBvcChpbnQgbikgewotICAgICAgICBfZnJlZSAtPSBuOwotICAgIH0KLQotICAgIHB1YmxpYyBmaW5hbCBpbnQgY2FyZGluYWxpdHkoKSB7Ci0gICAgICAgIHJldHVybiBfZnJlZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBwcmludChqYXZhLmlvLlByaW50U3RyZWFtIG91dCkgewotICAgICAgICBpZiAoX2ZyZWUgPiAwKSB7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IF9mcmVlIC0gMTsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgb3V0LnByaW50KF9hcnJheVtpXSk7Ci0gICAgICAgICAgICAgICAgb3V0LnByaW50KCcgJyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBvdXQucHJpbnRsbihfYXJyYXlbX2ZyZWUgLSAxXSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBvdXQucHJpbnRsbigiSW50ZWdlckFycmF5OiBlbXB0eSIpOwotICAgICAgICB9Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL0Fib3J0RXhjZXB0aW9uLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vQWJvcnRFeGNlcHRpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggM2UxNzhkZC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vQWJvcnRFeGNlcHRpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDM2ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMTYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5kb207Ci0KLXB1YmxpYyBjbGFzcyBBYm9ydEV4Y2VwdGlvbiBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24gewotCi0gICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDI2MDgzMDIxNzU0NzU3NDA0MTdMOwotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBDb25zdHJ1Y3RvciBBYm9ydEV4Y2VwdGlvbgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIEFib3J0RXhjZXB0aW9uKCkgeyBzdXBlcihudWxsLCBudWxsLCBmYWxzZSwgZmFsc2UpOyB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vQXR0ckltcGwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9BdHRySW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzNTJmYmE2Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9BdHRySW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTIzOSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tOwotCi1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uT2JqZWN0T3V0cHV0U3RyZWFtOwotCi1pbXBvcnQgb3JnLnczYy5kb20uVHlwZUluZm87Ci1pbXBvcnQgb3JnLnczYy5kb20uQXR0cjsKLWltcG9ydCBvcmcudzNjLmRvbS5ET01FeGNlcHRpb247Ci1pbXBvcnQgb3JnLnczYy5kb20uRWxlbWVudDsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGVMaXN0OwotaW1wb3J0IG9yZy53M2MuZG9tLlRleHQ7Ci0KLS8qKgotICogQXR0cmlidXRlIHJlcHJlc2VudHMgYW4gWE1MLXN0eWxlIGF0dHJpYnV0ZSBvZiBhbgotICogRWxlbWVudC4gVHlwaWNhbGx5LCB0aGUgYWxsb3dhYmxlIHZhbHVlcyBhcmUgY29udHJvbGxlZCBieSBpdHMKLSAqIGRlY2xhcmF0aW9uIGluIHRoZSBEb2N1bWVudCBUeXBlIERlZmluaXRpb24gKERURCkgZ292ZXJuaW5nIHRoaXMKLSAqIGtpbmQgb2YgZG9jdW1lbnQuCi0gKiA8UD4KLSAqIElmIHRoZSBhdHRyaWJ1dGUgaGFzIG5vdCBiZWVuIGV4cGxpY2l0bHkgYXNzaWduZWQgYSB2YWx1ZSwgYnV0IGhhcwotICogYmVlbiBkZWNsYXJlZCBpbiB0aGUgRFRELCBpdCB3aWxsIGV4aXN0IGFuZCBoYXZlIHRoYXQgZGVmYXVsdC4gT25seQotICogaWYgbmVpdGhlciB0aGUgZG9jdW1lbnQgbm9yIHRoZSBEVEQgc3BlY2lmaWVzIGEgdmFsdWUgd2lsbCB0aGUKLSAqIEF0dHJpYnV0ZSByZWFsbHkgYmUgY29uc2lkZXJlZCBhYnNlbnQgYW5kIGhhdmUgbm8gdmFsdWU7IGluIHRoYXQKLSAqIGNhc2UsIHF1ZXJ5aW5nIHRoZSBhdHRyaWJ1dGUgd2lsbCByZXR1cm4gbnVsbC4KLSAqIDxQPgotICogQXR0cmlidXRlcyBtYXkgaGF2ZSBtdWx0aXBsZSBjaGlsZHJlbiB0aGF0IGNvbnRhaW4gdGhlaXIgZGF0YS4gKFhNTAotICogYWxsb3dzIGF0dHJpYnV0ZXMgdG8gY29udGFpbiBlbnRpdHkgcmVmZXJlbmNlcywgYW5kIHRva2VuaXplZAotICogYXR0cmlidXRlIHR5cGVzIHN1Y2ggYXMgTk1UT0tFTlMgbWF5IGhhdmUgYSBjaGlsZCBmb3IgZWFjaCB0b2tlbi4pCi0gKiBGb3IgY29udmVuaWVuY2UsIHRoZSBBdHRyaWJ1dGUgb2JqZWN0J3MgZ2V0VmFsdWUoKSBtZXRob2QgcmV0dXJucwotICogdGhlIHN0cmluZyB2ZXJzaW9uIG9mIHRoZSBhdHRyaWJ1dGUncyB2YWx1ZS4KLSAqIDxQPgotICogQXR0cmlidXRlcyBhcmUgbm90IGNoaWxkcmVuIG9mIHRoZSBFbGVtZW50cyB0aGV5IGJlbG9uZyB0bywgaW4gdGhlCi0gKiB1c3VhbCBzZW5zZSwgYW5kIGhhdmUgbm8gdmFsaWQgUGFyZW50IHJlZmVyZW5jZS4gSG93ZXZlciwgdGhlIHNwZWMKLSAqIHNheXMgdGhleSBfZG9fIGJlbG9uZyB0byBhIHNwZWNpZmljIEVsZW1lbnQsIGFuZCBhbiBJTlVTRSBleGNlcHRpb24KLSAqIGlzIHRvIGJlIHRocm93biBpZiB0aGUgdXNlciBhdHRlbXB0cyB0byBleHBsaWNpdGx5IHNoYXJlIHRoZW0KLSAqIGJldHdlZW4gZWxlbWVudHMuCi0gKiA8UD4KLSAqIE5vdGUgdGhhdCBFbGVtZW50cyBkbyBub3QgcGVybWl0IGF0dHJpYnV0ZXMgdG8gYXBwZWFyIHRvIGJlIHNoYXJlZAotICogKHNlZSB0aGUgSU5VU0UgZXhjZXB0aW9uKSwgc28gdGhpcyBvYmplY3QncyBtdXRhYmlsaXR5IGlzCi0gKiBvZmZpY2lhbGx5IG5vdCBhbiBpc3N1ZS4KLSAqIDxwPgotICogTm90ZTogVGhlIG93bmVyTm9kZSBhdHRyaWJ1dGUgaXMgdXNlZCB0byBzdG9yZSB0aGUgRWxlbWVudCB0aGUgQXR0cgotICogbm9kZSBpcyBhc3NvY2lhdGVkIHdpdGguIEF0dHIgbm9kZXMgZG8gbm90IGhhdmUgcGFyZW50IG5vZGVzLgotICogQmVzaWRlcywgdGhlIGdldE93bmVyRWxlbWVudCgpIG1ldGhvZCBjYW4gYmUgdXNlZCB0byBnZXQgdGhlIGVsZW1lbnQgbm9kZQotICogdGhpcyBhdHRyaWJ1dGUgaXMgYXNzb2NpYXRlZCB3aXRoLgotICogPFA+Ci0gKiBBdHRySW1wbCBkb2VzIG5vdCBzdXBwb3J0IE5hbWVzcGFjZXMuIEF0dHJOU0ltcGwsIHdoaWNoIGluaGVyaXRzIGZyb20KLSAqIGl0LCBkb2VzLgotICoKLSAqIDxwPkF0dHJJbXBsIHVzZWQgdG8gaW5oZXJpdCBmcm9tIFBhcmVudE5vZGUuIEl0IG5vdyBkaXJlY3RseSBpbmhlcml0cyBmcm9tCi0gKiBOb2RlSW1wbCBhbmQgcHJvdmlkZSBpdHMgb3duIGltcGxlbWVudGF0aW9uIG9mIHRoZSBQYXJlbnROb2RlJ3MgYmVoYXZpb3IuCi0gKiBUaGUgcmVhc29uIGlzIHRoYXQgd2Ugbm93IHRyeSBhbmQgYXZvaWQgdG8gYWx3YXlzIGNyZWF0ZSBhIFRleHQgbm9kZSB0bwotICogaG9sZCB0aGUgdmFsdWUgb2YgYW4gYXR0cmlidXRlLiBUaGUgRE9NIHNwZWMgcmVxdWlyZXMgaXQsIHNvIHdlIHN0aWxsIGhhdmUKLSAqIHRvIGRvIGl0IGluIGNhc2UgZ2V0Rmlyc3RDaGlsZCgpIGlzIGNhbGxlZCBmb3IgaW5zdGFuY2UuIFRoZSByZWFzb24KLSAqIGF0dHJpYnV0ZSB2YWx1ZXMgYXJlIHN0b3JlZCBhcyBhIGxpc3Qgb2Ygbm9kZXMgaXMgc28gdGhhdCB0aGV5IGNhbiBjYXJyeQotICogbW9yZSB0aGFuIGEgc2ltcGxlIHN0cmluZy4gVGhleSBjYW4gYWxzbyBjb250YWluIEVudGl0eVJlZmVyZW5jZSBub2Rlcy4KLSAqIEhvd2V2ZXIsIG1vc3Qgb2YgdGhlIHRpbWVzIHBlb3BsZSBvbmx5IGhhdmUgYSBzaW5nbGUgc3RyaW5nIHRoYXQgdGhleSBvbmx5Ci0gKiBzZXQgYW5kIGdldCB0aHJvdWdoIEVsZW1lbnQuc2V0L2dldEF0dHJpYnV0ZSBvciBBdHRyLnNldC9nZXRWYWx1ZS4gSW4gdGhpcwotICogbmV3IHZlcnNpb24sIHRoZSBBdHRyIG5vZGUgaGFzIGEgdmFsdWUgcG9pbnRlciB3aGljaCBjYW4gZWl0aGVyIGJlIHRoZQotICogU3RyaW5nIGRpcmVjdGx5IG9yIGEgcG9pbnRlciB0byB0aGUgZmlyc3QgQ2hpbGROb2RlLiBBIGZsYWcgdGVsbHMgd2hpY2ggb25lCi0gKiBpdCBjdXJyZW50bHkgaXMuIE5vdGUgdGhhdCB3aGlsZSB3ZSB0cnkgdG8gc3RpY2sgd2l0aCB0aGUgZGlyZWN0IFN0cmluZyBhcwotICogbXVjaCBhcyBwb3NzaWJsZSBvbmNlIHdlJ3ZlIHN3aXRjaGVkIHRvIGEgbm9kZSB0aGVyZSBpcyBubyBnb2luZyBiYWNrLiBUaGlzCi0gKiBpcyBiZWNhdXNlIHdlIGhhdmUgbm8gd2F5IHRvIGtub3cgd2hldGhlciB0aGUgYXBwbGljYXRpb24ga2VlcHMgcmVmZXJyaW5nIHRvCi0gKiB0aGUgbm9kZSB3ZSBvbmNlIHJldHVybmVkLgotICogPHA+IFRoZSBnYWluIGluIG1lbW9yeSB2YXJpZXMgb24gdGhlIGRlbnNpdHkgb2YgYXR0cmlidXRlcyBpbiB0aGUgZG9jdW1lbnQuCi0gKiBCdXQgaW4gdGhlIHRlc3RzIEkndmUgcnVuIEkndmUgc2VlbiB1cCB0byAxMiUgb2YgbWVtb3J5IGdhaW4uIEFuZCB0aGUgZ29vZAotICogdGhpbmcgaXMgdGhhdCBpdCBhbHNvIGxlYWRzIHRvIGEgc2xpZ2h0IGdhaW4gaW4gc3BlZWQgYmVjYXVzZSB3ZSBhbGxvY2F0ZQotICogZmV3ZXIgb2JqZWN0cyEgSSBtZWFuLCB0aGF0J3MgdW50aWwgd2UgaGF2ZSB0byBhY3R1YWxseSBjcmVhdGUgdGhlIG5vZGUuLi4KLSAqIDxwPgotICogVG8gYXZvaWQgdG9vIG11Y2ggZHVwbGljYXRlZCBjb2RlLCBJIGdvdCByaWQgb2YgUGFyZW50Tm9kZSBhbmQgcmVuYW1lZAotICogQ2hpbGRBbmRQYXJlbnROb2RlLCB3aGljaCBJIG5ldmVyIHJlYWxseSBsaWtlZCwgdG8gUGFyZW50Tm9kZSBmb3IKLSAqIHNpbXBsaWNpdHksIHRoaXMgZG9lc24ndCBtYWtlIG11Y2ggb2YgYSBkaWZmZXJlbmNlIGluIG1lbW9yeSB1c2FnZSBiZWNhdXNlCi0gKiB0aGVyZSBhcmUgb25seSB2ZXJ5IGZldyBvYmplY3RzIHRoYXQgYXJlIG9ubHkgYSBQYXJlbnQuIFRoaXMgaXMgb25seSB0cnVlCi0gKiBub3cgYmVjYXVzZSBBdHRySW1wbCBub3cgaW5oZXJpdHMgZGlyZWN0bHkgZnJvbSBOb2RlSW1wbCBhbmQgaGFzIGl0cyBvd24KLSAqIGltcGxlbWVudGF0aW9uIG9mIHRoZSBQYXJlbnROb2RlJ3Mgbm9kZSBiZWhhdmlvci4gU28gdGhlcmUgaXMgc3RpbGwgc29tZQotICogZHVwbGljYXRlZCBjb2RlIHRoZXJlLgotICogPHA+Ci0gKiBUaGlzIGNsYXNzIGRvZXNuJ3QgZGlyZWN0bHkgc3VwcG9ydCBtdXRhdGlvbiBldmVudHMsIGhvd2V2ZXIsIGl0IG5vdGlmaWVzCi0gKiB0aGUgZG9jdW1lbnQgd2hlbiBtdXRhdGlvbnMgYXJlIHBlcmZvcm1lZCBzbyB0aGF0IHRoZSBkb2N1bWVudCBjbGFzcyBkbyBzby4KLSAqCi0gKiA8cD48Yj5XQVJOSU5HPC9iPjogU29tZSBvZiB0aGUgY29kZSBoZXJlIGlzIHBhcnRpYWxseSBkdXBsaWNhdGVkIGluCi0gKiBQYXJlbnROb2RlLCBiZSBjYXJlZnVsIHRvIGtlZXAgdGhlc2UgdHdvIGNsYXNzZXMgaW4gc3luYyEKLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQHNlZSBBdHRyTlNJbXBsCi0gKgotICogQGF1dGhvciBBcm5hdWQgIExlIEhvcnMsIElCTQotICogQGF1dGhvciBKb2UgS2Vzc2VsbWFuLCBJQk0KLSAqIEBhdXRob3IgQW5keSBDbGFyaywgSUJNCi0gKiBAdmVyc2lvbiAkSWQ6IEF0dHJJbXBsLmphdmEsdiAxLjUgMjAwOC8wNi8xMCAwMDo1OTozMiBqb2VodyBFeHAgJAotICogQHNpbmNlIFBSLURPTS1MZXZlbC0xLTE5OTgwODE4LgotICoKLSAqLwotcHVibGljIGNsYXNzIEF0dHJJbXBsCi0gICAgZXh0ZW5kcyBOb2RlSW1wbAotICAgIGltcGxlbWVudHMgQXR0ciwgVHlwZUluZm97Ci0KLSAgICAvLwotICAgIC8vIENvbnN0YW50cwotICAgIC8vCi0KLSAgICAvKiogU2VyaWFsaXphdGlvbiB2ZXJzaW9uLiAqLwotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA3Mjc3NzA3Njg4MjE4OTcyMTAyTDsKLQotICAgIC8qKiBEVEQgbmFtZXNwYWNlLiAqKi8KLSAgICBzdGF0aWMgZmluYWwgU3RyaW5nIERURF9VUkkgPSAiaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLXhtbCI7Ci0KLSAgICAvLwotICAgIC8vIERhdGEKLSAgICAvLwotCi0gICAgLyoqIFRoaXMgY2FuIGVpdGhlciBiZSBhIFN0cmluZyBvciB0aGUgZmlyc3QgY2hpbGQgbm9kZS4gKi8KLSAgICBwcm90ZWN0ZWQgT2JqZWN0IHZhbHVlID0gbnVsbDsKLQotICAgIC8qKiBBdHRyaWJ1dGUgbmFtZS4gKi8KLSAgICBwcm90ZWN0ZWQgU3RyaW5nIG5hbWU7Ci0KLSAgICAvKiogVHlwZSBpbmZvcm1hdGlvbiAqLwotICAgIC8vIFJFVklTSVQ6IHdlIGFyZSBsb3NpbmcgdGhlIHR5cGUgaW5mb3JtYXRpb24gaW4gRE9NIGR1cmluZyBzZXJpYWxpemF0aW9uCi0gICAgdHJhbnNpZW50IE9iamVjdCB0eXBlOwotCi0gICAgcHJvdGVjdGVkIFRleHRJbXBsIHRleHROb2RlID0gbnVsbDsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIEF0dHJpYnV0ZSBoYXMgbm8gcHVibGljIGNvbnN0cnVjdG9yLiBQbGVhc2UgdXNlIHRoZSBmYWN0b3J5Ci0gICAgICogbWV0aG9kIGluIHRoZSBEb2N1bWVudCBjbGFzcy4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgQXR0ckltcGwoQ29yZURvY3VtZW50SW1wbCBvd25lckRvY3VtZW50LCBTdHJpbmcgbmFtZSkgewotICAgICAgICBzdXBlcihvd25lckRvY3VtZW50KTsKLSAgICAgICAgdGhpcy5uYW1lID0gbmFtZTsKLSAgICAgICAgLyoqIEZhbHNlIGZvciBkZWZhdWx0IGF0dHJpYnV0ZXMuICovCi0gICAgICAgIGlzU3BlY2lmaWVkKHRydWUpOwotICAgICAgICBoYXNTdHJpbmdWYWx1ZSh0cnVlKTsKLSAgICB9Ci0KLSAgICAvLyBmb3IgQXR0ck5TSW1wbAotICAgIHByb3RlY3RlZCBBdHRySW1wbCgpIHt9Ci0KLSAgICAvLyBTdXBwb3J0IGZvciBET00gTGV2ZWwgMyByZW5hbWVOb2RlIG1ldGhvZC4KLSAgICAvLyBOb3RlOiBUaGlzIG9ubHkgZGVhbHMgd2l0aCBwYXJ0IG9mIHRoZSBwYi4gSXQgaXMgZXhwZWN0ZWQgdG8gYmUKLSAgICAvLyBjYWxsZWQgYWZ0ZXIgdGhlIEF0dHIgaGFzIGJlZW4gZGV0YWNoZWQgZm9yIG9uZSB0aGluZy4KLSAgICAvLyBDb3JlRG9jdW1lbnRJbXBsIGRvZXMgYWxsIHRoZSB3b3JrLgotICAgIHZvaWQgcmVuYW1lKFN0cmluZyBuYW1lKSB7Ci0gICAgICAgIGlmIChuZWVkc1N5bmNEYXRhKCkpIHsKLSAgICAgICAgICAgIHN5bmNocm9uaXplRGF0YSgpOwotICAgICAgICB9Ci0gICAgICAgIHRoaXMubmFtZSA9IG5hbWU7Ci0gICAgfQotCi0gICAgLy8gY3JlYXRlIGEgcmVhbCB0ZXh0IG5vZGUgYXMgY2hpbGQgaWYgd2UgZG9uJ3QgaGF2ZSBvbmUgeWV0Ci0gICAgcHJvdGVjdGVkIHZvaWQgbWFrZUNoaWxkTm9kZSgpIHsKLSAgICAgICAgaWYgKGhhc1N0cmluZ1ZhbHVlKCkpIHsKLSAgICAgICAgICAgIGlmICh2YWx1ZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgVGV4dEltcGwgdGV4dCA9Ci0gICAgICAgICAgICAgICAgICAgIChUZXh0SW1wbCkgb3duZXJEb2N1bWVudCgpLmNyZWF0ZVRleHROb2RlKChTdHJpbmcpIHZhbHVlKTsKLSAgICAgICAgICAgICAgICB2YWx1ZSA9IHRleHQ7Ci0gICAgICAgICAgICAgICAgdGV4dC5pc0ZpcnN0Q2hpbGQodHJ1ZSk7Ci0gICAgICAgICAgICAgICAgdGV4dC5wcmV2aW91c1NpYmxpbmcgPSB0ZXh0OwotICAgICAgICAgICAgICAgIHRleHQub3duZXJOb2RlID0gdGhpczsKLSAgICAgICAgICAgICAgICB0ZXh0LmlzT3duZWQodHJ1ZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBoYXNTdHJpbmdWYWx1ZShmYWxzZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBOT04tRE9NCi0gICAgICogc2V0IHRoZSBvd25lckRvY3VtZW50IG9mIHRoaXMgbm9kZSBhbmQgaXRzIGNoaWxkcmVuCi0gICAgICovCi0gICAgdm9pZCBzZXRPd25lckRvY3VtZW50KENvcmVEb2N1bWVudEltcGwgZG9jKSB7Ci0gICAgICAgIGlmIChuZWVkc1N5bmNDaGlsZHJlbigpKSB7Ci0gICAgICAgICAgICBzeW5jaHJvbml6ZUNoaWxkcmVuKCk7Ci0gICAgICAgIH0KLSAgICAgICAgc3VwZXIuc2V0T3duZXJEb2N1bWVudChkb2MpOwotICAgICAgICBpZiAoIWhhc1N0cmluZ1ZhbHVlKCkpIHsKLSAgICAgICAgICAgIGZvciAoQ2hpbGROb2RlIGNoaWxkID0gKENoaWxkTm9kZSkgdmFsdWU7Ci0gICAgICAgICAgICAgICAgIGNoaWxkICE9IG51bGw7IGNoaWxkID0gY2hpbGQubmV4dFNpYmxpbmcpIHsKLSAgICAgICAgICAgICAgICBjaGlsZC5zZXRPd25lckRvY3VtZW50KGRvYyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBOT04tRE9NOiBzZXQgdGhlIHR5cGUgb2YgdGhpcyBhdHRyaWJ1dGUgdG8gYmUgSUQgdHlwZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBpZAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldElkQXR0cmlidXRlKGJvb2xlYW4gaWQpewotICAgICAgICBpZiAobmVlZHNTeW5jRGF0YSgpKSB7Ci0gICAgICAgICAgICBzeW5jaHJvbml6ZURhdGEoKTsKLSAgICAgICAgfQotICAgICAgICBpc0lkQXR0cmlidXRlKGlkKTsKLSAgICB9Ci0gICAgLyoqIERPTSBMZXZlbCAzOiBpc0lkKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0lkKCl7Ci0gICAgICAgIC8vIFJFVklTSVQ6IHNob3VsZCBhbiBhdHRyaWJ1dGUgdGhhdCBpcyBub3QgaW4gdGhlIHRyZWUgcmV0dXJuCi0gICAgICAgIC8vIGlzSUQgdHJ1ZT8KLSAgICAgICAgcmV0dXJuIGlzSWRBdHRyaWJ1dGUoKTsKLSAgICB9Ci0KLQotICAgIC8vCi0gICAgLy8gTm9kZSBtZXRob2RzCi0gICAgLy8KLQotICAgIHB1YmxpYyBOb2RlIGNsb25lTm9kZShib29sZWFuIGRlZXApIHsKLQotICAgICAgICBpZiAobmVlZHNTeW5jQ2hpbGRyZW4oKSkgewotICAgICAgICAgICAgc3luY2hyb25pemVDaGlsZHJlbigpOwotICAgICAgICB9Ci0gICAgICAgIEF0dHJJbXBsIGNsb25lID0gKEF0dHJJbXBsKSBzdXBlci5jbG9uZU5vZGUoZGVlcCk7Ci0KLSAgICAgICAgLy8gdGFrZSBjYXJlIG9mIGNhc2Ugd2hlcmUgdGhlcmUgYXJlIGtpZHMKLSAgICAgICAgaWYgKCFjbG9uZS5oYXNTdHJpbmdWYWx1ZSgpKSB7Ci0KLSAgICAgICAgICAgIC8vIE5lZWQgdG8gYnJlYWsgdGhlIGFzc29jaWF0aW9uIHcvIG9yaWdpbmFsIGtpZHMKLSAgICAgICAgICAgIGNsb25lLnZhbHVlID0gbnVsbDsKLQotICAgICAgICAgICAgLy8gQ2xvbmluZyBhbiBBdHRyaWJ1dGUgYWx3YXlzIGNsb25lcyBpdHMgY2hpbGRyZW4sCi0gICAgICAgICAgICAvLyBzaW5jZSB0aGV5IHJlcHJlc2VudCBpdHMgdmFsdWUsIG5vIG1hdHRlciB3aGV0aGVyIHRoaXMKLSAgICAgICAgICAgIC8vIGlzIGEgZGVlcCBjbG9uZSBvciBub3QKLSAgICAgICAgICAgIGZvciAoTm9kZSBjaGlsZCA9IChOb2RlKSB2YWx1ZTsgY2hpbGQgIT0gbnVsbDsKLSAgICAgICAgICAgICAgICAgY2hpbGQgPSBjaGlsZC5nZXROZXh0U2libGluZygpKSB7Ci0gICAgICAgICAgICAgICAgIGNsb25lLmFwcGVuZENoaWxkKGNoaWxkLmNsb25lTm9kZSh0cnVlKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgY2xvbmUuaXNTcGVjaWZpZWQodHJ1ZSk7Ci0gICAgICAgIHJldHVybiBjbG9uZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBIHNob3J0IGludGVnZXIgaW5kaWNhdGluZyB3aGF0IHR5cGUgb2Ygbm9kZSB0aGlzIGlzLiBUaGUgbmFtZWQKLSAgICAgKiBjb25zdGFudHMgZm9yIHRoaXMgdmFsdWUgYXJlIGRlZmluZWQgaW4gdGhlIG9yZy53M2MuZG9tLk5vZGUgaW50ZXJmYWNlLgotICAgICAqLwotICAgIHB1YmxpYyBzaG9ydCBnZXROb2RlVHlwZSgpIHsKLSAgICAgICAgcmV0dXJuIE5vZGUuQVRUUklCVVRFX05PREU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgYXR0cmlidXRlIG5hbWUKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE5vZGVOYW1lKCkgewotICAgICAgICBpZiAobmVlZHNTeW5jRGF0YSgpKSB7Ci0gICAgICAgICAgICBzeW5jaHJvbml6ZURhdGEoKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbmFtZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJbXBsaWNpdCBpbiB0aGUgcmVyb3V0aW5nIG9mIGdldE5vZGVWYWx1ZSB0byBnZXRWYWx1ZSBpcyB0aGUKLSAgICAgKiBuZWVkIHRvIHJlZGVmaW5lIHNldE5vZGVWYWx1ZSwgZm9yIHN5bW1ldHJ5J3Mgc2FrZS4gIE5vdGUgdGhhdAotICAgICAqIHNpbmNlIHdlJ3JlIGV4cGxpY2l0bHkgcHJvdmlkaW5nIGEgdmFsdWUsIFNwZWNpZmllZCBzaG91bGQgYmUgc2V0Ci0gICAgICogdHJ1ZS4uLi4gZXZlbiBpZiB0aGF0IHZhbHVlIGVxdWFscyB0aGUgZGVmYXVsdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXROb2RlVmFsdWUoU3RyaW5nIHZhbHVlKSB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKLSAgICAgICAgc2V0VmFsdWUodmFsdWUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgb3JnLnczYy5kb20uVHlwZUluZm8jZ2V0VHlwZU5hbWUoKQotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VHlwZU5hbWUoKSB7Ci0gICAgICAgIHJldHVybiAoU3RyaW5nKXR5cGU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBvcmcudzNjLmRvbS5UeXBlSW5mbyNnZXRUeXBlTmFtZXNwYWNlKCkKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFR5cGVOYW1lc3BhY2UoKSB7Ci0gICAgICAgIGlmICh0eXBlICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBEVERfVVJJOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIE1ldGhvZCBnZXRTY2hlbWFUeXBlSW5mby4KLSAgICAgKiBAcmV0dXJuIFR5cGVJbmZvCi0gICAgICovCi0gICAgcHVibGljIFR5cGVJbmZvIGdldFNjaGVtYVR5cGVJbmZvKCl7Ci0gICAgICByZXR1cm4gdGhpczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJbiBBdHRyaWJ1dGUgb2JqZWN0cywgTm9kZVZhbHVlIGlzIGNvbnNpZGVyZWQgYSBzeW5vbnltIGZvcgotICAgICAqIFZhbHVlLgotICAgICAqCi0gICAgICogQHNlZSAjZ2V0VmFsdWUoKQotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Tm9kZVZhbHVlKCkgewotICAgICAgICByZXR1cm4gZ2V0VmFsdWUoKTsKLSAgICB9Ci0KLSAgICAvLwotICAgIC8vIEF0dHIgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBJbiBBdHRyaWJ1dGVzLCBOb2RlTmFtZSBpcyBjb25zaWRlcmVkIGEgc3lub255bSBmb3IgdGhlCi0gICAgICogYXR0cmlidXRlJ3MgTmFtZQotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpIHsKLQotICAgICAgICBpZiAobmVlZHNTeW5jRGF0YSgpKSB7Ci0gICAgICAgICAgICBzeW5jaHJvbml6ZURhdGEoKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbmFtZTsKLQotICAgIH0gLy8gZ2V0TmFtZSgpOlN0cmluZwotCi0gICAgLyoqCi0gICAgICogVGhlIERPTSBkb2Vzbid0IGNsZWFybHkgZGVmaW5lIHdoYXQgc2V0VmFsdWUobnVsbCkgbWVhbnMuIEkndmUgdGFrZW4gaXQKLSAgICAgKiBhcyAicmVtb3ZlIGFsbCBjaGlsZHJlbiIsIHdoaWNoIGZyb20gb3V0c2lkZSBzaG91bGQgYXBwZWFyCi0gICAgICogc2ltaWxhciB0byBzZXR0aW5nIGl0IHRvIHRoZSBlbXB0eSBzdHJpbmcuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0VmFsdWUoU3RyaW5nIG5ld3ZhbHVlKSB7Ci0KLSAgICAgICAgQ29yZURvY3VtZW50SW1wbCBvd25lckRvY3VtZW50ID0gb3duZXJEb2N1bWVudCgpOwotCi0gICAgICAgIGlmIChvd25lckRvY3VtZW50LmVycm9yQ2hlY2tpbmcgJiYgaXNSZWFkT25seSgpKSB7Ci0gICAgICAgICAgICBTdHJpbmcgbXNnID0gRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwgIk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiIsIG51bGwpOwotICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSLCBtc2cpOwotICAgICAgICB9Ci0KLSAgICAgICAgRWxlbWVudCBvd25lckVsZW1lbnQgPSBnZXRPd25lckVsZW1lbnQoKTsKLSAgICAgICAgU3RyaW5nIG9sZHZhbHVlID0gIiI7Ci0gICAgICAgIGlmIChuZWVkc1N5bmNEYXRhKCkpIHsKLSAgICAgICAgICAgIHN5bmNocm9uaXplRGF0YSgpOwotICAgICAgICB9Ci0gICAgICAgIGlmIChuZWVkc1N5bmNDaGlsZHJlbigpKSB7Ci0gICAgICAgICAgICBzeW5jaHJvbml6ZUNoaWxkcmVuKCk7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKHZhbHVlICE9IG51bGwpIHsKLSAgICAgICAgICAgIGlmIChvd25lckRvY3VtZW50LmdldE11dGF0aW9uRXZlbnRzKCkpIHsKLSAgICAgICAgICAgICAgICAvLyBDYW4gbm8gbG9uZ2VyIGp1c3QgZGlzY2FyZCB0aGUga2lkczsgdGhleSBtYXkgaGF2ZQotICAgICAgICAgICAgICAgIC8vIGV2ZW50IGxpc3RlbmVycyB3YWl0aW5nIGZvciB0aGVtIHRvIGRpc2Nvbm5lY3QuCi0gICAgICAgICAgICAgICAgaWYgKGhhc1N0cmluZ1ZhbHVlKCkpIHsKLSAgICAgICAgICAgICAgICAgICAgb2xkdmFsdWUgPSAoU3RyaW5nKSB2YWx1ZTsKLSAgICAgICAgICAgICAgICAgICAgLy8gY3JlYXRlIGFuIGFjdHVhbCB0ZXh0IG5vZGUgYXMgb3VyIGNoaWxkIHNvCi0gICAgICAgICAgICAgICAgICAgIC8vIHRoYXQgd2UgY2FuIHVzZSBpdCBpbiB0aGUgZXZlbnQKLSAgICAgICAgICAgICAgICAgICAgaWYgKHRleHROb2RlID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHRleHROb2RlID0gKFRleHRJbXBsKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG93bmVyRG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoKFN0cmluZykgdmFsdWUpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgdGV4dE5vZGUuZGF0YSA9IChTdHJpbmcpIHZhbHVlOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIHZhbHVlID0gdGV4dE5vZGU7Ci0gICAgICAgICAgICAgICAgICAgIHRleHROb2RlLmlzRmlyc3RDaGlsZCh0cnVlKTsKLSAgICAgICAgICAgICAgICAgICAgdGV4dE5vZGUucHJldmlvdXNTaWJsaW5nID0gdGV4dE5vZGU7Ci0gICAgICAgICAgICAgICAgICAgIHRleHROb2RlLm93bmVyTm9kZSA9IHRoaXM7Ci0gICAgICAgICAgICAgICAgICAgIHRleHROb2RlLmlzT3duZWQodHJ1ZSk7Ci0gICAgICAgICAgICAgICAgICAgIGhhc1N0cmluZ1ZhbHVlKGZhbHNlKTsKLSAgICAgICAgICAgICAgICAgICAgaW50ZXJuYWxSZW1vdmVDaGlsZCh0ZXh0Tm9kZSwgdHJ1ZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICBvbGR2YWx1ZSA9IGdldFZhbHVlKCk7Ci0gICAgICAgICAgICAgICAgICAgIHdoaWxlICh2YWx1ZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpbnRlcm5hbFJlbW92ZUNoaWxkKChOb2RlKSB2YWx1ZSwgdHJ1ZSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBpZiAoaGFzU3RyaW5nVmFsdWUoKSkgewotICAgICAgICAgICAgICAgICAgICBvbGR2YWx1ZSA9IChTdHJpbmcpIHZhbHVlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gc2ltcGx5IGRpc2NhcmQgY2hpbGRyZW4gaWYgYW55Ci0gICAgICAgICAgICAgICAgICAgIG9sZHZhbHVlID0gZ2V0VmFsdWUoKTsKLSAgICAgICAgICAgICAgICAgICAgLy8gcmVtb3ZlIHJlZiBmcm9tIGZpcnN0IGNoaWxkIHRvIGxhc3QgY2hpbGQKLSAgICAgICAgICAgICAgICAgICAgQ2hpbGROb2RlIGZpcnN0Q2hpbGQgPSAoQ2hpbGROb2RlKSB2YWx1ZTsKLSAgICAgICAgICAgICAgICAgICAgZmlyc3RDaGlsZC5wcmV2aW91c1NpYmxpbmcgPSBudWxsOwotICAgICAgICAgICAgICAgICAgICBmaXJzdENoaWxkLmlzRmlyc3RDaGlsZChmYWxzZSk7Ci0gICAgICAgICAgICAgICAgICAgIGZpcnN0Q2hpbGQub3duZXJOb2RlID0gb3duZXJEb2N1bWVudDsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLy8gdGhlbiByZW1vdmUgcmVmIHRvIGN1cnJlbnQgdmFsdWUKLSAgICAgICAgICAgICAgICB2YWx1ZSA9IG51bGw7Ci0gICAgICAgICAgICAgICAgbmVlZHNTeW5jQ2hpbGRyZW4oZmFsc2UpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKGlzSWRBdHRyaWJ1dGUoKSAmJiBvd25lckVsZW1lbnQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIG93bmVyRG9jdW1lbnQucmVtb3ZlSWRlbnRpZmllcihvbGR2YWx1ZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBDcmVhdGUgYW5kIGFkZCB0aGUgbmV3IG9uZSwgZ2VuZXJhdGluZyBvbmx5IG5vbi1hZ2dyZWdhdGUgZXZlbnRzCi0gICAgICAgIC8vIChUaGVyZSBhcmUgbm8gbGlzdGVuZXJzIG9uIHRoZSBuZXcgVGV4dCwgYnV0IHRoZXJlIG1heSBiZQotICAgICAgICAvLyBjYXB0dXJlL2J1YmJsZSBsaXN0ZW5lcnMgb24gdGhlIEF0dHIuCi0gICAgICAgIC8vIE5vdGUgdGhhdCBhZ2dyZWdhdGUgZXZlbnRzIGFyZSBOT1QgZGlzcGF0Y2hlZCBoZXJlLAotICAgICAgICAvLyBzaW5jZSB3ZSBuZWVkIHRvIGNvbWJpbmUgdGhlIHJlbW92ZSBhbmQgaW5zZXJ0LgotICAgICAgICBpc1NwZWNpZmllZCh0cnVlKTsKLSAgICAgICAgaWYgKG93bmVyRG9jdW1lbnQuZ2V0TXV0YXRpb25FdmVudHMoKSkgewotICAgICAgICAgICAgLy8gaWYgdGhlcmUgYXJlIGFueSBldmVudCBoYW5kbGVycyBjcmVhdGUgYSByZWFsIG5vZGUKLSAgICAgICAgICAgIGludGVybmFsSW5zZXJ0QmVmb3JlKG93bmVyRG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUobmV3dmFsdWUpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwgdHJ1ZSk7Ci0gICAgICAgICAgICBoYXNTdHJpbmdWYWx1ZShmYWxzZSk7Ci0gICAgICAgICAgICAvLyBub3RpZnkgZG9jdW1lbnQKLSAgICAgICAgICAgIG93bmVyRG9jdW1lbnQubW9kaWZpZWRBdHRyVmFsdWUodGhpcywgb2xkdmFsdWUpOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgLy8gZGlyZWN0bHkgc3RvcmUgdGhlIHN0cmluZwotICAgICAgICAgICAgdmFsdWUgPSBuZXd2YWx1ZTsKLSAgICAgICAgICAgIGhhc1N0cmluZ1ZhbHVlKHRydWUpOwotICAgICAgICAgICAgY2hhbmdlZCgpOwotICAgICAgICB9Ci0gICAgICAgIGlmIChpc0lkQXR0cmlidXRlKCkgJiYgb3duZXJFbGVtZW50ICE9IG51bGwpIHsKLSAgICAgICAgICAgIG93bmVyRG9jdW1lbnQucHV0SWRlbnRpZmllcihuZXd2YWx1ZSwgb3duZXJFbGVtZW50KTsKLSAgICAgICAgfQotCi0gICAgfSAvLyBzZXRWYWx1ZShTdHJpbmcpCi0KLSAgICAvKioKLSAgICAgKiBUaGUgInN0cmluZyB2YWx1ZSIgb2YgYW4gQXR0cmlidXRlIGlzIGl0cyB0ZXh0IHJlcHJlc2VudGF0aW9uLAotICAgICAqIHdoaWNoIGluIHR1cm4gaXMgYSBjb25jYXRlbmF0aW9uIG9mIHRoZSBzdHJpbmcgdmFsdWVzIG9mIGl0cyBjaGlsZHJlbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFZhbHVlKCkgewotCi0gICAgICAgIGlmIChuZWVkc1N5bmNEYXRhKCkpIHsKLSAgICAgICAgICAgIHN5bmNocm9uaXplRGF0YSgpOwotICAgICAgICB9Ci0gICAgICAgIGlmIChuZWVkc1N5bmNDaGlsZHJlbigpKSB7Ci0gICAgICAgICAgICBzeW5jaHJvbml6ZUNoaWxkcmVuKCk7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiAiIjsKLSAgICAgICAgfQotICAgICAgICBpZiAoaGFzU3RyaW5nVmFsdWUoKSkgewotICAgICAgICAgICAgcmV0dXJuIChTdHJpbmcpIHZhbHVlOwotICAgICAgICB9Ci0KLSAgICAgICAgQ2hpbGROb2RlIGZpcnN0Q2hpbGQgPSAoKENoaWxkTm9kZSkgdmFsdWUpOwotCi0gICAgICAgIFN0cmluZyBkYXRhID0gbnVsbDsKLSAgICAgICAgaWYgKGZpcnN0Q2hpbGQuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLkVOVElUWV9SRUZFUkVOQ0VfTk9ERSl7Ci0gICAgICAgICAgICAgICAgZGF0YSA9ICgoRW50aXR5UmVmZXJlbmNlSW1wbClmaXJzdENoaWxkKS5nZXRFbnRpdHlSZWZWYWx1ZSgpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIGRhdGEgPSAgZmlyc3RDaGlsZC5nZXROb2RlVmFsdWUoKTsKLSAgICAgICAgfQotCi0gICAgICAgIENoaWxkTm9kZSBub2RlID0gZmlyc3RDaGlsZC5uZXh0U2libGluZzsKLQotICAgICAgICBpZiAobm9kZSA9PSBudWxsIHx8IGRhdGEgPT0gbnVsbCkgIHJldHVybiAoZGF0YSA9PSBudWxsKT8iIjpkYXRhOwotCi0gICAgICAgIFN0cmluZ0J1ZmZlciB2YWx1ZSA9IG5ldyBTdHJpbmdCdWZmZXIoZGF0YSk7Ci0gICAgICAgIHdoaWxlIChub2RlICE9IG51bGwpIHsKLSAgICAgICAgICAgIGlmIChub2RlLmdldE5vZGVUeXBlKCkgID09IE5vZGUuRU5USVRZX1JFRkVSRU5DRV9OT0RFKXsKLSAgICAgICAgICAgICAgICBkYXRhID0gKChFbnRpdHlSZWZlcmVuY2VJbXBsKW5vZGUpLmdldEVudGl0eVJlZlZhbHVlKCk7Ci0gICAgICAgICAgICAgICAgaWYgKGRhdGEgPT0gbnVsbCkgcmV0dXJuICIiOwotICAgICAgICAgICAgICAgIHZhbHVlLmFwcGVuZChkYXRhKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIHZhbHVlLmFwcGVuZChub2RlLmdldE5vZGVWYWx1ZSgpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIG5vZGUgPSBub2RlLm5leHRTaWJsaW5nOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiB2YWx1ZS50b1N0cmluZygpOwotCi0gICAgfSAvLyBnZXRWYWx1ZSgpOlN0cmluZwotCi0KLSAgICAvKioKLSAgICAgKiBUaGUgInNwZWNpZmllZCIgZmxhZyBpcyB0cnVlIGlmIGFuZCBvbmx5IGlmIHRoaXMgYXR0cmlidXRlJ3MKLSAgICAgKiB2YWx1ZSB3YXMgZXhwbGljaXRseSBzcGVjaWZpZWQgaW4gdGhlIG9yaWdpbmFsIGRvY3VtZW50LiBOb3RlIHRoYXQKLSAgICAgKiB0aGUgaW1wbGVtZW50YXRpb24sIG5vdCB0aGUgdXNlciwgaXMgaW4gY2hhcmdlIG9mIHRoaXMKLSAgICAgKiBwcm9wZXJ0eS4gSWYgdGhlIHVzZXIgYXNzZXJ0cyBhbiBBdHRyaWJ1dGUgdmFsdWUgKGV2ZW4gaWYgaXQgZW5kcwotICAgICAqIHVwIGhhdmluZyB0aGUgc2FtZSB2YWx1ZSBhcyB0aGUgZGVmYXVsdCksIGl0IGlzIGNvbnNpZGVyZWQgYQotICAgICAqIHNwZWNpZmllZCBhdHRyaWJ1dGUuIElmIHlvdSByZWFsbHkgd2FudCB0byByZXZlcnQgdG8gdGhlIGRlZmF1bHQsCi0gICAgICogZGVsZXRlIHRoZSBhdHRyaWJ1dGUgZnJvbSB0aGUgRWxlbWVudCwgYW5kIHRoZSBJbXBsZW1lbnRhdGlvbiB3aWxsCi0gICAgICogcmUtYXNzZXJ0IHRoZSBkZWZhdWx0IChpZiBhbnkpIGluIGl0cyBwbGFjZSwgd2l0aCB0aGUgYXBwcm9wcmlhdGUKLSAgICAgKiBzcGVjaWZpZWQ9ZmFsc2Ugc2V0dGluZy4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXRTcGVjaWZpZWQoKSB7Ci0KLSAgICAgICAgaWYgKG5lZWRzU3luY0RhdGEoKSkgewotICAgICAgICAgICAgc3luY2hyb25pemVEYXRhKCk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGlzU3BlY2lmaWVkKCk7Ci0KLSAgICB9IC8vIGdldFNwZWNpZmllZCgpOmJvb2xlYW4KLQotICAgIC8vCi0gICAgLy8gQXR0cjIgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBlbGVtZW50IG5vZGUgdGhhdCB0aGlzIGF0dHJpYnV0ZSBpcyBhc3NvY2lhdGVkIHdpdGgsCi0gICAgICogb3IgbnVsbCBpZiB0aGUgYXR0cmlidXRlIGhhcyBub3QgYmVlbiBhZGRlZCB0byBhbiBlbGVtZW50LgotICAgICAqCi0gICAgICogQHNlZSAjZ2V0T3duZXJFbGVtZW50Ci0gICAgICoKLSAgICAgKiBAZGVwcmVjYXRlZCBQcmV2aW91cyB3b3JraW5nIGRyYWZ0IG9mIERPTSBMZXZlbCAyLiBOZXcgbWV0aG9kCi0gICAgICogICAgICAgICAgICAgaXMgPHR0PmdldE93bmVyRWxlbWVudCgpPC90dD4uCi0gICAgICovCi0gICAgcHVibGljIEVsZW1lbnQgZ2V0RWxlbWVudCgpIHsKLSAgICAgICAgLy8gaWYgd2UgaGF2ZSBhbiBvd25lciwgb3duZXJOb2RlIGlzIG91ciBvd25lckVsZW1lbnQsIG90aGVyd2lzZSBpdCdzCi0gICAgICAgIC8vIG91ciBvd25lckRvY3VtZW50IGFuZCB3ZSBkb24ndCBoYXZlIGFuIG93bmVyRWxlbWVudAotICAgICAgICByZXR1cm4gKEVsZW1lbnQpIChpc093bmVkKCkgPyBvd25lck5vZGUgOiBudWxsKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBlbGVtZW50IG5vZGUgdGhhdCB0aGlzIGF0dHJpYnV0ZSBpcyBhc3NvY2lhdGVkIHdpdGgsCi0gICAgICogb3IgbnVsbCBpZiB0aGUgYXR0cmlidXRlIGhhcyBub3QgYmVlbiBhZGRlZCB0byBhbiBlbGVtZW50LgotICAgICAqCi0gICAgICogQHNpbmNlIFdELURPTS1MZXZlbC0yLTE5OTkwNzE5Ci0gICAgICovCi0gICAgcHVibGljIEVsZW1lbnQgZ2V0T3duZXJFbGVtZW50KCkgewotICAgICAgICAvLyBpZiB3ZSBoYXZlIGFuIG93bmVyLCBvd25lck5vZGUgaXMgb3VyIG93bmVyRWxlbWVudCwgb3RoZXJ3aXNlIGl0J3MKLSAgICAgICAgLy8gb3VyIG93bmVyRG9jdW1lbnQgYW5kIHdlIGRvbid0IGhhdmUgYW4gb3duZXJFbGVtZW50Ci0gICAgICAgIHJldHVybiAoRWxlbWVudCkgKGlzT3duZWQoKSA/IG93bmVyTm9kZSA6IG51bGwpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIG5vcm1hbGl6ZSgpIHsKLQotICAgICAgICAvLyBObyBuZWVkIHRvIG5vcm1hbGl6ZSBpZiBhbHJlYWR5IG5vcm1hbGl6ZWQgb3IKLSAgICAgICAgLy8gaWYgdmFsdWUgaXMga2VwdCBhcyBhIFN0cmluZy4KLSAgICAgICAgaWYgKGlzTm9ybWFsaXplZCgpIHx8IGhhc1N0cmluZ1ZhbHVlKCkpCi0gICAgICAgICAgICByZXR1cm47Ci0KLSAgICAgICAgTm9kZSBraWQsIG5leHQ7Ci0gICAgICAgIENoaWxkTm9kZSBmaXJzdENoaWxkID0gKENoaWxkTm9kZSl2YWx1ZTsKLSAgICAgICAgZm9yIChraWQgPSBmaXJzdENoaWxkOyBraWQgIT0gbnVsbDsga2lkID0gbmV4dCkgewotICAgICAgICAgICAgbmV4dCA9IGtpZC5nZXROZXh0U2libGluZygpOwotCi0gICAgICAgICAgICAvLyBJZiBraWQgaXMgYSB0ZXh0IG5vZGUsIHdlIG5lZWQgdG8gY2hlY2sgZm9yIG9uZSBvZiB0d28KLSAgICAgICAgICAgIC8vIGNvbmRpdGlvbnM6Ci0gICAgICAgICAgICAvLyAgIDEpIFRoZXJlIGlzIGFuIGFkamFjZW50IHRleHQgbm9kZQotICAgICAgICAgICAgLy8gICAyKSBUaGVyZSBpcyBubyBhZGphY2VudCB0ZXh0IG5vZGUsIGJ1dCBraWQgaXMKLSAgICAgICAgICAgIC8vICAgICAgYW4gZW1wdHkgdGV4dCBub2RlLgotICAgICAgICAgICAgaWYgKCBraWQuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLlRFWFRfTk9ERSApCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgLy8gSWYgYW4gYWRqYWNlbnQgdGV4dCBub2RlLCBtZXJnZSBpdCB3aXRoIGtpZAotICAgICAgICAgICAgICAgIGlmICggbmV4dCE9bnVsbCAmJiBuZXh0LmdldE5vZGVUeXBlKCkgPT0gTm9kZS5URVhUX05PREUgKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgKChUZXh0KWtpZCkuYXBwZW5kRGF0YShuZXh0LmdldE5vZGVWYWx1ZSgpKTsKLSAgICAgICAgICAgICAgICAgICAgcmVtb3ZlQ2hpbGQoIG5leHQgKTsKLSAgICAgICAgICAgICAgICAgICAgbmV4dCA9IGtpZDsgLy8gRG9uJ3QgYWR2YW5jZTsgdGhlcmUgbWlnaHQgYmUgYW5vdGhlci4KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gSWYga2lkIGlzIGVtcHR5LCByZW1vdmUgaXQKLSAgICAgICAgICAgICAgICAgICAgaWYgKCBraWQuZ2V0Tm9kZVZhbHVlKCkgPT0gbnVsbCB8fCBraWQuZ2V0Tm9kZVZhbHVlKCkubGVuZ3RoKCkgPT0gMCApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZUNoaWxkKCBraWQgKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGlzTm9ybWFsaXplZCh0cnVlKTsKLSAgICB9IC8vIG5vcm1hbGl6ZSgpCi0KLSAgICAvLwotICAgIC8vIFB1YmxpYyBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKiBOT04tRE9NLCBmb3IgdXNlIGJ5IHBhcnNlciAqLwotICAgIHB1YmxpYyB2b2lkIHNldFNwZWNpZmllZChib29sZWFuIGFyZykgewotCi0gICAgICAgIGlmIChuZWVkc1N5bmNEYXRhKCkpIHsKLSAgICAgICAgICAgIHN5bmNocm9uaXplRGF0YSgpOwotICAgICAgICB9Ci0gICAgICAgIGlzU3BlY2lmaWVkKGFyZyk7Ci0KLSAgICB9IC8vIHNldFNwZWNpZmllZChib29sZWFuKQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBOT04tRE9NOiB1c2VkIGJ5IHRoZSBwYXJzZXIKLSAgICAgICAgICogQHBhcmFtIHR5cGUKLSAgICAgICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0VHlwZSAoT2JqZWN0IHR5cGUpewotICAgICAgICB0aGlzLnR5cGUgPSB0eXBlOwotICAgIH0KLQotICAgIC8vCi0gICAgLy8gT2JqZWN0IG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqIE5PTi1ET00gbWV0aG9kIGZvciBkZWJ1Z2dpbmcgY29udmVuaWVuY2UgKi8KLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgICAgICByZXR1cm4gZ2V0TmFtZSgpICsgIj0iICsgIlwiIiArIGdldFZhbHVlKCkgKyAiXCIiOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRlc3Qgd2hldGhlciB0aGlzIG5vZGUgaGFzIGFueSBjaGlsZHJlbi4gQ29udmVuaWVuY2Ugc2hvcnRoYW5kCi0gICAgICogZm9yIChOb2RlLmdldEZpcnN0Q2hpbGQoKSE9bnVsbCkKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBoYXNDaGlsZE5vZGVzKCkgewotICAgICAgICBpZiAobmVlZHNTeW5jQ2hpbGRyZW4oKSkgewotICAgICAgICAgICAgc3luY2hyb25pemVDaGlsZHJlbigpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiB2YWx1ZSAhPSBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIE9idGFpbiBhIE5vZGVMaXN0IGVudW1lcmF0aW5nIGFsbCBjaGlsZHJlbiBvZiB0aGlzIG5vZGUuIElmIHRoZXJlCi0gICAgICogYXJlIG5vbmUsIGFuIChpbml0aWFsbHkpIGVtcHR5IE5vZGVMaXN0IGlzIHJldHVybmVkLgotICAgICAqIDxwPgotICAgICAqIE5vZGVMaXN0cyBhcmUgImxpdmUiOyBhcyBjaGlsZHJlbiBhcmUgYWRkZWQvcmVtb3ZlZCB0aGUgTm9kZUxpc3QKLSAgICAgKiB3aWxsIGltbWVkaWF0ZWx5IHJlZmxlY3QgdGhvc2UgY2hhbmdlcy4gQWxzbywgdGhlIE5vZGVMaXN0IHJlZmVycwotICAgICAqIHRvIHRoZSBhY3R1YWwgbm9kZXMsIHNvIGNoYW5nZXMgdG8gdGhvc2Ugbm9kZXMgbWFkZSB2aWEgdGhlIERPTSB0cmVlCi0gICAgICogd2lsbCBiZSByZWZsZWN0ZWQgaW4gdGhlIE5vZGVMaXN0IGFuZCB2aWNlIHZlcnNhLgotICAgICAqIDxwPgotICAgICAqIEluIHRoaXMgaW1wbGVtZW50YXRpb24sIE5vZGVzIGltcGxlbWVudCB0aGUgTm9kZUxpc3QgaW50ZXJmYWNlIGFuZAotICAgICAqIHByb3ZpZGUgdGhlaXIgb3duIGdldENoaWxkTm9kZXMoKSBzdXBwb3J0LiBPdGhlciBET01zIG1heSBzb2x2ZSB0aGlzCi0gICAgICogZGlmZmVyZW50bHkuCi0gICAgICovCi0gICAgcHVibGljIE5vZGVMaXN0IGdldENoaWxkTm9kZXMoKSB7Ci0gICAgICAgIC8vIEpLRVNTOiBLTk9XTiBJU1NVRSBIRVJFCi0KLSAgICAgICAgaWYgKG5lZWRzU3luY0NoaWxkcmVuKCkpIHsKLSAgICAgICAgICAgIHN5bmNocm9uaXplQ2hpbGRyZW4oKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gdGhpczsKLQotICAgIH0gLy8gZ2V0Q2hpbGROb2RlcygpOk5vZGVMaXN0Ci0KLSAgICAvKiogVGhlIGZpcnN0IGNoaWxkIG9mIHRoaXMgTm9kZSwgb3IgbnVsbCBpZiBub25lLiAqLwotICAgIHB1YmxpYyBOb2RlIGdldEZpcnN0Q2hpbGQoKSB7Ci0KLSAgICAgICAgaWYgKG5lZWRzU3luY0NoaWxkcmVuKCkpIHsKLSAgICAgICAgICAgIHN5bmNocm9uaXplQ2hpbGRyZW4oKTsKLSAgICAgICAgfQotICAgICAgICBtYWtlQ2hpbGROb2RlKCk7Ci0gICAgICAgIHJldHVybiAoTm9kZSkgdmFsdWU7Ci0KLSAgICB9ICAgLy8gZ2V0Rmlyc3RDaGlsZCgpOk5vZGUKLQotICAgIC8qKiBUaGUgbGFzdCBjaGlsZCBvZiB0aGlzIE5vZGUsIG9yIG51bGwgaWYgbm9uZS4gKi8KLSAgICBwdWJsaWMgTm9kZSBnZXRMYXN0Q2hpbGQoKSB7Ci0KLSAgICAgICAgaWYgKG5lZWRzU3luY0NoaWxkcmVuKCkpIHsKLSAgICAgICAgICAgIHN5bmNocm9uaXplQ2hpbGRyZW4oKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbGFzdENoaWxkKCk7Ci0KLSAgICB9IC8vIGdldExhc3RDaGlsZCgpOk5vZGUKLQotICAgIGZpbmFsIENoaWxkTm9kZSBsYXN0Q2hpbGQoKSB7Ci0gICAgICAgIC8vIGxhc3QgY2hpbGQgaXMgc3RvcmVkIGFzIHRoZSBwcmV2aW91cyBzaWJsaW5nIG9mIGZpcnN0IGNoaWxkCi0gICAgICAgIG1ha2VDaGlsZE5vZGUoKTsKLSAgICAgICAgcmV0dXJuIHZhbHVlICE9IG51bGwgPyAoKENoaWxkTm9kZSkgdmFsdWUpLnByZXZpb3VzU2libGluZyA6IG51bGw7Ci0gICAgfQotCi0gICAgZmluYWwgdm9pZCBsYXN0Q2hpbGQoQ2hpbGROb2RlIG5vZGUpIHsKLSAgICAgICAgLy8gc3RvcmUgbGFzdENoaWxkIGFzIHByZXZpb3VzIHNpYmxpbmcgb2YgZmlyc3QgY2hpbGQKLSAgICAgICAgaWYgKHZhbHVlICE9IG51bGwpIHsKLSAgICAgICAgICAgICgoQ2hpbGROb2RlKSB2YWx1ZSkucHJldmlvdXNTaWJsaW5nID0gbm9kZTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIE1vdmUgb25lIG9yIG1vcmUgbm9kZShzKSB0byBvdXIgbGlzdCBvZiBjaGlsZHJlbi4gTm90ZSB0aGF0IHRoaXMKLSAgICAgKiBpbXBsaWNpdGx5IHJlbW92ZXMgdGhlbSBmcm9tIHRoZWlyIHByZXZpb3VzIHBhcmVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuZXdDaGlsZCBUaGUgTm9kZSB0byBiZSBtb3ZlZCB0byBvdXIgc3VidHJlZS4gQXMgYQotICAgICAqIGNvbnZlbmllbmNlIGZlYXR1cmUsIGluc2VydGluZyBhIERvY3VtZW50Tm9kZSB3aWxsIGluc3RlYWQgaW5zZXJ0Ci0gICAgICogYWxsIGl0cyBjaGlsZHJlbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSByZWZDaGlsZCBDdXJyZW50IGNoaWxkIHdoaWNoIG5ld0NoaWxkIHNob3VsZCBiZSBwbGFjZWQKLSAgICAgKiBpbW1lZGlhdGVseSBiZWZvcmUuIElmIHJlZkNoaWxkIGlzIG51bGwsIHRoZSBpbnNlcnRpb24gb2NjdXJzCi0gICAgICogYWZ0ZXIgYWxsIGV4aXN0aW5nIE5vZGVzLCBsaWtlIGFwcGVuZENoaWxkKCkuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIG5ld0NoaWxkLCBpbiBpdHMgbmV3IHN0YXRlIChyZWxvY2F0ZWQsIG9yIGVtcHRpZWQgaW4gdGhlIGNhc2Ugb2YKLSAgICAgKiBEb2N1bWVudE5vZGUuKQotICAgICAqCi0gICAgICogQHRocm93cyBET01FeGNlcHRpb24oSElFUkFSQ0hZX1JFUVVFU1RfRVJSKSBpZiBuZXdDaGlsZCBpcyBvZiBhCi0gICAgICogdHlwZSB0aGF0IHNob3VsZG4ndCBiZSBhIGNoaWxkIG9mIHRoaXMgbm9kZSwgb3IgaWYgbmV3Q2hpbGQgaXMgYW4KLSAgICAgKiBhbmNlc3RvciBvZiB0aGlzIG5vZGUuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbihXUk9OR19ET0NVTUVOVF9FUlIpIGlmIG5ld0NoaWxkIGhhcyBhCi0gICAgICogZGlmZmVyZW50IG93bmVyIGRvY3VtZW50IHRoYW4gd2UgZG8uCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbihOT1RfRk9VTkRfRVJSKSBpZiByZWZDaGlsZCBpcyBub3QgYSBjaGlsZCBvZgotICAgICAqIHRoaXMgbm9kZS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uKE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUikgaWYgdGhpcyBub2RlIGlzCi0gICAgICogcmVhZC1vbmx5LgotICAgICAqLwotICAgIHB1YmxpYyBOb2RlIGluc2VydEJlZm9yZShOb2RlIG5ld0NoaWxkLCBOb2RlIHJlZkNoaWxkKQotICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKLSAgICAgICAgLy8gVGFpbC1jYWxsOyBvcHRpbWl6ZXIgc2hvdWxkIGJlIGFibGUgdG8gZG8gZ29vZCB0aGluZ3Mgd2l0aC4KLSAgICAgICAgcmV0dXJuIGludGVybmFsSW5zZXJ0QmVmb3JlKG5ld0NoaWxkLCByZWZDaGlsZCwgZmFsc2UpOwotICAgIH0gLy8gaW5zZXJ0QmVmb3JlKE5vZGUsTm9kZSk6Tm9kZQotCi0gICAgLyoqIE5PTi1ET00gSU5URVJOQUw6IFdpdGhpbiBET00gYWN0aW9ucyx3ZSBzb21ldGltZXMgbmVlZCB0byBiZSBhYmxlCi0gICAgICogdG8gY29udHJvbCB3aGljaCBtdXRhdGlvbiBldmVudHMgYXJlIHNwYXduZWQuIFRoaXMgdmVyc2lvbiBvZiB0aGUKLSAgICAgKiBpbnNlcnRCZWZvcmUgb3BlcmF0aW9uIGFsbG93cyB1cyB0byBkbyBzby4gSXQgaXMgbm90IGludGVuZGVkCi0gICAgICogZm9yIHVzZSBieSBhcHBsaWNhdGlvbiBwcm9ncmFtcy4KLSAgICAgKi8KLSAgICBOb2RlIGludGVybmFsSW5zZXJ0QmVmb3JlKE5vZGUgbmV3Q2hpbGQsIE5vZGUgcmVmQ2hpbGQsIGJvb2xlYW4gcmVwbGFjZSkKLSAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgQ29yZURvY3VtZW50SW1wbCBvd25lckRvY3VtZW50ID0gb3duZXJEb2N1bWVudCgpOwotICAgICAgICBib29sZWFuIGVycm9yQ2hlY2tpbmcgPSBvd25lckRvY3VtZW50LmVycm9yQ2hlY2tpbmc7Ci0KLSAgICAgICAgaWYgKG5ld0NoaWxkLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5ET0NVTUVOVF9GUkFHTUVOVF9OT0RFKSB7Ci0gICAgICAgICAgICAvLyBTTE9XIEJVVCBTQUZFOiBXZSBjb3VsZCBpbnNlcnQgdGhlIHdob2xlIHN1YnRyZWUgd2l0aG91dAotICAgICAgICAgICAgLy8ganVnZ2xpbmcgc28gbWFueSBuZXh0L3ByZXZpb3VzIHBvaW50ZXJzLiAoV2lwZSBvdXQgdGhlCi0gICAgICAgICAgICAvLyBwYXJlbnQncyBjaGlsZC1saXN0LCBwYXRjaCB0aGUgcGFyZW50IHBvaW50ZXJzLCBzZXQgdGhlCi0gICAgICAgICAgICAvLyBlbmRzIG9mIHRoZSBsaXN0LikgQnV0IHdlIGtub3cgc29tZSBzdWJjbGFzc2VzIGhhdmUgc3BlY2lhbC0KLSAgICAgICAgICAgIC8vIGNhc2UgYmVoYXZpb3IgdGhleSBhZGQgdG8gaW5zZXJ0QmVmb3JlKCksIHNvIHdlIGRvbid0IHJpc2sgaXQuCi0gICAgICAgICAgICAvLyBUaGlzIGFwcHJvY2ggYWxzbyB0YWtlcyBmZXdlciBieXRlY29kZXMuCi0KLSAgICAgICAgICAgIC8vIE5PVEU6IElmIG9uZSBvZiB0aGUgY2hpbGRyZW4gaXMgbm90IGEgbGVnYWwgY2hpbGQgb2YgdGhpcwotICAgICAgICAgICAgLy8gbm9kZSwgdGhyb3cgSElFUkFSQ0hZX1JFUVVFU1RfRVJSIGJlZm9yZSBfYW55XyBvZiB0aGUgY2hpbGRyZW4KLSAgICAgICAgICAgIC8vIGhhdmUgYmVlbiB0cmFuc2ZlcnJlZC4gKEFsdGVybmF0aXZlIGJlaGF2aW9ycyB3b3VsZCBiZSB0bwotICAgICAgICAgICAgLy8gcmVwYXJlbnQgdXAgdG8gdGhlIGZpcnN0IGZhaWx1cmUgcG9pbnQgb3IgcmVwYXJlbnQgYWxsIHRob3NlCi0gICAgICAgICAgICAvLyB3aGljaCBhcmUgYWNjZXB0YWJsZSB0byB0aGUgdGFyZ2V0IG5vZGUsIG5laXRoZXIgb2Ygd2hpY2ggaXMKLSAgICAgICAgICAgIC8vIGFzIHJvYnVzdC4gUFItRE9NLTA4MTggaXNuJ3QgZW50aXJlbHkgY2xlYXIgb24gd2hpY2ggaXQKLSAgICAgICAgICAgIC8vIHJlY29tbWVuZHM/Pz8/PwotCi0gICAgICAgICAgICAvLyBObyBuZWVkIHRvIGNoZWNrIGtpZHMgZm9yIHJpZ2h0LWRvY3VtZW50OyBpZiB0aGV5IHdlcmVuJ3QsCi0gICAgICAgICAgICAvLyB0aGV5IHdvdWxkbid0IGJlIGtpZHMgb2YgdGhhdCBEb2NGcmFnLgotICAgICAgICAgICAgaWYgKGVycm9yQ2hlY2tpbmcpIHsKLSAgICAgICAgICAgICAgICBmb3IgKE5vZGUga2lkID0gbmV3Q2hpbGQuZ2V0Rmlyc3RDaGlsZCgpOyAvLyBQcmVzY2FuCi0gICAgICAgICAgICAgICAgICAgICBraWQgIT0gbnVsbDsga2lkID0ga2lkLmdldE5leHRTaWJsaW5nKCkpIHsKLQotICAgICAgICAgICAgICAgICAgICBpZiAoIW93bmVyRG9jdW1lbnQuaXNLaWRPSyh0aGlzLCBraWQpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbXNnID0gRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwgIkhJRVJBUkNIWV9SRVFVRVNUX0VSUiIsIG51bGwpOwotICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uSElFUkFSQ0hZX1JFUVVFU1RfRVJSLCBtc2cpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICB3aGlsZSAobmV3Q2hpbGQuaGFzQ2hpbGROb2RlcygpKSB7Ci0gICAgICAgICAgICAgICAgaW5zZXJ0QmVmb3JlKG5ld0NoaWxkLmdldEZpcnN0Q2hpbGQoKSwgcmVmQ2hpbGQpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIG5ld0NoaWxkOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKG5ld0NoaWxkID09IHJlZkNoaWxkKSB7Ci0gICAgICAgICAgICAvLyBzdHVwaWQgY2FzZSB0aGF0IG11c3QgYmUgaGFuZGxlZCBhcyBhIG5vLW9wIHRyaWdnZXJpbmcgZXZlbnRzLi4uCi0gICAgICAgICAgICByZWZDaGlsZCA9IHJlZkNoaWxkLmdldE5leHRTaWJsaW5nKCk7Ci0gICAgICAgICAgICByZW1vdmVDaGlsZChuZXdDaGlsZCk7Ci0gICAgICAgICAgICBpbnNlcnRCZWZvcmUobmV3Q2hpbGQsIHJlZkNoaWxkKTsKLSAgICAgICAgICAgIHJldHVybiBuZXdDaGlsZDsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChuZWVkc1N5bmNDaGlsZHJlbigpKSB7Ci0gICAgICAgICAgICBzeW5jaHJvbml6ZUNoaWxkcmVuKCk7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoZXJyb3JDaGVja2luZykgewotICAgICAgICAgICAgaWYgKGlzUmVhZE9ubHkoKSkgewotICAgICAgICAgICAgICAgIFN0cmluZyBtc2cgPSBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIiwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSLCBtc2cpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKG5ld0NoaWxkLmdldE93bmVyRG9jdW1lbnQoKSAhPSBvd25lckRvY3VtZW50KSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIG1zZyA9IERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sICJXUk9OR19ET0NVTUVOVF9FUlIiLCBudWxsKTsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5XUk9OR19ET0NVTUVOVF9FUlIsIG1zZyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoIW93bmVyRG9jdW1lbnQuaXNLaWRPSyh0aGlzLCBuZXdDaGlsZCkpIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgbXNnID0gRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwgIkhJRVJBUkNIWV9SRVFVRVNUX0VSUiIsIG51bGwpOwotICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLkhJRVJBUkNIWV9SRVFVRVNUX0VSUiwgbXNnKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIHJlZkNoaWxkIG11c3QgYmUgYSBjaGlsZCBvZiB0aGlzIG5vZGUgKG9yIG51bGwpCi0gICAgICAgICAgICBpZiAocmVmQ2hpbGQgIT0gbnVsbCAmJiByZWZDaGlsZC5nZXRQYXJlbnROb2RlKCkgIT0gdGhpcykgewotICAgICAgICAgICAgICAgIFN0cmluZyBtc2cgPSBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiTk9UX0ZPVU5EX0VSUiIsIG51bGwpOwotICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9GT1VORF9FUlIsIG1zZyk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIFByZXZlbnQgY3ljbGVzIGluIHRoZSB0cmVlCi0gICAgICAgICAgICAvLyBuZXdDaGlsZCBjYW5ub3QgYmUgYW5jZXN0b3Igb2YgdGhpcyBOb2RlLAotICAgICAgICAgICAgLy8gYW5kIGFjdHVhbGx5IGNhbm5vdCBiZSB0aGlzCi0gICAgICAgICAgICBib29sZWFuIHRyZWVTYWZlID0gdHJ1ZTsKLSAgICAgICAgICAgIGZvciAoTm9kZUltcGwgYSA9IHRoaXM7IHRyZWVTYWZlICYmIGEgIT0gbnVsbDsgYSA9IGEucGFyZW50Tm9kZSgpKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIHRyZWVTYWZlID0gbmV3Q2hpbGQgIT0gYTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmICghdHJlZVNhZmUpIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgbXNnID0gRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwgIkhJRVJBUkNIWV9SRVFVRVNUX0VSUiIsIG51bGwpOwotICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLkhJRVJBUkNIWV9SRVFVRVNUX0VSUiwgbXNnKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIG1ha2VDaGlsZE5vZGUoKTsgLy8gbWFrZSBzdXJlIHdlIGhhdmUgYSBub2RlIGFuZCBub3QgYSBzdHJpbmcKLQotICAgICAgICAvLyBub3RpZnkgZG9jdW1lbnQKLSAgICAgICAgb3duZXJEb2N1bWVudC5pbnNlcnRpbmdOb2RlKHRoaXMsIHJlcGxhY2UpOwotCi0gICAgICAgIC8vIENvbnZlcnQgdG8gaW50ZXJuYWwgdHlwZSwgdG8gYXZvaWQgcmVwZWF0ZWQgY2FzdGluZwotICAgICAgICBDaGlsZE5vZGUgbmV3SW50ZXJuYWwgPSAoQ2hpbGROb2RlKW5ld0NoaWxkOwotCi0gICAgICAgIE5vZGUgb2xkcGFyZW50ID0gbmV3SW50ZXJuYWwucGFyZW50Tm9kZSgpOwotICAgICAgICBpZiAob2xkcGFyZW50ICE9IG51bGwpIHsKLSAgICAgICAgICAgIG9sZHBhcmVudC5yZW1vdmVDaGlsZChuZXdJbnRlcm5hbCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBDb252ZXJ0IHRvIGludGVybmFsIHR5cGUsIHRvIGF2b2lkIHJlcGVhdGVkIGNhc3RpbmcKLSAgICAgICAgQ2hpbGROb2RlIHJlZkludGVybmFsID0gKENoaWxkTm9kZSkgcmVmQ2hpbGQ7Ci0KLSAgICAgICAgLy8gQXR0YWNoIHVwCi0gICAgICAgIG5ld0ludGVybmFsLm93bmVyTm9kZSA9IHRoaXM7Ci0gICAgICAgIG5ld0ludGVybmFsLmlzT3duZWQodHJ1ZSk7Ci0KLSAgICAgICAgLy8gQXR0YWNoIGJlZm9yZSBhbmQgYWZ0ZXIKLSAgICAgICAgLy8gTm90ZTogZmlyc3RDaGlsZC5wcmV2aW91c1NpYmxpbmcgPT0gbGFzdENoaWxkISEKLSAgICAgICAgQ2hpbGROb2RlIGZpcnN0Q2hpbGQgPSAoQ2hpbGROb2RlKSB2YWx1ZTsKLSAgICAgICAgaWYgKGZpcnN0Q2hpbGQgPT0gbnVsbCkgewotICAgICAgICAgICAgLy8gdGhpcyBvdXIgZmlyc3QgYW5kIG9ubHkgY2hpbGQKLSAgICAgICAgICAgIHZhbHVlID0gbmV3SW50ZXJuYWw7IC8vIGZpcnN0Y2hpbGQgPSBuZXdJbnRlcm5hbDsKLSAgICAgICAgICAgIG5ld0ludGVybmFsLmlzRmlyc3RDaGlsZCh0cnVlKTsKLSAgICAgICAgICAgIG5ld0ludGVybmFsLnByZXZpb3VzU2libGluZyA9IG5ld0ludGVybmFsOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgaWYgKHJlZkludGVybmFsID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAvLyB0aGlzIGlzIGFuIGFwcGVuZAotICAgICAgICAgICAgICAgIENoaWxkTm9kZSBsYXN0Q2hpbGQgPSBmaXJzdENoaWxkLnByZXZpb3VzU2libGluZzsKLSAgICAgICAgICAgICAgICBsYXN0Q2hpbGQubmV4dFNpYmxpbmcgPSBuZXdJbnRlcm5hbDsKLSAgICAgICAgICAgICAgICBuZXdJbnRlcm5hbC5wcmV2aW91c1NpYmxpbmcgPSBsYXN0Q2hpbGQ7Ci0gICAgICAgICAgICAgICAgZmlyc3RDaGlsZC5wcmV2aW91c1NpYmxpbmcgPSBuZXdJbnRlcm5hbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIC8vIHRoaXMgaXMgYW4gaW5zZXJ0Ci0gICAgICAgICAgICAgICAgaWYgKHJlZkNoaWxkID09IGZpcnN0Q2hpbGQpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gYXQgdGhlIGhlYWQgb2YgdGhlIGxpc3QKLSAgICAgICAgICAgICAgICAgICAgZmlyc3RDaGlsZC5pc0ZpcnN0Q2hpbGQoZmFsc2UpOwotICAgICAgICAgICAgICAgICAgICBuZXdJbnRlcm5hbC5uZXh0U2libGluZyA9IGZpcnN0Q2hpbGQ7Ci0gICAgICAgICAgICAgICAgICAgIG5ld0ludGVybmFsLnByZXZpb3VzU2libGluZyA9IGZpcnN0Q2hpbGQucHJldmlvdXNTaWJsaW5nOwotICAgICAgICAgICAgICAgICAgICBmaXJzdENoaWxkLnByZXZpb3VzU2libGluZyA9IG5ld0ludGVybmFsOwotICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IG5ld0ludGVybmFsOyAvLyBmaXJzdENoaWxkID0gbmV3SW50ZXJuYWw7Ci0gICAgICAgICAgICAgICAgICAgIG5ld0ludGVybmFsLmlzRmlyc3RDaGlsZCh0cnVlKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIHNvbWV3aGVyZSBpbiB0aGUgbWlkZGxlCi0gICAgICAgICAgICAgICAgICAgIENoaWxkTm9kZSBwcmV2ID0gcmVmSW50ZXJuYWwucHJldmlvdXNTaWJsaW5nOwotICAgICAgICAgICAgICAgICAgICBuZXdJbnRlcm5hbC5uZXh0U2libGluZyA9IHJlZkludGVybmFsOwotICAgICAgICAgICAgICAgICAgICBwcmV2Lm5leHRTaWJsaW5nID0gbmV3SW50ZXJuYWw7Ci0gICAgICAgICAgICAgICAgICAgIHJlZkludGVybmFsLnByZXZpb3VzU2libGluZyA9IG5ld0ludGVybmFsOwotICAgICAgICAgICAgICAgICAgICBuZXdJbnRlcm5hbC5wcmV2aW91c1NpYmxpbmcgPSBwcmV2OwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGNoYW5nZWQoKTsKLQotICAgICAgICAvLyBub3RpZnkgZG9jdW1lbnQKLSAgICAgICAgb3duZXJEb2N1bWVudC5pbnNlcnRlZE5vZGUodGhpcywgbmV3SW50ZXJuYWwsIHJlcGxhY2UpOwotCi0gICAgICAgIGNoZWNrTm9ybWFsaXphdGlvbkFmdGVySW5zZXJ0KG5ld0ludGVybmFsKTsKLQotICAgICAgICByZXR1cm4gbmV3Q2hpbGQ7Ci0KLSAgICB9IC8vIGludGVybmFsSW5zZXJ0QmVmb3JlKE5vZGUsTm9kZSxpbnQpOk5vZGUKLQotICAgIC8qKgotICAgICAqIFJlbW92ZSBhIGNoaWxkIGZyb20gdGhpcyBOb2RlLiBUaGUgcmVtb3ZlZCBjaGlsZCdzIHN1YnRyZWUKLSAgICAgKiByZW1haW5zIGludGFjdCBzbyBpdCBtYXkgYmUgcmUtaW5zZXJ0ZWQgZWxzZXdoZXJlLgotICAgICAqCi0gICAgICogQHJldHVybiBvbGRDaGlsZCwgaW4gaXRzIG5ldyBzdGF0ZSAocmVtb3ZlZCkuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbihOT1RfRk9VTkRfRVJSKSBpZiBvbGRDaGlsZCBpcyBub3QgYSBjaGlsZCBvZgotICAgICAqIHRoaXMgbm9kZS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uKE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUikgaWYgdGhpcyBub2RlIGlzCi0gICAgICogcmVhZC1vbmx5LgotICAgICAqLwotICAgIHB1YmxpYyBOb2RlIHJlbW92ZUNoaWxkKE5vZGUgb2xkQ2hpbGQpCi0gICAgICAgIHRocm93cyBET01FeGNlcHRpb24gewotICAgICAgICAvLyBUYWlsLWNhbGwsIHNob3VsZCBiZSBvcHRpbWl6YWJsZQotICAgICAgICBpZiAoaGFzU3RyaW5nVmFsdWUoKSkgewotICAgICAgICAgICAgLy8gd2UgZG9uJ3QgaGF2ZSBhbnkgY2hpbGQgcGVyIHNheSBzbyBpdCBjYW4ndCBiZSBvbmUgb2YgdGhlbSEKLSAgICAgICAgICAgIFN0cmluZyBtc2cgPSBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiTk9UX0ZPVU5EX0VSUiIsIG51bGwpOwotICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX0ZPVU5EX0VSUiwgbXNnKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gaW50ZXJuYWxSZW1vdmVDaGlsZChvbGRDaGlsZCwgZmFsc2UpOwotICAgIH0gLy8gcmVtb3ZlQ2hpbGQoTm9kZSkgOk5vZGUKLQotICAgIC8qKiBOT04tRE9NIElOVEVSTkFMOiBXaXRoaW4gRE9NIGFjdGlvbnMsd2Ugc29tZXRpbWVzIG5lZWQgdG8gYmUgYWJsZQotICAgICAqIHRvIGNvbnRyb2wgd2hpY2ggbXV0YXRpb24gZXZlbnRzIGFyZSBzcGF3bmVkLiBUaGlzIHZlcnNpb24gb2YgdGhlCi0gICAgICogcmVtb3ZlQ2hpbGQgb3BlcmF0aW9uIGFsbG93cyB1cyB0byBkbyBzby4gSXQgaXMgbm90IGludGVuZGVkCi0gICAgICogZm9yIHVzZSBieSBhcHBsaWNhdGlvbiBwcm9ncmFtcy4KLSAgICAgKi8KLSAgICBOb2RlIGludGVybmFsUmVtb3ZlQ2hpbGQoTm9kZSBvbGRDaGlsZCwgYm9vbGVhbiByZXBsYWNlKQotICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKLQotICAgICAgICBDb3JlRG9jdW1lbnRJbXBsIG93bmVyRG9jdW1lbnQgPSBvd25lckRvY3VtZW50KCk7Ci0gICAgICAgIGlmIChvd25lckRvY3VtZW50LmVycm9yQ2hlY2tpbmcpIHsKLSAgICAgICAgICAgIGlmIChpc1JlYWRPbmx5KCkpIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgbXNnID0gRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwgIk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiIsIG51bGwpOwotICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiwgbXNnKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChvbGRDaGlsZCAhPSBudWxsICYmIG9sZENoaWxkLmdldFBhcmVudE5vZGUoKSAhPSB0aGlzKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIG1zZyA9IERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sICJOT1RfRk9VTkRfRVJSIiwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX0ZPVU5EX0VSUiwgbXNnKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIENoaWxkTm9kZSBvbGRJbnRlcm5hbCA9IChDaGlsZE5vZGUpIG9sZENoaWxkOwotCi0gICAgICAgIC8vIG5vdGlmeSBkb2N1bWVudAotICAgICAgICBvd25lckRvY3VtZW50LnJlbW92aW5nTm9kZSh0aGlzLCBvbGRJbnRlcm5hbCwgcmVwbGFjZSk7Ci0KLSAgICAgICAgLy8gUGF0Y2ggbGlua2VkIGxpc3QgYXJvdW5kIG9sZENoaWxkCi0gICAgICAgIC8vIE5vdGU6IGxhc3RDaGlsZCA9PSBmaXJzdENoaWxkLnByZXZpb3VzU2libGluZwotICAgICAgICBpZiAob2xkSW50ZXJuYWwgPT0gdmFsdWUpIHsgLy8gb2xkSW50ZXJuYWwgPT0gZmlyc3RDaGlsZAotICAgICAgICAgICAgLy8gcmVtb3ZpbmcgZmlyc3QgY2hpbGQKLSAgICAgICAgICAgIG9sZEludGVybmFsLmlzRmlyc3RDaGlsZChmYWxzZSk7Ci0gICAgICAgICAgICAvLyBuZXh0IGxpbmUgaXM6IGZpcnN0Q2hpbGQgPSBvbGRJbnRlcm5hbC5uZXh0U2libGluZwotICAgICAgICAgICAgdmFsdWUgPSBvbGRJbnRlcm5hbC5uZXh0U2libGluZzsKLSAgICAgICAgICAgIENoaWxkTm9kZSBmaXJzdENoaWxkID0gKENoaWxkTm9kZSkgdmFsdWU7Ci0gICAgICAgICAgICBpZiAoZmlyc3RDaGlsZCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZmlyc3RDaGlsZC5pc0ZpcnN0Q2hpbGQodHJ1ZSk7Ci0gICAgICAgICAgICAgICAgZmlyc3RDaGlsZC5wcmV2aW91c1NpYmxpbmcgPSBvbGRJbnRlcm5hbC5wcmV2aW91c1NpYmxpbmc7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBDaGlsZE5vZGUgcHJldiA9IG9sZEludGVybmFsLnByZXZpb3VzU2libGluZzsKLSAgICAgICAgICAgIENoaWxkTm9kZSBuZXh0ID0gb2xkSW50ZXJuYWwubmV4dFNpYmxpbmc7Ci0gICAgICAgICAgICBwcmV2Lm5leHRTaWJsaW5nID0gbmV4dDsKLSAgICAgICAgICAgIGlmIChuZXh0ID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAvLyByZW1vdmluZyBsYXN0IGNoaWxkCi0gICAgICAgICAgICAgICAgQ2hpbGROb2RlIGZpcnN0Q2hpbGQgPSAoQ2hpbGROb2RlKSB2YWx1ZTsKLSAgICAgICAgICAgICAgICBmaXJzdENoaWxkLnByZXZpb3VzU2libGluZyA9IHByZXY7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIC8vIHJlbW92aW5nIHNvbWUgb3RoZXIgY2hpbGQgaW4gdGhlIG1pZGRsZQotICAgICAgICAgICAgICAgIG5leHQucHJldmlvdXNTaWJsaW5nID0gcHJldjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIFNhdmUgcHJldmlvdXMgc2libGluZyBmb3Igbm9ybWFsaXphdGlvbiBjaGVja2luZy4KLSAgICAgICAgQ2hpbGROb2RlIG9sZFByZXZpb3VzU2libGluZyA9IG9sZEludGVybmFsLnByZXZpb3VzU2libGluZygpOwotCi0gICAgICAgIC8vIFJlbW92ZSBvbGRJbnRlcm5hbCdzIHJlZmVyZW5jZXMgdG8gdHJlZQotICAgICAgICBvbGRJbnRlcm5hbC5vd25lck5vZGUgICAgICAgPSBvd25lckRvY3VtZW50OwotICAgICAgICBvbGRJbnRlcm5hbC5pc093bmVkKGZhbHNlKTsKLSAgICAgICAgb2xkSW50ZXJuYWwubmV4dFNpYmxpbmcgICAgID0gbnVsbDsKLSAgICAgICAgb2xkSW50ZXJuYWwucHJldmlvdXNTaWJsaW5nID0gbnVsbDsKLQotICAgICAgICBjaGFuZ2VkKCk7Ci0KLSAgICAgICAgLy8gbm90aWZ5IGRvY3VtZW50Ci0gICAgICAgIG93bmVyRG9jdW1lbnQucmVtb3ZlZE5vZGUodGhpcywgcmVwbGFjZSk7Ci0KLSAgICAgICAgY2hlY2tOb3JtYWxpemF0aW9uQWZ0ZXJSZW1vdmUob2xkUHJldmlvdXNTaWJsaW5nKTsKLQotICAgICAgICByZXR1cm4gb2xkSW50ZXJuYWw7Ci0KLSAgICB9IC8vIGludGVybmFsUmVtb3ZlQ2hpbGQoTm9kZSxpbnQpOk5vZGUKLQotICAgIC8qKgotICAgICAqIE1ha2UgbmV3Q2hpbGQgb2NjdXB5IHRoZSBsb2NhdGlvbiB0aGF0IG9sZENoaWxkIHVzZWQgdG8KLSAgICAgKiBoYXZlLiBOb3RlIHRoYXQgbmV3Q2hpbGQgd2lsbCBmaXJzdCBiZSByZW1vdmVkIGZyb20gaXRzIHByZXZpb3VzCi0gICAgICogcGFyZW50LCBpZiBhbnkuIEVxdWl2YWxlbnQgdG8gaW5zZXJ0aW5nIG5ld0NoaWxkIGJlZm9yZSBvbGRDaGlsZCwKLSAgICAgKiB0aGVuIHJlbW92aW5nIG9sZENoaWxkLgotICAgICAqCi0gICAgICogQHJldHVybiBvbGRDaGlsZCwgaW4gaXRzIG5ldyBzdGF0ZSAocmVtb3ZlZCkuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbihISUVSQVJDSFlfUkVRVUVTVF9FUlIpIGlmIG5ld0NoaWxkIGlzIG9mIGEKLSAgICAgKiB0eXBlIHRoYXQgc2hvdWxkbid0IGJlIGEgY2hpbGQgb2YgdGhpcyBub2RlLCBvciBpZiBuZXdDaGlsZCBpcwotICAgICAqIG9uZSBvZiBvdXIgYW5jZXN0b3JzLgotICAgICAqCi0gICAgICogQHRocm93cyBET01FeGNlcHRpb24oV1JPTkdfRE9DVU1FTlRfRVJSKSBpZiBuZXdDaGlsZCBoYXMgYQotICAgICAqIGRpZmZlcmVudCBvd25lciBkb2N1bWVudCB0aGFuIHdlIGRvLgotICAgICAqCi0gICAgICogQHRocm93cyBET01FeGNlcHRpb24oTk9UX0ZPVU5EX0VSUikgaWYgb2xkQ2hpbGQgaXMgbm90IGEgY2hpbGQgb2YKLSAgICAgKiB0aGlzIG5vZGUuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbihOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIpIGlmIHRoaXMgbm9kZSBpcwotICAgICAqIHJlYWQtb25seS4KLSAgICAgKi8KLSAgICBwdWJsaWMgTm9kZSByZXBsYWNlQ2hpbGQoTm9kZSBuZXdDaGlsZCwgTm9kZSBvbGRDaGlsZCkKLSAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgbWFrZUNoaWxkTm9kZSgpOwotCi0gICAgICAgIC8vIElmIE11dGF0aW9uIEV2ZW50cyBhcmUgYmVpbmcgZ2VuZXJhdGVkLCB0aGlzIG9wZXJhdGlvbiBtaWdodAotICAgICAgICAvLyB0aHJvdyBhZ2dyZWdhdGUgZXZlbnRzIHR3aWNlIHdoZW4gbW9kaWZ5aW5nIGFuIEF0dHIgLS0gb25jZQotICAgICAgICAvLyBvbiBpbnNlcnRpb24gYW5kIG9uY2Ugb24gcmVtb3ZhbC4gRE9NIExldmVsIDIgZG9lcyBub3Qgc3BlY2lmeQotICAgICAgICAvLyB0aGlzIGFzIGVpdGhlciBkZXNpcmFibGUgb3IgdW5kZXNpcmFibGUsIGJ1dCBoaW50cyB0aGF0Ci0gICAgICAgIC8vIGFnZ3JlZ2F0aW9ucyBzaG91bGQgYmUgaXNzdWVkIG9ubHkgb25jZSBwZXIgdXNlciByZXF1ZXN0LgotCi0gICAgICAgIC8vIG5vdGlmeSBkb2N1bWVudAotICAgICAgICBDb3JlRG9jdW1lbnRJbXBsIG93bmVyRG9jdW1lbnQgPSBvd25lckRvY3VtZW50KCk7Ci0gICAgICAgIG93bmVyRG9jdW1lbnQucmVwbGFjaW5nTm9kZSh0aGlzKTsKLQotICAgICAgICBpbnRlcm5hbEluc2VydEJlZm9yZShuZXdDaGlsZCwgb2xkQ2hpbGQsIHRydWUpOwotICAgICAgICBpZiAobmV3Q2hpbGQgIT0gb2xkQ2hpbGQpIHsKLSAgICAgICAgICAgIGludGVybmFsUmVtb3ZlQ2hpbGQob2xkQ2hpbGQsIHRydWUpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gbm90aWZ5IGRvY3VtZW50Ci0gICAgICAgIG93bmVyRG9jdW1lbnQucmVwbGFjZWROb2RlKHRoaXMpOwotCi0gICAgICAgIHJldHVybiBvbGRDaGlsZDsKLSAgICB9Ci0KLSAgICAvLwotICAgIC8vIE5vZGVMaXN0IG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogTm9kZUxpc3QgbWV0aG9kOiBDb3VudCB0aGUgaW1tZWRpYXRlIGNoaWxkcmVuIG9mIHRoaXMgbm9kZQotICAgICAqIEByZXR1cm4gaW50Ci0gICAgICovCi0gICAgcHVibGljIGludCBnZXRMZW5ndGgoKSB7Ci0KLSAgICAgICAgaWYgKGhhc1N0cmluZ1ZhbHVlKCkpIHsKLSAgICAgICAgICAgIHJldHVybiAxOwotICAgICAgICB9Ci0gICAgICAgIENoaWxkTm9kZSBub2RlID0gKENoaWxkTm9kZSkgdmFsdWU7Ci0gICAgICAgIGludCBsZW5ndGggPSAwOwotICAgICAgICBmb3IgKDsgbm9kZSAhPSBudWxsOyBub2RlID0gbm9kZS5uZXh0U2libGluZykgewotICAgICAgICAgICAgbGVuZ3RoKys7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGxlbmd0aDsKLQotICAgIH0gLy8gZ2V0TGVuZ3RoKCk6aW50Ci0KLSAgICAvKioKLSAgICAgKiBOb2RlTGlzdCBtZXRob2Q6IFJldHVybiB0aGUgTnRoIGltbWVkaWF0ZSBjaGlsZCBvZiB0aGlzIG5vZGUsIG9yCi0gICAgICogbnVsbCBpZiB0aGUgaW5kZXggaXMgb3V0IG9mIGJvdW5kcy4KLSAgICAgKiBAcmV0dXJuIG9yZy53M2MuZG9tLk5vZGUKLSAgICAgKiBAcGFyYW0gSW5kZXggaW50Ci0gICAgICovCi0gICAgcHVibGljIE5vZGUgaXRlbShpbnQgaW5kZXgpIHsKLQotICAgICAgICBpZiAoaGFzU3RyaW5nVmFsdWUoKSkgewotICAgICAgICAgICAgaWYgKGluZGV4ICE9IDAgfHwgdmFsdWUgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgbWFrZUNoaWxkTm9kZSgpOwotICAgICAgICAgICAgICAgIHJldHVybiAoTm9kZSkgdmFsdWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGluZGV4IDwgMCkgewotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLSAgICAgICAgQ2hpbGROb2RlIG5vZGUgPSAoQ2hpbGROb2RlKSB2YWx1ZTsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBpbmRleCAmJiBub2RlICE9IG51bGw7IGkrKykgewotICAgICAgICAgICAgbm9kZSA9IG5vZGUubmV4dFNpYmxpbmc7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG5vZGU7Ci0KLSAgICB9IC8vIGl0ZW0oaW50KTpOb2RlCi0KLSAgICAvLwotICAgIC8vIERPTTMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogRE9NIExldmVsIDMgV0QtIEV4cGVyaW1lbnRhbC4KLSAgICAgKiBPdmVycmlkZSBpbmhlcml0ZWQgYmVoYXZpb3IgZnJvbSBQYXJlbnROb2RlIHRvIHN1cHBvcnQgZGVlcCBlcXVhbC4KLSAgICAgKiBpc0VxdWFsTm9kZSBpcyBhbHdheXMgZGVlcCBvbiBBdHRyIG5vZGVzLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzRXF1YWxOb2RlKE5vZGUgYXJnKSB7Ci0gICAgICAgIHJldHVybiBzdXBlci5pc0VxdWFsTm9kZShhcmcpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEludHJvZHVjZWQgaW4gRE9NIExldmVsIDMuIDxwPgotICAgICAqIENoZWNrcyBpZiBhIHR5cGUgaXMgZGVyaXZlZCBmcm9tIGFub3RoZXIgYnkgcmVzdHJpY3Rpb24uIFNlZToKLSAgICAgKiBodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMy1Db3JlL2NvcmUuaHRtbCNUeXBlSW5mby1pc0Rlcml2ZWRGcm9tCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYW5jZXN0b3JOUwotICAgICAqICAgICAgICBUaGUgbmFtc3BhY2Ugb2YgdGhlIGFuY2VzdG9yIHR5cGUgZGVjbGFyYXRpb24KLSAgICAgKiBAcGFyYW0gYW5jZXN0b3JOYW1lCi0gICAgICogICAgICAgIFRoZSBuYW1lIG9mIHRoZSBhbmNlc3RvciB0eXBlIGRlY2xhcmF0aW9uCi0gICAgICogQHBhcmFtIHR5cGUKLSAgICAgKiAgICAgICAgVGhlIHJlZmVyZW5jZSB0eXBlIGRlZmluaXRpb24KLSAgICAgKgotICAgICAqIEByZXR1cm4gYm9vbGVhbiBUcnVlIGlmIHRoZSB0eXBlIGlzIGRlcml2ZWQgYnkgcmVzdHJpY2l0b24gZm9yIHRoZQotICAgICAqICAgICAgICAgcmVmZXJlbmNlIHR5cGUKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0Rlcml2ZWRGcm9tKFN0cmluZyB0eXBlTmFtZXNwYWNlQXJnLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHR5cGVOYW1lQXJnLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGRlcml2YXRpb25NZXRob2QpIHsKLQotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0KLSAgICAvLwotICAgIC8vIFB1YmxpYyBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIE92ZXJyaWRlIGRlZmF1bHQgYmVoYXZpb3Igc28gdGhhdCBpZiBkZWVwIGlzIHRydWUsIGNoaWxkcmVuIGFyZSBhbHNvCi0gICAgICogdG9nZ2xlZC4KLSAgICAgKiBAc2VlIE5vZGUKLSAgICAgKiA8UD4KLSAgICAgKiBOb3RlOiB0aGlzIHdpbGwgbm90IGNoYW5nZSB0aGUgc3RhdGUgb2YgYW4gRW50aXR5UmVmZXJlbmNlIG9yIGl0cwotICAgICAqIGNoaWxkcmVuLCB3aGljaCBhcmUgYWx3YXlzIHJlYWQtb25seS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRSZWFkT25seShib29sZWFuIHJlYWRPbmx5LCBib29sZWFuIGRlZXApIHsKLQotICAgICAgICBzdXBlci5zZXRSZWFkT25seShyZWFkT25seSwgZGVlcCk7Ci0KLSAgICAgICAgaWYgKGRlZXApIHsKLQotICAgICAgICAgICAgaWYgKG5lZWRzU3luY0NoaWxkcmVuKCkpIHsKLSAgICAgICAgICAgICAgICBzeW5jaHJvbml6ZUNoaWxkcmVuKCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmIChoYXNTdHJpbmdWYWx1ZSgpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gUmVjdXJzaXZlbHkgc2V0IGtpZHMKLSAgICAgICAgICAgIGZvciAoQ2hpbGROb2RlIG15a2lkID0gKENoaWxkTm9kZSkgdmFsdWU7Ci0gICAgICAgICAgICAgICAgIG15a2lkICE9IG51bGw7Ci0gICAgICAgICAgICAgICAgIG15a2lkID0gbXlraWQubmV4dFNpYmxpbmcpIHsKLSAgICAgICAgICAgICAgICBpZiAobXlraWQuZ2V0Tm9kZVR5cGUoKSAhPSBOb2RlLkVOVElUWV9SRUZFUkVOQ0VfTk9ERSkgewotICAgICAgICAgICAgICAgICAgICBteWtpZC5zZXRSZWFkT25seShyZWFkT25seSx0cnVlKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9IC8vIHNldFJlYWRPbmx5KGJvb2xlYW4sYm9vbGVhbikKLQotICAgIC8vCi0gICAgLy8gUHJvdGVjdGVkIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogT3ZlcnJpZGUgdGhpcyBtZXRob2QgaW4gc3ViY2xhc3MgdG8gaG9vayBpbiBlZmZpY2llbnQKLSAgICAgKiBpbnRlcm5hbCBkYXRhIHN0cnVjdHVyZS4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCBzeW5jaHJvbml6ZUNoaWxkcmVuKCkgewotICAgICAgICAvLyBCeSBkZWZhdWx0IGp1c3QgY2hhbmdlIHRoZSBmbGFnIHRvIGF2b2lkIGNhbGxpbmcgdGhpcyBtZXRob2QgYWdhaW4KLSAgICAgICAgbmVlZHNTeW5jQ2hpbGRyZW4oZmFsc2UpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENoZWNrcyB0aGUgbm9ybWFsaXplZCBzdGF0ZSBvZiB0aGlzIG5vZGUgYWZ0ZXIgaW5zZXJ0aW5nIGEgY2hpbGQuCi0gICAgICogSWYgdGhlIGluc2VydGVkIGNoaWxkIGNhdXNlcyB0aGlzIG5vZGUgdG8gYmUgdW5ub3JtYWxpemVkLCB0aGVuIHRoaXMKLSAgICAgKiBub2RlIGlzIGZsYWdnZWQgYWNjb3JkaW5nbHkuCi0gICAgICogVGhlIGNvbmRpdGlvbnMgZm9yIGNoYW5naW5nIHRoZSBub3JtYWxpemVkIHN0YXRlIGFyZToKLSAgICAgKiA8dWw+Ci0gICAgICogPGxpPlRoZSBpbnNlcnRlZCBjaGlsZCBpcyBhIHRleHQgbm9kZSBhbmQgb25lIG9mIGl0cyBhZGphY2VudCBzaWJsaW5ncwotICAgICAqIGlzIGFsc28gYSB0ZXh0IG5vZGUuCi0gICAgICogPGxpPlRoZSBpbnNlcnRlZCBjaGlsZCBpcyBpcyBpdHNlbGYgdW5ub3JtYWxpemVkLgotICAgICAqIDwvdWw+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gaW5zZXJ0ZWRDaGlsZCB0aGUgY2hpbGQgbm9kZSB0aGF0IHdhcyBpbnNlcnRlZCBpbnRvIHRoaXMgbm9kZQotICAgICAqCi0gICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgaW5zZXJ0ZWQgY2hpbGQgaXMgPGNvZGU+bnVsbDwvY29kZT4KLSAgICAgKi8KLSAgICB2b2lkIGNoZWNrTm9ybWFsaXphdGlvbkFmdGVySW5zZXJ0KENoaWxkTm9kZSBpbnNlcnRlZENoaWxkKSB7Ci0gICAgICAgIC8vIFNlZSBpZiBpbnNlcnRpb24gY2F1c2VkIHRoaXMgbm9kZSB0byBiZSB1bm5vcm1hbGl6ZWQuCi0gICAgICAgIGlmIChpbnNlcnRlZENoaWxkLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5URVhUX05PREUpIHsKLSAgICAgICAgICAgIENoaWxkTm9kZSBwcmV2ID0gaW5zZXJ0ZWRDaGlsZC5wcmV2aW91c1NpYmxpbmcoKTsKLSAgICAgICAgICAgIENoaWxkTm9kZSBuZXh0ID0gaW5zZXJ0ZWRDaGlsZC5uZXh0U2libGluZzsKLSAgICAgICAgICAgIC8vIElmIGFuIGFkamFjZW50IHNpYmxpbmcgb2YgdGhlIG5ldyBjaGlsZCBpcyBhIHRleHQgbm9kZSwKLSAgICAgICAgICAgIC8vIGZsYWcgdGhpcyBub2RlIGFzIHVubm9ybWFsaXplZC4KLSAgICAgICAgICAgIGlmICgocHJldiAhPSBudWxsICYmIHByZXYuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLlRFWFRfTk9ERSkgfHwKLSAgICAgICAgICAgICAgICAobmV4dCAhPSBudWxsICYmIG5leHQuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLlRFWFRfTk9ERSkpIHsKLSAgICAgICAgICAgICAgICBpc05vcm1hbGl6ZWQoZmFsc2UpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgLy8gSWYgdGhlIG5ldyBjaGlsZCBpcyBub3Qgbm9ybWFsaXplZCwKLSAgICAgICAgICAgIC8vIHRoZW4gdGhpcyBub2RlIGlzIGluaGVyZW50bHkgbm90IG5vcm1hbGl6ZWQuCi0gICAgICAgICAgICBpZiAoIWluc2VydGVkQ2hpbGQuaXNOb3JtYWxpemVkKCkpIHsKLSAgICAgICAgICAgICAgICBpc05vcm1hbGl6ZWQoZmFsc2UpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfSAvLyBjaGVja05vcm1hbGl6YXRpb25BZnRlckluc2VydChDaGlsZE5vZGUpCi0KLSAgICAvKioKLSAgICAgKiBDaGVja3MgdGhlIG5vcm1hbGl6ZWQgb2YgdGhpcyBub2RlIGFmdGVyIHJlbW92aW5nIGEgY2hpbGQuCi0gICAgICogSWYgdGhlIHJlbW92ZWQgY2hpbGQgY2F1c2VzIHRoaXMgbm9kZSB0byBiZSB1bm5vcm1hbGl6ZWQsIHRoZW4gdGhpcwotICAgICAqIG5vZGUgaXMgZmxhZ2dlZCBhY2NvcmRpbmdseS4KLSAgICAgKiBUaGUgY29uZGl0aW9ucyBmb3IgY2hhbmdpbmcgdGhlIG5vcm1hbGl6ZWQgc3RhdGUgYXJlOgotICAgICAqIDx1bD4KLSAgICAgKiA8bGk+VGhlIHJlbW92ZWQgY2hpbGQgaGFkIHR3byBhZGphY2VudCBzaWJsaW5ncyB0aGF0IHdlcmUgdGV4dCBub2Rlcy4KLSAgICAgKiA8L3VsPgotICAgICAqCi0gICAgICogQHBhcmFtIHByZXZpb3VzU2libGluZyB0aGUgcHJldmlvdXMgc2libGluZyBvZiB0aGUgcmVtb3ZlZCBjaGlsZCwgb3IKLSAgICAgKiA8Y29kZT5udWxsPC9jb2RlPgotICAgICAqLwotICAgIHZvaWQgY2hlY2tOb3JtYWxpemF0aW9uQWZ0ZXJSZW1vdmUoQ2hpbGROb2RlIHByZXZpb3VzU2libGluZykgewotICAgICAgICAvLyBTZWUgaWYgcmVtb3ZhbCBjYXVzZWQgdGhpcyBub2RlIHRvIGJlIHVubm9ybWFsaXplZC4KLSAgICAgICAgLy8gSWYgdGhlIGFkamFjZW50IHNpYmxpbmdzIG9mIHRoZSByZW1vdmVkIGNoaWxkIHdlcmUgYm90aCB0ZXh0IG5vZGVzLAotICAgICAgICAvLyBmbGFnIHRoaXMgbm9kZSBhcyB1bm5vcm1hbGl6ZWQuCi0gICAgICAgIGlmIChwcmV2aW91c1NpYmxpbmcgIT0gbnVsbCAmJgotICAgICAgICAgICAgcHJldmlvdXNTaWJsaW5nLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5URVhUX05PREUpIHsKLQotICAgICAgICAgICAgQ2hpbGROb2RlIG5leHQgPSBwcmV2aW91c1NpYmxpbmcubmV4dFNpYmxpbmc7Ci0gICAgICAgICAgICBpZiAobmV4dCAhPSBudWxsICYmIG5leHQuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLlRFWFRfTk9ERSkgewotICAgICAgICAgICAgICAgIGlzTm9ybWFsaXplZChmYWxzZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9IC8vIGNoZWNrTm9ybWFsaXphdGlvbkFmdGVyUmVtb3ZlKENoaWxkTm9kZSkKLQotICAgIC8vCi0gICAgLy8gU2VyaWFsaXphdGlvbiBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKiBTZXJpYWxpemUgb2JqZWN0LiAqLwotICAgIHByaXZhdGUgdm9pZCB3cml0ZU9iamVjdChPYmplY3RPdXRwdXRTdHJlYW0gb3V0KSB0aHJvd3MgSU9FeGNlcHRpb24gewotCi0gICAgICAgIC8vIHN5bmNocm9uaXplIGNoaWxyZW4KLSAgICAgICAgaWYgKG5lZWRzU3luY0NoaWxkcmVuKCkpIHsKLSAgICAgICAgICAgIHN5bmNocm9uaXplQ2hpbGRyZW4oKTsKLSAgICAgICAgfQotICAgICAgICAvLyB3cml0ZSBvYmplY3QKLSAgICAgICAgb3V0LmRlZmF1bHRXcml0ZU9iamVjdCgpOwotCi0gICAgfSAvLyB3cml0ZU9iamVjdChPYmplY3RPdXRwdXRTdHJlYW0pCi0KLSAgICAvKiogRGVzZXJpYWxpemUgb2JqZWN0LiAqLwotICAgIHByaXZhdGUgdm9pZCByZWFkT2JqZWN0KE9iamVjdElucHV0U3RyZWFtIG9pcykKLSAgICAgICAgdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKLQotICAgICAgICAvLyBwZXJmb3JtIGRlZmF1bHQgZGVzZXJhbGl6YXRpb24KLSAgICAgICAgb2lzLmRlZmF1bHRSZWFkT2JqZWN0KCk7Ci0KLSAgICAgICAgLy8gaGFyZHNldCBzeW5jaGlsZHJlbiAtIHNvIHdlIGRvbid0IHRyeSB0byBzeW5jIC0KLSAgICAgICAgLy8gaXQgZG9lcyBub3QgbWFrZSBhbnkgc2Vuc2UgdG8gdHJ5IHRvIHN5bmNoaWxkcmVuIHdoZW4gd2UganVzdAotICAgICAgICAvLyBkZXNlcmlhbGl6ZSBvYmplY3QuCi0gICAgICAgIG5lZWRzU3luY0NoaWxkcmVuKGZhbHNlKTsKLQotICAgIH0gLy8gcmVhZE9iamVjdChPYmplY3RJbnB1dFN0cmVhbSkKLQotCi19IC8vIGNsYXNzIEF0dHJJbXBsCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vQXR0ck5TSW1wbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL0F0dHJOU0ltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggN2RlZmM1NS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vQXR0ck5TSW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzUyICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5kb207Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYueHMuWFNTaW1wbGVUeXBlRGVjbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5OYW1lc3BhY2VDb250ZXh0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNTaW1wbGVUeXBlRGVmaW5pdGlvbjsKLWltcG9ydCBvcmcudzNjLmRvbS5ET01FeGNlcHRpb247Ci0KLS8qKgotICogQXR0ck5TSW1wbCBpbmhlcml0cyBmcm9tIEF0dHJJbXBsIGFuZCBhZGRzIG5hbWVzcGFjZSBzdXBwb3J0LgotICogPFA+Ci0gKiBUaGUgcXVhbGlmaWVkIG5hbWUgaXMgdGhlIG5vZGUgbmFtZSwgYW5kIHdlIHN0b3JlIGxvY2FsTmFtZSB3aGljaCBpcyBhbHNvCi0gKiB1c2VkIGluIGFsbCBxdWVyaWVzLiBPbiB0aGUgb3RoZXIgaGFuZCB3ZSByZWNvbXB1dGUgdGhlIHByZWZpeCB3aGVuCi0gKiBuZWNlc3NhcnkuCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgQXJuYXVkICBMZSBIb3JzLCBJQk0KLSAqIEBhdXRob3IgQW5keSBDbGFyaywgSUJNCi0gKiBAYXV0aG9yIFJhbGYgUGZlaWZmZXIsIElCTQotICogQHZlcnNpb24gJElkOiBBdHRyTlNJbXBsLmphdmEsdiAxLjcgMjAxMC0xMS0wMSAwNDozOTozNyBqb2VodyBFeHAgJAotICovCi1wdWJsaWMgY2xhc3MgQXR0ck5TSW1wbAotICAgIGV4dGVuZHMgQXR0ckltcGwgewotCi0gICAgLy8KLSAgICAvLyBDb25zdGFudHMKLSAgICAvLwotCi0gICAgLyoqIFNlcmlhbGl6YXRpb24gdmVyc2lvbi4gKi8KLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTc4MTkwNjYxNTM2OTc5NTQxNEw7Ci0KLSAgICBzdGF0aWMgZmluYWwgU3RyaW5nIHhtbG5zVVJJID0gImh0dHA6Ly93d3cudzMub3JnLzIwMDAveG1sbnMvIjsKLSAgICBzdGF0aWMgZmluYWwgU3RyaW5nIHhtbFVSSSA9ICJodHRwOi8vd3d3LnczLm9yZy9YTUwvMTk5OC9uYW1lc3BhY2UiOwotCi0gICAgLy8KLSAgICAvLyBEYXRhCi0gICAgLy8KLQotICAgIC8qKiBET00yOiBOYW1lc3BhY2UgVVJJLiAqLwotICAgIHByb3RlY3RlZCBTdHJpbmcgbmFtZXNwYWNlVVJJOwotCi0gICAgLyoqIERPTTI6IGxvY2FsTmFtZS4gKi8KLSAgICBwcm90ZWN0ZWQgU3RyaW5nIGxvY2FsTmFtZTsKLQotICAgIC8qCi0gICAgICogRGVmYXVsdCBjb25zdHJ1Y3RvcgotICAgICAqLwotICAgIHB1YmxpYyBBdHRyTlNJbXBsKCl7fQotCi0gICAvKioKLSAgICAgKiBET00yOiBDb25zdHJ1Y3RvciBmb3IgTmFtZXNwYWNlIGltcGxlbWVudGF0aW9uLgotICAgICAqLwotICAgIHByb3RlY3RlZCBBdHRyTlNJbXBsKENvcmVEb2N1bWVudEltcGwgb3duZXJEb2N1bWVudCwKLSAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbmFtZXNwYWNlVVJJLAotICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBxdWFsaWZpZWROYW1lKSB7Ci0KLSAgICAgICAgc3VwZXIob3duZXJEb2N1bWVudCwgcXVhbGlmaWVkTmFtZSk7Ci0gICAgICAgIHNldE5hbWUobmFtZXNwYWNlVVJJLCBxdWFsaWZpZWROYW1lKTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgc2V0TmFtZShTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgcW5hbWUpewotICAgICAgICBDb3JlRG9jdW1lbnRJbXBsIG93bmVyRG9jdW1lbnQgPSBvd25lckRvY3VtZW50KCk7Ci0gICAgICAgIFN0cmluZyBwcmVmaXg7Ci0gICAgICAgIC8vIERPTSBMZXZlbCAzOiBuYW1lc3BhY2UgVVJJIGlzIG5ldmVyIGVtcHR5IHN0cmluZy4KLSAgICAgICAgdGhpcy5uYW1lc3BhY2VVUkkgPSBuYW1lc3BhY2VVUkk7Ci0gICAgICAgIGlmIChuYW1lc3BhY2VVUkkgIT1udWxsKSB7Ci0gICAgICAgICAgICB0aGlzLm5hbWVzcGFjZVVSSSA9IChuYW1lc3BhY2VVUkkubGVuZ3RoKCkgPT0gMCk/IG51bGwKLSAgICAgICAgICAgICAgICAgICAgOiBuYW1lc3BhY2VVUkk7Ci0KLSAgICAgICAgfQotICAgICAgICBpbnQgY29sb24xID0gcW5hbWUuaW5kZXhPZignOicpOwotICAgICAgICBpbnQgY29sb24yID0gcW5hbWUubGFzdEluZGV4T2YoJzonKTsKLSAgICAgICAgb3duZXJEb2N1bWVudC5jaGVja05hbWVzcGFjZVdGKHFuYW1lLCBjb2xvbjEsIGNvbG9uMik7Ci0gICAgICAgIGlmIChjb2xvbjEgPCAwKSB7Ci0gICAgICAgICAgICAvLyB0aGVyZSBpcyBubyBwcmVmaXgKLSAgICAgICAgICAgIGxvY2FsTmFtZSA9IHFuYW1lOwotICAgICAgICAgICAgaWYgKG93bmVyRG9jdW1lbnQuZXJyb3JDaGVja2luZykgewotICAgICAgICAgICAgICAgIG93bmVyRG9jdW1lbnQuY2hlY2tRTmFtZShudWxsLCBsb2NhbE5hbWUpOwotCi0gICAgICAgICAgICAgICAgaWYgKHFuYW1lLmVxdWFscygieG1sbnMiKSAmJiAobmFtZXNwYWNlVVJJID09IG51bGwKLSAgICAgICAgICAgICAgICAgICAgfHwgIW5hbWVzcGFjZVVSSS5lcXVhbHMoTmFtZXNwYWNlQ29udGV4dC5YTUxOU19VUkkpKQotICAgICAgICAgICAgICAgICAgICB8fCAobmFtZXNwYWNlVVJJIT1udWxsICYmIG5hbWVzcGFjZVVSSS5lcXVhbHMoTmFtZXNwYWNlQ29udGV4dC5YTUxOU19VUkkpCi0gICAgICAgICAgICAgICAgICAgICYmICFxbmFtZS5lcXVhbHMoInhtbG5zIikpKSB7Ci0gICAgICAgICAgICAgICAgICAgIFN0cmluZyBtc2cgPQotICAgICAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOQU1FU1BBQ0VfRVJSIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5BTUVTUEFDRV9FUlIsIG1zZyk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgcHJlZml4ID0gcW5hbWUuc3Vic3RyaW5nKDAsIGNvbG9uMSk7Ci0gICAgICAgICAgICBsb2NhbE5hbWUgPSBxbmFtZS5zdWJzdHJpbmcoY29sb24yKzEpOwotICAgICAgICAgICAgb3duZXJEb2N1bWVudC5jaGVja1FOYW1lKHByZWZpeCwgbG9jYWxOYW1lKTsKLSAgICAgICAgICAgIG93bmVyRG9jdW1lbnQuY2hlY2tET01OU0VycihwcmVmaXgsIG5hbWVzcGFjZVVSSSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvLyB3aGVuIGxvY2FsIG5hbWUgaXMga25vd24KLSAgICBwdWJsaWMgQXR0ck5TSW1wbChDb3JlRG9jdW1lbnRJbXBsIG93bmVyRG9jdW1lbnQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSwKLSAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcXVhbGlmaWVkTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbG9jYWxOYW1lKSB7Ci0gICAgICAgIHN1cGVyKG93bmVyRG9jdW1lbnQsIHF1YWxpZmllZE5hbWUpOwotCi0gICAgICAgIHRoaXMubG9jYWxOYW1lID0gbG9jYWxOYW1lOwotICAgICAgICB0aGlzLm5hbWVzcGFjZVVSSSA9IG5hbWVzcGFjZVVSSTsKLSAgICB9Ci0KLSAgICAvLyBmb3IgRGVmZXJyZWRBdHRySW1wbAotICAgIHByb3RlY3RlZCBBdHRyTlNJbXBsKENvcmVEb2N1bWVudEltcGwgb3duZXJEb2N1bWVudCwKLSAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdmFsdWUpIHsKLSAgICAgICAgc3VwZXIob3duZXJEb2N1bWVudCwgdmFsdWUpOwotICAgIH0KLQotICAgIC8vIFN1cHBvcnQgZm9yIERPTSBMZXZlbCAzIHJlbmFtZU5vZGUgbWV0aG9kLgotICAgIC8vIE5vdGU6IFRoaXMgb25seSBkZWFscyB3aXRoIHBhcnQgb2YgdGhlIHBiLiBJdCBpcyBleHBlY3RlZCB0byBiZQotICAgIC8vIGNhbGxlZCBhZnRlciB0aGUgQXR0ciBoYXMgYmVlbiBkZXRhY2hlZCBmb3Igb25lIHRoaW5nLgotICAgIC8vIENvcmVEb2N1bWVudEltcGwgZG9lcyBhbGwgdGhlIHdvcmsuCi0gICAgdm9pZCByZW5hbWUoU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIHF1YWxpZmllZE5hbWUpIHsKLSAgICAgICAgaWYgKG5lZWRzU3luY0RhdGEoKSkgewotICAgICAgICAgICAgc3luY2hyb25pemVEYXRhKCk7Ci0gICAgICAgIH0KLSAgICAgICAgICAgICAgICB0aGlzLm5hbWUgPSBxdWFsaWZpZWROYW1lOwotICAgICAgICBzZXROYW1lKG5hbWVzcGFjZVVSSSwgcXVhbGlmaWVkTmFtZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogTk9OLURPTTogcmVzZXRzIHRoaXMgbm9kZSBhbmQgc2V0cyBzcGVjaWZpZWQgdmFsdWVzIGZvciB0aGUgbm9kZQotICAgICAqCi0gICAgICogQHBhcmFtIG93bmVyRG9jdW1lbnQKLSAgICAgKiBAcGFyYW0gbmFtZXNwYWNlVVJJCi0gICAgICogQHBhcmFtIHF1YWxpZmllZE5hbWUKLSAgICAgKiBAcGFyYW0gbG9jYWxOYW1lCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0VmFsdWVzIChDb3JlRG9jdW1lbnRJbXBsIG93bmVyRG9jdW1lbnQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSwKLSAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcXVhbGlmaWVkTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbG9jYWxOYW1lKXsKLQotICAgICAgICBzdXBlci50ZXh0Tm9kZSA9IG51bGw7Ci0gICAgICAgIHN1cGVyLmZsYWdzID0gMDsKLSAgICAgICAgaXNTcGVjaWZpZWQodHJ1ZSk7Ci0gICAgICAgIGhhc1N0cmluZ1ZhbHVlKHRydWUpOwotICAgICAgICBzdXBlci5zZXRPd25lckRvY3VtZW50KG93bmVyRG9jdW1lbnQpOwotICAgICAgICB0aGlzLmxvY2FsTmFtZSA9IGxvY2FsTmFtZTsKLSAgICAgICAgdGhpcy5uYW1lc3BhY2VVUkkgPSBuYW1lc3BhY2VVUkk7Ci0gICAgICAgIHN1cGVyLm5hbWUgPSBxdWFsaWZpZWROYW1lOwotICAgICAgICBzdXBlci52YWx1ZSA9IG51bGw7Ci0gICAgfQotCi0gICAgLy8KLSAgICAvLyBET00yOiBOYW1lc3BhY2UgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBJbnRyb2R1Y2VkIGluIERPTSBMZXZlbCAyLiA8cD4KLSAgICAgKgotICAgICAqIFRoZSBuYW1lc3BhY2UgVVJJIG9mIHRoaXMgbm9kZSwgb3IgbnVsbCBpZiBpdCBpcyB1bnNwZWNpZmllZC48cD4KLSAgICAgKgotICAgICAqIFRoaXMgaXMgbm90IGEgY29tcHV0ZWQgdmFsdWUgdGhhdCBpcyB0aGUgcmVzdWx0IG9mIGEgbmFtZXNwYWNlIGxvb2t1cAotICAgICAqIGJhc2VkIG9uIGFuIGV4YW1pbmF0aW9uIG9mIHRoZSBuYW1lc3BhY2UgZGVjbGFyYXRpb25zIGluIHNjb3BlLiBJdCBpcwotICAgICAqIG1lcmVseSB0aGUgbmFtZXNwYWNlIFVSSSBnaXZlbiBhdCBjcmVhdGlvbiB0aW1lLjxwPgotICAgICAqCi0gICAgICogRm9yIG5vZGVzIGNyZWF0ZWQgd2l0aCBhIERPTSBMZXZlbCAxIG1ldGhvZCwgc3VjaCBhcyBjcmVhdGVFbGVtZW50Ci0gICAgICogZnJvbSB0aGUgRG9jdW1lbnQgaW50ZXJmYWNlLCB0aGlzIGlzIG51bGwuCi0gICAgICogQHNpbmNlIFdELURPTS1MZXZlbC0yLTE5OTkwOTIzCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXROYW1lc3BhY2VVUkkoKQotICAgIHsKLSAgICAgICAgaWYgKG5lZWRzU3luY0RhdGEoKSkgewotICAgICAgICAgICAgc3luY2hyb25pemVEYXRhKCk7Ci0gICAgICAgIH0KLSAgICAgICAgLy8gUkVWSVNUOiBUaGlzIGNvZGUgY291bGQvc2hvdWxkIGJlIGRvbmUgYXQgYSBsb3dlci1sZXZlbCwgc3VjaCB0aGF0Ci0gICAgICAgIC8vIHRoZSBuYW1lc3BhY2VVUkkgaXMgc2V0IHByb3Blcmx5IHVwb24gY3JlYXRpb24uIEhvd2V2ZXIsIHRoZXJlIHN0aWxsCi0gICAgICAgIC8vIHNlZW1zIHRvIGJlIHNvbWUgRE9NIHNwZWMgaW50ZXJwcmV0YXRpb24gZ3JleS1hcmVhLgotICAgICAgICByZXR1cm4gbmFtZXNwYWNlVVJJOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEludHJvZHVjZWQgaW4gRE9NIExldmVsIDIuIDxwPgotICAgICAqCi0gICAgICogVGhlIG5hbWVzcGFjZSBwcmVmaXggb2YgdGhpcyBub2RlLCBvciBudWxsIGlmIGl0IGlzIHVuc3BlY2lmaWVkLiA8cD4KLSAgICAgKgotICAgICAqIEZvciBub2RlcyBjcmVhdGVkIHdpdGggYSBET00gTGV2ZWwgMSBtZXRob2QsIHN1Y2ggYXMgY3JlYXRlRWxlbWVudAotICAgICAqIGZyb20gdGhlIERvY3VtZW50IGludGVyZmFjZSwgdGhpcyBpcyBudWxsLiA8cD4KLSAgICAgKgotICAgICAqIEBzaW5jZSBXRC1ET00tTGV2ZWwtMi0xOTk5MDkyMwotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0UHJlZml4KCkKLSAgICB7Ci0gICAgICAgIGlmIChuZWVkc1N5bmNEYXRhKCkpIHsKLSAgICAgICAgICAgIHN5bmNocm9uaXplRGF0YSgpOwotICAgICAgICB9Ci0gICAgICAgIGludCBpbmRleCA9IG5hbWUuaW5kZXhPZignOicpOwotICAgICAgICByZXR1cm4gaW5kZXggPCAwID8gbnVsbCA6IG5hbWUuc3Vic3RyaW5nKDAsIGluZGV4KTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJbnRyb2R1Y2VkIGluIERPTSBMZXZlbCAyLiA8cD4KLSAgICAgKgotICAgICAqIE5vdGUgdGhhdCBzZXR0aW5nIHRoaXMgYXR0cmlidXRlIGNoYW5nZXMgdGhlIG5vZGVOYW1lIGF0dHJpYnV0ZSwgd2hpY2gKLSAgICAgKiBob2xkcyB0aGUgcXVhbGlmaWVkIG5hbWUsIGFzIHdlbGwgYXMgdGhlIHRhZ05hbWUgYW5kIG5hbWUgYXR0cmlidXRlcyBvZgotICAgICAqIHRoZSBFbGVtZW50IGFuZCBBdHRyIGludGVyZmFjZXMsIHdoZW4gYXBwbGljYWJsZS48cD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBwcmVmaXggVGhlIG5hbWVzcGFjZSBwcmVmaXggb2YgdGhpcyBub2RlLCBvciBudWxsKGVtcHR5IHN0cmluZykgaWYgaXQgaXMgdW5zcGVjaWZpZWQuCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIElOVkFMSURfQ0hBUkFDVEVSX0VSUgotICAgICAqICAgICAgICAgICAgICAgICAgIFJhaXNlZCBpZiB0aGUgc3BlY2lmaWVkCi0gICAgICogICAgICAgICAgICAgICAgICAgcHJlZml4IGNvbnRhaW5zIGFuIGludmFsaWQgY2hhcmFjdGVyLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogQHNpbmNlIFdELURPTS1MZXZlbC0yLTE5OTkwOTIzCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0UHJlZml4KFN0cmluZyBwcmVmaXgpCi0gICAgICAgIHRocm93cyBET01FeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGlmIChuZWVkc1N5bmNEYXRhKCkpIHsKLSAgICAgICAgICAgIHN5bmNocm9uaXplRGF0YSgpOwotICAgICAgICB9Ci0gICAgICAgIGlmIChvd25lckRvY3VtZW50KCkuZXJyb3JDaGVja2luZykgewotICAgICAgICAgICAgaWYgKGlzUmVhZE9ubHkoKSkgewotICAgICAgICAgICAgICAgIFN0cmluZyBtc2cgPSBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIiwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSLCBtc2cpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKHByZWZpeCAhPSBudWxsICYmIHByZWZpeC5sZW5ndGgoKSAhPSAwKSB7Ci0KLSAgICAgICAgICAgICAgICBpZiAoIUNvcmVEb2N1bWVudEltcGwuaXNYTUxOYW1lKHByZWZpeCxvd25lckRvY3VtZW50KCkuaXNYTUwxMVZlcnNpb24oKSkpIHsKLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG1zZyA9IERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sICJJTlZBTElEX0NIQVJBQ1RFUl9FUlIiLCBudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uSU5WQUxJRF9DSEFSQUNURVJfRVJSLCBtc2cpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpZiAobmFtZXNwYWNlVVJJID09IG51bGwgfHwgcHJlZml4LmluZGV4T2YoJzonKSA+PTApIHsKLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG1zZyA9IERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sICJOQU1FU1BBQ0VfRVJSIiwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5BTUVTUEFDRV9FUlIsIG1zZyk7Ci0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICBpZiAocHJlZml4LmVxdWFscygieG1sbnMiKSkgewotICAgICAgICAgICAgICAgICAgICBpZiAoIW5hbWVzcGFjZVVSSS5lcXVhbHMoeG1sbnNVUkkpKXsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBtc2cgPSBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiTkFNRVNQQUNFX0VSUiIsIG51bGwpOwotICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTkFNRVNQQUNFX0VSUiwgbXNnKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocHJlZml4LmVxdWFscygieG1sIikpIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKCFuYW1lc3BhY2VVUkkuZXF1YWxzKHhtbFVSSSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBtc2cgPSBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiTkFNRVNQQUNFX0VSUiIsIG51bGwpOwotICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTkFNRVNQQUNFX0VSUiwgbXNnKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH1lbHNlIGlmIChuYW1lLmVxdWFscygieG1sbnMiKSkgewotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbXNnID0gRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwgIk5BTUVTUEFDRV9FUlIiLCBudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTkFNRVNQQUNFX0VSUiwgbXNnKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyB1cGRhdGUgbm9kZSBuYW1lIHdpdGggbmV3IHF1YWxpZmllZE5hbWUKLSAgICAgICAgaWYgKHByZWZpeCAhPW51bGwgJiYgcHJlZml4Lmxlbmd0aCgpICE9IDApIHsKLSAgICAgICAgICAgIG5hbWUgPSBwcmVmaXggKyAiOiIgKyBsb2NhbE5hbWU7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBuYW1lID0gbG9jYWxOYW1lOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSW50cm9kdWNlZCBpbiBET00gTGV2ZWwgMi4gPHA+Ci0gICAgICoKLSAgICAgKiBSZXR1cm5zIHRoZSBsb2NhbCBwYXJ0IG9mIHRoZSBxdWFsaWZpZWQgbmFtZSBvZiB0aGlzIG5vZGUuCi0gICAgICogQHNpbmNlIFdELURPTS1MZXZlbC0yLTE5OTkwOTIzCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRMb2NhbE5hbWUoKQotICAgIHsKLSAgICAgICAgaWYgKG5lZWRzU3luY0RhdGEoKSkgewotICAgICAgICAgICAgc3luY2hyb25pemVEYXRhKCk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGxvY2FsTmFtZTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIEBzZWUgb3JnLnczYy5kb20uVHlwZUluZm8jZ2V0VHlwZU5hbWUoKQotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VHlwZU5hbWUoKSB7Ci0gICAgICAgIGlmICh0eXBlICE9bnVsbCl7Ci0gICAgICAgICAgICBpZiAodHlwZSBpbnN0YW5jZW9mIFhTU2ltcGxlVHlwZURlY2wpewotICAgICAgICAgICAgICAgIHJldHVybiAoKFhTU2ltcGxlVHlwZURlY2wpdHlwZSkuZ2V0TmFtZSgpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIChTdHJpbmcpdHlwZTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJbnRyb2R1Y2VkIGluIERPTSBMZXZlbCAzLiA8cD4KLSAgICAgKiBDaGVja3MgaWYgYSB0eXBlIGlzIGRlcml2ZWQgZnJvbSBhbm90aGVyIGJ5IHJlc3RyaWN0aW9uLiBTZWU6Ci0gICAgICogaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTMtQ29yZS9jb3JlLmh0bWwjVHlwZUluZm8taXNEZXJpdmVkRnJvbQotICAgICAqCi0gICAgICogQHBhcmFtIGFuY2VzdG9yTlMKLSAgICAgKiAgICAgICAgVGhlIG5hbXNwYWNlIG9mIHRoZSBhbmNlc3RvciB0eXBlIGRlY2xhcmF0aW9uCi0gICAgICogQHBhcmFtIGFuY2VzdG9yTmFtZQotICAgICAqICAgICAgICBUaGUgbmFtZSBvZiB0aGUgYW5jZXN0b3IgdHlwZSBkZWNsYXJhdGlvbgotICAgICAqIEBwYXJhbSB0eXBlCi0gICAgICogICAgICAgIFRoZSByZWZlcmVuY2UgdHlwZSBkZWZpbml0aW9uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIGJvb2xlYW4gVHJ1ZSBpZiB0aGUgdHlwZSBpcyBkZXJpdmVkIGJ5IHJlc3RyaWNpdG9uIGZvciB0aGUKLSAgICAgKiAgICAgICAgIHJlZmVyZW5jZSB0eXBlCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNEZXJpdmVkRnJvbShTdHJpbmcgdHlwZU5hbWVzcGFjZUFyZywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyB0eXBlTmFtZUFyZywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBkZXJpdmF0aW9uTWV0aG9kKSB7Ci0gICAgICAgIGlmICh0eXBlICE9IG51bGwpIHsKLSAgICAgICAgICAgIGlmICh0eXBlIGluc3RhbmNlb2YgWFNTaW1wbGVUeXBlRGVjbCkgewotICAgICAgICAgICAgICAgIHJldHVybiAoKFhTU2ltcGxlVHlwZURlY2wpIHR5cGUpLmlzRE9NRGVyaXZlZEZyb20oCi0gICAgICAgICAgICAgICAgICAgICAgICB0eXBlTmFtZXNwYWNlQXJnLCB0eXBlTmFtZUFyZywgZGVyaXZhdGlvbk1ldGhvZCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgb3JnLnczYy5kb20uVHlwZUluZm8jZ2V0VHlwZU5hbWVzcGFjZSgpCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRUeXBlTmFtZXNwYWNlKCkgewotICAgICAgICBpZiAodHlwZSAhPW51bGwpIHsKLSAgICAgICAgICAgIGlmICh0eXBlIGluc3RhbmNlb2YgWFNTaW1wbGVUeXBlRGVjbCl7Ci0gICAgICAgICAgICAgICAgcmV0dXJuICgoWFNTaW1wbGVUeXBlRGVjbCl0eXBlKS5nZXROYW1lc3BhY2UoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiBEVERfVVJJOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL0F0dHJpYnV0ZU1hcC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL0F0dHJpYnV0ZU1hcC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4ZDJkMDU0Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9BdHRyaWJ1dGVNYXAuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDYwNiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAwLTIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5kb207Ci0KLWltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwotaW1wb3J0IGphdmEudXRpbC5MaXN0OwotCi1pbXBvcnQgb3JnLnczYy5kb20uRE9NRXhjZXB0aW9uOwotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci0KLS8qKgotICogQXR0cmlidXRlTWFwIGluaGVyaXRzIGZyb20gTmFtZWROb2RlTWFwSW1wbCBhbmQgZXh0ZW5kcyBpdCB0byBkZWFsIHdpdGggdGhlCi0gKiBzcGVjaWZpY3Mgb2Ygc3RvcmluZyBhdHRyaWJ1dGVzLiBUaGVzZSBhcmU6Ci0gKiA8dWw+Ci0gKiAgPGxpPm1hbmFnaW5nIG93bmVyc2hpcCBvZiBhdHRyaWJ1dGUgbm9kZXMKLSAqICA8bGk+bWFuYWdpbmcgZGVmYXVsdCBhdHRyaWJ1dGVzCi0gKiAgPGxpPmZpcmluZyBtdXRhdGlvbiBldmVudHMKLSAqIDwvdWw+Ci0gKiA8cD4KLSAqIFRoaXMgY2xhc3MgZG9lc24ndCBkaXJlY3RseSBzdXBwb3J0IG11dGF0aW9uIGV2ZW50cywgaG93ZXZlciwgaXQgbm90aWZpZXMKLSAqIHRoZSBkb2N1bWVudCB3aGVuIG11dGF0aW9ucyBhcmUgcGVyZm9ybWVkIHNvIHRoYXQgdGhlIGRvY3VtZW50IGNsYXNzIGRvIHNvLgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAdmVyc2lvbiAkSWQ6IEF0dHJpYnV0ZU1hcC5qYXZhLHYgMS43IDIwMTAtMTEtMDEgMDQ6Mzk6Mzcgam9laHcgRXhwICQKLSAqLwotcHVibGljIGNsYXNzIEF0dHJpYnV0ZU1hcCBleHRlbmRzIE5hbWVkTm9kZU1hcEltcGwgewotCi0gICAgLyoqIFNlcmlhbGl6YXRpb24gdmVyc2lvbi4gKi8KLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gODg3MjYwNjI4MjEzODY2NTM4M0w7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0cnVjdG9ycwotICAgIC8vCi0KLSAgICAvKiogQ29uc3RydWN0cyBhIG5hbWVkIG5vZGUgbWFwLiAqLwotICAgIHByb3RlY3RlZCBBdHRyaWJ1dGVNYXAoRWxlbWVudEltcGwgb3duZXJOb2RlLCBOYW1lZE5vZGVNYXBJbXBsIGRlZmF1bHRzKSB7Ci0gICAgICAgIHN1cGVyKG93bmVyTm9kZSk7Ci0gICAgICAgIGlmIChkZWZhdWx0cyAhPSBudWxsKSB7Ci0gICAgICAgICAgICAvLyBpbml0aWFsaXplIG1hcCB3aXRoIHRoZSBkZWZhdWx0cwotICAgICAgICAgICAgY2xvbmVDb250ZW50KGRlZmF1bHRzKTsKLSAgICAgICAgICAgIGlmIChub2RlcyAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgaGFzRGVmYXVsdHModHJ1ZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBZGRzIGFuIGF0dHJpYnV0ZSB1c2luZyBpdHMgbm9kZU5hbWUgYXR0cmlidXRlLgotICAgICAqIEBzZWUgb3JnLnczYy5kb20uTmFtZWROb2RlTWFwI3NldE5hbWVkSXRlbQotICAgICAqIEByZXR1cm4gSWYgdGhlIG5ldyBOb2RlIHJlcGxhY2VzIGFuIGV4aXN0aW5nIG5vZGUgdGhlIHJlcGxhY2VkIE5vZGUgaXMKLSAgICAgKiAgICAgIHJldHVybmVkLCBvdGhlcndpc2UgbnVsbCBpcyByZXR1cm5lZC4KLSAgICAgKiBAcGFyYW0gYXJnCi0gICAgICogICAgICBBbiBBdHRyIG5vZGUgdG8gc3RvcmUgaW4gdGhpcyBtYXAuCi0gICAgICogQGV4Y2VwdGlvbiBvcmcudzNjLmRvbS5ET01FeGNlcHRpb24gVGhlIGV4Y2VwdGlvbiBkZXNjcmlwdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgTm9kZSBzZXROYW1lZEl0ZW0oTm9kZSBhcmcpCi0gICAgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgYm9vbGVhbiBlcnJDaGVjayA9IG93bmVyTm9kZS5vd25lckRvY3VtZW50KCkuZXJyb3JDaGVja2luZzsKLSAgICAgICAgaWYgKGVyckNoZWNrKSB7Ci0gICAgICAgICAgICBpZiAoaXNSZWFkT25seSgpKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIG1zZyA9IERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sICJOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIiLCBudWxsKTsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIsIG1zZyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoYXJnLmdldE93bmVyRG9jdW1lbnQoKSAhPSBvd25lck5vZGUub3duZXJEb2N1bWVudCgpKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIG1zZyA9IERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sICJXUk9OR19ET0NVTUVOVF9FUlIiLCBudWxsKTsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5XUk9OR19ET0NVTUVOVF9FUlIsIG1zZyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoYXJnLmdldE5vZGVUeXBlKCkgIT0gTm9kZS5BVFRSSUJVVEVfTk9ERSkgewotICAgICAgICAgICAgICAgIFN0cmluZyBtc2cgPSBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiSElFUkFSQ0hZX1JFUVVFU1RfRVJSIiwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uSElFUkFSQ0hZX1JFUVVFU1RfRVJSLCBtc2cpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIEF0dHJJbXBsIGFyZ24gPSAoQXR0ckltcGwpYXJnOwotCi0gICAgICAgIGlmIChhcmduLmlzT3duZWQoKSl7Ci0gICAgICAgICAgICBpZiAoZXJyQ2hlY2sgJiYgYXJnbi5nZXRPd25lckVsZW1lbnQoKSAhPSBvd25lck5vZGUpIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgbXNnID0gRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwgIklOVVNFX0FUVFJJQlVURV9FUlIiLCBudWxsKTsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5JTlVTRV9BVFRSSUJVVEVfRVJSLCBtc2cpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gcmVwbGFjaW5nIGFuIEF0dHJpYnV0ZSB3aXRoIGl0c2VsZiBkb2VzIG5vdGhpbmcKLSAgICAgICAgICAgIHJldHVybiBhcmc7Ci0gICAgICAgIH0KLQotCi0gICAgICAgIC8vIHNldCBvd25lcgotICAgICAgICBhcmduLm93bmVyTm9kZSA9IG93bmVyTm9kZTsKLSAgICAgICAgYXJnbi5pc093bmVkKHRydWUpOwotCi0gICAgICAgIGludCBpID0gZmluZE5hbWVQb2ludChhcmduLmdldE5vZGVOYW1lKCksMCk7Ci0gICAgICAgIEF0dHJJbXBsIHByZXZpb3VzID0gbnVsbDsKLSAgICAgICAgaWYgKGkgPj0gMCkgewotICAgICAgICAgICAgcHJldmlvdXMgPSAoQXR0ckltcGwpIG5vZGVzLmdldChpKTsKLSAgICAgICAgICAgIG5vZGVzLnNldChpLCBhcmcpOwotICAgICAgICAgICAgcHJldmlvdXMub3duZXJOb2RlID0gb3duZXJOb2RlLm93bmVyRG9jdW1lbnQoKTsKLSAgICAgICAgICAgIHByZXZpb3VzLmlzT3duZWQoZmFsc2UpOwotICAgICAgICAgICAgLy8gbWFrZSBzdXJlIGl0IHdvbid0IGJlIG1pc3Rha2VuIHdpdGggZGVmYXVsdHMgaW4gY2FzZSBpdCdzIHJldXNlZAotICAgICAgICAgICAgcHJldmlvdXMuaXNTcGVjaWZpZWQodHJ1ZSk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBpID0gLTEgLSBpOyAvLyBJbnNlcnQgcG9pbnQgKG1heSBiZSBlbmQgb2YgbGlzdCkKLSAgICAgICAgICAgIGlmIChudWxsID09IG5vZGVzKSB7Ci0gICAgICAgICAgICAgICAgbm9kZXMgPSBuZXcgQXJyYXlMaXN0KDUpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgbm9kZXMuYWRkKGksIGFyZyk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBub3RpZnkgZG9jdW1lbnQKLSAgICAgICAgb3duZXJOb2RlLm93bmVyRG9jdW1lbnQoKS5zZXRBdHRyTm9kZShhcmduLCBwcmV2aW91cyk7Ci0KLSAgICAgICAgLy8gSWYgdGhlIG5ldyBhdHRyaWJ1dGUgaXMgbm90IG5vcm1hbGl6ZWQsCi0gICAgICAgIC8vIHRoZSBvd25pbmcgZWxlbWVudCBpcyBpbmhlcmVudGx5IG5vdCBub3JtYWxpemVkLgotICAgICAgICBpZiAoIWFyZ24uaXNOb3JtYWxpemVkKCkpIHsKLSAgICAgICAgICAgIG93bmVyTm9kZS5pc05vcm1hbGl6ZWQoZmFsc2UpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBwcmV2aW91czsKLQotICAgIH0gLy8gc2V0TmFtZWRJdGVtKE5vZGUpOk5vZGUKLQotICAgIC8qKgotICAgICAqIEFkZHMgYW4gYXR0cmlidXRlIHVzaW5nIGl0cyBuYW1lc3BhY2VVUkkgYW5kIGxvY2FsTmFtZS4KLSAgICAgKiBAc2VlIG9yZy53M2MuZG9tLk5hbWVkTm9kZU1hcCNzZXROYW1lZEl0ZW0KLSAgICAgKiBAcmV0dXJuIElmIHRoZSBuZXcgTm9kZSByZXBsYWNlcyBhbiBleGlzdGluZyBub2RlIHRoZSByZXBsYWNlZCBOb2RlIGlzCi0gICAgICogICAgICByZXR1cm5lZCwgb3RoZXJ3aXNlIG51bGwgaXMgcmV0dXJuZWQuCi0gICAgICogQHBhcmFtIGFyZyBBIG5vZGUgdG8gc3RvcmUgaW4gYSBuYW1lZCBub2RlIG1hcC4KLSAgICAgKi8KLSAgICBwdWJsaWMgTm9kZSBzZXROYW1lZEl0ZW1OUyhOb2RlIGFyZykKLSAgICB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKLQotICAgICAgICBib29sZWFuIGVyckNoZWNrID0gb3duZXJOb2RlLm93bmVyRG9jdW1lbnQoKS5lcnJvckNoZWNraW5nOwotICAgICAgICBpZiAoZXJyQ2hlY2spIHsKLSAgICAgICAgICAgIGlmIChpc1JlYWRPbmx5KCkpIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgbXNnID0gRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwgIk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiIsIG51bGwpOwotICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiwgbXNnKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmKGFyZy5nZXRPd25lckRvY3VtZW50KCkgIT0gb3duZXJOb2RlLm93bmVyRG9jdW1lbnQoKSkgewotICAgICAgICAgICAgICAgIFN0cmluZyBtc2cgPSBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiV1JPTkdfRE9DVU1FTlRfRVJSIiwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uV1JPTkdfRE9DVU1FTlRfRVJSLCBtc2cpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKGFyZy5nZXROb2RlVHlwZSgpICE9IE5vZGUuQVRUUklCVVRFX05PREUpIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgbXNnID0gRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwgIkhJRVJBUkNIWV9SRVFVRVNUX0VSUiIsIG51bGwpOwotICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLkhJRVJBUkNIWV9SRVFVRVNUX0VSUiwgbXNnKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBBdHRySW1wbCBhcmduID0gKEF0dHJJbXBsKWFyZzsKLQotICAgICAgICBpZiAoYXJnbi5pc093bmVkKCkpewotICAgICAgICAgICAgaWYgKGVyckNoZWNrICYmIGFyZ24uZ2V0T3duZXJFbGVtZW50KCkgIT0gb3duZXJOb2RlKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIG1zZyA9IERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sICJJTlVTRV9BVFRSSUJVVEVfRVJSIiwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uSU5VU0VfQVRUUklCVVRFX0VSUiwgbXNnKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIHJlcGxhY2luZyBhbiBBdHRyaWJ1dGUgd2l0aCBpdHNlbGYgZG9lcyBub3RoaW5nCi0gICAgICAgICAgICByZXR1cm4gYXJnOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gc2V0IG93bmVyCi0gICAgICAgIGFyZ24ub3duZXJOb2RlID0gb3duZXJOb2RlOwotICAgICAgICBhcmduLmlzT3duZWQodHJ1ZSk7Ci0KLSAgICAgICAgaW50IGkgPSBmaW5kTmFtZVBvaW50KGFyZ24uZ2V0TmFtZXNwYWNlVVJJKCksIGFyZ24uZ2V0TG9jYWxOYW1lKCkpOwotICAgICAgICBBdHRySW1wbCBwcmV2aW91cyA9IG51bGw7Ci0gICAgICAgIGlmIChpID49IDApIHsKLSAgICAgICAgICAgIHByZXZpb3VzID0gKEF0dHJJbXBsKSBub2Rlcy5nZXQoaSk7Ci0gICAgICAgICAgICBub2Rlcy5zZXQoaSwgYXJnKTsKLSAgICAgICAgICAgIHByZXZpb3VzLm93bmVyTm9kZSA9IG93bmVyTm9kZS5vd25lckRvY3VtZW50KCk7Ci0gICAgICAgICAgICBwcmV2aW91cy5pc093bmVkKGZhbHNlKTsKLSAgICAgICAgICAgIC8vIG1ha2Ugc3VyZSBpdCB3b24ndCBiZSBtaXN0YWtlbiB3aXRoIGRlZmF1bHRzIGluIGNhc2UgaXQncyByZXVzZWQKLSAgICAgICAgICAgIHByZXZpb3VzLmlzU3BlY2lmaWVkKHRydWUpOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgLy8gSWYgd2UgY2FuJ3QgZmluZCBieSBuYW1lc3BhY2VVUkksIGxvY2FsTmFtZSwgdGhlbiB3ZSBmaW5kIGJ5Ci0gICAgICAgICAgICAvLyBub2RlTmFtZSBzbyB3ZSBrbm93IHdoZXJlIHRvIGluc2VydC4KLSAgICAgICAgICAgIGkgPSBmaW5kTmFtZVBvaW50KGFyZy5nZXROb2RlTmFtZSgpLDApOwotICAgICAgICAgICAgaWYgKGkgPj0wKSB7Ci0gICAgICAgICAgICAgICAgcHJldmlvdXMgPSAoQXR0ckltcGwpIG5vZGVzLmdldChpKTsKLSAgICAgICAgICAgICAgICBub2Rlcy5hZGQoaSwgYXJnKTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgaSA9IC0xIC0gaTsgLy8gSW5zZXJ0IHBvaW50IChtYXkgYmUgZW5kIG9mIGxpc3QpCi0gICAgICAgICAgICAgICAgaWYgKG51bGwgPT0gbm9kZXMpIHsKLSAgICAgICAgICAgICAgICAgICAgbm9kZXMgPSBuZXcgQXJyYXlMaXN0KDUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBub2Rlcy5hZGQoaSwgYXJnKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICAvLyAgICAgIGNoYW5nZWQodHJ1ZSk7Ci0KLSAgICAgICAgLy8gbm90aWZ5IGRvY3VtZW50Ci0gICAgICAgIG93bmVyTm9kZS5vd25lckRvY3VtZW50KCkuc2V0QXR0ck5vZGUoYXJnbiwgcHJldmlvdXMpOwotCi0gICAgICAgIC8vIElmIHRoZSBuZXcgYXR0cmlidXRlIGlzIG5vdCBub3JtYWxpemVkLAotICAgICAgICAvLyB0aGUgb3duaW5nIGVsZW1lbnQgaXMgaW5oZXJlbnRseSBub3Qgbm9ybWFsaXplZC4KLSAgICAgICAgaWYgKCFhcmduLmlzTm9ybWFsaXplZCgpKSB7Ci0gICAgICAgICAgICBvd25lck5vZGUuaXNOb3JtYWxpemVkKGZhbHNlKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gcHJldmlvdXM7Ci0KLSAgICB9IC8vIHNldE5hbWVkSXRlbU5TKE5vZGUpOk5vZGUKLQotICAgIC8qKgotICAgICAqIFJlbW92ZXMgYW4gYXR0cmlidXRlIHNwZWNpZmllZCBieSBuYW1lLgotICAgICAqIEBwYXJhbSBuYW1lCi0gICAgICogICAgICBUaGUgbmFtZSBvZiBhIG5vZGUgdG8gcmVtb3ZlLiBJZiB0aGUKLSAgICAgKiAgICAgIHJlbW92ZWQgYXR0cmlidXRlIGlzIGtub3duIHRvIGhhdmUgYSBkZWZhdWx0IHZhbHVlLCBhbgotICAgICAqICAgICAgYXR0cmlidXRlIGltbWVkaWF0ZWx5IGFwcGVhcnMgY29udGFpbmluZyB0aGUgZGVmYXVsdCB2YWx1ZQotICAgICAqICAgICAgYXMgd2VsbCBhcyB0aGUgY29ycmVzcG9uZGluZyBuYW1lc3BhY2UgVVJJLCBsb2NhbCBuYW1lLAotICAgICAqICAgICAgYW5kIHByZWZpeCB3aGVuIGFwcGxpY2FibGUuCi0gICAgICogQHJldHVybiBUaGUgbm9kZSByZW1vdmVkIGZyb20gdGhlIG1hcCBpZiBhIG5vZGUgd2l0aCBzdWNoIGEgbmFtZSBleGlzdHMuCi0gICAgICogQHRocm93cyAgICAgICAgICAgICAgTk9UX0ZPVU5EX0VSUjogUmFpc2VkIGlmIHRoZXJlIGlzIG5vIG5vZGUgbmFtZWQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBuYW1lIGluIHRoZSBtYXAuCi0gICAgICovCi0gICAgLyoqKi8KLSAgICBwdWJsaWMgTm9kZSByZW1vdmVOYW1lZEl0ZW0oU3RyaW5nIG5hbWUpCi0gICAgICAgIHRocm93cyBET01FeGNlcHRpb24gewotICAgICAgICByZXR1cm4gaW50ZXJuYWxSZW1vdmVOYW1lZEl0ZW0obmFtZSwgdHJ1ZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2FtZSBhcyByZW1vdmVOYW1lZEl0ZW0gZXhjZXB0IHRoYXQgaXQgc2ltcGx5IHJldHVybnMgbnVsbCBpZiB0aGUKLSAgICAgKiBzcGVjaWZpZWQgbmFtZSBpcyBub3QgZm91bmQuCi0gICAgICovCi0gICAgTm9kZSBzYWZlUmVtb3ZlTmFtZWRJdGVtKFN0cmluZyBuYW1lKSB7Ci0gICAgICAgIHJldHVybiBpbnRlcm5hbFJlbW92ZU5hbWVkSXRlbShuYW1lLCBmYWxzZSk7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBOT04tRE9NOiBSZW1vdmUgdGhlIG5vZGUgb2JqZWN0Ci0gICAgICoKLSAgICAgKiBOT1RFOiBTcGVjaWZpY2FsbHkgcmVtb3ZlcyBUSElTIE5PREUgLS0gbm90IHRoZSBub2RlIHdpdGggdGhpcwotICAgICAqIG5hbWUsIG5vciB0aGUgbm9kZSB3aXRoIHRoZXNlIGNvbnRlbnRzLiBJZiBub2RlIGRvZXMgbm90IGJlbG9uZyB0bwotICAgICAqIHRoaXMgbmFtZWQgbm9kZSBtYXAsIHdlIHRocm93IGEgRE9NRXhjZXB0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIGl0ZW0gICAgICAgVGhlIG5vZGUgdG8gcmVtb3ZlCi0gICAgICogQHBhcmFtIGFkZERlZmF1bHQgdHJ1ZSAtLSBtYWdpY2FsbHkgYWRkIGRlZmF1bHQgYXR0cmlidXRlCi0gICAgICogQHJldHVybiBSZW1vdmVkIG5vZGUKLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqLwotICAgIHByb3RlY3RlZCBOb2RlIHJlbW92ZUl0ZW0oTm9kZSBpdGVtLCBib29sZWFuIGFkZERlZmF1bHQpCi0gICAgICAgIHRocm93cyBET01FeGNlcHRpb24gewotCi0gICAgICAgIGludCBpbmRleCA9IC0xOwotICAgICAgICBpZiAobm9kZXMgIT0gbnVsbCkgewotICAgICAgICAgICAgZmluYWwgaW50IHNpemUgPSBub2Rlcy5zaXplKCk7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNpemU7ICsraSkgewotICAgICAgICAgICAgICAgIGlmIChub2Rlcy5nZXQoaSkgPT0gaXRlbSkgewotICAgICAgICAgICAgICAgICAgICBpbmRleCA9IGk7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBpZiAoaW5kZXggPCAwKSB7Ci0gICAgICAgICAgICBTdHJpbmcgbXNnID0gRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwgIk5PVF9GT1VORF9FUlIiLCBudWxsKTsKLSAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9GT1VORF9FUlIsIG1zZyk7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gcmVtb3ZlKChBdHRySW1wbClpdGVtLCBpbmRleCwgYWRkRGVmYXVsdCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSW50ZXJuYWwgcmVtb3ZlTmFtZWRJdGVtIG1ldGhvZCBhbGxvd2luZyB0byBzcGVjaWZ5IHdoZXRoZXIgYW4gZXhjZXB0aW9uCi0gICAgICogbXVzdCBiZSB0aHJvd24gaWYgdGhlIHNwZWNpZmllZCBuYW1lIGlzIG5vdCBmb3VuZC4KLSAgICAgKi8KLSAgICBmaW5hbCBwcm90ZWN0ZWQgTm9kZSBpbnRlcm5hbFJlbW92ZU5hbWVkSXRlbShTdHJpbmcgbmFtZSwgYm9vbGVhbiByYWlzZUV4KXsKLSAgICAgICAgaWYgKGlzUmVhZE9ubHkoKSkgewotICAgICAgICAgICAgICAgIFN0cmluZyBtc2cgPSBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIiwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSLCBtc2cpOwotICAgICAgICB9Ci0gICAgICAgIGludCBpID0gZmluZE5hbWVQb2ludChuYW1lLDApOwotICAgICAgICBpZiAoaSA8IDApIHsKLSAgICAgICAgICAgIGlmIChyYWlzZUV4KSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIG1zZyA9IERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sICJOT1RfRk9VTkRfRVJSIiwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX0ZPVU5EX0VSUiwgbXNnKTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gcmVtb3ZlKChBdHRySW1wbClub2Rlcy5nZXQoaSksIGksIHRydWUpOwotCi0gICAgfSAvLyBpbnRlcm5hbFJlbW92ZU5hbWVkSXRlbShTdHJpbmcsYm9vbGVhbik6Tm9kZQotCi0gICAgcHJpdmF0ZSBmaW5hbCBOb2RlIHJlbW92ZShBdHRySW1wbCBhdHRyLCBpbnQgaW5kZXgsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGFkZERlZmF1bHQpIHsKLQotICAgICAgICBDb3JlRG9jdW1lbnRJbXBsIG93bmVyRG9jdW1lbnQgPSBvd25lck5vZGUub3duZXJEb2N1bWVudCgpOwotICAgICAgICBTdHJpbmcgbmFtZSA9IGF0dHIuZ2V0Tm9kZU5hbWUoKTsKLSAgICAgICAgaWYgKGF0dHIuaXNJZEF0dHJpYnV0ZSgpKSB7Ci0gICAgICAgICAgICBvd25lckRvY3VtZW50LnJlbW92ZUlkZW50aWZpZXIoYXR0ci5nZXRWYWx1ZSgpKTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChoYXNEZWZhdWx0cygpICYmIGFkZERlZmF1bHQpIHsKLSAgICAgICAgICAgIC8vIElmIHRoZXJlJ3MgYSBkZWZhdWx0LCBhZGQgaXQgaW5zdGVhZAotICAgICAgICAgICAgTmFtZWROb2RlTWFwSW1wbCBkZWZhdWx0cyA9Ci0gICAgICAgICAgICAgICAgKChFbGVtZW50SW1wbCkgb3duZXJOb2RlKS5nZXREZWZhdWx0QXR0cmlidXRlcygpOwotCi0gICAgICAgICAgICBOb2RlIGQ7Ci0gICAgICAgICAgICBpZiAoZGVmYXVsdHMgIT0gbnVsbCAmJgotICAgICAgICAgICAgICAgIChkID0gZGVmYXVsdHMuZ2V0TmFtZWRJdGVtKG5hbWUpKSAhPSBudWxsICYmCi0gICAgICAgICAgICAgICAgZmluZE5hbWVQb2ludChuYW1lLCBpbmRleCsxKSA8IDApIHsKLSAgICAgICAgICAgICAgICAgICAgTm9kZUltcGwgY2xvbmUgPSAoTm9kZUltcGwpZC5jbG9uZU5vZGUodHJ1ZSk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChkLmdldExvY2FsTmFtZSgpICE9bnVsbCl7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gd2UgbXVzdCByZWx5IG9uIHRoZSBuYW1lIHRvIGZpbmQgYSBkZWZhdWx0IGF0dHJpYnV0ZQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICgidGVzdDphdHRyIiksIGJ1dCB3aGlsZSBjb3B5aW5nIGl0IGZyb20gdGhlIERPQ1RZUEUKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB3ZSBzaG91bGQgbm90IGxvb3NlIG5hbWVzcGFjZSBVUkkgdGhhdCB3YXMgYXNzaWduZWQKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0byB0aGUgYXR0cmlidXRlIGluIHRoZSBpbnN0YW5jZSBkb2N1bWVudC4KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKEF0dHJOU0ltcGwpY2xvbmUpLm5hbWVzcGFjZVVSSSA9IGF0dHIuZ2V0TmFtZXNwYWNlVVJJKCk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgY2xvbmUub3duZXJOb2RlID0gb3duZXJOb2RlOwotICAgICAgICAgICAgICAgICAgICBjbG9uZS5pc093bmVkKHRydWUpOwotICAgICAgICAgICAgICAgICAgICBjbG9uZS5pc1NwZWNpZmllZChmYWxzZSk7Ci0KLSAgICAgICAgICAgICAgICAgICAgbm9kZXMuc2V0KGluZGV4LCBjbG9uZSk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChhdHRyLmlzSWRBdHRyaWJ1dGUoKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgb3duZXJEb2N1bWVudC5wdXRJZGVudGlmaWVyKGNsb25lLmdldE5vZGVWYWx1ZSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKEVsZW1lbnRJbXBsKW93bmVyTm9kZSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgbm9kZXMucmVtb3ZlKGluZGV4KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIG5vZGVzLnJlbW92ZShpbmRleCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyAgICAgICAgY2hhbmdlZCh0cnVlKTsKLQotICAgICAgICAvLyByZW1vdmUgcmVmZXJlbmNlIHRvIG93bmVyCi0gICAgICAgIGF0dHIub3duZXJOb2RlID0gb3duZXJEb2N1bWVudDsKLSAgICAgICAgYXR0ci5pc093bmVkKGZhbHNlKTsKLQotICAgICAgICAvLyBtYWtlIHN1cmUgaXQgd29uJ3QgYmUgbWlzdGFrZW4gd2l0aCBkZWZhdWx0cyBpbiBjYXNlIGl0J3MKLSAgICAgICAgLy8gcmV1c2VkCi0gICAgICAgIGF0dHIuaXNTcGVjaWZpZWQodHJ1ZSk7Ci0gICAgICAgIGF0dHIuaXNJZEF0dHJpYnV0ZShmYWxzZSk7Ci0KLSAgICAgICAgLy8gbm90aWZ5IGRvY3VtZW50Ci0gICAgICAgIG93bmVyRG9jdW1lbnQucmVtb3ZlZEF0dHJOb2RlKGF0dHIsIG93bmVyTm9kZSwgbmFtZSk7Ci0KLSAgICAgICAgcmV0dXJuIGF0dHI7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSW50cm9kdWNlZCBpbiBET00gTGV2ZWwgMi4gPHA+Ci0gICAgICogUmVtb3ZlcyBhbiBhdHRyaWJ1dGUgc3BlY2lmaWVkIGJ5IGxvY2FsIG5hbWUgYW5kIG5hbWVzcGFjZSBVUkkuCi0gICAgICogQHBhcmFtIG5hbWVzcGFjZVVSSQotICAgICAqICAgICAgICAgICAgICAgICAgICAgIFRoZSBuYW1lc3BhY2UgVVJJIG9mIHRoZSBub2RlIHRvIHJlbW92ZS4KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBXaGVuIGl0IGlzIG51bGwgb3IgYW4gZW1wdHkgc3RyaW5nLCB0aGlzCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgbWV0aG9kIGJlaGF2ZXMgbGlrZSByZW1vdmVOYW1lZEl0ZW0uCi0gICAgICogQHBhcmFtIG5hbWUgICAgICAgICAgVGhlIGxvY2FsIG5hbWUgb2YgdGhlIG5vZGUgdG8gcmVtb3ZlLiBJZiB0aGUKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICByZW1vdmVkIGF0dHJpYnV0ZSBpcyBrbm93biB0byBoYXZlIGEgZGVmYXVsdAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIHZhbHVlLCBhbiBhdHRyaWJ1dGUgaW1tZWRpYXRlbHkgYXBwZWFycwotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGNvbnRhaW5pbmcgdGhlIGRlZmF1bHQgdmFsdWUuCi0gICAgICogQHJldHVybiBOb2RlICAgICAgICAgVGhlIG5vZGUgcmVtb3ZlZCBmcm9tIHRoZSBtYXAgaWYgYSBub2RlIHdpdGggc3VjaAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGEgbG9jYWwgbmFtZSBhbmQgbmFtZXNwYWNlIFVSSSBleGlzdHMuCi0gICAgICogQHRocm93cyAgICAgICAgICAgICAgTk9UX0ZPVU5EX0VSUjogUmFpc2VkIGlmIHRoZXJlIGlzIG5vIG5vZGUgbmFtZWQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBuYW1lIGluIHRoZSBtYXAuCi0gICAgICovCi0gICAgcHVibGljIE5vZGUgcmVtb3ZlTmFtZWRJdGVtTlMoU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIG5hbWUpCi0gICAgICAgIHRocm93cyBET01FeGNlcHRpb24gewotICAgICAgICByZXR1cm4gaW50ZXJuYWxSZW1vdmVOYW1lZEl0ZW1OUyhuYW1lc3BhY2VVUkksIG5hbWUsIHRydWUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNhbWUgYXMgcmVtb3ZlTmFtZWRJdGVtIGV4Y2VwdCB0aGF0IGl0IHNpbXBseSByZXR1cm5zIG51bGwgaWYgdGhlCi0gICAgICogc3BlY2lmaWVkIGxvY2FsIG5hbWUgYW5kIG5hbWVzcGFjZSBVUkkgaXMgbm90IGZvdW5kLgotICAgICAqLwotICAgIE5vZGUgc2FmZVJlbW92ZU5hbWVkSXRlbU5TKFN0cmluZyBuYW1lc3BhY2VVUkksIFN0cmluZyBuYW1lKSB7Ci0gICAgICAgIHJldHVybiBpbnRlcm5hbFJlbW92ZU5hbWVkSXRlbU5TKG5hbWVzcGFjZVVSSSwgbmFtZSwgZmFsc2UpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEludGVybmFsIHJlbW92ZU5hbWVkSXRlbU5TIG1ldGhvZCBhbGxvd2luZyB0byBzcGVjaWZ5IHdoZXRoZXIgYW4KLSAgICAgKiBleGNlcHRpb24gbXVzdCBiZSB0aHJvd24gaWYgdGhlIHNwZWNpZmllZCBsb2NhbCBuYW1lIGFuZCBuYW1lc3BhY2UgVVJJCi0gICAgICogaXMgbm90IGZvdW5kLgotICAgICAqLwotICAgIGZpbmFsIHByb3RlY3RlZCBOb2RlIGludGVybmFsUmVtb3ZlTmFtZWRJdGVtTlMoU3RyaW5nIG5hbWVzcGFjZVVSSSwKLSAgICAgICAgICAgIFN0cmluZyBuYW1lLAotICAgICAgICAgICAgYm9vbGVhbiByYWlzZUV4KSB7Ci0KLSAgICAgICAgQ29yZURvY3VtZW50SW1wbCBvd25lckRvY3VtZW50ID0gb3duZXJOb2RlLm93bmVyRG9jdW1lbnQoKTsKLSAgICAgICAgaWYgKG93bmVyRG9jdW1lbnQuZXJyb3JDaGVja2luZyAmJiBpc1JlYWRPbmx5KCkpIHsKLSAgICAgICAgICAgIFN0cmluZyBtc2cgPSBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIiwgbnVsbCk7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIsIG1zZyk7Ci0gICAgICAgIH0KLSAgICAgICAgaW50IGkgPSBmaW5kTmFtZVBvaW50KG5hbWVzcGFjZVVSSSwgbmFtZSk7Ci0gICAgICAgIGlmIChpIDwgMCkgewotICAgICAgICAgICAgaWYgKHJhaXNlRXgpIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgbXNnID0gRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwgIk5PVF9GT1VORF9FUlIiLCBudWxsKTsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfRk9VTkRfRVJSLCBtc2cpOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIEF0dHJJbXBsIG4gPSAoQXR0ckltcGwpbm9kZXMuZ2V0KGkpOwotCi0gICAgICAgIGlmIChuLmlzSWRBdHRyaWJ1dGUoKSkgewotICAgICAgICAgICAgb3duZXJEb2N1bWVudC5yZW1vdmVJZGVudGlmaWVyKG4uZ2V0VmFsdWUoKSk7Ci0gICAgICAgIH0KLSAgICAgICAgLy8gSWYgdGhlcmUncyBhIGRlZmF1bHQsIGFkZCBpdCBpbnN0ZWFkCi0gICAgICAgIFN0cmluZyBub2RlTmFtZSA9IG4uZ2V0Tm9kZU5hbWUoKTsKLSAgICAgICAgaWYgKGhhc0RlZmF1bHRzKCkpIHsKLSAgICAgICAgICAgIE5hbWVkTm9kZU1hcEltcGwgZGVmYXVsdHMgPSAoKEVsZW1lbnRJbXBsKSBvd25lck5vZGUpLmdldERlZmF1bHRBdHRyaWJ1dGVzKCk7Ci0gICAgICAgICAgICBOb2RlIGQ7Ci0gICAgICAgICAgICBpZiAoZGVmYXVsdHMgIT0gbnVsbAotICAgICAgICAgICAgICAgICAgICAmJiAoZCA9IGRlZmF1bHRzLmdldE5hbWVkSXRlbShub2RlTmFtZSkpICE9IG51bGwpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgaW50IGogPSBmaW5kTmFtZVBvaW50KG5vZGVOYW1lLDApOwotICAgICAgICAgICAgICAgIGlmIChqPj0wICYmIGZpbmROYW1lUG9pbnQobm9kZU5hbWUsIGorMSkgPCAwKSB7Ci0gICAgICAgICAgICAgICAgICAgIE5vZGVJbXBsIGNsb25lID0gKE5vZGVJbXBsKWQuY2xvbmVOb2RlKHRydWUpOwotICAgICAgICAgICAgICAgICAgICBjbG9uZS5vd25lck5vZGUgPSBvd25lck5vZGU7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChkLmdldExvY2FsTmFtZSgpICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIHdlIG11c3QgcmVseSBvbiB0aGUgbmFtZSB0byBmaW5kIGEgZGVmYXVsdCBhdHRyaWJ1dGUKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vICgidGVzdDphdHRyIiksIGJ1dCB3aGlsZSBjb3B5aW5nIGl0IGZyb20gdGhlIERPQ1RZUEUKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIHdlIHNob3VsZCBub3QgbG9vc2UgbmFtZXNwYWNlIFVSSSB0aGF0IHdhcyBhc3NpZ25lZAotICAgICAgICAgICAgICAgICAgICAgICAgLy8gdG8gdGhlIGF0dHJpYnV0ZSBpbiB0aGUgaW5zdGFuY2UgZG9jdW1lbnQuCi0gICAgICAgICAgICAgICAgICAgICAgICAoKEF0dHJOU0ltcGwpY2xvbmUpLm5hbWVzcGFjZVVSSSA9IG5hbWVzcGFjZVVSSTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBjbG9uZS5pc093bmVkKHRydWUpOwotICAgICAgICAgICAgICAgICAgICBjbG9uZS5pc1NwZWNpZmllZChmYWxzZSk7Ci0gICAgICAgICAgICAgICAgICAgIG5vZGVzLnNldChpLCBjbG9uZSk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChjbG9uZS5pc0lkQXR0cmlidXRlKCkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIG93bmVyRG9jdW1lbnQucHV0SWRlbnRpZmllcihjbG9uZS5nZXROb2RlVmFsdWUoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKEVsZW1lbnRJbXBsKW93bmVyTm9kZSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICBub2Rlcy5yZW1vdmUoaSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBub2Rlcy5yZW1vdmUoaSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBub2Rlcy5yZW1vdmUoaSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyAgICAgICAgY2hhbmdlZCh0cnVlKTsKLQotICAgICAgICAvLyByZW1vdmUgcmVmZXJlbmNlIHRvIG93bmVyCi0gICAgICAgIG4ub3duZXJOb2RlID0gb3duZXJEb2N1bWVudDsKLSAgICAgICAgbi5pc093bmVkKGZhbHNlKTsKLSAgICAgICAgLy8gbWFrZSBzdXJlIGl0IHdvbid0IGJlIG1pc3Rha2VuIHdpdGggZGVmYXVsdHMgaW4gY2FzZSBpdCdzCi0gICAgICAgIC8vIHJldXNlZAotICAgICAgICBuLmlzU3BlY2lmaWVkKHRydWUpOwotICAgICAgICAvLyB1cGRhdGUgaWQgdGFibGUgaWYgbmVlZGVkCi0gICAgICAgIG4uaXNJZEF0dHJpYnV0ZShmYWxzZSk7Ci0KLSAgICAgICAgLy8gbm90aWZ5IGRvY3VtZW50Ci0gICAgICAgIG93bmVyRG9jdW1lbnQucmVtb3ZlZEF0dHJOb2RlKG4sIG93bmVyTm9kZSwgbmFtZSk7Ci0KLSAgICAgICAgcmV0dXJuIG47Ci0KLSAgICB9IC8vIGludGVybmFsUmVtb3ZlTmFtZWRJdGVtTlMoU3RyaW5nLFN0cmluZyxib29sZWFuKTpOb2RlCi0KLSAgICAvLwotICAgIC8vIFB1YmxpYyBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIENsb25pbmcgYSBOYW1lZE5vZGVNYXAgaXMgYSBERUVQIE9QRVJBVElPTjsgaXQgYWx3YXlzIGNsb25lcwotICAgICAqIGFsbCB0aGUgbm9kZXMgY29udGFpbmVkIGluIHRoZSBtYXAuCi0gICAgICovCi0KLSAgICBwdWJsaWMgTmFtZWROb2RlTWFwSW1wbCBjbG9uZU1hcChOb2RlSW1wbCBvd25lck5vZGUpIHsKLSAgICAgICAgQXR0cmlidXRlTWFwIG5ld21hcCA9Ci0gICAgICAgICAgICBuZXcgQXR0cmlidXRlTWFwKChFbGVtZW50SW1wbCkgb3duZXJOb2RlLCBudWxsKTsKLSAgICAgICAgbmV3bWFwLmhhc0RlZmF1bHRzKGhhc0RlZmF1bHRzKCkpOwotICAgICAgICBuZXdtYXAuY2xvbmVDb250ZW50KHRoaXMpOwotICAgICAgICByZXR1cm4gbmV3bWFwOwotICAgIH0gLy8gY2xvbmVNYXAoKTpBdHRyaWJ1dGVNYXAKLQotICAgIC8qKgotICAgICAqIE92ZXJyaWRlIHBhcmVudCdzIG1ldGhvZCB0byBzZXQgdGhlIG93bmVyTm9kZSBjb3JyZWN0bHkKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCBjbG9uZUNvbnRlbnQoTmFtZWROb2RlTWFwSW1wbCBzcmNtYXApIHsKLSAgICAgICAgTGlzdCBzcmNub2RlcyA9IHNyY21hcC5ub2RlczsKLSAgICAgICAgaWYgKHNyY25vZGVzICE9IG51bGwpIHsKLSAgICAgICAgICAgIGludCBzaXplID0gc3Jjbm9kZXMuc2l6ZSgpOwotICAgICAgICAgICAgaWYgKHNpemUgIT0gMCkgewotICAgICAgICAgICAgICAgIGlmIChub2RlcyA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIG5vZGVzID0gbmV3IEFycmF5TGlzdChzaXplKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIG5vZGVzLmNsZWFyKCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgKytpKSB7Ci0gICAgICAgICAgICAgICAgICAgIE5vZGVJbXBsIG4gPSAoTm9kZUltcGwpIHNyY25vZGVzLmdldChpKTsKLSAgICAgICAgICAgICAgICAgICAgTm9kZUltcGwgY2xvbmUgPSAoTm9kZUltcGwpIG4uY2xvbmVOb2RlKHRydWUpOwotICAgICAgICAgICAgICAgICAgICBjbG9uZS5pc1NwZWNpZmllZChuLmlzU3BlY2lmaWVkKCkpOwotICAgICAgICAgICAgICAgICAgICBub2Rlcy5hZGQoY2xvbmUpOwotICAgICAgICAgICAgICAgICAgICBjbG9uZS5vd25lck5vZGUgPSBvd25lck5vZGU7Ci0gICAgICAgICAgICAgICAgICAgIGNsb25lLmlzT3duZWQodHJ1ZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfSAvLyBjbG9uZUNvbnRlbnQoKTpBdHRyaWJ1dGVNYXAKLQotCi0gICAgLyoqCi0gICAgICogTW92ZSBzcGVjaWZpZWQgYXR0cmlidXRlcyBmcm9tIHRoZSBnaXZlbiBtYXAgdG8gdGhpcyBvbmUKLSAgICAgKi8KLSAgICB2b2lkIG1vdmVTcGVjaWZpZWRBdHRyaWJ1dGVzKEF0dHJpYnV0ZU1hcCBzcmNtYXApIHsKLSAgICAgICAgaW50IG5zaXplID0gKHNyY21hcC5ub2RlcyAhPSBudWxsKSA/IHNyY21hcC5ub2Rlcy5zaXplKCkgOiAwOwotICAgICAgICBmb3IgKGludCBpID0gbnNpemUgLSAxOyBpID49IDA7IGktLSkgewotICAgICAgICAgICAgQXR0ckltcGwgYXR0ciA9IChBdHRySW1wbCkgc3JjbWFwLm5vZGVzLmdldChpKTsKLSAgICAgICAgICAgIGlmIChhdHRyLmlzU3BlY2lmaWVkKCkpIHsKLSAgICAgICAgICAgICAgICBzcmNtYXAucmVtb3ZlKGF0dHIsIGksIGZhbHNlKTsKLSAgICAgICAgICAgICAgICBpZiAoYXR0ci5nZXRMb2NhbE5hbWUoKSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIHNldE5hbWVkSXRlbShhdHRyKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIHNldE5hbWVkSXRlbU5TKGF0dHIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0gLy8gbW92ZVNwZWNpZmllZEF0dHJpYnV0ZXMoQXR0cmlidXRlTWFwKTp2b2lkCi0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGlzIEF0dHJpYnV0ZU1hcCBpbiBzeW5jIHdpdGggdGhlIGdpdmVuICJkZWZhdWx0cyIgbWFwLgotICAgICAqIEBwYXJhbSBkZWZhdWx0cyBUaGUgZGVmYXVsdCBhdHRyaWJ1dGVzIG1hcCB0byBzeW5jIHdpdGguCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgcmVjb25jaWxlRGVmYXVsdHMoTmFtZWROb2RlTWFwSW1wbCBkZWZhdWx0cykgewotCi0gICAgICAgIC8vIHJlbW92ZSBhbnkgZXhpc3RpbmcgZGVmYXVsdAotICAgICAgICBpbnQgbnNpemUgPSAobm9kZXMgIT0gbnVsbCkgPyBub2Rlcy5zaXplKCkgOiAwOwotICAgICAgICBmb3IgKGludCBpID0gbnNpemUgLSAxOyBpID49IDA7IC0taSkgewotICAgICAgICAgICAgQXR0ckltcGwgYXR0ciA9IChBdHRySW1wbCkgbm9kZXMuZ2V0KGkpOwotICAgICAgICAgICAgaWYgKCFhdHRyLmlzU3BlY2lmaWVkKCkpIHsKLSAgICAgICAgICAgICAgICByZW1vdmUoYXR0ciwgaSwgZmFsc2UpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIC8vIGFkZCB0aGUgbmV3IGRlZmF1bHRzCi0gICAgICAgIGlmIChkZWZhdWx0cyA9PSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKG5vZGVzID09IG51bGwgfHwgbm9kZXMuc2l6ZSgpID09IDApIHsKLSAgICAgICAgICAgIGNsb25lQ29udGVudChkZWZhdWx0cyk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBpbnQgZHNpemUgPSBkZWZhdWx0cy5ub2Rlcy5zaXplKCk7Ci0gICAgICAgICAgICBmb3IgKGludCBuID0gMDsgbiA8IGRzaXplOyArK24pIHsKLSAgICAgICAgICAgICAgICBBdHRySW1wbCBkID0gKEF0dHJJbXBsKSBkZWZhdWx0cy5ub2Rlcy5nZXQobik7Ci0gICAgICAgICAgICAgICAgaW50IGkgPSBmaW5kTmFtZVBvaW50KGQuZ2V0Tm9kZU5hbWUoKSwgMCk7Ci0gICAgICAgICAgICAgICAgaWYgKGkgPCAwKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpID0gLTEgLSBpOwotICAgICAgICAgICAgICAgICAgICBOb2RlSW1wbCBjbG9uZSA9IChOb2RlSW1wbCkgZC5jbG9uZU5vZGUodHJ1ZSk7Ci0gICAgICAgICAgICAgICAgICAgIGNsb25lLm93bmVyTm9kZSA9IG93bmVyTm9kZTsKLSAgICAgICAgICAgICAgICAgICAgY2xvbmUuaXNPd25lZCh0cnVlKTsKLSAgICAgICAgICAgICAgICAgICAgY2xvbmUuaXNTcGVjaWZpZWQoZmFsc2UpOwotICAgICAgICAgICAgICAgICAgICAgICAgbm9kZXMuYWRkKGksIGNsb25lKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgIH0gLy8gcmVjb25jaWxlRGVmYXVsdHMoKQotCi0gICAgcHJvdGVjdGVkIGZpbmFsIGludCBhZGRJdGVtIChOb2RlIGFyZykgewotCi0gICAgICAgIGZpbmFsIEF0dHJJbXBsIGFyZ24gPSAoQXR0ckltcGwpIGFyZzsKLQotICAgICAgICAvLyBzZXQgb3duZXIKLSAgICAgICAgYXJnbi5vd25lck5vZGUgPSBvd25lck5vZGU7Ci0gICAgICAgIGFyZ24uaXNPd25lZCh0cnVlKTsKLQotICAgICAgICBpbnQgaSA9IGZpbmROYW1lUG9pbnQoYXJnbi5nZXROYW1lc3BhY2VVUkkoKSwgYXJnbi5nZXRMb2NhbE5hbWUoKSk7Ci0gICAgICAgIGlmIChpID49IDApIHsKLSAgICAgICAgICAgIG5vZGVzLnNldChpLCBhcmcpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgLy8gSWYgd2UgY2FuJ3QgZmluZCBieSBuYW1lc3BhY2VVUkksIGxvY2FsTmFtZSwgdGhlbiB3ZSBmaW5kIGJ5Ci0gICAgICAgICAgICAvLyBub2RlTmFtZSBzbyB3ZSBrbm93IHdoZXJlIHRvIGluc2VydC4KLSAgICAgICAgICAgIGkgPSBmaW5kTmFtZVBvaW50KGFyZ24uZ2V0Tm9kZU5hbWUoKSwwKTsKLSAgICAgICAgICAgIGlmIChpID49IDApIHsKLSAgICAgICAgICAgICAgICBub2Rlcy5hZGQoaSwgYXJnKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIGkgPSAtMSAtIGk7IC8vIEluc2VydCBwb2ludCAobWF5IGJlIGVuZCBvZiBsaXN0KQotICAgICAgICAgICAgICAgIGlmIChudWxsID09IG5vZGVzKSB7Ci0gICAgICAgICAgICAgICAgICAgIG5vZGVzID0gbmV3IEFycmF5TGlzdCg1KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgbm9kZXMuYWRkKGksIGFyZyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBub3RpZnkgZG9jdW1lbnQKLSAgICAgICAgb3duZXJOb2RlLm93bmVyRG9jdW1lbnQoKS5zZXRBdHRyTm9kZShhcmduLCBudWxsKTsKLSAgICAgICAgcmV0dXJuIGk7Ci0gICAgfQotCi19IC8vIGNsYXNzIEF0dHJpYnV0ZU1hcApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL0NEQVRBU2VjdGlvbkltcGwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9DREFUQVNlY3Rpb25JbXBsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDBhNDk1NjAuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL0NEQVRBU2VjdGlvbkltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDg5ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwMiwyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbTsKLQotaW1wb3J0IG9yZy53M2MuZG9tLkNEQVRBU2VjdGlvbjsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotCi0vKioKLSAqIFhNTCBwcm92aWRlcyB0aGUgQ0RBVEEgbWFya3VwIHRvIGFsbG93IGEgcmVnaW9uIG9mIHRleHQgaW4gd2hpY2gKLSAqIG1vc3Qgb2YgdGhlIFhNTCBkZWxpbWl0ZXIgcmVjb2duaXRpb24gZG9lcyBub3QgdGFrZSBwbGFjZS4gVGhpcyBpcwotICogaW50ZW5kZWQgdG8gZWFzZSB0aGUgdGFzayBvZiBxdW90aW5nIFhNTCBmcmFnbWVudHMgYW5kIG90aGVyCi0gKiBwcm9ncmFtbWF0aWMgaW5mb3JtYXRpb24gaW4gYSBkb2N1bWVudCdzIHRleHQgd2l0aG91dCBuZWVkaW5nIHRvCi0gKiBlc2NhcGUgdGhlc2Ugc3BlY2lhbCBjaGFyYWN0ZXJzLiBJdCdzIHByaW1hcmlseSBhIGNvbnZlbmllbmNlIGZlYXR1cmUKLSAqIGZvciB0aG9zZSB3aG8gYXJlIGhhbmQtZWRpdGluZyBYTUwuCi0gKiA8UD4KLSAqIENEQVRBU2VjdGlvbiBpcyBhbiBFeHRlbmRlZCBET00gZmVhdHVyZSwgYW5kIGlzIG5vdCB1c2VkIGluIEhUTUwKLSAqIGNvbnRleHRzLgotICogPFA+Ci0gKiBXaXRoaW4gdGhlIERPTSwgQ0RBVEFTZWN0aW9ucyBhcmUgdHJlYXRlZCBlc3NlbnRpYWxseSBhcyBUZXh0Ci0gKiBibG9ja3MuIFRoZWlyIGRpc3RpbmN0IHR5cGUgaXMgcmV0YWluZWQgaW4gb3JkZXIgdG8gYWxsb3cgdXMgdG8KLSAqIHByb3Blcmx5IHJlY3JlYXRlIHRoZSBYTUwgc3ludGF4IHdoZW4gd2Ugd3JpdGUgdGhlbSBvdXQuCi0gKiA8UD4KLSAqIFJlbWluZGVyOiBDREFUQSBJUyBOT1QgQSBDT01QTEVURUxZIEdFTkVSQUwgU09MVVRJT047IGl0IGNhbid0Ci0gKiBxdW90ZSBpdHMgb3duIGVuZC1vZi1ibG9jayBtYXJraW5nLiBJZiB5b3UgbmVlZCB0byB3cml0ZSBvdXQgYQotICogQ0RBVEEgdGhhdCBjb250YWlucyB0aGUgXV0+IHNlcXVlbmNlLCBpdCdzIHlvdXIgcmVzcG9uc2liaWxpdHkgdG8KLSAqIHNwbGl0IHRoYXQgc3RyaW5nIG92ZXIgdHdvIHN1Y2Nlc3NpdmUgQ0RBVEFzIGF0IHRoYXQgdGltZS4KLSAqIDxQPgotICogQ0RBVEEgZG9lcyBub3QgcGFydGljaXBhdGUgaW4gRWxlbWVudC5ub3JtYWxpemUoKSBwcm9jZXNzaW5nLgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAc2luY2UgIFBSLURPTS1MZXZlbC0xLTE5OTgwODE4LgotICovCi1wdWJsaWMgY2xhc3MgQ0RBVEFTZWN0aW9uSW1wbAotICAgIGV4dGVuZHMgVGV4dEltcGwKLSAgICBpbXBsZW1lbnRzIENEQVRBU2VjdGlvbiB7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0YW50cwotICAgIC8vCi0KLSAgICAvKiogU2VyaWFsaXphdGlvbiB2ZXJzaW9uLiAqLwotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAyMzcyMDcxMjk3ODc4MTc3NzgwTDsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKiBGYWN0b3J5IGNvbnN0cnVjdG9yIGZvciBjcmVhdGluZyBhIENEQVRBIHNlY3Rpb24uICovCi0gICAgcHVibGljIENEQVRBU2VjdGlvbkltcGwoQ29yZURvY3VtZW50SW1wbCBvd25lckRvYywgU3RyaW5nIGRhdGEpIHsKLSAgICAgICAgc3VwZXIob3duZXJEb2MsIGRhdGEpOwotICAgIH0KLQotICAgIC8vCi0gICAgLy8gTm9kZSBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIEEgc2hvcnQgaW50ZWdlciBpbmRpY2F0aW5nIHdoYXQgdHlwZSBvZiBub2RlIHRoaXMgaXMuIFRoZSBuYW1lZAotICAgICAqIGNvbnN0YW50cyBmb3IgdGhpcyB2YWx1ZSBhcmUgZGVmaW5lZCBpbiB0aGUgb3JnLnczYy5kb20uTm9kZSBpbnRlcmZhY2UuCi0gICAgICovCi0gICAgcHVibGljIHNob3J0IGdldE5vZGVUeXBlKCkgewotICAgICAgICByZXR1cm4gTm9kZS5DREFUQV9TRUNUSU9OX05PREU7Ci0gICAgfQotCi0gICAgLyoqIFJldHVybnMgdGhlIG5vZGUgbmFtZS4gKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE5vZGVOYW1lKCkgewotICAgICAgICByZXR1cm4gIiNjZGF0YS1zZWN0aW9uIjsKLSAgICB9Ci0KLX0gLy8gY2xhc3MgQ0RBVEFTZWN0aW9uSW1wbApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL0NoYXJhY3RlckRhdGFJbXBsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vQ2hhcmFjdGVyRGF0YUltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNmYzZTVhMy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vQ2hhcmFjdGVyRGF0YUltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQyNSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5kb207Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5ET01FeGNlcHRpb247Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlTGlzdDsKLQotLyoqCi0gKiBDaGFyYWN0ZXJEYXRhIGlzIGFuIGFic3RyYWN0IE5vZGUgdGhhdCBjYW4gY2FycnkgY2hhcmFjdGVyIGRhdGEgYXMgaXRzCi0gKiBWYWx1ZS4gIEl0IHByb3ZpZGVzIHNoYXJlZCBiZWhhdmlvciBmb3IgVGV4dCwgQ0RhdGEsIGFuZAotICogcG9zc2libHkgb3RoZXIgbm9kZSB0eXBlcy4gQWxsIG9mZnNldHMgYXJlIDAtYmFzZWQuCi0gKiA8cD4KLSAqIFNpbmNlIFByb2Nlc3NpbmdJbnN0cnVjdGlvbkltcGwgaW5oZXJpdHMgZnJvbSB0aGlzIGNsYXNzIHRvIHJldXNlIHRoZQotICogc2V0Tm9kZVZhbHVlIG1ldGhvZCwgdGhpcyBjbGFzcyBpc24ndCBkZWNsYXJlZCBhcyBpbXBsZW1lbnRpbmcgdGhlIGludGVyZmFjZQotICogQ2hhcmFjdGVyRGF0YS4gVGhpcyBpcyBkb25lIGJ5IHJlbGV2YW50IHN1YmNsYXNzZXMgKFRleEltcGwsIENvbW1lbnRJbXBsKS4KLSAqIDxwPgotICogVGhpcyBjbGFzcyBkb2Vzbid0IGRpcmVjdGx5IHN1cHBvcnQgbXV0YXRpb24gZXZlbnRzLCBob3dldmVyLCBpdCBub3RpZmllcwotICogdGhlIGRvY3VtZW50IHdoZW4gbXV0YXRpb25zIGFyZSBwZXJmb3JtZWQgc28gdGhhdCB0aGUgZG9jdW1lbnQgY2xhc3MgZG8gc28uCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBzaW5jZSAgUFItRE9NLUxldmVsLTEtMTk5ODA4MTguCi0gKi8KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBDaGFyYWN0ZXJEYXRhSW1wbAotICAgIGV4dGVuZHMgQ2hpbGROb2RlIHsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RhbnRzCi0gICAgLy8KLQotICAgIC8qKiBTZXJpYWxpemF0aW9uIHZlcnNpb24uICovCi0gICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDc5MzExNzAxNTA0Mjg0NzQyMzBMOwotCi0gICAgLy8KLSAgICAvLyBEYXRhCi0gICAgLy8KLQotICAgIHByb3RlY3RlZCBTdHJpbmcgZGF0YTsKLQotICAgIC8qKiBFbXB0eSBjaGlsZCBub2Rlcy4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyB0cmFuc2llbnQgTm9kZUxpc3Qgc2luZ2xldG9uTm9kZUxpc3QgPSBuZXcgTm9kZUxpc3QoKSB7Ci0gICAgICAgIHB1YmxpYyBOb2RlIGl0ZW0oaW50IGluZGV4KSB7IHJldHVybiBudWxsOyB9Ci0gICAgICAgIHB1YmxpYyBpbnQgZ2V0TGVuZ3RoKCkgeyByZXR1cm4gMDsgfQotICAgIH07Ci0KLSAgICAvLwotICAgIC8vIENvbnN0cnVjdG9ycwotICAgIC8vCi0KLSAgICBwdWJsaWMgQ2hhcmFjdGVyRGF0YUltcGwoKXt9Ci0KLSAgICAvKiogRmFjdG9yeSBjb25zdHJ1Y3Rvci4gKi8KLSAgICBwcm90ZWN0ZWQgQ2hhcmFjdGVyRGF0YUltcGwoQ29yZURvY3VtZW50SW1wbCBvd25lckRvY3VtZW50LCBTdHJpbmcgZGF0YSkgewotICAgICAgICBzdXBlcihvd25lckRvY3VtZW50KTsKLSAgICAgICAgdGhpcy5kYXRhID0gZGF0YTsKLSAgICB9Ci0KLSAgICAvLwotICAgIC8vIE5vZGUgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKiogUmV0dXJucyBhbiBlbXB0eSBub2RlIGxpc3QuICovCi0gICAgcHVibGljIE5vZGVMaXN0IGdldENoaWxkTm9kZXMoKSB7Ci0gICAgICAgIHJldHVybiBzaW5nbGV0b25Ob2RlTGlzdDsKLSAgICB9Ci0KLSAgICAvKgotICAgICAqIHJldHVybnMgdGhlIGNvbnRlbnQgb2YgdGhpcyBub2RlCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXROb2RlVmFsdWUoKSB7Ci0gICAgICAgIGlmIChuZWVkc1N5bmNEYXRhKCkpIHsKLSAgICAgICAgICAgIHN5bmNocm9uaXplRGF0YSgpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBkYXRhOwotICAgIH0KLQotICAgLyoqIENvbnZlbmllbmNlIHdyYXBwZXIgZm9yIGNhbGxpbmcgc2V0Tm9kZVZhbHVlSW50ZXJuYWwgd2hlbgotICAgICAqIHdlIGFyZSBub3QgcGVyZm9ybWluZyBhIHJlcGxhY2VtZW50IG9wZXJhdGlvbgotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIHNldE5vZGVWYWx1ZUludGVybmFsIChTdHJpbmcgdmFsdWUpIHsKLSAgICAgICAgc2V0Tm9kZVZhbHVlSW50ZXJuYWwodmFsdWUsIGZhbHNlKTsKLSAgICB9Ci0KLSAgICAvKiogVGhpcyBmdW5jdGlvbiBhZGRlZCBzbyB0aGF0IHdlIGNhbiBkaXN0aW5ndWlzaCB3aGV0aGVyCi0gICAgICogIHNldE5vZGVWYWx1ZSBoYXMgYmVlbiBjYWxsZWQgZnJvbSBzb21lIG90aGVyIERPTSBmdW5jdGlvbnMuCi0gICAgICogIG9yIGJ5IHRoZSBjbGllbnQuPHA+Ci0gICAgICogIFRoaXMgaXMgaW1wb3J0YW50LCBiZWNhdXNlIHdlIGRvIG9uZSB0eXBlIG9mIFJhbmdlIGZpeC11cCwKLSAgICAgKiAgZnJvbSB0aGUgaGlnaC1sZXZlbCBmdW5jdGlvbnMgaW4gQ2hhcmFjdGVyRGF0YSwgYW5kIGFub3RoZXIKLSAgICAgKiAgdHlwZSBpZiB0aGUgY2xpZW50IHNpbXBseSBjYWxscyBzZXROb2RlVmFsdWUodmFsdWUpLgotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIHNldE5vZGVWYWx1ZUludGVybmFsKFN0cmluZyB2YWx1ZSwgYm9vbGVhbiByZXBsYWNlKSB7Ci0KLSAgICAgICAgQ29yZURvY3VtZW50SW1wbCBvd25lckRvY3VtZW50ID0gb3duZXJEb2N1bWVudCgpOwotCi0gICAgICAgIGlmIChvd25lckRvY3VtZW50LmVycm9yQ2hlY2tpbmcgJiYgaXNSZWFkT25seSgpKSB7Ci0gICAgICAgICAgICBTdHJpbmcgbXNnID0gRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwgIk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiIsIG51bGwpOwotICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSLCBtc2cpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gcmV2aXNpdDogbWF5IHdhbnQgdG8gc2V0IHRoZSB2YWx1ZSBpbiBvd25lckRvY3VtZW50LgotICAgICAgICAvLyBEZWZhdWx0IGJlaGF2aW9yLCBvdmVycmlkZGVuIGluIHNvbWUgc3ViY2xhc3NlcwotICAgICAgICBpZiAobmVlZHNTeW5jRGF0YSgpKSB7Ci0gICAgICAgICAgICBzeW5jaHJvbml6ZURhdGEoKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIGtlZXAgb2xkIHZhbHVlIGZvciBkb2N1bWVudCBub3RpZmljYXRpb24KLSAgICAgICAgU3RyaW5nIG9sZHZhbHVlID0gdGhpcy5kYXRhOwotCi0gICAgICAgIC8vIG5vdGlmeSBkb2N1bWVudAotICAgICAgICBvd25lckRvY3VtZW50Lm1vZGlmeWluZ0NoYXJhY3RlckRhdGEodGhpcywgcmVwbGFjZSk7Ci0KLSAgICAgICAgdGhpcy5kYXRhID0gdmFsdWU7Ci0KLSAgICAgICAgLy8gbm90aWZ5IGRvY3VtZW50Ci0gICAgICAgIG93bmVyRG9jdW1lbnQubW9kaWZpZWRDaGFyYWN0ZXJEYXRhKHRoaXMsIG9sZHZhbHVlLCB2YWx1ZSwgcmVwbGFjZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0cyB0aGUgY29udGVudCwgcG9zc2libHkgZmlyaW5nIHJlbGF0ZWQgZXZlbnRzLAotICAgICAqIGFuZCB1cGRhdGluZyByYW5nZXMgKHZpYSBub3RpZmljYXRpb24gdG8gdGhlIGRvY3VtZW50KQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldE5vZGVWYWx1ZShTdHJpbmcgdmFsdWUpIHsKLQotICAgICAgICBzZXROb2RlVmFsdWVJbnRlcm5hbCh2YWx1ZSk7Ci0KLSAgICAgICAgLy8gbm90aWZ5IGRvY3VtZW50Ci0gICAgICAgIG93bmVyRG9jdW1lbnQoKS5yZXBsYWNlZFRleHQodGhpcyk7Ci0gICAgfQotCi0gICAgLy8KLSAgICAvLyBDaGFyYWN0ZXJEYXRhIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogUmV0cmlldmUgY2hhcmFjdGVyIGRhdGEgY3VycmVudGx5IHN0b3JlZCBpbiB0aGlzIG5vZGUuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIERPTUV4Y3BldGlvbihET01TVFJJTkdfU0laRV9FUlIpIEluIHNvbWUgaW1wbGVtZW50YXRpb25zLAotICAgICAqIHRoZSBzdG9yZWQgZGF0YSBtYXkgZXhjZWVkIHRoZSBwZXJtaXR0ZWQgbGVuZ3RoIG9mIHN0cmluZ3MuIElmIHNvLAotICAgICAqIGdldERhdGEoKSB3aWxsIHRocm93IHRoaXMgRE9NRXhjZXB0aW9uIGFkdmlzaW5nIHRoZSB1c2VyIHRvCi0gICAgICogaW5zdGVhZCByZXRyaWV2ZSB0aGUgZGF0YSBpbiBjaHVua3MgdmlhIHRoZSBzdWJzdHJpbmcoKSBvcGVyYXRpb24uCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXREYXRhKCkgewotICAgICAgICBpZiAobmVlZHNTeW5jRGF0YSgpKSB7Ci0gICAgICAgICAgICBzeW5jaHJvbml6ZURhdGEoKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZGF0YTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXBvcnQgbnVtYmVyIG9mIGNoYXJhY3RlcnMgY3VycmVudGx5IHN0b3JlZCBpbiB0aGlzIG5vZGUncwotICAgICAqIGRhdGEuIEl0IG1heSBiZSAwLCBtZWFuaW5nIHRoYXQgdGhlIHZhbHVlIGlzIGFuIGVtcHR5IHN0cmluZy4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldExlbmd0aCgpIHsKLSAgICAgICAgaWYgKG5lZWRzU3luY0RhdGEoKSkgewotICAgICAgICAgICAgc3luY2hyb25pemVEYXRhKCk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGRhdGEubGVuZ3RoKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29uY2F0ZW5hdGUgYWRkaXRpb25hbCBjaGFyYWN0ZXJzIG9udG8gdGhlIGVuZCBvZiB0aGUgZGF0YQotICAgICAqIHN0b3JlZCBpbiB0aGlzIG5vZGUuIE5vdGUgdGhhdCB0aGlzLCBhbmQgaW5zZXJ0KCksIGFyZSB0aGUgcGF0aHMKLSAgICAgKiBieSB3aGljaCBhIERPTSBjb3VsZCB3aW5kIHVwIGFjY3VtdWxhdGluZyBtb3JlIGRhdGEgdGhhbiB0aGUKLSAgICAgKiBsYW5ndWFnZSdzIHN0cmluZ3MgY2FuIGVhc2lseSBoYW5kbGUuIChTZWUgYWJvdmUgZGlzY3Vzc2lvbi4pCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbihOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIpIGlmIG5vZGUgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgYXBwZW5kRGF0YShTdHJpbmcgZGF0YSkgewotCi0gICAgICAgIGlmIChpc1JlYWRPbmx5KCkpIHsKLSAgICAgICAgICAgIFN0cmluZyBtc2cgPSBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIiwgbnVsbCk7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIsIG1zZyk7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGRhdGEgPT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0gICAgICAgIGlmIChuZWVkc1N5bmNEYXRhKCkpIHsKLSAgICAgICAgICAgIHN5bmNocm9uaXplRGF0YSgpOwotICAgICAgICB9Ci0KLSAgICAgICAgc2V0Tm9kZVZhbHVlKHRoaXMuZGF0YSArIGRhdGEpOwotCi0gICAgfSAvLyBhcHBlbmREYXRhKFN0cmluZykKLQotICAgIC8qKgotICAgICAqIFJlbW92ZSBhIHJhbmdlIG9mIGNoYXJhY3RlcnMgZnJvbSB0aGUgbm9kZSdzIHZhbHVlLiBUaHJvd3MgYQotICAgICAqIERPTUV4Y2VwdGlvbiBpZiB0aGUgb2Zmc2V0IGlzIGJleW9uZCB0aGUgZW5kIG9mIHRoZQotICAgICAqIHN0cmluZy4gSG93ZXZlciwgYSBkZWxldGlvbiBfY291bnRfIHRoYXQgZXhjZWVkcyB0aGUgYXZhaWxhYmxlCi0gICAgICogZGF0YSBpcyBhY2NlcHRlZCBhcyBhIGRlbGV0ZS10by1lbmQgcmVxdWVzdC4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uKElOREVYX1NJWkVfRVJSKSBpZiBvZmZzZXQgaXMgbmVnYXRpdmUgb3IKLSAgICAgKiBncmVhdGVyIHRoYW4gbGVuZ3RoLCBvciBpZiBjb3VudCBpcyBuZWdhdGl2ZS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uKE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUikgaWYgbm9kZSBpcwotICAgICAqIHJlYWRvbmx5LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGRlbGV0ZURhdGEoaW50IG9mZnNldCwgaW50IGNvdW50KQotICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKLQotICAgICAgICBpbnRlcm5hbERlbGV0ZURhdGEob2Zmc2V0LCBjb3VudCwgZmFsc2UpOwotICAgIH0gLy8gZGVsZXRlRGF0YShpbnQsaW50KQotCi0KLSAgICAvKiogTk9OLURPTSBJTlRFUk5BTDogV2l0aGluIERPTSBhY3Rpb25zLCB3ZSBzb21ldGltZXMgbmVlZCB0byBiZSBhYmxlCi0gICAgICogdG8gY29udHJvbCB3aGljaCBtdXRhdGlvbiBldmVudHMgYXJlIHNwYXduZWQuIFRoaXMgdmVyc2lvbiBvZiB0aGUKLSAgICAgKiBkZWxldGVEYXRhIG9wZXJhdGlvbiBhbGxvd3MgdXMgdG8gZG8gc28uIEl0IGlzIG5vdCBpbnRlbmRlZAotICAgICAqIGZvciB1c2UgYnkgYXBwbGljYXRpb24gcHJvZ3JhbXMuCi0gICAgICovCi0gICAgdm9pZCBpbnRlcm5hbERlbGV0ZURhdGEgKGludCBvZmZzZXQsIGludCBjb3VudCwgYm9vbGVhbiByZXBsYWNlKQotICAgIHRocm93cyBET01FeGNlcHRpb24gewotCi0gICAgICAgIENvcmVEb2N1bWVudEltcGwgb3duZXJEb2N1bWVudCA9IG93bmVyRG9jdW1lbnQoKTsKLSAgICAgICAgaWYgKG93bmVyRG9jdW1lbnQuZXJyb3JDaGVja2luZykgewotICAgICAgICAgICAgaWYgKGlzUmVhZE9ubHkoKSkgewotICAgICAgICAgICAgICAgIFN0cmluZyBtc2cgPSBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIiwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSLCBtc2cpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAoY291bnQgPCAwKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIG1zZyA9IERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sICJJTkRFWF9TSVpFX0VSUiIsIG51bGwpOwotICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLklOREVYX1NJWkVfRVJSLCBtc2cpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKG5lZWRzU3luY0RhdGEoKSkgewotICAgICAgICAgICAgc3luY2hyb25pemVEYXRhKCk7Ci0gICAgICAgIH0KLSAgICAgICAgaW50IHRhaWxMZW5ndGggPSBNYXRoLm1heChkYXRhLmxlbmd0aCgpIC0gY291bnQgLSBvZmZzZXQsIDApOwotICAgICAgICB0cnkgewotICAgICAgICAgICAgU3RyaW5nIHZhbHVlID0gZGF0YS5zdWJzdHJpbmcoMCwgb2Zmc2V0KSArCi0gICAgICAgICAgICAodGFpbExlbmd0aCA+IDAgPyBkYXRhLnN1YnN0cmluZyhvZmZzZXQgKyBjb3VudCwgb2Zmc2V0ICsgY291bnQgKyB0YWlsTGVuZ3RoKSA6ICIiKTsKLQotICAgICAgICAgICAgc2V0Tm9kZVZhbHVlSW50ZXJuYWwodmFsdWUsIHJlcGxhY2UpOwotCi0gICAgICAgICAgICAvLyBub3RpZnkgZG9jdW1lbnQKLSAgICAgICAgICAgIG93bmVyRG9jdW1lbnQuZGVsZXRlZFRleHQodGhpcywgb2Zmc2V0LCBjb3VudCk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgU3RyaW5nIG1zZyA9IERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sICJJTkRFWF9TSVpFX0VSUiIsIG51bGwpOwotICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uSU5ERVhfU0laRV9FUlIsIG1zZyk7Ci0gICAgICAgIH0KLQotICAgIH0gLy8gaW50ZXJuYWxEZWxldGVEYXRhKGludCxpbnQsYm9vbGVhbikKLQotICAgIC8qKgotICAgICAqIEluc2VydCBhZGRpdGlvbmFsIGNoYXJhY3RlcnMgaW50byB0aGUgZGF0YSBzdG9yZWQgaW4gdGhpcyBub2RlLAotICAgICAqIGF0IHRoZSBvZmZzZXQgc3BlY2lmaWVkLgotICAgICAqCi0gICAgICogQHRocm93cyBET01FeGNlcHRpb24oSU5ERVhfU0laRV9FUlIpIGlmIG9mZnNldCBpcyBuZWdhdGl2ZSBvcgotICAgICAqIGdyZWF0ZXIgdGhhbiBsZW5ndGguCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbihOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIpIGlmIG5vZGUgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgaW5zZXJ0RGF0YShpbnQgb2Zmc2V0LCBTdHJpbmcgZGF0YSkKLSAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgaW50ZXJuYWxJbnNlcnREYXRhKG9mZnNldCwgZGF0YSwgZmFsc2UpOwotCi0gICAgfSAvLyBpbnNlcnREYXRhKGludCxpbnQpCi0KLQotCi0gICAgLyoqIE5PTi1ET00gSU5URVJOQUw6IFdpdGhpbiBET00gYWN0aW9ucywgd2Ugc29tZXRpbWVzIG5lZWQgdG8gYmUgYWJsZQotICAgICAqIHRvIGNvbnRyb2wgd2hpY2ggbXV0YXRpb24gZXZlbnRzIGFyZSBzcGF3bmVkLiBUaGlzIHZlcnNpb24gb2YgdGhlCi0gICAgICogaW5zZXJ0RGF0YSBvcGVyYXRpb24gYWxsb3dzIHVzIHRvIGRvIHNvLiBJdCBpcyBub3QgaW50ZW5kZWQKLSAgICAgKiBmb3IgdXNlIGJ5IGFwcGxpY2F0aW9uIHByb2dyYW1zLgotICAgICAqLwotICAgIHZvaWQgaW50ZXJuYWxJbnNlcnREYXRhIChpbnQgb2Zmc2V0LCBTdHJpbmcgZGF0YSwgYm9vbGVhbiByZXBsYWNlKQotICAgIHRocm93cyBET01FeGNlcHRpb24gewotCi0gICAgICAgIENvcmVEb2N1bWVudEltcGwgb3duZXJEb2N1bWVudCA9IG93bmVyRG9jdW1lbnQoKTsKLQotICAgICAgICBpZiAob3duZXJEb2N1bWVudC5lcnJvckNoZWNraW5nICYmIGlzUmVhZE9ubHkoKSkgewotICAgICAgICAgICAgU3RyaW5nIG1zZyA9IERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sICJOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIiLCBudWxsKTsKLSAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiwgbXNnKTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChuZWVkc1N5bmNEYXRhKCkpIHsKLSAgICAgICAgICAgIHN5bmNocm9uaXplRGF0YSgpOwotICAgICAgICB9Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBTdHJpbmcgdmFsdWUgPQotICAgICAgICAgICAgICAgIG5ldyBTdHJpbmdCdWZmZXIodGhpcy5kYXRhKS5pbnNlcnQob2Zmc2V0LCBkYXRhKS50b1N0cmluZygpOwotCi0KLSAgICAgICAgICAgIHNldE5vZGVWYWx1ZUludGVybmFsKHZhbHVlLCByZXBsYWNlKTsKLQotICAgICAgICAgICAgLy8gbm90aWZ5IGRvY3VtZW50Ci0gICAgICAgICAgICBvd25lckRvY3VtZW50Lmluc2VydGVkVGV4dCh0aGlzLCBvZmZzZXQsIGRhdGEubGVuZ3RoKCkpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIFN0cmluZyBtc2cgPSBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiSU5ERVhfU0laRV9FUlIiLCBudWxsKTsKLSAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLklOREVYX1NJWkVfRVJSLCBtc2cpOwotICAgICAgICB9Ci0KLSAgICB9IC8vIGludGVybmFsSW5zZXJ0RGF0YShpbnQsU3RyaW5nLGJvb2xlYW4pCi0KLQotCi0gICAgLyoqCi0gICAgICogUmVwbGFjZSBhIHNlcmllcyBvZiBjaGFyYWN0ZXJzIGF0IHRoZSBzcGVjaWZpZWQgKHplcm8tYmFzZWQpCi0gICAgICogb2Zmc2V0IHdpdGggYSBuZXcgc3RyaW5nLCBOT1QgbmVjZXNzYXJpbHkgb2YgdGhlIHNhbWUKLSAgICAgKiBsZW5ndGguIENvbnZlbmllbmNlIG1ldGhvZCwgZXF1aXZhbGVudCB0byBhIGRlbGV0ZSBmb2xsb3dlZCBieSBhbgotICAgICAqIGluc2VydC4gVGhyb3dzIGEgRE9NRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgb2Zmc2V0IGlzIGJleW9uZAotICAgICAqIHRoZSBlbmQgb2YgdGhlIGV4aXN0aW5nIGRhdGEuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gb2Zmc2V0ICAgICAgIFRoZSBvZmZzZXQgYXQgd2hpY2ggdG8gYmVnaW4gcmVwbGFjaW5nLgotICAgICAqCi0gICAgICogQHBhcmFtIGNvdW50ICAgICAgICBUaGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gcmVtb3ZlLAotICAgICAqIGludGVycHJldGVkIGFzIGluIHRoZSBkZWxldGUoKSBtZXRob2QuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZGF0YSAgICAgICAgIFRoZSBuZXcgc3RyaW5nIHRvIGJlIGluc2VydGVkIGF0IG9mZnNldCBpbiBwbGFjZSBvZgotICAgICAqIHRoZSByZW1vdmVkIGRhdGEuIE5vdGUgdGhhdCB0aGUgZW50aXJlIHN0cmluZyB3aWxsCi0gICAgICogYmUgaW5zZXJ0ZWQgLS0gdGhlIGNvdW50IHBhcmFtZXRlciBkb2VzIG5vdCBhZmZlY3QKLSAgICAgKiBpbnNlcnRpb24sIGFuZCB0aGUgbmV3IGRhdGEgbWF5IGJlIGxvbmdlciBvciBzaG9ydGVyCi0gICAgICogdGhhbiB0aGUgc3Vic3RyaW5nIGl0IHJlcGxhY2VzLgotICAgICAqCi0gICAgICogQHRocm93cyBET01FeGNlcHRpb24oSU5ERVhfU0laRV9FUlIpIGlmIG9mZnNldCBpcyBuZWdhdGl2ZSBvcgotICAgICAqIGdyZWF0ZXIgdGhhbiBsZW5ndGgsIG9yIGlmIGNvdW50IGlzIG5lZ2F0aXZlLgotICAgICAqCi0gICAgICogQHRocm93cyBET01FeGNlcHRpb24oTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSKSBpZiBub2RlIGlzCi0gICAgICogcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcmVwbGFjZURhdGEoaW50IG9mZnNldCwgaW50IGNvdW50LCBTdHJpbmcgZGF0YSkKLSAgICB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKLQotICAgICAgICBDb3JlRG9jdW1lbnRJbXBsIG93bmVyRG9jdW1lbnQgPSBvd25lckRvY3VtZW50KCk7Ci0KLSAgICAgICAgLy8gVGhlIHJlYWQtb25seSBjaGVjayBpcyBkb25lIGJ5IGRlbGV0ZURhdGEoKQotICAgICAgICAvLyAqKioqKiBUaGlzIGNvdWxkIGJlIG1vcmUgZWZmaWNpZW50IHcvci90IE11dGF0aW9uIEV2ZW50cywKLSAgICAgICAgLy8gc3BlY2lmaWNhbGx5IGJ5IGFnZ3JlZ2F0aW5nIERPTUF0dHJNb2RpZmllZCBhbmQKLSAgICAgICAgLy8gRE9NU3VidHJlZU1vZGlmaWVkLiBCdXQgbXV0YXRpb24gZXZlbnRzIGFyZQotICAgICAgICAvLyB1bmRlcnNwZWNpZmllZDsgSSBkb24ndCBmZWVsIGNvbXBlbGxlZAotICAgICAgICAvLyB0byBkZWFsIHdpdGggaXQgcmlnaHQgbm93LgotICAgICAgICBpZiAob3duZXJEb2N1bWVudC5lcnJvckNoZWNraW5nICYmIGlzUmVhZE9ubHkoKSkgewotICAgICAgICAgICAgU3RyaW5nIG1zZyA9IERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sICJOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIiLCBudWxsKTsKLSAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiwgbXNnKTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChuZWVkc1N5bmNEYXRhKCkpIHsKLSAgICAgICAgICAgIHN5bmNocm9uaXplRGF0YSgpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy9ub3RpZnkgZG9jdW1lbnQKLSAgICAgICAgb3duZXJEb2N1bWVudC5yZXBsYWNpbmdEYXRhKHRoaXMpOwotCi0gICAgICAgIC8vIGtlZXAgb2xkIHZhbHVlIGZvciBkb2N1bWVudCBub3RpZmljYXRpb24KLSAgICAgICAgU3RyaW5nIG9sZHZhbHVlID0gdGhpcy5kYXRhOwotCi0gICAgICAgIGludGVybmFsRGVsZXRlRGF0YShvZmZzZXQsIGNvdW50LCB0cnVlKTsKLSAgICAgICAgaW50ZXJuYWxJbnNlcnREYXRhKG9mZnNldCwgZGF0YSwgdHJ1ZSk7Ci0KLSAgICAgICAgb3duZXJEb2N1bWVudC5yZXBsYWNlZENoYXJhY3RlckRhdGEodGhpcywgb2xkdmFsdWUsIHRoaXMuZGF0YSk7Ci0KLSAgICB9IC8vIHJlcGxhY2VEYXRhKGludCxpbnQsU3RyaW5nKQotCi0gICAgLyoqCi0gICAgICogU3RvcmUgY2hhcmFjdGVyIGRhdGEgaW50byB0aGlzIG5vZGUuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbihOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIpIGlmIG5vZGUgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RGF0YShTdHJpbmcgdmFsdWUpCi0gICAgICAgIHRocm93cyBET01FeGNlcHRpb24gewotICAgICAgICBzZXROb2RlVmFsdWUodmFsdWUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFN1YnN0cmluZyBpcyBtb3JlIHRoYW4gYSBjb252ZW5pZW5jZSBmdW5jdGlvbi4gSW4gc29tZQotICAgICAqIGltcGxlbWVudGF0aW9ucyBvZiB0aGUgRE9NLCB3aGVyZSB0aGUgc3RvcmVkIGRhdGEgbWF5IGV4Y2VlZCB0aGUKLSAgICAgKiBsZW5ndGggdGhhdCBjYW4gYmUgcmV0dXJuZWQgaW4gYSBzaW5nbGUgc3RyaW5nLCB0aGUgb25seSB3YXkgdG8KLSAgICAgKiByZWFkIGl0IGFsbCBpcyB0byBleHRyYWN0IGl0IGluIGNodW5rcyB2aWEgdGhpcyBtZXRob2QuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gb2Zmc2V0ICAgICAgICBaZXJvLWJhc2VkIG9mZnNldCBvZiBmaXJzdCBjaGFyYWN0ZXIgdG8gcmV0cmlldmUuCi0gICAgICogQHBhcmFtIGNvdW50IE51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHJldHJpZXZlLgotICAgICAqCi0gICAgICogSWYgdGhlIHN1bSBvZiBvZmZzZXQgYW5kIGNvdW50IGV4Y2VlZHMgdGhlIGxlbmd0aCwgYWxsIGNoYXJhY3RlcnMKLSAgICAgKiB0byBlbmQgb2YgZGF0YSBhcmUgcmV0dXJuZWQuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbihJTkRFWF9TSVpFX0VSUikgaWYgb2Zmc2V0IGlzIG5lZ2F0aXZlIG9yCi0gICAgICogZ3JlYXRlciB0aGFuIGxlbmd0aCwgb3IgaWYgY291bnQgaXMgbmVnYXRpdmUuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbihXU1RSSU5HX1NJWkVfRVJSKSBJbiBzb21lIGltcGxlbWVudGF0aW9ucywKLSAgICAgKiBjb3VudCBtYXkgZXhjZWVkIHRoZSBwZXJtaXR0ZWQgbGVuZ3RoIG9mIHN0cmluZ3MuIElmIHNvLAotICAgICAqIHN1YnN0cmluZygpIHdpbGwgdGhyb3cgdGhpcyBET01FeGNlcHRpb24gYWR2aXNpbmcgdGhlIHVzZXIgdG8KLSAgICAgKiBpbnN0ZWFkIHJldHJpZXZlIHRoZSBkYXRhIGluIHNtYWxsZXIgY2h1bmtzLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgc3Vic3RyaW5nRGF0YShpbnQgb2Zmc2V0LCBpbnQgY291bnQpCi0gICAgICAgIHRocm93cyBET01FeGNlcHRpb24gewotCi0gICAgICAgIGlmIChuZWVkc1N5bmNEYXRhKCkpIHsKLSAgICAgICAgICAgIHN5bmNocm9uaXplRGF0YSgpOwotICAgICAgICB9Ci0KLSAgICAgICAgaW50IGxlbmd0aCA9IGRhdGEubGVuZ3RoKCk7Ci0gICAgICAgIGlmIChjb3VudCA8IDAgfHwgb2Zmc2V0IDwgMCB8fCBvZmZzZXQgPiBsZW5ndGggLSAxKSB7Ci0gICAgICAgICAgICBTdHJpbmcgbXNnID0gRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwgIklOREVYX1NJWkVfRVJSIiwgbnVsbCk7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5JTkRFWF9TSVpFX0VSUiwgbXNnKTsKLSAgICAgICAgfQotCi0gICAgICAgIGludCB0YWlsSW5kZXggPSBNYXRoLm1pbihvZmZzZXQgKyBjb3VudCwgbGVuZ3RoKTsKLQotICAgICAgICByZXR1cm4gZGF0YS5zdWJzdHJpbmcob2Zmc2V0LCB0YWlsSW5kZXgpOwotCi0gICAgfSAvLyBzdWJzdHJpbmdEYXRhKGludCxpbnQpOlN0cmluZwotCi19IC8vIGNsYXNzIENoYXJhY3RlckRhdGFJbXBsCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vQ2hpbGROb2RlLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vQ2hpbGROb2RlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDNkYWI5YzkuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL0NoaWxkTm9kZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTUwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDAtMjAwMiwyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbTsKLQotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci0KLS8qKgotICogQ2hpbGROb2RlIGluaGVyaXRzIGZyb20gTm9kZUltcGwgYW5kIGFkZHMgdGhlIGNhcGFiaWxpdHkgb2YgYmVpbmcgYSBjaGlsZCBieQotICogaGF2aW5nIHJlZmVyZW5jZXMgdG8gaXRzIHByZXZpb3VzIGFuZCBuZXh0IHNpYmxpbmdzLgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKi8KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBDaGlsZE5vZGUKLSAgICBleHRlbmRzIE5vZGVJbXBsIHsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RhbnRzCi0gICAgLy8KLQotICAgIC8qKiBTZXJpYWxpemF0aW9uIHZlcnNpb24uICovCi0gICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC02MTEyNDU1NzM4ODAyNDE0MDAyTDsKLQotICAgIHRyYW5zaWVudCBTdHJpbmdCdWZmZXIgZkJ1ZmZlclN0ciA9IG51bGw7Ci0KLSAgICAvLwotICAgIC8vIERhdGEKLSAgICAvLwotCi0gICAgLyoqIFByZXZpb3VzIHNpYmxpbmcuICovCi0gICAgcHJvdGVjdGVkIENoaWxkTm9kZSBwcmV2aW91c1NpYmxpbmc7Ci0KLSAgICAvKiogTmV4dCBzaWJsaW5nLiAqLwotICAgIHByb3RlY3RlZCBDaGlsZE5vZGUgbmV4dFNpYmxpbmc7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0cnVjdG9ycwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBObyBwdWJsaWMgY29uc3RydWN0b3I7IG9ubHkgc3ViY2xhc3NlcyBvZiBOb2RlIHNob3VsZCBiZQotICAgICAqIGluc3RhbnRpYXRlZCwgYW5kIHRob3NlIG5vcm1hbGx5IHZpYSBhIERvY3VtZW50J3MgZmFjdG9yeSBtZXRob2RzCi0gICAgICogPHA+Ci0gICAgICogRXZlcnkgTm9kZSBrbm93cyB3aGF0IERvY3VtZW50IGl0IGJlbG9uZ3MgdG8uCi0gICAgICovCi0gICAgcHJvdGVjdGVkIENoaWxkTm9kZShDb3JlRG9jdW1lbnRJbXBsIG93bmVyRG9jdW1lbnQpIHsKLSAgICAgICAgc3VwZXIob3duZXJEb2N1bWVudCk7Ci0gICAgfSAvLyA8aW5pdD4oQ29yZURvY3VtZW50SW1wbCkKLQotICAgIC8qKiBDb25zdHJ1Y3RvciBmb3Igc2VyaWFsaXphdGlvbi4gKi8KLSAgICBwdWJsaWMgQ2hpbGROb2RlKCkge30KLQotICAgIC8vCi0gICAgLy8gTm9kZSBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYSBkdXBsaWNhdGUgb2YgYSBnaXZlbiBub2RlLiBZb3UgY2FuIGNvbnNpZGVyIHRoaXMgYQotICAgICAqIGdlbmVyaWMgImNvcHkgY29uc3RydWN0b3IiIGZvciBub2Rlcy4gVGhlIG5ld2x5IHJldHVybmVkIG9iamVjdCBzaG91bGQKLSAgICAgKiBiZSBjb21wbGV0ZWx5IGluZGVwZW5kZW50IG9mIHRoZSBzb3VyY2Ugb2JqZWN0J3Mgc3VidHJlZSwgc28gY2hhbmdlcwotICAgICAqIGluIG9uZSBhZnRlciB0aGUgY2xvbmUgaGFzIGJlZW4gbWFkZSB3aWxsIG5vdCBhZmZlY3QgdGhlIG90aGVyLgotICAgICAqIDxQPgotICAgICAqIE5vdGU6IHNpbmNlIHdlIG5ldmVyIGhhdmUgYW55IGNoaWxkcmVuIGRlZXAgaXMgbWVhbmluZ2xlc3MgaGVyZSwKLSAgICAgKiBQYXJlbnROb2RlIG92ZXJyaWRlcyB0aGlzIGJlaGF2aW9yLgotICAgICAqIEBzZWUgUGFyZW50Tm9kZQotICAgICAqCi0gICAgICogPHA+Ci0gICAgICogRXhhbXBsZTogQ2xvbmluZyBhIFRleHQgbm9kZSB3aWxsIGNvcHkgYm90aCB0aGUgbm9kZSBhbmQgdGhlIHRleHQgaXQKLSAgICAgKiBjb250YWlucy4KLSAgICAgKiA8cD4KLSAgICAgKiBFeGFtcGxlOiBDbG9uaW5nIHNvbWV0aGluZyB0aGF0IGhhcyBjaGlsZHJlbiAtLSBFbGVtZW50IG9yIEF0dHIsIGZvcgotICAgICAqIGV4YW1wbGUgLS0gd2lsbCBfbm90XyBjbG9uZSB0aG9zZSBjaGlsZHJlbiB1bmxlc3MgYSAiZGVlcCBjbG9uZSIKLSAgICAgKiBoYXMgYmVlbiByZXF1ZXN0ZWQuIEEgc2hhbGxvdyBjbG9uZSBvZiBhbiBBdHRyIG5vZGUgd2lsbCB5aWVsZCBhbgotICAgICAqIGVtcHR5IEF0dHIgb2YgdGhlIHNhbWUgbmFtZS4KLSAgICAgKiA8cD4KLSAgICAgKiBOT1RFOiBDbG9uZXMgd2lsbCBhbHdheXMgYmUgcmVhZC93cml0ZSwgZXZlbiBpZiB0aGUgbm9kZSBiZWluZyBjbG9uZWQKLSAgICAgKiBpcyByZWFkLW9ubHksIHRvIHBlcm1pdCBhcHBsaWNhdGlvbnMgdXNpbmcgb25seSB0aGUgRE9NIEFQSSB0byBvYnRhaW4KLSAgICAgKiBlZGl0YWJsZSBjb3BpZXMgb2YgbG9ja2VkIHBvcnRpb25zIG9mIHRoZSB0cmVlLgotICAgICAqLwotICAgIHB1YmxpYyBOb2RlIGNsb25lTm9kZShib29sZWFuIGRlZXApIHsKLQotICAgICAgICBDaGlsZE5vZGUgbmV3bm9kZSA9IChDaGlsZE5vZGUpIHN1cGVyLmNsb25lTm9kZShkZWVwKTsKLQotICAgICAgICAvLyBOZWVkIHRvIGJyZWFrIHRoZSBhc3NvY2lhdGlvbiB3LyBvcmlnaW5hbCBraWRzCi0gICAgICAgIG5ld25vZGUucHJldmlvdXNTaWJsaW5nID0gbnVsbDsKLSAgICAgICAgbmV3bm9kZS5uZXh0U2libGluZyAgICAgPSBudWxsOwotICAgICAgICBuZXdub2RlLmlzRmlyc3RDaGlsZChmYWxzZSk7Ci0KLSAgICAgICAgcmV0dXJuIG5ld25vZGU7Ci0KLSAgICB9IC8vIGNsb25lTm9kZShib29sZWFuKTpOb2RlCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBwYXJlbnQgbm9kZSBvZiB0aGlzIG5vZGUKLSAgICAgKi8KLSAgICBwdWJsaWMgTm9kZSBnZXRQYXJlbnROb2RlKCkgewotICAgICAgICAvLyBpZiB3ZSBoYXZlIGFuIG93bmVyLCBvd25lck5vZGUgaXMgb3VyIHBhcmVudCwgb3RoZXJ3aXNlIGl0J3MKLSAgICAgICAgLy8gb3VyIG93bmVyRG9jdW1lbnQgYW5kIHdlIGRvbid0IGhhdmUgYSBwYXJlbnQKLSAgICAgICAgcmV0dXJuIGlzT3duZWQoKSA/IG93bmVyTm9kZSA6IG51bGw7Ci0gICAgfQotCi0gICAgLyoKLSAgICAgKiBzYW1lIGFzIGFib3ZlIGJ1dCByZXR1cm5zIGludGVybmFsIHR5cGUKLSAgICAgKi8KLSAgICBmaW5hbCBOb2RlSW1wbCBwYXJlbnROb2RlKCkgewotICAgICAgICAvLyBpZiB3ZSBoYXZlIGFuIG93bmVyLCBvd25lck5vZGUgaXMgb3VyIHBhcmVudCwgb3RoZXJ3aXNlIGl0J3MKLSAgICAgICAgLy8gb3VyIG93bmVyRG9jdW1lbnQgYW5kIHdlIGRvbid0IGhhdmUgYSBwYXJlbnQKLSAgICAgICAgcmV0dXJuIGlzT3duZWQoKSA/IG93bmVyTm9kZSA6IG51bGw7Ci0gICAgfQotCi0gICAgLyoqIFRoZSBuZXh0IGNoaWxkIG9mIHRoaXMgbm9kZSdzIHBhcmVudCwgb3IgbnVsbCBpZiBub25lICovCi0gICAgcHVibGljIE5vZGUgZ2V0TmV4dFNpYmxpbmcoKSB7Ci0gICAgICAgIHJldHVybiBuZXh0U2libGluZzsKLSAgICB9Ci0KLSAgICAvKiogVGhlIHByZXZpb3VzIGNoaWxkIG9mIHRoaXMgbm9kZSdzIHBhcmVudCwgb3IgbnVsbCBpZiBub25lICovCi0gICAgcHVibGljIE5vZGUgZ2V0UHJldmlvdXNTaWJsaW5nKCkgewotICAgICAgICAvLyBpZiB3ZSBhcmUgdGhlIGZpcnN0Q2hpbGQsIHByZXZpb3VzU2libGluZyBhY3R1YWxseSByZWZlcnMgdG8gb3VyCi0gICAgICAgIC8vIHBhcmVudCdzIGxhc3RDaGlsZCwgYnV0IHdlIGhpZGUgdGhhdAotICAgICAgICByZXR1cm4gaXNGaXJzdENoaWxkKCkgPyBudWxsIDogcHJldmlvdXNTaWJsaW5nOwotICAgIH0KLQotICAgIC8qCi0gICAgICogc2FtZSBhcyBhYm92ZSBidXQgcmV0dXJucyBpbnRlcm5hbCB0eXBlCi0gICAgICovCi0gICAgZmluYWwgQ2hpbGROb2RlIHByZXZpb3VzU2libGluZygpIHsKLSAgICAgICAgLy8gaWYgd2UgYXJlIHRoZSBmaXJzdENoaWxkLCBwcmV2aW91c1NpYmxpbmcgYWN0dWFsbHkgcmVmZXJzIHRvIG91cgotICAgICAgICAvLyBwYXJlbnQncyBsYXN0Q2hpbGQsIGJ1dCB3ZSBoaWRlIHRoYXQKLSAgICAgICAgcmV0dXJuIGlzRmlyc3RDaGlsZCgpID8gbnVsbCA6IHByZXZpb3VzU2libGluZzsKLSAgICB9Ci0KLX0gLy8gY2xhc3MgQ2hpbGROb2RlCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vQ29tbWVudEltcGwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9Db21tZW50SW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0MThlMmNjLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9Db21tZW50SW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNzEgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDAyLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tOwotCi1pbXBvcnQgb3JnLnczYy5kb20uQ2hhcmFjdGVyRGF0YTsKLWltcG9ydCBvcmcudzNjLmRvbS5Db21tZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci0KLS8qKgotICogUmVwcmVzZW50cyBhbiBYTUwgKG9yIEhUTUwpIGNvbW1lbnQuCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBzaW5jZSAgUFItRE9NLUxldmVsLTEtMTk5ODA4MTguCi0gKi8KLXB1YmxpYyBjbGFzcyBDb21tZW50SW1wbAotICAgIGV4dGVuZHMgQ2hhcmFjdGVyRGF0YUltcGwKLSAgICBpbXBsZW1lbnRzIENoYXJhY3RlckRhdGEsIENvbW1lbnQgewotCi0gICAgLy8KLSAgICAvLyBDb25zdGFudHMKLSAgICAvLwotCi0gICAgLyoqIFNlcmlhbGl6YXRpb24gdmVyc2lvbi4gKi8KLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTI2ODU3MzY4MzM0MDgxMzQwNDRMOwotCi0gICAgLy8KLSAgICAvLyBDb25zdHJ1Y3RvcnMKLSAgICAvLwotCi0gICAgLyoqIEZhY3RvcnkgY29uc3RydWN0b3IuICovCi0gICAgcHVibGljIENvbW1lbnRJbXBsKENvcmVEb2N1bWVudEltcGwgb3duZXJEb2MsIFN0cmluZyBkYXRhKSB7Ci0gICAgICAgIHN1cGVyKG93bmVyRG9jLCBkYXRhKTsKLSAgICB9Ci0KLSAgICAvLwotICAgIC8vIE5vZGUgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBBIHNob3J0IGludGVnZXIgaW5kaWNhdGluZyB3aGF0IHR5cGUgb2Ygbm9kZSB0aGlzIGlzLiBUaGUgbmFtZWQKLSAgICAgKiBjb25zdGFudHMgZm9yIHRoaXMgdmFsdWUgYXJlIGRlZmluZWQgaW4gdGhlIG9yZy53M2MuZG9tLk5vZGUgaW50ZXJmYWNlLgotICAgICAqLwotICAgIHB1YmxpYyBzaG9ydCBnZXROb2RlVHlwZSgpIHsKLSAgICAgICAgcmV0dXJuIE5vZGUuQ09NTUVOVF9OT0RFOwotICAgIH0KLQotICAgIC8qKiBSZXR1cm5zIHRoZSBub2RlIG5hbWUuICovCi0gICAgcHVibGljIFN0cmluZyBnZXROb2RlTmFtZSgpIHsKLSAgICAgICAgcmV0dXJuICIjY29tbWVudCI7Ci0gICAgfQotCi19IC8vIGNsYXNzIENvbW1lbnRJbXBsCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vQ29yZURPTUltcGxlbWVudGF0aW9uSW1wbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL0NvcmVET01JbXBsZW1lbnRhdGlvbkltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZjIwNzc1ZS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vQ29yZURPTUltcGxlbWVudGF0aW9uSW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDg4ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLlJldmFsaWRhdGlvbkhhbmRsZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5wYXJzZXJzLkRPTVBhcnNlckltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5wYXJzZXJzLkRURENvbmZpZ3VyYXRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5wYXJzZXJzLlhJbmNsdWRlQXdhcmVQYXJzZXJDb25maWd1cmF0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5YTUxDaGFyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbHMuT2JqZWN0RmFjdG9yeTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5ncmFtbWFycy5YTUxHcmFtbWFyRGVzY3JpcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemUuRE9NU2VyaWFsaXplckltcGw7Ci1pbXBvcnQgb3JnLnczYy5kb20uRE9NRXhjZXB0aW9uOwotaW1wb3J0IG9yZy53M2MuZG9tLkRPTUltcGxlbWVudGF0aW9uOwotaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50VHlwZTsKLWltcG9ydCBvcmcudzNjLmRvbS5FbGVtZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLmxzLkxTUGFyc2VyOwotaW1wb3J0IG9yZy53M2MuZG9tLmxzLkRPTUltcGxlbWVudGF0aW9uTFM7Ci1pbXBvcnQgb3JnLnczYy5kb20ubHMuTFNJbnB1dDsKLWltcG9ydCBvcmcudzNjLmRvbS5scy5MU091dHB1dDsKLWltcG9ydCBvcmcudzNjLmRvbS5scy5MU1NlcmlhbGl6ZXI7Ci0vKioKLSAqIFRoZSBET01JbXBsZW1lbnRhdGlvbiBjbGFzcyBpcyBkZXNjcmlwdGlvbiBvZiBhIHBhcnRpY3VsYXIKLSAqIGltcGxlbWVudGF0aW9uIG9mIHRoZSBEb2N1bWVudCBPYmplY3QgTW9kZWwuIEFzIHN1Y2ggaXRzIGRhdGEgaXMKLSAqIHN0YXRpYywgc2hhcmVkIGJ5IGFsbCBpbnN0YW5jZXMgb2YgdGhpcyBpbXBsZW1lbnRhdGlvbi4KLSAqIDxQPgotICogVGhlIERPTSBBUEkgcmVxdWlyZXMgdGhhdCBpdCBiZSBhIHJlYWwgb2JqZWN0IHJhdGhlciB0aGFuIHN0YXRpYwotICogbWV0aG9kcy4gSG93ZXZlciwgdGhlcmUncyBub3RoaW5nIHRoYXQgc2F5cyBpdCBjYW4ndCBiZSBhIHNpbmdsZXRvbiwKLSAqIHNvIHRoYXQncyBob3cgSSd2ZSBpbXBsZW1lbnRlZCBpdC4KLSAqIDxQPgotICogVGhpcyBwYXJ0aWN1bGFyIGNsYXNzLCBhbG9uZyB3aXRoIENvcmVEb2N1bWVudEltcGwsIHN1cHBvcnRzIHRoZSBET00KLSAqIENvcmUgYW5kIExvYWQvU2F2ZSAoRXhwZXJpbWVudGFsKS4gT3B0aW9uYWwgbW9kdWxlcyBhcmUgc3VwcG9ydGVkIGJ5Ci0gKiB0aGUgbW9yZSBjb21wbGV0ZSBET01JbXBsZW1lbnRhdGlvbiBjbGFzcyBhbG9uZyB3aXRoIERvY3VtZW50SW1wbC4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQHZlcnNpb24gJElkOiBDb3JlRE9NSW1wbGVtZW50YXRpb25JbXBsLmphdmEsdiAxLjYgMjAxMC0xMS0wMSAwNDozOTozNyBqb2VodyBFeHAgJAotICogQHNpbmNlIFBSLURPTS1MZXZlbC0xLTE5OTgwODE4LgotICovCi1wdWJsaWMgY2xhc3MgQ29yZURPTUltcGxlbWVudGF0aW9uSW1wbAotICAgICAgICBpbXBsZW1lbnRzIERPTUltcGxlbWVudGF0aW9uLCBET01JbXBsZW1lbnRhdGlvbkxTIHsKLSAgICAgICAgLy8KLSAgICAgICAgLy8gRGF0YQotICAgICAgICAvLwotCi0gICAgLy8gdmFsaWRhdG9ycyBwb29sCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFNJWkUgPSAyOwotICAgIHByaXZhdGUgUmV2YWxpZGF0aW9uSGFuZGxlciB2YWxpZGF0b3JzW10gPSBuZXcgUmV2YWxpZGF0aW9uSGFuZGxlcltTSVpFXTsKLQotICAgIHByaXZhdGUgUmV2YWxpZGF0aW9uSGFuZGxlciBkdGRWYWxpZGF0b3JzW10gPSBuZXcgUmV2YWxpZGF0aW9uSGFuZGxlcltTSVpFXTsKLSAgICBwcml2YXRlIGludCBmcmVlVmFsaWRhdG9ySW5kZXggPSAtMTsKLSAgICBwcml2YXRlIGludCBmcmVlRFREVmFsaWRhdG9ySW5kZXggPSAtMTsKLSAgICBwcml2YXRlIGludCBjdXJyZW50U2l6ZSA9IFNJWkU7Ci0KLSAgICAvLyBEb2N1bWVudCBhbmQgZG9jdHlwZSBjb3VudGVyLiAgVXNlZCB0byBhc3NpZ24gb3JkZXIgdG8gZG9jdW1lbnRzIGFuZAotICAgIC8vIGRvY3R5cGVzIHdpdGhvdXQgb3duZXJzLCBvbiBhbiBkZW1hbmQgYmFzaXMuICAgVXNlZCBmb3IKLSAgICAvLyBjb21wYXJlRG9jdW1lbnRQb3NpdGlvbgotICAgIHByaXZhdGUgaW50IGRvY0FuZERvY3R5cGVDb3VudGVyID0gMDsKLQotICAgICAgICAvLyBzdGF0aWMKLSAgICAgICAgLyoqIERvbSBpbXBsZW1lbnRhdGlvbiBzaW5nbGV0b24uICovCi0gICAgICAgIHN0YXRpYyBDb3JlRE9NSW1wbGVtZW50YXRpb25JbXBsIHNpbmdsZXRvbiA9Ci0gICAgICAgICAgICAgICAgbmV3IENvcmVET01JbXBsZW1lbnRhdGlvbkltcGwoKTsKLSAgICAgICAgLy8KLSAgICAgICAgLy8gUHVibGljIG1ldGhvZHMKLSAgICAgICAgLy8KLSAgICAgICAgLyoqIE5PTi1ET006IE9idGFpbiBhbmQgcmV0dXJuIHRoZSBzaW5nbGUgc2hhcmVkIG9iamVjdCAqLwotICAgICAgICBwdWJsaWMgc3RhdGljIERPTUltcGxlbWVudGF0aW9uIGdldERPTUltcGxlbWVudGF0aW9uKCkgewotICAgICAgICAgICAgICAgIHJldHVybiBzaW5nbGV0b247Ci0gICAgICAgIH0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gRE9NSW1wbGVtZW50YXRpb24gbWV0aG9kcwotICAgICAgICAvLwotICAgICAgICAvKioKLSAgICAgICAgICogVGVzdCBpZiB0aGUgRE9NIGltcGxlbWVudGF0aW9uIHN1cHBvcnRzIGEgc3BlY2lmaWMgImZlYXR1cmUiIC0tCi0gICAgICAgICAqIGN1cnJlbnRseSBtZWFuaW5nIGxhbmd1YWdlIGFuZCBsZXZlbCB0aGVyZW9mLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gZmVhdHVyZSBUaGUgcGFja2FnZSBuYW1lIG9mIHRoZSBmZWF0dXJlIHRvIHRlc3QuCi0gICAgICAgICAqIEluIExldmVsIDEsIHN1cHBvcnRlZCB2YWx1ZXMgYXJlICJIVE1MIiBhbmQgIlhNTCIgKGNhc2UtaW5zZW5zaXRpdmUpLgotICAgICAgICAgKiBBdCB0aGlzIHdyaXRpbmcsIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tIHN1cHBvcnRzIG9ubHkgWE1MLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gdmVyc2lvbiBUaGUgdmVyc2lvbiBudW1iZXIgb2YgdGhlIGZlYXR1cmUgYmVpbmcgdGVzdGVkLgotICAgICAgICAgKiBUaGlzIGlzIGludGVycHJldGVkIGFzICJWZXJzaW9uIG9mIHRoZSBET00gQVBJIHN1cHBvcnRlZCBmb3IgdGhlCi0gICAgICAgICAqIHNwZWNpZmllZCBGZWF0dXJlIiwgYW5kIGluIExldmVsIDEgc2hvdWxkIGJlICIxLjAiCi0gICAgICAgICAqCi0gICAgICAgICAqIEByZXR1cm4gdHJ1ZSBpZmYgdGhpcyBpbXBsZW1lbnRhdGlvbiBpcyBjb21wYXRhYmxlIHdpdGggdGhlIHNwZWNpZmllZAotICAgICAgICAgKiBmZWF0dXJlIGFuZCB2ZXJzaW9uLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmVhdHVyZShTdHJpbmcgZmVhdHVyZSwgU3RyaW5nIHZlcnNpb24pIHsKLQotICAgICAgICAgICAgYm9vbGVhbiBhbnlWZXJzaW9uID0gdmVyc2lvbiA9PSBudWxsIHx8IHZlcnNpb24ubGVuZ3RoKCkgPT0gMDsKLQotICAgICAgICAgICAgLy8gY2hlY2sgaWYgWGFsYW4gaW1wbGVtZW50YXRpb24gaXMgYXJvdW5kIGFuZCBpZiB5ZXMgcmVwb3J0IHRydWUgZm9yIHN1cHBvcnRpbmcKLSAgICAgICAgICAgIC8vIFhQYXRoIEFQSQotICAgICAgICAgICAgLy8gaWYgYSBwbHVzIHNpZ24gIisiIGlzIHByZXBlbmRlZCB0byBhbnkgZmVhdHVyZSBuYW1lLCBpbXBsZW1lbnRhdGlvbnMKLSAgICAgICAgICAgIC8vIGFyZSBjb25zaWRlcmVkIGluIHdoaWNoIHRoZSBzcGVjaWZpZWQgZmVhdHVyZSBtYXkgbm90IGJlIGRpcmVjdGx5Ci0gICAgICAgICAgICAvLyBjYXN0YWJsZSBET01JbXBsZW1lbnRhdGlvbi5nZXRGZWF0dXJlKGZlYXR1cmUsIHZlcnNpb24pLiBXaXRob3V0IGEKLSAgICAgICAgICAgIC8vIHBsdXMsIG9ubHkgZmVhdHVyZXMgd2hvc2UgaW50ZXJmYWNlcyBhcmUgZGlyZWN0bHkgY2FzdGFibGUgYXJlIGNvbnNpZGVyZWQuCi0gICAgICAgICAgICBpZiAoKGZlYXR1cmUuZXF1YWxzSWdub3JlQ2FzZSgiK1hQYXRoIikpCi0gICAgICAgICAgICAgICAgJiYgKGFueVZlcnNpb24gfHwgdmVyc2lvbi5lcXVhbHMoIjMuMCIpKSkgewotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgIENsYXNzIHhwYXRoQ2xhc3MgPSBPYmplY3RGYWN0b3J5LmZpbmRQcm92aWRlckNsYXNzKAotICAgICAgICAgICAgICAgICAgICAgICAgImNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5kb21hcGkuWFBhdGhFdmFsdWF0b3JJbXBsIiwgdHJ1ZSk7Ci0KLSAgICAgICAgICAgICAgICAvLyBDaGVjayBpZiB0aGUgRE9NIFhQYXRoIGltcGxlbWVudGF0aW9uIGltcGxlbWVudHMKLSAgICAgICAgICAgICAgICAvLyB0aGUgaW50ZXJmYWNlIG9yZy53M2MuZG9tLlhQYXRoRXZhbHVhdG9yCi0gICAgICAgICAgICAgICAgQ2xhc3MgaW50ZXJmYWNlc1tdID0geHBhdGhDbGFzcy5nZXRJbnRlcmZhY2VzKCk7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBpbnRlcmZhY2VzLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChpbnRlcmZhY2VzW2ldLmdldE5hbWUoKS5lcXVhbHMoCi0gICAgICAgICAgICAgICAgICAgICAgICAib3JnLnczYy5kb20ueHBhdGguWFBhdGhFdmFsdWF0b3IiKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChmZWF0dXJlLnN0YXJ0c1dpdGgoIisiKSkgewotICAgICAgICAgICAgICAgIGZlYXR1cmUgPSBmZWF0dXJlLnN1YnN0cmluZygxKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiAoCi0gICAgICAgICAgICAgICAgZmVhdHVyZS5lcXVhbHNJZ25vcmVDYXNlKCJDb3JlIikKLSAgICAgICAgICAgICAgICAgICAgJiYgKGFueVZlcnNpb24KLSAgICAgICAgICAgICAgICAgICAgICAgIHx8IHZlcnNpb24uZXF1YWxzKCIxLjAiKQotICAgICAgICAgICAgICAgICAgICAgICAgfHwgdmVyc2lvbi5lcXVhbHMoIjIuMCIpCi0gICAgICAgICAgICAgICAgICAgICAgICB8fCB2ZXJzaW9uLmVxdWFscygiMy4wIikpKQotICAgICAgICAgICAgICAgICAgICAgICAgfHwgKGZlYXR1cmUuZXF1YWxzSWdub3JlQ2FzZSgiWE1MIikKLSAgICAgICAgICAgICAgICAgICAgJiYgKGFueVZlcnNpb24KLSAgICAgICAgICAgICAgICAgICAgICAgIHx8IHZlcnNpb24uZXF1YWxzKCIxLjAiKQotICAgICAgICAgICAgICAgICAgICAgICAgfHwgdmVyc2lvbi5lcXVhbHMoIjIuMCIpCi0gICAgICAgICAgICAgICAgICAgICAgICB8fCB2ZXJzaW9uLmVxdWFscygiMy4wIikpKQotICAgICAgICAgICAgICAgICAgICAgICAgfHwgKGZlYXR1cmUuZXF1YWxzSWdub3JlQ2FzZSgiTFMiKQotICAgICAgICAgICAgICAgICAgICAmJiAoYW55VmVyc2lvbiB8fCB2ZXJzaW9uLmVxdWFscygiMy4wIikpKTsKLSAgICAgICAgfSAvLyBoYXNGZWF0dXJlKFN0cmluZyxTdHJpbmcpOmJvb2xlYW4KLQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBJbnRyb2R1Y2VkIGluIERPTSBMZXZlbCAyLiA8cD4KLSAgICAgICAgICoKLSAgICAgICAgICogQ3JlYXRlcyBhbiBlbXB0eSBEb2N1bWVudFR5cGUgbm9kZS4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIHF1YWxpZmllZE5hbWUgVGhlIHF1YWxpZmllZCBuYW1lIG9mIHRoZSBkb2N1bWVudCB0eXBlIHRvIGJlIGNyZWF0ZWQuCi0gICAgICAgICAqIEBwYXJhbSBwdWJsaWNJRCBUaGUgZG9jdW1lbnQgdHlwZSBwdWJsaWMgaWRlbnRpZmllci4KLSAgICAgICAgICogQHBhcmFtIHN5c3RlbUlEIFRoZSBkb2N1bWVudCB0eXBlIHN5c3RlbSBpZGVudGlmaWVyLgotICAgICAgICAgKiBAc2luY2UgV0QtRE9NLUxldmVsLTItMTk5OTA5MjMKLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBEb2N1bWVudFR5cGUgY3JlYXRlRG9jdW1lbnRUeXBlKCBTdHJpbmcgcXVhbGlmaWVkTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBwdWJsaWNJRCwgU3RyaW5nIHN5c3RlbUlEKSB7Ci0gICAgICAgICAgICAgICAgLy8gUkVWSVNJVDogdGhpcyBtaWdodCBhbGxvdyBjcmVhdGlvbiBvZiBpbnZhbGlkIG5hbWUgZm9yIERPQ1RZUEUKLSAgICAgICAgICAgICAgICAvLyAgICAgICAgICB4bWxucyBwcmVmaXguCi0gICAgICAgICAgICAgICAgLy8gICAgICAgICAgYWxzbyB0aGVyZSBpcyBubyB3YXkgZm9yIGEgdXNlciB0byB0dXJuIG9mZiBlcnJvciBjaGVja2luZy4KLSAgICAgICAgICAgICAgICBjaGVja1FOYW1lKHF1YWxpZmllZE5hbWUpOwotICAgICAgICAgICAgICAgIHJldHVybiBuZXcgRG9jdW1lbnRUeXBlSW1wbChudWxsLCBxdWFsaWZpZWROYW1lLCBwdWJsaWNJRCwgc3lzdGVtSUQpOwotICAgICAgICB9Ci0KLSAgICBmaW5hbCB2b2lkIGNoZWNrUU5hbWUoU3RyaW5nIHFuYW1lKXsKLSAgICAgICAgaW50IGluZGV4ID0gcW5hbWUuaW5kZXhPZignOicpOwotICAgICAgICBpbnQgbGFzdEluZGV4ID0gcW5hbWUubGFzdEluZGV4T2YoJzonKTsKLSAgICAgICAgaW50IGxlbmd0aCA9IHFuYW1lLmxlbmd0aCgpOwotCi0gICAgICAgIC8vIGl0IGlzIGFuIGVycm9yIGZvciBOQ05hbWUgdG8gaGF2ZSBtb3JlIHRoYW4gb25lICc6JwotICAgICAgICAvLyBjaGVjayBpZiBpdCBpcyB2YWxpZCBRTmFtZSBbTmFtZXNwYWNlIGluIFhNTCBwcm9kdWN0aW9uIDZdCi0gICAgICAgIGlmIChpbmRleCA9PSAwIHx8IGluZGV4ID09IGxlbmd0aCAtIDEgfHwgbGFzdEluZGV4ICE9IGluZGV4KSB7Ci0gICAgICAgICAgICBTdHJpbmcgbXNnID0KLSAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoCi0gICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgIk5BTUVTUEFDRV9FUlIiLAotICAgICAgICAgICAgICAgICAgICBudWxsKTsKLSAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5BTUVTUEFDRV9FUlIsIG1zZyk7Ci0gICAgICAgIH0KLSAgICAgICAgaW50IHN0YXJ0ID0gMDsKLSAgICAgICAgLy8gTmFtZXNwYWNlIGluIFhNTCBwcm9kdWN0aW9uIFs2XQotICAgICAgICBpZiAoaW5kZXggPiAwKSB7Ci0gICAgICAgICAgICAvLyBjaGVjayB0aGF0IHByZWZpeCBpcyBOQ05hbWUKLSAgICAgICAgICAgIGlmICghWE1MQ2hhci5pc05DTmFtZVN0YXJ0KHFuYW1lLmNoYXJBdChzdGFydCkpKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIG1zZyA9Ci0gICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZSgKLSAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICJJTlZBTElEX0NIQVJBQ1RFUl9FUlIiLAotICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCk7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uSU5WQUxJRF9DSEFSQUNURVJfRVJSLCBtc2cpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDE7IGkgPCBpbmRleDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgaWYgKCFYTUxDaGFyLmlzTkNOYW1lKHFuYW1lLmNoYXJBdChpKSkpIHsKLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG1zZyA9Ci0gICAgICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICJJTlZBTElEX0NIQVJBQ1RFUl9FUlIiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwpOwotICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICAgICAgRE9NRXhjZXB0aW9uLklOVkFMSURfQ0hBUkFDVEVSX0VSUiwKLSAgICAgICAgICAgICAgICAgICAgICAgIG1zZyk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgc3RhcnQgPSBpbmRleCArIDE7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBjaGVjayBsb2NhbCBwYXJ0Ci0gICAgICAgIGlmICghWE1MQ2hhci5pc05DTmFtZVN0YXJ0KHFuYW1lLmNoYXJBdChzdGFydCkpKSB7Ci0gICAgICAgICAgICAvLyBSRVZJU0lUOiBhZGQgcW5hbWUgcGFyYW1ldGVyIHRvIHRoZSBtZXNzYWdlCi0gICAgICAgICAgICBTdHJpbmcgbXNnID0KLSAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoCi0gICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgIklOVkFMSURfQ0hBUkFDVEVSX0VSUiIsCi0gICAgICAgICAgICAgICAgICAgIG51bGwpOwotICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uSU5WQUxJRF9DSEFSQUNURVJfRVJSLCBtc2cpOwotICAgICAgICB9Ci0gICAgICAgIGZvciAoaW50IGkgPSBzdGFydCArIDE7IGkgPCBsZW5ndGg7IGkrKykgewotICAgICAgICAgICAgaWYgKCFYTUxDaGFyLmlzTkNOYW1lKHFuYW1lLmNoYXJBdChpKSkpIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgbXNnID0KLSAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKAotICAgICAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgIklOVkFMSURfQ0hBUkFDVEVSX0VSUiIsCi0gICAgICAgICAgICAgICAgICAgICAgICBudWxsKTsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5JTlZBTElEX0NIQVJBQ1RFUl9FUlIsIG1zZyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgICAgICAvKioKLSAgICAgICAgICogSW50cm9kdWNlZCBpbiBET00gTGV2ZWwgMi4gPHA+Ci0gICAgICAgICAqCi0gICAgICAgICAqIENyZWF0ZXMgYW4gWE1MIERvY3VtZW50IG9iamVjdCBvZiB0aGUgc3BlY2lmaWVkIHR5cGUgd2l0aCBpdHMgZG9jdW1lbnQKLSAgICAgICAgICogZWxlbWVudC4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIG5hbWVzcGFjZVVSSSAgICAgVGhlIG5hbWVzcGFjZSBVUkkgb2YgdGhlIGRvY3VtZW50Ci0gICAgICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQgdG8gY3JlYXRlLCBvciBudWxsLgotICAgICAgICAgKiBAcGFyYW0gcXVhbGlmaWVkTmFtZSAgICBUaGUgcXVhbGlmaWVkIG5hbWUgb2YgdGhlIGRvY3VtZW50Ci0gICAgICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQgdG8gY3JlYXRlLgotICAgICAgICAgKiBAcGFyYW0gZG9jdHlwZSAgICAgICAgICBUaGUgdHlwZSBvZiBkb2N1bWVudCB0byBiZSBjcmVhdGVkIG9yIG51bGwuPHA+Ci0gICAgICAgICAqCi0gICAgICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIFdoZW4gZG9jdHlwZSBpcyBub3QgbnVsbCwgaXRzCi0gICAgICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIE5vZGUub3duZXJEb2N1bWVudCBhdHRyaWJ1dGUgaXMgc2V0IHRvCi0gICAgICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSBkb2N1bWVudCBiZWluZyBjcmVhdGVkLgotICAgICAgICAgKiBAcmV0dXJuIERvY3VtZW50ICAgICAgICBBIG5ldyBEb2N1bWVudCBvYmplY3QuCi0gICAgICAgICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uICAgIFdST05HX0RPQ1VNRU5UX0VSUjogUmFpc2VkIGlmIGRvY3R5cGUgaGFzCi0gICAgICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIGFscmVhZHkgYmVlbiB1c2VkIHdpdGggYSBkaWZmZXJlbnQgZG9jdW1lbnQuCi0gICAgICAgICAqIEBzaW5jZSBXRC1ET00tTGV2ZWwtMi0xOTk5MDkyMwotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIERvY3VtZW50IGNyZWF0ZURvY3VtZW50KAotICAgICAgICAgICAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkksCi0gICAgICAgICAgICAgICAgU3RyaW5nIHF1YWxpZmllZE5hbWUsCi0gICAgICAgICAgICAgICAgRG9jdW1lbnRUeXBlIGRvY3R5cGUpCi0gICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICAgICAgaWYgKGRvY3R5cGUgIT0gbnVsbCAmJiBkb2N0eXBlLmdldE93bmVyRG9jdW1lbnQoKSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbXNnID0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiV1JPTkdfRE9DVU1FTlRfRVJSIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLldST05HX0RPQ1VNRU5UX0VSUiwgbXNnKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgQ29yZURvY3VtZW50SW1wbCBkb2MgPSBuZXcgQ29yZURvY3VtZW50SW1wbChkb2N0eXBlKTsKLSAgICAgICAgICAgICAgICBFbGVtZW50IGUgPSBkb2MuY3JlYXRlRWxlbWVudE5TKG5hbWVzcGFjZVVSSSwgcXVhbGlmaWVkTmFtZSk7Ci0gICAgICAgICAgICAgICAgZG9jLmFwcGVuZENoaWxkKGUpOwotICAgICAgICAgICAgICAgIHJldHVybiBkb2M7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogRE9NIExldmVsIDMgV0QgLSBFeHBlcmltZW50YWwuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgT2JqZWN0IGdldEZlYXR1cmUoU3RyaW5nIGZlYXR1cmUsIFN0cmluZyB2ZXJzaW9uKSB7Ci0gICAgICAgICAgICBpZiAoc2luZ2xldG9uLmhhc0ZlYXR1cmUoZmVhdHVyZSwgdmVyc2lvbikpIHsKLSAgICAgICAgICAgICAgICBpZiAoKGZlYXR1cmUuZXF1YWxzSWdub3JlQ2FzZSgiK1hQYXRoIikpKSB7Ci0gICAgICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBDbGFzcyB4cGF0aENsYXNzID0gT2JqZWN0RmFjdG9yeS5maW5kUHJvdmlkZXJDbGFzcygKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAiY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmRvbWFwaS5YUGF0aEV2YWx1YXRvckltcGwiLCB0cnVlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIHRoZSBET00gWFBhdGggaW1wbGVtZW50YXRpb24gaW1wbGVtZW50cwotICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhlIGludGVyZmFjZSBvcmcudzNjLmRvbS5YUGF0aEV2YWx1YXRvcgotICAgICAgICAgICAgICAgICAgICAgICAgQ2xhc3MgaW50ZXJmYWNlc1tdID0geHBhdGhDbGFzcy5nZXRJbnRlcmZhY2VzKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGludGVyZmFjZXMubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW50ZXJmYWNlc1tpXS5nZXROYW1lKCkuZXF1YWxzKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAib3JnLnczYy5kb20ueHBhdGguWFBhdGhFdmFsdWF0b3IiKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4geHBhdGhDbGFzcy5uZXdJbnN0YW5jZSgpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNpbmdsZXRvbjsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIERPTSBMMyBMUwotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBET00gTGV2ZWwgMyBMUyBDUiAtIEV4cGVyaW1lbnRhbC4KLSAgICAgKiBDcmVhdGUgYSBuZXcgPGNvZGU+TFNQYXJzZXI8L2NvZGU+LiBUaGUgbmV3bHkgY29uc3RydWN0ZWQgcGFyc2VyIG1heQotICAgICAqIHRoZW4gYmUgY29uZmlndXJlZCBieSBtZWFucyBvZiBpdHMgPGNvZGU+RE9NQ29uZmlndXJhdGlvbjwvY29kZT4KLSAgICAgKiBvYmplY3QsIGFuZCB1c2VkIHRvIHBhcnNlIGRvY3VtZW50cyBieSBtZWFucyBvZiBpdHMgPGNvZGU+cGFyc2U8L2NvZGU+Ci0gICAgICogIG1ldGhvZC4KLSAgICAgKiBAcGFyYW0gbW9kZSAgVGhlIDxjb2RlPm1vZGU8L2NvZGU+IGFyZ3VtZW50IGlzIGVpdGhlcgotICAgICAqICAgPGNvZGU+TU9ERV9TWU5DSFJPTk9VUzwvY29kZT4gb3IgPGNvZGU+TU9ERV9BU1lOQ0hST05PVVM8L2NvZGU+LCBpZgotICAgICAqICAgPGNvZGU+bW9kZTwvY29kZT4gaXMgPGNvZGU+TU9ERV9TWU5DSFJPTk9VUzwvY29kZT4gdGhlbiB0aGUKLSAgICAgKiAgIDxjb2RlPkxTUGFyc2VyPC9jb2RlPiB0aGF0IGlzIGNyZWF0ZWQgd2lsbCBvcGVyYXRlIGluIHN5bmNocm9ub3VzCi0gICAgICogICBtb2RlLCBpZiBpdCdzIDxjb2RlPk1PREVfQVNZTkNIUk9OT1VTPC9jb2RlPiB0aGVuIHRoZQotICAgICAqICAgPGNvZGU+TFNQYXJzZXI8L2NvZGU+IHRoYXQgaXMgY3JlYXRlZCB3aWxsIG9wZXJhdGUgaW4gYXN5bmNocm9ub3VzCi0gICAgICogICBtb2RlLgotICAgICAqIEBwYXJhbSBzY2hlbWFUeXBlICBBbiBhYnNvbHV0ZSBVUkkgcmVwcmVzZW50aW5nIHRoZSB0eXBlIG9mIHRoZSBzY2hlbWEKLSAgICAgKiAgIGxhbmd1YWdlIHVzZWQgZHVyaW5nIHRoZSBsb2FkIG9mIGEgPGNvZGU+RG9jdW1lbnQ8L2NvZGU+IHVzaW5nIHRoZQotICAgICAqICAgbmV3bHkgY3JlYXRlZCA8Y29kZT5MU1BhcnNlcjwvY29kZT4uIE5vdGUgdGhhdCBubyBsZXhpY2FsIGNoZWNraW5nCi0gICAgICogICBpcyBkb25lIG9uIHRoZSBhYnNvbHV0ZSBVUkkuIEluIG9yZGVyIHRvIGNyZWF0ZSBhCi0gICAgICogICA8Y29kZT5MU1BhcnNlcjwvY29kZT4gZm9yIGFueSBraW5kIG9mIHNjaGVtYSB0eXBlcyAoaS5lLiB0aGUKLSAgICAgKiAgIExTUGFyc2VyIHdpbGwgYmUgZnJlZSB0byB1c2UgYW55IHNjaGVtYSBmb3VuZCksIHVzZSB0aGUgdmFsdWUKLSAgICAgKiAgIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAqIDxwID48Yj5Ob3RlOjwvYj4gICAgRm9yIFczQyBYTUwgU2NoZW1hIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAxL1JFQy14bWxzY2hlbWEtMS0yMDAxMDUwMi8nPlhNTCBTY2hlbWEgUGFydCAxPC9hPl0KLSAgICAgKiAgICwgYXBwbGljYXRpb25zIG11c3QgdXNlIHRoZSB2YWx1ZQotICAgICAqICAgPGNvZGU+Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hIjwvY29kZT4uIEZvciBYTUwgRFREIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAwL1JFQy14bWwtMjAwMDEwMDYnPlhNTCAxLjA8L2E+XSwKLSAgICAgKiAgIGFwcGxpY2F0aW9ucyBtdXN0IHVzZSB0aGUgdmFsdWUKLSAgICAgKiAgIDxjb2RlPiJodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMteG1sIjwvY29kZT4uIE90aGVyIFNjaGVtYSBsYW5ndWFnZXMKLSAgICAgKiAgIGFyZSBvdXRzaWRlIHRoZSBzY29wZSBvZiB0aGUgVzNDIGFuZCB0aGVyZWZvcmUgc2hvdWxkIHJlY29tbWVuZCBhbgotICAgICAqICAgYWJzb2x1dGUgVVJJIGluIG9yZGVyIHRvIHVzZSB0aGlzIG1ldGhvZC4KLSAgICAgKiBAcmV0dXJuICBUaGUgbmV3bHkgY3JlYXRlZCA8Y29kZT5MU1BhcnNlcjwvY29kZT4gb2JqZWN0LiBUaGlzCi0gICAgICogICA8Y29kZT5MU1BhcnNlcjwvY29kZT4gaXMgZWl0aGVyIHN5bmNocm9ub3VzIG9yIGFzeW5jaHJvbm91cwotICAgICAqICAgZGVwZW5kaW5nIG9uIHRoZSB2YWx1ZSBvZiB0aGUgPGNvZGU+bW9kZTwvY29kZT4gYXJndW1lbnQuCi0gICAgICogPHAgPjxiPk5vdGU6PC9iPiAgICBCeSBkZWZhdWx0LCB0aGUgbmV3bHkgY3JlYXRlZCA8Y29kZT5MU1BhcnNlcjwvY29kZT4KLSAgICAgKiAgICBkb2VzIG5vdCBjb250YWluIGEgPGNvZGU+RE9NRXJyb3JIYW5kbGVyPC9jb2RlPiwgaS5lLiB0aGUgdmFsdWUgb2YKLSAgICAgKiAgIHRoZSAiPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMy9XRC1ET00tTGV2ZWwtMy1Db3JlLTIwMDMwNjA5L2NvcmUuaHRtbCNwYXJhbWV0ZXItZXJyb3ItaGFuZGxlcic+Ci0gICAgICogICBlcnJvci1oYW5kbGVyPC9hPiIgY29uZmlndXJhdGlvbiBwYXJhbWV0ZXIgaXMgPGNvZGU+bnVsbDwvY29kZT4uIEhvd2V2ZXIsIGltcGxlbWVudGF0aW9ucwotICAgICAqICAgbWF5IHByb3ZpZGUgYSBkZWZhdWx0IGVycm9yIGhhbmRsZXIgYXQgY3JlYXRpb24gdGltZS4gSW4gdGhhdCBjYXNlLAotICAgICAqICAgdGhlIGluaXRpYWwgdmFsdWUgb2YgdGhlIDxjb2RlPiJlcnJvci1oYW5kbGVyIjwvY29kZT4gY29uZmlndXJhdGlvbgotICAgICAqICAgcGFyYW1ldGVyIG9uIHRoZSBuZXcgY3JlYXRlZCA8Y29kZT5MU1BhcnNlcjwvY29kZT4gY29udGFpbnMgYQotICAgICAqICAgcmVmZXJlbmNlIHRvIHRoZSBkZWZhdWx0IGVycm9yIGhhbmRsZXIuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgICBOT1RfU1VQUE9SVEVEX0VSUjogUmFpc2VkIGlmIHRoZSByZXF1ZXN0ZWQgbW9kZSBvciBzY2hlbWEgdHlwZSBpcwotICAgICAqICAgbm90IHN1cHBvcnRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBMU1BhcnNlciBjcmVhdGVMU1BhcnNlcihzaG9ydCBtb2RlLCBTdHJpbmcgc2NoZW1hVHlwZSkKLSAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKLSAgICAgICAgICAgICAgICBpZiAobW9kZSAhPSBET01JbXBsZW1lbnRhdGlvbkxTLk1PREVfU1lOQ0hST05PVVMgfHwgKHNjaGVtYVR5cGUgIT1udWxsICYmCi0gICAgICAgICAgICAgICAgICAgISJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYSIuZXF1YWxzKHNjaGVtYVR5cGUpICYmCi0gICAgICAgICAgICAgICAgICAgICAgICAhImh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy14bWwiLmVxdWFscyhzY2hlbWFUeXBlKSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBtc2cgPQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOT1RfU1VQUE9SVEVEX0VSUiIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUiwgbXNnKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaWYgKHNjaGVtYVR5cGUgIT0gbnVsbAotICAgICAgICAgICAgICAgICAgICAgICAgJiYgc2NoZW1hVHlwZS5lcXVhbHMoImh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy14bWwiKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBET01QYXJzZXJJbXBsKG5ldyBEVERDb25maWd1cmF0aW9uKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjaGVtYVR5cGUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNyZWF0ZSBkZWZhdWx0IHBhcnNlciBjb25maWd1cmF0aW9uIHZhbGlkYXRpbmcgYWdhaW5zdCBYTUxTY2hlbWFzCi0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IERPTVBhcnNlckltcGwobmV3IFhJbmNsdWRlQXdhcmVQYXJzZXJDb25maWd1cmF0aW9uKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjaGVtYVR5cGUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBET00gTGV2ZWwgMyBMUyBDUiAtIEV4cGVyaW1lbnRhbC4KLSAgICAgICAgICogQ3JlYXRlIGEgbmV3IDxjb2RlPkxTU2VyaWFsaXplcjwvY29kZT4gb2JqZWN0LgotICAgICAgICAgKiBAcmV0dXJuIFRoZSBuZXdseSBjcmVhdGVkIDxjb2RlPkxTU2VyaWFsaXplcjwvY29kZT4gb2JqZWN0LgotICAgICAgICAgKiA8cCA+PGI+Tm90ZTo8L2I+ICAgIEJ5IGRlZmF1bHQsIHRoZSBuZXdseSBjcmVhdGVkCi0gICAgICAgICAqIDxjb2RlPkxTU2VyaWFsaXplcjwvY29kZT4gaGFzIG5vIDxjb2RlPkRPTUVycm9ySGFuZGxlcjwvY29kZT4sCi0gICAgICAgICAqIGkuZS4gdGhlIHZhbHVlIG9mIHRoZSA8Y29kZT4iZXJyb3ItaGFuZGxlciI8L2NvZGU+IGNvbmZpZ3VyYXRpb24KLSAgICAgICAgICogcGFyYW1ldGVyIGlzIDxjb2RlPm51bGw8L2NvZGU+LiBIb3dldmVyLCBpbXBsZW1lbnRhdGlvbnMgbWF5Ci0gICAgICAgICAqIHByb3ZpZGUgYSBkZWZhdWx0IGVycm9yIGhhbmRsZXIgYXQgY3JlYXRpb24gdGltZS4gSW4gdGhhdCBjYXNlLCB0aGUKLSAgICAgICAgICogaW5pdGlhbCB2YWx1ZSBvZiB0aGUgPGNvZGU+ImVycm9yLWhhbmRsZXIiPC9jb2RlPiBjb25maWd1cmF0aW9uCi0gICAgICAgICAqIHBhcmFtZXRlciBvbiB0aGUgbmV3IGNyZWF0ZWQgPGNvZGU+TFNTZXJpYWxpemVyPC9jb2RlPiBjb250YWlucyBhCi0gICAgICAgICAqIHJlZmVyZW5jZSB0byB0aGUgZGVmYXVsdCBlcnJvciBoYW5kbGVyLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIExTU2VyaWFsaXplciBjcmVhdGVMU1NlcmlhbGl6ZXIoKSB7Ci0gICAgICAgIHJldHVybiBuZXcgRE9NU2VyaWFsaXplckltcGwoKTsKLSAgICB9Ci0gICAgICAgIC8qKgotICAgICAgICAgKiBET00gTGV2ZWwgMyBMUyBDUiAtIEV4cGVyaW1lbnRhbC4KLSAgICAgICAgICogQ3JlYXRlIGEgbmV3IGVtcHR5IGlucHV0IHNvdXJjZS4KLSAgICAgICAgICogQHJldHVybiAgVGhlIG5ld2x5IGNyZWF0ZWQgaW5wdXQgb2JqZWN0LgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIExTSW5wdXQgY3JlYXRlTFNJbnB1dCgpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gbmV3IERPTUlucHV0SW1wbCgpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gUHJvdGVjdGVkIG1ldGhvZHMKLSAgICAgICAgLy8KLSAgICAgICAgLyoqIE5PTi1ET006IHJldHJpZXZlIHZhbGlkYXRvci4gKi8KLSAgICAgICAgc3luY2hyb25pemVkIFJldmFsaWRhdGlvbkhhbmRsZXIgZ2V0VmFsaWRhdG9yKFN0cmluZyBzY2hlbWFUeXBlKSB7Ci0gICAgICAgICAgICAgICAgLy8gUkVWSVNJVDogaW1wbGVtZW50IHJldHJpZXZpbmcgRFREIHZhbGlkYXRvcgotICAgICAgICBpZiAoc2NoZW1hVHlwZSA9PSBYTUxHcmFtbWFyRGVzY3JpcHRpb24uWE1MX1NDSEVNQSkgewotICAgICAgICAgICAgLy8gY3JlYXRlIG5ldyB2YWxpZGF0b3IgLSB3ZSBzaG91bGQgbm90IGF0dGVtcHQKLSAgICAgICAgICAgIC8vIHRvIHJlc3RyaWN0IHRoZSBudW1iZXIgb2YgdmFsaWRhdGlvbiBoYW5kbGVycyBiZWluZwotICAgICAgICAgICAgLy8gcmVxdWVzdGVkCi0gICAgICAgICAgICBpZihmcmVlVmFsaWRhdG9ySW5kZXggPCAwKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIChSZXZhbGlkYXRpb25IYW5kbGVyKSAoT2JqZWN0RmFjdG9yeQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5uZXdJbnN0YW5jZSgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5YTUxTY2hlbWFWYWxpZGF0b3IiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPYmplY3RGYWN0b3J5LmZpbmRDbGFzc0xvYWRlcigpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyByZXR1cm4gZmlyc3QgYXZhaWxhYmxlIHZhbGlkYXRvcgotICAgICAgICAgICAgUmV2YWxpZGF0aW9uSGFuZGxlciB2YWwgPSB2YWxpZGF0b3JzW2ZyZWVWYWxpZGF0b3JJbmRleF07Ci0gICAgICAgICAgICB2YWxpZGF0b3JzW2ZyZWVWYWxpZGF0b3JJbmRleC0tXSA9IG51bGw7Ci0gICAgICAgICAgICByZXR1cm4gdmFsOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYoc2NoZW1hVHlwZSA9PSBYTUxHcmFtbWFyRGVzY3JpcHRpb24uWE1MX0RURCkgewotICAgICAgICAgICAgaWYoZnJlZURURFZhbGlkYXRvckluZGV4IDwgMCkgewotICAgICAgICAgICAgICAgIHJldHVybiAoUmV2YWxpZGF0aW9uSGFuZGxlcikgKE9iamVjdEZhY3RvcnkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAubmV3SW5zdGFuY2UoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHRkLlhNTERURFZhbGlkYXRvciIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9iamVjdEZhY3RvcnkuZmluZENsYXNzTG9hZGVyKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIHJldHVybiBmaXJzdCBhdmFpbGFibGUgdmFsaWRhdG9yCi0gICAgICAgICAgICBSZXZhbGlkYXRpb25IYW5kbGVyIHZhbCA9IGR0ZFZhbGlkYXRvcnNbZnJlZURURFZhbGlkYXRvckluZGV4XTsKLSAgICAgICAgICAgIGR0ZFZhbGlkYXRvcnNbZnJlZURURFZhbGlkYXRvckluZGV4LS1dID0gbnVsbDsKLSAgICAgICAgICAgIHJldHVybiB2YWw7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLQotICAgICAgICAvKiogTk9OLURPTTogcmVsZWFzZSB2YWxpZGF0b3IgKi8KLSAgICAgICAgc3luY2hyb25pemVkIHZvaWQgcmVsZWFzZVZhbGlkYXRvcihTdHJpbmcgc2NoZW1hVHlwZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmV2YWxpZGF0aW9uSGFuZGxlciB2YWxpZGF0b3IpIHsKLSAgICAgICAvLyBSRVZJU0lUOiBpbXBsZW1lbnQgc3VwcG9ydCBmb3IgRFREIHZhbGlkYXRvcnMgYXMgd2VsbAotICAgICAgIGlmKHNjaGVtYVR5cGUgPT0gWE1MR3JhbW1hckRlc2NyaXB0aW9uLlhNTF9TQ0hFTUEpIHsKLSAgICAgICAgICAgKytmcmVlVmFsaWRhdG9ySW5kZXg7Ci0gICAgICAgICAgIGlmICh2YWxpZGF0b3JzLmxlbmd0aCA9PSBmcmVlVmFsaWRhdG9ySW5kZXggKXsKLSAgICAgICAgICAgICAgICAvLyByZXNpemUgc2l6ZSBvZiB0aGUgdmFsaWRhdG9ycwotICAgICAgICAgICAgICAgIGN1cnJlbnRTaXplKz1TSVpFOwotICAgICAgICAgICAgICAgIFJldmFsaWRhdGlvbkhhbmRsZXIgbmV3YXJyYXlbXSA9ICBuZXcgUmV2YWxpZGF0aW9uSGFuZGxlcltjdXJyZW50U2l6ZV07Ci0gICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weSh2YWxpZGF0b3JzLCAwLCBuZXdhcnJheSwgMCwgdmFsaWRhdG9ycy5sZW5ndGgpOwotICAgICAgICAgICAgICAgIHZhbGlkYXRvcnMgPSBuZXdhcnJheTsKLSAgICAgICAgICAgfQotICAgICAgICAgICB2YWxpZGF0b3JzW2ZyZWVWYWxpZGF0b3JJbmRleF09dmFsaWRhdG9yOwotICAgICAgIH0KLSAgICAgICBlbHNlIGlmKHNjaGVtYVR5cGUgPT0gWE1MR3JhbW1hckRlc2NyaXB0aW9uLlhNTF9EVEQpIHsKLSAgICAgICAgICAgKytmcmVlRFREVmFsaWRhdG9ySW5kZXg7Ci0gICAgICAgICAgIGlmIChkdGRWYWxpZGF0b3JzLmxlbmd0aCA9PSBmcmVlRFREVmFsaWRhdG9ySW5kZXggKXsKLSAgICAgICAgICAgICAgICAvLyByZXNpemUgc2l6ZSBvZiB0aGUgdmFsaWRhdG9ycwotICAgICAgICAgICAgICAgIGN1cnJlbnRTaXplKz1TSVpFOwotICAgICAgICAgICAgICAgIFJldmFsaWRhdGlvbkhhbmRsZXIgbmV3YXJyYXlbXSA9ICBuZXcgUmV2YWxpZGF0aW9uSGFuZGxlcltjdXJyZW50U2l6ZV07Ci0gICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShkdGRWYWxpZGF0b3JzLCAwLCBuZXdhcnJheSwgMCwgZHRkVmFsaWRhdG9ycy5sZW5ndGgpOwotICAgICAgICAgICAgICAgIGR0ZFZhbGlkYXRvcnMgPSBuZXdhcnJheTsKLSAgICAgICAgICAgfQotICAgICAgICAgICBkdGRWYWxpZGF0b3JzW2ZyZWVEVERWYWxpZGF0b3JJbmRleF09dmFsaWRhdG9yOwotICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgLyoqIE5PTi1ET006ICBpbmNyZW1lbnQgZG9jdW1lbnQvZG9jdHlwZSBjb3VudGVyICovCi0gICAgICAgcHJvdGVjdGVkIHN5bmNocm9uaXplZCBpbnQgYXNzaWduRG9jdW1lbnROdW1iZXIoKSB7Ci0gICAgICAgICAgICByZXR1cm4gKytkb2NBbmREb2N0eXBlQ291bnRlcjsKLSAgICAgICB9Ci0gICAgICAgLyoqIE5PTi1ET006ICBpbmNyZW1lbnQgZG9jdW1lbnQvZG9jdHlwZSBjb3VudGVyICovCi0gICAgICAgcHJvdGVjdGVkIHN5bmNocm9uaXplZCBpbnQgYXNzaWduRG9jVHlwZU51bWJlcigpIHsKLSAgICAgICAgICAgIHJldHVybiArK2RvY0FuZERvY3R5cGVDb3VudGVyOwotICAgICAgIH0KLQotICAgIC8qIERPTSBMZXZlbCAzIExTIENSIC0gRXhwZXJpbWVudGFsLgotICAgICAqCi0gICAgICogQ3JlYXRlIGEgbmV3IGVtcHR5IG91dHB1dCBkZXN0aW5hdGlvbiBvYmplY3Qgd2hlcmUKLSAgICAgKiA8Y29kZT5MU091dHB1dC5jaGFyYWN0ZXJTdHJlYW08L2NvZGU+LAotICAgICAqIDxjb2RlPkxTT3V0cHV0LmJ5dGVTdHJlYW08L2NvZGU+LCA8Y29kZT5MU091dHB1dC5zeXN0ZW1JZDwvY29kZT4sCi0gICAgICogPGNvZGU+TFNPdXRwdXQuZW5jb2Rpbmc8L2NvZGU+IGFyZSBudWxsLgotCi0gICAgICogQHJldHVybiAgVGhlIG5ld2x5IGNyZWF0ZWQgb3V0cHV0IG9iamVjdC4KLSAgICAgKi8KLSAgICAgICBwdWJsaWMgTFNPdXRwdXQgY3JlYXRlTFNPdXRwdXQoKSB7Ci0gICAgICAgICAgIHJldHVybiBuZXcgRE9NT3V0cHV0SW1wbCgpOwotICAgICAgIH0KLQotfSAvLyBjbGFzcyBET01JbXBsZW1lbnRhdGlvbkltcGwKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9Db3JlRG9jdW1lbnRJbXBsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vQ29yZURvY3VtZW50SW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2NDA5NGIyLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9Db3JlRG9jdW1lbnRJbXBsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyODcwICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDksIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKi8KLS8qCi0gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKLSAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAotICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgotICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKLSAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCi0gKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5kb207Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5VUkk7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlhNTDExQ2hhcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuWE1MQ2hhcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWxzLk9iamVjdEZhY3Rvcnk7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlscy5TZWN1cml0eVN1cHBvcnQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuTmFtZXNwYWNlQ29udGV4dDsKLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotaW1wb3J0IGphdmEuaW8uT2JqZWN0SW5wdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5pby5PYmplY3RPdXRwdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5pby5PYmplY3RTdHJlYW1GaWVsZDsKLWltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3RvcjsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaHRhYmxlOwotaW1wb3J0IGphdmEudXRpbC5NYXA7Ci1pbXBvcnQgb3JnLnczYy5kb20uQXR0cjsKLWltcG9ydCBvcmcudzNjLmRvbS5DREFUQVNlY3Rpb247Ci1pbXBvcnQgb3JnLnczYy5kb20uQ29tbWVudDsKLWltcG9ydCBvcmcudzNjLmRvbS5ET01Db25maWd1cmF0aW9uOwotaW1wb3J0IG9yZy53M2MuZG9tLkRPTUV4Y2VwdGlvbjsKLWltcG9ydCBvcmcudzNjLmRvbS5ET01JbXBsZW1lbnRhdGlvbjsKLWltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKLWltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudEZyYWdtZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50VHlwZTsKLWltcG9ydCBvcmcudzNjLmRvbS5FbGVtZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLkVudGl0eTsKLWltcG9ydCBvcmcudzNjLmRvbS5FbnRpdHlSZWZlcmVuY2U7Ci1pbXBvcnQgb3JnLnczYy5kb20uTmFtZWROb2RlTWFwOwotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZUxpc3Q7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm90YXRpb247Ci1pbXBvcnQgb3JnLnczYy5kb20uUHJvY2Vzc2luZ0luc3RydWN0aW9uOwotaW1wb3J0IG9yZy53M2MuZG9tLlRleHQ7Ci1pbXBvcnQgb3JnLnczYy5kb20uVXNlckRhdGFIYW5kbGVyOwotaW1wb3J0IG9yZy53M2MuZG9tLmV2ZW50cy5FdmVudDsKLWltcG9ydCBvcmcudzNjLmRvbS5ldmVudHMuRXZlbnRMaXN0ZW5lcjsKLWltcG9ydCBvcmcudzNjLmRvbS5scy5ET01JbXBsZW1lbnRhdGlvbkxTOwotaW1wb3J0IG9yZy53M2MuZG9tLmxzLkxTU2VyaWFsaXplcjsKLQotLyoqCi0gKiBUaGUgRG9jdW1lbnQgaW50ZXJmYWNlIHJlcHJlc2VudHMgdGhlIGVudGlyZSBIVE1MIG9yIFhNTCBkb2N1bWVudC4KLSAqIENvbmNlcHR1YWxseSwgaXQgaXMgdGhlIHJvb3Qgb2YgdGhlIGRvY3VtZW50IHRyZWUsIGFuZCBwcm92aWRlcyB0aGUKLSAqIHByaW1hcnkgYWNjZXNzIHRvIHRoZSBkb2N1bWVudCdzIGRhdGEuCi0gKiA8UD4KLSAqIFNpbmNlIGVsZW1lbnRzLCB0ZXh0IG5vZGVzLCBjb21tZW50cywgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbnMsCi0gKiBldGMuIGNhbm5vdCBleGlzdCBvdXRzaWRlIHRoZSBjb250ZXh0IG9mIGEgRG9jdW1lbnQsIHRoZSBEb2N1bWVudAotICogaW50ZXJmYWNlIGFsc28gY29udGFpbnMgdGhlIGZhY3RvcnkgbWV0aG9kcyBuZWVkZWQgdG8gY3JlYXRlIHRoZXNlCi0gKiBvYmplY3RzLiBUaGUgTm9kZSBvYmplY3RzIGNyZWF0ZWQgaGF2ZSBhIG93bmVyRG9jdW1lbnQgYXR0cmlidXRlCi0gKiB3aGljaCBhc3NvY2lhdGVzIHRoZW0gd2l0aCB0aGUgRG9jdW1lbnQgd2l0aGluIHdob3NlIGNvbnRleHQgdGhleQotICogd2VyZSBjcmVhdGVkLgotICogPHA+Ci0gKiBUaGUgQ29yZURvY3VtZW50SW1wbCBjbGFzcyBvbmx5IGltcGxlbWVudHMgdGhlIERPTSBDb3JlLiBBZGRpdGlvbmFsIG1vZHVsZXMKLSAqIGFyZSBzdXBwb3J0ZWQgYnkgdGhlIG1vcmUgY29tcGxldGUgRG9jdW1lbnRJbXBsIHN1YmNsYXNzLgotICogPHA+Ci0gKiA8Yj5Ob3RlOjwvYj4gV2hlbiBhbnkgbm9kZSBpbiB0aGUgZG9jdW1lbnQgaXMgc2VyaWFsaXplZCwgdGhlCi0gKiBlbnRpcmUgZG9jdW1lbnQgaXMgc2VyaWFsaXplZCBhbG9uZyB3aXRoIGl0LgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIEFybmF1ZCAgTGUgSG9ycywgSUJNCi0gKiBAYXV0aG9yIEpvZSBLZXNzZWxtYW4sIElCTQotICogQGF1dGhvciBBbmR5IENsYXJrLCBJQk0KLSAqIEBhdXRob3IgUmFsZiBQZmVpZmZlciwgSUJNCi0gKiBAdmVyc2lvbiAkSWQ6IENvcmVEb2N1bWVudEltcGwuamF2YSx2IDEuOSAyMDEwLTExLTAxIDA0OjM5OjM3IGpvZWh3IEV4cCAkCi0gKiBAc2luY2UgIFBSLURPTS1MZXZlbC0xLTE5OTgwODE4LgotICovCi1wdWJsaWMgY2xhc3MgQ29yZURvY3VtZW50SW1wbAotICAgICAgICBleHRlbmRzIFBhcmVudE5vZGUgaW1wbGVtZW50cyBEb2N1bWVudCB7Ci0KLSAgICAvKioKLSAgICAgKiBUT0RPOjogMS4gQ2hhbmdlIFhNTDExQ2hhciBtZXRob2QgbmFtZXMgc2ltaWxhciB0byBYTUxDaGFyLiBUaGF0IHdpbGwKLSAgICAgKiBwcmV2ZW50IGxvdCBvZiBkaXJ0eSB2ZXJzaW9uIGNoZWNraW5nIGNvZGUuCi0gICAgICoKLSAgICAgKiAyLiBJTU8gZHVyaW5nIGNsb25lTm9kZSBxbmFtZS9pc1hNTE5hbWUgY2hlY2sgc2hvdWxkIG5vdCBiZSBtYWRlLgotICAgICAqLwotICAgIC8vCi0gICAgLy8gQ29uc3RhbnRzCi0gICAgLy8KLQotICAgIC8qKiBTZXJpYWxpemF0aW9uIHZlcnNpb24uICovCi0gICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDA7Ci0KLSAgICAvLwotICAgIC8vIERhdGEKLSAgICAvLwotCi0gICAgLy8gZG9jdW1lbnQgaW5mb3JtYXRpb24KLQotICAgIC8qKiBEb2N1bWVudCB0eXBlLiAqLwotICAgIHByb3RlY3RlZCBEb2N1bWVudFR5cGVJbXBsIGRvY1R5cGU7Ci0KLSAgICAvKiogRG9jdW1lbnQgZWxlbWVudC4gKi8KLSAgICBwcm90ZWN0ZWQgRWxlbWVudEltcGwgZG9jRWxlbWVudDsKLQotICAgIC8qKiBOb2RlTGlzdENhY2hlIGZyZWUgbGlzdCAqLwotICAgIHRyYW5zaWVudCBOb2RlTGlzdENhY2hlIGZGcmVlTkxDYWNoZTsKLQotICAgIC8qKkV4cGVyaW1lbnRhbCBET00gTGV2ZWwgMyBmZWF0dXJlOiBEb2N1bWVudCBlbmNvZGluZyAqLwotICAgIHByb3RlY3RlZCBTdHJpbmcgZW5jb2Rpbmc7Ci0KLSAgICAvKipFeHBlcmltZW50YWwgRE9NIExldmVsIDMgZmVhdHVyZTogRG9jdW1lbnQgYWN0dWFsRW5jb2RpbmcgKi8KLSAgICBwcm90ZWN0ZWQgU3RyaW5nIGFjdHVhbEVuY29kaW5nOwotCi0gICAgLyoqRXhwZXJpbWVudGFsIERPTSBMZXZlbCAzIGZlYXR1cmU6IERvY3VtZW50IHZlcnNpb24gKi8KLSAgICBwcm90ZWN0ZWQgU3RyaW5nIHZlcnNpb247Ci0KLSAgICAvKipFeHBlcmltZW50YWwgRE9NIExldmVsIDMgZmVhdHVyZTogRG9jdW1lbnQgc3RhbmRhbG9uZSAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIHN0YW5kYWxvbmU7Ci0KLSAgICAvKipFeHBlcmltZW50YWwgRE9NIExldmVsIDMgZmVhdHVyZTogZG9jdW1lbnRVUkkgKi8KLSAgICBwcm90ZWN0ZWQgU3RyaW5nIGZEb2N1bWVudFVSSTsKLQotICAgIC8vUmV2aXNpdCA6OiBjaGFuZ2UgdG8gYSBiZXR0ZXIgZGF0YSBzdHJ1Y3R1cmUuCi0gICAgLyoqIFRhYmxlIGZvciB1c2VyIGRhdGEgYXR0YWNoZWQgdG8gdGhpcyBkb2N1bWVudCBub2Rlcy4gKi8KLSAgICBwcml2YXRlIE1hcDxOb2RlLCBNYXA8U3RyaW5nLCBVc2VyRGF0YVJlY29yZD4+IG5vZGVVc2VyRGF0YTsKLQotICAgIC8qKiBJZGVudGlmaWVycy4gKi8KLSAgICBwcm90ZWN0ZWQgTWFwPFN0cmluZywgTm9kZT4gaWRlbnRpZmllcnM7Ci0KLSAgICAvLyBET00gTGV2ZWwgMzogbm9ybWFsaXplRG9jdW1lbnQKLSAgICB0cmFuc2llbnQgRE9NTm9ybWFsaXplciBkb21Ob3JtYWxpemVyID0gbnVsbDsKLSAgICB0cmFuc2llbnQgRE9NQ29uZmlndXJhdGlvbkltcGwgZkNvbmZpZ3VyYXRpb24gPSBudWxsOwotCi0gICAgLy8gc3VwcG9ydCBvZiBYUGF0aCBBUEkKLSAgICB0cmFuc2llbnQgT2JqZWN0IGZYUGF0aEV2YWx1YXRvciA9IG51bGw7Ci0KLSAgICAvKiogVGFibGUgZm9yIHF1aWNrIGNoZWNrIG9mIGNoaWxkIGluc2VydGlvbi4gKi8KLSAgICBwcml2YXRlIGZpbmFsIHN0YXRpYyBpbnRbXSBraWRPSzsKLQotICAgIC8qKgotICAgICAqIE51bWJlciBvZiBhbHRlcmF0aW9ucyBtYWRlIHRvIHRoaXMgZG9jdW1lbnQgc2luY2UgaXRzIGNyZWF0aW9uLgotICAgICAqIFNlcnZlcyBhcyBhICJkaXJ0eSBiaXQiIHNvIHRoYXQgbGl2ZSBvYmplY3RzIHN1Y2ggYXMgTm9kZUxpc3QgY2FuCi0gICAgICogcmVjb2duaXplIHdoZW4gYW4gYWx0ZXJhdGlvbiBoYXMgYmVlbiBtYWRlIGFuZCBkaXNjYXJkIGl0cyBjYWNoZWQKLSAgICAgKiBzdGF0ZSBpbmZvcm1hdGlvbi4KLSAgICAgKiA8cD4KLSAgICAgKiBBbnkgbWV0aG9kIHRoYXQgYWx0ZXJzIHRoZSB0cmVlIHN0cnVjdHVyZSBNVVNUIGNhdXNlIG9yIGJlCi0gICAgICogYWNjb21wYW5pZWQgYnkgYSBjYWxsIHRvIGNoYW5nZWQoKSwgdG8gaW5mb3JtIGl0IHRoYXQgYW55IG91dHN0YW5kaW5nCi0gICAgICogTm9kZUxpc3RzIG1heSBoYXZlIHRvIGJlIHVwZGF0ZWQuCi0gICAgICogPHA+Ci0gICAgICogKFJlcXVpcmVkIGJlY2F1c2UgTm9kZUxpc3QgaXMgc2ltdWx0YW5lb3VzbHkgImxpdmUiIGFuZCBpbnRlZ2VyLQotICAgICAqIGluZGV4ZWQgLS0gYSBiYWQgZGVjaXNpb24gaW4gdGhlIERPTSdzIGRlc2lnbi4pCi0gICAgICogPHA+Ci0gICAgICogTm90ZSB0aGF0IGNoYW5nZXMgd2hpY2ggZG8gbm90IGFmZmVjdCB0aGUgdHJlZSdzIHN0cnVjdHVyZSAtLSBjaGFuZ2luZwotICAgICAqIHRoZSBub2RlJ3MgbmFtZSwgZm9yIGV4YW1wbGUgLS0gZG8gX25vdF8gaGF2ZSB0byBjYWxsIGNoYW5nZWQoKS4KLSAgICAgKiA8cD4KLSAgICAgKiBBbHRlcm5hdGl2ZSBpbXBsZW1lbnRhdGlvbiB3b3VsZCBiZSB0byB1c2UgYSBjcnlwdG9ncmFwaGljCi0gICAgICogRGlnZXN0IHZhbHVlIHJhdGhlciB0aGFuIGEgY291bnQuIFRoaXMgd291bGQgaGF2ZSB0aGUgYWR2YW50YWdlIHRoYXQKLSAgICAgKiAiaGFybWxlc3MiIGNoYW5nZXMgKHRob3NlIHByb2R1Y2luZyBlcXVhbCgpIHRyZWVzKSB3b3VsZCBub3QgZm9yY2UKLSAgICAgKiBOb2RlTGlzdCB0byByZXN5bmNocm9uaXplLiBEaXNhZHZhbnRhZ2UgaXMgdGhhdCBpdCdzIHNsaWdodGx5IG1vcmUgcHJvbmUKLSAgICAgKiB0byAiZmFsc2UgbmVnYXRpdmVzIiwgdGhvdWdoIHRoYXQncyB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuICJ3aWxkbHkKLSAgICAgKiB1bmxpa2VseSIgYW5kICJhYnN1cmRseSB1bmxpa2VseSIuIElGIHdlIHN0YXJ0IG1haW50YWluaW5nIGRpZ2VzdHMsCi0gICAgICogd2Ugc2hvdWxkIGNvbnNpZGVyIHRha2luZyBhZHZhbnRhZ2Ugb2YgdGhlbS4KLSAgICAgKgotICAgICAqIE5vdGU6IFRoaXMgdXNlZCB0byBiZSBkb25lIGEgbm9kZSBiYXNpcywgc28gdGhhdCB3ZSBrbmV3IHdoYXQKLSAgICAgKiBzdWJ0cmVlIGNoYW5nZWQuIEJ1dCBzaW5jZSBvbmx5IERlZXBOb2RlTGlzdCByZWFsbHkgdXNlIHRoaXMgdG9kYXksCi0gICAgICogdGhlIGdhaW4gYXBwZWFycyB0byBiZSByZWFsbHkgc21hbGwgY29tcGFyZWQgdG8gdGhlIGNvc3Qgb2YgaGF2aW5nCi0gICAgICogYW4gaW50IG9uIGV2ZXJ5IChwYXJlbnQpIG5vZGUgcGx1cyBoYXZpbmcgdG8gd2FsayB1cCB0aGUgdHJlZSBhbGwgdGhlCi0gICAgICogd2F5IHRvIHRoZSByb290IHRvIG1hcmsgdGhlIGJyYW5jaCBhcyBjaGFuZ2VkIGV2ZXJ5dGltZSBhIG5vZGUgaXMKLSAgICAgKiBjaGFuZ2VkLgotICAgICAqIFNvIHdlIG5vdyBoYXZlIGEgc2luZ2xlIGNvdW50ZXIgZ2xvYmFsIHRvIHRoZSBkb2N1bWVudC4gSXQgbWVhbnMgdGhhdAotICAgICAqIHNvbWUgb2JqZWN0cyBtYXkgZmx1c2ggdGhlaXIgY2FjaGUgbW9yZSBvZnRlbiB0aGFuIG5lY2Vzc2FyeSwgYnV0IHRoaXMKLSAgICAgKiBtYWtlcyBub2RlcyBzbWFsbGVyIGFuZCBvbmx5IHRoZSBkb2N1bWVudCBuZWVkcyB0byBiZSBtYXJrZWQgYXMgY2hhbmdlZC4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgaW50IGNoYW5nZXMgPSAwOwotCi0gICAgLy8gZXhwZXJpbWVudGFsCi0KLSAgICAvKiogQWxsb3cgZ3JhbW1hciBhY2Nlc3MuICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gYWxsb3dHcmFtbWFyQWNjZXNzOwotCi0gICAgLyoqIEJ5cGFzcyBlcnJvciBjaGVja2luZy4gKi8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBlcnJvckNoZWNraW5nID0gdHJ1ZTsKLSAgICAvKiogQW5jZXN0b3IgY2hlY2tpbmcgKi8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBhbmNlc3RvckNoZWNraW5nID0gdHJ1ZTsKLQotICAgIC8vRGlkIHZlcnNpb24gY2hhbmdlIGF0IGFueSBwb2ludCB3aGVuIHRoZSBkb2N1bWVudCB3YXMgY3JlYXRlZCA/Ci0gICAgLy90aGlzIGZpZWxkIGhlbHBzIHVzIHRvIG9wdGltaXplIHdoZW4gbm9ybWFsaXppbmdEb2N1bWVudC4KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiB4bWxWZXJzaW9uQ2hhbmdlZCA9IGZhbHNlIDsKLQotICAgIC8qKiBUaGUgZm9sbG93aW5nIGFyZSByZXF1aXJlZCBmb3IgY29tcGFyZURvY3VtZW50UG9zaXRpb24KLSAgICAgKi8KLSAgICAvLyBEb2N1bWVudCBudW1iZXIuICAgRG9jdW1lbnRzIGFyZSBvcmRlcmVkIGFjcm9zcyB0aGUgaW1wbGVtZW50YXRpb24gdXNpbmcKLSAgICAvLyBwb3NpdGl2ZSBpbnRlZ2VyIHZhbHVlcy4gIERvY3VtZW50cyBhcmUgYXNzaWduZWQgbnVtYmVycyBvbiBkZW1hbmQuCi0gICAgcHJpdmF0ZSBpbnQgZG9jdW1lbnROdW1iZXI9MDsKLSAgICAvLyBOb2RlIGNvdW50ZXIgYW5kIHRhYmxlLiAgVXNlZCB0byBhc3NpZ24gbnVtYmVycyB0byBub2RlcyBmb3IgdGhpcwotICAgIC8vIGRvY3VtZW50LiAgTm9kZSBudW1iZXIgdmFsdWVzIGFyZSBuZWdhdGl2ZSBpbnRlZ2Vycy4gIE5vZGVzIGFyZQotICAgIC8vIGFzc2lnbmVkIG51bWJlcnMgb24gZGVtYW5kLgotICAgIHByaXZhdGUgaW50IG5vZGVDb3VudGVyID0gMDsKLSAgICBwcml2YXRlIE1hcDxOb2RlLCBJbnRlZ2VyPiBub2RlVGFibGU7Ci0gICAgcHJpdmF0ZSBib29sZWFuIHhtbDExVmVyc2lvbiA9IGZhbHNlOyAvL2J5IGRlZmF1bHQgMS4wCi0gICAgLy8KLSAgICAvLyBTdGF0aWMgaW5pdGlhbGl6YXRpb24KLSAgICAvLwotCi0gICAgc3RhdGljIHsKLQotICAgICAgICBraWRPSyA9IG5ldyBpbnRbMTNdOwotCi0gICAgICAgIGtpZE9LW0RPQ1VNRU5UX05PREVdID0KLSAgICAgICAgMSA8PCBFTEVNRU5UX05PREUgfCAxIDw8IFBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERSB8Ci0gICAgICAgIDEgPDwgQ09NTUVOVF9OT0RFIHwgMSA8PCBET0NVTUVOVF9UWVBFX05PREU7Ci0KLSAgICAgICAga2lkT0tbRE9DVU1FTlRfRlJBR01FTlRfTk9ERV0gPQotICAgICAgICBraWRPS1tFTlRJVFlfTk9ERV0gPQotICAgICAgICBraWRPS1tFTlRJVFlfUkVGRVJFTkNFX05PREVdID0KLSAgICAgICAga2lkT0tbRUxFTUVOVF9OT0RFXSA9Ci0gICAgICAgIDEgPDwgRUxFTUVOVF9OT0RFIHwgMSA8PCBQUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREUgfAotICAgICAgICAxIDw8IENPTU1FTlRfTk9ERSB8IDEgPDwgVEVYVF9OT0RFIHwKLSAgICAgICAgMSA8PCBDREFUQV9TRUNUSU9OX05PREUgfCAxIDw8IEVOVElUWV9SRUZFUkVOQ0VfTk9ERSA7Ci0KLQotICAgICAgICBraWRPS1tBVFRSSUJVVEVfTk9ERV0gPQotICAgICAgICAxIDw8IFRFWFRfTk9ERSB8IDEgPDwgRU5USVRZX1JFRkVSRU5DRV9OT0RFOwotCi0gICAgICAgIGtpZE9LW0RPQ1VNRU5UX1RZUEVfTk9ERV0gPQotICAgICAgICBraWRPS1tQUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREVdID0KLSAgICAgICAga2lkT0tbQ09NTUVOVF9OT0RFXSA9Ci0gICAgICAgIGtpZE9LW1RFWFRfTk9ERV0gPQotICAgICAgICBraWRPS1tDREFUQV9TRUNUSU9OX05PREVdID0KLSAgICAgICAga2lkT0tbTk9UQVRJT05fTk9ERV0gPQotICAgICAgICAwOwotCi0gICAgfSAvLyBzdGF0aWMKLQotICAgIC8qKgotICAgICAqIEBzZXJpYWxGaWVsZCBkb2NUeXBlIERvY3VtZW50VHlwZUltcGwgZG9jdW1lbnQgdHlwZQotICAgICAqIEBzZXJpYWxGaWVsZCBkb2NFbGVtZW50IEVsZW1lbnRJbXBsIGRvY3VtZW50IGVsZW1lbnQKLSAgICAgKiBAc2VyaWFsRmllbGQgZkZyZWVOTENhY2hlIE5vZGVMaXN0Q2FjaGUgTm9kZUxpc3RDYWNoZSBmcmVlIGxpc3QKLSAgICAgKiBAc2VyaWFsRmllbGQgZW5jb2RpbmcgU3RyaW5nIERvY3VtZW50IGVuY29kaW5nCi0gICAgICogQHNlcmlhbEZpZWxkIGFjdHVhbEVuY29kaW5nIFN0cmluZyBEb2N1bWVudCBhY3R1YWxFbmNvZGluZwotICAgICAqIEBzZXJpYWxGaWVsZCB2ZXJzaW9uIFN0cmluZyBEb2N1bWVudCB2ZXJzaW9uCi0gICAgICogQHNlcmlhbEZpZWxkIHN0YW5kYWxvbmUgYm9vbGVhbiBEb2N1bWVudCBzdGFuZGFsb25lCi0gICAgICogQHNlcmlhbEZpZWxkIGZEb2N1bWVudFVSSSBTdHJpbmcgRG9jdW1lbnQgVVJJCi0gICAgICogQHNlcmlhbEZpZWxkIHVzZXJEYXRhIEhhc2h0YWJsZSB1c2VyIGRhdGEgYXR0YWNoZWQgdG8gdGhlIG5vZGVzLiBOb3RlIHRoYXQKLSAgICAgKiBpdCB3YXMgb3JpZ2luYWwgY2FsbGVkICJ1c2VyRGF0YSIuIEl0IGhhcyBiZWVuIGNoYW5nZWQgdG8gbm9kZVVzZXJEYXRhIHRvCi0gICAgICogYXZvaWQgY29uZnVzaW9uIHdpdGggdGhvc2UgdGhhdCBhcmUgYWN0dWFsbHkgdmFsdWVzIG9mIHRoZSBtYXAuCi0gICAgICogQHNlcmlhbEZpZWxkIGlkZW50aWZpZXJzIEhhc2h0YWJsZSBpZGVudGlmaWVycwotICAgICAqIEBzZXJpYWxGaWVsZCBjaGFuZ2VzIGludCBmbGFnIGluZGljYXRlcyB3aGV0aGVyIHRoZSBub2RlIGhhcyBjaGFuZ2VkCi0gICAgICogQHNlcmlhbEZpZWxkIGFsbG93R3JhbW1hckFjY2VzcyBib29sZWFuIEFsbG93IGdyYW1tYXIgYWNjZXNzCi0gICAgICogQHNlcmlhbEZpZWxkIGVycm9yQ2hlY2tpbmcgYm9vbGVhbiBCeXBhc3MgZXJyb3IgY2hlY2tpbmcKLSAgICAgKiBAc2VyaWFsRmllbGQgYW5jZXN0b3JDaGVja2luZyBib29sZWFuIEFuY2VzdG9yIGNoZWNraW5nCi0gICAgICogQHNlcmlhbEZpZWxkIHhtbFZlcnNpb25DaGFuZ2VkIGJvb2xlYW4gSW5kaWNhdGUgd2hldGhlciB0aGUgdmVyc2lvbiBoYXMgY2hhbmdlZAotICAgICAqIEBzZXJpYWxGaWVsZCBkb2N1bWVudE51bWJlciBpbnQgRG9jdW1lbnQgbnVtYmVyCi0gICAgICogQHNlcmlhbEZpZWxkIG5vZGVDb3VudGVyIGludCBOb2RlIGNvdW50ZXIKLSAgICAgKiBAc2VyaWFsRmllbGQgbm9kZVRhYmxlIEhhc2h0YWJsZSBOb2RlIHRhYmxlCi0gICAgICogQHNlcmlhbEZpZWxkIHhtbDExVmVyc2lvbiBib29sZWFuIFhNTCB2ZXJzaW9uCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgT2JqZWN0U3RyZWFtRmllbGRbXSBzZXJpYWxQZXJzaXN0ZW50RmllbGRzID0KLSAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkW10gewotICAgICAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJkb2NUeXBlIiwgRG9jdW1lbnRUeXBlSW1wbC5jbGFzcyksCi0gICAgICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoImRvY0VsZW1lbnQiLCBFbGVtZW50SW1wbC5jbGFzcyksCi0gICAgICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoImZGcmVlTkxDYWNoZSIsIE5vZGVMaXN0Q2FjaGUuY2xhc3MpLAotICAgICAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJlbmNvZGluZyIsIFN0cmluZy5jbGFzcyksCi0gICAgICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoImFjdHVhbEVuY29kaW5nIiwgU3RyaW5nLmNsYXNzKSwKLSAgICAgICAgICAgIG5ldyBPYmplY3RTdHJlYW1GaWVsZCgidmVyc2lvbiIsIFN0cmluZy5jbGFzcyksCi0gICAgICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoInN0YW5kYWxvbmUiLCBib29sZWFuLmNsYXNzKSwKLSAgICAgICAgICAgIG5ldyBPYmplY3RTdHJlYW1GaWVsZCgiZkRvY3VtZW50VVJJIiwgU3RyaW5nLmNsYXNzKSwKLSAgICAgICAgICAgIG5ldyBPYmplY3RTdHJlYW1GaWVsZCgidXNlckRhdGEiLCBIYXNodGFibGUuY2xhc3MpLAotICAgICAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJpZGVudGlmaWVycyIsIEhhc2h0YWJsZS5jbGFzcyksCi0gICAgICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoImNoYW5nZXMiLCBpbnQuY2xhc3MpLAotICAgICAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJhbGxvd0dyYW1tYXJBY2Nlc3MiLCBib29sZWFuLmNsYXNzKSwKLSAgICAgICAgICAgIG5ldyBPYmplY3RTdHJlYW1GaWVsZCgiZXJyb3JDaGVja2luZyIsIGJvb2xlYW4uY2xhc3MpLAotICAgICAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJhbmNlc3RvckNoZWNraW5nIiwgYm9vbGVhbi5jbGFzcyksCi0gICAgICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoInhtbFZlcnNpb25DaGFuZ2VkIiwgYm9vbGVhbi5jbGFzcyksCi0gICAgICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoImRvY3VtZW50TnVtYmVyIiwgaW50LmNsYXNzKSwKLSAgICAgICAgICAgIG5ldyBPYmplY3RTdHJlYW1GaWVsZCgibm9kZUNvdW50ZXIiLCBpbnQuY2xhc3MpLAotICAgICAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJub2RlVGFibGUiLCBIYXNodGFibGUuY2xhc3MpLAotICAgICAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJ4bWwxMVZlcnNpb24iLCBib29sZWFuLmNsYXNzKSwKLSAgICAgICAgfTsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIE5PTi1ET006IEFjdHVhbGx5IGNyZWF0aW5nIGEgRG9jdW1lbnQgaXMgb3V0c2lkZSB0aGUgRE9NJ3Mgc3BlYywKLSAgICAgKiBzaW5jZSBpdCBoYXMgdG8gb3BlcmF0ZSBpbiB0ZXJtcyBvZiBhIHBhcnRpY3VsYXIgaW1wbGVtZW50YXRpb24uCi0gICAgICovCi0gICAgcHVibGljIENvcmVEb2N1bWVudEltcGwoKSB7Ci0gICAgICAgIHRoaXMoZmFsc2UpOwotICAgIH0KLQotICAgIC8qKiBDb25zdHJ1Y3Rvci4gKi8KLSAgICBwdWJsaWMgQ29yZURvY3VtZW50SW1wbChib29sZWFuIGdyYW1tYXJBY2Nlc3MpIHsKLSAgICAgICAgc3VwZXIobnVsbCk7Ci0gICAgICAgIG93bmVyRG9jdW1lbnQgPSB0aGlzOwotICAgICAgICBhbGxvd0dyYW1tYXJBY2Nlc3MgPSBncmFtbWFyQWNjZXNzOwotICAgICAgICBTdHJpbmcgc3lzdGVtUHJvcCA9IFNlY3VyaXR5U3VwcG9ydC5nZXRTeXN0ZW1Qcm9wZXJ0eShDb25zdGFudHMuU1VOX0RPTV9QUk9QRVJUWV9QUkVGSVgrQ29uc3RhbnRzLlNVTl9ET01fQU5DRVNUT1JfQ0hFQ0NLKTsKLSAgICAgICAgaWYgKHN5c3RlbVByb3AgIT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKHN5c3RlbVByb3AuZXF1YWxzSWdub3JlQ2FzZSgiZmFsc2UiKSkgewotICAgICAgICAgICAgICAgIGFuY2VzdG9yQ2hlY2tpbmcgPSBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEZvciBET00yIHN1cHBvcnQuCi0gICAgICogVGhlIGNyZWF0ZURvY3VtZW50IGZhY3RvcnkgbWV0aG9kIGlzIGluIERPTUltcGxlbWVudGF0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBDb3JlRG9jdW1lbnRJbXBsKERvY3VtZW50VHlwZSBkb2N0eXBlKSB7Ci0gICAgICAgIHRoaXMoZG9jdHlwZSwgZmFsc2UpOwotICAgIH0KLQotICAgIC8qKiBGb3IgRE9NMiBzdXBwb3J0LiAqLwotICAgIHB1YmxpYyBDb3JlRG9jdW1lbnRJbXBsKERvY3VtZW50VHlwZSBkb2N0eXBlLCBib29sZWFuIGdyYW1tYXJBY2Nlc3MpIHsKLSAgICAgICAgdGhpcyhncmFtbWFyQWNjZXNzKTsKLSAgICAgICAgaWYgKGRvY3R5cGUgIT0gbnVsbCkgewotICAgICAgICAgICAgRG9jdW1lbnRUeXBlSW1wbCBkb2N0eXBlSW1wbDsKLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgZG9jdHlwZUltcGwgPSAoRG9jdW1lbnRUeXBlSW1wbCkgZG9jdHlwZTsKLSAgICAgICAgICAgIH0gY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIG1zZyA9IERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sICJXUk9OR19ET0NVTUVOVF9FUlIiLCBudWxsKTsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5XUk9OR19ET0NVTUVOVF9FUlIsIG1zZyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBkb2N0eXBlSW1wbC5vd25lckRvY3VtZW50ID0gdGhpczsKLSAgICAgICAgICAgIGFwcGVuZENoaWxkKGRvY3R5cGUpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLy8KLSAgICAvLyBOb2RlIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLy8gZXZlbiB0aG91Z2ggb3duZXJEb2N1bWVudCByZWZlcnMgdG8gdGhpcyBpbiB0aGlzIGltcGxlbWVudGF0aW9uCi0gICAgLy8gdGhlIERPTSBMZXZlbCAyIHNwZWMgc2F5cyBpdCBtdXN0IGJlIG51bGwsIHNvIG1ha2UgaXQgYXBwZWFyIHNvCi0gICAgZmluYWwgcHVibGljIERvY3VtZW50IGdldE93bmVyRG9jdW1lbnQoKSB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKiBSZXR1cm5zIHRoZSBub2RlIHR5cGUuICovCi0gICAgcHVibGljIHNob3J0IGdldE5vZGVUeXBlKCkgewotICAgICAgICByZXR1cm4gTm9kZS5ET0NVTUVOVF9OT0RFOwotICAgIH0KLQotICAgIC8qKiBSZXR1cm5zIHRoZSBub2RlIG5hbWUuICovCi0gICAgcHVibGljIFN0cmluZyBnZXROb2RlTmFtZSgpIHsKLSAgICAgICAgcmV0dXJuICIjZG9jdW1lbnQiOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIERlZXAtY2xvbmUgYSBkb2N1bWVudCwgaW5jbHVkaW5nIGZpeGluZyBvd25lckRvYyBmb3IgdGhlIGNsb25lZAotICAgICAqIGNoaWxkcmVuLiBOb3RlIHRoYXQgdGhpcyByZXF1aXJlcyBieXBhc3NpbmcgdGhlIFdST05HX0RPQ1VNRU5UX0VSUgotICAgICAqIHByb3RlY3Rpb24uIEkndmUgY2hvc2VuIHRvIGltcGxlbWVudCBpdCBieSBjYWxsaW5nIGltcG9ydE5vZGUKLSAgICAgKiB3aGljaCBpcyBET00gTGV2ZWwgMi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gb3JnLnczYy5kb20uTm9kZQotICAgICAqIEBwYXJhbSBkZWVwIGJvb2xlYW4sIGlmZiB0cnVlIHJlcGxpY2F0ZSBjaGlsZHJlbgotICAgICAqLwotICAgIHB1YmxpYyBOb2RlIGNsb25lTm9kZShib29sZWFuIGRlZXApIHsKLQotICAgICAgICBDb3JlRG9jdW1lbnRJbXBsIG5ld2RvYyA9IG5ldyBDb3JlRG9jdW1lbnRJbXBsKCk7Ci0gICAgICAgIGNhbGxVc2VyRGF0YUhhbmRsZXJzKHRoaXMsIG5ld2RvYywgVXNlckRhdGFIYW5kbGVyLk5PREVfQ0xPTkVEKTsKLSAgICAgICAgY2xvbmVOb2RlKG5ld2RvYywgZGVlcCk7Ci0KLSAgICAgICAgcmV0dXJuIG5ld2RvYzsKLQotICAgIH0gLy8gY2xvbmVOb2RlKGJvb2xlYW4pOk5vZGUKLQotCi0gICAgLyoqCi0gICAgICogaW50ZXJuYWwgbWV0aG9kIHRvIHNoYXJlIGNvZGUgd2l0aCBzdWJjbGFzcwotICAgICAqKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCBjbG9uZU5vZGUoQ29yZURvY3VtZW50SW1wbCBuZXdkb2MsIGJvb2xlYW4gZGVlcCkgewotCi0gICAgICAgIC8vIGNsb25lIHRoZSBjaGlsZHJlbiBieSBpbXBvcnRpbmcgdGhlbQotICAgICAgICBpZiAobmVlZHNTeW5jQ2hpbGRyZW4oKSkgewotICAgICAgICAgICAgc3luY2hyb25pemVDaGlsZHJlbigpOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKGRlZXApIHsKLSAgICAgICAgICAgIE1hcDxOb2RlLCBTdHJpbmc+IHJldmVyc2VkSWRlbnRpZmllcnMgPSBudWxsOwotCi0gICAgICAgICAgICBpZiAoaWRlbnRpZmllcnMgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIC8vIEJ1aWxkIGEgcmV2ZXJzZSBtYXBwaW5nIGZyb20gZWxlbWVudCB0byBpZGVudGlmaWVyLgotICAgICAgICAgICAgICAgIHJldmVyc2VkSWRlbnRpZmllcnMgPSBuZXcgSGFzaE1hcDw+KGlkZW50aWZpZXJzLnNpemUoKSk7Ci0gICAgICAgICAgICAgICAgZm9yIChTdHJpbmcgZWxlbWVudElkIDogaWRlbnRpZmllcnMua2V5U2V0KCkpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV2ZXJzZWRJZGVudGlmaWVycy5wdXQoaWRlbnRpZmllcnMuZ2V0KGVsZW1lbnRJZCksIGVsZW1lbnRJZCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBDb3B5IGNoaWxkcmVuIGludG8gbmV3IGRvY3VtZW50LgotICAgICAgICAgICAgZm9yIChDaGlsZE5vZGUga2lkID0gZmlyc3RDaGlsZDsga2lkICE9IG51bGw7Ci0gICAgICAgICAgICAgICAgICAgIGtpZCA9IGtpZC5uZXh0U2libGluZykgewotICAgICAgICAgICAgICAgIG5ld2RvYy5hcHBlbmRDaGlsZChuZXdkb2MuaW1wb3J0Tm9kZShraWQsIHRydWUsIHRydWUsCi0gICAgICAgICAgICAgICAgICAgICAgICByZXZlcnNlZElkZW50aWZpZXJzKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBleHBlcmltZW50YWwKLSAgICAgICAgbmV3ZG9jLmFsbG93R3JhbW1hckFjY2VzcyA9IGFsbG93R3JhbW1hckFjY2VzczsKLSAgICAgICAgbmV3ZG9jLmVycm9yQ2hlY2tpbmcgPSBlcnJvckNoZWNraW5nOwotCi0gICAgfSAvLyBjbG9uZU5vZGUoQ29yZURvY3VtZW50SW1wbCxib29sZWFuKTp2b2lkCi0KLSAgICAvKioKLSAgICAgKiBTaW5jZSBhIERvY3VtZW50IG1heSBjb250YWluIGF0IG1vc3Qgb25lIHRvcC1sZXZlbCBFbGVtZW50IGNoaWxkLAotICAgICAqIGFuZCBhdCBtb3N0IG9uZSBEb2N1bWVudFR5cGUgZGVjbGFyYWN0aW9uLCB3ZSBuZWVkIHRvIHN1YmNsYXNzIG91cgotICAgICAqIGFkZC1jaGlsZHJlbiBtZXRob2RzIHRvIGltcGxlbWVudCB0aGlzIGNvbnN0cmFpbnQuCi0gICAgICogU2luY2UgYXBwZW5kQ2hpbGQoKSBpcyBpbXBsZW1lbnRlZCBhcyBpbnNlcnRCZWZvcmUoLG51bGwpLAotICAgICAqIGFsdGVyaW5nIHRoZSBsYXR0ZXIgZml4ZXMgYm90aC4KLSAgICAgKiA8cD4KLSAgICAgKiBXaGlsZSBJJ20gZG9pbmcgc28sIEkndmUgdGFrZW4gYWR2YW50YWdlIG9mIHRoZSBvcHBvcnR1bml0eSB0bwotICAgICAqIGNhY2hlIGRvY3VtZW50RWxlbWVudCBhbmQgZG9jVHlwZSBzbyB3ZSBkb24ndCBoYXZlIHRvCi0gICAgICogc2VhcmNoIGZvciB0aGVtLgotICAgICAqCi0gICAgICogUkVWSVNJVDogQWNjb3JkaW5nIHRvIHRoZSBzcGVjIGl0IGlzIG5vdCBhbGxvd2VkIHRvIGFsdGVyIG5laXRoZXIgdGhlCi0gICAgICogZG9jdW1lbnQgZWxlbWVudCBub3IgdGhlIGRvY3VtZW50IHR5cGUgaW4gYW55IHdheQotICAgICAqLwotICAgIHB1YmxpYyBOb2RlIGluc2VydEJlZm9yZShOb2RlIG5ld0NoaWxkLCBOb2RlIHJlZkNoaWxkKQotICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy8gT25seSBvbmUgc3VjaCBjaGlsZCBwZXJtaXR0ZWQKLSAgICAgICAgaW50IHR5cGUgPSBuZXdDaGlsZC5nZXROb2RlVHlwZSgpOwotICAgICAgICBpZiAoZXJyb3JDaGVja2luZykgewotICAgICAgICAgICAgaWYoKHR5cGUgPT0gTm9kZS5FTEVNRU5UX05PREUgJiYgZG9jRWxlbWVudCAhPSBudWxsKSB8fAotICAgICAgICAgICAgKHR5cGUgPT0gTm9kZS5ET0NVTUVOVF9UWVBFX05PREUgJiYgZG9jVHlwZSAhPSBudWxsKSkgewotICAgICAgICAgICAgICAgIFN0cmluZyBtc2cgPSBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiSElFUkFSQ0hZX1JFUVVFU1RfRVJSIiwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uSElFUkFSQ0hZX1JFUVVFU1RfRVJSLCBtc2cpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIC8vIEFkb3B0IG9ycGhhbiBkb2N0eXBlcwotICAgICAgICBpZiAobmV3Q2hpbGQuZ2V0T3duZXJEb2N1bWVudCgpID09IG51bGwgJiYKLSAgICAgICAgbmV3Q2hpbGQgaW5zdGFuY2VvZiBEb2N1bWVudFR5cGVJbXBsKSB7Ci0gICAgICAgICAgICAoKERvY3VtZW50VHlwZUltcGwpIG5ld0NoaWxkKS5vd25lckRvY3VtZW50ID0gdGhpczsKLSAgICAgICAgfQotICAgICAgICBzdXBlci5pbnNlcnRCZWZvcmUobmV3Q2hpbGQscmVmQ2hpbGQpOwotCi0gICAgICAgIC8vIElmIGluc2VydCBzdWNjZWVkZWQsIGNhY2hlIHRoZSBraWQgYXBwcm9wcmlhdGVseQotICAgICAgICBpZiAodHlwZSA9PSBOb2RlLkVMRU1FTlRfTk9ERSkgewotICAgICAgICAgICAgZG9jRWxlbWVudCA9IChFbGVtZW50SW1wbCluZXdDaGlsZDsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICh0eXBlID09IE5vZGUuRE9DVU1FTlRfVFlQRV9OT0RFKSB7Ci0gICAgICAgICAgICBkb2NUeXBlID0gKERvY3VtZW50VHlwZUltcGwpbmV3Q2hpbGQ7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gbmV3Q2hpbGQ7Ci0KLSAgICB9IC8vIGluc2VydEJlZm9yZShOb2RlLE5vZGUpOk5vZGUKLQotICAgIC8qKgotICAgICAqIFNpbmNlIGluc2VydEJlZm9yZSBjYWNoZXMgdGhlIGRvY0VsZW1lbnQgKGFuZCwgY3VycmVudGx5LCBkb2NUeXBlKSwKLSAgICAgKiByZW1vdmVDaGlsZCBoYXMgdG8ga25vdyBob3cgdG8gdW5kbyB0aGUgY2FjaGUKLSAgICAgKgotICAgICAqIFJFVklTSVQ6IEFjY29yZGluZyB0byB0aGUgc3BlYyBpdCBpcyBub3QgYWxsb3dlZCB0byBhbHRlciBuZWl0aGVyIHRoZQotICAgICAqIGRvY3VtZW50IGVsZW1lbnQgbm9yIHRoZSBkb2N1bWVudCB0eXBlIGluIGFueSB3YXkKLSAgICAgKi8KLSAgICBwdWJsaWMgTm9kZSByZW1vdmVDaGlsZChOb2RlIG9sZENoaWxkKSB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKLQotICAgICAgICBzdXBlci5yZW1vdmVDaGlsZChvbGRDaGlsZCk7Ci0KLSAgICAgICAgLy8gSWYgcmVtb3ZlIHN1Y2NlZWRlZCwgdW4tY2FjaGUgdGhlIGtpZCBhcHByb3ByaWF0ZWx5Ci0gICAgICAgIGludCB0eXBlID0gb2xkQ2hpbGQuZ2V0Tm9kZVR5cGUoKTsKLSAgICAgICAgaWYodHlwZSA9PSBOb2RlLkVMRU1FTlRfTk9ERSkgewotICAgICAgICAgICAgZG9jRWxlbWVudCA9IG51bGw7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAodHlwZSA9PSBOb2RlLkRPQ1VNRU5UX1RZUEVfTk9ERSkgewotICAgICAgICAgICAgZG9jVHlwZSA9IG51bGw7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gb2xkQ2hpbGQ7Ci0KLSAgICB9ICAgLy8gcmVtb3ZlQ2hpbGQoTm9kZSk6Tm9kZQotCi0gICAgLyoqCi0gICAgICogU2luY2Ugd2UgY2FjaGUgdGhlIGRvY0VsZW1lbnQgKGFuZCwgY3VycmVudGx5LCBkb2NUeXBlKSwKLSAgICAgKiByZXBsYWNlQ2hpbGQgaGFzIHRvIHVwZGF0ZSB0aGUgY2FjaGUKLSAgICAgKgotICAgICAqIFJFVklTSVQ6IEFjY29yZGluZyB0byB0aGUgc3BlYyBpdCBpcyBub3QgYWxsb3dlZCB0byBhbHRlciBuZWl0aGVyIHRoZQotICAgICAqIGRvY3VtZW50IGVsZW1lbnQgbm9yIHRoZSBkb2N1bWVudCB0eXBlIGluIGFueSB3YXkKLSAgICAgKi8KLSAgICBwdWJsaWMgTm9kZSByZXBsYWNlQ2hpbGQoTm9kZSBuZXdDaGlsZCwgTm9kZSBvbGRDaGlsZCkKLSAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb24gewotCi0gICAgICAgIC8vIEFkb3B0IG9ycGhhbiBkb2N0eXBlcwotICAgICAgICBpZiAobmV3Q2hpbGQuZ2V0T3duZXJEb2N1bWVudCgpID09IG51bGwgJiYKLSAgICAgICAgbmV3Q2hpbGQgaW5zdGFuY2VvZiBEb2N1bWVudFR5cGVJbXBsKSB7Ci0gICAgICAgICAgICAoKERvY3VtZW50VHlwZUltcGwpIG5ld0NoaWxkKS5vd25lckRvY3VtZW50ID0gdGhpczsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChlcnJvckNoZWNraW5nICYmKChkb2NUeXBlICE9IG51bGwgJiYKLSAgICAgICAgICAgIG9sZENoaWxkLmdldE5vZGVUeXBlKCkgIT0gTm9kZS5ET0NVTUVOVF9UWVBFX05PREUgJiYKLSAgICAgICAgICAgIG5ld0NoaWxkLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5ET0NVTUVOVF9UWVBFX05PREUpCi0gICAgICAgICAgICB8fCAoZG9jRWxlbWVudCAhPSBudWxsICYmCi0gICAgICAgICAgICBvbGRDaGlsZC5nZXROb2RlVHlwZSgpICE9IE5vZGUuRUxFTUVOVF9OT0RFICYmCi0gICAgICAgICAgICBuZXdDaGlsZC5nZXROb2RlVHlwZSgpID09IE5vZGUuRUxFTUVOVF9OT0RFKSkpIHsKLQotICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgRE9NRXhjZXB0aW9uLkhJRVJBUkNIWV9SRVFVRVNUX0VSUiwKLSAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwgIkhJRVJBUkNIWV9SRVFVRVNUX0VSUiIsIG51bGwpKTsKLSAgICAgICAgfQotICAgICAgICBzdXBlci5yZXBsYWNlQ2hpbGQobmV3Q2hpbGQsIG9sZENoaWxkKTsKLQotICAgICAgICBpbnQgdHlwZSA9IG9sZENoaWxkLmdldE5vZGVUeXBlKCk7Ci0gICAgICAgIGlmKHR5cGUgPT0gTm9kZS5FTEVNRU5UX05PREUpIHsKLSAgICAgICAgICAgIGRvY0VsZW1lbnQgPSAoRWxlbWVudEltcGwpbmV3Q2hpbGQ7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAodHlwZSA9PSBOb2RlLkRPQ1VNRU5UX1RZUEVfTk9ERSkgewotICAgICAgICAgICAgZG9jVHlwZSA9IChEb2N1bWVudFR5cGVJbXBsKW5ld0NoaWxkOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBvbGRDaGlsZDsKLSAgICB9ICAgLy8gcmVwbGFjZUNoaWxkKE5vZGUsTm9kZSk6Tm9kZQotCi0gICAgLyoKLSAgICAgKiBHZXQgTm9kZSB0ZXh0IGNvbnRlbnQKLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFRleHRDb250ZW50KCkgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qCi0gICAgICogU2V0IE5vZGUgdGV4dCBjb250ZW50Ci0gICAgICogQHNpbmNlIERPTSBMZXZlbCAzCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0VGV4dENvbnRlbnQoU3RyaW5nIHRleHRDb250ZW50KQotICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0gICAgICAgIC8vIG5vLW9wCi0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHNpbmNlIERPTSBMZXZlbCAzCi0gICAgICovCi0gICAgcHVibGljIE9iamVjdCBnZXRGZWF0dXJlKFN0cmluZyBmZWF0dXJlLCBTdHJpbmcgdmVyc2lvbikgewotCi0gICAgICAgIGJvb2xlYW4gYW55VmVyc2lvbiA9IHZlcnNpb24gPT0gbnVsbCB8fCB2ZXJzaW9uLmxlbmd0aCgpID09IDA7Ci0KLSAgICAgICAgLy8gaWYgYSBwbHVzIHNpZ24gIisiIGlzIHByZXBlbmRlZCB0byBhbnkgZmVhdHVyZSBuYW1lLCBpbXBsZW1lbnRhdGlvbnMKLSAgICAgICAgLy8gYXJlIGNvbnNpZGVyZWQgaW4gd2hpY2ggdGhlIHNwZWNpZmllZCBmZWF0dXJlIG1heSBub3QgYmUgZGlyZWN0bHkKLSAgICAgICAgLy8gY2FzdGFibGUgRE9NSW1wbGVtZW50YXRpb24uZ2V0RmVhdHVyZShmZWF0dXJlLCB2ZXJzaW9uKS4gV2l0aG91dCBhCi0gICAgICAgIC8vIHBsdXMsIG9ubHkgZmVhdHVyZXMgd2hvc2UgaW50ZXJmYWNlcyBhcmUgZGlyZWN0bHkgY2FzdGFibGUgYXJlCi0gICAgICAgIC8vIGNvbnNpZGVyZWQuCi0gICAgICAgIGlmICgoZmVhdHVyZS5lcXVhbHNJZ25vcmVDYXNlKCIrWFBhdGgiKSkKLSAgICAgICAgICAgICAgICAmJiAoYW55VmVyc2lvbiB8fCB2ZXJzaW9uLmVxdWFscygiMy4wIikpKSB7Ci0KLSAgICAgICAgICAgIC8vIElmIGFuIFhQYXRoRXZhbHVhdG9yIHdhcyBjcmVhdGVkIHByZXZpb3VzbHkKLSAgICAgICAgICAgIC8vIHJldHVybiBpdCBvdGhlcndpc2UgY3JlYXRlIGEgbmV3IG9uZS4KLSAgICAgICAgICAgIGlmIChmWFBhdGhFdmFsdWF0b3IgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJldHVybiBmWFBhdGhFdmFsdWF0b3I7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgQ2xhc3MgeHBhdGhDbGFzcyA9IE9iamVjdEZhY3RvcnkuZmluZFByb3ZpZGVyQ2xhc3MgKAotICAgICAgICAgICAgICAgICAgICAgICAgImNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5kb21hcGkuWFBhdGhFdmFsdWF0b3JJbXBsIiwgdHJ1ZSk7Ci0gICAgICAgICAgICAgICAgQ29uc3RydWN0b3IgeHBhdGhDbGFzc0NvbnN0ciA9Ci0gICAgICAgICAgICAgICAgICAgIHhwYXRoQ2xhc3MuZ2V0Q29uc3RydWN0b3IobmV3IENsYXNzW10geyBEb2N1bWVudC5jbGFzcyB9KTsKLQotICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIHRoZSBET00gWFBhdGggaW1wbGVtZW50YXRpb24gaW1wbGVtZW50cwotICAgICAgICAgICAgICAgIC8vIHRoZSBpbnRlcmZhY2Ugb3JnLnczYy5kb20uWFBhdGhFdmFsdWF0b3IKLSAgICAgICAgICAgICAgICBDbGFzcyBpbnRlcmZhY2VzW10gPSB4cGF0aENsYXNzLmdldEludGVyZmFjZXMoKTsKLSAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGludGVyZmFjZXMubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGludGVyZmFjZXNbaV0uZ2V0TmFtZSgpLmVxdWFscygKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAib3JnLnczYy5kb20ueHBhdGguWFBhdGhFdmFsdWF0b3IiKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgZlhQYXRoRXZhbHVhdG9yID0geHBhdGhDbGFzc0NvbnN0ci5uZXdJbnN0YW5jZShuZXcgT2JqZWN0W10geyB0aGlzIH0pOwotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZYUGF0aEV2YWx1YXRvcjsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHN1cGVyLmdldEZlYXR1cmUoZmVhdHVyZSwgdmVyc2lvbik7Ci0gICAgfQotCi0gICAgLy8KLSAgICAvLyBEb2N1bWVudCBtZXRob2RzCi0gICAgLy8KLQotICAgIC8vIGZhY3RvcnkgbWV0aG9kcwotCi0gICAgLyoqCi0gICAgICogRmFjdG9yeSBtZXRob2Q7IGNyZWF0ZXMgYW4gQXR0cmlidXRlIGhhdmluZyB0aGlzIERvY3VtZW50IGFzIGl0cwotICAgICAqIE93bmVyRG9jLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZS4gTm90ZSB0aGF0IHRoZSBhdHRyaWJ1dGUncyB2YWx1ZSBpcwotICAgICAqIF9ub3RfIGVzdGFibGlzaGVkIGF0IHRoZSBmYWN0b3J5OyByZW1lbWJlciB0byBzZXQgaXQhCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbihJTlZBTElEX05BTUVfRVJSKQotICAgICAqIGlmIHRoZSBhdHRyaWJ1dGUgbmFtZSBpcyBub3QgYWNjZXB0YWJsZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgQXR0ciBjcmVhdGVBdHRyaWJ1dGUoU3RyaW5nIG5hbWUpCi0gICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKLQotICAgICAgICBpZiAoZXJyb3JDaGVja2luZyAmJiAhaXNYTUxOYW1lKG5hbWUseG1sMTFWZXJzaW9uKSkgewotICAgICAgICAgICAgU3RyaW5nIG1zZyA9Ci0gICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAiSU5WQUxJRF9DSEFSQUNURVJfRVJSIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsKTsKLSAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLklOVkFMSURfQ0hBUkFDVEVSX0VSUiwgbXNnKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbmV3IEF0dHJJbXBsKHRoaXMsIG5hbWUpOwotCi0gICAgfSAvLyBjcmVhdGVBdHRyaWJ1dGUoU3RyaW5nKTpBdHRyCi0KLSAgICAvKioKLSAgICAgKiBGYWN0b3J5IG1ldGhvZDsgY3JlYXRlcyBhIENEQVRBU2VjdGlvbiBoYXZpbmcgdGhpcyBEb2N1bWVudCBhcwotICAgICAqIGl0cyBPd25lckRvYy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBkYXRhIFRoZSBpbml0aWFsIGNvbnRlbnRzIG9mIHRoZSBDREFUQQotICAgICAqCi0gICAgICogQHRocm93cyBET01FeGNlcHRpb24oTk9UX1NVUFBPUlRFRF9FUlIpIGZvciBIVE1MIGRvY3VtZW50cy4gKEhUTUwKLSAgICAgKiBub3QgeWV0IGltcGxlbWVudGVkLikKLSAgICAgKi8KLSAgICBwdWJsaWMgQ0RBVEFTZWN0aW9uIGNyZWF0ZUNEQVRBU2VjdGlvbihTdHJpbmcgZGF0YSkKLSAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb24gewotICAgICAgICByZXR1cm4gbmV3IENEQVRBU2VjdGlvbkltcGwodGhpcywgZGF0YSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRmFjdG9yeSBtZXRob2Q7IGNyZWF0ZXMgYSBDb21tZW50IGhhdmluZyB0aGlzIERvY3VtZW50IGFzIGl0cwotICAgICAqIE93bmVyRG9jLgotICAgICAqCi0gICAgICogQHBhcmFtIGRhdGEgVGhlIGluaXRpYWwgY29udGVudHMgb2YgdGhlIENvbW1lbnQuICovCi0gICAgcHVibGljIENvbW1lbnQgY3JlYXRlQ29tbWVudChTdHJpbmcgZGF0YSkgewotICAgICAgICByZXR1cm4gbmV3IENvbW1lbnRJbXBsKHRoaXMsIGRhdGEpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEZhY3RvcnkgbWV0aG9kOyBjcmVhdGVzIGEgRG9jdW1lbnRGcmFnbWVudCBoYXZpbmcgdGhpcyBEb2N1bWVudAotICAgICAqIGFzIGl0cyBPd25lckRvYy4KLSAgICAgKi8KLSAgICBwdWJsaWMgRG9jdW1lbnRGcmFnbWVudCBjcmVhdGVEb2N1bWVudEZyYWdtZW50KCkgewotICAgICAgICByZXR1cm4gbmV3IERvY3VtZW50RnJhZ21lbnRJbXBsKHRoaXMpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEZhY3RvcnkgbWV0aG9kOyBjcmVhdGVzIGFuIEVsZW1lbnQgaGF2aW5nIHRoaXMgRG9jdW1lbnQKLSAgICAgKiBhcyBpdHMgT3duZXJEb2MuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdGFnTmFtZSBUaGUgbmFtZSBvZiB0aGUgZWxlbWVudCB0eXBlIHRvIGluc3RhbnRpYXRlLiBGb3IKLSAgICAgKiBYTUwsIHRoaXMgaXMgY2FzZS1zZW5zaXRpdmUuIEZvciBIVE1MLCB0aGUgdGFnTmFtZSBwYXJhbWV0ZXIgbWF5Ci0gICAgICogYmUgcHJvdmlkZWQgaW4gYW55IGNhc2UsIGJ1dCBpdCBtdXN0IGJlIG1hcHBlZCB0byB0aGUgY2Fub25pY2FsCi0gICAgICogdXBwZXJjYXNlIGZvcm0gYnkgdGhlIERPTSBpbXBsZW1lbnRhdGlvbi4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uKElOVkFMSURfTkFNRV9FUlIpIGlmIHRoZSB0YWcgbmFtZSBpcyBub3QKLSAgICAgKiBhY2NlcHRhYmxlLgotICAgICAqLwotICAgIHB1YmxpYyBFbGVtZW50IGNyZWF0ZUVsZW1lbnQoU3RyaW5nIHRhZ05hbWUpCi0gICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKLQotICAgICAgICBpZiAoZXJyb3JDaGVja2luZyAmJiAhaXNYTUxOYW1lKHRhZ05hbWUseG1sMTFWZXJzaW9uKSkgewotICAgICAgICAgICAgU3RyaW5nIG1zZyA9IERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sICJJTlZBTElEX0NIQVJBQ1RFUl9FUlIiLCBudWxsKTsKLSAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLklOVkFMSURfQ0hBUkFDVEVSX0VSUiwgbXNnKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbmV3IEVsZW1lbnRJbXBsKHRoaXMsIHRhZ05hbWUpOwotCi0gICAgfSAvLyBjcmVhdGVFbGVtZW50KFN0cmluZyk6RWxlbWVudAotCi0gICAgLyoqCi0gICAgICogRmFjdG9yeSBtZXRob2Q7IGNyZWF0ZXMgYW4gRW50aXR5UmVmZXJlbmNlIGhhdmluZyB0aGlzIERvY3VtZW50Ci0gICAgICogYXMgaXRzIE93bmVyRG9jLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIEVudGl0eSB3ZSB3aXNoIHRvIHJlZmVyIHRvCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbihOT1RfU1VQUE9SVEVEX0VSUikgZm9yIEhUTUwgZG9jdW1lbnRzLCB3aGVyZQotICAgICAqIG5vbnN0YW5kYXJkIGVudGl0aWVzIGFyZSBub3QgcGVybWl0dGVkLiAoSFRNTCBub3QgeWV0Ci0gICAgICogaW1wbGVtZW50ZWQuKQotICAgICAqLwotICAgIHB1YmxpYyBFbnRpdHlSZWZlcmVuY2UgY3JlYXRlRW50aXR5UmVmZXJlbmNlKFN0cmluZyBuYW1lKQotICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgaWYgKGVycm9yQ2hlY2tpbmcgJiYgIWlzWE1MTmFtZShuYW1lLHhtbDExVmVyc2lvbikpIHsKLSAgICAgICAgICAgIFN0cmluZyBtc2cgPSBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiSU5WQUxJRF9DSEFSQUNURVJfRVJSIiwgbnVsbCk7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5JTlZBTElEX0NIQVJBQ1RFUl9FUlIsIG1zZyk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG5ldyBFbnRpdHlSZWZlcmVuY2VJbXBsKHRoaXMsIG5hbWUpOwotCi0gICAgfSAvLyBjcmVhdGVFbnRpdHlSZWZlcmVuY2UoU3RyaW5nKTpFbnRpdHlSZWZlcmVuY2UKLQotICAgIC8qKgotICAgICAqIEZhY3RvcnkgbWV0aG9kOyBjcmVhdGVzIGEgUHJvY2Vzc2luZ0luc3RydWN0aW9uIGhhdmluZyB0aGlzIERvY3VtZW50Ci0gICAgICogYXMgaXRzIE93bmVyRG9jLgotICAgICAqCi0gICAgICogQHBhcmFtIHRhcmdldCBUaGUgdGFyZ2V0ICJwcm9jZXNzb3IgY2hhbm5lbCIKLSAgICAgKiBAcGFyYW0gZGF0YSBQYXJhbWV0ZXIgc3RyaW5nIHRvIGJlIHBhc3NlZCB0byB0aGUgdGFyZ2V0LgotICAgICAqCi0gICAgICogQHRocm93cyBET01FeGNlcHRpb24oSU5WQUxJRF9OQU1FX0VSUikgaWYgdGhlIHRhcmdldCBuYW1lIGlzIG5vdAotICAgICAqIGFjY2VwdGFibGUuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbihOT1RfU1VQUE9SVEVEX0VSUikgZm9yIEhUTUwgZG9jdW1lbnRzLiAoSFRNTAotICAgICAqIG5vdCB5ZXQgaW1wbGVtZW50ZWQuKQotICAgICAqLwotICAgIHB1YmxpYyBQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24gY3JlYXRlUHJvY2Vzc2luZ0luc3RydWN0aW9uKFN0cmluZyB0YXJnZXQsCi0gICAgICAgICAgICBTdHJpbmcgZGF0YSkKLSAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb24gewotCi0gICAgICAgIGlmIChlcnJvckNoZWNraW5nICYmICFpc1hNTE5hbWUodGFyZ2V0LHhtbDExVmVyc2lvbikpIHsKLSAgICAgICAgICAgIFN0cmluZyBtc2cgPSBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiSU5WQUxJRF9DSEFSQUNURVJfRVJSIiwgbnVsbCk7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5JTlZBTElEX0NIQVJBQ1RFUl9FUlIsIG1zZyk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG5ldyBQcm9jZXNzaW5nSW5zdHJ1Y3Rpb25JbXBsKHRoaXMsIHRhcmdldCwgZGF0YSk7Ci0KLSAgICB9IC8vIGNyZWF0ZVByb2Nlc3NpbmdJbnN0cnVjdGlvbihTdHJpbmcsU3RyaW5nKTpQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24KLQotICAgIC8qKgotICAgICAqIEZhY3RvcnkgbWV0aG9kOyBjcmVhdGVzIGEgVGV4dCBub2RlIGhhdmluZyB0aGlzIERvY3VtZW50IGFzIGl0cwotICAgICAqIE93bmVyRG9jLgotICAgICAqCi0gICAgICogQHBhcmFtIGRhdGEgVGhlIGluaXRpYWwgY29udGVudHMgb2YgdGhlIFRleHQuCi0gICAgICovCi0gICAgcHVibGljIFRleHQgY3JlYXRlVGV4dE5vZGUoU3RyaW5nIGRhdGEpIHsKLSAgICAgICAgcmV0dXJuIG5ldyBUZXh0SW1wbCh0aGlzLCBkYXRhKTsKLSAgICB9Ci0KLSAgICAvLyBvdGhlciBkb2N1bWVudCBtZXRob2RzCi0KLSAgICAvKioKLSAgICAgKiBGb3IgWE1MLCB0aGlzIHByb3ZpZGVzIGFjY2VzcyB0byB0aGUgRG9jdW1lbnQgVHlwZSBEZWZpbml0aW9uLgotICAgICAqIEZvciBIVE1MIGRvY3VtZW50cywgYW5kIFhNTCBkb2N1bWVudHMgd2hpY2ggZG9uJ3Qgc3BlY2lmeSBhIERURCwKLSAgICAgKiBpdCB3aWxsIGJlIG51bGwuCi0gICAgICovCi0gICAgcHVibGljIERvY3VtZW50VHlwZSBnZXREb2N0eXBlKCkgewotICAgICAgICBpZiAobmVlZHNTeW5jQ2hpbGRyZW4oKSkgewotICAgICAgICAgICAgc3luY2hyb25pemVDaGlsZHJlbigpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBkb2NUeXBlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbnZlbmllbmNlIG1ldGhvZCwgYWxsb3dpbmcgZGlyZWN0IGFjY2VzcyB0byB0aGUgY2hpbGQgbm9kZQotICAgICAqIHdoaWNoIGlzIGNvbnNpZGVyZWQgdGhlIHJvb3Qgb2YgdGhlIGFjdHVhbCBkb2N1bWVudCBjb250ZW50LiBGb3IKLSAgICAgKiBIVE1MLCB3aGVyZSBpdCBpcyBsZWdhbCB0byBoYXZlIG1vcmUgdGhhbiBvbmUgRWxlbWVudCBhdCB0aGUgdG9wCi0gICAgICogbGV2ZWwgb2YgdGhlIGRvY3VtZW50LCB3ZSBwaWNrIHRoZSBvbmUgd2l0aCB0aGUgdGFnTmFtZQotICAgICAqICJIVE1MIi4gRm9yIFhNTCB0aGVyZSBzaG91bGQgYmUgb25seSBvbmUgdG9wLWxldmVsCi0gICAgICoKLSAgICAgKiAoSFRNTCBub3QgeWV0IHN1cHBvcnRlZC4pCi0gICAgICovCi0gICAgcHVibGljIEVsZW1lbnQgZ2V0RG9jdW1lbnRFbGVtZW50KCkgewotICAgICAgICBpZiAobmVlZHNTeW5jQ2hpbGRyZW4oKSkgewotICAgICAgICAgICAgc3luY2hyb25pemVDaGlsZHJlbigpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBkb2NFbGVtZW50OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybiBhIDxlbT5saXZlPC9lbT4gY29sbGVjdGlvbiBvZiBhbGwgZGVzY2VuZGVudCBFbGVtZW50cyAobm90IGp1c3QKLSAgICAgKiBpbW1lZGlhdGUgY2hpbGRyZW4pIGhhdmluZyB0aGUgc3BlY2lmaWVkIHRhZyBuYW1lLgotICAgICAqCi0gICAgICogQHBhcmFtIHRhZ25hbWUgVGhlIHR5cGUgb2YgRWxlbWVudCB3ZSB3YW50IHRvIGdhdGhlci4gIioiIHdpbGwgYmUKLSAgICAgKiB0YWtlbiBhcyBhIHdpbGRjYXJkLCBtZWFuaW5nICJhbGwgZWxlbWVudHMgaW4gdGhlIGRvY3VtZW50LiIKLSAgICAgKgotICAgICAqIEBzZWUgRGVlcE5vZGVMaXN0SW1wbAotICAgICAqLwotICAgIHB1YmxpYyBOb2RlTGlzdCBnZXRFbGVtZW50c0J5VGFnTmFtZShTdHJpbmcgdGFnbmFtZSkgewotICAgICAgICByZXR1cm4gbmV3IERlZXBOb2RlTGlzdEltcGwodGhpcyx0YWduYW1lKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXRyaWV2ZSBpbmZvcm1hdGlvbiBkZXNjcmliaW5nIHRoZSBhYmlsaXRpZXMgb2YgdGhpcyBwYXJ0aWN1bGFyCi0gICAgICogRE9NIGltcGxlbWVudGF0aW9uLiBJbnRlbmRlZCB0byBzdXBwb3J0IGFwcGxpY2F0aW9ucyB0aGF0IG1heSBiZQotICAgICAqIHVzaW5nIERPTXMgcmV0cmlldmVkIGZyb20gc2V2ZXJhbCBkaWZmZXJlbnQgc291cmNlcywgcG90ZW50aWFsbHkKLSAgICAgKiB3aXRoIGRpZmZlcmVudCB1bmRlcmx5aW5nIHJlcHJlc2VudGF0aW9ucy4KLSAgICAgKi8KLSAgICBwdWJsaWMgRE9NSW1wbGVtZW50YXRpb24gZ2V0SW1wbGVtZW50YXRpb24oKSB7Ci0gICAgICAgIC8vIEN1cnJlbnRseSBpbXBsZW1lbnRlZCBhcyBhIHNpbmdsZXRvbiwgc2luY2UgaXQncyBoYXJkY29kZWQKLSAgICAgICAgLy8gaW5mb3JtYXRpb24gYW55d2F5LgotICAgICAgICByZXR1cm4gQ29yZURPTUltcGxlbWVudGF0aW9uSW1wbC5nZXRET01JbXBsZW1lbnRhdGlvbigpOwotICAgIH0KLQotICAgIC8vCi0gICAgLy8gUHVibGljIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLy8gcHJvcGVydGllcwotCi0gICAgLyoqCi0gICAgICogU2V0cyB3aGV0aGVyIHRoZSBET00gaW1wbGVtZW50YXRpb24gcGVyZm9ybXMgZXJyb3IgY2hlY2tpbmcKLSAgICAgKiB1cG9uIG9wZXJhdGlvbnMuIFR1cm5pbmcgb2ZmIGVycm9yIGNoZWNraW5nIG9ubHkgYWZmZWN0cwotICAgICAqIHRoZSBmb2xsb3dpbmcgRE9NIGNoZWNrczoKLSAgICAgKiA8dWw+Ci0gICAgICogPGxpPkNoZWNraW5nIHN0cmluZ3MgdG8gbWFrZSBzdXJlIHRoYXQgYWxsIGNoYXJhY3RlcnMgYXJlCi0gICAgICogICAgIGxlZ2FsIFhNTCBjaGFyYWN0ZXJzCi0gICAgICogPGxpPkhpZXJhcmNoeSBjaGVja2luZyBzdWNoIGFzIGFsbG93ZWQgY2hpbGRyZW4sIGNoZWNrcyBmb3IKLSAgICAgKiAgICAgY3ljbGVzLCBldGMuCi0gICAgICogPC91bD4KLSAgICAgKiA8cD4KLSAgICAgKiBUdXJuaW5nIG9mZiBlcnJvciBjaGVja2luZyBkb2VzIDxlbT5ub3Q8L2VtPiB0dXJuIG9mZiB0aGUKLSAgICAgKiBmb2xsb3dpbmcgY2hlY2tzOgotICAgICAqIDx1bD4KLSAgICAgKiA8bGk+UmVhZCBvbmx5IGNoZWNrcwotICAgICAqIDxsaT5DaGVja3MgcmVsYXRlZCB0byBET00gZXZlbnRzCi0gICAgICogPC91bD4KLSAgICAgKi8KLQotICAgIHB1YmxpYyB2b2lkIHNldEVycm9yQ2hlY2tpbmcoYm9vbGVhbiBjaGVjaykgewotICAgICAgICBlcnJvckNoZWNraW5nID0gY2hlY2s7Ci0gICAgfQotCi0gICAgLyoKLSAgICAgKiBET00gTGV2ZWwgMyBXRCAtIEV4cGVyaW1lbnRhbC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRTdHJpY3RFcnJvckNoZWNraW5nKGJvb2xlYW4gY2hlY2spIHsKLSAgICAgICAgZXJyb3JDaGVja2luZyA9IGNoZWNrOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgRE9NIGltcGxlbWVudGF0aW9uIHBlcmZvcm1zIGVycm9yIGNoZWNraW5nLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGdldEVycm9yQ2hlY2tpbmcoKSB7Ci0gICAgICAgIHJldHVybiBlcnJvckNoZWNraW5nOwotICAgIH0KLQotICAgIC8qCi0gICAgICogRE9NIExldmVsIDMgV0QgLSBFeHBlcmltZW50YWwuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0U3RyaWN0RXJyb3JDaGVja2luZygpIHsKLSAgICAgICAgcmV0dXJuIGVycm9yQ2hlY2tpbmc7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRE9NIExldmVsIDMgQ1IgLSBFeHBlcmltZW50YWwuIChXYXMgZ2V0QWN0dWFsRW5jb2RpbmcpCi0gICAgICoKLSAgICAgKiBBbiBhdHRyaWJ1dGUgc3BlY2lmeWluZyB0aGUgZW5jb2RpbmcgdXNlZCBmb3IgdGhpcyBkb2N1bWVudAotICAgICAqIGF0IHRoZSB0aW1lIG9mIHRoZSBwYXJzaW5nLiBUaGlzIGlzIDxjb2RlPm51bGw8L2NvZGU+IHdoZW4KLSAgICAgKiBpdCBpcyBub3Qga25vd24sIHN1Y2ggYXMgd2hlbiB0aGUgPGNvZGU+RG9jdW1lbnQ8L2NvZGU+IHdhcwotICAgICAqIGNyZWF0ZWQgaW4gbWVtb3J5LgotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0SW5wdXRFbmNvZGluZygpIHsKLSAgICAgICAgcmV0dXJuIGFjdHVhbEVuY29kaW5nOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIERPTSBJbnRlcm5hbAotICAgICAqIChXYXMgYSBET00gTDMgQ29yZSBXRCBwdWJsaWMgaW50ZXJmYWNlIG1ldGhvZCBzZXRBY3R1YWxFbmNvZGluZyApCi0gICAgICoKLSAgICAgKiBBbiBhdHRyaWJ1dGUgc3BlY2lmeWluZyB0aGUgYWN0dWFsIGVuY29kaW5nIG9mIHRoaXMgZG9jdW1lbnQuIFRoaXMgaXMKLSAgICAgKiA8Y29kZT5udWxsPC9jb2RlPiBvdGhlcndpc2UuCi0gICAgICogPGJyPiBUaGlzIGF0dHJpYnV0ZSByZXByZXNlbnRzIHRoZSBwcm9wZXJ0eSBbY2hhcmFjdGVyIGVuY29kaW5nIHNjaGVtZV0KLSAgICAgKiBkZWZpbmVkIGluIC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRJbnB1dEVuY29kaW5nKFN0cmluZyB2YWx1ZSkgewotICAgICAgICBhY3R1YWxFbmNvZGluZyA9IHZhbHVlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIERPTSBJbnRlcm5hbAotICAgICAqIChXYXMgYSBET00gTDMgQ29yZSBXRCBwdWJsaWMgaW50ZXJmYWNlIG1ldGhvZCBzZXRYTUxFbmNvZGluZyApCi0gICAgICoKLSAgICAgKiBBbiBhdHRyaWJ1dGUgc3BlY2lmeWluZywgYXMgcGFydCBvZiB0aGUgWE1MIGRlY2xhcmF0aW9uLAotICAgICAqIHRoZSBlbmNvZGluZyBvZiB0aGlzIGRvY3VtZW50LiBUaGlzIGlzIG51bGwgd2hlbiB1bnNwZWNpZmllZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRYbWxFbmNvZGluZyhTdHJpbmcgdmFsdWUpIHsKLSAgICAgICAgZW5jb2RpbmcgPSB2YWx1ZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAZGVwcmVjYXRlZCBUaGlzIG1ldGhvZCBpcyBpbnRlcm5hbCBhbmQgb25seSBleGlzdHMgZm9yCi0gICAgICogY29tcGF0aWJpbGl0eSB3aXRoIG9sZGVyIGFwcGxpY2F0aW9ucy4gTmV3IGFwcGxpY2F0aW9ucwotICAgICAqIHNob3VsZCBuZXZlciBjYWxsIHRoaXMgbWV0aG9kLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEVuY29kaW5nKFN0cmluZyB2YWx1ZSkgewotICAgICAgICBzZXRYbWxFbmNvZGluZyh2YWx1ZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRE9NIExldmVsIDMgV0QgLSBFeHBlcmltZW50YWwuCi0gICAgICogVGhlIGVuY29kaW5nIG9mIHRoaXMgZG9jdW1lbnQgKHBhcnQgb2YgWE1MIERlY2xhcmF0aW9uKQotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0WG1sRW5jb2RpbmcoKSB7Ci0gICAgICAgIHJldHVybiBlbmNvZGluZzsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAZGVwcmVjYXRlZCBUaGlzIG1ldGhvZCBpcyBpbnRlcm5hbCBhbmQgb25seSBleGlzdHMgZm9yCi0gICAgICogY29tcGF0aWJpbGl0eSB3aXRoIG9sZGVyIGFwcGxpY2F0aW9ucy4gTmV3IGFwcGxpY2F0aW9ucwotICAgICAqIHNob3VsZCBuZXZlciBjYWxsIHRoaXMgbWV0aG9kLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0RW5jb2RpbmcoKSB7Ci0gICAgICAgIHJldHVybiBnZXRYbWxFbmNvZGluZygpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIERPTSBMZXZlbCAzIENSIC0gRXhwZXJpbWVudGFsLgotICAgICAqIHZlcnNpb24gLSBBbiBhdHRyaWJ1dGUgc3BlY2lmeWluZywgYXMgcGFydCBvZiB0aGUgWE1MIGRlY2xhcmF0aW9uLAotICAgICAqIHRoZSB2ZXJzaW9uIG51bWJlciBvZiB0aGlzIGRvY3VtZW50LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFhtbFZlcnNpb24oU3RyaW5nIHZhbHVlKSB7Ci0gICAgICAgIGlmKHZhbHVlLmVxdWFscygiMS4wIikgfHwgdmFsdWUuZXF1YWxzKCIxLjEiKSl7Ci0gICAgICAgICAgICAvL3dlIG5lZWQgdG8gY2hhbmdlIHRoZSBmbGFnIHZhbHVlIG9ubHkgLS0KLSAgICAgICAgICAgIC8vIHdoZW4gdGhlIHZlcnNpb24gc2V0IGlzIGRpZmZlcmVudCB0aGFuIGFscmVhZHkgc2V0LgotICAgICAgICAgICAgaWYoIWdldFhtbFZlcnNpb24oKS5lcXVhbHModmFsdWUpKXsKLSAgICAgICAgICAgICAgICB4bWxWZXJzaW9uQ2hhbmdlZCA9IHRydWUgOwotICAgICAgICAgICAgICAgIC8vY2hhbmdlIHRoZSBub3JtYWxpemF0aW9uIHZhbHVlIGJhY2sgdG8gZmFsc2UKLSAgICAgICAgICAgICAgICBpc05vcm1hbGl6ZWQoZmFsc2UpOwotICAgICAgICAgICAgICAgIHZlcnNpb24gPSB2YWx1ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlewotICAgICAgICAgICAgLy9OT1RfU1VQUE9SVEVEX0VSUjogUmFpc2VkIGlmIHRoZSB2ZXNpb24gaXMgc2V0IHRvIGEgdmFsdWUgdGhhdCBpcyBub3Qgc3VwcG9ydGVkIGJ5Ci0gICAgICAgICAgICAvL3RoaXMgZG9jdW1lbnQKLSAgICAgICAgICAgIC8vd2UgZG9udCBzdXBwb3J0IGFueSBvdGhlciBYTUwgdmVyc2lvbgotICAgICAgICAgICAgU3RyaW5nIG1zZyA9IERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sICJOT1RfU1VQUE9SVEVEX0VSUiIsIG51bGwpOwotICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIsIG1zZyk7Ci0KLSAgICAgICAgfQotICAgICAgICBpZigoZ2V0WG1sVmVyc2lvbigpKS5lcXVhbHMoIjEuMSIpKXsKLSAgICAgICAgICAgIHhtbDExVmVyc2lvbiA9IHRydWU7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZXsKLSAgICAgICAgICAgIHhtbDExVmVyc2lvbiA9IGZhbHNlOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQGRlcHJlY2F0ZWQgVGhpcyBtZXRob2QgaXMgaW50ZXJuYWwgYW5kIG9ubHkgZXhpc3RzIGZvcgotICAgICAqIGNvbXBhdGliaWxpdHkgd2l0aCBvbGRlciBhcHBsaWNhdGlvbnMuIE5ldyBhcHBsaWNhdGlvbnMKLSAgICAgKiBzaG91bGQgbmV2ZXIgY2FsbCB0aGlzIG1ldGhvZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRWZXJzaW9uKFN0cmluZyB2YWx1ZSkgewotICAgICAgICBzZXRYbWxWZXJzaW9uKHZhbHVlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBET00gTGV2ZWwgMyBXRCAtIEV4cGVyaW1lbnRhbC4KLSAgICAgKiBUaGUgdmVyc2lvbiBvZiB0aGlzIGRvY3VtZW50IChwYXJ0IG9mIFhNTCBEZWNsYXJhdGlvbikKLSAgICAgKi8KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0WG1sVmVyc2lvbigpIHsKLSAgICAgICAgcmV0dXJuICh2ZXJzaW9uID09IG51bGwpPyIxLjAiOnZlcnNpb247Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQGRlcHJlY2F0ZWQgVGhpcyBtZXRob2QgaXMgaW50ZXJuYWwgYW5kIG9ubHkgZXhpc3RzIGZvcgotICAgICAqIGNvbXBhdGliaWxpdHkgd2l0aCBvbGRlciBhcHBsaWNhdGlvbnMuIE5ldyBhcHBsaWNhdGlvbnMKLSAgICAgKiBzaG91bGQgbmV2ZXIgY2FsbCB0aGlzIG1ldGhvZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFZlcnNpb24oKSB7Ci0gICAgICAgIHJldHVybiBnZXRYbWxWZXJzaW9uKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRE9NIExldmVsIDMgQ1IgLSBFeHBlcmltZW50YWwuCi0gICAgICoKLSAgICAgKiBYbWxzdGFuZGFsb25lIC0gQW4gYXR0cmlidXRlIHNwZWNpZnlpbmcsIGFzIHBhcnQgb2YgdGhlIFhNTCBkZWNsYXJhdGlvbiwKLSAgICAgKiB3aGV0aGVyIHRoaXMgZG9jdW1lbnQgaXMgc3RhbmRhbG9uZQotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICAgTk9UX1NVUFBPUlRFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIGRvY3VtZW50IGRvZXMgbm90IHN1cHBvcnQgdGhlCi0gICAgICogICAiWE1MIiBmZWF0dXJlLgotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFhtbFN0YW5kYWxvbmUoYm9vbGVhbiB2YWx1ZSkKLSAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb24gewotICAgICAgICBzdGFuZGFsb25lID0gdmFsdWU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQGRlcHJlY2F0ZWQgVGhpcyBtZXRob2QgaXMgaW50ZXJuYWwgYW5kIG9ubHkgZXhpc3RzIGZvcgotICAgICAqIGNvbXBhdGliaWxpdHkgd2l0aCBvbGRlciBhcHBsaWNhdGlvbnMuIE5ldyBhcHBsaWNhdGlvbnMKLSAgICAgKiBzaG91bGQgbmV2ZXIgY2FsbCB0aGlzIG1ldGhvZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRTdGFuZGFsb25lKGJvb2xlYW4gdmFsdWUpIHsKLSAgICAgICAgc2V0WG1sU3RhbmRhbG9uZSh2YWx1ZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRE9NIExldmVsIDMgV0QgLSBFeHBlcmltZW50YWwuCi0gICAgICogc3RhbmRhbG9uZSB0aGF0IHNwZWNpZmllcyB3aGV0aGVyIHRoaXMgZG9jdW1lbnQgaXMgc3RhbmRhbG9uZQotICAgICAqIChwYXJ0IG9mIFhNTCBEZWNsYXJhdGlvbikKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXRYbWxTdGFuZGFsb25lKCkgewotICAgICAgICByZXR1cm4gc3RhbmRhbG9uZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAZGVwcmVjYXRlZCBUaGlzIG1ldGhvZCBpcyBpbnRlcm5hbCBhbmQgb25seSBleGlzdHMgZm9yCi0gICAgICogY29tcGF0aWJpbGl0eSB3aXRoIG9sZGVyIGFwcGxpY2F0aW9ucy4gTmV3IGFwcGxpY2F0aW9ucwotICAgICAqIHNob3VsZCBuZXZlciBjYWxsIHRoaXMgbWV0aG9kLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGdldFN0YW5kYWxvbmUoKSB7Ci0gICAgICAgIHJldHVybiBnZXRYbWxTdGFuZGFsb25lKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRE9NIExldmVsIDMgV0QgLSBFeHBlcmltZW50YWwuCi0gICAgICogVGhlIGxvY2F0aW9uIG9mIHRoZSBkb2N1bWVudCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiB1bmRlZmluZWQuCi0gICAgICogPGJyPkJld2FyZSB0aGF0IHdoZW4gdGhlIDxjb2RlPkRvY3VtZW50PC9jb2RlPiBzdXBwb3J0cyB0aGUgZmVhdHVyZQotICAgICAqICJIVE1MIiAsIHRoZSBocmVmIGF0dHJpYnV0ZSBvZiB0aGUgSFRNTCBCQVNFIGVsZW1lbnQgdGFrZXMgcHJlY2VkZW5jZQotICAgICAqIG92ZXIgdGhpcyBhdHRyaWJ1dGUuCi0gICAgICogQHNpbmNlIERPTSBMZXZlbCAzCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXREb2N1bWVudFVSSSgpewotICAgICAgICByZXR1cm4gZkRvY3VtZW50VVJJOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogRE9NIExldmVsIDMgV0QgLSBFeHBlcmltZW50YWwuCi0gICAgICogUmVuYW1pbmcgbm9kZQotICAgICAqLwotICAgIHB1YmxpYyBOb2RlIHJlbmFtZU5vZGUoTm9kZSBuLFN0cmluZyBuYW1lc3BhY2VVUkksU3RyaW5nIG5hbWUpCi0gICAgdGhyb3dzIERPTUV4Y2VwdGlvbnsKLQotICAgICAgICBpZiAoZXJyb3JDaGVja2luZyAmJiBuLmdldE93bmVyRG9jdW1lbnQoKSAhPSB0aGlzICYmIG4gIT0gdGhpcykgewotICAgICAgICAgICAgU3RyaW5nIG1zZyA9IERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZSgKLSAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiV1JPTkdfRE9DVU1FTlRfRVJSIiwgbnVsbCk7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5XUk9OR19ET0NVTUVOVF9FUlIsIG1zZyk7Ci0gICAgICAgIH0KLSAgICAgICAgc3dpdGNoIChuLmdldE5vZGVUeXBlKCkpIHsKLSAgICAgICAgICAgIGNhc2UgRUxFTUVOVF9OT0RFOiB7Ci0gICAgICAgICAgICAgICAgRWxlbWVudEltcGwgZWwgPSAoRWxlbWVudEltcGwpIG47Ci0gICAgICAgICAgICAgICAgaWYgKGVsIGluc3RhbmNlb2YgRWxlbWVudE5TSW1wbCkgewotICAgICAgICAgICAgICAgICAgICAoKEVsZW1lbnROU0ltcGwpIGVsKS5yZW5hbWUobmFtZXNwYWNlVVJJLCBuYW1lKTsKLQotICAgICAgICAgICAgICAgICAgICAvLyBmaXJlIHVzZXIgZGF0YSBOT0RFX1JFTkFNRUQgZXZlbnQKLSAgICAgICAgICAgICAgICAgICAgY2FsbFVzZXJEYXRhSGFuZGxlcnMoZWwsIG51bGwsIFVzZXJEYXRhSGFuZGxlci5OT0RFX1JFTkFNRUQpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKG5hbWVzcGFjZVVSSSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3JDaGVja2luZykgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBjb2xvbjEgPSBuYW1lLmluZGV4T2YoJzonKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihjb2xvbjEgIT0gLTEpewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbXNnID0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZSgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOQU1FU1BBQ0VfRVJSIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OQU1FU1BBQ0VfRVJSLCBtc2cpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWlzWE1MTmFtZShuYW1lLHhtbDExVmVyc2lvbikpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG1zZyA9IERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZSgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIklOVkFMSURfQ0hBUkFDVEVSX0VSUiIsIG51bGwpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5JTlZBTElEX0NIQVJBQ1RFUl9FUlIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXNnKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBlbC5yZW5hbWUobmFtZSk7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZpcmUgdXNlciBkYXRhIE5PREVfUkVOQU1FRCBldmVudAotICAgICAgICAgICAgICAgICAgICAgICAgY2FsbFVzZXJEYXRhSGFuZGxlcnMoZWwsIG51bGwsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVzZXJEYXRhSGFuZGxlci5OT0RFX1JFTkFNRUQpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gd2UgbmVlZCB0byBjcmVhdGUgYSBuZXcgb2JqZWN0Ci0gICAgICAgICAgICAgICAgICAgICAgICBFbGVtZW50TlNJbXBsIG5lbCA9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IEVsZW1lbnROU0ltcGwodGhpcywgbmFtZXNwYWNlVVJJLCBuYW1lKTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gcmVnaXN0ZXIgZXZlbnQgbGlzdGVuZXJzIG9uIG5ldyBub2RlCi0gICAgICAgICAgICAgICAgICAgICAgICBjb3B5RXZlbnRMaXN0ZW5lcnMoZWwsIG5lbCk7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIHJlbW92ZSB1c2VyIGRhdGEgZnJvbSBvbGQgbm9kZQotICAgICAgICAgICAgICAgICAgICAgICAgTWFwPFN0cmluZywgVXNlckRhdGFSZWNvcmQ+IGRhdGEgPSByZW1vdmVVc2VyRGF0YVRhYmxlKGVsKTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gcmVtb3ZlIG9sZCBub2RlIGZyb20gcGFyZW50IGlmIGFueQotICAgICAgICAgICAgICAgICAgICAgICAgTm9kZSBwYXJlbnQgPSBlbC5nZXRQYXJlbnROb2RlKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBOb2RlIG5leHRTaWIgPSBlbC5nZXROZXh0U2libGluZygpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBhcmVudCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50LnJlbW92ZUNoaWxkKGVsKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIG1vdmUgY2hpbGRyZW4gdG8gbmV3IG5vZGUKLSAgICAgICAgICAgICAgICAgICAgICAgIE5vZGUgY2hpbGQgPSBlbC5nZXRGaXJzdENoaWxkKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoY2hpbGQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsLnJlbW92ZUNoaWxkKGNoaWxkKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZWwuYXBwZW5kQ2hpbGQoY2hpbGQpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkID0gZWwuZ2V0Rmlyc3RDaGlsZCgpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gbW92ZSBzcGVjaWZpZWQgYXR0cmlidXRlcyB0byBuZXcgbm9kZQotICAgICAgICAgICAgICAgICAgICAgICAgbmVsLm1vdmVTcGVjaWZpZWRBdHRyaWJ1dGVzKGVsKTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gYXR0YWNoIHVzZXIgZGF0YSB0byBuZXcgbm9kZQotICAgICAgICAgICAgICAgICAgICAgICAgc2V0VXNlckRhdGFUYWJsZShuZWwsIGRhdGEpOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBhbmQgZmlyZSB1c2VyIGRhdGEgTk9ERV9SRU5BTUVEIGV2ZW50Ci0gICAgICAgICAgICAgICAgICAgICAgICBjYWxsVXNlckRhdGFIYW5kbGVycyhlbCwgbmVsLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVc2VyRGF0YUhhbmRsZXIuTk9ERV9SRU5BTUVEKTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gaW5zZXJ0IG5ldyBub2RlIHdoZXJlIG9sZCBvbmUgd2FzCi0gICAgICAgICAgICAgICAgICAgICAgICBpZiAocGFyZW50ICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnQuaW5zZXJ0QmVmb3JlKG5lbCwgbmV4dFNpYik7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBlbCA9IG5lbDsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvLyBmaXJlIEVsZW1lbnROYW1lQ2hhbmdlZCBldmVudAotICAgICAgICAgICAgICAgIHJlbmFtZWRFbGVtZW50KChFbGVtZW50KSBuLCBlbCk7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGVsOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2FzZSBBVFRSSUJVVEVfTk9ERTogewotICAgICAgICAgICAgICAgIEF0dHJJbXBsIGF0ID0gKEF0dHJJbXBsKSBuOwotCi0gICAgICAgICAgICAgICAgLy8gZGV0dGFjaCBhdHRyIGZyb20gZWxlbWVudAotICAgICAgICAgICAgICAgIEVsZW1lbnQgZWwgPSBhdC5nZXRPd25lckVsZW1lbnQoKTsKLSAgICAgICAgICAgICAgICBpZiAoZWwgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBlbC5yZW1vdmVBdHRyaWJ1dGVOb2RlKGF0KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaWYgKG4gaW5zdGFuY2VvZiBBdHRyTlNJbXBsKSB7Ci0gICAgICAgICAgICAgICAgICAgICgoQXR0ck5TSW1wbCkgYXQpLnJlbmFtZShuYW1lc3BhY2VVUkksIG5hbWUpOwotICAgICAgICAgICAgICAgICAgICAvLyByZWF0dGFjaCBhdHRyIHRvIGVsZW1lbnQKLSAgICAgICAgICAgICAgICAgICAgaWYgKGVsICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGVsLnNldEF0dHJpYnV0ZU5vZGVOUyhhdCk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAvLyBmaXJlIHVzZXIgZGF0YSBOT0RFX1JFTkFNRUQgZXZlbnQKLSAgICAgICAgICAgICAgICAgICAgY2FsbFVzZXJEYXRhSGFuZGxlcnMoYXQsIG51bGwsIFVzZXJEYXRhSGFuZGxlci5OT0RFX1JFTkFNRUQpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKG5hbWVzcGFjZVVSSSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBhdC5yZW5hbWUobmFtZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyByZWF0dGFjaCBhdHRyIHRvIGVsZW1lbnQKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlbCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWwuc2V0QXR0cmlidXRlTm9kZShhdCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZpcmUgdXNlciBkYXRhIE5PREVfUkVOQU1FRCBldmVudAotICAgICAgICAgICAgICAgICAgICAgICAgY2FsbFVzZXJEYXRhSGFuZGxlcnMoYXQsIG51bGwsIFVzZXJEYXRhSGFuZGxlci5OT0RFX1JFTkFNRUQpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gd2UgbmVlZCB0byBjcmVhdGUgYSBuZXcgb2JqZWN0Ci0gICAgICAgICAgICAgICAgICAgICAgICBBdHRyTlNJbXBsIG5hdCA9IG5ldyBBdHRyTlNJbXBsKHRoaXMsIG5hbWVzcGFjZVVSSSwgbmFtZSk7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIHJlZ2lzdGVyIGV2ZW50IGxpc3RlbmVycyBvbiBuZXcgbm9kZQotICAgICAgICAgICAgICAgICAgICAgICAgY29weUV2ZW50TGlzdGVuZXJzKGF0LCBuYXQpOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyByZW1vdmUgdXNlciBkYXRhIGZyb20gb2xkIG5vZGUKLSAgICAgICAgICAgICAgICAgICAgICAgIE1hcDxTdHJpbmcsIFVzZXJEYXRhUmVjb3JkPiBkYXRhID0gcmVtb3ZlVXNlckRhdGFUYWJsZShhdCk7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIG1vdmUgY2hpbGRyZW4gdG8gbmV3IG5vZGUKLSAgICAgICAgICAgICAgICAgICAgICAgIE5vZGUgY2hpbGQgPSBhdC5nZXRGaXJzdENoaWxkKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoY2hpbGQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0LnJlbW92ZUNoaWxkKGNoaWxkKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYXQuYXBwZW5kQ2hpbGQoY2hpbGQpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkID0gYXQuZ2V0Rmlyc3RDaGlsZCgpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBhdHRhY2ggdXNlciBkYXRhIHRvIG5ldyBub2RlCi0gICAgICAgICAgICAgICAgICAgICAgICBzZXRVc2VyRGF0YVRhYmxlKG5hdCwgZGF0YSk7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFuZCBmaXJlIHVzZXIgZGF0YSBOT0RFX1JFTkFNRUQgZXZlbnQKLSAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxVc2VyRGF0YUhhbmRsZXJzKGF0LCBuYXQsIFVzZXJEYXRhSGFuZGxlci5OT0RFX1JFTkFNRUQpOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyByZWF0dGFjaCBhdHRyIHRvIGVsZW1lbnQKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlbCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWwuc2V0QXR0cmlidXRlTm9kZShuYXQpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgYXQgPSBuYXQ7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLy8gZmlyZSBBdHRyaWJ1dGVOYW1lQ2hhbmdlZCBldmVudAotICAgICAgICAgICAgICAgIHJlbmFtZWRBdHRyTm9kZSgoQXR0cikgbiwgYXQpOwotCi0gICAgICAgICAgICAgICAgcmV0dXJuIGF0OwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZGVmYXVsdDogewotICAgICAgICAgICAgICAgIFN0cmluZyBtc2cgPSBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiTk9UX1NVUFBPUlRFRF9FUlIiLCBudWxsKTsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUiwgbXNnKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiAgRE9NIExldmVsIDMgV0QgLSBFeHBlcmltZW50YWwKLSAgICAgKiAgTm9ybWFsaXplIGRvY3VtZW50LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIG5vcm1hbGl6ZURvY3VtZW50KCl7Ci0gICAgICAgIC8vIE5vIG5lZWQgdG8gbm9ybWFsaXplIGlmIGFscmVhZHkgbm9ybWFsaXplZC4KLSAgICAgICAgaWYgKGlzTm9ybWFsaXplZCgpICYmICFpc05vcm1hbGl6ZURvY1JlcXVpcmVkKCkpIHsKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotICAgICAgICBpZiAobmVlZHNTeW5jQ2hpbGRyZW4oKSkgewotICAgICAgICAgICAgc3luY2hyb25pemVDaGlsZHJlbigpOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKGRvbU5vcm1hbGl6ZXIgPT0gbnVsbCkgewotICAgICAgICAgICAgZG9tTm9ybWFsaXplciA9IG5ldyBET01Ob3JtYWxpemVyKCk7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoZkNvbmZpZ3VyYXRpb24gPT0gbnVsbCkgewotICAgICAgICAgICAgZkNvbmZpZ3VyYXRpb24gPSAgbmV3IERPTUNvbmZpZ3VyYXRpb25JbXBsKCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBmQ29uZmlndXJhdGlvbi5yZXNldCgpOwotICAgICAgICB9Ci0KLSAgICAgICAgZG9tTm9ybWFsaXplci5ub3JtYWxpemVEb2N1bWVudCh0aGlzLCBmQ29uZmlndXJhdGlvbik7Ci0gICAgICAgIGlzTm9ybWFsaXplZCh0cnVlKTsKLSAgICAgICAgLy9zZXQgdGhlIFhNTHZlcnNpb24gY2hhbmdlZCB2YWx1ZSB0byBmYWxzZSAtLSBvbmNlIHdlIGhhdmUgZmluaXNoZWQKLSAgICAgICAgLy9kb2luZyBub3JtYWxpemF0aW9uCi0gICAgICAgIHhtbFZlcnNpb25DaGFuZ2VkID0gZmFsc2UgOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogRE9NIExldmVsIDMgQ1IgLSBFeHBlcmltZW50YWwKLSAgICAgKgotICAgICAqICBUaGUgY29uZmlndXJhdGlvbiB1c2VkIHdoZW4gPGNvZGU+RG9jdW1lbnQubm9ybWFsaXplRG9jdW1lbnQ8L2NvZGU+IGlzCi0gICAgICogaW52b2tlZC4KLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICAgKi8KLSAgICBwdWJsaWMgRE9NQ29uZmlndXJhdGlvbiBnZXREb21Db25maWcoKXsKLSAgICAgICAgaWYgKGZDb25maWd1cmF0aW9uID09IG51bGwpIHsKLSAgICAgICAgICAgIGZDb25maWd1cmF0aW9uID0gbmV3IERPTUNvbmZpZ3VyYXRpb25JbXBsKCk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGZDb25maWd1cmF0aW9uOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgYWJzb2x1dGUgYmFzZSBVUkkgb2YgdGhpcyBub2RlIG9yIG51bGwgaWYgdGhlIGltcGxlbWVudGF0aW9uCi0gICAgICogd2Fzbid0IGFibGUgdG8gb2J0YWluIGFuIGFic29sdXRlIFVSSS4gTm90ZTogSWYgdGhlIFVSSSBpcyBtYWxmb3JtZWQsIGEKLSAgICAgKiBudWxsIGlzIHJldHVybmVkLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgYWJzb2x1dGUgYmFzZSBVUkkgb2YgdGhpcyBub2RlIG9yIG51bGwuCi0gICAgICogQHNpbmNlIERPTSBMZXZlbCAzCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRCYXNlVVJJKCkgewotICAgICAgICBpZiAoZkRvY3VtZW50VVJJICE9IG51bGwgJiYgZkRvY3VtZW50VVJJLmxlbmd0aCgpICE9IDAgKSB7Ly8gYXR0cmlidXRlIHZhbHVlIGlzIGFsd2F5cyBlbXB0eSBzdHJpbmcKLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBVUkkoZkRvY3VtZW50VVJJKS50b1N0cmluZygpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2F0Y2ggKGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5VUkkuTWFsZm9ybWVkVVJJRXhjZXB0aW9uIGUpewotICAgICAgICAgICAgICAgIC8vIFJFVklTSVQ6IHdoYXQgc2hvdWxkIGhhcHBlbiBpbiB0aGlzIGNhc2U/Ci0gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGZEb2N1bWVudFVSSTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBET00gTGV2ZWwgMyBXRCAtIEV4cGVyaW1lbnRhbC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXREb2N1bWVudFVSSShTdHJpbmcgZG9jdW1lbnRVUkkpewotICAgICAgICBmRG9jdW1lbnRVUkkgPSBkb2N1bWVudFVSSTsKLSAgICB9Ci0KLQotICAgIC8vCi0gICAgLy8gRE9NIEwzIExTCi0gICAgLy8KLSAgICAvKioKLSAgICAgKiBET00gTGV2ZWwgMyBXRCAtIEV4cGVyaW1lbnRhbC4KLSAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGUgbWV0aG9kIGxvYWQgc2hvdWxkIGJlIHN5bmNocm9ub3VzIG9yCi0gICAgICogYXN5bmNocm9ub3VzLiBXaGVuIHRoZSBhc3luYyBhdHRyaWJ1dGUgaXMgc2V0IHRvIDxjb2RlPnRydWU8L2NvZGU+Ci0gICAgICogdGhlIGxvYWQgbWV0aG9kIHJldHVybnMgY29udHJvbCB0byB0aGUgY2FsbGVyIGJlZm9yZSB0aGUgZG9jdW1lbnQgaGFzCi0gICAgICogY29tcGxldGVkIGxvYWRpbmcuIFRoZSBkZWZhdWx0IHZhbHVlIG9mIHRoaXMgcHJvcGVydHkgaXMKLSAgICAgKiA8Y29kZT5mYWxzZTwvY29kZT4uCi0gICAgICogPGJyPlNldHRpbmcgdGhlIHZhbHVlIG9mIHRoaXMgYXR0cmlidXRlIG1pZ2h0IHRocm93IE5PVF9TVVBQT1JURURfRVJSCi0gICAgICogaWYgdGhlIGltcGxlbWVudGF0aW9uIGRvZXNuJ3Qgc3VwcG9ydCB0aGUgbW9kZSB0aGUgYXR0cmlidXRlIGlzIGJlaW5nCi0gICAgICogc2V0IHRvLiBTaG91bGQgdGhlIERPTSBzcGVjIGRlZmluZSB0aGUgZGVmYXVsdCB2YWx1ZSBvZiB0aGlzCi0gICAgICogcHJvcGVydHk/IFdoYXQgaWYgaW1wbGVtZW50aW5nIGJvdGggYXN5bmMgYW5kIHN5bmMgSU8gaXMgaW1wcmFjdGljYWwKLSAgICAgKiBpbiBzb21lIHN5c3RlbXM/ICAyMDAxLTA5LTE0LiBkZWZhdWx0IGlzIDxjb2RlPmZhbHNlPC9jb2RlPiBidXQgd2UKLSAgICAgKiBuZWVkIHRvIGNoZWNrIHdpdGggTW96aWxsYSBhbmQgSUUuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0QXN5bmMoKSB7Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBET00gTGV2ZWwgMyBXRCAtIEV4cGVyaW1lbnRhbC4KLSAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGUgbWV0aG9kIGxvYWQgc2hvdWxkIGJlIHN5bmNocm9ub3VzIG9yCi0gICAgICogYXN5bmNocm9ub3VzLiBXaGVuIHRoZSBhc3luYyBhdHRyaWJ1dGUgaXMgc2V0IHRvIDxjb2RlPnRydWU8L2NvZGU+Ci0gICAgICogdGhlIGxvYWQgbWV0aG9kIHJldHVybnMgY29udHJvbCB0byB0aGUgY2FsbGVyIGJlZm9yZSB0aGUgZG9jdW1lbnQgaGFzCi0gICAgICogY29tcGxldGVkIGxvYWRpbmcuIFRoZSBkZWZhdWx0IHZhbHVlIG9mIHRoaXMgcHJvcGVydHkgaXMKLSAgICAgKiA8Y29kZT5mYWxzZTwvY29kZT4uCi0gICAgICogPGJyPlNldHRpbmcgdGhlIHZhbHVlIG9mIHRoaXMgYXR0cmlidXRlIG1pZ2h0IHRocm93IE5PVF9TVVBQT1JURURfRVJSCi0gICAgICogaWYgdGhlIGltcGxlbWVudGF0aW9uIGRvZXNuJ3Qgc3VwcG9ydCB0aGUgbW9kZSB0aGUgYXR0cmlidXRlIGlzIGJlaW5nCi0gICAgICogc2V0IHRvLiBTaG91bGQgdGhlIERPTSBzcGVjIGRlZmluZSB0aGUgZGVmYXVsdCB2YWx1ZSBvZiB0aGlzCi0gICAgICogcHJvcGVydHk/IFdoYXQgaWYgaW1wbGVtZW50aW5nIGJvdGggYXN5bmMgYW5kIHN5bmMgSU8gaXMgaW1wcmFjdGljYWwKLSAgICAgKiBpbiBzb21lIHN5c3RlbXM/ICAyMDAxLTA5LTE0LiBkZWZhdWx0IGlzIDxjb2RlPmZhbHNlPC9jb2RlPiBidXQgd2UKLSAgICAgKiBuZWVkIHRvIGNoZWNrIHdpdGggTW96aWxsYSBhbmQgSUUuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0QXN5bmMoYm9vbGVhbiBhc3luYykgewotICAgICAgICBpZiAoYXN5bmMpIHsKLSAgICAgICAgICAgIFN0cmluZyBtc2cgPSBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiTk9UX1NVUFBPUlRFRF9FUlIiLCBudWxsKTsKLSAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSLCBtc2cpOwotICAgICAgICB9Ci0gICAgfQotICAgIC8qKgotICAgICAqIERPTSBMZXZlbCAzIFdEIC0gRXhwZXJpbWVudGFsLgotICAgICAqIElmIHRoZSBkb2N1bWVudCBpcyBjdXJyZW50bHkgYmVpbmcgbG9hZGVkIGFzIGEgcmVzdWx0IG9mIHRoZSBtZXRob2QKLSAgICAgKiA8Y29kZT5sb2FkPC9jb2RlPiBiZWluZyBpbnZva2VkIHRoZSBsb2FkaW5nIGFuZCBwYXJzaW5nIGlzCi0gICAgICogaW1tZWRpYXRlbHkgYWJvcnRlZC4gVGhlIHBvc3NpYmx5IHBhcnRpYWwgcmVzdWx0IG9mIHBhcnNpbmcgdGhlCi0gICAgICogZG9jdW1lbnQgaXMgZGlzY2FyZGVkIGFuZCB0aGUgZG9jdW1lbnQgaXMgY2xlYXJlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBhYm9ydCgpIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBET00gTGV2ZWwgMyBXRCAtIEV4cGVyaW1lbnRhbC4KLSAgICAgKgotICAgICAqIFJlcGxhY2VzIHRoZSBjb250ZW50IG9mIHRoZSBkb2N1bWVudCB3aXRoIHRoZSByZXN1bHQgb2YgcGFyc2luZyB0aGUKLSAgICAgKiBnaXZlbiBVUkkuIEludm9raW5nIHRoaXMgbWV0aG9kIHdpbGwgZWl0aGVyIGJsb2NrIHRoZSBjYWxsZXIgb3IKLSAgICAgKiByZXR1cm4gdG8gdGhlIGNhbGxlciBpbW1lZGlhdGVseSBkZXBlbmRpbmcgb24gdGhlIHZhbHVlIG9mIHRoZSBhc3luYwotICAgICAqIGF0dHJpYnV0ZS4gT25jZSB0aGUgZG9jdW1lbnQgaXMgZnVsbHkgbG9hZGVkIGEgImxvYWQiIGV2ZW50IChhcwotICAgICAqIGRlZmluZWQgaW4gWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDMvV0QtRE9NLUxldmVsLTMtRXZlbnRzLTIwMDMwMzMxJz5ET00gTGV2ZWwgMyBFdmVudHM8L2E+XQotICAgICAqICwgZXhjZXB0IHRoYXQgdGhlIDxjb2RlPkV2ZW50LnRhcmdldE5vZGU8L2NvZGU+IHdpbGwgYmUgdGhlIGRvY3VtZW50LAotICAgICAqIG5vdCBhbiBlbGVtZW50KSB3aWxsIGJlIGRpc3BhdGNoZWQgb24gdGhlIGRvY3VtZW50LiBJZiBhbiBlcnJvcgotICAgICAqIG9jY3VycywgYW4gaW1wbGVtZW50YXRpb24gZGVwZW5kZW50ICJlcnJvciIgZXZlbnQgd2lsbCBiZSBkaXNwYXRjaGVkCi0gICAgICogb24gdGhlIGRvY3VtZW50LiBJZiB0aGlzIG1ldGhvZCBpcyBjYWxsZWQgb24gYSBkb2N1bWVudCB0aGF0IGlzCi0gICAgICogY3VycmVudGx5IGxvYWRpbmcsIHRoZSBjdXJyZW50IGxvYWQgaXMgaW50ZXJydXB0ZWQgYW5kIHRoZSBuZXcgVVJJCi0gICAgICogbG9hZCBpcyBpbml0aWF0ZWQuCi0gICAgICogPGJyPiBXaGVuIGludm9raW5nIHRoaXMgbWV0aG9kIHRoZSBwYXJhbWV0ZXJzIHVzZWQgaW4gdGhlCi0gICAgICogPGNvZGU+RE9NUGFyc2VyPC9jb2RlPiBpbnRlcmZhY2UgYXJlIGFzc3VtZWQgdG8gaGF2ZSB0aGVpciBkZWZhdWx0Ci0gICAgICogdmFsdWVzIHdpdGggdGhlIGV4Y2VwdGlvbiB0aGF0IHRoZSBwYXJhbWV0ZXJzIDxjb2RlPiJlbnRpdGllcyI8L2NvZGU+Ci0gICAgICogLCA8Y29kZT4ibm9ybWFsaXplLWNoYXJhY3RlcnMiPC9jb2RlPiwKLSAgICAgKiA8Y29kZT4iY2hlY2stY2hhcmFjdGVyLW5vcm1hbGl6YXRpb24iPC9jb2RlPiBhcmUgc2V0IHRvCi0gICAgICogPGNvZGU+ImZhbHNlIjwvY29kZT4uCi0gICAgICogPGJyPiBUaGUgcmVzdWx0IG9mIGEgY2FsbCB0byB0aGlzIG1ldGhvZCBpcyB0aGUgc2FtZSB0aGUgcmVzdWx0IG9mIGEKLSAgICAgKiBjYWxsIHRvIDxjb2RlPkRPTVBhcnNlci5wYXJzZVdpdGhDb250ZXh0PC9jb2RlPiB3aXRoIGFuIGlucHV0IHN0cmVhbQotICAgICAqIHJlZmVyZW5jaW5nIHRoZSBVUkkgdGhhdCB3YXMgcGFzc2VkIHRvIHRoaXMgY2FsbCwgdGhlIGRvY3VtZW50IGFzIHRoZQotICAgICAqIGNvbnRleHQgbm9kZSwgYW5kIHRoZSBhY3Rpb24gPGNvZGU+QUNUSU9OX1JFUExBQ0VfQ0hJTERSRU48L2NvZGU+LgotICAgICAqIEBwYXJhbSB1cmkgVGhlIFVSSSByZWZlcmVuY2UgZm9yIHRoZSBYTUwgZmlsZSB0byBiZSBsb2FkZWQuIElmIHRoaXMgaXMKLSAgICAgKiAgYSByZWxhdGl2ZSBVUkksIHRoZSBiYXNlIFVSSSB1c2VkIGJ5IHRoZSBpbXBsZW1lbnRhdGlvbiBpcwotICAgICAqICBpbXBsZW1lbnRhdGlvbiBkZXBlbmRlbnQuCi0gICAgICogQHJldHVybiBJZiBhc3luYyBpcyBzZXQgdG8gPGNvZGU+dHJ1ZTwvY29kZT4gPGNvZGU+bG9hZDwvY29kZT4gcmV0dXJucwotICAgICAqICAgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIGRvY3VtZW50IGxvYWQgd2FzIHN1Y2Nlc3NmdWxseSBpbml0aWF0ZWQuCi0gICAgICogICBJZiBhbiBlcnJvciBvY2N1cnJlZCB3aGVuIGluaXRpYXRpbmcgdGhlIGRvY3VtZW50IGxvYWQsCi0gICAgICogICA8Y29kZT5sb2FkPC9jb2RlPiByZXR1cm5zIDxjb2RlPmZhbHNlPC9jb2RlPi5JZiBhc3luYyBpcyBzZXQgdG8KLSAgICAgKiAgIDxjb2RlPmZhbHNlPC9jb2RlPiA8Y29kZT5sb2FkPC9jb2RlPiByZXR1cm5zIDxjb2RlPnRydWU8L2NvZGU+IGlmCi0gICAgICogICB0aGUgZG9jdW1lbnQgd2FzIHN1Y2Nlc3NmdWxseSBsb2FkZWQgYW5kIHBhcnNlZC4gSWYgYW4gZXJyb3IKLSAgICAgKiAgIG9jY3VycmVkIHdoZW4gZWl0aGVyIGxvYWRpbmcgb3IgcGFyc2luZyB0aGUgVVJJLCA8Y29kZT5sb2FkPC9jb2RlPgotICAgICAqICAgcmV0dXJucyA8Y29kZT5mYWxzZTwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gbG9hZChTdHJpbmcgdXJpKSB7Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBET00gTGV2ZWwgMyBXRCAtIEV4cGVyaW1lbnRhbC4KLSAgICAgKiBSZXBsYWNlIHRoZSBjb250ZW50IG9mIHRoZSBkb2N1bWVudCB3aXRoIHRoZSByZXN1bHQgb2YgcGFyc2luZyB0aGUKLSAgICAgKiBpbnB1dCBzdHJpbmcsIHRoaXMgbWV0aG9kIGlzIGFsd2F5cyBzeW5jaHJvbm91cy4KLSAgICAgKiBAcGFyYW0gc291cmNlIEEgc3RyaW5nIGNvbnRhaW5pbmcgYW4gWE1MIGRvY3VtZW50LgotICAgICAqIEByZXR1cm4gPGNvZGU+dHJ1ZTwvY29kZT4gaWYgcGFyc2luZyB0aGUgaW5wdXQgc3RyaW5nIHN1Y2NlZWRlZAotICAgICAqICAgd2l0aG91dCBlcnJvcnMsIG90aGVyd2lzZSA8Y29kZT5mYWxzZTwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gbG9hZFhNTChTdHJpbmcgc291cmNlKSB7Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBET00gTGV2ZWwgMyBXRCAtIEV4cGVyaW1lbnRhbC4KLSAgICAgKiBTYXZlIHRoZSBkb2N1bWVudCBvciB0aGUgZ2l2ZW4gbm9kZSBhbmQgYWxsIGl0cyBkZXNjZW5kYW50cyB0byBhIHN0cmluZwotICAgICAqIChpLmUuIHNlcmlhbGl6ZSB0aGUgZG9jdW1lbnQgb3Igbm9kZSkuCi0gICAgICogPGJyPlRoZSBwYXJhbWV0ZXJzIHVzZWQgaW4gdGhlIDxjb2RlPkxTU2VyaWFsaXplcjwvY29kZT4gaW50ZXJmYWNlIGFyZQotICAgICAqIGFzc3VtZWQgdG8gaGF2ZSB0aGVpciBkZWZhdWx0IHZhbHVlcyB3aGVuIGludm9raW5nIHRoaXMgbWV0aG9kLgotICAgICAqIDxicj4gVGhlIHJlc3VsdCBvZiBhIGNhbGwgdG8gdGhpcyBtZXRob2QgaXMgdGhlIHNhbWUgdGhlIHJlc3VsdCBvZiBhCi0gICAgICogY2FsbCB0byA8Y29kZT5MU1NlcmlhbGl6ZXIud3JpdGVUb1N0cmluZzwvY29kZT4gd2l0aCB0aGUgZG9jdW1lbnQgYXMKLSAgICAgKiB0aGUgbm9kZSB0byB3cml0ZS4KLSAgICAgKiBAcGFyYW0gbm9kZSBTcGVjaWZpZXMgd2hhdCB0byBzZXJpYWxpemUsIGlmIHRoaXMgcGFyYW1ldGVyIGlzCi0gICAgICogICA8Y29kZT5udWxsPC9jb2RlPiB0aGUgd2hvbGUgZG9jdW1lbnQgaXMgc2VyaWFsaXplZCwgaWYgaXQncwotICAgICAqICAgbm9uLW51bGwgdGhlIGdpdmVuIG5vZGUgaXMgc2VyaWFsaXplZC4KLSAgICAgKiBAcmV0dXJuIFRoZSBzZXJpYWxpemVkIGRvY3VtZW50IG9yIDxjb2RlPm51bGw8L2NvZGU+IGluIGNhc2UgYW4gZXJyb3IKLSAgICAgKiAgIG9jY3VycmVkLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBXUk9OR19ET0NVTUVOVF9FUlI6IFJhaXNlZCBpZiB0aGUgbm9kZSBwYXNzZWQgaW4gYXMgdGhlIG5vZGUKLSAgICAgKiAgIHBhcmFtZXRlciBpcyBmcm9tIGFuIG90aGVyIGRvY3VtZW50LgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgc2F2ZVhNTChOb2RlIG5vZGUpCi0gICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKGVycm9yQ2hlY2tpbmcgJiYgbm9kZSAhPSBudWxsCi0gICAgICAgICAgICAgICAgJiYgdGhpcyAhPSBub2RlLmdldE93bmVyRG9jdW1lbnQoKSkgewotICAgICAgICAgICAgU3RyaW5nIG1zZyA9IERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sICJXUk9OR19ET0NVTUVOVF9FUlIiLCBudWxsKTsKLSAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLldST05HX0RPQ1VNRU5UX0VSUiwgbXNnKTsKLSAgICAgICAgfQotICAgICAgICBET01JbXBsZW1lbnRhdGlvbkxTIGRvbUltcGxMUyA9IChET01JbXBsZW1lbnRhdGlvbkxTKSBET01JbXBsZW1lbnRhdGlvbkltcGwuZ2V0RE9NSW1wbGVtZW50YXRpb24oKTsKLSAgICAgICAgTFNTZXJpYWxpemVyIHhtbFdyaXRlciA9IGRvbUltcGxMUy5jcmVhdGVMU1NlcmlhbGl6ZXIoKTsKLSAgICAgICAgaWYgKG5vZGUgPT0gbnVsbCkgewotICAgICAgICAgICAgbm9kZSA9IHRoaXM7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHhtbFdyaXRlci53cml0ZVRvU3RyaW5nKG5vZGUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldHMgd2hldGhlciB0aGUgRE9NIGltcGxlbWVudGF0aW9uIGdlbmVyYXRlcyBtdXRhdGlvbiBldmVudHMgdXBvbgotICAgICAqIG9wZXJhdGlvbnMuCi0gICAgICovCi0gICAgdm9pZCBzZXRNdXRhdGlvbkV2ZW50cyhib29sZWFuIHNldCkgewotICAgICAgICAvLyBkb2VzIG5vdGhpbmcgYnkgZGVmYXVsdCAtIG92ZXJpZGRlbiBpbiBzdWJjbGFzcwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgRE9NIGltcGxlbWVudGF0aW9uIGdlbmVyYXRlcyBtdXRhdGlvbiBldmVudHMuCi0gICAgICovCi0gICAgYm9vbGVhbiBnZXRNdXRhdGlvbkV2ZW50cygpIHsKLSAgICAgICAgLy8gZG9lcyBub3RoaW5nIGJ5IGRlZmF1bHQgLSBvdmVycmlkZW4gaW4gc3ViY2xhc3MKLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIC8vIG5vbi1ET00gZmFjdG9yeSBtZXRob2RzCi0gICAgLyoqCi0gICAgICogTk9OLURPTSBGYWN0b3J5IG1ldGhvZDsgY3JlYXRlcyBhIERvY3VtZW50VHlwZSBoYXZpbmcgdGhpcyBEb2N1bWVudCBhcwotICAgICAqIGl0cyBPd25lckRvYy4gKFJFQy1ET00tTGV2ZWwtMS0xOTk4MTAwMSBsZWZ0IHRoZSBwcm9jZXNzIG9mIGJ1aWxkaW5nIERURAotICAgICAqIGluZm9ybWF0aW9uIHVuc3BlY2lmaWVkLikKLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBFbnRpdHkgd2Ugd2lzaCB0byBwcm92aWRlIGEgdmFsdWUgZm9yLgotICAgICAqCi0gICAgICogQHRocm93cyBET01FeGNlcHRpb24oTk9UX1NVUFBPUlRFRF9FUlIpIGZvciBIVE1MIGRvY3VtZW50cywgd2hlcmUgRFREcwotICAgICAqIGFyZSBub3QgcGVybWl0dGVkLiAoSFRNTCBub3QgeWV0IGltcGxlbWVudGVkLikKLSAgICAgKi8KLSAgICBwdWJsaWMgRG9jdW1lbnRUeXBlIGNyZWF0ZURvY3VtZW50VHlwZShTdHJpbmcgcXVhbGlmaWVkTmFtZSwKLSAgICAgICAgICAgIFN0cmluZyBwdWJsaWNJRCwKLSAgICAgICAgICAgIFN0cmluZyBzeXN0ZW1JRCkKLSAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb24gewotCi0gICAgICAgIHJldHVybiBuZXcgRG9jdW1lbnRUeXBlSW1wbCh0aGlzLCBxdWFsaWZpZWROYW1lLCBwdWJsaWNJRCwgc3lzdGVtSUQpOwotCi0gICAgfSAvLyBjcmVhdGVEb2N1bWVudFR5cGUoU3RyaW5nKTpEb2N1bWVudFR5cGUKLQotICAgIC8qKgotICAgICAqIE5PTi1ET00gRmFjdG9yeSBtZXRob2Q7IGNyZWF0ZXMgYW4gRW50aXR5IGhhdmluZyB0aGlzIERvY3VtZW50IGFzIGl0cwotICAgICAqIE93bmVyRG9jLiAoUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxIGxlZnQgdGhlIHByb2Nlc3Mgb2YgYnVpbGRpbmcgRFRECi0gICAgICogaW5mb3JtYXRpb24gdW5zcGVjaWZpZWQuKQotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIEVudGl0eSB3ZSB3aXNoIHRvIHByb3ZpZGUgYSB2YWx1ZSBmb3IuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbihOT1RfU1VQUE9SVEVEX0VSUikgZm9yIEhUTUwgZG9jdW1lbnRzLCB3aGVyZQotICAgICAqIG5vbnN0YW5kYXJkIGVudGl0aWVzIGFyZSBub3QgcGVybWl0dGVkLiAoSFRNTCBub3QgeWV0IGltcGxlbWVudGVkLikKLSAgICAgKi8KLSAgICBwdWJsaWMgRW50aXR5IGNyZWF0ZUVudGl0eShTdHJpbmcgbmFtZSkKLSAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb24gewotCi0gICAgICAgIGlmIChlcnJvckNoZWNraW5nICYmICFpc1hNTE5hbWUobmFtZSwgeG1sMTFWZXJzaW9uKSkgewotICAgICAgICAgICAgU3RyaW5nIG1zZyA9IERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sICJJTlZBTElEX0NIQVJBQ1RFUl9FUlIiLCBudWxsKTsKLSAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLklOVkFMSURfQ0hBUkFDVEVSX0VSUiwgbXNnKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbmV3IEVudGl0eUltcGwodGhpcywgbmFtZSk7Ci0KLSAgICB9IC8vIGNyZWF0ZUVudGl0eShTdHJpbmcpOkVudGl0eQotCi0gICAgLyoqCi0gICAgICogTk9OLURPTSBGYWN0b3J5IG1ldGhvZDsgY3JlYXRlcyBhIE5vdGF0aW9uIGhhdmluZyB0aGlzIERvY3VtZW50IGFzIGl0cwotICAgICAqIE93bmVyRG9jLiAoUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxIGxlZnQgdGhlIHByb2Nlc3Mgb2YgYnVpbGRpbmcgRFRECi0gICAgICogaW5mb3JtYXRpb24gdW5zcGVjaWZpZWQuKQotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIE5vdGF0aW9uIHdlIHdpc2ggdG8gZGVzY3JpYmUKLSAgICAgKgotICAgICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uKE5PVF9TVVBQT1JURURfRVJSKSBmb3IgSFRNTCBkb2N1bWVudHMsIHdoZXJlCi0gICAgICogbm90YXRpb25zIGFyZSBub3QgcGVybWl0dGVkLiAoSFRNTCBub3QgeWV0IGltcGxlbWVudGVkLikKLSAgICAgKi8KLSAgICBwdWJsaWMgTm90YXRpb24gY3JlYXRlTm90YXRpb24oU3RyaW5nIG5hbWUpCi0gICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKLQotICAgICAgICBpZiAoZXJyb3JDaGVja2luZyAmJiAhaXNYTUxOYW1lKG5hbWUsIHhtbDExVmVyc2lvbikpIHsKLSAgICAgICAgICAgIFN0cmluZyBtc2cgPSBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiSU5WQUxJRF9DSEFSQUNURVJfRVJSIiwgbnVsbCk7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5JTlZBTElEX0NIQVJBQ1RFUl9FUlIsIG1zZyk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG5ldyBOb3RhdGlvbkltcGwodGhpcywgbmFtZSk7Ci0KLSAgICB9IC8vIGNyZWF0ZU5vdGF0aW9uKFN0cmluZyk6Tm90YXRpb24KLQotICAgIC8qKgotICAgICAqIE5PTi1ET00gRmFjdG9yeSBtZXRob2Q6IGNyZWF0ZXMgYW4gZWxlbWVudCBkZWZpbml0aW9uLiBFbGVtZW50Ci0gICAgICogZGVmaW5pdGlvbnMgaG9sZCBkZWZhdWx0IGF0dHJpYnV0ZSB2YWx1ZXMuCi0gICAgICovCi0gICAgcHVibGljIEVsZW1lbnREZWZpbml0aW9uSW1wbCBjcmVhdGVFbGVtZW50RGVmaW5pdGlvbihTdHJpbmcgbmFtZSkKLSAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb24gewotCi0gICAgICAgIGlmIChlcnJvckNoZWNraW5nICYmICFpc1hNTE5hbWUobmFtZSwgeG1sMTFWZXJzaW9uKSkgewotICAgICAgICAgICAgU3RyaW5nIG1zZyA9IERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sICJJTlZBTElEX0NIQVJBQ1RFUl9FUlIiLCBudWxsKTsKLSAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLklOVkFMSURfQ0hBUkFDVEVSX0VSUiwgbXNnKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbmV3IEVsZW1lbnREZWZpbml0aW9uSW1wbCh0aGlzLCBuYW1lKTsKLQotICAgIH0gLy8gY3JlYXRlRWxlbWVudERlZmluaXRpb24oU3RyaW5nKTpFbGVtZW50RGVmaW5pdGlvbkltcGwKLQotICAgIC8vIG90aGVyIG5vbi1ET00gbWV0aG9kcwotICAgIC8qKgotICAgICAqIE5PTi1ET006IEdldCB0aGUgbnVtYmVyIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGRvY3VtZW50LiBVc2VkIHRvIG9yZGVyCi0gICAgICogZG9jdW1lbnRzIGluIHRoZSBpbXBsZW1lbnRhdGlvbi4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgaW50IGdldE5vZGVOdW1iZXIoKSB7Ci0gICAgICAgIGlmIChkb2N1bWVudE51bWJlciA9PSAwKSB7Ci0KLSAgICAgICAgICAgIENvcmVET01JbXBsZW1lbnRhdGlvbkltcGwgY2QgPSAoQ29yZURPTUltcGxlbWVudGF0aW9uSW1wbCkgQ29yZURPTUltcGxlbWVudGF0aW9uSW1wbC5nZXRET01JbXBsZW1lbnRhdGlvbigpOwotICAgICAgICAgICAgZG9jdW1lbnROdW1iZXIgPSBjZC5hc3NpZ25Eb2N1bWVudE51bWJlcigpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBkb2N1bWVudE51bWJlcjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBOT04tRE9NOiBHZXQgYSBudW1iZXIgYXNzb2NpYXRlZCB3aXRoIGEgbm9kZSBjcmVhdGVkIHdpdGggcmVzcGVjdCB0byB0aGlzCi0gICAgICogZG9jdW1lbnQuIE5lZWRlZCBmb3IgY29tcGFyZURvY3VtZW50UG9zaXRpb24gd2hlbiBub2RlcyBhcmUgZGlzY29ubmVjdGVkLgotICAgICAqIFRoaXMgaXMgb25seSB1c2VkIG9uIGRlbWFuZC4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgaW50IGdldE5vZGVOdW1iZXIoTm9kZSBub2RlKSB7Ci0KLSAgICAgICAgLy8gQ2hlY2sgaWYgdGhlIG5vZGUgaXMgYWxyZWFkeSBpbiB0aGUgaGFzaAotICAgICAgICAvLyBJZiBzbywgcmV0cmlldmUgdGhlIG5vZGUgbnVtYmVyCi0gICAgICAgIC8vIElmIG5vdCwgYXNzaWduIGEgbnVtYmVyIHRvIHRoZSBub2RlCi0gICAgICAgIC8vIE5vZGUgbnVtYmVycyBhcmUgbmVnYXRpdmUsIGZyb20gLTEgdG8gLW4KLSAgICAgICAgaW50IG51bTsKLSAgICAgICAgaWYgKG5vZGVUYWJsZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBub2RlVGFibGUgPSBuZXcgSGFzaE1hcDw+KCk7Ci0gICAgICAgICAgICBudW0gPSAtLW5vZGVDb3VudGVyOwotICAgICAgICAgICAgbm9kZVRhYmxlLnB1dChub2RlLCBuZXcgSW50ZWdlcihudW0pKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIEludGVnZXIgbiA9IG5vZGVUYWJsZS5nZXQobm9kZSk7Ci0gICAgICAgICAgICBpZiAobiA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgbnVtID0gLS1ub2RlQ291bnRlcjsKLSAgICAgICAgICAgICAgICBub2RlVGFibGUucHV0KG5vZGUsIG51bSk7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIG51bSA9IG4uaW50VmFsdWUoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbnVtOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvcGllcyBhIG5vZGUgZnJvbSBhbm90aGVyIGRvY3VtZW50IHRvIHRoaXMgZG9jdW1lbnQuIFRoZSBuZXcgbm9kZXMgYXJlCi0gICAgICogY3JlYXRlZCB1c2luZyB0aGlzIGRvY3VtZW50J3MgZmFjdG9yeSBtZXRob2RzIGFuZCBhcmUgcG9wdWxhdGVkIHdpdGggdGhlCi0gICAgICogZGF0YSBmcm9tIHRoZSBzb3VyY2UncyBhY2Nlc3NvciBtZXRob2RzIGRlZmluZWQgYnkgdGhlIERPTSBpbnRlcmZhY2VzLgotICAgICAqIEl0cyBiZWhhdmlvciBpcyBvdGhlcndpc2Ugc2ltaWxhciB0byB0aGF0IG9mIGNsb25lTm9kZS4KLSAgICAgKiA8cD4KLSAgICAgKiBBY2NvcmRpbmcgdG8gdGhlIERPTSBzcGVjaWZpY2F0aW9ucywgZG9jdW1lbnQgbm9kZXMgY2Fubm90IGJlIGltcG9ydGVkCi0gICAgICogYW5kIGEgTk9UX1NVUFBPUlRFRF9FUlIgZXhjZXB0aW9uIGlzIHRocm93biBpZiBhdHRlbXB0ZWQuCi0gICAgICovCi0gICAgcHVibGljIE5vZGUgaW1wb3J0Tm9kZShOb2RlIHNvdXJjZSwgYm9vbGVhbiBkZWVwKQotICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0gICAgICAgIHJldHVybiBpbXBvcnROb2RlKHNvdXJjZSwgZGVlcCwgZmFsc2UsIG51bGwpOwotICAgIH0gLy8gaW1wb3J0Tm9kZShOb2RlLGJvb2xlYW4pOk5vZGUKLQotICAgIC8qKgotICAgICAqIE92ZXJsb2FkZWQgaW1wbGVtZW50YXRpb24gb2YgRE9NJ3MgaW1wb3J0Tm9kZSBtZXRob2QuIFRoaXMgbWV0aG9kCi0gICAgICogcHJvdmlkZXMgdGhlIGNvcmUgZnVuY3Rpb25hbGl0eSBmb3IgdGhlIHB1YmxpYyBpbXBvcnROb2RlIGFuZCBjbG9uZU5vZGUKLSAgICAgKiBtZXRob2RzLgotICAgICAqCi0gICAgICogVGhlIHJldmVyc2VkSWRlbnRpZmllcnMgcGFyYW1ldGVyIGlzIHByb3ZpZGVkIGZvciBjbG9uZU5vZGUgdG8gcHJlc2VydmUKLSAgICAgKiB0aGUgZG9jdW1lbnQncyBpZGVudGlmaWVycy4gVGhlIE1hcCBoYXMgRWxlbWVudHMgYXMgdGhlIGtleXMgYW5kCi0gICAgICogdGhlaXIgaWRlbnRpZmllcnMgYXMgdGhlIHZhbHVlcy4gV2hlbiBhbiBlbGVtZW50IGlzIGJlaW5nIGltcG9ydGVkLCBhCi0gICAgICogY2hlY2sgaXMgZG9uZSBmb3IgYW4gYXNzb2NpYXRlZCBpZGVudGlmaWVyLiBJZiBvbmUgZXhpc3RzLCB0aGUgaWRlbnRpZmllcgotICAgICAqIGlzIHJlZ2lzdGVyZWQgd2l0aCB0aGUgbmV3LCBpbXBvcnRlZCBlbGVtZW50LiBJZiByZXZlcnNlZElkZW50aWZpZXJzIGlzCi0gICAgICogbnVsbCwgdGhlIHBhcmFtZXRlciBpcyBub3QgYXBwbGllZC4KLSAgICAgKi8KLSAgICBwcml2YXRlIE5vZGUgaW1wb3J0Tm9kZShOb2RlIHNvdXJjZSwgYm9vbGVhbiBkZWVwLCBib29sZWFuIGNsb25pbmdEb2MsCi0gICAgICAgICAgICBNYXA8Tm9kZSwgU3RyaW5nPiByZXZlcnNlZElkZW50aWZpZXJzKQotICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0gICAgICAgIE5vZGUgbmV3bm9kZSA9IG51bGw7Ci0gICAgICAgIE1hcDxTdHJpbmcsIFVzZXJEYXRhUmVjb3JkPiB1c2VyRGF0YSA9IG51bGw7Ci0KLSAgICAgICAgLy8gU2lnaC4gVGhpcyBkb2Vzbid0IHdvcms7IHRvbyBtYW55IG5vZGVzIGhhdmUgcHJpdmF0ZSBkYXRhIHRoYXQKLSAgICAgICAgLy8gd291bGQgaGF2ZSB0byBiZSBtYW51YWxseSB0d2Vha2VkLiBNYXkgYmUgYWJsZSB0byBhZGQgbG9jYWwKLSAgICAgICAgLy8gc2hvcnRjdXRzIHRvIGVhY2ggbm9kZXR5cGUuIENvbnNpZGVyID8/Pz8/Ci0gICAgICAgIC8vIGlmKHNvdXJjZSBpbnN0YW5jZW9mIE5vZGVJbXBsICYmCi0gICAgICAgIC8vICAhKHNvdXJjZSBpbnN0YW5jZW9mIERvY3VtZW50SW1wbCkpCi0gICAgICAgIC8vIHsKLSAgICAgICAgLy8gIC8vIENhbid0IGNsb25lIERvY3VtZW50SW1wbCBzaW5jZSBpdCBpbnZva2VzIHVzLi4uCi0gICAgICAgIC8vICBuZXdub2RlPShOb2RlSW1wbClzb3VyY2UuY2xvbmVOb2RlKGZhbHNlKTsKLSAgICAgICAgLy8gIG5ld25vZGUub3duZXJEb2N1bWVudD10aGlzOwotICAgICAgICAvLyB9Ci0gICAgICAgIC8vIGVsc2UKLSAgICAgICAgaWYgKHNvdXJjZSBpbnN0YW5jZW9mIE5vZGVJbXBsKSB7Ci0gICAgICAgICAgICB1c2VyRGF0YSA9ICgoTm9kZUltcGwpIHNvdXJjZSkuZ2V0VXNlckRhdGFSZWNvcmQoKTsKLSAgICAgICAgfQotICAgICAgICBpbnQgdHlwZSA9IHNvdXJjZS5nZXROb2RlVHlwZSgpOwotICAgICAgICBzd2l0Y2ggKHR5cGUpIHsKLSAgICAgICAgICAgIGNhc2UgRUxFTUVOVF9OT0RFOiB7Ci0gICAgICAgICAgICAgICAgRWxlbWVudCBuZXdFbGVtZW50OwotICAgICAgICAgICAgICAgIGJvb2xlYW4gZG9tTGV2ZWwyMCA9IHNvdXJjZS5nZXRPd25lckRvY3VtZW50KCkuZ2V0SW1wbGVtZW50YXRpb24oKS5oYXNGZWF0dXJlKCJYTUwiLCAiMi4wIik7Ci0gICAgICAgICAgICAgICAgLy8gQ3JlYXRlIGVsZW1lbnQgYWNjb3JkaW5nIHRvIG5hbWVzcGFjZSBzdXBwb3J0L3F1YWxpZmljYXRpb24uCi0gICAgICAgICAgICAgICAgaWYoZG9tTGV2ZWwyMCA9PSBmYWxzZSB8fCBzb3VyY2UuZ2V0TG9jYWxOYW1lKCkgPT0gbnVsbCkKLSAgICAgICAgICAgICAgICAgICAgbmV3RWxlbWVudCA9IGNyZWF0ZUVsZW1lbnQoc291cmNlLmdldE5vZGVOYW1lKCkpOwotICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgICAgbmV3RWxlbWVudCA9IGNyZWF0ZUVsZW1lbnROUyhzb3VyY2UuZ2V0TmFtZXNwYWNlVVJJKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgc291cmNlLmdldE5vZGVOYW1lKCkpOwotCi0gICAgICAgICAgICAgICAgLy8gQ29weSBlbGVtZW50J3MgYXR0cmlidXRlcywgaWYgYW55LgotICAgICAgICAgICAgICAgIE5hbWVkTm9kZU1hcCBzb3VyY2VBdHRycyA9IHNvdXJjZS5nZXRBdHRyaWJ1dGVzKCk7Ci0gICAgICAgICAgICAgICAgaWYgKHNvdXJjZUF0dHJzICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IHNvdXJjZUF0dHJzLmdldExlbmd0aCgpOwotICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpbmRleCA9IDA7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCsrKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBBdHRyIGF0dHIgPSAoQXR0cilzb3VyY2VBdHRycy5pdGVtKGluZGV4KTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gTk9URTogdGhpcyBtZXRob2RzIGlzIHVzZWQgZm9yIGJvdGggaW1wb3J0aW5nTm9kZQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gYW5kIGNsb25pbmcgdGhlIGRvY3VtZW50IG5vZGUuIEluIGNhc2Ugb2YgdGhlCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBjbG9ubmluZyBkZWZhdWx0IGF0dHJpYnV0ZXMgc2hvdWxkIGJlIGNvcGllZC4KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIEJ1dCBmb3IgaW1wb3J0Tm9kZSBkZWZhdWx0cyBzaG91bGQgYmUgaWdub3JlZC4KLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhdHRyLmdldFNwZWNpZmllZCgpIHx8IGNsb25pbmdEb2MpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdHRyIG5ld0F0dHIgPSAoQXR0cilpbXBvcnROb2RlKGF0dHIsIHRydWUsIGNsb25pbmdEb2MsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXZlcnNlZElkZW50aWZpZXJzKTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEF0dGFjaCBhdHRyaWJ1dGUgYWNjb3JkaW5nIHRvIG5hbWVzcGFjZQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHN1cHBvcnQvcXVhbGlmaWNhdGlvbi4KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZG9tTGV2ZWwyMCA9PSBmYWxzZSB8fAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHIuZ2V0TG9jYWxOYW1lKCkgPT0gbnVsbCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3RWxlbWVudC5zZXRBdHRyaWJ1dGVOb2RlKG5ld0F0dHIpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3RWxlbWVudC5zZXRBdHRyaWJ1dGVOb2RlTlMobmV3QXR0cik7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyBSZWdpc3RlciBlbGVtZW50IGlkZW50aWZpZXIuCi0gICAgICAgICAgICAgICAgaWYgKHJldmVyc2VkSWRlbnRpZmllcnMgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAvLyBEb2VzIGVsZW1lbnQgaGF2ZSBhbiBhc3NvY2lhdGVkIGlkZW50aWZpZXI/Ci0gICAgICAgICAgICAgICAgICAgIFN0cmluZyBlbGVtZW50SWQgPSByZXZlcnNlZElkZW50aWZpZXJzLmdldChzb3VyY2UpOwotICAgICAgICAgICAgICAgICAgICBpZiAoZWxlbWVudElkICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpZGVudGlmaWVycyA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWRlbnRpZmllcnMgPSBuZXcgSGFzaE1hcDw+KCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIGlkZW50aWZpZXJzLnB1dChlbGVtZW50SWQsIG5ld0VsZW1lbnQpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgbmV3bm9kZSA9IG5ld0VsZW1lbnQ7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGNhc2UgQVRUUklCVVRFX05PREU6IHsKLQotICAgICAgICAgICAgICAgIGlmKCBzb3VyY2UuZ2V0T3duZXJEb2N1bWVudCgpLmdldEltcGxlbWVudGF0aW9uKCkuaGFzRmVhdHVyZSgiWE1MIiwgIjIuMCIpICl7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChzb3VyY2UuZ2V0TG9jYWxOYW1lKCkgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgbmV3bm9kZSA9IGNyZWF0ZUF0dHJpYnV0ZShzb3VyY2UuZ2V0Tm9kZU5hbWUoKSk7Ci0gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBuZXdub2RlID0gY3JlYXRlQXR0cmlidXRlTlMoc291cmNlLmdldE5hbWVzcGFjZVVSSSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzb3VyY2UuZ2V0Tm9kZU5hbWUoKSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIG5ld25vZGUgPSBjcmVhdGVBdHRyaWJ1dGUoc291cmNlLmdldE5vZGVOYW1lKCkpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvLyBpZiBzb3VyY2UgaXMgYW4gQXR0ckltcGwgZnJvbSB0aGlzIHZlcnkgc2FtZSBpbXBsZW1lbnRhdGlvbgotICAgICAgICAgICAgICAgIC8vIGF2b2lkIGNyZWF0aW5nIHRoZSBjaGlsZCBub2RlcyBpZiBwb3NzaWJsZQotICAgICAgICAgICAgICAgIGlmIChzb3VyY2UgaW5zdGFuY2VvZiBBdHRySW1wbCkgewotICAgICAgICAgICAgICAgICAgICBBdHRySW1wbCBhdHRyID0gKEF0dHJJbXBsKSBzb3VyY2U7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChhdHRyLmhhc1N0cmluZ1ZhbHVlKCkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIEF0dHJJbXBsIG5ld2F0dHIgPSAoQXR0ckltcGwpIG5ld25vZGU7Ci0gICAgICAgICAgICAgICAgICAgICAgICBuZXdhdHRyLnNldFZhbHVlKGF0dHIuZ2V0VmFsdWUoKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBkZWVwID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBkZWVwID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gQWNjb3JkaW5nIHRvIHRoZSBET00gc3BlYyB0aGUga2lkcyBjYXJyeSB0aGUgdmFsdWUuCi0gICAgICAgICAgICAgICAgICAgIC8vIEhvd2V2ZXIsIHRoZXJlIGFyZSBub24gY29tcGxpYW50IGltcGxlbWVudGF0aW9ucyBvdXQKLSAgICAgICAgICAgICAgICAgICAgLy8gdGhlcmUgdGhhdCBmYWlsIHRvIGRvIHNvLiBUbyBhdm9pZCBlbmRpbmcgdXAgd2l0aCBubwotICAgICAgICAgICAgICAgICAgICAvLyB2YWx1ZSBhdCBhbGwsIGluIHRoaXMgY2FzZSB3ZSBzaW1wbHkgY29weSB0aGUgdGV4dCB2YWx1ZQotICAgICAgICAgICAgICAgICAgICAvLyBkaXJlY3RseS4KLSAgICAgICAgICAgICAgICAgICAgaWYgKHNvdXJjZS5nZXRGaXJzdENoaWxkKCkgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgbmV3bm9kZS5zZXROb2RlVmFsdWUoc291cmNlLmdldE5vZGVWYWx1ZSgpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGRlZXAgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGRlZXAgPSB0cnVlOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBjYXNlIFRFWFRfTk9ERTogewotICAgICAgICAgICAgICAgIG5ld25vZGUgPSBjcmVhdGVUZXh0Tm9kZShzb3VyY2UuZ2V0Tm9kZVZhbHVlKCkpOwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBjYXNlIENEQVRBX1NFQ1RJT05fTk9ERTogewotICAgICAgICAgICAgICAgIG5ld25vZGUgPSBjcmVhdGVDREFUQVNlY3Rpb24oc291cmNlLmdldE5vZGVWYWx1ZSgpKTsKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgY2FzZSBFTlRJVFlfUkVGRVJFTkNFX05PREU6IHsKLSAgICAgICAgICAgICAgICBuZXdub2RlID0gY3JlYXRlRW50aXR5UmVmZXJlbmNlKHNvdXJjZS5nZXROb2RlTmFtZSgpKTsKLSAgICAgICAgICAgICAgICAvLyB0aGUgc3VidHJlZSBpcyBjcmVhdGVkIGFjY29yZGluZyB0byB0aGlzIGRvYyBieSB0aGUgbWV0aG9kCi0gICAgICAgICAgICAgICAgLy8gYWJvdmUsIHNvIGF2b2lkIGNhcnJ5aW5nIG92ZXIgb3JpZ2luYWwgc3VidHJlZQotICAgICAgICAgICAgICAgIGRlZXAgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgY2FzZSBFTlRJVFlfTk9ERTogewotICAgICAgICAgICAgICAgIEVudGl0eSBzcmNlbnRpdHkgPSAoRW50aXR5KXNvdXJjZTsKLSAgICAgICAgICAgICAgICBFbnRpdHlJbXBsIG5ld2VudGl0eSA9Ci0gICAgICAgICAgICAgICAgKEVudGl0eUltcGwpY3JlYXRlRW50aXR5KHNvdXJjZS5nZXROb2RlTmFtZSgpKTsKLSAgICAgICAgICAgICAgICBuZXdlbnRpdHkuc2V0UHVibGljSWQoc3JjZW50aXR5LmdldFB1YmxpY0lkKCkpOwotICAgICAgICAgICAgICAgIG5ld2VudGl0eS5zZXRTeXN0ZW1JZChzcmNlbnRpdHkuZ2V0U3lzdGVtSWQoKSk7Ci0gICAgICAgICAgICAgICAgbmV3ZW50aXR5LnNldE5vdGF0aW9uTmFtZShzcmNlbnRpdHkuZ2V0Tm90YXRpb25OYW1lKCkpOwotICAgICAgICAgICAgICAgIC8vIEtpZHMgY2FycnkgYWRkaXRpb25hbCB2YWx1ZSwKLSAgICAgICAgICAgICAgICAvLyBhbGxvdyBkZWVwIGltcG9ydCB0ZW1wb3JhcmlseQotICAgICAgICAgICAgICAgIG5ld2VudGl0eS5pc1JlYWRPbmx5KGZhbHNlKTsKLSAgICAgICAgICAgICAgICBuZXdub2RlID0gbmV3ZW50aXR5OwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBjYXNlIFBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERTogewotICAgICAgICAgICAgICAgIG5ld25vZGUgPSBjcmVhdGVQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oc291cmNlLmdldE5vZGVOYW1lKCksCi0gICAgICAgICAgICAgICAgICAgICAgICBzb3VyY2UuZ2V0Tm9kZVZhbHVlKCkpOwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBjYXNlIENPTU1FTlRfTk9ERTogewotICAgICAgICAgICAgICAgIG5ld25vZGUgPSBjcmVhdGVDb21tZW50KHNvdXJjZS5nZXROb2RlVmFsdWUoKSk7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGNhc2UgRE9DVU1FTlRfVFlQRV9OT0RFOiB7Ci0gICAgICAgICAgICAgICAgLy8gdW5sZXNzIHRoaXMgaXMgdXNlZCBhcyBwYXJ0IG9mIGNsb25pbmcgYSBEb2N1bWVudAotICAgICAgICAgICAgICAgIC8vIGZvcmJpZCBpdCBmb3IgdGhlIHNha2Ugb2YgYmVpbmcgY29tcGxpYW50IHRvIHRoZSBET00gc3BlYwotICAgICAgICAgICAgICAgIGlmICghY2xvbmluZ0RvYykgewotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbXNnID0gRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwgIk5PVF9TVVBQT1JURURfRVJSIiwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSLCBtc2cpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBEb2N1bWVudFR5cGUgc3JjZG9jdHlwZSA9IChEb2N1bWVudFR5cGUpc291cmNlOwotICAgICAgICAgICAgICAgIERvY3VtZW50VHlwZUltcGwgbmV3ZG9jdHlwZSA9IChEb2N1bWVudFR5cGVJbXBsKQotICAgICAgICAgICAgICAgIGNyZWF0ZURvY3VtZW50VHlwZShzcmNkb2N0eXBlLmdldE5vZGVOYW1lKCksCi0gICAgICAgICAgICAgICAgICAgICAgICBzcmNkb2N0eXBlLmdldFB1YmxpY0lkKCksCi0gICAgICAgICAgICAgICAgICAgICAgICBzcmNkb2N0eXBlLmdldFN5c3RlbUlkKCkpOwotICAgICAgICAgICAgICAgIC8vIFZhbHVlcyBhcmUgb24gTmFtZWROb2RlTWFwcwotICAgICAgICAgICAgICAgIE5hbWVkTm9kZU1hcCBzbWFwID0gc3JjZG9jdHlwZS5nZXRFbnRpdGllcygpOwotICAgICAgICAgICAgICAgIE5hbWVkTm9kZU1hcCB0bWFwID0gbmV3ZG9jdHlwZS5nZXRFbnRpdGllcygpOwotICAgICAgICAgICAgICAgIGlmKHNtYXAgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgc21hcC5nZXRMZW5ndGgoKTsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICB0bWFwLnNldE5hbWVkSXRlbShpbXBvcnROb2RlKHNtYXAuaXRlbShpKSwgdHJ1ZSwgdHJ1ZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV2ZXJzZWRJZGVudGlmaWVycykpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHNtYXAgPSBzcmNkb2N0eXBlLmdldE5vdGF0aW9ucygpOwotICAgICAgICAgICAgICAgIHRtYXAgPSBuZXdkb2N0eXBlLmdldE5vdGF0aW9ucygpOwotICAgICAgICAgICAgICAgIGlmIChzbWFwICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgZm9yKGludCBpID0gMDsgaSA8IHNtYXAuZ2V0TGVuZ3RoKCk7IGkrKykgewotICAgICAgICAgICAgICAgICAgICAgICAgdG1hcC5zZXROYW1lZEl0ZW0oaW1wb3J0Tm9kZShzbWFwLml0ZW0oaSksIHRydWUsIHRydWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldmVyc2VkSWRlbnRpZmllcnMpKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8vIE5PVEU6IEF0IHRoaXMgdGltZSwgdGhlIERPTSBkZWZpbml0aW9uIG9mIERvY3VtZW50VHlwZQotICAgICAgICAgICAgICAgIC8vIGRvZXNuJ3QgY292ZXIgRWxlbWVudHMgYW5kIHRoZWlyIEF0dHJpYnV0ZXMuIGRvbWltcGwncwotICAgICAgICAgICAgICAgIC8vIGV4dGVudGlvbnMgaW4gdGhhdCBhcmVhIHdpbGwgbm90IGJlIHByZXNlcnZlZCwgZXZlbiBpZgotICAgICAgICAgICAgICAgIC8vIGNvcHlpbmcgZnJvbSBkb21pbXBsIHRvIGRvbWltcGwuIFdlIGNvdWxkIHNwZWNpYWwtY2FzZQotICAgICAgICAgICAgICAgIC8vIHRoYXQgaGVyZS4gQXJndWFibHkgd2Ugc2hvdWxkLiBDb25zaWRlci4gPz8/Pz8KLSAgICAgICAgICAgICAgICBuZXdub2RlID0gbmV3ZG9jdHlwZTsKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgY2FzZSBET0NVTUVOVF9GUkFHTUVOVF9OT0RFOiB7Ci0gICAgICAgICAgICAgICAgbmV3bm9kZSA9IGNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTsKLSAgICAgICAgICAgICAgICAvLyBObyBuYW1lLCBraWRzIGNhcnJ5IHZhbHVlCi0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGNhc2UgTk9UQVRJT05fTk9ERTogewotICAgICAgICAgICAgICAgIE5vdGF0aW9uIHNyY25vdGF0aW9uID0gKE5vdGF0aW9uKXNvdXJjZTsKLSAgICAgICAgICAgICAgICBOb3RhdGlvbkltcGwgbmV3bm90YXRpb24gPQotICAgICAgICAgICAgICAgIChOb3RhdGlvbkltcGwpY3JlYXRlTm90YXRpb24oc291cmNlLmdldE5vZGVOYW1lKCkpOwotICAgICAgICAgICAgICAgIG5ld25vdGF0aW9uLnNldFB1YmxpY0lkKHNyY25vdGF0aW9uLmdldFB1YmxpY0lkKCkpOwotICAgICAgICAgICAgICAgIG5ld25vdGF0aW9uLnNldFN5c3RlbUlkKHNyY25vdGF0aW9uLmdldFN5c3RlbUlkKCkpOwotICAgICAgICAgICAgICAgIC8vIEtpZHMgY2FycnkgYWRkaXRpb25hbCB2YWx1ZQotICAgICAgICAgICAgICAgIG5ld25vZGUgPSBuZXdub3RhdGlvbjsKLSAgICAgICAgICAgICAgICAvLyBObyBuYW1lLCBubyB2YWx1ZQotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2FzZSBET0NVTUVOVF9OT0RFIDogLy8gQ2FuJ3QgaW1wb3J0IGRvY3VtZW50IG5vZGVzCi0gICAgICAgICAgICBkZWZhdWx0OiB7ICAgICAgICAgICAvLyBVbmtub3duIG5vZGUgdHlwZQotICAgICAgICAgICAgICAgIFN0cmluZyBtc2cgPSBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiTk9UX1NVUFBPUlRFRF9FUlIiLCBudWxsKTsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUiwgbXNnKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgaWYodXNlckRhdGEgIT0gbnVsbCkKLSAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxVc2VyRGF0YUhhbmRsZXJzKHNvdXJjZSwgbmV3bm9kZSwgVXNlckRhdGFIYW5kbGVyLk5PREVfSU1QT1JURUQsdXNlckRhdGEpOwotCi0gICAgICAgIC8vIElmIGRlZXAsIHJlcGxpY2F0ZSBhbmQgYXR0YWNoIHRoZSBraWRzLgotICAgICAgICBpZiAoZGVlcCkgewotICAgICAgICAgICAgZm9yIChOb2RlIHNyY2tpZCA9IHNvdXJjZS5nZXRGaXJzdENoaWxkKCk7Ci0gICAgICAgICAgICAgICAgICAgIHNyY2tpZCAhPSBudWxsOwotICAgICAgICAgICAgICAgICAgICBzcmNraWQgPSBzcmNraWQuZ2V0TmV4dFNpYmxpbmcoKSkgewotICAgICAgICAgICAgICAgIG5ld25vZGUuYXBwZW5kQ2hpbGQoaW1wb3J0Tm9kZShzcmNraWQsIHRydWUsIGNsb25pbmdEb2MsCi0gICAgICAgICAgICAgICAgICAgICAgICByZXZlcnNlZElkZW50aWZpZXJzKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKG5ld25vZGUuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLkVOVElUWV9OT0RFKSB7Ci0gICAgICAgICAgICAoKE5vZGVJbXBsKW5ld25vZGUpLnNldFJlYWRPbmx5KHRydWUsIHRydWUpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBuZXdub2RlOwotCi0gICAgfSAvLyBpbXBvcnROb2RlKE5vZGUsYm9vbGVhbixib29sZWFuLE1hcCk6Tm9kZQotCi0gICAgLyoqCi0gICAgICogRE9NIExldmVsIDMgV0QgLSBFeHBlcmltZW50YWwKLSAgICAgKiBDaGFuZ2UgdGhlIG5vZGUncyBvd25lckRvY3VtZW50LCBhbmQgaXRzIHN1YnRyZWUsIHRvIHRoaXMgRG9jdW1lbnQKLSAgICAgKgotICAgICAqIEBwYXJhbSBzb3VyY2UgVGhlIG5vZGUgdG8gYWRvcHQuCi0gICAgICogQHNlZSAjaW1wb3J0Tm9kZQotICAgICAqKi8KLSAgICBwdWJsaWMgTm9kZSBhZG9wdE5vZGUoTm9kZSBzb3VyY2UpIHsKLSAgICAgICAgTm9kZUltcGwgbm9kZTsKLSAgICAgICAgTWFwPFN0cmluZywgVXNlckRhdGFSZWNvcmQ+IHVzZXJEYXRhOwotICAgICAgICB0cnkgewotICAgICAgICAgICAgbm9kZSA9IChOb2RlSW1wbCkgc291cmNlOwotICAgICAgICB9IGNhdGNoIChDbGFzc0Nhc3RFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgLy8gc291cmNlIG5vZGUgY29tZXMgZnJvbSBhIGRpZmZlcmVudCBET01JbXBsZW1lbnRhdGlvbgotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBSZXR1cm4gbnVsbCBpZiB0aGUgc291cmNlIGlzIG51bGwKLQotICAgICAgICBpZiAoc291cmNlID09IG51bGwgKSB7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfSBlbHNlIGlmIChzb3VyY2UuZ2V0T3duZXJEb2N1bWVudCgpICE9IG51bGwpIHsKLQotICAgICAgICAgICAgRE9NSW1wbGVtZW50YXRpb24gdGhpc0ltcGwgPSB0aGlzLmdldEltcGxlbWVudGF0aW9uKCk7Ci0gICAgICAgICAgICBET01JbXBsZW1lbnRhdGlvbiBvdGhlckltcGwgPSBzb3VyY2UuZ2V0T3duZXJEb2N1bWVudCgpLmdldEltcGxlbWVudGF0aW9uKCk7Ci0KLSAgICAgICAgICAgIC8vIHdoZW4gdGhlIHNvdXJjZSBub2RlIGNvbWVzIGZyb20gYSBkaWZmZXJlbnQgaW1wbGVtZW50YXRpb24uCi0gICAgICAgICAgICBpZiAodGhpc0ltcGwgIT0gb3RoZXJJbXBsKSB7Ci0KLSAgICAgICAgICAgICAgICAvLyBBZG9wdGluZyBmcm9tIGEgRGVmZmVyZWRET00gdG8gRE9NCi0gICAgICAgICAgICAgICAgaWYgKHRoaXNJbXBsIGluc3RhbmNlb2YgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5kb20uRE9NSW1wbGVtZW50YXRpb25JbXBsICYmCi0gICAgICAgICAgICAgICAgICAgICAgICBvdGhlckltcGwgaW5zdGFuY2VvZiBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbS5EZWZlcnJlZERPTUltcGxlbWVudGF0aW9uSW1wbCkgewotICAgICAgICAgICAgICAgICAgICAvLyB0cmF2ZXJzZSB0aGUgRE9NIGFuZCBleHBhbmQgZGVmZmVyZWQgbm9kZXMgYW5kIHRoZW4gYWxsb3cgYWRvcHRpb24KLSAgICAgICAgICAgICAgICAgICAgdW5kZWZlckNoaWxkcmVuIChub2RlKTsKLSAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCB0aGlzSW1wbCBpbnN0YW5jZW9mIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tLkRlZmVycmVkRE9NSW1wbGVtZW50YXRpb25JbXBsCi0gICAgICAgICAgICAgICAgICAgICAgICAmJiBvdGhlckltcGwgaW5zdGFuY2VvZiBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbS5ET01JbXBsZW1lbnRhdGlvbkltcGwpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gQWRvcHRpbmcgZnJvbSBhIERPTSBpbnRvIGEgRGVmZmVyZWRET00sIHRoaXMgc2hvdWxkIGJlIG9rYXkKLSAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAvLyBBZG9wdGluZyBiZXR3ZWVuIHR3byBkaXNzaW1pbGFyIERPTSdzIGlzIG5vdCBhbGxvd2VkCi0gICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHN3aXRjaCAobm9kZS5nZXROb2RlVHlwZSgpKSB7Ci0gICAgICAgICAgICBjYXNlIEFUVFJJQlVURV9OT0RFOiB7Ci0gICAgICAgICAgICAgICAgQXR0ckltcGwgYXR0ciA9IChBdHRySW1wbCkgbm9kZTsKLSAgICAgICAgICAgICAgICAvLyByZW1vdmUgbm9kZSBmcm9tIHdoZXJldmVyIGl0IGlzCi0gICAgICAgICAgICAgICAgaWYoIGF0dHIuZ2V0T3duZXJFbGVtZW50KCkgIT0gbnVsbCl7Ci0gICAgICAgICAgICAgICAgICAgIC8vMS4gb3duZXIgZWxlbWVudCBhdHRyaWJ1dGUgaXMgc2V0IHRvIG51bGwKLSAgICAgICAgICAgICAgICAgICAgYXR0ci5nZXRPd25lckVsZW1lbnQoKS5yZW1vdmVBdHRyaWJ1dGVOb2RlKGF0dHIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvLzIuIHNwZWNpZmllZCBmbGFnIGlzIHNldCB0byB0cnVlCi0gICAgICAgICAgICAgICAgYXR0ci5pc1NwZWNpZmllZCh0cnVlKTsKLSAgICAgICAgICAgICAgICB1c2VyRGF0YSA9IG5vZGUuZ2V0VXNlckRhdGFSZWNvcmQoKTsKLQotICAgICAgICAgICAgICAgIC8vMy4gY2hhbmdlIG93bmVyc2hpcAotICAgICAgICAgICAgICAgIGF0dHIuc2V0T3duZXJEb2N1bWVudCh0aGlzKTsKLSAgICAgICAgICAgICAgICBpZiAodXNlckRhdGEgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBzZXRVc2VyRGF0YVRhYmxlKG5vZGUsIHVzZXJEYXRhKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvL2VudGl0eSwgbm90YXRpb24gbm9kZXMgYXJlIHJlYWQgb25seSBub2Rlcy4uIHNvIHRoZXkgY2FuJ3QgYmUgYWRvcHRlZC4KLSAgICAgICAgICAgIC8vcnVudGltZSB3aWxsIGZhbGwgdGhyb3VnaCB0byBOT1RBVElPTl9OT0RFCi0gICAgICAgICAgICBjYXNlIEVOVElUWV9OT0RFOgotICAgICAgICAgICAgY2FzZSBOT1RBVElPTl9OT0RFOnsKLSAgICAgICAgICAgICAgICBTdHJpbmcgbXNnID0gRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwgIk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiIsIG51bGwpOwotICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiwgbXNnKTsKLQotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy9kb2N1bWVudCwgZG9jdW1lbnR5cGUgbm9kZXMgY2FuJ3QgYmUgYWRvcHRlZC4KLSAgICAgICAgICAgIC8vcnVudGltZSB3aWxsIGZhbGwgdGhyb3VnaCB0byBEb2N1bWVudFR5cGVOb2RlCi0gICAgICAgICAgICBjYXNlIERPQ1VNRU5UX05PREU6Ci0gICAgICAgICAgICBjYXNlIERPQ1VNRU5UX1RZUEVfTk9ERTogewotICAgICAgICAgICAgICAgIFN0cmluZyBtc2cgPSBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiTk9UX1NVUFBPUlRFRF9FUlIiLCBudWxsKTsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUiwgbXNnKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhc2UgRU5USVRZX1JFRkVSRU5DRV9OT0RFOiB7Ci0gICAgICAgICAgICAgICAgdXNlckRhdGEgPSBub2RlLmdldFVzZXJEYXRhUmVjb3JkKCk7Ci0gICAgICAgICAgICAgICAgLy8gcmVtb3ZlIG5vZGUgZnJvbSB3aGVyZXZlciBpdCBpcwotICAgICAgICAgICAgICAgIE5vZGUgcGFyZW50ID0gbm9kZS5nZXRQYXJlbnROb2RlKCk7Ci0gICAgICAgICAgICAgICAgaWYgKHBhcmVudCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIHBhcmVudC5yZW1vdmVDaGlsZChzb3VyY2UpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvLyBkaXNjYXJkIGl0cyByZXBsYWNlbWVudCB2YWx1ZQotICAgICAgICAgICAgICAgIE5vZGUgY2hpbGQ7Ci0gICAgICAgICAgICAgICAgd2hpbGUgKChjaGlsZCA9IG5vZGUuZ2V0Rmlyc3RDaGlsZCgpKSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIG5vZGUucmVtb3ZlQ2hpbGQoY2hpbGQpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvLyBjaGFuZ2Ugb3duZXJzaGlwCi0gICAgICAgICAgICAgICAgbm9kZS5zZXRPd25lckRvY3VtZW50KHRoaXMpOwotICAgICAgICAgICAgICAgIGlmICh1c2VyRGF0YSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIHNldFVzZXJEYXRhVGFibGUobm9kZSwgdXNlckRhdGEpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvLyBzZXQgaXRzIG5ldyByZXBsYWNlbWVudCB2YWx1ZSBpZiBhbnkKLSAgICAgICAgICAgICAgICBpZiAoZG9jVHlwZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBOYW1lZE5vZGVNYXAgZW50aXRpZXMgPSBkb2NUeXBlLmdldEVudGl0aWVzKCk7Ci0gICAgICAgICAgICAgICAgTm9kZSBlbnRpdHlOb2RlID0gZW50aXRpZXMuZ2V0TmFtZWRJdGVtKG5vZGUuZ2V0Tm9kZU5hbWUoKSk7Ci0gICAgICAgICAgICAgICAgaWYgKGVudGl0eU5vZGUgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZm9yIChjaGlsZCA9IGVudGl0eU5vZGUuZ2V0Rmlyc3RDaGlsZCgpOwotICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGQgIT0gbnVsbDsgY2hpbGQgPSBjaGlsZC5nZXROZXh0U2libGluZygpKSB7Ci0gICAgICAgICAgICAgICAgICAgIE5vZGUgY2hpbGRDbG9uZSA9IGNoaWxkLmNsb25lTm9kZSh0cnVlKTsKLSAgICAgICAgICAgICAgICAgICAgbm9kZS5hcHBlbmRDaGlsZChjaGlsZENsb25lKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXNlIEVMRU1FTlRfTk9ERTogewotICAgICAgICAgICAgICAgIHVzZXJEYXRhID0gbm9kZS5nZXRVc2VyRGF0YVJlY29yZCgpOwotICAgICAgICAgICAgICAgIC8vIHJlbW92ZSBub2RlIGZyb20gd2hlcmV2ZXIgaXQgaXMKLSAgICAgICAgICAgICAgICBOb2RlIHBhcmVudCA9IG5vZGUuZ2V0UGFyZW50Tm9kZSgpOwotICAgICAgICAgICAgICAgIGlmIChwYXJlbnQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBwYXJlbnQucmVtb3ZlQ2hpbGQoc291cmNlKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLy8gY2hhbmdlIG93bmVyc2hpcAotICAgICAgICAgICAgICAgIG5vZGUuc2V0T3duZXJEb2N1bWVudCh0aGlzKTsKLSAgICAgICAgICAgICAgICBpZiAodXNlckRhdGEgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBzZXRVc2VyRGF0YVRhYmxlKG5vZGUsIHVzZXJEYXRhKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLy8gcmVjb25jaWxlIGRlZmF1bHQgYXR0cmlidXRlcwotICAgICAgICAgICAgICAgICgoRWxlbWVudEltcGwpbm9kZSkucmVjb25jaWxlRGVmYXVsdEF0dHJpYnV0ZXMoKTsKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGRlZmF1bHQ6IHsKLSAgICAgICAgICAgICAgICB1c2VyRGF0YSA9IG5vZGUuZ2V0VXNlckRhdGFSZWNvcmQoKTsKLSAgICAgICAgICAgICAgICAvLyByZW1vdmUgbm9kZSBmcm9tIHdoZXJldmVyIGl0IGlzCi0gICAgICAgICAgICAgICAgTm9kZSBwYXJlbnQgPSBub2RlLmdldFBhcmVudE5vZGUoKTsKLSAgICAgICAgICAgICAgICBpZiAocGFyZW50ICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgcGFyZW50LnJlbW92ZUNoaWxkKHNvdXJjZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIC8vIGNoYW5nZSBvd25lcnNoaXAKLSAgICAgICAgICAgICAgICBub2RlLnNldE93bmVyRG9jdW1lbnQodGhpcyk7Ci0gICAgICAgICAgICAgICAgaWYgKHVzZXJEYXRhICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgc2V0VXNlckRhdGFUYWJsZShub2RlLCB1c2VyRGF0YSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvL0RPTSBMMyBDb3JlIENSCi0gICAgICAgIC8vaHR0cDovL3d3dy53My5vcmcvVFIvMjAwMy9DUi1ET00tTGV2ZWwtMy1Db3JlLTIwMDMxMTA3L2NvcmUuaHRtbCNVc2VyRGF0YUhhbmRsZXItQURPUFRFRAotICAgICAgICBpZiAodXNlckRhdGEgIT0gbnVsbCkgewotICAgICAgICAgICAgY2FsbFVzZXJEYXRhSGFuZGxlcnMoc291cmNlLCBudWxsLCBVc2VyRGF0YUhhbmRsZXIuTk9ERV9BRE9QVEVELCB1c2VyRGF0YSk7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gbm9kZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmF2ZXJzZXMgdGhlIERPTSBUcmVlIGFuZCBleHBhbmRzIGRlZmVycmVkIG5vZGVzIGFuZCB0aGVpcgotICAgICAqIGNoaWxkcmVuLgotICAgICAqCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgdW5kZWZlckNoaWxkcmVuKE5vZGUgbm9kZSkgewotCi0gICAgICAgIE5vZGUgdG9wID0gbm9kZTsKLQotICAgICAgICB3aGlsZSAobnVsbCAhPSBub2RlKSB7Ci0KLSAgICAgICAgICAgIGlmICgoKE5vZGVJbXBsKW5vZGUpLm5lZWRzU3luY0RhdGEoKSkgewotICAgICAgICAgICAgICAgICgoTm9kZUltcGwpbm9kZSkuc3luY2hyb25pemVEYXRhKCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIE5hbWVkTm9kZU1hcCBhdHRyaWJ1dGVzID0gbm9kZS5nZXRBdHRyaWJ1dGVzKCk7Ci0gICAgICAgICAgICBpZiAoYXR0cmlidXRlcyAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGF0dHJpYnV0ZXMuZ2V0TGVuZ3RoKCk7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkgewotICAgICAgICAgICAgICAgICAgICB1bmRlZmVyQ2hpbGRyZW4oYXR0cmlidXRlcy5pdGVtKGkpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIE5vZGUgbmV4dE5vZGUgPSBudWxsOwotICAgICAgICAgICAgbmV4dE5vZGUgPSBub2RlLmdldEZpcnN0Q2hpbGQoKTsKLQotICAgICAgICAgICAgd2hpbGUgKG51bGwgPT0gbmV4dE5vZGUpIHsKLQotICAgICAgICAgICAgICAgIGlmICh0b3AuZXF1YWxzKG5vZGUpKQotICAgICAgICAgICAgICAgICAgICBicmVhazsKLQotICAgICAgICAgICAgICAgIG5leHROb2RlID0gbm9kZS5nZXROZXh0U2libGluZygpOwotCi0gICAgICAgICAgICAgICAgaWYgKG51bGwgPT0gbmV4dE5vZGUpIHsKLSAgICAgICAgICAgICAgICAgICAgbm9kZSA9IG5vZGUuZ2V0UGFyZW50Tm9kZSgpOwotCi0gICAgICAgICAgICAgICAgICAgIGlmICgobnVsbCA9PSBub2RlKSB8fCAodG9wLmVxdWFscyhub2RlKSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIG5leHROb2RlID0gbnVsbDsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBub2RlID0gbmV4dE5vZGU7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvLyBpZGVudGlmaWVyIG1haW50ZW5lbmNlCi0gICAgLyoqCi0gICAgICogSW50cm9kdWNlZCBpbiBET00gTGV2ZWwgMgotICAgICAqIFJldHVybnMgdGhlIEVsZW1lbnQgd2hvc2UgSUQgaXMgZ2l2ZW4gYnkgZWxlbWVudElkLiBJZiBubyBzdWNoIGVsZW1lbnQKLSAgICAgKiBleGlzdHMsIHJldHVybnMgbnVsbC4gQmVoYXZpb3IgaXMgbm90IGRlZmluZWQgaWYgbW9yZSB0aGFuIG9uZSBlbGVtZW50Ci0gICAgICogaGFzIHRoaXMgSUQuCi0gICAgICogPHA+Ci0gICAgICogTm90ZTogVGhlIERPTSBpbXBsZW1lbnRhdGlvbiBtdXN0IGhhdmUgaW5mb3JtYXRpb24gdGhhdCBzYXlzIHdoaWNoCi0gICAgICogYXR0cmlidXRlcyBhcmUgb2YgdHlwZSBJRC4gQXR0cmlidXRlcyB3aXRoIHRoZSBuYW1lICJJRCIgYXJlIG5vdCBvZiB0eXBlCi0gICAgICogSUQgdW5sZXNzIHNvIGRlZmluZWQuIEltcGxlbWVudGF0aW9ucyB0aGF0IGRvIG5vdCBrbm93IHdoZXRoZXIKLSAgICAgKiBhdHRyaWJ1dGVzIGFyZSBvZiB0eXBlIElEIG9yIG5vdCBhcmUgZXhwZWN0ZWQgdG8gcmV0dXJuIG51bGwuCi0gICAgICogQHNlZSAjZ2V0SWRlbnRpZmllcgotICAgICAqLwotICAgIHB1YmxpYyBFbGVtZW50IGdldEVsZW1lbnRCeUlkKFN0cmluZyBlbGVtZW50SWQpIHsKLSAgICAgICAgcmV0dXJuIGdldElkZW50aWZpZXIoZWxlbWVudElkKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZW1vdmUgYWxsIGlkZW50aWZpZXJzIGZyb20gdGhlIElEIHRhYmxlCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGZpbmFsIHZvaWQgY2xlYXJJZGVudGlmaWVycygpewotICAgICAgICBpZiAoaWRlbnRpZmllcnMgIT0gbnVsbCl7Ci0gICAgICAgICAgICBpZGVudGlmaWVycy5jbGVhcigpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmVnaXN0ZXJzIGFuIGlkZW50aWZpZXIgbmFtZSB3aXRoIGEgc3BlY2lmaWVkIGVsZW1lbnQgbm9kZS4KLSAgICAgKiBJZiB0aGUgaWRlbnRpZmllciBpcyBhbHJlYWR5IHJlZ2lzdGVyZWQsIHRoZSBuZXcgZWxlbWVudAotICAgICAqIG5vZGUgcmVwbGFjZXMgdGhlIHByZXZpb3VzIG5vZGUuIElmIHRoZSBzcGVjaWZpZWQgZWxlbWVudAotICAgICAqIG5vZGUgaXMgbnVsbCwgcmVtb3ZlSWRlbnRpZmllcigpIGlzIGNhbGxlZC4KLSAgICAgKgotICAgICAqIEBzZWUgI2dldElkZW50aWZpZXIKLSAgICAgKiBAc2VlICNyZW1vdmVJZGVudGlmaWVyCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcHV0SWRlbnRpZmllcihTdHJpbmcgaWROYW1lLCBFbGVtZW50IGVsZW1lbnQpIHsKLQotICAgICAgICBpZiAoZWxlbWVudCA9PSBudWxsKSB7Ci0gICAgICAgICAgICByZW1vdmVJZGVudGlmaWVyKGlkTmFtZSk7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAobmVlZHNTeW5jRGF0YSgpKSB7Ci0gICAgICAgICAgICBzeW5jaHJvbml6ZURhdGEoKTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChpZGVudGlmaWVycyA9PSBudWxsKSB7Ci0gICAgICAgICAgICBpZGVudGlmaWVycyA9IG5ldyBIYXNoTWFwPD4oKTsKLSAgICAgICAgfQotCi0gICAgICAgIGlkZW50aWZpZXJzLnB1dChpZE5hbWUsIGVsZW1lbnQpOwotCi0gICAgfSAvLyBwdXRJZGVudGlmaWVyKFN0cmluZyxFbGVtZW50KQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhIHByZXZpb3VzbHkgcmVnaXN0ZXJlZCBlbGVtZW50IHdpdGggdGhlIHNwZWNpZmllZAotICAgICAqIGlkZW50aWZpZXIgbmFtZSwgb3IgbnVsbCBpZiBubyBlbGVtZW50IGlzIHJlZ2lzdGVyZWQuCi0gICAgICoKLSAgICAgKiBAc2VlICNwdXRJZGVudGlmaWVyCi0gICAgICogQHNlZSAjcmVtb3ZlSWRlbnRpZmllcgotICAgICAqLwotICAgIHB1YmxpYyBFbGVtZW50IGdldElkZW50aWZpZXIoU3RyaW5nIGlkTmFtZSkgewotCi0gICAgICAgIGlmIChuZWVkc1N5bmNEYXRhKCkpIHsKLSAgICAgICAgICAgIHN5bmNocm9uaXplRGF0YSgpOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKGlkZW50aWZpZXJzID09IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgICAgIEVsZW1lbnQgZWxlbSA9IChFbGVtZW50KSBpZGVudGlmaWVycy5nZXQoaWROYW1lKTsKLSAgICAgICAgaWYgKGVsZW0gIT0gbnVsbCkgewotICAgICAgICAgICAgLy8gY2hlY2sgdGhhdCB0aGUgZWxlbWVudCBpcyBpbiB0aGUgdHJlZQotICAgICAgICAgICAgTm9kZSBwYXJlbnQgPSBlbGVtLmdldFBhcmVudE5vZGUoKTsKLSAgICAgICAgICAgIHdoaWxlIChwYXJlbnQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGlmIChwYXJlbnQgPT0gdGhpcykgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gZWxlbTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgcGFyZW50ID0gcGFyZW50LmdldFBhcmVudE5vZGUoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9IC8vIGdldElkZW50aWZpZXIoU3RyaW5nKTpFbGVtZW50Ci0KLSAgICAvKioKLSAgICAgKiBSZW1vdmVzIGEgcHJldmlvdXNseSByZWdpc3RlcmVkIGVsZW1lbnQgd2l0aCB0aGUgc3BlY2lmaWVkCi0gICAgICogaWRlbnRpZmllciBuYW1lLgotICAgICAqCi0gICAgICogQHNlZSAjcHV0SWRlbnRpZmllcgotICAgICAqIEBzZWUgI2dldElkZW50aWZpZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCByZW1vdmVJZGVudGlmaWVyKFN0cmluZyBpZE5hbWUpIHsKLQotICAgICAgICBpZiAobmVlZHNTeW5jRGF0YSgpKSB7Ci0gICAgICAgICAgICBzeW5jaHJvbml6ZURhdGEoKTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChpZGVudGlmaWVycyA9PSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLQotICAgICAgICBpZGVudGlmaWVycy5yZW1vdmUoaWROYW1lKTsKLQotICAgIH0gLy8gcmVtb3ZlSWRlbnRpZmllcihTdHJpbmcpCi0KLSAgICAvLwotICAgIC8vIERPTTI6IE5hbWVzcGFjZSBtZXRob2RzCi0gICAgLy8KLSAgICAvKioKLSAgICAgKiBJbnRyb2R1Y2VkIGluIERPTSBMZXZlbCAyLiA8cD4KLSAgICAgKiBDcmVhdGVzIGFuIGVsZW1lbnQgb2YgdGhlIGdpdmVuIHF1YWxpZmllZCBuYW1lIGFuZCBuYW1lc3BhY2UgVVJJLgotICAgICAqIElmIHRoZSBnaXZlbiBuYW1lc3BhY2VVUkkgaXMgbnVsbCBvciBhbiBlbXB0eSBzdHJpbmcgYW5kIHRoZQotICAgICAqIHF1YWxpZmllZE5hbWUgaGFzIGEgcHJlZml4IHRoYXQgaXMgInhtbCIsIHRoZSBjcmVhdGVkIGVsZW1lbnQKLSAgICAgKiBpcyBib3VuZCB0byB0aGUgcHJlZGVmaW5lZCBuYW1lc3BhY2UKLSAgICAgKiAiaHR0cDovL3d3dy53My5vcmcvWE1MLzE5OTgvbmFtZXNwYWNlIiBbTmFtZXNwYWNlc10uCi0gICAgICogQHBhcmFtIG5hbWVzcGFjZVVSSSBUaGUgbmFtZXNwYWNlIFVSSSBvZiB0aGUgZWxlbWVudCB0bwotICAgICAqICAgICAgICAgICAgICAgICAgICAgY3JlYXRlLgotICAgICAqIEBwYXJhbSBxdWFsaWZpZWROYW1lIFRoZSBxdWFsaWZpZWQgbmFtZSBvZiB0aGUgZWxlbWVudCB0eXBlIHRvCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgaW5zdGFudGlhdGUuCi0gICAgICogQHJldHVybiBFbGVtZW50IEEgbmV3IEVsZW1lbnQgb2JqZWN0IHdpdGggdGhlIGZvbGxvd2luZyBhdHRyaWJ1dGVzOgotICAgICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uIElOVkFMSURfQ0hBUkFDVEVSX0VSUjogUmFpc2VkIGlmIHRoZSBzcGVjaWZpZWQKLSAgICAgKiBuYW1lIGNvbnRhaW5zIGFuIGludmFsaWQgY2hhcmFjdGVyLgotICAgICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uIE5BTUVTUEFDRV9FUlI6IFJhaXNlZCBpZiB0aGUgcXVhbGlmaWVkTmFtZSBoYXMgYQotICAgICAqICAgICAgICAgICAgICAgICAgICAgIHByZWZpeCB0aGF0IGlzICJ4bWwiIGFuZCB0aGUgbmFtZXNwYWNlVVJJIGlzCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgbmVpdGhlciBudWxsIG5vciBhbiBlbXB0eSBzdHJpbmcgbm9yCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgImh0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZSIsIG9yCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgaWYgdGhlIHF1YWxpZmllZE5hbWUgaGFzIGEgcHJlZml4IGRpZmZlcmVudAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGZyb20gInhtbCIgYW5kIHRoZSBuYW1lc3BhY2VVUkkgaXMgbnVsbCBvciBhbgotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGVtcHR5IHN0cmluZy4KLSAgICAgKiBAc2luY2UgV0QtRE9NLUxldmVsLTItMTk5OTA5MjMKLSAgICAgKi8KLSAgICBwdWJsaWMgRWxlbWVudCBjcmVhdGVFbGVtZW50TlMoU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIHF1YWxpZmllZE5hbWUpCi0gICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKLSAgICAgICAgcmV0dXJuIG5ldyBFbGVtZW50TlNJbXBsKHRoaXMsIG5hbWVzcGFjZVVSSSwgcXVhbGlmaWVkTmFtZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogTk9OLURPTTogYSBmYWN0b3J5IG1ldGhvZCB1c2VkIGJ5IHRoZSBYZXJjZXMgRE9NIHBhcnNlcgotICAgICAqIHRvIGNyZWF0ZSBhbiBlbGVtZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWVzcGFjZVVSSSBUaGUgbmFtZXNwYWNlIFVSSSBvZiB0aGUgZWxlbWVudCB0bwotICAgICAqICAgICAgICAgICAgICAgICAgICAgY3JlYXRlLgotICAgICAqIEBwYXJhbSBxdWFsaWZpZWROYW1lIFRoZSBxdWFsaWZpZWQgbmFtZSBvZiB0aGUgZWxlbWVudCB0eXBlIHRvCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgaW5zdGFudGlhdGUuCi0gICAgICogQHBhcmFtIGxvY2FscGFydCAgVGhlIGxvY2FsIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZSB0byBpbnN0YW50aWF0ZS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gRWxlbWVudCBBIG5ldyBFbGVtZW50IG9iamVjdCB3aXRoIHRoZSBmb2xsb3dpbmcgYXR0cmlidXRlczoKLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbiBJTlZBTElEX0NIQVJBQ1RFUl9FUlI6IFJhaXNlZCBpZiB0aGUgc3BlY2lmaWVkCi0gICAgICogICAgICAgICAgICAgICAgICAgbmFtZSBjb250YWlucyBhbiBpbnZhbGlkIGNoYXJhY3Rlci4KLSAgICAgKi8KLSAgICBwdWJsaWMgRWxlbWVudCBjcmVhdGVFbGVtZW50TlMoU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIHF1YWxpZmllZE5hbWUsCi0gICAgICAgICAgICBTdHJpbmcgbG9jYWxwYXJ0KQotICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0gICAgICAgIHJldHVybiBuZXcgRWxlbWVudE5TSW1wbCh0aGlzLCBuYW1lc3BhY2VVUkksIHF1YWxpZmllZE5hbWUsIGxvY2FscGFydCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSW50cm9kdWNlZCBpbiBET00gTGV2ZWwgMi4gPHA+Ci0gICAgICogQ3JlYXRlcyBhbiBhdHRyaWJ1dGUgb2YgdGhlIGdpdmVuIHF1YWxpZmllZCBuYW1lIGFuZCBuYW1lc3BhY2UgVVJJLgotICAgICAqIElmIHRoZSBnaXZlbiBuYW1lc3BhY2VVUkkgaXMgbnVsbCBvciBhbiBlbXB0eSBzdHJpbmcgYW5kIHRoZQotICAgICAqIHF1YWxpZmllZE5hbWUgaGFzIGEgcHJlZml4IHRoYXQgaXMgInhtbCIsIHRoZSBjcmVhdGVkIGVsZW1lbnQKLSAgICAgKiBpcyBib3VuZCB0byB0aGUgcHJlZGVmaW5lZCBuYW1lc3BhY2UKLSAgICAgKiAiaHR0cDovL3d3dy53My5vcmcvWE1MLzE5OTgvbmFtZXNwYWNlIiBbTmFtZXNwYWNlc10uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZXNwYWNlVVJJICBUaGUgbmFtZXNwYWNlIFVSSSBvZiB0aGUgYXR0cmlidXRlIHRvCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgY3JlYXRlLiBXaGVuIGl0IGlzIG51bGwgb3IgYW4gZW1wdHkgc3RyaW5nLAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIHRoaXMgbWV0aG9kIGJlaGF2ZXMgbGlrZSBjcmVhdGVBdHRyaWJ1dGUuCi0gICAgICogQHBhcmFtIHF1YWxpZmllZE5hbWUgVGhlIHF1YWxpZmllZCBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUgdG8KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBpbnN0YW50aWF0ZS4KLSAgICAgKiBAcmV0dXJuIEF0dHIgICAgICAgICBBIG5ldyBBdHRyIG9iamVjdC4KLSAgICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbiBJTlZBTElEX0NIQVJBQ1RFUl9FUlI6IFJhaXNlZCBpZiB0aGUgc3BlY2lmaWVkCi0gICAgICogbmFtZSBjb250YWlucyBhbiBpbnZhbGlkIGNoYXJhY3Rlci4KLSAgICAgKiBAc2luY2UgV0QtRE9NLUxldmVsLTItMTk5OTA5MjMKLSAgICAgKi8KLSAgICBwdWJsaWMgQXR0ciBjcmVhdGVBdHRyaWJ1dGVOUyhTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgcXVhbGlmaWVkTmFtZSkKLSAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb24gewotICAgICAgICByZXR1cm4gbmV3IEF0dHJOU0ltcGwodGhpcywgbmFtZXNwYWNlVVJJLCBxdWFsaWZpZWROYW1lKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBOT04tRE9NOiBhIGZhY3RvcnkgbWV0aG9kIHVzZWQgYnkgdGhlIFhlcmNlcyBET00gcGFyc2VyCi0gICAgICogdG8gY3JlYXRlIGFuIGVsZW1lbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZXNwYWNlVVJJICBUaGUgbmFtZXNwYWNlIFVSSSBvZiB0aGUgYXR0cmlidXRlIHRvCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgY3JlYXRlLiBXaGVuIGl0IGlzIG51bGwgb3IgYW4gZW1wdHkgc3RyaW5nLAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIHRoaXMgbWV0aG9kIGJlaGF2ZXMgbGlrZSBjcmVhdGVBdHRyaWJ1dGUuCi0gICAgICogQHBhcmFtIHF1YWxpZmllZE5hbWUgVGhlIHF1YWxpZmllZCBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUgdG8KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBpbnN0YW50aWF0ZS4KLSAgICAgKiBAcGFyYW0gbG9jYWxwYXJ0ICAgICBUaGUgbG9jYWwgbmFtZSBvZiB0aGUgYXR0cmlidXRlIHRvIGluc3RhbnRpYXRlLgotICAgICAqCi0gICAgICogQHJldHVybiBBdHRyICAgICAgICAgQSBuZXcgQXR0ciBvYmplY3QuCi0gICAgICogQHRocm93cyBET01FeGNlcHRpb24gSU5WQUxJRF9DSEFSQUNURVJfRVJSOiBSYWlzZWQgaWYgdGhlIHNwZWNpZmllZAotICAgICAqIG5hbWUgY29udGFpbnMgYW4gaW52YWxpZCBjaGFyYWN0ZXIuCi0gICAgICovCi0gICAgcHVibGljIEF0dHIgY3JlYXRlQXR0cmlidXRlTlMoU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIHF1YWxpZmllZE5hbWUsCi0gICAgICAgICAgICBTdHJpbmcgbG9jYWxwYXJ0KQotICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0gICAgICAgIHJldHVybiBuZXcgQXR0ck5TSW1wbCh0aGlzLCBuYW1lc3BhY2VVUkksIHF1YWxpZmllZE5hbWUsIGxvY2FscGFydCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSW50cm9kdWNlZCBpbiBET00gTGV2ZWwgMi4gPHA+Ci0gICAgICogUmV0dXJucyBhIE5vZGVMaXN0IG9mIGFsbCB0aGUgRWxlbWVudHMgd2l0aCBhIGdpdmVuIGxvY2FsIG5hbWUgYW5kCi0gICAgICogbmFtZXNwYWNlIFVSSSBpbiB0aGUgb3JkZXIgaW4gd2hpY2ggdGhleSB3b3VsZCBiZSBlbmNvdW50ZXJlZCBpbiBhCi0gICAgICogcHJlb3JkZXIgdHJhdmVyc2FsIG9mIHRoZSBEb2N1bWVudCB0cmVlLgotICAgICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkgIFRoZSBuYW1lc3BhY2UgVVJJIG9mIHRoZSBlbGVtZW50cyB0byBtYXRjaAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIG9uLiBUaGUgc3BlY2lhbCB2YWx1ZSAiKiIgbWF0Y2hlcyBhbGwKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBuYW1lc3BhY2VzLiBXaGVuIGl0IGlzIG51bGwgb3IgYW4gZW1wdHkKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcsIHRoaXMgbWV0aG9kIGJlaGF2ZXMgbGlrZQotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGdldEVsZW1lbnRzQnlUYWdOYW1lLgotICAgICAqIEBwYXJhbSBsb2NhbE5hbWUgICAgIFRoZSBsb2NhbCBuYW1lIG9mIHRoZSBlbGVtZW50cyB0byBtYXRjaCBvbi4KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBUaGUgc3BlY2lhbCB2YWx1ZSAiKiIgbWF0Y2hlcyBhbGwgbG9jYWwgbmFtZXMuCi0gICAgICogQHJldHVybiBOb2RlTGlzdCAgICAgQSBuZXcgTm9kZUxpc3Qgb2JqZWN0IGNvbnRhaW5pbmcgYWxsIHRoZSBtYXRjaGVkCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgRWxlbWVudHMuCi0gICAgICogQHNpbmNlIFdELURPTS1MZXZlbC0yLTE5OTkwOTIzCi0gICAgICovCi0gICAgcHVibGljIE5vZGVMaXN0IGdldEVsZW1lbnRzQnlUYWdOYW1lTlMoU3RyaW5nIG5hbWVzcGFjZVVSSSwKLSAgICAgICAgICAgIFN0cmluZyBsb2NhbE5hbWUpIHsKLSAgICAgICAgcmV0dXJuIG5ldyBEZWVwTm9kZUxpc3RJbXBsKHRoaXMsIG5hbWVzcGFjZVVSSSwgbG9jYWxOYW1lKTsKLSAgICB9Ci0KLSAgICAvLwotICAgIC8vIE9iamVjdCBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKiBDbG9uZS4gKi8KLSAgICBwdWJsaWMgT2JqZWN0IGNsb25lKCkgdGhyb3dzIENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIHsKLSAgICAgICAgQ29yZURvY3VtZW50SW1wbCBuZXdkb2MgPSAoQ29yZURvY3VtZW50SW1wbCkgc3VwZXIuY2xvbmUoKTsKLSAgICAgICAgbmV3ZG9jLmRvY1R5cGUgPSBudWxsOwotICAgICAgICBuZXdkb2MuZG9jRWxlbWVudCA9IG51bGw7Ci0gICAgICAgIHJldHVybiBuZXdkb2M7Ci0gICAgfQotCi0gICAgLy8KLSAgICAvLyBQdWJsaWMgc3RhdGljIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogQ2hlY2sgdGhlIHN0cmluZyBhZ2FpbnN0IFhNTCdzIGRlZmluaXRpb24gb2YgYWNjZXB0YWJsZSBuYW1lcyBmb3IKLSAgICAgKiBlbGVtZW50cyBhbmQgYXR0cmlidXRlcyBhbmQgc28gb24gdXNpbmcgdGhlIFhNTENoYXJhY3RlclByb3BlcnRpZXMKLSAgICAgKiB1dGlsaXR5IGNsYXNzCi0gICAgICovCi0KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGJvb2xlYW4gaXNYTUxOYW1lKFN0cmluZyBzLCBib29sZWFuIHhtbDExVmVyc2lvbikgewotCi0gICAgICAgIGlmIChzID09IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotICAgICAgICBpZigheG1sMTFWZXJzaW9uKQotICAgICAgICAgICAgcmV0dXJuIFhNTENoYXIuaXNWYWxpZE5hbWUocyk7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICAgIHJldHVybiBYTUwxMUNoYXIuaXNYTUwxMVZhbGlkTmFtZShzKTsKLQotICAgIH0gLy8gaXNYTUxOYW1lKFN0cmluZyk6Ym9vbGVhbgotCi0gICAgLyoqCi0gICAgICogQ2hlY2tzIGlmIHRoZSBnaXZlbiBxdWFsaWZpZWQgbmFtZSBpcyBsZWdhbCB3aXRoIHJlc3BlY3QKLSAgICAgKiB0byB0aGUgdmVyc2lvbiBvZiBYTUwgdG8gd2hpY2ggdGhpcyBkb2N1bWVudCBtdXN0IGNvbmZvcm0uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcHJlZml4IHByZWZpeCBvZiBxdWFsaWZpZWQgbmFtZQotICAgICAqIEBwYXJhbSBsb2NhbCBsb2NhbCBwYXJ0IG9mIHF1YWxpZmllZCBuYW1lCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBib29sZWFuIGlzVmFsaWRRTmFtZShTdHJpbmcgcHJlZml4LCBTdHJpbmcgbG9jYWwsIGJvb2xlYW4geG1sMTFWZXJzaW9uKSB7Ci0KLSAgICAgICAgLy8gY2hlY2sgdGhhdCBib3RoIHByZWZpeCBhbmQgbG9jYWwgcGFydCBtYXRjaCBOQ05hbWUKLSAgICAgICAgaWYgKGxvY2FsID09IG51bGwpIHJldHVybiBmYWxzZTsKLSAgICAgICAgYm9vbGVhbiB2YWxpZE5DTmFtZSA9IGZhbHNlOwotCi0gICAgICAgIGlmICgheG1sMTFWZXJzaW9uKSB7Ci0gICAgICAgICAgICB2YWxpZE5DTmFtZSA9IChwcmVmaXggPT0gbnVsbCB8fCBYTUxDaGFyLmlzVmFsaWROQ05hbWUocHJlZml4KSkKLSAgICAgICAgICAgICAgICAgICAgJiYgWE1MQ2hhci5pc1ZhbGlkTkNOYW1lKGxvY2FsKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHZhbGlkTkNOYW1lID0gKHByZWZpeCA9PSBudWxsIHx8IFhNTDExQ2hhci5pc1hNTDExVmFsaWROQ05hbWUocHJlZml4KSkKLSAgICAgICAgICAgICAgICAgICAgJiYgWE1MMTFDaGFyLmlzWE1MMTFWYWxpZE5DTmFtZShsb2NhbCk7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gdmFsaWROQ05hbWU7Ci0gICAgfQotICAgIC8vCi0gICAgLy8gUHJvdGVjdGVkIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogVXNlcyB0aGUga2lkT0sgbG9va3VwIHRhYmxlIHRvIGNoZWNrIHdoZXRoZXIgdGhlIHByb3Bvc2VkCi0gICAgICogdHJlZSBzdHJ1Y3R1cmUgaXMgbGVnYWwuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gaXNLaWRPSyhOb2RlIHBhcmVudCwgTm9kZSBjaGlsZCkgewotICAgICAgICBpZiAoYWxsb3dHcmFtbWFyQWNjZXNzICYmCi0gICAgICAgIHBhcmVudC5nZXROb2RlVHlwZSgpID09IE5vZGUuRE9DVU1FTlRfVFlQRV9OT0RFKSB7Ci0gICAgICAgICAgICByZXR1cm4gY2hpbGQuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLkVMRU1FTlRfTk9ERTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gMCAhPSAoa2lkT0tbcGFyZW50LmdldE5vZGVUeXBlKCldICYgMSA8PCBjaGlsZC5nZXROb2RlVHlwZSgpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBEZW5vdGVzIHRoYXQgdGhpcyBub2RlIGhhcyBjaGFuZ2VkLgotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIGNoYW5nZWQoKSB7Ci0gICAgICAgIGNoYW5nZXMrKzsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgY2hhbmdlcyB0byB0aGlzIG5vZGUuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGludCBjaGFuZ2VzKCkgewotICAgICAgICByZXR1cm4gY2hhbmdlczsKLSAgICB9Ci0KLSAgICAvLyAgTm9kZUxpc3RDYWNoZSBwb29sCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGEgTm9kZUxpc3RDYWNoZSBmb3IgdGhlIGdpdmVuIG5vZGUuCi0gICAgICovCi0gICAgTm9kZUxpc3RDYWNoZSBnZXROb2RlTGlzdENhY2hlKFBhcmVudE5vZGUgb3duZXIpIHsKLSAgICAgICAgaWYgKGZGcmVlTkxDYWNoZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gbmV3IE5vZGVMaXN0Q2FjaGUob3duZXIpOwotICAgICAgICB9Ci0gICAgICAgIE5vZGVMaXN0Q2FjaGUgYyA9IGZGcmVlTkxDYWNoZTsKLSAgICAgICAgZkZyZWVOTENhY2hlID0gZkZyZWVOTENhY2hlLm5leHQ7Ci0gICAgICAgIGMuZkNoaWxkID0gbnVsbDsKLSAgICAgICAgYy5mQ2hpbGRJbmRleCA9IC0xOwotICAgICAgICBjLmZMZW5ndGggPSAtMTsKLSAgICAgICAgLy8gcmV2b2tlIHByZXZpb3VzIG93bmVyc2hpcAotICAgICAgICBpZiAoYy5mT3duZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgYy5mT3duZXIuZk5vZGVMaXN0Q2FjaGUgPSBudWxsOwotICAgICAgICB9Ci0gICAgICAgIGMuZk93bmVyID0gb3duZXI7Ci0gICAgICAgIC8vIGMubmV4dCA9IG51bGw7IG5vdCBuZWNlc3NhcnksIGV4Y2VwdCBmb3IgY29uZnVzZWQgcGVvcGxlLi4uCi0gICAgICAgIHJldHVybiBjOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFB1dHMgdGhlIGdpdmVuIE5vZGVMaXN0Q2FjaGUgaW4gdGhlIGZyZWUgbGlzdC4KLSAgICAgKiBOb3RlOiBUaGUgb3duZXIgbm9kZSBjYW4ga2VlcCB1c2luZyBpdCB1bnRpbCB3ZSByZXVzZSBpdAotICAgICAqLwotICAgIHZvaWQgZnJlZU5vZGVMaXN0Q2FjaGUoTm9kZUxpc3RDYWNoZSBjKSB7Ci0gICAgICAgIGMubmV4dCA9IGZGcmVlTkxDYWNoZTsKLSAgICAgICAgZkZyZWVOTENhY2hlID0gYzsKLSAgICB9Ci0KLQotCi0gICAgLyoqCi0gICAgICogQXNzb2NpYXRlIGFuIG9iamVjdCB0byBhIGtleSBvbiB0aGlzIG5vZGUuIFRoZSBvYmplY3QgY2FuIGxhdGVyIGJlCi0gICAgICogcmV0cmlldmVkIGZyb20gdGhpcyBub2RlIGJ5IGNhbGxpbmcgPGNvZGU+Z2V0VXNlckRhdGE8L2NvZGU+IHdpdGggdGhlCi0gICAgICogc2FtZSBrZXkuCi0gICAgICogQHBhcmFtIG4gVGhlIG5vZGUgdG8gYXNzb2NpYXRlIHRoZSBvYmplY3QgdG8uCi0gICAgICogQHBhcmFtIGtleSBUaGUga2V5IHRvIGFzc29jaWF0ZSB0aGUgb2JqZWN0IHRvLgotICAgICAqIEBwYXJhbSBkYXRhIFRoZSBvYmplY3QgdG8gYXNzb2NpYXRlIHRvIHRoZSBnaXZlbiBrZXksIG9yCi0gICAgICogICA8Y29kZT5udWxsPC9jb2RlPiB0byByZW1vdmUgYW55IGV4aXN0aW5nIGFzc29jaWF0aW9uIHRvIHRoYXQga2V5LgotICAgICAqIEBwYXJhbSBoYW5kbGVyIFRoZSBoYW5kbGVyIHRvIGFzc29jaWF0ZSB0byB0aGF0IGtleSwgb3IKLSAgICAgKiAgIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAqIEByZXR1cm4gUmV0dXJucyB0aGUgPGNvZGU+RE9NT2JqZWN0PC9jb2RlPiBwcmV2aW91c2x5IGFzc29jaWF0ZWQgdG8KLSAgICAgKiAgIHRoZSBnaXZlbiBrZXkgb24gdGhpcyBub2RlLCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGVyZSB3YXMgbm9uZS4KLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICAgKgotICAgICAqIFJFVklTSVQ6IHdlIGNvdWxkIHVzZSBhIGZyZWUgbGlzdCBvZiBVc2VyRGF0YVJlY29yZCBoZXJlCi0gICAgICovCi0gICAgcHVibGljIE9iamVjdCBzZXRVc2VyRGF0YShOb2RlIG4sIFN0cmluZyBrZXksCi0gICAgICAgICAgICBPYmplY3QgZGF0YSwgVXNlckRhdGFIYW5kbGVyIGhhbmRsZXIpIHsKLSAgICAgICAgaWYgKGRhdGEgPT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKG5vZGVVc2VyRGF0YSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgTWFwPFN0cmluZywgVXNlckRhdGFSZWNvcmQ+IHQgPSBub2RlVXNlckRhdGEuZ2V0KG4pOwotICAgICAgICAgICAgICAgIGlmICh0ICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgVXNlckRhdGFSZWNvcmQgciA9IHQucmVtb3ZlKGtleSk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByLmZEYXRhOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBNYXA8U3RyaW5nLCBVc2VyRGF0YVJlY29yZD4gdDsKLSAgICAgICAgICAgIGlmIChub2RlVXNlckRhdGEgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIG5vZGVVc2VyRGF0YSA9IG5ldyBIYXNoTWFwPD4oKTsKLSAgICAgICAgICAgICAgICB0ID0gbmV3IEhhc2hNYXA8PigpOwotICAgICAgICAgICAgICAgIG5vZGVVc2VyRGF0YS5wdXQobiwgdCk7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIHQgPSBub2RlVXNlckRhdGEuZ2V0KG4pOwotICAgICAgICAgICAgICAgIGlmICh0ID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgdCA9IG5ldyBIYXNoTWFwPD4oKTsKLSAgICAgICAgICAgICAgICAgICAgbm9kZVVzZXJEYXRhLnB1dChuLCB0KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBVc2VyRGF0YVJlY29yZCByID0gdC5wdXQoa2V5LCBuZXcgVXNlckRhdGFSZWNvcmQoZGF0YSwgaGFuZGxlcikpOwotICAgICAgICAgICAgaWYgKHIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJldHVybiByLmZEYXRhOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFJldHJpZXZlcyB0aGUgb2JqZWN0IGFzc29jaWF0ZWQgdG8gYSBrZXkgb24gYSB0aGlzIG5vZGUuIFRoZSBvYmplY3QKLSAgICAgKiBtdXN0IGZpcnN0IGhhdmUgYmVlbiBzZXQgdG8gdGhpcyBub2RlIGJ5IGNhbGxpbmcKLSAgICAgKiA8Y29kZT5zZXRVc2VyRGF0YTwvY29kZT4gd2l0aCB0aGUgc2FtZSBrZXkuCi0gICAgICogQHBhcmFtIG4gVGhlIG5vZGUgdGhlIG9iamVjdCBpcyBhc3NvY2lhdGVkIHRvLgotICAgICAqIEBwYXJhbSBrZXkgVGhlIGtleSB0aGUgb2JqZWN0IGlzIGFzc29jaWF0ZWQgdG8uCi0gICAgICogQHJldHVybiBSZXR1cm5zIHRoZSA8Y29kZT5ET01PYmplY3Q8L2NvZGU+IGFzc29jaWF0ZWQgdG8gdGhlIGdpdmVuIGtleQotICAgICAqICAgb24gdGhpcyBub2RlLCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGVyZSB3YXMgbm9uZS4KLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0IGdldFVzZXJEYXRhKE5vZGUgbiwgU3RyaW5nIGtleSkgewotICAgICAgICBpZiAobm9kZVVzZXJEYXRhID09IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgICAgIE1hcDxTdHJpbmcsIFVzZXJEYXRhUmVjb3JkPiB0ID0gbm9kZVVzZXJEYXRhLmdldChuKTsKLSAgICAgICAgaWYgKHQgPT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLSAgICAgICAgVXNlckRhdGFSZWNvcmQgciA9IHQuZ2V0KGtleSk7Ci0gICAgICAgIGlmIChyICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiByLmZEYXRhOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIHByb3RlY3RlZCBNYXA8U3RyaW5nLCBVc2VyRGF0YVJlY29yZD4gZ2V0VXNlckRhdGFSZWNvcmQoTm9kZSBuKSB7Ci0gICAgICAgIGlmIChub2RlVXNlckRhdGEgPT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLSAgICAgICAgTWFwPFN0cmluZywgVXNlckRhdGFSZWNvcmQ+IHQgPSBub2RlVXNlckRhdGEuZ2V0KG4pOwotICAgICAgICBpZiAodCA9PSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gdDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZW1vdmUgdXNlciBkYXRhIHRhYmxlIGZvciB0aGUgZ2l2ZW4gbm9kZS4KLSAgICAgKiBAcGFyYW0gbiBUaGUgbm9kZSB0aGlzIG9wZXJhdGlvbiBhcHBsaWVzIHRvLgotICAgICAqIEByZXR1cm4gVGhlIHJlbW92ZWQgdGFibGUuCi0gICAgICovCi0gICAgTWFwPFN0cmluZywgVXNlckRhdGFSZWNvcmQ+IHJlbW92ZVVzZXJEYXRhVGFibGUoTm9kZSBuKSB7Ci0gICAgICAgIGlmIChub2RlVXNlckRhdGEgPT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG5vZGVVc2VyRGF0YS5nZXQobik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0IHVzZXIgZGF0YSB0YWJsZSBmb3IgdGhlIGdpdmVuIG5vZGUuCi0gICAgICogQHBhcmFtIG4gVGhlIG5vZGUgdGhpcyBvcGVyYXRpb24gYXBwbGllcyB0by4KLSAgICAgKiBAcGFyYW0gZGF0YSBUaGUgdXNlciBkYXRhIHRhYmxlLgotICAgICAqLwotICAgIHZvaWQgc2V0VXNlckRhdGFUYWJsZShOb2RlIG4sIE1hcDxTdHJpbmcsIFVzZXJEYXRhUmVjb3JkPiBkYXRhKSB7Ci0gICAgICAgIGlmIChub2RlVXNlckRhdGEgPT0gbnVsbCkgewotICAgICAgICAgICAgbm9kZVVzZXJEYXRhID0gbmV3IEhhc2hNYXA8PigpOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKGRhdGEgIT0gbnVsbCkgewotICAgICAgICAgICAgbm9kZVVzZXJEYXRhLnB1dChuLCBkYXRhKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIENhbGwgdXNlciBkYXRhIGhhbmRsZXJzIHdoZW4gYSBub2RlIGlzIGRlbGV0ZWQgKGZpbmFsaXplZCkKLSAgICAgKiBAcGFyYW0gbiBUaGUgbm9kZSB0aGlzIG9wZXJhdGlvbiBhcHBsaWVzIHRvLgotICAgICAqIEBwYXJhbSBjIFRoZSBjb3B5IG5vZGUgb3IgbnVsbC4KLSAgICAgKiBAcGFyYW0gb3BlcmF0aW9uIFRoZSBvcGVyYXRpb24gLSBpbXBvcnQsIGNsb25lLCBvciBkZWxldGUuCi0gICAgICovCi0gICAgdm9pZCBjYWxsVXNlckRhdGFIYW5kbGVycyhOb2RlIG4sIE5vZGUgYywgc2hvcnQgb3BlcmF0aW9uKSB7Ci0gICAgICAgIGlmIChub2RlVXNlckRhdGEgPT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKG4gaW5zdGFuY2VvZiBOb2RlSW1wbCkgewotICAgICAgICAgICAgTWFwPFN0cmluZywgVXNlckRhdGFSZWNvcmQ+IHQgPSAoKE5vZGVJbXBsKSBuKS5nZXRVc2VyRGF0YVJlY29yZCgpOwotICAgICAgICAgICAgaWYgKHQgPT0gbnVsbCB8fCB0LmlzRW1wdHkoKSkgewotICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhbGxVc2VyRGF0YUhhbmRsZXJzKG4sIGMsIG9wZXJhdGlvbiwgdCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDYWxsIHVzZXIgZGF0YSBoYW5kbGVycyB3aGVuIGEgbm9kZSBpcyBkZWxldGVkIChmaW5hbGl6ZWQpCi0gICAgICogQHBhcmFtIG4gVGhlIG5vZGUgdGhpcyBvcGVyYXRpb24gYXBwbGllcyB0by4KLSAgICAgKiBAcGFyYW0gYyBUaGUgY29weSBub2RlIG9yIG51bGwuCi0gICAgICogQHBhcmFtIG9wZXJhdGlvbiBUaGUgb3BlcmF0aW9uIC0gaW1wb3J0LCBjbG9uZSwgb3IgZGVsZXRlLgotICAgICAqIEBwYXJhbSBoYW5kbGVycyBEYXRhIGFzc29jaWF0ZWQgd2l0aCBuLgotICAgICAqLwotICAgIHZvaWQgY2FsbFVzZXJEYXRhSGFuZGxlcnMoTm9kZSBuLCBOb2RlIGMsIHNob3J0IG9wZXJhdGlvbiwgTWFwPFN0cmluZywgVXNlckRhdGFSZWNvcmQ+IHVzZXJEYXRhKSB7Ci0gICAgICAgIGlmICh1c2VyRGF0YSA9PSBudWxsIHx8IHVzZXJEYXRhLmlzRW1wdHkoKSkgewotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0gICAgICAgIGZvciAoU3RyaW5nIGtleSA6IHVzZXJEYXRhLmtleVNldCgpKSB7Ci0gICAgICAgICAgICBVc2VyRGF0YVJlY29yZCByID0gdXNlckRhdGEuZ2V0KGtleSk7Ci0gICAgICAgICAgICBpZiAoci5mSGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgci5mSGFuZGxlci5oYW5kbGUob3BlcmF0aW9uLCBrZXksIHIuZkRhdGEsIG4sIGMpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ2FsbCB1c2VyIGRhdGEgaGFuZGxlcnMgdG8gbGV0IHRoZW0ga25vdyB0aGUgbm9kZXMgdGhleSBhcmUgcmVsYXRlZCB0bwotICAgICAqIGFyZSBiZWluZyBkZWxldGVkLiBUaGUgYWx0ZXJuYXRpdmUgd291bGQgYmUgdG8gZG8gdGhhdCBvbiBOb2RlIGJ1dAotICAgICAqIGJlY2F1c2UgdGhlIG5vZGVzIGFyZSB1c2VkIGFzIHRoZSBrZXlzIHdlIGhhdmUgYSByZWZlcmVuY2UgdG8gdGhlbSB0aGF0Ci0gICAgICogcHJldmVudHMgdGhlbSBmcm9tIGJlaW5nIGdjJ2VkIHVudGlsIHRoZSBkb2N1bWVudCBpcy4gQXQgdGhlIHNhbWUgdGltZSwKLSAgICAgKiBkb2luZyBpdCBoZXJlIGhhcyB0aGUgYWR2YW50YWdlIG9mIGF2b2lkaW5nIGEgZmluYWxpemUoKSBtZXRob2Qgb24gTm9kZSwKLSAgICAgKiB3aGljaCB3b3VsZCBhZmZlY3QgYWxsIG5vZGVzIGFuZCBub3QganVzdCB0aGUgb25lcyB0aGF0IGhhdmUgYSB1c2VyCi0gICAgICogZGF0YS4KLSAgICAgKi8KLSAgICAvLyBUZW1wb3JhcmlseSBjb21tZW50IG91dCB0aGlzIG1ldGhvZCwgYmVjYXVzZQotICAgIC8vIDEuIEl0IHNlZW1zIHRoYXQgZmluYWxpemVycyBhcmUgbm90IGd1YXJhbnRlZWQgdG8gYmUgY2FsbGVkLCBzbyB0aGUKLSAgICAvLyAgICBmdW5jdGlvbmFsaXR5IGlzIG5vdCBpbXBsZW1lbnRlZC4KLSAgICAvLyAyLiBJdCBhZmZlY3RzIHRoZSBwZXJmb3JtYW5jZSBncmVhdGx5IGluIG11bHRpLXRocmVhZCBlbnZpcm9ubWVudC4KLSAgICAvLyAtU0cKLSAgICAvKnB1YmxpYyB2b2lkIGZpbmFsaXplKCkgewotICAgICBpZiAodXNlckRhdGEgPT0gbnVsbCkgewotICAgICByZXR1cm47Ci0gICAgIH0KLSAgICAgRW51bWVyYXRpb24gbm9kZXMgPSB1c2VyRGF0YS5rZXlzKCk7Ci0gICAgIHdoaWxlIChub2Rlcy5oYXNNb3JlRWxlbWVudHMoKSkgewotICAgICBPYmplY3Qgbm9kZSA9IG5vZGVzLm5leHRFbGVtZW50KCk7Ci0gICAgIEhhc2h0YWJsZSB0ID0gKEhhc2h0YWJsZSkgdXNlckRhdGEuZ2V0KG5vZGUpOwotICAgICBpZiAodCAhPSBudWxsICYmICF0LmlzRW1wdHkoKSkgewotICAgICBFbnVtZXJhdGlvbiBrZXlzID0gdC5rZXlzKCk7Ci0gICAgIHdoaWxlIChrZXlzLmhhc01vcmVFbGVtZW50cygpKSB7Ci0gICAgIFN0cmluZyBrZXkgPSAoU3RyaW5nKSBrZXlzLm5leHRFbGVtZW50KCk7Ci0gICAgIFVzZXJEYXRhUmVjb3JkIHIgPSAoVXNlckRhdGFSZWNvcmQpIHQuZ2V0KGtleSk7Ci0gICAgIGlmIChyLmZIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgci5mSGFuZGxlci5oYW5kbGUoVXNlckRhdGFIYW5kbGVyLk5PREVfREVMRVRFRCwKLSAgICAga2V5LCByLmZEYXRhLCBudWxsLCBudWxsKTsKLSAgICAgfQotICAgICB9Ci0gICAgIH0KLSAgICAgfQotICAgICB9Ki8KLQotICAgIHByb3RlY3RlZCBmaW5hbCB2b2lkIGNoZWNrTmFtZXNwYWNlV0YoIFN0cmluZyBxbmFtZSwgaW50IGNvbG9uMSwKLSAgICAgICAgICAgIGludCBjb2xvbjIpIHsKLQotICAgICAgICBpZiAoIWVycm9yQ2hlY2tpbmcpIHsKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotICAgICAgICAvLyBpdCBpcyBhbiBlcnJvciBmb3IgTkNOYW1lIHRvIGhhdmUgbW9yZSB0aGFuIG9uZSAnOicKLSAgICAgICAgLy8gY2hlY2sgaWYgaXQgaXMgdmFsaWQgUU5hbWUgW05hbWVzcGFjZSBpbiBYTUwgcHJvZHVjdGlvbiA2XQotICAgICAgICAvLyA6Y2FtZXJhICwgbmlrb246Y2FtZXJhOm1pbm9sdGEsIGNhbWVyYToKLSAgICAgICAgaWYgKGNvbG9uMSA9PSAwIHx8IGNvbG9uMSA9PSBxbmFtZS5sZW5ndGgoKSAtIDEgfHwgY29sb24yICE9IGNvbG9uMSkgewotICAgICAgICAgICAgU3RyaW5nIG1zZyA9Ci0gICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOQU1FU1BBQ0VfRVJSIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsKTsKLSAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5BTUVTUEFDRV9FUlIsIG1zZyk7Ci0gICAgICAgIH0KLSAgICB9Ci0gICAgcHJvdGVjdGVkIGZpbmFsIHZvaWQgY2hlY2tET01OU0VycihTdHJpbmcgcHJlZml4LAotICAgICAgICAgICAgU3RyaW5nIG5hbWVzcGFjZSkgewotICAgICAgICBpZiAoZXJyb3JDaGVja2luZykgewotICAgICAgICAgICAgaWYgKG5hbWVzcGFjZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIG1zZyA9Ci0gICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOQU1FU1BBQ0VfRVJSIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCk7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTkFNRVNQQUNFX0VSUiwgbXNnKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKHByZWZpeC5lcXVhbHMoInhtbCIpCi0gICAgICAgICAgICAgICAgICAgICYmICFuYW1lc3BhY2UuZXF1YWxzKE5hbWVzcGFjZUNvbnRleHQuWE1MX1VSSSkpIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgbXNnID0KLSAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5BTUVTUEFDRV9FUlIiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsKTsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OQU1FU1BBQ0VfRVJSLCBtc2cpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoCi0gICAgICAgICAgICBwcmVmaXguZXF1YWxzKCJ4bWxucyIpCi0gICAgICAgICAgICAgICAgICAgICYmICFuYW1lc3BhY2UuZXF1YWxzKE5hbWVzcGFjZUNvbnRleHQuWE1MTlNfVVJJKQotICAgICAgICAgICAgICAgICAgICB8fCAoIXByZWZpeC5lcXVhbHMoInhtbG5zIikKLSAgICAgICAgICAgICAgICAgICAgJiYgbmFtZXNwYWNlLmVxdWFscyhOYW1lc3BhY2VDb250ZXh0LlhNTE5TX1VSSSkpKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIG1zZyA9Ci0gICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOQU1FU1BBQ0VfRVJSIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCk7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTkFNRVNQQUNFX0VSUiwgbXNnKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIENoZWNrcyBpZiB0aGUgZ2l2ZW4gcXVhbGlmaWVkIG5hbWUgaXMgbGVnYWwgd2l0aCByZXNwZWN0Ci0gICAgICogdG8gdGhlIHZlcnNpb24gb2YgWE1MIHRvIHdoaWNoIHRoaXMgZG9jdW1lbnQgbXVzdCBjb25mb3JtLgotICAgICAqCi0gICAgICogQHBhcmFtIHByZWZpeCBwcmVmaXggb2YgcXVhbGlmaWVkIG5hbWUKLSAgICAgKiBAcGFyYW0gbG9jYWwgbG9jYWwgcGFydCBvZiBxdWFsaWZpZWQgbmFtZQotICAgICAqLwotICAgIHByb3RlY3RlZCBmaW5hbCB2b2lkIGNoZWNrUU5hbWUoU3RyaW5nIHByZWZpeCwgU3RyaW5nIGxvY2FsKSB7Ci0gICAgICAgIGlmICghZXJyb3JDaGVja2luZykgewotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gY2hlY2sgdGhhdCBib3RoIHByZWZpeCBhbmQgbG9jYWwgcGFydCBtYXRjaCBOQ05hbWUKLSAgICAgICAgYm9vbGVhbiB2YWxpZE5DTmFtZSA9IGZhbHNlOwotICAgICAgICBpZiAoIXhtbDExVmVyc2lvbikgewotICAgICAgICAgICAgdmFsaWROQ05hbWUgPSAocHJlZml4ID09IG51bGwgfHwgWE1MQ2hhci5pc1ZhbGlkTkNOYW1lKHByZWZpeCkpCi0gICAgICAgICAgICAgICAgICAgICYmIFhNTENoYXIuaXNWYWxpZE5DTmFtZShsb2NhbCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICB2YWxpZE5DTmFtZSA9IChwcmVmaXggPT0gbnVsbCB8fCBYTUwxMUNoYXIuaXNYTUwxMVZhbGlkTkNOYW1lKHByZWZpeCkpCi0gICAgICAgICAgICAgICAgICAgICYmIFhNTDExQ2hhci5pc1hNTDExVmFsaWROQ05hbWUobG9jYWwpOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKCF2YWxpZE5DTmFtZSkgewotICAgICAgICAgICAgLy8gUkVWSVNJVDogYWRkIHFuYW1lIHBhcmFtZXRlciB0byB0aGUgbWVzc2FnZQotICAgICAgICAgICAgU3RyaW5nIG1zZyA9Ci0gICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICJJTlZBTElEX0NIQVJBQ1RFUl9FUlIiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwpOwotICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uSU5WQUxJRF9DSEFSQUNURVJfRVJSLCBtc2cpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogV2UgY291bGQgaGF2ZSBtb3JlIHhtbCB2ZXJzaW9ucyBpbiBmdXR1cmUgLCBidXQgZm9yIG5vdyB3ZSBjb3VsZAotICAgICAqIGRvIHdpdGggdGhpcyB0byBoYW5kbGUgWE1MIDEuMCBhbmQgMS4xCi0gICAgICovCi0gICAgYm9vbGVhbiBpc1hNTDExVmVyc2lvbigpewotICAgICAgICByZXR1cm4geG1sMTFWZXJzaW9uOwotICAgIH0KLQotICAgIGJvb2xlYW4gaXNOb3JtYWxpemVEb2NSZXF1aXJlZCgpewotICAgICAgICAvLyBSRVZJU0lUOiBJbXBsZW1lbnQgdG8gb3B0aW1pemUgd2hlbiBub3JtYWxpemF0aW9uCi0gICAgICAgIC8vIGlzIHJlcXVpcmVkCi0gICAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotICAgIC8vd2Ugc2hvdWxkIGJlIGNoZWNraW5nIHRoZSAoZWxlbWVudHMsIGF0dHJpYnV0ZSwgZW50aXR5IGV0Yy4pIG5hbWVzIG9ubHkgd2hlbgotICAgIC8vdmVyc2lvbiBvZiB0aGUgZG9jdW1lbnQgaXMgY2hhbmdlZC4KLSAgICBib29sZWFuIGlzWE1MVmVyc2lvbkNoYW5nZWQoKXsKLSAgICAgICAgcmV0dXJuIHhtbFZlcnNpb25DaGFuZ2VkIDsKLSAgICB9Ci0gICAgLyoqCi0gICAgICogTk9OLURPTToga2VwdCBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eQotICAgICAqIFN0b3JlIHVzZXIgZGF0YSByZWxhdGVkIHRvIGEgZ2l2ZW4gbm9kZQotICAgICAqIFRoaXMgaXMgYSBwbGFjZSB3aGVyZSB3ZSBjb3VsZCB1c2Ugd2VhayByZWZlcmVuY2VzISBJbmRlZWQsIHRoZSBub2RlCi0gICAgICogaGVyZSB3b24ndCBiZSBHQydlZCBhcyBsb25nIGFzIHNvbWUgdXNlciBkYXRhIGlzIGF0dGFjaGVkIHRvIGl0LCBzaW5jZQotICAgICAqIHRoZSB1c2VyRGF0YSB0YWJsZSB3aWxsIGhhdmUgYSByZWZlcmVuY2UgdG8gdGhlIG5vZGUuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgc2V0VXNlckRhdGEoTm9kZUltcGwgbiwgT2JqZWN0IGRhdGEpIHsKLSAgICAgICAgc2V0VXNlckRhdGEobiwgIlhFUkNFUzFET01VU0VSREFUQSIsIGRhdGEsIG51bGwpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIE5PTi1ET006IGtlcHQgZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkKLSAgICAgKiBSZXRyZWl2ZSB1c2VyIGRhdGEgcmVsYXRlZCB0byBhIGdpdmVuIG5vZGUKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgT2JqZWN0IGdldFVzZXJEYXRhKE5vZGVJbXBsIG4pIHsKLSAgICAgICAgcmV0dXJuIGdldFVzZXJEYXRhKG4sICJYRVJDRVMxRE9NVVNFUkRBVEEiKTsKLSAgICB9Ci0KLQotICAgIC8vIEV2ZW50IHJlbGF0ZWQgbWV0aG9kcyBvdmVyaWRkZW4gaW4gc3ViY2xhc3MKLQotICAgIHByb3RlY3RlZCB2b2lkIGFkZEV2ZW50TGlzdGVuZXIoTm9kZUltcGwgbm9kZSwgU3RyaW5nIHR5cGUsCi0gICAgICAgICAgICBFdmVudExpc3RlbmVyIGxpc3RlbmVyLAotICAgICAgICAgICAgYm9vbGVhbiB1c2VDYXB0dXJlKSB7Ci0gICAgICAgIC8vIGRvZXMgbm90aGluZyBieSBkZWZhdWx0IC0gb3ZlcmlkZGVuIGluIHN1YmNsYXNzCi0gICAgfQotCi0gICAgcHJvdGVjdGVkIHZvaWQgcmVtb3ZlRXZlbnRMaXN0ZW5lcihOb2RlSW1wbCBub2RlLCBTdHJpbmcgdHlwZSwKLSAgICAgICAgICAgIEV2ZW50TGlzdGVuZXIgbGlzdGVuZXIsCi0gICAgICAgICAgICBib29sZWFuIHVzZUNhcHR1cmUpIHsKLSAgICAgICAgLy8gZG9lcyBub3RoaW5nIGJ5IGRlZmF1bHQgLSBvdmVyaWRkZW4gaW4gc3ViY2xhc3MKLSAgICB9Ci0KLSAgICBwcm90ZWN0ZWQgdm9pZCBjb3B5RXZlbnRMaXN0ZW5lcnMoTm9kZUltcGwgc3JjLCBOb2RlSW1wbCB0Z3QpIHsKLSAgICAgICAgLy8gZG9lcyBub3RoaW5nIGJ5IGRlZmF1bHQgLSBvdmVyaWRkZW4gaW4gc3ViY2xhc3MKLSAgICB9Ci0KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBkaXNwYXRjaEV2ZW50KE5vZGVJbXBsIG5vZGUsIEV2ZW50IGV2ZW50KSB7Ci0gICAgICAgIC8vIGRvZXMgbm90aGluZyBieSBkZWZhdWx0IC0gb3ZlcmlkZGVuIGluIHN1YmNsYXNzCi0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICAvLyBOb3RpZmljYXRpb24gbWV0aG9kcyBvdmVyaWRkZW4gaW4gc3ViY2xhc3NlcwotCi0gICAgLyoqCi0gICAgICogQSBtZXRob2QgdG8gYmUgY2FsbGVkIHdoZW4gc29tZSB0ZXh0IHdhcyBjaGFuZ2VkIGluIGEgdGV4dCBub2RlLAotICAgICAqIHNvIHRoYXQgbGl2ZSBvYmplY3RzIGNhbiBiZSBub3RpZmllZC4KLSAgICAgKi8KLSAgICB2b2lkIHJlcGxhY2VkVGV4dChOb2RlSW1wbCBub2RlKSB7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQSBtZXRob2QgdG8gYmUgY2FsbGVkIHdoZW4gc29tZSB0ZXh0IHdhcyBkZWxldGVkIGZyb20gYSB0ZXh0IG5vZGUsCi0gICAgICogc28gdGhhdCBsaXZlIG9iamVjdHMgY2FuIGJlIG5vdGlmaWVkLgotICAgICAqLwotICAgIHZvaWQgZGVsZXRlZFRleHQoTm9kZUltcGwgbm9kZSwgaW50IG9mZnNldCwgaW50IGNvdW50KSB7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQSBtZXRob2QgdG8gYmUgY2FsbGVkIHdoZW4gc29tZSB0ZXh0IHdhcyBpbnNlcnRlZCBpbnRvIGEgdGV4dCBub2RlLAotICAgICAqIHNvIHRoYXQgbGl2ZSBvYmplY3RzIGNhbiBiZSBub3RpZmllZC4KLSAgICAgKi8KLSAgICB2b2lkIGluc2VydGVkVGV4dChOb2RlSW1wbCBub2RlLCBpbnQgb2Zmc2V0LCBpbnQgY291bnQpIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBIG1ldGhvZCB0byBiZSBjYWxsZWQgd2hlbiBhIGNoYXJhY3RlciBkYXRhIG5vZGUgaXMgYWJvdXQgdG8gYmUgbW9kaWZpZWQKLSAgICAgKi8KLSAgICB2b2lkIG1vZGlmeWluZ0NoYXJhY3RlckRhdGEoTm9kZUltcGwgbm9kZSwgYm9vbGVhbiByZXBsYWNlKSB7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQSBtZXRob2QgdG8gYmUgY2FsbGVkIHdoZW4gYSBjaGFyYWN0ZXIgZGF0YSBub2RlIGhhcyBiZWVuIG1vZGlmaWVkCi0gICAgICovCi0gICAgdm9pZCBtb2RpZmllZENoYXJhY3RlckRhdGEoTm9kZUltcGwgbm9kZSwgU3RyaW5nIG9sZHZhbHVlLCBTdHJpbmcgdmFsdWUsIGJvb2xlYW4gcmVwbGFjZSkgewotICAgIH0KLQotICAgIC8qKgotICAgICAqIEEgbWV0aG9kIHRvIGJlIGNhbGxlZCB3aGVuIGEgbm9kZSBpcyBhYm91dCB0byBiZSBpbnNlcnRlZCBpbiB0aGUgdHJlZS4KLSAgICAgKi8KLSAgICB2b2lkIGluc2VydGluZ05vZGUoTm9kZUltcGwgbm9kZSwgYm9vbGVhbiByZXBsYWNlKSB7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQSBtZXRob2QgdG8gYmUgY2FsbGVkIHdoZW4gYSBub2RlIGhhcyBiZWVuIGluc2VydGVkIGluIHRoZSB0cmVlLgotICAgICAqLwotICAgIHZvaWQgaW5zZXJ0ZWROb2RlKE5vZGVJbXBsIG5vZGUsIE5vZGVJbXBsIG5ld0ludGVybmFsLCBib29sZWFuIHJlcGxhY2UpIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBIG1ldGhvZCB0byBiZSBjYWxsZWQgd2hlbiBhIG5vZGUgaXMgYWJvdXQgdG8gYmUgcmVtb3ZlZCBmcm9tIHRoZSB0cmVlLgotICAgICAqLwotICAgIHZvaWQgcmVtb3ZpbmdOb2RlKE5vZGVJbXBsIG5vZGUsIE5vZGVJbXBsIG9sZENoaWxkLCBib29sZWFuIHJlcGxhY2UpIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBIG1ldGhvZCB0byBiZSBjYWxsZWQgd2hlbiBhIG5vZGUgaGFzIGJlZW4gcmVtb3ZlZCBmcm9tIHRoZSB0cmVlLgotICAgICAqLwotICAgIHZvaWQgcmVtb3ZlZE5vZGUoTm9kZUltcGwgbm9kZSwgYm9vbGVhbiByZXBsYWNlKSB7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQSBtZXRob2QgdG8gYmUgY2FsbGVkIHdoZW4gYSBub2RlIGlzIGFib3V0IHRvIGJlIHJlcGxhY2VkIGluIHRoZSB0cmVlLgotICAgICAqLwotICAgIHZvaWQgcmVwbGFjaW5nTm9kZShOb2RlSW1wbCBub2RlKSB7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQSBtZXRob2QgdG8gYmUgY2FsbGVkIHdoZW4gYSBub2RlIGhhcyBiZWVuIHJlcGxhY2VkIGluIHRoZSB0cmVlLgotICAgICAqLwotICAgIHZvaWQgcmVwbGFjZWROb2RlKE5vZGVJbXBsIG5vZGUpIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBIG1ldGhvZCB0byBiZSBjYWxsZWQgd2hlbiBhIGNoYXJhY3RlciBkYXRhIG5vZGUgaXMgYWJvdXQgdG8gYmUgcmVwbGFjZWQKLSAgICAgKi8KLSAgICB2b2lkIHJlcGxhY2luZ0RhdGEoTm9kZUltcGwgbm9kZSkgewotICAgIH0KLQotICAgIC8qKgotICAgICAqICBtZXRob2QgdG8gYmUgY2FsbGVkIHdoZW4gYSBjaGFyYWN0ZXIgZGF0YSBub2RlIGhhcyBiZWVuIHJlcGxhY2VkLgotICAgICAqLwotICAgIHZvaWQgcmVwbGFjZWRDaGFyYWN0ZXJEYXRhKE5vZGVJbXBsIG5vZGUsIFN0cmluZyBvbGR2YWx1ZSwgU3RyaW5nIHZhbHVlKSB7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBBIG1ldGhvZCB0byBiZSBjYWxsZWQgd2hlbiBhbiBhdHRyaWJ1dGUgdmFsdWUgaGFzIGJlZW4gbW9kaWZpZWQKLSAgICAgKi8KLSAgICB2b2lkIG1vZGlmaWVkQXR0clZhbHVlKEF0dHJJbXBsIGF0dHIsIFN0cmluZyBvbGR2YWx1ZSkgewotICAgIH0KLQotICAgIC8qKgotICAgICAqIEEgbWV0aG9kIHRvIGJlIGNhbGxlZCB3aGVuIGFuIGF0dHJpYnV0ZSBub2RlIGhhcyBiZWVuIHNldAotICAgICAqLwotICAgIHZvaWQgc2V0QXR0ck5vZGUoQXR0ckltcGwgYXR0ciwgQXR0ckltcGwgcHJldmlvdXMpIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBIG1ldGhvZCB0byBiZSBjYWxsZWQgd2hlbiBhbiBhdHRyaWJ1dGUgbm9kZSBoYXMgYmVlbiByZW1vdmVkCi0gICAgICovCi0gICAgdm9pZCByZW1vdmVkQXR0ck5vZGUoQXR0ckltcGwgYXR0ciwgTm9kZUltcGwgb2xkT3duZXIsIFN0cmluZyBuYW1lKSB7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQSBtZXRob2QgdG8gYmUgY2FsbGVkIHdoZW4gYW4gYXR0cmlidXRlIG5vZGUgaGFzIGJlZW4gcmVuYW1lZAotICAgICAqLwotICAgIHZvaWQgcmVuYW1lZEF0dHJOb2RlKEF0dHIgb2xkQXQsIEF0dHIgbmV3QXQpIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBIG1ldGhvZCB0byBiZSBjYWxsZWQgd2hlbiBhbiBlbGVtZW50IGhhcyBiZWVuIHJlbmFtZWQKLSAgICAgKi8KLSAgICB2b2lkIHJlbmFtZWRFbGVtZW50KEVsZW1lbnQgb2xkRWwsIEVsZW1lbnQgbmV3RWwpIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAc2VyaWFsRGF0YSBTZXJpYWxpemVkIGZpZWxkcy4gQ29udmVydCBNYXBzIHRvIEhhc2h0YWJsZXMgZm9yIGJhY2t3YXJkCi0gICAgICogY29tcGF0aWJpbGl0eS4KLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgd3JpdGVPYmplY3QoT2JqZWN0T3V0cHV0U3RyZWFtIG91dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLSAgICAgICAgLy8gQ29udmVydCBNYXBzIHRvIEhhc2h0YWJsZXMKLSAgICAgICAgSGFzaHRhYmxlPE5vZGUsIEhhc2h0YWJsZTxTdHJpbmcsIFVzZXJEYXRhUmVjb3JkPj4gbnVkID0gbnVsbDsKLSAgICAgICAgaWYgKG5vZGVVc2VyRGF0YSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBudWQgPSBuZXcgSGFzaHRhYmxlPD4oKTsKLSAgICAgICAgICAgIGZvciAoTWFwLkVudHJ5PE5vZGUsIE1hcDxTdHJpbmcsIFVzZXJEYXRhUmVjb3JkPj4gZSA6IG5vZGVVc2VyRGF0YS5lbnRyeVNldCgpKSB7Ci0gICAgICAgICAgICAgICAgLy9lLmdldFZhbHVlKCkgd2lsbCBub3QgYmUgbnVsbCBzaW5jZSBhbiBlbnRyeSBpcyBhbHdheXMgcHV0IHdpdGggYSBub24tbnVsbCB2YWx1ZQotICAgICAgICAgICAgICAgIG51ZC5wdXQoZS5nZXRLZXkoKSwgbmV3IEhhc2h0YWJsZTw+KGUuZ2V0VmFsdWUoKSkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgSGFzaHRhYmxlPFN0cmluZywgTm9kZT4gaWRzID0gKGlkZW50aWZpZXJzID09IG51bGwpPyBudWxsIDogbmV3IEhhc2h0YWJsZTw+KGlkZW50aWZpZXJzKTsKLSAgICAgICAgSGFzaHRhYmxlPE5vZGUsIEludGVnZXI+IG50ID0gKG5vZGVUYWJsZSA9PSBudWxsKT8gbnVsbCA6IG5ldyBIYXNodGFibGU8Pihub2RlVGFibGUpOwotCi0gICAgICAgIC8vIFdyaXRlIHNlcmlhbGl6ZWQgZmllbGRzCi0gICAgICAgIE9iamVjdE91dHB1dFN0cmVhbS5QdXRGaWVsZCBwZiA9IG91dC5wdXRGaWVsZHMoKTsKLSAgICAgICAgcGYucHV0KCJkb2NUeXBlIiwgZG9jVHlwZSk7Ci0gICAgICAgIHBmLnB1dCgiZG9jRWxlbWVudCIsIGRvY0VsZW1lbnQpOwotICAgICAgICBwZi5wdXQoImZGcmVlTkxDYWNoZSIsIGZGcmVlTkxDYWNoZSk7Ci0gICAgICAgIHBmLnB1dCgiZW5jb2RpbmciLCBlbmNvZGluZyk7Ci0gICAgICAgIHBmLnB1dCgiYWN0dWFsRW5jb2RpbmciLCBhY3R1YWxFbmNvZGluZyk7Ci0gICAgICAgIHBmLnB1dCgidmVyc2lvbiIsIHZlcnNpb24pOwotICAgICAgICBwZi5wdXQoInN0YW5kYWxvbmUiLCBzdGFuZGFsb25lKTsKLSAgICAgICAgcGYucHV0KCJmRG9jdW1lbnRVUkkiLCBmRG9jdW1lbnRVUkkpOwotCi0gICAgICAgIC8vdXNlckRhdGEgaXMgdGhlIG9yaWdpbmFsIG5hbWUuIEl0IGhhcyBiZWVuIGNoYW5nZWQgdG8gbm9kZVVzZXJEYXRhLCByZWZlciB0byB0aGUgY29ycnNwb25kaW5nIEBzZXJpYWxGaWVsZAotICAgICAgICBwZi5wdXQoInVzZXJEYXRhIiwgbnVkKTsKLSAgICAgICAgcGYucHV0KCJpZGVudGlmaWVycyIsIGlkcyk7Ci0gICAgICAgIHBmLnB1dCgiY2hhbmdlcyIsIGNoYW5nZXMpOwotICAgICAgICBwZi5wdXQoImFsbG93R3JhbW1hckFjY2VzcyIsIGFsbG93R3JhbW1hckFjY2Vzcyk7Ci0gICAgICAgIHBmLnB1dCgiZXJyb3JDaGVja2luZyIsIGVycm9yQ2hlY2tpbmcpOwotICAgICAgICBwZi5wdXQoImFuY2VzdG9yQ2hlY2tpbmciLCBhbmNlc3RvckNoZWNraW5nKTsKLSAgICAgICAgcGYucHV0KCJ4bWxWZXJzaW9uQ2hhbmdlZCIsIHhtbFZlcnNpb25DaGFuZ2VkKTsKLSAgICAgICAgcGYucHV0KCJkb2N1bWVudE51bWJlciIsIGRvY3VtZW50TnVtYmVyKTsKLSAgICAgICAgcGYucHV0KCJub2RlQ291bnRlciIsIG5vZGVDb3VudGVyKTsKLSAgICAgICAgcGYucHV0KCJub2RlVGFibGUiLCBudCk7Ci0gICAgICAgIHBmLnB1dCgieG1sMTFWZXJzaW9uIiwgeG1sMTFWZXJzaW9uKTsKLSAgICAgICAgb3V0LndyaXRlRmllbGRzKCk7Ci0gICAgfQotCi0gICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCi0gICAgcHJpdmF0ZSB2b2lkIHJlYWRPYmplY3QoT2JqZWN0SW5wdXRTdHJlYW0gaW4pCi0gICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIENsYXNzTm90Rm91bmRFeGNlcHRpb24gewotICAgICAgICAvLyBXZSBoYXZlIHRvIHJlYWQgc2VyaWFsaXplZCBmaWVsZHMgZmlyc3QuCi0gICAgICAgIE9iamVjdElucHV0U3RyZWFtLkdldEZpZWxkIGdmID0gaW4ucmVhZEZpZWxkcygpOwotICAgICAgICBkb2NUeXBlID0gKERvY3VtZW50VHlwZUltcGwpZ2YuZ2V0KCJkb2NUeXBlIiwgbnVsbCk7Ci0gICAgICAgIGRvY0VsZW1lbnQgPSAoRWxlbWVudEltcGwpZ2YuZ2V0KCJkb2NFbGVtZW50IiwgbnVsbCk7Ci0gICAgICAgIGZGcmVlTkxDYWNoZSA9IChOb2RlTGlzdENhY2hlKWdmLmdldCgiZkZyZWVOTENhY2hlIiwgbnVsbCk7Ci0gICAgICAgIGVuY29kaW5nID0gKFN0cmluZylnZi5nZXQoImVuY29kaW5nIiwgbnVsbCk7Ci0gICAgICAgIGFjdHVhbEVuY29kaW5nID0gKFN0cmluZylnZi5nZXQoImFjdHVhbEVuY29kaW5nIiwgbnVsbCk7Ci0gICAgICAgIHZlcnNpb24gPSAoU3RyaW5nKWdmLmdldCgidmVyc2lvbiIsIG51bGwpOwotICAgICAgICBzdGFuZGFsb25lID0gZ2YuZ2V0KCJzdGFuZGFsb25lIiwgZmFsc2UpOwotICAgICAgICBmRG9jdW1lbnRVUkkgPSAoU3RyaW5nKWdmLmdldCgiZkRvY3VtZW50VVJJIiwgbnVsbCk7Ci0KLSAgICAgICAgLy91c2VyRGF0YSBpcyB0aGUgb3JpZ2luYWwgbmFtZS4gSXQgaGFzIGJlZW4gY2hhbmdlZCB0byBub2RlVXNlckRhdGEsIHJlZmVyIHRvIHRoZSBjb3Jyc3BvbmRpbmcgQHNlcmlhbEZpZWxkCi0gICAgICAgIEhhc2h0YWJsZTxOb2RlLCBIYXNodGFibGU8U3RyaW5nLCBVc2VyRGF0YVJlY29yZD4+IG51ZCA9Ci0gICAgICAgICAgICAgICAgKEhhc2h0YWJsZTxOb2RlLCBIYXNodGFibGU8U3RyaW5nLCBVc2VyRGF0YVJlY29yZD4+KWdmLmdldCgidXNlckRhdGEiLCBudWxsKTsKLQotICAgICAgICBIYXNodGFibGU8U3RyaW5nLCBOb2RlPiBpZHMgPSAoSGFzaHRhYmxlPFN0cmluZywgTm9kZT4pZ2YuZ2V0KCJpZGVudGlmaWVycyIsIG51bGwpOwotCi0gICAgICAgIGNoYW5nZXMgPSBnZi5nZXQoImNoYW5nZXMiLCAwKTsKLSAgICAgICAgYWxsb3dHcmFtbWFyQWNjZXNzID0gZ2YuZ2V0KCJhbGxvd0dyYW1tYXJBY2Nlc3MiLCBmYWxzZSk7Ci0gICAgICAgIGVycm9yQ2hlY2tpbmcgPSBnZi5nZXQoImVycm9yQ2hlY2tpbmciLCB0cnVlKTsKLSAgICAgICAgYW5jZXN0b3JDaGVja2luZyA9IGdmLmdldCgiYW5jZXN0b3JDaGVja2luZyIsIHRydWUpOwotICAgICAgICB4bWxWZXJzaW9uQ2hhbmdlZCA9IGdmLmdldCgieG1sVmVyc2lvbkNoYW5nZWQiLCBmYWxzZSk7Ci0gICAgICAgIGRvY3VtZW50TnVtYmVyID0gZ2YuZ2V0KCJkb2N1bWVudE51bWJlciIsIDApOwotICAgICAgICBub2RlQ291bnRlciA9IGdmLmdldCgibm9kZUNvdW50ZXIiLCAwKTsKLQotICAgICAgICBIYXNodGFibGU8Tm9kZSwgSW50ZWdlcj4gbnQgPSAoSGFzaHRhYmxlPE5vZGUsIEludGVnZXI+KWdmLmdldCgibm9kZVRhYmxlIiwgbnVsbCk7Ci0KLSAgICAgICAgeG1sMTFWZXJzaW9uID0gZ2YuZ2V0KCJ4bWwxMVZlcnNpb24iLCBmYWxzZSk7Ci0KLSAgICAgICAgLy9jb252ZXJ0IEhhc2h0YWJsZXMgYmFjayB0byBIYXNoTWFwcwotICAgICAgICBpZiAobnVkICE9IG51bGwpIHsKLSAgICAgICAgICAgIG5vZGVVc2VyRGF0YSA9IG5ldyBIYXNoTWFwPD4oKTsKLSAgICAgICAgICAgIGZvciAoTWFwLkVudHJ5PE5vZGUsIEhhc2h0YWJsZTxTdHJpbmcsIFVzZXJEYXRhUmVjb3JkPj4gZSA6IG51ZC5lbnRyeVNldCgpKSB7Ci0gICAgICAgICAgICAgICAgbm9kZVVzZXJEYXRhLnB1dChlLmdldEtleSgpLCBuZXcgSGFzaE1hcDw+KGUuZ2V0VmFsdWUoKSkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKGlkcyAhPSBudWxsKSBpZGVudGlmaWVycyA9IG5ldyBIYXNoTWFwPD4oaWRzKTsKLSAgICAgICAgaWYgKG50ICE9IG51bGwpIG5vZGVUYWJsZSA9IG5ldyBIYXNoTWFwPD4obnQpOwotICAgIH0KLX0gLy8gY2xhc3MgQ29yZURvY3VtZW50SW1wbApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL0RPTUNvbmZpZ3VyYXRpb25JbXBsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vRE9NQ29uZmlndXJhdGlvbkltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMWU4ZGNkOS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vRE9NQ29uZmlndXJhdGlvbkltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExMDMgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbTsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5Db25zdGFudHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLlhNTEVudGl0eU1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLlhNTEVycm9yUmVwb3J0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LkRURERWRmFjdG9yeTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwubXNnLlhNTE1lc3NhZ2VGb3JtYXR0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnZhbGlkYXRpb24uVmFsaWRhdGlvbk1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLkRPTUVudGl0eVJlc29sdmVyV3JhcHBlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuRE9NRXJyb3JIYW5kbGVyV3JhcHBlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuTWVzc2FnZUZvcm1hdHRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuUGFyc2VyQ29uZmlndXJhdGlvblNldHRpbmdzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5Qcm9wZXJ0eVN0YXRlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5TeW1ib2xUYWJsZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWxzLk9iamVjdEZhY3Rvcnk7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlscy5YTUxTZWN1cml0eU1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlscy5YTUxTZWN1cml0eVByb3BlcnR5TWFuYWdlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxEVERDb250ZW50TW9kZWxIYW5kbGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTERUREhhbmRsZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MRG9jdW1lbnRIYW5kbGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhOSUV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5ncmFtbWFycy5YTUxHcmFtbWFyUG9vbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MQ29tcG9uZW50OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxDb21wb25lbnRNYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxFbnRpdHlSZXNvbHZlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MRXJyb3JIYW5kbGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxJbnB1dFNvdXJjZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MUGFyc2VyQ29uZmlndXJhdGlvbjsKLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7Ci1pbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7Ci1pbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotaW1wb3J0IGphdmF4LnhtbC5YTUxDb25zdGFudHM7Ci1pbXBvcnQgb3JnLnczYy5kb20uRE9NQ29uZmlndXJhdGlvbjsKLWltcG9ydCBvcmcudzNjLmRvbS5ET01FcnJvckhhbmRsZXI7Ci1pbXBvcnQgb3JnLnczYy5kb20uRE9NRXhjZXB0aW9uOwotaW1wb3J0IG9yZy53M2MuZG9tLkRPTVN0cmluZ0xpc3Q7Ci1pbXBvcnQgb3JnLnczYy5kb20ubHMuTFNSZXNvdXJjZVJlc29sdmVyOwotCi0KLQotLyoqCi0gKiBYZXJjZXMgaW1wbGVtZW50YXRpb24gb2YgRE9NQ29uZmlndXJhdGlvbiB0aGF0IG1haW50YWlucyBhIHRhYmxlIG9mIHJlY29nbml6ZWQgcGFyYW1ldGVycy4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBFbGVuYSBMaXRhbmksIElCTQotICogQGF1dGhvciBOZWVyYWogQmFqYWosIFN1biBNaWNyb3N5c3RlbXMuCi0gKiBAdmVyc2lvbiAkSWQ6IERPTUNvbmZpZ3VyYXRpb25JbXBsLmphdmEsdiAxLjkgMjAxMC0xMS0wMSAwNDozOTozNyBqb2VodyBFeHAgJAotICovCi1wdWJsaWMgY2xhc3MgRE9NQ29uZmlndXJhdGlvbkltcGwgZXh0ZW5kcyBQYXJzZXJDb25maWd1cmF0aW9uU2V0dGluZ3MKLSAgICBpbXBsZW1lbnRzIFhNTFBhcnNlckNvbmZpZ3VyYXRpb24sIERPTUNvbmZpZ3VyYXRpb24gewotCi0gICAgLy8KLSAgICAvLyBDb25zdGFudHMKLSAgICAvLwotCi0gICAgLy8gZmVhdHVyZSBpZGVudGlmaWVycwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogdmFsaWRhdGlvbi4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBYRVJDRVNfVkFMSURBVElPTiA9Ci0gICAgICAgIENvbnN0YW50cy5TQVhfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuVkFMSURBVElPTl9GRUFUVVJFOwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogbmFtZXNwYWNlcy4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBYRVJDRVNfTkFNRVNQQUNFUyA9Ci0gICAgICAgIENvbnN0YW50cy5TQVhfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuTkFNRVNQQUNFU19GRUFUVVJFOwotCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgU0NIRU1BID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5TQ0hFTUFfVkFMSURBVElPTl9GRUFUVVJFOwotCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgU0NIRU1BX0ZVTExfQ0hFQ0tJTkcgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLlNDSEVNQV9GVUxMX0NIRUNLSU5HOwotCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgRFlOQU1JQ19WQUxJREFUSU9OID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5EWU5BTUlDX1ZBTElEQVRJT05fRkVBVFVSRTsKLQotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIE5PUk1BTElaRV9EQVRBID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5TQ0hFTUFfTk9STUFMSVpFRF9WQUxVRTsKLQotICAgIC8qKiBzZW5kaW5nIHBzdmkgaW4gdGhlIHBpcGVsaW5lICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgU0VORF9QU1ZJID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5TQ0hFTUFfQVVHTUVOVF9QU1ZJOwotCi0gICAgcHJvdGVjdGVkIGZpbmFsIHN0YXRpYyBTdHJpbmcgRFREX1ZBTElEQVRPUl9GQUNUT1JZX1BST1BFUlRZID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuREFUQVRZUEVfVkFMSURBVE9SX0ZBQ1RPUllfUFJPUEVSVFk7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiBuYW1lc3BhY2UgZ3Jvd3RoICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgTkFNRVNQQUNFX0dST1dUSCA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuTkFNRVNQQUNFX0dST1dUSF9GRUFUVVJFOwotCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgVE9MRVJBVEVfRFVQTElDQVRFUyA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuVE9MRVJBVEVfRFVQTElDQVRFU19GRUFUVVJFOwotCi0gICAgLy8gcHJvcGVydHkgaWRlbnRpZmllcnMKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBlbnRpdHkgbWFuYWdlci4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBFTlRJVFlfTUFOQUdFUiA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLkVOVElUWV9NQU5BR0VSX1BST1BFUlRZOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IGVycm9yIHJlcG9ydGVyLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUk9SX1JFUE9SVEVSID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuRVJST1JfUkVQT1JURVJfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogeG1sIHN0cmluZy4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxfU1RSSU5HID0KLSAgICAgICAgQ29uc3RhbnRzLlNBWF9QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuWE1MX1NUUklOR19QUk9QRVJUWTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBzeW1ib2wgdGFibGUuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1lNQk9MX1RBQkxFID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuU1lNQk9MX1RBQkxFX1BST1BFUlRZOwotCi0gICAgLyoqIFByb3BlcnR5IGlkOiBHcmFtbWFyIHBvb2wqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIEdSQU1NQVJfUE9PTCA9Ci0gICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuWE1MR1JBTU1BUl9QT09MX1BST1BFUlRZOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IGVycm9yIGhhbmRsZXIuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJST1JfSEFORExFUiA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLkVSUk9SX0hBTkRMRVJfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogZW50aXR5IHJlc29sdmVyLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIEVOVElUWV9SRVNPTFZFUiA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLkVOVElUWV9SRVNPTFZFUl9QUk9QRVJUWTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBKQVhQIHNjaGVtYSBsYW5ndWFnZSAvIERPTSBzY2hlbWEtdHlwZS4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBKQVhQX1NDSEVNQV9MQU5HVUFHRSA9Ci0gICAgQ29uc3RhbnRzLkpBWFBfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLlNDSEVNQV9MQU5HVUFHRTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBKQVhQIHNjaGVtYSBzb3VyY2UvIERPTSBzY2hlbWEtbG9jYXRpb24uICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgSkFYUF9TQ0hFTUFfU09VUkNFID0KLSAgICBDb25zdGFudHMuSkFYUF9QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuU0NIRU1BX1NPVVJDRTsKLQotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFZBTElEQVRJT05fTUFOQUdFUiA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLlZBTElEQVRJT05fTUFOQUdFUl9QUk9QRVJUWTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBTY2hlbWEgRFYgRmFjdG9yeSAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFNDSEVNQV9EVl9GQUNUT1JZID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuU0NIRU1BX0RWX0ZBQ1RPUllfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogU2VjdXJpdHkgbWFuYWdlci4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgU0VDVVJJVFlfTUFOQUdFUiA9IENvbnN0YW50cy5TRUNVUklUWV9NQU5BR0VSOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IFNlY3VyaXR5IHByb3BlcnR5IG1hbmFnZXIuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFhNTF9TRUNVUklUWV9QUk9QRVJUWV9NQU5BR0VSID0KLSAgICAgICAgICAgIENvbnN0YW50cy5YTUxfU0VDVVJJVFlfUFJPUEVSVFlfTUFOQUdFUjsKLQotICAgIC8vCi0gICAgLy8gRGF0YQotICAgIC8vCi0gICAgWE1MRG9jdW1lbnRIYW5kbGVyIGZEb2N1bWVudEhhbmRsZXI7Ci0KLSAgICAvKiogTm9ybWFsaXphdGlvbiBmZWF0dXJlcyovCi0gICAgcHJvdGVjdGVkIHNob3J0IGZlYXR1cmVzID0gMDsKLQotICAgIHByb3RlY3RlZCBmaW5hbCBzdGF0aWMgc2hvcnQgTkFNRVNQQUNFUyAgICAgICAgICA9IDB4MTw8MDsKLSAgICBwcm90ZWN0ZWQgZmluYWwgc3RhdGljIHNob3J0IERUTk9STUFMSVpBVElPTiAgICAgPSAweDE8PDE7Ci0gICAgcHJvdGVjdGVkIGZpbmFsIHN0YXRpYyBzaG9ydCBFTlRJVElFUyAgICAgICAgICAgID0gMHgxPDwyOwotICAgIHByb3RlY3RlZCBmaW5hbCBzdGF0aWMgc2hvcnQgQ0RBVEEgICAgICAgICAgICAgICA9IDB4MTw8MzsKLSAgICBwcm90ZWN0ZWQgZmluYWwgc3RhdGljIHNob3J0IFNQTElUQ0RBVEEgICAgICAgICAgPSAweDE8PDQ7Ci0gICAgcHJvdGVjdGVkIGZpbmFsIHN0YXRpYyBzaG9ydCBDT01NRU5UUyAgICAgICAgICAgID0gMHgxPDw1OwotICAgIHByb3RlY3RlZCBmaW5hbCBzdGF0aWMgc2hvcnQgVkFMSURBVEUgICAgICAgICAgICA9IDB4MTw8NjsKLSAgICBwcm90ZWN0ZWQgZmluYWwgc3RhdGljIHNob3J0IFBTVkkgICAgICAgICAgICAgICAgPSAweDE8PDc7Ci0gICAgcHJvdGVjdGVkIGZpbmFsIHN0YXRpYyBzaG9ydCBXRUxMRk9STUVEICAgICAgICAgID0gMHgxPDw4OwotICAgIHByb3RlY3RlZCBmaW5hbCBzdGF0aWMgc2hvcnQgTlNERUNMICAgICAgICAgICAgICA9IDB4MTw8OTsKLQotICAgIHByb3RlY3RlZCBmaW5hbCBzdGF0aWMgc2hvcnQgSU5GT1NFVF9UUlVFX1BBUkFNUyA9IE5BTUVTUEFDRVMgfCBDT01NRU5UUyB8IFdFTExGT1JNRUQgfCBOU0RFQ0w7Ci0gICAgcHJvdGVjdGVkIGZpbmFsIHN0YXRpYyBzaG9ydCBJTkZPU0VUX0ZBTFNFX1BBUkFNUyA9IEVOVElUSUVTIHwgRFROT1JNQUxJWkFUSU9OIHwgQ0RBVEE7Ci0gICAgcHJvdGVjdGVkIGZpbmFsIHN0YXRpYyBzaG9ydCBJTkZPU0VUX01BU0sgPSBJTkZPU0VUX1RSVUVfUEFSQU1TIHwgSU5GT1NFVF9GQUxTRV9QQVJBTVM7Ci0KLSAgICAvLyBjb21wb25lbnRzCi0KLSAgICAvKiogU3ltYm9sIHRhYmxlLiAqLwotICAgIHByb3RlY3RlZCBTeW1ib2xUYWJsZSBmU3ltYm9sVGFibGU7Ci0KLSAgICAvKiogQ29tcG9uZW50cy4gKi8KLSAgICBwcm90ZWN0ZWQgQXJyYXlMaXN0IGZDb21wb25lbnRzOwotCi0gICAgcHJvdGVjdGVkIFZhbGlkYXRpb25NYW5hZ2VyIGZWYWxpZGF0aW9uTWFuYWdlcjsKLQotICAgIC8qKiBMb2NhbGUuICovCi0gICAgcHJvdGVjdGVkIExvY2FsZSBmTG9jYWxlOwotCi0gICAgLyoqIEVycm9yIHJlcG9ydGVyICovCi0gICAgcHJvdGVjdGVkIFhNTEVycm9yUmVwb3J0ZXIgZkVycm9yUmVwb3J0ZXI7Ci0KLSAgICBwcm90ZWN0ZWQgZmluYWwgRE9NRXJyb3JIYW5kbGVyV3JhcHBlciBmRXJyb3JIYW5kbGVyV3JhcHBlciA9Ci0gICAgICAgICAgICAgICAgbmV3IERPTUVycm9ySGFuZGxlcldyYXBwZXIoKTsKLQotICAgIC8vIHByaXZhdGUgZGF0YQotCi0gICAgcHJpdmF0ZSBET01TdHJpbmdMaXN0IGZSZWNvZ25pemVkUGFyYW1ldGVyczsKLQotCi0gICAgLy8KLSAgICAvLyBDb25zdHJ1Y3RvcnMKLSAgICAvLwotCi0gICAgLyoqIERlZmF1bHQgQ29uc3RydWN0b3IuICovCi0gICAgcHJvdGVjdGVkIERPTUNvbmZpZ3VyYXRpb25JbXBsKCkgewotICAgICAgICB0aGlzKG51bGwsIG51bGwpOwotICAgIH0gLy8gPGluaXQ+KCkKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHMgYSBwYXJzZXIgY29uZmlndXJhdGlvbiB1c2luZyB0aGUgc3BlY2lmaWVkIHN5bWJvbCB0YWJsZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzeW1ib2xUYWJsZSBUaGUgc3ltYm9sIHRhYmxlIHRvIHVzZS4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgRE9NQ29uZmlndXJhdGlvbkltcGwoU3ltYm9sVGFibGUgc3ltYm9sVGFibGUpIHsKLSAgICAgICAgdGhpcyhzeW1ib2xUYWJsZSwgbnVsbCk7Ci0gICAgfSAvLyA8aW5pdD4oU3ltYm9sVGFibGUpCi0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RzIGEgcGFyc2VyIGNvbmZpZ3VyYXRpb24gdXNpbmcgdGhlIHNwZWNpZmllZCBzeW1ib2wgdGFibGUKLSAgICAgKiBhbmQgcGFyZW50IHNldHRpbmdzLgotICAgICAqCi0gICAgICogQHBhcmFtIHN5bWJvbFRhYmxlICAgIFRoZSBzeW1ib2wgdGFibGUgdG8gdXNlLgotICAgICAqIEBwYXJhbSBwYXJlbnRTZXR0aW5ncyBUaGUgcGFyZW50IHNldHRpbmdzLgotICAgICAqLwotICAgIHByb3RlY3RlZCBET01Db25maWd1cmF0aW9uSW1wbChTeW1ib2xUYWJsZSBzeW1ib2xUYWJsZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTENvbXBvbmVudE1hbmFnZXIgcGFyZW50U2V0dGluZ3MpIHsKLSAgICAgICAgc3VwZXIocGFyZW50U2V0dGluZ3MpOwotCi0KLSAgICAgICAgLy8gY3JlYXRlIHRhYmxlIGZvciBmZWF0dXJlcyBhbmQgcHJvcGVydGllcwotICAgICAgICBmRmVhdHVyZXMgPSBuZXcgSGFzaE1hcCgpOwotICAgICAgICBmUHJvcGVydGllcyA9IG5ldyBIYXNoTWFwKCk7Ci0KLSAgICAgICAgLy8gYWRkIGRlZmF1bHQgcmVjb2duaXplZCBmZWF0dXJlcwotICAgICAgICBmaW5hbCBTdHJpbmdbXSByZWNvZ25pemVkRmVhdHVyZXMgPSB7Ci0gICAgICAgICAgICBYRVJDRVNfVkFMSURBVElPTiwKLSAgICAgICAgICAgIFhFUkNFU19OQU1FU1BBQ0VTLAotICAgICAgICAgICAgU0NIRU1BLAotICAgICAgICAgICAgU0NIRU1BX0ZVTExfQ0hFQ0tJTkcsCi0gICAgICAgICAgICBEWU5BTUlDX1ZBTElEQVRJT04sCi0gICAgICAgICAgICBOT1JNQUxJWkVfREFUQSwKLSAgICAgICAgICAgIFNFTkRfUFNWSSwKLSAgICAgICAgICAgIE5BTUVTUEFDRV9HUk9XVEgsCi0gICAgICAgICAgICBUT0xFUkFURV9EVVBMSUNBVEVTCi0gICAgICAgIH07Ci0gICAgICAgIGFkZFJlY29nbml6ZWRGZWF0dXJlcyhyZWNvZ25pemVkRmVhdHVyZXMpOwotCi0gICAgICAgIC8vIHNldCBzdGF0ZSBmb3IgZGVmYXVsdCBmZWF0dXJlcwotICAgICAgICBzZXRGZWF0dXJlKFhFUkNFU19WQUxJREFUSU9OLCBmYWxzZSk7Ci0gICAgICAgIHNldEZlYXR1cmUoU0NIRU1BLCBmYWxzZSk7Ci0gICAgICAgIHNldEZlYXR1cmUoU0NIRU1BX0ZVTExfQ0hFQ0tJTkcsIGZhbHNlKTsKLSAgICAgICAgc2V0RmVhdHVyZShEWU5BTUlDX1ZBTElEQVRJT04sIGZhbHNlKTsKLSAgICAgICAgc2V0RmVhdHVyZShOT1JNQUxJWkVfREFUQSwgZmFsc2UpOwotICAgICAgICBzZXRGZWF0dXJlKFhFUkNFU19OQU1FU1BBQ0VTLCB0cnVlKTsKLSAgICAgICAgc2V0RmVhdHVyZShTRU5EX1BTVkksIHRydWUpOwotICAgICAgICBzZXRGZWF0dXJlKE5BTUVTUEFDRV9HUk9XVEgsIGZhbHNlKTsKLQotICAgICAgICAvLyBhZGQgZGVmYXVsdCByZWNvZ25pemVkIHByb3BlcnRpZXMKLSAgICAgICAgZmluYWwgU3RyaW5nW10gcmVjb2duaXplZFByb3BlcnRpZXMgPSB7Ci0gICAgICAgICAgICBYTUxfU1RSSU5HLAotICAgICAgICAgICAgU1lNQk9MX1RBQkxFLAotICAgICAgICAgICAgRVJST1JfSEFORExFUiwKLSAgICAgICAgICAgIEVOVElUWV9SRVNPTFZFUiwKLSAgICAgICAgICAgIEVSUk9SX1JFUE9SVEVSLAotICAgICAgICAgICAgRU5USVRZX01BTkFHRVIsCi0gICAgICAgICAgICBWQUxJREFUSU9OX01BTkFHRVIsCi0gICAgICAgICAgICBHUkFNTUFSX1BPT0wsCi0gICAgICAgICAgICBKQVhQX1NDSEVNQV9TT1VSQ0UsCi0gICAgICAgICAgICBKQVhQX1NDSEVNQV9MQU5HVUFHRSwKLSAgICAgICAgICAgIERURF9WQUxJREFUT1JfRkFDVE9SWV9QUk9QRVJUWSwKLSAgICAgICAgICAgIFNDSEVNQV9EVl9GQUNUT1JZLAotICAgICAgICAgICAgU0VDVVJJVFlfTUFOQUdFUiwKLSAgICAgICAgICAgIFhNTF9TRUNVUklUWV9QUk9QRVJUWV9NQU5BR0VSCi0gICAgICAgIH07Ci0gICAgICAgIGFkZFJlY29nbml6ZWRQcm9wZXJ0aWVzKHJlY29nbml6ZWRQcm9wZXJ0aWVzKTsKLQotICAgICAgICAvLyBzZXQgZGVmYXVsdCB2YWx1ZXMgZm9yIG5vcm1hbGl6YXRpb24gZmVhdHVyZXMKLSAgICAgICAgZmVhdHVyZXMgfD0gTkFNRVNQQUNFUzsKLSAgICAgICAgZmVhdHVyZXMgfD0gRU5USVRJRVM7Ci0gICAgICAgIGZlYXR1cmVzIHw9IENPTU1FTlRTOwotICAgICAgICBmZWF0dXJlcyB8PSBDREFUQTsKLSAgICAgICAgZmVhdHVyZXMgfD0gU1BMSVRDREFUQTsKLSAgICAgICAgZmVhdHVyZXMgfD0gV0VMTEZPUk1FRDsKLSAgICAgICAgZmVhdHVyZXMgfD0gTlNERUNMOwotCi0gICAgICAgIGlmIChzeW1ib2xUYWJsZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBzeW1ib2xUYWJsZSA9IG5ldyBTeW1ib2xUYWJsZSgpOwotICAgICAgICB9Ci0gICAgICAgIGZTeW1ib2xUYWJsZSA9IHN5bWJvbFRhYmxlOwotCi0gICAgICAgIGZDb21wb25lbnRzID0gbmV3IEFycmF5TGlzdCgpOwotCi0gICAgICAgIHNldFByb3BlcnR5KFNZTUJPTF9UQUJMRSwgZlN5bWJvbFRhYmxlKTsKLSAgICAgICAgZkVycm9yUmVwb3J0ZXIgPSBuZXcgWE1MRXJyb3JSZXBvcnRlcigpOwotICAgICAgICBzZXRQcm9wZXJ0eShFUlJPUl9SRVBPUlRFUiwgZkVycm9yUmVwb3J0ZXIpOwotICAgICAgICBhZGRDb21wb25lbnQoZkVycm9yUmVwb3J0ZXIpOwotCi0gICAgICAgIHNldFByb3BlcnR5KERURF9WQUxJREFUT1JfRkFDVE9SWV9QUk9QRVJUWSwgRFRERFZGYWN0b3J5LmdldEluc3RhbmNlKCkpOwotCi0gICAgICAgIFhNTEVudGl0eU1hbmFnZXIgbWFuYWdlciA9ICBuZXcgWE1MRW50aXR5TWFuYWdlcigpOwotICAgICAgICBzZXRQcm9wZXJ0eShFTlRJVFlfTUFOQUdFUiwgbWFuYWdlcik7Ci0gICAgICAgIGFkZENvbXBvbmVudChtYW5hZ2VyKTsKLQotICAgICAgICBmVmFsaWRhdGlvbk1hbmFnZXIgPSBjcmVhdGVWYWxpZGF0aW9uTWFuYWdlcigpOwotICAgICAgICBzZXRQcm9wZXJ0eShWQUxJREFUSU9OX01BTkFHRVIsIGZWYWxpZGF0aW9uTWFuYWdlcik7Ci0KLSAgICAgICAgc2V0UHJvcGVydHkoU0VDVVJJVFlfTUFOQUdFUiwgbmV3IFhNTFNlY3VyaXR5TWFuYWdlcih0cnVlKSk7Ci0KLSAgICAgICAgc2V0UHJvcGVydHkoQ29uc3RhbnRzLlhNTF9TRUNVUklUWV9QUk9QRVJUWV9NQU5BR0VSLAotICAgICAgICAgICAgICAgIG5ldyBYTUxTZWN1cml0eVByb3BlcnR5TWFuYWdlcigpKTsKLQotICAgICAgICAvLyBhZGQgbWVzc2FnZSBmb3JtYXR0ZXJzCi0gICAgICAgIGlmIChmRXJyb3JSZXBvcnRlci5nZXRNZXNzYWdlRm9ybWF0dGVyKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTikgPT0gbnVsbCkgewotICAgICAgICAgICAgWE1MTWVzc2FnZUZvcm1hdHRlciB4bWZ0ID0gbmV3IFhNTE1lc3NhZ2VGb3JtYXR0ZXIoKTsKLSAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnB1dE1lc3NhZ2VGb3JtYXR0ZXIoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLCB4bWZ0KTsKLSAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnB1dE1lc3NhZ2VGb3JtYXR0ZXIoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxOU19ET01BSU4sIHhtZnQpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gUkVWSVNJVDogdHJ5IHRvIGluY2x1ZGUgWE1MIFNjaGVtYSBmb3JtYXR0ZXIuCi0gICAgICAgIC8vICAgICAgICAgIFRoaXMgaXMgYSBoYWNrIHRvIGFsbG93IERURCBjb25maWd1cmF0aW9uIHRvIGJlIGJ1aWxkLgotICAgICAgICAvLwotICAgICAgICBpZiAoZkVycm9yUmVwb3J0ZXIuZ2V0TWVzc2FnZUZvcm1hdHRlcigiaHR0cDovL3d3dy53My5vcmcvVFIveG1sLXNjaGVtYS0xIikgPT0gbnVsbCkgewotICAgICAgICAgICAgTWVzc2FnZUZvcm1hdHRlciB4bWZ0ID0gbnVsbDsKLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICB4bWZ0ID0gKE1lc3NhZ2VGb3JtYXR0ZXIpKAotICAgICAgICAgICAgICAgICAgICBPYmplY3RGYWN0b3J5Lm5ld0luc3RhbmNlKCJjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMuWFNNZXNzYWdlRm9ybWF0dGVyIiwgdHJ1ZSkpOwotICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4Y2VwdGlvbil7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICBpZiAoeG1mdCAhPSAgbnVsbCkgewotICAgICAgICAgICAgICAgICBmRXJyb3JSZXBvcnRlci5wdXRNZXNzYWdlRm9ybWF0dGVyKCJodHRwOi8vd3d3LnczLm9yZy9UUi94bWwtc2NoZW1hLTEiLCB4bWZ0KTsKLSAgICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotCi0gICAgICAgIC8vIHNldCBsb2NhbGUKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIHNldExvY2FsZShMb2NhbGUuZ2V0RGVmYXVsdCgpKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoWE5JRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIC8vIGRvIG5vdGhpbmcKLSAgICAgICAgICAgIC8vIFJFVklTSVQ6IFdoYXQgaXMgdGhlIHJpZ2h0IHRoaW5nIHRvIGRvPyAtQWMKLSAgICAgICAgfQotCi0KLSAgICB9IC8vIDxpbml0PihTeW1ib2xUYWJsZSkKLQotCi0gICAgLy8KLSAgICAvLyBYTUxQYXJzZXJDb25maWd1cmF0aW9uIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogUGFyc2UgYW4gWE1MIGRvY3VtZW50LgotICAgICAqIDxwPgotICAgICAqIFRoZSBwYXJzZXIgY2FuIHVzZSB0aGlzIG1ldGhvZCB0byBpbnN0cnVjdCB0aGlzIGNvbmZpZ3VyYXRpb24KLSAgICAgKiB0byBiZWdpbiBwYXJzaW5nIGFuIFhNTCBkb2N1bWVudCBmcm9tIGFueSB2YWxpZCBpbnB1dCBzb3VyY2UKLSAgICAgKiAoYSBjaGFyYWN0ZXIgc3RyZWFtLCBhIGJ5dGUgc3RyZWFtLCBvciBhIFVSSSkuCi0gICAgICogPHA+Ci0gICAgICogUGFyc2VycyBtYXkgbm90IGludm9rZSB0aGlzIG1ldGhvZCB3aGlsZSBhIHBhcnNlIGlzIGluIHByb2dyZXNzLgotICAgICAqIE9uY2UgYSBwYXJzZSBpcyBjb21wbGV0ZSwgdGhlIHBhcnNlciBtYXkgdGhlbiBwYXJzZSBhbm90aGVyIFhNTAotICAgICAqIGRvY3VtZW50LgotICAgICAqIDxwPgotICAgICAqIFRoaXMgbWV0aG9kIGlzIHN5bmNocm9ub3VzOiBpdCB3aWxsIG5vdCByZXR1cm4gdW50aWwgcGFyc2luZwotICAgICAqIGhhcyBlbmRlZC4gIElmIGEgY2xpZW50IGFwcGxpY2F0aW9uIHdhbnRzIHRvIHRlcm1pbmF0ZQotICAgICAqIHBhcnNpbmcgZWFybHksIGl0IHNob3VsZCB0aHJvdyBhbiBleGNlcHRpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc291cmNlIFRoZSBpbnB1dCBzb3VyY2UgZm9yIHRoZSB0b3AtbGV2ZWwgb2YgdGhlCi0gICAgICogICAgICAgICAgICAgICBYTUwgZG9jdW1lbnQuCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIFhOSUV4Y2VwdGlvbiBBbnkgWE5JIGV4Y2VwdGlvbiwgcG9zc2libHkgd3JhcHBpbmcKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICAgKiBAZXhjZXB0aW9uIElPRXhjZXB0aW9uICBBbiBJTyBleGNlcHRpb24gZnJvbSB0aGUgcGFyc2VyLCBwb3NzaWJseQotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIGZyb20gYSBieXRlIHN0cmVhbSBvciBjaGFyYWN0ZXIgc3RyZWFtCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgc3VwcGxpZWQgYnkgdGhlIHBhcnNlci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBwYXJzZShYTUxJbnB1dFNvdXJjZSBpbnB1dFNvdXJjZSkKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiwgSU9FeGNlcHRpb257Ci0gICAgICAgIC8vIG5vLW9wCi0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0cyB0aGUgZG9jdW1lbnQgaGFuZGxlciBvbiB0aGUgbGFzdCBjb21wb25lbnQgaW4gdGhlIHBpcGVsaW5lCi0gICAgICogdG8gcmVjZWl2ZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgZG9jdW1lbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZG9jdW1lbnRIYW5kbGVyICAgVGhlIGRvY3VtZW50IGhhbmRsZXIuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RG9jdW1lbnRIYW5kbGVyKFhNTERvY3VtZW50SGFuZGxlciBkb2N1bWVudEhhbmRsZXIpIHsKLSAgICAgICAgZkRvY3VtZW50SGFuZGxlciA9IGRvY3VtZW50SGFuZGxlcjsKLSAgICB9IC8vIHNldERvY3VtZW50SGFuZGxlcihYTUxEb2N1bWVudEhhbmRsZXIpCi0KLSAgICAvKiogUmV0dXJucyB0aGUgcmVnaXN0ZXJlZCBkb2N1bWVudCBoYW5kbGVyLiAqLwotICAgIHB1YmxpYyBYTUxEb2N1bWVudEhhbmRsZXIgZ2V0RG9jdW1lbnRIYW5kbGVyKCkgewotICAgICAgICByZXR1cm4gZkRvY3VtZW50SGFuZGxlcjsKLSAgICB9IC8vIGdldERvY3VtZW50SGFuZGxlcigpOlhNTERvY3VtZW50SGFuZGxlcgotCi0gICAgLyoqCi0gICAgICogU2V0cyB0aGUgRFREIGhhbmRsZXIuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZHRkSGFuZGxlciBUaGUgRFREIGhhbmRsZXIuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RFRESGFuZGxlcihYTUxEVERIYW5kbGVyIGR0ZEhhbmRsZXIpIHsKLSAgICAgICAgLy9uby1vcAotICAgIH0gLy8gc2V0RFRESGFuZGxlcihYTUxEVERIYW5kbGVyKQotCi0gICAgLyoqIFJldHVybnMgdGhlIHJlZ2lzdGVyZWQgRFREIGhhbmRsZXIuICovCi0gICAgcHVibGljIFhNTERUREhhbmRsZXIgZ2V0RFRESGFuZGxlcigpIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfSAvLyBnZXREVERIYW5kbGVyKCk6WE1MRFRESGFuZGxlcgotCi0gICAgLyoqCi0gICAgICogU2V0cyB0aGUgRFREIGNvbnRlbnQgbW9kZWwgaGFuZGxlci4KLSAgICAgKgotICAgICAqIEBwYXJhbSBoYW5kbGVyIFRoZSBEVEQgY29udGVudCBtb2RlbCBoYW5kbGVyLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldERURENvbnRlbnRNb2RlbEhhbmRsZXIoWE1MRFREQ29udGVudE1vZGVsSGFuZGxlciBoYW5kbGVyKSB7Ci0gICAgICAgIC8vbm8tb3AKLQotICAgIH0gLy8gc2V0RFREQ29udGVudE1vZGVsSGFuZGxlcihYTUxEVERDb250ZW50TW9kZWxIYW5kbGVyKQotCi0gICAgLyoqIFJldHVybnMgdGhlIHJlZ2lzdGVyZWQgRFREIGNvbnRlbnQgbW9kZWwgaGFuZGxlci4gKi8KLSAgICBwdWJsaWMgWE1MRFREQ29udGVudE1vZGVsSGFuZGxlciBnZXREVERDb250ZW50TW9kZWxIYW5kbGVyKCkgewotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9IC8vIGdldERURENvbnRlbnRNb2RlbEhhbmRsZXIoKTpYTUxEVERDb250ZW50TW9kZWxIYW5kbGVyCi0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSByZXNvbHZlciB1c2VkIHRvIHJlc29sdmUgZXh0ZXJuYWwgZW50aXRpZXMuIFRoZSBFbnRpdHlSZXNvbHZlcgotICAgICAqIGludGVyZmFjZSBzdXBwb3J0cyByZXNvbHV0aW9uIG9mIHB1YmxpYyBhbmQgc3lzdGVtIGlkZW50aWZpZXJzLgotICAgICAqCi0gICAgICogQHBhcmFtIHJlc29sdmVyIFRoZSBuZXcgZW50aXR5IHJlc29sdmVyLiBQYXNzaW5nIGEgbnVsbCB2YWx1ZSB3aWxsCi0gICAgICogICAgICAgICAgICAgICAgIHVuaW5zdGFsbCB0aGUgY3VycmVudGx5IGluc3RhbGxlZCByZXNvbHZlci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRFbnRpdHlSZXNvbHZlcihYTUxFbnRpdHlSZXNvbHZlciByZXNvbHZlcikgewotICAgICAgICBpZiAocmVzb2x2ZXIgIT1udWxsKSB7Ci0gICAgICAgICAgICBmUHJvcGVydGllcy5wdXQoRU5USVRZX1JFU09MVkVSLCByZXNvbHZlcik7Ci0gICAgICAgIH0KLSAgICB9IC8vIHNldEVudGl0eVJlc29sdmVyKFhNTEVudGl0eVJlc29sdmVyKQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSBjdXJyZW50IGVudGl0eSByZXNvbHZlci4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIGN1cnJlbnQgZW50aXR5IHJlc29sdmVyLCBvciBudWxsIGlmIG5vbmUKLSAgICAgKiAgICAgICAgIGhhcyBiZWVuIHJlZ2lzdGVyZWQuCi0gICAgICogQHNlZSAjc2V0RW50aXR5UmVzb2x2ZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgWE1MRW50aXR5UmVzb2x2ZXIgZ2V0RW50aXR5UmVzb2x2ZXIoKSB7Ci0gICAgICAgIHJldHVybiAoWE1MRW50aXR5UmVzb2x2ZXIpZlByb3BlcnRpZXMuZ2V0KEVOVElUWV9SRVNPTFZFUik7Ci0gICAgfSAvLyBnZXRFbnRpdHlSZXNvbHZlcigpOlhNTEVudGl0eVJlc29sdmVyCi0KLSAgICAvKioKLSAgICAgKiBBbGxvdyBhbiBhcHBsaWNhdGlvbiB0byByZWdpc3RlciBhbiBlcnJvciBldmVudCBoYW5kbGVyLgotICAgICAqCi0gICAgICogPHA+SWYgdGhlIGFwcGxpY2F0aW9uIGRvZXMgbm90IHJlZ2lzdGVyIGFuIGVycm9yIGhhbmRsZXIsIGFsbAotICAgICAqIGVycm9yIGV2ZW50cyByZXBvcnRlZCBieSB0aGUgU0FYIHBhcnNlciB3aWxsIGJlIHNpbGVudGx5Ci0gICAgICogaWdub3JlZDsgaG93ZXZlciwgbm9ybWFsIHByb2Nlc3NpbmcgbWF5IG5vdCBjb250aW51ZS4gIEl0IGlzCi0gICAgICogaGlnaGx5IHJlY29tbWVuZGVkIHRoYXQgYWxsIFNBWCBhcHBsaWNhdGlvbnMgaW1wbGVtZW50IGFuCi0gICAgICogZXJyb3IgaGFuZGxlciB0byBhdm9pZCB1bmV4cGVjdGVkIGJ1Z3MuPC9wPgotICAgICAqCi0gICAgICogPHA+QXBwbGljYXRpb25zIG1heSByZWdpc3RlciBhIG5ldyBvciBkaWZmZXJlbnQgaGFuZGxlciBpbiB0aGUKLSAgICAgKiBtaWRkbGUgb2YgYSBwYXJzZSwgYW5kIHRoZSBTQVggcGFyc2VyIG11c3QgYmVnaW4gdXNpbmcgdGhlIG5ldwotICAgICAqIGhhbmRsZXIgaW1tZWRpYXRlbHkuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGVycm9ySGFuZGxlciBUaGUgZXJyb3IgaGFuZGxlci4KLSAgICAgKiBAZXhjZXB0aW9uIGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbiBJZiB0aGUgaGFuZGxlcgotICAgICAqICAgICAgICAgICAgYXJndW1lbnQgaXMgbnVsbC4KLSAgICAgKiBAc2VlICNnZXRFcnJvckhhbmRsZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRFcnJvckhhbmRsZXIoWE1MRXJyb3JIYW5kbGVyIGVycm9ySGFuZGxlcikgewotICAgICAgICBpZiAoZXJyb3JIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZQcm9wZXJ0aWVzLnB1dChFUlJPUl9IQU5ETEVSLCBlcnJvckhhbmRsZXIpOwotICAgICAgICB9Ci0gICAgfSAvLyBzZXRFcnJvckhhbmRsZXIoWE1MRXJyb3JIYW5kbGVyKQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSBjdXJyZW50IGVycm9yIGhhbmRsZXIuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBjdXJyZW50IGVycm9yIGhhbmRsZXIsIG9yIG51bGwgaWYgbm9uZQotICAgICAqICAgICAgICAgaGFzIGJlZW4gcmVnaXN0ZXJlZC4KLSAgICAgKiBAc2VlICNzZXRFcnJvckhhbmRsZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgWE1MRXJyb3JIYW5kbGVyIGdldEVycm9ySGFuZGxlcigpIHsKLSAgICAgICAgcmV0dXJuIChYTUxFcnJvckhhbmRsZXIpZlByb3BlcnRpZXMuZ2V0KEVSUk9SX0hBTkRMRVIpOwotICAgIH0gLy8gZ2V0RXJyb3JIYW5kbGVyKCk6WE1MRXJyb3JIYW5kbGVyCi0KLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIHN0YXRlIG9mIGEgZmVhdHVyZS4KLSAgICAgKgotICAgICAqIFNldCB0aGUgc3RhdGUgb2YgYW55IGZlYXR1cmUgaW4gYSBTQVgyIHBhcnNlci4gIFRoZSBwYXJzZXIKLSAgICAgKiBtaWdodCBub3QgcmVjb2duaXplIHRoZSBmZWF0dXJlLCBhbmQgaWYgaXQgZG9lcyByZWNvZ25pemUKLSAgICAgKiBpdCwgaXQgbWlnaHQgbm90IGJlIGFibGUgdG8gZnVsZmlsbCB0aGUgcmVxdWVzdC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBmZWF0dXJlSWQgVGhlIHVuaXF1ZSBpZGVudGlmaWVyIChVUkkpIG9mIHRoZSBmZWF0dXJlLgotICAgICAqIEBwYXJhbSBzdGF0ZSBUaGUgcmVxdWVzdGVkIHN0YXRlIG9mIHRoZSBmZWF0dXJlICh0cnVlIG9yIGZhbHNlKS4KLSAgICAgKgotICAgICAqIEBleGNlcHRpb24gY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gSWYgdGhlCi0gICAgICogICAgICAgICAgICByZXF1ZXN0ZWQgZmVhdHVyZSBpcyBub3Qga25vd24uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RmVhdHVyZShTdHJpbmcgZmVhdHVyZUlkLCBib29sZWFuIHN0YXRlKQotICAgICAgICB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy8gc2F2ZSBzdGF0ZSBpZiBub29uZSAib2JqZWN0cyIKLSAgICAgICAgc3VwZXIuc2V0RmVhdHVyZShmZWF0dXJlSWQsIHN0YXRlKTsKLQotICAgIH0gLy8gc2V0RmVhdHVyZShTdHJpbmcsYm9vbGVhbikKLQotICAgIC8qKgotICAgICAqIHNldFByb3BlcnR5Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gcHJvcGVydHlJZAotICAgICAqIEBwYXJhbSB2YWx1ZQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFByb3BlcnR5KFN0cmluZyBwcm9wZXJ0eUlkLCBPYmplY3QgdmFsdWUpCi0gICAgICAgIHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIHsKLQotICAgICAgICAvLyBzdG9yZSB2YWx1ZSBpZiBub29uZSAib2JqZWN0cyIKLSAgICAgICAgc3VwZXIuc2V0UHJvcGVydHkocHJvcGVydHlJZCwgdmFsdWUpOwotCi0gICAgfSAvLyBzZXRQcm9wZXJ0eShTdHJpbmcsT2JqZWN0KQotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSBsb2NhbGUgdG8gdXNlIGZvciBtZXNzYWdlcy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBsb2NhbGUgVGhlIGxvY2FsZSBvYmplY3QgdG8gdXNlIGZvciBsb2NhbGl6YXRpb24gb2YgbWVzc2FnZXMuCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIFhOSUV4Y2VwdGlvbiBUaHJvd24gaWYgdGhlIHBhcnNlciBkb2VzIG5vdCBzdXBwb3J0IHRoZQotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIHNwZWNpZmllZCBsb2NhbGUuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0TG9jYWxlKExvY2FsZSBsb2NhbGUpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBmTG9jYWxlID0gbG9jYWxlOwotICAgICAgICBmRXJyb3JSZXBvcnRlci5zZXRMb2NhbGUobG9jYWxlKTsKLQotICAgIH0gLy8gc2V0TG9jYWxlKExvY2FsZSkKLQotICAgIC8qKiBSZXR1cm5zIHRoZSBsb2NhbGUuICovCi0gICAgcHVibGljIExvY2FsZSBnZXRMb2NhbGUoKSB7Ci0gICAgICAgIHJldHVybiBmTG9jYWxlOwotICAgIH0gLy8gZ2V0TG9jYWxlKCk6TG9jYWxlCi0KLSAgICAvKioKLSAgICAgKiBET00gTGV2ZWwgMyBXRCAtIEV4cGVyaW1lbnRhbC4KLSAgICAgKiBzZXRQYXJhbWV0ZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRQYXJhbWV0ZXIoU3RyaW5nIG5hbWUsIE9iamVjdCB2YWx1ZSkgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0gICAgICAgIGJvb2xlYW4gZm91bmQgPSB0cnVlOwotCi0gICAgICAgIC8vIFJFVklTSVQ6IFJlY29nbml6ZXMgRE9NIEwzIGRlZmF1bHQgZmVhdHVyZXMgb25seS4KLSAgICAgICAgLy8gICAgICAgICAgRG9lcyBub3QgeWV0IHJlY29nbml6ZSBYZXJjZXMgZmVhdHVyZXMuCi0gICAgICAgICAgICAgICAgaWYodmFsdWUgaW5zdGFuY2VvZiBCb29sZWFuKXsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gc3RhdGUgPSAoKEJvb2xlYW4pdmFsdWUpLmJvb2xlYW5WYWx1ZSgpOwotCi0gICAgICAgICAgICBpZiAobmFtZS5lcXVhbHNJZ25vcmVDYXNlKENvbnN0YW50cy5ET01fQ09NTUVOVFMpKSB7Ci0gICAgICAgICAgICAgICAgZmVhdHVyZXMgPSAoc2hvcnQpIChzdGF0ZSA/IGZlYXR1cmVzIHwgQ09NTUVOVFMgOiBmZWF0dXJlcyAmIH5DT01NRU5UUyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFsc0lnbm9yZUNhc2UoQ29uc3RhbnRzLkRPTV9EQVRBVFlQRV9OT1JNQUxJWkFUSU9OKSkgewotICAgICAgICAgICAgICAgIHNldEZlYXR1cmUoTk9STUFMSVpFX0RBVEEsIHN0YXRlKTsKLSAgICAgICAgICAgICAgICBmZWF0dXJlcyA9Ci0gICAgICAgICAgICAgICAgICAgIChzaG9ydCkgKHN0YXRlID8gZmVhdHVyZXMgfCBEVE5PUk1BTElaQVRJT04gOiBmZWF0dXJlcyAmIH5EVE5PUk1BTElaQVRJT04pOwotICAgICAgICAgICAgICAgIGlmIChzdGF0ZSkgewotICAgICAgICAgICAgICAgICAgICBmZWF0dXJlcyA9IChzaG9ydCkgKGZlYXR1cmVzIHwgVkFMSURBVEUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzSWdub3JlQ2FzZShDb25zdGFudHMuRE9NX05BTUVTUEFDRVMpKSB7Ci0gICAgICAgICAgICAgICAgZmVhdHVyZXMgPSAoc2hvcnQpIChzdGF0ZSA/IGZlYXR1cmVzIHwgTkFNRVNQQUNFUyA6IGZlYXR1cmVzICYgfk5BTUVTUEFDRVMpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAobmFtZS5lcXVhbHNJZ25vcmVDYXNlKENvbnN0YW50cy5ET01fQ0RBVEFfU0VDVElPTlMpKSB7Ci0gICAgICAgICAgICAgICAgZmVhdHVyZXMgPSAoc2hvcnQpIChzdGF0ZSA/IGZlYXR1cmVzIHwgQ0RBVEEgOiBmZWF0dXJlcyAmIH5DREFUQSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFsc0lnbm9yZUNhc2UoQ29uc3RhbnRzLkRPTV9FTlRJVElFUykpIHsKLSAgICAgICAgICAgICAgICBmZWF0dXJlcyA9IChzaG9ydCkgKHN0YXRlID8gZmVhdHVyZXMgfCBFTlRJVElFUyA6IGZlYXR1cmVzICYgfkVOVElUSUVTKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzSWdub3JlQ2FzZShDb25zdGFudHMuRE9NX1NQTElUX0NEQVRBKSkgewotICAgICAgICAgICAgICAgIGZlYXR1cmVzID0gKHNob3J0KSAoc3RhdGUgPyBmZWF0dXJlcyB8IFNQTElUQ0RBVEEgOiBmZWF0dXJlcyAmIH5TUExJVENEQVRBKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzSWdub3JlQ2FzZShDb25zdGFudHMuRE9NX1ZBTElEQVRFKSkgewotICAgICAgICAgICAgICAgIGZlYXR1cmVzID0gKHNob3J0KSAoc3RhdGUgPyBmZWF0dXJlcyB8IFZBTElEQVRFIDogZmVhdHVyZXMgJiB+VkFMSURBVEUpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAobmFtZS5lcXVhbHNJZ25vcmVDYXNlKENvbnN0YW50cy5ET01fV0VMTEZPUk1FRCkpIHsKLSAgICAgICAgICAgICAgICBmZWF0dXJlcyA9IChzaG9ydCkgKHN0YXRlID8gZmVhdHVyZXMgfCBXRUxMRk9STUVEIDogZmVhdHVyZXMgJiB+V0VMTEZPUk1FRCApOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAobmFtZS5lcXVhbHNJZ25vcmVDYXNlKENvbnN0YW50cy5ET01fTkFNRVNQQUNFX0RFQ0xBUkFUSU9OUykpIHsKLSAgICAgICAgICAgICAgICBmZWF0dXJlcyA9IChzaG9ydCkgKHN0YXRlID8gZmVhdHVyZXMgfCBOU0RFQ0wgOiBmZWF0dXJlcyAmIH5OU0RFQ0wpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAobmFtZS5lcXVhbHNJZ25vcmVDYXNlKENvbnN0YW50cy5ET01fSU5GT1NFVCkpIHsKLSAgICAgICAgICAgICAgICAvLyBTZXR0aW5nIHRvIGZhbHNlIGhhcyBubyBlZmZlY3QuCi0gICAgICAgICAgICAgICAgaWYgKHN0YXRlKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZlYXR1cmVzID0gKHNob3J0KSAoZmVhdHVyZXMgfCBJTkZPU0VUX1RSVUVfUEFSQU1TKTsKLSAgICAgICAgICAgICAgICAgICAgZmVhdHVyZXMgPSAoc2hvcnQpIChmZWF0dXJlcyAmIH5JTkZPU0VUX0ZBTFNFX1BBUkFNUyk7Ci0gICAgICAgICAgICAgICAgICAgIHNldEZlYXR1cmUoTk9STUFMSVpFX0RBVEEsIGZhbHNlKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFsc0lnbm9yZUNhc2UoQ29uc3RhbnRzLkRPTV9OT1JNQUxJWkVfQ0hBUkFDVEVSUykKLSAgICAgICAgICAgICAgICAgICAgfHwgbmFtZS5lcXVhbHNJZ25vcmVDYXNlKENvbnN0YW50cy5ET01fQ0FOT05JQ0FMX0ZPUk0pCi0gICAgICAgICAgICAgICAgICAgIHx8IG5hbWUuZXF1YWxzSWdub3JlQ2FzZShDb25zdGFudHMuRE9NX1ZBTElEQVRFX0lGX1NDSEVNQSkKLSAgICAgICAgICAgICAgICAgICAgfHwgbmFtZS5lcXVhbHNJZ25vcmVDYXNlKENvbnN0YW50cy5ET01fQ0hFQ0tfQ0hBUl9OT1JNQUxJWkFUSU9OKQotICAgICAgICAgICAgICAgICAgICApIHsKLSAgICAgICAgICAgICAgICBpZiAoc3RhdGUpIHsgLy8gdHJ1ZSBpcyBub3Qgc3VwcG9ydGVkCi0gICAgICAgICAgICAgICAgICAgIFN0cmluZyBtc2cgPQotICAgICAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRkVBVFVSRV9OT1RfU1VQUE9SVEVEIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBuYW1lIH0pOwotICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUiwgbXNnKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICggbmFtZS5lcXVhbHNJZ25vcmVDYXNlKENvbnN0YW50cy5ET01fRUxFTUVOVF9DT05URU5UX1dISVRFU1BBQ0UpKSB7Ci0gICAgICAgICAgICAgICAgaWYgKCFzdGF0ZSkgeyAvLyBmYWxzZSBpcyBub3Qgc3VwcG9ydGVkCi0gICAgICAgICAgICAgICAgICAgIFN0cmluZyBtc2cgPQotICAgICAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRkVBVFVSRV9OT1RfU1VQUE9SVEVEIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBuYW1lIH0pOwotICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSLCBtc2cpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzSWdub3JlQ2FzZShTRU5EX1BTVkkpICl7Ci0gICAgICAgICAgICAgICAgLy8gUkVWSVNJVDogdHVybmluZyBhdWdtZW50YXRpb24gb2YgUFNWSSBpcyBub3Qgc3VwcG9ydCwKLSAgICAgICAgICAgICAgICAvLyBiZWNhdXNlIGluIHRoaXMgY2FzZSB3ZSB3b24ndCBiZSBhYmxlIHRvIHJldHJpZXZlIGVsZW1lbnQKLSAgICAgICAgICAgICAgICAvLyBkZWZhdWx0IHZhbHVlLgotICAgICAgICAgICAgICAgIGlmICghc3RhdGUpIHsgLy8gZmFsc2UgaXMgbm90IHN1cHBvcnRlZAotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbXNnID0KLSAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZSgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIkZFQVRVUkVfTk9UX1NVUFBPUlRFRCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgbmFtZSB9KTsKLSAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIsIG1zZyk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAobmFtZS5lcXVhbHNJZ25vcmVDYXNlKENvbnN0YW50cy5ET01fUFNWSSkpewotICAgICAgICAgICAgICAgICAgZmVhdHVyZXMgPSAoc2hvcnQpIChzdGF0ZSA/IGZlYXR1cmVzIHwgUFNWSSA6IGZlYXR1cmVzICYgflBTVkkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgZm91bmQgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICAvKgotICAgICAgICAgICAgICAgIFN0cmluZyBtc2cgPQotICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoCi0gICAgICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAiRkVBVFVSRV9OT1RfRk9VTkQiLAotICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgbmFtZSB9KTsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfRk9VTkRfRVJSLCBtc2cpOwotICAgICAgICAgICAgICAgICovCi0gICAgICAgICAgICB9Ci0KLSAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgaWYgKCFmb3VuZCB8fCAhKHZhbHVlIGluc3RhbmNlb2YgQm9vbGVhbikpICB7IC8vIHNldCBwcm9wZXJ0aWVzCi0gICAgICAgICAgICAgICAgICAgICAgICBmb3VuZCA9IHRydWU7Ci0KLSAgICAgICAgICAgIGlmIChuYW1lLmVxdWFsc0lnbm9yZUNhc2UoQ29uc3RhbnRzLkRPTV9FUlJPUl9IQU5ETEVSKSkgewotICAgICAgICAgICAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIERPTUVycm9ySGFuZGxlciB8fCB2YWx1ZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZFcnJvckhhbmRsZXJXcmFwcGVyLnNldEVycm9ySGFuZGxlcigoRE9NRXJyb3JIYW5kbGVyKXZhbHVlKTsKLSAgICAgICAgICAgICAgICAgICAgc2V0RXJyb3JIYW5kbGVyKGZFcnJvckhhbmRsZXJXcmFwcGVyKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gUkVWSVNJVDogdHlwZSBtaXNtYXRjaAotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbXNnID0KLSAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZSgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIlRZUEVfTUlTTUFUQ0hfRVJSIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBuYW1lIH0pOwotICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5UWVBFX01JU01BVENIX0VSUiwgbXNnKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFsc0lnbm9yZUNhc2UoQ29uc3RhbnRzLkRPTV9SRVNPVVJDRV9SRVNPTFZFUikpIHsKLSAgICAgICAgICAgICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBMU1Jlc291cmNlUmVzb2x2ZXIgfHwgdmFsdWUgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICAgICAgc2V0RW50aXR5UmVzb2x2ZXIobmV3IERPTUVudGl0eVJlc29sdmVyV3JhcHBlcigoTFNSZXNvdXJjZVJlc29sdmVyKSB2YWx1ZSkpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGNhdGNoIChYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIGUpIHt9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAvLyBSRVZJU0lUOiB0eXBlIG1pc21hdGNoCi0gICAgICAgICAgICAgICAgICAgIFN0cmluZyBtc2cgPQotICAgICAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVFlQRV9NSVNNQVRDSF9FUlIiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7IG5hbWUgfSk7Ci0gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLlRZUEVfTUlTTUFUQ0hfRVJSLCBtc2cpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAobmFtZS5lcXVhbHNJZ25vcmVDYXNlKENvbnN0YW50cy5ET01fU0NIRU1BX0xPQ0FUSU9OKSkgewotICAgICAgICAgICAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIFN0cmluZyB8fCB2YWx1ZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBtYXAgRE9NIHNjaGVtYS1sb2NhdGlvbiB0byBKQVhQIHNjaGVtYVNvdXJjZSBwcm9wZXJ0eQotICAgICAgICAgICAgICAgICAgICAgICAgc2V0UHJvcGVydHkoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29uc3RhbnRzLkpBWFBfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLlNDSEVNQV9TT1VSQ0UsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGNhdGNoIChYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIGUpIHt9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAvLyBSRVZJU0lUOiB0eXBlIG1pc21hdGNoCi0gICAgICAgICAgICAgICAgICAgIFN0cmluZyBtc2cgPQotICAgICAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVFlQRV9NSVNNQVRDSF9FUlIiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7IG5hbWUgfSk7Ci0gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLlRZUEVfTUlTTUFUQ0hfRVJSLCBtc2cpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAobmFtZS5lcXVhbHNJZ25vcmVDYXNlKENvbnN0YW50cy5ET01fU0NIRU1BX1RZUEUpKSB7Ci0gICAgICAgICAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgU3RyaW5nIHx8IHZhbHVlID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0UHJvcGVydHkoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbnN0YW50cy5KQVhQX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5TQ0hFTUFfTEFOR1VBR0UsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAodmFsdWUuZXF1YWxzKENvbnN0YW50cy5OU19YTUxTQ0hFTUEpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUkVWSVNJVDogd2hlbiBhZGQgc3VwcG9ydCB0byBEVEQgdmFsaWRhdGlvbgotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldFByb3BlcnR5KAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb25zdGFudHMuSkFYUF9QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuU0NIRU1BX0xBTkdVQUdFLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb25zdGFudHMuTlNfWE1MU0NIRU1BKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHZhbHVlLmVxdWFscyhDb25zdGFudHMuTlNfRFREKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEFkZGVkIHN1cHBvcnQgZm9yIHJldmFsaWRhdGlvbiBhZ2FpbnN0IERURHMKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0UHJvcGVydHkoQ29uc3RhbnRzLkpBWFBfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLlNDSEVNQV9MQU5HVUFHRSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbnN0YW50cy5OU19EVEQpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGNhdGNoIChYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIGUpIHt9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbXNnID0KLSAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZSgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIlRZUEVfTUlTTUFUQ0hfRVJSIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBuYW1lIH0pOwotICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5UWVBFX01JU01BVENIX0VSUiwgbXNnKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzSWdub3JlQ2FzZShTWU1CT0xfVEFCTEUpKXsKLSAgICAgICAgICAgICAgICAvLyBYZXJjZXMgU3ltYm9sIFRhYmxlCi0gICAgICAgICAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgU3ltYm9sVGFibGUpewotICAgICAgICAgICAgICAgICAgICBzZXRQcm9wZXJ0eShTWU1CT0xfVEFCTEUsIHZhbHVlKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIFJFVklTSVQ6IHR5cGUgbWlzbWF0Y2gKLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG1zZyA9Ci0gICAgICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICJUWVBFX01JU01BVENIX0VSUiIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgbmFtZSB9KTsKLSAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uVFlQRV9NSVNNQVRDSF9FUlIsIG1zZyk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAobmFtZS5lcXVhbHNJZ25vcmVDYXNlIChHUkFNTUFSX1BPT0wpKXsKLSAgICAgICAgICAgICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBYTUxHcmFtbWFyUG9vbCl7Ci0gICAgICAgICAgICAgICAgICAgIHNldFByb3BlcnR5KEdSQU1NQVJfUE9PTCwgdmFsdWUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gUkVWSVNJVDogdHlwZSBtaXNtYXRjaAotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbXNnID0KLSAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZSgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIlRZUEVfTUlTTUFUQ0hfRVJSIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBuYW1lIH0pOwotICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5UWVBFX01JU01BVENIX0VSUiwgbXNnKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIC8vIFJFVklTSVQ6IGNoZWNrIGlmIHRoaXMgaXMgYSBib29sZWFuIHBhcmFtZXRlciAtLSB0eXBlIG1pc21hdGNoIHNob3VsZCBiZSB0aHJvd24uCi0gICAgICAgICAgICAgICAgLy9wYXJhbWV0ZXIgaXMgbm90IHJlY29nbml6ZWQKLSAgICAgICAgICAgICAgICBTdHJpbmcgbXNnID0KLSAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKAotICAgICAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgIkZFQVRVUkVfTk9UX0ZPVU5EIiwKLSAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7IG5hbWUgfSk7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX0ZPVU5EX0VSUiwgbXNnKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBET00gTGV2ZWwgMyBXRCAtIEV4cGVyaW1lbnRhbC4KLSAgICAgKiBnZXRQYXJhbWV0ZXIKLSAgICAgKi8KLSAgICAgICAgcHVibGljIE9iamVjdCBnZXRQYXJhbWV0ZXIoU3RyaW5nIG5hbWUpIHRocm93cyBET01FeGNlcHRpb24gewotCi0gICAgICAgICAgICAgICAgLy8gUkVWSVNJVDogUmVjb2duaXplcyBET00gTDMgZGVmYXVsdCBmZWF0dXJlcyBvbmx5LgotICAgICAgICAgICAgICAgIC8vICAgICAgICAgIERvZXMgbm90IHlldCByZWNvZ25pemUgWGVyY2VzIGZlYXR1cmVzLgotCi0gICAgICAgICAgICAgICAgaWYgKG5hbWUuZXF1YWxzSWdub3JlQ2FzZShDb25zdGFudHMuRE9NX0NPTU1FTlRTKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICgoZmVhdHVyZXMgJiBDT01NRU5UUykgIT0gMCkgPyBCb29sZWFuLlRSVUUgOiBCb29sZWFuLkZBTFNFOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFsc0lnbm9yZUNhc2UoQ29uc3RhbnRzLkRPTV9OQU1FU1BBQ0VTKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChmZWF0dXJlcyAmIE5BTUVTUEFDRVMpICE9IDAgPyBCb29sZWFuLlRSVUUgOiBCb29sZWFuLkZBTFNFOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFsc0lnbm9yZUNhc2UoQ29uc3RhbnRzLkRPTV9EQVRBVFlQRV9OT1JNQUxJWkFUSU9OKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gUkVWSVNJVDogZGF0YXR5cGUtbm9ybWFsaXphdGlvbiBvbmx5IHRha2VzIGVmZmVjdCBpZiB2YWxpZGF0aW9uIGlzIG9uCi0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKGZlYXR1cmVzICYgRFROT1JNQUxJWkFUSU9OKSAhPSAwID8gQm9vbGVhbi5UUlVFIDogQm9vbGVhbi5GQUxTRTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSBpZiAobmFtZS5lcXVhbHNJZ25vcmVDYXNlKENvbnN0YW50cy5ET01fQ0RBVEFfU0VDVElPTlMpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKGZlYXR1cmVzICYgQ0RBVEEpICE9IDAgPyBCb29sZWFuLlRSVUUgOiBCb29sZWFuLkZBTFNFOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFsc0lnbm9yZUNhc2UoQ29uc3RhbnRzLkRPTV9FTlRJVElFUykpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoZmVhdHVyZXMgJiBFTlRJVElFUykgIT0gMCA/IEJvb2xlYW4uVFJVRSA6IEJvb2xlYW4uRkFMU0U7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzSWdub3JlQ2FzZShDb25zdGFudHMuRE9NX1NQTElUX0NEQVRBKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChmZWF0dXJlcyAmIFNQTElUQ0RBVEEpICE9IDAgPyBCb29sZWFuLlRSVUUgOiBCb29sZWFuLkZBTFNFOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFsc0lnbm9yZUNhc2UoQ29uc3RhbnRzLkRPTV9WQUxJREFURSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoZmVhdHVyZXMgJiBWQUxJREFURSkgIT0gMCA/IEJvb2xlYW4uVFJVRSA6IEJvb2xlYW4uRkFMU0U7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzSWdub3JlQ2FzZShDb25zdGFudHMuRE9NX1dFTExGT1JNRUQpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKGZlYXR1cmVzICYgV0VMTEZPUk1FRCkgIT0gMCA/IEJvb2xlYW4uVFJVRSA6IEJvb2xlYW4uRkFMU0U7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzSWdub3JlQ2FzZShDb25zdGFudHMuRE9NX05BTUVTUEFDRV9ERUNMQVJBVElPTlMpKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiAoZmVhdHVyZXMgJiBOU0RFQ0wpICE9IDAgPyBCb29sZWFuLlRSVUUgOiBCb29sZWFuLkZBTFNFOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFsc0lnbm9yZUNhc2UoQ29uc3RhbnRzLkRPTV9JTkZPU0VUKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChmZWF0dXJlcyAmIElORk9TRVRfTUFTSykgPT0gSU5GT1NFVF9UUlVFX1BBUkFNUyA/IEJvb2xlYW4uVFJVRSA6IEJvb2xlYW4uRkFMU0U7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzSWdub3JlQ2FzZShDb25zdGFudHMuRE9NX05PUk1BTElaRV9DSEFSQUNURVJTKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCBuYW1lLmVxdWFsc0lnbm9yZUNhc2UoQ29uc3RhbnRzLkRPTV9DQU5PTklDQUxfRk9STSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgbmFtZS5lcXVhbHNJZ25vcmVDYXNlKENvbnN0YW50cy5ET01fVkFMSURBVEVfSUZfU0NIRU1BKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCBuYW1lLmVxdWFsc0lnbm9yZUNhc2UoQ29uc3RhbnRzLkRPTV9DSEVDS19DSEFSX05PUk1BTElaQVRJT04pCi0gICAgICAgICAgICAgICAgKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gQm9vbGVhbi5GQUxTRTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzSWdub3JlQ2FzZShTRU5EX1BTVkkpKSB7Ci0gICAgICAgICAgICByZXR1cm4gQm9vbGVhbi5UUlVFOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzSWdub3JlQ2FzZShDb25zdGFudHMuRE9NX1BTVkkpKSB7Ci0gICAgICAgICAgICByZXR1cm4gKGZlYXR1cmVzICYgUFNWSSkgIT0gMCA/IEJvb2xlYW4uVFJVRSA6IEJvb2xlYW4uRkFMU0U7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAobmFtZS5lcXVhbHNJZ25vcmVDYXNlKENvbnN0YW50cy5ET01fRUxFTUVOVF9DT05URU5UX1dISVRFU1BBQ0UpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gQm9vbGVhbi5UUlVFOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFsc0lnbm9yZUNhc2UoQ29uc3RhbnRzLkRPTV9FUlJPUl9IQU5ETEVSKSkgewotICAgICAgICAgICAgcmV0dXJuIGZFcnJvckhhbmRsZXJXcmFwcGVyLmdldEVycm9ySGFuZGxlcigpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFsc0lnbm9yZUNhc2UoQ29uc3RhbnRzLkRPTV9SRVNPVVJDRV9SRVNPTFZFUikpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIFhNTEVudGl0eVJlc29sdmVyIGVudGl0eVJlc29sdmVyID0gZ2V0RW50aXR5UmVzb2x2ZXIoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlbnRpdHlSZXNvbHZlciAhPSBudWxsICYmIGVudGl0eVJlc29sdmVyIGluc3RhbmNlb2YgRE9NRW50aXR5UmVzb2x2ZXJXcmFwcGVyKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoKERPTUVudGl0eVJlc29sdmVyV3JhcHBlcikgZW50aXR5UmVzb2x2ZXIpLmdldEVudGl0eVJlc29sdmVyKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSBpZiAobmFtZS5lcXVhbHNJZ25vcmVDYXNlKENvbnN0YW50cy5ET01fU0NIRU1BX1RZUEUpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZ2V0UHJvcGVydHkoQ29uc3RhbnRzLkpBWFBfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLlNDSEVNQV9MQU5HVUFHRSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzSWdub3JlQ2FzZShDb25zdGFudHMuRE9NX1NDSEVNQV9MT0NBVElPTikpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBnZXRQcm9wZXJ0eShDb25zdGFudHMuSkFYUF9QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuU0NIRU1BX1NPVVJDRSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFsc0lnbm9yZUNhc2UoU1lNQk9MX1RBQkxFKSl7Ci0gICAgICAgICAgICByZXR1cm4gZ2V0UHJvcGVydHkoU1lNQk9MX1RBQkxFKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFsc0lnbm9yZUNhc2UoR1JBTU1BUl9QT09MKSl7Ci0gICAgICAgICAgICByZXR1cm4gZ2V0UHJvcGVydHkoR1JBTU1BUl9QT09MKTsKLSAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG1zZyA9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZSgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkZFQVRVUkVfTk9UX0ZPVU5EIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBuYW1lIH0pOwotICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX0ZPVU5EX0VSUiwgbXNnKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgfQotCi0gICAgLyoqCi0gICAgICogRE9NIExldmVsIDMgV0QgLSBFeHBlcmltZW50YWwuCi0gICAgICogQ2hlY2sgaWYgc2V0dGluZyBhIHBhcmFtZXRlciB0byBhIHNwZWNpZmljIHZhbHVlIGlzIHN1cHBvcnRlZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBwYXJhbWV0ZXIgdG8gY2hlY2suCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdmFsdWUgQW4gb2JqZWN0LiBpZiBudWxsLCB0aGUgcmV0dXJuZWQgdmFsdWUgaXMgdHJ1ZS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgcGFyYW1ldGVyIGNvdWxkIGJlIHN1Y2Nlc3NmdWxseSBzZXQgdG8gdGhlCi0gICAgICogc3BlY2lmaWVkIHZhbHVlLCBvciBmYWxzZSBpZiB0aGUgcGFyYW1ldGVyIGlzIG5vdCByZWNvZ25pemVkIG9yCi0gICAgICogdGhlIHJlcXVlc3RlZCB2YWx1ZSBpcyBub3Qgc3VwcG9ydGVkLiBUaGlzIGRvZXMgbm90IGNoYW5nZSB0aGUKLSAgICAgKiBjdXJyZW50IHZhbHVlIG9mIHRoZSBwYXJhbWV0ZXIgaXRzZWxmLgotICAgICAqLwotICAgICAgICBwdWJsaWMgYm9vbGVhbiBjYW5TZXRQYXJhbWV0ZXIoU3RyaW5nIG5hbWUsIE9iamVjdCB2YWx1ZSkgewotCi0gICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKXsKLSAgICAgICAgICAgIC8vaWYgbnVsbCwgdGhlIHJldHVybmVkIHZhbHVlIGlzIHRydWUuCi0gICAgICAgICAgICAvL1JFVklTSVQ6IEkgZG9udCBsaWtlIHRoaXMgLS0tIGV2ZW4gZm9yIHVucmVjb2duaXplZCBwYXJhbWV0ZXIgaXQgd291bGQKLSAgICAgICAgICAgIC8vcmV0dXJuICd0cnVlJy4gSSB0aGluayBpdCBzaG91bGQgcmV0dXJuIGZhbHNlIGluIHRoYXQgY2FzZS4KLSAgICAgICAgICAgIC8vIEFwcGxpY2F0aW9uIHdpbGwgYmUgc3VycHJpc2VkIHRvIGZpbmQgdGhhdCBzZXRQYXJhbWV0ZXIgdGhyb3dzIG5vdAotICAgICAgICAgICAgLy9yZWNvZ25pemVkIGV4Y2VwdGlvbiB3aGVuIGNhblNldFBhcmFtZXRlciByZXR1cm5zICd0cnVlJyBUaGVuIHdoYXQgaXMgdGhlIHVzZQotICAgICAgICAgICAgLy9vZiBoYXZpbmcgY2FuU2V0UGFyYW1ldGVyID8/PyAtIG5iLgotICAgICAgICAgICAgcmV0dXJuIHRydWUgOwotICAgICAgICB9Ci0gICAgICAgIGlmKCB2YWx1ZSBpbnN0YW5jZW9mIEJvb2xlYW4gKXsKLSAgICAgICAgICAgIC8vZmVhdHVyZXMgd2hvc2UgcGFyYW1ldGVyIHZhbHVlIGNhbiBiZSBzZXQgZWl0aGVyICd0cnVlJyBvciAnZmFsc2UnCi0gICAgICAgICAgICAvLyBvciB0aGV5IGFjY2VwdCBhbnkgYm9vbGVhbiB2YWx1ZSAtLSBzbyB3ZSBqdXN0IG5lZWQgdG8gY2hlY2sgdGhhdAotICAgICAgICAgICAgLy8gaXRzIGEgYm9vbGVhbiB2YWx1ZS4uCi0gICAgICAgICAgICBpZiAobmFtZS5lcXVhbHNJZ25vcmVDYXNlKENvbnN0YW50cy5ET01fQ09NTUVOVFMpCi0gICAgICAgICAgICAgICAgfHwgbmFtZS5lcXVhbHNJZ25vcmVDYXNlKENvbnN0YW50cy5ET01fREFUQVRZUEVfTk9STUFMSVpBVElPTikKLSAgICAgICAgICAgICAgICB8fCBuYW1lLmVxdWFsc0lnbm9yZUNhc2UoQ29uc3RhbnRzLkRPTV9DREFUQV9TRUNUSU9OUykKLSAgICAgICAgICAgICAgICB8fCBuYW1lLmVxdWFsc0lnbm9yZUNhc2UoQ29uc3RhbnRzLkRPTV9FTlRJVElFUykKLSAgICAgICAgICAgICAgICB8fCBuYW1lLmVxdWFsc0lnbm9yZUNhc2UoQ29uc3RhbnRzLkRPTV9TUExJVF9DREFUQSkKLSAgICAgICAgICAgICAgICB8fCBuYW1lLmVxdWFsc0lnbm9yZUNhc2UoQ29uc3RhbnRzLkRPTV9OQU1FU1BBQ0VTKQotICAgICAgICAgICAgICAgIHx8IG5hbWUuZXF1YWxzSWdub3JlQ2FzZShDb25zdGFudHMuRE9NX1ZBTElEQVRFKQotICAgICAgICAgICAgICAgIHx8IG5hbWUuZXF1YWxzSWdub3JlQ2FzZShDb25zdGFudHMuRE9NX1dFTExGT1JNRUQpCi0gICAgICAgICAgICAgICAgfHwgbmFtZS5lcXVhbHNJZ25vcmVDYXNlKENvbnN0YW50cy5ET01fSU5GT1NFVCkKLSAgICAgICAgICAgICAgICB8fCBuYW1lLmVxdWFsc0lnbm9yZUNhc2UoQ29uc3RhbnRzLkRPTV9OQU1FU1BBQ0VfREVDTEFSQVRJT05TKQotICAgICAgICAgICAgICAgICkgewotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgfS8vZmVhdHVyZXMgd2hvc2UgcGFyYW1ldGVyIHZhbHVlIGNhbiBub3QgYmUgc2V0IHRvICd0cnVlJwotICAgICAgICAgICAgZWxzZSBpZiAoCi0gICAgICAgICAgICAgICAgbmFtZS5lcXVhbHNJZ25vcmVDYXNlKENvbnN0YW50cy5ET01fTk9STUFMSVpFX0NIQVJBQ1RFUlMpCi0gICAgICAgICAgICAgICAgICAgIHx8IG5hbWUuZXF1YWxzSWdub3JlQ2FzZShDb25zdGFudHMuRE9NX0NBTk9OSUNBTF9GT1JNKQotICAgICAgICAgICAgICAgICAgICB8fCBuYW1lLmVxdWFsc0lnbm9yZUNhc2UoQ29uc3RhbnRzLkRPTV9WQUxJREFURV9JRl9TQ0hFTUEpCi0gICAgICAgICAgICAgICAgICAgIHx8IG5hbWUuZXF1YWxzSWdub3JlQ2FzZShDb25zdGFudHMuRE9NX0NIRUNLX0NIQVJfTk9STUFMSVpBVElPTikKLSAgICAgICAgICAgICAgICAgICAgKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiAodmFsdWUuZXF1YWxzKEJvb2xlYW4uVFJVRSkpID8gZmFsc2UgOiB0cnVlOwotICAgICAgICAgICAgfS8vZmVhdHVyZXMgd2hvc2UgcGFyYW1ldGVyIHZhbHVlIGNhbiBub3QgYmUgc2V0IHRvICdmYWxzZScKLSAgICAgICAgICAgIGVsc2UgaWYoIG5hbWUuZXF1YWxzSWdub3JlQ2FzZShDb25zdGFudHMuRE9NX0VMRU1FTlRfQ09OVEVOVF9XSElURVNQQUNFKQotICAgICAgICAgICAgICAgICAgICB8fCBuYW1lLmVxdWFsc0lnbm9yZUNhc2UoU0VORF9QU1ZJKQotICAgICAgICAgICAgICAgICAgICApIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuICh2YWx1ZS5lcXVhbHMoQm9vbGVhbi5UUlVFKSkgPyB0cnVlIDogZmFsc2U7Ci0gICAgICAgICAgICB9Ly8gaWYgbmFtZSBpcyBub3QgYW1vbmcgdGhlIGFib3ZlIGxpc3RlZCBhYm92ZSAtLSBpdHMgbm90IHJlY29nbml6ZWQuIHJldHVybiBmYWxzZQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlIDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzSWdub3JlQ2FzZShDb25zdGFudHMuRE9NX0VSUk9SX0hBTkRMRVIpKSB7Ci0gICAgICAgICAgICByZXR1cm4gKHZhbHVlIGluc3RhbmNlb2YgRE9NRXJyb3JIYW5kbGVyKSA/IHRydWUgOiBmYWxzZSA7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAobmFtZS5lcXVhbHNJZ25vcmVDYXNlKENvbnN0YW50cy5ET01fUkVTT1VSQ0VfUkVTT0xWRVIpKSB7Ci0gICAgICAgICAgICByZXR1cm4gKHZhbHVlIGluc3RhbmNlb2YgTFNSZXNvdXJjZVJlc29sdmVyKSA/IHRydWUgOiBmYWxzZSA7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAobmFtZS5lcXVhbHNJZ25vcmVDYXNlKENvbnN0YW50cy5ET01fU0NIRU1BX0xPQ0FUSU9OKSkgewotICAgICAgICAgICAgcmV0dXJuICh2YWx1ZSBpbnN0YW5jZW9mIFN0cmluZykgPyB0cnVlIDogZmFsc2UgOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzSWdub3JlQ2FzZShDb25zdGFudHMuRE9NX1NDSEVNQV9UWVBFKSkgewotICAgICAgICAgICAgLy8gUkVWSVNJVDogc2hvdWxkIG51bGwgdmFsdWUgYmUgc3VwcG9ydGVkPwotICAgICAgICAgICAgLy9hcyBvZiBub3cgd2UgYXJlIG9ubHkgc3VwcG9ydGluZyBXM0MgWE1MIFNjaGVtYQotICAgICAgICAgICAgcmV0dXJuICggKHZhbHVlIGluc3RhbmNlb2YgU3RyaW5nKSAmJiB2YWx1ZS5lcXVhbHMoQ29uc3RhbnRzLk5TX1hNTFNDSEVNQSkgKSA/IHRydWUgOiBmYWxzZSA7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAobmFtZS5lcXVhbHNJZ25vcmVDYXNlKFNZTUJPTF9UQUJMRSkpewotICAgICAgICAgICAgLy8gWGVyY2VzIFN5bWJvbCBUYWJsZQotICAgICAgICAgICAgcmV0dXJuICh2YWx1ZSBpbnN0YW5jZW9mIFN5bWJvbFRhYmxlKSA/IHRydWUgOiBmYWxzZSA7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAobmFtZS5lcXVhbHNJZ25vcmVDYXNlIChHUkFNTUFSX1BPT0wpKXsKLSAgICAgICAgICAgIHJldHVybiAodmFsdWUgaW5zdGFuY2VvZiBYTUxHcmFtbWFyUG9vbCkgPyB0cnVlIDogZmFsc2UgOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgLy9mYWxzZSBpZiB0aGUgcGFyYW1ldGVyIGlzIG5vdCByZWNvZ25pemVkIG9yIHRoZSByZXF1ZXN0ZWQgdmFsdWUgaXMgbm90IHN1cHBvcnRlZC4KLSAgICAgICAgICAgIHJldHVybiBmYWxzZSA7Ci0gICAgICAgIH0KLQotICAgICAgICB9IC8vY2FuU2V0UGFyYW1ldGVyCi0KLSAgICAvKioKLSAgICAgKiAgRE9NIExldmVsIDMgQ1IgLSBFeHBlcmltZW50YWwuCi0gICAgICoKLSAgICAgKiAgVGhlIGxpc3Qgb2YgdGhlIHBhcmFtZXRlcnMgc3VwcG9ydGVkIGJ5IHRoaXMKLSAgICAgKiA8Y29kZT5ET01Db25maWd1cmF0aW9uPC9jb2RlPiBvYmplY3QgYW5kIGZvciB3aGljaCBhdCBsZWFzdCBvbmUgdmFsdWUKLSAgICAgKiBjYW4gYmUgc2V0IGJ5IHRoZSBhcHBsaWNhdGlvbi4gTm90ZSB0aGF0IHRoaXMgbGlzdCBjYW4gYWxzbyBjb250YWluCi0gICAgICogcGFyYW1ldGVyIG5hbWVzIGRlZmluZWQgb3V0c2lkZSB0aGlzIHNwZWNpZmljYXRpb24uCi0gICAgICovCi0gICAgcHVibGljIERPTVN0cmluZ0xpc3QgZ2V0UGFyYW1ldGVyTmFtZXMoKSB7Ci0gICAgICAgIGlmIChmUmVjb2duaXplZFBhcmFtZXRlcnMgPT0gbnVsbCl7Ci0gICAgICAgICAgICAgICAgICAgICAgICBWZWN0b3IgcGFyYW1ldGVycyA9IG5ldyBWZWN0b3IoKTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgLy9BZGQgRE9NIHJlY29nbml6ZWQgcGFyYW1ldGVycwotICAgICAgICAgICAgICAgICAgICAgICAgLy9SRVZJU0lUOiBXb3VsZCBoYXZlIGJlZW4gbmljZSB0byBoYXZlIGEgbGlzdCBvZgotICAgICAgICAgICAgICAgICAgICAgICAgLy9yZWNvZ25pemVkIHBhcmFtdGVycy4KLSAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtZXRlcnMuYWRkKENvbnN0YW50cy5ET01fQ09NTUVOVFMpOwotICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1ldGVycy5hZGQoQ29uc3RhbnRzLkRPTV9EQVRBVFlQRV9OT1JNQUxJWkFUSU9OKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtZXRlcnMuYWRkKENvbnN0YW50cy5ET01fQ0RBVEFfU0VDVElPTlMpOwotICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1ldGVycy5hZGQoQ29uc3RhbnRzLkRPTV9FTlRJVElFUyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBwYXJhbWV0ZXJzLmFkZChDb25zdGFudHMuRE9NX1NQTElUX0NEQVRBKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtZXRlcnMuYWRkKENvbnN0YW50cy5ET01fTkFNRVNQQUNFUyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBwYXJhbWV0ZXJzLmFkZChDb25zdGFudHMuRE9NX1ZBTElEQVRFKTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1ldGVycy5hZGQoQ29uc3RhbnRzLkRPTV9JTkZPU0VUKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtZXRlcnMuYWRkKENvbnN0YW50cy5ET01fTk9STUFMSVpFX0NIQVJBQ1RFUlMpOwotICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1ldGVycy5hZGQoQ29uc3RhbnRzLkRPTV9DQU5PTklDQUxfRk9STSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBwYXJhbWV0ZXJzLmFkZChDb25zdGFudHMuRE9NX1ZBTElEQVRFX0lGX1NDSEVNQSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBwYXJhbWV0ZXJzLmFkZChDb25zdGFudHMuRE9NX0NIRUNLX0NIQVJfTk9STUFMSVpBVElPTik7Ci0gICAgICAgICAgICAgICAgICAgICAgICBwYXJhbWV0ZXJzLmFkZChDb25zdGFudHMuRE9NX1dFTExGT1JNRUQpOwotCi0gICAgICAgICAgICAgICAgICAgICAgICBwYXJhbWV0ZXJzLmFkZChDb25zdGFudHMuRE9NX05BTUVTUEFDRV9ERUNMQVJBVElPTlMpOwotICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1ldGVycy5hZGQoQ29uc3RhbnRzLkRPTV9FTEVNRU5UX0NPTlRFTlRfV0hJVEVTUEFDRSk7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtZXRlcnMuYWRkKENvbnN0YW50cy5ET01fRVJST1JfSEFORExFUik7Ci0gICAgICAgICAgICAgICAgICAgICAgICBwYXJhbWV0ZXJzLmFkZChDb25zdGFudHMuRE9NX1NDSEVNQV9UWVBFKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtZXRlcnMuYWRkKENvbnN0YW50cy5ET01fU0NIRU1BX0xPQ0FUSU9OKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtZXRlcnMuYWRkKENvbnN0YW50cy5ET01fUkVTT1VSQ0VfUkVTT0xWRVIpOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAvL0FkZCByZWNvZ25pemVkIHhlcmNlcyBmZWF0dXJlcyBhbmQgcHJvcGVydGllcwotICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1ldGVycy5hZGQoR1JBTU1BUl9QT09MKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtZXRlcnMuYWRkKFNZTUJPTF9UQUJMRSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBwYXJhbWV0ZXJzLmFkZChTRU5EX1BTVkkpOwotCi0gICAgICAgICAgICAgICAgICAgICAgICBmUmVjb2duaXplZFBhcmFtZXRlcnMgPSBuZXcgRE9NU3RyaW5nTGlzdEltcGwocGFyYW1ldGVycyk7Ci0KLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBmUmVjb2duaXplZFBhcmFtZXRlcnM7Ci0gICAgfS8vZ2V0UGFyYW1ldGVyTmFtZXMKLQotICAgIC8vCi0gICAgLy8gUHJvdGVjdGVkIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogcmVzZXQgYWxsIGNvbXBvbmVudHMgYmVmb3JlIHBhcnNpbmcKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCByZXNldCgpIHRocm93cyBYTklFeGNlcHRpb24gewotCi0gICAgICAgIGlmIChmVmFsaWRhdGlvbk1hbmFnZXIgIT0gbnVsbCkKLSAgICAgICAgICAgIGZWYWxpZGF0aW9uTWFuYWdlci5yZXNldCgpOwotCi0gICAgICAgIGludCBjb3VudCA9IGZDb21wb25lbnRzLnNpemUoKTsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7Ci0gICAgICAgICAgICBYTUxDb21wb25lbnQgYyA9IChYTUxDb21wb25lbnQpIGZDb21wb25lbnRzLmdldChpKTsKLSAgICAgICAgICAgIGMucmVzZXQodGhpcyk7Ci0gICAgICAgIH0KLQotICAgIH0gLy8gcmVzZXQoKQotCi0gICAgLyoqCi0gICAgICogQ2hlY2sgYSBwcm9wZXJ0eS4gSWYgdGhlIHByb3BlcnR5IGlzIGtub3duIGFuZCBzdXBwb3J0ZWQsIHRoaXMgbWV0aG9kCi0gICAgICogc2ltcGx5IHJldHVybnMuIE90aGVyd2lzZSwgdGhlIGFwcHJvcHJpYXRlIGV4Y2VwdGlvbiBpcyB0aHJvd24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcHJvcGVydHlJZCBUaGUgdW5pcXVlIGlkZW50aWZpZXIgKFVSSSkgb2YgdGhlIHByb3BlcnR5Ci0gICAgICogICAgICAgICAgICAgICAgICAgYmVpbmcgc2V0LgotICAgICAqIEBleGNlcHRpb24gY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gSWYgdGhlCi0gICAgICogICAgICAgICAgICByZXF1ZXN0ZWQgZmVhdHVyZSBpcyBub3Qga25vd24gb3Igc3VwcG9ydGVkLgotICAgICAqLwotICAgIHByb3RlY3RlZCBQcm9wZXJ0eVN0YXRlIGNoZWNrUHJvcGVydHkoU3RyaW5nIHByb3BlcnR5SWQpCi0gICAgICAgIHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIHsKLQotICAgICAgICAvLyBzcGVjaWFsIGNhc2VzCi0gICAgICAgIGlmIChwcm9wZXJ0eUlkLnN0YXJ0c1dpdGgoQ29uc3RhbnRzLlNBWF9QUk9QRVJUWV9QUkVGSVgpKSB7Ci0gICAgICAgICAgICBmaW5hbCBpbnQgc3VmZml4TGVuZ3RoID0gcHJvcGVydHlJZC5sZW5ndGgoKSAtIENvbnN0YW50cy5TQVhfUFJPUEVSVFlfUFJFRklYLmxlbmd0aCgpOwotCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgLy8gaHR0cDovL3htbC5vcmcvc2F4L3Byb3BlcnRpZXMveG1sLXN0cmluZwotICAgICAgICAgICAgLy8gVmFsdWUgdHlwZTogU3RyaW5nCi0gICAgICAgICAgICAvLyBBY2Nlc3M6IHJlYWQtb25seQotICAgICAgICAgICAgLy8gICBHZXQgdGhlIGxpdGVyYWwgc3RyaW5nIG9mIGNoYXJhY3RlcnMgYXNzb2NpYXRlZCB3aXRoIHRoZQotICAgICAgICAgICAgLy8gICBjdXJyZW50IGV2ZW50LiAgSWYgdGhlIHBhcnNlciByZWNvZ25pc2VzIGFuZCBzdXBwb3J0cyB0aGlzCi0gICAgICAgICAgICAvLyAgIHByb3BlcnR5IGJ1dCBpcyBub3QgY3VycmVudGx5IHBhcnNpbmcgdGV4dCwgaXQgc2hvdWxkIHJldHVybgotICAgICAgICAgICAgLy8gICBudWxsICh0aGlzIGlzIGEgZ29vZCB3YXkgdG8gY2hlY2sgZm9yIGF2YWlsYWJpbGl0eSBiZWZvcmUgdGhlCi0gICAgICAgICAgICAvLyAgIHBhcnNlIGJlZ2lucykuCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgaWYgKHN1ZmZpeExlbmd0aCA9PSBDb25zdGFudHMuWE1MX1NUUklOR19QUk9QRVJUWS5sZW5ndGgoKSAmJgotICAgICAgICAgICAgICAgIHByb3BlcnR5SWQuZW5kc1dpdGgoQ29uc3RhbnRzLlhNTF9TVFJJTkdfUFJPUEVSVFkpKSB7Ci0gICAgICAgICAgICAgICAgLy8gUkVWSVNJVCAtIHdlIHNob3VsZCBwcm9iYWJseSBhc2sgeG1sLWRldiBmb3IgYSBwcmVjaXNlCi0gICAgICAgICAgICAgICAgLy8gZGVmaW5pdGlvbiBvZiB3aGF0IHRoaXMgaXMgYWN0dWFsbHkgc3VwcG9zZWQgdG8gcmV0dXJuLCBhbmQKLSAgICAgICAgICAgICAgICAvLyBpbiBleGFjdGx5IHdoaWNoIGNpcmN1bXN0YW5jZXMuCi0gICAgICAgICAgICAgICAgcmV0dXJuIFByb3BlcnR5U3RhdGUuTk9UX1NVUFBPUlRFRDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIGNoZWNrIHByb3BlcnR5Ci0gICAgICAgIHJldHVybiBzdXBlci5jaGVja1Byb3BlcnR5KHByb3BlcnR5SWQpOwotCi0gICAgfSAvLyBjaGVja1Byb3BlcnR5KFN0cmluZykKLQotCi0gICAgcHJvdGVjdGVkIHZvaWQgYWRkQ29tcG9uZW50KFhNTENvbXBvbmVudCBjb21wb25lbnQpIHsKLQotICAgICAgICAvLyBkb24ndCBhZGQgYSBjb21wb25lbnQgbW9yZSB0aGFuIG9uY2UKLSAgICAgICAgaWYgKGZDb21wb25lbnRzLmNvbnRhaW5zKGNvbXBvbmVudCkpIHsKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotICAgICAgICBmQ29tcG9uZW50cy5hZGQoY29tcG9uZW50KTsKLQotICAgICAgICAvLyByZWdpc3RlciBjb21wb25lbnQncyByZWNvZ25pemVkIGZlYXR1cmVzCi0gICAgICAgIFN0cmluZ1tdIHJlY29nbml6ZWRGZWF0dXJlcyA9IGNvbXBvbmVudC5nZXRSZWNvZ25pemVkRmVhdHVyZXMoKTsKLSAgICAgICAgYWRkUmVjb2duaXplZEZlYXR1cmVzKHJlY29nbml6ZWRGZWF0dXJlcyk7Ci0KLSAgICAgICAgLy8gcmVnaXN0ZXIgY29tcG9uZW50J3MgcmVjb2duaXplZCBwcm9wZXJ0aWVzCi0gICAgICAgIFN0cmluZ1tdIHJlY29nbml6ZWRQcm9wZXJ0aWVzID0gY29tcG9uZW50LmdldFJlY29nbml6ZWRQcm9wZXJ0aWVzKCk7Ci0gICAgICAgIGFkZFJlY29nbml6ZWRQcm9wZXJ0aWVzKHJlY29nbml6ZWRQcm9wZXJ0aWVzKTsKLQotICAgIH0gLy8gYWRkQ29tcG9uZW50KFhNTENvbXBvbmVudCkKLQotICAgIHByb3RlY3RlZCBWYWxpZGF0aW9uTWFuYWdlciBjcmVhdGVWYWxpZGF0aW9uTWFuYWdlcigpewotICAgICAgICByZXR1cm4gbmV3IFZhbGlkYXRpb25NYW5hZ2VyKCk7Ci0gICAgfQotCi19IC8vIGNsYXNzIFhNTFBhcnNlcgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL0RPTUVycm9ySW1wbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL0RPTUVycm9ySW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA5MGRlYzM4Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9ET01FcnJvckltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEzNiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLCAyMDAyLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tOwotCi1pbXBvcnQgb3JnLnczYy5kb20uRE9NRXJyb3I7Ci1pbXBvcnQgb3JnLnczYy5kb20uRE9NTG9jYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MUGFyc2VFeGNlcHRpb247Ci0KLQotLyoqCi0gKiA8Y29kZT5ET01FcnJvckltcGw8L2NvZGU+IGlzIGFuIGltcGxlbWVudGF0aW9uIHRoYXQgZGVzY3JpYmVzIGFuIGVycm9yLgotICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGUgZXJyb3Igb2JqZWN0IHRoYXQgZGVzY3JpYmVzIHRoZSBlcnJvcgotICogbWlnaHQgYmUgcmV1c2VkIGJ5IFhlcmNlcyBpbXBsZW1lbnRhdGlvbiwgYWNyb3NzIG11bHRpcGxlIGNhbGxzIHRvIHRoZQotICogaGFuZGxlRXZlbnQgbWV0aG9kIG9uIERPTUVycm9ySGFuZGxlciBpbnRlcmZhY2UuCi0gKgotICoKLSAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAxL1dELURPTS1MZXZlbC0zLUNvcmUtMjAwMTA5MTMnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAzIENvcmUgU3BlY2lmaWNhdGlvbjwvYT4uCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgR29wYWwgU2hhcm1hLCBTVU4gTWljcm9zeXN0ZW1zIEluYy4KLSAqIEBhdXRob3IgRWxlbmEgTGl0YW5pLCBJQk0KLSAqCi0gKi8KLQotLy8gUkVWSVNJVDogdGhlIGltcGxlbWVudGF0aW9uIG9mIEVycm9yUmVwb3J0ZXIuCi0vLyAgICAgICAgICB3ZSBwcm9iYWJseSBzaG91bGQgbm90IHBhc3MgWE1MUGFyc2VFeGNlcHRpb24KLS8vCi0KLXB1YmxpYyBjbGFzcyBET01FcnJvckltcGwgaW1wbGVtZW50cyBET01FcnJvciB7Ci0KLSAgICAvLwotICAgIC8vIERhdGEKLSAgICAvLwotCi0gICAgcHVibGljIHNob3J0IGZTZXZlcml0eSA9IERPTUVycm9yLlNFVkVSSVRZX1dBUk5JTkc7Ci0gICAgcHVibGljIFN0cmluZyBmTWVzc2FnZSA9IG51bGw7Ci0gICAgcHVibGljIERPTUxvY2F0b3JJbXBsIGZMb2NhdG9yID0gbmV3IERPTUxvY2F0b3JJbXBsKCk7Ci0gICAgcHVibGljIEV4Y2VwdGlvbiBmRXhjZXB0aW9uID0gbnVsbDsKLSAgICBwdWJsaWMgU3RyaW5nIGZUeXBlOwotICAgIHB1YmxpYyBPYmplY3QgZlJlbGF0ZWREYXRhOwotCi0KLQotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKiBEZWZhdWx0IGNvbnN0cnVjdG9yLiAqLwotICAgIHB1YmxpYyBET01FcnJvckltcGwgKCkgewotICAgIH0KLQotICAgIC8qKiBFeGN0cmFjdHMgaW5mb3JtYXRpb24gZnJvbSBYTUxQYXJzZXJFeGNlcHRpb24pICovCi0gICAgcHVibGljIERPTUVycm9ySW1wbCAoc2hvcnQgc2V2ZXJpdHksIFhNTFBhcnNlRXhjZXB0aW9uIGV4Y2VwdGlvbikgewotICAgICAgICBmU2V2ZXJpdHkgPSBzZXZlcml0eTsKLSAgICAgICAgZkV4Y2VwdGlvbiA9IGV4Y2VwdGlvbjsKLSAgICAgICAgZkxvY2F0b3IgPSBjcmVhdGVET01Mb2NhdG9yIChleGNlcHRpb24pOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoZSBzZXZlcml0eSBvZiB0aGUgZXJyb3IsIGVpdGhlciA8Y29kZT5TRVZFUklUWV9XQVJOSU5HPC9jb2RlPiwKLSAgICAgKiA8Y29kZT5TRVZFUklUWV9FUlJPUjwvY29kZT4sIG9yIDxjb2RlPlNFVkVSSVRZX0ZBVEFMX0VSUk9SPC9jb2RlPi4KLSAgICAgKi8KLQotICAgIHB1YmxpYyBzaG9ydCBnZXRTZXZlcml0eSgpIHsKLSAgICAgICAgcmV0dXJuIGZTZXZlcml0eTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBbiBpbXBsZW1lbnRhdGlvbiBzcGVjaWZpYyBzdHJpbmcgZGVzY3JpYmluZyB0aGUgZXJyb3IgdGhhdCBvY2N1cmVkLgotICAgICAqLwotCi0gICAgcHVibGljIFN0cmluZyBnZXRNZXNzYWdlKCkgewotICAgICAgICByZXR1cm4gZk1lc3NhZ2U7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhlIGxvY2F0aW9uIG9mIHRoZSBlcnJvci4KLSAgICAgKi8KLQotICAgIHB1YmxpYyBET01Mb2NhdG9yIGdldExvY2F0aW9uKCkgewotICAgICAgICByZXR1cm4gZkxvY2F0b3I7Ci0gICAgfQotCi0gICAgLy8gbWV0aG9kIHRvIGdldCB0aGUgRE9NTG9jYXRvciBPYmplY3QKLSAgICBwcml2YXRlIERPTUxvY2F0b3JJbXBsIGNyZWF0ZURPTUxvY2F0b3IoWE1MUGFyc2VFeGNlcHRpb24gZXhjZXB0aW9uKSB7Ci0gICAgICAgIC8vIGFzc3VtaW5nIERPTUxvY2F0b3Igd2FudHMgdGhlICpleHBhbmRlZCosIG5vdCB0aGUgbGl0ZXJhbCwgVVJJIG9mIHRoZSBkb2MuLi4gLSBuZWlsZwotICAgICAgICByZXR1cm4gbmV3IERPTUxvY2F0b3JJbXBsKGV4Y2VwdGlvbi5nZXRMaW5lTnVtYmVyKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhjZXB0aW9uLmdldENvbHVtbk51bWJlcigpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4Y2VwdGlvbi5nZXRDaGFyYWN0ZXJPZmZzZXQoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleGNlcHRpb24uZ2V0RXhwYW5kZWRTeXN0ZW1JZCgpKTsKLSAgICB9IC8vIGNyZWF0ZURPTUxvY2F0b3IoKQotCi0KLSAgICAvKioKLSAgICAgKiBUaGUgcmVsYXRlZCBwbGF0Zm9ybSBkZXBlbmRlbnQgZXhjZXB0aW9uIGlmIGFueS5leGNlcHRpb24gaXMgYSByZXNlcnZlZAotICAgICAqIHdvcmQsIHdlIG5lZWQgdG8gcmVuYW1lIGl0LkNoYW5nZSB0byAicmVsYXRlZEV4Y2VwdGlvbiIuIChGMkYgMjYgU2VwCi0gICAgICogMjAwMSkKLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0IGdldFJlbGF0ZWRFeGNlcHRpb24oKXsKLSAgICAgICAgcmV0dXJuIGZFeGNlcHRpb247Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgcmVzZXQoKXsKLSAgICAgICAgZlNldmVyaXR5ID0gRE9NRXJyb3IuU0VWRVJJVFlfV0FSTklORzsKLSAgICAgICAgZkV4Y2VwdGlvbiA9IG51bGw7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRUeXBlKCl7Ci0gICAgICAgIHJldHVybiBmVHlwZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgT2JqZWN0IGdldFJlbGF0ZWREYXRhKCl7Ci0gICAgICAgIHJldHVybiBmUmVsYXRlZERhdGE7Ci0gICAgfQotCi0KLX0vLyBjbGFzcyBET01FcnJvckltcGwKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9ET01JbXBsZW1lbnRhdGlvbkltcGwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9ET01JbXBsZW1lbnRhdGlvbkltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZTZhNjhmMC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vRE9NSW1wbGVtZW50YXRpb25JbXBsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNTEgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDAyLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tOwotCi1pbXBvcnQgb3JnLnczYy5kb20uRE9NRXhjZXB0aW9uOwotaW1wb3J0IG9yZy53M2MuZG9tLkRPTUltcGxlbWVudGF0aW9uOwotaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50VHlwZTsKLWltcG9ydCBvcmcudzNjLmRvbS5FbGVtZW50OwotCi0KLQotLyoqCi0gKiBUaGUgRE9NSW1wbGVtZW50YXRpb24gY2xhc3MgaXMgZGVzY3JpcHRpb24gb2YgYSBwYXJ0aWN1bGFyCi0gKiBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgRG9jdW1lbnQgT2JqZWN0IE1vZGVsLiBBcyBzdWNoIGl0cyBkYXRhIGlzCi0gKiBzdGF0aWMsIHNoYXJlZCBieSBhbGwgaW5zdGFuY2VzIG9mIHRoaXMgaW1wbGVtZW50YXRpb24uCi0gKiA8UD4KLSAqIFRoZSBET00gQVBJIHJlcXVpcmVzIHRoYXQgaXQgYmUgYSByZWFsIG9iamVjdCByYXRoZXIgdGhhbiBzdGF0aWMKLSAqIG1ldGhvZHMuIEhvd2V2ZXIsIHRoZXJlJ3Mgbm90aGluZyB0aGF0IHNheXMgaXQgY2FuJ3QgYmUgYSBzaW5nbGV0b24sCi0gKiBzbyB0aGF0J3MgaG93IEkndmUgaW1wbGVtZW50ZWQgaXQuCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBzaW5jZSAgUFItRE9NLUxldmVsLTEtMTk5ODA4MTguCi0gKi8KLXB1YmxpYyBjbGFzcyBET01JbXBsZW1lbnRhdGlvbkltcGwgZXh0ZW5kcyBDb3JlRE9NSW1wbGVtZW50YXRpb25JbXBsCi0gICAgaW1wbGVtZW50cyBET01JbXBsZW1lbnRhdGlvbiB7Ci0KLSAgICAvLwotICAgIC8vIERhdGEKLSAgICAvLwotCi0gICAgLy8gc3RhdGljCi0KLSAgICAvKiogRG9tIGltcGxlbWVudGF0aW9uIHNpbmdsZXRvbi4gKi8KLSAgICBzdGF0aWMgRE9NSW1wbGVtZW50YXRpb25JbXBsIHNpbmdsZXRvbiA9IG5ldyBET01JbXBsZW1lbnRhdGlvbkltcGwoKTsKLQotCi0gICAgLy8KLSAgICAvLyBQdWJsaWMgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKiogTk9OLURPTTogT2J0YWluIGFuZCByZXR1cm4gdGhlIHNpbmdsZSBzaGFyZWQgb2JqZWN0ICovCi0gICAgcHVibGljIHN0YXRpYyBET01JbXBsZW1lbnRhdGlvbiBnZXRET01JbXBsZW1lbnRhdGlvbigpIHsKLSAgICAgICAgcmV0dXJuIHNpbmdsZXRvbjsKLSAgICB9Ci0KLSAgICAvLwotICAgIC8vIERPTUltcGxlbWVudGF0aW9uIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogVGVzdCBpZiB0aGUgRE9NIGltcGxlbWVudGF0aW9uIHN1cHBvcnRzIGEgc3BlY2lmaWMgImZlYXR1cmUiIC0tCi0gICAgICogY3VycmVudGx5IG1lYW5pbmcgbGFuZ3VhZ2UgYW5kIGxldmVsIHRoZXJlb2YuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZmVhdHVyZSAgICAgIFRoZSBwYWNrYWdlIG5hbWUgb2YgdGhlIGZlYXR1cmUgdG8gdGVzdC4KLSAgICAgKiBJbiBMZXZlbCAxLCBzdXBwb3J0ZWQgdmFsdWVzIGFyZSAiSFRNTCIgYW5kICJYTUwiIChjYXNlLWluc2Vuc2l0aXZlKS4KLSAgICAgKiBBdCB0aGlzIHdyaXRpbmcsIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tIHN1cHBvcnRzIG9ubHkgWE1MLgotICAgICAqCi0gICAgICogQHBhcmFtIHZlcnNpb24gICAgICBUaGUgdmVyc2lvbiBudW1iZXIgb2YgdGhlIGZlYXR1cmUgYmVpbmcgdGVzdGVkLgotICAgICAqIFRoaXMgaXMgaW50ZXJwcmV0ZWQgYXMgIlZlcnNpb24gb2YgdGhlIERPTSBBUEkgc3VwcG9ydGVkIGZvciB0aGUKLSAgICAgKiBzcGVjaWZpZWQgRmVhdHVyZSIsIGFuZCBpbiBMZXZlbCAxIHNob3VsZCBiZSAiMS4wIgotICAgICAqCi0gICAgICogQHJldHVybiAgICB0cnVlIGlmZiB0aGlzIGltcGxlbWVudGF0aW9uIGlzIGNvbXBhdGFibGUgd2l0aCB0aGUKLSAgICAgKiBzcGVjaWZpZWQgZmVhdHVyZSBhbmQgdmVyc2lvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBoYXNGZWF0dXJlKFN0cmluZyBmZWF0dXJlLCBTdHJpbmcgdmVyc2lvbikgewotCi0gICAgICAgIGJvb2xlYW4gcmVzdWx0ID0gc3VwZXIuaGFzRmVhdHVyZShmZWF0dXJlLCB2ZXJzaW9uKTsKLSAgICAgICAgaWYgKCFyZXN1bHQpIHsKLSAgICAgICAgICAgIGJvb2xlYW4gYW55VmVyc2lvbiA9IHZlcnNpb24gPT0gbnVsbCB8fCB2ZXJzaW9uLmxlbmd0aCgpID09IDA7Ci0gICAgICAgICAgICBpZiAoZmVhdHVyZS5zdGFydHNXaXRoKCIrIikpIHsKLSAgICAgICAgICAgICAgICBmZWF0dXJlID0gZmVhdHVyZS5zdWJzdHJpbmcoMSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gKAotICAgICAgICAgICAgICAgIChmZWF0dXJlLmVxdWFsc0lnbm9yZUNhc2UoIkV2ZW50cyIpCi0gICAgICAgICAgICAgICAgICAgICYmIChhbnlWZXJzaW9uIHx8IHZlcnNpb24uZXF1YWxzKCIyLjAiKSkpCi0gICAgICAgICAgICAgICAgICAgIHx8IChmZWF0dXJlLmVxdWFsc0lnbm9yZUNhc2UoIk11dGF0aW9uRXZlbnRzIikKLSAgICAgICAgICAgICAgICAgICAgICAgICYmIChhbnlWZXJzaW9uIHx8IHZlcnNpb24uZXF1YWxzKCIyLjAiKSkpCi0gICAgICAgICAgICAgICAgICAgIHx8IChmZWF0dXJlLmVxdWFsc0lnbm9yZUNhc2UoIlRyYXZlcnNhbCIpCi0gICAgICAgICAgICAgICAgICAgICAgICAmJiAoYW55VmVyc2lvbiB8fCB2ZXJzaW9uLmVxdWFscygiMi4wIikpKQotICAgICAgICAgICAgICAgICAgICB8fCAoZmVhdHVyZS5lcXVhbHNJZ25vcmVDYXNlKCJSYW5nZSIpCi0gICAgICAgICAgICAgICAgICAgICAgICAmJiAoYW55VmVyc2lvbiB8fCB2ZXJzaW9uLmVxdWFscygiMi4wIikpKQotICAgICAgICAgICAgICAgICAgICB8fCAoZmVhdHVyZS5lcXVhbHNJZ25vcmVDYXNlKCJNdXRhdGlvbkV2ZW50cyIpCi0gICAgICAgICAgICAgICAgICAgICAgICAmJiAoYW55VmVyc2lvbiB8fCB2ZXJzaW9uLmVxdWFscygiMi4wIikpKSk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHJlc3VsdDsKLSAgICB9IC8vIGhhc0ZlYXR1cmUoU3RyaW5nLFN0cmluZyk6Ym9vbGVhbgotCi0KLQotICAgIC8qKgotICAgICAqIEludHJvZHVjZWQgaW4gRE9NIExldmVsIDIuIDxwPgotICAgICAqCi0gICAgICogQ3JlYXRlcyBhbiBYTUwgRG9jdW1lbnQgb2JqZWN0IG9mIHRoZSBzcGVjaWZpZWQgdHlwZSB3aXRoIGl0cyBkb2N1bWVudAotICAgICAqIGVsZW1lbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZXNwYWNlVVJJICAgICBUaGUgbmFtZXNwYWNlIFVSSSBvZiB0aGUgZG9jdW1lbnQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50IHRvIGNyZWF0ZSwgb3IgbnVsbC4KLSAgICAgKiBAcGFyYW0gcXVhbGlmaWVkTmFtZSAgICBUaGUgcXVhbGlmaWVkIG5hbWUgb2YgdGhlIGRvY3VtZW50Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudCB0byBjcmVhdGUuCi0gICAgICogQHBhcmFtIGRvY3R5cGUgICAgICAgICAgVGhlIHR5cGUgb2YgZG9jdW1lbnQgdG8gYmUgY3JlYXRlZCBvciBudWxsLjxwPgotICAgICAqCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgV2hlbiBkb2N0eXBlIGlzIG5vdCBudWxsLCBpdHMKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBOb2RlLm93bmVyRG9jdW1lbnQgYXR0cmlidXRlIGlzIHNldCB0bwotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSBkb2N1bWVudCBiZWluZyBjcmVhdGVkLgotICAgICAqIEByZXR1cm4gRG9jdW1lbnQgICAgICAgIEEgbmV3IERvY3VtZW50IG9iamVjdC4KLSAgICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbiAgICBXUk9OR19ET0NVTUVOVF9FUlI6IFJhaXNlZCBpZiBkb2N0eXBlIGhhcwotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIGFscmVhZHkgYmVlbiB1c2VkIHdpdGggYSBkaWZmZXJlbnQgZG9jdW1lbnQuCi0gICAgICogQHNpbmNlIFdELURPTS1MZXZlbC0yLTE5OTkwOTIzCi0gICAgICovCi0gICAgcHVibGljIERvY3VtZW50ICAgICAgICAgICBjcmVhdGVEb2N1bWVudChTdHJpbmcgbmFtZXNwYWNlVVJJLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHF1YWxpZmllZE5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEb2N1bWVudFR5cGUgZG9jdHlwZSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGlmKG5hbWVzcGFjZVVSSSA9PSBudWxsICYmIHF1YWxpZmllZE5hbWUgPT0gbnVsbCAmJiBkb2N0eXBlID09IG51bGwpewotICAgICAgICAvL2lmIG5hbWVzcGFjZVVSSSwgcXVhbGlmaWVkTmFtZSBhbmQgZG9jdHlwZSBhcmUgbnVsbCwgcmV0dXJuZWQgZG9jdW1lbnQgaXMgZW1wdHkgd2l0aAotICAgICAgICAvL25vIGRvY3VtZW50IGVsZW1lbnQKLSAgICAgICAgICAgIHJldHVybiBuZXcgRG9jdW1lbnRJbXBsKCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoZG9jdHlwZSAhPSBudWxsICYmIGRvY3R5cGUuZ2V0T3duZXJEb2N1bWVudCgpICE9IG51bGwpIHsKLSAgICAgICAgICAgIFN0cmluZyBtc2cgPSBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiV1JPTkdfRE9DVU1FTlRfRVJSIiwgbnVsbCk7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5XUk9OR19ET0NVTUVOVF9FUlIsIG1zZyk7Ci0gICAgICAgIH0KLSAgICAgICAgRG9jdW1lbnRJbXBsIGRvYyA9IG5ldyBEb2N1bWVudEltcGwoZG9jdHlwZSk7Ci0gICAgICAgIEVsZW1lbnQgZSA9IGRvYy5jcmVhdGVFbGVtZW50TlMoIG5hbWVzcGFjZVVSSSwgcXVhbGlmaWVkTmFtZSk7Ci0gICAgICAgIGRvYy5hcHBlbmRDaGlsZChlKTsKLSAgICAgICAgcmV0dXJuIGRvYzsKLSAgICB9Ci0KLQotfSAvLyBjbGFzcyBET01JbXBsZW1lbnRhdGlvbkltcGwKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9ET01JbXBsZW1lbnRhdGlvbkxpc3RJbXBsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vRE9NSW1wbGVtZW50YXRpb25MaXN0SW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxNTc5MWEzLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9ET01JbXBsZW1lbnRhdGlvbkxpc3RJbXBsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3NSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5kb207Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotaW1wb3J0IG9yZy53M2MuZG9tLkRPTUltcGxlbWVudGF0aW9uTGlzdDsKLWltcG9ydCBvcmcudzNjLmRvbS5ET01JbXBsZW1lbnRhdGlvbjsKLQotLyoqCi0gKiA8cD5UaGlzIGNsYXNzIGltcGxlbWVudHMgdGhlIERPTSBMZXZlbCAzIENvcmUgaW50ZXJmYWNlIERPTUltcGxlbWVudGF0aW9uTGlzdC48L3A+Ci0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgTmVpbCBEZWxpbWEsIElCTQotICogQHNpbmNlIERPTSBMZXZlbCAzIENvcmUKLSAqLwotcHVibGljIGNsYXNzIERPTUltcGxlbWVudGF0aW9uTGlzdEltcGwgaW1wbGVtZW50cyBET01JbXBsZW1lbnRhdGlvbkxpc3QgewotCi0gICAgLy9BIGNvbGxlY3Rpb24gb2YgRE9NSW1wbGVtZW50YXRpb25zCi0gICAgcHJpdmF0ZSBWZWN0b3IgZkltcGxlbWVudGF0aW9uczsKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdCBhbiBlbXB0eSBsaXN0IG9mIERPTUltcGxlbWVudGF0aW9ucwotICAgICAqLwotICAgIHB1YmxpYyBET01JbXBsZW1lbnRhdGlvbkxpc3RJbXBsKCkgewotICAgICAgICBmSW1wbGVtZW50YXRpb25zID0gbmV3IFZlY3RvcigpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdCBhbiBlbXB0eSBsaXN0IG9mIERPTUltcGxlbWVudGF0aW9ucwotICAgICAqLwotICAgIHB1YmxpYyBET01JbXBsZW1lbnRhdGlvbkxpc3RJbXBsKFZlY3RvciBwYXJhbXMpIHsKLSAgICAgICAgZkltcGxlbWVudGF0aW9ucyA9IHBhcmFtczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBpbmRleHRoIGl0ZW0gaW4gdGhlIGNvbGxlY3Rpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBET01JbXBsZW1ldGF0aW9uIGZyb20gdGhlIGxpc3QgdG8gcmV0dXJuLgotICAgICAqLwotICAgIHB1YmxpYyBET01JbXBsZW1lbnRhdGlvbiBpdGVtKGludCBpbmRleCkgewotICAgICAgICB0cnkgewotICAgICAgICAgICAgcmV0dXJuIChET01JbXBsZW1lbnRhdGlvbikgZkltcGxlbWVudGF0aW9ucy5lbGVtZW50QXQoaW5kZXgpOwotICAgICAgICB9IGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgRE9NSW1wbGVtZW50YXRpb25zIGluIHRoZSBsaXN0LgotICAgICAqCi0gICAgICogQHJldHVybiBBbiBpbnRlZ2VyIGluZGljYXRpbmcgdGhlIG51bWJlciBvZiBET01JbXBsZW1lbnRhdGlvbnMuCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRMZW5ndGgoKSB7Ci0gICAgICAgIHJldHVybiBmSW1wbGVtZW50YXRpb25zLnNpemUoKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vRE9NSW1wbGVtZW50YXRpb25Tb3VyY2VJbXBsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vRE9NSW1wbGVtZW50YXRpb25Tb3VyY2VJbXBsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDZjMmE5YjcuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL0RPTUltcGxlbWVudGF0aW9uU291cmNlSW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTM2ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEsIDIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5kb207Ci0KLWltcG9ydCBqYXZhLnV0aWwuU3RyaW5nVG9rZW5pemVyOwotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci1pbXBvcnQgb3JnLnczYy5kb20uRE9NSW1wbGVtZW50YXRpb25MaXN0OwotaW1wb3J0IG9yZy53M2MuZG9tLkRPTUltcGxlbWVudGF0aW9uU291cmNlOwotaW1wb3J0IG9yZy53M2MuZG9tLkRPTUltcGxlbWVudGF0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tLkRPTUltcGxlbWVudGF0aW9uTGlzdEltcGw7Ci0KLS8qKgotICogU3VwcGx5IG9uZSB0aGUgcmlnaHQgaW1wbGVtZW50YXRpb24sIGJhc2VkIHVwb24gcmVxdWVzdGVkIGZlYXR1cmVzLiBFYWNoCi0gKiBpbXBsZW1lbnRlZCA8Y29kZT5ET01JbXBsZW1lbnRhdGlvblNvdXJjZTwvY29kZT4gb2JqZWN0IGlzIGxpc3RlZCBpbiB0aGUKLSAqIGJpbmRpbmctc3BlY2lmaWMgbGlzdCBvZiBhdmFpbGFibGUgc291cmNlcyBzbyB0aGF0IGl0cwotICogPGNvZGU+RE9NSW1wbGVtZW50YXRpb248L2NvZGU+IG9iamVjdHMgYXJlIG1hZGUgYXZhaWxhYmxlLgotICoKLSAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy1ET00tTGV2ZWwtMy1Db3JlLTIwMDQwNDA3L2NvcmUuaHRtbCNET01JbXBsZW1lbnRhdGlvblNvdXJjZSc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDMgQ29yZSBTcGVjaWZpY2F0aW9uPC9hPi4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICovCi1wdWJsaWMgY2xhc3MgRE9NSW1wbGVtZW50YXRpb25Tb3VyY2VJbXBsCi0gICAgaW1wbGVtZW50cyBET01JbXBsZW1lbnRhdGlvblNvdXJjZSB7Ci0KLSAgICAvKioKLSAgICAgKiBBIG1ldGhvZCB0byByZXF1ZXN0IGEgRE9NIGltcGxlbWVudGF0aW9uLgotICAgICAqIEBwYXJhbSBmZWF0dXJlcyBBIHN0cmluZyB0aGF0IHNwZWNpZmllcyB3aGljaCBmZWF0dXJlcyBhcmUgcmVxdWlyZWQuCi0gICAgICogICBUaGlzIGlzIGEgc3BhY2Ugc2VwYXJhdGVkIGxpc3QgaW4gd2hpY2ggZWFjaCBmZWF0dXJlIGlzIHNwZWNpZmllZAotICAgICAqICAgYnkgaXRzIG5hbWUgb3B0aW9uYWxseSBmb2xsb3dlZCBieSBhIHNwYWNlIGFuZCBhIHZlcnNpb24gbnVtYmVyLgotICAgICAqICAgVGhpcyBpcyBzb21ldGhpbmcgbGlrZTogIlhNTCAxLjAgVHJhdmVyc2FsIEV2ZW50cyAyLjAiCi0gICAgICogQHJldHVybiBBbiBpbXBsZW1lbnRhdGlvbiB0aGF0IGhhcyB0aGUgZGVzaXJlZCBmZWF0dXJlcywgb3IKLSAgICAgKiAgIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoaXMgc291cmNlIGhhcyBub25lLgotICAgICAqLwotICAgIHB1YmxpYyBET01JbXBsZW1lbnRhdGlvbiBnZXRET01JbXBsZW1lbnRhdGlvbihTdHJpbmcgZmVhdHVyZXMpIHsKLSAgICAgICAgLy8gZmlyc3QgY2hlY2sgd2hldGhlciB0aGUgQ29yZURPTUltcGxlbWVudGF0aW9uIHdvdWxkIGRvCi0gICAgICAgIERPTUltcGxlbWVudGF0aW9uIGltcGwgPQotICAgICAgICAgICAgQ29yZURPTUltcGxlbWVudGF0aW9uSW1wbC5nZXRET01JbXBsZW1lbnRhdGlvbigpOwotICAgICAgICBpZiAodGVzdEltcGwoaW1wbCwgZmVhdHVyZXMpKSB7Ci0gICAgICAgICAgICByZXR1cm4gaW1wbDsKLSAgICAgICAgfQotICAgICAgICAvLyBpZiBub3QgdHJ5IHRoZSBET01JbXBsZW1lbnRhdGlvbgotICAgICAgICBpbXBsID0gRE9NSW1wbGVtZW50YXRpb25JbXBsLmdldERPTUltcGxlbWVudGF0aW9uKCk7Ci0gICAgICAgIGlmICh0ZXN0SW1wbChpbXBsLCBmZWF0dXJlcykpIHsKLSAgICAgICAgICAgIHJldHVybiBpbXBsOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQSBtZXRob2QgdG8gcmVxdWVzdCBhIGxpc3Qgb2YgRE9NIGltcGxlbWVudGF0aW9ucyB0aGF0IHN1cHBvcnQgdGhlCi0gICAgICogc3BlY2lmaWVkIGZlYXR1cmVzIGFuZCB2ZXJzaW9ucywgYXMgc3BlY2lmaWVkIGluIC4KLSAgICAgKiBAcGFyYW0gZmVhdHVyZXMgQSBzdHJpbmcgdGhhdCBzcGVjaWZpZXMgd2hpY2ggZmVhdHVyZXMgYW5kIHZlcnNpb25zCi0gICAgICogICBhcmUgcmVxdWlyZWQuIFRoaXMgaXMgYSBzcGFjZSBzZXBhcmF0ZWQgbGlzdCBpbiB3aGljaCBlYWNoIGZlYXR1cmUKLSAgICAgKiAgIGlzIHNwZWNpZmllZCBieSBpdHMgbmFtZSBvcHRpb25hbGx5IGZvbGxvd2VkIGJ5IGEgc3BhY2UgYW5kIGEKLSAgICAgKiAgIHZlcnNpb24gbnVtYmVyLiBUaGlzIGlzIHNvbWV0aGluZyBsaWtlOiAiWE1MIDMuMCBUcmF2ZXJzYWwgK0V2ZW50cwotICAgICAqICAgMi4wIgotICAgICAqIEByZXR1cm4gQSBsaXN0IG9mIERPTSBpbXBsZW1lbnRhdGlvbnMgdGhhdCBzdXBwb3J0IHRoZSBkZXNpcmVkCi0gICAgICogICBmZWF0dXJlcy4KLSAgICAgKi8KLSAgICBwdWJsaWMgRE9NSW1wbGVtZW50YXRpb25MaXN0IGdldERPTUltcGxlbWVudGF0aW9uTGlzdChTdHJpbmcgZmVhdHVyZXMpIHsKLSAgICAgICAgLy8gZmlyc3QgY2hlY2sgd2hldGhlciB0aGUgQ29yZURPTUltcGxlbWVudGF0aW9uIHdvdWxkIGRvCi0gICAgICAgIERPTUltcGxlbWVudGF0aW9uIGltcGwgPSBDb3JlRE9NSW1wbGVtZW50YXRpb25JbXBsLmdldERPTUltcGxlbWVudGF0aW9uKCk7Ci0gICAgICAgICAgICAgICAgZmluYWwgVmVjdG9yIGltcGxlbWVudGF0aW9ucyA9IG5ldyBWZWN0b3IoKTsKLSAgICAgICAgaWYgKHRlc3RJbXBsKGltcGwsIGZlYXR1cmVzKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgaW1wbGVtZW50YXRpb25zLmFkZEVsZW1lbnQoaW1wbCk7Ci0gICAgICAgIH0KLSAgICAgICAgaW1wbCA9IERPTUltcGxlbWVudGF0aW9uSW1wbC5nZXRET01JbXBsZW1lbnRhdGlvbigpOwotICAgICAgICBpZiAodGVzdEltcGwoaW1wbCwgZmVhdHVyZXMpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpbXBsZW1lbnRhdGlvbnMuYWRkRWxlbWVudChpbXBsKTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBuZXcgRE9NSW1wbGVtZW50YXRpb25MaXN0SW1wbChpbXBsZW1lbnRhdGlvbnMpOwotICAgIH0KLQotICAgIGJvb2xlYW4gdGVzdEltcGwoRE9NSW1wbGVtZW50YXRpb24gaW1wbCwgU3RyaW5nIGZlYXR1cmVzKSB7Ci0KLSAgICAgICAgU3RyaW5nVG9rZW5pemVyIHN0ID0gbmV3IFN0cmluZ1Rva2VuaXplcihmZWF0dXJlcyk7Ci0gICAgICAgIFN0cmluZyBmZWF0dXJlID0gbnVsbDsKLSAgICAgICAgU3RyaW5nIHZlcnNpb24gPSBudWxsOwotCi0gICAgICAgIGlmIChzdC5oYXNNb3JlVG9rZW5zKCkpIHsKLSAgICAgICAgICAgZmVhdHVyZSA9IHN0Lm5leHRUb2tlbigpOwotICAgICAgICB9Ci0gICAgICAgIHdoaWxlIChmZWF0dXJlICE9IG51bGwpIHsKLSAgICAgICAgICAgYm9vbGVhbiBpc1ZlcnNpb24gPSBmYWxzZTsKLSAgICAgICAgICAgaWYgKHN0Lmhhc01vcmVUb2tlbnMoKSkgewotICAgICAgICAgICAgICAgY2hhciBjOwotICAgICAgICAgICAgICAgdmVyc2lvbiA9IHN0Lm5leHRUb2tlbigpOwotICAgICAgICAgICAgICAgYyA9IHZlcnNpb24uY2hhckF0KDApOwotICAgICAgICAgICAgICAgc3dpdGNoIChjKSB7Ci0gICAgICAgICAgICAgICBjYXNlICcwJzogY2FzZSAnMSc6IGNhc2UgJzInOiBjYXNlICczJzogY2FzZSAnNCc6Ci0gICAgICAgICAgICAgICBjYXNlICc1JzogY2FzZSAnNic6IGNhc2UgJzcnOiBjYXNlICc4JzogY2FzZSAnOSc6Ci0gICAgICAgICAgICAgICAgICAgaXNWZXJzaW9uID0gdHJ1ZTsKLSAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgIHZlcnNpb24gPSBudWxsOwotICAgICAgICAgICB9Ci0gICAgICAgICAgIGlmIChpc1ZlcnNpb24pIHsKLSAgICAgICAgICAgICAgIGlmICghaW1wbC5oYXNGZWF0dXJlKGZlYXR1cmUsIHZlcnNpb24pKSB7Ci0gICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgaWYgKHN0Lmhhc01vcmVUb2tlbnMoKSkgewotICAgICAgICAgICAgICAgICAgIGZlYXR1cmUgPSBzdC5uZXh0VG9rZW4oKTsKLSAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgZmVhdHVyZSA9IG51bGw7Ci0gICAgICAgICAgICAgICB9Ci0gICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICBpZiAoIWltcGwuaGFzRmVhdHVyZShmZWF0dXJlLCBudWxsKSkgewotICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgIGZlYXR1cmUgPSB2ZXJzaW9uOwotICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL0RPTUlucHV0SW1wbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL0RPTUlucHV0SW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiYjZhYmY5Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9ET01JbnB1dEltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDM5MSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLCAyMDAyLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tOwotCi1pbXBvcnQgb3JnLnczYy5kb20ubHMuTFNJbnB1dDsKLQotaW1wb3J0IGphdmEuaW8uUmVhZGVyOwotaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07Ci0KLS8qKgotICogVGhpcyBDbGFzcyA8Y29kZT5ET01JbnB1dEltcGw8L2NvZGU+IHJlcHJlc2VudHMgYSBzaW5nbGUgaW5wdXQgc291cmNlIGZvciBhbiBYTUwgZW50aXR5LgotICogPHA+IFRoaXMgQ2xhc3MgYWxsb3dzIGFuIGFwcGxpY2F0aW9uIHRvIGVuY2Fwc3VsYXRlIGluZm9ybWF0aW9uIGFib3V0Ci0gKiBhbiBpbnB1dCBzb3VyY2UgaW4gYSBzaW5nbGUgb2JqZWN0LCB3aGljaCBtYXkgaW5jbHVkZSBhIHB1YmxpYwotICogaWRlbnRpZmllciwgYSBzeXN0ZW0gaWRlbnRpZmllciwgYSBieXRlIHN0cmVhbSAocG9zc2libHkgd2l0aCBhIHNwZWNpZmllZAotICogZW5jb2RpbmcpLCBhbmQvb3IgYSBjaGFyYWN0ZXIgc3RyZWFtLgotICogPHA+IFRoZSBleGFjdCBkZWZpbml0aW9ucyBvZiBhIGJ5dGUgc3RyZWFtIGFuZCBhIGNoYXJhY3RlciBzdHJlYW0gYXJlCi0gKiBiaW5kaW5nIGRlcGVuZGVudC4KLSAqIDxwPiBUaGVyZSBhcmUgdHdvIHBsYWNlcyB0aGF0IHRoZSBhcHBsaWNhdGlvbiB3aWxsIGRlbGl2ZXIgdGhpcyBpbnB1dAotICogc291cmNlIHRvIHRoZSBwYXJzZXI6IGFzIHRoZSBhcmd1bWVudCB0byB0aGUgPGNvZGU+cGFyc2U8L2NvZGU+IG1ldGhvZCwKLSAqIG9yIGFzIHRoZSByZXR1cm4gdmFsdWUgb2YgdGhlIDxjb2RlPkRPTVJlc291cmNlUmVzb2x2ZXIucmVzb2x2ZUVudGl0eTwvY29kZT4KLSAqICBtZXRob2QuCi0gKiA8cD4gVGhlIDxjb2RlPkRPTVBhcnNlcjwvY29kZT4gd2lsbCB1c2UgdGhlIDxjb2RlPkxTSW5wdXQ8L2NvZGU+Ci0gKiBvYmplY3QgdG8gZGV0ZXJtaW5lIGhvdyB0byByZWFkIFhNTCBpbnB1dC4gSWYgdGhlcmUgaXMgYSBjaGFyYWN0ZXIgc3RyZWFtCi0gKiBhdmFpbGFibGUsIHRoZSBwYXJzZXIgd2lsbCByZWFkIHRoYXQgc3RyZWFtIGRpcmVjdGx5OyBpZiBub3QsIHRoZSBwYXJzZXIKLSAqIHdpbGwgdXNlIGEgYnl0ZSBzdHJlYW0sIGlmIGF2YWlsYWJsZTsgaWYgbmVpdGhlciBhIGNoYXJhY3RlciBzdHJlYW0gbm9yIGEKLSAqIGJ5dGUgc3RyZWFtIGlzIGF2YWlsYWJsZSwgdGhlIHBhcnNlciB3aWxsIGF0dGVtcHQgdG8gb3BlbiBhIFVSSQotICogY29ubmVjdGlvbiB0byB0aGUgcmVzb3VyY2UgaWRlbnRpZmllZCBieSB0aGUgc3lzdGVtIGlkZW50aWZpZXIuCi0gKiA8cD4gQW4gPGNvZGU+TFNJbnB1dDwvY29kZT4gb2JqZWN0IGJlbG9uZ3MgdG8gdGhlIGFwcGxpY2F0aW9uOiB0aGUKLSAqIHBhcnNlciBzaGFsbCBuZXZlciBtb2RpZnkgaXQgaW4gYW55IHdheSAoaXQgbWF5IG1vZGlmeSBhIGNvcHkgaWYKLSAqIG5lY2Vzc2FyeSkuICBFdmVudGhvdWdoIGFsbCBhdHRyaWJ1dGVzIGluIHRoaXMgaW50ZXJmYWNlIGFyZSB3cml0YWJsZSB0aGUKLSAqIERPTSBpbXBsZW1lbnRhdGlvbiBpcyBleHBlY3RlZCB0byBuZXZlciBtdXRhdGUgYSBMU0lucHV0LgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDEvV0QtRE9NLUxldmVsLTMtQVNMUy0yMDAxMTAyNSc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDMgQWJzdHJhY3QgU2NoZW1hcyBhbmQgTG9hZAotYW5kIFNhdmUgU3BlY2lmaWNhdGlvbjwvYT4uCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgR29wYWwgU2hhcm1hLCBTVU4gTWljcm9zeXN0ZW1zIEluYy4KLSAqLwotCi0vLyBSRVZJU0lUOgotLy8gMS4gaXQgc2hvdWxkIGJlIHBvc3NpYmxlIHRvIGRvIHRoZSBmb2xsb3dpbmcKLS8vIERPTUlucHV0SW1wbCBleHRlbmRzIFhNTElucHV0U291cmNlIGltcGxlbWVudHMgTFNJbnB1dAotLy8gMi4gd2UgcHJvYmFibHkgbmVlZCBvbmx5IHRoZSBkZWZhdWx0IGNvbnN0cnVjdG9yLiAgLS0gZWwKLQotcHVibGljIGNsYXNzIERPTUlucHV0SW1wbCBpbXBsZW1lbnRzIExTSW5wdXQgewotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIERhdGEKLSAgICAgICAgLy8KLQotICAgICAgICBwcm90ZWN0ZWQgU3RyaW5nIGZQdWJsaWNJZCA9IG51bGw7Ci0gICAgICAgIHByb3RlY3RlZCBTdHJpbmcgZlN5c3RlbUlkID0gbnVsbDsKLSAgICAgICAgcHJvdGVjdGVkIFN0cmluZyBmQmFzZVN5c3RlbUlkID0gbnVsbDsKLQotICAgICAgICBwcm90ZWN0ZWQgSW5wdXRTdHJlYW0gZkJ5dGVTdHJlYW0gPSBudWxsOwotICAgICAgICBwcm90ZWN0ZWQgUmVhZGVyIGZDaGFyU3RyZWFtICAgID0gbnVsbDsKLSAgICAgICAgcHJvdGVjdGVkIFN0cmluZyBmRGF0YSA9IG51bGw7Ci0KLSAgICAgICAgcHJvdGVjdGVkIFN0cmluZyBmRW5jb2RpbmcgPSBudWxsOwotCi0gICAgICAgIHByb3RlY3RlZCBib29sZWFuIGZDZXJ0aWZpZWRUZXh0ID0gZmFsc2U7Ci0KLSAgIC8qKgotICAgICAqIERlZmF1bHQgQ29uc3RydWN0b3IsIGNvbnN0cnVjdHMgYW4gaW5wdXQgc291cmNlCi0gICAgICoKLSAgICAgKgotICAgICAqLwotICAgICBwdWJsaWMgRE9NSW5wdXRJbXBsKCkge30KLQotICAgLyoqCi0gICAgICogQ29uc3RydWN0cyBhbiBpbnB1dCBzb3VyY2UgZnJvbSBqdXN0IHRoZSBwdWJsaWMgYW5kIHN5c3RlbQotICAgICAqIGlkZW50aWZpZXJzLCBsZWF2aW5nIHJlc29sdXRpb24gb2YgdGhlIGVudGl0eSBhbmQgb3BlbmluZyBvZgotICAgICAqIHRoZSBpbnB1dCBzdHJlYW0gdXAgdG8gdGhlIGNhbGxlci4KLSAgICAgKgotICAgICAqIEBwYXJhbSBwdWJsaWNJZCAgICAgVGhlIHB1YmxpYyBpZGVudGlmaWVyLCBpZiBrbm93bi4KLSAgICAgKiBAcGFyYW0gc3lzdGVtSWQgICAgIFRoZSBzeXN0ZW0gaWRlbnRpZmllci4gVGhpcyB2YWx1ZSBzaG91bGQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgIGFsd2F5cyBiZSBzZXQsIGlmIHBvc3NpYmxlLCBhbmQgY2FuIGJlCi0gICAgICogICAgICAgICAgICAgICAgICAgICByZWxhdGl2ZSBvciBhYnNvbHV0ZS4gSWYgdGhlIHN5c3RlbSBpZGVudGlmaWVyCi0gICAgICogICAgICAgICAgICAgICAgICAgICBpcyByZWxhdGl2ZSwgdGhlbiB0aGUgYmFzZSBzeXN0ZW0gaWRlbnRpZmllcgotICAgICAqICAgICAgICAgICAgICAgICAgICAgc2hvdWxkIGJlIHNldC4KLSAgICAgKiBAcGFyYW0gYmFzZVN5c3RlbUlkIFRoZSBiYXNlIHN5c3RlbSBpZGVudGlmaWVyLiBUaGlzIHZhbHVlIHNob3VsZAotICAgICAqICAgICAgICAgICAgICAgICAgICAgYWx3YXlzIGJlIHNldCB0byB0aGUgZnVsbHkgZXhwYW5kZWQgVVJJIG9mIHRoZQotICAgICAqICAgICAgICAgICAgICAgICAgICAgYmFzZSBzeXN0ZW0gaWRlbnRpZmllciwgaWYgcG9zc2libGUuCi0gICAgICovCi0KLSAgICBwdWJsaWMgRE9NSW5wdXRJbXBsKFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkLAotICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgYmFzZVN5c3RlbUlkKSB7Ci0KLSAgICAgICAgICAgICAgICBmUHVibGljSWQgPSBwdWJsaWNJZDsKLSAgICAgICAgICAgICAgICBmU3lzdGVtSWQgPSBzeXN0ZW1JZDsKLSAgICAgICAgICAgICAgICBmQmFzZVN5c3RlbUlkID0gYmFzZVN5c3RlbUlkOwotCi0gICAgfSAvLyBET01JbnB1dEltcGwoU3RyaW5nLFN0cmluZyxTdHJpbmcpCi0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RzIGFuIGlucHV0IHNvdXJjZSBmcm9tIGEgYnl0ZSBzdHJlYW0uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcHVibGljSWQgICAgIFRoZSBwdWJsaWMgaWRlbnRpZmllciwgaWYga25vd24uCi0gICAgICogQHBhcmFtIHN5c3RlbUlkICAgICBUaGUgc3lzdGVtIGlkZW50aWZpZXIuIFRoaXMgdmFsdWUgc2hvdWxkCi0gICAgICogICAgICAgICAgICAgICAgICAgICBhbHdheXMgYmUgc2V0LCBpZiBwb3NzaWJsZSwgYW5kIGNhbiBiZQotICAgICAqICAgICAgICAgICAgICAgICAgICAgcmVsYXRpdmUgb3IgYWJzb2x1dGUuIElmIHRoZSBzeXN0ZW0gaWRlbnRpZmllcgotICAgICAqICAgICAgICAgICAgICAgICAgICAgaXMgcmVsYXRpdmUsIHRoZW4gdGhlIGJhc2Ugc3lzdGVtIGlkZW50aWZpZXIKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgIHNob3VsZCBiZSBzZXQuCi0gICAgICogQHBhcmFtIGJhc2VTeXN0ZW1JZCBUaGUgYmFzZSBzeXN0ZW0gaWRlbnRpZmllci4gVGhpcyB2YWx1ZSBzaG91bGQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgIGFsd2F5cyBiZSBzZXQgdG8gdGhlIGZ1bGx5IGV4cGFuZGVkIFVSSSBvZiB0aGUKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgIGJhc2Ugc3lzdGVtIGlkZW50aWZpZXIsIGlmIHBvc3NpYmxlLgotICAgICAqIEBwYXJhbSBieXRlU3RyZWFtICAgVGhlIGJ5dGUgc3RyZWFtLgotICAgICAqIEBwYXJhbSBlbmNvZGluZyAgICAgVGhlIGVuY29kaW5nIG9mIHRoZSBieXRlIHN0cmVhbSwgaWYga25vd24uCi0gICAgICovCi0KLSAgICBwdWJsaWMgRE9NSW5wdXRJbXBsKFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkLAotICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgYmFzZVN5c3RlbUlkLCBJbnB1dFN0cmVhbSBieXRlU3RyZWFtLAotICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgZW5jb2RpbmcpIHsKLQotICAgICAgICAgICAgICAgIGZQdWJsaWNJZCA9IHB1YmxpY0lkOwotICAgICAgICAgICAgICAgIGZTeXN0ZW1JZCA9IHN5c3RlbUlkOwotICAgICAgICAgICAgICAgIGZCYXNlU3lzdGVtSWQgPSBiYXNlU3lzdGVtSWQ7Ci0gICAgICAgICAgICAgICAgZkJ5dGVTdHJlYW0gPSBieXRlU3RyZWFtOwotICAgICAgICAgICAgICAgIGZFbmNvZGluZyA9IGVuY29kaW5nOwotCi0gICAgfSAvLyBET01JbnB1dEltcGwoU3RyaW5nLFN0cmluZyxTdHJpbmcsSW5wdXRTdHJlYW0sU3RyaW5nKQotCi0gICAvKioKLSAgICAgKiBDb25zdHJ1Y3RzIGFuIGlucHV0IHNvdXJjZSBmcm9tIGEgY2hhcmFjdGVyIHN0cmVhbS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBwdWJsaWNJZCAgICAgVGhlIHB1YmxpYyBpZGVudGlmaWVyLCBpZiBrbm93bi4KLSAgICAgKiBAcGFyYW0gc3lzdGVtSWQgICAgIFRoZSBzeXN0ZW0gaWRlbnRpZmllci4gVGhpcyB2YWx1ZSBzaG91bGQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgIGFsd2F5cyBiZSBzZXQsIGlmIHBvc3NpYmxlLCBhbmQgY2FuIGJlCi0gICAgICogICAgICAgICAgICAgICAgICAgICByZWxhdGl2ZSBvciBhYnNvbHV0ZS4gSWYgdGhlIHN5c3RlbSBpZGVudGlmaWVyCi0gICAgICogICAgICAgICAgICAgICAgICAgICBpcyByZWxhdGl2ZSwgdGhlbiB0aGUgYmFzZSBzeXN0ZW0gaWRlbnRpZmllcgotICAgICAqICAgICAgICAgICAgICAgICAgICAgc2hvdWxkIGJlIHNldC4KLSAgICAgKiBAcGFyYW0gYmFzZVN5c3RlbUlkIFRoZSBiYXNlIHN5c3RlbSBpZGVudGlmaWVyLiBUaGlzIHZhbHVlIHNob3VsZAotICAgICAqICAgICAgICAgICAgICAgICAgICAgYWx3YXlzIGJlIHNldCB0byB0aGUgZnVsbHkgZXhwYW5kZWQgVVJJIG9mIHRoZQotICAgICAqICAgICAgICAgICAgICAgICAgICAgYmFzZSBzeXN0ZW0gaWRlbnRpZmllciwgaWYgcG9zc2libGUuCi0gICAgICogQHBhcmFtIGNoYXJTdHJlYW0gICBUaGUgY2hhcmFjdGVyIHN0cmVhbS4KLSAgICAgKiBAcGFyYW0gZW5jb2RpbmcgICAgIFRoZSBvcmlnaW5hbCBlbmNvZGluZyBvZiB0aGUgYnl0ZSBzdHJlYW0KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgIHVzZWQgYnkgdGhlIHJlYWRlciwgaWYga25vd24uCi0gICAgICovCi0KLSAgICAgcHVibGljIERPTUlucHV0SW1wbChTdHJpbmcgcHVibGljSWQsIFN0cmluZyBzeXN0ZW1JZCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGJhc2VTeXN0ZW1JZCwgUmVhZGVyIGNoYXJTdHJlYW0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBlbmNvZGluZykgewotCi0gICAgICAgICAgICAgICAgZlB1YmxpY0lkID0gcHVibGljSWQ7Ci0gICAgICAgICAgICAgICAgZlN5c3RlbUlkID0gc3lzdGVtSWQ7Ci0gICAgICAgICAgICAgICAgZkJhc2VTeXN0ZW1JZCA9IGJhc2VTeXN0ZW1JZDsKLSAgICAgICAgICAgICAgICBmQ2hhclN0cmVhbSA9IGNoYXJTdHJlYW07Ci0gICAgICAgICAgICAgICAgZkVuY29kaW5nID0gZW5jb2Rpbmc7Ci0KLSAgICAgfSAvLyBET01JbnB1dEltcGwoU3RyaW5nLFN0cmluZyxTdHJpbmcsUmVhZGVyLFN0cmluZykKLQotICAgLyoqCi0gICAgICogQ29uc3RydWN0cyBhbiBpbnB1dCBzb3VyY2UgZnJvbSBhIFN0cmluZy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBwdWJsaWNJZCAgICAgVGhlIHB1YmxpYyBpZGVudGlmaWVyLCBpZiBrbm93bi4KLSAgICAgKiBAcGFyYW0gc3lzdGVtSWQgICAgIFRoZSBzeXN0ZW0gaWRlbnRpZmllci4gVGhpcyB2YWx1ZSBzaG91bGQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgIGFsd2F5cyBiZSBzZXQsIGlmIHBvc3NpYmxlLCBhbmQgY2FuIGJlCi0gICAgICogICAgICAgICAgICAgICAgICAgICByZWxhdGl2ZSBvciBhYnNvbHV0ZS4gSWYgdGhlIHN5c3RlbSBpZGVudGlmaWVyCi0gICAgICogICAgICAgICAgICAgICAgICAgICBpcyByZWxhdGl2ZSwgdGhlbiB0aGUgYmFzZSBzeXN0ZW0gaWRlbnRpZmllcgotICAgICAqICAgICAgICAgICAgICAgICAgICAgc2hvdWxkIGJlIHNldC4KLSAgICAgKiBAcGFyYW0gYmFzZVN5c3RlbUlkIFRoZSBiYXNlIHN5c3RlbSBpZGVudGlmaWVyLiBUaGlzIHZhbHVlIHNob3VsZAotICAgICAqICAgICAgICAgICAgICAgICAgICAgYWx3YXlzIGJlIHNldCB0byB0aGUgZnVsbHkgZXhwYW5kZWQgVVJJIG9mIHRoZQotICAgICAqICAgICAgICAgICAgICAgICAgICAgYmFzZSBzeXN0ZW0gaWRlbnRpZmllciwgaWYgcG9zc2libGUuCi0gICAgICogQHBhcmFtIGRhdGEgICAgICAgICAgICAgICAgIFRoZSBTdHJpbmcgRGF0YS4KLSAgICAgKiBAcGFyYW0gZW5jb2RpbmcgICAgIFRoZSBvcmlnaW5hbCBlbmNvZGluZyBvZiB0aGUgYnl0ZSBzdHJlYW0KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgIHVzZWQgYnkgdGhlIHJlYWRlciwgaWYga25vd24uCi0gICAgICovCi0KLSAgICAgcHVibGljIERPTUlucHV0SW1wbChTdHJpbmcgcHVibGljSWQsIFN0cmluZyBzeXN0ZW1JZCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGJhc2VTeXN0ZW1JZCwgU3RyaW5nIGRhdGEsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBlbmNvZGluZykgewotICAgICAgICAgICAgICAgIGZQdWJsaWNJZCA9IHB1YmxpY0lkOwotICAgICAgICAgICAgICAgIGZTeXN0ZW1JZCA9IHN5c3RlbUlkOwotICAgICAgICAgICAgICAgIGZCYXNlU3lzdGVtSWQgPSBiYXNlU3lzdGVtSWQ7Ci0gICAgICAgICAgICAgICAgZkRhdGEgPSBkYXRhOwotICAgICAgICAgICAgICAgIGZFbmNvZGluZyA9IGVuY29kaW5nOwotICAgICB9IC8vIERPTUlucHV0SW1wbChTdHJpbmcsU3RyaW5nLFN0cmluZyxTdHJpbmcsU3RyaW5nKQotCi0gICAvKioKLSAgICAgKiBBbiBhdHRyaWJ1dGUgb2YgYSBsYW5ndWFnZS1iaW5kaW5nIGRlcGVuZGVudCB0eXBlIHRoYXQgcmVwcmVzZW50cyBhCi0gICAgICogc3RyZWFtIG9mIGJ5dGVzLgotICAgICAqIDxicj5UaGUgcGFyc2VyIHdpbGwgaWdub3JlIHRoaXMgaWYgdGhlcmUgaXMgYWxzbyBhIGNoYXJhY3RlciBzdHJlYW0KLSAgICAgKiBzcGVjaWZpZWQsIGJ1dCBpdCB3aWxsIHVzZSBhIGJ5dGUgc3RyZWFtIGluIHByZWZlcmVuY2UgdG8gb3BlbmluZyBhCi0gICAgICogVVJJIGNvbm5lY3Rpb24gaXRzZWxmLgotICAgICAqIDxicj5JZiB0aGUgYXBwbGljYXRpb24ga25vd3MgdGhlIGNoYXJhY3RlciBlbmNvZGluZyBvZiB0aGUgYnl0ZSBzdHJlYW0sCi0gICAgICogaXQgc2hvdWxkIHNldCB0aGUgZW5jb2RpbmcgcHJvcGVydHkuIFNldHRpbmcgdGhlIGVuY29kaW5nIGluIHRoaXMgd2F5Ci0gICAgICogd2lsbCBvdmVycmlkZSBhbnkgZW5jb2Rpbmcgc3BlY2lmaWVkIGluIHRoZSBYTUwgZGVjbGFyYXRpb24gaXRzZWxmLgotICAgICAqLwotCi0gICAgcHVibGljIElucHV0U3RyZWFtIGdldEJ5dGVTdHJlYW0oKXsKLSAgICAgICAgcmV0dXJuIGZCeXRlU3RyZWFtOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEFuIGF0dHJpYnV0ZSBvZiBhIGxhbmd1YWdlLWJpbmRpbmcgZGVwZW5kZW50IHR5cGUgdGhhdCByZXByZXNlbnRzIGEKLSAgICAgKiBzdHJlYW0gb2YgYnl0ZXMuCi0gICAgICogPGJyPlRoZSBwYXJzZXIgd2lsbCBpZ25vcmUgdGhpcyBpZiB0aGVyZSBpcyBhbHNvIGEgY2hhcmFjdGVyIHN0cmVhbQotICAgICAqIHNwZWNpZmllZCwgYnV0IGl0IHdpbGwgdXNlIGEgYnl0ZSBzdHJlYW0gaW4gcHJlZmVyZW5jZSB0byBvcGVuaW5nIGEKLSAgICAgKiBVUkkgY29ubmVjdGlvbiBpdHNlbGYuCi0gICAgICogPGJyPklmIHRoZSBhcHBsaWNhdGlvbiBrbm93cyB0aGUgY2hhcmFjdGVyIGVuY29kaW5nIG9mIHRoZSBieXRlIHN0cmVhbSwKLSAgICAgKiBpdCBzaG91bGQgc2V0IHRoZSBlbmNvZGluZyBwcm9wZXJ0eS4gU2V0dGluZyB0aGUgZW5jb2RpbmcgaW4gdGhpcyB3YXkKLSAgICAgKiB3aWxsIG92ZXJyaWRlIGFueSBlbmNvZGluZyBzcGVjaWZpZWQgaW4gdGhlIFhNTCBkZWNsYXJhdGlvbiBpdHNlbGYuCi0gICAgICovCi0KLSAgICAgcHVibGljIHZvaWQgc2V0Qnl0ZVN0cmVhbShJbnB1dFN0cmVhbSBieXRlU3RyZWFtKXsKLSAgICAgICAgZkJ5dGVTdHJlYW0gPSBieXRlU3RyZWFtOwotICAgICB9Ci0KLSAgICAvKioKLSAgICAgKiAgQW4gYXR0cmlidXRlIG9mIGEgbGFuZ3VhZ2UtYmluZGluZyBkZXBlbmRlbnQgdHlwZSB0aGF0IHJlcHJlc2VudHMgYQotICAgICAqIHN0cmVhbSBvZiAxNi1iaXQgdW5pdHMuIEFwcGxpY2F0aW9uIG11c3QgZW5jb2RlIHRoZSBzdHJlYW0gdXNpbmcKLSAgICAgKiBVVEYtMTYgKGRlZmluZWQgaW4gIGFuZCBBbWVuZG1lbnQgMSBvZiApLgotICAgICAqIDxicj5JZiBhIGNoYXJhY3RlciBzdHJlYW0gaXMgc3BlY2lmaWVkLCB0aGUgcGFyc2VyIHdpbGwgaWdub3JlIGFueSBieXRlCi0gICAgICogc3RyZWFtIGFuZCB3aWxsIG5vdCBhdHRlbXB0IHRvIG9wZW4gYSBVUkkgY29ubmVjdGlvbiB0byB0aGUgc3lzdGVtCi0gICAgICogaWRlbnRpZmllci4KLSAgICAgKi8KLSAgICBwdWJsaWMgUmVhZGVyIGdldENoYXJhY3RlclN0cmVhbSgpewotICAgICAgICByZXR1cm4gZkNoYXJTdHJlYW07Ci0gICAgfQotICAgIC8qKgotICAgICAqICBBbiBhdHRyaWJ1dGUgb2YgYSBsYW5ndWFnZS1iaW5kaW5nIGRlcGVuZGVudCB0eXBlIHRoYXQgcmVwcmVzZW50cyBhCi0gICAgICogc3RyZWFtIG9mIDE2LWJpdCB1bml0cy4gQXBwbGljYXRpb24gbXVzdCBlbmNvZGUgdGhlIHN0cmVhbSB1c2luZwotICAgICAqIFVURi0xNiAoZGVmaW5lZCBpbiAgYW5kIEFtZW5kbWVudCAxIG9mICkuCi0gICAgICogPGJyPklmIGEgY2hhcmFjdGVyIHN0cmVhbSBpcyBzcGVjaWZpZWQsIHRoZSBwYXJzZXIgd2lsbCBpZ25vcmUgYW55IGJ5dGUKLSAgICAgKiBzdHJlYW0gYW5kIHdpbGwgbm90IGF0dGVtcHQgdG8gb3BlbiBhIFVSSSBjb25uZWN0aW9uIHRvIHRoZSBzeXN0ZW0KLSAgICAgKiBpZGVudGlmaWVyLgotICAgICAqLwotCi0gICAgIHB1YmxpYyB2b2lkIHNldENoYXJhY3RlclN0cmVhbShSZWFkZXIgY2hhcmFjdGVyU3RyZWFtKXsKLSAgICAgICAgZkNoYXJTdHJlYW0gPSBjaGFyYWN0ZXJTdHJlYW07Ci0gICAgIH0KLQotICAgIC8qKgotICAgICAqIEEgc3RyaW5nIGF0dHJpYnV0ZSB0aGF0IHJlcHJlc2VudHMgYSBzZXF1ZW5jZSBvZiAxNiBiaXQgdW5pdHMgKHV0Zi0xNgotICAgICAqIGVuY29kZWQgY2hhcmFjdGVycykuCi0gICAgICogPGJyPklmIHN0cmluZyBkYXRhIGlzIGF2YWlsYWJsZSBpbiB0aGUgaW5wdXQgc291cmNlLCB0aGUgcGFyc2VyIHdpbGwKLSAgICAgKiBpZ25vcmUgdGhlIGNoYXJhY3RlciBzdHJlYW0gYW5kIHRoZSBieXRlIHN0cmVhbSBhbmQgd2lsbCBub3QgYXR0ZW1wdAotICAgICAqIHRvIG9wZW4gYSBVUkkgY29ubmVjdGlvbiB0byB0aGUgc3lzdGVtIGlkZW50aWZpZXIuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRTdHJpbmdEYXRhKCl7Ci0gICAgICAgIHJldHVybiBmRGF0YTsKLSAgICB9Ci0KLSAgIC8qKgotICAgICAqIEEgc3RyaW5nIGF0dHJpYnV0ZSB0aGF0IHJlcHJlc2VudHMgYSBzZXF1ZW5jZSBvZiAxNiBiaXQgdW5pdHMgKHV0Zi0xNgotICAgICAqIGVuY29kZWQgY2hhcmFjdGVycykuCi0gICAgICogPGJyPklmIHN0cmluZyBkYXRhIGlzIGF2YWlsYWJsZSBpbiB0aGUgaW5wdXQgc291cmNlLCB0aGUgcGFyc2VyIHdpbGwKLSAgICAgKiBpZ25vcmUgdGhlIGNoYXJhY3RlciBzdHJlYW0gYW5kIHRoZSBieXRlIHN0cmVhbSBhbmQgd2lsbCBub3QgYXR0ZW1wdAotICAgICAqIHRvIG9wZW4gYSBVUkkgY29ubmVjdGlvbiB0byB0aGUgc3lzdGVtIGlkZW50aWZpZXIuCi0gICAgICovCi0KLSAgICAgcHVibGljIHZvaWQgc2V0U3RyaW5nRGF0YShTdHJpbmcgc3RyaW5nRGF0YSl7Ci0gICAgICAgICAgICAgICAgZkRhdGEgPSBzdHJpbmdEYXRhOwotICAgICB9Ci0KLSAgICAvKioKLSAgICAgKiAgVGhlIGNoYXJhY3RlciBlbmNvZGluZywgaWYga25vd24uIFRoZSBlbmNvZGluZyBtdXN0IGJlIGEgc3RyaW5nCi0gICAgICogYWNjZXB0YWJsZSBmb3IgYW4gWE1MIGVuY29kaW5nIGRlY2xhcmF0aW9uICggc2VjdGlvbiA0LjMuMyAiQ2hhcmFjdGVyCi0gICAgICogRW5jb2RpbmcgaW4gRW50aXRpZXMiKS4KLSAgICAgKiA8YnI+VGhpcyBhdHRyaWJ1dGUgaGFzIG5vIGVmZmVjdCB3aGVuIHRoZSBhcHBsaWNhdGlvbiBwcm92aWRlcyBhCi0gICAgICogY2hhcmFjdGVyIHN0cmVhbS4gRm9yIG90aGVyIHNvdXJjZXMgb2YgaW5wdXQsIGFuIGVuY29kaW5nIHNwZWNpZmllZAotICAgICAqIGJ5IG1lYW5zIG9mIHRoaXMgYXR0cmlidXRlIHdpbGwgb3ZlcnJpZGUgYW55IGVuY29kaW5nIHNwZWNpZmllZCBpbgotICAgICAqIHRoZSBYTUwgY2xhcmF0aW9uIG9yIHRoZSBUZXh0IERlY2xhcmF0aW9uLCBvciBhbiBlbmNvZGluZyBvYnRhaW5lZAotICAgICAqIGZyb20gYSBoaWdoZXIgbGV2ZWwgcHJvdG9jb2wsIHN1Y2ggYXMgSFRUUCAuCi0gICAgICovCi0KLSAgICBwdWJsaWMgU3RyaW5nIGdldEVuY29kaW5nKCl7Ci0gICAgICAgIHJldHVybiBmRW5jb2Rpbmc7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogIFRoZSBjaGFyYWN0ZXIgZW5jb2RpbmcsIGlmIGtub3duLiBUaGUgZW5jb2RpbmcgbXVzdCBiZSBhIHN0cmluZwotICAgICAqIGFjY2VwdGFibGUgZm9yIGFuIFhNTCBlbmNvZGluZyBkZWNsYXJhdGlvbiAoIHNlY3Rpb24gNC4zLjMgIkNoYXJhY3RlcgotICAgICAqIEVuY29kaW5nIGluIEVudGl0aWVzIikuCi0gICAgICogPGJyPlRoaXMgYXR0cmlidXRlIGhhcyBubyBlZmZlY3Qgd2hlbiB0aGUgYXBwbGljYXRpb24gcHJvdmlkZXMgYQotICAgICAqIGNoYXJhY3RlciBzdHJlYW0uIEZvciBvdGhlciBzb3VyY2VzIG9mIGlucHV0LCBhbiBlbmNvZGluZyBzcGVjaWZpZWQKLSAgICAgKiBieSBtZWFucyBvZiB0aGlzIGF0dHJpYnV0ZSB3aWxsIG92ZXJyaWRlIGFueSBlbmNvZGluZyBzcGVjaWZpZWQgaW4KLSAgICAgKiB0aGUgWE1MIGNsYXJhdGlvbiBvciB0aGUgVGV4dCBEZWNsYXJhdGlvbiwgb3IgYW4gZW5jb2Rpbmcgb2J0YWluZWQKLSAgICAgKiBmcm9tIGEgaGlnaGVyIGxldmVsIHByb3RvY29sLCBzdWNoIGFzIEhUVFAgLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEVuY29kaW5nKFN0cmluZyBlbmNvZGluZyl7Ci0gICAgICAgIGZFbmNvZGluZyA9IGVuY29kaW5nOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoZSBwdWJsaWMgaWRlbnRpZmllciBmb3IgdGhpcyBpbnB1dCBzb3VyY2UuIFRoZSBwdWJsaWMgaWRlbnRpZmllciBpcwotICAgICAqIGFsd2F5cyBvcHRpb25hbDogaWYgdGhlIGFwcGxpY2F0aW9uIHdyaXRlciBpbmNsdWRlcyBvbmUsIGl0IHdpbGwgYmUKLSAgICAgKiBwcm92aWRlZCBhcyBwYXJ0IG9mIHRoZSBsb2NhdGlvbiBpbmZvcm1hdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFB1YmxpY0lkKCl7Ci0gICAgICAgIHJldHVybiBmUHVibGljSWQ7Ci0gICAgfQotICAgIC8qKgotICAgICAqIFRoZSBwdWJsaWMgaWRlbnRpZmllciBmb3IgdGhpcyBpbnB1dCBzb3VyY2UuIFRoZSBwdWJsaWMgaWRlbnRpZmllciBpcwotICAgICAqIGFsd2F5cyBvcHRpb25hbDogaWYgdGhlIGFwcGxpY2F0aW9uIHdyaXRlciBpbmNsdWRlcyBvbmUsIGl0IHdpbGwgYmUKLSAgICAgKiBwcm92aWRlZCBhcyBwYXJ0IG9mIHRoZSBsb2NhdGlvbiBpbmZvcm1hdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRQdWJsaWNJZChTdHJpbmcgcHVibGljSWQpewotICAgICAgICBmUHVibGljSWQgPSBwdWJsaWNJZDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgc3lzdGVtIGlkZW50aWZpZXIsIGEgVVJJIHJlZmVyZW5jZSAsIGZvciB0aGlzIGlucHV0IHNvdXJjZS4gVGhlCi0gICAgICogc3lzdGVtIGlkZW50aWZpZXIgaXMgb3B0aW9uYWwgaWYgdGhlcmUgaXMgYSBieXRlIHN0cmVhbSBvciBhCi0gICAgICogY2hhcmFjdGVyIHN0cmVhbSwgYnV0IGl0IGlzIHN0aWxsIHVzZWZ1bCB0byBwcm92aWRlIG9uZSwgc2luY2UgdGhlCi0gICAgICogYXBwbGljYXRpb24gY2FuIHVzZSBpdCB0byByZXNvbHZlIHJlbGF0aXZlIFVSSXMgYW5kIGNhbiBpbmNsdWRlIGl0IGluCi0gICAgICogZXJyb3IgbWVzc2FnZXMgYW5kIHdhcm5pbmdzICh0aGUgcGFyc2VyIHdpbGwgYXR0ZW1wdCB0byBmZXRjaCB0aGUKLSAgICAgKiByZXNzb3VyY2UgaWRlbnRpZmllciBieSB0aGUgVVJJIHJlZmVyZW5jZSBvbmx5IGlmIHRoZXJlIGlzIG5vIGJ5dGUKLSAgICAgKiBzdHJlYW0gb3IgY2hhcmFjdGVyIHN0cmVhbSBzcGVjaWZpZWQpLgotICAgICAqIDxicj5JZiB0aGUgYXBwbGljYXRpb24ga25vd3MgdGhlIGNoYXJhY3RlciBlbmNvZGluZyBvZiB0aGUgb2JqZWN0Ci0gICAgICogcG9pbnRlZCB0byBieSB0aGUgc3lzdGVtIGlkZW50aWZpZXIsIGl0IGNhbiByZWdpc3RlciB0aGUgZW5jb2RpbmcgYnkKLSAgICAgKiBzZXR0aW5nIHRoZSBlbmNvZGluZyBhdHRyaWJ1dGUuCi0gICAgICogPGJyPklmIHRoZSBzeXN0ZW0gSUQgaXMgYSByZWxhdGl2ZSBVUkkgcmVmZXJlbmNlIChzZWUgc2VjdGlvbiA1IGluICksCi0gICAgICogdGhlIGJlaGF2aW9yIGlzIGltcGxlbWVudGF0aW9uIGRlcGVuZGVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFN5c3RlbUlkKCl7Ci0gICAgICAgIHJldHVybiBmU3lzdGVtSWQ7Ci0gICAgfQotICAgIC8qKgotICAgICAqIFRoZSBzeXN0ZW0gaWRlbnRpZmllciwgYSBVUkkgcmVmZXJlbmNlICwgZm9yIHRoaXMgaW5wdXQgc291cmNlLiBUaGUKLSAgICAgKiBzeXN0ZW0gaWRlbnRpZmllciBpcyBvcHRpb25hbCBpZiB0aGVyZSBpcyBhIGJ5dGUgc3RyZWFtIG9yIGEKLSAgICAgKiBjaGFyYWN0ZXIgc3RyZWFtLCBidXQgaXQgaXMgc3RpbGwgdXNlZnVsIHRvIHByb3ZpZGUgb25lLCBzaW5jZSB0aGUKLSAgICAgKiBhcHBsaWNhdGlvbiBjYW4gdXNlIGl0IHRvIHJlc29sdmUgcmVsYXRpdmUgVVJJcyBhbmQgY2FuIGluY2x1ZGUgaXQgaW4KLSAgICAgKiBlcnJvciBtZXNzYWdlcyBhbmQgd2FybmluZ3MgKHRoZSBwYXJzZXIgd2lsbCBhdHRlbXB0IHRvIGZldGNoIHRoZQotICAgICAqIHJlc3NvdXJjZSBpZGVudGlmaWVyIGJ5IHRoZSBVUkkgcmVmZXJlbmNlIG9ubHkgaWYgdGhlcmUgaXMgbm8gYnl0ZQotICAgICAqIHN0cmVhbSBvciBjaGFyYWN0ZXIgc3RyZWFtIHNwZWNpZmllZCkuCi0gICAgICogPGJyPklmIHRoZSBhcHBsaWNhdGlvbiBrbm93cyB0aGUgY2hhcmFjdGVyIGVuY29kaW5nIG9mIHRoZSBvYmplY3QKLSAgICAgKiBwb2ludGVkIHRvIGJ5IHRoZSBzeXN0ZW0gaWRlbnRpZmllciwgaXQgY2FuIHJlZ2lzdGVyIHRoZSBlbmNvZGluZyBieQotICAgICAqIHNldHRpbmcgdGhlIGVuY29kaW5nIGF0dHJpYnV0ZS4KLSAgICAgKiA8YnI+SWYgdGhlIHN5c3RlbSBJRCBpcyBhIHJlbGF0aXZlIFVSSSByZWZlcmVuY2UgKHNlZSBzZWN0aW9uIDUgaW4gKSwKLSAgICAgKiB0aGUgYmVoYXZpb3IgaXMgaW1wbGVtZW50YXRpb24gZGVwZW5kZW50LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFN5c3RlbUlkKFN0cmluZyBzeXN0ZW1JZCl7Ci0gICAgICAgIGZTeXN0ZW1JZCA9IHN5c3RlbUlkOwotICAgIH0KLQotICAgIC8qKgotICAgICAqICBUaGUgYmFzZSBVUkkgdG8gYmUgdXNlZCAoc2VlIHNlY3Rpb24gNS4xLjQgaW4gKSBmb3IgcmVzb2x2aW5nIHJlbGF0aXZlCi0gICAgICogVVJJcyB0byBhYnNvbHV0ZSBVUklzLiBJZiB0aGUgYmFzZVVSSSBpcyBpdHNlbGYgYSByZWxhdGl2ZSBVUkksIHRoZQotICAgICAqIGJlaGF2aW9yIGlzIGltcGxlbWVudGF0aW9uIGRlcGVuZGVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEJhc2VVUkkoKXsKLSAgICAgICAgcmV0dXJuIGZCYXNlU3lzdGVtSWQ7Ci0gICAgfQotICAgIC8qKgotICAgICAqICBUaGUgYmFzZSBVUkkgdG8gYmUgdXNlZCAoc2VlIHNlY3Rpb24gNS4xLjQgaW4gKSBmb3IgcmVzb2x2aW5nIHJlbGF0aXZlCi0gICAgICogVVJJcyB0byBhYnNvbHV0ZSBVUklzLiBJZiB0aGUgYmFzZVVSSSBpcyBpdHNlbGYgYSByZWxhdGl2ZSBVUkksIHRoZQotICAgICAqIGJlaGF2aW9yIGlzIGltcGxlbWVudGF0aW9uIGRlcGVuZGVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRCYXNlVVJJKFN0cmluZyBiYXNlVVJJKXsKLSAgICAgICAgZkJhc2VTeXN0ZW1JZCA9IGJhc2VVUkk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICAqICBJZiBzZXQgdG8gdHJ1ZSwgYXNzdW1lIHRoYXQgdGhlIGlucHV0IGlzIGNlcnRpZmllZCAoc2VlIHNlY3Rpb24gMi4xMwotICAgICAgKiBpbiBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMi9DUi14bWwxMS0yMDAyMTAxNS8nPlhNTCAxLjE8L2E+XSkgd2hlbgotICAgICAgKiBwYXJzaW5nIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAyL0NSLXhtbDExLTIwMDIxMDE1Lyc+WE1MIDEuMTwvYT5dLgotICAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXRDZXJ0aWZpZWRUZXh0KCl7Ci0gICAgICByZXR1cm4gZkNlcnRpZmllZFRleHQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICAqICBJZiBzZXQgdG8gdHJ1ZSwgYXNzdW1lIHRoYXQgdGhlIGlucHV0IGlzIGNlcnRpZmllZCAoc2VlIHNlY3Rpb24gMi4xMwotICAgICAgKiBpbiBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMi9DUi14bWwxMS0yMDAyMTAxNS8nPlhNTCAxLjE8L2E+XSkgd2hlbgotICAgICAgKiBwYXJzaW5nIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAyL0NSLXhtbDExLTIwMDIxMDE1Lyc+WE1MIDEuMTwvYT5dLgotICAgICAgKi8KLQotICAgIHB1YmxpYyB2b2lkIHNldENlcnRpZmllZFRleHQoYm9vbGVhbiBjZXJ0aWZpZWRUZXh0KXsKLSAgICAgIGZDZXJ0aWZpZWRUZXh0ID0gY2VydGlmaWVkVGV4dDsKLSAgICB9Ci0KLX0vLyBjbGFzcyBET01JbnB1dEltcGwKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9ET01Mb2NhdG9ySW1wbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL0RPTUxvY2F0b3JJbXBsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDJhNDIxYjUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL0RPTUxvY2F0b3JJbXBsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNjIgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMSwgMjAwMiwyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbTsKLQotaW1wb3J0IG9yZy53M2MuZG9tLkRPTUxvY2F0b3I7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLQotCi0vKioKLSAqIDxjb2RlPkRPTUxvY2F0b3JJbXBsPC9jb2RlPiBpcyBhbiBpbXBsZW1lbnRhaW9uIHRoYXQgZGVzY3JpYmVzIGEgbG9jYXRpb24gKGUuZy4KLSAqIHdoZXJlIGFuIGVycm9yIG9jY3VyZWQpLgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDEvV0QtRE9NLUxldmVsLTMtQ29yZS0yMDAxMDkxMyc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDMgQ29yZSBTcGVjaWZpY2F0aW9uPC9hPi4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBHb3BhbCBTaGFybWEsIFNVTiBNaWNyb3N5c3RlbXMgSW5jLgotICovCi0KLXB1YmxpYyBjbGFzcyBET01Mb2NhdG9ySW1wbCBpbXBsZW1lbnRzIERPTUxvY2F0b3IgewotCi0gICAgLy8KLSAgICAvLyBEYXRhCi0gICAgLy8KLQotICAgLyoqCi0gICAgKiBUaGUgY29sdW1uIG51bWJlciB3aGVyZSB0aGUgZXJyb3Igb2NjdXJlZCwKLSAgICAqIG9yIC0xIGlmIHRoZXJlIGlzIG5vIGNvbHVtbiBudW1iZXIgYXZhaWxhYmxlLgotICAgICovCi0gICBwdWJsaWMgaW50IGZDb2x1bW5OdW1iZXIgPSAtMTsKLQotICAgLyoqCi0gICAgKiBUaGUgbGluZSBudW1iZXIgd2hlcmUgdGhlIGVycm9yIG9jY3VyZWQsCi0gICAgKiBvciAtMSBpZiB0aGVyZSBpcyBubyBsaW5lIG51bWJlciBhdmFpbGFibGUuCi0gICAgKi8KLSAgIHB1YmxpYyBpbnQgZkxpbmVOdW1iZXIgPSAtMTsKLQotICAgLyoqIHJlbGF0ZWQgZGF0YSBub2RlKi8KLSAgIHB1YmxpYyBOb2RlIGZSZWxhdGVkTm9kZSA9IG51bGw7Ci0KLSAgIC8qKgotICAgICogVGhlIFVSSSB3aGVyZSB0aGUgZXJyb3Igb2NjdXJlZCwKLSAgICAqIG9yIG51bGwgaWYgdGhlcmUgaXMgbm8gVVJJIGF2YWlsYWJsZS4KLSAgICAqLwotICAgcHVibGljIFN0cmluZyBmVXJpID0gbnVsbDsKLQotICAgLyoqCi0gICAgKiBUaGUgYnl0ZSBvZmZzZXQgaW50byB0aGUgaW5wdXQgc291cmNlIHRoaXMgbG9jYXRvciBpcyBwb2ludGluZyB0byBvciAtMQotICAgICogaWYgdGhlcmUgaXMgbm8gYnl0ZSBvZmZzZXQgYXZhaWxhYmxlCi0gICAgKi8KLSAgIHB1YmxpYyBpbnQgZkJ5dGVPZmZzZXQgPSAtMTsKLQotICAgLyoqCi0gICAgKiBUaGUgVVRGLTE2LCBhcyBkZWZpbmVkIGluIFtVbmljb2RlXSBhbmQgQW1lbmRtZW50IDEgb2YgW0lTTy9JRUMgMTA2NDZdLAotICAgICogb2Zmc2V0IGludG8gdGhlIGlucHV0IHNvdXJjZSB0aGlzIGxvY2F0b3IgaXMgcG9pbnRpbmcgdG8gb3IgLTEgaWYgdGhlcmUKLSAgICAqIGlzIG5vIFVURi0xNiBvZmZzZXQgYXZhaWxhYmxlLgotICAgICovCi0gICBwdWJsaWMgaW50IGZVdGYxNk9mZnNldCA9IC0xOwotCi0gICAvLwotICAgLy8gQ29uc3RydWN0b3JzCi0gICAvLwotCi0gICBwdWJsaWMgRE9NTG9jYXRvckltcGwoKXsKLSAgIH0KLQotICAgcHVibGljIERPTUxvY2F0b3JJbXBsIChpbnQgbGluZU51bWJlciwgaW50IGNvbHVtbk51bWJlciwgU3RyaW5nIHVyaSApewotICAgICAgICBmTGluZU51bWJlciA9IGxpbmVOdW1iZXIgOwotICAgICAgICBmQ29sdW1uTnVtYmVyID0gY29sdW1uTnVtYmVyIDsKLSAgICAgICAgZlVyaSA9IHVyaTsKLSAgIH0gLy8gRE9NTG9jYXRvckltcGwgKGludCBsaW5lTnVtYmVyLCBpbnQgY29sdW1uTnVtYmVyLCBTdHJpbmcgdXJpICkKLQotICAgcHVibGljIERPTUxvY2F0b3JJbXBsIChpbnQgbGluZU51bWJlciwgaW50IGNvbHVtbk51bWJlciwgaW50IHV0ZjE2T2Zmc2V0LCBTdHJpbmcgdXJpICl7Ci0gICAgICAgIGZMaW5lTnVtYmVyID0gbGluZU51bWJlciA7Ci0gICAgICAgIGZDb2x1bW5OdW1iZXIgPSBjb2x1bW5OdW1iZXIgOwotICAgICAgICBmVXJpID0gdXJpOwotICAgICAgICBmVXRmMTZPZmZzZXQgPSB1dGYxNk9mZnNldDsKLSAgIH0gLy8gRE9NTG9jYXRvckltcGwgKGludCBsaW5lTnVtYmVyLCBpbnQgY29sdW1uTnVtYmVyLCBpbnQgdXRmMTZPZmZzZXQsIFN0cmluZyB1cmkgKQotCi0gICBwdWJsaWMgRE9NTG9jYXRvckltcGwgKGludCBsaW5lTnVtYmVyLCBpbnQgY29sdW1uTnVtYmVyLCBpbnQgYnl0ZW9mZnNldCwgTm9kZSByZWxhdGVkRGF0YSwgU3RyaW5nIHVyaSApewotICAgICAgICBmTGluZU51bWJlciA9IGxpbmVOdW1iZXIgOwotICAgICAgICBmQ29sdW1uTnVtYmVyID0gY29sdW1uTnVtYmVyIDsKLSAgICAgICAgZkJ5dGVPZmZzZXQgPSBieXRlb2Zmc2V0IDsKLSAgICAgICAgZlJlbGF0ZWROb2RlID0gcmVsYXRlZERhdGEgOwotICAgICAgICBmVXJpID0gdXJpOwotICAgfSAvLyBET01Mb2NhdG9ySW1wbCAoaW50IGxpbmVOdW1iZXIsIGludCBjb2x1bW5OdW1iZXIsIGludCBvZmZzZXQsIE5vZGUgZXJyb3JOb2RlLCBTdHJpbmcgdXJpICkKLQotICAgcHVibGljIERPTUxvY2F0b3JJbXBsIChpbnQgbGluZU51bWJlciwgaW50IGNvbHVtbk51bWJlciwgaW50IGJ5dGVvZmZzZXQsIE5vZGUgcmVsYXRlZERhdGEsIFN0cmluZyB1cmksIGludCB1dGYxNk9mZnNldCApewotICAgICAgICBmTGluZU51bWJlciA9IGxpbmVOdW1iZXIgOwotICAgICAgICBmQ29sdW1uTnVtYmVyID0gY29sdW1uTnVtYmVyIDsKLSAgICAgICAgZkJ5dGVPZmZzZXQgPSBieXRlb2Zmc2V0IDsKLSAgICAgICAgZlJlbGF0ZWROb2RlID0gcmVsYXRlZERhdGEgOwotICAgICAgICBmVXJpID0gdXJpOwotICAgICAgICBmVXRmMTZPZmZzZXQgPSB1dGYxNk9mZnNldDsKLSAgIH0gLy8gRE9NTG9jYXRvckltcGwgKGludCBsaW5lTnVtYmVyLCBpbnQgY29sdW1uTnVtYmVyLCBpbnQgb2Zmc2V0LCBOb2RlIGVycm9yTm9kZSwgU3RyaW5nIHVyaSApCi0KLQotICAvKioKLSAgICogVGhlIGxpbmUgbnVtYmVyIHdoZXJlIHRoZSBlcnJvciBvY2N1cmVkLCBvciAtMSBpZiB0aGVyZSBpcyBubyBsaW5lCi0gICAqIG51bWJlciBhdmFpbGFibGUuCi0gICAqLwotICAgcHVibGljIGludCBnZXRMaW5lTnVtYmVyKCl7Ci0gICAgICAgIHJldHVybiBmTGluZU51bWJlcjsKLSAgIH0KLQotICAvKioKLSAgICogVGhlIGNvbHVtbiBudW1iZXIgd2hlcmUgdGhlIGVycm9yIG9jY3VyZWQsIG9yIC0xIGlmIHRoZXJlIGlzIG5vIGNvbHVtbgotICAgKiBudW1iZXIgYXZhaWxhYmxlLgotICAgKi8KLSAgcHVibGljIGludCBnZXRDb2x1bW5OdW1iZXIoKXsKLSAgICAgICAgcmV0dXJuIGZDb2x1bW5OdW1iZXI7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBUaGUgVVJJIHdoZXJlIHRoZSBlcnJvciBvY2N1cmVkLCBvciBudWxsIGlmIHRoZXJlIGlzIG5vIFVSSSBhdmFpbGFibGUuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFVyaSgpewotICAgICAgICByZXR1cm4gZlVyaTsKLSAgfQotCi0KLSAgcHVibGljIE5vZGUgZ2V0UmVsYXRlZE5vZGUoKXsKLSAgICByZXR1cm4gZlJlbGF0ZWROb2RlOwotICB9Ci0KLQotICAvKioKLSAgICogVGhlIGJ5dGUgb2Zmc2V0IGludG8gdGhlIGlucHV0IHNvdXJjZSB0aGlzIGxvY2F0b3IgaXMgcG9pbnRpbmcgdG8gb3IgLTEKLSAgICogaWYgdGhlcmUgaXMgbm8gYnl0ZSBvZmZzZXQgYXZhaWxhYmxlCi0gICAqLwotICBwdWJsaWMgaW50IGdldEJ5dGVPZmZzZXQoKXsKLSAgICAgICAgcmV0dXJuIGZCeXRlT2Zmc2V0OwotICB9Ci0KLSAgLyoqCi0gICAqIFRoZSBVVEYtMTYsIGFzIGRlZmluZWQgaW4gW1VuaWNvZGVdIGFuZCBBbWVuZG1lbnQgMSBvZiBbSVNPL0lFQyAxMDY0Nl0sCi0gICAqIG9mZnNldCBpbnRvIHRoZSBpbnB1dCBzb3VyY2UgdGhpcyBsb2NhdG9yIGlzIHBvaW50aW5nIHRvIG9yIC0xIGlmIHRoZXJlCi0gICAqIGlzIG5vIFVURi0xNiBvZmZzZXQgYXZhaWxhYmxlLgotICAgKi8KLSAgcHVibGljIGludCBnZXRVdGYxNk9mZnNldCgpewotICAgICAgICByZXR1cm4gZlV0ZjE2T2Zmc2V0OwotICB9Ci0KLX0vLyBjbGFzcyBET01Mb2NhdG9ySW1wbApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL0RPTU1lc3NhZ2VGb3JtYXR0ZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9ET01NZXNzYWdlRm9ybWF0dGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGY3ZDEzMWYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL0RPTU1lc3NhZ2VGb3JtYXR0ZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE0MyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAyLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5kb207Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlscy5TZWN1cml0eVN1cHBvcnQ7Ci1pbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKLWltcG9ydCBqYXZhLnV0aWwuTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uOwotaW1wb3J0IGphdmEudXRpbC5SZXNvdXJjZUJ1bmRsZTsKLQotLyoqCi0gKiBVc2VkIHRvIGZvcm1hdCBET00gZXJyb3IgbWVzc2FnZXMsIHVzaW5nIHRoZSBzeXN0ZW0gbG9jYWxlLgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIFNhbmR5IEdhbywgSUJNCi0gKiBAdmVyc2lvbiAkSWQ6IERPTU1lc3NhZ2VGb3JtYXR0ZXIuamF2YSx2IDEuNiAyMDEwLTExLTAxIDA0OjM5OjM4IGpvZWh3IEV4cCAkCi0gKi8KLXB1YmxpYyBjbGFzcyBET01NZXNzYWdlRm9ybWF0dGVyIHsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBET01fRE9NQUlOID0gImh0dHA6Ly93d3cudzMub3JnL2RvbS9ET01UUiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MX0RPTUFJTiA9ICJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy14bWwtMTk5ODAyMTAiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFNFUklBTElaRVJfRE9NQUlOID0gImh0dHA6Ly9hcGFjaGUub3JnL3htbC9zZXJpYWxpemVyIjsKLQotICAgIHByaXZhdGUgc3RhdGljIFJlc291cmNlQnVuZGxlIGRvbVJlc291cmNlQnVuZGxlID0gbnVsbDsKLSAgICBwcml2YXRlIHN0YXRpYyBSZXNvdXJjZUJ1bmRsZSB4bWxSZXNvdXJjZUJ1bmRsZSA9IG51bGw7Ci0gICAgcHJpdmF0ZSBzdGF0aWMgUmVzb3VyY2VCdW5kbGUgc2VyUmVzb3VyY2VCdW5kbGUgPSBudWxsOwotICAgIHByaXZhdGUgc3RhdGljIExvY2FsZSBsb2NhbGUgPSBudWxsOwotCi0KLSAgICBET01NZXNzYWdlRm9ybWF0dGVyKCl7Ci0gICAgICAgIGxvY2FsZSA9IExvY2FsZS5nZXREZWZhdWx0KCk7Ci0gICAgfQotICAgIC8qKgotICAgICAqIEZvcm1hdHMgYSBtZXNzYWdlIHdpdGggdGhlIHNwZWNpZmllZCBhcmd1bWVudHMgdXNpbmcgdGhlIGdpdmVuCi0gICAgICogbG9jYWxlIGluZm9ybWF0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIGRvbWFpbiAgICBkb21haW4gZnJvbSB3aGljaCBlcnJvciBzdHJpbmcgaXMgdG8gY29tZS4KLSAgICAgKiBAcGFyYW0ga2V5ICAgICAgIFRoZSBtZXNzYWdlIGtleS4KLSAgICAgKiBAcGFyYW0gYXJndW1lbnRzIFRoZSBtZXNzYWdlIHJlcGxhY2VtZW50IHRleHQgYXJndW1lbnRzLiBUaGUgb3JkZXIKLSAgICAgKiAgICAgICAgICAgICAgICAgIG9mIHRoZSBhcmd1bWVudHMgbXVzdCBtYXRjaCB0aGF0IG9mIHRoZSBwbGFjZWhvbGRlcnMKLSAgICAgKiAgICAgICAgICAgICAgICAgIGluIHRoZSBhY3R1YWwgbWVzc2FnZS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gICAgICAgICAgdGhlIGZvcm1hdHRlZCBtZXNzYWdlLgotICAgICAqCi0gICAgICogQHRocm93cyBNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24gVGhyb3duIGlmIHRoZSBtZXNzYWdlIHdpdGggdGhlCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BlY2lmaWVkIGtleSBjYW5ub3QgYmUgZm91bmQuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZm9ybWF0TWVzc2FnZShTdHJpbmcgZG9tYWluLAotICAgIFN0cmluZyBrZXksIE9iamVjdFtdIGFyZ3VtZW50cykKLSAgICB0aHJvd3MgTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uIHsKLSAgICAgICAgUmVzb3VyY2VCdW5kbGUgcmVzb3VyY2VCdW5kbGUgPSBnZXRSZXNvdXJjZUJ1bmRsZShkb21haW4pOwotICAgICAgICBpZihyZXNvdXJjZUJ1bmRsZSA9PSBudWxsKXsKLSAgICAgICAgICAgIGluaXQoKTsKLSAgICAgICAgICAgIHJlc291cmNlQnVuZGxlID0gZ2V0UmVzb3VyY2VCdW5kbGUoZG9tYWluKTsKLSAgICAgICAgICAgIGlmKHJlc291cmNlQnVuZGxlID09IG51bGwpCi0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbigiVW5rbm93biBkb21haW4iICsgZG9tYWluLCBudWxsLCBrZXkpOwotICAgICAgICB9Ci0gICAgICAgIC8vIGZvcm1hdCBtZXNzYWdlCi0gICAgICAgIFN0cmluZyBtc2c7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBtc2cgPSBrZXkgKyAiOiAiICsgcmVzb3VyY2VCdW5kbGUuZ2V0U3RyaW5nKGtleSk7Ci0gICAgICAgICAgICBpZiAoYXJndW1lbnRzICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICBtc2cgPSBqYXZhLnRleHQuTWVzc2FnZUZvcm1hdC5mb3JtYXQobXNnLCBhcmd1bWVudHMpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICAgICAgbXNnID0gcmVzb3VyY2VCdW5kbGUuZ2V0U3RyaW5nKCJGb3JtYXRGYWlsZWQiKTsKLSAgICAgICAgICAgICAgICAgICAgbXNnICs9ICIgIiArIHJlc291cmNlQnVuZGxlLmdldFN0cmluZyhrZXkpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfSAvLyBlcnJvcgotICAgICAgICBjYXRjaCAoTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIG1zZyA9IHJlc291cmNlQnVuZGxlLmdldFN0cmluZygiQmFkTWVzc2FnZUtleSIpOwotICAgICAgICAgICAgdGhyb3cgbmV3IE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbihrZXksIG1zZywga2V5KTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIG5vIG1lc3NhZ2UKLSAgICAgICAgaWYgKG1zZyA9PSBudWxsKSB7Ci0gICAgICAgICAgICBtc2cgPSBrZXk7Ci0gICAgICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDApIHsKLSAgICAgICAgICAgICAgICBTdHJpbmdCdWZmZXIgc3RyID0gbmV3IFN0cmluZ0J1ZmZlcihtc2cpOwotICAgICAgICAgICAgICAgIHN0ci5hcHBlbmQoJz8nKTsKLSAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykgewotICAgICAgICAgICAgICAgICAgICBpZiAoaSA+IDApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHN0ci5hcHBlbmQoJyYnKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKFN0cmluZy52YWx1ZU9mKGFyZ3VtZW50c1tpXSkpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBtc2c7Ci0gICAgfQotCi0gICAgc3RhdGljIFJlc291cmNlQnVuZGxlIGdldFJlc291cmNlQnVuZGxlKFN0cmluZyBkb21haW4pewotICAgICAgICBpZihkb21haW4gPT0gRE9NX0RPTUFJTiB8fCBkb21haW4uZXF1YWxzKERPTV9ET01BSU4pKQotICAgICAgICAgICAgcmV0dXJuIGRvbVJlc291cmNlQnVuZGxlOwotICAgICAgICBlbHNlIGlmKCBkb21haW4gPT0gWE1MX0RPTUFJTiB8fCBkb21haW4uZXF1YWxzKFhNTF9ET01BSU4pKQotICAgICAgICAgICAgcmV0dXJuIHhtbFJlc291cmNlQnVuZGxlOwotICAgICAgICBlbHNlIGlmKGRvbWFpbiA9PSBTRVJJQUxJWkVSX0RPTUFJTiB8fCBkb21haW4uZXF1YWxzKFNFUklBTElaRVJfRE9NQUlOKSkKLSAgICAgICAgICAgIHJldHVybiBzZXJSZXNvdXJjZUJ1bmRsZTsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotICAgIC8qKgotICAgICAqIEluaXRpYWxpemUgTWVzc2FnZSBGb3JtYXR0ZXIuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyB2b2lkIGluaXQoKXsKLSAgICAgICAgaWYgKGxvY2FsZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBkb21SZXNvdXJjZUJ1bmRsZSA9IFNlY3VyaXR5U3VwcG9ydC5nZXRSZXNvdXJjZUJ1bmRsZSgiY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLm1zZy5ET01NZXNzYWdlcyIsIGxvY2FsZSk7Ci0gICAgICAgICAgICBzZXJSZXNvdXJjZUJ1bmRsZSA9IFNlY3VyaXR5U3VwcG9ydC5nZXRSZXNvdXJjZUJ1bmRsZSgiY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLm1zZy5YTUxTZXJpYWxpemVyTWVzc2FnZXMiLCBsb2NhbGUpOwotICAgICAgICAgICAgeG1sUmVzb3VyY2VCdW5kbGUgPSBTZWN1cml0eVN1cHBvcnQuZ2V0UmVzb3VyY2VCdW5kbGUoImNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5tc2cuWE1MTWVzc2FnZXMiLCBsb2NhbGUpOwotICAgICAgICB9ZWxzZXsKLSAgICAgICAgICAgIGRvbVJlc291cmNlQnVuZGxlID0gU2VjdXJpdHlTdXBwb3J0LmdldFJlc291cmNlQnVuZGxlKCJjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwubXNnLkRPTU1lc3NhZ2VzIik7Ci0gICAgICAgICAgICBzZXJSZXNvdXJjZUJ1bmRsZSA9IFNlY3VyaXR5U3VwcG9ydC5nZXRSZXNvdXJjZUJ1bmRsZSgiY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLm1zZy5YTUxTZXJpYWxpemVyTWVzc2FnZXMiKTsKLSAgICAgICAgICAgIHhtbFJlc291cmNlQnVuZGxlID0gU2VjdXJpdHlTdXBwb3J0LmdldFJlc291cmNlQnVuZGxlKCJjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwubXNnLlhNTE1lc3NhZ2VzIik7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBzZXRMb2NhbGUgdG8gYmUgdXNlZCBieSB0aGUgZm9ybWF0dGVyLgotICAgICAqIEBwYXJhbSBsb2NhbGUKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIHZvaWQgc2V0TG9jYWxlKExvY2FsZSBkbG9jYWxlKXsKLSAgICAgICAgbG9jYWxlID0gZGxvY2FsZTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vRE9NTm9ybWFsaXplci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL0RPTU5vcm1hbGl6ZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYzQyNjhkYy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vRE9NTm9ybWFsaXplci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjA0MiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDIsMjAwNCwgMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5kb207Ci0KLQotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci1pbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKLWltcG9ydCBqYXZhLmlvLlN0cmluZ1JlYWRlcjsKLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5kb20uQWJvcnRFeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLkNvbnN0YW50czsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuUmV2YWxpZGF0aW9uSGFuZGxlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHRkLkRUREdyYW1tYXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR0ZC5YTUxEVEREZXNjcmlwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHRkLlhNTERURFZhbGlkYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYuWFNTaW1wbGVUeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy51dGlsLlNpbXBsZUxvY2F0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5wYXJzZXJzLlhNTEdyYW1tYXJQcmVwYXJzZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLkF1Z21lbnRhdGlvbnNJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5OYW1lc3BhY2VTdXBwb3J0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5TeW1ib2xUYWJsZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuWE1MMTFDaGFyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5YTUxDaGFyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5YTUxHcmFtbWFyUG9vbEltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlhNTFN5bWJvbHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuQXVnbWVudGF0aW9uczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5OYW1lc3BhY2VDb250ZXh0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlFOYW1lOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTEF0dHJpYnV0ZXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MRG9jdW1lbnRIYW5kbGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTExvY2F0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MUmVzb3VyY2VJZGVudGlmaWVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTFN0cmluZzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTklFeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuZ3JhbW1hcnMuWE1MR3JhbW1hckRlc2NyaXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLmdyYW1tYXJzLlhNTEdyYW1tYXJQb29sOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxDb21wb25lbnQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTERvY3VtZW50U291cmNlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxJbnB1dFNvdXJjZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLkF0dHJpYnV0ZVBTVkk7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5FbGVtZW50UFNWSTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTVHlwZURlZmluaXRpb247Ci1pbXBvcnQgb3JnLnczYy5kb20uQXR0cjsKLWltcG9ydCBvcmcudzNjLmRvbS5Db21tZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLkRPTUVycm9yOwotaW1wb3J0IG9yZy53M2MuZG9tLkRPTUVycm9ySGFuZGxlcjsKLWltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKLWltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudFR5cGU7Ci1pbXBvcnQgb3JnLnczYy5kb20uRWxlbWVudDsKLWltcG9ydCBvcmcudzNjLmRvbS5FbnRpdHk7Ci1pbXBvcnQgb3JnLnczYy5kb20uTmFtZWROb2RlTWFwOwotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZUxpc3Q7Ci1pbXBvcnQgb3JnLnczYy5kb20uUHJvY2Vzc2luZ0luc3RydWN0aW9uOwotaW1wb3J0IG9yZy53M2MuZG9tLlRleHQ7Ci0vKioKLSAqIFRoaXMgY2xhc3MgYWRkcyBpbXBsZW1lbnRhdGlvbiBmb3Igbm9ybWFsaXplRG9jdW1lbnQgbWV0aG9kLgotICogSXQgYWN0cyBhcyBpZiB0aGUgZG9jdW1lbnQgd2FzIGdvaW5nIHRocm91Z2ggYSBzYXZlIGFuZCBsb2FkIGN5Y2xlLCBwdXR0aW5nCi0gKiB0aGUgZG9jdW1lbnQgaW4gYSAibm9ybWFsIiBmb3JtLiBUaGUgYWN0dWFsIHJlc3VsdCBkZXBlbmRzIG9uIHRoZSBmZWF0dXJlcyBiZWluZyBzZXQKLSAqIGFuZCBnb3Zlcm5pbmcgd2hhdCBvcGVyYXRpb25zIGFjdHVhbGx5IHRha2UgcGxhY2UuIFNlZSBzZXROb3JtYWxpemF0aW9uRmVhdHVyZSBmb3IgZGV0YWlscy4KLSAqIE5vdGljZWFibHkgdGhpcyBtZXRob2Qgbm9ybWFsaXplcyBUZXh0IG5vZGVzLCBtYWtlcyB0aGUgZG9jdW1lbnQgIm5hbWVzcGFjZSB3ZWxsZm9ybWVkIiwKLSAqIGFjY29yZGluZyB0byB0aGUgYWxnb3JpdGhtIGRlc2NyaWJlZCBiZWxvdyBpbiBwc2V1ZG8gY29kZSwgYnkgYWRkaW5nIG1pc3NpbmcgbmFtZXNwYWNlCi0gKiBkZWNsYXJhdGlvbiBhdHRyaWJ1dGVzIGFuZCBhZGRpbmcgb3IgY2hhbmdpbmcgbmFtZXNwYWNlIHByZWZpeGVzLCB1cGRhdGVzIHRoZSByZXBsYWNlbWVudAotICogdHJlZSBvZiBFbnRpdHlSZWZlcmVuY2Ugbm9kZXMsIG5vcm1hbGl6ZXMgYXR0cmlidXRlIHZhbHVlcywgZXRjLgotICogTXV0YXRpb24gZXZlbnRzLCB3aGVuIHN1cHBvcnRlZCwgYXJlIGdlbmVyYXRlZCB0byByZWZsZWN0IHRoZSBjaGFuZ2VzIG9jY3VyaW5nIG9uIHRoZQotICogZG9jdW1lbnQuCi0gKiBTZWUgTmFtZXNwYWNlIG5vcm1hbGl6YXRpb24gZm9yIGRldGFpbHMgb24gaG93IG5hbWVzcGFjZSBkZWNsYXJhdGlvbiBhdHRyaWJ1dGVzIGFuZCBwcmVmaXhlcwotICogYXJlIG5vcm1hbGl6ZWQuCi0gKgotICogTk9URTogVGhlcmUgaXMgYW4gaW5pdGlhbCBzdXBwb3J0IGZvciBET00gcmV2YWxpZGF0aW9uIHdpdGggWE1MIFNjaGVtYSBhcyBhIGdyYW1tYXIuCi0gKiBUaGUgdHJlZSBtaWdodCBub3QgYmUgdmFsaWRhdGVkIGNvcnJlY3RseSBpZiBlbnRpdHlSZWZlcmVuY2VzLCBDREFUQSBzZWN0aW9ucyBhcmUKLSAqIHByZXNlbnQgaW4gdGhlIHRyZWUuIFRoZSBQU1ZJIGluZm9ybWF0aW9uIGlzIG5vdCBleHBvc2VkLCBub3JtYWxpemVkIGRhdGEgKGluY2x1ZGluZyBlbGVtZW50Ci0gKiBkZWZhdWx0IGNvbnRlbnQgaXMgbm90IGF2YWlsYWJsZSkuCi0gKgotICogQHhlcmNlcy5leHBlcmltZW50YWwKLSAqCi0gKiBAYXV0aG9yIEVsZW5hIExpdGFuaSwgSUJNCi0gKiBAYXV0aG9yIE5lZXJhaiBCYWphaiwgU3VuIE1pY3Jvc3lzdGVtcywgaW5jLgotICogQHZlcnNpb24gJElkOiBET01Ob3JtYWxpemVyLmphdmEsdiAxLjkgMjAxMC0xMS0wMSAwNDozOTozOCBqb2VodyBFeHAgJAotICovCi1wdWJsaWMgY2xhc3MgRE9NTm9ybWFsaXplciBpbXBsZW1lbnRzIFhNTERvY3VtZW50SGFuZGxlciB7Ci0KLSAgICAvLwotICAgIC8vIGNvbnN0YW50cwotICAgIC8vCi0gICAgLyoqIERlYnVnIG5vcm1hbGl6ZSBkb2N1bWVudCovCi0gICAgcHJvdGVjdGVkIGZpbmFsIHN0YXRpYyBib29sZWFuIERFQlVHX05EID0gZmFsc2U7Ci0gICAgLyoqIERlYnVnIG5hbWVzcGFjZSBmaXggdXAgYWxnb3JpdGhtKi8KLSAgICBwcm90ZWN0ZWQgZmluYWwgc3RhdGljIGJvb2xlYW4gREVCVUcgPSBmYWxzZTsKLSAgICAvKiogRGVidWcgZG9jdW1lbnQgaGFuZGxlciBldmVudHMgKi8KLSAgICBwcm90ZWN0ZWQgZmluYWwgc3RhdGljIGJvb2xlYW4gREVCVUdfRVZFTlRTID0gZmFsc2U7Ci0KLSAgICAvKiogcHJlZml4IGFkZGVkIGJ5IG5hbWVzcGFjZSBmaXh1cCBhbGdvcml0aG0gc2hvdWxkIGZvbGxvdyBhIHBhdHRlcm4gIk5TIiArIGluZGV4Ki8KLSAgICBwcm90ZWN0ZWQgZmluYWwgc3RhdGljIFN0cmluZyBQUkVGSVggPSAiTlMiOwotCi0gICAgLy8KLSAgICAvLyBEYXRhCi0gICAgLy8KLSAgICBwcm90ZWN0ZWQgRE9NQ29uZmlndXJhdGlvbkltcGwgZkNvbmZpZ3VyYXRpb24gPSBudWxsOwotICAgIHByb3RlY3RlZCBDb3JlRG9jdW1lbnRJbXBsIGZEb2N1bWVudCA9IG51bGw7Ci0gICAgcHJvdGVjdGVkIGZpbmFsIFhNTEF0dHJpYnV0ZXNQcm94eSBmQXR0clByb3h5ID0gbmV3IFhNTEF0dHJpYnV0ZXNQcm94eSgpOwotICAgIHByb3RlY3RlZCBmaW5hbCBRTmFtZSBmUU5hbWUgPSBuZXcgUU5hbWUoKTsKLQotICAgIC8qKiBWYWxpZGF0aW9uIGhhbmRsZXIgcmVwcmVzZW50cyB2YWxpZGF0b3IgaW5zdGFuY2UuICovCi0gICAgcHJvdGVjdGVkIFJldmFsaWRhdGlvbkhhbmRsZXIgZlZhbGlkYXRpb25IYW5kbGVyOwotCi0gICAgLyoqIHN5bWJvbCB0YWJsZSAqLwotICAgIHByb3RlY3RlZCBTeW1ib2xUYWJsZSBmU3ltYm9sVGFibGU7Ci0gICAgLyoqIGVycm9yIGhhbmRsZXIuIG1heSBiZSBudWxsLiAqLwotICAgIHByb3RlY3RlZCBET01FcnJvckhhbmRsZXIgZkVycm9ySGFuZGxlcjsKLQotICAgIC8qKgotICAgICAqIENhY2hlZCB7QGxpbmsgRE9NRXJyb3J9IGltcGwuCi0gICAgICogVGhlIHNhbWUgb2JqZWN0IGlzIHJlLXVzZWQgdG8gcmVwb3J0IG11bHRpcGxlIGVycm9ycy4KLSAgICAgKi8KLSAgICBwcml2YXRlIGZpbmFsIERPTUVycm9ySW1wbCBmRXJyb3IgPSBuZXcgRE9NRXJyb3JJbXBsKCk7Ci0KLSAgICAvLyBWYWxpZGF0aW9uIGFnYWluc3QgbmFtZXNwYWNlIGF3YXJlIGdyYW1tYXIKLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBmTmFtZXNwYWNlVmFsaWRhdGlvbiA9IGZhbHNlOwotCi0gICAgLy8gVXBkYXRlIFBTVkkgaW5mb3JtYXRpb24gaW4gdGhlIHRyZWUKLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBmUFNWSSA9IGZhbHNlOwotCi0gICAgLyoqIFRoZSBuYW1lc3BhY2UgY29udGV4dCBvZiB0aGlzIGRvY3VtZW50OiBzdG9yZXMgbmFtZXNwYWNlcyBpbiBzY29wZSAqLwotICAgIHByb3RlY3RlZCBmaW5hbCBOYW1lc3BhY2VDb250ZXh0IGZOYW1lc3BhY2VDb250ZXh0ID0gbmV3IE5hbWVzcGFjZVN1cHBvcnQoKTsKLQotICAgIC8qKiBTdG9yZXMgYWxsIG5hbWVzcGFjZSBiaW5kaW5ncyBvbiB0aGUgY3VycmVudCBlbGVtZW50ICovCi0gICAgcHJvdGVjdGVkIGZpbmFsIE5hbWVzcGFjZUNvbnRleHQgZkxvY2FsTlNCaW5kZXIgPSBuZXcgTmFtZXNwYWNlU3VwcG9ydCgpOwotCi0gICAgLyoqIGxpc3Qgb2YgYXR0cmlidXRlcyAqLwotICAgIHByb3RlY3RlZCBmaW5hbCBBcnJheUxpc3QgZkF0dHJpYnV0ZUxpc3QgPSBuZXcgQXJyYXlMaXN0KDUpOwotCi0gICAgLyoqIERPTSBMb2NhdG9yIC0gIGZvciBuYW1lc3BhY2UgZml4dXAgYWxnb3JpdGhtICovCi0gICAgcHJvdGVjdGVkIGZpbmFsIERPTUxvY2F0b3JJbXBsIGZMb2NhdG9yID0gbmV3IERPTUxvY2F0b3JJbXBsKCk7Ci0KLSAgICAvKiogZm9yIHNldHRpbmcgdGhlIFBTVkkgKi8KLSAgICBwcm90ZWN0ZWQgTm9kZSBmQ3VycmVudE5vZGUgPSBudWxsOwotICAgIHByaXZhdGUgUU5hbWUgZkF0dHJRTmFtZSA9IG5ldyBRTmFtZSgpOwotCi0gICAgLy8gYXR0cmlidXRlIHZhbHVlIG5vcm1hbGl6YXRpb24KLSAgICBmaW5hbCBYTUxTdHJpbmcgZk5vcm1hbGl6ZWRWYWx1ZSA9IG5ldyBYTUxTdHJpbmcobmV3IGNoYXJbMTZdLCAwLCAwKTsKLQotICAgIC8vRFREIHZhbGlkYXRvcgotICAgIHByaXZhdGUgWE1MRFREVmFsaWRhdG9yIGZEVERWYWxpZGF0b3I7Ci0KLSAgICAvL0NoZWNrIGlmIGVsZW1lbnQgY29udGVudCBpcyBhbGwgImlnbm9yYWJsZSB3aGl0ZXNwYWNlIgotICAgIHByaXZhdGUgYm9vbGVhbiBhbGxXaGl0ZXNwYWNlID0gZmFsc2U7Ci0KLSAgICAvLyBDb25zdHJ1Y3RvcgotICAgIC8vCi0KLSAgICBwdWJsaWMgRE9NTm9ybWFsaXplcigpe30KLQotCi0KLSAgICAvKioKLSAgICAgKiBOb3JtYWxpemVzIGRvY3VtZW50LgotICAgICAqIE5vdGU6IHJlc2V0KCkgbXVzdCBiZSBjYWxsZWQgYmVmb3JlIHRoaXMgbWV0aG9kLgotICAgICAqLwotICAgICAgICBwcm90ZWN0ZWQgdm9pZCBub3JtYWxpemVEb2N1bWVudChDb3JlRG9jdW1lbnRJbXBsIGRvY3VtZW50LCBET01Db25maWd1cmF0aW9uSW1wbCBjb25maWcpIHsKLQotICAgICAgICAgICAgICAgIGZEb2N1bWVudCA9IGRvY3VtZW50OwotICAgICAgICAgICAgICAgIGZDb25maWd1cmF0aW9uID0gY29uZmlnOwotCi0gICAgICAgICAgICAgICAgLy8gaW50aWFsaXplIGFuZCByZXNldCBET01Ob3JtYWxpemVyIGNvbXBvbmVudAotICAgICAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAgICAgZlN5bWJvbFRhYmxlID0gKFN5bWJvbFRhYmxlKSBmQ29uZmlndXJhdGlvbi5nZXRQcm9wZXJ0eShET01Db25maWd1cmF0aW9uSW1wbC5TWU1CT0xfVEFCTEUpOwotICAgICAgICAgICAgICAgIC8vIHJlc2V0IG5hbWVzcGFjZSBjb250ZXh0Ci0gICAgICAgICAgICAgICAgZk5hbWVzcGFjZUNvbnRleHQucmVzZXQoKTsKLSAgICAgICAgICAgICAgICBmTmFtZXNwYWNlQ29udGV4dC5kZWNsYXJlUHJlZml4KFhNTFN5bWJvbHMuRU1QVFlfU1RSSU5HLCBYTUxTeW1ib2xzLkVNUFRZX1NUUklORyk7Ci0KLSAgICAgICAgICAgICAgICBpZiAoKGZDb25maWd1cmF0aW9uLmZlYXR1cmVzICYgRE9NQ29uZmlndXJhdGlvbkltcGwuVkFMSURBVEUpICE9IDApIHsKLSAgICAgICAgICAgIFN0cmluZyBzY2hlbWFMYW5nID0gKFN0cmluZylmQ29uZmlndXJhdGlvbi5nZXRQcm9wZXJ0eShET01Db25maWd1cmF0aW9uSW1wbC5KQVhQX1NDSEVNQV9MQU5HVUFHRSk7Ci0KLSAgICAgICAgICAgIGlmKHNjaGVtYUxhbmcgIT0gbnVsbCAmJiBzY2hlbWFMYW5nLmVxdWFscyhDb25zdGFudHMuTlNfWE1MU0NIRU1BKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgZlZhbGlkYXRpb25IYW5kbGVyID0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29yZURPTUltcGxlbWVudGF0aW9uSW1wbC5zaW5nbGV0b24uZ2V0VmFsaWRhdG9yKFhNTEdyYW1tYXJEZXNjcmlwdGlvbi5YTUxfU0NIRU1BKTsKLSAgICAgICAgICAgICAgICBmQ29uZmlndXJhdGlvbi5zZXRGZWF0dXJlKERPTUNvbmZpZ3VyYXRpb25JbXBsLlNDSEVNQSwgdHJ1ZSk7Ci0gICAgICAgICAgICAgICAgZkNvbmZpZ3VyYXRpb24uc2V0RmVhdHVyZShET01Db25maWd1cmF0aW9uSW1wbC5TQ0hFTUFfRlVMTF9DSEVDS0lORywgdHJ1ZSk7Ci0gICAgICAgICAgICAgICAgLy8gcmVwb3J0IGZhdGFsIGVycm9yIG9uIERPTSBMZXZlbCAxIG5vZGVzCi0gICAgICAgICAgICAgICAgZk5hbWVzcGFjZVZhbGlkYXRpb24gPSB0cnVlOwotCi0gICAgICAgICAgICAgICAgLy8gY2hlY2sgaWYgd2UgbmVlZCB0byBmaWxsIGluIFBTVkkKLSAgICAgICAgICAgICAgICBmUFNWSSA9ICgoZkNvbmZpZ3VyYXRpb24uZmVhdHVyZXMgJiBET01Db25maWd1cmF0aW9uSW1wbC5QU1ZJKSAhPTApP3RydWU6ZmFsc2U7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIGZDb25maWd1cmF0aW9uLnNldEZlYXR1cmUoRE9NQ29uZmlndXJhdGlvbkltcGwuWEVSQ0VTX1ZBTElEQVRJT04sIHRydWUpOwotCi0gICAgICAgICAgICAvLyByZXNldCBJRCB0YWJsZQotICAgICAgICAgICAgZkRvY3VtZW50LmNsZWFySWRlbnRpZmllcnMoKTsKLQotICAgICAgICAgICAgaWYoZlZhbGlkYXRpb25IYW5kbGVyICE9IG51bGwpCi0gICAgICAgICAgICAvLyByZXNldCBzY2hlbWEgdmFsaWRhdG9yCi0gICAgICAgICAgICAgICAgKChYTUxDb21wb25lbnQpIGZWYWxpZGF0aW9uSGFuZGxlcikucmVzZXQoZkNvbmZpZ3VyYXRpb24pOwotCi0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgZkVycm9ySGFuZGxlciA9IChET01FcnJvckhhbmRsZXIpIGZDb25maWd1cmF0aW9uLmdldFBhcmFtZXRlcihDb25zdGFudHMuRE9NX0VSUk9SX0hBTkRMRVIpOwotICAgICAgICAgICAgICAgIGlmIChmVmFsaWRhdGlvbkhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgZlZhbGlkYXRpb25IYW5kbGVyLnNldERvY3VtZW50SGFuZGxlcih0aGlzKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZWYWxpZGF0aW9uSGFuZGxlci5zdGFydERvY3VtZW50KAotICAgICAgICAgICAgICAgICAgICBuZXcgU2ltcGxlTG9jYXRvcihmRG9jdW1lbnQuZkRvY3VtZW50VVJJLCBmRG9jdW1lbnQuZkRvY3VtZW50VVJJLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLTEsIC0xICksIGZEb2N1bWVudC5lbmNvZGluZywgZk5hbWVzcGFjZUNvbnRleHQsIG51bGwpOwotCi0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBOb2RlIGtpZCwgbmV4dDsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoa2lkID0gZkRvY3VtZW50LmdldEZpcnN0Q2hpbGQoKTsga2lkICE9IG51bGw7IGtpZCA9IG5leHQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV4dCA9IGtpZC5nZXROZXh0U2libGluZygpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBraWQgPSBub3JtYWxpemVOb2RlKGtpZCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChraWQgIT0gbnVsbCkgeyAvLyBkb24ndCBhZHZhbmNlCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV4dCA9IGtpZDsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyByZWxlYXNlIHJlc291cmNlcwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZWYWxpZGF0aW9uSGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZWYWxpZGF0aW9uSGFuZGxlci5lbmREb2N1bWVudChudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29yZURPTUltcGxlbWVudGF0aW9uSW1wbC5zaW5nbGV0b24ucmVsZWFzZVZhbGlkYXRvcigKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxHcmFtbWFyRGVzY3JpcHRpb24uWE1MX1NDSEVNQSwgZlZhbGlkYXRpb25IYW5kbGVyKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZlZhbGlkYXRpb25IYW5kbGVyID0gbnVsbDsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9IGNhdGNoIChBYm9ydEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICAgICAgdGhyb3cgZTsgICAgLy8gb3RoZXJ3aXNlIHJlLXRocm93LgotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICB9Ci0KLQotICAgIC8qKgotICAgICAqCi0gICAgICogVGhpcyBtZXRob2QgYWN0cyBhcyBpZiB0aGUgZG9jdW1lbnQgd2FzIGdvaW5nIHRocm91Z2ggYSBzYXZlCi0gICAgICogYW5kIGxvYWQgY3ljbGUsIHB1dHRpbmcgdGhlIGRvY3VtZW50IGluIGEgIm5vcm1hbCIgZm9ybS4gVGhlIGFjdHVhbCByZXN1bHQKLSAgICAgKiBkZXBlbmRzIG9uIHRoZSBmZWF0dXJlcyBiZWluZyBzZXQgYW5kIGdvdmVybmluZyB3aGF0IG9wZXJhdGlvbnMgYWN0dWFsbHkKLSAgICAgKiB0YWtlIHBsYWNlLiBTZWUgc2V0Tm9ybWFsaXphdGlvbkZlYXR1cmUgZm9yIGRldGFpbHMuIE5vdGljZWFibHkgdGhpcyBtZXRob2QKLSAgICAgKiBub3JtYWxpemVzIFRleHQgbm9kZXMsIG1ha2VzIHRoZSBkb2N1bWVudCAibmFtZXNwYWNlIHdlbGxmb3JtZWQiLAotICAgICAqIGFjY29yZGluZyB0byB0aGUgYWxnb3JpdGhtIGRlc2NyaWJlZCBiZWxvdyBpbiBwc2V1ZG8gY29kZSwgYnkgYWRkaW5nIG1pc3NpbmcKLSAgICAgKiBuYW1lc3BhY2UgZGVjbGFyYXRpb24gYXR0cmlidXRlcyBhbmQgYWRkaW5nIG9yIGNoYW5naW5nIG5hbWVzcGFjZSBwcmVmaXhlcywgdXBkYXRlcwotICAgICAqIHRoZSByZXBsYWNlbWVudCB0cmVlIG9mIEVudGl0eVJlZmVyZW5jZSBub2Rlcyxub3JtYWxpemVzIGF0dHJpYnV0ZSB2YWx1ZXMsIGV0Yy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBub2RlICAgTW9kaWZpZWQgbm9kZSBvciBudWxsLiBJZiBub2RlIGlzIHJldHVybmVkLCB3ZSBuZWVkCi0gICAgICogICAgICAgICAgICAgICB0byBub3JtYWxpemUgYWdhaW4gc3RhcnRpbmcgb24gdGhlIG5vZGUgcmV0dXJuZWQuCi0gICAgICogQHJldHVybiAgdGhlIG5vcm1hbGl6ZWQgTm9kZQotICAgICAqLwotICAgIHByb3RlY3RlZCBOb2RlIG5vcm1hbGl6ZU5vZGUgKE5vZGUgbm9kZSl7Ci0KLSAgICAgICAgaW50IHR5cGUgPSBub2RlLmdldE5vZGVUeXBlKCk7Ci0gICAgICAgIGJvb2xlYW4gd2VsbGZvcm1lZDsKLSAgICAgICAgZkxvY2F0b3IuZlJlbGF0ZWROb2RlPW5vZGU7Ci0KLSAgICAgICAgc3dpdGNoICh0eXBlKSB7Ci0gICAgICAgIGNhc2UgTm9kZS5ET0NVTUVOVF9UWVBFX05PREU6IHsKLSAgICAgICAgICAgICAgICBpZiAoREVCVUdfTkQpIHsKLSAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCI9PT5ub3JtYWxpemVOb2RlOntkb2N0eXBlfSIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBEb2N1bWVudFR5cGVJbXBsIGRvY1R5cGUgPSAoRG9jdW1lbnRUeXBlSW1wbClub2RlOwotICAgICAgICAgICAgICAgIGZEVERWYWxpZGF0b3IgPSAoWE1MRFREVmFsaWRhdG9yKUNvcmVET01JbXBsZW1lbnRhdGlvbkltcGwuc2luZ2xldG9uLmdldFZhbGlkYXRvcihYTUxHcmFtbWFyRGVzY3JpcHRpb24uWE1MX0RURCk7Ci0gICAgICAgICAgICAgICAgZkRURFZhbGlkYXRvci5zZXREb2N1bWVudEhhbmRsZXIodGhpcyk7Ci0gICAgICAgICAgICAgICAgZkNvbmZpZ3VyYXRpb24uc2V0UHJvcGVydHkoQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuWE1MR1JBTU1BUl9QT09MX1BST1BFUlRZLCBjcmVhdGVHcmFtbWFyUG9vbChkb2NUeXBlKSk7Ci0gICAgICAgICAgICAgICAgZkRURFZhbGlkYXRvci5yZXNldChmQ29uZmlndXJhdGlvbik7Ci0gICAgICAgICAgICAgICAgZkRURFZhbGlkYXRvci5zdGFydERvY3VtZW50KAotICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFNpbXBsZUxvY2F0b3IoZkRvY3VtZW50LmZEb2N1bWVudFVSSSwgZkRvY3VtZW50LmZEb2N1bWVudFVSSSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAtMSwgLTEgKSwgZkRvY3VtZW50LmVuY29kaW5nLCBmTmFtZXNwYWNlQ29udGV4dCwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgZkRURFZhbGlkYXRvci5kb2N0eXBlRGVjbChkb2NUeXBlLmdldE5hbWUoKSwgZG9jVHlwZS5nZXRQdWJsaWNJZCgpLCBkb2NUeXBlLmdldFN5c3RlbUlkKCksIG51bGwpOwotICAgICAgICAgICAgICAgIC8vUkVWSVNJVDogd2VsbC1mb3JtbmVzcyBlbmNvZGluZyBpbmZvCi0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgY2FzZSBOb2RlLkVMRU1FTlRfTk9ERTogewotICAgICAgICAgICAgICAgIGlmIChERUJVR19ORCkgewotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIj09Pm5vcm1hbGl6ZU5vZGU6e2VsZW1lbnR9ICIrbm9kZS5nZXROb2RlTmFtZSgpKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvL2RvIHRoZSBuYW1lIGNoZWNrIG9ubHkgd2hlbiB2ZXJzaW9uIG9mIHRoZSBkb2N1bWVudCB3YXMgY2hhbmdlZCAmCi0gICAgICAgICAgICAgICAgLy9hcHBsaWNhdGlvbiBoYXMgc2V0IHRoZSB2YWx1ZSBvZiB3ZWxsLWZvcm1lZCBmZWF0dXJlcyB0byB0cnVlCi0gICAgICAgICAgICAgICAgaWYgKGZEb2N1bWVudC5lcnJvckNoZWNraW5nKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmICggKChmQ29uZmlndXJhdGlvbi5mZWF0dXJlcyAmIERPTUNvbmZpZ3VyYXRpb25JbXBsLldFTExGT1JNRUQpICE9IDApICYmCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZkRvY3VtZW50LmlzWE1MVmVyc2lvbkNoYW5nZWQoKSl7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZk5hbWVzcGFjZVZhbGlkYXRpb24pewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdlbGxmb3JtZWQgPSBDb3JlRG9jdW1lbnRJbXBsLmlzVmFsaWRRTmFtZShub2RlLmdldFByZWZpeCgpICwgbm9kZS5nZXRMb2NhbE5hbWUoKSwgZkRvY3VtZW50LmlzWE1MMTFWZXJzaW9uKCkpIDsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdlbGxmb3JtZWQgPSBDb3JlRG9jdW1lbnRJbXBsLmlzWE1MTmFtZShub2RlLmdldE5vZGVOYW1lKCkgLCBmRG9jdW1lbnQuaXNYTUwxMVZlcnNpb24oKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXdlbGxmb3JtZWQpewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBtc2cgPSBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAid2YtaW52YWxpZC1jaGFyYWN0ZXItaW4tbm9kZS1uYW1lIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXsiRWxlbWVudCIsIG5vZGUuZ2V0Tm9kZU5hbWUoKX0pOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydERPTUVycm9yKGZFcnJvckhhbmRsZXIsIGZFcnJvciwgZkxvY2F0b3IsIG1zZywgRE9NRXJyb3IuU0VWRVJJVFlfRVJST1IsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIndmLWludmFsaWQtY2hhcmFjdGVyLWluLW5vZGUtbmFtZSIpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIC8vIHB1c2ggbmFtZXNwYWNlIGNvbnRleHQKLSAgICAgICAgICAgICAgICBmTmFtZXNwYWNlQ29udGV4dC5wdXNoQ29udGV4dCgpOwotICAgICAgICAgICAgICAgIGZMb2NhbE5TQmluZGVyLnJlc2V0KCk7Ci0KLSAgICAgICAgICAgICAgICBFbGVtZW50SW1wbCBlbGVtID0gKEVsZW1lbnRJbXBsKW5vZGU7Ci0gICAgICAgICAgICAgICAgaWYgKGVsZW0ubmVlZHNTeW5jQ2hpbGRyZW4oKSkgewotICAgICAgICAgICAgICAgICAgICBlbGVtLnN5bmNocm9uaXplQ2hpbGRyZW4oKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgQXR0cmlidXRlTWFwIGF0dHJpYnV0ZXMgPSAoZWxlbS5oYXNBdHRyaWJ1dGVzKCkpID8gKEF0dHJpYnV0ZU1hcCkgZWxlbS5nZXRBdHRyaWJ1dGVzKCkgOiBudWxsOwotCi0gICAgICAgICAgICAgICAgLy8gZml4IG5hbWVzcGFjZXMgYW5kIHJlbW92ZSBkZWZhdWx0IGF0dHJpYnV0ZXMKLSAgICAgICAgICAgICAgICBpZiAoKGZDb25maWd1cmF0aW9uLmZlYXR1cmVzICYgRE9NQ29uZmlndXJhdGlvbkltcGwuTkFNRVNQQUNFUykgIT0wKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIGZpeCBuYW1lc3BhY2VzCi0gICAgICAgICAgICAgICAgICAgIC8vIG5vcm1hbGl6ZSBhdHRyaWJ1dGUgdmFsdWVzCi0gICAgICAgICAgICAgICAgICAgIC8vIHJlbW92ZSBkZWZhdWx0IGF0dHJpYnV0ZXMKLSAgICAgICAgICAgICAgICAgICAgbmFtZXNwYWNlRml4VXAoZWxlbSwgYXR0cmlidXRlcyk7Ci0KLSAgICAgICAgICAgICAgICAgICAgaWYgKChmQ29uZmlndXJhdGlvbi5mZWF0dXJlcyAmIERPTUNvbmZpZ3VyYXRpb25JbXBsLk5TREVDTCkgPT0gMCAmJiBhdHRyaWJ1dGVzICE9IG51bGwgKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGF0dHJpYnV0ZXMuZ2V0TGVuZ3RoKCk7ICsraSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0dHIgYXR0ID0gKEF0dHIpYXR0cmlidXRlcy5nZXRJdGVtKGkpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChYTUxTeW1ib2xzLlBSRUZJWF9YTUxOUy5lcXVhbHMoYXR0LmdldFByZWZpeCgpKSB8fAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxTeW1ib2xzLlBSRUZJWF9YTUxOUy5lcXVhbHMoYXR0LmdldE5hbWUoKSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbS5yZW1vdmVBdHRyaWJ1dGVOb2RlKGF0dCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0taTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmICggYXR0cmlidXRlcyE9bnVsbCApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoIGludCBpPTA7IGk8YXR0cmlidXRlcy5nZXRMZW5ndGgoKTsgKytpICkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0dHIgYXR0ciA9IChBdHRyKWF0dHJpYnV0ZXMuaXRlbShpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3JlbW92ZURlZmF1bHQoYXR0ciwgYXR0cmlidXRlcyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0ci5ub3JtYWxpemUoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZkRvY3VtZW50LmVycm9yQ2hlY2tpbmcgJiYgKChmQ29uZmlndXJhdGlvbi5mZWF0dXJlcyAmIERPTUNvbmZpZ3VyYXRpb25JbXBsLldFTExGT1JNRUQpICE9IDApKXsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzQXR0clZhbHVlV0YoZkVycm9ySGFuZGxlciwgZkVycm9yLCBmTG9jYXRvciwgYXR0cmlidXRlcywgKEF0dHJJbXBsKWF0dHIsIGF0dHIuZ2V0VmFsdWUoKSwgZkRvY3VtZW50LmlzWE1MMTFWZXJzaW9uKCkpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZkRvY3VtZW50LmlzWE1MVmVyc2lvbkNoYW5nZWQoKSl7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3ZWxsZm9ybWVkPUNvcmVEb2N1bWVudEltcGwuaXNYTUxOYW1lKG5vZGUuZ2V0Tm9kZU5hbWUoKSAsIGZEb2N1bWVudC5pc1hNTDExVmVyc2lvbigpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghd2VsbGZvcm1lZCl7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbXNnID0gRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ3Zi1pbnZhbGlkLWNoYXJhY3Rlci1pbi1ub2RlLW5hbWUiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdeyJBdHRyIixub2RlLmdldE5vZGVOYW1lKCl9KTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydERPTUVycm9yKGZFcnJvckhhbmRsZXIsIGZFcnJvciwgZkxvY2F0b3IsIG1zZywgRE9NRXJyb3IuU0VWRVJJVFlfRVJST1IsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIndmLWludmFsaWQtY2hhcmFjdGVyLWluLW5vZGUtbmFtZSIpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotCi0KLSAgICAgICAgICAgICAgICBpZiAoZlZhbGlkYXRpb25IYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gUkVWSVNJVDogcG9zc2libGUgc29sdXRpb25zIHRvIGRpc2NhcmQgZGVmYXVsdCBjb250ZW50IGFyZToKLSAgICAgICAgICAgICAgICAgICAgLy8gICAgICAgICBlaXRoZXIgd2UgcGFzcyBzb21lIGZsYWcgdG8gWE1MIFNjaGVtYSB2YWxpZGF0b3IKLSAgICAgICAgICAgICAgICAgICAgLy8gICAgICAgICBvciByZWx5IG9uIHRoZSBQU1ZJIGluZm9ybWF0aW9uLgotICAgICAgICAgICAgICAgICAgICBmQXR0clByb3h5LnNldEF0dHJpYnV0ZXMoYXR0cmlidXRlcywgZkRvY3VtZW50LCBlbGVtKTsKLSAgICAgICAgICAgICAgICAgICAgdXBkYXRlUU5hbWUoZWxlbSwgZlFOYW1lKTsgLy8gdXBkYXRlcyBnbG9iYWwgcW5hbWUKLSAgICAgICAgICAgICAgICAgICAgLy8gc2V0IGVycm9yIG5vZGUgaW4gdGhlIGRvbSBlcnJvciB3cmFwcGVyCi0gICAgICAgICAgICAgICAgICAgIC8vIHNvIGlmIGVycm9yIG9jY3VycyB3ZSBjYW4gcmVwb3J0IGFuIGVycm9yIG5vZGUKLSAgICAgICAgICAgICAgICAgICAgZkNvbmZpZ3VyYXRpb24uZkVycm9ySGFuZGxlcldyYXBwZXIuZkN1cnJlbnROb2RlID0gbm9kZTsKLSAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnROb2RlID0gbm9kZTsKLSAgICAgICAgICAgICAgICAgICAgLy8gY2FsbCByZS12YWxpZGF0aW9uIGhhbmRsZXIKLSAgICAgICAgICAgICAgICAgICAgZlZhbGlkYXRpb25IYW5kbGVyLnN0YXJ0RWxlbWVudChmUU5hbWUsIGZBdHRyUHJveHksIG51bGwpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIGlmIChmRFREVmFsaWRhdG9yICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gUkVWSVNJVDogcG9zc2libGUgc29sdXRpb25zIHRvIGRpc2NhcmQgZGVmYXVsdCBjb250ZW50IGFyZToKLSAgICAgICAgICAgICAgICAgICAgLy8gICAgICAgICBlaXRoZXIgd2UgcGFzcyBzb21lIGZsYWcgdG8gWE1MIFNjaGVtYSB2YWxpZGF0b3IKLSAgICAgICAgICAgICAgICAgICAgLy8gICAgICAgICBvciByZWx5IG9uIHRoZSBQU1ZJIGluZm9ybWF0aW9uLgotICAgICAgICAgICAgICAgICAgICBmQXR0clByb3h5LnNldEF0dHJpYnV0ZXMoYXR0cmlidXRlcywgZkRvY3VtZW50LCBlbGVtKTsKLSAgICAgICAgICAgICAgICAgICAgdXBkYXRlUU5hbWUoZWxlbSwgZlFOYW1lKTsgLy8gdXBkYXRlcyBnbG9iYWwgcW5hbWUKLSAgICAgICAgICAgICAgICAgICAgLy8gc2V0IGVycm9yIG5vZGUgaW4gdGhlIGRvbSBlcnJvciB3cmFwcGVyCi0gICAgICAgICAgICAgICAgICAgIC8vIHNvIGlmIGVycm9yIG9jY3VycyB3ZSBjYW4gcmVwb3J0IGFuIGVycm9yIG5vZGUKLSAgICAgICAgICAgICAgICAgICAgZkNvbmZpZ3VyYXRpb24uZkVycm9ySGFuZGxlcldyYXBwZXIuZkN1cnJlbnROb2RlID0gbm9kZTsKLSAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnROb2RlID0gbm9kZTsKLSAgICAgICAgICAgICAgICAgICAgLy8gY2FsbCByZS12YWxpZGF0aW9uIGhhbmRsZXIKLSAgICAgICAgICAgICAgICAgICAgZkRURFZhbGlkYXRvci5zdGFydEVsZW1lbnQoZlFOYW1lLCBmQXR0clByb3h5LCBudWxsKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyBub3JtYWxpemUgY2hpbGRyZW4KLSAgICAgICAgICAgICAgICBOb2RlIGtpZCwgbmV4dDsKLSAgICAgICAgICAgICAgICBmb3IgKGtpZCA9IGVsZW0uZ2V0Rmlyc3RDaGlsZCgpOyBraWQgIT0gbnVsbDsga2lkID0gbmV4dCkgewotICAgICAgICAgICAgICAgICAgICBuZXh0ID0ga2lkLmdldE5leHRTaWJsaW5nKCk7Ci0gICAgICAgICAgICAgICAgICAgIGtpZCA9IG5vcm1hbGl6ZU5vZGUoa2lkKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGtpZCAhPW51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIG5leHQgPSBraWQ7ICAvLyBkb24ndCBhZHZhbmNlCi0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaWYgKERFQlVHX05EKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIG5vcm1hbGl6ZWQgc3VidHJlZQotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIioqKlRoZSBjaGlsZHJlbiBvZiB7Iitub2RlLmdldE5vZGVOYW1lKCkrIn0gYXJlIG5vcm1hbGl6ZWQiKTsKLSAgICAgICAgICAgICAgICAgICAgZm9yIChraWQgPSBlbGVtLmdldEZpcnN0Q2hpbGQoKTsga2lkICE9IG51bGw7IGtpZCA9IG5leHQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIG5leHQgPSBraWQuZ2V0TmV4dFNpYmxpbmcoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbihraWQuZ2V0Tm9kZU5hbWUoKSArIlsiK2tpZC5nZXROb2RlVmFsdWUoKSsiXSIpOwotICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICB9Ci0KLQotICAgICAgICAgICAgICAgIGlmIChmVmFsaWRhdGlvbkhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICB1cGRhdGVRTmFtZShlbGVtLCBmUU5hbWUpOyAvLyB1cGRhdGVzIGdsb2JhbCBxbmFtZQotICAgICAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgICAgICAvLyBzZXQgZXJyb3Igbm9kZSBpbiB0aGUgZG9tIGVycm9yIHdyYXBwZXIKLSAgICAgICAgICAgICAgICAgICAgLy8gc28gaWYgZXJyb3Igb2NjdXJzIHdlIGNhbiByZXBvcnQgYW4gZXJyb3Igbm9kZQotICAgICAgICAgICAgICAgICAgICBmQ29uZmlndXJhdGlvbi5mRXJyb3JIYW5kbGVyV3JhcHBlci5mQ3VycmVudE5vZGUgPSBub2RlOwotICAgICAgICAgICAgICAgICAgICBmQ3VycmVudE5vZGUgPSBub2RlOwotICAgICAgICAgICAgICAgICAgICBmVmFsaWRhdGlvbkhhbmRsZXIuZW5kRWxlbWVudChmUU5hbWUsIG51bGwpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIGlmIChmRFREVmFsaWRhdG9yICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgdXBkYXRlUU5hbWUoZWxlbSwgZlFOYW1lKTsgLy8gdXBkYXRlcyBnbG9iYWwgcW5hbWUKLSAgICAgICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICAgICAgLy8gc2V0IGVycm9yIG5vZGUgaW4gdGhlIGRvbSBlcnJvciB3cmFwcGVyCi0gICAgICAgICAgICAgICAgICAgIC8vIHNvIGlmIGVycm9yIG9jY3VycyB3ZSBjYW4gcmVwb3J0IGFuIGVycm9yIG5vZGUKLSAgICAgICAgICAgICAgICAgICAgZkNvbmZpZ3VyYXRpb24uZkVycm9ySGFuZGxlcldyYXBwZXIuZkN1cnJlbnROb2RlID0gbm9kZTsKLSAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnROb2RlID0gbm9kZTsKLSAgICAgICAgICAgICAgICAgICAgZkRURFZhbGlkYXRvci5lbmRFbGVtZW50KGZRTmFtZSwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgLy8gcG9wIG5hbWVzcGFjZSBjb250ZXh0Ci0gICAgICAgICAgICAgICAgZk5hbWVzcGFjZUNvbnRleHQucG9wQ29udGV4dCgpOwotCi0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgY2FzZSBOb2RlLkNPTU1FTlRfTk9ERTogewotICAgICAgICAgICAgICAgIGlmIChERUJVR19ORCkgewotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIj09Pm5vcm1hbGl6ZU5vZGU6e2NvbW1lbnRzfSIpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIGlmICgoZkNvbmZpZ3VyYXRpb24uZmVhdHVyZXMgJiBET01Db25maWd1cmF0aW9uSW1wbC5DT01NRU5UUykgPT0gMCkgewotICAgICAgICAgICAgICAgICAgICBOb2RlIHByZXZTaWJsaW5nID0gbm9kZS5nZXRQcmV2aW91c1NpYmxpbmcoKTsKLSAgICAgICAgICAgICAgICAgICAgTm9kZSBwYXJlbnQgPSBub2RlLmdldFBhcmVudE5vZGUoKTsKLSAgICAgICAgICAgICAgICAgICAgLy8gcmVtb3ZlIHRoZSBjb21tZW50IG5vZGUKLSAgICAgICAgICAgICAgICAgICAgcGFyZW50LnJlbW92ZUNoaWxkKG5vZGUpOwotICAgICAgICAgICAgICAgICAgICBpZiAocHJldlNpYmxpbmcgIT0gbnVsbCAmJiBwcmV2U2libGluZy5nZXROb2RlVHlwZSgpID09IE5vZGUuVEVYVF9OT0RFKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBOb2RlIG5leHRTaWJsaW5nID0gcHJldlNpYmxpbmcuZ2V0TmV4dFNpYmxpbmcoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuZXh0U2libGluZyAhPSBudWxsICYmIG5leHRTaWJsaW5nLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5URVhUX05PREUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKFRleHRJbXBsKW5leHRTaWJsaW5nKS5pbnNlcnREYXRhKDAsIHByZXZTaWJsaW5nLmdldE5vZGVWYWx1ZSgpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnQucmVtb3ZlQ2hpbGQocHJldlNpYmxpbmcpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXh0U2libGluZzsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0vL2lmIGNvbW1lbnQgbm9kZSBuZWVkIG5vdCBiZSByZW1vdmVkCi0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChmRG9jdW1lbnQuZXJyb3JDaGVja2luZyAmJiAoKGZDb25maWd1cmF0aW9uLmZlYXR1cmVzICYgRE9NQ29uZmlndXJhdGlvbkltcGwuV0VMTEZPUk1FRCkgIT0gMCkpewotICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGNvbW1lbnRkYXRhID0gKChDb21tZW50KW5vZGUpLmdldERhdGEoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNoZWNrIGNvbW1lbnRzIGZvciBpbnZhbGlkIHhtbCBjaHJhY3RlciBhcyBwZXIgdGhlIHZlcnNpb24KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIG9mIHRoZSBkb2N1bWVudAotICAgICAgICAgICAgICAgICAgICAgICAgaXNDb21tZW50V0YoZkVycm9ySGFuZGxlciwgZkVycm9yLCBmTG9jYXRvciwgY29tbWVudGRhdGEsIGZEb2N1bWVudC5pc1hNTDExVmVyc2lvbigpKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0vL2VuZC1lbHNlIGlmIGNvbW1lbnQgbm9kZSBpcyBub3QgdG8gYmUgcmVtb3ZlZC4KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIGNhc2UgTm9kZS5FTlRJVFlfUkVGRVJFTkNFX05PREU6IHsKLSAgICAgICAgICAgICAgICBpZiAoREVCVUdfTkQpIHsKLSAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCI9PT5ub3JtYWxpemVOb2RlOntlbnRpdHlSZWZ9ICIrbm9kZS5nZXROb2RlTmFtZSgpKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBpZiAoKGZDb25maWd1cmF0aW9uLmZlYXR1cmVzICYgRE9NQ29uZmlndXJhdGlvbkltcGwuRU5USVRJRVMpID09IDApIHsKLSAgICAgICAgICAgICAgICAgICAgTm9kZSBwcmV2U2libGluZyA9IG5vZGUuZ2V0UHJldmlvdXNTaWJsaW5nKCk7Ci0gICAgICAgICAgICAgICAgICAgIE5vZGUgcGFyZW50ID0gbm9kZS5nZXRQYXJlbnROb2RlKCk7Ci0gICAgICAgICAgICAgICAgICAgICgoRW50aXR5UmVmZXJlbmNlSW1wbClub2RlKS5zZXRSZWFkT25seShmYWxzZSwgdHJ1ZSk7Ci0gICAgICAgICAgICAgICAgICAgIGV4cGFuZEVudGl0eVJlZiAocGFyZW50LCBub2RlKTsKLSAgICAgICAgICAgICAgICAgICAgcGFyZW50LnJlbW92ZUNoaWxkKG5vZGUpOwotICAgICAgICAgICAgICAgICAgICBOb2RlIG5leHQgPSAocHJldlNpYmxpbmcgIT0gbnVsbCk/cHJldlNpYmxpbmcuZ2V0TmV4dFNpYmxpbmcoKTpwYXJlbnQuZ2V0Rmlyc3RDaGlsZCgpOwotICAgICAgICAgICAgICAgICAgICAvLyBUaGUgbGlzdCBvZiBjaGlsZHJlbiAjdGV4dCAtPiAmZW50OwotICAgICAgICAgICAgICAgICAgICAvLyBhbmQgZW50aXR5IGhhcyBhIGZpcnN0IGNoaWxkIGFzIGEgdGV4dAotICAgICAgICAgICAgICAgICAgICAvLyB3ZSBzaG91bGQgbm90IGFkdmFuY2UKLSAgICAgICAgICAgICAgICAgICAgaWYgKHByZXZTaWJsaW5nICE9IG51bGwgJiYgbmV4dCAhPSBudWxsICYmIHByZXZTaWJsaW5nLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5URVhUX05PREUgJiYKLSAgICAgICAgICAgICAgICAgICAgICAgIG5leHQuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLlRFWFRfTk9ERSkgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHByZXZTaWJsaW5nOyAgLy8gRG9uJ3QgYWR2YW5jZQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXh0OwotICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChmRG9jdW1lbnQuZXJyb3JDaGVja2luZyAmJiAoKGZDb25maWd1cmF0aW9uLmZlYXR1cmVzICYgRE9NQ29uZmlndXJhdGlvbkltcGwuV0VMTEZPUk1FRCkgIT0gMCkgJiYKLSAgICAgICAgICAgICAgICAgICAgICAgIGZEb2N1bWVudC5pc1hNTFZlcnNpb25DaGFuZ2VkKCkpewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvcmVEb2N1bWVudEltcGwuaXNYTUxOYW1lKG5vZGUuZ2V0Tm9kZU5hbWUoKSAsIGZEb2N1bWVudC5pc1hNTDExVmVyc2lvbigpKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAvLyBSRVZJU0lUOiB0cmF2ZXJzZSBlbnRpdHkgcmVmZXJlbmNlIGFuZCBzZW5kIGFwcHJvcHJpYXRlIGNhbGxzIHRvIHRoZSB2YWxpZGF0b3IKLSAgICAgICAgICAgICAgICAgICAgLy8gKG5vIG5vcm1hbGl6YXRpb24gc2hvdWxkIGJlIHBlcmZvcm1lZCBmb3IgdGhlIGNoaWxkcmVuKS4KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgY2FzZSBOb2RlLkNEQVRBX1NFQ1RJT05fTk9ERTogewotICAgICAgICAgICAgICAgIGlmIChERUJVR19ORCkgewotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIj09Pm5vcm1hbGl6ZU5vZGU6e2NkYXRhfSIpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIGlmICgoZkNvbmZpZ3VyYXRpb24uZmVhdHVyZXMgJiBET01Db25maWd1cmF0aW9uSW1wbC5DREFUQSkgPT0gMCkgewotICAgICAgICAgICAgICAgICAgICAvLyBjb252ZXJ0IENEQVRBIHRvIFRFWFQgbm9kZXMKLSAgICAgICAgICAgICAgICAgICAgTm9kZSBwcmV2U2libGluZyA9IG5vZGUuZ2V0UHJldmlvdXNTaWJsaW5nKCk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChwcmV2U2libGluZyAhPSBudWxsICYmIHByZXZTaWJsaW5nLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5URVhUX05PREUpewotICAgICAgICAgICAgICAgICAgICAgICAgKChUZXh0KXByZXZTaWJsaW5nKS5hcHBlbmREYXRhKG5vZGUuZ2V0Tm9kZVZhbHVlKCkpOwotICAgICAgICAgICAgICAgICAgICAgICAgbm9kZS5nZXRQYXJlbnROb2RlKCkucmVtb3ZlQ2hpbGQobm9kZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcHJldlNpYmxpbmc7IC8vZG9uJ3QgYWR2YW5jZQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgVGV4dCB0ZXh0ID0gZkRvY3VtZW50LmNyZWF0ZVRleHROb2RlKG5vZGUuZ2V0Tm9kZVZhbHVlKCkpOwotICAgICAgICAgICAgICAgICAgICAgICAgTm9kZSBwYXJlbnQgPSBub2RlLmdldFBhcmVudE5vZGUoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUgPSBwYXJlbnQucmVwbGFjZUNoaWxkKHRleHQsIG5vZGUpOwotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRleHQ7ICAvL2Rvbid0IGFkdmFuY2UKLQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgLy8gc2VuZCBjaGFyYWN0ZXJzIGNhbGwgZm9yIENEQVRBCi0gICAgICAgICAgICAgICAgaWYgKGZWYWxpZGF0aW9uSGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIHNldCBlcnJvciBub2RlIGluIHRoZSBkb20gZXJyb3Igd3JhcHBlcgotICAgICAgICAgICAgICAgICAgICAvLyBzbyBpZiBlcnJvciBvY2N1cnMgd2UgY2FuIHJlcG9ydCBhbiBlcnJvciBub2RlCi0gICAgICAgICAgICAgICAgICAgIGZDb25maWd1cmF0aW9uLmZFcnJvckhhbmRsZXJXcmFwcGVyLmZDdXJyZW50Tm9kZSA9IG5vZGU7Ci0gICAgICAgICAgICAgICAgICAgIGZDdXJyZW50Tm9kZSA9IG5vZGU7Ci0gICAgICAgICAgICAgICAgICAgIGZWYWxpZGF0aW9uSGFuZGxlci5zdGFydENEQVRBKG51bGwpOwotICAgICAgICAgICAgICAgICAgICBmVmFsaWRhdGlvbkhhbmRsZXIuY2hhcmFjdGVyRGF0YShub2RlLmdldE5vZGVWYWx1ZSgpLCBudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgZlZhbGlkYXRpb25IYW5kbGVyLmVuZENEQVRBKG51bGwpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIGlmIChmRFREVmFsaWRhdG9yICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gc2V0IGVycm9yIG5vZGUgaW4gdGhlIGRvbSBlcnJvciB3cmFwcGVyCi0gICAgICAgICAgICAgICAgICAgIC8vIHNvIGlmIGVycm9yIG9jY3VycyB3ZSBjYW4gcmVwb3J0IGFuIGVycm9yIG5vZGUKLSAgICAgICAgICAgICAgICAgICAgZkNvbmZpZ3VyYXRpb24uZkVycm9ySGFuZGxlcldyYXBwZXIuZkN1cnJlbnROb2RlID0gbm9kZTsKLSAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnROb2RlID0gbm9kZTsKLSAgICAgICAgICAgICAgICAgICAgZkRURFZhbGlkYXRvci5zdGFydENEQVRBKG51bGwpOwotICAgICAgICAgICAgICAgICAgICBmRFREVmFsaWRhdG9yLmNoYXJhY3RlckRhdGEobm9kZS5nZXROb2RlVmFsdWUoKSwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgIGZEVERWYWxpZGF0b3IuZW5kQ0RBVEEobnVsbCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIFN0cmluZyB2YWx1ZSA9IG5vZGUuZ2V0Tm9kZVZhbHVlKCk7Ci0KLSAgICAgICAgICAgICAgICBpZiAoKGZDb25maWd1cmF0aW9uLmZlYXR1cmVzICYgRE9NQ29uZmlndXJhdGlvbkltcGwuU1BMSVRDREFUQSkgIT0gMCkgewotICAgICAgICAgICAgICAgICAgICBpbnQgaW5kZXg7Ci0gICAgICAgICAgICAgICAgICAgIE5vZGUgcGFyZW50ID0gbm9kZS5nZXRQYXJlbnROb2RlKCk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChmRG9jdW1lbnQuZXJyb3JDaGVja2luZykgewotICAgICAgICAgICAgICAgICAgICAgICAgaXNYTUxDaGFyV0YoZkVycm9ySGFuZGxlciwgZkVycm9yLCBmTG9jYXRvciwgbm9kZS5nZXROb2RlVmFsdWUoKSwgZkRvY3VtZW50LmlzWE1MMTFWZXJzaW9uKCkpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIHdoaWxlICggKGluZGV4PXZhbHVlLmluZGV4T2YoIl1dPiIpKSA+PSAwICkgewotICAgICAgICAgICAgICAgICAgICAgICAgbm9kZS5zZXROb2RlVmFsdWUodmFsdWUuc3Vic3RyaW5nKDAsIGluZGV4KzIpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlID0gdmFsdWUuc3Vic3RyaW5nKGluZGV4ICsyKTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgTm9kZSBmaXJzdFNwbGl0Tm9kZSA9IG5vZGU7Ci0gICAgICAgICAgICAgICAgICAgICAgICBOb2RlIG5ld0NoaWxkID0gZkRvY3VtZW50LmNyZWF0ZUNEQVRBU2VjdGlvbih2YWx1ZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnQuaW5zZXJ0QmVmb3JlKG5ld0NoaWxkLCBub2RlLmdldE5leHRTaWJsaW5nKCkpOwotICAgICAgICAgICAgICAgICAgICAgICAgbm9kZSA9IG5ld0NoaWxkOwotICAgICAgICAgICAgICAgICAgICAgICAgLy8gaXNzdWUgd2FybmluZwotICAgICAgICAgICAgICAgICAgICAgICAgZkxvY2F0b3IuZlJlbGF0ZWROb2RlID0gZmlyc3RTcGxpdE5vZGU7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbXNnID0gRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAiY2RhdGEtc2VjdGlvbnMtc3BsaXR0ZWQiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydERPTUVycm9yKGZFcnJvckhhbmRsZXIsIGZFcnJvciwgZkxvY2F0b3IsIG1zZywgRE9NRXJyb3IuU0VWRVJJVFlfV0FSTklORywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAiY2RhdGEtc2VjdGlvbnMtc3BsaXR0ZWQiKTsKLSAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgaWYgKGZEb2N1bWVudC5lcnJvckNoZWNraW5nKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIGNoZWNrIHdlbGwtZm9ybWVkbmVzcwotICAgICAgICAgICAgICAgICAgICBpc0NEYXRhV0YoZkVycm9ySGFuZGxlciwgZkVycm9yLCBmTG9jYXRvciwgdmFsdWUsIGZEb2N1bWVudC5pc1hNTDExVmVyc2lvbigpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgY2FzZSBOb2RlLlRFWFRfTk9ERTogewotICAgICAgICAgICAgICAgIGlmIChERUJVR19ORCkgewotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIj09Pm5vcm1hbGl6ZU5vZGUodGV4dCk6eyIrbm9kZS5nZXROb2RlVmFsdWUoKSsifSIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvLyBJZiBub2RlIGlzIGEgdGV4dCBub2RlLCB3ZSBuZWVkIHRvIGNoZWNrIGZvciBvbmUgb2YgdHdvCi0gICAgICAgICAgICAgICAgLy8gY29uZGl0aW9uczoKLSAgICAgICAgICAgICAgICAvLyAgIDEpIFRoZXJlIGlzIGFuIGFkamFjZW50IHRleHQgbm9kZQotICAgICAgICAgICAgICAgIC8vICAgMikgVGhlcmUgaXMgbm8gYWRqYWNlbnQgdGV4dCBub2RlLCBidXQgbm9kZSBpcwotICAgICAgICAgICAgICAgIC8vICAgICAgYW4gZW1wdHkgdGV4dCBub2RlLgotICAgICAgICAgICAgICAgIE5vZGUgbmV4dCA9IG5vZGUuZ2V0TmV4dFNpYmxpbmcoKTsKLSAgICAgICAgICAgICAgICAvLyBJZiBhbiBhZGphY2VudCB0ZXh0IG5vZGUsIG1lcmdlIGl0IHdpdGggdGhpcyBub2RlCi0gICAgICAgICAgICAgICAgaWYgKCBuZXh0IT1udWxsICYmIG5leHQuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLlRFWFRfTk9ERSApIHsKLSAgICAgICAgICAgICAgICAgICAgKChUZXh0KW5vZGUpLmFwcGVuZERhdGEobmV4dC5nZXROb2RlVmFsdWUoKSk7Ci0gICAgICAgICAgICAgICAgICAgIG5vZGUuZ2V0UGFyZW50Tm9kZSgpLnJlbW92ZUNoaWxkKCBuZXh0ICk7Ci0gICAgICAgICAgICAgICAgICAgIC8vIFdlIGRvbid0IG5lZWQgdG8gY2hlY2sgd2VsbC1mb3JtbmVzcyBoZXJlIHNpbmNlIHdlIGFyZSBub3QgeWV0Ci0gICAgICAgICAgICAgICAgICAgIC8vIGRvbmUgd2l0aCB0aGlzIG5vZGUuCi0KLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5vZGU7IC8vIERvbid0IGFkdmFuY2U7Ci0gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChub2RlLmdldE5vZGVWYWx1ZSgpLmxlbmd0aCgpPT0wKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIElmIGtpZCBpcyBlbXB0eSwgcmVtb3ZlIGl0Ci0gICAgICAgICAgICAgICAgICAgIG5vZGUuZ2V0UGFyZW50Tm9kZSgpLnJlbW92ZUNoaWxkKCBub2RlICk7Ci0gICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gdmFsaWRhdG9yLmNoYXJhY3RlcnMoKSBjYWxsIGFuZCB3ZWxsLWZvcm1uZXNzCi0gICAgICAgICAgICAgICAgICAgIC8vIERvbid0IHNlbmQgY2hhcmFjdGVycyBvciBjaGVjayB3ZWxsLWZvcm1uZXNzIGluIHRoZSBmb2xsb3dpbmcgY2FzZXM6Ci0gICAgICAgICAgICAgICAgICAgIC8vIDEuIGVudGl0aWVzIGlzIGZhbHNlLCBuZXh0IGNoaWxkIGlzIGVudGl0eSByZWZlcmVuY2U6IGV4cGFuZCB0cmVlIGZpcnN0Ci0gICAgICAgICAgICAgICAgICAgIC8vIDIuIGNvbW1lbnRzIGlzIGZhbHNlLCBhbmQgbmV4dCBjaGlsZCBpcyBjb21tZW50Ci0gICAgICAgICAgICAgICAgICAgIC8vIDMuIGNkYXRhIGlzIGZhbHNlLCBhbmQgbmV4dCBjaGlsZCBpcyBjZGF0YQotCi0gICAgICAgICAgICAgICAgICAgIHNob3J0IG5leHRUeXBlID0gKG5leHQgIT0gbnVsbCk/bmV4dC5nZXROb2RlVHlwZSgpOi0xOwotICAgICAgICAgICAgICAgICAgICBpZiAobmV4dFR5cGUgPT0gLTEgfHwgISgoKGZDb25maWd1cmF0aW9uLmZlYXR1cmVzICYgRE9NQ29uZmlndXJhdGlvbkltcGwuRU5USVRJRVMpID09IDAgJiYKLSAgICAgICAgICAgICAgICAgICAgICAgICAgIG5leHRUeXBlID09IE5vZGUuRU5USVRZX05PREUpIHx8Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICgoZkNvbmZpZ3VyYXRpb24uZmVhdHVyZXMgJiBET01Db25maWd1cmF0aW9uSW1wbC5DT01NRU5UUykgPT0gMCAmJgotICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV4dFR5cGUgPT0gTm9kZS5DT01NRU5UX05PREUpIHx8Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICgoZkNvbmZpZ3VyYXRpb24uZmVhdHVyZXMgJiBET01Db25maWd1cmF0aW9uSW1wbC5DREFUQSkgPT0gMCkgJiYKLSAgICAgICAgICAgICAgICAgICAgICAgICAgbmV4dFR5cGUgPT0gTm9kZS5DREFUQV9TRUNUSU9OX05PREUpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZkRvY3VtZW50LmVycm9yQ2hlY2tpbmcgJiYgKChmQ29uZmlndXJhdGlvbi5mZWF0dXJlcyAmIERPTUNvbmZpZ3VyYXRpb25JbXBsLldFTExGT1JNRUQpICE9IDApICl7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNYTUxDaGFyV0YoZkVycm9ySGFuZGxlciwgZkVycm9yLCBmTG9jYXRvciwgbm9kZS5nZXROb2RlVmFsdWUoKSwgZkRvY3VtZW50LmlzWE1MMTFWZXJzaW9uKCkpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZWYWxpZGF0aW9uSGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkNvbmZpZ3VyYXRpb24uZkVycm9ySGFuZGxlcldyYXBwZXIuZkN1cnJlbnROb2RlID0gbm9kZTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmQ3VycmVudE5vZGUgPSBub2RlOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZWYWxpZGF0aW9uSGFuZGxlci5jaGFyYWN0ZXJEYXRhKG5vZGUuZ2V0Tm9kZVZhbHVlKCksIG51bGwpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChERUJVR19ORCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIj09PT09PmNoYXJhY3RlckRhdGEoKSwiK25leHRUeXBlKTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmRFREVmFsaWRhdG9yICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmQ29uZmlndXJhdGlvbi5mRXJyb3JIYW5kbGVyV3JhcHBlci5mQ3VycmVudE5vZGUgPSBub2RlOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZDdXJyZW50Tm9kZSA9IG5vZGU7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkRURFZhbGlkYXRvci5jaGFyYWN0ZXJEYXRhKG5vZGUuZ2V0Tm9kZVZhbHVlKCksIG51bGwpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChERUJVR19ORCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIj09PT09PmNoYXJhY3RlckRhdGEoKSwiK25leHRUeXBlKTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihhbGxXaGl0ZXNwYWNlKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsbFdoaXRlc3BhY2UgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKChUZXh0SW1wbClub2RlKS5zZXRJZ25vcmFibGVXaGl0ZXNwYWNlKHRydWUpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoREVCVUdfTkQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCI9PT09PT5kb24ndCBzZW5kIGNoYXJhY3RlcnMoKSwiK25leHRUeXBlKTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLSAgICAgICAgY2FzZSBOb2RlLlBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERTogewotCi0gICAgICAgICAgICAvL2RvIHRoZSB3ZWxsLWZvcm1lZCB2YWxpZCBQSSB0YXJnZXQgbmFtZSAsIGRhdGEgY2hlY2sgd2hlbiBhcHBsaWNhdGlvbiBoYXMgc2V0IHRoZSB2YWx1ZSBvZiB3ZWxsLWZvcm1lZCBmZWF0dXJlIHRvIHRydWUKLSAgICAgICAgICAgIGlmIChmRG9jdW1lbnQuZXJyb3JDaGVja2luZyAmJiAoZkNvbmZpZ3VyYXRpb24uZmVhdHVyZXMgJiBET01Db25maWd1cmF0aW9uSW1wbC5XRUxMRk9STUVEKSAhPSAwICkgewotICAgICAgICAgICAgICAgIFByb2Nlc3NpbmdJbnN0cnVjdGlvbiBwaW5vZGUgPSAoUHJvY2Vzc2luZ0luc3RydWN0aW9uKW5vZGUgOwotCi0gICAgICAgICAgICAgICAgU3RyaW5nIHRhcmdldCA9IHBpbm9kZS5nZXRUYXJnZXQoKTsKLSAgICAgICAgICAgICAgICAvLzEuY2hlY2sgUEkgdGFyZ2V0IG5hbWUKLSAgICAgICAgICAgICAgICBpZihmRG9jdW1lbnQuaXNYTUwxMVZlcnNpb24oKSl7Ci0gICAgICAgICAgICAgICAgICAgIHdlbGxmb3JtZWQgPSBYTUwxMUNoYXIuaXNYTUwxMVZhbGlkTmFtZSh0YXJnZXQpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlewotICAgICAgICAgICAgICAgICAgICB3ZWxsZm9ybWVkID0gWE1MQ2hhci5pc1ZhbGlkTmFtZSh0YXJnZXQpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXdlbGxmb3JtZWQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBtc2cgPSBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ3Zi1pbnZhbGlkLWNoYXJhY3Rlci1pbi1ub2RlLW5hbWUiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXsiRWxlbWVudCIsIG5vZGUuZ2V0Tm9kZU5hbWUoKX0pOwotICAgICAgICAgICAgICAgICAgICByZXBvcnRET01FcnJvcihmRXJyb3JIYW5kbGVyLCBmRXJyb3IsIGZMb2NhdG9yLCBtc2csIERPTUVycm9yLlNFVkVSSVRZX0VSUk9SLAotICAgICAgICAgICAgICAgICAgICAgICAgIndmLWludmFsaWQtY2hhcmFjdGVyLWluLW5vZGUtbmFtZSIpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8vMi4gY2hlY2sgUEkgZGF0YQotICAgICAgICAgICAgICAgIC8vcHJvY2Vzc2luZyBpc250cnVjdGlvbiBkYXRhIG1heSBoYXZlIGNlcnRhaW4gY2hhcmFjdGVycwotICAgICAgICAgICAgICAgIC8vd2hpY2ggbWF5IG5vdCBiZSB2YWxpZCBYTUwgY2hhcmFjdGVyCi0gICAgICAgICAgICAgICAgaXNYTUxDaGFyV0YoZkVycm9ySGFuZGxlciwgZkVycm9yLCBmTG9jYXRvciwgcGlub2RlLmdldERhdGEoKSwgZkRvY3VtZW50LmlzWE1MMTFWZXJzaW9uKCkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ly9lbmQgY2FzZSBOb2RlLlBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERQotCi0gICAgICAgIH0vL2VuZCBvZiBzd2l0Y2gKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfS8vbm9ybWFsaXplTm9kZQotCi0gICAgcHJpdmF0ZSBYTUxHcmFtbWFyUG9vbCBjcmVhdGVHcmFtbWFyUG9vbChEb2N1bWVudFR5cGVJbXBsIGRvY1R5cGUpIHsKLQotICAgICAgICBYTUxHcmFtbWFyUG9vbEltcGwgcG9vbCA9IG5ldyBYTUxHcmFtbWFyUG9vbEltcGwoKTsKLQotICAgICAgICBYTUxHcmFtbWFyUHJlcGFyc2VyIHByZVBhcnNlciA9IG5ldyBYTUxHcmFtbWFyUHJlcGFyc2VyKGZTeW1ib2xUYWJsZSk7Ci0gICAgICAgIHByZVBhcnNlci5yZWdpc3RlclByZXBhcnNlcihYTUxHcmFtbWFyRGVzY3JpcHRpb24uWE1MX0RURCwgbnVsbCk7Ci0gICAgICAgIHByZVBhcnNlci5zZXRGZWF0dXJlKENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuTkFNRVNQQUNFU19GRUFUVVJFLCB0cnVlKTsKLSAgICAgICAgcHJlUGFyc2VyLnNldEZlYXR1cmUoQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5WQUxJREFUSU9OX0ZFQVRVUkUsIHRydWUpOwotICAgICAgICBwcmVQYXJzZXIuc2V0UHJvcGVydHkoQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuWE1MR1JBTU1BUl9QT09MX1BST1BFUlRZLCBwb29sKTsKLQotICAgICAgICBTdHJpbmcgaW50ZXJuYWxTdWJzZXQgPSBkb2NUeXBlLmdldEludGVybmFsU3Vic2V0KCk7Ci0gICAgICAgIFhNTElucHV0U291cmNlIGlzID0gbmV3IFhNTElucHV0U291cmNlKGRvY1R5cGUuZ2V0UHVibGljSWQoKSwgZG9jVHlwZS5nZXRTeXN0ZW1JZCgpLCBudWxsKTsKLQotICAgICAgICBpZihpbnRlcm5hbFN1YnNldCAhPSBudWxsKQotICAgICAgICAgICAgaXMuc2V0Q2hhcmFjdGVyU3RyZWFtKG5ldyBTdHJpbmdSZWFkZXIoaW50ZXJuYWxTdWJzZXQpKTsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIERUREdyYW1tYXIgZyA9IChEVERHcmFtbWFyKXByZVBhcnNlci5wcmVwYXJzZUdyYW1tYXIoWE1MR3JhbW1hckRlc2NyaXB0aW9uLlhNTF9EVEQsIGlzKTsKLSAgICAgICAgICAgICgoWE1MRFRERGVzY3JpcHRpb24pZy5nZXRHcmFtbWFyRGVzY3JpcHRpb24oKSkuc2V0Um9vdE5hbWUoZG9jVHlwZS5nZXROYW1lKCkpOwotICAgICAgICAgICAgaXMuc2V0Q2hhcmFjdGVyU3RyZWFtKG51bGwpOwotICAgICAgICAgICAgZyA9IChEVERHcmFtbWFyKXByZVBhcnNlci5wcmVwYXJzZUdyYW1tYXIoWE1MR3JhbW1hckRlc2NyaXB0aW9uLlhNTF9EVEQsIGlzKTsKLSAgICAgICAgICAgICgoWE1MRFRERGVzY3JpcHRpb24pZy5nZXRHcmFtbWFyRGVzY3JpcHRpb24oKSkuc2V0Um9vdE5hbWUoZG9jVHlwZS5nZXROYW1lKCkpOwotCi0gICAgICAgIH0gY2F0Y2ggKFhOSUV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBwb29sOwotICAgIH0KLQotCi0KLSAgICBwcm90ZWN0ZWQgZmluYWwgdm9pZCBleHBhbmRFbnRpdHlSZWYgKE5vZGUgcGFyZW50LCBOb2RlIHJlZmVyZW5jZSl7Ci0gICAgICAgIE5vZGUga2lkLCBuZXh0OwotICAgICAgICBmb3IgKGtpZCA9IHJlZmVyZW5jZS5nZXRGaXJzdENoaWxkKCk7IGtpZCAhPSBudWxsOyBraWQgPSBuZXh0KSB7Ci0gICAgICAgICAgICBuZXh0ID0ga2lkLmdldE5leHRTaWJsaW5nKCk7Ci0gICAgICAgICAgICBwYXJlbnQuaW5zZXJ0QmVmb3JlKGtpZCwgcmVmZXJlbmNlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8vIGZpeCBuYW1lc3BhY2VzCi0gICAgLy8gbm9ybWFsaXplIGF0dHJpYnV0ZSB2YWx1ZXMKLSAgICAvLyByZW1vdmUgZGVmYXVsdCBhdHRyaWJ1dGVzCi0gICAgLy8gY2hlY2sgYXR0cmlidXRlIG5hbWVzIGlmIHRoZSB2ZXJzaW9uIG9mIHRoZSBkb2N1bWVudCBjaGFuZ2VkLgotCi0gICAgcHJvdGVjdGVkIGZpbmFsIHZvaWQgbmFtZXNwYWNlRml4VXAgKEVsZW1lbnRJbXBsIGVsZW1lbnQsIEF0dHJpYnV0ZU1hcCBhdHRyaWJ1dGVzKXsKLSAgICAgICAgaWYgKERFQlVHKSB7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIltucy1maXh1cF0gZWxlbWVudDoiICtlbGVtZW50LmdldE5vZGVOYW1lKCkrCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiB1cmk6ICIrZWxlbWVudC5nZXROYW1lc3BhY2VVUkkoKSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICAgICAgLy8gcGljayB1cCBsb2NhbCBuYW1lc3BhY2UgZGVjbGFyYXRpb25zCi0gICAgICAgIC8vIDx4c2w6c3R5bGVzaGVldCB4bWxuczp4c2w9Imh0dHA6Ly94c2x0Ij4KLSAgICAgICAgLy8gICA8IS0tIGFkZCB0aGUgZm9sbG93aW5nIHZpYSBET00KLSAgICAgICAgLy8gICAgICAgICAgYm9keSBpcyBib3VuZCB0byBodHRwOi8veHNsdAotICAgICAgICAvLyAgICAtLT4KLSAgICAgICAgLy8gICA8eHNsOmJvZHkgeG1sbnM6eHNsPSJodHRwOi8vYm91bmQiLz4KLSAgICAgICAgLy8KLSAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0KLSAgICAgICAgU3RyaW5nIHZhbHVlLCBuYW1lLCB1cmksIHByZWZpeDsKLSAgICAgICAgaWYgKGF0dHJpYnV0ZXMgIT0gbnVsbCkgewotCi0gICAgICAgICAgICAvLyBSZWNvcmQgYWxsIHZhbGlkIGxvY2FsIGRlY2xhcmF0aW9ucwotICAgICAgICAgICAgZm9yIChpbnQgayA9IDA7IGsgPCBhdHRyaWJ1dGVzLmdldExlbmd0aCgpOyArK2spIHsKLSAgICAgICAgICAgICAgICBBdHRyIGF0dHIgPSAoQXR0cilhdHRyaWJ1dGVzLmdldEl0ZW0oayk7Ci0KLSAgICAgICAgICAgICAgICAvL2RvIHRoZSBuYW1lIGNoZWNrIG9ubHkgd2hlbiB2ZXJzaW9uIG9mIHRoZSBkb2N1bWVudCB3YXMgY2hhbmdlZCAmCi0gICAgICAgICAgICAgICAgLy9hcHBsaWNhdGlvbiBoYXMgc2V0IHRoZSB2YWx1ZSBvZiB3ZWxsLWZvcm1lZCBmZWF0dXJlcyB0byB0cnVlCi0gICAgICAgICAgICAgICAgaWYgKGZEb2N1bWVudC5lcnJvckNoZWNraW5nICYmICgoZkNvbmZpZ3VyYXRpb24uZmVhdHVyZXMgJiBET01Db25maWd1cmF0aW9uSW1wbC5XRUxMRk9STUVEKSAhPSAwKSAmJgotICAgICAgICAgICAgICAgICAgICBmRG9jdW1lbnQuaXNYTUxWZXJzaW9uQ2hhbmdlZCgpKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vY2hlY2tRTmFtZSBkb2VzIGNoZWNraW5nIGJhc2VkIG9uIHRoZSB2ZXJzaW9uIG9mIHRoZSBkb2N1bWVudAotICAgICAgICAgICAgICAgICAgICBmRG9jdW1lbnQuY2hlY2tRTmFtZShhdHRyLmdldFByZWZpeCgpICwgYXR0ci5nZXRMb2NhbE5hbWUoKSkgOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIHVyaSA9IGF0dHIuZ2V0TmFtZXNwYWNlVVJJKCk7Ci0gICAgICAgICAgICAgICAgaWYgKHVyaSAhPSBudWxsICYmIHVyaS5lcXVhbHMoTmFtZXNwYWNlQ29udGV4dC5YTUxOU19VUkkpKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIG5hbWVzcGFjZSBhdHRyaWJ1dGUKLQotICAgICAgICAgICAgICAgICAgICAvLyAibmFtZXNwYWNlLWRlY2xhcmF0aW9ucyIgPT0gZmFsc2U7IERpc2NhcmQgYWxsIG5hbWVzcGFjZSBkZWNsYXJhdGlvbiBhdHRyaWJ1dGVzCi0gICAgICAgICAgICAgICAgICAgIGlmICgoZkNvbmZpZ3VyYXRpb24uZmVhdHVyZXMgJiBET01Db25maWd1cmF0aW9uSW1wbC5OU0RFQ0wpID09IDApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBhdHRyLmdldE5vZGVWYWx1ZSgpOwotICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU9WE1MU3ltYm9scy5FTVBUWV9TVFJJTkc7Ci0gICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAvLyBDaGVjayBmb3IgaW52YWxpZCBuYW1lc3BhY2UgZGVjbGFyYXRpb246Ci0gICAgICAgICAgICAgICAgICAgIGlmIChmRG9jdW1lbnQuZXJyb3JDaGVja2luZyAmJiB2YWx1ZS5lcXVhbHMoTmFtZXNwYWNlQ29udGV4dC5YTUxOU19VUkkpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvL0EgbnVsbCB2YWx1ZSBmb3IgbG9jYWxlIGlzIHBhc3NlZCB0byBmb3JtYXRNZXNzYWdlLAotICAgICAgICAgICAgICAgICAgICAgICAgLy93aGljaCBtZWFucyB0aGF0IHRoZSBkZWZhdWx0IGxvY2FsZSB3aWxsIGJlIHVzZWQKLSAgICAgICAgICAgICAgICAgICAgICAgIGZMb2NhdG9yLmZSZWxhdGVkTm9kZSA9IGF0dHI7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbXNnID0gRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwiQ2FudEJpbmRYTUxOUyIsbnVsbCApOwotICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0RE9NRXJyb3IoZkVycm9ySGFuZGxlciwgZkVycm9yLCBmTG9jYXRvciwgbXNnLCBET01FcnJvci5TRVZFUklUWV9FUlJPUiwgIkNhbnRCaW5kWE1MTlMiKTsKLSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIFhNTCAxLjAgQXR0cmlidXRlIHZhbHVlIG5vcm1hbGl6YXRpb24KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIHZhbHVlID0gbm9ybWFsaXplQXR0cmlidXRlVmFsdWUodmFsdWUsIGF0dHIpOwotICAgICAgICAgICAgICAgICAgICAgICAgcHJlZml4ID0gYXR0ci5nZXRQcmVmaXgoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHByZWZpeCA9IChwcmVmaXggPT0gbnVsbCB8fAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZWZpeC5sZW5ndGgoKSA9PSAwKSA/IFhNTFN5bWJvbHMuRU1QVFlfU1RSSU5HIDpmU3ltYm9sVGFibGUuYWRkU3ltYm9sKHByZWZpeCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbG9jYWxwYXJ0ID0gZlN5bWJvbFRhYmxlLmFkZFN5bWJvbCggYXR0ci5nZXRMb2NhbE5hbWUoKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAocHJlZml4ID09IFhNTFN5bWJvbHMuUFJFRklYX1hNTE5TKSB7IC8veG1sbnM6cHJlZml4Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IGZTeW1ib2xUYWJsZS5hZGRTeW1ib2wodmFsdWUpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZS5sZW5ndGgoKSAhPSAwKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZOYW1lc3BhY2VDb250ZXh0LmRlY2xhcmVQcmVmaXgobG9jYWxwYXJ0LCB2YWx1ZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUkVWSVNJVDogaXNzdWUgZXJyb3Igb24gaW52YWxpZCBkZWNsYXJhdGlvbnMKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgICAgICAgeG1sbnM6Zm9vID0gIiIKLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3JlbW92ZURlZmF1bHQgKGF0dHIsIGF0dHJpYnV0ZXMpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsgLy8gKGxvY2FscGFydCA9PSBmWG1sbnNTeW1ib2wgJiYgcHJlZml4ID09IGZFbXB0eVN5bWJvbCkgIC0tIHhtbG5zCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZW1wdHkgcHJlZml4IGlzIGFsd2F5cyBib3VuZCAoIiIgb3Igc29tZSBzdHJpbmcpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBmU3ltYm9sVGFibGUuYWRkU3ltYm9sKHZhbHVlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmTmFtZXNwYWNlQ29udGV4dC5kZWNsYXJlUHJlZml4KFhNTFN5bWJvbHMuRU1QVFlfU1RSSU5HLCB2YWx1ZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9yZW1vdmVEZWZhdWx0IChhdHRyLCBhdHRyaWJ1dGVzKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfSAgLy8gZW5kLWVsc2U6IHZhbGlkIGRlY2xhcmF0aW9uCi0gICAgICAgICAgICAgICAgfSAvLyBlbmQtaWY6IG5hbWVzcGFjZSBhdHRyaWJ1dGUKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0KLQotICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICAgICAgLy8gRml4IHVwIG5hbWVzcGFjZXMgZm9yIGVsZW1lbnQ6IHBlciBET00gTDMKLSAgICAgICAgLy8gTmVlZCB0byBjb25zaWRlciB0aGUgZm9sbG93aW5nIGNhc2VzOgotICAgICAgICAvLwotICAgICAgICAvLyBjYXNlIDE6IDx4c2w6c3R5bGVzaGVldCB4bWxuczp4c2w9Imh0dHA6Ly94c2wiPgotICAgICAgICAvLyBXZSBjcmVhdGUgYW5vdGhlciBlbGVtZW50IGJvZHkgYm91bmQgdG8gdGhlICJodHRwOi8veHNsIiBuYW1lc3BhY2UKLSAgICAgICAgLy8gYXMgd2VsbCBhcyBuYW1lc3BhY2UgYXR0cmlidXRlIHJlYm91bmRpbmcgeHNsIHRvIGFub3RoZXIgbmFtZXNwYWNlLgotICAgICAgICAvLyA8eHNsOmJvZHkgeG1sbnM6eHNsPSJodHRwOi8vYW5vdGhlciI+Ci0gICAgICAgIC8vIE5lZWQgdG8gbWFrZSBzdXJlIHRoYXQgdGhlIG5ldyBuYW1lc3BhY2UgZGVjbCB2YWx1ZSBpcyBjaGFuZ2VkIHRvCi0gICAgICAgIC8vICJodHRwOi8veHNsIgotICAgICAgICAvLwotICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICAgICAgLy8gY2hlY2sgaWYgcHJlZml4L25hbWVzcGFjZSBpcyBjb3JyZWN0IGZvciBjdXJyZW50IGVsZW1lbnQKLSAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0KLSAgICAgICAgdXJpID0gZWxlbWVudC5nZXROYW1lc3BhY2VVUkkoKTsKLSAgICAgICAgcHJlZml4ID0gZWxlbWVudC5nZXRQcmVmaXgoKTsKLQotICAgICAgICAvLyAibmFtZXNwYWNlLWRlY2xhcmF0aW9ucyIgPT0gZmFsc2U/IERpc2NhcmQgYWxsIG5hbWVzcGFjZSBkZWNsYXJhdGlvbiBhdHRyaWJ1dGVzCi0gICAgICAgIGlmICgoZkNvbmZpZ3VyYXRpb24uZmVhdHVyZXMgJiBET01Db25maWd1cmF0aW9uSW1wbC5OU0RFQ0wpID09IDApIHsKLSAgICAgICAgICAgIC8vIG5vIG5hbWVzcGFjZSBkZWNsYXJhdGlvbiA9PSBubyBuYW1lc3BhY2UgVVJJLCBzZW1hbnRpY3MgYXJlIHRvIGtlZXAgcHJlZml4Ci0gICAgICAgICAgICB1cmkgPSBudWxsOwotICAgICAgICB9IGVsc2UgaWYgKHVyaSAhPSBudWxsKSB7ICAvLyBFbGVtZW50IGhhcyBhIG5hbWVzcGFjZQotICAgICAgICAgICAgdXJpID0gZlN5bWJvbFRhYmxlLmFkZFN5bWJvbCh1cmkpOwotICAgICAgICAgICAgcHJlZml4ID0gKHByZWZpeCA9PSBudWxsIHx8Ci0gICAgICAgICAgICAgICAgICAgICAgcHJlZml4Lmxlbmd0aCgpID09IDApID8gWE1MU3ltYm9scy5FTVBUWV9TVFJJTkcgOmZTeW1ib2xUYWJsZS5hZGRTeW1ib2wocHJlZml4KTsKLSAgICAgICAgICAgIGlmIChmTmFtZXNwYWNlQ29udGV4dC5nZXRVUkkocHJlZml4KSA9PSB1cmkpIHsKLSAgICAgICAgICAgICAgICAvLyBUaGUgeG1sbnM6cHJlZml4PW5hbWVzcGFjZSBvciB4bWxucz0iZGVmYXVsdCIgd2FzIGRlY2xhcmVkIGF0IHBhcmVudC4KLSAgICAgICAgICAgICAgICAvLyBUaGUgYmluZGVyIGFsd2F5cyBzdG9yZXMgbWFwcGluZyBvZiBlbXB0eSBwcmVmaXggdG8gIiIuCi0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIC8vIHRoZSBwcmVmaXggaXMgZWl0aGVyIHVuZGVjbGFyZWQKLSAgICAgICAgICAgICAgICAvLyBvcgotICAgICAgICAgICAgICAgIC8vIGNvbmZsaWN0OiB0aGUgcHJlZml4IGlzIGJvdW5kIHRvIGFub3RoZXIgVVJJCi0gICAgICAgICAgICAgICAgYWRkTmFtZXNwYWNlRGVjbChwcmVmaXgsIHVyaSwgZWxlbWVudCk7Ci0gICAgICAgICAgICAgICAgZkxvY2FsTlNCaW5kZXIuZGVjbGFyZVByZWZpeChwcmVmaXgsIHVyaSk7Ci0gICAgICAgICAgICAgICAgZk5hbWVzcGFjZUNvbnRleHQuZGVjbGFyZVByZWZpeChwcmVmaXgsIHVyaSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gZWxzZSB7IC8vIEVsZW1lbnQgaGFzIG5vIG5hbWVzcGFjZQotICAgICAgICAgICAgaWYgKGVsZW1lbnQuZ2V0TG9jYWxOYW1lKCkgPT0gbnVsbCkgewotCi0gICAgICAgICAgICAgICAgLy8gIEVycm9yOiBET00gTGV2ZWwgMSBub2RlIQotICAgICAgICAgICAgICAgIGlmIChmTmFtZXNwYWNlVmFsaWRhdGlvbikgewotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbXNnID0gRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwgIk51bGxMb2NhbEVsZW1lbnROYW1lIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117ZWxlbWVudC5nZXROb2RlTmFtZSgpfSk7Ci0gICAgICAgICAgICAgICAgICAgIHJlcG9ydERPTUVycm9yKGZFcnJvckhhbmRsZXIsIGZFcnJvciwgZkxvY2F0b3IsIG1zZywgRE9NRXJyb3IuU0VWRVJJVFlfRkFUQUxfRVJST1IsCi0gICAgICAgICAgICAgICAgICAgICJOdWxsTG9jYWxFbGVtZW50TmFtZSIpOwotICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIFN0cmluZyBtc2cgPSBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiTnVsbExvY2FsRWxlbWVudE5hbWUiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXtlbGVtZW50LmdldE5vZGVOYW1lKCl9KTsKLSAgICAgICAgICAgICAgICAgICAgcmVwb3J0RE9NRXJyb3IoZkVycm9ySGFuZGxlciwgZkVycm9yLCBmTG9jYXRvciwgbXNnLCBET01FcnJvci5TRVZFUklUWV9FUlJPUiwKLSAgICAgICAgICAgICAgICAgICAgIk51bGxMb2NhbEVsZW1lbnROYW1lIik7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICB9IGVsc2UgeyAvLyB1cmk9bnVsbCBhbmQgbm8gY29sb24gKERPTSBMMiBub2RlKQotICAgICAgICAgICAgICAgIHVyaSA9IGZOYW1lc3BhY2VDb250ZXh0LmdldFVSSShYTUxTeW1ib2xzLkVNUFRZX1NUUklORyk7Ci0gICAgICAgICAgICAgICAgaWYgKHVyaSAhPW51bGwgJiYgdXJpLmxlbmd0aCgpID4gMCkgewotICAgICAgICAgICAgICAgICAgICAvLyB1bmRlY2xhcmUgZGVmYXVsdCBuYW1lc3BhY2UgZGVjbGFyYXRpb24gKGJlZm9yZSB0aGF0IGVsZW1lbnQKLSAgICAgICAgICAgICAgICAgICAgLy8gYm91bmQgdG8gbm9uLXplcm8gbGVuZ3RoIHVpciksIGJ1dCBhZGRpbmcgeG1sbnM9IiIgZGVjbAotICAgICAgICAgICAgICAgICAgICBhZGROYW1lc3BhY2VEZWNsIChYTUxTeW1ib2xzLkVNUFRZX1NUUklORywgWE1MU3ltYm9scy5FTVBUWV9TVFJJTkcsIGVsZW1lbnQpOwotICAgICAgICAgICAgICAgICAgICBmTG9jYWxOU0JpbmRlci5kZWNsYXJlUHJlZml4KFhNTFN5bWJvbHMuRU1QVFlfU1RSSU5HLCBYTUxTeW1ib2xzLkVNUFRZX1NUUklORyk7Ci0gICAgICAgICAgICAgICAgICAgIGZOYW1lc3BhY2VDb250ZXh0LmRlY2xhcmVQcmVmaXgoWE1MU3ltYm9scy5FTVBUWV9TVFJJTkcsIFhNTFN5bWJvbHMuRU1QVFlfU1RSSU5HKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgICAgICAvLyBGaXggdXAgbmFtZXNwYWNlcyBmb3IgYXR0cmlidXRlczogcGVyIERPTSBMMwotICAgICAgICAvLyBjaGVjayBpZiBwcmVmaXgvbmFtZXNwYWNlIGlzIGNvcnJlY3QgdGhlIGF0dHJpYnV0ZXMKLSAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICAgICAgaWYgKGF0dHJpYnV0ZXMgIT0gbnVsbCkgewotCi0gICAgICAgICAgICAvLyBjbG9uZSBjb250ZW50IG9mIHRoZSBhdHRyaWJ1dGVzCi0gICAgICAgICAgICBhdHRyaWJ1dGVzLmNsb25lTWFwKGZBdHRyaWJ1dGVMaXN0KTsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZkF0dHJpYnV0ZUxpc3Quc2l6ZSgpOyBpKyspIHsKLSAgICAgICAgICAgICAgICBBdHRyIGF0dHIgPSAoQXR0cikgZkF0dHJpYnV0ZUxpc3QuZ2V0KGkpOwotICAgICAgICAgICAgICAgIGZMb2NhdG9yLmZSZWxhdGVkTm9kZSA9IGF0dHI7Ci0KLSAgICAgICAgICAgICAgICBpZiAoREVCVUcpIHsKLSAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCI9PT5bbnMtZml4dXBdIHByb2Nlc3MgYXR0cmlidXRlOiAiK2F0dHIuZ2V0Tm9kZU5hbWUoKSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIC8vIG5vcm1hbGl6ZSBhdHRyaWJ1dGUgdmFsdWUKLSAgICAgICAgICAgICAgICBhdHRyLm5vcm1hbGl6ZSgpOwotICAgICAgICAgICAgICAgIHZhbHVlID0gYXR0ci5nZXRWYWx1ZSgpOwotICAgICAgICAgICAgICAgIG5hbWUgPSBhdHRyLmdldE5vZGVOYW1lKCk7Ci0gICAgICAgICAgICAgICAgdXJpID0gYXR0ci5nZXROYW1lc3BhY2VVUkkoKTsKLQotICAgICAgICAgICAgICAgIC8vIG1ha2Ugc3VyZSB0aGF0IHZhbHVlIGlzIG5ldmVyIG51bGwuCi0gICAgICAgICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgdmFsdWU9WE1MU3ltYm9scy5FTVBUWV9TVFJJTkc7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgaWYgKHVyaSAhPSBudWxsKSB7ICAvLyBhdHRyaWJ1dGUgaGFzIG5hbWVzcGFjZSAhPW51bGwKLSAgICAgICAgICAgICAgICAgICAgcHJlZml4ID0gYXR0ci5nZXRQcmVmaXgoKTsKLSAgICAgICAgICAgICAgICAgICAgcHJlZml4ID0gKHByZWZpeCA9PSBudWxsIHx8Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmVmaXgubGVuZ3RoKCkgPT0gMCkgPyBYTUxTeW1ib2xzLkVNUFRZX1NUUklORyA6ZlN5bWJvbFRhYmxlLmFkZFN5bWJvbChwcmVmaXgpOwotICAgICAgICAgICAgICAgICAgICAvKlN0cmluZyBsb2NhbHBhcnQgPSovIGZTeW1ib2xUYWJsZS5hZGRTeW1ib2woIGF0dHIuZ2V0TG9jYWxOYW1lKCkpOwotCi0gICAgICAgICAgICAgICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgICAgICAgICAgICAgICAgICAvLyBza2lwIG5hbWVzcGFjZSBkZWNsYXJhdGlvbnMKLSAgICAgICAgICAgICAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgICAgICAgICAgICAgICAgIC8vIFJFVklTSVQ6IGNhbiB3ZSBhc3N1bWUgdGhhdCAidXJpIiBpcyBmcm9tIHNvbWUgc3ltYm9sCi0gICAgICAgICAgICAgICAgICAgIC8vIHRhYmxlLCBhbmQgY29tcGFyZSBieSByZWZlcmVuY2U/IC1TRwotICAgICAgICAgICAgICAgICAgICBpZiAodXJpICE9IG51bGwgJiYgdXJpLmVxdWFscyhOYW1lc3BhY2VDb250ZXh0LlhNTE5TX1VSSSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgICAgICAgICAgICAgICAgIC8vIGNoZWNrIGlmIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUgaXMgbmFtZXNwYWNlIHdlbGwtZm9ybWVkCi0gICAgICAgICAgICAgICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgICAgICAgICAgICAgICAgIGlmIChmRG9jdW1lbnQuZXJyb3JDaGVja2luZyAmJiAoKGZDb25maWd1cmF0aW9uLmZlYXR1cmVzICYgRE9NQ29uZmlndXJhdGlvbkltcGwuV0VMTEZPUk1FRCkgIT0gMCkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc0F0dHJWYWx1ZVdGKGZFcnJvckhhbmRsZXIsIGZFcnJvciwgZkxvY2F0b3IsIGF0dHJpYnV0ZXMsIChBdHRySW1wbClhdHRyLCBhdHRyLmdldFZhbHVlKCksIGZEb2N1bWVudC5pc1hNTDExVmVyc2lvbigpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZkRvY3VtZW50LmlzWE1MVmVyc2lvbkNoYW5nZWQoKSl7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gd2VsbGZvcm1lZD1Db3JlRG9jdW1lbnRJbXBsLmlzWE1MTmFtZShhdHRyLmdldE5vZGVOYW1lKCkgLCBmRG9jdW1lbnQuaXNYTUwxMVZlcnNpb24oKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghd2VsbGZvcm1lZCl7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBtc2cgPSBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAid2YtaW52YWxpZC1jaGFyYWN0ZXItaW4tbm9kZS1uYW1lIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXsiQXR0cmlidXRlIiwgYXR0ci5nZXROb2RlTmFtZSgpfSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0RE9NRXJyb3IoZkVycm9ySGFuZGxlciwgZkVycm9yLCBmTG9jYXRvciwgbXNnLCBET01FcnJvci5TRVZFUklUWV9FUlJPUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIndmLWludmFsaWQtY2hhcmFjdGVyLWluLW5vZGUtbmFtZSIpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICAgICAgICAgICAgICAgICAgLy8gcmVtb3ZlIGRlZmF1bHQgYXR0cmlidXRlcwotICAgICAgICAgICAgICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICAgICAgICAgICAgICAgICAgLyoKLSAgICAgICAgICAgICAgICAgICAgaWYgKHJlbW92ZURlZmF1bHQoYXR0ciwgYXR0cmlidXRlcykpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICovCi0gICAgICAgICAgICAgICAgICAgIC8vIFhNTCAxLjAgQXR0cmlidXRlIHZhbHVlIG5vcm1hbGl6YXRpb24KLSAgICAgICAgICAgICAgICAgICAgLy92YWx1ZSA9IG5vcm1hbGl6ZUF0dHJpYnV0ZVZhbHVlKHZhbHVlLCBhdHRyKTsKLQotICAgICAgICAgICAgICAgICAgICAvLyByZXNldCBpZC1hdHRyaWJ1dGVzCi0gICAgICAgICAgICAgICAgICAgICgoQXR0ckltcGwpYXR0cikuc2V0SWRBdHRyaWJ1dGUoZmFsc2UpOwotCi0KLSAgICAgICAgICAgICAgICAgICAgdXJpID0gZlN5bWJvbFRhYmxlLmFkZFN5bWJvbCh1cmkpOwotCi0gICAgICAgICAgICAgICAgICAgIC8vIGZpbmQgaWYgZm9yIHRoaXMgcHJlZml4IGEgVVJJIHdhcyBhbHJlYWR5IGRlY2xhcmVkCi0gICAgICAgICAgICAgICAgICAgIFN0cmluZyBkZWNsYXJlZFVSSSA9ICBmTmFtZXNwYWNlQ29udGV4dC5nZXRVUkkocHJlZml4KTsKLQotICAgICAgICAgICAgICAgICAgICBpZiAocHJlZml4ID09IFhNTFN5bWJvbHMuRU1QVFlfU1RSSU5HIHx8IGRlY2xhcmVkVVJJICE9IHVyaSkgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gYXR0cmlidXRlIGhhcyBubyBwcmVmaXggKGRlZmF1bHQgbmFtZXNwYWNlIGRlY2wgZG9lcyBub3QgYXBwbHkgdG8gYXR0cmlidXRlcykKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9SCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBhdHRyaWJ1dGUgcHJlZml4IGlzIG5vdCBkZWNsYXJlZAotICAgICAgICAgICAgICAgICAgICAgICAgLy8gT1IKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNvbmZsaWN0OiBhdHRyaWJ1dGUgaGFzIGEgcHJlZml4IHRoYXQgY29uZmljbGljdHMgd2l0aCBhIGJpbmRpbmcKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgICAgICAgICBhbHJlYWR5IGFjdGl2ZSBpbiBzY29wZQotCi0gICAgICAgICAgICAgICAgICAgICAgICBuYW1lICA9IGF0dHIuZ2V0Tm9kZU5hbWUoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIEZpbmQgaWYgYW55IHByZWZpeCBmb3IgYXR0cmlidXRlcyBuYW1lc3BhY2UgVVJJIGlzIGF2YWlsYWJsZQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gaW4gdGhlIHNjb3BlCi0gICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgZGVjbGFyZWRQcmVmaXggPSBmTmFtZXNwYWNlQ29udGV4dC5nZXRQcmVmaXgodXJpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkZWNsYXJlZFByZWZpeCAhPW51bGwgJiYgZGVjbGFyZWRQcmVmaXggIT1YTUxTeW1ib2xzLkVNUFRZX1NUUklORykgewotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdXNlIHRoZSBwcmVmaXggdGhhdCB3YXMgZm91bmQgKGRlY2xhcmVkIHByZXZpb3VzbHkgZm9yIHRoaXMgVVJJCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJlZml4ID0gZGVjbGFyZWRQcmVmaXg7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwcmVmaXggIT0gWE1MU3ltYm9scy5FTVBUWV9TVFJJTkcgJiYgZkxvY2FsTlNCaW5kZXIuZ2V0VVJJKHByZWZpeCkgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGUgY3VycmVudCBwcmVmaXggaXMgbm90IG51bGwgYW5kIGl0IGhhcyBubyBpbiBzY29wZSBkZWNsYXJhdGlvbgotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHVzZSB0aGlzIHByZWZpeAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZmluZCBhIHByZWZpeCBmb2xsb3dpbmcgdGhlIHBhdHRlcm4gIk5TIiAraW5kZXggKHN0YXJ0aW5nIGF0IDEpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG1ha2Ugc3VyZSB0aGlzIHByZWZpeCBpcyBub3QgZGVjbGFyZWQgaW4gdGhlIGN1cnJlbnQgc2NvcGUuCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBjb3VudGVyID0gMTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJlZml4ID0gZlN5bWJvbFRhYmxlLmFkZFN5bWJvbChQUkVGSVggK2NvdW50ZXIrKyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChmTG9jYWxOU0JpbmRlci5nZXRVUkkocHJlZml4KSE9bnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJlZml4ID0gZlN5bWJvbFRhYmxlLmFkZFN5bWJvbChQUkVGSVggK2NvdW50ZXIrKyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBhZGQgZGVjbGFyYXRpb24gZm9yIHRoZSBuZXcgcHJlZml4Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkTmFtZXNwYWNlRGVjbChwcmVmaXgsIHVyaSwgZWxlbWVudCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBmU3ltYm9sVGFibGUuYWRkU3ltYm9sKHZhbHVlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmTG9jYWxOU0JpbmRlci5kZWNsYXJlUHJlZml4KHByZWZpeCwgdmFsdWUpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZOYW1lc3BhY2VDb250ZXh0LmRlY2xhcmVQcmVmaXgocHJlZml4LCB1cmkpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBjaGFuZ2UgcHJlZml4IGZvciB0aGlzIGF0dHJpYnV0ZQotICAgICAgICAgICAgICAgICAgICAgICAgYXR0ci5zZXRQcmVmaXgocHJlZml4KTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0gZWxzZSB7IC8vIGF0dHJpYnV0ZSB1cmkgPT0gbnVsbAotCi0gICAgICAgICAgICAgICAgICAgIC8vIFhNTCAxLjAgQXR0cmlidXRlIHZhbHVlIG5vcm1hbGl6YXRpb24KLSAgICAgICAgICAgICAgICAgICAgLy92YWx1ZSA9IG5vcm1hbGl6ZUF0dHJpYnV0ZVZhbHVlKHZhbHVlLCBhdHRyKTsKLQotICAgICAgICAgICAgICAgICAgICAvLyByZXNldCBpZC1hdHRyaWJ1dGVzCi0gICAgICAgICAgICAgICAgICAgICgoQXR0ckltcGwpYXR0cikuc2V0SWRBdHRyaWJ1dGUoZmFsc2UpOwotCi0gICAgICAgICAgICAgICAgICAgIGlmIChhdHRyLmdldExvY2FsTmFtZSgpID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIEl0IGlzIGFuIGVycm9yIGlmIGRvY3VtZW50IGhhcyBET00gTDEgbm9kZXMuCi0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZk5hbWVzcGFjZVZhbGlkYXRpb24pIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbXNnID0gRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOdWxsTG9jYWxBdHRyTmFtZSIsIG5ldyBPYmplY3RbXXthdHRyLmdldE5vZGVOYW1lKCl9KTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRET01FcnJvcihmRXJyb3JIYW5kbGVyLCBmRXJyb3IsIGZMb2NhdG9yLCBtc2csIERPTUVycm9yLlNFVkVSSVRZX0ZBVEFMX0VSUk9SLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTnVsbExvY2FsQXR0ck5hbWUiKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG1zZyA9IERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZSgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTnVsbExvY2FsQXR0ck5hbWUiLCBuZXcgT2JqZWN0W117YXR0ci5nZXROb2RlTmFtZSgpfSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0RE9NRXJyb3IoZkVycm9ySGFuZGxlciwgZkVycm9yLCBmTG9jYXRvciwgbXNnLCBET01FcnJvci5TRVZFUklUWV9FUlJPUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk51bGxMb2NhbEF0dHJOYW1lIik7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyB1cmk9bnVsbCBhbmQgbm8gY29sb24KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIG5vIGZpeCB1cCBpcyBuZWVkZWQ6IGRlZmF1bHQgbmFtZXNwYWNlIGRlY2wgZG9lcyBub3QKLQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyByZW1vdmUgZGVmYXVsdCBhdHRyaWJ1dGVzCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIHJlbW92ZURlZmF1bHQoYXR0ciwgYXR0cmlidXRlcyk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gLy8gZW5kIGxvb3AgZm9yIGF0dHJpYnV0ZXMKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBZGRzIGEgbmFtZXNwYWNlIGF0dHJpYnV0ZSBvciByZXBsYWNlcyB0aGUgdmFsdWUgb2YgZXhpc3RpbmcgbmFtZXNwYWNlCi0gICAgICogYXR0cmlidXRlIHdpdGggdGhlIGdpdmVuIHByZWZpeCBhbmQgdmFsdWUgZm9yIFVSSS4KLSAgICAgKiBJbiBjYXNlIHByZWZpeCBpcyBlbXB0eSB3aWxsIGFkZC91cGRhdGUgZGVmYXVsdCBuYW1lc3BhY2UgZGVjbGFyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcHJlZml4Ci0gICAgICogQHBhcmFtIHVyaQotICAgICAqIEBleGNlcHRpb24gSU9FeGNlcHRpb24KLSAgICAgKi8KLQotICAgIHByb3RlY3RlZCBmaW5hbCB2b2lkIGFkZE5hbWVzcGFjZURlY2woU3RyaW5nIHByZWZpeCwgU3RyaW5nIHVyaSwgRWxlbWVudEltcGwgZWxlbWVudCl7Ci0gICAgICAgIGlmIChERUJVRykgewotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJbbnMtZml4dXBdIGFkZE5hbWVzcGFjZURlY2wgWyIrcHJlZml4KyJdIik7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKHByZWZpeCA9PSBYTUxTeW1ib2xzLkVNUFRZX1NUUklORykgewotICAgICAgICAgICAgaWYgKERFQlVHKSB7Ci0gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCI9PmFkZCB4bWxucz1cIiIrdXJpKyJcIiBkZWNsYXJhdGlvbiIpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGVOUyhOYW1lc3BhY2VDb250ZXh0LlhNTE5TX1VSSSwgWE1MU3ltYm9scy5QUkVGSVhfWE1MTlMsIHVyaSk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBpZiAoREVCVUcpIHsKLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIj0+YWRkIHhtbG5zOiIrcHJlZml4KyI9XCIiK3VyaSsiXCIgZGVjbGFyYXRpb24iKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlTlMoTmFtZXNwYWNlQ29udGV4dC5YTUxOU19VUkksICJ4bWxuczoiK3ByZWZpeCwgdXJpKTsKLSAgICAgICAgfQotICAgIH0KLQotCi0gICAgLy8KLSAgICAvLyBNZXRob2RzIGZvciB3ZWxsLWZvcm1uZXNzIGNoZWNraW5nCi0gICAgLy8KLQotCi0gICAgLyoqCi0gICAgICogQ2hlY2sgaWYgQ0RBVEEgc2VjdGlvbiBpcyB3ZWxsLWZvcm1lZAotICAgICAqIEBwYXJhbSBkYXRhdmFsdWUKLSAgICAgKiBAcGFyYW0gaXNYTUwxMVZlcnNpb24gPSB0cnVlIGlmIFhNTCAxLjEKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHZvaWQgaXNDRGF0YVdGKERPTUVycm9ySGFuZGxlciBlcnJvckhhbmRsZXIsIERPTUVycm9ySW1wbCBlcnJvciwgRE9NTG9jYXRvckltcGwgbG9jYXRvciwKLSAgICAgICAgU3RyaW5nIGRhdGF2YWx1ZSwgYm9vbGVhbiBpc1hNTDExVmVyc2lvbikKLSAgICB7Ci0gICAgICAgIGlmIChkYXRhdmFsdWUgPT0gbnVsbCB8fCAoZGF0YXZhbHVlLmxlbmd0aCgpID09IDApICkgewotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0KLSAgICAgICAgY2hhciBbXSBkYXRhYXJyYXkgPSBkYXRhdmFsdWUudG9DaGFyQXJyYXkoKTsKLSAgICAgICAgaW50IGRhdGFsZW5ndGggPSBkYXRhYXJyYXkubGVuZ3RoOwotCi0gICAgICAgIC8vIHZlcnNpb24gb2YgdGhlIGRvY3VtZW50IGlzIFhNTCAxLjEKLSAgICAgICAgaWYgKGlzWE1MMTFWZXJzaW9uKSB7Ci0gICAgICAgICAgICAvLyB3ZSBuZWVkIHRvIGNoZWNrIGFsbCBjaHJhY3RlcnMgYXMgcGVyIHByb2R1Y3Rpb24gcnVsZXMgb2YgWE1MMTEKLSAgICAgICAgICAgIGludCBpID0gMDsKLSAgICAgICAgICAgIHdoaWxlKGkgPCBkYXRhbGVuZ3RoKXsKLSAgICAgICAgICAgICAgICBjaGFyIGMgPSBkYXRhYXJyYXlbaSsrXTsKLSAgICAgICAgICAgICAgICBpZiAoIFhNTDExQ2hhci5pc1hNTDExSW52YWxpZChjKSApIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gY2hlY2sgaWYgdGhpcyBpcyBhIHN1cHBsZW1lbnRhbCBjaGFyYWN0ZXIKLSAgICAgICAgICAgICAgICAgICAgaWYgKFhNTENoYXIuaXNIaWdoU3Vycm9nYXRlKGMpICYmIGkgPCBkYXRhbGVuZ3RoKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBjaGFyIGMyID0gZGF0YWFycmF5W2krK107Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoWE1MQ2hhci5pc0xvd1N1cnJvZ2F0ZShjMikgJiYKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxDaGFyLmlzU3VwcGxlbWVudGFsKFhNTENoYXIuc3VwcGxlbWVudGFsKGMsIGMyKSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbXNnID0gRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKAotICAgICAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgIkludmFsaWRDaGFySW5DRFNlY3QiLAotICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgSW50ZWdlci50b1N0cmluZyhjLCAxNil9KTsKLSAgICAgICAgICAgICAgICAgICAgcmVwb3J0RE9NRXJyb3IoCi0gICAgICAgICAgICAgICAgICAgICAgICBlcnJvckhhbmRsZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICBlcnJvciwKLSAgICAgICAgICAgICAgICAgICAgICAgIGxvY2F0b3IsCi0gICAgICAgICAgICAgICAgICAgICAgICBtc2csCi0gICAgICAgICAgICAgICAgICAgICAgICBET01FcnJvci5TRVZFUklUWV9FUlJPUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICJ3Zi1pbnZhbGlkLWNoYXJhY3RlciIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIGlmIChjID09ICddJykgewotICAgICAgICAgICAgICAgICAgICBpbnQgY291bnQgPSBpOwotICAgICAgICAgICAgICAgICAgICBpZiAoY291bnQgPCBkYXRhbGVuZ3RoICYmIGRhdGFhcnJheVtjb3VudF0gPT0gJ10nKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoKytjb3VudCA8IGRhdGFsZW5ndGggJiYgZGF0YWFycmF5W2NvdW50XSA9PSAnXScpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBkbyBub3RoaW5nCi0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY291bnQgPCBkYXRhbGVuZ3RoICYmIGRhdGFhcnJheVtjb3VudF0gPT0gJz4nKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ0RFbmRJbkNvbnRlbnQKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbXNnID0gRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwgIkNERW5kSW5Db250ZW50IiwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0RE9NRXJyb3IoZXJyb3JIYW5kbGVyLCBlcnJvciwgbG9jYXRvcixtc2csIERPTUVycm9yLlNFVkVSSVRZX0VSUk9SLCAid2YtaW52YWxpZC1jaGFyYWN0ZXIiKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9IC8vIHZlcnNpb24gb2YgdGhlIGRvY3VtZW50IGlzIFhNTCAxLjAKLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAvLyB3ZSBuZWVkIHRvIGNoZWNrIGFsbCBjaHJhY3RlcnMgYXMgcGVyIHByb2R1Y3Rpb24gcnVsZXMgb2YgWE1MIDEuMAotICAgICAgICAgICAgaW50IGkgPSAwOwotICAgICAgICAgICAgd2hpbGUgKGkgPCBkYXRhbGVuZ3RoKSB7Ci0gICAgICAgICAgICAgICAgY2hhciBjID0gZGF0YWFycmF5W2krK107Ci0gICAgICAgICAgICAgICAgaWYoIFhNTENoYXIuaXNJbnZhbGlkKGMpICkgewotICAgICAgICAgICAgICAgICAgICAvLyBjaGVjayBpZiB0aGlzIGlzIGEgc3VwcGxlbWVudGFsIGNoYXJhY3RlcgotICAgICAgICAgICAgICAgICAgICBpZiAoWE1MQ2hhci5pc0hpZ2hTdXJyb2dhdGUoYykgJiYgaSA8IGRhdGFsZW5ndGgpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGNoYXIgYzIgPSBkYXRhYXJyYXlbaSsrXTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChYTUxDaGFyLmlzTG93U3Vycm9nYXRlKGMyKSAmJgotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTENoYXIuaXNTdXBwbGVtZW50YWwoWE1MQ2hhci5zdXBwbGVtZW50YWwoYywgYzIpKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIC8vIE5vdGU6ICBUaGUga2V5IEludmFsaWRDaGFySW5DRFNlY3QgZnJvbSBYTUxNZXNzYWdlcy5wcm9wZXJ0aWVzCi0gICAgICAgICAgICAgICAgICAgIC8vIGlzIGJlaW5nIHVzZWQgdG8gb2J0YWluIHRoZSBtZXNzYWdlIGFuZCBET00gZXJyb3IgdHlwZQotICAgICAgICAgICAgICAgICAgICAvLyAid2YtaW52YWxpZC1jaGFyYWN0ZXIiIGlzIHVzZWQuICBBbHNvIHBlciBET00gaXQgaXMgZXJyb3IgYnV0Ci0gICAgICAgICAgICAgICAgICAgIC8vIGFzIHBlciBYTUwgc3BlYy4gaXQgaXMgZmF0YWwgZXJyb3IKLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG1zZyA9IERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZSgKLSAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICJJbnZhbGlkQ2hhckluQ0RTZWN0IiwKLSAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXtJbnRlZ2VyLnRvU3RyaW5nKGMsIDE2KX0pOwotICAgICAgICAgICAgICAgICAgICByZXBvcnRET01FcnJvcihlcnJvckhhbmRsZXIsIGVycm9yLCBsb2NhdG9yLCBtc2csIERPTUVycm9yLlNFVkVSSVRZX0VSUk9SLCAid2YtaW52YWxpZC1jaGFyYWN0ZXIiKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSBpZiAoYz09J10nKSB7Ci0gICAgICAgICAgICAgICAgICAgIGludCBjb3VudCA9IGk7Ci0gICAgICAgICAgICAgICAgICAgIGlmICggY291bnQ8IGRhdGFsZW5ndGggJiYgZGF0YWFycmF5W2NvdW50XT09J10nICkgewotICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKCsrY291bnQgPCBkYXRhbGVuZ3RoICYmIGRhdGFhcnJheVtjb3VudF09PSddJyApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBkbyBub3RoaW5nCi0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIGNvdW50IDwgZGF0YWxlbmd0aCAmJiBkYXRhYXJyYXlbY291bnRdPT0nPicgKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG1zZyA9IERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShET01NZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sICJDREVuZEluQ29udGVudCIsIG51bGwpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydERPTUVycm9yKGVycm9ySGFuZGxlciwgZXJyb3IsIGxvY2F0b3IsIG1zZywgRE9NRXJyb3IuU0VWRVJJVFlfRVJST1IsICJ3Zi1pbnZhbGlkLWNoYXJhY3RlciIpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gLy8gZW5kLWVsc2UgZkRvY3VtZW50LmlzWE1MVmVyc2lvbigpCi0KLSAgICB9IC8vIGlzQ0RhdGFXRgotCi0gICAgLyoqCi0gICAgICogTk9OLURPTTogY2hlY2sgZm9yIHZhbGlkIFhNTCBjaGFyYWN0ZXJzIGFzIHBlciB0aGUgWE1MIHZlcnNpb24KLSAgICAgKiBAcGFyYW0gZGF0YXZhbHVlCi0gICAgICogQHBhcmFtIGlzWE1MMTFWZXJzaW9uID0gdHJ1ZSBpZiBYTUwgMS4xCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCB2b2lkIGlzWE1MQ2hhcldGKERPTUVycm9ySGFuZGxlciBlcnJvckhhbmRsZXIsIERPTUVycm9ySW1wbCBlcnJvciwgRE9NTG9jYXRvckltcGwgbG9jYXRvciwKLSAgICAgICAgU3RyaW5nIGRhdGF2YWx1ZSwgYm9vbGVhbiBpc1hNTDExVmVyc2lvbikKLSAgICB7Ci0gICAgICAgIGlmICggZGF0YXZhbHVlID09IG51bGwgfHwgKGRhdGF2YWx1ZS5sZW5ndGgoKSA9PSAwKSApIHsKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotCi0gICAgICAgIGNoYXIgW10gZGF0YWFycmF5ID0gZGF0YXZhbHVlLnRvQ2hhckFycmF5KCk7Ci0gICAgICAgIGludCBkYXRhbGVuZ3RoID0gZGF0YWFycmF5Lmxlbmd0aDsKLQotICAgICAgICAvLyB2ZXJzaW9uIG9mIHRoZSBkb2N1bWVudCBpcyBYTUwgMS4xCi0gICAgICAgIGlmKGlzWE1MMTFWZXJzaW9uKXsKLSAgICAgICAgICAgIC8vd2UgbmVlZCB0byBjaGVjayBhbGwgY2hhcmFjdGVycyBhcyBwZXIgcHJvZHVjdGlvbiBydWxlcyBvZiBYTUwxMQotICAgICAgICAgICAgaW50IGkgPSAwIDsKLSAgICAgICAgICAgIHdoaWxlIChpIDwgZGF0YWxlbmd0aCkgewotICAgICAgICAgICAgICAgIGlmKFhNTDExQ2hhci5pc1hNTDExSW52YWxpZChkYXRhYXJyYXlbaSsrXSkpewotICAgICAgICAgICAgICAgICAgICAvLyBjaGVjayBpZiB0aGlzIGlzIGEgc3VwcGxlbWVudGFsIGNoYXJhY3RlcgotICAgICAgICAgICAgICAgICAgICBjaGFyIGNoID0gZGF0YWFycmF5W2ktMV07Ci0gICAgICAgICAgICAgICAgICAgIGlmIChYTUxDaGFyLmlzSGlnaFN1cnJvZ2F0ZShjaCkgJiYgaSA8IGRhdGFsZW5ndGgpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGNoYXIgY2gyID0gZGF0YWFycmF5W2krK107Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoWE1MQ2hhci5pc0xvd1N1cnJvZ2F0ZShjaDIpICYmCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MQ2hhci5pc1N1cHBsZW1lbnRhbChYTUxDaGFyLnN1cHBsZW1lbnRhbChjaCwgY2gyKSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbXNnID0gRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKAotICAgICAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiSW52YWxpZFhNTENoYXJJbkRPTSIsCi0gICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117SW50ZWdlci50b1N0cmluZyhkYXRhYXJyYXlbaS0xXSwgMTYpfSk7Ci0gICAgICAgICAgICAgICAgICAgIHJlcG9ydERPTUVycm9yKGVycm9ySGFuZGxlciwgZXJyb3IsIGxvY2F0b3IsIG1zZywgRE9NRXJyb3IuU0VWRVJJVFlfRVJST1IsCi0gICAgICAgICAgICAgICAgICAgICJ3Zi1pbnZhbGlkLWNoYXJhY3RlciIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfSAvLyB2ZXJzaW9uIG9mIHRoZSBkb2N1bWVudCBpcyBYTUwgMS4wCi0gICAgICAgIGVsc2V7Ci0gICAgICAgICAgICAvLyB3ZSBuZWVkIHRvIGNoZWNrIGFsbCBjaGFyYWN0ZXJzIGFzIHBlciBwcm9kdWN0aW9uIHJ1bGVzIG9mIFhNTCAxLjAKLSAgICAgICAgICAgIGludCBpID0gMCA7Ci0gICAgICAgICAgICB3aGlsZSAoaSA8IGRhdGFsZW5ndGgpIHsKLSAgICAgICAgICAgICAgICBpZiggWE1MQ2hhci5pc0ludmFsaWQoZGF0YWFycmF5W2krK10pICkgewotICAgICAgICAgICAgICAgICAgICAvLyBjaGVjayBpZiB0aGlzIGlzIGEgc3VwcGxlbWVudGFsIGNoYXJhY3RlcgotICAgICAgICAgICAgICAgICAgICBjaGFyIGNoID0gZGF0YWFycmF5W2ktMV07Ci0gICAgICAgICAgICAgICAgICAgIGlmIChYTUxDaGFyLmlzSGlnaFN1cnJvZ2F0ZShjaCkgJiYgaSA8IGRhdGFsZW5ndGgpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGNoYXIgY2gyID0gZGF0YWFycmF5W2krK107Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoWE1MQ2hhci5pc0xvd1N1cnJvZ2F0ZShjaDIpICYmCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MQ2hhci5pc1N1cHBsZW1lbnRhbChYTUxDaGFyLnN1cHBsZW1lbnRhbChjaCwgY2gyKSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbXNnID0gRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKAotICAgICAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiSW52YWxpZFhNTENoYXJJbkRPTSIsCi0gICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117SW50ZWdlci50b1N0cmluZyhkYXRhYXJyYXlbaS0xXSwgMTYpfSk7Ci0gICAgICAgICAgICAgICAgICAgIHJlcG9ydERPTUVycm9yKGVycm9ySGFuZGxlciwgZXJyb3IsIGxvY2F0b3IsIG1zZywgRE9NRXJyb3IuU0VWRVJJVFlfRVJST1IsCi0gICAgICAgICAgICAgICAgICAgICJ3Zi1pbnZhbGlkLWNoYXJhY3RlciIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfSAvLyBlbmQtZWxzZSBmRG9jdW1lbnQuaXNYTUxWZXJzaW9uKCkKLQotICAgIH0gLy8gaXNYTUxDaGFyV0YKLQotICAgIC8qKgotICAgICAqIE5PTi1ET006IGNoZWNrIGlmIHZhbHVlIG9mIHRoZSBjb21tZW50IGlzIHdlbGwtZm9ybWVkCi0gICAgICogQHBhcmFtIGRhdGF2YWx1ZQotICAgICAqIEBwYXJhbSBpc1hNTDExVmVyc2lvbiA9IHRydWUgaWYgWE1MIDEuMQotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgdm9pZCBpc0NvbW1lbnRXRihET01FcnJvckhhbmRsZXIgZXJyb3JIYW5kbGVyLCBET01FcnJvckltcGwgZXJyb3IsIERPTUxvY2F0b3JJbXBsIGxvY2F0b3IsCi0gICAgICAgIFN0cmluZyBkYXRhdmFsdWUsIGJvb2xlYW4gaXNYTUwxMVZlcnNpb24pCi0gICAgewotICAgICAgICBpZiAoIGRhdGF2YWx1ZSA9PSBudWxsIHx8IChkYXRhdmFsdWUubGVuZ3RoKCkgPT0gMCkgKSB7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLQotICAgICAgICBjaGFyIFtdIGRhdGFhcnJheSA9IGRhdGF2YWx1ZS50b0NoYXJBcnJheSgpOwotICAgICAgICBpbnQgZGF0YWxlbmd0aCA9IGRhdGFhcnJheS5sZW5ndGggOwotCi0gICAgICAgIC8vIHZlcnNpb24gb2YgdGhlIGRvY3VtZW50IGlzIFhNTCAxLjEKLSAgICAgICAgaWYgKGlzWE1MMTFWZXJzaW9uKSB7Ci0gICAgICAgICAgICAvLyB3ZSBuZWVkIHRvIGNoZWNrIGFsbCBjaHJhY3RlcnMgYXMgcGVyIHByb2R1Y3Rpb24gcnVsZXMgb2YgWE1MMTEKLSAgICAgICAgICAgIGludCBpID0gMCA7Ci0gICAgICAgICAgICB3aGlsZSAoaSA8IGRhdGFsZW5ndGgpewotICAgICAgICAgICAgICAgIGNoYXIgYyA9IGRhdGFhcnJheVtpKytdOwotICAgICAgICAgICAgICAgIGlmICggWE1MMTFDaGFyLmlzWE1MMTFJbnZhbGlkKGMpICkgewotICAgICAgICAgICAgICAgICAgICAvLyBjaGVjayBpZiB0aGlzIGlzIGEgc3VwcGxlbWVudGFsIGNoYXJhY3RlcgotICAgICAgICAgICAgICAgICAgICBpZiAoWE1MQ2hhci5pc0hpZ2hTdXJyb2dhdGUoYykgJiYgaSA8IGRhdGFsZW5ndGgpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGNoYXIgYzIgPSBkYXRhYXJyYXlbaSsrXTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChYTUxDaGFyLmlzTG93U3Vycm9nYXRlKGMyKSAmJgotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTENoYXIuaXNTdXBwbGVtZW50YWwoWE1MQ2hhci5zdXBwbGVtZW50YWwoYywgYzIpKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIFN0cmluZyBtc2cgPSBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgIkludmFsaWRDaGFySW5Db21tZW50IiwKLSAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3QgW10ge0ludGVnZXIudG9TdHJpbmcoZGF0YWFycmF5W2ktMV0sIDE2KX0pOwotICAgICAgICAgICAgICAgICAgICByZXBvcnRET01FcnJvcihlcnJvckhhbmRsZXIsIGVycm9yLCBsb2NhdG9yLCBtc2csIERPTUVycm9yLlNFVkVSSVRZX0VSUk9SLCAid2YtaW52YWxpZC1jaGFyYWN0ZXIiKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSBpZiAoYyA9PSAnLScgJiYgaSA8IGRhdGFsZW5ndGggJiYgZGF0YWFycmF5W2ldID09ICctJykgewotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbXNnID0gRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICJEYXNoRGFzaEluQ29tbWVudCIsIG51bGwpOwotICAgICAgICAgICAgICAgICAgICAvLyBpbnZhbGlkOiAnLS0nIGluIGNvbW1lbnQKLSAgICAgICAgICAgICAgICAgICAgcmVwb3J0RE9NRXJyb3IoZXJyb3JIYW5kbGVyLCBlcnJvciwgbG9jYXRvciwgbXNnLCBET01FcnJvci5TRVZFUklUWV9FUlJPUiwgIndmLWludmFsaWQtY2hhcmFjdGVyIik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9IC8vIHZlcnNpb24gb2YgdGhlIGRvY3VtZW50IGlzIFhNTCAxLjAKLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAvLyB3ZSBuZWVkIHRvIGNoZWNrIGFsbCBjaHJhY3RlcnMgYXMgcGVyIHByb2R1Y3Rpb24gcnVsZXMgb2YgWE1MIDEuMAotICAgICAgICAgICAgaW50IGkgPSAwOwotICAgICAgICAgICAgd2hpbGUgKGkgPCBkYXRhbGVuZ3RoKXsKLSAgICAgICAgICAgICAgICBjaGFyIGMgPSBkYXRhYXJyYXlbaSsrXTsKLSAgICAgICAgICAgICAgICBpZiggWE1MQ2hhci5pc0ludmFsaWQoYykgKXsKLSAgICAgICAgICAgICAgICAgICAgLy8gY2hlY2sgaWYgdGhpcyBpcyBhIHN1cHBsZW1lbnRhbCBjaGFyYWN0ZXIKLSAgICAgICAgICAgICAgICAgICAgaWYgKFhNTENoYXIuaXNIaWdoU3Vycm9nYXRlKGMpICYmIGkgPCBkYXRhbGVuZ3RoKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBjaGFyIGMyID0gZGF0YWFycmF5W2krK107Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoWE1MQ2hhci5pc0xvd1N1cnJvZ2F0ZShjMikgJiYKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxDaGFyLmlzU3VwcGxlbWVudGFsKFhNTENoYXIuc3VwcGxlbWVudGFsKGMsIGMyKSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbXNnID0gRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICJJbnZhbGlkQ2hhckluQ29tbWVudCIsIG5ldyBPYmplY3QgW10ge0ludGVnZXIudG9TdHJpbmcoZGF0YWFycmF5W2ktMV0sIDE2KX0pOwotICAgICAgICAgICAgICAgICAgICByZXBvcnRET01FcnJvcihlcnJvckhhbmRsZXIsIGVycm9yLCBsb2NhdG9yLCBtc2csIERPTUVycm9yLlNFVkVSSVRZX0VSUk9SLCAid2YtaW52YWxpZC1jaGFyYWN0ZXIiKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSBpZiAoYyA9PSAnLScgJiYgaTxkYXRhbGVuZ3RoICYmIGRhdGFhcnJheVtpXT09Jy0nKXsKLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG1zZyA9IERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShET01NZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAiRGFzaERhc2hJbkNvbW1lbnQiLCBudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgLy8gaW52YWxpZDogJy0tJyBpbiBjb21tZW50Ci0gICAgICAgICAgICAgICAgICAgIHJlcG9ydERPTUVycm9yKGVycm9ySGFuZGxlciwgZXJyb3IsIGxvY2F0b3IsIG1zZywgRE9NRXJyb3IuU0VWRVJJVFlfRVJST1IsICJ3Zi1pbnZhbGlkLWNoYXJhY3RlciIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICB9IC8vIGVuZC1lbHNlIGZEb2N1bWVudC5pc1hNTFZlcnNpb24oKQotCi0gICAgfSAvLyBpc0NvbW1lbnRXRgotCi0gICAgLyoqIE5PTi1ET006IGNoZWNrIGlmIGF0dHJpYnV0ZSB2YWx1ZSBpcyB3ZWxsLWZvcm1lZAotICAgICAqIEBwYXJhbSBhdHRyaWJ1dGVzCi0gICAgICogQHBhcmFtIGEKLSAgICAgKiBAcGFyYW0gdmFsdWUKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHZvaWQgaXNBdHRyVmFsdWVXRihET01FcnJvckhhbmRsZXIgZXJyb3JIYW5kbGVyLCBET01FcnJvckltcGwgZXJyb3IsCi0gICAgICAgICAgICBET01Mb2NhdG9ySW1wbCBsb2NhdG9yLCBOYW1lZE5vZGVNYXAgYXR0cmlidXRlcywgQXR0ciBhLCBTdHJpbmcgdmFsdWUsIGJvb2xlYW4geG1sMTFWZXJzaW9uKSB7Ci0gICAgICAgIGlmIChhIGluc3RhbmNlb2YgQXR0ckltcGwgJiYgKChBdHRySW1wbClhKS5oYXNTdHJpbmdWYWx1ZSgpKSB7Ci0gICAgICAgICAgICBpc1hNTENoYXJXRihlcnJvckhhbmRsZXIsIGVycm9yLCBsb2NhdG9yLCB2YWx1ZSwgeG1sMTFWZXJzaW9uKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBOb2RlTGlzdCBjaGlsZHJlbiA9IGEuZ2V0Q2hpbGROb2RlcygpOwotICAgICAgICAgICAgLy9jaGVjayBlYWNoIGNoaWxkIG5vZGUgb2YgdGhlIGF0dHJpYnV0ZSdzIHZhbHVlCi0gICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IGNoaWxkcmVuLmdldExlbmd0aCgpOyBqKyspIHsKLSAgICAgICAgICAgICAgICBOb2RlIGNoaWxkID0gY2hpbGRyZW4uaXRlbShqKTsKLSAgICAgICAgICAgICAgICAvL0lmIHRoZSBhdHRyaWJ1dGUncyBjaGlsZCBpcyBhbiBlbnRpdHkgcmVmZXJuY2UKLSAgICAgICAgICAgICAgICBpZiAoY2hpbGQuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLkVOVElUWV9SRUZFUkVOQ0VfTk9ERSkgewotICAgICAgICAgICAgICAgICAgICBEb2N1bWVudCBvd25lciA9IGEuZ2V0T3duZXJEb2N1bWVudCgpOwotICAgICAgICAgICAgICAgICAgICBFbnRpdHkgZW50ID0gbnVsbDsKLSAgICAgICAgICAgICAgICAgICAgLy9zZWFyY2ggZm9yIHRoZSBlbnRpdHkgaW4gdGhlIGRvY1R5cGUKLSAgICAgICAgICAgICAgICAgICAgLy9vZiB0aGUgYXR0cmlidXRlJ3Mgb3duZXJEb2N1bWVudAotICAgICAgICAgICAgICAgICAgICBpZiAob3duZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgRG9jdW1lbnRUeXBlIGRvY1R5cGUgPSBvd25lci5nZXREb2N0eXBlKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZG9jVHlwZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgTmFtZWROb2RlTWFwIGVudGl0aWVzID0gZG9jVHlwZS5nZXRFbnRpdGllcygpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVudCA9IChFbnRpdHkpIGVudGl0aWVzLmdldE5hbWVkSXRlbU5TKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIioiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGQuZ2V0Tm9kZU5hbWUoKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgLy9JZiB0aGUgZW50aXR5IHdhcyBub3QgZm91bmQgaXNzdWUgYSBmYXRhbCBlcnJvcgotICAgICAgICAgICAgICAgICAgICBpZiAoZW50ID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBtc2cgPSBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiVW5kZWNsYXJlZEVudFJlZkluQXR0clZhbHVlIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117YS5nZXROb2RlTmFtZSgpfSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRET01FcnJvcihlcnJvckhhbmRsZXIsIGVycm9yLCBsb2NhdG9yLCBtc2csIERPTUVycm9yLlNFVkVSSVRZX0VSUk9SLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICJVbmRlY2xhcmVkRW50UmVmSW5BdHRyVmFsdWUiKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gVGV4dCBub2RlCi0gICAgICAgICAgICAgICAgICAgIGlzWE1MQ2hhcldGKGVycm9ySGFuZGxlciwgZXJyb3IsIGxvY2F0b3IsIGNoaWxkLmdldE5vZGVWYWx1ZSgpLCB4bWwxMVZlcnNpb24pOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotCi0KLSAgICAvKioKLSAgICAgKiBSZXBvcnRzIGEgRE9NIGVycm9yIHRvIHRoZSB1c2VyIGhhbmRsZXIuCi0gICAgICoKLSAgICAgKiBJZiB0aGUgZXJyb3IgaXMgZmF0YWwsIHRoZSBwcm9jZXNzaW5nIHdpbGwgYmUgYWx3YXlzIGFib3J0ZWQuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCB2b2lkIHJlcG9ydERPTUVycm9yKERPTUVycm9ySGFuZGxlciBlcnJvckhhbmRsZXIsIERPTUVycm9ySW1wbCBlcnJvciwgRE9NTG9jYXRvckltcGwgbG9jYXRvciwKLSAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBtZXNzYWdlLCBzaG9ydCBzZXZlcml0eSwgU3RyaW5nIHR5cGUgKSB7Ci0gICAgICAgIGlmKCBlcnJvckhhbmRsZXIhPW51bGwgKSB7Ci0gICAgICAgICAgICBlcnJvci5yZXNldCgpOwotICAgICAgICAgICAgZXJyb3IuZk1lc3NhZ2UgPSBtZXNzYWdlOwotICAgICAgICAgICAgZXJyb3IuZlNldmVyaXR5ID0gc2V2ZXJpdHk7Ci0gICAgICAgICAgICBlcnJvci5mTG9jYXRvciA9IGxvY2F0b3I7Ci0gICAgICAgICAgICBlcnJvci5mVHlwZSA9IHR5cGU7Ci0gICAgICAgICAgICBlcnJvci5mUmVsYXRlZERhdGEgPSBsb2NhdG9yLmZSZWxhdGVkTm9kZTsKLQotICAgICAgICAgICAgaWYoIWVycm9ySGFuZGxlci5oYW5kbGVFcnJvcihlcnJvcikpCi0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFib3J0RXhjZXB0aW9uKCk7Ci0gICAgICAgIH0KLSAgICAgICAgaWYoIHNldmVyaXR5PT1ET01FcnJvci5TRVZFUklUWV9GQVRBTF9FUlJPUiApCi0gICAgICAgICAgICB0aHJvdyBuZXcgQWJvcnRFeGNlcHRpb24oKTsKLSAgICB9Ci0KLSAgICBwcm90ZWN0ZWQgZmluYWwgdm9pZCB1cGRhdGVRTmFtZSAoTm9kZSBub2RlLCBRTmFtZSBxbmFtZSl7Ci0KLSAgICAgICAgU3RyaW5nIHByZWZpeCAgICA9IG5vZGUuZ2V0UHJlZml4KCk7Ci0gICAgICAgIFN0cmluZyBuYW1lc3BhY2UgPSBub2RlLmdldE5hbWVzcGFjZVVSSSgpOwotICAgICAgICBTdHJpbmcgbG9jYWxOYW1lID0gbm9kZS5nZXRMb2NhbE5hbWUoKTsKLSAgICAgICAgLy8gUkVWSVNJVDogdGhlIHN5bWJvbHMgYXJlIGFkZGVkIHRvbyBvZnRlbjogc3RhcnQvZW5kRWxlbWVudAotICAgICAgICAvLyAgICAgICAgICBhbmQgaW4gdGhlIG5hbWVzcGFjZUZpeHVwLiBTaG91bGQgcmVkdWNlIG51bWJlciBvZiBjYWxscyB0byBzeW1ib2wgdGFibGUuCi0gICAgICAgIHFuYW1lLnByZWZpeCA9IChwcmVmaXghPW51bGwgJiYgcHJlZml4Lmxlbmd0aCgpIT0wKT9mU3ltYm9sVGFibGUuYWRkU3ltYm9sKHByZWZpeCk6bnVsbDsKLSAgICAgICAgcW5hbWUubG9jYWxwYXJ0ID0gKGxvY2FsTmFtZSAhPSBudWxsKT9mU3ltYm9sVGFibGUuYWRkU3ltYm9sKGxvY2FsTmFtZSk6bnVsbDsKLSAgICAgICAgcW5hbWUucmF3bmFtZSA9IGZTeW1ib2xUYWJsZS5hZGRTeW1ib2wobm9kZS5nZXROb2RlTmFtZSgpKTsKLSAgICAgICAgcW5hbWUudXJpID0gIChuYW1lc3BhY2UgIT0gbnVsbCk/ZlN5bWJvbFRhYmxlLmFkZFN5bWJvbChuYW1lc3BhY2UpOm51bGw7Ci0gICAgfQotCi0KLQotICAgICAgICAvKiBSRVZJU0lUOiByZW1vdmUgdGhpcyBtZXRob2QgaWYgRE9NIGRvZXMgbm90IGNoYW5nZSBzcGVjLgotICAgICAgICAgKiBQZXJmb3JtcyBwYXJ0aWFsIFhNTCAxLjAgYXR0cmlidXRlIHZhbHVlIG5vcm1hbGl6YXRpb24gYW5kIHJlcGxhY2VzCi0gICAgICogYXR0cmlidXRlIHZhbHVlIGlmIHRoZSB2YWx1ZSBpcyBjaGFuZ2VkIGFmdGVyIHRoZSBub3JtYWxpemF0aW9uLgotICAgICAqIERPTSBkZWZpbmVzIHRoYXQgbm9ybWFsaXplRG9jdW1lbnQgYWN0cyBhcyBpZiB0aGUgZG9jdW1lbnQgd2FzIGdvaW5nCi0gICAgICogdGhyb3VnaCBhIHNhdmUgYW5kIGxvYWQgY3ljbGUsIGdpdmVuIHRoYXQgc2VyaWFsaXplciB3aWxsIG5vdCBlc2NhcGUKLSAgICAgKiBhbnkgJ1xuJyBvciAnXHInIGNoYXJhY3RlcnMgb24gbG9hZCB0aG9zZSB3aWxsIGJlIG5vcm1hbGl6ZWQuCi0gICAgICogVGh1cyBkdXJpbmcgbm9ybWFsaXplIGRvY3VtZW50IHdlIG5lZWQgdG8gZG8gdGhlIGZvbGxvd2luZzoKLSAgICAgKiAtIHBlcmZvcm0gIjIuMTEgRW5kLW9mLUxpbmUgSGFuZGxpbmciCi0gICAgICogLSByZXBsYWNlICN4RCwgI3hBLCAjeDkgd2l0aCAjeDIwICh3aGl0ZSBzcGFjZSkuCi0gICAgICogTm90ZTogVGhpcyBhbGcuIHdvbid0IGF0dGVtcHQgdG8gcmVzb2x2ZSBlbnRpdHkgcmVmZXJlbmNlcyBvciBjaGFyYWN0ZXIgZW50aXR5Ci0gICAgICogcmVmZXJlbmNlcywgc2luY2UgJyYnIHdpbGwgYmUgZXNjYXBlZCBkdXJpbmcgc2VyaWFsaXphdGlvbiBhbmQgZHVyaW5nIGxvYWRpbmcKLSAgICAgKiB0aGlzIHdvbid0IGJlIHJlY29nbml6ZWQgYXMgZW50aXR5IHJlZmVyZW5jZSwgaS5lLiBhdHRyaWJ1dGUgdmFsdWUgIiZmb287IiB3aWxsCi0gICAgICogYmUgc2VyaWFsaXplZCBhcyAiJmFtcDtmb287IiBhbmQgdGh1cyBhZnRlciBsb2FkaW5nIHdpbGwgYmUgIiZmb287IiBhZ2Fpbi4KLSAgICAgICAgICogQHBhcmFtIHZhbHVlIGN1cnJlbnQgYXR0cmlidXRlIHZhbHVlCi0gICAgICAgICAqIEBwYXJhbSBhdHRyIGN1cnJlbnQgYXR0cmlidXRlCi0gICAgICAgICAqIEByZXR1cm4gU3RyaW5nIHRoZSB2YWx1ZSAoY291bGQgYmUgb3JpZ2luYWwgaWYgbm9ybWFsaXphdGlvbiBkaWQgbm90IGNoYW5nZQotICAgICAqIHRoZSBzdHJpbmcpCi0gICAgICAgICAqLwotICAgIGZpbmFsIFN0cmluZyBub3JtYWxpemVBdHRyaWJ1dGVWYWx1ZShTdHJpbmcgdmFsdWUsIEF0dHIgYXR0cikgewotICAgICAgICBpZiAoIWF0dHIuZ2V0U3BlY2lmaWVkKCkpewotICAgICAgICAgICAgLy8gc3BlY2lmaWVkIGF0dHJpYnV0ZXMgc2hvdWxkIGFscmVhZHkgaGF2ZSBhIG5vcm1hbGl6ZWQgZm9ybQotICAgICAgICAgICAgLy8gc2luY2UgdGhvc2Ugd2VyZSBhZGRlZCBieSB2YWxpZGF0b3IKLSAgICAgICAgICAgIHJldHVybiB2YWx1ZTsKLSAgICAgICAgfQotICAgICAgICBpbnQgZW5kID0gdmFsdWUubGVuZ3RoKCk7Ci0gICAgICAgIC8vIGVuc3VyZSBjYXBhY2l0eQotICAgICAgICBpZiAoZk5vcm1hbGl6ZWRWYWx1ZS5jaC5sZW5ndGggPCBlbmQpIHsKLSAgICAgICAgICAgIGZOb3JtYWxpemVkVmFsdWUuY2ggPSBuZXcgY2hhcltlbmRdOwotICAgICAgICB9Ci0gICAgICAgIGZOb3JtYWxpemVkVmFsdWUubGVuZ3RoID0gMDsKLSAgICAgICAgYm9vbGVhbiBub3JtYWxpemVkID0gZmFsc2U7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZW5kOyBpKyspIHsKLSAgICAgICAgICAgIGNoYXIgYyA9IHZhbHVlLmNoYXJBdChpKTsKLSAgICAgICAgICAgIGlmIChjPT0weDAwMDkgfHwgYz09MHgwMDBBKSB7Ci0gICAgICAgICAgICAgICBmTm9ybWFsaXplZFZhbHVlLmNoW2ZOb3JtYWxpemVkVmFsdWUubGVuZ3RoKytdID0gJyAnOwotICAgICAgICAgICAgICAgbm9ybWFsaXplZCA9IHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmKGM9PTB4MDAwRCl7Ci0gICAgICAgICAgICAgICBub3JtYWxpemVkID0gdHJ1ZTsKLSAgICAgICAgICAgICAgIGZOb3JtYWxpemVkVmFsdWUuY2hbZk5vcm1hbGl6ZWRWYWx1ZS5sZW5ndGgrK10gPSAnICc7Ci0gICAgICAgICAgICAgICBpbnQgbmV4dCA9IGkrMTsKLSAgICAgICAgICAgICAgIGlmIChuZXh0IDwgZW5kICYmIHZhbHVlLmNoYXJBdChuZXh0KT09MHgwMDBBKSBpPW5leHQ7IC8vIHNraXAgZm9sbG93aW5nIHhBCi0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBmTm9ybWFsaXplZFZhbHVlLmNoW2ZOb3JtYWxpemVkVmFsdWUubGVuZ3RoKytdID0gYzsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBpZiAobm9ybWFsaXplZCl7Ci0gICAgICAgICAgIHZhbHVlID0gZk5vcm1hbGl6ZWRWYWx1ZS50b1N0cmluZygpOwotICAgICAgICAgICBhdHRyLnNldFZhbHVlKHZhbHVlKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gdmFsdWU7Ci0gICAgfQotCi0gICAgcHJvdGVjdGVkIGZpbmFsIGNsYXNzIFhNTEF0dHJpYnV0ZXNQcm94eQotICAgIGltcGxlbWVudHMgWE1MQXR0cmlidXRlcyB7Ci0gICAgICAgIHByb3RlY3RlZCBBdHRyaWJ1dGVNYXAgZkF0dHJpYnV0ZXM7Ci0gICAgICAgIHByb3RlY3RlZCBDb3JlRG9jdW1lbnRJbXBsIGZEb2N1bWVudDsKLSAgICAgICAgcHJvdGVjdGVkIEVsZW1lbnRJbXBsIGZFbGVtZW50OwotCi0gICAgICAgIHByb3RlY3RlZCBmaW5hbCBWZWN0b3IgZkF1Z21lbnRhdGlvbnMgPSBuZXcgVmVjdG9yKDUpOwotCi0KLSAgICAgICAgcHVibGljIHZvaWQgc2V0QXR0cmlidXRlcyhBdHRyaWJ1dGVNYXAgYXR0cmlidXRlcywgQ29yZURvY3VtZW50SW1wbCBkb2MsIEVsZW1lbnRJbXBsIGVsZW0pIHsKLSAgICAgICAgICAgIGZEb2N1bWVudCA9IGRvYzsKLSAgICAgICAgICAgIGZBdHRyaWJ1dGVzID0gYXR0cmlidXRlczsKLSAgICAgICAgICAgIGZFbGVtZW50ID0gZWxlbTsKLSAgICAgICAgICAgIGlmIChhdHRyaWJ1dGVzICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gYXR0cmlidXRlcy5nZXRMZW5ndGgoKTsKLQotICAgICAgICAgICAgICAgIGZBdWdtZW50YXRpb25zLnNldFNpemUobGVuZ3RoKTsKLSAgICAgICAgICAgICAgICAvLyBSRVZJU0lUOiB0aGlzIGltcGxlbWVudGF0aW9uIGRvZXMgbm90IHN0b3JlIGFueSB2YWx1ZSBpbiBhdWdtZW50YXRpb25zCi0gICAgICAgICAgICAgICAgLy8gICAgICAgICAgYW5kIGJhc2ljYWxseSBub3Qga2VlcGluZyBhdWdzIGluIHBhcmFsbGVsIHRvIGF0dHJpYnV0ZXMgbWFwCi0gICAgICAgICAgICAgICAgLy8gICAgICAgICAgdW50aWxsIGFsbCBhdHRyaWJ1dGVzIGFyZSBhZGRlZCAoZGVmYXVsdCBhdHRyaWJ1dGVzKQotICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgZkF1Z21lbnRhdGlvbnMuc2V0RWxlbWVudEF0KG5ldyBBdWdtZW50YXRpb25zSW1wbCgpLCBpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIGZBdWdtZW50YXRpb25zLnNldFNpemUoMCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotCi0gICAgICAgICAgICAgICAgLyoqCi0gICAgICAgICAqIFRoaXMgbWV0aG9kIGFkZHMgZGVmYXVsdCBkZWNsYXJhdGlvbnMKLSAgICAgICAgICAgICAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTEF0dHJpYnV0ZXMjYWRkQXR0cmlidXRlKFFOYW1lLCBTdHJpbmcsIFN0cmluZykKLSAgICAgICAgICAgICAgICAgKi8KLSAgICAgICAgICAgICAgICBwdWJsaWMgaW50IGFkZEF0dHJpYnV0ZShRTmFtZSBxbmFtZSwgU3RyaW5nIGF0dHJUeXBlLCBTdHJpbmcgYXR0clZhbHVlKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpbnQgaW5kZXggPSBmRWxlbWVudC5nZXRYZXJjZXNBdHRyaWJ1dGUocW5hbWUudXJpLCBxbmFtZS5sb2NhbHBhcnQpOwotICAgICAgICAgICAgICAgICAgICAgICAgLy8gYWRkIGRlZmF1bHRzIHRvIHRoZSB0cmVlCi0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5kZXggPCAwKSB7Ci0gICAgICAgICAgICAgICAgLy8gdGhlIGRlZmF1bHQgYXR0cmlidXRlIHdhcyByZW1vdmVkIGJ5IGEgdXNlciBhbmQgbmVlZGVkIHRvCi0gICAgICAgICAgICAgICAgLy8gYmUgYWRkZWQgYmFjawotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdHRySW1wbCBhdHRyID0gKEF0dHJJbXBsKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoQ29yZURvY3VtZW50SW1wbCkgZkVsZW1lbnQuZ2V0T3duZXJEb2N1bWVudCgpKS5jcmVhdGVBdHRyaWJ1dGVOUygKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHFuYW1lLnVyaSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHFuYW1lLnJhd25hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBxbmFtZS5sb2NhbHBhcnQpOwotICAgICAgICAgICAgICAgIC8vIFJFVklTSVQ6IHRoZSBmb2xsb3dpbmcgc2hvdWxkIGFsc28gdXBkYXRlIElEIHRhYmxlCi0gICAgICAgICAgICAgICAgYXR0ci5zZXROb2RlVmFsdWUoYXR0clZhbHVlKTsKLSAgICAgICAgICAgICAgICBpbmRleCA9IGZFbGVtZW50LnNldFhlcmNlc0F0dHJpYnV0ZU5vZGUoYXR0cik7Ci0gICAgICAgICAgICAgICAgZkF1Z21lbnRhdGlvbnMuaW5zZXJ0RWxlbWVudEF0KG5ldyBBdWdtZW50YXRpb25zSW1wbCgpLCBpbmRleCk7Ci0gICAgICAgICAgICAgICAgYXR0ci5zZXRTcGVjaWZpZWQoZmFsc2UpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgLy8gZGVmYXVsdCBhdHRyaWJ1dGUgaXMgaW4gdGhlIHRyZWUKLSAgICAgICAgICAgICAgICAvLyB3ZSBkb24ndCBuZWVkIHRvIGRvIGFueXRoaW5nIHNpbmNlIHByZWZpeCB3YXMgYWxyZWFkeSBmaXhlZAotICAgICAgICAgICAgICAgIC8vIGF0IHRoZSBuYW1lc3BhY2UgZml4dXAgdGltZSBhbmQgdmFsdWUgbXVzdCBiZSBzYW1lIHZhbHVlLCBvdGhlcndpc2UKLSAgICAgICAgICAgICAgICAvLyBhdHRyaWJ1dGUgd2lsbCBiZSB0cmVhdGVkIGFzIHNwZWNpZmllZCBhbmQgd2Ugd2lsbCBuZXZlciByZWFjaAotICAgICAgICAgICAgICAgIC8vIHRoaXMgbWV0aG9kLgotCi0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gaW5kZXg7Ci0gICAgICAgICAgICAgICAgfQotCi0KLSAgICAgICAgcHVibGljIHZvaWQgcmVtb3ZlQWxsQXR0cmlidXRlcygpewotICAgICAgICAgICAgLy8gUkVWSVNJVDogaW1wbGVtZW50Ci0gICAgICAgIH0KLQotCi0gICAgICAgIHB1YmxpYyB2b2lkIHJlbW92ZUF0dHJpYnV0ZUF0KGludCBhdHRySW5kZXgpewotICAgICAgICAgICAgLy8gUkVWSVNJVDogaW1wbGVtZW50Ci0gICAgICAgIH0KLQotCi0gICAgICAgIHB1YmxpYyBpbnQgZ2V0TGVuZ3RoKCl7Ci0gICAgICAgICAgICByZXR1cm4oZkF0dHJpYnV0ZXMgIT0gbnVsbCk/ZkF0dHJpYnV0ZXMuZ2V0TGVuZ3RoKCk6MDsKLSAgICAgICAgfQotCi0KLSAgICAgICAgcHVibGljIGludCBnZXRJbmRleChTdHJpbmcgcU5hbWUpewotICAgICAgICAgICAgLy8gUkVWSVNJVDogaW1wbGVtZW50Ci0gICAgICAgICAgICByZXR1cm4gLTE7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgaW50IGdldEluZGV4KFN0cmluZyB1cmksIFN0cmluZyBsb2NhbFBhcnQpewotICAgICAgICAgICAgLy8gUkVWSVNJVDogaW1wbGVtZW50Ci0gICAgICAgICAgICByZXR1cm4gLTE7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCBzZXROYW1lKGludCBhdHRySW5kZXgsIFFOYW1lIGF0dHJOYW1lKXsKLSAgICAgICAgICAgIC8vIFJFVklTSVQ6IGltcGxlbWVudAotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIHZvaWQgZ2V0TmFtZShpbnQgYXR0ckluZGV4LCBRTmFtZSBhdHRyTmFtZSl7Ci0gICAgICAgICAgICBpZiAoZkF0dHJpYnV0ZXMgIT1udWxsKSB7Ci0gICAgICAgICAgICAgICAgdXBkYXRlUU5hbWUoKE5vZGUpZkF0dHJpYnV0ZXMuZ2V0SXRlbShhdHRySW5kZXgpLCBhdHRyTmFtZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFByZWZpeChpbnQgaW5kZXgpewotICAgICAgICAgICAgLy8gUkVWSVNJVDogaW1wbGVtZW50Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotCi0KLSAgICAgICAgcHVibGljIFN0cmluZyBnZXRVUkkoaW50IGluZGV4KXsKLSAgICAgICAgICAgIC8vIFJFVklTSVQ6IGltcGxlbWVudAotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLQotCi0gICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0TG9jYWxOYW1lKGludCBpbmRleCl7Ci0gICAgICAgICAgICAvLyBSRVZJU0lUOiBpbXBsZW1lbnQKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0KLQotICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFFOYW1lKGludCBpbmRleCl7Ci0gICAgICAgICAgICAvLyBSRVZJU0lUOiBpbXBsZW1lbnQKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0KLSAgICAgICAgIHB1YmxpYyBRTmFtZSBnZXRRdWFsaWZpZWROYW1lKGludCBpbmRleCl7Ci0gICAgICAgICAgICAvL3JldHVybiBmQXR0cmlidXRlcy5pdGVtKGluZGV4KS5nZSk7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyB2b2lkIHNldFR5cGUoaW50IGF0dHJJbmRleCwgU3RyaW5nIGF0dHJUeXBlKXsKLSAgICAgICAgICAgIC8vIFJFVklTSVQ6IGltcGxlbWVudAotICAgICAgICB9Ci0KLQotICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFR5cGUoaW50IGluZGV4KXsKLSAgICAgICAgICAgIHJldHVybiAiQ0RBVEEiOwotICAgICAgICB9Ci0KLQotICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFR5cGUoU3RyaW5nIHFOYW1lKXsKLSAgICAgICAgICAgIHJldHVybiAiQ0RBVEEiOwotICAgICAgICB9Ci0KLQotICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFR5cGUoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSl7Ci0gICAgICAgICAgICByZXR1cm4gIkNEQVRBIjsKLSAgICAgICAgfQotCi0KLSAgICAgICAgcHVibGljIHZvaWQgc2V0VmFsdWUoaW50IGF0dHJJbmRleCwgU3RyaW5nIGF0dHJWYWx1ZSl7Ci0gICAgICAgICAgICAvLyBSRVZJU0lUOiBpcyB0aGlzIGRlc2lyZWQgYmVoYXZpb3VyPwotICAgICAgICAgICAgLy8gVGhlIHZhbHVlcyBhcmUgdXBkYXRlZCBpbiB0aGUgY2FzZSBkYXRhdHlwZS1ub3JtYWxpemF0aW9uIGlzIHR1cm5lZCBvbgotICAgICAgICAgICAgLy8gaW4gdGhpcyBjYXNlIHdlIG5lZWQgdG8gbWFrZSBzdXJlIHRoYXQgc3BlY2lmaWVkIGF0dHJpYnV0ZXMgc3RheSBzcGVjaWZpZWQKLQotICAgICAgICAgICAgaWYgKGZBdHRyaWJ1dGVzICE9IG51bGwpewotICAgICAgICAgICAgICAgIEF0dHJJbXBsIGF0dHIgPSAoQXR0ckltcGwpZkF0dHJpYnV0ZXMuZ2V0SXRlbShhdHRySW5kZXgpOwotICAgICAgICAgICAgICAgIGJvb2xlYW4gc3BlY2lmaWVkID0gYXR0ci5nZXRTcGVjaWZpZWQoKTsKLSAgICAgICAgICAgICAgICBhdHRyLnNldFZhbHVlKGF0dHJWYWx1ZSk7Ci0gICAgICAgICAgICAgICAgYXR0ci5zZXRTcGVjaWZpZWQoc3BlY2lmaWVkKTsKLQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljICB2b2lkIHNldFZhbHVlKGludCBhdHRySW5kZXgsIFN0cmluZyBhdHRyVmFsdWUsIFhNTFN0cmluZyB2YWx1ZSl7Ci0gICAgICAgICAgICBzZXRWYWx1ZShhdHRySW5kZXgsIHZhbHVlLnRvU3RyaW5nKCkpOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIFN0cmluZyBnZXRWYWx1ZShpbnQgaW5kZXgpewotICAgICAgICAgICAgcmV0dXJuIChmQXR0cmlidXRlcyAhPW51bGwpP2ZBdHRyaWJ1dGVzLml0ZW0oaW5kZXgpLmdldE5vZGVWYWx1ZSgpOiIiOwotCi0gICAgICAgIH0KLQotCi0gICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0VmFsdWUoU3RyaW5nIHFOYW1lKXsKLSAgICAgICAgICAgIC8vIFJFVklTSVQ6IGltcGxlbWVudAotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLQotCi0gICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0VmFsdWUoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSl7Ci0gICAgICAgICAgICBpZiAoZkF0dHJpYnV0ZXMgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIE5vZGUgbm9kZSA9ICBmQXR0cmlidXRlcy5nZXROYW1lZEl0ZW1OUyh1cmksIGxvY2FsTmFtZSk7Ci0gICAgICAgICAgICAgICAgcmV0dXJuKG5vZGUgIT0gbnVsbCk/IG5vZGUuZ2V0Tm9kZVZhbHVlKCk6bnVsbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0KLQotICAgICAgICBwdWJsaWMgdm9pZCBzZXROb25Ob3JtYWxpemVkVmFsdWUoaW50IGF0dHJJbmRleCwgU3RyaW5nIGF0dHJWYWx1ZSl7Ci0gICAgICAgICAgICAvLyBSRVZJU0lUOiBpbXBsZW1lbnQKLQotICAgICAgICB9Ci0KLQotICAgICAgICBwdWJsaWMgU3RyaW5nIGdldE5vbk5vcm1hbGl6ZWRWYWx1ZShpbnQgYXR0ckluZGV4KXsKLSAgICAgICAgICAgIC8vIFJFVklTSVQ6IGltcGxlbWVudAotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLQotCi0gICAgICAgIHB1YmxpYyB2b2lkIHNldFNwZWNpZmllZChpbnQgYXR0ckluZGV4LCBib29sZWFuIHNwZWNpZmllZCl7Ci0gICAgICAgICAgICBBdHRySW1wbCBhdHRyID0gKEF0dHJJbXBsKWZBdHRyaWJ1dGVzLmdldEl0ZW0oYXR0ckluZGV4KTsKLSAgICAgICAgICAgIGF0dHIuc2V0U3BlY2lmaWVkKHNwZWNpZmllZCk7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc1NwZWNpZmllZChpbnQgYXR0ckluZGV4KXsKLSAgICAgICAgICAgIHJldHVybigoQXR0cilmQXR0cmlidXRlcy5nZXRJdGVtKGF0dHJJbmRleCkpLmdldFNwZWNpZmllZCgpOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIEF1Z21lbnRhdGlvbnMgZ2V0QXVnbWVudGF0aW9ucyAoaW50IGF0dHJpYnV0ZUluZGV4KXsKLSAgICAgICAgICAgIHJldHVybihBdWdtZW50YXRpb25zKWZBdWdtZW50YXRpb25zLmVsZW1lbnRBdChhdHRyaWJ1dGVJbmRleCk7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgQXVnbWVudGF0aW9ucyBnZXRBdWdtZW50YXRpb25zIChTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxQYXJ0KXsKLSAgICAgICAgICAgIC8vIFJFVklTSVQ6IGltcGxlbWVudAotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgQXVnbWVudGF0aW9ucyBnZXRBdWdtZW50YXRpb25zKFN0cmluZyBxTmFtZSl7Ci0gICAgICAgICAgICAvLyBSRVZJU0lUOiBpbXBsZW1lbnQKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFNldHMgdGhlIGF1Z21lbnRhdGlvbnMgb2YgdGhlIGF0dHJpYnV0ZSBhdCB0aGUgc3BlY2lmaWVkIGluZGV4LgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gYXR0ckluZGV4IFRoZSBhdHRyaWJ1dGUgaW5kZXguCi0gICAgICAgICAqIEBwYXJhbSBhdWdzICAgICAgVGhlIGF1Z21lbnRhdGlvbnMuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgdm9pZCBzZXRBdWdtZW50YXRpb25zKGludCBhdHRySW5kZXgsIEF1Z21lbnRhdGlvbnMgYXVncykgewotICAgICAgICAgICAgZkF1Z21lbnRhdGlvbnMuc2V0RWxlbWVudEF0KGF1Z3MsIGF0dHJJbmRleCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvLwotICAgIC8vIFhNTERvY3VtZW50SGFuZGxlciBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFRoZSBzdGFydCBvZiB0aGUgZG9jdW1lbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbG9jYXRvciAgVGhlIGRvY3VtZW50IGxvY2F0b3IsIG9yIG51bGwgaWYgdGhlIGRvY3VtZW50Ci0gICAgICogICAgICAgICAgICAgICAgIGxvY2F0aW9uIGNhbm5vdCBiZSByZXBvcnRlZCBkdXJpbmcgdGhlIHBhcnNpbmcKLSAgICAgKiAgICAgICAgICAgICAgICAgb2YgdGhpcyBkb2N1bWVudC4gSG93ZXZlciwgaXQgaXMgPGVtPnN0cm9uZ2x5PC9lbT4KLSAgICAgKiAgICAgICAgICAgICAgICAgcmVjb21tZW5kZWQgdGhhdCBhIGxvY2F0b3IgYmUgc3VwcGxpZWQgdGhhdCBjYW4KLSAgICAgKiAgICAgICAgICAgICAgICAgYXQgbGVhc3QgcmVwb3J0IHRoZSBzeXN0ZW0gaWRlbnRpZmllciBvZiB0aGUKLSAgICAgKiAgICAgICAgICAgICAgICAgZG9jdW1lbnQuCi0gICAgICogQHBhcmFtIGVuY29kaW5nIFRoZSBhdXRvLWRldGVjdGVkIElBTkEgZW5jb2RpbmcgbmFtZSBvZiB0aGUgZW50aXR5Ci0gICAgICogICAgICAgICAgICAgICAgIHN0cmVhbS4gVGhpcyB2YWx1ZSB3aWxsIGJlIG51bGwgaW4gdGhvc2Ugc2l0dWF0aW9ucwotICAgICAqICAgICAgICAgICAgICAgICB3aGVyZSB0aGUgZW50aXR5IGVuY29kaW5nIGlzIG5vdCBhdXRvLWRldGVjdGVkIChlLmcuCi0gICAgICogICAgICAgICAgICAgICAgIGludGVybmFsIGVudGl0aWVzIG9yIGEgZG9jdW1lbnQgZW50aXR5IHRoYXQgaXMKLSAgICAgKiAgICAgICAgICAgICAgICAgcGFyc2VkIGZyb20gYSBqYXZhLmlvLlJlYWRlcikuCi0gICAgICogQHBhcmFtIG5hbWVzcGFjZUNvbnRleHQKLSAgICAgKiAgICAgICAgICAgICAgICAgVGhlIG5hbWVzcGFjZSBjb250ZXh0IGluIGVmZmVjdCBhdCB0aGUKLSAgICAgKiAgICAgICAgICAgICAgICAgc3RhcnQgb2YgdGhpcyBkb2N1bWVudC4KLSAgICAgKiAgICAgICAgICAgICAgICAgVGhpcyBvYmplY3QgcmVwcmVzZW50cyB0aGUgY3VycmVudCBjb250ZXh0LgotICAgICAqICAgICAgICAgICAgICAgICBJbXBsZW1lbnRvcnMgb2YgdGhpcyBjbGFzcyBhcmUgcmVzcG9uc2libGUKLSAgICAgKiAgICAgICAgICAgICAgICAgZm9yIGNvcHlpbmcgdGhlIG5hbWVzcGFjZSBiaW5kaW5ncyBmcm9tIHRoZQotICAgICAqICAgICAgICAgICAgICAgICB0aGUgY3VycmVudCBjb250ZXh0IChhbmQgaXRzIHBhcmVudCBjb250ZXh0cykKLSAgICAgKiAgICAgICAgICAgICAgICAgaWYgdGhhdCBpbmZvcm1hdGlvbiBpcyBpbXBvcnRhbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYXVncyAgICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqIEBleGNlcHRpb24gWE5JRXhjZXB0aW9uCi0gICAgICogICAgICAgICAgICAgICAgICAgVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RG9jdW1lbnQoWE1MTG9jYXRvciBsb2NhdG9yLCBTdHJpbmcgZW5jb2RpbmcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOYW1lc3BhY2VDb250ZXh0IG5hbWVzcGFjZUNvbnRleHQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdWdtZW50YXRpb25zIGF1Z3MpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb257Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogTm90aWZpZXMgb2YgdGhlIHByZXNlbmNlIG9mIGFuIFhNTERlY2wgbGluZSBpbiB0aGUgZG9jdW1lbnQuIElmCi0gICAgICogcHJlc2VudCwgdGhpcyBtZXRob2Qgd2lsbCBiZSBjYWxsZWQgaW1tZWRpYXRlbHkgZm9sbG93aW5nIHRoZQotICAgICAqIHN0YXJ0RG9jdW1lbnQgY2FsbC4KLSAgICAgKgotICAgICAqIEBwYXJhbSB2ZXJzaW9uICAgIFRoZSBYTUwgdmVyc2lvbi4KLSAgICAgKiBAcGFyYW0gZW5jb2RpbmcgICBUaGUgSUFOQSBlbmNvZGluZyBuYW1lIG9mIHRoZSBkb2N1bWVudCwgb3IgbnVsbCBpZgotICAgICAqICAgICAgICAgICAgICAgICAgIG5vdCBzcGVjaWZpZWQuCi0gICAgICogQHBhcmFtIHN0YW5kYWxvbmUgVGhlIHN0YW5kYWxvbmUgdmFsdWUsIG9yIG51bGwgaWYgbm90IHNwZWNpZmllZC4KLSAgICAgKiBAcGFyYW0gYXVncyAgICAgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIFhOSUV4Y2VwdGlvbgotICAgICAqICAgICAgICAgICAgICAgICAgIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB4bWxEZWNsKFN0cmluZyB2ZXJzaW9uLCBTdHJpbmcgZW5jb2RpbmcsIFN0cmluZyBzdGFuZGFsb25lLCBBdWdtZW50YXRpb25zIGF1Z3MpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb257Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogTm90aWZpZXMgb2YgdGhlIHByZXNlbmNlIG9mIHRoZSBET0NUWVBFIGxpbmUgaW4gdGhlIGRvY3VtZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIHJvb3RFbGVtZW50Ci0gICAgICogICAgICAgICAgICAgICAgIFRoZSBuYW1lIG9mIHRoZSByb290IGVsZW1lbnQuCi0gICAgICogQHBhcmFtIHB1YmxpY0lkIFRoZSBwdWJsaWMgaWRlbnRpZmllciBpZiBhbiBleHRlcm5hbCBEVEQgb3IgbnVsbAotICAgICAqICAgICAgICAgICAgICAgICBpZiB0aGUgZXh0ZXJuYWwgRFREIGlzIHNwZWNpZmllZCB1c2luZyBTWVNURU0uCi0gICAgICogQHBhcmFtIHN5c3RlbUlkIFRoZSBzeXN0ZW0gaWRlbnRpZmllciBpZiBhbiBleHRlcm5hbCBEVEQsIG51bGwKLSAgICAgKiAgICAgICAgICAgICAgICAgb3RoZXJ3aXNlLgotICAgICAqIEBwYXJhbSBhdWdzICAgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIFhOSUV4Y2VwdGlvbgotICAgICAqICAgICAgICAgICAgICAgICAgIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBkb2N0eXBlRGVjbChTdHJpbmcgcm9vdEVsZW1lbnQsIFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkLCBBdWdtZW50YXRpb25zIGF1Z3MpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb257Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQSBjb21tZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIHRleHQgICBUaGUgdGV4dCBpbiB0aGUgY29tbWVudC4KLSAgICAgKiBAcGFyYW0gYXVncyAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKgotICAgICAqIEBleGNlcHRpb24gWE5JRXhjZXB0aW9uCi0gICAgICogICAgICAgICAgICAgICAgICAgVGhyb3duIGJ5IGFwcGxpY2F0aW9uIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBjb21tZW50KFhNTFN0cmluZyB0ZXh0LCBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb257Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQSBwcm9jZXNzaW5nIGluc3RydWN0aW9uLiBQcm9jZXNzaW5nIGluc3RydWN0aW9ucyBjb25zaXN0IG9mIGEKLSAgICAgKiB0YXJnZXQgbmFtZSBhbmQsIG9wdGlvbmFsbHksIHRleHQgZGF0YS4gVGhlIGRhdGEgaXMgb25seSBtZWFuaW5nZnVsCi0gICAgICogdG8gdGhlIGFwcGxpY2F0aW9uLgotICAgICAqIDxwPgotICAgICAqIFR5cGljYWxseSwgYSBwcm9jZXNzaW5nIGluc3RydWN0aW9uJ3MgZGF0YSB3aWxsIGNvbnRhaW4gYSBzZXJpZXMKLSAgICAgKiBvZiBwc2V1ZG8tYXR0cmlidXRlcy4gVGhlc2UgcHNldWRvLWF0dHJpYnV0ZXMgZm9sbG93IHRoZSBmb3JtIG9mCi0gICAgICogZWxlbWVudCBhdHRyaWJ1dGVzIGJ1dCBhcmUgPHN0cm9uZz5ub3Q8L3N0cm9uZz4gcGFyc2VkIG9yIHByZXNlbnRlZAotICAgICAqIHRvIHRoZSBhcHBsaWNhdGlvbiBhcyBhbnl0aGluZyBvdGhlciB0aGFuIHRleHQuIFRoZSBhcHBsaWNhdGlvbiBpcwotICAgICAqIHJlc3BvbnNpYmxlIGZvciBwYXJzaW5nIHRoZSBkYXRhLgotICAgICAqCi0gICAgICogQHBhcmFtIHRhcmdldCBUaGUgdGFyZ2V0LgotICAgICAqIEBwYXJhbSBkYXRhICAgVGhlIGRhdGEgb3IgbnVsbCBpZiBub25lIHNwZWNpZmllZC4KLSAgICAgKiBAcGFyYW0gYXVncyAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKgotICAgICAqIEBleGNlcHRpb24gWE5JRXhjZXB0aW9uCi0gICAgICogICAgICAgICAgICAgICAgICAgVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHByb2Nlc3NpbmdJbnN0cnVjdGlvbihTdHJpbmcgdGFyZ2V0LCBYTUxTdHJpbmcgZGF0YSwgQXVnbWVudGF0aW9ucyBhdWdzKQotICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uewotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoZSBzdGFydCBvZiBhbiBlbGVtZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIGVsZW1lbnQgICAgVGhlIG5hbWUgb2YgdGhlIGVsZW1lbnQuCi0gICAgICogQHBhcmFtIGF0dHJpYnV0ZXMgVGhlIGVsZW1lbnQgYXR0cmlidXRlcy4KLSAgICAgKiBAcGFyYW0gYXVncyAgICAgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIFhOSUV4Y2VwdGlvbgotICAgICAqICAgICAgICAgICAgICAgICAgIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICAgICAgcHVibGljIHZvaWQgc3RhcnRFbGVtZW50KFFOYW1lIGVsZW1lbnQsIFhNTEF0dHJpYnV0ZXMgYXR0cmlidXRlcywgQXVnbWVudGF0aW9ucyBhdWdzKQotICAgICAgICAgICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICAgICAgICAgIEVsZW1lbnQgY3VycmVudEVsZW1lbnQgPSAoRWxlbWVudCkgZkN1cnJlbnROb2RlOwotICAgICAgICAgICAgICAgIGludCBhdHRyQ291bnQgPSBhdHRyaWJ1dGVzLmdldExlbmd0aCgpOwotICAgICAgICBpZiAoREVCVUdfRVZFTlRTKSB7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIj09PnN0YXJ0RWxlbWVudDogIiArZWxlbWVudCsKLSAgICAgICAgICAgICIgYXR0cnMubGVuZ3RoPSIrYXR0ckNvdW50KTsKLSAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhdHRyQ291bnQ7IGkrKykgewotICAgICAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlcy5nZXROYW1lKGksIGZBdHRyUU5hbWUpOwotICAgICAgICAgICAgICAgICAgICAgICAgQXR0ciBhdHRyID0gbnVsbDsKLQotICAgICAgICAgICAgICAgICAgICAgICAgYXR0ciA9IGN1cnJlbnRFbGVtZW50LmdldEF0dHJpYnV0ZU5vZGVOUyhmQXR0clFOYW1lLnVyaSwgZkF0dHJRTmFtZS5sb2NhbHBhcnQpOwotICAgICAgICAgICAgQXR0cmlidXRlUFNWSSBhdHRyUFNWSSA9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChBdHRyaWJ1dGVQU1ZJKSBhdHRyaWJ1dGVzLmdldEF1Z21lbnRhdGlvbnMoaSkuZ2V0SXRlbShDb25zdGFudHMuQVRUUklCVVRFX1BTVkkpOwotCi0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXR0clBTVkkgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIC8vUkVWSVNJVDogaW5zdGVhZCB3ZSBzaG91bGQgYmUgdXNpbmcgYXVnbWVudGF0aW9uczoKLSAgICAgICAgICAgICAgICAvLyB0byBzZXQvcmV0cmlldmUgSWQgYXR0cmlidXRlcwotICAgICAgICAgICAgICAgIFhTVHlwZURlZmluaXRpb24gZGVjbCA9IGF0dHJQU1ZJLmdldE1lbWJlclR5cGVEZWZpbml0aW9uKCk7Ci0gICAgICAgICAgICAgICAgYm9vbGVhbiBpZCA9IGZhbHNlOwotICAgICAgICAgICAgICAgIGlmIChkZWNsICE9IG51bGwpewotICAgICAgICAgICAgICAgICAgICBpZCA9ICgoWFNTaW1wbGVUeXBlKWRlY2wpLmlzSURUeXBlKCk7Ci0gICAgICAgICAgICAgICAgfSBlbHNlewotICAgICAgICAgICAgICAgICAgICBkZWNsID0gYXR0clBTVkkuZ2V0VHlwZURlZmluaXRpb24oKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGRlY2wgIT1udWxsKXsKLSAgICAgICAgICAgICAgICAgICAgICAgaWQgPSAoKFhTU2ltcGxlVHlwZSlkZWNsKS5pc0lEVHlwZSgpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGlmIChpZCl7Ci0gICAgICAgICAgICAgICAgICAgICgoRWxlbWVudEltcGwpY3VycmVudEVsZW1lbnQpLnNldElkQXR0cmlidXRlTm9kZShhdHRyLCB0cnVlKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZQU1ZJKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKChQU1ZJQXR0ck5TSW1wbCkgYXR0cikuc2V0UFNWSShhdHRyUFNWSSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChmQ29uZmlndXJhdGlvbi5mZWF0dXJlcyAmIERPTUNvbmZpZ3VyYXRpb25JbXBsLkRUTk9STUFMSVpBVElPTikgIT0gMCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGRhdGF0eXBlLW5vcm1hbGl6YXRpb24KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBOT1RFOiBUaGUgc3BlY2lmaWVkIHZhbHVlIE1VU1QgYmUgc2V0IGFmdGVyIHdlIHNldAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgICAgIHRoZSBub2RlIHZhbHVlIGJlY2F1c2UgdGhhdCB0dXJucyB0aGUgInNwZWNpZmllZCIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgICAgICBmbGFnIHRvICJ0cnVlIiB3aGljaCBtYXkgb3ZlcndyaXRlIGEgImZhbHNlIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgICAgIHZhbHVlIGZyb20gdGhlIGF0dHJpYnV0ZSBsaXN0LgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gc3BlY2lmaWVkID0gYXR0ci5nZXRTcGVjaWZpZWQoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyLnNldFZhbHVlKGF0dHJQU1ZJLmdldFNjaGVtYU5vcm1hbGl6ZWRWYWx1ZSgpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXNwZWNpZmllZCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKChBdHRySW1wbCkgYXR0cikuc2V0U3BlY2lmaWVkKHNwZWNpZmllZCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIEFuIGVtcHR5IGVsZW1lbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZWxlbWVudCAgICBUaGUgbmFtZSBvZiB0aGUgZWxlbWVudC4KLSAgICAgKiBAcGFyYW0gYXR0cmlidXRlcyBUaGUgZWxlbWVudCBhdHRyaWJ1dGVzLgotICAgICAqIEBwYXJhbSBhdWdzICAgICAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKgotICAgICAqIEBleGNlcHRpb24gWE5JRXhjZXB0aW9uCi0gICAgICogICAgICAgICAgICAgICAgICAgVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgICAgICBwdWJsaWMgdm9pZCBlbXB0eUVsZW1lbnQoUU5hbWUgZWxlbWVudCwgWE1MQXR0cmlidXRlcyBhdHRyaWJ1dGVzLCBBdWdtZW50YXRpb25zIGF1Z3MpCi0gICAgICAgICAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChERUJVR19FVkVOVFMpIHsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiPT0+ZW1wdHlFbGVtZW50OiAiICtlbGVtZW50KTsKLSAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgc3RhcnRFbGVtZW50KGVsZW1lbnQsIGF0dHJpYnV0ZXMsIGF1Z3MpOwotICAgICAgICBlbmRFbGVtZW50KGVsZW1lbnQsIGF1Z3MpOwotICAgICAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBub3RpZmllcyB0aGUgc3RhcnQgb2YgYSBnZW5lcmFsIGVudGl0eS4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoaXMgbWV0aG9kIGlzIG5vdCBjYWxsZWQgZm9yIGVudGl0eSByZWZlcmVuY2VzCi0gICAgICogYXBwZWFyaW5nIGFzIHBhcnQgb2YgYXR0cmlidXRlIHZhbHVlcy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lICAgICBUaGUgbmFtZSBvZiB0aGUgZ2VuZXJhbCBlbnRpdHkuCi0gICAgICogQHBhcmFtIGlkZW50aWZpZXIgVGhlIHJlc291cmNlIGlkZW50aWZpZXIuCi0gICAgICogQHBhcmFtIGVuY29kaW5nIFRoZSBhdXRvLWRldGVjdGVkIElBTkEgZW5jb2RpbmcgbmFtZSBvZiB0aGUgZW50aXR5Ci0gICAgICogICAgICAgICAgICAgICAgIHN0cmVhbS4gVGhpcyB2YWx1ZSB3aWxsIGJlIG51bGwgaW4gdGhvc2Ugc2l0dWF0aW9ucwotICAgICAqICAgICAgICAgICAgICAgICB3aGVyZSB0aGUgZW50aXR5IGVuY29kaW5nIGlzIG5vdCBhdXRvLWRldGVjdGVkIChlLmcuCi0gICAgICogICAgICAgICAgICAgICAgIGludGVybmFsIGVudGl0aWVzIG9yIGEgZG9jdW1lbnQgZW50aXR5IHRoYXQgaXMKLSAgICAgKiAgICAgICAgICAgICAgICAgcGFyc2VkIGZyb20gYSBqYXZhLmlvLlJlYWRlcikuCi0gICAgICogQHBhcmFtIGF1Z3MgICAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKgotICAgICAqIEBleGNlcHRpb24gWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydEdlbmVyYWxFbnRpdHkoU3RyaW5nIG5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTFJlc291cmNlSWRlbnRpZmllciBpZGVudGlmaWVyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgZW5jb2RpbmcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbnsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBOb3RpZmllcyBvZiB0aGUgcHJlc2VuY2Ugb2YgYSBUZXh0RGVjbCBsaW5lIGluIGFuIGVudGl0eS4gSWYgcHJlc2VudCwKLSAgICAgKiB0aGlzIG1ldGhvZCB3aWxsIGJlIGNhbGxlZCBpbW1lZGlhdGVseSBmb2xsb3dpbmcgdGhlIHN0YXJ0RW50aXR5IGNhbGwuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGlzIG1ldGhvZCB3aWxsIG5ldmVyIGJlIGNhbGxlZCBmb3IgdGhlCi0gICAgICogZG9jdW1lbnQgZW50aXR5OyBpdCBpcyBvbmx5IGNhbGxlZCBmb3IgZXh0ZXJuYWwgZ2VuZXJhbCBlbnRpdGllcwotICAgICAqIHJlZmVyZW5jZWQgaW4gZG9jdW1lbnQgY29udGVudC4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoaXMgbWV0aG9kIGlzIG5vdCBjYWxsZWQgZm9yIGVudGl0eSByZWZlcmVuY2VzCi0gICAgICogYXBwZWFyaW5nIGFzIHBhcnQgb2YgYXR0cmlidXRlIHZhbHVlcy4KLSAgICAgKgotICAgICAqIEBwYXJhbSB2ZXJzaW9uICBUaGUgWE1MIHZlcnNpb24sIG9yIG51bGwgaWYgbm90IHNwZWNpZmllZC4KLSAgICAgKiBAcGFyYW0gZW5jb2RpbmcgVGhlIElBTkEgZW5jb2RpbmcgbmFtZSBvZiB0aGUgZW50aXR5LgotICAgICAqIEBwYXJhbSBhdWdzICAgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIFhOSUV4Y2VwdGlvbgotICAgICAqICAgICAgICAgICAgICAgICAgIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0ZXh0RGVjbChTdHJpbmcgdmVyc2lvbiwgU3RyaW5nIGVuY29kaW5nLCBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb257Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2Qgbm90aWZpZXMgdGhlIGVuZCBvZiBhIGdlbmVyYWwgZW50aXR5LgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gVGhpcyBtZXRob2QgaXMgbm90IGNhbGxlZCBmb3IgZW50aXR5IHJlZmVyZW5jZXMKLSAgICAgKiBhcHBlYXJpbmcgYXMgcGFydCBvZiBhdHRyaWJ1dGUgdmFsdWVzLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgICBUaGUgbmFtZSBvZiB0aGUgZW50aXR5LgotICAgICAqIEBwYXJhbSBhdWdzICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBYTklFeGNlcHRpb24KLSAgICAgKiAgICAgICAgICAgICAgICAgICBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kR2VuZXJhbEVudGl0eShTdHJpbmcgbmFtZSwgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uewotICAgIH0KLQotICAgIC8qKgotICAgICAqIENoYXJhY3RlciBjb250ZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIHRleHQgICBUaGUgY29udGVudC4KLSAgICAgKiBAcGFyYW0gYXVncyAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKgotICAgICAqIEBleGNlcHRpb24gWE5JRXhjZXB0aW9uCi0gICAgICogICAgICAgICAgICAgICAgICAgVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGNoYXJhY3RlcnMoWE1MU3RyaW5nIHRleHQsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbnsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJZ25vcmFibGUgd2hpdGVzcGFjZS4gRm9yIHRoaXMgbWV0aG9kIHRvIGJlIGNhbGxlZCwgdGhlIGRvY3VtZW50Ci0gICAgICogc291cmNlIG11c3QgaGF2ZSBzb21lIHdheSBvZiBkZXRlcm1pbmluZyB0aGF0IHRoZSB0ZXh0IGNvbnRhaW5pbmcKLSAgICAgKiBvbmx5IHdoaXRlc3BhY2UgY2hhcmFjdGVycyBzaG91bGQgYmUgY29uc2lkZXJlZCBpZ25vcmFibGUuIEZvcgotICAgICAqIGV4YW1wbGUsIHRoZSB2YWxpZGF0b3IgY2FuIGRldGVybWluZSBpZiBhIGxlbmd0aCBvZiB3aGl0ZXNwYWNlCi0gICAgICogY2hhcmFjdGVycyBpbiB0aGUgZG9jdW1lbnQgYXJlIGlnbm9yYWJsZSBiYXNlZCBvbiB0aGUgZWxlbWVudAotICAgICAqIGNvbnRlbnQgbW9kZWwuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdGV4dCAgIFRoZSBpZ25vcmFibGUgd2hpdGVzcGFjZS4KLSAgICAgKiBAcGFyYW0gYXVncyAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKgotICAgICAqIEBleGNlcHRpb24gWE5JRXhjZXB0aW9uCi0gICAgICogICAgICAgICAgICAgICAgICAgVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGlnbm9yYWJsZVdoaXRlc3BhY2UoWE1MU3RyaW5nIHRleHQsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbnsKLSAgICAgICAgYWxsV2hpdGVzcGFjZSA9IHRydWU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhlIGVuZCBvZiBhbiBlbGVtZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIGVsZW1lbnQgVGhlIG5hbWUgb2YgdGhlIGVsZW1lbnQuCi0gICAgICogQHBhcmFtIGF1Z3MgICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBYTklFeGNlcHRpb24KLSAgICAgKiAgICAgICAgICAgICAgICAgICBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgICAgIHB1YmxpYyB2b2lkIGVuZEVsZW1lbnQoUU5hbWUgZWxlbWVudCwgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgICAgICAgICBpZiAoREVCVUdfRVZFTlRTKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIj09PmVuZEVsZW1lbnQ6ICIgKyBlbGVtZW50KTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgaWYoYXVncyAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgRWxlbWVudFBTVkkgZWxlbWVudFBTVkkgPSAoRWxlbWVudFBTVkkpIGF1Z3MuZ2V0SXRlbShDb25zdGFudHMuRUxFTUVOVF9QU1ZJKTsKLSAgICAgICAgICAgICAgICBpZiAoZWxlbWVudFBTVkkgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgRWxlbWVudEltcGwgZWxlbWVudE5vZGUgPSAoRWxlbWVudEltcGwpIGZDdXJyZW50Tm9kZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmUFNWSSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKFBTVklFbGVtZW50TlNJbXBsKSBmQ3VycmVudE5vZGUpLnNldFBTVkkoZWxlbWVudFBTVkkpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gaW5jbHVkZSBlbGVtZW50IGRlZmF1bHQgY29udGVudCAoaWYgb25lIGlzIGF2YWlsYWJsZSkKLSAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBub3JtYWxpemVkVmFsdWUgPSBlbGVtZW50UFNWSS5nZXRTY2hlbWFOb3JtYWxpemVkVmFsdWUoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoZkNvbmZpZ3VyYXRpb24uZmVhdHVyZXMgJiBET01Db25maWd1cmF0aW9uSW1wbC5EVE5PUk1BTElaQVRJT04pICE9IDApIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKG5vcm1hbGl6ZWRWYWx1ZSAhPW51bGwpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50Tm9kZS5zZXRUZXh0Q29udGVudChub3JtYWxpemVkVmFsdWUpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5PVEU6IHRoaXMgaXMgYSBoYWNrOiBpdCBpcyBwb3NzaWJsZSB0aGF0IERPTSBoYWQgYW4gZW1wdHkgZWxlbWVudAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBhbmQgdmFsaWRhdG9yIHNlbnQgZGVmYXVsdCB2YWx1ZSB1c2luZyBjaGFyYWN0ZXJzKCksIHdoaWNoIHdlIGRvbid0Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGltcGxlbWVudC4gVGh1cywgaGVyZSB3ZSBhdHRlbXB0IHRvIGFkZCB0aGUgZGVmYXVsdCB2YWx1ZS4KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHRleHQgPSBlbGVtZW50Tm9kZS5nZXRUZXh0Q29udGVudCgpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGV4dC5sZW5ndGgoKSA9PSAwKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZGVmYXVsdCBjb250ZW50IGNvdWxkIGJlIHByb3ZpZGVkCi0gICAgICAgICAgICAgICAgICAgICAgICBpZiAobm9ybWFsaXplZFZhbHVlICE9bnVsbCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50Tm9kZS5zZXRUZXh0Q29udGVudChub3JtYWxpemVkVmFsdWUpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogVGhlIHN0YXJ0IG9mIGEgQ0RBVEEgc2VjdGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBhdWdzICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBYTklFeGNlcHRpb24KLSAgICAgKiAgICAgICAgICAgICAgICAgICBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnRDREFUQShBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb257Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhlIGVuZCBvZiBhIENEQVRBIHNlY3Rpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYXVncyAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKgotICAgICAqIEBleGNlcHRpb24gWE5JRXhjZXB0aW9uCi0gICAgICogICAgICAgICAgICAgICAgICAgVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZENEQVRBKEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbnsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgZW5kIG9mIHRoZSBkb2N1bWVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBhdWdzICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBYTklFeGNlcHRpb24KLSAgICAgKiAgICAgICAgICAgICAgICAgICBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kRG9jdW1lbnQoQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uewotICAgIH0KLQotCi0gICAgLyoqIFNldHMgdGhlIGRvY3VtZW50IHNvdXJjZS4gKi8KLSAgICBwdWJsaWMgdm9pZCBzZXREb2N1bWVudFNvdXJjZShYTUxEb2N1bWVudFNvdXJjZSBzb3VyY2UpewotICAgIH0KLQotCi0gICAgLyoqIFJldHVybnMgdGhlIGRvY3VtZW50IHNvdXJjZS4gKi8KLSAgICBwdWJsaWMgWE1MRG9jdW1lbnRTb3VyY2UgZ2V0RG9jdW1lbnRTb3VyY2UoKXsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi19ICAvLyBET01Ob3JtYWxpemVyIGNsYXNzCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vRE9NT3V0cHV0SW1wbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL0RPTU91dHB1dEltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYzkyNDkxNi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vRE9NT3V0cHV0SW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTczICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEsIDIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5kb207Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5scy5MU091dHB1dDsKLQotaW1wb3J0IGphdmEuaW8uV3JpdGVyOwotaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgcmVwcmVzZW50cyBhbiBvdXRwdXQgZGVzdGluYXRpb24gZm9yIGRhdGEuCi0gKiBUaGlzIGludGVyZmFjZSBhbGxvd3MgYW4gYXBwbGljYXRpb24gdG8gZW5jYXBzdWxhdGUgaW5mb3JtYXRpb24gYWJvdXQgYW4KLSAqIG91dHB1dCBkZXN0aW5hdGlvbiBpbiBhIHNpbmdsZSBvYmplY3QsIHdoaWNoIG1heSBpbmNsdWRlIGEgVVJJLCBhIGJ5dGUgc3RyZWFtCi0gKiAocG9zc2libHkgd2l0aCBhIHNwZWNpZmllZGVuY29kaW5nKSwgYSBiYXNlIFVSSSwgYW5kL29yIGEgY2hhcmFjdGVyIHN0cmVhbS4KLSAqIFRoZSBleGFjdCBkZWZpbml0aW9ucyBvZiBhIGJ5dGUgc3RyZWFtIGFuZCBhIGNoYXJhY3RlciBzdHJlYW0gYXJlIGJpbmRpbmcKLSAqIGRlcGVuZGVudC4KLSAqIFRoZSBhcHBsaWNhdGlvbiBpcyBleHBlY3RlZCB0byBwcm92aWRlIG9iamVjdHMgdGhhdCBpbXBsZW1lbnQgdGhpcyBpbnRlcmZhY2UKLSAqIHdoZW5ldmVyIHN1Y2ggb2JqZWN0cyBhcmUgbmVlZGVkLiBUaGUgYXBwbGljYXRpb24gY2FuIGVpdGhlciBwcm92aWRlIGl0cwotICogb3duIG9iamVjdHMgdGhhdCBpbXBsZW1lbnQgdGhpcyBpbnRlcmZhY2UsIG9yIGl0IGNhbiB1c2UgdGhlIGdlbmVyaWMgZmFjdG9yeQotICogbWV0aG9kIERPTUltcGxlbWVudGF0aW9uTFMuY3JlYXRlTFNPdXRwdXQoKSB0byBjcmVhdGUgb2JqZWN0cyB0aGF0Ci0gKiBpbXBsZW1lbnQgdGhpcyBpbnRlcmZhY2UuCi0gKiBUaGUgRE9NU2VyaWFsaXplciB3aWxsIHVzZSB0aGUgTFNPdXRwdXQgb2JqZWN0IHRvIGRldGVybWluZSB3aGVyZSB0bwotICogc2VyaWFsaXplIHRoZSBvdXRwdXQgdG8uIFRoZSBET01TZXJpYWxpemVyIHdpbGwgbG9vayBhdCB0aGUgZGlmZmVyZW50Ci0gKiBvdXRwdXRzIHNwZWNpZmllZCBpbiB0aGUgTFNPdXRwdXQgaW4gdGhlIGZvbGxvd2luZyBvcmRlciB0byBrbm93IHdoaWNoIG9uZQotICogdG8gb3V0cHV0IHRvLCB0aGUgZmlyc3Qgb25lIHRoYXQgZGF0YSBjYW4gYmUgb3V0cHV0IHRvIHdpbGwgYmUgdXNlZDoKLSAqIDEuTFNPdXRwdXQuY2hhcmFjdGVyU3RyZWFtCi0gKiAyLkxTT3V0cHV0LmJ5dGVTdHJlYW0KLSAqIDMuTFNPdXRwdXQuc3lzdGVtSWQKLSAqIExTT3V0cHV0IG9iamVjdHMgYmVsb25nIHRvIHRoZSBhcHBsaWNhdGlvbi4gVGhlIERPTSBpbXBsZW1lbnRhdGlvbiB3aWxsCi0gKiBuZXZlciBtb2RpZnkgdGhlbSAodGhvdWdoIGl0IG1heSBtYWtlIGNvcGllcyBhbmQgbW9kaWZ5IHRoZSBjb3BpZXMsCi0gKiBpZiBuZWNlc3NhcnkpLgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIEFydW4gWWFkYXYsIFN1biBNaWNyb3N5dGVtcwotICogQGF1dGhvciBHb3BhbCBTaGFybWEsIFN1biBNaWNyb3N5c3RlbXMKLSAqKi8KLQotcHVibGljIGNsYXNzIERPTU91dHB1dEltcGwgaW1wbGVtZW50cyBMU091dHB1dCB7Ci0KLSAgICAgICAgcHJvdGVjdGVkIFdyaXRlciBmQ2hhclN0cmVhbSA9IG51bGw7Ci0gICAgICAgIHByb3RlY3RlZCBPdXRwdXRTdHJlYW0gZkJ5dGVTdHJlYW0gPSBudWxsOwotICAgICAgICBwcm90ZWN0ZWQgU3RyaW5nIGZTeXN0ZW1JZCA9IG51bGw7Ci0gICAgICAgIHByb3RlY3RlZCBTdHJpbmcgZkVuY29kaW5nID0gbnVsbDsKLQotICAgLyoqCi0gICAgKiBEZWZhdWx0IENvbnN0cnVjdG9yCi0gICAgKi8KLSAgICBwdWJsaWMgRE9NT3V0cHV0SW1wbCgpIHt9Ci0KLSAgIC8qKgotICAgICogQW4gYXR0cmlidXRlIG9mIGEgbGFuZ3VhZ2UgYW5kIGJpbmRpbmcgZGVwZW5kZW50IHR5cGUgdGhhdCByZXByZXNlbnRzIGEKLSAgICAqIHdyaXRhYmxlIHN0cmVhbSBvZiBieXRlcy4gSWYgdGhlIGFwcGxpY2F0aW9uIGtub3dzIHRoZSBjaGFyYWN0ZXIgZW5jb2RpbmcKLSAgICAqIG9mIHRoZSBieXRlIHN0cmVhbSwgaXQgc2hvdWxkIHNldCB0aGUgZW5jb2RpbmcgYXR0cmlidXRlLiBTZXR0aW5nIHRoZQotICAgICogZW5jb2RpbmcgaW4gdGhpcyB3YXkgd2lsbCBvdmVycmlkZSBhbnkgZW5jb2Rpbmcgc3BlY2lmaWVkIGluIGFuIFhNTAotICAgICogZGVjbGFyYXRpb24gaW4gdGhlIGRhdGEuCi0gICAgKi8KLQotICAgIHB1YmxpYyBXcml0ZXIgZ2V0Q2hhcmFjdGVyU3RyZWFtKCl7Ci0gICAgICAgIHJldHVybiBmQ2hhclN0cmVhbTsKLSAgICAgfTsKLQotICAgLyoqCi0gICAgKiBBbiBhdHRyaWJ1dGUgb2YgYSBsYW5ndWFnZSBhbmQgYmluZGluZyBkZXBlbmRlbnQgdHlwZSB0aGF0IHJlcHJlc2VudHMgYQotICAgICogd3JpdGFibGUgc3RyZWFtIG9mIGJ5dGVzLiBJZiB0aGUgYXBwbGljYXRpb24ga25vd3MgdGhlIGNoYXJhY3RlciBlbmNvZGluZwotICAgICogb2YgdGhlIGJ5dGUgc3RyZWFtLCBpdCBzaG91bGQgc2V0IHRoZSBlbmNvZGluZyBhdHRyaWJ1dGUuIFNldHRpbmcgdGhlCi0gICAgKiBlbmNvZGluZyBpbiB0aGlzIHdheSB3aWxsIG92ZXJyaWRlIGFueSBlbmNvZGluZyBzcGVjaWZpZWQgaW4gYW4gWE1MCi0gICAgKiBkZWNsYXJhdGlvbiBpbiB0aGUgZGF0YS4KLSAgICAqLwotCi0gICAgcHVibGljIHZvaWQgc2V0Q2hhcmFjdGVyU3RyZWFtKFdyaXRlciBjaGFyYWN0ZXJTdHJlYW0pewotICAgICAgICBmQ2hhclN0cmVhbSA9IGNoYXJhY3RlclN0cmVhbTsKLSAgICB9OwotCi0gICAvKioKLSAgICAqIERlcGVuZGluZyBvbiB0aGUgbGFuZ3VhZ2UgYmluZGluZyBpbiB1c2UsIHRoaXMgYXR0cmlidXRlIG1heSBub3QgYmUKLSAgICAqIGF2YWlsYWJsZS4gQW4gYXR0cmlidXRlIG9mIGEgbGFuZ3VhZ2UgYW5kIGJpbmRpbmcgZGVwZW5kZW50IHR5cGUgdGhhdAotICAgICogcmVwcmVzZW50cyBhIHdyaXRhYmxlIHN0cmVhbSB0byB3aGljaCAxNi1iaXQgdW5pdHMgY2FuIGJlIG91dHB1dC4gVGhlCi0gICAgKiBhcHBsaWNhdGlvbiBtdXN0IGVuY29kZSB0aGUgc3RyZWFtIHVzaW5nIFVURi0xNiAoZGVmaW5lZCBpbiBbVW5pY29kZV0gYW5kCi0gICAgKiAgQW1lbmRtZW50IDEgb2YgW0lTTy9JRUMgMTA2NDZdKS4KLSAgICAqLwotCi0gICAgcHVibGljIE91dHB1dFN0cmVhbSBnZXRCeXRlU3RyZWFtKCl7Ci0gICAgICAgIHJldHVybiBmQnl0ZVN0cmVhbTsKLSAgICB9OwotCi0gICAvKioKLSAgICAqIERlcGVuZGluZyBvbiB0aGUgbGFuZ3VhZ2UgYmluZGluZyBpbiB1c2UsIHRoaXMgYXR0cmlidXRlIG1heSBub3QgYmUKLSAgICAqIGF2YWlsYWJsZS4gQW4gYXR0cmlidXRlIG9mIGEgbGFuZ3VhZ2UgYW5kIGJpbmRpbmcgZGVwZW5kZW50IHR5cGUgdGhhdAotICAgICogcmVwcmVzZW50cyBhIHdyaXRhYmxlIHN0cmVhbSB0byB3aGljaCAxNi1iaXQgdW5pdHMgY2FuIGJlIG91dHB1dC4gVGhlCi0gICAgKiBhcHBsaWNhdGlvbiBtdXN0IGVuY29kZSB0aGUgc3RyZWFtIHVzaW5nIFVURi0xNiAoZGVmaW5lZCBpbiBbVW5pY29kZV0gYW5kCi0gICAgKiAgQW1lbmRtZW50IDEgb2YgW0lTTy9JRUMgMTA2NDZdKS4KLSAgICAqLwotCi0gICAgcHVibGljIHZvaWQgc2V0Qnl0ZVN0cmVhbShPdXRwdXRTdHJlYW0gYnl0ZVN0cmVhbSl7Ci0gICAgICAgIGZCeXRlU3RyZWFtID0gYnl0ZVN0cmVhbTsKLSAgICB9OwotCi0gICAvKioKLSAgICAqIFRoZSBzeXN0ZW0gaWRlbnRpZmllciwgYSBVUkkgcmVmZXJlbmNlIFtJRVRGIFJGQyAyMzk2XSwgZm9yIHRoaXMgb3V0cHV0Ci0gICAgKiAgZGVzdGluYXRpb24uIElmIHRoZSBhcHBsaWNhdGlvbiBrbm93cyB0aGUgY2hhcmFjdGVyIGVuY29kaW5nIG9mIHRoZQotICAgICogIG9iamVjdCBwb2ludGVkIHRvIGJ5IHRoZSBzeXN0ZW0gaWRlbnRpZmllciwgaXQgY2FuIHNldCB0aGUgZW5jb2RpbmcKLSAgICAqICB1c2luZyB0aGUgZW5jb2RpbmcgYXR0cmlidXRlLiBJZiB0aGUgc3lzdGVtIElEIGlzIGEgcmVsYXRpdmUgVVJJCi0gICAgKiAgcmVmZXJlbmNlIChzZWUgc2VjdGlvbiA1IGluIFtJRVRGIFJGQyAyMzk2XSksIHRoZSBiZWhhdmlvciBpcwotICAgICogIGltcGxlbWVudGF0aW9uIGRlcGVuZGVudC4KLSAgICAqLwotCi0gICAgcHVibGljIFN0cmluZyBnZXRTeXN0ZW1JZCgpewotICAgICAgICByZXR1cm4gZlN5c3RlbUlkOwotICAgIH07Ci0KLSAgIC8qKgotICAgICogVGhlIHN5c3RlbSBpZGVudGlmaWVyLCBhIFVSSSByZWZlcmVuY2UgW0lFVEYgUkZDIDIzOTZdLCBmb3IgdGhpcyBvdXRwdXQKLSAgICAqICBkZXN0aW5hdGlvbi4gSWYgdGhlIGFwcGxpY2F0aW9uIGtub3dzIHRoZSBjaGFyYWN0ZXIgZW5jb2Rpbmcgb2YgdGhlCi0gICAgKiAgb2JqZWN0IHBvaW50ZWQgdG8gYnkgdGhlIHN5c3RlbSBpZGVudGlmaWVyLCBpdCBjYW4gc2V0IHRoZSBlbmNvZGluZwotICAgICogIHVzaW5nIHRoZSBlbmNvZGluZyBhdHRyaWJ1dGUuIElmIHRoZSBzeXN0ZW0gSUQgaXMgYSByZWxhdGl2ZSBVUkkKLSAgICAqICByZWZlcmVuY2UgKHNlZSBzZWN0aW9uIDUgaW4gW0lFVEYgUkZDIDIzOTZdKSwgdGhlIGJlaGF2aW9yIGlzCi0gICAgKiAgaW1wbGVtZW50YXRpb24gZGVwZW5kZW50LgotICAgICovCi0KLSAgICBwdWJsaWMgdm9pZCBzZXRTeXN0ZW1JZChTdHJpbmcgc3lzdGVtSWQpewotICAgICAgICBmU3lzdGVtSWQgPSBzeXN0ZW1JZDsKLSAgICB9OwotCi0gICAvKioKLSAgICAqIFRoZSBjaGFyYWN0ZXIgZW5jb2RpbmcsIGlmIGtub3duLiBUaGUgZW5jb2RpbmcgbXVzdCBiZSBhIHN0cmluZwotICAgICogYWNjZXB0YWJsZSBmb3IgYW4gWE1MIGVuY29kaW5nIGRlY2xhcmF0aW9uIChbWE1MIDEuMF0gc2VjdGlvbiA0LjMuMwotICAgICogIkNoYXJhY3RlciBFbmNvZGluZyBpbiBFbnRpdGllcyIpLiBUaGlzIGF0dHJpYnV0ZSBoYXMgbm8gZWZmZWN0IHdoZW4gdGhlCi0gICAgKiBhcHBsaWNhdGlvbiBwcm92aWRlcyBhIGNoYXJhY3RlciBzdHJlYW0gb3Igc3RyaW5nIGRhdGEuIEZvciBvdGhlciBzb3VyY2VzCi0gICAgKiBvZiBpbnB1dCwgYW4gZW5jb2Rpbmcgc3BlY2lmaWVkIGJ5IG1lYW5zIG9mIHRoaXMgYXR0cmlidXRlIHdpbGwgb3ZlcnJpZGUKLSAgICAqIGFueSBlbmNvZGluZyBzcGVjaWZpZWQgaW4gdGhlIFhNTCBkZWNsYXJhdGlvbiBvciB0aGUgVGV4dCBkZWNsYXJhdGlvbiwgb3IKLSAgICAqIGFuIGVuY29kaW5nIG9idGFpbmVkIGZyb20gYSBoaWdoZXIgbGV2ZWwgcHJvdG9jb2wsIHN1Y2ggYXMgSFRUUAotICAgICogW0lFVEYgUkZDIDI2MTZdLgotICAgICovCi0KLSAgICBwdWJsaWMgU3RyaW5nIGdldEVuY29kaW5nKCl7Ci0gICAgICAgIHJldHVybiBmRW5jb2Rpbmc7Ci0gICAgfTsKLQotICAgLyoqCi0gICAgKiBUaGUgY2hhcmFjdGVyIGVuY29kaW5nLCBpZiBrbm93bi4gVGhlIGVuY29kaW5nIG11c3QgYmUgYSBzdHJpbmcKLSAgICAqIGFjY2VwdGFibGUgZm9yIGFuIFhNTCBlbmNvZGluZyBkZWNsYXJhdGlvbiAoW1hNTCAxLjBdIHNlY3Rpb24gNC4zLjMKLSAgICAqICJDaGFyYWN0ZXIgRW5jb2RpbmcgaW4gRW50aXRpZXMiKS4gVGhpcyBhdHRyaWJ1dGUgaGFzIG5vIGVmZmVjdCB3aGVuIHRoZQotICAgICogYXBwbGljYXRpb24gcHJvdmlkZXMgYSBjaGFyYWN0ZXIgc3RyZWFtIG9yIHN0cmluZyBkYXRhLiBGb3Igb3RoZXIgc291cmNlcwotICAgICogb2YgaW5wdXQsIGFuIGVuY29kaW5nIHNwZWNpZmllZCBieSBtZWFucyBvZiB0aGlzIGF0dHJpYnV0ZSB3aWxsIG92ZXJyaWRlCi0gICAgKiBhbnkgZW5jb2Rpbmcgc3BlY2lmaWVkIGluIHRoZSBYTUwgZGVjbGFyYXRpb24gb3IgdGhlIFRleHQgZGVjbGFyYXRpb24sIG9yCi0gICAgKiBhbiBlbmNvZGluZyBvYnRhaW5lZCBmcm9tIGEgaGlnaGVyIGxldmVsIHByb3RvY29sLCBzdWNoIGFzIEhUVFAKLSAgICAqIFtJRVRGIFJGQyAyNjE2XS4KLSAgICAqLwotCi0gICAgcHVibGljIHZvaWQgc2V0RW5jb2RpbmcoU3RyaW5nIGVuY29kaW5nKXsKLSAgICAgICAgZkVuY29kaW5nID0gZW5jb2Rpbmc7Ci0gICAgfTsKLQotfS8vRE9NT3V0cHV0SW1wbApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL0RPTVN0cmluZ0xpc3RJbXBsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vRE9NU3RyaW5nTGlzdEltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYzVjZTVlYy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vRE9NU3RyaW5nTGlzdEltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDkwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEsIDIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5kb207Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgb3JnLnczYy5kb20uRE9NU3RyaW5nTGlzdDsKLQotLyoqCi0gKiBET00gTGV2ZWwgMwotICoKLSAqIFRoaXMgY2xhc3MgaW1wbGVtZW50cyB0aGUgRE9NIExldmVsIDMgQ29yZSBpbnRlcmZhY2UgRE9NU3RyaW5nTGlzdC4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBOZWlsIERlbGltYSwgSUJNCi0gKi8KLXB1YmxpYyBjbGFzcyBET01TdHJpbmdMaXN0SW1wbCBpbXBsZW1lbnRzIERPTVN0cmluZ0xpc3QgewotCi0gICAgICAgIC8vQSBjb2xsZWN0aW9uIG9mIERPTVN0cmluZyB2YWx1ZXMKLSAgICBwcml2YXRlIFZlY3RvciBmU3RyaW5nczsKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdCBhbiBlbXB0eSBsaXN0IG9mIERPTVN0cmluZ0xpc3RJbXBsCi0gICAgICovCi0gICAgcHVibGljIERPTVN0cmluZ0xpc3RJbXBsKCkgewotICAgICAgICBmU3RyaW5ncyA9IG5ldyBWZWN0b3IoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3QgYW4gZW1wdHkgbGlzdCBvZiBET01TdHJpbmdMaXN0SW1wbAotICAgICAqLwotICAgIHB1YmxpYyBET01TdHJpbmdMaXN0SW1wbChWZWN0b3IgcGFyYW1zKSB7Ci0gICAgICAgIGZTdHJpbmdzID0gcGFyYW1zOwotICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogQHNlZSBvcmcudzNjLmRvbS5ET01TdHJpbmdMaXN0I2l0ZW0oaW50KQotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIFN0cmluZyBpdGVtKGludCBpbmRleCkgewotICAgICAgICB0cnkgewotICAgICAgICAgICAgcmV0dXJuIChTdHJpbmcpIGZTdHJpbmdzLmVsZW1lbnRBdChpbmRleCk7Ci0gICAgICAgIH0gY2F0Y2ggKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIEBzZWUgb3JnLnczYy5kb20uRE9NU3RyaW5nTGlzdCNnZXRMZW5ndGgoKQotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIGludCBnZXRMZW5ndGgoKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZTdHJpbmdzLnNpemUoKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBAc2VlIG9yZy53M2MuZG9tLkRPTVN0cmluZ0xpc3QjY29udGFpbnMoU3RyaW5nKQotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnMoU3RyaW5nIHBhcmFtKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZTdHJpbmdzLmNvbnRhaW5zKHBhcmFtKSA7Ci0gICAgICAgIH0KLQotICAgIC8qKgotICAgICAqIERPTSBJbnRlcm5hbDoKLSAgICAgKiBBZGQgYSA8Y29kZT5ET01TdHJpbmc8L2NvZGU+IHRvIHRoZSBsaXN0LgotICAgICAqCi0gICAgICogQHBhcmFtIGRvbVN0cmluZyBBIHN0cmluZyB0byBhZGQgdG8gdGhlIGxpc3QKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBhZGQoU3RyaW5nIHBhcmFtKSB7Ci0gICAgICAgIGZTdHJpbmdzLmFkZChwYXJhbSk7Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vRE9NWFNJbXBsZW1lbnRhdGlvblNvdXJjZUltcGwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9ET01YU0ltcGxlbWVudGF0aW9uU291cmNlSW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzNGEzMTFhLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9ET01YU0ltcGxlbWVudGF0aW9uU291cmNlSW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTAwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEsIDIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5kb207Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMuWFNJbXBsZW1lbnRhdGlvbkltcGw7Ci1pbXBvcnQgb3JnLnczYy5kb20uRE9NSW1wbGVtZW50YXRpb25MaXN0OwotaW1wb3J0IG9yZy53M2MuZG9tLkRPTUltcGxlbWVudGF0aW9uOwotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLS8qKgotICogQWxsb3dzIHRvIHJldHJpZXZlIDxjb2RlPlhTSW1wbGVtZW50YXRpb248L2NvZGU+LCBET00gTGV2ZWwgMyBDb3JlIGFuZCBMUyBpbXBsZW1lbnRhdGlvbnMKLSAqIGFuZCBQU1ZJIGltcGxlbWVudGF0aW9uLgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLURPTS1MZXZlbC0zLUNvcmUtMjAwNDA0MDcvY29yZS5odG1sI0RPTUltcGxlbWVudGF0aW9uU291cmNlJz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMyBDb3JlIFNwZWNpZmljYXRpb248L2E+LgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIEVsZW5hIExpdGFuaSwgSUJNCi0gKi8KLXB1YmxpYyBjbGFzcyBET01YU0ltcGxlbWVudGF0aW9uU291cmNlSW1wbAotICAgIGV4dGVuZHMgRE9NSW1wbGVtZW50YXRpb25Tb3VyY2VJbXBsIHsKLQotICAgIC8qKgotICAgICAqIEEgbWV0aG9kIHRvIHJlcXVlc3QgYSBET00gaW1wbGVtZW50YXRpb24uCi0gICAgICogQHBhcmFtIGZlYXR1cmVzIEEgc3RyaW5nIHRoYXQgc3BlY2lmaWVzIHdoaWNoIGZlYXR1cmVzIGFyZSByZXF1aXJlZC4KLSAgICAgKiAgIFRoaXMgaXMgYSBzcGFjZSBzZXBhcmF0ZWQgbGlzdCBpbiB3aGljaCBlYWNoIGZlYXR1cmUgaXMgc3BlY2lmaWVkCi0gICAgICogICBieSBpdHMgbmFtZSBvcHRpb25hbGx5IGZvbGxvd2VkIGJ5IGEgc3BhY2UgYW5kIGEgdmVyc2lvbiBudW1iZXIuCi0gICAgICogICBUaGlzIGlzIHNvbWV0aGluZyBsaWtlOiAiWE1MIDEuMCBUcmF2ZXJzYWwgRXZlbnRzIDIuMCIKLSAgICAgKiBAcmV0dXJuIEFuIGltcGxlbWVudGF0aW9uIHRoYXQgaGFzIHRoZSBkZXNpcmVkIGZlYXR1cmVzLCBvcgotICAgICAqICAgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhpcyBzb3VyY2UgaGFzIG5vbmUuCi0gICAgICovCi0gICAgcHVibGljIERPTUltcGxlbWVudGF0aW9uIGdldERPTUltcGxlbWVudGF0aW9uKFN0cmluZyBmZWF0dXJlcykgewotICAgICAgICBET01JbXBsZW1lbnRhdGlvbiBpbXBsID0gc3VwZXIuZ2V0RE9NSW1wbGVtZW50YXRpb24oZmVhdHVyZXMpOwotICAgICAgICBpZiAoaW1wbCAhPSBudWxsKXsKLSAgICAgICAgICAgIHJldHVybiBpbXBsOwotICAgICAgICB9Ci0gICAgICAgIC8vIGlmIG5vdCB0cnkgdGhlIFBTVklET01JbXBsZW1lbnRhdGlvbgotICAgICAgICBpbXBsID0gUFNWSURPTUltcGxlbWVudGF0aW9uSW1wbC5nZXRET01JbXBsZW1lbnRhdGlvbigpOwotICAgICAgICBpZiAodGVzdEltcGwoaW1wbCwgZmVhdHVyZXMpKSB7Ci0gICAgICAgICAgICByZXR1cm4gaW1wbDsKLSAgICAgICAgfQotICAgICAgICAvLyBpZiBub3QgdHJ5IHRoZSBYU0ltcGxlbWVudGF0aW9uCi0gICAgICAgIGltcGwgPSBYU0ltcGxlbWVudGF0aW9uSW1wbC5nZXRET01JbXBsZW1lbnRhdGlvbigpOwotICAgICAgICBpZiAodGVzdEltcGwoaW1wbCwgZmVhdHVyZXMpKSB7Ci0gICAgICAgICAgICByZXR1cm4gaW1wbDsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEEgbWV0aG9kIHRvIHJlcXVlc3QgYSBsaXN0IG9mIERPTSBpbXBsZW1lbnRhdGlvbnMgdGhhdCBzdXBwb3J0IHRoZQotICAgICAqIHNwZWNpZmllZCBmZWF0dXJlcyBhbmQgdmVyc2lvbnMsIGFzIHNwZWNpZmllZCBpbiAuCi0gICAgICogQHBhcmFtIGZlYXR1cmVzIEEgc3RyaW5nIHRoYXQgc3BlY2lmaWVzIHdoaWNoIGZlYXR1cmVzIGFuZCB2ZXJzaW9ucwotICAgICAqICAgYXJlIHJlcXVpcmVkLiBUaGlzIGlzIGEgc3BhY2Ugc2VwYXJhdGVkIGxpc3QgaW4gd2hpY2ggZWFjaCBmZWF0dXJlCi0gICAgICogICBpcyBzcGVjaWZpZWQgYnkgaXRzIG5hbWUgb3B0aW9uYWxseSBmb2xsb3dlZCBieSBhIHNwYWNlIGFuZCBhCi0gICAgICogICB2ZXJzaW9uIG51bWJlci4gVGhpcyBpcyBzb21ldGhpbmcgbGlrZTogIlhNTCAzLjAgVHJhdmVyc2FsICtFdmVudHMKLSAgICAgKiAgIDIuMCIKLSAgICAgKiBAcmV0dXJuIEEgbGlzdCBvZiBET00gaW1wbGVtZW50YXRpb25zIHRoYXQgc3VwcG9ydCB0aGUgZGVzaXJlZAotICAgICAqICAgZmVhdHVyZXMuCi0gICAgICovCi0gICAgcHVibGljIERPTUltcGxlbWVudGF0aW9uTGlzdCBnZXRET01JbXBsZW1lbnRhdGlvbkxpc3QoU3RyaW5nIGZlYXR1cmVzKSB7Ci0gICAgICAgIGZpbmFsIFZlY3RvciBpbXBsZW1lbnRhdGlvbnMgPSBuZXcgVmVjdG9yKCk7Ci0KLSAgICAgICAgLy8gZmlyc3QgY2hlY2sgd2hldGhlciB0aGUgQ29yZURPTUltcGxlbWVudGF0aW9uIHdvdWxkIGRvCi0gICAgICAgIERPTUltcGxlbWVudGF0aW9uTGlzdCBsaXN0ID0gc3VwZXIuZ2V0RE9NSW1wbGVtZW50YXRpb25MaXN0KGZlYXR1cmVzKTsKLSAgICAgICAgLy9BZGQgY29yZSBET01JbXBsZW1lbnRhdGlvbnMKLSAgICAgICAgZm9yIChpbnQgaT0wOyBpIDwgbGlzdC5nZXRMZW5ndGgoKTsgaSsrICkgewotICAgICAgICAgICAgaW1wbGVtZW50YXRpb25zLmFkZEVsZW1lbnQobGlzdC5pdGVtKGkpKTsKLSAgICAgICAgfQotCi0gICAgICAgIERPTUltcGxlbWVudGF0aW9uIGltcGwgPSBQU1ZJRE9NSW1wbGVtZW50YXRpb25JbXBsLmdldERPTUltcGxlbWVudGF0aW9uKCk7Ci0gICAgICAgIGlmICh0ZXN0SW1wbChpbXBsLCBmZWF0dXJlcykpIHsKLSAgICAgICAgICAgIGltcGxlbWVudGF0aW9ucy5hZGRFbGVtZW50KGltcGwpOwotICAgICAgICB9Ci0KLSAgICAgICAgaW1wbCA9IFhTSW1wbGVtZW50YXRpb25JbXBsLmdldERPTUltcGxlbWVudGF0aW9uKCk7Ci0gICAgICAgIGlmICh0ZXN0SW1wbChpbXBsLCBmZWF0dXJlcykpIHsKLSAgICAgICAgICAgIGltcGxlbWVudGF0aW9ucy5hZGRFbGVtZW50KGltcGwpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBuZXcgRE9NSW1wbGVtZW50YXRpb25MaXN0SW1wbChpbXBsZW1lbnRhdGlvbnMpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9EZWVwTm9kZUxpc3RJbXBsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vRGVlcE5vZGVMaXN0SW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxYWNmNjJlLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9EZWVwTm9kZUxpc3RJbXBsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyNDcgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDAyLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tOwotCi1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlTGlzdDsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLS8qKgotICogVGhpcyBjbGFzcyBpbXBsZW1lbnRzIHRoZSBET00ncyBOb2RlTGlzdCBiZWhhdmlvciBmb3IKLSAqIEVsZW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoKQotICogPFA+Ci0gKiBUaGUgRE9NIGRlc2NyaWJlcyBOb2RlTGlzdCBhcyBmb2xsb3dzOgotICogPFA+Ci0gKiAxKSBJdCBtYXkgcmVwcmVzZW50IEVJVEhFUiBub2RlcyBzY2F0dGVyZWQgdGhyb3VnaCBhIHN1YnRyZWUgKHdoZW4KLSAqIHJldHVybmVkIGJ5IEVsZW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUpLCBvciBqdXN0IHRoZSBpbW1lZGlhdGUKLSAqIGNoaWxkcmVuICh3aGVuIHJldHVybmVkIGJ5IE5vZGUuZ2V0Q2hpbGROb2RlcykuIFRoZSBsYXR0ZXIgaXMgZWFzeSwKLSAqIGJ1dCB0aGUgZm9ybWVyICh3aGljaCB0aGlzIGNsYXNzIGFkZHJlc3NlcykgaXMgbW9yZSBjaGFsbGVuZ2luZy4KLSAqIDxQPgotICogMikgSXRzIGJlaGF2aW9yIGlzICJsaXZlIiAtLSB0aGF0IGlzLCBpdCBhbHdheXMgcmVmbGVjdHMgdGhlCi0gKiBjdXJyZW50IHN0YXRlIG9mIHRoZSBkb2N1bWVudCB0cmVlLiBUbyBwdXQgaXQgYW5vdGhlciB3YXksIHRoZQotICogTm9kZUxpc3RzIG9idGFpbmVkIGJlZm9yZSBhbmQgYWZ0ZXIgYSBzZXJpZXMgb2YgaW5zZXJ0aW9ucyBhbmQKLSAqIGRlbGV0aW9ucyBhcmUgZWZmZWN0aXZlbHkgaWRlbnRpY2FsIChhcyBmYXIgYXMgdGhlIHVzZXIgaXMKLSAqIGNvbmNlcm5lZCwgdGhlIGZvcm1lciBoYXMgYmVlbiBkeW5hbWljYWxseSB1cGRhdGVkIGFzIHRoZSBjaGFuZ2VzCi0gKiBoYXZlIGJlZW4gbWFkZSkuCi0gKiA8UD4KLSAqIDMpIEl0cyBBUEkgYWNjZXNzZXMgaW5kaXZpZHVhbCBub2RlcyB2aWEgYW4gaW50ZWdlciBpbmRleCwgd2l0aCB0aGUKLSAqIGxpc3RlZCBub2RlcyBudW1iZXJlZCBzZXF1ZW50aWFsbHkgaW4gdGhlIG9yZGVyIHRoYXQgdGhleSB3ZXJlCi0gKiBmb3VuZCBkdXJpbmcgYSBwcmVvcmRlciBkZXB0aC1maXJzdCBsZWZ0LXRvLXJpZ2h0IHNlYXJjaCBvZiB0aGUgdHJlZS4KLSAqIChPZiBjb3Vyc2UgaW4gdGhlIGNhc2Ugb2YgZ2V0Q2hpbGROb2RlcywgZGVwdGggaXMgbm90IGludm9sdmVkLikgQXMKLSAqIG5vZGVzIGFyZSBpbnNlcnRlZCBvciBkZWxldGVkIGluIHRoZSB0cmVlLCBhbmQgaGVuY2UgdGhlIE5vZGVMaXN0LAotICogdGhlIG51bWJlcmluZyBvZiBub2RlcyB0aGF0IGZvbGxvdyB0aGVtIGluIHRoZSBOb2RlTGlzdCB3aWxsCi0gKiBjaGFuZ2UuCi0gKiA8UD4KLSAqIEl0IGlzIHJhdGhlciBwYWluZnVsIHRvIHN1cHBvcnQgdGhlIGxhdHRlciB0d28gaW4gdGhlCi0gKiBnZXRFbGVtZW50c0J5VGFnTmFtZSBjYXNlLiBUaGUgY3VycmVudCBzb2x1dGlvbiBpcyBmb3IgTm9kZXMgdG8KLSAqIG1haW50YWluIGEgY2hhbmdlIGNvdW50IChldmVudHVhbGx5IHRoYXQgbWF5IGJlIGEgRGlnZXN0IGluc3RlYWQpLAotICogd2hpY2ggdGhlIE5vZGVMaXN0IHRyYWNrcyBhbmQgdXNlcyB0byBpbnZhbGlkYXRlIGl0c2VsZi4KLSAqIDxQPgotICogVW5mb3J0dW5hdGVseSwgdGhpcyBkb2VzIF9ub3RfIHJlc3BvbmQgZWZmaWNpZW50bHkgaW4gdGhlIGNhc2UgdGhhdAotICogdGhlIGR5bmFtaWMgYmVoYXZpb3Igd2FzIHN1cHBvc2VkIHRvIGFkZHJlc3M6IHNjYW5uaW5nIGEgdHJlZSB3aGlsZQotICogaXQgaXMgYmVpbmcgZXh0ZW5kZWQuIFRoYXQgcmVxdWlyZXMga25vd2luZyB3aGljaCBzdWJ0cmVlcyBoYXZlCi0gKiBjaGFuZ2VkLCB3aGljaCBjYW4gYmVjb21lIGFuIGFyYml0cmFyaWx5IGNvbXBsZXggcHJvYmxlbS4KLSAqIDxQPgotICogV2Ugc2F2ZSBzb21lIHdvcmsgYnkgZmlsbGluZyB0aGUgdmVjdG9yIG9ubHkgYXMgd2UgYWNjZXNzIHRoZQotICogaXRlbSgpcy4uLiBidXQgSSBzdXNwZWN0IHRoZSBzYW1lIHVzZXJzIHdobyBkZW1hbmRlZCBpbmRleC1iYXNlZAotICogYWNjZXNzIHdpbGwgYWxzbyBzdGFydCBieSBkb2luZyBhIGdldExlbmd0aCgpIHRvIGNvbnRyb2wgdGhlaXIgbG9vcCwKLSAqIGJsb3dpbmcgdGhpcyBvcHRpbWl6YXRpb24gb3V0IG9mIHRoZSB3YXRlci4KLSAqIDxQPgotICogTk9URTogTGV2ZWwgMiBvZiB0aGUgRE9NIHdpbGwgcHJvYmFibHkgX25vdF8gdXNlIE5vZGVMaXN0IGZvciBpdHMKLSAqIGV4dGVuZGVkIHNlYXJjaCBtZWNoYW5pc21zLCBwYXJ0bHkgZm9yIHRoZSByZWFzb25zIGp1c3QgZGlzY3Vzc2VkLgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAc2luY2UgIFBSLURPTS1MZXZlbC0xLTE5OTgwODE4LgotICovCi1wdWJsaWMgY2xhc3MgRGVlcE5vZGVMaXN0SW1wbAotICAgIGltcGxlbWVudHMgTm9kZUxpc3QgewotCi0gICAgLy8KLSAgICAvLyBEYXRhCi0gICAgLy8KLQotICAgIHByb3RlY3RlZCBOb2RlSW1wbCByb290Tm9kZTsgLy8gV2hlcmUgdGhlIHNlYXJjaCBzdGFydGVkCi0gICAgcHJvdGVjdGVkIFN0cmluZyB0YWdOYW1lOyAgIC8vIE9yICIqIiB0byBtZWFuIGFsbC10YWdzLWFjY2VwdGFibGUKLSAgICBwcm90ZWN0ZWQgaW50IGNoYW5nZXM9MDsKLSAgICBwcm90ZWN0ZWQgVmVjdG9yIG5vZGVzOwotCi0gICAgcHJvdGVjdGVkIFN0cmluZyBuc05hbWU7Ci0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZW5hYmxlTlMgPSBmYWxzZTsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKiBDb25zdHJ1Y3Rvci4gKi8KLSAgICBwdWJsaWMgRGVlcE5vZGVMaXN0SW1wbChOb2RlSW1wbCByb290Tm9kZSwgU3RyaW5nIHRhZ05hbWUpIHsKLSAgICAgICAgdGhpcy5yb290Tm9kZSA9IHJvb3ROb2RlOwotICAgICAgICB0aGlzLnRhZ05hbWUgID0gdGFnTmFtZTsKLSAgICAgICAgbm9kZXMgPSBuZXcgVmVjdG9yKCk7Ci0gICAgfQotCi0gICAgLyoqIENvbnN0cnVjdG9yIGZvciBOYW1lc3BhY2Ugc3VwcG9ydC4gKi8KLSAgICBwdWJsaWMgRGVlcE5vZGVMaXN0SW1wbChOb2RlSW1wbCByb290Tm9kZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbnNOYW1lLCBTdHJpbmcgdGFnTmFtZSkgewotICAgICAgICB0aGlzKHJvb3ROb2RlLCB0YWdOYW1lKTsKLSAgICAgICAgdGhpcy5uc05hbWUgPSAobnNOYW1lICE9IG51bGwgJiYgIW5zTmFtZS5lcXVhbHMoIiIpKSA/IG5zTmFtZSA6IG51bGw7Ci0gICAgICAgIGVuYWJsZU5TID0gdHJ1ZTsKLSAgICB9Ci0KLSAgICAvLwotICAgIC8vIE5vZGVMaXN0IG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqIFJldHVybnMgdGhlIGxlbmd0aCBvZiB0aGUgbm9kZSBsaXN0LiAqLwotICAgIHB1YmxpYyBpbnQgZ2V0TGVuZ3RoKCkgewotICAgICAgICAvLyBQcmVsb2FkIGFsbCBtYXRjaGluZyBlbGVtZW50cy4gKFN0b3BzIHdoZW4gd2UgcnVuIG91dCBvZiBzdWJ0cmVlISkKLSAgICAgICAgaXRlbShqYXZhLmxhbmcuSW50ZWdlci5NQVhfVkFMVUUpOwotICAgICAgICByZXR1cm4gbm9kZXMuc2l6ZSgpOwotICAgIH0KLQotICAgIC8qKiBSZXR1cm5zIHRoZSBub2RlIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXguICovCi0gICAgcHVibGljIE5vZGUgaXRlbShpbnQgaW5kZXgpIHsKLSAgICAgICAgTm9kZSB0aGlzTm9kZTsKLQotICAgICAgICAvLyBUcmVlIGNoYW5nZWQuIERvIGl0IGFsbCBmcm9tIHNjcmF0Y2ghCi0gICAgICAgIGlmKHJvb3ROb2RlLmNoYW5nZXMoKSAhPSBjaGFuZ2VzKSB7Ci0gICAgICAgICAgICBub2RlcyAgID0gbmV3IFZlY3RvcigpOwotICAgICAgICAgICAgY2hhbmdlcyA9IHJvb3ROb2RlLmNoYW5nZXMoKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIEluIHRoZSBjYWNoZQotICAgICAgICBpZiAoaW5kZXggPCBub2Rlcy5zaXplKCkpCi0gICAgICAgICAgICByZXR1cm4gKE5vZGUpbm9kZXMuZWxlbWVudEF0KGluZGV4KTsKLQotICAgICAgICAvLyBOb3QgeWV0IHNlZW4KLSAgICAgICAgZWxzZSB7Ci0KLSAgICAgICAgICAgIC8vIFBpY2sgdXAgd2hlcmUgd2UgbGVmdCBvZmYgKFdoaWNoIG1heSBiZSB0aGUgYmVnaW5uaW5nKQotICAgICAgICAgICAgICAgIGlmIChub2Rlcy5zaXplKCkgPT0gMCkKLSAgICAgICAgICAgICAgICAgICAgdGhpc05vZGUgPSByb290Tm9kZTsKLSAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgIHRoaXNOb2RlPShOb2RlSW1wbCkobm9kZXMubGFzdEVsZW1lbnQoKSk7Ci0KLSAgICAgICAgICAgICAgICAvLyBBZGQgbm9kZXMgdXAgdG8gdGhlIG9uZSB3ZSdyZSBsb29raW5nIGZvcgotICAgICAgICAgICAgICAgIHdoaWxlKHRoaXNOb2RlICE9IG51bGwgJiYgaW5kZXggPj0gbm9kZXMuc2l6ZSgpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICB0aGlzTm9kZT1uZXh0TWF0Y2hpbmdFbGVtZW50QWZ0ZXIodGhpc05vZGUpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXNOb2RlICE9IG51bGwpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZXMuYWRkRWxlbWVudCh0aGlzTm9kZSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gRWl0aGVyIHdoYXQgd2Ugd2FudCwgb3IgbnVsbCAobm90IGF2YWlsLikKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXNOb2RlOwotICAgICAgICAgICAgfQotCi0gICAgfSAvLyBpdGVtKGludCk6Tm9kZQotCi0gICAgLy8KLSAgICAvLyBQcm90ZWN0ZWQgbWV0aG9kcyAobWlnaHQgYmUgb3ZlcnJpZGRlbiBieSBhbiBleHRlbmRpbmcgRE9NKQotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBJdGVyYXRpdmUgdHJlZS13YWxrZXIuIFdoZW4geW91IGhhdmUgYSBQYXJlbnQgbGluaywgdGhlcmUncyBvZnRlbiBubwotICAgICAqIG5lZWQgdG8gcmVzb3J0IHRvIHJlY3Vyc2lvbi4gTk9URSBUSEFUIG9ubHkgRWxlbWVudCBub2RlcyBhcmUgbWF0Y2hlZAotICAgICAqIHNpbmNlIHdlJ3JlIHNwZWNpZmljYWxseSBzdXBwb3J0aW5nIGdldEVsZW1lbnRzQnlUYWdOYW1lKCkuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIE5vZGUgbmV4dE1hdGNoaW5nRWxlbWVudEFmdGVyKE5vZGUgY3VycmVudCkgewotCi0gICAgICAgICAgICBOb2RlIG5leHQ7Ci0gICAgICAgICAgICB3aGlsZSAoY3VycmVudCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIExvb2sgZG93biB0byBmaXJzdCBjaGlsZC4KLSAgICAgICAgICAgICAgICAgICAgaWYgKGN1cnJlbnQuaGFzQ2hpbGROb2RlcygpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudCA9IChjdXJyZW50LmdldEZpcnN0Q2hpbGQoKSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAvLyBMb29rIHJpZ2h0IHRvIHNpYmxpbmcgKGJ1dCBub3QgZnJvbSByb290ISkKLSAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoY3VycmVudCAhPSByb290Tm9kZSAmJiBudWxsICE9IChuZXh0ID0gY3VycmVudC5nZXROZXh0U2libGluZygpKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50ID0gbmV4dDsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gTG9vayB1cCBhbmQgcmlnaHQgKGJ1dCBub3QgcGFzdCByb290ISkKLSAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXh0ID0gbnVsbDsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yICg7IGN1cnJlbnQgIT0gcm9vdE5vZGU7IC8vIFN0b3Agd2hlbiB3ZSByZXR1cm4gdG8gc3RhcnRpbmcgcG9pbnQKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50ID0gY3VycmVudC5nZXRQYXJlbnROb2RlKCkpIHsKLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5leHQgPSBjdXJyZW50LmdldE5leHRTaWJsaW5nKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5leHQgIT0gbnVsbCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnQgPSBuZXh0OwotICAgICAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBIYXZlIHdlIGZvdW5kIGFuIEVsZW1lbnQgd2l0aCB0aGUgcmlnaHQgdGFnTmFtZT8KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vICgiKiIgbWF0Y2hlcyBhbnl0aGluZy4pCi0gICAgICAgICAgICAgICAgICAgIGlmIChjdXJyZW50ICE9IHJvb3ROb2RlCi0gICAgICAgICAgICAgICAgICAgICAgICAmJiBjdXJyZW50ICE9IG51bGwKLSAgICAgICAgICAgICAgICAgICAgICAgICYmIGN1cnJlbnQuZ2V0Tm9kZVR5cGUoKSA9PSAgTm9kZS5FTEVNRU5UX05PREUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmICghZW5hYmxlTlMpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGFnTmFtZS5lcXVhbHMoIioiKSB8fAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKEVsZW1lbnRJbXBsKSBjdXJyZW50KS5nZXRUYWdOYW1lKCkuZXF1YWxzKHRhZ05hbWUpKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnQ7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBET00yOiBOYW1lc3BhY2UgbG9naWMuCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRhZ05hbWUuZXF1YWxzKCIqIikpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5zTmFtZSAhPSBudWxsICYmIG5zTmFtZS5lcXVhbHMoIioiKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnQ7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFbGVtZW50SW1wbCBlbCA9IChFbGVtZW50SW1wbCkgY3VycmVudDsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgobnNOYW1lID09IG51bGwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgZWwuZ2V0TmFtZXNwYWNlVVJJKCkgPT0gbnVsbCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCAobnNOYW1lICE9IG51bGwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgbnNOYW1lLmVxdWFscyhlbC5nZXROYW1lc3BhY2VVUkkoKSkpKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjdXJyZW50OwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRWxlbWVudEltcGwgZWwgPSAoRWxlbWVudEltcGwpIGN1cnJlbnQ7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlbC5nZXRMb2NhbE5hbWUoKSAhPSBudWxsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiBlbC5nZXRMb2NhbE5hbWUoKS5lcXVhbHModGFnTmFtZSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuc05hbWUgIT0gbnVsbCAmJiBuc05hbWUuZXF1YWxzKCIqIikpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gY3VycmVudDsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChuc05hbWUgPT0gbnVsbAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgZWwuZ2V0TmFtZXNwYWNlVVJJKCkgPT0gbnVsbCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgKG5zTmFtZSAhPSBudWxsICYmCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuc05hbWUuZXF1YWxzKGVsLmdldE5hbWVzcGFjZVVSSSgpKSkpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gY3VycmVudDsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8vIE90aGVyd2lzZSBjb250aW51ZSB3YWxraW5nIHRoZSB0cmVlCi0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIEZlbGwgb3V0IG9mIHRyZWUtd2Fsazsgbm8gbW9yZSBpbnN0YW5jZXMgZm91bmQKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotCi0gICAgfSAvLyBuZXh0TWF0Y2hpbmdFbGVtZW50QWZ0ZXIoaW50KTpOb2RlCi0KLX0gLy8gY2xhc3MgRGVlcE5vZGVMaXN0SW1wbApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL0RlZmVycmVkQXR0ckltcGwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9EZWZlcnJlZEF0dHJJbXBsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGMzZTEzNDIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL0RlZmVycmVkQXR0ckltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE0NSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLS8qCi0gKiBXQVJOSU5HOiBiZWNhdXNlIGphdmEgZG9lc24ndCBzdXBwb3J0IG11bHRpLWluaGVyaXRhbmNlIHNvbWUgY29kZSBpcwotICogZHVwbGljYXRlZC4gSWYgeW91J3JlIGNoYW5naW5nIHRoaXMgZmlsZSB5b3UgcHJvYmFibHkgd2FudCB0byBjaGFuZ2UKLSAqIERlZmVycmVkQXR0ck5TSW1wbC5qYXZhIGF0IHRoZSBzYW1lIHRpbWUuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbTsKLQotLyoqCi0gKiBBdHRyaWJ1dGUgcmVwcmVzZW50cyBhbiBYTUwtc3R5bGUgYXR0cmlidXRlIG9mIGFuCi0gKiBFbGVtZW50LiBUeXBpY2FsbHksIHRoZSBhbGxvd2FibGUgdmFsdWVzIGFyZSBjb250cm9sbGVkIGJ5IGl0cwotICogZGVjbGFyYXRpb24gaW4gdGhlIERvY3VtZW50IFR5cGUgRGVmaW5pdGlvbiAoRFREKSBnb3Zlcm5pbmcgdGhpcwotICoga2luZCBvZiBkb2N1bWVudC4KLSAqIDxQPgotICogSWYgdGhlIGF0dHJpYnV0ZSBoYXMgbm90IGJlZW4gZXhwbGljaXRseSBhc3NpZ25lZCBhIHZhbHVlLCBidXQgaGFzCi0gKiBiZWVuIGRlY2xhcmVkIGluIHRoZSBEVEQsIGl0IHdpbGwgZXhpc3QgYW5kIGhhdmUgdGhhdCBkZWZhdWx0LiBPbmx5Ci0gKiBpZiBuZWl0aGVyIHRoZSBkb2N1bWVudCBub3IgdGhlIERURCBzcGVjaWZpZXMgYSB2YWx1ZSB3aWxsIHRoZQotICogQXR0cmlidXRlIHJlYWxseSBiZSBjb25zaWRlcmVkIGFic2VudCBhbmQgaGF2ZSBubyB2YWx1ZTsgaW4gdGhhdAotICogY2FzZSwgcXVlcnlpbmcgdGhlIGF0dHJpYnV0ZSB3aWxsIHJldHVybiBudWxsLgotICogPFA+Ci0gKiBBdHRyaWJ1dGVzIG1heSBoYXZlIG11bHRpcGxlIGNoaWxkcmVuIHRoYXQgY29udGFpbiB0aGVpciBkYXRhLiAoWE1MCi0gKiBhbGxvd3MgYXR0cmlidXRlcyB0byBjb250YWluIGVudGl0eSByZWZlcmVuY2VzLCBhbmQgdG9rZW5pemVkCi0gKiBhdHRyaWJ1dGUgdHlwZXMgc3VjaCBhcyBOTVRPS0VOUyBtYXkgaGF2ZSBhIGNoaWxkIGZvciBlYWNoIHRva2VuLikKLSAqIEZvciBjb252ZW5pZW5jZSwgdGhlIEF0dHJpYnV0ZSBvYmplY3QncyBnZXRWYWx1ZSgpIG1ldGhvZCByZXR1cm5zCi0gKiB0aGUgc3RyaW5nIHZlcnNpb24gb2YgdGhlIGF0dHJpYnV0ZSdzIHZhbHVlLgotICogPFA+Ci0gKiBBdHRyaWJ1dGVzIGFyZSBub3QgY2hpbGRyZW4gb2YgdGhlIEVsZW1lbnRzIHRoZXkgYmVsb25nIHRvLCBpbiB0aGUKLSAqIHVzdWFsIHNlbnNlLCBhbmQgaGF2ZSBubyB2YWxpZCBQYXJlbnQgcmVmZXJlbmNlLiBIb3dldmVyLCB0aGUgc3BlYwotICogc2F5cyB0aGV5IF9kb18gYmVsb25nIHRvIGEgc3BlY2lmaWMgRWxlbWVudCwgYW5kIGFuIElOVVNFIGV4Y2VwdGlvbgotICogaXMgdG8gYmUgdGhyb3duIGlmIHRoZSB1c2VyIGF0dGVtcHRzIHRvIGV4cGxpY2l0bHkgc2hhcmUgdGhlbQotICogYmV0d2VlbiBlbGVtZW50cy4KLSAqIDxQPgotICogTm90ZSB0aGF0IEVsZW1lbnRzIGRvIG5vdCBwZXJtaXQgYXR0cmlidXRlcyB0byBhcHBlYXIgdG8gYmUgc2hhcmVkCi0gKiAoc2VlIHRoZSBJTlVTRSBleGNlcHRpb24pLCBzbyB0aGlzIG9iamVjdCdzIG11dGFiaWxpdHkgaXMKLSAqIG9mZmljaWFsbHkgbm90IGFuIGlzc3VlLgotICogPFA+Ci0gKiBEZWZlcnJlZEF0dHJJbXBsIGluaGVyaXRzIGZyb20gQXR0ckltcGwgd2hpY2ggZG9lcyBub3Qgc3VwcG9ydAotICogTmFtZXNwYWNlcy4gRGVmZXJyZWRBdHRyTlNJbXBsLCB3aGljaCBpbmhlcml0cyBmcm9tIEF0dHJOU0ltcGwsIGRvZXMuCi0gKiBAc2VlIERlZmVycmVkQXR0ck5TSW1wbAotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIEFuZHkgQ2xhcmssIElCTQotICogQGF1dGhvciBBcm5hdWQgIExlIEhvcnMsIElCTQotICogQHNpbmNlICBQUi1ET00tTGV2ZWwtMS0xOTk4MDgxOC4KLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIERlZmVycmVkQXR0ckltcGwKLSAgICBleHRlbmRzIEF0dHJJbXBsCi0gICAgaW1wbGVtZW50cyBEZWZlcnJlZE5vZGUgewotCi0gICAgLy8KLSAgICAvLyBDb25zdGFudHMKLSAgICAvLwotCi0gICAgLyoqIFNlcmlhbGl6YXRpb24gdmVyc2lvbi4gKi8KLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNjkwMzIzMjMxMjQ2OTE0ODYzNkw7Ci0KLSAgICAvLwotICAgIC8vIERhdGEKLSAgICAvLwotCi0gICAgLyoqIE5vZGUgaW5kZXguICovCi0gICAgcHJvdGVjdGVkIHRyYW5zaWVudCBpbnQgZk5vZGVJbmRleDsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFRoaXMgaXMgdGhlIGRlZmVycmVkIGNvbnN0cnVjdG9yLiBPbmx5IHRoZSBmTm9kZUluZGV4IGlzIGdpdmVuIGhlcmUuCi0gICAgICogQWxsIG90aGVyIGRhdGEsIGNhbiBiZSByZXF1ZXN0ZWQgZnJvbSB0aGUgb3duZXJEb2N1bWVudCB2aWEgdGhlIGluZGV4LgotICAgICAqLwotICAgIERlZmVycmVkQXR0ckltcGwoRGVmZXJyZWREb2N1bWVudEltcGwgb3duZXJEb2N1bWVudCwgaW50IG5vZGVJbmRleCkgewotICAgICAgICBzdXBlcihvd25lckRvY3VtZW50LCBudWxsKTsKLQotICAgICAgICBmTm9kZUluZGV4ID0gbm9kZUluZGV4OwotICAgICAgICBuZWVkc1N5bmNEYXRhKHRydWUpOwotICAgICAgICBuZWVkc1N5bmNDaGlsZHJlbih0cnVlKTsKLQotICAgIH0gLy8gPGluaXQ+KERlZmVycmVkRG9jdW1lbnRJbXBsLGludCkKLQotICAgIC8vCi0gICAgLy8gRGVmZXJyZWROb2RlIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqIFJldHVybnMgdGhlIG5vZGUgaW5kZXguICovCi0gICAgcHVibGljIGludCBnZXROb2RlSW5kZXgoKSB7Ci0gICAgICAgIHJldHVybiBmTm9kZUluZGV4OwotICAgIH0KLQotICAgIC8vCi0gICAgLy8gUHJvdGVjdGVkIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqIFN5bmNocm9uaXplcyB0aGUgZGF0YSAobmFtZSBhbmQgdmFsdWUpIGZvciBmYXN0IG5vZGVzLiAqLwotICAgIHByb3RlY3RlZCB2b2lkIHN5bmNocm9uaXplRGF0YSgpIHsKLQotICAgICAgICAvLyBubyBuZWVkIHRvIHN5bmMgaW4gdGhlIGZ1dHVyZQotICAgICAgICBuZWVkc1N5bmNEYXRhKGZhbHNlKTsKLQotICAgICAgICAvLyBmbHVmZiBkYXRhCi0gICAgICAgIERlZmVycmVkRG9jdW1lbnRJbXBsIG93bmVyRG9jdW1lbnQgPQotICAgICAgICAgICAgKERlZmVycmVkRG9jdW1lbnRJbXBsKSBvd25lckRvY3VtZW50KCk7Ci0gICAgICAgIG5hbWUgPSBvd25lckRvY3VtZW50LmdldE5vZGVOYW1lKGZOb2RlSW5kZXgpOwotICAgICAgICBpbnQgZXh0cmEgPSBvd25lckRvY3VtZW50LmdldE5vZGVFeHRyYShmTm9kZUluZGV4KTsKLSAgICAgICAgaXNTcGVjaWZpZWQoKGV4dHJhICYgU1BFQ0lGSUVEKSAhPSAwKTsKLSAgICAgICAgaXNJZEF0dHJpYnV0ZSgoZXh0cmEgJiBJRCkgIT0gMCk7Ci0KLSAgICAgICAgaW50IGV4dHJhTm9kZSA9IG93bmVyRG9jdW1lbnQuZ2V0TGFzdENoaWxkKGZOb2RlSW5kZXgpOwotICAgICAgICB0eXBlID0gb3duZXJEb2N1bWVudC5nZXRUeXBlSW5mbyhleHRyYU5vZGUpOwotICAgIH0gLy8gc3luY2hyb25pemVEYXRhKCkKLQotICAgIC8qKgotICAgICAqIFN5bmNocm9uaXplcyB0aGUgbm9kZSdzIGNoaWxkcmVuIHdpdGggdGhlIGludGVybmFsIHN0cnVjdHVyZS4KLSAgICAgKiBGbHVmZmluZyB0aGUgY2hpbGRyZW4gYXQgb25jZSBzb2x2ZXMgYSBsb3Qgb2Ygd29yayB0byBrZWVwCi0gICAgICogdGhlIHR3byBzdHJ1Y3R1cmVzIGluIHN5bmMuIFRoZSBwcm9ibGVtIGdldHMgd29yc2Ugd2hlbgotICAgICAqIGVkaXRpbmcgdGhlIHRyZWUgLS0gdGhpcyBtYWtlcyBpdCBhIGxvdCBlYXNpZXIuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgc3luY2hyb25pemVDaGlsZHJlbigpIHsKLSAgICAgICAgRGVmZXJyZWREb2N1bWVudEltcGwgb3duZXJEb2N1bWVudCA9Ci0gICAgICAgICAgICAoRGVmZXJyZWREb2N1bWVudEltcGwpIG93bmVyRG9jdW1lbnQoKTsKLSAgICAgICAgb3duZXJEb2N1bWVudC5zeW5jaHJvbml6ZUNoaWxkcmVuKHRoaXMsIGZOb2RlSW5kZXgpOwotICAgIH0gLy8gc3luY2hyb25pemVDaGlsZHJlbigpCi0KLX0gLy8gY2xhc3MgRGVmZXJyZWRBdHRySW1wbApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL0RlZmVycmVkQXR0ck5TSW1wbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL0RlZmVycmVkQXR0ck5TSW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzYjQwNTIxLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9EZWZlcnJlZEF0dHJOU0ltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEzMCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLS8qCi0gKiBXQVJOSU5HOiBiZWNhdXNlIGphdmEgZG9lc24ndCBzdXBwb3J0IG11bHRpLWluaGVyaXRhbmNlIHNvbWUgY29kZSBpcwotICogZHVwbGljYXRlZC4gSWYgeW91J3JlIGNoYW5naW5nIHRoaXMgZmlsZSB5b3UgcHJvYmFibHkgd2FudCB0byBjaGFuZ2UKLSAqIERlZmVycmVkQXR0ckltcGwuamF2YSBhdCB0aGUgc2FtZSB0aW1lLgotICovCi0KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbTsKLQotLyoqCi0gKiBEZWZlcnJlZEF0dHJOU0ltcGwgaXMgdG8gQXR0ck5TSW1wbCwgd2hhdCBEZWZlcnJlZEF0dHJJbXBsIGlzIHRvCi0gKiBBdHRySW1wbC4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBBbmR5IENsYXJrLCBJQk0KLSAqIEBhdXRob3IgQXJuYXVkICBMZSBIb3JzLCBJQk0KLSAqIEBzZWUgRGVmZXJyZWRBdHRySW1wbAotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgRGVmZXJyZWRBdHRyTlNJbXBsCi0gICAgZXh0ZW5kcyBBdHRyTlNJbXBsCi0gICAgaW1wbGVtZW50cyBEZWZlcnJlZE5vZGUgewotCi0gICAgLy8KLSAgICAvLyBDb25zdGFudHMKLSAgICAvLwotCi0gICAgLyoqIFNlcmlhbGl6YXRpb24gdmVyc2lvbi4gKi8KLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNjA3NDkyNDkzNDk0NTk1NzE1NEw7Ci0KLSAgICAvLwotICAgIC8vIERhdGEKLSAgICAvLwotCi0gICAgLyoqIE5vZGUgaW5kZXguICovCi0gICAgcHJvdGVjdGVkIHRyYW5zaWVudCBpbnQgZk5vZGVJbmRleDsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFRoaXMgaXMgdGhlIGRlZmVycmVkIGNvbnN0cnVjdG9yLiBPbmx5IHRoZSBmTm9kZUluZGV4IGlzIGdpdmVuIGhlcmUuCi0gICAgICogQWxsIG90aGVyIGRhdGEsIGNhbiBiZSByZXF1ZXN0ZWQgZnJvbSB0aGUgb3duZXJEb2N1bWVudCB2aWEgdGhlIGluZGV4LgotICAgICAqLwotICAgIERlZmVycmVkQXR0ck5TSW1wbChEZWZlcnJlZERvY3VtZW50SW1wbCBvd25lckRvY3VtZW50LCBpbnQgbm9kZUluZGV4KSB7Ci0gICAgICAgIHN1cGVyKG93bmVyRG9jdW1lbnQsIG51bGwpOwotCi0gICAgICAgIGZOb2RlSW5kZXggPSBub2RlSW5kZXg7Ci0gICAgICAgIG5lZWRzU3luY0RhdGEodHJ1ZSk7Ci0gICAgICAgIG5lZWRzU3luY0NoaWxkcmVuKHRydWUpOwotCi0gICAgfSAvLyA8aW5pdD4oRGVmZXJyZWREb2N1bWVudEltcGwsaW50KQotCi0gICAgLy8KLSAgICAvLyBEZWZlcnJlZE5vZGUgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKiogUmV0dXJucyB0aGUgbm9kZSBpbmRleC4gKi8KLSAgICBwdWJsaWMgaW50IGdldE5vZGVJbmRleCgpIHsKLSAgICAgICAgcmV0dXJuIGZOb2RlSW5kZXg7Ci0gICAgfQotCi0gICAgLy8KLSAgICAvLyBQcm90ZWN0ZWQgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKiogU3luY2hyb25pemVzIHRoZSBkYXRhIChuYW1lIGFuZCB2YWx1ZSkgZm9yIGZhc3Qgbm9kZXMuICovCi0gICAgcHJvdGVjdGVkIHZvaWQgc3luY2hyb25pemVEYXRhKCkgewotCi0gICAgICAgIC8vIG5vIG5lZWQgdG8gc3luYyBpbiB0aGUgZnV0dXJlCi0gICAgICAgIG5lZWRzU3luY0RhdGEoZmFsc2UpOwotCi0gICAgICAgIC8vIGZsdWZmIGRhdGEKLSAgICAgICAgRGVmZXJyZWREb2N1bWVudEltcGwgb3duZXJEb2N1bWVudCA9Ci0gICAgICAgICAgICAoRGVmZXJyZWREb2N1bWVudEltcGwpIG93bmVyRG9jdW1lbnQoKTsKLSAgICAgICAgbmFtZSA9IG93bmVyRG9jdW1lbnQuZ2V0Tm9kZU5hbWUoZk5vZGVJbmRleCk7Ci0KLSAgICAgICAgLy8gZXh0cmFjdCBwcmVmaXggYW5kIGxvY2FsIHBhcnQgZnJvbSBRTmFtZQotICAgICAgICBpbnQgaW5kZXggPSBuYW1lLmluZGV4T2YoJzonKTsKLSAgICAgICAgaWYgKGluZGV4IDwgMCkgewotICAgICAgICAgICAgbG9jYWxOYW1lID0gbmFtZTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIGxvY2FsTmFtZSA9IG5hbWUuc3Vic3RyaW5nKGluZGV4ICsgMSk7Ci0gICAgICAgIH0KLQotICAgICAgICBpbnQgZXh0cmEgPSBvd25lckRvY3VtZW50LmdldE5vZGVFeHRyYShmTm9kZUluZGV4KTsKLSAgICAgICAgaXNTcGVjaWZpZWQoKGV4dHJhICYgU1BFQ0lGSUVEKSAhPSAwKTsKLSAgICAgICAgaXNJZEF0dHJpYnV0ZSgoZXh0cmEgJiBJRCkgIT0gMCk7Ci0KLSAgICAgICAgbmFtZXNwYWNlVVJJID0gb3duZXJEb2N1bWVudC5nZXROb2RlVVJJKGZOb2RlSW5kZXgpOwotCi0gICAgICAgIGludCBleHRyYU5vZGUgPSBvd25lckRvY3VtZW50LmdldExhc3RDaGlsZChmTm9kZUluZGV4KTsKLSAgICAgICAgdHlwZSA9IG93bmVyRG9jdW1lbnQuZ2V0VHlwZUluZm8oZXh0cmFOb2RlKTsKLSAgICB9IC8vIHN5bmNocm9uaXplRGF0YSgpCi0KLSAgICAvKioKLSAgICAgKiBTeW5jaHJvbml6ZXMgdGhlIG5vZGUncyBjaGlsZHJlbiB3aXRoIHRoZSBpbnRlcm5hbCBzdHJ1Y3R1cmUuCi0gICAgICogRmx1ZmZpbmcgdGhlIGNoaWxkcmVuIGF0IG9uY2Ugc29sdmVzIGEgbG90IG9mIHdvcmsgdG8ga2VlcAotICAgICAqIHRoZSB0d28gc3RydWN0dXJlcyBpbiBzeW5jLiBUaGUgcHJvYmxlbSBnZXRzIHdvcnNlIHdoZW4KLSAgICAgKiBlZGl0aW5nIHRoZSB0cmVlIC0tIHRoaXMgbWFrZXMgaXQgYSBsb3QgZWFzaWVyLgotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIHN5bmNocm9uaXplQ2hpbGRyZW4oKSB7Ci0gICAgICAgIERlZmVycmVkRG9jdW1lbnRJbXBsIG93bmVyRG9jdW1lbnQgPQotICAgICAgICAgICAgKERlZmVycmVkRG9jdW1lbnRJbXBsKSBvd25lckRvY3VtZW50KCk7Ci0gICAgICAgIG93bmVyRG9jdW1lbnQuc3luY2hyb25pemVDaGlsZHJlbih0aGlzLCBmTm9kZUluZGV4KTsKLSAgICB9IC8vIHN5bmNocm9uaXplQ2hpbGRyZW4oKQotCi19IC8vIGNsYXNzIERlZmVycmVkQXR0ckltcGwKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9EZWZlcnJlZENEQVRBU2VjdGlvbkltcGwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9EZWZlcnJlZENEQVRBU2VjdGlvbkltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNTIxMzJmMC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vRGVmZXJyZWRDREFUQVNlY3Rpb25JbXBsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMDkgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDAyLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tOwotCi0vKioKLSAqIFhNTCBwcm92aWRlcyB0aGUgQ0RBVEEgbWFya3VwIHRvIGFsbG93IGEgcmVnaW9uIG9mIHRleHQgaW4gd2hpY2gKLSAqIG1vc3Qgb2YgdGhlIFhNTCBkZWxpbWl0ZXIgcmVjb2duaXRpb24gZG9lcyBub3QgdGFrZSBwbGFjZS4gVGhpcyBpcwotICogaW50ZW5kZWQgdG8gZWFzZSB0aGUgdGFzayBvZiBxdW90aW5nIFhNTCBmcmFnbWVudHMgYW5kIG90aGVyCi0gKiBwcm9ncmFtbWF0aWMgaW5mb3JtYXRpb24gaW4gYSBkb2N1bWVudCdzIHRleHQgd2l0aG91dCBuZWVkaW5nIHRvCi0gKiBlc2NhcGUgdGhlc2Ugc3BlY2lhbCBjaGFyYWN0ZXJzLiBJdCdzIHByaW1hcmlseSBhIGNvbnZlbmllbmNlIGZlYXR1cmUKLSAqIGZvciB0aG9zZSB3aG8gYXJlIGhhbmQtZWRpdGluZyBYTUwuCi0gKiA8UD4KLSAqIENEQVRBU2VjdGlvbiBpcyBhbiBFeHRlbmRlZCBET00gZmVhdHVyZSwgYW5kIGlzIG5vdCB1c2VkIGluIEhUTUwKLSAqIGNvbnRleHRzLgotICogPFA+Ci0gKiBXaXRoaW4gdGhlIERPTSwgQ0RBVEFTZWN0aW9ucyBhcmUgdHJlYXRlZCBlc3NlbnRpYWxseSBhcyBUZXh0Ci0gKiBibG9ja3MuIFRoZWlyIGRpc3RpbmN0IHR5cGUgaXMgcmV0YWluZWQgaW4gb3JkZXIgdG8gYWxsb3cgdXMgdG8KLSAqIHByb3Blcmx5IHJlY3JlYXRlIHRoZSBYTUwgc3ludGF4IHdoZW4gd2Ugd3JpdGUgdGhlbSBvdXQuCi0gKiA8UD4KLSAqIFJlbWluZGVyOiBDREFUQSBJUyBOT1QgQSBDT01QTEVURUxZIEdFTkVSQUwgU09MVVRJT047IGl0IGNhbid0Ci0gKiBxdW90ZSBpdHMgb3duIGVuZC1vZi1ibG9jayBtYXJraW5nLiBJZiB5b3UgbmVlZCB0byB3cml0ZSBvdXQgYQotICogQ0RBVEEgdGhhdCBjb250YWlucyB0aGUgXV0+IHNlcXVlbmNlLCBpdCdzIHlvdXIgcmVzcG9uc2liaWxpdHkgdG8KLSAqIHNwbGl0IHRoYXQgc3RyaW5nIG92ZXIgdHdvIHN1Y2Nlc3NpdmUgQ0RBVEFzIGF0IHRoYXQgdGltZS4KLSAqIDxQPgotICogQ0RBVEEgZG9lcyBub3QgcGFydGljaXBhdGUgaW4gRWxlbWVudC5ub3JtYWxpemUoKSBwcm9jZXNzaW5nLgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAc2luY2UgIFBSLURPTS1MZXZlbC0xLTE5OTgwODE4LgotICovCi1wdWJsaWMgY2xhc3MgRGVmZXJyZWRDREFUQVNlY3Rpb25JbXBsCi0gICAgZXh0ZW5kcyBDREFUQVNlY3Rpb25JbXBsCi0gICAgaW1wbGVtZW50cyBEZWZlcnJlZE5vZGUgewotCi0gICAgLy8KLSAgICAvLyBDb25zdGFudHMKLSAgICAvLwotCi0gICAgLyoqIFNlcmlhbGl6YXRpb24gdmVyc2lvbi4gKi8KLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMTk4MzU4MDYzMjM1NTY0NTcyNkw7Ci0KLSAgICAvLwotICAgIC8vIERhdGEKLSAgICAvLwotCi0gICAgLyoqIE5vZGUgaW5kZXguICovCi0gICAgcHJvdGVjdGVkIHRyYW5zaWVudCBpbnQgZk5vZGVJbmRleDsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFRoaXMgaXMgdGhlIGRlZmVycmVkIGNvbnN0cnVjdG9yLiBPbmx5IHRoZSBmTm9kZUluZGV4IGlzIGdpdmVuIGhlcmUuIEFsbCBvdGhlciBkYXRhLAotICAgICAqIGNhbiBiZSByZXF1ZXN0ZWQgZnJvbSB0aGUgb3duZXJEb2N1bWVudCB2aWEgdGhlIGluZGV4LgotICAgICAqLwotICAgIERlZmVycmVkQ0RBVEFTZWN0aW9uSW1wbChEZWZlcnJlZERvY3VtZW50SW1wbCBvd25lckRvY3VtZW50LCBpbnQgbm9kZUluZGV4KSB7Ci0gICAgICAgIHN1cGVyKG93bmVyRG9jdW1lbnQsIG51bGwpOwotCi0gICAgICAgIGZOb2RlSW5kZXggPSBub2RlSW5kZXg7Ci0gICAgICAgIG5lZWRzU3luY0RhdGEodHJ1ZSk7Ci0KLSAgICB9IC8vIDxpbml0PihEZWZlcnJlZERvY3VtZW50SW1wbCxpbnQpCi0KLSAgICAvLwotICAgIC8vIERlZmVycmVkTm9kZSBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKiBSZXR1cm5zIHRoZSBub2RlIGluZGV4LiAqLwotICAgIHB1YmxpYyBpbnQgZ2V0Tm9kZUluZGV4KCkgewotICAgICAgICByZXR1cm4gZk5vZGVJbmRleDsKLSAgICB9Ci0KLSAgICAvLwotICAgIC8vIFByb3RlY3RlZCBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKiBTeW5jaHJvbml6ZXMgdGhlIGRhdGEgKG5hbWUgYW5kIHZhbHVlKSBmb3IgZmFzdCBub2Rlcy4gKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCBzeW5jaHJvbml6ZURhdGEoKSB7Ci0KLSAgICAgICAgLy8gbm8gbmVlZCB0byBzeW5jIGluIHRoZSBmdXR1cmUKLSAgICAgICAgbmVlZHNTeW5jRGF0YShmYWxzZSk7Ci0KLSAgICAgICAgLy8gZmx1ZmYgZGF0YQotICAgICAgICBEZWZlcnJlZERvY3VtZW50SW1wbCBvd25lckRvY3VtZW50ID0KLSAgICAgICAgICAgIChEZWZlcnJlZERvY3VtZW50SW1wbCkgdGhpcy5vd25lckRvY3VtZW50KCk7Ci0gICAgICAgIGRhdGEgPSBvd25lckRvY3VtZW50LmdldE5vZGVWYWx1ZVN0cmluZyhmTm9kZUluZGV4KTsKLQotICAgIH0gLy8gc3luY2hyb25pemVEYXRhKCkKLQotfSAvLyBjbGFzcyBEZWZlcnJlZENEQVRBU2VjdGlvbkltcGwKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9EZWZlcnJlZENvbW1lbnRJbXBsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vRGVmZXJyZWRDb21tZW50SW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzZjgwNDkyLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9EZWZlcnJlZENvbW1lbnRJbXBsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5MCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5kb207Ci0KLS8qKgotICogUmVwcmVzZW50cyBhbiBYTUwgKG9yIEhUTUwpIGNvbW1lbnQuCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBzaW5jZSAgUFItRE9NLUxldmVsLTEtMTk5ODA4MTguCi0gKi8KLXB1YmxpYyBjbGFzcyBEZWZlcnJlZENvbW1lbnRJbXBsCi0gICAgZXh0ZW5kcyBDb21tZW50SW1wbAotICAgIGltcGxlbWVudHMgRGVmZXJyZWROb2RlIHsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RhbnRzCi0gICAgLy8KLQotICAgIC8qKiBTZXJpYWxpemF0aW9uIHZlcnNpb24uICovCi0gICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDY0OTg3OTYzNzEwODM1ODkzMzhMOwotCi0gICAgLy8KLSAgICAvLyBEYXRhCi0gICAgLy8KLQotICAgIC8qKiBOb2RlIGluZGV4LiAqLwotICAgIHByb3RlY3RlZCB0cmFuc2llbnQgaW50IGZOb2RlSW5kZXg7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0cnVjdG9ycwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBUaGlzIGlzIHRoZSBkZWZlcnJlZCBjb25zdHJ1Y3Rvci4gT25seSB0aGUgZk5vZGVJbmRleCBpcyBnaXZlbiBoZXJlLiBBbGwgb3RoZXIgZGF0YSwKLSAgICAgKiBjYW4gYmUgcmVxdWVzdGVkIGZyb20gdGhlIG93bmVyRG9jdW1lbnQgdmlhIHRoZSBpbmRleC4KLSAgICAgKi8KLSAgICBEZWZlcnJlZENvbW1lbnRJbXBsKERlZmVycmVkRG9jdW1lbnRJbXBsIG93bmVyRG9jdW1lbnQsIGludCBub2RlSW5kZXgpIHsKLSAgICAgICAgc3VwZXIob3duZXJEb2N1bWVudCwgbnVsbCk7Ci0KLSAgICAgICAgZk5vZGVJbmRleCA9IG5vZGVJbmRleDsKLSAgICAgICAgbmVlZHNTeW5jRGF0YSh0cnVlKTsKLQotICAgIH0gLy8gPGluaXQ+KERlZmVycmVkRG9jdW1lbnRJbXBsLGludCkKLQotICAgIC8vCi0gICAgLy8gRGVmZXJyZWROb2RlIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqIFJldHVybnMgdGhlIG5vZGUgaW5kZXguICovCi0gICAgcHVibGljIGludCBnZXROb2RlSW5kZXgoKSB7Ci0gICAgICAgIHJldHVybiBmTm9kZUluZGV4OwotICAgIH0KLQotICAgIC8vCi0gICAgLy8gUHJvdGVjdGVkIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqIFN5bmNocm9uaXplcyB0aGUgZGF0YSAobmFtZSBhbmQgdmFsdWUpIGZvciBmYXN0IG5vZGVzLiAqLwotICAgIHByb3RlY3RlZCB2b2lkIHN5bmNocm9uaXplRGF0YSgpIHsKLQotICAgICAgICAvLyBubyBuZWVkIHRvIHN5bmMgaW4gdGhlIGZ1dHVyZQotICAgICAgICBuZWVkc1N5bmNEYXRhKGZhbHNlKTsKLQotICAgICAgICAvLyBmbHVmZiBkYXRhCi0gICAgICAgIERlZmVycmVkRG9jdW1lbnRJbXBsIG93bmVyRG9jdW1lbnQgPQotICAgICAgICAgICAgKERlZmVycmVkRG9jdW1lbnRJbXBsKSB0aGlzLm93bmVyRG9jdW1lbnQoKTsKLSAgICAgICAgZGF0YSA9IG93bmVyRG9jdW1lbnQuZ2V0Tm9kZVZhbHVlU3RyaW5nKGZOb2RlSW5kZXgpOwotCi0gICAgfSAvLyBzeW5jaHJvbml6ZURhdGEoKQotCi19IC8vIGNsYXNzIERlZmVycmVkQ29tbWVudEltcGwKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9EZWZlcnJlZERPTUltcGxlbWVudGF0aW9uSW1wbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL0RlZmVycmVkRE9NSW1wbGVtZW50YXRpb25JbXBsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDJiYTFjOWUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL0RlZmVycmVkRE9NSW1wbGVtZW50YXRpb25JbXBsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw1OCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5kb207Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5ET01JbXBsZW1lbnRhdGlvbjsKLQotLyoqCi0gKiA8cD5UaGlzIERPTUltcGxlbWVudGF0aW9uIGNsYXNzIGlzIGRlc2NyaXB0aW9uIG9mIGEgcGFydGljdWxhcgotICogaW1wbGVtZW50YXRpb24gb2YgdGhlIERvY3VtZW50IE9iamVjdCBNb2RlbC4gQXMgc3VjaCBpdHMgZGF0YSBpcwotICogc3RhdGljLCBzaGFyZWQgYnkgYWxsIGluc3RhbmNlcyBvZiB0aGlzIGltcGxlbWVudGF0aW9uLjwvcD4KLSAqCi0gKiA8cD5UaGlzIGltcGxlbWVudGF0aW9uIHNpbXBseSBleHRlbmRzIERPTUltcGxlbWVudGF0aW9uSW1wbCB0byBkaWZmZXJlbnRpYXRlCi0gKiBiZXR3ZWVuIHRoZSBEZWZlcnJlZCBET00gSW1wbGVtZW50YXRpb25zIGFuZCBOb24tRGVmZXJyZWQgRE9NIEltcGxlbWVudGF0aW9ucy48L3A+Ci0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgTmVpbCBEZWxpbWEsIElCTQotICoKLSAqLwotcHVibGljIGNsYXNzIERlZmVycmVkRE9NSW1wbGVtZW50YXRpb25JbXBsCi0gICAgZXh0ZW5kcyBET01JbXBsZW1lbnRhdGlvbkltcGwgewotCi0gICAgLy8KLSAgICAvLyBEYXRhCi0gICAgLy8KLQotICAgIC8vIHN0YXRpYwotCi0gICAgLyoqIERvbSBpbXBsZW1lbnRhdGlvbiBzaW5nbGV0b24uICovCi0gICAgc3RhdGljIERlZmVycmVkRE9NSW1wbGVtZW50YXRpb25JbXBsIHNpbmdsZXRvbiA9IG5ldyBEZWZlcnJlZERPTUltcGxlbWVudGF0aW9uSW1wbCgpOwotCi0KLSAgICAvLwotICAgIC8vIFB1YmxpYyBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKiBOT04tRE9NOiBPYnRhaW4gYW5kIHJldHVybiB0aGUgc2luZ2xlIHNoYXJlZCBvYmplY3QgKi8KLSAgICBwdWJsaWMgc3RhdGljIERPTUltcGxlbWVudGF0aW9uIGdldERPTUltcGxlbWVudGF0aW9uKCkgewotICAgICAgICByZXR1cm4gc2luZ2xldG9uOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9EZWZlcnJlZERvY3VtZW50SW1wbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL0RlZmVycmVkRG9jdW1lbnRJbXBsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDE0ODYwODYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL0RlZmVycmVkRG9jdW1lbnRJbXBsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMTU4ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKi8KLS8qCi0gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKLSAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAotICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgotICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKLSAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCi0gKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbTsKLQotaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7Ci1pbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7Ci1pbXBvcnQgb3JnLnczYy5kb20uRE9NSW1wbGVtZW50YXRpb247Ci1pbXBvcnQgb3JnLnczYy5kb20uRWxlbWVudDsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotCi0vKioKLSAqIFRoZSBEb2N1bWVudCBpbnRlcmZhY2UgcmVwcmVzZW50cyB0aGUgZW50aXJlIEhUTUwgb3IgWE1MIGRvY3VtZW50LgotICogQ29uY2VwdHVhbGx5LCBpdCBpcyB0aGUgcm9vdCBvZiB0aGUgZG9jdW1lbnQgdHJlZSwgYW5kIHByb3ZpZGVzIHRoZQotICogcHJpbWFyeSBhY2Nlc3MgdG8gdGhlIGRvY3VtZW50J3MgZGF0YS4KLSAqIDxQPgotICogU2luY2UgZWxlbWVudHMsIHRleHQgbm9kZXMsIGNvbW1lbnRzLCBwcm9jZXNzaW5nIGluc3RydWN0aW9ucywKLSAqIGV0Yy4gY2Fubm90IGV4aXN0IG91dHNpZGUgdGhlIGNvbnRleHQgb2YgYSBEb2N1bWVudCwgdGhlIERvY3VtZW50Ci0gKiBpbnRlcmZhY2UgYWxzbyBjb250YWlucyB0aGUgZmFjdG9yeSBtZXRob2RzIG5lZWRlZCB0byBjcmVhdGUgdGhlc2UKLSAqIG9iamVjdHMuIFRoZSBOb2RlIG9iamVjdHMgY3JlYXRlZCBoYXZlIGEgb3duZXJEb2N1bWVudCBhdHRyaWJ1dGUKLSAqIHdoaWNoIGFzc29jaWF0ZXMgdGhlbSB3aXRoIHRoZSBEb2N1bWVudCB3aXRoaW4gd2hvc2UgY29udGV4dCB0aGV5Ci0gKiB3ZXJlIGNyZWF0ZWQuCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEB2ZXJzaW9uICRJZDogRGVmZXJyZWREb2N1bWVudEltcGwuamF2YSx2IDEuMTEgMjAxMC0xMS0wMSAwNDozOTozOCBqb2VodyBFeHAgJAotICogQHNpbmNlICBQUi1ET00tTGV2ZWwtMS0xOTk4MDgxOC4KLSAqLwotcHVibGljIGNsYXNzIERlZmVycmVkRG9jdW1lbnRJbXBsCi0gICAgZXh0ZW5kcyBEb2N1bWVudEltcGwKLSAgICBpbXBsZW1lbnRzIERlZmVycmVkTm9kZSB7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0YW50cwotICAgIC8vCi0KLSAgICAvKiogU2VyaWFsaXphdGlvbiB2ZXJzaW9uLiAqLwotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA1MTg2MzIzNTgwNzQ5NjI2ODU3TDsKLQotICAgIC8vIGRlYnVnZ2luZwotCi0gICAgLyoqIFRvIGluY2x1ZGUgY29kZSBmb3IgcHJpbnRpbmcgdGhlIHJlZiBjb3VudCB0YWJsZXMuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbiBERUJVR19QUklOVF9SRUZfQ09VTlRTID0gZmFsc2U7Ci0KLSAgICAvKiogVG8gaW5jbHVkZSBjb2RlIGZvciBwcmludGluZyB0aGUgaW50ZXJuYWwgdGFibGVzLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW4gREVCVUdfUFJJTlRfVEFCTEVTID0gZmFsc2U7Ci0KLSAgICAvKiogVG8gZGVidWcgaWRlbnRpZmllcnMgc2V0IHRvIHRydWUgYW5kIHJlY29tcGlsZS4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIERFQlVHX0lEUyA9IGZhbHNlOwotCi0gICAgLy8gcHJvdGVjdGVkCi0KLSAgICAvKiogQ2h1bmsgc2hpZnQuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBpbnQgQ0hVTktfU0hJRlQgPSA4OyAgICAgICAgICAgLy8gMl44ID0gMjU2Ci0KLSAgICAvKiogQ2h1bmsgc2l6ZS4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBDSFVOS19TSVpFID0gKDEgPDwgQ0hVTktfU0hJRlQpOwotCi0gICAgLyoqIENodW5rIG1hc2suICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBpbnQgQ0hVTktfTUFTSyA9IENIVU5LX1NJWkUgLSAxOwotCi0gICAgLyoqIEluaXRpYWwgY2h1bmsgc2l6ZS4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBJTklUSUFMX0NIVU5LX0NPVU5UID0gKDEgPDwgKDEzIC0gQ0hVTktfU0hJRlQpKTsgICAvLyAzMgotCi0gICAgLy8KLSAgICAvLyBEYXRhCi0gICAgLy8KLQotICAgIC8vIGxhenktZXZhbCBpbmZvcm1hdGlvbgotICAgIC8vIFRvIG1heGltaXplIG1lbW9yeSBjb25zdW1wdGlvbiB0aGUgYWN0dWFsIHNlbWFudGljIG9mIHRoZXNlIGZpZWxkcyB2YXJ5Ci0gICAgLy8gZGVwZW5kaW5nIG9uIHRoZSBub2RlIHR5cGUuCi0KLSAgICAvKiogTm9kZSBjb3VudC4gKi8KLSAgICBwcm90ZWN0ZWQgdHJhbnNpZW50IGludCBmTm9kZUNvdW50ID0gMDsKLQotICAgIC8qKiBOb2RlIHR5cGVzLiAqLwotICAgIHByb3RlY3RlZCB0cmFuc2llbnQgaW50IGZOb2RlVHlwZVtdW107Ci0KLSAgICAvKiogTm9kZSBuYW1lcy4gKi8KLSAgICBwcm90ZWN0ZWQgdHJhbnNpZW50IE9iamVjdCBmTm9kZU5hbWVbXVtdOwotCi0gICAgLyoqIE5vZGUgdmFsdWVzLiAqLwotICAgIHByb3RlY3RlZCB0cmFuc2llbnQgT2JqZWN0IGZOb2RlVmFsdWVbXVtdOwotCi0gICAgLyoqIE5vZGUgcGFyZW50cy4gKi8KLSAgICBwcm90ZWN0ZWQgdHJhbnNpZW50IGludCBmTm9kZVBhcmVudFtdW107Ci0KLSAgICAvKiogTm9kZSBmaXJzdCBjaGlsZHJlbi4gKi8KLSAgICBwcm90ZWN0ZWQgdHJhbnNpZW50IGludCBmTm9kZUxhc3RDaGlsZFtdW107Ci0KLSAgICAvKiogTm9kZSBwcmV2IHNpYmxpbmdzLiAqLwotICAgIHByb3RlY3RlZCB0cmFuc2llbnQgaW50IGZOb2RlUHJldlNpYltdW107Ci0KLSAgICAvKiogTm9kZSBuYW1lc3BhY2UgVVJJLiAqLwotICAgIHByb3RlY3RlZCB0cmFuc2llbnQgT2JqZWN0IGZOb2RlVVJJW11bXTsKLQotICAgIC8qKiBFeHRyYSBkYXRhLiAqLwotICAgIHByb3RlY3RlZCB0cmFuc2llbnQgaW50IGZOb2RlRXh0cmFbXVtdOwotCi0gICAgLyoqIElkZW50aWZpZXIgY291bnQuICovCi0gICAgcHJvdGVjdGVkIHRyYW5zaWVudCBpbnQgZklkQ291bnQ7Ci0KLSAgICAvKiogSWRlbnRpZmllciBuYW1lIGluZGV4ZXMuICovCi0gICAgcHJvdGVjdGVkIHRyYW5zaWVudCBTdHJpbmcgZklkTmFtZVtdOwotCi0gICAgLyoqIElkZW50aWZpZXIgZWxlbWVudCBpbmRleGVzLiAqLwotICAgIHByb3RlY3RlZCB0cmFuc2llbnQgaW50IGZJZEVsZW1lbnRbXTsKLQotICAgIC8qKiBET00yOiBGb3IgbmFtZXNwYWNlIHN1cHBvcnQgaW4gdGhlIGRlZmVycmVkIGNhc2UuCi0gICAgICovCi0gICAgLy8gSW1wbGVtZW50YXRpb24gTm90ZTogVGhlIGRlZmVycmVkIGVsZW1lbnQgYW5kIGF0dHJpYnV0ZSBtdXN0IGtub3cgaG93IHRvCi0gICAgLy8gaW50ZXJwcmV0IHRoZSBpbnQgcmVwcmVzZW50aW5nIHRoZSBxbmFtZS4KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBmTmFtZXNwYWNlc0VuYWJsZWQgPSBmYWxzZTsKLQotICAgIC8vCi0gICAgLy8gcHJpdmF0ZSBkYXRhCi0gICAgLy8KLSAgICBwcml2YXRlIHRyYW5zaWVudCBmaW5hbCBTdHJpbmdCdWlsZGVyIGZCdWZmZXJTdHIgPSBuZXcgU3RyaW5nQnVpbGRlcigpOwotICAgIHByaXZhdGUgdHJhbnNpZW50IGZpbmFsIEFycmF5TGlzdCBmU3RyQ2h1bmtzID0gbmV3IEFycmF5TGlzdCgpOwotCi0gICAgLy8KLSAgICAvLyBDb25zdHJ1Y3RvcnMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogTk9OLURPTTogQWN0dWFsbHkgY3JlYXRpbmcgYSBEb2N1bWVudCBpcyBvdXRzaWRlIHRoZSBET00ncyBzcGVjLAotICAgICAqIHNpbmNlIGl0IGhhcyB0byBvcGVyYXRlIGluIHRlcm1zIG9mIGEgcGFydGljdWxhciBpbXBsZW1lbnRhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgRGVmZXJyZWREb2N1bWVudEltcGwoKSB7Ci0gICAgICAgIHRoaXMoZmFsc2UpOwotICAgIH0gLy8gPGluaXQ+KCkKLQotICAgIC8qKgotICAgICAqIE5PTi1ET006IEFjdHVhbGx5IGNyZWF0aW5nIGEgRG9jdW1lbnQgaXMgb3V0c2lkZSB0aGUgRE9NJ3Mgc3BlYywKLSAgICAgKiBzaW5jZSBpdCBoYXMgdG8gb3BlcmF0ZSBpbiB0ZXJtcyBvZiBhIHBhcnRpY3VsYXIgaW1wbGVtZW50YXRpb24uCi0gICAgICovCi0gICAgcHVibGljIERlZmVycmVkRG9jdW1lbnRJbXBsKGJvb2xlYW4gbmFtZXNwYWNlc0VuYWJsZWQpIHsKLSAgICAgICAgdGhpcyhuYW1lc3BhY2VzRW5hYmxlZCwgZmFsc2UpOwotICAgIH0gLy8gPGluaXQ+KGJvb2xlYW4pCi0KLSAgICAvKiogRXhwZXJpbWVudGFsIGNvbnN0cnVjdG9yLiAqLwotICAgIHB1YmxpYyBEZWZlcnJlZERvY3VtZW50SW1wbChib29sZWFuIG5hbWVzcGFjZXMsIGJvb2xlYW4gZ3JhbW1hckFjY2VzcykgewotICAgICAgICBzdXBlcihncmFtbWFyQWNjZXNzKTsKLQotICAgICAgICBuZWVkc1N5bmNEYXRhKHRydWUpOwotICAgICAgICBuZWVkc1N5bmNDaGlsZHJlbih0cnVlKTsKLQotICAgICAgICBmTmFtZXNwYWNlc0VuYWJsZWQgPSBuYW1lc3BhY2VzOwotCi0gICAgfSAvLyA8aW5pdD4oYm9vbGVhbixib29sZWFuKQotCi0gICAgLy8KLSAgICAvLyBQdWJsaWMgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBSZXRyaWV2ZSBpbmZvcm1hdGlvbiBkZXNjcmliaW5nIHRoZSBhYmlsaXRpZXMgb2YgdGhpcyBwYXJ0aWN1bGFyCi0gICAgICogRE9NIGltcGxlbWVudGF0aW9uLiBJbnRlbmRlZCB0byBzdXBwb3J0IGFwcGxpY2F0aW9ucyB0aGF0IG1heSBiZQotICAgICAqIHVzaW5nIERPTXMgcmV0cmlldmVkIGZyb20gc2V2ZXJhbCBkaWZmZXJlbnQgc291cmNlcywgcG90ZW50aWFsbHkKLSAgICAgKiB3aXRoIGRpZmZlcmVudCB1bmRlcmx5aW5nIHJlcHJlc2VudGF0aW9ucy4KLSAgICAgKi8KLSAgICBwdWJsaWMgRE9NSW1wbGVtZW50YXRpb24gZ2V0SW1wbGVtZW50YXRpb24oKSB7Ci0gICAgICAgIC8vIEN1cnJlbnRseSBpbXBsZW1lbnRlZCBhcyBhIHNpbmdsZXRvbiwgc2luY2UgaXQncyBoYXJkY29kZWQKLSAgICAgICAgLy8gaW5mb3JtYXRpb24gYW55d2F5LgotICAgICAgICByZXR1cm4gRGVmZXJyZWRET01JbXBsZW1lbnRhdGlvbkltcGwuZ2V0RE9NSW1wbGVtZW50YXRpb24oKTsKLSAgICB9Ci0KLSAgICAvKiogUmV0dXJucyB0aGUgY2FjaGVkIHBhcnNlci5nZXROYW1lc3BhY2VzKCkgdmFsdWUuKi8KLSAgICBib29sZWFuIGdldE5hbWVzcGFjZXNFbmFibGVkKCkgewotICAgICAgICByZXR1cm4gZk5hbWVzcGFjZXNFbmFibGVkOwotICAgIH0KLQotICAgIHZvaWQgc2V0TmFtZXNwYWNlc0VuYWJsZWQoYm9vbGVhbiBlbmFibGUpIHsKLSAgICAgICAgZk5hbWVzcGFjZXNFbmFibGVkID0gZW5hYmxlOwotICAgIH0KLQotICAgIC8vIGludGVybmFsIGZhY3RvcnkgbWV0aG9kcwotCi0gICAgLyoqIENyZWF0ZXMgYSBkb2N1bWVudCBub2RlIGluIHRoZSB0YWJsZS4gKi8KLSAgICBwdWJsaWMgaW50IGNyZWF0ZURlZmVycmVkRG9jdW1lbnQoKSB7Ci0gICAgICAgIGludCBub2RlSW5kZXggPSBjcmVhdGVOb2RlKE5vZGUuRE9DVU1FTlRfTk9ERSk7Ci0gICAgICAgIHJldHVybiBub2RlSW5kZXg7Ci0gICAgfQotCi0gICAgLyoqIENyZWF0ZXMgYSBkb2N0eXBlLiAqLwotICAgIHB1YmxpYyBpbnQgY3JlYXRlRGVmZXJyZWREb2N1bWVudFR5cGUoU3RyaW5nIHJvb3RFbGVtZW50TmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkKSB7Ci0KLSAgICAgICAgLy8gY3JlYXRlIG5vZGUKLSAgICAgICAgaW50IG5vZGVJbmRleCA9IGNyZWF0ZU5vZGUoTm9kZS5ET0NVTUVOVF9UWVBFX05PREUpOwotICAgICAgICBpbnQgY2h1bmsgICAgID0gbm9kZUluZGV4ID4+IENIVU5LX1NISUZUOwotICAgICAgICBpbnQgaW5kZXggICAgID0gbm9kZUluZGV4ICYgQ0hVTktfTUFTSzsKLQotICAgICAgICAvLyBzYXZlIG5hbWUsIHB1YmxpYyBpZCwgc3lzdGVtIGlkCi0gICAgICAgIHNldENodW5rVmFsdWUoZk5vZGVOYW1lLCByb290RWxlbWVudE5hbWUsIGNodW5rLCBpbmRleCk7Ci0gICAgICAgIHNldENodW5rVmFsdWUoZk5vZGVWYWx1ZSwgcHVibGljSWQsIGNodW5rLCBpbmRleCk7Ci0gICAgICAgIHNldENodW5rVmFsdWUoZk5vZGVVUkksIHN5c3RlbUlkLCBjaHVuaywgaW5kZXgpOwotCi0gICAgICAgIC8vIHJldHVybiBub2RlIGluZGV4Ci0gICAgICAgIHJldHVybiBub2RlSW5kZXg7Ci0KLSAgICB9IC8vIGNyZWF0ZURlZmVycmVkRG9jdW1lbnRUeXBlKFN0cmluZyxTdHJpbmcsU3RyaW5nKTppbnQKLQotICAgIHB1YmxpYyB2b2lkIHNldEludGVybmFsU3Vic2V0KGludCBkb2N0eXBlSW5kZXgsIFN0cmluZyBzdWJzZXQpIHsKLSAgICAgICAgaW50IGNodW5rICAgICA9IGRvY3R5cGVJbmRleCA+PiBDSFVOS19TSElGVDsKLSAgICAgICAgaW50IGluZGV4ICAgICA9IGRvY3R5cGVJbmRleCAmIENIVU5LX01BU0s7Ci0KLSAgICAgICAgLy8gY3JlYXRlIGV4dHJhIGRhdGEgbm9kZSB0byBzdG9yZSBpbnRlcm5hbCBzdWJzZXQKLSAgICAgICAgaW50IGV4dHJhRGF0YUluZGV4ID0gY3JlYXRlTm9kZShOb2RlLkRPQ1VNRU5UX1RZUEVfTk9ERSk7Ci0gICAgICAgIGludCBlY2h1bmsgPSBleHRyYURhdGFJbmRleCA+PiBDSFVOS19TSElGVDsKLSAgICAgICAgaW50IGVpbmRleCA9IGV4dHJhRGF0YUluZGV4ICYgQ0hVTktfTUFTSzsKLSAgICAgICAgc2V0Q2h1bmtJbmRleChmTm9kZUV4dHJhLCBleHRyYURhdGFJbmRleCwgY2h1bmssIGluZGV4KTsKLSAgICAgICAgc2V0Q2h1bmtWYWx1ZShmTm9kZVZhbHVlLCBzdWJzZXQsIGVjaHVuaywgZWluZGV4KTsKLSAgICB9Ci0KLSAgICAvKiogQ3JlYXRlcyBhIG5vdGF0aW9uIGluIHRoZSB0YWJsZS4gKi8KLSAgICBwdWJsaWMgaW50IGNyZWF0ZURlZmVycmVkTm90YXRpb24oU3RyaW5nIG5vdGF0aW9uTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHB1YmxpY0lkLCBTdHJpbmcgc3lzdGVtSWQsIFN0cmluZyBiYXNlVVJJKSB7Ci0KLSAgICAgICAgLy8gY3JlYXRlIG5vZGUKLSAgICAgICAgaW50IG5vZGVJbmRleCA9IGNyZWF0ZU5vZGUoTm9kZS5OT1RBVElPTl9OT0RFKTsKLSAgICAgICAgaW50IGNodW5rICAgICA9IG5vZGVJbmRleCA+PiBDSFVOS19TSElGVDsKLSAgICAgICAgaW50IGluZGV4ICAgICA9IG5vZGVJbmRleCAmIENIVU5LX01BU0s7Ci0KLQotICAgICAgICAvLyBjcmVhdGUgZXh0cmEgZGF0YSBub2RlCi0gICAgICAgIGludCBleHRyYURhdGFJbmRleCA9IGNyZWF0ZU5vZGUoTm9kZS5OT1RBVElPTl9OT0RFKTsKLSAgICAgICAgaW50IGVjaHVuayA9IGV4dHJhRGF0YUluZGV4ID4+IENIVU5LX1NISUZUOwotICAgICAgICBpbnQgZWluZGV4ID0gZXh0cmFEYXRhSW5kZXggJiBDSFVOS19NQVNLOwotCi0gICAgICAgIC8vIHNhdmUgbmFtZSwgcHVibGljIGlkLCBzeXN0ZW0gaWQsIGFuZCBub3RhdGlvbiBuYW1lCi0gICAgICAgIHNldENodW5rVmFsdWUoZk5vZGVOYW1lLCBub3RhdGlvbk5hbWUsIGNodW5rLCBpbmRleCk7Ci0gICAgICAgIHNldENodW5rVmFsdWUoZk5vZGVWYWx1ZSwgcHVibGljSWQsIGNodW5rLCBpbmRleCk7Ci0gICAgICAgIHNldENodW5rVmFsdWUoZk5vZGVVUkksIHN5c3RlbUlkLCBjaHVuaywgaW5kZXgpOwotCi0gICAgICAgIC8vIGluIGV4dHJhIGRhdGEgbm9kZSBzZXQgYmFzZVVSSSB2YWx1ZQotICAgICAgICBzZXRDaHVua0luZGV4KGZOb2RlRXh0cmEsIGV4dHJhRGF0YUluZGV4LCBjaHVuaywgaW5kZXgpOwotICAgICAgICBzZXRDaHVua1ZhbHVlKGZOb2RlTmFtZSwgYmFzZVVSSSwgZWNodW5rLCBlaW5kZXgpOwotCi0gICAgICAgIC8vIHJldHVybiBub2RlIGluZGV4Ci0gICAgICAgIHJldHVybiBub2RlSW5kZXg7Ci0KLSAgICB9IC8vIGNyZWF0ZURlZmVycmVkTm90YXRpb24oU3RyaW5nLFN0cmluZyxTdHJpbmcpOmludAotCi0gICAgLyoqIENyZWF0ZXMgYW4gZW50aXR5IGluIHRoZSB0YWJsZS4gKi8KLSAgICBwdWJsaWMgaW50IGNyZWF0ZURlZmVycmVkRW50aXR5KFN0cmluZyBlbnRpdHlOYW1lLCBTdHJpbmcgcHVibGljSWQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgc3lzdGVtSWQsIFN0cmluZyBub3RhdGlvbk5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgYmFzZVVSSSkgewotICAgICAgICAvLyBjcmVhdGUgbm9kZQotICAgICAgICBpbnQgbm9kZUluZGV4ID0gY3JlYXRlTm9kZShOb2RlLkVOVElUWV9OT0RFKTsKLSAgICAgICAgaW50IGNodW5rICAgICA9IG5vZGVJbmRleCA+PiBDSFVOS19TSElGVDsKLSAgICAgICAgaW50IGluZGV4ICAgICA9IG5vZGVJbmRleCAmIENIVU5LX01BU0s7Ci0KLSAgICAgICAgLy8gY3JlYXRlIGV4dHJhIGRhdGEgbm9kZQotICAgICAgICBpbnQgZXh0cmFEYXRhSW5kZXggPSBjcmVhdGVOb2RlKE5vZGUuRU5USVRZX05PREUpOwotICAgICAgICBpbnQgZWNodW5rID0gZXh0cmFEYXRhSW5kZXggPj4gQ0hVTktfU0hJRlQ7Ci0gICAgICAgIGludCBlaW5kZXggPSBleHRyYURhdGFJbmRleCAmIENIVU5LX01BU0s7Ci0KLSAgICAgICAgLy8gc2F2ZSBuYW1lLCBwdWJsaWMgaWQsIHN5c3RlbSBpZCwgYW5kIG5vdGF0aW9uIG5hbWUKLSAgICAgICAgc2V0Q2h1bmtWYWx1ZShmTm9kZU5hbWUsIGVudGl0eU5hbWUsIGNodW5rLCBpbmRleCk7Ci0gICAgICAgIHNldENodW5rVmFsdWUoZk5vZGVWYWx1ZSwgcHVibGljSWQsIGNodW5rLCBpbmRleCk7Ci0gICAgICAgIHNldENodW5rVmFsdWUoZk5vZGVVUkksIHN5c3RlbUlkLCBjaHVuaywgaW5kZXgpOwotICAgICAgICBzZXRDaHVua0luZGV4KGZOb2RlRXh0cmEsIGV4dHJhRGF0YUluZGV4LCBjaHVuaywgaW5kZXgpOwotICAgICAgICAvLyBzZXQgb3RoZXIgdmFsdWVzIGluIHRoZSBleHRyYSBjaHVuawotICAgICAgICAvLyBub3RhdGlvbgotICAgICAgICBzZXRDaHVua1ZhbHVlKGZOb2RlTmFtZSwgbm90YXRpb25OYW1lLCBlY2h1bmssIGVpbmRleCk7Ci0gICAgICAgIC8vIHZlcnNpb24gIEwzCi0gICAgICAgIHNldENodW5rVmFsdWUoZk5vZGVWYWx1ZSwgbnVsbCwgZWNodW5rLCBlaW5kZXgpOwotICAgICAgICAvLyBlbmNvZGluZyBMMwotICAgICAgICBzZXRDaHVua1ZhbHVlKGZOb2RlVVJJLCBudWxsLCBlY2h1bmssIGVpbmRleCk7Ci0KLQotICAgICAgICBpbnQgZXh0cmFEYXRhSW5kZXgyID0gY3JlYXRlTm9kZShOb2RlLkVOVElUWV9OT0RFKTsKLSAgICAgICAgaW50IGVjaHVuazIgPSBleHRyYURhdGFJbmRleDIgPj4gQ0hVTktfU0hJRlQ7Ci0gICAgICAgIGludCBlaW5kZXgyID0gZXh0cmFEYXRhSW5kZXgyICYgQ0hVTktfTUFTSzsKLQotICAgICAgICBzZXRDaHVua0luZGV4KGZOb2RlRXh0cmEsIGV4dHJhRGF0YUluZGV4MiwgZWNodW5rLCBlaW5kZXgpOwotCi0gICAgICAgIC8vIGJhc2VVUkkKLSAgICAgICAgc2V0Q2h1bmtWYWx1ZShmTm9kZU5hbWUsIGJhc2VVUkksIGVjaHVuazIsIGVpbmRleDIpOwotCi0gICAgICAgIC8vIHJldHVybiBub2RlIGluZGV4Ci0gICAgICAgIHJldHVybiBub2RlSW5kZXg7Ci0KLSAgICB9IC8vIGNyZWF0ZURlZmVycmVkRW50aXR5KFN0cmluZyxTdHJpbmcsU3RyaW5nLFN0cmluZyk6aW50Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldERlZmVycmVkRW50aXR5QmFzZVVSSSAoaW50IGVudGl0eUluZGV4KXsKLSAgICAgICAgaWYgKGVudGl0eUluZGV4ICE9IC0xKSB7Ci0gICAgICAgICAgICBpbnQgZXh0cmFEYXRhSW5kZXggPSBnZXROb2RlRXh0cmEoZW50aXR5SW5kZXgsIGZhbHNlKTsKLSAgICAgICAgICAgIGV4dHJhRGF0YUluZGV4ID0gZ2V0Tm9kZUV4dHJhKGV4dHJhRGF0YUluZGV4LCBmYWxzZSk7Ci0gICAgICAgICAgICByZXR1cm4gZ2V0Tm9kZU5hbWUgKGV4dHJhRGF0YUluZGV4LCBmYWxzZSk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLy8gRE9NIExldmVsIDM6IHNldHRpbmcgZW5jb2RpbmcgYW5kIHZlcnNpb24KLSAgICBwdWJsaWMgdm9pZCBzZXRFbnRpdHlJbmZvKGludCBjdXJyZW50RW50aXR5RGVjbCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyB2ZXJzaW9uLCBTdHJpbmcgZW5jb2RpbmcpewotICAgICAgICBpbnQgZU5vZGVJbmRleCA9IGdldE5vZGVFeHRyYShjdXJyZW50RW50aXR5RGVjbCwgZmFsc2UpOwotICAgICAgICBpZiAoZU5vZGVJbmRleCAhPS0xKSB7Ci0gICAgICAgICAgICBpbnQgZWNodW5rID0gZU5vZGVJbmRleCA+PiBDSFVOS19TSElGVDsKLSAgICAgICAgICAgIGludCBlaW5kZXggPSBlTm9kZUluZGV4ICYgQ0hVTktfTUFTSzsKLSAgICAgICAgICAgIHNldENodW5rVmFsdWUoZk5vZGVWYWx1ZSwgdmVyc2lvbiwgZWNodW5rLCBlaW5kZXgpOwotICAgICAgICAgICAgc2V0Q2h1bmtWYWx1ZShmTm9kZVVSSSwgZW5jb2RpbmcsIGVjaHVuaywgZWluZGV4KTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8vIERPTSBMZXZlbCAzOiBzZXRzIGVsZW1lbnQgVHlwZUluZm8KLSAgICBwdWJsaWMgdm9pZCBzZXRUeXBlSW5mbyhpbnQgZWxlbWVudE5vZGVJbmRleCwgT2JqZWN0IHR5cGUpIHsKLSAgICAgICAgaW50IGVsZW1lbnRDaHVuayAgICAgPSBlbGVtZW50Tm9kZUluZGV4ID4+IENIVU5LX1NISUZUOwotICAgICAgICBpbnQgZWxlbWVudEluZGV4ICAgICA9IGVsZW1lbnROb2RlSW5kZXggJiBDSFVOS19NQVNLOwotICAgICAgICBzZXRDaHVua1ZhbHVlKGZOb2RlVmFsdWUsIHR5cGUsIGVsZW1lbnRDaHVuaywgZWxlbWVudEluZGV4KTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBET00gSW50ZXJuYWwKLSAgICAgKgotICAgICAqIEFuIGF0dHJpYnV0ZSBzcGVjaWZ5aW5nIHRoZSBhY3R1YWwgZW5jb2Rpbmcgb2YgdGhpcyBkb2N1bWVudC4gVGhpcyBpcwotICAgICAqIDxjb2RlPm51bGw8L2NvZGU+IG90aGVyd2lzZS4KLSAgICAgKiA8YnI+IFRoaXMgYXR0cmlidXRlIHJlcHJlc2VudHMgdGhlIHByb3BlcnR5IFtjaGFyYWN0ZXIgZW5jb2Rpbmcgc2NoZW1lXQotICAgICAqIGRlZmluZWQgaW4gLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldElucHV0RW5jb2RpbmcoaW50IGN1cnJlbnRFbnRpdHlEZWNsLCBTdHJpbmcgdmFsdWUpewotICAgICAgICAvLyBnZXQgZmlyc3QgZXh0cmEgZGF0YSBjaHVuawotICAgICAgICBpbnQgbm9kZUluZGV4ID0gZ2V0Tm9kZUV4dHJhKGN1cnJlbnRFbnRpdHlEZWNsLCBmYWxzZSk7Ci0gICAgICAgIC8vIGdldCBzZWNvbmQgZXh0cmEgZGF0YSBjaHVuawotICAgICAgICBpbnQgZXh0cmFEYXRhSW5kZXggPSBnZXROb2RlRXh0cmEobm9kZUluZGV4LCBmYWxzZSk7Ci0KLSAgICAgICAgaW50IGVjaHVuayA9IGV4dHJhRGF0YUluZGV4ID4+IENIVU5LX1NISUZUOwotICAgICAgICBpbnQgZWluZGV4ID0gZXh0cmFEYXRhSW5kZXggJiBDSFVOS19NQVNLOwotCi0gICAgICAgIHNldENodW5rVmFsdWUoZk5vZGVWYWx1ZSwgdmFsdWUsIGVjaHVuaywgZWluZGV4KTsKLQotICAgIH0KLQotICAgIC8qKiBDcmVhdGVzIGFuIGVudGl0eSByZWZlcmVuY2Ugbm9kZSBpbiB0aGUgdGFibGUuICovCi0gICAgcHVibGljIGludCBjcmVhdGVEZWZlcnJlZEVudGl0eVJlZmVyZW5jZShTdHJpbmcgbmFtZSwgU3RyaW5nIGJhc2VVUkkpIHsKLQotICAgICAgICAvLyBjcmVhdGUgbm9kZQotICAgICAgICBpbnQgbm9kZUluZGV4ID0gY3JlYXRlTm9kZShOb2RlLkVOVElUWV9SRUZFUkVOQ0VfTk9ERSk7Ci0gICAgICAgIGludCBjaHVuayAgICAgPSBub2RlSW5kZXggPj4gQ0hVTktfU0hJRlQ7Ci0gICAgICAgIGludCBpbmRleCAgICAgPSBub2RlSW5kZXggJiBDSFVOS19NQVNLOwotICAgICAgICBzZXRDaHVua1ZhbHVlKGZOb2RlTmFtZSwgbmFtZSwgY2h1bmssIGluZGV4KTsKLSAgICAgICAgc2V0Q2h1bmtWYWx1ZShmTm9kZVZhbHVlLCBiYXNlVVJJLCBjaHVuaywgaW5kZXgpOwotCi0gICAgICAgIC8vIHJldHVybiBub2RlIGluZGV4Ci0gICAgICAgIHJldHVybiBub2RlSW5kZXg7Ci0KLSAgICB9IC8vIGNyZWF0ZURlZmVycmVkRW50aXR5UmVmZXJlbmNlKFN0cmluZyk6aW50Ci0KLQotICAgIC8qKgotICAgICAqIENyZWF0ZXMgYW4gZWxlbWVudCBub2RlIHdpdGggYSBVUkkgaW4gdGhlIHRhYmxlIGFuZCB0eXBlIGluZm9ybWF0aW9uLgotICAgICAqIEBkZXByZWNhdGVkCi0gICAgICovCi0gICAgcHVibGljIGludCBjcmVhdGVEZWZlcnJlZEVsZW1lbnQoU3RyaW5nIGVsZW1lbnRVUkksIFN0cmluZyBlbGVtZW50TmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT2JqZWN0IHR5cGUpIHsKLQotICAgICAgICAvLyBjcmVhdGUgbm9kZQotICAgICAgICBpbnQgZWxlbWVudE5vZGVJbmRleCA9IGNyZWF0ZU5vZGUoTm9kZS5FTEVNRU5UX05PREUpOwotICAgICAgICBpbnQgZWxlbWVudENodW5rICAgICA9IGVsZW1lbnROb2RlSW5kZXggPj4gQ0hVTktfU0hJRlQ7Ci0gICAgICAgIGludCBlbGVtZW50SW5kZXggICAgID0gZWxlbWVudE5vZGVJbmRleCAmIENIVU5LX01BU0s7Ci0gICAgICAgIHNldENodW5rVmFsdWUoZk5vZGVOYW1lLCBlbGVtZW50TmFtZSwgZWxlbWVudENodW5rLCBlbGVtZW50SW5kZXgpOwotICAgICAgICBzZXRDaHVua1ZhbHVlKGZOb2RlVVJJLCBlbGVtZW50VVJJLCBlbGVtZW50Q2h1bmssIGVsZW1lbnRJbmRleCk7Ci0gICAgICAgIHNldENodW5rVmFsdWUoZk5vZGVWYWx1ZSwgdHlwZSwgZWxlbWVudENodW5rLCBlbGVtZW50SW5kZXgpOwotCi0gICAgICAgIC8vIHJldHVybiBub2RlIGluZGV4Ci0gICAgICAgIHJldHVybiBlbGVtZW50Tm9kZUluZGV4OwotCi0gICAgfSAvLyBjcmVhdGVEZWZlcnJlZEVsZW1lbnQoU3RyaW5nLFN0cmluZyxPYmplY3QpOmludAotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlcyBhbiBlbGVtZW50IG5vZGUgaW4gdGhlIHRhYmxlLgotICAgICAqIEBkZXByZWNhdGVkCi0gICAgICovCi0gICAgcHVibGljIGludCBjcmVhdGVEZWZlcnJlZEVsZW1lbnQoU3RyaW5nIGVsZW1lbnROYW1lKSB7Ci0gICAgICAgIHJldHVybiBjcmVhdGVEZWZlcnJlZEVsZW1lbnQobnVsbCwgZWxlbWVudE5hbWUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENyZWF0ZXMgYW4gZWxlbWVudCBub2RlIHdpdGggYSBVUkkgaW4gdGhlIHRhYmxlLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgY3JlYXRlRGVmZXJyZWRFbGVtZW50KFN0cmluZyBlbGVtZW50VVJJLCBTdHJpbmcgZWxlbWVudE5hbWUpIHsKLQotICAgICAgICAvLyBjcmVhdGUgbm9kZQotICAgICAgICBpbnQgZWxlbWVudE5vZGVJbmRleCA9IGNyZWF0ZU5vZGUoTm9kZS5FTEVNRU5UX05PREUpOwotICAgICAgICBpbnQgZWxlbWVudENodW5rICAgICA9IGVsZW1lbnROb2RlSW5kZXggPj4gQ0hVTktfU0hJRlQ7Ci0gICAgICAgIGludCBlbGVtZW50SW5kZXggICAgID0gZWxlbWVudE5vZGVJbmRleCAmIENIVU5LX01BU0s7Ci0gICAgICAgIHNldENodW5rVmFsdWUoZk5vZGVOYW1lLCBlbGVtZW50TmFtZSwgZWxlbWVudENodW5rLCBlbGVtZW50SW5kZXgpOwotICAgICAgICBzZXRDaHVua1ZhbHVlKGZOb2RlVVJJLCBlbGVtZW50VVJJLCBlbGVtZW50Q2h1bmssIGVsZW1lbnRJbmRleCk7Ci0KLSAgICAgICAgLy8gcmV0dXJuIG5vZGUgaW5kZXgKLSAgICAgICAgcmV0dXJuIGVsZW1lbnROb2RlSW5kZXg7Ci0KLSAgICB9IC8vIGNyZWF0ZURlZmVycmVkRWxlbWVudChTdHJpbmcsU3RyaW5nKTppbnQKLQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBUaGlzIG1ldGhvZCBpcyB1c2VkIGJ5IHRoZSBET01QYXJzZXIgdG8gY3JlYXRlIGF0dHJpYnV0ZXMuCi0gICAgICAgICAqIEBwYXJhbSBlbGVtZW50Tm9kZUluZGV4Ci0gICAgICAgICAqIEBwYXJhbSBhdHRyTmFtZQotICAgICAgICAgKiBAcGFyYW0gYXR0clVSSQotICAgICAgICAgKiBAcGFyYW0gYXR0clZhbHVlCi0gICAgICAgICAqIEBwYXJhbSBzcGVjaWZpZWQKLSAgICAgICAgICogQHBhcmFtIGlkCi0gICAgICAgICAqIEBwYXJhbSB0eXBlCi0gICAgICAgICAqIEByZXR1cm4gaW50Ci0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgaW50IHNldERlZmVycmVkQXR0cmlidXRlKGludCBlbGVtZW50Tm9kZUluZGV4LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBhdHRyTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgYXR0clVSSSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgYXR0clZhbHVlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gc3BlY2lmaWVkLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gaWQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT2JqZWN0IHR5cGUpIHsKLQotICAgICAgICAgICAgICAgIC8vIGNyZWF0ZSBhdHRyaWJ1dGUKLSAgICAgICAgICAgICAgICBpbnQgYXR0ck5vZGVJbmRleCA9IGNyZWF0ZURlZmVycmVkQXR0cmlidXRlKGF0dHJOYW1lLCBhdHRyVVJJLCBhdHRyVmFsdWUsIHNwZWNpZmllZCk7Ci0gICAgICAgICAgICAgICAgaW50IGF0dHJDaHVuayA9IGF0dHJOb2RlSW5kZXggPj4gQ0hVTktfU0hJRlQ7Ci0gICAgICAgICAgICAgICAgaW50IGF0dHJJbmRleCA9IGF0dHJOb2RlSW5kZXggJiBDSFVOS19NQVNLOwotICAgICAgICAgICAgICAgIC8vIHNldCBhdHRyaWJ1dGUncyBwYXJlbnQgdG8gZWxlbWVudAotICAgICAgICAgICAgICAgIHNldENodW5rSW5kZXgoZk5vZGVQYXJlbnQsIGVsZW1lbnROb2RlSW5kZXgsIGF0dHJDaHVuaywgYXR0ckluZGV4KTsKLQotICAgICAgICAgICAgICAgIGludCBlbGVtZW50Q2h1bmsgPSBlbGVtZW50Tm9kZUluZGV4ID4+IENIVU5LX1NISUZUOwotICAgICAgICAgICAgICAgIGludCBlbGVtZW50SW5kZXggPSBlbGVtZW50Tm9kZUluZGV4ICYgQ0hVTktfTUFTSzsKLQotICAgICAgICAgICAgICAgIC8vIGdldCBlbGVtZW50J3MgbGFzdCBhdHRyaWJ1dGUKLSAgICAgICAgICAgICAgICBpbnQgbGFzdEF0dHJOb2RlSW5kZXggPSBnZXRDaHVua0luZGV4KGZOb2RlRXh0cmEsIGVsZW1lbnRDaHVuaywgZWxlbWVudEluZGV4KTsKLSAgICAgICAgICAgICAgICBpZiAobGFzdEF0dHJOb2RlSW5kZXggIT0gMCkgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gYWRkIGxpbmsgZnJvbSBuZXcgYXR0cmlidXRlIHRvIGxhc3QgYXR0cmlidXRlCi0gICAgICAgICAgICAgICAgICAgICAgICBzZXRDaHVua0luZGV4KGZOb2RlUHJldlNpYiwgbGFzdEF0dHJOb2RlSW5kZXgsIGF0dHJDaHVuaywgYXR0ckluZGV4KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLy8gYWRkIGxpbmsgZnJvbSBlbGVtZW50IHRvIG5ldyBsYXN0IGF0dHJpYnV0ZQotICAgICAgICAgICAgICAgIHNldENodW5rSW5kZXgoZk5vZGVFeHRyYSwgYXR0ck5vZGVJbmRleCwgZWxlbWVudENodW5rLCBlbGVtZW50SW5kZXgpOwotCi0gICAgICAgICAgICAgICAgaW50IGV4dHJhID0gZ2V0Q2h1bmtJbmRleChmTm9kZUV4dHJhLCBhdHRyQ2h1bmssIGF0dHJJbmRleCk7Ci0gICAgICAgICAgICAgICAgaWYgKGlkKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBleHRyYSA9IGV4dHJhIHwgSUQ7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzZXRDaHVua0luZGV4KGZOb2RlRXh0cmEsIGV4dHJhLCBhdHRyQ2h1bmssIGF0dHJJbmRleCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdmFsdWUgPSBnZXRDaHVua1ZhbHVlKGZOb2RlVmFsdWUsIGF0dHJDaHVuaywgYXR0ckluZGV4KTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHB1dElkZW50aWZpZXIodmFsdWUsIGVsZW1lbnROb2RlSW5kZXgpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvLyBzdG9yZSB0eXBlIGluZm9ybWF0aW9uCi0gICAgICAgICAgICAgICAgaWYgKHR5cGUgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgaW50IGV4dHJhRGF0YUluZGV4ID0gY3JlYXRlTm9kZShEZWZlcnJlZE5vZGUuVFlQRV9OT0RFKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGludCBlY2h1bmsgPSBleHRyYURhdGFJbmRleCA+PiBDSFVOS19TSElGVDsKLSAgICAgICAgICAgICAgICAgICAgICAgIGludCBlaW5kZXggPSBleHRyYURhdGFJbmRleCAmIENIVU5LX01BU0s7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIHNldENodW5rSW5kZXgoZk5vZGVMYXN0Q2hpbGQsIGV4dHJhRGF0YUluZGV4LCBhdHRyQ2h1bmssIGF0dHJJbmRleCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzZXRDaHVua1ZhbHVlKGZOb2RlVmFsdWUsIHR5cGUsIGVjaHVuaywgZWluZGV4KTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyByZXR1cm4gbm9kZSBpbmRleAotICAgICAgICAgICAgICAgIHJldHVybiBhdHRyTm9kZUluZGV4OwotICAgICAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXRzIGFuIGF0dHJpYnV0ZSBvbiBhbiBlbGVtZW50IG5vZGUuCi0gICAgICogQGRlcHJlY2F0ZWQKLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IHNldERlZmVycmVkQXR0cmlidXRlKGludCBlbGVtZW50Tm9kZUluZGV4LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGF0dHJOYW1lLCBTdHJpbmcgYXR0clVSSSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBhdHRyVmFsdWUsIGJvb2xlYW4gc3BlY2lmaWVkKSB7Ci0gICAgICAgIC8vIGNyZWF0ZSBhdHRyaWJ1dGUKLSAgICAgICAgaW50IGF0dHJOb2RlSW5kZXggPSBjcmVhdGVEZWZlcnJlZEF0dHJpYnV0ZShhdHRyTmFtZSwgYXR0clVSSSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyVmFsdWUsIHNwZWNpZmllZCk7Ci0gICAgICAgIGludCBhdHRyQ2h1bmsgPSBhdHRyTm9kZUluZGV4ID4+IENIVU5LX1NISUZUOwotICAgICAgICBpbnQgYXR0ckluZGV4ICA9IGF0dHJOb2RlSW5kZXggJiBDSFVOS19NQVNLOwotICAgICAgICAvLyBzZXQgYXR0cmlidXRlJ3MgcGFyZW50IHRvIGVsZW1lbnQKLSAgICAgICAgc2V0Q2h1bmtJbmRleChmTm9kZVBhcmVudCwgZWxlbWVudE5vZGVJbmRleCwgYXR0ckNodW5rLCBhdHRySW5kZXgpOwotCi0gICAgICAgIGludCBlbGVtZW50Q2h1bmsgICAgID0gZWxlbWVudE5vZGVJbmRleCA+PiBDSFVOS19TSElGVDsKLSAgICAgICAgaW50IGVsZW1lbnRJbmRleCAgICAgPSBlbGVtZW50Tm9kZUluZGV4ICYgQ0hVTktfTUFTSzsKLQotICAgICAgICAvLyBnZXQgZWxlbWVudCdzIGxhc3QgYXR0cmlidXRlCi0gICAgICAgIGludCBsYXN0QXR0ck5vZGVJbmRleCA9IGdldENodW5rSW5kZXgoZk5vZGVFeHRyYSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50Q2h1bmssIGVsZW1lbnRJbmRleCk7Ci0gICAgICAgIGlmIChsYXN0QXR0ck5vZGVJbmRleCAhPSAwKSB7Ci0gICAgICAgICAgICAvLyBhZGQgbGluayBmcm9tIG5ldyBhdHRyaWJ1dGUgdG8gbGFzdCBhdHRyaWJ1dGUKLSAgICAgICAgICAgIHNldENodW5rSW5kZXgoZk5vZGVQcmV2U2liLCBsYXN0QXR0ck5vZGVJbmRleCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0ckNodW5rLCBhdHRySW5kZXgpOwotICAgICAgICB9Ci0gICAgICAgIC8vIGFkZCBsaW5rIGZyb20gZWxlbWVudCB0byBuZXcgbGFzdCBhdHRyaWJ1dGUKLSAgICAgICAgc2V0Q2h1bmtJbmRleChmTm9kZUV4dHJhLCBhdHRyTm9kZUluZGV4LAotICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRDaHVuaywgZWxlbWVudEluZGV4KTsKLQotICAgICAgICAvLyByZXR1cm4gbm9kZSBpbmRleAotICAgICAgICByZXR1cm4gYXR0ck5vZGVJbmRleDsKLQotICAgIH0gLy8gc2V0RGVmZXJyZWRBdHRyaWJ1dGUoaW50LFN0cmluZyxTdHJpbmcsU3RyaW5nLGJvb2xlYW4pOmludAotCi0gICAgLyoqIENyZWF0ZXMgYW4gYXR0cmlidXRlIGluIHRoZSB0YWJsZS4gKi8KLSAgICBwdWJsaWMgaW50IGNyZWF0ZURlZmVycmVkQXR0cmlidXRlKFN0cmluZyBhdHRyTmFtZSwgU3RyaW5nIGF0dHJWYWx1ZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gc3BlY2lmaWVkKSB7Ci0gICAgICAgIHJldHVybiBjcmVhdGVEZWZlcnJlZEF0dHJpYnV0ZShhdHRyTmFtZSwgbnVsbCwgYXR0clZhbHVlLCBzcGVjaWZpZWQpOwotICAgIH0KLQotICAgIC8qKiBDcmVhdGVzIGFuIGF0dHJpYnV0ZSB3aXRoIGEgVVJJIGluIHRoZSB0YWJsZS4gKi8KLSAgICBwdWJsaWMgaW50IGNyZWF0ZURlZmVycmVkQXR0cmlidXRlKFN0cmluZyBhdHRyTmFtZSwgU3RyaW5nIGF0dHJVUkksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgYXR0clZhbHVlLCBib29sZWFuIHNwZWNpZmllZCkgewotCi0gICAgICAgIC8vIGNyZWF0ZSBub2RlCi0gICAgICAgIGludCBub2RlSW5kZXggPSBjcmVhdGVOb2RlKE5vZGVJbXBsLkFUVFJJQlVURV9OT0RFKTsKLSAgICAgICAgaW50IGNodW5rID0gbm9kZUluZGV4ID4+IENIVU5LX1NISUZUOwotICAgICAgICBpbnQgaW5kZXggPSBub2RlSW5kZXggJiBDSFVOS19NQVNLOwotICAgICAgICBzZXRDaHVua1ZhbHVlKGZOb2RlTmFtZSwgYXR0ck5hbWUsIGNodW5rLCBpbmRleCk7Ci0gICAgICAgIHNldENodW5rVmFsdWUoZk5vZGVVUkksIGF0dHJVUkksIGNodW5rLCBpbmRleCk7Ci0gICAgICAgIHNldENodW5rVmFsdWUoZk5vZGVWYWx1ZSwgYXR0clZhbHVlLCBjaHVuaywgaW5kZXgpOwotICAgICAgICBpbnQgZXh0cmEgPSBzcGVjaWZpZWQgPyBTUEVDSUZJRUQgOiAwOwotICAgICAgICBzZXRDaHVua0luZGV4KGZOb2RlRXh0cmEsIGV4dHJhLCBjaHVuaywgaW5kZXgpOwotCi0gICAgICAgIC8vIHJldHVybiBub2RlIGluZGV4Ci0gICAgICAgIHJldHVybiBub2RlSW5kZXg7Ci0KLSAgICB9IC8vIGNyZWF0ZURlZmVycmVkQXR0cmlidXRlKFN0cmluZyxTdHJpbmcsU3RyaW5nLGJvb2xlYW4pOmludAotCi0gICAgLyoqIENyZWF0ZXMgYW4gZWxlbWVudCBkZWZpbml0aW9uIGluIHRoZSB0YWJsZS4qLwotICAgIHB1YmxpYyBpbnQgY3JlYXRlRGVmZXJyZWRFbGVtZW50RGVmaW5pdGlvbihTdHJpbmcgZWxlbWVudE5hbWUpIHsKLQotICAgICAgICAvLyBjcmVhdGUgbm9kZQotICAgICAgICBpbnQgbm9kZUluZGV4ID0gY3JlYXRlTm9kZShOb2RlSW1wbC5FTEVNRU5UX0RFRklOSVRJT05fTk9ERSk7Ci0gICAgICAgIGludCBjaHVuayA9IG5vZGVJbmRleCA+PiBDSFVOS19TSElGVDsKLSAgICAgICAgaW50IGluZGV4ID0gbm9kZUluZGV4ICYgQ0hVTktfTUFTSzsKLSAgICAgICAgc2V0Q2h1bmtWYWx1ZShmTm9kZU5hbWUsIGVsZW1lbnROYW1lLCBjaHVuaywgaW5kZXgpOwotCi0gICAgICAgIC8vIHJldHVybiBub2RlIGluZGV4Ci0gICAgICAgIHJldHVybiBub2RlSW5kZXg7Ci0KLSAgICB9IC8vIGNyZWF0ZURlZmVycmVkRWxlbWVudERlZmluaXRpb24oU3RyaW5nKTppbnQKLQotICAgIC8qKiBDcmVhdGVzIGEgdGV4dCBub2RlIGluIHRoZSB0YWJsZS4gKi8KLSAgICBwdWJsaWMgaW50IGNyZWF0ZURlZmVycmVkVGV4dE5vZGUoU3RyaW5nIGRhdGEsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gaWdub3JhYmxlV2hpdGVzcGFjZSkgewotCi0gICAgICAgIC8vIGNyZWF0ZSBub2RlCi0gICAgICAgIGludCBub2RlSW5kZXggPSBjcmVhdGVOb2RlKE5vZGUuVEVYVF9OT0RFKTsKLSAgICAgICAgaW50IGNodW5rID0gbm9kZUluZGV4ID4+IENIVU5LX1NISUZUOwotICAgICAgICBpbnQgaW5kZXggPSBub2RlSW5kZXggJiBDSFVOS19NQVNLOwotICAgICAgICBzZXRDaHVua1ZhbHVlKGZOb2RlVmFsdWUsIGRhdGEsIGNodW5rLCBpbmRleCk7Ci0gICAgICAgIC8vIHVzZSBleHRyYSB0byBzdG9yZSBpZ25vcmFibGVXaGl0ZXNwYWNlIGluZm8KLSAgICAgICAgc2V0Q2h1bmtJbmRleChmTm9kZUV4dHJhLCBpZ25vcmFibGVXaGl0ZXNwYWNlID8gIDEgOiAwLCBjaHVuaywgaW5kZXgpOwotCi0gICAgICAgIC8vIHJldHVybiBub2RlIGluZGV4Ci0gICAgICAgIHJldHVybiBub2RlSW5kZXg7Ci0KLSAgICB9IC8vIGNyZWF0ZURlZmVycmVkVGV4dE5vZGUoU3RyaW5nLGJvb2xlYW4pOmludAotCi0gICAgLyoqIENyZWF0ZXMgYSBDREFUQSBzZWN0aW9uIG5vZGUgaW4gdGhlIHRhYmxlLiAqLwotICAgIHB1YmxpYyBpbnQgY3JlYXRlRGVmZXJyZWRDREFUQVNlY3Rpb24oU3RyaW5nIGRhdGEpIHsKLQotICAgICAgICAvLyBjcmVhdGUgbm9kZQotICAgICAgICBpbnQgbm9kZUluZGV4ID0gY3JlYXRlTm9kZShOb2RlLkNEQVRBX1NFQ1RJT05fTk9ERSk7Ci0gICAgICAgIGludCBjaHVuayA9IG5vZGVJbmRleCA+PiBDSFVOS19TSElGVDsKLSAgICAgICAgaW50IGluZGV4ID0gbm9kZUluZGV4ICYgQ0hVTktfTUFTSzsKLSAgICAgICAgc2V0Q2h1bmtWYWx1ZShmTm9kZVZhbHVlLCBkYXRhLCBjaHVuaywgaW5kZXgpOwotCi0gICAgICAgIC8vIHJldHVybiBub2RlIGluZGV4Ci0gICAgICAgIHJldHVybiBub2RlSW5kZXg7Ci0KLSAgICB9IC8vIGNyZWF0ZURlZmVycmVkQ0RBVEFTZWN0aW9uKFN0cmluZyk6aW50Ci0KLSAgICAvKiogQ3JlYXRlcyBhIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gbm9kZSBpbiB0aGUgdGFibGUuICovCi0gICAgcHVibGljIGludCBjcmVhdGVEZWZlcnJlZFByb2Nlc3NpbmdJbnN0cnVjdGlvbihTdHJpbmcgdGFyZ2V0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGRhdGEpIHsKLSAgICAgICAgLy8gY3JlYXRlIG5vZGUKLSAgICAgICAgaW50IG5vZGVJbmRleCA9IGNyZWF0ZU5vZGUoTm9kZS5QUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREUpOwotICAgICAgICBpbnQgY2h1bmsgPSBub2RlSW5kZXggPj4gQ0hVTktfU0hJRlQ7Ci0gICAgICAgIGludCBpbmRleCA9IG5vZGVJbmRleCAmIENIVU5LX01BU0s7Ci0gICAgICAgIHNldENodW5rVmFsdWUoZk5vZGVOYW1lLCB0YXJnZXQsIGNodW5rLCBpbmRleCk7Ci0gICAgICAgIHNldENodW5rVmFsdWUoZk5vZGVWYWx1ZSwgZGF0YSwgY2h1bmssIGluZGV4KTsKLSAgICAgICAgLy8gcmV0dXJuIG5vZGUgaW5kZXgKLSAgICAgICAgcmV0dXJuIG5vZGVJbmRleDsKLQotICAgIH0gLy8gY3JlYXRlRGVmZXJyZWRQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oU3RyaW5nLFN0cmluZyk6aW50Ci0KLSAgICAvKiogQ3JlYXRlcyBhIGNvbW1lbnQgbm9kZSBpbiB0aGUgdGFibGUuICovCi0gICAgcHVibGljIGludCBjcmVhdGVEZWZlcnJlZENvbW1lbnQoU3RyaW5nIGRhdGEpIHsKLQotICAgICAgICAvLyBjcmVhdGUgbm9kZQotICAgICAgICBpbnQgbm9kZUluZGV4ID0gY3JlYXRlTm9kZShOb2RlLkNPTU1FTlRfTk9ERSk7Ci0gICAgICAgIGludCBjaHVuayA9IG5vZGVJbmRleCA+PiBDSFVOS19TSElGVDsKLSAgICAgICAgaW50IGluZGV4ID0gbm9kZUluZGV4ICYgQ0hVTktfTUFTSzsKLSAgICAgICAgc2V0Q2h1bmtWYWx1ZShmTm9kZVZhbHVlLCBkYXRhLCBjaHVuaywgaW5kZXgpOwotCi0gICAgICAgIC8vIHJldHVybiBub2RlIGluZGV4Ci0gICAgICAgIHJldHVybiBub2RlSW5kZXg7Ci0KLSAgICB9IC8vIGNyZWF0ZURlZmVycmVkQ29tbWVudChTdHJpbmcpOmludAotCi0gICAgLyoqIENyZWF0ZXMgYSBjbG9uZSBvZiB0aGUgc3BlY2lmaWVkIG5vZGUuICovCi0gICAgcHVibGljIGludCBjbG9uZU5vZGUoaW50IG5vZGVJbmRleCwgYm9vbGVhbiBkZWVwKSB7Ci0KLSAgICAgICAgLy8gY2xvbmUgaW1tZWRpYXRlIG5vZGUKLQotICAgICAgICBpbnQgbmNodW5rID0gbm9kZUluZGV4ID4+IENIVU5LX1NISUZUOwotICAgICAgICBpbnQgbmluZGV4ID0gbm9kZUluZGV4ICYgQ0hVTktfTUFTSzsKLSAgICAgICAgaW50IG5vZGVUeXBlID0gZk5vZGVUeXBlW25jaHVua11bbmluZGV4XTsKLSAgICAgICAgaW50IGNsb25lSW5kZXggPSBjcmVhdGVOb2RlKChzaG9ydClub2RlVHlwZSk7Ci0gICAgICAgIGludCBjY2h1bmsgPSBjbG9uZUluZGV4ID4+IENIVU5LX1NISUZUOwotICAgICAgICBpbnQgY2luZGV4ID0gY2xvbmVJbmRleCAmIENIVU5LX01BU0s7Ci0gICAgICAgIHNldENodW5rVmFsdWUoZk5vZGVOYW1lLCBmTm9kZU5hbWVbbmNodW5rXVtuaW5kZXhdLCBjY2h1bmssIGNpbmRleCk7Ci0gICAgICAgIHNldENodW5rVmFsdWUoZk5vZGVWYWx1ZSwgZk5vZGVWYWx1ZVtuY2h1bmtdW25pbmRleF0sIGNjaHVuaywgY2luZGV4KTsKLSAgICAgICAgc2V0Q2h1bmtWYWx1ZShmTm9kZVVSSSwgZk5vZGVVUklbbmNodW5rXVtuaW5kZXhdLCBjY2h1bmssIGNpbmRleCk7Ci0gICAgICAgIGludCBleHRyYUluZGV4ID0gZk5vZGVFeHRyYVtuY2h1bmtdW25pbmRleF07Ci0gICAgICAgIGlmIChleHRyYUluZGV4ICE9IC0xKSB7Ci0gICAgICAgICAgICBpZiAobm9kZVR5cGUgIT0gTm9kZS5BVFRSSUJVVEVfTk9ERSAmJiBub2RlVHlwZSAhPSBOb2RlLlRFWFRfTk9ERSkgewotICAgICAgICAgICAgICAgIGV4dHJhSW5kZXggPSBjbG9uZU5vZGUoZXh0cmFJbmRleCwgZmFsc2UpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgc2V0Q2h1bmtJbmRleChmTm9kZUV4dHJhLCBleHRyYUluZGV4LCBjY2h1bmssIGNpbmRleCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBjbG9uZSBhbmQgYXR0YWNoIGNoaWxkcmVuCi0gICAgICAgIGlmIChkZWVwKSB7Ci0gICAgICAgICAgICBpbnQgcHJldkluZGV4ID0gLTE7Ci0gICAgICAgICAgICBpbnQgY2hpbGRJbmRleCA9IGdldExhc3RDaGlsZChub2RlSW5kZXgsIGZhbHNlKTsKLSAgICAgICAgICAgIHdoaWxlIChjaGlsZEluZGV4ICE9IC0xKSB7Ci0gICAgICAgICAgICAgICAgaW50IGNsb25lZENoaWxkSW5kZXggPSBjbG9uZU5vZGUoY2hpbGRJbmRleCwgZGVlcCk7Ci0gICAgICAgICAgICAgICAgaW5zZXJ0QmVmb3JlKGNsb25lSW5kZXgsIGNsb25lZENoaWxkSW5kZXgsIHByZXZJbmRleCk7Ci0gICAgICAgICAgICAgICAgcHJldkluZGV4ID0gY2xvbmVkQ2hpbGRJbmRleDsKLSAgICAgICAgICAgICAgICBjaGlsZEluZGV4ID0gZ2V0UmVhbFByZXZTaWJsaW5nKGNoaWxkSW5kZXgsIGZhbHNlKTsKLSAgICAgICAgICAgIH0KLQotCi0gICAgICAgIH0KLQotICAgICAgICAvLyByZXR1cm4gY2xvbmVkIG5vZGUgaW5kZXgKLSAgICAgICAgcmV0dXJuIGNsb25lSW5kZXg7Ci0KLSAgICB9IC8vIGNsb25lTm9kZShpbnQsYm9vbGVhbik6aW50Ci0KLSAgICAvKiogQXBwZW5kcyBhIGNoaWxkIHRvIHRoZSBzcGVjaWZpZWQgcGFyZW50IGluIHRoZSB0YWJsZS4gKi8KLSAgICBwdWJsaWMgdm9pZCBhcHBlbmRDaGlsZChpbnQgcGFyZW50SW5kZXgsIGludCBjaGlsZEluZGV4KSB7Ci0KLSAgICAgICAgLy8gYXBwZW5kIHBhcmVudCBpbmRleAotICAgICAgICBpbnQgcGNodW5rID0gcGFyZW50SW5kZXggPj4gQ0hVTktfU0hJRlQ7Ci0gICAgICAgIGludCBwaW5kZXggPSBwYXJlbnRJbmRleCAmIENIVU5LX01BU0s7Ci0gICAgICAgIGludCBjY2h1bmsgPSBjaGlsZEluZGV4ID4+IENIVU5LX1NISUZUOwotICAgICAgICBpbnQgY2luZGV4ID0gY2hpbGRJbmRleCAmIENIVU5LX01BU0s7Ci0gICAgICAgIHNldENodW5rSW5kZXgoZk5vZGVQYXJlbnQsIHBhcmVudEluZGV4LCBjY2h1bmssIGNpbmRleCk7Ci0KLSAgICAgICAgLy8gc2V0IHByZXZpb3VzIHNpYmxpbmcgb2YgbmV3IGNoaWxkCi0gICAgICAgIGludCBvbGFzdCA9IGdldENodW5rSW5kZXgoZk5vZGVMYXN0Q2hpbGQsIHBjaHVuaywgcGluZGV4KTsKLSAgICAgICAgc2V0Q2h1bmtJbmRleChmTm9kZVByZXZTaWIsIG9sYXN0LCBjY2h1bmssIGNpbmRleCk7Ci0KLSAgICAgICAgLy8gdXBkYXRlIHBhcmVudCdzIGxhc3QgY2hpbGQKLSAgICAgICAgc2V0Q2h1bmtJbmRleChmTm9kZUxhc3RDaGlsZCwgY2hpbGRJbmRleCwgcGNodW5rLCBwaW5kZXgpOwotCi0gICAgfSAvLyBhcHBlbmRDaGlsZChpbnQsaW50KQotCi0gICAgLyoqIEFkZHMgYW4gYXR0cmlidXRlIG5vZGUgdG8gdGhlIHNwZWNpZmllZCBlbGVtZW50LiAqLwotICAgIHB1YmxpYyBpbnQgc2V0QXR0cmlidXRlTm9kZShpbnQgZWxlbUluZGV4LCBpbnQgYXR0ckluZGV4KSB7Ci0KLSAgICAgICAgaW50IGVjaHVuayA9IGVsZW1JbmRleCA+PiBDSFVOS19TSElGVDsKLSAgICAgICAgaW50IGVpbmRleCA9IGVsZW1JbmRleCAmIENIVU5LX01BU0s7Ci0gICAgICAgIGludCBhY2h1bmsgPSBhdHRySW5kZXggPj4gQ0hVTktfU0hJRlQ7Ci0gICAgICAgIGludCBhaW5kZXggPSBhdHRySW5kZXggJiBDSFVOS19NQVNLOwotCi0gICAgICAgIC8vIHNlZSBpZiB0aGlzIGF0dHJpYnV0ZSBpcyBhbHJlYWR5IGhlcmUKLSAgICAgICAgU3RyaW5nIGF0dHJOYW1lID0gZ2V0Q2h1bmtWYWx1ZShmTm9kZU5hbWUsIGFjaHVuaywgYWluZGV4KTsKLSAgICAgICAgaW50IG9sZEF0dHJJbmRleCA9IGdldENodW5rSW5kZXgoZk5vZGVFeHRyYSwgZWNodW5rLCBlaW5kZXgpOwotICAgICAgICBpbnQgbmV4dEluZGV4ID0gLTE7Ci0gICAgICAgIGludCBvYWNodW5rID0gLTE7Ci0gICAgICAgIGludCBvYWluZGV4ID0gLTE7Ci0gICAgICAgIHdoaWxlIChvbGRBdHRySW5kZXggIT0gLTEpIHsKLSAgICAgICAgICAgIG9hY2h1bmsgPSBvbGRBdHRySW5kZXggPj4gQ0hVTktfU0hJRlQ7Ci0gICAgICAgICAgICBvYWluZGV4ID0gb2xkQXR0ckluZGV4ICYgQ0hVTktfTUFTSzsKLSAgICAgICAgICAgIFN0cmluZyBvbGRBdHRyTmFtZSA9IGdldENodW5rVmFsdWUoZk5vZGVOYW1lLCBvYWNodW5rLCBvYWluZGV4KTsKLSAgICAgICAgICAgIGlmIChvbGRBdHRyTmFtZS5lcXVhbHMoYXR0ck5hbWUpKSB7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBuZXh0SW5kZXggPSBvbGRBdHRySW5kZXg7Ci0gICAgICAgICAgICBvbGRBdHRySW5kZXggPSBnZXRDaHVua0luZGV4KGZOb2RlUHJldlNpYiwgb2FjaHVuaywgb2FpbmRleCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyByZW1vdmUgb2xkIGF0dHJpYnV0ZQotICAgICAgICBpZiAob2xkQXR0ckluZGV4ICE9IC0xKSB7Ci0KLSAgICAgICAgICAgIC8vIHBhdGNoIGxpbmtzCi0gICAgICAgICAgICBpbnQgcHJldkluZGV4ID0gZ2V0Q2h1bmtJbmRleChmTm9kZVByZXZTaWIsIG9hY2h1bmssIG9haW5kZXgpOwotICAgICAgICAgICAgaWYgKG5leHRJbmRleCA9PSAtMSkgewotICAgICAgICAgICAgICAgIHNldENodW5rSW5kZXgoZk5vZGVFeHRyYSwgcHJldkluZGV4LCBlY2h1bmssIGVpbmRleCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBpbnQgcGNodW5rID0gbmV4dEluZGV4ID4+IENIVU5LX1NISUZUOwotICAgICAgICAgICAgICAgIGludCBwaW5kZXggPSBuZXh0SW5kZXggJiBDSFVOS19NQVNLOwotICAgICAgICAgICAgICAgIHNldENodW5rSW5kZXgoZk5vZGVQcmV2U2liLCBwcmV2SW5kZXgsIHBjaHVuaywgcGluZGV4KTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gcmVtb3ZlIGNvbm5lY3Rpb25zIHRvIHNpYmxpbmdzCi0gICAgICAgICAgICBjbGVhckNodW5rSW5kZXgoZk5vZGVUeXBlLCBvYWNodW5rLCBvYWluZGV4KTsKLSAgICAgICAgICAgIGNsZWFyQ2h1bmtWYWx1ZShmTm9kZU5hbWUsIG9hY2h1bmssIG9haW5kZXgpOwotICAgICAgICAgICAgY2xlYXJDaHVua1ZhbHVlKGZOb2RlVmFsdWUsIG9hY2h1bmssIG9haW5kZXgpOwotICAgICAgICAgICAgY2xlYXJDaHVua0luZGV4KGZOb2RlUGFyZW50LCBvYWNodW5rLCBvYWluZGV4KTsKLSAgICAgICAgICAgIGNsZWFyQ2h1bmtJbmRleChmTm9kZVByZXZTaWIsIG9hY2h1bmssIG9haW5kZXgpOwotICAgICAgICAgICAgaW50IGF0dHJUZXh0SW5kZXggPQotICAgICAgICAgICAgICAgIGNsZWFyQ2h1bmtJbmRleChmTm9kZUxhc3RDaGlsZCwgb2FjaHVuaywgb2FpbmRleCk7Ci0gICAgICAgICAgICBpbnQgYXRjaHVuayA9IGF0dHJUZXh0SW5kZXggPj4gQ0hVTktfU0hJRlQ7Ci0gICAgICAgICAgICBpbnQgYXRpbmRleCA9IGF0dHJUZXh0SW5kZXggJiBDSFVOS19NQVNLOwotICAgICAgICAgICAgY2xlYXJDaHVua0luZGV4KGZOb2RlVHlwZSwgYXRjaHVuaywgYXRpbmRleCk7Ci0gICAgICAgICAgICBjbGVhckNodW5rVmFsdWUoZk5vZGVWYWx1ZSwgYXRjaHVuaywgYXRpbmRleCk7Ci0gICAgICAgICAgICBjbGVhckNodW5rSW5kZXgoZk5vZGVQYXJlbnQsIGF0Y2h1bmssIGF0aW5kZXgpOwotICAgICAgICAgICAgY2xlYXJDaHVua0luZGV4KGZOb2RlTGFzdENoaWxkLCBhdGNodW5rLCBhdGluZGV4KTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIGFkZCBuZXcgYXR0cmlidXRlCi0gICAgICAgIGludCBwcmV2SW5kZXggPSBnZXRDaHVua0luZGV4KGZOb2RlRXh0cmEsIGVjaHVuaywgZWluZGV4KTsKLSAgICAgICAgc2V0Q2h1bmtJbmRleChmTm9kZUV4dHJhLCBhdHRySW5kZXgsIGVjaHVuaywgZWluZGV4KTsKLSAgICAgICAgc2V0Q2h1bmtJbmRleChmTm9kZVByZXZTaWIsIHByZXZJbmRleCwgYWNodW5rLCBhaW5kZXgpOwotCi0gICAgICAgIC8vIHJldHVybgotICAgICAgICByZXR1cm4gb2xkQXR0ckluZGV4OwotCi0gICAgfSAvLyBzZXRBdHRyaWJ1dGVOb2RlKGludCxpbnQpOmludAotCi0KLSAgICAvKiogQWRkcyBhbiBhdHRyaWJ1dGUgbm9kZSB0byB0aGUgc3BlY2lmaWVkIGVsZW1lbnQuICovCi0gICAgcHVibGljIHZvaWQgc2V0SWRBdHRyaWJ1dGVOb2RlKGludCBlbGVtSW5kZXgsIGludCBhdHRySW5kZXgpIHsKLQotICAgICAgICBpbnQgY2h1bmsgPSBhdHRySW5kZXggPj4gQ0hVTktfU0hJRlQ7Ci0gICAgICAgIGludCBpbmRleCA9IGF0dHJJbmRleCAmIENIVU5LX01BU0s7Ci0gICAgICAgIGludCBleHRyYSA9IGdldENodW5rSW5kZXgoZk5vZGVFeHRyYSwgY2h1bmssIGluZGV4KTsKLSAgICAgICAgZXh0cmEgPSBleHRyYSB8IElEOwotICAgICAgICBzZXRDaHVua0luZGV4KGZOb2RlRXh0cmEsIGV4dHJhLCBjaHVuaywgaW5kZXgpOwotCi0gICAgICAgIFN0cmluZyB2YWx1ZSA9IGdldENodW5rVmFsdWUoZk5vZGVWYWx1ZSwgY2h1bmssIGluZGV4KTsKLSAgICAgICAgcHV0SWRlbnRpZmllcih2YWx1ZSwgZWxlbUluZGV4KTsKLSAgICB9Ci0KLQotICAgIC8qKiBTZXRzIHR5cGUgb2YgYXR0cmlidXRlICovCi0gICAgcHVibGljIHZvaWQgc2V0SWRBdHRyaWJ1dGUoaW50IGF0dHJJbmRleCkgewotCi0gICAgICAgIGludCBjaHVuayA9IGF0dHJJbmRleCA+PiBDSFVOS19TSElGVDsKLSAgICAgICAgaW50IGluZGV4ID0gYXR0ckluZGV4ICYgQ0hVTktfTUFTSzsKLSAgICAgICAgaW50IGV4dHJhID0gZ2V0Q2h1bmtJbmRleChmTm9kZUV4dHJhLCBjaHVuaywgaW5kZXgpOwotICAgICAgICBleHRyYSA9IGV4dHJhIHwgSUQ7Ci0gICAgICAgIHNldENodW5rSW5kZXgoZk5vZGVFeHRyYSwgZXh0cmEsIGNodW5rLCBpbmRleCk7Ci0gICAgfQotCi0gICAgLyoqIEluc2VydHMgYSBjaGlsZCBiZWZvcmUgdGhlIHNwZWNpZmllZCBub2RlIGluIHRoZSB0YWJsZS4gKi8KLSAgICBwdWJsaWMgaW50IGluc2VydEJlZm9yZShpbnQgcGFyZW50SW5kZXgsIGludCBuZXdDaGlsZEluZGV4LCBpbnQgcmVmQ2hpbGRJbmRleCkgewotCi0gICAgICAgIGlmIChyZWZDaGlsZEluZGV4ID09IC0xKSB7Ci0gICAgICAgICAgICBhcHBlbmRDaGlsZChwYXJlbnRJbmRleCwgbmV3Q2hpbGRJbmRleCk7Ci0gICAgICAgICAgICByZXR1cm4gbmV3Q2hpbGRJbmRleDsKLSAgICAgICAgfQotCi0gICAgICAgIGludCBuY2h1bmsgPSBuZXdDaGlsZEluZGV4ID4+IENIVU5LX1NISUZUOwotICAgICAgICBpbnQgbmluZGV4ID0gbmV3Q2hpbGRJbmRleCAmIENIVU5LX01BU0s7Ci0gICAgICAgIGludCByY2h1bmsgPSByZWZDaGlsZEluZGV4ID4+IENIVU5LX1NISUZUOwotICAgICAgICBpbnQgcmluZGV4ID0gcmVmQ2hpbGRJbmRleCAmIENIVU5LX01BU0s7Ci0gICAgICAgIGludCBwcmV2aW91c0luZGV4ID0gZ2V0Q2h1bmtJbmRleChmTm9kZVByZXZTaWIsIHJjaHVuaywgcmluZGV4KTsKLSAgICAgICAgc2V0Q2h1bmtJbmRleChmTm9kZVByZXZTaWIsIG5ld0NoaWxkSW5kZXgsIHJjaHVuaywgcmluZGV4KTsKLSAgICAgICAgc2V0Q2h1bmtJbmRleChmTm9kZVByZXZTaWIsIHByZXZpb3VzSW5kZXgsIG5jaHVuaywgbmluZGV4KTsKLQotICAgICAgICByZXR1cm4gbmV3Q2hpbGRJbmRleDsKLQotICAgIH0gLy8gaW5zZXJ0QmVmb3JlKGludCxpbnQsaW50KTppbnQKLQotICAgIC8qKiBTZXRzIHRoZSBsYXN0IGNoaWxkIG9mIHRoZSBwYXJlbnRJbmRleCB0byBjaGlsZEluZGV4LiAqLwotICAgIHB1YmxpYyB2b2lkIHNldEFzTGFzdENoaWxkKGludCBwYXJlbnRJbmRleCwgaW50IGNoaWxkSW5kZXgpIHsKLSAgICAgICAgaW50IHBjaHVuayA9IHBhcmVudEluZGV4ID4+IENIVU5LX1NISUZUOwotICAgICAgICBpbnQgcGluZGV4ID0gcGFyZW50SW5kZXggJiBDSFVOS19NQVNLOwotICAgICAgICBzZXRDaHVua0luZGV4KGZOb2RlTGFzdENoaWxkLCBjaGlsZEluZGV4LCBwY2h1bmssIHBpbmRleCk7Ci0gICAgfSAvLyBzZXRBc0xhc3RDaGlsZChpbnQsaW50KQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgcGFyZW50IG5vZGUgb2YgdGhlIGdpdmVuIG5vZGUuCi0gICAgICogPGVtPkNhbGxpbmcgdGhpcyBtZXRob2QgZG9lcyBub3QgZnJlZSB0aGUgcGFyZW50IGluZGV4LjwvZW0+Ci0gICAgICovCi0gICAgcHVibGljIGludCBnZXRQYXJlbnROb2RlKGludCBub2RlSW5kZXgpIHsKLSAgICAgICAgcmV0dXJuIGdldFBhcmVudE5vZGUobm9kZUluZGV4LCBmYWxzZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgcGFyZW50IG5vZGUgb2YgdGhlIGdpdmVuIG5vZGUuCi0gICAgICogQHBhcmFtIGZyZWUgVHJ1ZSB0byBmcmVlIHBhcmVudCBub2RlLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0UGFyZW50Tm9kZShpbnQgbm9kZUluZGV4LCBib29sZWFuIGZyZWUpIHsKLQotICAgICAgICBpZiAobm9kZUluZGV4ID09IC0xKSB7Ci0gICAgICAgICAgICByZXR1cm4gLTE7Ci0gICAgICAgIH0KLQotICAgICAgICBpbnQgY2h1bmsgPSBub2RlSW5kZXggPj4gQ0hVTktfU0hJRlQ7Ci0gICAgICAgIGludCBpbmRleCA9IG5vZGVJbmRleCAmIENIVU5LX01BU0s7Ci0gICAgICAgIHJldHVybiBmcmVlID8gY2xlYXJDaHVua0luZGV4KGZOb2RlUGFyZW50LCBjaHVuaywgaW5kZXgpCi0gICAgICAgICAgICAgICAgICAgIDogZ2V0Q2h1bmtJbmRleChmTm9kZVBhcmVudCwgY2h1bmssIGluZGV4KTsKLQotICAgIH0gLy8gZ2V0UGFyZW50Tm9kZShpbnQpOmludAotCi0gICAgLyoqIFJldHVybnMgdGhlIGxhc3QgY2hpbGQgb2YgdGhlIGdpdmVuIG5vZGUuICovCi0gICAgcHVibGljIGludCBnZXRMYXN0Q2hpbGQoaW50IG5vZGVJbmRleCkgewotICAgICAgICByZXR1cm4gZ2V0TGFzdENoaWxkKG5vZGVJbmRleCwgdHJ1ZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgbGFzdCBjaGlsZCBvZiB0aGUgZ2l2ZW4gbm9kZS4KLSAgICAgKiBAcGFyYW0gZnJlZSBUcnVlIHRvIGZyZWUgY2hpbGQgaW5kZXguCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRMYXN0Q2hpbGQoaW50IG5vZGVJbmRleCwgYm9vbGVhbiBmcmVlKSB7Ci0KLSAgICAgICAgaWYgKG5vZGVJbmRleCA9PSAtMSkgewotICAgICAgICAgICAgcmV0dXJuIC0xOwotICAgICAgICB9Ci0KLSAgICAgICAgaW50IGNodW5rID0gbm9kZUluZGV4ID4+IENIVU5LX1NISUZUOwotICAgICAgICBpbnQgaW5kZXggPSBub2RlSW5kZXggJiBDSFVOS19NQVNLOwotICAgICAgICByZXR1cm4gZnJlZSA/IGNsZWFyQ2h1bmtJbmRleChmTm9kZUxhc3RDaGlsZCwgY2h1bmssIGluZGV4KQotICAgICAgICAgICAgICAgICAgICA6IGdldENodW5rSW5kZXgoZk5vZGVMYXN0Q2hpbGQsIGNodW5rLCBpbmRleCk7Ci0KLSAgICB9IC8vIGdldExhc3RDaGlsZChpbnQsYm9vbGVhbik6aW50Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBwcmV2IHNpYmxpbmcgb2YgdGhlIGdpdmVuIG5vZGUuCi0gICAgICogVGhpcyBpcyBwb3N0LW5vcm1hbGl6YXRpb24gb2YgVGV4dCBOb2Rlcy4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldFByZXZTaWJsaW5nKGludCBub2RlSW5kZXgpIHsKLSAgICAgICAgcmV0dXJuIGdldFByZXZTaWJsaW5nKG5vZGVJbmRleCwgdHJ1ZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgcHJldiBzaWJsaW5nIG9mIHRoZSBnaXZlbiBub2RlLgotICAgICAqIEBwYXJhbSBmcmVlIFRydWUgdG8gZnJlZSBzaWJsaW5nIGluZGV4LgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0UHJldlNpYmxpbmcoaW50IG5vZGVJbmRleCwgYm9vbGVhbiBmcmVlKSB7Ci0KLSAgICAgICAgaWYgKG5vZGVJbmRleCA9PSAtMSkgewotICAgICAgICAgICAgcmV0dXJuIC0xOwotICAgICAgICB9Ci0KLSAgICAgICAgaW50IGNodW5rID0gbm9kZUluZGV4ID4+IENIVU5LX1NISUZUOwotICAgICAgICBpbnQgaW5kZXggPSBub2RlSW5kZXggJiBDSFVOS19NQVNLOwotICAgICAgICBpbnQgdHlwZSA9IGdldENodW5rSW5kZXgoZk5vZGVUeXBlLCBjaHVuaywgaW5kZXgpOwotICAgICAgICBpZiAodHlwZSA9PSBOb2RlLlRFWFRfTk9ERSkgewotICAgICAgICAgICAgZG8gewotICAgICAgICAgICAgICAgIG5vZGVJbmRleCA9IGdldENodW5rSW5kZXgoZk5vZGVQcmV2U2liLCBjaHVuaywgaW5kZXgpOwotICAgICAgICAgICAgICAgIGlmIChub2RlSW5kZXggPT0gLTEpIHsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGNodW5rID0gbm9kZUluZGV4ID4+IENIVU5LX1NISUZUOwotICAgICAgICAgICAgICAgIGluZGV4ID0gbm9kZUluZGV4ICYgQ0hVTktfTUFTSzsKLSAgICAgICAgICAgICAgICB0eXBlID0gZ2V0Q2h1bmtJbmRleChmTm9kZVR5cGUsIGNodW5rLCBpbmRleCk7Ci0gICAgICAgICAgICB9IHdoaWxlICh0eXBlID09IE5vZGUuVEVYVF9OT0RFKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIG5vZGVJbmRleCA9IGdldENodW5rSW5kZXgoZk5vZGVQcmV2U2liLCBjaHVuaywgaW5kZXgpOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIG5vZGVJbmRleDsKLQotICAgIH0gLy8gZ2V0UHJldlNpYmxpbmcoaW50LGJvb2xlYW4pOmludAotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgPGk+cmVhbDwvaT4gcHJldiBzaWJsaW5nIG9mIHRoZSBnaXZlbiBub2RlLAotICAgICAqIGRpcmVjdGx5IGZyb20gdGhlIGRhdGEgc3RydWN0dXJlcy4gVXNlZCBieSBUZXh0SW1wbCNnZXROb2RlVmFsdWUoKQotICAgICAqIHRvIG5vcm1hbGl6ZSB2YWx1ZXMuCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRSZWFsUHJldlNpYmxpbmcoaW50IG5vZGVJbmRleCkgewotICAgICAgICByZXR1cm4gZ2V0UmVhbFByZXZTaWJsaW5nKG5vZGVJbmRleCwgdHJ1ZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgPGk+cmVhbDwvaT4gcHJldiBzaWJsaW5nIG9mIHRoZSBnaXZlbiBub2RlLgotICAgICAqIEBwYXJhbSBmcmVlIFRydWUgdG8gZnJlZSBzaWJsaW5nIGluZGV4LgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0UmVhbFByZXZTaWJsaW5nKGludCBub2RlSW5kZXgsIGJvb2xlYW4gZnJlZSkgewotCi0gICAgICAgIGlmIChub2RlSW5kZXggPT0gLTEpIHsKLSAgICAgICAgICAgIHJldHVybiAtMTsKLSAgICAgICAgfQotCi0gICAgICAgIGludCBjaHVuayA9IG5vZGVJbmRleCA+PiBDSFVOS19TSElGVDsKLSAgICAgICAgaW50IGluZGV4ID0gbm9kZUluZGV4ICYgQ0hVTktfTUFTSzsKLSAgICAgICAgcmV0dXJuIGZyZWUgPyBjbGVhckNodW5rSW5kZXgoZk5vZGVQcmV2U2liLCBjaHVuaywgaW5kZXgpCi0gICAgICAgICAgICAgICAgICAgIDogZ2V0Q2h1bmtJbmRleChmTm9kZVByZXZTaWIsIGNodW5rLCBpbmRleCk7Ci0KLSAgICB9IC8vIGdldFJlYWRQcmV2U2libGluZyhpbnQsYm9vbGVhbik6aW50Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCBkZWZpbml0aW9uIGluIHRoZSB0YWJsZQotICAgICAqIHdpdGggdGhlIHNwZWNpZmllZCBuYW1lIGluZGV4LCBvciAtMSBpZiBubyBzdWNoIGRlZmluaXRpb24KLSAgICAgKiBleGlzdHMuCi0gICAgICovCi0gICAgcHVibGljIGludCBsb29rdXBFbGVtZW50RGVmaW5pdGlvbihTdHJpbmcgZWxlbWVudE5hbWUpIHsKLQotICAgICAgICBpZiAoZk5vZGVDb3VudCA+IDEpIHsKLQotICAgICAgICAgICAgLy8gZmluZCBkb2N0eXBlCi0gICAgICAgICAgICBpbnQgZG9jVHlwZUluZGV4ID0gLTE7Ci0gICAgICAgICAgICBpbnQgbmNodW5rID0gMDsKLSAgICAgICAgICAgIGludCBuaW5kZXggPSAwOwotICAgICAgICAgICAgZm9yIChpbnQgaW5kZXggPSBnZXRDaHVua0luZGV4KGZOb2RlTGFzdENoaWxkLCBuY2h1bmssIG5pbmRleCk7Ci0gICAgICAgICAgICAgICAgIGluZGV4ICE9IC0xOwotICAgICAgICAgICAgICAgICBpbmRleCA9IGdldENodW5rSW5kZXgoZk5vZGVQcmV2U2liLCBuY2h1bmssIG5pbmRleCkpIHsKLQotICAgICAgICAgICAgICAgIG5jaHVuayA9IGluZGV4ID4+IENIVU5LX1NISUZUOwotICAgICAgICAgICAgICAgIG5pbmRleCA9IGluZGV4ICAmIENIVU5LX01BU0s7Ci0gICAgICAgICAgICAgICAgaWYgKGdldENodW5rSW5kZXgoZk5vZGVUeXBlLCBuY2h1bmssIG5pbmRleCkgPT0gTm9kZS5ET0NVTUVOVF9UWVBFX05PREUpIHsKLSAgICAgICAgICAgICAgICAgICAgZG9jVHlwZUluZGV4ID0gaW5kZXg7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gZmluZCBlbGVtZW50IGRlZmluaXRpb24KLSAgICAgICAgICAgIGlmIChkb2NUeXBlSW5kZXggPT0gLTEpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gLTE7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBuY2h1bmsgPSBkb2NUeXBlSW5kZXggPj4gQ0hVTktfU0hJRlQ7Ci0gICAgICAgICAgICBuaW5kZXggPSBkb2NUeXBlSW5kZXggJiBDSFVOS19NQVNLOwotICAgICAgICAgICAgZm9yIChpbnQgaW5kZXggPSBnZXRDaHVua0luZGV4KGZOb2RlTGFzdENoaWxkLCBuY2h1bmssIG5pbmRleCk7Ci0gICAgICAgICAgICAgICAgIGluZGV4ICE9IC0xOwotICAgICAgICAgICAgICAgICBpbmRleCA9IGdldENodW5rSW5kZXgoZk5vZGVQcmV2U2liLCBuY2h1bmssIG5pbmRleCkpIHsKLQotICAgICAgICAgICAgICAgIG5jaHVuayA9IGluZGV4ID4+IENIVU5LX1NISUZUOwotICAgICAgICAgICAgICAgIG5pbmRleCA9IGluZGV4ICYgQ0hVTktfTUFTSzsKLSAgICAgICAgICAgICAgICBpZiAoZ2V0Q2h1bmtJbmRleChmTm9kZVR5cGUsIG5jaHVuaywgbmluZGV4KSA9PQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5vZGVJbXBsLkVMRU1FTlRfREVGSU5JVElPTl9OT0RFCi0gICAgICAgICAgICAgICAgICYmIGdldENodW5rVmFsdWUoZk5vZGVOYW1lLCBuY2h1bmssIG5pbmRleCkgPT0gZWxlbWVudE5hbWUpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGluZGV4OwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiAtMTsKLQotICAgIH0gLy8gbG9va3VwRWxlbWVudERlZmluaXRpb24oU3RyaW5nKTppbnQKLQotICAgIC8qKiBJbnN0YW50aWF0ZXMgdGhlIHJlcXVlc3RlZCBub2RlIG9iamVjdC4gKi8KLSAgICBwdWJsaWMgRGVmZXJyZWROb2RlIGdldE5vZGVPYmplY3QoaW50IG5vZGVJbmRleCkgewotCi0gICAgICAgIC8vIGlzIHRoZXJlIGFueXRoaW5nIHRvIGRvPwotICAgICAgICBpZiAobm9kZUluZGV4ID09IC0xKSB7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIGdldCBub2RlIHR5cGUKLSAgICAgICAgaW50IGNodW5rID0gbm9kZUluZGV4ID4+IENIVU5LX1NISUZUOwotICAgICAgICBpbnQgaW5kZXggPSBub2RlSW5kZXggJiBDSFVOS19NQVNLOwotICAgICAgICBpbnQgdHlwZSA9IGdldENodW5rSW5kZXgoZk5vZGVUeXBlLCBjaHVuaywgaW5kZXgpOwotICAgICAgICBpZiAodHlwZSAhPSBOb2RlLlRFWFRfTk9ERSAmJiB0eXBlICE9IE5vZGUuQ0RBVEFfU0VDVElPTl9OT0RFKSB7Ci0gICAgICAgICAgICBjbGVhckNodW5rSW5kZXgoZk5vZGVUeXBlLCBjaHVuaywgaW5kZXgpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gY3JlYXRlIG5ldyBub2RlCi0gICAgICAgIERlZmVycmVkTm9kZSBub2RlID0gbnVsbDsKLSAgICAgICAgc3dpdGNoICh0eXBlKSB7Ci0KLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAvLyBTdGFuZGFyZCBET00gbm9kZSB0eXBlcwotICAgICAgICAgICAgLy8KLQotICAgICAgICAgICAgY2FzZSBOb2RlLkFUVFJJQlVURV9OT0RFOiB7Ci0gICAgICAgICAgICAgICAgaWYgKGZOYW1lc3BhY2VzRW5hYmxlZCkgewotICAgICAgICAgICAgICAgICAgICBub2RlID0gbmV3IERlZmVycmVkQXR0ck5TSW1wbCh0aGlzLCBub2RlSW5kZXgpOwotICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIG5vZGUgPSBuZXcgRGVmZXJyZWRBdHRySW1wbCh0aGlzLCBub2RlSW5kZXgpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgY2FzZSBOb2RlLkNEQVRBX1NFQ1RJT05fTk9ERTogewotICAgICAgICAgICAgICAgIG5vZGUgPSBuZXcgRGVmZXJyZWRDREFUQVNlY3Rpb25JbXBsKHRoaXMsIG5vZGVJbmRleCk7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGNhc2UgTm9kZS5DT01NRU5UX05PREU6IHsKLSAgICAgICAgICAgICAgICBub2RlID0gbmV3IERlZmVycmVkQ29tbWVudEltcGwodGhpcywgbm9kZUluZGV4KTsKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gTk9URTogRG9jdW1lbnQgZnJhZ21lbnRzIGNhbiBuZXZlciBiZSAiZmFzdCIuCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgLy8gICAgICAgVGhlIHBhcnNlciB3aWxsIG5ldmVyIGFzayB0byBjcmVhdGUgYSBkb2N1bWVudAotICAgICAgICAgICAgLy8gICAgICAgZnJhZ21lbnQgZHVyaW5nIHRoZSBwYXJzZS4gRG9jdW1lbnQgZnJhZ21lbnRzCi0gICAgICAgICAgICAvLyAgICAgICBhcmUgdXNlZCBieSB0aGUgYXBwbGljYXRpb24gKmFmdGVyKiB0aGUgcGFyc2UuCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgLy8gY2FzZSBOb2RlLkRPQ1VNRU5UX0ZSQUdNRU5UX05PREU6IHsgYnJlYWs7IH0KLSAgICAgICAgICAgIGNhc2UgTm9kZS5ET0NVTUVOVF9OT0RFOiB7Ci0gICAgICAgICAgICAgICAgLy8gdGhpcyBub2RlIGlzIG5ldmVyICJmYXN0IgotICAgICAgICAgICAgICAgIG5vZGUgPSB0aGlzOwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBjYXNlIE5vZGUuRE9DVU1FTlRfVFlQRV9OT0RFOiB7Ci0gICAgICAgICAgICAgICAgbm9kZSA9IG5ldyBEZWZlcnJlZERvY3VtZW50VHlwZUltcGwodGhpcywgbm9kZUluZGV4KTsKLSAgICAgICAgICAgICAgICAvLyBzYXZlIHRoZSBkb2N0eXBlIG5vZGUKLSAgICAgICAgICAgICAgICBkb2NUeXBlID0gKERvY3VtZW50VHlwZUltcGwpbm9kZTsKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgY2FzZSBOb2RlLkVMRU1FTlRfTk9ERTogewotCi0gICAgICAgICAgICAgICAgaWYgKERFQlVHX0lEUykgewotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oImdldE5vZGVPYmplY3QoRUxFTUVOVF9OT0RFKTogIitub2RlSW5kZXgpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8vIGNyZWF0ZSBub2RlCi0gICAgICAgICAgICAgICAgaWYgKGZOYW1lc3BhY2VzRW5hYmxlZCkgewotICAgICAgICAgICAgICAgICAgICBub2RlID0gbmV3IERlZmVycmVkRWxlbWVudE5TSW1wbCh0aGlzLCBub2RlSW5kZXgpOwotICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIG5vZGUgPSBuZXcgRGVmZXJyZWRFbGVtZW50SW1wbCh0aGlzLCBub2RlSW5kZXgpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8vIGNoZWNrIHRvIHNlZSBpZiB0aGlzIGVsZW1lbnQgbmVlZHMgdG8gYmUKLSAgICAgICAgICAgICAgICAvLyByZWdpc3RlcmVkIGZvciBpdHMgSUQgYXR0cmlidXRlcwotICAgICAgICAgICAgICAgIGlmIChmSWRFbGVtZW50ICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgaW50IGlkSW5kZXggPSBiaW5hcnlTZWFyY2goZklkRWxlbWVudCwgMCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZklkQ291bnQtMSwgbm9kZUluZGV4KTsKLSAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGlkSW5kZXggIT0gLTEpIHsKLQotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKERFQlVHX0lEUykgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiICBpZCBpbmRleDogIitpZEluZGV4KTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIiAgZklkTmFtZVsiK2lkSW5kZXgrCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJdOiAiK2ZJZE5hbWVbaWRJbmRleF0pOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyByZWdpc3RlciBJRAotICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG5hbWUgPSBmSWROYW1lW2lkSW5kZXhdOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5hbWUgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChERUJVR19JRFMpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCIgIG5hbWU6ICIrbmFtZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoImdldE5vZGVPYmplY3QoKSMiKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcHV0SWRlbnRpZmllcjAobmFtZSwgKEVsZW1lbnQpbm9kZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZklkTmFtZVtpZEluZGV4XSA9IG51bGw7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNvbnRpbnVlIGlmIHRoZXJlIGFyZSBtb3JlIElEcyBmb3IKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoaXMgZWxlbWVudAotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlkSW5kZXggKyAxIDwgZklkQ291bnQgJiYKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmSWRFbGVtZW50W2lkSW5kZXggKyAxXSA9PSBub2RlSW5kZXgpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZEluZGV4Kys7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZEluZGV4ID0gLTE7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGNhc2UgTm9kZS5FTlRJVFlfTk9ERTogewotICAgICAgICAgICAgICAgIG5vZGUgPSBuZXcgRGVmZXJyZWRFbnRpdHlJbXBsKHRoaXMsIG5vZGVJbmRleCk7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGNhc2UgTm9kZS5FTlRJVFlfUkVGRVJFTkNFX05PREU6IHsKLSAgICAgICAgICAgICAgICBub2RlID0gbmV3IERlZmVycmVkRW50aXR5UmVmZXJlbmNlSW1wbCh0aGlzLCBub2RlSW5kZXgpOwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBjYXNlIE5vZGUuTk9UQVRJT05fTk9ERTogewotICAgICAgICAgICAgICAgIG5vZGUgPSBuZXcgRGVmZXJyZWROb3RhdGlvbkltcGwodGhpcywgbm9kZUluZGV4KTsKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgY2FzZSBOb2RlLlBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERTogewotICAgICAgICAgICAgICAgIG5vZGUgPSBuZXcgRGVmZXJyZWRQcm9jZXNzaW5nSW5zdHJ1Y3Rpb25JbXBsKHRoaXMsIG5vZGVJbmRleCk7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGNhc2UgTm9kZS5URVhUX05PREU6IHsKLSAgICAgICAgICAgICAgICBub2RlID0gbmV3IERlZmVycmVkVGV4dEltcGwodGhpcywgbm9kZUluZGV4KTsKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIC8vIG5vbi1zdGFuZGFyZCBET00gbm9kZSB0eXBlcwotICAgICAgICAgICAgLy8KLQotICAgICAgICAgICAgY2FzZSBOb2RlSW1wbC5FTEVNRU5UX0RFRklOSVRJT05fTk9ERTogewotICAgICAgICAgICAgICAgIG5vZGUgPSBuZXcgRGVmZXJyZWRFbGVtZW50RGVmaW5pdGlvbkltcGwodGhpcywgbm9kZUluZGV4KTsKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgZGVmYXVsdDogewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInR5cGU6ICIrdHlwZSk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgfSAvLyBzd2l0Y2ggbm9kZSB0eXBlCi0KLSAgICAgICAgLy8gc3RvcmUgYW5kIHJldHVybgotICAgICAgICBpZiAobm9kZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gbm9kZTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIGVycm9yCi0gICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKLQotICAgIH0gLy8gY3JlYXRlTm9kZU9iamVjdChpbnQpOk5vZGUKLQotICAgIC8qKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSBnaXZlbiBub2RlLiAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Tm9kZU5hbWUoaW50IG5vZGVJbmRleCkgewotICAgICAgICByZXR1cm4gZ2V0Tm9kZU5hbWUobm9kZUluZGV4LCB0cnVlKTsKLSAgICB9IC8vIGdldE5vZGVOYW1lU3RyaW5nKGludCk6U3RyaW5nCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSBnaXZlbiBub2RlLgotICAgICAqIEBwYXJhbSBmcmVlIFRydWUgdG8gZnJlZSB0aGUgc3RyaW5nIGluZGV4LgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Tm9kZU5hbWUoaW50IG5vZGVJbmRleCwgYm9vbGVhbiBmcmVlKSB7Ci0KLSAgICAgICAgaWYgKG5vZGVJbmRleCA9PSAtMSkgewotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLQotICAgICAgICBpbnQgY2h1bmsgPSBub2RlSW5kZXggPj4gQ0hVTktfU0hJRlQ7Ci0gICAgICAgIGludCBpbmRleCA9IG5vZGVJbmRleCAmIENIVU5LX01BU0s7Ci0gICAgICAgIHJldHVybiBmcmVlID8gY2xlYXJDaHVua1ZhbHVlKGZOb2RlTmFtZSwgY2h1bmssIGluZGV4KQotICAgICAgICAgICAgICAgICAgICA6IGdldENodW5rVmFsdWUoZk5vZGVOYW1lLCBjaHVuaywgaW5kZXgpOwotCi0gICAgfSAvLyBnZXROb2RlTmFtZShpbnQsYm9vbGVhbik6U3RyaW5nCi0KLSAgICAvKiogUmV0dXJucyB0aGUgcmVhbCB2YWx1ZSBvZiB0aGUgZ2l2ZW4gbm9kZS4gKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE5vZGVWYWx1ZVN0cmluZyhpbnQgbm9kZUluZGV4KSB7Ci0gICAgICAgIHJldHVybiBnZXROb2RlVmFsdWVTdHJpbmcobm9kZUluZGV4LCB0cnVlKTsKLSAgICB9IC8vIGdldE5vZGVWYWx1ZVN0cmluZyhpbnQpOlN0cmluZwotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgcmVhbCB2YWx1ZSBvZiB0aGUgZ2l2ZW4gbm9kZS4KLSAgICAgKiBAcGFyYW0gZnJlZSBUcnVlIHRvIGZyZWUgdGhlIHN0cmluZyBpbmRleC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE5vZGVWYWx1ZVN0cmluZyhpbnQgbm9kZUluZGV4LCBib29sZWFuIGZyZWUpIHsKLQotICAgICAgICBpZiAobm9kZUluZGV4ID09IC0xKSB7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotCi0gICAgICAgIGludCBjaHVuayA9IG5vZGVJbmRleCA+PiBDSFVOS19TSElGVDsKLSAgICAgICAgaW50IGluZGV4ID0gbm9kZUluZGV4ICYgQ0hVTktfTUFTSzsKLSAgICAgICAgU3RyaW5nIHZhbHVlID0gZnJlZSA/IGNsZWFyQ2h1bmtWYWx1ZShmTm9kZVZhbHVlLCBjaHVuaywgaW5kZXgpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBnZXRDaHVua1ZhbHVlKGZOb2RlVmFsdWUsIGNodW5rLCBpbmRleCk7Ci0gICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotCi0gICAgICAgIGludCB0eXBlICA9IGdldENodW5rSW5kZXgoZk5vZGVUeXBlLCBjaHVuaywgaW5kZXgpOwotICAgICAgICBpZiAodHlwZSA9PSBOb2RlLlRFWFRfTk9ERSkgewotICAgICAgICAgICAgaW50IHByZXZTaWIgPSBnZXRSZWFsUHJldlNpYmxpbmcobm9kZUluZGV4KTsKLSAgICAgICAgICAgIGlmIChwcmV2U2liICE9IC0xICYmCi0gICAgICAgICAgICAgICAgZ2V0Tm9kZVR5cGUocHJldlNpYiwgZmFsc2UpID09IE5vZGUuVEVYVF9OT0RFKSB7Ci0gICAgICAgICAgICAgICAgLy8gYXBwZW5kIGRhdGEgdGhhdCBpcyBzdG9yZWQgaW4gZk5vZGVWYWx1ZQotICAgICAgICAgICAgICAgIC8vIFJFVklTSVQ6IGZvciB0ZXh0IG5vZGVzIGl0IHdvcmtzIGRpZmZlcmVudGx5IHRoYW4gZm9yIENEQVRBCi0gICAgICAgICAgICAgICAgLy8gICAgICAgICAgbm9kZXMuCi0gICAgICAgICAgICAgICAgZlN0ckNodW5rcy5hZGQodmFsdWUpOwotICAgICAgICAgICAgICAgIGRvIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gZ28gaW4gcmV2ZXJzZSBvcmRlcjogZmluZCBsYXN0IGNoaWxkLCB0aGVuCi0gICAgICAgICAgICAgICAgICAgIC8vIGl0cyBwcmV2aW91cyBzaWJsaW5nLCBldGMKLSAgICAgICAgICAgICAgICAgICAgY2h1bmsgPSBwcmV2U2liID4+IENIVU5LX1NISUZUOwotICAgICAgICAgICAgICAgICAgICBpbmRleCA9IHByZXZTaWIgJiBDSFVOS19NQVNLOwotICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IGdldENodW5rVmFsdWUoZk5vZGVWYWx1ZSwgY2h1bmssIGluZGV4KTsKLSAgICAgICAgICAgICAgICAgICAgZlN0ckNodW5rcy5hZGQodmFsdWUpOwotICAgICAgICAgICAgICAgICAgICBwcmV2U2liID0gZ2V0Q2h1bmtJbmRleChmTm9kZVByZXZTaWIsIGNodW5rLCBpbmRleCk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChwcmV2U2liID09IC0xKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0gd2hpbGUgKGdldE5vZGVUeXBlKHByZXZTaWIsIGZhbHNlKSA9PSBOb2RlLlRFWFRfTk9ERSk7Ci0KLSAgICAgICAgICAgICAgICBpbnQgY2h1bmtDb3VudCA9IGZTdHJDaHVua3Muc2l6ZSgpOwotCi0gICAgICAgICAgICAgICAgLy8gYWRkIHRvIHRoZSBidWZmZXIgaW4gdGhlIGNvcnJlY3Qgb3JkZXIuCi0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IGNodW5rQ291bnQgLSAxOyBpID49IDA7IGktLSkgewotICAgICAgICAgICAgICAgICAgICBmQnVmZmVyU3RyLmFwcGVuZCgoU3RyaW5nKWZTdHJDaHVua3MuZ2V0KGkpKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICB2YWx1ZSA9IGZCdWZmZXJTdHIudG9TdHJpbmcoKTsKLSAgICAgICAgICAgICAgICBmU3RyQ2h1bmtzLmNsZWFyKCk7Ci0gICAgICAgICAgICAgICAgZkJ1ZmZlclN0ci5zZXRMZW5ndGgoMCk7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKHR5cGUgPT0gTm9kZS5DREFUQV9TRUNUSU9OX05PREUpIHsKLSAgICAgICAgICAgIC8vIGZpbmQgaWYgYW55IG90aGVyIGRhdGEgc3RvcmVkIGluIGNoaWxkcmVuCi0gICAgICAgICAgICBpbnQgY2hpbGQgPSBnZXRMYXN0Q2hpbGQobm9kZUluZGV4LCBmYWxzZSk7Ci0gICAgICAgICAgICBpZiAoY2hpbGQgIT0tMSkgewotICAgICAgICAgICAgICAgIC8vIGFwcGVuZCBkYXRhIHRoYXQgaXMgc3RvcmVkIGluIGZOb2RlVmFsdWUKLSAgICAgICAgICAgICAgICBmQnVmZmVyU3RyLmFwcGVuZCh2YWx1ZSk7Ci0gICAgICAgICAgICAgICAgd2hpbGUgKGNoaWxkICE9LTEpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gZ28gaW4gcmV2ZXJzZSBvcmRlcjogZmluZCBsYXN0IGNoaWxkLCB0aGVuCi0gICAgICAgICAgICAgICAgICAgIC8vIGl0cyBwcmV2aW91cyBzaWJsaW5nLCBldGMKLSAgICAgICAgICAgICAgICAgICBjaHVuayA9IGNoaWxkID4+IENIVU5LX1NISUZUOwotICAgICAgICAgICAgICAgICAgICBpbmRleCA9IGNoaWxkICYgQ0hVTktfTUFTSzsKLSAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBnZXRDaHVua1ZhbHVlKGZOb2RlVmFsdWUsIGNodW5rLCBpbmRleCk7Ci0gICAgICAgICAgICAgICAgICAgIGZTdHJDaHVua3MuYWRkKHZhbHVlKTsKLSAgICAgICAgICAgICAgICAgICAgY2hpbGQgPSBnZXRDaHVua0luZGV4KGZOb2RlUHJldlNpYiwgY2h1bmssIGluZGV4KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLy8gYWRkIHRvIHRoZSBidWZmZXIgaW4gdGhlIGNvcnJlY3Qgb3JkZXIuCi0gICAgICAgICAgICAgICAgZm9yIChpbnQgaT1mU3RyQ2h1bmtzLnNpemUoKS0xOyBpPj0wOyBpLS0pIHsKLSAgICAgICAgICAgICAgICAgICAgIGZCdWZmZXJTdHIuYXBwZW5kKChTdHJpbmcpZlN0ckNodW5rcy5nZXQoaSkpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIHZhbHVlID0gZkJ1ZmZlclN0ci50b1N0cmluZygpOwotICAgICAgICAgICAgICAgIGZTdHJDaHVua3MuY2xlYXIoKTsKLSAgICAgICAgICAgICAgICBmQnVmZmVyU3RyLnNldExlbmd0aCgwKTsKLSAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gdmFsdWU7Ci0KLSAgICB9IC8vIGdldE5vZGVWYWx1ZVN0cmluZyhpbnQsYm9vbGVhbik6U3RyaW5nCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiB0aGUgZ2l2ZW4gbm9kZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE5vZGVWYWx1ZShpbnQgbm9kZUluZGV4KSB7Ci0gICAgICAgIHJldHVybiBnZXROb2RlVmFsdWUobm9kZUluZGV4LCB0cnVlKTsKLSAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIENsZWFycyB0aGUgdHlwZSBpbmZvIHRoYXQgaXMgc3RvcmVkIGluIHRoZSBmTm9kZVZhbHVlIGFycmF5Ci0gICAgICAgICAqIEBwYXJhbSBub2RlSW5kZXgKLSAgICAgICAgICogQHJldHVybiBPYmplY3QgLSB0eXBlIGluZm9ybWF0aW9uIGZvciB0aGUgYXR0cmlidXRlL2VsZW1lbnQgbm9kZQotICAgICAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0IGdldFR5cGVJbmZvKGludCBub2RlSW5kZXgpIHsKLSAgICAgICAgaWYgKG5vZGVJbmRleCA9PSAtMSkgewotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLQotICAgICAgICBpbnQgY2h1bmsgPSBub2RlSW5kZXggPj4gQ0hVTktfU0hJRlQ7Ci0gICAgICAgIGludCBpbmRleCA9IG5vZGVJbmRleCAmIENIVU5LX01BU0s7Ci0KLQotICAgICAgICBPYmplY3QgdmFsdWUgPSBmTm9kZVZhbHVlW2NodW5rXSAhPSBudWxsID8gZk5vZGVWYWx1ZVtjaHVua11baW5kZXhdIDogbnVsbDsKLSAgICAgICAgaWYgKHZhbHVlICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZOb2RlVmFsdWVbY2h1bmtdW2luZGV4XSA9IG51bGw7Ci0gICAgICAgICAgICBSZWZDb3VudCBjID0gKFJlZkNvdW50KSBmTm9kZVZhbHVlW2NodW5rXVtDSFVOS19TSVpFXTsKLSAgICAgICAgICAgIGMuZkNvdW50LS07Ci0gICAgICAgICAgICBpZiAoYy5mQ291bnQgPT0gMCkgewotICAgICAgICAgICAgICAgIGZOb2RlVmFsdWVbY2h1bmtdID0gbnVsbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gdmFsdWU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgdGhlIGdpdmVuIG5vZGUuCi0gICAgICogQHBhcmFtIGZyZWUgVHJ1ZSB0byBmcmVlIHRoZSB2YWx1ZSBpbmRleC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE5vZGVWYWx1ZShpbnQgbm9kZUluZGV4LCBib29sZWFuIGZyZWUpIHsKLQotICAgICAgICBpZiAobm9kZUluZGV4ID09IC0xKSB7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotCi0gICAgICAgIGludCBjaHVuayA9IG5vZGVJbmRleCA+PiBDSFVOS19TSElGVDsKLSAgICAgICAgaW50IGluZGV4ID0gbm9kZUluZGV4ICYgQ0hVTktfTUFTSzsKLSAgICAgICAgcmV0dXJuIGZyZWUgPyBjbGVhckNodW5rVmFsdWUoZk5vZGVWYWx1ZSwgY2h1bmssIGluZGV4KQotICAgICAgICAgICAgICAgICAgICA6IGdldENodW5rVmFsdWUoZk5vZGVWYWx1ZSwgY2h1bmssIGluZGV4KTsKLQotICAgIH0gLy8gZ2V0Tm9kZVZhbHVlKGludCxib29sZWFuKTpTdHJpbmcKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIGV4dHJhIGluZm8gb2YgdGhlIGdpdmVuIG5vZGUuCi0gICAgICogVXNlZCBieSBBdHRySW1wbCB0byBzdG9yZSBzcGVjaWZpZWQgdmFsdWUgKDEgPT0gdHJ1ZSkuCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXROb2RlRXh0cmEoaW50IG5vZGVJbmRleCkgewotICAgICAgICByZXR1cm4gZ2V0Tm9kZUV4dHJhKG5vZGVJbmRleCwgdHJ1ZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgZXh0cmEgaW5mbyBvZiB0aGUgZ2l2ZW4gbm9kZS4KLSAgICAgKiBAcGFyYW0gZnJlZSBUcnVlIHRvIGZyZWUgdGhlIHZhbHVlIGluZGV4LgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0Tm9kZUV4dHJhKGludCBub2RlSW5kZXgsIGJvb2xlYW4gZnJlZSkgewotCi0gICAgICAgIGlmIChub2RlSW5kZXggPT0gLTEpIHsKLSAgICAgICAgICAgIHJldHVybiAtMTsKLSAgICAgICAgfQotCi0gICAgICAgIGludCBjaHVuayA9IG5vZGVJbmRleCA+PiBDSFVOS19TSElGVDsKLSAgICAgICAgaW50IGluZGV4ID0gbm9kZUluZGV4ICYgQ0hVTktfTUFTSzsKLSAgICAgICAgcmV0dXJuIGZyZWUgPyBjbGVhckNodW5rSW5kZXgoZk5vZGVFeHRyYSwgY2h1bmssIGluZGV4KQotICAgICAgICAgICAgICAgICAgICA6IGdldENodW5rSW5kZXgoZk5vZGVFeHRyYSwgY2h1bmssIGluZGV4KTsKLQotICAgIH0gLy8gZ2V0Tm9kZUV4dHJhKGludCxib29sZWFuKTppbnQKLQotICAgIC8qKiBSZXR1cm5zIHRoZSB0eXBlIG9mIHRoZSBnaXZlbiBub2RlLiAqLwotICAgIHB1YmxpYyBzaG9ydCBnZXROb2RlVHlwZShpbnQgbm9kZUluZGV4KSB7Ci0gICAgICAgIHJldHVybiBnZXROb2RlVHlwZShub2RlSW5kZXgsIHRydWUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIHR5cGUgb2YgdGhlIGdpdmVuIG5vZGUuCi0gICAgICogQHBhcmFtIGZyZWUgVHJ1ZSB0byBmcmVlIHR5cGUgaW5kZXguCi0gICAgICovCi0gICAgcHVibGljIHNob3J0IGdldE5vZGVUeXBlKGludCBub2RlSW5kZXgsIGJvb2xlYW4gZnJlZSkgewotCi0gICAgICAgIGlmIChub2RlSW5kZXggPT0gLTEpIHsKLSAgICAgICAgICAgIHJldHVybiAtMTsKLSAgICAgICAgfQotCi0gICAgICAgIGludCBjaHVuayA9IG5vZGVJbmRleCA+PiBDSFVOS19TSElGVDsKLSAgICAgICAgaW50IGluZGV4ID0gbm9kZUluZGV4ICYgQ0hVTktfTUFTSzsKLSAgICAgICAgcmV0dXJuIGZyZWUgPyAoc2hvcnQpY2xlYXJDaHVua0luZGV4KGZOb2RlVHlwZSwgY2h1bmssIGluZGV4KQotICAgICAgICAgICAgICAgICAgICA6IChzaG9ydClnZXRDaHVua0luZGV4KGZOb2RlVHlwZSwgY2h1bmssIGluZGV4KTsKLQotICAgIH0gLy8gZ2V0Tm9kZVR5cGUoaW50KTppbnQKLQotICAgIC8qKiBSZXR1cm5zIHRoZSBhdHRyaWJ1dGUgdmFsdWUgb2YgdGhlIGdpdmVuIG5hbWUuICovCi0gICAgcHVibGljIFN0cmluZyBnZXRBdHRyaWJ1dGUoaW50IGVsZW1JbmRleCwgU3RyaW5nIG5hbWUpIHsKLSAgICAgICAgaWYgKGVsZW1JbmRleCA9PSAtMSB8fCBuYW1lID09IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgICAgIGludCBlY2h1bmsgPSBlbGVtSW5kZXggPj4gQ0hVTktfU0hJRlQ7Ci0gICAgICAgIGludCBlaW5kZXggPSBlbGVtSW5kZXggJiBDSFVOS19NQVNLOwotICAgICAgICBpbnQgYXR0ckluZGV4ID0gZ2V0Q2h1bmtJbmRleChmTm9kZUV4dHJhLCBlY2h1bmssIGVpbmRleCk7Ci0gICAgICAgIHdoaWxlIChhdHRySW5kZXggIT0gLTEpIHsKLSAgICAgICAgICAgIGludCBhY2h1bmsgPSBhdHRySW5kZXggPj4gQ0hVTktfU0hJRlQ7Ci0gICAgICAgICAgICBpbnQgYWluZGV4ID0gYXR0ckluZGV4ICYgQ0hVTktfTUFTSzsKLSAgICAgICAgICAgIGlmIChnZXRDaHVua1ZhbHVlKGZOb2RlTmFtZSwgYWNodW5rLCBhaW5kZXgpID09IG5hbWUpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZ2V0Q2h1bmtWYWx1ZShmTm9kZVZhbHVlLCBhY2h1bmssIGFpbmRleCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBhdHRySW5kZXggPSBnZXRDaHVua0luZGV4KGZOb2RlUHJldlNpYiwgYWNodW5rLCBhaW5kZXgpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKiBSZXR1cm5zIHRoZSBVUkkgb2YgdGhlIGdpdmVuIG5vZGUuICovCi0gICAgcHVibGljIFN0cmluZyBnZXROb2RlVVJJKGludCBub2RlSW5kZXgpIHsKLSAgICAgICAgcmV0dXJuIGdldE5vZGVVUkkobm9kZUluZGV4LCB0cnVlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBVUkkgb2YgdGhlIGdpdmVuIG5vZGUuCi0gICAgICogQHBhcmFtIGZyZWUgVHJ1ZSB0byBmcmVlIFVSSSBpbmRleC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE5vZGVVUkkoaW50IG5vZGVJbmRleCwgYm9vbGVhbiBmcmVlKSB7Ci0KLSAgICAgICAgaWYgKG5vZGVJbmRleCA9PSAtMSkgewotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLQotICAgICAgICBpbnQgY2h1bmsgPSBub2RlSW5kZXggPj4gQ0hVTktfU0hJRlQ7Ci0gICAgICAgIGludCBpbmRleCA9IG5vZGVJbmRleCAmIENIVU5LX01BU0s7Ci0gICAgICAgIHJldHVybiBmcmVlID8gY2xlYXJDaHVua1ZhbHVlKGZOb2RlVVJJLCBjaHVuaywgaW5kZXgpCi0gICAgICAgICAgICAgICAgICAgIDogZ2V0Q2h1bmtWYWx1ZShmTm9kZVVSSSwgY2h1bmssIGluZGV4KTsKLQotICAgIH0gLy8gZ2V0Tm9kZVVSSShpbnQsaW50KTpTdHJpbmcKLQotICAgIC8vIGlkZW50aWZpZXIgbWFpbnRlbmFuY2UKLQotICAgIC8qKiBSZWdpc3RlcnMgYW4gaWRlbnRpZmllciBuYW1lIHdpdGggYSBzcGVjaWZpZWQgZWxlbWVudCBub2RlLiAqLwotICAgIHB1YmxpYyB2b2lkIHB1dElkZW50aWZpZXIoU3RyaW5nIG5hbWUsIGludCBlbGVtZW50Tm9kZUluZGV4KSB7Ci0KLSAgICAgICAgaWYgKERFQlVHX0lEUykgewotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJwdXRJZGVudGlmaWVyKCIgKyBuYW1lICsgIiwgIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgZWxlbWVudE5vZGVJbmRleCArICcpJyArICIgLy8gIiArCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0Q2h1bmtWYWx1ZShmTm9kZU5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50Tm9kZUluZGV4ID4+IENIVU5LX1NISUZULAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudE5vZGVJbmRleCAmIENIVU5LX01BU0spKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIGluaXRpYWxpemUgYXJyYXlzCi0gICAgICAgIGlmIChmSWROYW1lID09IG51bGwpIHsKLSAgICAgICAgICAgIGZJZE5hbWUgICAgPSBuZXcgU3RyaW5nWzY0XTsKLSAgICAgICAgICAgIGZJZEVsZW1lbnQgPSBuZXcgaW50WzY0XTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIHJlc2l6ZSBhcnJheXMKLSAgICAgICAgaWYgKGZJZENvdW50ID09IGZJZE5hbWUubGVuZ3RoKSB7Ci0gICAgICAgICAgICBTdHJpbmcgaWROYW1lW10gPSBuZXcgU3RyaW5nW2ZJZENvdW50ICogMl07Ci0gICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGZJZE5hbWUsIDAsIGlkTmFtZSwgMCwgZklkQ291bnQpOwotICAgICAgICAgICAgZklkTmFtZSA9IGlkTmFtZTsKLQotICAgICAgICAgICAgaW50IGlkRWxlbWVudFtdID0gbmV3IGludFtpZE5hbWUubGVuZ3RoXTsKLSAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZklkRWxlbWVudCwgMCwgaWRFbGVtZW50LCAwLCBmSWRDb3VudCk7Ci0gICAgICAgICAgICBmSWRFbGVtZW50ID0gaWRFbGVtZW50OwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gc3RvcmUgaWRlbnRpZmllcgotICAgICAgICBmSWROYW1lW2ZJZENvdW50XSA9IG5hbWU7Ci0gICAgICAgIGZJZEVsZW1lbnRbZklkQ291bnRdID0gZWxlbWVudE5vZGVJbmRleDsKLSAgICAgICAgZklkQ291bnQrKzsKLQotICAgIH0gLy8gcHV0SWRlbnRpZmllcihTdHJpbmcsaW50KQotCi0gICAgLy8KLSAgICAvLyBERUJVRwotICAgIC8vCi0KLSAgICAvKiogUHJpbnRzIG91dCB0aGUgdGFibGVzLiAqLwotICAgIHB1YmxpYyB2b2lkIHByaW50KCkgewotCi0gICAgICAgIGlmIChERUJVR19QUklOVF9SRUZfQ09VTlRTKSB7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCJudW1cdCIpOwotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgidHlwZVx0Iik7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCJuYW1lXHQiKTsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoInZhbFx0Iik7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCJwYXJcdCIpOwotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgibGNoXHQiKTsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoInBzaWIiKTsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigpOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmTm9kZVR5cGUubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgICAgICBpZiAoZk5vZGVUeXBlW2ldICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gc2VwYXJhdG9yCi0gICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIi0tLS0tLS0tIik7Ci0gICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIi0tLS0tLS0tIik7Ci0gICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIi0tLS0tLS0tIik7Ci0gICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIi0tLS0tLS0tIik7Ci0gICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIi0tLS0tLS0tIik7Ci0gICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIi0tLS0tLS0tIik7Ci0gICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIi0tLS0tLS0tIik7Ci0gICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigpOwotCi0gICAgICAgICAgICAgICAgICAgIC8vIHJlZiBjb3VudAotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KGkpOwotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCdcdCcpOwotICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGZOb2RlVHlwZVtpXVtDSFVOS19TSVpFXSkgewotICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBEb2N1bWVudEltcGwuRUxFTUVOVF9ERUZJTklUSU9OX05PREU6IHsgU3lzdGVtLm91dC5wcmludCgiRURlZiIpOyBicmVhazsgfQotICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBOb2RlLkRPQ1VNRU5UX05PREU6IHsgU3lzdGVtLm91dC5wcmludCgiRG9jIik7IGJyZWFrOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIE5vZGUuRE9DVU1FTlRfVFlQRV9OT0RFOiB7IFN5c3RlbS5vdXQucHJpbnQoIkRUeXBlIik7IGJyZWFrOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIE5vZGUuQ09NTUVOVF9OT0RFOiB7IFN5c3RlbS5vdXQucHJpbnQoIkNvbSIpOyBicmVhazsgfQotICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBOb2RlLlBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERTogeyBTeXN0ZW0ub3V0LnByaW50KCJQSSIpOyBicmVhazsgfQotICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBOb2RlLkVMRU1FTlRfTk9ERTogeyBTeXN0ZW0ub3V0LnByaW50KCJFbGVtIik7IGJyZWFrOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIE5vZGUuRU5USVRZX05PREU6IHsgU3lzdGVtLm91dC5wcmludCgiRW50Iik7IGJyZWFrOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIE5vZGUuRU5USVRZX1JFRkVSRU5DRV9OT0RFOiB7IFN5c3RlbS5vdXQucHJpbnQoIkVSZWYiKTsgYnJlYWs7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgTm9kZS5URVhUX05PREU6IHsgU3lzdGVtLm91dC5wcmludCgiVGV4dCIpOyBicmVhazsgfQotICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBOb2RlLkFUVFJJQlVURV9OT0RFOiB7IFN5c3RlbS5vdXQucHJpbnQoIkF0dHIiKTsgYnJlYWs7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgRGVmZXJyZWROb2RlLlRZUEVfTk9ERTogeyBTeXN0ZW0ub3V0LnByaW50KCJUeXBlSW5mbyIpOyBicmVhazsgfQotICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDogeyBTeXN0ZW0ub3V0LnByaW50KCI/IitmTm9kZVR5cGVbaV1bQ0hVTktfU0laRV0pOyB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgnXHQnKTsKLSAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludChmTm9kZU5hbWVbaV1bQ0hVTktfU0laRV0pOwotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCdcdCcpOwotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KGZOb2RlVmFsdWVbaV1bQ0hVTktfU0laRV0pOwotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCdcdCcpOwotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KGZOb2RlVVJJW2ldW0NIVU5LX1NJWkVdKTsKLSAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgnXHQnKTsKLSAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludChmTm9kZVBhcmVudFtpXVtDSFVOS19TSVpFXSk7Ci0gICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoJ1x0Jyk7Ci0gICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoZk5vZGVMYXN0Q2hpbGRbaV1bQ0hVTktfU0laRV0pOwotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCdcdCcpOwotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KGZOb2RlUHJldlNpYltpXVtDSFVOS19TSVpFXSk7Ci0gICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoJ1x0Jyk7Ci0gICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoZk5vZGVFeHRyYVtpXVtDSFVOS19TSVpFXSk7Ci0gICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGlmIChERUJVR19QUklOVF9UQUJMRVMpIHsKLSAgICAgICAgICAgIC8vIFRoaXMgYXNzdW1lcyB0aGF0IHRoZSBkb2N1bWVudCBpcyBzbWFsbAotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCIjIHN0YXJ0IHRhYmxlIik7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZOb2RlQ291bnQ7IGkrKykgewotICAgICAgICAgICAgICAgIGludCBjaHVuayA9IGkgPj4gQ0hVTktfU0hJRlQ7Ci0gICAgICAgICAgICAgICAgaW50IGluZGV4ID0gaSAmIENIVU5LX01BU0s7Ci0gICAgICAgICAgICAgICAgaWYgKGkgJSAxMCA9PSAwKSB7Ci0gICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIm51bVx0Iik7Ci0gICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoInR5cGVcdCIpOwotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCJuYW1lXHQiKTsKLSAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgidmFsXHQiKTsKLSAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgidXJpXHQiKTsKLSAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgicGFyXHQiKTsKLSAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgibGNoXHQiKTsKLSAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgicHNpYlx0Iik7Ci0gICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoInh0cmEiKTsKLSAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoaSk7Ci0gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgnXHQnKTsKLSAgICAgICAgICAgICAgICBzd2l0Y2ggKGdldENodW5rSW5kZXgoZk5vZGVUeXBlLCBjaHVuaywgaW5kZXgpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgRG9jdW1lbnRJbXBsLkVMRU1FTlRfREVGSU5JVElPTl9OT0RFOiB7IFN5c3RlbS5vdXQucHJpbnQoIkVEZWYiKTsgYnJlYWs7IH0KLSAgICAgICAgICAgICAgICAgICAgY2FzZSBOb2RlLkRPQ1VNRU5UX05PREU6IHsgU3lzdGVtLm91dC5wcmludCgiRG9jIik7IGJyZWFrOyB9Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgTm9kZS5ET0NVTUVOVF9UWVBFX05PREU6IHsgU3lzdGVtLm91dC5wcmludCgiRFR5cGUiKTsgYnJlYWs7IH0KLSAgICAgICAgICAgICAgICAgICAgY2FzZSBOb2RlLkNPTU1FTlRfTk9ERTogeyBTeXN0ZW0ub3V0LnByaW50KCJDb20iKTsgYnJlYWs7IH0KLSAgICAgICAgICAgICAgICAgICAgY2FzZSBOb2RlLlBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERTogeyBTeXN0ZW0ub3V0LnByaW50KCJQSSIpOyBicmVhazsgfQotICAgICAgICAgICAgICAgICAgICBjYXNlIE5vZGUuRUxFTUVOVF9OT0RFOiB7IFN5c3RlbS5vdXQucHJpbnQoIkVsZW0iKTsgYnJlYWs7IH0KLSAgICAgICAgICAgICAgICAgICAgY2FzZSBOb2RlLkVOVElUWV9OT0RFOiB7IFN5c3RlbS5vdXQucHJpbnQoIkVudCIpOyBicmVhazsgfQotICAgICAgICAgICAgICAgICAgICBjYXNlIE5vZGUuRU5USVRZX1JFRkVSRU5DRV9OT0RFOiB7IFN5c3RlbS5vdXQucHJpbnQoIkVSZWYiKTsgYnJlYWs7IH0KLSAgICAgICAgICAgICAgICAgICAgY2FzZSBOb2RlLlRFWFRfTk9ERTogeyBTeXN0ZW0ub3V0LnByaW50KCJUZXh0Iik7IGJyZWFrOyB9Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgTm9kZS5BVFRSSUJVVEVfTk9ERTogeyBTeXN0ZW0ub3V0LnByaW50KCJBdHRyIik7IGJyZWFrOyB9Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgRGVmZXJyZWROb2RlLlRZUEVfTk9ERTogeyBTeXN0ZW0ub3V0LnByaW50KCJUeXBlSW5mbyIpOyBicmVhazsgfQotICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OiB7IFN5c3RlbS5vdXQucHJpbnQoIj8iK2dldENodW5rSW5kZXgoZk5vZGVUeXBlLCBjaHVuaywgaW5kZXgpKTsgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCdcdCcpOwotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoZ2V0Q2h1bmtWYWx1ZShmTm9kZU5hbWUsIGNodW5rLCBpbmRleCkpOwotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoJ1x0Jyk7Ci0gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludChnZXROb2RlVmFsdWUoY2h1bmssIGluZGV4KSk7Ci0gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgnXHQnKTsKLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KGdldENodW5rVmFsdWUoZk5vZGVVUkksIGNodW5rLCBpbmRleCkpOwotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoJ1x0Jyk7Ci0gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludChnZXRDaHVua0luZGV4KGZOb2RlUGFyZW50LCBjaHVuaywgaW5kZXgpKTsKLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCdcdCcpOwotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoZ2V0Q2h1bmtJbmRleChmTm9kZUxhc3RDaGlsZCwgY2h1bmssIGluZGV4KSk7Ci0gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgnXHQnKTsKLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KGdldENodW5rSW5kZXgoZk5vZGVQcmV2U2liLCBjaHVuaywgaW5kZXgpKTsKLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCdcdCcpOwotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoZ2V0Q2h1bmtJbmRleChmTm9kZUV4dHJhLCBjaHVuaywgaW5kZXgpKTsKLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiIyBlbmQgdGFibGUiKTsKLSAgICAgICAgfQotCi0gICAgfSAvLyBwcmludCgpCi0KLSAgICAvLwotICAgIC8vIERlZmVycmVkTm9kZSBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKiBSZXR1cm5zIHRoZSBub2RlIGluZGV4LiAqLwotICAgIHB1YmxpYyBpbnQgZ2V0Tm9kZUluZGV4KCkgewotICAgICAgICByZXR1cm4gMDsKLSAgICB9Ci0KLSAgICAvLwotICAgIC8vIFByb3RlY3RlZCBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKiBTeW5jaHJvbml6ZXMgdGhlIG5vZGUncyBkYXRhLiAqLwotICAgIHByb3RlY3RlZCB2b2lkIHN5bmNocm9uaXplRGF0YSgpIHsKLQotICAgICAgICAvLyBubyBuZWVkIHRvIHN5bmMgaW4gdGhlIGZ1dHVyZQotICAgICAgICBuZWVkc1N5bmNEYXRhKGZhbHNlKTsKLQotICAgICAgICAvLyBmbHVmZiB1cCBlbm91Z2ggbm9kZXMgdG8gZmlsbCBpZGVudGlmaWVycyBoYXNoCi0gICAgICAgIGlmIChmSWRFbGVtZW50ICE9IG51bGwpIHsKLQotICAgICAgICAgICAgLy8gUkVWSVNJVDogVGhlcmUgaGFzIHRvIGJlIGEgbW9yZSBlZmZpY2llbnQgd2F5IG9mCi0gICAgICAgICAgICAvLyAgICAgICAgICBkb2luZyB0aGlzLiBCdXQga2VlcCBpbiBtaW5kIHRoYXQgdGhlCi0gICAgICAgICAgICAvLyAgICAgICAgICB0cmVlIGNhbiBoYXZlIGJlZW4gYWx0ZXJlZCBhbmQgcmUtb3JkZXJlZAotICAgICAgICAgICAgLy8gICAgICAgICAgYmVmb3JlIGFsbCBvZiB0aGUgZWxlbWVudCBub2RlcyB3aXRoIElECi0gICAgICAgICAgICAvLyAgICAgICAgICBhdHRyaWJ1dGVzIGhhdmUgYmVlbiByZWdpc3RlcmVkLiBGb3Igbm93Ci0gICAgICAgICAgICAvLyAgICAgICAgICB0aGlzIGlzIHJlYXNvbmFibGUgYW5kIHNhZmUuIC1BYwotCi0gICAgICAgICAgICBJbnRWZWN0b3IgcGF0aCA9IG5ldyBJbnRWZWN0b3IoKTsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZklkQ291bnQ7IGkrKykgewotCi0gICAgICAgICAgICAgICAgLy8gaWdub3JlIGlmIGl0J3MgYWxyZWFkeSBiZWVuIHJlZ2lzdGVyZWQKLSAgICAgICAgICAgICAgICBpbnQgZWxlbWVudE5vZGVJbmRleCA9IGZJZEVsZW1lbnRbaV07Ci0gICAgICAgICAgICAgICAgU3RyaW5nIGlkTmFtZSAgICAgID0gZklkTmFtZVtpXTsKLSAgICAgICAgICAgICAgICBpZiAoaWROYW1lID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgLy8gZmluZCBwYXRoIGZyb20gdGhpcyBlbGVtZW50IHRvIHRoZSByb290Ci0gICAgICAgICAgICAgICAgcGF0aC5yZW1vdmVBbGxFbGVtZW50cygpOwotICAgICAgICAgICAgICAgIGludCBpbmRleCA9IGVsZW1lbnROb2RlSW5kZXg7Ci0gICAgICAgICAgICAgICAgZG8gewotICAgICAgICAgICAgICAgICAgICBwYXRoLmFkZEVsZW1lbnQoaW5kZXgpOwotICAgICAgICAgICAgICAgICAgICBpbnQgcGNodW5rID0gaW5kZXggPj4gQ0hVTktfU0hJRlQ7Ci0gICAgICAgICAgICAgICAgICAgIGludCBwaW5kZXggPSBpbmRleCAmIENIVU5LX01BU0s7Ci0gICAgICAgICAgICAgICAgICAgIGluZGV4ID0gZ2V0Q2h1bmtJbmRleChmTm9kZVBhcmVudCwgcGNodW5rLCBwaW5kZXgpOwotICAgICAgICAgICAgICAgIH0gd2hpbGUgKGluZGV4ICE9IC0xKTsKLQotICAgICAgICAgICAgICAgIC8vIFRyYXZlcnNlIHBhdGggKGJhY2t3YXJkcyksIGZsdWZmaW5nIHRoZSBlbGVtZW50cwotICAgICAgICAgICAgICAgIC8vIGFsb25nIHRoZSB3YXkuIFdoZW4gdGhpcyBsb29wIGZpbmlzaGVzLCAicGxhY2UiCi0gICAgICAgICAgICAgICAgLy8gd2lsbCBjb250YWluIHRoZSByZWZlcmVuY2UgdG8gdGhlIGVsZW1lbnQgbm9kZQotICAgICAgICAgICAgICAgIC8vIHdlJ3JlIGludGVyZXN0ZWQgaW4uIC1BYwotICAgICAgICAgICAgICAgIE5vZGUgcGxhY2UgPSB0aGlzOwotICAgICAgICAgICAgICAgIGZvciAoaW50IGogPSBwYXRoLnNpemUoKSAtIDI7IGogPj0gMDsgai0tKSB7Ci0gICAgICAgICAgICAgICAgICAgIGluZGV4ID0gcGF0aC5lbGVtZW50QXQoaik7Ci0gICAgICAgICAgICAgICAgICAgIE5vZGUgY2hpbGQgPSBwbGFjZS5nZXRMYXN0Q2hpbGQoKTsKLSAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGNoaWxkICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjaGlsZCBpbnN0YW5jZW9mIERlZmVycmVkTm9kZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBub2RlSW5kZXggPQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKERlZmVycmVkTm9kZSljaGlsZCkuZ2V0Tm9kZUluZGV4KCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5vZGVJbmRleCA9PSBpbmRleCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbGFjZSA9IGNoaWxkOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBjaGlsZCA9IGNoaWxkLmdldFByZXZpb3VzU2libGluZygpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgLy8gcmVnaXN0ZXIgdGhlIGVsZW1lbnQKLSAgICAgICAgICAgICAgICBFbGVtZW50IGVsZW1lbnQgPSAoRWxlbWVudClwbGFjZTsKLSAgICAgICAgICAgICAgICBwdXRJZGVudGlmaWVyMChpZE5hbWUsIGVsZW1lbnQpOwotICAgICAgICAgICAgICAgIGZJZE5hbWVbaV0gPSBudWxsOwotCi0gICAgICAgICAgICAgICAgLy8gc2VlIGlmIHRoZXJlIGFyZSBtb3JlIElEcyBvbiB0aGlzIGVsZW1lbnQKLSAgICAgICAgICAgICAgICB3aGlsZSAoaSArIDEgPCBmSWRDb3VudCAmJgotICAgICAgICAgICAgICAgICAgICBmSWRFbGVtZW50W2kgKyAxXSA9PSBlbGVtZW50Tm9kZUluZGV4KSB7Ci0gICAgICAgICAgICAgICAgICAgIGlkTmFtZSA9IGZJZE5hbWVbKytpXTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGlkTmFtZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBwdXRJZGVudGlmaWVyMChpZE5hbWUsIGVsZW1lbnQpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICB9IC8vIGlmIGlkZW50aWZpZXJzCi0KLSAgICB9IC8vIHN5bmNocm9uaXplRGF0YSgpCi0KLSAgICAvKioKLSAgICAgKiBTeW5jaHJvbml6ZXMgdGhlIG5vZGUncyBjaGlsZHJlbiB3aXRoIHRoZSBpbnRlcm5hbCBzdHJ1Y3R1cmUuCi0gICAgICogRmx1ZmZpbmcgdGhlIGNoaWxkcmVuIGF0IG9uY2Ugc29sdmVzIGEgbG90IG9mIHdvcmsgdG8ga2VlcAotICAgICAqIHRoZSB0d28gc3RydWN0dXJlcyBpbiBzeW5jLiBUaGUgcHJvYmxlbSBnZXRzIHdvcnNlIHdoZW4KLSAgICAgKiBlZGl0aW5nIHRoZSB0cmVlIC0tIHRoaXMgbWFrZXMgaXQgYSBsb3QgZWFzaWVyLgotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIHN5bmNocm9uaXplQ2hpbGRyZW4oKSB7Ci0KLSAgICAgICAgaWYgKG5lZWRzU3luY0RhdGEoKSkgewotICAgICAgICAgICAgc3luY2hyb25pemVEYXRhKCk7Ci0gICAgICAgICAgICAvKgotICAgICAgICAgICAgICogd2hlbiB3ZSBoYXZlIGVsZW1lbnRzIHdpdGggSURzIHRoaXMgbWV0aG9kIGlzIGJlaW5nIHJlY3Vyc2l2ZWx5Ci0gICAgICAgICAgICAgKiBjYWxsZWQgZnJvbSBzeW5jaHJvbml6ZURhdGEsIGluIHdoaWNoIGNhc2Ugd2UndmUgYWxyZWFkeSBnb25lCi0gICAgICAgICAgICAgKiB0aHJvdWdoIHRoZSBmb2xsb3dpbmcgYW5kIHdlIGNhbiBub3cgc2ltcGx5IHN0b3AgaGVyZS4KLSAgICAgICAgICAgICAqLwotICAgICAgICAgICAgaWYgKCFuZWVkc1N5bmNDaGlsZHJlbigpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gd2UgZG9uJ3Qgd2FudCB0byBnZW5lcmF0ZSBhbnkgZXZlbnQgZm9yIHRoaXMgc28gdHVybiB0aGVtIG9mZgotICAgICAgICBib29sZWFuIG9yaWcgPSBtdXRhdGlvbkV2ZW50czsKLSAgICAgICAgbXV0YXRpb25FdmVudHMgPSBmYWxzZTsKLQotICAgICAgICAvLyBubyBuZWVkIHRvIHN5bmMgaW4gdGhlIGZ1dHVyZQotICAgICAgICBuZWVkc1N5bmNDaGlsZHJlbihmYWxzZSk7Ci0KLSAgICAgICAgZ2V0Tm9kZVR5cGUoMCk7Ci0KLSAgICAgICAgLy8gY3JlYXRlIGNoaWxkcmVuIGFuZCBsaW5rIHRoZW0gYXMgc2libGluZ3MKLSAgICAgICAgQ2hpbGROb2RlIGZpcnN0ID0gbnVsbDsKLSAgICAgICAgQ2hpbGROb2RlIGxhc3QgPSBudWxsOwotICAgICAgICBmb3IgKGludCBpbmRleCA9IGdldExhc3RDaGlsZCgwKTsKLSAgICAgICAgICAgICBpbmRleCAhPSAtMTsKLSAgICAgICAgICAgICBpbmRleCA9IGdldFByZXZTaWJsaW5nKGluZGV4KSkgewotCi0gICAgICAgICAgICBDaGlsZE5vZGUgbm9kZSA9IChDaGlsZE5vZGUpZ2V0Tm9kZU9iamVjdChpbmRleCk7Ci0gICAgICAgICAgICBpZiAobGFzdCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgbGFzdCA9IG5vZGU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBmaXJzdC5wcmV2aW91c1NpYmxpbmcgPSBub2RlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgbm9kZS5vd25lck5vZGUgPSB0aGlzOwotICAgICAgICAgICAgbm9kZS5pc093bmVkKHRydWUpOwotICAgICAgICAgICAgbm9kZS5uZXh0U2libGluZyA9IGZpcnN0OwotICAgICAgICAgICAgZmlyc3QgPSBub2RlOwotCi0gICAgICAgICAgICAvLyBzYXZlIGRvY3R5cGUgYW5kIGRvY3VtZW50IHR5cGUKLSAgICAgICAgICAgIGludCB0eXBlID0gbm9kZS5nZXROb2RlVHlwZSgpOwotICAgICAgICAgICAgaWYgKHR5cGUgPT0gTm9kZS5FTEVNRU5UX05PREUpIHsKLSAgICAgICAgICAgICAgICBkb2NFbGVtZW50ID0gKEVsZW1lbnRJbXBsKW5vZGU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmICh0eXBlID09IE5vZGUuRE9DVU1FTlRfVFlQRV9OT0RFKSB7Ci0gICAgICAgICAgICAgICAgZG9jVHlwZSA9IChEb2N1bWVudFR5cGVJbXBsKW5vZGU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoZmlyc3QgIT0gbnVsbCkgewotICAgICAgICAgICAgZmlyc3RDaGlsZCA9IGZpcnN0OwotICAgICAgICAgICAgZmlyc3QuaXNGaXJzdENoaWxkKHRydWUpOwotICAgICAgICAgICAgbGFzdENoaWxkKGxhc3QpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gc2V0IG11dGF0aW9uIGV2ZW50cyBmbGFnIGJhY2sgdG8gaXRzIG9yaWdpbmFsIHZhbHVlCi0gICAgICAgIG11dGF0aW9uRXZlbnRzID0gb3JpZzsKLQotICAgIH0gLy8gc3luY2hyb25pemVDaGlsZHJlbigpCi0KLSAgICAvKioKLSAgICAgKiBTeW5jaHJvbml6ZXMgdGhlIG5vZGUncyBjaGlsZHJlbiB3aXRoIHRoZSBpbnRlcm5hbCBzdHJ1Y3R1cmUuCi0gICAgICogRmx1ZmZpbmcgdGhlIGNoaWxkcmVuIGF0IG9uY2Ugc29sdmVzIGEgbG90IG9mIHdvcmsgdG8ga2VlcAotICAgICAqIHRoZSB0d28gc3RydWN0dXJlcyBpbiBzeW5jLiBUaGUgcHJvYmxlbSBnZXRzIHdvcnNlIHdoZW4KLSAgICAgKiBlZGl0aW5nIHRoZSB0cmVlIC0tIHRoaXMgbWFrZXMgaXQgYSBsb3QgZWFzaWVyLgotICAgICAqIFRoaXMgaXMgbm90IGRpcmVjdGx5IHVzZWQgaW4gdGhpcyBjbGFzcyBidXQgdGhpcyBtZXRob2QgaXMKLSAgICAgKiBoZXJlIHNvIHRoYXQgaXQgY2FuIGJlIHNoYXJlZCBieSBhbGwgZGVmZXJyZWQgc3ViY2xhc3NlcyBvZiBBdHRySW1wbC4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgZmluYWwgdm9pZCBzeW5jaHJvbml6ZUNoaWxkcmVuKEF0dHJJbXBsIGEsIGludCBub2RlSW5kZXgpIHsKLQotICAgICAgICAvLyB3ZSBkb24ndCB3YW50IHRvIGdlbmVyYXRlIGFueSBldmVudCBmb3IgdGhpcyBzbyB0dXJuIHRoZW0gb2ZmCi0gICAgICAgIGJvb2xlYW4gb3JpZyA9IGdldE11dGF0aW9uRXZlbnRzKCk7Ci0gICAgICAgIHNldE11dGF0aW9uRXZlbnRzKGZhbHNlKTsKLQotICAgICAgICAvLyBubyBuZWVkIHRvIHN5bmMgaW4gdGhlIGZ1dHVyZQotICAgICAgICBhLm5lZWRzU3luY0NoaWxkcmVuKGZhbHNlKTsKLQotICAgICAgICAvLyBjcmVhdGUgY2hpbGRyZW4gYW5kIGxpbmsgdGhlbSBhcyBzaWJsaW5ncyBvciBzaW1wbHkgc3RvcmUgdGhlIHZhbHVlCi0gICAgICAgIC8vIGFzIGEgU3RyaW5nIGlmIGFsbCB3ZSBoYXZlIGlzIG9uZSBwaWVjZSBvZiB0ZXh0Ci0gICAgICAgIGludCBsYXN0ID0gZ2V0TGFzdENoaWxkKG5vZGVJbmRleCk7Ci0gICAgICAgIGludCBwcmV2ID0gZ2V0UHJldlNpYmxpbmcobGFzdCk7Ci0gICAgICAgIGlmIChwcmV2ID09IC0xKSB7Ci0gICAgICAgICAgICBhLnZhbHVlID0gZ2V0Tm9kZVZhbHVlU3RyaW5nKG5vZGVJbmRleCk7Ci0gICAgICAgICAgICBhLmhhc1N0cmluZ1ZhbHVlKHRydWUpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgQ2hpbGROb2RlIGZpcnN0Tm9kZSA9IG51bGw7Ci0gICAgICAgICAgICBDaGlsZE5vZGUgbGFzdE5vZGUgPSBudWxsOwotICAgICAgICAgICAgZm9yIChpbnQgaW5kZXggPSBsYXN0OyBpbmRleCAhPSAtMTsKLSAgICAgICAgICAgICAgICAgaW5kZXggPSBnZXRQcmV2U2libGluZyhpbmRleCkpIHsKLQotICAgICAgICAgICAgICAgIENoaWxkTm9kZSBub2RlID0gKENoaWxkTm9kZSkgZ2V0Tm9kZU9iamVjdChpbmRleCk7Ci0gICAgICAgICAgICAgICAgaWYgKGxhc3ROb2RlID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgbGFzdE5vZGUgPSBub2RlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgZmlyc3ROb2RlLnByZXZpb3VzU2libGluZyA9IG5vZGU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIG5vZGUub3duZXJOb2RlID0gYTsKLSAgICAgICAgICAgICAgICBub2RlLmlzT3duZWQodHJ1ZSk7Ci0gICAgICAgICAgICAgICAgbm9kZS5uZXh0U2libGluZyA9IGZpcnN0Tm9kZTsKLSAgICAgICAgICAgICAgICBmaXJzdE5vZGUgPSBub2RlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKGxhc3ROb2RlICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBhLnZhbHVlID0gZmlyc3ROb2RlOyAvLyBmaXJzdENoaWxkID0gZmlyc3ROb2RlCi0gICAgICAgICAgICAgICAgZmlyc3ROb2RlLmlzRmlyc3RDaGlsZCh0cnVlKTsKLSAgICAgICAgICAgICAgICBhLmxhc3RDaGlsZChsYXN0Tm9kZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBhLmhhc1N0cmluZ1ZhbHVlKGZhbHNlKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIHNldCBtdXRhdGlvbiBldmVudHMgZmxhZyBiYWNrIHRvIGl0cyBvcmlnaW5hbCB2YWx1ZQotICAgICAgICBzZXRNdXRhdGlvbkV2ZW50cyhvcmlnKTsKLQotICAgIH0gLy8gc3luY2hyb25pemVDaGlsZHJlbihBdHRySW1wbCxpbnQpOnZvaWQKLQotCi0gICAgLyoqCi0gICAgICogU3luY2hyb25pemVzIHRoZSBub2RlJ3MgY2hpbGRyZW4gd2l0aCB0aGUgaW50ZXJuYWwgc3RydWN0dXJlLgotICAgICAqIEZsdWZmaW5nIHRoZSBjaGlsZHJlbiBhdCBvbmNlIHNvbHZlcyBhIGxvdCBvZiB3b3JrIHRvIGtlZXAKLSAgICAgKiB0aGUgdHdvIHN0cnVjdHVyZXMgaW4gc3luYy4gVGhlIHByb2JsZW0gZ2V0cyB3b3JzZSB3aGVuCi0gICAgICogZWRpdGluZyB0aGUgdHJlZSAtLSB0aGlzIG1ha2VzIGl0IGEgbG90IGVhc2llci4KLSAgICAgKiBUaGlzIGlzIG5vdCBkaXJlY3RseSB1c2VkIGluIHRoaXMgY2xhc3MgYnV0IHRoaXMgbWV0aG9kIGlzCi0gICAgICogaGVyZSBzbyB0aGF0IGl0IGNhbiBiZSBzaGFyZWQgYnkgYWxsIGRlZmVycmVkIHN1YmNsYXNzZXMgb2YgUGFyZW50Tm9kZS4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgZmluYWwgdm9pZCBzeW5jaHJvbml6ZUNoaWxkcmVuKFBhcmVudE5vZGUgcCwgaW50IG5vZGVJbmRleCkgewotCi0gICAgICAgIC8vIHdlIGRvbid0IHdhbnQgdG8gZ2VuZXJhdGUgYW55IGV2ZW50IGZvciB0aGlzIHNvIHR1cm4gdGhlbSBvZmYKLSAgICAgICAgYm9vbGVhbiBvcmlnID0gZ2V0TXV0YXRpb25FdmVudHMoKTsKLSAgICAgICAgc2V0TXV0YXRpb25FdmVudHMoZmFsc2UpOwotCi0gICAgICAgIC8vIG5vIG5lZWQgdG8gc3luYyBpbiB0aGUgZnV0dXJlCi0gICAgICAgIHAubmVlZHNTeW5jQ2hpbGRyZW4oZmFsc2UpOwotCi0gICAgICAgIC8vIGNyZWF0ZSBjaGlsZHJlbiBhbmQgbGluayB0aGVtIGFzIHNpYmxpbmdzCi0gICAgICAgIENoaWxkTm9kZSBmaXJzdE5vZGUgPSBudWxsOwotICAgICAgICBDaGlsZE5vZGUgbGFzdE5vZGUgPSBudWxsOwotICAgICAgICBmb3IgKGludCBpbmRleCA9IGdldExhc3RDaGlsZChub2RlSW5kZXgpOwotICAgICAgICAgICAgIGluZGV4ICE9IC0xOwotICAgICAgICAgICAgIGluZGV4ID0gZ2V0UHJldlNpYmxpbmcoaW5kZXgpKSB7Ci0KLSAgICAgICAgICAgIENoaWxkTm9kZSBub2RlID0gKENoaWxkTm9kZSkgZ2V0Tm9kZU9iamVjdChpbmRleCk7Ci0gICAgICAgICAgICBpZiAobGFzdE5vZGUgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGxhc3ROb2RlID0gbm9kZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIGZpcnN0Tm9kZS5wcmV2aW91c1NpYmxpbmcgPSBub2RlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgbm9kZS5vd25lck5vZGUgPSBwOwotICAgICAgICAgICAgbm9kZS5pc093bmVkKHRydWUpOwotICAgICAgICAgICAgbm9kZS5uZXh0U2libGluZyA9IGZpcnN0Tm9kZTsKLSAgICAgICAgICAgIGZpcnN0Tm9kZSA9IG5vZGU7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGxhc3ROb2RlICE9IG51bGwpIHsKLSAgICAgICAgICAgIHAuZmlyc3RDaGlsZCA9IGZpcnN0Tm9kZTsKLSAgICAgICAgICAgIGZpcnN0Tm9kZS5pc0ZpcnN0Q2hpbGQodHJ1ZSk7Ci0gICAgICAgICAgICBwLmxhc3RDaGlsZChsYXN0Tm9kZSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBzZXQgbXV0YXRpb24gZXZlbnRzIGZsYWcgYmFjayB0byBpdHMgb3JpZ2luYWwgdmFsdWUKLSAgICAgICAgc2V0TXV0YXRpb25FdmVudHMob3JpZyk7Ci0KLSAgICB9IC8vIHN5bmNocm9uaXplQ2hpbGRyZW4oUGFyZW50Tm9kZSxpbnQpOnZvaWQKLQotICAgIC8vIHV0aWxpdHkgbWV0aG9kcwotCi0gICAgLyoqIEVuc3VyZXMgdGhhdCB0aGUgaW50ZXJuYWwgdGFibGVzIGFyZSBsYXJnZSBlbm91Z2guICovCi0gICAgcHJvdGVjdGVkIHZvaWQgZW5zdXJlQ2FwYWNpdHkoaW50IGNodW5rKSB7Ci0gICAgICAgIGlmIChmTm9kZVR5cGUgPT0gbnVsbCkgewotICAgICAgICAgICAgLy8gY3JlYXRlIGJ1ZmZlcnMKLSAgICAgICAgICAgIGZOb2RlVHlwZSAgICAgICA9IG5ldyBpbnRbSU5JVElBTF9DSFVOS19DT1VOVF1bXTsKLSAgICAgICAgICAgIGZOb2RlTmFtZSAgICAgICA9IG5ldyBPYmplY3RbSU5JVElBTF9DSFVOS19DT1VOVF1bXTsKLSAgICAgICAgICAgIGZOb2RlVmFsdWUgICAgICA9IG5ldyBPYmplY3RbSU5JVElBTF9DSFVOS19DT1VOVF1bXTsKLSAgICAgICAgICAgIGZOb2RlUGFyZW50ICAgICA9IG5ldyBpbnRbSU5JVElBTF9DSFVOS19DT1VOVF1bXTsKLSAgICAgICAgICAgIGZOb2RlTGFzdENoaWxkICA9IG5ldyBpbnRbSU5JVElBTF9DSFVOS19DT1VOVF1bXTsKLSAgICAgICAgICAgIGZOb2RlUHJldlNpYiAgICA9IG5ldyBpbnRbSU5JVElBTF9DSFVOS19DT1VOVF1bXTsKLSAgICAgICAgICAgIGZOb2RlVVJJICAgICAgICA9IG5ldyBPYmplY3RbSU5JVElBTF9DSFVOS19DT1VOVF1bXTsKLSAgICAgICAgICAgIGZOb2RlRXh0cmEgICAgICA9IG5ldyBpbnRbSU5JVElBTF9DSFVOS19DT1VOVF1bXTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChmTm9kZVR5cGUubGVuZ3RoIDw9IGNodW5rKSB7Ci0gICAgICAgICAgICAvLyByZXNpemUgdGhlIHRhYmxlcwotICAgICAgICAgICAgaW50IG5ld3NpemUgPSBjaHVuayAqIDI7Ci0KLSAgICAgICAgICAgIGludFtdW10gbmV3QXJyYXkgPSBuZXcgaW50W25ld3NpemVdW107Ci0gICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGZOb2RlVHlwZSwgMCwgbmV3QXJyYXksIDAsIGNodW5rKTsKLSAgICAgICAgICAgIGZOb2RlVHlwZSA9IG5ld0FycmF5OwotCi0gICAgICAgICAgICBPYmplY3RbXVtdIG5ld1N0ckFycmF5ID0gbmV3IE9iamVjdFtuZXdzaXplXVtdOwotICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShmTm9kZU5hbWUsIDAsIG5ld1N0ckFycmF5LCAwLCBjaHVuayk7Ci0gICAgICAgICAgICBmTm9kZU5hbWUgPSBuZXdTdHJBcnJheTsKLQotICAgICAgICAgICAgbmV3U3RyQXJyYXkgPSBuZXcgT2JqZWN0W25ld3NpemVdW107Ci0gICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGZOb2RlVmFsdWUsIDAsIG5ld1N0ckFycmF5LCAwLCBjaHVuayk7Ci0gICAgICAgICAgICBmTm9kZVZhbHVlID0gbmV3U3RyQXJyYXk7Ci0KLSAgICAgICAgICAgIG5ld0FycmF5ID0gbmV3IGludFtuZXdzaXplXVtdOwotICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShmTm9kZVBhcmVudCwgMCwgbmV3QXJyYXksIDAsIGNodW5rKTsKLSAgICAgICAgICAgIGZOb2RlUGFyZW50ID0gbmV3QXJyYXk7Ci0KLSAgICAgICAgICAgIG5ld0FycmF5ID0gbmV3IGludFtuZXdzaXplXVtdOwotICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShmTm9kZUxhc3RDaGlsZCwgMCwgbmV3QXJyYXksIDAsIGNodW5rKTsKLSAgICAgICAgICAgIGZOb2RlTGFzdENoaWxkID0gbmV3QXJyYXk7Ci0KLSAgICAgICAgICAgIG5ld0FycmF5ID0gbmV3IGludFtuZXdzaXplXVtdOwotICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShmTm9kZVByZXZTaWIsIDAsIG5ld0FycmF5LCAwLCBjaHVuayk7Ci0gICAgICAgICAgICBmTm9kZVByZXZTaWIgPSBuZXdBcnJheTsKLQotICAgICAgICAgICAgbmV3U3RyQXJyYXkgPSBuZXcgT2JqZWN0W25ld3NpemVdW107Ci0gICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGZOb2RlVVJJLCAwLCBuZXdTdHJBcnJheSwgMCwgY2h1bmspOwotICAgICAgICAgICAgZk5vZGVVUkkgPSBuZXdTdHJBcnJheTsKLQotICAgICAgICAgICAgbmV3QXJyYXkgPSBuZXcgaW50W25ld3NpemVdW107Ci0gICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGZOb2RlRXh0cmEsIDAsIG5ld0FycmF5LCAwLCBjaHVuayk7Ci0gICAgICAgICAgICBmTm9kZUV4dHJhID0gbmV3QXJyYXk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoZk5vZGVUeXBlW2NodW5rXSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAvLyBEb25lIC0gdGhlcmUncyBzdWZmaWNpZW50IGNhcGFjaXR5Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBjcmVhdGUgbmV3IGNodW5rcwotICAgICAgICBjcmVhdGVDaHVuayhmTm9kZVR5cGUsIGNodW5rKTsKLSAgICAgICAgY3JlYXRlQ2h1bmsoZk5vZGVOYW1lLCBjaHVuayk7Ci0gICAgICAgIGNyZWF0ZUNodW5rKGZOb2RlVmFsdWUsIGNodW5rKTsKLSAgICAgICAgY3JlYXRlQ2h1bmsoZk5vZGVQYXJlbnQsIGNodW5rKTsKLSAgICAgICAgY3JlYXRlQ2h1bmsoZk5vZGVMYXN0Q2hpbGQsIGNodW5rKTsKLSAgICAgICAgY3JlYXRlQ2h1bmsoZk5vZGVQcmV2U2liLCBjaHVuayk7Ci0gICAgICAgIGNyZWF0ZUNodW5rKGZOb2RlVVJJLCBjaHVuayk7Ci0gICAgICAgIGNyZWF0ZUNodW5rKGZOb2RlRXh0cmEsIGNodW5rKTsKLQotICAgICAgICAvLyBEb25lCi0gICAgICAgIHJldHVybjsKLQotICAgIH0gLy8gZW5zdXJlQ2FwYWNpdHkoaW50LGludCkKLQotICAgIC8qKiBDcmVhdGVzIGEgbm9kZSBvZiB0aGUgc3BlY2lmaWVkIHR5cGUuICovCi0gICAgcHJvdGVjdGVkIGludCBjcmVhdGVOb2RlKHNob3J0IG5vZGVUeXBlKSB7Ci0gICAgICAgIC8vIGVuc3VyZSB0YWJsZXMgYXJlIGxhcmdlIGVub3VnaAotICAgICAgICBpbnQgY2h1bmsgPSBmTm9kZUNvdW50ID4+IENIVU5LX1NISUZUOwotICAgICAgICBpbnQgaW5kZXggPSBmTm9kZUNvdW50ICYgQ0hVTktfTUFTSzsKLSAgICAgICAgZW5zdXJlQ2FwYWNpdHkoY2h1bmspOwotCi0gICAgICAgIC8vIGluaXRpYWxpemUgbm9kZQotICAgICAgICBzZXRDaHVua0luZGV4KGZOb2RlVHlwZSwgbm9kZVR5cGUsIGNodW5rLCBpbmRleCk7Ci0KLSAgICAgICAgLy8gcmV0dXJuIG5vZGUgaW5kZXggbnVtYmVyCi0gICAgICAgIHJldHVybiBmTm9kZUNvdW50Kys7Ci0KLSAgICB9IC8vIGNyZWF0ZU5vZGUoc2hvcnQpOmludAotCi0gICAgLyoqCi0gICAgICogUGVyZm9ybXMgYSBiaW5hcnkgc2VhcmNoIGZvciBhIHRhcmdldCB2YWx1ZSBpbiBhbiBhcnJheSBvZgotICAgICAqIHZhbHVlcy4gVGhlIGFycmF5IG9mIHZhbHVlcyBtdXN0IGJlIGluIGFzY2VuZGluZyBzb3J0ZWQgb3JkZXIKLSAgICAgKiBiZWZvcmUgY2FsbGluZyB0aGlzIG1ldGhvZCBhbmQgYWxsIGFycmF5IHZhbHVlcyBtdXN0IGJlCi0gICAgICogbm9uLW5lZ2F0aXZlLgotICAgICAqCi0gICAgICogQHBhcmFtIHZhbHVlcyAgVGhlIGFycmF5IG9mIHZhbHVlcyB0byBzZWFyY2guCi0gICAgICogQHBhcmFtIHN0YXJ0ICAgVGhlIHN0YXJ0aW5nIG9mZnNldCBvZiB0aGUgc2VhcmNoLgotICAgICAqIEBwYXJhbSBlbmQgICAgIFRoZSBlbmRpbmcgb2Zmc2V0IG9mIHRoZSBzZWFyY2guCi0gICAgICogQHBhcmFtIHRhcmdldCAgVGhlIHRhcmdldCB2YWx1ZS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhpcyBmdW5jdGlvbiB3aWxsIHJldHVybiB0aGUgPGk+Zmlyc3Q8L2k+IG9jY3VycmVuY2UKLSAgICAgKiAgICAgICAgIG9mIHRoZSB0YXJnZXQgdmFsdWUsIG9yIC0xIGlmIHRoZSB0YXJnZXQgdmFsdWUgY2Fubm90Ci0gICAgICogICAgICAgICBiZSBmb3VuZC4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGludCBiaW5hcnlTZWFyY2goZmluYWwgaW50IHZhbHVlc1tdLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgc3RhcnQsIGludCBlbmQsIGludCB0YXJnZXQpIHsKLQotICAgICAgICBpZiAoREVCVUdfSURTKSB7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oImJpbmFyeVNlYXJjaCgpLCB0YXJnZXQ6ICIrdGFyZ2V0KTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIGxvb2sgZm9yIHRhcmdldCB2YWx1ZQotICAgICAgICB3aGlsZSAoc3RhcnQgPD0gZW5kKSB7Ci0KLSAgICAgICAgICAgIC8vIGlzIHRoaXMgdGhlIG9uZSB3ZSdyZSBsb29raW5nIGZvcj8KLSAgICAgICAgICAgIGludCBtaWRkbGUgPSAoc3RhcnQgKyBlbmQpID4+PiAxOwotICAgICAgICAgICAgaW50IHZhbHVlICA9IHZhbHVlc1ttaWRkbGVdOwotICAgICAgICAgICAgaWYgKERFQlVHX0lEUykgewotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIiAgdmFsdWU6ICIrdmFsdWUrIiwgdGFyZ2V0OiAiK3RhcmdldCsiIC8vICIpOwotICAgICAgICAgICAgICAgIHByaW50KHZhbHVlcywgc3RhcnQsIGVuZCwgbWlkZGxlLCB0YXJnZXQpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKHZhbHVlID09IHRhcmdldCkgewotICAgICAgICAgICAgICAgIHdoaWxlIChtaWRkbGUgPiAwICYmIHZhbHVlc1ttaWRkbGUgLSAxXSA9PSB0YXJnZXQpIHsKLSAgICAgICAgICAgICAgICAgICAgbWlkZGxlLS07Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGlmIChERUJVR19JRFMpIHsKLSAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJGT1VORCBBVCAiK21pZGRsZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHJldHVybiBtaWRkbGU7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIGlzIHRoaXMgcG9pbnQgaGlnaGVyIG9yIGxvd2VyPwotICAgICAgICAgICAgaWYgKHZhbHVlID4gdGFyZ2V0KSB7Ci0gICAgICAgICAgICAgICAgZW5kID0gbWlkZGxlIC0gMTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIHN0YXJ0ID0gbWlkZGxlICsgMTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICB9IC8vIHdoaWxlCi0KLSAgICAgICAgLy8gbm90IGZvdW5kCi0gICAgICAgIGlmIChERUJVR19JRFMpIHsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiTk9UIEZPVU5EISIpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiAtMTsKLQotICAgIH0gLy8gYmluYXJ5U2VhcmNoKGludFtdLGludCxpbnQsaW50KTppbnQKLQotICAgIC8vCi0gICAgLy8gUHJpdmF0ZSBtZXRob2RzCi0gICAgLy8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnRbXSBJTklUX0FSUkFZID0gbmV3IGludFtDSFVOS19TSVpFICsgMV07Ci0gICAgc3RhdGljIHsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBDSFVOS19TSVpFOyBpKyspIHsKLSAgICAgICAgICAgIElOSVRfQVJSQVlbaV0gPSAtMTsKLSAgICAgICAgfQotICAgIH0KLSAgICAvKiogQ3JlYXRlcyB0aGUgc3BlY2lmaWVkIGNodW5rIGluIHRoZSBnaXZlbiBhcnJheSBvZiBjaHVua3MuICovCi0gICAgcHJpdmF0ZSBmaW5hbCB2b2lkIGNyZWF0ZUNodW5rKGludCBkYXRhW11bXSwgaW50IGNodW5rKSB7Ci0gICAgICAgIGRhdGFbY2h1bmtdID0gbmV3IGludFtDSFVOS19TSVpFICsgMV07Ci0gICAgICAgIFN5c3RlbS5hcnJheWNvcHkoSU5JVF9BUlJBWSwgMCwgZGF0YVtjaHVua10sIDAsIENIVU5LX1NJWkUpOwotICAgIH0KLQotICAgIHN0YXRpYyBmaW5hbCBjbGFzcyBSZWZDb3VudCB7Ci0gICAgICAgIGludCBmQ291bnQ7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBmaW5hbCB2b2lkIGNyZWF0ZUNodW5rKE9iamVjdCBkYXRhW11bXSwgaW50IGNodW5rKSB7Ci0gICAgICAgIGRhdGFbY2h1bmtdID0gbmV3IE9iamVjdFtDSFVOS19TSVpFICsgMV07Ci0gICAgICAgIGRhdGFbY2h1bmtdW0NIVU5LX1NJWkVdID0gbmV3IFJlZkNvdW50KCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0cyB0aGUgc3BlY2lmaWVkIHZhbHVlIGluIHRoZSBnaXZlbiBvZiBkYXRhIGF0IHRoZSBjaHVuayBhbmQgaW5kZXguCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFJldHVybnMgdGhlIG9sZCB2YWx1ZS4KLSAgICAgKi8KLSAgICBwcml2YXRlIGZpbmFsIGludCBzZXRDaHVua0luZGV4KGludCBkYXRhW11bXSwgaW50IHZhbHVlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGNodW5rLCBpbnQgaW5kZXgpIHsKLSAgICAgICAgaWYgKHZhbHVlID09IC0xKSB7Ci0gICAgICAgICAgICByZXR1cm4gY2xlYXJDaHVua0luZGV4KGRhdGEsIGNodW5rLCBpbmRleCk7Ci0gICAgICAgIH0KLSAgICAgICAgaW50IFtdIGRhdGFDaHVuayA9IGRhdGFbY2h1bmtdOwotICAgICAgICAvLyBSZS1jcmVhdGUgY2h1bmsgaWYgaXQgd2FzIGRlbGV0ZWQuCi0gICAgICAgIGlmIChkYXRhQ2h1bmsgPT0gbnVsbCkgewotICAgICAgICAgICAgY3JlYXRlQ2h1bmsoZGF0YSwgY2h1bmspOwotICAgICAgICAgICAgZGF0YUNodW5rID0gZGF0YVtjaHVua107Ci0gICAgICAgIH0KLSAgICAgICAgaW50IG92YWx1ZSA9IGRhdGFDaHVua1tpbmRleF07Ci0gICAgICAgIGlmIChvdmFsdWUgPT0gLTEpIHsKLSAgICAgICAgICAgIGRhdGFDaHVua1tDSFVOS19TSVpFXSsrOwotICAgICAgICB9Ci0gICAgICAgIGRhdGFDaHVua1tpbmRleF0gPSB2YWx1ZTsKLSAgICAgICAgcmV0dXJuIG92YWx1ZTsKLSAgICB9Ci0gICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgc2V0Q2h1bmtWYWx1ZShPYmplY3QgZGF0YVtdW10sIE9iamVjdCB2YWx1ZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBjaHVuaywgaW50IGluZGV4KSB7Ci0gICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gY2xlYXJDaHVua1ZhbHVlKGRhdGEsIGNodW5rLCBpbmRleCk7Ci0gICAgICAgIH0KLSAgICAgICAgT2JqZWN0IFtdIGRhdGFDaHVuayA9IGRhdGFbY2h1bmtdOwotICAgICAgICAvLyBSZS1jcmVhdGUgY2h1bmsgaWYgaXQgd2FzIGRlbGV0ZWQuCi0gICAgICAgIGlmIChkYXRhQ2h1bmsgPT0gbnVsbCkgewotICAgICAgICAgICAgY3JlYXRlQ2h1bmsoZGF0YSwgY2h1bmspOwotICAgICAgICAgICAgZGF0YUNodW5rID0gZGF0YVtjaHVua107Ci0gICAgICAgIH0KLSAgICAgICAgU3RyaW5nIG92YWx1ZSA9IChTdHJpbmcpIGRhdGFDaHVua1tpbmRleF07Ci0gICAgICAgIGlmIChvdmFsdWUgPT0gbnVsbCkgewotICAgICAgICAgICAgUmVmQ291bnQgYyA9IChSZWZDb3VudCkgZGF0YUNodW5rW0NIVU5LX1NJWkVdOwotICAgICAgICAgICAgYy5mQ291bnQrKzsKLSAgICAgICAgfQotICAgICAgICBkYXRhQ2h1bmtbaW5kZXhdID0gdmFsdWU7Ci0gICAgICAgIHJldHVybiBvdmFsdWU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgc3BlY2lmaWVkIHZhbHVlIGluIHRoZSBnaXZlbiBkYXRhIGF0IHRoZSBjaHVuayBhbmQgaW5kZXguCi0gICAgICovCi0gICAgcHJpdmF0ZSBmaW5hbCBpbnQgZ2V0Q2h1bmtJbmRleChpbnQgZGF0YVtdW10sIGludCBjaHVuaywgaW50IGluZGV4KSB7Ci0gICAgICAgIHJldHVybiBkYXRhW2NodW5rXSAhPSBudWxsID8gZGF0YVtjaHVua11baW5kZXhdIDogLTE7Ci0gICAgfQotICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIGdldENodW5rVmFsdWUoT2JqZWN0IGRhdGFbXVtdLCBpbnQgY2h1bmssIGludCBpbmRleCkgewotICAgICAgICByZXR1cm4gZGF0YVtjaHVua10gIT0gbnVsbCA/IChTdHJpbmcpIGRhdGFbY2h1bmtdW2luZGV4XSA6IG51bGw7Ci0gICAgfQotICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIGdldE5vZGVWYWx1ZShpbnQgY2h1bmssIGludCBpbmRleCkgewotICAgICAgICBPYmplY3QgZGF0YSA9IGZOb2RlVmFsdWVbY2h1bmtdW2luZGV4XTsKLSAgICAgICAgaWYgKGRhdGEgPT0gbnVsbCl7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChkYXRhIGluc3RhbmNlb2YgU3RyaW5nKXsKLSAgICAgICAgICAgIHJldHVybiAoU3RyaW5nKWRhdGE7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAvLyB0eXBlIGluZm9ybWF0aW9uCi0gICAgICAgICAgICByZXR1cm4gZGF0YS50b1N0cmluZygpOwotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBDbGVhcnMgdGhlIHNwZWNpZmllZCB2YWx1ZSBpbiB0aGUgZ2l2ZW4gZGF0YSBhdCB0aGUgY2h1bmsgYW5kIGluZGV4LgotICAgICAqIE5vdGUgdGhhdCB0aGlzIG1ldGhvZCB3aWxsIGNsZWFyIHRoZSBnaXZlbiBjaHVuayBpZiB0aGUgcmVmZXJlbmNlCi0gICAgICogY291bnQgYmVjb21lcyB6ZXJvLgotICAgICAqCi0gICAgICogQHJldHVybiBSZXR1cm5zIHRoZSBvbGQgdmFsdWUuCi0gICAgICovCi0gICAgcHJpdmF0ZSBmaW5hbCBpbnQgY2xlYXJDaHVua0luZGV4KGludCBkYXRhW11bXSwgaW50IGNodW5rLCBpbnQgaW5kZXgpIHsKLSAgICAgICAgaW50IHZhbHVlID0gZGF0YVtjaHVua10gIT0gbnVsbCA/IGRhdGFbY2h1bmtdW2luZGV4XSA6IC0xOwotICAgICAgICBpZiAodmFsdWUgIT0gLTEpIHsKLSAgICAgICAgICAgIGRhdGFbY2h1bmtdW0NIVU5LX1NJWkVdLS07Ci0gICAgICAgICAgICBkYXRhW2NodW5rXVtpbmRleF0gPSAtMTsKLSAgICAgICAgICAgIGlmIChkYXRhW2NodW5rXVtDSFVOS19TSVpFXSA9PSAwKSB7Ci0gICAgICAgICAgICAgICAgZGF0YVtjaHVua10gPSBudWxsOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiB2YWx1ZTsKLSAgICB9Ci0gICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgY2xlYXJDaHVua1ZhbHVlKE9iamVjdCBkYXRhW11bXSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGNodW5rLCBpbnQgaW5kZXgpIHsKLSAgICAgICAgU3RyaW5nIHZhbHVlID0gZGF0YVtjaHVua10gIT0gbnVsbCA/IChTdHJpbmcpZGF0YVtjaHVua11baW5kZXhdIDogbnVsbDsKLSAgICAgICAgaWYgKHZhbHVlICE9IG51bGwpIHsKLSAgICAgICAgICAgIGRhdGFbY2h1bmtdW2luZGV4XSA9IG51bGw7Ci0gICAgICAgICAgICBSZWZDb3VudCBjID0gKFJlZkNvdW50KSBkYXRhW2NodW5rXVtDSFVOS19TSVpFXTsKLSAgICAgICAgICAgIGMuZkNvdW50LS07Ci0gICAgICAgICAgICBpZiAoYy5mQ291bnQgPT0gMCkgewotICAgICAgICAgICAgICAgIGRhdGFbY2h1bmtdID0gbnVsbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gdmFsdWU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyB2ZXJzaW9uIG9mIHB1dElkZW50aWZpZXIgaXMgbmVlZGVkIHRvIGF2b2lkIGZsdWZmaW5nCi0gICAgICogYWxsIG9mIHRoZSBwYXRocyB0byBJRCBhdHRyaWJ1dGVzIHdoZW4gYSBub2RlIG9iamVjdCBpcwotICAgICAqIGNyZWF0ZWQgdGhhdCBjb250YWlucyBhbiBJRCBhdHRyaWJ1dGUuCi0gICAgICovCi0gICAgcHJpdmF0ZSBmaW5hbCB2b2lkIHB1dElkZW50aWZpZXIwKFN0cmluZyBpZE5hbWUsIEVsZW1lbnQgZWxlbWVudCkgewotCi0gICAgICAgIGlmIChERUJVR19JRFMpIHsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigicHV0SWRlbnRpZmllcjAoIisKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZE5hbWUrIiwgIisKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50KycpJyk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBjcmVhdGUgTWFwCi0gICAgICAgIGlmIChpZGVudGlmaWVycyA9PSBudWxsKSB7Ci0gICAgICAgICAgICBpZGVudGlmaWVycyA9IG5ldyBIYXNoTWFwPD4oKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIHNhdmUgSUQgYW5kIGl0cyBhc3NvY2lhdGVkIGVsZW1lbnQKLSAgICAgICAgaWRlbnRpZmllcnMucHV0KGlkTmFtZSwgZWxlbWVudCk7Ci0KLSAgICB9IC8vIHB1dElkZW50aWZpZXIwKFN0cmluZyxFbGVtZW50KQotCi0gICAgLyoqIFByaW50cyB0aGUgSUQgYXJyYXkuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBwcmludChpbnQgdmFsdWVzW10sIGludCBzdGFydCwgaW50IGVuZCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBtaWRkbGUsIGludCB0YXJnZXQpIHsKLQotICAgICAgICBpZiAoREVCVUdfSURTKSB7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KHN0YXJ0KTsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIiBbIik7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykgewotICAgICAgICAgICAgICAgIGlmIChtaWRkbGUgPT0gaSkgewotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCIhIik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQodmFsdWVzW2ldKTsKLSAgICAgICAgICAgICAgICBpZiAodmFsdWVzW2ldID09IHRhcmdldCkgewotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCIqIik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGlmIChpIDwgZW5kIC0gMSkgewotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCIgIik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJdICIrZW5kKTsKLSAgICAgICAgfQotCi0gICAgfSAvLyBwcmludChpbnRbXSxpbnQsaW50LGludCxpbnQpCi0KLSAgICAvLwotICAgIC8vIENsYXNzZXMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogQSBzaW1wbGUgaW50ZWdlciB2ZWN0b3IuCi0gICAgICovCi0gICAgc3RhdGljIGZpbmFsIGNsYXNzIEludFZlY3RvciB7Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gRGF0YQotICAgICAgICAvLwotCi0gICAgICAgIC8qKiBEYXRhLiAqLwotICAgICAgICBwcml2YXRlIGludCBkYXRhW107Ci0KLSAgICAgICAgLyoqIFNpemUuICovCi0gICAgICAgIHByaXZhdGUgaW50IHNpemU7Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gUHVibGljIG1ldGhvZHMKLSAgICAgICAgLy8KLQotICAgICAgICAvKiogUmV0dXJucyB0aGUgbGVuZ3RoIG9mIHRoaXMgdmVjdG9yLiAqLwotICAgICAgICBwdWJsaWMgaW50IHNpemUoKSB7Ci0gICAgICAgICAgICByZXR1cm4gc2l6ZTsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKiBSZXR1cm5zIHRoZSBlbGVtZW50IGF0IHRoZSBzcGVjaWZpZWQgaW5kZXguICovCi0gICAgICAgIHB1YmxpYyBpbnQgZWxlbWVudEF0KGludCBpbmRleCkgewotICAgICAgICAgICAgcmV0dXJuIGRhdGFbaW5kZXhdOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqIEFwcGVuZHMgYW4gZWxlbWVudCB0byB0aGUgZW5kIG9mIHRoZSB2ZWN0b3IuICovCi0gICAgICAgIHB1YmxpYyB2b2lkIGFkZEVsZW1lbnQoaW50IGVsZW1lbnQpIHsKLSAgICAgICAgICAgIGVuc3VyZUNhcGFjaXR5KHNpemUgKyAxKTsKLSAgICAgICAgICAgIGRhdGFbc2l6ZSsrXSA9IGVsZW1lbnQ7Ci0gICAgICAgIH0KLQotICAgICAgICAvKiogQ2xlYXJzIHRoZSB2ZWN0b3IuICovCi0gICAgICAgIHB1YmxpYyB2b2lkIHJlbW92ZUFsbEVsZW1lbnRzKCkgewotICAgICAgICAgICAgc2l6ZSA9IDA7Ci0gICAgICAgIH0KLQotICAgICAgICAvLwotICAgICAgICAvLyBQcml2YXRlIG1ldGhvZHMKLSAgICAgICAgLy8KLQotICAgICAgICAvKiogTWFrZXMgc3VyZSB0aGF0IHRoZXJlIGlzIGVub3VnaCBzdG9yYWdlLiAqLwotICAgICAgICBwcml2YXRlIHZvaWQgZW5zdXJlQ2FwYWNpdHkoaW50IG5ld3NpemUpIHsKLQotICAgICAgICAgICAgaWYgKGRhdGEgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGRhdGEgPSBuZXcgaW50W25ld3NpemUgKyAxNV07Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChuZXdzaXplID4gZGF0YS5sZW5ndGgpIHsKLSAgICAgICAgICAgICAgICBpbnQgbmV3ZGF0YVtdID0gbmV3IGludFtuZXdzaXplICsgMTVdOwotICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZGF0YSwgMCwgbmV3ZGF0YSwgMCwgZGF0YS5sZW5ndGgpOwotICAgICAgICAgICAgICAgIGRhdGEgPSBuZXdkYXRhOwotICAgICAgICAgICAgfQotCi0gICAgICAgIH0gLy8gZW5zdXJlQ2FwYWNpdHkoaW50KQotCi0gICAgfSAvLyBjbGFzcyBJbnRWZWN0b3IKLQotfSAvLyBjbGFzcyBEZWZlcnJlZERvY3VtZW50SW1wbApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL0RlZmVycmVkRG9jdW1lbnRUeXBlSW1wbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL0RlZmVycmVkRG9jdW1lbnRUeXBlSW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiN2QzMDM4Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9EZWZlcnJlZERvY3VtZW50VHlwZUltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE4NyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5kb207Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgcmVwcmVzZW50cyBhIERvY3VtZW50IFR5cGUgPGVtPmRlY2xhcmFjdGlvbjwvZW0+IGluCi0gKiB0aGUgZG9jdW1lbnQgaXRzZWxmLCA8ZW0+bm90PC9lbT4gYSBEb2N1bWVudCBUeXBlIERlZmluaXRpb24gKERURCkuCi0gKiBBbiBYTUwgZG9jdW1lbnQgbWF5IChvciBtYXkgbm90KSBoYXZlIHN1Y2ggYSByZWZlcmVuY2UuCi0gKiA8UD4KLSAqIERvY3VtZW50VHlwZSBpcyBhbiBFeHRlbmRlZCBET00gZmVhdHVyZSwgdXNlZCBpbiBYTUwgZG9jdW1lbnRzIGJ1dAotICogbm90IGluIEhUTUwuCi0gKiA8UD4KLSAqIE5vdGUgdGhhdCBFbnRpdGllcyBhbmQgTm90YXRpb25zIGFyZSBubyBsb25nZXIgY2hpbGRyZW4gb2YgdGhlCi0gKiBEb2N1bWVudFR5cGUsIGJ1dCBhcmUgcGFyZW50bGVzcyBub2RlcyBodW5nIG9ubHkgaW4gdGhlaXIKLSAqIGFwcHJvcHJpYXRlIE5hbWVkTm9kZU1hcHMuCi0gKiA8UD4KLSAqIFRoaXMgYXJlYSBpcyBVTkRFUlNQRUNJRklFRCBJTiBSRUMtRE9NLUxldmVsLTEtMTk5ODEwMDEKLSAqIE1vc3Qgbm90YWJseSwgYWJzb2x1dGVseSBubyBwcm92aXNpb24gd2FzIG1hZGUgZm9yIHN0b3JpbmcKLSAqIGFuZCB1c2luZyBFbGVtZW50IGFuZCBBdHRyaWJ1dGUgaW5mb3JtYXRpb24uIE5vciB3YXMgdGhlIGxpbmthZ2UKLSAqIGJldHdlZW4gRW50aXRpZXMgYW5kIEVudGl0eSBSZWZlcmVuY2VzIG5haWxlZCBkb3duIHNvbGlkbHkuCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBzaW5jZSAgUFItRE9NLUxldmVsLTEtMTk5ODA4MTguCi0gKi8KLXB1YmxpYyBjbGFzcyBEZWZlcnJlZERvY3VtZW50VHlwZUltcGwKLSAgICBleHRlbmRzIERvY3VtZW50VHlwZUltcGwKLSAgICBpbXBsZW1lbnRzIERlZmVycmVkTm9kZSB7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0YW50cwotICAgIC8vCi0KLSAgICAvKiogU2VyaWFsaXphdGlvbiB2ZXJzaW9uLiAqLwotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMjE3MjU3OTY2MzIyNzMxMzUwOUw7Ci0KLSAgICAvLwotICAgIC8vIERhdGEKLSAgICAvLwotCi0gICAgLyoqIE5vZGUgaW5kZXguICovCi0gICAgcHJvdGVjdGVkIHRyYW5zaWVudCBpbnQgZk5vZGVJbmRleDsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFRoaXMgaXMgdGhlIGRlZmVycmVkIGNvbnN0cnVjdG9yLiBPbmx5IHRoZSBmTm9kZUluZGV4IGlzIGdpdmVuIGhlcmUuCi0gICAgICogQWxsIG90aGVyIGRhdGEsIGNhbiBiZSByZXF1ZXN0ZWQgZnJvbSB0aGUgb3duZXJEb2N1bWVudCB2aWEgdGhlIGluZGV4LgotICAgICAqLwotICAgIERlZmVycmVkRG9jdW1lbnRUeXBlSW1wbChEZWZlcnJlZERvY3VtZW50SW1wbCBvd25lckRvY3VtZW50LCBpbnQgbm9kZUluZGV4KSB7Ci0gICAgICAgIHN1cGVyKG93bmVyRG9jdW1lbnQsIG51bGwpOwotCi0gICAgICAgIGZOb2RlSW5kZXggPSBub2RlSW5kZXg7Ci0gICAgICAgIG5lZWRzU3luY0RhdGEodHJ1ZSk7Ci0gICAgICAgIG5lZWRzU3luY0NoaWxkcmVuKHRydWUpOwotCi0gICAgfSAvLyA8aW5pdD4oRGVmZXJyZWREb2N1bWVudEltcGwsaW50KQotCi0gICAgLy8KLSAgICAvLyBEZWZlcnJlZE5vZGUgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKiogUmV0dXJucyB0aGUgbm9kZSBpbmRleC4gKi8KLSAgICBwdWJsaWMgaW50IGdldE5vZGVJbmRleCgpIHsKLSAgICAgICAgcmV0dXJuIGZOb2RlSW5kZXg7Ci0gICAgfQotCi0gICAgLy8KLSAgICAvLyBQcm90ZWN0ZWQgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKiogU3luY2hyb25pemVzIHRoZSBkYXRhIChuYW1lIGFuZCB2YWx1ZSkgZm9yIGZhc3Qgbm9kZXMuICovCi0gICAgcHJvdGVjdGVkIHZvaWQgc3luY2hyb25pemVEYXRhKCkgewotCi0gICAgICAgIC8vIG5vIG5lZWQgdG8gc3luYyBpbiB0aGUgZnV0dXJlCi0gICAgICAgIG5lZWRzU3luY0RhdGEoZmFsc2UpOwotCi0gICAgICAgIC8vIGZsdWZmIGRhdGEKLSAgICAgICAgRGVmZXJyZWREb2N1bWVudEltcGwgb3duZXJEb2N1bWVudCA9Ci0gICAgICAgICAgICAoRGVmZXJyZWREb2N1bWVudEltcGwpdGhpcy5vd25lckRvY3VtZW50OwotICAgICAgICBuYW1lID0gb3duZXJEb2N1bWVudC5nZXROb2RlTmFtZShmTm9kZUluZGV4KTsKLQotICAgICAgICAvLyBwdWJsaWMgYW5kIHN5c3RlbSBpZHMKLSAgICAgICAgcHVibGljSUQgPSBvd25lckRvY3VtZW50LmdldE5vZGVWYWx1ZShmTm9kZUluZGV4KTsKLSAgICAgICAgc3lzdGVtSUQgPSBvd25lckRvY3VtZW50LmdldE5vZGVVUkkoZk5vZGVJbmRleCk7Ci0gICAgICAgIGludCBleHRyYURhdGFJbmRleCA9IG93bmVyRG9jdW1lbnQuZ2V0Tm9kZUV4dHJhKGZOb2RlSW5kZXgpOwotICAgICAgICBpbnRlcm5hbFN1YnNldCA9IG93bmVyRG9jdW1lbnQuZ2V0Tm9kZVZhbHVlKGV4dHJhRGF0YUluZGV4KTsKLSAgICB9IC8vIHN5bmNocm9uaXplRGF0YSgpCi0KLSAgICAvKiogU3luY2hyb25pemVzIHRoZSBlbnRpdGllcywgbm90YXRpb25zLCBhbmQgZWxlbWVudHMuICovCi0gICAgcHJvdGVjdGVkIHZvaWQgc3luY2hyb25pemVDaGlsZHJlbigpIHsKLQotICAgICAgICAvLyB3ZSBkb24ndCB3YW50IHRvIGdlbmVyYXRlIGFueSBldmVudCBmb3IgdGhpcyBzbyB0dXJuIHRoZW0gb2ZmCi0gICAgICAgIGJvb2xlYW4gb3JpZyA9IG93bmVyRG9jdW1lbnQoKS5nZXRNdXRhdGlvbkV2ZW50cygpOwotICAgICAgICBvd25lckRvY3VtZW50KCkuc2V0TXV0YXRpb25FdmVudHMoZmFsc2UpOwotCi0gICAgICAgIC8vIG5vIG5lZWQgdG8gc3luY2hyb25pemUgYWdhaW4KLSAgICAgICAgbmVlZHNTeW5jQ2hpbGRyZW4oZmFsc2UpOwotCi0gICAgICAgIC8vIGNyZWF0ZSBuZXcgbm9kZSBtYXBzCi0gICAgICAgIERlZmVycmVkRG9jdW1lbnRJbXBsIG93bmVyRG9jdW1lbnQgPQotICAgICAgICAgICAgKERlZmVycmVkRG9jdW1lbnRJbXBsKXRoaXMub3duZXJEb2N1bWVudDsKLQotICAgICAgICBlbnRpdGllcyAgPSBuZXcgTmFtZWROb2RlTWFwSW1wbCh0aGlzKTsKLSAgICAgICAgbm90YXRpb25zID0gbmV3IE5hbWVkTm9kZU1hcEltcGwodGhpcyk7Ci0gICAgICAgIGVsZW1lbnRzICA9IG5ldyBOYW1lZE5vZGVNYXBJbXBsKHRoaXMpOwotCi0gICAgICAgIC8vIGZpbGwgbm9kZSBtYXBzCi0gICAgICAgIERlZmVycmVkTm9kZSBsYXN0ID0gbnVsbDsKLSAgICAgICAgZm9yIChpbnQgaW5kZXggPSBvd25lckRvY3VtZW50LmdldExhc3RDaGlsZChmTm9kZUluZGV4KTsKLSAgICAgICAgICAgIGluZGV4ICE9IC0xOwotICAgICAgICAgICAgaW5kZXggPSBvd25lckRvY3VtZW50LmdldFByZXZTaWJsaW5nKGluZGV4KSkgewotCi0gICAgICAgICAgICBEZWZlcnJlZE5vZGUgbm9kZSA9IG93bmVyRG9jdW1lbnQuZ2V0Tm9kZU9iamVjdChpbmRleCk7Ci0gICAgICAgICAgICBpbnQgdHlwZSA9IG5vZGUuZ2V0Tm9kZVR5cGUoKTsKLSAgICAgICAgICAgIHN3aXRjaCAodHlwZSkgewotCi0gICAgICAgICAgICAgICAgLy8gaW50ZXJuYWwsIGV4dGVybmFsLCBhbmQgdW5wYXJzZWQgZW50aXRpZXMKLSAgICAgICAgICAgICAgICBjYXNlIE5vZGUuRU5USVRZX05PREU6IHsKLSAgICAgICAgICAgICAgICAgICAgZW50aXRpZXMuc2V0TmFtZWRJdGVtKG5vZGUpOwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyBub3RhdGlvbnMKLSAgICAgICAgICAgICAgICBjYXNlIE5vZGUuTk9UQVRJT05fTk9ERTogewotICAgICAgICAgICAgICAgICAgICBub3RhdGlvbnMuc2V0TmFtZWRJdGVtKG5vZGUpOwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyBlbGVtZW50IGRlZmluaXRpb25zCi0gICAgICAgICAgICAgICAgY2FzZSBOb2RlSW1wbC5FTEVNRU5UX0RFRklOSVRJT05fTk9ERTogewotICAgICAgICAgICAgICAgICAgICBlbGVtZW50cy5zZXROYW1lZEl0ZW0obm9kZSk7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8vIGVsZW1lbnRzCi0gICAgICAgICAgICAgICAgY2FzZSBOb2RlLkVMRU1FTlRfTk9ERTogewotICAgICAgICAgICAgICAgICAgICBpZiAoKChEb2N1bWVudEltcGwpZ2V0T3duZXJEb2N1bWVudCgpKS5hbGxvd0dyYW1tYXJBY2Nlc3MpewotICAgICAgICAgICAgICAgICAgICAgICAgaW5zZXJ0QmVmb3JlKG5vZGUsIGxhc3QpOwotICAgICAgICAgICAgICAgICAgICAgICAgbGFzdCA9IG5vZGU7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8vIE5PVEU6IFNob3VsZCBuZXZlciBnZXQgaGVyZSEgLUFjCi0gICAgICAgICAgICAgICAgZGVmYXVsdDogewotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkRlZmVycmVkRG9jdW1lbnRUeXBlSW1wbCIgKwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiNzeW5jaHJvbml6ZUluZm86ICIgKwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm5vZGUuZ2V0Tm9kZVR5cGUoKSA9ICIgKwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZS5nZXROb2RlVHlwZSgpICsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIsIGNsYXNzID0gIiArCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlLmdldENsYXNzKCkuZ2V0TmFtZSgpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gc2V0IG11dGF0aW9uIGV2ZW50cyBmbGFnIGJhY2sgdG8gaXRzIG9yaWdpbmFsIHZhbHVlCi0gICAgICAgIG93bmVyRG9jdW1lbnQoKS5zZXRNdXRhdGlvbkV2ZW50cyhvcmlnKTsKLQotICAgICAgICAvLyBzZXQgZW50aXRpZXMgYW5kIG5vdGF0aW9ucyByZWFkX29ubHkgcGVyIERPTSBzcGVjCi0gICAgICAgIHNldFJlYWRPbmx5KHRydWUsIGZhbHNlKTsKLQotICAgIH0gLy8gc3luY2hyb25pemVDaGlsZHJlbigpCi0KLX0gLy8gY2xhc3MgRGVmZXJyZWREb2N1bWVudFR5cGVJbXBsCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vRGVmZXJyZWRFbGVtZW50RGVmaW5pdGlvbkltcGwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9EZWZlcnJlZEVsZW1lbnREZWZpbml0aW9uSW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwOWIwM2MwLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9EZWZlcnJlZEVsZW1lbnREZWZpbml0aW9uSW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTI2ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwMiwyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbTsKLQotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci0KLS8qKgotICogTk9OLURPTSBDTEFTUzogRGVzY3JpYmUgb25lIG9mIHRoZSBFbGVtZW50cyAoYW5kIGl0cyBhc3NvY2lhdGVkCi0gKiBBdHRyaWJ1dGVzKSBkZWZpbmVkIGluIHRoaXMgRG9jdW1lbnQgVHlwZS4KLSAqIDxwPgotICogSSd2ZSBpbmNsdWRlZCB0aGlzIGluIExldmVsIDEgcHVyZWx5IGFzIGFuIGFuY2hvciBwb2ludCBmb3IgZGVmYXVsdAotICogYXR0cmlidXRlcy4gSW4gTGV2ZWwgMiBpdCBzaG91bGQgZW5hYmxlIHRoZSBDaGlsZFJ1bGUgc3VwcG9ydC4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICovCi1wdWJsaWMgY2xhc3MgRGVmZXJyZWRFbGVtZW50RGVmaW5pdGlvbkltcGwKLSAgICBleHRlbmRzIEVsZW1lbnREZWZpbml0aW9uSW1wbAotICAgIGltcGxlbWVudHMgRGVmZXJyZWROb2RlIHsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RhbnRzCi0gICAgLy8KLQotICAgIC8qKiBTZXJpYWxpemF0aW9uIHZlcnNpb24uICovCi0gICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDY3MDMyMzgxOTk1MzgwNDE1OTFMOwotCi0gICAgLy8KLSAgICAvLyBEYXRhCi0gICAgLy8KLQotICAgIC8qKiBOb2RlIGluZGV4LiAqLwotICAgIHByb3RlY3RlZCB0cmFuc2llbnQgaW50IGZOb2RlSW5kZXg7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0cnVjdG9ycwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBUaGlzIGlzIHRoZSBkZWZlcnJlZCBjb25zdHJ1Y3Rvci4gT25seSB0aGUgZk5vZGVJbmRleCBpcyBnaXZlbiBoZXJlLgotICAgICAqIEFsbCBvdGhlciBkYXRhLCBjYW4gYmUgcmVxdWVzdGVkIGZyb20gdGhlIG93bmVyRG9jdW1lbnQgdmlhIHRoZSBpbmRleC4KLSAgICAgKi8KLSAgICBEZWZlcnJlZEVsZW1lbnREZWZpbml0aW9uSW1wbChEZWZlcnJlZERvY3VtZW50SW1wbCBvd25lckRvY3VtZW50LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBub2RlSW5kZXgpIHsKLSAgICAgICAgc3VwZXIob3duZXJEb2N1bWVudCwgbnVsbCk7Ci0KLSAgICAgICAgZk5vZGVJbmRleCA9IG5vZGVJbmRleDsKLSAgICAgICAgbmVlZHNTeW5jRGF0YSh0cnVlKTsKLSAgICAgICAgbmVlZHNTeW5jQ2hpbGRyZW4odHJ1ZSk7Ci0KLSAgICB9IC8vIDxpbml0PihEZWZlcnJlZERvY3VtZW50SW1wbCxpbnQpCi0KLSAgICAvLwotICAgIC8vIERlZmVycmVkTm9kZSBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKiBSZXR1cm5zIHRoZSBub2RlIGluZGV4LiAqLwotICAgIHB1YmxpYyBpbnQgZ2V0Tm9kZUluZGV4KCkgewotICAgICAgICByZXR1cm4gZk5vZGVJbmRleDsKLSAgICB9Ci0KLSAgICAvLwotICAgIC8vIFByb3RlY3RlZCBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKiBTeW5jaHJvbml6ZXMgdGhlIGRhdGEgKG5hbWUgYW5kIHZhbHVlKSBmb3IgZmFzdCBub2Rlcy4gKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCBzeW5jaHJvbml6ZURhdGEoKSB7Ci0KLSAgICAgICAgLy8gbm8gbmVlZCB0byBzeW5jIGluIHRoZSBmdXR1cmUKLSAgICAgICAgbmVlZHNTeW5jRGF0YShmYWxzZSk7Ci0KLSAgICAgICAgLy8gZmx1ZmYgZGF0YQotICAgICAgICBEZWZlcnJlZERvY3VtZW50SW1wbCBvd25lckRvY3VtZW50ID0KLSAgICAgICAgICAgIChEZWZlcnJlZERvY3VtZW50SW1wbCl0aGlzLm93bmVyRG9jdW1lbnQ7Ci0gICAgICAgIG5hbWUgPSBvd25lckRvY3VtZW50LmdldE5vZGVOYW1lKGZOb2RlSW5kZXgpOwotCi0gICAgfSAvLyBzeW5jaHJvbml6ZURhdGEoKQotCi0gICAgLyoqIFN5bmNocm9uaXplcyB0aGUgZGVmYXVsdCBhdHRyaWJ1dGUgdmFsdWVzLiAqLwotICAgIHByb3RlY3RlZCB2b2lkIHN5bmNocm9uaXplQ2hpbGRyZW4oKSB7Ci0KLSAgICAgICAgLy8gd2UgZG9uJ3Qgd2FudCB0byBnZW5lcmF0ZSBhbnkgZXZlbnQgZm9yIHRoaXMgc28gdHVybiB0aGVtIG9mZgotICAgICAgICBib29sZWFuIG9yaWcgPSBvd25lckRvY3VtZW50LmdldE11dGF0aW9uRXZlbnRzKCk7Ci0gICAgICAgIG93bmVyRG9jdW1lbnQuc2V0TXV0YXRpb25FdmVudHMoZmFsc2UpOwotCi0gICAgICAgIC8vIGF0dHJpYnV0ZXMgYXJlIG5vdyBzeW5jZWQKLSAgICAgICAgbmVlZHNTeW5jQ2hpbGRyZW4oZmFsc2UpOwotCi0gICAgICAgIC8vIGNyZWF0ZSBhdHRyaWJ1dGVzIG5vZGUgbWFwCi0gICAgICAgIERlZmVycmVkRG9jdW1lbnRJbXBsIG93bmVyRG9jdW1lbnQgPQotICAgICAgICAgICAgKERlZmVycmVkRG9jdW1lbnRJbXBsKXRoaXMub3duZXJEb2N1bWVudDsKLSAgICAgICAgYXR0cmlidXRlcyA9IG5ldyBOYW1lZE5vZGVNYXBJbXBsKG93bmVyRG9jdW1lbnQpOwotCi0gICAgICAgIC8vIERlZmF1bHQgYXR0cmlidXRlcyBkYW5nbGUgYXMgY2hpbGRyZW4gb2YgdGhlIGVsZW1lbnQKLSAgICAgICAgLy8gZGVmaW5pdGlvbiAibm9kZSIgaW4gdGhlIGludGVybmFsIGZhc3QgdGFibGUuCi0gICAgICAgIGZvciAoaW50IG5vZGVJbmRleCA9IG93bmVyRG9jdW1lbnQuZ2V0TGFzdENoaWxkKGZOb2RlSW5kZXgpOwotICAgICAgICAgICAgIG5vZGVJbmRleCAhPSAtMTsKLSAgICAgICAgICAgICBub2RlSW5kZXggPSBvd25lckRvY3VtZW50LmdldFByZXZTaWJsaW5nKG5vZGVJbmRleCkpIHsKLSAgICAgICAgICAgIE5vZGUgYXR0ciA9IG93bmVyRG9jdW1lbnQuZ2V0Tm9kZU9iamVjdChub2RlSW5kZXgpOwotICAgICAgICAgICAgYXR0cmlidXRlcy5zZXROYW1lZEl0ZW0oYXR0cik7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBzZXQgbXV0YXRpb24gZXZlbnRzIGZsYWcgYmFjayB0byBpdHMgb3JpZ2luYWwgdmFsdWUKLSAgICAgICAgb3duZXJEb2N1bWVudC5zZXRNdXRhdGlvbkV2ZW50cyhvcmlnKTsKLQotICAgIH0gLy8gc3luY2hyb25pemVDaGlsZHJlbigpCi0KLX0gLy8gY2xhc3MgRGVmZXJyZWRFbGVtZW50RGVmaW5pdGlvbkltcGwKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9EZWZlcnJlZEVsZW1lbnRJbXBsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vRGVmZXJyZWRFbGVtZW50SW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2NTdhNjM1Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9EZWZlcnJlZEVsZW1lbnRJbXBsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMzggKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDAyLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi0vKgotICogV0FSTklORzogYmVjYXVzZSBqYXZhIGRvZXNuJ3Qgc3VwcG9ydCBtdWx0aS1pbmhlcml0YW5jZSBzb21lIGNvZGUgaXMKLSAqIGR1cGxpY2F0ZWQuIElmIHlvdSdyZSBjaGFuZ2luZyB0aGlzIGZpbGUgeW91IHByb2JhYmx5IHdhbnQgdG8gY2hhbmdlCi0gKiBEZWZlcnJlZEVsZW1lbnROU0ltcGwuamF2YSBhdCB0aGUgc2FtZSB0aW1lLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5kb207Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5OYW1lZE5vZGVNYXA7Ci0KLS8qKgotICogRWxlbWVudHMgcmVwcmVzZW50IG1vc3Qgb2YgdGhlICJtYXJrdXAiIGFuZCBzdHJ1Y3R1cmUgb2YgdGhlCi0gKiBkb2N1bWVudC4gIFRoZXkgY29udGFpbiBib3RoIHRoZSBkYXRhIGZvciB0aGUgZWxlbWVudCBpdHNlbGYKLSAqIChlbGVtZW50IG5hbWUgYW5kIGF0dHJpYnV0ZXMpLCBhbmQgYW55IGNvbnRhaW5lZCBub2RlcywgaW5jbHVkaW5nCi0gKiBkb2N1bWVudCB0ZXh0IChhcyBjaGlsZHJlbikuCi0gKiA8UD4KLSAqIEVsZW1lbnRzIG1heSBoYXZlIEF0dHJpYnV0ZXMgYXNzb2NpYXRlZCB3aXRoIHRoZW07IHRoZSBBUEkgZm9yIHRoaXMgaXMKLSAqIGRlZmluZWQgaW4gTm9kZSwgYnV0IHRoZSBmdW5jdGlvbiBpcyBpbXBsZW1lbnRlZCBoZXJlLiBJbiBnZW5lcmFsLCBYTUwKLSAqIGFwcGxpY2F0aW9ucyBzaG91bGQgcmV0cml2ZSBBdHRyaWJ1dGVzIGFzIE5vZGVzLCBzaW5jZSB0aGV5IG1heSBjb250YWluCi0gKiBlbnRpdHkgcmVmZXJlbmNlcyBhbmQgaGVuY2UgYmUgYSBmYWlybHkgY29tcGxleCBzdWItdHJlZS4gSFRNTCB1c2VycyB3aWxsCi0gKiBiZSBkZWFsaW5nIHdpdGggc2ltcGxlIHN0cmluZyB2YWx1ZXMsIGFuZCBjb252ZW5pZW5jZSBtZXRob2RzIGFyZSBwcm92aWRlZAotICogdG8gd29yayBpbiB0ZXJtcyBvZiBTdHJpbmdzLgotICogPFA+Ci0gKiBEZWZlcnJlZEVsZW1lbnRJbXBsIGluaGVyaXRzIGZyb20gRWxlbWVudEltcGwgd2hpY2ggZG9lcyBub3Qgc3VwcG9ydAotICogTmFtZXNwYWNlcy4gRGVmZXJyZWRFbGVtZW50TlNJbXBsLCB3aGljaCBpbmhlcml0cyBmcm9tIEVsZW1lbnROU0ltcGwsIGRvZXMuCi0gKiBAc2VlIERlZmVycmVkRWxlbWVudE5TSW1wbAotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAc2luY2UgIFBSLURPTS1MZXZlbC0xLTE5OTgwODE4LgotICovCi1wdWJsaWMgY2xhc3MgRGVmZXJyZWRFbGVtZW50SW1wbAotICAgIGV4dGVuZHMgRWxlbWVudEltcGwKLSAgICBpbXBsZW1lbnRzIERlZmVycmVkTm9kZSB7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0YW50cwotICAgIC8vCi0KLSAgICAvKiogU2VyaWFsaXphdGlvbiB2ZXJzaW9uLiAqLwotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNzY3MDk4MTEzMzk0MDkzNDg0Mkw7Ci0KLSAgICAvLwotICAgIC8vIERhdGEKLSAgICAvLwotCi0gICAgLyoqIE5vZGUgaW5kZXguICovCi0gICAgcHJvdGVjdGVkIHRyYW5zaWVudCBpbnQgZk5vZGVJbmRleDsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFRoaXMgaXMgdGhlIGRlZmVycmVkIGNvbnN0cnVjdG9yLiBPbmx5IHRoZSBmTm9kZUluZGV4IGlzIGdpdmVuIGhlcmUuIEFsbAotICAgICAqIG90aGVyIGRhdGEsIGNhbiBiZSByZXF1ZXN0ZWQgZnJvbSB0aGUgb3duZXJEb2N1bWVudCB2aWEgdGhlIGluZGV4LgotICAgICAqLwotICAgIERlZmVycmVkRWxlbWVudEltcGwoRGVmZXJyZWREb2N1bWVudEltcGwgb3duZXJEb2MsIGludCBub2RlSW5kZXgpIHsKLSAgICAgICAgc3VwZXIob3duZXJEb2MsIG51bGwpOwotCi0gICAgICAgIGZOb2RlSW5kZXggPSBub2RlSW5kZXg7Ci0gICAgICAgIG5lZWRzU3luY0NoaWxkcmVuKHRydWUpOwotCi0gICAgfSAvLyA8aW5pdD4oRG9jdW1lbnRJbXBsLGludCkKLQotICAgIC8vCi0gICAgLy8gRGVmZXJyZWROb2RlIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqIFJldHVybnMgdGhlIG5vZGUgaW5kZXguICovCi0gICAgcHVibGljIGZpbmFsIGludCBnZXROb2RlSW5kZXgoKSB7Ci0gICAgICAgIHJldHVybiBmTm9kZUluZGV4OwotICAgIH0KLQotICAgIC8vCi0gICAgLy8gUHJvdGVjdGVkIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqIFN5bmNocm9uaXplcyB0aGUgZGF0YSAobmFtZSBhbmQgdmFsdWUpIGZvciBmYXN0IG5vZGVzLiAqLwotICAgIHByb3RlY3RlZCBmaW5hbCB2b2lkIHN5bmNocm9uaXplRGF0YSgpIHsKLQotICAgICAgICAvLyBubyBuZWVkIHRvIHN5bmMgaW4gdGhlIGZ1dHVyZQotICAgICAgICBuZWVkc1N5bmNEYXRhKGZhbHNlKTsKLQotICAgICAgICAvLyBmbHVmZiBkYXRhCi0gICAgICAgIERlZmVycmVkRG9jdW1lbnRJbXBsIG93bmVyRG9jdW1lbnQgPQotICAgICAgICAgICAgKERlZmVycmVkRG9jdW1lbnRJbXBsKXRoaXMub3duZXJEb2N1bWVudDsKLQotICAgICAgICAvLyB3ZSBkb24ndCB3YW50IHRvIGdlbmVyYXRlIGFueSBldmVudCBmb3IgdGhpcyBzbyB0dXJuIHRoZW0gb2ZmCi0gICAgICAgIGJvb2xlYW4gb3JpZyA9IG93bmVyRG9jdW1lbnQubXV0YXRpb25FdmVudHM7Ci0gICAgICAgIG93bmVyRG9jdW1lbnQubXV0YXRpb25FdmVudHMgPSBmYWxzZTsKLQotICAgICAgICBuYW1lID0gb3duZXJEb2N1bWVudC5nZXROb2RlTmFtZShmTm9kZUluZGV4KTsKLQotICAgICAgICAvLyBhdHRyaWJ1dGVzCi0gICAgICAgIHNldHVwRGVmYXVsdEF0dHJpYnV0ZXMoKTsKLSAgICAgICAgaW50IGluZGV4ID0gb3duZXJEb2N1bWVudC5nZXROb2RlRXh0cmEoZk5vZGVJbmRleCk7Ci0gICAgICAgIGlmIChpbmRleCAhPSAtMSkgewotICAgICAgICAgICAgTmFtZWROb2RlTWFwIGF0dHJzID0gZ2V0QXR0cmlidXRlcygpOwotICAgICAgICAgICAgZG8gewotICAgICAgICAgICAgICAgIE5vZGVJbXBsIGF0dHIgPSAoTm9kZUltcGwpb3duZXJEb2N1bWVudC5nZXROb2RlT2JqZWN0KGluZGV4KTsKLSAgICAgICAgICAgICAgICBhdHRycy5zZXROYW1lZEl0ZW0oYXR0cik7Ci0gICAgICAgICAgICAgICAgaW5kZXggPSBvd25lckRvY3VtZW50LmdldFByZXZTaWJsaW5nKGluZGV4KTsKLSAgICAgICAgICAgIH0gd2hpbGUgKGluZGV4ICE9IC0xKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIHNldCBtdXRhdGlvbiBldmVudHMgZmxhZyBiYWNrIHRvIGl0cyBvcmlnaW5hbCB2YWx1ZQotICAgICAgICBvd25lckRvY3VtZW50Lm11dGF0aW9uRXZlbnRzID0gb3JpZzsKLQotICAgIH0gLy8gc3luY2hyb25pemVEYXRhKCkKLQotICAgIHByb3RlY3RlZCBmaW5hbCB2b2lkIHN5bmNocm9uaXplQ2hpbGRyZW4oKSB7Ci0gICAgICAgIERlZmVycmVkRG9jdW1lbnRJbXBsIG93bmVyRG9jdW1lbnQgPQotICAgICAgICAgICAgKERlZmVycmVkRG9jdW1lbnRJbXBsKSBvd25lckRvY3VtZW50KCk7Ci0gICAgICAgIG93bmVyRG9jdW1lbnQuc3luY2hyb25pemVDaGlsZHJlbih0aGlzLCBmTm9kZUluZGV4KTsKLSAgICB9IC8vIHN5bmNocm9uaXplQ2hpbGRyZW4oKQotCi19IC8vIGNsYXNzIERlZmVycmVkRWxlbWVudEltcGwKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9EZWZlcnJlZEVsZW1lbnROU0ltcGwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9EZWZlcnJlZEVsZW1lbnROU0ltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZmQ1NGZlNi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vRGVmZXJyZWRFbGVtZW50TlNJbXBsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNjEgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDAyLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi0KLS8qCi0gKiBXQVJOSU5HOiBiZWNhdXNlIGphdmEgZG9lc24ndCBzdXBwb3J0IG11bHRpLWluaGVyaXRhbmNlIHNvbWUgY29kZSBpcwotICogZHVwbGljYXRlZC4gSWYgeW91J3JlIGNoYW5naW5nIHRoaXMgZmlsZSB5b3UgcHJvYmFibHkgd2FudCB0byBjaGFuZ2UKLSAqIERlZmVycmVkRWxlbWVudEltcGwuamF2YSBhdCB0aGUgc2FtZSB0aW1lLgotICoKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuTmFtZXNwYWNlQ29udGV4dDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTVHlwZURlZmluaXRpb247Ci1pbXBvcnQgb3JnLnczYy5kb20uTmFtZWROb2RlTWFwOwotCi0KLS8qKgotICogRGVmZXJyZWRFbGVtZW50TlNJbXBsIGlzIHRvIEVsZW1lbnROU0ltcGwsIHdoYXQgRGVmZXJyZWRFbGVtZW50SW1wbCBpcyB0bwotICogRWxlbWVudEltcGwuCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBzZWUgRGVmZXJyZWRFbGVtZW50SW1wbAotICovCi1wdWJsaWMgY2xhc3MgRGVmZXJyZWRFbGVtZW50TlNJbXBsCi0gICAgZXh0ZW5kcyBFbGVtZW50TlNJbXBsCi0gICAgaW1wbGVtZW50cyBEZWZlcnJlZE5vZGUgewotCi0gICAgLy8KLSAgICAvLyBDb25zdGFudHMKLSAgICAvLwotCi0gICAgLyoqIFNlcmlhbGl6YXRpb24gdmVyc2lvbi4gKi8KLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTUwMDE4ODUxNDUzNzA5MjczODVMOwotCi0gICAgLy8KLSAgICAvLyBEYXRhCi0gICAgLy8KLQotICAgIC8qKiBOb2RlIGluZGV4LiAqLwotICAgIHByb3RlY3RlZCB0cmFuc2llbnQgaW50IGZOb2RlSW5kZXg7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0cnVjdG9ycwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBUaGlzIGlzIHRoZSBkZWZlcnJlZCBjb25zdHJ1Y3Rvci4gT25seSB0aGUgZk5vZGVJbmRleCBpcyBnaXZlbiBoZXJlLiBBbGwKLSAgICAgKiBvdGhlciBkYXRhLCBjYW4gYmUgcmVxdWVzdGVkIGZyb20gdGhlIG93bmVyRG9jdW1lbnQgdmlhIHRoZSBpbmRleC4KLSAgICAgKi8KLSAgICBEZWZlcnJlZEVsZW1lbnROU0ltcGwoRGVmZXJyZWREb2N1bWVudEltcGwgb3duZXJEb2MsIGludCBub2RlSW5kZXgpIHsKLSAgICAgICAgc3VwZXIob3duZXJEb2MsIG51bGwpOwotCi0gICAgICAgIGZOb2RlSW5kZXggPSBub2RlSW5kZXg7Ci0gICAgICAgIG5lZWRzU3luY0NoaWxkcmVuKHRydWUpOwotCi0gICAgfSAvLyA8aW5pdD4oRG9jdW1lbnRJbXBsLGludCkKLQotICAgIC8vCi0gICAgLy8gRGVmZXJyZWROb2RlIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqIFJldHVybnMgdGhlIG5vZGUgaW5kZXguICovCi0gICAgcHVibGljIGZpbmFsIGludCBnZXROb2RlSW5kZXgoKSB7Ci0gICAgICAgIHJldHVybiBmTm9kZUluZGV4OwotICAgIH0KLQotICAgIC8vCi0gICAgLy8gUHJvdGVjdGVkIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqIFN5bmNocm9uaXplcyB0aGUgZGF0YSAobmFtZSBhbmQgdmFsdWUpIGZvciBmYXN0IG5vZGVzLiAqLwotICAgIHByb3RlY3RlZCBmaW5hbCB2b2lkIHN5bmNocm9uaXplRGF0YSgpIHsKLQotICAgICAgICAvLyBubyBuZWVkIHRvIHN5bmMgaW4gdGhlIGZ1dHVyZQotICAgICAgICBuZWVkc1N5bmNEYXRhKGZhbHNlKTsKLQotICAgICAgICAvLyBmbHVmZiBkYXRhCi0gICAgICAgIERlZmVycmVkRG9jdW1lbnRJbXBsIG93bmVyRG9jdW1lbnQgPQotICAgICAgICAgICAgKERlZmVycmVkRG9jdW1lbnRJbXBsKSB0aGlzLm93bmVyRG9jdW1lbnQ7Ci0KLSAgICAgICAgLy8gd2UgZG9uJ3Qgd2FudCB0byBnZW5lcmF0ZSBhbnkgZXZlbnQgZm9yIHRoaXMgc28gdHVybiB0aGVtIG9mZgotICAgICAgICBib29sZWFuIG9yaWcgPSBvd25lckRvY3VtZW50Lm11dGF0aW9uRXZlbnRzOwotICAgICAgICBvd25lckRvY3VtZW50Lm11dGF0aW9uRXZlbnRzID0gZmFsc2U7Ci0KLSAgICAgICAgbmFtZSA9IG93bmVyRG9jdW1lbnQuZ2V0Tm9kZU5hbWUoZk5vZGVJbmRleCk7Ci0KLSAgICAgICAgLy8gZXh0cmFjdCBsb2NhbCBwYXJ0IGZyb20gUU5hbWUKLSAgICAgICAgaW50IGluZGV4ID0gbmFtZS5pbmRleE9mKCc6Jyk7Ci0gICAgICAgIGlmIChpbmRleCA8IDApIHsKLSAgICAgICAgICAgIGxvY2FsTmFtZSA9IG5hbWU7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBsb2NhbE5hbWUgPSBuYW1lLnN1YnN0cmluZyhpbmRleCArIDEpOwotICAgICAgICB9Ci0KLSAgICAgICAgICAgIG5hbWVzcGFjZVVSSSA9IG93bmVyRG9jdW1lbnQuZ2V0Tm9kZVVSSShmTm9kZUluZGV4KTsKLSAgICAgICAgdHlwZSA9IChYU1R5cGVEZWZpbml0aW9uKW93bmVyRG9jdW1lbnQuZ2V0VHlwZUluZm8oZk5vZGVJbmRleCk7Ci0KLSAgICAgICAgLy8gYXR0cmlidXRlcwotICAgICAgICBzZXR1cERlZmF1bHRBdHRyaWJ1dGVzKCk7Ci0gICAgICAgIGludCBhdHRySW5kZXggPSBvd25lckRvY3VtZW50LmdldE5vZGVFeHRyYShmTm9kZUluZGV4KTsKLSAgICAgICAgaWYgKGF0dHJJbmRleCAhPSAtMSkgewotICAgICAgICAgICAgTmFtZWROb2RlTWFwIGF0dHJzID0gZ2V0QXR0cmlidXRlcygpOwotICAgICAgICAgICAgYm9vbGVhbiBzZWVuU2NoZW1hRGVmYXVsdCA9IGZhbHNlOwotICAgICAgICAgICAgZG8gewotICAgICAgICAgICAgICAgIEF0dHJJbXBsIGF0dHIgPSAoQXR0ckltcGwpIG93bmVyRG9jdW1lbnQuZ2V0Tm9kZU9iamVjdChhdHRySW5kZXgpOwotICAgICAgICAgICAgICAgIC8vIFRha2Ugc3BlY2lhbCBjYXJlIG9mIHNjaGVtYSBkZWZhdWx0ZWQgYXR0cmlidXRlcy4gQ2FsbGluZyB0aGUKLSAgICAgICAgICAgICAgICAvLyBub24tbmFtZXNwYWNlIGF3YXJlIHNldEF0dHJpYnV0ZU5vZGUoKSBtZXRob2QgY291bGQgb3ZlcndyaXRlCi0gICAgICAgICAgICAgICAgLy8gYW5vdGhlciBhdHRyaWJ1dGUgd2l0aCB0aGUgc2FtZSBsb2NhbCBuYW1lLgotICAgICAgICAgICAgICAgIGlmICghYXR0ci5nZXRTcGVjaWZpZWQoKSAmJiAoc2VlblNjaGVtYURlZmF1bHQgfHwKLSAgICAgICAgICAgICAgICAgICAgKGF0dHIuZ2V0TmFtZXNwYWNlVVJJKCkgIT0gbnVsbCAmJgotICAgICAgICAgICAgICAgICAgICBhdHRyLmdldE5hbWVzcGFjZVVSSSgpICE9IE5hbWVzcGFjZUNvbnRleHQuWE1MTlNfVVJJICYmCi0gICAgICAgICAgICAgICAgICAgIGF0dHIuZ2V0TmFtZSgpLmluZGV4T2YoJzonKSA8IDApKSkgewotICAgICAgICAgICAgICAgICAgICBzZWVuU2NoZW1hRGVmYXVsdCA9IHRydWU7Ci0gICAgICAgICAgICAgICAgICAgIGF0dHJzLnNldE5hbWVkSXRlbU5TKGF0dHIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgYXR0cnMuc2V0TmFtZWRJdGVtKGF0dHIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBhdHRySW5kZXggPSBvd25lckRvY3VtZW50LmdldFByZXZTaWJsaW5nKGF0dHJJbmRleCk7Ci0gICAgICAgICAgICB9IHdoaWxlIChhdHRySW5kZXggIT0gLTEpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gc2V0IG11dGF0aW9uIGV2ZW50cyBmbGFnIGJhY2sgdG8gaXRzIG9yaWdpbmFsIHZhbHVlCi0gICAgICAgIG93bmVyRG9jdW1lbnQubXV0YXRpb25FdmVudHMgPSBvcmlnOwotCi0gICAgfSAvLyBzeW5jaHJvbml6ZURhdGEoKQotCi0gICAgLyoqCi0gICAgICogU3luY2hyb25pemVzIHRoZSBub2RlJ3MgY2hpbGRyZW4gd2l0aCB0aGUgaW50ZXJuYWwgc3RydWN0dXJlLgotICAgICAqIEZsdWZmaW5nIHRoZSBjaGlsZHJlbiBhdCBvbmNlIHNvbHZlcyBhIGxvdCBvZiB3b3JrIHRvIGtlZXAKLSAgICAgKiB0aGUgdHdvIHN0cnVjdHVyZXMgaW4gc3luYy4gVGhlIHByb2JsZW0gZ2V0cyB3b3JzZSB3aGVuCi0gICAgICogZWRpdGluZyB0aGUgdHJlZSAtLSB0aGlzIG1ha2VzIGl0IGEgbG90IGVhc2llci4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgZmluYWwgdm9pZCBzeW5jaHJvbml6ZUNoaWxkcmVuKCkgewotICAgICAgICBEZWZlcnJlZERvY3VtZW50SW1wbCBvd25lckRvY3VtZW50ID0KLSAgICAgICAgICAgIChEZWZlcnJlZERvY3VtZW50SW1wbCkgb3duZXJEb2N1bWVudCgpOwotICAgICAgICBvd25lckRvY3VtZW50LnN5bmNocm9uaXplQ2hpbGRyZW4odGhpcywgZk5vZGVJbmRleCk7Ci0gICAgfSAvLyBzeW5jaHJvbml6ZUNoaWxkcmVuKCkKLQotfSAvLyBjbGFzcyBEZWZlcnJlZEVsZW1lbnRJbXBsCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vRGVmZXJyZWRFbnRpdHlJbXBsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vRGVmZXJyZWRFbnRpdHlJbXBsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDJiOWU4Y2MuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL0RlZmVycmVkRW50aXR5SW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTUzICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwMiwyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbTsKLQotCi0vKioKLSAqIEVudGl0eSBub2RlcyBob2xkIHRoZSByZWZlcmVuY2UgZGF0YSBmb3IgYW4gWE1MIEVudGl0eSAtLSBlaXRoZXIKLSAqIHBhcnNlZCBvciB1bnBhcnNlZC4gVGhlIG5vZGVOYW1lIChpbmhlcml0ZWQgZnJvbSBOb2RlKSB3aWxsIGNvbnRhaW4KLSAqIHRoZSBuYW1lIChpZiBhbnkpIG9mIHRoZSBFbnRpdHkuIEl0cyBkYXRhIHdpbGwgYmUgY29udGFpbmVkIGluIHRoZQotICogRW50aXR5J3MgY2hpbGRyZW4sIGluIGV4YWN0bHkgdGhlIHN0cnVjdHVyZSB3aGljaCBhbgotICogRW50aXR5UmVmZXJlbmNlIHRvIHRoaXMgbmFtZSB3aWxsIHByZXNlbnQgd2l0aGluIHRoZSBkb2N1bWVudCdzCi0gKiBib2R5LgotICogPFA+Ci0gKiBOb3RlIHRoYXQgdGhpcyBvYmplY3QgbW9kZWxzIHRoZSBhY3R1YWwgZW50aXR5LCBfbm90XyB0aGUgZW50aXR5Ci0gKiBkZWNsYXJhdGlvbiBvciB0aGUgZW50aXR5IHJlZmVyZW5jZS4KLSAqIDxQPgotICogQW4gWE1MIHByb2Nlc3NvciBtYXkgY2hvb3NlIHRvIGNvbXBsZXRlbHkgZXhwYW5kIGVudGl0aWVzIGJlZm9yZQotICogdGhlIHN0cnVjdHVyZSBtb2RlbCBpcyBwYXNzZWQgdG8gdGhlIERPTTsgaW4gdGhpcyBjYXNlLCB0aGVyZSB3aWxsCi0gKiBiZSBubyBFbnRpdHlSZWZlcmVuY2VzIGluIHRoZSBET00gdHJlZS4KLSAqIDxQPgotICogUXVvdGluZyB0aGUgMTAvMDEgRE9NIFByb3Bvc2FsLAotICogPEJMT0NLUVVPVEU+Ci0gKiAiVGhlIERPTSBMZXZlbCAxIGRvZXMgbm90IHN1cHBvcnQgZWRpdGluZyBFbnRpdHkgbm9kZXM7IGlmIGEgdXNlcgotICogd2FudHMgdG8gbWFrZSBjaGFuZ2VzIHRvIHRoZSBjb250ZW50cyBvZiBhbiBFbnRpdHksIGV2ZXJ5IHJlbGF0ZWQKLSAqIEVudGl0eVJlZmVyZW5jZSBub2RlIGhhcyB0byBiZSByZXBsYWNlZCBpbiB0aGUgc3RydWN0dXJlIG1vZGVsIGJ5Ci0gKiBhIGNsb25lIG9mIHRoZSBFbnRpdHkncyBjb250ZW50cywgYW5kIHRoZW4gdGhlIGRlc2lyZWQgY2hhbmdlcwotICogbXVzdCBiZSBtYWRlIHRvIGVhY2ggb2YgdGhvc2UgY2xvbmVzIGluc3RlYWQuIEFsbCB0aGUKLSAqIGRlc2NlbmRhbnRzIG9mIGFuIEVudGl0eSBub2RlIGFyZSByZWFkb25seS4iCi0gKiA8L0JMT0NLUVVPVEU+Ci0gKiBJJ20gaW50ZXJwcmV0aW5nIHRoaXMgYXM6IEl0IGlzIHRoZSBwYXJzZXIncyByZXNwb25zaWJpbHR5IHRvIGNhbGwKLSAqIHRoZSBub24tRE9NIG9wZXJhdGlvbiBzZXRSZWFkT25seSh0cnVlLHRydWUpIGFmdGVyIGl0IGNvbnN0cnVjdHMKLSAqIHRoZSBFbnRpdHkuIFNpbmNlIHRoZSBET00gZXhwbGljaXRseSBkZWNpZGVkIG5vdCB0byBkZWFsIHdpdGggdGhpcywKLSAqIF9hbnlfIGFuc3dlciB3aWxsIGludm9sdmUgYSBub24tRE9NIG9wZXJhdGlvbiwgYW5kIHRoaXMgaXMgdGhlCi0gKiBzaW1wbGVzdCBzb2x1dGlvbi4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQHNpbmNlICBQUi1ET00tTGV2ZWwtMS0xOTk4MDgxOC4KLSAqLwotcHVibGljIGNsYXNzIERlZmVycmVkRW50aXR5SW1wbAotICAgIGV4dGVuZHMgRW50aXR5SW1wbAotICAgIGltcGxlbWVudHMgRGVmZXJyZWROb2RlIHsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RhbnRzCi0gICAgLy8KLQotICAgIC8qKiBTZXJpYWxpemF0aW9uIHZlcnNpb24uICovCi0gICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDQ3NjAxODA0MzEwNzg5NDE2MzhMOwotCi0gICAgLy8KLSAgICAvLyBEYXRhCi0gICAgLy8KLQotICAgIC8qKiBOb2RlIGluZGV4LiAqLwotICAgIHByb3RlY3RlZCB0cmFuc2llbnQgaW50IGZOb2RlSW5kZXg7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0cnVjdG9ycwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBUaGlzIGlzIHRoZSBkZWZlcnJlZCBjb25zdHJ1Y3Rvci4gT25seSB0aGUgZk5vZGVJbmRleCBpcyBnaXZlbiBoZXJlLgotICAgICAqIEFsbCBvdGhlciBkYXRhLCBjYW4gYmUgcmVxdWVzdGVkIGZyb20gdGhlIG93bmVyRG9jdW1lbnQgdmlhIHRoZSBpbmRleC4KLSAgICAgKi8KLSAgICBEZWZlcnJlZEVudGl0eUltcGwoRGVmZXJyZWREb2N1bWVudEltcGwgb3duZXJEb2N1bWVudCwgaW50IG5vZGVJbmRleCkgewotICAgICAgICBzdXBlcihvd25lckRvY3VtZW50LCBudWxsKTsKLQotICAgICAgICBmTm9kZUluZGV4ID0gbm9kZUluZGV4OwotICAgICAgICBuZWVkc1N5bmNEYXRhKHRydWUpOwotICAgICAgICBuZWVkc1N5bmNDaGlsZHJlbih0cnVlKTsKLQotICAgIH0gLy8gPGluaXQ+KERlZmVycmVkRG9jdW1lbnRJbXBsLGludCkKLQotICAgIC8vCi0gICAgLy8gRGVmZXJyZWROb2RlIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqIFJldHVybnMgdGhlIG5vZGUgaW5kZXguICovCi0gICAgcHVibGljIGludCBnZXROb2RlSW5kZXgoKSB7Ci0gICAgICAgIHJldHVybiBmTm9kZUluZGV4OwotICAgIH0KLQotICAgIC8vCi0gICAgLy8gUHJvdGVjdGVkIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogU3luY2hyb25pemUgdGhlIGVudGl0eSBkYXRhLiBUaGlzIGlzIHNwZWNpYWwgYmVjYXVzZSBvZiB0aGUgd2F5Ci0gICAgICogdGhhdCB0aGUgImZhc3QiIHZlcnNpb24gc3RvcmVzIHRoZSBpbmZvcm1hdGlvbi4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCBzeW5jaHJvbml6ZURhdGEoKSB7Ci0KLSAgICAgICAgLy8gbm8gbmVlZCB0byBzeWNocm9uaXplIGFnYWluCi0gICAgICAgIG5lZWRzU3luY0RhdGEoZmFsc2UpOwotCi0gICAgICAgIC8vIGdldCB0aGUgbm9kZSBkYXRhCi0gICAgICAgIERlZmVycmVkRG9jdW1lbnRJbXBsIG93bmVyRG9jdW1lbnQgPQotICAgICAgICAgICAgKERlZmVycmVkRG9jdW1lbnRJbXBsKXRoaXMub3duZXJEb2N1bWVudDsKLSAgICAgICAgbmFtZSA9IG93bmVyRG9jdW1lbnQuZ2V0Tm9kZU5hbWUoZk5vZGVJbmRleCk7Ci0KLSAgICAgICAgLy8gZ2V0IHRoZSBlbnRpdHkgZGF0YQotICAgICAgICBwdWJsaWNJZCAgICA9IG93bmVyRG9jdW1lbnQuZ2V0Tm9kZVZhbHVlKGZOb2RlSW5kZXgpOwotICAgICAgICBzeXN0ZW1JZCAgICA9IG93bmVyRG9jdW1lbnQuZ2V0Tm9kZVVSSShmTm9kZUluZGV4KTsKLSAgICAgICAgaW50IGV4dHJhRGF0YUluZGV4ID0gb3duZXJEb2N1bWVudC5nZXROb2RlRXh0cmEoZk5vZGVJbmRleCk7Ci0gICAgICAgIG93bmVyRG9jdW1lbnQuZ2V0Tm9kZVR5cGUoZXh0cmFEYXRhSW5kZXgpOwotCi0gICAgICAgIG5vdGF0aW9uTmFtZSA9IG93bmVyRG9jdW1lbnQuZ2V0Tm9kZU5hbWUoZXh0cmFEYXRhSW5kZXgpOwotCi0gICAgICAgIC8vIGVuY29kaW5nIGFuZCB2ZXJzaW9uIERPTSBMMwotICAgICAgICB2ZXJzaW9uICAgICA9IG93bmVyRG9jdW1lbnQuZ2V0Tm9kZVZhbHVlKGV4dHJhRGF0YUluZGV4KTsKLSAgICAgICAgZW5jb2RpbmcgICAgPSBvd25lckRvY3VtZW50LmdldE5vZGVVUkkoZXh0cmFEYXRhSW5kZXgpOwotCi0gICAgICAgIC8vIGJhc2VVUkksIGFjdHVhbEVuY29kaW5nIERPTSBMMwotICAgICAgICBpbnQgZXh0cmFJbmRleDIgPSBvd25lckRvY3VtZW50LmdldE5vZGVFeHRyYShleHRyYURhdGFJbmRleCk7Ci0gICAgICAgIGJhc2VVUkkgPSBvd25lckRvY3VtZW50LmdldE5vZGVOYW1lKGV4dHJhSW5kZXgyKTsKLSAgICAgICAgaW5wdXRFbmNvZGluZyA9IG93bmVyRG9jdW1lbnQuZ2V0Tm9kZVZhbHVlKGV4dHJhSW5kZXgyKTsKLQotICAgIH0gLy8gc3luY2hyb25pemVEYXRhKCkKLQotICAgIC8qKiBTeW5jaHJvbml6ZSB0aGUgY2hpbGRyZW4uICovCi0gICAgcHJvdGVjdGVkIHZvaWQgc3luY2hyb25pemVDaGlsZHJlbigpIHsKLQotICAgICAgICAvLyBubyBuZWVkIHRvIHN5bmNocm9uaXplIGFnYWluCi0gICAgICAgIG5lZWRzU3luY0NoaWxkcmVuKGZhbHNlKTsKLQotICAgICAgICBpc1JlYWRPbmx5KGZhbHNlKTsKLSAgICAgICAgRGVmZXJyZWREb2N1bWVudEltcGwgb3duZXJEb2N1bWVudCA9Ci0gICAgICAgICAgICAoRGVmZXJyZWREb2N1bWVudEltcGwpIG93bmVyRG9jdW1lbnQoKTsKLSAgICAgICAgb3duZXJEb2N1bWVudC5zeW5jaHJvbml6ZUNoaWxkcmVuKHRoaXMsIGZOb2RlSW5kZXgpOwotICAgICAgICBzZXRSZWFkT25seSh0cnVlLCB0cnVlKTsKLQotICAgIH0gLy8gc3luY2hyb25pemVDaGlsZHJlbigpCi0KLX0gLy8gY2xhc3MgRGVmZXJyZWRFbnRpdHlJbXBsCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vRGVmZXJyZWRFbnRpdHlSZWZlcmVuY2VJbXBsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vRGVmZXJyZWRFbnRpdHlSZWZlcmVuY2VJbXBsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDdmMzgzNmEuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL0RlZmVycmVkRW50aXR5UmVmZXJlbmNlSW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTU1ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwMiwyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbTsKLQotLyoqCi0gKiBFbnRpdHlSZWZlcmVuY2UgbW9kZWxzIHRoZSBYTUwgJmVudGl0eW5hbWU7IHN5bnRheCwgd2hlbiB1c2VkIGZvcgotICogZW50aXRpZXMgZGVmaW5lZCBieSB0aGUgRE9NLiBFbnRpdGllcyBoYXJkY29kZWQgaW50byBYTUwsIHN1Y2ggYXMKLSAqIGNoYXJhY3RlciBlbnRpdGllcywgc2hvdWxkIGluc3RlYWQgaGF2ZSBiZWVuIHRyYW5zbGF0ZWQgaW50byB0ZXh0Ci0gKiBieSB0aGUgY29kZSB3aGljaCBnZW5lcmF0ZWQgdGhlIERPTSB0cmVlLgotICogPFA+Ci0gKiBBbiBYTUwgcHJvY2Vzc29yIGhhcyB0aGUgYWx0ZXJuYXRpdmUgb2YgZnVsbHkgZXhwYW5kaW5nIEVudGl0aWVzCi0gKiBpbnRvIHRoZSBub3JtYWwgZG9jdW1lbnQgdHJlZS4gSWYgaXQgZG9lcyBzbywgbm8gRW50aXR5UmVmZXJlbmNlIG5vZGVzCi0gKiB3aWxsIGFwcGVhci4KLSAqIDxQPgotICogU2ltaWxhcmx5LCBub24tdmFsaWRhdGluZyBYTUwgcHJvY2Vzc29ycyBhcmUgbm90IHJlcXVpcmVkIHRvIHJlYWQKLSAqIG9yIHByb2Nlc3MgZW50aXR5IGRlY2xhcmF0aW9ucyBtYWRlIGluIHRoZSBleHRlcm5hbCBzdWJzZXQgb3IKLSAqIGRlY2xhcmVkIGluIGV4dGVybmFsIHBhcmFtZXRlciBlbnRpdGllcy4gSGVuY2UsIHNvbWUgYXBwbGljYXRpb25zCi0gKiBtYXkgbm90IG1ha2UgdGhlIHJlcGxhY2VtZW50IHZhbHVlIGF2YWlsYWJsZSBmb3IgUGFyc2VkIEVudGl0aWVzCi0gKiBvZiB0aGVzZSB0eXBlcy4KLSAqIDxQPgotICogRW50aXR5UmVmZXJlbmNlIGJlaGF2ZXMgYXMgYSByZWFkLW9ubHkgbm9kZSwgYW5kIHRoZSBjaGlsZHJlbiBvZgotICogdGhlIEVudGl0eVJlZmVyZW5jZSAod2hpY2ggcmVmbGVjdCB0aG9zZSBvZiB0aGUgRW50aXR5LCBhbmQgc2hvdWxkCi0gKiBhbHNvIGJlIHJlYWQtb25seSkgZ2l2ZSBpdHMgcmVwbGFjZW1lbnQgdmFsdWUsIGlmIGFueS4gVGhleSBhcmUKLSAqIHN1cHBvc2VkIHRvIGF1dG9tYWdpY2FsbHkgc3RheSBpbiBzeW5jaCBpZiB0aGUgRG9jdW1lbnRUeXBlIGlzCi0gKiB1cGRhdGVkIHdpdGggbmV3IHZhbHVlcyBmb3IgdGhlIEVudGl0eS4KLSAqIDxQPgotICogVGhlIGRlZmluZWQgYmVoYXZpb3IgbWFrZXMgZWZmaWNpZW50IHN0b3JhZ2UgZGlmZmljdWx0IGZvciB0aGUgRE9NCi0gKiBpbXBsZW1lbnRvci4gV2UgY2FuJ3QganVzdCBsb29rIGFzaWRlIHRvIHRoZSBFbnRpdHkncyBkZWZpbml0aW9uCi0gKiBpbiB0aGUgRG9jdW1lbnRUeXBlIHNpbmNlIHRob3NlIG5vZGVzIGhhdmUgdGhlIHdyb25nIHBhcmVudCAodW5sZXNzCi0gKiB3ZSBjYW4gY29tZSB1cCB3aXRoIGEgY2xldmVyICJpbWFnaW5hcnkgcGFyZW50IiBtZWNoYW5pc20pLiBXZQotICogbXVzdCBhdCBsZWFzdCBhcHBlYXIgdG8gY2xvbmUgdGhvc2UgY2hpbGRyZW4uLi4gd2hpY2ggcmFpc2VzIHRoZQotICogaXNzdWUgb2Yga2VlcGluZyB0aGUgcmVmZXJlbmNlIHN5bmNocm9uaXplZCB3aXRoIGl0cyBwYXJlbnQuCi0gKiBUaGlzIGxlYWRzIG1lIGJhY2sgdG8gdGhlICJjYWNoZWQgaW1hZ2Ugb2YgY2VudHJhbGx5IGRlZmluZWQgZGF0YSIKLSAqIHNvbHV0aW9uLCBtdWNoIGFzIEkgZGlzbGlrZSBpdC4KLSAqIDxQPgotICogRm9yIG5vdyBJIGhhdmUgZGVjaWRlZCwgc2luY2UgUkVDLURPTS1MZXZlbC0xLTE5OTgwODE4IGRvZXNuJ3QKLSAqIGNvdmVyIHRoaXMgaW4gbXVjaCBkZXRhaWwsIHRoYXQgc3luY2hyb25pemF0aW9uIGRvZXNuJ3QgaGF2ZSB0byBiZQotICogY29uc2lkZXJlZCB3aGlsZSB0aGUgdXNlciBpcyBkZWVwIGluIHRoZSB0cmVlLiBUaGF0IGlzLCBpZiB5b3UncmUKLSAqIGxvb2tpbmcgd2l0aGluIG9uZSBvZiB0aGUgRW50aXR5UmVmZXJlbm5jZSdzIGNoaWxkcmVuIGFuZCB0aGUgRW50aXR5Ci0gKiBjaGFuZ2VzLCB5b3Ugd29uJ3QgYmUgaW5mb3JtZWQ7IGluc3RlYWQsIHlvdSB3aWxsIGNvbnRpbnVlIHRvIGFjY2VzcwotICogdGhlIHNhbWUgb2JqZWN0IC0tIHdoaWNoIG1heSBvciBtYXkgbm90IHN0aWxsIGJlIHBhcnQgb2YgdGhlIHRyZWUuCi0gKiBUaGlzIGlzIHRoZSBzYW1lIGJlaGF2aW9yIHRoYXQgb2J0YWlucyBlbHNld2hlcmUgaW4gdGhlIERPTSBpZiB0aGUKLSAqIHN1YnRyZWUgeW91J3JlIGxvb2tpbmcgYXQgaXMgZGVsZXRlZCBmcm9tIGl0cyBwYXJlbnQsIHNvIGl0J3MKLSAqIGFjY2VwdGFibGUgaGVyZS4gKElmIGl0IHJlYWxseSBib3RoZXJzIGZvbGtzLCB3ZSBjb3VsZCBzZXQgdGhpbmdzCi0gKiB1cCBzbyBkZWxldGVkIHN1YnRyZWVzIGFyZSB3YWxrZWQgYW5kIG1hcmtlZCBpbnZhbGlkLCBidXQgdGhhdCdzCi0gKiBub3QgcGFydCBvZiB0aGUgRE9NJ3MgZGVmaW5lZCBiZWhhdmlvci4pCi0gKiA8UD4KLSAqIEFzIGEgcmVzdWx0LCBvbmx5IHRoZSBFbnRpdHlSZWZlcmVuY2UgaXRzZWxmIGhhcyB0byBiZSBhd2FyZSBvZgotICogY2hhbmdlcyBpbiB0aGUgRW50aXR5LiBBbmQgaXQgY2FuIHRha2UgYWR2YW50YWdlIG9mIHRoZSBzYW1lCi0gKiBzdHJ1Y3R1cmUtY2hhbmdlLW1vbml0b3JpbmcgY29kZSBJIGltcGxlbWVudGVkIHRvIHN1cHBvcnQKLSAqIERlZXBOb2RlTGlzdC4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQHNpbmNlICBQUi1ET00tTGV2ZWwtMS0xOTk4MDgxOC4KLSAqLwotcHVibGljIGNsYXNzIERlZmVycmVkRW50aXR5UmVmZXJlbmNlSW1wbAotICAgIGV4dGVuZHMgRW50aXR5UmVmZXJlbmNlSW1wbAotICAgIGltcGxlbWVudHMgRGVmZXJyZWROb2RlIHsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RhbnRzCi0gICAgLy8KLQotICAgIC8qKiBTZXJpYWxpemF0aW9uIHZlcnNpb24uICovCi0gICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDM5MDMxOTA5MTM3MDAzMjIyM0w7Ci0KLSAgICAvLwotICAgIC8vIERhdGEKLSAgICAvLwotCi0gICAgLyoqIE5vZGUgaW5kZXguICovCi0gICAgcHJvdGVjdGVkIHRyYW5zaWVudCBpbnQgZk5vZGVJbmRleDsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFRoaXMgaXMgdGhlIGRlZmVycmVkIGNvbnN0cnVjdG9yLiBPbmx5IHRoZSBmTm9kZUluZGV4IGlzIGdpdmVuIGhlcmUuCi0gICAgICogQWxsIG90aGVyIGRhdGEsIGNhbiBiZSByZXF1ZXN0ZWQgZnJvbSB0aGUgb3duZXJEb2N1bWVudCB2aWEgdGhlIGluZGV4LgotICAgICAqLwotICAgIERlZmVycmVkRW50aXR5UmVmZXJlbmNlSW1wbChEZWZlcnJlZERvY3VtZW50SW1wbCBvd25lckRvY3VtZW50LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbm9kZUluZGV4KSB7Ci0gICAgICAgIHN1cGVyKG93bmVyRG9jdW1lbnQsIG51bGwpOwotCi0gICAgICAgIGZOb2RlSW5kZXggPSBub2RlSW5kZXg7Ci0gICAgICAgIG5lZWRzU3luY0RhdGEodHJ1ZSk7Ci0KLSAgICB9IC8vIDxpbml0PihEZWZlcnJlZERvY3VtZW50SW1wbCxpbnQpCi0KLSAgICAvLwotICAgIC8vIERlZmVycmVkTm9kZSBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKiBSZXR1cm5zIHRoZSBub2RlIGluZGV4LiAqLwotICAgIHB1YmxpYyBpbnQgZ2V0Tm9kZUluZGV4KCkgewotICAgICAgICByZXR1cm4gZk5vZGVJbmRleDsKLSAgICB9Ci0KLSAgICAvLwotICAgIC8vIFByb3RlY3RlZCBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFN5bmNocm9uaXplIHRoZSBlbnRpdHkgZGF0YS4gVGhpcyBpcyBzcGVjaWFsIGJlY2F1c2Ugb2YgdGhlIHdheQotICAgICAqIHRoYXQgdGhlICJmYXN0IiB2ZXJzaW9uIHN0b3JlcyB0aGUgaW5mb3JtYXRpb24uCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgc3luY2hyb25pemVEYXRhKCkgewotCi0gICAgICAgIC8vIG5vIG5lZWQgdG8gc3ljaHJvbml6ZSBhZ2FpbgotICAgICAgICBuZWVkc1N5bmNEYXRhKGZhbHNlKTsKLQotICAgICAgICAvLyBnZXQgdGhlIG5vZGUgZGF0YQotICAgICAgICBEZWZlcnJlZERvY3VtZW50SW1wbCBvd25lckRvY3VtZW50ID0KLSAgICAgICAgICAgIChEZWZlcnJlZERvY3VtZW50SW1wbCl0aGlzLm93bmVyRG9jdW1lbnQ7Ci0gICAgICAgIG5hbWUgPSBvd25lckRvY3VtZW50LmdldE5vZGVOYW1lKGZOb2RlSW5kZXgpOwotICAgICAgICBiYXNlVVJJID0gb3duZXJEb2N1bWVudC5nZXROb2RlVmFsdWUoZk5vZGVJbmRleCk7Ci0KLSAgICB9IC8vIHN5bmNocm9uaXplRGF0YSgpCi0KLSAgICAvKiogU3luY2hyb25pemUgdGhlIGNoaWxkcmVuLiAqLwotICAgIHByb3RlY3RlZCB2b2lkIHN5bmNocm9uaXplQ2hpbGRyZW4oKSB7Ci0KLSAgICAgICAgLy8gbm8gbmVlZCB0byBzeW5jaHJvbml6ZSBhZ2FpbgotICAgICAgICBuZWVkc1N5bmNDaGlsZHJlbihmYWxzZSk7Ci0KLSAgICAgICAgLy8gZ2V0IGNoaWxkcmVuCi0gICAgICAgIGlzUmVhZE9ubHkoZmFsc2UpOwotICAgICAgICBEZWZlcnJlZERvY3VtZW50SW1wbCBvd25lckRvY3VtZW50ID0KLSAgICAgICAgICAgIChEZWZlcnJlZERvY3VtZW50SW1wbCkgb3duZXJEb2N1bWVudCgpOwotICAgICAgICBvd25lckRvY3VtZW50LnN5bmNocm9uaXplQ2hpbGRyZW4odGhpcywgZk5vZGVJbmRleCk7Ci0gICAgICAgIHNldFJlYWRPbmx5KHRydWUsIHRydWUpOwotCi0gICAgfSAvLyBzeW5jaHJvbml6ZUNoaWxkcmVuKCkKLQotfSAvLyBjbGFzcyBEZWZlcnJlZEVudGl0eVJlZmVyZW5jZUltcGwKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9EZWZlcnJlZE5vZGUuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9EZWZlcnJlZE5vZGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggM2RiYTkxZC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vRGVmZXJyZWROb2RlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0MyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5kb207Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotCi0vKioKLSAqIEFuIGludGVyZmFjZSBmb3IgZGVmZXJyZWQgbm9kZSBvYmplY3QuCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqLwotcHVibGljIGludGVyZmFjZSBEZWZlcnJlZE5vZGUgZXh0ZW5kcyBOb2RlIHsKLQotCi0gICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgVFlQRV9OT0RFICA9ICAyMDsKLQotICAgIC8vCi0gICAgLy8gRGVmZXJyZWROb2RlIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqIFJldHVybnMgdGhlIG5vZGUgaW5kZXguICovCi0gICAgcHVibGljIGludCBnZXROb2RlSW5kZXgoKTsKLQotfSAvLyBpbnRlcmZhY2UgRGVmZXJyZWROb2RlCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vRGVmZXJyZWROb3RhdGlvbkltcGwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9EZWZlcnJlZE5vdGF0aW9uSW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0NmUwNmY3Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9EZWZlcnJlZE5vdGF0aW9uSW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTE3ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwMiwyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbTsKLQotLyoqCi0gKiBOb3RhdGlvbnMgYXJlIGhvdyB0aGUgRG9jdW1lbnQgVHlwZSBEZXNjcmlwdGlvbiAoRFREKSByZWNvcmRzIGhpbnRzCi0gKiBhYm91dCB0aGUgZm9ybWF0IG9mIGFuIFhNTCAidW5wYXJzZWQgZW50aXR5IiAtLSBpbiBvdGhlciB3b3JkcywKLSAqIG5vbi1YTUwgZGF0YSBib3VuZCB0byB0aGlzIGRvY3VtZW50IHR5cGUsIHdoaWNoIHNvbWUgYXBwbGljYXRpb25zCi0gKiBtYXkgd2lzaCB0byBjb25zdWx0IHdoZW4gbWFuaXB1bGF0aW5nIHRoZSBkb2N1bWVudC4gQSBOb3RhdGlvbgotICogcmVwcmVzZW50cyBhIG5hbWUtdmFsdWUgcGFpciwgd2l0aCBpdHMgbm9kZU5hbWUgYmVpbmcgc2V0IHRvIHRoZQotICogZGVjbGFyZWQgbmFtZSBvZiB0aGUgbm90YXRpb24uCi0gKiA8UD4KLSAqIE5vdGF0aW9ucyBhcmUgYWxzbyB1c2VkIHRvIGZvcm1hbGx5IGRlY2xhcmUgdGhlICJ0YXJnZXRzIiBvZgotICogUHJvY2Vzc2luZyBJbnN0cnVjdGlvbnMuCi0gKiA8UD4KLSAqIE5vdGUgdGhhdCB0aGUgTm90YXRpb24ncyBkYXRhIGlzIG5vbi1ET00gaW5mb3JtYXRpb247IHRoZSBET00gb25seQotICogcmVjb3JkcyB3aGF0IGFuZCB3aGVyZSBpdCBpcy4KLSAqIDxQPgotICogU2VlIHRoZSBYTUwgMS4wIHNwZWMsIHNlY3Rpb25zIDQuNyBhbmQgMi42LCBmb3IgbW9yZSBpbmZvLgotICogPFA+Ci0gKiBMZXZlbCAxIG9mIHRoZSBET00gZG9lcyBub3Qgc3VwcG9ydCBlZGl0aW5nIE5vdGF0aW9uIGNvbnRlbnRzLgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAc2luY2UgIFBSLURPTS1MZXZlbC0xLTE5OTgwODE4LgotICovCi1wdWJsaWMgY2xhc3MgRGVmZXJyZWROb3RhdGlvbkltcGwKLSAgICBleHRlbmRzIE5vdGF0aW9uSW1wbAotICAgIGltcGxlbWVudHMgRGVmZXJyZWROb2RlIHsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RhbnRzCi0gICAgLy8KLQotICAgIC8qKiBTZXJpYWxpemF0aW9uIHZlcnNpb24uICovCi0gICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDU3MDUzMzcxNzI4ODc5OTA4NDhMOwotCi0gICAgLy8KLSAgICAvLyBEYXRhCi0gICAgLy8KLQotICAgIC8qKiBOb2RlIGluZGV4LiAqLwotICAgIHByb3RlY3RlZCB0cmFuc2llbnQgaW50IGZOb2RlSW5kZXg7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0cnVjdG9ycwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBUaGlzIGlzIHRoZSBkZWZlcnJlZCBjb25zdHJ1Y3Rvci4gT25seSB0aGUgZk5vZGVJbmRleCBpcyBnaXZlbiBoZXJlLgotICAgICAqIEFsbCBvdGhlciBkYXRhLCBjYW4gYmUgcmVxdWVzdGVkIGZyb20gdGhlIG93bmVyRG9jdW1lbnQgdmlhIHRoZSBpbmRleC4KLSAgICAgKi8KLSAgICBEZWZlcnJlZE5vdGF0aW9uSW1wbChEZWZlcnJlZERvY3VtZW50SW1wbCBvd25lckRvY3VtZW50LCBpbnQgbm9kZUluZGV4KSB7Ci0gICAgICAgIHN1cGVyKG93bmVyRG9jdW1lbnQsIG51bGwpOwotCi0gICAgICAgIGZOb2RlSW5kZXggPSBub2RlSW5kZXg7Ci0gICAgICAgIG5lZWRzU3luY0RhdGEodHJ1ZSk7Ci0KLSAgICB9IC8vIDxpbml0PihEZWZlcnJlZERvY3VtZW50SW1wbCxpbnQpCi0KLSAgICAvLwotICAgIC8vIERlZmVycmVkTm9kZSBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKiBSZXR1cm5zIHRoZSBub2RlIGluZGV4LiAqLwotICAgIHB1YmxpYyBpbnQgZ2V0Tm9kZUluZGV4KCkgewotICAgICAgICByZXR1cm4gZk5vZGVJbmRleDsKLSAgICB9Ci0KLSAgICAvLwotICAgIC8vIFByb3RlY3RlZCBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFN5bmNocm9uaXplcyB0aGUgZGF0YS4gVGhpcyBpcyBzcGVjaWFsIGJlY2F1c2Ugb2YgdGhlIHdheQotICAgICAqIHRoYXQgdGhlICJmYXN0IiBub3RhdGlvbiBzdG9yZXMgaXRzIGluZm9ybWF0aW9uIGludGVybmFsbHkuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgc3luY2hyb25pemVEYXRhKCkgewotCi0gICAgICAgIC8vIG5vIG5lZWQgdG8gc3luY2hyb25pemUgYWdhaW4KLSAgICAgICAgbmVlZHNTeW5jRGF0YShmYWxzZSk7Ci0KLSAgICAgICAgLy8gbmFtZQotICAgICAgICBEZWZlcnJlZERvY3VtZW50SW1wbCBvd25lckRvY3VtZW50ID0KLSAgICAgICAgICAgIChEZWZlcnJlZERvY3VtZW50SW1wbCl0aGlzLm93bmVyRG9jdW1lbnQoKTsKLSAgICAgICAgbmFtZSA9IG93bmVyRG9jdW1lbnQuZ2V0Tm9kZU5hbWUoZk5vZGVJbmRleCk7Ci0KLSAgICAgICAgb3duZXJEb2N1bWVudC5nZXROb2RlVHlwZShmTm9kZUluZGV4KTsKLSAgICAgICAgLy8gcHVibGljIGFuZCBzeXN0ZW0gaWRzCi0gICAgICAgIHB1YmxpY0lkID0gb3duZXJEb2N1bWVudC5nZXROb2RlVmFsdWUoZk5vZGVJbmRleCk7Ci0gICAgICAgIHN5c3RlbUlkID0gb3duZXJEb2N1bWVudC5nZXROb2RlVVJJKGZOb2RlSW5kZXgpOwotICAgICAgICBpbnQgZXh0cmFEYXRhSW5kZXggPSBvd25lckRvY3VtZW50LmdldE5vZGVFeHRyYShmTm9kZUluZGV4KTsKLSAgICAgICAgb3duZXJEb2N1bWVudC5nZXROb2RlVHlwZShleHRyYURhdGFJbmRleCk7Ci0gICAgICAgIGJhc2VVUkkgPSBvd25lckRvY3VtZW50LmdldE5vZGVOYW1lKGV4dHJhRGF0YUluZGV4KTsKLQotCi0gICAgfSAvLyBzeW5jaHJvbml6ZURhdGEoKQotCi19IC8vIGNsYXNzIERlZmVycmVkTm90YXRpb25JbXBsCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vRGVmZXJyZWRQcm9jZXNzaW5nSW5zdHJ1Y3Rpb25JbXBsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vRGVmZXJyZWRQcm9jZXNzaW5nSW5zdHJ1Y3Rpb25JbXBsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDE3OGNkMTMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL0RlZmVycmVkUHJvY2Vzc2luZ0luc3RydWN0aW9uSW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTQgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDAyLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tOwotCi0vKioKLSAqIFByb2Nlc3NpbmcgSW5zdHJ1Y3Rpb25zIChQSXMpIHBlcm1pdCBkb2N1bWVudHMgdG8gY2FycnkKLSAqIHByb2Nlc3Nvci1zcGVjaWZpYyBpbmZvcm1hdGlvbiBhbG9uZ3NpZGUgdGhlaXIgYWN0dWFsIGNvbnRlbnQuIFBJcwotICogYXJlIG1vc3QgY29tbW9uIGluIFhNTCwgYnV0IHRoZXkgYXJlIHN1cHBvcnRlZCBpbiBIVE1MIGFzIHdlbGwuCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBzaW5jZSAgUFItRE9NLUxldmVsLTEtMTk5ODA4MTguCi0gKi8KLXB1YmxpYyBjbGFzcyBEZWZlcnJlZFByb2Nlc3NpbmdJbnN0cnVjdGlvbkltcGwKLSAgICBleHRlbmRzIFByb2Nlc3NpbmdJbnN0cnVjdGlvbkltcGwKLSAgICBpbXBsZW1lbnRzIERlZmVycmVkTm9kZSB7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0YW50cwotICAgIC8vCi0KLSAgICAvKiogU2VyaWFsaXphdGlvbiB2ZXJzaW9uLiAqLwotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNDY0MzU3Nzk1NDI5MzU2NTM4OEw7Ci0KLSAgICAvLwotICAgIC8vIERhdGEKLSAgICAvLwotCi0gICAgLyoqIE5vZGUgaW5kZXguICovCi0gICAgcHJvdGVjdGVkIHRyYW5zaWVudCBpbnQgZk5vZGVJbmRleDsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFRoaXMgaXMgdGhlIGRlZmVycmVkIGNvbnN0cnVjdG9yLiBPbmx5IHRoZSBmTm9kZUluZGV4IGlzIGdpdmVuIGhlcmUuCi0gICAgICogQWxsIG90aGVyIGRhdGEsIGNhbiBiZSByZXF1ZXN0ZWQgZnJvbSB0aGUgb3duZXJEb2N1bWVudCB2aWEgdGhlIGluZGV4LgotICAgICAqLwotICAgIERlZmVycmVkUHJvY2Vzc2luZ0luc3RydWN0aW9uSW1wbChEZWZlcnJlZERvY3VtZW50SW1wbCBvd25lckRvY3VtZW50LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbm9kZUluZGV4KSB7Ci0gICAgICAgIHN1cGVyKG93bmVyRG9jdW1lbnQsIG51bGwsIG51bGwpOwotCi0gICAgICAgIGZOb2RlSW5kZXggPSBub2RlSW5kZXg7Ci0gICAgICAgIG5lZWRzU3luY0RhdGEodHJ1ZSk7Ci0KLSAgICB9IC8vIDxpbml0PihEZWZlcnJlZERvY3VtZW50SW1wbCxpbnQpCi0KLSAgICAvLwotICAgIC8vIERlZmVycmVkTm9kZSBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKiBSZXR1cm5zIHRoZSBub2RlIGluZGV4LiAqLwotICAgIHB1YmxpYyBpbnQgZ2V0Tm9kZUluZGV4KCkgewotICAgICAgICByZXR1cm4gZk5vZGVJbmRleDsKLSAgICB9Ci0KLSAgICAvLwotICAgIC8vIFByb3RlY3RlZCBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKiBTeW5jaHJvbml6ZXMgdGhlIGRhdGEuICovCi0gICAgcHJvdGVjdGVkIHZvaWQgc3luY2hyb25pemVEYXRhKCkgewotCi0gICAgICAgIC8vIG5vIG5lZWQgdG8gc3luYyBpbiB0aGUgZnV0dXJlCi0gICAgICAgIG5lZWRzU3luY0RhdGEoZmFsc2UpOwotCi0gICAgICAgIC8vIGZsdWZmIGRhdGEKLSAgICAgICAgRGVmZXJyZWREb2N1bWVudEltcGwgb3duZXJEb2N1bWVudCA9Ci0gICAgICAgICAgICAoRGVmZXJyZWREb2N1bWVudEltcGwpIHRoaXMub3duZXJEb2N1bWVudCgpOwotICAgICAgICB0YXJnZXQgID0gb3duZXJEb2N1bWVudC5nZXROb2RlTmFtZShmTm9kZUluZGV4KTsKLSAgICAgICAgZGF0YSA9IG93bmVyRG9jdW1lbnQuZ2V0Tm9kZVZhbHVlU3RyaW5nKGZOb2RlSW5kZXgpOwotCi0gICAgfSAvLyBzeW5jaHJvbml6ZURhdGEoKQotCi19IC8vIGNsYXNzIERlZmVycmVkUHJvY2Vzc2luZ0luc3RydWN0aW9uSW1wbApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL0RlZmVycmVkVGV4dEltcGwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9EZWZlcnJlZFRleHRJbXBsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDM3ZDU1OWEuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL0RlZmVycmVkVGV4dEltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEwNyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5kb207Ci0KLS8qKgotICogVGV4dCBub2RlcyBob2xkIHRoZSBub24tbWFya3VwLCBub24tRW50aXR5IGNvbnRlbnQgb2YKLSAqIGFuIEVsZW1lbnQgb3IgQXR0cmlidXRlLgotICogPFA+Ci0gKiBXaGVuIGEgZG9jdW1lbnQgaXMgZmlyc3QgbWFkZSBhdmFpbGFibGUgdG8gdGhlIERPTSwgdGhlcmUgaXMgb25seQotICogb25lIFRleHQgb2JqZWN0IGZvciBlYWNoIGJsb2NrIG9mIGFkamFjZW50IHBsYWluLXRleHQuIFVzZXJzIChpZSwKLSAqIGFwcGxpY2F0aW9ucykgbWF5IGNyZWF0ZSBtdWx0aXBsZSBhZGphY2VudCBUZXh0cyBkdXJpbmcgZWRpdGluZyAtLQotICogc2VlIHtAbGluayBvcmcudzNjLmRvbS5FbGVtZW50I25vcm1hbGl6ZX0gZm9yIGRpc2N1c3Npb24uCi0gKiA8UD4KLSAqIE5vdGUgdGhhdCBDREFUQVNlY3Rpb24gaXMgYSBzdWJjbGFzcyBvZiBUZXh0LiBUaGlzIGlzIGNvbmNlcHR1YWxseQotICogdmFsaWQsIHNpbmNlIHRoZXkncmUgcmVhbGx5IGp1c3QgdHdvIGRpZmZlcmVudCB3YXlzIG9mIHF1b3RpbmcKLSAqIGNoYXJhY3RlcnMgd2hlbiB0aGV5J3JlIHdyaXR0ZW4gb3V0IGFzIHBhcnQgb2YgYW4gWE1MIHN0cmVhbS4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQHNpbmNlICBQUi1ET00tTGV2ZWwtMS0xOTk4MDgxOC4KLSAqLwotcHVibGljIGNsYXNzIERlZmVycmVkVGV4dEltcGwKLSAgICBleHRlbmRzIFRleHRJbXBsCi0gICAgaW1wbGVtZW50cyBEZWZlcnJlZE5vZGUgewotCi0gICAgLy8KLSAgICAvLyBDb25zdGFudHMKLSAgICAvLwotCi0gICAgLyoqIFNlcmlhbGl6YXRpb24gdmVyc2lvbi4gKi8KLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMjMxMDYxMzg3MjEwMDM5MzQyNUw7Ci0KLSAgICAvLwotICAgIC8vIERhdGEKLSAgICAvLwotCi0gICAgLyoqIE5vZGUgaW5kZXguICovCi0gICAgcHJvdGVjdGVkIHRyYW5zaWVudCBpbnQgZk5vZGVJbmRleDsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFRoaXMgaXMgdGhlIGRlZmVycmVkIGNvbnN0cnVjdG9yLiBPbmx5IHRoZSBmTm9kZUluZGV4IGlzIGdpdmVuIGhlcmUuCi0gICAgICogQWxsIG90aGVyIGRhdGEsIGNhbiBiZSByZXF1ZXN0ZWQgZnJvbSB0aGUgb3duZXJEb2N1bWVudCB2aWEgdGhlIGluZGV4LgotICAgICAqLwotICAgIERlZmVycmVkVGV4dEltcGwoRGVmZXJyZWREb2N1bWVudEltcGwgb3duZXJEb2N1bWVudCwgaW50IG5vZGVJbmRleCkgewotICAgICAgICBzdXBlcihvd25lckRvY3VtZW50LCBudWxsKTsKLQotICAgICAgICBmTm9kZUluZGV4ID0gbm9kZUluZGV4OwotICAgICAgICBuZWVkc1N5bmNEYXRhKHRydWUpOwotCi0gICAgfSAvLyA8aW5pdD4oRGVmZXJyZWREb2N1bWVudEltcGwsaW50KQotCi0gICAgLy8KLSAgICAvLyBEZWZlcnJlZE5vZGUgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKiogUmV0dXJucyB0aGUgbm9kZSBpbmRleC4gKi8KLSAgICBwdWJsaWMgaW50IGdldE5vZGVJbmRleCgpIHsKLSAgICAgICAgcmV0dXJuIGZOb2RlSW5kZXg7Ci0gICAgfQotCi0gICAgLy8KLSAgICAvLyBQcm90ZWN0ZWQgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKiogU3luY2hyb25pemVzIHRoZSB1bmRlcmx5aW5nIGRhdGEuICovCi0gICAgcHJvdGVjdGVkIHZvaWQgc3luY2hyb25pemVEYXRhKCkgewotCi0gICAgICAgIC8vIG5vIG5lZWQgZm9yIGZ1dHVyZSBzeW5jaHJvbml6YXRpb25zCi0gICAgICAgIG5lZWRzU3luY0RhdGEoZmFsc2UpOwotCi0gICAgICAgIC8vIGdldCBpbml0aWFsIHRleHQgdmFsdWUKLSAgICAgICAgRGVmZXJyZWREb2N1bWVudEltcGwgb3duZXJEb2N1bWVudCA9Ci0gICAgICAgICAgICAoRGVmZXJyZWREb2N1bWVudEltcGwpIHRoaXMub3duZXJEb2N1bWVudCgpOwotICAgICAgICBkYXRhID0gb3duZXJEb2N1bWVudC5nZXROb2RlVmFsdWVTdHJpbmcoZk5vZGVJbmRleCk7Ci0KLSAgICAgICAgLy8gTk9URTogV2UgdXNlZCB0byBub3JtYWxpemUgYWRqYWNlbnQgdGV4dCBub2RlIHZhbHVlcyBoZXJlLgotICAgICAgICAvLyAgICAgICBUaGlzIGNvZGUgaGFzIG1vdmVkIHRvIHRoZSBEZWZlcnJlZERvY3VtZW50SW1wbAotICAgICAgICAvLyAgICAgICBnZXROb2RlVmFsdWVTdHJpbmcoKSBtZXRob2QuIC1BYwotCi0gICAgICAgIC8vIGlnbm9yYWJsZSB3aGl0ZXNwYWNlCi0gICAgICAgIGlzSWdub3JhYmxlV2hpdGVzcGFjZShvd25lckRvY3VtZW50LmdldE5vZGVFeHRyYShmTm9kZUluZGV4KSA9PSAxKTsKLQotICAgIH0gLy8gc3luY2hyb25pemVEYXRhKCkKLQotfSAvLyBjbGFzcyBEZWZlcnJlZFRleHRJbXBsCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vRG9jdW1lbnRGcmFnbWVudEltcGwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9Eb2N1bWVudEZyYWdtZW50SW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2NDI0OGUyLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9Eb2N1bWVudEZyYWdtZW50SW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTU1ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5kb207Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudEZyYWdtZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci1pbXBvcnQgb3JnLnczYy5kb20uVGV4dDsKLQotLyoqCi0gKiBEb2N1bWVudEZyYWdtZW50IGlzIGEgImxpZ2h0d2VpZ2h0IiBvciAibWluaW1hbCIgRG9jdW1lbnQKLSAqIG9iamVjdC4gSXQgaXMgdmVyeSBjb21tb24gdG8gd2FudCB0byBiZSBhYmxlIHRvIGV4dHJhY3QgYSBwb3J0aW9uCi0gKiBvZiBhIGRvY3VtZW50J3MgdHJlZSBvciB0byBjcmVhdGUgYSBuZXcgZnJhZ21lbnQgb2YgYQotICogZG9jdW1lbnQuIEltYWdpbmUgaW1wbGVtZW50aW5nIGEgdXNlciBjb21tYW5kIGxpa2UgY3V0IG9yCi0gKiByZWFycmFuZ2luZyBhIGRvY3VtZW50IGJ5IG1vdmluZyBmcmFnbWVudHMgYXJvdW5kLiBJdCBpcyBkZXNpcmFibGUKLSAqIHRvIGhhdmUgYW4gb2JqZWN0IHdoaWNoIGNhbiBob2xkIHN1Y2ggZnJhZ21lbnRzIGFuZCBpdCBpcyBxdWl0ZQotICogbmF0dXJhbCB0byB1c2UgYSBOb2RlIGZvciB0aGlzIHB1cnBvc2UuIFdoaWxlIGl0IGlzIHRydWUgdGhhdCBhCi0gKiBEb2N1bWVudCBvYmplY3QgY291bGQgZnVsZmlsIHRoaXMgcm9sZSwgYSBEb2N1bWVudCBvYmplY3QgY2FuCi0gKiBwb3RlbnRpYWxseSBiZSBhIGhlYXZ5d2VpZ2h0IG9iamVjdCwgZGVwZW5kaW5nIG9uIHRoZSB1bmRlcmx5aW5nCi0gKiBpbXBsZW1lbnRhdGlvbi4uLiBhbmQgaW4gRE9NIExldmVsIDEsIG5vZGVzIGFyZW4ndCBhbGxvd2VkIHRvIGNyb3NzCi0gKiBEb2N1bWVudCBib3VuZGFyaWVzIGFueXdheS4gV2hhdCBpcyByZWFsbHkgbmVlZGVkIGZvciB0aGlzIGlzIGEKLSAqIHZlcnkgbGlnaHR3ZWlnaHQgb2JqZWN0LiAgRG9jdW1lbnRGcmFnbWVudCBpcyBzdWNoIGFuIG9iamVjdC4KLSAqIDxQPgotICogRnVydGhlcm1vcmUsIHZhcmlvdXMgb3BlcmF0aW9ucyAtLSBzdWNoIGFzIGluc2VydGluZyBub2RlcyBhcwotICogY2hpbGRyZW4gb2YgYW5vdGhlciBOb2RlIC0tIG1heSB0YWtlIERvY3VtZW50RnJhZ21lbnQgb2JqZWN0cyBhcwotICogYXJndW1lbnRzOyB0aGlzIHJlc3VsdHMgaW4gYWxsIHRoZSBjaGlsZCBub2RlcyBvZiB0aGUKLSAqIERvY3VtZW50RnJhZ21lbnQgYmVpbmcgbW92ZWQgdG8gdGhlIGNoaWxkIGxpc3Qgb2YgdGhpcyBub2RlLgotICogPFA+Ci0gKiBUaGUgY2hpbGRyZW4gb2YgYSBEb2N1bWVudEZyYWdtZW50IG5vZGUgYXJlIHplcm8gb3IgbW9yZSBub2RlcwotICogcmVwcmVzZW50aW5nIHRoZSB0b3BzIG9mIGFueSBzdWItdHJlZXMgZGVmaW5pbmcgdGhlIHN0cnVjdHVyZSBvZgotICogdGhlIGRvY3VtZW50LiAgRG9jdW1lbnRGcmFnbWVudCBkbyBub3QgbmVlZCB0byBiZSB3ZWxsLWZvcm1lZCBYTUwKLSAqIGRvY3VtZW50cyAoYWx0aG91Z2ggdGhleSBkbyBuZWVkIHRvIGZvbGxvdyB0aGUgcnVsZXMgaW1wb3NlZCB1cG9uCi0gKiB3ZWxsLWZvcm1lZCBYTUwgcGFyc2VkIGVudGl0aWVzLCB3aGljaCBjYW4gaGF2ZSBtdWx0aXBsZSB0b3AKLSAqIG5vZGVzKS4gRm9yIGV4YW1wbGUsIGEgRG9jdW1lbnRGcmFnbWVudCBtaWdodCBoYXZlIG9ubHkgb25lIGNoaWxkCi0gKiBhbmQgdGhhdCBjaGlsZCBub2RlIGNvdWxkIGJlIGEgVGV4dCBub2RlLiBTdWNoIGEgc3RydWN0dXJlIG1vZGVsCi0gKiByZXByZXNlbnRzIG5laXRoZXIgYW4gSFRNTCBkb2N1bWVudCBub3IgYSB3ZWxsLWZvcm1lZCBYTUwgZG9jdW1lbnQuCi0gKiA8UD4KLSAqIFdoZW4gYSBEb2N1bWVudEZyYWdtZW50IGlzIGluc2VydGVkIGludG8gYSBEb2N1bWVudCAob3IgaW5kZWVkIGFueQotICogb3RoZXIgTm9kZSB0aGF0IG1heSB0YWtlIGNoaWxkcmVuKSB0aGUgY2hpbGRyZW4gb2YgdGhlCi0gKiBEb2N1bWVudEZyYWdtZW50IGFuZCBub3QgdGhlIERvY3VtZW50RnJhZ21lbnQgaXRzZWxmIGFyZSBpbnNlcnRlZAotICogaW50byB0aGUgTm9kZS4gVGhpcyBtYWtlcyB0aGUgRG9jdW1lbnRGcmFnbWVudCB2ZXJ5IHVzZWZ1bCB3aGVuIHRoZQotICogdXNlciB3aXNoZXMgdG8gY3JlYXRlIG5vZGVzIHRoYXQgYXJlIHNpYmxpbmdzOyB0aGUgRG9jdW1lbnRGcmFnbWVudAotICogYWN0cyBhcyB0aGUgcGFyZW50IG9mIHRoZXNlIG5vZGVzIHNvIHRoYXQgdGhlIHVzZXIgY2FuIHVzZSB0aGUKLSAqIHN0YW5kYXJkIG1ldGhvZHMgZnJvbSB0aGUgTm9kZSBpbnRlcmZhY2UsIHN1Y2ggYXMgaW5zZXJ0QmVmb3JlKCkKLSAqIGFuZCBhcHBlbmRDaGlsZCgpLgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAc2luY2UgIFBSLURPTS1MZXZlbC0xLTE5OTgwODE4LgotICovCi1wdWJsaWMgY2xhc3MgRG9jdW1lbnRGcmFnbWVudEltcGwKLSAgICBleHRlbmRzIFBhcmVudE5vZGUKLSAgICBpbXBsZW1lbnRzIERvY3VtZW50RnJhZ21lbnQgewotCi0gICAgLy8KLSAgICAvLyBDb25zdGFudHMKLSAgICAvLwotCi0gICAgLyoqIFNlcmlhbGl6YXRpb24gdmVyc2lvbi4gKi8KLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTc1OTY0NDk5NjcyNzkyMzY3NDZMOwotCi0gICAgLy8KLSAgICAvLyBDb25zdHJ1Y3RvcnMKLSAgICAvLwotCi0gICAgLyoqIEZhY3RvcnkgY29uc3RydWN0b3IuICovCi0gICAgcHVibGljIERvY3VtZW50RnJhZ21lbnRJbXBsKENvcmVEb2N1bWVudEltcGwgb3duZXJEb2MpIHsKLSAgICAgICAgc3VwZXIob3duZXJEb2MpOwotICAgIH0KLQotICAgIC8qKiBDb25zdHJ1Y3RvciBmb3Igc2VyaWFsaXphdGlvbi4gKi8KLSAgICBwdWJsaWMgRG9jdW1lbnRGcmFnbWVudEltcGwoKSB7fQotCi0gICAgLy8KLSAgICAvLyBOb2RlIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogQSBzaG9ydCBpbnRlZ2VyIGluZGljYXRpbmcgd2hhdCB0eXBlIG9mIG5vZGUgdGhpcyBpcy4gVGhlIG5hbWVkCi0gICAgICogY29uc3RhbnRzIGZvciB0aGlzIHZhbHVlIGFyZSBkZWZpbmVkIGluIHRoZSBvcmcudzNjLmRvbS5Ob2RlIGludGVyZmFjZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc2hvcnQgZ2V0Tm9kZVR5cGUoKSB7Ci0gICAgICAgIHJldHVybiBOb2RlLkRPQ1VNRU5UX0ZSQUdNRU5UX05PREU7Ci0gICAgfQotCi0gICAgLyoqIFJldHVybnMgdGhlIG5vZGUgbmFtZS4gKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE5vZGVOYW1lKCkgewotICAgICAgICByZXR1cm4gIiNkb2N1bWVudC1mcmFnbWVudCI7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogT3ZlcnJpZGUgZGVmYXVsdCBiZWhhdmlvciB0byBjYWxsIG5vcm1hbGl6ZSgpIG9uIHRoaXMgTm9kZSdzCi0gICAgICogY2hpbGRyZW4uIEl0IGlzIHVwIHRvIGltcGxlbWVudG9ycyBvciBOb2RlIHRvIG92ZXJyaWRlIG5vcm1hbGl6ZSgpCi0gICAgICogdG8gdGFrZSBhY3Rpb24uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgbm9ybWFsaXplKCkgewotICAgICAgICAvLyBObyBuZWVkIHRvIG5vcm1hbGl6ZSBpZiBhbHJlYWR5IG5vcm1hbGl6ZWQuCi0gICAgICAgIGlmIChpc05vcm1hbGl6ZWQoKSkgewotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0gICAgICAgIGlmIChuZWVkc1N5bmNDaGlsZHJlbigpKSB7Ci0gICAgICAgICAgICBzeW5jaHJvbml6ZUNoaWxkcmVuKCk7Ci0gICAgICAgIH0KLSAgICAgICAgQ2hpbGROb2RlIGtpZCwgbmV4dDsKLQotICAgICAgICBmb3IgKGtpZCA9IGZpcnN0Q2hpbGQ7IGtpZCAhPSBudWxsOyBraWQgPSBuZXh0KSB7Ci0gICAgICAgICAgICBuZXh0ID0ga2lkLm5leHRTaWJsaW5nOwotCi0gICAgICAgICAgICAvLyBJZiBraWQgaXMgYSB0ZXh0IG5vZGUsIHdlIG5lZWQgdG8gY2hlY2sgZm9yIG9uZSBvZiB0d28KLSAgICAgICAgICAgIC8vIGNvbmRpdGlvbnM6Ci0gICAgICAgICAgICAvLyAgIDEpIFRoZXJlIGlzIGFuIGFkamFjZW50IHRleHQgbm9kZQotICAgICAgICAgICAgLy8gICAyKSBUaGVyZSBpcyBubyBhZGphY2VudCB0ZXh0IG5vZGUsIGJ1dCBraWQgaXMKLSAgICAgICAgICAgIC8vICAgICAgYW4gZW1wdHkgdGV4dCBub2RlLgotICAgICAgICAgICAgaWYgKCBraWQuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLlRFWFRfTk9ERSApCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgLy8gSWYgYW4gYWRqYWNlbnQgdGV4dCBub2RlLCBtZXJnZSBpdCB3aXRoIGtpZAotICAgICAgICAgICAgICAgIGlmICggbmV4dCE9bnVsbCAmJiBuZXh0LmdldE5vZGVUeXBlKCkgPT0gTm9kZS5URVhUX05PREUgKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgKChUZXh0KWtpZCkuYXBwZW5kRGF0YShuZXh0LmdldE5vZGVWYWx1ZSgpKTsKLSAgICAgICAgICAgICAgICAgICAgcmVtb3ZlQ2hpbGQoIG5leHQgKTsKLSAgICAgICAgICAgICAgICAgICAgbmV4dCA9IGtpZDsgLy8gRG9uJ3QgYWR2YW5jZTsgdGhlcmUgbWlnaHQgYmUgYW5vdGhlci4KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gSWYga2lkIGlzIGVtcHR5LCByZW1vdmUgaXQKLSAgICAgICAgICAgICAgICAgICAgaWYgKCBraWQuZ2V0Tm9kZVZhbHVlKCkgPT0gbnVsbCB8fCBraWQuZ2V0Tm9kZVZhbHVlKCkubGVuZ3RoKCkgPT0gMCApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZUNoaWxkKCBraWQgKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAga2lkLm5vcm1hbGl6ZSgpOwotICAgICAgICB9Ci0KLSAgICAgICAgaXNOb3JtYWxpemVkKHRydWUpOwotICAgIH0KLQotfSAvLyBjbGFzcyBEb2N1bWVudEZyYWdtZW50SW1wbApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL0RvY3VtZW50SW1wbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL0RvY3VtZW50SW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhNWZlNGI4Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9Eb2N1bWVudEltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEzNzkgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAxNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqLwotLyoKLSAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQotICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCi0gKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCi0gKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAotICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKLSAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5kb20uZXZlbnRzLkV2ZW50SW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbS5ldmVudHMuTXV0YXRpb25FdmVudEltcGw7Ci1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uT2JqZWN0T3V0cHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uT2JqZWN0U3RyZWFtRmllbGQ7Ci1pbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7Ci1pbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaHRhYmxlOwotaW1wb3J0IGphdmEudXRpbC5MaXN0OwotaW1wb3J0IGphdmEudXRpbC5NYXA7Ci1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLWltcG9ydCBvcmcudzNjLmRvbS5BdHRyOwotaW1wb3J0IG9yZy53M2MuZG9tLkRPTUV4Y2VwdGlvbjsKLWltcG9ydCBvcmcudzNjLmRvbS5ET01JbXBsZW1lbnRhdGlvbjsKLWltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudFR5cGU7Ci1pbXBvcnQgb3JnLnczYy5kb20uRWxlbWVudDsKLWltcG9ydCBvcmcudzNjLmRvbS5OYW1lZE5vZGVNYXA7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcudzNjLmRvbS5Vc2VyRGF0YUhhbmRsZXI7Ci1pbXBvcnQgb3JnLnczYy5kb20uZXZlbnRzLkRvY3VtZW50RXZlbnQ7Ci1pbXBvcnQgb3JnLnczYy5kb20uZXZlbnRzLkV2ZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLmV2ZW50cy5FdmVudEV4Y2VwdGlvbjsKLWltcG9ydCBvcmcudzNjLmRvbS5ldmVudHMuRXZlbnRMaXN0ZW5lcjsKLWltcG9ydCBvcmcudzNjLmRvbS5ldmVudHMuTXV0YXRpb25FdmVudDsKLWltcG9ydCBvcmcudzNjLmRvbS5yYW5nZXMuRG9jdW1lbnRSYW5nZTsKLWltcG9ydCBvcmcudzNjLmRvbS5yYW5nZXMuUmFuZ2U7Ci1pbXBvcnQgb3JnLnczYy5kb20udHJhdmVyc2FsLkRvY3VtZW50VHJhdmVyc2FsOwotaW1wb3J0IG9yZy53M2MuZG9tLnRyYXZlcnNhbC5Ob2RlRmlsdGVyOwotaW1wb3J0IG9yZy53M2MuZG9tLnRyYXZlcnNhbC5Ob2RlSXRlcmF0b3I7Ci1pbXBvcnQgb3JnLnczYy5kb20udHJhdmVyc2FsLlRyZWVXYWxrZXI7Ci0KLQotLyoqCi0gKiBUaGUgRG9jdW1lbnQgaW50ZXJmYWNlIHJlcHJlc2VudHMgdGhlIGVudGlyZSBIVE1MIG9yIFhNTCBkb2N1bWVudC4KLSAqIENvbmNlcHR1YWxseSwgaXQgaXMgdGhlIHJvb3Qgb2YgdGhlIGRvY3VtZW50IHRyZWUsIGFuZCBwcm92aWRlcyB0aGUKLSAqIHByaW1hcnkgYWNjZXNzIHRvIHRoZSBkb2N1bWVudCdzIGRhdGEuCi0gKiA8UD4KLSAqIFNpbmNlIGVsZW1lbnRzLCB0ZXh0IG5vZGVzLCBjb21tZW50cywgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbnMsCi0gKiBldGMuIGNhbm5vdCBleGlzdCBvdXRzaWRlIHRoZSBjb250ZXh0IG9mIGEgRG9jdW1lbnQsIHRoZSBEb2N1bWVudAotICogaW50ZXJmYWNlIGFsc28gY29udGFpbnMgdGhlIGZhY3RvcnkgbWV0aG9kcyBuZWVkZWQgdG8gY3JlYXRlIHRoZXNlCi0gKiBvYmplY3RzLiBUaGUgTm9kZSBvYmplY3RzIGNyZWF0ZWQgaGF2ZSBhIG93bmVyRG9jdW1lbnQgYXR0cmlidXRlCi0gKiB3aGljaCBhc3NvY2lhdGVzIHRoZW0gd2l0aCB0aGUgRG9jdW1lbnQgd2l0aGluIHdob3NlIGNvbnRleHQgdGhleQotICogd2VyZSBjcmVhdGVkLgotICogPHA+Ci0gKiBUaGUgRG9jdW1lbnRJbXBsIGNsYXNzIGFsc28gaW1wbGVtZW50cyB0aGUgRE9NIExldmVsIDIgRG9jdW1lbnRUcmF2ZXJzYWwKLSAqIGludGVyZmFjZS4gVGhpcyBpbnRlcmZhY2UgaXMgY29tcHJpc2VkIG9mIGZhY3RvcnkgbWV0aG9kcyBuZWVkZWQgdG8KLSAqIGNyZWF0ZSBOb2RlSXRlcmF0b3JzIGFuZCBUcmVlV2Fsa2Vycy4gVGhlIHByb2Nlc3Mgb2YgY3JlYXRpbmcgTm9kZUl0ZXJhdG9yCi0gKiBvYmplY3RzIGFsc28gYWRkcyB0aGVzZSByZWZlcmVuY2VzIHRvIHRoaXMgZG9jdW1lbnQuCi0gKiBBZnRlciBmaW5pc2hpbmcgd2l0aCBhbiBpdGVyYXRvciBpdCBpcyBpbXBvcnRhbnQgdG8gcmVtb3ZlIHRoZSBvYmplY3QKLSAqIHVzaW5nIHRoZSByZW1vdmUgbWV0aG9kcyBpbiB0aGlzIGltcGxlbWVudGF0aW9uLiBUaGlzIGFsbG93cyB0aGUgcmVsZWFzZSBvZgotICogdGhlIHJlZmVyZW5jZXMgZnJvbSB0aGUgaXRlcmF0b3Igb2JqZWN0cyB0byB0aGUgRE9NIE5vZGVzLgotICogPHA+Ci0gKiA8Yj5Ob3RlOjwvYj4gV2hlbiBhbnkgbm9kZSBpbiB0aGUgZG9jdW1lbnQgaXMgc2VyaWFsaXplZCwgdGhlCi0gKiBlbnRpcmUgZG9jdW1lbnQgaXMgc2VyaWFsaXplZCBhbG9uZyB3aXRoIGl0LgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIEFybmF1ZCAgTGUgSG9ycywgSUJNCi0gKiBAYXV0aG9yIEpvZSBLZXNzZWxtYW4sIElCTQotICogQGF1dGhvciBBbmR5IENsYXJrLCBJQk0KLSAqIEBhdXRob3IgUmFsZiBQZmVpZmZlciwgSUJNCi0gKiBAdmVyc2lvbiAkSWQ6IERvY3VtZW50SW1wbC5qYXZhLHYgMS42IDIwMTAvMDcvMjAgMjA6MjU6MjQgam9laHcgRXhwICQKLSAqIEBzaW5jZSAgUFItRE9NLUxldmVsLTEtMTk5ODA4MTguCi0gKi8KLXB1YmxpYyBjbGFzcyBEb2N1bWVudEltcGwKLSAgICBleHRlbmRzIENvcmVEb2N1bWVudEltcGwKLSAgICBpbXBsZW1lbnRzIERvY3VtZW50VHJhdmVyc2FsLCBEb2N1bWVudEV2ZW50LCBEb2N1bWVudFJhbmdlIHsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RhbnRzCi0gICAgLy8KLQotICAgIC8qKiBTZXJpYWxpemF0aW9uIHZlcnNpb24uICovCi0gICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDUxNTY4NzgzNTU0MjYxNjY5NEw7Ci0KLSAgICAvLwotICAgIC8vIERhdGEKLSAgICAvLwotCi0gICAgLyoqIEl0ZXJhdG9ycyAqLwotICAgIC8vIFJFVklTSVQ6IFNob3VsZCB0aGlzIGJlIHRyYW5zaWVudD8gLUFjCi0gICAgcHJvdGVjdGVkIExpc3Q8Tm9kZUl0ZXJhdG9yPiBpdGVyYXRvcnM7Ci0KLSAgICAgLyoqIFJhbmdlcyAqLwotICAgIC8vIFJFVklTSVQ6IFNob3VsZCB0aGlzIGJlIHRyYW5zaWVudD8gLUFjCi0gICAgcHJvdGVjdGVkIExpc3Q8UmFuZ2U+IHJhbmdlczsKLQotICAgIC8qKiBUYWJsZSBmb3IgZXZlbnQgbGlzdGVuZXJzIHJlZ2lzdGVyZWQgdG8gdGhpcyBkb2N1bWVudCBub2Rlcy4gKi8KLSAgICBwcm90ZWN0ZWQgTWFwPE5vZGVJbXBsLCBMaXN0PExFbnRyeT4+IGV2ZW50TGlzdGVuZXJzOwotCi0gICAgLyoqIEJ5cGFzcyBtdXRhdGlvbiBldmVudHMgZmlyaW5nLiAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIG11dGF0aW9uRXZlbnRzID0gZmFsc2U7Ci0KLQotICAgIC8qKgotICAgICAqIEBzZXJpYWxGaWVsZCBpdGVyYXRvcnMgVmVjdG9yIE5vZGUgaXRlcmF0b3JzCi0gICAgICogQHNlcmlhbEZpZWxkIHJhbmdlcyBWZWN0b3IgcmFuZ2VzCi0gICAgICogQHNlcmlhbEZpZWxkIGV2ZW50TGlzdGVuZXJzIEhhc2h0YWJsZSBFdmVudCBsaXN0ZW5lcnMKLSAgICAgKiBAc2VyaWFsRmllbGQgbXV0YXRpb25FdmVudHMgYm9vbGVhbiBCeXBhc3MgbXV0YXRpb24gZXZlbnRzIGZpcmluZwotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIE9iamVjdFN0cmVhbUZpZWxkW10gc2VyaWFsUGVyc2lzdGVudEZpZWxkcyA9Ci0gICAgICAgIG5ldyBPYmplY3RTdHJlYW1GaWVsZFtdIHsKLSAgICAgICAgICAgIG5ldyBPYmplY3RTdHJlYW1GaWVsZCgiaXRlcmF0b3JzIiwgVmVjdG9yLmNsYXNzKSwKLSAgICAgICAgICAgIG5ldyBPYmplY3RTdHJlYW1GaWVsZCgicmFuZ2VzIiwgVmVjdG9yLmNsYXNzKSwKLSAgICAgICAgICAgIG5ldyBPYmplY3RTdHJlYW1GaWVsZCgiZXZlbnRMaXN0ZW5lcnMiLCBIYXNodGFibGUuY2xhc3MpLAotICAgICAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJtdXRhdGlvbkV2ZW50cyIsIGJvb2xlYW4uY2xhc3MpLAotICAgICAgICB9OwotCi0gICAgLy8KLSAgICAvLyBDb25zdHJ1Y3RvcnMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogTk9OLURPTTogQWN0dWFsbHkgY3JlYXRpbmcgYSBEb2N1bWVudCBpcyBvdXRzaWRlIHRoZSBET00ncyBzcGVjLAotICAgICAqIHNpbmNlIGl0IGhhcyB0byBvcGVyYXRlIGluIHRlcm1zIG9mIGEgcGFydGljdWxhciBpbXBsZW1lbnRhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgRG9jdW1lbnRJbXBsKCkgewotICAgICAgICBzdXBlcigpOwotICAgIH0KLQotICAgIC8qKiBDb25zdHJ1Y3Rvci4gKi8KLSAgICBwdWJsaWMgRG9jdW1lbnRJbXBsKGJvb2xlYW4gZ3JhbW1hckFjY2VzcykgewotICAgICAgICBzdXBlcihncmFtbWFyQWNjZXNzKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBGb3IgRE9NMiBzdXBwb3J0LgotICAgICAqIFRoZSBjcmVhdGVEb2N1bWVudCBmYWN0b3J5IG1ldGhvZCBpcyBpbiBET01JbXBsZW1lbnRhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgRG9jdW1lbnRJbXBsKERvY3VtZW50VHlwZSBkb2N0eXBlKQotICAgIHsKLSAgICAgICAgc3VwZXIoZG9jdHlwZSk7Ci0gICAgfQotCi0gICAgLyoqIEZvciBET00yIHN1cHBvcnQuICovCi0gICAgcHVibGljIERvY3VtZW50SW1wbChEb2N1bWVudFR5cGUgZG9jdHlwZSwgYm9vbGVhbiBncmFtbWFyQWNjZXNzKSB7Ci0gICAgICAgIHN1cGVyKGRvY3R5cGUsIGdyYW1tYXJBY2Nlc3MpOwotICAgIH0KLQotICAgIC8vCi0gICAgLy8gTm9kZSBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIERlZXAtY2xvbmUgYSBkb2N1bWVudCwgaW5jbHVkaW5nIGZpeGluZyBvd25lckRvYyBmb3IgdGhlIGNsb25lZAotICAgICAqIGNoaWxkcmVuLiBOb3RlIHRoYXQgdGhpcyByZXF1aXJlcyBieXBhc3NpbmcgdGhlIFdST05HX0RPQ1VNRU5UX0VSUgotICAgICAqIHByb3RlY3Rpb24uIEkndmUgY2hvc2VuIHRvIGltcGxlbWVudCBpdCBieSBjYWxsaW5nIGltcG9ydE5vZGUKLSAgICAgKiB3aGljaCBpcyBET00gTGV2ZWwgMi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gb3JnLnczYy5kb20uTm9kZQotICAgICAqIEBwYXJhbSBkZWVwIGJvb2xlYW4sIGlmZiB0cnVlIHJlcGxpY2F0ZSBjaGlsZHJlbgotICAgICAqLwotICAgIHB1YmxpYyBOb2RlIGNsb25lTm9kZShib29sZWFuIGRlZXApIHsKLQotICAgICAgICBEb2N1bWVudEltcGwgbmV3ZG9jID0gbmV3IERvY3VtZW50SW1wbCgpOwotICAgICAgICBjYWxsVXNlckRhdGFIYW5kbGVycyh0aGlzLCBuZXdkb2MsIFVzZXJEYXRhSGFuZGxlci5OT0RFX0NMT05FRCk7Ci0gICAgICAgIGNsb25lTm9kZShuZXdkb2MsIGRlZXApOwotCi0gICAgICAgIC8vIGV4cGVyaW1lbnRhbAotICAgICAgICBuZXdkb2MubXV0YXRpb25FdmVudHMgPSBtdXRhdGlvbkV2ZW50czsKLQotICAgICAgICByZXR1cm4gbmV3ZG9jOwotCi0gICAgfSAvLyBjbG9uZU5vZGUoYm9vbGVhbik6Tm9kZQotCi0gICAgLyoqCi0gICAgICogUmV0cmlldmUgaW5mb3JtYXRpb24gZGVzY3JpYmluZyB0aGUgYWJpbGl0aWVzIG9mIHRoaXMgcGFydGljdWxhcgotICAgICAqIERPTSBpbXBsZW1lbnRhdGlvbi4gSW50ZW5kZWQgdG8gc3VwcG9ydCBhcHBsaWNhdGlvbnMgdGhhdCBtYXkgYmUKLSAgICAgKiB1c2luZyBET01zIHJldHJpZXZlZCBmcm9tIHNldmVyYWwgZGlmZmVyZW50IHNvdXJjZXMsIHBvdGVudGlhbGx5Ci0gICAgICogd2l0aCBkaWZmZXJlbnQgdW5kZXJseWluZyByZXByZXNlbnRhdGlvbnMuCi0gICAgICovCi0gICAgcHVibGljIERPTUltcGxlbWVudGF0aW9uIGdldEltcGxlbWVudGF0aW9uKCkgewotICAgICAgICAvLyBDdXJyZW50bHkgaW1wbGVtZW50ZWQgYXMgYSBzaW5nbGV0b24sIHNpbmNlIGl0J3MgaGFyZGNvZGVkCi0gICAgICAgIC8vIGluZm9ybWF0aW9uIGFueXdheS4KLSAgICAgICAgcmV0dXJuIERPTUltcGxlbWVudGF0aW9uSW1wbC5nZXRET01JbXBsZW1lbnRhdGlvbigpOwotICAgIH0KLQotICAgIC8vCi0gICAgLy8gRG9jdW1lbnRUcmF2ZXJzYWwgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBOT04tRE9NIGV4dGVuc2lvbjoKLSAgICAgKiBDcmVhdGUgYW5kIHJldHVybiBhIE5vZGVJdGVyYXRvci4gVGhlIE5vZGVJdGVyYXRvciBpcwotICAgICAqIGFkZGVkIHRvIGEgbGlzdCBvZiBOb2RlSXRlcmF0b3JzIHNvIHRoYXQgaXQgY2FuIGJlCi0gICAgICogcmVtb3ZlZCB0byBmcmVlIHVwIHRoZSBET00gTm9kZXMgaXQgcmVmZXJlbmNlcy4KLSAgICAgKgotICAgICAqIEBwYXJhbSByb290IFRoZSByb290IG9mIHRoZSBpdGVyYXRvci4KLSAgICAgKiBAcGFyYW0gd2hhdFRvU2hvdyBUaGUgd2hhdFRvU2hvdyBtYXNrLgotICAgICAqIEBwYXJhbSBmaWx0ZXIgVGhlIE5vZGVGaWx0ZXIgaW5zdGFsbGVkLiBOdWxsIG1lYW5zIG5vIGZpbHRlci4KLSAgICAgKi8KLSAgICBwdWJsaWMgTm9kZUl0ZXJhdG9yIGNyZWF0ZU5vZGVJdGVyYXRvcihOb2RlIHJvb3QsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hvcnQgd2hhdFRvU2hvdywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOb2RlRmlsdGVyIGZpbHRlcikKLSAgICB7Ci0gICAgICAgIHJldHVybiBjcmVhdGVOb2RlSXRlcmF0b3Iocm9vdCwgd2hhdFRvU2hvdywgZmlsdGVyLCB0cnVlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGUgYW5kIHJldHVybiBhIE5vZGVJdGVyYXRvci4gVGhlIE5vZGVJdGVyYXRvciBpcwotICAgICAqIGFkZGVkIHRvIGEgbGlzdCBvZiBOb2RlSXRlcmF0b3JzIHNvIHRoYXQgaXQgY2FuIGJlCi0gICAgICogcmVtb3ZlZCB0byBmcmVlIHVwIHRoZSBET00gTm9kZXMgaXQgcmVmZXJlbmNlcy4KLSAgICAgKgotICAgICAqIEBwYXJhbSByb290IFRoZSByb290IG9mIHRoZSBpdGVyYXRvci4KLSAgICAgKiBAcGFyYW0gd2hhdFRvU2hvdyBUaGUgd2hhdFRvU2hvdyBtYXNrLgotICAgICAqIEBwYXJhbSBmaWx0ZXIgVGhlIE5vZGVGaWx0ZXIgaW5zdGFsbGVkLiBOdWxsIG1lYW5zIG5vIGZpbHRlci4KLSAgICAgKiBAcGFyYW0gZW50aXR5UmVmZXJlbmNlRXhwYW5zaW9uIHRydWUgdG8gZXhwYW5kIHRoZSBjb250ZW50cyBvZgotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRW50aXR5UmVmZXJlbmNlIG5vZGVzCi0gICAgICogQHNpbmNlIFdELURPTS1MZXZlbC0yLTE5OTkwOTIzCi0gICAgICovCi0gICAgcHVibGljIE5vZGVJdGVyYXRvciBjcmVhdGVOb2RlSXRlcmF0b3IoTm9kZSByb290LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCB3aGF0VG9TaG93LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5vZGVGaWx0ZXIgZmlsdGVyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gZW50aXR5UmVmZXJlbmNlRXhwYW5zaW9uKQotICAgIHsKLQotICAgICAgICBpZiAocm9vdCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICBTdHJpbmcgbXNnID0gRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwgIk5PVF9TVVBQT1JURURfRVJSIiwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUiwgbXNnKTsKLSAgICAgICAgfQotCi0gICAgICAgIE5vZGVJdGVyYXRvciBpdGVyYXRvciA9IG5ldyBOb2RlSXRlcmF0b3JJbXBsKHRoaXMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvb3QsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoYXRUb1Nob3csCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW50aXR5UmVmZXJlbmNlRXhwYW5zaW9uKTsKLSAgICAgICAgaWYgKGl0ZXJhdG9ycyA9PSBudWxsKSB7Ci0gICAgICAgICAgICBpdGVyYXRvcnMgPSBuZXcgQXJyYXlMaXN0PD4oKTsKLSAgICAgICAgfQotCi0gICAgICAgIGl0ZXJhdG9ycy5hZGQoaXRlcmF0b3IpOwotCi0gICAgICAgIHJldHVybiBpdGVyYXRvcjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBOT04tRE9NIGV4dGVuc2lvbjoKLSAgICAgKiBDcmVhdGUgYW5kIHJldHVybiBhIFRyZWVXYWxrZXIuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcm9vdCBUaGUgcm9vdCBvZiB0aGUgaXRlcmF0b3IuCi0gICAgICogQHBhcmFtIHdoYXRUb1Nob3cgVGhlIHdoYXRUb1Nob3cgbWFzay4KLSAgICAgKiBAcGFyYW0gZmlsdGVyIFRoZSBOb2RlRmlsdGVyIGluc3RhbGxlZC4gTnVsbCBtZWFucyBubyBmaWx0ZXIuCi0gICAgICovCi0gICAgcHVibGljIFRyZWVXYWxrZXIgY3JlYXRlVHJlZVdhbGtlcihOb2RlIHJvb3QsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaG9ydCB3aGF0VG9TaG93LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTm9kZUZpbHRlciBmaWx0ZXIpCi0gICAgewotICAgICAgICByZXR1cm4gY3JlYXRlVHJlZVdhbGtlcihyb290LCB3aGF0VG9TaG93LCBmaWx0ZXIsIHRydWUpOwotICAgIH0KLSAgICAvKioKLSAgICAgKiBDcmVhdGUgYW5kIHJldHVybiBhIFRyZWVXYWxrZXIuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcm9vdCBUaGUgcm9vdCBvZiB0aGUgaXRlcmF0b3IuCi0gICAgICogQHBhcmFtIHdoYXRUb1Nob3cgVGhlIHdoYXRUb1Nob3cgbWFzay4KLSAgICAgKiBAcGFyYW0gZmlsdGVyIFRoZSBOb2RlRmlsdGVyIGluc3RhbGxlZC4gTnVsbCBtZWFucyBubyBmaWx0ZXIuCi0gICAgICogQHBhcmFtIGVudGl0eVJlZmVyZW5jZUV4cGFuc2lvbiB0cnVlIHRvIGV4cGFuZCB0aGUgY29udGVudHMgb2YKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVudGl0eVJlZmVyZW5jZSBub2RlcwotICAgICAqIEBzaW5jZSBXRC1ET00tTGV2ZWwtMi0xOTk5MDkyMwotICAgICAqLwotICAgIHB1YmxpYyBUcmVlV2Fsa2VyIGNyZWF0ZVRyZWVXYWxrZXIoTm9kZSByb290LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHdoYXRUb1Nob3csCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOb2RlRmlsdGVyIGZpbHRlciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gZW50aXR5UmVmZXJlbmNlRXhwYW5zaW9uKQotICAgIHsKLSAgICAgICAgaWYgKHJvb3QgPT0gbnVsbCkgewotICAgICAgICAgICAgU3RyaW5nIG1zZyA9IERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sICJOT1RfU1VQUE9SVEVEX0VSUiIsIG51bGwpOwotICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIsIG1zZyk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG5ldyBUcmVlV2Fsa2VySW1wbChyb290LCB3aGF0VG9TaG93LCBmaWx0ZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW50aXR5UmVmZXJlbmNlRXhwYW5zaW9uKTsKLSAgICB9Ci0KLSAgICAvLwotICAgIC8vIE5vdCBET00gTGV2ZWwgMi4gU3VwcG9ydCBEb2N1bWVudFRyYXZlcnNhbCBtZXRob2RzLgotICAgIC8vCi0KLSAgICAvKiogVGhpcyBpcyBub3QgY2FsbGVkIGJ5IHRoZSBkZXZlbG9wZXIgY2xpZW50LiBUaGUKLSAgICAgKiAgZGV2ZWxvcGVyIGNsaWVudCB1c2VzIHRoZSBkZXRhY2goKSBmdW5jdGlvbiBvbiB0aGUKLSAgICAgKiAgTm9kZUl0ZXJhdG9yIGl0c2VsZi4gPHA+Ci0gICAgICoKLSAgICAgKiAgVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgZnJvbSB0aGUgTm9kZUl0ZXJhdG9yI2RldGFjaCgpLgotICAgICAqLwotICAgICB2b2lkIHJlbW92ZU5vZGVJdGVyYXRvcihOb2RlSXRlcmF0b3Igbm9kZUl0ZXJhdG9yKSB7Ci0KLSAgICAgICAgaWYgKG5vZGVJdGVyYXRvciA9PSBudWxsKSByZXR1cm47Ci0gICAgICAgIGlmIChpdGVyYXRvcnMgPT0gbnVsbCkgcmV0dXJuOwotCi0gICAgICAgIGl0ZXJhdG9ycy5yZW1vdmUobm9kZUl0ZXJhdG9yKTsKLSAgICB9Ci0KLSAgICAvLwotICAgIC8vIERvY3VtZW50UmFuZ2UgbWV0aG9kcwotICAgIC8vCi0gICAgLyoqCi0gICAgICovCi0gICAgcHVibGljIFJhbmdlIGNyZWF0ZVJhbmdlKCkgewotCi0gICAgICAgIGlmIChyYW5nZXMgPT0gbnVsbCkgewotICAgICAgICAgICAgcmFuZ2VzID0gbmV3IEFycmF5TGlzdDw+KCk7Ci0gICAgICAgIH0KLQotICAgICAgICBSYW5nZSByYW5nZSA9IG5ldyBSYW5nZUltcGwodGhpcyk7Ci0gICAgICAgIHJhbmdlcy5hZGQocmFuZ2UpOwotCi0gICAgICAgIHJldHVybiByYW5nZTsKLQotICAgIH0KLQotICAgIC8qKiBOb3QgYSBjbGllbnQgZnVuY3Rpb24uIENhbGxlZCBieSBSYW5nZS5kZXRhY2goKSwKLSAgICAgKiAgc28gYSBSYW5nZSBjYW4gcmVtb3ZlIGl0c2VsZiBmcm9tIHRoZSBsaXN0IG9mCi0gICAgICogIFJhbmdlcy4KLSAgICAgKi8KLSAgICB2b2lkIHJlbW92ZVJhbmdlKFJhbmdlIHJhbmdlKSB7Ci0KLSAgICAgICAgaWYgKHJhbmdlID09IG51bGwpIHJldHVybjsKLSAgICAgICAgaWYgKHJhbmdlcyA9PSBudWxsKSByZXR1cm47Ci0KLSAgICAgICAgcmFuZ2VzLnJlbW92ZShyYW5nZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQSBtZXRob2QgdG8gYmUgY2FsbGVkIHdoZW4gc29tZSB0ZXh0IHdhcyBjaGFuZ2VkIGluIGEgdGV4dCBub2RlLAotICAgICAqIHNvIHRoYXQgbGl2ZSBvYmplY3RzIGNhbiBiZSBub3RpZmllZC4KLSAgICAgKi8KLSAgICB2b2lkIHJlcGxhY2VkVGV4dChOb2RlSW1wbCBub2RlKSB7Ci0gICAgICAgIC8vIG5vdGlmeSByYW5nZXMKLSAgICAgICAgaWYgKHJhbmdlcyAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpbnQgc2l6ZSA9IHJhbmdlcy5zaXplKCk7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSAhPSBzaXplOyBpKyspIHsKLSAgICAgICAgICAgICAgICAoKFJhbmdlSW1wbClyYW5nZXMuZ2V0KGkpKS5yZWNlaXZlUmVwbGFjZWRUZXh0KG5vZGUpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQSBtZXRob2QgdG8gYmUgY2FsbGVkIHdoZW4gc29tZSB0ZXh0IHdhcyBkZWxldGVkIGZyb20gYSB0ZXh0IG5vZGUsCi0gICAgICogc28gdGhhdCBsaXZlIG9iamVjdHMgY2FuIGJlIG5vdGlmaWVkLgotICAgICAqLwotICAgIHZvaWQgZGVsZXRlZFRleHQoTm9kZUltcGwgbm9kZSwgaW50IG9mZnNldCwgaW50IGNvdW50KSB7Ci0gICAgICAgIC8vIG5vdGlmeSByYW5nZXMKLSAgICAgICAgaWYgKHJhbmdlcyAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpbnQgc2l6ZSA9IHJhbmdlcy5zaXplKCk7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSAhPSBzaXplOyBpKyspIHsKLSAgICAgICAgICAgICAgICAoKFJhbmdlSW1wbClyYW5nZXMuZ2V0KGkpKS5yZWNlaXZlRGVsZXRlZFRleHQobm9kZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQsIGNvdW50KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEEgbWV0aG9kIHRvIGJlIGNhbGxlZCB3aGVuIHNvbWUgdGV4dCB3YXMgaW5zZXJ0ZWQgaW50byBhIHRleHQgbm9kZSwKLSAgICAgKiBzbyB0aGF0IGxpdmUgb2JqZWN0cyBjYW4gYmUgbm90aWZpZWQuCi0gICAgICovCi0gICAgdm9pZCBpbnNlcnRlZFRleHQoTm9kZUltcGwgbm9kZSwgaW50IG9mZnNldCwgaW50IGNvdW50KSB7Ci0gICAgICAgIC8vIG5vdGlmeSByYW5nZXMKLSAgICAgICAgaWYgKHJhbmdlcyAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpbnQgc2l6ZSA9IHJhbmdlcy5zaXplKCk7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSAhPSBzaXplOyBpKyspIHsKLSAgICAgICAgICAgICAgICAoKFJhbmdlSW1wbClyYW5nZXMuZ2V0KGkpKS5yZWNlaXZlSW5zZXJ0ZWRUZXh0KG5vZGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0LCBjb3VudCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBIG1ldGhvZCB0byBiZSBjYWxsZWQgd2hlbiBhIHRleHQgbm9kZSBoYXMgYmVlbiBzcGxpdCwKLSAgICAgKiBzbyB0aGF0IGxpdmUgb2JqZWN0cyBjYW4gYmUgbm90aWZpZWQuCi0gICAgICovCi0gICAgdm9pZCBzcGxpdERhdGEoTm9kZSBub2RlLCBOb2RlIG5ld05vZGUsIGludCBvZmZzZXQpIHsKLSAgICAgICAgLy8gbm90aWZ5IHJhbmdlcwotICAgICAgICBpZiAocmFuZ2VzICE9IG51bGwpIHsKLSAgICAgICAgICAgIGludCBzaXplID0gcmFuZ2VzLnNpemUoKTsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpICE9IHNpemU7IGkrKykgewotICAgICAgICAgICAgICAgICgoUmFuZ2VJbXBsKXJhbmdlcy5nZXQoaSkpLnJlY2VpdmVTcGxpdERhdGEobm9kZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3Tm9kZSwgb2Zmc2V0KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIC8vCi0gICAgLy8gRG9jdW1lbnRFdmVudCBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIEludHJvZHVjZWQgaW4gRE9NIExldmVsIDIuIE9wdGlvbmFsLiA8cD4KLSAgICAgKiBDcmVhdGUgYW5kIHJldHVybiBFdmVudCBvYmplY3RzLgotICAgICAqCi0gICAgICogQHBhcmFtIHR5cGUgVGhlIGV2ZW50VHlwZSBwYXJhbWV0ZXIgc3BlY2lmaWVzIHRoZSB0eXBlIG9mIEV2ZW50Ci0gICAgICogaW50ZXJmYWNlIHRvIGJlIGNyZWF0ZWQuICBJZiB0aGUgRXZlbnQgaW50ZXJmYWNlIHNwZWNpZmllZCBpcyBzdXBwb3J0ZWQKLSAgICAgKiBieSB0aGUgaW1wbGVtZW50YXRpb24gdGhpcyBtZXRob2Qgd2lsbCByZXR1cm4gYSBuZXcgRXZlbnQgb2YgdGhlCi0gICAgICogaW50ZXJmYWNlIHR5cGUgcmVxdWVzdGVkLiBJZiB0aGUgRXZlbnQgaXMgdG8gYmUgZGlzcGF0Y2hlZCB2aWEgdGhlCi0gICAgICogZGlzcGF0Y2hFdmVudCBtZXRob2QgdGhlIGFwcHJvcHJpYXRlIGV2ZW50IGluaXQgbWV0aG9kIG11c3QgYmUgY2FsbGVkCi0gICAgICogYWZ0ZXIgY3JlYXRpb24gaW4gb3JkZXIgdG8gaW5pdGlhbGl6ZSB0aGUgRXZlbnQncyB2YWx1ZXMuICBBcyBhbgotICAgICAqIGV4YW1wbGUsIGEgdXNlciB3aXNoaW5nIHRvIHN5bnRoZXNpemUgc29tZSBraW5kIG9mIEV2ZW50IHdvdWxkIGNhbGwKLSAgICAgKiBjcmVhdGVFdmVudCB3aXRoIHRoZSBwYXJhbWV0ZXIgIkV2ZW50cyIuIFRoZSBpbml0RXZlbnQgbWV0aG9kIGNvdWxkIHRoZW4KLSAgICAgKiBiZSBjYWxsZWQgb24gdGhlIG5ld2x5IGNyZWF0ZWQgRXZlbnQgdG8gc2V0IHRoZSBzcGVjaWZpYyB0eXBlIG9mIEV2ZW50Ci0gICAgICogdG8gYmUgZGlzcGF0Y2hlZCBhbmQgc2V0IGl0cyBjb250ZXh0IGluZm9ybWF0aW9uLgotICAgICAqIEByZXR1cm4gTmV3bHkgY3JlYXRlZCBFdmVudAotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uIE5PVF9TVVBQT1JURURfRVJSOiBSYWlzZWQgaWYgdGhlIGltcGxlbWVudGF0aW9uCi0gICAgICogZG9lcyBub3Qgc3VwcG9ydCB0aGUgdHlwZSBvZiBFdmVudCBpbnRlcmZhY2UgcmVxdWVzdGVkCi0gICAgICogQHNpbmNlIFdELURPTS1MZXZlbC0yLTE5OTkwOTIzCi0gICAgICovCi0gICAgcHVibGljIEV2ZW50IGNyZWF0ZUV2ZW50KFN0cmluZyB0eXBlKQotICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKLSAgICAgICAgICAgIGlmICh0eXBlLmVxdWFsc0lnbm9yZUNhc2UoIkV2ZW50cyIpIHx8ICJFdmVudCIuZXF1YWxzKHR5cGUpKQotICAgICAgICAgICAgICAgIHJldHVybiBuZXcgRXZlbnRJbXBsKCk7Ci0gICAgICAgICAgICBpZiAodHlwZS5lcXVhbHNJZ25vcmVDYXNlKCJNdXRhdGlvbkV2ZW50cyIpIHx8Ci0gICAgICAgICAgICAgICAgIk11dGF0aW9uRXZlbnQiLmVxdWFscyh0eXBlKSkKLSAgICAgICAgICAgICAgICByZXR1cm4gbmV3IE11dGF0aW9uRXZlbnRJbXBsKCk7Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIFN0cmluZyBtc2cgPSBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiTk9UX1NVUFBPUlRFRF9FUlIiLCBudWxsKTsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUiwgbXNnKTsKLSAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXRzIHdoZXRoZXIgdGhlIERPTSBpbXBsZW1lbnRhdGlvbiBnZW5lcmF0ZXMgbXV0YXRpb24gZXZlbnRzCi0gICAgICogdXBvbiBvcGVyYXRpb25zLgotICAgICAqLwotICAgIHZvaWQgc2V0TXV0YXRpb25FdmVudHMoYm9vbGVhbiBzZXQpIHsKLSAgICAgICAgbXV0YXRpb25FdmVudHMgPSBzZXQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBET00gaW1wbGVtZW50YXRpb24gZ2VuZXJhdGVzIG11dGF0aW9uIGV2ZW50cy4KLSAgICAgKi8KLSAgICBib29sZWFuIGdldE11dGF0aW9uRXZlbnRzKCkgewotICAgICAgICByZXR1cm4gbXV0YXRpb25FdmVudHM7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU3RvcmUgZXZlbnQgbGlzdGVuZXIgcmVnaXN0ZXJlZCBvbiBhIGdpdmVuIG5vZGUKLSAgICAgKiBUaGlzIGlzIGFub3RoZXIgcGxhY2Ugd2hlcmUgd2UgY291bGQgdXNlIHdlYWsgcmVmZXJlbmNlcyEgSW5kZWVkLCB0aGUKLSAgICAgKiBub2RlIGhlcmUgd29uJ3QgYmUgR0MnZWQgYXMgbG9uZyBhcyBzb21lIGxpc3RlbmVyIGlzIHJlZ2lzdGVyZWQgb24gaXQsCi0gICAgICogc2luY2UgdGhlIGV2ZW50c0xpc3RlbmVycyB0YWJsZSB3aWxsIGhhdmUgYSByZWZlcmVuY2UgdG8gdGhlIG5vZGUuCi0gICAgICovCi0gICAgcHJpdmF0ZSB2b2lkIHNldEV2ZW50TGlzdGVuZXJzKE5vZGVJbXBsIG4sIExpc3Q8TEVudHJ5PiBsaXN0ZW5lcnMpIHsKLSAgICAgICAgaWYgKGV2ZW50TGlzdGVuZXJzID09IG51bGwpIHsKLSAgICAgICAgICAgIGV2ZW50TGlzdGVuZXJzID0gbmV3IEhhc2hNYXA8PigpOwotICAgICAgICB9Ci0gICAgICAgIGlmIChsaXN0ZW5lcnMgPT0gbnVsbCkgewotICAgICAgICAgICAgZXZlbnRMaXN0ZW5lcnMucmVtb3ZlKG4pOwotICAgICAgICAgICAgaWYgKGV2ZW50TGlzdGVuZXJzLmlzRW1wdHkoKSkgewotICAgICAgICAgICAgICAgIC8vIHN0b3AgZmlyaW5nIGV2ZW50cyB3aGVuIHRoZXJlIGlzbid0IGFueSBsaXN0ZW5lcgotICAgICAgICAgICAgICAgIG11dGF0aW9uRXZlbnRzID0gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBldmVudExpc3RlbmVycy5wdXQobiwgbGlzdGVuZXJzKTsKLSAgICAgICAgICAgIC8vIHR1cm4gbXV0YXRpb24gZXZlbnRzIG9uCi0gICAgICAgICAgICBtdXRhdGlvbkV2ZW50cyA9IHRydWU7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXRyZWl2ZSBldmVudCBsaXN0ZW5lciByZWdpc3RlcmVkIG9uIGEgZ2l2ZW4gbm9kZQotICAgICAqLwotICAgIHByaXZhdGUgTGlzdDxMRW50cnk+IGdldEV2ZW50TGlzdGVuZXJzKE5vZGVJbXBsIG4pIHsKLSAgICAgICAgaWYgKGV2ZW50TGlzdGVuZXJzID09IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBldmVudExpc3RlbmVycy5nZXQobik7Ci0gICAgfQotCi0gICAgLy8KLSAgICAvLyBFdmVudFRhcmdldCBzdXBwb3J0IChwdWJsaWMgYW5kIGludGVybmFsKQotICAgIC8vCi0KLSAgICAvLwotICAgIC8vIENvbnN0YW50cwotICAgIC8vCi0KLSAgICAvKgotICAgICAqIE5PTi1ET00gSU5URVJOQUw6IENsYXNzIExFbnRyeSBpcyBqdXN0IGEgc3RydWN0IHVzZWQgdG8gcmVwcmVzZW50Ci0gICAgICogZXZlbnQgbGlzdGVuZXJzIHJlZ2lzdGVyZWQgd2l0aCB0aGlzIG5vZGUuIENvcGllcyBvZiB0aGlzIG9iamVjdAotICAgICAqIGFyZSBodW5nIGZyb20gdGhlIG5vZGVMaXN0ZW5lcnMgVmVjdG9yLgotICAgICAqIDxwPgotICAgICAqIEkgY29uc2lkZXJlZCB1c2luZyB0d28gdmVjdG9ycyAtLSBvbmUgZm9yIGNhcHR1cmUsCi0gICAgICogb25lIGZvciBidWJibGUgLS0gYnV0IGRlY2lkZWQgdGhhdCBzaW5jZSB0aGUgbGlzdCBvZiBsaXN0ZW5lcnMKLSAgICAgKiBpcyBwcm9iYWJseSBzaG9ydCBpbiBtb3N0IGNhc2VzLCBpdCBtaWdodCBub3QgYmUgd29ydGggc3BlbmRpbmcKLSAgICAgKiB0aGUgc3BhY2UuICoqKioqIFJFVklTSVQgV0hFTiBXRSBIQVZFIE1PUkUgRVhQRVJJRU5DRS4KLSAgICAgKi8KLSAgICBjbGFzcyBMRW50cnkgaW1wbGVtZW50cyBTZXJpYWxpemFibGUgewotCi0gICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC04NDI2NzU3MDU5NDkyNDIxNjMxTDsKLSAgICAgICAgU3RyaW5nIHR5cGU7Ci0gICAgICAgIEV2ZW50TGlzdGVuZXIgbGlzdGVuZXI7Ci0gICAgICAgIGJvb2xlYW4gdXNlQ2FwdHVyZTsKLQotICAgICAgICAvKiogTk9OLURPTSBJTlRFUk5BTDogQ29uc3RydWN0b3IgZm9yIExpc3RlbmVyIGxpc3QgRW50cnkKLSAgICAgICAgICogQHBhcmFtIHR5cGUgRXZlbnQgbmFtZSAoTk9UIGV2ZW50IGdyb3VwISkgdG8gbGlzdGVuIGZvci4KLSAgICAgICAgICogQHBhcmFtIGxpc3RlbmVyIFdobyBnZXRzIGNhbGxlZCB3aGVuIGV2ZW50IGlzIGRpc3BhdGNoZWQKLSAgICAgICAgICogQHBhcmFtIHVzZUNhcHR1ZSBUcnVlIGlmZiBsaXN0ZW5lciBpcyByZWdpc3RlcmVkIG9uCi0gICAgICAgICAqICBjYXB0dXJpbmcgcGhhc2UgcmF0aGVyIHRoYW4gYXQtdGFyZ2V0IG9yIGJ1YmJsaW5nCi0gICAgICAgICAqLwotICAgICAgICBMRW50cnkoU3RyaW5nIHR5cGUsIEV2ZW50TGlzdGVuZXIgbGlzdGVuZXIsIGJvb2xlYW4gdXNlQ2FwdHVyZSkKLSAgICAgICAgewotICAgICAgICAgICAgdGhpcy50eXBlID0gdHlwZTsKLSAgICAgICAgICAgIHRoaXMubGlzdGVuZXIgPSBsaXN0ZW5lcjsKLSAgICAgICAgICAgIHRoaXMudXNlQ2FwdHVyZSA9IHVzZUNhcHR1cmU7Ci0gICAgICAgIH0KLQotICAgIH0gLy8gTEVudHJ5Ci0KLSAgICAvKioKLSAgICAgKiBJbnRyb2R1Y2VkIGluIERPTSBMZXZlbCAyLiA8cD4gUmVnaXN0ZXIgYW4gZXZlbnQgbGlzdGVuZXIgd2l0aCB0aGlzCi0gICAgICogTm9kZS4gQSBsaXN0ZW5lciBtYXkgYmUgaW5kZXBlbmRlbnRseSByZWdpc3RlcmVkIGFzIGJvdGggQ2FwdHVyaW5nIGFuZAotICAgICAqIEJ1YmJsaW5nLCBidXQgbWF5IG9ubHkgYmUgcmVnaXN0ZXJlZCBvbmNlIHBlciByb2xlOyByZWR1bmRhbnQKLSAgICAgKiByZWdpc3RyYXRpb25zIGFyZSBpZ25vcmVkLgotICAgICAqIEBwYXJhbSBub2RlIG5vZGUgdG8gYWRkIGxpc3RlbmVyIHRvCi0gICAgICogQHBhcmFtIHR5cGUgRXZlbnQgbmFtZSAoTk9UIGV2ZW50IGdyb3VwISkgdG8gbGlzdGVuIGZvci4KLSAgICAgKiBAcGFyYW0gbGlzdGVuZXIgV2hvIGdldHMgY2FsbGVkIHdoZW4gZXZlbnQgaXMgZGlzcGF0Y2hlZAotICAgICAqIEBwYXJhbSB1c2VDYXB0dXJlIFRydWUgaWZmIGxpc3RlbmVyIGlzIHJlZ2lzdGVyZWQgb24KLSAgICAgKiAgY2FwdHVyaW5nIHBoYXNlIHJhdGhlciB0aGFuIGF0LXRhcmdldCBvciBidWJibGluZwotICAgICAqLwotICAgIEBPdmVycmlkZQotICAgIHByb3RlY3RlZCB2b2lkIGFkZEV2ZW50TGlzdGVuZXIoTm9kZUltcGwgbm9kZSwgU3RyaW5nIHR5cGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFdmVudExpc3RlbmVyIGxpc3RlbmVyLCBib29sZWFuIHVzZUNhcHR1cmUpCi0gICAgewotICAgICAgICAvLyBXZSBjYW4ndCBkaXNwYXRjaCB0byBibGFuayB0eXBlLW5hbWUsIGFuZCBvZiBjb3Vyc2Ugd2UgbmVlZAotICAgICAgICAvLyBhIGxpc3RlbmVyIHRvIGRpc3BhdGNoIHRvCi0gICAgICAgIGlmICh0eXBlID09IG51bGwgfHwgdHlwZS5lcXVhbHMoIiIpIHx8IGxpc3RlbmVyID09IG51bGwpCi0gICAgICAgICAgICByZXR1cm47Ci0KLSAgICAgICAgLy8gRWFjaCBsaXN0ZW5lciBtYXkgYmUgcmVnaXN0ZXJlZCBvbmx5IG9uY2UgcGVyIHR5cGUgcGVyIHBoYXNlLgotICAgICAgICAvLyBTaW1wbGVzdCB3YXkgdG8gY29kZSB0aGF0IGlzIHRvIHphcCB0aGUgcHJldmlvdXMgZW50cnksIGlmIGFueS4KLSAgICAgICAgcmVtb3ZlRXZlbnRMaXN0ZW5lcihub2RlLCB0eXBlLCBsaXN0ZW5lciwgdXNlQ2FwdHVyZSk7Ci0KLSAgICAgICAgTGlzdDxMRW50cnk+IG5vZGVMaXN0ZW5lcnMgPSBnZXRFdmVudExpc3RlbmVycyhub2RlKTsKLSAgICAgICAgaWYobm9kZUxpc3RlbmVycyA9PSBudWxsKSB7Ci0gICAgICAgICAgICBub2RlTGlzdGVuZXJzID0gbmV3IEFycmF5TGlzdDw+KCk7Ci0gICAgICAgICAgICBzZXRFdmVudExpc3RlbmVycyhub2RlLCBub2RlTGlzdGVuZXJzKTsKLSAgICAgICAgfQotICAgICAgICBub2RlTGlzdGVuZXJzLmFkZChuZXcgTEVudHJ5KHR5cGUsIGxpc3RlbmVyLCB1c2VDYXB0dXJlKSk7Ci0KLSAgICAgICAgLy8gUmVjb3JkIGFjdGl2ZSBsaXN0ZW5lcgotICAgICAgICBMQ291bnQgbGMgPSBMQ291bnQubG9va3VwKHR5cGUpOwotICAgICAgICBpZiAodXNlQ2FwdHVyZSkgewotICAgICAgICAgICAgKytsYy5jYXB0dXJlczsKLSAgICAgICAgICAgICsrbGMudG90YWw7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICArK2xjLmJ1YmJsZXM7Ci0gICAgICAgICAgICArK2xjLnRvdGFsOwotICAgICAgICB9Ci0KLSAgICB9IC8vIGFkZEV2ZW50TGlzdGVuZXIoTm9kZUltcGwsU3RyaW5nLEV2ZW50TGlzdGVuZXIsYm9vbGVhbikgOnZvaWQKLQotICAgIC8qKgotICAgICAqIEludHJvZHVjZWQgaW4gRE9NIExldmVsIDIuIDxwPiBEZXJlZ2lzdGVyIGFuIGV2ZW50IGxpc3RlbmVyIHByZXZpb3VzbHkKLSAgICAgKiByZWdpc3RlcmVkIHdpdGggdGhpcyBOb2RlLiAgQSBsaXN0ZW5lciBtdXN0IGJlIGluZGVwZW5kZW50bHkgcmVtb3ZlZAotICAgICAqIGZyb20gdGhlIENhcHR1cmluZyBhbmQgQnViYmxpbmcgcm9sZXMuIFJlZHVuZGFudCByZW1vdmFscyAob2YgbGlzdGVuZXJzCi0gICAgICogbm90IGN1cnJlbnRseSByZWdpc3RlcmVkIGZvciB0aGlzIHJvbGUpIGFyZSBpZ25vcmVkLgotICAgICAqIEBwYXJhbSBub2RlIG5vZGUgdG8gcmVtb3ZlIGxpc3RlbmVyIGZyb20KLSAgICAgKiBAcGFyYW0gdHlwZSBFdmVudCBuYW1lIChOT1QgZXZlbnQgZ3JvdXAhKSB0byBsaXN0ZW4gZm9yLgotICAgICAqIEBwYXJhbSBsaXN0ZW5lciBXaG8gZ2V0cyBjYWxsZWQgd2hlbiBldmVudCBpcyBkaXNwYXRjaGVkCi0gICAgICogQHBhcmFtIHVzZUNhcHR1cmUgVHJ1ZSBpZmYgbGlzdGVuZXIgaXMgcmVnaXN0ZXJlZCBvbgotICAgICAqICBjYXB0dXJpbmcgcGhhc2UgcmF0aGVyIHRoYW4gYXQtdGFyZ2V0IG9yIGJ1YmJsaW5nCi0gICAgICovCi0gICAgQE92ZXJyaWRlCi0gICAgcHJvdGVjdGVkIHZvaWQgcmVtb3ZlRXZlbnRMaXN0ZW5lcihOb2RlSW1wbCBub2RlLCBTdHJpbmcgdHlwZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEV2ZW50TGlzdGVuZXIgbGlzdGVuZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIHVzZUNhcHR1cmUpCi0gICAgewotICAgICAgICAvLyBJZiB0aGlzIGNvdWxkbid0IGJlIGEgdmFsaWQgbGlzdGVuZXIgcmVnaXN0cmF0aW9uLCBpZ25vcmUgcmVxdWVzdAotICAgICAgICBpZiAodHlwZSA9PSBudWxsIHx8IHR5cGUuZXF1YWxzKCIiKSB8fCBsaXN0ZW5lciA9PSBudWxsKQotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICBMaXN0PExFbnRyeT4gbm9kZUxpc3RlbmVycyA9IGdldEV2ZW50TGlzdGVuZXJzKG5vZGUpOwotICAgICAgICBpZiAobm9kZUxpc3RlbmVycyA9PSBudWxsKQotICAgICAgICAgICAgcmV0dXJuOwotCi0gICAgICAgIC8vIE5vdGUgdGhhdCBhZGRMaXN0ZW5lciBoYXMgcHJldmlvdXNseSBlbnN1cmVkIHRoYXQKLSAgICAgICAgLy8gZWFjaCBsaXN0ZW5lciBtYXkgYmUgcmVnaXN0ZXJlZCBvbmx5IG9uY2UgcGVyIHR5cGUgcGVyIHBoYXNlLgotICAgICAgICAvLyBjb3VudC1kb3duIGlzIE9LIGZvciBkZWxldGlvbnMhCi0gICAgICAgIGZvciAoaW50IGkgPSBub2RlTGlzdGVuZXJzLnNpemUoKSAtIDE7IGkgPj0gMDsgLS1pKSB7Ci0gICAgICAgICAgICBMRW50cnkgbGUgPSBub2RlTGlzdGVuZXJzLmdldChpKTsKLSAgICAgICAgICAgIGlmIChsZS51c2VDYXB0dXJlID09IHVzZUNhcHR1cmUgJiYgbGUubGlzdGVuZXIgPT0gbGlzdGVuZXIgJiYKLSAgICAgICAgICAgICAgICBsZS50eXBlLmVxdWFscyh0eXBlKSkgewotICAgICAgICAgICAgICAgIG5vZGVMaXN0ZW5lcnMucmVtb3ZlKGkpOwotICAgICAgICAgICAgICAgIC8vIFN0b3JhZ2UgbWFuYWdlbWVudDogRGlzY2FyZCBlbXB0eSBsaXN0ZW5lciBsaXN0cwotICAgICAgICAgICAgICAgIGlmIChub2RlTGlzdGVuZXJzLmlzRW1wdHkoKSkKLSAgICAgICAgICAgICAgICAgICAgc2V0RXZlbnRMaXN0ZW5lcnMobm9kZSwgbnVsbCk7Ci0KLSAgICAgICAgICAgICAgICAvLyBSZW1vdmUgYWN0aXZlIGxpc3RlbmVyCi0gICAgICAgICAgICAgICAgTENvdW50IGxjID0gTENvdW50Lmxvb2t1cCh0eXBlKTsKLSAgICAgICAgICAgICAgICBpZiAodXNlQ2FwdHVyZSkgewotICAgICAgICAgICAgICAgICAgICAtLWxjLmNhcHR1cmVzOwotICAgICAgICAgICAgICAgICAgICAtLWxjLnRvdGFsOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgLS1sYy5idWJibGVzOwotICAgICAgICAgICAgICAgICAgICAtLWxjLnRvdGFsOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIGJyZWFrOyAgLy8gRm91bmQgaXQ7IG5vIG5lZWQgdG8gbG9vcCBmYXJ0aGVyLgotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfSAvLyByZW1vdmVFdmVudExpc3RlbmVyKE5vZGVJbXBsLFN0cmluZyxFdmVudExpc3RlbmVyLGJvb2xlYW4pIDp2b2lkCi0KLSAgICBAT3ZlcnJpZGUKLSAgICBwcm90ZWN0ZWQgdm9pZCBjb3B5RXZlbnRMaXN0ZW5lcnMoTm9kZUltcGwgc3JjLCBOb2RlSW1wbCB0Z3QpIHsKLSAgICAgICAgTGlzdDxMRW50cnk+IG5vZGVMaXN0ZW5lcnMgPSBnZXRFdmVudExpc3RlbmVycyhzcmMpOwotICAgICAgICBpZiAobm9kZUxpc3RlbmVycyA9PSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLSAgICAgICAgc2V0RXZlbnRMaXN0ZW5lcnModGd0LCBuZXcgQXJyYXlMaXN0PD4obm9kZUxpc3RlbmVycykpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEludHJvZHVjZWQgaW4gRE9NIExldmVsIDIuIDxwPgotICAgICAqIERpc3RyaWJ1dGlvbiBlbmdpbmUgZm9yIERPTSBMZXZlbCAyIEV2ZW50cy4KLSAgICAgKiA8cD4KLSAgICAgKiBFdmVudCBwcm9wYWdhdGlvbiBydW5zIGFzIGZvbGxvd3M6Ci0gICAgICogPG9sPgotICAgICAqIDxsaT5FdmVudCBpcyBkaXNwYXRjaGVkIHRvIGEgcGFydGljdWxhciB0YXJnZXQgbm9kZSwgd2hpY2ggaW52b2tlcwotICAgICAqICAgdGhpcyBjb2RlLiBOb3RlIHRoYXQgdGhlIGV2ZW50J3Mgc3RvcFByb3BhZ2F0aW9uIGZsYWcgaXMKLSAgICAgKiAgIGNsZWFyZWQgd2hlbiBkaXNwYXRjaCBiZWdpbnM7IHRoZXJlYWZ0ZXIsIGlmIGl0IGhhcwotICAgICAqICAgYmVlbiBzZXQgYmVmb3JlIHByb2Nlc3Npbmcgb2YgYSBub2RlIGNvbW1lbmNlcywgd2UgaW5zdGVhZAotICAgICAqICAgaW1tZWRpYXRlbHkgYWR2YW5jZSB0byB0aGUgREVGQVVMVCBwaGFzZS4KLSAgICAgKiA8bGk+VGhlIG5vZGUncyBhbmNlc3RvcnMgYXJlIGVzdGFibGlzaGVkIGFzIGRlc3RpbmF0aW9ucyBmb3IgZXZlbnRzLgotICAgICAqICAgRm9yIGNhcHR1cmUgYW5kIGJ1YmJsZSBwdXJwb3Nlcywgbm9kZSBhbmNlc3RyeSBpcyBkZXRlcm1pbmVkIGF0Ci0gICAgICogICB0aGUgdGltZSBkaXNwYXRjaCBzdGFydHMuIElmIGFuIGV2ZW50IGhhbmRsZXIgYWx0ZXJzIHRoZSBkb2N1bWVudAotICAgICAqICAgdHJlZSwgdGhhdCBkb2VzIG5vdCBjaGFuZ2Ugd2hpY2ggbm9kZXMgd2lsbCBiZSBpbmZvcm1lZCBvZiB0aGUgZXZlbnQuCi0gICAgICogPGxpPkNBUFRVUklOR19QSEFTRTogQW5jZXN0b3JzIGFyZSBzY2FubmVkLCByb290IHRvIHRhcmdldCwgZm9yCi0gICAgICogICBDYXB0dXJpbmcgbGlzdGVuZXJzLiBJZiBmb3VuZCwgdGhleSBhcmUgaW52b2tlZCAoc2VlIGJlbG93KS4KLSAgICAgKiA8bGk+QVRfVEFSR0VUOgotICAgICAqICAgRXZlbnQgaXMgZGlzcGF0Y2hlZCB0byBOT04tQ0FQVFVSSU5HIGxpc3RlbmVycyBvbiB0aGUKLSAgICAgKiAgIHRhcmdldCBub2RlLiBOb3RlIHRoYXQgY2FwdHVyaW5nIGxpc3RlbmVycyBvbiB0aGlzIG5vZGUgYXJlIF9ub3RfCi0gICAgICogICBpbnZva2VkLgotICAgICAqIDxsaT5CVUJCTElOR19QSEFTRTogQW5jZXN0b3JzIGFyZSBzY2FubmVkLCB0YXJnZXQgdG8gcm9vdCwgZm9yCi0gICAgICogICBub24tY2FwdHVyaW5nIGxpc3RlbmVycy4KLSAgICAgKiA8bGk+RGVmYXVsdCBwcm9jZXNzaW5nOiBTb21lIERPTXMgaGF2ZSBkZWZhdWx0IGJlaGF2aW9ycyBib3VuZCB0bwotICAgICAqICAgc3BlY2lmaWMgbm9kZXMuIElmIHRoaXMgRE9NIGRvZXMsIGFuZCBpZiB0aGUgZXZlbnQncyBwcmV2ZW50RGVmYXVsdAotICAgICAqICAgZmxhZyBoYXMgbm90IGJlZW4gc2V0LCB3ZSBub3cgcmV0dXJuIHRvIHRoZSB0YXJnZXQgbm9kZSBhbmQgcHJvY2VzcwotICAgICAqICAgaXRzIGRlZmF1bHQgaGFuZGxlciBmb3IgdGhpcyBldmVudCwgaWYgYW55LgotICAgICAqIDwvb2w+Ci0gICAgICogPHA+Ci0gICAgICogTm90ZSB0aGF0IHJlZ2lzdHJhdGlvbiBvZiBoYW5kbGVycyBkdXJpbmcgcHJvY2Vzc2luZyBvZiBhbiBldmVudCBkb2VzCi0gICAgICogbm90IHRha2UgZWZmZWN0IGR1cmluZyB0aGlzIHBoYXNlIG9mIHRoaXMgZXZlbnQ7IHRoZXkgd2lsbCBub3QgYmUgY2FsbGVkCi0gICAgICogdW50aWwgdGhlIG5leHQgdGltZSB0aGlzIG5vZGUgaXMgdmlzaXRlZCBieSBkaXNwYXRjaEV2ZW50LiBPbiB0aGUgb3RoZXIKLSAgICAgKiBoYW5kLCByZW1vdmFscyB0YWtlIGVmZmVjdCBpbW1lZGlhdGVseS4KLSAgICAgKiA8cD4KLSAgICAgKiBJZiBhbiBldmVudCBoYW5kbGVyIGl0c2VsZiBjYXVzZXMgZXZlbnRzIHRvIGJlIGRpc3BhdGNoZWQsIHRoZXkgYXJlCi0gICAgICogcHJvY2Vzc2VkIHN5bmNocm9ub3VzbHksIGJlZm9yZSBwcm9jZXNzaW5nIHJlc3VtZXMKLSAgICAgKiBvbiB0aGUgZXZlbnQgd2hpY2ggdHJpZ2dlcmVkIHRoZW0uIFBsZWFzZSBiZSBhd2FyZSB0aGF0IHRoaXMgbWF5Ci0gICAgICogcmVzdWx0IGluIGV2ZW50cyBhcnJpdmluZyBhdCBsaXN0ZW5lcnMgIm91dCBvZiBvcmRlciIgcmVsYXRpdmUKLSAgICAgKiB0byB0aGUgYWN0dWFsIHNlcXVlbmNlIG9mIHJlcXVlc3RzLgotICAgICAqIDxwPgotICAgICAqIE5vdGUgdGhhdCBvdXIgaW1wbGVtZW50YXRpb24gcmVzZXRzIHRoZSBldmVudCdzIHN0b3AvcHJldmVudCBmbGFncwotICAgICAqIHdoZW4gZGlzcGF0Y2ggYmVnaW5zLgotICAgICAqIEkgYmVsaWV2ZSB0aGUgRE9NJ3MgaW50ZW50IGlzIHRoYXQgZXZlbnQgb2JqZWN0cyBiZSByZWRpc3BhdGNoYWJsZSwKLSAgICAgKiB0aG91Z2ggaXQgaXNuJ3Qgc3RhdGVkIGluIHRob3NlIHRlcm1zLgotICAgICAqIEBwYXJhbSBub2RlIG5vZGUgdG8gZGlzcGF0Y2ggdG8KLSAgICAgKiBAcGFyYW0gZXZlbnQgdGhlIGV2ZW50IG9iamVjdCB0byBiZSBkaXNwYXRjaGVkIHRvCi0gICAgICogICAgICAgICAgICAgIHJlZ2lzdGVyZWQgRXZlbnRMaXN0ZW5lcnMKLSAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGV2ZW50J3MgPGNvZGU+cHJldmVudERlZmF1bHQoKTwvY29kZT4KLSAgICAgKiAgICAgICAgICAgICAgbWV0aG9kIHdhcyBpbnZva2VkIGJ5IGFuIEV2ZW50TGlzdGVuZXI7IG90aGVyd2lzZSBmYWxzZS4KLSAgICAqLwotICAgIEBPdmVycmlkZQotICAgIHByb3RlY3RlZCBib29sZWFuIGRpc3BhdGNoRXZlbnQoTm9kZUltcGwgbm9kZSwgRXZlbnQgZXZlbnQpIHsKLSAgICAgICAgaWYgKGV2ZW50ID09IG51bGwpIHJldHVybiBmYWxzZTsKLQotICAgICAgICAvLyBDYW4ndCB1c2UgYW55b25lIGVsc2UncyBpbXBsZW1lbnRhdGlvbiwgc2luY2UgdGhlcmUncyBubyBwdWJsaWMKLSAgICAgICAgLy8gQVBJIGZvciBzZXR0aW5nIHRoZSBldmVudCdzIHByb2Nlc3Npbmctc3RhdGUgZmllbGRzLgotICAgICAgICBFdmVudEltcGwgZXZ0ID0gKEV2ZW50SW1wbClldmVudDsKLQotICAgICAgICAvLyBWQUxJREFURSAtLSBtdXN0IGhhdmUgYmVlbiBpbml0aWFsaXplZCBhdCBsZWFzdCBvbmNlLCBtdXN0IGhhdmUKLSAgICAgICAgLy8gYSBub24tbnVsbCBub24tYmxhbmsgbmFtZS4KLSAgICAgICAgaWYoIWV2dC5pbml0aWFsaXplZCB8fCBldnQudHlwZSA9PSBudWxsIHx8IGV2dC50eXBlLmVxdWFscygiIikpIHsKLSAgICAgICAgICAgIFN0cmluZyBtc2cgPSBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiVU5TUEVDSUZJRURfRVZFTlRfVFlQRV9FUlIiLCBudWxsKTsKLSAgICAgICAgICAgIHRocm93IG5ldyBFdmVudEV4Y2VwdGlvbihFdmVudEV4Y2VwdGlvbi5VTlNQRUNJRklFRF9FVkVOVF9UWVBFX0VSUiwgbXNnKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIElmIG5vYm9keSBpcyBsaXN0ZW5pbmcgZm9yIHRoaXMgZXZlbnQsIGRpc2NhcmQgaW1tZWRpYXRlbHkKLSAgICAgICAgTENvdW50IGxjID0gTENvdW50Lmxvb2t1cChldnQuZ2V0VHlwZSgpKTsKLSAgICAgICAgaWYgKGxjLnRvdGFsID09IDApCi0gICAgICAgICAgICByZXR1cm4gZXZ0LnByZXZlbnREZWZhdWx0OwotCi0gICAgICAgIC8vIElOSVRJQUxJWkUgVEhFIEVWRU5UJ1MgRElTUEFUQ0ggU1RBVFVTCi0gICAgICAgIC8vIChOb3RlIHRoYXQgRXZlbnQgb2JqZWN0cyBhcmUgcmV1c2FibGUgaW4gb3VyIGltcGxlbWVudGF0aW9uOwotICAgICAgICAvLyB0aGF0IGRvZXNuJ3Qgc2VlbSB0byBiZSBleHBsaWNpdGx5IGd1YXJhbnRlZWQgaW4gdGhlIERPTSwgYnV0Ci0gICAgICAgIC8vIEkgYmVsaWV2ZSBpdCBpcyB0aGUgaW50ZW50LikKLSAgICAgICAgZXZ0LnRhcmdldCA9IG5vZGU7Ci0gICAgICAgIGV2dC5zdG9wUHJvcGFnYXRpb24gPSBmYWxzZTsKLSAgICAgICAgZXZ0LnByZXZlbnREZWZhdWx0ID0gZmFsc2U7Ci0KLSAgICAgICAgLy8gQ2FwdHVyZSBwcmUtZXZlbnQgcGFyZW50YWdlIGNoYWluLCBub3QgaW5jbHVkaW5nIHRhcmdldDsKLSAgICAgICAgLy8gdXNlIHByZS1ldmVudC1kaXNwYXRjaCBhbmNlc3RvcnMgZXZlbiBpZiBldmVudCBoYW5kbGVycyBtdXRhdGUKLSAgICAgICAgLy8gZG9jdW1lbnQgYW5kIGNoYW5nZSB0aGUgdGFyZ2V0J3MgY29udGV4dC4KLSAgICAgICAgLy8gTm90ZSB0aGF0IHRoaXMgaXMgcGFyZW50cyBPTkxZOyBldmVudHMgZG8gbm90Ci0gICAgICAgIC8vIGNyb3NzIHRoZSBBdHRyL0VsZW1lbnQgImJsb29kL2JyYWluIGJhcnJpZXIiLgotICAgICAgICAvLyBET01BdHRyTW9kaWZpZWQuIHdoaWNoIGxvb2tzIGxpa2UgYW4gZXhjZXB0aW9uLAotICAgICAgICAvLyBpcyBpc3N1ZWQgdG8gdGhlIEVsZW1lbnQgcmF0aGVyIHRoYW4gdGhlIEF0dHIKLSAgICAgICAgLy8gYW5kIGNhdXNlcyBhIF9zZWNvbmRfIERPTVN1YnRyZWVNb2RpZmllZCBpbiB0aGUgRWxlbWVudCdzCi0gICAgICAgIC8vIHRyZWUuCi0gICAgICAgIExpc3Q8Tm9kZT4gcHYgPSBuZXcgQXJyYXlMaXN0PD4oMTApOwotICAgICAgICBOb2RlIHAgPSBub2RlOwotICAgICAgICBOb2RlIG4gPSBwLmdldFBhcmVudE5vZGUoKTsKLSAgICAgICAgd2hpbGUgKG4gIT0gbnVsbCkgewotICAgICAgICAgICAgcHYuYWRkKG4pOwotICAgICAgICAgICAgcCA9IG47Ci0gICAgICAgICAgICBuID0gbi5nZXRQYXJlbnROb2RlKCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBDQVBUVVJJTkdfUEhBU0U6Ci0gICAgICAgIGlmIChsYy5jYXB0dXJlcyA+IDApIHsKLSAgICAgICAgICAgIGV2dC5ldmVudFBoYXNlID0gRXZlbnQuQ0FQVFVSSU5HX1BIQVNFOwotICAgICAgICAgICAgLy8gQW5jZXN0b3JzIGFyZSBzY2FubmVkLCByb290IHRvIHRhcmdldCwgZm9yCi0gICAgICAgICAgICAvLyBDYXB0dXJpbmcgbGlzdGVuZXJzLgotICAgICAgICAgICAgZm9yIChpbnQgaiA9IHB2LnNpemUoKSAtIDE7IGogPj0gMDsgLS1qKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGV2dC5zdG9wUHJvcGFnYXRpb24pCi0gICAgICAgICAgICAgICAgICAgIGJyZWFrOyAgLy8gU29tZW9uZSBzZXQgdGhlIGZsYWcuIFBoYXNlIGVuZHMuCi0KLSAgICAgICAgICAgICAgICAvLyBIYW5kbGUgYWxsIGNhcHR1cmluZyBsaXN0ZW5lcnMgb24gdGhpcyBub2RlCi0gICAgICAgICAgICAgICAgTm9kZUltcGwgbm4gPSAoTm9kZUltcGwpIHB2LmdldChqKTsKLSAgICAgICAgICAgICAgICBldnQuY3VycmVudFRhcmdldCA9IG5uOwotICAgICAgICAgICAgICAgIExpc3Q8TEVudHJ5PiBub2RlTGlzdGVuZXJzID0gZ2V0RXZlbnRMaXN0ZW5lcnMobm4pOwotICAgICAgICAgICAgICAgIGlmIChub2RlTGlzdGVuZXJzICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgTGlzdDxMRW50cnk+IG5sID0gKExpc3QpKChBcnJheUxpc3Qpbm9kZUxpc3RlbmVycykuY2xvbmUoKTsKLSAgICAgICAgICAgICAgICAgICAgLy8gY2FsbCBsaXN0ZW5lcnMgaW4gdGhlIG9yZGVyIGluIHdoaWNoIHRoZXkgZ290IHJlZ2lzdGVyZWQKLSAgICAgICAgICAgICAgICAgICAgaW50IG5sc2l6ZSA9IG5sLnNpemUoKTsKLSAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBubHNpemU7IGkrKykgewotICAgICAgICAgICAgICAgICAgICAgICAgTEVudHJ5IGxlID0gbmwuZ2V0KGkpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxlLnVzZUNhcHR1cmUgJiYgbGUudHlwZS5lcXVhbHMoZXZ0LnR5cGUpICYmCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZUxpc3RlbmVycy5jb250YWlucyhsZSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZS5saXN0ZW5lci5oYW5kbGVFdmVudChldnQpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQWxsIGV4Y2VwdGlvbnMgYXJlIGlnbm9yZWQuCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLQotICAgICAgICAvLyBCb3RoIEFUX1RBUkdFVCBhbmQgQlVCQkxFIHVzZSBub24tY2FwdHVyaW5nIGxpc3RlbmVycy4KLSAgICAgICAgaWYgKGxjLmJ1YmJsZXMgPiAwKSB7Ci0gICAgICAgICAgICAvLyBBVF9UQVJHRVQgUEhBU0U6IEV2ZW50IGlzIGRpc3BhdGNoZWQgdG8gTk9OLUNBUFRVUklORyBsaXN0ZW5lcnMKLSAgICAgICAgICAgIC8vIG9uIHRoZSB0YXJnZXQgbm9kZS4gTm90ZSB0aGF0IGNhcHR1cmluZyBsaXN0ZW5lcnMgb24gdGhlIHRhcmdldAotICAgICAgICAgICAgLy8gbm9kZSBhcmUgX25vdF8gaW52b2tlZCwgZXZlbiBkdXJpbmcgdGhlIGNhcHR1cmUgcGhhc2UuCi0gICAgICAgICAgICBldnQuZXZlbnRQaGFzZSA9IEV2ZW50LkFUX1RBUkdFVDsKLSAgICAgICAgICAgIGV2dC5jdXJyZW50VGFyZ2V0ID0gbm9kZTsKLSAgICAgICAgICAgIExpc3Q8TEVudHJ5PiBub2RlTGlzdGVuZXJzID0gZ2V0RXZlbnRMaXN0ZW5lcnMobm9kZSk7Ci0gICAgICAgICAgICBpZiAoIWV2dC5zdG9wUHJvcGFnYXRpb24gJiYgbm9kZUxpc3RlbmVycyAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgTGlzdDxMRW50cnk+IG5sID0gKExpc3QpKChBcnJheUxpc3Qpbm9kZUxpc3RlbmVycykuY2xvbmUoKTsKLSAgICAgICAgICAgICAgICAvLyBjYWxsIGxpc3RlbmVycyBpbiB0aGUgb3JkZXIgaW4gd2hpY2ggdGhleSBnb3QgcmVnaXN0ZXJlZAotICAgICAgICAgICAgICAgIGludCBubHNpemUgPSBubC5zaXplKCk7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBubHNpemU7IGkrKykgewotICAgICAgICAgICAgICAgICAgICBMRW50cnkgbGUgPSAoTEVudHJ5KSBubC5nZXQoaSk7Ci0gICAgICAgICAgICAgICAgICAgIGlmICghbGUudXNlQ2FwdHVyZSAmJiBsZS50eXBlLmVxdWFscyhldnQudHlwZSkgJiYKLSAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVMaXN0ZW5lcnMuY29udGFpbnMobGUpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlLmxpc3RlbmVyLmhhbmRsZUV2ZW50KGV2dCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBBbGwgZXhjZXB0aW9ucyBhcmUgaWdub3JlZC4KLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIEJVQkJMSU5HX1BIQVNFOiBBbmNlc3RvcnMgYXJlIHNjYW5uZWQsIHRhcmdldCB0byByb290LCBmb3IKLSAgICAgICAgICAgIC8vIG5vbi1jYXB0dXJpbmcgbGlzdGVuZXJzLiBJZiB0aGUgZXZlbnQncyBwcmV2ZW50QnViYmxpbmcgZmxhZwotICAgICAgICAgICAgLy8gaGFzIGJlZW4gc2V0IGJlZm9yZSBwcm9jZXNzaW5nIG9mIGEgbm9kZSBjb21tZW5jZXMsIHdlCi0gICAgICAgICAgICAvLyBpbnN0ZWFkIGltbWVkaWF0ZWx5IGFkdmFuY2UgdG8gdGhlIGRlZmF1bHQgcGhhc2UuCi0gICAgICAgICAgICAvLyBOb3RlIHRoYXQgbm90IGFsbCBldmVudHMgYnViYmxlLgotICAgICAgICAgICAgaWYgKGV2dC5idWJibGVzKSB7Ci0gICAgICAgICAgICAgICAgZXZ0LmV2ZW50UGhhc2UgPSBFdmVudC5CVUJCTElOR19QSEFTRTsKLSAgICAgICAgICAgICAgICBpbnQgcHZzaXplID0gcHYuc2l6ZSgpOwotICAgICAgICAgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgcHZzaXplOyBqKyspIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGV2dC5zdG9wUHJvcGFnYXRpb24pCi0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsgIC8vIFNvbWVvbmUgc2V0IHRoZSBmbGFnLiBQaGFzZSBlbmRzLgotCi0gICAgICAgICAgICAgICAgICAgIC8vIEhhbmRsZSBhbGwgYnViYmxpbmcgbGlzdGVuZXJzIG9uIHRoaXMgbm9kZQotICAgICAgICAgICAgICAgICAgICBOb2RlSW1wbCBubiA9IChOb2RlSW1wbCkgcHYuZ2V0KGopOwotICAgICAgICAgICAgICAgICAgICBldnQuY3VycmVudFRhcmdldCA9IG5uOwotICAgICAgICAgICAgICAgICAgICBub2RlTGlzdGVuZXJzID0gZ2V0RXZlbnRMaXN0ZW5lcnMobm4pOwotICAgICAgICAgICAgICAgICAgICBpZiAobm9kZUxpc3RlbmVycyAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBMaXN0PExFbnRyeT4gbmwgPSAoTGlzdCkoKEFycmF5TGlzdClub2RlTGlzdGVuZXJzKS5jbG9uZSgpOwotICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2FsbCBsaXN0ZW5lcnMgaW4gdGhlIG9yZGVyIGluIHdoaWNoIHRoZXkgZ290Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyByZWdpc3RlcmVkCi0gICAgICAgICAgICAgICAgICAgICAgICBpbnQgbmxzaXplID0gbmwuc2l6ZSgpOwotICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBubHNpemU7IGkrKykgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIExFbnRyeSBsZSA9IG5sLmdldChpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWxlLnVzZUNhcHR1cmUgJiYgbGUudHlwZS5lcXVhbHMoZXZ0LnR5cGUpICYmCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVMaXN0ZW5lcnMuY29udGFpbnMobGUpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZS5saXN0ZW5lci5oYW5kbGVFdmVudChldnQpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQWxsIGV4Y2VwdGlvbnMgYXJlIGlnbm9yZWQuCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBERUZBVUxUIFBIQVNFOiBTb21lIERPTXMgaGF2ZSBkZWZhdWx0IGJlaGF2aW9ycyBib3VuZCB0byBzcGVjaWZpYwotICAgICAgICAvLyBub2Rlcy4gSWYgdGhpcyBET00gZG9lcywgYW5kIGlmIHRoZSBldmVudCdzIHByZXZlbnREZWZhdWx0IGZsYWcgaGFzCi0gICAgICAgIC8vIG5vdCBiZWVuIHNldCwgd2Ugbm93IHJldHVybiB0byB0aGUgdGFyZ2V0IG5vZGUgYW5kIHByb2Nlc3MgaXRzCi0gICAgICAgIC8vIGRlZmF1bHQgaGFuZGxlciBmb3IgdGhpcyBldmVudCwgaWYgYW55LgotICAgICAgICAvLyBObyBzcGVjaWZpYyBwaGFzZSB2YWx1ZSBkZWZpbmVkLCBzaW5jZSB0aGlzIGlzIERPTS1pbnRlcm5hbAotICAgICAgICBpZiAobGMuZGVmYXVsdHMgPiAwICYmICghZXZ0LmNhbmNlbGFibGUgfHwgIWV2dC5wcmV2ZW50RGVmYXVsdCkpIHsKLSAgICAgICAgICAgIC8vIGV2dC5ldmVudFBoYXNlID0gRXZlbnQuREVGQVVMVF9QSEFTRTsKLSAgICAgICAgICAgIC8vIGV2dC5jdXJyZW50VGFyZ2V0ID0gbm9kZTsKLSAgICAgICAgICAgIC8vIERPX0RFRkFVTFRfT1BFUkFUSU9OCi0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gZXZ0LnByZXZlbnREZWZhdWx0OwotICAgIH0gLy8gZGlzcGF0Y2hFdmVudChOb2RlSW1wbCxFdmVudCkgOmJvb2xlYW4KLQotICAgIC8qKgotICAgICAqIE5PTi1ET00gSU5URVJOQUw6IERPTU5vZGVJbnNlcnRlZEludG9Eb2N1bWVudCBhbmQgLi4uUmVtb3ZlZEZyb20uLi4KLSAgICAgKiBhcmUgZGlzcGF0Y2hlZCB0byBhbiBlbnRpcmUgc3VidHJlZS4gVGhpcyBpcyB0aGUgZGlzdHJpYnV0aW9uIGNvZGUKLSAgICAgKiB0aGVyZWZvci4gVGhleSBETyBOT1QgYnViYmxlLCB0aGFua3MgYmUsIGJ1dCBtYXkgYmUgY2FwdHVyZWQuCi0gICAgICogPHA+Ci0gICAgICogU2ltaWxhciB0byBjb2RlIGluIGRpc3BhdGNoaW5nRXZlbnRUb1N1YnRyZWUgaG93ZXZlciB0aGlzIG1ldGhvZAotICAgICAqIGlzIG9ubHkgdXNlZCBvbiB0aGUgdGFyZ2V0IG5vZGUgYW5kIGRvZXMgbm90IHN0YXJ0IGEgZGlzcGF0Y2hpbmcgY2hhaW4KLSAgICAgKiBvbiB0aGUgc2libGluZyBvZiB0aGUgdGFyZ2V0IG5vZGUgYXMgdGhpcyBpcyBub3QgcGFydCBvZiB0aGUgc3VidHJlZQotICAgICAqICoqKioqIEF0IHRoZSBtb21lbnQgSSdtIGJlaW5nIHNsb3BweSBhbmQgdXNpbmcgdGhlIG5vcm1hbAotICAgICAqIGNhcHR1cmUgZGlzcGF0Y2hlciBvbiBldmVyeSBub2RlLiBUaGlzIGNvdWxkIGJlIG9wdGltaXplZCBodWdlbHkKLSAgICAgKiBieSB3cml0aW5nIGEgY2FwdHVyZSBlbmdpbmUgdGhhdCB0cmFja3Mgb3VyIHBvc2l0aW9uIGluIHRoZSB0cmVlIHRvCi0gICAgICogdXBkYXRlIHRoZSBjYXB0dXJlIGNoYWluIHdpdGhvdXQgcmVwZWF0ZWQgY2hhc2VzIHVwIHRvIHJvb3QuCi0gICAgICogQHBhcmFtIG4gdGFyZ2V0IG5vZGUgKHRoYXQgd2FzIGRpcmVjdGx5IGluc2VydGVkIG9yIHJlbW92ZWQpCi0gICAgICogQHBhcmFtIGUgZXZlbnQgdG8gYmUgc2VudCB0byB0aGF0IG5vZGUgYW5kIGl0cyBzdWJ0cmVlCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgZGlzcGF0Y2hFdmVudFRvU3VidHJlZShOb2RlIG4sIEV2ZW50IGUpIHsKLQotICAgICAgICAoKE5vZGVJbXBsKSBuKS5kaXNwYXRjaEV2ZW50KGUpOwotICAgICAgICBpZiAobi5nZXROb2RlVHlwZSgpID09IE5vZGUuRUxFTUVOVF9OT0RFKSB7Ci0gICAgICAgICAgICBOYW1lZE5vZGVNYXAgYSA9IG4uZ2V0QXR0cmlidXRlcygpOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IGEuZ2V0TGVuZ3RoKCkgLSAxOyBpID49IDA7IC0taSkKLSAgICAgICAgICAgICAgICBkaXNwYXRjaGluZ0V2ZW50VG9TdWJ0cmVlKGEuaXRlbShpKSwgZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZGlzcGF0Y2hpbmdFdmVudFRvU3VidHJlZShuLmdldEZpcnN0Q2hpbGQoKSwgZSk7Ci0KLSAgICB9IC8vIGRpc3BhdGNoRXZlbnRUb1N1YnRyZWUoTm9kZUltcGwsTm9kZSxFdmVudCkgOnZvaWQKLQotCi0gICAgLyoqCi0gICAgICogRGlzcGF0Y2hlcyBldmVudCB0byB0aGUgdGFyZ2V0IG5vZGUncyBkZXNjZW5kZW50cyByZWN1cnNpdmVseQotICAgICAqCi0gICAgICogQHBhcmFtIG4gbm9kZSB0byBkaXNwYXRjaCB0bwotICAgICAqIEBwYXJhbSBlIGV2ZW50IHRvIGJlIHNlbnQgdG8gdGhhdCBub2RlIGFuZCBpdHMgc3VidHJlZQotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIGRpc3BhdGNoaW5nRXZlbnRUb1N1YnRyZWUoTm9kZSBuLCBFdmVudCBlKSB7Ci0gICAgICAgIGlmIChuPT1udWxsKQotICAgICAgICAgICAgICAgIHJldHVybjsKLQotICAgICAgICAvLyAqKioqKiBSZWN1cnNpdmUgaW1wbGVtZW50YXRpb24uIFRoaXMgaXMgZXhjZXNzaXZlbHkgZXhwZW5zaXZlLAotICAgICAgICAvLyBhbmQgc2hvdWxkIGJlIHJlcGxhY2VkIGluIGNvbmp1bmN0aW9uIHdpdGggb3B0aW1pemF0aW9uCi0gICAgICAgIC8vIG1lbnRpb25lZCBhYm92ZS4KLSAgICAgICAgKChOb2RlSW1wbCkgbikuZGlzcGF0Y2hFdmVudChlKTsKLSAgICAgICAgaWYgKG4uZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLkVMRU1FTlRfTk9ERSkgewotICAgICAgICAgICAgTmFtZWROb2RlTWFwIGEgPSBuLmdldEF0dHJpYnV0ZXMoKTsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSBhLmdldExlbmd0aCgpIC0gMTsgaSA+PSAwOyAtLWkpCi0gICAgICAgICAgICAgICAgZGlzcGF0Y2hpbmdFdmVudFRvU3VidHJlZShhLml0ZW0oaSksIGUpOwotICAgICAgICB9Ci0gICAgICAgIGRpc3BhdGNoaW5nRXZlbnRUb1N1YnRyZWUobi5nZXRGaXJzdENoaWxkKCksIGUpOwotICAgICAgICBkaXNwYXRjaGluZ0V2ZW50VG9TdWJ0cmVlKG4uZ2V0TmV4dFNpYmxpbmcoKSwgZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogTk9OLURPTSBJTlRFUk5BTDogUmV0dXJuIG9iamVjdCBmb3IgZ2V0RW5jbG9zaW5nQXR0ci4gQ2FycmllcwotICAgICAqICh0d28gdmFsdWVzLCB0aGUgQXR0ciBub2RlIGFmZmVjdGVkIChpZiBhbnkpIGFuZCBpdHMgcHJldmlvdXMKLSAgICAgKiBzdHJpbmcgdmFsdWUuIFNpbXBsZSBzdHJ1Y3QsIG5vIG1ldGhvZHMuCi0gICAgICovCi0gICAgY2xhc3MgRW5jbG9zaW5nQXR0ciBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZSB7Ci0gICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDUyMDgzODc3MjMzOTE2NDcyMTZMOwotICAgICAgICBBdHRySW1wbCBub2RlOwotICAgICAgICBTdHJpbmcgb2xkdmFsdWU7Ci0gICAgfQotCi0gICAgRW5jbG9zaW5nQXR0ciBzYXZlZEVuY2xvc2luZ0F0dHI7Ci0KLSAgICAvKioKLSAgICAgKiBOT04tRE9NIElOVEVSTkFMOiBDb252ZW5pZW5jZSB3cmFwcGVyIGZvciBjYWxsaW5nCi0gICAgICogZGlzcGF0Y2hBZ2dyZWdhdGVFdmVudHMgd2hlbiB0aGUgY29udGV4dCB3YXMgZXN0YWJsaXNoZWQKLSAgICAgKiBieSA8Y29kZT5zYXZlZEVuY2xvc2luZ0F0dHI8L2NvZGU+LgotICAgICAqIEBwYXJhbSBub2RlIG5vZGUgdG8gZGlzcGF0Y2ggdG8KLSAgICAgKiBAcGFyYW0gZWEgZGVzY3JpcHRpb24gb2YgQXR0ciBhZmZlY3RlZCBieSBjdXJyZW50IG9wZXJhdGlvbgotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIGRpc3BhdGNoQWdncmVnYXRlRXZlbnRzKE5vZGVJbXBsIG5vZGUsIEVuY2xvc2luZ0F0dHIgZWEpIHsKLSAgICAgICAgaWYgKGVhICE9IG51bGwpCi0gICAgICAgICAgICBkaXNwYXRjaEFnZ3JlZ2F0ZUV2ZW50cyhub2RlLCBlYS5ub2RlLCBlYS5vbGR2YWx1ZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE11dGF0aW9uRXZlbnQuTU9ESUZJQ0FUSU9OKTsKLSAgICAgICAgZWxzZQotICAgICAgICAgICAgZGlzcGF0Y2hBZ2dyZWdhdGVFdmVudHMobm9kZSwgbnVsbCwgbnVsbCwgKHNob3J0KSAwKTsKLQotICAgIH0gLy8gZGlzcGF0Y2hBZ2dyZWdhdGVFdmVudHMoTm9kZUltcGwsRW5jbG9zaW5nQXR0cikgOnZvaWQKLQotICAgIC8qKgotICAgICAqIE5PTi1ET00gSU5URVJOQUw6IEdlbmVyYXRlIHRoZSAiYWdncmVnYXRlZCIgcG9zdC1tdXRhdGlvbiBldmVudHMKLSAgICAgKiBET01BdHRyTW9kaWZpZWQgYW5kIERPTVN1YnRyZWVNb2RpZmllZC4KLSAgICAgKiBCb3RoIG9mIHRoZXNlIHNob3VsZCBiZSBpc3N1ZWQgb25seSBvbmNlIGZvciBlYWNoIHVzZXItcmVxdWVzdGVkCi0gICAgICogbXV0YXRpb24gb3BlcmF0aW9uLCBldmVuIGlmIHRoYXQgaW52b2x2ZXMgbXVsdGlwbGUgY2hhbmdlcyB0bwotICAgICAqIHRoZSBET00uCi0gICAgICogRm9yIGV4YW1wbGUsIGlmIGEgRE9NIG9wZXJhdGlvbiBtYWtlcyBtdWx0aXBsZSBjaGFuZ2VzIHRvIGEgc2luZ2xlCi0gICAgICogQXR0ciBiZWZvcmUgcmV0dXJuaW5nLCBpdCB3b3VsZCBiZSBuaWNlIHRvIGdlbmVyYXRlIG9ubHkgb25lCi0gICAgICogRE9NQXR0ck1vZGlmaWVkLCBhbmQgbXVsdGlwbGUgY2hhbmdlcyBvdmVyIGxhcmdlciBzY29wZSBidXQgd2l0aGluCi0gICAgICogYSByZWNvZ25pemFibGUgc2luZ2xlIHN1YnRyZWUgbWlnaHQgd2FudCB0byBnZW5lcmF0ZSBvbmx5IG9uZQotICAgICAqIERPTVN1YnRyZWVNb2RpZmllZCwgc2VudCB0byB0aGVpciBsb3dlc3QgY29tbW9uIGFuY2VzdG9yLgotICAgICAqIDxwPgotICAgICAqIFRvIG1hbmFnZSB0aGlzLCB1c2UgdGhlICJpbnRlcm5hbCIgdmVyc2lvbnMgb2YgaW5zZXJ0IGFuZCByZW1vdmUKLSAgICAgKiB3aXRoIE1VVEFUSU9OX0xPQ0FMLCB0aGVuIG1ha2UgYW4gZXhwbGljaXQgY2FsbCB0byB0aGlzIHJvdXRpbmUKLSAgICAgKiBhdCB0aGUgaGlnaGVyIGxldmVsLiBTb21lIGV4YW1wbGVzIG5vdyBleGlzdCBpbiBvdXIgY29kZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBub2RlIFRoZSBub2RlIHRvIGRpc3BhdGNoIHRvCi0gICAgICogQHBhcmFtIGVuY2xvc2luZ0F0dHIgVGhlIEF0dHIgbm9kZSAoaWYgYW55KSB3aG9zZSB2YWx1ZSBoYXMgYmVlbiBjaGFuZ2VkCi0gICAgICogYXMgYSByZXN1bHQgb2YgdGhlIERPTSBvcGVyYXRpb24uIE51bGwgaWYgbm9uZSBzdWNoLgotICAgICAqIEBwYXJhbSBvbGRWYWx1ZSBUaGUgU3RyaW5nIHZhbHVlIHByZXZpb3VzbHkgaGVsZCBieSB0aGUKLSAgICAgKiBlbmNsb3NpbmdBdHRyLiBJZ25vcmVkIGlmIG5vbmUgc3VjaC4KLSAgICAgKiBAcGFyYW0gY2hhbmdlIFR5cGUgb2YgbW9kaWZpY2F0aW9uIHRvIHRoZSBhdHRyLiBTZWUKLSAgICAgKiBNdXRhdGlvbkV2ZW50LmF0dHJDaGFuZ2UKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCBkaXNwYXRjaEFnZ3JlZ2F0ZUV2ZW50cyhOb2RlSW1wbCBub2RlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0dHJJbXBsIGVuY2xvc2luZ0F0dHIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG9sZHZhbHVlLCBzaG9ydCBjaGFuZ2UpIHsKLSAgICAgICAgLy8gV2UgaGF2ZSB0byBzZW5kIERPTUF0dHJNb2RpZmllZC4KLSAgICAgICAgTm9kZUltcGwgb3duZXIgPSBudWxsOwotICAgICAgICBpZiAoZW5jbG9zaW5nQXR0ciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBMQ291bnQgbGMgPSBMQ291bnQubG9va3VwKE11dGF0aW9uRXZlbnRJbXBsLkRPTV9BVFRSX01PRElGSUVEKTsKLSAgICAgICAgICAgIG93bmVyID0gKE5vZGVJbXBsKSBlbmNsb3NpbmdBdHRyLmdldE93bmVyRWxlbWVudCgpOwotICAgICAgICAgICAgaWYgKGxjLnRvdGFsID4gMCkgewotICAgICAgICAgICAgICAgIGlmIChvd25lciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIE11dGF0aW9uRXZlbnRJbXBsIG1lID0gIG5ldyBNdXRhdGlvbkV2ZW50SW1wbCgpOwotICAgICAgICAgICAgICAgICAgICBtZS5pbml0TXV0YXRpb25FdmVudChNdXRhdGlvbkV2ZW50SW1wbC5ET01fQVRUUl9NT0RJRklFRCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ1ZSwgZmFsc2UsIGVuY2xvc2luZ0F0dHIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9sZHZhbHVlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmNsb3NpbmdBdHRyLmdldE5vZGVWYWx1ZSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmNsb3NpbmdBdHRyLmdldE5vZGVOYW1lKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5nZSk7Ci0gICAgICAgICAgICAgICAgICAgIG93bmVyLmRpc3BhdGNoRXZlbnQobWUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICAvLyBET01TdWJ0cmVlTW9kaWZpZWQgZ2V0cyBzZW50IHRvIHRoZSBsb3dlc3QgY29tbW9uIHJvb3Qgb2YgYQotICAgICAgICAvLyBzZXQgb2YgY2hhbmdlcy4KLSAgICAgICAgLy8gIlRoaXMgZXZlbnQgaXMgZGlzcGF0Y2hlZCBhZnRlciBhbGwgb3RoZXIgZXZlbnRzIGNhdXNlZCBieSB0aGUKLSAgICAgICAgLy8gbXV0YXRpb24gaGF2ZSBiZWVuIGZpcmVkLiIKLSAgICAgICAgTENvdW50IGxjID0gTENvdW50Lmxvb2t1cChNdXRhdGlvbkV2ZW50SW1wbC5ET01fU1VCVFJFRV9NT0RJRklFRCk7Ci0gICAgICAgIGlmIChsYy50b3RhbCA+IDApIHsKLSAgICAgICAgICAgIE11dGF0aW9uRXZlbnQgbWUgPSAgbmV3IE11dGF0aW9uRXZlbnRJbXBsKCk7Ci0gICAgICAgICAgICBtZS5pbml0TXV0YXRpb25FdmVudChNdXRhdGlvbkV2ZW50SW1wbC5ET01fU1VCVFJFRV9NT0RJRklFRCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUsIGZhbHNlLCBudWxsLCBudWxsLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwgbnVsbCwgKHNob3J0KSAwKTsKLQotICAgICAgICAgICAgLy8gSWYgd2UncmUgd2l0aGluIGFuIEF0dHIsIERTdE0gZ2V0cyBzZW50IHRvIHRoZSBBdHRyCi0gICAgICAgICAgICAvLyBhbmQgdG8gaXRzIG93bmluZ0VsZW1lbnQuIE90aGVyd2lzZSB3ZSBkaXNwYXRjaCBpdAotICAgICAgICAgICAgLy8gbG9jYWxseS4KLSAgICAgICAgICAgIGlmIChlbmNsb3NpbmdBdHRyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBkaXNwYXRjaEV2ZW50KGVuY2xvc2luZ0F0dHIsIG1lKTsKLSAgICAgICAgICAgICAgICBpZiAob3duZXIgIT0gbnVsbCkKLSAgICAgICAgICAgICAgICAgICAgZGlzcGF0Y2hFdmVudChvd25lciwgbWUpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIGRpc3BhdGNoRXZlbnQobm9kZSwgbWUpOwotICAgICAgICB9Ci0gICAgfSAvLyBkaXNwYXRjaEFnZ3JlZ2F0ZUV2ZW50cyhOb2RlSW1wbCwgQXR0ckltcGwsU3RyaW5nKSA6dm9pZAotCi0gICAgLyoqCi0gICAgICogTk9OLURPTSBJTlRFUk5BTDogUHJlLW11dGF0aW9uIGNvbnRleHQgY2hlY2ssIGluCi0gICAgICogcHJlcGFyYXRpb24gZm9yIGxhdGVyIGdlbmVyYXRpbmcgRE9NQXR0ck1vZGlmaWVkIGV2ZW50cy4KLSAgICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgdGhpcyBub2RlIGlzIHdpdGhpbiBhbiBBdHRyCi0gICAgICogQHBhcmFtIG5vZGUgbm9kZSB0byBnZXQgZW5jbG9zaW5nIGF0dHJpYnV0ZSBmb3IKLSAgICAgKiBAcmV0dXJuIGVpdGhlciBhIGRlc2NyaXB0aW9uIG9mIHRoYXQgQXR0ciwgb3IgbnVsbCBpZiBub25lIHN1Y2guCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgc2F2ZUVuY2xvc2luZ0F0dHIoTm9kZUltcGwgbm9kZSkgewotICAgICAgICBzYXZlZEVuY2xvc2luZ0F0dHIgPSBudWxsOwotICAgICAgICAvLyBNVVRBVElPTiBQUkVQUk9DRVNTSU5HIEFORCBQUkUtRVZFTlRTOgotICAgICAgICAvLyBJZiB3ZSdyZSB3aXRoaW4gdGhlIHNjb3BlIG9mIGFuIEF0dHIgYW5kIERPTUF0dHJNb2RpZmllZAotICAgICAgICAvLyB3YXMgcmVxdWVzdGVkLCB3ZSBuZWVkIHRvIHByZXNlcnZlIGl0cyBwcmV2aW91cyB2YWx1ZSBmb3IKLSAgICAgICAgLy8gdGhhdCBldmVudC4KLSAgICAgICAgTENvdW50IGxjID0gTENvdW50Lmxvb2t1cChNdXRhdGlvbkV2ZW50SW1wbC5ET01fQVRUUl9NT0RJRklFRCk7Ci0gICAgICAgIGlmIChsYy50b3RhbCA+IDApIHsKLSAgICAgICAgICAgIE5vZGVJbXBsIGV2ZW50QW5jZXN0b3IgPSBub2RlOwotICAgICAgICAgICAgd2hpbGUgKHRydWUpIHsKLSAgICAgICAgICAgICAgICBpZiAoZXZlbnRBbmNlc3RvciA9PSBudWxsKQotICAgICAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICAgICAgaW50IHR5cGUgPSBldmVudEFuY2VzdG9yLmdldE5vZGVUeXBlKCk7Ci0gICAgICAgICAgICAgICAgaWYgKHR5cGUgPT0gTm9kZS5BVFRSSUJVVEVfTk9ERSkgewotICAgICAgICAgICAgICAgICAgICBFbmNsb3NpbmdBdHRyIHJldHZhbCA9IG5ldyBFbmNsb3NpbmdBdHRyKCk7Ci0gICAgICAgICAgICAgICAgICAgIHJldHZhbC5ub2RlID0gKEF0dHJJbXBsKSBldmVudEFuY2VzdG9yOwotICAgICAgICAgICAgICAgICAgICByZXR2YWwub2xkdmFsdWUgPSByZXR2YWwubm9kZS5nZXROb2RlVmFsdWUoKTsKLSAgICAgICAgICAgICAgICAgICAgc2F2ZWRFbmNsb3NpbmdBdHRyID0gcmV0dmFsOwotICAgICAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGUgPT0gTm9kZS5FTlRJVFlfUkVGRVJFTkNFX05PREUpCi0gICAgICAgICAgICAgICAgICAgIGV2ZW50QW5jZXN0b3IgPSBldmVudEFuY2VzdG9yLnBhcmVudE5vZGUoKTsKLSAgICAgICAgICAgICAgICBlbHNlIGlmICh0eXBlID09IE5vZGUuVEVYVF9OT0RFKQotICAgICAgICAgICAgICAgICAgICBldmVudEFuY2VzdG9yID0gZXZlbnRBbmNlc3Rvci5wYXJlbnROb2RlKCk7Ci0gICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICAgICAgLy8gQW55IG90aGVyIHBhcmVudCBtZWFucyB3ZSdyZSBub3QgaW4gYW4gQXR0cgotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfSAvLyBzYXZlRW5jbG9zaW5nQXR0cihOb2RlSW1wbCkgOnZvaWQKLQotICAgIC8qKgotICAgICAqIEEgbWV0aG9kIHRvIGJlIGNhbGxlZCB3aGVuIGEgY2hhcmFjdGVyIGRhdGEgbm9kZSBoYXMgYmVlbiBtb2RpZmllZAotICAgICAqLwotICAgIHZvaWQgbW9kaWZ5aW5nQ2hhcmFjdGVyRGF0YShOb2RlSW1wbCBub2RlLCBib29sZWFuIHJlcGxhY2UpIHsKLSAgICAgICAgaWYgKG11dGF0aW9uRXZlbnRzKSB7Ci0gICAgICAgICAgICAgICAgaWYgKCFyZXBsYWNlKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzYXZlRW5jbG9zaW5nQXR0cihub2RlKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBIG1ldGhvZCB0byBiZSBjYWxsZWQgd2hlbiBhIGNoYXJhY3RlciBkYXRhIG5vZGUgaGFzIGJlZW4gbW9kaWZpZWQKLSAgICAgKi8KLSAgICB2b2lkIG1vZGlmaWVkQ2hhcmFjdGVyRGF0YShOb2RlSW1wbCBub2RlLCBTdHJpbmcgb2xkdmFsdWUsIFN0cmluZyB2YWx1ZSwgYm9vbGVhbiByZXBsYWNlKSB7Ci0gICAgICAgIGlmIChtdXRhdGlvbkV2ZW50cykgewotICAgICAgICAgICAgICAgIGlmICghcmVwbGFjZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gTVVUQVRJT04gUE9TVC1FVkVOVFM6Ci0gICAgICAgICAgICAgICAgICAgICAgICBMQ291bnQgbGMgPQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMQ291bnQubG9va3VwKE11dGF0aW9uRXZlbnRJbXBsLkRPTV9DSEFSQUNURVJfREFUQV9NT0RJRklFRCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAobGMudG90YWwgPiAwKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE11dGF0aW9uRXZlbnQgbWUgPSBuZXcgTXV0YXRpb25FdmVudEltcGwoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWUuaW5pdE11dGF0aW9uRXZlbnQoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTXV0YXRpb25FdmVudEltcGwuRE9NX0NIQVJBQ1RFUl9EQVRBX01PRElGSUVELAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUsIGZhbHNlLCBudWxsLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbGR2YWx1ZSwgdmFsdWUsIG51bGwsIChzaG9ydCkgMCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpc3BhdGNoRXZlbnQobm9kZSwgbWUpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBTdWJyb3V0aW5lOiBUcmFuc21pdCBET01BdHRyTW9kaWZpZWQgYW5kIERPTVN1YnRyZWVNb2RpZmllZCwKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlmIHJlcXVpcmVkLiAoQ29tbW9uIHRvIG1vc3Qga2luZHMgb2YgbXV0YXRpb24pCi0gICAgICAgICAgICAgICAgICAgICAgICBkaXNwYXRjaEFnZ3JlZ2F0ZUV2ZW50cyhub2RlLCBzYXZlZEVuY2xvc2luZ0F0dHIpOwotICAgICAgICAgICAgICAgIH0gLy8gRW5kIG11dGF0aW9uIHBvc3Rwcm9jZXNzaW5nCi0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBIG1ldGhvZCB0byBiZSBjYWxsZWQgd2hlbiBhIGNoYXJhY3RlciBkYXRhIG5vZGUgaGFzIGJlZW4gcmVwbGFjZWQKLSAgICAgKi8KLSAgICB2b2lkIHJlcGxhY2VkQ2hhcmFjdGVyRGF0YShOb2RlSW1wbCBub2RlLCBTdHJpbmcgb2xkdmFsdWUsIFN0cmluZyB2YWx1ZSkgewotICAgICAgICAvL25vdyB0aGF0IHdlIGhhdmUgZmluaXNoZWQgcmVwbGFjaW5nIGRhdGEsIHdlIG5lZWQgdG8gcGVyZm9ybSB0aGUgc2FtZSBhY3Rpb25zCi0gICAgICAgIC8vdGhhdCBhcmUgcmVxdWlyZWQgYWZ0ZXIgYSBjaGFyYWN0ZXIgZGF0YSBub2RlIGhhcyBiZWVuIG1vZGlmaWVkCi0gICAgICAgIC8vc2VuZCB0aGUgdmFsdWUgb2YgZmFsc2UgZm9yIHJlcGxhY2UgcGFyYW1ldGVyIHNvIHRoYXQgbXV0YXRpb24KLSAgICAgICAgLy9ldmVudHMgaWYgYXBwcm9wcmlhdGUgd2lsbCBiZSBpbml0aWF0ZWQKLSAgICAgICAgbW9kaWZpZWRDaGFyYWN0ZXJEYXRhKG5vZGUsIG9sZHZhbHVlLCB2YWx1ZSwgZmFsc2UpOwotICAgIH0KLQotCi0KLSAgICAvKioKLSAgICAgKiBBIG1ldGhvZCB0byBiZSBjYWxsZWQgd2hlbiBhIG5vZGUgaXMgYWJvdXQgdG8gYmUgaW5zZXJ0ZWQgaW4gdGhlIHRyZWUuCi0gICAgICovCi0gICAgdm9pZCBpbnNlcnRpbmdOb2RlKE5vZGVJbXBsIG5vZGUsIGJvb2xlYW4gcmVwbGFjZSkgewotICAgICAgICBpZiAobXV0YXRpb25FdmVudHMpIHsKLSAgICAgICAgICAgIGlmICghcmVwbGFjZSkgewotICAgICAgICAgICAgICAgIHNhdmVFbmNsb3NpbmdBdHRyKG5vZGUpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQSBtZXRob2QgdG8gYmUgY2FsbGVkIHdoZW4gYSBub2RlIGhhcyBiZWVuIGluc2VydGVkIGluIHRoZSB0cmVlLgotICAgICAqLwotICAgIHZvaWQgaW5zZXJ0ZWROb2RlKE5vZGVJbXBsIG5vZGUsIE5vZGVJbXBsIG5ld0ludGVybmFsLCBib29sZWFuIHJlcGxhY2UpIHsKLSAgICAgICAgaWYgKG11dGF0aW9uRXZlbnRzKSB7Ci0gICAgICAgICAgICAvLyBNVVRBVElPTiBQT1NULUVWRU5UUzoKLSAgICAgICAgICAgIC8vICJMb2NhbCIgZXZlbnRzIChub24tYWdncmVnYXRlZCkKLSAgICAgICAgICAgIC8vIE5ldyBjaGlsZCBpcyB0b2xkIGl0IHdhcyBpbnNlcnRlZCwgYW5kIHdoZXJlCi0gICAgICAgICAgICBMQ291bnQgbGMgPSBMQ291bnQubG9va3VwKE11dGF0aW9uRXZlbnRJbXBsLkRPTV9OT0RFX0lOU0VSVEVEKTsKLSAgICAgICAgICAgIGlmIChsYy50b3RhbCA+IDApIHsKLSAgICAgICAgICAgICAgICBNdXRhdGlvbkV2ZW50SW1wbCBtZSA9IG5ldyBNdXRhdGlvbkV2ZW50SW1wbCgpOwotICAgICAgICAgICAgICAgIG1lLmluaXRNdXRhdGlvbkV2ZW50KE11dGF0aW9uRXZlbnRJbXBsLkRPTV9OT0RFX0lOU0VSVEVELAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUsIGZhbHNlLCBub2RlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsIG51bGwsIG51bGwsIChzaG9ydCkgMCk7Ci0gICAgICAgICAgICAgICAgZGlzcGF0Y2hFdmVudChuZXdJbnRlcm5hbCwgbWUpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBJZiB3aXRoaW4gdGhlIERvY3VtZW50LCB0ZWxsIHRoZSBzdWJ0cmVlIGl0J3MgYmVlbiBhZGRlZAotICAgICAgICAgICAgLy8gdG8gdGhlIERvYy4KLSAgICAgICAgICAgIGxjID0gTENvdW50Lmxvb2t1cCgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBNdXRhdGlvbkV2ZW50SW1wbC5ET01fTk9ERV9JTlNFUlRFRF9JTlRPX0RPQ1VNRU5UKTsKLSAgICAgICAgICAgIGlmIChsYy50b3RhbCA+IDApIHsKLSAgICAgICAgICAgICAgICBOb2RlSW1wbCBldmVudEFuY2VzdG9yID0gbm9kZTsKLSAgICAgICAgICAgICAgICBpZiAoc2F2ZWRFbmNsb3NpbmdBdHRyICE9IG51bGwpCi0gICAgICAgICAgICAgICAgICAgIGV2ZW50QW5jZXN0b3IgPSAoTm9kZUltcGwpCi0gICAgICAgICAgICAgICAgICAgICAgICBzYXZlZEVuY2xvc2luZ0F0dHIubm9kZS5nZXRPd25lckVsZW1lbnQoKTsKLSAgICAgICAgICAgICAgICBpZiAoZXZlbnRBbmNlc3RvciAhPSBudWxsKSB7IC8vIE1pZ2h0IGhhdmUgYmVlbiBvcnBoYW4gQXR0cgotICAgICAgICAgICAgICAgICAgICBOb2RlSW1wbCBwID0gZXZlbnRBbmNlc3RvcjsKLSAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHAgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRBbmNlc3RvciA9IHA7IC8vIExhc3Qgbm9uLW51bGwgYW5jZXN0b3IKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIEluIHRoaXMgY29udGV4dCwgYW5jZXN0cnkgaW5jbHVkZXMKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIHdhbGtpbmcgYmFjayBmcm9tIEF0dHIgdG8gRWxlbWVudAotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHAuZ2V0Tm9kZVR5cGUoKSA9PSBBVFRSSUJVVEVfTk9ERSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHAgPSAoTm9kZUltcGwpICgoQXR0ckltcGwpcCkuZ2V0T3duZXJFbGVtZW50KCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBwID0gcC5wYXJlbnROb2RlKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgaWYgKGV2ZW50QW5jZXN0b3IuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLkRPQ1VNRU5UX05PREUpewotICAgICAgICAgICAgICAgICAgICAgICAgTXV0YXRpb25FdmVudEltcGwgbWUgPSBuZXcgTXV0YXRpb25FdmVudEltcGwoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIG1lLmluaXRNdXRhdGlvbkV2ZW50KE11dGF0aW9uRXZlbnRJbXBsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuRE9NX05PREVfSU5TRVJURURfSU5UT19ET0NVTUVOVCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlLGZhbHNlLG51bGwsbnVsbCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsbnVsbCwoc2hvcnQpMCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBkaXNwYXRjaEV2ZW50VG9TdWJ0cmVlKG5ld0ludGVybmFsLCBtZSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoIXJlcGxhY2UpIHsKLSAgICAgICAgICAgICAgICAvLyBTdWJyb3V0aW5lOiBUcmFuc21pdCBET01BdHRyTW9kaWZpZWQgYW5kIERPTVN1YnRyZWVNb2RpZmllZAotICAgICAgICAgICAgICAgIC8vIChDb21tb24gdG8gbW9zdCBraW5kcyBvZiBtdXRhdGlvbikKLSAgICAgICAgICAgICAgICBkaXNwYXRjaEFnZ3JlZ2F0ZUV2ZW50cyhub2RlLCBzYXZlZEVuY2xvc2luZ0F0dHIpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gbm90aWZ5IHRoZSByYW5nZSBvZiBpbnNlcnRpb25zCi0gICAgICAgIGlmIChyYW5nZXMgIT0gbnVsbCkgewotICAgICAgICAgICAgaW50IHNpemUgPSByYW5nZXMuc2l6ZSgpOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgIT0gc2l6ZTsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgKChSYW5nZUltcGwpcmFuZ2VzLmdldChpKSkuaW5zZXJ0ZWROb2RlRnJvbURPTShuZXdJbnRlcm5hbCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBIG1ldGhvZCB0byBiZSBjYWxsZWQgd2hlbiBhIG5vZGUgaXMgYWJvdXQgdG8gYmUgcmVtb3ZlZCBmcm9tIHRoZSB0cmVlLgotICAgICAqLwotICAgIHZvaWQgcmVtb3ZpbmdOb2RlKE5vZGVJbXBsIG5vZGUsIE5vZGVJbXBsIG9sZENoaWxkLCBib29sZWFuIHJlcGxhY2UpIHsKLQotICAgICAgICAvLyBub3RpZnkgaXRlcmF0b3JzCi0gICAgICAgIGlmIChpdGVyYXRvcnMgIT0gbnVsbCkgewotICAgICAgICAgICAgaW50IHNpemUgPSBpdGVyYXRvcnMuc2l6ZSgpOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgIT0gc2l6ZTsgaSsrKSB7Ci0gICAgICAgICAgICAgICAoKE5vZGVJdGVyYXRvckltcGwpaXRlcmF0b3JzLmdldChpKSkucmVtb3ZlTm9kZShvbGRDaGlsZCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBub3RpZnkgcmFuZ2VzCi0gICAgICAgIGlmIChyYW5nZXMgIT0gbnVsbCkgewotICAgICAgICAgICAgaW50IHNpemUgPSByYW5nZXMuc2l6ZSgpOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgIT0gc2l6ZTsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgKChSYW5nZUltcGwpcmFuZ2VzLmdldChpKSkucmVtb3ZlTm9kZShvbGRDaGlsZCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBtdXRhdGlvbiBldmVudHMKLSAgICAgICAgaWYgKG11dGF0aW9uRXZlbnRzKSB7Ci0gICAgICAgICAgICAvLyBNVVRBVElPTiBQUkVQUk9DRVNTSU5HIEFORCBQUkUtRVZFTlRTOgotICAgICAgICAgICAgLy8gSWYgd2UncmUgd2l0aGluIHRoZSBzY29wZSBvZiBhbiBBdHRyIGFuZCBET01BdHRyTW9kaWZpZWQKLSAgICAgICAgICAgIC8vIHdhcyByZXF1ZXN0ZWQsIHdlIG5lZWQgdG8gcHJlc2VydmUgaXRzIHByZXZpb3VzIHZhbHVlIGZvcgotICAgICAgICAgICAgLy8gdGhhdCBldmVudC4KLSAgICAgICAgICAgIGlmICghcmVwbGFjZSkgewotICAgICAgICAgICAgICAgIHNhdmVFbmNsb3NpbmdBdHRyKG5vZGUpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gQ2hpbGQgaXMgdG9sZCB0aGF0IGl0IGlzIGFib3V0IHRvIGJlIHJlbW92ZWQKLSAgICAgICAgICAgIExDb3VudCBsYyA9IExDb3VudC5sb29rdXAoTXV0YXRpb25FdmVudEltcGwuRE9NX05PREVfUkVNT1ZFRCk7Ci0gICAgICAgICAgICBpZiAobGMudG90YWwgPiAwKSB7Ci0gICAgICAgICAgICAgICAgTXV0YXRpb25FdmVudEltcGwgbWU9IG5ldyBNdXRhdGlvbkV2ZW50SW1wbCgpOwotICAgICAgICAgICAgICAgIG1lLmluaXRNdXRhdGlvbkV2ZW50KE11dGF0aW9uRXZlbnRJbXBsLkRPTV9OT0RFX1JFTU9WRUQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ1ZSwgZmFsc2UsIG5vZGUsIG51bGwsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwgbnVsbCwgKHNob3J0KSAwKTsKLSAgICAgICAgICAgICAgICBkaXNwYXRjaEV2ZW50KG9sZENoaWxkLCBtZSk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIElmIHdpdGhpbiBEb2N1bWVudCwgY2hpbGQncyBzdWJ0cmVlIGlzIGluZm9ybWVkIHRoYXQgaXQncwotICAgICAgICAgICAgLy8gbG9zaW5nIHRoYXQgc3RhdHVzCi0gICAgICAgICAgICBsYyA9IExDb3VudC5sb29rdXAoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIE11dGF0aW9uRXZlbnRJbXBsLkRPTV9OT0RFX1JFTU9WRURfRlJPTV9ET0NVTUVOVCk7Ci0gICAgICAgICAgICBpZiAobGMudG90YWwgPiAwKSB7Ci0gICAgICAgICAgICAgICAgTm9kZUltcGwgZXZlbnRBbmNlc3RvciA9IHRoaXM7Ci0gICAgICAgICAgICAgICAgaWYoc2F2ZWRFbmNsb3NpbmdBdHRyICE9IG51bGwpCi0gICAgICAgICAgICAgICAgICAgIGV2ZW50QW5jZXN0b3IgPSAoTm9kZUltcGwpCi0gICAgICAgICAgICAgICAgICAgICAgICBzYXZlZEVuY2xvc2luZ0F0dHIubm9kZS5nZXRPd25lckVsZW1lbnQoKTsKLSAgICAgICAgICAgICAgICBpZiAoZXZlbnRBbmNlc3RvciAhPSBudWxsKSB7IC8vIE1pZ2h0IGhhdmUgYmVlbiBvcnBoYW4gQXR0cgotICAgICAgICAgICAgICAgICAgICBmb3IgKE5vZGVJbXBsIHAgPSBldmVudEFuY2VzdG9yLnBhcmVudE5vZGUoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICBwICE9IG51bGw7IHAgPSBwLnBhcmVudE5vZGUoKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRBbmNlc3RvciA9IHA7IC8vIExhc3Qgbm9uLW51bGwgYW5jZXN0b3IKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBpZiAoZXZlbnRBbmNlc3Rvci5nZXROb2RlVHlwZSgpID09IE5vZGUuRE9DVU1FTlRfTk9ERSl7Ci0gICAgICAgICAgICAgICAgICAgICAgICBNdXRhdGlvbkV2ZW50SW1wbCBtZSA9IG5ldyBNdXRhdGlvbkV2ZW50SW1wbCgpOwotICAgICAgICAgICAgICAgICAgICAgICAgbWUuaW5pdE11dGF0aW9uRXZlbnQoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNdXRhdGlvbkV2ZW50SW1wbC5ET01fTk9ERV9SRU1PVkVEX0ZST01fRE9DVU1FTlQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSwgZmFsc2UsIG51bGwsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLCBudWxsLCBudWxsLCAoc2hvcnQpIDApOwotICAgICAgICAgICAgICAgICAgICAgICAgZGlzcGF0Y2hFdmVudFRvU3VidHJlZShvbGRDaGlsZCwgbWUpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9IC8vIEVuZCBtdXRhdGlvbiBwcmVwcm9jZXNzaW5nCi0gICAgfQotCi0gICAgLyoqCi0gICAgICogQSBtZXRob2QgdG8gYmUgY2FsbGVkIHdoZW4gYSBub2RlIGhhcyBiZWVuIHJlbW92ZWQgZnJvbSB0aGUgdHJlZS4KLSAgICAgKi8KLSAgICB2b2lkIHJlbW92ZWROb2RlKE5vZGVJbXBsIG5vZGUsIGJvb2xlYW4gcmVwbGFjZSkgewotICAgICAgICBpZiAobXV0YXRpb25FdmVudHMpIHsKLSAgICAgICAgICAgIC8vIE1VVEFUSU9OIFBPU1QtRVZFTlRTOgotICAgICAgICAgICAgLy8gU3Vicm91dGluZTogVHJhbnNtaXQgRE9NQXR0ck1vZGlmaWVkIGFuZCBET01TdWJ0cmVlTW9kaWZpZWQsCi0gICAgICAgICAgICAvLyBpZiByZXF1aXJlZC4gKENvbW1vbiB0byBtb3N0IGtpbmRzIG9mIG11dGF0aW9uKQotICAgICAgICAgICAgaWYgKCFyZXBsYWNlKSB7Ci0gICAgICAgICAgICAgICAgZGlzcGF0Y2hBZ2dyZWdhdGVFdmVudHMobm9kZSwgc2F2ZWRFbmNsb3NpbmdBdHRyKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSAvLyBFbmQgbXV0YXRpb24gcG9zdHByb2Nlc3NpbmcKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBIG1ldGhvZCB0byBiZSBjYWxsZWQgd2hlbiBhIG5vZGUgaXMgYWJvdXQgdG8gYmUgcmVwbGFjZWQgaW4gdGhlIHRyZWUuCi0gICAgICovCi0gICAgdm9pZCByZXBsYWNpbmdOb2RlKE5vZGVJbXBsIG5vZGUpIHsKLSAgICAgICAgaWYgKG11dGF0aW9uRXZlbnRzKSB7Ci0gICAgICAgICAgICBzYXZlRW5jbG9zaW5nQXR0cihub2RlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEEgbWV0aG9kIHRvIGJlIGNhbGxlZCB3aGVuIGNoYXJhY3RlciBkYXRhIGlzIGFib3V0IHRvIGJlIHJlcGxhY2VkIGluIHRoZSB0cmVlLgotICAgICAqLwotICAgIHZvaWQgcmVwbGFjaW5nRGF0YSAoTm9kZUltcGwgbm9kZSkgewotICAgICAgICBpZiAobXV0YXRpb25FdmVudHMpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHNhdmVFbmNsb3NpbmdBdHRyKG5vZGUpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQSBtZXRob2QgdG8gYmUgY2FsbGVkIHdoZW4gYSBub2RlIGhhcyBiZWVuIHJlcGxhY2VkIGluIHRoZSB0cmVlLgotICAgICAqLwotICAgIHZvaWQgcmVwbGFjZWROb2RlKE5vZGVJbXBsIG5vZGUpIHsKLSAgICAgICAgaWYgKG11dGF0aW9uRXZlbnRzKSB7Ci0gICAgICAgICAgICBkaXNwYXRjaEFnZ3JlZ2F0ZUV2ZW50cyhub2RlLCBzYXZlZEVuY2xvc2luZ0F0dHIpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQSBtZXRob2QgdG8gYmUgY2FsbGVkIHdoZW4gYW4gYXR0cmlidXRlIHZhbHVlIGhhcyBiZWVuIG1vZGlmaWVkCi0gICAgICovCi0gICAgdm9pZCBtb2RpZmllZEF0dHJWYWx1ZShBdHRySW1wbCBhdHRyLCBTdHJpbmcgb2xkdmFsdWUpIHsKLSAgICAgICAgaWYgKG11dGF0aW9uRXZlbnRzKSB7Ci0gICAgICAgICAgICAvLyBNVVRBVElPTiBQT1NULUVWRU5UUzoKLSAgICAgICAgICAgIGRpc3BhdGNoQWdncmVnYXRlRXZlbnRzKGF0dHIsIGF0dHIsIG9sZHZhbHVlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTXV0YXRpb25FdmVudC5NT0RJRklDQVRJT04pOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQSBtZXRob2QgdG8gYmUgY2FsbGVkIHdoZW4gYW4gYXR0cmlidXRlIG5vZGUgaGFzIGJlZW4gc2V0Ci0gICAgICovCi0gICAgdm9pZCBzZXRBdHRyTm9kZShBdHRySW1wbCBhdHRyLCBBdHRySW1wbCBwcmV2aW91cykgewotICAgICAgICBpZiAobXV0YXRpb25FdmVudHMpIHsKLSAgICAgICAgICAgIC8vIE1VVEFUSU9OIFBPU1QtRVZFTlRTOgotICAgICAgICAgICAgaWYgKHByZXZpb3VzID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBkaXNwYXRjaEFnZ3JlZ2F0ZUV2ZW50cyhhdHRyLm93bmVyTm9kZSwgYXR0ciwgbnVsbCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNdXRhdGlvbkV2ZW50LkFERElUSU9OKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIGRpc3BhdGNoQWdncmVnYXRlRXZlbnRzKGF0dHIub3duZXJOb2RlLCBhdHRyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZXZpb3VzLmdldE5vZGVWYWx1ZSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE11dGF0aW9uRXZlbnQuTU9ESUZJQ0FUSU9OKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEEgbWV0aG9kIHRvIGJlIGNhbGxlZCB3aGVuIGFuIGF0dHJpYnV0ZSBub2RlIGhhcyBiZWVuIHJlbW92ZWQKLSAgICAgKi8KLSAgICB2b2lkIHJlbW92ZWRBdHRyTm9kZShBdHRySW1wbCBhdHRyLCBOb2RlSW1wbCBvbGRPd25lciwgU3RyaW5nIG5hbWUpIHsKLSAgICAgICAgLy8gV2UgY2FuJ3QgdXNlIHRoZSBzdGFuZGFyZCBkaXNwYXRjaEFnZ3JlZ2F0ZSwgc2luY2UgaXQgYXNzdW1lcwotICAgICAgICAvLyB0aGF0IHRoZSBBdHRyIGlzIHN0aWxsIGF0dGFjaGVkIHRvIGFuIG93bmVyLiBUaGlzIGNvZGUgaXMKLSAgICAgICAgLy8gc2ltaWxhciBidXQgZGlzcGF0Y2hlcyB0byB0aGUgcHJldmlvdXMgb3duZXIsICJlbGVtZW50Ii4KLSAgICAgICAgaWYgKG11dGF0aW9uRXZlbnRzKSB7Ci0gICAgICAgICAgICAvLyBJZiB3ZSBoYXZlIHRvIHNlbmQgRE9NQXR0ck1vZGlmaWVkIChkZXRlcm1pbmVkIGVhcmxpZXIpLAotICAgICAgICAgICAgLy8gZG8gc28uCi0gICAgICAgICAgICBMQ291bnQgbGMgPSBMQ291bnQubG9va3VwKE11dGF0aW9uRXZlbnRJbXBsLkRPTV9BVFRSX01PRElGSUVEKTsKLSAgICAgICAgICAgIGlmIChsYy50b3RhbCA+IDApIHsKLSAgICAgICAgICAgICAgICBNdXRhdGlvbkV2ZW50SW1wbCBtZT0gbmV3IE11dGF0aW9uRXZlbnRJbXBsKCk7Ci0gICAgICAgICAgICAgICAgbWUuaW5pdE11dGF0aW9uRXZlbnQoTXV0YXRpb25FdmVudEltcGwuRE9NX0FUVFJfTU9ESUZJRUQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ1ZSwgZmFsc2UsIGF0dHIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0ci5nZXROb2RlVmFsdWUoKSwgbnVsbCwgbmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNdXRhdGlvbkV2ZW50LlJFTU9WQUwpOwotICAgICAgICAgICAgICAgIGRpc3BhdGNoRXZlbnQob2xkT3duZXIsIG1lKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gV2UgY2FuIGhhbmQgb2ZmIHRvIHByb2Nlc3MgRE9NU3VidHJlZU1vZGlmaWVkLCB0aG91Z2guCi0gICAgICAgICAgICAvLyBOb3RlIHRoYXQgb25seSB0aGUgRWxlbWVudCBuZWVkcyB0byBiZSBpbmZvcm1lZDsgdGhlCi0gICAgICAgICAgICAvLyBBdHRyJ3Mgc3VidHJlZSBoYXMgbm90IGJlZW4gY2hhbmdlZCBieSB0aGlzIG9wZXJhdGlvbi4KLSAgICAgICAgICAgIGRpc3BhdGNoQWdncmVnYXRlRXZlbnRzKG9sZE93bmVyLCBudWxsLCBudWxsLCAoc2hvcnQpIDApOwotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBBIG1ldGhvZCB0byBiZSBjYWxsZWQgd2hlbiBhbiBhdHRyaWJ1dGUgbm9kZSBoYXMgYmVlbiByZW5hbWVkCi0gICAgICovCi0gICAgdm9pZCByZW5hbWVkQXR0ck5vZGUoQXR0ciBvbGRBdCwgQXR0ciBuZXdBdCkgewotICAgICAgICAvLyBSRVZJU0lUOiBUbyBiZSBpbXBsZW1lbnRlZCEhIQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEEgbWV0aG9kIHRvIGJlIGNhbGxlZCB3aGVuIGFuIGVsZW1lbnQgaGFzIGJlZW4gcmVuYW1lZAotICAgICAqLwotICAgIHZvaWQgcmVuYW1lZEVsZW1lbnQoRWxlbWVudCBvbGRFbCwgRWxlbWVudCBuZXdFbCkgewotICAgICAgICAvLyBSRVZJU0lUOiBUbyBiZSBpbXBsZW1lbnRlZCEhIQotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogQHNlcmlhbERhdGEgU2VyaWFsaXplZCBmaWVsZHMuIENvbnZlcnQgTWFwcyB0byBIYXNodGFibGVzIGFuZCBMaXN0cwotICAgICAqIHRvIFZlY3RvcnMgZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkuCi0gICAgICovCi0gICAgcHJpdmF0ZSB2b2lkIHdyaXRlT2JqZWN0KE9iamVjdE91dHB1dFN0cmVhbSBvdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgIC8vIENvbnZlcnQgTWFwcyB0byBIYXNodGFibGVzLCBMaXN0cyB0byBWZWN0b3JzCi0gICAgICAgIFZlY3RvcjxOb2RlSXRlcmF0b3I+IGl0ID0gKGl0ZXJhdG9ycyA9PSBudWxsKT8gbnVsbCA6IG5ldyBWZWN0b3I8PihpdGVyYXRvcnMpOwotICAgICAgICBWZWN0b3I8UmFuZ2U+IHIgPSAocmFuZ2VzID09IG51bGwpPyBudWxsIDogbmV3IFZlY3Rvcjw+KHJhbmdlcyk7Ci0KLSAgICAgICAgSGFzaHRhYmxlPE5vZGVJbXBsLCBWZWN0b3I8TEVudHJ5Pj4gZWwgPSBudWxsOwotICAgICAgICBpZiAoZXZlbnRMaXN0ZW5lcnMgIT0gbnVsbCkgewotICAgICAgICAgICAgZWwgPSBuZXcgSGFzaHRhYmxlPD4oKTsKLSAgICAgICAgICAgIGZvciAoTWFwLkVudHJ5PE5vZGVJbXBsLCBMaXN0PExFbnRyeT4+IGUgOiBldmVudExpc3RlbmVycy5lbnRyeVNldCgpKSB7Ci0gICAgICAgICAgICAgICAgIGVsLnB1dChlLmdldEtleSgpLCBuZXcgVmVjdG9yPD4oZS5nZXRWYWx1ZSgpKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBXcml0ZSBzZXJpYWxpemVkIGZpZWxkcwotICAgICAgICBPYmplY3RPdXRwdXRTdHJlYW0uUHV0RmllbGQgcGYgPSBvdXQucHV0RmllbGRzKCk7Ci0gICAgICAgIHBmLnB1dCgiaXRlcmF0b3JzIiwgaXQpOwotICAgICAgICBwZi5wdXQoInJhbmdlcyIsIHIpOwotICAgICAgICBwZi5wdXQoImV2ZW50TGlzdGVuZXJzIiwgZWwpOwotICAgICAgICBwZi5wdXQoIm11dGF0aW9uRXZlbnRzIiwgbXV0YXRpb25FdmVudHMpOwotICAgICAgICBvdXQud3JpdGVGaWVsZHMoKTsKLSAgICB9Ci0KLSAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKLSAgICBwcml2YXRlIHZvaWQgcmVhZE9iamVjdChPYmplY3RJbnB1dFN0cmVhbSBpbikKLSAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB7Ci0gICAgICAgIC8vIFdlIGhhdmUgdG8gcmVhZCBzZXJpYWxpemVkIGZpZWxkcyBmaXJzdC4KLSAgICAgICAgT2JqZWN0SW5wdXRTdHJlYW0uR2V0RmllbGQgZ2YgPSBpbi5yZWFkRmllbGRzKCk7Ci0gICAgICAgIFZlY3RvcjxOb2RlSXRlcmF0b3I+IGl0ID0gKFZlY3RvcjxOb2RlSXRlcmF0b3I+KWdmLmdldCgiaXRlcmF0b3JzIiwgbnVsbCk7Ci0gICAgICAgIFZlY3RvcjxSYW5nZT4gciA9IChWZWN0b3I8UmFuZ2U+KWdmLmdldCgicmFuZ2VzIiwgbnVsbCk7Ci0gICAgICAgIEhhc2h0YWJsZTxOb2RlSW1wbCwgVmVjdG9yPExFbnRyeT4+IGVsID0KLSAgICAgICAgICAgICAgICAoSGFzaHRhYmxlPE5vZGVJbXBsLCBWZWN0b3I8TEVudHJ5Pj4pZ2YuZ2V0KCJldmVudExpc3RlbmVycyIsIG51bGwpOwotCi0gICAgICAgIG11dGF0aW9uRXZlbnRzID0gZ2YuZ2V0KCJtdXRhdGlvbkV2ZW50cyIsIGZhbHNlKTsKLQotICAgICAgICAvL2NvbnZlcnQgSGFzaHRhYmxlcyBiYWNrIHRvIEhhc2hNYXBzIGFuZCBWZWN0b3JzIHRvIExpc3RzCi0gICAgICAgIGlmIChpdCAhPSBudWxsKSBpdGVyYXRvcnMgPSBuZXcgQXJyYXlMaXN0PD4oaXQpOwotICAgICAgICBpZiAociAhPSBudWxsKSByYW5nZXMgPSBuZXcgQXJyYXlMaXN0PD4ocik7Ci0gICAgICAgIGlmIChlbCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBldmVudExpc3RlbmVycyA9IG5ldyBIYXNoTWFwPD4oKTsKLSAgICAgICAgICAgIGZvciAoTWFwLkVudHJ5PE5vZGVJbXBsLCBWZWN0b3I8TEVudHJ5Pj4gZSA6IGVsLmVudHJ5U2V0KCkpIHsKLSAgICAgICAgICAgICAgICAgZXZlbnRMaXN0ZW5lcnMucHV0KGUuZ2V0S2V5KCksIG5ldyBBcnJheUxpc3Q8PihlLmdldFZhbHVlKCkpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLX0gLy8gY2xhc3MgRG9jdW1lbnRJbXBsCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vRG9jdW1lbnRUeXBlSW1wbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL0RvY3VtZW50VHlwZUltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNmJlYzUxYi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vRG9jdW1lbnRUeXBlSW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTU4ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKi8KLS8qCi0gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKLSAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAotICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgotICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKLSAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCi0gKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbTsKLQotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci1pbXBvcnQgamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbTsKLWltcG9ydCBqYXZhLmlvLk9iamVjdE91dHB1dFN0cmVhbTsKLWltcG9ydCBqYXZhLmlvLk9iamVjdFN0cmVhbUZpZWxkOwotaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwotaW1wb3J0IGphdmEudXRpbC5IYXNodGFibGU7Ci1pbXBvcnQgamF2YS51dGlsLk1hcDsKLWltcG9ydCBvcmcudzNjLmRvbS5ET01FeGNlcHRpb247Ci1pbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnRUeXBlOwotaW1wb3J0IG9yZy53M2MuZG9tLk5hbWVkTm9kZU1hcDsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotaW1wb3J0IG9yZy53M2MuZG9tLlVzZXJEYXRhSGFuZGxlcjsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIHJlcHJlc2VudHMgYSBEb2N1bWVudCBUeXBlIDxlbT5kZWNsYXJhY3Rpb248L2VtPiBpbgotICogdGhlIGRvY3VtZW50IGl0c2VsZiwgPGVtPm5vdDwvZW0+IGEgRG9jdW1lbnQgVHlwZSBEZWZpbml0aW9uIChEVEQpLgotICogQW4gWE1MIGRvY3VtZW50IG1heSAob3IgbWF5IG5vdCkgaGF2ZSBzdWNoIGEgcmVmZXJlbmNlLgotICogPFA+Ci0gKiBEb2N1bWVudFR5cGUgaXMgYW4gRXh0ZW5kZWQgRE9NIGZlYXR1cmUsIHVzZWQgaW4gWE1MIGRvY3VtZW50cyBidXQKLSAqIG5vdCBpbiBIVE1MLgotICogPFA+Ci0gKiBOb3RlIHRoYXQgRW50aXRpZXMgYW5kIE5vdGF0aW9ucyBhcmUgbm8gbG9uZ2VyIGNoaWxkcmVuIG9mIHRoZQotICogRG9jdW1lbnRUeXBlLCBidXQgYXJlIHBhcmVudGxlc3Mgbm9kZXMgaHVuZyBvbmx5IGluIHRoZWlyCi0gKiBhcHByb3ByaWF0ZSBOYW1lZE5vZGVNYXBzLgotICogPFA+Ci0gKiBUaGlzIGFyZWEgaXMgVU5ERVJTUEVDSUZJRUQgSU4gUkVDLURPTS1MZXZlbC0xLTE5OTgxMDAxCi0gKiBNb3N0IG5vdGFibHksIGFic29sdXRlbHkgbm8gcHJvdmlzaW9uIHdhcyBtYWRlIGZvciBzdG9yaW5nCi0gKiBhbmQgdXNpbmcgRWxlbWVudCBhbmQgQXR0cmlidXRlIGluZm9ybWF0aW9uLiBOb3Igd2FzIHRoZSBsaW5rYWdlCi0gKiBiZXR3ZWVuIEVudGl0aWVzIGFuZCBFbnRpdHkgUmVmZXJlbmNlcyBuYWlsZWQgZG93biBzb2xpZGx5LgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIEFybmF1ZCAgTGUgSG9ycywgSUJNCi0gKiBAYXV0aG9yIEpvZSBLZXNzZWxtYW4sIElCTQotICogQGF1dGhvciBBbmR5IENsYXJrLCBJQk0KLSAqIEBzaW5jZSAgUFItRE9NLUxldmVsLTEtMTk5ODA4MTguCi0gKi8KLXB1YmxpYyBjbGFzcyBEb2N1bWVudFR5cGVJbXBsCi0gICAgZXh0ZW5kcyBQYXJlbnROb2RlCi0gICAgaW1wbGVtZW50cyBEb2N1bWVudFR5cGUgewotCi0gICAgLy8KLSAgICAvLyBDb25zdGFudHMKLSAgICAvLwotCi0gICAgLyoqIFNlcmlhbGl6YXRpb24gdmVyc2lvbi4gKi8KLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNzc1MTI5OTE5MjMxNjUyNjQ4NUw7Ci0KLSAgICAvLwotICAgIC8vIERhdGEKLSAgICAvLwotCi0gICAgLyoqIERvY3VtZW50IHR5cGUgbmFtZS4gKi8KLSAgICBwcm90ZWN0ZWQgU3RyaW5nIG5hbWU7Ci0KLSAgICAvKiogRW50aXRpZXMuICovCi0gICAgcHJvdGVjdGVkIE5hbWVkTm9kZU1hcEltcGwgZW50aXRpZXM7Ci0KLSAgICAvKiogTm90YXRpb25zLiAqLwotICAgIHByb3RlY3RlZCBOYW1lZE5vZGVNYXBJbXBsIG5vdGF0aW9uczsKLQotICAgIC8vIE5PTi1ET00KLQotICAgIC8qKiBFbGVtZW50cy4gKi8KLSAgICBwcm90ZWN0ZWQgTmFtZWROb2RlTWFwSW1wbCBlbGVtZW50czsKLQotICAgIC8vIERPTTI6IHN1cHBvcnQgcHVibGljIElELgotICAgIHByb3RlY3RlZCBTdHJpbmcgcHVibGljSUQ7Ci0KLSAgICAvLyBET00yOiBzdXBwb3J0IHN5c3RlbSBJRC4KLSAgICBwcm90ZWN0ZWQgU3RyaW5nIHN5c3RlbUlEOwotCi0gICAgLy8gRE9NMjogc3VwcG9ydCBpbnRlcm5hbCBzdWJzZXQuCi0gICAgcHJvdGVjdGVkIFN0cmluZyBpbnRlcm5hbFN1YnNldDsKLQotICAgIC8qKiBUaGUgZm9sbG93aW5nIGFyZSByZXF1aXJlZCBmb3IgY29tcGFyZURvY3VtZW50UG9zaXRpb24KLSAgICAqLwotICAgIC8vIERvY3R5cGUgbnVtYmVyLiAgIERvYyB0eXBlcyB3aGljaCBoYXZlIG5vIG93bmVyIG1heSBiZSBhc3NpZ25lZAotICAgIC8vIGEgbnVtYmVyLCBvbiBkZW1hbmQsIGZvciBvcmRlcmluZyBwdXJwb3NlcyBmb3IgY29tcGFyZURvY3VtZW50UG9zaXRpb24KLSAgICBwcml2YXRlIGludCBkb2N0eXBlTnVtYmVyPTA7Ci0KLSAgICBwcml2YXRlIE1hcDxTdHJpbmcsIFVzZXJEYXRhUmVjb3JkPiB1c2VyRGF0YSA9ICBudWxsOwotCi0KLSAgICAvKioKLSAgICAgKiBAc2VyaWFsRmllbGQgbmFtZSBTdHJpbmcgZG9jdW1lbnQgdHlwZSBuYW1lCi0gICAgICogQHNlcmlhbEZpZWxkIGVudGl0aWVzIE5hbWVkTm9kZU1hcEltcGwgZW50aXRpZXMKLSAgICAgKiBAc2VyaWFsRmllbGQgbm90YXRpb25zIE5hbWVkTm9kZU1hcEltcGwgbm90YXRpb25zCi0gICAgICogQHNlcmlhbEZpZWxkIGVsZW1lbnRzIE5hbWVkTm9kZU1hcEltcGwgZWxlbWVudHMKLSAgICAgKiBAc2VyaWFsRmllbGQgcHVibGljSUQgU3RyaW5nIHN1cHBvcnQgcHVibGljIElECi0gICAgICogQHNlcmlhbEZpZWxkIHN5c3RlbUlEIFN0cmluZyBzdXBwb3J0IHN5c3RlbSBJRAotICAgICAqIEBzZXJpYWxGaWVsZCBpbnRlcm5hbFN1YnNldCBTdHJpbmcgc3VwcG9ydCBpbnRlcm5hbCBzdWJzZXQKLSAgICAgKiBAc2VyaWFsRmllbGQgZG9jdHlwZU51bWJlciBpbnQgRG9jdHlwZSBudW1iZXIKLSAgICAgKiBAc2VyaWFsRmllbGQgdXNlckRhdGEgSGFzaHRhYmxlIHVzZXIgZGF0YQotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIE9iamVjdFN0cmVhbUZpZWxkW10gc2VyaWFsUGVyc2lzdGVudEZpZWxkcyA9Ci0gICAgICAgIG5ldyBPYmplY3RTdHJlYW1GaWVsZFtdIHsKLSAgICAgICAgICAgIG5ldyBPYmplY3RTdHJlYW1GaWVsZCgibmFtZSIsIFN0cmluZy5jbGFzcyksCi0gICAgICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoImVudGl0aWVzIiwgTmFtZWROb2RlTWFwSW1wbC5jbGFzcyksCi0gICAgICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoIm5vdGF0aW9ucyIsIE5hbWVkTm9kZU1hcEltcGwuY2xhc3MpLAotICAgICAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJlbGVtZW50cyIsIE5hbWVkTm9kZU1hcEltcGwuY2xhc3MpLAotICAgICAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJwdWJsaWNJRCIsIFN0cmluZy5jbGFzcyksCi0gICAgICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoInN5c3RlbUlEIiwgU3RyaW5nLmNsYXNzKSwKLSAgICAgICAgICAgIG5ldyBPYmplY3RTdHJlYW1GaWVsZCgiaW50ZXJuYWxTdWJzZXQiLCBTdHJpbmcuY2xhc3MpLAotICAgICAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJkb2N0eXBlTnVtYmVyIiwgaW50LmNsYXNzKSwKLSAgICAgICAgICAgIG5ldyBPYmplY3RTdHJlYW1GaWVsZCgidXNlckRhdGEiLCBIYXNodGFibGUuY2xhc3MpLAotICAgICAgICB9OwotCi0gICAgLy8KLSAgICAvLyBDb25zdHJ1Y3RvcnMKLSAgICAvLwotCi0gICAgLyoqIEZhY3RvcnkgbWV0aG9kIGZvciBjcmVhdGluZyBhIGRvY3VtZW50IHR5cGUgbm9kZS4gKi8KLSAgICBwdWJsaWMgRG9jdW1lbnRUeXBlSW1wbChDb3JlRG9jdW1lbnRJbXBsIG93bmVyRG9jdW1lbnQsIFN0cmluZyBuYW1lKSB7Ci0gICAgICAgIHN1cGVyKG93bmVyRG9jdW1lbnQpOwotCi0gICAgICAgIHRoaXMubmFtZSA9IG5hbWU7Ci0gICAgICAgIC8vIERPTQotICAgICAgICBlbnRpdGllcyAgPSBuZXcgTmFtZWROb2RlTWFwSW1wbCh0aGlzKTsKLSAgICAgICAgbm90YXRpb25zID0gbmV3IE5hbWVkTm9kZU1hcEltcGwodGhpcyk7Ci0KLSAgICAgICAgLy8gTk9OLURPTQotICAgICAgICBlbGVtZW50cyA9IG5ldyBOYW1lZE5vZGVNYXBJbXBsKHRoaXMpOwotCi0gICAgfSAvLyA8aW5pdD4oQ29yZURvY3VtZW50SW1wbCxTdHJpbmcpCi0KLSAgICAvKiogRmFjdG9yeSBtZXRob2QgZm9yIGNyZWF0aW5nIGEgZG9jdW1lbnQgdHlwZSBub2RlLiAqLwotICAgIHB1YmxpYyBEb2N1bWVudFR5cGVJbXBsKENvcmVEb2N1bWVudEltcGwgb3duZXJEb2N1bWVudCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcXVhbGlmaWVkTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcHVibGljSUQsIFN0cmluZyBzeXN0ZW1JRCkgewotICAgICAgICB0aGlzKG93bmVyRG9jdW1lbnQsIHF1YWxpZmllZE5hbWUpOwotICAgICAgICB0aGlzLnB1YmxpY0lEID0gcHVibGljSUQ7Ci0gICAgICAgIHRoaXMuc3lzdGVtSUQgPSBzeXN0ZW1JRDsKLQotICAgIH0gLy8gPGluaXQ+KENvcmVEb2N1bWVudEltcGwsU3RyaW5nKQotCi0gICAgLy8KLSAgICAvLyBET00yOiBtZXRob2RzLgotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBJbnRyb2R1Y2VkIGluIERPTSBMZXZlbCAyLiA8cD4KLSAgICAgKgotICAgICAqIFJldHVybiB0aGUgcHVibGljIGlkZW50aWZpZXIgb2YgdGhpcyBEb2N1bWVudCB0eXBlLgotICAgICAqIEBzaW5jZSBXRC1ET00tTGV2ZWwtMi0xOTk5MDkyMwotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0UHVibGljSWQoKSB7Ci0gICAgICAgIGlmIChuZWVkc1N5bmNEYXRhKCkpIHsKLSAgICAgICAgICAgIHN5bmNocm9uaXplRGF0YSgpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBwdWJsaWNJRDsKLSAgICB9Ci0gICAgLyoqCi0gICAgICogSW50cm9kdWNlZCBpbiBET00gTGV2ZWwgMi4gPHA+Ci0gICAgICoKLSAgICAgKiBSZXR1cm4gdGhlIHN5c3RlbSBpZGVudGlmaWVyIG9mIHRoaXMgRG9jdW1lbnQgdHlwZS4KLSAgICAgKiBAc2luY2UgV0QtRE9NLUxldmVsLTItMTk5OTA5MjMKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFN5c3RlbUlkKCkgewotICAgICAgICBpZiAobmVlZHNTeW5jRGF0YSgpKSB7Ci0gICAgICAgICAgICBzeW5jaHJvbml6ZURhdGEoKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gc3lzdGVtSUQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogTk9OLURPTS4gPHA+Ci0gICAgICoKLSAgICAgKiBTZXQgdGhlIGludGVybmFsU3Vic2V0IGdpdmVuIGFzIGEgc3RyaW5nLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEludGVybmFsU3Vic2V0KFN0cmluZyBpbnRlcm5hbFN1YnNldCkgewotICAgICAgICBpZiAobmVlZHNTeW5jRGF0YSgpKSB7Ci0gICAgICAgICAgICBzeW5jaHJvbml6ZURhdGEoKTsKLSAgICAgICAgfQotICAgICAgICB0aGlzLmludGVybmFsU3Vic2V0ID0gaW50ZXJuYWxTdWJzZXQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSW50cm9kdWNlZCBpbiBET00gTGV2ZWwgMi4gPHA+Ci0gICAgICoKLSAgICAgKiBSZXR1cm4gdGhlIGludGVybmFsU3Vic2V0IGdpdmVuIGFzIGEgc3RyaW5nLgotICAgICAqIEBzaW5jZSBXRC1ET00tTGV2ZWwtMi0xOTk5MDkyMwotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0SW50ZXJuYWxTdWJzZXQoKSB7Ci0gICAgICAgIGlmIChuZWVkc1N5bmNEYXRhKCkpIHsKLSAgICAgICAgICAgIHN5bmNocm9uaXplRGF0YSgpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBpbnRlcm5hbFN1YnNldDsKLSAgICB9Ci0KLSAgICAvLwotICAgIC8vIE5vZGUgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBBIHNob3J0IGludGVnZXIgaW5kaWNhdGluZyB3aGF0IHR5cGUgb2Ygbm9kZSB0aGlzIGlzLiBUaGUgbmFtZWQKLSAgICAgKiBjb25zdGFudHMgZm9yIHRoaXMgdmFsdWUgYXJlIGRlZmluZWQgaW4gdGhlIG9yZy53M2MuZG9tLk5vZGUgaW50ZXJmYWNlLgotICAgICAqLwotICAgIHB1YmxpYyBzaG9ydCBnZXROb2RlVHlwZSgpIHsKLSAgICAgICAgcmV0dXJuIE5vZGUuRE9DVU1FTlRfVFlQRV9OT0RFOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIGRvY3VtZW50IHR5cGUgbmFtZQotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Tm9kZU5hbWUoKSB7Ci0gICAgICAgIGlmIChuZWVkc1N5bmNEYXRhKCkpIHsKLSAgICAgICAgICAgIHN5bmNocm9uaXplRGF0YSgpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBuYW1lOwotICAgIH0KLQotICAgIC8qKiBDbG9uZXMgdGhlIG5vZGUuICovCi0gICAgcHVibGljIE5vZGUgY2xvbmVOb2RlKGJvb2xlYW4gZGVlcCkgewotCi0gICAgICAgIERvY3VtZW50VHlwZUltcGwgbmV3bm9kZSA9IChEb2N1bWVudFR5cGVJbXBsKXN1cGVyLmNsb25lTm9kZShkZWVwKTsKLSAgICAgICAgLy8gTmFtZWROb2RlTWFwcyBtdXN0IGJlIGNsb25lZCBleHBsaWNpdGx5LCB0byBhdm9pZCBzaGFyaW5nIHRoZW0uCi0gICAgICAgIG5ld25vZGUuZW50aXRpZXMgID0gZW50aXRpZXMuY2xvbmVNYXAobmV3bm9kZSk7Ci0gICAgICAgIG5ld25vZGUubm90YXRpb25zID0gbm90YXRpb25zLmNsb25lTWFwKG5ld25vZGUpOwotICAgICAgICBuZXdub2RlLmVsZW1lbnRzICA9IGVsZW1lbnRzLmNsb25lTWFwKG5ld25vZGUpOwotCi0gICAgICAgIHJldHVybiBuZXdub2RlOwotCi0gICAgfSAvLyBjbG9uZU5vZGUoYm9vbGVhbik6Tm9kZQotCi0gICAgLyoKLSAgICAgKiBHZXQgTm9kZSB0ZXh0IGNvbnRlbnQKLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFRleHRDb250ZW50KCkgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qCi0gICAgICogU2V0IE5vZGUgdGV4dCBjb250ZW50Ci0gICAgICogQHNpbmNlIERPTSBMZXZlbCAzCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0VGV4dENvbnRlbnQoU3RyaW5nIHRleHRDb250ZW50KQotICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKLSAgICAgICAgLy8gbm8tb3AKLSAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAgKiBET00gTGV2ZWwgMyBXRC0gRXhwZXJpbWVudGFsLgotICAgICAgICAgICogT3ZlcnJpZGUgaW5oZXJpdGVkIGJlaGF2aW9yIGZyb20gUGFyZW50Tm9kZUltcGwgdG8gc3VwcG9ydCBkZWVwIGVxdWFsLgotICAgICAgICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNFcXVhbE5vZGUoTm9kZSBhcmcpIHsKLQotICAgICAgICBpZiAoIXN1cGVyLmlzRXF1YWxOb2RlKGFyZykpIHsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChuZWVkc1N5bmNEYXRhKCkpIHsKLSAgICAgICAgICAgIHN5bmNocm9uaXplRGF0YSgpOwotICAgICAgICB9Ci0gICAgICAgIERvY3VtZW50VHlwZUltcGwgYXJnRG9jVHlwZSA9IChEb2N1bWVudFR5cGVJbXBsKSBhcmc7Ci0KLSAgICAgICAgLy90ZXN0IGlmIHRoZSBmb2xsb3dpbmcgc3RyaW5nIGF0dHJpYnV0ZXMgYXJlIGVxdWFsOiBwdWJsaWNJZCwKLSAgICAgICAgLy9zeXN0ZW1JZCwgaW50ZXJuYWxTdWJzZXQuCi0gICAgICAgIGlmICgoZ2V0UHVibGljSWQoKSA9PSBudWxsICYmIGFyZ0RvY1R5cGUuZ2V0UHVibGljSWQoKSAhPSBudWxsKQotICAgICAgICAgICAgfHwgKGdldFB1YmxpY0lkKCkgIT0gbnVsbCAmJiBhcmdEb2NUeXBlLmdldFB1YmxpY0lkKCkgPT0gbnVsbCkKLSAgICAgICAgICAgIHx8IChnZXRTeXN0ZW1JZCgpID09IG51bGwgJiYgYXJnRG9jVHlwZS5nZXRTeXN0ZW1JZCgpICE9IG51bGwpCi0gICAgICAgICAgICB8fCAoZ2V0U3lzdGVtSWQoKSAhPSBudWxsICYmIGFyZ0RvY1R5cGUuZ2V0U3lzdGVtSWQoKSA9PSBudWxsKQotICAgICAgICAgICAgfHwgKGdldEludGVybmFsU3Vic2V0KCkgPT0gbnVsbAotICAgICAgICAgICAgICAgICYmIGFyZ0RvY1R5cGUuZ2V0SW50ZXJuYWxTdWJzZXQoKSAhPSBudWxsKQotICAgICAgICAgICAgfHwgKGdldEludGVybmFsU3Vic2V0KCkgIT0gbnVsbAotICAgICAgICAgICAgICAgICYmIGFyZ0RvY1R5cGUuZ2V0SW50ZXJuYWxTdWJzZXQoKSA9PSBudWxsKSkgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKGdldFB1YmxpY0lkKCkgIT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKCFnZXRQdWJsaWNJZCgpLmVxdWFscyhhcmdEb2NUeXBlLmdldFB1YmxpY0lkKCkpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKGdldFN5c3RlbUlkKCkgIT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKCFnZXRTeXN0ZW1JZCgpLmVxdWFscyhhcmdEb2NUeXBlLmdldFN5c3RlbUlkKCkpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKGdldEludGVybmFsU3Vic2V0KCkgIT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKCFnZXRJbnRlcm5hbFN1YnNldCgpLmVxdWFscyhhcmdEb2NUeXBlLmdldEludGVybmFsU3Vic2V0KCkpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy90ZXN0IGlmIE5hbWVkTm9kZU1hcHMgZW50aXRpZXMgYW5kIG5vdGF0aW9ucyBhcmUgZXF1YWwKLSAgICAgICAgTmFtZWROb2RlTWFwSW1wbCBhcmdFbnRpdGllcyA9IGFyZ0RvY1R5cGUuZW50aXRpZXM7Ci0KLSAgICAgICAgaWYgKChlbnRpdGllcyA9PSBudWxsICYmIGFyZ0VudGl0aWVzICE9IG51bGwpCi0gICAgICAgICAgICB8fCAoZW50aXRpZXMgIT0gbnVsbCAmJiBhcmdFbnRpdGllcyA9PSBudWxsKSkKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLQotICAgICAgICBpZiAoZW50aXRpZXMgIT0gbnVsbCAmJiBhcmdFbnRpdGllcyAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAoZW50aXRpZXMuZ2V0TGVuZ3RoKCkgIT0gYXJnRW50aXRpZXMuZ2V0TGVuZ3RoKCkpCi0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotCi0gICAgICAgICAgICBmb3IgKGludCBpbmRleCA9IDA7IGVudGl0aWVzLml0ZW0oaW5kZXgpICE9IG51bGw7IGluZGV4KyspIHsKLSAgICAgICAgICAgICAgICBOb2RlIGVudE5vZGUxID0gZW50aXRpZXMuaXRlbShpbmRleCk7Ci0gICAgICAgICAgICAgICAgTm9kZSBlbnROb2RlMiA9Ci0gICAgICAgICAgICAgICAgICAgIGFyZ0VudGl0aWVzLmdldE5hbWVkSXRlbShlbnROb2RlMS5nZXROb2RlTmFtZSgpKTsKLQotICAgICAgICAgICAgICAgIGlmICghKChOb2RlSW1wbCkgZW50Tm9kZTEpLmlzRXF1YWxOb2RlKChOb2RlSW1wbCkgZW50Tm9kZTIpKQotICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBOYW1lZE5vZGVNYXBJbXBsIGFyZ05vdGF0aW9ucyA9IGFyZ0RvY1R5cGUubm90YXRpb25zOwotCi0gICAgICAgIGlmICgobm90YXRpb25zID09IG51bGwgJiYgYXJnTm90YXRpb25zICE9IG51bGwpCi0gICAgICAgICAgICB8fCAobm90YXRpb25zICE9IG51bGwgJiYgYXJnTm90YXRpb25zID09IG51bGwpKQotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotCi0gICAgICAgIGlmIChub3RhdGlvbnMgIT0gbnVsbCAmJiBhcmdOb3RhdGlvbnMgIT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKG5vdGF0aW9ucy5nZXRMZW5ndGgoKSAhPSBhcmdOb3RhdGlvbnMuZ2V0TGVuZ3RoKCkpCi0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotCi0gICAgICAgICAgICBmb3IgKGludCBpbmRleCA9IDA7IG5vdGF0aW9ucy5pdGVtKGluZGV4KSAhPSBudWxsOyBpbmRleCsrKSB7Ci0gICAgICAgICAgICAgICAgTm9kZSBub3RlTm9kZTEgPSBub3RhdGlvbnMuaXRlbShpbmRleCk7Ci0gICAgICAgICAgICAgICAgTm9kZSBub3RlTm9kZTIgPQotICAgICAgICAgICAgICAgICAgICBhcmdOb3RhdGlvbnMuZ2V0TmFtZWRJdGVtKG5vdGVOb2RlMS5nZXROb2RlTmFtZSgpKTsKLQotICAgICAgICAgICAgICAgIGlmICghKChOb2RlSW1wbCkgbm90ZU5vZGUxKS5pc0VxdWFsTm9kZSgoTm9kZUltcGwpIG5vdGVOb2RlMikpCi0gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiB0cnVlOwotICAgIH0gLy9lbmQgaXNFcXVhbE5vZGUKLQotCi0gICAgLyoqCi0gICAgICogTk9OLURPTQotICAgICAqIHNldCB0aGUgb3duZXJEb2N1bWVudCBvZiB0aGlzIG5vZGUgYW5kIGl0cyBjaGlsZHJlbgotICAgICAqLwotICAgIHZvaWQgc2V0T3duZXJEb2N1bWVudChDb3JlRG9jdW1lbnRJbXBsIGRvYykgewotICAgICAgICBzdXBlci5zZXRPd25lckRvY3VtZW50KGRvYyk7Ci0gICAgICAgIGVudGl0aWVzLnNldE93bmVyRG9jdW1lbnQoZG9jKTsKLSAgICAgICAgbm90YXRpb25zLnNldE93bmVyRG9jdW1lbnQoZG9jKTsKLSAgICAgICAgZWxlbWVudHMuc2V0T3duZXJEb2N1bWVudChkb2MpOwotICAgIH0KLQotICAgIC8qKiBOT04tRE9NCi0gICAgICAgIEdldCB0aGUgbnVtYmVyIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGRvY3R5cGUuCi0gICAgKi8KLSAgICBwcm90ZWN0ZWQgaW50IGdldE5vZGVOdW1iZXIoKSB7Ci0gICAgICAgICAvLyBJZiB0aGUgZG9jdHlwZSBoYXMgYSBkb2N1bWVudCBvd25lciwgZ2V0IHRoZSBub2RlIG51bWJlcgotICAgICAgICAgLy8gcmVsYXRpdmUgdG8gdGhlIG93bmVyIGRvYwotICAgICAgICAgaWYgKGdldE93bmVyRG9jdW1lbnQoKSE9bnVsbCkKLSAgICAgICAgICAgIHJldHVybiBzdXBlci5nZXROb2RlTnVtYmVyKCk7Ci0KLSAgICAgICAgIC8vIFRoZSBkb2N0eXBlIGlzIGRpc2Nvbm5lY3RlZCBhbmQgbm90IGFzc29jaWF0ZWQgd2l0aCBhbnkgZG9jdW1lbnQuCi0gICAgICAgICAvLyBBc3NpZ24gdGhlIGRvY3R5cGUgYSBudW1iZXIgcmVsYXRpdmUgdG8gdGhlIGltcGxlbWVudGF0aW9uLgotICAgICAgICAgaWYgKGRvY3R5cGVOdW1iZXI9PTApIHsKLQotICAgICAgICAgICAgQ29yZURPTUltcGxlbWVudGF0aW9uSW1wbCBjZCA9IChDb3JlRE9NSW1wbGVtZW50YXRpb25JbXBsKUNvcmVET01JbXBsZW1lbnRhdGlvbkltcGwuZ2V0RE9NSW1wbGVtZW50YXRpb24oKTsKLSAgICAgICAgICAgIGRvY3R5cGVOdW1iZXIgPSBjZC5hc3NpZ25Eb2NUeXBlTnVtYmVyKCk7Ci0gICAgICAgICB9Ci0gICAgICAgICByZXR1cm4gZG9jdHlwZU51bWJlcjsKLSAgICB9Ci0KLSAgICAvLwotICAgIC8vIERvY3VtZW50VHlwZSBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIE5hbWUgb2YgdGhpcyBkb2N1bWVudCB0eXBlLiBJZiB3ZSBsb2FkZWQgZnJvbSBhIERURCwgdGhpcyBzaG91bGQKLSAgICAgKiBiZSB0aGUgbmFtZSBpbW1lZGlhdGVseSBmb2xsb3dpbmcgdGhlIERPQ1RZUEUga2V5d29yZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKSB7Ci0KLSAgICAgICAgaWYgKG5lZWRzU3luY0RhdGEoKSkgewotICAgICAgICAgICAgc3luY2hyb25pemVEYXRhKCk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG5hbWU7Ci0KLSAgICB9IC8vIGdldE5hbWUoKTpTdHJpbmcKLQotICAgIC8qKgotICAgICAqIEFjY2VzcyB0aGUgY29sbGVjdGlvbiBvZiBnZW5lcmFsIEVudGl0aWVzLCBib3RoIGV4dGVybmFsIGFuZAotICAgICAqIGludGVybmFsLCBkZWZpbmVkIGluIHRoZSBEVEQuIEZvciBleGFtcGxlLCBpbjoKLSAgICAgKiA8cD4KLSAgICAgKiA8cHJlPgotICAgICAqICAgJmx0OyFkb2N0eXBlIGV4YW1wbGUgU1lTVEVNICJleC5kdGQiIFsKLSAgICAgKiAgICAgJmx0OyFFTlRJVFkgZm9vICJmb28iJmd0OwotICAgICAqICAgICAmbHQ7IUVOVElUWSBiYXIgImJhciImZ3Q7Ci0gICAgICogICAgICZsdDshRU5USVRZICUgYmF6ICJiYXoiJmd0OwotICAgICAqICAgICBdJmd0OwotICAgICAqIDwvcHJlPgotICAgICAqIDxwPgotICAgICAqIFRoZSBFbnRpdGllcyBtYXAgaW5jbHVkZXMgZm9vIGFuZCBiYXIsIGJ1dCBub3QgYmF6LiBJdCBpcyBwcm9taXNlZCB0aGF0Ci0gICAgICogb25seSBOb2RlcyB3aGljaCBhcmUgRW50aXRpZXMgd2lsbCBleGlzdCBpbiB0aGlzIE5hbWVkTm9kZU1hcC4KLSAgICAgKiA8cD4KLSAgICAgKiBGb3IgSFRNTCwgdGhpcyB3aWxsIGFsd2F5cyBiZSBudWxsLgotICAgICAqIDxwPgotICAgICAqIE5vdGUgdGhhdCAiYnVpbHQgaW4iIGVudGl0aWVzIHN1Y2ggYXMgJmFtcDsgYW5kICZsdDsgc2hvdWxkIGJlCi0gICAgICogY29udmVydGVkIHRvIHRoZWlyIGFjdHVhbCBjaGFyYWN0ZXJzIGJlZm9yZSBiZWluZyBwbGFjZWQgaW4gdGhlIERPTSdzCi0gICAgICogY29udGFpbmVkIHRleHQsIGFuZCBzaG91bGQgYmUgY29udmVydGVkIGJhY2sgd2hlbiB0aGUgRE9NIGlzIHJlbmRlcmVkCi0gICAgICogYXMgWE1MIG9yIEhUTUwsIGFuZCBoZW5jZSBETyBOT1QgYXBwZWFyIGhlcmUuCi0gICAgICovCi0gICAgcHVibGljIE5hbWVkTm9kZU1hcCBnZXRFbnRpdGllcygpIHsKLSAgICAgICAgaWYgKG5lZWRzU3luY0NoaWxkcmVuKCkpIHsKLSAgICAgICAgICAgIHN5bmNocm9uaXplQ2hpbGRyZW4oKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGVudGl0aWVzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEFjY2VzcyB0aGUgY29sbGVjdGlvbiBvZiBOb3RhdGlvbnMgZGVmaW5lZCBpbiB0aGUgRFRELiAgQQotICAgICAqIG5vdGF0aW9uIGRlY2xhcmVzLCBieSBuYW1lLCB0aGUgZm9ybWF0IG9mIGFuIFhNTCB1bnBhcnNlZCBlbnRpdHkKLSAgICAgKiBvciBpcyB1c2VkIHRvIGZvcm1hbGx5IGRlY2xhcmUgYSBQcm9jZXNzaW5nIEluc3RydWN0aW9uIHRhcmdldC4KLSAgICAgKi8KLSAgICBwdWJsaWMgTmFtZWROb2RlTWFwIGdldE5vdGF0aW9ucygpIHsKLSAgICAgICAgaWYgKG5lZWRzU3luY0NoaWxkcmVuKCkpIHsKLSAgICAgICAgICAgIHN5bmNocm9uaXplQ2hpbGRyZW4oKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG5vdGF0aW9uczsKLSAgICB9Ci0KLSAgICAvLwotICAgIC8vIFB1YmxpYyBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIE5PTi1ET006IFN1YmNsYXNzZWQgdG8gZmxpcCB0aGUgZW50aXRpZXMnIGFuZCBub3RhdGlvbnMnIHJlYWRvbmx5IHN3aXRjaAotICAgICAqIGFzIHdlbGwuCi0gICAgICogQHNlZSBOb2RlSW1wbCNzZXRSZWFkT25seQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFJlYWRPbmx5KGJvb2xlYW4gcmVhZE9ubHksIGJvb2xlYW4gZGVlcCkgewotCi0gICAgICAgIGlmIChuZWVkc1N5bmNDaGlsZHJlbigpKSB7Ci0gICAgICAgICAgICBzeW5jaHJvbml6ZUNoaWxkcmVuKCk7Ci0gICAgICAgIH0KLSAgICAgICAgc3VwZXIuc2V0UmVhZE9ubHkocmVhZE9ubHksIGRlZXApOwotCi0gICAgICAgIC8vIHNldCByZWFkLW9ubHkgcHJvcGVydHkKLSAgICAgICAgZWxlbWVudHMuc2V0UmVhZE9ubHkocmVhZE9ubHksIHRydWUpOwotICAgICAgICBlbnRpdGllcy5zZXRSZWFkT25seShyZWFkT25seSwgdHJ1ZSk7Ci0gICAgICAgIG5vdGF0aW9ucy5zZXRSZWFkT25seShyZWFkT25seSwgdHJ1ZSk7Ci0KLSAgICB9IC8vIHNldFJlYWRPbmx5KGJvb2xlYW4sYm9vbGVhbikKLQotICAgIC8qKgotICAgICAqIE5PTi1ET006IEFjY2VzcyB0aGUgY29sbGVjdGlvbiBvZiBFbGVtZW50RGVmaW5pdGlvbnMuCi0gICAgICogQHNlZSBFbGVtZW50RGVmaW5pdGlvbkltcGwKLSAgICAgKi8KLSAgICBwdWJsaWMgTmFtZWROb2RlTWFwIGdldEVsZW1lbnRzKCkgewotICAgICAgICBpZiAobmVlZHNTeW5jQ2hpbGRyZW4oKSkgewotICAgICAgICAgICAgc3luY2hyb25pemVDaGlsZHJlbigpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBlbGVtZW50czsKLSAgICB9Ci0KLSAgICBwdWJsaWMgT2JqZWN0IHNldFVzZXJEYXRhKFN0cmluZyBrZXksCi0gICAgT2JqZWN0IGRhdGEsIFVzZXJEYXRhSGFuZGxlciBoYW5kbGVyKSB7Ci0gICAgICAgIGlmKHVzZXJEYXRhID09IG51bGwpCi0gICAgICAgICAgICB1c2VyRGF0YSA9IG5ldyBIYXNoTWFwPD4oKTsKLSAgICAgICAgaWYgKGRhdGEgPT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKHVzZXJEYXRhICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBVc2VyRGF0YVJlY29yZCB1ZHIgPSB1c2VyRGF0YS5yZW1vdmUoa2V5KTsKLSAgICAgICAgICAgICAgICBpZiAodWRyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHVkci5mRGF0YTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIFVzZXJEYXRhUmVjb3JkIHVkciA9IHVzZXJEYXRhLnB1dChrZXksIG5ldyBVc2VyRGF0YVJlY29yZChkYXRhLCBoYW5kbGVyKSk7Ci0gICAgICAgICAgICBpZiAodWRyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gdWRyLmZEYXRhOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIHB1YmxpYyBPYmplY3QgZ2V0VXNlckRhdGEoU3RyaW5nIGtleSkgewotICAgICAgICBpZiAodXNlckRhdGEgPT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLSAgICAgICAgVXNlckRhdGFSZWNvcmQgdWRyID0gdXNlckRhdGEuZ2V0KGtleSk7Ci0gICAgICAgIGlmICh1ZHIgIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIHVkci5mRGF0YTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICBAT3ZlcnJpZGUKLSAgICBwcm90ZWN0ZWQgTWFwPFN0cmluZywgVXNlckRhdGFSZWNvcmQ+IGdldFVzZXJEYXRhUmVjb3JkKCl7Ci0gICAgICAgIHJldHVybiB1c2VyRGF0YTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAc2VyaWFsRGF0YSBTZXJpYWxpemVkIGZpZWxkcy4gQ29udmVydCBNYXAgdG8gSGFzaHRhYmxlIGZvciBiYWNrd2FyZAotICAgICAqIGNvbXBhdGliaWxpdHkuCi0gICAgICovCi0gICAgcHJpdmF0ZSB2b2lkIHdyaXRlT2JqZWN0KE9iamVjdE91dHB1dFN0cmVhbSBvdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgIC8vIENvbnZlcnQgdGhlIEhhc2hNYXAgdG8gSGFzaHRhYmxlCi0gICAgICAgIEhhc2h0YWJsZTxTdHJpbmcsIFVzZXJEYXRhUmVjb3JkPiB1ZCA9ICh1c2VyRGF0YSA9PSBudWxsKT8gbnVsbCA6IG5ldyBIYXNodGFibGU8Pih1c2VyRGF0YSk7Ci0KLSAgICAgICAgLy8gV3JpdGUgc2VyaWFsaXplZCBmaWVsZHMKLSAgICAgICAgT2JqZWN0T3V0cHV0U3RyZWFtLlB1dEZpZWxkIHBmID0gb3V0LnB1dEZpZWxkcygpOwotICAgICAgICBwZi5wdXQoIm5hbWUiLCBuYW1lKTsKLSAgICAgICAgcGYucHV0KCJlbnRpdGllcyIsIGVudGl0aWVzKTsKLSAgICAgICAgcGYucHV0KCJub3RhdGlvbnMiLCBub3RhdGlvbnMpOwotICAgICAgICBwZi5wdXQoImVsZW1lbnRzIiwgZWxlbWVudHMpOwotICAgICAgICBwZi5wdXQoInB1YmxpY0lEIiwgcHVibGljSUQpOwotICAgICAgICBwZi5wdXQoInN5c3RlbUlEIiwgc3lzdGVtSUQpOwotICAgICAgICBwZi5wdXQoImludGVybmFsU3Vic2V0IiwgaW50ZXJuYWxTdWJzZXQpOwotICAgICAgICBwZi5wdXQoImRvY3R5cGVOdW1iZXIiLCBkb2N0eXBlTnVtYmVyKTsKLSAgICAgICAgcGYucHV0KCJ1c2VyRGF0YSIsIHVkKTsKLSAgICAgICAgb3V0LndyaXRlRmllbGRzKCk7Ci0gICAgfQotCi0gICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCi0gICAgcHJpdmF0ZSB2b2lkIHJlYWRPYmplY3QoT2JqZWN0SW5wdXRTdHJlYW0gaW4pCi0gICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIENsYXNzTm90Rm91bmRFeGNlcHRpb24gewotICAgICAgICAvLyBXZSBoYXZlIHRvIHJlYWQgc2VyaWFsaXplZCBmaWVsZHMgZmlyc3QuCi0gICAgICAgIE9iamVjdElucHV0U3RyZWFtLkdldEZpZWxkIGdmID0gaW4ucmVhZEZpZWxkcygpOwotICAgICAgICBuYW1lID0gKFN0cmluZylnZi5nZXQoIm5hbWUiLCBudWxsKTsKLSAgICAgICAgZW50aXRpZXMgPSAoTmFtZWROb2RlTWFwSW1wbClnZi5nZXQoImVudGl0aWVzIiwgbnVsbCk7Ci0gICAgICAgIG5vdGF0aW9ucyA9IChOYW1lZE5vZGVNYXBJbXBsKWdmLmdldCgibm90YXRpb25zIiwgbnVsbCk7Ci0gICAgICAgIGVsZW1lbnRzID0gKE5hbWVkTm9kZU1hcEltcGwpZ2YuZ2V0KCJlbGVtZW50cyIsIG51bGwpOwotICAgICAgICBwdWJsaWNJRCA9IChTdHJpbmcpZ2YuZ2V0KCJwdWJsaWNJRCIsIG51bGwpOwotICAgICAgICBzeXN0ZW1JRCA9IChTdHJpbmcpZ2YuZ2V0KCJzeXN0ZW1JRCIsIG51bGwpOwotICAgICAgICBpbnRlcm5hbFN1YnNldCA9IChTdHJpbmcpZ2YuZ2V0KCJpbnRlcm5hbFN1YnNldCIsIG51bGwpOwotICAgICAgICBkb2N0eXBlTnVtYmVyID0gZ2YuZ2V0KCJkb2N0eXBlTnVtYmVyIiwgMCk7Ci0KLSAgICAgICAgSGFzaHRhYmxlPFN0cmluZywgVXNlckRhdGFSZWNvcmQ+IHVkID0KLSAgICAgICAgICAgICAgICAoSGFzaHRhYmxlPFN0cmluZywgVXNlckRhdGFSZWNvcmQ+KWdmLmdldCgidXNlckRhdGEiLCBudWxsKTsKLQotICAgICAgICAvL2NvbnZlcnQgdGhlIEhhc2h0YWJsZSBiYWNrIHRvIEhhc2hNYXAKLSAgICAgICAgaWYgKHVkICE9IG51bGwpIHVzZXJEYXRhID0gbmV3IEhhc2hNYXA8Pih1ZCk7Ci0gICAgfQotfSAvLyBjbGFzcyBEb2N1bWVudFR5cGVJbXBsCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vRWxlbWVudERlZmluaXRpb25JbXBsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vRWxlbWVudERlZmluaXRpb25JbXBsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDZjNTZhNjkuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL0VsZW1lbnREZWZpbml0aW9uSW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTIxICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwMiwyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbTsKLQotaW1wb3J0IG9yZy53M2MuZG9tLk5hbWVkTm9kZU1hcDsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotCi0vKioKLSAqIE5PTi1ET00gQ0xBU1M6IERlc2NyaWJlIG9uZSBvZiB0aGUgRWxlbWVudHMgKGFuZCBpdHMgYXNzb2NpYXRlZAotICogQXR0cmlidXRlcykgZGVmaW5lZCBpbiB0aGlzIERvY3VtZW50IFR5cGUuCi0gKiA8cD4KLSAqIEkndmUgaW5jbHVkZWQgdGhpcyBpbiBMZXZlbCAxIHB1cmVseSBhcyBhbiBhbmNob3IgcG9pbnQgZm9yIGRlZmF1bHQKLSAqIGF0dHJpYnV0ZXMuIEluIExldmVsIDIgaXQgc2hvdWxkIGVuYWJsZSB0aGUgQ2hpbGRSdWxlIHN1cHBvcnQuCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqLwotcHVibGljIGNsYXNzIEVsZW1lbnREZWZpbml0aW9uSW1wbAotICAgIGV4dGVuZHMgUGFyZW50Tm9kZSB7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0YW50cwotICAgIC8vCi0KLSAgICAvKiogU2VyaWFsaXphdGlvbiB2ZXJzaW9uLiAqLwotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtODM3Mzg5MDY3MjY3MDAyMjcxNEw7Ci0KLSAgICAvLwotICAgIC8vIERhdGEKLSAgICAvLwotCi0gICAgLyoqIEVsZW1lbnQgZGVmaW5pdGlvbiBuYW1lLiAqLwotICAgIHByb3RlY3RlZCBTdHJpbmcgbmFtZTsKLQotICAgIC8qKiBEZWZhdWx0IGF0dHJpYnV0ZXMuICovCi0gICAgcHJvdGVjdGVkIE5hbWVkTm9kZU1hcEltcGwgYXR0cmlidXRlczsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKiBGYWN0b3J5IGNvbnN0cnVjdG9yLiAqLwotICAgIHB1YmxpYyBFbGVtZW50RGVmaW5pdGlvbkltcGwoQ29yZURvY3VtZW50SW1wbCBvd25lckRvY3VtZW50LCBTdHJpbmcgbmFtZSkgewotICAgICAgICBzdXBlcihvd25lckRvY3VtZW50KTsKLSAgICAgICAgdGhpcy5uYW1lID0gbmFtZTsKLSAgICAgICAgYXR0cmlidXRlcyA9IG5ldyBOYW1lZE5vZGVNYXBJbXBsKG93bmVyRG9jdW1lbnQpOwotICAgIH0KLQotICAgIC8vCi0gICAgLy8gTm9kZSBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIEEgc2hvcnQgaW50ZWdlciBpbmRpY2F0aW5nIHdoYXQgdHlwZSBvZiBub2RlIHRoaXMgaXMuIFRoZSBuYW1lZAotICAgICAqIGNvbnN0YW50cyBmb3IgdGhpcyB2YWx1ZSBhcmUgZGVmaW5lZCBpbiB0aGUgb3JnLnczYy5kb20uTm9kZSBpbnRlcmZhY2UuCi0gICAgICovCi0gICAgcHVibGljIHNob3J0IGdldE5vZGVUeXBlKCkgewotICAgICAgICByZXR1cm4gTm9kZUltcGwuRUxFTUVOVF9ERUZJTklUSU9OX05PREU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgZWxlbWVudCBkZWZpbml0aW9uIG5hbWUKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE5vZGVOYW1lKCkgewotICAgICAgICBpZiAobmVlZHNTeW5jRGF0YSgpKSB7Ci0gICAgICAgICAgICBzeW5jaHJvbml6ZURhdGEoKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbmFtZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXBsaWNhdGUgdGhpcyBvYmplY3QuCi0gICAgICovCi0gICAgcHVibGljIE5vZGUgY2xvbmVOb2RlKGJvb2xlYW4gZGVlcCkgewotCi0gICAgICAgIEVsZW1lbnREZWZpbml0aW9uSW1wbCBuZXdub2RlID0KLSAgICAgICAgICAgIChFbGVtZW50RGVmaW5pdGlvbkltcGwpIHN1cGVyLmNsb25lTm9kZShkZWVwKTsKLSAgICAgICAgLy8gTmFtZWROb2RlTWFwIG11c3QgYmUgZXhwbGljaXRseSByZXBsaWNhdGVkIHRvIGF2b2lkIHNoYXJpbmcKLSAgICAgICAgbmV3bm9kZS5hdHRyaWJ1dGVzID0gYXR0cmlidXRlcy5jbG9uZU1hcChuZXdub2RlKTsKLSAgICAgICAgcmV0dXJuIG5ld25vZGU7Ci0KLSAgICB9IC8vIGNsb25lTm9kZShib29sZWFuKTpOb2RlCi0KLSAgICAvKioKLSAgICAgKiBRdWVyeSB0aGUgYXR0cmlidXRlcyBkZWZpbmVkIG9uIHRoaXMgRWxlbWVudC4KLSAgICAgKiA8cD4KLSAgICAgKiBJbiB0aGUgYmFzZSBpbXBsZW1lbnRhdGlvbiB0aGlzIE1hcCBzaW1wbHkgY29udGFpbnMgQXR0cmlidXRlIG9iamVjdHMKLSAgICAgKiByZXByZXNlbnRpbmcgdGhlIGRlZmF1bHRzLiBJbiBhIG1vcmUgc2VyaW91cyBpbXBsZW1lbnRhdGlvbiwgaXQgd291bGQKLSAgICAgKiBjb250YWluIEF0dHJpYnV0ZURlZmluaXRpb25JbXBsIG9iamVjdHMgZm9yIGFsbCBkZWNsYXJlZCBBdHRyaWJ1dGVzLAotICAgICAqIGluZGljYXRpbmcgd2hpY2ggYXJlIERlZmF1bHQsIERlZmF1bHRGaXhlZCwgSW1wbGljaXQgYW5kL29yIFJlcXVpcmVkLgotICAgICAqCi0gICAgICogQHJldHVybiBvcmcudzNjLmRvbS5OYW1lZE5vZGVNYXAgY29udGFpbmluZyBvcmcudzNjLmRvbS5BdHRyaWJ1dGUKLSAgICAgKi8KLSAgICBwdWJsaWMgTmFtZWROb2RlTWFwIGdldEF0dHJpYnV0ZXMoKSB7Ci0KLSAgICAgICAgaWYgKG5lZWRzU3luY0NoaWxkcmVuKCkpIHsKLSAgICAgICAgICAgIHN5bmNocm9uaXplQ2hpbGRyZW4oKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gYXR0cmlidXRlczsKLQotICAgIH0gLy8gZ2V0QXR0cmlidXRlcygpOk5hbWVkTm9kZU1hcAotCi19IC8vIGNsYXNzIEVsZW1lbnREZWZpbml0aW9uSW1wbApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL0VsZW1lbnRJbXBsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vRWxlbWVudEltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZTJjM2RlNC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vRWxlbWVudEltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExNzggKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDAyLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tOwotCi1pbXBvcnQgb3JnLnczYy5kb20uQXR0cjsKLWltcG9ydCBvcmcudzNjLmRvbS5ET01FeGNlcHRpb247Ci1pbXBvcnQgb3JnLnczYy5kb20uRWxlbWVudDsKLWltcG9ydCBvcmcudzNjLmRvbS5OYW1lZE5vZGVNYXA7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlTGlzdDsKLWltcG9ydCBvcmcudzNjLmRvbS5UZXh0OwotCi1pbXBvcnQgb3JnLnczYy5kb20uVHlwZUluZm87Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlVSSTsKLQotLyoqCi0gKiBFbGVtZW50cyByZXByZXNlbnQgbW9zdCBvZiB0aGUgIm1hcmt1cCIgYW5kIHN0cnVjdHVyZSBvZiB0aGUKLSAqIGRvY3VtZW50LiAgVGhleSBjb250YWluIGJvdGggdGhlIGRhdGEgZm9yIHRoZSBlbGVtZW50IGl0c2VsZgotICogKGVsZW1lbnQgbmFtZSBhbmQgYXR0cmlidXRlcyksIGFuZCBhbnkgY29udGFpbmVkIG5vZGVzLCBpbmNsdWRpbmcKLSAqIGRvY3VtZW50IHRleHQgKGFzIGNoaWxkcmVuKS4KLSAqIDxQPgotICogRWxlbWVudHMgbWF5IGhhdmUgQXR0cmlidXRlcyBhc3NvY2lhdGVkIHdpdGggdGhlbTsgdGhlIEFQSSBmb3IgdGhpcyBpcwotICogZGVmaW5lZCBpbiBOb2RlLCBidXQgdGhlIGZ1bmN0aW9uIGlzIGltcGxlbWVudGVkIGhlcmUuIEluIGdlbmVyYWwsIFhNTAotICogYXBwbGljYXRpb25zIHNob3VsZCByZXRyaXZlIEF0dHJpYnV0ZXMgYXMgTm9kZXMsIHNpbmNlIHRoZXkgbWF5IGNvbnRhaW4KLSAqIGVudGl0eSByZWZlcmVuY2VzIGFuZCBoZW5jZSBiZSBhIGZhaXJseSBjb21wbGV4IHN1Yi10cmVlLiBIVE1MIHVzZXJzIHdpbGwKLSAqIGJlIGRlYWxpbmcgd2l0aCBzaW1wbGUgc3RyaW5nIHZhbHVlcywgYW5kIGNvbnZlbmllbmNlIG1ldGhvZHMgYXJlIHByb3ZpZGVkCi0gKiB0byB3b3JrIGluIHRlcm1zIG9mIFN0cmluZ3MuCi0gKiA8UD4KLSAqIEVsZW1lbnRJbXBsIGRvZXMgbm90IHN1cHBvcnQgTmFtZXNwYWNlcy4gRWxlbWVudE5TSW1wbCwgd2hpY2ggaW5oZXJpdHMgZnJvbQotICogaXQsIGRvZXMuCi0gKiBAc2VlIEVsZW1lbnROU0ltcGwKLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBBcm5hdWQgIExlIEhvcnMsIElCTQotICogQGF1dGhvciBKb2UgS2Vzc2VsbWFuLCBJQk0KLSAqIEBhdXRob3IgQW5keSBDbGFyaywgSUJNCi0gKiBAYXV0aG9yIFJhbGYgUGZlaWZmZXIsIElCTQotICogQHNpbmNlICBQUi1ET00tTGV2ZWwtMS0xOTk4MDgxOC4KLSAqLwotcHVibGljIGNsYXNzIEVsZW1lbnRJbXBsCi0gICAgZXh0ZW5kcyBQYXJlbnROb2RlCi0gICAgaW1wbGVtZW50cyBFbGVtZW50LCBUeXBlSW5mbyB7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0YW50cwotICAgIC8vCi0KLSAgICAvKiogU2VyaWFsaXphdGlvbiB2ZXJzaW9uLiAqLwotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAzNzE3MjUzNTE2NjUyNzIyMjc4TDsKLSAgICAvLwotICAgIC8vIERhdGEKLSAgICAvLwotCi0gICAgLyoqIEVsZW1lbnQgbmFtZS4gKi8KLSAgICBwcm90ZWN0ZWQgU3RyaW5nIG5hbWU7Ci0KLSAgICAvKiogQXR0cmlidXRlcy4gKi8KLSAgICBwcm90ZWN0ZWQgQXR0cmlidXRlTWFwIGF0dHJpYnV0ZXM7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0cnVjdG9ycwotICAgIC8vCi0KLSAgICAvKiogRmFjdG9yeSBjb25zdHJ1Y3Rvci4gKi8KLSAgICBwdWJsaWMgRWxlbWVudEltcGwoQ29yZURvY3VtZW50SW1wbCBvd25lckRvYywgU3RyaW5nIG5hbWUpIHsKLSAgICAgICAgc3VwZXIob3duZXJEb2MpOwotICAgICAgICB0aGlzLm5hbWUgPSBuYW1lOwotICAgICAgICBuZWVkc1N5bmNEYXRhKHRydWUpOyAgICAvLyBzeW5jaHJvbml6ZURhdGEgd2lsbCBpbml0aWFsaXplIGF0dHJpYnV0ZXMKLSAgICB9Ci0KLSAgICAvLyBmb3IgRWxlbWVudE5TSW1wbAotICAgIHByb3RlY3RlZCBFbGVtZW50SW1wbCgpIHt9Ci0KLSAgICAvLyBTdXBwb3J0IGZvciBET00gTGV2ZWwgMyByZW5hbWVOb2RlIG1ldGhvZC4KLSAgICAvLyBOb3RlOiBUaGlzIG9ubHkgZGVhbHMgd2l0aCBwYXJ0IG9mIHRoZSBwYi4gQ29yZURvY3VtZW50SW1wbAotICAgIC8vIGRvZXMgYWxsIHRoZSB3b3JrLgotICAgIHZvaWQgcmVuYW1lKFN0cmluZyBuYW1lKSB7Ci0gICAgICAgIGlmIChuZWVkc1N5bmNEYXRhKCkpIHsKLSAgICAgICAgICAgIHN5bmNocm9uaXplRGF0YSgpOwotICAgICAgICB9Ci0gICAgICAgICAgICB0aGlzLm5hbWUgPSBuYW1lOwotICAgICAgICByZWNvbmNpbGVEZWZhdWx0QXR0cmlidXRlcygpOwotICAgIH0KLQotICAgIC8vCi0gICAgLy8gTm9kZSBtZXRob2RzCi0gICAgLy8KLQotCi0gICAgLyoqCi0gICAgICogQSBzaG9ydCBpbnRlZ2VyIGluZGljYXRpbmcgd2hhdCB0eXBlIG9mIG5vZGUgdGhpcyBpcy4gVGhlIG5hbWVkCi0gICAgICogY29uc3RhbnRzIGZvciB0aGlzIHZhbHVlIGFyZSBkZWZpbmVkIGluIHRoZSBvcmcudzNjLmRvbS5Ob2RlIGludGVyZmFjZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc2hvcnQgZ2V0Tm9kZVR5cGUoKSB7Ci0gICAgICAgIHJldHVybiBOb2RlLkVMRU1FTlRfTk9ERTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBlbGVtZW50IG5hbWUKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE5vZGVOYW1lKCkgewotICAgICAgICBpZiAobmVlZHNTeW5jRGF0YSgpKSB7Ci0gICAgICAgICAgICBzeW5jaHJvbml6ZURhdGEoKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbmFtZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXRyaWV2ZSBhbGwgdGhlIEF0dHJpYnV0ZXMgYXMgYSBzZXQuIE5vdGUgdGhhdCB0aGlzIEFQSSBpcyBpbmhlcml0ZWQKLSAgICAgKiBmcm9tIE5vZGUgcmF0aGVyIHRoYW4gc3BlY2lmaWVkIG9uIEVsZW1lbnQ7IGluIGZhY3Qgb25seSBFbGVtZW50cyB3aWxsCi0gICAgICogZXZlciBoYXZlIEF0dHJpYnV0ZXMsIGJ1dCB0aGV5IHdhbnQgdG8gYWxsb3cgZm9sa3MgdG8gImJsaW5kbHkiIG9wZXJhdGUKLSAgICAgKiBvbiB0aGUgdHJlZSBhcyBhIHNldCBvZiBOb2Rlcy4KLSAgICAgKi8KLSAgICBwdWJsaWMgTmFtZWROb2RlTWFwIGdldEF0dHJpYnV0ZXMoKSB7Ci0KLSAgICAgICAgaWYgKG5lZWRzU3luY0RhdGEoKSkgewotICAgICAgICAgICAgc3luY2hyb25pemVEYXRhKCk7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGF0dHJpYnV0ZXMgPT0gbnVsbCkgewotICAgICAgICAgICAgYXR0cmlidXRlcyA9IG5ldyBBdHRyaWJ1dGVNYXAodGhpcywgbnVsbCk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGF0dHJpYnV0ZXM7Ci0KLSAgICB9IC8vIGdldEF0dHJpYnV0ZXMoKTpOYW1lZE5vZGVNYXAKLQotICAgIC8qKgotICAgICAqIFJldHVybiBhIGR1cGxpY2F0ZSBjb3B5IG9mIHRoaXMgRWxlbWVudC4gTm90ZSB0aGF0IGl0cyBjaGlsZHJlbgotICAgICAqIHdpbGwgbm90IGJlIGNvcGllZCB1bmxlc3MgdGhlICJkZWVwIiBmbGFnIGlzIHRydWUsIGJ1dCBBdHRyaWJ1dGVzCi0gICAgICogYXJlIDxpPmFsd2F5czwvaT4gcmVwbGljYXRlZC4KLSAgICAgKgotICAgICAqIEBzZWUgb3JnLnczYy5kb20uTm9kZSNjbG9uZU5vZGUoYm9vbGVhbikKLSAgICAgKi8KLSAgICBwdWJsaWMgTm9kZSBjbG9uZU5vZGUoYm9vbGVhbiBkZWVwKSB7Ci0KLSAgICAgICAgRWxlbWVudEltcGwgbmV3bm9kZSA9IChFbGVtZW50SW1wbCkgc3VwZXIuY2xvbmVOb2RlKGRlZXApOwotICAgICAgICAvLyBSZXBsaWNhdGUgTmFtZWROb2RlTWFwIHJhdGhlciB0aGFuIHNoYXJpbmcgaXQuCi0gICAgICAgIGlmIChhdHRyaWJ1dGVzICE9IG51bGwpIHsKLSAgICAgICAgICAgIG5ld25vZGUuYXR0cmlidXRlcyA9IChBdHRyaWJ1dGVNYXApIGF0dHJpYnV0ZXMuY2xvbmVNYXAobmV3bm9kZSk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG5ld25vZGU7Ci0KLSAgICB9IC8vIGNsb25lTm9kZShib29sZWFuKTpOb2RlCi0KLSAgIC8qKgotICAgICAqIERPTSBMZXZlbCAzIFdEIC0gRXhwZXJpbWVudGFsLgotICAgICAqIFJldHJpZXZlIGJhc2VVUkkKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEJhc2VVUkkoKSB7Ci0KLSAgICAgICAgaWYgKG5lZWRzU3luY0RhdGEoKSkgewotICAgICAgICAgICAgc3luY2hyb25pemVEYXRhKCk7Ci0gICAgICAgIH0KLSAgICAgICAgLy8gQWJzb2x1dGUgYmFzZSBVUkkgaXMgY29tcHV0ZWQgYWNjb3JkaW5nIHRvCi0gICAgICAgIC8vIFhNTCBCYXNlIChodHRwOi8vd3d3LnczLm9yZy9UUi94bWxiYXNlLyNncmFudWxhcml0eSkKLSAgICAgICAgLy8gMS4gVGhlIGJhc2UgVVJJIHNwZWNpZmllZCBieSBhbiB4bWw6YmFzZSBhdHRyaWJ1dGUgb24gdGhlIGVsZW1lbnQsCi0gICAgICAgIC8vIGlmIG9uZSBleGlzdHMKLSAgICAgICAgaWYgKGF0dHJpYnV0ZXMgIT0gbnVsbCkgewotICAgICAgICAgICAgQXR0ciBhdHRyTm9kZSA9IChBdHRyKWF0dHJpYnV0ZXMuZ2V0TmFtZWRJdGVtKCJ4bWw6YmFzZSIpOwotICAgICAgICAgICAgaWYgKGF0dHJOb2RlICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgdXJpID0gIGF0dHJOb2RlLmdldE5vZGVWYWx1ZSgpOwotICAgICAgICAgICAgICAgIGlmICh1cmkubGVuZ3RoKCkgIT0gMCApIHsvLyBhdHRyaWJ1dGUgdmFsdWUgaXMgYWx3YXlzIGVtcHR5IHN0cmluZwotICAgICAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICAgICB1cmkgPSBuZXcgVVJJKHVyaSkudG9TdHJpbmcoKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBjYXRjaCAoY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlVSSS5NYWxmb3JtZWRVUklFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhpcyBtYXkgYmUgYSByZWxhdGl2ZSBVUkkuCi0KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIE1ha2UgYW55IHBhcmVudFVSSSBpbnRvIGEgVVJJIG9iamVjdCB0byB1c2Ugd2l0aCB0aGUgVVJJKFVSSSwgU3RyaW5nKSBjb25zdHJ1Y3RvcgotICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHBhcmVudEJhc2VVUkkgPSAodGhpcy5vd25lck5vZGUgIT0gbnVsbCkgPyB0aGlzLm93bmVyTm9kZS5nZXRCYXNlVVJJKCkgOiBudWxsOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBhcmVudEJhc2VVUkkgIT0gbnVsbCl7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5ewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cmkgPSBuZXcgVVJJKG5ldyBVUkkocGFyZW50QmFzZVVSSSksIHVyaSkudG9TdHJpbmcoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2F0Y2ggKGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5VUkkuTWFsZm9ybWVkVVJJRXhjZXB0aW9uIGV4KXsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhpcyBzaG91bGQgbmV2ZXIgaGFwcGVuOiBwYXJlbnQgc2hvdWxkIGhhdmUgY2hlY2tlZCB0aGUgVVJJIGFuZCByZXR1cm5lZCBudWxsIGlmIGludmFsaWQuCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdXJpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHVyaTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyAyLnRoZSBiYXNlIFVSSSBvZiB0aGUgZWxlbWVudCdzIHBhcmVudCBlbGVtZW50IHdpdGhpbiB0aGUKLSAgICAgICAgLy8gZG9jdW1lbnQgb3IgZXh0ZXJuYWwgZW50aXR5LCBpZiBvbmUgZXhpc3RzCi0gICAgICAgICAgICAgICAgLy8gMy4gdGhlIGJhc2UgVVJJIG9mIHRoZSBkb2N1bWVudCBlbnRpdHkgb3IgZXh0ZXJuYWwgZW50aXR5Ci0gICAgICAgICAgICAgICAgLy8gY29udGFpbmluZyB0aGUgZWxlbWVudAotCi0gICAgICAgICAgICAgICAgLy8gb3duZXJOb2RlIHNlcnZlcyBhcyBhIHBhcmVudCBvciBhcyBkb2N1bWVudAotICAgICAgICAgICAgICAgIFN0cmluZyBiYXNlVVJJID0gKHRoaXMub3duZXJOb2RlICE9IG51bGwpID8gdGhpcy5vd25lck5vZGUuZ2V0QmFzZVVSSSgpIDogbnVsbCA7Ci0gICAgICAgIC8vYmFzZSBVUkkgb2YgcGFyZW50IGVsZW1lbnQgaXMgbm90IG51bGwKLSAgICAgICAgaWYoYmFzZVVSSSAhPSBudWxsKXsKLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgLy9yZXR1cm4gdmFsaWQgYWJzb2x1dGUgYmFzZSBVUkkKLSAgICAgICAgICAgICAgIHJldHVybiBuZXcgVVJJKGJhc2VVUkkpLnRvU3RyaW5nKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXRjaCAoY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlVSSS5NYWxmb3JtZWRVUklFeGNlcHRpb24gZSl7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfSAvL2dldEJhc2VVUkkKLQotCi0KLSAgICAvKioKLSAgICAgKiBOT04tRE9NCi0gICAgICogc2V0IHRoZSBvd25lckRvY3VtZW50IG9mIHRoaXMgbm9kZSwgaXRzIGNoaWxkcmVuLCBhbmQgaXRzIGF0dHJpYnV0ZXMKLSAgICAgKi8KLSAgICB2b2lkIHNldE93bmVyRG9jdW1lbnQoQ29yZURvY3VtZW50SW1wbCBkb2MpIHsKLSAgICAgICAgc3VwZXIuc2V0T3duZXJEb2N1bWVudChkb2MpOwotICAgICAgICBpZiAoYXR0cmlidXRlcyAhPSBudWxsKSB7Ci0gICAgICAgICAgICBhdHRyaWJ1dGVzLnNldE93bmVyRG9jdW1lbnQoZG9jKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8vCi0gICAgLy8gRWxlbWVudCBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIExvb2sgdXAgYSBzaW5nbGUgQXR0cmlidXRlIGJ5IG5hbWUuIFJldHVybnMgdGhlIEF0dHJpYnV0ZSdzCi0gICAgICogc3RyaW5nIHZhbHVlLCBvciBhbiBlbXB0eSBzdHJpbmcgKE5PVCBudWxsISkgdG8gaW5kaWNhdGUgdGhhdCB0aGUKLSAgICAgKiBuYW1lIGRpZCBub3QgbWFwIHRvIGEgY3VycmVudGx5IGRlZmluZWQgYXR0cmlidXRlLgotICAgICAqIDxwPgotICAgICAqIE5vdGU6IEF0dHJpYnV0ZXMgbWF5IGNvbnRhaW4gY29tcGxleCBub2RlIHRyZWVzLiBUaGlzIG1ldGhvZAotICAgICAqIHJldHVybnMgdGhlICJmbGF0dGVuZWQiIHN0cmluZyBvYnRhaW5lZCBmcm9tIEF0dHJpYnV0ZS5nZXRWYWx1ZSgpLgotICAgICAqIElmIHlvdSBuZWVkIHRoZSBzdHJ1Y3R1cmUgaW5mb3JtYXRpb24sIHNlZSBnZXRBdHRyaWJ1dGVOb2RlKCkuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRBdHRyaWJ1dGUoU3RyaW5nIG5hbWUpIHsKLQotICAgICAgICBpZiAobmVlZHNTeW5jRGF0YSgpKSB7Ci0gICAgICAgICAgICBzeW5jaHJvbml6ZURhdGEoKTsKLSAgICAgICAgfQotICAgICAgICBpZiAoYXR0cmlidXRlcyA9PSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gIiI7Ci0gICAgICAgIH0KLSAgICAgICAgQXR0ciBhdHRyID0gKEF0dHIpKGF0dHJpYnV0ZXMuZ2V0TmFtZWRJdGVtKG5hbWUpKTsKLSAgICAgICAgcmV0dXJuIChhdHRyID09IG51bGwpID8gIiIgOiBhdHRyLmdldFZhbHVlKCk7Ci0KLSAgICB9IC8vIGdldEF0dHJpYnV0ZShTdHJpbmcpOlN0cmluZwotCi0KLSAgICAvKioKLSAgICAgKiBMb29rIHVwIGEgc2luZ2xlIEF0dHJpYnV0ZSBieSBuYW1lLiBSZXR1cm5zIHRoZSBBdHRyaWJ1dGUgTm9kZSwKLSAgICAgKiBzbyBpdHMgY29tcGxldGUgY2hpbGQgdHJlZSBpcyBhdmFpbGFibGUuIFRoaXMgY291bGQgYmUgaW1wb3J0YW50IGluCi0gICAgICogWE1MLCB3aGVyZSB0aGUgc3RyaW5nIHJlbmRlcmluZyBtYXkgbm90IGJlIHN1ZmZpY2llbnQgaW5mb3JtYXRpb24uCi0gICAgICogPHA+Ci0gICAgICogSWYgbm8gbWF0Y2hpbmcgYXR0cmlidXRlIGlzIGF2YWlsYWJsZSwgcmV0dXJucyBudWxsLgotICAgICAqLwotICAgIHB1YmxpYyBBdHRyIGdldEF0dHJpYnV0ZU5vZGUoU3RyaW5nIG5hbWUpIHsKLQotICAgICAgICBpZiAobmVlZHNTeW5jRGF0YSgpKSB7Ci0gICAgICAgICAgICBzeW5jaHJvbml6ZURhdGEoKTsKLSAgICAgICAgfQotICAgICAgICBpZiAoYXR0cmlidXRlcyA9PSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gKEF0dHIpYXR0cmlidXRlcy5nZXROYW1lZEl0ZW0obmFtZSk7Ci0KLSAgICB9IC8vIGdldEF0dHJpYnV0ZU5vZGUoU3RyaW5nKTpBdHRyCi0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYSBOb2RlTGlzdCBvZiBhbGwgZGVzY2VuZGVudCBub2RlcyAoY2hpbGRyZW4sCi0gICAgICogZ3JhbmRjaGlsZHJlbiwgYW5kIHNvIG9uKSB3aGljaCBhcmUgRWxlbWVudHMgYW5kIHdoaWNoIGhhdmUgdGhlCi0gICAgICogc3BlY2lmaWVkIHRhZyBuYW1lLgotICAgICAqIDxwPgotICAgICAqIE5vdGU6IE5vZGVMaXN0IGlzIGEgImxpdmUiIHZpZXcgb2YgdGhlIERPTS4gSXRzIGNvbnRlbnRzIHdpbGwKLSAgICAgKiBjaGFuZ2UgYXMgdGhlIERPTSBjaGFuZ2VzLCBhbmQgYWx0ZXJhdGlvbnMgbWFkZSB0byB0aGUgTm9kZUxpc3QKLSAgICAgKiB3aWxsIGJlIHJlZmxlY3RlZCBpbiB0aGUgRE9NLgotICAgICAqCi0gICAgICogQHBhcmFtIHRhZ25hbWUgVGhlIHR5cGUgb2YgZWxlbWVudCB0byBnYXRoZXIuIFRvIG9idGFpbiBhIGxpc3Qgb2YKLSAgICAgKiBhbGwgZWxlbWVudHMgbm8gbWF0dGVyIHdoYXQgdGhlaXIgbmFtZXMsIHVzZSB0aGUgd2lsZC1jYXJkIHRhZwotICAgICAqIG5hbWUgIioiLgotICAgICAqCi0gICAgICogQHNlZSBEZWVwTm9kZUxpc3RJbXBsCi0gICAgICovCi0gICAgcHVibGljIE5vZGVMaXN0IGdldEVsZW1lbnRzQnlUYWdOYW1lKFN0cmluZyB0YWduYW1lKSB7Ci0gICAgICAgIHJldHVybiBuZXcgRGVlcE5vZGVMaXN0SW1wbCh0aGlzLHRhZ25hbWUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhlIEVsZW1lbnQuIE5vdGUgdGhhdCBFbGVtZW50Lm5vZGVOYW1lKCkgaXMKLSAgICAgKiBkZWZpbmVkIHRvIGFsc28gcmV0dXJuIHRoZSB0YWcgbmFtZS4KLSAgICAgKiA8cD4KLSAgICAgKiBUaGlzIGlzIGNhc2UtcHJlc2VydmluZyBpbiBYTUwuIEhUTUwgc2hvdWxkIHVwcGVyY2FzaWZ5IGl0IG9uIHRoZQotICAgICAqIHdheSBpbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFRhZ05hbWUoKSB7Ci0gICAgICAgIGlmIChuZWVkc1N5bmNEYXRhKCkpIHsKLSAgICAgICAgICAgIHN5bmNocm9uaXplRGF0YSgpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBuYW1lOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEluICJub3JtYWwgZm9ybSIgKGFzIHJlYWQgZnJvbSBhIHNvdXJjZSBmaWxlKSwgdGhlcmUgd2lsbCBuZXZlciBiZSB0d28KLSAgICAgKiBUZXh0IGNoaWxkcmVuIGluIHN1Y2Nlc3Npb24uIEJ1dCBET00gdXNlcnMgbWF5IGNyZWF0ZSBzdWNjZXNzaXZlIFRleHQKLSAgICAgKiBub2RlcyBpbiB0aGUgY291cnNlIG9mIG1hbmlwdWxhdGluZyB0aGUgZG9jdW1lbnQuIE5vcm1hbGl6ZSB3YWxrcyB0aGUKLSAgICAgKiBzdWItdHJlZSBhbmQgbWVyZ2VzIGFkamFjZW50IFRleHRzLCBhcyBpZiB0aGUgRE9NIGhhZCBiZWVuIHdyaXR0ZW4gb3V0Ci0gICAgICogYW5kIHJlYWQgYmFjayBpbiBhZ2Fpbi4gVGhpcyBzaW1wbGlmaWVzIGltcGxlbWVudGF0aW9uIG9mIGhpZ2hlci1sZXZlbAotICAgICAqIGZ1bmN0aW9ucyB0aGF0IG1heSB3YW50IHRvIGFzc3VtZSB0aGF0IHRoZSBkb2N1bWVudCBpcyBpbiBzdGFuZGFyZCBmb3JtLgotICAgICAqIDxwPgotICAgICAqIFRvIG5vcm1hbGl6ZSBhIERvY3VtZW50LCBub3JtYWxpemUgaXRzIHRvcC1sZXZlbCBFbGVtZW50IGNoaWxkLgotICAgICAqIDxwPgotICAgICAqIEFzIG9mIFBSLURPTS1MZXZlbC0xLTE5OTgwODE4LCBDREFUQSAtLSBkZXNwaXRlIGJlaW5nIGEgc3ViY2xhc3Mgb2YKLSAgICAgKiBUZXh0IC0tIGlzIGNvbnNpZGVyZWQgIm1hcmt1cCIgYW5kIHdpbGwgX25vdF8gYmUgbWVyZ2VkIGVpdGhlciB3aXRoCi0gICAgICogbm9ybWFsIFRleHQgb3Igd2l0aCBvdGhlciBDREFUQVNlY3Rpb25zLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIG5vcm1hbGl6ZSgpIHsKLSAgICAgICAgLy8gTm8gbmVlZCB0byBub3JtYWxpemUgaWYgYWxyZWFkeSBub3JtYWxpemVkLgotICAgICAgICBpZiAoaXNOb3JtYWxpemVkKCkpIHsKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotICAgICAgICBpZiAobmVlZHNTeW5jQ2hpbGRyZW4oKSkgewotICAgICAgICAgICAgc3luY2hyb25pemVDaGlsZHJlbigpOwotICAgICAgICB9Ci0gICAgICAgIENoaWxkTm9kZSBraWQsIG5leHQ7Ci0gICAgICAgIGZvciAoa2lkID0gZmlyc3RDaGlsZDsga2lkICE9IG51bGw7IGtpZCA9IG5leHQpIHsKLSAgICAgICAgICAgIG5leHQgPSBraWQubmV4dFNpYmxpbmc7Ci0KLSAgICAgICAgICAgIC8vIElmIGtpZCBpcyBhIHRleHQgbm9kZSwgd2UgbmVlZCB0byBjaGVjayBmb3Igb25lIG9mIHR3bwotICAgICAgICAgICAgLy8gY29uZGl0aW9uczoKLSAgICAgICAgICAgIC8vICAgMSkgVGhlcmUgaXMgYW4gYWRqYWNlbnQgdGV4dCBub2RlCi0gICAgICAgICAgICAvLyAgIDIpIFRoZXJlIGlzIG5vIGFkamFjZW50IHRleHQgbm9kZSwgYnV0IGtpZCBpcwotICAgICAgICAgICAgLy8gICAgICBhbiBlbXB0eSB0ZXh0IG5vZGUuCi0gICAgICAgICAgICBpZiAoIGtpZC5nZXROb2RlVHlwZSgpID09IE5vZGUuVEVYVF9OT0RFICkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAvLyBJZiBhbiBhZGphY2VudCB0ZXh0IG5vZGUsIG1lcmdlIGl0IHdpdGgga2lkCi0gICAgICAgICAgICAgICAgaWYgKCBuZXh0IT1udWxsICYmIG5leHQuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLlRFWFRfTk9ERSApCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAoKFRleHQpa2lkKS5hcHBlbmREYXRhKG5leHQuZ2V0Tm9kZVZhbHVlKCkpOwotICAgICAgICAgICAgICAgICAgICByZW1vdmVDaGlsZCggbmV4dCApOwotICAgICAgICAgICAgICAgICAgICBuZXh0ID0ga2lkOyAvLyBEb24ndCBhZHZhbmNlOyB0aGVyZSBtaWdodCBiZSBhbm90aGVyLgotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAvLyBJZiBraWQgaXMgZW1wdHksIHJlbW92ZSBpdAotICAgICAgICAgICAgICAgICAgICBpZiAoIGtpZC5nZXROb2RlVmFsdWUoKSA9PSBudWxsIHx8IGtpZC5nZXROb2RlVmFsdWUoKS5sZW5ndGgoKSA9PSAwICkgewotICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlQ2hpbGQoIGtpZCApOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBPdGhlcndpc2UgaXQgbWlnaHQgYmUgYW4gRWxlbWVudCwgd2hpY2ggaXMgaGFuZGxlZCByZWN1cnNpdmVseQotICAgICAgICAgICAgZWxzZSBpZiAoa2lkLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5FTEVNRU5UX05PREUpIHsKLSAgICAgICAgICAgICAgICBraWQubm9ybWFsaXplKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBXZSBtdXN0IGFsc28gbm9ybWFsaXplIGFsbCBvZiB0aGUgYXR0cmlidXRlcwotICAgICAgICBpZiAoIGF0dHJpYnV0ZXMhPW51bGwgKQotICAgICAgICB7Ci0gICAgICAgICAgICBmb3IoIGludCBpPTA7IGk8YXR0cmlidXRlcy5nZXRMZW5ndGgoKTsgKytpICkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBOb2RlIGF0dHIgPSBhdHRyaWJ1dGVzLml0ZW0oaSk7Ci0gICAgICAgICAgICAgICAgYXR0ci5ub3JtYWxpemUoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIGNoYW5nZWQoKSB3aWxsIGhhdmUgb2NjdXJyZWQgd2hlbiB0aGUgcmVtb3ZlQ2hpbGQoKSB3YXMgZG9uZSwKLSAgICAgICAgLy8gc28gZG9lcyBub3QgaGF2ZSB0byBiZSByZWlzc3VlZC4KLQotICAgICAgICBpc05vcm1hbGl6ZWQodHJ1ZSk7Ci0gICAgfSAvLyBub3JtYWxpemUoKQotCi0gICAgLyoqCi0gICAgICogUmVtb3ZlIHRoZSBuYW1lZCBhdHRyaWJ1dGUgZnJvbSB0aGlzIEVsZW1lbnQuIElmIHRoZSByZW1vdmVkCi0gICAgICogQXR0cmlidXRlIGhhcyBhIGRlZmF1bHQgdmFsdWUsIGl0IGlzIGltbWVkaWF0ZWx5IHJlcGxhY2VkIHRoZXJlYnkuCi0gICAgICogPFA+Ci0gICAgICogVGhlIGRlZmF1bHQgbG9naWMgaXMgYWN0dWFsbHkgaW1wbGVtZW50ZWQgaW4gTmFtZWROb2RlTWFwSW1wbC4KLSAgICAgKiBQUi1ET00tTGV2ZWwtMS0xOTk4MDgxOCBkb2Vzbid0IGZ1bGx5IGFkZHJlc3MgdGhlIERURCwgc28gc29tZQotICAgICAqIG9mIHRoaXMgYmVoYXZpb3IgaXMgbGlrZWx5IHRvIGNoYW5nZSBpbiBmdXR1cmUgdmVyc2lvbnMuID8/Pz8/Ci0gICAgICogPFA+Ci0gICAgICogTm90ZSB0aGF0IHRoaXMgY2FsbCAic3VjY2VlZHMiIGV2ZW4gaWYgbm8gYXR0cmlidXRlIGJ5IHRoaXMgbmFtZQotICAgICAqIGV4aXN0ZWQgLS0gdW5saWtlIHJlbW92ZUF0dHJpYnV0ZU5vZGUsIHdoaWNoIHdpbGwgdGhyb3cgYSBub3QtZm91bmQKLSAgICAgKiBleGNlcHRpb24gaW4gdGhhdCBjYXNlLgotICAgICAqCi0gICAgICogQHRocm93cyBET01FeGNlcHRpb24oTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSKSBpZiB0aGUgbm9kZSBpcwotICAgICAqIHJlYWRvbmx5LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHJlbW92ZUF0dHJpYnV0ZShTdHJpbmcgbmFtZSkgewotCi0gICAgICAgIGlmIChvd25lckRvY3VtZW50LmVycm9yQ2hlY2tpbmcgJiYgaXNSZWFkT25seSgpKSB7Ci0gICAgICAgICAgICBTdHJpbmcgbXNnID0gRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwgIk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiIsIG51bGwpOwotICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSLCBtc2cpOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKG5lZWRzU3luY0RhdGEoKSkgewotICAgICAgICAgICAgc3luY2hyb25pemVEYXRhKCk7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoYXR0cmlidXRlcyA9PSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLQotICAgICAgICBhdHRyaWJ1dGVzLnNhZmVSZW1vdmVOYW1lZEl0ZW0obmFtZSk7Ci0KLSAgICB9IC8vIHJlbW92ZUF0dHJpYnV0ZShTdHJpbmcpCi0KLQotICAgIC8qKgotICAgICAqIFJlbW92ZSB0aGUgc3BlY2lmaWVkIGF0dHJpYnV0ZS92YWx1ZSBwYWlyLiBJZiB0aGUgcmVtb3ZlZAotICAgICAqIEF0dHJpYnV0ZSBoYXMgYSBkZWZhdWx0IHZhbHVlLCBpdCBpcyBpbW1lZGlhdGVseSByZXBsYWNlZC4KLSAgICAgKiA8cD4KLSAgICAgKiBOT1RFOiBTcGVjaWZpY2FsbHkgcmVtb3ZlcyBUSElTIE5PREUgLS0gbm90IHRoZSBub2RlIHdpdGggdGhpcwotICAgICAqIG5hbWUsIG5vciB0aGUgbm9kZSB3aXRoIHRoZXNlIGNvbnRlbnRzLiBJZiB0aGUgc3BlY2lmaWMgQXR0cmlidXRlCi0gICAgICogb2JqZWN0IHBhc3NlZCBpbiBpcyBub3Qgc3RvcmVkIGluIHRoaXMgRWxlbWVudCwgd2UgdGhyb3cgYQotICAgICAqIERPTUV4Y2VwdGlvbi4gIElmIHlvdSByZWFsbHkgd2FudCB0byByZW1vdmUgYW4gYXR0cmlidXRlIGJ5IG5hbWUsCi0gICAgICogdXNlIHJlbW92ZUF0dHJpYnV0ZSgpLgotICAgICAqCi0gICAgICogQHJldHVybiB0aGUgQXR0cmlidXRlIG9iamVjdCB0aGF0IHdhcyByZW1vdmVkLgotICAgICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uKE5PVF9GT1VORF9FUlIpIGlmIG9sZGF0dHIgaXMgbm90IGFuIGF0dHJpYnV0ZSBvZgotICAgICAqIHRoaXMgRWxlbWVudC4KLSAgICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbihOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIpIGlmIHRoZSBub2RlIGlzCi0gICAgICogcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIEF0dHIgcmVtb3ZlQXR0cmlidXRlTm9kZShBdHRyIG9sZEF0dHIpCi0gICAgICAgIHRocm93cyBET01FeGNlcHRpb24gewotCi0gICAgICAgIGlmIChvd25lckRvY3VtZW50LmVycm9yQ2hlY2tpbmcgJiYgaXNSZWFkT25seSgpKSB7Ci0gICAgICAgICAgICBTdHJpbmcgbXNnID0gRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwgIk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiIsIG51bGwpOwotICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSLCBtc2cpOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKG5lZWRzU3luY0RhdGEoKSkgewotICAgICAgICAgICAgc3luY2hyb25pemVEYXRhKCk7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoYXR0cmlidXRlcyA9PSBudWxsKSB7Ci0gICAgICAgICAgICBTdHJpbmcgbXNnID0gRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwgIk5PVF9GT1VORF9FUlIiLCBudWxsKTsKLSAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9GT1VORF9FUlIsIG1zZyk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIChBdHRyKSBhdHRyaWJ1dGVzLnJlbW92ZUl0ZW0ob2xkQXR0ciwgdHJ1ZSk7Ci0KLSAgICB9IC8vIHJlbW92ZUF0dHJpYnV0ZU5vZGUoQXR0cik6QXR0cgotCi0KLSAgICAvKioKLSAgICAgKiBBZGQgYSBuZXcgbmFtZS92YWx1ZSBwYWlyLCBvciByZXBsYWNlIHRoZSB2YWx1ZSBvZiB0aGUgZXhpc3RpbmcKLSAgICAgKiBhdHRyaWJ1dGUgaGF2aW5nIHRoYXQgbmFtZS4KLSAgICAgKgotICAgICAqIE5vdGU6IHRoaXMgbWV0aG9kIHN1cHBvcnRzIG9ubHkgdGhlIHNpbXBsZXN0IGtpbmQgb2YgQXR0cmlidXRlLAotICAgICAqIG9uZSB3aG9zZSB2YWx1ZSBpcyBhIHN0cmluZyBjb250YWluZWQgaW4gYSBzaW5nbGUgVGV4dCBub2RlLgotICAgICAqIElmIHlvdSB3YW50IHRvIGFzc2VydCBhIG1vcmUgY29tcGxleCB2YWx1ZSAod2hpY2ggWE1MIHBlcm1pdHMsCi0gICAgICogdGhvdWdoIEhUTUwgZG9lc24ndCksIHNlZSBzZXRBdHRyaWJ1dGVOb2RlKCkuCi0gICAgICoKLSAgICAgKiBUaGUgYXR0cmlidXRlIGlzIGNyZWF0ZWQgd2l0aCBzcGVjaWZpZWQ9dHJ1ZSwgbWVhbmluZyBpdCdzIGFuCi0gICAgICogZXhwbGljaXQgdmFsdWUgcmF0aGVyIHRoYW4gaW5oZXJpdGVkIGZyb20gdGhlIERURCBhcyBhIGRlZmF1bHQuCi0gICAgICogQWdhaW4sIHNldEF0dHJpYnV0ZU5vZGUgY2FuIGJlIHVzZWQgdG8gYWNoaWV2ZSBvdGhlciByZXN1bHRzLgotICAgICAqCi0gICAgICogQHRocm93cyBET01FeGNlcHRpb24oSU5WQUxJRF9OQU1FX0VSUikgaWYgdGhlIG5hbWUgaXMgbm90IGFjY2VwdGFibGUuCi0gICAgICogKEF0dHJpYnV0ZSBmYWN0b3J5IHdpbGwgZG8gdGhhdCB0ZXN0IGZvciB1cy4pCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbihOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIpIGlmIHRoZSBub2RlIGlzCi0gICAgICogcmVhZG9ubHkuCi0gICAgICovCi0gICAgICAgIHB1YmxpYyB2b2lkIHNldEF0dHJpYnV0ZShTdHJpbmcgbmFtZSwgU3RyaW5nIHZhbHVlKSB7Ci0KLSAgICAgICAgICAgICAgICBpZiAob3duZXJEb2N1bWVudC5lcnJvckNoZWNraW5nICYmIGlzUmVhZE9ubHkoKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG1zZyA9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZSgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIsIG1zZyk7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgaWYgKG5lZWRzU3luY0RhdGEoKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgc3luY2hyb25pemVEYXRhKCk7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgQXR0ciBuZXdBdHRyID0gZ2V0QXR0cmlidXRlTm9kZShuYW1lKTsKLSAgICAgICAgICAgICAgICBpZiAobmV3QXR0ciA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBuZXdBdHRyID0gZ2V0T3duZXJEb2N1bWVudCgpLmNyZWF0ZUF0dHJpYnV0ZShuYW1lKTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGF0dHJpYnV0ZXMgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzID0gbmV3IEF0dHJpYnV0ZU1hcCh0aGlzLCBudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAgICAgbmV3QXR0ci5zZXROb2RlVmFsdWUodmFsdWUpOwotICAgICAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlcy5zZXROYW1lZEl0ZW0obmV3QXR0cik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgbmV3QXR0ci5zZXROb2RlVmFsdWUodmFsdWUpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICB9IC8vIHNldEF0dHJpYnV0ZShTdHJpbmcsU3RyaW5nKQotCi0gICAgLyoqCi0gICAgICogQWRkIGEgbmV3IGF0dHJpYnV0ZS92YWx1ZSBwYWlyLCBvciByZXBsYWNlIHRoZSB2YWx1ZSBvZiB0aGUKLSAgICAgKiBleGlzdGluZyBhdHRyaWJ1dGUgd2l0aCB0aGF0IG5hbWUuCi0gICAgICogPFA+Ci0gICAgICogVGhpcyBtZXRob2QgYWxsb3dzIHlvdSB0byBhZGQgYW4gQXR0cmlidXRlIHRoYXQgaGFzIGFscmVhZHkgYmVlbgotICAgICAqIGNvbnN0cnVjdGVkLCBhbmQgaGVuY2UgYXZvaWRzIHRoZSBsaW1pdGF0aW9ucyBvZiB0aGUgc2ltcGxlCi0gICAgICogc2V0QXR0cmlidXRlKCkgY2FsbC4gSXQgY2FuIGhhbmRsZSBhdHRyaWJ1dGUgdmFsdWVzIHRoYXQgaGF2ZQotICAgICAqIGFyYml0cmFyaWx5IGNvbXBsZXggdHJlZSBzdHJ1Y3R1cmUgLS0gaW4gcGFydGljdWxhciwgdGhvc2Ugd2hpY2gKLSAgICAgKiBoYWQgZW50aXR5IHJlZmVyZW5jZXMgbWl4ZWQgaW50byB0aGVpciB0ZXh0LgotICAgICAqCi0gICAgICogQHRocm93cyBET01FeGNlcHRpb24oSU5VU0VfQVRUUklCVVRFX0VSUikgaWYgdGhlIEF0dHJpYnV0ZSBvYmplY3QKLSAgICAgKiBoYXMgYWxyZWFkeSBiZWVuIGFzc2lnbmVkIHRvIGFub3RoZXIgRWxlbWVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgQXR0ciBzZXRBdHRyaWJ1dGVOb2RlKEF0dHIgbmV3QXR0cikKLSAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgICAgICB7Ci0KLSAgICAgICAgaWYgKG5lZWRzU3luY0RhdGEoKSkgewotICAgICAgICAgICAgc3luY2hyb25pemVEYXRhKCk7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAob3duZXJEb2N1bWVudC5lcnJvckNoZWNraW5nKSB7Ci0gICAgICAgICAgICBpZiAoaXNSZWFkT25seSgpKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIG1zZyA9IERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sICJOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIiLCBudWxsKTsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERPTUV4Y2VwdGlvbi5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXNnKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKG5ld0F0dHIuZ2V0T3duZXJEb2N1bWVudCgpICE9IG93bmVyRG9jdW1lbnQpIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgbXNnID0gRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwgIldST05HX0RPQ1VNRU5UX0VSUiIsIG51bGwpOwotICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5XUk9OR19ET0NVTUVOVF9FUlIsIG1zZyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoYXR0cmlidXRlcyA9PSBudWxsKSB7Ci0gICAgICAgICAgICBhdHRyaWJ1dGVzID0gbmV3IEF0dHJpYnV0ZU1hcCh0aGlzLCBudWxsKTsKLSAgICAgICAgfQotICAgICAgICAvLyBUaGlzIHdpbGwgdGhyb3cgSU5VU0UgaWYgbmVjZXNzYXJ5Ci0gICAgICAgIHJldHVybiAoQXR0cikgYXR0cmlidXRlcy5zZXROYW1lZEl0ZW0obmV3QXR0cik7Ci0KLSAgICB9IC8vIHNldEF0dHJpYnV0ZU5vZGUoQXR0cik6QXR0cgotCi0gICAgLy8KLSAgICAvLyBET00yOiBOYW1lc3BhY2UgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBJbnRyb2R1Y2VkIGluIERPTSBMZXZlbCAyLiA8cD4KLSAgICAgKgotICAgICAqIFJldHJpZXZlcyBhbiBhdHRyaWJ1dGUgdmFsdWUgYnkgbG9jYWwgbmFtZSBhbmQgbmFtZXNwYWNlIFVSSS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBUaGUgbmFtZXNwYWNlIFVSSSBvZiB0aGUgYXR0cmlidXRlIHRvCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgcmV0cmlldmUuCi0gICAgICogQHBhcmFtIGxvY2FsTmFtZSAgICAgVGhlIGxvY2FsIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZSB0byByZXRyaWV2ZS4KLSAgICAgKiBAcmV0dXJuIFN0cmluZyAgICAgICBUaGUgQXR0ciB2YWx1ZSBhcyBhIHN0cmluZywgb3IgZW1wdHkgc3RyaW5nCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgaWYgdGhhdCBhdHRyaWJ1dGUKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBkb2VzIG5vdCBoYXZlIGEgc3BlY2lmaWVkIG9yIGRlZmF1bHQgdmFsdWUuCi0gICAgICogQHNpbmNlIFdELURPTS1MZXZlbC0yLTE5OTkwOTIzCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRBdHRyaWJ1dGVOUyhTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgbG9jYWxOYW1lKSB7Ci0KLSAgICAgICAgaWYgKG5lZWRzU3luY0RhdGEoKSkgewotICAgICAgICAgICAgc3luY2hyb25pemVEYXRhKCk7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoYXR0cmlidXRlcyA9PSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gIiI7Ci0gICAgICAgIH0KLQotICAgICAgICBBdHRyIGF0dHIgPSAoQXR0cikoYXR0cmlidXRlcy5nZXROYW1lZEl0ZW1OUyhuYW1lc3BhY2VVUkksIGxvY2FsTmFtZSkpOwotICAgICAgICByZXR1cm4gKGF0dHIgPT0gbnVsbCkgPyAiIiA6IGF0dHIuZ2V0VmFsdWUoKTsKLQotICAgIH0gLy8gZ2V0QXR0cmlidXRlTlMoU3RyaW5nLFN0cmluZyk6U3RyaW5nCi0KLSAgICAvKioKLSAgICAgKiBJbnRyb2R1Y2VkIGluIERPTSBMZXZlbCAyLiA8cD4KLSAgICAgKgotICAgICAqICBBZGRzIGEgbmV3IGF0dHJpYnV0ZS4KLSAgICAgKiAgSWYgdGhlIGdpdmVuIG5hbWVzcGFjZVVSSSBpcyBudWxsIG9yIGFuIGVtcHR5IHN0cmluZyBhbmQgdGhlCi0gICAgICogIHF1YWxpZmllZE5hbWUgaGFzIGEgcHJlZml4IHRoYXQgaXMgInhtbCIsIHRoZSBuZXcgYXR0cmlidXRlIGlzIGJvdW5kIHRvCi0gICAgICogIHRoZSBwcmVkZWZpbmVkIG5hbWVzcGFjZSAiaHR0cDovL3d3dy53My5vcmcvWE1MLzE5OTgvbmFtZXNwYWNlIgotICAgICAqICBbTmFtZXNwYWNlc10uICBJZiBhbiBhdHRyaWJ1dGUgd2l0aCB0aGUgc2FtZSBsb2NhbCBuYW1lIGFuZCBuYW1lc3BhY2UKLSAgICAgKiAgVVJJIGlzIGFscmVhZHkgcHJlc2VudCBvbiB0aGUgZWxlbWVudCwgaXRzIHByZWZpeCBpcyBjaGFuZ2VkIHRvIGJlIHRoZQotICAgICAqICBwcmVmaXggcGFydCBvZiB0aGUgcXVhbGlmaWVkTmFtZSwgYW5kIGl0cyB2YWx1ZSBpcyBjaGFuZ2VkIHRvIGJlIHRoZQotICAgICAqICB2YWx1ZSBwYXJhbWV0ZXIuIFRoaXMgdmFsdWUgaXMgYSBzaW1wbGUgc3RyaW5nLCBpdCBpcyBub3QgcGFyc2VkIGFzIGl0Ci0gICAgICogIGlzIGJlaW5nIHNldC4gU28gYW55IG1hcmt1cCAoc3VjaCBhcyBzeW50YXggdG8gYmUgcmVjb2duaXplZCBhcyBhbgotICAgICAqICBlbnRpdHkgcmVmZXJlbmNlKSBpcyB0cmVhdGVkIGFzIGxpdGVyYWwgdGV4dCwgYW5kIG5lZWRzIHRvIGJlCi0gICAgICogIGFwcHJvcHJpYXRlbHkgZXNjYXBlZCBieSB0aGUgaW1wbGVtZW50YXRpb24gd2hlbiBpdCBpcyB3cml0dGVuIG91dC4gSW4KLSAgICAgKiAgb3JkZXIgdG8gYXNzaWduIGFuIGF0dHJpYnV0ZSB2YWx1ZSB0aGF0IGNvbnRhaW5zIGVudGl0eSByZWZlcmVuY2VzLCB0aGUKLSAgICAgKiAgdXNlciBtdXN0IGNyZWF0ZSBhbiBBdHRyIG5vZGUgcGx1cyBhbnkgVGV4dCBhbmQgRW50aXR5UmVmZXJlbmNlIG5vZGVzLAotICAgICAqICBidWlsZCB0aGUgYXBwcm9wcmlhdGUgc3VidHJlZSwgYW5kIHVzZSBzZXRBdHRyaWJ1dGVOb2RlTlMgb3IKLSAgICAgKiAgc2V0QXR0cmlidXRlTm9kZSB0byBhc3NpZ24gaXQgYXMgdGhlIHZhbHVlIG9mIGFuIGF0dHJpYnV0ZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkgICAgICBUaGUgbmFtZXNwYWNlIFVSSSBvZiB0aGUgYXR0cmlidXRlIHRvIGNyZWF0ZQotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICBvciBhbHRlci4KLSAgICAgKiBAcGFyYW0gcXVhbGlmaWVkTmFtZSAgICAgVGhlIHF1YWxpZmllZCBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUgdG8gY3JlYXRlIG9yCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgIGFsdGVyLgotICAgICAqIEBwYXJhbSB2YWx1ZSAgICAgICAgICAgICBUaGUgdmFsdWUgdG8gc2V0IGluIHN0cmluZyBmb3JtLgotICAgICAqIEB0aHJvd3MgICAgICAgICAgICAgICAgICBJTlZBTElEX0NIQVJBQ1RFUl9FUlI6IFJhaXNlZCBpZiB0aGUgc3BlY2lmaWVkCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUgY29udGFpbnMgYW4gaW52YWxpZCBjaGFyYWN0ZXIuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzICAgICAgICAgICAgICAgICAgTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcwotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlIGlzIHJlYWRvbmx5LgotICAgICAqCi0gICAgICogQHRocm93cyAgICAgICAgICAgICAgICAgIE5BTUVTUEFDRV9FUlI6IFJhaXNlZCBpZiB0aGUgcXVhbGlmaWVkTmFtZQotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICBoYXMgYSBwcmVmaXggdGhhdCBpcyAieG1sIiBhbmQgdGhlIG5hbWVzcGFjZVVSSQotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICBpcyBuZWl0aGVyIG51bGwgbm9yIGFuIGVtcHR5IHN0cmluZyBub3IKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgImh0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZSIsIG9yIGlmCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSBxdWFsaWZpZWROYW1lIGhhcyBhIHByZWZpeCB0aGF0IGlzICJ4bWxucyIKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgYnV0IHRoZSBuYW1lc3BhY2VVUkkgaXMgbmVpdGhlciBudWxsIG5vciBhbgotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICBlbXB0eSBzdHJpbmcsIG9yIGlmIGlmIHRoZSBxdWFsaWZpZWROYW1lIGhhcyBhCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgIHByZWZpeCBkaWZmZXJlbnQgZnJvbSAieG1sIiBhbmQgInhtbG5zIiBhbmQgdGhlCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZVVSSSBpcyBudWxsIG9yIGFuIGVtcHR5IHN0cmluZy4KLSAgICAgKiBAc2luY2UgV0QtRE9NLUxldmVsLTItMTk5OTA5MjMKLSAgICAgKi8KLSAgICAgcHVibGljIHZvaWQgc2V0QXR0cmlidXRlTlMoU3RyaW5nIG5hbWVzcGFjZVVSSSxTdHJpbmcgcXVhbGlmaWVkTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyB2YWx1ZSkgewotICAgICAgICAgICAgICAgIGlmIChvd25lckRvY3VtZW50LmVycm9yQ2hlY2tpbmcgJiYgaXNSZWFkT25seSgpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbXNnID0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERPTUV4Y2VwdGlvbi5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1zZyk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGlmIChuZWVkc1N5bmNEYXRhKCkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHN5bmNocm9uaXplRGF0YSgpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpbnQgaW5kZXggPSBxdWFsaWZpZWROYW1lLmluZGV4T2YoJzonKTsKLSAgICAgICAgICAgICAgICBTdHJpbmcgcHJlZml4LCBsb2NhbE5hbWU7Ci0gICAgICAgICAgICAgICAgaWYgKGluZGV4IDwgMCkgewotICAgICAgICAgICAgICAgICAgICAgICAgcHJlZml4ID0gbnVsbDsKLSAgICAgICAgICAgICAgICAgICAgICAgIGxvY2FsTmFtZSA9IHF1YWxpZmllZE5hbWU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgcHJlZml4ID0gcXVhbGlmaWVkTmFtZS5zdWJzdHJpbmcoMCwgaW5kZXgpOwotICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWxOYW1lID0gcXVhbGlmaWVkTmFtZS5zdWJzdHJpbmcoaW5kZXggKyAxKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgQXR0ciBuZXdBdHRyID0gZ2V0QXR0cmlidXRlTm9kZU5TKG5hbWVzcGFjZVVSSSwgbG9jYWxOYW1lKTsKLSAgICAgICAgICAgICAgICBpZiAobmV3QXR0ciA9PSBudWxsKSB7Ci0gICAgICAgICAgICAvLyBSRVZJU0lUOiB0aGlzIGlzIG5vdCBlZmZpY2llbnQsIHdlIGFyZSBjcmVhdGluZyB0d2ljZSB0aGUgc2FtZQotICAgICAgICAgICAgLy8gICAgICAgICAgc3RyaW5ncyBmb3IgcHJlZml4IGFuZCBsb2NhbE5hbWUuCi0gICAgICAgICAgICAgICAgICAgICAgICBuZXdBdHRyID0gZ2V0T3duZXJEb2N1bWVudCgpLmNyZWF0ZUF0dHJpYnV0ZU5TKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZVVSSSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBxdWFsaWZpZWROYW1lKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhdHRyaWJ1dGVzID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlcyA9IG5ldyBBdHRyaWJ1dGVNYXAodGhpcywgbnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBuZXdBdHRyLnNldE5vZGVWYWx1ZSh2YWx1ZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzLnNldE5hbWVkSXRlbU5TKG5ld0F0dHIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIGlmIChuZXdBdHRyIGluc3RhbmNlb2YgQXR0ck5TSW1wbCl7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIG9yaWdOb2RlTmFtZSA9ICgoQXR0ck5TSW1wbCkgbmV3QXR0cikubmFtZTsKLSAgICAgICAgICAgICAgICBTdHJpbmcgbmV3TmFtZSA9IChwcmVmaXghPW51bGwpID8gKHByZWZpeCsiOiIrbG9jYWxOYW1lKSA6IGxvY2FsTmFtZTsKLQotICAgICAgICAgICAgICAgICgoQXR0ck5TSW1wbCkgbmV3QXR0cikubmFtZSA9IG5ld05hbWU7Ci0KLSAgICAgICAgICAgICAgICBpZiAoIW5ld05hbWUuZXF1YWxzKG9yaWdOb2RlTmFtZSkpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gTm90ZTogd2UgY2FuJ3QganVzdCBjaGFuZ2UgdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZS4gTmFtZXMgaGF2ZSB0byBiZSBpbiBzb3J0ZWQKLSAgICAgICAgICAgICAgICAgICAgLy8gb3JkZXIgaW4gdGhlIGF0dHJpYnV0ZXMgdmVjdG9yIGJlY2F1c2UgYSBiaW5hcnkgc2VhcmNoIGlzIHVzZWQgdG8gbG9jYXRlIHRoZW0uCi0gICAgICAgICAgICAgICAgICAgIC8vIElmIHRoZSBuZXcgbmFtZSBoYXMgYSBkaWZmZXJlbnQgcHJlZml4LCB0aGUgbGlzdCBtYXkgYmVjb21lIHVuc29ydGVkLgotICAgICAgICAgICAgICAgICAgICAvLyBNYXliZSBpdCB3b3VsZCBiZSBiZXR0ZXIgdG8gcmVzb3J0IHRoZSBsaXN0LCBidXQgdGhlIHNpbXBsZXN0Ci0gICAgICAgICAgICAgICAgICAgIC8vIGZpeCBzZWVtcyB0byBiZSB0byByZW1vdmUgdGhlIG9sZCBhdHRyaWJ1dGUgYW5kIHJlLWluc2VydCBpdC4KLSAgICAgICAgICAgICAgICAgICAgLy8gLS0gTm9ybWFuLldhbHNoQFN1bi5DT00sIDIgRmViIDIwMDcKLSAgICAgICAgICAgICAgICAgICAgbmV3QXR0ciA9IChBdHRyKSBhdHRyaWJ1dGVzLnJlbW92ZUl0ZW0obmV3QXR0ciwgZmFsc2UpOwotICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzLmFkZEl0ZW0obmV3QXR0cik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgLy8gVGhpcyBjYXNlIG1heSBoYXBwZW4gaWYgdXNlciBjYWxsczoKLSAgICAgICAgICAgICAgICAvLyAgICAgIGVsZW0uc2V0QXR0cmlidXRlKCJuYW1lIiwgInZhbHVlIik7Ci0gICAgICAgICAgICAgICAgLy8gICAgICBlbGVtLnNldEF0dHJpYnV0ZU5TKG51bGwsICJuYW1lIiwgInZhbHVlIik7Ci0gICAgICAgICAgICAgICAgLy8gVGhpcyBjYXNlIGlzIG5vdCBkZWZpbmVkIGJ5IHRoZSBET00gc3BlYywgd2UgY2hvb3NlCi0gICAgICAgICAgICAgICAgLy8gdG8gY3JlYXRlIGEgbmV3IGF0dHJpYnV0ZSBpbiB0aGlzIGNhc2UgYW5kIHJlbW92ZSBhbiBvbGQgb25lIGZyb20gdGhlIHRyZWUKLSAgICAgICAgICAgICAgICAvLyBub3RlIHRoaXMgbWlnaHQgY2F1c2UgZXZlbnRzIHRvIGJlIHByb3BhZ2F0ZWQgb3IgdXNlciBkYXRhIHRvIGJlIGxvc3QKLSAgICAgICAgICAgICAgICBuZXdBdHRyID0gbmV3IEF0dHJOU0ltcGwoKENvcmVEb2N1bWVudEltcGwpZ2V0T3duZXJEb2N1bWVudCgpLCBuYW1lc3BhY2VVUkksIHF1YWxpZmllZE5hbWUsIGxvY2FsTmFtZSk7Ci0gICAgICAgICAgICAgICAgYXR0cmlidXRlcy5zZXROYW1lZEl0ZW1OUyhuZXdBdHRyKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAgICAgbmV3QXR0ci5zZXROb2RlVmFsdWUodmFsdWUpOwotICAgICAgICAgICAgICAgIH0KLQotICAgIH0gLy8gc2V0QXR0cmlidXRlTlMoU3RyaW5nLFN0cmluZyxTdHJpbmcpCi0KLQotICAgIC8qKgotICAgICAqIEludHJvZHVjZWQgaW4gRE9NIExldmVsIDIuIDxwPgotICAgICAqCi0gICAgICogUmVtb3ZlcyBhbiBhdHRyaWJ1dGUgYnkgbG9jYWwgbmFtZSBhbmQgbmFtZXNwYWNlIFVSSS4gSWYgdGhlIHJlbW92ZWQKLSAgICAgKiBhdHRyaWJ1dGUgaGFzIGEgZGVmYXVsdCB2YWx1ZSBpdCBpcyBpbW1lZGlhdGVseSByZXBsYWNlZC4KLSAgICAgKiBUaGUgcmVwbGFjaW5nIGF0dHJpYnV0ZSBoYXMgdGhlIHNhbWUgbmFtZXNwYWNlIFVSSSBhbmQgbG9jYWwgbmFtZSwKLSAgICAgKiBhcyB3ZWxsIGFzIHRoZSBvcmlnaW5hbCBwcmVmaXguPHA+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZXNwYWNlVVJJICBUaGUgbmFtZXNwYWNlIFVSSSBvZiB0aGUgYXR0cmlidXRlIHRvIHJlbW92ZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBsb2NhbE5hbWUgICAgIFRoZSBsb2NhbCBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUgdG8gcmVtb3ZlLgotICAgICAqIEB0aHJvd3MgICAgICAgICAgICAgICAgICBOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUgaXMgcmVhZG9ubHkuCi0gICAgICogQHNpbmNlIFdELURPTS1MZXZlbC0yLTE5OTkwOTIzCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcmVtb3ZlQXR0cmlidXRlTlMoU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIGxvY2FsTmFtZSkgewotCi0gICAgICAgIGlmIChvd25lckRvY3VtZW50LmVycm9yQ2hlY2tpbmcgJiYgaXNSZWFkT25seSgpKSB7Ci0gICAgICAgICAgICBTdHJpbmcgbXNnID0gRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwgIk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiIsIG51bGwpOwotICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSLCBtc2cpOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKG5lZWRzU3luY0RhdGEoKSkgewotICAgICAgICAgICAgc3luY2hyb25pemVEYXRhKCk7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoYXR0cmlidXRlcyA9PSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLQotICAgICAgICBhdHRyaWJ1dGVzLnNhZmVSZW1vdmVOYW1lZEl0ZW1OUyhuYW1lc3BhY2VVUkksIGxvY2FsTmFtZSk7Ci0KLSAgICB9IC8vIHJlbW92ZUF0dHJpYnV0ZU5TKFN0cmluZyxTdHJpbmcpCi0KLSAgICAvKioKLSAgICAgKiBSZXRyaWV2ZXMgYW4gQXR0ciBub2RlIGJ5IGxvY2FsIG5hbWUgYW5kIG5hbWVzcGFjZSBVUkkuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZXNwYWNlVVJJICBUaGUgbmFtZXNwYWNlIFVSSSBvZiB0aGUgYXR0cmlidXRlIHRvCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgcmV0cmlldmUuCi0gICAgICogQHBhcmFtIGxvY2FsTmFtZSAgICAgVGhlIGxvY2FsIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZSB0byByZXRyaWV2ZS4KLSAgICAgKiBAcmV0dXJuIEF0dHIgICAgICAgICBUaGUgQXR0ciBub2RlIHdpdGggdGhlIHNwZWNpZmllZCBhdHRyaWJ1dGUKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBsb2NhbCBuYW1lIGFuZCBuYW1lc3BhY2UKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBVUkkgb3IgbnVsbCBpZiB0aGVyZSBpcyBubyBzdWNoIGF0dHJpYnV0ZS4KLSAgICAgKiBAc2luY2UgV0QtRE9NLUxldmVsLTItMTk5OTA5MjMKLSAgICAgKi8KLSAgICBwdWJsaWMgQXR0ciBnZXRBdHRyaWJ1dGVOb2RlTlMoU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIGxvY2FsTmFtZSl7Ci0KLSAgICAgICAgaWYgKG5lZWRzU3luY0RhdGEoKSkgewotICAgICAgICAgICAgc3luY2hyb25pemVEYXRhKCk7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGF0dHJpYnV0ZXMgPT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIChBdHRyKWF0dHJpYnV0ZXMuZ2V0TmFtZWRJdGVtTlMobmFtZXNwYWNlVVJJLCBsb2NhbE5hbWUpOwotCi0gICAgfSAvLyBnZXRBdHRyaWJ1dGVOb2RlTlMoU3RyaW5nLFN0cmluZyk6QXR0cgotCi0gICAgLyoqCi0gICAgICogSW50cm9kdWNlZCBpbiBET00gTGV2ZWwgMi4gPHA+Ci0gICAgICoKLSAgICAgKiBBZGRzIGEgbmV3IGF0dHJpYnV0ZS4gSWYgYW4gYXR0cmlidXRlIHdpdGggdGhhdCBsb2NhbCBuYW1lIGFuZAotICAgICAqIG5hbWVzcGFjZSBVUkkgaXMgYWxyZWFkeSBwcmVzZW50IGluIHRoZSBlbGVtZW50LCBpdCBpcyByZXBsYWNlZAotICAgICAqIGJ5IHRoZSBuZXcgb25lLgotICAgICAqCi0gICAgICogQHBhcmFtIEF0dHIgICAgICBUaGUgQXR0ciBub2RlIHRvIGFkZCB0byB0aGUgYXR0cmlidXRlIGxpc3QuIFdoZW4KLSAgICAgKiAgICAgICAgICAgICAgICAgIHRoZSBOb2RlIGhhcyBubyBuYW1lc3BhY2VVUkksIHRoaXMgbWV0aG9kIGJlaGF2ZXMKLSAgICAgKiAgICAgICAgICAgICAgICAgIGxpa2Ugc2V0QXR0cmlidXRlTm9kZS4KLSAgICAgKiBAcmV0dXJuIEF0dHIgICAgIElmIHRoZSBuZXdBdHRyIGF0dHJpYnV0ZSByZXBsYWNlcyBhbiBleGlzdGluZyBhdHRyaWJ1dGUKLSAgICAgKiAgICAgICAgICAgICAgICAgIHdpdGggdGhlIHNhbWUgbG9jYWwgbmFtZSBhbmQgbmFtZXNwYWNlIFVSSSwgdGhlICoKLSAgICAgKiAgICAgICAgICAgICAgICAgIHByZXZpb3VzbHkgZXhpc3RpbmcgQXR0ciBub2RlIGlzIHJldHVybmVkLCBvdGhlcndpc2UKLSAgICAgKiAgICAgICAgICAgICAgICAgIG51bGwgaXMgcmV0dXJuZWQuCi0gICAgICogQHRocm93cyAgICAgICAgICBXUk9OR19ET0NVTUVOVF9FUlI6IFJhaXNlZCBpZiBuZXdBdHRyCi0gICAgICogICAgICAgICAgICAgICAgICB3YXMgY3JlYXRlZCBmcm9tIGEgZGlmZmVyZW50IGRvY3VtZW50IHRoYW4gdGhlIG9uZSB0aGF0Ci0gICAgICogICAgICAgICAgICAgICAgICBjcmVhdGVkIHRoZSBlbGVtZW50LgotICAgICAqCi0gICAgICogQHRocm93cyAgICAgICAgICBOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZgotICAgICAqICAgICAgICAgICAgICAgICAgdGhpcyBub2RlIGlzIHJlYWRvbmx5LgotICAgICAqCi0gICAgICogQHRocm93cyAgICAgICAgICBJTlVTRV9BVFRSSUJVVEVfRVJSOiBSYWlzZWQgaWYgbmV3QXR0ciBpcwotICAgICAqICAgICAgICAgICAgICAgICAgYWxyZWFkeSBhbiBhdHRyaWJ1dGUgb2YgYW5vdGhlciBFbGVtZW50IG9iamVjdC4gVGhlCi0gICAgICogICAgICAgICAgICAgICAgICBET00gdXNlciBtdXN0IGV4cGxpY2l0bHkgY2xvbmUgQXR0ciBub2RlcyB0byByZS11c2UKLSAgICAgKiAgICAgICAgICAgICAgICAgIHRoZW0gaW4gb3RoZXIgZWxlbWVudHMuCi0gICAgICogQHNpbmNlIFdELURPTS1MZXZlbC0yLTE5OTkwOTIzCi0gICAgICovCi0gICAgcHVibGljIEF0dHIgc2V0QXR0cmlidXRlTm9kZU5TKEF0dHIgbmV3QXR0cikKLSAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgICAgICB7Ci0KLSAgICAgICAgaWYgKG5lZWRzU3luY0RhdGEoKSkgewotICAgICAgICAgICAgc3luY2hyb25pemVEYXRhKCk7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKG93bmVyRG9jdW1lbnQuZXJyb3JDaGVja2luZykgewotICAgICAgICAgICAgaWYgKGlzUmVhZE9ubHkoKSkgewotICAgICAgICAgICAgICAgIFN0cmluZyBtc2cgPSBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIiwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRE9NRXhjZXB0aW9uLk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtc2cpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKG5ld0F0dHIuZ2V0T3duZXJEb2N1bWVudCgpICE9IG93bmVyRG9jdW1lbnQpIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgbXNnID0gRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwgIldST05HX0RPQ1VNRU5UX0VSUiIsIG51bGwpOwotICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLldST05HX0RPQ1VNRU5UX0VSUiwgbXNnKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGlmIChhdHRyaWJ1dGVzID09IG51bGwpIHsKLSAgICAgICAgICAgIGF0dHJpYnV0ZXMgPSBuZXcgQXR0cmlidXRlTWFwKHRoaXMsIG51bGwpOwotICAgICAgICB9Ci0gICAgICAgIC8vIFRoaXMgd2lsbCB0aHJvdyBJTlVTRSBpZiBuZWNlc3NhcnkKLSAgICAgICAgcmV0dXJuIChBdHRyKSBhdHRyaWJ1dGVzLnNldE5hbWVkSXRlbU5TKG5ld0F0dHIpOwotCi0gICAgfSAvLyBzZXRBdHRyaWJ1dGVOb2RlTlMoQXR0cik6QXR0cgotCi0gICAgLyoqCi0gICAgICAqIE5PTi1ET006IHNldHMgYXR0cmlidXRlIG5vZGUgZm9yIHRoaXMgZWxlbWVudAotICAgICAgKi8KLSAgICBwcm90ZWN0ZWQgaW50IHNldFhlcmNlc0F0dHJpYnV0ZU5vZGUgKEF0dHIgYXR0cil7Ci0KLSAgICAgICAgaWYgKG5lZWRzU3luY0RhdGEoKSkgewotICAgICAgICAgICAgc3luY2hyb25pemVEYXRhKCk7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoYXR0cmlidXRlcyA9PSBudWxsKSB7Ci0gICAgICAgICAgICBhdHRyaWJ1dGVzID0gbmV3IEF0dHJpYnV0ZU1hcCh0aGlzLCBudWxsKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gYXR0cmlidXRlcy5hZGRJdGVtKGF0dHIpOwotCi0gICAgfQotCi0gICAgLyoqCi0gICAgICAqIE5PTi1ET006IGdldCBpbmRlZCBvZiBhbiBhdHRyaWJ1dGUKLSAgICAgICovCi0gICAgcHJvdGVjdGVkIGludCBnZXRYZXJjZXNBdHRyaWJ1dGUoU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIGxvY2FsTmFtZSl7Ci0KLSAgICAgICAgaWYgKG5lZWRzU3luY0RhdGEoKSkgewotICAgICAgICAgICAgc3luY2hyb25pemVEYXRhKCk7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGF0dHJpYnV0ZXMgPT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIC0xOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBhdHRyaWJ1dGVzLmdldE5hbWVkSXRlbUluZGV4KG5hbWVzcGFjZVVSSSwgbG9jYWxOYW1lKTsKLQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEludHJvZHVjZWQgaW4gRE9NIExldmVsIDIuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaGFzQXR0cmlidXRlcygpIHsKLSAgICAgICAgaWYgKG5lZWRzU3luY0RhdGEoKSkgewotICAgICAgICAgICAgc3luY2hyb25pemVEYXRhKCk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIChhdHRyaWJ1dGVzICE9IG51bGwgJiYgYXR0cmlidXRlcy5nZXRMZW5ndGgoKSAhPSAwKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJbnRyb2R1Y2VkIGluIERPTSBMZXZlbCAyLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGhhc0F0dHJpYnV0ZShTdHJpbmcgbmFtZSkgewotICAgICAgICByZXR1cm4gZ2V0QXR0cmlidXRlTm9kZShuYW1lKSAhPSBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEludHJvZHVjZWQgaW4gRE9NIExldmVsIDIuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaGFzQXR0cmlidXRlTlMoU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIGxvY2FsTmFtZSkgewotICAgICAgICByZXR1cm4gZ2V0QXR0cmlidXRlTm9kZU5TKG5hbWVzcGFjZVVSSSwgbG9jYWxOYW1lKSAhPSBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEludHJvZHVjZWQgaW4gRE9NIExldmVsIDIuIDxwPgotICAgICAqCi0gICAgICogUmV0dXJucyBhIE5vZGVMaXN0IG9mIGFsbCB0aGUgRWxlbWVudHMgd2l0aCBhIGdpdmVuIGxvY2FsIG5hbWUgYW5kCi0gICAgICogbmFtZXNwYWNlIFVSSSBpbiB0aGUgb3JkZXIgaW4gd2hpY2ggdGhleSB3b3VsZCBiZSBlbmNvdW50ZXJlZCBpbiBhCi0gICAgICogcHJlb3JkZXIgdHJhdmVyc2FsIG9mIHRoZSBEb2N1bWVudCB0cmVlLCBzdGFydGluZyBmcm9tIHRoaXMgbm9kZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkgVGhlIG5hbWVzcGFjZSBVUkkgb2YgdGhlIGVsZW1lbnRzIHRvIG1hdGNoCi0gICAgICogICAgICAgICAgICAgICAgICAgICBvbi4gVGhlIHNwZWNpYWwgdmFsdWUgIioiIG1hdGNoZXMgYWxsCi0gICAgICogICAgICAgICAgICAgICAgICAgICBuYW1lc3BhY2VzLiBXaGVuIGl0IGlzIG51bGwgb3IgYW4gZW1wdHkKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgIHN0cmluZywgdGhpcyBtZXRob2QgYmVoYXZlcyBsaWtlCi0gICAgICogICAgICAgICAgICAgICAgICAgICBnZXRFbGVtZW50c0J5VGFnTmFtZS4KLSAgICAgKiBAcGFyYW0gbG9jYWxOYW1lICAgIFRoZSBsb2NhbCBuYW1lIG9mIHRoZSBlbGVtZW50cyB0byBtYXRjaCBvbi4KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgIFRoZSBzcGVjaWFsIHZhbHVlICIqIiBtYXRjaGVzIGFsbCBsb2NhbCBuYW1lcy4KLSAgICAgKiBAcmV0dXJuIE5vZGVMaXN0ICAgIEEgbmV3IE5vZGVMaXN0IG9iamVjdCBjb250YWluaW5nIGFsbCB0aGUgbWF0Y2hlZAotICAgICAqICAgICAgICAgICAgICAgICAgICAgRWxlbWVudHMuCi0gICAgICogQHNpbmNlIFdELURPTS1MZXZlbC0yLTE5OTkwOTIzCi0gICAgICovCi0gICAgcHVibGljIE5vZGVMaXN0IGdldEVsZW1lbnRzQnlUYWdOYW1lTlMoU3RyaW5nIG5hbWVzcGFjZVVSSSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbG9jYWxOYW1lKSB7Ci0gICAgICAgIHJldHVybiBuZXcgRGVlcE5vZGVMaXN0SW1wbCh0aGlzLCBuYW1lc3BhY2VVUkksIGxvY2FsTmFtZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRE9NIExldmVsIDMgV0QtIEV4cGVyaW1lbnRhbC4KLSAgICAgKiBPdmVycmlkZSBpbmhlcml0ZWQgYmVoYXZpb3IgZnJvbSBOb2RlSW1wbCBhbmQgUGFyZW50Tm9kZSB0byBjaGVjayBvbgotICAgICAqIGF0dHJpYnV0ZXMKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0VxdWFsTm9kZShOb2RlIGFyZykgewotICAgICAgICBpZiAoIXN1cGVyLmlzRXF1YWxOb2RlKGFyZykpIHsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotICAgICAgICBib29sZWFuIGhhc0F0dHJzID0gaGFzQXR0cmlidXRlcygpOwotICAgICAgICBpZiAoaGFzQXR0cnMgIT0gKChFbGVtZW50KSBhcmcpLmhhc0F0dHJpYnV0ZXMoKSkgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0gICAgICAgIGlmIChoYXNBdHRycykgewotICAgICAgICAgICAgTmFtZWROb2RlTWFwIG1hcDEgPSBnZXRBdHRyaWJ1dGVzKCk7Ci0gICAgICAgICAgICBOYW1lZE5vZGVNYXAgbWFwMiA9ICgoRWxlbWVudCkgYXJnKS5nZXRBdHRyaWJ1dGVzKCk7Ci0gICAgICAgICAgICBpbnQgbGVuID0gbWFwMS5nZXRMZW5ndGgoKTsKLSAgICAgICAgICAgIGlmIChsZW4gIT0gbWFwMi5nZXRMZW5ndGgoKSkgewotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKLSAgICAgICAgICAgICAgICBOb2RlIG4xID0gbWFwMS5pdGVtKGkpOwotICAgICAgICAgICAgICAgIGlmIChuMS5nZXRMb2NhbE5hbWUoKSA9PSBudWxsKSB7IC8vIERPTSBMZXZlbCAxIE5vZGUKLSAgICAgICAgICAgICAgICAgICAgTm9kZSBuMiA9IG1hcDIuZ2V0TmFtZWRJdGVtKG4xLmdldE5vZGVOYW1lKCkpOwotICAgICAgICAgICAgICAgICAgICBpZiAobjIgPT0gbnVsbCB8fCAhKChOb2RlSW1wbCkgbjEpLmlzRXF1YWxOb2RlKG4yKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICBOb2RlIG4yID0gbWFwMi5nZXROYW1lZEl0ZW1OUyhuMS5nZXROYW1lc3BhY2VVUkkoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbjEuZ2V0TG9jYWxOYW1lKCkpOwotICAgICAgICAgICAgICAgICAgICBpZiAobjIgPT0gbnVsbCB8fCAhKChOb2RlSW1wbCkgbjEpLmlzRXF1YWxOb2RlKG4yKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIERPTSBMZXZlbCAzOiByZWdpc3RlciB0aGUgZ2l2ZW4gYXR0cmlidXRlIG5vZGUgYXMgYW4gSUQgYXR0cmlidXRlCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0SWRBdHRyaWJ1dGVOb2RlKEF0dHIgYXQsIGJvb2xlYW4gbWFrZUlkKSB7Ci0gICAgICAgIGlmIChuZWVkc1N5bmNEYXRhKCkpIHsKLSAgICAgICAgICAgIHN5bmNocm9uaXplRGF0YSgpOwotICAgICAgICB9Ci0gICAgICAgIGlmIChvd25lckRvY3VtZW50LmVycm9yQ2hlY2tpbmcpIHsKLSAgICAgICAgICAgIGlmIChpc1JlYWRPbmx5KCkpIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgbXNnID0gRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwgIk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiIsIG51bGwpOwotICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRE9NRXhjZXB0aW9uLk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtc2cpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAoYXQuZ2V0T3duZXJFbGVtZW50KCkgIT0gdGhpcykgewotICAgICAgICAgICAgICAgIFN0cmluZyBtc2cgPSBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiTk9UX0ZPVU5EX0VSUiIsIG51bGwpOwotICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9GT1VORF9FUlIsIG1zZyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgKChBdHRySW1wbCkgYXQpLmlzSWRBdHRyaWJ1dGUobWFrZUlkKTsKLSAgICAgICAgaWYgKCFtYWtlSWQpIHsKLSAgICAgICAgICAgIG93bmVyRG9jdW1lbnQucmVtb3ZlSWRlbnRpZmllcihhdC5nZXRWYWx1ZSgpKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIG93bmVyRG9jdW1lbnQucHV0SWRlbnRpZmllcihhdC5nZXRWYWx1ZSgpLCB0aGlzKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIERPTSBMZXZlbCAzOiByZWdpc3RlciB0aGUgZ2l2ZW4gYXR0cmlidXRlIG5vZGUgYXMgYW4gSUQgYXR0cmlidXRlCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0SWRBdHRyaWJ1dGUoU3RyaW5nIG5hbWUsIGJvb2xlYW4gbWFrZUlkKSB7Ci0gICAgICAgIGlmIChuZWVkc1N5bmNEYXRhKCkpIHsKLSAgICAgICAgICAgIHN5bmNocm9uaXplRGF0YSgpOwotICAgICAgICB9Ci0gICAgICAgIEF0dHIgYXQgPSBnZXRBdHRyaWJ1dGVOb2RlKG5hbWUpOwotCi0gICAgICAgICAgICAgICAgaWYoIGF0ID09IG51bGwpewotICAgICAgICAgICAgICAgIFN0cmluZyBtc2cgPSBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTk9UX0ZPVU5EX0VSUiIsIG51bGwpOwotICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX0ZPVU5EX0VSUiwgbXNnKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBpZiAob3duZXJEb2N1bWVudC5lcnJvckNoZWNraW5nKSB7Ci0gICAgICAgICAgICBpZiAoaXNSZWFkT25seSgpKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIG1zZyA9IERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sICJOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIiLCBudWxsKTsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERPTUV4Y2VwdGlvbi5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXNnKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKGF0LmdldE93bmVyRWxlbWVudCgpICE9IHRoaXMpIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgbXNnID0gRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwgIk5PVF9GT1VORF9FUlIiLCBudWxsKTsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfRk9VTkRfRVJSLCBtc2cpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgKChBdHRySW1wbCkgYXQpLmlzSWRBdHRyaWJ1dGUobWFrZUlkKTsKLSAgICAgICAgaWYgKCFtYWtlSWQpIHsKLSAgICAgICAgICAgIG93bmVyRG9jdW1lbnQucmVtb3ZlSWRlbnRpZmllcihhdC5nZXRWYWx1ZSgpKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIG93bmVyRG9jdW1lbnQucHV0SWRlbnRpZmllcihhdC5nZXRWYWx1ZSgpLCB0aGlzKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIERPTSBMZXZlbCAzOiByZWdpc3RlciB0aGUgZ2l2ZW4gYXR0cmlidXRlIG5vZGUgYXMgYW4gSUQgYXR0cmlidXRlCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0SWRBdHRyaWJ1dGVOUyhTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgbG9jYWxOYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBtYWtlSWQpIHsKLSAgICAgICAgaWYgKG5lZWRzU3luY0RhdGEoKSkgewotICAgICAgICAgICAgc3luY2hyb25pemVEYXRhKCk7Ci0gICAgICAgIH0KLSAgICAgICAgLy9pZiBuYW1lc3BhY2UgdXJpIGlzIGVtcHR5IHN0cmluZywgc2V0IGl0IHRvICdudWxsJwotICAgICAgICBpZiAobmFtZXNwYWNlVVJJICE9IG51bGwpIHsKLSAgICAgICAgICAgIG5hbWVzcGFjZVVSSSA9IChuYW1lc3BhY2VVUkkubGVuZ3RoKCkgPT0gMCk/IG51bGwgOiBuYW1lc3BhY2VVUkk7Ci0gICAgICAgIH0KLSAgICAgICAgQXR0ciBhdCA9IGdldEF0dHJpYnV0ZU5vZGVOUyhuYW1lc3BhY2VVUkksIGxvY2FsTmFtZSk7Ci0KLSAgICAgICAgICAgICAgICBpZiggYXQgPT0gbnVsbCl7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIG1zZyA9IERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZSgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOT1RfRk9VTkRfRVJSIiwgbnVsbCk7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfRk9VTkRfRVJSLCBtc2cpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIGlmIChvd25lckRvY3VtZW50LmVycm9yQ2hlY2tpbmcpIHsKLSAgICAgICAgICAgIGlmIChpc1JlYWRPbmx5KCkpIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgbXNnID0gRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwgIk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiIsIG51bGwpOwotICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRE9NRXhjZXB0aW9uLk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtc2cpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAoYXQuZ2V0T3duZXJFbGVtZW50KCkgIT0gdGhpcykgewotICAgICAgICAgICAgICAgIFN0cmluZyBtc2cgPSBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiTk9UX0ZPVU5EX0VSUiIsIG51bGwpOwotICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9GT1VORF9FUlIsIG1zZyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgKChBdHRySW1wbCkgYXQpLmlzSWRBdHRyaWJ1dGUobWFrZUlkKTsKLSAgICAgICAgaWYgKCFtYWtlSWQpIHsKLSAgICAgICAgICAgIG93bmVyRG9jdW1lbnQucmVtb3ZlSWRlbnRpZmllcihhdC5nZXRWYWx1ZSgpKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIG93bmVyRG9jdW1lbnQucHV0SWRlbnRpZmllcihhdC5nZXRWYWx1ZSgpLCB0aGlzKTsKLSAgICAgICAgfQotICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBvcmcudzNjLmRvbS5UeXBlSW5mbyNnZXRUeXBlTmFtZSgpCi0gICAgICovCi0gICAgIHB1YmxpYyBTdHJpbmcgZ2V0VHlwZU5hbWUoKSB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAc2VlIG9yZy53M2MuZG9tLlR5cGVJbmZvI2dldFR5cGVOYW1lc3BhY2UoKQotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VHlwZU5hbWVzcGFjZSgpIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSW50cm9kdWNlZCBpbiBET00gTGV2ZWwgMy4gPHA+Ci0gICAgICogQ2hlY2tzIGlmIGEgdHlwZSBpcyBkZXJpdmVkIGZyb20gYW5vdGhlciBieSByZXN0cmljdGlvbi4gU2VlOgotICAgICAqIGh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0zLUNvcmUvY29yZS5odG1sI1R5cGVJbmZvLWlzRGVyaXZlZEZyb20KLSAgICAgKgotICAgICAqIEBwYXJhbSBhbmNlc3Rvck5TCi0gICAgICogICAgICAgIFRoZSBuYW1zcGFjZSBvZiB0aGUgYW5jZXN0b3IgdHlwZSBkZWNsYXJhdGlvbgotICAgICAqIEBwYXJhbSBhbmNlc3Rvck5hbWUKLSAgICAgKiAgICAgICAgVGhlIG5hbWUgb2YgdGhlIGFuY2VzdG9yIHR5cGUgZGVjbGFyYXRpb24KLSAgICAgKiBAcGFyYW0gdHlwZQotICAgICAqICAgICAgICBUaGUgcmVmZXJlbmNlIHR5cGUgZGVmaW5pdGlvbgotICAgICAqCi0gICAgICogQHJldHVybiBib29sZWFuIFRydWUgaWYgdGhlIHR5cGUgaXMgZGVyaXZlZCBieSByZXN0cmljaXRvbiBmb3IgdGhlCi0gICAgICogICAgICAgICByZWZlcmVuY2UgdHlwZQotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzRGVyaXZlZEZyb20oU3RyaW5nIHR5cGVOYW1lc3BhY2VBcmcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdHlwZU5hbWVBcmcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgZGVyaXZhdGlvbk1ldGhvZCkgewotCi0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIE1ldGhvZCBnZXRTY2hlbWFUeXBlSW5mby4KLSAgICAgICAgICogQHJldHVybiBUeXBlSW5mbwotICAgICAgICAgKi8KLSAgICBwdWJsaWMgVHlwZUluZm8gZ2V0U2NoZW1hVHlwZUluZm8oKXsKLSAgICAgICAgaWYobmVlZHNTeW5jRGF0YSgpKSB7Ci0gICAgICAgICAgICBzeW5jaHJvbml6ZURhdGEoKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gdGhpczsKLSAgICB9Ci0KLSAgICAvLwotICAgIC8vIFB1YmxpYyBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIE5PTi1ET006IFN1YmNsYXNzZWQgdG8gZmxpcCB0aGUgYXR0cmlidXRlcycgcmVhZG9ubHkgc3dpdGNoIGFzIHdlbGwuCi0gICAgICogQHNlZSBOb2RlSW1wbCNzZXRSZWFkT25seQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFJlYWRPbmx5KGJvb2xlYW4gcmVhZE9ubHksIGJvb2xlYW4gZGVlcCkgewotICAgICAgICBzdXBlci5zZXRSZWFkT25seShyZWFkT25seSxkZWVwKTsKLSAgICAgICAgaWYgKGF0dHJpYnV0ZXMgIT0gbnVsbCkgewotICAgICAgICAgICAgYXR0cmlidXRlcy5zZXRSZWFkT25seShyZWFkT25seSx0cnVlKTsKLSAgICAgICAgfQotICAgIH0KLQotCi0KLSAgICAvLwotICAgIC8vIFByb3RlY3RlZCBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKiBTeW5jaHJvbml6ZXMgdGhlIGRhdGEgKG5hbWUgYW5kIHZhbHVlKSBmb3IgZmFzdCBub2Rlcy4gKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCBzeW5jaHJvbml6ZURhdGEoKSB7Ci0KLSAgICAgICAgLy8gbm8gbmVlZCB0byBzeW5jIGluIHRoZSBmdXR1cmUKLSAgICAgICAgbmVlZHNTeW5jRGF0YShmYWxzZSk7Ci0KLSAgICAgICAgLy8gd2UgZG9uJ3Qgd2FudCB0byBnZW5lcmF0ZSBhbnkgZXZlbnQgZm9yIHRoaXMgc28gdHVybiB0aGVtIG9mZgotICAgICAgICBib29sZWFuIG9yaWcgPSBvd25lckRvY3VtZW50LmdldE11dGF0aW9uRXZlbnRzKCk7Ci0gICAgICAgIG93bmVyRG9jdW1lbnQuc2V0TXV0YXRpb25FdmVudHMoZmFsc2UpOwotCi0gICAgICAgIC8vIGF0dHJpYnV0ZXMKLSAgICAgICAgc2V0dXBEZWZhdWx0QXR0cmlidXRlcygpOwotCi0gICAgICAgIC8vIHNldCBtdXRhdGlvbiBldmVudHMgZmxhZyBiYWNrIHRvIGl0cyBvcmlnaW5hbCB2YWx1ZQotICAgICAgICBvd25lckRvY3VtZW50LnNldE11dGF0aW9uRXZlbnRzKG9yaWcpOwotCi0gICAgfSAvLyBzeW5jaHJvbml6ZURhdGEoKQotCi0gICAgLy8gc3VwcG9ydCBmb3IgRE9NIExldmVsIDMgcmVuYW1lTm9kZSBtZXRob2QKLSAgICAvLyBAcGFyYW0gZWwgVGhlIGVsZW1lbnQgZnJvbSB3aGljaCB0byB0YWtlIHRoZSBhdHRyaWJ1dGVzCi0gICAgdm9pZCBtb3ZlU3BlY2lmaWVkQXR0cmlidXRlcyhFbGVtZW50SW1wbCBlbCkgewotICAgICAgICBpZiAobmVlZHNTeW5jRGF0YSgpKSB7Ci0gICAgICAgICAgICBzeW5jaHJvbml6ZURhdGEoKTsKLSAgICAgICAgfQotICAgICAgICBpZiAoZWwuaGFzQXR0cmlidXRlcygpKSB7Ci0gICAgICAgICAgICBpZiAoYXR0cmlidXRlcyA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgYXR0cmlidXRlcyA9IG5ldyBBdHRyaWJ1dGVNYXAodGhpcywgbnVsbCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBhdHRyaWJ1dGVzLm1vdmVTcGVjaWZpZWRBdHRyaWJ1dGVzKGVsLmF0dHJpYnV0ZXMpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqIFNldHVwIHRoZSBkZWZhdWx0IGF0dHJpYnV0ZXMuICovCi0gICAgcHJvdGVjdGVkIHZvaWQgc2V0dXBEZWZhdWx0QXR0cmlidXRlcygpIHsKLSAgICAgICAgTmFtZWROb2RlTWFwSW1wbCBkZWZhdWx0cyA9IGdldERlZmF1bHRBdHRyaWJ1dGVzKCk7Ci0gICAgICAgIGlmIChkZWZhdWx0cyAhPSBudWxsKSB7Ci0gICAgICAgICAgICBhdHRyaWJ1dGVzID0gbmV3IEF0dHJpYnV0ZU1hcCh0aGlzLCBkZWZhdWx0cyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKiogUmVjb25jaWxlIGRlZmF1bHQgYXR0cmlidXRlcy4gKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCByZWNvbmNpbGVEZWZhdWx0QXR0cmlidXRlcygpIHsKLSAgICAgICAgaWYgKGF0dHJpYnV0ZXMgIT0gbnVsbCkgewotICAgICAgICAgICAgTmFtZWROb2RlTWFwSW1wbCBkZWZhdWx0cyA9IGdldERlZmF1bHRBdHRyaWJ1dGVzKCk7Ci0gICAgICAgICAgICBhdHRyaWJ1dGVzLnJlY29uY2lsZURlZmF1bHRzKGRlZmF1bHRzKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKiBHZXQgdGhlIGRlZmF1bHQgYXR0cmlidXRlcy4gKi8KLSAgICBwcm90ZWN0ZWQgTmFtZWROb2RlTWFwSW1wbCBnZXREZWZhdWx0QXR0cmlidXRlcygpIHsKLQotICAgICAgICBEb2N1bWVudFR5cGVJbXBsIGRvY3R5cGUgPQotICAgICAgICAgICAgKERvY3VtZW50VHlwZUltcGwpIG93bmVyRG9jdW1lbnQuZ2V0RG9jdHlwZSgpOwotICAgICAgICBpZiAoZG9jdHlwZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotICAgICAgICBFbGVtZW50RGVmaW5pdGlvbkltcGwgZWxkZWYgPQotICAgICAgICAgICAgKEVsZW1lbnREZWZpbml0aW9uSW1wbClkb2N0eXBlLmdldEVsZW1lbnRzKCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmdldE5hbWVkSXRlbShnZXROb2RlTmFtZSgpKTsKLSAgICAgICAgaWYgKGVsZGVmID09IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiAoTmFtZWROb2RlTWFwSW1wbCkgZWxkZWYuZ2V0QXR0cmlidXRlcygpOwotCi0gICAgfSAvLyBnZXREZWZhdWx0QXR0cmlidXRlcygpCi0KLX0gLy8gY2xhc3MgRWxlbWVudEltcGwKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9FbGVtZW50TlNJbXBsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vRWxlbWVudE5TSW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzNTc1N2RiLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9FbGVtZW50TlNJbXBsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0ODkgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDAyLDIwMDQsMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5kb207Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTU2ltcGxlVHlwZURlZmluaXRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU1R5cGVEZWZpbml0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi54cy5YU1NpbXBsZVR5cGVEZWNsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5YU0NvbXBsZXhUeXBlRGVjbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuVVJJOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLk5hbWVzcGFjZUNvbnRleHQ7Ci1pbXBvcnQgb3JnLnczYy5kb20uQXR0cjsKLWltcG9ydCBvcmcudzNjLmRvbS5ET01FeGNlcHRpb247Ci0KLQotCi0vKioKLSAqIEVsZW1lbnROU0ltcGwgaW5oZXJpdHMgZnJvbSBFbGVtZW50SW1wbCBhbmQgYWRkcyBuYW1lc3BhY2Ugc3VwcG9ydC4KLSAqIDxQPgotICogVGhlIHF1YWxpZmllZCBuYW1lIGlzIHRoZSBub2RlIG5hbWUsIGFuZCB3ZSBzdG9yZSBsb2NhbE5hbWUgd2hpY2ggaXMgYWxzbwotICogdXNlZCBpbiBhbGwgcXVlcmllcy4gT24gdGhlIG90aGVyIGhhbmQgd2UgcmVjb21wdXRlIHRoZSBwcmVmaXggd2hlbgotICogbmVjZXNzYXJ5LgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIEVsZW5hIGxpdGFuaSwgSUJNCi0gKiBAYXV0aG9yIE5lZXJhaiBCYWphaiwgU3VuIE1pY3Jvc3lzdGVtcwotICogQHZlcnNpb24gJElkOiBFbGVtZW50TlNJbXBsLmphdmEsdiAxLjcgMjAxMC0xMS0wMSAwNDozOTozOSBqb2VodyBFeHAgJAotICovCi1wdWJsaWMgY2xhc3MgRWxlbWVudE5TSW1wbAotICAgIGV4dGVuZHMgRWxlbWVudEltcGwgewotCi0gICAgLy8KLSAgICAvLyBDb25zdGFudHMKLSAgICAvLwotCi0gICAgLyoqIFNlcmlhbGl6YXRpb24gdmVyc2lvbi4gKi8KLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTkxNDIzMTA2MjU0OTQzOTI2NDJMOwotICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgeG1sVVJJID0gImh0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZSI7Ci0KLSAgICAvLwotICAgIC8vIERhdGEKLSAgICAvLwotCi0gICAgLyoqIERPTTI6IE5hbWVzcGFjZSBVUkkuICovCi0gICAgcHJvdGVjdGVkIFN0cmluZyBuYW1lc3BhY2VVUkk7Ci0KLSAgICAvKiogRE9NMjogbG9jYWxOYW1lLiAqLwotICAgIHByb3RlY3RlZCBTdHJpbmcgbG9jYWxOYW1lOwotCi0gICAgLyoqIERPTTM6IHR5cGUgaW5mb3JtYXRpb24gKi8KLSAgICAvLyBSRVZJU0lUOiB3ZSBhcmUgbG9zaW5nIHRoZSB0eXBlIGluZm9ybWF0aW9uIGluIERPTSBkdXJpbmcgc2VyaWFsaXphdGlvbgotICAgIHRyYW5zaWVudCBYU1R5cGVEZWZpbml0aW9uIHR5cGU7Ci0KLSAgICBwcm90ZWN0ZWQgRWxlbWVudE5TSW1wbCgpIHsKLSAgICAgICAgc3VwZXIoKTsKLSAgICB9Ci0gICAgLyoqCi0gICAgICogRE9NMjogQ29uc3RydWN0b3IgZm9yIE5hbWVzcGFjZSBpbXBsZW1lbnRhdGlvbi4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgRWxlbWVudE5TSW1wbChDb3JlRG9jdW1lbnRJbXBsIG93bmVyRG9jdW1lbnQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcXVhbGlmaWVkTmFtZSkKLSAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgc3VwZXIob3duZXJEb2N1bWVudCwgcXVhbGlmaWVkTmFtZSk7Ci0gICAgICAgIHNldE5hbWUobmFtZXNwYWNlVVJJLCBxdWFsaWZpZWROYW1lKTsKLSAgICB9Ci0KLSAgICAgICAgcHJpdmF0ZSB2b2lkIHNldE5hbWUoU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIHFuYW1lKSB7Ci0KLSAgICAgICAgICAgICAgICBTdHJpbmcgcHJlZml4OwotICAgICAgICAgICAgICAgIC8vIERPTSBMZXZlbCAzOiBuYW1lc3BhY2UgVVJJIGlzIG5ldmVyIGVtcHR5IHN0cmluZy4KLSAgICAgICAgICAgICAgICB0aGlzLm5hbWVzcGFjZVVSSSA9IG5hbWVzcGFjZVVSSTsKLSAgICAgICAgICAgICAgICBpZiAobmFtZXNwYWNlVVJJICE9IG51bGwpIHsKLSAgICAgICAgICAgIC8vY29udmVydCB0aGUgZW1wdHkgc3RyaW5nIHRvICdudWxsJwotICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5uYW1lc3BhY2VVUkkgPSAgICAgKG5hbWVzcGFjZVVSSS5sZW5ndGgoKSA9PSAwKSA/IG51bGwgOiBuYW1lc3BhY2VVUkk7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgIGludCBjb2xvbjEsIGNvbG9uMiA7Ci0KLSAgICAgICAgLy9OQU1FU1BBQ0VfRVJSOgotICAgICAgICAvLzEuIGlmIHRoZSBxdWFsaWZpZWQgbmFtZSBpcyAnbnVsbCcgaXQgaXMgbWFsZm9ybWVkLgotICAgICAgICAvLzIuIG9yIGlmIHRoZSBxdWFsaWZpZWROYW1lIGlzIG51bGwgYW5kIHRoZSBuYW1lc3BhY2VVUkkgaXMgZGlmZmVyZW50IGZyb20gbnVsbCwKLSAgICAgICAgLy8gV2UgZG9udCBuZWVkIHRvIGNoZWNrIGZvciBuYW1lc3BhY2VVUkkgIT0gbnVsbCwgaWYgcXVhbGlmaWVkIG5hbWUgaXMgbnVsbCB0aHJvdyBET01FeGNlcHRpb24uCi0gICAgICAgIGlmKHFuYW1lID09IG51bGwpewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbXNnID0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTkFNRVNQQUNFX0VSUiIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTkFNRVNQQUNFX0VSUiwgbXNnKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlewotICAgICAgICAgICAgICAgICAgICBjb2xvbjEgPSBxbmFtZS5pbmRleE9mKCc6Jyk7Ci0gICAgICAgICAgICAgICAgICAgIGNvbG9uMiA9IHFuYW1lLmxhc3RJbmRleE9mKCc6Jyk7Ci0gICAgICAgIH0KLQotICAgICAgICAgICAgICAgIG93bmVyRG9jdW1lbnQuY2hlY2tOYW1lc3BhY2VXRihxbmFtZSwgY29sb24xLCBjb2xvbjIpOwotICAgICAgICAgICAgICAgIGlmIChjb2xvbjEgPCAwKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGVyZSBpcyBubyBwcmVmaXgKLSAgICAgICAgICAgICAgICAgICAgICAgIGxvY2FsTmFtZSA9IHFuYW1lOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG93bmVyRG9jdW1lbnQuZXJyb3JDaGVja2luZykgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG93bmVyRG9jdW1lbnQuY2hlY2tRTmFtZShudWxsLCBsb2NhbE5hbWUpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChxbmFtZS5lcXVhbHMoInhtbG5zIikKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgKG5hbWVzcGFjZVVSSSA9PSBudWxsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8ICFuYW1lc3BhY2VVUkkuZXF1YWxzKE5hbWVzcGFjZUNvbnRleHQuWE1MTlNfVVJJKSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgKG5hbWVzcGFjZVVSSSE9bnVsbCAmJiBuYW1lc3BhY2VVUkkuZXF1YWxzKE5hbWVzcGFjZUNvbnRleHQuWE1MTlNfVVJJKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiAhcW5hbWUuZXF1YWxzKCJ4bWxucyIpKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbXNnID0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZSgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTkFNRVNQQUNFX0VSUiIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OQU1FU1BBQ0VfRVJSLCBtc2cpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ly90aGVyZSBpcyBhIHByZWZpeAotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICBwcmVmaXggPSBxbmFtZS5zdWJzdHJpbmcoMCwgY29sb24xKTsKLSAgICAgICAgICAgICAgICAgICAgbG9jYWxOYW1lID0gcW5hbWUuc3Vic3RyaW5nKGNvbG9uMiArIDEpOwotCi0gICAgICAgICAgICAgICAgICAgIC8vTkFNRVNQQUNFX0VSUjoKLSAgICAgICAgICAgICAgICAgICAgLy8xLiBpZiB0aGUgcXVhbGlmaWVkTmFtZSBoYXMgYSBwcmVmaXggYW5kIHRoZSBuYW1lc3BhY2VVUkkgaXMgbnVsbCwKLQotICAgICAgICAgICAgICAgICAgICAvLzIuIG9yIGlmIHRoZSBxdWFsaWZpZWROYW1lIGhhcyBhIHByZWZpeCB0aGF0IGlzICJ4bWwiIGFuZCB0aGUgbmFtZXNwYWNlVVJJCi0gICAgICAgICAgICAgICAgICAgIC8vaXMgZGlmZmVyZW50IGZyb20gIiBodHRwOi8vd3d3LnczLm9yZy9YTUwvMTk5OC9uYW1lc3BhY2UiCi0KLSAgICAgICAgICAgICAgICAgICAgaWYgKG93bmVyRG9jdW1lbnQuZXJyb3JDaGVja2luZykgewotICAgICAgICAgICAgICAgICAgICAgICAgaWYoIG5hbWVzcGFjZVVSSSA9PSBudWxsIHx8ICggcHJlZml4LmVxdWFscygieG1sIikgJiYgIW5hbWVzcGFjZVVSSS5lcXVhbHMoTmFtZXNwYWNlQ29udGV4dC5YTUxfVVJJKSApKXsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbXNnID0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTkFNRVNQQUNFX0VSUiIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTkFNRVNQQUNFX0VSUiwgbXNnKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAgICAgb3duZXJEb2N1bWVudC5jaGVja1FOYW1lKHByZWZpeCwgbG9jYWxOYW1lKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIG93bmVyRG9jdW1lbnQuY2hlY2tET01OU0VycihwcmVmaXgsIG5hbWVzcGFjZVVSSSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgIC8vIHdoZW4gbG9jYWwgbmFtZSBpcyBrbm93bgotICAgIHByb3RlY3RlZCBFbGVtZW50TlNJbXBsKENvcmVEb2N1bWVudEltcGwgb3duZXJEb2N1bWVudCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgcXVhbGlmaWVkTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbG9jYWxOYW1lKQotICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gICAgewotICAgICAgICBzdXBlcihvd25lckRvY3VtZW50LCBxdWFsaWZpZWROYW1lKTsKLQotICAgICAgICB0aGlzLmxvY2FsTmFtZSA9IGxvY2FsTmFtZTsKLSAgICAgICAgdGhpcy5uYW1lc3BhY2VVUkkgPSBuYW1lc3BhY2VVUkk7Ci0gICAgfQotCi0gICAgLy8gZm9yIERlZmVycmVkRWxlbWVudEltcGwKLSAgICBwcm90ZWN0ZWQgRWxlbWVudE5TSW1wbChDb3JlRG9jdW1lbnRJbXBsIG93bmVyRG9jdW1lbnQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHZhbHVlKSB7Ci0gICAgICAgIHN1cGVyKG93bmVyRG9jdW1lbnQsIHZhbHVlKTsKLSAgICB9Ci0KLSAgICAvLyBTdXBwb3J0IGZvciBET00gTGV2ZWwgMyByZW5hbWVOb2RlIG1ldGhvZC4KLSAgICAvLyBOb3RlOiBUaGlzIG9ubHkgZGVhbHMgd2l0aCBwYXJ0IG9mIHRoZSBwYi4gQ29yZURvY3VtZW50SW1wbAotICAgIC8vIGRvZXMgYWxsIHRoZSB3b3JrLgotICAgIHZvaWQgcmVuYW1lKFN0cmluZyBuYW1lc3BhY2VVUkksIFN0cmluZyBxdWFsaWZpZWROYW1lKQotICAgIHsKLSAgICAgICAgaWYgKG5lZWRzU3luY0RhdGEoKSkgewotICAgICAgICAgICAgc3luY2hyb25pemVEYXRhKCk7Ci0gICAgICAgIH0KLSAgICAgICAgICAgICAgICB0aGlzLm5hbWUgPSBxdWFsaWZpZWROYW1lOwotICAgICAgICBzZXROYW1lKG5hbWVzcGFjZVVSSSwgcXVhbGlmaWVkTmFtZSk7Ci0gICAgICAgIHJlY29uY2lsZURlZmF1bHRBdHRyaWJ1dGVzKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogTk9OLURPTTogcmVzZXRzIHRoaXMgbm9kZSBhbmQgc2V0cyBzcGVjaWZpZWQgdmFsdWVzIGZvciB0aGUgbm9kZQotICAgICAqCi0gICAgICogQHBhcmFtIG93bmVyRG9jdW1lbnQKLSAgICAgKiBAcGFyYW0gbmFtZXNwYWNlVVJJCi0gICAgICogQHBhcmFtIHF1YWxpZmllZE5hbWUKLSAgICAgKiBAcGFyYW0gbG9jYWxOYW1lCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgc2V0VmFsdWVzIChDb3JlRG9jdW1lbnRJbXBsIG93bmVyRG9jdW1lbnQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIHF1YWxpZmllZE5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGxvY2FsTmFtZSl7Ci0KLSAgICAgICAgLy8gcmVtb3ZlIGNoaWxkcmVuIGZpcnN0Ci0gICAgICAgIGZpcnN0Q2hpbGQgPSBudWxsOwotICAgICAgICBwcmV2aW91c1NpYmxpbmcgPSBudWxsOwotICAgICAgICBuZXh0U2libGluZyA9IG51bGw7Ci0gICAgICAgIGZOb2RlTGlzdENhY2hlID0gbnVsbDsKLQotICAgICAgICAvLyBzZXQgb3duZXIgZG9jdW1lbnQKLSAgICAgICAgYXR0cmlidXRlcyA9IG51bGw7Ci0gICAgICAgIHN1cGVyLmZsYWdzID0gMDsKLSAgICAgICAgc2V0T3duZXJEb2N1bWVudChvd25lckRvY3VtZW50KTsKLQotICAgICAgICAvLyBzeW5jaHJvbml6ZURhdGEgd2lsbCBpbml0aWFsaXplIGF0dHJpYnV0ZXMKLSAgICAgICAgbmVlZHNTeW5jRGF0YSh0cnVlKTsKLSAgICAgICAgc3VwZXIubmFtZSA9IHF1YWxpZmllZE5hbWU7Ci0gICAgICAgIHRoaXMubG9jYWxOYW1lID0gbG9jYWxOYW1lOwotICAgICAgICB0aGlzLm5hbWVzcGFjZVVSSSA9IG5hbWVzcGFjZVVSSTsKLQotICAgIH0KLQotICAgIC8vCi0gICAgLy8gTm9kZSBtZXRob2RzCi0gICAgLy8KLQotCi0KLSAgICAvLwotICAgIC8vRE9NMjogTmFtZXNwYWNlIG1ldGhvZHMuCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIEludHJvZHVjZWQgaW4gRE9NIExldmVsIDIuIDxwPgotICAgICAqCi0gICAgICogVGhlIG5hbWVzcGFjZSBVUkkgb2YgdGhpcyBub2RlLCBvciBudWxsIGlmIGl0IGlzIHVuc3BlY2lmaWVkLjxwPgotICAgICAqCi0gICAgICogVGhpcyBpcyBub3QgYSBjb21wdXRlZCB2YWx1ZSB0aGF0IGlzIHRoZSByZXN1bHQgb2YgYSBuYW1lc3BhY2UgbG9va3VwIGJhc2VkIG9uCi0gICAgICogYW4gZXhhbWluYXRpb24gb2YgdGhlIG5hbWVzcGFjZSBkZWNsYXJhdGlvbnMgaW4gc2NvcGUuIEl0IGlzIG1lcmVseSB0aGUKLSAgICAgKiBuYW1lc3BhY2UgVVJJIGdpdmVuIGF0IGNyZWF0aW9uIHRpbWUuPHA+Ci0gICAgICoKLSAgICAgKiBGb3Igbm9kZXMgY3JlYXRlZCB3aXRoIGEgRE9NIExldmVsIDEgbWV0aG9kLCBzdWNoIGFzIGNyZWF0ZUVsZW1lbnQKLSAgICAgKiBmcm9tIHRoZSBEb2N1bWVudCBpbnRlcmZhY2UsIHRoaXMgaXMgbnVsbC4KLSAgICAgKiBAc2luY2UgV0QtRE9NLUxldmVsLTItMTk5OTA5MjMKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWVzcGFjZVVSSSgpCi0gICAgewotICAgICAgICBpZiAobmVlZHNTeW5jRGF0YSgpKSB7Ci0gICAgICAgICAgICBzeW5jaHJvbml6ZURhdGEoKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbmFtZXNwYWNlVVJJOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEludHJvZHVjZWQgaW4gRE9NIExldmVsIDIuIDxwPgotICAgICAqCi0gICAgICogVGhlIG5hbWVzcGFjZSBwcmVmaXggb2YgdGhpcyBub2RlLCBvciBudWxsIGlmIGl0IGlzIHVuc3BlY2lmaWVkLiA8cD4KLSAgICAgKgotICAgICAqIEZvciBub2RlcyBjcmVhdGVkIHdpdGggYSBET00gTGV2ZWwgMSBtZXRob2QsIHN1Y2ggYXMgY3JlYXRlRWxlbWVudAotICAgICAqIGZyb20gdGhlIERvY3VtZW50IGludGVyZmFjZSwgdGhpcyBpcyBudWxsLiA8cD4KLSAgICAgKgotICAgICAqIEBzaW5jZSBXRC1ET00tTGV2ZWwtMi0xOTk5MDkyMwotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0UHJlZml4KCkKLSAgICB7Ci0KLSAgICAgICAgaWYgKG5lZWRzU3luY0RhdGEoKSkgewotICAgICAgICAgICAgc3luY2hyb25pemVEYXRhKCk7Ci0gICAgICAgIH0KLSAgICAgICAgaW50IGluZGV4ID0gbmFtZS5pbmRleE9mKCc6Jyk7Ci0gICAgICAgIHJldHVybiBpbmRleCA8IDAgPyBudWxsIDogbmFtZS5zdWJzdHJpbmcoMCwgaW5kZXgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEludHJvZHVjZWQgaW4gRE9NIExldmVsIDIuIDxwPgotICAgICAqCi0gICAgICogTm90ZSB0aGF0IHNldHRpbmcgdGhpcyBhdHRyaWJ1dGUgY2hhbmdlcyB0aGUgbm9kZU5hbWUgYXR0cmlidXRlLCB3aGljaCBob2xkcyB0aGUKLSAgICAgKiBxdWFsaWZpZWQgbmFtZSwgYXMgd2VsbCBhcyB0aGUgdGFnTmFtZSBhbmQgbmFtZSBhdHRyaWJ1dGVzIG9mIHRoZSBFbGVtZW50Ci0gICAgICogYW5kIEF0dHIgaW50ZXJmYWNlcywgd2hlbiBhcHBsaWNhYmxlLjxwPgotICAgICAqCi0gICAgICogQHBhcmFtIHByZWZpeCBUaGUgbmFtZXNwYWNlIHByZWZpeCBvZiB0aGlzIG5vZGUsIG9yIG51bGwoZW1wdHkgc3RyaW5nKSBpZiBpdCBpcyB1bnNwZWNpZmllZC4KLSAgICAgKgotICAgICAqIEBleGNlcHRpb24gSU5WQUxJRF9DSEFSQUNURVJfRVJSCi0gICAgICogICAgICAgICAgICAgICAgICAgUmFpc2VkIGlmIHRoZSBzcGVjaWZpZWQKLSAgICAgKiAgICAgICAgICAgICAgICAgICBwcmVmaXggY29udGFpbnMgYW4gaW52YWxpZCBjaGFyYWN0ZXIuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiBAc2luY2UgV0QtRE9NLUxldmVsLTItMTk5OTA5MjMKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRQcmVmaXgoU3RyaW5nIHByZWZpeCkKLSAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaWYgKG5lZWRzU3luY0RhdGEoKSkgewotICAgICAgICAgICAgc3luY2hyb25pemVEYXRhKCk7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKG93bmVyRG9jdW1lbnQuZXJyb3JDaGVja2luZykgewotICAgICAgICAgICAgaWYgKGlzUmVhZE9ubHkoKSkgewotICAgICAgICAgICAgICAgIFN0cmluZyBtc2cgPSBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIiwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBET01FeGNlcHRpb24uTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1zZyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAocHJlZml4ICE9IG51bGwgJiYgcHJlZml4Lmxlbmd0aCgpICE9IDApIHsKLSAgICAgICAgICAgICAgICBpZiAoIUNvcmVEb2N1bWVudEltcGwuaXNYTUxOYW1lKHByZWZpeCxvd25lckRvY3VtZW50LmlzWE1MMTFWZXJzaW9uKCkpKSB7Ci0gICAgICAgICAgICAgICAgICAgIFN0cmluZyBtc2cgPSBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiSU5WQUxJRF9DSEFSQUNURVJfRVJSIiwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLklOVkFMSURfQ0hBUkFDVEVSX0VSUiwgbXNnKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaWYgKG5hbWVzcGFjZVVSSSA9PSBudWxsIHx8IHByZWZpeC5pbmRleE9mKCc6JykgPj0wKSB7Ci0gICAgICAgICAgICAgICAgICAgIFN0cmluZyBtc2cgPSBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiTkFNRVNQQUNFX0VSUiIsIG51bGwpOwotICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OQU1FU1BBQ0VfRVJSLCBtc2cpOwotICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocHJlZml4LmVxdWFscygieG1sIikpIHsKLSAgICAgICAgICAgICAgICAgICAgIGlmICghbmFtZXNwYWNlVVJJLmVxdWFscyh4bWxVUkkpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG1zZyA9IERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sICJOQU1FU1BBQ0VfRVJSIiwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTkFNRVNQQUNFX0VSUiwgbXNnKTsKLSAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgfQotICAgICAgICAvLyB1cGRhdGUgbm9kZSBuYW1lIHdpdGggbmV3IHF1YWxpZmllZE5hbWUKLSAgICAgICAgaWYgKHByZWZpeCAhPW51bGwgJiYgcHJlZml4Lmxlbmd0aCgpICE9IDApIHsKLSAgICAgICAgICAgIG5hbWUgPSBwcmVmaXggKyAiOiIgKyBsb2NhbE5hbWU7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBuYW1lID0gbG9jYWxOYW1lOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSW50cm9kdWNlZCBpbiBET00gTGV2ZWwgMi4gPHA+Ci0gICAgICoKLSAgICAgKiBSZXR1cm5zIHRoZSBsb2NhbCBwYXJ0IG9mIHRoZSBxdWFsaWZpZWQgbmFtZSBvZiB0aGlzIG5vZGUuCi0gICAgICogQHNpbmNlIFdELURPTS1MZXZlbC0yLTE5OTkwOTIzCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRMb2NhbE5hbWUoKQotICAgIHsKLSAgICAgICAgaWYgKG5lZWRzU3luY0RhdGEoKSkgewotICAgICAgICAgICAgc3luY2hyb25pemVEYXRhKCk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGxvY2FsTmFtZTsKLSAgICB9Ci0KLQotICAgLyoqCi0gICAgICogRE9NIExldmVsIDMgV0QgLSBFeHBlcmltZW50YWwuCi0gICAgICogUmV0cmlldmUgYmFzZVVSSQotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0QmFzZVVSSSgpIHsKLQotICAgICAgICBpZiAobmVlZHNTeW5jRGF0YSgpKSB7Ci0gICAgICAgICAgICBzeW5jaHJvbml6ZURhdGEoKTsKLSAgICAgICAgfQotICAgICAgICAvLyBBYnNvbHV0ZSBiYXNlIFVSSSBpcyBjb21wdXRlZCBhY2NvcmRpbmcgdG8gWE1MIEJhc2UgKGh0dHA6Ly93d3cudzMub3JnL1RSL3htbGJhc2UvI2dyYW51bGFyaXR5KQotCi0gICAgICAgIC8vIDEuICB0aGUgYmFzZSBVUkkgc3BlY2lmaWVkIGJ5IGFuIHhtbDpiYXNlIGF0dHJpYnV0ZSBvbiB0aGUgZWxlbWVudCwgaWYgb25lIGV4aXN0cwotCi0gICAgICAgIGlmIChhdHRyaWJ1dGVzICE9IG51bGwpIHsKLSAgICAgICAgICAgIEF0dHIgYXR0ck5vZGUgPSAoQXR0cilhdHRyaWJ1dGVzLmdldE5hbWVkSXRlbU5TKCJodHRwOi8vd3d3LnczLm9yZy9YTUwvMTk5OC9uYW1lc3BhY2UiLCAiYmFzZSIpOwotICAgICAgICAgICAgaWYgKGF0dHJOb2RlICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgdXJpID0gIGF0dHJOb2RlLmdldE5vZGVWYWx1ZSgpOwotICAgICAgICAgICAgICAgIGlmICh1cmkubGVuZ3RoKCkgIT0gMCApIHsvLyBhdHRyaWJ1dGUgdmFsdWUgaXMgYWx3YXlzIGVtcHR5IHN0cmluZwotICAgICAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICAgICAgdXJpID0gbmV3IFVSSSh1cmkpLnRvU3RyaW5nKCk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgY2F0Y2ggKGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5VUkkuTWFsZm9ybWVkVVJJRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoaXMgbWF5IGJlIGEgcmVsYXRpdmUgVVJJLgotCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBTdGFydCBmcm9tIHRoZSBiYXNlIFVSSSBvZiB0aGUgcGFyZW50LCBvciBpZiB0aGlzIG5vZGUgaGFzIG5vIHBhcmVudCwgdGhlIG93bmVyIG5vZGUuCi0gICAgICAgICAgICAgICAgICAgICAgICBOb2RlSW1wbCBwYXJlbnRPck93bmVyID0gKHBhcmVudE5vZGUoKSAhPSBudWxsKSA/IHBhcmVudE5vZGUoKSA6IG93bmVyTm9kZTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gTWFrZSBhbnkgcGFyZW50VVJJIGludG8gYSBVUkkgb2JqZWN0IHRvIHVzZSB3aXRoIHRoZSBVUkkoVVJJLCBTdHJpbmcpIGNvbnN0cnVjdG9yLgotICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHBhcmVudEJhc2VVUkkgPSAocGFyZW50T3JPd25lciAhPSBudWxsKSA/IHBhcmVudE9yT3duZXIuZ2V0QmFzZVVSSSgpIDogbnVsbDsKLQotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBhcmVudEJhc2VVUkkgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVyaSA9IG5ldyBVUkkobmV3IFVSSShwYXJlbnRCYXNlVVJJKSwgdXJpKS50b1N0cmluZygpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXRjaCAoY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlVSSS5NYWxmb3JtZWRVUklFeGNlcHRpb24gZXgpewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGlzIHNob3VsZCBuZXZlciBoYXBwZW46IHBhcmVudCBzaG91bGQgaGF2ZSBjaGVja2VkIHRoZSBVUkkgYW5kIHJldHVybmVkIG51bGwgaWYgaW52YWxpZC4KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB1cmk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBSRVZJU0lUOiB3aGF0IHNob3VsZCBoYXBwZW4gaW4gdGhpcyBjYXNlPwotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHVyaTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLzIudGhlIGJhc2UgVVJJIG9mIHRoZSBlbGVtZW50J3MgcGFyZW50IGVsZW1lbnQgd2l0aGluIHRoZSBkb2N1bWVudCBvciBleHRlcm5hbCBlbnRpdHksCi0gICAgICAgIC8vaWYgb25lIGV4aXN0cwotICAgICAgICBTdHJpbmcgcGFyZW50RWxlbWVudEJhc2VVUkkgPSAodGhpcy5wYXJlbnROb2RlKCkgIT0gbnVsbCkgPyB0aGlzLnBhcmVudE5vZGUoKS5nZXRCYXNlVVJJKCkgOiBudWxsIDsKLSAgICAgICAgLy9iYXNlIFVSSSBvZiBwYXJlbnQgZWxlbWVudCBpcyBub3QgbnVsbAotICAgICAgICBpZihwYXJlbnRFbGVtZW50QmFzZVVSSSAhPSBudWxsKXsKLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgLy9yZXR1cm4gdmFsaWQgYWJzb2x1dGUgYmFzZSBVUkkKLSAgICAgICAgICAgICAgIHJldHVybiBuZXcgVVJJKHBhcmVudEVsZW1lbnRCYXNlVVJJKS50b1N0cmluZygpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2F0Y2ggKGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5VUkkuTWFsZm9ybWVkVVJJRXhjZXB0aW9uIGUpewotICAgICAgICAgICAgICAgIC8vIFJFVklTSVQ6IHdoYXQgc2hvdWxkIGhhcHBlbiBpbiB0aGlzIGNhc2U/Ci0gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgLy8zLiB0aGUgYmFzZSBVUkkgb2YgdGhlIGRvY3VtZW50IGVudGl0eSBvciBleHRlcm5hbCBlbnRpdHkgY29udGFpbmluZyB0aGUgZWxlbWVudAotCi0gICAgICAgIFN0cmluZyBiYXNlVVJJID0gKHRoaXMub3duZXJOb2RlICE9IG51bGwpID8gdGhpcy5vd25lck5vZGUuZ2V0QmFzZVVSSSgpIDogbnVsbCA7Ci0KLSAgICAgICAgaWYoYmFzZVVSSSAhPSBudWxsKXsKLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgLy9yZXR1cm4gdmFsaWQgYWJzb2x1dGUgYmFzZSBVUkkKLSAgICAgICAgICAgICAgIHJldHVybiBuZXcgVVJJKGJhc2VVUkkpLnRvU3RyaW5nKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXRjaCAoY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlVSSS5NYWxmb3JtZWRVUklFeGNlcHRpb24gZSl7Ci0gICAgICAgICAgICAgICAgLy8gUkVWSVNJVDogd2hhdCBzaG91bGQgaGFwcGVuIGluIHRoaXMgY2FzZT8KLSAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBudWxsOwotCi0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBAc2VlIG9yZy53M2MuZG9tLlR5cGVJbmZvI2dldFR5cGVOYW1lKCkKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFR5cGVOYW1lKCkgewotICAgICAgICBpZiAodHlwZSAhPW51bGwpewotICAgICAgICAgICAgaWYgKHR5cGUgaW5zdGFuY2VvZiBYU1NpbXBsZVR5cGVEZWNsKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuICgoWFNTaW1wbGVUeXBlRGVjbCkgdHlwZSkuZ2V0VHlwZU5hbWUoKTsKLSAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZSBpbnN0YW5jZW9mIFhTQ29tcGxleFR5cGVEZWNsKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuICgoWFNDb21wbGV4VHlwZURlY2wpIHR5cGUpLmdldFR5cGVOYW1lKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBvcmcudzNjLmRvbS5UeXBlSW5mbyNnZXRUeXBlTmFtZXNwYWNlKCkKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFR5cGVOYW1lc3BhY2UoKSB7Ci0gICAgICAgIGlmICh0eXBlICE9bnVsbCl7Ci0gICAgICAgICAgICByZXR1cm4gdHlwZS5nZXROYW1lc3BhY2UoKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJbnRyb2R1Y2VkIGluIERPTSBMZXZlbCAyLiA8cD4KLSAgICAgKiBDaGVja3MgaWYgYSB0eXBlIGlzIGRlcml2ZWQgZnJvbSBhbm90aGVyIGJ5IHJlc3RyaWN0aW9uLiBTZWU6Ci0gICAgICogaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTMtQ29yZS9jb3JlLmh0bWwjVHlwZUluZm8taXNEZXJpdmVkRnJvbQotICAgICAqCi0gICAgICogQHBhcmFtIGFuY2VzdG9yTlMKLSAgICAgKiAgICAgICAgVGhlIG5hbXNwYWNlIG9mIHRoZSBhbmNlc3RvciB0eXBlIGRlY2xhcmF0aW9uCi0gICAgICogQHBhcmFtIGFuY2VzdG9yTmFtZQotICAgICAqICAgICAgICBUaGUgbmFtZSBvZiB0aGUgYW5jZXN0b3IgdHlwZSBkZWNsYXJhdGlvbgotICAgICAqIEBwYXJhbSB0eXBlCi0gICAgICogICAgICAgIFRoZSByZWZlcmVuY2UgdHlwZSBkZWZpbml0aW9uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIGJvb2xlYW4gVHJ1ZSBpZiB0aGUgdHlwZSBpcyBkZXJpdmVkIGJ5IHJlc3RyaWNpdG9uIGZvciB0aGUKLSAgICAgKiAgICAgICAgIHJlZmVyZW5jZSB0eXBlCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNEZXJpdmVkRnJvbShTdHJpbmcgdHlwZU5hbWVzcGFjZUFyZywgU3RyaW5nIHR5cGVOYW1lQXJnLAotICAgICAgICAgICAgaW50IGRlcml2YXRpb25NZXRob2QpIHsKLSAgICAgICAgaWYobmVlZHNTeW5jRGF0YSgpKSB7Ci0gICAgICAgICAgICBzeW5jaHJvbml6ZURhdGEoKTsKLSAgICAgICAgfQotICAgICAgICBpZiAodHlwZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAodHlwZSBpbnN0YW5jZW9mIFhTU2ltcGxlVHlwZURlY2wpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gKChYU1NpbXBsZVR5cGVEZWNsKSB0eXBlKS5pc0RPTURlcml2ZWRGcm9tKAotICAgICAgICAgICAgICAgICAgICAgICAgdHlwZU5hbWVzcGFjZUFyZywgdHlwZU5hbWVBcmcsIGRlcml2YXRpb25NZXRob2QpOwotICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlIGluc3RhbmNlb2YgWFNDb21wbGV4VHlwZURlY2wpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gKChYU0NvbXBsZXhUeXBlRGVjbCkgdHlwZSkuaXNET01EZXJpdmVkRnJvbSgKLSAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVOYW1lc3BhY2VBcmcsIHR5cGVOYW1lQXJnLCBkZXJpdmF0aW9uTWV0aG9kKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogTk9OLURPTTogc2V0dGluZyB0eXBlIHVzZWQgYnkgdGhlIERPTSBwYXJzZXIKLSAgICAgKiBAc2VlIE5vZGVJbXBsI3NldFJlYWRPbmx5Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0VHlwZShYU1R5cGVEZWZpbml0aW9uIHR5cGUpIHsKLSAgICAgICAgdGhpcy50eXBlID0gdHlwZTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vRW50aXR5SW1wbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL0VudGl0eUltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNTFkNzZjNC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vRW50aXR5SW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzY3ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwMiwyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbTsKLQotaW1wb3J0IG9yZy53M2MuZG9tLkVudGl0eTsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotaW1wb3J0IG9yZy53M2MuZG9tLkRPTUV4Y2VwdGlvbjsKLQotLyoqCi0gKiBFbnRpdHkgbm9kZXMgaG9sZCB0aGUgcmVmZXJlbmNlIGRhdGEgZm9yIGFuIFhNTCBFbnRpdHkgLS0gZWl0aGVyCi0gKiBwYXJzZWQgb3IgdW5wYXJzZWQuIFRoZSBub2RlTmFtZSAoaW5oZXJpdGVkIGZyb20gTm9kZSkgd2lsbCBjb250YWluCi0gKiB0aGUgbmFtZSAoaWYgYW55KSBvZiB0aGUgRW50aXR5LiBJdHMgZGF0YSB3aWxsIGJlIGNvbnRhaW5lZCBpbiB0aGUKLSAqIEVudGl0eSdzIGNoaWxkcmVuLCBpbiBleGFjdGx5IHRoZSBzdHJ1Y3R1cmUgd2hpY2ggYW4KLSAqIEVudGl0eVJlZmVyZW5jZSB0byB0aGlzIG5hbWUgd2lsbCBwcmVzZW50IHdpdGhpbiB0aGUgZG9jdW1lbnQncwotICogYm9keS4KLSAqIDxQPgotICogTm90ZSB0aGF0IHRoaXMgb2JqZWN0IG1vZGVscyB0aGUgYWN0dWFsIGVudGl0eSwgX25vdF8gdGhlIGVudGl0eQotICogZGVjbGFyYXRpb24gb3IgdGhlIGVudGl0eSByZWZlcmVuY2UuCi0gKiA8UD4KLSAqIEFuIFhNTCBwcm9jZXNzb3IgbWF5IGNob29zZSB0byBjb21wbGV0ZWx5IGV4cGFuZCBlbnRpdGllcyBiZWZvcmUKLSAqIHRoZSBzdHJ1Y3R1cmUgbW9kZWwgaXMgcGFzc2VkIHRvIHRoZSBET007IGluIHRoaXMgY2FzZSwgdGhlcmUgd2lsbAotICogYmUgbm8gRW50aXR5UmVmZXJlbmNlcyBpbiB0aGUgRE9NIHRyZWUuCi0gKiA8UD4KLSAqIFF1b3RpbmcgdGhlIDEwLzAxIERPTSBQcm9wb3NhbCwKLSAqIDxCTE9DS1FVT1RFPgotICogIlRoZSBET00gTGV2ZWwgMSBkb2VzIG5vdCBzdXBwb3J0IGVkaXRpbmcgRW50aXR5IG5vZGVzOyBpZiBhIHVzZXIKLSAqIHdhbnRzIHRvIG1ha2UgY2hhbmdlcyB0byB0aGUgY29udGVudHMgb2YgYW4gRW50aXR5LCBldmVyeSByZWxhdGVkCi0gKiBFbnRpdHlSZWZlcmVuY2Ugbm9kZSBoYXMgdG8gYmUgcmVwbGFjZWQgaW4gdGhlIHN0cnVjdHVyZSBtb2RlbCBieQotICogYSBjbG9uZSBvZiB0aGUgRW50aXR5J3MgY29udGVudHMsIGFuZCB0aGVuIHRoZSBkZXNpcmVkIGNoYW5nZXMKLSAqIG11c3QgYmUgbWFkZSB0byBlYWNoIG9mIHRob3NlIGNsb25lcyBpbnN0ZWFkLiBBbGwgdGhlCi0gKiBkZXNjZW5kYW50cyBvZiBhbiBFbnRpdHkgbm9kZSBhcmUgcmVhZG9ubHkuIgotICogPC9CTE9DS1FVT1RFPgotICogSSdtIGludGVycHJldGluZyB0aGlzIGFzOiBJdCBpcyB0aGUgcGFyc2VyJ3MgcmVzcG9uc2liaWx0eSB0byBjYWxsCi0gKiB0aGUgbm9uLURPTSBvcGVyYXRpb24gc2V0UmVhZE9ubHkodHJ1ZSx0cnVlKSBhZnRlciBpdCBjb25zdHJ1Y3RzCi0gKiB0aGUgRW50aXR5LiBTaW5jZSB0aGUgRE9NIGV4cGxpY2l0bHkgZGVjaWRlZCBub3QgdG8gZGVhbCB3aXRoIHRoaXMsCi0gKiBfYW55XyBhbnN3ZXIgd2lsbCBpbnZvbHZlIGEgbm9uLURPTSBvcGVyYXRpb24sIGFuZCB0aGlzIGlzIHRoZQotICogc2ltcGxlc3Qgc29sdXRpb24uCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgRWxlbmEgTGl0YW5pLCBJQk0KLSAqIEBzaW5jZSBQUi1ET00tTGV2ZWwtMS0xOTk4MDgxOC4KLSAqLwotcHVibGljIGNsYXNzIEVudGl0eUltcGwKLSAgICBleHRlbmRzIFBhcmVudE5vZGUKLSAgICBpbXBsZW1lbnRzIEVudGl0eSB7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0YW50cwotICAgIC8vCi0KLSAgICAvKiogU2VyaWFsaXphdGlvbiB2ZXJzaW9uLiAqLwotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMzU3NTc2MDk0MzQ0NDMwMzQyM0w7Ci0KLSAgICAvLwotICAgIC8vIERhdGEKLSAgICAvLwotCi0gICAgLyoqIEVudGl0eSBuYW1lLiAqLwotICAgIHByb3RlY3RlZCBTdHJpbmcgbmFtZTsKLQotICAgIC8qKiBQdWJsaWMgaWRlbnRpZmllci4gKi8KLSAgICBwcm90ZWN0ZWQgU3RyaW5nIHB1YmxpY0lkOwotCi0gICAgLyoqIFN5c3RlbSBpZGVudGlmaWVyLiAqLwotICAgIHByb3RlY3RlZCBTdHJpbmcgc3lzdGVtSWQ7Ci0KLSAgICAvKiogRW5jb2RpbmcgKi8KLSAgICBwcm90ZWN0ZWQgU3RyaW5nIGVuY29kaW5nOwotCi0KLSAgICAvKiogSW5wdXQgRW5jb2RpbmcgKi8KLSAgICBwcm90ZWN0ZWQgU3RyaW5nIGlucHV0RW5jb2Rpbmc7Ci0KLSAgICAvKiogVmVyc2lvbiAqLwotICAgIHByb3RlY3RlZCBTdHJpbmcgdmVyc2lvbjsKLQotCi0gICAgLyoqIE5vdGF0aW9uIG5hbWUuICovCi0gICAgcHJvdGVjdGVkIFN0cmluZyBub3RhdGlvbk5hbWU7Ci0KLSAgICAvKiogYmFzZSB1cmkqLwotICAgIHByb3RlY3RlZCBTdHJpbmcgYmFzZVVSSTsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKiBGYWN0b3J5IGNvbnN0cnVjdG9yLiAqLwotICAgIHB1YmxpYyBFbnRpdHlJbXBsKENvcmVEb2N1bWVudEltcGwgb3duZXJEb2MsIFN0cmluZyBuYW1lKSB7Ci0gICAgICAgIHN1cGVyKG93bmVyRG9jKTsKLSAgICAgICAgdGhpcy5uYW1lID0gbmFtZTsKLSAgICAgICAgaXNSZWFkT25seSh0cnVlKTsKLSAgICB9Ci0KLSAgICAvLwotICAgIC8vIE5vZGUgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBBIHNob3J0IGludGVnZXIgaW5kaWNhdGluZyB3aGF0IHR5cGUgb2Ygbm9kZSB0aGlzIGlzLiBUaGUgbmFtZWQKLSAgICAgKiBjb25zdGFudHMgZm9yIHRoaXMgdmFsdWUgYXJlIGRlZmluZWQgaW4gdGhlIG9yZy53M2MuZG9tLk5vZGUgaW50ZXJmYWNlLgotICAgICAqLwotICAgIHB1YmxpYyBzaG9ydCBnZXROb2RlVHlwZSgpIHsKLSAgICAgICAgcmV0dXJuIE5vZGUuRU5USVRZX05PREU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgZW50aXR5IG5hbWUKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE5vZGVOYW1lKCkgewotICAgICAgICBpZiAobmVlZHNTeW5jRGF0YSgpKSB7Ci0gICAgICAgICAgICBzeW5jaHJvbml6ZURhdGEoKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbmFtZTsKLSAgICB9Ci0gICAgLyoqCi0gICAgICogU2V0cyB0aGUgbm9kZSB2YWx1ZS4KLSAgICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbihOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0Tm9kZVZhbHVlKFN0cmluZyB4KQotICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKG93bmVyRG9jdW1lbnQuZXJyb3JDaGVja2luZyAmJiBpc1JlYWRPbmx5KCkpIHsKLSAgICAgICAgICAgIFN0cmluZyBtc2cgPSBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIiwgbnVsbCk7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIsIG1zZyk7Ci0gICAgICAgIH0KLSAgICB9Ci0gICAgLyoqCi0gICAgICogVGhlIG5hbWVzcGFjZSBwcmVmaXggb2YgdGhpcyBub2RlCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIG5vZGUgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0UHJlZml4KFN0cmluZyBwcmVmaXgpCi0gICAgICAgIHRocm93cyBET01FeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGlmIChvd25lckRvY3VtZW50LmVycm9yQ2hlY2tpbmcgJiYgaXNSZWFkT25seSgpKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIsCi0gICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAiTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIiwgbnVsbCkpOwotICAgICAgICB9Ci0gICAgfQotICAgIC8qKiBDbG9uZSBub2RlLiAqLwotICAgIHB1YmxpYyBOb2RlIGNsb25lTm9kZShib29sZWFuIGRlZXApIHsKLSAgICAgICAgRW50aXR5SW1wbCBuZXdlbnRpdHkgPSAoRW50aXR5SW1wbClzdXBlci5jbG9uZU5vZGUoZGVlcCk7Ci0gICAgICAgIG5ld2VudGl0eS5zZXRSZWFkT25seSh0cnVlLCBkZWVwKTsKLSAgICAgICAgcmV0dXJuIG5ld2VudGl0eTsKLSAgICB9Ci0KLSAgICAvLwotICAgIC8vIEVudGl0eSBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFRoZSBwdWJsaWMgaWRlbnRpZmllciBhc3NvY2lhdGVkIHdpdGggdGhlIGVudGl0eS4gSWYgbm90IHNwZWNpZmllZCwKLSAgICAgKiB0aGlzIHdpbGwgYmUgbnVsbC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFB1YmxpY0lkKCkgewotCi0gICAgICAgIGlmIChuZWVkc1N5bmNEYXRhKCkpIHsKLSAgICAgICAgICAgIHN5bmNocm9uaXplRGF0YSgpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBwdWJsaWNJZDsKLQotICAgIH0gLy8gZ2V0UHVibGljSWQoKTpTdHJpbmcKLQotICAgIC8qKgotICAgICAqIFRoZSBzeXN0ZW0gaWRlbnRpZmllciBhc3NvY2lhdGVkIHdpdGggdGhlIGVudGl0eS4gSWYgbm90IHNwZWNpZmllZCwKLSAgICAgKiB0aGlzIHdpbGwgYmUgbnVsbC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFN5c3RlbUlkKCkgewotCi0gICAgICAgIGlmIChuZWVkc1N5bmNEYXRhKCkpIHsKLSAgICAgICAgICAgIHN5bmNocm9uaXplRGF0YSgpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBzeXN0ZW1JZDsKLQotICAgIH0gLy8gZ2V0U3lzdGVtSWQoKTpTdHJpbmcKLQotICAgIC8qKgotICAgICAgKiBET00gTGV2ZWwgMyBXRCAtIGV4cGVyaW1lbnRhbAotICAgICAgKiB0aGUgdmVyc2lvbiBudW1iZXIgb2YgdGhpcyBlbnRpdHksIHdoZW4gaXQgaXMgYW4gZXh0ZXJuYWwgcGFyc2VkIGVudGl0eS4KLSAgICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRYbWxWZXJzaW9uKCkgewotCi0gICAgICAgaWYgKG5lZWRzU3luY0RhdGEoKSkgewotICAgICAgICAgICBzeW5jaHJvbml6ZURhdGEoKTsKLSAgICAgICB9Ci0gICAgICAgcmV0dXJuIHZlcnNpb247Ci0KLSAgIH0gLy8gZ2V0VmVyc2lvbigpOlN0cmluZwotCi0KLSAgICAvKioKLSAgICAgKiBET00gTGV2ZWwgMyBXRCAtIGV4cGVyaW1lbnRhbAotICAgICAqIHRoZSBlbmNvZGluZyBvZiB0aGlzIGVudGl0eSwgd2hlbiBpdCBpcyBhbiBleHRlcm5hbCBwYXJzZWQgZW50aXR5LgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0WG1sRW5jb2RpbmcoKSB7Ci0KLSAgICAgICBpZiAobmVlZHNTeW5jRGF0YSgpKSB7Ci0gICAgICAgICAgIHN5bmNocm9uaXplRGF0YSgpOwotICAgICAgIH0KLQotICAgICAgIHJldHVybiBlbmNvZGluZzsKLQotICAgfSAvLyBnZXRWZXJzaW9uKCk6U3RyaW5nCi0KLQotCi0KLQotICAgIC8qKgotICAgICAqIFVucGFyc2VkIGVudGl0aWVzIC0tIHdoaWNoIGNvbnRhaW4gbm9uLVhNTCBkYXRhIC0tIGhhdmUgYQotICAgICAqICJub3RhdGlvbiBuYW1lIiB3aGljaCB0ZWxscyBhcHBsaWNhdGlvbnMgaG93IHRvIGRlYWwgd2l0aCB0aGVtLgotICAgICAqIFBhcnNlZCBlbnRpdGllcywgd2hpY2ggPGVtPmFyZTwvZW0+IGluIFhNTCBmb3JtYXQsIGRvbid0IG5lZWQgdGhpcyBhbmQKLSAgICAgKiBzZXQgaXQgdG8gbnVsbC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE5vdGF0aW9uTmFtZSgpIHsKLQotICAgICAgICBpZiAobmVlZHNTeW5jRGF0YSgpKSB7Ci0gICAgICAgICAgICBzeW5jaHJvbml6ZURhdGEoKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbm90YXRpb25OYW1lOwotCi0gICAgfSAvLyBnZXROb3RhdGlvbk5hbWUoKTpTdHJpbmcKLQotICAgIC8vCi0gICAgLy8gUHVibGljIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogRE9NIExldmVsIDI6IFRoZSBwdWJsaWMgaWRlbnRpZmllciBhc3NvY2lhdGVkIHdpdGggdGhlIGVudGl0eS4gSWYgbm90IHNwZWNpZmllZCwKLSAgICAgKiB0aGlzIHdpbGwgYmUgbnVsbC4gKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRQdWJsaWNJZChTdHJpbmcgaWQpIHsKLQotICAgICAgICBpZiAobmVlZHNTeW5jRGF0YSgpKSB7Ci0gICAgICAgICAgICBzeW5jaHJvbml6ZURhdGEoKTsKLSAgICAgICAgfQotICAgICAgICBwdWJsaWNJZCA9IGlkOwotCi0gICAgfSAvLyBzZXRQdWJsaWNJZChTdHJpbmcpCi0KLSAgICAvKioKLSAgICAgKiBOT04tRE9NCi0gICAgICogZW5jb2RpbmcgLSBBbiBhdHRyaWJ1dGUgc3BlY2lmeWluZywgYXMgcGFydCBvZiB0aGUgdGV4dCBkZWNsYXJhdGlvbiwKLSAgICAgKiB0aGUgZW5jb2Rpbmcgb2YgdGhpcyBlbnRpdHksIHdoZW4gaXQgaXMgYW4gZXh0ZXJuYWwgcGFyc2VkIGVudGl0eS4KLSAgICAgKiBUaGlzIGlzIG51bGwgb3RoZXJ3aXNlCi0gICAgICoKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRYbWxFbmNvZGluZyhTdHJpbmcgdmFsdWUpIHsKLSAgICAgICAgaWYgKG5lZWRzU3luY0RhdGEoKSkgewotICAgICAgICAgICAgc3luY2hyb25pemVEYXRhKCk7Ci0gICAgICAgIH0KLSAgICAgICAgZW5jb2RpbmcgPSB2YWx1ZTsKLSAgICB9IC8vIHNldEVuY29kaW5nIChTdHJpbmcpCi0KLQotICAgIC8qKgotICAgICAqIEFuIGF0dHJpYnV0ZSBzcGVjaWZ5aW5nIHRoZSBlbmNvZGluZyB1c2VkIGZvciB0aGlzIGVudGl0eSBhdCB0aGUgdGlvbWUKLSAgICAgKiBvZiBwYXJzaW5nLCB3aGVuIGl0IGlzIGFuIGV4dGVybmFsIHBhcnNlZCBlbnRpdHkuIFRoaXMgaXMKLSAgICAgKiA8Y29kZT5udWxsPC9jb2RlPiBpZiBpdCBhbiBlbnRpdHkgZnJvbSB0aGUgaW50ZXJuYWwgc3Vic2V0IG9yIGlmIGl0Ci0gICAgICogaXMgbm90IGtub3duLi4KLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldElucHV0RW5jb2RpbmcoKXsKLSAgICAgICAgaWYgKG5lZWRzU3luY0RhdGEoKSkgewotICAgICAgICAgICAgc3luY2hyb25pemVEYXRhKCk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGlucHV0RW5jb2Rpbmc7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogTk9OLURPTSwgdXNlZCB0byBzZXQgdGhlIGlucHV0IGVuY29kaW5nLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldElucHV0RW5jb2RpbmcoU3RyaW5nIGlucHV0RW5jb2RpbmcpewotICAgICAgICBpZiAobmVlZHNTeW5jRGF0YSgpKSB7Ci0gICAgICAgICAgICBzeW5jaHJvbml6ZURhdGEoKTsKLSAgICAgICAgfQotICAgICAgICB0aGlzLmlucHV0RW5jb2RpbmcgPSBpbnB1dEVuY29kaW5nOwotICAgIH0KLQotICAgIC8qKgotICAgICAgKiBOT04tRE9NCi0gICAgICAqIHZlcnNpb24gLSBBbiBhdHRyaWJ1dGUgc3BlY2lmeWluZywgYXMgcGFydCBvZiB0aGUgdGV4dCBkZWNsYXJhdGlvbiwKLSAgICAgICogdGhlIHZlcnNpb24gbnVtYmVyIG9mIHRoaXMgZW50aXR5LCB3aGVuIGl0IGlzIGFuIGV4dGVybmFsIHBhcnNlZCBlbnRpdHkuCi0gICAgICAqIFRoaXMgaXMgbnVsbCBvdGhlcndpc2UKLSAgICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0WG1sVmVyc2lvbihTdHJpbmcgdmFsdWUpIHsKLSAgICAgICAgaWYgKG5lZWRzU3luY0RhdGEoKSkgewotICAgICAgICAgICAgc3luY2hyb25pemVEYXRhKCk7Ci0gICAgICAgIH0KLSAgICAgICAgdmVyc2lvbiA9IHZhbHVlOwotICAgIH0gLy8gc2V0VmVyc2lvbiAoU3RyaW5nKQotCi0KLSAgICAvKioKLSAgICAgKiBET00gTGV2ZWwgMjogVGhlIHN5c3RlbSBpZGVudGlmaWVyIGFzc29jaWF0ZWQgd2l0aCB0aGUgZW50aXR5LiBJZiBub3QKLSAgICAgKiBzcGVjaWZpZWQsIHRoaXMgd2lsbCBiZSBudWxsLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFN5c3RlbUlkKFN0cmluZyBpZCkgewotICAgICAgICBpZiAobmVlZHNTeW5jRGF0YSgpKSB7Ci0gICAgICAgICAgICBzeW5jaHJvbml6ZURhdGEoKTsKLSAgICAgICAgfQotICAgICAgICBzeXN0ZW1JZCA9IGlkOwotCi0gICAgfSAvLyBzZXRTeXN0ZW1JZChTdHJpbmcpCi0KLSAgICAvKioKLSAgICAgKiBET00gTGV2ZWwgMjogVW5wYXJzZWQgZW50aXRpZXMgLS0gd2hpY2ggY29udGFpbiBub24tWE1MIGRhdGEgLS0gaGF2ZSBhCi0gICAgICogIm5vdGF0aW9uIG5hbWUiIHdoaWNoIHRlbGxzIGFwcGxpY2F0aW9ucyBob3cgdG8gZGVhbCB3aXRoIHRoZW0uCi0gICAgICogUGFyc2VkIGVudGl0aWVzLCB3aGljaCA8ZW0+YXJlPC9lbT4gaW4gWE1MIGZvcm1hdCwgZG9uJ3QgbmVlZCB0aGlzIGFuZAotICAgICAqIHNldCBpdCB0byBudWxsLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldE5vdGF0aW9uTmFtZShTdHJpbmcgbmFtZSkgewotICAgICAgICBpZiAobmVlZHNTeW5jRGF0YSgpKSB7Ci0gICAgICAgICAgICBzeW5jaHJvbml6ZURhdGEoKTsKLSAgICAgICAgfQotICAgICAgICBub3RhdGlvbk5hbWUgPSBuYW1lOwotCi0gICAgfSAvLyBzZXROb3RhdGlvbk5hbWUoU3RyaW5nKQotCi0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIGFic29sdXRlIGJhc2UgVVJJIG9mIHRoaXMgbm9kZSBvciBudWxsIGlmIHRoZSBpbXBsZW1lbnRhdGlvbgotICAgICAqIHdhc24ndCBhYmxlIHRvIG9idGFpbiBhbiBhYnNvbHV0ZSBVUkkuIE5vdGU6IElmIHRoZSBVUkkgaXMgbWFsZm9ybWVkLCBhCi0gICAgICogbnVsbCBpcyByZXR1cm5lZC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIGFic29sdXRlIGJhc2UgVVJJIG9mIHRoaXMgbm9kZSBvciBudWxsLgotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0QmFzZVVSSSgpIHsKLQotICAgICAgICBpZiAobmVlZHNTeW5jRGF0YSgpKSB7Ci0gICAgICAgICAgICBzeW5jaHJvbml6ZURhdGEoKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gKGJhc2VVUkkhPW51bGwpP2Jhc2VVUkk6KChDb3JlRG9jdW1lbnRJbXBsKWdldE93bmVyRG9jdW1lbnQoKSkuZ2V0QmFzZVVSSSgpOwotICAgIH0KLQotICAgIC8qKiBOT04tRE9NOiBzZXQgYmFzZSB1cmkqLwotICAgIHB1YmxpYyB2b2lkIHNldEJhc2VVUkkoU3RyaW5nIHVyaSl7Ci0gICAgICAgIGlmIChuZWVkc1N5bmNEYXRhKCkpIHsKLSAgICAgICAgICAgIHN5bmNocm9uaXplRGF0YSgpOwotICAgICAgICB9Ci0gICAgICAgIGJhc2VVUkkgPSB1cmk7Ci0gICAgfQotCi0KLQotfSAvLyBjbGFzcyBFbnRpdHlJbXBsCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vRW50aXR5UmVmZXJlbmNlSW1wbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL0VudGl0eVJlZmVyZW5jZUltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMzA1ZGMzMy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vRW50aXR5UmVmZXJlbmNlSW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDAyICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwMiwyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbTsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5VUkk7Ci1pbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnRUeXBlOwotaW1wb3J0IG9yZy53M2MuZG9tLkVudGl0eVJlZmVyZW5jZTsKLWltcG9ydCBvcmcudzNjLmRvbS5OYW1lZE5vZGVNYXA7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLQotLyoqCi0gKiBFbnRpdHlSZWZlcmVuY2UgbW9kZWxzIHRoZSBYTUwgJmVudGl0eW5hbWU7IHN5bnRheCwgd2hlbiB1c2VkIGZvcgotICogZW50aXRpZXMgZGVmaW5lZCBieSB0aGUgRE9NLiBFbnRpdGllcyBoYXJkY29kZWQgaW50byBYTUwsIHN1Y2ggYXMKLSAqIGNoYXJhY3RlciBlbnRpdGllcywgc2hvdWxkIGluc3RlYWQgaGF2ZSBiZWVuIHRyYW5zbGF0ZWQgaW50byB0ZXh0Ci0gKiBieSB0aGUgY29kZSB3aGljaCBnZW5lcmF0ZWQgdGhlIERPTSB0cmVlLgotICogPFA+Ci0gKiBBbiBYTUwgcHJvY2Vzc29yIGhhcyB0aGUgYWx0ZXJuYXRpdmUgb2YgZnVsbHkgZXhwYW5kaW5nIEVudGl0aWVzCi0gKiBpbnRvIHRoZSBub3JtYWwgZG9jdW1lbnQgdHJlZS4gSWYgaXQgZG9lcyBzbywgbm8gRW50aXR5UmVmZXJlbmNlIG5vZGVzCi0gKiB3aWxsIGFwcGVhci4KLSAqIDxQPgotICogU2ltaWxhcmx5LCBub24tdmFsaWRhdGluZyBYTUwgcHJvY2Vzc29ycyBhcmUgbm90IHJlcXVpcmVkIHRvIHJlYWQKLSAqIG9yIHByb2Nlc3MgZW50aXR5IGRlY2xhcmF0aW9ucyBtYWRlIGluIHRoZSBleHRlcm5hbCBzdWJzZXQgb3IKLSAqIGRlY2xhcmVkIGluIGV4dGVybmFsIHBhcmFtZXRlciBlbnRpdGllcy4gSGVuY2UsIHNvbWUgYXBwbGljYXRpb25zCi0gKiBtYXkgbm90IG1ha2UgdGhlIHJlcGxhY2VtZW50IHZhbHVlIGF2YWlsYWJsZSBmb3IgUGFyc2VkIEVudGl0aWVzCi0gKiBvZiB0aGVzZSB0eXBlcy4KLSAqIDxQPgotICogRW50aXR5UmVmZXJlbmNlIGJlaGF2ZXMgYXMgYSByZWFkLW9ubHkgbm9kZSwgYW5kIHRoZSBjaGlsZHJlbiBvZgotICogdGhlIEVudGl0eVJlZmVyZW5jZSAod2hpY2ggcmVmbGVjdCB0aG9zZSBvZiB0aGUgRW50aXR5LCBhbmQgc2hvdWxkCi0gKiBhbHNvIGJlIHJlYWQtb25seSkgZ2l2ZSBpdHMgcmVwbGFjZW1lbnQgdmFsdWUsIGlmIGFueS4gVGhleSBhcmUKLSAqIHN1cHBvc2VkIHRvIGF1dG9tYWdpY2FsbHkgc3RheSBpbiBzeW5jaCBpZiB0aGUgRG9jdW1lbnRUeXBlIGlzCi0gKiB1cGRhdGVkIHdpdGggbmV3IHZhbHVlcyBmb3IgdGhlIEVudGl0eS4KLSAqIDxQPgotICogVGhlIGRlZmluZWQgYmVoYXZpb3IgbWFrZXMgZWZmaWNpZW50IHN0b3JhZ2UgZGlmZmljdWx0IGZvciB0aGUgRE9NCi0gKiBpbXBsZW1lbnRvci4gV2UgY2FuJ3QganVzdCBsb29rIGFzaWRlIHRvIHRoZSBFbnRpdHkncyBkZWZpbml0aW9uCi0gKiBpbiB0aGUgRG9jdW1lbnRUeXBlIHNpbmNlIHRob3NlIG5vZGVzIGhhdmUgdGhlIHdyb25nIHBhcmVudCAodW5sZXNzCi0gKiB3ZSBjYW4gY29tZSB1cCB3aXRoIGEgY2xldmVyICJpbWFnaW5hcnkgcGFyZW50IiBtZWNoYW5pc20pLiBXZQotICogbXVzdCBhdCBsZWFzdCBhcHBlYXIgdG8gY2xvbmUgdGhvc2UgY2hpbGRyZW4uLi4gd2hpY2ggcmFpc2VzIHRoZQotICogaXNzdWUgb2Yga2VlcGluZyB0aGUgcmVmZXJlbmNlIHN5bmNocm9uaXplZCB3aXRoIGl0cyBwYXJlbnQuCi0gKiBUaGlzIGxlYWRzIG1lIGJhY2sgdG8gdGhlICJjYWNoZWQgaW1hZ2Ugb2YgY2VudHJhbGx5IGRlZmluZWQgZGF0YSIKLSAqIHNvbHV0aW9uLCBtdWNoIGFzIEkgZGlzbGlrZSBpdC4KLSAqIDxQPgotICogRm9yIG5vdyBJIGhhdmUgZGVjaWRlZCwgc2luY2UgUkVDLURPTS1MZXZlbC0xLTE5OTgwODE4IGRvZXNuJ3QKLSAqIGNvdmVyIHRoaXMgaW4gbXVjaCBkZXRhaWwsIHRoYXQgc3luY2hyb25pemF0aW9uIGRvZXNuJ3QgaGF2ZSB0byBiZQotICogY29uc2lkZXJlZCB3aGlsZSB0aGUgdXNlciBpcyBkZWVwIGluIHRoZSB0cmVlLiBUaGF0IGlzLCBpZiB5b3UncmUKLSAqIGxvb2tpbmcgd2l0aGluIG9uZSBvZiB0aGUgRW50aXR5UmVmZXJlbm5jZSdzIGNoaWxkcmVuIGFuZCB0aGUgRW50aXR5Ci0gKiBjaGFuZ2VzLCB5b3Ugd29uJ3QgYmUgaW5mb3JtZWQ7IGluc3RlYWQsIHlvdSB3aWxsIGNvbnRpbnVlIHRvIGFjY2VzcwotICogdGhlIHNhbWUgb2JqZWN0IC0tIHdoaWNoIG1heSBvciBtYXkgbm90IHN0aWxsIGJlIHBhcnQgb2YgdGhlIHRyZWUuCi0gKiBUaGlzIGlzIHRoZSBzYW1lIGJlaGF2aW9yIHRoYXQgb2J0YWlucyBlbHNld2hlcmUgaW4gdGhlIERPTSBpZiB0aGUKLSAqIHN1YnRyZWUgeW91J3JlIGxvb2tpbmcgYXQgaXMgZGVsZXRlZCBmcm9tIGl0cyBwYXJlbnQsIHNvIGl0J3MKLSAqIGFjY2VwdGFibGUgaGVyZS4gKElmIGl0IHJlYWxseSBib3RoZXJzIGZvbGtzLCB3ZSBjb3VsZCBzZXQgdGhpbmdzCi0gKiB1cCBzbyBkZWxldGVkIHN1YnRyZWVzIGFyZSB3YWxrZWQgYW5kIG1hcmtlZCBpbnZhbGlkLCBidXQgdGhhdCdzCi0gKiBub3QgcGFydCBvZiB0aGUgRE9NJ3MgZGVmaW5lZCBiZWhhdmlvci4pCi0gKiA8UD4KLSAqIEFzIGEgcmVzdWx0LCBvbmx5IHRoZSBFbnRpdHlSZWZlcmVuY2UgaXRzZWxmIGhhcyB0byBiZSBhd2FyZSBvZgotICogY2hhbmdlcyBpbiB0aGUgRW50aXR5LiBBbmQgaXQgY2FuIHRha2UgYWR2YW50YWdlIG9mIHRoZSBzYW1lCi0gKiBzdHJ1Y3R1cmUtY2hhbmdlLW1vbml0b3JpbmcgY29kZSBJIGltcGxlbWVudGVkIHRvIHN1cHBvcnQKLSAqIERlZXBOb2RlTGlzdC4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBBcm5hdWQgIExlIEhvcnMsIElCTQotICogQGF1dGhvciBKb2UgS2Vzc2VsbWFuLCBJQk0KLSAqIEBhdXRob3IgQW5keSBDbGFyaywgSUJNCi0gKiBAYXV0aG9yIFJhbGYgUGZlaWZmZXIsIElCTQotICogQHNpbmNlICBQUi1ET00tTGV2ZWwtMS0xOTk4MDgxOC4KLSAqLwotcHVibGljIGNsYXNzIEVudGl0eVJlZmVyZW5jZUltcGwKLWV4dGVuZHMgUGFyZW50Tm9kZQotaW1wbGVtZW50cyBFbnRpdHlSZWZlcmVuY2UgewotCi0gICAgLy8KLSAgICAvLyBDb25zdGFudHMKLSAgICAvLwotCi0gICAgLyoqIFNlcmlhbGl6YXRpb24gdmVyc2lvbi4gKi8KLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTczODE0NTI5NTU2ODcxMDIwNjJMOwotCi0gICAgLy8KLSAgICAvLyBEYXRhCi0gICAgLy8KLQotICAgIC8qKiBOYW1lIG9mIEVudGl0eSByZWZlcmVuY2VkICovCi0gICAgcHJvdGVjdGVkIFN0cmluZyBuYW1lOwotICAgIC8qKiBCYXNlIFVSSSovCi0gICAgcHJvdGVjdGVkIFN0cmluZyBiYXNlVVJJOwotCi0KLSAgICAvKiogRW50aXR5IGNoYW5nZXMuICovCi0gICAgLy9wcm90ZWN0ZWQgaW50IGVudGl0eUNoYW5nZXMgPSAtMTsKLQotICAgIC8qKiBFbmFibGUgc3luY2hyb25pemUuICovCi0gICAgLy9wcm90ZWN0ZWQgYm9vbGVhbiBmRW5hYmxlU3luY2hyb25pemUgPSBmYWxzZTsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKiBGYWN0b3J5IGNvbnN0cnVjdG9yLiAqLwotICAgIHB1YmxpYyBFbnRpdHlSZWZlcmVuY2VJbXBsKENvcmVEb2N1bWVudEltcGwgb3duZXJEb2MsIFN0cmluZyBuYW1lKSB7Ci0gICAgICAgIHN1cGVyKG93bmVyRG9jKTsKLSAgICAgICAgdGhpcy5uYW1lID0gbmFtZTsKLSAgICAgICAgaXNSZWFkT25seSh0cnVlKTsKLSAgICAgICAgbmVlZHNTeW5jQ2hpbGRyZW4odHJ1ZSk7Ci0gICAgfQotCi0gICAgLy8KLSAgICAvLyBOb2RlIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogQSBzaG9ydCBpbnRlZ2VyIGluZGljYXRpbmcgd2hhdCB0eXBlIG9mIG5vZGUgdGhpcyBpcy4gVGhlIG5hbWVkCi0gICAgICogY29uc3RhbnRzIGZvciB0aGlzIHZhbHVlIGFyZSBkZWZpbmVkIGluIHRoZSBvcmcudzNjLmRvbS5Ob2RlIGludGVyZmFjZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc2hvcnQgZ2V0Tm9kZVR5cGUoKSB7Ci0gICAgICAgIHJldHVybiBOb2RlLkVOVElUWV9SRUZFUkVOQ0VfTk9ERTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSBlbnRpdHkgcmVmZXJlbmNlZAotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Tm9kZU5hbWUoKSB7Ci0gICAgICAgIGlmIChuZWVkc1N5bmNEYXRhKCkpIHsKLSAgICAgICAgICAgIHN5bmNocm9uaXplRGF0YSgpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBuYW1lOwotICAgIH0KLQotICAgIC8qKiBDbG9uZSBub2RlLiAqLwotICAgIHB1YmxpYyBOb2RlIGNsb25lTm9kZShib29sZWFuIGRlZXApIHsKLSAgICAgICAgRW50aXR5UmVmZXJlbmNlSW1wbCBlciA9IChFbnRpdHlSZWZlcmVuY2VJbXBsKXN1cGVyLmNsb25lTm9kZShkZWVwKTsKLSAgICAgICAgZXIuc2V0UmVhZE9ubHkodHJ1ZSwgZGVlcCk7Ci0gICAgICAgIHJldHVybiBlcjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBhYnNvbHV0ZSBiYXNlIFVSSSBvZiB0aGlzIG5vZGUgb3IgbnVsbCBpZiB0aGUgaW1wbGVtZW50YXRpb24KLSAgICAgKiB3YXNuJ3QgYWJsZSB0byBvYnRhaW4gYW4gYWJzb2x1dGUgVVJJLiBOb3RlOiBJZiB0aGUgVVJJIGlzIG1hbGZvcm1lZCwgYQotICAgICAqIG51bGwgaXMgcmV0dXJuZWQuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBhYnNvbHV0ZSBiYXNlIFVSSSBvZiB0aGlzIG5vZGUgb3IgbnVsbC4KLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEJhc2VVUkkoKSB7Ci0gICAgICAgIGlmIChuZWVkc1N5bmNEYXRhKCkpIHsKLSAgICAgICAgICAgIHN5bmNocm9uaXplRGF0YSgpOwotICAgICAgICB9Ci0gICAgICAgIGlmIChiYXNlVVJJID09IG51bGwpIHsKLSAgICAgICAgICAgIERvY3VtZW50VHlwZSBkb2N0eXBlOwotICAgICAgICAgICAgTmFtZWROb2RlTWFwIGVudGl0aWVzOwotICAgICAgICAgICAgRW50aXR5SW1wbCBlbnREZWY7Ci0gICAgICAgICAgICBpZiAobnVsbCAhPSAoZG9jdHlwZSA9IGdldE93bmVyRG9jdW1lbnQoKS5nZXREb2N0eXBlKCkpICYmCi0gICAgICAgICAgICAgICAgbnVsbCAhPSAoZW50aXRpZXMgPSBkb2N0eXBlLmdldEVudGl0aWVzKCkpKSB7Ci0KLSAgICAgICAgICAgICAgICBlbnREZWYgPSAoRW50aXR5SW1wbCllbnRpdGllcy5nZXROYW1lZEl0ZW0oZ2V0Tm9kZU5hbWUoKSk7Ci0gICAgICAgICAgICAgICAgaWYgKGVudERlZiAhPW51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVudERlZi5nZXRCYXNlVVJJKCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9IGVsc2UgaWYgKGJhc2VVUkkgIT0gbnVsbCAmJiBiYXNlVVJJLmxlbmd0aCgpICE9IDAgKSB7Ly8gYXR0cmlidXRlIHZhbHVlIGlzIGFsd2F5cyBlbXB0eSBzdHJpbmcKLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBVUkkoYmFzZVVSSSkudG9TdHJpbmcoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhdGNoIChjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuVVJJLk1hbGZvcm1lZFVSSUV4Y2VwdGlvbiBlKXsKLSAgICAgICAgICAgICAgICAvLyBSRVZJU0lUOiB3aGF0IHNob3VsZCBoYXBwZW4gaW4gdGhpcyBjYXNlPwotICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBiYXNlVVJJOwotICAgIH0KLQotCi0gICAgLyoqIE5PTi1ET006IHNldCBiYXNlIHVyaSovCi0gICAgcHVibGljIHZvaWQgc2V0QmFzZVVSSShTdHJpbmcgdXJpKXsKLSAgICAgICAgaWYgKG5lZWRzU3luY0RhdGEoKSkgewotICAgICAgICAgICAgc3luY2hyb25pemVEYXRhKCk7Ci0gICAgICAgIH0KLSAgICAgICAgYmFzZVVSSSA9IHVyaTsKLSAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIE5PTi1ET006IGNvbXB1dGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBlbnRpdHkgcmVmZXJlbmNlLgotICAgICAqIFRoaXMgbWV0aG9kIGlzIHVzZWQgdG8gcmV0cmlldmUgYSBzdHJpbmcgdmFsdWUgZm9yIGFuIGF0dHJpYnV0ZSBub2RlIHRoYXQgaGFzIGNoaWxkIG5vZGVzLgotICAgICAgICAgKiBAcmV0dXJuIFN0cmluZyByZXByZXNlbnRpbmcgYSB2YWx1ZSBvZiB0aGlzIGVudGl0eSByZWYuIG9yCi0gICAgICogICAgICAgICAgbnVsbCBpZiBhbnkgbm9kZSBvdGhlciB0aGFuIEVudGl0eVJlZmVyZW5jZSwgVGV4dCBpcyBlbmNvdW50ZXJlZAotICAgICAqICAgICAgICAgIGR1cmluZyBjb21wdXRhdGlvbgotICAgICAgICAgKi8KLSAgICBwcm90ZWN0ZWQgU3RyaW5nIGdldEVudGl0eVJlZlZhbHVlICgpewotICAgICAgICBpZiAobmVlZHNTeW5jQ2hpbGRyZW4oKSl7Ci0gICAgICAgICAgICBzeW5jaHJvbml6ZUNoaWxkcmVuKCk7Ci0gICAgICAgIH0KLQotICAgICAgICBTdHJpbmcgdmFsdWUgPSAiIjsKLSAgICAgICAgaWYgKGZpcnN0Q2hpbGQgIT0gbnVsbCl7Ci0gICAgICAgICAgaWYgKGZpcnN0Q2hpbGQuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLkVOVElUWV9SRUZFUkVOQ0VfTk9ERSl7Ci0gICAgICAgICAgICAgIHZhbHVlID0gKChFbnRpdHlSZWZlcmVuY2VJbXBsKWZpcnN0Q2hpbGQpLmdldEVudGl0eVJlZlZhbHVlKCk7Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UgaWYgKGZpcnN0Q2hpbGQuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLlRFWFRfTk9ERSl7Ci0gICAgICAgICAgICB2YWx1ZSA9IGZpcnN0Q2hpbGQuZ2V0Tm9kZVZhbHVlKCk7Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgIC8vIGludmFsaWQgdG8gaGF2ZSBvdGhlciB0eXBlcyBvZiBub2RlcyBpbiBhdHRyIHZhbHVlCi0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgICB9Ci0KLSAgICAgICAgICBpZiAoZmlyc3RDaGlsZC5uZXh0U2libGluZyA9PSBudWxsKXsKLSAgICAgICAgICAgIHJldHVybiB2YWx1ZTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBTdHJpbmdCdWZmZXIgYnVmZiA9IG5ldyBTdHJpbmdCdWZmZXIodmFsdWUpOwotICAgICAgICAgICAgQ2hpbGROb2RlIG5leHQgPSBmaXJzdENoaWxkLm5leHRTaWJsaW5nOwotICAgICAgICAgICAgd2hpbGUgKG5leHQgIT0gbnVsbCl7Ci0KLSAgICAgICAgICAgICAgICBpZiAobmV4dC5nZXROb2RlVHlwZSgpID09IE5vZGUuRU5USVRZX1JFRkVSRU5DRV9OT0RFKXsKLSAgICAgICAgICAgICAgICAgICB2YWx1ZSA9ICgoRW50aXR5UmVmZXJlbmNlSW1wbCluZXh0KS5nZXRFbnRpdHlSZWZWYWx1ZSgpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIGlmIChuZXh0LmdldE5vZGVUeXBlKCkgPT0gTm9kZS5URVhUX05PREUpewotICAgICAgICAgICAgICAgICAgdmFsdWUgPSBuZXh0LmdldE5vZGVWYWx1ZSgpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gaW52YWxpZCB0byBoYXZlIG90aGVyIHR5cGVzIG9mIG5vZGVzIGluIGF0dHIgdmFsdWUKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGJ1ZmYuYXBwZW5kKHZhbHVlKTsKLSAgICAgICAgICAgICAgICBuZXh0ID0gbmV4dC5uZXh0U2libGluZzsKLQotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIGJ1ZmYudG9TdHJpbmcoKTsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuICIiOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEVudGl0eVJlZmVyZW5jZSdzIGNoaWxkcmVuIGFyZSBhIHJlZmxlY3Rpb24gb2YgdGhvc2UgZGVmaW5lZCBpbiB0aGUKLSAgICAgKiBuYW1lZCBFbnRpdHkuIFRoaXMgbWV0aG9kIGNyZWF0ZXMgdGhlbSBpZiB0aGV5IGhhdmVuJ3QgYmVlbiBjcmVhdGVkIHlldC4KLSAgICAgKiBUaGlzIGRvZXNuJ3Qgc3VwcG9ydCBlZGl0aW5nIHRoZSBFbnRpdHkgdGhvdWdoLCBzaW5jZSB0aGlzIG9ubHkgY2FsbGVkCi0gICAgICogb25jZSBmb3IgYWxsLgotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIHN5bmNocm9uaXplQ2hpbGRyZW4oKSB7Ci0gICAgICAgIC8vIG5vIG5lZWQgdG8gc3luY2hyb25pemUgYWdhaW4KLSAgICAgICAgbmVlZHNTeW5jQ2hpbGRyZW4oZmFsc2UpOwotCi0gICAgICAgIERvY3VtZW50VHlwZSBkb2N0eXBlOwotICAgICAgICBOYW1lZE5vZGVNYXAgZW50aXRpZXM7Ci0gICAgICAgIEVudGl0eUltcGwgZW50RGVmOwotICAgICAgICBpZiAobnVsbCAhPSAoZG9jdHlwZSA9IGdldE93bmVyRG9jdW1lbnQoKS5nZXREb2N0eXBlKCkpICYmCi0gICAgICAgICAgICBudWxsICE9IChlbnRpdGllcyA9IGRvY3R5cGUuZ2V0RW50aXRpZXMoKSkpIHsKLQotICAgICAgICAgICAgZW50RGVmID0gKEVudGl0eUltcGwpZW50aXRpZXMuZ2V0TmFtZWRJdGVtKGdldE5vZGVOYW1lKCkpOwotCi0gICAgICAgICAgICAvLyBObyBFbnRpdHkgYnkgdGhpcyBuYW1lLCBzdG9wIGhlcmUuCi0gICAgICAgICAgICBpZiAoZW50RGVmID09IG51bGwpCi0gICAgICAgICAgICAgICAgcmV0dXJuOwotCi0gICAgICAgICAgICAvLyBJZiBlbnRpdHkncyBkZWZpbml0aW9uIGV4aXN0cywgY2xvbmUgaXRzIGtpZHMKLSAgICAgICAgICAgIGlzUmVhZE9ubHkoZmFsc2UpOwotICAgICAgICAgICAgZm9yIChOb2RlIGRlZmtpZCA9IGVudERlZi5nZXRGaXJzdENoaWxkKCk7Ci0gICAgICAgICAgICAgICAgZGVma2lkICE9IG51bGw7Ci0gICAgICAgICAgICAgICAgZGVma2lkID0gZGVma2lkLmdldE5leHRTaWJsaW5nKCkpIHsKLSAgICAgICAgICAgICAgICBOb2RlIG5ld2tpZCA9IGRlZmtpZC5jbG9uZU5vZGUodHJ1ZSk7Ci0gICAgICAgICAgICAgICAgaW5zZXJ0QmVmb3JlKG5ld2tpZCwgbnVsbCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBzZXRSZWFkT25seSh0cnVlLCB0cnVlKTsKLSAgICAgICAgfQotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogTk9OLURPTTogc2V0cyB0aGUgbm9kZSBhbmQgaXRzIGNoaWxkcmVuIHZhbHVlLgotICAgICAqIDxQPgotICAgICAqIE5vdGU6IG1ha2Ugc3VyZSB0aGF0IGVudGl0eSByZWZlcmVuY2UgYW5kIGl0cyBraWRzIGNvdWxkIGJlIHNldCByZWFkb25seS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRSZWFkT25seShib29sZWFuIHJlYWRPbmx5LCBib29sZWFuIGRlZXApIHsKLQotICAgICAgICBpZiAobmVlZHNTeW5jRGF0YSgpKSB7Ci0gICAgICAgICAgICBzeW5jaHJvbml6ZURhdGEoKTsKLSAgICAgICAgfQotICAgICAgICBpZiAoZGVlcCkgewotCi0gICAgICAgICAgICBpZiAobmVlZHNTeW5jQ2hpbGRyZW4oKSkgewotICAgICAgICAgICAgICAgIHN5bmNocm9uaXplQ2hpbGRyZW4oKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIFJlY3Vyc2l2ZWx5IHNldCBraWRzCi0gICAgICAgICAgICBmb3IgKENoaWxkTm9kZSBteWtpZCA9IGZpcnN0Q2hpbGQ7Ci0gICAgICAgICAgICAgICAgIG15a2lkICE9IG51bGw7Ci0gICAgICAgICAgICAgICAgIG15a2lkID0gbXlraWQubmV4dFNpYmxpbmcpIHsKLQotICAgICAgICAgICAgICAgIG15a2lkLnNldFJlYWRPbmx5KHJlYWRPbmx5LHRydWUpOwotCi0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgaXNSZWFkT25seShyZWFkT25seSk7Ci0gICAgfSAvLyBzZXRSZWFkT25seShib29sZWFuLGJvb2xlYW4pCi0KLQotICAgIC8qKgotICAgICAqIEVuYWJsZSB0aGUgc3luY2hyb25pemUgbWV0aG9kIHdoaWNoIG1heSBkbyBjbG9uaW5nLiBUaGlzIG1ldGhvZCBpcyBlbmFibGVkCi0gICAgICogd2hlbiB0aGUgcGFyc2VyIGlzIGRvbmUgd2l0aCBhbiBFbnRpdHlSZWZlcmVuY2UuCi0gICAgLyoqKgotICAgIC8vIHJldmlzaXQ6IGVuYWJsZSBlZGl0aW5nIG9mIEVudGl0eQotICAgIHB1YmxpYyB2b2lkIGVuYWJsZVN5bmNocm9uaXplKGJvb2xlYW4gZW5hYmxlU3luY2hyb25pemUpIHsKLSAgICAgICAgZkVuYWJsZVN5bmNocm9uaXplPSBlbmFibGVTeW5jaHJvbml6ZTsKLSAgICB9Ci0gICAgLyoqKi8KLQotICAgIC8qKgotICAgICAqIEVudGl0eVJlZmVyZW5jZSdzIGNoaWxkcmVuIGFyZSBhIHJlZmxlY3Rpb24gb2YgdGhvc2UgZGVmaW5lZCBpbiB0aGUKLSAgICAgKiBuYW1lZCBFbnRpdHkuIFRoaXMgbWV0aG9kIHVwZGF0ZXMgdGhlbSBpZiB0aGUgRW50aXR5IGlzIGNoYW5nZWQuCi0gICAgICogPFA+Ci0gICAgICogSXQgaXMgdW5jbGVhciB3aGF0IHRoZSBsZWFzdC1jb3N0IHJlc3luY2ggbWVjaGFuaXNtIGlzLgotICAgICAqIElmIHdlIGV4cGVjdCB0aGUga2lkcyB0byBiZSBzaGFsbG93LCBhbmQvb3IgZXhwZWN0IGNoYW5nZXMKLSAgICAgKiB0byB0aGUgRW50aXR5IGNvbnRlbnRzIHRvIGJlIHJhcmUsIHdpcGluZyB0aGVtIGFsbCBvdXQKLSAgICAgKiBhbmQgcmVjbG9uaW5nIGlzIHNpbXBsZXN0LgotICAgICAqIDxQPgotICAgICAqIElmIHdlIGV4cGVjdCB0aGVtIHRvIGJlIGRlZXAsCi0gICAgICogaXQgbWlnaHQgYmUgYmV0dGVyIHRvIGZpcnN0IGRlY2lkZSB3aGljaCBraWRzIChpZiBhbnkpCi0gICAgICogcGVyc2lzdCwgYW5kIGtlZXAgdGhlIG9uZXMgKGlmIGFueSkgdGhhdCBhcmUgdW5jaGFuZ2VkCi0gICAgICogcmF0aGVyIHRoYW4gZG9pbmcgYWxsIHRoZSB3b3JrIG9mIGNsb25pbmcgdGhlbSBhZ2Fpbi4KLSAgICAgKiBCdXQgdGhhdCBsYXR0ZXIgZ2V0cyBpbnRvIGhhdmluZyB0byBjb252b2x2ZSB0aGUgdHdvIGNoaWxkIGxpc3RzLAotICAgICAqIGluc2VydCBuZXcgaW5mb3JtYXRpb24gaW4gdGhlIHJpZ2h0IG9yZGVyIChhbmQgcG9zc2libHkgcmVvcmRlcgotICAgICAqIHRoZSBleGlzdGluZyBraWRzKSwgYW5kIGEgZmV3IG90aGVyIGNvbXBsZXhpdGllcyB0aGF0IEkgcmVhbGx5Ci0gICAgICogZG9uJ3Qgd2FudCB0byBkZWFsIHdpdGggaW4gdGhpcyBpbXBsZW1lbnRhdGlvbi4KLSAgICAgKiA8UD4KLSAgICAgKiBOb3RlIHRoYXQgaWYgd2UgZGVjaWRlIHRoYXQgd2UgbmVlZCB0byB1cGRhdGUgdGhlIEVudGl0eVJlZmVyZW5jZSdzCi0gICAgICogY29udGVudHMsIHdlIGhhdmUgdG8gdHVybiBvZmYgdGhlIHJlYWRPbmx5IGZsYWcgdGVtcG9yYXJpbHkgdG8gZG8gc28uCi0gICAgICogV2hlbiB3ZSBnZXQgYXJvdW5kIHRvIGFkZGluZyBtdWx0aXRhc2tpbmcgc3VwcG9ydCwgdGhpcyB3aG9sZSBtZXRob2QKLSAgICAgKiBzaG91bGQgcHJvYmFibHkgYmUgYW4gYXRvbWljIG9wZXJhdGlvbi4KLSAgICAgKgotICAgICAqIEBzZWUgRG9jdW1lbnRUeXBlSW1wbAotICAgICAqIEBzZWUgRW50aXR5SW1wbAotICAgICAqLwotICAgIC8vIFRoZSBYZXJjZXMgcGFyc2VyIGludm9rZXMgY2FsbGJhY2tzIGZvciBzdGFydEVuaXR5UmVmZXJlbmNlCi0gICAgLy8gdGhlIHBhcnNlZCB2YWx1ZSBvZiB0aGUgZW50aXR5IEVBQ0ggVElNRSwgc28gaXQgaXMgYWN0dWFsbHkKLSAgICAvLyBlYXNpZXIgdG8gY3JlYXRlIHRoZSBub2RlcyB0aHJvdWdoIHRoZSBjYWxsYmFja3MgcmF0aGVyIHRoYW4KLSAgICAvLyBjbG9uZSB0aGUgRW50aXR5LgotICAgIC8qKioKLSAgICAvLyByZXZpc2l0OiBlbmFibGUgZWRpdGluZyBvZiBFbnRpdHkKLSAgICBwcml2YXRlIHZvaWQgc3luY2hyb25pemUoKSB7Ci0gICAgICAgIGlmICghZkVuYWJsZVN5bmNocm9uaXplKSB7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLSAgICAgICAgRG9jdW1lbnRUeXBlIGRvY3R5cGU7Ci0gICAgICAgIE5hbWVkTm9kZU1hcCBlbnRpdGllczsKLSAgICAgICAgRW50aXR5SW1wbCBlbnREZWY7Ci0gICAgICAgIGlmIChudWxsICE9IChkb2N0eXBlID0gZ2V0T3duZXJEb2N1bWVudCgpLmdldERvY3R5cGUoKSkgJiYKLSAgICAgICAgICAgIG51bGwgIT0gKGVudGl0aWVzID0gZG9jdHlwZS5nZXRFbnRpdGllcygpKSkgewotCi0gICAgICAgICAgICBlbnREZWYgPSAoRW50aXR5SW1wbCllbnRpdGllcy5nZXROYW1lZEl0ZW0oZ2V0Tm9kZU5hbWUoKSk7Ci0KLSAgICAgICAgICAgIC8vIE5vIEVudGl0eSBieSB0aGlzIG5hbWUuIElmIHdlIGhhZCBhIGNoYW5nZSBjb3VudCwgcmVzZXQgaXQuCi0gICAgICAgICAgICBpZihudWxsPT1lbnREZWYpCi0gICAgICAgICAgICAgICAgZW50aXR5Q2hhbmdlcz0tMTsKLQotICAgICAgICAgICAgLy8gSWYgbm8ga2lkcyBhdmFpbGFsYmxlLCB3aXBlIGFueSBwcmUtZXhpc3RpbmcgY2hpbGRyZW4uCi0gICAgICAgICAgICAvLyAoU2VlIGRpc2N1c3Npb24gYWJvdmUuKQotICAgICAgICAgICAgLy8gTm90ZSB0aGF0IHdlIGhhdmUgdG8gdXNlIHRoZSBzdXBlcmNsYXNzIHRvIGF2b2lkIHJlY3Vyc2lvbgotICAgICAgICAgICAgLy8gdGhyb3VnaCBTeW5jaHJvbml6ZS4KLSAgICAgICAgICAgIHJlYWRPbmx5PWZhbHNlOwotICAgICAgICAgICAgaWYobnVsbD09ZW50RGVmIHx8ICFlbnREZWYuaGFzQ2hpbGROb2RlcygpKQotICAgICAgICAgICAgICAgIGZvcihOb2RlIGtpZD1zdXBlci5nZXRGaXJzdENoaWxkKCk7Ci0gICAgICAgICAgICAgICAgICAgIGtpZCE9bnVsbDsKLSAgICAgICAgICAgICAgICAgICAga2lkPXN1cGVyLmdldEZpcnN0Q2hpbGQoKSkKLSAgICAgICAgICAgICAgICAgICAgcmVtb3ZlQ2hpbGQoa2lkKTsKLQotICAgICAgICAgICAgLy8gSWYgZW50aXR5J3MgZGVmaW5pdGlvbiBjaGFuZ2VkLCBjbG9uZSBpdHMga2lkcwotICAgICAgICAgICAgLy8gKFNlZSBkaXNjdXNzaW9uIGFib3ZlLikKLSAgICAgICAgICAgIGlmKG51bGwhPWVudERlZiAmJiBlbnREZWYuY2hhbmdlcyE9ZW50aXR5Q2hhbmdlcykgewotICAgICAgICAgICAgICAgIGZvcihOb2RlIGRlZmtpZD1lbnREZWYuZ2V0Rmlyc3RDaGlsZCgpOwotICAgICAgICAgICAgICAgICAgICBkZWZraWQhPW51bGw7Ci0gICAgICAgICAgICAgICAgICAgIGRlZmtpZD1kZWZraWQuZ2V0TmV4dFNpYmxpbmcoKSkgewotCi0gICAgICAgICAgICAgICAgICAgIE5vZGVJbXBsIG5ld2tpZD0oTm9kZUltcGwpIGRlZmtpZC5jbG9uZU5vZGUodHJ1ZSk7Ci0gICAgICAgICAgICAgICAgICAgIG5ld2tpZC5zZXRSZWFkT25seSh0cnVlLHRydWUpOwotICAgICAgICAgICAgICAgICAgICBpbnNlcnRCZWZvcmUobmV3a2lkLG51bGwpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbnRpdHlDaGFuZ2VzPWVudERlZi5jaGFuZ2VzOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmVhZE9ubHk9dHJ1ZTsKLSAgICAgICAgfQotICAgIH0KLSAgICAgLyoqKi8KLQotCi19IC8vIGNsYXNzIEVudGl0eVJlZmVyZW5jZUltcGwKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9MQ291bnQuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9MQ291bnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNzc1NDViZC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vTENvdW50LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw1MCArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDE1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICovCi0vKgotICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCi0gKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKLSAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KLSAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCi0gKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAotICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tOwotCi0KLS8qKiBJbnRlcm5hbCBjbGFzcyBMQ291bnQgaXMgdXNlZCB0byB0cmFjayB0aGUgbnVtYmVyIG9mCi0gICAgbGlzdGVuZXJzIHJlZ2lzdGVyZWQgZm9yIGEgZ2l2ZW4gZXZlbnQgbmFtZSwgYXMgYW4gZW50cnkKLSAgICBpbiBhIGdsb2JhbCBNYXAuIFRoaXMgc2hvdWxkIGFsbG93IHVzIHRvIGF2b2lkIGdlbmVyYXRpbmcsCi0gICAgb3IgZGlzY2FyZGluZywgZXZlbnRzIGZvciB3aGljaCBubyBsaXN0ZW5lcnMgYXJlIHJlZ2lzdGVyZWQuCi0KLSAgICAqKioqKiBUaGVyZSBzaG91bGQgdW5kb3VidGVkbHkgYmUgbWV0aG9kcyBoZXJlIHRvIG1hbmlwdWxhdGUKLSAgICB0aGlzIHRhYmxlLiBBdCB0aGUgbW9tZW50IHRoYXQgY29kZSdzIHJlc2lkaW5nIGluIE5vZGVJbXBsLgotICAgIE1vdmUgaXQgd2hlbiB3ZSBoYXZlIGEgY2hhbmNlIHRvIGRvIHNvLiBTb3JyeTsgd2Ugd2VyZQotICAgIHJ1c2hlZC4KLSovCi0vKioKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKi8KLQotY2xhc3MgTENvdW50Ci17Ci0gICAgc3RhdGljIGZpbmFsIGphdmEudXRpbC5NYXA8U3RyaW5nLCBMQ291bnQ+IGxDb3VudHM9bmV3IGphdmEudXRpbC5jb25jdXJyZW50LkNvbmN1cnJlbnRIYXNoTWFwPD4oKTsKLSAgICBwdWJsaWMgaW50IGNhcHR1cmVzPTAsYnViYmxlcz0wLGRlZmF1bHRzLCB0b3RhbD0wOwotCi0gICAgc3RhdGljIExDb3VudCBsb29rdXAoU3RyaW5nIGV2dE5hbWUpCi0gICAgewotICAgICAgICBMQ291bnQgbGM9KExDb3VudClsQ291bnRzLmdldChldnROYW1lKTsKLSAgICAgICAgaWYobGM9PW51bGwpCi0gICAgICAgICAgICBsQ291bnRzLnB1dChldnROYW1lLChsYz1uZXcgTENvdW50KCkpKTsKLSAgICAgICAgcmV0dXJuIGxjOwotICAgIH0KLX0gLy8gY2xhc3MgTENvdW50CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vTmFtZWROb2RlTWFwSW1wbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL05hbWVkTm9kZU1hcEltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZmNmNDA0Ny4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vTmFtZWROb2RlTWFwSW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNjMwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwMiwyMDA0LDIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tOwotCi1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uT2JqZWN0T3V0cHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOwotaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7Ci1pbXBvcnQgamF2YS51dGlsLkxpc3Q7Ci1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotaW1wb3J0IG9yZy53M2MuZG9tLkRPTUV4Y2VwdGlvbjsKLWltcG9ydCBvcmcudzNjLmRvbS5OYW1lZE5vZGVNYXA7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLQotLyoqCi0gKiBOYW1lZE5vZGVNYXBzIHJlcHJlc2VudCBjb2xsZWN0aW9ucyBvZiBOb2RlcyB0aGF0IGNhbiBiZSBhY2Nlc3NlZAotICogYnkgbmFtZS4gRW50aXR5IGFuZCBOb3RhdGlvbiBub2RlcyBhcmUgc3RvcmVkIGluIE5hbWVkTm9kZU1hcHMKLSAqIGF0dGFjaGVkIHRvIHRoZSBEb2N1bWVudFR5cGUuIEF0dHJpYnV0ZXMgYXJlIHBsYWNlZCBpbiBhIE5hbWVkTm9kZU1hcAotICogYXR0YWNoZWQgdG8gdGhlIGVsZW0gdGhleSdyZSByZWxhdGVkIHRvby4gSG93ZXZlciwgYmVjYXVzZSBhdHRyaWJ1dGVzCi0gKiByZXF1aXJlIG1vcmUgd29yaywgc3VjaCBhcyBmaXJpbmcgbXV0YXRpb24gZXZlbnRzLCB0aGV5IGFyZSBzdG9yZWQgaW4KLSAqIGEgc3ViY2xhc3Mgb2YgTmFtZWROb2RlTWFwSW1wbC4KLSAqIDxQPgotICogT25seSBvbmUgTm9kZSBtYXkgYmUgc3RvcmVkIHBlciBuYW1lOyBhdHRlbXB0aW5nIHRvCi0gKiBzdG9yZSBhbm90aGVyIHdpbGwgcmVwbGFjZSB0aGUgcHJldmlvdXMgdmFsdWUuCi0gKiA8UD4KLSAqIE5PVEU6IFRoZSAicHJpbWFyeSIgc3RvcmFnZSBrZXkgaXMgdGFrZW4gZnJvbSB0aGUgTm9kZU5hbWUgYXR0cmlidXRlIG9mIHRoZQotICogbm9kZS4gVGhlICJzZWNvbmRhcnkiIHN0b3JhZ2Uga2V5IGlzIHRoZSBuYW1lc3BhY2VVUkkgYW5kIGxvY2FsTmFtZSwgd2hlbgotICogYWNjZXNzZWQgYnkgRE9NIGxldmVsIDIgbm9kZXMuIEFsbCBub2RlcywgZXZlbiBET00gTGV2ZWwgMiBub2RlcyBhcmUgc3RvcmVkCi0gKiBpbiBhIHNpbmdsZSBWZWN0b3Igc29ydGVkIGJ5IHRoZSBwcmltYXJ5ICJub2RlbmFtZSIga2V5LgotICogPFA+Ci0gKiBOT1RFOiBpdGVtKCkncyBpbnRlZ2VyIGluZGV4IGRvZXMgX25vdF8gaW1wbHkgdGhhdCB0aGUgbmFtZWQgbm9kZXMKLSAqIG11c3QgYmUgc3RvcmVkIGluIGFuIGFycmF5OyB0aGF0J3Mgb25seSBhbiBhY2Nlc3MgbWV0aG9kLiBOb3RlIHRvbwotICogdGhhdCB0aGVzZSBpbmRpY2VzIGFyZSAibGl2ZSI7IGlmIHNvbWVvbmUgY2hhbmdlcyB0aGUgbWFwJ3MKLSAqIGNvbnRlbnRzLCB0aGUgaW5kaWNlcyBhc3NvY2lhdGVkIHdpdGggbm9kZXMgbWF5IGNoYW5nZS4KLSAqIDxQPgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAdmVyc2lvbiAkSWQ6IE5hbWVkTm9kZU1hcEltcGwuamF2YSx2IDEuOCAyMDEwLTExLTAxIDA0OjM5OjM5IGpvZWh3IEV4cCAkCi0gKiBAc2luY2UgIFBSLURPTS1MZXZlbC0xLTE5OTgwODE4LgotICovCi1wdWJsaWMgY2xhc3MgTmFtZWROb2RlTWFwSW1wbAotICAgIGltcGxlbWVudHMgTmFtZWROb2RlTWFwLCBTZXJpYWxpemFibGUgewotCi0gICAgLy8KLSAgICAvLyBDb25zdGFudHMKLSAgICAvLwotCi0gICAgLyoqIFNlcmlhbGl6YXRpb24gdmVyc2lvbi4gKi8KLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTcwMzkyNDI0NTEwNDY3NTgwMjBMOwotCi0gICAgLy8KLSAgICAvLyBEYXRhCi0gICAgLy8KLQotICAgIHByb3RlY3RlZCBzaG9ydCBmbGFnczsKLQotICAgIHByb3RlY3RlZCBmaW5hbCBzdGF0aWMgc2hvcnQgUkVBRE9OTFkgICAgID0gMHgxPDwwOwotICAgIHByb3RlY3RlZCBmaW5hbCBzdGF0aWMgc2hvcnQgQ0hBTkdFRCAgICAgID0gMHgxPDwxOwotICAgIHByb3RlY3RlZCBmaW5hbCBzdGF0aWMgc2hvcnQgSEFTREVGQVVMVFMgID0gMHgxPDwyOwotCi0gICAgLyoqIE5vZGVzLiAqLwotICAgIHByb3RlY3RlZCBMaXN0IG5vZGVzOwotCi0gICAgcHJvdGVjdGVkIE5vZGVJbXBsIG93bmVyTm9kZTsgLy8gdGhlIG5vZGUgdGhpcyBtYXAgYmVsb25ncyB0bwotCi0gICAgLy8KLSAgICAvLyBDb25zdHJ1Y3RvcnMKLSAgICAvLwotCi0gICAgLyoqIENvbnN0cnVjdHMgYSBuYW1lZCBub2RlIG1hcC4gKi8KLSAgICBwcm90ZWN0ZWQgTmFtZWROb2RlTWFwSW1wbChOb2RlSW1wbCBvd25lck5vZGUpIHsKLSAgICAgICAgdGhpcy5vd25lck5vZGUgPSBvd25lck5vZGU7Ci0gICAgfQotCi0gICAgLy8KLSAgICAvLyBOYW1lZE5vZGVNYXAgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBSZXBvcnQgaG93IG1hbnkgbm9kZXMgYXJlIGN1cnJlbnRseSBzdG9yZWQgaW4gdGhpcyBOYW1lZE5vZGVNYXAuCi0gICAgICogQ2F2ZWF0OiBUaGlzIGlzIGEgY291bnQgcmF0aGVyIHRoYW4gYW4gaW5kZXgsIHNvIHRoZQotICAgICAqIGhpZ2hlc3QtbnVtYmVyZWQgbm9kZSBhdCBhbnkgdGltZSBjYW4gYmUgYWNjZXNzZWQgdmlhCi0gICAgICogaXRlbShnZXRMZW5ndGgoKS0xKS4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldExlbmd0aCgpIHsKLSAgICAgICAgcmV0dXJuIChub2RlcyAhPSBudWxsKSA/IG5vZGVzLnNpemUoKSA6IDA7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0cmlldmUgYW4gaXRlbSBmcm9tIHRoZSBtYXAgYnkgMC1iYXNlZCBpbmRleC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBpbmRleCBXaGljaCBpdGVtIHRvIHJldHJpZXZlLiBOb3RlIHRoYXQgaW5kaWNlcyBhcmUganVzdCBhbgotICAgICAqIGVudW1lcmF0aW9uIG9mIHRoZSBjdXJyZW50IGNvbnRlbnRzOyB0aGV5IGFyZW4ndCBndWFyYW50ZWVkIHRvIGJlCi0gICAgICogc3RhYmxlLCBub3IgZG8gdGhleSBpbXBseSBhbnkgcHJvbWlzZXMgYWJvdXQgdGhlIG9yZGVyIG9mIHRoZQotICAgICAqIE5hbWVkTm9kZU1hcCdzIGNvbnRlbnRzLiBJbiBvdGhlciB3b3JkcywgRE8gTk9UIGFzc3VtZSBlaXRoZXIgdGhhdAotICAgICAqIGluZGV4KGkpIHdpbGwgYWx3YXlzIHJlZmVyIHRvIHRoZSBzYW1lIGVudHJ5LCBvciB0aGF0IHRoZXJlIGlzIGFueQotICAgICAqIHN0YWJsZSBvcmRlcmluZyBvZiBlbnRyaWVzLi4uIGFuZCBiZSBwcmVwYXJlZCBmb3IgZG91YmxlLXJlcG9ydGluZwotICAgICAqIG9yIHNraXBzIGFzIGluc2VydGlvbiBhbmQgZGVsZXRpb24gb2NjdXIuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRoZSBub2RlIHdoaWNoIGN1cnJlbmx5IGhhcyB0aGUgc3BlY2lmaWVkIGluZGV4LCBvciBudWxsIGlmIGluZGV4Ci0gICAgICogaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIGdldExlbmd0aCgpLgotICAgICAqLwotICAgIHB1YmxpYyBOb2RlIGl0ZW0oaW50IGluZGV4KSB7Ci0gICAgICAgIHJldHVybiAobm9kZXMgIT0gbnVsbCAmJiBpbmRleCA8IG5vZGVzLnNpemUoKSkgPwotICAgICAgICAgICAgICAgICAgICAoTm9kZSkobm9kZXMuZ2V0KGluZGV4KSkgOiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHJpZXZlIGEgbm9kZSBieSBuYW1lLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgTmFtZSBvZiBhIG5vZGUgdG8gbG9vayB1cC4KLSAgICAgKiBAcmV0dXJuIHRoZSBOb2RlIChvZiB1bnNwZWNpZmllZCBzdWItY2xhc3MpIHN0b3JlZCB3aXRoIHRoYXQgbmFtZSwgb3IKLSAgICAgKiBudWxsIGlmIG5vIHZhbHVlIGhhcyBiZWVuIGFzc2lnbmVkIHRvIHRoYXQgbmFtZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgTm9kZSBnZXROYW1lZEl0ZW0oU3RyaW5nIG5hbWUpIHsKLQotICAgICAgICBpbnQgaSA9IGZpbmROYW1lUG9pbnQobmFtZSwwKTsKLSAgICAgICAgcmV0dXJuIChpIDwgMCkgPyBudWxsIDogKE5vZGUpKG5vZGVzLmdldChpKSk7Ci0KLSAgICB9IC8vIGdldE5hbWVkSXRlbShTdHJpbmcpOk5vZGUKLQotICAgIC8qKgotICAgICAqIEludHJvZHVjZWQgaW4gRE9NIExldmVsIDIuIDxwPgotICAgICAqIFJldHJpZXZlcyBhIG5vZGUgc3BlY2lmaWVkIGJ5IGxvY2FsIG5hbWUgYW5kIG5hbWVzcGFjZSBVUkkuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZXNwYWNlVVJJICBUaGUgbmFtZXNwYWNlIFVSSSBvZiB0aGUgbm9kZSB0byByZXRyaWV2ZS4KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBXaGVuIGl0IGlzIG51bGwgb3IgYW4gZW1wdHkgc3RyaW5nLCB0aGlzCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgbWV0aG9kIGJlaGF2ZXMgbGlrZSBnZXROYW1lZEl0ZW0uCi0gICAgICogQHBhcmFtIGxvY2FsTmFtZSAgICAgVGhlIGxvY2FsIG5hbWUgb2YgdGhlIG5vZGUgdG8gcmV0cmlldmUuCi0gICAgICogQHJldHVybiBOb2RlICAgICAgICAgQSBOb2RlIChvZiBhbnkgdHlwZSkgd2l0aCB0aGUgc3BlY2lmaWVkIG5hbWUsIG9yIG51bGwgaWYgdGhlIHNwZWNpZmllZAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIG5hbWUgZGlkIG5vdCBpZGVudGlmeSBhbnkgbm9kZSBpbiB0aGUgbWFwLgotICAgICAqLwotICAgIHB1YmxpYyBOb2RlIGdldE5hbWVkSXRlbU5TKFN0cmluZyBuYW1lc3BhY2VVUkksIFN0cmluZyBsb2NhbE5hbWUpIHsKLQotICAgICAgICBpbnQgaSA9IGZpbmROYW1lUG9pbnQobmFtZXNwYWNlVVJJLCBsb2NhbE5hbWUpOwotICAgICAgICByZXR1cm4gKGkgPCAwKSA/IG51bGwgOiAoTm9kZSkobm9kZXMuZ2V0KGkpKTsKLQotICAgIH0gLy8gZ2V0TmFtZWRJdGVtTlMoU3RyaW5nLFN0cmluZyk6Tm9kZQotCi0gICAgLyoqCi0gICAgICogQWRkcyBhIG5vZGUgdXNpbmcgaXRzIG5vZGVOYW1lIGF0dHJpYnV0ZS4KLSAgICAgKiBBcyB0aGUgbm9kZU5hbWUgYXR0cmlidXRlIGlzIHVzZWQgdG8gZGVyaXZlIHRoZSBuYW1lIHdoaWNoIHRoZSBub2RlIG11c3QgYmUKLSAgICAgKiBzdG9yZWQgdW5kZXIsIG11bHRpcGxlIG5vZGVzIG9mIGNlcnRhaW4gdHlwZXMgKHRob3NlIHRoYXQgaGF2ZSBhICJzcGVjaWFsIiBzdHJpbmcKLSAgICAgKiB2YWx1ZSkgY2Fubm90IGJlIHN0b3JlZCBhcyB0aGUgbmFtZXMgd291bGQgY2xhc2guIFRoaXMgaXMgc2VlbiBhcyBwcmVmZXJhYmxlIHRvCi0gICAgICogYWxsb3dpbmcgbm9kZXMgdG8gYmUgYWxpYXNlZC4KLSAgICAgKiBAc2VlIG9yZy53M2MuZG9tLk5hbWVkTm9kZU1hcCNzZXROYW1lZEl0ZW0KLSAgICAgKiBAcmV0dXJuIElmIHRoZSBuZXcgTm9kZSByZXBsYWNlcyBhbiBleGlzdGluZyBub2RlIHRoZSByZXBsYWNlZCBOb2RlIGlzIHJldHVybmVkLAotICAgICAqICAgICAgb3RoZXJ3aXNlIG51bGwgaXMgcmV0dXJuZWQuCi0gICAgICogQHBhcmFtIGFyZwotICAgICAqICAgICAgQSBub2RlIHRvIHN0b3JlIGluIGEgbmFtZWQgbm9kZSBtYXAuIFRoZSBub2RlIHdpbGwgbGF0ZXIgYmUKLSAgICAgKiAgICAgIGFjY2Vzc2libGUgdXNpbmcgdGhlIHZhbHVlIG9mIHRoZSBuYW1lc3BhY2VVUkkgYW5kIGxvY2FsTmFtZQotICAgICAqICAgICAgYXR0cmlidXRlIG9mIHRoZSBub2RlLiBJZiBhIG5vZGUgd2l0aCB0aG9zZSBuYW1lc3BhY2UgVVJJIGFuZAotICAgICAqICAgICAgbG9jYWwgbmFtZSBpcyBhbHJlYWR5IHByZXNlbnQgaW4gdGhlIG1hcCwgaXQgaXMgcmVwbGFjZWQgYnkgdGhlIG5ldwotICAgICAqICAgICAgb25lLgotICAgICAqIEBleGNlcHRpb24gb3JnLnczYy5kb20uRE9NRXhjZXB0aW9uIFRoZSBleGNlcHRpb24gZGVzY3JpcHRpb24uCi0gICAgICovCi0gICAgcHVibGljIE5vZGUgc2V0TmFtZWRJdGVtKE5vZGUgYXJnKQotICAgIHRocm93cyBET01FeGNlcHRpb24gewotCi0gICAgICAgIENvcmVEb2N1bWVudEltcGwgb3duZXJEb2N1bWVudCA9IG93bmVyTm9kZS5vd25lckRvY3VtZW50KCk7Ci0gICAgICAgIGlmIChvd25lckRvY3VtZW50LmVycm9yQ2hlY2tpbmcpIHsKLSAgICAgICAgICAgIGlmIChpc1JlYWRPbmx5KCkpIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgbXNnID0gRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwgIk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiIsIG51bGwpOwotICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiwgbXNnKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChhcmcuZ2V0T3duZXJEb2N1bWVudCgpICE9IG93bmVyRG9jdW1lbnQpIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgbXNnID0gRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwgIldST05HX0RPQ1VNRU5UX0VSUiIsIG51bGwpOwotICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLldST05HX0RPQ1VNRU5UX0VSUiwgbXNnKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGludCBpID0gZmluZE5hbWVQb2ludChhcmcuZ2V0Tm9kZU5hbWUoKSwwKTsKLSAgICAgICAgTm9kZUltcGwgcHJldmlvdXMgPSBudWxsOwotICAgICAgICBpZiAoaSA+PSAwKSB7Ci0gICAgICAgICAgICBwcmV2aW91cyA9IChOb2RlSW1wbCkgbm9kZXMuZ2V0KGkpOwotICAgICAgICAgICAgbm9kZXMuc2V0KGksIGFyZyk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBpID0gLTEgLSBpOyAvLyBJbnNlcnQgcG9pbnQgKG1heSBiZSBlbmQgb2YgbGlzdCkKLSAgICAgICAgICAgIGlmIChudWxsID09IG5vZGVzKSB7Ci0gICAgICAgICAgICAgICAgbm9kZXMgPSBuZXcgQXJyYXlMaXN0KDUpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgbm9kZXMuYWRkKGksIGFyZyk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHByZXZpb3VzOwotCi0gICAgfSAvLyBzZXROYW1lZEl0ZW0oTm9kZSk6Tm9kZQotCi0gICAgLyoqCi0gICAgICogQWRkcyBhIG5vZGUgdXNpbmcgaXRzIG5hbWVzcGFjZVVSSSBhbmQgbG9jYWxOYW1lLgotICAgICAqIEBzZWUgb3JnLnczYy5kb20uTmFtZWROb2RlTWFwI3NldE5hbWVkSXRlbQotICAgICAqIEByZXR1cm4gSWYgdGhlIG5ldyBOb2RlIHJlcGxhY2VzIGFuIGV4aXN0aW5nIG5vZGUgdGhlIHJlcGxhY2VkIE5vZGUgaXMgcmV0dXJuZWQsCi0gICAgICogICAgICBvdGhlcndpc2UgbnVsbCBpcyByZXR1cm5lZC4KLSAgICAgKiBAcGFyYW0gYXJnIEEgbm9kZSB0byBzdG9yZSBpbiBhIG5hbWVkIG5vZGUgbWFwLiBUaGUgbm9kZSB3aWxsIGxhdGVyIGJlCi0gICAgICogICAgICBhY2Nlc3NpYmxlIHVzaW5nIHRoZSB2YWx1ZSBvZiB0aGUgbmFtZXNwYWNlVVJJIGFuZCBsb2NhbE5hbWUKLSAgICAgKiAgICAgIGF0dHJpYnV0ZSBvZiB0aGUgbm9kZS4gSWYgYSBub2RlIHdpdGggdGhvc2UgbmFtZXNwYWNlIFVSSSBhbmQKLSAgICAgKiAgICAgIGxvY2FsIG5hbWUgaXMgYWxyZWFkeSBwcmVzZW50IGluIHRoZSBtYXAsIGl0IGlzIHJlcGxhY2VkIGJ5IHRoZSBuZXcKLSAgICAgKiAgICAgIG9uZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgTm9kZSBzZXROYW1lZEl0ZW1OUyhOb2RlIGFyZykKLSAgICB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKLQotICAgICAgICBDb3JlRG9jdW1lbnRJbXBsIG93bmVyRG9jdW1lbnQgPSBvd25lck5vZGUub3duZXJEb2N1bWVudCgpOwotICAgICAgICBpZiAob3duZXJEb2N1bWVudC5lcnJvckNoZWNraW5nKSB7Ci0gICAgICAgICAgICBpZiAoaXNSZWFkT25seSgpKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIG1zZyA9IERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sICJOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIiLCBudWxsKTsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIsIG1zZyk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmKGFyZy5nZXRPd25lckRvY3VtZW50KCkgIT0gb3duZXJEb2N1bWVudCkgewotICAgICAgICAgICAgICAgIFN0cmluZyBtc2cgPSBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiV1JPTkdfRE9DVU1FTlRfRVJSIiwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uV1JPTkdfRE9DVU1FTlRfRVJSLCBtc2cpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgaW50IGkgPSBmaW5kTmFtZVBvaW50KGFyZy5nZXROYW1lc3BhY2VVUkkoKSwgYXJnLmdldExvY2FsTmFtZSgpKTsKLSAgICAgICAgTm9kZUltcGwgcHJldmlvdXMgPSBudWxsOwotICAgICAgICBpZiAoaSA+PSAwKSB7Ci0gICAgICAgICAgICBwcmV2aW91cyA9IChOb2RlSW1wbCkgbm9kZXMuZ2V0KGkpOwotICAgICAgICAgICAgbm9kZXMuc2V0KGksIGFyZyk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAvLyBJZiB3ZSBjYW4ndCBmaW5kIGJ5IG5hbWVzcGFjZVVSSSwgbG9jYWxOYW1lLCB0aGVuIHdlIGZpbmQgYnkKLSAgICAgICAgICAgIC8vIG5vZGVOYW1lIHNvIHdlIGtub3cgd2hlcmUgdG8gaW5zZXJ0LgotICAgICAgICAgICAgaSA9IGZpbmROYW1lUG9pbnQoYXJnLmdldE5vZGVOYW1lKCksMCk7Ci0gICAgICAgICAgICBpZiAoaSA+PSAwKSB7Ci0gICAgICAgICAgICAgICAgcHJldmlvdXMgPSAoTm9kZUltcGwpIG5vZGVzLmdldChpKTsKLSAgICAgICAgICAgICAgICBub2Rlcy5hZGQoaSwgYXJnKTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgaSA9IC0xIC0gaTsgLy8gSW5zZXJ0IHBvaW50IChtYXkgYmUgZW5kIG9mIGxpc3QpCi0gICAgICAgICAgICAgICAgaWYgKG51bGwgPT0gbm9kZXMpIHsKLSAgICAgICAgICAgICAgICAgICAgbm9kZXMgPSBuZXcgQXJyYXlMaXN0KDUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBub2Rlcy5hZGQoaSwgYXJnKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gcHJldmlvdXM7Ci0KLSAgICB9IC8vIHNldE5hbWVkSXRlbU5TKE5vZGUpOk5vZGUKLQotICAgIC8qKgotICAgICAqIFJlbW92ZXMgYSBub2RlIHNwZWNpZmllZCBieSBuYW1lLgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIGEgbm9kZSB0byByZW1vdmUuCi0gICAgICogQHJldHVybiBUaGUgbm9kZSByZW1vdmVkIGZyb20gdGhlIG1hcCBpZiBhIG5vZGUgd2l0aCBzdWNoIGEgbmFtZSBleGlzdHMuCi0gICAgICovCi0gICAgLyoqKi8KLSAgICBwdWJsaWMgTm9kZSByZW1vdmVOYW1lZEl0ZW0oU3RyaW5nIG5hbWUpCi0gICAgICAgIHRocm93cyBET01FeGNlcHRpb24gewotCi0gICAgICAgIGlmIChpc1JlYWRPbmx5KCkpIHsKLSAgICAgICAgICAgIFN0cmluZyBtc2cgPSBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIiwgbnVsbCk7Ci0gICAgICAgICAgICB0aHJvdwotICAgICAgICAgICAgICAgIG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiwKLSAgICAgICAgICAgICAgICBtc2cpOwotICAgICAgICB9Ci0gICAgICAgIGludCBpID0gZmluZE5hbWVQb2ludChuYW1lLDApOwotICAgICAgICBpZiAoaSA8IDApIHsKLSAgICAgICAgICAgIFN0cmluZyBtc2cgPSBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiTk9UX0ZPVU5EX0VSUiIsIG51bGwpOwotICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX0ZPVU5EX0VSUiwgbXNnKTsKLSAgICAgICAgfQotCi0gICAgICAgIE5vZGVJbXBsIG4gPSAoTm9kZUltcGwpbm9kZXMuZ2V0KGkpOwotICAgICAgICBub2Rlcy5yZW1vdmUoaSk7Ci0KLSAgICAgICAgcmV0dXJuIG47Ci0KLSAgICB9IC8vIHJlbW92ZU5hbWVkSXRlbShTdHJpbmcpOk5vZGUKLQotICAgIC8qKgotICAgICAqIEludHJvZHVjZWQgaW4gRE9NIExldmVsIDIuIDxwPgotICAgICAqIFJlbW92ZXMgYSBub2RlIHNwZWNpZmllZCBieSBsb2NhbCBuYW1lIGFuZCBuYW1lc3BhY2UgVVJJLgotICAgICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBUaGUgbmFtZXNwYWNlIFVSSSBvZiB0aGUgbm9kZSB0byByZW1vdmUuCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgV2hlbiBpdCBpcyBudWxsIG9yIGFuIGVtcHR5IHN0cmluZywgdGhpcwotICAgICAqICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZCBiZWhhdmVzIGxpa2UgcmVtb3ZlTmFtZWRJdGVtLgotICAgICAqIEBwYXJhbSBuYW1lICAgICAgICAgIFRoZSBsb2NhbCBuYW1lIG9mIHRoZSBub2RlIHRvIHJlbW92ZS4KLSAgICAgKiBAcmV0dXJuIE5vZGUgICAgICAgICBUaGUgbm9kZSByZW1vdmVkIGZyb20gdGhlIG1hcCBpZiBhIG5vZGUgd2l0aCBzdWNoCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgYSBsb2NhbCBuYW1lIGFuZCBuYW1lc3BhY2UgVVJJIGV4aXN0cy4KLSAgICAgKiBAdGhyb3dzICAgICAgICAgICAgICBOT1RfRk9VTkRfRVJSOiBSYWlzZWQgaWYgdGhlcmUgaXMgbm8gbm9kZSBuYW1lZAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIG5hbWUgaW4gdGhlIG1hcC4KLQotICAgICAqLwotICAgICBwdWJsaWMgTm9kZSByZW1vdmVOYW1lZEl0ZW1OUyhTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgbmFtZSkKLSAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgaWYgKGlzUmVhZE9ubHkoKSkgewotICAgICAgICAgICAgU3RyaW5nIG1zZyA9IERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sICJOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIiLCBudWxsKTsKLSAgICAgICAgICAgIHRocm93Ci0gICAgICAgICAgICAgICAgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSLAotICAgICAgICAgICAgICAgIG1zZyk7Ci0gICAgICAgIH0KLSAgICAgICAgaW50IGkgPSBmaW5kTmFtZVBvaW50KG5hbWVzcGFjZVVSSSwgbmFtZSk7Ci0gICAgICAgIGlmIChpIDwgMCkgewotICAgICAgICAgICAgU3RyaW5nIG1zZyA9IERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sICJOT1RfRk9VTkRfRVJSIiwgbnVsbCk7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfRk9VTkRfRVJSLCBtc2cpOwotICAgICAgICB9Ci0KLSAgICAgICAgTm9kZUltcGwgbiA9IChOb2RlSW1wbClub2Rlcy5nZXQoaSk7Ci0gICAgICAgIG5vZGVzLnJlbW92ZShpKTsKLQotICAgICAgICByZXR1cm4gbjsKLQotICAgIH0gLy8gcmVtb3ZlTmFtZWRJdGVtKFN0cmluZyk6Tm9kZQotCi0gICAgLy8KLSAgICAvLyBQdWJsaWMgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBDbG9uaW5nIGEgTmFtZWROb2RlTWFwIGlzIGEgREVFUCBPUEVSQVRJT047IGl0IGFsd2F5cyBjbG9uZXMKLSAgICAgKiBhbGwgdGhlIG5vZGVzIGNvbnRhaW5lZCBpbiB0aGUgbWFwLgotICAgICAqLwotCi0gICAgcHVibGljIE5hbWVkTm9kZU1hcEltcGwgY2xvbmVNYXAoTm9kZUltcGwgb3duZXJOb2RlKSB7Ci0gICAgICAgIE5hbWVkTm9kZU1hcEltcGwgbmV3bWFwID0gbmV3IE5hbWVkTm9kZU1hcEltcGwob3duZXJOb2RlKTsKLSAgICAgICAgbmV3bWFwLmNsb25lQ29udGVudCh0aGlzKTsKLSAgICAgICAgcmV0dXJuIG5ld21hcDsKLSAgICB9Ci0KLSAgICBwcm90ZWN0ZWQgdm9pZCBjbG9uZUNvbnRlbnQoTmFtZWROb2RlTWFwSW1wbCBzcmNtYXApIHsKLSAgICAgICAgTGlzdCBzcmNub2RlcyA9IHNyY21hcC5ub2RlczsKLSAgICAgICAgaWYgKHNyY25vZGVzICE9IG51bGwpIHsKLSAgICAgICAgICAgIGludCBzaXplID0gc3Jjbm9kZXMuc2l6ZSgpOwotICAgICAgICAgICAgaWYgKHNpemUgIT0gMCkgewotICAgICAgICAgICAgICAgIGlmIChub2RlcyA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIG5vZGVzID0gbmV3IEFycmF5TGlzdChzaXplKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIG5vZGVzLmNsZWFyKCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgKytpKSB7Ci0gICAgICAgICAgICAgICAgICAgIE5vZGVJbXBsIG4gPSAoTm9kZUltcGwpIHNyY21hcC5ub2Rlcy5nZXQoaSk7Ci0gICAgICAgICAgICAgICAgICAgIE5vZGVJbXBsIGNsb25lID0gKE5vZGVJbXBsKSBuLmNsb25lTm9kZSh0cnVlKTsKLSAgICAgICAgICAgICAgICAgICAgY2xvbmUuaXNTcGVjaWZpZWQobi5pc1NwZWNpZmllZCgpKTsKLSAgICAgICAgICAgICAgICAgICAgbm9kZXMuYWRkKGNsb25lKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9IC8vIGNsb25lTWFwKCk6TmFtZWROb2RlTWFwSW1wbAotCi0gICAgLy8KLSAgICAvLyBQYWNrYWdlIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogSW50ZXJuYWwgc3Vicm91dGluZSB0byBhbGxvdyByZWFkLW9ubHkgTm9kZXMgdG8gbWFrZSB0aGVpciBjb250YWluZWQKLSAgICAgKiBOYW1lZE5vZGVNYXBzIHJlYWRvbmx5IHRvby4gSSBleHBlY3QgdGhhdCBpbiBmYWN0IHRoZSBzaGFsbG93Ci0gICAgICogdmVyc2lvbiBvZiB0aGlzIG9wZXJhdGlvbiB3aWxsIG5ldmVyIGJlCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcmVhZE9ubHkgYm9vbGVhbiB0cnVlIHRvIG1ha2UgcmVhZC1vbmx5LCBmYWxzZSB0byBwZXJtaXQgZWRpdGluZy4KLSAgICAgKiBAcGFyYW0gZGVlcCBib29sZWFuIHRydWUgdG8gcGFzcyB0aGlzIHJlcXVlc3QgYWxvbmcgdG8gdGhlIGNvbnRhaW5lZAotICAgICAqIG5vZGVzLCBmYWxzZSB0byBvbmx5IHRvZ2dsZSB0aGUgTmFtZWROb2RlTWFwIGl0c2VsZi4gSSBleHBlY3QgdGhhdAotICAgICAqIHRoZSBzaGFsbG93IHZlcnNpb24gb2YgdGhpcyBvcGVyYXRpb24gd2lsbCBuZXZlciBiZSB1c2VkLCBidXQgSSB3YW50Ci0gICAgICogdG8gZGVzaWduIGl0IGluIG5vdywgd2hpbGUgSSdtIHRoaW5raW5nIGFib3V0IGl0LgotICAgICAqLwotICAgIHZvaWQgc2V0UmVhZE9ubHkoYm9vbGVhbiByZWFkT25seSwgYm9vbGVhbiBkZWVwKSB7Ci0gICAgICAgIGlzUmVhZE9ubHkocmVhZE9ubHkpOwotICAgICAgICBpZiAoZGVlcCAmJiBub2RlcyAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gbm9kZXMuc2l6ZSgpIC0gMTsgaSA+PSAwOyBpLS0pIHsKLSAgICAgICAgICAgICAgICAoKE5vZGVJbXBsKSBub2Rlcy5nZXQoaSkpLnNldFJlYWRPbmx5KHJlYWRPbmx5LGRlZXApOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfSAvLyBzZXRSZWFkT25seShib29sZWFuLGJvb2xlYW4pCi0KLSAgICAvKioKLSAgICAgKiBJbnRlcm5hbCBzdWJyb3V0aW5lIHJldHVybnMgdGhpcyBOb2RlTmFtZU1hcCdzIChzaGFsbG93KSByZWFkT25seSB2YWx1ZS4KLSAgICAgKgotICAgICAqLwotICAgIGJvb2xlYW4gZ2V0UmVhZE9ubHkoKSB7Ci0gICAgICAgIHJldHVybiBpc1JlYWRPbmx5KCk7Ci0gICAgfSAvLyBnZXRSZWFkT25seSgpCi0KLQotICAgIC8vCi0gICAgLy8gUHJvdGVjdGVkIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogTk9OLURPTQotICAgICAqIHNldCB0aGUgb3duZXJEb2N1bWVudCBvZiB0aGlzIG5vZGUsIGFuZCB0aGUgYXR0cmlidXRlcyBpdCBjb250YWlucwotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIHNldE93bmVyRG9jdW1lbnQoQ29yZURvY3VtZW50SW1wbCBkb2MpIHsKLSAgICAgICAgaWYgKG5vZGVzICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZpbmFsIGludCBzaXplID0gbm9kZXMuc2l6ZSgpOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyArK2kpIHsKLSAgICAgICAgICAgICAgICAoKE5vZGVJbXBsKWl0ZW0oaSkpLnNldE93bmVyRG9jdW1lbnQoZG9jKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIGZpbmFsIGJvb2xlYW4gaXNSZWFkT25seSgpIHsKLSAgICAgICAgcmV0dXJuIChmbGFncyAmIFJFQURPTkxZKSAhPSAwOwotICAgIH0KLQotICAgIGZpbmFsIHZvaWQgaXNSZWFkT25seShib29sZWFuIHZhbHVlKSB7Ci0gICAgICAgIGZsYWdzID0gKHNob3J0KSAodmFsdWUgPyBmbGFncyB8IFJFQURPTkxZIDogZmxhZ3MgJiB+UkVBRE9OTFkpOwotICAgIH0KLQotICAgIGZpbmFsIGJvb2xlYW4gY2hhbmdlZCgpIHsKLSAgICAgICAgcmV0dXJuIChmbGFncyAmIENIQU5HRUQpICE9IDA7Ci0gICAgfQotCi0gICAgZmluYWwgdm9pZCBjaGFuZ2VkKGJvb2xlYW4gdmFsdWUpIHsKLSAgICAgICAgZmxhZ3MgPSAoc2hvcnQpICh2YWx1ZSA/IGZsYWdzIHwgQ0hBTkdFRCA6IGZsYWdzICYgfkNIQU5HRUQpOwotICAgIH0KLQotICAgIGZpbmFsIGJvb2xlYW4gaGFzRGVmYXVsdHMoKSB7Ci0gICAgICAgIHJldHVybiAoZmxhZ3MgJiBIQVNERUZBVUxUUykgIT0gMDsKLSAgICB9Ci0KLSAgICBmaW5hbCB2b2lkIGhhc0RlZmF1bHRzKGJvb2xlYW4gdmFsdWUpIHsKLSAgICAgICAgZmxhZ3MgPSAoc2hvcnQpICh2YWx1ZSA/IGZsYWdzIHwgSEFTREVGQVVMVFMgOiBmbGFncyAmIH5IQVNERUZBVUxUUyk7Ci0gICAgfQotCi0gICAgLy8KLSAgICAvLyBQcml2YXRlIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogU3Vicm91dGluZTogTG9jYXRlIHRoZSBuYW1lZCBpdGVtLCBvciB0aGUgcG9pbnQgYXQgd2hpY2ggc2FpZCBpdGVtCi0gICAgICogc2hvdWxkIGJlIGFkZGVkLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgTmFtZSBvZiBhIG5vZGUgdG8gbG9vayB1cC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gSWYgcG9zaXRpdmUgb3IgemVybywgdGhlIGluZGV4IG9mIHRoZSBmb3VuZCBpdGVtLgotICAgICAqIElmIG5lZ2F0aXZlLCBpbmRleCBvZiB0aGUgYXBwcm9wcmlhdGUgcG9pbnQgYXQgd2hpY2ggdG8gaW5zZXJ0Ci0gICAgICogdGhlIGl0ZW0sIGVuY29kZWQgYXMgLTEtaW5kZXggYW5kIGhlbmNlIHJlY29udmVydGFibGUgYnkgc3VidHJhY3RpbmcKLSAgICAgKiBpdCBmcm9tIC0xLiAoRW5jb2RpbmcgYmVjYXVzZSBJIGRvbid0IHdhbnQgdG8gcmVjb21wYXJlIHRoZSBzdHJpbmdzCi0gICAgICogYnV0IGRvbid0IHdhbnQgdG8gYnVybiBieXRlcyBvbiBhIGRhdGF0eXBlIHRvIGhvbGQgYSBmbGFnZ2VkIHZhbHVlLikKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgaW50IGZpbmROYW1lUG9pbnQoU3RyaW5nIG5hbWUsIGludCBzdGFydCkgewotCi0gICAgICAgIC8vIEJpbmFyeSBzZWFyY2gKLSAgICAgICAgaW50IGkgPSAwOwotICAgICAgICBpZiAobm9kZXMgIT0gbnVsbCkgewotICAgICAgICAgICAgaW50IGZpcnN0ID0gc3RhcnQ7Ci0gICAgICAgICAgICBpbnQgbGFzdCAgPSBub2Rlcy5zaXplKCkgLSAxOwotCi0gICAgICAgICAgICB3aGlsZSAoZmlyc3QgPD0gbGFzdCkgewotICAgICAgICAgICAgICAgIGkgPSAoZmlyc3QgKyBsYXN0KSAvIDI7Ci0gICAgICAgICAgICAgICAgaW50IHRlc3QgPSBuYW1lLmNvbXBhcmVUbygoKE5vZGUpKG5vZGVzLmdldChpKSkpLmdldE5vZGVOYW1lKCkpOwotICAgICAgICAgICAgICAgIGlmICh0ZXN0ID09IDApIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGk7IC8vIE5hbWUgZm91bmQKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSBpZiAodGVzdCA8IDApIHsKLSAgICAgICAgICAgICAgICAgICAgbGFzdCA9IGkgLSAxOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgZmlyc3QgPSBpICsgMTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmIChmaXJzdCA+IGkpIHsKLSAgICAgICAgICAgICAgICBpID0gZmlyc3Q7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gLTEgLSBpOyAvLyBub3QtZm91bmQgaGFzIHRvIGJlIGVuY29kZWQuCi0KLSAgICB9IC8vIGZpbmROYW1lUG9pbnQoU3RyaW5nKTppbnQKLQotCi0gICAgLyoqIFRoaXMgZmluZE5hbWVQb2ludCBpcyBmb3IgRE9NIExldmVsIDIgTmFtZXNwYWNlcy4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgaW50IGZpbmROYW1lUG9pbnQoU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIG5hbWUpIHsKLQotICAgICAgICBpZiAobm9kZXMgPT0gbnVsbCkgcmV0dXJuIC0xOwotICAgICAgICBpZiAobmFtZSA9PSBudWxsKSByZXR1cm4gLTE7Ci0KLSAgICAgICAgLy8gVGhpcyBpcyBhIGxpbmVhciBzZWFyY2ggdGhyb3VnaCB0aGUgc2FtZSBub2RlcyBBcnJheUxpc3QuCi0gICAgICAgIC8vIFRoZSBBcnJheUxpc3QgaXMgc29ydGVkIG9uIHRoZSBET00gTGV2ZWwgMSBub2RlbmFtZS4KLSAgICAgICAgLy8gVGhlIERPTSBMZXZlbCAyIE5TIGtleXMgYXJlIG5hbWVzcGFjZVVSSSBhbmQgTG9jYWxuYW1lLAotICAgICAgICAvLyBzbyB3ZSBtdXN0IGxpbmVhciBzZWFyY2ggdGhydSBpdC4KLSAgICAgICAgLy8gSW4gYWRkaXRpb24sIHRvIGdldCB0aGlzIHRvIHdvcmsgd2l0aCBub2RlcyB3aXRob3V0IGFueSBuYW1lc3BhY2UKLSAgICAgICAgLy8gKG5hbWVzcGFjZVVSSSBhbmQgbG9jYWxOYW1lcyBhcmUgYm90aCBudWxsKSB3ZSB0aGVuIHVzZSB0aGUgbm9kZU5hbWUKLSAgICAgICAgLy8gYXMgYSBzZWNvbmRhcnkga2V5LgotICAgICAgICBmaW5hbCBpbnQgc2l6ZSA9IG5vZGVzLnNpemUoKTsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyArK2kpIHsKLSAgICAgICAgICAgIE5vZGVJbXBsIGEgPSAoTm9kZUltcGwpbm9kZXMuZ2V0KGkpOwotICAgICAgICAgICAgU3RyaW5nIGFOYW1lc3BhY2VVUkkgPSBhLmdldE5hbWVzcGFjZVVSSSgpOwotICAgICAgICAgICAgU3RyaW5nIGFMb2NhbE5hbWUgPSBhLmdldExvY2FsTmFtZSgpOwotICAgICAgICAgICAgaWYgKG5hbWVzcGFjZVVSSSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgIGlmIChhTmFtZXNwYWNlVVJJID09IG51bGwKLSAgICAgICAgICAgICAgICAgICYmCi0gICAgICAgICAgICAgICAgICAobmFtZS5lcXVhbHMoYUxvY2FsTmFtZSkKLSAgICAgICAgICAgICAgICAgICB8fAotICAgICAgICAgICAgICAgICAgIChhTG9jYWxOYW1lID09IG51bGwgJiYgbmFtZS5lcXVhbHMoYS5nZXROb2RlTmFtZSgpKSkpKQotICAgICAgICAgICAgICAgIHJldHVybiBpOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgaWYgKG5hbWVzcGFjZVVSSS5lcXVhbHMoYU5hbWVzcGFjZVVSSSkKLSAgICAgICAgICAgICAgICAgICYmCi0gICAgICAgICAgICAgICAgICBuYW1lLmVxdWFscyhhTG9jYWxOYW1lKSkKLSAgICAgICAgICAgICAgICByZXR1cm4gaTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gLTE7Ci0gICAgfQotCi0gICAgLy8gY29tcGFyZSAyIG5vZGVzIGluIHRoZSBtYXAuICBJZiBhIHByZWNlZGVzIGIsIHJldHVybiB0cnVlLCBvdGhlcndpc2UKLSAgICAvLyByZXR1cm4gZmFsc2UKLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBwcmVjZWRlcyhOb2RlIGEsIE5vZGUgYikgewotCi0gICAgICAgIGlmIChub2RlcyAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmaW5hbCBpbnQgc2l6ZSA9IG5vZGVzLnNpemUoKTsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgKytpKSB7Ci0gICAgICAgICAgICAgICAgTm9kZSBuID0gKE5vZGUpbm9kZXMuZ2V0KGkpOwotICAgICAgICAgICAgICAgIGlmIChuPT1hKSByZXR1cm4gdHJ1ZTsKLSAgICAgICAgICAgICAgICBpZiAobj09YikgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAgKiBOT04tRE9NOiBSZW1vdmUgYXR0cmlidXRlIGF0IHNwZWNpZmllZCBpbmRleAotICAgICAgKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCByZW1vdmVJdGVtKGludCBpbmRleCkgewotICAgICAgIGlmIChub2RlcyAhPSBudWxsICYmIGluZGV4IDwgbm9kZXMuc2l6ZSgpKXsKLSAgICAgICAgICAgbm9kZXMucmVtb3ZlKGluZGV4KTsKLSAgICAgICB9Ci0gICAgfQotCi0KLSAgICBwcm90ZWN0ZWQgT2JqZWN0IGdldEl0ZW0gKGludCBpbmRleCl7Ci0gICAgICAgIGlmIChub2RlcyAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gbm9kZXMuZ2V0KGluZGV4KTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICBwcm90ZWN0ZWQgaW50IGFkZEl0ZW0gKE5vZGUgYXJnKSB7Ci0gICAgICAgIGludCBpID0gZmluZE5hbWVQb2ludChhcmcuZ2V0TmFtZXNwYWNlVVJJKCksIGFyZy5nZXRMb2NhbE5hbWUoKSk7Ci0gICAgICAgIGlmIChpID49IDApIHsKLSAgICAgICAgICAgIG5vZGVzLnNldChpLCBhcmcpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgLy8gSWYgd2UgY2FuJ3QgZmluZCBieSBuYW1lc3BhY2VVUkksIGxvY2FsTmFtZSwgdGhlbiB3ZSBmaW5kIGJ5Ci0gICAgICAgICAgICAvLyBub2RlTmFtZSBzbyB3ZSBrbm93IHdoZXJlIHRvIGluc2VydC4KLSAgICAgICAgICAgIGkgPSBmaW5kTmFtZVBvaW50KGFyZy5nZXROb2RlTmFtZSgpLDApOwotICAgICAgICAgICAgaWYgKGkgPj0gMCkgewotICAgICAgICAgICAgICAgIG5vZGVzLmFkZChpLCBhcmcpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgaSA9IC0xIC0gaTsgLy8gSW5zZXJ0IHBvaW50IChtYXkgYmUgZW5kIG9mIGxpc3QpCi0gICAgICAgICAgICAgICAgaWYgKG51bGwgPT0gbm9kZXMpIHsKLSAgICAgICAgICAgICAgICAgICAgbm9kZXMgPSBuZXcgQXJyYXlMaXN0KDUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBub2Rlcy5hZGQoaSwgYXJnKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gaTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBOT04tRE9NOiBjb3B5IGNvbnRlbnQgb2YgdGhpcyBtYXAgaW50byB0aGUgc3BlY2lmaWVkIEFycmF5TGlzdAotICAgICAqCi0gICAgICogQHBhcmFtIGxpc3QgICBBcnJheUxpc3QgdG8gY29weSBpbmZvcm1hdGlvbiBpbnRvLgotICAgICAqIEByZXR1cm4gQSBjb3B5IG9mIHRoaXMgbm9kZSBuYW1lZCBtYXAKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgQXJyYXlMaXN0IGNsb25lTWFwKEFycmF5TGlzdCBsaXN0KSB7Ci0gICAgICAgIGlmIChsaXN0ID09IG51bGwpIHsKLSAgICAgICAgICAgIGxpc3QgPSBuZXcgQXJyYXlMaXN0KDUpOwotICAgICAgICB9Ci0gICAgICAgIGxpc3QuY2xlYXIoKTsKLSAgICAgICAgaWYgKG5vZGVzICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZpbmFsIGludCBzaXplID0gbm9kZXMuc2l6ZSgpOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyArK2kpIHsKLSAgICAgICAgICAgICAgICBsaXN0LmFkZChub2Rlcy5nZXQoaSkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBsaXN0OwotICAgIH0KLQotICAgICBwcm90ZWN0ZWQgaW50IGdldE5hbWVkSXRlbUluZGV4KFN0cmluZyBuYW1lc3BhY2VVUkksIFN0cmluZyBsb2NhbE5hbWUpIHsKLSAgICAgICAgcmV0dXJuIGZpbmROYW1lUG9pbnQobmFtZXNwYWNlVVJJLCBsb2NhbE5hbWUpOwotICAgICB9Ci0KLSAgICAvKioKLSAgICAgICogTk9OLURPTSByZW1vdmUgYWxsIGVsZW1lbnRzIGZyb20gdGhpcyBtYXAKLSAgICAgICovCi0gICAgcHVibGljIHZvaWQgcmVtb3ZlQWxsICgpewotICAgICAgICBpZiAobm9kZXMgIT0gbnVsbCkgewotICAgICAgICAgICAgbm9kZXMuY2xlYXIoKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCByZWFkT2JqZWN0KE9iamVjdElucHV0U3RyZWFtIGluKQotICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIENsYXNzTm90Rm91bmRFeGNlcHRpb24gewotICAgICAgICBpbi5kZWZhdWx0UmVhZE9iamVjdCgpOwotICAgICAgICBpZiAobm9kZXMgIT0gbnVsbCkgewotICAgICAgICAgICAgbm9kZXMgPSBuZXcgQXJyYXlMaXN0KG5vZGVzKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCB3cml0ZU9iamVjdChPYmplY3RPdXRwdXRTdHJlYW0gb3V0KSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgICAgICBMaXN0IG9sZE5vZGVzID0gdGhpcy5ub2RlczsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGlmIChvbGROb2RlcyAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgdGhpcy5ub2RlcyA9IG5ldyBWZWN0b3Iob2xkTm9kZXMpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgb3V0LmRlZmF1bHRXcml0ZU9iamVjdCgpOwotICAgICAgICB9Ci0gICAgICAgIC8vIElmIHRoZSB3cml0ZSBmYWlscyBmb3Igc29tZSByZWFzb24gZW5zdXJlCi0gICAgICAgIC8vIHRoYXQgd2UgcmVzdG9yZSB0aGUgb3JpZ2luYWwgb2JqZWN0LgotICAgICAgICBmaW5hbGx5IHsKLSAgICAgICAgICAgIHRoaXMubm9kZXMgPSBvbGROb2RlczsKLSAgICAgICAgfQotICAgIH0KLQotfSAvLyBjbGFzcyBOYW1lZE5vZGVNYXBJbXBsCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vTm9kZUltcGwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9Ob2RlSW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1MjlmNTMzLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9Ob2RlSW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjAyMyArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDE1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICovCi0gLyoKLSAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQotICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCi0gKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCi0gKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAotICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKLSAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tOwotCi1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLk9iamVjdE91dHB1dFN0cmVhbTsKLWltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKLWltcG9ydCBqYXZhLnV0aWwuTWFwOwotaW1wb3J0IG9yZy53M2MuZG9tLkRPTUV4Y2VwdGlvbjsKLWltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKLWltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudFR5cGU7Ci1pbXBvcnQgb3JnLnczYy5kb20uTmFtZWROb2RlTWFwOwotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZUxpc3Q7Ci1pbXBvcnQgb3JnLnczYy5kb20uVXNlckRhdGFIYW5kbGVyOwotaW1wb3J0IG9yZy53M2MuZG9tLmV2ZW50cy5FdmVudDsKLWltcG9ydCBvcmcudzNjLmRvbS5ldmVudHMuRXZlbnRMaXN0ZW5lcjsKLWltcG9ydCBvcmcudzNjLmRvbS5ldmVudHMuRXZlbnRUYXJnZXQ7Ci0KLS8qKgotICogTm9kZUltcGwgcHJvdmlkZXMgdGhlIGJhc2ljIHN0cnVjdHVyZSBvZiBhIERPTSB0cmVlLiBJdCBpcyBuZXZlciB1c2VkCi0gKiBkaXJlY3RseSwgYnV0IGluc3RlYWQgaXMgc3ViY2xhc3NlZCB0byBhZGQgdHlwZSBhbmQgZGF0YQotICogaW5mb3JtYXRpb24sIGFuZCBhZGRpdGlvbmFsIG1ldGhvZHMsIGFwcHJvcHJpYXRlIHRvIGVhY2ggbm9kZSBvZgotICogdGhlIHRyZWUuIE9ubHkgaXRzIHN1YmNsYXNzZXMgc2hvdWxkIGJlIGluc3RhbnRpYXRlZCAtLSBhbmQgdGhvc2UsCi0gKiB3aXRoIHRoZSBleGNlcHRpb24gb2YgRG9jdW1lbnQgaXRzZWxmLCBvbmx5IHRocm91Z2ggYSBzcGVjaWZpYwotICogRG9jdW1lbnQncyBmYWN0b3J5IG1ldGhvZHMuCi0gKiA8UD4KLSAqIFRoZSBOb2RlIGludGVyZmFjZSBwcm92aWRlcyBzaGFyZWQgYmVoYXZpb3JzIHN1Y2ggYXMgc2libGluZ3MgYW5kCi0gKiBjaGlsZHJlbiwgYm90aCBmb3IgY29uc2lzdGFuY3kgYW5kIHNvIHRoYXQgdGhlIG1vc3QgY29tbW9uIHRyZWUKLSAqIG9wZXJhdGlvbnMgbWF5IGJlIHBlcmZvcm1lZCB3aXRob3V0IGNvbnN0YW50bHkgaGF2aW5nIHRvIGRvd25jYXN0Ci0gKiB0byBzcGVjaWZpYyBub2RlIHR5cGVzLiBXaGVuIHRoZXJlIGlzIG5vIG9idmlvdXMgbWFwcGluZyBmb3Igb25lIG9mCi0gKiB0aGVzZSBxdWVyaWVzLCBpdCB3aWxsIHJlc3BvbmQgd2l0aCBudWxsLgotICogTm90ZSB0aGF0IHRoZSBkZWZhdWx0IGJlaGF2aW9yIGlzIHRoYXQgY2hpbGRyZW4gYXJlIGZvcmJpZGRlbi4gVG8KLSAqIHBlcm1pdCB0aGVtLCB0aGUgc3ViY2xhc3MgUGFyZW50Tm9kZSBvdmVycmlkZXMgc2V2ZXJhbCBtZXRob2RzLgotICogPFA+Ci0gKiBOb2RlSW1wbCBhbHNvIGltcGxlbWVudHMgTm9kZUxpc3QsIHNvIGl0IGNhbiByZXR1cm4gaXRzZWxmIGluCi0gKiByZXNwb25zZSB0byB0aGUgZ2V0Q2hpbGROb2RlcygpIHF1ZXJ5LiBUaGlzIGVsaW1pbmlhdGVzIHRoZSBuZWVkCi0gKiBmb3IgYSBzZXBhcmF0ZSBDaGlsZE5vZGVMaXN0IG9iamVjdC4gTm90ZSB0aGF0IHRoaXMgaXMgYW4KLSAqIElNUExFTUVOVEFUSU9OIERFVEFJTDsgYXBwbGljYXRpb25zIHNob3VsZCBfbmV2ZXJfIGFzc3VtZSB0aGF0Ci0gKiB0aGlzIGlkZW50aXR5IGV4aXN0cy4KLSAqIDxQPgotICogQWxsIG5vZGVzIGluIGEgc2luZ2xlIGRvY3VtZW50IG11c3Qgb3JpZ2luYXRlCi0gKiBpbiB0aGF0IGRvY3VtZW50LiAoTm90ZSB0aGF0IHRoaXMgaXMgbXVjaCB0aWdodGVyIHRoYW4gIm11c3QgYmUKLSAqIHNhbWUgaW1wbGVtZW50YXRpb24iKSBOb2RlcyBhcmUgYWxsIGF3YXJlIG9mIHRoZWlyIG93bmVyRG9jdW1lbnQsCi0gKiBhbmQgYXR0ZW1wdHMgdG8gbWlzbWF0Y2ggd2lsbCB0aHJvdyBXUk9OR19ET0NVTUVOVF9FUlIuCi0gKiA8UD4KLSAqIEhvd2V2ZXIsIHRvIHNhdmUgbWVtb3J5IG5vdCBhbGwgbm9kZXMgYWx3YXlzIGhhdmUgYSBkaXJlY3QgcmVmZXJlbmNlCi0gKiB0byB0aGVpciBvd25lckRvY3VtZW50LiBXaGVuIGEgbm9kZSBpcyBvd25lZCBieSBhbm90aGVyIG5vZGUgaXQgcmVsaWVzCi0gKiBvbiBpdHMgb3duZXIgdG8gc3RvcmUgaXRzIG93bmVyRG9jdW1lbnQuIFBhcmVudCBub2RlcyBhbHdheXMgc3RvcmUgaXQKLSAqIHRob3VnaCwgc28gdGhlcmUgaXMgbmV2ZXIgbW9yZSB0aGFuIG9uZSBsZXZlbCBvZiBpbmRpcmVjdGlvbi4KLSAqIEFuZCB3aGVuIGEgbm9kZSBkb2Vzbid0IGhhdmUgYW4gb3duZXIsIG93bmVyTm9kZSByZWZlcnMgdG8gaXRzCi0gKiBvd25lckRvY3VtZW50LgotICogPHA+Ci0gKiBUaGlzIGNsYXNzIGRvZXNuJ3QgZGlyZWN0bHkgc3VwcG9ydCBtdXRhdGlvbiBldmVudHMsIGhvd2V2ZXIsIGl0IHN0aWxsCi0gKiBpbXBsZW1lbnRzIHRoZSBFdmVudFRhcmdldCBpbnRlcmZhY2UgYW5kIGZvcndhcmQgYWxsIHJlbGF0ZWQgY2FsbHMgdG8gdGhlCi0gKiBkb2N1bWVudCBzbyB0aGF0IHRoZSBkb2N1bWVudCBjbGFzcyBkbyBzby4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBBcm5hdWQgIExlIEhvcnMsIElCTQotICogQGF1dGhvciBKb2UgS2Vzc2VsbWFuLCBJQk0KLSAqIEBzaW5jZSAgUFItRE9NLUxldmVsLTEtMTk5ODA4MTguCi0gKi8KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBOb2RlSW1wbAotICAgIGltcGxlbWVudHMgTm9kZSwgTm9kZUxpc3QsIEV2ZW50VGFyZ2V0LCBDbG9uZWFibGUsIFNlcmlhbGl6YWJsZXsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RhbnRzCi0gICAgLy8KLQotCi0gICAgLy8gVHJlZVBvc2l0aW9uIENvbnN0YW50cy4KLSAgICAvLyBUYWtlbiBmcm9tIERPTSBMMyBOb2RlIGludGVyZmFjZS4KLSAgICAvKioKLSAgICAgKiBUaGUgbm9kZSBwcmVjZWRlcyB0aGUgcmVmZXJlbmNlIG5vZGUuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBUUkVFX1BPU0lUSU9OX1BSRUNFRElORyAgID0gMHgwMTsKLSAgICAvKioKLSAgICAgKiBUaGUgbm9kZSBmb2xsb3dzIHRoZSByZWZlcmVuY2Ugbm9kZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFRSRUVfUE9TSVRJT05fRk9MTE9XSU5HICAgPSAweDAyOwotICAgIC8qKgotICAgICAqIFRoZSBub2RlIGlzIGFuIGFuY2VzdG9yIG9mIHRoZSByZWZlcmVuY2Ugbm9kZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFRSRUVfUE9TSVRJT05fQU5DRVNUT1IgICAgPSAweDA0OwotICAgIC8qKgotICAgICAqIFRoZSBub2RlIGlzIGEgZGVzY2VuZGFudCBvZiB0aGUgcmVmZXJlbmNlIG5vZGUuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBUUkVFX1BPU0lUSU9OX0RFU0NFTkRBTlQgID0gMHgwODsKLSAgICAvKioKLSAgICAgKiBUaGUgdHdvIG5vZGVzIGhhdmUgYW4gZXF1aXZhbGVudCBwb3NpdGlvbi4gVGhpcyBpcyB0aGUgY2FzZSBvZiB0d28KLSAgICAgKiBhdHRyaWJ1dGVzIHRoYXQgaGF2ZSB0aGUgc2FtZSA8Y29kZT5vd25lckVsZW1lbnQ8L2NvZGU+LCBhbmQgdHdvCi0gICAgICogbm9kZXMgdGhhdCBhcmUgdGhlIHNhbWUuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBUUkVFX1BPU0lUSU9OX0VRVUlWQUxFTlQgID0gMHgxMDsKLSAgICAvKioKLSAgICAgKiBUaGUgdHdvIG5vZGVzIGFyZSB0aGUgc2FtZS4gVHdvIG5vZGVzIHRoYXQgYXJlIHRoZSBzYW1lIGhhdmUgYW4KLSAgICAgKiBlcXVpdmFsZW50IHBvc2l0aW9uLCB0aG91Z2ggdGhlIHJldmVyc2UgbWF5IG5vdCBiZSB0cnVlLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgVFJFRV9QT1NJVElPTl9TQU1FX05PREUgICA9IDB4MjA7Ci0gICAgLyoqCi0gICAgICogVGhlIHR3byBub2RlcyBhcmUgZGlzY29ubmVjdGVkLCB0aGV5IGRvIG5vdCBoYXZlIGFueSBjb21tb24gYW5jZXN0b3IuCi0gICAgICogVGhpcyBpcyB0aGUgY2FzZSBvZiB0d28gbm9kZXMgdGhhdCBhcmUgbm90IGluIHRoZSBzYW1lIGRvY3VtZW50LgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgVFJFRV9QT1NJVElPTl9ESVNDT05ORUNURUQgPSAweDAwOwotCi0KLSAgICAvLyBEb2N1bWVudFBvc2l0aW9uCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBET0NVTUVOVF9QT1NJVElPTl9ESVNDT05ORUNURUQgPSAweDAxOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgRE9DVU1FTlRfUE9TSVRJT05fUFJFQ0VESU5HID0gMHgwMjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IERPQ1VNRU5UX1BPU0lUSU9OX0ZPTExPV0lORyA9IDB4MDQ7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBET0NVTUVOVF9QT1NJVElPTl9DT05UQUlOUyA9IDB4MDg7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBET0NVTUVOVF9QT1NJVElPTl9JU19DT05UQUlORUQgPSAweDEwOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgRE9DVU1FTlRfUE9TSVRJT05fSU1QTEVNRU5UQVRJT05fU1BFQ0lGSUMgPSAweDIwOwotCi0gICAgLyoqIFNlcmlhbGl6YXRpb24gdmVyc2lvbi4gKi8KLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTYzMTY1OTE5OTIxNjcyMTk2OTZMOwotCi0gICAgLy8gcHVibGljCi0KLSAgICAvKiogRWxlbWVudCBkZWZpbml0aW9uIG5vZGUgdHlwZS4gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IEVMRU1FTlRfREVGSU5JVElPTl9OT0RFID0gMjE7Ci0KLSAgICAvLwotICAgIC8vIERhdGEKLSAgICAvLwotCi0gICAgLy8gbGlua3MKLQotICAgIHByb3RlY3RlZCBOb2RlSW1wbCBvd25lck5vZGU7IC8vIHR5cGljYWxseSB0aGUgcGFyZW50IGJ1dCBub3QgYWx3YXlzIQotCi0gICAgLy8gZGF0YQotCi0gICAgcHJvdGVjdGVkIHNob3J0IGZsYWdzOwotCi0gICAgcHJvdGVjdGVkIGZpbmFsIHN0YXRpYyBzaG9ydCBSRUFET05MWSAgICAgPSAweDE8PDA7Ci0gICAgcHJvdGVjdGVkIGZpbmFsIHN0YXRpYyBzaG9ydCBTWU5DREFUQSAgICAgPSAweDE8PDE7Ci0gICAgcHJvdGVjdGVkIGZpbmFsIHN0YXRpYyBzaG9ydCBTWU5DQ0hJTERSRU4gPSAweDE8PDI7Ci0gICAgcHJvdGVjdGVkIGZpbmFsIHN0YXRpYyBzaG9ydCBPV05FRCAgICAgICAgPSAweDE8PDM7Ci0gICAgcHJvdGVjdGVkIGZpbmFsIHN0YXRpYyBzaG9ydCBGSVJTVENISUxEICAgPSAweDE8PDQ7Ci0gICAgcHJvdGVjdGVkIGZpbmFsIHN0YXRpYyBzaG9ydCBTUEVDSUZJRUQgICAgPSAweDE8PDU7Ci0gICAgcHJvdGVjdGVkIGZpbmFsIHN0YXRpYyBzaG9ydCBJR05PUkFCTEVXUyAgPSAweDE8PDY7Ci0gICAgcHJvdGVjdGVkIGZpbmFsIHN0YXRpYyBzaG9ydCBIQVNTVFJJTkcgICAgPSAweDE8PDc7Ci0gICAgcHJvdGVjdGVkIGZpbmFsIHN0YXRpYyBzaG9ydCBOT1JNQUxJWkVEID0gMHgxPDw4OwotICAgIHByb3RlY3RlZCBmaW5hbCBzdGF0aWMgc2hvcnQgSUQgICAgICAgICAgID0gMHgxPDw5OwotCi0gICAgLy8KLSAgICAvLyBDb25zdHJ1Y3RvcnMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogTm8gcHVibGljIGNvbnN0cnVjdG9yOyBvbmx5IHN1YmNsYXNzZXMgb2YgTm9kZSBzaG91bGQgYmUKLSAgICAgKiBpbnN0YW50aWF0ZWQsIGFuZCB0aG9zZSBub3JtYWxseSB2aWEgYSBEb2N1bWVudCdzIGZhY3RvcnkgbWV0aG9kcwotICAgICAqIDxwPgotICAgICAqIEV2ZXJ5IE5vZGUga25vd3Mgd2hhdCBEb2N1bWVudCBpdCBiZWxvbmdzIHRvLgotICAgICAqLwotICAgIHByb3RlY3RlZCBOb2RlSW1wbChDb3JlRG9jdW1lbnRJbXBsIG93bmVyRG9jdW1lbnQpIHsKLSAgICAgICAgLy8gYXMgbG9uZyBhcyB3ZSBkbyBub3QgaGF2ZSBhbnkgb3duZXIsIG93bmVyTm9kZSBpcyBvdXIgb3duZXJEb2N1bWVudAotICAgICAgICBvd25lck5vZGUgPSBvd25lckRvY3VtZW50OwotICAgIH0gLy8gPGluaXQ+KENvcmVEb2N1bWVudEltcGwpCi0KLSAgICAvKiogQ29uc3RydWN0b3IgZm9yIHNlcmlhbGl6YXRpb24uICovCi0gICAgcHVibGljIE5vZGVJbXBsKCkge30KLQotICAgIC8vCi0gICAgLy8gTm9kZSBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIEEgc2hvcnQgaW50ZWdlciBpbmRpY2F0aW5nIHdoYXQgdHlwZSBvZiBub2RlIHRoaXMgaXMuIFRoZSBuYW1lZAotICAgICAqIGNvbnN0YW50cyBmb3IgdGhpcyB2YWx1ZSBhcmUgZGVmaW5lZCBpbiB0aGUgb3JnLnczYy5kb20uTm9kZSBpbnRlcmZhY2UuCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IHNob3J0IGdldE5vZGVUeXBlKCk7Ci0KLSAgICAvKioKLSAgICAgKiB0aGUgbmFtZSBvZiB0aGlzIG5vZGUuCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IFN0cmluZyBnZXROb2RlTmFtZSgpOwotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgbm9kZSB2YWx1ZS4KLSAgICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbihET01TVFJJTkdfU0laRV9FUlIpCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXROb2RlVmFsdWUoKQotICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKLSAgICAgICAgcmV0dXJuIG51bGw7ICAgICAgICAgICAgLy8gb3ZlcnJpZGRlbiBpbiBzb21lIHN1YmNsYXNzZXMKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSBub2RlIHZhbHVlLgotICAgICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uKE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUikKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXROb2RlVmFsdWUoU3RyaW5nIHgpCi0gICAgICAgIHRocm93cyBET01FeGNlcHRpb24gewotICAgICAgICAvLyBEZWZhdWx0IGJlaGF2aW9yIGlzIHRvIGRvIG5vdGhpbmcsIG92ZXJyaWRkZW4gaW4gc29tZSBzdWJjbGFzc2VzCi0gICAgfQotCi0gICAgLyoqCi0gICAgICogQWRkcyBhIGNoaWxkIG5vZGUgdG8gdGhlIGVuZCBvZiB0aGUgbGlzdCBvZiBjaGlsZHJlbiBmb3IgdGhpcyBub2RlLgotICAgICAqIENvbnZlbmllbmNlIHNob3J0aGFuZCBmb3IgaW5zZXJ0QmVmb3JlKG5ld0NoaWxkLG51bGwpLgotICAgICAqIEBzZWUgI2luc2VydEJlZm9yZShOb2RlLCBOb2RlKQotICAgICAqIDxQPgotICAgICAqIEJ5IGRlZmF1bHQgd2UgZG8gbm90IGFjY2VwdCBhbnkgY2hpbGRyZW4sIFBhcmVudE5vZGUgb3ZlcnJpZGVzIHRoaXMuCi0gICAgICogQHNlZSBQYXJlbnROb2RlCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIG5ld0NoaWxkLCBpbiBpdHMgbmV3IHN0YXRlIChyZWxvY2F0ZWQsIG9yIGVtcHRpZWQgaW4gdGhlIGNhc2Ugb2YKLSAgICAgKiBEb2N1bWVudE5vZGUuKQotICAgICAqCi0gICAgICogQHRocm93cyBET01FeGNlcHRpb24oSElFUkFSQ0hZX1JFUVVFU1RfRVJSKSBpZiBuZXdDaGlsZCBpcyBvZiBhCi0gICAgICogdHlwZSB0aGF0IHNob3VsZG4ndCBiZSBhIGNoaWxkIG9mIHRoaXMgbm9kZS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uKFdST05HX0RPQ1VNRU5UX0VSUikgaWYgbmV3Q2hpbGQgaGFzIGEKLSAgICAgKiBkaWZmZXJlbnQgb3duZXIgZG9jdW1lbnQgdGhhbiB3ZSBkby4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uKE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUikgaWYgdGhpcyBub2RlIGlzCi0gICAgICogcmVhZC1vbmx5LgotICAgICAqLwotICAgIHB1YmxpYyBOb2RlIGFwcGVuZENoaWxkKE5vZGUgbmV3Q2hpbGQpIHRocm93cyBET01FeGNlcHRpb24gewotICAgICAgICByZXR1cm4gaW5zZXJ0QmVmb3JlKG5ld0NoaWxkLCBudWxsKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGEgZHVwbGljYXRlIG9mIGEgZ2l2ZW4gbm9kZS4gWW91IGNhbiBjb25zaWRlciB0aGlzIGEKLSAgICAgKiBnZW5lcmljICJjb3B5IGNvbnN0cnVjdG9yIiBmb3Igbm9kZXMuIFRoZSBuZXdseSByZXR1cm5lZCBvYmplY3Qgc2hvdWxkCi0gICAgICogYmUgY29tcGxldGVseSBpbmRlcGVuZGVudCBvZiB0aGUgc291cmNlIG9iamVjdCdzIHN1YnRyZWUsIHNvIGNoYW5nZXMKLSAgICAgKiBpbiBvbmUgYWZ0ZXIgdGhlIGNsb25lIGhhcyBiZWVuIG1hZGUgd2lsbCBub3QgYWZmZWN0IHRoZSBvdGhlci4KLSAgICAgKiA8UD4KLSAgICAgKiBOb3RlOiBzaW5jZSB3ZSBuZXZlciBoYXZlIGFueSBjaGlsZHJlbiBkZWVwIGlzIG1lYW5pbmdsZXNzIGhlcmUsCi0gICAgICogUGFyZW50Tm9kZSBvdmVycmlkZXMgdGhpcyBiZWhhdmlvci4KLSAgICAgKiBAc2VlIFBhcmVudE5vZGUKLSAgICAgKgotICAgICAqIDxwPgotICAgICAqIEV4YW1wbGU6IENsb25pbmcgYSBUZXh0IG5vZGUgd2lsbCBjb3B5IGJvdGggdGhlIG5vZGUgYW5kIHRoZSB0ZXh0IGl0Ci0gICAgICogY29udGFpbnMuCi0gICAgICogPHA+Ci0gICAgICogRXhhbXBsZTogQ2xvbmluZyBzb21ldGhpbmcgdGhhdCBoYXMgY2hpbGRyZW4gLS0gRWxlbWVudCBvciBBdHRyLCBmb3IKLSAgICAgKiBleGFtcGxlIC0tIHdpbGwgX25vdF8gY2xvbmUgdGhvc2UgY2hpbGRyZW4gdW5sZXNzIGEgImRlZXAgY2xvbmUiCi0gICAgICogaGFzIGJlZW4gcmVxdWVzdGVkLiBBIHNoYWxsb3cgY2xvbmUgb2YgYW4gQXR0ciBub2RlIHdpbGwgeWllbGQgYW4KLSAgICAgKiBlbXB0eSBBdHRyIG9mIHRoZSBzYW1lIG5hbWUuCi0gICAgICogPHA+Ci0gICAgICogTk9URTogQ2xvbmVzIHdpbGwgYWx3YXlzIGJlIHJlYWQvd3JpdGUsIGV2ZW4gaWYgdGhlIG5vZGUgYmVpbmcgY2xvbmVkCi0gICAgICogaXMgcmVhZC1vbmx5LCB0byBwZXJtaXQgYXBwbGljYXRpb25zIHVzaW5nIG9ubHkgdGhlIERPTSBBUEkgdG8gb2J0YWluCi0gICAgICogZWRpdGFibGUgY29waWVzIG9mIGxvY2tlZCBwb3J0aW9ucyBvZiB0aGUgdHJlZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgTm9kZSBjbG9uZU5vZGUoYm9vbGVhbiBkZWVwKSB7Ci0KLSAgICAgICAgaWYgKG5lZWRzU3luY0RhdGEoKSkgewotICAgICAgICAgICAgc3luY2hyb25pemVEYXRhKCk7Ci0gICAgICAgIH0KLQotICAgICAgICBOb2RlSW1wbCBuZXdub2RlOwotICAgICAgICB0cnkgewotICAgICAgICAgICAgbmV3bm9kZSA9IChOb2RlSW1wbCljbG9uZSgpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAvLyBpZiB3ZSBnZXQgaGVyZSB3ZSBoYXZlIGFuIGVycm9yIGluIG91ciBwcm9ncmFtIHdlIG1heSBhcyB3ZWxsCi0gICAgICAgICAgICAvLyBiZSB2b2NhbCBhYm91dCBpdCwgc28gdGhhdCBwZW9wbGUgY2FuIHRha2UgYXBwcm9wcmlhdGUgYWN0aW9uLgotICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIioqSW50ZXJuYWwgRXJyb3IqKiIgKyBlKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIE5lZWQgdG8gYnJlYWsgdGhlIGFzc29jaWF0aW9uIHcvIG9yaWdpbmFsIGtpZHMKLSAgICAgICAgbmV3bm9kZS5vd25lck5vZGUgICAgICA9IG93bmVyRG9jdW1lbnQoKTsKLSAgICAgICAgbmV3bm9kZS5pc093bmVkKGZhbHNlKTsKLQotICAgICAgICAvLyBCeSBkZWZhdWx0IHdlIG1ha2UgYWxsIGNsb25lcyByZWFkd3JpdGUsCi0gICAgICAgIC8vIHRoaXMgaXMgb3ZlcnJpZGVuIGluIHJlYWRvbmx5IHN1YmNsYXNzZXMKLSAgICAgICAgbmV3bm9kZS5pc1JlYWRPbmx5KGZhbHNlKTsKLQotICAgICAgICBvd25lckRvY3VtZW50KCkuY2FsbFVzZXJEYXRhSGFuZGxlcnModGhpcywgbmV3bm9kZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVzZXJEYXRhSGFuZGxlci5OT0RFX0NMT05FRCk7Ci0KLSAgICAgICAgcmV0dXJuIG5ld25vZGU7Ci0KLSAgICB9IC8vIGNsb25lTm9kZShib29sZWFuKTpOb2RlCi0KLSAgICAvKioKLSAgICAgKiBGaW5kIHRoZSBEb2N1bWVudCB0aGF0IHRoaXMgTm9kZSBiZWxvbmdzIHRvICh0aGUgZG9jdW1lbnQgaW4KLSAgICAgKiB3aG9zZSBjb250ZXh0IHRoZSBOb2RlIHdhcyBjcmVhdGVkKS4gVGhlIE5vZGUgbWF5IG9yIG1heSBub3QKLSAgICAgKiBjdXJyZW50bHkgYmUgcGFydCBvZiB0aGF0IERvY3VtZW50J3MgYWN0dWFsIGNvbnRlbnRzLgotICAgICAqLwotICAgIHB1YmxpYyBEb2N1bWVudCBnZXRPd25lckRvY3VtZW50KCkgewotICAgICAgICAvLyBpZiB3ZSBoYXZlIGFuIG93bmVyIHNpbXBseSBmb3J3YXJkIHRoZSByZXF1ZXN0Ci0gICAgICAgIC8vIG90aGVyd2lzZSBvd25lck5vZGUgaXMgb3VyIG93bmVyRG9jdW1lbnQKLSAgICAgICAgaWYgKGlzT3duZWQoKSkgewotICAgICAgICAgICAgcmV0dXJuIG93bmVyTm9kZS5vd25lckRvY3VtZW50KCk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gKERvY3VtZW50KSBvd25lck5vZGU7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBzYW1lIGFzIGFib3ZlIGJ1dCByZXR1cm5zIGludGVybmFsIHR5cGUgYW5kIHRoaXMgb25lIGlzIG5vdCBvdmVycmlkZGVuCi0gICAgICogYnkgQ29yZURvY3VtZW50SW1wbCB0byByZXR1cm4gbnVsbAotICAgICAqLwotICAgIENvcmVEb2N1bWVudEltcGwgb3duZXJEb2N1bWVudCgpIHsKLSAgICAgICAgLy8gaWYgd2UgaGF2ZSBhbiBvd25lciBzaW1wbHkgZm9yd2FyZCB0aGUgcmVxdWVzdAotICAgICAgICAvLyBvdGhlcndpc2Ugb3duZXJOb2RlIGlzIG91ciBvd25lckRvY3VtZW50Ci0gICAgICAgIGlmIChpc093bmVkKCkpIHsKLSAgICAgICAgICAgIHJldHVybiBvd25lck5vZGUub3duZXJEb2N1bWVudCgpOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIChDb3JlRG9jdW1lbnRJbXBsKSBvd25lck5vZGU7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBOT04tRE9NCi0gICAgICogc2V0IHRoZSBvd25lckRvY3VtZW50IG9mIHRoaXMgbm9kZQotICAgICAqLwotICAgIHZvaWQgc2V0T3duZXJEb2N1bWVudChDb3JlRG9jdW1lbnRJbXBsIGRvYykgewotICAgICAgICBpZiAobmVlZHNTeW5jRGF0YSgpKSB7Ci0gICAgICAgICAgICBzeW5jaHJvbml6ZURhdGEoKTsKLSAgICAgICAgfQotICAgICAgICAvLyBpZiB3ZSBoYXZlIGFuIG93bmVyIHdlIHJlbHkgb24gaXQgdG8gaGF2ZSBpdCByaWdodAotICAgICAgICAvLyBvdGhlcndpc2Ugb3duZXJOb2RlIGlzIG91ciBvd25lckRvY3VtZW50Ci0gICAgICAgIGlmICghaXNPd25lZCgpKSB7Ci0gICAgICAgICAgICBvd25lck5vZGUgPSBkb2M7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBub2RlIG51bWJlcgotICAgICAqLwotICAgIHByb3RlY3RlZCBpbnQgZ2V0Tm9kZU51bWJlcigpIHsKLSAgICAgICAgaW50IG5vZGVOdW1iZXI7Ci0gICAgICAgIENvcmVEb2N1bWVudEltcGwgY2QgPSAoQ29yZURvY3VtZW50SW1wbCkodGhpcy5nZXRPd25lckRvY3VtZW50KCkpOwotICAgICAgICBub2RlTnVtYmVyID0gY2QuZ2V0Tm9kZU51bWJlcih0aGlzKTsKLSAgICAgICAgcmV0dXJuIG5vZGVOdW1iZXI7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogT2J0YWluIHRoZSBET00tdHJlZSBwYXJlbnQgb2YgdGhpcyBub2RlLCBvciBudWxsIGlmIGl0IGlzIG5vdAotICAgICAqIGN1cnJlbnRseSBhY3RpdmUgaW4gdGhlIERPTSB0cmVlIChwZXJoYXBzIGJlY2F1c2UgaXQgaGFzIGp1c3QgYmVlbgotICAgICAqIGNyZWF0ZWQgb3IgcmVtb3ZlZCkuIE5vdGUgdGhhdCBEb2N1bWVudCwgRG9jdW1lbnRGcmFnbWVudCwgYW5kCi0gICAgICogQXR0cmlidXRlIHdpbGwgbmV2ZXIgaGF2ZSBwYXJlbnRzLgotICAgICAqLwotICAgIHB1YmxpYyBOb2RlIGdldFBhcmVudE5vZGUoKSB7Ci0gICAgICAgIHJldHVybiBudWxsOyAgICAgICAgICAgIC8vIG92ZXJyaWRlbiBieSBDaGlsZE5vZGUKLSAgICB9Ci0KLSAgICAvKgotICAgICAqIHNhbWUgYXMgYWJvdmUgYnV0IHJldHVybnMgaW50ZXJuYWwgdHlwZQotICAgICAqLwotICAgIE5vZGVJbXBsIHBhcmVudE5vZGUoKSB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKiBUaGUgbmV4dCBjaGlsZCBvZiB0aGlzIG5vZGUncyBwYXJlbnQsIG9yIG51bGwgaWYgbm9uZSAqLwotICAgIHB1YmxpYyBOb2RlIGdldE5leHRTaWJsaW5nKCkgewotICAgICAgICByZXR1cm4gbnVsbDsgICAgICAgICAgICAvLyBkZWZhdWx0IGJlaGF2aW9yLCBvdmVycmlkZW4gaW4gQ2hpbGROb2RlCi0gICAgfQotCi0gICAgLyoqIFRoZSBwcmV2aW91cyBjaGlsZCBvZiB0aGlzIG5vZGUncyBwYXJlbnQsIG9yIG51bGwgaWYgbm9uZSAqLwotICAgIHB1YmxpYyBOb2RlIGdldFByZXZpb3VzU2libGluZygpIHsKLSAgICAgICAgcmV0dXJuIG51bGw7ICAgICAgICAgICAgLy8gZGVmYXVsdCBiZWhhdmlvciwgb3ZlcnJpZGVuIGluIENoaWxkTm9kZQotICAgIH0KLQotICAgIENoaWxkTm9kZSBwcmV2aW91c1NpYmxpbmcoKSB7Ci0gICAgICAgIHJldHVybiBudWxsOyAgICAgICAgICAgIC8vIGRlZmF1bHQgYmVoYXZpb3IsIG92ZXJyaWRlbiBpbiBDaGlsZE5vZGUKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIGNvbGxlY3Rpb24gb2YgYXR0cmlidXRlcyBhc3NvY2lhdGVkIHdpdGggdGhpcyBub2RlLAotICAgICAqIG9yIG51bGwgaWYgbm9uZS4gQXQgdGhpcyB3cml0aW5nLCBFbGVtZW50IGlzIHRoZSBvbmx5IHR5cGUgb2Ygbm9kZQotICAgICAqIHdoaWNoIHdpbGwgZXZlciBoYXZlIGF0dHJpYnV0ZXMuCi0gICAgICoKLSAgICAgKiBAc2VlIEVsZW1lbnRJbXBsCi0gICAgICovCi0gICAgcHVibGljIE5hbWVkTm9kZU1hcCBnZXRBdHRyaWJ1dGVzKCkgewotICAgICAgICByZXR1cm4gbnVsbDsgLy8gb3ZlcnJpZGRlbiBpbiBFbGVtZW50SW1wbAotICAgIH0KLQotICAgIC8qKgotICAgICAqICBSZXR1cm5zIHdoZXRoZXIgdGhpcyBub2RlIChpZiBpdCBpcyBhbiBlbGVtZW50KSBoYXMgYW55IGF0dHJpYnV0ZXMuCi0gICAgICogQHJldHVybiA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGlzIG5vZGUgaGFzIGFueSBhdHRyaWJ1dGVzLAotICAgICAqICAgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4KLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDIKLSAgICAgKiBAc2VlIEVsZW1lbnRJbXBsCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaGFzQXR0cmlidXRlcygpIHsKLSAgICAgICAgcmV0dXJuIGZhbHNlOyAgICAgICAgICAgLy8gb3ZlcnJpZGRlbiBpbiBFbGVtZW50SW1wbAotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRlc3Qgd2hldGhlciB0aGlzIG5vZGUgaGFzIGFueSBjaGlsZHJlbi4gQ29udmVuaWVuY2Ugc2hvcnRoYW5kCi0gICAgICogZm9yIChOb2RlLmdldEZpcnN0Q2hpbGQoKSE9bnVsbCkKLSAgICAgKiA8UD4KLSAgICAgKiBCeSBkZWZhdWx0IHdlIGRvIG5vdCBoYXZlIGFueSBjaGlsZHJlbiwgUGFyZW50Tm9kZSBvdmVycmlkZXMgdGhpcy4KLSAgICAgKiBAc2VlIFBhcmVudE5vZGUKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBoYXNDaGlsZE5vZGVzKCkgewotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogT2J0YWluIGEgTm9kZUxpc3QgZW51bWVyYXRpbmcgYWxsIGNoaWxkcmVuIG9mIHRoaXMgbm9kZS4gSWYgdGhlcmUKLSAgICAgKiBhcmUgbm9uZSwgYW4gKGluaXRpYWxseSkgZW1wdHkgTm9kZUxpc3QgaXMgcmV0dXJuZWQuCi0gICAgICogPHA+Ci0gICAgICogTm9kZUxpc3RzIGFyZSAibGl2ZSI7IGFzIGNoaWxkcmVuIGFyZSBhZGRlZC9yZW1vdmVkIHRoZSBOb2RlTGlzdAotICAgICAqIHdpbGwgaW1tZWRpYXRlbHkgcmVmbGVjdCB0aG9zZSBjaGFuZ2VzLiBBbHNvLCB0aGUgTm9kZUxpc3QgcmVmZXJzCi0gICAgICogdG8gdGhlIGFjdHVhbCBub2Rlcywgc28gY2hhbmdlcyB0byB0aG9zZSBub2RlcyBtYWRlIHZpYSB0aGUgRE9NIHRyZWUKLSAgICAgKiB3aWxsIGJlIHJlZmxlY3RlZCBpbiB0aGUgTm9kZUxpc3QgYW5kIHZpY2UgdmVyc2EuCi0gICAgICogPHA+Ci0gICAgICogSW4gdGhpcyBpbXBsZW1lbnRhdGlvbiwgTm9kZXMgaW1wbGVtZW50IHRoZSBOb2RlTGlzdCBpbnRlcmZhY2UgYW5kCi0gICAgICogcHJvdmlkZSB0aGVpciBvd24gZ2V0Q2hpbGROb2RlcygpIHN1cHBvcnQuIE90aGVyIERPTXMgbWF5IHNvbHZlIHRoaXMKLSAgICAgKiBkaWZmZXJlbnRseS4KLSAgICAgKi8KLSAgICBwdWJsaWMgTm9kZUxpc3QgZ2V0Q2hpbGROb2RlcygpIHsKLSAgICAgICAgcmV0dXJuIHRoaXM7Ci0gICAgfQotCi0gICAgLyoqIFRoZSBmaXJzdCBjaGlsZCBvZiB0aGlzIE5vZGUsIG9yIG51bGwgaWYgbm9uZS4KLSAgICAgKiA8UD4KLSAgICAgKiBCeSBkZWZhdWx0IHdlIGRvIG5vdCBoYXZlIGFueSBjaGlsZHJlbiwgUGFyZW50Tm9kZSBvdmVycmlkZXMgdGhpcy4KLSAgICAgKiBAc2VlIFBhcmVudE5vZGUKLSAgICAgKi8KLSAgICBwdWJsaWMgTm9kZSBnZXRGaXJzdENoaWxkKCkgewotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICAvKiogVGhlIGZpcnN0IGNoaWxkIG9mIHRoaXMgTm9kZSwgb3IgbnVsbCBpZiBub25lLgotICAgICAqIDxQPgotICAgICAqIEJ5IGRlZmF1bHQgd2UgZG8gbm90IGhhdmUgYW55IGNoaWxkcmVuLCBQYXJlbnROb2RlIG92ZXJyaWRlcyB0aGlzLgotICAgICAqIEBzZWUgUGFyZW50Tm9kZQotICAgICAqLwotICAgIHB1YmxpYyBOb2RlIGdldExhc3RDaGlsZCgpIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogTW92ZSBvbmUgb3IgbW9yZSBub2RlKHMpIHRvIG91ciBsaXN0IG9mIGNoaWxkcmVuLiBOb3RlIHRoYXQgdGhpcwotICAgICAqIGltcGxpY2l0bHkgcmVtb3ZlcyB0aGVtIGZyb20gdGhlaXIgcHJldmlvdXMgcGFyZW50LgotICAgICAqIDxQPgotICAgICAqIEJ5IGRlZmF1bHQgd2UgZG8gbm90IGFjY2VwdCBhbnkgY2hpbGRyZW4sIFBhcmVudE5vZGUgb3ZlcnJpZGVzIHRoaXMuCi0gICAgICogQHNlZSBQYXJlbnROb2RlCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmV3Q2hpbGQgVGhlIE5vZGUgdG8gYmUgbW92ZWQgdG8gb3VyIHN1YnRyZWUuIEFzIGEKLSAgICAgKiBjb252ZW5pZW5jZSBmZWF0dXJlLCBpbnNlcnRpbmcgYSBEb2N1bWVudE5vZGUgd2lsbCBpbnN0ZWFkIGluc2VydAotICAgICAqIGFsbCBpdHMgY2hpbGRyZW4uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcmVmQ2hpbGQgQ3VycmVudCBjaGlsZCB3aGljaCBuZXdDaGlsZCBzaG91bGQgYmUgcGxhY2VkCi0gICAgICogaW1tZWRpYXRlbHkgYmVmb3JlLiBJZiByZWZDaGlsZCBpcyBudWxsLCB0aGUgaW5zZXJ0aW9uIG9jY3VycwotICAgICAqIGFmdGVyIGFsbCBleGlzdGluZyBOb2RlcywgbGlrZSBhcHBlbmRDaGlsZCgpLgotICAgICAqCi0gICAgICogQHJldHVybiBuZXdDaGlsZCwgaW4gaXRzIG5ldyBzdGF0ZSAocmVsb2NhdGVkLCBvciBlbXB0aWVkIGluIHRoZSBjYXNlIG9mCi0gICAgICogRG9jdW1lbnROb2RlLikKLSAgICAgKgotICAgICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uKEhJRVJBUkNIWV9SRVFVRVNUX0VSUikgaWYgbmV3Q2hpbGQgaXMgb2YgYQotICAgICAqIHR5cGUgdGhhdCBzaG91bGRuJ3QgYmUgYSBjaGlsZCBvZiB0aGlzIG5vZGUsIG9yIGlmIG5ld0NoaWxkIGlzIGFuCi0gICAgICogYW5jZXN0b3Igb2YgdGhpcyBub2RlLgotICAgICAqCi0gICAgICogQHRocm93cyBET01FeGNlcHRpb24oV1JPTkdfRE9DVU1FTlRfRVJSKSBpZiBuZXdDaGlsZCBoYXMgYQotICAgICAqIGRpZmZlcmVudCBvd25lciBkb2N1bWVudCB0aGFuIHdlIGRvLgotICAgICAqCi0gICAgICogQHRocm93cyBET01FeGNlcHRpb24oTk9UX0ZPVU5EX0VSUikgaWYgcmVmQ2hpbGQgaXMgbm90IGEgY2hpbGQgb2YKLSAgICAgKiB0aGlzIG5vZGUuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbihOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIpIGlmIHRoaXMgbm9kZSBpcwotICAgICAqIHJlYWQtb25seS4KLSAgICAgKi8KLSAgICBwdWJsaWMgTm9kZSBpbnNlcnRCZWZvcmUoTm9kZSBuZXdDaGlsZCwgTm9kZSByZWZDaGlsZCkKLSAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0gICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLkhJRVJBUkNIWV9SRVFVRVNUX0VSUiwKLSAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgIkhJRVJBUkNIWV9SRVFVRVNUX0VSUiIsIG51bGwpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZW1vdmUgYSBjaGlsZCBmcm9tIHRoaXMgTm9kZS4gVGhlIHJlbW92ZWQgY2hpbGQncyBzdWJ0cmVlCi0gICAgICogcmVtYWlucyBpbnRhY3Qgc28gaXQgbWF5IGJlIHJlLWluc2VydGVkIGVsc2V3aGVyZS4KLSAgICAgKiA8UD4KLSAgICAgKiBCeSBkZWZhdWx0IHdlIGRvIG5vdCBoYXZlIGFueSBjaGlsZHJlbiwgUGFyZW50Tm9kZSBvdmVycmlkZXMgdGhpcy4KLSAgICAgKiBAc2VlIFBhcmVudE5vZGUKLSAgICAgKgotICAgICAqIEByZXR1cm4gb2xkQ2hpbGQsIGluIGl0cyBuZXcgc3RhdGUgKHJlbW92ZWQpLgotICAgICAqCi0gICAgICogQHRocm93cyBET01FeGNlcHRpb24oTk9UX0ZPVU5EX0VSUikgaWYgb2xkQ2hpbGQgaXMgbm90IGEgY2hpbGQgb2YKLSAgICAgKiB0aGlzIG5vZGUuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbihOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIpIGlmIHRoaXMgbm9kZSBpcwotICAgICAqIHJlYWQtb25seS4KLSAgICAgKi8KLSAgICBwdWJsaWMgTm9kZSByZW1vdmVDaGlsZChOb2RlIG9sZENoaWxkKQotICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb24gewotICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfRk9VTkRfRVJSLAotICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLAotICAgICAgICAgICAgICAgICAiTk9UX0ZPVU5EX0VSUiIsIG51bGwpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBNYWtlIG5ld0NoaWxkIG9jY3VweSB0aGUgbG9jYXRpb24gdGhhdCBvbGRDaGlsZCB1c2VkIHRvCi0gICAgICogaGF2ZS4gTm90ZSB0aGF0IG5ld0NoaWxkIHdpbGwgZmlyc3QgYmUgcmVtb3ZlZCBmcm9tIGl0cyBwcmV2aW91cwotICAgICAqIHBhcmVudCwgaWYgYW55LiBFcXVpdmFsZW50IHRvIGluc2VydGluZyBuZXdDaGlsZCBiZWZvcmUgb2xkQ2hpbGQsCi0gICAgICogdGhlbiByZW1vdmluZyBvbGRDaGlsZC4KLSAgICAgKiA8UD4KLSAgICAgKiBCeSBkZWZhdWx0IHdlIGRvIG5vdCBoYXZlIGFueSBjaGlsZHJlbiwgUGFyZW50Tm9kZSBvdmVycmlkZXMgdGhpcy4KLSAgICAgKiBAc2VlIFBhcmVudE5vZGUKLSAgICAgKgotICAgICAqIEByZXR1cm4gb2xkQ2hpbGQsIGluIGl0cyBuZXcgc3RhdGUgKHJlbW92ZWQpLgotICAgICAqCi0gICAgICogQHRocm93cyBET01FeGNlcHRpb24oSElFUkFSQ0hZX1JFUVVFU1RfRVJSKSBpZiBuZXdDaGlsZCBpcyBvZiBhCi0gICAgICogdHlwZSB0aGF0IHNob3VsZG4ndCBiZSBhIGNoaWxkIG9mIHRoaXMgbm9kZSwgb3IgaWYgbmV3Q2hpbGQgaXMKLSAgICAgKiBvbmUgb2Ygb3VyIGFuY2VzdG9ycy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uKFdST05HX0RPQ1VNRU5UX0VSUikgaWYgbmV3Q2hpbGQgaGFzIGEKLSAgICAgKiBkaWZmZXJlbnQgb3duZXIgZG9jdW1lbnQgdGhhbiB3ZSBkby4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uKE5PVF9GT1VORF9FUlIpIGlmIG9sZENoaWxkIGlzIG5vdCBhIGNoaWxkIG9mCi0gICAgICogdGhpcyBub2RlLgotICAgICAqCi0gICAgICogQHRocm93cyBET01FeGNlcHRpb24oTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSKSBpZiB0aGlzIG5vZGUgaXMKLSAgICAgKiByZWFkLW9ubHkuCi0gICAgICovCi0gICAgcHVibGljIE5vZGUgcmVwbGFjZUNoaWxkKE5vZGUgbmV3Q2hpbGQsIE5vZGUgb2xkQ2hpbGQpCi0gICAgICAgIHRocm93cyBET01FeGNlcHRpb24gewotICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5ISUVSQVJDSFlfUkVRVUVTVF9FUlIsCi0gICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sCi0gICAgICAgICAgICAgICAgICJISUVSQVJDSFlfUkVRVUVTVF9FUlIiLCBudWxsKSk7Ci0gICAgfQotCi0gICAgLy8KLSAgICAvLyBOb2RlTGlzdCBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIE5vZGVMaXN0IG1ldGhvZDogQ291bnQgdGhlIGltbWVkaWF0ZSBjaGlsZHJlbiBvZiB0aGlzIG5vZGUKLSAgICAgKiA8UD4KLSAgICAgKiBCeSBkZWZhdWx0IHdlIGRvIG5vdCBoYXZlIGFueSBjaGlsZHJlbiwgUGFyZW50Tm9kZSBvdmVycmlkZXMgdGhpcy4KLSAgICAgKiBAc2VlIFBhcmVudE5vZGUKLSAgICAgKgotICAgICAqIEByZXR1cm4gaW50Ci0gICAgICovCi0gICAgcHVibGljIGludCBnZXRMZW5ndGgoKSB7Ci0gICAgICAgIHJldHVybiAwOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIE5vZGVMaXN0IG1ldGhvZDogUmV0dXJuIHRoZSBOdGggaW1tZWRpYXRlIGNoaWxkIG9mIHRoaXMgbm9kZSwgb3IKLSAgICAgKiBudWxsIGlmIHRoZSBpbmRleCBpcyBvdXQgb2YgYm91bmRzLgotICAgICAqIDxQPgotICAgICAqIEJ5IGRlZmF1bHQgd2UgZG8gbm90IGhhdmUgYW55IGNoaWxkcmVuLCBQYXJlbnROb2RlIG92ZXJyaWRlcyB0aGlzLgotICAgICAqIEBzZWUgUGFyZW50Tm9kZQotICAgICAqCi0gICAgICogQHJldHVybiBvcmcudzNjLmRvbS5Ob2RlCi0gICAgICogQHBhcmFtIEluZGV4IGludAotICAgICAqLwotICAgIHB1YmxpYyBOb2RlIGl0ZW0oaW50IGluZGV4KSB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8vCi0gICAgLy8gRE9NMjogbWV0aG9kcywgZ2V0dGVycywgc2V0dGVycwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBQdXRzIGFsbCA8Y29kZT5UZXh0PC9jb2RlPiBub2RlcyBpbiB0aGUgZnVsbCBkZXB0aCBvZiB0aGUgc3ViLXRyZWUKLSAgICAgKiB1bmRlcm5lYXRoIHRoaXMgPGNvZGU+Tm9kZTwvY29kZT4sIGluY2x1ZGluZyBhdHRyaWJ1dGUgbm9kZXMsIGludG8gYQotICAgICAqICJub3JtYWwiIGZvcm0gd2hlcmUgb25seSBtYXJrdXAgKGUuZy4sIHRhZ3MsIGNvbW1lbnRzLCBwcm9jZXNzaW5nCi0gICAgICogaW5zdHJ1Y3Rpb25zLCBDREFUQSBzZWN0aW9ucywgYW5kIGVudGl0eSByZWZlcmVuY2VzKSBzZXBhcmF0ZXMKLSAgICAgKiA8Y29kZT5UZXh0PC9jb2RlPiBub2RlcywgaS5lLiwgdGhlcmUgYXJlIG5vIGFkamFjZW50IDxjb2RlPlRleHQ8L2NvZGU+Ci0gICAgICogbm9kZXMuICBUaGlzIGNhbiBiZSB1c2VkIHRvIGVuc3VyZSB0aGF0IHRoZSBET00gdmlldyBvZiBhIGRvY3VtZW50IGlzCi0gICAgICogdGhlIHNhbWUgYXMgaWYgaXQgd2VyZSBzYXZlZCBhbmQgcmUtbG9hZGVkLCBhbmQgaXMgdXNlZnVsIHdoZW4KLSAgICAgKiBvcGVyYXRpb25zIChzdWNoIGFzIFhQb2ludGVyIGxvb2t1cHMpIHRoYXQgZGVwZW5kIG9uIGEgcGFydGljdWxhcgotICAgICAqIGRvY3VtZW50IHRyZWUgc3RydWN0dXJlIGFyZSB0byBiZSB1c2VkLkluIGNhc2VzIHdoZXJlIHRoZSBkb2N1bWVudAotICAgICAqIGNvbnRhaW5zIDxjb2RlPkNEQVRBU2VjdGlvbnM8L2NvZGU+LCB0aGUgbm9ybWFsaXplIG9wZXJhdGlvbiBhbG9uZSBtYXkKLSAgICAgKiBub3QgYmUgc3VmZmljaWVudCwgc2luY2UgWFBvaW50ZXJzIGRvIG5vdCBkaWZmZXJlbnRpYXRlIGJldHdlZW4KLSAgICAgKiA8Y29kZT5UZXh0PC9jb2RlPiBub2RlcyBhbmQgPGNvZGU+Q0RBVEFTZWN0aW9uPC9jb2RlPiBub2Rlcy4KLSAgICAgKiA8cD4KLSAgICAgKiBOb3RlIHRoYXQgdGhpcyBpbXBsZW1lbnRhdGlvbiBzaW1wbHkgY2FsbHMgbm9ybWFsaXplKCkgb24gdGhpcyBOb2RlJ3MKLSAgICAgKiBjaGlsZHJlbi4gSXQgaXMgdXAgdG8gaW1wbGVtZW50b3JzIG9yIE5vZGUgdG8gb3ZlcnJpZGUgbm9ybWFsaXplKCkKLSAgICAgKiB0byB0YWtlIGFjdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBub3JtYWxpemUoKSB7Ci0gICAgICAgIC8qIGJ5IGRlZmF1bHQgd2UgZG8gbm90IGhhdmUgYW55IGNoaWxkcmVuLAotICAgICAgICAgICBQYXJlbnROb2RlIG92ZXJyaWRlcyB0aGlzIGJlaGF2aW9yICovCi0gICAgfQotCi0gICAgLyoqCi0gICAgICogSW50cm9kdWNlZCBpbiBET00gTGV2ZWwgMi4gPHA+Ci0gICAgICogVGVzdHMgd2hldGhlciB0aGUgRE9NIGltcGxlbWVudGF0aW9uIGltcGxlbWVudHMgYSBzcGVjaWZpYyBmZWF0dXJlIGFuZAotICAgICAqIHRoYXQgZmVhdHVyZSBpcyBzdXBwb3J0ZWQgYnkgdGhpcyBub2RlLgotICAgICAqIEBwYXJhbSBmZWF0dXJlIFRoZSBwYWNrYWdlIG5hbWUgb2YgdGhlIGZlYXR1cmUgdG8gdGVzdC4gVGhpcyBpcyB0aGUgc2FtZQotICAgICAqIG5hbWUgYXMgd2hhdCBjYW4gYmUgcGFzc2VkIHRvIHRoZSBtZXRob2QgaGFzRmVhdHVyZSBvbgotICAgICAqIERPTUltcGxlbWVudGF0aW9uLgotICAgICAqIEBwYXJhbSB2ZXJzaW9uIFRoaXMgaXMgdGhlIHZlcnNpb24gbnVtYmVyIG9mIHRoZSBwYWNrYWdlIG5hbWUgdG8KLSAgICAgKiB0ZXN0LiBJbiBMZXZlbCAyLCB2ZXJzaW9uIDEsIHRoaXMgaXMgdGhlIHN0cmluZyAiMi4wIi4gSWYgdGhlIHZlcnNpb24gaXMKLSAgICAgKiBub3Qgc3BlY2lmaWVkLCBzdXBwb3J0aW5nIGFueSB2ZXJzaW9uIG9mIHRoZSBmZWF0dXJlIHdpbGwgY2F1c2UgdGhlCi0gICAgICogbWV0aG9kIHRvIHJldHVybiB0cnVlLgotICAgICAqIEByZXR1cm4gYm9vbGVhbiBSZXR1cm5zIHRydWUgaWYgdGhpcyBub2RlIGRlZmluZXMgYSBzdWJ0cmVlIHdpdGhpbiB3aGljaAotICAgICAqIHRoZSBzcGVjaWZpZWQgZmVhdHVyZSBpcyBzdXBwb3J0ZWQsIGZhbHNlIG90aGVyd2lzZS4KLSAgICAgKiBAc2luY2UgV0QtRE9NLUxldmVsLTItMTk5OTA5MjMKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc1N1cHBvcnRlZChTdHJpbmcgZmVhdHVyZSwgU3RyaW5nIHZlcnNpb24pCi0gICAgewotICAgICAgICByZXR1cm4gb3duZXJEb2N1bWVudCgpLmdldEltcGxlbWVudGF0aW9uKCkuaGFzRmVhdHVyZShmZWF0dXJlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZXJzaW9uKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJbnRyb2R1Y2VkIGluIERPTSBMZXZlbCAyLiA8cD4KLSAgICAgKgotICAgICAqIFRoZSBuYW1lc3BhY2UgVVJJIG9mIHRoaXMgbm9kZSwgb3IgbnVsbCBpZiBpdCBpcyB1bnNwZWNpZmllZC4gV2hlbiB0aGlzCi0gICAgICogbm9kZSBpcyBvZiBhbnkgdHlwZSBvdGhlciB0aGFuIEVMRU1FTlRfTk9ERSBhbmQgQVRUUklCVVRFX05PREUsIHRoaXMgaXMKLSAgICAgKiBhbHdheXMgbnVsbCBhbmQgc2V0dGluZyBpdCBoYXMgbm8gZWZmZWN0LiA8cD4KLSAgICAgKgotICAgICAqIFRoaXMgaXMgbm90IGEgY29tcHV0ZWQgdmFsdWUgdGhhdCBpcyB0aGUgcmVzdWx0IG9mIGEgbmFtZXNwYWNlIGxvb2t1cAotICAgICAqIGJhc2VkIG9uIGFuIGV4YW1pbmF0aW9uIG9mIHRoZSBuYW1lc3BhY2UgZGVjbGFyYXRpb25zIGluIHNjb3BlLiBJdCBpcwotICAgICAqIG1lcmVseSB0aGUgbmFtZXNwYWNlIFVSSSBnaXZlbiBhdCBjcmVhdGlvbiB0aW1lLjxwPgotICAgICAqCi0gICAgICogRm9yIG5vZGVzIGNyZWF0ZWQgd2l0aCBhIERPTSBMZXZlbCAxIG1ldGhvZCwgc3VjaCBhcyBjcmVhdGVFbGVtZW50Ci0gICAgICogZnJvbSB0aGUgRG9jdW1lbnQgaW50ZXJmYWNlLCB0aGlzIGlzIG51bGwuCi0gICAgICogQHNpbmNlIFdELURPTS1MZXZlbC0yLTE5OTkwOTIzCi0gICAgICogQHNlZSBBdHRyTlNJbXBsCi0gICAgICogQHNlZSBFbGVtZW50TlNJbXBsCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXROYW1lc3BhY2VVUkkoKQotICAgIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSW50cm9kdWNlZCBpbiBET00gTGV2ZWwgMi4gPHA+Ci0gICAgICoKLSAgICAgKiBUaGUgbmFtZXNwYWNlIHByZWZpeCBvZiB0aGlzIG5vZGUsIG9yIG51bGwgaWYgaXQgaXMgdW5zcGVjaWZpZWQuIFdoZW4KLSAgICAgKiB0aGlzIG5vZGUgaXMgb2YgYW55IHR5cGUgb3RoZXIgdGhhbiBFTEVNRU5UX05PREUgYW5kIEFUVFJJQlVURV9OT0RFIHRoaXMKLSAgICAgKiBpcyBhbHdheXMgbnVsbCBhbmQgc2V0dGluZyBpdCBoYXMgbm8gZWZmZWN0LjxwPgotICAgICAqCi0gICAgICogRm9yIG5vZGVzIGNyZWF0ZWQgd2l0aCBhIERPTSBMZXZlbCAxIG1ldGhvZCwgc3VjaCBhcyBjcmVhdGVFbGVtZW50Ci0gICAgICogZnJvbSB0aGUgRG9jdW1lbnQgaW50ZXJmYWNlLCB0aGlzIGlzIG51bGwuIDxwPgotICAgICAqCi0gICAgICogQHNpbmNlIFdELURPTS1MZXZlbC0yLTE5OTkwOTIzCi0gICAgICogQHNlZSBBdHRyTlNJbXBsCi0gICAgICogQHNlZSBFbGVtZW50TlNJbXBsCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRQcmVmaXgoKQotICAgIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogIEludHJvZHVjZWQgaW4gRE9NIExldmVsIDIuIDxwPgotICAgICAqCi0gICAgICogIFRoZSBuYW1lc3BhY2UgcHJlZml4IG9mIHRoaXMgbm9kZSwgb3IgbnVsbCBpZiBpdCBpcyB1bnNwZWNpZmllZC4gV2hlbgotICAgICAqICB0aGlzIG5vZGUgaXMgb2YgYW55IHR5cGUgb3RoZXIgdGhhbiBFTEVNRU5UX05PREUgYW5kIEFUVFJJQlVURV9OT0RFCi0gICAgICogIHRoaXMgaXMgYWx3YXlzIG51bGwgYW5kIHNldHRpbmcgaXQgaGFzIG5vIGVmZmVjdC48cD4KLSAgICAgKgotICAgICAqICBGb3Igbm9kZXMgY3JlYXRlZCB3aXRoIGEgRE9NIExldmVsIDEgbWV0aG9kLCBzdWNoIGFzIGNyZWF0ZUVsZW1lbnQgZnJvbQotICAgICAqICB0aGUgRG9jdW1lbnQgaW50ZXJmYWNlLCB0aGlzIGlzIG51bGwuPHA+Ci0gICAgICoKLSAgICAgKiAgTm90ZSB0aGF0IHNldHRpbmcgdGhpcyBhdHRyaWJ1dGUgY2hhbmdlcyB0aGUgbm9kZU5hbWUgYXR0cmlidXRlLCB3aGljaAotICAgICAqICBob2xkcyB0aGUgcXVhbGlmaWVkIG5hbWUsIGFzIHdlbGwgYXMgdGhlIHRhZ05hbWUgYW5kIG5hbWUgYXR0cmlidXRlcyBvZgotICAgICAqICB0aGUgRWxlbWVudCBhbmQgQXR0ciBpbnRlcmZhY2VzLCB3aGVuIGFwcGxpY2FibGUuPHA+Ci0gICAgICoKLSAgICAgKiBAdGhyb3dzIElOVkFMSURfQ0hBUkFDVEVSX0VSUiBSYWlzZWQgaWYgdGhlIHNwZWNpZmllZAotICAgICAqICBwcmVmaXggY29udGFpbnMgYW4gaW52YWxpZCBjaGFyYWN0ZXIuCi0gICAgICoKLSAgICAgKiBAc2luY2UgV0QtRE9NLUxldmVsLTItMTk5OTA5MjMKLSAgICAgKiBAc2VlIEF0dHJOU0ltcGwKLSAgICAgKiBAc2VlIEVsZW1lbnROU0ltcGwKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRQcmVmaXgoU3RyaW5nIHByZWZpeCkKLSAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTkFNRVNQQUNFX0VSUiwKLSAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgIk5BTUVTUEFDRV9FUlIiLCBudWxsKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSW50cm9kdWNlZCBpbiBET00gTGV2ZWwgMi4gPHA+Ci0gICAgICoKLSAgICAgKiBSZXR1cm5zIHRoZSBsb2NhbCBwYXJ0IG9mIHRoZSBxdWFsaWZpZWQgbmFtZSBvZiB0aGlzIG5vZGUuCi0gICAgICogRm9yIG5vZGVzIGNyZWF0ZWQgd2l0aCBhIERPTSBMZXZlbCAxIG1ldGhvZCwgc3VjaCBhcyBjcmVhdGVFbGVtZW50Ci0gICAgICogZnJvbSB0aGUgRG9jdW1lbnQgaW50ZXJmYWNlLCBhbmQgZm9yIG5vZGVzIG9mIGFueSB0eXBlIG90aGVyIHRoYW4KLSAgICAgKiBFTEVNRU5UX05PREUgYW5kIEFUVFJJQlVURV9OT0RFIHRoaXMgaXMgdGhlIHNhbWUgYXMgdGhlIG5vZGVOYW1lCi0gICAgICogYXR0cmlidXRlLgotICAgICAqIEBzaW5jZSBXRC1ET00tTGV2ZWwtMi0xOTk5MDkyMwotICAgICAqIEBzZWUgQXR0ck5TSW1wbAotICAgICAqIEBzZWUgRWxlbWVudE5TSW1wbAotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgICAgICAgICAgICAgZ2V0TG9jYWxOYW1lKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8vCi0gICAgLy8gRXZlbnRUYXJnZXQgc3VwcG9ydAotICAgIC8vCi0KLSAgICBwdWJsaWMgdm9pZCBhZGRFdmVudExpc3RlbmVyKFN0cmluZyB0eXBlLCBFdmVudExpc3RlbmVyIGxpc3RlbmVyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiB1c2VDYXB0dXJlKSB7Ci0gICAgICAgIC8vIHNpbXBseSBmb3J3YXJkIHRvIERvY3VtZW50Ci0gICAgICAgIG93bmVyRG9jdW1lbnQoKS5hZGRFdmVudExpc3RlbmVyKHRoaXMsIHR5cGUsIGxpc3RlbmVyLCB1c2VDYXB0dXJlKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCByZW1vdmVFdmVudExpc3RlbmVyKFN0cmluZyB0eXBlLCBFdmVudExpc3RlbmVyIGxpc3RlbmVyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiB1c2VDYXB0dXJlKSB7Ci0gICAgICAgIC8vIHNpbXBseSBmb3J3YXJkIHRvIERvY3VtZW50Ci0gICAgICAgIG93bmVyRG9jdW1lbnQoKS5yZW1vdmVFdmVudExpc3RlbmVyKHRoaXMsIHR5cGUsIGxpc3RlbmVyLCB1c2VDYXB0dXJlKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBkaXNwYXRjaEV2ZW50KEV2ZW50IGV2ZW50KSB7Ci0gICAgICAgIC8vIHNpbXBseSBmb3J3YXJkIHRvIERvY3VtZW50Ci0gICAgICAgIHJldHVybiBvd25lckRvY3VtZW50KCkuZGlzcGF0Y2hFdmVudCh0aGlzLCBldmVudCk7Ci0gICAgfQotCi0gICAgLy8KLSAgICAvLyBQdWJsaWMgRE9NIExldmVsIDMgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBUaGUgYWJzb2x1dGUgYmFzZSBVUkkgb2YgdGhpcyBub2RlIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIHVuZGVmaW5lZC4KLSAgICAgKiBUaGlzIHZhbHVlIGlzIGNvbXB1dGVkIGFjY29yZGluZyB0byAuIEhvd2V2ZXIsIHdoZW4gdGhlCi0gICAgICogPGNvZGU+RG9jdW1lbnQ8L2NvZGU+IHN1cHBvcnRzIHRoZSBmZWF0dXJlICJIVE1MIiAsIHRoZSBiYXNlIFVSSSBpcwotICAgICAqIGNvbXB1dGVkIHVzaW5nIGZpcnN0IHRoZSB2YWx1ZSBvZiB0aGUgaHJlZiBhdHRyaWJ1dGUgb2YgdGhlIEhUTUwgQkFTRQotICAgICAqIGVsZW1lbnQgaWYgYW55LCBhbmQgdGhlIHZhbHVlIG9mIHRoZSA8Y29kZT5kb2N1bWVudFVSSTwvY29kZT4KLSAgICAgKiBhdHRyaWJ1dGUgZnJvbSB0aGUgPGNvZGU+RG9jdW1lbnQ8L2NvZGU+IGludGVyZmFjZSBvdGhlcndpc2UuCi0gICAgICogPGJyPiBXaGVuIHRoZSBub2RlIGlzIGFuIDxjb2RlPkVsZW1lbnQ8L2NvZGU+LCBhIDxjb2RlPkRvY3VtZW50PC9jb2RlPgotICAgICAqIG9yIGEgYSA8Y29kZT5Qcm9jZXNzaW5nSW5zdHJ1Y3Rpb248L2NvZGU+LCB0aGlzIGF0dHJpYnV0ZSByZXByZXNlbnRzCi0gICAgICogdGhlIHByb3BlcnRpZXMgW2Jhc2UgVVJJXSBkZWZpbmVkIGluIC4gV2hlbiB0aGUgbm9kZSBpcyBhCi0gICAgICogPGNvZGU+Tm90YXRpb248L2NvZGU+LCBhbiA8Y29kZT5FbnRpdHk8L2NvZGU+LCBvciBhbgotICAgICAqIDxjb2RlPkVudGl0eVJlZmVyZW5jZTwvY29kZT4sIHRoaXMgYXR0cmlidXRlIHJlcHJlc2VudHMgdGhlCi0gICAgICogcHJvcGVydGllcyBbZGVjbGFyYXRpb24gYmFzZSBVUkldIGluIHRoZSAuIEhvdyB3aWxsIHRoaXMgYmUgYWZmZWN0ZWQKLSAgICAgKiBieSByZXNvbHV0aW9uIG9mIHJlbGF0aXZlIG5hbWVzcGFjZSBVUklzIGlzc3VlP0l0J3Mgbm90LlNob3VsZCB0aGlzCi0gICAgICogb25seSBiZSBvbiBEb2N1bWVudCwgRWxlbWVudCwgUHJvY2Vzc2luZ0luc3RydWN0aW9uLCBFbnRpdHksIGFuZAotICAgICAqIE5vdGF0aW9uIG5vZGVzLCBhY2NvcmRpbmcgdG8gdGhlIGluZm9zZXQ/IElmIG5vdCwgd2hhdCBpcyBpdCBlcXVhbCB0bwotICAgICAqIG9uIG90aGVyIG5vZGVzPyBOdWxsPyBBbiBlbXB0eSBzdHJpbmc/IEkgdGhpbmsgaXQgc2hvdWxkIGJlIHRoZQotICAgICAqIHBhcmVudCdzLk5vLlNob3VsZCB0aGlzIGJlIHJlYWQtb25seSBhbmQgY29tcHV0ZWQgb3IgYW5kIGFjdHVhbAotICAgICAqIHJlYWQtd3JpdGUgYXR0cmlidXRlP1JlYWQtb25seSBhbmQgY29tcHV0ZWQgKEYyRiAxOSBKdW4gMjAwMCBhbmQKLSAgICAgKiB0ZWxlY29uZmVyZW5jZSAzMCBNYXkgMjAwMSkuSWYgdGhlIGJhc2UgSFRNTCBlbGVtZW50IGlzIG5vdCB5ZXQKLSAgICAgKiBhdHRhY2hlZCB0byBhIGRvY3VtZW50LCBkb2VzIHRoZSBpbnNlcnQgY2hhbmdlIHRoZSBEb2N1bWVudC5iYXNlVVJJPwotICAgICAqIFllcy4gKEYyRiAyNiBTZXAgMjAwMSkKLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEJhc2VVUkkoKSB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbXBhcmVzIGEgbm9kZSB3aXRoIHRoaXMgbm9kZSB3aXRoIHJlZ2FyZCB0byB0aGVpciBwb3NpdGlvbiBpbiB0aGUKLSAgICAgKiB0cmVlIGFuZCBhY2NvcmRpbmcgdG8gdGhlIGRvY3VtZW50IG9yZGVyLiBUaGlzIG9yZGVyIGNhbiBiZSBleHRlbmRlZAotICAgICAqIGJ5IG1vZHVsZSB0aGF0IGRlZmluZSBhZGRpdGlvbmFsIHR5cGVzIG9mIG5vZGVzLgotICAgICAqIEBwYXJhbSBvdGhlciBUaGUgbm9kZSB0byBjb21wYXJlIGFnYWluc3QgdGhpcyBub2RlLgotICAgICAqIEByZXR1cm4gUmV0dXJucyBob3cgdGhlIGdpdmVuIG5vZGUgaXMgcG9zaXRpb25lZCByZWxhdGl2ZWx5IHRvIHRoaXMKLSAgICAgKiAgIG5vZGUuCi0gICAgICogQHNpbmNlIERPTSBMZXZlbCAzCi0gICAgICogQGRlcHJlY2F0ZWQKLSAgICAgKi8KLSAgICBwdWJsaWMgc2hvcnQgY29tcGFyZVRyZWVQb3NpdGlvbihOb2RlIG90aGVyKSB7Ci0gICAgICAgIC8vIFF1ZXN0aW9ucyBvZiBjbGFyaWZpY2F0aW9uIGZvciB0aGlzIG1ldGhvZCAtIHRvIGJlIGFuc3dlcmVkIGJ5IHRoZQotICAgICAgICAvLyBET00gV0cuICAgQ3VycmVudCBhc3N1bXB0aW9ucyBsaXN0ZWQgLSBMTQotICAgICAgICAvLwotICAgICAgICAvLyAxLiBIb3cgZG8gRU5USVRZIG5vZGVzIGNvbXBhcmU/Ci0gICAgICAgIC8vICAgIEN1cnJlbnQgYXNzdW1wdGlvbjogVFJFRV9QT1NJVElPTl9ESVNDT05ORUNURUQsIGFzIEVOVElUWSBub2RlcwotICAgICAgICAvLyAgICBhcmVuJ3QgcmVhbGx5ICdpbiB0aGUgdHJlZScKLSAgICAgICAgLy8KLSAgICAgICAgLy8gMi4gSG93IGRvIE5PVEFUSU9OIG5vZGVzIGNvbXBhcmU/Ci0gICAgICAgIC8vICAgIEN1cnJlbnQgYXNzdW1wdGlvbjogVFJFRV9QT1NJVElPTl9ESVNDT05ORUNURUQsIGFzIE5PVEFUSU9OIG5vZGVzCi0gICAgICAgIC8vICAgIGFyZW4ndCByZWFsbHkgJ2luIHRoZSB0cmVlJwotICAgICAgICAvLwotICAgICAgICAvLyAzLiBBcmUgVFJFRV9QT1NJVElPTl9BTkNFU1RPUiBhbmQgVFJFRV9QT1NJVElPTl9ERVNDRU5EQU5UCi0gICAgICAgIC8vICAgIG9ubHkgcmVsZXZhbnQgZm9yIG5vZGVzIHRoYXQgYXJlICJwYXJ0IG9mIHRoZSBkb2N1bWVudCB0cmVlIj8KLSAgICAgICAgLy8gICAgIDxvdXRlcj4KLSAgICAgICAgLy8gICAgICAgICA8aW5uZXIgIG15YXR0cj0idHJ1ZSIvPgotICAgICAgICAvLyAgICAgPC9vdXRlcj4KLSAgICAgICAgLy8gICAgSXMgdGhlIGVsZW1lbnQgbm9kZSAib3V0ZXIiIGNvbnNpZGVyZWQgYW4gYW5jZXN0b3Igb2YgIm15YXR0ciI/Ci0gICAgICAgIC8vICAgIEN1cnJlbnQgYXNzdW1wdGlvbjogTm8uCi0gICAgICAgIC8vCi0gICAgICAgIC8vIDQuIEhvdyBkbyBjaGlsZHJlbiBvZiBBVFRSSUJVVEUgbm9kZXMgY29tcGFyZSAod2l0aCBlYWNob3RoZXIsIG9yCi0gICAgICAgIC8vICAgIHdpdGggY2hpbGRyZW4gb2Ygb3RoZXIgYXR0cmlidXRlIG5vZGVzIHdpdGggdGhlIHNhbWUgZWxlbWVudCkKLSAgICAgICAgLy8gICAgQ3VycmVudCBhc3N1bXB0aW9uOiBDaGlsZHJlbiBvZiBBVFRSSUJVVEUgbm9kZXMgYXJlIHRyZWF0ZWQgYXMgaWYKLSAgICAgICAgLy8gICAgdGhleSB0aGV5IGFyZSB0aGUgYXR0cmlidXRlIG5vZGUgaXRzZWxmLCB1bmxlc3MgdGhlIDIgbm9kZXMKLSAgICAgICAgLy8gICAgYXJlIGJvdGggY2hpbGRyZW4gb2YgdGhlIHNhbWUgYXR0cmlidXRlLgotICAgICAgICAvLwotICAgICAgICAvLyA1LiBIb3cgZG9lcyBhbiBFTlRJVFlfUkVGRVJFTkNFIG5vZGUgY29tcGFyZSB3aXRoIGl0J3MgY2hpbGRyZW4/Ci0gICAgICAgIC8vICAgIEdpdmVuIHRoZSBET00sIGl0IHNob3VsZCBwcmVjZWRlIGl0cyBjaGlsZHJlbiBhcyBhbiBhbmNlc3Rvci4KLSAgICAgICAgLy8gICAgR2l2ZW4gImRvY3VtZW50IG9yZGVyIiwgIGRvZXMgaXQgcmVwcmVzZW50IHRoZSBzYW1lIHBvc2l0aW9uPwotICAgICAgICAvLyAgICBDdXJyZW50IGFzc3VtcHRpb246IEFuIEVOVElUWV9SRUZFUkVOQ0Ugbm9kZSBpcyBhbiBhbmNlc3RvciBvZiBpdHMKLSAgICAgICAgLy8gICAgY2hpbGRyZW4uCi0gICAgICAgIC8vCi0gICAgICAgIC8vIDYuIEhvdyBkbyBjaGlsZHJlbiBvZiBhIERvY3VtZW50RnJhZ21lbnQgY29tcGFyZT8KLSAgICAgICAgLy8gICAgQ3VycmVudCBhc3N1bXB0aW9uOiBJZiBib3RoIG5vZGVzIGFyZSBwYXJ0IG9mIHRoZSBzYW1lIGRvY3VtZW50Ci0gICAgICAgIC8vICAgIGZyYWdtZW50LCB0aGVyZSBhcmUgY29tcGFyZWQgYXMgaWYgdGhleSB3ZXJlIHBhcnQgb2YgYSBkb2N1bWVudC4KLQotCi0gICAgICAgIC8vIElmIHRoZSBub2RlcyBhcmUgdGhlIHNhbWUuLi4KLSAgICAgICAgaWYgKHRoaXM9PW90aGVyKQotICAgICAgICAgIHJldHVybiAoVFJFRV9QT1NJVElPTl9TQU1FX05PREUgfCBUUkVFX1BPU0lUSU9OX0VRVUlWQUxFTlQpOwotCi0gICAgICAgIC8vIElmIGVpdGhlciBub2RlIGlzIG9mIHR5cGUgRU5USVRZIG9yIE5PVEFUSU9OLCBjb21wYXJlIGFzIGRpc2Nvbm5lY3RlZAotICAgICAgICBzaG9ydCB0aGlzVHlwZSA9IHRoaXMuZ2V0Tm9kZVR5cGUoKTsKLSAgICAgICAgc2hvcnQgb3RoZXJUeXBlID0gb3RoZXIuZ2V0Tm9kZVR5cGUoKTsKLQotICAgICAgICAvLyBJZiBlaXRoZXIgbm9kZSBpcyBvZiB0eXBlIEVOVElUWSBvciBOT1RBVElPTiwgY29tcGFyZSBhcyBkaXNjb25uZWN0ZWQKLSAgICAgICAgaWYgKHRoaXNUeXBlID09IE5vZGUuRU5USVRZX05PREUgfHwKLSAgICAgICAgICAgIHRoaXNUeXBlID09IE5vZGUuTk9UQVRJT05fTk9ERSB8fAotICAgICAgICAgICAgb3RoZXJUeXBlID09IE5vZGUuRU5USVRZX05PREUgfHwKLSAgICAgICAgICAgIG90aGVyVHlwZSA9PSBOb2RlLk5PVEFUSU9OX05PREUgKSB7Ci0gICAgICAgICAgcmV0dXJuIFRSRUVfUE9TSVRJT05fRElTQ09OTkVDVEVEOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gRmluZCB0aGUgYW5jZXN0b3Igb2YgZWFjaCBub2RlLCBhbmQgdGhlIGRpc3RhbmNlIGVhY2ggbm9kZSBpcyBmcm9tCi0gICAgICAgIC8vIGl0cyBhbmNlc3Rvci4KLSAgICAgICAgLy8gRHVyaW5nIHRoaXMgdHJhdmVyc2FsLCBsb29rIGZvciBhbmNlc3Rvci9kZXNjZW5kZW50IHJlbGF0aW9uc2hpcHMKLSAgICAgICAgLy8gYmV0d2VlbiB0aGUgMiBub2RlcyBpbiBxdWVzdGlvbi4KLSAgICAgICAgLy8gV2UgZG8gdGhpcyBub3csIHNvIHRoYXQgd2UgZ2V0IHRoaXMgaW5mbyBjb3JyZWN0IGZvciBhdHRyaWJ1dGUgbm9kZXMKLSAgICAgICAgLy8gYW5kIHRoZWlyIGNoaWxkcmVuLgotCi0gICAgICAgIE5vZGUgbm9kZTsKLSAgICAgICAgTm9kZSB0aGlzQW5jZXN0b3IgPSB0aGlzOwotICAgICAgICBOb2RlIG90aGVyQW5jZXN0b3IgPSBvdGhlcjsKLSAgICAgICAgaW50IHRoaXNEZXB0aD0wOwotICAgICAgICBpbnQgb3RoZXJEZXB0aD0wOwotICAgICAgICBmb3IgKG5vZGU9dGhpczsgbm9kZSAhPSBudWxsOyBub2RlID0gbm9kZS5nZXRQYXJlbnROb2RlKCkpIHsKLSAgICAgICAgICAgIHRoaXNEZXB0aCArPTE7Ci0gICAgICAgICAgICBpZiAobm9kZSA9PSBvdGhlcikKLSAgICAgICAgICAgICAgLy8gVGhlIG90aGVyIG5vZGUgaXMgYW4gYW5jZXN0b3Igb2YgdGhpcyBvbmUuCi0gICAgICAgICAgICAgIHJldHVybiAoVFJFRV9QT1NJVElPTl9BTkNFU1RPUiB8IFRSRUVfUE9TSVRJT05fUFJFQ0VESU5HKTsKLSAgICAgICAgICAgIHRoaXNBbmNlc3RvciA9IG5vZGU7Ci0gICAgICAgIH0KLQotICAgICAgICBmb3IgKG5vZGU9b3RoZXI7IG5vZGUhPW51bGw7IG5vZGU9bm9kZS5nZXRQYXJlbnROb2RlKCkpIHsKLSAgICAgICAgICAgIG90aGVyRGVwdGggKz0xOwotICAgICAgICAgICAgaWYgKG5vZGUgPT0gdGhpcykKLSAgICAgICAgICAgICAgLy8gVGhlIG90aGVyIG5vZGUgaXMgYSBkZXNjZW5kZW50IG9mIHRoZSByZWZlcmVuY2Ugbm9kZS4KLSAgICAgICAgICAgICAgcmV0dXJuIChUUkVFX1BPU0lUSU9OX0RFU0NFTkRBTlQgfCBUUkVFX1BPU0lUSU9OX0ZPTExPV0lORyk7Ci0gICAgICAgICAgICBvdGhlckFuY2VzdG9yID0gbm9kZTsKLSAgICAgICAgfQotCi0KLSAgICAgICAgTm9kZSB0aGlzTm9kZSA9IHRoaXM7Ci0gICAgICAgIE5vZGUgb3RoZXJOb2RlID0gb3RoZXI7Ci0KLSAgICAgICAgaW50IHRoaXNBbmNlc3RvclR5cGUgPSB0aGlzQW5jZXN0b3IuZ2V0Tm9kZVR5cGUoKTsKLSAgICAgICAgaW50IG90aGVyQW5jZXN0b3JUeXBlID0gb3RoZXJBbmNlc3Rvci5nZXROb2RlVHlwZSgpOwotCi0gICAgICAgIC8vIGlmIHRoZSBhbmNlc3RvciBpcyBhbiBhdHRyaWJ1dGUsIGdldCBvd25pbmcgZWxlbWVudC4KLSAgICAgICAgLy8gd2UgYXJlIG5vdyBpbnRlcmVzdGVkIGluIHRoZSBvd25lciB0byBkZXRlcm1pbmUgcG9zaXRpb24uCi0KLSAgICAgICAgaWYgKHRoaXNBbmNlc3RvclR5cGUgPT0gTm9kZS5BVFRSSUJVVEVfTk9ERSkgIHsKLSAgICAgICAgICAgdGhpc05vZGUgPSAoKEF0dHJJbXBsKXRoaXNBbmNlc3RvcikuZ2V0T3duZXJFbGVtZW50KCk7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKG90aGVyQW5jZXN0b3JUeXBlID09IE5vZGUuQVRUUklCVVRFX05PREUpIHsKLSAgICAgICAgICAgb3RoZXJOb2RlID0gKChBdHRySW1wbClvdGhlckFuY2VzdG9yKS5nZXRPd25lckVsZW1lbnQoKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIEJlZm9yZSBwcm9jZWVkaW5nLCB3ZSBzaG91bGQgY2hlY2sgaWYgYm90aCBhbmNlc3RvciBub2RlcyB0dXJuZWQKLSAgICAgICAgLy8gb3V0IHRvIGJlIGF0dHJpYnV0ZXMgZm9yIHRoZSBzYW1lIGVsZW1lbnQKLSAgICAgICAgaWYgKHRoaXNBbmNlc3RvclR5cGUgPT0gTm9kZS5BVFRSSUJVVEVfTk9ERSAmJgotICAgICAgICAgICAgb3RoZXJBbmNlc3RvclR5cGUgPT0gTm9kZS5BVFRSSUJVVEVfTk9ERSAmJgotICAgICAgICAgICAgdGhpc05vZGU9PW90aGVyTm9kZSkKLSAgICAgICAgICAgIHJldHVybiBUUkVFX1BPU0lUSU9OX0VRVUlWQUxFTlQ7Ci0KLSAgICAgICAgLy8gTm93LCBmaW5kIHRoZSBhbmNlc3RvciBvZiB0aGUgb3duaW5nIGVsZW1lbnQsIGlmIHRoZSBvcmlnaW5hbAotICAgICAgICAvLyBhbmNlc3RvciB3YXMgYW4gYXR0cmlidXRlCi0KLSAgICAgICAgLy8gTm90ZTogIHRoZSBmb2xsb3dpbmcgMiBsb29wcyBhcmUgcXVpdGUgY2xvc2UgdG8gdGhlIG9uZXMgYWJvdmUuCi0gICAgICAgIC8vIE1heSB3YW50IHRvIGNvbW1vbiB0aGVtIHVwLiAgTE0uCi0gICAgICAgIGlmICh0aGlzQW5jZXN0b3JUeXBlID09IE5vZGUuQVRUUklCVVRFX05PREUpIHsKLSAgICAgICAgICAgIHRoaXNEZXB0aD0wOwotICAgICAgICAgICAgZm9yIChub2RlPXRoaXNOb2RlOyBub2RlICE9IG51bGw7IG5vZGU9bm9kZS5nZXRQYXJlbnROb2RlKCkpIHsKLSAgICAgICAgICAgICAgICB0aGlzRGVwdGggKz0xOwotICAgICAgICAgICAgICAgIGlmIChub2RlID09IG90aGVyTm9kZSkKLSAgICAgICAgICAgICAgICAgIC8vIFRoZSBvdGhlciBub2RlIGlzIGFuIGFuY2VzdG9yIG9mIHRoZSBvd25pbmcgZWxlbWVudAotICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgcmV0dXJuIFRSRUVfUE9TSVRJT05fUFJFQ0VESU5HOwotICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHRoaXNBbmNlc3RvciA9IG5vZGU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBOb3csIGZpbmQgdGhlIGFuY2VzdG9yIG9mIHRoZSBvd25pbmcgZWxlbWVudCwgaWYgdGhlIG9yaWdpbmFsCi0gICAgICAgIC8vIGFuY2VzdG9yIHdhcyBhbiBhdHRyaWJ1dGUKLSAgICAgICAgaWYgKG90aGVyQW5jZXN0b3JUeXBlID09IE5vZGUuQVRUUklCVVRFX05PREUpIHsKLSAgICAgICAgICAgIG90aGVyRGVwdGg9MDsKLSAgICAgICAgICAgIGZvciAobm9kZT1vdGhlck5vZGU7IG5vZGUgIT0gbnVsbDsgbm9kZT1ub2RlLmdldFBhcmVudE5vZGUoKSkgewotICAgICAgICAgICAgICAgIG90aGVyRGVwdGggKz0xOwotICAgICAgICAgICAgICAgIGlmIChub2RlID09IHRoaXNOb2RlKQotICAgICAgICAgICAgICAgICAgLy8gVGhlIG90aGVyIG5vZGUgaXMgYSBkZXNjZW5kZW50IG9mIHRoZSByZWZlcmVuY2UKLSAgICAgICAgICAgICAgICAgIC8vIG5vZGUncyBlbGVtZW50Ci0gICAgICAgICAgICAgICAgICByZXR1cm4gVFJFRV9QT1NJVElPTl9GT0xMT1dJTkc7Ci0gICAgICAgICAgICAgICAgb3RoZXJBbmNlc3RvciA9IG5vZGU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyB0aGlzQW5jZXN0b3IgYW5kIG90aGVyQW5jZXN0b3IgbXVzdCBiZSB0aGUgc2FtZSBhdCB0aGlzIHBvaW50LAotICAgICAgICAvLyBvdGhlcndpc2UsIHdlIGFyZSBub3QgaW4gdGhlIHNhbWUgdHJlZSBvciBkb2N1bWVudCBmcmFnbWVudAotICAgICAgICBpZiAodGhpc0FuY2VzdG9yICE9IG90aGVyQW5jZXN0b3IpCi0gICAgICAgICAgcmV0dXJuIFRSRUVfUE9TSVRJT05fRElTQ09OTkVDVEVEOwotCi0KLSAgICAgICAgLy8gR28gdXAgdGhlIHBhcmVudCBjaGFpbiBvZiB0aGUgZGVlcGVyIG5vZGUsIHVudGlsIHdlIGZpbmQgYSBub2RlCi0gICAgICAgIC8vIHdpdGggdGhlIHNhbWUgZGVwdGggYXMgdGhlIHNoYWxsb3dlciBub2RlCi0KLSAgICAgICAgaWYgKHRoaXNEZXB0aCA+IG90aGVyRGVwdGgpIHsKLSAgICAgICAgICBmb3IgKGludCBpPTA7IGk8dGhpc0RlcHRoIC0gb3RoZXJEZXB0aDsgaSsrKQotICAgICAgICAgICAgdGhpc05vZGUgPSB0aGlzTm9kZS5nZXRQYXJlbnROb2RlKCk7Ci0gICAgICAgICAgLy8gQ2hlY2sgaWYgdGhlIG5vZGUgd2UgaGF2ZSByZWFjaGVkIGlzIGluIGZhY3QgIm90aGVyTm9kZSIuIFRoaXMgY2FuCi0gICAgICAgICAgLy8gaGFwcGVuIGluIHRoZSBjYXNlIG9mIGF0dHJpYnV0ZXMuICBJbiB0aGlzIGNhc2UsIG90aGVyTm9kZQotICAgICAgICAgIC8vICJwcmVjZWRlcyIgdGhpcy4KLSAgICAgICAgICBpZiAodGhpc05vZGUgPT0gb3RoZXJOb2RlKQotICAgICAgICAgICAgcmV0dXJuIFRSRUVfUE9TSVRJT05fUFJFQ0VESU5HOwotICAgICAgICB9Ci0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgZm9yIChpbnQgaT0wOyBpPG90aGVyRGVwdGggLSB0aGlzRGVwdGg7IGkrKykKLSAgICAgICAgICAgIG90aGVyTm9kZSA9IG90aGVyTm9kZS5nZXRQYXJlbnROb2RlKCk7Ci0gICAgICAgICAgLy8gQ2hlY2sgaWYgdGhlIG5vZGUgd2UgaGF2ZSByZWFjaGVkIGlzIGluIGZhY3QgInRoaXNOb2RlIi4gIFRoaXMgY2FuCi0gICAgICAgICAgLy8gaGFwcGVuIGluIHRoZSBjYXNlIG9mIGF0dHJpYnV0ZXMuICBJbiB0aGlzIGNhc2UsIG90aGVyTm9kZQotICAgICAgICAgIC8vICJmb2xsb3dzIiB0aGlzLgotICAgICAgICAgIGlmIChvdGhlck5vZGUgPT0gdGhpc05vZGUpCi0gICAgICAgICAgICByZXR1cm4gVFJFRV9QT1NJVElPTl9GT0xMT1dJTkc7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBXZSBub3cgaGF2ZSBub2RlcyBhdCB0aGUgc2FtZSBkZXB0aCBpbiB0aGUgdHJlZS4gIEZpbmQgYSBjb21tb24KLSAgICAgICAgLy8gYW5jZXN0b3IuCi0gICAgICAgIE5vZGUgdGhpc05vZGVQLCBvdGhlck5vZGVQOwotICAgICAgICBmb3IgKHRoaXNOb2RlUD10aGlzTm9kZS5nZXRQYXJlbnROb2RlKCksCi0gICAgICAgICAgICAgICAgICBvdGhlck5vZGVQPW90aGVyTm9kZS5nZXRQYXJlbnROb2RlKCk7Ci0gICAgICAgICAgICAgdGhpc05vZGVQIT1vdGhlck5vZGVQOykgewotICAgICAgICAgICAgIHRoaXNOb2RlID0gdGhpc05vZGVQOwotICAgICAgICAgICAgIG90aGVyTm9kZSA9IG90aGVyTm9kZVA7Ci0gICAgICAgICAgICAgdGhpc05vZGVQID0gdGhpc05vZGVQLmdldFBhcmVudE5vZGUoKTsKLSAgICAgICAgICAgICBvdGhlck5vZGVQID0gb3RoZXJOb2RlUC5nZXRQYXJlbnROb2RlKCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBBdCB0aGlzIHBvaW50LCB0aGlzTm9kZSBhbmQgb3RoZXJOb2RlIGFyZSBkaXJlY3QgY2hpbGRyZW4gb2YKLSAgICAgICAgLy8gdGhlIGNvbW1vbiBhbmNlc3Rvci4KLSAgICAgICAgLy8gU2VlIHdoZXRoZXIgdGhpc05vZGUgb3Igb3RoZXJOb2RlIGlzIHRoZSBsZWZ0bW9zdAotCi0gICAgICAgIGZvciAoTm9kZSBjdXJyZW50PXRoaXNOb2RlUC5nZXRGaXJzdENoaWxkKCk7Ci0gICAgICAgICAgICAgICAgICBjdXJyZW50IT1udWxsOwotICAgICAgICAgICAgICAgICAgY3VycmVudD1jdXJyZW50LmdldE5leHRTaWJsaW5nKCkpIHsKLSAgICAgICAgICAgICAgIGlmIChjdXJyZW50PT1vdGhlck5vZGUpIHsKLSAgICAgICAgICAgICAgICAgcmV0dXJuIFRSRUVfUE9TSVRJT05fUFJFQ0VESU5HOwotICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgZWxzZSBpZiAoY3VycmVudD09dGhpc05vZGUpIHsKLSAgICAgICAgICAgICAgICAgcmV0dXJuIFRSRUVfUE9TSVRJT05fRk9MTE9XSU5HOwotICAgICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIC8vIFJFVklTSVQ6ICBzaG91bGRuJ3QgZ2V0IGhlcmUuICAgU2hvdWxkIHByb2JhYmx5IHRocm93IGFuCi0gICAgICAgIC8vIGV4Y2VwdGlvbgotICAgICAgICByZXR1cm4gMDsKLQotICAgIH0KLSAgICAvKioKLSAgICAgKiBDb21wYXJlcyBhIG5vZGUgd2l0aCB0aGlzIG5vZGUgd2l0aCByZWdhcmQgdG8gdGhlaXIgcG9zaXRpb24gaW4gdGhlCi0gICAgICogZG9jdW1lbnQuCi0gICAgICogQHBhcmFtIG90aGVyIFRoZSBub2RlIHRvIGNvbXBhcmUgYWdhaW5zdCB0aGlzIG5vZGUuCi0gICAgICogQHJldHVybiBSZXR1cm5zIGhvdyB0aGUgZ2l2ZW4gbm9kZSBpcyBwb3NpdGlvbmVkIHJlbGF0aXZlbHkgdG8gdGhpcwotICAgICAqICAgbm9kZS4KLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICAgKi8KLSAgICBwdWJsaWMgc2hvcnQgY29tcGFyZURvY3VtZW50UG9zaXRpb24oTm9kZSBvdGhlcikgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy8gSWYgdGhlIG5vZGVzIGFyZSB0aGUgc2FtZSwgbm8gZmxhZ3Mgc2hvdWxkIGJlIHNldAotICAgICAgICBpZiAodGhpcz09b3RoZXIpCi0gICAgICAgICAgcmV0dXJuIDA7Ci0KLSAgICAgICAgLy8gY2hlY2sgaWYgb3RoZXIgaXMgZnJvbSBhIGRpZmZlcmVudCBpbXBsZW1lbnRhdGlvbgotICAgICAgICB0cnkgewotICAgICAgICAgICAgTm9kZUltcGwgbm9kZSA9IChOb2RlSW1wbCkgb3RoZXI7Ci0gICAgICAgIH0gY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAvLyBvdGhlciBjb21lcyBmcm9tIGEgZGlmZmVyZW50IGltcGxlbWVudGF0aW9uCi0gICAgICAgICAgICBTdHJpbmcgbXNnID0gRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKAotICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiTk9UX1NVUFBPUlRFRF9FUlIiLCBudWxsKTsKLSAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSLCBtc2cpOwotICAgICAgICB9Ci0KLSAgICAgICAgRG9jdW1lbnQgdGhpc093bmVyRG9jLCBvdGhlck93bmVyRG9jOwotICAgICAgICAvLyBnZXQgdGhlIHJlc3BlY3RpdmUgRG9jdW1lbnQgb3duZXJzLgotICAgICAgICBpZiAodGhpcy5nZXROb2RlVHlwZSgpID09IE5vZGUuRE9DVU1FTlRfTk9ERSkKLSAgICAgICAgICB0aGlzT3duZXJEb2MgPSAoRG9jdW1lbnQpdGhpczsKLSAgICAgICAgZWxzZQotICAgICAgICAgIHRoaXNPd25lckRvYyA9IHRoaXMuZ2V0T3duZXJEb2N1bWVudCgpOwotICAgICAgICBpZiAob3RoZXIuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLkRPQ1VNRU5UX05PREUpCi0gICAgICAgICAgb3RoZXJPd25lckRvYyA9IChEb2N1bWVudClvdGhlcjsKLSAgICAgICAgZWxzZQotICAgICAgICAgIG90aGVyT3duZXJEb2MgPSBvdGhlci5nZXRPd25lckRvY3VtZW50KCk7Ci0KLSAgICAgICAgLy8gSWYgZnJvbSBkaWZmZXJlbnQgZG9jdW1lbnRzLCB3ZSBrbm93IHRoZXkgYXJlIGRpc2Nvbm5lY3RlZC4KLSAgICAgICAgLy8gYW5kIGhhdmUgYW4gaW1wbGVtZW50YXRpb24gZGVwZW5kZW50IG9yZGVyCi0gICAgICAgIGlmICh0aGlzT3duZXJEb2MgIT0gb3RoZXJPd25lckRvYyAmJgotICAgICAgICAgICAgdGhpc093bmVyRG9jICE9bnVsbCAmJgotICAgICAgICAgICAgb3RoZXJPd25lckRvYyAhPW51bGwpCi0gewotICAgICAgICAgIGludCBvdGhlckRvY051bSA9ICgoQ29yZURvY3VtZW50SW1wbClvdGhlck93bmVyRG9jKS5nZXROb2RlTnVtYmVyKCk7Ci0gICAgICAgICAgaW50IHRoaXNEb2NOdW0gPSAoKENvcmVEb2N1bWVudEltcGwpdGhpc093bmVyRG9jKS5nZXROb2RlTnVtYmVyKCk7Ci0gICAgICAgICAgaWYgKG90aGVyRG9jTnVtID4gdGhpc0RvY051bSkKLSAgICAgICAgICAgIHJldHVybiBET0NVTUVOVF9QT1NJVElPTl9ESVNDT05ORUNURUQgfAotICAgICAgICAgICAgICAgICAgIERPQ1VNRU5UX1BPU0lUSU9OX0ZPTExPV0lORyB8Ci0gICAgICAgICAgICAgICAgICAgRE9DVU1FTlRfUE9TSVRJT05fSU1QTEVNRU5UQVRJT05fU1BFQ0lGSUM7Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgICAgcmV0dXJuIERPQ1VNRU5UX1BPU0lUSU9OX0RJU0NPTk5FQ1RFRCB8Ci0gICAgICAgICAgICAgICAgICAgRE9DVU1FTlRfUE9TSVRJT05fUFJFQ0VESU5HIHwKLSAgICAgICAgICAgICAgICAgICBET0NVTUVOVF9QT1NJVElPTl9JTVBMRU1FTlRBVElPTl9TUEVDSUZJQzsKLQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gRmluZCB0aGUgYW5jZXN0b3Igb2YgZWFjaCBub2RlLCBhbmQgdGhlIGRpc3RhbmNlIGVhY2ggbm9kZSBpcyBmcm9tCi0gICAgICAgIC8vIGl0cyBhbmNlc3Rvci4KLSAgICAgICAgLy8gRHVyaW5nIHRoaXMgdHJhdmVyc2FsLCBsb29rIGZvciBhbmNlc3Rvci9kZXNjZW5kZW50IHJlbGF0aW9uc2hpcHMKLSAgICAgICAgLy8gYmV0d2VlbiB0aGUgMiBub2RlcyBpbiBxdWVzdGlvbi4KLSAgICAgICAgLy8gV2UgZG8gdGhpcyBub3csIHNvIHRoYXQgd2UgZ2V0IHRoaXMgaW5mbyBjb3JyZWN0IGZvciBhdHRyaWJ1dGUgbm9kZXMKLSAgICAgICAgLy8gYW5kIHRoZWlyIGNoaWxkcmVuLgotCi0gICAgICAgIE5vZGUgbm9kZTsKLSAgICAgICAgTm9kZSB0aGlzQW5jZXN0b3IgPSB0aGlzOwotICAgICAgICBOb2RlIG90aGVyQW5jZXN0b3IgPSBvdGhlcjsKLQotICAgICAgICBpbnQgdGhpc0RlcHRoPTA7Ci0gICAgICAgIGludCBvdGhlckRlcHRoPTA7Ci0gICAgICAgIGZvciAobm9kZT10aGlzOyBub2RlICE9IG51bGw7IG5vZGUgPSBub2RlLmdldFBhcmVudE5vZGUoKSkgewotICAgICAgICAgICAgdGhpc0RlcHRoICs9MTsKLSAgICAgICAgICAgIGlmIChub2RlID09IG90aGVyKQotICAgICAgICAgICAgICAvLyBUaGUgb3RoZXIgbm9kZSBpcyBhbiBhbmNlc3RvciBvZiB0aGlzIG9uZS4KLSAgICAgICAgICAgICAgcmV0dXJuIChET0NVTUVOVF9QT1NJVElPTl9DT05UQUlOUyB8Ci0gICAgICAgICAgICAgICAgICAgICAgRE9DVU1FTlRfUE9TSVRJT05fUFJFQ0VESU5HKTsKLSAgICAgICAgICAgIHRoaXNBbmNlc3RvciA9IG5vZGU7Ci0gICAgICAgIH0KLQotICAgICAgICBmb3IgKG5vZGU9b3RoZXI7IG5vZGUhPW51bGw7IG5vZGU9bm9kZS5nZXRQYXJlbnROb2RlKCkpIHsKLSAgICAgICAgICAgIG90aGVyRGVwdGggKz0xOwotICAgICAgICAgICAgaWYgKG5vZGUgPT0gdGhpcykKLSAgICAgICAgICAgICAgLy8gVGhlIG90aGVyIG5vZGUgaXMgYSBkZXNjZW5kZW50IG9mIHRoZSByZWZlcmVuY2Ugbm9kZS4KLSAgICAgICAgICAgICAgcmV0dXJuIChET0NVTUVOVF9QT1NJVElPTl9JU19DT05UQUlORUQgfAotICAgICAgICAgICAgICAgICAgICAgIERPQ1VNRU5UX1BPU0lUSU9OX0ZPTExPV0lORyk7Ci0gICAgICAgICAgICBvdGhlckFuY2VzdG9yID0gbm9kZTsKLSAgICAgICAgfQotCi0KLQotICAgICAgICBpbnQgdGhpc0FuY2VzdG9yVHlwZSA9IHRoaXNBbmNlc3Rvci5nZXROb2RlVHlwZSgpOwotICAgICAgICBpbnQgb3RoZXJBbmNlc3RvclR5cGUgPSBvdGhlckFuY2VzdG9yLmdldE5vZGVUeXBlKCk7Ci0gICAgICAgIE5vZGUgdGhpc05vZGUgPSB0aGlzOwotICAgICAgICBOb2RlIG90aGVyTm9kZSA9IG90aGVyOwotCi0gICAgICAgIC8vIFNwZWNpYWwgY2FzaW5nIGZvciBFTlRJVFksIE5PVEFUSU9OLCBET0NUWVBFIGFuZCBBVFRSSUJVVEVTCi0gICAgICAgIC8vIExNOiAgc2hvdWxkIHJld3JpdGUgdGhpcy4KLSAgICAgICAgc3dpdGNoICh0aGlzQW5jZXN0b3JUeXBlKSB7Ci0gICAgICAgICAgY2FzZSBOb2RlLk5PVEFUSU9OX05PREU6Ci0gICAgICAgICAgY2FzZSBOb2RlLkVOVElUWV9OT0RFOiB7Ci0gICAgICAgICAgICBEb2N1bWVudFR5cGUgY29udGFpbmVyID0gdGhpc093bmVyRG9jLmdldERvY3R5cGUoKTsKLSAgICAgICAgICAgIGlmIChjb250YWluZXIgPT0gb3RoZXJBbmNlc3RvcikgcmV0dXJuCi0gICAgICAgICAgICAgICAgICAgKERPQ1VNRU5UX1BPU0lUSU9OX0NPTlRBSU5TIHwgRE9DVU1FTlRfUE9TSVRJT05fUFJFQ0VESU5HKTsKLSAgICAgICAgICAgIHN3aXRjaCAob3RoZXJBbmNlc3RvclR5cGUpIHsKLSAgICAgICAgICAgICAgY2FzZSBOb2RlLk5PVEFUSU9OX05PREU6Ci0gICAgICAgICAgICAgIGNhc2UgTm9kZS5FTlRJVFlfTk9ERTogIHsKLSAgICAgICAgICAgICAgICBpZiAodGhpc0FuY2VzdG9yVHlwZSAhPSBvdGhlckFuY2VzdG9yVHlwZSkKLSAgICAgICAgICAgICAgICAgLy8gdGhlIG5vZGVzIGFyZSBvZiBkaWZmZXJlbnQgdHlwZXMKLSAgICAgICAgICAgICAgICAgcmV0dXJuICgodGhpc0FuY2VzdG9yVHlwZT5vdGhlckFuY2VzdG9yVHlwZSkgPwotICAgICAgICAgICAgICAgICAgICBET0NVTUVOVF9QT1NJVElPTl9QUkVDRURJTkc6RE9DVU1FTlRfUE9TSVRJT05fRk9MTE9XSU5HKTsKLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgLy8gdGhlIG5vZGVzIGFyZSBvZiB0aGUgc2FtZSB0eXBlLiAgRmluZCBvcmRlci4KLSAgICAgICAgICAgICAgICAgaWYgKHRoaXNBbmNlc3RvclR5cGUgPT0gTm9kZS5OT1RBVElPTl9OT0RFKQotCi0gICAgICAgICAgICAgICAgICAgICBpZiAoKChOYW1lZE5vZGVNYXBJbXBsKWNvbnRhaW5lci5nZXROb3RhdGlvbnMoKSkucHJlY2VkZXMob3RoZXJBbmNlc3Rvcix0aGlzQW5jZXN0b3IpKQotICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKERPQ1VNRU5UX1BPU0lUSU9OX1BSRUNFRElORyB8Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRE9DVU1FTlRfUE9TSVRJT05fSU1QTEVNRU5UQVRJT05fU1BFQ0lGSUMpOwotICAgICAgICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKERPQ1VNRU5UX1BPU0lUSU9OX0ZPTExPV0lORyB8Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRE9DVU1FTlRfUE9TSVRJT05fSU1QTEVNRU5UQVRJT05fU1BFQ0lGSUMpOwotICAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgICBpZiAoKChOYW1lZE5vZGVNYXBJbXBsKWNvbnRhaW5lci5nZXRFbnRpdGllcygpKS5wcmVjZWRlcyhvdGhlckFuY2VzdG9yLHRoaXNBbmNlc3RvcikpCi0gICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoRE9DVU1FTlRfUE9TSVRJT05fUFJFQ0VESU5HIHwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBET0NVTUVOVF9QT1NJVElPTl9JTVBMRU1FTlRBVElPTl9TUEVDSUZJQyk7Ci0gICAgICAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoRE9DVU1FTlRfUE9TSVRJT05fRk9MTE9XSU5HIHwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBET0NVTUVOVF9QT1NJVElPTl9JTVBMRU1FTlRBVElPTl9TUEVDSUZJQyk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICB0aGlzTm9kZSA9IHRoaXNBbmNlc3RvciA9IHRoaXNPd25lckRvYzsKLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgIH0KLSAgICAgICAgICBjYXNlIE5vZGUuRE9DVU1FTlRfVFlQRV9OT0RFOiB7Ci0gICAgICAgICAgICBpZiAob3RoZXJOb2RlID09IHRoaXNPd25lckRvYykKLSAgICAgICAgICAgICAgcmV0dXJuIChET0NVTUVOVF9QT1NJVElPTl9QUkVDRURJTkcgfAotICAgICAgICAgICAgICAgICAgICAgIERPQ1VNRU5UX1BPU0lUSU9OX0NPTlRBSU5TKTsKLSAgICAgICAgICAgIGVsc2UgaWYgKHRoaXNPd25lckRvYyE9bnVsbCAmJiB0aGlzT3duZXJEb2M9PW90aGVyT3duZXJEb2MpCi0gICAgICAgICAgICAgIHJldHVybiAoRE9DVU1FTlRfUE9TSVRJT05fRk9MTE9XSU5HKTsKLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgIH0KLSAgICAgICAgICBjYXNlIE5vZGUuQVRUUklCVVRFX05PREU6IHsKLSAgICAgICAgICAgIHRoaXNOb2RlID0gKChBdHRySW1wbCl0aGlzQW5jZXN0b3IpLmdldE93bmVyRWxlbWVudCgpOwotICAgICAgICAgICAgaWYgKG90aGVyQW5jZXN0b3JUeXBlPT1Ob2RlLkFUVFJJQlVURV9OT0RFKSB7Ci0gICAgICAgICAgICAgIG90aGVyTm9kZSA9ICgoQXR0ckltcGwpb3RoZXJBbmNlc3RvcikuZ2V0T3duZXJFbGVtZW50KCk7Ci0gICAgICAgICAgICAgIGlmIChvdGhlck5vZGUgPT0gdGhpc05vZGUpIHsKLSAgICAgICAgICAgICAgICBpZiAoKChOYW1lZE5vZGVNYXBJbXBsKXRoaXNOb2RlLmdldEF0dHJpYnV0ZXMoKSkucHJlY2VkZXMob3RoZXIsdGhpcykpCi0gICAgICAgICAgICAgICAgICByZXR1cm4gKERPQ1VNRU5UX1BPU0lUSU9OX1BSRUNFRElORyB8Ci0gICAgICAgICAgICAgICAgICAgICAgICAgIERPQ1VNRU5UX1BPU0lUSU9OX0lNUExFTUVOVEFUSU9OX1NQRUNJRklDKTsKLSAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICByZXR1cm4gKERPQ1VNRU5UX1BPU0lUSU9OX0ZPTExPV0lORyB8Ci0gICAgICAgICAgICAgICAgICAgICAgICAgIERPQ1VNRU5UX1BPU0lUSU9OX0lNUExFTUVOVEFUSU9OX1NQRUNJRklDKTsKLSAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBOb3csIGZpbmQgdGhlIGFuY2VzdG9yIG9mIHRoZSBlbGVtZW50Ci0gICAgICAgICAgICB0aGlzRGVwdGg9MDsKLSAgICAgICAgICAgIGZvciAobm9kZT10aGlzTm9kZTsgbm9kZSAhPSBudWxsOyBub2RlPW5vZGUuZ2V0UGFyZW50Tm9kZSgpKSB7Ci0gICAgICAgICAgICAgICAgdGhpc0RlcHRoICs9MTsKLSAgICAgICAgICAgICAgICBpZiAobm9kZSA9PSBvdGhlck5vZGUpCi0gICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAvLyBUaGUgb3RoZXIgbm9kZSBpcyBhbiBhbmNlc3RvciBvZiB0aGUgb3duaW5nIGVsZW1lbnQKLSAgICAgICAgICAgICAgICAgIHJldHVybiAoRE9DVU1FTlRfUE9TSVRJT05fQ09OVEFJTlMgfAotICAgICAgICAgICAgICAgICAgICAgICAgICBET0NVTUVOVF9QT1NJVElPTl9QUkVDRURJTkcpOwotICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHRoaXNBbmNlc3RvciA9IG5vZGU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHN3aXRjaCAob3RoZXJBbmNlc3RvclR5cGUpIHsKLSAgICAgICAgICBjYXNlIE5vZGUuTk9UQVRJT05fTk9ERToKLSAgICAgICAgICBjYXNlIE5vZGUuRU5USVRZX05PREU6IHsKLSAgICAgICAgICBEb2N1bWVudFR5cGUgY29udGFpbmVyID0gdGhpc093bmVyRG9jLmdldERvY3R5cGUoKTsKLSAgICAgICAgICAgIGlmIChjb250YWluZXIgPT0gdGhpcykgcmV0dXJuIChET0NVTUVOVF9QT1NJVElPTl9JU19DT05UQUlORUQgfAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRE9DVU1FTlRfUE9TSVRJT05fRk9MTE9XSU5HKTsKLSAgICAgICAgICAgIG90aGVyTm9kZSA9IG90aGVyQW5jZXN0b3IgPSB0aGlzT3duZXJEb2M7Ci0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgICB9Ci0gICAgICAgICAgY2FzZSBOb2RlLkRPQ1VNRU5UX1RZUEVfTk9ERTogewotICAgICAgICAgICAgaWYgKHRoaXNOb2RlID09IG90aGVyT3duZXJEb2MpCi0gICAgICAgICAgICAgIHJldHVybiAoRE9DVU1FTlRfUE9TSVRJT05fRk9MTE9XSU5HIHwKLSAgICAgICAgICAgICAgICAgICAgICBET0NVTUVOVF9QT1NJVElPTl9JU19DT05UQUlORUQpOwotICAgICAgICAgICAgZWxzZSBpZiAob3RoZXJPd25lckRvYyE9bnVsbCAmJiB0aGlzT3duZXJEb2M9PW90aGVyT3duZXJEb2MpCi0gICAgICAgICAgICAgIHJldHVybiAoRE9DVU1FTlRfUE9TSVRJT05fUFJFQ0VESU5HKTsKLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgIH0KLSAgICAgICAgICBjYXNlIE5vZGUuQVRUUklCVVRFX05PREU6IHsKLSAgICAgICAgICAgIG90aGVyRGVwdGg9MDsKLSAgICAgICAgICAgIG90aGVyTm9kZSA9ICgoQXR0ckltcGwpb3RoZXJBbmNlc3RvcikuZ2V0T3duZXJFbGVtZW50KCk7Ci0gICAgICAgICAgICBmb3IgKG5vZGU9b3RoZXJOb2RlOyBub2RlICE9IG51bGw7IG5vZGU9bm9kZS5nZXRQYXJlbnROb2RlKCkpIHsKLSAgICAgICAgICAgICAgICBvdGhlckRlcHRoICs9MTsKLSAgICAgICAgICAgICAgICBpZiAobm9kZSA9PSB0aGlzTm9kZSkKLSAgICAgICAgICAgICAgICAgIC8vIFRoZSBvdGhlciBub2RlIGlzIGEgZGVzY2VuZGVudCBvZiB0aGUgcmVmZXJlbmNlCi0gICAgICAgICAgICAgICAgICAvLyBub2RlJ3MgZWxlbWVudAotICAgICAgICAgICAgICAgICAgcmV0dXJuIERPQ1VNRU5UX1BPU0lUSU9OX0ZPTExPV0lORyB8Ci0gICAgICAgICAgICAgICAgICAgICAgICAgRE9DVU1FTlRfUE9TSVRJT05fSVNfQ09OVEFJTkVEOwotICAgICAgICAgICAgICAgIG90aGVyQW5jZXN0b3IgPSBub2RlOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gdGhpc0FuY2VzdG9yIGFuZCBvdGhlckFuY2VzdG9yIG11c3QgYmUgdGhlIHNhbWUgYXQgdGhpcyBwb2ludCwKLSAgICAgICAgLy8gb3RoZXJ3aXNlLCB0aGUgb3JpZ2luYWwgbm9kZXMgYXJlIGRpc2Nvbm5lY3RlZAotICAgICAgICBpZiAodGhpc0FuY2VzdG9yICE9IG90aGVyQW5jZXN0b3IpIHsKLSAgICAgICAgICBpbnQgdGhpc0FuY2VzdG9yTnVtLCBvdGhlckFuY2VzdG9yTnVtOwotICAgICAgICAgIHRoaXNBbmNlc3Rvck51bSA9ICgoTm9kZUltcGwpdGhpc0FuY2VzdG9yKS5nZXROb2RlTnVtYmVyKCk7Ci0gICAgICAgICAgb3RoZXJBbmNlc3Rvck51bSA9ICgoTm9kZUltcGwpb3RoZXJBbmNlc3RvcikuZ2V0Tm9kZU51bWJlcigpOwotCi0gICAgICAgICAgaWYgKHRoaXNBbmNlc3Rvck51bSA+IG90aGVyQW5jZXN0b3JOdW0pCi0gICAgICAgICAgICByZXR1cm4gRE9DVU1FTlRfUE9TSVRJT05fRElTQ09OTkVDVEVEIHwKLSAgICAgICAgICAgICAgICAgICBET0NVTUVOVF9QT1NJVElPTl9GT0xMT1dJTkcgfAotICAgICAgICAgICAgICAgICAgIERPQ1VNRU5UX1BPU0lUSU9OX0lNUExFTUVOVEFUSU9OX1NQRUNJRklDOwotICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgIHJldHVybiBET0NVTUVOVF9QT1NJVElPTl9ESVNDT05ORUNURUQgfAotICAgICAgICAgICAgICAgICAgIERPQ1VNRU5UX1BPU0lUSU9OX1BSRUNFRElORyB8Ci0gICAgICAgICAgICAgICAgICAgRE9DVU1FTlRfUE9TSVRJT05fSU1QTEVNRU5UQVRJT05fU1BFQ0lGSUM7Ci0gICAgICAgIH0KLQotCi0gICAgICAgIC8vIEdvIHVwIHRoZSBwYXJlbnQgY2hhaW4gb2YgdGhlIGRlZXBlciBub2RlLCB1bnRpbCB3ZSBmaW5kIGEgbm9kZQotICAgICAgICAvLyB3aXRoIHRoZSBzYW1lIGRlcHRoIGFzIHRoZSBzaGFsbG93ZXIgbm9kZQotCi0gICAgICAgIGlmICh0aGlzRGVwdGggPiBvdGhlckRlcHRoKSB7Ci0gICAgICAgICAgZm9yIChpbnQgaT0wOyBpPHRoaXNEZXB0aCAtIG90aGVyRGVwdGg7IGkrKykKLSAgICAgICAgICAgIHRoaXNOb2RlID0gdGhpc05vZGUuZ2V0UGFyZW50Tm9kZSgpOwotICAgICAgICAgIC8vIENoZWNrIGlmIHRoZSBub2RlIHdlIGhhdmUgcmVhY2hlZCBpcyBpbiBmYWN0ICJvdGhlck5vZGUiLiBUaGlzIGNhbgotICAgICAgICAgIC8vIGhhcHBlbiBpbiB0aGUgY2FzZSBvZiBhdHRyaWJ1dGVzLiAgSW4gdGhpcyBjYXNlLCBvdGhlck5vZGUKLSAgICAgICAgICAvLyAicHJlY2VkZXMiIHRoaXMuCi0gICAgICAgICAgaWYgKHRoaXNOb2RlID09IG90aGVyTm9kZSkKLXsKLSAgICAgICAgICAgIHJldHVybiBET0NVTUVOVF9QT1NJVElPTl9QUkVDRURJTkc7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgZm9yIChpbnQgaT0wOyBpPG90aGVyRGVwdGggLSB0aGlzRGVwdGg7IGkrKykKLSAgICAgICAgICAgIG90aGVyTm9kZSA9IG90aGVyTm9kZS5nZXRQYXJlbnROb2RlKCk7Ci0gICAgICAgICAgLy8gQ2hlY2sgaWYgdGhlIG5vZGUgd2UgaGF2ZSByZWFjaGVkIGlzIGluIGZhY3QgInRoaXNOb2RlIi4gIFRoaXMgY2FuCi0gICAgICAgICAgLy8gaGFwcGVuIGluIHRoZSBjYXNlIG9mIGF0dHJpYnV0ZXMuICBJbiB0aGlzIGNhc2UsIG90aGVyTm9kZQotICAgICAgICAgIC8vICJmb2xsb3dzIiB0aGlzLgotICAgICAgICAgIGlmIChvdGhlck5vZGUgPT0gdGhpc05vZGUpCi0gICAgICAgICAgICByZXR1cm4gRE9DVU1FTlRfUE9TSVRJT05fRk9MTE9XSU5HOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gV2Ugbm93IGhhdmUgbm9kZXMgYXQgdGhlIHNhbWUgZGVwdGggaW4gdGhlIHRyZWUuICBGaW5kIGEgY29tbW9uCi0gICAgICAgIC8vIGFuY2VzdG9yLgotICAgICAgICBOb2RlIHRoaXNOb2RlUCwgb3RoZXJOb2RlUDsKLSAgICAgICAgZm9yICh0aGlzTm9kZVA9dGhpc05vZGUuZ2V0UGFyZW50Tm9kZSgpLAotICAgICAgICAgICAgICAgICAgb3RoZXJOb2RlUD1vdGhlck5vZGUuZ2V0UGFyZW50Tm9kZSgpOwotICAgICAgICAgICAgIHRoaXNOb2RlUCE9b3RoZXJOb2RlUDspIHsKLSAgICAgICAgICAgICB0aGlzTm9kZSA9IHRoaXNOb2RlUDsKLSAgICAgICAgICAgICBvdGhlck5vZGUgPSBvdGhlck5vZGVQOwotICAgICAgICAgICAgIHRoaXNOb2RlUCA9IHRoaXNOb2RlUC5nZXRQYXJlbnROb2RlKCk7Ci0gICAgICAgICAgICAgb3RoZXJOb2RlUCA9IG90aGVyTm9kZVAuZ2V0UGFyZW50Tm9kZSgpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gQXQgdGhpcyBwb2ludCwgdGhpc05vZGUgYW5kIG90aGVyTm9kZSBhcmUgZGlyZWN0IGNoaWxkcmVuIG9mCi0gICAgICAgIC8vIHRoZSBjb21tb24gYW5jZXN0b3IuCi0gICAgICAgIC8vIFNlZSB3aGV0aGVyIHRoaXNOb2RlIG9yIG90aGVyTm9kZSBpcyB0aGUgbGVmdG1vc3QKLQotICAgICAgICBmb3IgKE5vZGUgY3VycmVudD10aGlzTm9kZVAuZ2V0Rmlyc3RDaGlsZCgpOwotICAgICAgICAgICAgICAgICAgY3VycmVudCE9bnVsbDsKLSAgICAgICAgICAgICAgICAgIGN1cnJlbnQ9Y3VycmVudC5nZXROZXh0U2libGluZygpKSB7Ci0gICAgICAgICAgICAgICBpZiAoY3VycmVudD09b3RoZXJOb2RlKSB7Ci0gICAgICAgICAgICAgICAgIHJldHVybiBET0NVTUVOVF9QT1NJVElPTl9QUkVDRURJTkc7Ci0gICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICBlbHNlIGlmIChjdXJyZW50PT10aGlzTm9kZSkgewotICAgICAgICAgICAgICAgICByZXR1cm4gRE9DVU1FTlRfUE9TSVRJT05fRk9MTE9XSU5HOwotICAgICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIC8vIFJFVklTSVQ6ICBzaG91bGRuJ3QgZ2V0IGhlcmUuICAgU2hvdWxkIHByb2JhYmx5IHRocm93IGFuCi0gICAgICAgIC8vIGV4Y2VwdGlvbgotICAgICAgICByZXR1cm4gMDsKLQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgYXR0cmlidXRlIHJldHVybnMgdGhlIHRleHQgY29udGVudCBvZiB0aGlzIG5vZGUgYW5kIGl0cwotICAgICAqIGRlc2NlbmRhbnRzLiBXaGVuIGl0IGlzIGRlZmluZWQgdG8gYmUgbnVsbCwgc2V0dGluZyBpdCBoYXMgbm8gZWZmZWN0LgotICAgICAqIFdoZW4gc2V0LCBhbnkgcG9zc2libGUgY2hpbGRyZW4gdGhpcyBub2RlIG1heSBoYXZlIGFyZSByZW1vdmVkIGFuZAotICAgICAqIHJlcGxhY2VkIGJ5IGEgc2luZ2xlIDxjb2RlPlRleHQ8L2NvZGU+IG5vZGUgY29udGFpbmluZyB0aGUgc3RyaW5nCi0gICAgICogdGhpcyBhdHRyaWJ1dGUgaXMgc2V0IHRvLiBPbiBnZXR0aW5nLCBubyBzZXJpYWxpemF0aW9uIGlzIHBlcmZvcm1lZCwKLSAgICAgKiB0aGUgcmV0dXJuZWQgc3RyaW5nIGRvZXMgbm90IGNvbnRhaW4gYW55IG1hcmt1cC4gTm8gd2hpdGVzcGFjZQotICAgICAqIG5vcm1hbGl6YXRpb24gaXMgcGVyZm9ybWVkLCB0aGUgcmV0dXJuZWQgc3RyaW5nIGRvZXMgbm90IGNvbnRhaW4gdGhlCi0gICAgICogZWxlbWVudCBjb250ZW50IHdoaXRlc3BhY2VzIC4gU2ltaWxhcmx5LCBvbiBzZXR0aW5nLCBubyBwYXJzaW5nIGlzCi0gICAgICogcGVyZm9ybWVkIGVpdGhlciwgdGhlIGlucHV0IHN0cmluZyBpcyB0YWtlbiBhcyBwdXJlIHRleHR1YWwgY29udGVudC4KLSAgICAgKiA8YnI+VGhlIHN0cmluZyByZXR1cm5lZCBpcyBtYWRlIG9mIHRoZSB0ZXh0IGNvbnRlbnQgb2YgdGhpcyBub2RlCi0gICAgICogZGVwZW5kaW5nIG9uIGl0cyB0eXBlLCBhcyBkZWZpbmVkIGJlbG93OgotICAgICAqIDx0YWJsZSBib3JkZXI9JzEnPgotICAgICAqIDx0cj4KLSAgICAgKiA8dGg+Tm9kZSB0eXBlPC90aD4KLSAgICAgKiA8dGg+Q29udGVudDwvdGg+Ci0gICAgICogPC90cj4KLQotICAgIC8qKgotICAgICAqIFRoaXMgYXR0cmlidXRlIHJldHVybnMgdGhlIHRleHQgY29udGVudCBvZiB0aGlzIG5vZGUgYW5kIGl0cwotICAgICAqIGRlc2NlbmRhbnRzLiBXaGVuIGl0IGlzIGRlZmluZWQgdG8gYmUgbnVsbCwgc2V0dGluZyBpdCBoYXMgbm8gZWZmZWN0LgotICAgICAqIFdoZW4gc2V0LCBhbnkgcG9zc2libGUgY2hpbGRyZW4gdGhpcyBub2RlIG1heSBoYXZlIGFyZSByZW1vdmVkIGFuZAotICAgICAqIHJlcGxhY2VkIGJ5IGEgc2luZ2xlIDxjb2RlPlRleHQ8L2NvZGU+IG5vZGUgY29udGFpbmluZyB0aGUgc3RyaW5nCi0gICAgICogdGhpcyBhdHRyaWJ1dGUgaXMgc2V0IHRvLiBPbiBnZXR0aW5nLCBubyBzZXJpYWxpemF0aW9uIGlzIHBlcmZvcm1lZCwKLSAgICAgKiB0aGUgcmV0dXJuZWQgc3RyaW5nIGRvZXMgbm90IGNvbnRhaW4gYW55IG1hcmt1cC4gTm8gd2hpdGVzcGFjZQotICAgICAqIG5vcm1hbGl6YXRpb24gaXMgcGVyZm9ybWVkLCB0aGUgcmV0dXJuZWQgc3RyaW5nIGRvZXMgbm90IGNvbnRhaW4gdGhlCi0gICAgICogZWxlbWVudCBjb250ZW50IHdoaXRlc3BhY2VzIC4gU2ltaWxhcmx5LCBvbiBzZXR0aW5nLCBubyBwYXJzaW5nIGlzCi0gICAgICogcGVyZm9ybWVkIGVpdGhlciwgdGhlIGlucHV0IHN0cmluZyBpcyB0YWtlbiBhcyBwdXJlIHRleHR1YWwgY29udGVudC4KLSAgICAgKiA8YnI+VGhlIHN0cmluZyByZXR1cm5lZCBpcyBtYWRlIG9mIHRoZSB0ZXh0IGNvbnRlbnQgb2YgdGhpcyBub2RlCi0gICAgICogZGVwZW5kaW5nIG9uIGl0cyB0eXBlLCBhcyBkZWZpbmVkIGJlbG93OgotICAgICAqIDx0YWJsZSBib3JkZXI9JzEnPgotICAgICAqIDx0cj4KLSAgICAgKiA8dGg+Tm9kZSB0eXBlPC90aD4KLSAgICAgKiA8dGg+Q29udGVudDwvdGg+Ci0gICAgICogPC90cj4KLSAgICAgKiA8dHI+Ci0gICAgICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz4KLSAgICAgKiBFTEVNRU5UX05PREUsIEVOVElUWV9OT0RFLCBFTlRJVFlfUkVGRVJFTkNFX05PREUsCi0gICAgICogRE9DVU1FTlRfRlJBR01FTlRfTk9ERTwvdGQ+Ci0gICAgICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz5jb25jYXRlbmF0aW9uIG9mIHRoZSA8Y29kZT50ZXh0Q29udGVudDwvY29kZT4KLSAgICAgKiBhdHRyaWJ1dGUgdmFsdWUgb2YgZXZlcnkgY2hpbGQgbm9kZSwgZXhjbHVkaW5nIENPTU1FTlRfTk9ERSBhbmQKLSAgICAgKiBQUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREUgbm9kZXM8L3RkPgotICAgICAqIDwvdHI+Ci0gICAgICogPHRyPgotICAgICAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+QVRUUklCVVRFX05PREUsIFRFWFRfTk9ERSwKLSAgICAgKiBDREFUQV9TRUNUSU9OX05PREUsIENPTU1FTlRfTk9ERSwgUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFPC90ZD4KLSAgICAgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPgotICAgICAqIDxjb2RlPm5vZGVWYWx1ZTwvY29kZT48L3RkPgotICAgICAqIDwvdHI+Ci0gICAgICogPHRyPgotICAgICAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+RE9DVU1FTlRfTk9ERSwgRE9DVU1FTlRfVFlQRV9OT0RFLCBOT1RBVElPTl9OT0RFPC90ZD4KLSAgICAgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPgotICAgICAqIG51bGw8L3RkPgotICAgICAqIDwvdHI+Ci0gICAgICogPC90YWJsZT4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgd2hlbiB0aGUgbm9kZSBpcyByZWFkb25seS4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgRE9NU1RSSU5HX1NJWkVfRVJSOiBSYWlzZWQgd2hlbiBpdCB3b3VsZCByZXR1cm4gbW9yZSBjaGFyYWN0ZXJzIHRoYW4KLSAgICAgKiAgIGZpdCBpbiBhIDxjb2RlPkRPTVN0cmluZzwvY29kZT4gdmFyaWFibGUgb24gdGhlIGltcGxlbWVudGF0aW9uCi0gICAgICogICBwbGF0Zm9ybS4KLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFRleHRDb250ZW50KCkgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0gICAgICAgIHJldHVybiBnZXROb2RlVmFsdWUoKTsgIC8vIG92ZXJyaWRlbiBpbiBzb21lIHN1YmNsYXNzZXMKLSAgICB9Ci0KLSAgICAvLyBpbnRlcm5hbCBtZXRob2QgdGFraW5nIGEgU3RyaW5nQnVmZmVyIGluIHBhcmFtZXRlcgotICAgIHZvaWQgZ2V0VGV4dENvbnRlbnQoU3RyaW5nQnVmZmVyIGJ1ZikgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0gICAgICAgIFN0cmluZyBjb250ZW50ID0gZ2V0Tm9kZVZhbHVlKCk7Ci0gICAgICAgIGlmIChjb250ZW50ICE9IG51bGwpIHsKLSAgICAgICAgICAgIGJ1Zi5hcHBlbmQoY29udGVudCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIGF0dHJpYnV0ZSByZXR1cm5zIHRoZSB0ZXh0IGNvbnRlbnQgb2YgdGhpcyBub2RlIGFuZCBpdHMKLSAgICAgKiBkZXNjZW5kYW50cy4gV2hlbiBpdCBpcyBkZWZpbmVkIHRvIGJlIG51bGwsIHNldHRpbmcgaXQgaGFzIG5vIGVmZmVjdC4KLSAgICAgKiBXaGVuIHNldCwgYW55IHBvc3NpYmxlIGNoaWxkcmVuIHRoaXMgbm9kZSBtYXkgaGF2ZSBhcmUgcmVtb3ZlZCBhbmQKLSAgICAgKiByZXBsYWNlZCBieSBhIHNpbmdsZSA8Y29kZT5UZXh0PC9jb2RlPiBub2RlIGNvbnRhaW5pbmcgdGhlIHN0cmluZwotICAgICAqIHRoaXMgYXR0cmlidXRlIGlzIHNldCB0by4gT24gZ2V0dGluZywgbm8gc2VyaWFsaXphdGlvbiBpcyBwZXJmb3JtZWQsCi0gICAgICogdGhlIHJldHVybmVkIHN0cmluZyBkb2VzIG5vdCBjb250YWluIGFueSBtYXJrdXAuIE5vIHdoaXRlc3BhY2UKLSAgICAgKiBub3JtYWxpemF0aW9uIGlzIHBlcmZvcm1lZCwgdGhlIHJldHVybmVkIHN0cmluZyBkb2VzIG5vdCBjb250YWluIHRoZQotICAgICAqIGVsZW1lbnQgY29udGVudCB3aGl0ZXNwYWNlcyAuIFNpbWlsYXJseSwgb24gc2V0dGluZywgbm8gcGFyc2luZyBpcwotICAgICAqIHBlcmZvcm1lZCBlaXRoZXIsIHRoZSBpbnB1dCBzdHJpbmcgaXMgdGFrZW4gYXMgcHVyZSB0ZXh0dWFsIGNvbnRlbnQuCi0gICAgICogPGJyPlRoZSBzdHJpbmcgcmV0dXJuZWQgaXMgbWFkZSBvZiB0aGUgdGV4dCBjb250ZW50IG9mIHRoaXMgbm9kZQotICAgICAqIGRlcGVuZGluZyBvbiBpdHMgdHlwZSwgYXMgZGVmaW5lZCBiZWxvdzoKLSAgICAgKiA8dGFibGUgYm9yZGVyPScxJz4KLSAgICAgKiA8dHI+Ci0gICAgICogPHRoPk5vZGUgdHlwZTwvdGg+Ci0gICAgICogPHRoPkNvbnRlbnQ8L3RoPgotICAgICAqIDwvdHI+Ci0gICAgICogPHRyPgotICAgICAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+Ci0gICAgICogRUxFTUVOVF9OT0RFLCBFTlRJVFlfTk9ERSwgRU5USVRZX1JFRkVSRU5DRV9OT0RFLAotICAgICAqIERPQ1VNRU5UX0ZSQUdNRU5UX05PREU8L3RkPgotICAgICAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+Y29uY2F0ZW5hdGlvbiBvZiB0aGUgPGNvZGU+dGV4dENvbnRlbnQ8L2NvZGU+Ci0gICAgICogYXR0cmlidXRlIHZhbHVlIG9mIGV2ZXJ5IGNoaWxkIG5vZGUsIGV4Y2x1ZGluZyBDT01NRU5UX05PREUgYW5kCi0gICAgICogUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFIG5vZGVzPC90ZD4KLSAgICAgKiA8L3RyPgotICAgICAqIDx0cj4KLSAgICAgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPkFUVFJJQlVURV9OT0RFLCBURVhUX05PREUsCi0gICAgICogQ0RBVEFfU0VDVElPTl9OT0RFLCBDT01NRU5UX05PREUsIFBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERTwvdGQ+Ci0gICAgICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz4KLSAgICAgKiA8Y29kZT5ub2RlVmFsdWU8L2NvZGU+PC90ZD4KLSAgICAgKiA8L3RyPgotICAgICAqIDx0cj4KLSAgICAgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPkRPQ1VNRU5UX05PREUsIERPQ1VNRU5UX1RZUEVfTk9ERSwgTk9UQVRJT05fTk9ERTwvdGQ+Ci0gICAgICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz4KLSAgICAgKiBudWxsPC90ZD4KLSAgICAgKiA8L3RyPgotICAgICAqIDwvdGFibGU+Ci0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIHdoZW4gdGhlIG5vZGUgaXMgcmVhZG9ubHkuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIERPTVNUUklOR19TSVpFX0VSUjogUmFpc2VkIHdoZW4gaXQgd291bGQgcmV0dXJuIG1vcmUgY2hhcmFjdGVycyB0aGFuCi0gICAgICogICBmaXQgaW4gYSA8Y29kZT5ET01TdHJpbmc8L2NvZGU+IHZhcmlhYmxlIG9uIHRoZSBpbXBsZW1lbnRhdGlvbgotICAgICAqICAgcGxhdGZvcm0uCi0gICAgICogQHNpbmNlIERPTSBMZXZlbCAzCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0VGV4dENvbnRlbnQoU3RyaW5nIHRleHRDb250ZW50KQotICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKLSAgICAgICAgc2V0Tm9kZVZhbHVlKHRleHRDb250ZW50KTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhpcyBub2RlIGlzIHRoZSBzYW1lIG5vZGUgYXMgdGhlIGdpdmVuIG9uZS4KLSAgICAgKiA8YnI+VGhpcyBtZXRob2QgcHJvdmlkZXMgYSB3YXkgdG8gZGV0ZXJtaW5lIHdoZXRoZXIgdHdvCi0gICAgICogPGNvZGU+Tm9kZTwvY29kZT4gcmVmZXJlbmNlcyByZXR1cm5lZCBieSB0aGUgaW1wbGVtZW50YXRpb24gcmVmZXJlbmNlCi0gICAgICogdGhlIHNhbWUgb2JqZWN0LiBXaGVuIHR3byA8Y29kZT5Ob2RlPC9jb2RlPiByZWZlcmVuY2VzIGFyZSByZWZlcmVuY2VzCi0gICAgICogdG8gdGhlIHNhbWUgb2JqZWN0LCBldmVuIGlmIHRocm91Z2ggYSBwcm94eSwgdGhlIHJlZmVyZW5jZXMgbWF5IGJlCi0gICAgICogdXNlZCBjb21wbGV0ZWx5IGludGVyY2hhbmdhYmx5LCBzdWNoIHRoYXQgYWxsIGF0dHJpYnV0ZXMgaGF2ZSB0aGUKLSAgICAgKiBzYW1lIHZhbHVlcyBhbmQgY2FsbGluZyB0aGUgc2FtZSBET00gbWV0aG9kIG9uIGVpdGhlciByZWZlcmVuY2UKLSAgICAgKiBhbHdheXMgaGFzIGV4YWN0bHkgdGhlIHNhbWUgZWZmZWN0LgotICAgICAqIEBwYXJhbSBvdGhlciBUaGUgbm9kZSB0byB0ZXN0IGFnYWluc3QuCi0gICAgICogQHJldHVybiBSZXR1cm5zIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBub2RlcyBhcmUgdGhlIHNhbWUsCi0gICAgICogICA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLgotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzU2FtZU5vZGUoTm9kZSBvdGhlcikgewotICAgICAgICAvLyB3ZSBkbyBub3QgdXNlIGFueSB3cmFwcGVyIHNvIHRoZSBhbnN3ZXIgaXMgb2J2aW91cwotICAgICAgICByZXR1cm4gdGhpcyA9PSBvdGhlcjsKLSAgICB9Ci0KLQotCi0KLSAgICAvKioKLSAgICAgKiAgRE9NIExldmVsIDM6IEV4cGVyaW1lbnRhbAotICAgICAqICBUaGlzIG1ldGhvZCBjaGVja3MgaWYgdGhlIHNwZWNpZmllZCA8Y29kZT5uYW1lc3BhY2VVUkk8L2NvZGU+IGlzIHRoZQotICAgICAqICBkZWZhdWx0IG5hbWVzcGFjZSBvciBub3QuCi0gICAgICogIEBwYXJhbSBuYW1lc3BhY2VVUkkgVGhlIG5hbWVzcGFjZSBVUkkgdG8gbG9vayBmb3IuCi0gICAgICogIEByZXR1cm4gIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBzcGVjaWZpZWQgPGNvZGU+bmFtZXNwYWNlVVJJPC9jb2RlPgotICAgICAqICAgaXMgdGhlIGRlZmF1bHQgbmFtZXNwYWNlLCA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLgotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzRGVmYXVsdE5hbWVzcGFjZShTdHJpbmcgbmFtZXNwYWNlVVJJKXsKLSAgICAgICAgLy8gUkVWSVNJVDogcmVtb3ZlIGNhc3RzIHdoZW4gRE9NIEwzIGJlY29tZXMgUkVDLgotICAgICAgICBzaG9ydCB0eXBlID0gdGhpcy5nZXROb2RlVHlwZSgpOwotICAgICAgICBzd2l0Y2ggKHR5cGUpIHsKLSAgICAgICAgY2FzZSBOb2RlLkVMRU1FTlRfTk9ERTogewotICAgICAgICAgICAgU3RyaW5nIG5hbWVzcGFjZSA9IHRoaXMuZ2V0TmFtZXNwYWNlVVJJKCk7Ci0gICAgICAgICAgICBTdHJpbmcgcHJlZml4ID0gdGhpcy5nZXRQcmVmaXgoKTsKLQotICAgICAgICAgICAgLy8gUkVWSVNJVDogaXMgaXQgcG9zc2libGUgdGhhdCBwcmVmaXggaXMgZW1wdHkgc3RyaW5nPwotICAgICAgICAgICAgaWYgKHByZWZpeCA9PSBudWxsIHx8IHByZWZpeC5sZW5ndGgoKSA9PSAwKSB7Ci0gICAgICAgICAgICAgICAgaWYgKG5hbWVzcGFjZVVSSSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiAobmFtZXNwYWNlID09IG5hbWVzcGFjZVVSSSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHJldHVybiBuYW1lc3BhY2VVUkkuZXF1YWxzKG5hbWVzcGFjZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAodGhpcy5oYXNBdHRyaWJ1dGVzKCkpIHsKLSAgICAgICAgICAgICAgICBFbGVtZW50SW1wbCBlbGVtID0gKEVsZW1lbnRJbXBsKXRoaXM7Ci0gICAgICAgICAgICAgICAgTm9kZUltcGwgYXR0ciA9IChOb2RlSW1wbCllbGVtLmdldEF0dHJpYnV0ZU5vZGVOUygiaHR0cDovL3d3dy53My5vcmcvMjAwMC94bWxucy8iLCAieG1sbnMiKTsKLSAgICAgICAgICAgICAgICBpZiAoYXR0ciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIFN0cmluZyB2YWx1ZSA9IGF0dHIuZ2V0Tm9kZVZhbHVlKCk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChuYW1lc3BhY2VVUkkgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChuYW1lc3BhY2UgPT0gdmFsdWUpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBuYW1lc3BhY2VVUkkuZXF1YWxzKHZhbHVlKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIE5vZGVJbXBsIGFuY2VzdG9yID0gKE5vZGVJbXBsKWdldEVsZW1lbnRBbmNlc3Rvcih0aGlzKTsKLSAgICAgICAgICAgIGlmIChhbmNlc3RvciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGFuY2VzdG9yLmlzRGVmYXVsdE5hbWVzcGFjZShuYW1lc3BhY2VVUkkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0gICAgICAgIGNhc2UgTm9kZS5ET0NVTUVOVF9OT0RFOnsKLSAgICAgICAgICAgICAgICByZXR1cm4oKE5vZGVJbXBsKSgoRG9jdW1lbnQpdGhpcykuZ2V0RG9jdW1lbnRFbGVtZW50KCkpLmlzRGVmYXVsdE5hbWVzcGFjZShuYW1lc3BhY2VVUkkpOwotICAgICAgICAgICAgfQotCi0gICAgICAgIGNhc2UgTm9kZS5FTlRJVFlfTk9ERSA6Ci0gICAgICAgIGNhc2UgTm9kZS5OT1RBVElPTl9OT0RFOgotICAgICAgICBjYXNlIE5vZGUuRE9DVU1FTlRfRlJBR01FTlRfTk9ERToKLSAgICAgICAgY2FzZSBOb2RlLkRPQ1VNRU5UX1RZUEVfTk9ERToKLSAgICAgICAgICAgIC8vIHR5cGUgaXMgdW5rbm93bgotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICBjYXNlIE5vZGUuQVRUUklCVVRFX05PREU6ewotICAgICAgICAgICAgICAgIGlmICh0aGlzLm93bmVyTm9kZS5nZXROb2RlVHlwZSgpID09IE5vZGUuRUxFTUVOVF9OT0RFKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBvd25lck5vZGUuaXNEZWZhdWx0TmFtZXNwYWNlKG5hbWVzcGFjZVVSSSk7Ci0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICBkZWZhdWx0OnsKLSAgICAgICAgICAgICAgICBOb2RlSW1wbCBhbmNlc3RvciA9IChOb2RlSW1wbClnZXRFbGVtZW50QW5jZXN0b3IodGhpcyk7Ci0gICAgICAgICAgICAgICAgaWYgKGFuY2VzdG9yICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFuY2VzdG9yLmlzRGVmYXVsdE5hbWVzcGFjZShuYW1lc3BhY2VVUkkpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgfQotCi0KLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqCi0gICAgICogRE9NIExldmVsIDMgLSBFeHBlcmltZW50YWw6Ci0gICAgICogTG9vayB1cCB0aGUgcHJlZml4IGFzc29jaWF0ZWQgdG8gdGhlIGdpdmVuIG5hbWVzcGFjZSBVUkksIHN0YXJ0aW5nIGZyb20gdGhpcyBub2RlLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWVzcGFjZVVSSQotICAgICAqIEByZXR1cm4gdGhlIHByZWZpeCBmb3IgdGhlIG5hbWVzcGFjZQotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgbG9va3VwUHJlZml4KFN0cmluZyBuYW1lc3BhY2VVUkkpewotCi0gICAgICAgIC8vIFJFVklTSVQ6IFdoZW4gTmFtZXNwYWNlcyAxLjEgY29tZXMgb3V0IHRoaXMgbWF5IG5vdCBiZSB0cnVlCi0gICAgICAgIC8vIFByZWZpeCBjYW4ndCBiZSBib3VuZCB0byBudWxsIG5hbWVzcGFjZQotICAgICAgICBpZiAobmFtZXNwYWNlVVJJID09IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0KLSAgICAgICAgc2hvcnQgdHlwZSA9IHRoaXMuZ2V0Tm9kZVR5cGUoKTsKLQotICAgICAgICBzd2l0Y2ggKHR5cGUpIHsKLSAgICAgICAgY2FzZSBOb2RlLkVMRU1FTlRfTk9ERTogewotCi0gICAgICAgICAgICAgICAgU3RyaW5nIG5hbWVzcGFjZSA9IHRoaXMuZ2V0TmFtZXNwYWNlVVJJKCk7IC8vIHRvIGZsaXAgb3V0IGNoaWxkcmVuCi0gICAgICAgICAgICAgICAgcmV0dXJuIGxvb2t1cE5hbWVzcGFjZVByZWZpeChuYW1lc3BhY2VVUkksIChFbGVtZW50SW1wbCl0aGlzKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgY2FzZSBOb2RlLkRPQ1VNRU5UX05PREU6ewotICAgICAgICAgICAgICAgIHJldHVybigoTm9kZUltcGwpKChEb2N1bWVudCl0aGlzKS5nZXREb2N1bWVudEVsZW1lbnQoKSkubG9va3VwUHJlZml4KG5hbWVzcGFjZVVSSSk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgY2FzZSBOb2RlLkVOVElUWV9OT0RFIDoKLSAgICAgICAgY2FzZSBOb2RlLk5PVEFUSU9OX05PREU6Ci0gICAgICAgIGNhc2UgTm9kZS5ET0NVTUVOVF9GUkFHTUVOVF9OT0RFOgotICAgICAgICBjYXNlIE5vZGUuRE9DVU1FTlRfVFlQRV9OT0RFOgotICAgICAgICAgICAgLy8gdHlwZSBpcyB1bmtub3duCi0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgY2FzZSBOb2RlLkFUVFJJQlVURV9OT0RFOnsKLSAgICAgICAgICAgICAgICBpZiAodGhpcy5vd25lck5vZGUuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLkVMRU1FTlRfTk9ERSkgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gb3duZXJOb2RlLmxvb2t1cFByZWZpeChuYW1lc3BhY2VVUkkpOwotCi0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICAgICAgfQotICAgICAgICBkZWZhdWx0OnsKLSAgICAgICAgICAgICAgICBOb2RlSW1wbCBhbmNlc3RvciA9IChOb2RlSW1wbClnZXRFbGVtZW50QW5jZXN0b3IodGhpcyk7Ci0gICAgICAgICAgICAgICAgaWYgKGFuY2VzdG9yICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFuY2VzdG9yLmxvb2t1cFByZWZpeChuYW1lc3BhY2VVUkkpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgICAgIH0KLQotICAgICAgICB9Ci0gICAgfQotICAgIC8qKgotICAgICAqIERPTSBMZXZlbCAzIC0gRXhwZXJpbWVudGFsOgotICAgICAqIExvb2sgdXAgdGhlIG5hbWVzcGFjZSBVUkkgYXNzb2NpYXRlZCB0byB0aGUgZ2l2ZW4gcHJlZml4LCBzdGFydGluZyBmcm9tIHRoaXMgbm9kZS4KLSAgICAgKiBVc2UgbG9va3VwTmFtZXNwYWNlVVJJKG51bGwpIHRvIGxvb2t1cCB0aGUgZGVmYXVsdCBuYW1lc3BhY2UKLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkKLSAgICAgKiBAcmV0dXJuIHRoIFVSSSBmb3IgdGhlIG5hbWVzcGFjZQotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgbG9va3VwTmFtZXNwYWNlVVJJKFN0cmluZyBzcGVjaWZpZWRQcmVmaXgpIHsKLSAgICAgICAgc2hvcnQgdHlwZSA9IHRoaXMuZ2V0Tm9kZVR5cGUoKTsKLSAgICAgICAgc3dpdGNoICh0eXBlKSB7Ci0gICAgICAgIGNhc2UgTm9kZS5FTEVNRU5UX05PREUgOiB7Ci0KLSAgICAgICAgICAgICAgICBTdHJpbmcgbmFtZXNwYWNlID0gdGhpcy5nZXROYW1lc3BhY2VVUkkoKTsKLSAgICAgICAgICAgICAgICBTdHJpbmcgcHJlZml4ID0gdGhpcy5nZXRQcmVmaXgoKTsKLSAgICAgICAgICAgICAgICBpZiAobmFtZXNwYWNlICE9bnVsbCkgewotICAgICAgICAgICAgICAgICAgICAvLyBSRVZJU0lUOiBpcyBpdCBwb3NzaWJsZSB0aGF0IHByZWZpeCBpcyBlbXB0eSBzdHJpbmc/Ci0gICAgICAgICAgICAgICAgICAgIGlmIChzcGVjaWZpZWRQcmVmaXg9PSBudWxsICYmIHByZWZpeD09c3BlY2lmaWVkUHJlZml4KSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBsb29raW5nIGZvciBkZWZhdWx0IG5hbWVzcGFjZQotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5hbWVzcGFjZTsKLSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChwcmVmaXggIT0gbnVsbCAmJiBwcmVmaXguZXF1YWxzKHNwZWNpZmllZFByZWZpeCkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIG5vbiBkZWZhdWx0IG5hbWVzcGFjZQotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5hbWVzcGFjZTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpZiAodGhpcy5oYXNBdHRyaWJ1dGVzKCkpIHsKLSAgICAgICAgICAgICAgICAgICAgTmFtZWROb2RlTWFwIG1hcCA9IHRoaXMuZ2V0QXR0cmlidXRlcygpOwotICAgICAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gbWFwLmdldExlbmd0aCgpOwotICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpPTA7aTxsZW5ndGg7aSsrKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBOb2RlIGF0dHIgPSBtYXAuaXRlbShpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBhdHRyUHJlZml4ID0gYXR0ci5nZXRQcmVmaXgoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyB2YWx1ZSA9IGF0dHIuZ2V0Tm9kZVZhbHVlKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBuYW1lc3BhY2UgPSBhdHRyLmdldE5hbWVzcGFjZVVSSSgpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5hbWVzcGFjZSAhPW51bGwgJiYgbmFtZXNwYWNlLmVxdWFscygiaHR0cDovL3d3dy53My5vcmcvMjAwMC94bWxucy8iKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGF0IHRoaXMgcG9pbnQgd2UgYXJlIGRlYWxpbmcgd2l0aCBET00gTGV2ZWwgMiBub2RlcyBvbmx5Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNwZWNpZmllZFByZWZpeCA9PSBudWxsICYmCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHIuZ2V0Tm9kZU5hbWUoKS5lcXVhbHMoInhtbG5zIikpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZGVmYXVsdCBuYW1lc3BhY2UKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYXR0clByZWZpeCAhPW51bGwgJiYKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJQcmVmaXguZXF1YWxzKCJ4bWxucyIpICYmCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyLmdldExvY2FsTmFtZSgpLmVxdWFscyhzcGVjaWZpZWRQcmVmaXgpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG5vbiBkZWZhdWx0IG5hbWVzcGFjZQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIE5vZGVJbXBsIGFuY2VzdG9yID0gKE5vZGVJbXBsKWdldEVsZW1lbnRBbmNlc3Rvcih0aGlzKTsKLSAgICAgICAgICAgICAgICBpZiAoYW5jZXN0b3IgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gYW5jZXN0b3IubG9va3VwTmFtZXNwYWNlVVJJKHNwZWNpZmllZFByZWZpeCk7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0KLQotICAgICAgICAgICAgfQotICAgICAgICBjYXNlIE5vZGUuRE9DVU1FTlRfTk9ERSA6IHsKLSAgICAgICAgICAgICAgICByZXR1cm4oKE5vZGVJbXBsKSgoRG9jdW1lbnQpdGhpcykuZ2V0RG9jdW1lbnRFbGVtZW50KCkpLmxvb2t1cE5hbWVzcGFjZVVSSShzcGVjaWZpZWRQcmVmaXgpOwotICAgICAgICAgICAgfQotICAgICAgICBjYXNlIE5vZGUuRU5USVRZX05PREUgOgotICAgICAgICBjYXNlIE5vZGUuTk9UQVRJT05fTk9ERToKLSAgICAgICAgY2FzZSBOb2RlLkRPQ1VNRU5UX0ZSQUdNRU5UX05PREU6Ci0gICAgICAgIGNhc2UgTm9kZS5ET0NVTUVOVF9UWVBFX05PREU6Ci0gICAgICAgICAgICAvLyB0eXBlIGlzIHVua25vd24KLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICBjYXNlIE5vZGUuQVRUUklCVVRFX05PREU6ewotICAgICAgICAgICAgICAgIGlmICh0aGlzLm93bmVyTm9kZS5nZXROb2RlVHlwZSgpID09IE5vZGUuRUxFTUVOVF9OT0RFKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBvd25lck5vZGUubG9va3VwTmFtZXNwYWNlVVJJKHNwZWNpZmllZFByZWZpeCk7Ci0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIGRlZmF1bHQ6ewotICAgICAgICAgICAgICAgIE5vZGVJbXBsIGFuY2VzdG9yID0gKE5vZGVJbXBsKWdldEVsZW1lbnRBbmNlc3Rvcih0aGlzKTsKLSAgICAgICAgICAgICAgICBpZiAoYW5jZXN0b3IgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gYW5jZXN0b3IubG9va3VwTmFtZXNwYWNlVVJJKHNwZWNpZmllZFByZWZpeCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICAgICAgfQotCi0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIE5vZGUgZ2V0RWxlbWVudEFuY2VzdG9yIChOb2RlIGN1cnJlbnROb2RlKXsKLSAgICAgICAgTm9kZSBwYXJlbnQgPSBjdXJyZW50Tm9kZS5nZXRQYXJlbnROb2RlKCk7Ci0gICAgICAgIGlmIChwYXJlbnQgIT0gbnVsbCkgewotICAgICAgICAgICAgc2hvcnQgdHlwZSA9IHBhcmVudC5nZXROb2RlVHlwZSgpOwotICAgICAgICAgICAgaWYgKHR5cGUgPT0gTm9kZS5FTEVNRU5UX05PREUpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gcGFyZW50OwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIGdldEVsZW1lbnRBbmNlc3RvcihwYXJlbnQpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIFN0cmluZyBsb29rdXBOYW1lc3BhY2VQcmVmaXgoU3RyaW5nIG5hbWVzcGFjZVVSSSwgRWxlbWVudEltcGwgZWwpewotICAgICAgICBTdHJpbmcgbmFtZXNwYWNlID0gdGhpcy5nZXROYW1lc3BhY2VVUkkoKTsKLSAgICAgICAgLy8gUkVWSVNJVDogaWYgbm8gcHJlZml4IGlzIGF2YWlsYWJsZSBpcyBpdCBudWxsIG9yIGVtcHR5IHN0cmluZywgb3IKLSAgICAgICAgLy8gICAgICAgICAgY291bGQgYmUgYm90aD8KLSAgICAgICAgU3RyaW5nIHByZWZpeCA9IHRoaXMuZ2V0UHJlZml4KCk7Ci0KLSAgICAgICAgaWYgKG5hbWVzcGFjZSE9bnVsbCAmJiBuYW1lc3BhY2UuZXF1YWxzKG5hbWVzcGFjZVVSSSkpIHsKLSAgICAgICAgICAgIGlmIChwcmVmaXggIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIFN0cmluZyBmb3VuZE5hbWVzcGFjZSA9ICBlbC5sb29rdXBOYW1lc3BhY2VVUkkocHJlZml4KTsKLSAgICAgICAgICAgICAgICBpZiAoZm91bmROYW1lc3BhY2UgIT1udWxsICYmIGZvdW5kTmFtZXNwYWNlLmVxdWFscyhuYW1lc3BhY2VVUkkpKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBwcmVmaXg7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKHRoaXMuaGFzQXR0cmlidXRlcygpKSB7Ci0gICAgICAgICAgICBOYW1lZE5vZGVNYXAgbWFwID0gdGhpcy5nZXRBdHRyaWJ1dGVzKCk7Ci0gICAgICAgICAgICBpbnQgbGVuZ3RoID0gbWFwLmdldExlbmd0aCgpOwotICAgICAgICAgICAgZm9yIChpbnQgaT0wO2k8bGVuZ3RoO2krKykgewotICAgICAgICAgICAgICAgIE5vZGUgYXR0ciA9IG1hcC5pdGVtKGkpOwotICAgICAgICAgICAgICAgIFN0cmluZyBhdHRyUHJlZml4ID0gYXR0ci5nZXRQcmVmaXgoKTsKLSAgICAgICAgICAgICAgICBTdHJpbmcgdmFsdWUgPSBhdHRyLmdldE5vZGVWYWx1ZSgpOwotICAgICAgICAgICAgICAgIG5hbWVzcGFjZSA9IGF0dHIuZ2V0TmFtZXNwYWNlVVJJKCk7Ci0gICAgICAgICAgICAgICAgaWYgKG5hbWVzcGFjZSAhPW51bGwgJiYgbmFtZXNwYWNlLmVxdWFscygiaHR0cDovL3d3dy53My5vcmcvMjAwMC94bWxucy8iKSkgewotICAgICAgICAgICAgICAgICAgICAvLyBET00gTGV2ZWwgMiBub2RlcwotICAgICAgICAgICAgICAgICAgICBpZiAoKChhdHRyLmdldE5vZGVOYW1lKCkuZXF1YWxzKCJ4bWxucyIpKSB8fAotICAgICAgICAgICAgICAgICAgICAgICAgIChhdHRyUHJlZml4ICE9bnVsbCAmJiBhdHRyUHJlZml4LmVxdWFscygieG1sbnMiKSkgJiYKLSAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZS5lcXVhbHMobmFtZXNwYWNlVVJJKSkpIHsKLQotICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGxvY2FsbmFtZT0gYXR0ci5nZXRMb2NhbE5hbWUoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBmb3VuZE5hbWVzcGFjZSA9IGVsLmxvb2t1cE5hbWVzcGFjZVVSSShsb2NhbG5hbWUpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZvdW5kTmFtZXNwYWNlICE9bnVsbCAmJiBmb3VuZE5hbWVzcGFjZS5lcXVhbHMobmFtZXNwYWNlVVJJKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBsb2NhbG5hbWU7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLQotCi0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIE5vZGVJbXBsIGFuY2VzdG9yID0gKE5vZGVJbXBsKWdldEVsZW1lbnRBbmNlc3Rvcih0aGlzKTsKLQotICAgICAgICBpZiAoYW5jZXN0b3IgIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIGFuY2VzdG9yLmxvb2t1cE5hbWVzcGFjZVByZWZpeChuYW1lc3BhY2VVUkksIGVsKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUZXN0cyB3aGV0aGVyIHR3byBub2RlcyBhcmUgZXF1YWwuCi0gICAgICogPGJyPlRoaXMgbWV0aG9kIHRlc3RzIGZvciBlcXVhbGl0eSBvZiBub2Rlcywgbm90IHNhbWVuZXNzIChpLmUuLAotICAgICAqIHdoZXRoZXIgdGhlIHR3byBub2RlcyBhcmUgcmVmZXJlbmNlcyB0byB0aGUgc2FtZSBvYmplY3QpIHdoaWNoIGNhbiBiZQotICAgICAqIHRlc3RlZCB3aXRoIDxjb2RlPk5vZGUuaXNTYW1lTm9kZTwvY29kZT4uIEFsbCBub2RlcyB0aGF0IGFyZSB0aGUgc2FtZQotICAgICAqIHdpbGwgYWxzbyBiZSBlcXVhbCwgdGhvdWdoIHRoZSByZXZlcnNlIG1heSBub3QgYmUgdHJ1ZS4KLSAgICAgKiA8YnI+VHdvIG5vZGVzIGFyZSBlcXVhbCBpZiBhbmQgb25seSBpZiB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCi0gICAgICogc2F0aXNmaWVkOiBUaGUgdHdvIG5vZGVzIGFyZSBvZiB0aGUgc2FtZSB0eXBlLlRoZSBmb2xsb3dpbmcgc3RyaW5nCi0gICAgICogYXR0cmlidXRlcyBhcmUgZXF1YWw6IDxjb2RlPm5vZGVOYW1lPC9jb2RlPiwgPGNvZGU+bG9jYWxOYW1lPC9jb2RlPiwKLSAgICAgKiA8Y29kZT5uYW1lc3BhY2VVUkk8L2NvZGU+LCA8Y29kZT5wcmVmaXg8L2NvZGU+LCA8Y29kZT5ub2RlVmFsdWU8L2NvZGU+Ci0gICAgICogLCA8Y29kZT5iYXNlVVJJPC9jb2RlPi4gVGhpcyBpczogdGhleSBhcmUgYm90aCA8Y29kZT5udWxsPC9jb2RlPiwgb3IKLSAgICAgKiB0aGV5IGhhdmUgdGhlIHNhbWUgbGVuZ3RoIGFuZCBhcmUgY2hhcmFjdGVyIGZvciBjaGFyYWN0ZXIgaWRlbnRpY2FsLgotICAgICAqIFRoZSA8Y29kZT5hdHRyaWJ1dGVzPC9jb2RlPiA8Y29kZT5OYW1lZE5vZGVNYXBzPC9jb2RlPiBhcmUgZXF1YWwuCi0gICAgICogVGhpcyBpczogdGhleSBhcmUgYm90aCA8Y29kZT5udWxsPC9jb2RlPiwgb3IgdGhleSBoYXZlIHRoZSBzYW1lCi0gICAgICogbGVuZ3RoIGFuZCBmb3IgZWFjaCBub2RlIHRoYXQgZXhpc3RzIGluIG9uZSBtYXAgdGhlcmUgaXMgYSBub2RlIHRoYXQKLSAgICAgKiBleGlzdHMgaW4gdGhlIG90aGVyIG1hcCBhbmQgaXMgZXF1YWwsIGFsdGhvdWdoIG5vdCBuZWNlc3NhcmlseSBhdCB0aGUKLSAgICAgKiBzYW1lIGluZGV4LlRoZSA8Y29kZT5jaGlsZE5vZGVzPC9jb2RlPiA8Y29kZT5Ob2RlTGlzdHM8L2NvZGU+IGFyZQotICAgICAqIGVxdWFsLiBUaGlzIGlzOiB0aGV5IGFyZSBib3RoIDxjb2RlPm51bGw8L2NvZGU+LCBvciB0aGV5IGhhdmUgdGhlCi0gICAgICogc2FtZSBsZW5ndGggYW5kIGNvbnRhaW4gZXF1YWwgbm9kZXMgYXQgdGhlIHNhbWUgaW5kZXguIFRoaXMgaXMgdHJ1ZQotICAgICAqIGZvciA8Y29kZT5BdHRyPC9jb2RlPiBub2RlcyBhcyBmb3IgYW55IG90aGVyIHR5cGUgb2Ygbm9kZS4gTm90ZSB0aGF0Ci0gICAgICogbm9ybWFsaXphdGlvbiBjYW4gYWZmZWN0IGVxdWFsaXR5OyB0byBhdm9pZCB0aGlzLCBub2RlcyBzaG91bGQgYmUKLSAgICAgKiBub3JtYWxpemVkIGJlZm9yZSBiZWluZyBjb21wYXJlZC4KLSAgICAgKiA8YnI+Rm9yIHR3byA8Y29kZT5Eb2N1bWVudFR5cGU8L2NvZGU+IG5vZGVzIHRvIGJlIGVxdWFsLCB0aGUgZm9sbG93aW5nCi0gICAgICogY29uZGl0aW9ucyBtdXN0IGFsc28gYmUgc2F0aXNmaWVkOiBUaGUgZm9sbG93aW5nIHN0cmluZyBhdHRyaWJ1dGVzCi0gICAgICogYXJlIGVxdWFsOiA8Y29kZT5wdWJsaWNJZDwvY29kZT4sIDxjb2RlPnN5c3RlbUlkPC9jb2RlPiwKLSAgICAgKiA8Y29kZT5pbnRlcm5hbFN1YnNldDwvY29kZT4uVGhlIDxjb2RlPmVudGl0aWVzPC9jb2RlPgotICAgICAqIDxjb2RlPk5hbWVkTm9kZU1hcHM8L2NvZGU+IGFyZSBlcXVhbC5UaGUgPGNvZGU+bm90YXRpb25zPC9jb2RlPgotICAgICAqIDxjb2RlPk5hbWVkTm9kZU1hcHM8L2NvZGU+IGFyZSBlcXVhbC4KLSAgICAgKiA8YnI+T24gdGhlIG90aGVyIGhhbmQsIHRoZSBmb2xsb3dpbmcgZG8gbm90IGFmZmVjdCBlcXVhbGl0eTogdGhlCi0gICAgICogPGNvZGU+b3duZXJEb2N1bWVudDwvY29kZT4gYXR0cmlidXRlLCB0aGUgPGNvZGU+c3BlY2lmaWVkPC9jb2RlPgotICAgICAqIGF0dHJpYnV0ZSBmb3IgPGNvZGU+QXR0cjwvY29kZT4gbm9kZXMsIHRoZQotICAgICAqIDxjb2RlPmlzV2hpdGVzcGFjZUluRWxlbWVudENvbnRlbnQ8L2NvZGU+IGF0dHJpYnV0ZSBmb3IKLSAgICAgKiA8Y29kZT5UZXh0PC9jb2RlPiBub2RlcywgYXMgd2VsbCBhcyBhbnkgdXNlciBkYXRhIG9yIGV2ZW50IGxpc3RlbmVycwotICAgICAqIHJlZ2lzdGVyZWQgb24gdGhlIG5vZGVzLgotICAgICAqIEBwYXJhbSBhcmcgVGhlIG5vZGUgdG8gY29tcGFyZSBlcXVhbGl0eSB3aXRoLgotICAgICAqIEBwYXJhbSBkZWVwIElmIDxjb2RlPnRydWU8L2NvZGU+LCByZWN1cnNpdmVseSBjb21wYXJlIHRoZSBzdWJ0cmVlczsgaWYKLSAgICAgKiAgIDxjb2RlPmZhbHNlPC9jb2RlPiwgY29tcGFyZSBvbmx5IHRoZSBub2RlcyB0aGVtc2VsdmVzIChhbmQgaXRzCi0gICAgICogICBhdHRyaWJ1dGVzLCBpZiBpdCBpcyBhbiA8Y29kZT5FbGVtZW50PC9jb2RlPikuCi0gICAgICogQHJldHVybiBJZiB0aGUgbm9kZXMsIGFuZCBwb3NzaWJseSBzdWJ0cmVlcyBhcmUgZXF1YWwsCi0gICAgICogICA8Y29kZT50cnVlPC9jb2RlPiBvdGhlcndpc2UgPGNvZGU+ZmFsc2U8L2NvZGU+LgotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzRXF1YWxOb2RlKE5vZGUgYXJnKSB7Ci0gICAgICAgIGlmIChhcmcgPT0gdGhpcykgewotICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGFyZy5nZXROb2RlVHlwZSgpICE9IGdldE5vZGVUeXBlKCkpIHsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotICAgICAgICAvLyBpbiB0aGVvcnkgbm9kZU5hbWUgY2FuJ3QgYmUgbnVsbCBidXQgYmV0dGVyIGJlIGNhcmVmdWwKLSAgICAgICAgLy8gd2hvIGtub3dzIHdoYXQgb3RoZXIgaW1wbGVtZW50YXRpb25zIG1heSBiZSBkb2luZz8uLi4KLSAgICAgICAgaWYgKGdldE5vZGVOYW1lKCkgPT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKGFyZy5nZXROb2RlTmFtZSgpICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoIWdldE5vZGVOYW1lKCkuZXF1YWxzKGFyZy5nZXROb2RlTmFtZSgpKSkgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKGdldExvY2FsTmFtZSgpID09IG51bGwpIHsKLSAgICAgICAgICAgIGlmIChhcmcuZ2V0TG9jYWxOYW1lKCkgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICghZ2V0TG9jYWxOYW1lKCkuZXF1YWxzKGFyZy5nZXRMb2NhbE5hbWUoKSkpIHsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChnZXROYW1lc3BhY2VVUkkoKSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAoYXJnLmdldE5hbWVzcGFjZVVSSSgpICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoIWdldE5hbWVzcGFjZVVSSSgpLmVxdWFscyhhcmcuZ2V0TmFtZXNwYWNlVVJJKCkpKSB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoZ2V0UHJlZml4KCkgPT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKGFyZy5nZXRQcmVmaXgoKSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKCFnZXRQcmVmaXgoKS5lcXVhbHMoYXJnLmdldFByZWZpeCgpKSkgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKGdldE5vZGVWYWx1ZSgpID09IG51bGwpIHsKLSAgICAgICAgICAgIGlmIChhcmcuZ2V0Tm9kZVZhbHVlKCkgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICghZ2V0Tm9kZVZhbHVlKCkuZXF1YWxzKGFyZy5nZXROb2RlVmFsdWUoKSkpIHsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotCi0KLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHNpbmNlIERPTSBMZXZlbCAzCi0gICAgICovCi0gICAgcHVibGljIE9iamVjdCBnZXRGZWF0dXJlKFN0cmluZyBmZWF0dXJlLCBTdHJpbmcgdmVyc2lvbikgewotICAgICAgICAvLyB3ZSBkb24ndCBoYXZlIGFueSBhbHRlcm5hdGUgbm9kZSwgZWl0aGVyIHRoaXMgbm9kZSBkb2VzIHRoZSBqb2IKLSAgICAgICAgLy8gb3Igd2UgZG9uJ3QgaGF2ZSBhbnl0aGluZyB0aGF0IGRvZXMKLSAgICAgICAgcmV0dXJuIGlzU3VwcG9ydGVkKGZlYXR1cmUsIHZlcnNpb24pID8gdGhpcyA6IG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQXNzb2NpYXRlIGFuIG9iamVjdCB0byBhIGtleSBvbiB0aGlzIG5vZGUuIFRoZSBvYmplY3QgY2FuIGxhdGVyIGJlCi0gICAgICogcmV0cmlldmVkIGZyb20gdGhpcyBub2RlIGJ5IGNhbGxpbmcgPGNvZGU+Z2V0VXNlckRhdGE8L2NvZGU+IHdpdGggdGhlCi0gICAgICogc2FtZSBrZXkuCi0gICAgICogQHBhcmFtIGtleSBUaGUga2V5IHRvIGFzc29jaWF0ZSB0aGUgb2JqZWN0IHRvLgotICAgICAqIEBwYXJhbSBkYXRhIFRoZSBvYmplY3QgdG8gYXNzb2NpYXRlIHRvIHRoZSBnaXZlbiBrZXksIG9yCi0gICAgICogICA8Y29kZT5udWxsPC9jb2RlPiB0byByZW1vdmUgYW55IGV4aXN0aW5nIGFzc29jaWF0aW9uIHRvIHRoYXQga2V5LgotICAgICAqIEBwYXJhbSBoYW5kbGVyIFRoZSBoYW5kbGVyIHRvIGFzc29jaWF0ZSB0byB0aGF0IGtleSwgb3IKLSAgICAgKiAgIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAqIEByZXR1cm4gUmV0dXJucyB0aGUgPGNvZGU+RE9NT2JqZWN0PC9jb2RlPiBwcmV2aW91c2x5IGFzc29jaWF0ZWQgdG8KLSAgICAgKiAgIHRoZSBnaXZlbiBrZXkgb24gdGhpcyBub2RlLCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGVyZSB3YXMgbm9uZS4KLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0IHNldFVzZXJEYXRhKFN0cmluZyBrZXksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPYmplY3QgZGF0YSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVzZXJEYXRhSGFuZGxlciBoYW5kbGVyKSB7Ci0gICAgICAgIHJldHVybiBvd25lckRvY3VtZW50KCkuc2V0VXNlckRhdGEodGhpcywga2V5LCBkYXRhLCBoYW5kbGVyKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXRyaWV2ZXMgdGhlIG9iamVjdCBhc3NvY2lhdGVkIHRvIGEga2V5IG9uIGEgdGhpcyBub2RlLiBUaGUgb2JqZWN0Ci0gICAgICogbXVzdCBmaXJzdCBoYXZlIGJlZW4gc2V0IHRvIHRoaXMgbm9kZSBieSBjYWxsaW5nCi0gICAgICogPGNvZGU+c2V0VXNlckRhdGE8L2NvZGU+IHdpdGggdGhlIHNhbWUga2V5LgotICAgICAqIEBwYXJhbSBrZXkgVGhlIGtleSB0aGUgb2JqZWN0IGlzIGFzc29jaWF0ZWQgdG8uCi0gICAgICogQHJldHVybiBSZXR1cm5zIHRoZSA8Y29kZT5ET01PYmplY3Q8L2NvZGU+IGFzc29jaWF0ZWQgdG8gdGhlIGdpdmVuIGtleQotICAgICAqICAgb24gdGhpcyBub2RlLCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGVyZSB3YXMgbm9uZS4KLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0IGdldFVzZXJEYXRhKFN0cmluZyBrZXkpIHsKLSAgICAgICAgcmV0dXJuIG93bmVyRG9jdW1lbnQoKS5nZXRVc2VyRGF0YSh0aGlzLCBrZXkpOwotICAgIH0KLQotICAgIHByb3RlY3RlZCBNYXA8U3RyaW5nLCBQYXJlbnROb2RlLlVzZXJEYXRhUmVjb3JkPiBnZXRVc2VyRGF0YVJlY29yZCgpewotICAgICAgICByZXR1cm4gb3duZXJEb2N1bWVudCgpLmdldFVzZXJEYXRhUmVjb3JkKHRoaXMpOwotICAgICAgICB9Ci0KLSAgICAvLwotICAgIC8vIFB1YmxpYyBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIE5PTi1ET006IFBSLURPTS1MZXZlbC0xLTE5OTgwODE4IG1lbnRpb25zIHJlYWRvbmx5IG5vZGVzIGluIGNvbmp1bmN0aW9uCi0gICAgICogd2l0aCBFbnRpdGllcywgYnV0IHByb3ZpZGVzIG5vIEFQSSB0byBzdXBwb3J0IHRoaXMuCi0gICAgICogPFA+Ci0gICAgICogTW9zdCBET00gdXNlcnMgc2hvdWxkIG5vdCB0b3VjaCB0aGlzIG1ldGhvZC4gSXRzIGFudGljcGF0ZWQgdXNlCi0gICAgICogaXMgZHVyaW5nIGNvbnN0cnVjdGlvbiBvZiBFbnRpdHlSZWZlcm5jZXMsIHdoZXJlIGl0IHdpbGwgYmUgdXNlZCB0bwotICAgICAqIGxvY2sgdGhlIGNvbnRlbnRzIHJlcGxpY2F0ZWQgZnJvbSBFbnRpdHkgc28gdGhleSBjYW4ndCBiZSBjYXN1YWxseQotICAgICAqIGFsdGVyZWQuIEl0IF9jb3VsZF8gYmUgcHVibGlzaGVkIGFzIGEgRE9NIGV4dGVuc2lvbiwgaWYgZGVzaXJlZC4KLSAgICAgKiA8UD4KLSAgICAgKiBOb3RlOiBzaW5jZSB3ZSBuZXZlciBoYXZlIGFueSBjaGlsZHJlbiBkZWVwIGlzIG1lYW5pbmdsZXNzIGhlcmUsCi0gICAgICogUGFyZW50Tm9kZSBvdmVycmlkZXMgdGhpcyBiZWhhdmlvci4KLSAgICAgKiBAc2VlIFBhcmVudE5vZGUKLSAgICAgKgotICAgICAqIEBwYXJhbSByZWFkT25seSBUcnVlIG9yIGZhbHNlIGFzIGRlc2lyZWQuCi0gICAgICogQHBhcmFtIGRlZXAgSWYgdHJ1ZSwgY2hpbGRyZW4gYXJlIGFsc28gdG9nZ2xlZC4gTm90ZSB0aGF0IHRoaXMgd2lsbAotICAgICAqICBub3QgY2hhbmdlIHRoZSBzdGF0ZSBvZiBhbiBFbnRpdHlSZWZlcmVuY2Ugb3IgaXRzIGNoaWxkcmVuLAotICAgICAqICB3aGljaCBhcmUgYWx3YXlzIHJlYWQtb25seS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRSZWFkT25seShib29sZWFuIHJlYWRPbmx5LCBib29sZWFuIGRlZXApIHsKLQotICAgICAgICBpZiAobmVlZHNTeW5jRGF0YSgpKSB7Ci0gICAgICAgICAgICBzeW5jaHJvbml6ZURhdGEoKTsKLSAgICAgICAgfQotICAgICAgICBpc1JlYWRPbmx5KHJlYWRPbmx5KTsKLQotICAgIH0gLy8gc2V0UmVhZE9ubHkoYm9vbGVhbixib29sZWFuKQotCi0gICAgLyoqCi0gICAgICogTk9OLURPTTogUmV0dXJucyB0cnVlIGlmIHRoaXMgbm9kZSBpcyByZWFkLW9ubHkuIFRoaXMgaXMgYQotICAgICAqIHNoYWxsb3cgY2hlY2suCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0UmVhZE9ubHkoKSB7Ci0KLSAgICAgICAgaWYgKG5lZWRzU3luY0RhdGEoKSkgewotICAgICAgICAgICAgc3luY2hyb25pemVEYXRhKCk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGlzUmVhZE9ubHkoKTsKLQotICAgIH0gLy8gZ2V0UmVhZE9ubHkoKTpib29sZWFuCi0KLSAgICAvKioKLSAgICAgKiBOT04tRE9NOiBBcyBhbiBhbHRlcm5hdGl2ZSB0byBzdWJjbGFzc2luZyB0aGUgRE9NLCB0aGlzIGltcGxlbWVudGF0aW9uCi0gICAgICogaGFzIGJlZW4gZXh0ZW5kZWQgd2l0aCB0aGUgYWJpbGl0eSB0byBhdHRhY2ggYW4gb2JqZWN0IHRvIGVhY2ggbm9kZS4KLSAgICAgKiAoSWYgeW91IG5lZWQgbXVsdGlwbGUgb2JqZWN0cywgeW91IGNhbiBhdHRhY2ggYSBjb2xsZWN0aW9uIHN1Y2ggYXMgYQotICAgICAqIExpc3Qgb3IgTWFwLCB0aGVuIGF0dGFjaCB5b3VyIGFwcGxpY2F0aW9uIGluZm9ybWF0aW9uIHRvIHRoYXQuKQotICAgICAqIDxwPjxiPkltcG9ydGFudCBOb3RlOjwvYj4gWW91IGFyZSByZXNwb25zaWJsZSBmb3IgcmVtb3ZpbmcgcmVmZXJlbmNlcwotICAgICAqIHRvIHlvdXIgZGF0YSBvbiBub2RlcyB0aGF0IGFyZSBubyBsb25nZXIgdXNlZC4gRmFpbHVyZSB0byBkbyBzbyB3aWxsCi0gICAgICogcHJldmVudCB0aGUgbm9kZXMsIHlvdXIgZGF0YSBpcyBhdHRhY2hlZCB0bywgdG8gYmUgZ2FyYmFnZSBjb2xsZWN0ZWQKLSAgICAgKiB1bnRpbCB0aGUgd2hvbGUgZG9jdW1lbnQgaXMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZGF0YSB0aGUgb2JqZWN0IHRvIHN0b3JlIG9yIG51bGwgdG8gcmVtb3ZlIGFueSBleGlzdGluZyByZWZlcmVuY2UKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRVc2VyRGF0YShPYmplY3QgZGF0YSkgewotICAgICAgICBvd25lckRvY3VtZW50KCkuc2V0VXNlckRhdGEodGhpcywgZGF0YSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogTk9OLURPTToKLSAgICAgKiBSZXR1cm5zIHRoZSB1c2VyIGRhdGEgYXNzb2NpYXRlZCB0byB0aGlzIG5vZGUuCi0gICAgICovCi0gICAgcHVibGljIE9iamVjdCBnZXRVc2VyRGF0YSgpIHsKLSAgICAgICAgcmV0dXJuIG93bmVyRG9jdW1lbnQoKS5nZXRVc2VyRGF0YSh0aGlzKTsKLSAgICB9Ci0KLSAgICAvLwotICAgIC8vIFByb3RlY3RlZCBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIERlbm90ZXMgdGhhdCB0aGlzIG5vZGUgaGFzIGNoYW5nZWQuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgY2hhbmdlZCgpIHsKLSAgICAgICAgLy8gd2UgZG8gbm90IGFjdHVhbGx5IHN0b3JlIHRoaXMgaW5mb3JtYXRpb24gb24gZXZlcnkgbm9kZSwgd2Ugb25seQotICAgICAgICAvLyBoYXZlIGEgZ2xvYmFsIGluZGljYXRvciBvbiB0aGUgRG9jdW1lbnQuIERvaW5nIG90aGVyd2lzZSBjb3N0IHVzIHRvbwotICAgICAgICAvLyBtdWNoIGZvciBsaXR0bGUgZ2Fpbi4KLSAgICAgICAgb3duZXJEb2N1bWVudCgpLmNoYW5nZWQoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgY2hhbmdlcyB0byB0aGlzIG5vZGUuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGludCBjaGFuZ2VzKCkgewotICAgICAgICAvLyB3ZSBkbyBub3QgYWN0dWFsbHkgc3RvcmUgdGhpcyBpbmZvcm1hdGlvbiBvbiBldmVyeSBub2RlLCB3ZSBvbmx5Ci0gICAgICAgIC8vIGhhdmUgYSBnbG9iYWwgaW5kaWNhdG9yIG9uIHRoZSBEb2N1bWVudC4gRG9pbmcgb3RoZXJ3aXNlIGNvc3QgdXMgdG9vCi0gICAgICAgIC8vIG11Y2ggZm9yIGxpdHRsZSBnYWluLgotICAgICAgICByZXR1cm4gb3duZXJEb2N1bWVudCgpLmNoYW5nZXMoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBPdmVycmlkZSB0aGlzIG1ldGhvZCBpbiBzdWJjbGFzcyB0byBob29rIGluIGVmZmljaWVudAotICAgICAqIGludGVybmFsIGRhdGEgc3RydWN0dXJlLgotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIHN5bmNocm9uaXplRGF0YSgpIHsKLSAgICAgICAgLy8gQnkgZGVmYXVsdCBqdXN0IGNoYW5nZSB0aGUgZmxhZyB0byBhdm9pZCBjYWxsaW5nIHRoaXMgbWV0aG9kIGFnYWluCi0gICAgICAgIG5lZWRzU3luY0RhdGEoZmFsc2UpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEZvciBub24tY2hpbGQgbm9kZXMsIHRoZSBub2RlIHdoaWNoICJwb2ludHMiIHRvIHRoaXMgbm9kZS4KLSAgICAgKiBGb3IgZXhhbXBsZSwgdGhlIG93bmluZyBlbGVtZW50IGZvciBhbiBhdHRyaWJ1dGUKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgTm9kZSBnZXRDb250YWluZXIoKSB7Ci0gICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0KLSAgICAvKgotICAgICAqIEZsYWdzIHNldHRlcnMgYW5kIGdldHRlcnMKLSAgICAgKi8KLQotICAgIGZpbmFsIGJvb2xlYW4gaXNSZWFkT25seSgpIHsKLSAgICAgICAgcmV0dXJuIChmbGFncyAmIFJFQURPTkxZKSAhPSAwOwotICAgIH0KLQotICAgIGZpbmFsIHZvaWQgaXNSZWFkT25seShib29sZWFuIHZhbHVlKSB7Ci0gICAgICAgIGZsYWdzID0gKHNob3J0KSAodmFsdWUgPyBmbGFncyB8IFJFQURPTkxZIDogZmxhZ3MgJiB+UkVBRE9OTFkpOwotICAgIH0KLQotICAgIGZpbmFsIGJvb2xlYW4gbmVlZHNTeW5jRGF0YSgpIHsKLSAgICAgICAgcmV0dXJuIChmbGFncyAmIFNZTkNEQVRBKSAhPSAwOwotICAgIH0KLQotICAgIGZpbmFsIHZvaWQgbmVlZHNTeW5jRGF0YShib29sZWFuIHZhbHVlKSB7Ci0gICAgICAgIGZsYWdzID0gKHNob3J0KSAodmFsdWUgPyBmbGFncyB8IFNZTkNEQVRBIDogZmxhZ3MgJiB+U1lOQ0RBVEEpOwotICAgIH0KLQotICAgIGZpbmFsIGJvb2xlYW4gbmVlZHNTeW5jQ2hpbGRyZW4oKSB7Ci0gICAgICAgIHJldHVybiAoZmxhZ3MgJiBTWU5DQ0hJTERSRU4pICE9IDA7Ci0gICAgfQotCi0gICAgcHVibGljIGZpbmFsIHZvaWQgbmVlZHNTeW5jQ2hpbGRyZW4oYm9vbGVhbiB2YWx1ZSkgewotICAgICAgICBmbGFncyA9IChzaG9ydCkgKHZhbHVlID8gZmxhZ3MgfCBTWU5DQ0hJTERSRU4gOiBmbGFncyAmIH5TWU5DQ0hJTERSRU4pOwotICAgIH0KLQotICAgIGZpbmFsIGJvb2xlYW4gaXNPd25lZCgpIHsKLSAgICAgICAgcmV0dXJuIChmbGFncyAmIE9XTkVEKSAhPSAwOwotICAgIH0KLQotICAgIGZpbmFsIHZvaWQgaXNPd25lZChib29sZWFuIHZhbHVlKSB7Ci0gICAgICAgIGZsYWdzID0gKHNob3J0KSAodmFsdWUgPyBmbGFncyB8IE9XTkVEIDogZmxhZ3MgJiB+T1dORUQpOwotICAgIH0KLQotICAgIGZpbmFsIGJvb2xlYW4gaXNGaXJzdENoaWxkKCkgewotICAgICAgICByZXR1cm4gKGZsYWdzICYgRklSU1RDSElMRCkgIT0gMDsKLSAgICB9Ci0KLSAgICBmaW5hbCB2b2lkIGlzRmlyc3RDaGlsZChib29sZWFuIHZhbHVlKSB7Ci0gICAgICAgIGZsYWdzID0gKHNob3J0KSAodmFsdWUgPyBmbGFncyB8IEZJUlNUQ0hJTEQgOiBmbGFncyAmIH5GSVJTVENISUxEKTsKLSAgICB9Ci0KLSAgICBmaW5hbCBib29sZWFuIGlzU3BlY2lmaWVkKCkgewotICAgICAgICByZXR1cm4gKGZsYWdzICYgU1BFQ0lGSUVEKSAhPSAwOwotICAgIH0KLQotICAgIGZpbmFsIHZvaWQgaXNTcGVjaWZpZWQoYm9vbGVhbiB2YWx1ZSkgewotICAgICAgICBmbGFncyA9IChzaG9ydCkgKHZhbHVlID8gZmxhZ3MgfCBTUEVDSUZJRUQgOiBmbGFncyAmIH5TUEVDSUZJRUQpOwotICAgIH0KLQotICAgIC8vIGluY29uc2lzdGVudCBuYW1lIHRvIGF2b2lkIGNsYXNoIHdpdGggcHVibGljIG1ldGhvZCBvbiBUZXh0SW1wbAotICAgIGZpbmFsIGJvb2xlYW4gaW50ZXJuYWxJc0lnbm9yYWJsZVdoaXRlc3BhY2UoKSB7Ci0gICAgICAgIHJldHVybiAoZmxhZ3MgJiBJR05PUkFCTEVXUykgIT0gMDsKLSAgICB9Ci0KLSAgICBmaW5hbCB2b2lkIGlzSWdub3JhYmxlV2hpdGVzcGFjZShib29sZWFuIHZhbHVlKSB7Ci0gICAgICAgIGZsYWdzID0gKHNob3J0KSAodmFsdWUgPyBmbGFncyB8IElHTk9SQUJMRVdTIDogZmxhZ3MgJiB+SUdOT1JBQkxFV1MpOwotICAgIH0KLQotICAgIGZpbmFsIGJvb2xlYW4gaGFzU3RyaW5nVmFsdWUoKSB7Ci0gICAgICAgIHJldHVybiAoZmxhZ3MgJiBIQVNTVFJJTkcpICE9IDA7Ci0gICAgfQotCi0gICAgZmluYWwgdm9pZCBoYXNTdHJpbmdWYWx1ZShib29sZWFuIHZhbHVlKSB7Ci0gICAgICAgIGZsYWdzID0gKHNob3J0KSAodmFsdWUgPyBmbGFncyB8IEhBU1NUUklORyA6IGZsYWdzICYgfkhBU1NUUklORyk7Ci0gICAgfQotCi0gICAgZmluYWwgYm9vbGVhbiBpc05vcm1hbGl6ZWQoKSB7Ci0gICAgICAgIHJldHVybiAoZmxhZ3MgJiBOT1JNQUxJWkVEKSAhPSAwOwotICAgIH0KLQotICAgIGZpbmFsIHZvaWQgaXNOb3JtYWxpemVkKGJvb2xlYW4gdmFsdWUpIHsKLSAgICAgICAgLy8gU2VlIGlmIGZsYWcgc2hvdWxkIHByb3BhZ2F0ZSB0byBwYXJlbnQuCi0gICAgICAgIGlmICghdmFsdWUgJiYgaXNOb3JtYWxpemVkKCkgJiYgb3duZXJOb2RlICE9IG51bGwpIHsKLSAgICAgICAgICAgIG93bmVyTm9kZS5pc05vcm1hbGl6ZWQoZmFsc2UpOwotICAgICAgICB9Ci0gICAgICAgIGZsYWdzID0gKHNob3J0KSAodmFsdWUgPyAgZmxhZ3MgfCBOT1JNQUxJWkVEIDogZmxhZ3MgJiB+Tk9STUFMSVpFRCk7Ci0gICAgfQotCi0gICAgZmluYWwgYm9vbGVhbiBpc0lkQXR0cmlidXRlKCkgewotICAgICAgICByZXR1cm4gKGZsYWdzICYgSUQpICE9IDA7Ci0gICAgfQotCi0gICAgZmluYWwgdm9pZCBpc0lkQXR0cmlidXRlKGJvb2xlYW4gdmFsdWUpIHsKLSAgICAgICAgZmxhZ3MgPSAoc2hvcnQpICh2YWx1ZSA/IGZsYWdzIHwgSUQgOiBmbGFncyAmIH5JRCk7Ci0gICAgfQotCi0gICAgLy8KLSAgICAvLyBPYmplY3QgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKiogTk9OLURPTSBtZXRob2QgZm9yIGRlYnVnZ2luZyBjb252ZW5pZW5jZS4gKi8KLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgICAgICByZXR1cm4gIlsiK2dldE5vZGVOYW1lKCkrIjogIitnZXROb2RlVmFsdWUoKSsiXSI7Ci0gICAgfQotCi0gICAgLy8KLSAgICAvLyBTZXJpYWxpemF0aW9uIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqIFNlcmlhbGl6ZSBvYmplY3QuICovCi0gICAgcHJpdmF0ZSB2b2lkIHdyaXRlT2JqZWN0KE9iamVjdE91dHB1dFN0cmVhbSBvdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy8gc3luY2hyb25pemUgZGF0YQotICAgICAgICBpZiAobmVlZHNTeW5jRGF0YSgpKSB7Ci0gICAgICAgICAgICBzeW5jaHJvbml6ZURhdGEoKTsKLSAgICAgICAgfQotICAgICAgICAvLyB3cml0ZSBvYmplY3QKLSAgICAgICAgb3V0LmRlZmF1bHRXcml0ZU9iamVjdCgpOwotCi0gICAgfSAvLyB3cml0ZU9iamVjdChPYmplY3RPdXRwdXRTdHJlYW0pCi0KLX0gLy8gY2xhc3MgTm9kZUltcGwKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9Ob2RlSXRlcmF0b3JJbXBsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vTm9kZUl0ZXJhdG9ySW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxZjE3ZDQ3Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9Ob2RlSXRlcmF0b3JJbXBsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzNzQgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDAyLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tOwotCi1pbXBvcnQgb3JnLnczYy5kb20uRE9NRXhjZXB0aW9uOwotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci1pbXBvcnQgb3JnLnczYy5kb20udHJhdmVyc2FsLk5vZGVGaWx0ZXI7Ci1pbXBvcnQgb3JnLnczYy5kb20udHJhdmVyc2FsLk5vZGVJdGVyYXRvcjsKLQotCi0vKiogRGVmYXVsdE5vZGVJdGVyYXRvciBpbXBsZW1lbnRzIGEgTm9kZUl0ZXJhdG9yLCB3aGljaCBpdGVyYXRlcyBhCi0gKiAgRE9NIHRyZWUgaW4gdGhlIGV4cGVjdGVkIGRlcHRoIGZpcnN0IHdheS4KLSAqCi0gKiAgPHA+VGhlIHdoYXRUb1Nob3cgYW5kIGZpbHRlciBmdW5jdGlvbmFsaXR5IGlzIGltcGxlbWVudGVkIGFzIGV4cGVjdGVkLgotICoKLSAqICA8cD5UaGlzIGNsYXNzIGFsc28gaGFzIG1ldGhvZCByZW1vdmVOb2RlIHRvIGVuYWJsZSBpdGVyYXRvciAiZml4LXVwIgotICogIG9uIERPTSByZW1vdmUuIEl0IGlzIGV4cGVjdGVkIHRoYXQgdGhlIERPTSBpbXBsZW1lbnRhdGlvbiBjYWxsIHJlbW92ZU5vZGUKLSAqICByaWdodCBiZWZvcmUgdGhlIGFjdHVhbCBET00gdHJhbnNmb3JtYXRpb24uIElmIG5vdCBjYWxsZWQgYnkgdGhlIERPTSwKLSAqICB0aGUgY2xpZW50IGNvdWxkIGNhbGwgaXQgYmVmb3JlIGRvaW5nIHRoZSByZW1vdmFsLgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKi8KLXB1YmxpYyBjbGFzcyBOb2RlSXRlcmF0b3JJbXBsIGltcGxlbWVudHMgTm9kZUl0ZXJhdG9yIHsKLQotICAgIC8vCi0gICAgLy8gRGF0YQotICAgIC8vCi0KLSAgICAvKiogVGhlIERvY3VtZW50SW1wbCB3aGljaCBjcmVhdGVkIHRoaXMgaXRlcmF0b3IsIHNvIGl0IGNhbiBiZSBkZXRhY2hlZC4gKi8KLSAgICBwcml2YXRlIERvY3VtZW50SW1wbCBmRG9jdW1lbnQ7Ci0gICAgLyoqIFRoZSByb290LiAqLwotICAgIHByaXZhdGUgTm9kZSBmUm9vdDsKLSAgICAvKiogVGhlIHdoYXRUb1Nob3cgbWFzay4gKi8KLSAgICBwcml2YXRlIGludCBmV2hhdFRvU2hvdyA9IE5vZGVGaWx0ZXIuU0hPV19BTEw7Ci0gICAgLyoqIFRoZSBOb2RlRmlsdGVyIHJlZmVyZW5jZS4gKi8KLSAgICBwcml2YXRlIE5vZGVGaWx0ZXIgZk5vZGVGaWx0ZXI7Ci0gICAgLyoqIElmIGRldGFjaCBpcyBjYWxsZWQsIHRoZSBmRGV0YWNoIGZsYWcgaXMgdHJ1ZSwgb3RoZXJ3aXNlIGZsYXNlLiAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBmRGV0YWNoID0gZmFsc2U7Ci0KLSAgICAvLwotICAgIC8vIEl0ZXJhdG9yIHN0YXRlIC0gY3VycmVudCBub2RlIGFuZCBkaXJlY3Rpb24uCi0gICAgLy8KLSAgICAvLyBOb3RlOiBUaGUgY3VycmVudCBub2RlIGFuZCBkaXJlY3Rpb24gYXJlIHN1ZmZpY2llbnQgdG8gaW1wbGVtZW50Ci0gICAgLy8gdGhlIGRlc2lyZWQgYmVoYXZpb3VyIG9mIHRoZSBjdXJyZW50IHBvaW50ZXIgYmVpbmcgX2JldHdlZW5fCi0gICAgLy8gdHdvIG5vZGVzLiBUaGUgZkN1cnJlbnROb2RlIGlzIGFjdHVhbGx5IHRoZSBsYXN0IG5vZGUgcmV0dXJuZWQsCi0gICAgLy8gYW5kIHRoZQotICAgIC8vIGRpcmVjdGlvbiBpcyB3aGV0aGVyIHRoZSBwb2ludGVyIGlzIGluIGZyb250IG9yIGJlaGluZCB0aGlzIG5vZGUuCi0gICAgLy8gKHVzdWFsbHkgYWtpbiB0byB3aGV0aGVyIHRoZSBub2RlIHdhcyByZXR1cm5lZCB2aWEgbmV4dE5vZGUoKSkKLSAgICAvLyAoZWcgZkZvcndhcmQgPSB0cnVlKSBvciBwcmV2aW91c05vZGUoKSAoZWcgZkZvcndhcmQgPSBmYWxzZSkuCi0gICAgLy8gTm90ZSBhbHNvLCBpZiByZW1vdmluZyBhIE5vZGUsIHRoZSBmQ3VycmVudE5vZGUKLSAgICAvLyBjYW4gYmUgcGxhY2VkIG9uIGEgTm9kZSB3aGljaCB3b3VsZCBub3QgcGFzcyBmaWx0ZXJzLgotCi0gICAgLyoqIFRoZSBsYXN0IE5vZGUgcmV0dXJuZWQuICovCi0gICAgcHJpdmF0ZSBOb2RlIGZDdXJyZW50Tm9kZTsKLQotICAgIC8qKiBUaGUgZGlyZWN0aW9uIG9mIHRoZSBpdGVyYXRvciBvbiB0aGUgZkN1cnJlbnROb2RlLgotICAgICAqICA8cHJlPgotICAgICAqICBuZXh0Tm9kZSgpICA9PSAgICAgIGZGb3J3YXJkID0gdHJ1ZTsKLSAgICAgKiAgcHJldmlvdXNOb2RlKCkgPT0gICBmRm9yd2FyZCA9IGZhbHNlOwotICAgICAqICA8L3ByZT4KLSAgICAgKi8KLSAgICBwcml2YXRlIGJvb2xlYW4gZkZvcndhcmQgPSB0cnVlOwotCi0gICAgLyoqIFdoZW4gVFJVRSwgdGhlIGNoaWxkcmVuIG9mIGVudGl0ZXMgcmVmZXJlbmNlcyBhcmUgcmV0dXJuZWQgaW4gdGhlIGl0ZXJhdG9yLiAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBmRW50aXR5UmVmZXJlbmNlRXhwYW5zaW9uOwotCi0gICAgLy8KLSAgICAvLyBDb25zdHJ1Y3RvcgotICAgIC8vCi0KLSAgICAvKiogUHVibGljIGNvbnN0cnVjdG9yICovCi0gICAgcHVibGljIE5vZGVJdGVyYXRvckltcGwoIERvY3VtZW50SW1wbCBkb2N1bWVudCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTm9kZSByb290LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgd2hhdFRvU2hvdywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTm9kZUZpbHRlciBub2RlRmlsdGVyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGVudGl0eVJlZmVyZW5jZUV4cGFuc2lvbikgewotICAgICAgICBmRG9jdW1lbnQgPSBkb2N1bWVudDsKLSAgICAgICAgZlJvb3QgPSByb290OwotICAgICAgICBmQ3VycmVudE5vZGUgPSBudWxsOwotICAgICAgICBmV2hhdFRvU2hvdyA9IHdoYXRUb1Nob3c7Ci0gICAgICAgIGZOb2RlRmlsdGVyID0gbm9kZUZpbHRlcjsKLSAgICAgICAgZkVudGl0eVJlZmVyZW5jZUV4cGFuc2lvbiA9IGVudGl0eVJlZmVyZW5jZUV4cGFuc2lvbjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgTm9kZSBnZXRSb290KCkgewotICAgICAgICByZXR1cm4gZlJvb3Q7Ci0gICAgfQotCi0gICAgLy8gSW1wbGVtZW50YXRpb24gTm90ZTogTm90ZSB0aGF0IHRoZSBpdGVyYXRvciBsb29rcyBhdCB3aGF0VG9TaG93Ci0gICAgLy8gYW5kIGZpbHRlciB2YWx1ZXMgYXQgZWFjaCBjYWxsLCBhbmQgdGhlcmVmb3JlIG9uZSBfY291bGRfIGFkZAotICAgIC8vIHNldHRlcnMgZm9yIHRoZXNlIHZhbHVlcyBhbmQgYWx0ZXIgdGhlbSB3aGlsZSBpdGVyYXRpbmchCi0KLSAgICAvKiogUmV0dXJuIHRoZSB3aGF0VG9TaG93IHZhbHVlICovCi0gICAgcHVibGljIGludCAgICAgICAgICAgICAgICBnZXRXaGF0VG9TaG93KCkgewotICAgICAgICByZXR1cm4gZldoYXRUb1Nob3c7Ci0gICAgfQotCi0gICAgLyoqIFJldHVybiB0aGUgZmlsdGVyICovCi0gICAgcHVibGljIE5vZGVGaWx0ZXIgICAgICAgICBnZXRGaWx0ZXIoKSB7Ci0gICAgICAgIHJldHVybiBmTm9kZUZpbHRlcjsKLSAgICB9Ci0KLSAgICAvKiogUmV0dXJuIHdoZXRoZXIgY2hpbGRyZW4gZW50aXR5IHJlZmVyZW5jZXMgYXJlIGluY2x1ZGVkIGluIHRoZSBpdGVyYXRvci4gKi8KLSAgICBwdWJsaWMgYm9vbGVhbiAgICAgICAgICAgIGdldEV4cGFuZEVudGl0eVJlZmVyZW5jZXMoKSB7Ci0gICAgICAgIHJldHVybiBmRW50aXR5UmVmZXJlbmNlRXhwYW5zaW9uOwotICAgIH0KLQotICAgIC8qKiBSZXR1cm4gdGhlIG5leHQgTm9kZSBpbiB0aGUgSXRlcmF0b3IuIFRoZSBub2RlIGlzIHRoZSBuZXh0IG5vZGUgaW4KLSAgICAgKiAgZGVwdGgtZmlyc3Qgb3JkZXIgd2hpY2ggYWxzbyBwYXNzZXMgdGhlIGZpbHRlciwgYW5kIHdoYXRUb1Nob3cuCi0gICAgICogIElmIHRoZXJlIGlzIG5vIG5leHQgbm9kZSB3aGljaCBwYXNzZXMgdGhlc2UgY3JpdGVyaWEsIHRoZW4gcmV0dXJuIG51bGwuCi0gICAgICovCi0gICAgcHVibGljIE5vZGUgICAgICAgICAgICAgICBuZXh0Tm9kZSgpIHsKLQotICAgICAgICBpZiggZkRldGFjaCkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgRE9NRXhjZXB0aW9uLklOVkFMSURfU1RBVEVfRVJSLAotICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sICJJTlZBTElEX1NUQVRFX0VSUiIsIG51bGwpKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIGlmIHJvb3QgaXMgbnVsbCB0aGVyZSBpcyBubyBuZXh0IG5vZGUuCi0gICAgICAgIGlmIChmUm9vdCA9PSBudWxsKSByZXR1cm4gbnVsbDsKLQotICAgICAgICBOb2RlIG5leHROb2RlID0gZkN1cnJlbnROb2RlOwotICAgICAgICBib29sZWFuIGFjY2VwdGVkID0gZmFsc2U7IC8vIHRoZSBuZXh0IG5vZGUgaGFzIG5vdCBiZWVuIGFjY2VwdGVkLgotCi0gICAgICAgIGFjY2VwdGVkX2xvb3A6Ci0gICAgICAgIHdoaWxlICghYWNjZXB0ZWQpIHsKLQotICAgICAgICAgICAgLy8gaWYgbGFzdCBkaXJlY3Rpb24gaXMgbm90IGZvcndhcmQsIHJlcGVhdCBub2RlLgotICAgICAgICAgICAgaWYgKCFmRm9yd2FyZCAmJiBuZXh0Tm9kZSE9bnVsbCkgewotICAgICAgICAgICAgICAgIC8vU3lzdGVtLm91dC5wcmludGxuKCJuZXh0Tm9kZSgpOiFmRm9yd2FyZDoiK2ZDdXJyZW50Tm9kZS5nZXROb2RlTmFtZSgpKTsKLSAgICAgICAgICAgICAgICBuZXh0Tm9kZSA9IGZDdXJyZW50Tm9kZTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAvLyBlbHNlIGdldCB0aGUgbmV4dCBub2RlIHZpYSBkZXB0aC1maXJzdAotICAgICAgICAgICAgICAgIGlmICghZkVudGl0eVJlZmVyZW5jZUV4cGFuc2lvbgotICAgICAgICAgICAgICAgICAgICAmJiBuZXh0Tm9kZSAhPSBudWxsCi0gICAgICAgICAgICAgICAgICAgICYmIG5leHROb2RlLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5FTlRJVFlfUkVGRVJFTkNFX05PREUpIHsKLSAgICAgICAgICAgICAgICAgICAgbmV4dE5vZGUgPSBuZXh0Tm9kZShuZXh0Tm9kZSwgZmFsc2UpOwotICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIG5leHROb2RlID0gbmV4dE5vZGUobmV4dE5vZGUsIHRydWUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgZkZvcndhcmQgPSB0cnVlOyAvL1JFVklTVDogc2hvdWxkIGRpcmVjdGlvbiBiZSBzZXQgZm9yd2FyZCBiZWZvcmUgbnVsbCBjaGVjaz8KLQotICAgICAgICAgICAgLy8gbm90aGluZyBpbiB0aGUgbGlzdC4gcmV0dXJuIG51bGwuCi0gICAgICAgICAgICBpZiAobmV4dE5vZGUgPT0gbnVsbCkgcmV0dXJuIG51bGw7Ci0KLSAgICAgICAgICAgIC8vIGRvZXMgbm9kZSBwYXNzIHRoZSBmaWx0ZXJzIGFuZCB3aGF0VG9TaG93PwotICAgICAgICAgICAgYWNjZXB0ZWQgPSBhY2NlcHROb2RlKG5leHROb2RlKTsKLSAgICAgICAgICAgIGlmIChhY2NlcHRlZCkgewotICAgICAgICAgICAgICAgIC8vIGlmIHNvLCB0aGVuIHRoZSBub2RlIGlzIHRoZSBjdXJyZW50IG5vZGUuCi0gICAgICAgICAgICAgICAgZkN1cnJlbnROb2RlID0gbmV4dE5vZGU7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZDdXJyZW50Tm9kZTsKLSAgICAgICAgICAgIH0gZWxzZQotICAgICAgICAgICAgICAgIGNvbnRpbnVlIGFjY2VwdGVkX2xvb3A7Ci0KLSAgICAgICAgfSAvLyB3aGlsZSAoIWFjY2VwdGVkKSB7Ci0KLSAgICAgICAgLy8gbm8gbm9kZXMsIG9yIG5vIGFjY2VwdGVkIG5vZGVzLgotICAgICAgICByZXR1cm4gbnVsbDsKLQotICAgIH0KLQotICAgIC8qKiBSZXR1cm4gdGhlIHByZXZpb3VzIE5vZGUgaW4gdGhlIEl0ZXJhdG9yLiBUaGUgbm9kZSBpcyB0aGUgbmV4dCBub2RlIGluCi0gICAgICogIF9iYWNrd2FyZHNfIGRlcHRoLWZpcnN0IG9yZGVyIHdoaWNoIGFsc28gcGFzc2VzIHRoZSBmaWx0ZXIsIGFuZCB3aGF0VG9TaG93LgotICAgICAqLwotICAgIHB1YmxpYyBOb2RlICAgICAgICAgICAgICAgcHJldmlvdXNOb2RlKCkgewotCi0gICAgICAgIGlmKCBmRGV0YWNoKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICBET01FeGNlcHRpb24uSU5WQUxJRF9TVEFURV9FUlIsCi0gICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwgIklOVkFMSURfU1RBVEVfRVJSIiwgbnVsbCkpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gaWYgdGhlIHJvb3QgaXMgbnVsbCwgb3IgdGhlIGN1cnJlbnQgbm9kZSBpcyBudWxsLCByZXR1cm4gbnVsbC4KLSAgICAgICAgaWYgKGZSb290ID09IG51bGwgfHwgZkN1cnJlbnROb2RlID09IG51bGwpIHJldHVybiBudWxsOwotCi0gICAgICAgIE5vZGUgcHJldmlvdXNOb2RlID0gZkN1cnJlbnROb2RlOwotICAgICAgICBib29sZWFuIGFjY2VwdGVkID0gZmFsc2U7Ci0KLSAgICAgICAgYWNjZXB0ZWRfbG9vcDoKLSAgICAgICAgd2hpbGUgKCFhY2NlcHRlZCkgewotCi0gICAgICAgICAgICBpZiAoZkZvcndhcmQgJiYgcHJldmlvdXNOb2RlICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAvL3JlcGVhdCBsYXN0IG5vZGUuCi0gICAgICAgICAgICAgICAgcHJldmlvdXNOb2RlID0gZkN1cnJlbnROb2RlOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAvLyBnZXQgcHJldmlvdXMgbm9kZSBpbiBiYWNrd2FyZHMgZGVwdGggZmlyc3Qgb3JkZXIuCi0gICAgICAgICAgICAgICAgcHJldmlvdXNOb2RlID0gcHJldmlvdXNOb2RlKHByZXZpb3VzTm9kZSk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIHdlIGFyZSBnb2luZyBiYWNrd2FyZHMKLSAgICAgICAgICAgIGZGb3J3YXJkID0gZmFsc2U7Ci0KLSAgICAgICAgICAgIC8vIGlmIHRoZSBuZXcgcHJldmlvdXMgbm9kZSBpcyBudWxsLCB3ZSdyZSBhdCBoZWFkIG9yIHBhc3QgdGhlIHJvb3QsCi0gICAgICAgICAgICAvLyBzbyByZXR1cm4gbnVsbC4KLSAgICAgICAgICAgIGlmIChwcmV2aW91c05vZGUgPT0gbnVsbCkgcmV0dXJuIG51bGw7Ci0KLSAgICAgICAgICAgIC8vIGNoZWNrIGlmIG5vZGUgcGFzc2VzIGZpbHRlcnMgYW5kIHdoYXRUb1Nob3cuCi0gICAgICAgICAgICBhY2NlcHRlZCA9IGFjY2VwdE5vZGUocHJldmlvdXNOb2RlKTsKLSAgICAgICAgICAgIGlmIChhY2NlcHRlZCkgewotICAgICAgICAgICAgICAgIC8vIGlmIGFjY2VwdGVkLCB1cGRhdGUgdGhlIGN1cnJlbnQgbm9kZSwgYW5kIHJldHVybiBpdC4KLSAgICAgICAgICAgICAgICBmQ3VycmVudE5vZGUgPSBwcmV2aW91c05vZGU7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZDdXJyZW50Tm9kZTsKLSAgICAgICAgICAgIH0gZWxzZQotICAgICAgICAgICAgICAgIGNvbnRpbnVlIGFjY2VwdGVkX2xvb3A7Ci0gICAgICAgIH0KLSAgICAgICAgLy8gdGhlcmUgYXJlIG5vIG5vZGVzPwotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICAvKiogVGhlIG5vZGUgaXMgYWNjZXB0ZWQgaWYgaXQgcGFzc2VzIHRoZSB3aGF0VG9TaG93IGFuZCB0aGUgZmlsdGVyLiAqLwotICAgIGJvb2xlYW4gYWNjZXB0Tm9kZShOb2RlIG5vZGUpIHsKLQotICAgICAgICBpZiAoZk5vZGVGaWx0ZXIgPT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuICggZldoYXRUb1Nob3cgJiAoMSA8PCBub2RlLmdldE5vZGVUeXBlKCktMSkpICE9IDAgOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgcmV0dXJuICgoZldoYXRUb1Nob3cgJiAoMSA8PCBub2RlLmdldE5vZGVUeXBlKCktMSkpICE9IDAgKQotICAgICAgICAgICAgICAgICYmIGZOb2RlRmlsdGVyLmFjY2VwdE5vZGUobm9kZSkgPT0gTm9kZUZpbHRlci5GSUxURVJfQUNDRVBUOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqIFJldHVybiBub2RlLCBpZiBtYXRjaGVzIG9yIGFueSBwYXJlbnQgaWYgbWF0Y2hlcy4gKi8KLSAgICBOb2RlIG1hdGNoTm9kZU9yUGFyZW50KE5vZGUgbm9kZSkgewotICAgICAgICAvLyBBZGRpdGlvbnMgYW5kIHJlbW92YWxzIGluIHRoZSB1bmRlcmx5aW5nIGRhdGEgc3RydWN0dXJlIG1heSBvY2N1cgotICAgICAgICAvLyBiZWZvcmUgYW55IGl0ZXJhdGlvbnMsIGFuZCBpbiB0aGlzIGNhc2UgdGhlIHJlZmVyZW5jZV9ub2RlIGlzIG51bGwuCi0gICAgICAgIGlmIChmQ3VycmVudE5vZGUgPT0gbnVsbCkgcmV0dXJuIG51bGw7Ci0KLSAgICAgICAgLy8gY2hlY2sgaWYgdGhlIHJlbW92ZWQgbm9kZSBpcyBhbiBfYW5jZXN0b3JfIG9mIHRoZQotICAgICAgICAvLyByZWZlcmVuY2Ugbm9kZQotICAgICAgICBmb3IgKE5vZGUgbiA9IGZDdXJyZW50Tm9kZTsgbiAhPSBmUm9vdDsgbiA9IG4uZ2V0UGFyZW50Tm9kZSgpKSB7Ci0gICAgICAgICAgICBpZiAobm9kZSA9PSBuKSByZXR1cm4gbjsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICAvKiogVGhlIG1ldGhvZCBuZXh0Tm9kZShOb2RlLCBib29sZWFuKSByZXR1cm5zIHRoZSBuZXh0IG5vZGUKLSAgICAgKiAgZnJvbSB0aGUgYWN0dWFsIERPTSB0cmVlLgotICAgICAqCi0gICAgICogIFRoZSBib29sZWFuIHZpc2l0Q2hpbGRyZW4gZGV0ZXJtaW5lcyB3aGV0aGVyIHRvIHZpc2l0IHRoZSBjaGlsZHJlbi4KLSAgICAgKiAgVGhlIHJlc3VsdCBpcyB0aGUgbmV4dE5vZGUuCi0gICAgICovCi0gICAgTm9kZSBuZXh0Tm9kZShOb2RlIG5vZGUsIGJvb2xlYW4gdmlzaXRDaGlsZHJlbikgewotCi0gICAgICAgIGlmIChub2RlID09IG51bGwpIHJldHVybiBmUm9vdDsKLQotICAgICAgICBOb2RlIHJlc3VsdDsKLSAgICAgICAgLy8gb25seSBjaGVjayBjaGlsZHJlbiBpZiB3ZSB2aXNpdCBjaGlsZHJlbi4KLSAgICAgICAgaWYgKHZpc2l0Q2hpbGRyZW4pIHsKLSAgICAgICAgICAgIC8vaWYgaGFzQ2hpbGRyZW4sIHJldHVybiAxc3QgY2hpbGQuCi0gICAgICAgICAgICBpZiAobm9kZS5oYXNDaGlsZE5vZGVzKCkpIHsKLSAgICAgICAgICAgICAgICByZXN1bHQgPSBub2RlLmdldEZpcnN0Q2hpbGQoKTsKLSAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0OwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKG5vZGUgPT0gZlJvb3QpIHsgLy9pZiBSb290IGhhcyBubyBraWRzCi0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIGlmIGhhc1NpYmxpbmcsIHJldHVybiBzaWJsaW5nCi0gICAgICAgIHJlc3VsdCA9IG5vZGUuZ2V0TmV4dFNpYmxpbmcoKTsKLSAgICAgICAgaWYgKHJlc3VsdCAhPSBudWxsKSByZXR1cm4gcmVzdWx0OwotCi0KLSAgICAgICAgLy8gcmV0dXJuIHBhcmVudCdzIDFzdCBzaWJsaW5nLgotICAgICAgICBOb2RlIHBhcmVudCA9IG5vZGUuZ2V0UGFyZW50Tm9kZSgpOwotICAgICAgICB3aGlsZSAocGFyZW50ICE9IG51bGwgJiYgcGFyZW50ICE9IGZSb290KSB7Ci0gICAgICAgICAgICByZXN1bHQgPSBwYXJlbnQuZ2V0TmV4dFNpYmxpbmcoKTsKLSAgICAgICAgICAgIGlmIChyZXN1bHQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIHBhcmVudCA9IHBhcmVudC5nZXRQYXJlbnROb2RlKCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgfSAvLyB3aGlsZSAocGFyZW50ICE9IG51bGwgJiYgcGFyZW50ICE9IGZSb290KSB7Ci0KLSAgICAgICAgLy8gZW5kIG9mIGxpc3QsIHJldHVybiBudWxsCi0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKiBUaGUgbWV0aG9kIHByZXZpb3VzTm9kZShOb2RlKSByZXR1cm5zIHRoZSBwcmV2aW91cyBub2RlCi0gICAgICogIGZyb20gdGhlIGFjdHVhbCBET00gdHJlZS4KLSAgICAgKi8KLSAgICBOb2RlIHByZXZpb3VzTm9kZShOb2RlIG5vZGUpIHsKLQotICAgICAgICBOb2RlIHJlc3VsdDsKLQotICAgICAgICAvLyBpZiB3ZSdyZSBhdCB0aGUgcm9vdCwgcmV0dXJuIG51bGwuCi0gICAgICAgIGlmIChub2RlID09IGZSb290KSByZXR1cm4gbnVsbDsKLQotICAgICAgICAvLyBnZXQgc2libGluZwotICAgICAgICByZXN1bHQgPSBub2RlLmdldFByZXZpb3VzU2libGluZygpOwotICAgICAgICBpZiAocmVzdWx0ID09IG51bGwpIHsKLSAgICAgICAgICAgIC8vaWYgMXN0IHNpYmxpbmcsIHJldHVybiBwYXJlbnQKLSAgICAgICAgICAgIHJlc3VsdCA9IG5vZGUuZ2V0UGFyZW50Tm9kZSgpOwotICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIGlmIHNpYmxpbmcgaGFzIGNoaWxkcmVuLCBrZWVwIGdldHRpbmcgbGFzdCBjaGlsZCBvZiBjaGlsZC4KLSAgICAgICAgaWYgKHJlc3VsdC5oYXNDaGlsZE5vZGVzKCkKLSAgICAgICAgICAgICYmICEoIWZFbnRpdHlSZWZlcmVuY2VFeHBhbnNpb24KLSAgICAgICAgICAgICAgICAmJiByZXN1bHQgIT0gbnVsbAotICAgICAgICAgICAgICAgICYmIHJlc3VsdC5nZXROb2RlVHlwZSgpID09IE5vZGUuRU5USVRZX1JFRkVSRU5DRV9OT0RFKSkKLQotICAgICAgICB7Ci0gICAgICAgICAgICB3aGlsZSAocmVzdWx0Lmhhc0NoaWxkTm9kZXMoKSkgewotICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdC5nZXRMYXN0Q2hpbGQoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiByZXN1bHQ7Ci0gICAgfQotCi0gICAgLyoqIEZpeC11cCB0aGUgaXRlcmF0b3Igb24gYSByZW1vdmUuIENhbGxlZCBieSBET00gb3Igb3RoZXJ3aXNlLAotICAgICAqICBiZWZvcmUgYW4gYWN0dWFsIERPTSByZW1vdmUuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcmVtb3ZlTm9kZShOb2RlIG5vZGUpIHsKLQotICAgICAgICAvLyBJbXBsZW1lbnRhdGlvbiBub3RlOiBGaXgtdXAgbWVhbnMgc2V0dGluZyB0aGUgY3VycmVudCBub2RlIHByb3Blcmx5Ci0gICAgICAgIC8vIGFmdGVyIGEgcmVtb3ZlLgotCi0gICAgICAgIGlmIChub2RlID09IG51bGwpIHJldHVybjsKLQotICAgICAgICBOb2RlIGRlbGV0ZWQgPSBtYXRjaE5vZGVPclBhcmVudChub2RlKTsKLQotICAgICAgICBpZiAoZGVsZXRlZCA9PSBudWxsKSByZXR1cm47Ci0KLSAgICAgICAgaWYgKGZGb3J3YXJkKSB7Ci0gICAgICAgICAgICBmQ3VycmVudE5vZGUgPSBwcmV2aW91c05vZGUoZGVsZXRlZCk7Ci0gICAgICAgIH0gZWxzZQotICAgICAgICAvLyBpZiAoIWZGb3J3YXJkKQotICAgICAgICB7Ci0gICAgICAgICAgICBOb2RlIG5leHQgPSBuZXh0Tm9kZShkZWxldGVkLCBmYWxzZSk7Ci0gICAgICAgICAgICBpZiAobmV4dCE9bnVsbCkgewotICAgICAgICAgICAgICAgIC8vIG5vcm1hbCBjYXNlOiB0aGVyZSBfYXJlXyBub2RlcyBmb2xsb3dpbmcgdGhpcyBpbiB0aGUgaXRlcmF0b3IuCi0gICAgICAgICAgICAgICAgZkN1cnJlbnROb2RlID0gbmV4dDsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgLy8gdGhlIGxhc3Qgbm9kZSBpbiB0aGUgaXRlcmF0b3IgaXMgdG8gYmUgcmVtb3ZlZCwKLSAgICAgICAgICAgICAgICAvLyBzbyB3ZSBzZXQgdGhlIGN1cnJlbnQgbm9kZSB0byBiZSB0aGUgcHJldmlvdXMgb25lLgotICAgICAgICAgICAgICAgIGZDdXJyZW50Tm9kZSA9IHByZXZpb3VzTm9kZShkZWxldGVkKTsKLSAgICAgICAgICAgICAgICBmRm9yd2FyZCA9IHRydWU7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgfQotCi0gICAgfQotCi0gICAgcHVibGljIHZvaWQgICAgICAgICAgICAgICBkZXRhY2goKSB7Ci0gICAgICAgIGZEZXRhY2ggPSB0cnVlOwotICAgICAgICBmRG9jdW1lbnQucmVtb3ZlTm9kZUl0ZXJhdG9yKHRoaXMpOwotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL05vZGVMaXN0Q2FjaGUuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9Ob2RlTGlzdENhY2hlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGUwOTIzY2UuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL05vZGVMaXN0Q2FjaGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDU5ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEsMjAwMiwyMDA0LDIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tOwotCi1pbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7Ci0KLS8qKgotICogVGhpcyBjbGFzcyBpcyB1c2VkLCB2aWEgYSBwb29sIG1hbmFnZWQgb24gQ29yZURvY3VtZW50SW1wbCwgaW4gUGFyZW50Tm9kZSB0bwotICogaW1wcm92ZSBwZXJmb3JtYW5jZSBvZiB0aGUgTm9kZUxpc3QgYWNjZXNzb3JzLCBnZXRMZW5ndGgoKSBhbmQgaXRlbShpKS4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBBcm5hdWQgIExlIEhvcnMsIElCTQotICoKLSAqIEB2ZXJzaW9uICRJZDogTm9kZUxpc3RDYWNoZS5qYXZhLHYgMS42IDIwMTAvMDcvMjAgMjA6MjU6MjUgam9laHcgRXhwICQKLSAqLwotY2xhc3MgTm9kZUxpc3RDYWNoZSBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZSB7Ci0KLSAgICAvKiogU2VyaWFsaXphdGlvbiB2ZXJzaW9uLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC03OTI3NTI5MjU0OTE4NjMxMDAyTDsKLQotICAgIC8qKiBDYWNoZWQgbm9kZSBsaXN0IGxlbmd0aC4gKi8KLSAgICBpbnQgZkxlbmd0aCA9IC0xOwotCi0gICAgLyoqIExhc3QgcmVxdWVzdGVkIG5vZGUgaW5kZXguICovCi0gICAgaW50IGZDaGlsZEluZGV4ID0gLTE7Ci0KLSAgICAvKiogTGFzdCByZXF1ZXN0ZWQgbm9kZS4gKi8KLSAgICBDaGlsZE5vZGUgZkNoaWxkOwotCi0gICAgLyoqIE93bmVyIG9mIHRoaXMgY2FjaGUgKi8KLSAgICBQYXJlbnROb2RlIGZPd25lcjsKLQotICAgIC8qKiBQb2ludGVyIHRvIHRoZSBuZXh0IG9iamVjdCBvbiB0aGUgbGlzdCwKLSAgICAgICAgb25seSBtZWFuaW5nZnVsIHdoZW4gYWN0dWxseSBzdG9yZWQgaW4gdGhlIGZyZWUgbGlzdC4gKi8KLSAgICBOb2RlTGlzdENhY2hlIG5leHQ7Ci0KLSAgICBOb2RlTGlzdENhY2hlKFBhcmVudE5vZGUgb3duZXIpIHsKLSAgICAgICAgZk93bmVyID0gb3duZXI7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL05vdGF0aW9uSW1wbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL05vdGF0aW9uSW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhODgyN2Y0Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9Ob3RhdGlvbkltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIxMiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5kb207Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuVVJJOwotaW1wb3J0IG9yZy53M2MuZG9tLkRPTUV4Y2VwdGlvbjsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotaW1wb3J0IG9yZy53M2MuZG9tLk5vdGF0aW9uOwotCi0vKioKLSAqIE5vdGF0aW9ucyBhcmUgaG93IHRoZSBEb2N1bWVudCBUeXBlIERlc2NyaXB0aW9uIChEVEQpIHJlY29yZHMgaGludHMKLSAqIGFib3V0IHRoZSBmb3JtYXQgb2YgYW4gWE1MICJ1bnBhcnNlZCBlbnRpdHkiIC0tIGluIG90aGVyIHdvcmRzLAotICogbm9uLVhNTCBkYXRhIGJvdW5kIHRvIHRoaXMgZG9jdW1lbnQgdHlwZSwgd2hpY2ggc29tZSBhcHBsaWNhdGlvbnMKLSAqIG1heSB3aXNoIHRvIGNvbnN1bHQgd2hlbiBtYW5pcHVsYXRpbmcgdGhlIGRvY3VtZW50LiBBIE5vdGF0aW9uCi0gKiByZXByZXNlbnRzIGEgbmFtZS12YWx1ZSBwYWlyLCB3aXRoIGl0cyBub2RlTmFtZSBiZWluZyBzZXQgdG8gdGhlCi0gKiBkZWNsYXJlZCBuYW1lIG9mIHRoZSBub3RhdGlvbi4KLSAqIDxQPgotICogTm90YXRpb25zIGFyZSBhbHNvIHVzZWQgdG8gZm9ybWFsbHkgZGVjbGFyZSB0aGUgInRhcmdldHMiIG9mCi0gKiBQcm9jZXNzaW5nIEluc3RydWN0aW9ucy4KLSAqIDxQPgotICogTm90ZSB0aGF0IHRoZSBOb3RhdGlvbidzIGRhdGEgaXMgbm9uLURPTSBpbmZvcm1hdGlvbjsgdGhlIERPTSBvbmx5Ci0gKiByZWNvcmRzIHdoYXQgYW5kIHdoZXJlIGl0IGlzLgotICogPFA+Ci0gKiBTZWUgdGhlIFhNTCAxLjAgc3BlYywgc2VjdGlvbnMgNC43IGFuZCAyLjYsIGZvciBtb3JlIGluZm8uCi0gKiA8UD4KLSAqIExldmVsIDEgb2YgdGhlIERPTSBkb2VzIG5vdCBzdXBwb3J0IGVkaXRpbmcgTm90YXRpb24gY29udGVudHMuCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBzaW5jZSAgUFItRE9NLUxldmVsLTEtMTk5ODA4MTguCi0gKi8KLXB1YmxpYyBjbGFzcyBOb3RhdGlvbkltcGwKLSAgICBleHRlbmRzIE5vZGVJbXBsCi0gICAgaW1wbGVtZW50cyBOb3RhdGlvbiB7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0YW50cwotICAgIC8vCi0KLSAgICAvKiogU2VyaWFsaXphdGlvbiB2ZXJzaW9uLiAqLwotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNzY0NjMyMTk1ODkwNjU4NDAyTDsKLQotICAgIC8vCi0gICAgLy8gRGF0YQotICAgIC8vCi0KLSAgICAvKiogTm90YXRpb24gbmFtZS4gKi8KLSAgICBwcm90ZWN0ZWQgU3RyaW5nIG5hbWU7Ci0KLSAgICAvKiogUHVibGljIGlkZW50aWZpZXIuICovCi0gICAgcHJvdGVjdGVkIFN0cmluZyBwdWJsaWNJZDsKLQotICAgIC8qKiBTeXN0ZW0gaWRlbnRpZmllci4gKi8KLSAgICBwcm90ZWN0ZWQgU3RyaW5nIHN5c3RlbUlkOwotCi0gICAgLyoqIEJhc2UgVVJJKi8KLSAgICBwcm90ZWN0ZWQgU3RyaW5nIGJhc2VVUkk7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0cnVjdG9ycwotICAgIC8vCi0KLSAgICAvKiogRmFjdG9yeSBjb25zdHJ1Y3Rvci4gKi8KLSAgICBwdWJsaWMgTm90YXRpb25JbXBsKENvcmVEb2N1bWVudEltcGwgb3duZXJEb2MsIFN0cmluZyBuYW1lKSB7Ci0gICAgICAgIHN1cGVyKG93bmVyRG9jKTsKLSAgICAgICAgdGhpcy5uYW1lID0gbmFtZTsKLSAgICB9Ci0KLSAgICAvLwotICAgIC8vIE5vZGUgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBBIHNob3J0IGludGVnZXIgaW5kaWNhdGluZyB3aGF0IHR5cGUgb2Ygbm9kZSB0aGlzIGlzLiBUaGUgbmFtZWQKLSAgICAgKiBjb25zdGFudHMgZm9yIHRoaXMgdmFsdWUgYXJlIGRlZmluZWQgaW4gdGhlIG9yZy53M2MuZG9tLk5vZGUgaW50ZXJmYWNlLgotICAgICAqLwotICAgIHB1YmxpYyBzaG9ydCBnZXROb2RlVHlwZSgpIHsKLSAgICAgICAgcmV0dXJuIE5vZGUuTk9UQVRJT05fTk9ERTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBub3RhdGlvbiBuYW1lCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXROb2RlTmFtZSgpIHsKLSAgICAgICAgaWYgKG5lZWRzU3luY0RhdGEoKSkgewotICAgICAgICAgICAgc3luY2hyb25pemVEYXRhKCk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG5hbWU7Ci0gICAgfQotCi0gICAgLy8KLSAgICAvLyBOb3RhdGlvbiBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFRoZSBQdWJsaWMgSWRlbnRpZmllciBmb3IgdGhpcyBOb3RhdGlvbi4gSWYgbm8gcHVibGljIGlkZW50aWZpZXIKLSAgICAgKiB3YXMgc3BlY2lmaWVkLCB0aGlzIHdpbGwgYmUgbnVsbC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFB1YmxpY0lkKCkgewotCi0gICAgICAgIGlmIChuZWVkc1N5bmNEYXRhKCkpIHsKLSAgICAgICAgICAgIHN5bmNocm9uaXplRGF0YSgpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBwdWJsaWNJZDsKLQotICAgIH0gLy8gZ2V0UHVibGljSWQoKTpTdHJpbmcKLQotICAgIC8qKgotICAgICAqIFRoZSBTeXN0ZW0gSWRlbnRpZmllciBmb3IgdGhpcyBOb3RhdGlvbi4gSWYgbm8gc3lzdGVtIGlkZW50aWZpZXIKLSAgICAgKiB3YXMgc3BlY2lmaWVkLCB0aGlzIHdpbGwgYmUgbnVsbC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFN5c3RlbUlkKCkgewotCi0gICAgICAgIGlmIChuZWVkc1N5bmNEYXRhKCkpIHsKLSAgICAgICAgICAgIHN5bmNocm9uaXplRGF0YSgpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBzeXN0ZW1JZDsKLQotICAgIH0gLy8gZ2V0U3lzdGVtSWQoKTpTdHJpbmcKLQotICAgIC8vCi0gICAgLy8gUHVibGljIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogTk9OLURPTTogVGhlIFB1YmxpYyBJZGVudGlmaWVyIGZvciB0aGlzIE5vdGF0aW9uLiBJZiBubyBwdWJsaWMKLSAgICAgKiBpZGVudGlmaWVyIHdhcyBzcGVjaWZpZWQsIHRoaXMgd2lsbCBiZSBudWxsLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFB1YmxpY0lkKFN0cmluZyBpZCkgewotCi0gICAgICAgIGlmIChpc1JlYWRPbmx5KCkpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgIERPTUV4Y2VwdGlvbi5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIsCi0gICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwgIk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiIsIG51bGwpKTsKLSAgICAgICAgfQotICAgICAgICBpZiAobmVlZHNTeW5jRGF0YSgpKSB7Ci0gICAgICAgICAgICBzeW5jaHJvbml6ZURhdGEoKTsKLSAgICAgICAgfQotICAgICAgICBwdWJsaWNJZCA9IGlkOwotCi0gICAgfSAvLyBzZXRQdWJsaWNJZChTdHJpbmcpCi0KLSAgICAvKioKLSAgICAgKiBOT04tRE9NOiBUaGUgU3lzdGVtIElkZW50aWZpZXIgZm9yIHRoaXMgTm90YXRpb24uIElmIG5vIHN5c3RlbQotICAgICAqIGlkZW50aWZpZXIgd2FzIHNwZWNpZmllZCwgdGhpcyB3aWxsIGJlIG51bGwuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0U3lzdGVtSWQoU3RyaW5nIGlkKSB7Ci0KLSAgICAgICAgaWYoaXNSZWFkT25seSgpKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICBET01FeGNlcHRpb24uTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSLAotICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sICJOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIiLCBudWxsKSk7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKG5lZWRzU3luY0RhdGEoKSkgewotICAgICAgICAgICAgc3luY2hyb25pemVEYXRhKCk7Ci0gICAgICAgIH0KLSAgICAgICAgc3lzdGVtSWQgPSBpZDsKLQotICAgIH0gLy8gc2V0U3lzdGVtSWQoU3RyaW5nKQotCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBhYnNvbHV0ZSBiYXNlIFVSSSBvZiB0aGlzIG5vZGUgb3IgbnVsbCBpZiB0aGUgaW1wbGVtZW50YXRpb24KLSAgICAgKiB3YXNuJ3QgYWJsZSB0byBvYnRhaW4gYW4gYWJzb2x1dGUgVVJJLiBOb3RlOiBJZiB0aGUgVVJJIGlzIG1hbGZvcm1lZCwgYQotICAgICAqIG51bGwgaXMgcmV0dXJuZWQuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBhYnNvbHV0ZSBiYXNlIFVSSSBvZiB0aGlzIG5vZGUgb3IgbnVsbC4KLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEJhc2VVUkkoKSB7Ci0gICAgICAgIGlmIChuZWVkc1N5bmNEYXRhKCkpIHsKLSAgICAgICAgICAgIHN5bmNocm9uaXplRGF0YSgpOwotICAgICAgICB9Ci0gICAgICAgIGlmIChiYXNlVVJJICE9IG51bGwgJiYgYmFzZVVSSS5sZW5ndGgoKSAhPSAwICkgey8vIGF0dHJpYnV0ZSB2YWx1ZSBpcyBhbHdheXMgZW1wdHkgc3RyaW5nCi0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIHJldHVybiBuZXcgVVJJKGJhc2VVUkkpLnRvU3RyaW5nKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXRjaCAoY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlVSSS5NYWxmb3JtZWRVUklFeGNlcHRpb24gZSl7Ci0gICAgICAgICAgICAgICAgLy8gUkVWSVNJVDogd2hhdCBzaG91bGQgaGFwcGVuIGluIHRoaXMgY2FzZT8KLSAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gYmFzZVVSSTsKLSAgICB9Ci0KLSAgICAvKiogTk9OLURPTTogc2V0IGJhc2UgdXJpKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRCYXNlVVJJKFN0cmluZyB1cmkpewotICAgICAgICBpZiAobmVlZHNTeW5jRGF0YSgpKSB7Ci0gICAgICAgICAgICBzeW5jaHJvbml6ZURhdGEoKTsKLSAgICAgICAgfQotICAgICAgICBiYXNlVVJJID0gdXJpOwotICAgIH0KLQotfSAvLyBjbGFzcyBOb3RhdGlvbkltcGwKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9QU1ZJQXR0ck5TSW1wbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL1BTVklBdHRyTlNJbXBsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGNlZmU5MmQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL1BTVklBdHRyTlNJbXBsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyNTMgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMi0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbTsKLQotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci1pbXBvcnQgamF2YS5pby5Ob3RTZXJpYWxpemFibGVFeGNlcHRpb247Ci1pbXBvcnQgamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbTsKLWltcG9ydCBqYXZhLmlvLk9iamVjdE91dHB1dFN0cmVhbTsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuQXR0cmlidXRlUFNWSTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLio7Ci0KLS8qKgotICogQXR0cmlidXRlIG5hbWVzcGFjZSBpbXBsZW1lbnRhdGlvbjsgc3RvcmVzIFBTVkkgYXR0cmlidXRlIGl0ZW1zLgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIFNhbmR5IEdhbywgSUJNCi0gKgotICovCi1wdWJsaWMgY2xhc3MgUFNWSUF0dHJOU0ltcGwgZXh0ZW5kcyBBdHRyTlNJbXBsIGltcGxlbWVudHMgQXR0cmlidXRlUFNWSSB7Ci0KLSAgICAvKiogU2VyaWFsaXphdGlvbiB2ZXJzaW9uLiAqLwotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMzI0MTczODY5OTQyMTAxODg4OUw7Ci0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3QgYW4gYXR0cmlidXRlIG5vZGUuCi0gICAgICovCi0gICAgcHVibGljIFBTVklBdHRyTlNJbXBsKENvcmVEb2N1bWVudEltcGwgb3duZXJEb2N1bWVudCwgU3RyaW5nIG5hbWVzcGFjZVVSSSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHF1YWxpZmllZE5hbWUsIFN0cmluZyBsb2NhbE5hbWUpIHsKLSAgICAgICAgc3VwZXIob3duZXJEb2N1bWVudCwgbmFtZXNwYWNlVVJJLCBxdWFsaWZpZWROYW1lLCBsb2NhbE5hbWUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdCBhbiBhdHRyaWJ1dGUgbm9kZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgUFNWSUF0dHJOU0ltcGwoQ29yZURvY3VtZW50SW1wbCBvd25lckRvY3VtZW50LCBTdHJpbmcgbmFtZXNwYWNlVVJJLAotICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcXVhbGlmaWVkTmFtZSkgewotICAgICAgICBzdXBlcihvd25lckRvY3VtZW50LCBuYW1lc3BhY2VVUkksIHF1YWxpZmllZE5hbWUpOwotICAgIH0KLQotICAgIC8qKiBhdHRyaWJ1dGUgZGVjbGFyYXRpb24gKi8KLSAgICBwcm90ZWN0ZWQgWFNBdHRyaWJ1dGVEZWNsYXJhdGlvbiBmRGVjbGFyYXRpb24gPSBudWxsOwotCi0gICAgLyoqIHR5cGUgb2YgYXR0cmlidXRlLCBzaW1wbGVUeXBlICovCi0gICAgcHJvdGVjdGVkIFhTVHlwZURlZmluaXRpb24gZlR5cGVEZWNsID0gbnVsbDsKLQotICAgIC8qKiBJZiB0aGlzIGF0dHJpYnV0ZSB3YXMgZXhwbGljaXRseSBnaXZlbiBhCi0gICAgICogdmFsdWUgaW4gdGhlIG9yaWdpbmFsIGRvY3VtZW50LCB0aGlzIGlzIHRydWU7IG90aGVyd2lzZSwgaXQgaXMgZmFsc2UgICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZlNwZWNpZmllZCA9IHRydWU7Ci0KLSAgICAvKiogc2NoZW1hIG5vcm1hbGl6ZWQgdmFsdWUgcHJvcGVydHkgKi8KLSAgICBwcm90ZWN0ZWQgU3RyaW5nIGZOb3JtYWxpemVkVmFsdWUgPSBudWxsOwotCi0gICAgLyoqIHNjaGVtYSBhY3R1YWwgdmFsdWUgKi8KLSAgICBwcm90ZWN0ZWQgT2JqZWN0IGZBY3R1YWxWYWx1ZSA9IG51bGw7Ci0KLSAgICAvKiogc2NoZW1hIGFjdHVhbCB2YWx1ZSB0eXBlICovCi0gICAgcHJvdGVjdGVkIHNob3J0IGZBY3R1YWxWYWx1ZVR5cGUgPSBYU0NvbnN0YW50cy5VTkFWQUlMQUJMRV9EVDsKLQotICAgIC8qKiBhY3R1YWwgdmFsdWUgdHlwZXMgaWYgdGhlIHZhbHVlIGlzIGEgbGlzdCAqLwotICAgIHByb3RlY3RlZCBTaG9ydExpc3QgZkl0ZW1WYWx1ZVR5cGVzID0gbnVsbDsKLQotICAgIC8qKiBtZW1iZXIgdHlwZSBkZWZpbml0aW9uIGFnYWluc3Qgd2hpY2ggYXR0cmlidXRlIHdhcyB2YWxpZGF0ZWQgKi8KLSAgICBwcm90ZWN0ZWQgWFNTaW1wbGVUeXBlRGVmaW5pdGlvbiBmTWVtYmVyVHlwZSA9IG51bGw7Ci0KLSAgICAvKiogdmFsaWRhdGlvbiBhdHRlbXB0ZWQ6IG5vbmUsIHBhcnRpYWwsIGZ1bGwgKi8KLSAgICBwcm90ZWN0ZWQgc2hvcnQgZlZhbGlkYXRpb25BdHRlbXB0ZWQgPSBBdHRyaWJ1dGVQU1ZJLlZBTElEQVRJT05fTk9ORTsKLQotICAgIC8qKiB2YWxpZGl0eTogdmFsaWQsIGludmFsaWQsIHVua25vd24gKi8KLSAgICBwcm90ZWN0ZWQgc2hvcnQgZlZhbGlkaXR5ID0gQXR0cmlidXRlUFNWSS5WQUxJRElUWV9OT1RLTk9XTjsKLQotICAgIC8qKiBlcnJvciBjb2RlcyAqLwotICAgIHByb3RlY3RlZCBTdHJpbmdMaXN0IGZFcnJvckNvZGVzID0gbnVsbDsKLQotICAgIC8qKiB2YWxpZGF0aW9uIGNvbnRleHQ6IGNvdWxkIGJlIFFOYW1lIG9yIFhQYXRoIGV4cHJlc3Npb24qLwotICAgIHByb3RlY3RlZCBTdHJpbmcgZlZhbGlkYXRpb25Db250ZXh0ID0gbnVsbDsKLQotICAgIC8vCi0gICAgLy8gQXR0cmlidXRlUFNWSSBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFtzY2hlbWEgZGVmYXVsdF0KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIGNhbm9uaWNhbCBsZXhpY2FsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBkZWNsYXJhdGlvbidzIHt2YWx1ZSBjb25zdHJhaW50fSB2YWx1ZS4KLSAgICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3htbHNjaGVtYS0xLyNlLXNjaGVtYV9kZWZhdWx0PlhNTCBTY2hlbWEgUGFydCAxOiBTdHJ1Y3R1cmVzIFtzY2hlbWEgZGVmYXVsdF08L2E+Ci0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRTY2hlbWFEZWZhdWx0KCkgewotICAgICAgICByZXR1cm4gZkRlY2xhcmF0aW9uID09IG51bGwgPyBudWxsIDogZkRlY2xhcmF0aW9uLmdldENvbnN0cmFpbnRWYWx1ZSgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFtzY2hlbWEgbm9ybWFsaXplZCB2YWx1ZV0KLSAgICAgKgotICAgICAqCi0gICAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94bWxzY2hlbWEtMS8jZS1zY2hlbWFfbm9ybWFsaXplZF92YWx1ZT5YTUwgU2NoZW1hIFBhcnQgMTogU3RydWN0dXJlcyBbc2NoZW1hIG5vcm1hbGl6ZWQgdmFsdWVdPC9hPgotICAgICAqIEByZXR1cm4gdGhlIG5vcm1hbGl6ZWQgdmFsdWUgb2YgdGhpcyBpdGVtIGFmdGVyIHZhbGlkYXRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFNjaGVtYU5vcm1hbGl6ZWRWYWx1ZSgpIHsKLSAgICAgICAgcmV0dXJuIGZOb3JtYWxpemVkVmFsdWU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogW3NjaGVtYSBzcGVjaWZpZWRdCi0gICAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94bWxzY2hlbWEtMS8jZS1zY2hlbWFfc3BlY2lmaWVkIj5YTUwgU2NoZW1hIFBhcnQgMTogU3RydWN0dXJlcyBbc2NoZW1hIHNwZWNpZmllZF08L2E+Ci0gICAgICogQHJldHVybiBmYWxzZSB2YWx1ZSB3YXMgc3BlY2lmaWVkIGluIHNjaGVtYSwgdHJ1ZSB2YWx1ZSBjb21lcyBmcm9tIHRoZSBpbmZvc2V0Ci0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0SXNTY2hlbWFTcGVjaWZpZWQoKSB7Ci0gICAgICAgIHJldHVybiBmU3BlY2lmaWVkOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogRGV0ZXJtaW5lcyB0aGUgZXh0ZW50IHRvIHdoaWNoIHRoZSBkb2N1bWVudCBoYXMgYmVlbiB2YWxpZGF0ZWQKLSAgICAgKgotICAgICAqIEByZXR1cm4gcmV0dXJuIHRoZSBbdmFsaWRhdGlvbiBhdHRlbXB0ZWRdIHByb3BlcnR5LiBUaGUgcG9zc2libGUgdmFsdWVzIGFyZQotICAgICAqICAgICAgICAgTk9fVkFMSURBVElPTiwgUEFSVElBTF9WQUxJREFUSU9OIGFuZCBGVUxMX1ZBTElEQVRJT04KLSAgICAgKi8KLSAgICBwdWJsaWMgc2hvcnQgZ2V0VmFsaWRhdGlvbkF0dGVtcHRlZCgpIHsKLSAgICAgICAgcmV0dXJuIGZWYWxpZGF0aW9uQXR0ZW1wdGVkOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIERldGVybWluZSB0aGUgdmFsaWRpdHkgb2YgdGhlIG5vZGUgd2l0aCByZXNwZWN0Ci0gICAgICogdG8gdGhlIHZhbGlkYXRpb24gYmVpbmcgYXR0ZW1wdGVkCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHJldHVybiB0aGUgW3ZhbGlkaXR5XSBwcm9wZXJ0eS4gUG9zc2libGUgdmFsdWVzIGFyZToKLSAgICAgKiAgICAgICAgIFVOS05PV05fVkFMSURJVFksIElOVkFMSURfVkFMSURJVFksIFZBTElEX1ZBTElESVRZCi0gICAgICovCi0gICAgcHVibGljIHNob3J0IGdldFZhbGlkaXR5KCkgewotICAgICAgICByZXR1cm4gZlZhbGlkaXR5OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEEgbGlzdCBvZiBlcnJvciBjb2RlcyBnZW5lcmF0ZWQgZnJvbSB2YWxpZGF0aW9uIGF0dGVtcHRzLgotICAgICAqIE5lZWQgdG8gZmluZCBhbGwgdGhlIHBvc3NpYmxlIHN1YmNsYXVzZSByZXBvcnRzIHRoYXQgbmVlZCByZXBvcnRpbmcKLSAgICAgKgotICAgICAqIEByZXR1cm4gbGlzdCBvZiBlcnJvciBjb2RlcwotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmdMaXN0IGdldEVycm9yQ29kZXMoKSB7Ci0gICAgICAgIHJldHVybiBmRXJyb3JDb2RlczsKLSAgICB9Ci0KLSAgICAvLyBUaGlzIGlzIHRoZSBvbmx5IGluZm9ybWF0aW9uIHdlIGNhbiBwcm92aWRlIGluIGEgcGlwZWxpbmUuCi0gICAgcHVibGljIFN0cmluZyBnZXRWYWxpZGF0aW9uQ29udGV4dCgpIHsKLSAgICAgICAgcmV0dXJuIGZWYWxpZGF0aW9uQ29udGV4dDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBbiBpdGVtIGlzb21vcnBoaWMgdG8gdGhlIHR5cGUgZGVmaW5pdGlvbiB1c2VkIHRvIHZhbGlkYXRlIHRoaXMgZWxlbWVudC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gIGEgdHlwZSBkZWNsYXJhdGlvbgotICAgICAqLwotICAgIHB1YmxpYyBYU1R5cGVEZWZpbml0aW9uIGdldFR5cGVEZWZpbml0aW9uKCkgewotICAgICAgICByZXR1cm4gZlR5cGVEZWNsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIElmIGFuZCBvbmx5IGlmIHRoYXQgdHlwZSBkZWZpbml0aW9uIGlzIGEgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbgotICAgICAqIHdpdGgge3ZhcmlldHl9IHVuaW9uLCBvciBhIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uIHdob3NlIHtjb250ZW50IHR5cGV9Ci0gICAgICogaXMgYSBzaW1wbGUgdGh5cGUgZGVmaW5pdGlvbiB3aXRoIHt2YXJpZXR5fSB1bmlvbiwgdGhlbiBhbiBpdGVtIGlzb21vcnBoaWMKLSAgICAgKiB0byB0aGF0IG1lbWJlciBvZiB0aGUgdW5pb24ncyB7bWVtYmVyIHR5cGUgZGVmaW5pdGlvbnN9IHdoaWNoIGFjdHVhbGx5Ci0gICAgICogdmFsaWRhdGVkIHRoZSBlbGVtZW50IGl0ZW0ncyBub3JtYWxpemVkIHZhbHVlLgotICAgICAqCi0gICAgICogQHJldHVybiAgYSBzaW1wbGUgdHlwZSBkZWNsYXJhdGlvbgotICAgICAqLwotICAgIHB1YmxpYyBYU1NpbXBsZVR5cGVEZWZpbml0aW9uIGdldE1lbWJlclR5cGVEZWZpbml0aW9uKCkgewotICAgICAgICByZXR1cm4gZk1lbWJlclR5cGU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQW4gaXRlbSBpc29tb3JwaGljIHRvIHRoZSBhdHRyaWJ1dGUgZGVjbGFyYXRpb24gdXNlZCB0byB2YWxpZGF0ZQotICAgICAqIHRoaXMgYXR0cmlidXRlLgotICAgICAqCi0gICAgICogQHJldHVybiAgYW4gYXR0cmlidXRlIGRlY2xhcmF0aW9uCi0gICAgICovCi0gICAgcHVibGljIFhTQXR0cmlidXRlRGVjbGFyYXRpb24gZ2V0QXR0cmlidXRlRGVjbGFyYXRpb24oKSB7Ci0gICAgICAgIHJldHVybiBmRGVjbGFyYXRpb247Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29weSBQU1ZJIHByb3BlcnRpZXMgZnJvbSBhbm90aGVyIHBzdmkgaXRlbS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBhdHRyICB0aGUgc291cmNlIG9mIGF0dHJpYnV0ZSBQU1ZJIGl0ZW1zCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0UFNWSShBdHRyaWJ1dGVQU1ZJIGF0dHIpIHsKLSAgICAgICAgdGhpcy5mRGVjbGFyYXRpb24gPSBhdHRyLmdldEF0dHJpYnV0ZURlY2xhcmF0aW9uKCk7Ci0gICAgICAgIHRoaXMuZlZhbGlkYXRpb25Db250ZXh0ID0gYXR0ci5nZXRWYWxpZGF0aW9uQ29udGV4dCgpOwotICAgICAgICB0aGlzLmZWYWxpZGl0eSA9IGF0dHIuZ2V0VmFsaWRpdHkoKTsKLSAgICAgICAgdGhpcy5mVmFsaWRhdGlvbkF0dGVtcHRlZCA9IGF0dHIuZ2V0VmFsaWRhdGlvbkF0dGVtcHRlZCgpOwotICAgICAgICB0aGlzLmZFcnJvckNvZGVzID0gYXR0ci5nZXRFcnJvckNvZGVzKCk7Ci0gICAgICAgIHRoaXMuZk5vcm1hbGl6ZWRWYWx1ZSA9IGF0dHIuZ2V0U2NoZW1hTm9ybWFsaXplZFZhbHVlKCk7Ci0gICAgICAgIHRoaXMuZkFjdHVhbFZhbHVlID0gYXR0ci5nZXRBY3R1YWxOb3JtYWxpemVkVmFsdWUoKTsKLSAgICAgICAgdGhpcy5mQWN0dWFsVmFsdWVUeXBlID0gYXR0ci5nZXRBY3R1YWxOb3JtYWxpemVkVmFsdWVUeXBlKCk7Ci0gICAgICAgIHRoaXMuZkl0ZW1WYWx1ZVR5cGVzID0gYXR0ci5nZXRJdGVtVmFsdWVUeXBlcygpOwotICAgICAgICB0aGlzLmZUeXBlRGVjbCA9IGF0dHIuZ2V0VHlwZURlZmluaXRpb24oKTsKLSAgICAgICAgdGhpcy5mTWVtYmVyVHlwZSA9IGF0dHIuZ2V0TWVtYmVyVHlwZURlZmluaXRpb24oKTsKLSAgICAgICAgdGhpcy5mU3BlY2lmaWVkID0gYXR0ci5nZXRJc1NjaGVtYVNwZWNpZmllZCgpOwotICAgIH0KLQotICAgIC8qIChub24tSmF2YWRvYykKLSAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuSXRlbVBTVkkjZ2V0QWN0dWFsTm9ybWFsaXplZFZhbHVlKCkKLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0IGdldEFjdHVhbE5vcm1hbGl6ZWRWYWx1ZSgpIHsKLSAgICAgICAgcmV0dXJuIHRoaXMuZkFjdHVhbFZhbHVlOwotICAgIH0KLQotICAgIC8qIChub24tSmF2YWRvYykKLSAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuSXRlbVBTVkkjZ2V0QWN0dWFsTm9ybWFsaXplZFZhbHVlVHlwZSgpCi0gICAgICovCi0gICAgcHVibGljIHNob3J0IGdldEFjdHVhbE5vcm1hbGl6ZWRWYWx1ZVR5cGUoKSB7Ci0gICAgICAgIHJldHVybiB0aGlzLmZBY3R1YWxWYWx1ZVR5cGU7Ci0gICAgfQotCi0gICAgLyogKG5vbi1KYXZhZG9jKQotICAgICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5JdGVtUFNWSSNnZXRJdGVtVmFsdWVUeXBlcygpCi0gICAgICovCi0gICAgcHVibGljIFNob3J0TGlzdCBnZXRJdGVtVmFsdWVUeXBlcygpIHsKLSAgICAgICAgcmV0dXJuIHRoaXMuZkl0ZW1WYWx1ZVR5cGVzOwotICAgIH0KLQotICAgIC8vIFJFVklTSVQ6IEZvcmJpZCBzZXJpYWxpemF0aW9uIG9mIFBTVkkgRE9NIHVudGlsCi0gICAgLy8gd2Ugc3VwcG9ydCBvYmplY3Qgc2VyaWFsaXphdGlvbiBvZiBncmFtbWFycyAtLSBtcmdsYXZhcwotCi0gICAgcHJpdmF0ZSB2b2lkIHdyaXRlT2JqZWN0KE9iamVjdE91dHB1dFN0cmVhbSBvdXQpCi0gICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgIHRocm93IG5ldyBOb3RTZXJpYWxpemFibGVFeGNlcHRpb24oZ2V0Q2xhc3MoKS5nZXROYW1lKCkpOwotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCByZWFkT2JqZWN0KE9iamVjdElucHV0U3RyZWFtIGluKQotICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIENsYXNzTm90Rm91bmRFeGNlcHRpb24gewotICAgICAgICB0aHJvdyBuZXcgTm90U2VyaWFsaXphYmxlRXhjZXB0aW9uKGdldENsYXNzKCkuZ2V0TmFtZSgpKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vUFNWSURPTUltcGxlbWVudGF0aW9uSW1wbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL1BTVklET01JbXBsZW1lbnRhdGlvbkltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDcyNzFmMS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vUFNWSURPTUltcGxlbWVudGF0aW9uSW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTI0ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwMiwyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbTsKLQotaW1wb3J0IG9yZy53M2MuZG9tLkRPTUV4Y2VwdGlvbjsKLWltcG9ydCBvcmcudzNjLmRvbS5ET01JbXBsZW1lbnRhdGlvbjsKLWltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKLWltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudFR5cGU7Ci1pbXBvcnQgb3JnLnczYy5kb20uRWxlbWVudDsKLQotLyoqCi0gKiBUaGUgRE9NSW1wbGVtZW50YXRpb24gY2xhc3MgaXMgZGVzY3JpcHRpb24gb2YgYSBwYXJ0aWN1bGFyCi0gKiBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgRG9jdW1lbnQgT2JqZWN0IE1vZGVsLiBBcyBzdWNoIGl0cyBkYXRhIGlzCi0gKiBzdGF0aWMsIHNoYXJlZCBieSBhbGwgaW5zdGFuY2VzIG9mIHRoaXMgaW1wbGVtZW50YXRpb24uCi0gKiA8UD4KLSAqIFRoZSBET00gQVBJIHJlcXVpcmVzIHRoYXQgaXQgYmUgYSByZWFsIG9iamVjdCByYXRoZXIgdGhhbiBzdGF0aWMKLSAqIG1ldGhvZHMuIEhvd2V2ZXIsIHRoZXJlJ3Mgbm90aGluZyB0aGF0IHNheXMgaXQgY2FuJ3QgYmUgYSBzaW5nbGV0b24sCi0gKiBzbyB0aGF0J3MgaG93IEkndmUgaW1wbGVtZW50ZWQgaXQuCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBzaW5jZSAgUFItRE9NLUxldmVsLTEtMTk5ODA4MTguCi0gKi8KLXB1YmxpYyBjbGFzcyBQU1ZJRE9NSW1wbGVtZW50YXRpb25JbXBsIGV4dGVuZHMgQ29yZURPTUltcGxlbWVudGF0aW9uSW1wbCB7Ci0KLSAgICAvLwotICAgIC8vIERhdGEKLSAgICAvLwotCi0gICAgLy8gc3RhdGljCi0KLSAgICAvKiogRG9tIGltcGxlbWVudGF0aW9uIHNpbmdsZXRvbi4gKi8KLSAgICBzdGF0aWMgUFNWSURPTUltcGxlbWVudGF0aW9uSW1wbCBzaW5nbGV0b24gPSBuZXcgUFNWSURPTUltcGxlbWVudGF0aW9uSW1wbCgpOwotCi0gICAgLy8KLSAgICAvLyBQdWJsaWMgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKiogTk9OLURPTTogT2J0YWluIGFuZCByZXR1cm4gdGhlIHNpbmdsZSBzaGFyZWQgb2JqZWN0ICovCi0gICAgcHVibGljIHN0YXRpYyBET01JbXBsZW1lbnRhdGlvbiBnZXRET01JbXBsZW1lbnRhdGlvbigpIHsKLSAgICAgICAgcmV0dXJuIHNpbmdsZXRvbjsKLSAgICB9Ci0KLSAgICAvLwotICAgIC8vIERPTUltcGxlbWVudGF0aW9uIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogVGVzdCBpZiB0aGUgRE9NIGltcGxlbWVudGF0aW9uIHN1cHBvcnRzIGEgc3BlY2lmaWMgImZlYXR1cmUiIC0tCi0gICAgICogY3VycmVudGx5IG1lYW5pbmcgbGFuZ3VhZ2UgYW5kIGxldmVsIHRoZXJlb2YuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZmVhdHVyZSAgICAgIFRoZSBwYWNrYWdlIG5hbWUgb2YgdGhlIGZlYXR1cmUgdG8gdGVzdC4KLSAgICAgKiBJbiBMZXZlbCAxLCBzdXBwb3J0ZWQgdmFsdWVzIGFyZSAiSFRNTCIgYW5kICJYTUwiIChjYXNlLWluc2Vuc2l0aXZlKS4KLSAgICAgKiBBdCB0aGlzIHdyaXRpbmcsIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tIHN1cHBvcnRzIG9ubHkgWE1MLgotICAgICAqCi0gICAgICogQHBhcmFtIHZlcnNpb24gICAgICBUaGUgdmVyc2lvbiBudW1iZXIgb2YgdGhlIGZlYXR1cmUgYmVpbmcgdGVzdGVkLgotICAgICAqIFRoaXMgaXMgaW50ZXJwcmV0ZWQgYXMgIlZlcnNpb24gb2YgdGhlIERPTSBBUEkgc3VwcG9ydGVkIGZvciB0aGUKLSAgICAgKiBzcGVjaWZpZWQgRmVhdHVyZSIsIGFuZCBpbiBMZXZlbCAxIHNob3VsZCBiZSAiMS4wIgotICAgICAqCi0gICAgICogQHJldHVybiAgICB0cnVlIGlmZiB0aGlzIGltcGxlbWVudGF0aW9uIGlzIGNvbXBhdGFibGUgd2l0aCB0aGUgc3BlY2lmaWVkCi0gICAgICogZmVhdHVyZSBhbmQgdmVyc2lvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBoYXNGZWF0dXJlKFN0cmluZyBmZWF0dXJlLCBTdHJpbmcgdmVyc2lvbikgewotICAgICAgICByZXR1cm4gc3VwZXIuaGFzRmVhdHVyZShmZWF0dXJlLCB2ZXJzaW9uKSB8fAotICAgICAgICAgICAgICAgZmVhdHVyZS5lcXVhbHNJZ25vcmVDYXNlKCJwc3ZpIik7Ci0gICAgfSAvLyBoYXNGZWF0dXJlKFN0cmluZyxTdHJpbmcpOmJvb2xlYW4KLQotICAgIC8qKgotICAgICAqIEludHJvZHVjZWQgaW4gRE9NIExldmVsIDIuIDxwPgotICAgICAqCi0gICAgICogQ3JlYXRlcyBhbiBYTUwgRG9jdW1lbnQgb2JqZWN0IG9mIHRoZSBzcGVjaWZpZWQgdHlwZSB3aXRoIGl0cyBkb2N1bWVudAotICAgICAqIGVsZW1lbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZXNwYWNlVVJJICAgICBUaGUgbmFtZXNwYWNlIFVSSSBvZiB0aGUgZG9jdW1lbnQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50IHRvIGNyZWF0ZSwgb3IgbnVsbC4KLSAgICAgKiBAcGFyYW0gcXVhbGlmaWVkTmFtZSAgICBUaGUgcXVhbGlmaWVkIG5hbWUgb2YgdGhlIGRvY3VtZW50Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudCB0byBjcmVhdGUuCi0gICAgICogQHBhcmFtIGRvY3R5cGUgICAgICAgICAgVGhlIHR5cGUgb2YgZG9jdW1lbnQgdG8gYmUgY3JlYXRlZCBvciBudWxsLjxwPgotICAgICAqCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgV2hlbiBkb2N0eXBlIGlzIG5vdCBudWxsLCBpdHMKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBOb2RlLm93bmVyRG9jdW1lbnQgYXR0cmlidXRlIGlzIHNldCB0bwotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSBkb2N1bWVudCBiZWluZyBjcmVhdGVkLgotICAgICAqIEByZXR1cm4gRG9jdW1lbnQgICAgICAgIEEgbmV3IERvY3VtZW50IG9iamVjdC4KLSAgICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbiAgICBXUk9OR19ET0NVTUVOVF9FUlI6IFJhaXNlZCBpZiBkb2N0eXBlIGhhcwotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIGFscmVhZHkgYmVlbiB1c2VkIHdpdGggYSBkaWZmZXJlbnQgZG9jdW1lbnQuCi0gICAgICogQHNpbmNlIFdELURPTS1MZXZlbC0yLTE5OTkwOTIzCi0gICAgICovCi0gICAgcHVibGljIERvY3VtZW50ICAgICAgICAgICBjcmVhdGVEb2N1bWVudChTdHJpbmcgbmFtZXNwYWNlVVJJLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHF1YWxpZmllZE5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEb2N1bWVudFR5cGUgZG9jdHlwZSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGlmIChkb2N0eXBlICE9IG51bGwgJiYgZG9jdHlwZS5nZXRPd25lckRvY3VtZW50KCkgIT0gbnVsbCkgewotICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uV1JPTkdfRE9DVU1FTlRfRVJSLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiV1JPTkdfRE9DVU1FTlRfRVJSIiwgbnVsbCkpOwotICAgICAgICB9Ci0gICAgICAgIERvY3VtZW50SW1wbCBkb2MgPSBuZXcgUFNWSURvY3VtZW50SW1wbChkb2N0eXBlKTsKLSAgICAgICAgRWxlbWVudCBlID0gZG9jLmNyZWF0ZUVsZW1lbnROUyggbmFtZXNwYWNlVVJJLCBxdWFsaWZpZWROYW1lKTsKLSAgICAgICAgZG9jLmFwcGVuZENoaWxkKGUpOwotICAgICAgICByZXR1cm4gZG9jOwotICAgIH0KLQotCi19IC8vIGNsYXNzIERPTUltcGxlbWVudGF0aW9uSW1wbApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL1BTVklEb2N1bWVudEltcGwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9QU1ZJRG9jdW1lbnRJbXBsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDYxZDRiZjkuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL1BTVklEb2N1bWVudEltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE1MCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAyLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tOwotCi1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLk5vdFNlcmlhbGl6YWJsZUV4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uT2JqZWN0T3V0cHV0U3RyZWFtOwotaW1wb3J0IG9yZy53M2MuZG9tLkRPTUNvbmZpZ3VyYXRpb247Ci1pbXBvcnQgb3JnLnczYy5kb20uVXNlckRhdGFIYW5kbGVyOwotaW1wb3J0IG9yZy53M2MuZG9tLio7Ci0KLS8qKgotICogT3VyIG93biBkb2N1bWVudCBpbXBsZW1lbnRhdGlvbiwgd2hpY2gga25vd3MgaG93IHRvIGNyZWF0ZSBhbiBlbGVtZW50Ci0gKiB3aXRoIFBTVkkgaW5mb3JtYXRpb24uCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgU2FuZHkgR2FvLCBJQk0KLSAqCi0gKi8KLXB1YmxpYyBjbGFzcyBQU1ZJRG9jdW1lbnRJbXBsIGV4dGVuZHMgRG9jdW1lbnRJbXBsIHsKLQotICAgIC8qKiBTZXJpYWxpemF0aW9uIHZlcnNpb24uICovCi0gICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC04ODIyMjIwMjUwNjc2NDM0NTIyTDsKLQotICAgIC8qKgotICAgICAqIENyZWF0ZSBhIGRvY3VtZW50LgotICAgICAqLwotICAgIHB1YmxpYyBQU1ZJRG9jdW1lbnRJbXBsKCkgewotICAgICAgICBzdXBlcigpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEZvciBET00yIHN1cHBvcnQuCi0gICAgICogVGhlIGNyZWF0ZURvY3VtZW50IGZhY3RvcnkgbWV0aG9kIGlzIGluIERPTUltcGxlbWVudGF0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBQU1ZJRG9jdW1lbnRJbXBsKERvY3VtZW50VHlwZSBkb2N0eXBlKSB7Ci0gICAgICAgIHN1cGVyKGRvY3R5cGUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIERlZXAtY2xvbmUgYSBkb2N1bWVudCwgaW5jbHVkaW5nIGZpeGluZyBvd25lckRvYyBmb3IgdGhlIGNsb25lZAotICAgICAqIGNoaWxkcmVuLiBOb3RlIHRoYXQgdGhpcyByZXF1aXJlcyBieXBhc3NpbmcgdGhlIFdST05HX0RPQ1VNRU5UX0VSUgotICAgICAqIHByb3RlY3Rpb24uIEkndmUgY2hvc2VuIHRvIGltcGxlbWVudCBpdCBieSBjYWxsaW5nIGltcG9ydE5vZGUKLSAgICAgKiB3aGljaCBpcyBET00gTGV2ZWwgMi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gb3JnLnczYy5kb20uTm9kZQotICAgICAqIEBwYXJhbSBkZWVwIGJvb2xlYW4sIGlmZiB0cnVlIHJlcGxpY2F0ZSBjaGlsZHJlbgotICAgICAqLwotICAgIHB1YmxpYyBOb2RlIGNsb25lTm9kZShib29sZWFuIGRlZXApIHsKLQotICAgICAgICBQU1ZJRG9jdW1lbnRJbXBsIG5ld2RvYyA9IG5ldyBQU1ZJRG9jdW1lbnRJbXBsKCk7Ci0gICAgICAgIGNhbGxVc2VyRGF0YUhhbmRsZXJzKHRoaXMsIG5ld2RvYywgVXNlckRhdGFIYW5kbGVyLk5PREVfQ0xPTkVEKTsKLSAgICAgICAgY2xvbmVOb2RlKG5ld2RvYywgZGVlcCk7Ci0KLSAgICAgICAgLy8gZXhwZXJpbWVudGFsCi0gICAgICAgIG5ld2RvYy5tdXRhdGlvbkV2ZW50cyA9IG11dGF0aW9uRXZlbnRzOwotCi0gICAgICAgIHJldHVybiBuZXdkb2M7Ci0KLSAgICB9IC8vIGNsb25lTm9kZShib29sZWFuKTpOb2RlCi0KLSAgICAvKioKLSAgICAgKiBSZXRyaWV2ZSBpbmZvcm1hdGlvbiBkZXNjcmliaW5nIHRoZSBhYmlsaXRpZXMgb2YgdGhpcyBwYXJ0aWN1bGFyCi0gICAgICogRE9NIGltcGxlbWVudGF0aW9uLiBJbnRlbmRlZCB0byBzdXBwb3J0IGFwcGxpY2F0aW9ucyB0aGF0IG1heSBiZQotICAgICAqIHVzaW5nIERPTXMgcmV0cmlldmVkIGZyb20gc2V2ZXJhbCBkaWZmZXJlbnQgc291cmNlcywgcG90ZW50aWFsbHkKLSAgICAgKiB3aXRoIGRpZmZlcmVudCB1bmRlcmx5aW5nIHJlcHJlc2VudGF0aW9ucy4KLSAgICAgKi8KLSAgICBwdWJsaWMgRE9NSW1wbGVtZW50YXRpb24gZ2V0SW1wbGVtZW50YXRpb24oKSB7Ci0gICAgICAgIC8vIEN1cnJlbnRseSBpbXBsZW1lbnRlZCBhcyBhIHNpbmdsZXRvbiwgc2luY2UgaXQncyBoYXJkY29kZWQKLSAgICAgICAgLy8gaW5mb3JtYXRpb24gYW55d2F5LgotICAgICAgICByZXR1cm4gUFNWSURPTUltcGxlbWVudGF0aW9uSW1wbC5nZXRET01JbXBsZW1lbnRhdGlvbigpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENyZWF0ZSBhbiBlbGVtZW50IHdpdGggUFNWSSBpbmZvcm1hdGlvbgotICAgICAqLwotICAgIHB1YmxpYyBFbGVtZW50IGNyZWF0ZUVsZW1lbnROUyhTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgcXVhbGlmaWVkTmFtZSkKLSAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0gICAgICAgIHJldHVybiBuZXcgUFNWSUVsZW1lbnROU0ltcGwodGhpcywgbmFtZXNwYWNlVVJJLCBxdWFsaWZpZWROYW1lKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGUgYW4gZWxlbWVudCB3aXRoIFBTVkkgaW5mb3JtYXRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgRWxlbWVudCBjcmVhdGVFbGVtZW50TlMoU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIHF1YWxpZmllZE5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBsb2NhbHBhcnQpIHRocm93cyBET01FeGNlcHRpb24gewotICAgICAgICByZXR1cm4gbmV3IFBTVklFbGVtZW50TlNJbXBsKHRoaXMsIG5hbWVzcGFjZVVSSSwgcXVhbGlmaWVkTmFtZSwgbG9jYWxwYXJ0KTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGUgYW4gYXR0cmlidXRlIHdpdGggUFNWSSBpbmZvcm1hdGlvbgotICAgICAqLwotICAgIHB1YmxpYyBBdHRyIGNyZWF0ZUF0dHJpYnV0ZU5TKFN0cmluZyBuYW1lc3BhY2VVUkksIFN0cmluZyBxdWFsaWZpZWROYW1lKQotICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKLSAgICAgICAgcmV0dXJuIG5ldyBQU1ZJQXR0ck5TSW1wbCh0aGlzLCBuYW1lc3BhY2VVUkksIHF1YWxpZmllZE5hbWUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENyZWF0ZSBhbiBhdHRyaWJ1dGUgd2l0aCBQU1ZJIGluZm9ybWF0aW9uCi0gICAgICovCi0gICAgcHVibGljIEF0dHIgY3JlYXRlQXR0cmlidXRlTlMoU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIHF1YWxpZmllZE5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGxvY2FsTmFtZSkgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0gICAgICAgIHJldHVybiBuZXcgUFNWSUF0dHJOU0ltcGwodGhpcywgbmFtZXNwYWNlVVJJLCBxdWFsaWZpZWROYW1lLCBsb2NhbE5hbWUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqCi0gICAgICogVGhlIGNvbmZpZ3VyYXRpb24gdXNlZCB3aGVuIDxjb2RlPkRvY3VtZW50Lm5vcm1hbGl6ZURvY3VtZW50PC9jb2RlPiBpcwotICAgICAqIGludm9rZWQuCi0gICAgICogQHNpbmNlIERPTSBMZXZlbCAzCi0gICAgICovCi0gICAgcHVibGljIERPTUNvbmZpZ3VyYXRpb24gZ2V0RG9tQ29uZmlnKCl7Ci0gICAgICAgIHN1cGVyLmdldERvbUNvbmZpZygpOwotICAgICAgICByZXR1cm4gZkNvbmZpZ3VyYXRpb247Ci0gICAgfQotCi0gICAgLy8gUkVWSVNJVDogRm9yYmlkIHNlcmlhbGl6YXRpb24gb2YgUFNWSSBET00gdW50aWwKLSAgICAvLyB3ZSBzdXBwb3J0IG9iamVjdCBzZXJpYWxpemF0aW9uIG9mIGdyYW1tYXJzIC0tIG1yZ2xhdmFzCi0KLSAgICBwcml2YXRlIHZvaWQgd3JpdGVPYmplY3QoT2JqZWN0T3V0cHV0U3RyZWFtIG91dCkKLSAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKLSAgICAgICAgdGhyb3cgbmV3IE5vdFNlcmlhbGl6YWJsZUV4Y2VwdGlvbihnZXRDbGFzcygpLmdldE5hbWUoKSk7Ci0gICAgICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCByZWFkT2JqZWN0KE9iamVjdElucHV0U3RyZWFtIGluKQotICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIENsYXNzTm90Rm91bmRFeGNlcHRpb24gewotICAgICAgICB0aHJvdyBuZXcgTm90U2VyaWFsaXphYmxlRXhjZXB0aW9uKGdldENsYXNzKCkuZ2V0TmFtZSgpKTsKLSAgICB9Ci0KLX0gLy8gY2xhc3MgUFNWSURvY3VtZW50SW1wbApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL1BTVklFbGVtZW50TlNJbXBsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vUFNWSUVsZW1lbnROU0ltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggN2IyNmE5YS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vUFNWSUVsZW1lbnROU0ltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI5NiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAyLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tOwotCi1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLk5vdFNlcmlhbGl6YWJsZUV4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uT2JqZWN0T3V0cHV0U3RyZWFtOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5FbGVtZW50UFNWSTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLio7Ci0KLS8qKgotICogRWxlbWVudCBuYW1lc3BhY2UgaW1wbGVtZW50YXRpb247IHN0b3JlcyBQU1ZJIGVsZW1lbnQgaXRlbXMuCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgU2FuZHkgR2FvLCBJQk0KLSAqCi0gKiBAdmVyc2lvbiAkSWQ6IFBTVklFbGVtZW50TlNJbXBsLmphdmEsdiAxLjYgMjAxMC8wOC8yMCAxODo1MTo1NCBqb2VodyBFeHAgJAotICovCi1wdWJsaWMgY2xhc3MgUFNWSUVsZW1lbnROU0ltcGwgZXh0ZW5kcyBFbGVtZW50TlNJbXBsIGltcGxlbWVudHMgRWxlbWVudFBTVkkgewotCi0gICAgLyoqIFNlcmlhbGl6YXRpb24gdmVyc2lvbi4gKi8KLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNjgxNTQ4OTYyNDYzNjAxNjA2OEw7Ci0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3QgYW4gZWxlbWVudCBub2RlLgotICAgICAqLwotICAgIHB1YmxpYyBQU1ZJRWxlbWVudE5TSW1wbChDb3JlRG9jdW1lbnRJbXBsIG93bmVyRG9jdW1lbnQsIFN0cmluZyBuYW1lc3BhY2VVUkksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBxdWFsaWZpZWROYW1lLCBTdHJpbmcgbG9jYWxOYW1lKSB7Ci0gICAgICAgIHN1cGVyKG93bmVyRG9jdW1lbnQsIG5hbWVzcGFjZVVSSSwgcXVhbGlmaWVkTmFtZSwgbG9jYWxOYW1lKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3QgYW4gZWxlbWVudCBub2RlLgotICAgICAqLwotICAgIHB1YmxpYyBQU1ZJRWxlbWVudE5TSW1wbChDb3JlRG9jdW1lbnRJbXBsIG93bmVyRG9jdW1lbnQsIFN0cmluZyBuYW1lc3BhY2VVUkksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBxdWFsaWZpZWROYW1lKSB7Ci0gICAgICAgIHN1cGVyKG93bmVyRG9jdW1lbnQsIG5hbWVzcGFjZVVSSSwgcXVhbGlmaWVkTmFtZSk7Ci0gICAgfQotCi0gICAgLyoqIGVsZW1lbnQgZGVjbGFyYXRpb24gKi8KLSAgICBwcm90ZWN0ZWQgWFNFbGVtZW50RGVjbGFyYXRpb24gZkRlY2xhcmF0aW9uID0gbnVsbDsKLQotICAgIC8qKiB0eXBlIG9mIGVsZW1lbnQsIGNvdWxkIGJlIHhzaTp0eXBlICovCi0gICAgcHJvdGVjdGVkIFhTVHlwZURlZmluaXRpb24gZlR5cGVEZWNsID0gbnVsbDsKLQotICAgIC8qKiB0cnVlIGlmIGNsYXVzZSAzLjIgb2YgRWxlbWVudCBMb2NhbGx5IFZhbGlkIChFbGVtZW50KSAoMy4zLjQpCi0gICAgICAqIGlzIHNhdGlzZmllZCwgb3RoZXJ3aXNlIGZhbHNlCi0gICAgICAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIGZOaWwgPSBmYWxzZTsKLQotICAgIC8qKiBmYWxzZSBpZiB0aGUgZWxlbWVudCB2YWx1ZSB3YXMgcHJvdmlkZWQgYnkgdGhlIHNjaGVtYTsgdHJ1ZSBvdGhlcndpc2UuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZlNwZWNpZmllZCA9IHRydWU7Ci0KLSAgICAvKiogc2NoZW1hIG5vcm1hbGl6ZWQgdmFsdWUgcHJvcGVydHkgKi8KLSAgICBwcm90ZWN0ZWQgU3RyaW5nIGZOb3JtYWxpemVkVmFsdWUgPSBudWxsOwotCi0gICAgLyoqIHNjaGVtYSBhY3R1YWwgdmFsdWUgKi8KLSAgICBwcm90ZWN0ZWQgT2JqZWN0IGZBY3R1YWxWYWx1ZSA9IG51bGw7Ci0KLSAgICAvKiogc2NoZW1hIGFjdHVhbCB2YWx1ZSB0eXBlICovCi0gICAgcHJvdGVjdGVkIHNob3J0IGZBY3R1YWxWYWx1ZVR5cGUgPSBYU0NvbnN0YW50cy5VTkFWQUlMQUJMRV9EVDsKLQotICAgIC8qKiBhY3R1YWwgdmFsdWUgdHlwZXMgaWYgdGhlIHZhbHVlIGlzIGEgbGlzdCAqLwotICAgIHByb3RlY3RlZCBTaG9ydExpc3QgZkl0ZW1WYWx1ZVR5cGVzID0gbnVsbDsKLQotICAgIC8qKiBodHRwOi8vd3d3LnczLm9yZy9UUi94bWxzY2hlbWEtMS8jZS1ub3RhdGlvbiovCi0gICAgcHJvdGVjdGVkIFhTTm90YXRpb25EZWNsYXJhdGlvbiBmTm90YXRpb24gPSBudWxsOwotCi0gICAgLyoqIG1lbWJlciB0eXBlIGRlZmluaXRpb24gYWdhaW5zdCB3aGljaCBlbGVtZW50IHdhcyB2YWxpZGF0ZWQgKi8KLSAgICBwcm90ZWN0ZWQgWFNTaW1wbGVUeXBlRGVmaW5pdGlvbiBmTWVtYmVyVHlwZSA9IG51bGw7Ci0KLSAgICAvKiogdmFsaWRhdGlvbiBhdHRlbXB0ZWQ6IG5vbmUsIHBhcnRpYWwsIGZ1bGwgKi8KLSAgICBwcm90ZWN0ZWQgc2hvcnQgZlZhbGlkYXRpb25BdHRlbXB0ZWQgPSBFbGVtZW50UFNWSS5WQUxJREFUSU9OX05PTkU7Ci0KLSAgICAvKiogdmFsaWRpdHk6IHZhbGlkLCBpbnZhbGlkLCB1bmtub3duICovCi0gICAgcHJvdGVjdGVkIHNob3J0IGZWYWxpZGl0eSA9IEVsZW1lbnRQU1ZJLlZBTElESVRZX05PVEtOT1dOOwotCi0gICAgLyoqIGVycm9yIGNvZGVzICovCi0gICAgcHJvdGVjdGVkIFN0cmluZ0xpc3QgZkVycm9yQ29kZXMgPSBudWxsOwotCi0gICAgLyoqIHZhbGlkYXRpb24gY29udGV4dDogY291bGQgYmUgUU5hbWUgb3IgWFBhdGggZXhwcmVzc2lvbiovCi0gICAgcHJvdGVjdGVkIFN0cmluZyBmVmFsaWRhdGlvbkNvbnRleHQgPSBudWxsOwotCi0gICAgLyoqIHRoZSBzY2hlbWEgaW5mb3JtYXRpb24gcHJvcGVydHkgKi8KLSAgICBwcm90ZWN0ZWQgWFNNb2RlbCBmU2NoZW1hSW5mb3JtYXRpb24gPSBudWxsOwotCi0gICAgLy8KLSAgICAvLyBFbGVtZW50UFNWSSBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFtzY2hlbWEgZGVmYXVsdF0KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIGNhbm9uaWNhbCBsZXhpY2FsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBkZWNsYXJhdGlvbidzIHt2YWx1ZSBjb25zdHJhaW50fSB2YWx1ZS4KLSAgICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3htbHNjaGVtYS0xLyNlLXNjaGVtYV9kZWZhdWx0PlhNTCBTY2hlbWEgUGFydCAxOiBTdHJ1Y3R1cmVzIFtzY2hlbWEgZGVmYXVsdF08L2E+Ci0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRTY2hlbWFEZWZhdWx0KCkgewotICAgICAgICByZXR1cm4gZkRlY2xhcmF0aW9uID09IG51bGwgPyBudWxsIDogZkRlY2xhcmF0aW9uLmdldENvbnN0cmFpbnRWYWx1ZSgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFtzY2hlbWEgbm9ybWFsaXplZCB2YWx1ZV0KLSAgICAgKgotICAgICAqCi0gICAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94bWxzY2hlbWEtMS8jZS1zY2hlbWFfbm9ybWFsaXplZF92YWx1ZT5YTUwgU2NoZW1hIFBhcnQgMTogU3RydWN0dXJlcyBbc2NoZW1hIG5vcm1hbGl6ZWQgdmFsdWVdPC9hPgotICAgICAqIEByZXR1cm4gdGhlIG5vcm1hbGl6ZWQgdmFsdWUgb2YgdGhpcyBpdGVtIGFmdGVyIHZhbGlkYXRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFNjaGVtYU5vcm1hbGl6ZWRWYWx1ZSgpIHsKLSAgICAgICAgcmV0dXJuIGZOb3JtYWxpemVkVmFsdWU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogW3NjaGVtYSBzcGVjaWZpZWRdCi0gICAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94bWxzY2hlbWEtMS8jZS1zY2hlbWFfc3BlY2lmaWVkIj5YTUwgU2NoZW1hIFBhcnQgMTogU3RydWN0dXJlcyBbc2NoZW1hIHNwZWNpZmllZF08L2E+Ci0gICAgICogQHJldHVybiBmYWxzZSB2YWx1ZSB3YXMgc3BlY2lmaWVkIGluIHNjaGVtYSwgdHJ1ZSB2YWx1ZSBjb21lcyBmcm9tIHRoZSBpbmZvc2V0Ci0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0SXNTY2hlbWFTcGVjaWZpZWQoKSB7Ci0gICAgICAgIHJldHVybiBmU3BlY2lmaWVkOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIERldGVybWluZXMgdGhlIGV4dGVudCB0byB3aGljaCB0aGUgZG9jdW1lbnQgaGFzIGJlZW4gdmFsaWRhdGVkCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHJldHVybiB0aGUgW3ZhbGlkYXRpb24gYXR0ZW1wdGVkXSBwcm9wZXJ0eS4gVGhlIHBvc3NpYmxlIHZhbHVlcyBhcmUKLSAgICAgKiAgICAgICAgIE5PX1ZBTElEQVRJT04sIFBBUlRJQUxfVkFMSURBVElPTiBhbmQgRlVMTF9WQUxJREFUSU9OCi0gICAgICovCi0gICAgcHVibGljIHNob3J0IGdldFZhbGlkYXRpb25BdHRlbXB0ZWQoKSB7Ci0gICAgICAgIHJldHVybiBmVmFsaWRhdGlvbkF0dGVtcHRlZDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBEZXRlcm1pbmUgdGhlIHZhbGlkaXR5IG9mIHRoZSBub2RlIHdpdGggcmVzcGVjdAotICAgICAqIHRvIHRoZSB2YWxpZGF0aW9uIGJlaW5nIGF0dGVtcHRlZAotICAgICAqCi0gICAgICogQHJldHVybiByZXR1cm4gdGhlIFt2YWxpZGl0eV0gcHJvcGVydHkuIFBvc3NpYmxlIHZhbHVlcyBhcmU6Ci0gICAgICogICAgICAgICBVTktOT1dOX1ZBTElESVRZLCBJTlZBTElEX1ZBTElESVRZLCBWQUxJRF9WQUxJRElUWQotICAgICAqLwotICAgIHB1YmxpYyBzaG9ydCBnZXRWYWxpZGl0eSgpIHsKLSAgICAgICAgcmV0dXJuIGZWYWxpZGl0eTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBIGxpc3Qgb2YgZXJyb3IgY29kZXMgZ2VuZXJhdGVkIGZyb20gdmFsaWRhdGlvbiBhdHRlbXB0cy4KLSAgICAgKiBOZWVkIHRvIGZpbmQgYWxsIHRoZSBwb3NzaWJsZSBzdWJjbGF1c2UgcmVwb3J0cyB0aGF0IG5lZWQgcmVwb3J0aW5nCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIEFycmF5IG9mIGVycm9yIGNvZGVzCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZ0xpc3QgZ2V0RXJyb3JDb2RlcygpIHsKLSAgICAgICAgcmV0dXJuIGZFcnJvckNvZGVzOwotICAgIH0KLQotCi0gICAgLy8gVGhpcyBpcyB0aGUgb25seSBpbmZvcm1hdGlvbiB3ZSBjYW4gcHJvdmlkZSBpbiBhIHBpcGVsaW5lLgotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VmFsaWRhdGlvbkNvbnRleHQoKSB7Ci0gICAgICAgIHJldHVybiBmVmFsaWRhdGlvbkNvbnRleHQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogW25pbF0KLSAgICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3htbHNjaGVtYS0xLyNlLW5pbD5YTUwgU2NoZW1hIFBhcnQgMTogU3RydWN0dXJlcyBbbmlsXTwvYT4KLSAgICAgKiBAcmV0dXJuIHRydWUgaWYgY2xhdXNlIDMuMiBvZiBFbGVtZW50IExvY2FsbHkgVmFsaWQgKEVsZW1lbnQpICgzLjMuNCkgYWJvdmUgaXMgc2F0aXNmaWVkLCBvdGhlcndpc2UgZmFsc2UKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXROaWwoKSB7Ci0gICAgICAgIHJldHVybiBmTmlsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFtub3RhdGlvbl0KLSAgICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3htbHNjaGVtYS0xLyNlLW5vdGF0aW9uPlhNTCBTY2hlbWEgUGFydCAxOiBTdHJ1Y3R1cmVzIFtub3RhdGlvbl08L2E+Ci0gICAgICogQHJldHVybiBUaGUgbm90YXRpb24gZGVjbGFyYXRpb24uCi0gICAgICovCi0gICAgcHVibGljIFhTTm90YXRpb25EZWNsYXJhdGlvbiBnZXROb3RhdGlvbigpIHsKLSAgICAgICAgcmV0dXJuIGZOb3RhdGlvbjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBbiBpdGVtIGlzb21vcnBoaWMgdG8gdGhlIHR5cGUgZGVmaW5pdGlvbiB1c2VkIHRvIHZhbGlkYXRlIHRoaXMgZWxlbWVudC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gIGEgdHlwZSBkZWNsYXJhdGlvbgotICAgICAqLwotICAgIHB1YmxpYyBYU1R5cGVEZWZpbml0aW9uIGdldFR5cGVEZWZpbml0aW9uKCkgewotICAgICAgICByZXR1cm4gZlR5cGVEZWNsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIElmIGFuZCBvbmx5IGlmIHRoYXQgdHlwZSBkZWZpbml0aW9uIGlzIGEgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbgotICAgICAqIHdpdGgge3ZhcmlldHl9IHVuaW9uLCBvciBhIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uIHdob3NlIHtjb250ZW50IHR5cGV9Ci0gICAgICogaXMgYSBzaW1wbGUgdGh5cGUgZGVmaW5pdGlvbiB3aXRoIHt2YXJpZXR5fSB1bmlvbiwgdGhlbiBhbiBpdGVtIGlzb21vcnBoaWMKLSAgICAgKiB0byB0aGF0IG1lbWJlciBvZiB0aGUgdW5pb24ncyB7bWVtYmVyIHR5cGUgZGVmaW5pdGlvbnN9IHdoaWNoIGFjdHVhbGx5Ci0gICAgICogdmFsaWRhdGVkIHRoZSBlbGVtZW50IGl0ZW0ncyBub3JtYWxpemVkIHZhbHVlLgotICAgICAqCi0gICAgICogQHJldHVybiAgYSBzaW1wbGUgdHlwZSBkZWNsYXJhdGlvbgotICAgICAqLwotICAgIHB1YmxpYyBYU1NpbXBsZVR5cGVEZWZpbml0aW9uIGdldE1lbWJlclR5cGVEZWZpbml0aW9uKCkgewotICAgICAgICByZXR1cm4gZk1lbWJlclR5cGU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQW4gaXRlbSBpc29tb3JwaGljIHRvIHRoZSBlbGVtZW50IGRlY2xhcmF0aW9uIHVzZWQgdG8gdmFsaWRhdGUKLSAgICAgKiB0aGlzIGVsZW1lbnQuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuICBhbiBlbGVtZW50IGRlY2xhcmF0aW9uCi0gICAgICovCi0gICAgcHVibGljIFhTRWxlbWVudERlY2xhcmF0aW9uIGdldEVsZW1lbnREZWNsYXJhdGlvbigpIHsKLSAgICAgICAgcmV0dXJuIGZEZWNsYXJhdGlvbjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBbc2NoZW1hIGluZm9ybWF0aW9uXQotICAgICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveG1sc2NoZW1hLTEvI2Utc2NoZW1hX2luZm9ybWF0aW9uIj5YTUwgU2NoZW1hIFBhcnQgMTogU3RydWN0dXJlcyBbc2NoZW1hIGluZm9ybWF0aW9uXTwvYT4KLSAgICAgKiBAcmV0dXJuIFRoZSBzY2hlbWEgaW5mb3JtYXRpb24gcHJvcGVydHkgaWYgaXQncyB0aGUgdmFsaWRhdGlvbiByb290LAotICAgICAqICAgICAgICAgbnVsbCBvdGhlcndpc2UuCi0gICAgICovCi0gICAgcHVibGljIFhTTW9kZWwgZ2V0U2NoZW1hSW5mb3JtYXRpb24oKSB7Ci0gICAgICAgIHJldHVybiBmU2NoZW1hSW5mb3JtYXRpb247Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29weSBQU1ZJIHByb3BlcnRpZXMgZnJvbSBhbm90aGVyIHBzdmkgaXRlbS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBhdHRyICB0aGUgc291cmNlIG9mIGF0dHJpYnV0ZSBQU1ZJIGl0ZW1zCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0UFNWSShFbGVtZW50UFNWSSBlbGVtKSB7Ci0gICAgICAgIHRoaXMuZkRlY2xhcmF0aW9uID0gZWxlbS5nZXRFbGVtZW50RGVjbGFyYXRpb24oKTsKLSAgICAgICAgdGhpcy5mTm90YXRpb24gPSBlbGVtLmdldE5vdGF0aW9uKCk7Ci0gICAgICAgIHRoaXMuZlZhbGlkYXRpb25Db250ZXh0ID0gZWxlbS5nZXRWYWxpZGF0aW9uQ29udGV4dCgpOwotICAgICAgICB0aGlzLmZUeXBlRGVjbCA9IGVsZW0uZ2V0VHlwZURlZmluaXRpb24oKTsKLSAgICAgICAgdGhpcy5mU2NoZW1hSW5mb3JtYXRpb24gPSBlbGVtLmdldFNjaGVtYUluZm9ybWF0aW9uKCk7Ci0gICAgICAgIHRoaXMuZlZhbGlkaXR5ID0gZWxlbS5nZXRWYWxpZGl0eSgpOwotICAgICAgICB0aGlzLmZWYWxpZGF0aW9uQXR0ZW1wdGVkID0gZWxlbS5nZXRWYWxpZGF0aW9uQXR0ZW1wdGVkKCk7Ci0gICAgICAgIHRoaXMuZkVycm9yQ29kZXMgPSBlbGVtLmdldEVycm9yQ29kZXMoKTsKLSAgICAgICAgdGhpcy5mTm9ybWFsaXplZFZhbHVlID0gZWxlbS5nZXRTY2hlbWFOb3JtYWxpemVkVmFsdWUoKTsKLSAgICAgICAgdGhpcy5mQWN0dWFsVmFsdWUgPSBlbGVtLmdldEFjdHVhbE5vcm1hbGl6ZWRWYWx1ZSgpOwotICAgICAgICB0aGlzLmZBY3R1YWxWYWx1ZVR5cGUgPSBlbGVtLmdldEFjdHVhbE5vcm1hbGl6ZWRWYWx1ZVR5cGUoKTsKLSAgICAgICAgdGhpcy5mSXRlbVZhbHVlVHlwZXMgPSBlbGVtLmdldEl0ZW1WYWx1ZVR5cGVzKCk7Ci0gICAgICAgIHRoaXMuZk1lbWJlclR5cGUgPSBlbGVtLmdldE1lbWJlclR5cGVEZWZpbml0aW9uKCk7Ci0gICAgICAgIHRoaXMuZlNwZWNpZmllZCA9IGVsZW0uZ2V0SXNTY2hlbWFTcGVjaWZpZWQoKTsKLSAgICAgICAgdGhpcy5mTmlsID0gZWxlbS5nZXROaWwoKTsKLSAgICB9Ci0KLSAgICAvKiAobm9uLUphdmFkb2MpCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLkl0ZW1QU1ZJI2dldEFjdHVhbE5vcm1hbGl6ZWRWYWx1ZSgpCi0gICAgICovCi0gICAgcHVibGljIE9iamVjdCBnZXRBY3R1YWxOb3JtYWxpemVkVmFsdWUoKSB7Ci0gICAgICAgIHJldHVybiB0aGlzLmZBY3R1YWxWYWx1ZTsKLSAgICB9Ci0KLSAgICAvKiAobm9uLUphdmFkb2MpCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLkl0ZW1QU1ZJI2dldEFjdHVhbE5vcm1hbGl6ZWRWYWx1ZVR5cGUoKQotICAgICAqLwotICAgIHB1YmxpYyBzaG9ydCBnZXRBY3R1YWxOb3JtYWxpemVkVmFsdWVUeXBlKCkgewotICAgICAgICByZXR1cm4gdGhpcy5mQWN0dWFsVmFsdWVUeXBlOwotICAgIH0KLQotICAgIC8qIChub24tSmF2YWRvYykKLSAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuSXRlbVBTVkkjZ2V0SXRlbVZhbHVlVHlwZXMoKQotICAgICAqLwotICAgIHB1YmxpYyBTaG9ydExpc3QgZ2V0SXRlbVZhbHVlVHlwZXMoKSB7Ci0gICAgICAgIHJldHVybiB0aGlzLmZJdGVtVmFsdWVUeXBlczsKLSAgICB9Ci0KLSAgICAvLyBSRVZJU0lUOiBGb3JiaWQgc2VyaWFsaXphdGlvbiBvZiBQU1ZJIERPTSB1bnRpbAotICAgIC8vIHdlIHN1cHBvcnQgb2JqZWN0IHNlcmlhbGl6YXRpb24gb2YgZ3JhbW1hcnMgLS0gbXJnbGF2YXMKLQotICAgIHByaXZhdGUgdm9pZCB3cml0ZU9iamVjdChPYmplY3RPdXRwdXRTdHJlYW0gb3V0KQotICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgICAgICB0aHJvdyBuZXcgTm90U2VyaWFsaXphYmxlRXhjZXB0aW9uKGdldENsYXNzKCkuZ2V0TmFtZSgpKTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgcmVhZE9iamVjdChPYmplY3RJbnB1dFN0cmVhbSBpbikKLSAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHsKLSAgICAgICAgdGhyb3cgbmV3IE5vdFNlcmlhbGl6YWJsZUV4Y2VwdGlvbihnZXRDbGFzcygpLmdldE5hbWUoKSk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL1BhcmVudE5vZGUuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9QYXJlbnROb2RlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDJlMTk5N2UuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL1BhcmVudE5vZGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEwMzcgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAxNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqLwotLyoKLSAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQotICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCi0gKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCi0gKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAotICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKLSAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tOwotCi1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uT2JqZWN0T3V0cHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOwotCi1pbXBvcnQgb3JnLnczYy5kb20uRE9NRXhjZXB0aW9uOwotaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZUxpc3Q7Ci1pbXBvcnQgb3JnLnczYy5kb20uVXNlckRhdGFIYW5kbGVyOwotCi0vKioKLSAqIFBhcmVudE5vZGUgaW5oZXJpdHMgZnJvbSBDaGlsZE5vZGUgYW5kIGFkZHMgdGhlIGNhcGFiaWxpdHkgb2YgaGF2aW5nIGNoaWxkCi0gKiBub2Rlcy4gTm90IGV2ZXJ5IG5vZGUgaW4gdGhlIERPTSBjYW4gaGF2ZSBjaGlsZHJlbiwgc28gb25seSBub2RlcyB0aGF0IGNhbgotICogc2hvdWxkIGluaGVyaXQgZnJvbSB0aGlzIGNsYXNzIGFuZCBwYXkgdGhlIHByaWNlIGZvciBpdC4KLSAqIDxQPgotICogUGFyZW50Tm9kZSwganVzdCBsaWtlIE5vZGVJbXBsLCBhbHNvIGltcGxlbWVudHMgTm9kZUxpc3QsIHNvIGl0IGNhbgotICogcmV0dXJuIGl0c2VsZiBpbiByZXNwb25zZSB0byB0aGUgZ2V0Q2hpbGROb2RlcygpIHF1ZXJ5LiBUaGlzIGVsaW1pbmlhdGVzCi0gKiB0aGUgbmVlZCBmb3IgYSBzZXBhcmF0ZSBDaGlsZE5vZGVMaXN0IG9iamVjdC4gTm90ZSB0aGF0IHRoaXMgaXMgYW4KLSAqIElNUExFTUVOVEFUSU9OIERFVEFJTDsgYXBwbGljYXRpb25zIHNob3VsZCBfbmV2ZXJfIGFzc3VtZSB0aGF0Ci0gKiB0aGlzIGlkZW50aXR5IGV4aXN0cy4gT24gdGhlIG90aGVyIGhhbmQsIHN1YmNsYXNzZXMgbWF5IG5lZWQgdG8gb3ZlcnJpZGUKLSAqIHRoaXMsIGluIGNhc2Ugb2YgY29uZmxpY3RpbmcgbmFtZXMuIFRoaXMgaXMgdGhlIGNhc2UgZm9yIHRoZSBjbGFzc2VzCi0gKiBIVE1MU2VsZWN0RWxlbWVudEltcGwgYW5kIEhUTUxGb3JtRWxlbWVudEltcGwgb2YgdGhlIEhUTUwgRE9NLgotICogPFA+Ci0gKiBXaGlsZSB3ZSBoYXZlIGEgZGlyZWN0IHJlZmVyZW5jZSB0byB0aGUgZmlyc3QgY2hpbGQsIHRoZSBsYXN0IGNoaWxkIGlzCi0gKiBzdG9yZWQgYXMgdGhlIHByZXZpb3VzIHNpYmxpbmcgb2YgdGhlIGZpcnN0IGNoaWxkLiBGaXJzdCBjaGlsZCBub2RlcyBhcmUKLSAqIG1hcmtlZCBhcyBiZWluZyBzbywgYW5kIGdldE5leHRTaWJsaW5nIGhpZGVzIHRoaXMgZmFjdC4KLSAqIDxQPk5vdGU6IE5vdCBhbGwgcGFyZW50IG5vZGVzIGFjdHVhbGx5IG5lZWQgdG8gYWxzbyBiZSBhIGNoaWxkLiBBdCBzb21lCi0gKiBwb2ludCB3ZSB1c2VkIHRvIGhhdmUgUGFyZW50Tm9kZSBpbmhlcml0aW5nIGZyb20gTm9kZUltcGwgYW5kIGFub3RoZXIgY2xhc3MKLSAqIGNhbGxlZCBDaGlsZEFuZFBhcmVudE5vZGUgdGhhdCBpbmhlcml0ZWQgZnJvbSBDaGlsZE5vZGUuIEJ1dCBkdWUgdG8gdGhlIGxhY2sKLSAqIG9mIG11bHRpcGxlIGluaGVyaXRhbmNlIGEgbG90IG9mIGNvZGUgaGFkIHRvIGJlIGR1cGxpY2F0ZWQgd2hpY2ggbGVkIHRvIGEKLSAqIG1haW50ZW5hbmNlIG5pZ2h0bWFyZS4gQXQgdGhlIHNhbWUgdGltZSBvbmx5IGEgZmV3IG5vZGVzIChEb2N1bWVudCwKLSAqIERvY3VtZW50RnJhZ21lbnQsIEVudGl0eSwgYW5kIEF0dHJpYnV0ZSkgY2Fubm90IGJlIGEgY2hpbGQgc28gdGhlIGdhaW4gaW4KLSAqIG1lbW9yeSB3YXNuJ3QgcmVhbGx5IHdvcnRoIGl0LiBUaGUgb25seSB0eXBlIGZvciB3aGljaCB0aGlzIHdvdWxkIGJlIHRoZQotICogY2FzZSBpcyBBdHRyaWJ1dGUsIGJ1dCB3ZSBkZWFsIHdpdGggdGhlcmUgaW4gYW5vdGhlciBzcGVjaWFsIHdheSwgc28gdGhpcyBpcwotICogbm90IGFwcGxpY2FibGUuCi0gKiA8cD4KLSAqIFRoaXMgY2xhc3MgZG9lc24ndCBkaXJlY3RseSBzdXBwb3J0IG11dGF0aW9uIGV2ZW50cywgaG93ZXZlciwgaXQgbm90aWZpZXMKLSAqIHRoZSBkb2N1bWVudCB3aGVuIG11dGF0aW9ucyBhcmUgcGVyZm9ybWVkIHNvIHRoYXQgdGhlIGRvY3VtZW50IGNsYXNzIGRvIHNvLgotICoKLSAqIDxwPjxiPldBUk5JTkc8L2I+OiBTb21lIG9mIHRoZSBjb2RlIGhlcmUgaXMgcGFydGlhbGx5IGR1cGxpY2F0ZWQgaW4KLSAqIEF0dHJJbXBsLCBiZSBjYXJlZnVsIHRvIGtlZXAgdGhlc2UgdHdvIGNsYXNzZXMgaW4gc3luYyEKLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBBcm5hdWQgIExlIEhvcnMsIElCTQotICogQGF1dGhvciBKb2UgS2Vzc2VsbWFuLCBJQk0KLSAqIEBhdXRob3IgQW5keSBDbGFyaywgSUJNCi0gKiBAdmVyc2lvbiAkSWQ6IFBhcmVudE5vZGUuamF2YSx2IDEuNiAyMDA5LzA3LzIxIDIwOjMwOjI4IGpvZWh3IEV4cCAkCi0gKi8KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBQYXJlbnROb2RlCi0gICAgZXh0ZW5kcyBDaGlsZE5vZGUgewotCi0gICAgLyoqIFNlcmlhbGl6YXRpb24gdmVyc2lvbi4gKi8KLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMjgxNTgyOTg2NzE1MjEyMDg3Mkw7Ci0KLSAgICAvKiogT3duZXIgZG9jdW1lbnQuICovCi0gICAgcHJvdGVjdGVkIENvcmVEb2N1bWVudEltcGwgb3duZXJEb2N1bWVudDsKLQotICAgIC8qKiBGaXJzdCBjaGlsZC4gKi8KLSAgICBwcm90ZWN0ZWQgQ2hpbGROb2RlIGZpcnN0Q2hpbGQgPSBudWxsOwotCi0gICAgLy8gdHJhbnNpZW50cwotCi0gICAgLyoqIE5vZGVMaXN0IGNhY2hlICovCi0gICAgcHJvdGVjdGVkIHRyYW5zaWVudCBOb2RlTGlzdENhY2hlIGZOb2RlTGlzdENhY2hlID0gbnVsbDsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIE5vIHB1YmxpYyBjb25zdHJ1Y3Rvcjsgb25seSBzdWJjbGFzc2VzIG9mIFBhcmVudE5vZGUgc2hvdWxkIGJlCi0gICAgICogaW5zdGFudGlhdGVkLCBhbmQgdGhvc2Ugbm9ybWFsbHkgdmlhIGEgRG9jdW1lbnQncyBmYWN0b3J5IG1ldGhvZHMKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgUGFyZW50Tm9kZShDb3JlRG9jdW1lbnRJbXBsIG93bmVyRG9jdW1lbnQpIHsKLSAgICAgICAgc3VwZXIob3duZXJEb2N1bWVudCk7Ci0gICAgICAgIHRoaXMub3duZXJEb2N1bWVudCA9IG93bmVyRG9jdW1lbnQ7Ci0gICAgfQotCi0gICAgLyoqIENvbnN0cnVjdG9yIGZvciBzZXJpYWxpemF0aW9uLiAqLwotICAgIHB1YmxpYyBQYXJlbnROb2RlKCkge30KLQotICAgIC8vCi0gICAgLy8gTm9kZUxpc3QgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGEgZHVwbGljYXRlIG9mIGEgZ2l2ZW4gbm9kZS4gWW91IGNhbiBjb25zaWRlciB0aGlzIGEKLSAgICAgKiBnZW5lcmljICJjb3B5IGNvbnN0cnVjdG9yIiBmb3Igbm9kZXMuIFRoZSBuZXdseSByZXR1cm5lZCBvYmplY3Qgc2hvdWxkCi0gICAgICogYmUgY29tcGxldGVseSBpbmRlcGVuZGVudCBvZiB0aGUgc291cmNlIG9iamVjdCdzIHN1YnRyZWUsIHNvIGNoYW5nZXMKLSAgICAgKiBpbiBvbmUgYWZ0ZXIgdGhlIGNsb25lIGhhcyBiZWVuIG1hZGUgd2lsbCBub3QgYWZmZWN0IHRoZSBvdGhlci4KLSAgICAgKiA8cD4KLSAgICAgKiBFeGFtcGxlOiBDbG9uaW5nIGEgVGV4dCBub2RlIHdpbGwgY29weSBib3RoIHRoZSBub2RlIGFuZCB0aGUgdGV4dCBpdAotICAgICAqIGNvbnRhaW5zLgotICAgICAqIDxwPgotICAgICAqIEV4YW1wbGU6IENsb25pbmcgc29tZXRoaW5nIHRoYXQgaGFzIGNoaWxkcmVuIC0tIEVsZW1lbnQgb3IgQXR0ciwgZm9yCi0gICAgICogZXhhbXBsZSAtLSB3aWxsIF9ub3RfIGNsb25lIHRob3NlIGNoaWxkcmVuIHVubGVzcyBhICJkZWVwIGNsb25lIgotICAgICAqIGhhcyBiZWVuIHJlcXVlc3RlZC4gQSBzaGFsbG93IGNsb25lIG9mIGFuIEF0dHIgbm9kZSB3aWxsIHlpZWxkIGFuCi0gICAgICogZW1wdHkgQXR0ciBvZiB0aGUgc2FtZSBuYW1lLgotICAgICAqIDxwPgotICAgICAqIE5PVEU6IENsb25lcyB3aWxsIGFsd2F5cyBiZSByZWFkL3dyaXRlLCBldmVuIGlmIHRoZSBub2RlIGJlaW5nIGNsb25lZAotICAgICAqIGlzIHJlYWQtb25seSwgdG8gcGVybWl0IGFwcGxpY2F0aW9ucyB1c2luZyBvbmx5IHRoZSBET00gQVBJIHRvIG9idGFpbgotICAgICAqIGVkaXRhYmxlIGNvcGllcyBvZiBsb2NrZWQgcG9ydGlvbnMgb2YgdGhlIHRyZWUuCi0gICAgICovCi0gICAgcHVibGljIE5vZGUgY2xvbmVOb2RlKGJvb2xlYW4gZGVlcCkgewotCi0gICAgICAgIGlmIChuZWVkc1N5bmNDaGlsZHJlbigpKSB7Ci0gICAgICAgICAgICBzeW5jaHJvbml6ZUNoaWxkcmVuKCk7Ci0gICAgICAgIH0KLSAgICAgICAgUGFyZW50Tm9kZSBuZXdub2RlID0gKFBhcmVudE5vZGUpIHN1cGVyLmNsb25lTm9kZShkZWVwKTsKLQotICAgICAgICAvLyBzZXQgb3duZXIgZG9jdW1lbnQKLSAgICAgICAgbmV3bm9kZS5vd25lckRvY3VtZW50ID0gb3duZXJEb2N1bWVudDsKLQotICAgICAgICAvLyBOZWVkIHRvIGJyZWFrIHRoZSBhc3NvY2lhdGlvbiB3LyBvcmlnaW5hbCBraWRzCi0gICAgICAgIG5ld25vZGUuZmlyc3RDaGlsZCAgICAgID0gbnVsbDsKLQotICAgICAgICAvLyBpbnZhbGlkYXRlIGNhY2hlIGZvciBjaGlsZHJlbiBOb2RlTGlzdAotICAgICAgICBuZXdub2RlLmZOb2RlTGlzdENhY2hlID0gbnVsbDsKLQotICAgICAgICAvLyBUaGVuLCBpZiBkZWVwLCBjbG9uZSB0aGUga2lkcyB0b28uCi0gICAgICAgIGlmIChkZWVwKSB7Ci0gICAgICAgICAgICBmb3IgKENoaWxkTm9kZSBjaGlsZCA9IGZpcnN0Q2hpbGQ7Ci0gICAgICAgICAgICAgICAgIGNoaWxkICE9IG51bGw7Ci0gICAgICAgICAgICAgICAgIGNoaWxkID0gY2hpbGQubmV4dFNpYmxpbmcpIHsKLSAgICAgICAgICAgICAgICBuZXdub2RlLmFwcGVuZENoaWxkKGNoaWxkLmNsb25lTm9kZSh0cnVlKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gbmV3bm9kZTsKLQotICAgIH0gLy8gY2xvbmVOb2RlKGJvb2xlYW4pOk5vZGUKLQotICAgIC8qKgotICAgICAqIEZpbmQgdGhlIERvY3VtZW50IHRoYXQgdGhpcyBOb2RlIGJlbG9uZ3MgdG8gKHRoZSBkb2N1bWVudCBpbgotICAgICAqIHdob3NlIGNvbnRleHQgdGhlIE5vZGUgd2FzIGNyZWF0ZWQpLiBUaGUgTm9kZSBtYXkgb3IgbWF5IG5vdAotICAgICAqIGN1cnJlbnRseSBiZSBwYXJ0IG9mIHRoYXQgRG9jdW1lbnQncyBhY3R1YWwgY29udGVudHMuCi0gICAgICovCi0gICAgcHVibGljIERvY3VtZW50IGdldE93bmVyRG9jdW1lbnQoKSB7Ci0gICAgICAgIHJldHVybiBvd25lckRvY3VtZW50OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIHNhbWUgYXMgYWJvdmUgYnV0IHJldHVybnMgaW50ZXJuYWwgdHlwZSBhbmQgdGhpcyBvbmUgaXMgbm90IG92ZXJyaWRkZW4KLSAgICAgKiBieSBDb3JlRG9jdW1lbnRJbXBsIHRvIHJldHVybiBudWxsCi0gICAgICovCi0gICAgQ29yZURvY3VtZW50SW1wbCBvd25lckRvY3VtZW50KCkgewotICAgICAgICByZXR1cm4gb3duZXJEb2N1bWVudDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBOT04tRE9NCi0gICAgICogc2V0IHRoZSBvd25lckRvY3VtZW50IG9mIHRoaXMgbm9kZSBhbmQgaXRzIGNoaWxkcmVuCi0gICAgICovCi0gICAgdm9pZCBzZXRPd25lckRvY3VtZW50KENvcmVEb2N1bWVudEltcGwgZG9jKSB7Ci0gICAgICAgIGlmIChuZWVkc1N5bmNDaGlsZHJlbigpKSB7Ci0gICAgICAgICAgICBzeW5jaHJvbml6ZUNoaWxkcmVuKCk7Ci0gICAgICAgIH0KLSAgICAgICBmb3IgKENoaWxkTm9kZSBjaGlsZCA9IGZpcnN0Q2hpbGQ7Ci0gICAgICAgICAgICAgY2hpbGQgIT0gbnVsbDsgY2hpbGQgPSBjaGlsZC5uZXh0U2libGluZykgewotICAgICAgICAgICAgIGNoaWxkLnNldE93bmVyRG9jdW1lbnQoZG9jKTsKLSAgICAgICAgfQotICAgICAgICAvKiBzZXR0aW5nIHRoZSBvd25lciBkb2N1bWVudCBvZiBzZWxmLCBhZnRlciBpdCdzIGNoaWxkcmVuIG1ha2VzIHRoZQotICAgICAgICAgICBkYXRhIG9mIGNoaWxkcmVuIGF2YWlsYWJsZSB0byB0aGUgbmV3IGRvY3VtZW50LiAqLwotICAgICAgICBzdXBlci5zZXRPd25lckRvY3VtZW50KGRvYyk7Ci0gICAgICAgIG93bmVyRG9jdW1lbnQgPSBkb2M7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGVzdCB3aGV0aGVyIHRoaXMgbm9kZSBoYXMgYW55IGNoaWxkcmVuLiBDb252ZW5pZW5jZSBzaG9ydGhhbmQKLSAgICAgKiBmb3IgKE5vZGUuZ2V0Rmlyc3RDaGlsZCgpIT1udWxsKQotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGhhc0NoaWxkTm9kZXMoKSB7Ci0gICAgICAgIGlmIChuZWVkc1N5bmNDaGlsZHJlbigpKSB7Ci0gICAgICAgICAgICBzeW5jaHJvbml6ZUNoaWxkcmVuKCk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGZpcnN0Q2hpbGQgIT0gbnVsbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBPYnRhaW4gYSBOb2RlTGlzdCBlbnVtZXJhdGluZyBhbGwgY2hpbGRyZW4gb2YgdGhpcyBub2RlLiBJZiB0aGVyZQotICAgICAqIGFyZSBub25lLCBhbiAoaW5pdGlhbGx5KSBlbXB0eSBOb2RlTGlzdCBpcyByZXR1cm5lZC4KLSAgICAgKiA8cD4KLSAgICAgKiBOb2RlTGlzdHMgYXJlICJsaXZlIjsgYXMgY2hpbGRyZW4gYXJlIGFkZGVkL3JlbW92ZWQgdGhlIE5vZGVMaXN0Ci0gICAgICogd2lsbCBpbW1lZGlhdGVseSByZWZsZWN0IHRob3NlIGNoYW5nZXMuIEFsc28sIHRoZSBOb2RlTGlzdCByZWZlcnMKLSAgICAgKiB0byB0aGUgYWN0dWFsIG5vZGVzLCBzbyBjaGFuZ2VzIHRvIHRob3NlIG5vZGVzIG1hZGUgdmlhIHRoZSBET00gdHJlZQotICAgICAqIHdpbGwgYmUgcmVmbGVjdGVkIGluIHRoZSBOb2RlTGlzdCBhbmQgdmljZSB2ZXJzYS4KLSAgICAgKiA8cD4KLSAgICAgKiBJbiB0aGlzIGltcGxlbWVudGF0aW9uLCBOb2RlcyBpbXBsZW1lbnQgdGhlIE5vZGVMaXN0IGludGVyZmFjZSBhbmQKLSAgICAgKiBwcm92aWRlIHRoZWlyIG93biBnZXRDaGlsZE5vZGVzKCkgc3VwcG9ydC4gT3RoZXIgRE9NcyBtYXkgc29sdmUgdGhpcwotICAgICAqIGRpZmZlcmVudGx5LgotICAgICAqLwotICAgIHB1YmxpYyBOb2RlTGlzdCBnZXRDaGlsZE5vZGVzKCkgewotCi0gICAgICAgIGlmIChuZWVkc1N5bmNDaGlsZHJlbigpKSB7Ci0gICAgICAgICAgICBzeW5jaHJvbml6ZUNoaWxkcmVuKCk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHRoaXM7Ci0KLSAgICB9IC8vIGdldENoaWxkTm9kZXMoKTpOb2RlTGlzdAotCi0gICAgLyoqIFRoZSBmaXJzdCBjaGlsZCBvZiB0aGlzIE5vZGUsIG9yIG51bGwgaWYgbm9uZS4gKi8KLSAgICBwdWJsaWMgTm9kZSBnZXRGaXJzdENoaWxkKCkgewotCi0gICAgICAgIGlmIChuZWVkc1N5bmNDaGlsZHJlbigpKSB7Ci0gICAgICAgICAgICBzeW5jaHJvbml6ZUNoaWxkcmVuKCk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGZpcnN0Q2hpbGQ7Ci0KLSAgICB9ICAgLy8gZ2V0Rmlyc3RDaGlsZCgpOk5vZGUKLQotICAgIC8qKiBUaGUgbGFzdCBjaGlsZCBvZiB0aGlzIE5vZGUsIG9yIG51bGwgaWYgbm9uZS4gKi8KLSAgICBwdWJsaWMgTm9kZSBnZXRMYXN0Q2hpbGQoKSB7Ci0KLSAgICAgICAgaWYgKG5lZWRzU3luY0NoaWxkcmVuKCkpIHsKLSAgICAgICAgICAgIHN5bmNocm9uaXplQ2hpbGRyZW4oKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbGFzdENoaWxkKCk7Ci0KLSAgICB9IC8vIGdldExhc3RDaGlsZCgpOk5vZGUKLQotICAgIGZpbmFsIENoaWxkTm9kZSBsYXN0Q2hpbGQoKSB7Ci0gICAgICAgIC8vIGxhc3QgY2hpbGQgaXMgc3RvcmVkIGFzIHRoZSBwcmV2aW91cyBzaWJsaW5nIG9mIGZpcnN0IGNoaWxkCi0gICAgICAgIHJldHVybiBmaXJzdENoaWxkICE9IG51bGwgPyBmaXJzdENoaWxkLnByZXZpb3VzU2libGluZyA6IG51bGw7Ci0gICAgfQotCi0gICAgZmluYWwgdm9pZCBsYXN0Q2hpbGQoQ2hpbGROb2RlIG5vZGUpIHsKLSAgICAgICAgLy8gc3RvcmUgbGFzdENoaWxkIGFzIHByZXZpb3VzIHNpYmxpbmcgb2YgZmlyc3QgY2hpbGQKLSAgICAgICAgaWYgKGZpcnN0Q2hpbGQgIT0gbnVsbCkgewotICAgICAgICAgICAgZmlyc3RDaGlsZC5wcmV2aW91c1NpYmxpbmcgPSBub2RlOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogTW92ZSBvbmUgb3IgbW9yZSBub2RlKHMpIHRvIG91ciBsaXN0IG9mIGNoaWxkcmVuLiBOb3RlIHRoYXQgdGhpcwotICAgICAqIGltcGxpY2l0bHkgcmVtb3ZlcyB0aGVtIGZyb20gdGhlaXIgcHJldmlvdXMgcGFyZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIG5ld0NoaWxkIFRoZSBOb2RlIHRvIGJlIG1vdmVkIHRvIG91ciBzdWJ0cmVlLiBBcyBhCi0gICAgICogY29udmVuaWVuY2UgZmVhdHVyZSwgaW5zZXJ0aW5nIGEgRG9jdW1lbnROb2RlIHdpbGwgaW5zdGVhZCBpbnNlcnQKLSAgICAgKiBhbGwgaXRzIGNoaWxkcmVuLgotICAgICAqCi0gICAgICogQHBhcmFtIHJlZkNoaWxkIEN1cnJlbnQgY2hpbGQgd2hpY2ggbmV3Q2hpbGQgc2hvdWxkIGJlIHBsYWNlZAotICAgICAqIGltbWVkaWF0ZWx5IGJlZm9yZS4gSWYgcmVmQ2hpbGQgaXMgbnVsbCwgdGhlIGluc2VydGlvbiBvY2N1cnMKLSAgICAgKiBhZnRlciBhbGwgZXhpc3RpbmcgTm9kZXMsIGxpa2UgYXBwZW5kQ2hpbGQoKS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gbmV3Q2hpbGQsIGluIGl0cyBuZXcgc3RhdGUgKHJlbG9jYXRlZCwgb3IgZW1wdGllZCBpbiB0aGUgY2FzZSBvZgotICAgICAqIERvY3VtZW50Tm9kZS4pCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbihISUVSQVJDSFlfUkVRVUVTVF9FUlIpIGlmIG5ld0NoaWxkIGlzIG9mIGEKLSAgICAgKiB0eXBlIHRoYXQgc2hvdWxkbid0IGJlIGEgY2hpbGQgb2YgdGhpcyBub2RlLCBvciBpZiBuZXdDaGlsZCBpcyBhbgotICAgICAqIGFuY2VzdG9yIG9mIHRoaXMgbm9kZS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uKFdST05HX0RPQ1VNRU5UX0VSUikgaWYgbmV3Q2hpbGQgaGFzIGEKLSAgICAgKiBkaWZmZXJlbnQgb3duZXIgZG9jdW1lbnQgdGhhbiB3ZSBkby4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uKE5PVF9GT1VORF9FUlIpIGlmIHJlZkNoaWxkIGlzIG5vdCBhIGNoaWxkIG9mCi0gICAgICogdGhpcyBub2RlLgotICAgICAqCi0gICAgICogQHRocm93cyBET01FeGNlcHRpb24oTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSKSBpZiB0aGlzIG5vZGUgaXMKLSAgICAgKiByZWFkLW9ubHkuCi0gICAgICovCi0gICAgcHVibGljIE5vZGUgaW5zZXJ0QmVmb3JlKE5vZGUgbmV3Q2hpbGQsIE5vZGUgcmVmQ2hpbGQpCi0gICAgICAgIHRocm93cyBET01FeGNlcHRpb24gewotICAgICAgICAvLyBUYWlsLWNhbGw7IG9wdGltaXplciBzaG91bGQgYmUgYWJsZSB0byBkbyBnb29kIHRoaW5ncyB3aXRoLgotICAgICAgICByZXR1cm4gaW50ZXJuYWxJbnNlcnRCZWZvcmUobmV3Q2hpbGQsIHJlZkNoaWxkLCBmYWxzZSk7Ci0gICAgfSAvLyBpbnNlcnRCZWZvcmUoTm9kZSxOb2RlKTpOb2RlCi0KLSAgICAvKiogTk9OLURPTSBJTlRFUk5BTDogV2l0aGluIERPTSBhY3Rpb25zLHdlIHNvbWV0aW1lcyBuZWVkIHRvIGJlIGFibGUKLSAgICAgKiB0byBjb250cm9sIHdoaWNoIG11dGF0aW9uIGV2ZW50cyBhcmUgc3Bhd25lZC4gVGhpcyB2ZXJzaW9uIG9mIHRoZQotICAgICAqIGluc2VydEJlZm9yZSBvcGVyYXRpb24gYWxsb3dzIHVzIHRvIGRvIHNvLiBJdCBpcyBub3QgaW50ZW5kZWQKLSAgICAgKiBmb3IgdXNlIGJ5IGFwcGxpY2F0aW9uIHByb2dyYW1zLgotICAgICAqLwotICAgIE5vZGUgaW50ZXJuYWxJbnNlcnRCZWZvcmUoTm9kZSBuZXdDaGlsZCwgTm9kZSByZWZDaGlsZCwgYm9vbGVhbiByZXBsYWNlKQotICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKLQotICAgICAgICBib29sZWFuIGVycm9yQ2hlY2tpbmcgPSBvd25lckRvY3VtZW50LmVycm9yQ2hlY2tpbmc7Ci0KLSAgICAgICAgaWYgKG5ld0NoaWxkLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5ET0NVTUVOVF9GUkFHTUVOVF9OT0RFKSB7Ci0gICAgICAgICAgICAvLyBTTE9XIEJVVCBTQUZFOiBXZSBjb3VsZCBpbnNlcnQgdGhlIHdob2xlIHN1YnRyZWUgd2l0aG91dAotICAgICAgICAgICAgLy8ganVnZ2xpbmcgc28gbWFueSBuZXh0L3ByZXZpb3VzIHBvaW50ZXJzLiAoV2lwZSBvdXQgdGhlCi0gICAgICAgICAgICAvLyBwYXJlbnQncyBjaGlsZC1saXN0LCBwYXRjaCB0aGUgcGFyZW50IHBvaW50ZXJzLCBzZXQgdGhlCi0gICAgICAgICAgICAvLyBlbmRzIG9mIHRoZSBsaXN0LikgQnV0IHdlIGtub3cgc29tZSBzdWJjbGFzc2VzIGhhdmUgc3BlY2lhbC0KLSAgICAgICAgICAgIC8vIGNhc2UgYmVoYXZpb3IgdGhleSBhZGQgdG8gaW5zZXJ0QmVmb3JlKCksIHNvIHdlIGRvbid0IHJpc2sgaXQuCi0gICAgICAgICAgICAvLyBUaGlzIGFwcHJvY2ggYWxzbyB0YWtlcyBmZXdlciBieXRlY29kZXMuCi0KLSAgICAgICAgICAgIC8vIE5PVEU6IElmIG9uZSBvZiB0aGUgY2hpbGRyZW4gaXMgbm90IGEgbGVnYWwgY2hpbGQgb2YgdGhpcwotICAgICAgICAgICAgLy8gbm9kZSwgdGhyb3cgSElFUkFSQ0hZX1JFUVVFU1RfRVJSIGJlZm9yZSBfYW55XyBvZiB0aGUgY2hpbGRyZW4KLSAgICAgICAgICAgIC8vIGhhdmUgYmVlbiB0cmFuc2ZlcnJlZC4gKEFsdGVybmF0aXZlIGJlaGF2aW9ycyB3b3VsZCBiZSB0bwotICAgICAgICAgICAgLy8gcmVwYXJlbnQgdXAgdG8gdGhlIGZpcnN0IGZhaWx1cmUgcG9pbnQgb3IgcmVwYXJlbnQgYWxsIHRob3NlCi0gICAgICAgICAgICAvLyB3aGljaCBhcmUgYWNjZXB0YWJsZSB0byB0aGUgdGFyZ2V0IG5vZGUsIG5laXRoZXIgb2Ygd2hpY2ggaXMKLSAgICAgICAgICAgIC8vIGFzIHJvYnVzdC4gUFItRE9NLTA4MTggaXNuJ3QgZW50aXJlbHkgY2xlYXIgb24gd2hpY2ggaXQKLSAgICAgICAgICAgIC8vIHJlY29tbWVuZHM/Pz8/PwotCi0gICAgICAgICAgICAvLyBObyBuZWVkIHRvIGNoZWNrIGtpZHMgZm9yIHJpZ2h0LWRvY3VtZW50OyBpZiB0aGV5IHdlcmVuJ3QsCi0gICAgICAgICAgICAvLyB0aGV5IHdvdWxkbid0IGJlIGtpZHMgb2YgdGhhdCBEb2NGcmFnLgotICAgICAgICAgICAgaWYgKGVycm9yQ2hlY2tpbmcpIHsKLSAgICAgICAgICAgICAgICBmb3IgKE5vZGUga2lkID0gbmV3Q2hpbGQuZ2V0Rmlyc3RDaGlsZCgpOyAvLyBQcmVzY2FuCi0gICAgICAgICAgICAgICAgICAgICBraWQgIT0gbnVsbDsga2lkID0ga2lkLmdldE5leHRTaWJsaW5nKCkpIHsKLQotICAgICAgICAgICAgICAgICAgICBpZiAoIW93bmVyRG9jdW1lbnQuaXNLaWRPSyh0aGlzLCBraWQpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRE9NRXhjZXB0aW9uLkhJRVJBUkNIWV9SRVFVRVNUX0VSUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sICJISUVSQVJDSFlfUkVRVUVTVF9FUlIiLCBudWxsKSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIHdoaWxlIChuZXdDaGlsZC5oYXNDaGlsZE5vZGVzKCkpIHsKLSAgICAgICAgICAgICAgICBpbnNlcnRCZWZvcmUobmV3Q2hpbGQuZ2V0Rmlyc3RDaGlsZCgpLCByZWZDaGlsZCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gbmV3Q2hpbGQ7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAobmV3Q2hpbGQgPT0gcmVmQ2hpbGQpIHsKLSAgICAgICAgICAgIC8vIHN0dXBpZCBjYXNlIHRoYXQgbXVzdCBiZSBoYW5kbGVkIGFzIGEgbm8tb3AgdHJpZ2dlcmluZyBldmVudHMuLi4KLSAgICAgICAgICAgIHJlZkNoaWxkID0gcmVmQ2hpbGQuZ2V0TmV4dFNpYmxpbmcoKTsKLSAgICAgICAgICAgIHJlbW92ZUNoaWxkKG5ld0NoaWxkKTsKLSAgICAgICAgICAgIGluc2VydEJlZm9yZShuZXdDaGlsZCwgcmVmQ2hpbGQpOwotICAgICAgICAgICAgcmV0dXJuIG5ld0NoaWxkOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKG5lZWRzU3luY0NoaWxkcmVuKCkpIHsKLSAgICAgICAgICAgIHN5bmNocm9uaXplQ2hpbGRyZW4oKTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChlcnJvckNoZWNraW5nKSB7Ci0gICAgICAgICAgICBpZiAoaXNSZWFkT25seSgpKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERPTUV4Y2VwdGlvbi5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIiwgbnVsbCkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKG5ld0NoaWxkLmdldE93bmVyRG9jdW1lbnQoKSAhPSBvd25lckRvY3VtZW50ICYmIG5ld0NoaWxkICE9IG93bmVyRG9jdW1lbnQpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5XUk9OR19ET0NVTUVOVF9FUlIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwgIldST05HX0RPQ1VNRU5UX0VSUiIsIG51bGwpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmICghb3duZXJEb2N1bWVudC5pc0tpZE9LKHRoaXMsIG5ld0NoaWxkKSkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLkhJRVJBUkNIWV9SRVFVRVNUX0VSUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiSElFUkFSQ0hZX1JFUVVFU1RfRVJSIiwgbnVsbCkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gcmVmQ2hpbGQgbXVzdCBiZSBhIGNoaWxkIG9mIHRoaXMgbm9kZSAob3IgbnVsbCkKLSAgICAgICAgICAgIGlmIChyZWZDaGlsZCAhPSBudWxsICYmIHJlZkNoaWxkLmdldFBhcmVudE5vZGUoKSAhPSB0aGlzKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX0ZPVU5EX0VSUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiTk9UX0ZPVU5EX0VSUiIsIG51bGwpKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gUHJldmVudCBjeWNsZXMgaW4gdGhlIHRyZWUKLSAgICAgICAgICAgIC8vIG5ld0NoaWxkIGNhbm5vdCBiZSBhbmNlc3RvciBvZiB0aGlzIE5vZGUsCi0gICAgICAgICAgICAvLyBhbmQgYWN0dWFsbHkgY2Fubm90IGJlIHRoaXMKLSAgICAgICAgICAgIGlmIChvd25lckRvY3VtZW50LmFuY2VzdG9yQ2hlY2tpbmcpIHsKLSAgICAgICAgICAgICAgICBib29sZWFuIHRyZWVTYWZlID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICBmb3IgKE5vZGVJbXBsIGEgPSB0aGlzOyB0cmVlU2FmZSAmJiBhICE9IG51bGw7IGEgPSBhLnBhcmVudE5vZGUoKSkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIHRyZWVTYWZlID0gbmV3Q2hpbGQgIT0gYTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaWYoIXRyZWVTYWZlKSB7Ci0gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLkhJRVJBUkNIWV9SRVFVRVNUX0VSUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwgIkhJRVJBUkNIWV9SRVFVRVNUX0VSUiIsIG51bGwpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBub3RpZnkgZG9jdW1lbnQKLSAgICAgICAgb3duZXJEb2N1bWVudC5pbnNlcnRpbmdOb2RlKHRoaXMsIHJlcGxhY2UpOwotCi0gICAgICAgIC8vIENvbnZlcnQgdG8gaW50ZXJuYWwgdHlwZSwgdG8gYXZvaWQgcmVwZWF0ZWQgY2FzdGluZwotICAgICAgICBDaGlsZE5vZGUgbmV3SW50ZXJuYWwgPSAoQ2hpbGROb2RlKW5ld0NoaWxkOwotCi0gICAgICAgIE5vZGUgb2xkcGFyZW50ID0gbmV3SW50ZXJuYWwucGFyZW50Tm9kZSgpOwotICAgICAgICBpZiAob2xkcGFyZW50ICE9IG51bGwpIHsKLSAgICAgICAgICAgIG9sZHBhcmVudC5yZW1vdmVDaGlsZChuZXdJbnRlcm5hbCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBDb252ZXJ0IHRvIGludGVybmFsIHR5cGUsIHRvIGF2b2lkIHJlcGVhdGVkIGNhc3RpbmcKLSAgICAgICAgQ2hpbGROb2RlIHJlZkludGVybmFsID0gKENoaWxkTm9kZSlyZWZDaGlsZDsKLQotICAgICAgICAvLyBBdHRhY2ggdXAKLSAgICAgICAgbmV3SW50ZXJuYWwub3duZXJOb2RlID0gdGhpczsKLSAgICAgICAgbmV3SW50ZXJuYWwuaXNPd25lZCh0cnVlKTsKLQotICAgICAgICAvLyBBdHRhY2ggYmVmb3JlIGFuZCBhZnRlcgotICAgICAgICAvLyBOb3RlOiBmaXJzdENoaWxkLnByZXZpb3VzU2libGluZyA9PSBsYXN0Q2hpbGQhIQotICAgICAgICBpZiAoZmlyc3RDaGlsZCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAvLyB0aGlzIG91ciBmaXJzdCBhbmQgb25seSBjaGlsZAotICAgICAgICAgICAgZmlyc3RDaGlsZCA9IG5ld0ludGVybmFsOwotICAgICAgICAgICAgbmV3SW50ZXJuYWwuaXNGaXJzdENoaWxkKHRydWUpOwotICAgICAgICAgICAgbmV3SW50ZXJuYWwucHJldmlvdXNTaWJsaW5nID0gbmV3SW50ZXJuYWw7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBpZiAocmVmSW50ZXJuYWwgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIC8vIHRoaXMgaXMgYW4gYXBwZW5kCi0gICAgICAgICAgICAgICAgQ2hpbGROb2RlIGxhc3RDaGlsZCA9IGZpcnN0Q2hpbGQucHJldmlvdXNTaWJsaW5nOwotICAgICAgICAgICAgICAgIGxhc3RDaGlsZC5uZXh0U2libGluZyA9IG5ld0ludGVybmFsOwotICAgICAgICAgICAgICAgIG5ld0ludGVybmFsLnByZXZpb3VzU2libGluZyA9IGxhc3RDaGlsZDsKLSAgICAgICAgICAgICAgICBmaXJzdENoaWxkLnByZXZpb3VzU2libGluZyA9IG5ld0ludGVybmFsOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgLy8gdGhpcyBpcyBhbiBpbnNlcnQKLSAgICAgICAgICAgICAgICBpZiAocmVmQ2hpbGQgPT0gZmlyc3RDaGlsZCkgewotICAgICAgICAgICAgICAgICAgICAvLyBhdCB0aGUgaGVhZCBvZiB0aGUgbGlzdAotICAgICAgICAgICAgICAgICAgICBmaXJzdENoaWxkLmlzRmlyc3RDaGlsZChmYWxzZSk7Ci0gICAgICAgICAgICAgICAgICAgIG5ld0ludGVybmFsLm5leHRTaWJsaW5nID0gZmlyc3RDaGlsZDsKLSAgICAgICAgICAgICAgICAgICAgbmV3SW50ZXJuYWwucHJldmlvdXNTaWJsaW5nID0gZmlyc3RDaGlsZC5wcmV2aW91c1NpYmxpbmc7Ci0gICAgICAgICAgICAgICAgICAgIGZpcnN0Q2hpbGQucHJldmlvdXNTaWJsaW5nID0gbmV3SW50ZXJuYWw7Ci0gICAgICAgICAgICAgICAgICAgIGZpcnN0Q2hpbGQgPSBuZXdJbnRlcm5hbDsKLSAgICAgICAgICAgICAgICAgICAgbmV3SW50ZXJuYWwuaXNGaXJzdENoaWxkKHRydWUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gc29tZXdoZXJlIGluIHRoZSBtaWRkbGUKLSAgICAgICAgICAgICAgICAgICAgQ2hpbGROb2RlIHByZXYgPSByZWZJbnRlcm5hbC5wcmV2aW91c1NpYmxpbmc7Ci0gICAgICAgICAgICAgICAgICAgIG5ld0ludGVybmFsLm5leHRTaWJsaW5nID0gcmVmSW50ZXJuYWw7Ci0gICAgICAgICAgICAgICAgICAgIHByZXYubmV4dFNpYmxpbmcgPSBuZXdJbnRlcm5hbDsKLSAgICAgICAgICAgICAgICAgICAgcmVmSW50ZXJuYWwucHJldmlvdXNTaWJsaW5nID0gbmV3SW50ZXJuYWw7Ci0gICAgICAgICAgICAgICAgICAgIG5ld0ludGVybmFsLnByZXZpb3VzU2libGluZyA9IHByZXY7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgY2hhbmdlZCgpOwotCi0gICAgICAgIC8vIHVwZGF0ZSBjYWNoZWQgbGVuZ3RoIGlmIHdlIGhhdmUgYW55Ci0gICAgICAgIGlmIChmTm9kZUxpc3RDYWNoZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAoZk5vZGVMaXN0Q2FjaGUuZkxlbmd0aCAhPSAtMSkgewotICAgICAgICAgICAgICAgIGZOb2RlTGlzdENhY2hlLmZMZW5ndGgrKzsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChmTm9kZUxpc3RDYWNoZS5mQ2hpbGRJbmRleCAhPSAtMSkgewotICAgICAgICAgICAgICAgIC8vIGlmIHdlIGhhcHBlbiB0byBpbnNlcnQganVzdCBiZWZvcmUgdGhlIGNhY2hlZCBub2RlLCB1cGRhdGUKLSAgICAgICAgICAgICAgICAvLyB0aGUgY2FjaGUgdG8gdGhlIG5ldyBub2RlIHRvIG1hdGNoIHRoZSBjYWNoZWQgaW5kZXgKLSAgICAgICAgICAgICAgICBpZiAoZk5vZGVMaXN0Q2FjaGUuZkNoaWxkID09IHJlZkludGVybmFsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZOb2RlTGlzdENhY2hlLmZDaGlsZCA9IG5ld0ludGVybmFsOwotICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIG90aGVyd2lzZSBqdXN0IGludmFsaWRhdGUgdGhlIGNhY2hlCi0gICAgICAgICAgICAgICAgICAgIGZOb2RlTGlzdENhY2hlLmZDaGlsZEluZGV4ID0gLTE7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gbm90aWZ5IGRvY3VtZW50Ci0gICAgICAgIG93bmVyRG9jdW1lbnQuaW5zZXJ0ZWROb2RlKHRoaXMsIG5ld0ludGVybmFsLCByZXBsYWNlKTsKLQotICAgICAgICBjaGVja05vcm1hbGl6YXRpb25BZnRlckluc2VydChuZXdJbnRlcm5hbCk7Ci0KLSAgICAgICAgcmV0dXJuIG5ld0NoaWxkOwotCi0gICAgfSAvLyBpbnRlcm5hbEluc2VydEJlZm9yZShOb2RlLE5vZGUsYm9vbGVhbik6Tm9kZQotCi0gICAgLyoqCi0gICAgICogUmVtb3ZlIGEgY2hpbGQgZnJvbSB0aGlzIE5vZGUuIFRoZSByZW1vdmVkIGNoaWxkJ3Mgc3VidHJlZQotICAgICAqIHJlbWFpbnMgaW50YWN0IHNvIGl0IG1heSBiZSByZS1pbnNlcnRlZCBlbHNld2hlcmUuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIG9sZENoaWxkLCBpbiBpdHMgbmV3IHN0YXRlIChyZW1vdmVkKS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uKE5PVF9GT1VORF9FUlIpIGlmIG9sZENoaWxkIGlzIG5vdCBhIGNoaWxkIG9mCi0gICAgICogdGhpcyBub2RlLgotICAgICAqCi0gICAgICogQHRocm93cyBET01FeGNlcHRpb24oTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSKSBpZiB0aGlzIG5vZGUgaXMKLSAgICAgKiByZWFkLW9ubHkuCi0gICAgICovCi0gICAgcHVibGljIE5vZGUgcmVtb3ZlQ2hpbGQoTm9kZSBvbGRDaGlsZCkKLSAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0gICAgICAgIC8vIFRhaWwtY2FsbCwgc2hvdWxkIGJlIG9wdGltaXphYmxlCi0gICAgICAgIHJldHVybiBpbnRlcm5hbFJlbW92ZUNoaWxkKG9sZENoaWxkLCBmYWxzZSk7Ci0gICAgfSAvLyByZW1vdmVDaGlsZChOb2RlKSA6Tm9kZQotCi0gICAgLyoqIE5PTi1ET00gSU5URVJOQUw6IFdpdGhpbiBET00gYWN0aW9ucyx3ZSBzb21ldGltZXMgbmVlZCB0byBiZSBhYmxlCi0gICAgICogdG8gY29udHJvbCB3aGljaCBtdXRhdGlvbiBldmVudHMgYXJlIHNwYXduZWQuIFRoaXMgdmVyc2lvbiBvZiB0aGUKLSAgICAgKiByZW1vdmVDaGlsZCBvcGVyYXRpb24gYWxsb3dzIHVzIHRvIGRvIHNvLiBJdCBpcyBub3QgaW50ZW5kZWQKLSAgICAgKiBmb3IgdXNlIGJ5IGFwcGxpY2F0aW9uIHByb2dyYW1zLgotICAgICAqLwotICAgIE5vZGUgaW50ZXJuYWxSZW1vdmVDaGlsZChOb2RlIG9sZENoaWxkLCBib29sZWFuIHJlcGxhY2UpCi0gICAgICAgIHRocm93cyBET01FeGNlcHRpb24gewotCi0gICAgICAgIENvcmVEb2N1bWVudEltcGwgb3duZXJEb2N1bWVudCA9IG93bmVyRG9jdW1lbnQoKTsKLSAgICAgICAgaWYgKG93bmVyRG9jdW1lbnQuZXJyb3JDaGVja2luZykgewotICAgICAgICAgICAgaWYgKGlzUmVhZE9ubHkoKSkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgRE9NRXhjZXB0aW9uLk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIiwgbnVsbCkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKG9sZENoaWxkICE9IG51bGwgJiYgb2xkQ2hpbGQuZ2V0UGFyZW50Tm9kZSgpICE9IHRoaXMpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfRk9VTkRfRVJSLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sICJOT1RfRk9VTkRfRVJSIiwgbnVsbCkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgQ2hpbGROb2RlIG9sZEludGVybmFsID0gKENoaWxkTm9kZSkgb2xkQ2hpbGQ7Ci0KLSAgICAgICAgLy8gbm90aWZ5IGRvY3VtZW50Ci0gICAgICAgIG93bmVyRG9jdW1lbnQucmVtb3ZpbmdOb2RlKHRoaXMsIG9sZEludGVybmFsLCByZXBsYWNlKTsKLQotICAgICAgICAvLyB1cGRhdGUgY2FjaGVkIGxlbmd0aCBpZiB3ZSBoYXZlIGFueQotICAgICAgICBpZiAoZk5vZGVMaXN0Q2FjaGUgIT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKGZOb2RlTGlzdENhY2hlLmZMZW5ndGggIT0gLTEpIHsKLSAgICAgICAgICAgICAgICBmTm9kZUxpc3RDYWNoZS5mTGVuZ3RoLS07Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoZk5vZGVMaXN0Q2FjaGUuZkNoaWxkSW5kZXggIT0gLTEpIHsKLSAgICAgICAgICAgICAgICAvLyBpZiB0aGUgcmVtb3ZlZCBub2RlIGlzIHRoZSBjYWNoZWQgbm9kZQotICAgICAgICAgICAgICAgIC8vIG1vdmUgdGhlIGNhY2hlIHRvIGl0cyAoc29vbiBmb3JtZXIpIHByZXZpb3VzIHNpYmxpbmcKLSAgICAgICAgICAgICAgICBpZiAoZk5vZGVMaXN0Q2FjaGUuZkNoaWxkID09IG9sZEludGVybmFsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZOb2RlTGlzdENhY2hlLmZDaGlsZEluZGV4LS07Ci0gICAgICAgICAgICAgICAgICAgIGZOb2RlTGlzdENhY2hlLmZDaGlsZCA9IG9sZEludGVybmFsLnByZXZpb3VzU2libGluZygpOwotICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIG90aGVyd2lzZSBqdXN0IGludmFsaWRhdGUgdGhlIGNhY2hlCi0gICAgICAgICAgICAgICAgICAgIGZOb2RlTGlzdENhY2hlLmZDaGlsZEluZGV4ID0gLTE7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gUGF0Y2ggbGlua2VkIGxpc3QgYXJvdW5kIG9sZENoaWxkCi0gICAgICAgIC8vIE5vdGU6IGxhc3RDaGlsZCA9PSBmaXJzdENoaWxkLnByZXZpb3VzU2libGluZwotICAgICAgICBpZiAob2xkSW50ZXJuYWwgPT0gZmlyc3RDaGlsZCkgewotICAgICAgICAgICAgLy8gcmVtb3ZpbmcgZmlyc3QgY2hpbGQKLSAgICAgICAgICAgIG9sZEludGVybmFsLmlzRmlyc3RDaGlsZChmYWxzZSk7Ci0gICAgICAgICAgICBmaXJzdENoaWxkID0gb2xkSW50ZXJuYWwubmV4dFNpYmxpbmc7Ci0gICAgICAgICAgICBpZiAoZmlyc3RDaGlsZCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZmlyc3RDaGlsZC5pc0ZpcnN0Q2hpbGQodHJ1ZSk7Ci0gICAgICAgICAgICAgICAgZmlyc3RDaGlsZC5wcmV2aW91c1NpYmxpbmcgPSBvbGRJbnRlcm5hbC5wcmV2aW91c1NpYmxpbmc7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBDaGlsZE5vZGUgcHJldiA9IG9sZEludGVybmFsLnByZXZpb3VzU2libGluZzsKLSAgICAgICAgICAgIENoaWxkTm9kZSBuZXh0ID0gb2xkSW50ZXJuYWwubmV4dFNpYmxpbmc7Ci0gICAgICAgICAgICBwcmV2Lm5leHRTaWJsaW5nID0gbmV4dDsKLSAgICAgICAgICAgIGlmIChuZXh0ID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAvLyByZW1vdmluZyBsYXN0IGNoaWxkCi0gICAgICAgICAgICAgICAgZmlyc3RDaGlsZC5wcmV2aW91c1NpYmxpbmcgPSBwcmV2OwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAvLyByZW1vdmluZyBzb21lIG90aGVyIGNoaWxkIGluIHRoZSBtaWRkbGUKLSAgICAgICAgICAgICAgICBuZXh0LnByZXZpb3VzU2libGluZyA9IHByZXY7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBTYXZlIHByZXZpb3VzIHNpYmxpbmcgZm9yIG5vcm1hbGl6YXRpb24gY2hlY2tpbmcuCi0gICAgICAgIENoaWxkTm9kZSBvbGRQcmV2aW91c1NpYmxpbmcgPSBvbGRJbnRlcm5hbC5wcmV2aW91c1NpYmxpbmcoKTsKLQotICAgICAgICAvLyBSZW1vdmUgb2xkSW50ZXJuYWwncyByZWZlcmVuY2VzIHRvIHRyZWUKLSAgICAgICAgb2xkSW50ZXJuYWwub3duZXJOb2RlICAgICAgID0gb3duZXJEb2N1bWVudDsKLSAgICAgICAgb2xkSW50ZXJuYWwuaXNPd25lZChmYWxzZSk7Ci0gICAgICAgIG9sZEludGVybmFsLm5leHRTaWJsaW5nICAgICA9IG51bGw7Ci0gICAgICAgIG9sZEludGVybmFsLnByZXZpb3VzU2libGluZyA9IG51bGw7Ci0KLSAgICAgICAgY2hhbmdlZCgpOwotCi0gICAgICAgIC8vIG5vdGlmeSBkb2N1bWVudAotICAgICAgICBvd25lckRvY3VtZW50LnJlbW92ZWROb2RlKHRoaXMsIHJlcGxhY2UpOwotCi0gICAgICAgIGNoZWNrTm9ybWFsaXphdGlvbkFmdGVyUmVtb3ZlKG9sZFByZXZpb3VzU2libGluZyk7Ci0KLSAgICAgICAgcmV0dXJuIG9sZEludGVybmFsOwotCi0gICAgfSAvLyBpbnRlcm5hbFJlbW92ZUNoaWxkKE5vZGUsYm9vbGVhbik6Tm9kZQotCi0gICAgLyoqCi0gICAgICogTWFrZSBuZXdDaGlsZCBvY2N1cHkgdGhlIGxvY2F0aW9uIHRoYXQgb2xkQ2hpbGQgdXNlZCB0bwotICAgICAqIGhhdmUuIE5vdGUgdGhhdCBuZXdDaGlsZCB3aWxsIGZpcnN0IGJlIHJlbW92ZWQgZnJvbSBpdHMgcHJldmlvdXMKLSAgICAgKiBwYXJlbnQsIGlmIGFueS4gRXF1aXZhbGVudCB0byBpbnNlcnRpbmcgbmV3Q2hpbGQgYmVmb3JlIG9sZENoaWxkLAotICAgICAqIHRoZW4gcmVtb3Zpbmcgb2xkQ2hpbGQuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIG9sZENoaWxkLCBpbiBpdHMgbmV3IHN0YXRlIChyZW1vdmVkKS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uKEhJRVJBUkNIWV9SRVFVRVNUX0VSUikgaWYgbmV3Q2hpbGQgaXMgb2YgYQotICAgICAqIHR5cGUgdGhhdCBzaG91bGRuJ3QgYmUgYSBjaGlsZCBvZiB0aGlzIG5vZGUsIG9yIGlmIG5ld0NoaWxkIGlzCi0gICAgICogb25lIG9mIG91ciBhbmNlc3RvcnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbihXUk9OR19ET0NVTUVOVF9FUlIpIGlmIG5ld0NoaWxkIGhhcyBhCi0gICAgICogZGlmZmVyZW50IG93bmVyIGRvY3VtZW50IHRoYW4gd2UgZG8uCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbihOT1RfRk9VTkRfRVJSKSBpZiBvbGRDaGlsZCBpcyBub3QgYSBjaGlsZCBvZgotICAgICAqIHRoaXMgbm9kZS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uKE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUikgaWYgdGhpcyBub2RlIGlzCi0gICAgICogcmVhZC1vbmx5LgotICAgICAqLwotICAgIHB1YmxpYyBOb2RlIHJlcGxhY2VDaGlsZChOb2RlIG5ld0NoaWxkLCBOb2RlIG9sZENoaWxkKQotICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKLSAgICAgICAgLy8gSWYgTXV0YXRpb24gRXZlbnRzIGFyZSBiZWluZyBnZW5lcmF0ZWQsIHRoaXMgb3BlcmF0aW9uIG1pZ2h0Ci0gICAgICAgIC8vIHRocm93IGFnZ3JlZ2F0ZSBldmVudHMgdHdpY2Ugd2hlbiBtb2RpZnlpbmcgYW4gQXR0ciAtLSBvbmNlCi0gICAgICAgIC8vIG9uIGluc2VydGlvbiBhbmQgb25jZSBvbiByZW1vdmFsLiBET00gTGV2ZWwgMiBkb2VzIG5vdCBzcGVjaWZ5Ci0gICAgICAgIC8vIHRoaXMgYXMgZWl0aGVyIGRlc2lyYWJsZSBvciB1bmRlc2lyYWJsZSwgYnV0IGhpbnRzIHRoYXQKLSAgICAgICAgLy8gYWdncmVnYXRpb25zIHNob3VsZCBiZSBpc3N1ZWQgb25seSBvbmNlIHBlciB1c2VyIHJlcXVlc3QuCi0KLSAgICAgICAgLy8gbm90aWZ5IGRvY3VtZW50Ci0gICAgICAgIG93bmVyRG9jdW1lbnQucmVwbGFjaW5nTm9kZSh0aGlzKTsKLQotICAgICAgICBpbnRlcm5hbEluc2VydEJlZm9yZShuZXdDaGlsZCwgb2xkQ2hpbGQsIHRydWUpOwotICAgICAgICBpZiAobmV3Q2hpbGQgIT0gb2xkQ2hpbGQpIHsKLSAgICAgICAgICAgIGludGVybmFsUmVtb3ZlQ2hpbGQob2xkQ2hpbGQsIHRydWUpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gbm90aWZ5IGRvY3VtZW50Ci0gICAgICAgIG93bmVyRG9jdW1lbnQucmVwbGFjZWROb2RlKHRoaXMpOwotCi0gICAgICAgIHJldHVybiBvbGRDaGlsZDsKLSAgICB9Ci0KLSAgICAvKgotICAgICAqIEdldCBOb2RlIHRleHQgY29udGVudAotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VGV4dENvbnRlbnQoKSB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKLSAgICAgICAgTm9kZSBjaGlsZCA9IGdldEZpcnN0Q2hpbGQoKTsKLSAgICAgICAgaWYgKGNoaWxkICE9IG51bGwpIHsKLSAgICAgICAgICAgIE5vZGUgbmV4dCA9IGNoaWxkLmdldE5leHRTaWJsaW5nKCk7Ci0gICAgICAgICAgICBpZiAobmV4dCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGhhc1RleHRDb250ZW50KGNoaWxkKSA/ICgoTm9kZUltcGwpIGNoaWxkKS5nZXRUZXh0Q29udGVudCgpIDogIiI7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoZkJ1ZmZlclN0ciA9PSBudWxsKXsKLSAgICAgICAgICAgICAgICBmQnVmZmVyU3RyID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgZkJ1ZmZlclN0ci5zZXRMZW5ndGgoMCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBnZXRUZXh0Q29udGVudChmQnVmZmVyU3RyKTsKLSAgICAgICAgICAgIHJldHVybiBmQnVmZmVyU3RyLnRvU3RyaW5nKCk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuICIiOwotICAgIH0KLQotICAgIC8vIGludGVybmFsIG1ldGhvZCB0YWtpbmcgYSBTdHJpbmdCdWZmZXIgaW4gcGFyYW1ldGVyCi0gICAgdm9pZCBnZXRUZXh0Q29udGVudChTdHJpbmdCdWZmZXIgYnVmKSB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKLSAgICAgICAgTm9kZSBjaGlsZCA9IGdldEZpcnN0Q2hpbGQoKTsKLSAgICAgICAgd2hpbGUgKGNoaWxkICE9IG51bGwpIHsKLSAgICAgICAgICAgIGlmIChoYXNUZXh0Q29udGVudChjaGlsZCkpIHsKLSAgICAgICAgICAgICAgICAoKE5vZGVJbXBsKSBjaGlsZCkuZ2V0VGV4dENvbnRlbnQoYnVmKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNoaWxkID0gY2hpbGQuZ2V0TmV4dFNpYmxpbmcoKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8vIGludGVybmFsIG1ldGhvZCByZXR1cm5pbmcgd2hldGhlciB0byB0YWtlIHRoZSBnaXZlbiBub2RlJ3MgdGV4dCBjb250ZW50Ci0gICAgZmluYWwgYm9vbGVhbiBoYXNUZXh0Q29udGVudChOb2RlIGNoaWxkKSB7Ci0gICAgICAgIHJldHVybiBjaGlsZC5nZXROb2RlVHlwZSgpICE9IE5vZGUuQ09NTUVOVF9OT0RFICYmCi0gICAgICAgICAgICBjaGlsZC5nZXROb2RlVHlwZSgpICE9IE5vZGUuUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFICYmCi0gICAgICAgICAgICAoY2hpbGQuZ2V0Tm9kZVR5cGUoKSAhPSBOb2RlLlRFWFRfTk9ERSB8fAotICAgICAgICAgICAgICgoVGV4dEltcGwpIGNoaWxkKS5pc0lnbm9yYWJsZVdoaXRlc3BhY2UoKSA9PSBmYWxzZSk7Ci0gICAgfQotCi0gICAgLyoKLSAgICAgKiBTZXQgTm9kZSB0ZXh0IGNvbnRlbnQKLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRUZXh0Q29udGVudChTdHJpbmcgdGV4dENvbnRlbnQpCi0gICAgICAgIHRocm93cyBET01FeGNlcHRpb24gewotICAgICAgICAvLyBnZXQgcmlkIG9mIGFueSBleGlzdGluZyBjaGlsZHJlbgotICAgICAgICBOb2RlIGNoaWxkOwotICAgICAgICB3aGlsZSAoKGNoaWxkID0gZ2V0Rmlyc3RDaGlsZCgpKSAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZW1vdmVDaGlsZChjaGlsZCk7Ci0gICAgICAgIH0KLSAgICAgICAgLy8gY3JlYXRlIGEgVGV4dCBub2RlIHRvIGhvbGQgdGhlIGdpdmVuIGNvbnRlbnQKLSAgICAgICAgaWYgKHRleHRDb250ZW50ICE9IG51bGwgJiYgdGV4dENvbnRlbnQubGVuZ3RoKCkgIT0gMCl7Ci0gICAgICAgICAgICBhcHBlbmRDaGlsZChvd25lckRvY3VtZW50KCkuY3JlYXRlVGV4dE5vZGUodGV4dENvbnRlbnQpKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8vCi0gICAgLy8gTm9kZUxpc3QgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBDb3VudCB0aGUgaW1tZWRpYXRlIGNoaWxkcmVuIG9mIHRoaXMgbm9kZS4gIFVzZSB0byBpbXBsZW1lbnQKLSAgICAgKiBOb2RlTGlzdC5nZXRMZW5ndGgoKS4KLSAgICAgKiBAcmV0dXJuIGludAotICAgICAqLwotICAgIHByaXZhdGUgaW50IG5vZGVMaXN0R2V0TGVuZ3RoKCkgewotCi0gICAgICAgIGlmIChmTm9kZUxpc3RDYWNoZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAvLyBnZXQgcmlkIG9mIHRyaXZpYWwgY2FzZXMKLSAgICAgICAgICAgIGlmIChmaXJzdENoaWxkID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gMDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChmaXJzdENoaWxkID09IGxhc3RDaGlsZCgpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIDE7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyBvdGhlcndpc2UgcmVxdWVzdCBhIGNhY2hlIG9iamVjdAotICAgICAgICAgICAgZk5vZGVMaXN0Q2FjaGUgPSBvd25lckRvY3VtZW50LmdldE5vZGVMaXN0Q2FjaGUodGhpcyk7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGZOb2RlTGlzdENhY2hlLmZMZW5ndGggPT0gLTEpIHsgLy8gaXMgdGhlIGNhY2hlZCBsZW5ndGggaW52YWxpZCA/Ci0gICAgICAgICAgICBpbnQgbDsKLSAgICAgICAgICAgIENoaWxkTm9kZSBuOwotICAgICAgICAgICAgLy8gc3RhcnQgZnJvbSB0aGUgY2FjaGVkIG5vZGUgaWYgd2UgaGF2ZSBvbmUKLSAgICAgICAgICAgIGlmIChmTm9kZUxpc3RDYWNoZS5mQ2hpbGRJbmRleCAhPSAtMSAmJgotICAgICAgICAgICAgICAgIGZOb2RlTGlzdENhY2hlLmZDaGlsZCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgbCA9IGZOb2RlTGlzdENhY2hlLmZDaGlsZEluZGV4OwotICAgICAgICAgICAgICAgIG4gPSBmTm9kZUxpc3RDYWNoZS5mQ2hpbGQ7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIG4gPSBmaXJzdENoaWxkOwotICAgICAgICAgICAgICAgIGwgPSAwOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgd2hpbGUgKG4gIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGwrKzsKLSAgICAgICAgICAgICAgICBuID0gbi5uZXh0U2libGluZzsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGZOb2RlTGlzdENhY2hlLmZMZW5ndGggPSBsOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIGZOb2RlTGlzdENhY2hlLmZMZW5ndGg7Ci0KLSAgICB9IC8vIG5vZGVMaXN0R2V0TGVuZ3RoKCk6aW50Ci0KLSAgICAvKioKLSAgICAgKiBOb2RlTGlzdCBtZXRob2Q6IENvdW50IHRoZSBpbW1lZGlhdGUgY2hpbGRyZW4gb2YgdGhpcyBub2RlCi0gICAgICogQHJldHVybiBpbnQKLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldExlbmd0aCgpIHsKLSAgICAgICAgcmV0dXJuIG5vZGVMaXN0R2V0TGVuZ3RoKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSBOdGggaW1tZWRpYXRlIGNoaWxkIG9mIHRoaXMgbm9kZSwgb3IgbnVsbCBpZiB0aGUgaW5kZXggaXMKLSAgICAgKiBvdXQgb2YgYm91bmRzLiAgVXNlIHRvIGltcGxlbWVudCBOb2RlTGlzdC5pdGVtKCkuCi0gICAgICogQHBhcmFtIGluZGV4IGludAotICAgICAqLwotICAgIHByaXZhdGUgTm9kZSBub2RlTGlzdEl0ZW0oaW50IGluZGV4KSB7Ci0KLSAgICAgICAgaWYgKGZOb2RlTGlzdENhY2hlID09IG51bGwpIHsKLSAgICAgICAgICAgIC8vIGdldCByaWQgb2YgdHJpdmlhbCBjYXNlCi0gICAgICAgICAgICBpZiAoZmlyc3RDaGlsZCA9PSBsYXN0Q2hpbGQoKSkgewotICAgICAgICAgICAgICAgIHJldHVybiBpbmRleCA9PSAwID8gZmlyc3RDaGlsZCA6IG51bGw7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyBvdGhlcndpc2UgcmVxdWVzdCBhIGNhY2hlIG9iamVjdAotICAgICAgICAgICAgZk5vZGVMaXN0Q2FjaGUgPSBvd25lckRvY3VtZW50LmdldE5vZGVMaXN0Q2FjaGUodGhpcyk7Ci0gICAgICAgIH0KLSAgICAgICAgaW50IGkgPSBmTm9kZUxpc3RDYWNoZS5mQ2hpbGRJbmRleDsKLSAgICAgICAgQ2hpbGROb2RlIG4gPSBmTm9kZUxpc3RDYWNoZS5mQ2hpbGQ7Ci0gICAgICAgIGJvb2xlYW4gZmlyc3RBY2Nlc3MgPSB0cnVlOwotICAgICAgICAvLyBzaG9ydCB3YXkKLSAgICAgICAgaWYgKGkgIT0gLTEgJiYgbiAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmaXJzdEFjY2VzcyA9IGZhbHNlOwotICAgICAgICAgICAgaWYgKGkgPCBpbmRleCkgewotICAgICAgICAgICAgICAgIHdoaWxlIChpIDwgaW5kZXggJiYgbiAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGkrKzsKLSAgICAgICAgICAgICAgICAgICAgbiA9IG4ubmV4dFNpYmxpbmc7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoaSA+IGluZGV4KSB7Ci0gICAgICAgICAgICAgICAgd2hpbGUgKGkgPiBpbmRleCAmJiBuICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgaS0tOwotICAgICAgICAgICAgICAgICAgICBuID0gbi5wcmV2aW91c1NpYmxpbmcoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAvLyBsb25nIHdheQotICAgICAgICAgICAgaWYgKGluZGV4IDwgMCkgewotICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgbiA9IGZpcnN0Q2hpbGQ7Ci0gICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgaW5kZXggJiYgbiAhPSBudWxsOyBpKyspIHsKLSAgICAgICAgICAgICAgICBuID0gbi5uZXh0U2libGluZzsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIHJlbGVhc2UgY2FjaGUgaWYgcmVhY2hpbmcgbGFzdCBjaGlsZCBvciBmaXJzdCBjaGlsZAotICAgICAgICBpZiAoIWZpcnN0QWNjZXNzICYmIChuID09IGZpcnN0Q2hpbGQgfHwgbiA9PSBsYXN0Q2hpbGQoKSkpIHsKLSAgICAgICAgICAgIGZOb2RlTGlzdENhY2hlLmZDaGlsZEluZGV4ID0gLTE7Ci0gICAgICAgICAgICBmTm9kZUxpc3RDYWNoZS5mQ2hpbGQgPSBudWxsOwotICAgICAgICAgICAgb3duZXJEb2N1bWVudC5mcmVlTm9kZUxpc3RDYWNoZShmTm9kZUxpc3RDYWNoZSk7Ci0gICAgICAgICAgICAvLyB3ZSBjYW4ga2VlcCB1c2luZyB0aGUgY2FjaGUgdW50aWwgaXQgaXMgYWN0dWFsbHkgcmV1c2VkCi0gICAgICAgICAgICAvLyBmTm9kZUxpc3RDYWNoZSB3aWxsIGJlIG51bGxlZCBieSB0aGUgcG9vbCAoZG9jdW1lbnQpIGlmIHRoYXQKLSAgICAgICAgICAgIC8vIGhhcHBlbnMuCi0gICAgICAgICAgICAvLyBmTm9kZUxpc3RDYWNoZSA9IG51bGw7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAvLyBvdGhlcndpc2UgdXBkYXRlIGl0Ci0gICAgICAgICAgICBmTm9kZUxpc3RDYWNoZS5mQ2hpbGRJbmRleCA9IGk7Ci0gICAgICAgICAgICBmTm9kZUxpc3RDYWNoZS5mQ2hpbGQgPSBuOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBuOwotCi0gICAgfSAvLyBub2RlTGlzdEl0ZW0oaW50KTpOb2RlCi0KLSAgICAvKioKLSAgICAgKiBOb2RlTGlzdCBtZXRob2Q6IFJldHVybiB0aGUgTnRoIGltbWVkaWF0ZSBjaGlsZCBvZiB0aGlzIG5vZGUsIG9yCi0gICAgICogbnVsbCBpZiB0aGUgaW5kZXggaXMgb3V0IG9mIGJvdW5kcy4KLSAgICAgKiBAcmV0dXJuIG9yZy53M2MuZG9tLk5vZGUKLSAgICAgKiBAcGFyYW0gaW5kZXggaW50Ci0gICAgICovCi0gICAgcHVibGljIE5vZGUgaXRlbShpbnQgaW5kZXgpIHsKLSAgICAgICAgcmV0dXJuIG5vZGVMaXN0SXRlbShpbmRleCk7Ci0gICAgfSAvLyBpdGVtKGludCk6Tm9kZQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlIGEgTm9kZUxpc3QgdG8gYWNjZXNzIGNoaWxkcmVuIHRoYXQgaXMgdXNlIGJ5IHN1YmNsYXNzIGVsZW1lbnRzCi0gICAgICogdGhhdCBoYXZlIG1ldGhvZHMgbmFtZWQgZ2V0TGVuZ3RoKCkgb3IgaXRlbShpbnQpLiAgQ2hpbGRBbmRQYXJlbnROb2RlCi0gICAgICogb3B0aW1pemVzIGdldENoaWxkTm9kZXMoKSBieSBpbXBsZW1lbnRpbmcgTm9kZUxpc3QgaXRzZWxmLiAgSG93ZXZlciBpZgotICAgICAqIGEgc3ViY2xhc3MgRWxlbWVudCBpbXBsZW1lbnRzIG1ldGhvZHMgd2l0aCB0aGUgc2FtZSBuYW1lIGFzIHRoZSBOb2RlTGlzdAotICAgICAqIG1ldGhvZHMsIHRoZXkgd2lsbCBvdmVycmlkZSB0aGUgYWN0dWFsbHkgbWV0aG9kcyBpbiB0aGlzIGNsYXNzLgotICAgICAqIDxwPgotICAgICAqIFRvIHVzZSB0aGlzIG1ldGhvZCwgdGhlIHN1YmNsYXNzIHNob3VsZCBpbXBsZW1lbnQgZ2V0Q2hpbGROb2RlcygpIGFuZAotICAgICAqIGhhdmUgaXQgY2FsbCB0aGlzIG1ldGhvZC4gIFRoZSByZXN1bHRpbmcgTm9kZUxpc3QgaW5zdGFuY2UgbWF5YmUKLSAgICAgKiBzaGFyZWQgYW5kIGNhY2hlZCBpbiBhIHRyYW5zaWVudCBmaWVsZCwgYnV0IHRoZSBjYWNoZWQgdmFsdWUgbXVzdCBiZQotICAgICAqIGNsZWFyZWQgaWYgdGhlIG5vZGUgaXMgY2xvbmVkLgotICAgICAqLwotICAgIHByb3RlY3RlZCBmaW5hbCBOb2RlTGlzdCBnZXRDaGlsZE5vZGVzVW5vcHRpbWl6ZWQoKSB7Ci0gICAgICAgIGlmIChuZWVkc1N5bmNDaGlsZHJlbigpKSB7Ci0gICAgICAgICAgICBzeW5jaHJvbml6ZUNoaWxkcmVuKCk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG5ldyBOb2RlTGlzdCgpIHsKLSAgICAgICAgICAgICAgICAvKioKLSAgICAgICAgICAgICAgICAgKiBAc2VlIE5vZGVMaXN0LmdldExlbmd0aCgpCi0gICAgICAgICAgICAgICAgICovCi0gICAgICAgICAgICAgICAgcHVibGljIGludCBnZXRMZW5ndGgoKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBub2RlTGlzdEdldExlbmd0aCgpOwotICAgICAgICAgICAgICAgIH0gLy8gZ2V0TGVuZ3RoKCk6aW50Ci0KLSAgICAgICAgICAgICAgICAvKioKLSAgICAgICAgICAgICAgICAgKiBAc2VlIE5vZGVMaXN0Lml0ZW0oaW50KQotICAgICAgICAgICAgICAgICAqLwotICAgICAgICAgICAgICAgIHB1YmxpYyBOb2RlIGl0ZW0oaW50IGluZGV4KSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBub2RlTGlzdEl0ZW0oaW5kZXgpOwotICAgICAgICAgICAgICAgIH0gLy8gaXRlbShpbnQpOk5vZGUKLSAgICAgICAgICAgIH07Ci0gICAgfSAvLyBnZXRDaGlsZE5vZGVzVW5vcHRpbWl6ZWQoKTpOb2RlTGlzdAotCi0gICAgLy8KLSAgICAvLyBET00yOiBtZXRob2RzLCBnZXR0ZXJzLCBzZXR0ZXJzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIE92ZXJyaWRlIGRlZmF1bHQgYmVoYXZpb3IgdG8gY2FsbCBub3JtYWxpemUoKSBvbiB0aGlzIE5vZGUncwotICAgICAqIGNoaWxkcmVuLiBJdCBpcyB1cCB0byBpbXBsZW1lbnRvcnMgb3IgTm9kZSB0byBvdmVycmlkZSBub3JtYWxpemUoKQotICAgICAqIHRvIHRha2UgYWN0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIG5vcm1hbGl6ZSgpIHsKLSAgICAgICAgLy8gTm8gbmVlZCB0byBub3JtYWxpemUgaWYgYWxyZWFkeSBub3JtYWxpemVkLgotICAgICAgICBpZiAoaXNOb3JtYWxpemVkKCkpIHsKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotICAgICAgICBpZiAobmVlZHNTeW5jQ2hpbGRyZW4oKSkgewotICAgICAgICAgICAgc3luY2hyb25pemVDaGlsZHJlbigpOwotICAgICAgICB9Ci0gICAgICAgIENoaWxkTm9kZSBraWQ7Ci0gICAgICAgIGZvciAoa2lkID0gZmlyc3RDaGlsZDsga2lkICE9IG51bGw7IGtpZCA9IGtpZC5uZXh0U2libGluZykgewotICAgICAgICAgICAga2lkLm5vcm1hbGl6ZSgpOwotICAgICAgICB9Ci0gICAgICAgIGlzTm9ybWFsaXplZCh0cnVlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBET00gTGV2ZWwgMyBXRC0gRXhwZXJpbWVudGFsLgotICAgICAqIE92ZXJyaWRlIGluaGVyaXRlZCBiZWhhdmlvciBmcm9tIE5vZGVJbXBsIHRvIHN1cHBvcnQgZGVlcCBlcXVhbC4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0VxdWFsTm9kZShOb2RlIGFyZykgewotICAgICAgICBpZiAoIXN1cGVyLmlzRXF1YWxOb2RlKGFyZykpIHsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotICAgICAgICAvLyB0aGVyZSBhcmUgbWFueSB3YXlzIHRvIGRvIHRoaXMgdGVzdCwgYW5kIHRoZXJlIGlzbid0IGFueSB3YXkKLSAgICAgICAgLy8gYmV0dGVyIHRoYW4gYW5vdGhlci4gUGVyZm9ybWFuY2UgbWF5IHZhcnkgZ3JlYXRseSBkZXBlbmRpbmcgb24KLSAgICAgICAgLy8gdGhlIGltcGxlbWVudGF0aW9ucyBpbnZvbHZlZC4gVGhpcyBvbmUgc2hvdWxkIHdvcmsgZmluZSBmb3IgdXMuCi0gICAgICAgIE5vZGUgY2hpbGQxID0gZ2V0Rmlyc3RDaGlsZCgpOwotICAgICAgICBOb2RlIGNoaWxkMiA9IGFyZy5nZXRGaXJzdENoaWxkKCk7Ci0gICAgICAgIHdoaWxlIChjaGlsZDEgIT0gbnVsbCAmJiBjaGlsZDIgIT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKCEoKE5vZGVJbXBsKSBjaGlsZDEpLmlzRXF1YWxOb2RlKGNoaWxkMikpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjaGlsZDEgPSBjaGlsZDEuZ2V0TmV4dFNpYmxpbmcoKTsKLSAgICAgICAgICAgIGNoaWxkMiA9IGNoaWxkMi5nZXROZXh0U2libGluZygpOwotICAgICAgICB9Ci0gICAgICAgIGlmIChjaGlsZDEgIT0gY2hpbGQyKSB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotCi0gICAgLy8KLSAgICAvLyBQdWJsaWMgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBPdmVycmlkZSBkZWZhdWx0IGJlaGF2aW9yIHNvIHRoYXQgaWYgZGVlcCBpcyB0cnVlLCBjaGlsZHJlbiBhcmUgYWxzbwotICAgICAqIHRvZ2dsZWQuCi0gICAgICogQHNlZSBOb2RlCi0gICAgICogPFA+Ci0gICAgICogTm90ZTogdGhpcyB3aWxsIG5vdCBjaGFuZ2UgdGhlIHN0YXRlIG9mIGFuIEVudGl0eVJlZmVyZW5jZSBvciBpdHMKLSAgICAgKiBjaGlsZHJlbiwgd2hpY2ggYXJlIGFsd2F5cyByZWFkLW9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0UmVhZE9ubHkoYm9vbGVhbiByZWFkT25seSwgYm9vbGVhbiBkZWVwKSB7Ci0KLSAgICAgICAgc3VwZXIuc2V0UmVhZE9ubHkocmVhZE9ubHksIGRlZXApOwotCi0gICAgICAgIGlmIChkZWVwKSB7Ci0KLSAgICAgICAgICAgIGlmIChuZWVkc1N5bmNDaGlsZHJlbigpKSB7Ci0gICAgICAgICAgICAgICAgc3luY2hyb25pemVDaGlsZHJlbigpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBSZWN1cnNpdmVseSBzZXQga2lkcwotICAgICAgICAgICAgZm9yIChDaGlsZE5vZGUgbXlraWQgPSBmaXJzdENoaWxkOwotICAgICAgICAgICAgICAgICBteWtpZCAhPSBudWxsOwotICAgICAgICAgICAgICAgICBteWtpZCA9IG15a2lkLm5leHRTaWJsaW5nKSB7Ci0gICAgICAgICAgICAgICAgaWYgKG15a2lkLmdldE5vZGVUeXBlKCkgIT0gTm9kZS5FTlRJVFlfUkVGRVJFTkNFX05PREUpIHsKLSAgICAgICAgICAgICAgICAgICAgbXlraWQuc2V0UmVhZE9ubHkocmVhZE9ubHksdHJ1ZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfSAvLyBzZXRSZWFkT25seShib29sZWFuLGJvb2xlYW4pCi0KLSAgICAvLwotICAgIC8vIFByb3RlY3RlZCBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIE92ZXJyaWRlIHRoaXMgbWV0aG9kIGluIHN1YmNsYXNzIHRvIGhvb2sgaW4gZWZmaWNpZW50Ci0gICAgICogaW50ZXJuYWwgZGF0YSBzdHJ1Y3R1cmUuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgc3luY2hyb25pemVDaGlsZHJlbigpIHsKLSAgICAgICAgLy8gQnkgZGVmYXVsdCBqdXN0IGNoYW5nZSB0aGUgZmxhZyB0byBhdm9pZCBjYWxsaW5nIHRoaXMgbWV0aG9kIGFnYWluCi0gICAgICAgIG5lZWRzU3luY0NoaWxkcmVuKGZhbHNlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDaGVja3MgdGhlIG5vcm1hbGl6ZWQgc3RhdGUgb2YgdGhpcyBub2RlIGFmdGVyIGluc2VydGluZyBhIGNoaWxkLgotICAgICAqIElmIHRoZSBpbnNlcnRlZCBjaGlsZCBjYXVzZXMgdGhpcyBub2RlIHRvIGJlIHVubm9ybWFsaXplZCwgdGhlbiB0aGlzCi0gICAgICogbm9kZSBpcyBmbGFnZ2VkIGFjY29yZGluZ2x5LgotICAgICAqIFRoZSBjb25kaXRpb25zIGZvciBjaGFuZ2luZyB0aGUgbm9ybWFsaXplZCBzdGF0ZSBhcmU6Ci0gICAgICogPHVsPgotICAgICAqIDxsaT5UaGUgaW5zZXJ0ZWQgY2hpbGQgaXMgYSB0ZXh0IG5vZGUgYW5kIG9uZSBvZiBpdHMgYWRqYWNlbnQgc2libGluZ3MKLSAgICAgKiBpcyBhbHNvIGEgdGV4dCBub2RlLgotICAgICAqIDxsaT5UaGUgaW5zZXJ0ZWQgY2hpbGQgaXMgaXMgaXRzZWxmIHVubm9ybWFsaXplZC4KLSAgICAgKiA8L3VsPgotICAgICAqCi0gICAgICogQHBhcmFtIGluc2VydGVkQ2hpbGQgdGhlIGNoaWxkIG5vZGUgdGhhdCB3YXMgaW5zZXJ0ZWQgaW50byB0aGlzIG5vZGUKLSAgICAgKgotICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIGluc2VydGVkIGNoaWxkIGlzIDxjb2RlPm51bGw8L2NvZGU+Ci0gICAgICovCi0gICAgdm9pZCBjaGVja05vcm1hbGl6YXRpb25BZnRlckluc2VydChDaGlsZE5vZGUgaW5zZXJ0ZWRDaGlsZCkgewotICAgICAgICAvLyBTZWUgaWYgaW5zZXJ0aW9uIGNhdXNlZCB0aGlzIG5vZGUgdG8gYmUgdW5ub3JtYWxpemVkLgotICAgICAgICBpZiAoaW5zZXJ0ZWRDaGlsZC5nZXROb2RlVHlwZSgpID09IE5vZGUuVEVYVF9OT0RFKSB7Ci0gICAgICAgICAgICBDaGlsZE5vZGUgcHJldiA9IGluc2VydGVkQ2hpbGQucHJldmlvdXNTaWJsaW5nKCk7Ci0gICAgICAgICAgICBDaGlsZE5vZGUgbmV4dCA9IGluc2VydGVkQ2hpbGQubmV4dFNpYmxpbmc7Ci0gICAgICAgICAgICAvLyBJZiBhbiBhZGphY2VudCBzaWJsaW5nIG9mIHRoZSBuZXcgY2hpbGQgaXMgYSB0ZXh0IG5vZGUsCi0gICAgICAgICAgICAvLyBmbGFnIHRoaXMgbm9kZSBhcyB1bm5vcm1hbGl6ZWQuCi0gICAgICAgICAgICBpZiAoKHByZXYgIT0gbnVsbCAmJiBwcmV2LmdldE5vZGVUeXBlKCkgPT0gTm9kZS5URVhUX05PREUpIHx8Ci0gICAgICAgICAgICAgICAgKG5leHQgIT0gbnVsbCAmJiBuZXh0LmdldE5vZGVUeXBlKCkgPT0gTm9kZS5URVhUX05PREUpKSB7Ci0gICAgICAgICAgICAgICAgaXNOb3JtYWxpemVkKGZhbHNlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIC8vIElmIHRoZSBuZXcgY2hpbGQgaXMgbm90IG5vcm1hbGl6ZWQsCi0gICAgICAgICAgICAvLyB0aGVuIHRoaXMgbm9kZSBpcyBpbmhlcmVudGx5IG5vdCBub3JtYWxpemVkLgotICAgICAgICAgICAgaWYgKCFpbnNlcnRlZENoaWxkLmlzTm9ybWFsaXplZCgpKSB7Ci0gICAgICAgICAgICAgICAgaXNOb3JtYWxpemVkKGZhbHNlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0gLy8gY2hlY2tOb3JtYWxpemF0aW9uQWZ0ZXJJbnNlcnQoQ2hpbGROb2RlKQotCi0gICAgLyoqCi0gICAgICogQ2hlY2tzIHRoZSBub3JtYWxpemVkIG9mIHRoaXMgbm9kZSBhZnRlciByZW1vdmluZyBhIGNoaWxkLgotICAgICAqIElmIHRoZSByZW1vdmVkIGNoaWxkIGNhdXNlcyB0aGlzIG5vZGUgdG8gYmUgdW5ub3JtYWxpemVkLCB0aGVuIHRoaXMKLSAgICAgKiBub2RlIGlzIGZsYWdnZWQgYWNjb3JkaW5nbHkuCi0gICAgICogVGhlIGNvbmRpdGlvbnMgZm9yIGNoYW5naW5nIHRoZSBub3JtYWxpemVkIHN0YXRlIGFyZToKLSAgICAgKiA8dWw+Ci0gICAgICogPGxpPlRoZSByZW1vdmVkIGNoaWxkIGhhZCB0d28gYWRqYWNlbnQgc2libGluZ3MgdGhhdCB3ZXJlIHRleHQgbm9kZXMuCi0gICAgICogPC91bD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBwcmV2aW91c1NpYmxpbmcgdGhlIHByZXZpb3VzIHNpYmxpbmcgb2YgdGhlIHJlbW92ZWQgY2hpbGQsIG9yCi0gICAgICogPGNvZGU+bnVsbDwvY29kZT4KLSAgICAgKi8KLSAgICB2b2lkIGNoZWNrTm9ybWFsaXphdGlvbkFmdGVyUmVtb3ZlKENoaWxkTm9kZSBwcmV2aW91c1NpYmxpbmcpIHsKLSAgICAgICAgLy8gU2VlIGlmIHJlbW92YWwgY2F1c2VkIHRoaXMgbm9kZSB0byBiZSB1bm5vcm1hbGl6ZWQuCi0gICAgICAgIC8vIElmIHRoZSBhZGphY2VudCBzaWJsaW5ncyBvZiB0aGUgcmVtb3ZlZCBjaGlsZCB3ZXJlIGJvdGggdGV4dCBub2RlcywKLSAgICAgICAgLy8gZmxhZyB0aGlzIG5vZGUgYXMgdW5ub3JtYWxpemVkLgotICAgICAgICBpZiAocHJldmlvdXNTaWJsaW5nICE9IG51bGwgJiYKLSAgICAgICAgICAgIHByZXZpb3VzU2libGluZy5nZXROb2RlVHlwZSgpID09IE5vZGUuVEVYVF9OT0RFKSB7Ci0KLSAgICAgICAgICAgIENoaWxkTm9kZSBuZXh0ID0gcHJldmlvdXNTaWJsaW5nLm5leHRTaWJsaW5nOwotICAgICAgICAgICAgaWYgKG5leHQgIT0gbnVsbCAmJiBuZXh0LmdldE5vZGVUeXBlKCkgPT0gTm9kZS5URVhUX05PREUpIHsKLSAgICAgICAgICAgICAgICBpc05vcm1hbGl6ZWQoZmFsc2UpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfSAvLyBjaGVja05vcm1hbGl6YXRpb25BZnRlclJlbW92ZShOb2RlKQotCi0gICAgLy8KLSAgICAvLyBTZXJpYWxpemF0aW9uIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqIFNlcmlhbGl6ZSBvYmplY3QuICovCi0gICAgcHJpdmF0ZSB2b2lkIHdyaXRlT2JqZWN0KE9iamVjdE91dHB1dFN0cmVhbSBvdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy8gc3luY2hyb25pemUgY2hpbHJlbgotICAgICAgICBpZiAobmVlZHNTeW5jQ2hpbGRyZW4oKSkgewotICAgICAgICAgICAgc3luY2hyb25pemVDaGlsZHJlbigpOwotICAgICAgICB9Ci0gICAgICAgIC8vIHdyaXRlIG9iamVjdAotICAgICAgICBvdXQuZGVmYXVsdFdyaXRlT2JqZWN0KCk7Ci0KLSAgICB9IC8vIHdyaXRlT2JqZWN0KE9iamVjdE91dHB1dFN0cmVhbSkKLQotICAgIC8qKiBEZXNlcmlhbGl6ZSBvYmplY3QuICovCi0gICAgcHJpdmF0ZSB2b2lkIHJlYWRPYmplY3QoT2JqZWN0SW5wdXRTdHJlYW0gb2lzKQotICAgICAgICB0aHJvd3MgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewotCi0gICAgICAgIC8vIHBlcmZvcm0gZGVmYXVsdCBkZXNlcmFsaXphdGlvbgotICAgICAgICBvaXMuZGVmYXVsdFJlYWRPYmplY3QoKTsKLQotICAgICAgICAvLyBoYXJkc2V0IHN5bmNoaWxkcmVuIC0gc28gd2UgZG9uJ3QgdHJ5IHRvIHN5bmMgLSBpdCBkb2VzIG5vdCBtYWtlIGFueQotICAgICAgICAvLyBzZW5zZSB0byB0cnkgdG8gc3luY2hpbGRyZW4gd2hlbiB3ZSBqdXN0IGRlc2VyaWFsaXplIG9iamVjdC4KLSAgICAgICAgbmVlZHNTeW5jQ2hpbGRyZW4oZmFsc2UpOwotCi0gICAgfSAvLyByZWFkT2JqZWN0KE9iamVjdElucHV0U3RyZWFtKQotCi0gICAgLyoKLSAgICAgKiBhIGNsYXNzIHRvIHN0b3JlIHNvbWUgdXNlciBkYXRhIGFsb25nIHdpdGggaXRzIGhhbmRsZXIKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgY2xhc3MgVXNlckRhdGFSZWNvcmQgaW1wbGVtZW50cyBTZXJpYWxpemFibGUgewotICAgICAgICAvKiogU2VyaWFsaXphdGlvbiB2ZXJzaW9uLiAqLwotICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAzMjU4MTI2OTc3MTM0MzEwNDU1TDsKLQotICAgICAgICBPYmplY3QgZkRhdGE7Ci0gICAgICAgIFVzZXJEYXRhSGFuZGxlciBmSGFuZGxlcjsKLSAgICAgICAgVXNlckRhdGFSZWNvcmQoT2JqZWN0IGRhdGEsIFVzZXJEYXRhSGFuZGxlciBoYW5kbGVyKSB7Ci0gICAgICAgICAgICBmRGF0YSA9IGRhdGE7Ci0gICAgICAgICAgICBmSGFuZGxlciA9IGhhbmRsZXI7Ci0gICAgICAgIH0KLSAgICB9Ci19IC8vIGNsYXNzIFBhcmVudE5vZGUKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9Qcm9jZXNzaW5nSW5zdHJ1Y3Rpb25JbXBsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vUHJvY2Vzc2luZ0luc3RydWN0aW9uSW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhMjM2NTc2Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9Qcm9jZXNzaW5nSW5zdHJ1Y3Rpb25JbXBsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNjEgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDAyLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tOwotCi1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcudzNjLmRvbS5Qcm9jZXNzaW5nSW5zdHJ1Y3Rpb247Ci0KLS8qKgotICogUHJvY2Vzc2luZyBJbnN0cnVjdGlvbnMgKFBJcykgcGVybWl0IGRvY3VtZW50cyB0byBjYXJyeQotICogcHJvY2Vzc29yLXNwZWNpZmljIGluZm9ybWF0aW9uIGFsb25nc2lkZSB0aGVpciBhY3R1YWwgY29udGVudC4gUElzCi0gKiBhcmUgbW9zdCBjb21tb24gaW4gWE1MLCBidXQgdGhleSBhcmUgc3VwcG9ydGVkIGluIEhUTUwgYXMgd2VsbC4KLSAqCi0gKiBUaGlzIGNsYXNzIGluaGVyaXRzIGZyb20gQ2hhcmFjdGVyRGF0YUltcGwgdG8gcmV1c2UgaXRzIHNldE5vZGVWYWx1ZSBtZXRob2QuCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBzaW5jZSAgUFItRE9NLUxldmVsLTEtMTk5ODA4MTguCi0gKi8KLXB1YmxpYyBjbGFzcyBQcm9jZXNzaW5nSW5zdHJ1Y3Rpb25JbXBsCi0gICAgZXh0ZW5kcyBDaGFyYWN0ZXJEYXRhSW1wbAotICAgIGltcGxlbWVudHMgUHJvY2Vzc2luZ0luc3RydWN0aW9uIHsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RhbnRzCi0gICAgLy8KLQotICAgIC8qKiBTZXJpYWxpemF0aW9uIHZlcnNpb24uICovCi0gICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDc1NTQ0MzUxNzQwOTk5ODE1MTBMOwotCi0gICAgLy8KLSAgICAvLyBEYXRhCi0gICAgLy8KLQotICAgIHByb3RlY3RlZCBTdHJpbmcgdGFyZ2V0OwotCi0gICAgLy8KLSAgICAvLyBDb25zdHJ1Y3RvcnMKLSAgICAvLwotCi0gICAgLyoqIEZhY3RvcnkgY29uc3RydWN0b3IuICovCi0gICAgcHVibGljIFByb2Nlc3NpbmdJbnN0cnVjdGlvbkltcGwoQ29yZURvY3VtZW50SW1wbCBvd25lckRvYywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdGFyZ2V0LCBTdHJpbmcgZGF0YSkgewotICAgICAgICBzdXBlcihvd25lckRvYywgZGF0YSk7Ci0gICAgICAgIHRoaXMudGFyZ2V0ID0gdGFyZ2V0OwotICAgIH0KLQotICAgIC8vCi0gICAgLy8gTm9kZSBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIEEgc2hvcnQgaW50ZWdlciBpbmRpY2F0aW5nIHdoYXQgdHlwZSBvZiBub2RlIHRoaXMgaXMuIFRoZSBuYW1lZAotICAgICAqIGNvbnN0YW50cyBmb3IgdGhpcyB2YWx1ZSBhcmUgZGVmaW5lZCBpbiB0aGUgb3JnLnczYy5kb20uTm9kZSBpbnRlcmZhY2UuCi0gICAgICovCi0gICAgcHVibGljIHNob3J0IGdldE5vZGVUeXBlKCkgewotICAgICAgICByZXR1cm4gTm9kZS5QUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgdGFyZ2V0Ci0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXROb2RlTmFtZSgpIHsKLSAgICAgICAgaWYgKG5lZWRzU3luY0RhdGEoKSkgewotICAgICAgICAgICAgc3luY2hyb25pemVEYXRhKCk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHRhcmdldDsKLSAgICB9Ci0KLSAgICAvLwotICAgIC8vIFByb2Nlc3NpbmdJbnN0cnVjdGlvbiBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIEEgUEkncyAidGFyZ2V0IiBzdGF0ZXMgd2hhdCBwcm9jZXNzb3IgY2hhbm5lbCB0aGUgUEkncyBkYXRhCi0gICAgICogc2hvdWxkIGJlIGRpcmVjdGVkIHRvLiBJdCBpcyBkZWZpbmVkIGRpZmZlcmVudGx5IGluIEhUTUwgYW5kIFhNTC4KLSAgICAgKiA8cD4KLSAgICAgKiBJbiBYTUwsIGEgUEkncyAidGFyZ2V0IiBpcyB0aGUgZmlyc3QgKHdoaXRlc3BhY2UtZGVsaW1pdGVkKSB0b2tlbgotICAgICAqIGZvbGxvd2luZyB0aGUgIjw/IiB0b2tlbiB0aGF0IGJlZ2lucyB0aGUgUEkuCi0gICAgICogPHA+Ci0gICAgICogSW4gSFRNTCwgdGFyZ2V0IGlzIGFsd2F5cyBudWxsLgotICAgICAqIDxwPgotICAgICAqIE5vdGUgdGhhdCBnZXROb2RlTmFtZSBpcyBhbGlhc2VkIHRvIGdldFRhcmdldC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldCgpIHsKLSAgICAgICAgaWYgKG5lZWRzU3luY0RhdGEoKSkgewotICAgICAgICAgICAgc3luY2hyb25pemVEYXRhKCk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHRhcmdldDsKLQotICAgIH0gLy8gZ2V0VGFyZ2V0KCk6U3RyaW5nCi0KLSAgICAvKioKLSAgICAgKiBBIFBJJ3MgZGF0YSBjb250ZW50IHRlbGxzIHRoZSBwcm9jZXNzb3Igd2hhdCB3ZSBhY3R1YWxseSB3YW50IGl0Ci0gICAgICogdG8gZG8uICBJdCBpcyBkZWZpbmVkIHNsaWdodGx5IGRpZmZlcmVudGx5IGluIEhUTUwgYW5kIFhNTC4KLSAgICAgKiA8cD4KLSAgICAgKiBJbiBYTUwsIHRoZSBkYXRhIGJlZ2lucyB3aXRoIHRoZSBub24td2hpdGVzcGFjZSBjaGFyYWN0ZXIKLSAgICAgKiBpbW1lZGlhdGVseSBhZnRlciB0aGUgdGFyZ2V0IC0tIEBzZWUgZ2V0VGFyZ2V0KCkuCi0gICAgICogPHA+Ci0gICAgICogSW4gSFRNTCwgdGhlIGRhdGEgYmVnaW5zIHdpdGggdGhlIGNoYXJhY3RlciBpbW1lZGlhdGVseSBhZnRlciB0aGUKLSAgICAgKiAiJmx0Oz8iIHRva2VuIHRoYXQgYmVnaW5zIHRoZSBQSS4KLSAgICAgKiA8cD4KLSAgICAgKiBOb3RlIHRoYXQgZ2V0Tm9kZVZhbHVlIGlzIGFsaWFzZWQgdG8gZ2V0RGF0YQotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0RGF0YSgpIHsKLSAgICAgICAgaWYgKG5lZWRzU3luY0RhdGEoKSkgewotICAgICAgICAgICAgc3luY2hyb25pemVEYXRhKCk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGRhdGE7Ci0KLSAgICB9IC8vIGdldERhdGEoKTpTdHJpbmcKLQotICAgIC8qKgotICAgICAqIENoYW5nZSB0aGUgZGF0YSBjb250ZW50IG9mIHRoaXMgUEkuCi0gICAgICogTm90ZSB0aGF0IHNldERhdGEgaXMgYWxpYXNlZCB0byBzZXROb2RlVmFsdWUuCi0gICAgICogQHNlZSAjZ2V0RGF0YSgpLgotICAgICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uKE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUikgaWYgbm9kZSBpcyByZWFkLW9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RGF0YShTdHJpbmcgZGF0YSkgewotICAgICAgICAvLyBIYW5kIG9mZiB0byBzZXROb2RlVmFsdWUgZm9yIGNvZGUtcmV1c2UgcmVhc29ucyAobXV0YXRpb24KLSAgICAgICAgLy8gZXZlbnRzLCByZWFkb25seSBwcm90ZWN0aW9uLCBzeW5jaHJvbml6aW5nLCBldGMuKQotICAgICAgICBzZXROb2RlVmFsdWUoZGF0YSk7Ci0gICAgfSAvLyBzZXREYXRhKFN0cmluZykKLQotCi0KLSAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIGFic29sdXRlIGJhc2UgVVJJIG9mIHRoaXMgbm9kZSBvciBudWxsIGlmIHRoZSBpbXBsZW1lbnRhdGlvbgotICAgICAqIHdhc24ndCBhYmxlIHRvIG9idGFpbiBhbiBhYnNvbHV0ZSBVUkkuIE5vdGU6IElmIHRoZSBVUkkgaXMgbWFsZm9ybWVkLCBhCi0gICAgICogbnVsbCBpcyByZXR1cm5lZC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIGFic29sdXRlIGJhc2UgVVJJIG9mIHRoaXMgbm9kZSBvciBudWxsLgotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0QmFzZVVSSSgpIHsKLQotICAgICAgICBpZiAobmVlZHNTeW5jRGF0YSgpKSB7Ci0gICAgICAgICAgICBzeW5jaHJvbml6ZURhdGEoKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gb3duZXJOb2RlLmdldEJhc2VVUkkoKTsKLSAgICB9Ci0KLQotfSAvLyBjbGFzcyBQcm9jZXNzaW5nSW5zdHJ1Y3Rpb25JbXBsCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vUmFuZ2VFeGNlcHRpb25JbXBsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vUmFuZ2VFeGNlcHRpb25JbXBsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDlmMzkxZjIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL1JhbmdlRXhjZXB0aW9uSW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzcgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDAyLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbTsKLQotaW1wb3J0IG9yZy53M2MuZG9tLnJhbmdlcy5SYW5nZUV4Y2VwdGlvbjsKLQotLyoqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICovCi0KLXB1YmxpYyBjbGFzcyBSYW5nZUV4Y2VwdGlvbkltcGwgZXh0ZW5kcyBSYW5nZUV4Y2VwdGlvbiB7Ci0KLSAgICAvKiogU2VyaWFsaXphdGlvbiB2ZXJzaW9uLiAqLwotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtOTA1ODA1MjYyNzQ2NzI0MDg1Nkw7Ci0KLSAgICBwdWJsaWMgUmFuZ2VFeGNlcHRpb25JbXBsKHNob3J0IGNvZGUsIFN0cmluZyBtZXNzYWdlKSB7Ci0gICAgICAgIHN1cGVyKGNvZGUsbWVzc2FnZSk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL1JhbmdlSW1wbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL1JhbmdlSW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzMWM2MzFkLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9SYW5nZUltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIwODUgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbTsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5DaGFyYWN0ZXJEYXRhOwotaW1wb3J0IG9yZy53M2MuZG9tLkRPTUV4Y2VwdGlvbjsKLWltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudEZyYWdtZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci1pbXBvcnQgb3JnLnczYy5kb20ucmFuZ2VzLlJhbmdlOwotaW1wb3J0IG9yZy53M2MuZG9tLnJhbmdlcy5SYW5nZUV4Y2VwdGlvbjsKLQotCi0vKiogVGhlIFJhbmdlSW1wbCBjbGFzcyBpbXBsZW1lbnRzIHRoZSBvcmcudzNjLmRvbS5yYW5nZS5SYW5nZSBpbnRlcmZhY2UuCi0gKiAgPHA+IFBsZWFzZSBzZWUgdGhlIEFQSSBkb2N1bWVudGF0aW9uIGZvciB0aGUgaW50ZXJmYWNlIGNsYXNzZXMKLSAqICBhbmQgdXNlIHRoZSBpbnRlcmZhY2VzIGluIHlvdXIgY2xpZW50IHByb2dyYW1zLgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKi8KLXB1YmxpYyBjbGFzcyBSYW5nZUltcGwgIGltcGxlbWVudHMgUmFuZ2UgewotCi0gICAgLy8KLSAgICAvLyBDb25zdGFudHMKLSAgICAvLwotCi0KLSAgICAvLwotICAgIC8vIERhdGEKLSAgICAvLwotCi0gICAgRG9jdW1lbnRJbXBsIGZEb2N1bWVudDsKLSAgICBOb2RlIGZTdGFydENvbnRhaW5lcjsKLSAgICBOb2RlIGZFbmRDb250YWluZXI7Ci0gICAgaW50IGZTdGFydE9mZnNldDsKLSAgICBpbnQgZkVuZE9mZnNldDsKLSAgICBib29sZWFuIGZJc0NvbGxhcHNlZDsKLSAgICBib29sZWFuIGZEZXRhY2ggPSBmYWxzZTsKLSAgICBOb2RlIGZJbnNlcnROb2RlID0gbnVsbDsKLSAgICBOb2RlIGZEZWxldGVOb2RlID0gbnVsbDsKLSAgICBOb2RlIGZTcGxpdE5vZGUgPSBudWxsOwotICAgIC8vIFdhcyB0aGUgTm9kZSBpbnNlcnRlZCBmcm9tIHRoZSBSYW5nZSBvciB0aGUgRG9jdW1lbnQKLSAgICBib29sZWFuIGZJbnNlcnRlZEZyb21SYW5nZSA9IGZhbHNlOwotCi0gICAgLyoqIFRoZSBjb25zdHJ1Y3Rvci4gQ2xpZW50cyBtdXN0IHVzZSBEb2N1bWVudFJhbmdlLmNyZWF0ZVJhbmdlKCksCi0gICAgICogIGJlY2F1c2UgaXQgcmVnaXN0ZXJzIHRoZSBSYW5nZSB3aXRoIHRoZSBkb2N1bWVudCwgc28gaXQgY2FuCi0gICAgICogIGJlIGZpeGVkLXVwLgotICAgICAqLwotICAgIHB1YmxpYyBSYW5nZUltcGwoRG9jdW1lbnRJbXBsIGRvY3VtZW50KSB7Ci0gICAgICAgIGZEb2N1bWVudCA9IGRvY3VtZW50OwotICAgICAgICBmU3RhcnRDb250YWluZXIgPSBkb2N1bWVudDsKLSAgICAgICAgZkVuZENvbnRhaW5lciA9IGRvY3VtZW50OwotICAgICAgICBmU3RhcnRPZmZzZXQgPSAwOwotICAgICAgICBmRW5kT2Zmc2V0ID0gMDsKLSAgICAgICAgZkRldGFjaCA9IGZhbHNlOwotICAgIH0KLQotICAgIHB1YmxpYyBOb2RlIGdldFN0YXJ0Q29udGFpbmVyKCkgewotICAgICAgICBpZiAoIGZEZXRhY2ggKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgIERPTUV4Y2VwdGlvbi5JTlZBTElEX1NUQVRFX0VSUiwKLSAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiSU5WQUxJRF9TVEFURV9FUlIiLCBudWxsKSk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGZTdGFydENvbnRhaW5lcjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldFN0YXJ0T2Zmc2V0KCkgewotICAgICAgICBpZiAoIGZEZXRhY2ggKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgIERPTUV4Y2VwdGlvbi5JTlZBTElEX1NUQVRFX0VSUiwKLSAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiSU5WQUxJRF9TVEFURV9FUlIiLCBudWxsKSk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGZTdGFydE9mZnNldDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgTm9kZSBnZXRFbmRDb250YWluZXIoKSB7Ci0gICAgICAgIGlmICggZkRldGFjaCApIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgRE9NRXhjZXB0aW9uLklOVkFMSURfU1RBVEVfRVJSLAotICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sICJJTlZBTElEX1NUQVRFX0VSUiIsIG51bGwpKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZkVuZENvbnRhaW5lcjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldEVuZE9mZnNldCgpIHsKLSAgICAgICAgaWYgKCBmRGV0YWNoICkgewotICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICBET01FeGNlcHRpb24uSU5WQUxJRF9TVEFURV9FUlIsCi0gICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwgIklOVkFMSURfU1RBVEVfRVJSIiwgbnVsbCkpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmRW5kT2Zmc2V0OwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGdldENvbGxhcHNlZCgpIHsKLSAgICAgICAgaWYgKCBmRGV0YWNoICkgewotICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICBET01FeGNlcHRpb24uSU5WQUxJRF9TVEFURV9FUlIsCi0gICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwgIklOVkFMSURfU1RBVEVfRVJSIiwgbnVsbCkpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiAoZlN0YXJ0Q29udGFpbmVyID09IGZFbmRDb250YWluZXIKLSAgICAgICAgICAgICAmJiBmU3RhcnRPZmZzZXQgPT0gZkVuZE9mZnNldCk7Ci0gICAgfQotCi0gICAgcHVibGljIE5vZGUgZ2V0Q29tbW9uQW5jZXN0b3JDb250YWluZXIoKSB7Ci0gICAgICAgIGlmICggZkRldGFjaCApIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgRE9NRXhjZXB0aW9uLklOVkFMSURfU1RBVEVfRVJSLAotICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sICJJTlZBTElEX1NUQVRFX0VSUiIsIG51bGwpKTsKLSAgICAgICAgfQotICAgICAgICBWZWN0b3Igc3RhcnRWID0gbmV3IFZlY3RvcigpOwotICAgICAgICBOb2RlIG5vZGU7Ci0gICAgICAgIGZvciAobm9kZT1mU3RhcnRDb250YWluZXI7IG5vZGUgIT0gbnVsbDsKLSAgICAgICAgICAgICBub2RlPW5vZGUuZ2V0UGFyZW50Tm9kZSgpKQotICAgICAgICB7Ci0gICAgICAgICAgICBzdGFydFYuYWRkRWxlbWVudChub2RlKTsKLSAgICAgICAgfQotICAgICAgICBWZWN0b3IgZW5kViA9IG5ldyBWZWN0b3IoKTsKLSAgICAgICAgZm9yIChub2RlPWZFbmRDb250YWluZXI7IG5vZGUgIT0gbnVsbDsKLSAgICAgICAgICAgICBub2RlPW5vZGUuZ2V0UGFyZW50Tm9kZSgpKQotICAgICAgICB7Ci0gICAgICAgICAgICBlbmRWLmFkZEVsZW1lbnQobm9kZSk7Ci0gICAgICAgIH0KLSAgICAgICAgaW50IHMgPSBzdGFydFYuc2l6ZSgpLTE7Ci0gICAgICAgIGludCBlID0gZW5kVi5zaXplKCktMTsKLSAgICAgICAgT2JqZWN0IHJlc3VsdCA9IG51bGw7Ci0gICAgICAgIHdoaWxlIChzPj0wICYmIGU+PTApIHsKLSAgICAgICAgICAgIGlmIChzdGFydFYuZWxlbWVudEF0KHMpID09IGVuZFYuZWxlbWVudEF0KGUpKSB7Ci0gICAgICAgICAgICAgICAgcmVzdWx0ID0gc3RhcnRWLmVsZW1lbnRBdChzKTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAtLXM7Ci0gICAgICAgICAgICAtLWU7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIChOb2RlKXJlc3VsdDsKLSAgICB9Ci0KLQotICAgIHB1YmxpYyB2b2lkIHNldFN0YXJ0KE5vZGUgcmVmTm9kZSwgaW50IG9mZnNldCkKLSAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgUmFuZ2VFeGNlcHRpb24sIERPTUV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaWYgKGZEb2N1bWVudC5lcnJvckNoZWNraW5nKSB7Ci0gICAgICAgICAgICBpZiAoIGZEZXRhY2gpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICAgICAgRE9NRXhjZXB0aW9uLklOVkFMSURfU1RBVEVfRVJSLAotICAgICAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwgIklOVkFMSURfU1RBVEVfRVJSIiwgbnVsbCkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKCAhaXNMZWdhbENvbnRhaW5lcihyZWZOb2RlKSkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUV4Y2VwdGlvbkltcGwoCi0gICAgICAgICAgICAgICAgICAgICAgICBSYW5nZUV4Y2VwdGlvbi5JTlZBTElEX05PREVfVFlQRV9FUlIsCi0gICAgICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiSU5WQUxJRF9OT0RFX1RZUEVfRVJSIiwgbnVsbCkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKCBmRG9jdW1lbnQgIT0gcmVmTm9kZS5nZXRPd25lckRvY3VtZW50KCkgJiYgZkRvY3VtZW50ICE9IHJlZk5vZGUpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICAgICAgRE9NRXhjZXB0aW9uLldST05HX0RPQ1VNRU5UX0VSUiwKLSAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sICJXUk9OR19ET0NVTUVOVF9FUlIiLCBudWxsKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBjaGVja0luZGV4KHJlZk5vZGUsIG9mZnNldCk7Ci0KLSAgICAgICAgZlN0YXJ0Q29udGFpbmVyID0gcmVmTm9kZTsKLSAgICAgICAgZlN0YXJ0T2Zmc2V0ID0gb2Zmc2V0OwotCi0gICAgICAgIC8vIElmIG9uZSBib3VuZGFyeS1wb2ludCBvZiBhIFJhbmdlIGlzIHNldCB0byBoYXZlIGEgcm9vdCBjb250YWluZXIKLSAgICAgICAgLy8gb3RoZXIKLSAgICAgICAgLy8gdGhhbiB0aGUgY3VycmVudCBvbmUgZm9yIHRoZSBSYW5nZSwgdGhlIFJhbmdlIHNob3VsZCBiZSBjb2xsYXBzZWQgdG8KLSAgICAgICAgLy8gdGhlIG5ldyBwb3NpdGlvbi4KLSAgICAgICAgLy8gVGhlIHN0YXJ0IHBvc2l0aW9uIG9mIGEgUmFuZ2Ugc2hvdWxkIG5ldmVyIGJlIGFmdGVyIHRoZSBlbmQgcG9zaXRpb24uCi0gICAgICAgIGlmIChnZXRDb21tb25BbmNlc3RvckNvbnRhaW5lcigpID09IG51bGwKLSAgICAgICAgICAgICAgICB8fCAoZlN0YXJ0Q29udGFpbmVyID09IGZFbmRDb250YWluZXIgJiYgZkVuZE9mZnNldCA8IGZTdGFydE9mZnNldCkpIHsKLSAgICAgICAgICAgIGNvbGxhcHNlKHRydWUpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0RW5kKE5vZGUgcmVmTm9kZSwgaW50IG9mZnNldCkKLSAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIFJhbmdlRXhjZXB0aW9uLCBET01FeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGlmIChmRG9jdW1lbnQuZXJyb3JDaGVja2luZykgewotICAgICAgICAgICAgaWYgKGZEZXRhY2gpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICAgICAgRE9NRXhjZXB0aW9uLklOVkFMSURfU1RBVEVfRVJSLAotICAgICAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwgIklOVkFMSURfU1RBVEVfRVJSIiwgbnVsbCkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKCAhaXNMZWdhbENvbnRhaW5lcihyZWZOb2RlKSkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUV4Y2VwdGlvbkltcGwoCi0gICAgICAgICAgICAgICAgICAgICAgICBSYW5nZUV4Y2VwdGlvbi5JTlZBTElEX05PREVfVFlQRV9FUlIsCi0gICAgICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiSU5WQUxJRF9OT0RFX1RZUEVfRVJSIiwgbnVsbCkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKCBmRG9jdW1lbnQgIT0gcmVmTm9kZS5nZXRPd25lckRvY3VtZW50KCkgJiYgZkRvY3VtZW50ICE9IHJlZk5vZGUpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICAgICAgRE9NRXhjZXB0aW9uLldST05HX0RPQ1VNRU5UX0VSUiwKLSAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sICJXUk9OR19ET0NVTUVOVF9FUlIiLCBudWxsKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBjaGVja0luZGV4KHJlZk5vZGUsIG9mZnNldCk7Ci0KLSAgICAgICAgZkVuZENvbnRhaW5lciA9IHJlZk5vZGU7Ci0gICAgICAgIGZFbmRPZmZzZXQgPSBvZmZzZXQ7Ci0KLSAgICAgICAgLy8gSWYgb25lIGJvdW5kYXJ5LXBvaW50IG9mIGEgUmFuZ2UgaXMgc2V0IHRvIGhhdmUgYSByb290IGNvbnRhaW5lcgotICAgICAgICAvLyBvdGhlcgotICAgICAgICAvLyB0aGFuIHRoZSBjdXJyZW50IG9uZSBmb3IgdGhlIFJhbmdlLCB0aGUgUmFuZ2Ugc2hvdWxkIGJlIGNvbGxhcHNlZCB0bwotICAgICAgICAvLyB0aGUgbmV3IHBvc2l0aW9uLgotICAgICAgICAvLyBUaGUgc3RhcnQgcG9zaXRpb24gb2YgYSBSYW5nZSBzaG91bGQgbmV2ZXIgYmUgYWZ0ZXIgdGhlIGVuZCBwb3NpdGlvbi4KLSAgICAgICAgaWYgKGdldENvbW1vbkFuY2VzdG9yQ29udGFpbmVyKCkgPT0gbnVsbAotICAgICAgICAgICAgICAgIHx8IChmU3RhcnRDb250YWluZXIgPT0gZkVuZENvbnRhaW5lciAmJiBmRW5kT2Zmc2V0IDwgZlN0YXJ0T2Zmc2V0KSkgewotICAgICAgICAgICAgY29sbGFwc2UoZmFsc2UpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0U3RhcnRCZWZvcmUoTm9kZSByZWZOb2RlKQotICAgICAgICB0aHJvd3MgUmFuZ2VFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGlmIChmRG9jdW1lbnQuZXJyb3JDaGVja2luZykgewotICAgICAgICAgICAgaWYgKGZEZXRhY2gpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICAgICAgRE9NRXhjZXB0aW9uLklOVkFMSURfU1RBVEVfRVJSLAotICAgICAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwgIklOVkFMSURfU1RBVEVfRVJSIiwgbnVsbCkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKCAhaGFzTGVnYWxSb290Q29udGFpbmVyKHJlZk5vZGUpIHx8Ci0gICAgICAgICAgICAgICAgICAgICFpc0xlZ2FsQ29udGFpbmVkTm9kZShyZWZOb2RlKSApCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXhjZXB0aW9uSW1wbCgKLSAgICAgICAgICAgICAgICAgICAgICAgIFJhbmdlRXhjZXB0aW9uLklOVkFMSURfTk9ERV9UWVBFX0VSUiwKLSAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sICJJTlZBTElEX05PREVfVFlQRV9FUlIiLCBudWxsKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoIGZEb2N1bWVudCAhPSByZWZOb2RlLmdldE93bmVyRG9jdW1lbnQoKSAmJiBmRG9jdW1lbnQgIT0gcmVmTm9kZSkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgICAgICBET01FeGNlcHRpb24uV1JPTkdfRE9DVU1FTlRfRVJSLAotICAgICAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwgIldST05HX0RPQ1VNRU5UX0VSUiIsIG51bGwpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGZTdGFydENvbnRhaW5lciA9IHJlZk5vZGUuZ2V0UGFyZW50Tm9kZSgpOwotICAgICAgICBpbnQgaSA9IDA7Ci0gICAgICAgIGZvciAoTm9kZSBuID0gcmVmTm9kZTsgbiE9bnVsbDsgbiA9IG4uZ2V0UHJldmlvdXNTaWJsaW5nKCkpIHsKLSAgICAgICAgICAgIGkrKzsKLSAgICAgICAgfQotICAgICAgICBmU3RhcnRPZmZzZXQgPSBpLTE7Ci0KLSAgICAgICAgLy8gSWYgb25lIGJvdW5kYXJ5LXBvaW50IG9mIGEgUmFuZ2UgaXMgc2V0IHRvIGhhdmUgYSByb290IGNvbnRhaW5lcgotICAgICAgICAvLyBvdGhlcgotICAgICAgICAvLyB0aGFuIHRoZSBjdXJyZW50IG9uZSBmb3IgdGhlIFJhbmdlLCB0aGUgUmFuZ2Ugc2hvdWxkIGJlIGNvbGxhcHNlZCB0bwotICAgICAgICAvLyB0aGUgbmV3IHBvc2l0aW9uLgotICAgICAgICAvLyBUaGUgc3RhcnQgcG9zaXRpb24gb2YgYSBSYW5nZSBzaG91bGQgbmV2ZXIgYmUgYWZ0ZXIgdGhlIGVuZCBwb3NpdGlvbi4KLSAgICAgICAgaWYgKGdldENvbW1vbkFuY2VzdG9yQ29udGFpbmVyKCkgPT0gbnVsbAotICAgICAgICAgICAgICAgIHx8IChmU3RhcnRDb250YWluZXIgPT0gZkVuZENvbnRhaW5lciAmJiBmRW5kT2Zmc2V0IDwgZlN0YXJ0T2Zmc2V0KSkgewotICAgICAgICAgICAgY29sbGFwc2UodHJ1ZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRTdGFydEFmdGVyKE5vZGUgcmVmTm9kZSkKLSAgICAgICAgdGhyb3dzIFJhbmdlRXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAoZkRvY3VtZW50LmVycm9yQ2hlY2tpbmcpIHsKLSAgICAgICAgICAgIGlmIChmRGV0YWNoKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgICAgIERPTUV4Y2VwdGlvbi5JTlZBTElEX1NUQVRFX0VSUiwKLSAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sICJJTlZBTElEX1NUQVRFX0VSUiIsIG51bGwpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmICggIWhhc0xlZ2FsUm9vdENvbnRhaW5lcihyZWZOb2RlKSB8fAotICAgICAgICAgICAgICAgICAgICAhaXNMZWdhbENvbnRhaW5lZE5vZGUocmVmTm9kZSkpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFeGNlcHRpb25JbXBsKAotICAgICAgICAgICAgICAgICAgICAgICAgUmFuZ2VFeGNlcHRpb24uSU5WQUxJRF9OT0RFX1RZUEVfRVJSLAotICAgICAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwgIklOVkFMSURfTk9ERV9UWVBFX0VSUiIsIG51bGwpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmICggZkRvY3VtZW50ICE9IHJlZk5vZGUuZ2V0T3duZXJEb2N1bWVudCgpICYmIGZEb2N1bWVudCAhPSByZWZOb2RlKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgICAgIERPTUV4Y2VwdGlvbi5XUk9OR19ET0NVTUVOVF9FUlIsCi0gICAgICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiV1JPTkdfRE9DVU1FTlRfRVJSIiwgbnVsbCkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGZTdGFydENvbnRhaW5lciA9IHJlZk5vZGUuZ2V0UGFyZW50Tm9kZSgpOwotICAgICAgICBpbnQgaSA9IDA7Ci0gICAgICAgIGZvciAoTm9kZSBuID0gcmVmTm9kZTsgbiE9bnVsbDsgbiA9IG4uZ2V0UHJldmlvdXNTaWJsaW5nKCkpIHsKLSAgICAgICAgICAgIGkrKzsKLSAgICAgICAgfQotICAgICAgICBmU3RhcnRPZmZzZXQgPSBpOwotCi0gICAgICAgIC8vIElmIG9uZSBib3VuZGFyeS1wb2ludCBvZiBhIFJhbmdlIGlzIHNldCB0byBoYXZlIGEgcm9vdCBjb250YWluZXIKLSAgICAgICAgLy8gb3RoZXIKLSAgICAgICAgLy8gdGhhbiB0aGUgY3VycmVudCBvbmUgZm9yIHRoZSBSYW5nZSwgdGhlIFJhbmdlIHNob3VsZCBiZSBjb2xsYXBzZWQgdG8KLSAgICAgICAgLy8gdGhlIG5ldyBwb3NpdGlvbi4KLSAgICAgICAgLy8gVGhlIHN0YXJ0IHBvc2l0aW9uIG9mIGEgUmFuZ2Ugc2hvdWxkIG5ldmVyIGJlIGFmdGVyIHRoZSBlbmQgcG9zaXRpb24uCi0gICAgICAgIGlmIChnZXRDb21tb25BbmNlc3RvckNvbnRhaW5lcigpID09IG51bGwKLSAgICAgICAgICAgICAgICB8fCAoZlN0YXJ0Q29udGFpbmVyID09IGZFbmRDb250YWluZXIgJiYgZkVuZE9mZnNldCA8IGZTdGFydE9mZnNldCkpIHsKLSAgICAgICAgICAgIGNvbGxhcHNlKHRydWUpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0RW5kQmVmb3JlKE5vZGUgcmVmTm9kZSkKLSAgICAgICAgdGhyb3dzIFJhbmdlRXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAoZkRvY3VtZW50LmVycm9yQ2hlY2tpbmcpIHsKLSAgICAgICAgICAgIGlmIChmRGV0YWNoKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgICAgIERPTUV4Y2VwdGlvbi5JTlZBTElEX1NUQVRFX0VSUiwKLSAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sICJJTlZBTElEX1NUQVRFX0VSUiIsIG51bGwpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmICggIWhhc0xlZ2FsUm9vdENvbnRhaW5lcihyZWZOb2RlKSB8fAotICAgICAgICAgICAgICAgICAgICAhaXNMZWdhbENvbnRhaW5lZE5vZGUocmVmTm9kZSkpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFeGNlcHRpb25JbXBsKAotICAgICAgICAgICAgICAgICAgICAgICAgUmFuZ2VFeGNlcHRpb24uSU5WQUxJRF9OT0RFX1RZUEVfRVJSLAotICAgICAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwgIklOVkFMSURfTk9ERV9UWVBFX0VSUiIsIG51bGwpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmICggZkRvY3VtZW50ICE9IHJlZk5vZGUuZ2V0T3duZXJEb2N1bWVudCgpICYmIGZEb2N1bWVudCAhPSByZWZOb2RlKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgICAgIERPTUV4Y2VwdGlvbi5XUk9OR19ET0NVTUVOVF9FUlIsCi0gICAgICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiV1JPTkdfRE9DVU1FTlRfRVJSIiwgbnVsbCkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGZFbmRDb250YWluZXIgPSByZWZOb2RlLmdldFBhcmVudE5vZGUoKTsKLSAgICAgICAgaW50IGkgPSAwOwotICAgICAgICBmb3IgKE5vZGUgbiA9IHJlZk5vZGU7IG4hPW51bGw7IG4gPSBuLmdldFByZXZpb3VzU2libGluZygpKSB7Ci0gICAgICAgICAgICBpKys7Ci0gICAgICAgIH0KLSAgICAgICAgZkVuZE9mZnNldCA9IGktMTsKLQotICAgICAgICAvLyBJZiBvbmUgYm91bmRhcnktcG9pbnQgb2YgYSBSYW5nZSBpcyBzZXQgdG8gaGF2ZSBhIHJvb3QgY29udGFpbmVyCi0gICAgICAgIC8vIG90aGVyCi0gICAgICAgIC8vIHRoYW4gdGhlIGN1cnJlbnQgb25lIGZvciB0aGUgUmFuZ2UsIHRoZSBSYW5nZSBzaG91bGQgYmUgY29sbGFwc2VkIHRvCi0gICAgICAgIC8vIHRoZSBuZXcgcG9zaXRpb24uCi0gICAgICAgIC8vIFRoZSBzdGFydCBwb3NpdGlvbiBvZiBhIFJhbmdlIHNob3VsZCBuZXZlciBiZSBhZnRlciB0aGUgZW5kIHBvc2l0aW9uLgotICAgICAgICBpZiAoZ2V0Q29tbW9uQW5jZXN0b3JDb250YWluZXIoKSA9PSBudWxsCi0gICAgICAgICAgICAgICAgfHwgKGZTdGFydENvbnRhaW5lciA9PSBmRW5kQ29udGFpbmVyICYmIGZFbmRPZmZzZXQgPCBmU3RhcnRPZmZzZXQpKSB7Ci0gICAgICAgICAgICBjb2xsYXBzZShmYWxzZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRFbmRBZnRlcihOb2RlIHJlZk5vZGUpCi0gICAgICAgIHRocm93cyBSYW5nZUV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaWYgKGZEb2N1bWVudC5lcnJvckNoZWNraW5nKSB7Ci0gICAgICAgICAgICBpZiggZkRldGFjaCkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgICAgICBET01FeGNlcHRpb24uSU5WQUxJRF9TVEFURV9FUlIsCi0gICAgICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiSU5WQUxJRF9TVEFURV9FUlIiLCBudWxsKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoICFoYXNMZWdhbFJvb3RDb250YWluZXIocmVmTm9kZSkgfHwKLSAgICAgICAgICAgICAgICAgICAgIWlzTGVnYWxDb250YWluZWROb2RlKHJlZk5vZGUpKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXhjZXB0aW9uSW1wbCgKLSAgICAgICAgICAgICAgICAgICAgICAgIFJhbmdlRXhjZXB0aW9uLklOVkFMSURfTk9ERV9UWVBFX0VSUiwKLSAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sICJJTlZBTElEX05PREVfVFlQRV9FUlIiLCBudWxsKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoIGZEb2N1bWVudCAhPSByZWZOb2RlLmdldE93bmVyRG9jdW1lbnQoKSAmJiBmRG9jdW1lbnQgIT0gcmVmTm9kZSkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgICAgICBET01FeGNlcHRpb24uV1JPTkdfRE9DVU1FTlRfRVJSLAotICAgICAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwgIldST05HX0RPQ1VNRU5UX0VSUiIsIG51bGwpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBmRW5kQ29udGFpbmVyID0gcmVmTm9kZS5nZXRQYXJlbnROb2RlKCk7Ci0gICAgICAgIGludCBpID0gMDsKLSAgICAgICAgZm9yIChOb2RlIG4gPSByZWZOb2RlOyBuIT1udWxsOyBuID0gbi5nZXRQcmV2aW91c1NpYmxpbmcoKSkgewotICAgICAgICAgICAgaSsrOwotICAgICAgICB9Ci0gICAgICAgIGZFbmRPZmZzZXQgPSBpOwotCi0gICAgICAgIC8vIElmIG9uZSBib3VuZGFyeS1wb2ludCBvZiBhIFJhbmdlIGlzIHNldCB0byBoYXZlIGEgcm9vdCBjb250YWluZXIKLSAgICAgICAgLy8gb3RoZXIKLSAgICAgICAgLy8gdGhhbiB0aGUgY3VycmVudCBvbmUgZm9yIHRoZSBSYW5nZSwgdGhlIFJhbmdlIHNob3VsZCBiZSBjb2xsYXBzZWQgdG8KLSAgICAgICAgLy8gdGhlIG5ldyBwb3NpdGlvbi4KLSAgICAgICAgLy8gVGhlIHN0YXJ0IHBvc2l0aW9uIG9mIGEgUmFuZ2Ugc2hvdWxkIG5ldmVyIGJlIGFmdGVyIHRoZSBlbmQgcG9zaXRpb24uCi0gICAgICAgIGlmIChnZXRDb21tb25BbmNlc3RvckNvbnRhaW5lcigpID09IG51bGwKLSAgICAgICAgICAgICAgICB8fCAoZlN0YXJ0Q29udGFpbmVyID09IGZFbmRDb250YWluZXIgJiYgZkVuZE9mZnNldCA8IGZTdGFydE9mZnNldCkpIHsKLSAgICAgICAgICAgIGNvbGxhcHNlKGZhbHNlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGNvbGxhcHNlKGJvb2xlYW4gdG9TdGFydCkgewotCi0gICAgICAgIGlmKCBmRGV0YWNoKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICBET01FeGNlcHRpb24uSU5WQUxJRF9TVEFURV9FUlIsCi0gICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwgIklOVkFMSURfU1RBVEVfRVJSIiwgbnVsbCkpOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKHRvU3RhcnQpIHsKLSAgICAgICAgICAgIGZFbmRDb250YWluZXIgPSBmU3RhcnRDb250YWluZXI7Ci0gICAgICAgICAgICBmRW5kT2Zmc2V0ID0gZlN0YXJ0T2Zmc2V0OwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgZlN0YXJ0Q29udGFpbmVyID0gZkVuZENvbnRhaW5lcjsKLSAgICAgICAgICAgIGZTdGFydE9mZnNldCA9IGZFbmRPZmZzZXQ7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZWxlY3ROb2RlKE5vZGUgcmVmTm9kZSkKLSAgICAgICAgdGhyb3dzIFJhbmdlRXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAoZkRvY3VtZW50LmVycm9yQ2hlY2tpbmcpIHsKLSAgICAgICAgICAgIGlmIChmRGV0YWNoKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgICAgIERPTUV4Y2VwdGlvbi5JTlZBTElEX1NUQVRFX0VSUiwKLSAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sICJJTlZBTElEX1NUQVRFX0VSUiIsIG51bGwpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmICggIWlzTGVnYWxDb250YWluZXIoIHJlZk5vZGUuZ2V0UGFyZW50Tm9kZSgpICkgfHwKLSAgICAgICAgICAgICAgICAgICAgIWlzTGVnYWxDb250YWluZWROb2RlKCByZWZOb2RlICkgKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXhjZXB0aW9uSW1wbCgKLSAgICAgICAgICAgICAgICAgICAgICAgIFJhbmdlRXhjZXB0aW9uLklOVkFMSURfTk9ERV9UWVBFX0VSUiwKLSAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sICJJTlZBTElEX05PREVfVFlQRV9FUlIiLCBudWxsKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoIGZEb2N1bWVudCAhPSByZWZOb2RlLmdldE93bmVyRG9jdW1lbnQoKSAmJiBmRG9jdW1lbnQgIT0gcmVmTm9kZSkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgICAgICBET01FeGNlcHRpb24uV1JPTkdfRE9DVU1FTlRfRVJSLAotICAgICAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwgIldST05HX0RPQ1VNRU5UX0VSUiIsIG51bGwpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBOb2RlIHBhcmVudCA9IHJlZk5vZGUuZ2V0UGFyZW50Tm9kZSgpOwotICAgICAgICBpZiAocGFyZW50ICE9IG51bGwgKSAvLyBSRVZJU1Q6IHdoYXQgdG8gZG8gaWYgaXQgSVMgbnVsbD8KLSAgICAgICAgewotICAgICAgICAgICAgZlN0YXJ0Q29udGFpbmVyID0gcGFyZW50OwotICAgICAgICAgICAgZkVuZENvbnRhaW5lciA9IHBhcmVudDsKLSAgICAgICAgICAgIGludCBpID0gMDsKLSAgICAgICAgICAgIGZvciAoTm9kZSBuID0gcmVmTm9kZTsgbiE9bnVsbDsgbiA9IG4uZ2V0UHJldmlvdXNTaWJsaW5nKCkpIHsKLSAgICAgICAgICAgICAgICBpKys7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmU3RhcnRPZmZzZXQgPSBpLTE7Ci0gICAgICAgICAgICBmRW5kT2Zmc2V0ID0gZlN0YXJ0T2Zmc2V0KzE7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZWxlY3ROb2RlQ29udGVudHMoTm9kZSByZWZOb2RlKQotICAgICAgICB0aHJvd3MgUmFuZ2VFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGlmIChmRG9jdW1lbnQuZXJyb3JDaGVja2luZykgewotICAgICAgICAgICAgaWYoIGZEZXRhY2gpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICAgICAgRE9NRXhjZXB0aW9uLklOVkFMSURfU1RBVEVfRVJSLAotICAgICAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwgIklOVkFMSURfU1RBVEVfRVJSIiwgbnVsbCkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKCAhaXNMZWdhbENvbnRhaW5lcihyZWZOb2RlKSkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUV4Y2VwdGlvbkltcGwoCi0gICAgICAgICAgICAgICAgICAgICAgICBSYW5nZUV4Y2VwdGlvbi5JTlZBTElEX05PREVfVFlQRV9FUlIsCi0gICAgICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiSU5WQUxJRF9OT0RFX1RZUEVfRVJSIiwgbnVsbCkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKCBmRG9jdW1lbnQgIT0gcmVmTm9kZS5nZXRPd25lckRvY3VtZW50KCkgJiYgZkRvY3VtZW50ICE9IHJlZk5vZGUpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICAgICAgRE9NRXhjZXB0aW9uLldST05HX0RPQ1VNRU5UX0VSUiwKLSAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sICJXUk9OR19ET0NVTUVOVF9FUlIiLCBudWxsKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZlN0YXJ0Q29udGFpbmVyID0gcmVmTm9kZTsKLSAgICAgICAgZkVuZENvbnRhaW5lciA9IHJlZk5vZGU7Ci0gICAgICAgIE5vZGUgZmlyc3QgPSByZWZOb2RlLmdldEZpcnN0Q2hpbGQoKTsKLSAgICAgICAgZlN0YXJ0T2Zmc2V0ID0gMDsKLSAgICAgICAgaWYgKGZpcnN0ID09IG51bGwpIHsKLSAgICAgICAgICAgIGZFbmRPZmZzZXQgPSAwOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgaW50IGkgPSAwOwotICAgICAgICAgICAgZm9yIChOb2RlIG4gPSBmaXJzdDsgbiE9bnVsbDsgbiA9IG4uZ2V0TmV4dFNpYmxpbmcoKSkgewotICAgICAgICAgICAgICAgIGkrKzsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGZFbmRPZmZzZXQgPSBpOwotICAgICAgICB9Ci0KLSAgICB9Ci0KLSAgICBwdWJsaWMgc2hvcnQgY29tcGFyZUJvdW5kYXJ5UG9pbnRzKHNob3J0IGhvdywgUmFuZ2Ugc291cmNlUmFuZ2UpCi0gICAgICAgIHRocm93cyBET01FeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGlmIChmRG9jdW1lbnQuZXJyb3JDaGVja2luZykgewotICAgICAgICAgICAgaWYoIGZEZXRhY2gpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICAgICAgRE9NRXhjZXB0aW9uLklOVkFMSURfU1RBVEVfRVJSLAotICAgICAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwgIklOVkFMSURfU1RBVEVfRVJSIiwgbnVsbCkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gV1JPTkdfRE9DVU1FTlRfRVJSOiBSYWlzZWQgaWYgdGhlIHR3byBSYW5nZXMgYXJlIG5vdCBpbiB0aGUgc2FtZSBEb2N1bWVudCBvciBEb2N1bWVudEZyYWdtZW50LgotICAgICAgICAgICAgaWYgKChmRG9jdW1lbnQgIT0gc291cmNlUmFuZ2UuZ2V0U3RhcnRDb250YWluZXIoKS5nZXRPd25lckRvY3VtZW50KCkKLSAgICAgICAgICAgICAgICAgICAgJiYgZkRvY3VtZW50ICE9IHNvdXJjZVJhbmdlLmdldFN0YXJ0Q29udGFpbmVyKCkKLSAgICAgICAgICAgICAgICAgICAgJiYgc291cmNlUmFuZ2UuZ2V0U3RhcnRDb250YWluZXIoKSAhPSBudWxsKQotICAgICAgICAgICAgICAgICAgICB8fCAoZkRvY3VtZW50ICE9IHNvdXJjZVJhbmdlLmdldEVuZENvbnRhaW5lcigpLmdldE93bmVyRG9jdW1lbnQoKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmIGZEb2N1bWVudCAhPSBzb3VyY2VSYW5nZS5nZXRFbmRDb250YWluZXIoKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmIHNvdXJjZVJhbmdlLmdldFN0YXJ0Q29udGFpbmVyKCkgIT0gbnVsbCkpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5XUk9OR19ET0NVTUVOVF9FUlIsCi0gICAgICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoIERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwgIldST05HX0RPQ1VNRU5UX0VSUiIsIG51bGwpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIE5vZGUgZW5kUG9pbnRBOwotICAgICAgICBOb2RlIGVuZFBvaW50QjsKLSAgICAgICAgaW50IG9mZnNldEE7Ci0gICAgICAgIGludCBvZmZzZXRCOwotCi0gICAgICAgIGlmIChob3cgPT0gU1RBUlRfVE9fU1RBUlQpIHsKLSAgICAgICAgICAgIGVuZFBvaW50QSA9IHNvdXJjZVJhbmdlLmdldFN0YXJ0Q29udGFpbmVyKCk7Ci0gICAgICAgICAgICBlbmRQb2ludEIgPSBmU3RhcnRDb250YWluZXI7Ci0gICAgICAgICAgICBvZmZzZXRBID0gc291cmNlUmFuZ2UuZ2V0U3RhcnRPZmZzZXQoKTsKLSAgICAgICAgICAgIG9mZnNldEIgPSBmU3RhcnRPZmZzZXQ7Ci0gICAgICAgIH0gZWxzZQotICAgICAgICBpZiAoaG93ID09IFNUQVJUX1RPX0VORCkgewotICAgICAgICAgICAgZW5kUG9pbnRBID0gc291cmNlUmFuZ2UuZ2V0U3RhcnRDb250YWluZXIoKTsKLSAgICAgICAgICAgIGVuZFBvaW50QiA9IGZFbmRDb250YWluZXI7Ci0gICAgICAgICAgICBvZmZzZXRBID0gc291cmNlUmFuZ2UuZ2V0U3RhcnRPZmZzZXQoKTsKLSAgICAgICAgICAgIG9mZnNldEIgPSBmRW5kT2Zmc2V0OwotICAgICAgICB9IGVsc2UKLSAgICAgICAgaWYgKGhvdyA9PSBFTkRfVE9fU1RBUlQpIHsKLSAgICAgICAgICAgIGVuZFBvaW50QSA9IHNvdXJjZVJhbmdlLmdldEVuZENvbnRhaW5lcigpOwotICAgICAgICAgICAgZW5kUG9pbnRCID0gZlN0YXJ0Q29udGFpbmVyOwotICAgICAgICAgICAgb2Zmc2V0QSA9IHNvdXJjZVJhbmdlLmdldEVuZE9mZnNldCgpOwotICAgICAgICAgICAgb2Zmc2V0QiA9IGZTdGFydE9mZnNldDsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIGVuZFBvaW50QSA9IHNvdXJjZVJhbmdlLmdldEVuZENvbnRhaW5lcigpOwotICAgICAgICAgICAgZW5kUG9pbnRCID0gZkVuZENvbnRhaW5lcjsKLSAgICAgICAgICAgIG9mZnNldEEgPSBzb3VyY2VSYW5nZS5nZXRFbmRPZmZzZXQoKTsKLSAgICAgICAgICAgIG9mZnNldEIgPSBmRW5kT2Zmc2V0OwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gVGhlIERPTSBTcGVjIG91dGxpbmVzIGZvdXIgY2FzZXMgdGhhdCBuZWVkIHRvIGJlIHRlc3RlZAotICAgICAgICAvLyB0byBjb21wYXJlIHR3byByYW5nZSBib3VuZGFyeSBwb2ludHM6Ci0gICAgICAgIC8vICAgY2FzZSAxOiBzYW1lIGNvbnRhaW5lcgotICAgICAgICAvLyAgIGNhc2UgMjogQ2hpbGQgQyBvZiBjb250YWluZXIgQSBpcyBhbmNlc3RvciBvZiBCCi0gICAgICAgIC8vICAgY2FzZSAzOiBDaGlsZCBDIG9mIGNvbnRhaW5lciBCIGlzIGFuY2VzdG9yIG9mIEEKLSAgICAgICAgLy8gICBjYXNlIDQ6IHByZW9yZGVyIHRyYXZlcnNhbCBvZiBjb250ZXh0IHRyZWUuCi0KLSAgICAgICAgLy8gY2FzZSAxOiBzYW1lIGNvbnRhaW5lcgotICAgICAgICBpZiAoZW5kUG9pbnRBID09IGVuZFBvaW50QikgewotICAgICAgICAgICAgaWYgKG9mZnNldEEgPCBvZmZzZXRCKSByZXR1cm4gMTsKLSAgICAgICAgICAgIGlmIChvZmZzZXRBID09IG9mZnNldEIpIHJldHVybiAwOwotICAgICAgICAgICAgcmV0dXJuIC0xOwotICAgICAgICB9Ci0gICAgICAgIC8vIGNhc2UgMjogQ2hpbGQgQyBvZiBjb250YWluZXIgQSBpcyBhbmNlc3RvciBvZiBCCi0gICAgICAgIC8vIFRoaXMgY2FuIGJlIHF1aWNrbHkgdGVzdGVkIGJ5IHdhbGtpbmcgdGhlIHBhcmVudCBjaGFpbiBvZiBCCi0gICAgICAgIGZvciAoIE5vZGUgYyA9IGVuZFBvaW50QiwgcCA9IGMuZ2V0UGFyZW50Tm9kZSgpOwotICAgICAgICAgICAgIHAgIT0gbnVsbDsKLSAgICAgICAgICAgICBjID0gcCwgcCA9IHAuZ2V0UGFyZW50Tm9kZSgpKQotICAgICAgICB7Ci0gICAgICAgICAgICBpZiAocCA9PSBlbmRQb2ludEEpIHsKLSAgICAgICAgICAgICAgICBpbnQgaW5kZXggPSBpbmRleE9mKGMsIGVuZFBvaW50QSk7Ci0gICAgICAgICAgICAgICAgaWYgKG9mZnNldEEgPD0gaW5kZXgpIHJldHVybiAxOwotICAgICAgICAgICAgICAgIHJldHVybiAtMTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIGNhc2UgMzogQ2hpbGQgQyBvZiBjb250YWluZXIgQiBpcyBhbmNlc3RvciBvZiBBCi0gICAgICAgIC8vIFRoaXMgY2FuIGJlIHF1aWNrbHkgdGVzdGVkIGJ5IHdhbGtpbmcgdGhlIHBhcmVudCBjaGFpbiBvZiBBCi0gICAgICAgIGZvciAoIE5vZGUgYyA9IGVuZFBvaW50QSwgcCA9IGMuZ2V0UGFyZW50Tm9kZSgpOwotICAgICAgICAgICAgIHAgIT0gbnVsbDsKLSAgICAgICAgICAgICBjID0gcCwgcCA9IHAuZ2V0UGFyZW50Tm9kZSgpKQotICAgICAgICB7Ci0gICAgICAgICAgICBpZiAocCA9PSBlbmRQb2ludEIpIHsKLSAgICAgICAgICAgICAgICBpbnQgaW5kZXggPSBpbmRleE9mKGMsIGVuZFBvaW50Qik7Ci0gICAgICAgICAgICAgICAgaWYgKGluZGV4IDwgb2Zmc2V0QikgcmV0dXJuIDE7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIC0xOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gY2FzZSA0OiBwcmVvcmRlciB0cmF2ZXJzYWwgb2YgY29udGV4dCB0cmVlLgotICAgICAgICAvLyBJbnN0ZWFkIG9mIGxpdGVyYWxseSB3YWxraW5nIHRoZSBjb250ZXh0IHRyZWUgaW4gcHJlLW9yZGVyLAotICAgICAgICAvLyB3ZSB1c2UgcmVsYXRpdmUgbm9kZSBkZXB0aCB3YWxraW5nIHdoaWNoIGlzIHVzdWFsbHkgZmFzdGVyCi0KLSAgICAgICAgaW50IGRlcHRoRGlmZiA9IDA7Ci0gICAgICAgIGZvciAoIE5vZGUgbiA9IGVuZFBvaW50QTsgbiAhPSBudWxsOyBuID0gbi5nZXRQYXJlbnROb2RlKCkgKQotICAgICAgICAgICAgZGVwdGhEaWZmKys7Ci0gICAgICAgIGZvciAoIE5vZGUgbiA9IGVuZFBvaW50QjsgbiAhPSBudWxsOyBuID0gbi5nZXRQYXJlbnROb2RlKCkgKQotICAgICAgICAgICAgZGVwdGhEaWZmLS07Ci0gICAgICAgIHdoaWxlIChkZXB0aERpZmYgPiAwKSB7Ci0gICAgICAgICAgICBlbmRQb2ludEEgPSBlbmRQb2ludEEuZ2V0UGFyZW50Tm9kZSgpOwotICAgICAgICAgICAgZGVwdGhEaWZmLS07Ci0gICAgICAgIH0KLSAgICAgICAgd2hpbGUgKGRlcHRoRGlmZiA8IDApIHsKLSAgICAgICAgICAgIGVuZFBvaW50QiA9IGVuZFBvaW50Qi5nZXRQYXJlbnROb2RlKCk7Ci0gICAgICAgICAgICBkZXB0aERpZmYrKzsKLSAgICAgICAgfQotICAgICAgICBmb3IgKE5vZGUgcEEgPSBlbmRQb2ludEEuZ2V0UGFyZW50Tm9kZSgpLAotICAgICAgICAgICAgIHBCID0gZW5kUG9pbnRCLmdldFBhcmVudE5vZGUoKTsKLSAgICAgICAgICAgICBwQSAhPSBwQjsKLSAgICAgICAgICAgICBwQSA9IHBBLmdldFBhcmVudE5vZGUoKSwgcEIgPSBwQi5nZXRQYXJlbnROb2RlKCkgKQotICAgICAgICB7Ci0gICAgICAgICAgICBlbmRQb2ludEEgPSBwQTsKLSAgICAgICAgICAgIGVuZFBvaW50QiA9IHBCOwotICAgICAgICB9Ci0gICAgICAgIGZvciAoIE5vZGUgbiA9IGVuZFBvaW50QS5nZXROZXh0U2libGluZygpOwotICAgICAgICAgICAgIG4gIT0gbnVsbDsKLSAgICAgICAgICAgICBuID0gbi5nZXROZXh0U2libGluZygpICkKLSAgICAgICAgewotICAgICAgICAgICAgaWYgKG4gPT0gZW5kUG9pbnRCKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIDE7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIC0xOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGRlbGV0ZUNvbnRlbnRzKCkKLSAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgdHJhdmVyc2VDb250ZW50cyhERUxFVEVfQ09OVEVOVFMpOwotICAgIH0KLQotICAgIHB1YmxpYyBEb2N1bWVudEZyYWdtZW50IGV4dHJhY3RDb250ZW50cygpCi0gICAgICAgIHRocm93cyBET01FeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIHJldHVybiB0cmF2ZXJzZUNvbnRlbnRzKEVYVFJBQ1RfQ09OVEVOVFMpOwotICAgIH0KLQotICAgIHB1YmxpYyBEb2N1bWVudEZyYWdtZW50IGNsb25lQ29udGVudHMoKQotICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gICAgewotICAgICAgICByZXR1cm4gdHJhdmVyc2VDb250ZW50cyhDTE9ORV9DT05URU5UUyk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgaW5zZXJ0Tm9kZShOb2RlIG5ld05vZGUpCi0gICAgICAgIHRocm93cyBET01FeGNlcHRpb24sIFJhbmdlRXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAoIG5ld05vZGUgPT0gbnVsbCApIHJldHVybjsgLy90aHJvdyBleGNlcHRpb24/Ci0KLSAgICAgICAgaW50IHR5cGUgPSBuZXdOb2RlLmdldE5vZGVUeXBlKCk7Ci0KLSAgICAgICAgaWYgKGZEb2N1bWVudC5lcnJvckNoZWNraW5nKSB7Ci0gICAgICAgICAgICBpZiAoZkRldGFjaCkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgICAgICBET01FeGNlcHRpb24uSU5WQUxJRF9TVEFURV9FUlIsCi0gICAgICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiSU5WQUxJRF9TVEFURV9FUlIiLCBudWxsKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoIGZEb2N1bWVudCAhPSBuZXdOb2RlLmdldE93bmVyRG9jdW1lbnQoKSApIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5XUk9OR19ET0NVTUVOVF9FUlIsCi0gICAgICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiV1JPTkdfRE9DVU1FTlRfRVJSIiwgbnVsbCkpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAodHlwZSA9PSBOb2RlLkFUVFJJQlVURV9OT0RFCi0gICAgICAgICAgICAgICAgICAgIHx8IHR5cGUgPT0gTm9kZS5FTlRJVFlfTk9ERQotICAgICAgICAgICAgICAgICAgICB8fCB0eXBlID09IE5vZGUuTk9UQVRJT05fTk9ERQotICAgICAgICAgICAgICAgICAgICB8fCB0eXBlID09IE5vZGUuRE9DVU1FTlRfTk9ERSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFeGNlcHRpb25JbXBsKAotICAgICAgICAgICAgICAgICAgICAgICAgUmFuZ2VFeGNlcHRpb24uSU5WQUxJRF9OT0RFX1RZUEVfRVJSLAotICAgICAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwgIklOVkFMSURfTk9ERV9UWVBFX0VSUiIsIG51bGwpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBOb2RlIGNsb25lQ3VycmVudDsKLSAgICAgICAgTm9kZSBjdXJyZW50OwotICAgICAgICBpbnQgY3VycmVudENoaWxkcmVuID0gMDsKLSAgICAgICAgZkluc2VydGVkRnJvbVJhbmdlID0gdHJ1ZTsKLQotICAgICAgICAvL2Jvb2xlYW4gTVVMVElQTEVfTU9ERSA9IGZhbHNlOwotICAgICAgICBpZiAoZlN0YXJ0Q29udGFpbmVyLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5URVhUX05PREUpIHsKLQotICAgICAgICAgICAgTm9kZSBwYXJlbnQgPSBmU3RhcnRDb250YWluZXIuZ2V0UGFyZW50Tm9kZSgpOwotICAgICAgICAgICAgY3VycmVudENoaWxkcmVuID0gcGFyZW50LmdldENoaWxkTm9kZXMoKS5nZXRMZW5ndGgoKTsgLy9ob2xkcyBudW1iZXIgb2Yga2lkcyBiZWZvcmUgaW5zZXJ0aW9uCi0gICAgICAgICAgICAvLyBzcGxpdCB0ZXh0IG5vZGU6IHJlc3VsdHMgaXMgMyBub2Rlcy4uCi0gICAgICAgICAgICBjbG9uZUN1cnJlbnQgPSBmU3RhcnRDb250YWluZXIuY2xvbmVOb2RlKGZhbHNlKTsKLSAgICAgICAgICAgICgoVGV4dEltcGwpY2xvbmVDdXJyZW50KS5zZXROb2RlVmFsdWVJbnRlcm5hbCgKLSAgICAgICAgICAgICAgICAgICAgKGNsb25lQ3VycmVudC5nZXROb2RlVmFsdWUoKSkuc3Vic3RyaW5nKGZTdGFydE9mZnNldCkpOwotICAgICAgICAgICAgKChUZXh0SW1wbClmU3RhcnRDb250YWluZXIpLnNldE5vZGVWYWx1ZUludGVybmFsKAotICAgICAgICAgICAgICAgICAgICAoZlN0YXJ0Q29udGFpbmVyLmdldE5vZGVWYWx1ZSgpKS5zdWJzdHJpbmcoMCxmU3RhcnRPZmZzZXQpKTsKLSAgICAgICAgICAgIE5vZGUgbmV4dCA9IGZTdGFydENvbnRhaW5lci5nZXROZXh0U2libGluZygpOwotICAgICAgICAgICAgaWYgKG5leHQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBpZiAocGFyZW50ICE9ICBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnQuaW5zZXJ0QmVmb3JlKG5ld05vZGUsIG5leHQpOwotICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50Lmluc2VydEJlZm9yZShjbG9uZUN1cnJlbnQsIG5leHQpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICBpZiAocGFyZW50ICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudC5hcHBlbmRDaGlsZChuZXdOb2RlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudC5hcHBlbmRDaGlsZChjbG9uZUN1cnJlbnQpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAgLy91cGRhdGUgcmFuZ2VzIGFmdGVyIHRoZSBpbnNlcnRpb24KLSAgICAgICAgICAgICBpZiAoIGZFbmRDb250YWluZXIgPT0gZlN0YXJ0Q29udGFpbmVyKSB7Ci0gICAgICAgICAgICAgICAgICBmRW5kQ29udGFpbmVyID0gY2xvbmVDdXJyZW50OyAvL2VuZENvbnRhaW5lciBpcyB0aGUgbmV3IE5vZGUgY3JlYXRlZAotICAgICAgICAgICAgICAgICAgZkVuZE9mZnNldCAtPSBmU3RhcnRPZmZzZXQ7Ci0gICAgICAgICAgICAgfQotICAgICAgICAgICAgIGVsc2UgaWYgKCBmRW5kQ29udGFpbmVyID09IHBhcmVudCApIHsgICAgLy9lbmRDb250YWluZXIgd2FzIG5vdCBhIHRleHQgTm9kZS4KLSAgICAgICAgICAgICAgICAgIC8vZW5kT2Zmc2V0ICsgPSBudW1iZXJfb2ZfY2hpbGRyZW5fYWRkZWQKLSAgICAgICAgICAgICAgICAgICBmRW5kT2Zmc2V0ICs9IChwYXJlbnQuZ2V0Q2hpbGROb2RlcygpLmdldExlbmd0aCgpIC0gY3VycmVudENoaWxkcmVuKTsKLSAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAvLyBzaWduYWwgb3RoZXIgUmFuZ2VzIHRvIHVwZGF0ZSB0aGVpciBzdGFydC9lbmQgY29udGFpbmVycy9vZmZzZXRzCi0gICAgICAgICAgICAgc2lnbmFsU3BsaXREYXRhKGZTdGFydENvbnRhaW5lciwgY2xvbmVDdXJyZW50LCBmU3RhcnRPZmZzZXQpOwotCi0KLSAgICAgICAgfSBlbHNlIHsgLy8gISBURVhUX05PREUKLSAgICAgICAgICAgIGlmICggZkVuZENvbnRhaW5lciA9PSBmU3RhcnRDb250YWluZXIgKSAgICAgIC8vbmVlZCB0byByZW1lbWJlciBudW1iZXIgb2Yga2lkcwotICAgICAgICAgICAgICAgIGN1cnJlbnRDaGlsZHJlbj0gZkVuZENvbnRhaW5lci5nZXRDaGlsZE5vZGVzKCkuZ2V0TGVuZ3RoKCk7Ci0KLSAgICAgICAgICAgIGN1cnJlbnQgPSBmU3RhcnRDb250YWluZXIuZ2V0Rmlyc3RDaGlsZCgpOwotICAgICAgICAgICAgaW50IGkgPSAwOwotICAgICAgICAgICAgZm9yKGkgPSAwOyBpIDwgZlN0YXJ0T2Zmc2V0ICYmIGN1cnJlbnQgIT0gbnVsbDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgY3VycmVudD1jdXJyZW50LmdldE5leHRTaWJsaW5nKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoY3VycmVudCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZlN0YXJ0Q29udGFpbmVyLmluc2VydEJlZm9yZShuZXdOb2RlLCBjdXJyZW50KTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgZlN0YXJ0Q29udGFpbmVyLmFwcGVuZENoaWxkKG5ld05vZGUpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy91cGRhdGUgZkVuZE9mZnNldC4gZXg6PGJvZHk+PHAvPjwvYm9keT4uIFJhbmdlKHN0YXJ0O2VuZCk6IGJvZHksMDsgYm9keSwxCi0gICAgICAgICAgICAvLyBpbnNlcnQgPGgxPjogPGJvZHk+PC9oMT48cC8+PC9ib2R5Pi4gUmFuZ2Uoc3RhcnQ7ZW5kKTogYm9keSwwOyBib2R5LDIKLSAgICAgICAgICAgIGlmICggZkVuZENvbnRhaW5lciA9PSBmU3RhcnRDb250YWluZXIgJiYgZkVuZE9mZnNldCAhPSAwICkgeyAgICAgLy91cGRhdGUgZkVuZE9mZnNldCBpZiBub3QgMAotICAgICAgICAgICAgICAgIGZFbmRPZmZzZXQgKz0gKGZFbmRDb250YWluZXIuZ2V0Q2hpbGROb2RlcygpLmdldExlbmd0aCgpIC0gY3VycmVudENoaWxkcmVuKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBmSW5zZXJ0ZWRGcm9tUmFuZ2UgPSBmYWxzZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzdXJyb3VuZENvbnRlbnRzKE5vZGUgbmV3UGFyZW50KQotICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uLCBSYW5nZUV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaWYgKG5ld1BhcmVudD09bnVsbCkgcmV0dXJuOwotICAgICAgICBpbnQgdHlwZSA9IG5ld1BhcmVudC5nZXROb2RlVHlwZSgpOwotCi0gICAgICAgIGlmIChmRG9jdW1lbnQuZXJyb3JDaGVja2luZykgewotICAgICAgICAgICAgaWYgKGZEZXRhY2gpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICAgICAgRE9NRXhjZXB0aW9uLklOVkFMSURfU1RBVEVfRVJSLAotICAgICAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwgIklOVkFMSURfU1RBVEVfRVJSIiwgbnVsbCkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKHR5cGUgPT0gTm9kZS5BVFRSSUJVVEVfTk9ERQotICAgICAgICAgICAgICAgICAgICB8fCB0eXBlID09IE5vZGUuRU5USVRZX05PREUKLSAgICAgICAgICAgICAgICAgICAgfHwgdHlwZSA9PSBOb2RlLk5PVEFUSU9OX05PREUKLSAgICAgICAgICAgICAgICAgICAgfHwgdHlwZSA9PSBOb2RlLkRPQ1VNRU5UX1RZUEVfTk9ERQotICAgICAgICAgICAgICAgICAgICB8fCB0eXBlID09IE5vZGUuRE9DVU1FTlRfTk9ERQotICAgICAgICAgICAgICAgICAgICB8fCB0eXBlID09IE5vZGUuRE9DVU1FTlRfRlJBR01FTlRfTk9ERSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFeGNlcHRpb25JbXBsKAotICAgICAgICAgICAgICAgICAgICAgICAgUmFuZ2VFeGNlcHRpb24uSU5WQUxJRF9OT0RFX1RZUEVfRVJSLAotICAgICAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwgIklOVkFMSURfTk9ERV9UWVBFX0VSUiIsIG51bGwpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIE5vZGUgcmVhbFN0YXJ0ID0gZlN0YXJ0Q29udGFpbmVyOwotICAgICAgICBOb2RlIHJlYWxFbmQgPSBmRW5kQ29udGFpbmVyOwotICAgICAgICBpZiAoZlN0YXJ0Q29udGFpbmVyLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5URVhUX05PREUpIHsKLSAgICAgICAgICAgIHJlYWxTdGFydCA9IGZTdGFydENvbnRhaW5lci5nZXRQYXJlbnROb2RlKCk7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGZFbmRDb250YWluZXIuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLlRFWFRfTk9ERSkgewotICAgICAgICAgICAgcmVhbEVuZCA9IGZFbmRDb250YWluZXIuZ2V0UGFyZW50Tm9kZSgpOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKHJlYWxTdGFydCAhPSByZWFsRW5kKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXhjZXB0aW9uSW1wbCgKLSAgICAgICAgICAgICAgICBSYW5nZUV4Y2VwdGlvbi5CQURfQk9VTkRBUllQT0lOVFNfRVJSLAotICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sICJCQURfQk9VTkRBUllQT0lOVFNfRVJSIiwgbnVsbCkpOwotICAgICAgICB9Ci0KLSAgICAgICAgRG9jdW1lbnRGcmFnbWVudCBmcmFnID0gZXh0cmFjdENvbnRlbnRzKCk7Ci0gICAgICAgIGluc2VydE5vZGUobmV3UGFyZW50KTsKLSAgICAgICAgbmV3UGFyZW50LmFwcGVuZENoaWxkKGZyYWcpOwotICAgICAgICBzZWxlY3ROb2RlKG5ld1BhcmVudCk7Ci0gICAgfQotCi0gICAgcHVibGljIFJhbmdlIGNsb25lUmFuZ2UoKXsKLSAgICAgICAgaWYoIGZEZXRhY2gpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgIERPTUV4Y2VwdGlvbi5JTlZBTElEX1NUQVRFX0VSUiwKLSAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiSU5WQUxJRF9TVEFURV9FUlIiLCBudWxsKSk7Ci0gICAgICAgIH0KLQotICAgICAgICBSYW5nZSByYW5nZSA9IGZEb2N1bWVudC5jcmVhdGVSYW5nZSgpOwotICAgICAgICByYW5nZS5zZXRTdGFydChmU3RhcnRDb250YWluZXIsIGZTdGFydE9mZnNldCk7Ci0gICAgICAgIHJhbmdlLnNldEVuZChmRW5kQ29udGFpbmVyLCBmRW5kT2Zmc2V0KTsKLSAgICAgICAgcmV0dXJuIHJhbmdlOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKXsKLSAgICAgICAgaWYoIGZEZXRhY2gpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgIERPTUV4Y2VwdGlvbi5JTlZBTElEX1NUQVRFX0VSUiwKLSAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiSU5WQUxJRF9TVEFURV9FUlIiLCBudWxsKSk7Ci0gICAgICAgIH0KLQotICAgICAgICBOb2RlIG5vZGUgPSBmU3RhcnRDb250YWluZXI7Ci0gICAgICAgIE5vZGUgc3RvcE5vZGUgPSBmRW5kQ29udGFpbmVyOwotICAgICAgICBTdHJpbmdCdWZmZXIgc2IgPSBuZXcgU3RyaW5nQnVmZmVyKCk7Ci0gICAgICAgIGlmIChmU3RhcnRDb250YWluZXIuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLlRFWFRfTk9ERQotICAgICAgICAgfHwgZlN0YXJ0Q29udGFpbmVyLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5DREFUQV9TRUNUSU9OX05PREUKLSAgICAgICAgKSB7Ci0gICAgICAgICAgICBpZiAoZlN0YXJ0Q29udGFpbmVyID09IGZFbmRDb250YWluZXIpIHsKLSAgICAgICAgICAgICAgICBzYi5hcHBlbmQoZlN0YXJ0Q29udGFpbmVyLmdldE5vZGVWYWx1ZSgpLnN1YnN0cmluZyhmU3RhcnRPZmZzZXQsIGZFbmRPZmZzZXQpKTsKLSAgICAgICAgICAgICAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHNiLmFwcGVuZChmU3RhcnRDb250YWluZXIuZ2V0Tm9kZVZhbHVlKCkuc3Vic3RyaW5nKGZTdGFydE9mZnNldCkpOwotICAgICAgICAgICAgbm9kZT1uZXh0Tm9kZSAobm9kZSx0cnVlKTsgLy9mRW5kQ29udGFpbmVyIT1mU3RhcnRDb250YWluZXIKLQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgeyAgLy9mU3RhcnRDb250YWluZXIgaXMgbm90IGEgVGV4dE5vZGUKLSAgICAgICAgICAgIG5vZGU9bm9kZS5nZXRGaXJzdENoaWxkKCk7Ci0gICAgICAgICAgICBpZiAoZlN0YXJ0T2Zmc2V0PjApIHsgLy9maW5kIGEgZmlyc3Qgbm9kZSB3aXRoaW4gYSByYW5nZSwgc3BlY2lmaWVkIGJ5IGZTdGFydE9mZnNldAotICAgICAgICAgICAgICAgaW50IGNvdW50ZXI9MDsKLSAgICAgICAgICAgICAgIHdoaWxlIChjb3VudGVyPGZTdGFydE9mZnNldCAmJiBub2RlIT1udWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgbm9kZT1ub2RlLmdldE5leHRTaWJsaW5nKCk7Ci0gICAgICAgICAgICAgICAgICAgY291bnRlcisrOwotICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKG5vZGUgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgIG5vZGUgPSBuZXh0Tm9kZShmU3RhcnRDb250YWluZXIsZmFsc2UpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGlmICggZkVuZENvbnRhaW5lci5nZXROb2RlVHlwZSgpIT0gTm9kZS5URVhUX05PREUgJiYKLSAgICAgICAgICAgICBmRW5kQ29udGFpbmVyLmdldE5vZGVUeXBlKCkhPSBOb2RlLkNEQVRBX1NFQ1RJT05fTk9ERSApewotICAgICAgICAgICAgIGludCBpPWZFbmRPZmZzZXQ7Ci0gICAgICAgICAgICAgc3RvcE5vZGUgPSBmRW5kQ29udGFpbmVyLmdldEZpcnN0Q2hpbGQoKTsKLSAgICAgICAgICAgICB3aGlsZSggaT4wICYmIHN0b3BOb2RlIT1udWxsICl7Ci0gICAgICAgICAgICAgICAgIC0taTsKLSAgICAgICAgICAgICAgICAgc3RvcE5vZGUgPSBzdG9wTm9kZS5nZXROZXh0U2libGluZygpOwotICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICBpZiAoIHN0b3BOb2RlID09IG51bGwgKQotICAgICAgICAgICAgICAgICBzdG9wTm9kZSA9IG5leHROb2RlKCBmRW5kQ29udGFpbmVyLCBmYWxzZSApOwotICAgICAgICAgfQotICAgICAgICAgd2hpbGUgKG5vZGUgIT0gc3RvcE5vZGUpIHsgIC8vbG9vayBpbnRvIGFsbCBraWRzIG9mIHRoZSBSYW5nZQotICAgICAgICAgICAgIGlmIChub2RlID09IG51bGwpIGJyZWFrOwotICAgICAgICAgICAgIGlmIChub2RlLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5URVhUX05PREUKLSAgICAgICAgICAgICB8fCAgbm9kZS5nZXROb2RlVHlwZSgpID09IE5vZGUuQ0RBVEFfU0VDVElPTl9OT0RFKSB7Ci0gICAgICAgICAgICAgICAgIHNiLmFwcGVuZChub2RlLmdldE5vZGVWYWx1ZSgpKTsKLSAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICBub2RlID0gbmV4dE5vZGUobm9kZSwgdHJ1ZSk7Ci0gICAgICAgICB9Ci0KLSAgICAgICAgaWYgKGZFbmRDb250YWluZXIuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLlRFWFRfTk9ERQotICAgICAgICAgfHwgZkVuZENvbnRhaW5lci5nZXROb2RlVHlwZSgpID09IE5vZGUuQ0RBVEFfU0VDVElPTl9OT0RFKSB7Ci0gICAgICAgICAgICBzYi5hcHBlbmQoZkVuZENvbnRhaW5lci5nZXROb2RlVmFsdWUoKS5zdWJzdHJpbmcoMCxmRW5kT2Zmc2V0KSk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgZGV0YWNoKCkgewotICAgICAgICBpZiggZkRldGFjaCkgewotICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbigKLSAgICAgICAgICAgIERPTUV4Y2VwdGlvbi5JTlZBTElEX1NUQVRFX0VSUiwKLSAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiSU5WQUxJRF9TVEFURV9FUlIiLCBudWxsKSk7Ci0gICAgICAgIH0KLSAgICAgICAgZkRldGFjaCA9IHRydWU7Ci0gICAgICAgIGZEb2N1bWVudC5yZW1vdmVSYW5nZSh0aGlzKTsKLSAgICB9Ci0KLSAgICAvLwotICAgIC8vIE11dGF0aW9uIGZ1bmN0aW9ucwotICAgIC8vCi0KLSAgICAvKiogU2lnbmFsIG90aGVyIFJhbmdlcyB0byB1cGRhdGUgdGhlaXIgc3RhcnQvZW5kCi0gICAgICogIGNvbnRhaW5lcnMvb2Zmc2V0cy4gVGhlIGRhdGEgaGFzIGFscmVhZHkgYmVlbiBzcGxpdAotICAgICAqICBpbnRvIHRoZSB0d28gTm9kZXMuCi0gICAgICovCi0gICAgdm9pZCBzaWduYWxTcGxpdERhdGEoTm9kZSBub2RlLCBOb2RlIG5ld05vZGUsIGludCBvZmZzZXQpIHsKLSAgICAgICAgZlNwbGl0Tm9kZSA9IG5vZGU7Ci0gICAgICAgIC8vIG5vdGlmeSBkb2N1bWVudAotICAgICAgICBmRG9jdW1lbnQuc3BsaXREYXRhKG5vZGUsIG5ld05vZGUsIG9mZnNldCk7Ci0gICAgICAgIGZTcGxpdE5vZGUgPSBudWxsOwotICAgIH0KLQotICAgIC8qKiBGaXggdXAgdGhpcyBSYW5nZSBpZiBhbm90aGVyIFJhbmdlIGhhcyBzcGxpdCBhIFRleHQgTm9kZQotICAgICAqICBpbnRvIDIgTm9kZXMuCi0gICAgICovCi0gICAgdm9pZCByZWNlaXZlU3BsaXREYXRhKE5vZGUgbm9kZSwgTm9kZSBuZXdOb2RlLCBpbnQgb2Zmc2V0KSB7Ci0gICAgICAgIGlmIChub2RlID09IG51bGwgfHwgbmV3Tm9kZSA9PSBudWxsKSByZXR1cm47Ci0gICAgICAgIGlmIChmU3BsaXROb2RlID09IG5vZGUpIHJldHVybjsKLQotICAgICAgICBpZiAobm9kZSA9PSBmU3RhcnRDb250YWluZXIKLSAgICAgICAgJiYgZlN0YXJ0Q29udGFpbmVyLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5URVhUX05PREUpIHsKLSAgICAgICAgICAgIGlmIChmU3RhcnRPZmZzZXQgPiBvZmZzZXQpIHsKLSAgICAgICAgICAgICAgICBmU3RhcnRPZmZzZXQgPSBmU3RhcnRPZmZzZXQgLSBvZmZzZXQ7Ci0gICAgICAgICAgICAgICAgZlN0YXJ0Q29udGFpbmVyID0gbmV3Tm9kZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBpZiAobm9kZSA9PSBmRW5kQ29udGFpbmVyCi0gICAgICAgICYmIGZFbmRDb250YWluZXIuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLlRFWFRfTk9ERSkgewotICAgICAgICAgICAgaWYgKGZFbmRPZmZzZXQgPiBvZmZzZXQpIHsKLSAgICAgICAgICAgICAgICBmRW5kT2Zmc2V0ID0gZkVuZE9mZnNldC1vZmZzZXQ7Ci0gICAgICAgICAgICAgICAgZkVuZENvbnRhaW5lciA9IG5ld05vZGU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgIH0KLQotICAgIC8qKiBUaGlzIGZ1bmN0aW9uIGluc2VydHMgdGV4dCBpbnRvIGEgTm9kZSBhbmQgaW52b2tlcwotICAgICAqICBhIG1ldGhvZCB0byBmaXgtdXAgYWxsIG90aGVyIFJhbmdlcy4KLSAgICAgKi8KLSAgICB2b2lkIGRlbGV0ZURhdGEoQ2hhcmFjdGVyRGF0YSBub2RlLCBpbnQgb2Zmc2V0LCBpbnQgY291bnQpIHsKLSAgICAgICAgZkRlbGV0ZU5vZGUgPSBub2RlOwotICAgICAgICBub2RlLmRlbGV0ZURhdGEoIG9mZnNldCwgIGNvdW50KTsKLSAgICAgICAgZkRlbGV0ZU5vZGUgPSBudWxsOwotICAgIH0KLQotCi0gICAgLyoqIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGZyb20gRE9NLgotICAgICAqICBUaGUgIHRleHQgaGFzIGFscmVhZHkgYmVlZW4gaW5zZXJ0ZWQuCi0gICAgICogIEZpeC11cCBhbnkgb2Zmc2V0cy4KLSAgICAgKi8KLSAgICB2b2lkIHJlY2VpdmVEZWxldGVkVGV4dChOb2RlIG5vZGUsIGludCBvZmZzZXQsIGludCBjb3VudCkgewotICAgICAgICBpZiAobm9kZSA9PSBudWxsKSByZXR1cm47Ci0gICAgICAgIGlmIChmRGVsZXRlTm9kZSA9PSBub2RlKSByZXR1cm47Ci0gICAgICAgIGlmIChub2RlID09IGZTdGFydENvbnRhaW5lcgotICAgICAgICAmJiBmU3RhcnRDb250YWluZXIuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLlRFWFRfTk9ERSkgewotICAgICAgICAgICAgaWYgKGZTdGFydE9mZnNldCA+IG9mZnNldCtjb3VudCkgewotICAgICAgICAgICAgICAgIGZTdGFydE9mZnNldCA9IG9mZnNldCsoZlN0YXJ0T2Zmc2V0LShvZmZzZXQrY291bnQpKTsKLSAgICAgICAgICAgIH0gZWxzZQotICAgICAgICAgICAgaWYgKGZTdGFydE9mZnNldCA+IG9mZnNldCkgewotICAgICAgICAgICAgICAgIGZTdGFydE9mZnNldCA9IG9mZnNldDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBpZiAobm9kZSA9PSBmRW5kQ29udGFpbmVyCi0gICAgICAgICYmIGZFbmRDb250YWluZXIuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLlRFWFRfTk9ERSkgewotICAgICAgICAgICAgaWYgKGZFbmRPZmZzZXQgPiBvZmZzZXQrY291bnQpIHsKLSAgICAgICAgICAgICAgICBmRW5kT2Zmc2V0ID0gb2Zmc2V0KyhmRW5kT2Zmc2V0LShvZmZzZXQrY291bnQpKTsKLSAgICAgICAgICAgIH0gZWxzZQotICAgICAgICAgICAgaWYgKGZFbmRPZmZzZXQgPiBvZmZzZXQpIHsKLSAgICAgICAgICAgICAgICBmRW5kT2Zmc2V0ID0gb2Zmc2V0OwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICB9Ci0KLSAgICAvKiogVGhpcyBmdW5jdGlvbiBpbnNlcnRzIHRleHQgaW50byBhIE5vZGUgYW5kIGludm9rZXMKLSAgICAgKiAgYSBtZXRob2QgdG8gZml4LXVwIGFsbCBvdGhlciBSYW5nZXMuCi0gICAgICovCi0gICAgdm9pZCBpbnNlcnREYXRhKENoYXJhY3RlckRhdGEgbm9kZSwgaW50IGluZGV4LCBTdHJpbmcgaW5zZXJ0KSB7Ci0gICAgICAgIGZJbnNlcnROb2RlID0gbm9kZTsKLSAgICAgICAgbm9kZS5pbnNlcnREYXRhKCBpbmRleCwgIGluc2VydCk7Ci0gICAgICAgIGZJbnNlcnROb2RlID0gbnVsbDsKLSAgICB9Ci0KLQotICAgIC8qKiBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBmcm9tIERPTS4KLSAgICAgKiAgVGhlICB0ZXh0IGhhcyBhbHJlYWR5IGJlZWVuIGluc2VydGVkLgotICAgICAqICBGaXgtdXAgYW55IG9mZnNldHMuCi0gICAgICovCi0gICAgdm9pZCByZWNlaXZlSW5zZXJ0ZWRUZXh0KE5vZGUgbm9kZSwgaW50IGluZGV4LCBpbnQgbGVuKSB7Ci0gICAgICAgIGlmIChub2RlID09IG51bGwpIHJldHVybjsKLSAgICAgICAgaWYgKGZJbnNlcnROb2RlID09IG5vZGUpIHJldHVybjsKLSAgICAgICAgaWYgKG5vZGUgPT0gZlN0YXJ0Q29udGFpbmVyCi0gICAgICAgICYmIGZTdGFydENvbnRhaW5lci5nZXROb2RlVHlwZSgpID09IE5vZGUuVEVYVF9OT0RFKSB7Ci0gICAgICAgICAgICBpZiAoaW5kZXggPCBmU3RhcnRPZmZzZXQpIHsKLSAgICAgICAgICAgICAgICBmU3RhcnRPZmZzZXQgPSBmU3RhcnRPZmZzZXQrbGVuOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGlmIChub2RlID09IGZFbmRDb250YWluZXIKLSAgICAgICAgJiYgZkVuZENvbnRhaW5lci5nZXROb2RlVHlwZSgpID09IE5vZGUuVEVYVF9OT0RFKSB7Ci0gICAgICAgICAgICBpZiAoaW5kZXggPCBmRW5kT2Zmc2V0KSB7Ci0gICAgICAgICAgICAgICAgZkVuZE9mZnNldCA9IGZFbmRPZmZzZXQrbGVuOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICB9Ci0KLSAgICAvKiogVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgZnJvbSBET00uCi0gICAgICogIFRoZSAgdGV4dCBoYXMgYWxyZWFkeSBiZWVlbiByZXBsYWNlZC4KLSAgICAgKiAgRml4LXVwIGFueSBvZmZzZXRzLgotICAgICAqLwotICAgIHZvaWQgcmVjZWl2ZVJlcGxhY2VkVGV4dChOb2RlIG5vZGUpIHsKLSAgICAgICAgaWYgKG5vZGUgPT0gbnVsbCkgcmV0dXJuOwotICAgICAgICBpZiAobm9kZSA9PSBmU3RhcnRDb250YWluZXIKLSAgICAgICAgJiYgZlN0YXJ0Q29udGFpbmVyLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5URVhUX05PREUpIHsKLSAgICAgICAgICAgIGZTdGFydE9mZnNldCA9IDA7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKG5vZGUgPT0gZkVuZENvbnRhaW5lcgotICAgICAgICAmJiBmRW5kQ29udGFpbmVyLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5URVhUX05PREUpIHsKLSAgICAgICAgICAgIGZFbmRPZmZzZXQgPSAwOwotICAgICAgICB9Ci0KLSAgICB9Ci0KLSAgICAvKiogVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgZnJvbSB0aGUgRE9NLgotICAgICAqICBUaGlzIG5vZGUgaGFzIGFscmVhZHkgYmVlbiBpbnNlcnRlZCBpbnRvIHRoZSBET00uCi0gICAgICogIEZpeC11cCBhbnkgb2Zmc2V0cy4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBpbnNlcnRlZE5vZGVGcm9tRE9NKE5vZGUgbm9kZSkgewotICAgICAgICBpZiAobm9kZSA9PSBudWxsKSByZXR1cm47Ci0gICAgICAgIGlmIChmSW5zZXJ0Tm9kZSA9PSBub2RlKSByZXR1cm47Ci0gICAgICAgIGlmIChmSW5zZXJ0ZWRGcm9tUmFuZ2UpIHJldHVybjsgLy8gT2Zmc2V0cyBhcmUgYWRqdXN0ZWQgaW4gUmFuZ2UuaW5zZXJ0Tm9kZQotCi0gICAgICAgIE5vZGUgcGFyZW50ID0gbm9kZS5nZXRQYXJlbnROb2RlKCk7Ci0KLSAgICAgICAgaWYgKHBhcmVudCA9PSBmU3RhcnRDb250YWluZXIpIHsKLSAgICAgICAgICAgIGludCBpbmRleCA9IGluZGV4T2Yobm9kZSwgZlN0YXJ0Q29udGFpbmVyKTsKLSAgICAgICAgICAgIGlmIChpbmRleCA8IGZTdGFydE9mZnNldCkgewotICAgICAgICAgICAgICAgIGZTdGFydE9mZnNldCsrOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKHBhcmVudCA9PSBmRW5kQ29udGFpbmVyKSB7Ci0gICAgICAgICAgICBpbnQgaW5kZXggPSBpbmRleE9mKG5vZGUsIGZFbmRDb250YWluZXIpOwotICAgICAgICAgICAgaWYgKGluZGV4IDwgZkVuZE9mZnNldCkgewotICAgICAgICAgICAgICAgIGZFbmRPZmZzZXQrKzsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgfQotCi0gICAgLyoqIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIHdpdGhpbiBSYW5nZQotICAgICAqICBpbnN0ZWFkIG9mIE5vZGUucmVtb3ZlQ2hpbGQsCi0gICAgICogIHNvIHRoYXQgdGhlIHJhbmdlIGNhbiByZW1lbWJlciB0aGF0IGl0IGlzIGFjdGl2ZWx5Ci0gICAgICogIHJlbW92aW5nIHRoaXMgY2hpbGQuCi0gICAgICovCi0KLSAgICBOb2RlIGZSZW1vdmVDaGlsZCA9IG51bGw7Ci0gICAgTm9kZSByZW1vdmVDaGlsZChOb2RlIHBhcmVudCwgTm9kZSBjaGlsZCkgewotICAgICAgICBmUmVtb3ZlQ2hpbGQgPSBjaGlsZDsKLSAgICAgICAgTm9kZSBuID0gcGFyZW50LnJlbW92ZUNoaWxkKGNoaWxkKTsKLSAgICAgICAgZlJlbW92ZUNoaWxkID0gbnVsbDsKLSAgICAgICAgcmV0dXJuIG47Ci0gICAgfQotCi0gICAgLyoqIFRoaXMgZnVuY3Rpb24gbXVzdCBiZSBjYWxsZWQgYnkgdGhlIERPTSBfQkVGT1JFXwotICAgICAqICBhIG5vZGUgaXMgZGVsZXRlZCwgYmVjYXVzZSBhdCB0aGF0IHRpbWUgaXQgaXMKLSAgICAgKiAgY29ubmVjdGVkIGluIHRoZSBET00gdHJlZSwgd2hpY2ggd2UgZGVwZW5kIG9uLgotICAgICAqLwotICAgIHZvaWQgcmVtb3ZlTm9kZShOb2RlIG5vZGUpIHsKLSAgICAgICAgaWYgKG5vZGUgPT0gbnVsbCkgcmV0dXJuOwotICAgICAgICBpZiAoZlJlbW92ZUNoaWxkID09IG5vZGUpIHJldHVybjsKLQotICAgICAgICBOb2RlIHBhcmVudCA9IG5vZGUuZ2V0UGFyZW50Tm9kZSgpOwotCi0gICAgICAgIGlmIChwYXJlbnQgPT0gZlN0YXJ0Q29udGFpbmVyKSB7Ci0gICAgICAgICAgICBpbnQgaW5kZXggPSBpbmRleE9mKG5vZGUsIGZTdGFydENvbnRhaW5lcik7Ci0gICAgICAgICAgICBpZiAoaW5kZXggPCBmU3RhcnRPZmZzZXQpIHsKLSAgICAgICAgICAgICAgICBmU3RhcnRPZmZzZXQtLTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGlmIChwYXJlbnQgPT0gZkVuZENvbnRhaW5lcikgewotICAgICAgICAgICAgaW50IGluZGV4ID0gaW5kZXhPZihub2RlLCBmRW5kQ29udGFpbmVyKTsKLSAgICAgICAgICAgIGlmIChpbmRleCA8IGZFbmRPZmZzZXQpIHsKLSAgICAgICAgICAgICAgICBmRW5kT2Zmc2V0LS07Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgLy9zdGFydENvbnRhaW5lciBvciBlbmRDb250YWluZXIgb3IgYm90aCBpcy9hcmUgdGhlIGFuY2VzdG9yKHMpIG9mIHRoZSBOb2RlIHRvIGJlIGRlbGV0ZWQKLSAgICAgICAgaWYgKHBhcmVudCAhPSBmU3RhcnRDb250YWluZXIKLSAgICAgICAgfHwgIHBhcmVudCAhPSBmRW5kQ29udGFpbmVyKSB7Ci0gICAgICAgICAgICBpZiAoaXNBbmNlc3Rvck9mKG5vZGUsIGZTdGFydENvbnRhaW5lcikpIHsKLSAgICAgICAgICAgICAgICBmU3RhcnRDb250YWluZXIgPSBwYXJlbnQ7Ci0gICAgICAgICAgICAgICAgZlN0YXJ0T2Zmc2V0ID0gaW5kZXhPZiggbm9kZSwgcGFyZW50KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChpc0FuY2VzdG9yT2Yobm9kZSwgZkVuZENvbnRhaW5lcikpIHsKLSAgICAgICAgICAgICAgICBmRW5kQ29udGFpbmVyID0gcGFyZW50OwotICAgICAgICAgICAgICAgIGZFbmRPZmZzZXQgPSBpbmRleE9mKCBub2RlLCBwYXJlbnQpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICB9Ci0KLSAgICAvLwotICAgIC8vIFV0aWxpdHkgZnVuY3Rpb25zLgotICAgIC8vCi0KLSAgICAvLyBwYXJhbWV0ZXJzIGZvciB0cmF2ZXJzZUNvbnRlbnRzKGludCkKLSAgICAvL1JFVklTVDogdXNlIGJvb2xlYW4sIHNpbmNlIHRoZXJlIGFyZSBvbmx5IDIgbm93Li4uCi0gICAgc3RhdGljIGZpbmFsIGludCBFWFRSQUNUX0NPTlRFTlRTID0gMTsKLSAgICBzdGF0aWMgZmluYWwgaW50IENMT05FX0NPTlRFTlRTID0gMjsKLSAgICBzdGF0aWMgZmluYWwgaW50IERFTEVURV9DT05URU5UUyA9IDM7Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIGlzIHRoZSBtYXN0ZXIgcm91dGluZSBpbnZva2VkIHRvIHZpc2l0IHRoZSBub2RlcwotICAgICAqIHNlbGVjdGVkIGJ5IHRoaXMgcmFuZ2UuICBGb3IgZWFjaCBzdWNoIG5vZGUsIGRpZmZlcmVudAotICAgICAqIGFjdGlvbnMgYXJlIHRha2VuIGRlcGVuZGluZyBvbiB0aGUgdmFsdWUgb2YgdGhlCi0gICAgICogPGNvZGU+aG93PC9jb2RlPiBhcmd1bWVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBob3cgICAgU3BlY2lmaWVzIHdoYXQgdHlwZSBvZiB0cmF2ZXJzYWwgaXMgYmVpbmcKLSAgICAgKiAgICAgICAgICAgICAgIHJlcXVlc3RlZCAoZXh0cmFjdCwgY2xvbmUsIG9yIGRlbGV0ZSkuCi0gICAgICogICAgICAgICAgICAgICBMZWdhbCB2YWx1ZXMgZm9yIHRoaXMgYXJndW1lbnQgYXJlOgotICAgICAqCi0gICAgICogICAgICAgICAgICAgICA8b2w+Ci0gICAgICogICAgICAgICAgICAgICA8bGk+PGNvZGU+RVhUUkFDVF9DT05URU5UUzwvY29kZT4gLSB3aWxsIHByb2R1Y2UKLSAgICAgKiAgICAgICAgICAgICAgIGEgZG9jdW1lbnQgZnJhZ21lbnQgY29udGFpbmluZyB0aGUgcmFuZ2UncyBjb250ZW50LgotICAgICAqICAgICAgICAgICAgICAgUGFydGlhbGx5IHNlbGVjdGVkIG5vZGVzIGFyZSBjb3BpZWQsIGJ1dCBmdWxseQotICAgICAqICAgICAgICAgICAgICAgc2VsZWN0ZWQgbm9kZXMgYXJlIG1vdmVkLgotICAgICAqCi0gICAgICogICAgICAgICAgICAgICA8bGk+PGNvZGU+Q0xPTkVfQ09OVEVOVFM8L2NvZGU+IC0gd2lsbCBsZWF2ZSB0aGUKLSAgICAgKiAgICAgICAgICAgICAgIGNvbnRleHQgdHJlZSBvZiB0aGUgcmFuZ2UgdW5kaXN0dXJiZWQsIGJ1dCBzaWxsCi0gICAgICogICAgICAgICAgICAgICBwcm9kdWNlZCBjbG9uZWQgY29udGVudCBpbiBhIGRvY3VtZW50IGZyYWdtZW50Ci0gICAgICoKLSAgICAgKiAgICAgICAgICAgICAgIDxsaT48Y29kZT5ERUxFVEVfQ09OVEVOVFM8L2NvZGU+IC0gd2lsbCBkZWxldGUgZnJvbQotICAgICAqICAgICAgICAgICAgICAgdGhlIGNvbnRleHQgdHJlZSBvZiB0aGUgcmFuZ2UsIGFsbCBmdWxseSBzZWxlY3RlZAotICAgICAqICAgICAgICAgICAgICAgbm9kZXMuCi0gICAgICogICAgICAgICAgICAgICA8L29sPgotICAgICAqCi0gICAgICogQHJldHVybiBSZXR1cm5zIGEgZG9jdW1lbnQgZnJhZ21lbnQgY29udGFpbmluZyBhbnkKLSAgICAgKiAgICAgICAgIGNvcGllZCBvciBleHRyYWN0ZWQgbm9kZXMuICBJZiB0aGUgPGNvZGU+aG93PC9jb2RlPgotICAgICAqICAgICAgICAgcGFyYW1ldGVyIHdhcyA8Y29kZT5ERUxFVEVfQ09OVEVOVFM8L2NvZGU+LCB0aGUKLSAgICAgKiAgICAgICAgIHJldHVybiB2YWx1ZSBpcyBudWxsLgotICAgICAqLwotICAgIHByaXZhdGUgRG9jdW1lbnRGcmFnbWVudCB0cmF2ZXJzZUNvbnRlbnRzKCBpbnQgaG93ICkKLSAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaWYgKGZTdGFydENvbnRhaW5lciA9PSBudWxsIHx8IGZFbmRDb250YWluZXIgPT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIG51bGw7IC8vIFJFVklTVDogVGhyb3cgZXhjZXB0aW9uPwotICAgICAgICB9Ci0KLSAgICAgICAgLy9DaGVjayBmb3IgYSBkZXRhY2hlZCByYW5nZS4KLSAgICAgICAgaWYoIGZEZXRhY2gpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgRE9NRXhjZXB0aW9uLklOVkFMSURfU1RBVEVfRVJSLAotICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sICJJTlZBTElEX1NUQVRFX0VSUiIsIG51bGwpKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8qCi0gICAgICAgICAgVHJhdmVyc2FsIGlzIGFjY29tcGxpc2hlZCBieSBmaXJzdCBkZXRlcm1pbmluZyB0aGUKLSAgICAgICAgICByZWxhdGlvbnNoaXAgYmV0d2VlbiB0aGUgZW5kcG9pbnRzIG9mIHRoZSByYW5nZS4KLSAgICAgICAgICBGb3IgZWFjaCBvZiBmb3VyIHNpZ25pZmljYW50IHJlbGF0aW9uc2hpcHMsIHdlIHdpbGwKLSAgICAgICAgICBkZWxlZ2F0ZSB0aGUgdHJhdmVyc2FsIGNhbGwgdG8gYSBtZXRob2QgdGhhdAotICAgICAgICAgIGNhbiBtYWtlIGFwcHJvcHJpYXRlIGFzc3VtcHRpb25zLgotICAgICAgICAgKi8KLQotICAgICAgICAvLyBjYXNlIDE6IHNhbWUgY29udGFpbmVyCi0gICAgICAgIGlmICggZlN0YXJ0Q29udGFpbmVyID09IGZFbmRDb250YWluZXIgKQotICAgICAgICAgICAgcmV0dXJuIHRyYXZlcnNlU2FtZUNvbnRhaW5lciggaG93ICk7Ci0KLQotICAgICAgICAvLyBjYXNlIDI6IENoaWxkIEMgb2Ygc3RhcnQgY29udGFpbmVyIGlzIGFuY2VzdG9yIG9mIGVuZCBjb250YWluZXIKLSAgICAgICAgLy8gVGhpcyBjYW4gYmUgcXVpY2tseSB0ZXN0ZWQgYnkgd2Fsa2luZyB0aGUgcGFyZW50IGNoYWluIG9mCi0gICAgICAgIC8vIGVuZCBjb250YWluZXIKLSAgICAgICAgaW50IGVuZENvbnRhaW5lckRlcHRoID0gMDsKLSAgICAgICAgZm9yICggTm9kZSBjID0gZkVuZENvbnRhaW5lciwgcCA9IGMuZ2V0UGFyZW50Tm9kZSgpOwotICAgICAgICAgICAgIHAgIT0gbnVsbDsKLSAgICAgICAgICAgICBjID0gcCwgcCA9IHAuZ2V0UGFyZW50Tm9kZSgpKQotICAgICAgICB7Ci0gICAgICAgICAgICBpZiAocCA9PSBmU3RhcnRDb250YWluZXIpCi0gICAgICAgICAgICAgICAgcmV0dXJuIHRyYXZlcnNlQ29tbW9uU3RhcnRDb250YWluZXIoIGMsIGhvdyApOwotICAgICAgICAgICAgKytlbmRDb250YWluZXJEZXB0aDsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIGNhc2UgMzogQ2hpbGQgQyBvZiBjb250YWluZXIgQiBpcyBhbmNlc3RvciBvZiBBCi0gICAgICAgIC8vIFRoaXMgY2FuIGJlIHF1aWNrbHkgdGVzdGVkIGJ5IHdhbGtpbmcgdGhlIHBhcmVudCBjaGFpbiBvZiBBCi0gICAgICAgIGludCBzdGFydENvbnRhaW5lckRlcHRoID0gMDsKLSAgICAgICAgZm9yICggTm9kZSBjID0gZlN0YXJ0Q29udGFpbmVyLCBwID0gYy5nZXRQYXJlbnROb2RlKCk7Ci0gICAgICAgICAgICAgcCAhPSBudWxsOwotICAgICAgICAgICAgIGMgPSBwLCBwID0gcC5nZXRQYXJlbnROb2RlKCkpCi0gICAgICAgIHsKLSAgICAgICAgICAgIGlmIChwID09IGZFbmRDb250YWluZXIpCi0gICAgICAgICAgICAgICAgcmV0dXJuIHRyYXZlcnNlQ29tbW9uRW5kQ29udGFpbmVyKCBjLCBob3cgKTsKLSAgICAgICAgICAgICsrc3RhcnRDb250YWluZXJEZXB0aDsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIGNhc2UgNDogVGhlcmUgaXMgYSBjb21tb24gYW5jZXN0b3IgY29udGFpbmVyLiAgRmluZCB0aGUKLSAgICAgICAgLy8gYW5jZXN0b3Igc2libGluZ3MgdGhhdCBhcmUgY2hpbGRyZW4gb2YgdGhhdCBjb250YWluZXIuCi0gICAgICAgIGludCBkZXB0aERpZmYgPSBzdGFydENvbnRhaW5lckRlcHRoIC0gZW5kQ29udGFpbmVyRGVwdGg7Ci0KLSAgICAgICAgTm9kZSBzdGFydE5vZGUgPSBmU3RhcnRDb250YWluZXI7Ci0gICAgICAgIHdoaWxlIChkZXB0aERpZmYgPiAwKSB7Ci0gICAgICAgICAgICBzdGFydE5vZGUgPSBzdGFydE5vZGUuZ2V0UGFyZW50Tm9kZSgpOwotICAgICAgICAgICAgZGVwdGhEaWZmLS07Ci0gICAgICAgIH0KLQotICAgICAgICBOb2RlIGVuZE5vZGUgPSBmRW5kQ29udGFpbmVyOwotICAgICAgICB3aGlsZSAoZGVwdGhEaWZmIDwgMCkgewotICAgICAgICAgICAgZW5kTm9kZSA9IGVuZE5vZGUuZ2V0UGFyZW50Tm9kZSgpOwotICAgICAgICAgICAgZGVwdGhEaWZmKys7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBhc2NlbmQgdGhlIGFuY2VzdG9yIGhpZXJhcmNoeSB1bnRpbCB3ZSBoYXZlIGEgY29tbW9uIHBhcmVudC4KLSAgICAgICAgZm9yKCBOb2RlIHNwID0gc3RhcnROb2RlLmdldFBhcmVudE5vZGUoKSwgZXAgPSBlbmROb2RlLmdldFBhcmVudE5vZGUoKTsKLSAgICAgICAgICAgICBzcCE9ZXA7Ci0gICAgICAgICAgICAgc3AgPSBzcC5nZXRQYXJlbnROb2RlKCksIGVwID0gZXAuZ2V0UGFyZW50Tm9kZSgpICkKLSAgICAgICAgewotICAgICAgICAgICAgc3RhcnROb2RlID0gc3A7Ci0gICAgICAgICAgICBlbmROb2RlID0gZXA7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHRyYXZlcnNlQ29tbW9uQW5jZXN0b3JzKCBzdGFydE5vZGUsIGVuZE5vZGUsIGhvdyApOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFZpc2l0cyB0aGUgbm9kZXMgc2VsZWN0ZWQgYnkgdGhpcyByYW5nZSB3aGVuIHdlIGtub3cKLSAgICAgKiBhLXByaW9yaSB0aGF0IHRoZSBzdGFydCBhbmQgZW5kIGNvbnRhaW5lcnMgYXJlIHRoZSBzYW1lLgotICAgICAqIFRoaXMgbWV0aG9kIGlzIGludm9rZWQgYnkgdGhlIGdlbmVyaWMgPGNvZGU+dHJhdmVyc2U8L2NvZGU+Ci0gICAgICogbWV0aG9kLgotICAgICAqCi0gICAgICogQHBhcmFtIGhvdyAgICBTcGVjaWZpZXMgd2hhdCB0eXBlIG9mIHRyYXZlcnNhbCBpcyBiZWluZwotICAgICAqICAgICAgICAgICAgICAgcmVxdWVzdGVkIChleHRyYWN0LCBjbG9uZSwgb3IgZGVsZXRlKS4KLSAgICAgKiAgICAgICAgICAgICAgIExlZ2FsIHZhbHVlcyBmb3IgdGhpcyBhcmd1bWVudCBhcmU6Ci0gICAgICoKLSAgICAgKiAgICAgICAgICAgICAgIDxvbD4KLSAgICAgKiAgICAgICAgICAgICAgIDxsaT48Y29kZT5FWFRSQUNUX0NPTlRFTlRTPC9jb2RlPiAtIHdpbGwgcHJvZHVjZQotICAgICAqICAgICAgICAgICAgICAgYSBkb2N1bWVudCBmcmFnbWVudCBjb250YWluaW5nIHRoZSByYW5nZSdzIGNvbnRlbnQuCi0gICAgICogICAgICAgICAgICAgICBQYXJ0aWFsbHkgc2VsZWN0ZWQgbm9kZXMgYXJlIGNvcGllZCwgYnV0IGZ1bGx5Ci0gICAgICogICAgICAgICAgICAgICBzZWxlY3RlZCBub2RlcyBhcmUgbW92ZWQuCi0gICAgICoKLSAgICAgKiAgICAgICAgICAgICAgIDxsaT48Y29kZT5DTE9ORV9DT05URU5UUzwvY29kZT4gLSB3aWxsIGxlYXZlIHRoZQotICAgICAqICAgICAgICAgICAgICAgY29udGV4dCB0cmVlIG9mIHRoZSByYW5nZSB1bmRpc3R1cmJlZCwgYnV0IHNpbGwKLSAgICAgKiAgICAgICAgICAgICAgIHByb2R1Y2VkIGNsb25lZCBjb250ZW50IGluIGEgZG9jdW1lbnQgZnJhZ21lbnQKLSAgICAgKgotICAgICAqICAgICAgICAgICAgICAgPGxpPjxjb2RlPkRFTEVURV9DT05URU5UUzwvY29kZT4gLSB3aWxsIGRlbGV0ZSBmcm9tCi0gICAgICogICAgICAgICAgICAgICB0aGUgY29udGV4dCB0cmVlIG9mIHRoZSByYW5nZSwgYWxsIGZ1bGx5IHNlbGVjdGVkCi0gICAgICogICAgICAgICAgICAgICBub2Rlcy4KLSAgICAgKiAgICAgICAgICAgICAgIDwvb2w+Ci0gICAgICoKLSAgICAgKiBAcmV0dXJuIFJldHVybnMgYSBkb2N1bWVudCBmcmFnbWVudCBjb250YWluaW5nIGFueQotICAgICAqICAgICAgICAgY29waWVkIG9yIGV4dHJhY3RlZCBub2Rlcy4gIElmIHRoZSA8Y29kZT5ob3c8L2NvZGU+Ci0gICAgICogICAgICAgICBwYXJhbWV0ZXIgd2FzIDxjb2RlPkRFTEVURV9DT05URU5UUzwvY29kZT4sIHRoZQotICAgICAqICAgICAgICAgcmV0dXJuIHZhbHVlIGlzIG51bGwuCi0gICAgICovCi0gICAgcHJpdmF0ZSBEb2N1bWVudEZyYWdtZW50IHRyYXZlcnNlU2FtZUNvbnRhaW5lciggaW50IGhvdyApCi0gICAgewotICAgICAgICBEb2N1bWVudEZyYWdtZW50IGZyYWcgPSBudWxsOwotICAgICAgICBpZiAoIGhvdyE9REVMRVRFX0NPTlRFTlRTKQotICAgICAgICAgICAgZnJhZyA9IGZEb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7Ci0KLSAgICAgICAgLy8gSWYgc2VsZWN0aW9uIGlzIGVtcHR5LCBqdXN0IHJldHVybiB0aGUgZnJhZ21lbnQKLSAgICAgICAgaWYgKCBmU3RhcnRPZmZzZXQ9PWZFbmRPZmZzZXQgKQotICAgICAgICAgICAgcmV0dXJuIGZyYWc7Ci0KLSAgICAgICAgLy8gVGV4dCBub2RlIG5lZWRzIHNwZWNpYWwgY2FzZSBoYW5kbGluZwotICAgICAgICBpZiAoIGZTdGFydENvbnRhaW5lci5nZXROb2RlVHlwZSgpPT1Ob2RlLlRFWFRfTk9ERSApCi0gICAgICAgIHsKLSAgICAgICAgICAgIC8vIGdldCB0aGUgc3Vic3RyaW5nCi0gICAgICAgICAgICBTdHJpbmcgcyA9IGZTdGFydENvbnRhaW5lci5nZXROb2RlVmFsdWUoKTsKLSAgICAgICAgICAgIFN0cmluZyBzdWIgPSBzLnN1YnN0cmluZyggZlN0YXJ0T2Zmc2V0LCBmRW5kT2Zmc2V0ICk7Ci0KLSAgICAgICAgICAgIC8vIHNldCB0aGUgb3JpZ2luYWwgdGV4dCBub2RlIHRvIGl0cyBuZXcgdmFsdWUKLSAgICAgICAgICAgIGlmICggaG93ICE9IENMT05FX0NPTlRFTlRTICkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAoKFRleHRJbXBsKWZTdGFydENvbnRhaW5lcikuZGVsZXRlRGF0YShmU3RhcnRPZmZzZXQsCi0gICAgICAgICAgICAgICAgICAgICBmRW5kT2Zmc2V0LWZTdGFydE9mZnNldCkgOwotICAgICAgICAgICAgICAgIC8vIE5vdGhpbmcgaXMgcGFydGlhbGx5IHNlbGVjdGVkLCBzbyBjb2xsYXBzZSB0byBzdGFydCBwb2ludAotICAgICAgICAgICAgICAgIGNvbGxhcHNlKCB0cnVlICk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoIGhvdz09REVMRVRFX0NPTlRFTlRTKQotICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICAgICAgZnJhZy5hcHBlbmRDaGlsZCggZkRvY3VtZW50LmNyZWF0ZVRleHROb2RlKHN1YikgKTsKLSAgICAgICAgICAgIHJldHVybiBmcmFnOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gQ29weSBub2RlcyBiZXR3ZWVuIHRoZSBzdGFydC9lbmQgb2Zmc2V0cy4KLSAgICAgICAgTm9kZSBuID0gZ2V0U2VsZWN0ZWROb2RlKCBmU3RhcnRDb250YWluZXIsIGZTdGFydE9mZnNldCApOwotICAgICAgICBpbnQgY250ID0gZkVuZE9mZnNldCAtIGZTdGFydE9mZnNldDsKLSAgICAgICAgd2hpbGUoIGNudCA+IDAgKQotICAgICAgICB7Ci0gICAgICAgICAgICBOb2RlIHNpYmxpbmcgPSBuLmdldE5leHRTaWJsaW5nKCk7Ci0gICAgICAgICAgICBOb2RlIHhmZXJOb2RlID0gdHJhdmVyc2VGdWxseVNlbGVjdGVkKCBuLCBob3cgKTsKLSAgICAgICAgICAgIGlmICggZnJhZyE9bnVsbCApCi0gICAgICAgICAgICAgICAgZnJhZy5hcHBlbmRDaGlsZCggeGZlck5vZGUgKTsKLSAgICAgICAgICAgIC0tY250OwotICAgICAgICAgICAgbiA9IHNpYmxpbmc7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBOb3RoaW5nIGlzIHBhcnRpYWxseSBzZWxlY3RlZCwgc28gY29sbGFwc2UgdG8gc3RhcnQgcG9pbnQKLSAgICAgICAgaWYgKCBob3cgIT0gQ0xPTkVfQ09OVEVOVFMgKQotICAgICAgICAgICAgY29sbGFwc2UoIHRydWUgKTsKLSAgICAgICAgcmV0dXJuIGZyYWc7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVmlzaXRzIHRoZSBub2RlcyBzZWxlY3RlZCBieSB0aGlzIHJhbmdlIHdoZW4gd2Uga25vdwotICAgICAqIGEtcHJpb3JpIHRoYXQgdGhlIHN0YXJ0IGFuZCBlbmQgY29udGFpbmVycyBhcmUgbm90IHRoZQotICAgICAqIHNhbWUsIGJ1dCB0aGUgc3RhcnQgY29udGFpbmVyIGlzIGFuIGFuY2VzdG9yIG9mIHRoZQotICAgICAqIGVuZCBjb250YWluZXIuIFRoaXMgbWV0aG9kIGlzIGludm9rZWQgYnkgdGhlIGdlbmVyaWMKLSAgICAgKiA8Y29kZT50cmF2ZXJzZTwvY29kZT4gbWV0aG9kLgotICAgICAqCi0gICAgICogQHBhcmFtIGVuZEFuY2VzdG9yCi0gICAgICogICAgICAgICAgICAgICBUaGUgYW5jZXN0b3Igb2YgdGhlIGVuZCBjb250YWluZXIgdGhhdCBpcyBhIGRpcmVjdCBjaGlsZAotICAgICAqICAgICAgICAgICAgICAgb2YgdGhlIHN0YXJ0IGNvbnRhaW5lci4KLSAgICAgKgotICAgICAqIEBwYXJhbSBob3cgICAgU3BlY2lmaWVzIHdoYXQgdHlwZSBvZiB0cmF2ZXJzYWwgaXMgYmVpbmcKLSAgICAgKiAgICAgICAgICAgICAgIHJlcXVlc3RlZCAoZXh0cmFjdCwgY2xvbmUsIG9yIGRlbGV0ZSkuCi0gICAgICogICAgICAgICAgICAgICBMZWdhbCB2YWx1ZXMgZm9yIHRoaXMgYXJndW1lbnQgYXJlOgotICAgICAqCi0gICAgICogICAgICAgICAgICAgICA8b2w+Ci0gICAgICogICAgICAgICAgICAgICA8bGk+PGNvZGU+RVhUUkFDVF9DT05URU5UUzwvY29kZT4gLSB3aWxsIHByb2R1Y2UKLSAgICAgKiAgICAgICAgICAgICAgIGEgZG9jdW1lbnQgZnJhZ21lbnQgY29udGFpbmluZyB0aGUgcmFuZ2UncyBjb250ZW50LgotICAgICAqICAgICAgICAgICAgICAgUGFydGlhbGx5IHNlbGVjdGVkIG5vZGVzIGFyZSBjb3BpZWQsIGJ1dCBmdWxseQotICAgICAqICAgICAgICAgICAgICAgc2VsZWN0ZWQgbm9kZXMgYXJlIG1vdmVkLgotICAgICAqCi0gICAgICogICAgICAgICAgICAgICA8bGk+PGNvZGU+Q0xPTkVfQ09OVEVOVFM8L2NvZGU+IC0gd2lsbCBsZWF2ZSB0aGUKLSAgICAgKiAgICAgICAgICAgICAgIGNvbnRleHQgdHJlZSBvZiB0aGUgcmFuZ2UgdW5kaXN0dXJiZWQsIGJ1dCBzaWxsCi0gICAgICogICAgICAgICAgICAgICBwcm9kdWNlZCBjbG9uZWQgY29udGVudCBpbiBhIGRvY3VtZW50IGZyYWdtZW50Ci0gICAgICoKLSAgICAgKiAgICAgICAgICAgICAgIDxsaT48Y29kZT5ERUxFVEVfQ09OVEVOVFM8L2NvZGU+IC0gd2lsbCBkZWxldGUgZnJvbQotICAgICAqICAgICAgICAgICAgICAgdGhlIGNvbnRleHQgdHJlZSBvZiB0aGUgcmFuZ2UsIGFsbCBmdWxseSBzZWxlY3RlZAotICAgICAqICAgICAgICAgICAgICAgbm9kZXMuCi0gICAgICogICAgICAgICAgICAgICA8L29sPgotICAgICAqCi0gICAgICogQHJldHVybiBSZXR1cm5zIGEgZG9jdW1lbnQgZnJhZ21lbnQgY29udGFpbmluZyBhbnkKLSAgICAgKiAgICAgICAgIGNvcGllZCBvciBleHRyYWN0ZWQgbm9kZXMuICBJZiB0aGUgPGNvZGU+aG93PC9jb2RlPgotICAgICAqICAgICAgICAgcGFyYW1ldGVyIHdhcyA8Y29kZT5ERUxFVEVfQ09OVEVOVFM8L2NvZGU+LCB0aGUKLSAgICAgKiAgICAgICAgIHJldHVybiB2YWx1ZSBpcyBudWxsLgotICAgICAqLwotICAgIHByaXZhdGUgRG9jdW1lbnRGcmFnbWVudAotICAgICAgICB0cmF2ZXJzZUNvbW1vblN0YXJ0Q29udGFpbmVyKCBOb2RlIGVuZEFuY2VzdG9yLCBpbnQgaG93ICkKLSAgICB7Ci0gICAgICAgIERvY3VtZW50RnJhZ21lbnQgZnJhZyA9IG51bGw7Ci0gICAgICAgIGlmICggaG93IT1ERUxFVEVfQ09OVEVOVFMpCi0gICAgICAgICAgICBmcmFnID0gZkRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTsKLSAgICAgICAgTm9kZSBuID0gdHJhdmVyc2VSaWdodEJvdW5kYXJ5KCBlbmRBbmNlc3RvciwgaG93ICk7Ci0gICAgICAgIGlmICggZnJhZyE9bnVsbCApCi0gICAgICAgICAgICBmcmFnLmFwcGVuZENoaWxkKCBuICk7Ci0KLSAgICAgICAgaW50IGVuZElkeCA9IGluZGV4T2YoIGVuZEFuY2VzdG9yLCBmU3RhcnRDb250YWluZXIgKTsKLSAgICAgICAgaW50IGNudCA9IGVuZElkeCAtIGZTdGFydE9mZnNldDsKLSAgICAgICAgaWYgKCBjbnQgPD0wICkKLSAgICAgICAgewotICAgICAgICAgICAgLy8gQ29sbGFwc2UgdG8ganVzdCBiZWZvcmUgdGhlIGVuZEFuY2VzdG9yLCB3aGljaAotICAgICAgICAgICAgLy8gaXMgcGFydGlhbGx5IHNlbGVjdGVkLgotICAgICAgICAgICAgaWYgKCBob3cgIT0gQ0xPTkVfQ09OVEVOVFMgKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIHNldEVuZEJlZm9yZSggZW5kQW5jZXN0b3IgKTsKLSAgICAgICAgICAgICAgICBjb2xsYXBzZSggZmFsc2UgKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiBmcmFnOwotICAgICAgICB9Ci0KLSAgICAgICAgbiA9IGVuZEFuY2VzdG9yLmdldFByZXZpb3VzU2libGluZygpOwotICAgICAgICB3aGlsZSggY250ID4gMCApCi0gICAgICAgIHsKLSAgICAgICAgICAgIE5vZGUgc2libGluZyA9IG4uZ2V0UHJldmlvdXNTaWJsaW5nKCk7Ci0gICAgICAgICAgICBOb2RlIHhmZXJOb2RlID0gdHJhdmVyc2VGdWxseVNlbGVjdGVkKCBuLCBob3cgKTsKLSAgICAgICAgICAgIGlmICggZnJhZyE9bnVsbCApCi0gICAgICAgICAgICAgICAgZnJhZy5pbnNlcnRCZWZvcmUoIHhmZXJOb2RlLCBmcmFnLmdldEZpcnN0Q2hpbGQoKSApOwotICAgICAgICAgICAgLS1jbnQ7Ci0gICAgICAgICAgICBuID0gc2libGluZzsKLSAgICAgICAgfQotICAgICAgICAvLyBDb2xsYXBzZSB0byBqdXN0IGJlZm9yZSB0aGUgZW5kQW5jZXN0b3IsIHdoaWNoCi0gICAgICAgIC8vIGlzIHBhcnRpYWxseSBzZWxlY3RlZC4KLSAgICAgICAgaWYgKCBob3cgIT0gQ0xPTkVfQ09OVEVOVFMgKQotICAgICAgICB7Ci0gICAgICAgICAgICBzZXRFbmRCZWZvcmUoIGVuZEFuY2VzdG9yICk7Ci0gICAgICAgICAgICBjb2xsYXBzZSggZmFsc2UgKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZnJhZzsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBWaXNpdHMgdGhlIG5vZGVzIHNlbGVjdGVkIGJ5IHRoaXMgcmFuZ2Ugd2hlbiB3ZSBrbm93Ci0gICAgICogYS1wcmlvcmkgdGhhdCB0aGUgc3RhcnQgYW5kIGVuZCBjb250YWluZXJzIGFyZSBub3QgdGhlCi0gICAgICogc2FtZSwgYnV0IHRoZSBlbmQgY29udGFpbmVyIGlzIGFuIGFuY2VzdG9yIG9mIHRoZQotICAgICAqIHN0YXJ0IGNvbnRhaW5lci4gVGhpcyBtZXRob2QgaXMgaW52b2tlZCBieSB0aGUgZ2VuZXJpYwotICAgICAqIDxjb2RlPnRyYXZlcnNlPC9jb2RlPiBtZXRob2QuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc3RhcnRBbmNlc3RvcgotICAgICAqICAgICAgICAgICAgICAgVGhlIGFuY2VzdG9yIG9mIHRoZSBzdGFydCBjb250YWluZXIgdGhhdCBpcyBhIGRpcmVjdAotICAgICAqICAgICAgICAgICAgICAgY2hpbGQgb2YgdGhlIGVuZCBjb250YWluZXIuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaG93ICAgIFNwZWNpZmllcyB3aGF0IHR5cGUgb2YgdHJhdmVyc2FsIGlzIGJlaW5nCi0gICAgICogICAgICAgICAgICAgICByZXF1ZXN0ZWQgKGV4dHJhY3QsIGNsb25lLCBvciBkZWxldGUpLgotICAgICAqICAgICAgICAgICAgICAgTGVnYWwgdmFsdWVzIGZvciB0aGlzIGFyZ3VtZW50IGFyZToKLSAgICAgKgotICAgICAqICAgICAgICAgICAgICAgPG9sPgotICAgICAqICAgICAgICAgICAgICAgPGxpPjxjb2RlPkVYVFJBQ1RfQ09OVEVOVFM8L2NvZGU+IC0gd2lsbCBwcm9kdWNlCi0gICAgICogICAgICAgICAgICAgICBhIGRvY3VtZW50IGZyYWdtZW50IGNvbnRhaW5pbmcgdGhlIHJhbmdlJ3MgY29udGVudC4KLSAgICAgKiAgICAgICAgICAgICAgIFBhcnRpYWxseSBzZWxlY3RlZCBub2RlcyBhcmUgY29waWVkLCBidXQgZnVsbHkKLSAgICAgKiAgICAgICAgICAgICAgIHNlbGVjdGVkIG5vZGVzIGFyZSBtb3ZlZC4KLSAgICAgKgotICAgICAqICAgICAgICAgICAgICAgPGxpPjxjb2RlPkNMT05FX0NPTlRFTlRTPC9jb2RlPiAtIHdpbGwgbGVhdmUgdGhlCi0gICAgICogICAgICAgICAgICAgICBjb250ZXh0IHRyZWUgb2YgdGhlIHJhbmdlIHVuZGlzdHVyYmVkLCBidXQgc2lsbAotICAgICAqICAgICAgICAgICAgICAgcHJvZHVjZWQgY2xvbmVkIGNvbnRlbnQgaW4gYSBkb2N1bWVudCBmcmFnbWVudAotICAgICAqCi0gICAgICogICAgICAgICAgICAgICA8bGk+PGNvZGU+REVMRVRFX0NPTlRFTlRTPC9jb2RlPiAtIHdpbGwgZGVsZXRlIGZyb20KLSAgICAgKiAgICAgICAgICAgICAgIHRoZSBjb250ZXh0IHRyZWUgb2YgdGhlIHJhbmdlLCBhbGwgZnVsbHkgc2VsZWN0ZWQKLSAgICAgKiAgICAgICAgICAgICAgIG5vZGVzLgotICAgICAqICAgICAgICAgICAgICAgPC9vbD4KLSAgICAgKgotICAgICAqIEByZXR1cm4gUmV0dXJucyBhIGRvY3VtZW50IGZyYWdtZW50IGNvbnRhaW5pbmcgYW55Ci0gICAgICogICAgICAgICBjb3BpZWQgb3IgZXh0cmFjdGVkIG5vZGVzLiAgSWYgdGhlIDxjb2RlPmhvdzwvY29kZT4KLSAgICAgKiAgICAgICAgIHBhcmFtZXRlciB3YXMgPGNvZGU+REVMRVRFX0NPTlRFTlRTPC9jb2RlPiwgdGhlCi0gICAgICogICAgICAgICByZXR1cm4gdmFsdWUgaXMgbnVsbC4KLSAgICAgKi8KLSAgICBwcml2YXRlIERvY3VtZW50RnJhZ21lbnQKLSAgICAgICAgdHJhdmVyc2VDb21tb25FbmRDb250YWluZXIoIE5vZGUgc3RhcnRBbmNlc3RvciwgaW50IGhvdyApCi0gICAgewotICAgICAgICBEb2N1bWVudEZyYWdtZW50IGZyYWcgPSBudWxsOwotICAgICAgICBpZiAoIGhvdyE9REVMRVRFX0NPTlRFTlRTKQotICAgICAgICAgICAgZnJhZyA9IGZEb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7Ci0gICAgICAgIE5vZGUgbiA9IHRyYXZlcnNlTGVmdEJvdW5kYXJ5KCBzdGFydEFuY2VzdG9yLCBob3cgKTsKLSAgICAgICAgaWYgKCBmcmFnIT1udWxsICkKLSAgICAgICAgICAgIGZyYWcuYXBwZW5kQ2hpbGQoIG4gKTsKLSAgICAgICAgaW50IHN0YXJ0SWR4ID0gaW5kZXhPZiggc3RhcnRBbmNlc3RvciwgZkVuZENvbnRhaW5lciApOwotICAgICAgICArK3N0YXJ0SWR4OyAgLy8gQmVjYXVzZSB3ZSBhbHJlYWR5IHRyYXZlcnNlZCBpdC4uLi4KLQotICAgICAgICBpbnQgY250ID0gZkVuZE9mZnNldCAtIHN0YXJ0SWR4OwotICAgICAgICBuID0gc3RhcnRBbmNlc3Rvci5nZXROZXh0U2libGluZygpOwotICAgICAgICB3aGlsZSggY250ID4gMCApCi0gICAgICAgIHsKLSAgICAgICAgICAgIE5vZGUgc2libGluZyA9IG4uZ2V0TmV4dFNpYmxpbmcoKTsKLSAgICAgICAgICAgIE5vZGUgeGZlck5vZGUgPSB0cmF2ZXJzZUZ1bGx5U2VsZWN0ZWQoIG4sIGhvdyApOwotICAgICAgICAgICAgaWYgKCBmcmFnIT1udWxsICkKLSAgICAgICAgICAgICAgICBmcmFnLmFwcGVuZENoaWxkKCB4ZmVyTm9kZSApOwotICAgICAgICAgICAgLS1jbnQ7Ci0gICAgICAgICAgICBuID0gc2libGluZzsKLSAgICAgICAgfQotCi0gICAgICAgIGlmICggaG93ICE9IENMT05FX0NPTlRFTlRTICkKLSAgICAgICAgewotICAgICAgICAgICAgc2V0U3RhcnRBZnRlciggc3RhcnRBbmNlc3RvciApOwotICAgICAgICAgICAgY29sbGFwc2UoIHRydWUgKTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBmcmFnOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFZpc2l0cyB0aGUgbm9kZXMgc2VsZWN0ZWQgYnkgdGhpcyByYW5nZSB3aGVuIHdlIGtub3cKLSAgICAgKiBhLXByaW9yaSB0aGF0IHRoZSBzdGFydCBhbmQgZW5kIGNvbnRhaW5lcnMgYXJlIG5vdAotICAgICAqIHRoZSBzYW1lLCBhbmQgd2UgYWxzbyBrbm93IHRoYXQgbmVpdGhlciB0aGUgc3RhcnQKLSAgICAgKiBub3IgZW5kIGNvbnRhaW5lciBpcyBhbiBhbmNlc3RvciBvZiB0aGUgb3RoZXIuCi0gICAgICogVGhpcyBtZXRob2QgaXMgaW52b2tlZCBieQotICAgICAqIHRoZSBnZW5lcmljIDxjb2RlPnRyYXZlcnNlPC9jb2RlPiBtZXRob2QuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc3RhcnRBbmNlc3RvcgotICAgICAqICAgICAgICAgICAgICAgR2l2ZW4gYSBjb21tb24gYW5jZXN0b3Igb2YgdGhlIHN0YXJ0IGFuZCBlbmQgY29udGFpbmVycywKLSAgICAgKiAgICAgICAgICAgICAgIHRoaXMgcGFyYW1ldGVyIGlzIHRoZSBhbmNlc3RvciAob3Igc2VsZikgb2YgdGhlIHN0YXJ0Ci0gICAgICogICAgICAgICAgICAgICBjb250YWluZXIgdGhhdCBpcyBhIGRpcmVjdCBjaGlsZCBvZiB0aGUgY29tbW9uIGFuY2VzdG9yLgotICAgICAqCi0gICAgICogQHBhcmFtIGVuZEFuY2VzdG9yCi0gICAgICogICAgICAgICAgICAgICBHaXZlbiBhIGNvbW1vbiBhbmNlc3RvciBvZiB0aGUgc3RhcnQgYW5kIGVuZCBjb250YWluZXJzLAotICAgICAqICAgICAgICAgICAgICAgdGhpcyBwYXJhbWV0ZXIgaXMgdGhlIGFuY2VzdG9yIChvciBzZWxmKSBvZiB0aGUgZW5kCi0gICAgICogICAgICAgICAgICAgICBjb250YWluZXIgdGhhdCBpcyBhIGRpcmVjdCBjaGlsZCBvZiB0aGUgY29tbW9uIGFuY2VzdG9yLgotICAgICAqCi0gICAgICogQHBhcmFtIGhvdyAgICBTcGVjaWZpZXMgd2hhdCB0eXBlIG9mIHRyYXZlcnNhbCBpcyBiZWluZwotICAgICAqICAgICAgICAgICAgICAgcmVxdWVzdGVkIChleHRyYWN0LCBjbG9uZSwgb3IgZGVsZXRlKS4KLSAgICAgKiAgICAgICAgICAgICAgIExlZ2FsIHZhbHVlcyBmb3IgdGhpcyBhcmd1bWVudCBhcmU6Ci0gICAgICoKLSAgICAgKiAgICAgICAgICAgICAgIDxvbD4KLSAgICAgKiAgICAgICAgICAgICAgIDxsaT48Y29kZT5FWFRSQUNUX0NPTlRFTlRTPC9jb2RlPiAtIHdpbGwgcHJvZHVjZQotICAgICAqICAgICAgICAgICAgICAgYSBkb2N1bWVudCBmcmFnbWVudCBjb250YWluaW5nIHRoZSByYW5nZSdzIGNvbnRlbnQuCi0gICAgICogICAgICAgICAgICAgICBQYXJ0aWFsbHkgc2VsZWN0ZWQgbm9kZXMgYXJlIGNvcGllZCwgYnV0IGZ1bGx5Ci0gICAgICogICAgICAgICAgICAgICBzZWxlY3RlZCBub2RlcyBhcmUgbW92ZWQuCi0gICAgICoKLSAgICAgKiAgICAgICAgICAgICAgIDxsaT48Y29kZT5DTE9ORV9DT05URU5UUzwvY29kZT4gLSB3aWxsIGxlYXZlIHRoZQotICAgICAqICAgICAgICAgICAgICAgY29udGV4dCB0cmVlIG9mIHRoZSByYW5nZSB1bmRpc3R1cmJlZCwgYnV0IHNpbGwKLSAgICAgKiAgICAgICAgICAgICAgIHByb2R1Y2VkIGNsb25lZCBjb250ZW50IGluIGEgZG9jdW1lbnQgZnJhZ21lbnQKLSAgICAgKgotICAgICAqICAgICAgICAgICAgICAgPGxpPjxjb2RlPkRFTEVURV9DT05URU5UUzwvY29kZT4gLSB3aWxsIGRlbGV0ZSBmcm9tCi0gICAgICogICAgICAgICAgICAgICB0aGUgY29udGV4dCB0cmVlIG9mIHRoZSByYW5nZSwgYWxsIGZ1bGx5IHNlbGVjdGVkCi0gICAgICogICAgICAgICAgICAgICBub2Rlcy4KLSAgICAgKiAgICAgICAgICAgICAgIDwvb2w+Ci0gICAgICoKLSAgICAgKiBAcmV0dXJuIFJldHVybnMgYSBkb2N1bWVudCBmcmFnbWVudCBjb250YWluaW5nIGFueQotICAgICAqICAgICAgICAgY29waWVkIG9yIGV4dHJhY3RlZCBub2Rlcy4gIElmIHRoZSA8Y29kZT5ob3c8L2NvZGU+Ci0gICAgICogICAgICAgICBwYXJhbWV0ZXIgd2FzIDxjb2RlPkRFTEVURV9DT05URU5UUzwvY29kZT4sIHRoZQotICAgICAqICAgICAgICAgcmV0dXJuIHZhbHVlIGlzIG51bGwuCi0gICAgICovCi0gICAgcHJpdmF0ZSBEb2N1bWVudEZyYWdtZW50Ci0gICAgICAgIHRyYXZlcnNlQ29tbW9uQW5jZXN0b3JzKCBOb2RlIHN0YXJ0QW5jZXN0b3IsIE5vZGUgZW5kQW5jZXN0b3IsIGludCBob3cgKQotICAgIHsKLSAgICAgICAgRG9jdW1lbnRGcmFnbWVudCBmcmFnID0gbnVsbDsKLSAgICAgICAgaWYgKCBob3chPURFTEVURV9DT05URU5UUykKLSAgICAgICAgICAgIGZyYWcgPSBmRG9jdW1lbnQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpOwotCi0gICAgICAgIE5vZGUgbiA9IHRyYXZlcnNlTGVmdEJvdW5kYXJ5KCBzdGFydEFuY2VzdG9yLCBob3cgKTsKLSAgICAgICAgaWYgKCBmcmFnIT1udWxsICkKLSAgICAgICAgICAgIGZyYWcuYXBwZW5kQ2hpbGQoIG4gKTsKLQotICAgICAgICBOb2RlIGNvbW1vblBhcmVudCA9IHN0YXJ0QW5jZXN0b3IuZ2V0UGFyZW50Tm9kZSgpOwotICAgICAgICBpbnQgc3RhcnRPZmZzZXQgPSBpbmRleE9mKCBzdGFydEFuY2VzdG9yLCBjb21tb25QYXJlbnQgKTsKLSAgICAgICAgaW50IGVuZE9mZnNldCA9IGluZGV4T2YoIGVuZEFuY2VzdG9yLCBjb21tb25QYXJlbnQgKTsKLSAgICAgICAgKytzdGFydE9mZnNldDsKLQotICAgICAgICBpbnQgY250ID0gZW5kT2Zmc2V0IC0gc3RhcnRPZmZzZXQ7Ci0gICAgICAgIE5vZGUgc2libGluZyA9IHN0YXJ0QW5jZXN0b3IuZ2V0TmV4dFNpYmxpbmcoKTsKLQotICAgICAgICB3aGlsZSggY250ID4gMCApCi0gICAgICAgIHsKLSAgICAgICAgICAgIE5vZGUgbmV4dFNpYmxpbmcgPSBzaWJsaW5nLmdldE5leHRTaWJsaW5nKCk7Ci0gICAgICAgICAgICBuID0gdHJhdmVyc2VGdWxseVNlbGVjdGVkKCBzaWJsaW5nLCBob3cgKTsKLSAgICAgICAgICAgIGlmICggZnJhZyE9bnVsbCApCi0gICAgICAgICAgICAgICAgZnJhZy5hcHBlbmRDaGlsZCggbiApOwotICAgICAgICAgICAgc2libGluZyA9IG5leHRTaWJsaW5nOwotICAgICAgICAgICAgLS1jbnQ7Ci0gICAgICAgIH0KLQotICAgICAgICBuID0gdHJhdmVyc2VSaWdodEJvdW5kYXJ5KCBlbmRBbmNlc3RvciwgaG93ICk7Ci0gICAgICAgIGlmICggZnJhZyE9bnVsbCApCi0gICAgICAgICAgICBmcmFnLmFwcGVuZENoaWxkKCBuICk7Ci0KLSAgICAgICAgaWYgKCBob3cgIT0gQ0xPTkVfQ09OVEVOVFMgKQotICAgICAgICB7Ci0gICAgICAgICAgICBzZXRTdGFydEFmdGVyKCBzdGFydEFuY2VzdG9yICk7Ci0gICAgICAgICAgICBjb2xsYXBzZSggdHJ1ZSApOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmcmFnOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYXZlcnNlcyB0aGUgInJpZ2h0IGJvdW5kYXJ5IiBvZiB0aGlzIHJhbmdlIGFuZAotICAgICAqIG9wZXJhdGVzIG9uIGVhY2ggImJvdW5kYXJ5IG5vZGUiIGFjY29yZGluZyB0byB0aGUKLSAgICAgKiA8Y29kZT5ob3c8L2NvZGU+IHBhcmFtZXRlci4gIEl0IGlzIGEtcHJpb3JpIGFzc3VtZWQKLSAgICAgKiBieSB0aGlzIG1ldGhvZCB0aGF0IHRoZSByaWdodCBib3VuZGFyeSBkb2VzCi0gICAgICogbm90IGNvbnRhaW4gdGhlIHJhbmdlJ3Mgc3RhcnQgY29udGFpbmVyLgotICAgICAqIDxwPgotICAgICAqIEEgInJpZ2h0IGJvdW5kYXJ5IiBpcyBiZXN0IHZpc3VhbGl6ZWQgYnkgdGhpbmtpbmcKLSAgICAgKiBvZiBhIHNhbXBsZSB0cmVlOjxwcmU+Ci0gICAgICogICAgICAgICAgICAgICAgIEEKLSAgICAgKiAgICAgICAgICAgICAgICAvfFwKLSAgICAgKiAgICAgICAgICAgICAgIC8gfCBcCi0gICAgICogICAgICAgICAgICAgIC8gIHwgIFwKLSAgICAgKiAgICAgICAgICAgICBCICAgQyAgIEQKLSAgICAgKiAgICAgICAgICAgIC98XCAgICAgL3xcCi0gICAgICogICAgICAgICAgIEUgRiBHICAgSCBJIEoKLSAgICAgKiA8L3ByZT4KLSAgICAgKiBJbWFnaW5lIGZpcnN0IGEgcmFuZ2UgdGhhdCBiZWdpbnMgYmV0d2VlbiB0aGUKLSAgICAgKiAiRSIgYW5kICJGIiBub2RlcyBhbmQgZW5kcyBiZXR3ZWVuIHRoZQotICAgICAqICJJIiBhbmQgIkoiIG5vZGVzLiAgVGhlIHN0YXJ0IGNvbnRhaW5lciBpcwotICAgICAqICJCIiBhbmQgdGhlIGVuZCBjb250YWluZXIgaXMgIkQiLiAgR2l2ZW4gdGhpcyBzZXR1cCwKLSAgICAgKiB0aGUgZm9sbG93aW5nIGFwcGxpZXM6Ci0gICAgICogPHA+Ci0gICAgICogUGFydGlhbGx5IFNlbGVjdGVkIE5vZGVzOiBCLCBEPGJyPgotICAgICAqIEZ1bGx5IFNlbGVjdGVkIE5vZGVzOiBGLCBHLCBDLCBILCBJCi0gICAgICogPHA+Ci0gICAgICogVGhlICJyaWdodCBib3VuZGFyeSIgaXMgdGhlIGhpZ2hlc3Qgc3VidHJlZSBub2RlCi0gICAgICogdGhhdCBjb250YWlucyB0aGUgZW5kaW5nIGNvbnRhaW5lci4gIFRoZSByb290IG9mCi0gICAgICogdGhpcyBzdWJ0cmVlIGlzIGFsd2F5cyBwYXJ0aWFsbHkgc2VsZWN0ZWQuCi0gICAgICogPHA+Ci0gICAgICogSW4gdGhpcyBleGFtcGxlLCB0aGUgbm9kZXMgdGhhdCBhcmUgdHJhdmVyc2VkCi0gICAgICogYXMgInJpZ2h0IGJvdW5kYXJ5IiBub2RlcyBhcmU6IEgsIEksIGFuZCBELgotICAgICAqCi0gICAgICogQHBhcmFtIHJvb3QgICBUaGUgbm9kZSB0aGF0IGlzIHRoZSByb290IG9mIHRoZSAicmlnaHQgYm91bmRhcnkiIHN1YnRyZWUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaG93ICAgIFNwZWNpZmllcyB3aGF0IHR5cGUgb2YgdHJhdmVyc2FsIGlzIGJlaW5nCi0gICAgICogICAgICAgICAgICAgICByZXF1ZXN0ZWQgKGV4dHJhY3QsIGNsb25lLCBvciBkZWxldGUpLgotICAgICAqICAgICAgICAgICAgICAgTGVnYWwgdmFsdWVzIGZvciB0aGlzIGFyZ3VtZW50IGFyZToKLSAgICAgKgotICAgICAqICAgICAgICAgICAgICAgPG9sPgotICAgICAqICAgICAgICAgICAgICAgPGxpPjxjb2RlPkVYVFJBQ1RfQ09OVEVOVFM8L2NvZGU+IC0gd2lsbCBwcm9kdWNlCi0gICAgICogICAgICAgICAgICAgICBhIG5vZGUgY29udGFpbmluZyB0aGUgYm91bmRhcmllcyBjb250ZW50LgotICAgICAqICAgICAgICAgICAgICAgUGFydGlhbGx5IHNlbGVjdGVkIG5vZGVzIGFyZSBjb3BpZWQsIGJ1dCBmdWxseQotICAgICAqICAgICAgICAgICAgICAgc2VsZWN0ZWQgbm9kZXMgYXJlIG1vdmVkLgotICAgICAqCi0gICAgICogICAgICAgICAgICAgICA8bGk+PGNvZGU+Q0xPTkVfQ09OVEVOVFM8L2NvZGU+IC0gd2lsbCBsZWF2ZSB0aGUKLSAgICAgKiAgICAgICAgICAgICAgIGNvbnRleHQgdHJlZSBvZiB0aGUgcmFuZ2UgdW5kaXN0dXJiZWQsIGJ1dCB3aWxsCi0gICAgICogICAgICAgICAgICAgICBwcm9kdWNlZCBjbG9uZWQgY29udGVudC4KLSAgICAgKgotICAgICAqICAgICAgICAgICAgICAgPGxpPjxjb2RlPkRFTEVURV9DT05URU5UUzwvY29kZT4gLSB3aWxsIGRlbGV0ZSBmcm9tCi0gICAgICogICAgICAgICAgICAgICB0aGUgY29udGV4dCB0cmVlIG9mIHRoZSByYW5nZSwgYWxsIGZ1bGx5IHNlbGVjdGVkCi0gICAgICogICAgICAgICAgICAgICBub2RlcyB3aXRoaW4gdGhlIGJvdW5kYXJ5LgotICAgICAqICAgICAgICAgICAgICAgPC9vbD4KLSAgICAgKgotICAgICAqIEByZXR1cm4gUmV0dXJucyBhIG5vZGUgdGhhdCBpcyB0aGUgcmVzdWx0IG9mIHZpc2l0aW5nIG5vZGVzLgotICAgICAqICAgICAgICAgSWYgdGhlIHRyYXZlcnNhbCBvcGVyYXRpb24gaXMKLSAgICAgKiAgICAgICAgIDxjb2RlPkRFTEVURV9DT05URU5UUzwvY29kZT4gdGhlIHJldHVybiB2YWx1ZSBpcyBudWxsLgotICAgICAqLwotICAgIHByaXZhdGUgTm9kZSB0cmF2ZXJzZVJpZ2h0Qm91bmRhcnkoIE5vZGUgcm9vdCwgaW50IGhvdyApCi0gICAgewotICAgICAgICBOb2RlIG5leHQgPSBnZXRTZWxlY3RlZE5vZGUoIGZFbmRDb250YWluZXIsIGZFbmRPZmZzZXQtMSApOwotICAgICAgICBib29sZWFuIGlzRnVsbHlTZWxlY3RlZCA9ICggbmV4dCE9ZkVuZENvbnRhaW5lciApOwotCi0gICAgICAgIGlmICggbmV4dD09cm9vdCApCi0gICAgICAgICAgICByZXR1cm4gdHJhdmVyc2VOb2RlKCBuZXh0LCBpc0Z1bGx5U2VsZWN0ZWQsIGZhbHNlLCBob3cgKTsKLQotICAgICAgICBOb2RlIHBhcmVudCA9IG5leHQuZ2V0UGFyZW50Tm9kZSgpOwotICAgICAgICBOb2RlIGNsb25lZFBhcmVudCA9IHRyYXZlcnNlTm9kZSggcGFyZW50LCBmYWxzZSwgZmFsc2UsIGhvdyApOwotCi0gICAgICAgIHdoaWxlKCBwYXJlbnQhPW51bGwgKQotICAgICAgICB7Ci0gICAgICAgICAgICB3aGlsZSggbmV4dCE9bnVsbCApCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgTm9kZSBwcmV2U2libGluZyA9IG5leHQuZ2V0UHJldmlvdXNTaWJsaW5nKCk7Ci0gICAgICAgICAgICAgICAgTm9kZSBjbG9uZWRDaGlsZCA9Ci0gICAgICAgICAgICAgICAgICAgIHRyYXZlcnNlTm9kZSggbmV4dCwgaXNGdWxseVNlbGVjdGVkLCBmYWxzZSwgaG93ICk7Ci0gICAgICAgICAgICAgICAgaWYgKCBob3chPURFTEVURV9DT05URU5UUyApCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICBjbG9uZWRQYXJlbnQuaW5zZXJ0QmVmb3JlKAotICAgICAgICAgICAgICAgICAgICAgICAgY2xvbmVkQ2hpbGQsCi0gICAgICAgICAgICAgICAgICAgICAgICBjbG9uZWRQYXJlbnQuZ2V0Rmlyc3RDaGlsZCgpCi0gICAgICAgICAgICAgICAgICAgICk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGlzRnVsbHlTZWxlY3RlZCA9IHRydWU7Ci0gICAgICAgICAgICAgICAgbmV4dCA9IHByZXZTaWJsaW5nOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKCBwYXJlbnQ9PXJvb3QgKQotICAgICAgICAgICAgICAgIHJldHVybiBjbG9uZWRQYXJlbnQ7Ci0KLSAgICAgICAgICAgIG5leHQgPSBwYXJlbnQuZ2V0UHJldmlvdXNTaWJsaW5nKCk7Ci0gICAgICAgICAgICBwYXJlbnQgPSBwYXJlbnQuZ2V0UGFyZW50Tm9kZSgpOwotICAgICAgICAgICAgTm9kZSBjbG9uZWRHcmFuZFBhcmVudCA9IHRyYXZlcnNlTm9kZSggcGFyZW50LCBmYWxzZSwgZmFsc2UsIGhvdyApOwotICAgICAgICAgICAgaWYgKCBob3chPURFTEVURV9DT05URU5UUyApCi0gICAgICAgICAgICAgICAgY2xvbmVkR3JhbmRQYXJlbnQuYXBwZW5kQ2hpbGQoIGNsb25lZFBhcmVudCApOwotICAgICAgICAgICAgY2xvbmVkUGFyZW50ID0gY2xvbmVkR3JhbmRQYXJlbnQ7Ci0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIHNob3VsZCBuZXZlciBvY2N1cgotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmF2ZXJzZXMgdGhlICJsZWZ0IGJvdW5kYXJ5IiBvZiB0aGlzIHJhbmdlIGFuZAotICAgICAqIG9wZXJhdGVzIG9uIGVhY2ggImJvdW5kYXJ5IG5vZGUiIGFjY29yZGluZyB0byB0aGUKLSAgICAgKiA8Y29kZT5ob3c8L2NvZGU+IHBhcmFtZXRlci4gIEl0IGlzIGEtcHJpb3JpIGFzc3VtZWQKLSAgICAgKiBieSB0aGlzIG1ldGhvZCB0aGF0IHRoZSBsZWZ0IGJvdW5kYXJ5IGRvZXMKLSAgICAgKiBub3QgY29udGFpbiB0aGUgcmFuZ2UncyBlbmQgY29udGFpbmVyLgotICAgICAqIDxwPgotICAgICAqIEEgImxlZnQgYm91bmRhcnkiIGlzIGJlc3QgdmlzdWFsaXplZCBieSB0aGlua2luZwotICAgICAqIG9mIGEgc2FtcGxlIHRyZWU6PHByZT4KLSAgICAgKgotICAgICAqICAgICAgICAgICAgICAgICBBCi0gICAgICogICAgICAgICAgICAgICAgL3xcCi0gICAgICogICAgICAgICAgICAgICAvIHwgXAotICAgICAqICAgICAgICAgICAgICAvICB8ICBcCi0gICAgICogICAgICAgICAgICAgQiAgIEMgICBECi0gICAgICogICAgICAgICAgICAvfFwgICAgIC98XAotICAgICAqICAgICAgICAgICBFIEYgRyAgIEggSSBKCi0gICAgICogPC9wcmU+Ci0gICAgICogSW1hZ2luZSBmaXJzdCBhIHJhbmdlIHRoYXQgYmVnaW5zIGJldHdlZW4gdGhlCi0gICAgICogIkUiIGFuZCAiRiIgbm9kZXMgYW5kIGVuZHMgYmV0d2VlbiB0aGUKLSAgICAgKiAiSSIgYW5kICJKIiBub2Rlcy4gIFRoZSBzdGFydCBjb250YWluZXIgaXMKLSAgICAgKiAiQiIgYW5kIHRoZSBlbmQgY29udGFpbmVyIGlzICJEIi4gIEdpdmVuIHRoaXMgc2V0dXAsCi0gICAgICogdGhlIGZvbGxvd2luZyBhcHBsaWVzOgotICAgICAqIDxwPgotICAgICAqIFBhcnRpYWxseSBTZWxlY3RlZCBOb2RlczogQiwgRDxicj4KLSAgICAgKiBGdWxseSBTZWxlY3RlZCBOb2RlczogRiwgRywgQywgSCwgSQotICAgICAqIDxwPgotICAgICAqIFRoZSAibGVmdCBib3VuZGFyeSIgaXMgdGhlIGhpZ2hlc3Qgc3VidHJlZSBub2RlCi0gICAgICogdGhhdCBjb250YWlucyB0aGUgc3RhcnRpbmcgY29udGFpbmVyLiAgVGhlIHJvb3Qgb2YKLSAgICAgKiB0aGlzIHN1YnRyZWUgaXMgYWx3YXlzIHBhcnRpYWxseSBzZWxlY3RlZC4KLSAgICAgKiA8cD4KLSAgICAgKiBJbiB0aGlzIGV4YW1wbGUsIHRoZSBub2RlcyB0aGF0IGFyZSB0cmF2ZXJzZWQKLSAgICAgKiBhcyAibGVmdCBib3VuZGFyeSIgbm9kZXMgYXJlOiBGLCBHLCBhbmQgQi4KLSAgICAgKgotICAgICAqIEBwYXJhbSByb290ICAgVGhlIG5vZGUgdGhhdCBpcyB0aGUgcm9vdCBvZiB0aGUgImxlZnQgYm91bmRhcnkiIHN1YnRyZWUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaG93ICAgIFNwZWNpZmllcyB3aGF0IHR5cGUgb2YgdHJhdmVyc2FsIGlzIGJlaW5nCi0gICAgICogICAgICAgICAgICAgICByZXF1ZXN0ZWQgKGV4dHJhY3QsIGNsb25lLCBvciBkZWxldGUpLgotICAgICAqICAgICAgICAgICAgICAgTGVnYWwgdmFsdWVzIGZvciB0aGlzIGFyZ3VtZW50IGFyZToKLSAgICAgKgotICAgICAqICAgICAgICAgICAgICAgPG9sPgotICAgICAqICAgICAgICAgICAgICAgPGxpPjxjb2RlPkVYVFJBQ1RfQ09OVEVOVFM8L2NvZGU+IC0gd2lsbCBwcm9kdWNlCi0gICAgICogICAgICAgICAgICAgICBhIG5vZGUgY29udGFpbmluZyB0aGUgYm91bmRhcmllcyBjb250ZW50LgotICAgICAqICAgICAgICAgICAgICAgUGFydGlhbGx5IHNlbGVjdGVkIG5vZGVzIGFyZSBjb3BpZWQsIGJ1dCBmdWxseQotICAgICAqICAgICAgICAgICAgICAgc2VsZWN0ZWQgbm9kZXMgYXJlIG1vdmVkLgotICAgICAqCi0gICAgICogICAgICAgICAgICAgICA8bGk+PGNvZGU+Q0xPTkVfQ09OVEVOVFM8L2NvZGU+IC0gd2lsbCBsZWF2ZSB0aGUKLSAgICAgKiAgICAgICAgICAgICAgIGNvbnRleHQgdHJlZSBvZiB0aGUgcmFuZ2UgdW5kaXN0dXJiZWQsIGJ1dCB3aWxsCi0gICAgICogICAgICAgICAgICAgICBwcm9kdWNlZCBjbG9uZWQgY29udGVudC4KLSAgICAgKgotICAgICAqICAgICAgICAgICAgICAgPGxpPjxjb2RlPkRFTEVURV9DT05URU5UUzwvY29kZT4gLSB3aWxsIGRlbGV0ZSBmcm9tCi0gICAgICogICAgICAgICAgICAgICB0aGUgY29udGV4dCB0cmVlIG9mIHRoZSByYW5nZSwgYWxsIGZ1bGx5IHNlbGVjdGVkCi0gICAgICogICAgICAgICAgICAgICBub2RlcyB3aXRoaW4gdGhlIGJvdW5kYXJ5LgotICAgICAqICAgICAgICAgICAgICAgPC9vbD4KLSAgICAgKgotICAgICAqIEByZXR1cm4gUmV0dXJucyBhIG5vZGUgdGhhdCBpcyB0aGUgcmVzdWx0IG9mIHZpc2l0aW5nIG5vZGVzLgotICAgICAqICAgICAgICAgSWYgdGhlIHRyYXZlcnNhbCBvcGVyYXRpb24gaXMKLSAgICAgKiAgICAgICAgIDxjb2RlPkRFTEVURV9DT05URU5UUzwvY29kZT4gdGhlIHJldHVybiB2YWx1ZSBpcyBudWxsLgotICAgICAqLwotICAgIHByaXZhdGUgTm9kZSB0cmF2ZXJzZUxlZnRCb3VuZGFyeSggTm9kZSByb290LCBpbnQgaG93ICkKLSAgICB7Ci0gICAgICAgIE5vZGUgbmV4dCA9IGdldFNlbGVjdGVkTm9kZSggZ2V0U3RhcnRDb250YWluZXIoKSwgZ2V0U3RhcnRPZmZzZXQoKSApOwotICAgICAgICBib29sZWFuIGlzRnVsbHlTZWxlY3RlZCA9ICggbmV4dCE9Z2V0U3RhcnRDb250YWluZXIoKSApOwotCi0gICAgICAgIGlmICggbmV4dD09cm9vdCApCi0gICAgICAgICAgICByZXR1cm4gdHJhdmVyc2VOb2RlKCBuZXh0LCBpc0Z1bGx5U2VsZWN0ZWQsIHRydWUsIGhvdyApOwotCi0gICAgICAgIE5vZGUgcGFyZW50ID0gbmV4dC5nZXRQYXJlbnROb2RlKCk7Ci0gICAgICAgIE5vZGUgY2xvbmVkUGFyZW50ID0gdHJhdmVyc2VOb2RlKCBwYXJlbnQsIGZhbHNlLCB0cnVlLCBob3cgKTsKLQotICAgICAgICB3aGlsZSggcGFyZW50IT1udWxsICkKLSAgICAgICAgewotICAgICAgICAgICAgd2hpbGUoIG5leHQhPW51bGwgKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIE5vZGUgbmV4dFNpYmxpbmcgPSBuZXh0LmdldE5leHRTaWJsaW5nKCk7Ci0gICAgICAgICAgICAgICAgTm9kZSBjbG9uZWRDaGlsZCA9Ci0gICAgICAgICAgICAgICAgICAgIHRyYXZlcnNlTm9kZSggbmV4dCwgaXNGdWxseVNlbGVjdGVkLCB0cnVlLCBob3cgKTsKLSAgICAgICAgICAgICAgICBpZiAoIGhvdyE9REVMRVRFX0NPTlRFTlRTICkKLSAgICAgICAgICAgICAgICAgICAgY2xvbmVkUGFyZW50LmFwcGVuZENoaWxkKGNsb25lZENoaWxkKTsKLSAgICAgICAgICAgICAgICBpc0Z1bGx5U2VsZWN0ZWQgPSB0cnVlOwotICAgICAgICAgICAgICAgIG5leHQgPSBuZXh0U2libGluZzsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmICggcGFyZW50PT1yb290ICkKLSAgICAgICAgICAgICAgICByZXR1cm4gY2xvbmVkUGFyZW50OwotCi0gICAgICAgICAgICBuZXh0ID0gcGFyZW50LmdldE5leHRTaWJsaW5nKCk7Ci0gICAgICAgICAgICBwYXJlbnQgPSBwYXJlbnQuZ2V0UGFyZW50Tm9kZSgpOwotICAgICAgICAgICAgTm9kZSBjbG9uZWRHcmFuZFBhcmVudCA9IHRyYXZlcnNlTm9kZSggcGFyZW50LCBmYWxzZSwgdHJ1ZSwgaG93ICk7Ci0gICAgICAgICAgICBpZiAoIGhvdyE9REVMRVRFX0NPTlRFTlRTICkKLSAgICAgICAgICAgICAgICBjbG9uZWRHcmFuZFBhcmVudC5hcHBlbmRDaGlsZCggY2xvbmVkUGFyZW50ICk7Ci0gICAgICAgICAgICBjbG9uZWRQYXJlbnQgPSBjbG9uZWRHcmFuZFBhcmVudDsKLQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gc2hvdWxkIG5ldmVyIG9jY3VyCi0gICAgICAgIHJldHVybiBudWxsOwotCi0gICAgfQotCi0gICAgLyoqCi0gICAgICogVXRpbGl0eSBtZXRob2QgZm9yIHRyYXZlcnNpbmcgYSBzaW5nbGUgbm9kZS4KLSAgICAgKiBEb2VzIG5vdCBwcm9wZXJseSBoYW5kbGUgYSB0ZXh0IG5vZGUgY29udGFpbmluZyBib3RoIHRoZQotICAgICAqIHN0YXJ0IGFuZCBlbmQgb2Zmc2V0cy4gIFN1Y2ggbm9kZXMgc2hvdWxkCi0gICAgICogaGF2ZSBiZWVuIHByZXZpb3VzbHkgZGV0ZWN0ZWQgYW5kIGJlZW4gcm91dGVkIHRvIHRyYXZlcnNlVGV4dE5vZGUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbiAgICAgIFRoZSBub2RlIHRvIGJlIHRyYXZlcnNlZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBpc0Z1bGx5U2VsZWN0ZWQKLSAgICAgKiAgICAgICAgICAgICAgIFNldCB0byB0cnVlIGlmIHRoZSBub2RlIGlzIGZ1bGx5IHNlbGVjdGVkLiAgU2hvdWxkIGJlCi0gICAgICogICAgICAgICAgICAgICBmYWxzZSBvdGhlcndpc2UuCi0gICAgICogICAgICAgICAgICAgICBOb3RlIHRoYXQgYWx0aG91Z2ggdGhlIERPTSAyIHNwZWNpZmljYXRpb24gc2F5cyB0aGF0IGEKLSAgICAgKiAgICAgICAgICAgICAgIHRleHQgbm9kZSB0aGF0IGlzIGJvdGh0aGUgc3RhcnQgYW5kIGVuZCBjb250YWluZXIgaXMgbm90Ci0gICAgICogICAgICAgICAgICAgICBzZWxlY3RlZCwgd2UgdHJlYXQgaXQgaGVyZSBhcyBpZiBpdCB3ZXJlIHBhcnRpYWxseQotICAgICAqICAgICAgICAgICAgICAgc2VsZWN0ZWQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaXNMZWZ0IElzIHRydWUgaWYgd2UgYXJlIHRyYXZlcnNpbmcgdGhlIG5vZGUgYXMgcGFydCBvZiBuYXZpZ2F0aW5nCi0gICAgICogICAgICAgICAgICAgICB0aGUgImxlZnQgYm91bmRhcnkiIG9mIHRoZSByYW5nZS4gIElmIHRoaXMgdmFsdWUgaXMgZmFsc2UsCi0gICAgICogICAgICAgICAgICAgICBpdCBpbXBsaWVzIHdlIGFyZSBuYXZpZ2F0aW5nIHRoZSAicmlnaHQgYm91bmRhcnkiIG9mIHRoZQotICAgICAqICAgICAgICAgICAgICAgcmFuZ2UuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaG93ICAgIFNwZWNpZmllcyB3aGF0IHR5cGUgb2YgdHJhdmVyc2FsIGlzIGJlaW5nCi0gICAgICogICAgICAgICAgICAgICByZXF1ZXN0ZWQgKGV4dHJhY3QsIGNsb25lLCBvciBkZWxldGUpLgotICAgICAqICAgICAgICAgICAgICAgTGVnYWwgdmFsdWVzIGZvciB0aGlzIGFyZ3VtZW50IGFyZToKLSAgICAgKgotICAgICAqICAgICAgICAgICAgICAgPG9sPgotICAgICAqICAgICAgICAgICAgICAgPGxpPjxjb2RlPkVYVFJBQ1RfQ09OVEVOVFM8L2NvZGU+IC0gd2lsbCBzaW1wbHkKLSAgICAgKiAgICAgICAgICAgICAgIHJldHVybiB0aGUgb3JpZ2luYWwgbm9kZS4KLSAgICAgKgotICAgICAqICAgICAgICAgICAgICAgPGxpPjxjb2RlPkNMT05FX0NPTlRFTlRTPC9jb2RlPiAtIHdpbGwgbGVhdmUgdGhlCi0gICAgICogICAgICAgICAgICAgICBjb250ZXh0IHRyZWUgb2YgdGhlIHJhbmdlIHVuZGlzdHVyYmVkLCBidXQgd2lsbAotICAgICAqICAgICAgICAgICAgICAgcmV0dXJuIGEgY2xvbmVkIG5vZGUuCi0gICAgICoKLSAgICAgKiAgICAgICAgICAgICAgIDxsaT48Y29kZT5ERUxFVEVfQ09OVEVOVFM8L2NvZGU+IC0gd2lsbCBkZWxldGUgdGhlCi0gICAgICogICAgICAgICAgICAgICBub2RlIGZyb20gaXQncyBwYXJlbnQsIGJ1dCB3aWxsIHJldHVybiBudWxsLgotICAgICAqICAgICAgICAgICAgICAgPC9vbD4KLSAgICAgKgotICAgICAqIEByZXR1cm4gUmV0dXJucyBhIG5vZGUgdGhhdCBpcyB0aGUgcmVzdWx0IG9mIHZpc2l0aW5nIHRoZSBub2RlLgotICAgICAqICAgICAgICAgSWYgdGhlIHRyYXZlcnNhbCBvcGVyYXRpb24gaXMKLSAgICAgKiAgICAgICAgIDxjb2RlPkRFTEVURV9DT05URU5UUzwvY29kZT4gdGhlIHJldHVybiB2YWx1ZSBpcyBudWxsLgotICAgICAqLwotICAgIHByaXZhdGUgTm9kZSB0cmF2ZXJzZU5vZGUoIE5vZGUgbiwgYm9vbGVhbiBpc0Z1bGx5U2VsZWN0ZWQsIGJvb2xlYW4gaXNMZWZ0LCBpbnQgaG93ICkKLSAgICB7Ci0gICAgICAgIGlmICggaXNGdWxseVNlbGVjdGVkICkKLSAgICAgICAgICAgIHJldHVybiB0cmF2ZXJzZUZ1bGx5U2VsZWN0ZWQoIG4sIGhvdyApOwotICAgICAgICBpZiAoIG4uZ2V0Tm9kZVR5cGUoKT09Tm9kZS5URVhUX05PREUgKQotICAgICAgICAgICAgcmV0dXJuIHRyYXZlcnNlVGV4dE5vZGUoIG4sIGlzTGVmdCwgaG93ICk7Ci0gICAgICAgIHJldHVybiB0cmF2ZXJzZVBhcnRpYWxseVNlbGVjdGVkKCBuLCBob3cgKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBVdGlsaXR5IG1ldGhvZCBmb3IgdHJhdmVyc2luZyBhIHNpbmdsZSBub2RlIHdoZW4KLSAgICAgKiB3ZSBrbm93IGEtcHJpb3JpIHRoYXQgdGhlIG5vZGUgaWYgZnVsbHkKLSAgICAgKiBzZWxlY3RlZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuICAgICAgVGhlIG5vZGUgdG8gYmUgdHJhdmVyc2VkLgotICAgICAqCi0gICAgICogQHBhcmFtIGhvdyAgICBTcGVjaWZpZXMgd2hhdCB0eXBlIG9mIHRyYXZlcnNhbCBpcyBiZWluZwotICAgICAqICAgICAgICAgICAgICAgcmVxdWVzdGVkIChleHRyYWN0LCBjbG9uZSwgb3IgZGVsZXRlKS4KLSAgICAgKiAgICAgICAgICAgICAgIExlZ2FsIHZhbHVlcyBmb3IgdGhpcyBhcmd1bWVudCBhcmU6Ci0gICAgICoKLSAgICAgKiAgICAgICAgICAgICAgIDxvbD4KLSAgICAgKiAgICAgICAgICAgICAgIDxsaT48Y29kZT5FWFRSQUNUX0NPTlRFTlRTPC9jb2RlPiAtIHdpbGwgc2ltcGx5Ci0gICAgICogICAgICAgICAgICAgICByZXR1cm4gdGhlIG9yaWdpbmFsIG5vZGUuCi0gICAgICoKLSAgICAgKiAgICAgICAgICAgICAgIDxsaT48Y29kZT5DTE9ORV9DT05URU5UUzwvY29kZT4gLSB3aWxsIGxlYXZlIHRoZQotICAgICAqICAgICAgICAgICAgICAgY29udGV4dCB0cmVlIG9mIHRoZSByYW5nZSB1bmRpc3R1cmJlZCwgYnV0IHdpbGwKLSAgICAgKiAgICAgICAgICAgICAgIHJldHVybiBhIGNsb25lZCBub2RlLgotICAgICAqCi0gICAgICogICAgICAgICAgICAgICA8bGk+PGNvZGU+REVMRVRFX0NPTlRFTlRTPC9jb2RlPiAtIHdpbGwgZGVsZXRlIHRoZQotICAgICAqICAgICAgICAgICAgICAgbm9kZSBmcm9tIGl0J3MgcGFyZW50LCBidXQgd2lsbCByZXR1cm4gbnVsbC4KLSAgICAgKiAgICAgICAgICAgICAgIDwvb2w+Ci0gICAgICoKLSAgICAgKiBAcmV0dXJuIFJldHVybnMgYSBub2RlIHRoYXQgaXMgdGhlIHJlc3VsdCBvZiB2aXNpdGluZyB0aGUgbm9kZS4KLSAgICAgKiAgICAgICAgIElmIHRoZSB0cmF2ZXJzYWwgb3BlcmF0aW9uIGlzCi0gICAgICogICAgICAgICA8Y29kZT5ERUxFVEVfQ09OVEVOVFM8L2NvZGU+IHRoZSByZXR1cm4gdmFsdWUgaXMgbnVsbC4KLSAgICAgKi8KLSAgICBwcml2YXRlIE5vZGUgdHJhdmVyc2VGdWxseVNlbGVjdGVkKCBOb2RlIG4sIGludCBob3cgKQotICAgIHsKLSAgICAgICAgc3dpdGNoKCBob3cgKQotICAgICAgICB7Ci0gICAgICAgIGNhc2UgQ0xPTkVfQ09OVEVOVFM6Ci0gICAgICAgICAgICByZXR1cm4gbi5jbG9uZU5vZGUoIHRydWUgKTsKLSAgICAgICAgY2FzZSBFWFRSQUNUX0NPTlRFTlRTOgotICAgICAgICAgICAgaWYgKCBuLmdldE5vZGVUeXBlKCk9PU5vZGUuRE9DVU1FTlRfVFlQRV9OT0RFICkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAvLyBUQkQ6IFRoaXMgc2hvdWxkIGJlIGEgSElFUkFSQ0hZX1JFUVVFU1RfRVJSCi0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgICAgIERPTUV4Y2VwdGlvbi5ISUVSQVJDSFlfUkVRVUVTVF9FUlIsCi0gICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwgIkhJRVJBUkNIWV9SRVFVRVNUX0VSUiIsIG51bGwpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiBuOwotICAgICAgICBjYXNlIERFTEVURV9DT05URU5UUzoKLSAgICAgICAgICAgIG4uZ2V0UGFyZW50Tm9kZSgpLnJlbW92ZUNoaWxkKG4pOwotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVXRpbGl0eSBtZXRob2QgZm9yIHRyYXZlcnNpbmcgYSBzaW5nbGUgbm9kZSB3aGVuCi0gICAgICogd2Uga25vdyBhLXByaW9yaSB0aGF0IHRoZSBub2RlIGlmIHBhcnRpYWxseQotICAgICAqIHNlbGVjdGVkIGFuZCBpcyBub3QgYSB0ZXh0IG5vZGUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbiAgICAgIFRoZSBub2RlIHRvIGJlIHRyYXZlcnNlZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBob3cgICAgU3BlY2lmaWVzIHdoYXQgdHlwZSBvZiB0cmF2ZXJzYWwgaXMgYmVpbmcKLSAgICAgKiAgICAgICAgICAgICAgIHJlcXVlc3RlZCAoZXh0cmFjdCwgY2xvbmUsIG9yIGRlbGV0ZSkuCi0gICAgICogICAgICAgICAgICAgICBMZWdhbCB2YWx1ZXMgZm9yIHRoaXMgYXJndW1lbnQgYXJlOgotICAgICAqCi0gICAgICogICAgICAgICAgICAgICA8b2w+Ci0gICAgICogICAgICAgICAgICAgICA8bGk+PGNvZGU+RVhUUkFDVF9DT05URU5UUzwvY29kZT4gLSB3aWxsIHNpbXBseQotICAgICAqICAgICAgICAgICAgICAgcmV0dXJuIHRoZSBvcmlnaW5hbCBub2RlLgotICAgICAqCi0gICAgICogICAgICAgICAgICAgICA8bGk+PGNvZGU+Q0xPTkVfQ09OVEVOVFM8L2NvZGU+IC0gd2lsbCBsZWF2ZSB0aGUKLSAgICAgKiAgICAgICAgICAgICAgIGNvbnRleHQgdHJlZSBvZiB0aGUgcmFuZ2UgdW5kaXN0dXJiZWQsIGJ1dCB3aWxsCi0gICAgICogICAgICAgICAgICAgICByZXR1cm4gYSBjbG9uZWQgbm9kZS4KLSAgICAgKgotICAgICAqICAgICAgICAgICAgICAgPGxpPjxjb2RlPkRFTEVURV9DT05URU5UUzwvY29kZT4gLSB3aWxsIGRlbGV0ZSB0aGUKLSAgICAgKiAgICAgICAgICAgICAgIG5vZGUgZnJvbSBpdCdzIHBhcmVudCwgYnV0IHdpbGwgcmV0dXJuIG51bGwuCi0gICAgICogICAgICAgICAgICAgICA8L29sPgotICAgICAqCi0gICAgICogQHJldHVybiBSZXR1cm5zIGEgbm9kZSB0aGF0IGlzIHRoZSByZXN1bHQgb2YgdmlzaXRpbmcgdGhlIG5vZGUuCi0gICAgICogICAgICAgICBJZiB0aGUgdHJhdmVyc2FsIG9wZXJhdGlvbiBpcwotICAgICAqICAgICAgICAgPGNvZGU+REVMRVRFX0NPTlRFTlRTPC9jb2RlPiB0aGUgcmV0dXJuIHZhbHVlIGlzIG51bGwuCi0gICAgICovCi0gICAgcHJpdmF0ZSBOb2RlIHRyYXZlcnNlUGFydGlhbGx5U2VsZWN0ZWQoIE5vZGUgbiwgaW50IGhvdyApCi0gICAgewotICAgICAgICBzd2l0Y2goIGhvdyApCi0gICAgICAgIHsKLSAgICAgICAgY2FzZSBERUxFVEVfQ09OVEVOVFM6Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgY2FzZSBDTE9ORV9DT05URU5UUzoKLSAgICAgICAgY2FzZSBFWFRSQUNUX0NPTlRFTlRTOgotICAgICAgICAgICAgcmV0dXJuIG4uY2xvbmVOb2RlKCBmYWxzZSApOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFV0aWxpdHkgbWV0aG9kIGZvciB0cmF2ZXJzaW5nIGEgdGV4dCBub2RlIHRoYXQgd2Uga25vdwotICAgICAqIGEtcHJpb3JpIHRvIGJlIG9uIGEgbGVmdCBvciByaWdodCBib3VuZGFyeSBvZiB0aGUgcmFuZ2UuCi0gICAgICogVGhpcyBtZXRob2QgZG9lcyBub3QgcHJvcGVybHkgaGFuZGxlIHRleHQgbm9kZXMgdGhhdCBjb250YWluCi0gICAgICogYm90aCB0aGUgc3RhcnQgYW5kIGVuZCBwb2ludHMgb2YgdGhlIHJhbmdlLgotICAgICAqCi0gICAgICogQHBhcmFtIG4gICAgICBUaGUgbm9kZSB0byBiZSB0cmF2ZXJzZWQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaXNMZWZ0IElzIHRydWUgaWYgd2UgYXJlIHRyYXZlcnNpbmcgdGhlIG5vZGUgYXMgcGFydCBvZiBuYXZpZ2F0aW5nCi0gICAgICogICAgICAgICAgICAgICB0aGUgImxlZnQgYm91bmRhcnkiIG9mIHRoZSByYW5nZS4gIElmIHRoaXMgdmFsdWUgaXMgZmFsc2UsCi0gICAgICogICAgICAgICAgICAgICBpdCBpbXBsaWVzIHdlIGFyZSBuYXZpZ2F0aW5nIHRoZSAicmlnaHQgYm91bmRhcnkiIG9mIHRoZQotICAgICAqICAgICAgICAgICAgICAgcmFuZ2UuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaG93ICAgIFNwZWNpZmllcyB3aGF0IHR5cGUgb2YgdHJhdmVyc2FsIGlzIGJlaW5nCi0gICAgICogICAgICAgICAgICAgICByZXF1ZXN0ZWQgKGV4dHJhY3QsIGNsb25lLCBvciBkZWxldGUpLgotICAgICAqICAgICAgICAgICAgICAgTGVnYWwgdmFsdWVzIGZvciB0aGlzIGFyZ3VtZW50IGFyZToKLSAgICAgKgotICAgICAqICAgICAgICAgICAgICAgPG9sPgotICAgICAqICAgICAgICAgICAgICAgPGxpPjxjb2RlPkVYVFJBQ1RfQ09OVEVOVFM8L2NvZGU+IC0gd2lsbCBzaW1wbHkKLSAgICAgKiAgICAgICAgICAgICAgIHJldHVybiB0aGUgb3JpZ2luYWwgbm9kZS4KLSAgICAgKgotICAgICAqICAgICAgICAgICAgICAgPGxpPjxjb2RlPkNMT05FX0NPTlRFTlRTPC9jb2RlPiAtIHdpbGwgbGVhdmUgdGhlCi0gICAgICogICAgICAgICAgICAgICBjb250ZXh0IHRyZWUgb2YgdGhlIHJhbmdlIHVuZGlzdHVyYmVkLCBidXQgd2lsbAotICAgICAqICAgICAgICAgICAgICAgcmV0dXJuIGEgY2xvbmVkIG5vZGUuCi0gICAgICoKLSAgICAgKiAgICAgICAgICAgICAgIDxsaT48Y29kZT5ERUxFVEVfQ09OVEVOVFM8L2NvZGU+IC0gd2lsbCBkZWxldGUgdGhlCi0gICAgICogICAgICAgICAgICAgICBub2RlIGZyb20gaXQncyBwYXJlbnQsIGJ1dCB3aWxsIHJldHVybiBudWxsLgotICAgICAqICAgICAgICAgICAgICAgPC9vbD4KLSAgICAgKgotICAgICAqIEByZXR1cm4gUmV0dXJucyBhIG5vZGUgdGhhdCBpcyB0aGUgcmVzdWx0IG9mIHZpc2l0aW5nIHRoZSBub2RlLgotICAgICAqICAgICAgICAgSWYgdGhlIHRyYXZlcnNhbCBvcGVyYXRpb24gaXMKLSAgICAgKiAgICAgICAgIDxjb2RlPkRFTEVURV9DT05URU5UUzwvY29kZT4gdGhlIHJldHVybiB2YWx1ZSBpcyBudWxsLgotICAgICAqLwotICAgIHByaXZhdGUgTm9kZSB0cmF2ZXJzZVRleHROb2RlKCBOb2RlIG4sIGJvb2xlYW4gaXNMZWZ0LCBpbnQgaG93ICkKLSAgICB7Ci0gICAgICAgIFN0cmluZyB0eHRWYWx1ZSA9IG4uZ2V0Tm9kZVZhbHVlKCk7Ci0gICAgICAgIFN0cmluZyBuZXdOb2RlVmFsdWU7Ci0gICAgICAgIFN0cmluZyBvbGROb2RlVmFsdWU7Ci0KLSAgICAgICAgaWYgKCBpc0xlZnQgKQotICAgICAgICB7Ci0gICAgICAgICAgICBpbnQgb2Zmc2V0ID0gZ2V0U3RhcnRPZmZzZXQoKTsKLSAgICAgICAgICAgIG5ld05vZGVWYWx1ZSA9IHR4dFZhbHVlLnN1YnN0cmluZyggb2Zmc2V0ICk7Ci0gICAgICAgICAgICBvbGROb2RlVmFsdWUgPSB0eHRWYWx1ZS5zdWJzdHJpbmcoIDAsIG9mZnNldCApOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotICAgICAgICAgICAgaW50IG9mZnNldCA9IGdldEVuZE9mZnNldCgpOwotICAgICAgICAgICAgbmV3Tm9kZVZhbHVlID0gdHh0VmFsdWUuc3Vic3RyaW5nKCAwLCBvZmZzZXQgKTsKLSAgICAgICAgICAgIG9sZE5vZGVWYWx1ZSA9IHR4dFZhbHVlLnN1YnN0cmluZyggb2Zmc2V0ICk7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoIGhvdyAhPSBDTE9ORV9DT05URU5UUyApCi0gICAgICAgICAgICBuLnNldE5vZGVWYWx1ZSggb2xkTm9kZVZhbHVlICk7Ci0gICAgICAgIGlmICggaG93PT1ERUxFVEVfQ09OVEVOVFMgKQotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIE5vZGUgbmV3Tm9kZSA9IG4uY2xvbmVOb2RlKCBmYWxzZSApOwotICAgICAgICBuZXdOb2RlLnNldE5vZGVWYWx1ZSggbmV3Tm9kZVZhbHVlICk7Ci0gICAgICAgIHJldHVybiBuZXdOb2RlOwotICAgIH0KLQotICAgIHZvaWQgY2hlY2tJbmRleChOb2RlIHJlZk5vZGUsIGludCBvZmZzZXQpIHRocm93cyBET01FeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGlmIChvZmZzZXQgPCAwKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgIERPTUV4Y2VwdGlvbi5JTkRFWF9TSVpFX0VSUiwKLSAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiSU5ERVhfU0laRV9FUlIiLCBudWxsKSk7Ci0gICAgICAgIH0KLQotICAgICAgICBpbnQgdHlwZSA9IHJlZk5vZGUuZ2V0Tm9kZVR5cGUoKTsKLQotICAgICAgICAvLyBJZiB0aGUgbm9kZSBjb250YWlucyB0ZXh0LCBlbnN1cmUgdGhhdCB0aGUKLSAgICAgICAgLy8gb2Zmc2V0IG9mIHRoZSByYW5nZSBpcyA8PSB0byB0aGUgbGVuZ3RoIG9mIHRoZSB0ZXh0Ci0gICAgICAgIGlmICh0eXBlID09IE5vZGUuVEVYVF9OT0RFCi0gICAgICAgICAgICB8fCB0eXBlID09IE5vZGUuQ0RBVEFfU0VDVElPTl9OT0RFCi0gICAgICAgICAgICB8fCB0eXBlID09IE5vZGUuQ09NTUVOVF9OT0RFCi0gICAgICAgICAgICB8fCB0eXBlID09IE5vZGUuUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFKSB7Ci0gICAgICAgICAgICBpZiAob2Zmc2V0ID4gcmVmTm9kZS5nZXROb2RlVmFsdWUoKS5sZW5ndGgoKSkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLklOREVYX1NJWkVfRVJSLAotICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sICJJTkRFWF9TSVpFX0VSUiIsIG51bGwpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIC8vIFNpbmNlIHRoZSBub2RlIGlzIG5vdCB0ZXh0LCBlbnN1cmUgdGhhdCB0aGUgb2Zmc2V0Ci0gICAgICAgICAgICAvLyBpcyB2YWxpZCB3aXRoIHJlc3BlY3QgdG8gdGhlIG51bWJlciBvZiBjaGlsZCBub2RlcwotICAgICAgICAgICAgaWYgKG9mZnNldCA+IHJlZk5vZGUuZ2V0Q2hpbGROb2RlcygpLmdldExlbmd0aCgpKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uSU5ERVhfU0laRV9FUlIsCi0gICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwgIklOREVYX1NJWkVfRVJSIiwgbnVsbCkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBHaXZlbiBhIG5vZGUsIGNhbGN1bGF0ZSB3aGF0IHRoZSBSYW5nZSdzIHJvb3QgY29udGFpbmVyCi0gICAgICAgICAqIGZvciB0aGF0IG5vZGUgd291bGQgYmUuCi0gICAgICAgICAqLwotICAgICAgICBwcml2YXRlIE5vZGUgZ2V0Um9vdENvbnRhaW5lciggTm9kZSBub2RlICkKLSAgICAgICAgewotICAgICAgICAgICAgICAgIGlmICggbm9kZT09bnVsbCApCi0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLQotICAgICAgICAgICAgICAgIHdoaWxlKCBub2RlLmdldFBhcmVudE5vZGUoKSE9bnVsbCApCi0gICAgICAgICAgICAgICAgICAgICAgICBub2RlID0gbm9kZS5nZXRQYXJlbnROb2RlKCk7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIG5vZGU7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogUmV0dXJucyB0cnVlIElGRiB0aGUgZ2l2ZW4gbm9kZSBjYW4gc2VydmUgYXMgYSBjb250YWluZXIKLSAgICAgICAgICogZm9yIGEgcmFuZ2UncyBib3VuZGFyeSBwb2ludHMuCi0gICAgICAgICAqLwotICAgICAgICBwcml2YXRlIGJvb2xlYW4gaXNMZWdhbENvbnRhaW5lciggTm9kZSBub2RlICkKLSAgICAgICAgewotICAgICAgICAgICAgICAgIGlmICggbm9kZT09bnVsbCApCi0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0KLSAgICAgICAgICAgICAgICB3aGlsZSggbm9kZSE9bnVsbCApCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoKCBub2RlLmdldE5vZGVUeXBlKCkgKQotICAgICAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBOb2RlLkVOVElUWV9OT0RFOgotICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBOb2RlLk5PVEFUSU9OX05PREU6Ci0gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIE5vZGUuRE9DVU1FTlRfVFlQRV9OT0RFOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBub2RlID0gbm9kZS5nZXRQYXJlbnROb2RlKCk7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgIH0KLQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBGaW5kcyB0aGUgcm9vdCBjb250YWluZXIgZm9yIHRoZSBnaXZlbiBub2RlIGFuZCBkZXRlcm1pbmVzCi0gICAgICAgICAqIGlmIHRoYXQgcm9vdCBjb250YWluZXIgaXMgbGVnYWwgd2l0aCByZXNwZWN0IHRvIHRoZQotICAgICAgICAgKiBET00gMiBzcGVjaWZpY2F0aW9uLiAgQXQgcHJlc2VudCwgdGhhdCBtZWFucyB0aGUgcm9vdAotICAgICAgICAgKiBjb250YWluZXIgbXVzdCBiZSBlaXRoZXIgYW4gYXR0cmlidXRlLCBhIGRvY3VtZW50LAotICAgICAgICAgKiBvciBhIGRvY3VtZW50IGZyYWdtZW50LgotICAgICAgICAgKi8KLSAgICAgICAgcHJpdmF0ZSBib29sZWFuIGhhc0xlZ2FsUm9vdENvbnRhaW5lciggTm9kZSBub2RlICkKLSAgICAgICAgewotICAgICAgICAgICAgICAgIGlmICggbm9kZT09bnVsbCApCi0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0KLSAgICAgICAgICAgICAgICBOb2RlIHJvb3RDb250YWluZXIgPSBnZXRSb290Q29udGFpbmVyKCBub2RlICk7Ci0gICAgICAgICAgICAgICAgc3dpdGNoKCByb290Q29udGFpbmVyLmdldE5vZGVUeXBlKCkgKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBjYXNlIE5vZGUuQVRUUklCVVRFX05PREU6Ci0gICAgICAgICAgICAgICAgY2FzZSBOb2RlLkRPQ1VNRU5UX05PREU6Ci0gICAgICAgICAgICAgICAgY2FzZSBOb2RlLkRPQ1VNRU5UX0ZSQUdNRU5UX05PREU6Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFJldHVybnMgdHJ1ZSBJRkYgdGhlIGdpdmVuIG5vZGUgY2FuIGJlIGNvbnRhaW5lZCBieQotICAgICAgICAgKiBhIHJhbmdlLgotICAgICAgICAgKi8KLSAgICAgICAgcHJpdmF0ZSBib29sZWFuIGlzTGVnYWxDb250YWluZWROb2RlKCBOb2RlIG5vZGUgKQotICAgICAgICB7Ci0gICAgICAgICAgICAgICAgaWYgKCBub2RlPT1udWxsICkKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgICAgICBzd2l0Y2goIG5vZGUuZ2V0Tm9kZVR5cGUoKSApCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIGNhc2UgTm9kZS5ET0NVTUVOVF9OT0RFOgotICAgICAgICAgICAgICAgIGNhc2UgTm9kZS5ET0NVTUVOVF9GUkFHTUVOVF9OT0RFOgotICAgICAgICAgICAgICAgIGNhc2UgTm9kZS5BVFRSSUJVVEVfTk9ERToKLSAgICAgICAgICAgICAgICBjYXNlIE5vZGUuRU5USVRZX05PREU6Ci0gICAgICAgICAgICAgICAgY2FzZSBOb2RlLk5PVEFUSU9OX05PREU6Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0KLSAgICBOb2RlIG5leHROb2RlKE5vZGUgbm9kZSwgYm9vbGVhbiB2aXNpdENoaWxkcmVuKSB7Ci0KLSAgICAgICAgaWYgKG5vZGUgPT0gbnVsbCkgcmV0dXJuIG51bGw7Ci0KLSAgICAgICAgTm9kZSByZXN1bHQ7Ci0gICAgICAgIGlmICh2aXNpdENoaWxkcmVuKSB7Ci0gICAgICAgICAgICByZXN1bHQgPSBub2RlLmdldEZpcnN0Q2hpbGQoKTsKLSAgICAgICAgICAgIGlmIChyZXN1bHQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBpZiBoYXNTaWJsaW5nLCByZXR1cm4gc2libGluZwotICAgICAgICByZXN1bHQgPSBub2RlLmdldE5leHRTaWJsaW5nKCk7Ci0gICAgICAgIGlmIChyZXN1bHQgIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKLSAgICAgICAgfQotCi0KLSAgICAgICAgLy8gcmV0dXJuIHBhcmVudCdzIDFzdCBzaWJsaW5nLgotICAgICAgICBOb2RlIHBhcmVudCA9IG5vZGUuZ2V0UGFyZW50Tm9kZSgpOwotICAgICAgICB3aGlsZSAocGFyZW50ICE9IG51bGwKLSAgICAgICAgICAgICAgICYmIHBhcmVudCAhPSBmRG9jdW1lbnQKLSAgICAgICAgICAgICAgICApIHsKLSAgICAgICAgICAgIHJlc3VsdCA9IHBhcmVudC5nZXROZXh0U2libGluZygpOwotICAgICAgICAgICAgaWYgKHJlc3VsdCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgcGFyZW50ID0gcGFyZW50LmdldFBhcmVudE5vZGUoKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICB9IC8vIHdoaWxlIChwYXJlbnQgIT0gbnVsbCAmJiBwYXJlbnQgIT0gZlJvb3QpIHsKLQotICAgICAgICAvLyBlbmQgb2YgbGlzdCwgcmV0dXJuIG51bGwKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLyoqIGlzIGEgYW4gYW5jZXN0b3Igb2YgYiA/ICovCi0gICAgYm9vbGVhbiBpc0FuY2VzdG9yT2YoTm9kZSBhLCBOb2RlIGIpIHsKLSAgICAgICAgZm9yIChOb2RlIG5vZGU9Yjsgbm9kZSAhPSBudWxsOyBub2RlPW5vZGUuZ2V0UGFyZW50Tm9kZSgpKSB7Ci0gICAgICAgICAgICBpZiAobm9kZSA9PSBhKSByZXR1cm4gdHJ1ZTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgLyoqIHdoYXQgaXMgdGhlIGluZGV4IG9mIHRoZSBjaGlsZCBpbiB0aGUgcGFyZW50ICovCi0gICAgaW50IGluZGV4T2YoTm9kZSBjaGlsZCwgTm9kZSBwYXJlbnQpIHsKLSAgICAgICAgaWYgKGNoaWxkLmdldFBhcmVudE5vZGUoKSAhPSBwYXJlbnQpIHJldHVybiAtMTsKLSAgICAgICAgaW50IGkgPSAwOwotICAgICAgICBmb3IoTm9kZSBub2RlID0gcGFyZW50LmdldEZpcnN0Q2hpbGQoKTsgbm9kZSE9IGNoaWxkOyBub2RlPW5vZGUuZ2V0TmV4dFNpYmxpbmcoKSkgewotICAgICAgICAgICAgaSsrOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFV0aWxpdHkgbWV0aG9kIHRvIHJldHJpZXZlIGEgY2hpbGQgbm9kZSBieSBpbmRleC4gIFRoaXMgbWV0aG9kCi0gICAgICogYXNzdW1lcyB0aGUgY2FsbGVyIGlzIHRyeWluZyB0byBmaW5kIG91dCB3aGljaCBub2RlIGlzCi0gICAgICogc2VsZWN0ZWQgYnkgdGhlIGdpdmVuIGluZGV4LiAgTm90ZSB0aGF0IGlmIHRoZSBpbmRleCBpcwotICAgICAqIGdyZWF0ZXIgdGhhbiB0aGUgbnVtYmVyIG9mIGNoaWxkcmVuLCB0aGlzIGltcGxpZXMgdGhhdCB0aGUKLSAgICAgKiBmaXJzdCBub2RlIHNlbGVjdGVkIGlzIHRoZSBwYXJlbnQgbm9kZSBpdHNlbGYuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29udGFpbmVyIEEgY29udGFpbmVyIG5vZGUKLSAgICAgKgotICAgICAqIEBwYXJhbSBvZmZzZXQgICAgQW4gb2Zmc2V0IHdpdGhpbiB0aGUgY29udGFpbmVyIGZvciB3aGljaCBhIHNlbGVjdGVkIG5vZGUgc2hvdWxkCi0gICAgICogICAgICAgICAgICAgICAgICBiZSBjb21wdXRlZC4gIElmIHRoZSBvZmZzZXQgaXMgbGVzcyB0aGFuIHplcm8sIG9yIGlmIHRoZSBvZmZzZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgIGlzIGdyZWF0ZXIgdGhhbiB0aGUgbnVtYmVyIG9mIGNoaWxkcmVuLCB0aGUgY29udGFpbmVyIGlzIHJldHVybmVkLgotICAgICAqCi0gICAgICogQHJldHVybiBSZXR1cm5zIGVpdGhlciBhIGNoaWxkIG5vZGUgb2YgdGhlIGNvbnRhaW5lciBvciB0aGUKLSAgICAgKiAgICAgICAgIGNvbnRhaW5lciBpdHNlbGYuCi0gICAgICovCi0gICAgcHJpdmF0ZSBOb2RlIGdldFNlbGVjdGVkTm9kZSggTm9kZSBjb250YWluZXIsIGludCBvZmZzZXQgKQotICAgIHsKLSAgICAgICAgaWYgKCBjb250YWluZXIuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLlRFWFRfTk9ERSApCi0gICAgICAgICAgICByZXR1cm4gY29udGFpbmVyOwotCi0gICAgICAgIC8vIFRoaXMgY2FzZSBpcyBhbiBpbXBvcnRhbnQgY29udmVuaWVuY2UgZm9yCi0gICAgICAgIC8vIHRyYXZlcnNlUmlnaHRCb3VuZGFyeSgpCi0gICAgICAgIGlmICggb2Zmc2V0PDAgKQotICAgICAgICAgICAgcmV0dXJuIGNvbnRhaW5lcjsKLQotICAgICAgICBOb2RlIGNoaWxkID0gY29udGFpbmVyLmdldEZpcnN0Q2hpbGQoKTsKLSAgICAgICAgd2hpbGUoIGNoaWxkIT1udWxsICYmIG9mZnNldCA+IDAgKQotICAgICAgICB7Ci0gICAgICAgICAgICAtLW9mZnNldDsKLSAgICAgICAgICAgIGNoaWxkID0gY2hpbGQuZ2V0TmV4dFNpYmxpbmcoKTsKLSAgICAgICAgfQotICAgICAgICBpZiAoIGNoaWxkIT1udWxsICkKLSAgICAgICAgICAgIHJldHVybiBjaGlsZDsKLSAgICAgICAgcmV0dXJuIGNvbnRhaW5lcjsKLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9UZXh0SW1wbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL1RleHRJbXBsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDM2N2FlNjUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL1RleHRJbXBsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw2NjUgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDAyLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tOwotCi1pbXBvcnQgb3JnLnczYy5kb20uQ2hhcmFjdGVyRGF0YTsKLWltcG9ydCBvcmcudzNjLmRvbS5ET01FeGNlcHRpb247Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcudzNjLmRvbS5UZXh0OwotCi0vKioKLSAqIFRleHQgbm9kZXMgaG9sZCB0aGUgbm9uLW1hcmt1cCwgbm9uLUVudGl0eSBjb250ZW50IG9mCi0gKiBhbiBFbGVtZW50IG9yIEF0dHJpYnV0ZS4KLSAqIDxQPgotICogV2hlbiBhIGRvY3VtZW50IGlzIGZpcnN0IG1hZGUgYXZhaWxhYmxlIHRvIHRoZSBET00sIHRoZXJlIGlzIG9ubHkKLSAqIG9uZSBUZXh0IG9iamVjdCBmb3IgZWFjaCBibG9jayBvZiBhZGphY2VudCBwbGFpbi10ZXh0LiBVc2VycyAoaWUsCi0gKiBhcHBsaWNhdGlvbnMpIG1heSBjcmVhdGUgbXVsdGlwbGUgYWRqYWNlbnQgVGV4dHMgZHVyaW5nIGVkaXRpbmcgLS0KLSAqIHNlZSB7QGxpbmsgb3JnLnczYy5kb20uRWxlbWVudCNub3JtYWxpemV9IGZvciBkaXNjdXNzaW9uLgotICogPFA+Ci0gKiBOb3RlIHRoYXQgQ0RBVEFTZWN0aW9uIGlzIGEgc3ViY2xhc3Mgb2YgVGV4dC4gVGhpcyBpcyBjb25jZXB0dWFsbHkKLSAqIHZhbGlkLCBzaW5jZSB0aGV5J3JlIHJlYWxseSBqdXN0IHR3byBkaWZmZXJlbnQgd2F5cyBvZiBxdW90aW5nCi0gKiBjaGFyYWN0ZXJzIHdoZW4gdGhleSdyZSB3cml0dGVuIG91dCBhcyBwYXJ0IG9mIGFuIFhNTCBzdHJlYW0uCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBzaW5jZSAgUFItRE9NLUxldmVsLTEtMTk5ODA4MTguCi0gKi8KLXB1YmxpYyBjbGFzcyBUZXh0SW1wbAotICAgIGV4dGVuZHMgQ2hhcmFjdGVyRGF0YUltcGwKLSAgICBpbXBsZW1lbnRzIENoYXJhY3RlckRhdGEsIFRleHQgewotCi0gICAgLy8KLSAgICAvLyBQcml2YXRlIERhdGEgbWVtYmVycwotICAgIC8vCi0KLQotICAgIC8vCi0gICAgLy8gQ29uc3RhbnRzCi0gICAgLy8KLQotICAgIC8qKiBTZXJpYWxpemF0aW9uIHZlcnNpb24uICovCi0gICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC01Mjk0OTgwODUyOTU3NDAzNDY5TDsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKiBEZWZhdWx0IGNvbnN0cnVjdG9yICovCi0gICAgcHVibGljIFRleHRJbXBsKCl7fQotCi0gICAgLyoqIEZhY3RvcnkgY29uc3RydWN0b3IuICovCi0gICAgcHVibGljIFRleHRJbXBsKENvcmVEb2N1bWVudEltcGwgb3duZXJEb2MsIFN0cmluZyBkYXRhKSB7Ci0gICAgICAgIHN1cGVyKG93bmVyRG9jLCBkYXRhKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBOT04tRE9NOiByZXNldHMgbm9kZSBhbmQgc2V0cyBzcGVjaWZpZWQgdmFsdWVzIGZvciB0aGUgY3VycmVudCBub2RlCi0gICAgICoKLSAgICAgKiBAcGFyYW0gb3duZXJEb2MKLSAgICAgKiBAcGFyYW0gZGF0YQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFZhbHVlcyhDb3JlRG9jdW1lbnRJbXBsIG93bmVyRG9jLCBTdHJpbmcgZGF0YSl7Ci0KLSAgICAgICAgZmxhZ3M9MDsKLSAgICAgICAgbmV4dFNpYmxpbmcgPSBudWxsOwotICAgICAgICBwcmV2aW91c1NpYmxpbmc9bnVsbDsKLSAgICAgICAgc2V0T3duZXJEb2N1bWVudChvd25lckRvYyk7Ci0gICAgICAgIHN1cGVyLmRhdGEgPSBkYXRhOwotICAgIH0KLSAgICAvLwotICAgIC8vIE5vZGUgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBBIHNob3J0IGludGVnZXIgaW5kaWNhdGluZyB3aGF0IHR5cGUgb2Ygbm9kZSB0aGlzIGlzLiBUaGUgbmFtZWQKLSAgICAgKiBjb25zdGFudHMgZm9yIHRoaXMgdmFsdWUgYXJlIGRlZmluZWQgaW4gdGhlIG9yZy53M2MuZG9tLk5vZGUgaW50ZXJmYWNlLgotICAgICAqLwotICAgIHB1YmxpYyBzaG9ydCBnZXROb2RlVHlwZSgpIHsKLSAgICAgICAgcmV0dXJuIE5vZGUuVEVYVF9OT0RFOwotICAgIH0KLQotICAgIC8qKiBSZXR1cm5zIHRoZSBub2RlIG5hbWUuICovCi0gICAgcHVibGljIFN0cmluZyBnZXROb2RlTmFtZSgpIHsKLSAgICAgICAgcmV0dXJuICIjdGV4dCI7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogTk9OLURPTTogU2V0IHdoZXRoZXIgdGhpcyBUZXh0IGlzIGlnbm9yYWJsZSB3aGl0ZXNwYWNlLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldElnbm9yYWJsZVdoaXRlc3BhY2UoYm9vbGVhbiBpZ25vcmUpIHsKLQotICAgICAgICBpZiAobmVlZHNTeW5jRGF0YSgpKSB7Ci0gICAgICAgICAgICBzeW5jaHJvbml6ZURhdGEoKTsKLSAgICAgICAgfQotICAgICAgICBpc0lnbm9yYWJsZVdoaXRlc3BhY2UoaWdub3JlKTsKLQotICAgIH0gLy8gc2V0SWdub3JhYmxlV2hpdGVzcGFjZShib29sZWFuKQotCi0KLSAgICAvKioKLSAgICAgKiBET00gTDMgQ29yZSBDUiAtIEV4cGVyaW1lbnRhbAotICAgICAqCi0gICAgICogUmV0dXJucyB3aGV0aGVyIHRoaXMgdGV4dCBub2RlIGNvbnRhaW5zCi0gICAgICogZWxlbWVudCBjb250ZW50IHdoaXRlc3BhY2U8L2E+LCBvZnRlbiBhYnVzaXZlbHkgY2FsbGVkICJpZ25vcmFibGUgd2hpdGVzcGFjZSIuCi0gICAgICogVGhlIHRleHQgbm9kZSBpcyBkZXRlcm1pbmVkIHRvIGNvbnRhaW4gd2hpdGVzcGFjZSBpbiBlbGVtZW50IGNvbnRlbnQKLSAgICAgKiBkdXJpbmcgdGhlIGxvYWQgb2YgdGhlIGRvY3VtZW50IG9yIGlmIHZhbGlkYXRpb24gb2NjdXJzIHdoaWxlIHVzaW5nCi0gICAgICogPGNvZGU+RG9jdW1lbnQubm9ybWFsaXplRG9jdW1lbnQoKTwvY29kZT4uCi0gICAgICogQHNpbmNlIERPTSBMZXZlbCAzCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNFbGVtZW50Q29udGVudFdoaXRlc3BhY2UoKSB7Ci0gICAgICAgIC8vIFJFVklTSVQ6IGlzIHRoaXMgaW1wbGVtZW5hdGlvbiBjb3JyZWN0PwotICAgICAgICBpZiAobmVlZHNTeW5jRGF0YSgpKSB7Ci0gICAgICAgICAgICBzeW5jaHJvbml6ZURhdGEoKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gaW50ZXJuYWxJc0lnbm9yYWJsZVdoaXRlc3BhY2UoKTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIERPTSBMZXZlbCAzIFdEIC0gRXhwZXJpbWVudGFsLgotICAgICAqIFJldHVybnMgYWxsIHRleHQgb2YgPGNvZGU+VGV4dDwvY29kZT4gbm9kZXMgbG9naWNhbGx5LWFkamFjZW50IHRleHQKLSAgICAgKiBub2RlcyB0byB0aGlzIG5vZGUsIGNvbmNhdGVuYXRlZCBpbiBkb2N1bWVudCBvcmRlci4KLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFdob2xlVGV4dCgpewotCi0gICAgICAgIGlmIChuZWVkc1N5bmNEYXRhKCkpIHsKLSAgICAgICAgICAgIHN5bmNocm9uaXplRGF0YSgpOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKGZCdWZmZXJTdHIgPT0gbnVsbCl7Ci0gICAgICAgICAgICBmQnVmZmVyU3RyID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgZkJ1ZmZlclN0ci5zZXRMZW5ndGgoMCk7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGRhdGEgIT0gbnVsbCAmJiBkYXRhLmxlbmd0aCgpICE9IDApIHsKLSAgICAgICAgICAgIGZCdWZmZXJTdHIuYXBwZW5kKGRhdGEpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy9jb25jYXRlbmF0ZSB0ZXh0IG9mIGxvZ2ljYWxseSBhZGphY2VudCB0ZXh0IG5vZGVzIHRvIHRoZSBsZWZ0IG9mIHRoaXMgbm9kZSBpbiB0aGUgdHJlZQotICAgICAgICBnZXRXaG9sZVRleHRCYWNrd2FyZCh0aGlzLmdldFByZXZpb3VzU2libGluZygpLCBmQnVmZmVyU3RyLCB0aGlzLmdldFBhcmVudE5vZGUoKSk7Ci0gICAgICAgIFN0cmluZyB0ZW1wID0gZkJ1ZmZlclN0ci50b1N0cmluZygpOwotCi0gICAgICAgIC8vY2xlYXIgYnVmZmVyCi0gICAgICAgIGZCdWZmZXJTdHIuc2V0TGVuZ3RoKDApOwotCi0gICAgICAgIC8vY29uY2F0ZW5hdGUgdGV4dCBvZiBsb2dpY2FsbHkgYWRqYWNlbnQgdGV4dCBub2RlcyB0byB0aGUgcmlnaHQgb2YgdGhpcyBub2RlIGluIHRoZSB0cmVlCi0gICAgICAgIGdldFdob2xlVGV4dEZvcndhcmQodGhpcy5nZXROZXh0U2libGluZygpLCBmQnVmZmVyU3RyLCB0aGlzLmdldFBhcmVudE5vZGUoKSk7Ci0KLSAgICAgICAgcmV0dXJuIHRlbXAgKyBmQnVmZmVyU3RyLnRvU3RyaW5nKCk7Ci0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBpbnRlcm5hbCBtZXRob2QgdGFraW5nIGEgU3RyaW5nQnVmZmVyIGluIHBhcmFtZXRlciBhbmQgaW5zZXJ0cyB0aGUKLSAgICAgKiB0ZXh0IGNvbnRlbnQgYXQgdGhlIHN0YXJ0IG9mIHRoZSBidWZmZXIKLSAgICAgKgotICAgICAqIEBwYXJhbSBidWYKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCBpbnNlcnRUZXh0Q29udGVudChTdHJpbmdCdWZmZXIgYnVmKSB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKLSAgICAgICAgIFN0cmluZyBjb250ZW50ID0gZ2V0Tm9kZVZhbHVlKCk7Ci0gICAgICAgICBpZiAoY29udGVudCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgYnVmLmluc2VydCgwLCBjb250ZW50KTsKLSAgICAgICAgIH0KLSAgICAgfQotCi0gICAgLyoqCi0gICAgICogQ29uY2F0ZW5hdGVzIHRoZSB0ZXh0IG9mIGFsbCBsb2dpY2FsbHktYWRqYWNlbnQgdGV4dCBub2RlcyB0byB0aGUKLSAgICAgKiByaWdodCBvZiB0aGlzIG5vZGUKLSAgICAgKiBAcGFyYW0gbm9kZQotICAgICAqIEBwYXJhbSBidWZmZXIKLSAgICAgKiBAcGFyYW0gcGFyZW50Ci0gICAgICogQHJldHVybiB0cnVlIC0gaWYgZXhlY3V0aW9uIHdhcyBzdG9wcGVkIGJlY2F1c2UgdGhlIHR5cGUgb2Ygbm9kZQotICAgICAqICAgICAgICAgb3RoZXIgdGhhbiBFbnRpdHlSZWYsIFRleHQsIENEQVRBIGlzIGVuY291bnRlcmVkLCBvdGhlcndpc2UKLSAgICAgKiAgICAgICAgIHJldHVybiBmYWxzZQotICAgICAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBnZXRXaG9sZVRleHRGb3J3YXJkKE5vZGUgbm9kZSwgU3RyaW5nQnVmZmVyIGJ1ZmZlciwgTm9kZSBwYXJlbnQpewotICAgICAgICAvLyBib29sZWFuIHRvIGluZGljYXRlIHdoZXRoZXIgbm9kZSBpcyBhIGNoaWxkIG9mIGFuIGVudGl0eSByZWZlcmVuY2UKLSAgICAgICAgYm9vbGVhbiBpbkVudFJlZiA9IGZhbHNlOwotCi0gICAgICAgIGlmIChwYXJlbnQhPW51bGwpIHsKLSAgICAgICAgICAgICAgICBpbkVudFJlZiA9IHBhcmVudC5nZXROb2RlVHlwZSgpPT1Ob2RlLkVOVElUWV9SRUZFUkVOQ0VfTk9ERTsKLSAgICAgICAgfQotCi0gICAgICAgIHdoaWxlIChub2RlICE9IG51bGwpIHsKLSAgICAgICAgICAgIHNob3J0IHR5cGUgPSBub2RlLmdldE5vZGVUeXBlKCk7Ci0gICAgICAgICAgICBpZiAodHlwZSA9PSBOb2RlLkVOVElUWV9SRUZFUkVOQ0VfTk9ERSkgewotICAgICAgICAgICAgICAgIGlmIChnZXRXaG9sZVRleHRGb3J3YXJkKG5vZGUuZ2V0Rmlyc3RDaGlsZCgpLCBidWZmZXIsIG5vZGUpKXsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAodHlwZSA9PSBOb2RlLlRFWFRfTk9ERSB8fAotICAgICAgICAgICAgICAgICAgICAgdHlwZSA9PSBOb2RlLkNEQVRBX1NFQ1RJT05fTk9ERSkgewotICAgICAgICAgICAgICAgICgoTm9kZUltcGwpbm9kZSkuZ2V0VGV4dENvbnRlbnQoYnVmZmVyKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBub2RlID0gbm9kZS5nZXROZXh0U2libGluZygpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gaWYgdGhlIHBhcmVudCBub2RlIGlzIGFuIGVudGl0eSByZWZlcmVuY2Ugbm9kZSwgbXVzdAotICAgICAgICAvLyBjaGVjayBub2RlcyB0byB0aGUgcmlnaHQgb2YgdGhlIHBhcmVudCBlbnRpdHkgcmVmZXJlbmNlIG5vZGUgZm9yIGxvZ2ljYWxseSBhZGphY2VudAotICAgICAgICAvLyB0ZXh0IG5vZGVzCi0gICAgICAgIGlmIChpbkVudFJlZikgewotICAgICAgICAgICAgZ2V0V2hvbGVUZXh0Rm9yd2FyZChwYXJlbnQuZ2V0TmV4dFNpYmxpbmcoKSwgYnVmZmVyLCBwYXJlbnQuZ2V0UGFyZW50Tm9kZSgpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbmNhdGVuYXRlcyB0aGUgdGV4dCBvZiBhbGwgbG9naWNhbGx5LWFkamFjZW50IHRleHQgbm9kZXMgdG8gdGhlIGxlZnQgb2YKLSAgICAgKiB0aGUgbm9kZQotICAgICAqIEBwYXJhbSBub2RlCi0gICAgICogQHBhcmFtIGJ1ZmZlcgotICAgICAqIEBwYXJhbSBwYXJlbnQKLSAgICAgKiBAcmV0dXJuIHRydWUgLSBpZiBleGVjdXRpb24gd2FzIHN0b3BwZWQgYmVjYXVzZSB0aGUgdHlwZSBvZiBub2RlCi0gICAgICogICAgICAgICBvdGhlciB0aGFuIEVudGl0eVJlZiwgVGV4dCwgQ0RBVEEgaXMgZW5jb3VudGVyZWQsIG90aGVyd2lzZQotICAgICAqICAgICAgICAgcmV0dXJuIGZhbHNlCi0gICAgICovCi0gICAgcHJpdmF0ZSBib29sZWFuIGdldFdob2xlVGV4dEJhY2t3YXJkKE5vZGUgbm9kZSwgU3RyaW5nQnVmZmVyIGJ1ZmZlciwgTm9kZSBwYXJlbnQpewotCi0gICAgICAgIC8vIGJvb2xlYW4gdG8gaW5kaWNhdGUgd2hldGhlciBub2RlIGlzIGEgY2hpbGQgb2YgYW4gZW50aXR5IHJlZmVyZW5jZQotICAgICAgICBib29sZWFuIGluRW50UmVmID0gZmFsc2U7Ci0gICAgICAgIGlmIChwYXJlbnQhPW51bGwpIHsKLSAgICAgICAgICAgICAgICBpbkVudFJlZiA9IHBhcmVudC5nZXROb2RlVHlwZSgpPT1Ob2RlLkVOVElUWV9SRUZFUkVOQ0VfTk9ERTsKLSAgICAgICAgfQotCi0gICAgICAgIHdoaWxlIChub2RlICE9IG51bGwpIHsKLSAgICAgICAgICAgIHNob3J0IHR5cGUgPSBub2RlLmdldE5vZGVUeXBlKCk7Ci0gICAgICAgICAgICBpZiAodHlwZSA9PSBOb2RlLkVOVElUWV9SRUZFUkVOQ0VfTk9ERSkgewotICAgICAgICAgICAgICAgIGlmIChnZXRXaG9sZVRleHRCYWNrd2FyZChub2RlLmdldExhc3RDaGlsZCgpLCBidWZmZXIsIG5vZGUpKXsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAodHlwZSA9PSBOb2RlLlRFWFRfTk9ERSB8fAotICAgICAgICAgICAgICAgICAgICAgdHlwZSA9PSBOb2RlLkNEQVRBX1NFQ1RJT05fTk9ERSkgewotICAgICAgICAgICAgICAgICgoVGV4dEltcGwpbm9kZSkuaW5zZXJ0VGV4dENvbnRlbnQoYnVmZmVyKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBub2RlID0gbm9kZS5nZXRQcmV2aW91c1NpYmxpbmcoKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIGlmIHRoZSBwYXJlbnQgbm9kZSBpcyBhbiBlbnRpdHkgcmVmZXJlbmNlIG5vZGUsIG11c3QKLSAgICAgICAgLy8gY2hlY2sgbm9kZXMgdG8gdGhlIGxlZnQgb2YgdGhlIHBhcmVudCBlbnRpdHkgcmVmZXJlbmNlIG5vZGUgZm9yIGxvZ2ljYWxseSBhZGphY2VudAotICAgICAgICAvLyB0ZXh0IG5vZGVzCi0gICAgICAgIGlmIChpbkVudFJlZikgewotICAgICAgICAgICAgICAgIGdldFdob2xlVGV4dEJhY2t3YXJkKHBhcmVudC5nZXRQcmV2aW91c1NpYmxpbmcoKSwgYnVmZmVyLCBwYXJlbnQuZ2V0UGFyZW50Tm9kZSgpKTsKLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJlcGxhY2VzIHRoZSB0ZXh0IG9mIHRoZSBjdXJyZW50IG5vZGUgYW5kIGFsbCBsb2dpY2FsbHktYWRqYWNlbnQgdGV4dAotICAgICAqIG5vZGVzIHdpdGggdGhlIHNwZWNpZmllZCB0ZXh0LiBBbGwgbG9naWNhbGx5LWFkamFjZW50IHRleHQgbm9kZXMgYXJlCi0gICAgICogcmVtb3ZlZCBpbmNsdWRpbmcgdGhlIGN1cnJlbnQgbm9kZSB1bmxlc3MgaXQgd2FzIHRoZSByZWNpcGllbnQgb2YgdGhlCi0gICAgICogcmVwbGFjZW1lbnQgdGV4dC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjb250ZW50Ci0gICAgICogICAgICAgICAgICBUaGUgY29udGVudCBvZiB0aGUgcmVwbGFjaW5nIFRleHQgbm9kZS4KLSAgICAgKiBAcmV0dXJuIHRleHQgLSBUaGUgVGV4dCBub2RlIGNyZWF0ZWQgd2l0aCB0aGUgc3BlY2lmaWVkIGNvbnRlbnQuCi0gICAgICogQHNpbmNlIERPTSBMZXZlbCAzCi0gICAgICovCi0gICAgcHVibGljIFRleHQgcmVwbGFjZVdob2xlVGV4dChTdHJpbmcgY29udGVudCkgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgaWYgKG5lZWRzU3luY0RhdGEoKSkgewotICAgICAgICAgICAgc3luY2hyb25pemVEYXRhKCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvL2lmIHRoZSBjb250ZW50IGlzIG51bGwKLSAgICAgICAgTm9kZSBwYXJlbnQgPSB0aGlzLmdldFBhcmVudE5vZGUoKTsKLSAgICAgICAgaWYgKGNvbnRlbnQgPT0gbnVsbCB8fCBjb250ZW50Lmxlbmd0aCgpID09IDApIHsKLSAgICAgICAgICAgIC8vIHJlbW92ZSBjdXJyZW50IG5vZGUKLSAgICAgICAgICAgIGlmIChwYXJlbnQgIT0gbnVsbCkgeyAvLyBjaGVjayBpZiBub2RlIGluIHRoZSB0cmVlCi0gICAgICAgICAgICAgICAgcGFyZW50LnJlbW92ZUNoaWxkKHRoaXMpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBtYWtlIHN1cmUgd2UgY2FuIG1ha2UgdGhlIHJlcGxhY2VtZW50Ci0gICAgICAgIGlmIChvd25lckRvY3VtZW50KCkuZXJyb3JDaGVja2luZykgewotICAgICAgICAgICAgaWYgKCFjYW5Nb2RpZnlQcmV2KHRoaXMpKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSLAotICAgICAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIiLCBudWxsKSk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIG1ha2Ugc3VyZSB3ZSBjYW4gbWFrZSB0aGUgcmVwbGFjZW1lbnQKLSAgICAgICAgICAgIGlmICghY2FuTW9kaWZ5TmV4dCh0aGlzKSkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiwKLSAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZSgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIiwgbnVsbCkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy9yZXBsYWNlIHRoZSB0ZXh0IG5vZGUKLSAgICAgICAgVGV4dCBjdXJyZW50Tm9kZSA9IG51bGw7Ci0gICAgICAgIGlmIChpc1JlYWRPbmx5KCkpIHsKLSAgICAgICAgICAgIFRleHQgbmV3Tm9kZSA9IHRoaXMub3duZXJEb2N1bWVudCgpLmNyZWF0ZVRleHROb2RlKGNvbnRlbnQpOwotICAgICAgICAgICAgaWYgKHBhcmVudCAhPSBudWxsKSB7IC8vIGNoZWNrIGlmIG5vZGUgaW4gdGhlIHRyZWUKLSAgICAgICAgICAgICAgICBwYXJlbnQuaW5zZXJ0QmVmb3JlKG5ld05vZGUsIHRoaXMpOwotICAgICAgICAgICAgICAgIHBhcmVudC5yZW1vdmVDaGlsZCh0aGlzKTsKLSAgICAgICAgICAgICAgICBjdXJyZW50Tm9kZSA9IG5ld05vZGU7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIHJldHVybiBuZXdOb2RlOwotICAgICAgICAgICAgfQotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgdGhpcy5zZXREYXRhKGNvbnRlbnQpOwotICAgICAgICAgICAgY3VycmVudE5vZGUgPSB0aGlzOwotICAgICAgICB9Ci0KLSAgICAgICAgLy9jaGVjayBsb2dpY2FsbHktYWRqYWNlbnQgdGV4dCBub2RlcwotICAgICAgICBOb2RlIHByZXYgPSBjdXJyZW50Tm9kZS5nZXRQcmV2aW91c1NpYmxpbmcoKTsKLSAgICAgICAgd2hpbGUgKHByZXYgIT0gbnVsbCkgewotICAgICAgICAgICAgLy9JZiB0aGUgbG9naWNhbGx5LWFkamFjZW50IG5leHQgbm9kZSBjYW4gYmUgcmVtb3ZlZAotICAgICAgICAgICAgLy9yZW1vdmUgaXQuIEEgbG9naWNhbGx5IGFkamFjZW50IG5vZGUgY2FuIGJlIHJlbW92ZWQgaWYKLSAgICAgICAgICAgIC8vaXQgaXMgYSBUZXh0IG9yIENEQVRBU2VjdGlvbiBub2RlIG9yIGFuIEVudGl0eVJlZmVyZW5jZSB3aXRoCi0gICAgICAgICAgICAvL1RleHQgYW5kIENEQVRBIG9ubHkgY2hpbGRyZW4uCi0gICAgICAgICAgICBpZiAoKHByZXYuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLlRFWFRfTk9ERSkKLSAgICAgICAgICAgICAgICAgICAgfHwgKHByZXYuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLkNEQVRBX1NFQ1RJT05fTk9ERSkKLSAgICAgICAgICAgICAgICAgICAgfHwgKHByZXYuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLkVOVElUWV9SRUZFUkVOQ0VfTk9ERSAmJiBoYXNUZXh0T25seUNoaWxkcmVuKHByZXYpKSkgewotICAgICAgICAgICAgICAgIHBhcmVudC5yZW1vdmVDaGlsZChwcmV2KTsKLSAgICAgICAgICAgICAgICBwcmV2ID0gY3VycmVudE5vZGU7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcHJldiA9IHByZXYuZ2V0UHJldmlvdXNTaWJsaW5nKCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvL2NoZWNrIGxvZ2ljYWxseS1hZGphY2VudCB0ZXh0IG5vZGVzCi0gICAgICAgIE5vZGUgbmV4dCA9IGN1cnJlbnROb2RlLmdldE5leHRTaWJsaW5nKCk7Ci0gICAgICAgIHdoaWxlIChuZXh0ICE9IG51bGwpIHsKLSAgICAgICAgICAgIC8vSWYgdGhlIGxvZ2ljYWxseS1hZGphY2VudCBuZXh0IG5vZGUgY2FuIGJlIHJlbW92ZWQKLSAgICAgICAgICAgIC8vcmVtb3ZlIGl0LiBBIGxvZ2ljYWxseSBhZGphY2VudCBub2RlIGNhbiBiZSByZW1vdmVkIGlmCi0gICAgICAgICAgICAvL2l0IGlzIGEgVGV4dCBvciBDREFUQVNlY3Rpb24gbm9kZSBvciBhbiBFbnRpdHlSZWZlcmVuY2Ugd2l0aAotICAgICAgICAgICAgLy9UZXh0IGFuZCBDREFUQSBvbmx5IGNoaWxkcmVuLgotICAgICAgICAgICAgaWYgKChuZXh0LmdldE5vZGVUeXBlKCkgPT0gTm9kZS5URVhUX05PREUpCi0gICAgICAgICAgICAgICAgICAgIHx8IChuZXh0LmdldE5vZGVUeXBlKCkgPT0gTm9kZS5DREFUQV9TRUNUSU9OX05PREUpCi0gICAgICAgICAgICAgICAgICAgIHx8IChuZXh0LmdldE5vZGVUeXBlKCkgPT0gTm9kZS5FTlRJVFlfUkVGRVJFTkNFX05PREUgJiYgaGFzVGV4dE9ubHlDaGlsZHJlbihuZXh0KSkpIHsKLSAgICAgICAgICAgICAgICBwYXJlbnQucmVtb3ZlQ2hpbGQobmV4dCk7Ci0gICAgICAgICAgICAgICAgbmV4dCA9IGN1cnJlbnROb2RlOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIG5leHQgPSBuZXh0LmdldE5leHRTaWJsaW5nKCk7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gY3VycmVudE5vZGU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSWYgYW55IEVudGl0eVJlZmVyZW5jZSB0byBiZSByZW1vdmVkIGhhcyBkZXNjZW5kYW50cyB0aGF0IGFyZSBub3QKLSAgICAgKiBFbnRpdHlSZWZlcmVuY2UsIFRleHQsIG9yIENEQVRBU2VjdGlvbiBub2RlcywgdGhlIHJlcGxhY2VXaG9sZVRleHQgbWV0aG9kCi0gICAgICogbXVzdCBmYWlsIGJlZm9yZSBwZXJmb3JtaW5nIGFueSBtb2RpZmljYXRpb24gb2YgdGhlIGRvY3VtZW50LCByYWlzaW5nIGEKLSAgICAgKiBET01FeGNlcHRpb24gd2l0aCB0aGUgY29kZSBOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIuIFRyYXZlcnNlIHByZXZpb3VzCi0gICAgICogc2libGluZ3Mgb2YgdGhlIG5vZGUgdG8gYmUgcmVwbGFjZWQuIElmIGEgcHJldmlvdXMgc2libGluZyBpcyBhbgotICAgICAqIEVudGl0eVJlZmVyZW5jZSBub2RlLCBnZXQgaXQncyBsYXN0IGNoaWxkLiBJZiB0aGUgbGFzdCBjaGlsZCB3YXMgYSBUZXh0Ci0gICAgICogb3IgQ0RBVEFTZWN0aW9uIG5vZGUgYW5kIGl0cyBwcmV2aW91cyBzaWJsaW5ncyBhcmUgbmVpdGhlciBhIHJlcGxhY2VhYmxlCi0gICAgICogRW50aXR5UmVmZXJlbmNlIG9yIFRleHQgb3IgQ0RBVEFTZWN0aW9uIG5vZGVzLCByZXR1cm4gZmFsc2UuIElGIHRoZSBsYXN0Ci0gICAgICogY2hpbGQgd2FzIG5laXRoZXIgVGV4dCBub3IgQ0RBVEFTZWN0aW9uIG5vciBhIHJlcGxhY2VhYmxlIEVudGl0eVJlZmVyZW5jZQotICAgICAqIE5vZGUsIHRoZW4gcmV0dXJuIHRydWUuIElmIHRoZSBsYXN0IGNoaWxkIHdhcyBhIFRleHQgb3IgQ0RBVEFTZWN0aW9uIG5vZGUKLSAgICAgKiBhbnkgaXRzIHByZXZpb3VzIHNpYmxpbmcgd2FzIG5vdCBvciB3YXMgYW4gRW50aXR5UmVmZXJlbmNlIHRoYXQgZGlkIG5vdAotICAgICAqIGNvbnRhaW4gb25seSBUZXh0IG9yIENEQVRBU2VjdGlvbiBub2RlcywgcmV0dXJuIGZhbHNlLiBDaGVjayB0aGlzCi0gICAgICogcmVjdXJzaXZlbHkgZm9yIEVudGl0eVJlZmVyZW5jZSBub2Rlcy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBub2RlCi0gICAgICogQHJldHVybiB0cnVlIC0gY2FuIHJlcGxhY2UgdGV4dCBmYWxzZSAtIGNhbid0IHJlcGxhY2UgZXhjZXB0aW9uIG11c3QgYmUKLSAgICAgKiAgICAgICAgIHJhaXNlZAotICAgICAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBjYW5Nb2RpZnlQcmV2KE5vZGUgbm9kZSkgewotICAgICAgICBib29sZWFuIHRleHRMYXN0Q2hpbGQgPSBmYWxzZTsKLQotICAgICAgICBOb2RlIHByZXYgPSBub2RlLmdldFByZXZpb3VzU2libGluZygpOwotCi0gICAgICAgIHdoaWxlIChwcmV2ICE9IG51bGwpIHsKLQotICAgICAgICAgICAgc2hvcnQgdHlwZSA9IHByZXYuZ2V0Tm9kZVR5cGUoKTsKLQotICAgICAgICAgICAgaWYgKHR5cGUgPT0gTm9kZS5FTlRJVFlfUkVGRVJFTkNFX05PREUpIHsKLSAgICAgICAgICAgICAgICAvL0lmIHRoZSBwcmV2aW91cyBzaWJsaW5nIHdhcyBlbnRpdHlyZWZlcmVuY2UKLSAgICAgICAgICAgICAgICAvL2NoZWNrIGlmIGl0cyBjb250ZW50IGlzIHJlcGxhY2VhYmxlCi0gICAgICAgICAgICAgICAgTm9kZSBsYXN0Q2hpbGQgPSBwcmV2LmdldExhc3RDaGlsZCgpOwotCi0gICAgICAgICAgICAgICAgLy9pZiB0aGUgZW50aXR5IHJlZmVyZW5jZSBoYXMgbm8gY2hpbGRyZW4KLSAgICAgICAgICAgICAgICAvL3JldHVybiBmYWxzZQotICAgICAgICAgICAgICAgIGlmIChsYXN0Q2hpbGQgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgLy9UaGUgcmVwbGFjZW1lbnQgdGV4dCBvZiB0aGUgZW50aXR5IHJlZmVyZW5jZSBzaG91bGQKLSAgICAgICAgICAgICAgICAvL2JlIGVpdGhlciBvbmx5IHRleHQsY2FkYXRzZWN0aW9ucyBvciByZXBsYWNlYWJsZSBlbnRpdHkKLSAgICAgICAgICAgICAgICAvL3JlZmVyZW5jZSBub2RlcyBvciB0aGUgbGFzdCBjaGlsZCBzaG91bGQgYmUgbmVpdGhlciBvZiB0aGVzZQotICAgICAgICAgICAgICAgIHdoaWxlIChsYXN0Q2hpbGQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBzaG9ydCBsVHlwZSA9IGxhc3RDaGlsZC5nZXROb2RlVHlwZSgpOwotCi0gICAgICAgICAgICAgICAgICAgIGlmIChsVHlwZSA9PSBOb2RlLlRFWFRfTk9ERQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IGxUeXBlID09IE5vZGUuQ0RBVEFfU0VDVElPTl9OT0RFKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICB0ZXh0TGFzdENoaWxkID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChsVHlwZSA9PSBOb2RlLkVOVElUWV9SRUZFUkVOQ0VfTk9ERSkgewotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFjYW5Nb2RpZnlQcmV2KGxhc3RDaGlsZCkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vSWYgdGhlIEVudGl0eVJlZmVyZW5jZSBjaGlsZCBjb250YWlucwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vb25seSB0ZXh0LCBvciBub24tdGV4dCBvciBlbmRzIHdpdGggYQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vbm9uLXRleHQgbm9kZS4KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0TGFzdENoaWxkID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vSWYgdGhlIGxhc3QgY2hpbGQgd2FzIHJlcGxhY2VhYmxlIGFuZCBvdGhlcnMgYXJlIG5vdAotICAgICAgICAgICAgICAgICAgICAgICAgLy9UZXh0IG9yIENEYXRhU2VjdGlvbiBvciByZXBsYWNlYWJsZSBFbnRpdHlSZWYgbm9kZXMKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vcmV0dXJuIGZhbHNlLgotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRleHRMYXN0Q2hpbGQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGxhc3RDaGlsZCA9IGxhc3RDaGlsZC5nZXRQcmV2aW91c1NpYmxpbmcoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT0gTm9kZS5URVhUX05PREUKLSAgICAgICAgICAgICAgICAgICAgfHwgdHlwZSA9PSBOb2RlLkNEQVRBX1NFQ1RJT05fTk9ERSkgewotICAgICAgICAgICAgICAgIC8vSWYgdGhlIHByZXZpb3VzIHNpYmxpbmcgd2FzIHRleHQgb3IgY2RhdGFzZWN0aW9uIG1vdmUgdG8gbmV4dAotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAvL0lmIHRoZSBwcmV2aW91cyBzaWJsaW5nIHdhcyBhbnl0aGluZyBidXQgdGV4dCBvcgotICAgICAgICAgICAgICAgIC8vY2RhdGFzZWN0aW9uIG9yIGFuIGVudGl0eSByZWZlcmVuY2UsIHN0b3Agc2VhcmNoIGFuZAotICAgICAgICAgICAgICAgIC8vcmV0dXJuIHRydWUKLSAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgcHJldiA9IHByZXYuZ2V0UHJldmlvdXNTaWJsaW5nKCk7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJZiBhbnkgRW50aXR5UmVmZXJlbmNlIHRvIGJlIHJlbW92ZWQgaGFzIGRlc2NlbmRhbnRzIHRoYXQgYXJlIG5vdAotICAgICAqIEVudGl0eVJlZmVyZW5jZSwgVGV4dCwgb3IgQ0RBVEFTZWN0aW9uIG5vZGVzLCB0aGUgcmVwbGFjZVdob2xlVGV4dCBtZXRob2QKLSAgICAgKiBtdXN0IGZhaWwgYmVmb3JlIHBlcmZvcm1pbmcgYW55IG1vZGlmaWNhdGlvbiBvZiB0aGUgZG9jdW1lbnQsIHJhaXNpbmcgYQotICAgICAqIERPTUV4Y2VwdGlvbiB3aXRoIHRoZSBjb2RlIE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUi4gVHJhdmVyc2UgcHJldmlvdXMKLSAgICAgKiBzaWJsaW5ncyBvZiB0aGUgbm9kZSB0byBiZSByZXBsYWNlZC4gSWYgYSBwcmV2aW91cyBzaWJsaW5nIGlzIGFuCi0gICAgICogRW50aXR5UmVmZXJlbmNlIG5vZGUsIGdldCBpdCdzIGxhc3QgY2hpbGQuIElmIHRoZSBmaXJzdCBjaGlsZCB3YXMgYSBUZXh0Ci0gICAgICogb3IgQ0RBVEFTZWN0aW9uIG5vZGUgYW5kIGl0cyBuZXh0IHNpYmxpbmdzIGFyZSBuZWl0aGVyIGEgcmVwbGFjZWFibGUKLSAgICAgKiBFbnRpdHlSZWZlcmVuY2Ugb3IgVGV4dCBvciBDREFUQVNlY3Rpb24gbm9kZXMsIHJldHVybiBmYWxzZS4gSUYgdGhlIGZpcnN0Ci0gICAgICogY2hpbGQgd2FzIG5laXRoZXIgVGV4dCBub3IgQ0RBVEFTZWN0aW9uIG5vciBhIHJlcGxhY2VhYmxlIEVudGl0eVJlZmVyZW5jZQotICAgICAqIE5vZGUsIHRoZW4gcmV0dXJuIHRydWUuIElmIHRoZSBmaXJzdCBjaGlsZCB3YXMgYSBUZXh0IG9yIENEQVRBU2VjdGlvbgotICAgICAqIG5vZGUgYW55IGl0cyBuZXh0IHNpYmxpbmcgd2FzIG5vdCBvciB3YXMgYW4gRW50aXR5UmVmZXJlbmNlIHRoYXQgZGlkIG5vdAotICAgICAqIGNvbnRhaW4gb25seSBUZXh0IG9yIENEQVRBU2VjdGlvbiBub2RlcywgcmV0dXJuIGZhbHNlLiBDaGVjayB0aGlzCi0gICAgICogcmVjdXJzaXZlbHkgZm9yIEVudGl0eVJlZmVyZW5jZSBub2Rlcy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBub2RlCi0gICAgICogQHJldHVybiB0cnVlIC0gY2FuIHJlcGxhY2UgdGV4dCBmYWxzZSAtIGNhbid0IHJlcGxhY2UgZXhjZXB0aW9uIG11c3QgYmUKLSAgICAgKiAgICAgICAgIHJhaXNlZAotICAgICAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBjYW5Nb2RpZnlOZXh0KE5vZGUgbm9kZSkgewotICAgICAgICBib29sZWFuIHRleHRGaXJzdENoaWxkID0gZmFsc2U7Ci0KLSAgICAgICAgTm9kZSBuZXh0ID0gbm9kZS5nZXROZXh0U2libGluZygpOwotICAgICAgICB3aGlsZSAobmV4dCAhPSBudWxsKSB7Ci0KLSAgICAgICAgICAgIHNob3J0IHR5cGUgPSBuZXh0LmdldE5vZGVUeXBlKCk7Ci0KLSAgICAgICAgICAgIGlmICh0eXBlID09IE5vZGUuRU5USVRZX1JFRkVSRU5DRV9OT0RFKSB7Ci0gICAgICAgICAgICAgICAgLy9JZiB0aGUgcHJldmlvdXMgc2libGluZyB3YXMgZW50aXR5cmVmZXJlbmNlCi0gICAgICAgICAgICAgICAgLy9jaGVjayBpZiBpdHMgY29udGVudCBpcyByZXBsYWNlYWJsZQotICAgICAgICAgICAgICAgIE5vZGUgZmlyc3RDaGlsZCA9IG5leHQuZ2V0Rmlyc3RDaGlsZCgpOwotCi0gICAgICAgICAgICAgICAgLy9pZiB0aGUgZW50aXR5IHJlZmVyZW5jZSBoYXMgbm8gY2hpbGRyZW4KLSAgICAgICAgICAgICAgICAvL3JldHVybiBmYWxzZQotICAgICAgICAgICAgICAgIGlmIChmaXJzdENoaWxkID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8vVGhlIHJlcGxhY2VtZW50IHRleHQgb2YgdGhlIGVudGl0eSByZWZlcmVuY2Ugc2hvdWxkCi0gICAgICAgICAgICAgICAgLy9iZSBlaXRoZXIgb25seSB0ZXh0LGNhZGF0c2VjdGlvbnMgb3IgcmVwbGFjZWFibGUgZW50aXR5Ci0gICAgICAgICAgICAgICAgLy9yZWZlcmVuY2Ugbm9kZXMgb3IgdGhlIGxhc3QgY2hpbGQgc2hvdWxkIGJlIG5laXRoZXIgb2YgdGhlc2UKLSAgICAgICAgICAgICAgICB3aGlsZSAoZmlyc3RDaGlsZCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIHNob3J0IGxUeXBlID0gZmlyc3RDaGlsZC5nZXROb2RlVHlwZSgpOwotCi0gICAgICAgICAgICAgICAgICAgIGlmIChsVHlwZSA9PSBOb2RlLlRFWFRfTk9ERQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IGxUeXBlID09IE5vZGUuQ0RBVEFfU0VDVElPTl9OT0RFKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICB0ZXh0Rmlyc3RDaGlsZCA9IHRydWU7Ci0gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAobFR5cGUgPT0gTm9kZS5FTlRJVFlfUkVGRVJFTkNFX05PREUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmICghY2FuTW9kaWZ5TmV4dChmaXJzdENoaWxkKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9JZiB0aGUgRW50aXR5UmVmZXJlbmNlIGNoaWxkIGNvbnRhaW5zCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9vbmx5IHRleHQsIG9yIG5vbi10ZXh0IG9yIGVuZHMgd2l0aCBhCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9ub24tdGV4dCBub2RlLgotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHRGaXJzdENoaWxkID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vSWYgdGhlIGZpcnN0IGNoaWxkIHdhcyByZXBsYWNlYWJsZSB0ZXh0IGFuZCBuZXh0Ci0gICAgICAgICAgICAgICAgICAgICAgICAvL2NoaWxkcmVuIGFyZSBub3QsIHRoZW4gcmV0dXJuIGZhbHNlCi0gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGV4dEZpcnN0Q2hpbGQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGZpcnN0Q2hpbGQgPSBmaXJzdENoaWxkLmdldE5leHRTaWJsaW5nKCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlID09IE5vZGUuVEVYVF9OT0RFCi0gICAgICAgICAgICAgICAgICAgIHx8IHR5cGUgPT0gTm9kZS5DREFUQV9TRUNUSU9OX05PREUpIHsKLSAgICAgICAgICAgICAgICAvL0lmIHRoZSBwcmV2aW91cyBzaWJsaW5nIHdhcyB0ZXh0IG9yIGNkYXRhc2VjdGlvbiBtb3ZlIHRvIG5leHQKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgLy9JZiB0aGUgbmV4dCBzaWJsaW5nIHdhcyBhbnl0aGluZyBidXQgdGV4dCBvcgotICAgICAgICAgICAgICAgIC8vY2RhdGFzZWN0aW9uIG9yIGFuIGVudGl0eSByZWZlcmVuY2UsIHN0b3Agc2VhcmNoIGFuZAotICAgICAgICAgICAgICAgIC8vcmV0dXJuIHRydWUKLSAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgbmV4dCA9IG5leHQuZ2V0TmV4dFNpYmxpbmcoKTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENoZWNrIGlmIGFuIEVudGl0eVJlZmVyZW5jZSBub2RlIGhhcyBUZXh0IE9ubHkgY2hpbGQgbm9kZXMKLSAgICAgKgotICAgICAqIEBwYXJhbSBub2RlCi0gICAgICogQHJldHVybiB0cnVlIC0gQ29udGFpbnMgdGV4dCBvbmx5IGNoaWxkcmVuCi0gICAgICovCi0gICAgcHJpdmF0ZSBib29sZWFuIGhhc1RleHRPbmx5Q2hpbGRyZW4oTm9kZSBub2RlKSB7Ci0KLSAgICAgICAgTm9kZSBjaGlsZCA9IG5vZGU7Ci0KLSAgICAgICAgaWYgKGNoaWxkID09IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotCi0gICAgICAgIGNoaWxkID0gY2hpbGQuZ2V0Rmlyc3RDaGlsZCgpOwotICAgICAgICB3aGlsZSAoY2hpbGQgIT0gbnVsbCkgewotICAgICAgICAgICAgaW50IHR5cGUgPSBjaGlsZC5nZXROb2RlVHlwZSgpOwotCi0gICAgICAgICAgICBpZiAodHlwZSA9PSBOb2RlLkVOVElUWV9SRUZFUkVOQ0VfTk9ERSkgewotICAgICAgICAgICAgICAgIHJldHVybiBoYXNUZXh0T25seUNoaWxkcmVuKGNoaWxkKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKHR5cGUgIT0gTm9kZS5URVhUX05PREUKLSAgICAgICAgICAgICAgICAgICAgJiYgdHlwZSAhPSBOb2RlLkNEQVRBX1NFQ1RJT05fTk9ERQotICAgICAgICAgICAgICAgICAgICAmJiB0eXBlICE9IE5vZGUuRU5USVRZX1JFRkVSRU5DRV9OT0RFKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2hpbGQgPSBjaGlsZC5nZXROZXh0U2libGluZygpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogTk9OLURPTTogUmV0dXJucyB3aGV0aGVyIHRoaXMgVGV4dCBpcyBpZ25vcmFibGUgd2hpdGVzcGFjZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0lnbm9yYWJsZVdoaXRlc3BhY2UoKSB7Ci0KLSAgICAgICAgaWYgKG5lZWRzU3luY0RhdGEoKSkgewotICAgICAgICAgICAgc3luY2hyb25pemVEYXRhKCk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGludGVybmFsSXNJZ25vcmFibGVXaGl0ZXNwYWNlKCk7Ci0KLSAgICB9IC8vIGlzSWdub3JhYmxlV2hpdGVzcGFjZSgpOmJvb2xlYW4KLQotCi0gICAgLy8KLSAgICAvLyBUZXh0IG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogQnJlYWsgYSB0ZXh0IG5vZGUgaW50byB0d28gc2libGluZyBub2Rlcy4gKE5vdGUgdGhhdCBpZiB0aGUgY3VycmVudCBub2RlCi0gICAgICogaGFzIG5vIHBhcmVudCwgdGhleSB3b24ndCB3aW5kIHVwIGFzICJzaWJsaW5ncyIgLS0gdGhleSdsbCBib3RoIGJlCi0gICAgICogb3JwaGFucy4pCi0gICAgICoKLSAgICAgKiBAcGFyYW0gb2Zmc2V0Ci0gICAgICogICAgICAgICAgICBUaGUgb2Zmc2V0IGF0IHdoaWNoIHRvIHNwbGl0LiBJZiBvZmZzZXQgaXMgYXQgdGhlIGVuZCBvZiB0aGUKLSAgICAgKiAgICAgICAgICAgIGF2YWlsYWJsZSBkYXRhLCB0aGUgc2Vjb25kIG5vZGUgd2lsbCBiZSBlbXB0eS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gQSByZWZlcmVuY2UgdG8gdGhlIG5ldyBub2RlIChjb250YWluaW5nIGRhdGEgYWZ0ZXIgdGhlIG9mZnNldAotICAgICAqICAgICAgICAgcG9pbnQpLiBUaGUgb3JpZ2luYWwgbm9kZSB3aWxsIGNvbnRhaW4gZGF0YSB1cCB0byB0aGF0IHBvaW50LgotICAgICAqCi0gICAgICogQHRocm93cyBET01FeGNlcHRpb24oSU5ERVhfU0laRV9FUlIpCi0gICAgICogICAgICAgICAgICAgaWYgb2Zmc2V0IGlzIDwwIG9yID5sZW5ndGguCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbihOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIpCi0gICAgICogICAgICAgICAgICAgaWYgbm9kZSBpcyByZWFkLW9ubHkuCi0gICAgICovCi0gICAgcHVibGljIFRleHQgc3BsaXRUZXh0KGludCBvZmZzZXQpCi0gICAgICAgIHRocm93cyBET01FeGNlcHRpb24gewotCi0gICAgICAgIGlmIChpc1JlYWRPbmx5KCkpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oCi0gICAgICAgICAgICBET01FeGNlcHRpb24uTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSLAotICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sICJOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIiLCBudWxsKSk7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAobmVlZHNTeW5jRGF0YSgpKSB7Ci0gICAgICAgICAgICBzeW5jaHJvbml6ZURhdGEoKTsKLSAgICAgICAgfQotICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgPiBkYXRhLmxlbmd0aCgpICkgewotICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uSU5ERVhfU0laRV9FUlIsCi0gICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwgIklOREVYX1NJWkVfRVJSIiwgbnVsbCkpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gc3BsaXQgdGV4dCBpbnRvIHR3byBzZXBhcmF0ZSBub2RlcwotICAgICAgICBUZXh0IG5ld1RleHQgPQotICAgICAgICAgICAgZ2V0T3duZXJEb2N1bWVudCgpLmNyZWF0ZVRleHROb2RlKGRhdGEuc3Vic3RyaW5nKG9mZnNldCkpOwotICAgICAgICBzZXROb2RlVmFsdWUoZGF0YS5zdWJzdHJpbmcoMCwgb2Zmc2V0KSk7Ci0KLSAgICAgICAgLy8gaW5zZXJ0IG5ldyB0ZXh0IG5vZGUKLSAgICAgICAgTm9kZSBwYXJlbnROb2RlID0gZ2V0UGFyZW50Tm9kZSgpOwotICAgICAgICBpZiAocGFyZW50Tm9kZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBwYXJlbnROb2RlLmluc2VydEJlZm9yZShuZXdUZXh0LCBuZXh0U2libGluZyk7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gbmV3VGV4dDsKLQotICAgIH0gLy8gc3BsaXRUZXh0KGludCk6VGV4dAotCi0KLSAgICAvKioKLSAgICAgKiBOT04tRE9NICh1c2VkIGJ5IERPTVBhcnNlcik6IFJlc2V0IGRhdGEgZm9yIHRoZSBub2RlLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHJlcGxhY2VEYXRhIChTdHJpbmcgdmFsdWUpewotICAgICAgICBkYXRhID0gdmFsdWU7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBOT04tRE9NICh1c2VkIGJ5IERPTVBhcnNlcjogU2V0cyBkYXRhIHRvIGVtcHR5IHN0cmluZy4KLSAgICAgKiAgUmV0dXJucyB0aGUgdmFsdWUgdGhlIGRhdGEgd2FzIHNldCB0by4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIHJlbW92ZURhdGEgKCl7Ci0gICAgICAgIFN0cmluZyBvbGRkYXRhPWRhdGE7Ci0gICAgICAgIGRhdGEgPSAiIjsKLSAgICAgICAgcmV0dXJuIG9sZGRhdGE7Ci0gICAgfQotCi19IC8vIGNsYXNzIFRleHRJbXBsCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vVHJlZVdhbGtlckltcGwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9UcmVlV2Fsa2VySW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyMDUzM2RkLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9UcmVlV2Fsa2VySW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTA3ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwMiwyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbTsKLQotaW1wb3J0IG9yZy53M2MuZG9tLkRPTUV4Y2VwdGlvbjsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotaW1wb3J0IG9yZy53M2MuZG9tLnRyYXZlcnNhbC5Ob2RlRmlsdGVyOwotaW1wb3J0IG9yZy53M2MuZG9tLnRyYXZlcnNhbC5UcmVlV2Fsa2VyOwotCi0vKiogVGhpcyBjbGFzcyBpbXBsZW1lbnRzIHRoZSBUcmVlV2Fsa2VyIGludGVyZmFjZS4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICovCi0KLXB1YmxpYyBjbGFzcyBUcmVlV2Fsa2VySW1wbCBpbXBsZW1lbnRzIFRyZWVXYWxrZXIgewotCi0gICAgLy8KLSAgICAvLyBEYXRhCi0gICAgLy8KLQotICAgIC8qKiBXaGVuIFRSVUUsIHRoZSBjaGlsZHJlbiBvZiBlbnRpdGVzIHJlZmVyZW5jZXMgYXJlIHJldHVybmVkIGluIHRoZSBpdGVyYXRvci4gKi8KLSAgICBwcml2YXRlIGJvb2xlYW4gZkVudGl0eVJlZmVyZW5jZUV4cGFuc2lvbiA9IGZhbHNlOwotICAgIC8qKiBUaGUgd2hhdFRvU2hvdyBtYXNrLiAqLwotICAgIGludCBmV2hhdFRvU2hvdyA9IE5vZGVGaWx0ZXIuU0hPV19BTEw7Ci0gICAgLyoqIFRoZSBOb2RlRmlsdGVyIHJlZmVyZW5jZS4gKi8KLSAgICBOb2RlRmlsdGVyIGZOb2RlRmlsdGVyOwotICAgIC8qKiBUaGUgY3VycmVudCBOb2RlLiAqLwotICAgIE5vZGUgZkN1cnJlbnROb2RlOwotICAgIC8qKiBUaGUgcm9vdCBOb2RlLiAqLwotICAgIE5vZGUgZlJvb3Q7Ci0KLSAgICAvLwotICAgIC8vIEltcGxlbWVudGF0aW9uIE5vdGU6IE5vIHN0YXRlIGlzIGtlcHQgZXhjZXB0IHRoZSBkYXRhIGFib3ZlCi0gICAgLy8gKGZXaGF0VG9TaG93LCBmTm9kZUZpbHRlciwgZkN1cnJlbnROb2RlLCBmUm9vdCkgc3VjaCB0aGF0Ci0gICAgLy8gc2V0dGVycyBjb3VsZCBiZSBjcmVhdGVkIGZvciB0aGVzZSBkYXRhIHZhbHVlcyBhbmQgdGhlCi0gICAgLy8gaW1wbGVtZW50YXRpb24gd2lsbCBzdGlsbCB3b3JrLgotCi0KLSAgICAvLwotICAgIC8vIENvbnN0cnVjdG9yCi0gICAgLy8KLQotICAgIC8qKiBQdWJsaWMgY29uc3RydWN0b3IgKi8KLSAgICBwdWJsaWMgVHJlZVdhbGtlckltcGwoTm9kZSByb290LAotICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgd2hhdFRvU2hvdywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgTm9kZUZpbHRlciBub2RlRmlsdGVyLAotICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGVudGl0eVJlZmVyZW5jZUV4cGFuc2lvbikgewotICAgICAgICBmQ3VycmVudE5vZGUgPSByb290OwotICAgICAgICBmUm9vdCA9IHJvb3Q7Ci0gICAgICAgIGZXaGF0VG9TaG93ID0gd2hhdFRvU2hvdzsKLSAgICAgICAgZk5vZGVGaWx0ZXIgPSBub2RlRmlsdGVyOwotICAgICAgICBmRW50aXR5UmVmZXJlbmNlRXhwYW5zaW9uID0gZW50aXR5UmVmZXJlbmNlRXhwYW5zaW9uOwotICAgIH0KLQotICAgIHB1YmxpYyBOb2RlIGdldFJvb3QoKSB7Ci0gICAgICAgIHJldHVybiBmUm9vdDsKLSAgICB9Ci0KLSAgICAvKiogUmV0dXJuIHRoZSB3aGF0VG9TaG93IHZhbHVlICovCi0gICAgcHVibGljIGludCAgICAgICAgICAgICAgICBnZXRXaGF0VG9TaG93KCkgewotICAgICAgICByZXR1cm4gZldoYXRUb1Nob3c7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0V2hhdFNob3coaW50IHdoYXRUb1Nob3cpewotICAgICAgICBmV2hhdFRvU2hvdyA9IHdoYXRUb1Nob3c7Ci0gICAgfQotICAgIC8qKiBSZXR1cm4gdGhlIE5vZGVGaWx0ZXIgKi8KLSAgICBwdWJsaWMgTm9kZUZpbHRlciAgICAgICAgIGdldEZpbHRlcigpIHsKLSAgICAgICAgcmV0dXJuIGZOb2RlRmlsdGVyOwotICAgIH0KLQotICAgIC8qKiBSZXR1cm4gd2hldGhlciBjaGlsZHJlbiBlbnRpdHkgcmVmZXJlbmNlcyBhcmUgaW5jbHVkZWQgaW4gdGhlIGl0ZXJhdG9yLiAqLwotICAgIHB1YmxpYyBib29sZWFuICAgICAgICAgICAgZ2V0RXhwYW5kRW50aXR5UmVmZXJlbmNlcygpIHsKLSAgICAgICAgcmV0dXJuIGZFbnRpdHlSZWZlcmVuY2VFeHBhbnNpb247Ci0gICAgfQotCi0gICAgLyoqIFJldHVybiB0aGUgY3VycmVudCBOb2RlLiAqLwotICAgIHB1YmxpYyBOb2RlICAgICAgICAgICAgICAgZ2V0Q3VycmVudE5vZGUoKSB7Ci0gICAgICAgIHJldHVybiBmQ3VycmVudE5vZGU7Ci0gICAgfQotICAgIC8qKiBSZXR1cm4gdGhlIGN1cnJlbnQgTm9kZS4gKi8KLSAgICBwdWJsaWMgdm9pZCAgICAgICAgICAgICAgIHNldEN1cnJlbnROb2RlKE5vZGUgbm9kZSkgewotICAgICAgICBpZiAobm9kZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBTdHJpbmcgbXNnID0gRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwgIk5PVF9TVVBQT1JURURfRVJSIiwgbnVsbCk7Ci0gICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSLCBtc2cpOwotICAgICAgICB9Ci0KLSAgICAgICAgZkN1cnJlbnROb2RlID0gbm9kZTsKLSAgICB9Ci0KLSAgICAvKiogUmV0dXJuIHRoZSBwYXJlbnQgTm9kZSBmcm9tIHRoZSBjdXJyZW50IG5vZGUsCi0gICAgICogIGFmdGVyIGFwcGx5aW5nIGZpbHRlciwgd2hhdFRvc2hvdy4KLSAgICAgKiAgSWYgcmVzdWx0IGlzIG5vdCBudWxsLCBzZXQgdGhlIGN1cnJlbnQgTm9kZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgTm9kZSAgICAgICAgICAgICAgIHBhcmVudE5vZGUoKSB7Ci0KLSAgICAgICAgaWYgKGZDdXJyZW50Tm9kZSA9PSBudWxsKSByZXR1cm4gbnVsbDsKLQotICAgICAgICBOb2RlIG5vZGUgPSBnZXRQYXJlbnROb2RlKGZDdXJyZW50Tm9kZSk7Ci0gICAgICAgIGlmIChub2RlICE9bnVsbCkgewotICAgICAgICAgICAgZkN1cnJlbnROb2RlID0gbm9kZTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbm9kZTsKLQotICAgIH0KLQotICAgIC8qKiBSZXR1cm4gdGhlIGZpcnN0IGNoaWxkIE5vZGUgZnJvbSB0aGUgY3VycmVudCBub2RlLAotICAgICAqICBhZnRlciBhcHBseWluZyBmaWx0ZXIsIHdoYXRUb3Nob3cuCi0gICAgICogIElmIHJlc3VsdCBpcyBub3QgbnVsbCwgc2V0IHRoZSBjdXJyZW50IE5vZGUuCi0gICAgICovCi0gICAgcHVibGljIE5vZGUgICAgICAgICAgICAgICBmaXJzdENoaWxkKCkgewotCi0gICAgICAgIGlmIChmQ3VycmVudE5vZGUgPT0gbnVsbCkgcmV0dXJuIG51bGw7Ci0KLSAgICAgICAgTm9kZSBub2RlID0gZ2V0Rmlyc3RDaGlsZChmQ3VycmVudE5vZGUpOwotICAgICAgICBpZiAobm9kZSAhPW51bGwpIHsKLSAgICAgICAgICAgIGZDdXJyZW50Tm9kZSA9IG5vZGU7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG5vZGU7Ci0gICAgfQotICAgIC8qKiBSZXR1cm4gdGhlIGxhc3QgY2hpbGQgTm9kZSBmcm9tIHRoZSBjdXJyZW50IG5vZGUsCi0gICAgICogIGFmdGVyIGFwcGx5aW5nIGZpbHRlciwgd2hhdFRvc2hvdy4KLSAgICAgKiAgSWYgcmVzdWx0IGlzIG5vdCBudWxsLCBzZXQgdGhlIGN1cnJlbnQgTm9kZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgTm9kZSAgICAgICAgICAgICAgIGxhc3RDaGlsZCgpIHsKLQotICAgICAgICBpZiAoZkN1cnJlbnROb2RlID09IG51bGwpIHJldHVybiBudWxsOwotCi0gICAgICAgIE5vZGUgbm9kZSA9IGdldExhc3RDaGlsZChmQ3VycmVudE5vZGUpOwotICAgICAgICBpZiAobm9kZSAhPW51bGwpIHsKLSAgICAgICAgICAgIGZDdXJyZW50Tm9kZSA9IG5vZGU7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG5vZGU7Ci0gICAgfQotCi0gICAgLyoqIFJldHVybiB0aGUgcHJldmlvdXMgc2libGluZyBOb2RlIGZyb20gdGhlIGN1cnJlbnQgbm9kZSwKLSAgICAgKiAgYWZ0ZXIgYXBwbHlpbmcgZmlsdGVyLCB3aGF0VG9zaG93LgotICAgICAqICBJZiByZXN1bHQgaXMgbm90IG51bGwsIHNldCB0aGUgY3VycmVudCBOb2RlLgotICAgICAqLwotICAgIHB1YmxpYyBOb2RlICAgICAgICAgICAgICAgcHJldmlvdXNTaWJsaW5nKCkgewotCi0gICAgICAgIGlmIChmQ3VycmVudE5vZGUgPT0gbnVsbCkgcmV0dXJuIG51bGw7Ci0KLSAgICAgICAgTm9kZSBub2RlID0gZ2V0UHJldmlvdXNTaWJsaW5nKGZDdXJyZW50Tm9kZSk7Ci0gICAgICAgIGlmIChub2RlICE9bnVsbCkgewotICAgICAgICAgICAgZkN1cnJlbnROb2RlID0gbm9kZTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbm9kZTsKLSAgICB9Ci0KLSAgICAvKiogUmV0dXJuIHRoZSBuZXh0IHNpYmxpbmcgTm9kZSBmcm9tIHRoZSBjdXJyZW50IG5vZGUsCi0gICAgICogIGFmdGVyIGFwcGx5aW5nIGZpbHRlciwgd2hhdFRvc2hvdy4KLSAgICAgKiAgSWYgcmVzdWx0IGlzIG5vdCBudWxsLCBzZXQgdGhlIGN1cnJlbnQgTm9kZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgTm9kZSAgICAgICAgICAgICAgIG5leHRTaWJsaW5nKCl7Ci0gICAgICAgIGlmIChmQ3VycmVudE5vZGUgPT0gbnVsbCkgcmV0dXJuIG51bGw7Ci0KLSAgICAgICAgTm9kZSBub2RlID0gZ2V0TmV4dFNpYmxpbmcoZkN1cnJlbnROb2RlKTsKLSAgICAgICAgaWYgKG5vZGUgIT1udWxsKSB7Ci0gICAgICAgICAgICBmQ3VycmVudE5vZGUgPSBub2RlOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBub2RlOwotICAgIH0KLQotICAgIC8qKiBSZXR1cm4gdGhlIHByZXZpb3VzIE5vZGUgZnJvbSB0aGUgY3VycmVudCBub2RlLAotICAgICAqICBhZnRlciBhcHBseWluZyBmaWx0ZXIsIHdoYXRUb3Nob3cuCi0gICAgICogIElmIHJlc3VsdCBpcyBub3QgbnVsbCwgc2V0IHRoZSBjdXJyZW50IE5vZGUuCi0gICAgICovCi0gICAgcHVibGljIE5vZGUgICAgICAgICAgICAgICBwcmV2aW91c05vZGUoKSB7Ci0gICAgICAgIE5vZGUgcmVzdWx0OwotCi0gICAgICAgIGlmIChmQ3VycmVudE5vZGUgPT0gbnVsbCkgcmV0dXJuIG51bGw7Ci0KLSAgICAgICAgLy8gZ2V0IHNpYmxpbmcKLSAgICAgICAgcmVzdWx0ID0gZ2V0UHJldmlvdXNTaWJsaW5nKGZDdXJyZW50Tm9kZSk7Ci0gICAgICAgIGlmIChyZXN1bHQgPT0gbnVsbCkgewotICAgICAgICAgICAgcmVzdWx0ID0gZ2V0UGFyZW50Tm9kZShmQ3VycmVudE5vZGUpOwotICAgICAgICAgICAgaWYgKHJlc3VsdCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZkN1cnJlbnROb2RlID0gcmVzdWx0OwotICAgICAgICAgICAgICAgIHJldHVybiBmQ3VycmVudE5vZGU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIGdldCB0aGUgbGFzdENoaWxkIG9mIHJlc3VsdC4KLSAgICAgICAgTm9kZSBsYXN0Q2hpbGQgID0gZ2V0TGFzdENoaWxkKHJlc3VsdCk7Ci0KLSAgICAgICAgTm9kZSBwcmV2ID0gbGFzdENoaWxkIDsKLSAgICAgICAgd2hpbGUgKGxhc3RDaGlsZCAhPSBudWxsKSB7Ci0gICAgICAgICAgcHJldiA9IGxhc3RDaGlsZCA7Ci0gICAgICAgICAgbGFzdENoaWxkID0gZ2V0TGFzdENoaWxkKHByZXYpIDsKLSAgICAgICAgfQotCi0gICAgICAgIGxhc3RDaGlsZCA9IHByZXYgOwotCi0gICAgICAgIC8vIGlmIHRoZXJlIGlzIGEgbGFzdENoaWxkIHdoaWNoIHBhc3NlcyBmaWx0ZXJzIHJldHVybiBpdC4KLSAgICAgICAgaWYgKGxhc3RDaGlsZCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmQ3VycmVudE5vZGUgPSBsYXN0Q2hpbGQ7Ci0gICAgICAgICAgICByZXR1cm4gZkN1cnJlbnROb2RlOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gb3RoZXJ3aXNlIHJldHVybiB0aGUgcHJldmlvdXMgc2libGluZy4KLSAgICAgICAgaWYgKHJlc3VsdCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmQ3VycmVudE5vZGUgPSByZXN1bHQ7Ci0gICAgICAgICAgICByZXR1cm4gZkN1cnJlbnROb2RlOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gb3RoZXJ3aXNlIHJldHVybiBudWxsLgotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICAvKiogUmV0dXJuIHRoZSBuZXh0IE5vZGUgZnJvbSB0aGUgY3VycmVudCBub2RlLAotICAgICAqICBhZnRlciBhcHBseWluZyBmaWx0ZXIsIHdoYXRUb3Nob3cuCi0gICAgICogIElmIHJlc3VsdCBpcyBub3QgbnVsbCwgc2V0IHRoZSBjdXJyZW50IE5vZGUuCi0gICAgICovCi0gICAgcHVibGljIE5vZGUgICAgICAgICAgICAgICBuZXh0Tm9kZSgpIHsKLQotICAgICAgICBpZiAoZkN1cnJlbnROb2RlID09IG51bGwpIHJldHVybiBudWxsOwotCi0gICAgICAgIE5vZGUgcmVzdWx0ID0gZ2V0Rmlyc3RDaGlsZChmQ3VycmVudE5vZGUpOwotCi0gICAgICAgIGlmIChyZXN1bHQgIT0gbnVsbCkgewotICAgICAgICAgICAgZkN1cnJlbnROb2RlID0gcmVzdWx0OwotICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKLSAgICAgICAgfQotCi0gICAgICAgIHJlc3VsdCA9IGdldE5leHRTaWJsaW5nKGZDdXJyZW50Tm9kZSk7Ci0KLSAgICAgICAgaWYgKHJlc3VsdCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmQ3VycmVudE5vZGUgPSByZXN1bHQ7Ci0gICAgICAgICAgICByZXR1cm4gcmVzdWx0OwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gcmV0dXJuIHBhcmVudCdzIDFzdCBzaWJsaW5nLgotICAgICAgICBOb2RlIHBhcmVudCA9IGdldFBhcmVudE5vZGUoZkN1cnJlbnROb2RlKTsKLSAgICAgICAgd2hpbGUgKHBhcmVudCAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXN1bHQgPSBnZXROZXh0U2libGluZyhwYXJlbnQpOwotICAgICAgICAgICAgaWYgKHJlc3VsdCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZkN1cnJlbnROb2RlID0gcmVzdWx0OwotICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIHBhcmVudCA9IGdldFBhcmVudE5vZGUocGFyZW50KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIGVuZCAsIHJldHVybiBudWxsCi0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKiBJbnRlcm5hbCBmdW5jdGlvbi4KLSAgICAgKiAgUmV0dXJuIHRoZSBwYXJlbnQgTm9kZSwgZnJvbSB0aGUgaW5wdXQgbm9kZQotICAgICAqICBhZnRlciBhcHBseWluZyBmaWx0ZXIsIHdoYXRUb3Nob3cuCi0gICAgICogIFRoZSBjdXJyZW50IG5vZGUgaXMgbm90IGNvbnN1bHRlZCBvciBzZXQuCi0gICAgICovCi0gICAgTm9kZSBnZXRQYXJlbnROb2RlKE5vZGUgbm9kZSkgewotCi0gICAgICAgIGlmIChub2RlID09IG51bGwgfHwgbm9kZSA9PSBmUm9vdCkgcmV0dXJuIG51bGw7Ci0KLSAgICAgICAgTm9kZSBuZXdOb2RlID0gbm9kZS5nZXRQYXJlbnROb2RlKCk7Ci0gICAgICAgIGlmIChuZXdOb2RlID09IG51bGwpICByZXR1cm4gbnVsbDsKLQotICAgICAgICBpbnQgYWNjZXB0ID0gYWNjZXB0Tm9kZShuZXdOb2RlKTsKLQotICAgICAgICBpZiAoYWNjZXB0ID09IE5vZGVGaWx0ZXIuRklMVEVSX0FDQ0VQVCkKLSAgICAgICAgICAgIHJldHVybiBuZXdOb2RlOwotICAgICAgICBlbHNlCi0gICAgICAgIC8vaWYgKGFjY2VwdCA9PSBOb2RlRmlsdGVyLlNLSVBfTk9ERSkgLy8gYW5kIFJFSkVDVCB0b28uCi0gICAgICAgIHsKLSAgICAgICAgICAgIHJldHVybiBnZXRQYXJlbnROb2RlKG5ld05vZGUpOwotICAgICAgICB9Ci0KLQotICAgIH0KLQotICAgIC8qKiBJbnRlcm5hbCBmdW5jdGlvbi4KLSAgICAgKiAgUmV0dXJuIHRoZSBuZXh0U2libGluZyBOb2RlLCBmcm9tIHRoZSBpbnB1dCBub2RlCi0gICAgICogIGFmdGVyIGFwcGx5aW5nIGZpbHRlciwgd2hhdFRvc2hvdy4KLSAgICAgKiAgVGhlIGN1cnJlbnQgbm9kZSBpcyBub3QgY29uc3VsdGVkIG9yIHNldC4KLSAgICAgKi8KLSAgICBOb2RlIGdldE5leHRTaWJsaW5nKE5vZGUgbm9kZSkgewotICAgICAgICAgICAgICAgIHJldHVybiBnZXROZXh0U2libGluZyhub2RlLCBmUm9vdCk7Ci0gICAgICAgIH0KLQotICAgIC8qKiBJbnRlcm5hbCBmdW5jdGlvbi4KLSAgICAgKiAgUmV0dXJuIHRoZSBuZXh0U2libGluZyBOb2RlLCBmcm9tIHRoZSBpbnB1dCBub2RlCi0gICAgICogIGFmdGVyIGFwcGx5aW5nIGZpbHRlciwgd2hhdFRvc2hvdy4KLSAgICAgKiAgTkVWRVIgVFJBVkVSU0VTIEFCT1ZFIFRIRSBTUEVDSUZJRUQgUk9PVCBOT0RFLgotICAgICAqICBUaGUgY3VycmVudCBub2RlIGlzIG5vdCBjb25zdWx0ZWQgb3Igc2V0LgotICAgICAqLwotICAgIE5vZGUgZ2V0TmV4dFNpYmxpbmcoTm9kZSBub2RlLCBOb2RlIHJvb3QpIHsKLQotICAgICAgICBpZiAobm9kZSA9PSBudWxsIHx8IG5vZGUgPT0gcm9vdCkgcmV0dXJuIG51bGw7Ci0KLSAgICAgICAgTm9kZSBuZXdOb2RlID0gbm9kZS5nZXROZXh0U2libGluZygpOwotICAgICAgICBpZiAobmV3Tm9kZSA9PSBudWxsKSB7Ci0KLSAgICAgICAgICAgIG5ld05vZGUgPSBub2RlLmdldFBhcmVudE5vZGUoKTsKLQotICAgICAgICAgICAgaWYgKG5ld05vZGUgPT0gbnVsbCB8fCBuZXdOb2RlID09IHJvb3QpICByZXR1cm4gbnVsbDsKLQotICAgICAgICAgICAgaW50IHBhcmVudEFjY2VwdCA9IGFjY2VwdE5vZGUobmV3Tm9kZSk7Ci0KLSAgICAgICAgICAgIGlmIChwYXJlbnRBY2NlcHQ9PU5vZGVGaWx0ZXIuRklMVEVSX1NLSVApIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZ2V0TmV4dFNpYmxpbmcobmV3Tm9kZSwgcm9vdCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0KLSAgICAgICAgaW50IGFjY2VwdCA9IGFjY2VwdE5vZGUobmV3Tm9kZSk7Ci0KLSAgICAgICAgaWYgKGFjY2VwdCA9PSBOb2RlRmlsdGVyLkZJTFRFUl9BQ0NFUFQpCi0gICAgICAgICAgICByZXR1cm4gbmV3Tm9kZTsKLSAgICAgICAgZWxzZQotICAgICAgICBpZiAoYWNjZXB0ID09IE5vZGVGaWx0ZXIuRklMVEVSX1NLSVApIHsKLSAgICAgICAgICAgIE5vZGUgZkNoaWxkID0gZ2V0Rmlyc3RDaGlsZChuZXdOb2RlKTsKLSAgICAgICAgICAgIGlmIChmQ2hpbGQgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJldHVybiBnZXROZXh0U2libGluZyhuZXdOb2RlLCByb290KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiBmQ2hpbGQ7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICAvL2lmIChhY2NlcHQgPT0gTm9kZUZpbHRlci5SRUpFQ1RfTk9ERSkKLSAgICAgICAgewotICAgICAgICAgICAgcmV0dXJuIGdldE5leHRTaWJsaW5nKG5ld05vZGUsIHJvb3QpOwotICAgICAgICB9Ci0KLSAgICB9IC8vIGdldE5leHRTaWJsaW5nKE5vZGUgbm9kZSkgewotCi0gICAgLyoqIEludGVybmFsIGZ1bmN0aW9uLgotICAgICAqICBSZXR1cm4gdGhlIHByZXZpb3VzIHNpYmxpbmcgTm9kZSwgZnJvbSB0aGUgaW5wdXQgbm9kZQotICAgICAqICBhZnRlciBhcHBseWluZyBmaWx0ZXIsIHdoYXRUb3Nob3cuCi0gICAgICogIFRoZSBjdXJyZW50IG5vZGUgaXMgbm90IGNvbnN1bHRlZCBvciBzZXQuCi0gICAgICovCi0gICAgTm9kZSBnZXRQcmV2aW91c1NpYmxpbmcoTm9kZSBub2RlKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGdldFByZXZpb3VzU2libGluZyhub2RlLCBmUm9vdCk7Ci0gICAgICAgIH0KLQotICAgIC8qKiBJbnRlcm5hbCBmdW5jdGlvbi4KLSAgICAgKiAgUmV0dXJuIHRoZSBwcmV2aW91c1NpYmxpbmcgTm9kZSwgZnJvbSB0aGUgaW5wdXQgbm9kZQotICAgICAqICBhZnRlciBhcHBseWluZyBmaWx0ZXIsIHdoYXRUb3Nob3cuCi0gICAgICAgICAqICBORVZFUiBUUkFWRVJTRVMgQUJPVkUgVEhFIFNQRUNJRklFRCBST09UIE5PREUuCi0gICAgICogIFRoZSBjdXJyZW50IG5vZGUgaXMgbm90IGNvbnN1bHRlZCBvciBzZXQuCi0gICAgICovCi0gICAgTm9kZSBnZXRQcmV2aW91c1NpYmxpbmcoTm9kZSBub2RlLCBOb2RlIHJvb3QpIHsKLQotICAgICAgICBpZiAobm9kZSA9PSBudWxsIHx8IG5vZGUgPT0gcm9vdCkgcmV0dXJuIG51bGw7Ci0KLSAgICAgICAgTm9kZSBuZXdOb2RlID0gbm9kZS5nZXRQcmV2aW91c1NpYmxpbmcoKTsKLSAgICAgICAgaWYgKG5ld05vZGUgPT0gbnVsbCkgewotCi0gICAgICAgICAgICBuZXdOb2RlID0gbm9kZS5nZXRQYXJlbnROb2RlKCk7Ci0gICAgICAgICAgICBpZiAobmV3Tm9kZSA9PSBudWxsIHx8IG5ld05vZGUgPT0gcm9vdCkgIHJldHVybiBudWxsOwotCi0gICAgICAgICAgICBpbnQgcGFyZW50QWNjZXB0ID0gYWNjZXB0Tm9kZShuZXdOb2RlKTsKLQotICAgICAgICAgICAgaWYgKHBhcmVudEFjY2VwdD09Tm9kZUZpbHRlci5GSUxURVJfU0tJUCkgewotICAgICAgICAgICAgICAgIHJldHVybiBnZXRQcmV2aW91c1NpYmxpbmcobmV3Tm9kZSwgcm9vdCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0KLSAgICAgICAgaW50IGFjY2VwdCA9IGFjY2VwdE5vZGUobmV3Tm9kZSk7Ci0KLSAgICAgICAgaWYgKGFjY2VwdCA9PSBOb2RlRmlsdGVyLkZJTFRFUl9BQ0NFUFQpCi0gICAgICAgICAgICByZXR1cm4gbmV3Tm9kZTsKLSAgICAgICAgZWxzZQotICAgICAgICBpZiAoYWNjZXB0ID09IE5vZGVGaWx0ZXIuRklMVEVSX1NLSVApIHsKLSAgICAgICAgICAgIE5vZGUgZkNoaWxkID0gIGdldExhc3RDaGlsZChuZXdOb2RlKTsKLSAgICAgICAgICAgIGlmIChmQ2hpbGQgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJldHVybiBnZXRQcmV2aW91c1NpYmxpbmcobmV3Tm9kZSwgcm9vdCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gZkNoaWxkOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgLy9pZiAoYWNjZXB0ID09IE5vZGVGaWx0ZXIuUkVKRUNUX05PREUpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHJldHVybiBnZXRQcmV2aW91c1NpYmxpbmcobmV3Tm9kZSwgcm9vdCk7Ci0gICAgICAgIH0KLQotICAgIH0gLy8gZ2V0UHJldmlvdXNTaWJsaW5nKE5vZGUgbm9kZSkgewotCi0gICAgLyoqIEludGVybmFsIGZ1bmN0aW9uLgotICAgICAqICBSZXR1cm4gdGhlIGZpcnN0IGNoaWxkIE5vZGUsIGZyb20gdGhlIGlucHV0IG5vZGUKLSAgICAgKiAgYWZ0ZXIgYXBwbHlpbmcgZmlsdGVyLCB3aGF0VG9zaG93LgotICAgICAqICBUaGUgY3VycmVudCBub2RlIGlzIG5vdCBjb25zdWx0ZWQgb3Igc2V0LgotICAgICAqLwotICAgIE5vZGUgZ2V0Rmlyc3RDaGlsZChOb2RlIG5vZGUpIHsKLSAgICAgICAgaWYgKG5vZGUgPT0gbnVsbCkgcmV0dXJuIG51bGw7Ci0KLSAgICAgICAgaWYgKCAhZkVudGl0eVJlZmVyZW5jZUV4cGFuc2lvbgotICAgICAgICAgICAgICYmIG5vZGUuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLkVOVElUWV9SRUZFUkVOQ0VfTk9ERSkKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICBOb2RlIG5ld05vZGUgPSBub2RlLmdldEZpcnN0Q2hpbGQoKTsKLSAgICAgICAgaWYgKG5ld05vZGUgPT0gbnVsbCkgIHJldHVybiBudWxsOwotICAgICAgICBpbnQgYWNjZXB0ID0gYWNjZXB0Tm9kZShuZXdOb2RlKTsKLQotICAgICAgICBpZiAoYWNjZXB0ID09IE5vZGVGaWx0ZXIuRklMVEVSX0FDQ0VQVCkKLSAgICAgICAgICAgIHJldHVybiBuZXdOb2RlOwotICAgICAgICBlbHNlCi0gICAgICAgIGlmIChhY2NlcHQgPT0gTm9kZUZpbHRlci5GSUxURVJfU0tJUAotICAgICAgICAgICAgJiYgbmV3Tm9kZS5oYXNDaGlsZE5vZGVzKCkpCi0gICAgICAgIHsKLSAgICAgICAgICAgIE5vZGUgZkNoaWxkID0gZ2V0Rmlyc3RDaGlsZChuZXdOb2RlKTsKLQotICAgICAgICAgICAgaWYgKGZDaGlsZCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGdldE5leHRTaWJsaW5nKG5ld05vZGUsIG5vZGUpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIGZDaGlsZDsKLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgIC8vaWYgKGFjY2VwdCA9PSBOb2RlRmlsdGVyLlJFSkVDVF9OT0RFKQotICAgICAgICB7Ci0gICAgICAgICAgICByZXR1cm4gZ2V0TmV4dFNpYmxpbmcobmV3Tm9kZSwgbm9kZSk7Ci0gICAgICAgIH0KLQotCi0gICAgfQotCi0gICAgLyoqIEludGVybmFsIGZ1bmN0aW9uLgotICAgICAqICBSZXR1cm4gdGhlIGxhc3QgY2hpbGQgTm9kZSwgZnJvbSB0aGUgaW5wdXQgbm9kZQotICAgICAqICBhZnRlciBhcHBseWluZyBmaWx0ZXIsIHdoYXRUb3Nob3cuCi0gICAgICogIFRoZSBjdXJyZW50IG5vZGUgaXMgbm90IGNvbnN1bHRlZCBvciBzZXQuCi0gICAgICovCi0gICAgTm9kZSBnZXRMYXN0Q2hpbGQoTm9kZSBub2RlKSB7Ci0KLSAgICAgICAgaWYgKG5vZGUgPT0gbnVsbCkgcmV0dXJuIG51bGw7Ci0KLSAgICAgICAgaWYgKCAhZkVudGl0eVJlZmVyZW5jZUV4cGFuc2lvbgotICAgICAgICAgICAgICYmIG5vZGUuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLkVOVElUWV9SRUZFUkVOQ0VfTk9ERSkKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotCi0gICAgICAgIE5vZGUgbmV3Tm9kZSA9IG5vZGUuZ2V0TGFzdENoaWxkKCk7Ci0gICAgICAgIGlmIChuZXdOb2RlID09IG51bGwpICByZXR1cm4gbnVsbDsKLQotICAgICAgICBpbnQgYWNjZXB0ID0gYWNjZXB0Tm9kZShuZXdOb2RlKTsKLQotICAgICAgICBpZiAoYWNjZXB0ID09IE5vZGVGaWx0ZXIuRklMVEVSX0FDQ0VQVCkKLSAgICAgICAgICAgIHJldHVybiBuZXdOb2RlOwotICAgICAgICBlbHNlCi0gICAgICAgIGlmIChhY2NlcHQgPT0gTm9kZUZpbHRlci5GSUxURVJfU0tJUAotICAgICAgICAgICAgJiYgbmV3Tm9kZS5oYXNDaGlsZE5vZGVzKCkpCi0gICAgICAgIHsKLSAgICAgICAgICAgIE5vZGUgbENoaWxkID0gZ2V0TGFzdENoaWxkKG5ld05vZGUpOwotICAgICAgICAgICAgaWYgKGxDaGlsZCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGdldFByZXZpb3VzU2libGluZyhuZXdOb2RlLCBub2RlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiBsQ2hpbGQ7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICAvL2lmIChhY2NlcHQgPT0gTm9kZUZpbHRlci5SRUpFQ1RfTk9ERSkKLSAgICAgICAgewotICAgICAgICAgICAgcmV0dXJuIGdldFByZXZpb3VzU2libGluZyhuZXdOb2RlLCBub2RlKTsKLSAgICAgICAgfQotCi0KLSAgICB9Ci0KLSAgICAvKiogSW50ZXJuYWwgZnVuY3Rpb24uCi0gICAgICogIFRoZSBub2RlIHdoYXRUb1Nob3cgYW5kIHRoZSBmaWx0ZXIgYXJlIGNvbWJpbmVkIGludG8gb25lIHJlc3VsdC4gKi8KLSAgICBzaG9ydCBhY2NlcHROb2RlKE5vZGUgbm9kZSkgewotICAgICAgICAvKioqCi0gICAgICAgICA3LjEuMi40LiBGaWx0ZXJzIGFuZCB3aGF0VG9TaG93IGZsYWdzCi0KLSAgICAgICAgIEl0ZXJhdG9yIGFuZCBUcmVlV2Fsa2VyIGFwcGx5IHdoYXRUb1Nob3cgZmxhZ3MgYmVmb3JlIGFwcGx5aW5nIEZpbHRlcnMuIElmIGEgbm9kZSBpcyByZWplY3RlZCBieSB0aGUKLSAgICAgICAgIGFjdGl2ZSB3aGF0VG9TaG93IGZsYWdzLCBhIEZpbHRlciB3aWxsIG5vdCBiZSBjYWxsZWQgdG8gZXZhbHVhdGUgdGhhdCBub2RlLiBXaGVuIGEgbm9kZSBpcyByZWplY3RlZCBieQotICAgICAgICAgdGhlIGFjdGl2ZSB3aGF0VG9TaG93IGZsYWdzLCBjaGlsZHJlbiBvZiB0aGF0IG5vZGUgd2lsbCBzdGlsbCBiZSBjb25zaWRlcmVkLCBhbmQgRmlsdGVycyBtYXkgYmUgY2FsbGVkIHRvCi0gICAgICAgICBldmFsdWF0ZSB0aGVtLgotICAgICAgICAgKioqLwotCi0gICAgICAgIGlmIChmTm9kZUZpbHRlciA9PSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAoICggZldoYXRUb1Nob3cgJiAoMSA8PCBub2RlLmdldE5vZGVUeXBlKCktMSkpICE9IDApIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gTm9kZUZpbHRlci5GSUxURVJfQUNDRVBUOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gTm9kZUZpbHRlci5GSUxURVJfU0tJUDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIGlmICgoZldoYXRUb1Nob3cgJiAoMSA8PCBub2RlLmdldE5vZGVUeXBlKCktMSkpICE9IDAgKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZOb2RlRmlsdGVyLmFjY2VwdE5vZGUobm9kZSk7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIC8vIFdoYXQgdG8gc2hvdyBoYXMgZmFpbGVkLiBTZWUgYWJvdmUgZXhjZXJwdCBmcm9tIHNwZWMuCi0gICAgICAgICAgICAgICAgLy8gRXF1aXZhbGVudCB0byBGSUxURVJfU0tJUC4KLSAgICAgICAgICAgICAgICByZXR1cm4gTm9kZUZpbHRlci5GSUxURVJfU0tJUDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9ldmVudHMvRXZlbnRJbXBsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vZXZlbnRzL0V2ZW50SW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4M2EwODVlLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9ldmVudHMvRXZlbnRJbXBsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMzUgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDAyLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbS5ldmVudHM7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5ldmVudHMuRXZlbnQ7Ci1pbXBvcnQgb3JnLnczYy5kb20uZXZlbnRzLkV2ZW50VGFyZ2V0OwotCi0vKioKLSAqIEV2ZW50SW1wbCBpcyBhbiBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgYmFzaWMgImdlbmVyaWMiIERPTSBMZXZlbCAyIEV2ZW50Ci0gKiBvYmplY3QuIEl0IG1heSBiZSBzdWJjbGFzc2VkIGJ5IG1vcmUgc3BlY2lhbGl6ZWQgZXZlbnQgc2V0cy4KLSAqIE5vdGUgdGhhdCBpbiBvdXIgaW1wbGVtZW50YXRpb24sIGV2ZW50cyBhcmUgcmUtZGlzcGF0Y2hhYmxlIChkaXNwYXRjaAotICogY2xlYXJzIHRoZSBzdG9wUHJvcGFnYXRpb24gYW5kIHByZXZlbnREZWZhdWx0IGZsYWdzIGJlZm9yZSBpdCBzdGFydHMpOwotICogSSBiZWxpZXZlIHRoYXQgaXMgdGhlIERPTSdzIGludGVudCBidXQgSSBkb24ndCBzZWUgYW4gZXhwbGljaXQgc3RhdGVtZW50Ci0gKiB0byB0aGlzIGVmZmVjdC4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICovCi1wdWJsaWMgY2xhc3MgRXZlbnRJbXBsIGltcGxlbWVudHMgRXZlbnQKLXsKLSAgICBwdWJsaWMgU3RyaW5nIHR5cGU9bnVsbDsKLSAgICBwdWJsaWMgRXZlbnRUYXJnZXQgdGFyZ2V0OwotICAgIHB1YmxpYyBFdmVudFRhcmdldCBjdXJyZW50VGFyZ2V0OwotICAgIHB1YmxpYyBzaG9ydCBldmVudFBoYXNlOwotICAgIHB1YmxpYyBib29sZWFuIGluaXRpYWxpemVkPWZhbHNlLCBidWJibGVzPXRydWUsIGNhbmNlbGFibGU9ZmFsc2U7Ci0gICAgcHVibGljIGJvb2xlYW4gc3RvcFByb3BhZ2F0aW9uPWZhbHNlLCBwcmV2ZW50RGVmYXVsdD1mYWxzZTsKLQotICAgIHByb3RlY3RlZCBsb25nIHRpbWVTdGFtcCA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOwotCi0gICAgLyoqIFRoZSBET00gZG9lc24ndCBkZWFsIHdpdGggY29uc3RydWN0b3JzLCBzbyBpbnN0ZWFkIHdlIGhhdmUgYW4KLSAgICAgICAgaW5pdGlhbGl6ZXIgY2FsbCB0byBzZXQgbW9zdCBvZiB0aGUgcmVhZC1vbmx5IGZpZWxkcy4gVGhlCi0gICAgICAgIG90aGVycyBhcmUgc2V0LCBhbmQgcmVzZXQsIGJ5IHRoZSBldmVudCBzdWJzeXN0ZW0gZHVyaW5nIGRpc3BhdGNoLgotICAgICAgICA8cD4KLSAgICAgICAgTm90ZSB0aGF0IGluaXQoKSAtLSBhbmQgdGhlIHN1YmNsYXNzLXNwZWNpZmljIGluaXRXaGF0ZXZlcigpIGNhbGxzIC0tCi0gICAgICAgIG1heSBiZSByZWludm9rZWQuIEF0IGxlYXN0IG9uZSBpbml0aWFsaXphdGlvbiBpcyByZXF1aXJlZDsgcmVwZWF0ZWQKLSAgICAgICAgaW5pdGlhbGl6YXRpb25zIG92ZXJ3cml0ZSB0aGUgZXZlbnQgd2l0aCBuZXcgdmFsdWVzIG9mIHRoZWlyCi0gICAgICAgIHBhcmFtZXRlcnMuCi0gICAgKi8KLSAgICBwdWJsaWMgdm9pZCBpbml0RXZlbnQoU3RyaW5nIGV2ZW50VHlwZUFyZywgYm9vbGVhbiBjYW5CdWJibGVBcmcsCi0gICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGNhbmNlbGFibGVBcmcpCi0gICAgewotICAgICAgICAgICAgdHlwZT1ldmVudFR5cGVBcmc7Ci0gICAgICAgICAgICBidWJibGVzPWNhbkJ1YmJsZUFyZzsKLSAgICAgICAgICAgIGNhbmNlbGFibGU9Y2FuY2VsYWJsZUFyZzsKLQotICAgICAgICAgICAgaW5pdGlhbGl6ZWQ9dHJ1ZTsKLSAgICB9Ci0KLSAgICAvKiogQHJldHVybiB0cnVlIGlmZiB0aGlzIEV2ZW50IGlzIG9mIGEgY2xhc3MgYW5kIHR5cGUgd2hpY2ggc3VwcG9ydHMKLSAgICAgICAgYnViYmxpbmcuIEluIHRoZSBnZW5lcmljIGNhc2UsIHRoaXMgaXMgVHJ1ZS4KLSAgICAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXRCdWJibGVzKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBidWJibGVzOwotICAgIH0KLQotICAgIC8qKiBAcmV0dXJuIHRydWUgaWZmIHRoaXMgRXZlbnQgaXMgb2YgYSBjbGFzcyBhbmQgdHlwZSB3aGljaCAoYSkgaGFzIGEKLSAgICAgICAgRGVmYXVsdCBCZWhhdmlvciBpbiB0aGlzIERPTSwgYW5kIChiKWFsbG93cyBjYW5jZWxsYXRpb24gKGJsb2NraW5nKQotICAgICAgICBvZiB0aGF0IGJlaGF2aW9yLiBJbiB0aGUgZ2VuZXJpYyBjYXNlLCB0aGlzIGlzIEZhbHNlLgotICAgICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGdldENhbmNlbGFibGUoKQotICAgIHsKLSAgICAgICAgcmV0dXJuIGNhbmNlbGFibGU7Ci0gICAgfQotCi0gICAgLyoqIEByZXR1cm4gdGhlIE5vZGUgKEV2ZW50VGFyZ2V0KSB3aG9zZSBFdmVudExpc3RlbmVycyBhcmUgY3VycmVudGx5Ci0gICAgICAgIGJlaW5nIHByb2Nlc3NlZC4gRHVyaW5nIGNhcHR1cmUgYW5kIGJ1YmJsZSBwaGFzZXMsIHRoaXMgbWF5IG5vdCBiZQotICAgICAgICB0aGUgdGFyZ2V0IG5vZGUuICovCi0gICAgcHVibGljIEV2ZW50VGFyZ2V0IGdldEN1cnJlbnRUYXJnZXQoKQotICAgIHsKLSAgICAgICAgcmV0dXJuIGN1cnJlbnRUYXJnZXQ7Ci0gICAgfQotCi0gICAgLyoqIEByZXR1cm4gdGhlIGN1cnJlbnQgcHJvY2Vzc2luZyBwaGFzZSBmb3IgdGhpcyBldmVudCAtLQotICAgICAgICBDQVBUVVJJTkdfUEhBU0UsIEFUX1RBUkdFVCwgQlVCQkxJTkdfUEhBU0UuIChUaGVyZSBtYXkgYmUKLSAgICAgICAgYW4gaW50ZXJuYWwgREVGQVVMVF9QSEFTRSBhcyB3ZWxsLCBidXQgdGhlIHVzZXJzIHdvbid0IHNlZSBpdC4pICovCi0gICAgcHVibGljIHNob3J0IGdldEV2ZW50UGhhc2UoKQotICAgIHsKLSAgICAgICAgcmV0dXJuIGV2ZW50UGhhc2U7Ci0gICAgfQotCi0gICAgLyoqIEByZXR1cm4gdGhlIEV2ZW50VGFyZ2V0IChOb2RlKSB0byB3aGljaCB0aGUgZXZlbnQgd2FzIG9yaWdpbmFsbHkKLSAgICAgICAgZGlzcGF0Y2hlZC4KLSAgICAgICAgKi8KLSAgICBwdWJsaWMgRXZlbnRUYXJnZXQgZ2V0VGFyZ2V0KCkKLSAgICB7Ci0gICAgICAgIHJldHVybiB0YXJnZXQ7Ci0gICAgfQotCi0gICAgLyoqIEByZXR1cm4gZXZlbnQgbmFtZSBhcyBhIHN0cmluZwotICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRUeXBlKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiB0eXBlOwotICAgIH0KLQotICAgIHB1YmxpYyBsb25nIGdldFRpbWVTdGFtcCgpIHsKLSAgICAgICAgcmV0dXJuIHRpbWVTdGFtcDsKLSAgICB9Ci0KLSAgICAvKiogQ2F1c2VzIGV4aXQgZnJvbSBpbi1wcm9ncmVzcyBldmVudCBkaXNwYXRjaCBiZWZvcmUgdGhlIG5leHQKLSAgICAgICAgY3VycmVudFRhcmdldCBpcyBzZWxlY3RlZC4gUmVwbGFjZXMgdGhlIHByZXZlbnRCdWJibGUoKSBhbmQKLSAgICAgICAgcHJldmVudENhcHR1cmUoKSBtZXRob2RzIHdoaWNoIHdlcmUgcHJlc2VudCBpbiBlYXJseSBkcmFmdHM7Ci0gICAgICAgIHRoZXkgbWF5IGJlIHJlaW50cm9kdWNlZCBpbiBmdXR1cmUgbGV2ZWxzIG9mIHRoZSBET00uICovCi0gICAgcHVibGljIHZvaWQgc3RvcFByb3BhZ2F0aW9uKCkKLSAgICB7Ci0gICAgICAgIHN0b3BQcm9wYWdhdGlvbj10cnVlOwotICAgIH0KLQotICAgIC8qKiBQcmV2ZW50cyBhbnkgZGVmYXVsdCBwcm9jZXNzaW5nIGJ1aWx0IGludG8gdGhlIHRhcmdldCBub2RlIGZyb20KLSAgICAgICAgb2NjdXJyaW5nLgotICAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBwcmV2ZW50RGVmYXVsdCgpCi0gICAgewotICAgICAgICBwcmV2ZW50RGVmYXVsdD10cnVlOwotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL2V2ZW50cy9NdXRhdGlvbkV2ZW50SW1wbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL2V2ZW50cy9NdXRhdGlvbkV2ZW50SW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzMjg3MDM0Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9ldmVudHMvTXV0YXRpb25FdmVudEltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExMiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5kb20uZXZlbnRzOwotCi1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcudzNjLmRvbS5ldmVudHMuTXV0YXRpb25FdmVudDsKLQotLyoqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICovCi0KLXB1YmxpYyBjbGFzcyBNdXRhdGlvbkV2ZW50SW1wbAotZXh0ZW5kcyBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbS5ldmVudHMuRXZlbnRJbXBsCi1pbXBsZW1lbnRzIE11dGF0aW9uRXZlbnQKLXsKLSAgICBOb2RlIHJlbGF0ZWROb2RlPW51bGw7Ci0gICAgU3RyaW5nIHByZXZWYWx1ZT1udWxsLG5ld1ZhbHVlPW51bGwsYXR0ck5hbWU9bnVsbDsKLSAgICAvLyBSRVZJU0lUOiBUaGUgRE9NIExldmVsIDIgUFIgaGFzIGEgYnVnOiB0aGUgaW5pdCBtZXRob2Qgc2hvdWxkIGxldCB0aGlzCi0gICAgLy8gYXR0cmlidXRlIGJlIHNwZWNpZmllZC4gU2luY2UgaXQgZG9lc24ndCB3ZSBoYXZlIHRvIGdpdmUgd3JpdGUgYWNjZXNzLgotICAgIHB1YmxpYyBzaG9ydCBhdHRyQ2hhbmdlOwotCi0gICAgLy8gTk9OLURPTSBDT05TVEFOVFM6IFN0b3JhZ2UgZWZmaWNpZW5jeSwgYXZvaWQgcmlzayBvZiB0eXBvcy4KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBET01fU1VCVFJFRV9NT0RJRklFRCA9ICJET01TdWJ0cmVlTW9kaWZpZWQiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIERPTV9OT0RFX0lOU0VSVEVEID0gIkRPTU5vZGVJbnNlcnRlZCI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRE9NX05PREVfUkVNT1ZFRCA9ICJET01Ob2RlUmVtb3ZlZCI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRE9NX05PREVfUkVNT1ZFRF9GUk9NX0RPQ1VNRU5UID0gIkRPTU5vZGVSZW1vdmVkRnJvbURvY3VtZW50IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBET01fTk9ERV9JTlNFUlRFRF9JTlRPX0RPQ1VNRU5UID0gIkRPTU5vZGVJbnNlcnRlZEludG9Eb2N1bWVudCI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRE9NX0FUVFJfTU9ESUZJRUQgPSAiRE9NQXR0ck1vZGlmaWVkIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBET01fQ0hBUkFDVEVSX0RBVEFfTU9ESUZJRUQgPSAiRE9NQ2hhcmFjdGVyRGF0YU1vZGlmaWVkIjsKLQotICAgIC8qKiBAcmV0dXJuIHRoZSBuYW1lIG9mIHRoZSBBdHRyIHdoaWNoCi0gICAgICAgIGNoYW5nZWQsIGZvciBET01BdHRyTW9kaWZpZWQgZXZlbnRzLgotICAgICAgICBVbmRlZmluZWQgZm9yIG90aGVycy4KLSAgICAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEF0dHJOYW1lKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBhdHRyTmFtZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiAgPGNvZGU+YXR0ckNoYW5nZTwvY29kZT4gaW5kaWNhdGVzIHRoZSB0eXBlIG9mIGNoYW5nZSB3aGljaCB0cmlnZ2VyZWQKLSAgICAgKiB0aGUgRE9NQXR0ck1vZGlmaWVkIGV2ZW50LiBUaGUgdmFsdWVzIGNhbiBiZSA8Y29kZT5NT0RJRklDQVRJT048L2NvZGU+Ci0gICAgICogLCA8Y29kZT5BRERJVElPTjwvY29kZT4sIG9yIDxjb2RlPlJFTU9WQUw8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBzaG9ydCBnZXRBdHRyQ2hhbmdlKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBhdHRyQ2hhbmdlOwotICAgIH0KLQotICAgIC8qKiBAcmV0dXJuIHRoZSBuZXcgc3RyaW5nIHZhbHVlIG9mIHRoZSBBdHRyIGZvciBET01BdHRyTW9kaWZpZWQgZXZlbnRzLCBvcgotICAgICAgICBvZiB0aGUgQ2hhcmFjdGVyRGF0YSBub2RlIGZvciBET01DaGFyRGF0YU1vZGlmZWQgZXZlbnRzLgotICAgICAgICBVbmRlZmluZWQgZm9yIG90aGVycy4KLSAgICAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE5ld1ZhbHVlKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBuZXdWYWx1ZTsKLSAgICB9Ci0KLSAgICAvKiogQHJldHVybiB0aGUgcHJldmlvdXMgc3RyaW5nIHZhbHVlIG9mIHRoZSBBdHRyIGZvciBET01BdHRyTW9kaWZpZWQgZXZlbnRzLCBvcgotICAgICAgICBvZiB0aGUgQ2hhcmFjdGVyRGF0YSBub2RlIGZvciBET01DaGFyRGF0YU1vZGlmZWQgZXZlbnRzLgotICAgICAgICBVbmRlZmluZWQgZm9yIG90aGVycy4KLSAgICAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFByZXZWYWx1ZSgpCi0gICAgewotICAgICAgICByZXR1cm4gcHJldlZhbHVlOwotICAgIH0KLQotICAgIC8qKiBAcmV0dXJuIGEgTm9kZSByZWxhdGVkIHRvIHRoaXMgZXZlbnQsIG90aGVyIHRoYW4gdGhlIHRhcmdldCB0aGF0IHRoZQotICAgICAgICBub2RlIHdhcyBkaXNwYXRjaGVkIHRvLiBGb3IgRE9NTm9kZVJlbW92ZWQsIGl0IGlzIHRoZSBub2RlIHdoaWNoCi0gICAgICAgIHdhcyByZW1vdmVkLgotICAgICAgICBObyBvdGhlciB1c2VzIGFyZSBjdXJyZW50bHkgZGVmaW5lZC4KLSAgICAgICAgKi8KLSAgICBwdWJsaWMgTm9kZSBnZXRSZWxhdGVkTm9kZSgpCi0gICAgewotICAgICAgICByZXR1cm4gcmVsYXRlZE5vZGU7Ci0gICAgfQotCi0gICAgLyoqIEluaXRpYWxpemUgYSBtdXRhdGlvbiBldmVudCwgb3Igb3ZlcndyaXRlIHRoZSBldmVudCdzIGN1cnJlbnQKLSAgICAgICAgc2V0dGluZ3Mgd2l0aCBuZXcgdmFsdWVzIG9mIHRoZSBwYXJhbWV0ZXJzLgotICAgICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGluaXRNdXRhdGlvbkV2ZW50KFN0cmluZyB0eXBlQXJnLCBib29sZWFuIGNhbkJ1YmJsZUFyZywKLSAgICAgICAgYm9vbGVhbiBjYW5jZWxhYmxlQXJnLCBOb2RlIHJlbGF0ZWROb2RlQXJnLCBTdHJpbmcgcHJldlZhbHVlQXJnLAotICAgICAgICBTdHJpbmcgbmV3VmFsdWVBcmcsIFN0cmluZyBhdHRyTmFtZUFyZywgc2hvcnQgYXR0ckNoYW5nZUFyZykKLSAgICB7Ci0gICAgICAgIHJlbGF0ZWROb2RlPXJlbGF0ZWROb2RlQXJnOwotICAgICAgICBwcmV2VmFsdWU9cHJldlZhbHVlQXJnOwotICAgICAgICBuZXdWYWx1ZT1uZXdWYWx1ZUFyZzsKLSAgICAgICAgYXR0ck5hbWU9YXR0ck5hbWVBcmc7Ci0gICAgICAgIGF0dHJDaGFuZ2U9YXR0ckNoYW5nZUFyZzsKLSAgICAgICAgc3VwZXIuaW5pdEV2ZW50KHR5cGVBcmcsY2FuQnViYmxlQXJnLGNhbmNlbGFibGVBcmcpOwotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL29yZy5hcGFjaGUueGVyY2VzLmRvbS5ET01JbXBsZW1lbnRhdGlvblNvdXJjZUltcGwgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vb3JnLmFwYWNoZS54ZXJjZXMuZG9tLkRPTUltcGxlbWVudGF0aW9uU291cmNlSW1wbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNzljMzNkZC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9kb20vb3JnLmFwYWNoZS54ZXJjZXMuZG9tLkRPTUltcGxlbWVudGF0aW9uU291cmNlSW1wbAorKysgL2Rldi9udWxsCkBAIC0xICswLDAgQEAKLWNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tLkRPTUltcGxlbWVudGF0aW9uU291cmNlSW1wbApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL29yZy53M2MuZG9tLkRPTUltcGxlbWVudGF0aW9uU291cmNlTGlzdCBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2RvbS9vcmcudzNjLmRvbS5ET01JbXBsZW1lbnRhdGlvblNvdXJjZUxpc3QKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDgxNGYwMzEuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvZG9tL29yZy53M2MuZG9tLkRPTUltcGxlbWVudGF0aW9uU291cmNlTGlzdAorKysgL2Rldi9udWxsCkBAIC0xICswLDAgQEAKLWNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tLkRPTVhTSW1wbGVtZW50YXRpb25Tb3VyY2VJbXBsCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL0NvbnN0YW50cy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9Db25zdGFudHMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYzUzNTVhMC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL0NvbnN0YW50cy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTQxICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDMsIDIwMTYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKi8KLQotLyoKLSAqIENvcHlyaWdodCAyMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGw7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWxzLlNlY3VyaXR5U3VwcG9ydDsKLWltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247Ci1pbXBvcnQgamF2YS51dGlsLk5vU3VjaEVsZW1lbnRFeGNlcHRpb247Ci0KLS8qKgotICogQ29tbW9ubHkgdXNlZCBjb25zdGFudHMuCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgQW5keSBDbGFyaywgSUJNCi0gKgotICogQHZlcnNpb24gJElkOiBDb25zdGFudHMuamF2YSx2IDEuMTQgMjAxMC0xMS0wMSAwNDozOTo0MCBqb2VodyBFeHAgJAotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgQ29uc3RhbnRzIHsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RhbnRzCi0gICAgLy8KLSAgICAvLyBTY2hlbWEgVHlwZXM6Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTlNfWE1MU0NIRU1BID0gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hIi5pbnRlcm4oKTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBOU19EVEQgPSAiaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLXhtbCIuaW50ZXJuKCk7Ci0KLSAgICAvLyBTY2hlbWEgZmVhdHVyZXMKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBTVU5fU0NIRU1BX0ZFQVRVUkVfUFJFRklYID0gImh0dHA6Ly9qYXZhLnN1bi5jb20veG1sL3NjaGVtYS9mZWF0dXJlcy8iOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFNVTl9SRVBPUlRfSUdOT1JFRF9FTEVNRU5UX0NPTlRFTlRfV0hJVEVTUEFDRSA9ICJyZXBvcnQtaWdub3JlZC1lbGVtZW50LWNvbnRlbnQtd2hpdGVzcGFjZSI7Ci0KLSAgICAvL3N0YXggcHJvcGVydGllcwotCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgWkVQSFlSX1BST1BFUlRZX1BSRUZJWCA9ICJodHRwOi8vamF2YS5zdW4uY29tL3htbC9zdHJlYW0vcHJvcGVydGllcy8iIDsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBTVEFYX1BST1BFUlRJRVMgPSAic3RheC1wcm9wZXJ0aWVzIiA7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1RBWF9FTlRJVFlfUkVTT0xWRVJfUFJPUEVSVFkgPSAiaW50ZXJuYWwvc3RheC1lbnRpdHktcmVzb2x2ZXIiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFNUQVhfUkVQT1JUX0NEQVRBX0VWRU5UID0gInJlcG9ydC1jZGF0YS1ldmVudCI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgUkVBREVSX0lOX0RFRklORURfU1RBVEUgPSBaRVBIWVJfUFJPUEVSVFlfUFJFRklYICsgInJlYWRlci1pbi1kZWZpbmVkLXN0YXRlIiA7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQUREX05BTUVTUEFDRV9ERUNMX0FTX0FUVFJJQlVURSA9ICJhZGQtbmFtZXNwYWNlZGVjbC1hcy1hdHRyYml1dGUiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVTQ0FQRV9DSEFSQUNURVJTID0gImVzY2FwZUNoYXJhY3RlcnMiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFJFVVNFX0lOU1RBTkNFID0gInJldXNlLWluc3RhbmNlIiA7Ci0KLSAgICAvL0RPTSBwcm9wZXJ0aWVzCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1VOX0RPTV9QUk9QRVJUWV9QUkVGSVggPSAiaHR0cDovL2phdmEuc3VuLmNvbS94bWwvZG9tL3Byb3BlcnRpZXMvIiA7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1VOX0RPTV9BTkNFU1RPUl9DSEVDQ0sgPSAiYW5jZXN0b3ItY2hlY2siOwotCi0gICAgLyoqCi0gICAgICogSWYgdHJ1ZSwgaWdub3JlIERPQ1RZUEUgZGVjbGFyYXRpb24gYXMgaWYgaXQgd2Fzbid0IHByZXNlbnQgYXQgYWxsLgotICAgICAqIE5vdGUgdGhhdCB0aGlzIGlzIGEgdmlvbGF0aW9uIG9mIHRoZSBYTUwgcmVjb21tZW5kYXRpb24uCi0gICAgICogVGhlIGZ1bGwgcHJvcGVydHkgbmFtZSBpcyBwcmVmaXhlZCBieSB7QGxpbmsgI1pFUEhZUl9QUk9QRVJUWV9QUkVGSVh9LgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIElHTk9SRV9FWFRFUk5BTF9EVEQgPSAiaWdub3JlLWV4dGVybmFsLWR0ZCI7Ci0KLSAgICAvLyBzYXggZmVhdHVyZXMKLQotICAgIC8qKiBTQVggZmVhdHVyZSBwcmVmaXggKCJodHRwOi8veG1sLm9yZy9zYXgvZmVhdHVyZXMvIikuICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU0FYX0ZFQVRVUkVfUFJFRklYID0gImh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy8iOwotCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTkFNRVNQQUNFU19GRUFUVVJFID0gIm5hbWVzcGFjZXMiOwotCi0gICAgLyoqIE5hbWVzcGFjZSBwcmVmaXhlcyBmZWF0dXJlICgibmFtZXNwYWNlLXByZWZpeGVzIikuICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTkFNRVNQQUNFX1BSRUZJWEVTX0ZFQVRVUkUgPSAibmFtZXNwYWNlLXByZWZpeGVzIjsKLQotICAgIC8qKiBTdHJpbmcgaW50ZXJuaW5nIGZlYXR1cmUgKCJzdHJpbmctaW50ZXJuaW5nIikuICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1RSSU5HX0lOVEVSTklOR19GRUFUVVJFID0gInN0cmluZy1pbnRlcm5pbmciOwotCi0gICAgLyoqIFZhbGlkYXRpb24gZmVhdHVyZSAoInZhbGlkYXRpb24iKS4gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBWQUxJREFUSU9OX0ZFQVRVUkUgPSAidmFsaWRhdGlvbiI7Ci0KLSAgICAvKiogRXh0ZXJuYWwgZ2VuZXJhbCBlbnRpdGllcyBmZWF0dXJlICgiZXh0ZXJuYWwtZ2VuZXJhbC1lbnRpdGllcyAiKS4gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFWFRFUk5BTF9HRU5FUkFMX0VOVElUSUVTX0ZFQVRVUkUgPSAiZXh0ZXJuYWwtZ2VuZXJhbC1lbnRpdGllcyI7Ci0KLSAgICAvKiogRXh0ZXJuYWwgcGFyYW1ldGVyIGVudGl0aWVzIGZlYXR1cmUgKCJleHRlcm5hbC1wYXJhbWV0ZXItZW50aXRpZXMgIikuICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVhURVJOQUxfUEFSQU1FVEVSX0VOVElUSUVTX0ZFQVRVUkUgPSAiZXh0ZXJuYWwtcGFyYW1ldGVyLWVudGl0aWVzIjsKLQotICAgIC8qKiBMZXhpY2FsIGhhbmRsZXIgcGFyYW1ldGVyIGVudGl0aWVzIGZlYXR1cmUgKCJsZXhpY2FsLWhhbmRsZXIvcGFyYW1ldGVyLWVudGl0aWVzIikuICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTEVYSUNBTF9IQU5ETEVSX1BBUkFNRVRFUl9FTlRJVElFU19GRUFUVVJFID0gImxleGljYWwtaGFuZGxlci9wYXJhbWV0ZXItZW50aXRpZXMiOwotCi0gICAgLyoqIElzIHN0YW5kYWxvbmUgZmVhdHVyZSAoImlzLXN0YW5kYWxvbmUiKS4gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBJU19TVEFOREFMT05FX0ZFQVRVUkUgPSAiaXMtc3RhbmRhbG9uZSI7Ci0KLSAgICAvKiogUmVzb2x2ZSBEVEQgVVJJcyBmZWF0dXJlICgicmVzb2x2ZS1kdGQtdXJpcyIpLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFJFU09MVkVfRFREX1VSSVNfRkVBVFVSRSA9ICJyZXNvbHZlLWR0ZC11cmlzIjsKLQotICAgIC8qKiBVc2UgQXR0cmlidXRlczIgZmVhdHVyZSAoInVzZS1hdHRyaWJ1dGVzMiIpLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFVTRV9BVFRSSUJVVEVTMl9GRUFUVVJFID0gInVzZS1hdHRyaWJ1dGVzMiI7Ci0KLSAgICAvKiogVXNlIExvY2F0b3IyIGZlYXR1cmUgKCJ1c2UtbG9jYXRvcjIiKS4gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBVU0VfTE9DQVRPUjJfRkVBVFVSRSA9ICJ1c2UtbG9jYXRvcjIiOwotCi0gICAgLyoqIFVzZSBFbnRpdHlSZXNvbHZlcjIgZmVhdHVyZSAoInVzZS1lbnRpdHktcmVzb2x2ZXIyIikuICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgVVNFX0VOVElUWV9SRVNPTFZFUjJfRkVBVFVSRSA9ICJ1c2UtZW50aXR5LXJlc29sdmVyMiI7Ci0KLSAgICAvKiogVW5pY29kZSBub3JtYWxpemF0aW9uIGNoZWNraW5nIGZlYXR1cmUgKCJ1bmljb2RlLW5vcm1hbGl6YXRpb24tY2hlY2tpbmciKS4gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBVTklDT0RFX05PUk1BTElaQVRJT05fQ0hFQ0tJTkdfRkVBVFVSRSA9ICJ1bmljb2RlLW5vcm1hbGl6YXRpb24tY2hlY2tpbmciOwotCi0gICAgLyoqIHhtbG5zIFVSSXMgZmVhdHVyZSAoInhtbG5zLXVyaXMiKS4gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxOU19VUklTX0ZFQVRVUkUgPSAieG1sbnMtdXJpcyI7Ci0KLSAgICAvKiogWE1MIDEuMSBmZWF0dXJlICgieG1sLTEuMSIpLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFhNTF8xMV9GRUFUVVJFID0gInhtbC0xLjEiOwotCi0gICAgLyoqIEFsbG93IHVucGFyc2VkIGVudGl0eSBhbmQgbm90YXRpb24gZGVjbGFyYXRpb24gZXZlbnRzIHRvIGJlIHNlbnQgYWZ0ZXIgdGhlIGVuZCBEVEQgZXZlbnQgKCJhbGxvdy1kdGQtZXZlbnRzLWFmdGVyLWVuZERURCIpICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQUxMT1dfRFREX0VWRU5UU19BRlRFUl9FTkREVERfRkVBVFVSRSA9ICJhbGxvdy1kdGQtZXZlbnRzLWFmdGVyLWVuZERURCI7Ci0KLSAgICAvLyBzYXggcHJvcGVydGllcwotCi0gICAgLyoqIFNBWCBwcm9wZXJ0eSBwcmVmaXggKCJodHRwOi8veG1sLm9yZy9zYXgvcHJvcGVydGllcy8iKS4gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBTQVhfUFJPUEVSVFlfUFJFRklYID0gImh0dHA6Ly94bWwub3JnL3NheC9wcm9wZXJ0aWVzLyI7Ci0KLSAgICAvKiogRGVjbGFyYXRpb24gaGFuZGxlciBwcm9wZXJ0eSAoImRlY2xhcmF0aW9uLWhhbmRsZXIiKS4gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBERUNMQVJBVElPTl9IQU5ETEVSX1BST1BFUlRZID0gImRlY2xhcmF0aW9uLWhhbmRsZXIiOwotCi0gICAgLyoqIExleGljYWwgaGFuZGxlciBwcm9wZXJ0eSAoImxleGljYWwtaGFuZGxlciIpLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIExFWElDQUxfSEFORExFUl9QUk9QRVJUWSA9ICJsZXhpY2FsLWhhbmRsZXIiOwotCi0gICAgLyoqIERPTSBub2RlIHByb3BlcnR5ICgiZG9tLW5vZGUiKS4gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBET01fTk9ERV9QUk9QRVJUWSA9ICJkb20tbm9kZSI7Ci0KLSAgICAvKiogWE1MIHN0cmluZyBwcm9wZXJ0eSAoInhtbC1zdHJpbmciKS4gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxfU1RSSU5HX1BST1BFUlRZID0gInhtbC1zdHJpbmciOwotCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRkVBVFVSRV9TRUNVUkVfUFJPQ0VTU0lORyA9ICJodHRwOi8vamF2YXgueG1sLlhNTENvbnN0YW50cy9mZWF0dXJlL3NlY3VyZS1wcm9jZXNzaW5nIjsKLQotICAgIC8vIE9yYWNsZSBGZWF0dXJlOgotICAgIC8qKgotICAgICAqIDxwPlVzZSBTZXJ2aWNlIE1lY2hhbmlzbTwvcD4KLSAgICAgKgotICAgICAqIDx1bD4KLSAgICAgKiAgIDxsaT4KLSAgICAgKiB7QGNvZGUgdHJ1ZX0gaW5zdHJ1Y3QgYW4gb2JqZWN0IHRvIHVzZSBzZXJ2aWNlIG1lY2hhbmlzbSB0bwotICAgICAqIGZpbmQgYSBzZXJ2aWNlIGltcGxlbWVudGF0aW9uLiBUaGlzIGlzIHRoZSBkZWZhdWx0IGJlaGF2aW9yLgotICAgICAqICAgPC9saT4KLSAgICAgKiAgIDxsaT4KLSAgICAgKiB7QGNvZGUgZmFsc2V9IGluc3RydWN0IGFuIG9iamVjdCB0byBza2lwIHNlcnZpY2UgbWVjaGFuaXNtIGFuZAotICAgICAqIHVzZSB0aGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBmb3IgdGhhdCBzZXJ2aWNlLgotICAgICAqICAgPC9saT4KLSAgICAgKiA8L3VsPgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIE9SQUNMRV9GRUFUVVJFX1NFUlZJQ0VfTUVDSEFOSVNNID0gImh0dHA6Ly93d3cub3JhY2xlLmNvbS9mZWF0dXJlL3VzZS1zZXJ2aWNlLW1lY2hhbmlzbSI7Ci0KLSAgICAvKiogRG9jdW1lbnQgWE1MIHZlcnNpb24gcHJvcGVydHkgKCJkb2N1bWVudC14bWwtdmVyc2lvbiIpLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIERPQ1VNRU5UX1hNTF9WRVJTSU9OX1BST1BFUlRZID0gImRvY3VtZW50LXhtbC12ZXJzaW9uIjsKLQotCi0gICAgLy8KLSAgICAvLyBKQVhQIHByb3BlcnRpZXMKLSAgICAvLwotCi0gICAgLyoqIEpBWFAgcHJvcGVydHkgcHJlZml4ICgiaHR0cDovL2phdmEuc3VuLmNvbS94bWwvamF4cC9wcm9wZXJ0aWVzLyIpLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEpBWFBfUFJPUEVSVFlfUFJFRklYID0KLSAgICAgICAgImh0dHA6Ly9qYXZhLnN1bi5jb20veG1sL2pheHAvcHJvcGVydGllcy8iOwotCi0gICAgLyoqIEpBWFAgc2NoZW1hU291cmNlIHByb3BlcnR5OiB3aGVuIHVzZWQgaW50ZXJuYWxseSBtYXkgaW5jbHVkZSBEVEQgc291cmNlcyAoRE9NKSAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFNDSEVNQV9TT1VSQ0UgPSAic2NoZW1hU291cmNlIjsKLQotICAgIC8qKiBKQVhQIHNjaGVtYVNvdXJjZSBsYW5ndWFnZTogd2hlbiB1c2VkIGludGVybmFsbHkgbWF5IGluY2x1ZGUgRFREIG5hbWVzcGFjZSAoRE9NKSAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFNDSEVNQV9MQU5HVUFHRSA9ICJzY2hlbWFMYW5ndWFnZSI7Ci0KLSAgICAvKiogSkFYUCBTdGFuZGFyZCBwcm9wZXJ0eSBwcmVmaXggKCJodHRwOi8vamF2YXgueG1sLlhNTENvbnN0YW50cy9wcm9wZXJ0eS8iKS4gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBKQVhQQVBJX1BST1BFUlRZX1BSRUZJWCA9Ci0gICAgICAgICJodHRwOi8vamF2YXgueG1sLlhNTENvbnN0YW50cy9wcm9wZXJ0eS8iOwotCi0gICAgLyoqIE9yYWNsZSBKQVhQIHByb3BlcnR5IHByZWZpeCAoImh0dHA6Ly93d3cub3JhY2xlLmNvbS94bWwvamF4cC9wcm9wZXJ0aWVzLyIpLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIE9SQUNMRV9KQVhQX1BST1BFUlRZX1BSRUZJWCA9Ci0gICAgICAgICJodHRwOi8vd3d3Lm9yYWNsZS5jb20veG1sL2pheHAvcHJvcGVydGllcy8iOwotCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MX1NFQ1VSSVRZX1BST1BFUlRZX01BTkFHRVIgPQotICAgICAgICAgICAgT1JBQ0xFX0pBWFBfUFJPUEVSVFlfUFJFRklYICsgInhtbFNlY3VyaXR5UHJvcGVydHlNYW5hZ2VyIjsKLQotICAgIC8vU3lzdGVtIFByb3BlcnRpZXMgY29ycmVzcG9uZGluZyB0byBBQ0NFU1NfRVhURVJOQUxfKiBwcm9wZXJ0aWVzCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1BfQUNDRVNTX0VYVEVSTkFMX0RURCA9ICJqYXZheC54bWwuYWNjZXNzRXh0ZXJuYWxEVEQiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFNQX0FDQ0VTU19FWFRFUk5BTF9TQ0hFTUEgPSAiamF2YXgueG1sLmFjY2Vzc0V4dGVybmFsU2NoZW1hIjsKLSAgICAvL2FsbCBhY2Nlc3Mga2V5d29yZAotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEFDQ0VTU19FWFRFUk5BTF9BTEwgPSAiYWxsIjsKLQotICAgIC8qKgotICAgICAqIERlZmF1bHQgdmFsdWUgd2hlbiBGRUFUVVJFX1NFQ1VSRV9QUk9DRVNTSU5HIChGU1ApIGlzIHNldCB0byB0cnVlCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVhURVJOQUxfQUNDRVNTX0RFRkFVTFRfRlNQID0gIiI7Ci0KLSAgICAvKioKLSAgICAgKiBGRUFUVVJFX1NFQ1VSRV9QUk9DRVNTSU5HIChGU1ApIGlzIHRydWUgYnkgZGVmYXVsdAotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVYVEVSTkFMX0FDQ0VTU19ERUZBVUxUID0gQUNDRVNTX0VYVEVSTkFMX0FMTDsKLQotICAgIC8qKgotICAgICAqIENoZWNrIGlmIHdlJ3JlIGluIGpkazggb3IgYWJvdmUKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGJvb2xlYW4gSVNfSkRLOF9PUl9BQk9WRSA9IGlzSmF2YVZlcnNpb25BdExlYXN0KDgpOwotCi0gICAgLy8KLSAgICAvLyBJbXBsZW1lbnRhdGlvbiBsaW1pdHM6IGNvcnJlc3BvbmRpbmcgU3lzdGVtIFByb3BlcnRpZXMgb2YgdGhlIGFib3ZlCi0gICAgLy8gQVBJIHByb3BlcnRpZXMKLSAgICAvLwotICAgIC8qKgotICAgICAqIEpESyBlbnRpdHkgZXhwYW5zaW9uIGxpbWl0OyBOb3RlIHRoYXQgdGhlIGV4aXN0aW5nIHN5c3RlbSBwcm9wZXJ0eQotICAgICAqICJlbnRpdHlFeHBhbnNpb25MaW1pdCIgd2l0aCBubyBwcmVmaXggaXMgc3RpbGwgb2JzZXJ2ZWQKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBKREtfRU5USVRZX0VYUEFOU0lPTl9MSU1JVCA9Ci0gICAgICAgICAgICBPUkFDTEVfSkFYUF9QUk9QRVJUWV9QUkVGSVggKyAiZW50aXR5RXhwYW5zaW9uTGltaXQiOwotCi0gICAgLyoqCi0gICAgICogSkRLIGVsZW1lbnQgYXR0cmlidXRlIGxpbWl0OyBOb3RlIHRoYXQgdGhlIGV4aXN0aW5nIHN5c3RlbSBwcm9wZXJ0eQotICAgICAqICJlbGVtZW50QXR0cmlidXRlTGltaXQiIHdpdGggbm8gcHJlZml4IGlzIHN0aWxsIG9ic2VydmVkCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSkRLX0VMRU1FTlRfQVRUUklCVVRFX0xJTUlUID0KLSAgICAgICAgICAgIE9SQUNMRV9KQVhQX1BST1BFUlRZX1BSRUZJWCArICJlbGVtZW50QXR0cmlidXRlTGltaXQiOwotCi0gICAgLyoqCi0gICAgICogSkRLIG1heE9jY3VyIGxpbWl0OyBOb3RlIHRoYXQgdGhlIGV4aXN0aW5nIHN5c3RlbSBwcm9wZXJ0eQotICAgICAqICJtYXhPY2N1ckxpbWl0IiB3aXRoIG5vIHByZWZpeCBpcyBzdGlsbCBvYnNlcnZlZAotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEpES19NQVhfT0NDVVJfTElNSVQgPQotICAgICAgICAgICAgT1JBQ0xFX0pBWFBfUFJPUEVSVFlfUFJFRklYICsgIm1heE9jY3VyTGltaXQiOwotCi0gICAgLyoqCi0gICAgICogSkRLIHRvdGFsIGVudGl0eSBzaXplIGxpbWl0Ci0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSkRLX1RPVEFMX0VOVElUWV9TSVpFX0xJTUlUID0KLSAgICAgICAgICAgIE9SQUNMRV9KQVhQX1BST1BFUlRZX1BSRUZJWCArICJ0b3RhbEVudGl0eVNpemVMaW1pdCI7Ci0KLSAgICAvKioKLSAgICAgKiBKREsgbWF4aW11bSBnZW5lcmFsIGVudGl0eSBzaXplIGxpbWl0Ci0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSkRLX0dFTkVSQUxfRU5USVRZX1NJWkVfTElNSVQgPQotICAgICAgICAgICAgT1JBQ0xFX0pBWFBfUFJPUEVSVFlfUFJFRklYICsgIm1heEdlbmVyYWxFbnRpdHlTaXplTGltaXQiOwotCi0gICAgLyoqCi0gICAgICogSkRLIG5vZGUgY291bnQgbGltaXQgaW4gZW50aXRpZXMgdGhhdCBsaW1pdHMgdGhlIHRvdGFsIG51bWJlciBvZiBub2RlcwotICAgICAqIGluIGFsbCBvZiBlbnRpdHkgcmVmZXJlbmNlcy4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBKREtfRU5USVRZX1JFUExBQ0VNRU5UX0xJTUlUID0KLSAgICAgICAgICAgIE9SQUNMRV9KQVhQX1BST1BFUlRZX1BSRUZJWCArICJlbnRpdHlSZXBsYWNlbWVudExpbWl0IjsKLQotICAgIC8qKgotICAgICAqIEpESyBtYXhpbXVtIHBhcmFtZXRlciBlbnRpdHkgc2l6ZSBsaW1pdAotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEpES19QQVJBTUVURVJfRU5USVRZX1NJWkVfTElNSVQgPQotICAgICAgICAgICAgT1JBQ0xFX0pBWFBfUFJPUEVSVFlfUFJFRklYICsgIm1heFBhcmFtZXRlckVudGl0eVNpemVMaW1pdCI7Ci0gICAgLyoqCi0gICAgICogSkRLIG1heGltdW0gWE1MIG5hbWUgbGltaXQKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBKREtfWE1MX05BTUVfTElNSVQgPQotICAgICAgICAgICAgT1JBQ0xFX0pBWFBfUFJPUEVSVFlfUFJFRklYICsgIm1heFhNTE5hbWVMaW1pdCI7Ci0KLSAgICAvKioKLSAgICAgKiBKREsgbWF4RWxlbWVudERlcHRoIGxpbWl0Ci0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSkRLX01BWF9FTEVNRU5UX0RFUFRIID0KLSAgICAgICAgICAgIE9SQUNMRV9KQVhQX1BST1BFUlRZX1BSRUZJWCArICJtYXhFbGVtZW50RGVwdGgiOwotCi0gICAgLyoqCi0gICAgICogSkRLIHByb3BlcnR5IHRvIGFsbG93IHByaW50aW5nIG91dCBpbmZvcm1hdGlvbiBmcm9tIHRoZSBsaW1pdCBhbmFseXplcgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEpES19FTlRJVFlfQ09VTlRfSU5GTyA9Ci0gICAgICAgICAgICBPUkFDTEVfSkFYUF9QUk9QRVJUWV9QUkVGSVggKyAiZ2V0RW50aXR5Q291bnRJbmZvIjsKLQotICAgIC8vCi0gICAgLy8gSW1wbGVtZW50YXRpb24gbGltaXRzOiBBUEkgcHJvcGVydGllcwotICAgIC8vCi0gICAgLyoqCi0gICAgICogSkRLIGVudGl0eSBleHBhbnNpb24gbGltaXQ7IE5vdGUgdGhhdCB0aGUgZXhpc3Rpbmcgc3lzdGVtIHByb3BlcnR5Ci0gICAgICogImVudGl0eUV4cGFuc2lvbkxpbWl0IiB3aXRoIG5vIHByZWZpeCBpcyBzdGlsbCBvYnNlcnZlZAotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFNQX0VOVElUWV9FWFBBTlNJT05fTElNSVQgPSAiamRrLnhtbC5lbnRpdHlFeHBhbnNpb25MaW1pdCI7Ci0KLSAgICAvKioKLSAgICAgKiBKREsgZWxlbWVudCBhdHRyaWJ1dGUgbGltaXQ7IE5vdGUgdGhhdCB0aGUgZXhpc3Rpbmcgc3lzdGVtIHByb3BlcnR5Ci0gICAgICogImVsZW1lbnRBdHRyaWJ1dGVMaW1pdCIgd2l0aCBubyBwcmVmaXggaXMgc3RpbGwgb2JzZXJ2ZWQKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBTUF9FTEVNRU5UX0FUVFJJQlVURV9MSU1JVCA9ICAiamRrLnhtbC5lbGVtZW50QXR0cmlidXRlTGltaXQiOwotCi0gICAgLyoqCi0gICAgICogSkRLIG1heE9jY3VyIGxpbWl0OyBOb3RlIHRoYXQgdGhlIGV4aXN0aW5nIHN5c3RlbSBwcm9wZXJ0eQotICAgICAqICJtYXhPY2N1ckxpbWl0IiB3aXRoIG5vIHByZWZpeCBpcyBzdGlsbCBvYnNlcnZlZAotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFNQX01BWF9PQ0NVUl9MSU1JVCA9ICJqZGsueG1sLm1heE9jY3VyTGltaXQiOwotCi0gICAgLyoqCi0gICAgICogSkRLIHRvdGFsIGVudGl0eSBzaXplIGxpbWl0Ci0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1BfVE9UQUxfRU5USVRZX1NJWkVfTElNSVQgPSAiamRrLnhtbC50b3RhbEVudGl0eVNpemVMaW1pdCI7Ci0KLSAgICAvKioKLSAgICAgKiBKREsgbWF4aW11bSBnZW5lcmFsIGVudGl0eSBzaXplIGxpbWl0Ci0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1BfR0VORVJBTF9FTlRJVFlfU0laRV9MSU1JVCA9ICJqZGsueG1sLm1heEdlbmVyYWxFbnRpdHlTaXplTGltaXQiOwotCi0gICAgLyoqCi0gICAgICogSkRLIG5vZGUgY291bnQgbGltaXQgaW4gZW50aXRpZXMgdGhhdCBsaW1pdHMgdGhlIHRvdGFsIG51bWJlciBvZiBub2RlcwotICAgICAqIGluIGFsbCBvZiBlbnRpdHkgcmVmZXJlbmNlcy4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBTUF9FTlRJVFlfUkVQTEFDRU1FTlRfTElNSVQgPSAiamRrLnhtbC5lbnRpdHlSZXBsYWNlbWVudExpbWl0IjsKLQotICAgIC8qKgotICAgICAqIEpESyBtYXhpbXVtIHBhcmFtZXRlciBlbnRpdHkgc2l6ZSBsaW1pdAotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFNQX1BBUkFNRVRFUl9FTlRJVFlfU0laRV9MSU1JVCA9ICJqZGsueG1sLm1heFBhcmFtZXRlckVudGl0eVNpemVMaW1pdCI7Ci0gICAgLyoqCi0gICAgICogSkRLIG1heGltdW0gWE1MIG5hbWUgbGltaXQKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBTUF9YTUxfTkFNRV9MSU1JVCA9ICJqZGsueG1sLm1heFhNTE5hbWVMaW1pdCI7Ci0KLSAgICAvKioKLSAgICAgKiBKREsgbWF4RWxlbWVudERlcHRoIGxpbWl0Ci0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1BfTUFYX0VMRU1FTlRfREVQVEggPSAiamRrLnhtbC5tYXhFbGVtZW50RGVwdGgiOwotCi0gICAgLy9sZWdhY3kgU3lzdGVtIFByb3BlcnRpZXMKLSAgICBwdWJsaWMgZmluYWwgc3RhdGljIFN0cmluZyBFTlRJVFlfRVhQQU5TSU9OX0xJTUlUID0gImVudGl0eUV4cGFuc2lvbkxpbWl0IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFTEVNRU5UX0FUVFJJQlVURV9MSU1JVCA9ICJlbGVtZW50QXR0cmlidXRlTGltaXQiIDsKLSAgICBwdWJsaWMgZmluYWwgc3RhdGljIFN0cmluZyBNQVhfT0NDVVJfTElNSVQgPSAibWF4T2NjdXJMaW1pdCI7Ci0KLSAgICAvKioKLSAgICAgKiBBIHN0cmluZyAieWVzIiB0aGF0IGNhbiBiZSB1c2VkIGZvciBwcm9wZXJ0aWVzIHN1Y2ggYXMgZ2V0RW50aXR5Q291bnRJbmZvCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSkRLX1lFUyA9ICJ5ZXMiOwotCi0gICAgLy8KLSAgICAvLyBET00gZmVhdHVyZXMKLSAgICAvLwotCi0gICAgLyoqIENvbW1lbnRzIGZlYXR1cmUgKCJpbmNsdWRlLWNvbW1lbnRzIikuICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSU5DTFVERV9DT01NRU5UU19GRUFUVVJFID0gImluY2x1ZGUtY29tbWVudHMiOwotCi0gICAgLyoqIENyZWF0ZSBjZGF0YSBub2RlcyBmZWF0dXJlICgiY3JlYXRlLWNkYXRhLW5vZGVzIikuICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ1JFQVRFX0NEQVRBX05PREVTX0ZFQVRVUkUgPSAiY3JlYXRlLWNkYXRhLW5vZGVzIjsKLQotICAgIC8qKiBGZWF0dXJlIGlkOiBsb2FkIGFzIGluZm9zZXQuICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTE9BRF9BU19JTkZPU0VUID0gImxvYWQtYXMtaW5mb3NldCI7Ci0KLQotICAgIC8vCi0gICAgLy8gQ29uc3RhbnRzOiBET00gTGV2ZWwgMyBmZWF0dXJlIGlkcwotICAgIC8vCi0KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBET01fQ0FOT05JQ0FMX0ZPUk0gPSAiY2Fub25pY2FsLWZvcm0iOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIERPTV9DREFUQV9TRUNUSU9OUyA9ImNkYXRhLXNlY3Rpb25zIjsKLQotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIERPTV9DT01NRU5UUyA9ICJjb21tZW50cyI7Ci0KLSAgICAvLyBSRVZJU0lUOiB0aGlzIGZlYXR1cmUgc2VlbXMgdG8gaGF2ZSBubyBlZmZlY3QgZm9yIFhlcmNlcwotCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRE9NX0NIQVJTRVRfT1ZFUlJJREVTX1hNTF9FTkNPRElORyA9Ci0gICAgImNoYXJzZXQtb3ZlcnJpZGVzLXhtbC1lbmNvZGluZyI7Ci0KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBET01fREFUQVRZUEVfTk9STUFMSVpBVElPTiA9ICJkYXRhdHlwZS1ub3JtYWxpemF0aW9uIjsKLQotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIERPTV9FTlRJVElFUyA9ICJlbnRpdGllcyI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRE9NX0lORk9TRVQgPSAiaW5mb3NldCI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRE9NX05BTUVTUEFDRVMgPSAibmFtZXNwYWNlcyI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRE9NX05BTUVTUEFDRV9ERUNMQVJBVElPTlMgPSAibmFtZXNwYWNlLWRlY2xhcmF0aW9ucyI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRE9NX1NVUFBPUlRFRF9NRURJQVRZUEVTX09OTFkgPQotICAgICAgICAic3VwcG9ydGVkLW1lZGlhLXR5cGVzLW9ubHkiOwotCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRE9NX1ZBTElEQVRFX0lGX1NDSEVNQSA9ICJ2YWxpZGF0ZS1pZi1zY2hlbWEiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIERPTV9WQUxJREFURSA9ICJ2YWxpZGF0ZSI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRE9NX0VMRU1FTlRfQ09OVEVOVF9XSElURVNQQUNFID0KLSAgICAgICAgImVsZW1lbnQtY29udGVudC13aGl0ZXNwYWNlIjsKLQotICAgIC8vIERPTSBMZXZlbCAzIGZlYXR1cmVzIGRlZmluZWQgaW4gQ29yZToKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBET01fRElTQ0FSRF9ERUZBVUxUX0NPTlRFTlQgPSAiZGlzY2FyZC1kZWZhdWx0LWNvbnRlbnQiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIERPTV9OT1JNQUxJWkVfQ0hBUkFDVEVSUyAgICA9ICJub3JtYWxpemUtY2hhcmFjdGVycyI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRE9NX0NIRUNLX0NIQVJfTk9STUFMSVpBVElPTiAgPSAiY2hlY2stY2hhcmFjdGVyLW5vcm1hbGl6YXRpb24iOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIERPTV9XRUxMRk9STUVEICA9ICJ3ZWxsLWZvcm1lZCI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRE9NX1NQTElUX0NEQVRBID0gInNwbGl0LWNkYXRhLXNlY3Rpb25zIjsKLQotICAgIC8vIExvYWQgYW5kIFNhdmUKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBET01fRk9STUFUX1BSRVRUWV9QUklOVCA9ICJmb3JtYXQtcHJldHR5LXByaW50IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBET01fWE1MREVDTCA9ICJ4bWwtZGVjbGFyYXRpb24iOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIERPTV9VTktOT1dOQ0hBUlMgPSAidW5rbm93bi1jaGFyYWN0ZXJzIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBET01fQ0VSVElGSUVEID0gICJjZXJ0aWZpZWQiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIERPTV9ESVNBTExPV19ET0NUWVBFID0gICJkaXNhbGxvdy1kb2N0eXBlIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBET01fSUdOT1JFX1VOS05PV05fQ0hBUkFDVEVSX0RFTk9STUFMSVpBVElPTlMgPSAgImlnbm9yZS11bmtub3duLWNoYXJhY3Rlci1kZW5vcm1hbGl6YXRpb25zIjsKLQotICAgIC8vIERPTSBQcm9wZXJ0aWVzCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRE9NX1JFU09VUkNFX1JFU09MVkVSID0gInJlc291cmNlLXJlc29sdmVyIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBET01fRVJST1JfSEFORExFUiA9ICJlcnJvci1oYW5kbGVyIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBET01fU0NIRU1BX1RZUEUgPSAic2NoZW1hLXR5cGUiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIERPTV9TQ0hFTUFfTE9DQVRJT04gPSAic2NoZW1hLWxvY2F0aW9uIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBET01fQU5DRVNUT1JfQ0hFQ0NLID0gImFuY2VzdG9yLWNoZWNrIjsKLSAgICAvLyBYU01vZGVsCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRE9NX1BTVkkgPSAicHN2aSI7Ci0KLQotICAgIC8vIHhlcmNlcyBmZWF0dXJlcwotCi0gICAgLyoqIFhlcmNlcyBmZWF0dXJlcyBwcmVmaXggKCJodHRwOi8vYXBhY2hlLm9yZy94bWwvZmVhdHVyZXMvIikuICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgWEVSQ0VTX0ZFQVRVUkVfUFJFRklYID0gImh0dHA6Ly9hcGFjaGUub3JnL3htbC9mZWF0dXJlcy8iOwotCi0gICAgLyoqIFNjaGVtYSB2YWxpZGF0aW9uIGZlYXR1cmUgKCJ2YWxpZGF0aW9uL3NjaGVtYSIpLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFNDSEVNQV9WQUxJREFUSU9OX0ZFQVRVUkUgPSAidmFsaWRhdGlvbi9zY2hlbWEiOwotCi0gICAgLyoqIEV4cG9zZSBzY2hlbWEgbm9ybWFsaXplZCB2YWx1ZXMgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBTQ0hFTUFfTk9STUFMSVpFRF9WQUxVRSA9ICJ2YWxpZGF0aW9uL3NjaGVtYS9ub3JtYWxpemVkLXZhbHVlIjsKLQotICAgIC8qKiBTZW5kIHNjaGVtYSBkZWZhdWx0IHZhbHVlIHZpYSBjaGFyYWN0ZXJzKCkgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBTQ0hFTUFfRUxFTUVOVF9ERUZBVUxUID0gInZhbGlkYXRpb24vc2NoZW1hL2VsZW1lbnQtZGVmYXVsdCI7Ci0KLSAgICAvKiogU2NoZW1hIGZ1bGwgY29uc3RyYWludCBjaGVja2luZyAoInZhbGlkYXRpb24vc2NoZW1hLWZ1bGwtY2hlY2tpbmciKS4gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBTQ0hFTUFfRlVMTF9DSEVDS0lORyA9ICJ2YWxpZGF0aW9uL3NjaGVtYS1mdWxsLWNoZWNraW5nIjsKLQotICAgIC8qKiBBdWdtZW50IFBvc3QtU2NoZW1hLVZhbGlkYXRpb24tSW5mb3NldCAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFNDSEVNQV9BVUdNRU5UX1BTVkkgPSAidmFsaWRhdGlvbi9zY2hlbWEvYXVnbWVudC1wc3ZpIjsKLQotICAgIC8qKiBEeW5hbWljIHZhbGlkYXRpb24gZmVhdHVyZSAoInZhbGlkYXRpb24vZHluYW1pYyIpLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIERZTkFNSUNfVkFMSURBVElPTl9GRUFUVVJFID0gInZhbGlkYXRpb24vZHluYW1pYyI7Ci0KLSAgICAvKiogV2FybiBvbiBkdXBsaWNhdGUgYXR0cmlidXRlIGRlY2xhcmF0aW9uIGZlYXR1cmUgKCJ2YWxpZGF0aW9uL3dhcm4tb24tZHVwbGljYXRlLWF0dGRlZiIpLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdBUk5fT05fRFVQTElDQVRFX0FUVERFRl9GRUFUVVJFID0gInZhbGlkYXRpb24vd2Fybi1vbi1kdXBsaWNhdGUtYXR0ZGVmIjsKLQotICAgIC8qKiBXYXJuIG9uIHVuZGVjbGFyZWQgZWxlbWVudCBmZWF0dXJlICgidmFsaWRhdGlvbi93YXJuLW9uLXVuZGVjbGFyZWQtZWxlbWRlZiIpLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdBUk5fT05fVU5ERUNMQVJFRF9FTEVNREVGX0ZFQVRVUkUgPSAidmFsaWRhdGlvbi93YXJuLW9uLXVuZGVjbGFyZWQtZWxlbWRlZiI7Ci0KLSAgICAvKiogV2FybiBvbiBkdXBsaWNhdGUgZW50aXR5IGRlY2xhcmF0aW9uIGZlYXR1cmUgKCJ3YXJuLW9uLWR1cGxpY2F0ZS1lbnRpdHlkZWYiKS4gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXQVJOX09OX0RVUExJQ0FURV9FTlRJVFlERUZfRkVBVFVSRSA9ICJ3YXJuLW9uLWR1cGxpY2F0ZS1lbnRpdHlkZWYiOwotCi0gICAgLyoqIEFsbG93IEphdmEgZW5jb2RpbmcgbmFtZXMgZmVhdHVyZSAoImFsbG93LWphdmEtZW5jb2RpbmdzIikuICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQUxMT1dfSkFWQV9FTkNPRElOR1NfRkVBVFVSRSA9ICJhbGxvdy1qYXZhLWVuY29kaW5ncyI7Ci0KLSAgICAvKiogRGlzYWxsb3cgRE9DVFlQRSBkZWNsYXJhdGlvbiBmZWF0dXJlICgiZGlzYWxsb3ctZG9jdHlwZS1kZWNsIikuICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRElTQUxMT1dfRE9DVFlQRV9ERUNMX0ZFQVRVUkUgPSAiZGlzYWxsb3ctZG9jdHlwZS1kZWNsIjsKLQotICAgIC8qKiBDb250aW51ZSBhZnRlciBmYXRhbCBlcnJvciBmZWF0dXJlICgiY29udGludWUtYWZ0ZXItZmF0YWwtZXJyb3IiKS4gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBDT05USU5VRV9BRlRFUl9GQVRBTF9FUlJPUl9GRUFUVVJFID0gImNvbnRpbnVlLWFmdGVyLWZhdGFsLWVycm9yIjsKLQotICAgIC8qKiBMb2FkIGR0ZCBncmFtbWFyIHdoZW4gbm9udmFsaWRhdGluZyBmZWF0dXJlICgibm9udmFsaWRhdGluZy9sb2FkLWR0ZC1ncmFtbWFyIikuICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTE9BRF9EVERfR1JBTU1BUl9GRUFUVVJFID0gIm5vbnZhbGlkYXRpbmcvbG9hZC1kdGQtZ3JhbW1hciI7Ci0KLSAgICAvKiogTG9hZCBleHRlcm5hbCBkdGQgd2hlbiBub252YWxpZGF0aW5nIGZlYXR1cmUgKCJub252YWxpZGF0aW5nL2xvYWQtZXh0ZXJuYWwtZHRkIikuICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTE9BRF9FWFRFUk5BTF9EVERfRkVBVFVSRSA9ICJub252YWxpZGF0aW5nL2xvYWQtZXh0ZXJuYWwtZHRkIjsKLQotICAgIC8qKiBEZWZlciBub2RlIGV4cGFuc2lvbiBmZWF0dXJlICgiZG9tL2RlZmVyLW5vZGUtZXhwYW5zaW9uIikuICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgREVGRVJfTk9ERV9FWFBBTlNJT05fRkVBVFVSRSA9ICJkb20vZGVmZXItbm9kZS1leHBhbnNpb24iOwotCi0gICAgLyoqIENyZWF0ZSBlbnRpdHkgcmVmZXJlbmNlIG5vZGVzIGZlYXR1cmUgKCJkb20vY3JlYXRlLWVudGl0eS1yZWYtbm9kZXMiKS4gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBDUkVBVEVfRU5USVRZX1JFRl9OT0RFU19GRUFUVVJFID0gImRvbS9jcmVhdGUtZW50aXR5LXJlZi1ub2RlcyI7Ci0KLSAgICAvKiogSW5jbHVkZSBpZ25vcmFibGUgd2hpdGVzcGFjZSBmZWF0dXJlICgiZG9tL2luY2x1ZGUtaWdub3JhYmxlLXdoaXRlc3BhY2UiKS4gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBJTkNMVURFX0lHTk9SQUJMRV9XSElURVNQQUNFID0gImRvbS9pbmNsdWRlLWlnbm9yYWJsZS13aGl0ZXNwYWNlIjsKLQotICAgIC8qKiBEZWZhdWx0IGF0dHJpYnV0ZSB2YWx1ZXMgZmVhdHVyZSAoInZhbGlkYXRpb24vZGVmYXVsdC1hdHRyaWJ1dGUtdmFsdWVzIikuICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgREVGQVVMVF9BVFRSSUJVVEVfVkFMVUVTX0ZFQVRVUkUgPSAidmFsaWRhdGlvbi9kZWZhdWx0LWF0dHJpYnV0ZS12YWx1ZXMiOwotCi0gICAgLyoqIFZhbGlkYXRlIGNvbnRlbnQgbW9kZWxzIGZlYXR1cmUgKCJ2YWxpZGF0aW9uL3ZhbGlkYXRlLWNvbnRlbnQtbW9kZWxzIikuICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgVkFMSURBVEVfQ09OVEVOVF9NT0RFTFNfRkVBVFVSRSA9ICJ2YWxpZGF0aW9uL3ZhbGlkYXRlLWNvbnRlbnQtbW9kZWxzIjsKLQotICAgIC8qKiBWYWxpZGF0ZSBkYXRhdHlwZXMgZmVhdHVyZSAoInZhbGlkYXRpb24vdmFsaWRhdGUtZGF0YXR5cGVzIikuICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgVkFMSURBVEVfREFUQVRZUEVTX0ZFQVRVUkUgPSAidmFsaWRhdGlvbi92YWxpZGF0ZS1kYXRhdHlwZXMiOwotCi0gICAgLyoqIEJhbGFuY2Ugc3ludGF4IHRyZWVzIGZlYXR1cmUgKCJ2YWxpZGF0aW9uL2JhbGFuY2Utc3ludGF4LXRyZWVzIikuICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQkFMQU5DRV9TWU5UQVhfVFJFRVMgPSAidmFsaWRhdGlvbi9iYWxhbmNlLXN5bnRheC10cmVlcyI7Ci0KLSAgICAvKiogTm90aWZ5IGNoYXJhY3RlciByZWZlcmVuY2VzIGZlYXR1cmUgKHNjYW5uZXIvbm90aWZ5LWNoYXItcmVmcyIpLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIE5PVElGWV9DSEFSX1JFRlNfRkVBVFVSRSA9ICJzY2FubmVyL25vdGlmeS1jaGFyLXJlZnMiOwotCi0gICAgLyoqIE5vdGlmeSBidWlsdC1pbiAoJmFtcDthbXA7LCBldGMuKSByZWZlcmVuY2VzIGZlYXR1cmUgKHNjYW5uZXIvbm90aWZ5LWJ1aWx0aW4tcmVmcyIpLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIE5PVElGWV9CVUlMVElOX1JFRlNfRkVBVFVSRSA9ICJzY2FubmVyL25vdGlmeS1idWlsdGluLXJlZnMiOwotCi0gICAgLyoqIFN0YW5kYXJkIFVSSSBjb25mb3JtYW50IGZlYXR1cmUgKCJzdGFuZGFyZC11cmktY29uZm9ybWFudCIpLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFNUQU5EQVJEX1VSSV9DT05GT1JNQU5UX0ZFQVRVUkUgPSAic3RhbmRhcmQtdXJpLWNvbmZvcm1hbnQiOwotCi0gICAgLyoqIEdlbmVyYXRlIHN5bnRoZXRpYyBhbm5vdGF0aW9ucyBmZWF0dXJlICgiZ2VuZXJhdGUtc3ludGhldGljLWFubm90YXRpb25zIikuICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgR0VORVJBVEVfU1lOVEhFVElDX0FOTk9UQVRJT05TX0ZFQVRVUkUgPSAiZ2VuZXJhdGUtc3ludGhldGljLWFubm90YXRpb25zIjsKLQotICAgIC8qKiBWYWxpZGF0ZSBhbm5vdGF0aW9ucyBmZWF0dXJlICgidmFsaWRhdGUtYW5ub3RhdGlvbnMiKS4gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBWQUxJREFURV9BTk5PVEFUSU9OU19GRUFUVVJFID0gInZhbGlkYXRlLWFubm90YXRpb25zIjsKLQotCi0gICAgICAgIC8qKiBIb25vdXIgYWxsIHNjaGVtYUxvY2F0aW9ucyBmZWF0dXJlICgiaG9ub3VyLWFsbC1zY2hlbWFMb2NhdGlvbnMiKS4gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBIT05PVVJfQUxMX1NDSEVNQUxPQ0FUSU9OU19GRUFUVVJFID0gImhvbm91ci1hbGwtc2NoZW1hTG9jYXRpb25zIjsKLQotICAgIC8qKiBOYW1lc3BhY2UgZ3Jvd3RoIGZlYXR1cmUgKCJuYW1lc3BhY2UtZ3Jvd3RoIikuICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTkFNRVNQQUNFX0dST1dUSF9GRUFUVVJFID0gIm5hbWVzcGFjZS1ncm93dGgiOwotCi0gICAgLyoqIFRvbGVyYXRlIGR1cGxpY2F0ZXMgZmVhdHVyZSAoImludGVybmFsL3RvbGVyYXRlLWR1cGxpY2F0ZXMiKS4gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBUT0xFUkFURV9EVVBMSUNBVEVTX0ZFQVRVUkUgPSAiaW50ZXJuYWwvdG9sZXJhdGUtZHVwbGljYXRlcyI7Ci0KLSAgICAvKiogWEluY2x1ZGUgcHJvY2Vzc2luZyBmZWF0dXJlICgieGluY2x1ZGUiKS4gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBYSU5DTFVERV9GRUFUVVJFID0gInhpbmNsdWRlIjsKLQotICAgIC8qKiBYSW5jbHVkZSBmaXh1cCBiYXNlIFVSSXMgZmVhdHVyZSAoInhpbmNsdWRlL2ZpeHVwLWJhc2UtdXJpcyIpLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFhJTkNMVURFX0ZJWFVQX0JBU0VfVVJJU19GRUFUVVJFID0gInhpbmNsdWRlL2ZpeHVwLWJhc2UtdXJpcyI7Ci0KLSAgICAvKiogWEluY2x1ZGUgZml4dXAgbGFuZ3VhZ2UgZmVhdHVyZSAoInhpbmNsdWRlL2ZpeHVwLWxhbmd1YWdlIikuICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgWElOQ0xVREVfRklYVVBfTEFOR1VBR0VfRkVBVFVSRSA9ICJ4aW5jbHVkZS9maXh1cC1sYW5ndWFnZSI7Ci0KLSAgICAvKioKLSAgICAgKiBJbnRlcm5hbCBmZWF0dXJlLiBXaGVuIHNldCB0byB0cnVlIHRoZSBzY2hlbWEgdmFsaWRhdG9yIHdpbGwgb25seSB1c2UKLSAgICAgKiBzY2hlbWEgY29tcG9uZW50cyBmcm9tIHRoZSBncmFtbWFyIHBvb2wgcHJvdmlkZWQuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgVVNFX0dSQU1NQVJfUE9PTF9PTkxZX0ZFQVRVUkUgPSAiaW50ZXJuYWwvdmFsaWRhdGlvbi9zY2hlbWEvdXNlLWdyYW1tYXItcG9vbC1vbmx5IjsKLQotICAgIC8qKiBJbnRlcm5hbCBwZXJmb3JtYW5jZSByZWxhdGVkIGZlYXR1cmU6Ci0gICAgICogZmFsc2UgLSB0aGUgcGFyc2VyIHNldHRpbmdzIChmZWF0dXJlcy9wcm9wZXJ0aWVzKSBoYXZlIG5vdCBjaGFuZ2VkIGJldHdlZW4gMiBwYXJzZXMKLSAgICAgKiB0cnVlIC0gdGhlIHBhcnNlciBzZXR0aW5ncyBoYXZlIGNoYW5nZWQgYmV0d2VlbiAyIHBhcnNlcwotICAgICAqIE5PVEU6IHRoaXMgZmVhdHVyZSBzaG91bGQgb25seSBiZSBzZXQgYnkgdGhlIHBhcnNlciBjb25maWd1cmF0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFBBUlNFUl9TRVRUSU5HUyA9ICJpbnRlcm5hbC9wYXJzZXItc2V0dGluZ3MiOwotCi0KLSAgICAvKiogRmVhdHVyZSB0byBtYWtlIFhNTCBQcm9jZXNzb3IgWEluY2x1ZGUgQXdhcmUgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBYSU5DTFVERV9BV0FSRSA9ICJ4aW5jbHVkZS1hd2FyZSI7Ci0KLSAgICAvKiogSWdub3JlIHhzaTpzY2hlbWFMb2NhdGlvbiBhbmQgeHNpOm5vTmFtZXNwYWNlU2NoZW1hTG9jYXRpb24uICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSUdOT1JFX1NDSEVNQV9MT0NBVElPTl9ISU5UUyA9ICJ2YWxpZGF0aW9uL3NjaGVtYS9pZ25vcmUtc2NoZW1hLWxvY2F0aW9uLWhpbnRzIjsKLQotICAgIC8qKgotICAgICAqIFdoZW4gdHJ1ZSwgdGhlIHNjaGVtYSBwcm9jZXNzb3Igd2lsbCBjaGFuZ2UgY2hhcmFjdGVycyBldmVudHMKLSAgICAgKiB0byBpZ25vcmFibGVXaGl0ZXNwYWNlcyBldmVudHMsIHdoZW4gY2hhcmFjdGVycyBhcmUgZXhwZWN0ZWQgdG8KLSAgICAgKiBvbmx5IGNvbnRhaW4gaWdub3JhYmxlIHdoaXRlc3BhY2VzLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIENIQU5HRV9JR05PUkFCTEVfQ0hBUkFDVEVSU19JTlRPX0lHTk9SQUJMRV9XSElURVNQQUNFUyA9Ci0gICAgICAgICJ2YWxpZGF0aW9uL2NoYW5nZS1pZ25vcmFibGUtY2hhcmFjdGVycy1pbnRvLWlnbm9yYWJsZS13aGl0ZXNwYWNlcyI7Ci0KLSAgICAvLyB4ZXJjZXMgcHJvcGVydGllcwotCi0gICAgLyoqIFhlcmNlcyBwcm9wZXJ0aWVzIHByZWZpeCAoImh0dHA6Ly9hcGFjaGUub3JnL3htbC9wcm9wZXJ0aWVzLyIpLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFhFUkNFU19QUk9QRVJUWV9QUkVGSVggPSAiaHR0cDovL2FwYWNoZS5vcmcveG1sL3Byb3BlcnRpZXMvIjsKLQotICAgIC8qKiBDdXJyZW50IGVsZW1lbnQgbm9kZSBwcm9wZXJ0eSAoImRvbS9jdXJyZW50LWVsZW1lbnQtbm9kZSIpLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIENVUlJFTlRfRUxFTUVOVF9OT0RFX1BST1BFUlRZID0gImRvbS9jdXJyZW50LWVsZW1lbnQtbm9kZSI7Ci0KLSAgICAvKiogRG9jdW1lbnQgY2xhc3MgbmFtZSBwcm9wZXJ0eSAoImRvbS9kb2N1bWVudC1jbGFzcy1uYW1lIikuICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRE9DVU1FTlRfQ0xBU1NfTkFNRV9QUk9QRVJUWSA9ICJkb20vZG9jdW1lbnQtY2xhc3MtbmFtZSI7Ci0KLSAgICAvKiogU3ltYm9sIHRhYmxlIHByb3BlcnR5ICgiaW50ZXJuYWwvc3ltYm9sLXRhYmxlIikuICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1lNQk9MX1RBQkxFX1BST1BFUlRZID0gImludGVybmFsL3N5bWJvbC10YWJsZSI7Ci0KLSAgICAvKiogRXJyb3IgcmVwb3J0ZXIgcHJvcGVydHkgKCJpbnRlcm5hbC9lcnJvci1yZXBvcnRlciIpLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUk9SX1JFUE9SVEVSX1BST1BFUlRZID0gImludGVybmFsL2Vycm9yLXJlcG9ydGVyIjsKLQotICAgIC8qKiBFcnJvciBoYW5kbGVyIHByb3BlcnR5ICgiaW50ZXJuYWwvZXJyb3ItaGFuZGxlciIpLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUk9SX0hBTkRMRVJfUFJPUEVSVFkgPSAiaW50ZXJuYWwvZXJyb3ItaGFuZGxlciI7Ci0KLSAgICAvKiogWEluY2x1ZGUgaGFuZGxlciBwcm9wZXJ0eSAoImludGVybmFsL3hpbmNsdWRlLWhhbmRsZXIiKS4gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBYSU5DTFVERV9IQU5ETEVSX1BST1BFUlRZID0gImludGVybmFsL3hpbmNsdWRlLWhhbmRsZXIiOwotCi0gICAgLyoqIFhQb2ludGVyIGhhbmRsZXIgcHJvcGVydHkgKCJpbnRlcm5hbC94cG9pbnRlci1oYW5kbGVyIikuICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgWFBPSU5URVJfSEFORExFUl9QUk9QRVJUWSA9ICJpbnRlcm5hbC94cG9pbnRlci1oYW5kbGVyIjsKLQotICAgIC8qKiBFbnRpdHkgbWFuYWdlciBwcm9wZXJ0eSAoImludGVybmFsL2VudGl0eS1tYW5hZ2VyIikuICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRU5USVRZX01BTkFHRVJfUFJPUEVSVFkgPSAiaW50ZXJuYWwvZW50aXR5LW1hbmFnZXIiOwotICAgIC8qKiBJbnB1dCBidWZmZXIgc2l6ZSBwcm9wZXJ0eSAoImlucHV0LWJ1ZmZlci1zaXplIikuICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQlVGRkVSX1NJWkVfUFJPUEVSVFkgPSAiaW5wdXQtYnVmZmVyLXNpemUiOwotCi0gICAgLyoqIFNlY3VyaXR5IG1hbmFnZXIgcHJvcGVydHkgKCJzZWN1cml0eS1tYW5hZ2VyIikuICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU0VDVVJJVFlfTUFOQUdFUl9QUk9QRVJUWSA9ICJzZWN1cml0eS1tYW5hZ2VyIjsKLQotICAgIC8qKiBMb2NhbGUgcHJvcGVydHkgKCJsb2NhbGUiKS4gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBMT0NBTEVfUFJPUEVSVFkgPSAibG9jYWxlIjsKLQotICAgIC8qKiBwcm9wZXJ0eSBpZGVudGlmaWVyOiBzZWN1cml0eSBtYW5hZ2VyLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFNFQ1VSSVRZX01BTkFHRVIgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5TRUNVUklUWV9NQU5BR0VSX1BST1BFUlRZOwotCi0KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFTlRJVFlfUkVTT0xWRVJfUFJPUEVSVFkgPSAiaW50ZXJuYWwvZW50aXR5LXJlc29sdmVyIjsKLQotICAgIC8qKiBHcmFtbWFyIHBvb2wgcHJvcGVydHkgKCJpbnRlcm5hbC9ncmFtbWFyLXBvb2wiKS4gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxHUkFNTUFSX1BPT0xfUFJPUEVSVFkgPSAiaW50ZXJuYWwvZ3JhbW1hci1wb29sIjsKLQotICAgIC8qKiBEYXRhdHlwZSB2YWxpZGF0b3IgZmFjdG9yeSAoImludGVybmFsL2RhdGF0eXBlLXZhbGlkYXRvci1mYWN0b3J5IikuICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgREFUQVRZUEVfVkFMSURBVE9SX0ZBQ1RPUllfUFJPUEVSVFkgPSAiaW50ZXJuYWwvZGF0YXR5cGUtdmFsaWRhdG9yLWZhY3RvcnkiOwotCi0gICAgLyoqIERvY3VtZW50IHNjYW5uZXIgcHJvcGVydHkgKCJpbnRlcm5hbC9kb2N1bWVudC1zY2FubmVyIikuICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRE9DVU1FTlRfU0NBTk5FUl9QUk9QRVJUWSA9ICJpbnRlcm5hbC9kb2N1bWVudC1zY2FubmVyIjsKLQotICAgIC8qKiBEVEQgc2Nhbm5lciBwcm9wZXJ0eSAoImludGVybmFsL2R0ZC1zY2FubmVyIikuICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRFREX1NDQU5ORVJfUFJPUEVSVFkgPSAiaW50ZXJuYWwvZHRkLXNjYW5uZXIiOwotCi0gICAgLyoqIERURCBwcm9jZXNzb3IgcHJvcGVydHkgKCJpbnRlcm5hbC9kdGQtcHJvY2Vzc29yIikuICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRFREX1BST0NFU1NPUl9QUk9QRVJUWSA9ICJpbnRlcm5hbC9kdGQtcHJvY2Vzc29yIjsKLQotICAgIC8qKiBWYWxpZGF0b3IgcHJvcGVydHkgKCJpbnRlcm5hbC92YWxpZGF0b3IiKS4gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBWQUxJREFUT1JfUFJPUEVSVFkgPSAiaW50ZXJuYWwvdmFsaWRhdG9yIjsKLQotICAgIC8qKiBWYWxpZGF0b3IgcHJvcGVydHkgKCJpbnRlcm5hbC92YWxpZGF0b3IvZHRkIikuICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRFREX1ZBTElEQVRPUl9QUk9QRVJUWSA9ICJpbnRlcm5hbC92YWxpZGF0b3IvZHRkIjsKLQotICAgIC8qKiBWYWxpZGF0b3IgcHJvcGVydHkgKCJpbnRlcm5hbC92YWxpZGF0b3Ivc2NoZW1hIikuICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU0NIRU1BX1ZBTElEQVRPUl9QUk9QRVJUWSA9ICJpbnRlcm5hbC92YWxpZGF0b3Ivc2NoZW1hIjsKLQotICAgIC8qKiBObyBuYW1lc3BhY2Ugc2NoZW1hIGxvY2F0aW9uIHByb3BlcnR5ICgic2NoZW1hL2V4dGVybmFsLXNjaGVtYUxvY2F0aW9uIikuICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU0NIRU1BX0xPQ0FUSU9OID0gInNjaGVtYS9leHRlcm5hbC1zY2hlbWFMb2NhdGlvbiI7Ci0KLSAgICAvKiogU2NoZW1hIGxvY2F0aW9uIHByb3BlcnR5ICgic2NoZW1hL2V4dGVybmFsLW5vTmFtZXNwYWNlU2NoZW1hTG9jYXRpb24iKS4gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBTQ0hFTUFfTk9OU19MT0NBVElPTiA9ICJzY2hlbWEvZXh0ZXJuYWwtbm9OYW1lc3BhY2VTY2hlbWFMb2NhdGlvbiI7Ci0KLSAgICAvKiogTmFtZXNwYWNlIGJpbmRlciBwcm9wZXJ0eSAoImludGVybmFsL25hbWVzcGFjZS1iaW5kZXIiKS4gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBOQU1FU1BBQ0VfQklOREVSX1BST1BFUlRZID0gImludGVybmFsL25hbWVzcGFjZS1iaW5kZXIiOwotCi0gICAgLyoqIE5hbWVzcGFjZSBjb250ZXh0IHByb3BlcnR5ICgiaW50ZXJuYWwvbmFtZXNwYWNlLWNvbnRleHQiKS4gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBOQU1FU1BBQ0VfQ09OVEVYVF9QUk9QRVJUWSA9ICJpbnRlcm5hbC9uYW1lc3BhY2UtY29udGV4dCI7Ci0KLSAgICAvKiogVmFsaWRhdGlvbiBtYW5hZ2VyIHByb3BlcnR5ICgiaW50ZXJuYWwvdmFsaWRhdGlvbi1tYW5hZ2VyIikuICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgVkFMSURBVElPTl9NQU5BR0VSX1BST1BFUlRZID0gImludGVybmFsL3ZhbGlkYXRpb24tbWFuYWdlciI7Ci0KLQotICAgIC8qKiBYUG9pbnRlciBTY2hlbWEgcHJvcGVydHkgKCJ4cG9pbnRlci1zY2hlbWEiKS4gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBYUE9JTlRFUl9TQ0hFTUFfUFJPUEVSVFkgPSAieHBvaW50ZXItc2NoZW1hIjsKLQotICAgIC8qKiBTY2hlbWEgZWxlbWVudCBkZWNsYXJhdGlvbiBmb3IgdGhlIHJvb3QgZWxlbWVudCBpbiBhIGRvY3VtZW50ICgiaW50ZXJuYWwvdmFsaWRhdGlvbi9zY2hlbWEvZHYtZmFjdG9yeSIpLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFNDSEVNQV9EVl9GQUNUT1JZX1BST1BFUlRZID0gImludGVybmFsL3ZhbGlkYXRpb24vc2NoZW1hL2R2LWZhY3RvcnkiOwotCi0KLSAgICAvLyBnZW5lcmFsIGNvbnN0YW50cwotCi0gICAgLyoqIEVsZW1lbnQgUFNWSSBpcyBzdG9yZWQgaW4gYXVnbWVudGF0aW9ucyB1c2luZyBzdHJpbmcgIkVMRU1FTlRfUFNWSSIgKi8KLSAgICBwdWJsaWMgZmluYWwgc3RhdGljIFN0cmluZyBFTEVNRU5UX1BTVkkgPSAiRUxFTUVOVF9QU1ZJIjsKLQotICAgIC8qKiBBdHRyaWJ1dGUgUFNWSSBpcyBzdG9yZWQgaW4gYXVnbWVudGF0aW9ucyB1c2luZyBzdHJpbmcgIkFUVFJJQlVURV9QU1ZJIiAqLwotICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgU3RyaW5nIEFUVFJJQlVURV9QU1ZJID0gIkFUVFJJQlVURV9QU1ZJIjsKLQotICAgIC8qKgotICAgICAqIEJvb2xlYW4gaW5kaWNhdGluZyB3aGV0aGVyIGFuIGF0dHJpYnV0ZSBpcyBkZWNsYXJlZCBpbiB0aGUgRFREIGlzIHN0b3JlZAotICAgICAqIGluIGF1Z21lbnRhdGlvbnMgdXNpbmcgdGhlIHN0cmluZyAiQVRUUklCVVRFX0RFQ0xBUkVEIi4gVGhlIGFic2VuY2Ugb2YgdGhpcwotICAgICAqIGF1Z21lbnRhdGlvbiBpbmRpY2F0ZXMgdGhhdCB0aGUgYXR0cmlidXRlIHdhcyBub3QgZGVjbGFyZWQgaW4gdGhlIERURC4KLSAgICAgKi8KLSAgICBwdWJsaWMgZmluYWwgc3RhdGljIFN0cmluZyBBVFRSSUJVVEVfREVDTEFSRUQgPSAiQVRUUklCVVRFX0RFQ0xBUkVEIjsKLQotCi0gICAgLyoqCi0gICAgICoge0BsaW5rIG9yZy53M2MuZG9tLlR5cGVJbmZvfSBhc3NvY2lhdGVkIHdpdGggY3VycmVudCBlbGVtZW50L2F0dHJpYnV0ZQotICAgICAqIGlzIHN0b3JlZCBpbiBhdWdtZW50YXRpb25zIHVzaW5nIHRoaXMgc3RyaW5nIGFzIHRoZSBrZXkuCi0gICAgICoKLSAgICAgKiBUaGlzIHdpbGwgdWx0aW1hdGVseSBjb250cm9scyB7QGxpbmsgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5wYXJzZXJzLkFic3RyYWN0RE9NUGFyc2VyfQotICAgICAqIHJlZ2FyZGluZyB3aGF0IG9iamVjdCB0aGUgRE9NIHdpbGwgcmV0dXJuIGZyb20KLSAgICAgKiB7QGxpbmsgb3JnLnczYy5kb20uQXR0ciNnZXRTY2hlbWFUeXBlSW5mbygpfSBhbmQKLSAgICAgKiB7QGxpbmsgb3JnLnczYy5kb20uRWxlbWVudCNnZXRTY2hlbWFUeXBlSW5mbygpfSBhbmQKLSAgICAgKi8KLSAgICBwdWJsaWMgZmluYWwgc3RhdGljIFN0cmluZyBUWVBFSU5GTyA9ICJvcmcudzNjLmRvbS5UeXBlSW5mbyI7Ci0KLSAgICAvKioKLSAgICAgKiBXaGV0aGVyIGFuIGF0dHJpYnV0ZSBpcyBhbiBpZCBvciBub3QgaXMgc3RvcmVkIGluIGF1Z21lbnRhdGlvbnMKLSAgICAgKiB1c2luZyB0aGlzIHN0cmluZyBhcyB0aGUga2V5LiBUaGUgdmFsdWUgaXMge0BsaW5rIEJvb2xlYW4jVFJVRX0KLSAgICAgKiBvciB7QGxpbmsgQm9vbGVhbiNGQUxTRX0uCi0gICAgICoKLSAgICAgKiBUaGlzIHdpbGwgdWx0aW1hdGVseSBjb250cm9scyB7QGxpbmsgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5wYXJzZXJzLkFic3RyYWN0RE9NUGFyc2VyfQotICAgICAqIGFib3V0IHdoZXRoZXIgaXQgd2lsbCBtYXJrIGFuIGF0dHJpYnV0ZSBhcyBJRCBvciBub3QuCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIHN0YXRpYyBTdHJpbmcgSURfQVRUUklCVVRFID0gIklEX0FUVFJJQlVURSI7Ci0KLSAgICAvLyBYTUwgdmVyc2lvbiBjb25zdGFudHMKLQotICAgIC8qKgotICAgICAqIEJvb2xlYW4gaW5kaWNhdGluZyB3aGV0aGVyIGFuIGVudGl0eSByZWZlcmVuY2VkIGluIHRoZSBkb2N1bWVudCBoYXMKLSAgICAgKiBub3QgYmVlbiByZWFkIGlzIHN0b3JlZCBpbiBhdWdtZW50YXRpb25zIHVzaW5nIHRoZSBzdHJpbmcgIkVOVElUWV9TS0lQUEVEIi4KLSAgICAgKiBUaGUgYWJzZW5jZSBvZiB0aGlzIGF1Z21lbnRhdGlvbiBpbmRpY2F0ZXMgdGhhdCB0aGUgZW50aXR5IGhhZCBhCi0gICAgICogZGVjbGFyYXRpb24gYW5kIHdhcyBleHBhbmRlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgZmluYWwgc3RhdGljIFN0cmluZyBFTlRJVFlfU0tJUFBFRCA9ICJFTlRJVFlfU0tJUFBFRCI7Ci0KLSAgICAvKioKLSAgICAgKiBCb29sZWFuIGluZGljYXRpbmcgd2hldGhlciBhIGNoYXJhY3RlciBpcyBhIHByb2JhYmxlIHdoaXRlIHNwYWNlCi0gICAgICogY2hhcmFjdGVyIChjaCA8PSAweDIwKSB0aGF0IHdhcyB0aGUgcmVwbGFjZW1lbnQgdGV4dCBvZiBhIGNoYXJhY3RlcgotICAgICAqIHJlZmVyZW5jZSBpcyBzdG9yZWQgaW4gYXVnbWVudGF0aW9ucyB1c2luZyB0aGUgc3RyaW5nICJDSEFSX1JFRl9QUk9CQUJMRV9XUyIuCi0gICAgICogVGhlIGFic2VuY2Ugb2YgdGhpcyBhdWdtZW50YXRpb24gaW5kaWNhdGVzIHRoYXQgdGhlIGNoYXJhY3RlciBpcyBub3QKLSAgICAgKiBwcm9iYWJsZSB3aGl0ZSBzcGFjZSBhbmQvb3Igd2FzIG5vdCBpbmNsdWRlZCBmcm9tIGEgY2hhcmFjdGVyIHJlZmVyZW5jZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgZmluYWwgc3RhdGljIFN0cmluZyBDSEFSX1JFRl9QUk9CQUJMRV9XUyA9ICJDSEFSX1JFRl9QUk9CQUJMRV9XUyI7Ci0KLSAgICAvKiogQm9vbGVhbiBpbmRpY2F0aW5nIGlmIHRoaXMgZW50aXR5IGlzIHRoZSBsYXN0IG9wZW5lZCBlbnRpdHkuCi0gICAgICoKLSAgICAgKkBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLlhNTEVudGl0eU1hbmFnZXIjZW5kRW50aXR5KCkKLSAgICAgKkBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLlhNTERvY3VtZW50U2Nhbm5lckltcGwjZW5kRW50aXR5KCkKLSAgICAgKkBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLlhNTERURFNjYW5uZXJJbXBsI2VuZEVudGl0eSgpCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIHN0YXRpYyBTdHJpbmcgTEFTVF9FTlRJVFkgPSAiTEFTVF9FTlRJVFkiOwotCi0gICAgLy8gWE1MIHZlcnNpb24gY29uc3RhbnRzCi0gICAgcHVibGljIGZpbmFsIHN0YXRpYyBzaG9ydCBYTUxfVkVSU0lPTl9FUlJPUiA9IC0xOwotICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgc2hvcnQgWE1MX1ZFUlNJT05fMV8wID0gMTsKLSAgICBwdWJsaWMgZmluYWwgc3RhdGljIHNob3J0IFhNTF9WRVJTSU9OXzFfMSA9IDI7Ci0KLQotCi0gICAgLy8gRE9NIHJlbGF0ZWQgY29uc3RhbnRzCi0gICAgcHVibGljIGZpbmFsIHN0YXRpYyBTdHJpbmcgQU5PTllNT1VTX1RZUEVfTkFNRVNQQUNFID0KLSAgICAgICAgImh0dHA6Ly9hcGFjaGUub3JnL3htbC94bWxzY2hlbWEvMS4wL2Fub255bW91c1R5cGVzIjsKLQotCi0KLSAgICAvLyBDb25zdGFudCB0byBlbmFibGUgU2NoZW1hIDEuMSBzdXBwb3J0Ci0gICAgcHVibGljIGZpbmFsIHN0YXRpYyBib29sZWFuIFNDSEVNQV8xXzFfU1VQUE9SVCA9IGZhbHNlOwotICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgc2hvcnQgU0NIRU1BX1ZFUlNJT05fMV8wICAgICAgICAgID0gMTsKLSAgICBwdWJsaWMgZmluYWwgc3RhdGljIHNob3J0IFNDSEVNQV9WRVJTSU9OXzFfMF9FWFRFTkRFRCA9IDI7Ci0KLSAgICAvLyBwcml2YXRlCi0KLSAgICAvKiogU0FYIGZlYXR1cmVzLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZ1tdIGZnU0FYRmVhdHVyZXMgPSB7Ci0gICAgICAgICAgICBOQU1FU1BBQ0VTX0ZFQVRVUkUsCi0gICAgICAgICAgICBOQU1FU1BBQ0VfUFJFRklYRVNfRkVBVFVSRSwKLSAgICAgICAgICAgIFNUUklOR19JTlRFUk5JTkdfRkVBVFVSRSwKLSAgICAgICAgICAgIFZBTElEQVRJT05fRkVBVFVSRSwKLSAgICAgICAgICAgIEVYVEVSTkFMX0dFTkVSQUxfRU5USVRJRVNfRkVBVFVSRSwKLSAgICAgICAgICAgIEVYVEVSTkFMX1BBUkFNRVRFUl9FTlRJVElFU19GRUFUVVJFLAotICAgIH07Ci0KLSAgICAvKiogU0FYIHByb3BlcnRpZXMuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nW10gZmdTQVhQcm9wZXJ0aWVzID0gewotICAgICAgICAgICAgREVDTEFSQVRJT05fSEFORExFUl9QUk9QRVJUWSwKLSAgICAgICAgICAgIExFWElDQUxfSEFORExFUl9QUk9QRVJUWSwKLSAgICAgICAgICAgIERPTV9OT0RFX1BST1BFUlRZLAotICAgICAgICAgICAgWE1MX1NUUklOR19QUk9QRVJUWSwKLSAgICB9OwotCi0gICAgLyoqIFhlcmNlcyBmZWF0dXJlcy4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSBmZ1hlcmNlc0ZlYXR1cmVzID0gewotCi0gICAgICAgIFNDSEVNQV9WQUxJREFUSU9OX0ZFQVRVUkUsCi0gICAgICAgIFNDSEVNQV9GVUxMX0NIRUNLSU5HLAotICAgICAgICBEWU5BTUlDX1ZBTElEQVRJT05fRkVBVFVSRSwKLSAgICAgICAgV0FSTl9PTl9EVVBMSUNBVEVfQVRUREVGX0ZFQVRVUkUsCi0gICAgICAgIFdBUk5fT05fVU5ERUNMQVJFRF9FTEVNREVGX0ZFQVRVUkUsCi0gICAgICAgIEFMTE9XX0pBVkFfRU5DT0RJTkdTX0ZFQVRVUkUsCi0gICAgICAgIENPTlRJTlVFX0FGVEVSX0ZBVEFMX0VSUk9SX0ZFQVRVUkUsCi0gICAgICAgIExPQURfRFREX0dSQU1NQVJfRkVBVFVSRSwKLSAgICAgICAgTE9BRF9FWFRFUk5BTF9EVERfRkVBVFVSRSwKLSAgICAgICAgLy9ERUZFUl9OT0RFX0VYUEFOU0lPTl9GRUFUVVJFLAotICAgICAgICBDUkVBVEVfRU5USVRZX1JFRl9OT0RFU19GRUFUVVJFLAotICAgICAgICBYSU5DTFVERV9BV0FSRSwKLSAgICAgICAgSU5DTFVERV9JR05PUkFCTEVfV0hJVEVTUEFDRSwKLSAgICAgICAgLy9HUkFNTUFSX0FDQ0VTU19GRUFUVVJFLAotICAgICAgICBERUZBVUxUX0FUVFJJQlVURV9WQUxVRVNfRkVBVFVSRSwKLSAgICAgICAgVkFMSURBVEVfQ09OVEVOVF9NT0RFTFNfRkVBVFVSRSwKLSAgICAgICAgVkFMSURBVEVfREFUQVRZUEVTX0ZFQVRVUkUsCi0gICAgICAgIEJBTEFOQ0VfU1lOVEFYX1RSRUVTLAotICAgICAgICBOT1RJRllfQ0hBUl9SRUZTX0ZFQVRVUkUsCi0gICAgICAgIE5PVElGWV9CVUlMVElOX1JFRlNfRkVBVFVSRSwKLSAgICAgICAgRElTQUxMT1dfRE9DVFlQRV9ERUNMX0ZFQVRVUkUsCi0gICAgICAgIFNUQU5EQVJEX1VSSV9DT05GT1JNQU5UX0ZFQVRVUkUsCi0gICAgICAgIEdFTkVSQVRFX1NZTlRIRVRJQ19BTk5PVEFUSU9OU19GRUFUVVJFLAotICAgICAgICBWQUxJREFURV9BTk5PVEFUSU9OU19GRUFUVVJFLAotICAgICAgICBIT05PVVJfQUxMX1NDSEVNQUxPQ0FUSU9OU19GRUFUVVJFLAotICAgICAgICBYSU5DTFVERV9GRUFUVVJFLAotICAgICAgICBYSU5DTFVERV9GSVhVUF9CQVNFX1VSSVNfRkVBVFVSRSwKLSAgICAgICAgWElOQ0xVREVfRklYVVBfTEFOR1VBR0VfRkVBVFVSRSwKLSAgICAgICAgTkFNRVNQQUNFX0dST1dUSF9GRUFUVVJFLAotICAgICAgICBUT0xFUkFURV9EVVBMSUNBVEVTX0ZFQVRVUkUsCi0gICAgfTsKLQotICAgIC8qKiBYZXJjZXMgcHJvcGVydGllcy4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSBmZ1hlcmNlc1Byb3BlcnRpZXMgPSB7Ci0gICAgICAgICAgICBDVVJSRU5UX0VMRU1FTlRfTk9ERV9QUk9QRVJUWSwKLSAgICAgICAgICAgIERPQ1VNRU5UX0NMQVNTX05BTUVfUFJPUEVSVFksCi0gICAgICAgICAgICBTWU1CT0xfVEFCTEVfUFJPUEVSVFksCi0gICAgICAgICAgICBFUlJPUl9IQU5ETEVSX1BST1BFUlRZLAotICAgICAgICAgICAgRVJST1JfUkVQT1JURVJfUFJPUEVSVFksCi0gICAgICAgICAgICBFTlRJVFlfTUFOQUdFUl9QUk9QRVJUWSwKLSAgICAgICAgICAgIEVOVElUWV9SRVNPTFZFUl9QUk9QRVJUWSwKLSAgICAgICAgICAgIFhNTEdSQU1NQVJfUE9PTF9QUk9QRVJUWSwKLSAgICAgICAgICAgIERBVEFUWVBFX1ZBTElEQVRPUl9GQUNUT1JZX1BST1BFUlRZLAotICAgICAgICAgICAgRE9DVU1FTlRfU0NBTk5FUl9QUk9QRVJUWSwKLSAgICAgICAgICAgIERURF9TQ0FOTkVSX1BST1BFUlRZLAotICAgICAgICAgICAgVkFMSURBVE9SX1BST1BFUlRZLAotICAgICAgICAgICAgU0NIRU1BX0xPQ0FUSU9OLAotICAgICAgICAgICAgU0NIRU1BX05PTlNfTE9DQVRJT04sCi0gICAgICAgICAgICBWQUxJREFUSU9OX01BTkFHRVJfUFJPUEVSVFksCi0gICAgICAgICAgICBCVUZGRVJfU0laRV9QUk9QRVJUWSwKLSAgICAgICAgICAgIFNFQ1VSSVRZX01BTkFHRVJfUFJPUEVSVFksCi0gICAgICAgICAgICBMT0NBTEVfUFJPUEVSVFksCi0gICAgICAgICAgICBTQ0hFTUFfRFZfRkFDVE9SWV9QUk9QRVJUWSwKLSAgICB9OwotCi0gICAgLyoqIEVtcHR5IGVudW1lcmF0aW9uLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEVudW1lcmF0aW9uIGZnRW1wdHlFbnVtZXJhdGlvbiA9IG5ldyBBcnJheUVudW1lcmF0aW9uKG5ldyBPYmplY3RbXSB7fSk7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0cnVjdG9ycwotICAgIC8vCi0KLSAgICAvKiogVGhpcyBjbGFzcyBjYW5ub3QgYmUgaW5zdGFudGlhdGVkLiAqLwotICAgIHByaXZhdGUgQ29uc3RhbnRzKCkge30KLQotICAgIC8vCi0gICAgLy8gUHVibGljIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLy8gc2F4Ci0KLSAgICAvKiogUmV0dXJucyBhbiBlbnVtZXJhdGlvbiBvZiB0aGUgU0FYIGZlYXR1cmVzLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgRW51bWVyYXRpb24gZ2V0U0FYRmVhdHVyZXMoKSB7Ci0gICAgICAgIHJldHVybiBmZ1NBWEZlYXR1cmVzLmxlbmd0aCA+IDAKLSAgICAgICAgPyBuZXcgQXJyYXlFbnVtZXJhdGlvbihmZ1NBWEZlYXR1cmVzKSA6IGZnRW1wdHlFbnVtZXJhdGlvbjsKLSAgICB9IC8vIGdldFNBWEZlYXR1cmVzKCk6RW51bWVyYXRpb24KLQotICAgIC8qKiBSZXR1cm5zIGFuIGVudW1lcmF0aW9uIG9mIHRoZSBTQVggcHJvcGVydGllcy4gKi8KLSAgICBwdWJsaWMgc3RhdGljIEVudW1lcmF0aW9uIGdldFNBWFByb3BlcnRpZXMoKSB7Ci0gICAgICAgIHJldHVybiBmZ1NBWFByb3BlcnRpZXMubGVuZ3RoID4gMAotICAgICAgICA/IG5ldyBBcnJheUVudW1lcmF0aW9uKGZnU0FYUHJvcGVydGllcykgOiBmZ0VtcHR5RW51bWVyYXRpb247Ci0gICAgfSAvLyBnZXRTQVhQcm9wZXJ0aWVzKCk6RW51bWVyYXRpb24KLQotICAgIC8vIHhlcmNlcwotCi0gICAgLyoqIFJldHVybnMgYW4gZW51bWVyYXRpb24gb2YgdGhlIFhlcmNlcyBmZWF0dXJlcy4gKi8KLSAgICBwdWJsaWMgc3RhdGljIEVudW1lcmF0aW9uIGdldFhlcmNlc0ZlYXR1cmVzKCkgewotICAgICAgICByZXR1cm4gZmdYZXJjZXNGZWF0dXJlcy5sZW5ndGggPiAwCi0gICAgICAgID8gbmV3IEFycmF5RW51bWVyYXRpb24oZmdYZXJjZXNGZWF0dXJlcykgOiBmZ0VtcHR5RW51bWVyYXRpb247Ci0gICAgfSAvLyBnZXRYZXJjZXNGZWF0dXJlcygpOkVudW1lcmF0aW9uCi0KLSAgICAvKiogUmV0dXJucyBhbiBlbnVtZXJhdGlvbiBvZiB0aGUgWGVyY2VzIHByb3BlcnRpZXMuICovCi0gICAgcHVibGljIHN0YXRpYyBFbnVtZXJhdGlvbiBnZXRYZXJjZXNQcm9wZXJ0aWVzKCkgewotICAgICAgICByZXR1cm4gZmdYZXJjZXNQcm9wZXJ0aWVzLmxlbmd0aCA+IDAKLSAgICAgICAgPyBuZXcgQXJyYXlFbnVtZXJhdGlvbihmZ1hlcmNlc1Byb3BlcnRpZXMpIDogZmdFbXB0eUVudW1lcmF0aW9uOwotICAgIH0gLy8gZ2V0WGVyY2VzUHJvcGVydGllcygpOkVudW1lcmF0aW9uCi0KLSAgICAvKgotICAgICAqIENoZWNrIHRoZSB2ZXJzaW9uIG9mIHRoZSBjdXJyZW50IEpESyBhZ2FpbnN0IHRoYXQgc3BlY2lmaWVkIGluIHRoZQotICAgICAqIHBhcmFtZXRlcgotICAgICAqCi0gICAgICogVGhlcmUgaXMgYSBwcm9wb3NhbCB0byBjaGFuZ2UgdGhlIGphdmEgdmVyc2lvbiBzdHJpbmcgdG86Ci0gICAgICogTUFKT1IuTUlOT1IuRlUuQ1BVLlBTVS1CVUlMRE5VTUJFUl9CVUdJRE5VTUJFUl9PUFRJT05BTAotICAgICAqIFRoaXMgbWV0aG9kIHdvdWxkIHdvcmsgd2l0aCBib3RoIHRoZSBjdXJyZW50IGZvcm1hdCBhbmQgdGhhdCBwcm9wb3NlZAotICAgICAqCi0gICAgICogQHBhcmFtIGNvbXBhcmVUbyBhIEpESyB2ZXJzaW9uIHRvIGJlIGNvbXBhcmVkIHRvCi0gICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBjdXJyZW50IHZlcnNpb24gaXMgdGhlIHNhbWUgb3IgYWJvdmUgdGhhdCByZXByZXNlbnRlZAotICAgICAqIGJ5IHRoZSBwYXJhbWV0ZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNKYXZhVmVyc2lvbkF0TGVhc3QoaW50IGNvbXBhcmVUbykgewotICAgICAgICBTdHJpbmcgamF2YVZlcnNpb24gPSBTZWN1cml0eVN1cHBvcnQuZ2V0U3lzdGVtUHJvcGVydHkoImphdmEudmVyc2lvbiIpOwotICAgICAgICBTdHJpbmcgdmVyc2lvbnNbXSA9IGphdmFWZXJzaW9uLnNwbGl0KCJcXC4iLCAzKTsKLSAgICAgICAgaWYgKEludGVnZXIucGFyc2VJbnQodmVyc2lvbnNbMF0pID49IGNvbXBhcmVUbyB8fAotICAgICAgICAgICAgSW50ZWdlci5wYXJzZUludCh2ZXJzaW9uc1sxXSkgPj0gY29tcGFyZVRvKSB7Ci0gICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgLy8KLSAgICAvLyBDbGFzc2VzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIEFuIGFycmF5IGVudW1lcmF0aW9uLgotICAgICAqCi0gICAgICogQGF1dGhvciBBbmR5IENsYXJrLCBJQk0KLSAgICAgKi8KLSAgICBzdGF0aWMgY2xhc3MgQXJyYXlFbnVtZXJhdGlvbgotICAgIGltcGxlbWVudHMgRW51bWVyYXRpb24gewotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIERhdGEKLSAgICAgICAgLy8KLQotICAgICAgICAvKiogQXJyYXkuICovCi0gICAgICAgIHByaXZhdGUgT2JqZWN0W10gYXJyYXk7Ci0KLSAgICAgICAgLyoqIEluZGV4LiAqLwotICAgICAgICBwcml2YXRlIGludCBpbmRleDsKLQotICAgICAgICAvLwotICAgICAgICAvLyBDb25zdHJ1Y3RvcnMKLSAgICAgICAgLy8KLQotICAgICAgICAvKiogQ29uc3RydWN0cyBhbiBhcnJheSBlbnVtZXJhdGlvbi4gKi8KLSAgICAgICAgcHVibGljIEFycmF5RW51bWVyYXRpb24oT2JqZWN0W10gYXJyYXkpIHsKLSAgICAgICAgICAgIHRoaXMuYXJyYXkgPSBhcnJheTsKLSAgICAgICAgfSAvLyA8aW5pdD4oT2JqZWN0W10pCi0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gRW51bWVyYXRpb24gbWV0aG9kcwotICAgICAgICAvLwotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBUZXN0cyBpZiB0aGlzIGVudW1lcmF0aW9uIGNvbnRhaW5zIG1vcmUgZWxlbWVudHMuCi0gICAgICAgICAqCi0gICAgICAgICAqIEByZXR1cm4gIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoaXMgZW51bWVyYXRpb24gY29udGFpbnMgbW9yZSBlbGVtZW50czsKLSAgICAgICAgICogICAgICAgICAgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4KLSAgICAgICAgICogQHNpbmNlICAgSkRLMS4wCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNNb3JlRWxlbWVudHMoKSB7Ci0gICAgICAgICAgICByZXR1cm4gaW5kZXggPCBhcnJheS5sZW5ndGg7Ci0gICAgICAgIH0gLy8gaGFzTW9yZUVsZW1lbnQoKTpib29sZWFuCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFJldHVybnMgdGhlIG5leHQgZWxlbWVudCBvZiB0aGlzIGVudW1lcmF0aW9uLgotICAgICAgICAgKgotICAgICAgICAgKiBAcmV0dXJuICAgICB0aGUgbmV4dCBlbGVtZW50IG9mIHRoaXMgZW51bWVyYXRpb24uCi0gICAgICAgICAqIEBleGNlcHRpb24gIE5vU3VjaEVsZW1lbnRFeGNlcHRpb24gIGlmIG5vIG1vcmUgZWxlbWVudHMgZXhpc3QuCi0gICAgICAgICAqIEBzaW5jZSAgICAgIEpESzEuMAotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIE9iamVjdCBuZXh0RWxlbWVudCgpIHsKLSAgICAgICAgICAgIGlmIChpbmRleCA8IGFycmF5Lmxlbmd0aCkgewotICAgICAgICAgICAgICAgIHJldHVybiBhcnJheVtpbmRleCsrXTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uKCk7Ci0gICAgICAgIH0gLy8gbmV4dEVsZW1lbnQoKTpPYmplY3QKLQotICAgIH0gLy8gY2xhc3MgQXJyYXlFbnVtZXJhdGlvbgotCi0gICAgLy8KLSAgICAvLyBNQUlOCi0gICAgLy8KLQotICAgIC8qKiBQcmludHMgYWxsIG9mIHRoZSBjb25zdGFudHMgdG8gc3RhbmRhcmQgb3V0cHV0LiAqLwotICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3YpIHsKLQotICAgICAgICBwcmludCgiU0FYIGZlYXR1cmVzOiIsIFNBWF9GRUFUVVJFX1BSRUZJWCwgZmdTQVhGZWF0dXJlcyk7Ci0gICAgICAgIHByaW50KCJTQVggcHJvcGVydGllczoiLCBTQVhfUFJPUEVSVFlfUFJFRklYLCBmZ1NBWFByb3BlcnRpZXMpOwotICAgICAgICBwcmludCgiWGVyY2VzIGZlYXR1cmVzOiIsIFhFUkNFU19GRUFUVVJFX1BSRUZJWCwgZmdYZXJjZXNGZWF0dXJlcyk7Ci0gICAgICAgIHByaW50KCJYZXJjZXMgcHJvcGVydGllczoiLCBYRVJDRVNfUFJPUEVSVFlfUFJFRklYLCBmZ1hlcmNlc1Byb3BlcnRpZXMpOwotCi0gICAgfSAvLyBtYWluKFN0cmluZ1tdKQotCi0gICAgLyoqIFByaW50cyBhIGxpc3Qgb2YgZmVhdHVyZXMvcHJvcGVydGllcy4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyB2b2lkIHByaW50KFN0cmluZyBoZWFkZXIsIFN0cmluZyBwcmVmaXgsIE9iamVjdFtdIGFycmF5KSB7Ci0gICAgICAgIFN5c3RlbS5vdXQucHJpbnQoaGVhZGVyKTsKLSAgICAgICAgaWYgKGFycmF5Lmxlbmd0aCA+IDApIHsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigpOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhcnJheS5sZW5ndGg7IGkrKykgewotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIiAgIik7Ci0gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludChwcmVmaXgpOwotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbihhcnJheVtpXSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIiBub25lLiIpOwotICAgICAgICB9Ci0gICAgfSAvLyBwcmludChTdHJpbmcsU3RyaW5nLE9iamVjdFtdKQotCi19IC8vIGNsYXNzIENvbnN0YW50cwpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9FeHRlcm5hbFN1YnNldFJlc29sdmVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL0V4dGVybmFsU3Vic2V0UmVzb2x2ZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZTg0NWE3Yy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL0V4dGVybmFsU3Vic2V0UmVzb2x2ZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDY2ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbDsKLQotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTklFeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuZ3JhbW1hcnMuWE1MRFRERGVzY3JpcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTEVudGl0eVJlc29sdmVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxJbnB1dFNvdXJjZTsKLQotLyoqCi0gKiA8cD5UaGlzIGludGVyZmFjZSBleHRlbmRzIDxjb2RlPlhNTEVudGl0eVJlc29sdmVyPC9jb2RlPiBwcm92aWRpbmcKLSAqIGEgbWV0aG9kIHRvIHJlc29sdmUgZXh0ZXJuYWwgc3Vic2V0cyBmb3IgZG9jdW1lbnRzIHdoaWNoIGRvIG5vdAotICogZXhwbGljaXRseSBwcm92aWRlIG9uZS4gVGhlIGFwcGxpY2F0aW9uIGNhbiByZWdpc3RlciBhbiBvYmplY3QgdGhhdAotICogaW1wbGVtZW50cyB0aGlzIGludGVyZmFjZSB3aXRoIHRoZSBwYXJzZXIgY29uZmlndXJhdGlvbi4gSWYgcmVnaXN0ZXJlZCwKLSAqIGl0IHdpbGwgYmUgcXVlcmllZCB0byBsb2NhdGUgYW4gZXh0ZXJuYWwgc3Vic2V0IHdoZW4gbm9uZSBpcyBwcm92aWRlZCwKLSAqIGV2ZW4gZm9yIGRvY3VtZW50cyB0aGF0IGRvIG5vdCBjb250YWluIERPQ1RZUEUgZGVjbGFyYXRpb25zLiBJZiB0aGUKLSAqIHJlZ2lzdGVyZWQgZXh0ZXJuYWwgc3Vic2V0IHJlc29sdmVyIGRvZXMgbm90IHByb3ZpZGUgYW4gZXh0ZXJuYWwgc3Vic2V0Ci0gKiBmb3IgYSBnaXZlbiBkb2N1bWVudCwgaXQgc2hvdWxkIHJldHVybiA8Y29kZT5udWxsPC9jb2RlPi48L3A+Ci0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgTWljaGFlbCBHbGF2YXNzZXZpY2gsIElCTQotICoKLSAqLwotcHVibGljIGludGVyZmFjZSBFeHRlcm5hbFN1YnNldFJlc29sdmVyCi0gICAgZXh0ZW5kcyBYTUxFbnRpdHlSZXNvbHZlciB7Ci0KLSAgICAvLwotICAgIC8vIEV4dGVybmFsU3Vic2V0UmVzb2x2ZXIgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiA8cD5Mb2NhdGVzIGFuIGV4dGVybmFsIHN1YnNldCBmb3IgZG9jdW1lbnRzIHdoaWNoIGRvIG5vdCBleHBsaWNpdGx5Ci0gICAgICogcHJvdmlkZSBvbmUuIElmIG5vIGV4dGVybmFsIHN1YnNldCBpcyBwcm92aWRlZCwgdGhpcyBtZXRob2Qgc2hvdWxkCi0gICAgICogcmV0dXJuIDxjb2RlPm51bGw8L2NvZGU+LjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBncmFtbWFyRGVzY3JpcHRpb24gYSBkZXNjcmlwdGlvbiBvZiB0aGUgRFRECi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gb24gZ2VuZXJhbCBlcnJvci4KLSAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uICBUaHJvd24gaWYgcmVzb2x2ZWQgZW50aXR5IHN0cmVhbSBjYW5ub3QgYmUKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBvcGVuZWQgb3Igc29tZSBvdGhlciBpL28gZXJyb3Igb2NjdXJzLgotICAgICAqLwotICAgIHB1YmxpYyBYTUxJbnB1dFNvdXJjZSBnZXRFeHRlcm5hbFN1YnNldChYTUxEVEREZXNjcmlwdGlvbiBncmFtbWFyRGVzY3JpcHRpb24pCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb24sIElPRXhjZXB0aW9uOwotCi19IC8vIGludGVyZmFjZSBFeHRlcm5hbFN1YnNldFJlc29sdmVyCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL1Byb3BlcnR5TWFuYWdlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9Qcm9wZXJ0eU1hbmFnZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNTAwNzE1Yi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL1Byb3BlcnR5TWFuYWdlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjIwICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTMsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlscy5YTUxTZWN1cml0eU1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlscy5YTUxTZWN1cml0eVByb3BlcnR5TWFuYWdlcjsKLWltcG9ydCBjb20uc3VuLnhtbC5pbnRlcm5hbC5zdHJlYW0uU3RheEVudGl0eVJlc29sdmVyV3JhcHBlcjsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLlhNTElucHV0RmFjdG9yeTsKLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLlhNTE91dHB1dEZhY3Rvcnk7Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5YTUxSZXNvbHZlcjsKLQotLyoqCi0gKiAgVGhpcyBjbGFzcyBtYW5hZ2VzIGRpZmZlcmVudCBwcm9wZXJ0aWVzIHJlbGF0ZWQgdG8gU3RheCBzcGVjaWZpY2F0aW9uIGFuZCBpdHMgaW1wbGVtZW50YXRpb24uCi0gKiBUaGlzIGNsYXNzIGNvbnN0cnVjdG9yIGFsc28gdGFrZXMgaXRzZWxmIChQcm9wZXJ0eU1hbmFnZXIgb2JqZWN0KSBhcyBwYXJhbWV0ZXIgYW5kIGluaXRpYWxpemVzIHRoZQotICogb2JqZWN0IHdpdGggdGhlIHByb3BlcnR5IHRha2VuIGZyb20gdGhlIG9iamVjdCBwYXNzZWQuCi0gKgotICogQGF1dGhvciAgTmVlcmFqIEJhamFqLCBuZWVyYWouYmFqYWpAc3VuLmNvbQotICogQGF1dGhvciBLLlZlbnVnb3BhbEBzdW4uY29tCi0gKiBAYXV0aG9yIFN1bml0aGEgUmVkZHksIHN1bml0aGEucmVkZHlAc3VuLmNvbQotICovCi0KLXB1YmxpYyBjbGFzcyBQcm9wZXJ0eU1hbmFnZXIgewotCi0KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBTVEFYX05PVEFUSU9OUyA9ICJqYXZheC54bWwuc3RyZWFtLm5vdGF0aW9ucyI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1RBWF9FTlRJVElFUyA9ICJqYXZheC54bWwuc3RyZWFtLmVudGl0aWVzIjsKLQotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBTVFJJTkdfSU5URVJOSU5HID0gImh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy9zdHJpbmctaW50ZXJuaW5nIjsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBTZWN1cml0eSBtYW5hZ2VyLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBTRUNVUklUWV9NQU5BR0VSID0gQ29uc3RhbnRzLlNFQ1VSSVRZX01BTkFHRVI7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogU2VjdXJpdHkgcHJvcGVydHkgbWFuYWdlci4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MX1NFQ1VSSVRZX1BST1BFUlRZX01BTkFHRVIgPQotICAgICAgICAgICAgQ29uc3RhbnRzLlhNTF9TRUNVUklUWV9QUk9QRVJUWV9NQU5BR0VSOwotCi0gICAgSGFzaE1hcCBzdXBwb3J0ZWRQcm9wcyA9IG5ldyBIYXNoTWFwKCk7Ci0KLSAgICBwcml2YXRlIFhNTFNlY3VyaXR5TWFuYWdlciBmU2VjdXJpdHlNYW5hZ2VyOwotICAgIHByaXZhdGUgWE1MU2VjdXJpdHlQcm9wZXJ0eU1hbmFnZXIgZlNlY3VyaXR5UHJvcGVydHlNZ3I7Ci0KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDT05URVhUX1JFQURFUiA9IDE7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ09OVEVYVF9XUklURVIgPSAyOwotCi0gICAgLyoqIENyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgUHJvcGVydHlNYW5hZ2VyICovCi0gICAgcHVibGljIFByb3BlcnR5TWFuYWdlcihpbnQgY29udGV4dCkgewotICAgICAgICBzd2l0Y2goY29udGV4dCl7Ci0gICAgICAgICAgICBjYXNlIENPTlRFWFRfUkVBREVSOnsKLSAgICAgICAgICAgICAgICBpbml0Q29uZmlndXJhYmxlUmVhZGVyUHJvcGVydGllcygpOwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2FzZSBDT05URVhUX1dSSVRFUjp7Ci0gICAgICAgICAgICAgICAgaW5pdFdyaXRlclByb3BzKCk7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJbml0aWFsaXplIHRoaXMgb2JqZWN0IHdpdGggdGhlIHByb3BlcnRpZXMgdGFrZW4gZnJvbSBwYXNzZWQgUHJvcGVydHlNYW5hZ2VyIG9iamVjdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgUHJvcGVydHlNYW5hZ2VyKFByb3BlcnR5TWFuYWdlciBwcm9wZXJ0eU1hbmFnZXIpewotCi0gICAgICAgIEhhc2hNYXAgcHJvcGVydGllcyA9IHByb3BlcnR5TWFuYWdlci5nZXRQcm9wZXJ0aWVzKCk7Ci0gICAgICAgIHN1cHBvcnRlZFByb3BzLnB1dEFsbChwcm9wZXJ0aWVzKTsKLSAgICAgICAgZlNlY3VyaXR5TWFuYWdlciA9IChYTUxTZWN1cml0eU1hbmFnZXIpZ2V0UHJvcGVydHkoU0VDVVJJVFlfTUFOQUdFUik7Ci0gICAgICAgIGZTZWN1cml0eVByb3BlcnR5TWdyID0gKFhNTFNlY3VyaXR5UHJvcGVydHlNYW5hZ2VyKWdldFByb3BlcnR5KFhNTF9TRUNVUklUWV9QUk9QRVJUWV9NQU5BR0VSKTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIEhhc2hNYXAgZ2V0UHJvcGVydGllcygpewotICAgICAgICByZXR1cm4gc3VwcG9ydGVkUHJvcHMgOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogSW1wb3J0YW50IHBvaW50OgotICAgICAqIDEuIFdlIGFyZSBub3QgZXhwb3NpbmcgWGVyY2VzIG5hbWVzcGFjZSBwcm9wZXJ0eS4gQXBwbGljYXRpb24gc2hvdWxkIGNvbmZpZ3VyZSBuYW1lc3BhY2UgdGhyb3VnaAotICAgICAqIFN0YXggc3BlY2lmaWMgcHJvcGVydHkuCi0gICAgICoKLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgaW5pdENvbmZpZ3VyYWJsZVJlYWRlclByb3BlcnRpZXMoKXsKLSAgICAgICAgLy9zcGVjIGRlZmF1bHQgdmFsdWVzCi0gICAgICAgIHN1cHBvcnRlZFByb3BzLnB1dChYTUxJbnB1dEZhY3RvcnkuSVNfTkFNRVNQQUNFX0FXQVJFLCBCb29sZWFuLlRSVUUpOwotICAgICAgICBzdXBwb3J0ZWRQcm9wcy5wdXQoWE1MSW5wdXRGYWN0b3J5LklTX1ZBTElEQVRJTkcsIEJvb2xlYW4uRkFMU0UpOwotICAgICAgICBzdXBwb3J0ZWRQcm9wcy5wdXQoWE1MSW5wdXRGYWN0b3J5LklTX1JFUExBQ0lOR19FTlRJVFlfUkVGRVJFTkNFUywgQm9vbGVhbi5UUlVFKTsKLSAgICAgICAgc3VwcG9ydGVkUHJvcHMucHV0KFhNTElucHV0RmFjdG9yeS5JU19TVVBQT1JUSU5HX0VYVEVSTkFMX0VOVElUSUVTLCBCb29sZWFuLlRSVUUpOwotICAgICAgICBzdXBwb3J0ZWRQcm9wcy5wdXQoWE1MSW5wdXRGYWN0b3J5LklTX0NPQUxFU0NJTkcsIEJvb2xlYW4uRkFMU0UpOwotICAgICAgICBzdXBwb3J0ZWRQcm9wcy5wdXQoWE1MSW5wdXRGYWN0b3J5LlNVUFBPUlRfRFRELCBCb29sZWFuLlRSVUUpOwotICAgICAgICBzdXBwb3J0ZWRQcm9wcy5wdXQoWE1MSW5wdXRGYWN0b3J5LlJFUE9SVEVSLCBudWxsKTsKLSAgICAgICAgc3VwcG9ydGVkUHJvcHMucHV0KFhNTElucHV0RmFjdG9yeS5SRVNPTFZFUiwgbnVsbCk7Ci0gICAgICAgIHN1cHBvcnRlZFByb3BzLnB1dChYTUxJbnB1dEZhY3RvcnkuQUxMT0NBVE9SLCBudWxsKTsKLSAgICAgICAgc3VwcG9ydGVkUHJvcHMucHV0KFNUQVhfTk9UQVRJT05TLG51bGwgKTsKLQotICAgICAgICAvL3plcGh5ciAoaW1wbGVtZW50YXRpb24pIHNwZWNpZmljIHByb3BlcnRpZXMgd2hpY2ggY2FuIGJlIHNldCBieSB0aGUgYXBwbGljYXRpb24uCi0gICAgICAgIC8vaW50ZXJuaW5nIGlzIGFsd2F5cyBkb25lCi0gICAgICAgIHN1cHBvcnRlZFByb3BzLnB1dChDb25zdGFudHMuU0FYX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLlNUUklOR19JTlRFUk5JTkdfRkVBVFVSRSAsIG5ldyBCb29sZWFuKHRydWUpKTsKLSAgICAgICAgLy9yZWNvZ25pemluZyBqYXZhIGVuY29kaW5nIG5hbWVzIGJ5IGRlZmF1bHQKLSAgICAgICAgc3VwcG9ydGVkUHJvcHMucHV0KENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuQUxMT1dfSkFWQV9FTkNPRElOR1NfRkVBVFVSRSwgIG5ldyBCb29sZWFuKHRydWUpKSA7Ci0gICAgICAgIC8vaW4gc3RheCBtb2RlLCBuYW1lc3BhY2UgZGVjbGFyYXRpb25zIGFyZSBub3QgYWRkZWQgYXMgYXR0cmlidXRlcwotICAgICAgICBzdXBwb3J0ZWRQcm9wcy5wdXQoQ29uc3RhbnRzLkFERF9OQU1FU1BBQ0VfREVDTF9BU19BVFRSSUJVVEUgLCAgQm9vbGVhbi5GQUxTRSkgOwotICAgICAgICBzdXBwb3J0ZWRQcm9wcy5wdXQoQ29uc3RhbnRzLlJFQURFUl9JTl9ERUZJTkVEX1NUQVRFLCBuZXcgQm9vbGVhbih0cnVlKSk7Ci0gICAgICAgIHN1cHBvcnRlZFByb3BzLnB1dChDb25zdGFudHMuUkVVU0VfSU5TVEFOQ0UsIG5ldyBCb29sZWFuKHRydWUpKTsKLSAgICAgICAgc3VwcG9ydGVkUHJvcHMucHV0KENvbnN0YW50cy5aRVBIWVJfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLlNUQVhfUkVQT1JUX0NEQVRBX0VWRU5UICwgbmV3IEJvb2xlYW4oZmFsc2UpKTsKLSAgICAgICAgc3VwcG9ydGVkUHJvcHMucHV0KENvbnN0YW50cy5aRVBIWVJfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLklHTk9SRV9FWFRFUk5BTF9EVEQsIEJvb2xlYW4uRkFMU0UpOwotICAgICAgICBzdXBwb3J0ZWRQcm9wcy5wdXQoQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5XQVJOX09OX0RVUExJQ0FURV9BVFRERUZfRkVBVFVSRSwgbmV3IEJvb2xlYW4oZmFsc2UpKTsKLSAgICAgICAgc3VwcG9ydGVkUHJvcHMucHV0KENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuV0FSTl9PTl9EVVBMSUNBVEVfRU5USVRZREVGX0ZFQVRVUkUsIG5ldyBCb29sZWFuKGZhbHNlKSk7Ci0gICAgICAgIHN1cHBvcnRlZFByb3BzLnB1dChDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLldBUk5fT05fVU5ERUNMQVJFRF9FTEVNREVGX0ZFQVRVUkUsIG5ldyBCb29sZWFuKGZhbHNlKSk7Ci0KLSAgICAgICAgZlNlY3VyaXR5TWFuYWdlciA9IG5ldyBYTUxTZWN1cml0eU1hbmFnZXIodHJ1ZSk7Ci0gICAgICAgIHN1cHBvcnRlZFByb3BzLnB1dChTRUNVUklUWV9NQU5BR0VSLCBmU2VjdXJpdHlNYW5hZ2VyKTsKLSAgICAgICAgZlNlY3VyaXR5UHJvcGVydHlNZ3IgPSBuZXcgWE1MU2VjdXJpdHlQcm9wZXJ0eU1hbmFnZXIoKTsKLSAgICAgICAgc3VwcG9ydGVkUHJvcHMucHV0KFhNTF9TRUNVUklUWV9QUk9QRVJUWV9NQU5BR0VSLCBmU2VjdXJpdHlQcm9wZXJ0eU1ncik7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIGluaXRXcml0ZXJQcm9wcygpewotICAgICAgICBzdXBwb3J0ZWRQcm9wcy5wdXQoWE1MT3V0cHV0RmFjdG9yeS5JU19SRVBBSVJJTkdfTkFNRVNQQUNFUyAsIEJvb2xlYW4uRkFMU0UpOwotICAgICAgICAvL2RlZmF1bHQgdmFsdWUgb2YgZXNjYXBpbmcgY2hhcmFjdGVycyBpcyAndHJ1ZScKLSAgICAgICAgc3VwcG9ydGVkUHJvcHMucHV0KENvbnN0YW50cy5FU0NBUEVfQ0hBUkFDVEVSUyAsIEJvb2xlYW4uVFJVRSk7Ci0gICAgICAgIHN1cHBvcnRlZFByb3BzLnB1dChDb25zdGFudHMuUkVVU0VfSU5TVEFOQ0UsIG5ldyBCb29sZWFuKHRydWUpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBwdWJsaWMgdm9pZCByZXNldCgpewotICAgICAqIHN1cHBvcnRlZFByb3BzLmNsZWFyKCkgOwotICAgICAqIH0KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1Byb3BlcnR5KFN0cmluZyBwcm9wZXJ0eSl7Ci0gICAgICAgIHJldHVybiBzdXBwb3J0ZWRQcm9wcy5jb250YWluc0tleShwcm9wZXJ0eSkgfHwKLSAgICAgICAgICAgICAgICAoZlNlY3VyaXR5TWFuYWdlciAhPSBudWxsICYmIGZTZWN1cml0eU1hbmFnZXIuZ2V0SW5kZXgocHJvcGVydHkpID4gLTEpIHx8Ci0gICAgICAgICAgICAgICAgKGZTZWN1cml0eVByb3BlcnR5TWdyIT1udWxsICYmIGZTZWN1cml0eVByb3BlcnR5TWdyLmdldEluZGV4KHByb3BlcnR5KSA+IC0xKSA7Ci0gICAgfQotCi0gICAgcHVibGljIE9iamVjdCBnZXRQcm9wZXJ0eShTdHJpbmcgcHJvcGVydHkpewotICAgICAgICByZXR1cm4gc3VwcG9ydGVkUHJvcHMuZ2V0KHByb3BlcnR5KTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRQcm9wZXJ0eShTdHJpbmcgcHJvcGVydHksIE9iamVjdCB2YWx1ZSl7Ci0gICAgICAgIFN0cmluZyBlcXVpdmFsZW50UHJvcGVydHkgPSBudWxsIDsKLSAgICAgICAgaWYocHJvcGVydHkgPT0gWE1MSW5wdXRGYWN0b3J5LklTX05BTUVTUEFDRV9BV0FSRSB8fCBwcm9wZXJ0eS5lcXVhbHMoWE1MSW5wdXRGYWN0b3J5LklTX05BTUVTUEFDRV9BV0FSRSkpewotICAgICAgICAgICAgZXF1aXZhbGVudFByb3BlcnR5ID0gQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5OQU1FU1BBQ0VTX0ZFQVRVUkUgOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYocHJvcGVydHkgPT0gWE1MSW5wdXRGYWN0b3J5LklTX1ZBTElEQVRJTkcgfHwgcHJvcGVydHkuZXF1YWxzKFhNTElucHV0RmFjdG9yeS5JU19WQUxJREFUSU5HKSl7Ci0gICAgICAgICAgICBpZiggKHZhbHVlIGluc3RhbmNlb2YgQm9vbGVhbikgJiYgKChCb29sZWFuKXZhbHVlKS5ib29sZWFuVmFsdWUoKSl7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInRydWUgdmFsdWUgb2YgaXNWYWxpZGF0aW5nIG5vdCBzdXBwb3J0ZWQiKSA7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZihwcm9wZXJ0eSA9PSBTVFJJTkdfSU5URVJOSU5HIHx8IHByb3BlcnR5LmVxdWFscyhTVFJJTkdfSU5URVJOSU5HKSl7Ci0gICAgICAgICAgICBpZiggKHZhbHVlIGluc3RhbmNlb2YgQm9vbGVhbikgJiYgISgoQm9vbGVhbil2YWx1ZSkuYm9vbGVhblZhbHVlKCkpewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJmYWxzZSB2YWx1ZSBvZiAiICsgU1RSSU5HX0lOVEVSTklORyArICJmZWF0dXJlIGlzIG5vdCBzdXBwb3J0ZWQiKSA7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZihwcm9wZXJ0eSA9PSBYTUxJbnB1dEZhY3RvcnkuUkVTT0xWRVIgfHwgcHJvcGVydHkuZXF1YWxzKFhNTElucHV0RmFjdG9yeS5SRVNPTFZFUikpewotICAgICAgICAgICAgLy9hZGQgaW50ZXJuYWwgc3RheCBwcm9wZXJ0eQotICAgICAgICAgICAgc3VwcG9ydGVkUHJvcHMucHV0KCBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5TVEFYX0VOVElUWV9SRVNPTFZFUl9QUk9QRVJUWSAsIG5ldyBTdGF4RW50aXR5UmVzb2x2ZXJXcmFwcGVyKChYTUxSZXNvbHZlcil2YWx1ZSkpIDsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBJdCdzIHBvc3NpYmxlIGZvciB1c2VycyB0byBzZXQgYSBzZWN1cml0eSBtYW5hZ2VyIHRocm91Z2ggdGhlIGludGVyZmFjZS4KLSAgICAgICAgICogSWYgaXQncyB0aGUgb2xkIFNlY3VyaXR5TWFuYWdlciwgY29udmVydCBpdCB0byB0aGUgbmV3IFhNTFNlY3VyaXR5TWFuYWdlcgotICAgICAgICAgKi8KLSAgICAgICAgaWYgKHByb3BlcnR5LmVxdWFscyhDb25zdGFudHMuU0VDVVJJVFlfTUFOQUdFUikpIHsKLSAgICAgICAgICAgIGZTZWN1cml0eU1hbmFnZXIgPSBYTUxTZWN1cml0eU1hbmFnZXIuY29udmVydCh2YWx1ZSwgZlNlY3VyaXR5TWFuYWdlcik7Ci0gICAgICAgICAgICBzdXBwb3J0ZWRQcm9wcy5wdXQoQ29uc3RhbnRzLlNFQ1VSSVRZX01BTkFHRVIsIGZTZWN1cml0eU1hbmFnZXIpOwotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0gICAgICAgIGlmIChwcm9wZXJ0eS5lcXVhbHMoQ29uc3RhbnRzLlhNTF9TRUNVUklUWV9QUk9QRVJUWV9NQU5BR0VSKSkgewotICAgICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmU2VjdXJpdHlQcm9wZXJ0eU1nciA9IG5ldyBYTUxTZWN1cml0eVByb3BlcnR5TWFuYWdlcigpOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBmU2VjdXJpdHlQcm9wZXJ0eU1nciA9IChYTUxTZWN1cml0eVByb3BlcnR5TWFuYWdlcil2YWx1ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHN1cHBvcnRlZFByb3BzLnB1dChDb25zdGFudHMuWE1MX1NFQ1VSSVRZX1BST1BFUlRZX01BTkFHRVIsIGZTZWN1cml0eVByb3BlcnR5TWdyKTsKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotCi0gICAgICAgIC8vY2hlY2sgaWYgdGhlIHByb3BlcnR5IGlzIG1hbmFnZWQgYnkgc2VjdXJpdHkgbWFuYWdlcgotICAgICAgICBpZiAoZlNlY3VyaXR5TWFuYWdlciA9PSBudWxsIHx8Ci0gICAgICAgICAgICAgICAgIWZTZWN1cml0eU1hbmFnZXIuc2V0TGltaXQocHJvcGVydHksIFhNTFNlY3VyaXR5TWFuYWdlci5TdGF0ZS5BUElQUk9QRVJUWSwgdmFsdWUpKSB7Ci0gICAgICAgICAgICAvL2NoZWNrIGlmIHRoZSBwcm9wZXJ0eSBpcyBtYW5hZ2VkIGJ5IHNlY3VyaXR5IHByb3BlcnR5IG1hbmFnZXIKLSAgICAgICAgICAgIGlmIChmU2VjdXJpdHlQcm9wZXJ0eU1nciA9PSBudWxsIHx8Ci0gICAgICAgICAgICAgICAgICAgICFmU2VjdXJpdHlQcm9wZXJ0eU1nci5zZXRWYWx1ZShwcm9wZXJ0eSwgWE1MU2VjdXJpdHlQcm9wZXJ0eU1hbmFnZXIuU3RhdGUuQVBJUFJPUEVSVFksIHZhbHVlKSkgewotICAgICAgICAgICAgICAgIC8vZmFsbCBiYWNrIHRvIHRoZSBleGlzdGluZyBwcm9wZXJ0eSBtYW5hZ2VyCi0gICAgICAgICAgICAgICAgc3VwcG9ydGVkUHJvcHMucHV0KHByb3BlcnR5LCB2YWx1ZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBpZihlcXVpdmFsZW50UHJvcGVydHkgIT0gbnVsbCl7Ci0gICAgICAgICAgICBzdXBwb3J0ZWRQcm9wcy5wdXQoZXF1aXZhbGVudFByb3BlcnR5LCB2YWx1ZSApIDsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKXsKLSAgICAgICAgcmV0dXJuIHN1cHBvcnRlZFByb3BzLnRvU3RyaW5nKCk7Ci0gICAgfQotCi19Ly9Qcm9wZXJ0eU1hbmFnZXIKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvUmV2YWxpZGF0aW9uSGFuZGxlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9SZXZhbGlkYXRpb25IYW5kbGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGQ1MzdkMDIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9SZXZhbGlkYXRpb25IYW5kbGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4NCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxLCAyMDAyIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYZXJjZXMiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDIsIEludGVybmF0aW9uYWwKLSAqIEJ1c2luZXNzIE1hY2hpbmVzLCBJbmMuLCBodHRwOi8vd3d3LmFwYWNoZS5vcmcuICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGw7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5BdWdtZW50YXRpb25zOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxEb2N1bWVudEZpbHRlcjsKLS8qKgotICogRE9NIFJldmFsaWRhdGlvbiBoYW5kbGVyIGFkZHMgYWRkaXRpb25hbCBmdW5jdGlvbmFsaXR5IHRvIFhNTERvY3VtZW50SGFuZGxlcgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqIEBhdXRob3IgRWxlbmEgTGl0YW5pLCBJQk0KLSAqLwotcHVibGljIGludGVyZmFjZSBSZXZhbGlkYXRpb25IYW5kbGVyIGV4dGVuZHMgWE1MRG9jdW1lbnRGaWx0ZXIgewotCi0gICAgLyoqCi0gICAgICogQ2hhcmFjdGVyIGNvbnRlbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZGF0YSAgIFRoZSBjaGFyYWN0ZXIgZGF0YS4KLSAgICAgKiBAcGFyYW0gYXVncyAgIEF1Z21lbnRhdGlvbnMKLSAgICAgKiBAcmV0dXJuIFRydWUgaWYgZGF0YSBpcyB3aGl0ZXNwYWNlIG9ubHkKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBjaGFyYWN0ZXJEYXRhKFN0cmluZyBkYXRhLCBBdWdtZW50YXRpb25zIGF1Z3MpOwotCi0KLX0gLy8gaW50ZXJmYWNlIERPTVJldmFsaWRhdGlvbkhhbmRsZXIKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvVmVyc2lvbi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9WZXJzaW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGFjNjJkYjcuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9WZXJzaW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMDIgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OS0yMDAyIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGVyY2VzIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBJbnRlcm5hdGlvbmFsCi0gKiBCdXNpbmVzcyBNYWNoaW5lcywgSW5jLiwgaHR0cDovL3d3dy5hcGFjaGUub3JnLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgZGVmaW5lcyB0aGUgdmVyc2lvbiBudW1iZXIgb2YgdGhlIHBhcnNlci4KLSAqCi0gKiBAdmVyc2lvbiAkSWQ6IFZlcnNpb24uamF2YSx2IDEuNCAyMDEwLTExLTAxIDA0OjM5OjQwIGpvZWh3IEV4cCAkCi0gKi8KLXB1YmxpYyBjbGFzcyBWZXJzaW9uIHsKLQotICAgIC8vCi0gICAgLy8gRGF0YQotICAgIC8vCi0KLSAgICAvKiogVmVyc2lvbiBzdHJpbmcuCi0gICAgICogQGRlcHJlY2F0ZWQgIGdldFZlcnNpb24oKSBzaG91bGQgYmUgdXNlZCBpbnN0ZWFkLiAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBmVmVyc2lvbiA9IGdldFZlcnNpb24oKTsKLQotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBmSW1tdXRhYmxlVmVyc2lvbiA9ICJYZXJjZXMtSiAyLjcuMSI7Ci0KLSAgICAvLyBwdWJsaWMgbWV0aG9kcwotCi0gICAgLyogUHJpbnQgb3V0IHRoZSB2ZXJzaW9uIGluZm9ybWF0aW9uLgotICAgICAqIEByZXR1cm4gdGhlIHZlcnNpb24gb2YgdGhlIHBhcnNlci4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBnZXRWZXJzaW9uKCkgewotICAgICAgICByZXR1cm4gZkltbXV0YWJsZVZlcnNpb247Ci0gICAgfSAvLyBnZXRWZXJzaW9uKCk6ICBTdHJpbmcKLQotICAgIC8vCi0gICAgLy8gTUFJTgotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBQcmludHMgb3V0IHRoZSB2ZXJzaW9uIG51bWJlciB0byBTeXN0ZW0ub3V0LiBUaGlzIGlzIG5lZWRlZAotICAgICAqIGZvciB0aGUgYnVpbGQgc3lzdGVtLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZyBhcmd2W10pIHsKLSAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKGZWZXJzaW9uKTsKLSAgICB9Ci0KLX0gLy8gY2xhc3MgVmVyc2lvbgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9YTUwxMURURFNjYW5uZXJJbXBsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL1hNTDExRFREU2Nhbm5lckltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYTQzNjFiMi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL1hNTDExRFREU2Nhbm5lckltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI1NiArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDE2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICovCi0vKgotICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCi0gKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKLSAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KLSAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCi0gKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAotICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsOwotCi1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5TeW1ib2xUYWJsZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuWE1MMTFDaGFyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5YTUxDaGFyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5YTUxTdHJpbmdCdWZmZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MU3RyaW5nOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhOSUV4Y2VwdGlvbjsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGlzIHJlc3BvbnNpYmxlIGZvciBzY2FubmluZyB0aGUgZGVjbGFyYXRpb25zIGZvdW5kCi0gKiBpbiB0aGUgaW50ZXJuYWwgYW5kIGV4dGVybmFsIHN1YnNldHMgb2YgYSBEVEQgaW4gYW4gWE1MIGRvY3VtZW50LgotICogVGhlIHNjYW5uZXIgYWN0cyBhcyB0aGUgc291cmNlcyBmb3IgdGhlIERURCBpbmZvcm1hdGlvbiB3aGljaCBpcwotICogY29tbXVuaWNhdGVkIHRvIHRoZSBEVEQgaGFuZGxlcnMuCi0gKiA8cD4KLSAqIFRoaXMgY29tcG9uZW50IHJlcXVpcmVzIHRoZSBmb2xsb3dpbmcgZmVhdHVyZXMgYW5kIHByb3BlcnRpZXMgZnJvbSB0aGUKLSAqIGNvbXBvbmVudCBtYW5hZ2VyIHRoYXQgdXNlcyBpdDoKLSAqIDx1bD4KLSAqICA8bGk+aHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL3ZhbGlkYXRpb248L2xpPgotICogIDxsaT5odHRwOi8vYXBhY2hlLm9yZy94bWwvZmVhdHVyZXMvc2Nhbm5lci9ub3RpZnktY2hhci1yZWZzPC9saT4KLSAqICA8bGk+aHR0cDovL2FwYWNoZS5vcmcveG1sL3Byb3BlcnRpZXMvaW50ZXJuYWwvc3ltYm9sLXRhYmxlPC9saT4KLSAqICA8bGk+aHR0cDovL2FwYWNoZS5vcmcveG1sL3Byb3BlcnRpZXMvaW50ZXJuYWwvZXJyb3ItcmVwb3J0ZXI8L2xpPgotICogIDxsaT5odHRwOi8vYXBhY2hlLm9yZy94bWwvcHJvcGVydGllcy9pbnRlcm5hbC9lbnRpdHktbWFuYWdlcjwvbGk+Ci0gKiA8L3VsPgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIEFybmF1ZCAgTGUgSG9ycywgSUJNCi0gKiBAYXV0aG9yIEFuZHkgQ2xhcmssIElCTQotICogQGF1dGhvciBHbGVubiBNYXJjeSwgSUJNCi0gKiBAYXV0aG9yIEVyaWMgWWUsIElCTQotICoKLSAqLwotcHVibGljIGNsYXNzIFhNTDExRFREU2Nhbm5lckltcGwKLSAgICBleHRlbmRzIFhNTERURFNjYW5uZXJJbXBsIHsKLQotICAgIC8qKiBTdHJpbmcgYnVmZmVyLiAqLwotICAgIHByaXZhdGUgWE1MU3RyaW5nQnVmZmVyIGZTdHJpbmdCdWZmZXIgPSBuZXcgWE1MU3RyaW5nQnVmZmVyKCk7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0cnVjdG9ycwotICAgIC8vCi0KLSAgICAvKiogRGVmYXVsdCBjb25zdHJ1Y3Rvci4gKi8KLSAgICBwdWJsaWMgWE1MMTFEVERTY2FubmVySW1wbCgpIHtzdXBlcigpO30gLy8gPGluaXQ+KCkKLQotICAgIC8qKiBDb25zdHJ1Y3RvciBmb3IgaGUgdXNlIG9mIG5vbi1YTUxDb21wb25lbnRNYW5hZ2Vycy4gKi8KLSAgICBwdWJsaWMgWE1MMTFEVERTY2FubmVySW1wbChTeW1ib2xUYWJsZSBzeW1ib2xUYWJsZSwKLSAgICAgICAgICAgICAgICBYTUxFcnJvclJlcG9ydGVyIGVycm9yUmVwb3J0ZXIsIFhNTEVudGl0eU1hbmFnZXIgZW50aXR5TWFuYWdlcikgewotICAgICAgICBzdXBlcihzeW1ib2xUYWJsZSwgZXJyb3JSZXBvcnRlciwgZW50aXR5TWFuYWdlcik7Ci0gICAgfQotCi0gICAgLy8KLSAgICAvLyBYTUxEVERTY2FubmVyIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLy8KLSAgICAvLyBYTUxTY2FubmVyIG1ldGhvZHMKLSAgICAvLwotICAgIC8vIE5PVEU6ICB0aGlzIGlzIGEgY2FyYm9uIGNvcHkgb2YgdGhlIGNvZGUgaW4gWE1MMTFEb2N1bWVudFNjYW5uZXJJbXBsOwotICAgIC8vIHdlIG5lZWQgdG8gb3ZlcnJpZGUgdGhlc2UgbWV0aG9kcyBpbiBib3RoIHBsYWNlcy4gIEFoIGZvcgotICAgIC8vIG11bHRpcGxlIGluaGVyaXRhbmNlLi4uCi0gICAgLy8gVGhpcyBuZWVkcyB0byBiZSByZWZhY3RvcmVkISEhICAtIE5HCi0gICAgLyoqCi0gICAgICogU2NhbnMgcHVibGljIElEIGxpdGVyYWwuCi0gICAgICoKLSAgICAgKiBbMTJdIFB1YmlkTGl0ZXJhbCA6Oj0gJyInIFB1YmlkQ2hhciogJyInIHwgIiciIChQdWJpZENoYXIgLSAiJyIpKiAiJyIKLSAgICAgKiBbMTNdIFB1YmlkQ2hhcjo6PSAjeDIwIHwgI3hEIHwgI3hBIHwgW2EtekEtWjAtOV0gfCBbLScoKSssLi86PT87ISojQCRfJV0KLSAgICAgKgotICAgICAqIFRoZSByZXR1cm5lZCBzdHJpbmcgaXMgbm9ybWFsaXplZCBhY2NvcmRpbmcgdG8gdGhlIGZvbGxvd2luZyBydWxlLAotICAgICAqIGZyb20gaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLXhtbCNkdC1wdWJpZDoKLSAgICAgKgotICAgICAqIEJlZm9yZSBhIG1hdGNoIGlzIGF0dGVtcHRlZCwgYWxsIHN0cmluZ3Mgb2Ygd2hpdGUgc3BhY2UgaW4gdGhlIHB1YmxpYwotICAgICAqIGlkZW50aWZpZXIgbXVzdCBiZSBub3JtYWxpemVkIHRvIHNpbmdsZSBzcGFjZSBjaGFyYWN0ZXJzICgjeDIwKSwgYW5kCi0gICAgICogbGVhZGluZyBhbmQgdHJhaWxpbmcgd2hpdGUgc3BhY2UgbXVzdCBiZSByZW1vdmVkLgotICAgICAqCi0gICAgICogQHBhcmFtIGxpdGVyYWwgVGhlIHN0cmluZyB0byBmaWxsIGluIHdpdGggdGhlIHB1YmxpYyBJRCBsaXRlcmFsLgotICAgICAqIEByZXR1cm4gVHJ1ZSBvbiBzdWNjZXNzLgotICAgICAqCi0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGlzIG1ldGhvZCB1c2VzIGZTdHJpbmdCdWZmZXIsIGFueXRoaW5nIGluIGl0IGF0Ci0gICAgICogdGhlIHRpbWUgb2YgY2FsbGluZyBpcyBsb3N0LgotICAgICAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIHNjYW5QdWJpZExpdGVyYWwoWE1MU3RyaW5nIGxpdGVyYWwpCi0gICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgWE5JRXhjZXB0aW9uCi0gICAgewotICAgICAgICBpbnQgcXVvdGUgPSBmRW50aXR5U2Nhbm5lci5zY2FuQ2hhcihudWxsKTsKLSAgICAgICAgaWYgKHF1b3RlICE9ICdcJycgJiYgcXVvdGUgIT0gJyInKSB7Ci0gICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJRdW90ZVJlcXVpcmVkSW5QdWJsaWNJRCIsIG51bGwpOwotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0KLSAgICAgICAgZlN0cmluZ0J1ZmZlci5jbGVhcigpOwotICAgICAgICAvLyBza2lwIGxlYWRpbmcgd2hpdGVzcGFjZQotICAgICAgICBib29sZWFuIHNraXBTcGFjZSA9IHRydWU7Ci0gICAgICAgIGJvb2xlYW4gZGF0YW9rID0gdHJ1ZTsKLSAgICAgICAgd2hpbGUgKHRydWUpIHsKLSAgICAgICAgICAgIGludCBjID0gZkVudGl0eVNjYW5uZXIuc2NhbkNoYXIobnVsbCk7Ci0gICAgICAgICAgICAvLyBSRVZJU0lUOiAgaXQgY291bGQgcmVhbGx5IG9ubHkgYmUgXG4gb3IgMHgyMDsgYWxsIGVsc2UgaXMgbm9ybWFsaXplZCwgbm8/ICAtIG5laWxnCi0gICAgICAgICAgICBpZiAoYyA9PSAnICcgfHwgYyA9PSAnXG4nIHx8IGMgPT0gJ1xyJyB8fCBjID09IDB4ODUgfHwgYyA9PSAweDIwMjgpIHsKLSAgICAgICAgICAgICAgICBpZiAoIXNraXBTcGFjZSkgewotICAgICAgICAgICAgICAgICAgICAvLyB0YWtlIHRoZSBmaXJzdCB3aGl0ZXNwYWNlIGFzIGEgc3BhY2UgYW5kIHNraXAgdGhlIG90aGVycwotICAgICAgICAgICAgICAgICAgICBmU3RyaW5nQnVmZmVyLmFwcGVuZCgnICcpOwotICAgICAgICAgICAgICAgICAgICBza2lwU3BhY2UgPSB0cnVlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKGMgPT0gcXVvdGUpIHsKLSAgICAgICAgICAgICAgICBpZiAoc2tpcFNwYWNlKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIGlmIHdlIGZpbmlzaGVkIG9uIGEgc3BhY2UgbGV0J3MgdHJpbSBpdAotICAgICAgICAgICAgICAgICAgICBmU3RyaW5nQnVmZmVyLmxlbmd0aC0tOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBsaXRlcmFsLnNldFZhbHVlcyhmU3RyaW5nQnVmZmVyKTsKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKFhNTENoYXIuaXNQdWJpZChjKSkgewotICAgICAgICAgICAgICAgIGZTdHJpbmdCdWZmZXIuYXBwZW5kKChjaGFyKWMpOwotICAgICAgICAgICAgICAgIHNraXBTcGFjZSA9IGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoYyA9PSAtMSkgewotICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIlB1YmxpY0lEVW50ZXJtaW5hdGVkIiwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgZGF0YW9rID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiSW52YWxpZENoYXJJblB1YmxpY0lEIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXtJbnRlZ2VyLnRvSGV4U3RyaW5nKGMpfSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGRhdGFvazsKLSAgIH0KLQotICAgIC8qKgotICAgICAqIE5vcm1hbGl6ZSB3aGl0ZXNwYWNlIGluIGFuIFhNTFN0cmluZyBjb252ZXJ0aW5nIGFsbCB3aGl0ZXNwYWNlCi0gICAgICogY2hhcmFjdGVycyB0byBzcGFjZSBjaGFyYWN0ZXJzLgotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIG5vcm1hbGl6ZVdoaXRlc3BhY2UoWE1MU3RyaW5nIHZhbHVlKSB7Ci0gICAgICAgIGludCBlbmQgPSB2YWx1ZS5vZmZzZXQgKyB2YWx1ZS5sZW5ndGg7Ci0gICAgICAgIGZvciAoaW50IGkgPSB2YWx1ZS5vZmZzZXQ7IGkgPCBlbmQ7ICsraSkgewotICAgICAgICAgICAgaW50IGMgPSB2YWx1ZS5jaFtpXTsKLSAgICAgICAgICAgIGlmIChYTUxDaGFyLmlzU3BhY2UoYykpIHsKLSAgICAgICAgICAgICAgICB2YWx1ZS5jaFtpXSA9ICcgJzsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIE5vcm1hbGl6ZSB3aGl0ZXNwYWNlIGluIGFuIFhNTFN0cmluZyBjb252ZXJ0aW5nIGFsbCB3aGl0ZXNwYWNlCi0gICAgICogY2hhcmFjdGVycyB0byBzcGFjZSBjaGFyYWN0ZXJzLgotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIG5vcm1hbGl6ZVdoaXRlc3BhY2UoWE1MU3RyaW5nIHZhbHVlLCBpbnQgZnJvbUluZGV4KSB7Ci0gICAgICAgIGludCBlbmQgPSB2YWx1ZS5vZmZzZXQgKyB2YWx1ZS5sZW5ndGg7Ci0gICAgICAgIGZvciAoaW50IGkgPSB2YWx1ZS5vZmZzZXQgKyBmcm9tSW5kZXg7IGkgPCBlbmQ7ICsraSkgewotICAgICAgICAgICAgaW50IGMgPSB2YWx1ZS5jaFtpXTsKLSAgICAgICAgICAgIGlmIChYTUxDaGFyLmlzU3BhY2UoYykpIHsKLSAgICAgICAgICAgICAgICB2YWx1ZS5jaFtpXSA9ICcgJzsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIENoZWNrcyB3aGV0aGVyIHRoaXMgc3RyaW5nIHdvdWxkIGJlIHVuY2hhbmdlZCBieSBub3JtYWxpemF0aW9uLgotICAgICAqCi0gICAgICogQHJldHVybiAtMSBpZiB0aGUgdmFsdWUgd291bGQgYmUgdW5jaGFuZ2VkIGJ5IG5vcm1hbGl6YXRpb24sCi0gICAgICogb3RoZXJ3aXNlIHRoZSBpbmRleCBvZiB0aGUgZmlyc3Qgd2hpdGVzcGFjZSBjaGFyYWN0ZXIgd2hpY2gKLSAgICAgKiB3b3VsZCBiZSB0cmFuc2Zvcm1lZC4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgaW50IGlzVW5jaGFuZ2VkQnlOb3JtYWxpemF0aW9uKFhNTFN0cmluZyB2YWx1ZSkgewotICAgICAgICBpbnQgZW5kID0gdmFsdWUub2Zmc2V0ICsgdmFsdWUubGVuZ3RoOwotICAgICAgICBmb3IgKGludCBpID0gdmFsdWUub2Zmc2V0OyBpIDwgZW5kOyArK2kpIHsKLSAgICAgICAgICAgIGludCBjID0gdmFsdWUuY2hbaV07Ci0gICAgICAgICAgICBpZiAoWE1MQ2hhci5pc1NwYWNlKGMpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGkgLSB2YWx1ZS5vZmZzZXQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIC0xOwotICAgIH0KLQotICAgIC8vIHJldHVybnMgdHJ1ZSBpZiB0aGUgZ2l2ZW4gY2hhcmFjdGVyIGlzIG5vdAotICAgIC8vIHZhbGlkIHdpdGggcmVzcGVjdCB0byB0aGUgdmVyc2lvbiBvZgotICAgIC8vIFhNTCB1bmRlcnN0b29kIGJ5IHRoaXMgc2Nhbm5lci4KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBpc0ludmFsaWQoaW50IHZhbHVlKSB7Ci0gICAgICAgIHJldHVybiAoIVhNTDExQ2hhci5pc1hNTDExVmFsaWQodmFsdWUpKTsKLSAgICB9IC8vIGlzSW52YWxpZChpbnQpOiAgYm9vbGVhbgotCi0gICAgLy8gcmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiBjaGFyYWN0ZXIgaXMgbm90Ci0gICAgLy8gdmFsaWQgb3IgbWF5IG5vdCBiZSB1c2VkIG91dHNpZGUgYSBjaGFyYWN0ZXIgcmVmZXJlbmNlCi0gICAgLy8gd2l0aCByZXNwZWN0IHRvIHRoZSB2ZXJzaW9uIG9mIFhNTCB1bmRlcnN0b29kIGJ5IHRoaXMgc2Nhbm5lci4KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBpc0ludmFsaWRMaXRlcmFsKGludCB2YWx1ZSkgewotICAgICAgICByZXR1cm4gKCFYTUwxMUNoYXIuaXNYTUwxMVZhbGlkTGl0ZXJhbCh2YWx1ZSkpOwotICAgIH0gLy8gaXNJbnZhbGlkTGl0ZXJhbChpbnQpOiAgYm9vbGVhbgotCi0gICAgLy8gcmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiBjaGFyYWN0ZXIgaXMKLSAgICAvLyBhIHZhbGlkIG5hbWVDaGFyIHdpdGggcmVzcGVjdCB0byB0aGUgdmVyc2lvbiBvZgotICAgIC8vIFhNTCB1bmRlcnN0b29kIGJ5IHRoaXMgc2Nhbm5lci4KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBpc1ZhbGlkTmFtZUNoYXIoaW50IHZhbHVlKSB7Ci0gICAgICAgIHJldHVybiAoWE1MMTFDaGFyLmlzWE1MMTFOYW1lKHZhbHVlKSk7Ci0gICAgfSAvLyBpc1ZhbGlkTmFtZUNoYXIoaW50KTogIGJvb2xlYW4KLQotICAgIC8vIHJldHVybnMgdHJ1ZSBpZiB0aGUgZ2l2ZW4gY2hhcmFjdGVyIGlzCi0gICAgLy8gYSB2YWxpZCBuYW1lU3RhcnRDaGFyIHdpdGggcmVzcGVjdCB0byB0aGUgdmVyc2lvbiBvZgotICAgIC8vIFhNTCB1bmRlcnN0b29kIGJ5IHRoaXMgc2Nhbm5lci4KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBpc1ZhbGlkTmFtZVN0YXJ0Q2hhcihpbnQgdmFsdWUpIHsKLSAgICAgICAgcmV0dXJuIChYTUwxMUNoYXIuaXNYTUwxMU5hbWVTdGFydCh2YWx1ZSkpOwotICAgIH0gLy8gaXNWYWxpZE5hbWVTdGFydENoYXIoaW50KTogIGJvb2xlYW4KLQotICAgIC8vIHJldHVybnMgdHJ1ZSBpZiB0aGUgZ2l2ZW4gY2hhcmFjdGVyIGlzCi0gICAgLy8gYSB2YWxpZCBOQ05hbWUgY2hhcmFjdGVyIHdpdGggcmVzcGVjdCB0byB0aGUgdmVyc2lvbiBvZgotICAgIC8vIFhNTCB1bmRlcnN0b29kIGJ5IHRoaXMgc2Nhbm5lci4KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBpc1ZhbGlkTkNOYW1lKGludCB2YWx1ZSkgewotICAgICAgICByZXR1cm4gKFhNTDExQ2hhci5pc1hNTDExTkNOYW1lKHZhbHVlKSk7Ci0gICAgfSAvLyBpc1ZhbGlkTkNOYW1lKGludCk6ICBib29sZWFuCi0KLSAgICAvLyByZXR1cm5zIHRydWUgaWYgdGhlIGdpdmVuIGNoYXJhY3RlciBpcwotICAgIC8vIGEgdmFsaWQgaGlnaCBzdXJyb2dhdGUgZm9yIGEgbmFtZVN0YXJ0Q2hhcgotICAgIC8vIHdpdGggcmVzcGVjdCB0byB0aGUgdmVyc2lvbiBvZiBYTUwgdW5kZXJzdG9vZAotICAgIC8vIGJ5IHRoaXMgc2Nhbm5lci4KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBpc1ZhbGlkTmFtZVN0YXJ0SGlnaFN1cnJvZ2F0ZShpbnQgdmFsdWUpIHsKLSAgICAgICAgcmV0dXJuIFhNTDExQ2hhci5pc1hNTDExTmFtZUhpZ2hTdXJyb2dhdGUodmFsdWUpOwotICAgIH0gLy8gaXNWYWxpZE5hbWVTdGFydEhpZ2hTdXJyb2dhdGUoaW50KTogIGJvb2xlYW4KLQotICAgIC8vIG5vdGUgdGhhdCwgYWNjb3JkaW5nIHRvIDQuMy40IG9mIHRoZSBYTUwgMS4xIHNwZWMsIFhNTCAxLjEKLSAgICAvLyBkb2N1bWVudHMgbWF5IGludm9rZSAxLjAgZW50aXRpZXM7IHRodXMgZWl0aGVyIHZlcnNpb24gZGVjbCAob3Igbm9uZSEpCi0gICAgLy8gaXMgYWxsb3dlZCB0byBhcHBlYXIgaW4gdGhpcyBjb250ZXh0Ci0gICAgcHJvdGVjdGVkIGJvb2xlYW4gdmVyc2lvblN1cHBvcnRlZChTdHJpbmcgdmVyc2lvbikgewotICAgICAgICByZXR1cm4gdmVyc2lvbi5lcXVhbHMoIjEuMSIpIHx8IHZlcnNpb24uZXF1YWxzICgiMS4wIik7Ci0gICAgfSAvLyB2ZXJzaW9uU3VwcG9ydGVkKFN0cmluZyk6ICBib29sZWFuCi0KLSAgICAvLyByZXR1cm5zIHRoZSBlcnJvciBtZXNzYWdlIGtleSBmb3IgdW5zdXBwb3J0ZWQKLSAgICAvLyB2ZXJzaW9ucyBvZiBYTUwgd2l0aCByZXNwZWN0IHRvIHRoZSB2ZXJzaW9uIG9mCi0gICAgLy8gWE1MIHVuZGVyc3Rvb2QgYnkgdGhpcyBzY2FubmVyLgotICAgIHByb3RlY3RlZCBTdHJpbmcgZ2V0VmVyc2lvbk5vdFN1cHBvcnRlZEtleSAoKSB7Ci0gICAgICAgIHJldHVybiAiVmVyc2lvbk5vdFN1cHBvcnRlZDExIjsKLSAgICB9IC8vIGdldFZlcnNpb25Ob3RTdXBwb3J0ZWRLZXk6IFN0cmluZwotCi19IC8vIGNsYXNzIFhNTDExRFREU2Nhbm5lckltcGwKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvWE1MMTFEb2N1bWVudFNjYW5uZXJJbXBsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL1hNTDExRG9jdW1lbnRTY2FubmVySW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjZWE2MjlhLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvWE1MMTFEb2N1bWVudFNjYW5uZXJJbXBsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw1MTAgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqLwotLyoKLSAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQotICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCi0gKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCi0gKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAotICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKLSAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbDsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5tc2cuWE1MTWVzc2FnZUZvcm1hdHRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuWE1MMTFDaGFyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5YTUxDaGFyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5YTUxTdHJpbmdCdWZmZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MU3RyaW5nOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhOSUV4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgaXMgcmVzcG9uc2libGUgZm9yIHNjYW5uaW5nIFhNTCBkb2N1bWVudCBzdHJ1Y3R1cmUKLSAqIGFuZCBjb250ZW50LiBUaGUgc2Nhbm5lciBhY3RzIGFzIHRoZSBzb3VyY2UgZm9yIHRoZSBkb2N1bWVudAotICogaW5mb3JtYXRpb24gd2hpY2ggaXMgY29tbXVuaWNhdGVkIHRvIHRoZSBkb2N1bWVudCBoYW5kbGVyLgotICogPHA+Ci0gKiBUaGlzIGNvbXBvbmVudCByZXF1aXJlcyB0aGUgZm9sbG93aW5nIGZlYXR1cmVzIGFuZCBwcm9wZXJ0aWVzIGZyb20gdGhlCi0gKiBjb21wb25lbnQgbWFuYWdlciB0aGF0IHVzZXMgaXQ6Ci0gKiA8dWw+Ci0gKiAgPGxpPmh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy9uYW1lc3BhY2VzPC9saT4KLSAqICA8bGk+aHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL3ZhbGlkYXRpb248L2xpPgotICogIDxsaT5odHRwOi8vYXBhY2hlLm9yZy94bWwvZmVhdHVyZXMvbm9udmFsaWRhdGluZy9sb2FkLWV4dGVybmFsLWR0ZDwvbGk+Ci0gKiAgPGxpPmh0dHA6Ly9hcGFjaGUub3JnL3htbC9mZWF0dXJlcy9zY2FubmVyL25vdGlmeS1jaGFyLXJlZnM8L2xpPgotICogIDxsaT5odHRwOi8vYXBhY2hlLm9yZy94bWwvZmVhdHVyZXMvc2Nhbm5lci9ub3RpZnktYnVpbHRpbi1yZWZzPC9saT4KLSAqICA8bGk+aHR0cDovL2FwYWNoZS5vcmcveG1sL3Byb3BlcnRpZXMvaW50ZXJuYWwvc3ltYm9sLXRhYmxlPC9saT4KLSAqICA8bGk+aHR0cDovL2FwYWNoZS5vcmcveG1sL3Byb3BlcnRpZXMvaW50ZXJuYWwvZXJyb3ItcmVwb3J0ZXI8L2xpPgotICogIDxsaT5odHRwOi8vYXBhY2hlLm9yZy94bWwvcHJvcGVydGllcy9pbnRlcm5hbC9lbnRpdHktbWFuYWdlcjwvbGk+Ci0gKiAgPGxpPmh0dHA6Ly9hcGFjaGUub3JnL3htbC9wcm9wZXJ0aWVzL2ludGVybmFsL2R0ZC1zY2FubmVyPC9saT4KLSAqIDwvdWw+Ci0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgR2xlbm4gTWFyY3ksIElCTQotICogQGF1dGhvciBBbmR5IENsYXJrLCBJQk0KLSAqIEBhdXRob3IgQXJuYXVkICBMZSBIb3JzLCBJQk0KLSAqIEBhdXRob3IgRXJpYyBZZSwgSUJNCi0gKgotICogQHZlcnNpb24gJElkOiBYTUwxMURvY3VtZW50U2Nhbm5lckltcGwuamF2YSx2IDEuNSAyMDEwLzA4LzA0IDIwOjU5OjA5IGpvZWh3IEV4cCAkCi0gKi8KLXB1YmxpYyBjbGFzcyBYTUwxMURvY3VtZW50U2Nhbm5lckltcGwKLSAgICBleHRlbmRzIFhNTERvY3VtZW50U2Nhbm5lckltcGwgewotCi0KLSAgICAvKiogU3RyaW5nIGJ1ZmZlci4gKi8KLSAgICBwcml2YXRlIGZpbmFsIFhNTFN0cmluZ0J1ZmZlciBmU3RyaW5nQnVmZmVyID0gbmV3IFhNTFN0cmluZ0J1ZmZlcigpOwotICAgIHByaXZhdGUgZmluYWwgWE1MU3RyaW5nQnVmZmVyIGZTdHJpbmdCdWZmZXIyID0gbmV3IFhNTFN0cmluZ0J1ZmZlcigpOwotICAgIHByaXZhdGUgZmluYWwgWE1MU3RyaW5nQnVmZmVyIGZTdHJpbmdCdWZmZXIzID0gbmV3IFhNTFN0cmluZ0J1ZmZlcigpOwotCi0gICAgLy8KLSAgICAvLyBDb25zdHJ1Y3RvcnMKLSAgICAvLwotCi0gICAgLyoqIERlZmF1bHQgY29uc3RydWN0b3IuICovCi0gICAgcHVibGljIFhNTDExRG9jdW1lbnRTY2FubmVySW1wbCgpIHtzdXBlcigpO30gLy8gPGluaXQ+KCkKLQotICAgIC8vCi0gICAgLy8gb3ZlcnJpZGRlbiBtZXRob2RzCi0gICAgLy8KLQotICAgIC8vIFhNTERvY3VtZW50RnJhZ21lbnRJbXBsIG1ldGhvZHMKLQotICAgIC8qKgotICAgICAqIFNjYW5zIGVsZW1lbnQgY29udGVudC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gUmV0dXJucyB0aGUgbmV4dCBjaGFyYWN0ZXIgb24gdGhlIHN0cmVhbS4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgaW50IHNjYW5Db250ZW50KFhNTFN0cmluZ0J1ZmZlciBjb250ZW50KSB0aHJvd3MgSU9FeGNlcHRpb24sIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgZlRlbXBTdHJpbmcubGVuZ3RoID0gMDsKLSAgICAgICAgaW50IGMgPSBmRW50aXR5U2Nhbm5lci5zY2FuQ29udGVudChmVGVtcFN0cmluZyk7Ci0gICAgICAgIGNvbnRlbnQuYXBwZW5kKGZUZW1wU3RyaW5nKTsKLQotICAgICAgICBpZiAoYyA9PSAnXHInIHx8IGMgPT0gMHg4NSB8fCBjID09IDB4MjAyOCkgewotICAgICAgICAgICAgLy8gaGFwcGVucyB3aGVuIHRoZXJlIGlzIHRoZSBjaGFyYWN0ZXIgcmVmZXJlbmNlICYjMTM7Ci0gICAgICAgICAgICAvLyBidXQgc2NhbkNvbnRlbnQgZG9lc24ndCBkbyBlbnRpdHkgZXhwYW5zaW9ucy4uLgotICAgICAgICAgICAgLy8gaXMgdGhpcyAqcmVhbGx5KiBuZWNlc3Nhcnk/Pz8gIC0gTkcKLSAgICAgICAgICAgIGZFbnRpdHlTY2FubmVyLnNjYW5DaGFyKG51bGwpOwotICAgICAgICAgICAgY29udGVudC5hcHBlbmQoKGNoYXIpYyk7Ci0gICAgICAgICAgICBjID0gLTE7Ci0gICAgICAgIH0KLSAgICAgICAgLyppZiAoZkRvY3VtZW50SGFuZGxlciAhPSBudWxsICYmIGNvbnRlbnQubGVuZ3RoID4gMCkgewotICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci5jaGFyYWN0ZXJzKGNvbnRlbnQsIG51bGwpOwotICAgICAgICB9ICovCi0KLSAgICAgICAgaWYgKGMgPT0gJ10nKSB7Ci0gICAgICAgICAgICBjb250ZW50LmFwcGVuZCgoY2hhcilmRW50aXR5U2Nhbm5lci5zY2FuQ2hhcihudWxsKSk7Ci0gICAgICAgICAgICAvLyByZW1lbWJlciB3aGVyZSB3ZSBhcmUgaW4gY2FzZSB3ZSBnZXQgYW4gZW5kRW50aXR5IGJlZm9yZSB3ZQotICAgICAgICAgICAgLy8gY291bGQgZmx1c2ggdGhlIGJ1ZmZlciBvdXQgLSB0aGlzIGhhcHBlbnMgd2hlbiB3ZSdyZSBwYXJzaW5nIGFuCi0gICAgICAgICAgICAvLyBlbnRpdHkgd2hpY2ggZW5kcyB3aXRoIGEgXQotICAgICAgICAgICAgZkluU2NhbkNvbnRlbnQgPSB0cnVlOwotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIC8vIFdlIHdvcmsgb24gYSBzaW5nbGUgY2hhcmFjdGVyIGJhc2lzIHRvIGhhbmRsZSBjYXNlcyBzdWNoIGFzOgotICAgICAgICAgICAgLy8gJ11dXT4nIHdoaWNoIHdlIG1pZ2h0IG90aGVyd2lzZSBtaXNzLgotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIGlmIChmRW50aXR5U2Nhbm5lci5za2lwQ2hhcignXScsIG51bGwpKSB7Ci0gICAgICAgICAgICAgICAgY29udGVudC5hcHBlbmQoJ10nKTsKLSAgICAgICAgICAgICAgICB3aGlsZSAoZkVudGl0eVNjYW5uZXIuc2tpcENoYXIoJ10nLCBudWxsKSkgewotICAgICAgICAgICAgICAgICAgICBjb250ZW50LmFwcGVuZCgnXScpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpZiAoZkVudGl0eVNjYW5uZXIuc2tpcENoYXIoJz4nLCBudWxsKSkgewotICAgICAgICAgICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJDREVuZEluQ29udGVudCIsIG51bGwpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8qaWYgKGZEb2N1bWVudEhhbmRsZXIgIT0gbnVsbCAmJiBmU3RyaW5nQnVmZmVyLmxlbmd0aCAhPSAwKSB7Ci0gICAgICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci5jaGFyYWN0ZXJzKGZTdHJpbmdCdWZmZXIsIG51bGwpOwotICAgICAgICAgICAgfSovCi0gICAgICAgICAgICBmSW5TY2FuQ29udGVudCA9IGZhbHNlOwotICAgICAgICAgICAgYyA9IC0xOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBjOwotCi0gICAgfSAvLyBzY2FuQ29udGVudCgpOmludAotCi0gICAgLyoqCi0gICAgICogU2NhbnMgYW4gYXR0cmlidXRlIHZhbHVlIGFuZCBub3JtYWxpemVzIHdoaXRlc3BhY2UgY29udmVydGluZyBhbGwKLSAgICAgKiB3aGl0ZXNwYWNlIGNoYXJhY3RlcnMgdG8gc3BhY2UgY2hhcmFjdGVycy4KLSAgICAgKgotICAgICAqIFsxMF0gQXR0VmFsdWUgOjo9ICciJyAoW148JiJdIHwgUmVmZXJlbmNlKSogJyInIHwgIiciIChbXjwmJ10gfCBSZWZlcmVuY2UpKiAiJyIKLSAgICAgKgotICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgWE1MU3RyaW5nIHRvIGZpbGwgaW4gd2l0aCB0aGUgdmFsdWUuCi0gICAgICogQHBhcmFtIG5vbk5vcm1hbGl6ZWRWYWx1ZSBUaGUgWE1MU3RyaW5nIHRvIGZpbGwgaW4gd2l0aCB0aGUKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vbi1ub3JtYWxpemVkIHZhbHVlLgotICAgICAqIEBwYXJhbSBhdE5hbWUgVGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZSBiZWluZyBwYXJzZWQgKGZvciBlcnJvciBtc2dzKS4KLSAgICAgKiBAcGFyYW0gY2hlY2tFbnRpdGllcyB0cnVlIGlmIHVuZGVjbGFyZWQgZW50aXRpZXMgc2hvdWxkIGJlIHJlcG9ydGVkIGFzIFZDIHZpb2xhdGlvbiwKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBmYWxzZSBpZiB1bmRlY2xhcmVkIGVudGl0aWVzIHNob3VsZCBiZSByZXBvcnRlZCBhcyBXRkMgdmlvbGF0aW9uLgotICAgICAqIEBwYXJhbSBlbGVOYW1lIFRoZSBuYW1lIG9mIGVsZW1lbnQgdG8gd2hpY2ggdGhpcyBhdHRyaWJ1dGUgYmVsb25ncy4KLSAgICAgKiBAcGFyYW0gaXNOU1VSSSBUaGUgZmxhZyBpbmRpY2F0aW5nIHdoZXRoZXIgdGhlIGNvbnRlbnQgaXMgYSBuYW1lc3BhY2UgVVJJCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIG5vbi1ub3JtYWxpemVkIGFuZCBub3JtYWxpemVkIHZhbHVlIGFyZSB0aGUgc2FtZQotICAgICAqCi0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGlzIG1ldGhvZCB1c2VzIGZTdHJpbmdCdWZmZXIyLCBhbnl0aGluZyBpbiBpdAotICAgICAqIGF0IHRoZSB0aW1lIG9mIGNhbGxpbmcgaXMgbG9zdC4KLSAgICAgKiovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gc2NhbkF0dHJpYnV0ZVZhbHVlKFhNTFN0cmluZyB2YWx1ZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MU3RyaW5nIG5vbk5vcm1hbGl6ZWRWYWx1ZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGF0TmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBjaGVja0VudGl0aWVzLFN0cmluZyBlbGVOYW1lLCBib29sZWFuIGlzTlNVUkkpCi0gICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgWE5JRXhjZXB0aW9uCi0gICAgewotICAgICAgICAvLyBxdW90ZQotICAgICAgICBpbnQgcXVvdGUgPSBmRW50aXR5U2Nhbm5lci5wZWVrQ2hhcigpOwotICAgICAgICBpZiAocXVvdGUgIT0gJ1wnJyAmJiBxdW90ZSAhPSAnIicpIHsKLSAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIk9wZW5RdW90ZUV4cGVjdGVkIiwgbmV3IE9iamVjdFtde2VsZU5hbWUsYXROYW1lfSk7Ci0gICAgICAgIH0KLQotICAgICAgICBmRW50aXR5U2Nhbm5lci5zY2FuQ2hhcihOYW1lVHlwZS5BVFRSSUJVVEUpOwotICAgICAgICBpbnQgZW50aXR5RGVwdGggPSBmRW50aXR5RGVwdGg7Ci0KLSAgICAgICAgaW50IGMgPSBmRW50aXR5U2Nhbm5lci5zY2FuTGl0ZXJhbChxdW90ZSwgdmFsdWUsIGlzTlNVUkkpOwotICAgICAgICBpZiAoREVCVUdfQVRUUl9OT1JNQUxJWkFUSU9OKSB7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIioqIHNjYW5MaXRlcmFsIC0+IFwiIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgdmFsdWUudG9TdHJpbmcoKSArICJcIiIpOwotICAgICAgICB9Ci0KLSAgICAgICAgaW50IGZyb21JbmRleCA9IDA7Ci0gICAgICAgIGlmIChjID09IHF1b3RlICYmIChmcm9tSW5kZXggPSBpc1VuY2hhbmdlZEJ5Tm9ybWFsaXphdGlvbih2YWx1ZSkpID09IC0xKSB7Ci0gICAgICAgICAgICAvKiogQm90aCB0aGUgbm9uLW5vcm1hbGl6ZWQgYW5kIG5vcm1hbGl6ZWQgYXR0cmlidXRlIHZhbHVlcyBhcmUgZXF1YWwuICoqLwotICAgICAgICAgICAgbm9uTm9ybWFsaXplZFZhbHVlLnNldFZhbHVlcyh2YWx1ZSk7Ci0gICAgICAgICAgICBpbnQgY3F1b3RlID0gZkVudGl0eVNjYW5uZXIuc2NhbkNoYXIoTmFtZVR5cGUuQVRUUklCVVRFKTsKLSAgICAgICAgICAgIGlmIChjcXVvdGUgIT0gcXVvdGUpIHsKLSAgICAgICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJDbG9zZVF1b3RlRXhwZWN0ZWQiLCBuZXcgT2JqZWN0W117ZWxlTmFtZSxhdE5hbWV9KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0gICAgICAgIGZTdHJpbmdCdWZmZXIyLmNsZWFyKCk7Ci0gICAgICAgIGZTdHJpbmdCdWZmZXIyLmFwcGVuZCh2YWx1ZSk7Ci0gICAgICAgIG5vcm1hbGl6ZVdoaXRlc3BhY2UodmFsdWUsIGZyb21JbmRleCk7Ci0gICAgICAgIGlmIChERUJVR19BVFRSX05PUk1BTElaQVRJT04pIHsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiKiogbm9ybWFsaXplV2hpdGVzcGFjZSAtPiBcIiIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIHZhbHVlLnRvU3RyaW5nKCkgKyAiXCIiKTsKLSAgICAgICAgfQotICAgICAgICBpZiAoYyAhPSBxdW90ZSkgewotICAgICAgICAgICAgZlNjYW5uaW5nQXR0cmlidXRlID0gdHJ1ZTsKLSAgICAgICAgICAgIGZTdHJpbmdCdWZmZXIuY2xlYXIoKTsKLSAgICAgICAgICAgIGRvIHsKLSAgICAgICAgICAgICAgICBmU3RyaW5nQnVmZmVyLmFwcGVuZCh2YWx1ZSk7Ci0gICAgICAgICAgICAgICAgaWYgKERFQlVHX0FUVFJfTk9STUFMSVpBVElPTikgewotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIioqIHZhbHVlMjogXCIiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGZTdHJpbmdCdWZmZXIudG9TdHJpbmcoKSArICJcIiIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpZiAoYyA9PSAnJicpIHsKLSAgICAgICAgICAgICAgICAgICAgZkVudGl0eVNjYW5uZXIuc2tpcENoYXIoJyYnLCBOYW1lVHlwZS5SRUZFUkVOQ0UpOwotICAgICAgICAgICAgICAgICAgICBpZiAoZW50aXR5RGVwdGggPT0gZkVudGl0eURlcHRoKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmU3RyaW5nQnVmZmVyMi5hcHBlbmQoJyYnKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBpZiAoZkVudGl0eVNjYW5uZXIuc2tpcENoYXIoJyMnLCBOYW1lVHlwZS5SRUZFUkVOQ0UpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZW50aXR5RGVwdGggPT0gZkVudGl0eURlcHRoKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZlN0cmluZ0J1ZmZlcjIuYXBwZW5kKCcjJyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBpbnQgY2ggPSBzY2FuQ2hhclJlZmVyZW5jZVZhbHVlKGZTdHJpbmdCdWZmZXIsIGZTdHJpbmdCdWZmZXIyKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjaCAhPSAtMSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChERUJVR19BVFRSX05PUk1BTElaQVRJT04pIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCIqKiB2YWx1ZTM6IFwiIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBmU3RyaW5nQnVmZmVyLnRvU3RyaW5nKCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIlwiIik7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGVudGl0eU5hbWUgPSBmRW50aXR5U2Nhbm5lci5zY2FuTmFtZShOYW1lVHlwZS5SRUZFUkVOQ0UpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVudGl0eU5hbWUgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIk5hbWVSZXF1aXJlZEluUmVmZXJlbmNlIiwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChlbnRpdHlEZXB0aCA9PSBmRW50aXR5RGVwdGgpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmU3RyaW5nQnVmZmVyMi5hcHBlbmQoZW50aXR5TmFtZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWZFbnRpdHlTY2FubmVyLnNraXBDaGFyKCc7JywgTmFtZVR5cGUuUkVGRVJFTkNFKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIlNlbWljb2xvblJlcXVpcmVkSW5SZWZlcmVuY2UiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdCBbXXtlbnRpdHlOYW1lfSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChlbnRpdHlEZXB0aCA9PSBmRW50aXR5RGVwdGgpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmU3RyaW5nQnVmZmVyMi5hcHBlbmQoJzsnKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXNvbHZlQ2hhcmFjdGVyKGVudGl0eU5hbWUsIGZTdHJpbmdCdWZmZXIpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tFbnRpdHlMaW1pdChmYWxzZSwgZkVudGl0eVNjYW5uZXIuZkN1cnJlbnRFbnRpdHkubmFtZSwgMSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZkVudGl0eU1hbmFnZXIuaXNFeHRlcm5hbEVudGl0eShlbnRpdHlOYW1lKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJSZWZlcmVuY2VUb0V4dGVybmFsRW50aXR5IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBlbnRpdHlOYW1lIH0pOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFmRW50aXR5TWFuYWdlci5pc0RlY2xhcmVkRW50aXR5KGVudGl0eU5hbWUpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL1dGQyAmIFZDOiBFbnRpdHkgRGVjbGFyZWQKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjaGVja0VudGl0aWVzKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZWYWxpZGF0aW9uKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkVudGl0eU5vdERlY2xhcmVkIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde2VudGl0eU5hbWV9LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxFcnJvclJlcG9ydGVyLlNFVkVSSVRZX0VSUk9SKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJFbnRpdHlOb3REZWNsYXJlZCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117ZW50aXR5TmFtZX0pOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZFbnRpdHlNYW5hZ2VyLnN0YXJ0RW50aXR5KHRydWUsIGVudGl0eU5hbWUsIHRydWUpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIGlmIChjID09ICc8JykgewotICAgICAgICAgICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJMZXNzdGhhbkluQXR0VmFsdWUiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7IGVsZU5hbWUsIGF0TmFtZSB9KTsKLSAgICAgICAgICAgICAgICAgICAgZkVudGl0eVNjYW5uZXIuc2NhbkNoYXIobnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChlbnRpdHlEZXB0aCA9PSBmRW50aXR5RGVwdGgpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZTdHJpbmdCdWZmZXIyLmFwcGVuZCgoY2hhciljKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIGlmIChjID09ICclJyB8fCBjID09ICddJykgewotICAgICAgICAgICAgICAgICAgICBmRW50aXR5U2Nhbm5lci5zY2FuQ2hhcihudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgZlN0cmluZ0J1ZmZlci5hcHBlbmQoKGNoYXIpYyk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChlbnRpdHlEZXB0aCA9PSBmRW50aXR5RGVwdGgpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZTdHJpbmdCdWZmZXIyLmFwcGVuZCgoY2hhciljKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBpZiAoREVCVUdfQVRUUl9OT1JNQUxJWkFUSU9OKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIioqIHZhbHVlRjogXCIiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBmU3RyaW5nQnVmZmVyLnRvU3RyaW5nKCkgKyAiXCIiKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvLyBub3RlIHRoYXQgbm9uZSBvZiB0aGVzZSBjaGFyYWN0ZXJzIHNob3VsZCBldmVyIGdldCB0aHJvdWdoCi0gICAgICAgICAgICAgICAgLy8gWE1MMTFFbnRpdHlTY2FubmVyLiAgTm90IHN1cmUgd2h5Ci0gICAgICAgICAgICAgICAgLy8gdGhpcyBjaGVjayB3YXMgb3JpZ2luYWxseSBuZWNlc3NhcnkuICAtIE5HCi0gICAgICAgICAgICAgICAgZWxzZSBpZiAoYyA9PSAnXG4nIHx8IGMgPT0gJ1xyJyB8fCBjID09IDB4ODUgfHwgYyA9PSAweDIwMjgpIHsKLSAgICAgICAgICAgICAgICAgICAgZkVudGl0eVNjYW5uZXIuc2NhbkNoYXIobnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgIGZTdHJpbmdCdWZmZXIuYXBwZW5kKCcgJyk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChlbnRpdHlEZXB0aCA9PSBmRW50aXR5RGVwdGgpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZTdHJpbmdCdWZmZXIyLmFwcGVuZCgnXG4nKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIGlmIChjICE9IC0xICYmIFhNTENoYXIuaXNIaWdoU3Vycm9nYXRlKGMpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZTdHJpbmdCdWZmZXIzLmNsZWFyKCk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChzY2FuU3Vycm9nYXRlcyhmU3RyaW5nQnVmZmVyMykpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZTdHJpbmdCdWZmZXIuYXBwZW5kKGZTdHJpbmdCdWZmZXIzKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlbnRpdHlEZXB0aCA9PSBmRW50aXR5RGVwdGgpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmU3RyaW5nQnVmZmVyMi5hcHBlbmQoZlN0cmluZ0J1ZmZlcjMpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKERFQlVHX0FUVFJfTk9STUFMSVpBVElPTikgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiKiogdmFsdWVJOiBcIiIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBmU3RyaW5nQnVmZmVyLnRvU3RyaW5nKCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiXCIiKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIGlmIChjICE9IC0xICYmIGlzSW52YWxpZExpdGVyYWwoYykpIHsKLSAgICAgICAgICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiSW52YWxpZENoYXJJbkF0dFZhbHVlIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10ge2VsZU5hbWUsIGF0TmFtZSwgSW50ZWdlci50b1N0cmluZyhjLCAxNil9KTsKLSAgICAgICAgICAgICAgICAgICAgZkVudGl0eVNjYW5uZXIuc2NhbkNoYXIobnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChlbnRpdHlEZXB0aCA9PSBmRW50aXR5RGVwdGgpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZTdHJpbmdCdWZmZXIyLmFwcGVuZCgoY2hhciljKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBjID0gZkVudGl0eVNjYW5uZXIuc2NhbkxpdGVyYWwocXVvdGUsIHZhbHVlLCBpc05TVVJJKTsKLSAgICAgICAgICAgICAgICBpZiAoZW50aXR5RGVwdGggPT0gZkVudGl0eURlcHRoKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZTdHJpbmdCdWZmZXIyLmFwcGVuZCh2YWx1ZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIG5vcm1hbGl6ZVdoaXRlc3BhY2UodmFsdWUpOwotICAgICAgICAgICAgfSB3aGlsZSAoYyAhPSBxdW90ZSB8fCBlbnRpdHlEZXB0aCAhPSBmRW50aXR5RGVwdGgpOwotICAgICAgICAgICAgZlN0cmluZ0J1ZmZlci5hcHBlbmQodmFsdWUpOwotICAgICAgICAgICAgaWYgKERFQlVHX0FUVFJfTk9STUFMSVpBVElPTikgewotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiKiogdmFsdWVOOiBcIiIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBmU3RyaW5nQnVmZmVyLnRvU3RyaW5nKCkgKyAiXCIiKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHZhbHVlLnNldFZhbHVlcyhmU3RyaW5nQnVmZmVyKTsKLSAgICAgICAgICAgIGZTY2FubmluZ0F0dHJpYnV0ZSA9IGZhbHNlOwotICAgICAgICB9Ci0gICAgICAgIG5vbk5vcm1hbGl6ZWRWYWx1ZS5zZXRWYWx1ZXMoZlN0cmluZ0J1ZmZlcjIpOwotCi0gICAgICAgIC8vIHF1b3RlCi0gICAgICAgIGludCBjcXVvdGUgPSBmRW50aXR5U2Nhbm5lci5zY2FuQ2hhcihudWxsKTsKLSAgICAgICAgaWYgKGNxdW90ZSAhPSBxdW90ZSkgewotICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiQ2xvc2VRdW90ZUV4cGVjdGVkIiwgbmV3IE9iamVjdFtde2VsZU5hbWUsYXROYW1lfSk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG5vbk5vcm1hbGl6ZWRWYWx1ZS5lcXVhbHModmFsdWUuY2gsIHZhbHVlLm9mZnNldCwgdmFsdWUubGVuZ3RoKTsKLSAgICB9IC8vIHNjYW5BdHRyaWJ1dGVWYWx1ZSgpCi0KLSAgICAvLwotICAgIC8vIFhNTFNjYW5uZXIgbWV0aG9kcwotICAgIC8vCi0gICAgLy8gTk9URTogIHRoaXMgaXMgYSBjYXJib24gY29weSBvZiB0aGUgY29kZSBpbiBYTUwxMURURFNjYW5uZXJJbXBsOwotICAgIC8vIHdlIG5lZWQgdG8gb3ZlcnJpZGUgdGhlc2UgbWV0aG9kcyBpbiBib3RoIHBsYWNlcy4KLSAgICAvLyB0aGlzIG5lZWRzIHRvIGJlIHJlZmFjdG9yZWQhISEgIC0gTkcKLSAgICAvKioKLSAgICAgKiBTY2FucyBwdWJsaWMgSUQgbGl0ZXJhbC4KLSAgICAgKgotICAgICAqIFsxMl0gUHViaWRMaXRlcmFsIDo6PSAnIicgUHViaWRDaGFyKiAnIicgfCAiJyIgKFB1YmlkQ2hhciAtICInIikqICInIgotICAgICAqIFsxM10gUHViaWRDaGFyOjo9ICN4MjAgfCAjeEQgfCAjeEEgfCBbYS16QS1aMC05XSB8IFstJygpKywuLzo9PzshKiNAJF8lXQotICAgICAqCi0gICAgICogVGhlIHJldHVybmVkIHN0cmluZyBpcyBub3JtYWxpemVkIGFjY29yZGluZyB0byB0aGUgZm9sbG93aW5nIHJ1bGUsCi0gICAgICogZnJvbSBodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMteG1sI2R0LXB1YmlkOgotICAgICAqCi0gICAgICogQmVmb3JlIGEgbWF0Y2ggaXMgYXR0ZW1wdGVkLCBhbGwgc3RyaW5ncyBvZiB3aGl0ZSBzcGFjZSBpbiB0aGUgcHVibGljCi0gICAgICogaWRlbnRpZmllciBtdXN0IGJlIG5vcm1hbGl6ZWQgdG8gc2luZ2xlIHNwYWNlIGNoYXJhY3RlcnMgKCN4MjApLCBhbmQKLSAgICAgKiBsZWFkaW5nIGFuZCB0cmFpbGluZyB3aGl0ZSBzcGFjZSBtdXN0IGJlIHJlbW92ZWQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbGl0ZXJhbCBUaGUgc3RyaW5nIHRvIGZpbGwgaW4gd2l0aCB0aGUgcHVibGljIElEIGxpdGVyYWwuCi0gICAgICogQHJldHVybiBUcnVlIG9uIHN1Y2Nlc3MuCi0gICAgICoKLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoaXMgbWV0aG9kIHVzZXMgZlN0cmluZ0J1ZmZlciwgYW55dGhpbmcgaW4gaXQgYXQKLSAgICAgKiB0aGUgdGltZSBvZiBjYWxsaW5nIGlzIGxvc3QuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gc2NhblB1YmlkTGl0ZXJhbChYTUxTdHJpbmcgbGl0ZXJhbCkKLSAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBYTklFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGludCBxdW90ZSA9IGZFbnRpdHlTY2FubmVyLnNjYW5DaGFyKG51bGwpOwotICAgICAgICBpZiAocXVvdGUgIT0gJ1wnJyAmJiBxdW90ZSAhPSAnIicpIHsKLSAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIlF1b3RlUmVxdWlyZWRJblB1YmxpY0lEIiwgbnVsbCk7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLQotICAgICAgICBmU3RyaW5nQnVmZmVyLmNsZWFyKCk7Ci0gICAgICAgIC8vIHNraXAgbGVhZGluZyB3aGl0ZXNwYWNlCi0gICAgICAgIGJvb2xlYW4gc2tpcFNwYWNlID0gdHJ1ZTsKLSAgICAgICAgYm9vbGVhbiBkYXRhb2sgPSB0cnVlOwotICAgICAgICB3aGlsZSAodHJ1ZSkgewotICAgICAgICAgICAgaW50IGMgPSBmRW50aXR5U2Nhbm5lci5zY2FuQ2hhcihudWxsKTsKLSAgICAgICAgICAgIC8vIFJFVklTSVQ6ICBub25lIG9mIHRoZXNlIGV4Y2VwdCBcbiBhbmQgMHgyMCBzaG91bGQgbWFrZSBpdCBwYXN0IHRoZSBlbnRpdHkgc2Nhbm5lcgotICAgICAgICAgICAgaWYgKGMgPT0gJyAnIHx8IGMgPT0gJ1xuJyB8fCBjID09ICdccicgfHwgYyA9PSAweDg1IHx8IGMgPT0gMHgyMDI4KSB7Ci0gICAgICAgICAgICAgICAgaWYgKCFza2lwU3BhY2UpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gdGFrZSB0aGUgZmlyc3Qgd2hpdGVzcGFjZSBhcyBhIHNwYWNlIGFuZCBza2lwIHRoZSBvdGhlcnMKLSAgICAgICAgICAgICAgICAgICAgZlN0cmluZ0J1ZmZlci5hcHBlbmQoJyAnKTsKLSAgICAgICAgICAgICAgICAgICAgc2tpcFNwYWNlID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChjID09IHF1b3RlKSB7Ci0gICAgICAgICAgICAgICAgaWYgKHNraXBTcGFjZSkgewotICAgICAgICAgICAgICAgICAgICAvLyBpZiB3ZSBmaW5pc2hlZCBvbiBhIHNwYWNlIGxldCdzIHRyaW0gaXQKLSAgICAgICAgICAgICAgICAgICAgZlN0cmluZ0J1ZmZlci5sZW5ndGgtLTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgbGl0ZXJhbC5zZXRWYWx1ZXMoZlN0cmluZ0J1ZmZlcik7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChYTUxDaGFyLmlzUHViaWQoYykpIHsKLSAgICAgICAgICAgICAgICBmU3RyaW5nQnVmZmVyLmFwcGVuZCgoY2hhciljKTsKLSAgICAgICAgICAgICAgICBza2lwU3BhY2UgPSBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKGMgPT0gLTEpIHsKLSAgICAgICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJQdWJsaWNJRFVudGVybWluYXRlZCIsIG51bGwpOwotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIGRhdGFvayA9IGZhbHNlOwotICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIkludmFsaWRDaGFySW5QdWJsaWNJRCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117SW50ZWdlci50b0hleFN0cmluZyhjKX0pOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBkYXRhb2s7Ci0gICB9Ci0KLSAgICAvKioKLSAgICAgKiBOb3JtYWxpemUgd2hpdGVzcGFjZSBpbiBhbiBYTUxTdHJpbmcgY29udmVydGluZyBhbGwgd2hpdGVzcGFjZQotICAgICAqIGNoYXJhY3RlcnMgdG8gc3BhY2UgY2hhcmFjdGVycy4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCBub3JtYWxpemVXaGl0ZXNwYWNlKFhNTFN0cmluZyB2YWx1ZSkgewotICAgICAgICBpbnQgZW5kID0gdmFsdWUub2Zmc2V0ICsgdmFsdWUubGVuZ3RoOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IHZhbHVlLm9mZnNldDsgaSA8IGVuZDsgKytpKSB7Ci0gICAgICAgICAgIGludCBjID0gdmFsdWUuY2hbaV07Ci0gICAgICAgICAgIGlmIChYTUxDaGFyLmlzU3BhY2UoYykpIHsKLSAgICAgICAgICAgICAgIHZhbHVlLmNoW2ldID0gJyAnOwotICAgICAgICAgICB9Ci0gICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIE5vcm1hbGl6ZSB3aGl0ZXNwYWNlIGluIGFuIFhNTFN0cmluZyBjb252ZXJ0aW5nIGFsbCB3aGl0ZXNwYWNlCi0gICAgICogY2hhcmFjdGVycyB0byBzcGFjZSBjaGFyYWN0ZXJzLgotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIG5vcm1hbGl6ZVdoaXRlc3BhY2UoWE1MU3RyaW5nIHZhbHVlLCBpbnQgZnJvbUluZGV4KSB7Ci0gICAgICAgIGludCBlbmQgPSB2YWx1ZS5vZmZzZXQgKyB2YWx1ZS5sZW5ndGg7Ci0gICAgICAgIGZvciAoaW50IGkgPSB2YWx1ZS5vZmZzZXQgKyBmcm9tSW5kZXg7IGkgPCBlbmQ7ICsraSkgewotICAgICAgICAgICAgaW50IGMgPSB2YWx1ZS5jaFtpXTsKLSAgICAgICAgICAgIGlmIChYTUxDaGFyLmlzU3BhY2UoYykpIHsKLSAgICAgICAgICAgICAgICB2YWx1ZS5jaFtpXSA9ICcgJzsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIENoZWNrcyB3aGV0aGVyIHRoaXMgc3RyaW5nIHdvdWxkIGJlIHVuY2hhbmdlZCBieSBub3JtYWxpemF0aW9uLgotICAgICAqCi0gICAgICogQHJldHVybiAtMSBpZiB0aGUgdmFsdWUgd291bGQgYmUgdW5jaGFuZ2VkIGJ5IG5vcm1hbGl6YXRpb24sCi0gICAgICogb3RoZXJ3aXNlIHRoZSBpbmRleCBvZiB0aGUgZmlyc3Qgd2hpdGVzcGFjZSBjaGFyYWN0ZXIgd2hpY2gKLSAgICAgKiB3b3VsZCBiZSB0cmFuc2Zvcm1lZC4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgaW50IGlzVW5jaGFuZ2VkQnlOb3JtYWxpemF0aW9uKFhNTFN0cmluZyB2YWx1ZSkgewotICAgICAgICBpbnQgZW5kID0gdmFsdWUub2Zmc2V0ICsgdmFsdWUubGVuZ3RoOwotICAgICAgICBmb3IgKGludCBpID0gdmFsdWUub2Zmc2V0OyBpIDwgZW5kOyArK2kpIHsKLSAgICAgICAgICAgIGludCBjID0gdmFsdWUuY2hbaV07Ci0gICAgICAgICAgICBpZiAoWE1MQ2hhci5pc1NwYWNlKGMpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGkgLSB2YWx1ZS5vZmZzZXQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIC0xOwotICAgIH0KLQotICAgIC8vIHJldHVybnMgdHJ1ZSBpZiB0aGUgZ2l2ZW4gY2hhcmFjdGVyIGlzIG5vdAotICAgIC8vIHZhbGlkIHdpdGggcmVzcGVjdCB0byB0aGUgdmVyc2lvbiBvZgotICAgIC8vIFhNTCB1bmRlcnN0b29kIGJ5IHRoaXMgc2Nhbm5lci4KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBpc0ludmFsaWQoaW50IHZhbHVlKSB7Ci0gICAgICAgIHJldHVybiAoWE1MMTFDaGFyLmlzWE1MMTFJbnZhbGlkKHZhbHVlKSk7Ci0gICAgfSAvLyBpc0ludmFsaWQoaW50KTogIGJvb2xlYW4KLQotICAgIC8vIHJldHVybnMgdHJ1ZSBpZiB0aGUgZ2l2ZW4gY2hhcmFjdGVyIGlzIG5vdAotICAgIC8vIHZhbGlkIG9yIG1heSBub3QgYmUgdXNlZCBvdXRzaWRlIGEgY2hhcmFjdGVyIHJlZmVyZW5jZQotICAgIC8vIHdpdGggcmVzcGVjdCB0byB0aGUgdmVyc2lvbiBvZiBYTUwgdW5kZXJzdG9vZCBieSB0aGlzIHNjYW5uZXIuCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gaXNJbnZhbGlkTGl0ZXJhbChpbnQgdmFsdWUpIHsKLSAgICAgICAgcmV0dXJuICghWE1MMTFDaGFyLmlzWE1MMTFWYWxpZExpdGVyYWwodmFsdWUpKTsKLSAgICB9IC8vIGlzSW52YWxpZExpdGVyYWwoaW50KTogIGJvb2xlYW4KLQotICAgIC8vIHJldHVybnMgdHJ1ZSBpZiB0aGUgZ2l2ZW4gY2hhcmFjdGVyIGlzCi0gICAgLy8gYSB2YWxpZCBuYW1lQ2hhciB3aXRoIHJlc3BlY3QgdG8gdGhlIHZlcnNpb24gb2YKLSAgICAvLyBYTUwgdW5kZXJzdG9vZCBieSB0aGlzIHNjYW5uZXIuCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gaXNWYWxpZE5hbWVDaGFyKGludCB2YWx1ZSkgewotICAgICAgICByZXR1cm4gKFhNTDExQ2hhci5pc1hNTDExTmFtZSh2YWx1ZSkpOwotICAgIH0gLy8gaXNWYWxpZE5hbWVDaGFyKGludCk6ICBib29sZWFuCi0KLSAgICAvLyByZXR1cm5zIHRydWUgaWYgdGhlIGdpdmVuIGNoYXJhY3RlciBpcwotICAgIC8vIGEgdmFsaWQgbmFtZVN0YXJ0Q2hhciB3aXRoIHJlc3BlY3QgdG8gdGhlIHZlcnNpb24gb2YKLSAgICAvLyBYTUwgdW5kZXJzdG9vZCBieSB0aGlzIHNjYW5uZXIuCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gaXNWYWxpZE5hbWVTdGFydENoYXIoaW50IHZhbHVlKSB7Ci0gICAgICAgIHJldHVybiAoWE1MMTFDaGFyLmlzWE1MMTFOYW1lU3RhcnQodmFsdWUpKTsKLSAgICB9IC8vIGlzVmFsaWROYW1lU3RhcnRDaGFyKGludCk6ICBib29sZWFuCi0KLSAgICAvLyByZXR1cm5zIHRydWUgaWYgdGhlIGdpdmVuIGNoYXJhY3RlciBpcwotICAgIC8vIGEgdmFsaWQgTkNOYW1lIGNoYXJhY3RlciB3aXRoIHJlc3BlY3QgdG8gdGhlIHZlcnNpb24gb2YKLSAgICAvLyBYTUwgdW5kZXJzdG9vZCBieSB0aGlzIHNjYW5uZXIuCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gaXNWYWxpZE5DTmFtZShpbnQgdmFsdWUpIHsKLSAgICAgICAgcmV0dXJuIChYTUwxMUNoYXIuaXNYTUwxMU5DTmFtZSh2YWx1ZSkpOwotICAgIH0gLy8gaXNWYWxpZE5DTmFtZShpbnQpOiAgYm9vbGVhbgotCi0gICAgLy8gcmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiBjaGFyYWN0ZXIgaXMKLSAgICAvLyBhIHZhbGlkIGhpZ2ggc3Vycm9nYXRlIGZvciBhIG5hbWVTdGFydENoYXIKLSAgICAvLyB3aXRoIHJlc3BlY3QgdG8gdGhlIHZlcnNpb24gb2YgWE1MIHVuZGVyc3Rvb2QKLSAgICAvLyBieSB0aGlzIHNjYW5uZXIuCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gaXNWYWxpZE5hbWVTdGFydEhpZ2hTdXJyb2dhdGUoaW50IHZhbHVlKSB7Ci0gICAgICAgIHJldHVybiBYTUwxMUNoYXIuaXNYTUwxMU5hbWVIaWdoU3Vycm9nYXRlKHZhbHVlKTsKLSAgICB9IC8vIGlzVmFsaWROYW1lU3RhcnRIaWdoU3Vycm9nYXRlKGludCk6ICBib29sZWFuCi0KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiB2ZXJzaW9uU3VwcG9ydGVkKFN0cmluZyB2ZXJzaW9uKSB7Ci0gICAgICAgIHJldHVybiAodmVyc2lvbi5lcXVhbHMoIjEuMSIpIHx8IHZlcnNpb24uZXF1YWxzKCIxLjAiKSk7Ci0gICAgfSAvLyB2ZXJzaW9uU3VwcG9ydGVkKFN0cmluZyk6ICBib29sZWFuCi0KLSAgICAvLyByZXR1cm5zIHRoZSBlcnJvciBtZXNzYWdlIGtleSBmb3IgdW5zdXBwb3J0ZWQKLSAgICAvLyB2ZXJzaW9ucyBvZiBYTUwgd2l0aCByZXNwZWN0IHRvIHRoZSB2ZXJzaW9uIG9mCi0gICAgLy8gWE1MIHVuZGVyc3Rvb2QgYnkgdGhpcyBzY2FubmVyLgotICAgIHByb3RlY3RlZCBTdHJpbmcgZ2V0VmVyc2lvbk5vdFN1cHBvcnRlZEtleSAoKSB7Ci0gICAgICAgIHJldHVybiAiVmVyc2lvbk5vdFN1cHBvcnRlZDExIjsKLSAgICB9IC8vIGdldFZlcnNpb25Ob3RTdXBwb3J0ZWRLZXk6IFN0cmluZwotCi19IC8vIGNsYXNzIFhNTDExRG9jdW1lbnRTY2FubmVySW1wbApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9YTUwxMUVudGl0eVNjYW5uZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvWE1MMTFFbnRpdHlTY2FubmVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGUyOWQyOTYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9YTUwxMUVudGl0eVNjYW5uZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE0OTkgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAxNSwgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqLwotLyoKLSAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQotICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCi0gKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCi0gKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAotICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKLSAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbDsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5YTUxTY2FubmVyLk5hbWVUeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5tc2cuWE1MTWVzc2FnZUZvcm1hdHRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuWE1MMTFDaGFyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5YTUxDaGFyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5YTUxTdHJpbmdCdWZmZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlscy5YTUxTZWN1cml0eU1hbmFnZXIuTGltaXQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuUU5hbWU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MU3RyaW5nOwotaW1wb3J0IGNvbS5zdW4ueG1sLmludGVybmFsLnN0cmVhbS5FbnRpdHk7Ci1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLQotLyoqCi0gKiBJbXBsZW1lbnRzIHRoZSBlbnRpdHkgc2Nhbm5lciBtZXRob2RzIGluCi0gKiB0aGUgY29udGV4dCBvZiBYTUwgMS4xLgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIE1pY2hhZWwgR2xhdmFzc2V2aWNoLCBJQk0KLSAqIEBhdXRob3IgTmVpbCBHcmFoYW0sIElCTQotICogQHZlcnNpb24gJElkOiBYTUwxMUVudGl0eVNjYW5uZXIuamF2YSx2IDEuNSAyMDEwLTExLTAxIDA0OjM5OjQwIGpvZWh3IEV4cCAkCi0gKi8KLQotcHVibGljIGNsYXNzIFhNTDExRW50aXR5U2Nhbm5lcgotICAgIGV4dGVuZHMgWE1MRW50aXR5U2Nhbm5lciB7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0cnVjdG9ycwotICAgIC8vCi0KLSAgICAvKiogRGVmYXVsdCBjb25zdHJ1Y3Rvci4gKi8KLSAgICBwdWJsaWMgWE1MMTFFbnRpdHlTY2FubmVyKCkgewotICAgICAgICBzdXBlcigpOwotICAgIH0gLy8gPGluaXQ+KCkKLQotICAgIC8vCi0gICAgLy8gWE1MRW50aXR5U2Nhbm5lciBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIG5leHQgY2hhcmFjdGVyIG9uIHRoZSBpbnB1dC4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoZSBjaGFyYWN0ZXIgaXMgPGVtPm5vdDwvZW0+IGNvbnN1bWVkLgotICAgICAqCi0gICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiAgVGhyb3duIGlmIGkvbyBlcnJvciBvY2N1cnMuCi0gICAgICogQHRocm93cyBFT0ZFeGNlcHRpb24gVGhyb3duIG9uIGVuZCBvZiBmaWxlLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgcGVla0NoYXIoKSB0aHJvd3MgSU9FeGNlcHRpb24gewotCi0gICAgICAgIC8vIGxvYWQgbW9yZSBjaGFyYWN0ZXJzLCBpZiBuZWVkZWQKLSAgICAgICAgaWYgKGZDdXJyZW50RW50aXR5LnBvc2l0aW9uID09IGZDdXJyZW50RW50aXR5LmNvdW50KSB7Ci0gICAgICAgICAgICBsb2FkKDAsIHRydWUsIHRydWUpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gcGVlayBhdCBjaGFyYWN0ZXIKLSAgICAgICAgaW50IGMgPSBmQ3VycmVudEVudGl0eS5jaFtmQ3VycmVudEVudGl0eS5wb3NpdGlvbl07Ci0KLSAgICAgICAgLy8gcmV0dXJuIHBlZWtlZCBjaGFyYWN0ZXIKLSAgICAgICAgaWYgKGZDdXJyZW50RW50aXR5LmlzRXh0ZXJuYWwoKSkgewotICAgICAgICAgICAgcmV0dXJuIChjICE9ICdccicgJiYgYyAhPSAweDg1ICYmIGMgIT0gMHgyMDI4KSA/IGMgOiAnXG4nOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIGM7Ci0gICAgICAgIH0KLQotICAgIH0gLy8gcGVla0NoYXIoKTppbnQKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIG5leHQgY2hhcmFjdGVyIG9uIHRoZSBpbnB1dC4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoZSBjaGFyYWN0ZXIgaXMgY29uc3VtZWQuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uICBUaHJvd24gaWYgaS9vIGVycm9yIG9jY3Vycy4KLSAgICAgKiBAdGhyb3dzIEVPRkV4Y2VwdGlvbiBUaHJvd24gb24gZW5kIG9mIGZpbGUuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGludCBzY2FuQ2hhcihOYW1lVHlwZSBudCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLQotICAgICAgICAvLyBsb2FkIG1vcmUgY2hhcmFjdGVycywgaWYgbmVlZGVkCi0gICAgICAgIGlmIChmQ3VycmVudEVudGl0eS5wb3NpdGlvbiA9PSBmQ3VycmVudEVudGl0eS5jb3VudCkgewotICAgICAgICAgICAgbG9hZCgwLCB0cnVlLCB0cnVlKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIHNjYW4gY2hhcmFjdGVyCi0gICAgICAgIGludCBvZmZzZXQgPSBmQ3VycmVudEVudGl0eS5wb3NpdGlvbjsKLSAgICAgICAgaW50IGMgPSBmQ3VycmVudEVudGl0eS5jaFtmQ3VycmVudEVudGl0eS5wb3NpdGlvbisrXTsKLSAgICAgICAgYm9vbGVhbiBleHRlcm5hbCA9IGZhbHNlOwotICAgICAgICBpZiAoYyA9PSAnXG4nIHx8Ci0gICAgICAgICAgICAoKGMgPT0gJ1xyJyB8fCBjID09IDB4ODUgfHwgYyA9PSAweDIwMjgpICYmIChleHRlcm5hbCA9IGZDdXJyZW50RW50aXR5LmlzRXh0ZXJuYWwoKSkpKSB7Ci0gICAgICAgICAgICBmQ3VycmVudEVudGl0eS5saW5lTnVtYmVyKys7Ci0gICAgICAgICAgICBmQ3VycmVudEVudGl0eS5jb2x1bW5OdW1iZXIgPSAxOwotICAgICAgICAgICAgaWYgKGZDdXJyZW50RW50aXR5LnBvc2l0aW9uID09IGZDdXJyZW50RW50aXR5LmNvdW50KSB7Ci0gICAgICAgICAgICAgICAgaW52b2tlTGlzdGVuZXJzKDEpOwotICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LmNoWzBdID0gKGNoYXIpYzsKLSAgICAgICAgICAgICAgICBsb2FkKDEsIGZhbHNlLCBmYWxzZSk7Ci0gICAgICAgICAgICAgICAgb2Zmc2V0ID0gMDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChjID09ICdccicgJiYgZXh0ZXJuYWwpIHsKLSAgICAgICAgICAgICAgICBpbnQgY2MgPSBmQ3VycmVudEVudGl0eS5jaFtmQ3VycmVudEVudGl0eS5wb3NpdGlvbisrXTsKLSAgICAgICAgICAgICAgICBpZiAoY2MgIT0gJ1xuJyAmJiBjYyAhPSAweDg1KSB7Ci0gICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LnBvc2l0aW9uLS07Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgYyA9ICdcbic7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyByZXR1cm4gY2hhcmFjdGVyIHRoYXQgd2FzIHNjYW5uZWQKLSAgICAgICAgZkN1cnJlbnRFbnRpdHkuY29sdW1uTnVtYmVyKys7Ci0gICAgICAgIGlmICghZGV0ZWN0aW5nVmVyc2lvbikgewotICAgICAgICAgICAgY2hlY2tFbnRpdHlMaW1pdChudCwgZkN1cnJlbnRFbnRpdHksIG9mZnNldCwgZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gLSBvZmZzZXQpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBjOwotCi0gICAgfSAvLyBzY2FuQ2hhcigpOmludAotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhIHN0cmluZyBtYXRjaGluZyB0aGUgTk1UT0tFTiBwcm9kdWN0aW9uIGFwcGVhcmluZyBpbW1lZGlhdGVseQotICAgICAqIG9uIHRoZSBpbnB1dCBhcyBhIHN5bWJvbCwgb3IgbnVsbCBpZiBOTVRPS0VOIE5hbWUgc3RyaW5nIGlzIHByZXNlbnQuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGUgTk1UT0tFTiBjaGFyYWN0ZXJzIGFyZSBjb25zdW1lZC4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoZSBzdHJpbmcgcmV0dXJuZWQgbXVzdCBiZSBhIHN5bWJvbC4gVGhlCi0gICAgICogU3ltYm9sVGFibGUgY2FuIGJlIHVzZWQgZm9yIHRoaXMgcHVycG9zZS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gIFRocm93biBpZiBpL28gZXJyb3Igb2NjdXJzLgotICAgICAqIEB0aHJvd3MgRU9GRXhjZXB0aW9uIFRocm93biBvbiBlbmQgb2YgZmlsZS4KLSAgICAgKgotICAgICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlN5bWJvbFRhYmxlCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuWE1MMTFDaGFyI2lzWE1MMTFOYW1lCi0gICAgICovCi0gICAgcHJvdGVjdGVkIFN0cmluZyBzY2FuTm10b2tlbigpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgIC8vIGxvYWQgbW9yZSBjaGFyYWN0ZXJzLCBpZiBuZWVkZWQKLSAgICAgICAgaWYgKGZDdXJyZW50RW50aXR5LnBvc2l0aW9uID09IGZDdXJyZW50RW50aXR5LmNvdW50KSB7Ci0gICAgICAgICAgICBsb2FkKDAsIHRydWUsIHRydWUpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gc2NhbiBubXRva2VuCi0gICAgICAgIGludCBvZmZzZXQgPSBmQ3VycmVudEVudGl0eS5wb3NpdGlvbjsKLQotICAgICAgICBkbyB7Ci0gICAgICAgICAgICBjaGFyIGNoID0gZkN1cnJlbnRFbnRpdHkuY2hbZkN1cnJlbnRFbnRpdHkucG9zaXRpb25dOwotICAgICAgICAgICAgaWYgKFhNTDExQ2hhci5pc1hNTDExTmFtZShjaCkpIHsKLSAgICAgICAgICAgICAgICBpZiAoKytmQ3VycmVudEVudGl0eS5wb3NpdGlvbiA9PSBmQ3VycmVudEVudGl0eS5jb3VudCkgewotICAgICAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gLSBvZmZzZXQ7Ci0gICAgICAgICAgICAgICAgICAgIGludm9rZUxpc3RlbmVycyhsZW5ndGgpOwotICAgICAgICAgICAgICAgICAgICBpZiAobGVuZ3RoID09IGZDdXJyZW50RW50aXR5LmNoLmxlbmd0aCkgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gYmFkIGx1Y2sgd2UgaGF2ZSB0byByZXNpemUgb3VyIGJ1ZmZlcgotICAgICAgICAgICAgICAgICAgICAgICAgY2hhcltdIHRtcCA9IG5ldyBjaGFyW2ZDdXJyZW50RW50aXR5LmNoLmxlbmd0aCA8PCAxXTsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZkN1cnJlbnRFbnRpdHkuY2gsIG9mZnNldCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG1wLCAwLCBsZW5ndGgpOwotICAgICAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkuY2ggPSB0bXA7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGZDdXJyZW50RW50aXR5LmNoLCBvZmZzZXQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LmNoLCAwLCBsZW5ndGgpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIG9mZnNldCA9IDA7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChsb2FkKGxlbmd0aCwgZmFsc2UsIGZhbHNlKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChYTUwxMUNoYXIuaXNYTUwxMU5hbWVIaWdoU3Vycm9nYXRlKGNoKSkgewotICAgICAgICAgICAgICAgIGlmICgrK2ZDdXJyZW50RW50aXR5LnBvc2l0aW9uID09IGZDdXJyZW50RW50aXR5LmNvdW50KSB7Ci0gICAgICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBmQ3VycmVudEVudGl0eS5wb3NpdGlvbiAtIG9mZnNldDsKLSAgICAgICAgICAgICAgICAgICAgaW52b2tlTGlzdGVuZXJzKGxlbmd0aCk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChsZW5ndGggPT0gZkN1cnJlbnRFbnRpdHkuY2gubGVuZ3RoKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBiYWQgbHVjayB3ZSBoYXZlIHRvIHJlc2l6ZSBvdXIgYnVmZmVyCi0gICAgICAgICAgICAgICAgICAgICAgICBjaGFyW10gdG1wID0gbmV3IGNoYXJbZkN1cnJlbnRFbnRpdHkuY2gubGVuZ3RoIDw8IDFdOwotICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShmQ3VycmVudEVudGl0eS5jaCwgb2Zmc2V0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0bXAsIDAsIGxlbmd0aCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5jaCA9IHRtcDsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZkN1cnJlbnRFbnRpdHkuY2gsIG9mZnNldCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkuY2gsIDAsIGxlbmd0aCk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgb2Zmc2V0ID0gMDsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGxvYWQobGVuZ3RoLCBmYWxzZSwgZmFsc2UpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAtLWZDdXJyZW50RW50aXR5LnN0YXJ0UG9zaXRpb247Ci0gICAgICAgICAgICAgICAgICAgICAgICAtLWZDdXJyZW50RW50aXR5LnBvc2l0aW9uOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgY2hhciBjaDIgPSBmQ3VycmVudEVudGl0eS5jaFtmQ3VycmVudEVudGl0eS5wb3NpdGlvbl07Ci0gICAgICAgICAgICAgICAgaWYgKCAhWE1MQ2hhci5pc0xvd1N1cnJvZ2F0ZShjaDIpIHx8Ci0gICAgICAgICAgICAgICAgICAgICAhWE1MMTFDaGFyLmlzWE1MMTFOYW1lKFhNTENoYXIuc3VwcGxlbWVudGFsKGNoLCBjaDIpKSApIHsKLSAgICAgICAgICAgICAgICAgICAgLS1mQ3VycmVudEVudGl0eS5wb3NpdGlvbjsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGlmICgrK2ZDdXJyZW50RW50aXR5LnBvc2l0aW9uID09IGZDdXJyZW50RW50aXR5LmNvdW50KSB7Ci0gICAgICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBmQ3VycmVudEVudGl0eS5wb3NpdGlvbiAtIG9mZnNldDsKLSAgICAgICAgICAgICAgICAgICAgaW52b2tlTGlzdGVuZXJzKGxlbmd0aCk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChsZW5ndGggPT0gZkN1cnJlbnRFbnRpdHkuY2gubGVuZ3RoKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBiYWQgbHVjayB3ZSBoYXZlIHRvIHJlc2l6ZSBvdXIgYnVmZmVyCi0gICAgICAgICAgICAgICAgICAgICAgICBjaGFyW10gdG1wID0gbmV3IGNoYXJbZkN1cnJlbnRFbnRpdHkuY2gubGVuZ3RoIDw8IDFdOwotICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShmQ3VycmVudEVudGl0eS5jaCwgb2Zmc2V0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0bXAsIDAsIGxlbmd0aCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5jaCA9IHRtcDsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZkN1cnJlbnRFbnRpdHkuY2gsIG9mZnNldCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkuY2gsIDAsIGxlbmd0aCk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgb2Zmc2V0ID0gMDsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGxvYWQobGVuZ3RoLCBmYWxzZSwgZmFsc2UpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHdoaWxlICh0cnVlKTsKLQotICAgICAgICBpbnQgbGVuZ3RoID0gZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gLSBvZmZzZXQ7Ci0gICAgICAgIGZDdXJyZW50RW50aXR5LmNvbHVtbk51bWJlciArPSBsZW5ndGg7Ci0KLSAgICAgICAgLy8gcmV0dXJuIG5tdG9rZW4KLSAgICAgICAgU3RyaW5nIHN5bWJvbCA9IG51bGw7Ci0gICAgICAgIGlmIChsZW5ndGggPiAwKSB7Ci0gICAgICAgICAgICBzeW1ib2wgPSBmU3ltYm9sVGFibGUuYWRkU3ltYm9sKGZDdXJyZW50RW50aXR5LmNoLCBvZmZzZXQsIGxlbmd0aCk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHN5bWJvbDsKLQotICAgIH0gLy8gc2Nhbk5tdG9rZW4oKTpTdHJpbmcKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYSBzdHJpbmcgbWF0Y2hpbmcgdGhlIE5hbWUgcHJvZHVjdGlvbiBhcHBlYXJpbmcgaW1tZWRpYXRlbHkKLSAgICAgKiBvbiB0aGUgaW5wdXQgYXMgYSBzeW1ib2wsIG9yIG51bGwgaWYgbm8gTmFtZSBzdHJpbmcgaXMgcHJlc2VudC4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoZSBOYW1lIGNoYXJhY3RlcnMgYXJlIGNvbnN1bWVkLgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gVGhlIHN0cmluZyByZXR1cm5lZCBtdXN0IGJlIGEgc3ltYm9sLiBUaGUKLSAgICAgKiBTeW1ib2xUYWJsZSBjYW4gYmUgdXNlZCBmb3IgdGhpcyBwdXJwb3NlLgotICAgICAqCi0gICAgICogQHBhcmFtIG50IFRoZSB0eXBlIG9mIHRoZSBuYW1lIChlbGVtZW50IG9yIGF0dHJpYnV0ZSkKLSAgICAgKgotICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gIFRocm93biBpZiBpL28gZXJyb3Igb2NjdXJzLgotICAgICAqIEB0aHJvd3MgRU9GRXhjZXB0aW9uIFRocm93biBvbiBlbmQgb2YgZmlsZS4KLSAgICAgKgotICAgICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlN5bWJvbFRhYmxlCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuWE1MMTFDaGFyI2lzWE1MMTFOYW1lCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuWE1MMTFDaGFyI2lzWE1MMTFOYW1lU3RhcnQKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgU3RyaW5nIHNjYW5OYW1lKE5hbWVUeXBlIG50KSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgICAgICAvLyBsb2FkIG1vcmUgY2hhcmFjdGVycywgaWYgbmVlZGVkCi0gICAgICAgIGlmIChmQ3VycmVudEVudGl0eS5wb3NpdGlvbiA9PSBmQ3VycmVudEVudGl0eS5jb3VudCkgewotICAgICAgICAgICAgbG9hZCgwLCB0cnVlLCB0cnVlKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIHNjYW4gbmFtZQotICAgICAgICBpbnQgb2Zmc2V0ID0gZkN1cnJlbnRFbnRpdHkucG9zaXRpb247Ci0gICAgICAgIGNoYXIgY2ggPSBmQ3VycmVudEVudGl0eS5jaFtvZmZzZXRdOwotCi0gICAgICAgIGlmIChYTUwxMUNoYXIuaXNYTUwxMU5hbWVTdGFydChjaCkpIHsKLSAgICAgICAgICAgIGlmICgrK2ZDdXJyZW50RW50aXR5LnBvc2l0aW9uID09IGZDdXJyZW50RW50aXR5LmNvdW50KSB7Ci0gICAgICAgICAgICAgICAgaW52b2tlTGlzdGVuZXJzKDEpOwotICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LmNoWzBdID0gY2g7Ci0gICAgICAgICAgICAgICAgb2Zmc2V0ID0gMDsKLSAgICAgICAgICAgICAgICBpZiAobG9hZCgxLCBmYWxzZSwgZmFsc2UpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LmNvbHVtbk51bWJlcisrOwotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgc3ltYm9sID0gZlN5bWJvbFRhYmxlLmFkZFN5bWJvbChmQ3VycmVudEVudGl0eS5jaCwgMCwgMSk7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBzeW1ib2w7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKFhNTDExQ2hhci5pc1hNTDExTmFtZUhpZ2hTdXJyb2dhdGUoY2gpKSB7Ci0gICAgICAgICAgICBpZiAoKytmQ3VycmVudEVudGl0eS5wb3NpdGlvbiA9PSBmQ3VycmVudEVudGl0eS5jb3VudCkgewotICAgICAgICAgICAgICAgIGludm9rZUxpc3RlbmVycygxKTsKLSAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5jaFswXSA9IGNoOwotICAgICAgICAgICAgICAgIG9mZnNldCA9IDA7Ci0gICAgICAgICAgICAgICAgaWYgKGxvYWQoMSwgZmFsc2UsIGZhbHNlKSkgewotICAgICAgICAgICAgICAgICAgICAtLWZDdXJyZW50RW50aXR5LnBvc2l0aW9uOwotICAgICAgICAgICAgICAgICAgICAtLWZDdXJyZW50RW50aXR5LnN0YXJ0UG9zaXRpb247Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNoYXIgY2gyID0gZkN1cnJlbnRFbnRpdHkuY2hbZkN1cnJlbnRFbnRpdHkucG9zaXRpb25dOwotICAgICAgICAgICAgaWYgKCAhWE1MQ2hhci5pc0xvd1N1cnJvZ2F0ZShjaDIpIHx8Ci0gICAgICAgICAgICAgICAgICFYTUwxMUNoYXIuaXNYTUwxMU5hbWVTdGFydChYTUxDaGFyLnN1cHBsZW1lbnRhbChjaCwgY2gyKSkgKSB7Ci0gICAgICAgICAgICAgICAgLS1mQ3VycmVudEVudGl0eS5wb3NpdGlvbjsKLSAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmICgrK2ZDdXJyZW50RW50aXR5LnBvc2l0aW9uID09IGZDdXJyZW50RW50aXR5LmNvdW50KSB7Ci0gICAgICAgICAgICAgICAgaW52b2tlTGlzdGVuZXJzKDIpOwotICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LmNoWzBdID0gY2g7Ci0gICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkuY2hbMV0gPSBjaDI7Ci0gICAgICAgICAgICAgICAgb2Zmc2V0ID0gMDsKLSAgICAgICAgICAgICAgICBpZiAobG9hZCgyLCBmYWxzZSwgZmFsc2UpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LmNvbHVtbk51bWJlciArPSAyOwotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgc3ltYm9sID0gZlN5bWJvbFRhYmxlLmFkZFN5bWJvbChmQ3VycmVudEVudGl0eS5jaCwgMCwgMik7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBzeW1ib2w7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLQotICAgICAgICBpbnQgbGVuZ3RoID0gMDsKLSAgICAgICAgZG8gewotICAgICAgICAgICAgY2ggPSBmQ3VycmVudEVudGl0eS5jaFtmQ3VycmVudEVudGl0eS5wb3NpdGlvbl07Ci0gICAgICAgICAgICBpZiAoWE1MMTFDaGFyLmlzWE1MMTFOYW1lKGNoKSkgewotICAgICAgICAgICAgICAgIGlmICgobGVuZ3RoID0gY2hlY2tCZWZvcmVMb2FkKGZDdXJyZW50RW50aXR5LCBvZmZzZXQsIG9mZnNldCkpID4gMCkgewotICAgICAgICAgICAgICAgICAgICBvZmZzZXQgPSAwOwotICAgICAgICAgICAgICAgICAgICBpZiAobG9hZChsZW5ndGgsIGZhbHNlLCBmYWxzZSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoWE1MMTFDaGFyLmlzWE1MMTFOYW1lSGlnaFN1cnJvZ2F0ZShjaCkpIHsKLSAgICAgICAgICAgICAgICBpZiAoKGxlbmd0aCA9IGNoZWNrQmVmb3JlTG9hZChmQ3VycmVudEVudGl0eSwgb2Zmc2V0LCBvZmZzZXQpKSA+IDApIHsKLSAgICAgICAgICAgICAgICAgICAgb2Zmc2V0ID0gMDsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGxvYWQobGVuZ3RoLCBmYWxzZSwgZmFsc2UpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAtLWZDdXJyZW50RW50aXR5LnBvc2l0aW9uOwotICAgICAgICAgICAgICAgICAgICAgICAgLS1mQ3VycmVudEVudGl0eS5zdGFydFBvc2l0aW9uOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgY2hhciBjaDIgPSBmQ3VycmVudEVudGl0eS5jaFtmQ3VycmVudEVudGl0eS5wb3NpdGlvbl07Ci0gICAgICAgICAgICAgICAgaWYgKCAhWE1MQ2hhci5pc0xvd1N1cnJvZ2F0ZShjaDIpIHx8Ci0gICAgICAgICAgICAgICAgICAgICAhWE1MMTFDaGFyLmlzWE1MMTFOYW1lKFhNTENoYXIuc3VwcGxlbWVudGFsKGNoLCBjaDIpKSApIHsKLSAgICAgICAgICAgICAgICAgICAgLS1mQ3VycmVudEVudGl0eS5wb3NpdGlvbjsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGlmICgobGVuZ3RoID0gY2hlY2tCZWZvcmVMb2FkKGZDdXJyZW50RW50aXR5LCBvZmZzZXQsIG9mZnNldCkpID4gMCkgewotICAgICAgICAgICAgICAgICAgICBvZmZzZXQgPSAwOwotICAgICAgICAgICAgICAgICAgICBpZiAobG9hZChsZW5ndGgsIGZhbHNlLCBmYWxzZSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgd2hpbGUgKHRydWUpOwotCi0gICAgICAgIGxlbmd0aCA9IGZDdXJyZW50RW50aXR5LnBvc2l0aW9uIC0gb2Zmc2V0OwotICAgICAgICBmQ3VycmVudEVudGl0eS5jb2x1bW5OdW1iZXIgKz0gbGVuZ3RoOwotCi0gICAgICAgIC8vIHJldHVybiBuYW1lCi0gICAgICAgIFN0cmluZyBzeW1ib2wgPSBudWxsOwotICAgICAgICBpZiAobGVuZ3RoID4gMCkgewotICAgICAgICAgICAgY2hlY2tMaW1pdChMaW1pdC5NQVhfTkFNRV9MSU1JVCwgZkN1cnJlbnRFbnRpdHksIG9mZnNldCwgbGVuZ3RoKTsKLSAgICAgICAgICAgIGNoZWNrRW50aXR5TGltaXQobnQsIGZDdXJyZW50RW50aXR5LCBvZmZzZXQsIGxlbmd0aCk7Ci0gICAgICAgICAgICBzeW1ib2wgPSBmU3ltYm9sVGFibGUuYWRkU3ltYm9sKGZDdXJyZW50RW50aXR5LmNoLCBvZmZzZXQsIGxlbmd0aCk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHN5bWJvbDsKLQotICAgIH0gLy8gc2Nhbk5hbWUoKTpTdHJpbmcKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYSBzdHJpbmcgbWF0Y2hpbmcgdGhlIE5DTmFtZSBwcm9kdWN0aW9uIGFwcGVhcmluZyBpbW1lZGlhdGVseQotICAgICAqIG9uIHRoZSBpbnB1dCBhcyBhIHN5bWJvbCwgb3IgbnVsbCBpZiBubyBOQ05hbWUgc3RyaW5nIGlzIHByZXNlbnQuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGUgTkNOYW1lIGNoYXJhY3RlcnMgYXJlIGNvbnN1bWVkLgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gVGhlIHN0cmluZyByZXR1cm5lZCBtdXN0IGJlIGEgc3ltYm9sLiBUaGUKLSAgICAgKiBTeW1ib2xUYWJsZSBjYW4gYmUgdXNlZCBmb3IgdGhpcyBwdXJwb3NlLgotICAgICAqCi0gICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiAgVGhyb3duIGlmIGkvbyBlcnJvciBvY2N1cnMuCi0gICAgICogQHRocm93cyBFT0ZFeGNlcHRpb24gVGhyb3duIG9uIGVuZCBvZiBmaWxlLgotICAgICAqCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuU3ltYm9sVGFibGUKLSAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5YTUwxMUNoYXIjaXNYTUwxMU5DTmFtZQotICAgICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlhNTDExQ2hhciNpc1hNTDExTkNOYW1lU3RhcnQKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgU3RyaW5nIHNjYW5OQ05hbWUoKSB0aHJvd3MgSU9FeGNlcHRpb24gewotCi0gICAgICAgIC8vIGxvYWQgbW9yZSBjaGFyYWN0ZXJzLCBpZiBuZWVkZWQKLSAgICAgICAgaWYgKGZDdXJyZW50RW50aXR5LnBvc2l0aW9uID09IGZDdXJyZW50RW50aXR5LmNvdW50KSB7Ci0gICAgICAgICAgICBsb2FkKDAsIHRydWUsIHRydWUpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gc2NhbiBuYW1lCi0gICAgICAgIGludCBvZmZzZXQgPSBmQ3VycmVudEVudGl0eS5wb3NpdGlvbjsKLSAgICAgICAgY2hhciBjaCA9IGZDdXJyZW50RW50aXR5LmNoW29mZnNldF07Ci0KLSAgICAgICAgaWYgKFhNTDExQ2hhci5pc1hNTDExTkNOYW1lU3RhcnQoY2gpKSB7Ci0gICAgICAgICAgICBpZiAoKytmQ3VycmVudEVudGl0eS5wb3NpdGlvbiA9PSBmQ3VycmVudEVudGl0eS5jb3VudCkgewotICAgICAgICAgICAgICAgIGludm9rZUxpc3RlbmVycygxKTsKLSAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5jaFswXSA9IGNoOwotICAgICAgICAgICAgICAgIG9mZnNldCA9IDA7Ci0gICAgICAgICAgICAgICAgaWYgKGxvYWQoMSwgZmFsc2UsIGZhbHNlKSkgewotICAgICAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5jb2x1bW5OdW1iZXIrKzsKLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHN5bWJvbCA9IGZTeW1ib2xUYWJsZS5hZGRTeW1ib2woZkN1cnJlbnRFbnRpdHkuY2gsIDAsIDEpOwotICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3ltYm9sOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChYTUwxMUNoYXIuaXNYTUwxMU5hbWVIaWdoU3Vycm9nYXRlKGNoKSkgewotICAgICAgICAgICAgaWYgKCsrZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gPT0gZkN1cnJlbnRFbnRpdHkuY291bnQpIHsKLSAgICAgICAgICAgICAgICBpbnZva2VMaXN0ZW5lcnMoMSk7Ci0gICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkuY2hbMF0gPSBjaDsKLSAgICAgICAgICAgICAgICBvZmZzZXQgPSAwOwotICAgICAgICAgICAgICAgIGlmIChsb2FkKDEsIGZhbHNlLCBmYWxzZSkpIHsKLSAgICAgICAgICAgICAgICAgICAgLS1mQ3VycmVudEVudGl0eS5wb3NpdGlvbjsKLSAgICAgICAgICAgICAgICAgICAgLS1mQ3VycmVudEVudGl0eS5zdGFydFBvc2l0aW9uOwotICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjaGFyIGNoMiA9IGZDdXJyZW50RW50aXR5LmNoW2ZDdXJyZW50RW50aXR5LnBvc2l0aW9uXTsKLSAgICAgICAgICAgIGlmICggIVhNTENoYXIuaXNMb3dTdXJyb2dhdGUoY2gyKSB8fAotICAgICAgICAgICAgICAgICAhWE1MMTFDaGFyLmlzWE1MMTFOQ05hbWVTdGFydChYTUxDaGFyLnN1cHBsZW1lbnRhbChjaCwgY2gyKSkgKSB7Ci0gICAgICAgICAgICAgICAgLS1mQ3VycmVudEVudGl0eS5wb3NpdGlvbjsKLSAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmICgrK2ZDdXJyZW50RW50aXR5LnBvc2l0aW9uID09IGZDdXJyZW50RW50aXR5LmNvdW50KSB7Ci0gICAgICAgICAgICAgICAgaW52b2tlTGlzdGVuZXJzKDIpOwotICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LmNoWzBdID0gY2g7Ci0gICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkuY2hbMV0gPSBjaDI7Ci0gICAgICAgICAgICAgICAgb2Zmc2V0ID0gMDsKLSAgICAgICAgICAgICAgICBpZiAobG9hZCgyLCBmYWxzZSwgZmFsc2UpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LmNvbHVtbk51bWJlciArPSAyOwotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgc3ltYm9sID0gZlN5bWJvbFRhYmxlLmFkZFN5bWJvbChmQ3VycmVudEVudGl0eS5jaCwgMCwgMik7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBzeW1ib2w7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLQotICAgICAgICBkbyB7Ci0gICAgICAgICAgICBjaCA9IGZDdXJyZW50RW50aXR5LmNoW2ZDdXJyZW50RW50aXR5LnBvc2l0aW9uXTsKLSAgICAgICAgICAgIGlmIChYTUwxMUNoYXIuaXNYTUwxMU5DTmFtZShjaCkpIHsKLSAgICAgICAgICAgICAgICBpZiAoKytmQ3VycmVudEVudGl0eS5wb3NpdGlvbiA9PSBmQ3VycmVudEVudGl0eS5jb3VudCkgewotICAgICAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gLSBvZmZzZXQ7Ci0gICAgICAgICAgICAgICAgICAgIGludm9rZUxpc3RlbmVycyhsZW5ndGgpOwotICAgICAgICAgICAgICAgICAgICBpZiAobGVuZ3RoID09IGZDdXJyZW50RW50aXR5LmNoLmxlbmd0aCkgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gYmFkIGx1Y2sgd2UgaGF2ZSB0byByZXNpemUgb3VyIGJ1ZmZlcgotICAgICAgICAgICAgICAgICAgICAgICAgY2hhcltdIHRtcCA9IG5ldyBjaGFyW2ZDdXJyZW50RW50aXR5LmNoLmxlbmd0aCA8PCAxXTsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZkN1cnJlbnRFbnRpdHkuY2gsIG9mZnNldCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG1wLCAwLCBsZW5ndGgpOwotICAgICAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkuY2ggPSB0bXA7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGZDdXJyZW50RW50aXR5LmNoLCBvZmZzZXQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LmNoLCAwLCBsZW5ndGgpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIG9mZnNldCA9IDA7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChsb2FkKGxlbmd0aCwgZmFsc2UsIGZhbHNlKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChYTUwxMUNoYXIuaXNYTUwxMU5hbWVIaWdoU3Vycm9nYXRlKGNoKSkgewotICAgICAgICAgICAgICAgIGlmICgrK2ZDdXJyZW50RW50aXR5LnBvc2l0aW9uID09IGZDdXJyZW50RW50aXR5LmNvdW50KSB7Ci0gICAgICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBmQ3VycmVudEVudGl0eS5wb3NpdGlvbiAtIG9mZnNldDsKLSAgICAgICAgICAgICAgICAgICAgaW52b2tlTGlzdGVuZXJzKGxlbmd0aCk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChsZW5ndGggPT0gZkN1cnJlbnRFbnRpdHkuY2gubGVuZ3RoKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBiYWQgbHVjayB3ZSBoYXZlIHRvIHJlc2l6ZSBvdXIgYnVmZmVyCi0gICAgICAgICAgICAgICAgICAgICAgICBjaGFyW10gdG1wID0gbmV3IGNoYXJbZkN1cnJlbnRFbnRpdHkuY2gubGVuZ3RoIDw8IDFdOwotICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShmQ3VycmVudEVudGl0eS5jaCwgb2Zmc2V0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0bXAsIDAsIGxlbmd0aCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5jaCA9IHRtcDsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZkN1cnJlbnRFbnRpdHkuY2gsIG9mZnNldCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkuY2gsIDAsIGxlbmd0aCk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgb2Zmc2V0ID0gMDsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGxvYWQobGVuZ3RoLCBmYWxzZSwgZmFsc2UpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAtLWZDdXJyZW50RW50aXR5LnN0YXJ0UG9zaXRpb247Ci0gICAgICAgICAgICAgICAgICAgICAgICAtLWZDdXJyZW50RW50aXR5LnBvc2l0aW9uOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgY2hhciBjaDIgPSBmQ3VycmVudEVudGl0eS5jaFtmQ3VycmVudEVudGl0eS5wb3NpdGlvbl07Ci0gICAgICAgICAgICAgICAgaWYgKCAhWE1MQ2hhci5pc0xvd1N1cnJvZ2F0ZShjaDIpIHx8Ci0gICAgICAgICAgICAgICAgICAgICAhWE1MMTFDaGFyLmlzWE1MMTFOQ05hbWUoWE1MQ2hhci5zdXBwbGVtZW50YWwoY2gsIGNoMikpICkgewotICAgICAgICAgICAgICAgICAgICAtLWZDdXJyZW50RW50aXR5LnBvc2l0aW9uOwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaWYgKCsrZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gPT0gZkN1cnJlbnRFbnRpdHkuY291bnQpIHsKLSAgICAgICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGZDdXJyZW50RW50aXR5LnBvc2l0aW9uIC0gb2Zmc2V0OwotICAgICAgICAgICAgICAgICAgICBpbnZva2VMaXN0ZW5lcnMobGVuZ3RoKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGxlbmd0aCA9PSBmQ3VycmVudEVudGl0eS5jaC5sZW5ndGgpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGJhZCBsdWNrIHdlIGhhdmUgdG8gcmVzaXplIG91ciBidWZmZXIKLSAgICAgICAgICAgICAgICAgICAgICAgIGNoYXJbXSB0bXAgPSBuZXcgY2hhcltmQ3VycmVudEVudGl0eS5jaC5sZW5ndGggPDwgMV07Ci0gICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGZDdXJyZW50RW50aXR5LmNoLCBvZmZzZXQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRtcCwgMCwgbGVuZ3RoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LmNoID0gdG1wOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShmQ3VycmVudEVudGl0eS5jaCwgb2Zmc2V0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5jaCwgMCwgbGVuZ3RoKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBvZmZzZXQgPSAwOwotICAgICAgICAgICAgICAgICAgICBpZiAobG9hZChsZW5ndGgsIGZhbHNlLCBmYWxzZSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgd2hpbGUgKHRydWUpOwotCi0gICAgICAgIGludCBsZW5ndGggPSBmQ3VycmVudEVudGl0eS5wb3NpdGlvbiAtIG9mZnNldDsKLSAgICAgICAgZkN1cnJlbnRFbnRpdHkuY29sdW1uTnVtYmVyICs9IGxlbmd0aDsKLQotICAgICAgICAvLyByZXR1cm4gbmFtZQotICAgICAgICBTdHJpbmcgc3ltYm9sID0gbnVsbDsKLSAgICAgICAgaWYgKGxlbmd0aCA+IDApIHsKLSAgICAgICAgICAgIHN5bWJvbCA9IGZTeW1ib2xUYWJsZS5hZGRTeW1ib2woZkN1cnJlbnRFbnRpdHkuY2gsIG9mZnNldCwgbGVuZ3RoKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gc3ltYm9sOwotCi0gICAgfSAvLyBzY2FuTkNOYW1lKCk6U3RyaW5nCi0KLSAgICAvKioKLSAgICAgKiBTY2FucyBhIHF1YWxpZmllZCBuYW1lIGZyb20gdGhlIGlucHV0LCBzZXR0aW5nIHRoZSBmaWVsZHMgb2YgdGhlCi0gICAgICogUU5hbWUgc3RydWN0dXJlIGFwcHJvcHJpYXRlbHkuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGUgcXVhbGlmaWVkIG5hbWUgY2hhcmFjdGVycyBhcmUgY29uc3VtZWQuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGUgc3RyaW5ncyB1c2VkIHRvIHNldCB0aGUgdmFsdWVzIG9mIHRoZQotICAgICAqIFFOYW1lIHN0cnVjdHVyZSBtdXN0IGJlIHN5bWJvbHMuIFRoZSBTeW1ib2xUYWJsZSBjYW4gYmUgdXNlZCBmb3IKLSAgICAgKiB0aGlzIHB1cnBvc2UuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcW5hbWUgVGhlIHF1YWxpZmllZCBuYW1lIHN0cnVjdHVyZSB0byBmaWxsLgotICAgICAqIEBwYXJhbSBudCBUaGUgdHlwZSBvZiB0aGUgbmFtZSAoZWxlbWVudCBvciBhdHRyaWJ1dGUpCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFJldHVybnMgdHJ1ZSBpZiBhIHF1YWxpZmllZCBuYW1lIGFwcGVhcmVkIGltbWVkaWF0ZWx5IG9uCi0gICAgICogICAgICAgICB0aGUgaW5wdXQgYW5kIHdhcyBzY2FubmVkLCBmYWxzZSBvdGhlcndpc2UuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uICBUaHJvd24gaWYgaS9vIGVycm9yIG9jY3Vycy4KLSAgICAgKiBAdGhyb3dzIEVPRkV4Y2VwdGlvbiBUaHJvd24gb24gZW5kIG9mIGZpbGUuCi0gICAgICoKLSAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5TeW1ib2xUYWJsZQotICAgICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlhNTDExQ2hhciNpc1hNTDExTmFtZQotICAgICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlhNTDExQ2hhciNpc1hNTDExTmFtZVN0YXJ0Ci0gICAgICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gc2NhblFOYW1lKFFOYW1lIHFuYW1lLCBYTUxTY2FubmVyLk5hbWVUeXBlIG50KSB0aHJvd3MgSU9FeGNlcHRpb24gewotCi0gICAgICAgIC8vIGxvYWQgbW9yZSBjaGFyYWN0ZXJzLCBpZiBuZWVkZWQKLSAgICAgICAgaWYgKGZDdXJyZW50RW50aXR5LnBvc2l0aW9uID09IGZDdXJyZW50RW50aXR5LmNvdW50KSB7Ci0gICAgICAgICAgICBsb2FkKDAsIHRydWUsIHRydWUpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gc2NhbiBxdWFsaWZpZWQgbmFtZQotICAgICAgICBpbnQgb2Zmc2V0ID0gZkN1cnJlbnRFbnRpdHkucG9zaXRpb247Ci0gICAgICAgIGNoYXIgY2ggPSBmQ3VycmVudEVudGl0eS5jaFtvZmZzZXRdOwotCi0gICAgICAgIGlmIChYTUwxMUNoYXIuaXNYTUwxMU5DTmFtZVN0YXJ0KGNoKSkgewotICAgICAgICAgICAgaWYgKCsrZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gPT0gZkN1cnJlbnRFbnRpdHkuY291bnQpIHsKLSAgICAgICAgICAgICAgICBpbnZva2VMaXN0ZW5lcnMoMSk7Ci0gICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkuY2hbMF0gPSBjaDsKLSAgICAgICAgICAgICAgICBvZmZzZXQgPSAwOwotICAgICAgICAgICAgICAgIGlmIChsb2FkKDEsIGZhbHNlLCBmYWxzZSkpIHsKLSAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkuY29sdW1uTnVtYmVyKys7Ci0gICAgICAgICAgICAgICAgICAgIFN0cmluZyBuYW1lID0gZlN5bWJvbFRhYmxlLmFkZFN5bWJvbChmQ3VycmVudEVudGl0eS5jaCwgMCwgMSk7Ci0gICAgICAgICAgICAgICAgICAgIHFuYW1lLnNldFZhbHVlcyhudWxsLCBuYW1lLCBuYW1lLCBudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgY2hlY2tFbnRpdHlMaW1pdChudCwgZkN1cnJlbnRFbnRpdHksIDAsIDEpOwotICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoWE1MMTFDaGFyLmlzWE1MMTFOYW1lSGlnaFN1cnJvZ2F0ZShjaCkpIHsKLSAgICAgICAgICAgIGlmICgrK2ZDdXJyZW50RW50aXR5LnBvc2l0aW9uID09IGZDdXJyZW50RW50aXR5LmNvdW50KSB7Ci0gICAgICAgICAgICAgICAgaW52b2tlTGlzdGVuZXJzKDEpOwotICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LmNoWzBdID0gY2g7Ci0gICAgICAgICAgICAgICAgb2Zmc2V0ID0gMDsKLSAgICAgICAgICAgICAgICBpZiAobG9hZCgxLCBmYWxzZSwgZmFsc2UpKSB7Ci0gICAgICAgICAgICAgICAgICAgIC0tZkN1cnJlbnRFbnRpdHkuc3RhcnRQb3NpdGlvbjsKLSAgICAgICAgICAgICAgICAgICAgLS1mQ3VycmVudEVudGl0eS5wb3NpdGlvbjsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNoYXIgY2gyID0gZkN1cnJlbnRFbnRpdHkuY2hbZkN1cnJlbnRFbnRpdHkucG9zaXRpb25dOwotICAgICAgICAgICAgaWYgKCAhWE1MQ2hhci5pc0xvd1N1cnJvZ2F0ZShjaDIpIHx8Ci0gICAgICAgICAgICAgICAgICFYTUwxMUNoYXIuaXNYTUwxMU5DTmFtZVN0YXJ0KFhNTENoYXIuc3VwcGxlbWVudGFsKGNoLCBjaDIpKSApIHsKLSAgICAgICAgICAgICAgICAtLWZDdXJyZW50RW50aXR5LnBvc2l0aW9uOwotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmICgrK2ZDdXJyZW50RW50aXR5LnBvc2l0aW9uID09IGZDdXJyZW50RW50aXR5LmNvdW50KSB7Ci0gICAgICAgICAgICAgICAgaW52b2tlTGlzdGVuZXJzKDIpOwotICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LmNoWzBdID0gY2g7Ci0gICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkuY2hbMV0gPSBjaDI7Ci0gICAgICAgICAgICAgICAgb2Zmc2V0ID0gMDsKLSAgICAgICAgICAgICAgICBpZiAobG9hZCgyLCBmYWxzZSwgZmFsc2UpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LmNvbHVtbk51bWJlciArPSAyOwotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbmFtZSA9IGZTeW1ib2xUYWJsZS5hZGRTeW1ib2woZkN1cnJlbnRFbnRpdHkuY2gsIDAsIDIpOwotICAgICAgICAgICAgICAgICAgICBxbmFtZS5zZXRWYWx1ZXMobnVsbCwgbmFtZSwgbmFtZSwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgIGNoZWNrRW50aXR5TGltaXQobnQsIGZDdXJyZW50RW50aXR5LCAwLCAyKTsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0KLSAgICAgICAgaW50IGluZGV4ID0gLTE7Ci0gICAgICAgIGludCBsZW5ndGggPSAwOwotICAgICAgICBib29sZWFuIHNhd0luY29tcGxldGVTdXJyb2dhdGVQYWlyID0gZmFsc2U7Ci0gICAgICAgIGRvIHsKLSAgICAgICAgICAgIGNoID0gZkN1cnJlbnRFbnRpdHkuY2hbZkN1cnJlbnRFbnRpdHkucG9zaXRpb25dOwotICAgICAgICAgICAgaWYgKFhNTDExQ2hhci5pc1hNTDExTmFtZShjaCkpIHsKLSAgICAgICAgICAgICAgICBpZiAoY2ggPT0gJzonKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChpbmRleCAhPSAtMSkgewotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgaW5kZXggPSBmQ3VycmVudEVudGl0eS5wb3NpdGlvbjsKLSAgICAgICAgICAgICAgICAgICAgLy9jaGVjayBwcmVmaXggYmVmb3JlIGZ1cnRoZXIgcmVhZAotICAgICAgICAgICAgICAgICAgICBjaGVja0xpbWl0KExpbWl0Lk1BWF9OQU1FX0xJTUlULCBmQ3VycmVudEVudGl0eSwgb2Zmc2V0LCBpbmRleCAtIG9mZnNldCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGlmICgobGVuZ3RoID0gY2hlY2tCZWZvcmVMb2FkKGZDdXJyZW50RW50aXR5LCBvZmZzZXQsIGluZGV4KSkgPiAwKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChpbmRleCAhPSAtMSkgewotICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXggPSBpbmRleCAtIG9mZnNldDsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBvZmZzZXQgPSAwOwotICAgICAgICAgICAgICAgICAgICBpZiAobG9hZChsZW5ndGgsIGZhbHNlLCBmYWxzZSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoWE1MMTFDaGFyLmlzWE1MMTFOYW1lSGlnaFN1cnJvZ2F0ZShjaCkpIHsKLSAgICAgICAgICAgICAgICBpZiAoKGxlbmd0aCA9IGNoZWNrQmVmb3JlTG9hZChmQ3VycmVudEVudGl0eSwgb2Zmc2V0LCBpbmRleCkpID4gMCkgewotICAgICAgICAgICAgICAgICAgICBpZiAoaW5kZXggIT0gLTEpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4ID0gaW5kZXggLSBvZmZzZXQ7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgb2Zmc2V0ID0gMDsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGxvYWQobGVuZ3RoLCBmYWxzZSwgZmFsc2UpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzYXdJbmNvbXBsZXRlU3Vycm9nYXRlUGFpciA9IHRydWU7Ci0gICAgICAgICAgICAgICAgICAgICAgICAtLWZDdXJyZW50RW50aXR5LnN0YXJ0UG9zaXRpb247Ci0gICAgICAgICAgICAgICAgICAgICAgICAtLWZDdXJyZW50RW50aXR5LnBvc2l0aW9uOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgY2hhciBjaDIgPSBmQ3VycmVudEVudGl0eS5jaFtmQ3VycmVudEVudGl0eS5wb3NpdGlvbl07Ci0gICAgICAgICAgICAgICAgaWYgKCAhWE1MQ2hhci5pc0xvd1N1cnJvZ2F0ZShjaDIpIHx8Ci0gICAgICAgICAgICAgICAgICAgICAhWE1MMTFDaGFyLmlzWE1MMTFOYW1lKFhNTENoYXIuc3VwcGxlbWVudGFsKGNoLCBjaDIpKSApIHsKLSAgICAgICAgICAgICAgICAgICAgc2F3SW5jb21wbGV0ZVN1cnJvZ2F0ZVBhaXIgPSB0cnVlOwotICAgICAgICAgICAgICAgICAgICAtLWZDdXJyZW50RW50aXR5LnBvc2l0aW9uOwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaWYgKChsZW5ndGggPSBjaGVja0JlZm9yZUxvYWQoZkN1cnJlbnRFbnRpdHksIG9mZnNldCwgaW5kZXgpKSA+IDApIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGluZGV4ICE9IC0xKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpbmRleCA9IGluZGV4IC0gb2Zmc2V0OwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIG9mZnNldCA9IDA7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChsb2FkKGxlbmd0aCwgZmFsc2UsIGZhbHNlKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICB3aGlsZSAodHJ1ZSk7Ci0KLSAgICAgICAgbGVuZ3RoID0gZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gLSBvZmZzZXQ7Ci0gICAgICAgIGZDdXJyZW50RW50aXR5LmNvbHVtbk51bWJlciArPSBsZW5ndGg7Ci0KLSAgICAgICAgaWYgKGxlbmd0aCA+IDApIHsKLSAgICAgICAgICAgIFN0cmluZyBwcmVmaXggPSBudWxsOwotICAgICAgICAgICAgU3RyaW5nIGxvY2FscGFydCA9IG51bGw7Ci0gICAgICAgICAgICBTdHJpbmcgcmF3bmFtZSA9IGZTeW1ib2xUYWJsZS5hZGRTeW1ib2woZkN1cnJlbnRFbnRpdHkuY2gsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0LCBsZW5ndGgpOwotICAgICAgICAgICAgaWYgKGluZGV4ICE9IC0xKSB7Ci0gICAgICAgICAgICAgICAgaW50IHByZWZpeExlbmd0aCA9IGluZGV4IC0gb2Zmc2V0OwotICAgICAgICAgICAgICAgIC8vY2hlY2sgdGhlIHJlc3VsdDogcHJlZml4Ci0gICAgICAgICAgICAgICAgY2hlY2tMaW1pdChMaW1pdC5NQVhfTkFNRV9MSU1JVCwgZkN1cnJlbnRFbnRpdHksIG9mZnNldCwgcHJlZml4TGVuZ3RoKTsKLSAgICAgICAgICAgICAgICBwcmVmaXggPSBmU3ltYm9sVGFibGUuYWRkU3ltYm9sKGZDdXJyZW50RW50aXR5LmNoLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldCwgcHJlZml4TGVuZ3RoKTsKLSAgICAgICAgICAgICAgICBpbnQgbGVuID0gbGVuZ3RoIC0gcHJlZml4TGVuZ3RoIC0gMTsKLSAgICAgICAgICAgICAgICBpbnQgc3RhcnRMb2NhbCA9IGluZGV4ICsxOwotICAgICAgICAgICAgICAgIGlmICghWE1MMTFDaGFyLmlzWE1MMTFOQ05hbWVTdGFydChmQ3VycmVudEVudGl0eS5jaFtzdGFydExvY2FsXSkgJiYKLSAgICAgICAgICAgICAgICAgICAgKCFYTUwxMUNoYXIuaXNYTUwxMU5hbWVIaWdoU3Vycm9nYXRlKGZDdXJyZW50RW50aXR5LmNoW3N0YXJ0TG9jYWxdKSB8fAotICAgICAgICAgICAgICAgICAgICBzYXdJbmNvbXBsZXRlU3Vycm9nYXRlUGFpcikpewotICAgICAgICAgICAgICAgICAgICBmRXJyb3JSZXBvcnRlci5yZXBvcnRFcnJvcihYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJJbGxlZ2FsUU5hbWUiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxFcnJvclJlcG9ydGVyLlNFVkVSSVRZX0ZBVEFMX0VSUk9SKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLy9jaGVjayB0aGUgcmVzdWx0OiBsb2NhbHBhcnQKLSAgICAgICAgICAgICAgICBjaGVja0xpbWl0KExpbWl0Lk1BWF9OQU1FX0xJTUlULCBmQ3VycmVudEVudGl0eSwgaW5kZXggKyAxLCBsZW4pOwotICAgICAgICAgICAgICAgIGxvY2FscGFydCA9IGZTeW1ib2xUYWJsZS5hZGRTeW1ib2woZkN1cnJlbnRFbnRpdHkuY2gsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmRleCArIDEsIGxlbik7Ci0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIGxvY2FscGFydCA9IHJhd25hbWU7Ci0gICAgICAgICAgICAgICAgLy9jaGVjayB0aGUgcmVzdWx0OiBsb2NhbHBhcnQKLSAgICAgICAgICAgICAgICBjaGVja0xpbWl0KExpbWl0Lk1BWF9OQU1FX0xJTUlULCBmQ3VycmVudEVudGl0eSwgb2Zmc2V0LCBsZW5ndGgpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcW5hbWUuc2V0VmFsdWVzKHByZWZpeCwgbG9jYWxwYXJ0LCByYXduYW1lLCBudWxsKTsKLSAgICAgICAgICAgIGNoZWNrRW50aXR5TGltaXQobnQsIGZDdXJyZW50RW50aXR5LCBvZmZzZXQsIGxlbmd0aCk7Ci0gICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZmFsc2U7Ci0KLSAgICB9IC8vIHNjYW5RTmFtZShRTmFtZSk6Ym9vbGVhbgotCi0gICAgLyoqCi0gICAgICogU2NhbnMgYSByYW5nZSBvZiBwYXJzZWQgY2hhcmFjdGVyIGRhdGEsIHNldHRpbmcgdGhlIGZpZWxkcyBvZiB0aGUKLSAgICAgKiBYTUxTdHJpbmcgc3RydWN0dXJlLCBhcHByb3ByaWF0ZWx5LgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gVGhlIGNoYXJhY3RlcnMgYXJlIGNvbnN1bWVkLgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gVGhpcyBtZXRob2QgZG9lcyBub3QgZ3VhcmFudGVlIHRvIHJldHVybgotICAgICAqIHRoZSBsb25nZXN0IHJ1biBvZiBwYXJzZWQgY2hhcmFjdGVyIGRhdGEuIFRoaXMgbWV0aG9kIG1heSByZXR1cm4KLSAgICAgKiBiZWZvcmUgbWFya3VwIGR1ZSB0byByZWFjaGluZyB0aGUgZW5kIG9mIHRoZSBpbnB1dCBidWZmZXIgb3IgYW55Ci0gICAgICogb3RoZXIgcmVhc29uLgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gVGhlIGZpZWxkcyBjb250YWluZWQgaW4gdGhlIFhNTFN0cmluZwotICAgICAqIHN0cnVjdHVyZSBhcmUgbm90IGd1YXJhbnRlZWQgdG8gcmVtYWluIHZhbGlkIHVwb24gc3Vic2VxdWVudCBjYWxscwotICAgICAqIHRvIHRoZSBlbnRpdHkgc2Nhbm5lci4gVGhlcmVmb3JlLCB0aGUgY2FsbGVyIGlzIHJlc3BvbnNpYmxlIGZvcgotICAgICAqIGltbWVkaWF0ZWx5IHVzaW5nIHRoZSByZXR1cm5lZCBjaGFyYWN0ZXIgZGF0YSBvciBtYWtpbmcgYSBjb3B5IG9mCi0gICAgICogdGhlIGNoYXJhY3RlciBkYXRhLgotICAgICAqCi0gICAgICogQHBhcmFtIGNvbnRlbnQgVGhlIGNvbnRlbnQgc3RydWN0dXJlIHRvIGZpbGwuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFJldHVybnMgdGhlIG5leHQgY2hhcmFjdGVyIG9uIHRoZSBpbnB1dCwgaWYga25vd24uIFRoaXMKLSAgICAgKiAgICAgICAgIHZhbHVlIG1heSBiZSAtMSBidXQgdGhpcyBkb2VzIDxlbT5ub3RlPC9lbT4gZGVzaWduYXRlCi0gICAgICogICAgICAgICBlbmQgb2YgZmlsZS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gIFRocm93biBpZiBpL28gZXJyb3Igb2NjdXJzLgotICAgICAqIEB0aHJvd3MgRU9GRXhjZXB0aW9uIFRocm93biBvbiBlbmQgb2YgZmlsZS4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgaW50IHNjYW5Db250ZW50KFhNTFN0cmluZyBjb250ZW50KSB0aHJvd3MgSU9FeGNlcHRpb24gewotCi0gICAgICAgIC8vIGxvYWQgbW9yZSBjaGFyYWN0ZXJzLCBpZiBuZWVkZWQKLSAgICAgICAgaWYgKGZDdXJyZW50RW50aXR5LnBvc2l0aW9uID09IGZDdXJyZW50RW50aXR5LmNvdW50KSB7Ci0gICAgICAgICAgICBsb2FkKDAsIHRydWUsIHRydWUpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKGZDdXJyZW50RW50aXR5LnBvc2l0aW9uID09IGZDdXJyZW50RW50aXR5LmNvdW50IC0gMSkgewotICAgICAgICAgICAgaW52b2tlTGlzdGVuZXJzKDEpOwotICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkuY2hbMF0gPSBmQ3VycmVudEVudGl0eS5jaFtmQ3VycmVudEVudGl0eS5jb3VudCAtIDFdOwotICAgICAgICAgICAgbG9hZCgxLCBmYWxzZSwgZmFsc2UpOwotICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gPSAwOwotICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkuc3RhcnRQb3NpdGlvbiA9IDA7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBub3JtYWxpemUgbmV3bGluZXMKLSAgICAgICAgaW50IG9mZnNldCA9IGZDdXJyZW50RW50aXR5LnBvc2l0aW9uOwotICAgICAgICBpbnQgYyA9IGZDdXJyZW50RW50aXR5LmNoW29mZnNldF07Ci0gICAgICAgIGludCBuZXdsaW5lcyA9IDA7Ci0gICAgICAgIGJvb2xlYW4gY291bnRlZCA9IGZhbHNlOwotICAgICAgICBib29sZWFuIGV4dGVybmFsID0gZkN1cnJlbnRFbnRpdHkuaXNFeHRlcm5hbCgpOwotICAgICAgICBpZiAoYyA9PSAnXG4nIHx8ICgoYyA9PSAnXHInIHx8IGMgPT0gMHg4NSB8fCBjID09IDB4MjAyOCkgJiYgZXh0ZXJuYWwpKSB7Ci0gICAgICAgICAgICBkbyB7Ci0gICAgICAgICAgICAgICAgYyA9IGZDdXJyZW50RW50aXR5LmNoW2ZDdXJyZW50RW50aXR5LnBvc2l0aW9uKytdOwotICAgICAgICAgICAgICAgIGlmICgoYyA9PSAnXHInICkgJiYgZXh0ZXJuYWwpIHsKLSAgICAgICAgICAgICAgICAgICAgbmV3bGluZXMrKzsKLSAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkubGluZU51bWJlcisrOwotICAgICAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5jb2x1bW5OdW1iZXIgPSAxOwotICAgICAgICAgICAgICAgICAgICBpZiAoZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gPT0gZkN1cnJlbnRFbnRpdHkuY291bnQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGNoZWNrRW50aXR5TGltaXQobnVsbCwgZkN1cnJlbnRFbnRpdHksIG9mZnNldCwgbmV3bGluZXMpOwotICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0ID0gMDsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LmJhc2VDaGFyT2Zmc2V0ICs9IChmQ3VycmVudEVudGl0eS5wb3NpdGlvbiAtIGZDdXJyZW50RW50aXR5LnN0YXJ0UG9zaXRpb24pOwotICAgICAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gPSBuZXdsaW5lczsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LnN0YXJ0UG9zaXRpb24gPSBuZXdsaW5lczsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsb2FkKG5ld2xpbmVzLCBmYWxzZSwgdHJ1ZSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3VudGVkID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBpbnQgY2MgPSBmQ3VycmVudEVudGl0eS5jaFtmQ3VycmVudEVudGl0eS5wb3NpdGlvbl07Ci0gICAgICAgICAgICAgICAgICAgIGlmIChjYyA9PSAnXG4nIHx8IGNjID09IDB4ODUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LnBvc2l0aW9uKys7Ci0gICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQrKzsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAvKioqIE5FV0xJTkUgTk9STUFMSVpBVElPTiAqKiovCi0gICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgbmV3bGluZXMrKzsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIGlmIChjID09ICdcbicgfHwgKChjID09IDB4ODUgfHwgYyA9PSAweDIwMjgpICYmIGV4dGVybmFsKSkgewotICAgICAgICAgICAgICAgICAgICBuZXdsaW5lcysrOwotICAgICAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5saW5lTnVtYmVyKys7Ci0gICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LmNvbHVtbk51bWJlciA9IDE7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChmQ3VycmVudEVudGl0eS5wb3NpdGlvbiA9PSBmQ3VycmVudEVudGl0eS5jb3VudCkgewotICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tFbnRpdHlMaW1pdChudWxsLCBmQ3VycmVudEVudGl0eSwgb2Zmc2V0LCBuZXdsaW5lcyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQgPSAwOwotICAgICAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkuYmFzZUNoYXJPZmZzZXQgKz0gKGZDdXJyZW50RW50aXR5LnBvc2l0aW9uIC0gZkN1cnJlbnRFbnRpdHkuc3RhcnRQb3NpdGlvbik7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5wb3NpdGlvbiA9IG5ld2xpbmVzOwotICAgICAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkuc3RhcnRQb3NpdGlvbiA9IG5ld2xpbmVzOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxvYWQobmV3bGluZXMsIGZhbHNlLCB0cnVlKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50ZWQgPSB0cnVlOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5wb3NpdGlvbi0tOwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9IHdoaWxlIChmQ3VycmVudEVudGl0eS5wb3NpdGlvbiA8IGZDdXJyZW50RW50aXR5LmNvdW50IC0gMSk7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gb2Zmc2V0OyBpIDwgZkN1cnJlbnRFbnRpdHkucG9zaXRpb247IGkrKykgewotICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LmNoW2ldID0gJ1xuJzsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGludCBsZW5ndGggPSBmQ3VycmVudEVudGl0eS5wb3NpdGlvbiAtIG9mZnNldDsKLSAgICAgICAgICAgIGlmIChmQ3VycmVudEVudGl0eS5wb3NpdGlvbiA9PSBmQ3VycmVudEVudGl0eS5jb3VudCAtIDEpIHsKLSAgICAgICAgICAgICAgICBjaGVja0VudGl0eUxpbWl0KG51bGwsIGZDdXJyZW50RW50aXR5LCBvZmZzZXQsIGxlbmd0aCk7Ci0gICAgICAgICAgICAgICAgY29udGVudC5zZXRWYWx1ZXMoZkN1cnJlbnRFbnRpdHkuY2gsIG9mZnNldCwgbGVuZ3RoKTsKLSAgICAgICAgICAgICAgICByZXR1cm4gLTE7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBpbm5lciBsb29wLCBzY2FubmluZyBmb3IgY29udGVudAotICAgICAgICBpZiAoZXh0ZXJuYWwpIHsKLSAgICAgICAgICAgIHdoaWxlIChmQ3VycmVudEVudGl0eS5wb3NpdGlvbiA8IGZDdXJyZW50RW50aXR5LmNvdW50KSB7Ci0gICAgICAgICAgICAgICAgYyA9IGZDdXJyZW50RW50aXR5LmNoW2ZDdXJyZW50RW50aXR5LnBvc2l0aW9uKytdOwotICAgICAgICAgICAgICAgIGlmICghWE1MMTFDaGFyLmlzWE1MMTFDb250ZW50KGMpIHx8IGMgPT0gMHg4NSB8fCBjID09IDB4MjAyOCkgewotICAgICAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5wb3NpdGlvbi0tOwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICB3aGlsZSAoZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gPCBmQ3VycmVudEVudGl0eS5jb3VudCkgewotICAgICAgICAgICAgICAgIGMgPSBmQ3VycmVudEVudGl0eS5jaFtmQ3VycmVudEVudGl0eS5wb3NpdGlvbisrXTsKLSAgICAgICAgICAgICAgICAvLyBJbiBpbnRlcm5hbCBlbnRpdGllcyBjb250cm9sIGNoYXJhY3RlcnMgYXJlIGFsbG93ZWQgdG8gYXBwZWFyIHVuZXNjYXBlZC4KLSAgICAgICAgICAgICAgICBpZiAoIVhNTDExQ2hhci5pc1hNTDExSW50ZXJuYWxFbnRpdHlDb250ZW50KGMpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LnBvc2l0aW9uLS07Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBpbnQgbGVuZ3RoID0gZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gLSBvZmZzZXQ7Ci0gICAgICAgIGZDdXJyZW50RW50aXR5LmNvbHVtbk51bWJlciArPSBsZW5ndGggLSBuZXdsaW5lczsKLSAgICAgICAgaWYgKCFjb3VudGVkKSB7Ci0gICAgICAgICAgICBjaGVja0VudGl0eUxpbWl0KG51bGwsIGZDdXJyZW50RW50aXR5LCBvZmZzZXQsIGxlbmd0aCk7Ci0gICAgICAgIH0KLSAgICAgICAgY29udGVudC5zZXRWYWx1ZXMoZkN1cnJlbnRFbnRpdHkuY2gsIG9mZnNldCwgbGVuZ3RoKTsKLQotICAgICAgICAvLyByZXR1cm4gbmV4dCBjaGFyYWN0ZXIKLSAgICAgICAgaWYgKGZDdXJyZW50RW50aXR5LnBvc2l0aW9uICE9IGZDdXJyZW50RW50aXR5LmNvdW50KSB7Ci0gICAgICAgICAgICBjID0gZkN1cnJlbnRFbnRpdHkuY2hbZkN1cnJlbnRFbnRpdHkucG9zaXRpb25dOwotICAgICAgICAgICAgLy8gUkVWSVNJVDogRG9lcyB0aGlzIG5lZWQgdG8gYmUgdXBkYXRlZCB0byBmaXggdGhlCi0gICAgICAgICAgICAvLyAgICAgICAgICAjeDBEIF4jeDBBIG5ld2xpbmUgbm9ybWFsaXphdGlvbiBwcm9ibGVtPyAtQWMKLSAgICAgICAgICAgIGlmICgoYyA9PSAnXHInIHx8IGMgPT0gMHg4NSB8fCBjID09IDB4MjAyOCkgJiYgZXh0ZXJuYWwpIHsKLSAgICAgICAgICAgICAgICBjID0gJ1xuJzsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIGMgPSAtMTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gYzsKLQotICAgIH0gLy8gc2NhbkNvbnRlbnQoWE1MU3RyaW5nKTppbnQKLQotICAgIC8qKgotICAgICAqIFNjYW5zIGEgcmFuZ2Ugb2YgYXR0cmlidXRlIHZhbHVlIGRhdGEsIHNldHRpbmcgdGhlIGZpZWxkcyBvZiB0aGUKLSAgICAgKiBYTUxTdHJpbmcgc3RydWN0dXJlLCBhcHByb3ByaWF0ZWx5LgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gVGhlIGNoYXJhY3RlcnMgYXJlIGNvbnN1bWVkLgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gVGhpcyBtZXRob2QgZG9lcyBub3QgZ3VhcmFudGVlIHRvIHJldHVybgotICAgICAqIHRoZSBsb25nZXN0IHJ1biBvZiBhdHRyaWJ1dGUgdmFsdWUgZGF0YS4gVGhpcyBtZXRob2QgbWF5IHJldHVybgotICAgICAqIGJlZm9yZSB0aGUgcXVvdGUgY2hhcmFjdGVyIGR1ZSB0byByZWFjaGluZyB0aGUgZW5kIG9mIHRoZSBpbnB1dAotICAgICAqIGJ1ZmZlciBvciBhbnkgb3RoZXIgcmVhc29uLgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gVGhlIGZpZWxkcyBjb250YWluZWQgaW4gdGhlIFhNTFN0cmluZwotICAgICAqIHN0cnVjdHVyZSBhcmUgbm90IGd1YXJhbnRlZWQgdG8gcmVtYWluIHZhbGlkIHVwb24gc3Vic2VxdWVudCBjYWxscwotICAgICAqIHRvIHRoZSBlbnRpdHkgc2Nhbm5lci4gVGhlcmVmb3JlLCB0aGUgY2FsbGVyIGlzIHJlc3BvbnNpYmxlIGZvcgotICAgICAqIGltbWVkaWF0ZWx5IHVzaW5nIHRoZSByZXR1cm5lZCBjaGFyYWN0ZXIgZGF0YSBvciBtYWtpbmcgYSBjb3B5IG9mCi0gICAgICogdGhlIGNoYXJhY3RlciBkYXRhLgotICAgICAqCi0gICAgICogQHBhcmFtIHF1b3RlICAgVGhlIHF1b3RlIGNoYXJhY3RlciB0aGF0IHNpZ25pZmllcyB0aGUgZW5kIG9mIHRoZQotICAgICAqICAgICAgICAgICAgICAgIGF0dHJpYnV0ZSB2YWx1ZSBkYXRhLgotICAgICAqIEBwYXJhbSBjb250ZW50IFRoZSBjb250ZW50IHN0cnVjdHVyZSB0byBmaWxsLgotICAgICAqIEBwYXJhbSBpc05TVVJJIGEgZmxhZyBpbmRpY2F0aW5nIHdoZXRoZXIgdGhlIGNvbnRlbnQgaXMgYSBOYW1lc3BhY2UgVVJJCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFJldHVybnMgdGhlIG5leHQgY2hhcmFjdGVyIG9uIHRoZSBpbnB1dCwgaWYga25vd24uIFRoaXMKLSAgICAgKiAgICAgICAgIHZhbHVlIG1heSBiZSAtMSBidXQgdGhpcyBkb2VzIDxlbT5ub3RlPC9lbT4gZGVzaWduYXRlCi0gICAgICogICAgICAgICBlbmQgb2YgZmlsZS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gIFRocm93biBpZiBpL28gZXJyb3Igb2NjdXJzLgotICAgICAqIEB0aHJvd3MgRU9GRXhjZXB0aW9uIFRocm93biBvbiBlbmQgb2YgZmlsZS4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgaW50IHNjYW5MaXRlcmFsKGludCBxdW90ZSwgWE1MU3RyaW5nIGNvbnRlbnQsIGJvb2xlYW4gaXNOU1VSSSkKLSAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKLSAgICAgICAgLy8gbG9hZCBtb3JlIGNoYXJhY3RlcnMsIGlmIG5lZWRlZAotICAgICAgICBpZiAoZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gPT0gZkN1cnJlbnRFbnRpdHkuY291bnQpIHsKLSAgICAgICAgICAgIGxvYWQoMCwgdHJ1ZSwgdHJ1ZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gPT0gZkN1cnJlbnRFbnRpdHkuY291bnQgLSAxKSB7Ci0gICAgICAgICAgICBpbnZva2VMaXN0ZW5lcnMoMSk7Ci0gICAgICAgICAgICBmQ3VycmVudEVudGl0eS5jaFswXSA9IGZDdXJyZW50RW50aXR5LmNoW2ZDdXJyZW50RW50aXR5LmNvdW50IC0gMV07Ci0gICAgICAgICAgICBsb2FkKDEsIGZhbHNlLCBmYWxzZSk7Ci0gICAgICAgICAgICBmQ3VycmVudEVudGl0eS5zdGFydFBvc2l0aW9uID0gMDsKLSAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LnBvc2l0aW9uID0gMDsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIG5vcm1hbGl6ZSBuZXdsaW5lcwotICAgICAgICBpbnQgb2Zmc2V0ID0gZkN1cnJlbnRFbnRpdHkucG9zaXRpb247Ci0gICAgICAgIGludCBjID0gZkN1cnJlbnRFbnRpdHkuY2hbb2Zmc2V0XTsKLSAgICAgICAgaW50IG5ld2xpbmVzID0gMDsKLSAgICAgICAgYm9vbGVhbiBleHRlcm5hbCA9IGZDdXJyZW50RW50aXR5LmlzRXh0ZXJuYWwoKTsKLSAgICAgICAgaWYgKGMgPT0gJ1xuJyB8fCAoKGMgPT0gJ1xyJyB8fCBjID09IDB4ODUgfHwgYyA9PSAweDIwMjgpICYmIGV4dGVybmFsKSkgewotICAgICAgICAgICAgZG8gewotICAgICAgICAgICAgICAgIGMgPSBmQ3VycmVudEVudGl0eS5jaFtmQ3VycmVudEVudGl0eS5wb3NpdGlvbisrXTsKLSAgICAgICAgICAgICAgICBpZiAoKGMgPT0gJ1xyJyApICYmIGV4dGVybmFsKSB7Ci0gICAgICAgICAgICAgICAgICAgIG5ld2xpbmVzKys7Ci0gICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LmxpbmVOdW1iZXIrKzsKLSAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkuY29sdW1uTnVtYmVyID0gMTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGZDdXJyZW50RW50aXR5LnBvc2l0aW9uID09IGZDdXJyZW50RW50aXR5LmNvdW50KSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQgPSAwOwotICAgICAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkuYmFzZUNoYXJPZmZzZXQgKz0gKGZDdXJyZW50RW50aXR5LnBvc2l0aW9uIC0gZkN1cnJlbnRFbnRpdHkuc3RhcnRQb3NpdGlvbik7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5wb3NpdGlvbiA9IG5ld2xpbmVzOwotICAgICAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkuc3RhcnRQb3NpdGlvbiA9IG5ld2xpbmVzOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxvYWQobmV3bGluZXMsIGZhbHNlLCB0cnVlKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGludCBjYyA9IGZDdXJyZW50RW50aXR5LmNoW2ZDdXJyZW50RW50aXR5LnBvc2l0aW9uXTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGNjID09ICdcbicgfHwgY2MgPT0gMHg4NSkgewotICAgICAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkucG9zaXRpb24rKzsKLSAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldCsrOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIC8qKiogTkVXTElORSBOT1JNQUxJWkFUSU9OICoqKi8KLSAgICAgICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBuZXdsaW5lcysrOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgaWYgKGMgPT0gJ1xuJyB8fCAoKGMgPT0gMHg4NSB8fCBjID09IDB4MjAyOCkgJiYgZXh0ZXJuYWwpKSB7Ci0gICAgICAgICAgICAgICAgICAgIG5ld2xpbmVzKys7Ci0gICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LmxpbmVOdW1iZXIrKzsKLSAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkuY29sdW1uTnVtYmVyID0gMTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGZDdXJyZW50RW50aXR5LnBvc2l0aW9uID09IGZDdXJyZW50RW50aXR5LmNvdW50KSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQgPSAwOwotICAgICAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkuYmFzZUNoYXJPZmZzZXQgKz0gKGZDdXJyZW50RW50aXR5LnBvc2l0aW9uIC0gZkN1cnJlbnRFbnRpdHkuc3RhcnRQb3NpdGlvbik7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5wb3NpdGlvbiA9IG5ld2xpbmVzOwotICAgICAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkuc3RhcnRQb3NpdGlvbiA9IG5ld2xpbmVzOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxvYWQobmV3bGluZXMsIGZhbHNlLCB0cnVlKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5wb3NpdGlvbi0tOwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9IHdoaWxlIChmQ3VycmVudEVudGl0eS5wb3NpdGlvbiA8IGZDdXJyZW50RW50aXR5LmNvdW50IC0gMSk7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gb2Zmc2V0OyBpIDwgZkN1cnJlbnRFbnRpdHkucG9zaXRpb247IGkrKykgewotICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LmNoW2ldID0gJ1xuJzsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGludCBsZW5ndGggPSBmQ3VycmVudEVudGl0eS5wb3NpdGlvbiAtIG9mZnNldDsKLSAgICAgICAgICAgIGlmIChmQ3VycmVudEVudGl0eS5wb3NpdGlvbiA9PSBmQ3VycmVudEVudGl0eS5jb3VudCAtIDEpIHsKLSAgICAgICAgICAgICAgICBjb250ZW50LnNldFZhbHVlcyhmQ3VycmVudEVudGl0eS5jaCwgb2Zmc2V0LCBsZW5ndGgpOwotICAgICAgICAgICAgICAgIHJldHVybiAtMTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIHNjYW4gbGl0ZXJhbCB2YWx1ZQotICAgICAgICBpZiAoZXh0ZXJuYWwpIHsKLSAgICAgICAgICAgIHdoaWxlIChmQ3VycmVudEVudGl0eS5wb3NpdGlvbiA8IGZDdXJyZW50RW50aXR5LmNvdW50KSB7Ci0gICAgICAgICAgICAgICAgYyA9IGZDdXJyZW50RW50aXR5LmNoW2ZDdXJyZW50RW50aXR5LnBvc2l0aW9uKytdOwotICAgICAgICAgICAgICAgIGlmIChjID09IHF1b3RlIHx8IGMgPT0gJyUnIHx8ICFYTUwxMUNoYXIuaXNYTUwxMUNvbnRlbnQoYykKLSAgICAgICAgICAgICAgICAgICAgfHwgYyA9PSAweDg1IHx8IGMgPT0gMHgyMDI4KSB7Ci0gICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LnBvc2l0aW9uLS07Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHdoaWxlIChmQ3VycmVudEVudGl0eS5wb3NpdGlvbiA8IGZDdXJyZW50RW50aXR5LmNvdW50KSB7Ci0gICAgICAgICAgICAgICAgYyA9IGZDdXJyZW50RW50aXR5LmNoW2ZDdXJyZW50RW50aXR5LnBvc2l0aW9uKytdOwotICAgICAgICAgICAgICAgIC8vIEluIGludGVybmFsIGVudGl0aWVzIGNvbnRyb2wgY2hhcmFjdGVycyBhcmUgYWxsb3dlZCB0byBhcHBlYXIgdW5lc2NhcGVkLgotICAgICAgICAgICAgICAgIGlmICgoYyA9PSBxdW90ZSAmJiAhZkN1cnJlbnRFbnRpdHkubGl0ZXJhbCkKLSAgICAgICAgICAgICAgICAgICAgfHwgYyA9PSAnJScgfHwgIVhNTDExQ2hhci5pc1hNTDExSW50ZXJuYWxFbnRpdHlDb250ZW50KGMpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LnBvc2l0aW9uLS07Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBpbnQgbGVuZ3RoID0gZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gLSBvZmZzZXQ7Ci0gICAgICAgIGZDdXJyZW50RW50aXR5LmNvbHVtbk51bWJlciArPSBsZW5ndGggLSBuZXdsaW5lczsKLQotICAgICAgICBjaGVja0VudGl0eUxpbWl0KG51bGwsIGZDdXJyZW50RW50aXR5LCBvZmZzZXQsIGxlbmd0aCk7Ci0gICAgICAgIGlmIChpc05TVVJJKSB7Ci0gICAgICAgICAgICBjaGVja0xpbWl0KExpbWl0Lk1BWF9OQU1FX0xJTUlULCBmQ3VycmVudEVudGl0eSwgb2Zmc2V0LCBsZW5ndGgpOwotICAgICAgICB9Ci0gICAgICAgIGNvbnRlbnQuc2V0VmFsdWVzKGZDdXJyZW50RW50aXR5LmNoLCBvZmZzZXQsIGxlbmd0aCk7Ci0KLSAgICAgICAgLy8gcmV0dXJuIG5leHQgY2hhcmFjdGVyCi0gICAgICAgIGlmIChmQ3VycmVudEVudGl0eS5wb3NpdGlvbiAhPSBmQ3VycmVudEVudGl0eS5jb3VudCkgewotICAgICAgICAgICAgYyA9IGZDdXJyZW50RW50aXR5LmNoW2ZDdXJyZW50RW50aXR5LnBvc2l0aW9uXTsKLSAgICAgICAgICAgIC8vIE5PVEU6IFdlIGRvbid0IHdhbnQgdG8gYWNjaWRlbnRhbGx5IHNpZ25hbCB0aGUKLSAgICAgICAgICAgIC8vICAgICAgIGVuZCBvZiB0aGUgbGl0ZXJhbCBpZiB3ZSdyZSBleHBhbmRpbmcgYW4KLSAgICAgICAgICAgIC8vICAgICAgIGVudGl0eSBhcHBlYXJpbmcgaW4gdGhlIGxpdGVyYWwuIC1BYwotICAgICAgICAgICAgaWYgKGMgPT0gcXVvdGUgJiYgZkN1cnJlbnRFbnRpdHkubGl0ZXJhbCkgewotICAgICAgICAgICAgICAgIGMgPSAtMTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIGMgPSAtMTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gYzsKLQotICAgIH0gLy8gc2NhbkxpdGVyYWwoaW50LFhNTFN0cmluZyk6aW50Ci0KLSAgICAvKioKLSAgICAgKiBTY2FucyBhIHJhbmdlIG9mIGNoYXJhY3RlciBkYXRhIHVwIHRvIHRoZSBzcGVjaWNpZWQgZGVsaW1pdGVyLAotICAgICAqIHNldHRpbmcgdGhlIGZpZWxkcyBvZiB0aGUgWE1MU3RyaW5nIHN0cnVjdHVyZSwgYXBwcm9wcmlhdGVseS4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoZSBjaGFyYWN0ZXJzIGFyZSBjb25zdW1lZC4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoaXMgYXNzdW1lcyB0aGF0IHRoZSBpbnRlcm5hbCBidWZmZXIgaXMKLSAgICAgKiBhdCBsZWFzdCB0aGUgc2FtZSBzaXplLCBvciBiaWdnZXIsIHRoYW4gdGhlIGxlbmd0aCBvZiB0aGUgZGVsaW1pdGVyCi0gICAgICogYW5kIHRoYXQgdGhlIGRlbGltaXRlciBjb250YWlucyBhdCBsZWFzdCBvbmUgY2hhcmFjdGVyLgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gVGhpcyBtZXRob2QgZG9lcyBub3QgZ3VhcmFudGVlIHRvIHJldHVybgotICAgICAqIHRoZSBsb25nZXN0IHJ1biBvZiBjaGFyYWN0ZXIgZGF0YS4gVGhpcyBtZXRob2QgbWF5IHJldHVybiBiZWZvcmUKLSAgICAgKiB0aGUgZGVsaW1pdGVyIGR1ZSB0byByZWFjaGluZyB0aGUgZW5kIG9mIHRoZSBpbnB1dCBidWZmZXIgb3IgYW55Ci0gICAgICogb3RoZXIgcmVhc29uLgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gVGhlIGZpZWxkcyBjb250YWluZWQgaW4gdGhlIFhNTFN0cmluZwotICAgICAqIHN0cnVjdHVyZSBhcmUgbm90IGd1YXJhbnRlZWQgdG8gcmVtYWluIHZhbGlkIHVwb24gc3Vic2VxdWVudCBjYWxscwotICAgICAqIHRvIHRoZSBlbnRpdHkgc2Nhbm5lci4gVGhlcmVmb3JlLCB0aGUgY2FsbGVyIGlzIHJlc3BvbnNpYmxlIGZvcgotICAgICAqIGltbWVkaWF0ZWx5IHVzaW5nIHRoZSByZXR1cm5lZCBjaGFyYWN0ZXIgZGF0YSBvciBtYWtpbmcgYSBjb3B5IG9mCi0gICAgICogdGhlIGNoYXJhY3RlciBkYXRhLgotICAgICAqCi0gICAgICogQHBhcmFtIGRlbGltaXRlciBUaGUgc3RyaW5nIHRoYXQgc2lnbmlmaWVzIHRoZSBlbmQgb2YgdGhlIGNoYXJhY3RlcgotICAgICAqICAgICAgICAgICAgICAgICAgZGF0YSB0byBiZSBzY2FubmVkLgotICAgICAqIEBwYXJhbSBkYXRhICAgICAgVGhlIGRhdGEgc3RydWN0dXJlIHRvIGZpbGwuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFJldHVybnMgdHJ1ZSBpZiB0aGVyZSBpcyBtb3JlIGRhdGEgdG8gc2NhbiwgZmFsc2Ugb3RoZXJ3aXNlLgotICAgICAqCi0gICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiAgVGhyb3duIGlmIGkvbyBlcnJvciBvY2N1cnMuCi0gICAgICogQHRocm93cyBFT0ZFeGNlcHRpb24gVGhyb3duIG9uIGVuZCBvZiBmaWxlLgotICAgICAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIHNjYW5EYXRhKFN0cmluZyBkZWxpbWl0ZXIsIFhNTFN0cmluZ0J1ZmZlciBidWZmZXIpCi0gICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0KLSAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7Ci0gICAgICAgIGludCBkZWxpbUxlbiA9IGRlbGltaXRlci5sZW5ndGgoKTsKLSAgICAgICAgY2hhciBjaGFyQXQwID0gZGVsaW1pdGVyLmNoYXJBdCgwKTsKLSAgICAgICAgYm9vbGVhbiBleHRlcm5hbCA9IGZDdXJyZW50RW50aXR5LmlzRXh0ZXJuYWwoKTsKLSAgICAgICAgZG8gewotICAgICAgICAgICAgLy8gbG9hZCBtb3JlIGNoYXJhY3RlcnMsIGlmIG5lZWRlZAotICAgICAgICAgICAgaWYgKGZDdXJyZW50RW50aXR5LnBvc2l0aW9uID09IGZDdXJyZW50RW50aXR5LmNvdW50KSB7Ci0gICAgICAgICAgICAgICAgbG9hZCgwLCB0cnVlLCBmYWxzZSk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGJvb2xlYW4gYk5leHRFbnRpdHkgPSBmYWxzZTsKLQotICAgICAgICAgICAgd2hpbGUgKChmQ3VycmVudEVudGl0eS5wb3NpdGlvbiA+PSBmQ3VycmVudEVudGl0eS5jb3VudCAtIGRlbGltTGVuKQotICAgICAgICAgICAgICAgICYmICghYk5leHRFbnRpdHkpKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGZDdXJyZW50RW50aXR5LmNoLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LnBvc2l0aW9uLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LmNoLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkuY291bnQgLSBmQ3VycmVudEVudGl0eS5wb3NpdGlvbik7Ci0KLSAgICAgICAgICAgICAgYk5leHRFbnRpdHkgPSBsb2FkKGZDdXJyZW50RW50aXR5LmNvdW50IC0gZkN1cnJlbnRFbnRpdHkucG9zaXRpb24sIGZhbHNlLCBmYWxzZSk7Ci0gICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LnBvc2l0aW9uID0gMDsKLSAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkuc3RhcnRQb3NpdGlvbiA9IDA7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmIChmQ3VycmVudEVudGl0eS5wb3NpdGlvbiA+PSBmQ3VycmVudEVudGl0eS5jb3VudCAtIGRlbGltTGVuKSB7Ci0gICAgICAgICAgICAgICAgLy8gc29tZXRoaW5nIG11c3QgYmUgd3Jvbmcgd2l0aCB0aGUgaW5wdXQ6ICBlLmcuLCBmaWxlIGVuZHMgIGFuIHVudGVybWluYXRlZCBjb21tZW50Ci0gICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGZDdXJyZW50RW50aXR5LmNvdW50IC0gZkN1cnJlbnRFbnRpdHkucG9zaXRpb247Ci0gICAgICAgICAgICAgICAgY2hlY2tFbnRpdHlMaW1pdChOYW1lVHlwZS5DT01NRU5ULCBmQ3VycmVudEVudGl0eSwgZkN1cnJlbnRFbnRpdHkucG9zaXRpb24sIGxlbmd0aCk7Ci0gICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCAoZkN1cnJlbnRFbnRpdHkuY2gsIGZDdXJyZW50RW50aXR5LnBvc2l0aW9uLCBsZW5ndGgpOwotICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LmNvbHVtbk51bWJlciArPSBmQ3VycmVudEVudGl0eS5jb3VudDsKLSAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5iYXNlQ2hhck9mZnNldCArPSAoZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gLSBmQ3VycmVudEVudGl0eS5zdGFydFBvc2l0aW9uKTsKLSAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5wb3NpdGlvbiA9IGZDdXJyZW50RW50aXR5LmNvdW50OwotICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LnN0YXJ0UG9zaXRpb24gPSBmQ3VycmVudEVudGl0eS5jb3VudDsKLSAgICAgICAgICAgICAgICBsb2FkKDAsdHJ1ZSwgZmFsc2UpOwotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gbm9ybWFsaXplIG5ld2xpbmVzCi0gICAgICAgICAgICBpbnQgb2Zmc2V0ID0gZkN1cnJlbnRFbnRpdHkucG9zaXRpb247Ci0gICAgICAgICAgICBpbnQgYyA9IGZDdXJyZW50RW50aXR5LmNoW29mZnNldF07Ci0gICAgICAgICAgICBpbnQgbmV3bGluZXMgPSAwOwotICAgICAgICAgICAgaWYgKGMgPT0gJ1xuJyB8fCAoKGMgPT0gJ1xyJyB8fCBjID09IDB4ODUgfHwgYyA9PSAweDIwMjgpICYmIGV4dGVybmFsKSkgewotICAgICAgICAgICAgICAgIGRvIHsKLSAgICAgICAgICAgICAgICAgICAgYyA9IGZDdXJyZW50RW50aXR5LmNoW2ZDdXJyZW50RW50aXR5LnBvc2l0aW9uKytdOwotICAgICAgICAgICAgICAgICAgICBpZiAoKGMgPT0gJ1xyJyApICYmIGV4dGVybmFsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBuZXdsaW5lcysrOwotICAgICAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkubGluZU51bWJlcisrOwotICAgICAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkuY29sdW1uTnVtYmVyID0gMTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmQ3VycmVudEVudGl0eS5wb3NpdGlvbiA9PSBmQ3VycmVudEVudGl0eS5jb3VudCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldCA9IDA7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkuYmFzZUNoYXJPZmZzZXQgKz0gKGZDdXJyZW50RW50aXR5LnBvc2l0aW9uIC0gZkN1cnJlbnRFbnRpdHkuc3RhcnRQb3NpdGlvbik7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gPSBuZXdsaW5lczsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5zdGFydFBvc2l0aW9uID0gbmV3bGluZXM7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxvYWQobmV3bGluZXMsIGZhbHNlLCB0cnVlKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBpbnQgY2MgPSBmQ3VycmVudEVudGl0eS5jaFtmQ3VycmVudEVudGl0eS5wb3NpdGlvbl07Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2MgPT0gJ1xuJyB8fCBjYyA9PSAweDg1KSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkucG9zaXRpb24rKzsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQrKzsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIC8qKiogTkVXTElORSBOT1JNQUxJWkFUSU9OICoqKi8KLSAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld2xpbmVzKys7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoYyA9PSAnXG4nIHx8ICgoYyA9PSAweDg1IHx8IGMgPT0gMHgyMDI4KSAmJiBleHRlcm5hbCkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIG5ld2xpbmVzKys7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5saW5lTnVtYmVyKys7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5jb2x1bW5OdW1iZXIgPSAxOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZDdXJyZW50RW50aXR5LnBvc2l0aW9uID09IGZDdXJyZW50RW50aXR5LmNvdW50KSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0ID0gMDsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5iYXNlQ2hhck9mZnNldCArPSAoZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gLSBmQ3VycmVudEVudGl0eS5zdGFydFBvc2l0aW9uKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5wb3NpdGlvbiA9IG5ld2xpbmVzOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LnN0YXJ0UG9zaXRpb24gPSBuZXdsaW5lczsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5jb3VudCA9IG5ld2xpbmVzOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsb2FkKG5ld2xpbmVzLCBmYWxzZSwgdHJ1ZSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkucG9zaXRpb24tLTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfSB3aGlsZSAoZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gPCBmQ3VycmVudEVudGl0eS5jb3VudCAtIDEpOwotICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSBvZmZzZXQ7IGkgPCBmQ3VycmVudEVudGl0eS5wb3NpdGlvbjsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LmNoW2ldID0gJ1xuJzsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGZDdXJyZW50RW50aXR5LnBvc2l0aW9uIC0gb2Zmc2V0OwotICAgICAgICAgICAgICAgIGlmIChmQ3VycmVudEVudGl0eS5wb3NpdGlvbiA9PSBmQ3VycmVudEVudGl0eS5jb3VudCAtIDEpIHsKLSAgICAgICAgICAgICAgICAgICAgY2hlY2tFbnRpdHlMaW1pdChOYW1lVHlwZS5DT01NRU5ULCBmQ3VycmVudEVudGl0eSwgb2Zmc2V0LCBsZW5ndGgpOwotICAgICAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKGZDdXJyZW50RW50aXR5LmNoLCBvZmZzZXQsIGxlbmd0aCk7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gaXRlcmF0ZSBvdmVyIGJ1ZmZlciBsb29raW5nIGZvciBkZWxpbWl0ZXIKLSAgICAgICAgICAgIGlmIChleHRlcm5hbCkgewotICAgICAgICAgICAgICAgIE9VVEVSOiB3aGlsZSAoZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gPCBmQ3VycmVudEVudGl0eS5jb3VudCkgewotICAgICAgICAgICAgICAgICAgICBjID0gZkN1cnJlbnRFbnRpdHkuY2hbZkN1cnJlbnRFbnRpdHkucG9zaXRpb24rK107Ci0gICAgICAgICAgICAgICAgICAgIGlmIChjID09IGNoYXJBdDApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGxvb2tzIGxpa2Ugd2UganVzdCBoaXQgdGhlIGRlbGltaXRlcgotICAgICAgICAgICAgICAgICAgICAgICAgaW50IGRlbGltT2Zmc2V0ID0gZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gLSAxOwotICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDE7IGkgPCBkZWxpbUxlbjsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZDdXJyZW50RW50aXR5LnBvc2l0aW9uID09IGZDdXJyZW50RW50aXR5LmNvdW50KSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LnBvc2l0aW9uIC09IGk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrIE9VVEVSOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjID0gZkN1cnJlbnRFbnRpdHkuY2hbZkN1cnJlbnRFbnRpdHkucG9zaXRpb24rK107Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRlbGltaXRlci5jaGFyQXQoaSkgIT0gYykgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5wb3NpdGlvbi0tOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmQ3VycmVudEVudGl0eS5wb3NpdGlvbiA9PSBkZWxpbU9mZnNldCArIGRlbGltTGVuKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGMgPT0gJ1xuJyB8fCBjID09ICdccicgfHwgYyA9PSAweDg1IHx8IGMgPT0gMHgyMDI4KSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5wb3NpdGlvbi0tOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgLy8gSW4gZXh0ZXJuYWwgZW50aXRpZXMgY29udHJvbCBjaGFyYWN0ZXJzIGNhbm5vdCBhcHBlYXIKLSAgICAgICAgICAgICAgICAgICAgLy8gYXMgbGl0ZXJhbHMgc28gZG8gbm90IHNraXAgb3ZlciB0aGVtLgotICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICghWE1MMTFDaGFyLmlzWE1MMTFWYWxpZExpdGVyYWwoYykpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LnBvc2l0aW9uLS07Ci0gICAgICAgICAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gLSBvZmZzZXQ7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5jb2x1bW5OdW1iZXIgKz0gbGVuZ3RoIC0gbmV3bGluZXM7Ci0gICAgICAgICAgICAgICAgICAgICAgICBjaGVja0VudGl0eUxpbWl0KE5hbWVUeXBlLkNPTU1FTlQsIGZDdXJyZW50RW50aXR5LCBvZmZzZXQsIGxlbmd0aCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKGZDdXJyZW50RW50aXR5LmNoLCBvZmZzZXQsIGxlbmd0aCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIE9VVEVSOiB3aGlsZSAoZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gPCBmQ3VycmVudEVudGl0eS5jb3VudCkgewotICAgICAgICAgICAgICAgICAgICBjID0gZkN1cnJlbnRFbnRpdHkuY2hbZkN1cnJlbnRFbnRpdHkucG9zaXRpb24rK107Ci0gICAgICAgICAgICAgICAgICAgIGlmIChjID09IGNoYXJBdDApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGxvb2tzIGxpa2Ugd2UganVzdCBoaXQgdGhlIGRlbGltaXRlcgotICAgICAgICAgICAgICAgICAgICAgICAgaW50IGRlbGltT2Zmc2V0ID0gZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gLSAxOwotICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDE7IGkgPCBkZWxpbUxlbjsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZDdXJyZW50RW50aXR5LnBvc2l0aW9uID09IGZDdXJyZW50RW50aXR5LmNvdW50KSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LnBvc2l0aW9uIC09IGk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrIE9VVEVSOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjID0gZkN1cnJlbnRFbnRpdHkuY2hbZkN1cnJlbnRFbnRpdHkucG9zaXRpb24rK107Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRlbGltaXRlci5jaGFyQXQoaSkgIT0gYykgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5wb3NpdGlvbi0tOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gPT0gZGVsaW1PZmZzZXQgKyBkZWxpbUxlbikgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGMgPT0gJ1xuJykgewotICAgICAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkucG9zaXRpb24tLTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIC8vIENvbnRyb2wgY2hhcmFjdGVycyBhcmUgYWxsb3dlZCB0byBhcHBlYXIgYXMgbGl0ZXJhbHMKLSAgICAgICAgICAgICAgICAgICAgLy8gaW4gaW50ZXJuYWwgZW50aXRpZXMuCi0gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKCFYTUwxMUNoYXIuaXNYTUwxMVZhbGlkKGMpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5wb3NpdGlvbi0tOwotICAgICAgICAgICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGZDdXJyZW50RW50aXR5LnBvc2l0aW9uIC0gb2Zmc2V0OwotICAgICAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkuY29sdW1uTnVtYmVyICs9IGxlbmd0aCAtIG5ld2xpbmVzOwotICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tFbnRpdHlMaW1pdChOYW1lVHlwZS5DT01NRU5ULCBmQ3VycmVudEVudGl0eSwgb2Zmc2V0LCBsZW5ndGgpOwotICAgICAgICAgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZChmQ3VycmVudEVudGl0eS5jaCwgb2Zmc2V0LCBsZW5ndGgpOwotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpbnQgbGVuZ3RoID0gZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gLSBvZmZzZXQ7Ci0gICAgICAgICAgICBmQ3VycmVudEVudGl0eS5jb2x1bW5OdW1iZXIgKz0gbGVuZ3RoIC0gbmV3bGluZXM7Ci0gICAgICAgICAgICBjaGVja0VudGl0eUxpbWl0KE5hbWVUeXBlLkNPTU1FTlQsIGZDdXJyZW50RW50aXR5LCBvZmZzZXQsIGxlbmd0aCk7Ci0gICAgICAgICAgICBpZiAoZG9uZSkgewotICAgICAgICAgICAgICAgIGxlbmd0aCAtPSBkZWxpbUxlbjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoZkN1cnJlbnRFbnRpdHkuY2gsIG9mZnNldCwgbGVuZ3RoKTsKLQotICAgICAgICAgICAgLy8gcmV0dXJuIHRydWUgaWYgc3RyaW5nIHdhcyBza2lwcGVkCi0gICAgICAgIH0gd2hpbGUgKCFkb25lKTsKLSAgICAgICAgcmV0dXJuICFkb25lOwotCi0gICAgfSAvLyBzY2FuRGF0YShTdHJpbmcsWE1MU3RyaW5nKQotCi0gICAgLyoqCi0gICAgICogU2tpcHMgYSBjaGFyYWN0ZXIgYXBwZWFyaW5nIGltbWVkaWF0ZWx5IG9uIHRoZSBpbnB1dC4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoZSBjaGFyYWN0ZXIgaXMgY29uc3VtZWQgb25seSBpZiBpdCBtYXRjaGVzCi0gICAgICogdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXIuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYyBUaGUgY2hhcmFjdGVyIHRvIHNraXAuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFJldHVybnMgdHJ1ZSBpZiB0aGUgY2hhcmFjdGVyIHdhcyBza2lwcGVkLgotICAgICAqCi0gICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiAgVGhyb3duIGlmIGkvbyBlcnJvciBvY2N1cnMuCi0gICAgICogQHRocm93cyBFT0ZFeGNlcHRpb24gVGhyb3duIG9uIGVuZCBvZiBmaWxlLgotICAgICAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIHNraXBDaGFyKGludCBjLCBOYW1lVHlwZSBudCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLQotICAgICAgICAvLyBsb2FkIG1vcmUgY2hhcmFjdGVycywgaWYgbmVlZGVkCi0gICAgICAgIGlmIChmQ3VycmVudEVudGl0eS5wb3NpdGlvbiA9PSBmQ3VycmVudEVudGl0eS5jb3VudCkgewotICAgICAgICAgICAgbG9hZCgwLCB0cnVlLCB0cnVlKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIHNraXAgY2hhcmFjdGVyCi0gICAgICAgIGludCBvZmZzZXQgPSBmQ3VycmVudEVudGl0eS5wb3NpdGlvbjsKLSAgICAgICAgaW50IGNjID0gZkN1cnJlbnRFbnRpdHkuY2hbZkN1cnJlbnRFbnRpdHkucG9zaXRpb25dOwotICAgICAgICBpZiAoY2MgPT0gYykgewotICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkucG9zaXRpb24rKzsKLSAgICAgICAgICAgIGlmIChjID09ICdcbicpIHsKLSAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5saW5lTnVtYmVyKys7Ci0gICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkuY29sdW1uTnVtYmVyID0gMTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LmNvbHVtbk51bWJlcisrOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2hlY2tFbnRpdHlMaW1pdChudCwgZkN1cnJlbnRFbnRpdHksIG9mZnNldCwgZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gLSBvZmZzZXQpOwotICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoYyA9PSAnXG4nICYmICgoY2MgPT0gMHgyMDI4IHx8IGNjID09IDB4ODUpICYmIGZDdXJyZW50RW50aXR5LmlzRXh0ZXJuYWwoKSkpIHsKLSAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LnBvc2l0aW9uKys7Ci0gICAgICAgICAgICBmQ3VycmVudEVudGl0eS5saW5lTnVtYmVyKys7Ci0gICAgICAgICAgICBmQ3VycmVudEVudGl0eS5jb2x1bW5OdW1iZXIgPSAxOwotICAgICAgICAgICAgY2hlY2tFbnRpdHlMaW1pdChudCwgZkN1cnJlbnRFbnRpdHksIG9mZnNldCwgZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gLSBvZmZzZXQpOwotICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoYyA9PSAnXG4nICYmIChjYyA9PSAnXHInICkgJiYgZkN1cnJlbnRFbnRpdHkuaXNFeHRlcm5hbCgpKSB7Ci0gICAgICAgICAgICAvLyBoYW5kbGUgbmV3bGluZXMKLSAgICAgICAgICAgIGlmIChmQ3VycmVudEVudGl0eS5wb3NpdGlvbiA9PSBmQ3VycmVudEVudGl0eS5jb3VudCkgewotICAgICAgICAgICAgICAgIGludm9rZUxpc3RlbmVycygxKTsKLSAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5jaFswXSA9IChjaGFyKWNjOwotICAgICAgICAgICAgICAgIGxvYWQoMSwgZmFsc2UsIGZhbHNlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGludCBjY2MgPSBmQ3VycmVudEVudGl0eS5jaFsrK2ZDdXJyZW50RW50aXR5LnBvc2l0aW9uXTsKLSAgICAgICAgICAgIGlmIChjY2MgPT0gJ1xuJyB8fCBjY2MgPT0gMHg4NSkgewotICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LnBvc2l0aW9uKys7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmQ3VycmVudEVudGl0eS5saW5lTnVtYmVyKys7Ci0gICAgICAgICAgICBmQ3VycmVudEVudGl0eS5jb2x1bW5OdW1iZXIgPSAxOwotICAgICAgICAgICAgY2hlY2tFbnRpdHlMaW1pdChudCwgZkN1cnJlbnRFbnRpdHksIG9mZnNldCwgZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gLSBvZmZzZXQpOwotICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBjaGFyYWN0ZXIgd2FzIG5vdCBza2lwcGVkCi0gICAgICAgIHJldHVybiBmYWxzZTsKLQotICAgIH0gLy8gc2tpcENoYXIoaW50KTpib29sZWFuCi0KLSAgICAvKioKLSAgICAgKiBTa2lwcyBzcGFjZSBjaGFyYWN0ZXJzIGFwcGVhcmluZyBpbW1lZGlhdGVseSBvbiB0aGUgaW5wdXQuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGUgY2hhcmFjdGVycyBhcmUgY29uc3VtZWQgb25seSBpZiB0aGV5IGFyZQotICAgICAqIHNwYWNlIGNoYXJhY3RlcnMuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFJldHVybnMgdHJ1ZSBpZiBhdCBsZWFzdCBvbmUgc3BhY2UgY2hhcmFjdGVyIHdhcyBza2lwcGVkLgotICAgICAqCi0gICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiAgVGhyb3duIGlmIGkvbyBlcnJvciBvY2N1cnMuCi0gICAgICogQHRocm93cyBFT0ZFeGNlcHRpb24gVGhyb3duIG9uIGVuZCBvZiBmaWxlLgotICAgICAqCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuWE1MQ2hhciNpc1NwYWNlCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuWE1MMTFDaGFyI2lzWE1MMTFTcGFjZQotICAgICAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIHNraXBTcGFjZXMoKSB0aHJvd3MgSU9FeGNlcHRpb24gewotCi0gICAgICAgIC8vIGxvYWQgbW9yZSBjaGFyYWN0ZXJzLCBpZiBuZWVkZWQKLSAgICAgICAgaWYgKGZDdXJyZW50RW50aXR5LnBvc2l0aW9uID09IGZDdXJyZW50RW50aXR5LmNvdW50KSB7Ci0gICAgICAgICAgICBsb2FkKDAsIHRydWUsIHRydWUpOwotICAgICAgICB9Ci0KLQotICAgICAgICAvL3dlIGFyZSBkb2luZyB0aGlzIGNoZWNrIG9ubHkgaW4gc2tpcFNwYWNlKCkgYmVjYXVzZSBpdCBpcyBjYWxsZWQgYnkKLSAgICAgICAgLy9mTWlzY0Rpc3BhdGNoZXIgYW5kIHdlIHdhbnQgdGhlIHBhcnNlciB0byBleGl0IGdyYWNlZnVsbHkgd2hlbiBkb2N1bWVudAotICAgICAgICAvL2lzIHdlbGwtZm9ybWVkLgotICAgICAgICAvL2l0IGlzIHBvc3NpYmxlIHRoYXQgZW5kIG9mIGRvY3VtZW50IGlzIHJlYWNoZWQgYW5kCi0gICAgICAgIC8vZkN1cnJlbnRFbnRpdHkgYmVjb21lcyBudWxsCi0gICAgICAgIC8vbm90aGluZyB3YXMgcmVhZCBzbyBlbnRpdHkgY2hhbmdlZCAgJ2ZhbHNlJyBzaG91bGQgYmUgcmV0dXJuZWQuCi0gICAgICAgIGlmKGZDdXJyZW50RW50aXR5ID09IG51bGwpewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlIDsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIHNraXAgc3BhY2VzCi0gICAgICAgIGludCBjID0gZkN1cnJlbnRFbnRpdHkuY2hbZkN1cnJlbnRFbnRpdHkucG9zaXRpb25dOwotICAgICAgICBpbnQgb2Zmc2V0ID0gZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gLSAxOwotICAgICAgICAvLyBFeHRlcm5hbCAtLSAgTWF0Y2g6IFMgKyAweDg1ICsgMHgyMDI4LCBhbmQgcGVyZm9ybSBlbmQgb2YgbGluZSBub3JtYWxpemF0aW9uCi0gICAgICAgIGlmIChmQ3VycmVudEVudGl0eS5pc0V4dGVybmFsKCkpIHsKLSAgICAgICAgICAgIGlmIChYTUwxMUNoYXIuaXNYTUwxMVNwYWNlKGMpKSB7Ci0gICAgICAgICAgICAgICAgZG8gewotICAgICAgICAgICAgICAgICAgICBib29sZWFuIGVudGl0eUNoYW5nZWQgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICAgICAgLy8gaGFuZGxlIG5ld2xpbmVzCi0gICAgICAgICAgICAgICAgICAgIGlmIChjID09ICdcbicgfHwgYyA9PSAnXHInIHx8IGMgPT0gMHg4NSB8fCBjID09IDB4MjAyOCkgewotICAgICAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkubGluZU51bWJlcisrOwotICAgICAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkuY29sdW1uTnVtYmVyID0gMTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmQ3VycmVudEVudGl0eS5wb3NpdGlvbiA9PSBmQ3VycmVudEVudGl0eS5jb3VudCAtIDEpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnZva2VMaXN0ZW5lcnMoMSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkuY2hbMF0gPSAoY2hhciljOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVudGl0eUNoYW5nZWQgPSBsb2FkKDEsIHRydWUsIGZhbHNlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWVudGl0eUNoYW5nZWQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhlIGxvYWQgY2hhbmdlIHRoZSBwb3NpdGlvbiB0byBiZSAxLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBuZWVkIHRvIHJlc3RvcmUgaXQgd2hlbiBlbnRpdHkgbm90IGNoYW5nZWQKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkuc3RhcnRQb3NpdGlvbiA9IDA7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LnBvc2l0aW9uID0gMDsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYoZkN1cnJlbnRFbnRpdHkgPT0gbnVsbCl7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlIDsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjID09ICdccicpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBSRVZJU0lUOiBEb2VzIHRoaXMgbmVlZCB0byBiZSB1cGRhdGVkIHRvIGZpeCB0aGUKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgICAgICAgICAjeDBEIF4jeDBBIG5ld2xpbmUgbm9ybWFsaXphdGlvbiBwcm9ibGVtPyAtQWMKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgY2MgPSBmQ3VycmVudEVudGl0eS5jaFsrK2ZDdXJyZW50RW50aXR5LnBvc2l0aW9uXTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2MgIT0gJ1xuJyAmJiBjYyAhPSAweDg1ICkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5wb3NpdGlvbi0tOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LmNvbHVtbk51bWJlcisrOwotICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgLy9JZiB0aGlzIGlzIGEgZ2VuZXJhbCBlbnRpdHksIHNwYWNlcyB3aXRoaW4gYSBzdGFydCBlbGVtZW50IHNob3VsZCBiZSBjb3VudGVkCi0gICAgICAgICAgICAgICAgICAgIGNoZWNrRW50aXR5TGltaXQobnVsbCwgZkN1cnJlbnRFbnRpdHksIG9mZnNldCwgZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gLSBvZmZzZXQpOwotICAgICAgICAgICAgICAgICAgICBvZmZzZXQgPSBmQ3VycmVudEVudGl0eS5wb3NpdGlvbjsKLQotICAgICAgICAgICAgICAgICAgICAvLyBsb2FkIG1vcmUgY2hhcmFjdGVycywgaWYgbmVlZGVkCi0gICAgICAgICAgICAgICAgICAgIGlmICghZW50aXR5Q2hhbmdlZCkKLSAgICAgICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LnBvc2l0aW9uKys7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChmQ3VycmVudEVudGl0eS5wb3NpdGlvbiA9PSBmQ3VycmVudEVudGl0eS5jb3VudCkgewotICAgICAgICAgICAgICAgICAgICAgICAgbG9hZCgwLCB0cnVlLCB0cnVlKTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgaWYoZkN1cnJlbnRFbnRpdHkgPT0gbnVsbCl7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZSA7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0gd2hpbGUgKFhNTDExQ2hhci5pc1hNTDExU3BhY2UoYyA9IGZDdXJyZW50RW50aXR5LmNoW2ZDdXJyZW50RW50aXR5LnBvc2l0aW9uXSkpOwotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIC8vIEludGVybmFsIC0tIE1hdGNoOiBTIChvbmx5KQotICAgICAgICBlbHNlIGlmIChYTUxDaGFyLmlzU3BhY2UoYykpIHsKLSAgICAgICAgICAgIGRvIHsKLSAgICAgICAgICAgICAgICBib29sZWFuIGVudGl0eUNoYW5nZWQgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICAvLyBoYW5kbGUgbmV3bGluZXMKLSAgICAgICAgICAgICAgICBpZiAoYyA9PSAnXG4nKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LmxpbmVOdW1iZXIrKzsKLSAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkuY29sdW1uTnVtYmVyID0gMTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGZDdXJyZW50RW50aXR5LnBvc2l0aW9uID09IGZDdXJyZW50RW50aXR5LmNvdW50IC0gMSkgewotICAgICAgICAgICAgICAgICAgICAgICAgaW52b2tlTGlzdGVuZXJzKDEpOwotICAgICAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkuY2hbMF0gPSAoY2hhciljOwotICAgICAgICAgICAgICAgICAgICAgICAgZW50aXR5Q2hhbmdlZCA9IGxvYWQoMSwgdHJ1ZSwgZmFsc2UpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFlbnRpdHlDaGFuZ2VkKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhlIGxvYWQgY2hhbmdlIHRoZSBwb3NpdGlvbiB0byBiZSAxLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG5lZWQgdG8gcmVzdG9yZSBpdCB3aGVuIGVudGl0eSBub3QgY2hhbmdlZAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LnN0YXJ0UG9zaXRpb24gPSAwOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LnBvc2l0aW9uID0gMDsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZihmQ3VycmVudEVudGl0eSA9PSBudWxsKXsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlIDsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkuY29sdW1uTnVtYmVyKys7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgLy9JZiB0aGlzIGlzIGEgZ2VuZXJhbCBlbnRpdHksIHNwYWNlcyB3aXRoaW4gYSBzdGFydCBlbGVtZW50IHNob3VsZCBiZSBjb3VudGVkCi0gICAgICAgICAgICAgICAgY2hlY2tFbnRpdHlMaW1pdChudWxsLCBmQ3VycmVudEVudGl0eSwgb2Zmc2V0LCBmQ3VycmVudEVudGl0eS5wb3NpdGlvbiAtIG9mZnNldCk7Ci0gICAgICAgICAgICAgICAgb2Zmc2V0ID0gZkN1cnJlbnRFbnRpdHkucG9zaXRpb247Ci0KLSAgICAgICAgICAgICAgICAvLyBsb2FkIG1vcmUgY2hhcmFjdGVycywgaWYgbmVlZGVkCi0gICAgICAgICAgICAgICAgaWYgKCFlbnRpdHlDaGFuZ2VkKQotICAgICAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5wb3NpdGlvbisrOwotICAgICAgICAgICAgICAgIGlmIChmQ3VycmVudEVudGl0eS5wb3NpdGlvbiA9PSBmQ3VycmVudEVudGl0eS5jb3VudCkgewotICAgICAgICAgICAgICAgICAgICBsb2FkKDAsIHRydWUsIHRydWUpOwotCi0gICAgICAgICAgICAgICAgICAgIGlmKGZDdXJyZW50RW50aXR5ID09IG51bGwpewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWUgOwotICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9IHdoaWxlIChYTUxDaGFyLmlzU3BhY2UoYyA9IGZDdXJyZW50RW50aXR5LmNoW2ZDdXJyZW50RW50aXR5LnBvc2l0aW9uXSkpOwotICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBubyBzcGFjZXMgd2VyZSBmb3VuZAotICAgICAgICByZXR1cm4gZmFsc2U7Ci0KLSAgICB9IC8vIHNraXBTcGFjZXMoKTpib29sZWFuCi0KLSAgICAvKioKLSAgICAgKiBTa2lwcyB0aGUgc3BlY2lmaWVkIHN0cmluZyBhcHBlYXJpbmcgaW1tZWRpYXRlbHkgb24gdGhlIGlucHV0LgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gVGhlIGNoYXJhY3RlcnMgYXJlIGNvbnN1bWVkIG9ubHkgaWYgdGhleSBhcmUKLSAgICAgKiBzcGFjZSBjaGFyYWN0ZXJzLgotICAgICAqCi0gICAgICogQHBhcmFtIHMgVGhlIHN0cmluZyB0byBza2lwLgotICAgICAqCi0gICAgICogQHJldHVybiBSZXR1cm5zIHRydWUgaWYgdGhlIHN0cmluZyB3YXMgc2tpcHBlZC4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gIFRocm93biBpZiBpL28gZXJyb3Igb2NjdXJzLgotICAgICAqIEB0aHJvd3MgRU9GRXhjZXB0aW9uIFRocm93biBvbiBlbmQgb2YgZmlsZS4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBza2lwU3RyaW5nKFN0cmluZyBzKSB0aHJvd3MgSU9FeGNlcHRpb24gewotCi0gICAgICAgIC8vIGxvYWQgbW9yZSBjaGFyYWN0ZXJzLCBpZiBuZWVkZWQKLSAgICAgICAgaWYgKGZDdXJyZW50RW50aXR5LnBvc2l0aW9uID09IGZDdXJyZW50RW50aXR5LmNvdW50KSB7Ci0gICAgICAgICAgICBsb2FkKDAsIHRydWUsIHRydWUpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gc2tpcCBzdHJpbmcKLSAgICAgICAgZmluYWwgaW50IGxlbmd0aCA9IHMubGVuZ3RoKCk7Ci0gICAgICAgIGZpbmFsIGludCBiZWZvcmVTa2lwID0gZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gOwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICBjaGFyIGMgPSBmQ3VycmVudEVudGl0eS5jaFtmQ3VycmVudEVudGl0eS5wb3NpdGlvbisrXTsKLSAgICAgICAgICAgIGlmIChjICE9IHMuY2hhckF0KGkpKSB7Ci0gICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gLT0gaSArIDE7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKGkgPCBsZW5ndGggLSAxICYmIGZDdXJyZW50RW50aXR5LnBvc2l0aW9uID09IGZDdXJyZW50RW50aXR5LmNvdW50KSB7Ci0gICAgICAgICAgICAgICAgaW52b2tlTGlzdGVuZXJzKDApOwotICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZkN1cnJlbnRFbnRpdHkuY2gsIGZDdXJyZW50RW50aXR5LmNvdW50IC0gaSAtIDEsIGZDdXJyZW50RW50aXR5LmNoLCAwLCBpICsgMSk7Ci0gICAgICAgICAgICAgICAgLy8gUkVWSVNJVDogQ2FuIGEgc3RyaW5nIHRvIGJlIHNraXBwZWQgY3Jvc3MgYW4KLSAgICAgICAgICAgICAgICAvLyAgICAgICAgICBlbnRpdHkgYm91bmRhcnk/IC1BYwotICAgICAgICAgICAgICAgIGlmIChsb2FkKGkgKyAxLCBmYWxzZSwgZmFsc2UpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LnN0YXJ0UG9zaXRpb24gLT0gaSArIDE7Ci0gICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LnBvc2l0aW9uIC09IGkgKyAxOwotICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGZDdXJyZW50RW50aXR5LmNvbHVtbk51bWJlciArPSBsZW5ndGg7Ci0gICAgICAgIGlmICghZGV0ZWN0aW5nVmVyc2lvbikgewotICAgICAgICAgICAgY2hlY2tFbnRpdHlMaW1pdChudWxsLCBmQ3VycmVudEVudGl0eSwgYmVmb3JlU2tpcCwgbGVuZ3RoKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gdHJ1ZTsKLQotICAgIH0gLy8gc2tpcFN0cmluZyhTdHJpbmcpOmJvb2xlYW4KLQotfSAvLyBjbGFzcyBYTUwxMUVudGl0eVNjYW5uZXIKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvWE1MMTFOU0RvY3VtZW50U2Nhbm5lckltcGwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvWE1MMTFOU0RvY3VtZW50U2Nhbm5lckltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYWU3ZDdiOC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL1hNTDExTlNEb2N1bWVudFNjYW5uZXJJbXBsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4OTIgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAxNSwgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqLwotCi0vKgotICogQ29weXJpZ2h0IDIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbDsKLQotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHRkLlhNTERURFZhbGlkYXRvckZpbHRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwubXNnLlhNTE1lc3NhZ2VGb3JtYXR0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlhNTEF0dHJpYnV0ZXNJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5YTUxTeW1ib2xzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbHMuWE1MU2VjdXJpdHlNYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLk5hbWVzcGFjZUNvbnRleHQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuUU5hbWU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MRG9jdW1lbnRIYW5kbGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhOSUV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MQ29tcG9uZW50TWFuYWdlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MRG9jdW1lbnRTb3VyY2U7Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5ldmVudHMuWE1MRXZlbnQ7Ci0KLQotLyoqCi0gKiBUaGUgc2Nhbm5lciBhY3RzIGFzIHRoZSBzb3VyY2UgZm9yIHRoZSBkb2N1bWVudAotICogaW5mb3JtYXRpb24gd2hpY2ggaXMgY29tbXVuaWNhdGVkIHRvIHRoZSBkb2N1bWVudCBoYW5kbGVyLgotICoKLSAqIFRoaXMgY2xhc3Mgc2NhbnMgYW4gWE1MIGRvY3VtZW50LCBjaGVja3MgaWYgZG9jdW1lbnQgaGFzIGEgRFRELCBhbmQgaWYKLSAqIERURCBpcyBub3QgZm91bmQgdGhlIHNjYW5uZXIgd2lsbCByZW1vdmUgdGhlIERURCBWYWxpZGF0b3IgZnJvbSB0aGUgcGlwZWxpbmUgYW5kIHBlcmZvcm0KLSAqIG5hbWVzcGFjZSBiaW5kaW5nLgotICoKLSAqIE5vdGU6IFRoaXMgc2Nhbm5lciBzaG91bGQgb25seSBiZSB1c2VkIHdoZW4gdGhlIG5hbWVzcGFjZSBwcm9jZXNzaW5nIGlzIG9uIQotICoKLSAqIDxwPgotICogVGhpcyBjb21wb25lbnQgcmVxdWlyZXMgdGhlIGZvbGxvd2luZyBmZWF0dXJlcyBhbmQgcHJvcGVydGllcyBmcm9tIHRoZQotICogY29tcG9uZW50IG1hbmFnZXIgdGhhdCB1c2VzIGl0OgotICogPHVsPgotICogIDxsaT5odHRwOi8veG1sLm9yZy9zYXgvZmVhdHVyZXMvbmFtZXNwYWNlcyB7dHJ1ZX0gLS0gaWYgdGhlIHZhbHVlIG9mIHRoaXMKLSAqICAgICAgZmVhdHVyZSBpcyBzZXQgdG8gZmFsc2UgdGhpcyBzY2FubmVyIG11c3Qgbm90IGJlIHVzZWQuPC9saT4KLSAqICA8bGk+aHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL3ZhbGlkYXRpb248L2xpPgotICogIDxsaT5odHRwOi8vYXBhY2hlLm9yZy94bWwvZmVhdHVyZXMvbm9udmFsaWRhdGluZy9sb2FkLWV4dGVybmFsLWR0ZDwvbGk+Ci0gKiAgPGxpPmh0dHA6Ly9hcGFjaGUub3JnL3htbC9mZWF0dXJlcy9zY2FubmVyL25vdGlmeS1jaGFyLXJlZnM8L2xpPgotICogIDxsaT5odHRwOi8vYXBhY2hlLm9yZy94bWwvZmVhdHVyZXMvc2Nhbm5lci9ub3RpZnktYnVpbHRpbi1yZWZzPC9saT4KLSAqICA8bGk+aHR0cDovL2FwYWNoZS5vcmcveG1sL3Byb3BlcnRpZXMvaW50ZXJuYWwvc3ltYm9sLXRhYmxlPC9saT4KLSAqICA8bGk+aHR0cDovL2FwYWNoZS5vcmcveG1sL3Byb3BlcnRpZXMvaW50ZXJuYWwvZXJyb3ItcmVwb3J0ZXI8L2xpPgotICogIDxsaT5odHRwOi8vYXBhY2hlLm9yZy94bWwvcHJvcGVydGllcy9pbnRlcm5hbC9lbnRpdHktbWFuYWdlcjwvbGk+Ci0gKiAgPGxpPmh0dHA6Ly9hcGFjaGUub3JnL3htbC9wcm9wZXJ0aWVzL2ludGVybmFsL2R0ZC1zY2FubmVyPC9saT4KLSAqIDwvdWw+Ci0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgRWxlbmEgTGl0YW5pLCBJQk0KLSAqIEBhdXRob3IgTWljaGFlbCBHbGF2YXNzZXZpY2gsIElCTQotICogQGF1dGhvciBTdW5pdGhhIFJlZGR5LCBTdW4gTWljcm9zeXN0ZW1zCi0gKiBAdmVyc2lvbiAkSWQ6IFhNTDExTlNEb2N1bWVudFNjYW5uZXJJbXBsLmphdmEsdiAxLjYgMjAxMC0xMS0wMSAwNDozOTo0MCBqb2VodyBFeHAgJAotICovCi1wdWJsaWMgY2xhc3MgWE1MMTFOU0RvY3VtZW50U2Nhbm5lckltcGwgZXh0ZW5kcyBYTUwxMURvY3VtZW50U2Nhbm5lckltcGwgewotCi0gICAgLyoqCi0gICAgICogSWYgaXMgdHJ1ZSwgdGhlIGR0ZCB2YWxpZGF0b3IgaXMgbm8gbG9uZ2VyIGluIHRoZSBwaXBlbGluZQotICAgICAqIGFuZCB0aGUgc2Nhbm5lciBzaG91bGQgYmluZCBuYW1lc3BhY2VzCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZkJpbmROYW1lc3BhY2VzOwotCi0gICAgLyoqCi0gICAgICogSWYgdmFsaWRhdGluZyBwYXJzZXIsIG1ha2Ugc3VyZSB3ZSByZXBvcnQgYW4gZXJyb3IgaW4gdGhlCi0gICAgICogIHNjYW5uZXIgaWYgRFREIGdyYW1tYXIgaXMgbWlzc2luZy4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBmUGVyZm9ybVZhbGlkYXRpb247Ci0KLSAgICAvLyBwcml2YXRlIGRhdGEKLSAgICAvLwotCi0gICAgLyoqIERURCB2YWxpZGF0b3IgKi8KLSAgICBwcml2YXRlIFhNTERURFZhbGlkYXRvckZpbHRlciBmRFREVmFsaWRhdG9yOwotCi0gICAgLyoqCi0gICAgICogU2F3IHNwYWNlcyBhZnRlciBlbGVtZW50IG5hbWUgb3IgYmV0d2VlbiBhdHRyaWJ1dGVzLgotICAgICAqCi0gICAgICogVGhpcyBpcyByZXNlcnZlZCBmb3IgdGhlIGNhc2Ugd2hlcmUgc2Nhbm5pbmcgb2YgYSBzdGFydCBlbGVtZW50IHNwYW5zCi0gICAgICogc2V2ZXJhbCBtZXRob2RzLCBhcyBpcyB0aGUgY2FzZSB3aGVuIHNjYW5uaW5nIHRoZSBzdGFydCBvZiBhIHJvb3QgZWxlbWVudAotICAgICAqIHdoZXJlIGEgRFREIGV4dGVybmFsIHN1YnNldCBtYXkgYmUgcmVhZCBhZnRlciBzY2FubmluZyB0aGUgZWxlbWVudCBuYW1lLgotICAgICAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBmU2F3U3BhY2U7Ci0KLQotICAgIC8qKgotICAgICAqIFRoZSBzY2FubmVyIGlzIHJlc3BvbnNpYmxlIGZvciByZW1vdmluZyBEVEQgdmFsaWRhdG9yCi0gICAgICogZnJvbSB0aGUgcGlwZWxpbmUgaWYgaXQgaXMgbm90IG5lZWRlZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSB2YWxpZGF0b3IgdGhlIERURCB2YWxpZGF0b3IgZnJvbSB0aGUgcGlwZWxpbmUKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXREVERWYWxpZGF0b3IoWE1MRFREVmFsaWRhdG9yRmlsdGVyIHZhbGlkYXRvcikgewotICAgICAgICBmRFREVmFsaWRhdG9yID0gdmFsaWRhdG9yOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNjYW5zIGEgc3RhcnQgZWxlbWVudC4gVGhpcyBtZXRob2Qgd2lsbCBoYW5kbGUgdGhlIGJpbmRpbmcgb2YKLSAgICAgKiBuYW1lc3BhY2UgaW5mb3JtYXRpb24gYW5kIG5vdGlmeWluZyB0aGUgaGFuZGxlciBvZiB0aGUgc3RhcnQKLSAgICAgKiBvZiB0aGUgZWxlbWVudC4KLSAgICAgKiA8cD4KLSAgICAgKiA8cHJlPgotICAgICAqIFs0NF0gRW1wdHlFbGVtVGFnIDo6PSAnJmx0OycgTmFtZSAoUyBBdHRyaWJ1dGUpKiBTPyAnLz4nCi0gICAgICogWzQwXSBTVGFnIDo6PSAnJmx0OycgTmFtZSAoUyBBdHRyaWJ1dGUpKiBTPyAnPicKLSAgICAgKiA8L3ByZT4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoaXMgbWV0aG9kIGFzc3VtZXMgdGhhdCB0aGUgbGVhZGluZwotICAgICAqICcmbHQ7JyBjaGFyYWN0ZXIgaGFzIGJlZW4gY29uc3VtZWQuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGlzIG1ldGhvZCB1c2VzIHRoZSBmRWxlbWVudFFOYW1lIGFuZAotICAgICAqIGZBdHRyaWJ1dGVzIHZhcmlhYmxlcy4gVGhlIGNvbnRlbnRzIG9mIHRoZXNlIHZhcmlhYmxlcyB3aWxsIGJlCi0gICAgICogZGVzdHJveWVkLiBUaGUgY2FsbGVyIHNob3VsZCBjb3B5IGltcG9ydGFudCBpbmZvcm1hdGlvbiBvdXQgb2YKLSAgICAgKiB0aGVzZSB2YXJpYWJsZXMgYmVmb3JlIGNhbGxpbmcgdGhpcyBtZXRob2QuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRydWUgaWYgZWxlbWVudCBpcyBlbXB0eS4gKGkuZS4gSXQgbWF0Y2hlcwotICAgICAqICAgICAgICAgIHByb2R1Y3Rpb24gWzQ0XS4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBzY2FuU3RhcnRFbGVtZW50KCkgdGhyb3dzIElPRXhjZXB0aW9uLCBYTklFeGNlcHRpb24gewotCi0gICAgICAgIGlmIChERUJVR19TVEFSVF9FTkRfRUxFTUVOVCkKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiPj4+IHNjYW5TdGFydEVsZW1lbnROUygpIik7Ci0gICAgICAgICAgICAgICAgLy8gTm90ZTogbmFtZXNwYWNlIHByb2Nlc3NpbmcgaXMgb24gYnkgZGVmYXVsdAotICAgICAgICBmRW50aXR5U2Nhbm5lci5zY2FuUU5hbWUoZkVsZW1lbnRRTmFtZSwgTmFtZVR5cGUuQVRUUklCVVRFKTsKLSAgICAgICAgLy8gUkVWSVNJVCAtIFtRXSBXaHkgZG8gd2UgbmVlZCB0aGlzIGxvY2FsIHZhcmlhYmxlPyAtLSBtcmdsYXZhcwotICAgICAgICBTdHJpbmcgcmF3bmFtZSA9IGZFbGVtZW50UU5hbWUucmF3bmFtZTsKLSAgICAgICAgaWYgKGZCaW5kTmFtZXNwYWNlcykgewotICAgICAgICAgICAgZk5hbWVzcGFjZUNvbnRleHQucHVzaENvbnRleHQoKTsKLSAgICAgICAgICAgIGlmIChmU2Nhbm5lclN0YXRlID09IFNDQU5ORVJfU1RBVEVfUk9PVF9FTEVNRU5UKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGZQZXJmb3JtVmFsaWRhdGlvbikgewotICAgICAgICAgICAgICAgICAgICBmRXJyb3JSZXBvcnRlci5yZXBvcnRFcnJvcigKLSAgICAgICAgICAgICAgICAgICAgICAgIFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICJNU0dfR1JBTU1BUl9OT1RfRk9VTkQiLAotICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgcmF3bmFtZSB9LAotICAgICAgICAgICAgICAgICAgICAgICAgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9FUlJPUik7Ci0KLSAgICAgICAgICAgICAgICAgICAgaWYgKGZEb2N0eXBlTmFtZSA9PSBudWxsCi0gICAgICAgICAgICAgICAgICAgICAgICB8fCAhZkRvY3R5cGVOYW1lLmVxdWFscyhyYXduYW1lKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICJSb290RWxlbWVudFR5cGVNdXN0TWF0Y2hEb2N0eXBlZGVjbCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgZkRvY3R5cGVOYW1lLCByYXduYW1lIH0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9FUlJPUik7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBwdXNoIGVsZW1lbnQgc3RhY2sKLSAgICAgICAgZkN1cnJlbnRFbGVtZW50ID0gZkVsZW1lbnRTdGFjay5wdXNoRWxlbWVudChmRWxlbWVudFFOYW1lKTsKLQotICAgICAgICAvLyBhdHRyaWJ1dGVzCi0gICAgICAgIGJvb2xlYW4gZW1wdHkgPSBmYWxzZTsKLSAgICAgICAgZkF0dHJpYnV0ZXMucmVtb3ZlQWxsQXR0cmlidXRlcygpOwotICAgICAgICBkbyB7Ci0gICAgICAgICAgICAvLyBzcGFjZXMKLSAgICAgICAgICAgIGJvb2xlYW4gc2F3U3BhY2UgPSBmRW50aXR5U2Nhbm5lci5za2lwU3BhY2VzKCk7Ci0KLSAgICAgICAgICAgIC8vIGVuZCB0YWc/Ci0gICAgICAgICAgICBpbnQgYyA9IGZFbnRpdHlTY2FubmVyLnBlZWtDaGFyKCk7Ci0gICAgICAgICAgICBpZiAoYyA9PSAnPicpIHsKLSAgICAgICAgICAgICAgICBmRW50aXR5U2Nhbm5lci5zY2FuQ2hhcihudWxsKTsKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0gZWxzZSBpZiAoYyA9PSAnLycpIHsKLSAgICAgICAgICAgICAgICBmRW50aXR5U2Nhbm5lci5zY2FuQ2hhcihudWxsKTsKLSAgICAgICAgICAgICAgICBpZiAoIWZFbnRpdHlTY2FubmVyLnNraXBDaGFyKCc+JywgbnVsbCkpIHsKLSAgICAgICAgICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigKLSAgICAgICAgICAgICAgICAgICAgICAgICJFbGVtZW50VW50ZXJtaW5hdGVkIiwKLSAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7IHJhd25hbWUgfSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVtcHR5ID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0gZWxzZSBpZiAoIWlzVmFsaWROYW1lU3RhcnRDaGFyKGMpIHx8ICFzYXdTcGFjZSkgewotICAgICAgICAgICAgICAgIC8vIFNlY29uZCBjaGFuY2UuIENoZWNrIGlmIHRoaXMgY2hhcmFjdGVyIGlzIGEgaGlnaAotICAgICAgICAgICAgICAgIC8vIHN1cnJvZ2F0ZSBvZiBhIHZhbGlkIG5hbWUgc3RhcnQgY2hhcmFjdGVyLgotICAgICAgICAgICAgICAgIGlmICghaXNWYWxpZE5hbWVTdGFydEhpZ2hTdXJyb2dhdGUoYykgfHwgIXNhd1NwYWNlKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoCi0gICAgICAgICAgICAgICAgICAgICAgICAiRWxlbWVudFVudGVybWluYXRlZCIsCi0gICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyByYXduYW1lIH0pOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gYXR0cmlidXRlcwotICAgICAgICAgICAgc2NhbkF0dHJpYnV0ZShmQXR0cmlidXRlcyk7Ci0gICAgICAgICAgICBpZiAoZlNlY3VyaXR5TWFuYWdlciAhPSBudWxsICYmICghZlNlY3VyaXR5TWFuYWdlci5pc05vTGltaXQoZkVsZW1lbnRBdHRyaWJ1dGVMaW1pdCkpICYmCi0gICAgICAgICAgICAgICAgICAgIGZBdHRyaWJ1dGVzLmdldExlbmd0aCgpID4gZkVsZW1lbnRBdHRyaWJ1dGVMaW1pdCl7Ci0gICAgICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkVsZW1lbnRBdHRyaWJ1dGVMaW1pdCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117cmF3bmFtZSwgbmV3IEludGVnZXIoZkVsZW1lbnRBdHRyaWJ1dGVMaW1pdCkgfSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTEVycm9yUmVwb3J0ZXIuU0VWRVJJVFlfRkFUQUxfRVJST1IgKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICB9IHdoaWxlICh0cnVlKTsKLQotICAgICAgICBpZiAoZkJpbmROYW1lc3BhY2VzKSB7Ci0gICAgICAgICAgICAvLyBSRVZJU0lUOiBpcyBpdCByZXF1aXJlZD8gZm9yYml0IHhtbG5zIHByZWZpeCBmb3IgZWxlbWVudAotICAgICAgICAgICAgaWYgKGZFbGVtZW50UU5hbWUucHJlZml4ID09IFhNTFN5bWJvbHMuUFJFRklYX1hNTE5TKSB7Ci0gICAgICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IoCi0gICAgICAgICAgICAgICAgICAgIFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MTlNfRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAiRWxlbWVudFhNTE5TUHJlZml4IiwKLSAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgZkVsZW1lbnRRTmFtZS5yYXduYW1lIH0sCi0gICAgICAgICAgICAgICAgICAgIFhNTEVycm9yUmVwb3J0ZXIuU0VWRVJJVFlfRkFUQUxfRVJST1IpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBiaW5kIHRoZSBlbGVtZW50Ci0gICAgICAgICAgICBTdHJpbmcgcHJlZml4ID0KLSAgICAgICAgICAgICAgICBmRWxlbWVudFFOYW1lLnByZWZpeCAhPSBudWxsCi0gICAgICAgICAgICAgICAgICAgID8gZkVsZW1lbnRRTmFtZS5wcmVmaXgKLSAgICAgICAgICAgICAgICAgICAgOiBYTUxTeW1ib2xzLkVNUFRZX1NUUklORzsKLSAgICAgICAgICAgIC8vIGFzc2lnbiB1cmkgdG8gdGhlIGVsZW1lbnQKLSAgICAgICAgICAgIGZFbGVtZW50UU5hbWUudXJpID0gZk5hbWVzcGFjZUNvbnRleHQuZ2V0VVJJKHByZWZpeCk7Ci0gICAgICAgICAgICAvLyBtYWtlIHN1cmUgdGhhdCBvYmplY3QgaW4gdGhlIGVsZW1lbnQgc3RhY2sgaXMgdXBkYXRlZCBhcyB3ZWxsCi0gICAgICAgICAgICBmQ3VycmVudEVsZW1lbnQudXJpID0gZkVsZW1lbnRRTmFtZS51cmk7Ci0KLSAgICAgICAgICAgIGlmIChmRWxlbWVudFFOYW1lLnByZWZpeCA9PSBudWxsICYmIGZFbGVtZW50UU5hbWUudXJpICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmRWxlbWVudFFOYW1lLnByZWZpeCA9IFhNTFN5bWJvbHMuRU1QVFlfU1RSSU5HOwotICAgICAgICAgICAgICAgIC8vIG1ha2luZyBzdXJlIHRoYXQgdGhlIG9iamVjdCBpbiB0aGUgZWxlbWVudCBzdGFjayBpcyB1cGRhdGVkIHRvby4KLSAgICAgICAgICAgICAgICBmQ3VycmVudEVsZW1lbnQucHJlZml4ID0gWE1MU3ltYm9scy5FTVBUWV9TVFJJTkc7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoZkVsZW1lbnRRTmFtZS5wcmVmaXggIT0gbnVsbCAmJiBmRWxlbWVudFFOYW1lLnVyaSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IoCi0gICAgICAgICAgICAgICAgICAgIFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MTlNfRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAiRWxlbWVudFByZWZpeFVuYm91bmQiLAotICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10gewotICAgICAgICAgICAgICAgICAgICAgICAgZkVsZW1lbnRRTmFtZS5wcmVmaXgsCi0gICAgICAgICAgICAgICAgICAgICAgICBmRWxlbWVudFFOYW1lLnJhd25hbWUgfSwKLSAgICAgICAgICAgICAgICAgICAgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9GQVRBTF9FUlJPUik7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIGJpbmQgYXR0cmlidXRlcyAoeG1sbnMgYXJlIGFscmVhZHkgYm91bmQgYmVsbG93KQotICAgICAgICAgICAgaW50IGxlbmd0aCA9IGZBdHRyaWJ1dGVzLmdldExlbmd0aCgpOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykgewotICAgICAgICAgICAgICAgIGZBdHRyaWJ1dGVzLmdldE5hbWUoaSwgZkF0dHJpYnV0ZVFOYW1lKTsKLQotICAgICAgICAgICAgICAgIFN0cmluZyBhcHJlZml4ID0KLSAgICAgICAgICAgICAgICAgICAgZkF0dHJpYnV0ZVFOYW1lLnByZWZpeCAhPSBudWxsCi0gICAgICAgICAgICAgICAgICAgICAgICA/IGZBdHRyaWJ1dGVRTmFtZS5wcmVmaXgKLSAgICAgICAgICAgICAgICAgICAgICAgIDogWE1MU3ltYm9scy5FTVBUWV9TVFJJTkc7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIHVyaSA9IGZOYW1lc3BhY2VDb250ZXh0LmdldFVSSShhcHJlZml4KTsKLSAgICAgICAgICAgICAgICAvLyBSRVZJU0lUOiB0cnkgcmVtb3ZpbmcgdGhlIGZpcnN0ICJpZiIgYW5kIHNlZSBpZiBpdCBpcyBmYXN0ZXIuCi0gICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICBpZiAoZkF0dHJpYnV0ZVFOYW1lLnVyaSAhPSBudWxsCi0gICAgICAgICAgICAgICAgICAgICYmIGZBdHRyaWJ1dGVRTmFtZS51cmkgPT0gdXJpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpZiAoYXByZWZpeCAhPSBYTUxTeW1ib2xzLkVNUFRZX1NUUklORykgewotICAgICAgICAgICAgICAgICAgICBmQXR0cmlidXRlUU5hbWUudXJpID0gdXJpOwotICAgICAgICAgICAgICAgICAgICBpZiAodXJpID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MTlNfRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBdHRyaWJ1dGVQcmVmaXhVbmJvdW5kIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10gewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmRWxlbWVudFFOYW1lLnJhd25hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZBdHRyaWJ1dGVRTmFtZS5yYXduYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcHJlZml4IH0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9GQVRBTF9FUlJPUik7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZkF0dHJpYnV0ZXMuc2V0VVJJKGksIHVyaSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAobGVuZ3RoID4gMSkgewotICAgICAgICAgICAgICAgIFFOYW1lIG5hbWUgPSBmQXR0cmlidXRlcy5jaGVja0R1cGxpY2F0ZXNOUygpOwotICAgICAgICAgICAgICAgIGlmIChuYW1lICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKG5hbWUudXJpICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MTlNfRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBdHRyaWJ1dGVOU05vdFVuaXF1ZSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkVsZW1lbnRRTmFtZS5yYXduYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lLmxvY2FscGFydCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZS51cmkgfSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxFcnJvclJlcG9ydGVyLlNFVkVSSVRZX0ZBVEFMX0VSUk9SKTsKLSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MTlNfRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBdHRyaWJ1dGVOb3RVbmlxdWUiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZFbGVtZW50UU5hbWUucmF3bmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZS5yYXduYW1lIH0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9GQVRBTF9FUlJPUik7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBjYWxsIGhhbmRsZXIKLSAgICAgICAgaWYgKGVtcHR5KSB7Ci0gICAgICAgICAgICAvL2RlY3JlYXNlIHRoZSBtYXJrdXAgZGVwdGguLgotICAgICAgICAgICAgZk1hcmt1cERlcHRoLS07Ci0KLSAgICAgICAgICAgIC8vIGNoZWNrIHRoYXQgdGhpcyBlbGVtZW50IHdhcyBvcGVuZWQgaW4gdGhlIHNhbWUgZW50aXR5Ci0gICAgICAgICAgICBpZiAoZk1hcmt1cERlcHRoIDwgZkVudGl0eVN0YWNrW2ZFbnRpdHlEZXB0aCAtIDFdKSB7Ci0gICAgICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigKLSAgICAgICAgICAgICAgICAgICAgIkVsZW1lbnRFbnRpdHlNaXNtYXRjaCIsCi0gICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7IGZDdXJyZW50RWxlbWVudC5yYXduYW1lIH0pOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAoZkRvY3VtZW50SGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci5lbXB0eUVsZW1lbnQoZkVsZW1lbnRRTmFtZSwgZkF0dHJpYnV0ZXMsIG51bGwpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvKmlmIChmQmluZE5hbWVzcGFjZXMpIHsKLSAgICAgICAgICAgICAgICBmTmFtZXNwYWNlQ29udGV4dC5wb3BDb250ZXh0KCk7Ci0gICAgICAgICAgICB9Ki8KLSAgICAgICAgICAgIGZTY2FuRW5kRWxlbWVudCA9IHRydWU7Ci0KLSAgICAgICAgICAgIC8vcG9wIHRoZSBlbGVtZW50IG9mZiB0aGUgc3RhY2suLgotICAgICAgICAgICAgZkVsZW1lbnRTdGFjay5wb3BFbGVtZW50KCk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBpZihkdGRHcmFtbWFyVXRpbCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZHRkR3JhbW1hclV0aWwuc3RhcnRFbGVtZW50KGZFbGVtZW50UU5hbWUsIGZBdHRyaWJ1dGVzKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKGZEb2N1bWVudEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZEb2N1bWVudEhhbmRsZXIuc3RhcnRFbGVtZW50KGZFbGVtZW50UU5hbWUsIGZBdHRyaWJ1dGVzLCBudWxsKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGlmIChERUJVR19TVEFSVF9FTkRfRUxFTUVOVCkKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiPDw8IHNjYW5TdGFydEVsZW1lbnQoKTogIiArIGVtcHR5KTsKLSAgICAgICAgcmV0dXJuIGVtcHR5OwotCi0gICAgfSAvLyBzY2FuU3RhcnRFbGVtZW50KCk6Ym9vbGVhbgotCi0gICAgLyoqCi0gICAgICogU2NhbnMgdGhlIG5hbWUgb2YgYW4gZWxlbWVudCBpbiBhIHN0YXJ0IG9yIGVtcHR5IHRhZy4KLSAgICAgKgotICAgICAqIEBzZWUgI3NjYW5TdGFydEVsZW1lbnQoKQotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIHNjYW5TdGFydEVsZW1lbnROYW1lICgpCi0gICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgLy8gTm90ZTogbmFtZXNwYWNlIHByb2Nlc3NpbmcgaXMgb24gYnkgZGVmYXVsdAotICAgICAgICBmRW50aXR5U2Nhbm5lci5zY2FuUU5hbWUoZkVsZW1lbnRRTmFtZSwgTmFtZVR5cGUuQVRUUklCVVRFKTsKLSAgICAgICAgLy8gTXVzdCBza2lwIHNwYWNlcyBoZXJlIGJlY2F1c2UgdGhlIERURCBzY2FubmVyCi0gICAgICAgIC8vIHdvdWxkIGNvbnN1bWUgdGhlbSBhdCB0aGUgZW5kIG9mIHRoZSBleHRlcm5hbCBzdWJzZXQuCi0gICAgICAgIGZTYXdTcGFjZSA9IGZFbnRpdHlTY2FubmVyLnNraXBTcGFjZXMoKTsKLSAgICB9IC8vIHNjYW5TdGFydEVsZW1lbnROYW1lKCkKLQotICAgIC8qKgotICAgICAqIFNjYW5zIHRoZSByZW1haW5kZXIgb2YgYSBzdGFydCBvciBlbXB0eSB0YWcgYWZ0ZXIgdGhlIGVsZW1lbnQgbmFtZS4KLSAgICAgKgotICAgICAqIEBzZWUgI3NjYW5TdGFydEVsZW1lbnQKLSAgICAgKiBAcmV0dXJuIFRydWUgaWYgZWxlbWVudCBpcyBlbXB0eS4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBzY2FuU3RhcnRFbGVtZW50QWZ0ZXJOYW1lKCkKLSAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBYTklFeGNlcHRpb24gewotCi0gICAgICAgIC8vIFJFVklTSVQgLSBbUV0gV2h5IGRvIHdlIG5lZWQgdGhpcyBsb2NhbCB2YXJpYWJsZT8gLS0gbXJnbGF2YXMKLSAgICAgICAgU3RyaW5nIHJhd25hbWUgPSBmRWxlbWVudFFOYW1lLnJhd25hbWU7Ci0gICAgICAgIGlmIChmQmluZE5hbWVzcGFjZXMpIHsKLSAgICAgICAgICAgIGZOYW1lc3BhY2VDb250ZXh0LnB1c2hDb250ZXh0KCk7Ci0gICAgICAgICAgICBpZiAoZlNjYW5uZXJTdGF0ZSA9PSBTQ0FOTkVSX1NUQVRFX1JPT1RfRUxFTUVOVCkgewotICAgICAgICAgICAgICAgIGlmIChmUGVyZm9ybVZhbGlkYXRpb24pIHsKLSAgICAgICAgICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IoCi0gICAgICAgICAgICAgICAgICAgICAgICBYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAiTVNHX0dSQU1NQVJfTk9UX0ZPVU5EIiwKLSAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7IHJhd25hbWUgfSwKLSAgICAgICAgICAgICAgICAgICAgICAgIFhNTEVycm9yUmVwb3J0ZXIuU0VWRVJJVFlfRVJST1IpOwotCi0gICAgICAgICAgICAgICAgICAgIGlmIChmRG9jdHlwZU5hbWUgPT0gbnVsbAotICAgICAgICAgICAgICAgICAgICAgICAgfHwgIWZEb2N0eXBlTmFtZS5lcXVhbHMocmF3bmFtZSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUm9vdEVsZW1lbnRUeXBlTXVzdE1hdGNoRG9jdHlwZWRlY2wiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7IGZEb2N0eXBlTmFtZSwgcmF3bmFtZSB9LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTEVycm9yUmVwb3J0ZXIuU0VWRVJJVFlfRVJST1IpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gcHVzaCBlbGVtZW50IHN0YWNrCi0gICAgICAgIGZDdXJyZW50RWxlbWVudCA9IGZFbGVtZW50U3RhY2sucHVzaEVsZW1lbnQoZkVsZW1lbnRRTmFtZSk7Ci0KLSAgICAgICAgLy8gYXR0cmlidXRlcwotICAgICAgICBib29sZWFuIGVtcHR5ID0gZmFsc2U7Ci0gICAgICAgIGZBdHRyaWJ1dGVzLnJlbW92ZUFsbEF0dHJpYnV0ZXMoKTsKLSAgICAgICAgZG8gewotCi0gICAgICAgICAgICAvLyBlbmQgdGFnPwotICAgICAgICAgICAgaW50IGMgPSBmRW50aXR5U2Nhbm5lci5wZWVrQ2hhcigpOwotICAgICAgICAgICAgaWYgKGMgPT0gJz4nKSB7Ci0gICAgICAgICAgICAgICAgZkVudGl0eVNjYW5uZXIuc2NhbkNoYXIobnVsbCk7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9IGVsc2UgaWYgKGMgPT0gJy8nKSB7Ci0gICAgICAgICAgICAgICAgZkVudGl0eVNjYW5uZXIuc2NhbkNoYXIobnVsbCk7Ci0gICAgICAgICAgICAgICAgaWYgKCFmRW50aXR5U2Nhbm5lci5za2lwQ2hhcignPicsIG51bGwpKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoCi0gICAgICAgICAgICAgICAgICAgICAgICAiRWxlbWVudFVudGVybWluYXRlZCIsCi0gICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyByYXduYW1lIH0pOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbXB0eSA9IHRydWU7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9IGVsc2UgaWYgKCFpc1ZhbGlkTmFtZVN0YXJ0Q2hhcihjKSB8fCAhZlNhd1NwYWNlKSB7Ci0gICAgICAgICAgICAgICAgLy8gU2Vjb25kIGNoYW5jZS4gQ2hlY2sgaWYgdGhpcyBjaGFyYWN0ZXIgaXMgYSBoaWdoCi0gICAgICAgICAgICAgICAgLy8gc3Vycm9nYXRlIG9mIGEgdmFsaWQgbmFtZSBzdGFydCBjaGFyYWN0ZXIuCi0gICAgICAgICAgICAgICAgaWYgKCFpc1ZhbGlkTmFtZVN0YXJ0SGlnaFN1cnJvZ2F0ZShjKSB8fCAhZlNhd1NwYWNlKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoCi0gICAgICAgICAgICAgICAgICAgICAgICAiRWxlbWVudFVudGVybWluYXRlZCIsCi0gICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyByYXduYW1lIH0pOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gYXR0cmlidXRlcwotICAgICAgICAgICAgc2NhbkF0dHJpYnV0ZShmQXR0cmlidXRlcyk7Ci0KLSAgICAgICAgICAgIC8vIHNwYWNlcwotICAgICAgICAgICAgZlNhd1NwYWNlID0gZkVudGl0eVNjYW5uZXIuc2tpcFNwYWNlcygpOwotCi0gICAgICAgIH0gd2hpbGUgKHRydWUpOwotCi0gICAgICAgIGlmIChmQmluZE5hbWVzcGFjZXMpIHsKLSAgICAgICAgICAgIC8vIFJFVklTSVQ6IGlzIGl0IHJlcXVpcmVkPyBmb3JiaXQgeG1sbnMgcHJlZml4IGZvciBlbGVtZW50Ci0gICAgICAgICAgICBpZiAoZkVsZW1lbnRRTmFtZS5wcmVmaXggPT0gWE1MU3ltYm9scy5QUkVGSVhfWE1MTlMpIHsKLSAgICAgICAgICAgICAgICBmRXJyb3JSZXBvcnRlci5yZXBvcnRFcnJvcigKLSAgICAgICAgICAgICAgICAgICAgWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxOU19ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICJFbGVtZW50WE1MTlNQcmVmaXgiLAotICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBmRWxlbWVudFFOYW1lLnJhd25hbWUgfSwKLSAgICAgICAgICAgICAgICAgICAgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9GQVRBTF9FUlJPUik7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIGJpbmQgdGhlIGVsZW1lbnQKLSAgICAgICAgICAgIFN0cmluZyBwcmVmaXggPQotICAgICAgICAgICAgICAgIGZFbGVtZW50UU5hbWUucHJlZml4ICE9IG51bGwKLSAgICAgICAgICAgICAgICAgICAgPyBmRWxlbWVudFFOYW1lLnByZWZpeAotICAgICAgICAgICAgICAgICAgICA6IFhNTFN5bWJvbHMuRU1QVFlfU1RSSU5HOwotICAgICAgICAgICAgLy8gYXNzaWduIHVyaSB0byB0aGUgZWxlbWVudAotICAgICAgICAgICAgZkVsZW1lbnRRTmFtZS51cmkgPSBmTmFtZXNwYWNlQ29udGV4dC5nZXRVUkkocHJlZml4KTsKLSAgICAgICAgICAgIC8vIG1ha2Ugc3VyZSB0aGF0IG9iamVjdCBpbiB0aGUgZWxlbWVudCBzdGFjayBpcyB1cGRhdGVkIGFzIHdlbGwKLSAgICAgICAgICAgIGZDdXJyZW50RWxlbWVudC51cmkgPSBmRWxlbWVudFFOYW1lLnVyaTsKLQotICAgICAgICAgICAgaWYgKGZFbGVtZW50UU5hbWUucHJlZml4ID09IG51bGwgJiYgZkVsZW1lbnRRTmFtZS51cmkgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZFbGVtZW50UU5hbWUucHJlZml4ID0gWE1MU3ltYm9scy5FTVBUWV9TVFJJTkc7Ci0gICAgICAgICAgICAgICAgLy8gbWFraW5nIHN1cmUgdGhhdCB0aGUgb2JqZWN0IGluIHRoZSBlbGVtZW50IHN0YWNrIGlzIHVwZGF0ZWQgdG9vLgotICAgICAgICAgICAgICAgIGZDdXJyZW50RWxlbWVudC5wcmVmaXggPSBYTUxTeW1ib2xzLkVNUFRZX1NUUklORzsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChmRWxlbWVudFFOYW1lLnByZWZpeCAhPSBudWxsICYmIGZFbGVtZW50UU5hbWUudXJpID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmRXJyb3JSZXBvcnRlci5yZXBvcnRFcnJvcigKLSAgICAgICAgICAgICAgICAgICAgWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxOU19ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICJFbGVtZW50UHJlZml4VW5ib3VuZCIsCi0gICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmRWxlbWVudFFOYW1lLnByZWZpeCwKLSAgICAgICAgICAgICAgICAgICAgICAgIGZFbGVtZW50UU5hbWUucmF3bmFtZSB9LAotICAgICAgICAgICAgICAgICAgICBYTUxFcnJvclJlcG9ydGVyLlNFVkVSSVRZX0ZBVEFMX0VSUk9SKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gYmluZCBhdHRyaWJ1dGVzICh4bWxucyBhcmUgYWxyZWFkeSBib3VuZCBiZWxsb3cpCi0gICAgICAgICAgICBpbnQgbGVuZ3RoID0gZkF0dHJpYnV0ZXMuZ2V0TGVuZ3RoKCk7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgZkF0dHJpYnV0ZXMuZ2V0TmFtZShpLCBmQXR0cmlidXRlUU5hbWUpOwotCi0gICAgICAgICAgICAgICAgU3RyaW5nIGFwcmVmaXggPQotICAgICAgICAgICAgICAgICAgICBmQXR0cmlidXRlUU5hbWUucHJlZml4ICE9IG51bGwKLSAgICAgICAgICAgICAgICAgICAgICAgID8gZkF0dHJpYnV0ZVFOYW1lLnByZWZpeAotICAgICAgICAgICAgICAgICAgICAgICAgOiBYTUxTeW1ib2xzLkVNUFRZX1NUUklORzsKLSAgICAgICAgICAgICAgICBTdHJpbmcgdXJpID0gZk5hbWVzcGFjZUNvbnRleHQuZ2V0VVJJKGFwcmVmaXgpOwotICAgICAgICAgICAgICAgIC8vIFJFVklTSVQ6IHRyeSByZW1vdmluZyB0aGUgZmlyc3QgImlmIiBhbmQgc2VlIGlmIGl0IGlzIGZhc3Rlci4KLSAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgIGlmIChmQXR0cmlidXRlUU5hbWUudXJpICE9IG51bGwKLSAgICAgICAgICAgICAgICAgICAgJiYgZkF0dHJpYnV0ZVFOYW1lLnVyaSA9PSB1cmkpIHsKLSAgICAgICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGlmIChhcHJlZml4ICE9IFhNTFN5bWJvbHMuRU1QVFlfU1RSSU5HKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZBdHRyaWJ1dGVRTmFtZS51cmkgPSB1cmk7Ci0gICAgICAgICAgICAgICAgICAgIGlmICh1cmkgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxOU19ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIkF0dHJpYnV0ZVByZWZpeFVuYm91bmQiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZFbGVtZW50UU5hbWUucmF3bmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkF0dHJpYnV0ZVFOYW1lLnJhd25hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcmVmaXggfSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxFcnJvclJlcG9ydGVyLlNFVkVSSVRZX0ZBVEFMX0VSUk9SKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBmQXR0cmlidXRlcy5zZXRVUkkoaSwgdXJpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmIChsZW5ndGggPiAxKSB7Ci0gICAgICAgICAgICAgICAgUU5hbWUgbmFtZSA9IGZBdHRyaWJ1dGVzLmNoZWNrRHVwbGljYXRlc05TKCk7Ci0gICAgICAgICAgICAgICAgaWYgKG5hbWUgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBpZiAobmFtZS51cmkgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxOU19ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIkF0dHJpYnV0ZU5TTm90VW5pcXVlIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10gewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmRWxlbWVudFFOYW1lLnJhd25hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUubG9jYWxwYXJ0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lLnVyaSB9LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTEVycm9yUmVwb3J0ZXIuU0VWRVJJVFlfRkFUQUxfRVJST1IpOwotICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxOU19ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIkF0dHJpYnV0ZU5vdFVuaXF1ZSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkVsZW1lbnRRTmFtZS5yYXduYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lLnJhd25hbWUgfSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxFcnJvclJlcG9ydGVyLlNFVkVSSVRZX0ZBVEFMX0VSUk9SKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIGNhbGwgaGFuZGxlcgotICAgICAgICBpZiAoZkRvY3VtZW50SGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAoZW1wdHkpIHsKLQotICAgICAgICAgICAgICAgIC8vZGVjcmVhc2UgdGhlIG1hcmt1cCBkZXB0aC4uCi0gICAgICAgICAgICAgICAgZk1hcmt1cERlcHRoLS07Ci0KLSAgICAgICAgICAgICAgICAvLyBjaGVjayB0aGF0IHRoaXMgZWxlbWVudCB3YXMgb3BlbmVkIGluIHRoZSBzYW1lIGVudGl0eQotICAgICAgICAgICAgICAgIGlmIChmTWFya3VwRGVwdGggPCBmRW50aXR5U3RhY2tbZkVudGl0eURlcHRoIC0gMV0pIHsKLSAgICAgICAgICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigKLSAgICAgICAgICAgICAgICAgICAgICAgICJFbGVtZW50RW50aXR5TWlzbWF0Y2giLAotICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgZkN1cnJlbnRFbGVtZW50LnJhd25hbWUgfSk7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci5lbXB0eUVsZW1lbnQoZkVsZW1lbnRRTmFtZSwgZkF0dHJpYnV0ZXMsIG51bGwpOwotCi0gICAgICAgICAgICAgICAgaWYgKGZCaW5kTmFtZXNwYWNlcykgewotICAgICAgICAgICAgICAgICAgICBmTmFtZXNwYWNlQ29udGV4dC5wb3BDb250ZXh0KCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIC8vcG9wIHRoZSBlbGVtZW50IG9mZiB0aGUgc3RhY2suLgotICAgICAgICAgICAgICAgIGZFbGVtZW50U3RhY2sucG9wRWxlbWVudCgpOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLnN0YXJ0RWxlbWVudChmRWxlbWVudFFOYW1lLCBmQXR0cmlidXRlcywgbnVsbCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoREVCVUdfU1RBUlRfRU5EX0VMRU1FTlQpCi0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIjw8PCBzY2FuU3RhcnRFbGVtZW50QWZ0ZXJOYW1lKCk6ICIgKyBlbXB0eSk7Ci0gICAgICAgIHJldHVybiBlbXB0eTsKLQotICAgIH0gLy8gc2NhblN0YXJ0RWxlbWVudEFmdGVyTmFtZSgpCi0KLSAgICAvKioKLSAgICAgKiBTY2FucyBhbiBhdHRyaWJ1dGUuCi0gICAgICogPHA+Ci0gICAgICogPHByZT4KLSAgICAgKiBbNDFdIEF0dHJpYnV0ZSA6Oj0gTmFtZSBFcSBBdHRWYWx1ZQotICAgICAqIDwvcHJlPgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gVGhpcyBtZXRob2QgYXNzdW1lcyB0aGF0IHRoZSBuZXh0Ci0gICAgICogY2hhcmFjdGVyIG9uIHRoZSBzdHJlYW0gaXMgdGhlIGZpcnN0IGNoYXJhY3RlciBvZiB0aGUgYXR0cmlidXRlCi0gICAgICogbmFtZS4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoaXMgbWV0aG9kIHVzZXMgdGhlIGZBdHRyaWJ1dGVRTmFtZSBhbmQKLSAgICAgKiBmUU5hbWUgdmFyaWFibGVzLiBUaGUgY29udGVudHMgb2YgdGhlc2UgdmFyaWFibGVzIHdpbGwgYmUKLSAgICAgKiBkZXN0cm95ZWQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYXR0cmlidXRlcyBUaGUgYXR0cmlidXRlcyBsaXN0IGZvciB0aGUgc2Nhbm5lZCBhdHRyaWJ1dGUuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgc2NhbkF0dHJpYnV0ZShYTUxBdHRyaWJ1dGVzSW1wbCBhdHRyaWJ1dGVzKQotICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChERUJVR19TVEFSVF9FTkRfRUxFTUVOVCkKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiPj4+IHNjYW5BdHRyaWJ1dGUoKSIpOwotCi0gICAgICAgIC8vIG5hbWUKLSAgICAgICAgZkVudGl0eVNjYW5uZXIuc2NhblFOYW1lKGZBdHRyaWJ1dGVRTmFtZSwgTmFtZVR5cGUuQVRUUklCVVRFKTsKLQotICAgICAgICAvLyBlcXVhbHMKLSAgICAgICAgZkVudGl0eVNjYW5uZXIuc2tpcFNwYWNlcygpOwotICAgICAgICBpZiAoIWZFbnRpdHlTY2FubmVyLnNraXBDaGFyKCc9JywgTmFtZVR5cGUuQVRUUklCVVRFKSkgewotICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigKLSAgICAgICAgICAgICAgICAiRXFSZXF1aXJlZEluQXR0cmlidXRlIiwKLSAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10gewotICAgICAgICAgICAgICAgICAgICBmQ3VycmVudEVsZW1lbnQucmF3bmFtZSwKLSAgICAgICAgICAgICAgICAgICAgZkF0dHJpYnV0ZVFOYW1lLnJhd25hbWUgfSk7Ci0gICAgICAgIH0KLSAgICAgICAgZkVudGl0eVNjYW5uZXIuc2tpcFNwYWNlcygpOwotCi0gICAgICAgIC8vIGNvbnRlbnQKLSAgICAgICAgaW50IGF0dHJJbmRleDsKLQotICAgICAgICBpZiAoZkJpbmROYW1lc3BhY2VzKSB7Ci0gICAgICAgICAgICBhdHRySW5kZXggPSBhdHRyaWJ1dGVzLmdldExlbmd0aCgpOwotICAgICAgICAgICAgYXR0cmlidXRlcy5hZGRBdHRyaWJ1dGVOUygKLSAgICAgICAgICAgICAgICBmQXR0cmlidXRlUU5hbWUsCi0gICAgICAgICAgICAgICAgWE1MU3ltYm9scy5mQ0RBVEFTeW1ib2wsCi0gICAgICAgICAgICAgICAgbnVsbCk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBpbnQgb2xkTGVuID0gYXR0cmlidXRlcy5nZXRMZW5ndGgoKTsKLSAgICAgICAgICAgIGF0dHJJbmRleCA9Ci0gICAgICAgICAgICAgICAgYXR0cmlidXRlcy5hZGRBdHRyaWJ1dGUoCi0gICAgICAgICAgICAgICAgICAgIGZBdHRyaWJ1dGVRTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgWE1MU3ltYm9scy5mQ0RBVEFTeW1ib2wsCi0gICAgICAgICAgICAgICAgICAgIG51bGwpOwotCi0gICAgICAgICAgICAvLyBXRkM6IFVuaXF1ZSBBdHQgU3BlYwotICAgICAgICAgICAgaWYgKG9sZExlbiA9PSBhdHRyaWJ1dGVzLmdldExlbmd0aCgpKSB7Ci0gICAgICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigKLSAgICAgICAgICAgICAgICAgICAgIkF0dHJpYnV0ZU5vdFVuaXF1ZSIsCi0gICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmQ3VycmVudEVsZW1lbnQucmF3bmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgIGZBdHRyaWJ1dGVRTmFtZS5yYXduYW1lIH0pOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy9SRVZJU0lUOiBvbmUgbW9yZSBjYXNlIG5lZWRzIHRvIGJlIGluY2x1ZGVkOiBleHRlcm5hbCBQRSBhbmQgc3RhbmRhbG9uZSBpcyBubwotICAgICAgICBib29sZWFuIGlzVkMgPSBmSGFzRXh0ZXJuYWxEVEQgJiYgIWZTdGFuZGFsb25lOwotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBEZXRlcm1pbmUgd2hldGhlciB0aGlzIGlzIGEgbmFtZXNwYWNlIGRlY2xhcmF0aW9uIHRoYXQgd2lsbCBiZSBzdWJqZWN0Ci0gICAgICAgICAqIHRvIHRoZSBuYW1lIGxpbWl0IGNoZWNrIGluIHRoZSBzY2FuQXR0cmlidXRlVmFsdWUgb3BlcmF0aW9uLgotICAgICAgICAgKiBOYW1lc3BhY2UgZGVjbGFyYXRpb24gZm9ybWF0OiB4bWxucz0iLi4uIiBvciB4bWxuczpwcmVmaXg9Ii4uLiIKLSAgICAgICAgICogTm90ZSB0aGF0IHByZWZpeDp4bWxucz0iLi4uIiBpc24ndCBhIG5hbWVzcGFjZS4KLSAgICAgICAgICovCi0gICAgICAgIFN0cmluZyBsb2NhbHBhcnQgPSBmQXR0cmlidXRlUU5hbWUubG9jYWxwYXJ0OwotICAgICAgICBTdHJpbmcgcHJlZml4ID0gZkF0dHJpYnV0ZVFOYW1lLnByZWZpeCAhPSBudWxsCi0gICAgICAgICAgICAgICAgPyBmQXR0cmlidXRlUU5hbWUucHJlZml4IDogWE1MU3ltYm9scy5FTVBUWV9TVFJJTkc7Ci0gICAgICAgIGJvb2xlYW4gaXNOU0RlY2wgPSBmQmluZE5hbWVzcGFjZXMgJiAocHJlZml4ID09IFhNTFN5bWJvbHMuUFJFRklYX1hNTE5TIHx8Ci0gICAgICAgICAgICAgICAgICAgIHByZWZpeCA9PSBYTUxTeW1ib2xzLkVNUFRZX1NUUklORyAmJiBsb2NhbHBhcnQgPT0gWE1MU3ltYm9scy5QUkVGSVhfWE1MTlMpOwotCi0gICAgICAgIHNjYW5BdHRyaWJ1dGVWYWx1ZSh0aGlzLmZUZW1wU3RyaW5nLCBmVGVtcFN0cmluZzIsIGZBdHRyaWJ1dGVRTmFtZS5yYXduYW1lLAotICAgICAgICAgICAgaXNWQywgZkN1cnJlbnRFbGVtZW50LnJhd25hbWUsIGlzTlNEZWNsKTsKLSAgICAgICAgU3RyaW5nIHZhbHVlID0gZlRlbXBTdHJpbmcudG9TdHJpbmcoKTsKLSAgICAgICAgYXR0cmlidXRlcy5zZXRWYWx1ZShhdHRySW5kZXgsIHZhbHVlKTsKLSAgICAgICAgYXR0cmlidXRlcy5zZXROb25Ob3JtYWxpemVkVmFsdWUoYXR0ckluZGV4LCBmVGVtcFN0cmluZzIudG9TdHJpbmcoKSk7Ci0gICAgICAgIGF0dHJpYnV0ZXMuc2V0U3BlY2lmaWVkKGF0dHJJbmRleCwgdHJ1ZSk7Ci0KLSAgICAgICAgLy8gcmVjb3JkIG5hbWVzcGFjZSBkZWNsYXJhdGlvbnMgaWYgYW55LgotICAgICAgICBpZiAoZkJpbmROYW1lc3BhY2VzKSB7Ci0gICAgICAgICAgICBpZiAoaXNOU0RlY2wpIHsKLSAgICAgICAgICAgICAgICBpZiAodmFsdWUubGVuZ3RoKCkgPiBmWE1MTmFtZUxpbWl0KSB7Ci0gICAgICAgICAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTWF4WE1MTmFtZUxpbWl0IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117dmFsdWUsIHZhbHVlLmxlbmd0aCgpLCBmWE1MTmFtZUxpbWl0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZTZWN1cml0eU1hbmFnZXIuZ2V0U3RhdGVMaXRlcmFsKFhNTFNlY3VyaXR5TWFuYWdlci5MaW1pdC5NQVhfTkFNRV9MSU1JVCl9LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTEVycm9yUmVwb3J0ZXIuU0VWRVJJVFlfRkFUQUxfRVJST1IpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvLyBnZXQgdGhlIGludGVybmFsaXplZCB2YWx1ZSBvZiB0aGlzIGF0dHJpYnV0ZQotICAgICAgICAgICAgICAgIFN0cmluZyB1cmkgPSBmU3ltYm9sVGFibGUuYWRkU3ltYm9sKHZhbHVlKTsKLQotICAgICAgICAgICAgICAgIC8vIDEuICJ4bWxucyIgY2FuJ3QgYmUgYm91bmQgdG8gYW55IG5hbWVzcGFjZQotICAgICAgICAgICAgICAgIGlmIChwcmVmaXggPT0gWE1MU3ltYm9scy5QUkVGSVhfWE1MTlMKLSAgICAgICAgICAgICAgICAgICAgJiYgbG9jYWxwYXJ0ID09IFhNTFN5bWJvbHMuUFJFRklYX1hNTE5TKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKAotICAgICAgICAgICAgICAgICAgICAgICAgWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxOU19ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAiQ2FudEJpbmRYTUxOUyIsCi0gICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBmQXR0cmlidXRlUU5hbWUgfSwKLSAgICAgICAgICAgICAgICAgICAgICAgIFhNTEVycm9yUmVwb3J0ZXIuU0VWRVJJVFlfRkFUQUxfRVJST1IpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8vIDIuIHRoZSBuYW1lc3BhY2UgZm9yICJ4bWxucyIgY2FuJ3QgYmUgYm91bmQgdG8gYW55IHByZWZpeAotICAgICAgICAgICAgICAgIGlmICh1cmkgPT0gTmFtZXNwYWNlQ29udGV4dC5YTUxOU19VUkkpIHsKLSAgICAgICAgICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IoCi0gICAgICAgICAgICAgICAgICAgICAgICBYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTE5TX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICJDYW50QmluZFhNTE5TIiwKLSAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7IGZBdHRyaWJ1dGVRTmFtZSB9LAotICAgICAgICAgICAgICAgICAgICAgICAgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9GQVRBTF9FUlJPUik7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgLy8gMy4gInhtbCIgY2FuJ3QgYmUgYm91bmQgdG8gYW55IG90aGVyIG5hbWVzcGFjZSB0aGFuIGl0J3Mgb3duCi0gICAgICAgICAgICAgICAgaWYgKGxvY2FscGFydCA9PSBYTUxTeW1ib2xzLlBSRUZJWF9YTUwpIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKHVyaSAhPSBOYW1lc3BhY2VDb250ZXh0LlhNTF9VUkkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MTlNfRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDYW50QmluZFhNTCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgZkF0dHJpYnV0ZVFOYW1lIH0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9GQVRBTF9FUlJPUik7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLy8gNC4gdGhlIG5hbWVzcGFjZSBmb3IgInhtbCIgY2FuJ3QgYmUgYm91bmQgdG8gYW55IG90aGVyIHByZWZpeAotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICBpZiAodXJpID09IE5hbWVzcGFjZUNvbnRleHQuWE1MX1VSSSkgewotICAgICAgICAgICAgICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxOU19ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNhbnRCaW5kWE1MIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBmQXR0cmlidXRlUU5hbWUgfSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxFcnJvclJlcG9ydGVyLlNFVkVSSVRZX0ZBVEFMX0VSUk9SKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIHByZWZpeCA9Ci0gICAgICAgICAgICAgICAgICAgIGxvY2FscGFydCAhPSBYTUxTeW1ib2xzLlBSRUZJWF9YTUxOUwotICAgICAgICAgICAgICAgICAgICAgICAgPyBsb2NhbHBhcnQKLSAgICAgICAgICAgICAgICAgICAgICAgIDogWE1MU3ltYm9scy5FTVBUWV9TVFJJTkc7Ci0KLSAgICAgICAgICAgICAgICAvLyBEZWNsYXJlIHByZWZpeCBpbiBjb250ZXh0LiBSZW1vdmluZyB0aGUgYXNzb2NpYXRpb24gYmV0d2VlbiBhIHByZWZpeCBhbmQgYQotICAgICAgICAgICAgICAgIC8vIG5hbWVzcGFjZSBuYW1lIGlzIHBlcm1pdHRlZCBpbiBYTUwgMS4xLCBzbyBpZiB0aGUgdXJpIHZhbHVlIGlzIHRoZSBlbXB0eSBzdHJpbmcsCi0gICAgICAgICAgICAgICAgLy8gdGhlIHByZWZpeCBpcyBiZWluZyB1bmJvdW5kLiAtLSBtcmdsYXZhcwotICAgICAgICAgICAgICAgIGZOYW1lc3BhY2VDb250ZXh0LmRlY2xhcmVQcmVmaXgoCi0gICAgICAgICAgICAgICAgICAgIHByZWZpeCwKLSAgICAgICAgICAgICAgICAgICAgdXJpLmxlbmd0aCgpICE9IDAgPyB1cmkgOiBudWxsKTsKLSAgICAgICAgICAgICAgICAvLyBiaW5kIG5hbWVzcGFjZSBhdHRyaWJ1dGUgdG8gYSBuYW1lc3BhY2UKLSAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzLnNldFVSSSgKLSAgICAgICAgICAgICAgICAgICAgYXR0ckluZGV4LAotICAgICAgICAgICAgICAgICAgICBmTmFtZXNwYWNlQ29udGV4dC5nZXRVUkkoWE1MU3ltYm9scy5QUkVGSVhfWE1MTlMpKTsKLQotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAvLyBhdHRlbXB0IHRvIGJpbmQgYXR0cmlidXRlCi0gICAgICAgICAgICAgICAgaWYgKGZBdHRyaWJ1dGVRTmFtZS5wcmVmaXggIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzLnNldFVSSSgKLSAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJJbmRleCwKLSAgICAgICAgICAgICAgICAgICAgICAgIGZOYW1lc3BhY2VDb250ZXh0LmdldFVSSShmQXR0cmlidXRlUU5hbWUucHJlZml4KSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKERFQlVHX1NUQVJUX0VORF9FTEVNRU5UKQotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCI8PDwgc2NhbkF0dHJpYnV0ZSgpIik7Ci0gICAgfSAvLyBzY2FuQXR0cmlidXRlKFhNTEF0dHJpYnV0ZXMpCi0KLSAgICAvKioKLSAgICAgKiBTY2FucyBhbiBlbmQgZWxlbWVudC4KLSAgICAgKiA8cD4KLSAgICAgKiA8cHJlPgotICAgICAqIFs0Ml0gRVRhZyA6Oj0gJyZsdDsvJyBOYW1lIFM/ICc+JwotICAgICAqIDwvcHJlPgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gVGhpcyBtZXRob2QgdXNlcyB0aGUgZkVsZW1lbnRRTmFtZSB2YXJpYWJsZS4KLSAgICAgKiBUaGUgY29udGVudHMgb2YgdGhpcyB2YXJpYWJsZSB3aWxsIGJlIGRlc3Ryb3llZC4gVGhlIGNhbGxlciBzaG91bGQKLSAgICAgKiBjb3B5IHRoZSBuZWVkZWQgaW5mb3JtYXRpb24gb3V0IG9mIHRoaXMgdmFyaWFibGUgYmVmb3JlIGNhbGxpbmcKLSAgICAgKiB0aGlzIG1ldGhvZC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIGVsZW1lbnQgZGVwdGguCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGludCBzY2FuRW5kRWxlbWVudCgpIHRocm93cyBJT0V4Y2VwdGlvbiwgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKERFQlVHX1NUQVJUX0VORF9FTEVNRU5UKQotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCI+Pj4gc2NhbkVuZEVsZW1lbnQoKSIpOwotCi0gICAgICAgIC8vIHBvcCBjb250ZXh0Ci0gICAgICAgIFFOYW1lIGVuZEVsZW1lbnROYW1lID0gZkVsZW1lbnRTdGFjay5wb3BFbGVtZW50KCk7Ci0KLSAgICAgICAgLy8gVGFrZSBhZHZhbnRhZ2Ugb2YgdGhlIGZhY3QgdGhhdCBuZXh0IHN0cmluZyBfc2hvdWxkXyBiZSAiZkVsZW1lbnRRTmFtZS5yYXdOYW1lIiwKLSAgICAgICAgLy9JbiBzY2FubmVycyBtb3N0IG9mIHRoZSB0aW1lIGlzIGNvbnN1bWVkIG9uIGNoZWNrcyBkb25lIGZvciBYTUwgY2hhcmFjdGVycywgd2UgY2FuCi0gICAgICAgIC8vIG9wdGltaXplIG9uIGl0IGFuZCBhdm9pZCB0aGUgY2hlY2tzIGRvbmUgZm9yIGVuZEVsZW1lbnQsCi0gICAgICAgIC8vd2Ugd2lsbCBhbHNvIGF2b2lkIHN5bWJvbCB0YWJsZSBsb29rdXAgLSBuZWVyYWouYmFqYWpAc3VuLmNvbQotCi0gICAgICAgIC8vIHRoaXMgc2hvdWxkIHdvcmsgYm90aCBmb3IgbmFtZXNwYWNlIHByb2Nlc3NpbmcgdHJ1ZSBvciBmYWxzZS4uLgotCi0gICAgICAgIC8vUkVWSVNJVDogaWYgdGhlIHN0cmluZyBpcyBub3QgdGhlIHNhbWUgYXMgZXhwZWN0ZWQuLiB3ZSBuZWVkIHRvIGRvIGJldHRlciBlcnJvciBoYW5kbGluZy4uCi0gICAgICAgIC8vV2UgY2FuIHNraXAgdGhpcyBmb3Igbm93Li4uIEluIGFueSBjYXNlIGlmIHRoZSBzdHJpbmcgZG9lc24ndCBtYXRjaCAtLSBkb2N1bWVudCBpcyBub3Qgd2VsbCBmb3JtZWQuCi0KLSAgICAgICAgaWYgKCFmRW50aXR5U2Nhbm5lci5za2lwU3RyaW5nKGVuZEVsZW1lbnROYW1lLnJhd25hbWUpKSB7Ci0gICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigKLSAgICAgICAgICAgICAgICAiRVRhZ1JlcXVpcmVkIiwKLSAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBlbmRFbGVtZW50TmFtZS5yYXduYW1lIH0pOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gZW5kCi0gICAgICAgIGZFbnRpdHlTY2FubmVyLnNraXBTcGFjZXMoKTsKLSAgICAgICAgaWYgKCFmRW50aXR5U2Nhbm5lci5za2lwQ2hhcignPicsIE5hbWVUeXBlLkVMRU1FTlRFTkQpKSB7Ci0gICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKAotICAgICAgICAgICAgICAgICJFVGFnVW50ZXJtaW5hdGVkIiwKLSAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBlbmRFbGVtZW50TmFtZS5yYXduYW1lIH0pOwotICAgICAgICB9Ci0gICAgICAgIGZNYXJrdXBEZXB0aC0tOwotCi0gICAgICAgIC8vd2UgaGF2ZSBpbmNyZWFzZWQgdGhlIGRlcHRoIGZvciB0d28gbWFya3VwICI8IiBjaGFyYWN0ZXJzCi0gICAgICAgIGZNYXJrdXBEZXB0aC0tOwotCi0gICAgICAgIC8vIGNoZWNrIHRoYXQgdGhpcyBlbGVtZW50IHdhcyBvcGVuZWQgaW4gdGhlIHNhbWUgZW50aXR5Ci0gICAgICAgIGlmIChmTWFya3VwRGVwdGggPCBmRW50aXR5U3RhY2tbZkVudGl0eURlcHRoIC0gMV0pIHsKLSAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoCi0gICAgICAgICAgICAgICAgIkVsZW1lbnRFbnRpdHlNaXNtYXRjaCIsCi0gICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgZW5kRWxlbWVudE5hbWUucmF3bmFtZSB9KTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIGNhbGwgaGFuZGxlcgotICAgICAgICBpZiAoZkRvY3VtZW50SGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLmVuZEVsZW1lbnQoZW5kRWxlbWVudE5hbWUsIG51bGwpOwotCi0gICAgICAgICAgICAvKmlmIChmQmluZE5hbWVzcGFjZXMpIHsKLSAgICAgICAgICAgICAgICBmTmFtZXNwYWNlQ29udGV4dC5wb3BDb250ZXh0KCk7Ci0gICAgICAgICAgICB9Ki8KLQotICAgICAgICB9Ci0KLSAgICAgICAgaWYoZHRkR3JhbW1hclV0aWwgIT0gbnVsbCkKLSAgICAgICAgICAgIGR0ZEdyYW1tYXJVdGlsLmVuZEVsZW1lbnQoZW5kRWxlbWVudE5hbWUpOwotCi0gICAgICAgIHJldHVybiBmTWFya3VwRGVwdGg7Ci0KLSAgICB9IC8vIHNjYW5FbmRFbGVtZW50KCk6aW50Ci0KLSAgICBwdWJsaWMgdm9pZCByZXNldChYTUxDb21wb25lbnRNYW5hZ2VyIGNvbXBvbmVudE1hbmFnZXIpCi0gICAgICAgIHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIHsKLQotICAgICAgICBzdXBlci5yZXNldChjb21wb25lbnRNYW5hZ2VyKTsKLSAgICAgICAgZlBlcmZvcm1WYWxpZGF0aW9uID0gZmFsc2U7Ci0gICAgICAgIGZCaW5kTmFtZXNwYWNlcyA9IGZhbHNlOwotICAgIH0KLQotICAgIC8qKiBDcmVhdGVzIGEgY29udGVudCBEcml2ZXIuICovCi0gICAgcHJvdGVjdGVkIERyaXZlciBjcmVhdGVDb250ZW50RHJpdmVyKCkgewotICAgICAgICByZXR1cm4gbmV3IE5TMTFDb250ZW50RHJpdmVyKCk7Ci0gICAgfSAvLyBjcmVhdGVDb250ZW50RHJpdmVyKCk6RHJpdmVyCi0KLQotICAgIC8qKiByZXR1cm4gdGhlIG5leHQgc3RhdGUgb24gdGhlIGlucHV0Ci0gICAgICoKLSAgICAgKiBAcmV0dXJuIGludAotICAgICAqLwotCi0gICAgcHVibGljIGludCBuZXh0KCkgdGhyb3dzIElPRXhjZXB0aW9uLCBYTklFeGNlcHRpb24gewotICAgICAgICAvL3NpbmNlIG5hbWVzcGFjZSBjb250ZXh0IHNob3VsZCBzdGlsbCBiZSB2YWxpZCB3aGVuIHRoZSBwYXJzZXIgaXMgYXQgdGhlIGVuZCBlbGVtZW50IHN0YXRlIHRoZXJlZm9yZQotICAgICAgICAvL3dlIHBvcCB0aGUgY29udGV4dCBvbmx5IHdoZW4gbmV4dCgpIGhhcyBiZWVuIGNhbGxlZCBhZnRlciB0aGUgZW5kIGVsZW1lbnQgc3RhdGUgd2FzIGVuY291bnRlcmVkLiAtIG5iLgotCi0gICAgICAgIGlmKChmU2Nhbm5lckxhc3RTdGF0ZSA9PSBYTUxFdmVudC5FTkRfRUxFTUVOVCkgJiYgZkJpbmROYW1lc3BhY2VzKXsKLSAgICAgICAgICAgIGZTY2FubmVyTGFzdFN0YXRlID0gLTE7Ci0gICAgICAgICAgICBmTmFtZXNwYWNlQ29udGV4dC5wb3BDb250ZXh0KCk7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gZlNjYW5uZXJMYXN0U3RhdGUgPSBzdXBlci5uZXh0KCk7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBEcml2ZXIgdG8gaGFuZGxlIGNvbnRlbnQgc2Nhbm5pbmcuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGZpbmFsIGNsYXNzIE5TMTFDb250ZW50RHJpdmVyIGV4dGVuZHMgQ29udGVudERyaXZlciB7Ci0gICAgICAgIC8qKgotICAgICAgICAgKiBTY2FuIGZvciByb290IGVsZW1lbnQgaG9vay4gVGhpcyBtZXRob2QgaXMgYSBob29rIGZvcgotICAgICAgICAgKiBzdWJjbGFzc2VzIHRvIGFkZCBjb2RlIHRoYXQgaGFuZGxlcyBzY2FubmluZyBmb3IgdGhlIHJvb3QKLSAgICAgICAgICogZWxlbWVudC4gVGhpcyBtZXRob2Qgd2lsbCBhbHNvIGF0dGVtcHQgdG8gcmVtb3ZlIERURCB2YWxpZGF0b3IKLSAgICAgICAgICogZnJvbSB0aGUgcGlwZWxpbmUsIGlmIHRoZXJlIGlzIG5vIERURCBncmFtbWFyLiBJZiBEVEQgdmFsaWRhdG9yCi0gICAgICAgICAqIGlzIG5vIGxvbmdlciBpbiB0aGUgcGlwZWxpbmUgYmluZCBuYW1lc3BhY2VzIGluIHRoZSBzY2FubmVyLgotICAgICAgICAgKgotICAgICAgICAgKgotICAgICAgICAgKiBAcmV0dXJuIFRydWUgaWYgdGhlIGNhbGxlciBzaG91bGQgc3RvcCBhbmQgcmV0dXJuIHRydWUgd2hpY2gKLSAgICAgICAgICogICAgICAgICAgYWxsb3dzIHRoZSBzY2FubmVyIHRvIHN3aXRjaCB0byBhIG5ldyBzY2FubmluZwotICAgICAgICAgKiAgICAgICAgICBEcml2ZXIuIEEgcmV0dXJuIHZhbHVlIG9mIGZhbHNlIGluZGljYXRlcyB0aGF0Ci0gICAgICAgICAqICAgICAgICAgIHRoZSBjb250ZW50IERyaXZlciBzaG91bGQgY29udGludWUgYXMgbm9ybWFsLgotICAgICAgICAgKi8KLSAgICAgICAgcHJvdGVjdGVkIGJvb2xlYW4gc2NhblJvb3RFbGVtZW50SG9vaygpCi0gICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgICAgIGlmIChmRXh0ZXJuYWxTdWJzZXRSZXNvbHZlciAhPSBudWxsICYmICFmU2VlbkRvY3R5cGVEZWNsCi0gICAgICAgICAgICAgICAgJiYgIWZEaXNhbGxvd0RvY3R5cGUgJiYgKGZWYWxpZGF0aW9uIHx8IGZMb2FkRXh0ZXJuYWxEVEQpKSB7Ci0gICAgICAgICAgICAgICAgc2NhblN0YXJ0RWxlbWVudE5hbWUoKTsKLSAgICAgICAgICAgICAgICByZXNvbHZlRXh0ZXJuYWxTdWJzZXRBbmRSZWFkKCk7Ci0gICAgICAgICAgICAgICAgcmVjb25maWd1cmVQaXBlbGluZSgpOwotICAgICAgICAgICAgICAgIGlmIChzY2FuU3RhcnRFbGVtZW50QWZ0ZXJOYW1lKCkpIHsKLSAgICAgICAgICAgICAgICAgICAgc2V0U2Nhbm5lclN0YXRlKFNDQU5ORVJfU1RBVEVfVFJBSUxJTkdfTUlTQyk7Ci0gICAgICAgICAgICAgICAgICAgIHNldERyaXZlcihmVHJhaWxpbmdNaXNjRHJpdmVyKTsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgcmVjb25maWd1cmVQaXBlbGluZSgpOwotICAgICAgICAgICAgICAgIGlmIChzY2FuU3RhcnRFbGVtZW50KCkpIHsKLSAgICAgICAgICAgICAgICAgICAgc2V0U2Nhbm5lclN0YXRlKFNDQU5ORVJfU1RBVEVfVFJBSUxJTkdfTUlTQyk7Ci0gICAgICAgICAgICAgICAgICAgIHNldERyaXZlcihmVHJhaWxpbmdNaXNjRHJpdmVyKTsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotCi0gICAgICAgIH0gLy8gc2NhblJvb3RFbGVtZW50SG9vaygpOmJvb2xlYW4KLQotICAgICAgICAvKioKLSAgICAgICAgICogUmUtY29uZmlndXJlcyBwaXBlbGluZSBieSByZW1vdmluZyB0aGUgRFREIHZhbGlkYXRvcgotICAgICAgICAgKiBpZiBubyBEVEQgZ3JhbW1hciBleGlzdHMuIElmIG5vIHZhbGlkYXRvciBleGlzdHMgaW4gdGhlCi0gICAgICAgICAqIHBpcGVsaW5lIG9yIHRoZXJlIGlzIG5vIERURCBncmFtbWFyLCBuYW1lc3BhY2UgYmluZGluZwotICAgICAgICAgKiBpcyBwZXJmb3JtZWQgYnkgdGhlIHNjYW5uZXIgaW4gdGhlIGVuY2xvc2luZyBjbGFzcy4KLSAgICAgICAgICovCi0gICAgICAgIHByaXZhdGUgdm9pZCByZWNvbmZpZ3VyZVBpcGVsaW5lKCkgewotICAgICAgICAgICAgaWYgKGZEVERWYWxpZGF0b3IgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZCaW5kTmFtZXNwYWNlcyA9IHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmICghZkRURFZhbGlkYXRvci5oYXNHcmFtbWFyKCkpIHsKLSAgICAgICAgICAgICAgICBmQmluZE5hbWVzcGFjZXMgPSB0cnVlOwotICAgICAgICAgICAgICAgIGZQZXJmb3JtVmFsaWRhdGlvbiA9IGZEVERWYWxpZGF0b3IudmFsaWRhdGUoKTsKLSAgICAgICAgICAgICAgICAvLyByZS1jb25maWd1cmUgcGlwZWxpbmUKLSAgICAgICAgICAgICAgICBYTUxEb2N1bWVudFNvdXJjZSBzb3VyY2UgPSBmRFREVmFsaWRhdG9yLmdldERvY3VtZW50U291cmNlKCk7Ci0gICAgICAgICAgICAgICAgWE1MRG9jdW1lbnRIYW5kbGVyIGhhbmRsZXIgPSBmRFREVmFsaWRhdG9yLmdldERvY3VtZW50SGFuZGxlcigpOwotICAgICAgICAgICAgICAgIHNvdXJjZS5zZXREb2N1bWVudEhhbmRsZXIoaGFuZGxlcik7Ci0gICAgICAgICAgICAgICAgaWYgKGhhbmRsZXIgIT0gbnVsbCkKLSAgICAgICAgICAgICAgICAgICAgaGFuZGxlci5zZXREb2N1bWVudFNvdXJjZShzb3VyY2UpOwotICAgICAgICAgICAgICAgIGZEVERWYWxpZGF0b3Iuc2V0RG9jdW1lbnRTb3VyY2UobnVsbCk7Ci0gICAgICAgICAgICAgICAgZkRURFZhbGlkYXRvci5zZXREb2N1bWVudEhhbmRsZXIobnVsbCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gLy8gcmVjb25maWd1cmVQaXBlbGluZSgpCi0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9YTUwxMU5hbWVzcGFjZUJpbmRlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9YTUwxMU5hbWVzcGFjZUJpbmRlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4N2U2NmMzLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvWE1MMTFOYW1lc3BhY2VCaW5kZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEwNiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAwLTIwMDIgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYZXJjZXMiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIEludGVybmF0aW9uYWwKLSAqIEJ1c2luZXNzIE1hY2hpbmVzLCBJbmMuLCBodHRwOi8vd3d3LmFwYWNoZS5vcmcuICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGw7Ci0KLQotLyoqCi0gKiBUaGlzIGNsYXNzIHBlcmZvcm1zIG5hbWVzcGFjZSBiaW5kaW5nIG9uIHRoZSBzdGFydEVsZW1lbnQgYW5kIGVuZEVsZW1lbnQKLSAqIG1ldGhvZCBjYWxscyBpbiBhY2NvcmRhbmNlIHdpdGggTmFtZXNwYWNlcyBpbiBYTUwgMS4xLiAgSXQgZXh0ZW5kcyB0aGUgc3RhbmRhcmQsCi0gKiBOYW1lc3BhY2UtMS4wLWNvbXBsaWFudCBiaW5kZXIgaW4gb3JkZXIgdG8gZG8gdGhpcy4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBOZWlsIEdyYWhhbSwgSUJNCi0gKgotICovCi1wdWJsaWMgY2xhc3MgWE1MMTFOYW1lc3BhY2VCaW5kZXIgZXh0ZW5kcyBYTUxOYW1lc3BhY2VCaW5kZXIgewotCi0gICAgLy8KLSAgICAvLyBDb25zdGFudHMKLSAgICAvLwotCi0gICAgLy8KLSAgICAvLyBEYXRhCi0gICAgLy8KLQotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKiBEZWZhdWx0IGNvbnN0cnVjdG9yLiAqLwotICAgIHB1YmxpYyBYTUwxMU5hbWVzcGFjZUJpbmRlcigpIHsKLSAgICB9IC8vIDxpbml0PigpCi0gICAgLy8KLSAgICAvLyBQdWJsaWMgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvLwotICAgIC8vIFByb3RlY3RlZCBtZXRob2RzCi0gICAgLy8KLQotICAgIC8vIHJldHVybnMgdHJ1ZSBpZmYgdGhlIGdpdmVuIHByZWZpeCBpcyBib3VuZCB0byAiIiAqYW5kKgotICAgIC8vIHRoaXMgaXMgZGlzYWxsb3dlZCBieSB0aGUgdmVyc2lvbiBvZiBYTUwgbmFtZXNwYWNlcyBpbiB1c2UuCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gcHJlZml4Qm91bmRUb051bGxVUkkoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FscGFydCkgewotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfSAvLyBwcmVmaXhCb3VuZFRvTnVsbFVSSShTdHJpbmcsIFN0cmluZyk6ICBib29sZWFuCi0KLX0gLy8gY2xhc3MgWE1MMTFOYW1lc3BhY2VCaW5kZXIKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvWE1MRFREU2Nhbm5lckltcGwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvWE1MRFREU2Nhbm5lckltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZDYzZGY2NC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL1hNTERURFNjYW5uZXJJbXBsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMjAwICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDMsIDIwMTYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKi8KLQotLyoKLSAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQotICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCi0gKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCi0gKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAotICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKLSAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0KLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLkNvbnN0YW50czsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwubXNnLlhNTE1lc3NhZ2VGb3JtYXR0ZXI7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuWE1MRXJyb3JSZXBvcnRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuWE1MRW50aXR5SGFuZGxlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuU3ltYm9sVGFibGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlhNTEF0dHJpYnV0ZXNJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5YTUxDaGFyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5YTUxTdHJpbmdCdWZmZXI7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWxzLlhNTExpbWl0QW5hbHl6ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlscy5YTUxTZWN1cml0eU1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MRFREQ29udGVudE1vZGVsSGFuZGxlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxEVERIYW5kbGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTFJlc291cmNlSWRlbnRpZmllcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxTdHJpbmc7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE5JRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxDb21wb25lbnQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTENvbXBvbmVudE1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTERURFNjYW5uZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTElucHV0U291cmNlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLkF1Z21lbnRhdGlvbnM7Ci1pbXBvcnQgY29tLnN1bi54bWwuaW50ZXJuYWwuc3RyZWFtLmR0ZC5ub252YWxpZGF0aW5nLkRUREdyYW1tYXI7Ci1pbXBvcnQgamF2YS5pby5FT0ZFeGNlcHRpb247Ci1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGlzIHJlc3BvbnNpYmxlIGZvciBzY2FubmluZyB0aGUgZGVjbGFyYXRpb25zIGZvdW5kCi0gKiBpbiB0aGUgaW50ZXJuYWwgYW5kIGV4dGVybmFsIHN1YnNldHMgb2YgYSBEVEQgaW4gYW4gWE1MIGRvY3VtZW50LgotICogVGhlIHNjYW5uZXIgYWN0cyBhcyB0aGUgc291cmNlcyBmb3IgdGhlIERURCBpbmZvcm1hdGlvbiB3aGljaCBpcwotICogY29tbXVuaWNhdGVkIHRvIHRoZSBEVEQgaGFuZGxlcnMuCi0gKiA8cD4KLSAqIFRoaXMgY29tcG9uZW50IHJlcXVpcmVzIHRoZSBmb2xsb3dpbmcgZmVhdHVyZXMgYW5kIHByb3BlcnRpZXMgZnJvbSB0aGUKLSAqIGNvbXBvbmVudCBtYW5hZ2VyIHRoYXQgdXNlcyBpdDoKLSAqIDx1bD4KLSAqICA8bGk+aHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL3ZhbGlkYXRpb248L2xpPgotICogIDxsaT5odHRwOi8vYXBhY2hlLm9yZy94bWwvZmVhdHVyZXMvc2Nhbm5lci9ub3RpZnktY2hhci1yZWZzPC9saT4KLSAqICA8bGk+aHR0cDovL2FwYWNoZS5vcmcveG1sL3Byb3BlcnRpZXMvaW50ZXJuYWwvc3ltYm9sLXRhYmxlPC9saT4KLSAqICA8bGk+aHR0cDovL2FwYWNoZS5vcmcveG1sL3Byb3BlcnRpZXMvaW50ZXJuYWwvZXJyb3ItcmVwb3J0ZXI8L2xpPgotICogIDxsaT5odHRwOi8vYXBhY2hlLm9yZy94bWwvcHJvcGVydGllcy9pbnRlcm5hbC9lbnRpdHktbWFuYWdlcjwvbGk+Ci0gKiA8L3VsPgotICoKLSAqIEBhdXRob3IgQXJuYXVkICBMZSBIb3JzLCBJQk0KLSAqIEBhdXRob3IgQW5keSBDbGFyaywgSUJNCi0gKiBAYXV0aG9yIEdsZW5uIE1hcmN5LCBJQk0KLSAqIEBhdXRob3IgRXJpYyBZZSwgSUJNCi0gKgotICogQHZlcnNpb24gJElkOiBYTUxEVERTY2FubmVySW1wbC5qYXZhLHYgMS44IDIwMTAtMTEtMDEgMDQ6Mzk6NDEgam9laHcgRXhwICQKLSAqLwotcHVibGljIGNsYXNzIFhNTERURFNjYW5uZXJJbXBsCi1leHRlbmRzIFhNTFNjYW5uZXIKLWltcGxlbWVudHMgWE1MRFREU2Nhbm5lciwgWE1MQ29tcG9uZW50LCBYTUxFbnRpdHlIYW5kbGVyIHsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RhbnRzCi0gICAgLy8KLQotICAgIC8vIHNjYW5uZXIgc3RhdGVzCi0KLSAgICAvKiogU2Nhbm5lciBzdGF0ZTogZW5kIG9mIGlucHV0LiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgaW50IFNDQU5ORVJfU1RBVEVfRU5EX09GX0lOUFVUID0gMDsKLQotICAgIC8qKiBTY2FubmVyIHN0YXRlOiB0ZXh0IGRlY2xhcmF0aW9uLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgaW50IFNDQU5ORVJfU1RBVEVfVEVYVF9ERUNMID0gMTsKLQotICAgIC8qKiBTY2FubmVyIHN0YXRlOiBtYXJrdXAgZGVjbGFyYXRpb24uICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBpbnQgU0NBTk5FUl9TVEFURV9NQVJLVVBfREVDTCA9IDI7Ci0KLSAgICAvLyByZWNvZ25pemVkIGZlYXR1cmVzIGFuZCBwcm9wZXJ0aWVzCi0KLSAgICAvKiogUmVjb2duaXplZCBmZWF0dXJlcy4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSBSRUNPR05JWkVEX0ZFQVRVUkVTID0gewotICAgICAgICBWQUxJREFUSU9OLAotICAgICAgICBOT1RJRllfQ0hBUl9SRUZTLAotICAgIH07Ci0KLSAgICAvKiogRmVhdHVyZSBkZWZhdWx0cy4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBCb29sZWFuW10gRkVBVFVSRV9ERUZBVUxUUyA9IHsKLSAgICAgICAgbnVsbCwKLSAgICAgICAgQm9vbGVhbi5GQUxTRSwKLSAgICB9OwotCi0gICAgLyoqIFJlY29nbml6ZWQgcHJvcGVydGllcy4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSBSRUNPR05JWkVEX1BST1BFUlRJRVMgPSB7Ci0gICAgICAgIFNZTUJPTF9UQUJMRSwKLSAgICAgICAgRVJST1JfUkVQT1JURVIsCi0gICAgICAgIEVOVElUWV9NQU5BR0VSLAotICAgIH07Ci0KLSAgICAvKiogUHJvcGVydHkgZGVmYXVsdHMuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgT2JqZWN0W10gUFJPUEVSVFlfREVGQVVMVFMgPSB7Ci0gICAgICAgIG51bGwsCi0gICAgICAgIG51bGwsCi0gICAgICAgIG51bGwsCi0gICAgfTsKLQotICAgIC8vIGRlYnVnZ2luZwotCi0gICAgLyoqIERlYnVnIHNjYW5uZXIgc3RhdGUuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbiBERUJVR19TQ0FOTkVSX1NUQVRFID0gZmFsc2U7Ci0KLSAgICAvLwotICAgIC8vIERhdGEKLSAgICAvLwotCi0gICAgLy8gaGFuZGxlcnMKLQotICAgIC8qKiBEVEQgaGFuZGxlci4gKi8KLSAgICBwdWJsaWMgWE1MRFRESGFuZGxlciBmRFRESGFuZGxlciA9IG51bGw7Ci0KLSAgICAvKiogRFREIGNvbnRlbnQgbW9kZWwgaGFuZGxlci4gKi8KLSAgICBwcm90ZWN0ZWQgWE1MRFREQ29udGVudE1vZGVsSGFuZGxlciBmRFREQ29udGVudE1vZGVsSGFuZGxlcjsKLQotICAgIC8vIHN0YXRlCi0KLSAgICAvKiogU2Nhbm5lciBzdGF0ZS4gKi8KLSAgICBwcm90ZWN0ZWQgaW50IGZTY2FubmVyU3RhdGU7Ci0KLSAgICAvKiogU3RhbmRhbG9uZS4gKi8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBmU3RhbmRhbG9uZTsKLQotICAgIC8qKiBTZWVuIGV4dGVybmFsIERURC4gKi8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBmU2VlbkV4dGVybmFsRFREOwotCi0gICAgLyoqIFNlZW4gZXh0ZXJuYWwgcGFyYW1ldGVyIGVudGl0eS4gKi8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBmU2VlbkV4dGVybmFsUEU7Ci0KLSAgICAvLyBwcml2YXRlIGRhdGEKLQotICAgIC8qKiBTdGFydCBEVEQgY2FsbGVkLiAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBmU3RhcnREVERDYWxsZWQ7Ci0KLSAgICAvKiogRGVmYXVsdCBhdHRyaWJ1dGUgKi8KLSAgICBwcml2YXRlIFhNTEF0dHJpYnV0ZXNJbXBsIGZBdHRyaWJ1dGVzID0gbmV3IFhNTEF0dHJpYnV0ZXNJbXBsKCk7Ci0KLSAgICAvKioKLSAgICAgKiBTdGFjayBvZiBjb250ZW50IG9wZXJhdG9ycyAoZWl0aGVyICd8JyBvciAnLCcpIGluIGNoaWxkcmVuCi0gICAgICogY29udGVudC4KLSAgICAgKi8KLSAgICBwcml2YXRlIGludFtdIGZDb250ZW50U3RhY2sgPSBuZXcgaW50WzVdOwotCi0gICAgLyoqIFNpemUgb2YgY29udGVudCBzdGFjay4gKi8KLSAgICBwcml2YXRlIGludCBmQ29udGVudERlcHRoOwotCi0gICAgLyoqIFBhcmFtZXRlciBlbnRpdHkgc3RhY2sgdG8gY2hlY2sgd2VsbC1mb3JtZWRuZXNzLiAqLwotICAgIHByaXZhdGUgaW50W10gZlBFU3RhY2sgPSBuZXcgaW50WzVdOwotCi0KLSAgICAvKiogUGFyYW1ldGVyIGVudGl0eSBzdGFjayB0byByZXBvcnQgc3RhcnQvZW5kIGVudGl0eSBjYWxscy4gKi8KLSAgICBwcml2YXRlIGJvb2xlYW5bXSBmUEVSZXBvcnQgPSBuZXcgYm9vbGVhbls1XTsKLQotICAgIC8qKiBOdW1iZXIgb2Ygb3BlbmVkIHBhcmFtZXRlciBlbnRpdGllcy4gKi8KLSAgICBwcml2YXRlIGludCBmUEVEZXB0aDsKLQotICAgIC8qKiBNYXJrdXAgZGVwdGguICovCi0gICAgcHJpdmF0ZSBpbnQgZk1hcmtVcERlcHRoOwotCi0gICAgLyoqIE51bWJlciBvZiBvcGVuZWQgZXh0ZXJuYWwgZW50aXRpZXMuICovCi0gICAgcHJpdmF0ZSBpbnQgZkV4dEVudGl0eURlcHRoOwotCi0gICAgLyoqIE51bWJlciBvZiBvcGVuZWQgaW5jbHVkZSBzZWN0aW9ucy4gKi8KLSAgICBwcml2YXRlIGludCBmSW5jbHVkZVNlY3REZXB0aDsKLQotICAgIC8vIHRlbXBvcmFyeSB2YXJpYWJsZXMKLQotICAgIC8qKiBBcnJheSBvZiAzIHN0cmluZ3MuICovCi0gICAgcHJpdmF0ZSBTdHJpbmdbXSBmU3RyaW5ncyA9IG5ldyBTdHJpbmdbM107Ci0KLSAgICAvKiogU3RyaW5nLiAqLwotICAgIHByaXZhdGUgWE1MU3RyaW5nIGZTdHJpbmcgPSBuZXcgWE1MU3RyaW5nKCk7Ci0KLSAgICAvKiogU3RyaW5nIGJ1ZmZlci4gKi8KLSAgICBwcml2YXRlIFhNTFN0cmluZ0J1ZmZlciBmU3RyaW5nQnVmZmVyID0gbmV3IFhNTFN0cmluZ0J1ZmZlcigpOwotCi0gICAgLyoqIFN0cmluZyBidWZmZXIuICovCi0gICAgcHJpdmF0ZSBYTUxTdHJpbmdCdWZmZXIgZlN0cmluZ0J1ZmZlcjIgPSBuZXcgWE1MU3RyaW5nQnVmZmVyKCk7Ci0KLSAgICAvKiogTGl0ZXJhbCB0ZXh0LiAqLwotICAgIHByaXZhdGUgWE1MU3RyaW5nIGZMaXRlcmFsID0gbmV3IFhNTFN0cmluZygpOwotCi0gICAgLyoqIExpdGVyYWwgdGV4dC4gKi8KLSAgICBwcml2YXRlIFhNTFN0cmluZyBmTGl0ZXJhbDIgPSBuZXcgWE1MU3RyaW5nKCk7Ci0KLSAgICAvKiogRW51bWVyYXRpb24gdmFsdWVzLiAqLwotICAgIHByaXZhdGUgU3RyaW5nW10gZkVudW1lcmF0aW9uID0gbmV3IFN0cmluZ1s1XTsKLQotICAgIC8qKiBFbnVtZXJhdGlvbiB2YWx1ZXMgY291bnQuICovCi0gICAgcHJpdmF0ZSBpbnQgZkVudW1lcmF0aW9uQ291bnQ7Ci0KLSAgICAvKiogSWdub3JlIGNvbmRpdGlvbmFsIHNlY3Rpb24gYnVmZmVyLiAqLwotICAgIHByaXZhdGUgWE1MU3RyaW5nQnVmZmVyIGZJZ25vcmVDb25kaXRpb25hbEJ1ZmZlciA9IG5ldyBYTUxTdHJpbmdCdWZmZXIoMTI4KTsKLQotICAgIC8qKiBPYmplY3QgY29udGFpbnMgZ3JhbW1hciBpbmZvcm1hdGlvbiBmb3IgYSBub24tdmFsaWRhaW5nIHBhcnNlci4gKi8KLSAgICBEVERHcmFtbWFyIG52R3JhbW1hckluZm8gPSBudWxsOwotCi0gICAgYm9vbGVhbiBub25WYWxpZGF0aW5nTW9kZSA9IGZhbHNlOwotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKiBEZWZhdWx0IGNvbnN0cnVjdG9yLiAqLwotICAgIHB1YmxpYyBYTUxEVERTY2FubmVySW1wbCgpIHsKLSAgICB9IC8vIDxpbml0PigpCi0KLSAgICAvKiogQ29uc3RydWN0b3IgZm9yIGhlIHVzZSBvZiBub24tWE1MQ29tcG9uZW50TWFuYWdlcnMuICovCi0gICAgcHVibGljIFhNTERURFNjYW5uZXJJbXBsKFN5bWJvbFRhYmxlIHN5bWJvbFRhYmxlLAotICAgICAgICAgICAgWE1MRXJyb3JSZXBvcnRlciBlcnJvclJlcG9ydGVyLCBYTUxFbnRpdHlNYW5hZ2VyIGVudGl0eU1hbmFnZXIpIHsKLSAgICAgICAgZlN5bWJvbFRhYmxlID0gc3ltYm9sVGFibGU7Ci0gICAgICAgIGZFcnJvclJlcG9ydGVyID0gZXJyb3JSZXBvcnRlcjsKLSAgICAgICAgZkVudGl0eU1hbmFnZXIgPSBlbnRpdHlNYW5hZ2VyOwotICAgICAgICBlbnRpdHlNYW5hZ2VyLnNldFByb3BlcnR5KFNZTUJPTF9UQUJMRSwgZlN5bWJvbFRhYmxlKTsKLSAgICB9Ci0KLSAgICAvLwotICAgIC8vIFhNTERURFNjYW5uZXIgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSBpbnB1dCBzb3VyY2UuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaW5wdXRTb3VyY2UgVGhlIGlucHV0IHNvdXJjZSBvciBudWxsLgotICAgICAqCi0gICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBUaHJvd24gb24gaS9vIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldElucHV0U291cmNlKFhNTElucHV0U291cmNlIGlucHV0U291cmNlKSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgICAgICBpZiAoaW5wdXRTb3VyY2UgPT0gbnVsbCkgewotICAgICAgICAgICAgLy8gbm8gc3lzdGVtIGlkIHdhcyBhdmFpbGFibGUKLSAgICAgICAgICAgIGlmIChmRFRESGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZkRUREhhbmRsZXIuc3RhcnREVEQobnVsbCwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgZkRUREhhbmRsZXIuZW5kRFREKG51bGwpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKG5vblZhbGlkYXRpbmdNb2RlKXsKLSAgICAgICAgICAgICAgICBudkdyYW1tYXJJbmZvLnN0YXJ0RFREKG51bGwsbnVsbCk7Ci0gICAgICAgICAgICAgICAgbnZHcmFtbWFySW5mby5lbmREVEQobnVsbCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLSAgICAgICAgZkVudGl0eU1hbmFnZXIuc2V0RW50aXR5SGFuZGxlcih0aGlzKTsKLSAgICAgICAgZkVudGl0eU1hbmFnZXIuc3RhcnREVERFbnRpdHkoaW5wdXRTb3VyY2UpOwotICAgIH0gLy8gc2V0SW5wdXRTb3VyY2UoWE1MSW5wdXRTb3VyY2UpCi0KLQotICAgIHB1YmxpYyB2b2lkIHNldExpbWl0QW5hbHl6ZXIoWE1MTGltaXRBbmFseXplciBsaW1pdEFuYWx5emVyKSB7Ci0gICAgICAgIGZMaW1pdEFuYWx5emVyID0gbGltaXRBbmFseXplcjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTY2FucyB0aGUgZXh0ZXJuYWwgc3Vic2V0IG9mIHRoZSBkb2N1bWVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjb21wbGV0ZSBUcnVlIGlmIHRoZSBzY2FubmVyIHNob3VsZCBzY2FuIHRoZSBkb2N1bWVudAotICAgICAqICAgICAgICAgICAgICAgICBjb21wbGV0ZWx5LCBwdXNoaW5nIGFsbCBldmVudHMgdG8gdGhlIHJlZ2lzdGVyZWQKLSAgICAgKiAgICAgICAgICAgICAgICAgZG9jdW1lbnQgaGFuZGxlci4gQSB2YWx1ZSBvZiBmYWxzZSBpbmRpY2F0ZXMgdGhhdAotICAgICAqICAgICAgICAgICAgICAgICB0aGF0IHRoZSBzY2FubmVyIHNob3VsZCBvbmx5IHNjYW4gdGhlIG5leHQgcG9ydGlvbgotICAgICAqICAgICAgICAgICAgICAgICBvZiB0aGUgZG9jdW1lbnQgYW5kIHJldHVybi4gQSBzY2FubmVyIGluc3RhbmNlIGlzCi0gICAgICogICAgICAgICAgICAgICAgIHBlcm1pdHRlZCB0byBjb21wbGV0ZWx5IHNjYW4gYSBkb2N1bWVudCBpZiBpdCBkb2VzCi0gICAgICogICAgICAgICAgICAgICAgIG5vdCBzdXBwb3J0IHRoaXMgInB1bGwiIHNjYW5uaW5nIG1vZGVsLgotICAgICAqCi0gICAgICogQHJldHVybiBUcnVlIGlmIHRoZXJlIGlzIG1vcmUgdG8gc2NhbiwgZmFsc2Ugb3RoZXJ3aXNlLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIHNjYW5EVERFeHRlcm5hbFN1YnNldChib29sZWFuIGNvbXBsZXRlKQotICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgWE5JRXhjZXB0aW9uIHsKLQotICAgICAgICBmRW50aXR5TWFuYWdlci5zZXRFbnRpdHlIYW5kbGVyKHRoaXMpOwotICAgICAgICBpZiAoZlNjYW5uZXJTdGF0ZSA9PSBTQ0FOTkVSX1NUQVRFX1RFWFRfREVDTCkgewotICAgICAgICAgICAgZlNlZW5FeHRlcm5hbERURCA9IHRydWU7Ci0gICAgICAgICAgICBib29sZWFuIHRleHREZWNsID0gc2NhblRleHREZWNsKCk7Ci0gICAgICAgICAgICBpZiAoZlNjYW5uZXJTdGF0ZSA9PSBTQ0FOTkVSX1NUQVRFX0VORF9PRl9JTlBVVCkgewotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIC8vIG5leHQgc3RhdGUgaXMgbWFya3VwIGRlY2xzIHJlZ2FyZGxlc3Mgb2Ygd2hldGhlciB0aGVyZQotICAgICAgICAgICAgICAgIC8vIGlzIGEgVGV4dERlY2wgb3Igbm90Ci0gICAgICAgICAgICAgICAgc2V0U2Nhbm5lclN0YXRlKFNDQU5ORVJfU1RBVEVfTUFSS1VQX0RFQ0wpOwotICAgICAgICAgICAgICAgIGlmICh0ZXh0RGVjbCAmJiAhY29tcGxldGUpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIC8vIGtlZXAgZGlzcGF0Y2hpbmcgImV2ZW50cyIKLSAgICAgICAgZG8gewotICAgICAgICAgICAgaWYgKCFzY2FuRGVjbHMoY29tcGxldGUpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICB9IHdoaWxlIChjb21wbGV0ZSk7Ci0KLSAgICAgICAgLy8gcmV0dXJuIHRoYXQgdGhlcmUgaXMgbW9yZSB0byBzY2FuCi0gICAgICAgIHJldHVybiB0cnVlOwotCi0gICAgfSAvLyBzY2FuRFRERXh0ZXJuYWxTdWJzZXQoYm9vbGVhbik6Ym9vbGVhbgotCi0gICAgLyoqCi0gICAgICogU2NhbnMgdGhlIGludGVybmFsIHN1YnNldCBvZiB0aGUgZG9jdW1lbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29tcGxldGUgVHJ1ZSBpZiB0aGUgc2Nhbm5lciBzaG91bGQgc2NhbiB0aGUgZG9jdW1lbnQKLSAgICAgKiAgICAgICAgICAgICAgICAgY29tcGxldGVseSwgcHVzaGluZyBhbGwgZXZlbnRzIHRvIHRoZSByZWdpc3RlcmVkCi0gICAgICogICAgICAgICAgICAgICAgIGRvY3VtZW50IGhhbmRsZXIuIEEgdmFsdWUgb2YgZmFsc2UgaW5kaWNhdGVzIHRoYXQKLSAgICAgKiAgICAgICAgICAgICAgICAgdGhhdCB0aGUgc2Nhbm5lciBzaG91bGQgb25seSBzY2FuIHRoZSBuZXh0IHBvcnRpb24KLSAgICAgKiAgICAgICAgICAgICAgICAgb2YgdGhlIGRvY3VtZW50IGFuZCByZXR1cm4uIEEgc2Nhbm5lciBpbnN0YW5jZSBpcwotICAgICAqICAgICAgICAgICAgICAgICBwZXJtaXR0ZWQgdG8gY29tcGxldGVseSBzY2FuIGEgZG9jdW1lbnQgaWYgaXQgZG9lcwotICAgICAqICAgICAgICAgICAgICAgICBub3Qgc3VwcG9ydCB0aGlzICJwdWxsIiBzY2FubmluZyBtb2RlbC4KLSAgICAgKiBAcGFyYW0gc3RhbmRhbG9uZSBUcnVlIGlmIHRoZSBkb2N1bWVudCB3YXMgc3BlY2lmaWVkIGFzIHN0YW5kYWxvbmUuCi0gICAgICogICAgICAgICAgICAgICAgICAgVGhpcyB2YWx1ZSBpcyBpbXBvcnRhbnQgZm9yIHZlcmlmeWluZyBjZXJ0YWluCi0gICAgICogICAgICAgICAgICAgICAgICAgd2VsbC1mb3JtZWRuZXNzIGNvbnN0cmFpbnRzLgotICAgICAqIEBwYXJhbSBoYXNFeHRlcm5hbERURCBUcnVlIGlmIHRoZSBkb2N1bWVudCBoYXMgYW4gZXh0ZXJuYWwgRFRELgotICAgICAqICAgICAgICAgICAgICAgICAgICAgICBUaGlzIGFsbG93cyB0aGUgc2Nhbm5lciB0byBwcm9wZXJseSBub3RpZnkKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgdGhlIGhhbmRsZXIgb2YgdGhlIGVuZCBvZiB0aGUgRFREIGluIHRoZQotICAgICAqICAgICAgICAgICAgICAgICAgICAgICBhYnNlbmNlIG9mIGFuIGV4dGVybmFsIHN1YnNldC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVHJ1ZSBpZiB0aGVyZSBpcyBtb3JlIHRvIHNjYW4sIGZhbHNlIG90aGVyd2lzZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBzY2FuRFRESW50ZXJuYWxTdWJzZXQoYm9vbGVhbiBjb21wbGV0ZSwgYm9vbGVhbiBzdGFuZGFsb25lLAotICAgIGJvb2xlYW4gaGFzRXh0ZXJuYWxTdWJzZXQpCi0gICAgdGhyb3dzIElPRXhjZXB0aW9uLCBYTklFeGNlcHRpb24gewotICAgICAgICAvLyByZXNldCBlbnRpdHkgc2Nhbm5lcgotICAgICAgICAvL3h4eDpzdGF4IGdldFRleHQoKSBpcyBzdXBwb3NlZCB0byByZXR1cm4gb25seSBEVEQgaW50ZXJuYWwgc3Vic2V0Ci0gICAgICAgIC8vc2hvdWxkbid0IHdlIHJlY29yZCBwb3NpdGlvbiBoZXJlIGJlZm9yZSB3ZSBnbyBhaGVhZCA/PwotCi0gICAgICAgIGZFbnRpdHlTY2FubmVyID0gKFhNTEVudGl0eVNjYW5uZXIpZkVudGl0eU1hbmFnZXIuZ2V0RW50aXR5U2Nhbm5lcigpOwotICAgICAgICBmRW50aXR5TWFuYWdlci5zZXRFbnRpdHlIYW5kbGVyKHRoaXMpOwotICAgICAgICBmU3RhbmRhbG9uZSA9IHN0YW5kYWxvbmU7Ci0gICAgICAgIC8vU3lzdGVtLm91dC5wcmludGxuKCJzdGF0ZSIrZlNjYW5uZXJTdGF0ZSk7Ci0gICAgICAgIGlmIChmU2Nhbm5lclN0YXRlID09IFNDQU5ORVJfU1RBVEVfVEVYVF9ERUNMKSB7Ci0gICAgICAgICAgICAvLyBjYWxsIGhhbmRsZXIKLSAgICAgICAgICAgIGlmIChmRFRESGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZkRUREhhbmRsZXIuc3RhcnREVEQoZkVudGl0eVNjYW5uZXIsIG51bGwpOwotICAgICAgICAgICAgICAgIGZTdGFydERURENhbGxlZCA9IHRydWU7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmIChub25WYWxpZGF0aW5nTW9kZSl7Ci0gICAgICAgICAgICAgICAgZlN0YXJ0RFREQ2FsbGVkID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICBudkdyYW1tYXJJbmZvLnN0YXJ0RFREKGZFbnRpdHlTY2FubmVyLG51bGwpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gc2V0IHN0YXJ0aW5nIHN0YXRlIGZvciBpbnRlcm5hbCBzdWJzZXQKLSAgICAgICAgICAgIHNldFNjYW5uZXJTdGF0ZShTQ0FOTkVSX1NUQVRFX01BUktVUF9ERUNMKTsKLSAgICAgICAgfQotICAgICAgICAvLyBrZWVwIGRpc3BhdGNoaW5nICJldmVudHMiCi0gICAgICAgIGRvIHsKLSAgICAgICAgICAgIGlmICghc2NhbkRlY2xzKGNvbXBsZXRlKSkgewotICAgICAgICAgICAgICAgIC8vIGNhbGwgaGFuZGxlcgotICAgICAgICAgICAgICAgIGlmIChmRFRESGFuZGxlciAhPSBudWxsICYmIGhhc0V4dGVybmFsU3Vic2V0ID09IGZhbHNlKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZEVERIYW5kbGVyLmVuZERURChudWxsKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaWYgKG5vblZhbGlkYXRpbmdNb2RlICYmIGhhc0V4dGVybmFsU3Vic2V0ID09IGZhbHNlICl7Ci0gICAgICAgICAgICAgICAgICAgIG52R3JhbW1hckluZm8uZW5kRFREKG51bGwpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvLyB3ZSdyZSBkb25lLCBzZXQgc3RhcnRpbmcgc3RhdGUgZm9yIGV4dGVybmFsIHN1YnNldAotICAgICAgICAgICAgICAgIHNldFNjYW5uZXJTdGF0ZShTQ0FOTkVSX1NUQVRFX1RFWFRfREVDTCk7Ci0gICAgICAgICAgICAgICAgLy8gd2UncmUgZG9uZSBzY2FubmluZyBEVEQuCi0gICAgICAgICAgICAgICAgZkxpbWl0QW5hbHl6ZXIucmVzZXQoWE1MU2VjdXJpdHlNYW5hZ2VyLkxpbWl0LkdFTkVSQUxfRU5USVRZX1NJWkVfTElNSVQpOwotICAgICAgICAgICAgICAgIGZMaW1pdEFuYWx5emVyLnJlc2V0KFhNTFNlY3VyaXR5TWFuYWdlci5MaW1pdC5UT1RBTF9FTlRJVFlfU0laRV9MSU1JVCk7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICB9IHdoaWxlIChjb21wbGV0ZSk7Ci0KLSAgICAgICAgLy8gcmV0dXJuIHRoYXQgdGhlcmUgaXMgbW9yZSB0byBzY2FuCi0gICAgICAgIHJldHVybiB0cnVlOwotCi0gICAgfSAvLyBzY2FuRFRESW50ZXJuYWxTdWJzZXQoYm9vbGVhbixib29sZWFuLGJvb2xlYW4pOmJvb2xlYW4KLQotICAgIC8qKgotICAgICAqIFNraXAgdGhlIERURCBpZiBqYXZheC54bWwuc3RyZWFtLnN1cHBvcnREVEQgaXMgZmFsc2UuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc3VwcG9ydERURCBUaGUgdmFsdWUgb2YgdGhlIHByb3BlcnR5IGphdmF4LnhtbC5zdHJlYW0uc3VwcG9ydERURC4KLSAgICAgKiBAcmV0dXJuIHRydWUgaWYgRFREIGlzIHNraXBwZWQsIGZhbHNlIG90aGVyd2lzZS4KLSAgICAgKiBAdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gaWYgaS9vIGVycm9yIG9jY3VycwotICAgICAqLwotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyBib29sZWFuIHNraXBEVEQoYm9vbGVhbiBzdXBwb3J0RFREKSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgICAgICBpZiAoc3VwcG9ydERURCkKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLQotICAgICAgICBmU3RyaW5nQnVmZmVyLmNsZWFyKCk7Ci0gICAgICAgIHdoaWxlIChmRW50aXR5U2Nhbm5lci5zY2FuRGF0YSgiXSIsIGZTdHJpbmdCdWZmZXIpKSB7Ci0gICAgICAgICAgICBpbnQgYyA9IGZFbnRpdHlTY2FubmVyLnBlZWtDaGFyKCk7Ci0gICAgICAgICAgICBpZiAoYyAhPSAtMSkgewotICAgICAgICAgICAgICAgIGlmIChYTUxDaGFyLmlzSGlnaFN1cnJvZ2F0ZShjKSkgewotICAgICAgICAgICAgICAgICAgICBzY2FuU3Vycm9nYXRlcyhmU3RyaW5nQnVmZmVyKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaWYgKGlzSW52YWxpZExpdGVyYWwoYykpIHsKLSAgICAgICAgICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiSW52YWxpZENoYXJJbkRURCIsCi0gICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBJbnRlZ2VyLnRvSGV4U3RyaW5nKGMpIH0pOwotICAgICAgICAgICAgICAgICAgICBmRW50aXR5U2Nhbm5lci5zY2FuQ2hhcihudWxsKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZkVudGl0eVNjYW5uZXIuZkN1cnJlbnRFbnRpdHkucG9zaXRpb24tLTsKLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotCi0gICAgLy8KLSAgICAvLyBYTUxDb21wb25lbnQgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiByZXNldAotICAgICAqCi0gICAgICogQHBhcmFtIGNvbXBvbmVudE1hbmFnZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCByZXNldChYTUxDb21wb25lbnRNYW5hZ2VyIGNvbXBvbmVudE1hbmFnZXIpCi0gICAgdGhyb3dzIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gewotCi0gICAgICAgIHN1cGVyLnJlc2V0KGNvbXBvbmVudE1hbmFnZXIpOwotICAgICAgICBpbml0KCk7Ci0KLSAgICB9IC8vIHJlc2V0KFhNTENvbXBvbmVudE1hbmFnZXIpCi0KLSAgICAvLyB0aGlzIGlzIG1hZGUgZm9yIHNvbWV0aGluZyBsaWtlIFhNTERURExvYWRlci0tWE1MQ29tcG9uZW50TWFuYWdlci1mcmVlIG9wZXJhdGlvbi4uLgotICAgIHB1YmxpYyB2b2lkIHJlc2V0KCkgewotICAgICAgICBzdXBlci5yZXNldCgpOwotICAgICAgICBpbml0KCk7Ci0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCByZXNldChQcm9wZXJ0eU1hbmFnZXIgcHJvcHMpIHsKLSAgICAgICAgc2V0UHJvcGVydHlNYW5hZ2VyKHByb3BzKTsKLSAgICAgICAgc3VwZXIucmVzZXQocHJvcHMpOwotICAgICAgICBpbml0KCkgOwotICAgICAgICBub25WYWxpZGF0aW5nTW9kZSA9IHRydWU7Ci0gICAgICAgIC8vUmV2aXNpdCA6IENyZWF0ZSBuZXcgZ3JhbW1hciB1bnRpbCB3ZSBpbXBsZW1lbnQgR3JhbW1hclBvb2wuCi0gICAgICAgIG52R3JhbW1hckluZm8gPSBuZXcgRFRER3JhbW1hcihmU3ltYm9sVGFibGUpOwotICAgIH0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGEgbGlzdCBvZiBmZWF0dXJlIGlkZW50aWZpZXJzIHRoYXQgYXJlIHJlY29nbml6ZWQgYnkKLSAgICAgKiB0aGlzIGNvbXBvbmVudC4gVGhpcyBtZXRob2QgbWF5IHJldHVybiBudWxsIGlmIG5vIGZlYXR1cmVzCi0gICAgICogYXJlIHJlY29nbml6ZWQgYnkgdGhpcyBjb21wb25lbnQuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZ1tdIGdldFJlY29nbml6ZWRGZWF0dXJlcygpIHsKLSAgICAgICAgcmV0dXJuIChTdHJpbmdbXSkoUkVDT0dOSVpFRF9GRUFUVVJFUy5jbG9uZSgpKTsKLSAgICB9IC8vIGdldFJlY29nbml6ZWRGZWF0dXJlcygpOlN0cmluZ1tdCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGEgbGlzdCBvZiBwcm9wZXJ0eSBpZGVudGlmaWVycyB0aGF0IGFyZSByZWNvZ25pemVkIGJ5Ci0gICAgICogdGhpcyBjb21wb25lbnQuIFRoaXMgbWV0aG9kIG1heSByZXR1cm4gbnVsbCBpZiBubyBwcm9wZXJ0aWVzCi0gICAgICogYXJlIHJlY29nbml6ZWQgYnkgdGhpcyBjb21wb25lbnQuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZ1tdIGdldFJlY29nbml6ZWRQcm9wZXJ0aWVzKCkgewotICAgICAgICByZXR1cm4gKFN0cmluZ1tdKShSRUNPR05JWkVEX1BST1BFUlRJRVMuY2xvbmUoKSk7Ci0gICAgfSAvLyBnZXRSZWNvZ25pemVkUHJvcGVydGllcygpOlN0cmluZ1tdCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBkZWZhdWx0IHN0YXRlIGZvciBhIGZlYXR1cmUsIG9yIG51bGwgaWYgdGhpcwotICAgICAqIGNvbXBvbmVudCBkb2VzIG5vdCB3YW50IHRvIHJlcG9ydCBhIGRlZmF1bHQgdmFsdWUgZm9yIHRoaXMKLSAgICAgKiBmZWF0dXJlLgotICAgICAqCi0gICAgICogQHBhcmFtIGZlYXR1cmVJZCBUaGUgZmVhdHVyZSBpZGVudGlmaWVyLgotICAgICAqCi0gICAgICogQHNpbmNlIFhlcmNlcyAyLjIuMAotICAgICAqLwotICAgIHB1YmxpYyBCb29sZWFuIGdldEZlYXR1cmVEZWZhdWx0KFN0cmluZyBmZWF0dXJlSWQpIHsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBSRUNPR05JWkVEX0ZFQVRVUkVTLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICBpZiAoUkVDT0dOSVpFRF9GRUFUVVJFU1tpXS5lcXVhbHMoZmVhdHVyZUlkKSkgewotICAgICAgICAgICAgICAgIHJldHVybiBGRUFUVVJFX0RFRkFVTFRTW2ldOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0gLy8gZ2V0RmVhdHVyZURlZmF1bHQoU3RyaW5nKTpCb29sZWFuCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBkZWZhdWx0IHN0YXRlIGZvciBhIHByb3BlcnR5LCBvciBudWxsIGlmIHRoaXMKLSAgICAgKiBjb21wb25lbnQgZG9lcyBub3Qgd2FudCB0byByZXBvcnQgYSBkZWZhdWx0IHZhbHVlIGZvciB0aGlzCi0gICAgICogcHJvcGVydHkuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcHJvcGVydHlJZCBUaGUgcHJvcGVydHkgaWRlbnRpZmllci4KLSAgICAgKgotICAgICAqIEBzaW5jZSBYZXJjZXMgMi4yLjAKLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0IGdldFByb3BlcnR5RGVmYXVsdChTdHJpbmcgcHJvcGVydHlJZCkgewotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IFJFQ09HTklaRURfUFJPUEVSVElFUy5sZW5ndGg7IGkrKykgewotICAgICAgICAgICAgaWYgKFJFQ09HTklaRURfUFJPUEVSVElFU1tpXS5lcXVhbHMocHJvcGVydHlJZCkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gUFJPUEVSVFlfREVGQVVMVFNbaV07Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfSAvLyBnZXRQcm9wZXJ0eURlZmF1bHQoU3RyaW5nKTpPYmplY3QKLQotICAgIC8vCi0gICAgLy8gWE1MRFREU291cmNlIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogc2V0RFRESGFuZGxlcgotICAgICAqCi0gICAgICogQHBhcmFtIGR0ZEhhbmRsZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXREVERIYW5kbGVyKFhNTERUREhhbmRsZXIgZHRkSGFuZGxlcikgewotICAgICAgICBmRFRESGFuZGxlciA9IGR0ZEhhbmRsZXI7Ci0gICAgfSAvLyBzZXREVERIYW5kbGVyKFhNTERUREhhbmRsZXIpCi0KLSAgICAvKioKLSAgICAgKiBnZXREVERIYW5kbGVyCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRoZSBYTUxEVERIYW5kbGVyCi0gICAgICovCi0gICAgcHVibGljIFhNTERUREhhbmRsZXIgZ2V0RFRESGFuZGxlcigpIHsKLSAgICAgICAgcmV0dXJuIGZEVERIYW5kbGVyOwotICAgIH0gLy8gZ2V0RFRESGFuZGxlcigpOiAgWE1MRFRESGFuZGxlcgotCi0gICAgLy8KLSAgICAvLyBYTUxEVERDb250ZW50TW9kZWxTb3VyY2UgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBzZXREVERDb250ZW50TW9kZWxIYW5kbGVyCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZHRkQ29udGVudE1vZGVsSGFuZGxlcgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldERURENvbnRlbnRNb2RlbEhhbmRsZXIoWE1MRFREQ29udGVudE1vZGVsSGFuZGxlcgotICAgIGR0ZENvbnRlbnRNb2RlbEhhbmRsZXIpIHsKLSAgICAgICAgZkRURENvbnRlbnRNb2RlbEhhbmRsZXIgPSBkdGRDb250ZW50TW9kZWxIYW5kbGVyOwotICAgIH0gLy8gc2V0RFREQ29udGVudE1vZGVsSGFuZGxlcgotCi0gICAgLyoqCi0gICAgICogZ2V0RFREQ29udGVudE1vZGVsSGFuZGxlcgotICAgICAqCi0gICAgICogQHJldHVybiBYTUxEVERDb250ZW50TW9kZWxIYW5kbGVyCi0gICAgICovCi0gICAgcHVibGljIFhNTERURENvbnRlbnRNb2RlbEhhbmRsZXIgZ2V0RFREQ29udGVudE1vZGVsSGFuZGxlcigpIHsKLSAgICAgICAgcmV0dXJuIGZEVERDb250ZW50TW9kZWxIYW5kbGVyIDsKLSAgICB9IC8vIHNldERURENvbnRlbnRNb2RlbEhhbmRsZXIKLQotICAgIC8vCi0gICAgLy8gWE1MRW50aXR5SGFuZGxlciBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIG5vdGlmaWVzIG9mIHRoZSBzdGFydCBvZiBhbiBlbnRpdHkuIFRoZSBEVEQgaGFzIHRoZQotICAgICAqIHBzZXVkby1uYW1lIG9mICJbZHRkXSIgcGFyYW1ldGVyIGVudGl0eSBuYW1lcyBzdGFydCB3aXRoICclJzsgYW5kCi0gICAgICogZ2VuZXJhbCBlbnRpdGllcyBhcmUganVzdCBzcGVjaWZpZWQgYnkgdGhlaXIgbmFtZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lICAgICBUaGUgbmFtZSBvZiB0aGUgZW50aXR5LgotICAgICAqIEBwYXJhbSBpZGVudGlmaWVyIFRoZSByZXNvdXJjZSBpZGVudGlmaWVyLgotICAgICAqIEBwYXJhbSBlbmNvZGluZyBUaGUgYXV0by1kZXRlY3RlZCBJQU5BIGVuY29kaW5nIG5hbWUgb2YgdGhlIGVudGl0eQotICAgICAqICAgICAgICAgICAgICAgICBzdHJlYW0uIFRoaXMgdmFsdWUgd2lsbCBiZSBudWxsIGluIHRob3NlIHNpdHVhdGlvbnMKLSAgICAgKiAgICAgICAgICAgICAgICAgd2hlcmUgdGhlIGVudGl0eSBlbmNvZGluZyBpcyBub3QgYXV0by1kZXRlY3RlZCAoZS5nLgotICAgICAqICAgICAgICAgICAgICAgICBpbnRlcm5hbCBlbnRpdGllcyBvciBhIGRvY3VtZW50IGVudGl0eSB0aGF0IGlzCi0gICAgICogICAgICAgICAgICAgICAgIHBhcnNlZCBmcm9tIGEgamF2YS5pby5SZWFkZXIpLgotICAgICAqIEBwYXJhbSBhdWdzICAgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnRFbnRpdHkoU3RyaW5nIG5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MUmVzb3VyY2VJZGVudGlmaWVyIGlkZW50aWZpZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGVuY29kaW5nLCBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotCi0gICAgICAgIHN1cGVyLnN0YXJ0RW50aXR5KG5hbWUsIGlkZW50aWZpZXIsIGVuY29kaW5nLCBhdWdzKTsKLQotICAgICAgICBib29sZWFuIGR0ZEVudGl0eSA9IG5hbWUuZXF1YWxzKCJbZHRkXSIpOwotICAgICAgICBpZiAoZHRkRW50aXR5KSB7Ci0gICAgICAgICAgICAvLyBjYWxsIGhhbmRsZXIKLSAgICAgICAgICAgIGlmIChmRFRESGFuZGxlciAhPSBudWxsICYmICFmU3RhcnREVERDYWxsZWQgKSB7Ci0gICAgICAgICAgICAgICAgZkRUREhhbmRsZXIuc3RhcnREVEQoZkVudGl0eVNjYW5uZXIsIG51bGwpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKGZEVERIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmRFRESGFuZGxlci5zdGFydEV4dGVybmFsU3Vic2V0KGlkZW50aWZpZXIsbnVsbCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmRW50aXR5TWFuYWdlci5zdGFydEV4dGVybmFsU3Vic2V0KCk7Ci0gICAgICAgICAgICBmRW50aXR5U3RvcmUuc3RhcnRFeHRlcm5hbFN1YnNldCgpOwotICAgICAgICAgICAgZkV4dEVudGl0eURlcHRoKys7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAobmFtZS5jaGFyQXQoMCkgPT0gJyUnKSB7Ci0gICAgICAgICAgICBwdXNoUEVTdGFjayhmTWFya1VwRGVwdGgsIGZSZXBvcnRFbnRpdHkpOwotICAgICAgICAgICAgaWYgKGZFbnRpdHlTY2FubmVyLmlzRXh0ZXJuYWwoKSkgewotICAgICAgICAgICAgICAgIGZFeHRFbnRpdHlEZXB0aCsrOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gY2FsbCBoYW5kbGVyCi0gICAgICAgIGlmIChmRFRESGFuZGxlciAhPSBudWxsICYmICFkdGRFbnRpdHkgJiYgZlJlcG9ydEVudGl0eSkgewotICAgICAgICAgICAgZkRUREhhbmRsZXIuc3RhcnRQYXJhbWV0ZXJFbnRpdHkobmFtZSwgaWRlbnRpZmllciwgZW5jb2RpbmcsIG51bGwpOwotICAgICAgICB9Ci0KLSAgICB9IC8vIHN0YXJ0RW50aXR5KFN0cmluZyxYTUxSZXNvdXJjZUlkZW50aWZpZXIsU3RyaW5nKQotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2Qgbm90aWZpZXMgdGhlIGVuZCBvZiBhbiBlbnRpdHkuIFRoZSBEVEQgaGFzIHRoZSBwc2V1ZG8tbmFtZQotICAgICAqIG9mICJbZHRkXSIgcGFyYW1ldGVyIGVudGl0eSBuYW1lcyBzdGFydCB3aXRoICclJzsgYW5kIGdlbmVyYWwgZW50aXRpZXMKLSAgICAgKiBhcmUganVzdCBzcGVjaWZpZWQgYnkgdGhlaXIgbmFtZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBlbnRpdHkuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kRW50aXR5KFN0cmluZyBuYW1lLCBBdWdtZW50YXRpb25zIGF1Z3MpCi0gICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewotCi0gICAgICAgIHN1cGVyLmVuZEVudGl0eShuYW1lLCBhdWdzKTsKLQotICAgICAgICAvLyBpZiB0aGVyZSBpcyBubyBkYXRhIGFmdGVyIHRoZSBkb2N0eXBlCi0gICAgICAgIC8vCi0gICAgICAgIGlmIChmU2Nhbm5lclN0YXRlID09IFNDQU5ORVJfU1RBVEVfRU5EX09GX0lOUFVUKQotICAgICAgICAgICAgcmV0dXJuOwotCi0gICAgICAgIC8vIEhhbmRsZSBlbmQgb2YgUEUKLSAgICAgICAgYm9vbGVhbiByZXBvcnRFbnRpdHkgPSBmUmVwb3J0RW50aXR5OwotICAgICAgICBpZiAobmFtZS5zdGFydHNXaXRoKCIlIikpIHsKLSAgICAgICAgICAgIHJlcG9ydEVudGl0eSA9IHBlZWtSZXBvcnRFbnRpdHkoKTsKLSAgICAgICAgICAgIC8vIGNoZWNrIHdlbGwtZm9ybWVkbmVzcyBvZiB0aGUgZW5pdHkKLSAgICAgICAgICAgIGludCBzdGFydE1hcmtVcERlcHRoID0gcG9wUEVTdGFjaygpOwotICAgICAgICAgICAgLy8gdGhyb3cgZmF0YWxFcnJvciBpZiB0aGlzIGVudGl0eSB3YXMgaW5jb21wbGV0ZSBhbmQKLSAgICAgICAgICAgIC8vIHdhcyBhIGZyZWVzdGFuZGluZyBkZWNsCi0gICAgICAgICAgICBpZihzdGFydE1hcmtVcERlcHRoID09IDAgJiYKLSAgICAgICAgICAgIHN0YXJ0TWFya1VwRGVwdGggPCBmTWFya1VwRGVwdGgpIHsKLSAgICAgICAgICAgICAgICBmRXJyb3JSZXBvcnRlci5yZXBvcnRFcnJvcihYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sCi0gICAgICAgICAgICAgICAgIklMTF9GT1JNRURfUEFSQU1FVEVSX0VOVElUWV9XSEVOX1VTRURfSU5fREVDTCIsCi0gICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdeyBmRW50aXR5TWFuYWdlci5mQ3VycmVudEVudGl0eS5uYW1lfSwKLSAgICAgICAgICAgICAgICBYTUxFcnJvclJlcG9ydGVyLlNFVkVSSVRZX0ZBVEFMX0VSUk9SKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChzdGFydE1hcmtVcERlcHRoICE9IGZNYXJrVXBEZXB0aCkgewotICAgICAgICAgICAgICAgIHJlcG9ydEVudGl0eSA9IGZhbHNlOwotICAgICAgICAgICAgICAgIGlmIChmVmFsaWRhdGlvbikgewotICAgICAgICAgICAgICAgICAgICAvLyBQcm9wZXIgbmVzdGluZyBvZiBwYXJhbWV0ZXIgZW50aXRpZXMgaXMgYSBWYWxpZGl0eSBDb25zdHJhaW50Ci0gICAgICAgICAgICAgICAgICAgIC8vIGFuZCBtdXN0IG5vdCBiZSBlbmZvcmNlZCB3aGVuIHZhbGlkYXRpb24gaXMgb2ZmCi0gICAgICAgICAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgIkltcHJvcGVyRGVjbGFyYXRpb25OZXN0aW5nIiwKLSAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdeyBuYW1lIH0sCi0gICAgICAgICAgICAgICAgICAgIFhNTEVycm9yUmVwb3J0ZXIuU0VWRVJJVFlfRVJST1IpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChmRW50aXR5U2Nhbm5lci5pc0V4dGVybmFsKCkpIHsKLSAgICAgICAgICAgICAgICBmRXh0RW50aXR5RGVwdGgtLTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIGNhbGwgaGFuZGxlcgotICAgICAgICBib29sZWFuIGR0ZEVudGl0eSA9IG5hbWUuZXF1YWxzKCJbZHRkXSIpOwotICAgICAgICBpZiAoZkRUREhhbmRsZXIgIT0gbnVsbCAmJiAhZHRkRW50aXR5ICYmIHJlcG9ydEVudGl0eSkgewotICAgICAgICAgICAgZkRUREhhbmRsZXIuZW5kUGFyYW1ldGVyRW50aXR5KG5hbWUsIG51bGwpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gZW5kIERURAotICAgICAgICBpZiAoZHRkRW50aXR5KSB7Ci0gICAgICAgICAgICBpZiAoZkluY2x1ZGVTZWN0RGVwdGggIT0gMCkgewotICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIkluY2x1ZGVTZWN0VW50ZXJtaW5hdGVkIiwgbnVsbCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmU2Nhbm5lclN0YXRlID0gU0NBTk5FUl9TVEFURV9FTkRfT0ZfSU5QVVQ7Ci0gICAgICAgICAgICAvLyBjYWxsIGhhbmRsZXIKLSAgICAgICAgICAgIGZFbnRpdHlNYW5hZ2VyLmVuZEV4dGVybmFsU3Vic2V0KCk7Ci0gICAgICAgICAgICBmRW50aXR5U3RvcmUuZW5kRXh0ZXJuYWxTdWJzZXQoKTsKLQotICAgICAgICAgICAgaWYgKGZEVERIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmRFRESGFuZGxlci5lbmRFeHRlcm5hbFN1YnNldChudWxsKTsKLSAgICAgICAgICAgICAgICBmRFRESGFuZGxlci5lbmREVEQobnVsbCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmRXh0RW50aXR5RGVwdGgtLTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vWE1MIChEb2N1bWVudCBFbnRpdHkpIGlzIHRoZSBsYXN0IG9wZW5lZCBlbnRpdHksIGhvd2V2ZXIKLSAgICAgICAgLy9pZiBmb3Igc29tZSByZWFzb24gRFREIFNjYW5uZXIgcmVjZWl2ZXMgdGhpcyBjYWxsYmFjawotICAgICAgICAvL3RoZXJlIGlzIHNvbWV0aGluZyB3cm9uZyAocHJvYmFibHkgaW52YWxpZCBYTUwpLCB0aHJvdyBleGNlcHRpb24uCi0gICAgICAgIC8vb3IKLSAgICAgICAgLy9Gb3Igc3RhbmRhbG9uZSBEVEQgbG9hZGVyLCBpdCBtaWdodCBiZSB0aGUgbGFzdCBvcGVuZWQgZW50aXR5Ci0gICAgICAgIC8vYW5kIGlmIHRoaXMgaXMgdGhlIGxhc3Qgb3BlbmVkIGVudGl0eSBhbmQgZk1hcmtVcERlcHRoICE9IDAgb3IKLSAgICAgICAgLy9mSW5jbHVkZVNlY3REZXB0aCAhPSAwIG9yIGZFeHRFbnRpdHlEZXB0aCAhPSAwIHRocm93IEV4Y2VwdGlvbgotICAgICAgICBpZiAoYXVncyAhPSBudWxsICYmIEJvb2xlYW4uVFJVRS5lcXVhbHMoYXVncy5nZXRJdGVtKENvbnN0YW50cy5MQVNUX0VOVElUWSkpCi0gICAgICAgICAgICAmJiAoIGZNYXJrVXBEZXB0aCAhPSAwIHx8IGZFeHRFbnRpdHlEZXB0aCAhPTAgfHwgZkluY2x1ZGVTZWN0RGVwdGggIT0gMCkpewotICAgICAgICAgICAgdGhyb3cgbmV3IEVPRkV4Y2VwdGlvbigpOwotICAgICAgICB9Ci0KLSAgICB9IC8vIGVuZEVudGl0eShTdHJpbmcpCi0KLSAgICAvLyBoZWxwZXIgbWV0aG9kcwotCi0gICAgLyoqCi0gICAgICogU2V0cyB0aGUgc2Nhbm5lciBzdGF0ZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzdGF0ZSBUaGUgbmV3IHNjYW5uZXIgc3RhdGUuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGZpbmFsIHZvaWQgc2V0U2Nhbm5lclN0YXRlKGludCBzdGF0ZSkgewotCi0gICAgICAgIGZTY2FubmVyU3RhdGUgPSBzdGF0ZTsKLSAgICAgICAgaWYgKERFQlVHX1NDQU5ORVJfU1RBVEUpIHsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIiMjIyBzZXRTY2FubmVyU3RhdGU6ICIpOwotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludChnZXRTY2FubmVyU3RhdGVOYW1lKHN0YXRlKSk7Ci0gICAgICAgICAgICAvL1N5c3RlbS5vdXQucHJpbnRsbigpOwotICAgICAgICB9Ci0KLSAgICB9IC8vIHNldFNjYW5uZXJTdGF0ZShpbnQpCi0KLSAgICAvLwotICAgIC8vIFByaXZhdGUgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKiogUmV0dXJucyB0aGUgc2Nhbm5lciBzdGF0ZSBuYW1lLiAqLwotICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBnZXRTY2FubmVyU3RhdGVOYW1lKGludCBzdGF0ZSkgewotCi0gICAgICAgIGlmIChERUJVR19TQ0FOTkVSX1NUQVRFKSB7Ci0gICAgICAgICAgICBzd2l0Y2ggKHN0YXRlKSB7Ci0gICAgICAgICAgICAgICAgY2FzZSBTQ0FOTkVSX1NUQVRFX0VORF9PRl9JTlBVVDogcmV0dXJuICJTQ0FOTkVSX1NUQVRFX0VORF9PRl9JTlBVVCI7Ci0gICAgICAgICAgICAgICAgY2FzZSBTQ0FOTkVSX1NUQVRFX1RFWFRfREVDTDogcmV0dXJuICJTQ0FOTkVSX1NUQVRFX1RFWFRfREVDTCI7Ci0gICAgICAgICAgICAgICAgY2FzZSBTQ0FOTkVSX1NUQVRFX01BUktVUF9ERUNMOiByZXR1cm4gIlNDQU5ORVJfU1RBVEVfTUFSS1VQX0RFQ0wiOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuICI/Pz8gKCIrc3RhdGUrJyknOwotCi0gICAgfSAvLyBnZXRTY2FubmVyU3RhdGVOYW1lKGludCk6U3RyaW5nCi0KLSAgICBwcm90ZWN0ZWQgZmluYWwgYm9vbGVhbiBzY2FubmluZ0ludGVybmFsU3Vic2V0KCkgewotICAgICAgICByZXR1cm4gZkV4dEVudGl0eURlcHRoID09IDA7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogc3RhcnQgYSBwYXJhbWV0ZXIgZW50aXR5IGRlYWxpbmcgd2l0aCB0aGUgdGV4dGRlY2wgaWYgdGhlcmUgaXMgYW55Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgcGFyYW1ldGVyIGVudGl0eSB0byBzdGFydCAod2l0aG91dCB0aGUgJyUnKQotICAgICAqIEBwYXJhbSBsaXRlcmFsIFdoZXRoZXIgdGhpcyBpcyBoYXBwZW5pbmcgd2l0aGluIGEgbGl0ZXJhbAotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIHN0YXJ0UEUoU3RyaW5nIG5hbWUsIGJvb2xlYW4gbGl0ZXJhbCkKLSAgICB0aHJvd3MgSU9FeGNlcHRpb24sIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIGludCBkZXB0aCA9IGZQRURlcHRoOwotICAgICAgICBTdHJpbmcgcE5hbWUgPSAiJSIrbmFtZTsKLSAgICAgICAgaWYgKGZWYWxpZGF0aW9uICYmICFmRW50aXR5U3RvcmUuaXNEZWNsYXJlZEVudGl0eShwTmFtZSkpIHsKLSAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKCBYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sIkVudGl0eU5vdERlY2xhcmVkIiwKLSAgICAgICAgICAgIG5ldyBPYmplY3RbXXtuYW1lfSwgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9FUlJPUik7Ci0gICAgICAgIH0KLSAgICAgICAgZkVudGl0eU1hbmFnZXIuc3RhcnRFbnRpdHkoZmFsc2UsIGZTeW1ib2xUYWJsZS5hZGRTeW1ib2wocE5hbWUpLAotICAgICAgICBsaXRlcmFsKTsKLSAgICAgICAgLy8gaWYgd2UgYWN0dWFsbHkgZ290IGEgbmV3IGVudGl0eSBhbmQgaXQncyBleHRlcm5hbAotICAgICAgICAvLyBwYXJzZSB0ZXh0IGRlY2wgaWYgdGhlcmUgaXMgYW55Ci0gICAgICAgIGlmIChkZXB0aCAhPSBmUEVEZXB0aCAmJiBmRW50aXR5U2Nhbm5lci5pc0V4dGVybmFsKCkpIHsKLSAgICAgICAgICAgIHNjYW5UZXh0RGVjbCgpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRGlzcGF0Y2ggYW4gWE1MICJldmVudCIuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29tcGxldGUgVHJ1ZSBpZiB0aGlzIG1ldGhvZCBpcyBpbnRlbmRlZCB0byBzY2FuCi0gICAgICogICAgICAgICAgICAgICAgIGFuZCBkaXNwYXRjaCBhcyBtdWNoIGFzIHBvc3NpYmxlLgotICAgICAqCi0gICAgICogQHJldHVybiBUcnVlIGlmIGEgVGV4dERlY2wgd2FzIHNjYW5uZWQuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uICBUaHJvd24gb24gaS9vIGVycm9yLgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBvbiBwYXJzZSBlcnJvci4KLSAgICAgKgotICAgICAqLwotICAgIHByb3RlY3RlZCBmaW5hbCBib29sZWFuIHNjYW5UZXh0RGVjbCgpCi0gICAgdGhyb3dzIElPRXhjZXB0aW9uLCBYTklFeGNlcHRpb24gewotCi0gICAgICAgIC8vIHNjYW4gWE1MRGVjbAotICAgICAgICBib29sZWFuIHRleHREZWNsID0gZmFsc2U7Ci0gICAgICAgIGlmIChmRW50aXR5U2Nhbm5lci5za2lwU3RyaW5nKCI8P3htbCIpKSB7Ci0gICAgICAgICAgICBmTWFya1VwRGVwdGgrKzsKLSAgICAgICAgICAgIC8vIE5PVEU6IHNwZWNpYWwgY2FzZSB3aGVyZSBkb2N1bWVudCBzdGFydHMgd2l0aCBhIFBJCi0gICAgICAgICAgICAvLyAgICAgICB3aG9zZSBuYW1lIHN0YXJ0cyB3aXRoICJ4bWwiIChlLmcuICJ4bWxmb28iKQotICAgICAgICAgICAgaWYgKGlzVmFsaWROYW1lQ2hhcihmRW50aXR5U2Nhbm5lci5wZWVrQ2hhcigpKSkgewotICAgICAgICAgICAgICAgIGZTdHJpbmdCdWZmZXIuY2xlYXIoKTsKLSAgICAgICAgICAgICAgICBmU3RyaW5nQnVmZmVyLmFwcGVuZCgieG1sIik7Ci0gICAgICAgICAgICAgICAgd2hpbGUgKGlzVmFsaWROYW1lQ2hhcihmRW50aXR5U2Nhbm5lci5wZWVrQ2hhcigpKSkgewotICAgICAgICAgICAgICAgICAgICBmU3RyaW5nQnVmZmVyLmFwcGVuZCgoY2hhcilmRW50aXR5U2Nhbm5lci5zY2FuQ2hhcihudWxsKSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIFN0cmluZyB0YXJnZXQgPQotICAgICAgICAgICAgICAgIGZTeW1ib2xUYWJsZS5hZGRTeW1ib2woZlN0cmluZ0J1ZmZlci5jaCwKLSAgICAgICAgICAgICAgICBmU3RyaW5nQnVmZmVyLm9mZnNldCwKLSAgICAgICAgICAgICAgICBmU3RyaW5nQnVmZmVyLmxlbmd0aCk7Ci0gICAgICAgICAgICAgICAgc2NhblBJRGF0YSh0YXJnZXQsIGZTdHJpbmcpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBzdGFuZGFyZCBUZXh0IGRlY2xhcmF0aW9uCi0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAvLyBwc2V1ZG8tYXR0cmlidXRlIHZhbHVlcwotICAgICAgICAgICAgICAgIFN0cmluZyB2ZXJzaW9uID0gbnVsbDsKLSAgICAgICAgICAgICAgICBTdHJpbmcgZW5jb2RpbmcgPSBudWxsOwotCi0gICAgICAgICAgICAgICAgc2NhblhNTERlY2xPclRleHREZWNsKHRydWUsIGZTdHJpbmdzKTsKLSAgICAgICAgICAgICAgICB0ZXh0RGVjbCA9IHRydWU7Ci0gICAgICAgICAgICAgICAgZk1hcmtVcERlcHRoLS07Ci0KLSAgICAgICAgICAgICAgICB2ZXJzaW9uID0gZlN0cmluZ3NbMF07Ci0gICAgICAgICAgICAgICAgZW5jb2RpbmcgPSBmU3RyaW5nc1sxXTsKLQotICAgICAgICAgICAgICAgIGZFbnRpdHlTY2FubmVyLnNldEVuY29kaW5nKGVuY29kaW5nKTsKLQotICAgICAgICAgICAgICAgIC8vIGNhbGwgaGFuZGxlcgotICAgICAgICAgICAgICAgIGlmIChmRFRESGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZEVERIYW5kbGVyLnRleHREZWNsKHZlcnNpb24sIGVuY29kaW5nLCBudWxsKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZkVudGl0eU1hbmFnZXIuZkN1cnJlbnRFbnRpdHkubWF5UmVhZENodW5rcyA9IHRydWU7Ci0KLSAgICAgICAgcmV0dXJuIHRleHREZWNsOwotCi0gICAgfSAvLyBzY2FuVGV4dERlY2woYm9vbGVhbik6Ym9vbGVhbgotCi0gICAgLyoqCi0gICAgICogU2NhbnMgYSBwcm9jZXNzaW5nIGRhdGEuIFRoaXMgaXMgbmVlZGVkIHRvIGhhbmRsZSB0aGUgc2l0dWF0aW9uCi0gICAgICogd2hlcmUgYSBkb2N1bWVudCBzdGFydHMgd2l0aCBhIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gd2hvc2UKLSAgICAgKiB0YXJnZXQgbmFtZSA8ZW0+c3RhcnRzIHdpdGg8L2VtPiAieG1sIi4gKGUuZy4geG1sZm9vKQotICAgICAqCi0gICAgICogQHBhcmFtIHRhcmdldCBUaGUgUEkgdGFyZ2V0Ci0gICAgICogQHBhcmFtIGRhdGEgVGhlIHN0cmluZyB0byBmaWxsIGluIHdpdGggdGhlIGRhdGEKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgZmluYWwgdm9pZCBzY2FuUElEYXRhKFN0cmluZyB0YXJnZXQsIFhNTFN0cmluZyBkYXRhKQotICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgLy9WZW51IFJFVklTSVQKLSAgICAgICAgLy8gICAgICBzdXBlci5zY2FuUElEYXRhKHRhcmdldCwgZGF0YSk7Ci0gICAgICAgIGZNYXJrVXBEZXB0aC0tOwotCi0gICAgICAgIC8vIGNhbGwgaGFuZGxlcgotICAgICAgICBpZiAoZkRUREhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkRUREhhbmRsZXIucHJvY2Vzc2luZ0luc3RydWN0aW9uKHRhcmdldCwgZGF0YSwgbnVsbCk7Ci0gICAgICAgIH0KLQotICAgIH0gLy8gc2NhblBJRGF0YShTdHJpbmcpCi0KLSAgICAvKioKLSAgICAgKiBTY2FucyBhIGNvbW1lbnQuCi0gICAgICogPHA+Ci0gICAgICogPHByZT4KLSAgICAgKiBbMTVdIENvbW1lbnQgOjo9ICcmbHQhLS0nICgoQ2hhciAtICctJykgfCAoJy0nIChDaGFyIC0gJy0nKSkpKiAnLS0+JwotICAgICAqIDwvcHJlPgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gQ2FsbGVkIGFmdGVyIHNjYW5uaW5nIHBhc3QgJyZsdDshLS0nCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGZpbmFsIHZvaWQgc2NhbkNvbW1lbnQoKSB0aHJvd3MgSU9FeGNlcHRpb24sIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgZlJlcG9ydEVudGl0eSA9IGZhbHNlOwotICAgICAgICBzY2FuQ29tbWVudChmU3RyaW5nQnVmZmVyKTsKLSAgICAgICAgZk1hcmtVcERlcHRoLS07Ci0KLSAgICAgICAgLy8gY2FsbCBoYW5kbGVyCi0gICAgICAgIGlmIChmRFRESGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmRFRESGFuZGxlci5jb21tZW50KGZTdHJpbmdCdWZmZXIsIG51bGwpOwotICAgICAgICB9Ci0gICAgICAgIGZSZXBvcnRFbnRpdHkgPSB0cnVlOwotCi0gICAgfSAvLyBzY2FuQ29tbWVudCgpCi0KLSAgICAvKioKLSAgICAgKiBTY2FucyBhbiBlbGVtZW50IGRlY2xhcmF0aW9uCi0gICAgICogPHA+Ci0gICAgICogPHByZT4KLSAgICAgKiBbNDVdICAgIGVsZW1lbnRkZWNsICAgIDo6PSAgICAnJmx0OyFFTEVNRU5UJyBTIE5hbWUgUyBjb250ZW50c3BlYyBTPyAnPicKLSAgICAgKiBbNDZdICAgIGNvbnRlbnRzcGVjICAgIDo6PSAgICAnRU1QVFknIHwgJ0FOWScgfCBNaXhlZCB8IGNoaWxkcmVuCi0gICAgICogPC9wcmU+Ci0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBDYWxsZWQgYWZ0ZXIgc2Nhbm5pbmcgcGFzdCAnJmx0OyFFTEVNRU5UJwotICAgICAqLwotICAgIHByb3RlY3RlZCBmaW5hbCB2b2lkIHNjYW5FbGVtZW50RGVjbCgpIHRocm93cyBJT0V4Y2VwdGlvbiwgWE5JRXhjZXB0aW9uIHsKLQotICAgICAgICAvLyBzcGFjZXMKLSAgICAgICAgZlJlcG9ydEVudGl0eSA9IGZhbHNlOwotICAgICAgICBpZiAoIXNraXBTZXBhcmF0b3IodHJ1ZSwgIXNjYW5uaW5nSW50ZXJuYWxTdWJzZXQoKSkpIHsKLSAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIk1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfRUxFTUVOVF9UWVBFX0lOX0VMRU1FTlRERUNMIiwKLSAgICAgICAgICAgIG51bGwpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gZWxlbWVudCBuYW1lCi0gICAgICAgIFN0cmluZyBuYW1lID0gZkVudGl0eVNjYW5uZXIuc2Nhbk5hbWUoTmFtZVR5cGUuRUxFTUVOVFNUQVJUKTsKLSAgICAgICAgaWYgKG5hbWUgPT0gbnVsbCkgewotICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiTVNHX0VMRU1FTlRfVFlQRV9SRVFVSVJFRF9JTl9FTEVNRU5UREVDTCIsCi0gICAgICAgICAgICBudWxsKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIHNwYWNlcwotICAgICAgICBpZiAoIXNraXBTZXBhcmF0b3IodHJ1ZSwgIXNjYW5uaW5nSW50ZXJuYWxTdWJzZXQoKSkpIHsKLSAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIk1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfQ09OVEVOVFNQRUNfSU5fRUxFTUVOVERFQ0wiLAotICAgICAgICAgICAgbmV3IE9iamVjdFtde25hbWV9KTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIGNvbnRlbnQgbW9kZWwKLSAgICAgICAgaWYgKGZEVERDb250ZW50TW9kZWxIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZEVERDb250ZW50TW9kZWxIYW5kbGVyLnN0YXJ0Q29udGVudE1vZGVsKG5hbWUsIG51bGwpOwotICAgICAgICB9Ci0gICAgICAgIFN0cmluZyBjb250ZW50TW9kZWwgPSBudWxsOwotICAgICAgICBmUmVwb3J0RW50aXR5ID0gdHJ1ZTsKLSAgICAgICAgaWYgKGZFbnRpdHlTY2FubmVyLnNraXBTdHJpbmcoIkVNUFRZIikpIHsKLSAgICAgICAgICAgIGNvbnRlbnRNb2RlbCA9ICJFTVBUWSI7Ci0gICAgICAgICAgICAvLyBjYWxsIGhhbmRsZXIKLSAgICAgICAgICAgIGlmIChmRFREQ29udGVudE1vZGVsSGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZkRURENvbnRlbnRNb2RlbEhhbmRsZXIuZW1wdHkobnVsbCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoZkVudGl0eVNjYW5uZXIuc2tpcFN0cmluZygiQU5ZIikpIHsKLSAgICAgICAgICAgIGNvbnRlbnRNb2RlbCA9ICJBTlkiOwotICAgICAgICAgICAgLy8gY2FsbCBoYW5kbGVyCi0gICAgICAgICAgICBpZiAoZkRURENvbnRlbnRNb2RlbEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZEVERDb250ZW50TW9kZWxIYW5kbGVyLmFueShudWxsKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIGlmICghZkVudGl0eVNjYW5uZXIuc2tpcENoYXIoJygnLCBudWxsKSkgewotICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIk1TR19PUEVOX1BBUkVOX09SX0VMRU1FTlRfVFlQRV9SRVFVSVJFRF9JTl9DSElMRFJFTiIsCi0gICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde25hbWV9KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChmRFREQ29udGVudE1vZGVsSGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZkRURENvbnRlbnRNb2RlbEhhbmRsZXIuc3RhcnRHcm91cChudWxsKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGZTdHJpbmdCdWZmZXIuY2xlYXIoKTsKLSAgICAgICAgICAgIGZTdHJpbmdCdWZmZXIuYXBwZW5kKCcoJyk7Ci0gICAgICAgICAgICBmTWFya1VwRGVwdGgrKzsKLSAgICAgICAgICAgIHNraXBTZXBhcmF0b3IoZmFsc2UsICFzY2FubmluZ0ludGVybmFsU3Vic2V0KCkpOwotCi0gICAgICAgICAgICAvLyBNaXhlZCBjb250ZW50IG1vZGVsCi0gICAgICAgICAgICBpZiAoZkVudGl0eVNjYW5uZXIuc2tpcFN0cmluZygiI1BDREFUQSIpKSB7Ci0gICAgICAgICAgICAgICAgc2Nhbk1peGVkKG5hbWUpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7ICAgICAgICAgICAgICAvLyBjaGlsZHJlbiBjb250ZW50Ci0gICAgICAgICAgICAgICAgc2NhbkNoaWxkcmVuKG5hbWUpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY29udGVudE1vZGVsID0gZlN0cmluZ0J1ZmZlci50b1N0cmluZygpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gY2FsbCBoYW5kbGVyCi0gICAgICAgIGlmIChmRFREQ29udGVudE1vZGVsSGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmRFREQ29udGVudE1vZGVsSGFuZGxlci5lbmRDb250ZW50TW9kZWwobnVsbCk7Ci0gICAgICAgIH0KLQotICAgICAgICBmUmVwb3J0RW50aXR5ID0gZmFsc2U7Ci0gICAgICAgIHNraXBTZXBhcmF0b3IoZmFsc2UsICFzY2FubmluZ0ludGVybmFsU3Vic2V0KCkpOwotICAgICAgICAvLyBlbmQKLSAgICAgICAgaWYgKCFmRW50aXR5U2Nhbm5lci5za2lwQ2hhcignPicsIG51bGwpKSB7Ci0gICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJFbGVtZW50RGVjbFVudGVybWluYXRlZCIsIG5ldyBPYmplY3RbXXtuYW1lfSk7Ci0gICAgICAgIH0KLSAgICAgICAgZlJlcG9ydEVudGl0eSA9IHRydWU7Ci0gICAgICAgIGZNYXJrVXBEZXB0aC0tOwotCi0gICAgICAgIC8vIGNhbGwgaGFuZGxlcgotICAgICAgICBpZiAoZkRUREhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkRUREhhbmRsZXIuZWxlbWVudERlY2wobmFtZSwgY29udGVudE1vZGVsLCBudWxsKTsKLSAgICAgICAgfQotICAgICAgICBpZiAobm9uVmFsaWRhdGluZ01vZGUpIG52R3JhbW1hckluZm8uZWxlbWVudERlY2wobmFtZSwgY29udGVudE1vZGVsLCBudWxsKTsKLSAgICB9IC8vIHNjYW5FbGVtZW50RGVjbCgpCi0KLSAgICAvKioKLSAgICAgKiBzY2FuIE1peGVkIGNvbnRlbnQgbW9kZWwKLSAgICAgKiBUaGlzIGFzc3VtZXMgdGhlIGNvbnRlbnQgbW9kZWwgaGFzIGJlZW4gcGFyc2VkIHVwIHRvICNQQ0RBVEEgYW5kCi0gICAgICogY2FuIHNpbXBseSBhcHBlbmQgdG8gZlN0cmluZ0J1ZmZlci4KLSAgICAgKiA8cHJlPgotICAgICAqIFs1MV0gICAgTWl4ZWQgICAgOjo9ICAgICcoJyBTPyAnI1BDREFUQScgKFM/ICd8JyBTPyBOYW1lKSogUz8gJykqJwotICAgICAqICAgICAgICAgICAgICAgICAgICAgICB8ICcoJyBTPyAnI1BDREFUQScgUz8gJyknCi0gICAgICogPC9wcmU+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gZWxOYW1lIFRoZSBlbGVtZW50IHR5cGUgbmFtZSB0aGlzIGRlY2xhcmF0aW9uIGlzIGFib3V0LgotICAgICAqCi0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBDYWxsZWQgYWZ0ZXIgc2Nhbm5pbmcgcGFzdCAnKCNQQ0RBVEEnLgotICAgICAqLwotICAgIHByaXZhdGUgZmluYWwgdm9pZCBzY2FuTWl4ZWQoU3RyaW5nIGVsTmFtZSkKLSAgICB0aHJvd3MgSU9FeGNlcHRpb24sIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgU3RyaW5nIGNoaWxkTmFtZSA9IG51bGw7Ci0KLSAgICAgICAgZlN0cmluZ0J1ZmZlci5hcHBlbmQoIiNQQ0RBVEEiKTsKLSAgICAgICAgLy8gY2FsbCBoYW5kbGVyCi0gICAgICAgIGlmIChmRFREQ29udGVudE1vZGVsSGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmRFREQ29udGVudE1vZGVsSGFuZGxlci5wY2RhdGEobnVsbCk7Ci0gICAgICAgIH0KLSAgICAgICAgc2tpcFNlcGFyYXRvcihmYWxzZSwgIXNjYW5uaW5nSW50ZXJuYWxTdWJzZXQoKSk7Ci0gICAgICAgIHdoaWxlIChmRW50aXR5U2Nhbm5lci5za2lwQ2hhcignfCcsIG51bGwpKSB7Ci0gICAgICAgICAgICBmU3RyaW5nQnVmZmVyLmFwcGVuZCgnfCcpOwotICAgICAgICAgICAgLy8gY2FsbCBoYW5kbGVyCi0gICAgICAgICAgICBpZiAoZkRURENvbnRlbnRNb2RlbEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZEVERDb250ZW50TW9kZWxIYW5kbGVyLnNlcGFyYXRvcihYTUxEVERDb250ZW50TW9kZWxIYW5kbGVyLlNFUEFSQVRPUl9DSE9JQ0UsCi0gICAgICAgICAgICAgICAgbnVsbCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBza2lwU2VwYXJhdG9yKGZhbHNlLCAhc2Nhbm5pbmdJbnRlcm5hbFN1YnNldCgpKTsKLQotICAgICAgICAgICAgY2hpbGROYW1lID0gZkVudGl0eVNjYW5uZXIuc2Nhbk5hbWUoTmFtZVR5cGUuRU5USVRZKTsKLSAgICAgICAgICAgIGlmIChjaGlsZE5hbWUgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIk1TR19FTEVNRU5UX1RZUEVfUkVRVUlSRURfSU5fTUlYRURfQ09OVEVOVCIsCi0gICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde2VsTmFtZX0pOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZlN0cmluZ0J1ZmZlci5hcHBlbmQoY2hpbGROYW1lKTsKLSAgICAgICAgICAgIC8vIGNhbGwgaGFuZGxlcgotICAgICAgICAgICAgaWYgKGZEVERDb250ZW50TW9kZWxIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmRFREQ29udGVudE1vZGVsSGFuZGxlci5lbGVtZW50KGNoaWxkTmFtZSwgbnVsbCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBza2lwU2VwYXJhdG9yKGZhbHNlLCAhc2Nhbm5pbmdJbnRlcm5hbFN1YnNldCgpKTsKLSAgICAgICAgfQotICAgICAgICAvLyBUaGUgZm9sbG93aW5nIGNoZWNrIG11c3QgYmUgZG9uZSBpbiBhIHNpbmdsZSBjYWxsIChhcyBvcHBvc2VkIHRvIG9uZQotICAgICAgICAvLyBmb3IgJyknIGFuZCB0aGVuIG9uZSBmb3IgJyonKSB0byBndWFyYW50ZWUgdGhhdCBjYWxsYmFja3MgYXJlCi0gICAgICAgIC8vIHByb3Blcmx5IG5lc3RlZC4gV2UgZG8gbm90IHdhbnQgdG8gdHJpZ2dlciBlbmRFbnRpdHkgdG9vIGVhcmx5IGluCi0gICAgICAgIC8vIGNhc2Ugd2UgY3Jvc3MgdGhlIGJvdW5kYXJ5IG9mIGFuIGVudGl0eSBiZXR3ZWVuIHRoZSB0d28gY2hhcmFjdGVycy4KLSAgICAgICAgaWYgKGZFbnRpdHlTY2FubmVyLnNraXBTdHJpbmcoIikqIikpIHsKLSAgICAgICAgICAgIGZTdHJpbmdCdWZmZXIuYXBwZW5kKCIpKiIpOwotICAgICAgICAgICAgLy8gY2FsbCBoYW5kbGVyCi0gICAgICAgICAgICBpZiAoZkRURENvbnRlbnRNb2RlbEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZEVERDb250ZW50TW9kZWxIYW5kbGVyLmVuZEdyb3VwKG51bGwpOwotICAgICAgICAgICAgICAgIGZEVERDb250ZW50TW9kZWxIYW5kbGVyLm9jY3VycmVuY2UoWE1MRFREQ29udGVudE1vZGVsSGFuZGxlci5PQ0NVUlNfWkVST19PUl9NT1JFLAotICAgICAgICAgICAgICAgIG51bGwpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKGNoaWxkTmFtZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJNaXhlZENvbnRlbnRVbnRlcm1pbmF0ZWQiLAotICAgICAgICAgICAgbmV3IE9iamVjdFtde2VsTmFtZX0pOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKGZFbnRpdHlTY2FubmVyLnNraXBDaGFyKCcpJywgbnVsbCkpewotICAgICAgICAgICAgZlN0cmluZ0J1ZmZlci5hcHBlbmQoJyknKTsKLSAgICAgICAgICAgIC8vIGNhbGwgaGFuZGxlcgotICAgICAgICAgICAgaWYgKGZEVERDb250ZW50TW9kZWxIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmRFREQ29udGVudE1vZGVsSGFuZGxlci5lbmRHcm91cChudWxsKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIk1TR19DTE9TRV9QQVJFTl9SRVFVSVJFRF9JTl9DSElMRFJFTiIsCi0gICAgICAgICAgICBuZXcgT2JqZWN0W117ZWxOYW1lfSk7Ci0gICAgICAgIH0KLSAgICAgICAgZk1hcmtVcERlcHRoLS07Ci0gICAgICAgIC8vIHdlIGFyZSBkb25lCi0gICAgfQotCi0gICAgLyoqCi0gICAgICogc2NhbiBjaGlsZHJlbiBjb250ZW50IG1vZGVsCi0gICAgICogVGhpcyBhc3N1bWVzIGl0IGNhbiBzaW1wbHkgYXBwZW5kIHRvIGZTdHJpbmdCdWZmZXIuCi0gICAgICogPHByZT4KLSAgICAgKiBbNDddICAgIGNoaWxkcmVuICA6Oj0gICAgKGNob2ljZSB8IHNlcSkgKCc/JyB8ICcqJyB8ICcrJyk/Ci0gICAgICogWzQ4XSAgICBjcCAgICAgICAgOjo9ICAgIChOYW1lIHwgY2hvaWNlIHwgc2VxKSAoJz8nIHwgJyonIHwgJysnKT8KLSAgICAgKiBbNDldICAgIGNob2ljZSAgICA6Oj0gICAgJygnIFM/IGNwICggUz8gJ3wnIFM/IGNwICkrIFM/ICcpJwotICAgICAqIFs1MF0gICAgc2VxICAgICAgIDo6PSAgICAnKCcgUz8gY3AgKCBTPyAnLCcgUz8gY3AgKSogUz8gJyknCi0gICAgICogPC9wcmU+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gZWxOYW1lIFRoZSBlbGVtZW50IHR5cGUgbmFtZSB0aGlzIGRlY2xhcmF0aW9uIGlzIGFib3V0LgotICAgICAqCi0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBDYWxsZWQgYWZ0ZXIgc2Nhbm5pbmcgcGFzdCB0aGUgZmlyc3Qgb3BlbgotICAgICAqIHBhcmFudGhlc2lzLgotICAgICAqLwotICAgIHByaXZhdGUgZmluYWwgdm9pZCBzY2FuQ2hpbGRyZW4oU3RyaW5nIGVsTmFtZSkKLSAgICB0aHJvd3MgSU9FeGNlcHRpb24sIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgZkNvbnRlbnREZXB0aCA9IDA7Ci0gICAgICAgIHB1c2hDb250ZW50U3RhY2soMCk7Ci0gICAgICAgIGludCBjdXJyZW50T3AgPSAwOwotICAgICAgICBpbnQgYzsKLSAgICAgICAgd2hpbGUgKHRydWUpIHsKLSAgICAgICAgICAgIGlmIChmRW50aXR5U2Nhbm5lci5za2lwQ2hhcignKCcsIG51bGwpKSB7Ci0gICAgICAgICAgICAgICAgZk1hcmtVcERlcHRoKys7Ci0gICAgICAgICAgICAgICAgZlN0cmluZ0J1ZmZlci5hcHBlbmQoJygnKTsKLSAgICAgICAgICAgICAgICAvLyBjYWxsIGhhbmRsZXIKLSAgICAgICAgICAgICAgICBpZiAoZkRURENvbnRlbnRNb2RlbEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBmRFREQ29udGVudE1vZGVsSGFuZGxlci5zdGFydEdyb3VwKG51bGwpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvLyBwdXNoIGN1cnJlbnQgb3Agb24gc3RhY2sgYW5kIHJlc2V0IGl0Ci0gICAgICAgICAgICAgICAgcHVzaENvbnRlbnRTdGFjayhjdXJyZW50T3ApOwotICAgICAgICAgICAgICAgIGN1cnJlbnRPcCA9IDA7Ci0gICAgICAgICAgICAgICAgc2tpcFNlcGFyYXRvcihmYWxzZSwgIXNjYW5uaW5nSW50ZXJuYWxTdWJzZXQoKSk7Ci0gICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBza2lwU2VwYXJhdG9yKGZhbHNlLCAhc2Nhbm5pbmdJbnRlcm5hbFN1YnNldCgpKTsKLSAgICAgICAgICAgIFN0cmluZyBjaGlsZE5hbWUgPSBmRW50aXR5U2Nhbm5lci5zY2FuTmFtZShOYW1lVHlwZS5FTEVNRU5UU1RBUlQpOwotICAgICAgICAgICAgaWYgKGNoaWxkTmFtZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiTVNHX09QRU5fUEFSRU5fT1JfRUxFTUVOVF9UWVBFX1JFUVVJUkVEX0lOX0NISUxEUkVOIiwKLSAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117ZWxOYW1lfSk7Ci0gICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gY2FsbCBoYW5kbGVyCi0gICAgICAgICAgICBpZiAoZkRURENvbnRlbnRNb2RlbEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZEVERDb250ZW50TW9kZWxIYW5kbGVyLmVsZW1lbnQoY2hpbGROYW1lLCBudWxsKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGZTdHJpbmdCdWZmZXIuYXBwZW5kKGNoaWxkTmFtZSk7Ci0gICAgICAgICAgICBjID0gZkVudGl0eVNjYW5uZXIucGVla0NoYXIoKTsKLSAgICAgICAgICAgIGlmIChjID09ICc/JyB8fCBjID09ICcqJyB8fCBjID09ICcrJykgewotICAgICAgICAgICAgICAgIC8vIGNhbGwgaGFuZGxlcgotICAgICAgICAgICAgICAgIGlmIChmRFREQ29udGVudE1vZGVsSGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIHNob3J0IG9jOwotICAgICAgICAgICAgICAgICAgICBpZiAoYyA9PSAnPycpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIG9jID0gWE1MRFREQ29udGVudE1vZGVsSGFuZGxlci5PQ0NVUlNfWkVST19PUl9PTkU7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoYyA9PSAnKicpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIG9jID0gWE1MRFREQ29udGVudE1vZGVsSGFuZGxlci5PQ0NVUlNfWkVST19PUl9NT1JFOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgb2MgPSBYTUxEVERDb250ZW50TW9kZWxIYW5kbGVyLk9DQ1VSU19PTkVfT1JfTU9SRTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBmRFREQ29udGVudE1vZGVsSGFuZGxlci5vY2N1cnJlbmNlKG9jLCBudWxsKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZkVudGl0eVNjYW5uZXIuc2NhbkNoYXIobnVsbCk7Ci0gICAgICAgICAgICAgICAgZlN0cmluZ0J1ZmZlci5hcHBlbmQoKGNoYXIpYyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICB3aGlsZSAodHJ1ZSkgewotICAgICAgICAgICAgICAgIHNraXBTZXBhcmF0b3IoZmFsc2UsICFzY2FubmluZ0ludGVybmFsU3Vic2V0KCkpOwotICAgICAgICAgICAgICAgIGMgPSBmRW50aXR5U2Nhbm5lci5wZWVrQ2hhcigpOwotICAgICAgICAgICAgICAgIGlmIChjID09ICcsJyAmJiBjdXJyZW50T3AgIT0gJ3wnKSB7Ci0gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRPcCA9IGM7Ci0gICAgICAgICAgICAgICAgICAgIC8vIGNhbGwgaGFuZGxlcgotICAgICAgICAgICAgICAgICAgICBpZiAoZkRURENvbnRlbnRNb2RlbEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgZkRURENvbnRlbnRNb2RlbEhhbmRsZXIuc2VwYXJhdG9yKFhNTERURENvbnRlbnRNb2RlbEhhbmRsZXIuU0VQQVJBVE9SX1NFUVVFTkNFLAotICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZkVudGl0eVNjYW5uZXIuc2NhbkNoYXIobnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgIGZTdHJpbmdCdWZmZXIuYXBwZW5kKCcsJyk7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIGlmIChjID09ICd8JyAmJiBjdXJyZW50T3AgIT0gJywnKSB7Ci0gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRPcCA9IGM7Ci0gICAgICAgICAgICAgICAgICAgIC8vIGNhbGwgaGFuZGxlcgotICAgICAgICAgICAgICAgICAgICBpZiAoZkRURENvbnRlbnRNb2RlbEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgZkRURENvbnRlbnRNb2RlbEhhbmRsZXIuc2VwYXJhdG9yKFhNTERURENvbnRlbnRNb2RlbEhhbmRsZXIuU0VQQVJBVE9SX0NIT0lDRSwKLSAgICAgICAgICAgICAgICAgICAgICAgIG51bGwpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGZFbnRpdHlTY2FubmVyLnNjYW5DaGFyKG51bGwpOwotICAgICAgICAgICAgICAgICAgICBmU3RyaW5nQnVmZmVyLmFwcGVuZCgnfCcpOwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSBpZiAoYyAhPSAnKScpIHsKLSAgICAgICAgICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiTVNHX0NMT1NFX1BBUkVOX1JFUVVJUkVEX0lOX0NISUxEUkVOIiwKLSAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde2VsTmFtZX0pOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvLyBjYWxsIGhhbmRsZXIKLSAgICAgICAgICAgICAgICBpZiAoZkRURENvbnRlbnRNb2RlbEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBmRFREQ29udGVudE1vZGVsSGFuZGxlci5lbmRHcm91cChudWxsKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLy8gcmVzdG9yZSBwcmV2aW91cyBvcAotICAgICAgICAgICAgICAgIGN1cnJlbnRPcCA9IHBvcENvbnRlbnRTdGFjaygpOwotICAgICAgICAgICAgICAgIHNob3J0IG9jOwotICAgICAgICAgICAgICAgIC8vIFRoZSBmb2xsb3dpbmcgY2hlY2tzIG11c3QgYmUgZG9uZSBpbiBhIHNpbmdsZSBjYWxsIChhcwotICAgICAgICAgICAgICAgIC8vIG9wcG9zZWQgdG8gb25lIGZvciAnKScgYW5kIHRoZW4gb25lIGZvciAnPycsICcqJywgYW5kICcrJykKLSAgICAgICAgICAgICAgICAvLyB0byBndWFyYW50ZWUgdGhhdCBjYWxsYmFja3MgYXJlIHByb3Blcmx5IG5lc3RlZC4gV2UgZG8gbm90Ci0gICAgICAgICAgICAgICAgLy8gd2FudCB0byB0cmlnZ2VyIGVuZEVudGl0eSB0b28gZWFybHkgaW4gY2FzZSB3ZSBjcm9zcyB0aGUKLSAgICAgICAgICAgICAgICAvLyBib3VuZGFyeSBvZiBhbiBlbnRpdHkgYmV0d2VlbiB0aGUgdHdvIGNoYXJhY3RlcnMuCi0gICAgICAgICAgICAgICAgaWYgKGZFbnRpdHlTY2FubmVyLnNraXBTdHJpbmcoIik/IikpIHsKLSAgICAgICAgICAgICAgICAgICAgZlN0cmluZ0J1ZmZlci5hcHBlbmQoIik/Iik7Ci0gICAgICAgICAgICAgICAgICAgIC8vIGNhbGwgaGFuZGxlcgotICAgICAgICAgICAgICAgICAgICBpZiAoZkRURENvbnRlbnRNb2RlbEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgb2MgPSBYTUxEVERDb250ZW50TW9kZWxIYW5kbGVyLk9DQ1VSU19aRVJPX09SX09ORTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZEVERDb250ZW50TW9kZWxIYW5kbGVyLm9jY3VycmVuY2Uob2MsIG51bGwpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgaWYgKGZFbnRpdHlTY2FubmVyLnNraXBTdHJpbmcoIikrIikpIHsKLSAgICAgICAgICAgICAgICAgICAgZlN0cmluZ0J1ZmZlci5hcHBlbmQoIikrIik7Ci0gICAgICAgICAgICAgICAgICAgIC8vIGNhbGwgaGFuZGxlcgotICAgICAgICAgICAgICAgICAgICBpZiAoZkRURENvbnRlbnRNb2RlbEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgb2MgPSBYTUxEVERDb250ZW50TW9kZWxIYW5kbGVyLk9DQ1VSU19PTkVfT1JfTU9SRTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZEVERDb250ZW50TW9kZWxIYW5kbGVyLm9jY3VycmVuY2Uob2MsIG51bGwpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgaWYgKGZFbnRpdHlTY2FubmVyLnNraXBTdHJpbmcoIikqIikpIHsKLSAgICAgICAgICAgICAgICAgICAgZlN0cmluZ0J1ZmZlci5hcHBlbmQoIikqIik7Ci0gICAgICAgICAgICAgICAgICAgIC8vIGNhbGwgaGFuZGxlcgotICAgICAgICAgICAgICAgICAgICBpZiAoZkRURENvbnRlbnRNb2RlbEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgb2MgPSBYTUxEVERDb250ZW50TW9kZWxIYW5kbGVyLk9DQ1VSU19aRVJPX09SX01PUkU7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmRFREQ29udGVudE1vZGVsSGFuZGxlci5vY2N1cnJlbmNlKG9jLCBudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gbm8gb2NjdXJyZW5jZSBzcGVjaWZpZWQKLSAgICAgICAgICAgICAgICAgICAgZkVudGl0eVNjYW5uZXIuc2NhbkNoYXIobnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgIGZTdHJpbmdCdWZmZXIuYXBwZW5kKCcpJyk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGZNYXJrVXBEZXB0aC0tOwotICAgICAgICAgICAgICAgIGlmIChmQ29udGVudERlcHRoID09IDApIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHNraXBTZXBhcmF0b3IoZmFsc2UsICFzY2FubmluZ0ludGVybmFsU3Vic2V0KCkpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2NhbnMgYW4gYXR0bGlzdCBkZWNsYXJhdGlvbgotICAgICAqIDxwPgotICAgICAqIDxwcmU+Ci0gICAgICogWzUyXSAgQXR0bGlzdERlY2wgICAgOjo9ICAgJyZsdDshQVRUTElTVCcgUyBOYW1lIEF0dERlZiogUz8gJz4nCi0gICAgICogWzUzXSAgQXR0RGVmICAgICAgICAgOjo9ICAgUyBOYW1lIFMgQXR0VHlwZSBTIERlZmF1bHREZWNsCi0gICAgICogPC9wcmU+Ci0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBDYWxsZWQgYWZ0ZXIgc2Nhbm5pbmcgcGFzdCAnJmx0OyFBVFRMSVNUJwotICAgICAqLwotICAgIHByb3RlY3RlZCBmaW5hbCB2b2lkIHNjYW5BdHRsaXN0RGVjbCgpIHRocm93cyBJT0V4Y2VwdGlvbiwgWE5JRXhjZXB0aW9uIHsKLQotICAgICAgICAvLyBzcGFjZXMKLSAgICAgICAgZlJlcG9ydEVudGl0eSA9IGZhbHNlOwotICAgICAgICBpZiAoIXNraXBTZXBhcmF0b3IodHJ1ZSwgIXNjYW5uaW5nSW50ZXJuYWxTdWJzZXQoKSkpIHsKLSAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIk1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfRUxFTUVOVF9UWVBFX0lOX0FUVExJU1RERUNMIiwKLSAgICAgICAgICAgIG51bGwpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gZWxlbWVudCBuYW1lCi0gICAgICAgIFN0cmluZyBlbE5hbWUgPSBmRW50aXR5U2Nhbm5lci5zY2FuTmFtZShOYW1lVHlwZS5FTEVNRU5UU1RBUlQpOwotICAgICAgICBpZiAoZWxOYW1lID09IG51bGwpIHsKLSAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIk1TR19FTEVNRU5UX1RZUEVfUkVRVUlSRURfSU5fQVRUTElTVERFQ0wiLAotICAgICAgICAgICAgbnVsbCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBjYWxsIGhhbmRsZXIKLSAgICAgICAgaWYgKGZEVERIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZEVERIYW5kbGVyLnN0YXJ0QXR0bGlzdChlbE5hbWUsIG51bGwpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gc3BhY2VzCi0gICAgICAgIGlmICghc2tpcFNlcGFyYXRvcih0cnVlLCAhc2Nhbm5pbmdJbnRlcm5hbFN1YnNldCgpKSkgewotICAgICAgICAgICAgLy8gbm8gc3BhY2UsIGlzIGl0IHRoZSBlbmQgeWV0PwotICAgICAgICAgICAgaWYgKGZFbnRpdHlTY2FubmVyLnNraXBDaGFyKCc+JywgbnVsbCkpIHsKLSAgICAgICAgICAgICAgICAvLyB5ZXMsIHN0b3AgaGVyZQotICAgICAgICAgICAgICAgIC8vIGNhbGwgaGFuZGxlcgotICAgICAgICAgICAgICAgIGlmIChmRFRESGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZEVERIYW5kbGVyLmVuZEF0dGxpc3QobnVsbCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGZNYXJrVXBEZXB0aC0tOwotICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIk1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfQVRUUklCVVRFX05BTUVfSU5fQVRUREVGIiwKLSAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117ZWxOYW1lfSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBkZWZpbml0aW9ucwotICAgICAgICB3aGlsZSAoIWZFbnRpdHlTY2FubmVyLnNraXBDaGFyKCc+JywgbnVsbCkpIHsKLSAgICAgICAgICAgIFN0cmluZyBuYW1lID0gZkVudGl0eVNjYW5uZXIuc2Nhbk5hbWUoTmFtZVR5cGUuQVRUUklCVVRFKTsKLSAgICAgICAgICAgIGlmIChuYW1lID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJBdHROYW1lUmVxdWlyZWRJbkF0dERlZiIsCi0gICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde2VsTmFtZX0pOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gc3BhY2VzCi0gICAgICAgICAgICBpZiAoIXNraXBTZXBhcmF0b3IodHJ1ZSwgIXNjYW5uaW5nSW50ZXJuYWxTdWJzZXQoKSkpIHsKLSAgICAgICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX0FUVFRZUEVfSU5fQVRUREVGIiwKLSAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117ZWxOYW1lLCBuYW1lfSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyB0eXBlCi0gICAgICAgICAgICBTdHJpbmcgdHlwZSA9IHNjYW5BdHRUeXBlKGVsTmFtZSwgbmFtZSk7Ci0KLSAgICAgICAgICAgIC8vIHNwYWNlcwotICAgICAgICAgICAgaWYgKCFza2lwU2VwYXJhdG9yKHRydWUsICFzY2FubmluZ0ludGVybmFsU3Vic2V0KCkpKSB7Ci0gICAgICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9ERUZBVUxUREVDTF9JTl9BVFRERUYiLAotICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXtlbE5hbWUsIG5hbWV9KTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gZGVmYXVsdCBkZWNsCi0gICAgICAgICAgICBTdHJpbmcgZGVmYXVsdFR5cGUgPSBzY2FuQXR0RGVmYXVsdERlY2woZWxOYW1lLCBuYW1lLAotICAgICAgICAgICAgdHlwZSwKLSAgICAgICAgICAgIGZMaXRlcmFsLCBmTGl0ZXJhbDIpOwotICAgICAgICAgICAgLy8gUkVWSVNJVDogU2hvdWxkIHdlIGRvIGFueXRoaW5nIHdpdGggdGhlIG5vbi1ub3JtYWxpemVkCi0gICAgICAgICAgICAvLyAgICAgICAgICBkZWZhdWx0IGF0dHJpYnV0ZSB2YWx1ZT8gLUFjCi0gICAgICAgICAgICAvLyB5ZXMtLWFjY29yZGluZyB0byBidWcgNTA3My4gIC0gbmVpbGcKLSAgICAgICAgICAgIFN0cmluZ1tdIGVudW1yID0gbnVsbDsKLSAgICAgICAgICAgIGlmKCBmRFRESGFuZGxlciAhPSBudWxsIHx8IG5vblZhbGlkYXRpbmdNb2RlKXsKLSAgICAgICAgICAgICAgICBpZiAoZkVudW1lcmF0aW9uQ291bnQgIT0gMCkgewotICAgICAgICAgICAgICAgICAgICBlbnVtciA9IG5ldyBTdHJpbmdbZkVudW1lcmF0aW9uQ291bnRdOwotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGZFbnVtZXJhdGlvbiwgMCwgZW51bXIsCi0gICAgICAgICAgICAgICAgICAgIDAsIGZFbnVtZXJhdGlvbkNvdW50KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyBjYWxsIGhhbmRsZXIKLSAgICAgICAgICAgIC8vIERldGVybWluZSB3aGV0aGVyIHRoZSBkZWZhdWx0IHZhbHVlIHRvIGJlIHBhc3NlZCBzaG91bGQgYmUgbnVsbC4KLSAgICAgICAgICAgIC8vIFJFVklTSVQ6IHNob3VsZCBwcm9iYWJseSBjaGVjayB3aGV0aGVyIGZMaXRlcmFsLmNoIGlzIG51bGwgaW5zdGVhZC4gTE0uCi0gICAgICAgICAgICBpZiAoZGVmYXVsdFR5cGUhPW51bGwgJiYgKGRlZmF1bHRUeXBlLmVxdWFscygiI1JFUVVJUkVEIikgfHwKLSAgICAgICAgICAgIGRlZmF1bHRUeXBlLmVxdWFscygiI0lNUExJRUQiKSkpIHsKLSAgICAgICAgICAgICAgICBpZiAoZkRUREhhbmRsZXIgIT0gbnVsbCl7Ci0gICAgICAgICAgICAgICAgICAgIGZEVERIYW5kbGVyLmF0dHJpYnV0ZURlY2woZWxOYW1lLCBuYW1lLCB0eXBlLCBlbnVtciwKLSAgICAgICAgICAgICAgICAgICAgZGVmYXVsdFR5cGUsIG51bGwsIG51bGwsIG51bGwpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpZihub25WYWxpZGF0aW5nTW9kZSl7Ci0gICAgICAgICAgICAgICAgICAgIG52R3JhbW1hckluZm8uYXR0cmlidXRlRGVjbChlbE5hbWUsIG5hbWUsIHR5cGUsIGVudW1yLAotICAgICAgICAgICAgICAgICAgICBkZWZhdWx0VHlwZSwgbnVsbCwgbnVsbCwgbnVsbCk7Ci0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBpZiAoZkRUREhhbmRsZXIgIT0gbnVsbCl7Ci0gICAgICAgICAgICAgICAgICAgIGZEVERIYW5kbGVyLmF0dHJpYnV0ZURlY2woZWxOYW1lLCBuYW1lLCB0eXBlLCBlbnVtciwKLSAgICAgICAgICAgICAgICAgICAgZGVmYXVsdFR5cGUsIGZMaXRlcmFsLCBmTGl0ZXJhbDIsIG51bGwpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpZihub25WYWxpZGF0aW5nTW9kZSl7Ci0gICAgICAgICAgICAgICAgICAgIG52R3JhbW1hckluZm8uYXR0cmlidXRlRGVjbChlbE5hbWUsIG5hbWUsIHR5cGUsIGVudW1yLAotICAgICAgICAgICAgICAgICAgICBkZWZhdWx0VHlwZSwgZkxpdGVyYWwsIGZMaXRlcmFsMiwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgc2tpcFNlcGFyYXRvcihmYWxzZSwgIXNjYW5uaW5nSW50ZXJuYWxTdWJzZXQoKSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBjYWxsIGhhbmRsZXIKLSAgICAgICAgaWYgKGZEVERIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZEVERIYW5kbGVyLmVuZEF0dGxpc3QobnVsbCk7Ci0gICAgICAgIH0KLSAgICAgICAgZk1hcmtVcERlcHRoLS07Ci0gICAgICAgIGZSZXBvcnRFbnRpdHkgPSB0cnVlOwotCi0gICAgfSAvLyBzY2FuQXR0bGlzdERlY2woKQotCi0gICAgLyoqCi0gICAgICogU2NhbnMgYW4gYXR0cmlidXRlIHR5cGUgZGVmaW5pdGlvbgotICAgICAqIDxwPgotICAgICAqIDxwcmU+Ci0gICAgICogWzU0XSAgQXR0VHlwZSAgICAgICAgOjo9ICAgU3RyaW5nVHlwZSB8IFRva2VuaXplZFR5cGUgfCBFbnVtZXJhdGVkVHlwZQotICAgICAqIFs1NV0gIFN0cmluZ1R5cGUgICAgIDo6PSAgICdDREFUQScKLSAgICAgKiBbNTZdICBUb2tlbml6ZWRUeXBlICA6Oj0gICAnSUQnCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgIHwgJ0lEUkVGJwotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICB8ICdJRFJFRlMnCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgIHwgJ0VOVElUWScKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgfCAnRU5USVRJRVMnCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgIHwgJ05NVE9LRU4nCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgIHwgJ05NVE9LRU5TJwotICAgICAqIFs1N10gIEVudW1lcmF0ZWRUeXBlIDo6PSAgICBOb3RhdGlvblR5cGUgfCBFbnVtZXJhdGlvbgotICAgICAqIFs1OF0gIE5vdGF0aW9uVHlwZSA6Oj0gJ05PVEFUSU9OJyBTICcoJyBTPyBOYW1lIChTPyAnfCcgUz8gTmFtZSkqIFM/ICcpJwotICAgICAqIFs1OV0gIEVudW1lcmF0aW9uICAgIDo6PSAgICAnKCcgUz8gTm10b2tlbiAoUz8gJ3wnIFM/IE5tdG9rZW4pKiBTPyAnKScKLSAgICAgKiA8L3ByZT4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IENhbGxlZCBhZnRlciBzY2FubmluZyBwYXN0ICcmbHQ7IUFUVExJU1QnCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZWxOYW1lIFRoZSBlbGVtZW50IHR5cGUgbmFtZSB0aGlzIGRlY2xhcmF0aW9uIGlzIGFib3V0LgotICAgICAqIEBwYXJhbSBhdE5hbWUgVGhlIGF0dHJpYnV0ZSBuYW1lIHRoaXMgZGVjbGFyYXRpb24gaXMgYWJvdXQuCi0gICAgICovCi0gICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgc2NhbkF0dFR5cGUoU3RyaW5nIGVsTmFtZSwgU3RyaW5nIGF0TmFtZSkKLSAgICB0aHJvd3MgSU9FeGNlcHRpb24sIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgU3RyaW5nIHR5cGUgPSBudWxsOwotICAgICAgICBmRW51bWVyYXRpb25Db3VudCA9IDA7Ci0gICAgICAgIC8qCi0gICAgICAgICAqIFdhdGNob3V0OiB0aGUgb3JkZXIgaGVyZSBpcyBpbXBvcnRhbnQ6IHdoZW4gYSBzdHJpbmcgaGFwcGVucyB0bwotICAgICAgICAgKiBiZSBhIHN1YnN0cmluZyBvZiBhbm90aGVyIHN0cmluZywgdGhlIGxvbmdlciBvbmUgbmVlZHMgdG8gYmUKLSAgICAgICAgICogbG9va2VkIGZvciBmaXJzdCEhCi0gICAgICAgICAqLwotICAgICAgICBpZiAoZkVudGl0eVNjYW5uZXIuc2tpcFN0cmluZygiQ0RBVEEiKSkgewotICAgICAgICAgICAgdHlwZSA9ICJDREFUQSI7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoZkVudGl0eVNjYW5uZXIuc2tpcFN0cmluZygiSURSRUZTIikpIHsKLSAgICAgICAgICAgIHR5cGUgPSAiSURSRUZTIjsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChmRW50aXR5U2Nhbm5lci5za2lwU3RyaW5nKCJJRFJFRiIpKSB7Ci0gICAgICAgICAgICB0eXBlID0gIklEUkVGIjsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChmRW50aXR5U2Nhbm5lci5za2lwU3RyaW5nKCJJRCIpKSB7Ci0gICAgICAgICAgICB0eXBlID0gIklEIjsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChmRW50aXR5U2Nhbm5lci5za2lwU3RyaW5nKCJFTlRJVFkiKSkgewotICAgICAgICAgICAgdHlwZSA9ICJFTlRJVFkiOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKGZFbnRpdHlTY2FubmVyLnNraXBTdHJpbmcoIkVOVElUSUVTIikpIHsKLSAgICAgICAgICAgIHR5cGUgPSAiRU5USVRJRVMiOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKGZFbnRpdHlTY2FubmVyLnNraXBTdHJpbmcoIk5NVE9LRU5TIikpIHsKLSAgICAgICAgICAgIHR5cGUgPSAiTk1UT0tFTlMiOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKGZFbnRpdHlTY2FubmVyLnNraXBTdHJpbmcoIk5NVE9LRU4iKSkgewotICAgICAgICAgICAgdHlwZSA9ICJOTVRPS0VOIjsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChmRW50aXR5U2Nhbm5lci5za2lwU3RyaW5nKCJOT1RBVElPTiIpKSB7Ci0gICAgICAgICAgICB0eXBlID0gIk5PVEFUSU9OIjsKLSAgICAgICAgICAgIC8vIHNwYWNlcwotICAgICAgICAgICAgaWYgKCFza2lwU2VwYXJhdG9yKHRydWUsICFzY2FubmluZ0ludGVybmFsU3Vic2V0KCkpKSB7Ci0gICAgICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiTVNHX1NQQUNFX1JFUVVJUkVEX0FGVEVSX05PVEFUSU9OX0lOX05PVEFUSU9OVFlQRSIsCi0gICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde2VsTmFtZSwgYXROYW1lfSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyBvcGVuIHBhcmVuCi0gICAgICAgICAgICBpbnQgYyA9IGZFbnRpdHlTY2FubmVyLnNjYW5DaGFyKG51bGwpOwotICAgICAgICAgICAgaWYgKGMgIT0gJygnKSB7Ci0gICAgICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiTVNHX09QRU5fUEFSRU5fUkVRVUlSRURfSU5fTk9UQVRJT05UWVBFIiwKLSAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117ZWxOYW1lLCBhdE5hbWV9KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGZNYXJrVXBEZXB0aCsrOwotICAgICAgICAgICAgZG8gewotICAgICAgICAgICAgICAgIHNraXBTZXBhcmF0b3IoZmFsc2UsICFzY2FubmluZ0ludGVybmFsU3Vic2V0KCkpOwotICAgICAgICAgICAgICAgIFN0cmluZyBhTmFtZSA9IGZFbnRpdHlTY2FubmVyLnNjYW5OYW1lKE5hbWVUeXBlLkFUVFJJQlVURSk7Ci0gICAgICAgICAgICAgICAgaWYgKGFOYW1lID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiTVNHX05BTUVfUkVRVUlSRURfSU5fTk9UQVRJT05UWVBFIiwKLSAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde2VsTmFtZSwgYXROYW1lfSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVuc3VyZUVudW1lcmF0aW9uU2l6ZShmRW51bWVyYXRpb25Db3VudCArIDEpOwotICAgICAgICAgICAgICAgIGZFbnVtZXJhdGlvbltmRW51bWVyYXRpb25Db3VudCsrXSA9IGFOYW1lOwotICAgICAgICAgICAgICAgIHNraXBTZXBhcmF0b3IoZmFsc2UsICFzY2FubmluZ0ludGVybmFsU3Vic2V0KCkpOwotICAgICAgICAgICAgICAgIGMgPSBmRW50aXR5U2Nhbm5lci5zY2FuQ2hhcihudWxsKTsKLSAgICAgICAgICAgIH0gd2hpbGUgKGMgPT0gJ3wnKTsKLSAgICAgICAgICAgIGlmIChjICE9ICcpJykgewotICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIk5vdGF0aW9uVHlwZVVudGVybWluYXRlZCIsCi0gICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde2VsTmFtZSwgYXROYW1lfSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmTWFya1VwRGVwdGgtLTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsgICAgICAgICAgICAgIC8vIEVudW1lcmF0aW9uCi0gICAgICAgICAgICB0eXBlID0gIkVOVU1FUkFUSU9OIjsKLSAgICAgICAgICAgIC8vIG9wZW4gcGFyZW4KLSAgICAgICAgICAgIGludCBjID0gZkVudGl0eVNjYW5uZXIuc2NhbkNoYXIobnVsbCk7Ci0gICAgICAgICAgICBpZiAoYyAhPSAnKCcpIHsKLSAgICAgICAgICAgICAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgIk9QRU5fUEFSRU5fUkVRVUlSRURfQkVGT1JFX0VOVU1FUkFUSU9OX0lOX0FUVFJERUNMIiwKLSAgICAgICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJBdHRUeXBlUmVxdWlyZWRJbkF0dERlZiIsCi0gICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde2VsTmFtZSwgYXROYW1lfSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmTWFya1VwRGVwdGgrKzsKLSAgICAgICAgICAgIGRvIHsKLSAgICAgICAgICAgICAgICBza2lwU2VwYXJhdG9yKGZhbHNlLCAhc2Nhbm5pbmdJbnRlcm5hbFN1YnNldCgpKTsKLSAgICAgICAgICAgICAgICBTdHJpbmcgdG9rZW4gPSBmRW50aXR5U2Nhbm5lci5zY2FuTm10b2tlbigpOwotICAgICAgICAgICAgICAgIGlmICh0b2tlbiA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIk1TR19OTVRPS0VOX1JFUVVJUkVEX0lOX0VOVU1FUkFUSU9OIiwKLSAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde2VsTmFtZSwgYXROYW1lfSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVuc3VyZUVudW1lcmF0aW9uU2l6ZShmRW51bWVyYXRpb25Db3VudCArIDEpOwotICAgICAgICAgICAgICAgIGZFbnVtZXJhdGlvbltmRW51bWVyYXRpb25Db3VudCsrXSA9IHRva2VuOwotICAgICAgICAgICAgICAgIHNraXBTZXBhcmF0b3IoZmFsc2UsICFzY2FubmluZ0ludGVybmFsU3Vic2V0KCkpOwotICAgICAgICAgICAgICAgIGMgPSBmRW50aXR5U2Nhbm5lci5zY2FuQ2hhcihudWxsKTsKLSAgICAgICAgICAgIH0gd2hpbGUgKGMgPT0gJ3wnKTsKLSAgICAgICAgICAgIGlmIChjICE9ICcpJykgewotICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIkVudW1lcmF0aW9uVW50ZXJtaW5hdGVkIiwKLSAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117ZWxOYW1lLCBhdE5hbWV9KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGZNYXJrVXBEZXB0aC0tOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiB0eXBlOwotCi0gICAgfSAvLyBzY2FuQXR0VHlwZSgpOlN0cmluZwotCi0KLSAgICAvKioKLSAgICAgKiBTY2FucyBhbiBhdHRyaWJ1dGUgZGVmYXVsdCBkZWNsYXJhdGlvbgotICAgICAqIDxwPgotICAgICAqIDxwcmU+Ci0gICAgICogWzYwXSBEZWZhdWx0RGVjbCA6Oj0gJyNSRVFVSVJFRCcgfCAnI0lNUExJRUQnIHwgKCgnI0ZJWEVEJyBTKT8gQXR0VmFsdWUpCi0gICAgICogPC9wcmU+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlIGJlaW5nIHNjYW5uZWQuCi0gICAgICogQHBhcmFtIGRlZmF1bHRWYWwgVGhlIHN0cmluZyB0byBmaWxsIGluIHdpdGggdGhlIGRlZmF1bHQgdmFsdWUuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGZpbmFsIFN0cmluZyBzY2FuQXR0RGVmYXVsdERlY2woU3RyaW5nIGVsTmFtZSwgU3RyaW5nIGF0TmFtZSwKLSAgICBTdHJpbmcgdHlwZSwKLSAgICBYTUxTdHJpbmcgZGVmYXVsdFZhbCwKLSAgICBYTUxTdHJpbmcgbm9uTm9ybWFsaXplZERlZmF1bHRWYWwpCi0gICAgdGhyb3dzIElPRXhjZXB0aW9uLCBYTklFeGNlcHRpb24gewotCi0gICAgICAgIFN0cmluZyBkZWZhdWx0VHlwZSA9IG51bGw7Ci0gICAgICAgIGZTdHJpbmcuY2xlYXIoKTsKLSAgICAgICAgZGVmYXVsdFZhbC5jbGVhcigpOwotICAgICAgICBpZiAoZkVudGl0eVNjYW5uZXIuc2tpcFN0cmluZygiI1JFUVVJUkVEIikpIHsKLSAgICAgICAgICAgIGRlZmF1bHRUeXBlID0gIiNSRVFVSVJFRCI7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoZkVudGl0eVNjYW5uZXIuc2tpcFN0cmluZygiI0lNUExJRUQiKSkgewotICAgICAgICAgICAgZGVmYXVsdFR5cGUgPSAiI0lNUExJRUQiOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgaWYgKGZFbnRpdHlTY2FubmVyLnNraXBTdHJpbmcoIiNGSVhFRCIpKSB7Ci0gICAgICAgICAgICAgICAgZGVmYXVsdFR5cGUgPSAiI0ZJWEVEIjsKLSAgICAgICAgICAgICAgICAvLyBzcGFjZXMKLSAgICAgICAgICAgICAgICBpZiAoIXNraXBTZXBhcmF0b3IodHJ1ZSwgIXNjYW5uaW5nSW50ZXJuYWxTdWJzZXQoKSkpIHsKLSAgICAgICAgICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiTVNHX1NQQUNFX1JFUVVJUkVEX0FGVEVSX0ZJWEVEX0lOX0RFRkFVTFRERUNMIiwKLSAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde2VsTmFtZSwgYXROYW1lfSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gQXR0VmFsdWUKLSAgICAgICAgICAgIGJvb2xlYW4gaXNWQyA9ICFmU3RhbmRhbG9uZSAgJiYgIChmU2VlbkV4dGVybmFsRFREIHx8IGZTZWVuRXh0ZXJuYWxQRSkgOwotICAgICAgICAgICAgc2NhbkF0dHJpYnV0ZVZhbHVlKGRlZmF1bHRWYWwsIG5vbk5vcm1hbGl6ZWREZWZhdWx0VmFsLCBhdE5hbWUsCi0gICAgICAgICAgICBmQXR0cmlidXRlcywgMCwgaXNWQywgZWxOYW1lLCBmYWxzZSk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGRlZmF1bHRUeXBlOwotCi0gICAgfSAvLyBTY2FuQXR0RGVmYXVsdERlY2wKLQotICAgIC8qKgotICAgICAqIFNjYW5zIGFuIGVudGl0eSBkZWNsYXJhdGlvbgotICAgICAqIDxwPgotICAgICAqIDxwcmU+Ci0gICAgICogWzcwXSAgICBFbnRpdHlEZWNsICA6Oj0gICAgR0VEZWNsIHwgUEVEZWNsCi0gICAgICogWzcxXSAgICBHRURlY2wgICAgICA6Oj0gICAgJyZsdDshRU5USVRZJyBTIE5hbWUgUyBFbnRpdHlEZWYgUz8gJz4nCi0gICAgICogWzcyXSAgICBQRURlY2wgICAgICA6Oj0gICAgJyZsdDshRU5USVRZJyBTICclJyBTIE5hbWUgUyBQRURlZiBTPyAnPicKLSAgICAgKiBbNzNdICAgIEVudGl0eURlZiAgIDo6PSAgICBFbnRpdHlWYWx1ZSB8IChFeHRlcm5hbElEIE5EYXRhRGVjbD8pCi0gICAgICogWzc0XSAgICBQRURlZiAgICAgICA6Oj0gICAgRW50aXR5VmFsdWUgfCBFeHRlcm5hbElECi0gICAgICogWzc1XSAgICBFeHRlcm5hbElEICA6Oj0gICAgJ1NZU1RFTScgUyBTeXN0ZW1MaXRlcmFsCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgIHwgJ1BVQkxJQycgUyBQdWJpZExpdGVyYWwgUyBTeXN0ZW1MaXRlcmFsCi0gICAgICogWzc2XSAgICBORGF0YURlY2wgICA6Oj0gICAgUyAnTkRBVEEnIFMgTmFtZQotICAgICAqIDwvcHJlPgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gQ2FsbGVkIGFmdGVyIHNjYW5uaW5nIHBhc3QgJyZsdDshRU5USVRZJwotICAgICAqLwotICAgIHByaXZhdGUgZmluYWwgdm9pZCBzY2FuRW50aXR5RGVjbCgpIHRocm93cyBJT0V4Y2VwdGlvbiwgWE5JRXhjZXB0aW9uIHsKLQotICAgICAgICBib29sZWFuIGlzUEVEZWNsID0gZmFsc2U7Ci0gICAgICAgIGJvb2xlYW4gc2F3UEVSZWYgPSBmYWxzZTsKLSAgICAgICAgZlJlcG9ydEVudGl0eSA9IGZhbHNlOwotICAgICAgICBpZiAoZkVudGl0eVNjYW5uZXIuc2tpcFNwYWNlcygpKSB7Ci0gICAgICAgICAgICBpZiAoIWZFbnRpdHlTY2FubmVyLnNraXBDaGFyKCclJywgTmFtZVR5cGUuUkVGRVJFTkNFKSkgewotICAgICAgICAgICAgICAgIGlzUEVEZWNsID0gZmFsc2U7IC8vIDwhRU5USVRZIHggIngiPgotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoc2tpcFNlcGFyYXRvcih0cnVlLCAhc2Nhbm5pbmdJbnRlcm5hbFN1YnNldCgpKSkgewotICAgICAgICAgICAgICAgIC8vIDwhRU5USVRZICUgeCAieCI+Ci0gICAgICAgICAgICAgICAgaXNQRURlY2wgPSB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoc2Nhbm5pbmdJbnRlcm5hbFN1YnNldCgpKSB7Ci0gICAgICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9FTlRJVFlfTkFNRV9JTl9FTlRJVFlERUNMIiwKLSAgICAgICAgICAgICAgICBudWxsKTsKLSAgICAgICAgICAgICAgICBpc1BFRGVjbCA9IHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChmRW50aXR5U2Nhbm5lci5wZWVrQ2hhcigpID09ICclJykgewotICAgICAgICAgICAgICAgIC8vIDwhRU5USVRZICUleDsgIngiPiBpcyBsZWdhbAotICAgICAgICAgICAgICAgIHNraXBTZXBhcmF0b3IoZmFsc2UsICFzY2FubmluZ0ludGVybmFsU3Vic2V0KCkpOwotICAgICAgICAgICAgICAgIGlzUEVEZWNsID0gdHJ1ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIHNhd1BFUmVmID0gdHJ1ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChzY2FubmluZ0ludGVybmFsU3Vic2V0KCkgfHwgIWZFbnRpdHlTY2FubmVyLnNraXBDaGFyKCclJywgTmFtZVR5cGUuUkVGRVJFTkNFKSkgewotICAgICAgICAgICAgLy8gPCFFTlRJVFlbXiBdLi4uPiBvciA8IUVOVElUWVteICVdLi4uPgotICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9FTlRJVFlfTkFNRV9JTl9FTlRJVFlERUNMIiwKLSAgICAgICAgICAgIG51bGwpOwotICAgICAgICAgICAgaXNQRURlY2wgPSBmYWxzZTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChmRW50aXR5U2Nhbm5lci5za2lwU3BhY2VzKCkpIHsKLSAgICAgICAgICAgIC8vIDwhRU5USVRZJSAuLi4+Ci0gICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX1BFUkNFTlRfSU5fUEVERUNMIiwKLSAgICAgICAgICAgIG51bGwpOwotICAgICAgICAgICAgaXNQRURlY2wgPSBmYWxzZTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHNhd1BFUmVmID0gdHJ1ZTsKLSAgICAgICAgfQotICAgICAgICBpZiAoc2F3UEVSZWYpIHsKLSAgICAgICAgICAgIHdoaWxlICh0cnVlKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIHBlTmFtZSA9IGZFbnRpdHlTY2FubmVyLnNjYW5OYW1lKE5hbWVUeXBlLlJFRkVSRU5DRSk7Ci0gICAgICAgICAgICAgICAgaWYgKHBlTmFtZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIk5hbWVSZXF1aXJlZEluUEVSZWZlcmVuY2UiLCBudWxsKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSBpZiAoIWZFbnRpdHlTY2FubmVyLnNraXBDaGFyKCc7JywgTmFtZVR5cGUuUkVGRVJFTkNFKSkgewotICAgICAgICAgICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJTZW1pY29sb25SZXF1aXJlZEluUEVSZWZlcmVuY2UiLAotICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117cGVOYW1lfSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICBzdGFydFBFKHBlTmFtZSwgZmFsc2UpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBmRW50aXR5U2Nhbm5lci5za2lwU3BhY2VzKCk7Ci0gICAgICAgICAgICAgICAgaWYgKCFmRW50aXR5U2Nhbm5lci5za2lwQ2hhcignJScsIE5hbWVUeXBlLlJFRkVSRU5DRSkpCi0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGlmICghaXNQRURlY2wpIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKHNraXBTZXBhcmF0b3IodHJ1ZSwgIXNjYW5uaW5nSW50ZXJuYWxTdWJzZXQoKSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlzUEVEZWNsID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGlzUEVEZWNsID0gZkVudGl0eVNjYW5uZXIuc2tpcENoYXIoJyUnLCBOYW1lVHlwZS5SRUZFUkVOQ0UpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIG5hbWUKLSAgICAgICAgU3RyaW5nIG5hbWUgPSBmRW50aXR5U2Nhbm5lci5zY2FuTmFtZShOYW1lVHlwZS5FTlRJVFkpOwotICAgICAgICBpZiAobmFtZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJNU0dfRU5USVRZX05BTUVfUkVRVUlSRURfSU5fRU5USVRZREVDTCIsIG51bGwpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gc3BhY2VzCi0gICAgICAgIGlmICghc2tpcFNlcGFyYXRvcih0cnVlLCAhc2Nhbm5pbmdJbnRlcm5hbFN1YnNldCgpKSkgewotICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiTVNHX1NQQUNFX1JFUVVJUkVEX0FGVEVSX0VOVElUWV9OQU1FX0lOX0VOVElUWURFQ0wiLAotICAgICAgICAgICAgbmV3IE9iamVjdFtde25hbWV9KTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIGV4dGVybmFsIGlkCi0gICAgICAgIHNjYW5FeHRlcm5hbElEKGZTdHJpbmdzLCBmYWxzZSk7Ci0gICAgICAgIFN0cmluZyBzeXN0ZW1JZCA9IGZTdHJpbmdzWzBdOwotICAgICAgICBTdHJpbmcgcHVibGljSWQgPSBmU3RyaW5nc1sxXTsKLQotICAgICAgICBpZiAoaXNQRURlY2wgJiYgc3lzdGVtSWQgIT0gbnVsbCkgewotICAgICAgICAgICAgZlNlZW5FeHRlcm5hbFBFID0gdHJ1ZTsKLSAgICAgICAgfQotCi0gICAgICAgIFN0cmluZyBub3RhdGlvbiA9IG51bGw7Ci0gICAgICAgIC8vIE5EQVRBCi0gICAgICAgIGJvb2xlYW4gc2F3U3BhY2UgPSBza2lwU2VwYXJhdG9yKHRydWUsICFzY2FubmluZ0ludGVybmFsU3Vic2V0KCkpOwotICAgICAgICBpZiAoIWlzUEVEZWNsICYmIGZFbnRpdHlTY2FubmVyLnNraXBTdHJpbmcoIk5EQVRBIikpIHsKLSAgICAgICAgICAgIC8vIGNoZWNrIHdoZXRoZXIgdGhlcmUgd2FzIHNwYWNlIGJlZm9yZSBOREFUQQotICAgICAgICAgICAgaWYgKCFzYXdTcGFjZSkgewotICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIk1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfTkRBVEFfSU5fVU5QQVJTRURfRU5USVRZREVDTCIsCi0gICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde25hbWV9KTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gc3BhY2VzCi0gICAgICAgICAgICBpZiAoIXNraXBTZXBhcmF0b3IodHJ1ZSwgIXNjYW5uaW5nSW50ZXJuYWxTdWJzZXQoKSkpIHsKLSAgICAgICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX05PVEFUSU9OX05BTUVfSU5fVU5QQVJTRURfRU5USVRZREVDTCIsCi0gICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde25hbWV9KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIG5vdGF0aW9uID0gZkVudGl0eVNjYW5uZXIuc2Nhbk5hbWUoTmFtZVR5cGUuTk9UQVRJT04pOwotICAgICAgICAgICAgaWYgKG5vdGF0aW9uID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJNU0dfTk9UQVRJT05fTkFNRV9SRVFVSVJFRF9GT1JfVU5QQVJTRURfRU5USVRZREVDTCIsCi0gICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde25hbWV9KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIGludGVybmFsIGVudGl0eQotICAgICAgICBpZiAoc3lzdGVtSWQgPT0gbnVsbCkgewotICAgICAgICAgICAgc2NhbkVudGl0eVZhbHVlKG5hbWUsIGlzUEVEZWNsLCBmTGl0ZXJhbCwgZkxpdGVyYWwyKTsKLSAgICAgICAgICAgIC8vIHNpbmNlIHdlIG5lZWQgaXQncyB2YWx1ZSBhbnl3YXksIGxldCdzIHNuYWcgaXQgc28gaXQgZG9lc24ndCBnZXQgY29ycnVwdGVkCi0gICAgICAgICAgICAvLyBpZiBhIG5ldyBsb2FkIHRha2VzIHBsYWNlIGJlZm9yZSB3ZSBzdG9yZSB0aGUgZW50aXR5IHZhbHVlcwotICAgICAgICAgICAgZlN0cmluZ0J1ZmZlci5jbGVhcigpOwotICAgICAgICAgICAgZlN0cmluZ0J1ZmZlcjIuY2xlYXIoKTsKLSAgICAgICAgICAgIGZTdHJpbmdCdWZmZXIuYXBwZW5kKGZMaXRlcmFsLmNoLCBmTGl0ZXJhbC5vZmZzZXQsIGZMaXRlcmFsLmxlbmd0aCk7Ci0gICAgICAgICAgICBmU3RyaW5nQnVmZmVyMi5hcHBlbmQoZkxpdGVyYWwyLmNoLCBmTGl0ZXJhbDIub2Zmc2V0LCBmTGl0ZXJhbDIubGVuZ3RoKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIHNraXAgcG9zc2libGUgdHJhaWxpbmcgc3BhY2UKLSAgICAgICAgc2tpcFNlcGFyYXRvcihmYWxzZSwgIXNjYW5uaW5nSW50ZXJuYWxTdWJzZXQoKSk7Ci0KLSAgICAgICAgLy8gZW5kCi0gICAgICAgIGlmICghZkVudGl0eVNjYW5uZXIuc2tpcENoYXIoJz4nLCBudWxsKSkgewotICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiRW50aXR5RGVjbFVudGVybWluYXRlZCIsIG5ldyBPYmplY3RbXXtuYW1lfSk7Ci0gICAgICAgIH0KLSAgICAgICAgZk1hcmtVcERlcHRoLS07Ci0KLSAgICAgICAgLy8gcmVnaXN0ZXIgZW50aXR5IGFuZCBtYWtlIGNhbGxiYWNrCi0gICAgICAgIGlmIChpc1BFRGVjbCkgewotICAgICAgICAgICAgbmFtZSA9ICIlIiArIG5hbWU7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKHN5c3RlbUlkICE9IG51bGwpIHsKLSAgICAgICAgICAgIFN0cmluZyBiYXNlU3lzdGVtSWQgPSBmRW50aXR5U2Nhbm5lci5nZXRCYXNlU3lzdGVtSWQoKTsKLSAgICAgICAgICAgIGlmIChub3RhdGlvbiAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZkVudGl0eVN0b3JlLmFkZFVucGFyc2VkRW50aXR5KG5hbWUsIHB1YmxpY0lkLCBzeXN0ZW1JZCwgYmFzZVN5c3RlbUlkLCBub3RhdGlvbik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBmRW50aXR5U3RvcmUuYWRkRXh0ZXJuYWxFbnRpdHkobmFtZSwgcHVibGljSWQsIHN5c3RlbUlkLAotICAgICAgICAgICAgICAgIGJhc2VTeXN0ZW1JZCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoZkRUREhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIC8vVmVudSBSZXZpc2l0IDogd2h5IGZhbHNlIGhhcyBiZWVuIHJlbW92ZWQgaW4gZXhwYW5kU1lzdGVtCi0gICAgICAgICAgICAgICAgZlJlc291cmNlSWRlbnRpZmllci5zZXRWYWx1ZXMocHVibGljSWQsIHN5c3RlbUlkLCBiYXNlU3lzdGVtSWQsIFhNTEVudGl0eU1hbmFnZXIuZXhwYW5kU3lzdGVtSWQoc3lzdGVtSWQsIGJhc2VTeXN0ZW1JZCApKTsKLQotICAgICAgICAgICAgICAgIGlmIChub3RhdGlvbiAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZEVERIYW5kbGVyLnVucGFyc2VkRW50aXR5RGVjbChuYW1lLCBmUmVzb3VyY2VJZGVudGlmaWVyLAotICAgICAgICAgICAgICAgICAgICBub3RhdGlvbiwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICBmRFRESGFuZGxlci5leHRlcm5hbEVudGl0eURlY2wobmFtZSwgZlJlc291cmNlSWRlbnRpZmllciwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgZkVudGl0eVN0b3JlLmFkZEludGVybmFsRW50aXR5KG5hbWUsIGZTdHJpbmdCdWZmZXIudG9TdHJpbmcoKSk7Ci0gICAgICAgICAgICBpZiAoZkRUREhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZEVERIYW5kbGVyLmludGVybmFsRW50aXR5RGVjbChuYW1lLCBmU3RyaW5nQnVmZmVyLCBmU3RyaW5nQnVmZmVyMiwgbnVsbCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZlJlcG9ydEVudGl0eSA9IHRydWU7Ci0KLSAgICB9IC8vIHNjYW5FbnRpdHlEZWNsKCkKLQotICAgIC8qKgotICAgICAqIFNjYW5zIGFuIGVudGl0eSB2YWx1ZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgc3RyaW5nIHRvIGZpbGwgaW4gd2l0aCB0aGUgdmFsdWUuCi0gICAgICogQHBhcmFtIG5vbk5vcm1hbGl6ZWRWYWx1ZSBUaGUgc3RyaW5nIHRvIGZpbGwgaW4gd2l0aCB0aGUKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vbi1ub3JtYWxpemVkIHZhbHVlLgotICAgICAqCi0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGlzIG1ldGhvZCB1c2VzIGZTdHJpbmcsIGZTdHJpbmdCdWZmZXIgKHRocm91Z2gKLSAgICAgKiB0aGUgdXNlIG9mIHNjYW5DaGFyUmVmZXJlbmNlVmFsdWUpLCBhbmQgZlN0cmluZ0J1ZmZlcjIsIGFueXRoaW5nIGluIHRoZW0KLSAgICAgKiBhdCB0aGUgdGltZSBvZiBjYWxsaW5nIGlzIGxvc3QuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGZpbmFsIHZvaWQgc2NhbkVudGl0eVZhbHVlKFN0cmluZyBlbnRpdHlOYW1lLCBib29sZWFuIGlzUEVEZWNsLCBYTUxTdHJpbmcgdmFsdWUsCi0gICAgWE1MU3RyaW5nIG5vbk5vcm1hbGl6ZWRWYWx1ZSkKLSAgICB0aHJvd3MgSU9FeGNlcHRpb24sIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIGludCBxdW90ZSA9IGZFbnRpdHlTY2FubmVyLnNjYW5DaGFyKG51bGwpOwotICAgICAgICBpZiAocXVvdGUgIT0gJ1wnJyAmJiBxdW90ZSAhPSAnIicpIHsKLSAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIk9wZW5RdW90ZU1pc3NpbmdJbkRlY2wiLCBudWxsKTsKLSAgICAgICAgfQotICAgICAgICAvLyBzdG9yZSBhdCB3aGljaCBkZXB0aCBvZiBlbnRpdGllcyB3ZSBzdGFydAotICAgICAgICBpbnQgZW50aXR5RGVwdGggPSBmRW50aXR5RGVwdGg7Ci0KLSAgICAgICAgWE1MU3RyaW5nIGxpdGVyYWwgPSBmU3RyaW5nOwotICAgICAgICBYTUxTdHJpbmcgbGl0ZXJhbDIgPSBmU3RyaW5nOwotICAgICAgICBpbnQgY291bnRDaGFyID0gMDsKLSAgICAgICAgaWYgKGZMaW1pdEFuYWx5emVyID09IG51bGwgKSB7Ci0gICAgICAgICAgICBmTGltaXRBbmFseXplciA9IGZFbnRpdHlNYW5hZ2VyLmZMaW1pdEFuYWx5emVyOwotICAgICAgICAgfQotICAgICAgICBmTGltaXRBbmFseXplci5zdGFydEVudGl0eShlbnRpdHlOYW1lKTsKLQotICAgICAgICBpZiAoZkVudGl0eVNjYW5uZXIuc2NhbkxpdGVyYWwocXVvdGUsIGZTdHJpbmcsIGZhbHNlKSAhPSBxdW90ZSkgewotICAgICAgICAgICAgZlN0cmluZ0J1ZmZlci5jbGVhcigpOwotICAgICAgICAgICAgZlN0cmluZ0J1ZmZlcjIuY2xlYXIoKTsKLSAgICAgICAgICAgIGludCBvZmZzZXQ7Ci0gICAgICAgICAgICBkbyB7Ci0gICAgICAgICAgICAgICAgY291bnRDaGFyID0gMDsKLSAgICAgICAgICAgICAgICBvZmZzZXQgPSBmU3RyaW5nQnVmZmVyLmxlbmd0aDsKLSAgICAgICAgICAgICAgICBmU3RyaW5nQnVmZmVyLmFwcGVuZChmU3RyaW5nKTsKLSAgICAgICAgICAgICAgICBmU3RyaW5nQnVmZmVyMi5hcHBlbmQoZlN0cmluZyk7Ci0gICAgICAgICAgICAgICAgaWYgKGZFbnRpdHlTY2FubmVyLnNraXBDaGFyKCcmJywgTmFtZVR5cGUuUkVGRVJFTkNFKSkgewotICAgICAgICAgICAgICAgICAgICBpZiAoZkVudGl0eVNjYW5uZXIuc2tpcENoYXIoJyMnLCBOYW1lVHlwZS5SRUZFUkVOQ0UpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmU3RyaW5nQnVmZmVyMi5hcHBlbmQoIiYjIik7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzY2FuQ2hhclJlZmVyZW5jZVZhbHVlKGZTdHJpbmdCdWZmZXIsIGZTdHJpbmdCdWZmZXIyKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZTdHJpbmdCdWZmZXIuYXBwZW5kKCcmJyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmU3RyaW5nQnVmZmVyMi5hcHBlbmQoJyYnKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBlTmFtZSA9IGZFbnRpdHlTY2FubmVyLnNjYW5OYW1lKE5hbWVUeXBlLlJFRkVSRU5DRSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZU5hbWUgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIk5hbWVSZXF1aXJlZEluUmVmZXJlbmNlIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZTdHJpbmdCdWZmZXIuYXBwZW5kKGVOYW1lKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmU3RyaW5nQnVmZmVyMi5hcHBlbmQoZU5hbWUpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFmRW50aXR5U2Nhbm5lci5za2lwQ2hhcignOycsIE5hbWVUeXBlLlJFRkVSRU5DRSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJTZW1pY29sb25SZXF1aXJlZEluUmVmZXJlbmNlIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117ZU5hbWV9KTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZTdHJpbmdCdWZmZXIuYXBwZW5kKCc7Jyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZlN0cmluZ0J1ZmZlcjIuYXBwZW5kKCc7Jyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSBpZiAoZkVudGl0eVNjYW5uZXIuc2tpcENoYXIoJyUnLCBOYW1lVHlwZS5SRUZFUkVOQ0UpKSB7Ci0gICAgICAgICAgICAgICAgICAgIHdoaWxlICh0cnVlKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmU3RyaW5nQnVmZmVyMi5hcHBlbmQoJyUnKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBwZU5hbWUgPSBmRW50aXR5U2Nhbm5lci5zY2FuTmFtZShOYW1lVHlwZS5SRUZFUkVOQ0UpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBlTmFtZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiTmFtZVJlcXVpcmVkSW5QRVJlZmVyZW5jZSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICghZkVudGl0eVNjYW5uZXIuc2tpcENoYXIoJzsnLCBOYW1lVHlwZS5SRUZFUkVOQ0UpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiU2VtaWNvbG9uUmVxdWlyZWRJblBFUmVmZXJlbmNlIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117cGVOYW1lfSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2Nhbm5pbmdJbnRlcm5hbFN1YnNldCgpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIlBFUmVmZXJlbmNlV2l0aGluTWFya3VwIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde3BlTmFtZX0pOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmU3RyaW5nQnVmZmVyMi5hcHBlbmQocGVOYW1lKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmU3RyaW5nQnVmZmVyMi5hcHBlbmQoJzsnKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0UEUocGVOYW1lLCB0cnVlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJFVklTSVQ6IFtRXSBXaHkgZG8gd2Ugc2tpcCBzcGFjZXMgaGVyZT8gLUFjCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBSRVZJU0lUOiBUaGlzIHdpbGwgbWFrZSByZXR1cm5pbmcgdGhlIG5vbi0KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgICAgICAgIG5vcm1hbGl6ZWQgdmFsdWUgaGFyZGVyLiAtQWMKLSAgICAgICAgICAgICAgICAgICAgICAgIGZFbnRpdHlTY2FubmVyLnNraXBTcGFjZXMoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmICghZkVudGl0eVNjYW5uZXIuc2tpcENoYXIoJyUnLCBOYW1lVHlwZS5SRUZFUkVOQ0UpKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICBpbnQgYyA9IGZFbnRpdHlTY2FubmVyLnBlZWtDaGFyKCk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChYTUxDaGFyLmlzSGlnaFN1cnJvZ2F0ZShjKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgY291bnRDaGFyKys7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzY2FuU3Vycm9nYXRlcyhmU3RyaW5nQnVmZmVyMik7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoaXNJbnZhbGlkTGl0ZXJhbChjKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiSW52YWxpZENoYXJJbkxpdGVyYWwiLAotICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde0ludGVnZXIudG9IZXhTdHJpbmcoYyl9KTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZFbnRpdHlTY2FubmVyLnNjYW5DaGFyKG51bGwpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIC8vIGlmIGl0J3Mgbm90IHRoZSBkZWxpbWl0aW5nIHF1b3RlIG9yIGlmIGl0IGlzIGJ1dCBmcm9tIGEKLSAgICAgICAgICAgICAgICAgICAgLy8gZGlmZmVyZW50IGVudGl0eSB0aGFuIHRoZSBvbmUgdGhpcyBsaXRlcmFsIHN0YXJ0ZWQgZnJvbSwKLSAgICAgICAgICAgICAgICAgICAgLy8gc2ltcGx5IGFwcGVuZCB0aGUgY2hhcmFjdGVyIHRvIG91ciBidWZmZXIKLSAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoYyAhPSBxdW90ZSB8fCBlbnRpdHlEZXB0aCAhPSBmRW50aXR5RGVwdGgpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZTdHJpbmdCdWZmZXIuYXBwZW5kKChjaGFyKWMpOwotICAgICAgICAgICAgICAgICAgICAgICAgZlN0cmluZ0J1ZmZlcjIuYXBwZW5kKChjaGFyKWMpOwotICAgICAgICAgICAgICAgICAgICAgICAgZkVudGl0eVNjYW5uZXIuc2NhbkNoYXIobnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgY2hlY2tFbnRpdHlMaW1pdChpc1BFRGVjbCwgZW50aXR5TmFtZSwgZlN0cmluZ0J1ZmZlci5sZW5ndGggLSBvZmZzZXQgKyBjb3VudENoYXIpOwotICAgICAgICAgICAgfSB3aGlsZSAoZkVudGl0eVNjYW5uZXIuc2NhbkxpdGVyYWwocXVvdGUsIGZTdHJpbmcsIGZhbHNlKSAhPSBxdW90ZSk7Ci0gICAgICAgICAgICBjaGVja0VudGl0eUxpbWl0KGlzUEVEZWNsLCBlbnRpdHlOYW1lLCBmU3RyaW5nLmxlbmd0aCk7Ci0gICAgICAgICAgICBmU3RyaW5nQnVmZmVyLmFwcGVuZChmU3RyaW5nKTsKLSAgICAgICAgICAgIGZTdHJpbmdCdWZmZXIyLmFwcGVuZChmU3RyaW5nKTsKLSAgICAgICAgICAgIGxpdGVyYWwgPSBmU3RyaW5nQnVmZmVyOwotICAgICAgICAgICAgbGl0ZXJhbDIgPSBmU3RyaW5nQnVmZmVyMjsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIGNoZWNrRW50aXR5TGltaXQoaXNQRURlY2wsIGVudGl0eU5hbWUsIGxpdGVyYWwpOwotICAgICAgICB9Ci0gICAgICAgIHZhbHVlLnNldFZhbHVlcyhsaXRlcmFsKTsKLSAgICAgICAgbm9uTm9ybWFsaXplZFZhbHVlLnNldFZhbHVlcyhsaXRlcmFsMik7Ci0gICAgICAgIGlmIChmTGltaXRBbmFseXplciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAoaXNQRURlY2wpIHsKLSAgICAgICAgICAgICAgICBmTGltaXRBbmFseXplci5lbmRFbnRpdHkoWE1MU2VjdXJpdHlNYW5hZ2VyLkxpbWl0LlBBUkFNRVRFUl9FTlRJVFlfU0laRV9MSU1JVCwgZW50aXR5TmFtZSk7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIGZMaW1pdEFuYWx5emVyLmVuZEVudGl0eShYTUxTZWN1cml0eU1hbmFnZXIuTGltaXQuR0VORVJBTF9FTlRJVFlfU0laRV9MSU1JVCwgZW50aXR5TmFtZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoIWZFbnRpdHlTY2FubmVyLnNraXBDaGFyKHF1b3RlLCBudWxsKSkgewotICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiQ2xvc2VRdW90ZU1pc3NpbmdJbkRlY2wiLCBudWxsKTsKLSAgICAgICAgfQotICAgIH0gLy8gc2NhbkVudGl0eVZhbHVlKFhNTFN0cmluZyxYTUxTdHJpbmcpOnZvaWQKLQotICAgIC8qKgotICAgICAqIFNjYW5zIGEgbm90YXRpb24gZGVjbGFyYXRpb24KLSAgICAgKiA8cD4KLSAgICAgKiA8cHJlPgotICAgICAqIFs4Ml0gTm90YXRpb25EZWNsIDo6PSAnJmx0OyFOT1RBVElPTicgUyBOYW1lIFMgKEV4dGVybmFsSUR8UHVibGljSUQpIFM/ICc+JwotICAgICAqIFs4M10gIFB1YmxpY0lEICAgIDo6PSAnUFVCTElDJyBTIFB1YmlkTGl0ZXJhbAotICAgICAqIDwvcHJlPgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gQ2FsbGVkIGFmdGVyIHNjYW5uaW5nIHBhc3QgJyZsdDshTk9UQVRJT04nCi0gICAgICovCi0gICAgcHJpdmF0ZSBmaW5hbCB2b2lkIHNjYW5Ob3RhdGlvbkRlY2woKSB0aHJvd3MgSU9FeGNlcHRpb24sIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy8gc3BhY2VzCi0gICAgICAgIGZSZXBvcnRFbnRpdHkgPSBmYWxzZTsKLSAgICAgICAgaWYgKCFza2lwU2VwYXJhdG9yKHRydWUsICFzY2FubmluZ0ludGVybmFsU3Vic2V0KCkpKSB7Ci0gICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX05PVEFUSU9OX05BTUVfSU5fTk9UQVRJT05ERUNMIiwKLSAgICAgICAgICAgIG51bGwpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gbm90YXRpb24gbmFtZQotICAgICAgICBTdHJpbmcgbmFtZSA9IGZFbnRpdHlTY2FubmVyLnNjYW5OYW1lKE5hbWVUeXBlLk5PVEFUSU9OKTsKLSAgICAgICAgaWYgKG5hbWUgPT0gbnVsbCkgewotICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiTVNHX05PVEFUSU9OX05BTUVfUkVRVUlSRURfSU5fTk9UQVRJT05ERUNMIiwKLSAgICAgICAgICAgIG51bGwpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gc3BhY2VzCi0gICAgICAgIGlmICghc2tpcFNlcGFyYXRvcih0cnVlLCAhc2Nhbm5pbmdJbnRlcm5hbFN1YnNldCgpKSkgewotICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiTVNHX1NQQUNFX1JFUVVJUkVEX0FGVEVSX05PVEFUSU9OX05BTUVfSU5fTk9UQVRJT05ERUNMIiwKLSAgICAgICAgICAgIG5ldyBPYmplY3RbXXtuYW1lfSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBleHRlcm5hbCBpZAotICAgICAgICBzY2FuRXh0ZXJuYWxJRChmU3RyaW5ncywgdHJ1ZSk7Ci0gICAgICAgIFN0cmluZyBzeXN0ZW1JZCA9IGZTdHJpbmdzWzBdOwotICAgICAgICBTdHJpbmcgcHVibGljSWQgPSBmU3RyaW5nc1sxXTsKLSAgICAgICAgU3RyaW5nIGJhc2VTeXN0ZW1JZCA9IGZFbnRpdHlTY2FubmVyLmdldEJhc2VTeXN0ZW1JZCgpOwotCi0gICAgICAgIGlmIChzeXN0ZW1JZCA9PSBudWxsICYmIHB1YmxpY0lkID09IG51bGwpIHsKLSAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIkV4dGVybmFsSURvclB1YmxpY0lEUmVxdWlyZWQiLAotICAgICAgICAgICAgbmV3IE9iamVjdFtde25hbWV9KTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIHNraXAgcG9zc2libGUgdHJhaWxpbmcgc3BhY2UKLSAgICAgICAgc2tpcFNlcGFyYXRvcihmYWxzZSwgIXNjYW5uaW5nSW50ZXJuYWxTdWJzZXQoKSk7Ci0KLSAgICAgICAgLy8gZW5kCi0gICAgICAgIGlmICghZkVudGl0eVNjYW5uZXIuc2tpcENoYXIoJz4nLCBudWxsKSkgewotICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiTm90YXRpb25EZWNsVW50ZXJtaW5hdGVkIiwgbmV3IE9iamVjdFtde25hbWV9KTsKLSAgICAgICAgfQotICAgICAgICBmTWFya1VwRGVwdGgtLTsKLQotICAgICAgICBmUmVzb3VyY2VJZGVudGlmaWVyLnNldFZhbHVlcyhwdWJsaWNJZCwgc3lzdGVtSWQsIGJhc2VTeXN0ZW1JZCwgWE1MRW50aXR5TWFuYWdlci5leHBhbmRTeXN0ZW1JZChzeXN0ZW1JZCwgYmFzZVN5c3RlbUlkICkpOwotICAgICAgICBpZiAobm9uVmFsaWRhdGluZ01vZGUpIG52R3JhbW1hckluZm8ubm90YXRpb25EZWNsKG5hbWUsIGZSZXNvdXJjZUlkZW50aWZpZXIsIG51bGwpOwotICAgICAgICAvLyBjYWxsIGhhbmRsZXIKLSAgICAgICAgaWYgKGZEVERIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIC8vVmVudSBSZXZpc2l0IHdieSBmYWxzZSBoYXMgYmVlbiByZW1vdmVkLgotICAgICAgICAgICAgLy9mUmVzb3VyY2VJZGVudGlmaWVyLnNldFZhbHVlcyhwdWJsaWNJZCwgc3lzdGVtSWQsIGJhc2VTeXN0ZW1JZCwgWE1MRW50aXR5TWFuYWdlci5leHBhbmRTeXN0ZW1JZChzeXN0ZW1JZCwgYmFzZVN5c3RlbUlkLCBmYWxzZSkpOwotICAgICAgICAgICAgZkRUREhhbmRsZXIubm90YXRpb25EZWNsKG5hbWUsIGZSZXNvdXJjZUlkZW50aWZpZXIsIG51bGwpOwotICAgICAgICB9Ci0gICAgICAgIGZSZXBvcnRFbnRpdHkgPSB0cnVlOwotCi0gICAgfSAvLyBzY2FuTm90YXRpb25EZWNsKCkKLQotICAgIC8qKgotICAgICAqIFNjYW5zIGEgY29uZGl0aW9uYWwgc2VjdGlvbi4gSWYgaXQncyBhIHNlY3Rpb24gdG8gaWdub3JlIHRoZSB3aG9sZQotICAgICAqIHNlY3Rpb24gZ2V0cyBzY2FubmVkIHRocm91Z2ggYW5kIHRoaXMgbWV0aG9kIG9ubHkgcmV0dXJucyBhZnRlciB0aGUKLSAgICAgKiBjbG9zaW5nIGJyYWNrZXQgaGFzIGJlZW4gZm91bmQuIFdoZW4gaXQncyBhbiBpbmNsdWRlIHNlY3Rpb24gdGhvdWdoLCBpdAotICAgICAqIHJldHVybnMgdG8gbGV0IHRoZSBtYWluIGxvb3AgdGFrZSBjYXJlIG9mIHNjYW5uaW5nIGl0LiBJbiB0aGF0IGNhc2UgdGhlCi0gICAgICogZW5kIG9mIHRoZSBzZWN0aW9uIGlmIGhhbmRsZWQgYnkgdGhlIG1haW4gbG9vcCAoc2NhbkRlY2xzKS4KLSAgICAgKiA8cD4KLSAgICAgKiA8cHJlPgotICAgICAqIFs2MV0gY29uZGl0aW9uYWxTZWN0ICAgOjo9IGluY2x1ZGVTZWN0IHwgaWdub3JlU2VjdAotICAgICAqIFs2Ml0gaW5jbHVkZVNlY3QgICAgICAgOjo9ICcmbHQ7IVsnIFM/ICdJTkNMVURFJyBTPyAnWycgZXh0U3Vic2V0RGVjbCAnXV0+JwotICAgICAqIFs2M10gaWdub3JlU2VjdCAgIDo6PSAnJmx0OyFbJyBTPyAnSUdOT1JFJyBTPyAnWycgaWdub3JlU2VjdENvbnRlbnRzKiAnXV0+JwotICAgICAqIFs2NF0gaWdub3JlU2VjdENvbnRlbnRzIDo6PSBJZ25vcmUgKCcmbHQ7IVsnIGlnbm9yZVNlY3RDb250ZW50cyAnXV0+JyBJZ25vcmUpKgotICAgICAqIFs2NV0gSWdub3JlICAgICAgICAgICAgOjo9ICAgIENoYXIqIC0gKENoYXIqICgnJmx0OyFbJyB8ICddXT4nKSBDaGFyKikKLSAgICAgKiA8L3ByZT4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IENhbGxlZCBhZnRlciBzY2FubmluZyBwYXN0ICcmbHQ7IVsnICovCi0gICAgcHJpdmF0ZSBmaW5hbCB2b2lkIHNjYW5Db25kaXRpb25hbFNlY3QoaW50IGN1cnJQRURlcHRoKQotICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgWE5JRXhjZXB0aW9uIHsKLQotICAgICAgICBmUmVwb3J0RW50aXR5ID0gZmFsc2U7Ci0gICAgICAgIHNraXBTZXBhcmF0b3IoZmFsc2UsICFzY2FubmluZ0ludGVybmFsU3Vic2V0KCkpOwotCi0gICAgICAgIGlmIChmRW50aXR5U2Nhbm5lci5za2lwU3RyaW5nKCJJTkNMVURFIikpIHsKLSAgICAgICAgICAgIHNraXBTZXBhcmF0b3IoZmFsc2UsICFzY2FubmluZ0ludGVybmFsU3Vic2V0KCkpOwotICAgICAgICAgICAgaWYoY3VyclBFRGVwdGggIT0gZlBFRGVwdGggJiYgZlZhbGlkYXRpb24pIHsKLSAgICAgICAgICAgICAgICBmRXJyb3JSZXBvcnRlci5yZXBvcnRFcnJvcihYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sCi0gICAgICAgICAgICAgICAgIklOVkFMSURfUEVfSU5fQ09ORElUSU9OQUwiLAotICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXsgZkVudGl0eU1hbmFnZXIuZkN1cnJlbnRFbnRpdHkubmFtZX0sCi0gICAgICAgICAgICAgICAgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9FUlJPUik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyBjYWxsIGhhbmRsZXIKLSAgICAgICAgICAgIGlmICghZkVudGl0eVNjYW5uZXIuc2tpcENoYXIoJ1snLCBudWxsKSkgewotICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIk1TR19NQVJLVVBfTk9UX1JFQ09HTklaRURfSU5fRFREIiwgbnVsbCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmIChmRFRESGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZkRUREhhbmRsZXIuc3RhcnRDb25kaXRpb25hbChYTUxEVERIYW5kbGVyLkNPTkRJVElPTkFMX0lOQ0xVREUsCi0gICAgICAgICAgICAgICAgbnVsbCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmSW5jbHVkZVNlY3REZXB0aCsrOwotICAgICAgICAgICAgLy8ganVzdCBzdG9wIHRoZXJlIGFuZCBnbyBiYWNrIHRvIHRoZSBtYWluIGxvb3AKLSAgICAgICAgICAgIGZSZXBvcnRFbnRpdHkgPSB0cnVlOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKGZFbnRpdHlTY2FubmVyLnNraXBTdHJpbmcoIklHTk9SRSIpKSB7Ci0gICAgICAgICAgICBza2lwU2VwYXJhdG9yKGZhbHNlLCAhc2Nhbm5pbmdJbnRlcm5hbFN1YnNldCgpKTsKLSAgICAgICAgICAgIGlmKGN1cnJQRURlcHRoICE9IGZQRURlcHRoICYmIGZWYWxpZGF0aW9uKSB7Ci0gICAgICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLAotICAgICAgICAgICAgICAgICJJTlZBTElEX1BFX0lOX0NPTkRJVElPTkFMIiwKLSAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117IGZFbnRpdHlNYW5hZ2VyLmZDdXJyZW50RW50aXR5Lm5hbWV9LAotICAgICAgICAgICAgICAgIFhNTEVycm9yUmVwb3J0ZXIuU0VWRVJJVFlfRVJST1IpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gY2FsbCBoYW5kbGVyCi0gICAgICAgICAgICBpZiAoZkRUREhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZEVERIYW5kbGVyLnN0YXJ0Q29uZGl0aW9uYWwoWE1MRFRESGFuZGxlci5DT05ESVRJT05BTF9JR05PUkUsCi0gICAgICAgICAgICAgICAgbnVsbCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoIWZFbnRpdHlTY2FubmVyLnNraXBDaGFyKCdbJywgbnVsbCkpIHsKLSAgICAgICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJNU0dfTUFSS1VQX05PVF9SRUNPR05JWkVEX0lOX0RURCIsIG51bGwpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZlJlcG9ydEVudGl0eSA9IHRydWU7Ci0gICAgICAgICAgICBpbnQgaW5pdGlhbERlcHRoID0gKytmSW5jbHVkZVNlY3REZXB0aDsKLSAgICAgICAgICAgIGlmIChmRFRESGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZklnbm9yZUNvbmRpdGlvbmFsQnVmZmVyLmNsZWFyKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICB3aGlsZSAodHJ1ZSkgewotICAgICAgICAgICAgICAgIGlmIChmRW50aXR5U2Nhbm5lci5za2lwQ2hhcignPCcsIG51bGwpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChmRFRESGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmSWdub3JlQ29uZGl0aW9uYWxCdWZmZXIuYXBwZW5kKCc8Jyk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICAgICAgLy8gVGhlc2UgdGVzdHMgYXJlIHNwbGl0IHNvIHRoYXQgd2UgaGFuZGxlIGNhc2VzIGxpa2UKLSAgICAgICAgICAgICAgICAgICAgLy8gJzw8IVsnIGFuZCAnPCE8IVsnIHdoaWNoIHdlIG1pZ2h0IG90aGVyd2lzZSBtaXNzLgotICAgICAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgICAgICBpZiAoZkVudGl0eVNjYW5uZXIuc2tpcENoYXIoJyEnLCBudWxsKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgaWYoZkVudGl0eVNjYW5uZXIuc2tpcENoYXIoJ1snLCBudWxsKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmRFRESGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZJZ25vcmVDb25kaXRpb25hbEJ1ZmZlci5hcHBlbmQoIiFbIik7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZJbmNsdWRlU2VjdERlcHRoKys7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmRFRESGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZJZ25vcmVDb25kaXRpb25hbEJ1ZmZlci5hcHBlbmQoIiEiKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSBpZiAoZkVudGl0eVNjYW5uZXIuc2tpcENoYXIoJ10nLCBudWxsKSkgewotICAgICAgICAgICAgICAgICAgICBpZiAoZkRUREhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgZklnbm9yZUNvbmRpdGlvbmFsQnVmZmVyLmFwcGVuZCgnXScpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAgICAgICAgIC8vIFRoZSBzYW1lIHRoaW5nIGdvZXMgZm9yICddPCFbJyBhbmQgJzxdXT4nLCBldGMuCi0gICAgICAgICAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAgICAgICAgIGlmIChmRW50aXR5U2Nhbm5lci5za2lwQ2hhcignXScsIG51bGwpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZkRUREhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZJZ25vcmVDb25kaXRpb25hbEJ1ZmZlci5hcHBlbmQoJ10nKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChmRW50aXR5U2Nhbm5lci5za2lwQ2hhcignXScsIG51bGwpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogZW1wdHkgbG9vcCBib2R5ICovCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZEVERIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZklnbm9yZUNvbmRpdGlvbmFsQnVmZmVyLmFwcGVuZCgnXScpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmRW50aXR5U2Nhbm5lci5za2lwQ2hhcignPicsIG51bGwpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZJbmNsdWRlU2VjdERlcHRoLS0gPT0gaW5pdGlhbERlcHRoKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZNYXJrVXBEZXB0aC0tOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjYWxsIGhhbmRsZXIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZEVERIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZMaXRlcmFsLnNldFZhbHVlcyhmSWdub3JlQ29uZGl0aW9uYWxCdWZmZXIuY2gsIDAsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmSWdub3JlQ29uZGl0aW9uYWxCdWZmZXIubGVuZ3RoIC0gMik7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmRFRESGFuZGxlci5pZ25vcmVkQ2hhcmFjdGVycyhmTGl0ZXJhbCwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmRFRESGFuZGxlci5lbmRDb25kaXRpb25hbChudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmKGZEVERIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZklnbm9yZUNvbmRpdGlvbmFsQnVmZmVyLmFwcGVuZCgnPicpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgaW50IGMgPSBmRW50aXR5U2Nhbm5lci5zY2FuQ2hhcihudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGZTY2FubmVyU3RhdGUgPT0gU0NBTk5FUl9TVEFURV9FTkRfT0ZfSU5QVVQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIklnbm9yZVNlY3RVbnRlcm1pbmF0ZWQiLCBudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBpZiAoZkRUREhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgZklnbm9yZUNvbmRpdGlvbmFsQnVmZmVyLmFwcGVuZCgoY2hhciljKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIk1TR19NQVJLVVBfTk9UX1JFQ09HTklaRURfSU5fRFREIiwgbnVsbCk7Ci0gICAgICAgIH0KLQotICAgIH0gLy8gc2NhbkNvbmRpdGlvbmFsU2VjdCgpCi0KLSAgICAvKioKLSAgICAgKiBEaXNwYXRjaCBhbiBYTUwgImV2ZW50Ii4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjb21wbGV0ZSBUcnVlIGlmIHRoaXMgbWV0aG9kIGlzIGludGVuZGVkIHRvIHNjYW4KLSAgICAgKiAgICAgICAgICAgICAgICAgYW5kIGRpc3BhdGNoIGFzIG11Y2ggYXMgcG9zc2libGUuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRydWUgaWYgdGhlcmUgaXMgbW9yZSB0byBzY2FuLgotICAgICAqCi0gICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiAgVGhyb3duIG9uIGkvbyBlcnJvci4KLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gb24gcGFyc2UgZXJyb3IuCi0gICAgICoKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgZmluYWwgYm9vbGVhbiBzY2FuRGVjbHMoYm9vbGVhbiBjb21wbGV0ZSkKLSAgICB0aHJvd3MgSU9FeGNlcHRpb24sIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgc2tpcFNlcGFyYXRvcihmYWxzZSwgdHJ1ZSk7Ci0gICAgICAgIGJvb2xlYW4gYWdhaW4gPSB0cnVlOwotICAgICAgICAvL1N5c3RlbS5vdXQucHJpbnRsbigic2NhbkRlY2xzIitmU2Nhbm5lclN0YXRlKTsKLSAgICAgICAgd2hpbGUgKGFnYWluICYmIGZTY2FubmVyU3RhdGUgPT0gU0NBTk5FUl9TVEFURV9NQVJLVVBfREVDTCkgewotICAgICAgICAgICAgYWdhaW4gPSBjb21wbGV0ZTsKLSAgICAgICAgICAgIGlmIChmRW50aXR5U2Nhbm5lci5za2lwQ2hhcignPCcsIG51bGwpKSB7Ci0gICAgICAgICAgICAgICAgZk1hcmtVcERlcHRoKys7Ci0gICAgICAgICAgICAgICAgaWYgKGZFbnRpdHlTY2FubmVyLnNraXBDaGFyKCc/JywgbnVsbCkpIHsKLSAgICAgICAgICAgICAgICAgICAgZlN0cmluZ0J1ZmZlci5jbGVhcigpOwotICAgICAgICAgICAgICAgICAgICBzY2FuUEkoZlN0cmluZ0J1ZmZlcik7Ci0gICAgICAgICAgICAgICAgICAgIGZNYXJrVXBEZXB0aC0tOyAvLyB3ZSdyZSBkb25lIHdpdGggdGhpcyBkZWNsCi0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgaWYgKGZFbnRpdHlTY2FubmVyLnNraXBDaGFyKCchJywgbnVsbCkpIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGZFbnRpdHlTY2FubmVyLnNraXBDaGFyKCctJywgbnVsbCkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmICghZkVudGl0eVNjYW5uZXIuc2tpcENoYXIoJy0nLCBudWxsKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIk1TR19NQVJLVVBfTk9UX1JFQ09HTklaRURfSU5fRFREIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NhbkNvbW1lbnQoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChmRW50aXR5U2Nhbm5lci5za2lwU3RyaW5nKCJFTEVNRU5UIikpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHNjYW5FbGVtZW50RGVjbCgpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGZFbnRpdHlTY2FubmVyLnNraXBTdHJpbmcoIkFUVExJU1QiKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgc2NhbkF0dGxpc3REZWNsKCk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoZkVudGl0eVNjYW5uZXIuc2tpcFN0cmluZygiRU5USVRZIikpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHNjYW5FbnRpdHlEZWNsKCk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoZkVudGl0eVNjYW5uZXIuc2tpcFN0cmluZygiTk9UQVRJT04iKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgc2Nhbk5vdGF0aW9uRGVjbCgpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGZFbnRpdHlTY2FubmVyLnNraXBDaGFyKCdbJywgbnVsbCkgJiYKLSAgICAgICAgICAgICAgICAgICAgIXNjYW5uaW5nSW50ZXJuYWxTdWJzZXQoKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgc2NhbkNvbmRpdGlvbmFsU2VjdChmUEVEZXB0aCk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmTWFya1VwRGVwdGgtLTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIk1TR19NQVJLVVBfTk9UX1JFQ09HTklaRURfSU5fRFREIiwKLSAgICAgICAgICAgICAgICAgICAgICAgIG51bGwpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICBmTWFya1VwRGVwdGgtLTsKLSAgICAgICAgICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiTVNHX01BUktVUF9OT1RfUkVDT0dOSVpFRF9JTl9EVEQiLCBudWxsKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChmSW5jbHVkZVNlY3REZXB0aCA+IDAgJiYgZkVudGl0eVNjYW5uZXIuc2tpcENoYXIoJ10nLCBudWxsKSkgewotICAgICAgICAgICAgICAgIC8vIGVuZCBvZiBjb25kaXRpb25hbCBzZWN0aW9uPwotICAgICAgICAgICAgICAgIGlmICghZkVudGl0eVNjYW5uZXIuc2tpcENoYXIoJ10nLCBudWxsKQotICAgICAgICAgICAgICAgIHx8ICFmRW50aXR5U2Nhbm5lci5za2lwQ2hhcignPicsIG51bGwpKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIkluY2x1ZGVTZWN0VW50ZXJtaW5hdGVkIiwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIC8vIGNhbGwgaGFuZGxlcgotICAgICAgICAgICAgICAgIGlmIChmRFRESGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZEVERIYW5kbGVyLmVuZENvbmRpdGlvbmFsKG51bGwpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvLyBkZWNyZWFzZU1hcmt1cERlcHRoKCk7Ci0gICAgICAgICAgICAgICAgZkluY2x1ZGVTZWN0RGVwdGgtLTsKLSAgICAgICAgICAgICAgICBmTWFya1VwRGVwdGgtLTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKHNjYW5uaW5nSW50ZXJuYWxTdWJzZXQoKSAmJgotICAgICAgICAgICAgZkVudGl0eVNjYW5uZXIucGVla0NoYXIoKSA9PSAnXScpIHsKLSAgICAgICAgICAgICAgICAvLyB0aGlzIGlzIHRoZSBlbmQgb2YgdGhlIGludGVybmFsIHN1YnNldCwgbGV0J3Mgc3RvcCBoZXJlCi0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoZkVudGl0eVNjYW5uZXIuc2tpcFNwYWNlcygpKSB7Ci0gICAgICAgICAgICAgICAgLy8gc2ltcGx5IHNraXAKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIk1TR19NQVJLVVBfTk9UX1JFQ09HTklaRURfSU5fRFREIiwgbnVsbCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBza2lwU2VwYXJhdG9yKGZhbHNlLCB0cnVlKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZlNjYW5uZXJTdGF0ZSAhPSBTQ0FOTkVSX1NUQVRFX0VORF9PRl9JTlBVVDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTa2lwIHNlcGFyYXRvci4gVGhpcyBpcyB0eXBpY2FsbHkganVzdCB3aGl0ZXNwYWNlIGJ1dCBpdCBjYW4gYWxzbyBiZSBvbmUKLSAgICAgKiBvciBtb3JlIHBhcmFtZXRlciBlbnRpdHkgcmVmZXJlbmNlcy4KLSAgICAgKiA8cD4KLSAgICAgKiBJZiB0aGVyZSBhcmUgc29tZSBpdCAiZXhwYW5kcyB0aGVtIiBieSBjYWxsaW5nIHRoZSBjb3JyZXNwb25kaW5nIGVudGl0eQotICAgICAqIGZyb20gdGhlIGVudGl0eSBtYW5hZ2VyLgotICAgICAqIDxwPgotICAgICAqIFRoaXMgaXMgcmVjdXJzaXZlIGFuZCB3aWxsIHByb2Nlc3MgaGFzIG1hbnkgcmVmcyBhcyBwb3NzaWJsZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzcGFjZVJlcXVpcmVkIFNwZWNpZnkgd2hldGhlciBzb21lIGxlYWRpbmcgd2hpdGVzcGFjZSBzaG91bGQgYmUKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBmb3VuZAotICAgICAqIEBwYXJhbSBsb29rRm9yUEVSZWZzIFNwZWNpZnkgd2hldGhlciBwYXJhbWV0ZXIgZW50aXR5IHJlZmVyZW5jZXMgc2hvdWxkCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgYmUgbG9va2VkIGZvcgotICAgICAqIEByZXR1cm4gVHJ1ZSBpZiBhbnkgbGVhZGluZyB3aGl0ZXNwYWNlIHdhcyBmb3VuZCBvciB0aGUgZW5kIG9mIGEKLSAgICAgKiAgICAgICAgIHBhcmFtZXRlciBlbnRpdHkgd2FzIGNyb3NzZWQuCi0gICAgICovCi0gICAgcHJpdmF0ZSBib29sZWFuIHNraXBTZXBhcmF0b3IoYm9vbGVhbiBzcGFjZVJlcXVpcmVkLCBib29sZWFuIGxvb2tGb3JQRVJlZnMpCi0gICAgdGhyb3dzIElPRXhjZXB0aW9uLCBYTklFeGNlcHRpb24gewotICAgICAgICBpbnQgZGVwdGggPSBmUEVEZXB0aDsKLSAgICAgICAgYm9vbGVhbiBzYXdTcGFjZSA9IGZFbnRpdHlTY2FubmVyLnNraXBTcGFjZXMoKTsKLSAgICAgICAgaWYgKCFsb29rRm9yUEVSZWZzIHx8ICFmRW50aXR5U2Nhbm5lci5za2lwQ2hhcignJScsIE5hbWVUeXBlLlJFRkVSRU5DRSkpIHsKLSAgICAgICAgICAgIHJldHVybiAhc3BhY2VSZXF1aXJlZCB8fCBzYXdTcGFjZSB8fCAoZGVwdGggIT0gZlBFRGVwdGgpOwotICAgICAgICB9Ci0gICAgICAgIHdoaWxlICh0cnVlKSB7Ci0gICAgICAgICAgICBTdHJpbmcgbmFtZSA9IGZFbnRpdHlTY2FubmVyLnNjYW5OYW1lKE5hbWVUeXBlLkVOVElUWSk7Ci0gICAgICAgICAgICBpZiAobmFtZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiTmFtZVJlcXVpcmVkSW5QRVJlZmVyZW5jZSIsIG51bGwpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoIWZFbnRpdHlTY2FubmVyLnNraXBDaGFyKCc7JywgTmFtZVR5cGUuUkVGRVJFTkNFKSkgewotICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIlNlbWljb2xvblJlcXVpcmVkSW5QRVJlZmVyZW5jZSIsCi0gICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde25hbWV9KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHN0YXJ0UEUobmFtZSwgZmFsc2UpOwotICAgICAgICAgICAgZkVudGl0eVNjYW5uZXIuc2tpcFNwYWNlcygpOwotICAgICAgICAgICAgaWYgKCFmRW50aXR5U2Nhbm5lci5za2lwQ2hhcignJScsIE5hbWVUeXBlLlJFRkVSRU5DRSkpCi0gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIC8qCi0gICAgICogRWxlbWVudCBDaGlsZHJlbiBDb250ZW50IFN0YWNrCi0gICAgICovCi0gICAgcHJpdmF0ZSBmaW5hbCB2b2lkIHB1c2hDb250ZW50U3RhY2soaW50IGMpIHsKLSAgICAgICAgaWYgKGZDb250ZW50U3RhY2subGVuZ3RoID09IGZDb250ZW50RGVwdGgpIHsKLSAgICAgICAgICAgIGludFtdIG5ld1N0YWNrID0gbmV3IGludFtmQ29udGVudERlcHRoICogMl07Ci0gICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGZDb250ZW50U3RhY2ssIDAsIG5ld1N0YWNrLCAwLCBmQ29udGVudERlcHRoKTsKLSAgICAgICAgICAgIGZDb250ZW50U3RhY2sgPSBuZXdTdGFjazsKLSAgICAgICAgfQotICAgICAgICBmQ29udGVudFN0YWNrW2ZDb250ZW50RGVwdGgrK10gPSBjOwotICAgIH0KLQotICAgIHByaXZhdGUgZmluYWwgaW50IHBvcENvbnRlbnRTdGFjaygpIHsKLSAgICAgICAgcmV0dXJuIGZDb250ZW50U3RhY2tbLS1mQ29udGVudERlcHRoXTsKLSAgICB9Ci0KLQotICAgIC8qCi0gICAgICogUGFyYW1ldGVyIEVudGl0eSBTdGFjawotICAgICAqLwotICAgIHByaXZhdGUgZmluYWwgdm9pZCBwdXNoUEVTdGFjayhpbnQgZGVwdGgsIGJvb2xlYW4gcmVwb3J0KSB7Ci0gICAgICAgIGlmIChmUEVTdGFjay5sZW5ndGggPT0gZlBFRGVwdGgpIHsKLSAgICAgICAgICAgIGludFtdIG5ld0ludFN0YWNrID0gbmV3IGludFtmUEVEZXB0aCAqIDJdOwotICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShmUEVTdGFjaywgMCwgbmV3SW50U3RhY2ssIDAsIGZQRURlcHRoKTsKLSAgICAgICAgICAgIGZQRVN0YWNrID0gbmV3SW50U3RhY2s7Ci0gICAgICAgICAgICAvLyByZXBvcnQgZW5kL3N0YXJ0IGNhbGxzCi0gICAgICAgICAgICBib29sZWFuW10gbmV3Qm9vbGVhblN0YWNrID0gbmV3IGJvb2xlYW5bZlBFRGVwdGggKiAyXTsKLSAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZlBFUmVwb3J0LCAwLCBuZXdCb29sZWFuU3RhY2ssIDAsIGZQRURlcHRoKTsKLSAgICAgICAgICAgIGZQRVJlcG9ydCA9IG5ld0Jvb2xlYW5TdGFjazsKLQotICAgICAgICB9Ci0gICAgICAgIGZQRVJlcG9ydFtmUEVEZXB0aF0gPSByZXBvcnQ7Ci0gICAgICAgIGZQRVN0YWNrW2ZQRURlcHRoKytdID0gZGVwdGg7Ci0gICAgfQotCi0gICAgLyoqIHBvcCB0aGUgc3RhY2sgKi8KLSAgICBwcml2YXRlIGZpbmFsIGludCBwb3BQRVN0YWNrKCkgewotICAgICAgICByZXR1cm4gZlBFU3RhY2tbLS1mUEVEZXB0aF07Ci0gICAgfQotCi0gICAgLyoqIGxvb2sgYXQgdGhlIHRvcCBvZiB0aGUgc3RhY2sgKi8KLSAgICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gcGVla1JlcG9ydEVudGl0eSgpIHsKLSAgICAgICAgcmV0dXJuIGZQRVJlcG9ydFtmUEVEZXB0aC0xXTsKLSAgICB9Ci0KLQotICAgIC8qCi0gICAgICogVXRpbGl0eSBtZXRob2QKLSAgICAgKi8KLSAgICBwcml2YXRlIGZpbmFsIHZvaWQgZW5zdXJlRW51bWVyYXRpb25TaXplKGludCBzaXplKSB7Ci0gICAgICAgIGlmIChmRW51bWVyYXRpb24ubGVuZ3RoID09IHNpemUpIHsKLSAgICAgICAgICAgIFN0cmluZ1tdIG5ld0VudW0gPSBuZXcgU3RyaW5nW3NpemUgKiAyXTsKLSAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZkVudW1lcmF0aW9uLCAwLCBuZXdFbnVtLCAwLCBzaXplKTsKLSAgICAgICAgICAgIGZFbnVtZXJhdGlvbiA9IG5ld0VudW07Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvLyBwcml2YXRlIG1ldGhvZHMKLSAgICBwcml2YXRlIHZvaWQgaW5pdCgpIHsKLSAgICAgICAgLy8gcmVzZXQgc3RhdGUgcmVsYXRlZCBkYXRhCi0gICAgICAgIGZTdGFydERURENhbGxlZCA9IGZhbHNlOwotICAgICAgICBmRXh0RW50aXR5RGVwdGggPSAwOwotICAgICAgICBmSW5jbHVkZVNlY3REZXB0aCA9IDA7Ci0gICAgICAgIGZNYXJrVXBEZXB0aCA9IDA7Ci0gICAgICAgIGZQRURlcHRoID0gMDsKLQotICAgICAgICBmU3RhbmRhbG9uZSA9IGZhbHNlOwotICAgICAgICBmU2VlbkV4dGVybmFsRFREID0gZmFsc2U7Ci0gICAgICAgIGZTZWVuRXh0ZXJuYWxQRSA9IGZhbHNlOwotCi0gICAgICAgIC8vIHNldCBzdGFydGluZyBzdGF0ZQotICAgICAgICBzZXRTY2FubmVyU3RhdGUoU0NBTk5FUl9TVEFURV9URVhUX0RFQ0wpOwotICAgICAgICAvL25ldyBTeW1ib2xUYWJsZSgpKTsKLQotICAgICAgICBmTGltaXRBbmFseXplciA9IGZFbnRpdHlNYW5hZ2VyLmZMaW1pdEFuYWx5emVyOwotICAgICAgICBmU2VjdXJpdHlNYW5hZ2VyID0gZkVudGl0eU1hbmFnZXIuZlNlY3VyaXR5TWFuYWdlcjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgRFRER3JhbW1hciBnZXRHcmFtbWFyKCl7Ci0gICAgICAgIHJldHVybiBudkdyYW1tYXJJbmZvOwotICAgIH0KLQotfSAvLyBjbGFzcyBYTUxEVERTY2FubmVySW1wbApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9YTUxEb2N1bWVudEZyYWdtZW50U2Nhbm5lckltcGwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvWE1MRG9jdW1lbnRGcmFnbWVudFNjYW5uZXJJbXBsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDZkMTk3YzUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9YTUxEb2N1bWVudEZyYWdtZW50U2Nhbm5lckltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDMyOTIgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwMywgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqLwotCi0vKgotICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCi0gKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKLSAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KLSAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCi0gKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAotICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGw7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwubXNnLlhNTE1lc3NhZ2VGb3JtYXR0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLkF1Z21lbnRhdGlvbnNJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5YTUxBdHRyaWJ1dGVzSXRlcmF0b3JJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5YTUxDaGFyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5YTUxTdHJpbmdCdWZmZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlhNTFN5bWJvbHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlscy5TZWN1cml0eVN1cHBvcnQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlscy5YTUxTZWN1cml0eU1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlscy5YTUxTZWN1cml0eU1hbmFnZXIuTGltaXQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlscy5YTUxTZWN1cml0eVByb3BlcnR5TWFuYWdlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5BdWdtZW50YXRpb25zOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlFOYW1lOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTEF0dHJpYnV0ZXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MRG9jdW1lbnRIYW5kbGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTFJlc291cmNlSWRlbnRpZmllcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxTdHJpbmc7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE5JRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxDb21wb25lbnQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTENvbXBvbmVudE1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTERvY3VtZW50U2Nhbm5lcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MSW5wdXRTb3VyY2U7Ci1pbXBvcnQgY29tLnN1bi54bWwuaW50ZXJuYWwuc3RyZWFtLlhNTEJ1ZmZlckxpc3RlbmVyOwotaW1wb3J0IGNvbS5zdW4ueG1sLmludGVybmFsLnN0cmVhbS5YTUxFbnRpdHlTdG9yYWdlOwotaW1wb3J0IGNvbS5zdW4ueG1sLmludGVybmFsLnN0cmVhbS5kdGQuRFRER3JhbW1hclV0aWw7Ci1pbXBvcnQgamF2YS5pby5FT0ZFeGNlcHRpb247Ci1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLlhNTElucHV0RmFjdG9yeTsKLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLlhNTFN0cmVhbUNvbnN0YW50czsKLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLmV2ZW50cy5YTUxFdmVudDsKLQotCi0vKioKLSAqCi0gKiBUaGlzIGNsYXNzIGlzIHJlc3BvbnNpYmxlIGZvciBzY2FubmluZyB0aGUgc3RydWN0dXJlIGFuZCBjb250ZW50Ci0gKiBvZiBkb2N1bWVudCBmcmFnbWVudHMuCi0gKgotICogVGhpcyBjbGFzcyBoYXMgYmVlbiBtb2RpZmllZCBhcyBwZXIgdGhlIG5ldyBkZXNpZ24gd2hpY2ggaXMgbW9yZSBzdWl0ZWQgdG8KLSAqIGVmZmljaWVudGx5IGJ1aWxkIHB1bGwgcGFyc2VyLiBMb3Qgb2YgaW1wcm92ZW1lbnRzIGhhdmUgYmVlbiBkb25lIGFuZAotICogdGhlIGNvZGUgaGFzIGJlZW4gYWRkZWQgdG8gc3VwcG9ydCBzdGF4IGZ1bmN0aW9uYWxpdHkvZmVhdHVyZXMuCi0gKgotICogQGF1dGhvciBOZWVyYWogQmFqYWogU1VOIE1pY3Jvc3lzdGVtcwotICogQGF1dGhvciBLLlZlbnVnb3BhbCBTVU4gTWljcm9zeXN0ZW1zCi0gKiBAYXV0aG9yIEdsZW5uIE1hcmN5LCBJQk0KLSAqIEBhdXRob3IgQW5keSBDbGFyaywgSUJNCi0gKiBAYXV0aG9yIEFybmF1ZCAgTGUgSG9ycywgSUJNCi0gKiBAYXV0aG9yIEVyaWMgWWUsIElCTQotICogQGF1dGhvciBTdW5pdGhhIFJlZGR5LCBTVU4gTWljcm9zeXN0ZW1zCi0gKiBAdmVyc2lvbiAkSWQ6IFhNTERvY3VtZW50RnJhZ21lbnRTY2FubmVySW1wbC5qYXZhLHYgMS4xOSAyMDEwLTExLTAyIDE5OjU0OjU1IGpvZWh3IEV4cCAkCi0gKgotICovCi1wdWJsaWMgY2xhc3MgWE1MRG9jdW1lbnRGcmFnbWVudFNjYW5uZXJJbXBsCi0gICAgICAgIGV4dGVuZHMgWE1MU2Nhbm5lcgotICAgICAgICBpbXBsZW1lbnRzIFhNTERvY3VtZW50U2Nhbm5lciwgWE1MQ29tcG9uZW50LCBYTUxFbnRpdHlIYW5kbGVyLCBYTUxCdWZmZXJMaXN0ZW5lciB7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0YW50cwotICAgIC8vCi0KLSAgICBwcm90ZWN0ZWQgaW50IGZFbGVtZW50QXR0cmlidXRlTGltaXQsIGZYTUxOYW1lTGltaXQ7Ci0KLSAgICAvKiogRXh0ZXJuYWwgc3Vic2V0IHJlc29sdmVyLiAqKi8KLSAgICBwcm90ZWN0ZWQgRXh0ZXJuYWxTdWJzZXRSZXNvbHZlciBmRXh0ZXJuYWxTdWJzZXRSZXNvbHZlcjsKLQotICAgIC8vIHNjYW5uZXIgc3RhdGVzCi0KLSAgICAvL1hYWCB0aGlzIHNob3VsZCBiZSBkaXZpZGVkIGludG8gbW9yZSBzdGF0ZXMuCi0gICAgLyoqIFNjYW5uZXIgc3RhdGU6IHN0YXJ0IG9mIG1hcmt1cC4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBTQ0FOTkVSX1NUQVRFX1NUQVJUX09GX01BUktVUCA9IDIxOwotCi0gICAgLyoqIFNjYW5uZXIgc3RhdGU6IGNvbnRlbnQuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBpbnQgU0NBTk5FUl9TVEFURV9DT05URU5UID0gMjI7Ci0KLSAgICAvKiogU2Nhbm5lciBzdGF0ZTogcHJvY2Vzc2luZyBpbnN0cnVjdGlvbi4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBTQ0FOTkVSX1NUQVRFX1BJID0gMjM7Ci0KLSAgICAvKiogU2Nhbm5lciBzdGF0ZTogRE9DVFlQRS4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBTQ0FOTkVSX1NUQVRFX0RPQ1RZUEUgPSAyNDsKLQotICAgIC8qKiBTY2FubmVyIHN0YXRlOiBYTUwgRGVjbGFyYXRpb24gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBTQ0FOTkVSX1NUQVRFX1hNTF9ERUNMID0gMjU7Ci0KLSAgICAvKiogU2Nhbm5lciBzdGF0ZTogcm9vdCBlbGVtZW50LiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgaW50IFNDQU5ORVJfU1RBVEVfUk9PVF9FTEVNRU5UID0gMjY7Ci0KLSAgICAvKiogU2Nhbm5lciBzdGF0ZTogY29tbWVudC4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBTQ0FOTkVSX1NUQVRFX0NPTU1FTlQgPSAyNzsKLQotICAgIC8qKiBTY2FubmVyIHN0YXRlOiByZWZlcmVuY2UuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBpbnQgU0NBTk5FUl9TVEFURV9SRUZFUkVOQ0UgPSAyODsKLQotICAgIC8vIDxib29rIHR5cGU9ImhhcmQiPiByZWFkaW5nIGF0dHJpYnV0ZSBuYW1lICd0eXBlJwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgaW50IFNDQU5ORVJfU1RBVEVfQVRUUklCVVRFID0gMjk7Ci0KLSAgICAvLyA8Ym9vayB0eXBlPSJoYXJkIj4gLy9yZWFkaW5nIGF0dHJpYnV0ZSB2YWx1ZS4KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBTQ0FOTkVSX1NUQVRFX0FUVFJJQlVURV9WQUxVRSA9IDMwOwotCi0gICAgLyoqIFNjYW5uZXIgc3RhdGU6IHRyYWlsaW5nIG1pc2MuIFVTRUQgQlkgRE9DVU1FTlRfU0NBTk5FUl9JTVBMKi8KLSAgICAvL3Byb3RlY3RlZCBzdGF0aWMgZmluYWwgaW50IFNDQU5ORVJfU1RBVEVfVFJBSUxJTkdfTUlTQyA9IDMyOwotCi0gICAgLyoqIFNjYW5uZXIgc3RhdGU6IGVuZCBvZiBpbnB1dC4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBTQ0FOTkVSX1NUQVRFX0VORF9PRl9JTlBVVCA9IDMzOwotCi0gICAgLyoqIFNjYW5uZXIgc3RhdGU6IHRlcm1pbmF0ZWQuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBpbnQgU0NBTk5FUl9TVEFURV9URVJNSU5BVEVEID0gMzQ7Ci0KLSAgICAvKiogU2Nhbm5lciBzdGF0ZTogQ0RBVEEgc2VjdGlvbi4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBTQ0FOTkVSX1NUQVRFX0NEQVRBID0gMzU7Ci0KLSAgICAvKiogU2Nhbm5lciBzdGF0ZTogVGV4dCBkZWNsYXJhdGlvbi4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBTQ0FOTkVSX1NUQVRFX1RFWFRfREVDTCA9IDM2OwotCi0gICAgLyoqIFNjYW5uZXIgc3RhdGU6IFRleHQgZGVjbGFyYXRpb24uICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBpbnQgU0NBTk5FUl9TVEFURV9DSEFSQUNURVJfREFUQSA9IDM3OwotCi0gICAgLy88Ym9vayB0eXBlPSJoYXJkIj5mb288L2Jvb2s+Ci0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBpbnQgU0NBTk5FUl9TVEFURV9TVEFSVF9FTEVNRU5UX1RBRyA9IDM4OwotCi0gICAgLy88Ym9vayB0eXBlPSJoYXJkIj5mb288L2Jvb2s+IHJlYWRpbmcgPC9ib29rPgotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgaW50IFNDQU5ORVJfU1RBVEVfRU5EX0VMRU1FTlRfVEFHID0gMzk7Ci0KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBTQ0FOTkVSX1NUQVRFX0NIQVJfUkVGRVJFTkNFID0gNDA7Ci0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBpbnQgU0NBTk5FUl9TVEFURV9CVUlMVF9JTl9SRUZTID0gNDE7Ci0KLSAgICAvLyBmZWF0dXJlIGlkZW50aWZpZXJzCi0KLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IG5vdGlmeSBidWlsdC1pbiByZWZlcmVjZXMuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgTk9USUZZX0JVSUxUSU5fUkVGUyA9Ci0gICAgICAgICAgICBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLk5PVElGWV9CVUlMVElOX1JFRlNfRkVBVFVSRTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBlbnRpdHkgcmVzb2x2ZXIuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgRU5USVRZX1JFU09MVkVSID0KLSAgICAgICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLkVOVElUWV9SRVNPTFZFUl9QUk9QRVJUWTsKLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IHN0YW5kYXJkIHVyaSBjb25mb3JtYW50ICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1RBTkRBUkRfVVJJX0NPTkZPUk1BTlQgPQotICAgICAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArQ29uc3RhbnRzLlNUQU5EQVJEX1VSSV9DT05GT1JNQU5UX0ZFQVRVUkU7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogU2VjdXJpdHkgcHJvcGVydHkgbWFuYWdlci4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MX1NFQ1VSSVRZX1BST1BFUlRZX01BTkFHRVIgPQotICAgICAgICAgICAgQ29uc3RhbnRzLlhNTF9TRUNVUklUWV9QUk9QRVJUWV9NQU5BR0VSOwotCi0gICAgLyoqIGFjY2VzcyBleHRlcm5hbCBkdGQ6IGZpbGUgcHJvdG9jb2wKLSAgICAgKiAgRm9yIERPTS9TQVgsIHRoZSBzZWN1cmUgZmVhdHVyZSBpcyBzZXQgdG8gdHJ1ZSBieSBkZWZhdWx0Ci0gICAgICovCi0gICAgZmluYWwgc3RhdGljIFN0cmluZyBFWFRFUk5BTF9BQ0NFU1NfREVGQVVMVCA9IENvbnN0YW50cy5FWFRFUk5BTF9BQ0NFU1NfREVGQVVMVDsKLQotICAgIC8vIHJlY29nbml6ZWQgZmVhdHVyZXMgYW5kIHByb3BlcnRpZXMKLQotICAgIC8qKiBSZWNvZ25pemVkIGZlYXR1cmVzLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZ1tdIFJFQ09HTklaRURfRkVBVFVSRVMgPSB7Ci0gICAgICAgICAgICAgICAgTkFNRVNQQUNFUywKLSAgICAgICAgICAgICAgICBWQUxJREFUSU9OLAotICAgICAgICAgICAgICAgIE5PVElGWV9CVUlMVElOX1JFRlMsCi0gICAgICAgICAgICAgICAgTk9USUZZX0NIQVJfUkVGUywKLSAgICAgICAgICAgICAgICBDb25zdGFudHMuU1RBWF9SRVBPUlRfQ0RBVEFfRVZFTlQKLSAgICB9OwotCi0gICAgLyoqIEZlYXR1cmUgZGVmYXVsdHMuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQm9vbGVhbltdIEZFQVRVUkVfREVGQVVMVFMgPSB7Ci0gICAgICAgICAgICAgICAgQm9vbGVhbi5UUlVFLAotICAgICAgICAgICAgICAgIG51bGwsCi0gICAgICAgICAgICAgICAgQm9vbGVhbi5GQUxTRSwKLSAgICAgICAgICAgICAgICBCb29sZWFuLkZBTFNFLAotICAgICAgICAgICAgICAgIEJvb2xlYW4uVFJVRQotICAgIH07Ci0KLSAgICAvKiogUmVjb2duaXplZCBwcm9wZXJ0aWVzLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZ1tdIFJFQ09HTklaRURfUFJPUEVSVElFUyA9IHsKLSAgICAgICAgU1lNQk9MX1RBQkxFLAotICAgICAgICAgICAgICAgIEVSUk9SX1JFUE9SVEVSLAotICAgICAgICAgICAgICAgIEVOVElUWV9NQU5BR0VSLAotICAgICAgICAgICAgICAgIFhNTF9TRUNVUklUWV9QUk9QRVJUWV9NQU5BR0VSCi0gICAgfTsKLQotICAgIC8qKiBQcm9wZXJ0eSBkZWZhdWx0cy4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBPYmplY3RbXSBQUk9QRVJUWV9ERUZBVUxUUyA9IHsKLSAgICAgICAgICAgICAgICBudWxsLAotICAgICAgICAgICAgICAgIG51bGwsCi0gICAgICAgICAgICAgICAgbnVsbCwKLSAgICAgICAgICAgICAgICBudWxsCi0gICAgfTsKLQotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNoYXIgW10gY2RhdGEgPSB7J1snLCdDJywnRCcsJ0EnLCdUJywnQScsJ1snfTsKLSAgICBzdGF0aWMgZmluYWwgY2hhciBbXSB4bWxEZWNsID0geyc8JywnPycsJ3gnLCdtJywnbCd9OwotICAgIC8vIHByaXZhdGUgc3RhdGljIGZpbmFsIGNoYXIgW10gZW5kVGFnID0geyc8JywnLyd9OwotICAgIC8vIGRlYnVnZ2luZwotCi0gICAgLyoqIERlYnVnIHNjYW5uZXIgc3RhdGUuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbiBERUJVR19TQ0FOTkVSX1NUQVRFID0gZmFsc2U7Ci0KLSAgICAvKiogRGVidWcgZHJpdmVyLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW4gREVCVUdfRElTUEFUQ0hFUiA9IGZhbHNlOwotCi0gICAgLyoqIERlYnVnIGNvbnRlbnQgZHJpdmVyIHNjYW5uaW5nLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgYm9vbGVhbiBERUJVR19TVEFSVF9FTkRfRUxFTUVOVCA9IGZhbHNlOwotCi0KLSAgICAvKiogRGVidWcgZHJpdmVyIG5leHQgKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGJvb2xlYW4gREVCVUdfTkVYVCA9IGZhbHNlIDsKLQotICAgIC8qKiBEZWJ1ZyBkcml2ZXIgbmV4dCAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgYm9vbGVhbiBERUJVRyA9IGZhbHNlOwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgYm9vbGVhbiBERUJVR19DT0FMRVNDRSA9IGZhbHNlOwotICAgIC8vCi0gICAgLy8gRGF0YQotICAgIC8vCi0KLSAgICAvLyBwcm90ZWN0ZWQgZGF0YQotCi0gICAgLyoqIERvY3VtZW50IGhhbmRsZXIuICovCi0gICAgcHJvdGVjdGVkIFhNTERvY3VtZW50SGFuZGxlciBmRG9jdW1lbnRIYW5kbGVyOwotICAgIHByb3RlY3RlZCBpbnQgZlNjYW5uZXJMYXN0U3RhdGUgOwotCi0gICAgLyoqIEVudGl0eSBTdG9yYWdlICovCi0gICAgcHJvdGVjdGVkIFhNTEVudGl0eVN0b3JhZ2UgZkVudGl0eVN0b3JlOwotCi0gICAgLyoqIEVudGl0eSBzdGFjay4gKi8KLSAgICBwcm90ZWN0ZWQgaW50W10gZkVudGl0eVN0YWNrID0gbmV3IGludFs0XTsKLQotICAgIC8qKiBNYXJrdXAgZGVwdGguICovCi0gICAgcHJvdGVjdGVkIGludCBmTWFya3VwRGVwdGg7Ci0KLSAgICAvL2lzIHRoZSBlbGVtZW50IGVtcHR5Ci0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZkVtcHR5RWxlbWVudCA7Ci0KLSAgICAvL3RyYWNrIGlmIHdlIGFyZSByZWFkaW5nIGF0dHJpYnV0ZXMsIHRoaXMgaXMgdXNlZnVsZSB3aGlsZQotICAgIC8vdGhlcmUgaXMgYSBjYWxsYmFjawotICAgIHByb3RlY3RlZCBib29sZWFuIGZSZWFkaW5nQXR0cmlidXRlcyA9IGZhbHNlOwotCi0gICAgLyoqIFNjYW5uZXIgc3RhdGUuICovCi0gICAgcHJvdGVjdGVkIGludCBmU2Nhbm5lclN0YXRlOwotCi0gICAgLyoqIFN1YlNjYW5uZXIgc3RhdGU6IGluc2lkZSBzY2FuQ29udGVudCBtZXRob2QuICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZkluU2NhbkNvbnRlbnQgPSBmYWxzZTsKLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBmTGFzdFNlY3Rpb25XYXNDRGF0YSA9IGZhbHNlOwotICAgIHByb3RlY3RlZCBib29sZWFuIGZMYXN0U2VjdGlvbldhc0VudGl0eVJlZmVyZW5jZSA9IGZhbHNlOwotICAgIHByb3RlY3RlZCBib29sZWFuIGZMYXN0U2VjdGlvbldhc0NoYXJhY3RlckRhdGEgPSBmYWxzZTsKLQotICAgIC8qKiBoYXMgZXh0ZXJuYWwgZHRkICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZkhhc0V4dGVybmFsRFREOwotCi0gICAgLyoqIFN0YW5kYWxvbmUuICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZlN0YW5kYWxvbmVTZXQ7Ci0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZlN0YW5kYWxvbmU7Ci0gICAgcHJvdGVjdGVkIFN0cmluZyBmVmVyc2lvbjsKLQotICAgIC8vIGVsZW1lbnQgaW5mb3JtYXRpb24KLQotICAgIC8qKiBDdXJyZW50IGVsZW1lbnQuICovCi0gICAgcHJvdGVjdGVkIFFOYW1lIGZDdXJyZW50RWxlbWVudDsKLQotICAgIC8qKiBFbGVtZW50IHN0YWNrLiAqLwotICAgIHByb3RlY3RlZCBFbGVtZW50U3RhY2sgZkVsZW1lbnRTdGFjayA9IG5ldyBFbGVtZW50U3RhY2soKTsKLSAgICBwcm90ZWN0ZWQgRWxlbWVudFN0YWNrMiBmRWxlbWVudFN0YWNrMiA9IG5ldyBFbGVtZW50U3RhY2syKCk7Ci0KLSAgICAvLyBvdGhlciBpbmZvCi0KLSAgICAvKiogRG9jdW1lbnQgc3lzdGVtIGlkZW50aWZpZXIuCi0gICAgICogUkVWSVNJVDogIFNvIHdoYXQncyB0aGlzIHVzZWQgZm9yPyAgLSBORwotICAgICAqIHByb3RlY3RlZCBTdHJpbmcgZkRvY3VtZW50U3lzdGVtSWQ7Ci0gICAgICoqKioqKi8KLQotICAgIHByb3RlY3RlZCBTdHJpbmcgZlBJVGFyZ2V0IDsKLQotICAgIC8veHh4IGRvIHdlIG5lZWQgdG8gY3JlYXRlIGFuIGV4dHJhIFhNTFN0cmluZyBvYmplY3QuLi4gbG9vayBmb3IgdXNpbmcgZlRlbXBTdHJpbmcgZm9yIGNvbGxlY3RpbmcgYWxsIHRoZSBkYXRhIHZhbHVlcwotICAgIHByb3RlY3RlZCBYTUxTdHJpbmcgZlBJRGF0YSAgPSBuZXcgWE1MU3RyaW5nKCk7Ci0KLSAgICAvLyBmZWF0dXJlcwotCi0KLSAgICAvKiogTm90aWZ5IGJ1aWx0LWluIHJlZmVyZW5jZXMuICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZk5vdGlmeUJ1aWx0SW5SZWZzID0gZmFsc2U7Ci0KLSAgICAvL1NUQVggcmVsYXRlZCBwcm9wZXJ0aWVzCi0gICAgLy9kZWZhdWx0VmFsdWVzLgotICAgIHByb3RlY3RlZCBib29sZWFuIGZTdXBwb3J0RFREID0gdHJ1ZTsKLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBmUmVwbGFjZUVudGl0eVJlZmVyZW5jZXMgPSB0cnVlOwotICAgIHByb3RlY3RlZCBib29sZWFuIGZTdXBwb3J0RXh0ZXJuYWxFbnRpdGllcyA9IGZhbHNlOwotICAgIHByb3RlY3RlZCBib29sZWFuIGZSZXBvcnRDZGF0YUV2ZW50ID0gZmFsc2UgOwotICAgIHByb3RlY3RlZCBib29sZWFuIGZJc0NvYWxlc2NlID0gZmFsc2UgOwotICAgIHByb3RlY3RlZCBTdHJpbmcgZkRlY2xhcmVkRW5jb2RpbmcgPSAgbnVsbDsKLSAgICAvKiogWGVyY2VzIEZlYXR1cmU6IERpc2FsbG93IGRvY3R5cGUgZGVjbGFyYXRpb24uICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZkRpc2FsbG93RG9jdHlwZSA9IGZhbHNlOwotCi0gICAgLyoqCi0gICAgICogY29tbWEtZGVsaW1pdGVkIGxpc3Qgb2YgcHJvdG9jb2xzIHRoYXQgYXJlIGFsbG93ZWQgZm9yIHRoZSBwdXJwb3NlCi0gICAgICogb2YgYWNjZXNzaW5nIGV4dGVybmFsIGR0ZCBvciBlbnRpdHkgcmVmZXJlbmNlcwotICAgICAqLwotICAgIHByb3RlY3RlZCBTdHJpbmcgZkFjY2Vzc0V4dGVybmFsRFREID0gRVhURVJOQUxfQUNDRVNTX0RFRkFVTFQ7Ci0KLSAgICAvKioKLSAgICAgKiBzdGFuZGFyZCB1cmkgY29uZm9ybWFudCAoc3RyaWN0IHVyaSkuCi0gICAgICogaHR0cDovL2FwYWNoZS5vcmcveG1sL2ZlYXR1cmVzL3N0YW5kYXJkLXVyaS1jb25mb3JtYW50Ci0gICAgICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZlN0cmljdFVSSTsKLQotICAgIC8vIGRyaXZlcnMKLQotICAgIC8qKiBBY3RpdmUgZHJpdmVyLiAqLwotICAgIHByb3RlY3RlZCBEcml2ZXIgZkRyaXZlcjsKLQotICAgIC8qKiBDb250ZW50IGRyaXZlci4gKi8KLSAgICBwcm90ZWN0ZWQgRHJpdmVyIGZDb250ZW50RHJpdmVyID0gY3JlYXRlQ29udGVudERyaXZlcigpOwotCi0gICAgLy8gdGVtcG9yYXJ5IHZhcmlhYmxlcwotCi0gICAgLyoqIEVsZW1lbnQgUU5hbWUuICovCi0gICAgcHJvdGVjdGVkIFFOYW1lIGZFbGVtZW50UU5hbWUgPSBuZXcgUU5hbWUoKTsKLQotICAgIC8qKiBBdHRyaWJ1dGUgUU5hbWUuICovCi0gICAgcHJvdGVjdGVkIFFOYW1lIGZBdHRyaWJ1dGVRTmFtZSA9IG5ldyBRTmFtZSgpOwotCi0gICAgLyoqCi0gICAgICogQ0hBTkdFRDogVXNpbmcgWE1MQXR0cmlidXRlc0l0ZXJhdG9ySW1wbCBpbnN0ZWFkIG9mIFhNTEF0dHJpYnV0ZXNJbXBsLiBUaGlzIGNsYXNzCi0gICAgICogaW1wbGVtZW50cyBJdGVyYXRvciBpbnRlcmZhY2Ugc28gd2UgY2FuIGRpcmVjdGx5IGdpdmUgQXR0cmlidXRlcyBpbiB0aGUgZm9ybSBvZgotICAgICAqIGl0ZXJhdG9yLgotICAgICAqLwotICAgIHByb3RlY3RlZCBYTUxBdHRyaWJ1dGVzSXRlcmF0b3JJbXBsIGZBdHRyaWJ1dGVzID0gbmV3IFhNTEF0dHJpYnV0ZXNJdGVyYXRvckltcGwoKTsKLQotCi0gICAgLyoqIFN0cmluZy4gKi8KLSAgICBwcm90ZWN0ZWQgWE1MU3RyaW5nIGZUZW1wU3RyaW5nID0gbmV3IFhNTFN0cmluZygpOwotCi0gICAgLyoqIFN0cmluZy4gKi8KLSAgICBwcm90ZWN0ZWQgWE1MU3RyaW5nIGZUZW1wU3RyaW5nMiA9IG5ldyBYTUxTdHJpbmcoKTsKLQotICAgIC8qKiBBcnJheSBvZiAzIHN0cmluZ3MuICovCi0gICAgcHJpdmF0ZSBTdHJpbmdbXSBmU3RyaW5ncyA9IG5ldyBTdHJpbmdbM107Ci0KLSAgICAvKiogTWFraW5nIHRoZSBidWZmZXIgYWNjZXNpYmxlIHRvIGRlcml2ZWQgY2xhc3MgLS0gU3RyaW5nIGJ1ZmZlci4gKi8KLSAgICBwcm90ZWN0ZWQgWE1MU3RyaW5nQnVmZmVyIGZTdHJpbmdCdWZmZXIgPSBuZXcgWE1MU3RyaW5nQnVmZmVyKCk7Ci0KLSAgICAvKiogTWFraW5nIHRoZSBidWZmZXIgYWNjZXNpYmxlIHRvIGRlcml2ZWQgY2xhc3MgLS0gU3RyaW5nIGJ1ZmZlci4gKi8KLSAgICBwcm90ZWN0ZWQgWE1MU3RyaW5nQnVmZmVyIGZTdHJpbmdCdWZmZXIyID0gbmV3IFhNTFN0cmluZ0J1ZmZlcigpOwotCi0gICAgLyoqIHN0b3JlcyBjaGFyYWN0ZXIgZGF0YS4gKi8KLSAgICAvKiogTWFraW5nIHRoZSBidWZmZXIgYWNjZXNpYmxlIHRvIGRlcml2ZWQgY2xhc3MgLS0gc3RvcmVzIFBJIGRhdGEgKi8KLSAgICBwcm90ZWN0ZWQgWE1MU3RyaW5nQnVmZmVyIGZDb250ZW50QnVmZmVyID0gbmV3IFhNTFN0cmluZ0J1ZmZlcigpOwotCi0gICAgLyoqIFNpbmdsZSBjaGFyYWN0ZXIgYXJyYXkuICovCi0gICAgcHJpdmF0ZSBmaW5hbCBjaGFyW10gZlNpbmdsZUNoYXIgPSBuZXcgY2hhclsxXTsKLSAgICBwcml2YXRlIFN0cmluZyBmQ3VycmVudEVudGl0eU5hbWUgPSBudWxsOwotCi0gICAgLy8gTmV3IG1lbWJlcnMKLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBmU2NhblRvRW5kID0gZmFsc2U7Ci0KLSAgICBwcm90ZWN0ZWQgRFRER3JhbW1hclV0aWwgZHRkR3JhbW1hclV0aWw9IG51bGw7Ci0KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBmQWRkRGVmYXVsdEF0dHIgPSBmYWxzZTsKLQotICAgIHByb3RlY3RlZCBib29sZWFuIGZvdW5kQnVpbHRJblJlZnMgPSBmYWxzZTsKLQotCi0gICAgLy9za2lwIGVsZW1lbnQgYWxnb3JpdGhtCi0gICAgc3RhdGljIGZpbmFsIHNob3J0IE1BWF9ERVBUSF9MSU1JVCA9IDUgOwotICAgIHN0YXRpYyBmaW5hbCBzaG9ydCBFTEVNRU5UX0FSUkFZX0xFTkdUSCA9IDIwMCA7Ci0gICAgc3RhdGljIGZpbmFsIHNob3J0IE1BWF9QT0lOVEVSX0FUX0FfREVQVEggPSA0IDsKLSAgICBzdGF0aWMgZmluYWwgYm9vbGVhbiBERUJVR19TS0lQX0FMR09SSVRITSA9IGZhbHNlOwotICAgIC8vY3JlYXRlIGEgZWxlbW5ldCBhcnJheSBvZiBsZW5ndGggZXF1YWwgdG8gRUxFTUVOVF9BUlJBWV9MRU5HVEgKLSAgICBTdHJpbmcgW10gZkVsZW1lbnRBcnJheSA9IG5ldyBTdHJpbmdbRUxFTUVOVF9BUlJBWV9MRU5HVEhdIDsKLSAgICAvL3BvaW50ZXIgbG9jYXRpb24gd2hlcmUgbGFzdCBlbGVtZW50IHdhcyBza2lwcGVkCi0gICAgc2hvcnQgZkxhc3RQb2ludGVyTG9jYXRpb24gPSAwIDsKLSAgICBzaG9ydCBmRWxlbWVudFBvaW50ZXIgPSAwIDsKLSAgICAvLzJEIGFycmF5IHRvIHN0b3JlIHBvaW50ZXIgaW5mbwotICAgIHNob3J0IFtdIFtdIGZQb2ludGVySW5mbyA9IG5ldyBzaG9ydFtNQVhfREVQVEhfTElNSVRdIFtNQVhfUE9JTlRFUl9BVF9BX0RFUFRIXSA7Ci0gICAgcHJvdGVjdGVkIFN0cmluZyBmRWxlbWVudFJhd25hbWUgOwotICAgIHByb3RlY3RlZCBib29sZWFuIGZTaG91bGRTa2lwID0gZmFsc2U7Ci0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZkFkZCA9IGZhbHNlIDsKLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBmU2tpcCA9IGZhbHNlOwotCi0gICAgLyoqIFJldXNhYmxlIEF1Z21lbnRhdGlvbnMuICovCi0gICAgcHJpdmF0ZSBBdWdtZW50YXRpb25zIGZUZW1wQXVnbWVudGF0aW9ucyA9IG51bGw7Ci0gICAgLy8KLSAgICAvLyBDb25zdHJ1Y3RvcnMKLSAgICAvLwotCi0gICAgLyoqIERlZmF1bHQgY29uc3RydWN0b3IuICovCi0gICAgcHVibGljIFhNTERvY3VtZW50RnJhZ21lbnRTY2FubmVySW1wbCgpIHsKLSAgICB9IC8vIDxpbml0PigpCi0KLSAgICAvLwotICAgIC8vIFhNTERvY3VtZW50U2Nhbm5lciBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIGlucHV0IHNvdXJjZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBpbnB1dFNvdXJjZSBUaGUgaW5wdXQgc291cmNlLgotICAgICAqCi0gICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBUaHJvd24gb24gaS9vIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldElucHV0U291cmNlKFhNTElucHV0U291cmNlIGlucHV0U291cmNlKSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgICAgICBmRW50aXR5TWFuYWdlci5zZXRFbnRpdHlIYW5kbGVyKHRoaXMpOwotICAgICAgICBmRW50aXR5TWFuYWdlci5zdGFydEVudGl0eShmYWxzZSwgIiRmcmFnbWVudCQiLCBpbnB1dFNvdXJjZSwgZmFsc2UsIHRydWUpOwotICAgICAgICAvLyBmRG9jdW1lbnRTeXN0ZW1JZCA9IGZFbnRpdHlNYW5hZ2VyLmV4cGFuZFN5c3RlbUlkKGlucHV0U291cmNlLmdldFN5c3RlbUlkKCkpOwotICAgIH0gLy8gc2V0SW5wdXRTb3VyY2UoWE1MSW5wdXRTb3VyY2UpCi0KLSAgICAvKioKLSAgICAgKiBTY2FucyBhIGRvY3VtZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIGNvbXBsZXRlIFRydWUgaWYgdGhlIHNjYW5uZXIgc2hvdWxkIHNjYW4gdGhlIGRvY3VtZW50Ci0gICAgICogICAgICAgICAgICAgICAgIGNvbXBsZXRlbHksIHB1c2hpbmcgYWxsIGV2ZW50cyB0byB0aGUgcmVnaXN0ZXJlZAotICAgICAqICAgICAgICAgICAgICAgICBkb2N1bWVudCBoYW5kbGVyLiBBIHZhbHVlIG9mIGZhbHNlIGluZGljYXRlcyB0aGF0Ci0gICAgICogICAgICAgICAgICAgICAgIHRoYXQgdGhlIHNjYW5uZXIgc2hvdWxkIG9ubHkgc2NhbiB0aGUgbmV4dCBwb3J0aW9uCi0gICAgICogICAgICAgICAgICAgICAgIG9mIHRoZSBkb2N1bWVudCBhbmQgcmV0dXJuLiBBIHNjYW5uZXIgaW5zdGFuY2UgaXMKLSAgICAgKiAgICAgICAgICAgICAgICAgcGVybWl0dGVkIHRvIGNvbXBsZXRlbHkgc2NhbiBhIGRvY3VtZW50IGlmIGl0IGRvZXMKLSAgICAgKiAgICAgICAgICAgICAgICAgbm90IHN1cHBvcnQgdGhpcyAicHVsbCIgc2Nhbm5pbmcgbW9kZWwuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRydWUgaWYgdGhlcmUgaXMgbW9yZSB0byBzY2FuLCBmYWxzZSBvdGhlcndpc2UuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gc2NhbkRvY3VtZW50KGJvb2xlYW4gY29tcGxldGUpCi0gICAgdGhyb3dzIElPRXhjZXB0aW9uLCBYTklFeGNlcHRpb24gewotCi0gICAgICAgIC8vIGtlZXAgZGlzcGF0Y2hpbmcgImV2ZW50cyIKLSAgICAgICAgZkVudGl0eU1hbmFnZXIuc2V0RW50aXR5SGFuZGxlcih0aGlzKTsKLSAgICAgICAgLy9TeXN0ZW0ub3V0LnByaW50bG4oIiBnZXQgRG9jdW1lbnQgSGFuZGxlciBpbiBOU0RvY3VtZW50SGFuZGxlciAiICsgZkRvY3VtZW50SGFuZGxlciApOwotCi0gICAgICAgIGludCBldmVudCA9IG5leHQoKTsKLSAgICAgICAgZG8gewotICAgICAgICAgICAgc3dpdGNoIChldmVudCkgewotICAgICAgICAgICAgICAgIGNhc2UgWE1MU3RyZWFtQ29uc3RhbnRzLlNUQVJUX0RPQ1VNRU5UIDoKLSAgICAgICAgICAgICAgICAgICAgLy9mRG9jdW1lbnRIYW5kbGVyLnN0YXJ0RG9jdW1lbnQoZkVudGl0eU1hbmFnZXIuZ2V0RW50aXR5U2Nhbm5lcigpLGZFbnRpdHlNYW5hZ2VyLmdldEVudGl0eVNjYW5uZXIoKS5nZXRWZXJzaW9uKCksZk5hbWVzcGFjZUNvbnRleHQsbnVsbCk7Ly8gbm90IGFibGUgdG8gZ2V0Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGNhc2UgWE1MU3RyZWFtQ29uc3RhbnRzLlNUQVJUX0VMRU1FTlQgOgotICAgICAgICAgICAgICAgICAgICAvL1N5c3RlbS5vdXQucHJpbnRsbigiIGluIHNjYW5uIGVsZW1lbnQiKTsKLSAgICAgICAgICAgICAgICAgICAgLy9mRG9jdW1lbnRIYW5kbGVyLnN0YXJ0RWxlbWVudChnZXRFbGVtZW50UU5hbWUoKSxmQXR0cmlidXRlcyxudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgY2FzZSBYTUxTdHJlYW1Db25zdGFudHMuQ0hBUkFDVEVSUyA6Ci0gICAgICAgICAgICAgICAgICAgIGZFbnRpdHlTY2FubmVyLmNoZWNrTm9kZUNvdW50KGZFbnRpdHlTY2FubmVyLmZDdXJyZW50RW50aXR5KTsKLSAgICAgICAgICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci5jaGFyYWN0ZXJzKGdldENoYXJhY3RlckRhdGEoKSxudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgY2FzZSBYTUxTdHJlYW1Db25zdGFudHMuU1BBQ0U6Ci0gICAgICAgICAgICAgICAgICAgIC8vY2hlY2sgaWYgZ2V0Q2hhcmFjdGVyRGF0YSgpIGlzIHRoZSByaWdodCBmdW5jdGlvbiB0byByZXRyaWV2ZSBpZ25vcmFibGVXaGl0ZXNwYWNlIGluZm9ybWF0aW9uLgotICAgICAgICAgICAgICAgICAgICAvL1N5c3RlbS5vdXQucHJpbnRsbigiaW4gdGhlIHNwYWNlIik7Ci0gICAgICAgICAgICAgICAgICAgIC8vZkRvY3VtZW50SGFuZGxlci5pZ25vcmFibGVXaGl0ZXNwYWNlKGdldENoYXJhY3RlckRhdGEoKSwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGNhc2UgWE1MU3RyZWFtQ29uc3RhbnRzLkVOVElUWV9SRUZFUkVOQ0UgOgotICAgICAgICAgICAgICAgICAgICBmRW50aXR5U2Nhbm5lci5jaGVja05vZGVDb3VudChmRW50aXR5U2Nhbm5lci5mQ3VycmVudEVudGl0eSk7Ci0gICAgICAgICAgICAgICAgICAgIC8vZW50aXR5IHJlZmVyZW5jZSBjYWxsYmFjayBhcmUgZ2l2ZW4gaW4gc3RhcnRFbnRpdHkKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgY2FzZSBYTUxTdHJlYW1Db25zdGFudHMuUFJPQ0VTU0lOR19JTlNUUlVDVElPTiA6Ci0gICAgICAgICAgICAgICAgICAgIGZFbnRpdHlTY2FubmVyLmNoZWNrTm9kZUNvdW50KGZFbnRpdHlTY2FubmVyLmZDdXJyZW50RW50aXR5KTsKLSAgICAgICAgICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci5wcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oZ2V0UElUYXJnZXQoKSxnZXRQSURhdGEoKSxudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgY2FzZSBYTUxTdHJlYW1Db25zdGFudHMuQ09NTUVOVCA6Ci0gICAgICAgICAgICAgICAgICAgIGZFbnRpdHlTY2FubmVyLmNoZWNrTm9kZUNvdW50KGZFbnRpdHlTY2FubmVyLmZDdXJyZW50RW50aXR5KTsKLSAgICAgICAgICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci5jb21tZW50KGdldENoYXJhY3RlckRhdGEoKSxudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgY2FzZSBYTUxTdHJlYW1Db25zdGFudHMuRFREIDoKLSAgICAgICAgICAgICAgICAgICAgLy9hbGwgRFREIHJlbGF0ZWQgY2FsbGJhY2tzIGFyZSBoYW5kbGVkIGluIERURFNjYW5uZXIuCi0gICAgICAgICAgICAgICAgICAgIC8vMS4gU3RheCBkb2Vzbid0IGRlZmluZSBEVEQgc3RhdGVzIGFzIGl0IGRvZXMgZm9yIFhNTCBEb2N1bWVudC4KLSAgICAgICAgICAgICAgICAgICAgLy90aGVyZWZvcmUgd2UgZG9uJ3QgbmVlZCB0byB0YWtlIGNhcmUgb2YgYW55dGhpbmcgaGVyZS4gU28gSnVzdCBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgY2FzZSBYTUxTdHJlYW1Db25zdGFudHMuQ0RBVEE6Ci0gICAgICAgICAgICAgICAgICAgIGZFbnRpdHlTY2FubmVyLmNoZWNrTm9kZUNvdW50KGZFbnRpdHlTY2FubmVyLmZDdXJyZW50RW50aXR5KTsKLSAgICAgICAgICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci5zdGFydENEQVRBKG51bGwpOwotICAgICAgICAgICAgICAgICAgICAvL3h4eDogY2hlY2sgaWYgQ0RBVEEgdmFsdWVzIGNvbWVzIGZyb20gZ2V0Q2hhcmFjdGVyRGF0YSgpIGZ1bmN0aW9uCi0gICAgICAgICAgICAgICAgICAgIGZEb2N1bWVudEhhbmRsZXIuY2hhcmFjdGVycyhnZXRDaGFyYWN0ZXJEYXRhKCksbnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgIGZEb2N1bWVudEhhbmRsZXIuZW5kQ0RBVEEobnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgIC8vU3lzdGVtLm91dC5wcmludGxuKCIgaW4gQ0RBVEEgb2YgdGhlIFhNTE5TRG9jdW1lbnRTY2FubmVySW1wbCIpOwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICBjYXNlIFhNTFN0cmVhbUNvbnN0YW50cy5OT1RBVElPTl9ERUNMQVJBVElPTiA6Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGNhc2UgWE1MU3RyZWFtQ29uc3RhbnRzLkVOVElUWV9ERUNMQVJBVElPTiA6Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGNhc2UgWE1MU3RyZWFtQ29uc3RhbnRzLk5BTUVTUEFDRSA6Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGNhc2UgWE1MU3RyZWFtQ29uc3RhbnRzLkFUVFJJQlVURSA6Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGNhc2UgWE1MU3RyZWFtQ29uc3RhbnRzLkVORF9FTEVNRU5UIDoKLSAgICAgICAgICAgICAgICAgICAgLy9kbyBub3QgZ2l2ZSBjYWxsYmFjayBoZXJlLgotICAgICAgICAgICAgICAgICAgICAvL3RoaXMgY2FsbGJhY2sgaXMgZ2l2ZW4gaW4gc2NhbkVuZEVsZW1lbnQgZnVuY3Rpb24uCi0gICAgICAgICAgICAgICAgICAgIC8vZkRvY3VtZW50SGFuZGxlci5lbmRFbGVtZW50KGdldEVsZW1lbnRRTmFtZSgpLG51bGwpOwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICBkZWZhdWx0IDoKLSAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoInByb2Nlc3NpbmcgZXZlbnQ6ICIgKyBldmVudCk7Ci0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vU3lzdGVtLm91dC5wcmludGxuKCJoZXJlIGluIGJlZm9yZSBjYWxsaW5nIG5leHQiKTsKLSAgICAgICAgICAgIGV2ZW50ID0gbmV4dCgpOwotICAgICAgICAgICAgLy9TeXN0ZW0ub3V0LnByaW50bG4oImhlcmUgaW4gYWZ0ZXIgY2FsbGluZyBuZXh0Iik7Ci0gICAgICAgIH0gd2hpbGUgKGV2ZW50IT1YTUxTdHJlYW1Db25zdGFudHMuRU5EX0RPQ1VNRU5UICYmIGNvbXBsZXRlKTsKLQotICAgICAgICBpZihldmVudCA9PSBYTUxTdHJlYW1Db25zdGFudHMuRU5EX0RPQ1VNRU5UKSB7Ci0gICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLmVuZERvY3VtZW50KG51bGwpOwotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIHRydWU7Ci0KLSAgICB9IC8vIHNjYW5Eb2N1bWVudChib29sZWFuKTpib29sZWFuCi0KLQotCi0gICAgcHVibGljIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlFOYW1lIGdldEVsZW1lbnRRTmFtZSgpewotICAgICAgICBpZihmU2Nhbm5lckxhc3RTdGF0ZSA9PSBYTUxFdmVudC5FTkRfRUxFTUVOVCl7Ci0gICAgICAgICAgICBmRWxlbWVudFFOYW1lLnNldFZhbHVlcyhmRWxlbWVudFN0YWNrLmdldExhc3RQb3BwZWRFbGVtZW50KCkpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmRWxlbWVudFFOYW1lIDsKLSAgICB9Ci0KLSAgICAvKiogcmV0dXJuIHRoZSBuZXh0IHN0YXRlIG9uIHRoZSBpbnB1dAotICAgICAqIEByZXR1cm4gaW50Ci0gICAgICovCi0KLSAgICBwdWJsaWMgaW50IG5leHQoKSB0aHJvd3MgSU9FeGNlcHRpb24sIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIHJldHVybiBmRHJpdmVyLm5leHQoKTsKLSAgICB9Ci0KLSAgICAvLwotICAgIC8vIFhNTENvbXBvbmVudCBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFJlc2V0cyB0aGUgY29tcG9uZW50LiBUaGUgY29tcG9uZW50IGNhbiBxdWVyeSB0aGUgY29tcG9uZW50IG1hbmFnZXIKLSAgICAgKiBhYm91dCBhbnkgZmVhdHVyZXMgYW5kIHByb3BlcnRpZXMgdGhhdCBhZmZlY3QgdGhlIG9wZXJhdGlvbiBvZiB0aGUKLSAgICAgKiBjb21wb25lbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29tcG9uZW50TWFuYWdlciBUaGUgY29tcG9uZW50IG1hbmFnZXIuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBUaHJvd24gYnkgY29tcG9uZW50IG9uIGluaXRpYWxpemF0aW9uIGVycm9yLgotICAgICAqICAgICAgICAgICAgICAgICAgICAgIEZvciBleGFtcGxlLCBpZiBhIGZlYXR1cmUgb3IgcHJvcGVydHkgaXMKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICByZXF1aXJlZCBmb3IgdGhlIG9wZXJhdGlvbiBvZiB0aGUgY29tcG9uZW50LCB0aGUKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBjb21wb25lbnQgbWFuYWdlciBtYXkgdGhyb3cgYQotICAgICAqICAgICAgICAgICAgICAgICAgICAgIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24gb3IgYQotICAgICAqICAgICAgICAgICAgICAgICAgICAgIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbi4KLSAgICAgKi8KLQotICAgIHB1YmxpYyB2b2lkIHJlc2V0KFhNTENvbXBvbmVudE1hbmFnZXIgY29tcG9uZW50TWFuYWdlcikKLSAgICB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgc3VwZXIucmVzZXQoY29tcG9uZW50TWFuYWdlcik7Ci0KLSAgICAgICAgLy8gb3RoZXIgc2V0dGluZ3MKLSAgICAgICAgLy8gZkRvY3VtZW50U3lzdGVtSWQgPSBudWxsOwotCi0gICAgICAgIC8vIHNheCBmZWF0dXJlcwotICAgICAgICAvL2ZBdHRyaWJ1dGVzLnNldE5hbWVzcGFjZXMoZk5hbWVzcGFjZXMpOwotCi0gICAgICAgIC8vIHhlcmNlcyBmZWF0dXJlcwotICAgICAgICBmUmVwb3J0Q2RhdGFFdmVudCA9IGNvbXBvbmVudE1hbmFnZXIuZ2V0RmVhdHVyZShDb25zdGFudHMuU1RBWF9SRVBPUlRfQ0RBVEFfRVZFTlQsIHRydWUpOwotICAgICAgICBmU2VjdXJpdHlNYW5hZ2VyID0gKFhNTFNlY3VyaXR5TWFuYWdlciljb21wb25lbnRNYW5hZ2VyLmdldFByb3BlcnR5KENvbnN0YW50cy5TRUNVUklUWV9NQU5BR0VSLCBudWxsKTsKLSAgICAgICAgZk5vdGlmeUJ1aWx0SW5SZWZzID0gY29tcG9uZW50TWFuYWdlci5nZXRGZWF0dXJlKE5PVElGWV9CVUlMVElOX1JFRlMsIGZhbHNlKTsKLQotICAgICAgICBPYmplY3QgcmVzb2x2ZXIgPSBjb21wb25lbnRNYW5hZ2VyLmdldFByb3BlcnR5KEVOVElUWV9SRVNPTFZFUiwgbnVsbCk7Ci0gICAgICAgIGZFeHRlcm5hbFN1YnNldFJlc29sdmVyID0gKHJlc29sdmVyIGluc3RhbmNlb2YgRXh0ZXJuYWxTdWJzZXRSZXNvbHZlcikgPwotICAgICAgICAgICAgICAgIChFeHRlcm5hbFN1YnNldFJlc29sdmVyKSByZXNvbHZlciA6IG51bGw7Ci0KLSAgICAgICAgLy9hdHRyaWJ1dGUKLSAgICAgICAgZlJlYWRpbmdBdHRyaWJ1dGVzID0gZmFsc2U7Ci0gICAgICAgIC8veHh4OiBleHRlcm5hbCBlbnRpdGllcyBhcmUgc3VwcG9ydGVkIGluIFhlcmNlcwotICAgICAgICAvLyBpdCB3b3VsZCBiZSBnb29kIHRvIGRlZmluZSBmZWF0dXJlIGZvciB0aGlzIGNhc2UKLSAgICAgICAgZlN1cHBvcnRFeHRlcm5hbEVudGl0aWVzID0gdHJ1ZTsKLSAgICAgICAgZlJlcGxhY2VFbnRpdHlSZWZlcmVuY2VzID0gdHJ1ZTsKLSAgICAgICAgZklzQ29hbGVzY2UgPSBmYWxzZTsKLQotICAgICAgICAvLyBzZXR1cCBEcml2ZXIKLSAgICAgICAgc2V0U2Nhbm5lclN0YXRlKFNDQU5ORVJfU1RBVEVfQ09OVEVOVCk7Ci0gICAgICAgIHNldERyaXZlcihmQ29udGVudERyaXZlcik7Ci0KLSAgICAgICAgLy8gSkFYUCAxLjUgZmVhdHVyZXMgYW5kIHByb3BlcnRpZXMKLSAgICAgICAgWE1MU2VjdXJpdHlQcm9wZXJ0eU1hbmFnZXIgc3BtID0gKFhNTFNlY3VyaXR5UHJvcGVydHlNYW5hZ2VyKQotICAgICAgICAgICAgICAgIGNvbXBvbmVudE1hbmFnZXIuZ2V0UHJvcGVydHkoWE1MX1NFQ1VSSVRZX1BST1BFUlRZX01BTkFHRVIsIG51bGwpOwotICAgICAgICBmQWNjZXNzRXh0ZXJuYWxEVEQgPSBzcG0uZ2V0VmFsdWUoWE1MU2VjdXJpdHlQcm9wZXJ0eU1hbmFnZXIuUHJvcGVydHkuQUNDRVNTX0VYVEVSTkFMX0RURCk7Ci0KLSAgICAgICAgZlN0cmljdFVSSSA9IGNvbXBvbmVudE1hbmFnZXIuZ2V0RmVhdHVyZShTVEFOREFSRF9VUklfQ09ORk9STUFOVCwgZmFsc2UpOwotCi0gICAgICAgIHJlc2V0Q29tbW9uKCk7Ci0gICAgICAgIC8vZkVudGl0eU1hbmFnZXIudGVzdCgpOwotICAgIH0gLy8gcmVzZXQoWE1MQ29tcG9uZW50TWFuYWdlcikKLQotCi0gICAgcHVibGljIHZvaWQgcmVzZXQoUHJvcGVydHlNYW5hZ2VyIHByb3BlcnR5TWFuYWdlcil7Ci0KLSAgICAgICAgc3VwZXIucmVzZXQocHJvcGVydHlNYW5hZ2VyKTsKLQotICAgICAgICAvLyBvdGhlciBzZXR0aW5ncwotICAgICAgICAvLyBmRG9jdW1lbnRTeXN0ZW1JZCA9IG51bGw7Ci0gICAgICAgIGZOYW1lc3BhY2VzID0gKChCb29sZWFuKXByb3BlcnR5TWFuYWdlci5nZXRQcm9wZXJ0eShYTUxJbnB1dEZhY3RvcnkuSVNfTkFNRVNQQUNFX0FXQVJFKSkuYm9vbGVhblZhbHVlKCk7Ci0gICAgICAgIGZOb3RpZnlCdWlsdEluUmVmcyA9IGZhbHNlIDsKLQotICAgICAgICAvL2ZFbGVtZW50U3RhY2syLmNsZWFyKCk7Ci0gICAgICAgIC8vZlJlcGxhY2VFbnRpdHlSZWZlcmVuY2VzID0gdHJ1ZTsKLSAgICAgICAgLy9mU3VwcG9ydEV4dGVybmFsRW50aXRpZXMgPSB0cnVlOwotICAgICAgICBCb29sZWFuIGJvID0gKEJvb2xlYW4pcHJvcGVydHlNYW5hZ2VyLmdldFByb3BlcnR5KFhNTElucHV0RmFjdG9yeS5JU19SRVBMQUNJTkdfRU5USVRZX1JFRkVSRU5DRVMpOwotICAgICAgICBmUmVwbGFjZUVudGl0eVJlZmVyZW5jZXMgPSBiby5ib29sZWFuVmFsdWUoKTsKLSAgICAgICAgYm8gPSAoQm9vbGVhbilwcm9wZXJ0eU1hbmFnZXIuZ2V0UHJvcGVydHkoWE1MSW5wdXRGYWN0b3J5LklTX1NVUFBPUlRJTkdfRVhURVJOQUxfRU5USVRJRVMpOwotICAgICAgICBmU3VwcG9ydEV4dGVybmFsRW50aXRpZXMgPSBiby5ib29sZWFuVmFsdWUoKTsKLSAgICAgICAgQm9vbGVhbiBjZGF0YSA9IChCb29sZWFuKXByb3BlcnR5TWFuYWdlci5nZXRQcm9wZXJ0eShDb25zdGFudHMuWkVQSFlSX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5TVEFYX1JFUE9SVF9DREFUQV9FVkVOVCkgOwotICAgICAgICBpZihjZGF0YSAhPSBudWxsKQotICAgICAgICAgICAgZlJlcG9ydENkYXRhRXZlbnQgPSBjZGF0YS5ib29sZWFuVmFsdWUoKSA7Ci0gICAgICAgIEJvb2xlYW4gY29hbGVzY2UgPSAoQm9vbGVhbilwcm9wZXJ0eU1hbmFnZXIuZ2V0UHJvcGVydHkoWE1MSW5wdXRGYWN0b3J5LklTX0NPQUxFU0NJTkcpIDsKLSAgICAgICAgaWYoY29hbGVzY2UgIT0gbnVsbCkKLSAgICAgICAgICAgIGZJc0NvYWxlc2NlID0gY29hbGVzY2UuYm9vbGVhblZhbHVlKCk7Ci0gICAgICAgIGZSZXBvcnRDZGF0YUV2ZW50ID0gZklzQ29hbGVzY2UgPyBmYWxzZSA6IChmUmVwb3J0Q2RhdGFFdmVudCAmJiB0cnVlKSA7Ci0gICAgICAgIC8vaWYgZklzQ29hbGVzY2UgaXMgc2V0IHRvIHRydWUsIHNldCB0aGUgdmFsdWUgb2YgZlJlcGxhY2VFbnRpdHlSZWZlcmVuY2VzIHRvIHRydWUsCi0gICAgICAgIC8vaWYgZklzQ29hbGVzY2UgaXMgc2V0IHRvIGZhbHNlLCB0YWtlIHRoZSB2YWx1ZSBvZiBmUmVwbGFjZUVudGl0eVJlZmVyZW5jZXMgYXMgc2V0IGJ5IGFwcGxpY2F0aW9uCi0gICAgICAgIGZSZXBsYWNlRW50aXR5UmVmZXJlbmNlcyA9IGZJc0NvYWxlc2NlID8gdHJ1ZSA6IGZSZXBsYWNlRW50aXR5UmVmZXJlbmNlczsKLSAgICAgICAgLy8gc2V0dXAgRHJpdmVyCi0gICAgICAgIC8vd2UgZG9udCBuZWVkIHRvIGRvIHRoaXMgLS0gbmIuCi0gICAgICAgIC8vc2V0U2Nhbm5lclN0YXRlKFNDQU5ORVJfU1RBVEVfQ09OVEVOVCk7Ci0gICAgICAgIC8vc2V0RHJpdmVyKGZDb250ZW50RHJpdmVyKTsKLSAgICAgICAgLy9mRW50aXR5TWFuYWdlci50ZXN0KCk7Ci0KLSAgICAgICAgIC8vIEpBWFAgMS41IGZlYXR1cmVzIGFuZCBwcm9wZXJ0aWVzCi0gICAgICAgIFhNTFNlY3VyaXR5UHJvcGVydHlNYW5hZ2VyIHNwbSA9IChYTUxTZWN1cml0eVByb3BlcnR5TWFuYWdlcikKLSAgICAgICAgICAgICAgICBwcm9wZXJ0eU1hbmFnZXIuZ2V0UHJvcGVydHkoWE1MX1NFQ1VSSVRZX1BST1BFUlRZX01BTkFHRVIpOwotICAgICAgICBmQWNjZXNzRXh0ZXJuYWxEVEQgPSBzcG0uZ2V0VmFsdWUoWE1MU2VjdXJpdHlQcm9wZXJ0eU1hbmFnZXIuUHJvcGVydHkuQUNDRVNTX0VYVEVSTkFMX0RURCk7Ci0KLSAgICAgICAgZlNlY3VyaXR5TWFuYWdlciA9IChYTUxTZWN1cml0eU1hbmFnZXIpcHJvcGVydHlNYW5hZ2VyLmdldFByb3BlcnR5KENvbnN0YW50cy5TRUNVUklUWV9NQU5BR0VSKTsKLSAgICAgICAgcmVzZXRDb21tb24oKTsKLSAgICB9IC8vIHJlc2V0KFhNTENvbXBvbmVudE1hbmFnZXIpCi0KLSAgICB2b2lkIHJlc2V0Q29tbW9uKCkgewotICAgICAgICAvLyBpbml0aWFsaXplIHZhcnMKLSAgICAgICAgZk1hcmt1cERlcHRoID0gMDsKLSAgICAgICAgZkN1cnJlbnRFbGVtZW50ID0gbnVsbDsKLSAgICAgICAgZkVsZW1lbnRTdGFjay5jbGVhcigpOwotICAgICAgICBmSGFzRXh0ZXJuYWxEVEQgPSBmYWxzZTsKLSAgICAgICAgZlN0YW5kYWxvbmVTZXQgPSBmYWxzZTsKLSAgICAgICAgZlN0YW5kYWxvbmUgPSBmYWxzZTsKLSAgICAgICAgZkluU2NhbkNvbnRlbnQgPSBmYWxzZTsKLSAgICAgICAgLy9za2lwcGluZyBhbGdvcml0aG0KLSAgICAgICAgZlNob3VsZFNraXAgPSBmYWxzZTsKLSAgICAgICAgZkFkZCA9IGZhbHNlOwotICAgICAgICBmU2tpcCA9IGZhbHNlOwotCi0gICAgICAgIGZFbnRpdHlTdG9yZSA9IGZFbnRpdHlNYW5hZ2VyLmdldEVudGl0eVN0b3JlKCk7Ci0gICAgICAgIGR0ZEdyYW1tYXJVdGlsID0gbnVsbDsKLQotICAgICAgICBpZiAoZlNlY3VyaXR5TWFuYWdlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmRWxlbWVudEF0dHJpYnV0ZUxpbWl0ID0gZlNlY3VyaXR5TWFuYWdlci5nZXRMaW1pdChYTUxTZWN1cml0eU1hbmFnZXIuTGltaXQuRUxFTUVOVF9BVFRSSUJVVEVfTElNSVQpOwotICAgICAgICAgICAgZlhNTE5hbWVMaW1pdCA9IGZTZWN1cml0eU1hbmFnZXIuZ2V0TGltaXQoWE1MU2VjdXJpdHlNYW5hZ2VyLkxpbWl0Lk1BWF9OQU1FX0xJTUlUKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIGZFbGVtZW50QXR0cmlidXRlTGltaXQgPSAwOwotICAgICAgICAgICAgZlhNTE5hbWVMaW1pdCA9IFhNTFNlY3VyaXR5TWFuYWdlci5MaW1pdC5NQVhfTkFNRV9MSU1JVC5kZWZhdWx0VmFsdWUoKTsKLSAgICAgICAgfQotICAgICAgICBmTGltaXRBbmFseXplciA9IGZFbnRpdHlNYW5hZ2VyLmZMaW1pdEFuYWx5emVyOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYSBsaXN0IG9mIGZlYXR1cmUgaWRlbnRpZmllcnMgdGhhdCBhcmUgcmVjb2duaXplZCBieQotICAgICAqIHRoaXMgY29tcG9uZW50LiBUaGlzIG1ldGhvZCBtYXkgcmV0dXJuIG51bGwgaWYgbm8gZmVhdHVyZXMKLSAgICAgKiBhcmUgcmVjb2duaXplZCBieSB0aGlzIGNvbXBvbmVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nW10gZ2V0UmVjb2duaXplZEZlYXR1cmVzKCkgewotICAgICAgICByZXR1cm4gKFN0cmluZ1tdKShSRUNPR05JWkVEX0ZFQVRVUkVTLmNsb25lKCkpOwotICAgIH0gLy8gZ2V0UmVjb2duaXplZEZlYXR1cmVzKCk6U3RyaW5nW10KLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIHN0YXRlIG9mIGEgZmVhdHVyZS4gVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBjb21wb25lbnQKLSAgICAgKiBtYW5hZ2VyIGFueSB0aW1lIGFmdGVyIHJlc2V0IHdoZW4gYSBmZWF0dXJlIGNoYW5nZXMgc3RhdGUuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBDb21wb25lbnRzIHNob3VsZCBzaWxlbnRseSBpZ25vcmUgZmVhdHVyZXMKLSAgICAgKiB0aGF0IGRvIG5vdCBhZmZlY3QgdGhlIG9wZXJhdGlvbiBvZiB0aGUgY29tcG9uZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIGZlYXR1cmVJZCBUaGUgZmVhdHVyZSBpZGVudGlmaWVyLgotICAgICAqIEBwYXJhbSBzdGF0ZSAgICAgVGhlIHN0YXRlIG9mIHRoZSBmZWF0dXJlLgotICAgICAqCi0gICAgICogQHRocm93cyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIFRoZSBjb21wb25lbnQgc2hvdWxkIG5vdCB0aHJvdwotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzIGV4Y2VwdGlvbi4KLSAgICAgKiBAdGhyb3dzIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBUaGUgY29tcG9uZW50IHNob3VsZCBub3QgdGhyb3cKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzIGV4Y2VwdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRGZWF0dXJlKFN0cmluZyBmZWF0dXJlSWQsIGJvb2xlYW4gc3RhdGUpCi0gICAgdGhyb3dzIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gewotCi0gICAgICAgIHN1cGVyLnNldEZlYXR1cmUoZmVhdHVyZUlkLCBzdGF0ZSk7Ci0KLSAgICAgICAgLy8gWGVyY2VzIHByb3BlcnRpZXMKLSAgICAgICAgaWYgKGZlYXR1cmVJZC5zdGFydHNXaXRoKENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVgpKSB7Ci0gICAgICAgICAgICBTdHJpbmcgZmVhdHVyZSA9IGZlYXR1cmVJZC5zdWJzdHJpbmcoQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWC5sZW5ndGgoKSk7Ci0gICAgICAgICAgICBpZiAoZmVhdHVyZS5lcXVhbHMoQ29uc3RhbnRzLk5PVElGWV9CVUlMVElOX1JFRlNfRkVBVFVSRSkpIHsKLSAgICAgICAgICAgICAgICBmTm90aWZ5QnVpbHRJblJlZnMgPSBzdGF0ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgfSAvLyBzZXRGZWF0dXJlKFN0cmluZyxib29sZWFuKQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhIGxpc3Qgb2YgcHJvcGVydHkgaWRlbnRpZmllcnMgdGhhdCBhcmUgcmVjb2duaXplZCBieQotICAgICAqIHRoaXMgY29tcG9uZW50LiBUaGlzIG1ldGhvZCBtYXkgcmV0dXJuIG51bGwgaWYgbm8gcHJvcGVydGllcwotICAgICAqIGFyZSByZWNvZ25pemVkIGJ5IHRoaXMgY29tcG9uZW50LgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmdbXSBnZXRSZWNvZ25pemVkUHJvcGVydGllcygpIHsKLSAgICAgICAgcmV0dXJuIChTdHJpbmdbXSkoUkVDT0dOSVpFRF9QUk9QRVJUSUVTLmNsb25lKCkpOwotICAgIH0gLy8gZ2V0UmVjb2duaXplZFByb3BlcnRpZXMoKTpTdHJpbmdbXQotCi0gICAgLyoqCi0gICAgICogU2V0cyB0aGUgdmFsdWUgb2YgYSBwcm9wZXJ0eS4gVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBjb21wb25lbnQKLSAgICAgKiBtYW5hZ2VyIGFueSB0aW1lIGFmdGVyIHJlc2V0IHdoZW4gYSBwcm9wZXJ0eSBjaGFuZ2VzIHZhbHVlLgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gQ29tcG9uZW50cyBzaG91bGQgc2lsZW50bHkgaWdub3JlIHByb3BlcnRpZXMKLSAgICAgKiB0aGF0IGRvIG5vdCBhZmZlY3QgdGhlIG9wZXJhdGlvbiBvZiB0aGUgY29tcG9uZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIHByb3BlcnR5SWQgVGhlIHByb3BlcnR5IGlkZW50aWZpZXIuCi0gICAgICogQHBhcmFtIHZhbHVlICAgICAgVGhlIHZhbHVlIG9mIHRoZSBwcm9wZXJ0eS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiBUaGUgY29tcG9uZW50IHNob3VsZCBub3QgdGhyb3cKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcyBleGNlcHRpb24uCi0gICAgICogQHRocm93cyBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gVGhlIGNvbXBvbmVudCBzaG91bGQgbm90IHRocm93Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcyBleGNlcHRpb24uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0UHJvcGVydHkoU3RyaW5nIHByb3BlcnR5SWQsIE9iamVjdCB2YWx1ZSkKLSAgICB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgc3VwZXIuc2V0UHJvcGVydHkocHJvcGVydHlJZCwgdmFsdWUpOwotCi0gICAgICAgIC8vIFhlcmNlcyBwcm9wZXJ0aWVzCi0gICAgICAgIGlmIChwcm9wZXJ0eUlkLnN0YXJ0c1dpdGgoQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVgpKSB7Ci0gICAgICAgICAgICBmaW5hbCBpbnQgc3VmZml4TGVuZ3RoID0gcHJvcGVydHlJZC5sZW5ndGgoKSAtIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYLmxlbmd0aCgpOwotICAgICAgICAgICAgaWYgKHN1ZmZpeExlbmd0aCA9PSBDb25zdGFudHMuRU5USVRZX01BTkFHRVJfUFJPUEVSVFkubGVuZ3RoKCkgJiYKLSAgICAgICAgICAgICAgICAgICAgcHJvcGVydHlJZC5lbmRzV2l0aChDb25zdGFudHMuRU5USVRZX01BTkFHRVJfUFJPUEVSVFkpKSB7Ci0gICAgICAgICAgICAgICAgZkVudGl0eU1hbmFnZXIgPSAoWE1MRW50aXR5TWFuYWdlcil2YWx1ZTsKLSAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoc3VmZml4TGVuZ3RoID09IENvbnN0YW50cy5FTlRJVFlfUkVTT0xWRVJfUFJPUEVSVFkubGVuZ3RoKCkgJiYKLSAgICAgICAgICAgICAgICAgICAgcHJvcGVydHlJZC5lbmRzV2l0aChDb25zdGFudHMuRU5USVRZX1JFU09MVkVSX1BST1BFUlRZKSkgewotICAgICAgICAgICAgICAgIGZFeHRlcm5hbFN1YnNldFJlc29sdmVyID0gKHZhbHVlIGluc3RhbmNlb2YgRXh0ZXJuYWxTdWJzZXRSZXNvbHZlcikgPwotICAgICAgICAgICAgICAgICAgICAoRXh0ZXJuYWxTdWJzZXRSZXNvbHZlcikgdmFsdWUgOiBudWxsOwotICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0KLSAgICAgICAgICAgICAgICAvLyBYZXJjZXMgcHJvcGVydGllcwotICAgICAgICBpZiAocHJvcGVydHlJZC5zdGFydHNXaXRoKENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYKSkgewotICAgICAgICAgICAgU3RyaW5nIHByb3BlcnR5ID0gcHJvcGVydHlJZC5zdWJzdHJpbmcoQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVgubGVuZ3RoKCkpOwotICAgICAgICAgICAgaWYgKHByb3BlcnR5LmVxdWFscyhDb25zdGFudHMuRU5USVRZX01BTkFHRVJfUFJPUEVSVFkpKSB7Ci0gICAgICAgICAgICAgICAgZkVudGl0eU1hbmFnZXIgPSAoWE1MRW50aXR5TWFuYWdlcil2YWx1ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotCi0gICAgICAgIC8vSkFYUCAxLjUgcHJvcGVydGllcwotICAgICAgICBpZiAocHJvcGVydHlJZC5lcXVhbHMoWE1MX1NFQ1VSSVRZX1BST1BFUlRZX01BTkFHRVIpKQotICAgICAgICB7Ci0gICAgICAgICAgICBYTUxTZWN1cml0eVByb3BlcnR5TWFuYWdlciBzcG0gPSAoWE1MU2VjdXJpdHlQcm9wZXJ0eU1hbmFnZXIpdmFsdWU7Ci0gICAgICAgICAgICBmQWNjZXNzRXh0ZXJuYWxEVEQgPSBzcG0uZ2V0VmFsdWUoWE1MU2VjdXJpdHlQcm9wZXJ0eU1hbmFnZXIuUHJvcGVydHkuQUNDRVNTX0VYVEVSTkFMX0RURCk7Ci0gICAgICAgIH0KLQotICAgIH0gLy8gc2V0UHJvcGVydHkoU3RyaW5nLE9iamVjdCkKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIGRlZmF1bHQgc3RhdGUgZm9yIGEgZmVhdHVyZSwgb3IgbnVsbCBpZiB0aGlzCi0gICAgICogY29tcG9uZW50IGRvZXMgbm90IHdhbnQgdG8gcmVwb3J0IGEgZGVmYXVsdCB2YWx1ZSBmb3IgdGhpcwotICAgICAqIGZlYXR1cmUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZmVhdHVyZUlkIFRoZSBmZWF0dXJlIGlkZW50aWZpZXIuCi0gICAgICoKLSAgICAgKiBAc2luY2UgWGVyY2VzIDIuMi4wCi0gICAgICovCi0gICAgcHVibGljIEJvb2xlYW4gZ2V0RmVhdHVyZURlZmF1bHQoU3RyaW5nIGZlYXR1cmVJZCkgewotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IFJFQ09HTklaRURfRkVBVFVSRVMubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgIGlmIChSRUNPR05JWkVEX0ZFQVRVUkVTW2ldLmVxdWFscyhmZWF0dXJlSWQpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIEZFQVRVUkVfREVGQVVMVFNbaV07Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfSAvLyBnZXRGZWF0dXJlRGVmYXVsdChTdHJpbmcpOkJvb2xlYW4KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIGRlZmF1bHQgc3RhdGUgZm9yIGEgcHJvcGVydHksIG9yIG51bGwgaWYgdGhpcwotICAgICAqIGNvbXBvbmVudCBkb2VzIG5vdCB3YW50IHRvIHJlcG9ydCBhIGRlZmF1bHQgdmFsdWUgZm9yIHRoaXMKLSAgICAgKiBwcm9wZXJ0eS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBwcm9wZXJ0eUlkIFRoZSBwcm9wZXJ0eSBpZGVudGlmaWVyLgotICAgICAqCi0gICAgICogQHNpbmNlIFhlcmNlcyAyLjIuMAotICAgICAqLwotICAgIHB1YmxpYyBPYmplY3QgZ2V0UHJvcGVydHlEZWZhdWx0KFN0cmluZyBwcm9wZXJ0eUlkKSB7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgUkVDT0dOSVpFRF9QUk9QRVJUSUVTLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICBpZiAoUkVDT0dOSVpFRF9QUk9QRVJUSUVTW2ldLmVxdWFscyhwcm9wZXJ0eUlkKSkgewotICAgICAgICAgICAgICAgIHJldHVybiBQUk9QRVJUWV9ERUZBVUxUU1tpXTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9IC8vIGdldFByb3BlcnR5RGVmYXVsdChTdHJpbmcpOk9iamVjdAotCi0gICAgLy8KLSAgICAvLyBYTUxEb2N1bWVudFNvdXJjZSBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIHNldERvY3VtZW50SGFuZGxlcgotICAgICAqCi0gICAgICogQHBhcmFtIGRvY3VtZW50SGFuZGxlcgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldERvY3VtZW50SGFuZGxlcihYTUxEb2N1bWVudEhhbmRsZXIgZG9jdW1lbnRIYW5kbGVyKSB7Ci0gICAgICAgIGZEb2N1bWVudEhhbmRsZXIgPSBkb2N1bWVudEhhbmRsZXI7Ci0gICAgICAgIC8vU3lzdGVtLm91dC5wcmludGxuKCIgSW4gU2V0IERPQ1VNRU5UIEhBTkRMRVIiICsgZkRvY3VtZW50SGFuZGxlciArICIgc2Nhbm5lciA9IiArIHRoaXMpOwotICAgIH0gLy8gc2V0RG9jdW1lbnRIYW5kbGVyKFhNTERvY3VtZW50SGFuZGxlcikKLQotCi0gICAgLyoqIFJldHVybnMgdGhlIGRvY3VtZW50IGhhbmRsZXIgKi8KLSAgICBwdWJsaWMgWE1MRG9jdW1lbnRIYW5kbGVyIGdldERvY3VtZW50SGFuZGxlcigpewotICAgICAgICByZXR1cm4gZkRvY3VtZW50SGFuZGxlcjsKLSAgICB9Ci0KLSAgICAvLwotICAgIC8vIFhNTEVudGl0eUhhbmRsZXIgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBub3RpZmllcyBvZiB0aGUgc3RhcnQgb2YgYW4gZW50aXR5LiBUaGUgRFREIGhhcyB0aGUKLSAgICAgKiBwc2V1ZG8tbmFtZSBvZiAiW2R0ZF0iIHBhcmFtZXRlciBlbnRpdHkgbmFtZXMgc3RhcnQgd2l0aCAnJSc7IGFuZAotICAgICAqIGdlbmVyYWwgZW50aXRpZXMgYXJlIGp1c3Qgc3BlY2lmaWVkIGJ5IHRoZWlyIG5hbWUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSAgICAgVGhlIG5hbWUgb2YgdGhlIGVudGl0eS4KLSAgICAgKiBAcGFyYW0gaWRlbnRpZmllciBUaGUgcmVzb3VyY2UgaWRlbnRpZmllci4KLSAgICAgKiBAcGFyYW0gZW5jb2RpbmcgVGhlIGF1dG8tZGV0ZWN0ZWQgSUFOQSBlbmNvZGluZyBuYW1lIG9mIHRoZSBlbnRpdHkKLSAgICAgKiAgICAgICAgICAgICAgICAgc3RyZWFtLiBUaGlzIHZhbHVlIHdpbGwgYmUgbnVsbCBpbiB0aG9zZSBzaXR1YXRpb25zCi0gICAgICogICAgICAgICAgICAgICAgIHdoZXJlIHRoZSBlbnRpdHkgZW5jb2RpbmcgaXMgbm90IGF1dG8tZGV0ZWN0ZWQgKGUuZy4KLSAgICAgKiAgICAgICAgICAgICAgICAgaW50ZXJuYWwgZW50aXRpZXMgb3IgYSBkb2N1bWVudCBlbnRpdHkgdGhhdCBpcwotICAgICAqICAgICAgICAgICAgICAgICBwYXJzZWQgZnJvbSBhIGphdmEuaW8uUmVhZGVyKS4KLSAgICAgKiBAcGFyYW0gYXVncyAgICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RW50aXR5KFN0cmluZyBuYW1lLAotICAgICAgICAgICAgWE1MUmVzb3VyY2VJZGVudGlmaWVyIGlkZW50aWZpZXIsCi0gICAgICAgICAgICBTdHJpbmcgZW5jb2RpbmcsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy8ga2VlcCB0cmFjayBvZiB0aGlzIGVudGl0eSBiZWZvcmUgZkVudGl0eURlcHRoIGlzIGluY3JlYXNlZAotICAgICAgICBpZiAoZkVudGl0eURlcHRoID09IGZFbnRpdHlTdGFjay5sZW5ndGgpIHsKLSAgICAgICAgICAgIGludFtdIGVudGl0eWFycmF5ID0gbmV3IGludFtmRW50aXR5U3RhY2subGVuZ3RoICogMl07Ci0gICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGZFbnRpdHlTdGFjaywgMCwgZW50aXR5YXJyYXksIDAsIGZFbnRpdHlTdGFjay5sZW5ndGgpOwotICAgICAgICAgICAgZkVudGl0eVN0YWNrID0gZW50aXR5YXJyYXk7Ci0gICAgICAgIH0KLSAgICAgICAgZkVudGl0eVN0YWNrW2ZFbnRpdHlEZXB0aF0gPSBmTWFya3VwRGVwdGg7Ci0KLSAgICAgICAgc3VwZXIuc3RhcnRFbnRpdHkobmFtZSwgaWRlbnRpZmllciwgZW5jb2RpbmcsIGF1Z3MpOwotCi0gICAgICAgIC8vIFdGQzogIGVudGl0eSBkZWNsYXJlZCBpbiBleHRlcm5hbCBzdWJzZXQgaW4gc3RhbmRhbG9uZSBkb2MKLSAgICAgICAgaWYoZlN0YW5kYWxvbmUgJiYgZkVudGl0eVN0b3JlLmlzRW50aXR5RGVjbEluRXh0ZXJuYWxTdWJzZXQobmFtZSkpIHsKLSAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIk1TR19SRUZFUkVOQ0VfVE9fRVhURVJOQUxMWV9ERUNMQVJFRF9FTlRJVFlfV0hFTl9TVEFOREFMT05FIiwKLSAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde25hbWV9KTsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKiB3ZSBhcmUgbm90IGNhbGxpbmcgdGhlIGhhbmRsZXJzIHlldC4uICovCi0gICAgICAgIC8vIGNhbGwgaGFuZGxlcgotICAgICAgICBpZiAoZkRvY3VtZW50SGFuZGxlciAhPSBudWxsICYmICFmU2Nhbm5pbmdBdHRyaWJ1dGUpIHsKLSAgICAgICAgICAgIGlmICghbmFtZS5lcXVhbHMoIlt4bWxdIikpIHsKLSAgICAgICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLnN0YXJ0R2VuZXJhbEVudGl0eShuYW1lLCBpZGVudGlmaWVyLCBlbmNvZGluZywgYXVncyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgIH0gLy8gc3RhcnRFbnRpdHkoU3RyaW5nLFhNTFJlc291cmNlSWRlbnRpZmllcixTdHJpbmcpCi0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBub3RpZmllcyB0aGUgZW5kIG9mIGFuIGVudGl0eS4gVGhlIERURCBoYXMgdGhlIHBzZXVkby1uYW1lCi0gICAgICogb2YgIltkdGRdIiBwYXJhbWV0ZXIgZW50aXR5IG5hbWVzIHN0YXJ0IHdpdGggJyUnOyBhbmQgZ2VuZXJhbCBlbnRpdGllcwotICAgICAqIGFyZSBqdXN0IHNwZWNpZmllZCBieSB0aGVpciBuYW1lLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGVudGl0eS4KLSAgICAgKiBAcGFyYW0gYXVncyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kRW50aXR5KFN0cmluZyBuYW1lLCBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBJT0V4Y2VwdGlvbiwgWE5JRXhjZXB0aW9uIHsKLQotICAgICAgICAvKioKLSAgICAgICAgICogLy8gZmx1c2ggcG9zc2libGUgcGVuZGluZyBvdXRwdXQgYnVmZmVyIC0gc2VlIHNjYW5Db250ZW50Ci0gICAgICAgICAqIGlmIChmSW5TY2FuQ29udGVudCAmJiBmU3RyaW5nQnVmZmVyLmxlbmd0aCAhPSAwCi0gICAgICAgICAqICYmIGZEb2N1bWVudEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgKiBmRG9jdW1lbnRIYW5kbGVyLmNoYXJhY3RlcnMoZlN0cmluZ0J1ZmZlciwgbnVsbCk7Ci0gICAgICAgICAqIGZTdHJpbmdCdWZmZXIubGVuZ3RoID0gMDsgLy8gbWFrZSBzdXJlIHdlIGtub3cgaXQncyBiZWVuIGZsdXNoZWQKLSAgICAgICAgICogfQotICAgICAgICAgKi8KLSAgICAgICAgc3VwZXIuZW5kRW50aXR5KG5hbWUsIGF1Z3MpOwotCi0gICAgICAgIC8vIG1ha2Ugc3VyZSBtYXJrdXAgaXMgcHJvcGVybHkgYmFsYW5jZWQKLSAgICAgICAgaWYgKGZNYXJrdXBEZXB0aCAhPSBmRW50aXR5U3RhY2tbZkVudGl0eURlcHRoXSkgewotICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiTWFya3VwRW50aXR5TWlzbWF0Y2giLCBudWxsKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKi8KLSAgICAgICAgLy8gY2FsbCBoYW5kbGVyCi0gICAgICAgIGlmIChmRG9jdW1lbnRIYW5kbGVyICE9IG51bGwgJiYgIWZTY2FubmluZ0F0dHJpYnV0ZSkgewotICAgICAgICAgICAgaWYgKCFuYW1lLmVxdWFscygiW3htbF0iKSkgewotICAgICAgICAgICAgICAgIGZEb2N1bWVudEhhbmRsZXIuZW5kR2VuZXJhbEVudGl0eShuYW1lLCBhdWdzKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0KLSAgICB9IC8vIGVuZEVudGl0eShTdHJpbmcpCi0KLSAgICAvLwotICAgIC8vIFByb3RlY3RlZCBtZXRob2RzCi0gICAgLy8KLQotICAgIC8vIERyaXZlciBmYWN0b3J5IG1ldGhvZHMKLQotICAgIC8qKiBDcmVhdGVzIGEgY29udGVudCBEcml2ZXIuICovCi0gICAgcHJvdGVjdGVkIERyaXZlciBjcmVhdGVDb250ZW50RHJpdmVyKCkgewotICAgICAgICByZXR1cm4gbmV3IEZyYWdtZW50Q29udGVudERyaXZlcigpOwotICAgIH0gLy8gY3JlYXRlQ29udGVudERyaXZlcigpOkRyaXZlcgotCi0gICAgLy8gc2Nhbm5pbmcgbWV0aG9kcwotCi0gICAgLyoqCi0gICAgICogU2NhbnMgYW4gWE1MIG9yIHRleHQgZGVjbGFyYXRpb24uCi0gICAgICogPHA+Ci0gICAgICogPHByZT4KLSAgICAgKiBbMjNdIFhNTERlY2wgOjo9ICcmbHQ7P3htbCcgVmVyc2lvbkluZm8gRW5jb2RpbmdEZWNsPyBTRERlY2w/IFM/ICc/PicKLSAgICAgKiBbMjRdIFZlcnNpb25JbmZvIDo6PSBTICd2ZXJzaW9uJyBFcSAoJyBWZXJzaW9uTnVtICcgfCAiIFZlcnNpb25OdW0gIikKLSAgICAgKiBbODBdIEVuY29kaW5nRGVjbCA6Oj0gUyAnZW5jb2RpbmcnIEVxICgnIicgRW5jTmFtZSAnIicgfCAgIiciIEVuY05hbWUgIiciICkKLSAgICAgKiBbODFdIEVuY05hbWUgOjo9IFtBLVphLXpdIChbQS1aYS16MC05Ll9dIHwgJy0nKSoKLSAgICAgKiBbMzJdIFNERGVjbCA6Oj0gUyAnc3RhbmRhbG9uZScgRXEgKCgiJyIgKCd5ZXMnIHwgJ25vJykgIiciKQotICAgICAqICAgICAgICAgICAgICAgICB8ICgnIicgKCd5ZXMnIHwgJ25vJykgJyInKSkKLSAgICAgKgotICAgICAqIFs3N10gVGV4dERlY2wgOjo9ICcmbHQ7P3htbCcgVmVyc2lvbkluZm8/IEVuY29kaW5nRGVjbCBTPyAnPz4nCi0gICAgICogPC9wcmU+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gc2Nhbm5pbmdUZXh0RGVjbCBUcnVlIGlmIGEgdGV4dCBkZWNsYXJhdGlvbiBpcyB0bwotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIGJlIHNjYW5uZWQgaW5zdGVhZCBvZiBhbiBYTUwKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBkZWNsYXJhdGlvbi4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCBzY2FuWE1MRGVjbE9yVGV4dERlY2woYm9vbGVhbiBzY2FubmluZ1RleHREZWNsKQotICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgWE5JRXhjZXB0aW9uIHsKLQotICAgICAgICAvLyBzY2FuIGRlY2wKLSAgICAgICAgc3VwZXIuc2NhblhNTERlY2xPclRleHREZWNsKHNjYW5uaW5nVGV4dERlY2wsIGZTdHJpbmdzKTsKLSAgICAgICAgZk1hcmt1cERlcHRoLS07Ci0KLSAgICAgICAgLy8gcHNldWRvLWF0dHJpYnV0ZSB2YWx1ZXMKLSAgICAgICAgU3RyaW5nIHZlcnNpb24gPSBmU3RyaW5nc1swXTsKLSAgICAgICAgU3RyaW5nIGVuY29kaW5nID0gZlN0cmluZ3NbMV07Ci0gICAgICAgIFN0cmluZyBzdGFuZGFsb25lID0gZlN0cmluZ3NbMl07Ci0gICAgICAgIGZEZWNsYXJlZEVuY29kaW5nID0gZW5jb2Rpbmc7Ci0gICAgICAgIC8vIHNldCBzdGFuZGFsb25lCi0gICAgICAgIGZTdGFuZGFsb25lU2V0ID0gc3RhbmRhbG9uZSAhPSBudWxsOwotICAgICAgICBmU3RhbmRhbG9uZSA9IGZTdGFuZGFsb25lU2V0ICYmIHN0YW5kYWxvbmUuZXF1YWxzKCJ5ZXMiKTsKLSAgICAgICAgLy8veHh4IHNlZSB3aGVyZSBpdHMgdXNlZC4uIHRoaXMgaXMgbm90IHVzZWQgYW55d2hlcmUuIGl0IG1heSBiZSB1c2VmdWwgZm9yIGVudGl0eSB0byBzdG9yZSB0aGlzIGluZm9ybWF0aW9uCi0gICAgICAgIC8vYnV0IHRoaXMgaW5mb3JtYXRpb24gaXMgb25seSByZWxhdGVkIHdpdGggRG9jdW1lbnQgRW50aXR5LgotICAgICAgICBmRW50aXR5TWFuYWdlci5zZXRTdGFuZGFsb25lKGZTdGFuZGFsb25lKTsKLQotCi0gICAgICAgIC8vIGNhbGwgaGFuZGxlcgotICAgICAgICBpZiAoZkRvY3VtZW50SGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAoc2Nhbm5pbmdUZXh0RGVjbCkgewotICAgICAgICAgICAgICAgIGZEb2N1bWVudEhhbmRsZXIudGV4dERlY2wodmVyc2lvbiwgZW5jb2RpbmcsIG51bGwpOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLnhtbERlY2wodmVyc2lvbiwgZW5jb2RpbmcsIHN0YW5kYWxvbmUsIG51bGwpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgaWYodmVyc2lvbiAhPSBudWxsKXsKLSAgICAgICAgICAgIGZFbnRpdHlTY2FubmVyLnNldFZlcnNpb24odmVyc2lvbik7Ci0gICAgICAgICAgICBmRW50aXR5U2Nhbm5lci5zZXRYTUxWZXJzaW9uKHZlcnNpb24pOwotICAgICAgICB9Ci0gICAgICAgIC8vIHNldCBlbmNvZGluZyBvbiByZWFkZXIsIG9ubHkgaWYgZW5jb2Rpbmcgd2FzIG5vdCBzcGVjaWZpZWQgYnkgdGhlIGFwcGxpY2F0aW9uIGV4cGxpY2l0bHkKLSAgICAgICAgaWYgKGVuY29kaW5nICE9IG51bGwgJiYgIWZFbnRpdHlTY2FubmVyLmdldEN1cnJlbnRFbnRpdHkoKS5pc0VuY29kaW5nRXh0ZXJuYWxseVNwZWNpZmllZCgpKSB7Ci0gICAgICAgICAgICAgZkVudGl0eVNjYW5uZXIuc2V0RW5jb2RpbmcoZW5jb2RpbmcpOwotICAgICAgICB9Ci0KLSAgICB9IC8vIHNjYW5YTUxEZWNsT3JUZXh0RGVjbChib29sZWFuKQotCi0gICAgcHVibGljIFN0cmluZyBnZXRQSVRhcmdldCgpewotICAgICAgICByZXR1cm4gZlBJVGFyZ2V0IDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgWE1MU3RyaW5nQnVmZmVyIGdldFBJRGF0YSgpewotICAgICAgICByZXR1cm4gZkNvbnRlbnRCdWZmZXIgOwotICAgIH0KLQotICAgIC8vWFhYOiB3aHkgbm90IHRoaXMgZnVuY3Rpb24gYmVoYXZlIGFzIHBlciB0aGUgc3RhdGUgb2YgdGhlIHBhcnNlcj8KLSAgICBwdWJsaWMgWE1MU3RyaW5nIGdldENoYXJhY3RlckRhdGEoKXsKLSAgICAgICAgaWYoZlVzZWJ1ZmZlcil7Ci0gICAgICAgICAgICByZXR1cm4gZkNvbnRlbnRCdWZmZXIgOwotICAgICAgICB9ZWxzZXsKLSAgICAgICAgICAgIHJldHVybiBmVGVtcFN0cmluZzsKLSAgICAgICAgfQotCi0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBTY2FucyBhIHByb2Nlc3NpbmcgZGF0YS4gVGhpcyBpcyBuZWVkZWQgdG8gaGFuZGxlIHRoZSBzaXR1YXRpb24KLSAgICAgKiB3aGVyZSBhIGRvY3VtZW50IHN0YXJ0cyB3aXRoIGEgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiB3aG9zZQotICAgICAqIHRhcmdldCBuYW1lIDxlbT5zdGFydHMgd2l0aDwvZW0+ICJ4bWwiLiAoZS5nLiB4bWxmb28pCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdGFyZ2V0IFRoZSBQSSB0YXJnZXQKLSAgICAgKiBAcGFyYW0gZGF0YSBUaGUgWE1MU3RyaW5nQnVmZmVyIHRvIGZpbGwgaW4gd2l0aCB0aGUgZGF0YQotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIHNjYW5QSURhdGEoU3RyaW5nIHRhcmdldCwgWE1MU3RyaW5nQnVmZmVyIGRhdGEpCi0gICAgdGhyb3dzIElPRXhjZXB0aW9uLCBYTklFeGNlcHRpb24gewotCi0gICAgICAgIHN1cGVyLnNjYW5QSURhdGEodGFyZ2V0LCBkYXRhKTsKLQotICAgICAgICAvL3NldCB0aGUgUEkgdGFyZ2V0IGFuZCB2YWx1ZXMKLSAgICAgICAgZlBJVGFyZ2V0ID0gdGFyZ2V0IDsKLQotICAgICAgICBmTWFya3VwRGVwdGgtLTsKLQotICAgIH0gLy8gc2NhblBJRGF0YShTdHJpbmcpCi0KLSAgICAvKioKLSAgICAgKiBTY2FucyBhIGNvbW1lbnQuCi0gICAgICogPHA+Ci0gICAgICogPHByZT4KLSAgICAgKiBbMTVdIENvbW1lbnQgOjo9ICcmbHQhLS0nICgoQ2hhciAtICctJykgfCAoJy0nIChDaGFyIC0gJy0nKSkpKiAnLS0+JwotICAgICAqIDwvcHJlPgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gQ2FsbGVkIGFmdGVyIHNjYW5uaW5nIHBhc3QgJyZsdDshLS0nCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgc2NhbkNvbW1lbnQoKSB0aHJvd3MgSU9FeGNlcHRpb24sIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIGZDb250ZW50QnVmZmVyLmNsZWFyKCk7Ci0gICAgICAgIHNjYW5Db21tZW50KGZDb250ZW50QnVmZmVyKTsKLSAgICAgICAgLy9nZXRUZXh0Q2hhcmFjdGVycyBjYW4gYWxzbyBiZSBjYWxsZWQgZm9yIHJlYWRpbmcgY29tbWVudHMKLSAgICAgICAgZlVzZWJ1ZmZlciA9IHRydWU7Ci0gICAgICAgIGZNYXJrdXBEZXB0aC0tOwotCi0gICAgfSAvLyBzY2FuQ29tbWVudCgpCi0KLSAgICAvL3h4eCB2YWx1ZSByZXR1cm5lZCBieSB0aGlzIGZ1bmN0aW9uIG1heSBub3QgcmVtYWluIHZhbGlkIGlmIGFub3RoZXIgZXZlbnQgaXMgc2Nhbm5lZC4KLSAgICBwdWJsaWMgU3RyaW5nIGdldENvbW1lbnQoKXsKLSAgICAgICAgcmV0dXJuIGZDb250ZW50QnVmZmVyLnRvU3RyaW5nKCk7Ci0gICAgfQotCi0gICAgdm9pZCBhZGRFbGVtZW50KFN0cmluZyByYXduYW1lKXsKLSAgICAgICAgaWYoZkVsZW1lbnRQb2ludGVyIDwgRUxFTUVOVF9BUlJBWV9MRU5HVEgpewotICAgICAgICAgICAgLy9zdG9yaW5nIGVsZW1lbnQgcmF3IG5hbWUgaW4gYSBsaW5lYXIgbGlzdCBvZiBhcnJheQotICAgICAgICAgICAgZkVsZW1lbnRBcnJheVtmRWxlbWVudFBvaW50ZXJdID0gcmF3bmFtZSA7Ci0gICAgICAgICAgICAvL3N0b3JpbmcgZWxlbW5ldFBvaW50ZXIgZm9yIHBhcnRpY3VsYXIgZWxlbWVudCBkZXB0aAotCi0gICAgICAgICAgICBpZihERUJVR19TS0lQX0FMR09SSVRITSl7Ci0gICAgICAgICAgICAgICAgU3RyaW5nQnVmZmVyIHNiID0gbmV3IFN0cmluZ0J1ZmZlcigpIDsKLSAgICAgICAgICAgICAgICBzYi5hcHBlbmQoIiBTdG9yaW5nIGVsZW1lbnQgaW5mb3JtYXRpb24gIikgOwotICAgICAgICAgICAgICAgIHNiLmFwcGVuZCgiIGZFbGVtZW50UG9pbnRlciA9ICIgKyBmRWxlbWVudFBvaW50ZXIpIDsKLSAgICAgICAgICAgICAgICBzYi5hcHBlbmQoIiBmRWxlbWVudFJhd25hbWUgPSAiICsgZkVsZW1lbnRRTmFtZS5yYXduYW1lKSA7Ci0gICAgICAgICAgICAgICAgc2IuYXBwZW5kKCIgZkVsZW1lbnRTdGFjay5mRGVwdGggPSAiICsgZkVsZW1lbnRTdGFjay5mRGVwdGgpOwotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbihzYi50b1N0cmluZygpKSA7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vc3RvcmUgcG9pbnRlciBpbmZvcm1hdGlvbiBvbmx5IHdoZW4gZWxlbWVudCBkZXB0aCBpcyBsZXNzIE1BWF9ERVBUSF9MSU1JVAotICAgICAgICAgICAgaWYoZkVsZW1lbnRTdGFjay5mRGVwdGggPCBNQVhfREVQVEhfTElNSVQpewotICAgICAgICAgICAgICAgIHNob3J0IGNvbHVtbiA9IHN0b3JlUG9pbnRlckZvckFEZXB0aChmRWxlbWVudFBvaW50ZXIpOwotICAgICAgICAgICAgICAgIGlmKGNvbHVtbiA+IDApewotICAgICAgICAgICAgICAgICAgICBzaG9ydCBwb2ludGVyID0gZ2V0RWxlbWVudFBvaW50ZXIoKHNob3J0KWZFbGVtZW50U3RhY2suZkRlcHRoLCAoc2hvcnQpKGNvbHVtbiAtIDEpICk7Ci0gICAgICAgICAgICAgICAgICAgIC8vaWRlbnRpdHkgY29tcGFyaXNvbiBzaG91bGRuJ3QgdGFrZSBtdWNoIHRpbWUgYW5kIHdlIGNhbiByZWx5IG9uIHRoaXMKLSAgICAgICAgICAgICAgICAgICAgLy9zaW5jZSBpdHMgZ3VhcmFudGVlZCB0byBoYXZlIHNhbWUgb2JqZWN0IGlkIGZvciBzYW1lIHN0cmluZy4KLSAgICAgICAgICAgICAgICAgICAgaWYocmF3bmFtZSA9PSBmRWxlbWVudEFycmF5W3BvaW50ZXJdKXsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZTaG91bGRTa2lwID0gdHJ1ZSA7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmTGFzdFBvaW50ZXJMb2NhdGlvbiA9IHBvaW50ZXIgOwotICAgICAgICAgICAgICAgICAgICAgICAgLy9yZXNldCB0aGUgdGhpbmdzIGFuZCByZXR1cm4uCi0gICAgICAgICAgICAgICAgICAgICAgICByZXNldFBvaW50ZXIoKHNob3J0KWZFbGVtZW50U3RhY2suZkRlcHRoICwgY29sdW1uKSA7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmRWxlbWVudEFycmF5W2ZFbGVtZW50UG9pbnRlcl0gPSBudWxsIDsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiA7Ci0gICAgICAgICAgICAgICAgICAgIH1lbHNlewotICAgICAgICAgICAgICAgICAgICAgICAgZlNob3VsZFNraXAgPSBmYWxzZSA7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmRWxlbWVudFBvaW50ZXIrKyA7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIHZvaWQgcmVzZXRQb2ludGVyKHNob3J0IGRlcHRoLCBzaG9ydCBjb2x1bW4pewotICAgICAgICBmUG9pbnRlckluZm9bZGVwdGhdIFtjb2x1bW5dID0gKHNob3J0KTA7Ci0gICAgfQotCi0gICAgLy9yZXR1cm5zIGNvbHVtbiBpbmZvcm1hdGlvbiBhdCB3aGljaCBwb2ludGVyIHdhcyBzdG9yZWQuCi0gICAgc2hvcnQgc3RvcmVQb2ludGVyRm9yQURlcHRoKHNob3J0IGVsZW1lbnRQb2ludGVyKXsKLSAgICAgICAgc2hvcnQgZGVwdGggPSAoc2hvcnQpIGZFbGVtZW50U3RhY2suZkRlcHRoIDsKLQotICAgICAgICAvL1N0b3JlcyBlbGVtZW50IHBvaW50ZXIgbG9jYXRpb25zIGF0IHBhcnRpY3VsYXIgZGVwdGggLCBvbmx5IDQgcG9pbnRlciBsb2NhdGlvbnMKLSAgICAgICAgLy9hcmUgc3RvcmVkIGF0IHBhcnRpY3VsYXIgZGVwdGggZm9yIG5vdy4KLSAgICAgICAgZm9yKHNob3J0IGkgPSAwIDsgaSA8IE1BWF9QT0lOVEVSX0FUX0FfREVQVEggOyBpKyspewotCi0gICAgICAgICAgICBpZihjYW5TdG9yZShkZXB0aCwgaSkpewotICAgICAgICAgICAgICAgIGZQb2ludGVySW5mb1tkZXB0aF1baV0gPSBlbGVtZW50UG9pbnRlciA7Ci0gICAgICAgICAgICAgICAgaWYoREVCVUdfU0tJUF9BTEdPUklUSE0pewotICAgICAgICAgICAgICAgICAgICBTdHJpbmdCdWZmZXIgc2IgPSBuZXcgU3RyaW5nQnVmZmVyKCkgOwotICAgICAgICAgICAgICAgICAgICBzYi5hcHBlbmQoIiBQb2ludGVyIGluZm9ybWF0aW9uICIpIDsKLSAgICAgICAgICAgICAgICAgICAgc2IuYXBwZW5kKCIgZkVsZW1lbnRQb2ludGVyID0gIiArIGZFbGVtZW50UG9pbnRlcikgOwotICAgICAgICAgICAgICAgICAgICBzYi5hcHBlbmQoIiBmRWxlbWVudFN0YWNrLmZEZXB0aCA9ICIgKyBmRWxlbWVudFN0YWNrLmZEZXB0aCk7Ci0gICAgICAgICAgICAgICAgICAgIHNiLmFwcGVuZCgiIGNvbHVtbiA9ICIgKyBpICkgOwotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oc2IudG9TdHJpbmcoKSkgOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICByZXR1cm4gaTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vZWxzZQotICAgICAgICAgICAgLy9wb2ludGVyIHdhcyBub3Qgc3RvcmVkIGJlY2F1c2Ugd2UgcmVhY2hlZCB0aGUgbGltaXQKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gLTEgOwotICAgIH0KLQotICAgIGJvb2xlYW4gY2FuU3RvcmUoc2hvcnQgZGVwdGgsIHNob3J0IGNvbHVtbil7Ci0gICAgICAgIC8vY29sdW0gPSAwICwgbWVhbnMgZmlyc3QgZWxlbWVudCBhdCBwYXJ0aWN1bGFyIGRlcHRoCi0gICAgICAgIC8vY29sdW1uID0gMSwgbWVhbnMgc2Vjb25kIGVsZW1lbnQgYXQgcGFydGljdWxhciBkZXB0aAotICAgICAgICAvLyAgICAgICAgY2FsbGUgc2hvdWxkIG1ha2Ugc3VyZSB0aGF0IGl0IGRvZXNuJ3QgY2FsbCBmb3IgdmFsdWUgb3V0c2lkZSBhbGxvd2VkIGNvLW9yZGluYXRlcwotICAgICAgICByZXR1cm4gZlBvaW50ZXJJbmZvW2RlcHRoXVtjb2x1bW5dID09IDAgPyB0cnVlIDogZmFsc2UgOwotICAgIH0KLQotCi0gICAgc2hvcnQgZ2V0RWxlbWVudFBvaW50ZXIoc2hvcnQgZGVwdGgsIHNob3J0IGNvbHVtbil7Ci0gICAgICAgIC8vY29sdW0gPSAwICwgbWVhbnMgZmlyc3QgZWxlbWVudCBhdCBwYXJ0aWN1bGFyIGRlcHRoCi0gICAgICAgIC8vY29sdW1uID0gMSwgbWVhbnMgc2Vjb25kIGVsZW1lbnQgYXQgcGFydGljdWxhciBkZXB0aAotICAgICAgICAvLyAgICAgICAgY2FsbGUgc2hvdWxkIG1ha2Ugc3VyZSB0aGF0IGl0IGRvZXNuJ3QgY2FsbCBmb3IgdmFsdWUgb3V0c2lkZSBhbGxvd2VkIGNvLW9yZGluYXRlcwotICAgICAgICByZXR1cm4gZlBvaW50ZXJJbmZvW2RlcHRoXVtjb2x1bW5dIDsKLSAgICB9Ci0KLSAgICAvL3RoaXMgZnVuY3Rpb24gYXNzdW1lcyB0aGF0IHN0cmluZyBwYXNzZWQgaXMgbm90IG51bGwgYW5kIHNraXBzCi0gICAgLy90aGUgZm9sbG93aW5nIHN0cmluZyBmcm9tIHRoZSBidWZmZXIgdGhpcyBtYWtlcyBzdXJlCi0gICAgYm9vbGVhbiBza2lwRnJvbVRoZUJ1ZmZlcihTdHJpbmcgcmF3bmFtZSkgdGhyb3dzIElPRXhjZXB0aW9uewotICAgICAgICBpZihmRW50aXR5U2Nhbm5lci5za2lwU3RyaW5nKHJhd25hbWUpKXsKLSAgICAgICAgICAgIGNoYXIgYyA9IChjaGFyKWZFbnRpdHlTY2FubmVyLnBlZWtDaGFyKCkgOwotICAgICAgICAgICAgLy9JZiB0aGUgc3RhcnQgZWxlbWVudCB3YXMgY29tcGxldGVseSBza2lwcGVkIHdlIHNob3VsZCBlbmNvdW50ZXIgZWl0aGVyICcgJyhzcGFjZSksCi0gICAgICAgICAgICAvL29yICcvJyAoaW4gY2FzZSBvZiBlbXB0eSBlbGVtZW50KSAgb3IgJz4nCi0gICAgICAgICAgICBpZiggYyA9PSAnICcgfHwgYyA9PSAnLycgfHwgYyA9PSAnPicpewotICAgICAgICAgICAgICAgIGZFbGVtZW50UmF3bmFtZSA9IHJhd25hbWUgOwotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlIDsKLSAgICAgICAgICAgIH0gZWxzZXsKLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gZWxzZQotICAgICAgICAgICAgcmV0dXJuIGZhbHNlIDsKLSAgICB9Ci0KLSAgICBib29sZWFuIHNraXBRRWxlbWVudChTdHJpbmcgcmF3bmFtZSkgdGhyb3dzIElPRXhjZXB0aW9uewotCi0gICAgICAgIGZpbmFsIGludCBjID0gZkVudGl0eVNjYW5uZXIuZ2V0Q2hhcihyYXduYW1lLmxlbmd0aCgpKTsKLSAgICAgICAgLy9pZiB0aGlzIGNoYXJhY3RlciBpcyBzdGlsbCB2YWxpZCBlbGVtZW50IG5hbWUgLS0gdGhpcyBtZWFucyBzdHJpbmcgY2FuJ3QgbWF0Y2gKLSAgICAgICAgaWYoWE1MQ2hhci5pc05hbWUoYykpewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9ZWxzZXsKLSAgICAgICAgICAgIHJldHVybiBmRW50aXR5U2Nhbm5lci5za2lwU3RyaW5nKHJhd25hbWUpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gc2tpcEVsZW1lbnQoKSB0aHJvd3MgSU9FeGNlcHRpb24gewotCi0gICAgICAgIGlmKCFmU2hvdWxkU2tpcCkgcmV0dXJuIGZhbHNlIDsKLQotICAgICAgICBpZihmTGFzdFBvaW50ZXJMb2NhdGlvbiAhPSAwKXsKLSAgICAgICAgICAgIC8vTG9vayBhdCB0aGUgbmV4dCBlbGVtZW50IHN0b3JlZCBpbiB0aGUgYXJyYXkgbGlzdC4uIHdlIG1pZ2h0IGp1c3QgZ2V0IGEgbWF0Y2guCi0gICAgICAgICAgICBTdHJpbmcgcmF3bmFtZSA9IGZFbGVtZW50QXJyYXlbZkxhc3RQb2ludGVyTG9jYXRpb24gKyAxXSA7Ci0gICAgICAgICAgICBpZihyYXduYW1lICE9IG51bGwgJiYgc2tpcEZyb21UaGVCdWZmZXIocmF3bmFtZSkpewotICAgICAgICAgICAgICAgIGZMYXN0UG9pbnRlckxvY2F0aW9uKysgOwotICAgICAgICAgICAgICAgIGlmKERFQlVHX1NLSVBfQUxHT1JJVEhNKXsKLSAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJFbGVtZW50ICIgKyBmRWxlbWVudFJhd25hbWUgKyAiIHdhcyBTS0lQUEVEIGF0IHBvaW50ZXIgbG9jYXRpb24gPSAiICsgZkxhc3RQb2ludGVyTG9jYXRpb24pOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZSA7Ci0gICAgICAgICAgICB9IGVsc2V7Ci0gICAgICAgICAgICAgICAgLy9yZXNldCBpdCBiYWNrIHRvIHplcm8uLi4gd2UgaGF2ZW4ndCBnb3QgdGhlIGNvcnJlY3Qgc3Vic2V0IHlldC4KLSAgICAgICAgICAgICAgICBmTGFzdFBvaW50ZXJMb2NhdGlvbiA9IDAgOwotCi0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgLy94eHg6IHdlIGNhbiBwdXQgc29tZSBsb2dpYyBoZXJlIGFzIGZyb20gd2hhdCBjb2x1bW4gaXQgc2hvdWxkIHN0YXJ0IGxvb2tpbmcKLSAgICAgICAgLy9mb3Igbm93IHdlIGFsd2F5cyBzdGFydCBhdCAwCi0gICAgICAgIC8vZmFsbGJhY2sgdG8gdG9sZXJhbnQgYWxnb3JpdGhtLCBpdCB3b3VsZCBsb29rIGZvciBkaWZmZXJudCBlbGVtZW50IHN0b3JlZCBhdCBkaWZmZXJlbnQKLSAgICAgICAgLy9kZXB0aCBhbmQgZ2V0IHVzIHRoZSBwb2ludGVyIGxvY2F0aW9uLgotICAgICAgICByZXR1cm4gZlNob3VsZFNraXAgJiYgc2tpcEVsZW1lbnQoKHNob3J0KTApOwotCi0gICAgfQotCi0gICAgLy9zdGFydCBvZiB0aGUgY29sdW1uIGF0IHdoaWNoIGl0IHNob3VsZCB0cnkgc2VhcmNoaW5nCi0gICAgYm9vbGVhbiBza2lwRWxlbWVudChzaG9ydCBjb2x1bW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgIHNob3J0IGRlcHRoID0gKHNob3J0KWZFbGVtZW50U3RhY2suZkRlcHRoIDsKLQotICAgICAgICBpZihkZXB0aCA+IE1BWF9ERVBUSF9MSU1JVCl7Ci0gICAgICAgICAgICByZXR1cm4gZlNob3VsZFNraXAgPSBmYWxzZSA7Ci0gICAgICAgIH0KLSAgICAgICAgZm9yKHNob3J0IGkgPSBjb2x1bW4gOyBpIDwgTUFYX1BPSU5URVJfQVRfQV9ERVBUSCA7IGkrKyl7Ci0gICAgICAgICAgICBzaG9ydCBwb2ludGVyID0gZ2V0RWxlbWVudFBvaW50ZXIoZGVwdGggLCBpICkgOwotCi0gICAgICAgICAgICBpZihwb2ludGVyID09IDApewotICAgICAgICAgICAgICAgIHJldHVybiBmU2hvdWxkU2tpcCA9IGZhbHNlIDsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYoZkVsZW1lbnRBcnJheVtwb2ludGVyXSAhPSBudWxsICYmIHNraXBGcm9tVGhlQnVmZmVyKGZFbGVtZW50QXJyYXlbcG9pbnRlcl0pKXsKLSAgICAgICAgICAgICAgICBpZihERUJVR19TS0lQX0FMR09SSVRITSl7Ci0gICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigpOwotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkVsZW1lbnQgIiArIGZFbGVtZW50UmF3bmFtZSArICIgd2FzIFNLSVBQRUQgYXQgZGVwdGggPSAiICsgZkVsZW1lbnRTdGFjay5mRGVwdGggKyAiIGNvbHVtbiA9ICIgKyBjb2x1bW4gKTsKLSAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGZMYXN0UG9pbnRlckxvY2F0aW9uID0gcG9pbnRlciA7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZTaG91bGRTa2lwID0gdHJ1ZSA7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGZTaG91bGRTa2lwID0gZmFsc2UgOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNjYW5zIGEgc3RhcnQgZWxlbWVudC4gVGhpcyBtZXRob2Qgd2lsbCBoYW5kbGUgdGhlIGJpbmRpbmcgb2YKLSAgICAgKiBuYW1lc3BhY2UgaW5mb3JtYXRpb24gYW5kIG5vdGlmeWluZyB0aGUgaGFuZGxlciBvZiB0aGUgc3RhcnQKLSAgICAgKiBvZiB0aGUgZWxlbWVudC4KLSAgICAgKiA8cD4KLSAgICAgKiA8cHJlPgotICAgICAqIFs0NF0gRW1wdHlFbGVtVGFnIDo6PSAnJmx0OycgTmFtZSAoUyBBdHRyaWJ1dGUpKiBTPyAnLz4nCi0gICAgICogWzQwXSBTVGFnIDo6PSAnJmx0OycgTmFtZSAoUyBBdHRyaWJ1dGUpKiBTPyAnPicKLSAgICAgKiA8L3ByZT4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoaXMgbWV0aG9kIGFzc3VtZXMgdGhhdCB0aGUgbGVhZGluZwotICAgICAqICcmbHQ7JyBjaGFyYWN0ZXIgaGFzIGJlZW4gY29uc3VtZWQuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGlzIG1ldGhvZCB1c2VzIHRoZSBmRWxlbWVudFFOYW1lIGFuZAotICAgICAqIGZBdHRyaWJ1dGVzIHZhcmlhYmxlcy4gVGhlIGNvbnRlbnRzIG9mIHRoZXNlIHZhcmlhYmxlcyB3aWxsIGJlCi0gICAgICogZGVzdHJveWVkLiBUaGUgY2FsbGVyIHNob3VsZCBjb3B5IGltcG9ydGFudCBpbmZvcm1hdGlvbiBvdXQgb2YKLSAgICAgKiB0aGVzZSB2YXJpYWJsZXMgYmVmb3JlIGNhbGxpbmcgdGhpcyBtZXRob2QuCi0gICAgICogTkI6IENvbnRlbnQgaW4gZkF0dHJpYnV0ZXMgaXMgdmFsaWQgb25seSB0aWxsIHRoZSBzdGF0ZSBvZiB0aGUgcGFyc2VyIGlzIFhNTEV2ZW50LlNUQVJUX0VMRU1FTlQKLSAgICAgKgotICAgICAqIEByZXR1cm4gVHJ1ZSBpZiBlbGVtZW50IGlzIGVtcHR5LiAoaS5lLiBJdCBtYXRjaGVzCi0gICAgICogICAgICAgICAgcHJvZHVjdGlvbiBbNDRdLgotICAgICAqLwotICAgIC8vIGZFbGVtZW50UU5hbWUgd2lsbCBoYXZlIHRoZSBkZXRhaWxzIG9mIGVsZW1lbnQganVzdCByZWFkLi4KLSAgICAvLyBmQXR0cmlidXRlcyB3aWxsIGhhdmUgdGhlIGRldGFpbHMgb2YgYWxsIHRoZSBhdHRyaWJ1dGVzLgotICAgIHByb3RlY3RlZCBib29sZWFuIHNjYW5TdGFydEVsZW1lbnQoKQotICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgWE5JRXhjZXB0aW9uIHsKLQotICAgICAgICBpZiAoREVCVUdfU1RBUlRfRU5EX0VMRU1FTlQpIFN5c3RlbS5vdXQucHJpbnRsbiggdGhpcy5nZXRDbGFzcygpLnRvU3RyaW5nKCkgKyAiPj4+IHNjYW5TdGFydEVsZW1lbnQoKSIpOwotICAgICAgICAvL3doZW4gc2tpcHBpbmcgaXMgdHJ1ZSBhbmQgbm8gbW9yZSBlbGVtZW50cyBzaG91bGQgYmUgYWRkZWQKLSAgICAgICAgaWYoZlNraXAgJiYgIWZBZGQpewotICAgICAgICAgICAgLy9nZXQgdGhlIHN0b3JlZCBlbGVtZW50IC0tIGlmIGV2ZXJ5dGhpbmcgZ29lcyByaWdodCB0aGlzIHNob3VsZCBtYXRjaCB0aGUKLSAgICAgICAgICAgIC8vdG9rZW4gaW4gdGhlIGJ1ZmZlcgotCi0gICAgICAgICAgICBRTmFtZSBuYW1lID0gZkVsZW1lbnRTdGFjay5nZXROZXh0KCk7Ci0KLSAgICAgICAgICAgIGlmKERFQlVHX1NLSVBfQUxHT1JJVEhNKXsKLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlRyeWluZyB0byBza2lwIFN0cmluZyA9ICIgKyBuYW1lLnJhd25hbWUpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvL0JlIGNvbnNlcnZhdGl2ZSAtLSBpZiBza2lwcGluZyBmYWlscyAtLSBzdG9wLgotICAgICAgICAgICAgZlNraXAgPSBmRW50aXR5U2Nhbm5lci5za2lwU3RyaW5nKG5hbWUucmF3bmFtZSk7Ci0KLSAgICAgICAgICAgIGlmKGZTa2lwKXsKLSAgICAgICAgICAgICAgICBpZihERUJVR19TS0lQX0FMR09SSVRITSl7Ci0gICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiRWxlbWVudCBTVUNFU1NGVUxMWSBza2lwcGVkID0gIiArIG5hbWUucmF3bmFtZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGZFbGVtZW50U3RhY2sucHVzaCgpOwotICAgICAgICAgICAgICAgIGZFbGVtZW50UU5hbWUgPSBuYW1lOwotICAgICAgICAgICAgfWVsc2V7Ci0gICAgICAgICAgICAgICAgLy9pZiBza2lwcGluZyBmYWlscyByZXBvc2l0aW9uIHRoZSBzdGFjayBvciBmYWxsYmFjayB0byBub3JtYWwgd2F5IG9mIHByb2Nlc3NpbmcKLSAgICAgICAgICAgICAgICBmRWxlbWVudFN0YWNrLnJlcG9zaXRpb24oKTsKLSAgICAgICAgICAgICAgICBpZihERUJVR19TS0lQX0FMR09SSVRITSl7Ci0gICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiRWxlbWVudCB3YXMgTk9UIHNraXBwZWQsIFJFUE9TSVRJT05JTkcgc3RhY2siICk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy93ZSBhcmUgc3RpbGwgYXQgdGhlIHN0YWdlIG9mIGFkZGluZyBlbGVtZW50cwotICAgICAgICAvL3RoZSBlbGVtZW50cyB3ZXJlIG5vdCBtYXRjaGVkIG9yCi0gICAgICAgIC8vZlNraXAgaXMgbm90IHNldCB0byB0cnVlCi0gICAgICAgIGlmKCFmU2tpcCB8fCBmQWRkKXsKLSAgICAgICAgICAgIC8vZ2V0IHRoZSBuZXh0IGVsZW1lbnQgZnJvbSB0aGUgc3RhY2sKLSAgICAgICAgICAgIGZFbGVtZW50UU5hbWUgPSBmRWxlbWVudFN0YWNrLm5leHRFbGVtZW50KCk7Ci0gICAgICAgICAgICAvLyBuYW1lCi0gICAgICAgICAgICBpZiAoZk5hbWVzcGFjZXMpIHsKLSAgICAgICAgICAgICAgICBmRW50aXR5U2Nhbm5lci5zY2FuUU5hbWUoZkVsZW1lbnRRTmFtZSwgTmFtZVR5cGUuRUxFTUVOVFNUQVJUKTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIG5hbWUgPSBmRW50aXR5U2Nhbm5lci5zY2FuTmFtZShOYW1lVHlwZS5FTEVNRU5UU1RBUlQpOwotICAgICAgICAgICAgICAgIGZFbGVtZW50UU5hbWUuc2V0VmFsdWVzKG51bGwsIG5hbWUsIG5hbWUsIG51bGwpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZihERUJVRylTeXN0ZW0ub3V0LnByaW50bG4oIkVsZW1lbnQgc2Nhbm5lZCBpbiBzdGFydCBlbGVtZW50IGlzICIgKyBmRWxlbWVudFFOYW1lLnRvU3RyaW5nKCkpOwotICAgICAgICAgICAgaWYoREVCVUdfU0tJUF9BTEdPUklUSE0pewotICAgICAgICAgICAgICAgIGlmKGZBZGQpewotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkVsZW1lbnRzIGFyZSBiZWluZyBBRERFRCAtLSBlbGVtZXQgYWRkZWQgaXMgPSAiICsgZkVsZW1lbnRRTmFtZS5yYXduYW1lICsgIiBhdCBjb3VudCA9ICIgKyBmRWxlbWVudFN0YWNrLmZDb3VudCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgIH0KLQotICAgICAgICAvL3doZW4gdGhlIGVsZW1lbnRzIGFyZSBiZWluZyBhZGRlZCAsIHdlIG5lZWQgdG8gY2hlY2sgaWYgd2UgYXJlIHNldCBmb3Igc2tpcHBpbmcgdGhlIGVsZW1lbnRzCi0gICAgICAgIGlmKGZBZGQpewotICAgICAgICAgICAgLy90aGlzIHNldHMgdGhlIHZhbHVlIG9mIGZBZGQgdmFyaWFibGUKLSAgICAgICAgICAgIGZFbGVtZW50U3RhY2subWF0Y2hFbGVtZW50KGZFbGVtZW50UU5hbWUpOwotICAgICAgICB9Ci0KLQotICAgICAgICAvL3h4eDogV2UgZG9udCBuZWVkIGFub3RoZXIgcG9pbnRlciwgZkN1cnJlbnRFbGVtZW50LCB3ZSBjYW4gdXNlIGZFbGVtZW50UU5hbWUKLSAgICAgICAgZkN1cnJlbnRFbGVtZW50ID0gZkVsZW1lbnRRTmFtZTsKLQotICAgICAgICBTdHJpbmcgcmF3bmFtZSA9IGZFbGVtZW50UU5hbWUucmF3bmFtZTsKLQotICAgICAgICBmRW1wdHlFbGVtZW50ID0gZmFsc2U7Ci0KLSAgICAgICAgZkF0dHJpYnV0ZXMucmVtb3ZlQWxsQXR0cmlidXRlcygpOwotCi0gICAgICAgIGNoZWNrRGVwdGgocmF3bmFtZSk7Ci0gICAgICAgIGlmKCFzZWVrQ2xvc2VPZlN0YXJ0VGFnKCkpewotICAgICAgICAgICAgZlJlYWRpbmdBdHRyaWJ1dGVzID0gdHJ1ZTsKLSAgICAgICAgICAgIGZBdHRyaWJ1dGVDYWNoZVVzZWRDb3VudCA9MDsKLSAgICAgICAgICAgIGZTdHJpbmdCdWZmZXJJbmRleCA9MDsKLSAgICAgICAgICAgIGZBZGREZWZhdWx0QXR0ciA9IHRydWU7Ci0gICAgICAgICAgICBkbyB7Ci0gICAgICAgICAgICAgICAgc2NhbkF0dHJpYnV0ZShmQXR0cmlidXRlcyk7Ci0gICAgICAgICAgICAgICAgaWYgKGZTZWN1cml0eU1hbmFnZXIgIT0gbnVsbCAmJiAhZlNlY3VyaXR5TWFuYWdlci5pc05vTGltaXQoZkVsZW1lbnRBdHRyaWJ1dGVMaW1pdCkgJiYKLSAgICAgICAgICAgICAgICAgICAgICAgIGZBdHRyaWJ1dGVzLmdldExlbmd0aCgpID4gZkVsZW1lbnRBdHRyaWJ1dGVMaW1pdCl7Ci0gICAgICAgICAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRWxlbWVudEF0dHJpYnV0ZUxpbWl0IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117cmF3bmFtZSwgZkVsZW1lbnRBdHRyaWJ1dGVMaW1pdCB9LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTEVycm9yUmVwb3J0ZXIuU0VWRVJJVFlfRkFUQUxfRVJST1IgKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIH0gd2hpbGUgKCFzZWVrQ2xvc2VPZlN0YXJ0VGFnKCkpOwotICAgICAgICAgICAgZlJlYWRpbmdBdHRyaWJ1dGVzPWZhbHNlOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKGZFbXB0eUVsZW1lbnQpIHsKLSAgICAgICAgICAgIC8vZGVjcmVhc2UgdGhlIG1hcmt1cCBkZXB0aC4uCi0gICAgICAgICAgICBmTWFya3VwRGVwdGgtLTsKLQotICAgICAgICAgICAgLy8gY2hlY2sgdGhhdCB0aGlzIGVsZW1lbnQgd2FzIG9wZW5lZCBpbiB0aGUgc2FtZSBlbnRpdHkKLSAgICAgICAgICAgIGlmIChmTWFya3VwRGVwdGggPCBmRW50aXR5U3RhY2tbZkVudGl0eURlcHRoIC0gMV0pIHsKLSAgICAgICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJFbGVtZW50RW50aXR5TWlzbWF0Y2giLAotICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde2ZDdXJyZW50RWxlbWVudC5yYXduYW1lfSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyBjYWxsIGhhbmRsZXIKLSAgICAgICAgICAgIGlmIChmRG9jdW1lbnRIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLmVtcHR5RWxlbWVudChmRWxlbWVudFFOYW1lLCBmQXR0cmlidXRlcywgbnVsbCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vV2Ugc2hvdWxkIG5vdCBiZSBwb3BwaW5nIG91dCB0aGUgY29udGV4dCBoZXJlIGluIGVuZEVMZW1lbnQgYmVjYWF1c2UgdGhlIG5hbWVzcGFjZSBjb250ZXh0IGlzIHN0aWxsCi0gICAgICAgICAgICAvL3ZhbGlkIHdoZW4gcGFyc2VyIGlzIGF0IHRoZSBlbmRFbGVtZW50IHN0YXRlLgotICAgICAgICAgICAgLy9pZiAoZk5hbWVzcGFjZXMpIHsKLSAgICAgICAgICAgIC8vICBmTmFtZXNwYWNlQ29udGV4dC5wb3BDb250ZXh0KCk7Ci0gICAgICAgICAgICAvL30KLQotICAgICAgICAgICAgLy9wb3AgdGhlIGVsZW1lbnQgb2ZmIHRoZSBzdGFjay4uCi0gICAgICAgICAgICBmRWxlbWVudFN0YWNrLnBvcEVsZW1lbnQoKTsKLQotICAgICAgICB9IGVsc2UgewotCi0gICAgICAgICAgICBpZihkdGRHcmFtbWFyVXRpbCAhPSBudWxsKQotICAgICAgICAgICAgICAgIGR0ZEdyYW1tYXJVdGlsLnN0YXJ0RWxlbWVudChmRWxlbWVudFFOYW1lLCBmQXR0cmlidXRlcyk7Ci0gICAgICAgICAgICBpZihmRG9jdW1lbnRIYW5kbGVyICE9IG51bGwpewotICAgICAgICAgICAgICAgIC8vY29tcGxldGUgZWxlbWVudCBhbmQgYXR0cmlidXRlcyBhcmUgdHJhdmVyc2VkIGluIHRoaXMgZnVuY3Rpb24gc28gd2UgY2FuIHNlbmQgYSBjYWxsYmFjawotICAgICAgICAgICAgICAgIC8vaGVyZS4KLSAgICAgICAgICAgICAgICAvLzxzdHJvbmc+d2Ugc2hvdWxkbid0IGJlIHNlbmRpbmcgY2FsbGJhY2sgaW4gc2NhbkRvY3VtZW50KCk8L3N0cm9uZz4KLSAgICAgICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLnN0YXJ0RWxlbWVudChmRWxlbWVudFFOYW1lLCBmQXR0cmlidXRlcywgbnVsbCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotCi0gICAgICAgIGlmIChERUJVR19TVEFSVF9FTkRfRUxFTUVOVCkgU3lzdGVtLm91dC5wcmludGxuKHRoaXMuZ2V0Q2xhc3MoKS50b1N0cmluZygpICsgIjw8PCBzY2FuU3RhcnRFbGVtZW50KCk6ICIrZkVtcHR5RWxlbWVudCk7Ci0gICAgICAgIHJldHVybiBmRW1wdHlFbGVtZW50OwotCi0gICAgfSAvLyBzY2FuU3RhcnRFbGVtZW50KCk6Ym9vbGVhbgotCi0gICAgLyoqCi0gICAgICogTG9va3MgZm9yIHRoZSBjbG9zZSBvZiBzdGFydCB0YWcsIGkuZS4gaWYgaXQgZmluZHMgJz4nIG9yICcvPicKLSAgICAgKiBDaGFyYWN0ZXJzIGFyZSBjb25zdW1lZC4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBzZWVrQ2xvc2VPZlN0YXJ0VGFnKCkgdGhyb3dzIElPRXhjZXB0aW9uLCBYTklFeGNlcHRpb24gewotICAgICAgICAvLyBzcGFjZXMKLSAgICAgICAgYm9vbGVhbiBzYXdTcGFjZSA9IGZFbnRpdHlTY2FubmVyLnNraXBTcGFjZXMoKTsKLQotICAgICAgICAvLyBlbmQgdGFnPwotICAgICAgICBmaW5hbCBpbnQgYyA9IGZFbnRpdHlTY2FubmVyLnBlZWtDaGFyKCk7Ci0gICAgICAgIGlmIChjID09ICc+JykgewotICAgICAgICAgICAgZkVudGl0eVNjYW5uZXIuc2NhbkNoYXIobnVsbCk7Ci0gICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgfSBlbHNlIGlmIChjID09ICcvJykgewotICAgICAgICAgICAgZkVudGl0eVNjYW5uZXIuc2NhbkNoYXIobnVsbCk7Ci0gICAgICAgICAgICBpZiAoIWZFbnRpdHlTY2FubmVyLnNraXBDaGFyKCc+JywgTmFtZVR5cGUuRUxFTUVOVEVORCkpIHsKLSAgICAgICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJFbGVtZW50VW50ZXJtaW5hdGVkIiwKLSAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXtmRWxlbWVudFFOYW1lLnJhd25hbWV9KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGZFbXB0eUVsZW1lbnQgPSB0cnVlOwotICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgIH0gZWxzZSBpZiAoIWlzVmFsaWROYW1lU3RhcnRDaGFyKGMpIHx8ICFzYXdTcGFjZSkgewotICAgICAgICAgICAgLy8gU2Vjb25kIGNoYW5jZS4gQ2hlY2sgaWYgdGhpcyBjaGFyYWN0ZXIgaXMgYSBoaWdoCi0gICAgICAgICAgICAvLyBzdXJyb2dhdGUgb2YgYSB2YWxpZCBuYW1lIHN0YXJ0IGNoYXJhY3Rlci4KLSAgICAgICAgICAgIGlmICghaXNWYWxpZE5hbWVTdGFydEhpZ2hTdXJyb2dhdGUoYykgfHwgIXNhd1NwYWNlKSB7Ci0gICAgICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiRWxlbWVudFVudGVybWluYXRlZCIsCi0gICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117ZkVsZW1lbnRRTmFtZS5yYXduYW1lfSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gaGFzQXR0cmlidXRlcygpewotICAgICAgICByZXR1cm4gZkF0dHJpYnV0ZXMuZ2V0TGVuZ3RoKCkgPiAwID8gdHJ1ZSA6IGZhbHNlIDsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFNjYW5zIGFuIGF0dHJpYnV0ZS4KLSAgICAgKiA8cD4KLSAgICAgKiA8cHJlPgotICAgICAqIFs0MV0gQXR0cmlidXRlIDo6PSBOYW1lIEVxIEF0dFZhbHVlCi0gICAgICogPC9wcmU+Ci0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGlzIG1ldGhvZCBhc3N1bWVzIHRoYXQgdGhlIG5leHQKLSAgICAgKiBjaGFyYWN0ZXIgb24gdGhlIHN0cmVhbSBpcyB0aGUgZmlyc3QgY2hhcmFjdGVyIG9mIHRoZSBhdHRyaWJ1dGUKLSAgICAgKiBuYW1lLgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gVGhpcyBtZXRob2QgdXNlcyB0aGUgZkF0dHJpYnV0ZVFOYW1lIGFuZAotICAgICAqIGZRTmFtZSB2YXJpYWJsZXMuIFRoZSBjb250ZW50cyBvZiB0aGVzZSB2YXJpYWJsZXMgd2lsbCBiZQotICAgICAqIGRlc3Ryb3llZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBhdHRyaWJ1dGVzIFRoZSBhdHRyaWJ1dGVzIGxpc3QgZm9yIHRoZSBzY2FubmVkIGF0dHJpYnV0ZS4KLSAgICAgKi8KLQotICAgIC8qKgotICAgICAqIHByb3RlY3RlZCB2b2lkIHNjYW5BdHRyaWJ1dGUoQXR0cmlidXRlSXRlcmF0b3JJbXBsIGF0dHJpYnV0ZXMpCi0gICAgICogdGhyb3dzIElPRXhjZXB0aW9uLCBYTklFeGNlcHRpb24gewotICAgICAqIGlmIChERUJVR19TVEFSVF9FTkRfRUxFTUVOVCkgU3lzdGVtLm91dC5wcmludGxuKCI+Pj4gc2NhbkF0dHJpYnV0ZSgpIik7Ci0gICAgICoKLSAgICAgKgotICAgICAqIC8vIG5hbWUKLSAgICAgKiBpZiAoZk5hbWVzcGFjZXMpIHsKLSAgICAgKiBmRW50aXR5U2Nhbm5lci5zY2FuUU5hbWUoZkF0dHJpYnV0ZVFOYW1lKTsKLSAgICAgKiB9Ci0gICAgICogZWxzZSB7Ci0gICAgICogU3RyaW5nIG5hbWUgPSBmRW50aXR5U2Nhbm5lci5zY2FuTmFtZSgpOwotICAgICAqIGZBdHRyaWJ1dGVRTmFtZS5zZXRWYWx1ZXMobnVsbCwgbmFtZSwgbmFtZSwgbnVsbCk7Ci0gICAgICogfQotICAgICAqCi0gICAgICogLy8gZXF1YWxzCi0gICAgICogZkVudGl0eVNjYW5uZXIuc2tpcFNwYWNlcygpOwotICAgICAqIGlmICghZkVudGl0eVNjYW5uZXIuc2tpcENoYXIoJz0nKSkgewotICAgICAqIHJlcG9ydEZhdGFsRXJyb3IoIkVxUmVxdWlyZWRJbkF0dHJpYnV0ZSIsCi0gICAgICogbmV3IE9iamVjdFtde2ZBdHRyaWJ1dGVRTmFtZS5yYXduYW1lfSk7Ci0gICAgICogfQotICAgICAqIGZFbnRpdHlTY2FubmVyLnNraXBTcGFjZXMoKTsKLSAgICAgKgotICAgICAqCi0gICAgICogLy8gY29udGVudAotICAgICAqIGludCBvbGRMZW4gPSBhdHRyaWJ1dGVzLmdldExlbmd0aCgpOwotICAgICAqLwotICAgIC8qKnh4eCB0aGVyZSBpcyBvbmUgY2hlY2sgb2YgZHVwbGljYXRlIGF0dHJpYnV0ZSB0aGF0IGhhcyBiZWVuIHJlbW92ZWQuCi0gICAgICogYXR0cmlidXRlcy5hZGRBdHRyaWJ1dGUoZkF0dHJpYnV0ZVFOYW1lLCBYTUxTeW1ib2xzLmZDREFUQVN5bWJvbCwgbnVsbCk7Ci0gICAgICoKLSAgICAgKiAvLyBXRkM6IFVuaXF1ZSBBdHQgU3BlYwotICAgICAqIGlmIChvbGRMZW4gPT0gYXR0cmlidXRlcy5nZXRMZW5ndGgoKSkgewotICAgICAqIHJlcG9ydEZhdGFsRXJyb3IoIkF0dHJpYnV0ZU5vdFVuaXF1ZSIsCi0gICAgICogbmV3IE9iamVjdFtde2ZDdXJyZW50RWxlbWVudC5yYXduYW1lLAotICAgICAqIGZBdHRyaWJ1dGVRTmFtZS5yYXduYW1lfSk7Ci0gICAgICogfQotICAgICAqLwotCi0gICAgLyoKLSAgICAgICAgLy9SRVZJU0lUOiBvbmUgbW9yZSBjYXNlIG5lZWRzIHRvIGJlIGluY2x1ZGVkOiBleHRlcm5hbCBQRSBhbmQgc3RhbmRhbG9uZSBpcyBubwotICAgICAgICBib29sZWFuIGlzVkMgPSAgZkhhc0V4dGVybmFsRFREICYmICFmU3RhbmRhbG9uZTsKLSAgICAgICAgc2NhbkF0dHJpYnV0ZVZhbHVlKGZUZW1wU3RyaW5nLCBmVGVtcFN0cmluZzIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICBmQXR0cmlidXRlUU5hbWUucmF3bmFtZSwgYXR0cmlidXRlcywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgIG9sZExlbiwgaXNWQyk7Ci0KLSAgICAgICAgLy9hdHRyaWJ1dGVzLnNldFZhbHVlKG9sZExlbiwgZlRlbXBTdHJpbmcudG9TdHJpbmcoKSk7Ci0gICAgICAgIC8vYXR0cmlidXRlcy5zZXROb25Ob3JtYWxpemVkVmFsdWUob2xkTGVuLCBmVGVtcFN0cmluZzIudG9TdHJpbmcoKSk7Ci0gICAgICAgIC8vYXR0cmlidXRlcy5zZXRTcGVjaWZpZWQob2xkTGVuLCB0cnVlKTsKLQotICAgICAgICBBdHRyaWJ1dGVJbXBsIGF0dHJpYnV0ZSA9IG5ldyBBdHRyaWJ1dGVJbXBsKGZBdHRyaWJ1dGVRTmFtZS5wcmVmaXgsZkF0dHJpYnV0ZVFOYW1lLmxvY2FscGFydCxmQXR0cmlidXRlUU5hbWUudXJpLGZUZW1wU3RyaW5nLnRvU3RyaW5nKCksZlRlbXBTdHJpbmcyLnRvU3RyaW5nKCksWE1MU3ltYm9scy5mQ0RBVEFTeW1ib2wsdHJ1ZSk7Ci0gICAgICAgIGZBdHRyaWJ1dGVzLmFkZEF0dHJpYnV0ZShhdHRyaWJ1dGUpOwotICAgICAgICBpZiAoREVCVUdfU1RBUlRfRU5EX0VMRU1FTlQpIFN5c3RlbS5vdXQucHJpbnRsbigiPDw8IHNjYW5BdHRyaWJ1dGUoKSIpOwotICAgIH0gLy8gc2NhbkF0dHJpYnV0ZShYTUxBdHRyaWJ1dGVzKQotCi0gICAgICovCi0KLSAgICAvKiogcmV0dXJuIHRoZSBhdHRyaWJ1dGUgaXRlcmF0b3IgaW1wbGVtZW50YXRpb24gKi8KLSAgICBwdWJsaWMgWE1MQXR0cmlidXRlc0l0ZXJhdG9ySW1wbCBnZXRBdHRyaWJ1dGVJdGVyYXRvcigpewotICAgICAgICBpZihkdGRHcmFtbWFyVXRpbCAhPSBudWxsICYmIGZBZGREZWZhdWx0QXR0cil7Ci0gICAgICAgICAgICBkdGRHcmFtbWFyVXRpbC5hZGREVEREZWZhdWx0QXR0cnMoZkVsZW1lbnRRTmFtZSxmQXR0cmlidXRlcyk7Ci0gICAgICAgICAgICBmQWRkRGVmYXVsdEF0dHIgPSBmYWxzZTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZkF0dHJpYnV0ZXM7Ci0gICAgfQotCi0gICAgLyoqIHJldHVybiBpZiBzdGFuZGFsb25lIGlzIHNldCAqLwotICAgIHB1YmxpYyBib29sZWFuIHN0YW5kYWxvbmVTZXQoKXsKLSAgICAgICAgcmV0dXJuIGZTdGFuZGFsb25lU2V0OwotICAgIH0KLSAgICAvKiogcmV0dXJuIGlmIHRoZSBkb3VjbWVudCBpcyBzdGFuZGFsb25lICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNTdGFuZEFsb25lKCl7Ci0gICAgICAgIHJldHVybiBmU3RhbmRhbG9uZSA7Ci0gICAgfQotICAgIC8qKgotICAgICAqIFNjYW5zIGFuIGF0dHJpYnV0ZSBuYW1lIHZhbHVlIHBhaXIuCi0gICAgICogPHA+Ci0gICAgICogPHByZT4KLSAgICAgKiBbNDFdIEF0dHJpYnV0ZSA6Oj0gTmFtZSBFcSBBdHRWYWx1ZQotICAgICAqIDwvcHJlPgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gVGhpcyBtZXRob2QgYXNzdW1lcyB0aGF0IHRoZSBuZXh0Ci0gICAgICogY2hhcmFjdGVyIG9uIHRoZSBzdHJlYW0gaXMgdGhlIGZpcnN0IGNoYXJhY3RlciBvZiB0aGUgYXR0cmlidXRlCi0gICAgICogbmFtZS4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoaXMgbWV0aG9kIHVzZXMgdGhlIGZBdHRyaWJ1dGVRTmFtZSBhbmQKLSAgICAgKiBmUU5hbWUgdmFyaWFibGVzLiBUaGUgY29udGVudHMgb2YgdGhlc2UgdmFyaWFibGVzIHdpbGwgYmUKLSAgICAgKiBkZXN0cm95ZWQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYXR0cmlidXRlcyBUaGUgYXR0cmlidXRlcyBsaXN0IGZvciB0aGUgc2Nhbm5lZCBhdHRyaWJ1dGUuCi0gICAgICovCi0KLSAgICBwcm90ZWN0ZWQgdm9pZCBzY2FuQXR0cmlidXRlKFhNTEF0dHJpYnV0ZXMgYXR0cmlidXRlcykKLSAgICB0aHJvd3MgSU9FeGNlcHRpb24sIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChERUJVR19TVEFSVF9FTkRfRUxFTUVOVCkgU3lzdGVtLm91dC5wcmludGxuKHRoaXMuZ2V0Q2xhc3MoKS50b1N0cmluZygpICsiPj4+IHNjYW5BdHRyaWJ1dGUoKSIpOwotCi0gICAgICAgIC8vIG5hbWUKLSAgICAgICAgaWYgKGZOYW1lc3BhY2VzKSB7Ci0gICAgICAgICAgICBmRW50aXR5U2Nhbm5lci5zY2FuUU5hbWUoZkF0dHJpYnV0ZVFOYW1lLCBOYW1lVHlwZS5BVFRSSUJVVEVOQU1FKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIFN0cmluZyBuYW1lID0gZkVudGl0eVNjYW5uZXIuc2Nhbk5hbWUoTmFtZVR5cGUuQVRUUklCVVRFTkFNRSk7Ci0gICAgICAgICAgICBmQXR0cmlidXRlUU5hbWUuc2V0VmFsdWVzKG51bGwsIG5hbWUsIG5hbWUsIG51bGwpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gZXF1YWxzCi0gICAgICAgIGZFbnRpdHlTY2FubmVyLnNraXBTcGFjZXMoKTsKLSAgICAgICAgaWYgKCFmRW50aXR5U2Nhbm5lci5za2lwQ2hhcignPScsIE5hbWVUeXBlLkFUVFJJQlVURSkpIHsKLSAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIkVxUmVxdWlyZWRJbkF0dHJpYnV0ZSIsCi0gICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHtmQ3VycmVudEVsZW1lbnQucmF3bmFtZSwgZkF0dHJpYnV0ZVFOYW1lLnJhd25hbWV9KTsKLSAgICAgICAgfQotICAgICAgICBmRW50aXR5U2Nhbm5lci5za2lwU3BhY2VzKCk7Ci0KLSAgICAgICAgaW50IGF0dEluZGV4ID0gMCA7Ci0gICAgICAgIC8vUkVWSVNJVDogb25lIG1vcmUgY2FzZSBuZWVkcyB0byBiZSBpbmNsdWRlZDogZXh0ZXJuYWwgUEUgYW5kIHN0YW5kYWxvbmUgaXMgbm8KLSAgICAgICAgYm9vbGVhbiBpc1ZDID0gIGZIYXNFeHRlcm5hbERURCAmJiAhZlN0YW5kYWxvbmU7Ci0gICAgICAgIC8vZlRlbXBTdHJpbmcgd291bGQgc3RvcmUgYXR0cmlidXRlIHZhbHVlCi0gICAgICAgIC8vL2ZUZW1wU3RyaW5nMiB3b3VsZCBzdG9yZSBhdHRyaWJ1dGUgbm9uLW5vcm1hbGl6ZWQgdmFsdWUKLQotICAgICAgICAvL3RoaXMgZnVuY3Rpb24gZG9lc24ndCB1c2UgJ2F0dEluZGV4Jy4gV2UgYXJlIGFkZGluZyB0aGUgYXR0cmlidXRlIGxhdGVyCi0gICAgICAgIC8vYWZ0ZXIgd2UgaGF2ZSBmaWd1cmVkIG91dCB0aGF0IGN1cnJlbnQgYXR0cmlidXRlIGlzIG5vdCBuYW1lc3BhY2UgZGVjbGFyYXRpb24KLSAgICAgICAgLy9zaW5jZSBzY2FuQXR0cmlidXRlVmFsdWUgZG9lc24ndCB1c2UgYXR0SW5kZXggcGFyYW1ldGVyIHRoZXJlZm9yZSB3ZQotICAgICAgICAvL2NhbiBzYWZlbHkgYWRkIHRoZSBhdHRyaWJ1dGUgbGF0ZXIuLgotICAgICAgICBYTUxTdHJpbmcgdG1wU3RyID0gZ2V0U3RyaW5nKCk7Ci0KLSAgICAgICAgc2NhbkF0dHJpYnV0ZVZhbHVlKHRtcFN0ciwgZlRlbXBTdHJpbmcyLCBmQXR0cmlidXRlUU5hbWUucmF3bmFtZSwgYXR0cmlidXRlcywKLSAgICAgICAgICAgICAgICBhdHRJbmRleCwgaXNWQywgZkN1cnJlbnRFbGVtZW50LnJhd25hbWUsIGZhbHNlKTsKLQotICAgICAgICAvLyBjb250ZW50Ci0gICAgICAgIGludCBvbGRMZW4gPSBhdHRyaWJ1dGVzLmdldExlbmd0aCgpOwotICAgICAgICAvL2lmIHRoZSBhdHRyaWJ1dGUgbmFtZSBhbHJlYWR5IGV4aXN0cy4uIG5ldyB2YWx1ZSBpcyByZXBsYWNlZCB3aXRoIG9sZCB2YWx1ZQotICAgICAgICBhdHRJbmRleCA9IGF0dHJpYnV0ZXMuYWRkQXR0cmlidXRlKGZBdHRyaWJ1dGVRTmFtZSwgWE1MU3ltYm9scy5mQ0RBVEFTeW1ib2wsIG51bGwpOwotCi0gICAgICAgIC8vIFdGQzogVW5pcXVlIEF0dCBTcGVjCi0gICAgICAgIC8vYXR0cmlidXRlcyBjb3VudCB3aWxsIGJlIHNhbWUgaWYgdGhlIGN1cnJlbnQgYXR0cmlidXRlICBuYW1lIGFscmVhZHkgZXhpc3RzIGZvciB0aGlzIGVsZW1lbnQgbmFtZS4KLSAgICAgICAgLy90aGlzIG1lYW5zIHRoZXJlIGFyZSB0d28gZHVwbGljYXRlIGF0dHJpYnV0ZXMuCi0gICAgICAgIGlmIChvbGRMZW4gPT0gYXR0cmlidXRlcy5nZXRMZW5ndGgoKSkgewotICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiQXR0cmlidXRlTm90VW5pcXVlIiwKLSAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde2ZDdXJyZW50RWxlbWVudC5yYXduYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZBdHRyaWJ1dGVRTmFtZS5yYXduYW1lfSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvL3RtcFN0cmluZyBjb250YWlucyBhdHRyaWJ1dGUgdmFsdWUKLSAgICAgICAgLy93ZSBhcmUgcGFzc2luZyBudWxsIGFzIHRoZSBhdHRyaWJ1dGUgdmFsdWUKLSAgICAgICAgYXR0cmlidXRlcy5zZXRWYWx1ZShhdHRJbmRleCwgbnVsbCwgdG1wU3RyKTsKLQotICAgICAgICAvLy94eHg6IG5vbk5vcm1hbGl6ZWRWYWx1ZSBpcyBub3QgYmVpbmcgc2V0IGFzIGl0IGlzIG5vdCByZXF1aXJlZCBieSBTQVggJiBET00KLSAgICAgICAgLy9hdHRyaWJ1dGVzLnNldE5vbk5vcm1hbGl6ZWRWYWx1ZShvbGRMZW4sIGZUZW1wU3RyaW5nMi50b1N0cmluZygpKTsKLSAgICAgICAgYXR0cmlidXRlcy5zZXRTcGVjaWZpZWQoYXR0SW5kZXgsIHRydWUpOwotCi0gICAgICAgIGlmIChERUJVR19TVEFSVF9FTkRfRUxFTUVOVCkgU3lzdGVtLm91dC5wcmludGxuKHRoaXMuZ2V0Q2xhc3MoKS50b1N0cmluZygpICsiPDw8IHNjYW5BdHRyaWJ1dGUoKSIpOwotCi0gICAgfSAvLyBzY2FuQXR0cmlidXRlKFhNTEF0dHJpYnV0ZXMpCi0KLSAgICAvKioKLSAgICAgKiBTY2FucyBlbGVtZW50IGNvbnRlbnQuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFJldHVybnMgdGhlIG5leHQgY2hhcmFjdGVyIG9uIHRoZSBzdHJlYW0uCi0gICAgICovCi0gICAgLy9DSEFOR0VEOgotICAgIC8vRUFSTElFUjogc2NhbkNvbnRlbnQoKQotICAgIC8vTk9XOiBzY2FuQ29udGVudChYTUxTdHJpbmdCdWZmZXIpCi0gICAgLy9JdCBtYWtlcyB0aGluZ3MgZWFzeSBpZiB0aGlzIGZ1bmN0aW9ucyB0YWtlcyBYTUxTdHJpbmdCdWZmZXIgYXMgcGFyYW1ldGVyLi4KLSAgICAvL3RoaXMgZnVuY3Rpb24gYXBwZW5kcyB0aGUgZGF0YSB0byB0aGUgYnVmZmVyLgotICAgIHByb3RlY3RlZCBpbnQgc2NhbkNvbnRlbnQoWE1MU3RyaW5nQnVmZmVyIGNvbnRlbnQpIHRocm93cyBJT0V4Y2VwdGlvbiwgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgLy9zZXQgdGhlIGZUZW1wU3RyaW5nIGxlbmd0aCB0byAwIGJlZm9yZSBwYXNzaW5nIGl0IG9uIHRvIHNjYW5Db250ZW50Ci0gICAgICAgIC8vc2NhbkNvbnRlbnQgc2V0cyB0aGUgY29ycmVjdCBjby1vcmRpbmF0ZXMgYXMgcGVyIHRoZSBjb250ZW50IHJlYWQKLSAgICAgICAgZlRlbXBTdHJpbmcubGVuZ3RoID0gMDsKLSAgICAgICAgaW50IGMgPSBmRW50aXR5U2Nhbm5lci5zY2FuQ29udGVudChmVGVtcFN0cmluZyk7Ci0gICAgICAgIGNvbnRlbnQuYXBwZW5kKGZUZW1wU3RyaW5nKTsKLSAgICAgICAgZlRlbXBTdHJpbmcubGVuZ3RoID0gMDsKLSAgICAgICAgaWYgKGMgPT0gJ1xyJykgewotICAgICAgICAgICAgLy8gaGFwcGVucyB3aGVuIHRoZXJlIGlzIHRoZSBjaGFyYWN0ZXIgcmVmZXJlbmNlICYjMTM7Ci0gICAgICAgICAgICAvL3h4eDogV2Uga25vdyB0aGUgbmV4dCBjaHJhY3Rlci4uIHdlIHNob3VsZCBqdXN0IHNraXAgaXQgYW5kIGFkZCAnXScgZGlyZWN0bHJ5Ci0gICAgICAgICAgICBmRW50aXR5U2Nhbm5lci5zY2FuQ2hhcihudWxsKTsKLSAgICAgICAgICAgIGNvbnRlbnQuYXBwZW5kKChjaGFyKWMpOwotICAgICAgICAgICAgYyA9IC0xOwotICAgICAgICB9IGVsc2UgaWYgKGMgPT0gJ10nKSB7Ci0gICAgICAgICAgICAvL2ZTdHJpbmdCdWZmZXIuY2xlYXIoKTsKLSAgICAgICAgICAgIC8veHh4OiBXZSBrbm93IHRoZSBuZXh0IGNocmFjdGVyLi4gd2Ugc2hvdWxkIGp1c3Qgc2tpcCBpdCBhbmQgYWRkICddJyBkaXJlY3RscnkKLSAgICAgICAgICAgIGNvbnRlbnQuYXBwZW5kKChjaGFyKWZFbnRpdHlTY2FubmVyLnNjYW5DaGFyKG51bGwpKTsKLSAgICAgICAgICAgIC8vIHJlbWVtYmVyIHdoZXJlIHdlIGFyZSBpbiBjYXNlIHdlIGdldCBhbiBlbmRFbnRpdHkgYmVmb3JlIHdlCi0gICAgICAgICAgICAvLyBjb3VsZCBmbHVzaCB0aGUgYnVmZmVyIG91dCAtIHRoaXMgaGFwcGVucyB3aGVuIHdlJ3JlIHBhcnNpbmcgYW4KLSAgICAgICAgICAgIC8vIGVudGl0eSB3aGljaCBlbmRzIHdpdGggYSBdCi0gICAgICAgICAgICBmSW5TY2FuQ29udGVudCA9IHRydWU7Ci0gICAgICAgICAgICAvLwotICAgICAgICAgICAgLy8gV2Ugd29yayBvbiBhIHNpbmdsZSBjaGFyYWN0ZXIgYmFzaXMgdG8gaGFuZGxlIGNhc2VzIHN1Y2ggYXM6Ci0gICAgICAgICAgICAvLyAnXV1dPicgd2hpY2ggd2UgbWlnaHQgb3RoZXJ3aXNlIG1pc3MuCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgaWYgKGZFbnRpdHlTY2FubmVyLnNraXBDaGFyKCddJywgbnVsbCkpIHsKLSAgICAgICAgICAgICAgICBjb250ZW50LmFwcGVuZCgnXScpOwotICAgICAgICAgICAgICAgIHdoaWxlIChmRW50aXR5U2Nhbm5lci5za2lwQ2hhcignXScsIG51bGwpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGNvbnRlbnQuYXBwZW5kKCddJyk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGlmIChmRW50aXR5U2Nhbm5lci5za2lwQ2hhcignPicsIG51bGwpKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIkNERW5kSW5Db250ZW50IiwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZkluU2NhbkNvbnRlbnQgPSBmYWxzZTsKLSAgICAgICAgICAgIGMgPSAtMTsKLSAgICAgICAgfQotICAgICAgICBpZiAoZkRvY3VtZW50SGFuZGxlciAhPSBudWxsICYmIGNvbnRlbnQubGVuZ3RoID4gMCkgewotICAgICAgICAgICAgLy9mRG9jdW1lbnRIYW5kbGVyLmNoYXJhY3RlcnMoY29udGVudCwgbnVsbCk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGM7Ci0KLSAgICB9IC8vIHNjYW5Db250ZW50KCk6aW50Ci0KLQotICAgIC8qKgotICAgICAqIFNjYW5zIGEgQ0RBVEEgc2VjdGlvbi4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoaXMgbWV0aG9kIHVzZXMgdGhlIGZUZW1wU3RyaW5nIGFuZAotICAgICAqIGZTdHJpbmdCdWZmZXIgdmFyaWFibGVzLgotICAgICAqCi0gICAgICogQHBhcmFtIGNvbXBsZXRlIFRydWUgaWYgdGhlIENEQVRBIHNlY3Rpb24gaXMgdG8gYmUgc2Nhbm5lZAotICAgICAqICAgICAgICAgICAgICAgICBjb21wbGV0ZWx5LgotICAgICAqCi0gICAgICogQHJldHVybiBUcnVlIGlmIENEQVRBIGlzIGNvbXBsZXRlbHkgc2Nhbm5lZC4KLSAgICAgKi8KLSAgICAvL0NIQU5HRUQ6Ci0gICAgcHJvdGVjdGVkIGJvb2xlYW4gc2NhbkNEQVRBU2VjdGlvbihYTUxTdHJpbmdCdWZmZXIgY29udGVudEJ1ZmZlciwgYm9vbGVhbiBjb21wbGV0ZSkKLSAgICB0aHJvd3MgSU9FeGNlcHRpb24sIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy8gY2FsbCBoYW5kbGVyCi0gICAgICAgIGlmIChmRG9jdW1lbnRIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIC8vZkRvY3VtZW50SGFuZGxlci5zdGFydENEQVRBKG51bGwpOwotICAgICAgICB9Ci0KLSAgICAgICAgd2hpbGUgKHRydWUpIHsKLSAgICAgICAgICAgIC8vc2NhbkRhdGEgd2lsbCBmaWxsIHRoZSBjb250ZW50QnVmZmVyCi0gICAgICAgICAgICBpZiAoIWZFbnRpdHlTY2FubmVyLnNjYW5EYXRhKCJdXT4iLCBjb250ZW50QnVmZmVyKSkgewotICAgICAgICAgICAgICAgIGJyZWFrIDsKLSAgICAgICAgICAgICAgICAvKiogV2UgZG9udCBuZWVkIGFsbCB0aGlzIGNvZGUgaWYgd2UgcGFzcyAnXV0+JyBhcyBkZWxpbWV0ZXIuLgotICAgICAgICAgICAgICAgICAqIGludCBicmFja2V0cyA9IDI7Ci0gICAgICAgICAgICAgICAgICogd2hpbGUgKGZFbnRpdHlTY2FubmVyLnNraXBDaGFyKCddJykpIHsKLSAgICAgICAgICAgICAgICAgKiBicmFja2V0cysrOwotICAgICAgICAgICAgICAgICAqIH0KLSAgICAgICAgICAgICAgICAgKgotICAgICAgICAgICAgICAgICAqIC8vV2hlbiB3ZSBmaW5kIG1vcmUgdGhhbiAyIHNxdWFyZSBicmFja2V0cwotICAgICAgICAgICAgICAgICAqIGlmIChmRG9jdW1lbnRIYW5kbGVyICE9IG51bGwgJiYgYnJhY2tldHMgPiAyKSB7Ci0gICAgICAgICAgICAgICAgICogLy93ZSBkb250IG5lZWQgdG8gY2xlYXIgdGhlIGJ1ZmZlci4uCi0gICAgICAgICAgICAgICAgICogLy9jb250ZW50QnVmZmVyLmNsZWFyKCk7Ci0gICAgICAgICAgICAgICAgICogZm9yIChpbnQgaSA9IDI7IGkgPCBicmFja2V0czsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgICogY29udGVudEJ1ZmZlci5hcHBlbmQoJ10nKTsKLSAgICAgICAgICAgICAgICAgKiB9Ci0gICAgICAgICAgICAgICAgICogZkRvY3VtZW50SGFuZGxlci5jaGFyYWN0ZXJzKGNvbnRlbnRCdWZmZXIsIG51bGwpOwotICAgICAgICAgICAgICAgICAqIH0KLSAgICAgICAgICAgICAgICAgKgotICAgICAgICAgICAgICAgICAqIGlmIChmRW50aXR5U2Nhbm5lci5za2lwQ2hhcignPicpKSB7Ci0gICAgICAgICAgICAgICAgICogYnJlYWs7Ci0gICAgICAgICAgICAgICAgICogfQotICAgICAgICAgICAgICAgICAqIGlmIChmRG9jdW1lbnRIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgKiAvL3dlIGRvbnQgbmVlZCB0byBjbGVhciB0aGUgYnVmZmVyIG5vdy4uCi0gICAgICAgICAgICAgICAgICogLy9jb250ZW50QnVmZmVyLmNsZWFyKCk7Ci0gICAgICAgICAgICAgICAgICogY29udGVudEJ1ZmZlci5hcHBlbmQoIl1dIik7Ci0gICAgICAgICAgICAgICAgICogZkRvY3VtZW50SGFuZGxlci5jaGFyYWN0ZXJzKGNvbnRlbnRCdWZmZXIsIG51bGwpOwotICAgICAgICAgICAgICAgICAqIH0KLSAgICAgICAgICAgICAgICAgKiovCi0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIGludCBjID0gZkVudGl0eVNjYW5uZXIucGVla0NoYXIoKTsKLSAgICAgICAgICAgICAgICBpZiAoYyAhPSAtMSAmJiBpc0ludmFsaWRMaXRlcmFsKGMpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChYTUxDaGFyLmlzSGlnaFN1cnJvZ2F0ZShjKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgLy9jb250ZW50QnVmZmVyLmNsZWFyKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvL3NjYW4gc3Vycm9nYXRlcyBpZiBhbnkuLi4uCi0gICAgICAgICAgICAgICAgICAgICAgICBzY2FuU3Vycm9nYXRlcyhjb250ZW50QnVmZmVyKTsKLSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIkludmFsaWRDaGFySW5DRFNlY3QiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117SW50ZWdlci50b1N0cmluZyhjLDE2KX0pOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmRW50aXR5U2Nhbm5lci5zY2FuQ2hhcihudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvL2J5IHRoaXMgdGltZSB3ZSBoYXZlIGFsc28gcmVhZCBzdXJyb2dhdGUgY29udGVudHMgaWYgYW55Li4uCi0gICAgICAgICAgICAgICAgaWYgKGZEb2N1bWVudEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAvL2ZEb2N1bWVudEhhbmRsZXIuY2hhcmFjdGVycyhjb250ZW50QnVmZmVyLCBudWxsKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZk1hcmt1cERlcHRoLS07Ci0KLSAgICAgICAgaWYgKGZEb2N1bWVudEhhbmRsZXIgIT0gbnVsbCAmJiBjb250ZW50QnVmZmVyLmxlbmd0aCA+IDApIHsKLSAgICAgICAgICAgIC8vZkRvY3VtZW50SGFuZGxlci5jaGFyYWN0ZXJzKGNvbnRlbnRCdWZmZXIsIG51bGwpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gY2FsbCBoYW5kbGVyCi0gICAgICAgIGlmIChmRG9jdW1lbnRIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIC8vZkRvY3VtZW50SGFuZGxlci5lbmRDREFUQShudWxsKTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiB0cnVlOwotCi0gICAgfSAvLyBzY2FuQ0RBVEFTZWN0aW9uKFhNTFN0cmluZ0J1ZmZlciwgYm9vbGVhbik6Ym9vbGVhbgotCi0gICAgLyoqCi0gICAgICogU2NhbnMgYW4gZW5kIGVsZW1lbnQuCi0gICAgICogPHA+Ci0gICAgICogPHByZT4KLSAgICAgKiBbNDJdIEVUYWcgOjo9ICcmbHQ7LycgTmFtZSBTPyAnPicKLSAgICAgKiA8L3ByZT4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoaXMgbWV0aG9kIHVzZXMgdGhlIGZFbGVtZW50UU5hbWUgdmFyaWFibGUuCi0gICAgICogVGhlIGNvbnRlbnRzIG9mIHRoaXMgdmFyaWFibGUgd2lsbCBiZSBkZXN0cm95ZWQuIFRoZSBjYWxsZXIgc2hvdWxkCi0gICAgICogY29weSB0aGUgbmVlZGVkIGluZm9ybWF0aW9uIG91dCBvZiB0aGlzIHZhcmlhYmxlIGJlZm9yZSBjYWxsaW5nCi0gICAgICogdGhpcyBtZXRob2QuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBlbGVtZW50IGRlcHRoLgotICAgICAqLwotICAgIHByb3RlY3RlZCBpbnQgc2NhbkVuZEVsZW1lbnQoKSB0aHJvd3MgSU9FeGNlcHRpb24sIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChERUJVR19TVEFSVF9FTkRfRUxFTUVOVCkgU3lzdGVtLm91dC5wcmludGxuKHRoaXMuZ2V0Q2xhc3MoKS50b1N0cmluZygpICsiPj4+IHNjYW5FbmRFbGVtZW50KCkiKTsKLQotICAgICAgICAvLyBwb3AgY29udGV4dAotICAgICAgICBRTmFtZSBlbmRFbGVtZW50TmFtZSA9IGZFbGVtZW50U3RhY2sucG9wRWxlbWVudCgpOwotCi0gICAgICAgIFN0cmluZyByYXduYW1lID0gZW5kRWxlbWVudE5hbWUucmF3bmFtZTsKLSAgICAgICAgaWYoREVCVUcpU3lzdGVtLm91dC5wcmludGxuKCJlbmRFbGVtZW50TmFtZSA9ICIgKyBlbmRFbGVtZW50TmFtZS50b1N0cmluZygpKTsKLSAgICAgICAgLy8gVGFrZSBhZHZhbnRhZ2Ugb2YgdGhlIGZhY3QgdGhhdCBuZXh0IHN0cmluZyBfc2hvdWxkXyBiZSAiZkVsZW1lbnRRTmFtZS5yYXdOYW1lIiwKLSAgICAgICAgLy9JbiBzY2FubmVycyBtb3N0IG9mIHRoZSB0aW1lIGlzIGNvbnN1bWVkIG9uIGNoZWNrcyBkb25lIGZvciBYTUwgY2hhcmFjdGVycywgd2UgY2FuCi0gICAgICAgIC8vIG9wdGltaXplIG9uIGl0IGFuZCBhdm9pZCB0aGUgY2hlY2tzIGRvbmUgZm9yIGVuZEVsZW1lbnQsCi0gICAgICAgIC8vd2Ugd2lsbCBhbHNvIGF2b2lkIHN5bWJvbCB0YWJsZSBsb29rdXAgLSBuZWVyYWouYmFqYWpAc3VuLmNvbQotCi0gICAgICAgIC8vIHRoaXMgc2hvdWxkIHdvcmsgYm90aCBmb3IgbmFtZXNwYWNlIHByb2Nlc3NpbmcgdHJ1ZSBvciBmYWxzZS4uLgotCi0gICAgICAgIC8vUkVWSVNJVDogaWYgdGhlIHN0cmluZyBpcyBub3QgdGhlIHNhbWUgYXMgZXhwZWN0ZWQuLiB3ZSBuZWVkIHRvIGRvIGJldHRlciBlcnJvciBoYW5kbGluZy4uCi0gICAgICAgIC8vV2UgY2FuIHNraXAgdGhpcyBmb3Igbm93Li4uIEluIGFueSBjYXNlIGlmIHRoZSBzdHJpbmcgZG9lc24ndCBtYXRjaCAtLSBkb2N1bWVudCBpcyBub3Qgd2VsbCBmb3JtZWQuCi0KLSAgICAgICAgaWYgKCFmRW50aXR5U2Nhbm5lci5za2lwU3RyaW5nKGVuZEVsZW1lbnROYW1lLnJhd25hbWUpKSB7Ci0gICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiRVRhZ1JlcXVpcmVkIiwgbmV3IE9iamVjdFtde3Jhd25hbWV9KTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIGVuZAotICAgICAgICBmRW50aXR5U2Nhbm5lci5za2lwU3BhY2VzKCk7Ci0gICAgICAgIGlmICghZkVudGl0eVNjYW5uZXIuc2tpcENoYXIoJz4nLCBOYW1lVHlwZS5FTEVNRU5URU5EKSkgewotICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiRVRhZ1VudGVybWluYXRlZCIsCi0gICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXtyYXduYW1lfSk7Ci0gICAgICAgIH0KLSAgICAgICAgZk1hcmt1cERlcHRoLS07Ci0KLSAgICAgICAgLy93ZSBoYXZlIGluY3JlYXNlZCB0aGUgZGVwdGggZm9yIHR3byBtYXJrdXAgIjwiIGNoYXJhY3RlcnMKLSAgICAgICAgZk1hcmt1cERlcHRoLS07Ci0KLSAgICAgICAgLy8gY2hlY2sgdGhhdCB0aGlzIGVsZW1lbnQgd2FzIG9wZW5lZCBpbiB0aGUgc2FtZSBlbnRpdHkKLSAgICAgICAgaWYgKGZNYXJrdXBEZXB0aCA8IGZFbnRpdHlTdGFja1tmRW50aXR5RGVwdGggLSAxXSkgewotICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiRWxlbWVudEVudGl0eU1pc21hdGNoIiwKLSAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde3Jhd25hbWV9KTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vV2Ugc2hvdWxkIG5vdCBiZSBwb3BwaW5nIG91dCB0aGUgY29udGV4dCBoZXJlIGluIGVuZEVMZW1lbnQgYmVjYWF1c2UgdGhlIG5hbWVzcGFjZSBjb250ZXh0IGlzIHN0aWxsCi0gICAgICAgIC8vdmFsaWQgd2hlbiBwYXJzZXIgaXMgYXQgdGhlIGVuZEVsZW1lbnQgc3RhdGUuCi0KLSAgICAgICAgLy9pZiAoZk5hbWVzcGFjZXMpIHsKLSAgICAgICAgLy8gIGZOYW1lc3BhY2VDb250ZXh0LnBvcENvbnRleHQoKTsKLSAgICAgICAgLy99Ci0KLSAgICAgICAgLy8gY2FsbCBoYW5kbGVyCi0gICAgICAgIGlmIChmRG9jdW1lbnRIYW5kbGVyICE9IG51bGwgKSB7Ci0gICAgICAgICAgICAvL2VuZCBlbGVtZW50IGlzIHNjYW5uZWQgaW4gdGhpcyBmdW5jdGlvbiBzbyB3ZSBjYW4gc2VuZCBhIGNhbGxiYWNrCi0gICAgICAgICAgICAvL2hlcmUuCi0gICAgICAgICAgICAvLzxzdHJvbmc+d2Ugc2hvdWxkbid0IGJlIHNlbmRpbmcgY2FsbGJhY2sgaW4gc2NhbkRvY3VtZW50KCk8L3N0cm9uZz4KLQotICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci5lbmRFbGVtZW50KGVuZEVsZW1lbnROYW1lLCBudWxsKTsKLSAgICAgICAgfQotICAgICAgICBpZihkdGRHcmFtbWFyVXRpbCAhPSBudWxsKQotICAgICAgICAgICAgZHRkR3JhbW1hclV0aWwuZW5kRWxlbWVudChlbmRFbGVtZW50TmFtZSk7Ci0KLSAgICAgICAgcmV0dXJuIGZNYXJrdXBEZXB0aDsKLQotICAgIH0gLy8gc2NhbkVuZEVsZW1lbnQoKTppbnQKLQotICAgIC8qKgotICAgICAqIFNjYW5zIGEgY2hhcmFjdGVyIHJlZmVyZW5jZS4KLSAgICAgKiA8cD4KLSAgICAgKiA8cHJlPgotICAgICAqIFs2Nl0gQ2hhclJlZiA6Oj0gJyYjJyBbMC05XSsgJzsnIHwgJyYjeCcgWzAtOWEtZkEtRl0rICc7JwotICAgICAqIDwvcHJlPgotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIHNjYW5DaGFyUmVmZXJlbmNlKCkKLSAgICB0aHJvd3MgSU9FeGNlcHRpb24sIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgZlN0cmluZ0J1ZmZlcjIuY2xlYXIoKTsKLSAgICAgICAgaW50IGNoID0gc2NhbkNoYXJSZWZlcmVuY2VWYWx1ZShmU3RyaW5nQnVmZmVyMiwgbnVsbCk7Ci0gICAgICAgIGZNYXJrdXBEZXB0aC0tOwotICAgICAgICBpZiAoY2ggIT0gLTEpIHsKLSAgICAgICAgICAgIC8vIGNhbGwgaGFuZGxlcgotCi0gICAgICAgICAgICBpZiAoZkRvY3VtZW50SGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGZOb3RpZnlDaGFyUmVmcykgewotICAgICAgICAgICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLnN0YXJ0R2VuZXJhbEVudGl0eShmQ2hhclJlZkxpdGVyYWwsIG51bGwsIG51bGwsIG51bGwpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBBdWdtZW50YXRpb25zIGF1Z3MgPSBudWxsOwotICAgICAgICAgICAgICAgIGlmIChmVmFsaWRhdGlvbiAmJiBjaCA8PSAweDIwKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChmVGVtcEF1Z21lbnRhdGlvbnMgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgZlRlbXBBdWdtZW50YXRpb25zLnJlbW92ZUFsbEl0ZW1zKCk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmVGVtcEF1Z21lbnRhdGlvbnMgPSBuZXcgQXVnbWVudGF0aW9uc0ltcGwoKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBhdWdzID0gZlRlbXBBdWdtZW50YXRpb25zOwotICAgICAgICAgICAgICAgICAgICBhdWdzLnB1dEl0ZW0oQ29uc3RhbnRzLkNIQVJfUkVGX1BST0JBQkxFX1dTLCBCb29sZWFuLlRSVUUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvL3h4eDogSG93IGRvIHdlIGRlYWwgd2l0aCB0aGlzIC0gaG93IHRvIHJldHVybiBjaGFyUmVmZXJlbmNlVmFsdWVzCi0gICAgICAgICAgICAgICAgLy9ub3cgdGhpcyBpcyBiZWluZyBjb21tZW50ZWQgYmVjYXVzZSB0aGlzIGlzIHRha2VuIGNhcmUgaW4gc2NhbkRvY3VtZW50KCkKLSAgICAgICAgICAgICAgICAvL2ZEb2N1bWVudEhhbmRsZXIuY2hhcmFjdGVycyhmU3RyaW5nQnVmZmVyMiwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgaWYgKGZOb3RpZnlDaGFyUmVmcykgewotICAgICAgICAgICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLmVuZEdlbmVyYWxFbnRpdHkoZkNoYXJSZWZMaXRlcmFsLCBudWxsKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgIH0gLy8gc2NhbkNoYXJSZWZlcmVuY2UoKQotCi0KLSAgICAvKioKLSAgICAgKiBTY2FucyBhbiBlbnRpdHkgcmVmZXJlbmNlLgotICAgICAqCi0gICAgICogQHJldHVybiByZXR1cm5zIHRydWUgaWYgdGhlIG5ldyBlbnRpdHkgaXMgc3RhcnRlZC4gSWYgaXQgd2FzIGJ1aWx0LWluIGVudGl0eQotICAgICAqICAgICAgICAgJ2ZhbHNlJyBpcyByZXR1cm5lZC4KLSAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uICBUaHJvd24gaWYgaS9vIGVycm9yIG9jY3Vycy4KLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gaWYgaGFuZGxlciB0aHJvd3MgZXhjZXB0aW9uIHVwb24KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBub3RpZmljYXRpb24uCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgc2NhbkVudGl0eVJlZmVyZW5jZShYTUxTdHJpbmdCdWZmZXIgY29udGVudCkgdGhyb3dzIElPRXhjZXB0aW9uLCBYTklFeGNlcHRpb24gewotICAgICAgICBTdHJpbmcgbmFtZSA9IGZFbnRpdHlTY2FubmVyLnNjYW5OYW1lKE5hbWVUeXBlLlJFRkVSRU5DRSk7Ci0gICAgICAgIGlmIChuYW1lID09IG51bGwpIHsKLSAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIk5hbWVSZXF1aXJlZEluUmVmZXJlbmNlIiwgbnVsbCk7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKCFmRW50aXR5U2Nhbm5lci5za2lwQ2hhcignOycsIE5hbWVUeXBlLlJFRkVSRU5DRSkpIHsKLSAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIlNlbWljb2xvblJlcXVpcmVkSW5SZWZlcmVuY2UiLCBuZXcgT2JqZWN0IFtde25hbWV9KTsKLSAgICAgICAgfQotICAgICAgICBpZiAoZkVudGl0eVN0b3JlLmlzVW5wYXJzZWRFbnRpdHkobmFtZSkpIHsKLSAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIlJlZmVyZW5jZVRvVW5wYXJzZWRFbnRpdHkiLCBuZXcgT2JqZWN0W117bmFtZX0pOwotICAgICAgICB9Ci0gICAgICAgIGZNYXJrdXBEZXB0aC0tOwotICAgICAgICBmQ3VycmVudEVudGl0eU5hbWUgPSBuYW1lOwotCi0gICAgICAgIC8vIGhhbmRsZSBidWlsdC1pbiBlbnRpdGllcwotICAgICAgICBpZiAobmFtZSA9PSBmQW1wU3ltYm9sKSB7Ci0gICAgICAgICAgICBoYW5kbGVDaGFyYWN0ZXIoJyYnLCBmQW1wU3ltYm9sLCBjb250ZW50KTsKLSAgICAgICAgICAgIGZTY2FubmVyU3RhdGUgPSBTQ0FOTkVSX1NUQVRFX0JVSUxUX0lOX1JFRlM7Ci0gICAgICAgICAgICByZXR1cm4gOwotICAgICAgICB9IGVsc2UgaWYgKG5hbWUgPT0gZkx0U3ltYm9sKSB7Ci0gICAgICAgICAgICBoYW5kbGVDaGFyYWN0ZXIoJzwnLCBmTHRTeW1ib2wsIGNvbnRlbnQpOwotICAgICAgICAgICAgZlNjYW5uZXJTdGF0ZSA9IFNDQU5ORVJfU1RBVEVfQlVJTFRfSU5fUkVGUzsKLSAgICAgICAgICAgIHJldHVybiA7Ci0gICAgICAgIH0gZWxzZSBpZiAobmFtZSA9PSBmR3RTeW1ib2wpIHsKLSAgICAgICAgICAgIGhhbmRsZUNoYXJhY3RlcignPicsIGZHdFN5bWJvbCwgY29udGVudCk7Ci0gICAgICAgICAgICBmU2Nhbm5lclN0YXRlID0gU0NBTk5FUl9TVEFURV9CVUlMVF9JTl9SRUZTOwotICAgICAgICAgICAgcmV0dXJuIDsKLSAgICAgICAgfSBlbHNlIGlmIChuYW1lID09IGZRdW90U3ltYm9sKSB7Ci0gICAgICAgICAgICBoYW5kbGVDaGFyYWN0ZXIoJyInLCBmUXVvdFN5bWJvbCwgY29udGVudCk7Ci0gICAgICAgICAgICBmU2Nhbm5lclN0YXRlID0gU0NBTk5FUl9TVEFURV9CVUlMVF9JTl9SRUZTOwotICAgICAgICAgICAgcmV0dXJuIDsKLSAgICAgICAgfSBlbHNlIGlmIChuYW1lID09IGZBcG9zU3ltYm9sKSB7Ci0gICAgICAgICAgICBoYW5kbGVDaGFyYWN0ZXIoJ1wnJywgZkFwb3NTeW1ib2wsIGNvbnRlbnQpOwotICAgICAgICAgICAgZlNjYW5uZXJTdGF0ZSA9IFNDQU5ORVJfU1RBVEVfQlVJTFRfSU5fUkVGUzsKLSAgICAgICAgICAgIHJldHVybiA7Ci0gICAgICAgIH0KLQotICAgICAgICAvLzEuIGlmIHRoZSBlbnRpdHkgaXMgZXh0ZXJuYWwgYW5kIHN1cHBvcnQgdG8gZXh0ZXJuYWwgZW50aXRpZXMgaXMgbm90IHJlcXVpcmVkCi0gICAgICAgIC8vIDIuIG9yIGVudGl0aWVzIHNob3VsZCBub3QgYmUgcmVwbGFjZWQKLSAgICAgICAgLy8zLiBvciBpZiBpdCBpcyBidWlsdCBpbiBlbnRpdHkgcmVmZXJlbmNlLgotICAgICAgICBib29sZWFuIGlzRUUgPSBmRW50aXR5U3RvcmUuaXNFeHRlcm5hbEVudGl0eShuYW1lKTsKLSAgICAgICAgaWYoKGlzRUUgJiYgIWZTdXBwb3J0RXh0ZXJuYWxFbnRpdGllcykgfHwgKCFpc0VFICYmICFmUmVwbGFjZUVudGl0eVJlZmVyZW5jZXMpIHx8IGZvdW5kQnVpbHRJblJlZnMpewotICAgICAgICAgICAgZlNjYW5uZXJTdGF0ZSA9IFNDQU5ORVJfU1RBVEVfUkVGRVJFTkNFOwotICAgICAgICAgICAgcmV0dXJuIDsKLSAgICAgICAgfQotICAgICAgICAvLyBzdGFydCBnZW5lcmFsIGVudGl0eQotICAgICAgICBpZiAoIWZFbnRpdHlTdG9yZS5pc0RlY2xhcmVkRW50aXR5KG5hbWUpKSB7Ci0gICAgICAgICAgICAvL1NVUFBPUlRfRFREPWZhbHNlICYmIFJlcGxhY2VFbnRpdHlSZWZlcmVuY2VzIHNob3VsZCB0aHJvdyBleGNlcHRpb24KLSAgICAgICAgICAgIGlmICghZlN1cHBvcnREVEQgJiYgZlJlcGxhY2VFbnRpdHlSZWZlcmVuY2VzKSB7Ci0gICAgICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiRW50aXR5Tm90RGVjbGFyZWQiLCBuZXcgT2JqZWN0W117bmFtZX0pOwotICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vUkVWSVNJVDogb25lIG1vcmUgY2FzZSBuZWVkcyB0byBiZSBpbmNsdWRlZDogZXh0ZXJuYWwgUEUgYW5kIHN0YW5kYWxvbmUgaXMgbm8KLSAgICAgICAgICAgIGlmICggZkhhc0V4dGVybmFsRFREICYmICFmU3RhbmRhbG9uZSkgewotICAgICAgICAgICAgICAgIGlmIChmVmFsaWRhdGlvbikKLSAgICAgICAgICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IoZkVudGl0eVNjYW5uZXIsIFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwiRW50aXR5Tm90RGVjbGFyZWQiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXtuYW1lfSwgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9FUlJPUik7Ci0gICAgICAgICAgICB9IGVsc2UKLSAgICAgICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJFbnRpdHlOb3REZWNsYXJlZCIsIG5ldyBPYmplY3RbXXtuYW1lfSk7Ci0gICAgICAgIH0KLSAgICAgICAgLy93ZSBhcmUgc3RhcnRpbmcgdGhlIGVudGl0eSBldmVuIGlmIHRoZSBlbnRpdHkgd2FzIG5vdCBkZWNsYXJlZAotICAgICAgICAvL2lmIHRoYXQgd2FzIHRoZSBjYXNlIGl0IGl0cyB0YWtlbiBjYXJlIGluIFhNTEVudGl0eU1hbmFnZXIuc3RhcnRFbnRpdHkoKQotICAgICAgICAvL3dlIGltbWVkaWF0ZWx5IGNhbGwgdGhlIGVuZEVudGl0eS4gQXBwbGljYXRpb24gZ2V0cyB0byBrbm93IGlmIHRoZXJlIHdhcwotICAgICAgICAvL2FueSBlbnRpdHkgdGhhdCB3YXMgbm90IGRlY2xhcmVkLgotICAgICAgICBmRW50aXR5TWFuYWdlci5zdGFydEVudGl0eSh0cnVlLCBuYW1lLCBmYWxzZSk7Ci0gICAgICAgIC8vc2V0IHRoZSBzY2FuZXIgc3RhdGUgdG8gY29udGVudC4uIHBhcnNlciB3aWxsIGF1dG9tYXRpY2FsbHkgcmV2aXZlIGl0c2VsZiBhdCBhbnkgcG9pbnQgb2YgdGltZS4KLSAgICAgICAgLy9zZXRTY2FubmVyU3RhdGUoU0NBTk5FUl9TVEFURV9DT05URU5UKTsKLSAgICAgICAgLy9yZXR1cm4gdHJ1ZSA7Ci0gICAgfSAvLyBzY2FuRW50aXR5UmVmZXJlbmNlKCkKLQotICAgIC8vIHV0aWxpdHkgbWV0aG9kcwotCi0gICAgLyoqCi0gICAgICogQ2hlY2sgaWYgdGhlIGRlcHRoIGV4Y2VlZHMgdGhlIG1heEVsZW1lbnREZXB0aCBsaW1pdAotICAgICAqIEBwYXJhbSBlbGVtZW50TmFtZSBuYW1lIG9mIHRoZSBjdXJyZW50IGVsZW1lbnQKLSAgICAgKi8KLSAgICB2b2lkIGNoZWNrRGVwdGgoU3RyaW5nIGVsZW1lbnROYW1lKSB7Ci0gICAgICAgIGZMaW1pdEFuYWx5emVyLmFkZFZhbHVlKExpbWl0Lk1BWF9FTEVNRU5UX0RFUFRIX0xJTUlULCBlbGVtZW50TmFtZSwgZkVsZW1lbnRTdGFjay5mRGVwdGgpOwotICAgICAgICBpZiAoZlNlY3VyaXR5TWFuYWdlci5pc092ZXJMaW1pdChMaW1pdC5NQVhfRUxFTUVOVF9ERVBUSF9MSU1JVCxmTGltaXRBbmFseXplcikpIHsKLSAgICAgICAgICAgIGZTZWN1cml0eU1hbmFnZXIuZGVidWdQcmludChmTGltaXRBbmFseXplcik7Ci0gICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJNYXhFbGVtZW50RGVwdGhMaW1pdCIsIG5ldyBPYmplY3RbXXtlbGVtZW50TmFtZSwKLSAgICAgICAgICAgICAgICBmTGltaXRBbmFseXplci5nZXRUb3RhbFZhbHVlKExpbWl0Lk1BWF9FTEVNRU5UX0RFUFRIX0xJTUlUKSwKLSAgICAgICAgICAgICAgICBmU2VjdXJpdHlNYW5hZ2VyLmdldExpbWl0KExpbWl0Lk1BWF9FTEVNRU5UX0RFUFRIX0xJTUlUKSwKLSAgICAgICAgICAgICAgICAibWF4RWxlbWVudERlcHRoIn0pOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ2FsbHMgZG9jdW1lbnQgaGFuZGxlciB3aXRoIGEgc2luZ2xlIGNoYXJhY3RlciByZXN1bHRpbmcgZnJvbQotICAgICAqIGJ1aWx0LWluIGVudGl0eSByZXNvbHV0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIGMKLSAgICAgKiBAcGFyYW0gZW50aXR5IGJ1aWx0LWluIG5hbWUKLSAgICAgKiBAcGFyYW0gWE1MU3RyaW5nQnVmZmVyIGFwcGVuZCB0aGUgY2hhcmFjdGVyIHRvIGJ1ZmZlcgotICAgICAqCi0gICAgICogd2UgcmVhbGx5IGRvbnQgbmVlZCB0byBjYWxsIHRoaXMgZnVuY3Rpb24gLS0gdGhpcyBmdW5jdGlvbiBpcyBvbmx5IHJlcXVpcmVkIHdoZW4KLSAgICAgKiB3ZSBpbnRlZ3JhdGUgd2l0aCByZXN0IG9mIFhlcmNlczIuIFNPIG1haW50YWluaW5nIHRoZSBjdXJyZW50IGJlaGF2aW9yIGFuZCBzdGlsbAotICAgICAqIGNhbGxpbmcgdGhpcyBmdW5jdGlvbiB0byBoYW5sZGUgYnVpbHQtaW4gZW50aXR5IHJlZmVyZW5jZS4KLSAgICAgKgotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCBoYW5kbGVDaGFyYWN0ZXIoY2hhciBjLCBTdHJpbmcgZW50aXR5LCBYTUxTdHJpbmdCdWZmZXIgY29udGVudCkgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIGZvdW5kQnVpbHRJblJlZnMgPSB0cnVlOwotICAgICAgICBjaGVja0VudGl0eUxpbWl0KGZhbHNlLCBmRW50aXR5U2Nhbm5lci5mQ3VycmVudEVudGl0eS5uYW1lLCAxKTsKLSAgICAgICAgY29udGVudC5hcHBlbmQoYyk7Ci0gICAgICAgIGlmIChmRG9jdW1lbnRIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZTaW5nbGVDaGFyWzBdID0gYzsKLSAgICAgICAgICAgIGlmIChmTm90aWZ5QnVpbHRJblJlZnMpIHsKLSAgICAgICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLnN0YXJ0R2VuZXJhbEVudGl0eShlbnRpdHksIG51bGwsIG51bGwsIG51bGwpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZlRlbXBTdHJpbmcuc2V0VmFsdWVzKGZTaW5nbGVDaGFyLCAwLCAxKTsKLSAgICAgICAgICAgIC8vZkRvY3VtZW50SGFuZGxlci5jaGFyYWN0ZXJzKGZUZW1wU3RyaW5nLCBudWxsKTsKLQotICAgICAgICAgICAgaWYgKGZOb3RpZnlCdWlsdEluUmVmcykgewotICAgICAgICAgICAgICAgIGZEb2N1bWVudEhhbmRsZXIuZW5kR2VuZXJhbEVudGl0eShlbnRpdHksIG51bGwpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfSAvLyBoYW5kbGVDaGFyYWN0ZXIoY2hhcikKLQotICAgIC8vIGhlbHBlciBtZXRob2RzCi0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSBzY2FubmVyIHN0YXRlLgotICAgICAqCi0gICAgICogQHBhcmFtIHN0YXRlIFRoZSBuZXcgc2Nhbm5lciBzdGF0ZS4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgZmluYWwgdm9pZCBzZXRTY2FubmVyU3RhdGUoaW50IHN0YXRlKSB7Ci0KLSAgICAgICAgZlNjYW5uZXJTdGF0ZSA9IHN0YXRlOwotICAgICAgICBpZiAoREVCVUdfU0NBTk5FUl9TVEFURSkgewotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiIyMjIHNldFNjYW5uZXJTdGF0ZTogIik7Ci0gICAgICAgICAgICAvL1N5c3RlbS5vdXQucHJpbnQoZlNjYW5uZXJTdGF0ZSk7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KGdldFNjYW5uZXJTdGF0ZU5hbWUoc3RhdGUpKTsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigpOwotICAgICAgICB9Ci0KLSAgICB9IC8vIHNldFNjYW5uZXJTdGF0ZShpbnQpCi0KLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIERyaXZlci4KLSAgICAgKgotICAgICAqIEBwYXJhbSBEcml2ZXIgVGhlIG5ldyBEcml2ZXIuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGZpbmFsIHZvaWQgc2V0RHJpdmVyKERyaXZlciBkcml2ZXIpIHsKLSAgICAgICAgZkRyaXZlciA9IGRyaXZlcjsKLSAgICAgICAgaWYgKERFQlVHX0RJU1BBVENIRVIpIHsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIiUlJSBzZXREcml2ZXI6ICIpOwotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludChnZXREcml2ZXJOYW1lKGRyaXZlcikpOwotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvLwotICAgIC8vIFByaXZhdGUgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKiogUmV0dXJucyB0aGUgc2Nhbm5lciBzdGF0ZSBuYW1lLiAqLwotICAgIHByb3RlY3RlZCBTdHJpbmcgZ2V0U2Nhbm5lclN0YXRlTmFtZShpbnQgc3RhdGUpIHsKLQotICAgICAgICBzd2l0Y2ggKHN0YXRlKSB7Ci0gICAgICAgICAgICBjYXNlIFNDQU5ORVJfU1RBVEVfRE9DVFlQRTogcmV0dXJuICJTQ0FOTkVSX1NUQVRFX0RPQ1RZUEUiOwotICAgICAgICAgICAgY2FzZSBTQ0FOTkVSX1NUQVRFX1JPT1RfRUxFTUVOVDogcmV0dXJuICJTQ0FOTkVSX1NUQVRFX1JPT1RfRUxFTUVOVCI7Ci0gICAgICAgICAgICBjYXNlIFNDQU5ORVJfU1RBVEVfU1RBUlRfT0ZfTUFSS1VQOiByZXR1cm4gIlNDQU5ORVJfU1RBVEVfU1RBUlRfT0ZfTUFSS1VQIjsKLSAgICAgICAgICAgIGNhc2UgU0NBTk5FUl9TVEFURV9DT01NRU5UOiByZXR1cm4gIlNDQU5ORVJfU1RBVEVfQ09NTUVOVCI7Ci0gICAgICAgICAgICBjYXNlIFNDQU5ORVJfU1RBVEVfUEk6IHJldHVybiAiU0NBTk5FUl9TVEFURV9QSSI7Ci0gICAgICAgICAgICBjYXNlIFNDQU5ORVJfU1RBVEVfQ09OVEVOVDogcmV0dXJuICJTQ0FOTkVSX1NUQVRFX0NPTlRFTlQiOwotICAgICAgICAgICAgY2FzZSBTQ0FOTkVSX1NUQVRFX1JFRkVSRU5DRTogcmV0dXJuICJTQ0FOTkVSX1NUQVRFX1JFRkVSRU5DRSI7Ci0gICAgICAgICAgICBjYXNlIFNDQU5ORVJfU1RBVEVfRU5EX09GX0lOUFVUOiByZXR1cm4gIlNDQU5ORVJfU1RBVEVfRU5EX09GX0lOUFVUIjsKLSAgICAgICAgICAgIGNhc2UgU0NBTk5FUl9TVEFURV9URVJNSU5BVEVEOiByZXR1cm4gIlNDQU5ORVJfU1RBVEVfVEVSTUlOQVRFRCI7Ci0gICAgICAgICAgICBjYXNlIFNDQU5ORVJfU1RBVEVfQ0RBVEE6IHJldHVybiAiU0NBTk5FUl9TVEFURV9DREFUQSI7Ci0gICAgICAgICAgICBjYXNlIFNDQU5ORVJfU1RBVEVfVEVYVF9ERUNMOiByZXR1cm4gIlNDQU5ORVJfU1RBVEVfVEVYVF9ERUNMIjsKLSAgICAgICAgICAgIGNhc2UgU0NBTk5FUl9TVEFURV9BVFRSSUJVVEU6IHJldHVybiAiU0NBTk5FUl9TVEFURV9BVFRSSUJVVEUiOwotICAgICAgICAgICAgY2FzZSBTQ0FOTkVSX1NUQVRFX0FUVFJJQlVURV9WQUxVRTogcmV0dXJuICJTQ0FOTkVSX1NUQVRFX0FUVFJJQlVURV9WQUxVRSI7Ci0gICAgICAgICAgICBjYXNlIFNDQU5ORVJfU1RBVEVfU1RBUlRfRUxFTUVOVF9UQUc6IHJldHVybiAiU0NBTk5FUl9TVEFURV9TVEFSVF9FTEVNRU5UX1RBRyI7Ci0gICAgICAgICAgICBjYXNlIFNDQU5ORVJfU1RBVEVfRU5EX0VMRU1FTlRfVEFHOiByZXR1cm4gIlNDQU5ORVJfU1RBVEVfRU5EX0VMRU1FTlRfVEFHIjsKLSAgICAgICAgICAgIGNhc2UgU0NBTk5FUl9TVEFURV9DSEFSQUNURVJfREFUQTogcmV0dXJuICJTQ0FOTkVSX1NUQVRFX0NIQVJBQ1RFUl9EQVRBIiA7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gIj8/PyAoIitzdGF0ZSsnKSc7Ci0KLSAgICB9IC8vIGdldFNjYW5uZXJTdGF0ZU5hbWUoaW50KTpTdHJpbmcKLSAgICBwdWJsaWMgU3RyaW5nIGdldEVudGl0eU5hbWUoKXsKLSAgICAgICAgLy9yZXR1cm4gdGhlIGNhY2hlZCBuYW1lCi0gICAgICAgIHJldHVybiBmQ3VycmVudEVudGl0eU5hbWU7Ci0gICAgfQotCi0gICAgLyoqIFJldHVybnMgdGhlIGRyaXZlciBuYW1lLiAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0RHJpdmVyTmFtZShEcml2ZXIgZHJpdmVyKSB7Ci0KLSAgICAgICAgaWYgKERFQlVHX0RJU1BBVENIRVIpIHsKLSAgICAgICAgICAgIGlmIChkcml2ZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIFN0cmluZyBuYW1lID0gZHJpdmVyLmdldENsYXNzKCkuZ2V0TmFtZSgpOwotICAgICAgICAgICAgICAgIGludCBpbmRleCA9IG5hbWUubGFzdEluZGV4T2YoJy4nKTsKLSAgICAgICAgICAgICAgICBpZiAoaW5kZXggIT0gLTEpIHsKLSAgICAgICAgICAgICAgICAgICAgbmFtZSA9IG5hbWUuc3Vic3RyaW5nKGluZGV4ICsgMSk7Ci0gICAgICAgICAgICAgICAgICAgIGluZGV4ID0gbmFtZS5sYXN0SW5kZXhPZignJCcpOwotICAgICAgICAgICAgICAgICAgICBpZiAoaW5kZXggIT0gLTEpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUgPSBuYW1lLnN1YnN0cmluZyhpbmRleCArIDEpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHJldHVybiBuYW1lOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiAibnVsbCI7Ci0KLSAgICB9IC8vIGdldERyaXZlck5hbWUoKTpTdHJpbmcKLQotICAgIC8qKgotICAgICAqIENoZWNrIHRoZSBwcm90b2NvbCB1c2VkIGluIHRoZSBzeXN0ZW1JZCBhZ2FpbnN0IGFsbG93ZWQgcHJvdG9jb2xzCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc3lzdGVtSWQgdGhlIElkIG9mIHRoZSBVUkkKLSAgICAgKiBAcGFyYW0gYWxsb3dlZFByb3RvY29scyBhIGxpc3Qgb2YgYWxsb3dlZCBwcm90b2NvbHMgc2VwYXJhdGVkIGJ5IGNvbW1hCi0gICAgICogQHJldHVybiB0aGUgbmFtZSBvZiB0aGUgcHJvdG9jb2wgaWYgcmVqZWN0ZWQsIG51bGwgb3RoZXJ3aXNlCi0gICAgICovCi0gICAgU3RyaW5nIGNoZWNrQWNjZXNzKFN0cmluZyBzeXN0ZW1JZCwgU3RyaW5nIGFsbG93ZWRQcm90b2NvbHMpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgIFN0cmluZyBiYXNlU3lzdGVtSWQgPSBmRW50aXR5U2Nhbm5lci5nZXRCYXNlU3lzdGVtSWQoKTsKLSAgICAgICAgU3RyaW5nIGV4cGFuZGVkU3lzdGVtSWQgPSBYTUxFbnRpdHlNYW5hZ2VyLmV4cGFuZFN5c3RlbUlkKHN5c3RlbUlkLCBiYXNlU3lzdGVtSWQsIGZTdHJpY3RVUkkpOwotICAgICAgICByZXR1cm4gU2VjdXJpdHlTdXBwb3J0LmNoZWNrQWNjZXNzKGV4cGFuZGVkU3lzdGVtSWQsIGFsbG93ZWRQcm90b2NvbHMsIENvbnN0YW50cy5BQ0NFU1NfRVhURVJOQUxfQUxMKTsKLSAgICB9Ci0KLSAgICAvLwotICAgIC8vIENsYXNzZXMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogQGF1dGhvciBOZWVyYWogQmFqYWosIFN1biBNaWNyb3N5c3RlbXMuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBjbGFzcyBFbGVtZW50IHsKLQotICAgICAgICAvLwotICAgICAgICAvLyBEYXRhCi0gICAgICAgIC8vCi0KLSAgICAgICAgLyoqIFN5bWJvbC4gKi8KLSAgICAgICAgcHVibGljIFFOYW1lIHFuYW1lOwotCi0gICAgICAgIC8vcmF3IG5hbWUgc3RvcmVkIGFzIGNoYXJhY3RlcnMKLSAgICAgICAgcHVibGljIGNoYXJbXSBmUmF3bmFtZTsKLQotICAgICAgICAvKiogVGhlIG5leHQgRWxlbWVudCBlbnRyeS4gKi8KLSAgICAgICAgcHVibGljIEVsZW1lbnQgbmV4dDsKLQotICAgICAgICAvLwotICAgICAgICAvLyBDb25zdHJ1Y3RvcnMKLSAgICAgICAgLy8KLQotICAgICAgICAvKioKLSAgICAgICAgICogQ29uc3RydWN0cyBhIG5ldyBFbGVtZW50IGZyb20gdGhlIGdpdmVuIFFOYW1lIGFuZCBuZXh0IEVsZW1lbnQKLSAgICAgICAgICogcmVmZXJlbmNlLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIEVsZW1lbnQoUU5hbWUgcW5hbWUsIEVsZW1lbnQgbmV4dCkgewotICAgICAgICAgICAgdGhpcy5xbmFtZS5zZXRWYWx1ZXMocW5hbWUpOwotICAgICAgICAgICAgdGhpcy5mUmF3bmFtZSA9IHFuYW1lLnJhd25hbWUudG9DaGFyQXJyYXkoKTsKLSAgICAgICAgICAgIHRoaXMubmV4dCA9IG5leHQ7Ci0gICAgICAgIH0KLQotICAgIH0gLy8gY2xhc3MgRWxlbWVudAotCi0gICAgLyoqCi0gICAgICogRWxlbWVudCBzdGFjay4KLSAgICAgKgotICAgICAqIEBhdXRob3IgTmVlcmFqIEJhamFqLCBTdW4gTWljcm9zeXN0ZW1zLgotICAgICAqLwotICAgIHByb3RlY3RlZCBjbGFzcyBFbGVtZW50U3RhY2syIHsKLQotICAgICAgICAvLwotICAgICAgICAvLyBEYXRhCi0gICAgICAgIC8vCi0KLSAgICAgICAgLyoqIFRoZSBzdGFjayBkYXRhLiAqLwotICAgICAgICBwcm90ZWN0ZWQgUU5hbWUgW10gZlFOYW1lID0gbmV3IFFOYW1lWzIwXTsKLQotICAgICAgICAvL0VsZW1lbnQgZGVwdGgKLSAgICAgICAgcHJvdGVjdGVkIGludCBmRGVwdGg7Ci0gICAgICAgIC8vdG90YWwgbnVtYmVyIG9mIGVsZW1lbnRzCi0gICAgICAgIHByb3RlY3RlZCBpbnQgZkNvdW50OwotICAgICAgICAvL2N1cnJlbnQgcG9zaXRpb24KLSAgICAgICAgcHJvdGVjdGVkIGludCBmUG9zaXRpb247Ci0gICAgICAgIC8vTWFyayByZWZlcnMgdG8gdGhlIHBvc2l0aW9uCi0gICAgICAgIHByb3RlY3RlZCBpbnQgZk1hcms7Ci0KLSAgICAgICAgcHJvdGVjdGVkIGludCBmTGFzdERlcHRoIDsKLQotICAgICAgICAvLwotICAgICAgICAvLyBDb25zdHJ1Y3RvcnMKLSAgICAgICAgLy8KLQotICAgICAgICAvKiogRGVmYXVsdCBjb25zdHJ1Y3Rvci4gKi8KLSAgICAgICAgcHVibGljIEVsZW1lbnRTdGFjazIoKSB7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZRTmFtZS5sZW5ndGg7IGkrKykgewotICAgICAgICAgICAgICAgIGZRTmFtZVtpXSA9IG5ldyBRTmFtZSgpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZk1hcmsgPSBmUG9zaXRpb24gPSAxOwotICAgICAgICB9IC8vIDxpbml0PigpCi0KLSAgICAgICAgcHVibGljIHZvaWQgcmVzaXplKCl7Ci0gICAgICAgICAgICAvKioKLSAgICAgICAgICAgICAqIGludCBsZW5ndGggPSBmRWxlbWVudHMubGVuZ3RoOwotICAgICAgICAgICAgICogRWxlbWVudCBbXSB0ZW1wID0gbmV3IEVsZW1lbnRbbGVuZ3RoICogMl07Ci0gICAgICAgICAgICAgKiBTeXN0ZW0uYXJyYXljb3B5KGZFbGVtZW50cywgMCwgdGVtcCwgMCwgbGVuZ3RoKTsKLSAgICAgICAgICAgICAqIGZFbGVtZW50cyA9IHRlbXA7Ci0gICAgICAgICAgICAgKi8KLSAgICAgICAgICAgIC8vcmVzaXplIFFOYW1lcwotICAgICAgICAgICAgaW50IG9sZExlbmd0aCA9IGZRTmFtZS5sZW5ndGg7Ci0gICAgICAgICAgICBRTmFtZSBbXSB0bXAgPSBuZXcgUU5hbWVbb2xkTGVuZ3RoICogMl07Ci0gICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGZRTmFtZSwgMCwgdG1wLCAwLCBvbGRMZW5ndGgpOwotICAgICAgICAgICAgZlFOYW1lID0gdG1wOwotCi0gICAgICAgICAgICBmb3IgKGludCBpID0gb2xkTGVuZ3RoOyBpIDwgZlFOYW1lLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgZlFOYW1lW2ldID0gbmV3IFFOYW1lKCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgfQotCi0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gUHVibGljIG1ldGhvZHMKLSAgICAgICAgLy8KLQotICAgICAgICAvKiogQ2hlY2sgaWYgdGhlIGVsZW1lbnQgc2Nhbm5lZCBkdXJpbmcgdGhlIHN0YXJ0IGVsZW1lbnQKLSAgICAgICAgICptYXRjaGVzIHRoZSBzdG9yZWQgZWxlbWVudC4KLSAgICAgICAgICoKLSAgICAgICAgICpAcmV0dXJuIHRydWUgaWYgdGhlIG1hdGNoIHN1Y2VlZHMuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgYm9vbGVhbiBtYXRjaEVsZW1lbnQoUU5hbWUgZWxlbWVudCkgewotICAgICAgICAgICAgLy9sYXN0IGRlcHRoIGlzIHRoZSBkZXB0aCB3aGVuIGxhc3QgZWxlbW50IHdhcyBwdXNoZWQKLSAgICAgICAgICAgIC8vaWYgbGFzdCBkZXB0aCBpcyBncmVhdGVyIHRoYW4gY3VycmVudCBkZXB0aAotICAgICAgICAgICAgaWYoREVCVUdfU0tJUF9BTEdPUklUSE0pewotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiZkxhc3REZXB0aCA9ICIgKyBmTGFzdERlcHRoKTsKLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oImZEZXB0aCA9ICIgKyBmRGVwdGgpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgYm9vbGVhbiBtYXRjaCA9IGZhbHNlOwotICAgICAgICAgICAgaWYoZkxhc3REZXB0aCA+IGZEZXB0aCAmJiBmRGVwdGggPD0gMil7Ci0gICAgICAgICAgICAgICAgaWYoREVCVUdfU0tJUF9BTEdPUklUSE0pewotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkNoZWNraW5nIGlmIHRoZSBlbGVtZW50cyBtYXRjaCAiICsgZWxlbWVudC5yYXduYW1lICsgIiAsICIgKyBmUU5hbWVbZkRlcHRoXS5yYXduYW1lKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaWYoZWxlbWVudC5yYXduYW1lID09IGZRTmFtZVtmRGVwdGhdLnJhd25hbWUpewotICAgICAgICAgICAgICAgICAgICBmQWRkID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgICAgIC8vbWFyayB0aGlzIHBvc2l0aW9uCi0gICAgICAgICAgICAgICAgICAgIC8vZGVjcmVhc2UgdGhlIGRlcHRoIGJ5IDEgYXMgYXJyYXlzIGFyZSAwIGJhc2VkCi0gICAgICAgICAgICAgICAgICAgIGZNYXJrID0gZkRlcHRoIC0gMTsKLSAgICAgICAgICAgICAgICAgICAgLy93ZSBmb3VuZCB0aGUgbWF0Y2ggYW5kIGZyb20gbmV4dCBlbGVtZW50IHNraXBwaW5nIHdpbGwgc3RhcnQsIGFkZCAxCi0gICAgICAgICAgICAgICAgICAgIGZQb3NpdGlvbiA9IGZNYXJrICsgMSA7Ci0gICAgICAgICAgICAgICAgICAgIG1hdGNoID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgLy9PbmNlIHdlIGdldCBtYXRjaCBkZWNyZWFzZSB0aGUgY291bnQgLS0gdGhpcyB3YXMgaW5jcmVhc2VkIGJ5IG5leHRFbGVtZW50KCkKLSAgICAgICAgICAgICAgICAgICAgLS1mQ291bnQ7Ci0gICAgICAgICAgICAgICAgICAgIGlmKERFQlVHX1NLSVBfQUxHT1JJVEhNKXsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiZkFkZCBGQUxTRSAtLSBOT1cgRUxFTUVOVCBTSE9VTEQgTk9UIEJFIEFEREVEIik7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oImZNYXJrID0gIiArIGZNYXJrKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiZlBvc2l0aW9uID0gIiArIGZQb3NpdGlvbik7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oImZEZXB0aCA9ICIgKyBmRGVwdGgpOwotICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJmQ291bnQgPSAiICsgZkNvdW50KTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH1lbHNlewotICAgICAgICAgICAgICAgICAgICBmQWRkID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgaWYoREVCVUdfU0tJUF9BTEdPUklUSE0pU3lzdGVtLm91dC5wcmludGxuKCJmQWRkIGlzICIgKyBmQWRkKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvL3N0b3JlIHRoZSBsYXN0IGRlcHRoCi0gICAgICAgICAgICBmTGFzdERlcHRoID0gZkRlcHRoKys7Ci0gICAgICAgICAgICByZXR1cm4gbWF0Y2g7Ci0gICAgICAgIH0gLy8gcHVzaEVsZW1lbnQoUU5hbWUpOlFOYW1lCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFRoaXMgZnVuY3Rpb24gZG9lc24ndCBpbmNyZWFzZSBkZXB0aC4gVGhlIGZ1bmN0aW9uIGluIHRoaXMgZnVuY3Rpb24gaXMKLSAgICAgICAgICpicm9rZW4gZG93biBpbnRvIHR3byBmdW5jdGlvbnMgZm9yIGVmZmljaWVuY3kuIDxAc2VlPm1hdGNoRWxlbWVudDwvc2VlPi4KLSAgICAgICAgICogVGhpcyBmdW5jdGlvbiBqdXN0IHJldHVybnMgdGhlIHBvaW50ZXIgdG8gdGhlIG9iamVjdCBhbmQgaXRzIHZhbHVlcyBhcmUgc2V0LgotICAgICAgICAgKgotICAgICAgICAgKkByZXR1cm4gUU5hbWUgcmVmZXJlbmNlIHRvIHRoZSBuZXh0IGVsZW1lbnQgaW4gdGhlIGxpc3QKLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBRTmFtZSBuZXh0RWxlbWVudCgpIHsKLQotICAgICAgICAgICAgLy9pZiBudW1iZXIgb2YgZWxlbWVudHMgYmVjb21lcyBlcXVhbCB0byB0aGUgbGVuZ3RoIG9mIGFycmF5IC0tIHN0b3AgdGhlIHNraXBwaW5nCi0gICAgICAgICAgICBpZiAoZkNvdW50ID09IGZRTmFtZS5sZW5ndGgpIHsKLSAgICAgICAgICAgICAgICBmU2hvdWxkU2tpcCA9IGZhbHNlOwotICAgICAgICAgICAgICAgIGZBZGQgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICBpZihERUJVR19TS0lQX0FMR09SSVRITSlTeXN0ZW0ub3V0LnByaW50bG4oIlNLSVBQSU5HIFNUT1BQRUQsIGZTaG91bGRTa2lwID0gIiArIGZTaG91bGRTa2lwKTsKLSAgICAgICAgICAgICAgICAvL3h4eDogdGhpcyBpcyBub3QgY29ycmVjdCwgd2UgYXJlIHJldHVybmluZyB0aGUgbGFzdCBlbGVtZW50Ci0gICAgICAgICAgICAgICAgLy90aGlzIHdvbnQgbWFrZSBhbnkgZGlmZmVyZW5jZSBzaW5jZSBmbGFnIGhhcyBiZWVuIHNldCB0byAnZmFsc2UnCi0gICAgICAgICAgICAgICAgcmV0dXJuIGZRTmFtZVstLWZDb3VudF07Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZihERUJVR19TS0lQX0FMR09SSVRITSl7Ci0gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJmQ291bnQgPSAiICsgZkNvdW50KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiBmUU5hbWVbZkNvdW50KytdOwotCi0gICAgICAgIH0KLQotICAgICAgICAvKiogTm90ZSB0aGF0IHRoaXMgZnVuY3Rpb24gaXMgY29uc2lkZXJhYmx5IGRpZmZlcmVudCB0aGFuIG5leHRFbGVtZW50KCkKLSAgICAgICAgICogVGhpcyBmdW5jdGlvbiBqdXN0IHJldHVybnMgdGhlIHByZXZpb3VzbHkgc3RvcmVkIGVsZW1lbnRzCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgUU5hbWUgZ2V0TmV4dCgpewotICAgICAgICAgICAgLy93aGVuIHBvc2l0aW9uIHJlYWNoZXMgbnVtYmVyIG9mIGVsZW1lbnRzIGluIHRoZSBsaXN0Li4KLSAgICAgICAgICAgIC8vc2V0IHRoZSBwb3NpdGlvbiBiYWNrIHRvIG1hcmssICBtYWtpbmcgaXQgYSBjaXJjdWxhciBsaW5rZWQgbGlzdC4KLSAgICAgICAgICAgIGlmKGZQb3NpdGlvbiA9PSBmQ291bnQpewotICAgICAgICAgICAgICAgIGZQb3NpdGlvbiA9IGZNYXJrOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIGZRTmFtZVtmUG9zaXRpb24rK107Ci0gICAgICAgIH0KLQotICAgICAgICAvKiogcmV0dXJucyB0aGUgY3VycmVudCBkZXB0aAotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIGludCBwb3BFbGVtZW50KCl7Ci0gICAgICAgICAgICByZXR1cm4gZkRlcHRoLS07Ci0gICAgICAgIH0KLQotCi0gICAgICAgIC8qKiBDbGVhcnMgdGhlIHN0YWNrIHdpdGhvdXQgdGhyb3dpbmcgYXdheSBleGlzdGluZyBRTmFtZSBvYmplY3RzLiAqLwotICAgICAgICBwdWJsaWMgdm9pZCBjbGVhcigpIHsKLSAgICAgICAgICAgIGZMYXN0RGVwdGggPSAwOwotICAgICAgICAgICAgZkRlcHRoID0gMDsKLSAgICAgICAgICAgIGZDb3VudCA9IDAgOwotICAgICAgICAgICAgZlBvc2l0aW9uID0gZk1hcmsgPSAxOwotICAgICAgICB9IC8vIGNsZWFyKCkKLQotICAgIH0gLy8gY2xhc3MgRWxlbWVudFN0YWNrCi0KLSAgICAvKioKLSAgICAgKiBFbGVtZW50IHN0YWNrLiBUaGlzIHN0YWNrIG9wZXJhdGVzIHdpdGhvdXQgc3luY2hyb25pemF0aW9uLCBlcnJvcgotICAgICAqIGNoZWNraW5nLCBhbmQgaXQgcmUtdXNlcyBvYmplY3RzIGluc3RlYWQgb2YgdGhyb3dpbmcgcG9wcGVkIGl0ZW1zCi0gICAgICogYXdheS4KLSAgICAgKgotICAgICAqIEBhdXRob3IgQW5keSBDbGFyaywgSUJNCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGNsYXNzIEVsZW1lbnRTdGFjayB7Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gRGF0YQotICAgICAgICAvLwotCi0gICAgICAgIC8qKiBUaGUgc3RhY2sgZGF0YS4gKi8KLSAgICAgICAgcHJvdGVjdGVkIFFOYW1lW10gZkVsZW1lbnRzOwotICAgICAgICBwcm90ZWN0ZWQgaW50IFtdICBmSW50ID0gbmV3IGludFsyMF07Ci0KLQotICAgICAgICAvL0VsZW1lbnQgZGVwdGgKLSAgICAgICAgcHJvdGVjdGVkIGludCBmRGVwdGg7Ci0gICAgICAgIC8vdG90YWwgbnVtYmVyIG9mIGVsZW1lbnRzCi0gICAgICAgIHByb3RlY3RlZCBpbnQgZkNvdW50OwotICAgICAgICAvL2N1cnJlbnQgcG9zaXRpb24KLSAgICAgICAgcHJvdGVjdGVkIGludCBmUG9zaXRpb247Ci0gICAgICAgIC8vTWFyayByZWZlcnMgdG8gdGhlIHBvc2l0aW9uCi0gICAgICAgIHByb3RlY3RlZCBpbnQgZk1hcms7Ci0KLSAgICAgICAgcHJvdGVjdGVkIGludCBmTGFzdERlcHRoIDsKLQotICAgICAgICAvLwotICAgICAgICAvLyBDb25zdHJ1Y3RvcnMKLSAgICAgICAgLy8KLQotICAgICAgICAvKiogRGVmYXVsdCBjb25zdHJ1Y3Rvci4gKi8KLSAgICAgICAgcHVibGljIEVsZW1lbnRTdGFjaygpIHsKLSAgICAgICAgICAgIGZFbGVtZW50cyA9IG5ldyBRTmFtZVsyMF07Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZFbGVtZW50cy5sZW5ndGg7IGkrKykgewotICAgICAgICAgICAgICAgIGZFbGVtZW50c1tpXSA9IG5ldyBRTmFtZSgpOwotICAgICAgICAgICAgfQotICAgICAgICB9IC8vIDxpbml0PigpCi0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gUHVibGljIG1ldGhvZHMKLSAgICAgICAgLy8KLQotICAgICAgICAvKioKLSAgICAgICAgICogUHVzaGVzIGFuIGVsZW1lbnQgb24gdGhlIHN0YWNrLgotICAgICAgICAgKiA8cD4KLSAgICAgICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGUgUU5hbWUgdmFsdWVzIGFyZSBjb3BpZWQgaW50byB0aGUKLSAgICAgICAgICogc3RhY2suIEluIG90aGVyIHdvcmRzLCB0aGUgY2FsbGVyIGRvZXMgPGVtPm5vdDwvZW0+IG9ycGhhbgotICAgICAgICAgKiB0aGUgZWxlbWVudCB0byB0aGUgc3RhY2suIEFsc28sIHRoZSBRTmFtZSBvYmplY3QgcmV0dXJuZWQKLSAgICAgICAgICogaXMgPGVtPm5vdDwvZW0+IG9ycGhhbmVkIHRvIHRoZSBjYWxsZXIuIEl0IHNob3VsZCBiZQotICAgICAgICAgKiBjb25zaWRlcmVkIHJlYWQtb25seS4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIGVsZW1lbnQgVGhlIGVsZW1lbnQgdG8gcHVzaCBvbnRvIHRoZSBzdGFjay4KLSAgICAgICAgICoKLSAgICAgICAgICogQHJldHVybiBSZXR1cm5zIHRoZSBhY3R1YWwgUU5hbWUgb2JqZWN0IHRoYXQgc3RvcmVzIHRoZQotICAgICAgICAgKi8KLSAgICAgICAgLy9YWFg6IFRISVMgRlVOQ1RJT04gSVMgTk9UIFVTRUQKLSAgICAgICAgcHVibGljIFFOYW1lIHB1c2hFbGVtZW50KFFOYW1lIGVsZW1lbnQpIHsKLSAgICAgICAgICAgIGlmIChmRGVwdGggPT0gZkVsZW1lbnRzLmxlbmd0aCkgewotICAgICAgICAgICAgICAgIFFOYW1lW10gYXJyYXkgPSBuZXcgUU5hbWVbZkVsZW1lbnRzLmxlbmd0aCAqIDJdOwotICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZkVsZW1lbnRzLCAwLCBhcnJheSwgMCwgZkRlcHRoKTsKLSAgICAgICAgICAgICAgICBmRWxlbWVudHMgPSBhcnJheTsKLSAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gZkRlcHRoOyBpIDwgZkVsZW1lbnRzLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZFbGVtZW50c1tpXSA9IG5ldyBRTmFtZSgpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGZFbGVtZW50c1tmRGVwdGhdLnNldFZhbHVlcyhlbGVtZW50KTsKLSAgICAgICAgICAgIHJldHVybiBmRWxlbWVudHNbZkRlcHRoKytdOwotICAgICAgICB9IC8vIHB1c2hFbGVtZW50KFFOYW1lKTpRTmFtZQotCi0KLSAgICAgICAgLyoqIE5vdGUgdGhhdCB0aGlzIGZ1bmN0aW9uIGlzIGNvbnNpZGVyYWJseSBkaWZmZXJlbnQgdGhhbiBuZXh0RWxlbWVudCgpCi0gICAgICAgICAqIFRoaXMgZnVuY3Rpb24ganVzdCByZXR1cm5zIHRoZSBwcmV2aW91c2x5IHN0b3JlZCBlbGVtZW50cwotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIFFOYW1lIGdldE5leHQoKXsKLSAgICAgICAgICAgIC8vd2hlbiBwb3NpdGlvbiByZWFjaGVzIG51bWJlciBvZiBlbGVtZW50cyBpbiB0aGUgbGlzdC4uCi0gICAgICAgICAgICAvL3NldCB0aGUgcG9zaXRpb24gYmFjayB0byBtYXJrLCAgbWFraW5nIGl0IGEgY2lyY3VsYXIgbGlua2VkIGxpc3QuCi0gICAgICAgICAgICBpZihmUG9zaXRpb24gPT0gZkNvdW50KXsKLSAgICAgICAgICAgICAgICBmUG9zaXRpb24gPSBmTWFyazsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vc3RvcmUgdGhlIHBvc2l0aW9uIG9mIGxhc3Qgb3BlbmVkIHRhZyBhdCBwYXJ0aWN1bGFyIGRlcHRoCi0gICAgICAgICAgICAvL2ZJbnRbKytmRGVwdGhdID0gZlBvc2l0aW9uOwotICAgICAgICAgICAgaWYoREVCVUdfU0tJUF9BTEdPUklUSE0pewotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiRWxlbWVudCBhdCBmUG9zaXRpb24gPSAiICsgZlBvc2l0aW9uICsgIiBpcyAiICsgZkVsZW1lbnRzW2ZQb3NpdGlvbl0ucmF3bmFtZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvL3JldHVybiBmRWxlbWVudHNbZlBvc2l0aW9uKytdOwotICAgICAgICAgICAgcmV0dXJuIGZFbGVtZW50c1tmUG9zaXRpb25dOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqIFRoaXMgZnVuY3Rpb24gc2hvdWxkIGJlIGNhbGxlZCBvbmx5IHdoZW4gZWxlbWVudCB3YXMgc2tpcHBlZCBzdWNlc3NmdWxseS4KLSAgICAgICAgICogMS4gSW5jcmVhc2UgdGhlIGRlcHRoIC0gYmVjYXVzZSBlbGVtZW50IHdhcyBzdWNlc3NmdWxseSBza2lwcGVkLgotICAgICAgICAgKjIuIFN0b3JlIHRoZSBwb3NpdGlvbiBvZiB0aGUgZWxlbWVudCB0b2tlbiBpbiBhcnJheSAgImxhc3Qgb3BlbmVkIHRhZyIgYXQgZGVwdGguCi0gICAgICAgICAqMy4gaW5jcmVhc2UgdGhlIHBvc2l0aW9uIGNvdW50ZXIgc28gYXMgdG8gcG9pbnQgdG8gdGhlIG5leHQgZWxlbWVudCBpbiB0aGUgYXJyYXkKLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyB2b2lkIHB1c2goKXsKLQotICAgICAgICAgICAgZkludFsrK2ZEZXB0aF0gPSBmUG9zaXRpb24rKzsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKiBDaGVjayBpZiB0aGUgZWxlbWVudCBzY2FubmVkIGR1cmluZyB0aGUgc3RhcnQgZWxlbWVudAotICAgICAgICAgKm1hdGNoZXMgdGhlIHN0b3JlZCBlbGVtZW50LgotICAgICAgICAgKgotICAgICAgICAgKkByZXR1cm4gdHJ1ZSBpZiB0aGUgbWF0Y2ggc3VjZWVkcy4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBib29sZWFuIG1hdGNoRWxlbWVudChRTmFtZSBlbGVtZW50KSB7Ci0gICAgICAgICAgICAvL2xhc3QgZGVwdGggaXMgdGhlIGRlcHRoIHdoZW4gbGFzdCBlbGVtbnQgd2FzIHB1c2hlZAotICAgICAgICAgICAgLy9pZiBsYXN0IGRlcHRoIGlzIGdyZWF0ZXIgdGhhbiBjdXJyZW50IGRlcHRoCi0gICAgICAgICAgICAvL2lmKERFQlVHX1NLSVBfQUxHT1JJVEhNKXsKLSAgICAgICAgICAgIC8vICAgU3lzdGVtLm91dC5wcmludGxuKCJDaGVjayBpZiB0aGUgZWxlbWVudCAiICsgZWxlbWVudC5yYXduYW1lICsgIiBtYXRjaGVzIik7Ci0gICAgICAgICAgICAvLyAgU3lzdGVtLm91dC5wcmludGxuKCJmTGFzdERlcHRoID0gIiArIGZMYXN0RGVwdGgpOwotICAgICAgICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJmRGVwdGggPSAiICsgZkRlcHRoKTsKLSAgICAgICAgICAgIC8vfQotICAgICAgICAgICAgYm9vbGVhbiBtYXRjaCA9IGZhbHNlOwotICAgICAgICAgICAgaWYoZkxhc3REZXB0aCA+IGZEZXB0aCAmJiBmRGVwdGggPD0gMyl7Ci0gICAgICAgICAgICAgICAgaWYoREVCVUdfU0tJUF9BTEdPUklUSE0pewotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIi0tLS0tLS0tLS1FTlRFUkVEIFRIRSBMT09QIFdIRVJFIFdFIENIRUNLIEZPUiBNQVRDSElORyBPRiBFTE1FTlQtLS0tLSIpOwotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkRlcHRoID0gIiArIGZEZXB0aCArICIgQ2hlY2tpbmcgaWYgSU5DT01JTkcgZWxlbWVudCAiICsgZWxlbWVudC5yYXduYW1lICsgIiBtYXRjaCBTVE9SRUQgRUxFTUVOVCAiICsgZkVsZW1lbnRzW2ZEZXB0aCAtIDFdLnJhd25hbWUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpZihlbGVtZW50LnJhd25hbWUgPT0gZkVsZW1lbnRzW2ZEZXB0aCAtIDFdLnJhd25hbWUpewotICAgICAgICAgICAgICAgICAgICBmQWRkID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgICAgIC8vbWFyayB0aGlzIHBvc2l0aW9uCi0gICAgICAgICAgICAgICAgICAgIC8vZGVjcmVhc2UgdGhlIGRlcHRoIGJ5IDEgYXMgYXJyYXlzIGFyZSAwIGJhc2VkCi0gICAgICAgICAgICAgICAgICAgIGZNYXJrID0gZkRlcHRoIC0gMTsKLSAgICAgICAgICAgICAgICAgICAgLy93ZSBmb3VuZCB0aGUgbWF0Y2gKLSAgICAgICAgICAgICAgICAgICAgZlBvc2l0aW9uID0gZk1hcms7Ci0gICAgICAgICAgICAgICAgICAgIG1hdGNoID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgLy9PbmNlIHdlIGdldCBtYXRjaCBkZWNyZWFzZSB0aGUgY291bnQgLS0gdGhpcyB3YXMgaW5jcmVhc2VkIGJ5IG5leHRFbGVtZW50KCkKLSAgICAgICAgICAgICAgICAgICAgLS1mQ291bnQ7Ci0gICAgICAgICAgICAgICAgICAgIGlmKERFQlVHX1NLSVBfQUxHT1JJVEhNKXsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiTk9XIEVMRU1FTlQgU0hPVUxEIE5PVCBCRSBBRERFRCwgZkFkZCBpcyBzZXQgdG8gZmFsc2UiKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiZk1hcmsgPSAiICsgZk1hcmspOwotICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJmUG9zaXRpb24gPSAiICsgZlBvc2l0aW9uKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiZkRlcHRoID0gIiArIGZEZXB0aCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oImZDb3VudCA9ICIgKyBmQ291bnQpOwotICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCItLS0tLS0tLS1NQVRDSCBTVUNFRURFRC0tLS0tLS0tLS0tLS0tLS0tIik7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIiIpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfWVsc2V7Ci0gICAgICAgICAgICAgICAgICAgIGZBZGQgPSB0cnVlOwotICAgICAgICAgICAgICAgICAgICBpZihERUJVR19TS0lQX0FMR09SSVRITSlTeXN0ZW0ub3V0LnByaW50bG4oImZBZGQgaXMgIiArIGZBZGQpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vc3RvcmUgdGhlIHBvc2l0aW9uIGZvciB0aGUgY3VycmVudCBkZXB0aAotICAgICAgICAgICAgLy93aGVuIHdlIGFyZSBhZGRpbmcgdGhlIGVsZW1lbnRzLCB3aGVuIHNraXBwaW5nCi0gICAgICAgICAgICAvL3N0YXJ0cyBldmVuIHRoZW4gdGhpcyBzaG91bGQgYmUgdHJhY2tlZCBpZS4gd2hlbgotICAgICAgICAgICAgLy9jYWxsaW5nIGdldE5leHQoKQotICAgICAgICAgICAgaWYobWF0Y2gpewotICAgICAgICAgICAgICAgIC8vZnJvbSBuZXh0IGVsZW1lbnQgc2tpcHBpbmcgd2lsbCBzdGFydCwgYWRkIDEKLSAgICAgICAgICAgICAgICBmSW50W2ZEZXB0aF0gPSBmUG9zaXRpb24rKzsKLSAgICAgICAgICAgIH0gZWxzZXsKLSAgICAgICAgICAgICAgICBpZihERUJVR19TS0lQX0FMR09SSVRITSl7Ci0gICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiQXQgZGVwdGggPSAiICsgZkRlcHRoICsgImFycmF5IHBvc2l0aW9uIGlzID0gIiArIChmQ291bnQgLSAxKSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIC8vc2ljbmUgZkludFtmRGVwdGhdIGNvbnRhaW5zIHBvaW50ZXIgdG8gdGhlIGVsZW1lbnQgYXJyYXkgd2hpY2ggYXJlIDAgYmFzZWQuCi0gICAgICAgICAgICAgICAgZkludFtmRGVwdGhdID0gZkNvdW50IC0gMTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy9pZiBudW1iZXIgb2YgZWxlbWVudHMgYmVjb21lcyBlcXVhbCB0byB0aGUgbGVuZ3RoIG9mIGFycmF5IC0tIHN0b3AgdGhlIHNraXBwaW5nCi0gICAgICAgICAgICAvL3h4eDogc2hvdWxkIHdlIGRvICJmQ291bnQgPT0gZkludC5sZW5ndGgiCi0gICAgICAgICAgICBpZiAoZkNvdW50ID09IGZFbGVtZW50cy5sZW5ndGgpIHsKLSAgICAgICAgICAgICAgICBmU2tpcCA9IGZhbHNlOwotICAgICAgICAgICAgICAgIGZBZGQgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICAvL3JlcG9zaXRpb24gdGhlIHN0YWNrIC0tIGl0IHNlZW1zIHRvIGJlIHRvbyBjb21wbGV4IGRvY3VtZW50IGFuZCB0aGVyZSBpcyBubyBzeW1tZXJ0eSBpbiBzdHJ1Y3R1cmUKLSAgICAgICAgICAgICAgICByZXBvc2l0aW9uKCk7Ci0gICAgICAgICAgICAgICAgaWYoREVCVUdfU0tJUF9BTEdPUklUSE0pewotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkFMTCBUSEUgRUxNRU5UUyBJTiBBUlJBWSBIQVZFIEJFRU4gRklMTEVEIik7Ci0gICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiUkVQT1NJVElPTklORyBUSEUgU1RBQ0siKTsKLSAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCItLS0tLS0tLS0tLVNLSVBQSU5HIFNUT1BQRUQtLS0tLS0tLS0tIik7Ci0gICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiIik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmKERFQlVHX1NLSVBfQUxHT1JJVEhNKXsKLSAgICAgICAgICAgICAgICBpZihtYXRjaCl7Ci0gICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiU3RvcmluZyBmUG9zaXRpb24gPSAiICsgZkludFtmRGVwdGhdICsgIiBhdCBmRGVwdGggPSAiICsgZkRlcHRoKTsKLSAgICAgICAgICAgICAgICB9ZWxzZXsKLSAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJTdG9yaW5nIGZDb3VudCA9ICIgKyBmSW50W2ZEZXB0aF0gKyAiIGF0IGZEZXB0aCA9ICIgKyBmRGVwdGgpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vc3RvcmUgdGhlIGxhc3QgZGVwdGgKLSAgICAgICAgICAgIGZMYXN0RGVwdGggPSBmRGVwdGg7Ci0gICAgICAgICAgICByZXR1cm4gbWF0Y2g7Ci0gICAgICAgIH0gLy8gbWF0Y2hFbGVtZW50KFFOYW1lKTpRTmFtZQotCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFJldHVybnMgdGhlIG5leHQgZWxlbWVudCBvbiB0aGUgc3RhY2suCi0gICAgICAgICAqCi0gICAgICAgICAqIEByZXR1cm4gUmV0dXJucyB0aGUgYWN0dWFsIFFOYW1lIG9iamVjdC4gQ2FsbGVlIHNob3VsZAotICAgICAgICAgKiB1c2UgdGhpcyBvYmplY3QgdG8gc3RvcmUgdGhlIGRldGFpbHMgb2YgbmV4dCBlbGVtZW50IGVuY291bnRlcmVkLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIFFOYW1lIG5leHRFbGVtZW50KCkgewotICAgICAgICAgICAgaWYoZlNraXApewotICAgICAgICAgICAgICAgIGZEZXB0aCsrOwotICAgICAgICAgICAgICAgIC8vYm91bmRhcnkgY2hlY2tzIGFyZSBkb25lIGluIG1hdGNoRWxlbWVudCgpCi0gICAgICAgICAgICAgICAgcmV0dXJuIGZFbGVtZW50c1tmQ291bnQrK107Ci0gICAgICAgICAgICB9IGVsc2UgaWYgKGZEZXB0aCA9PSBmRWxlbWVudHMubGVuZ3RoKSB7Ci0gICAgICAgICAgICAgICAgUU5hbWVbXSBhcnJheSA9IG5ldyBRTmFtZVtmRWxlbWVudHMubGVuZ3RoICogMl07Ci0gICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShmRWxlbWVudHMsIDAsIGFycmF5LCAwLCBmRGVwdGgpOwotICAgICAgICAgICAgICAgIGZFbGVtZW50cyA9IGFycmF5OwotICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSBmRGVwdGg7IGkgPCBmRWxlbWVudHMubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgZkVsZW1lbnRzW2ldID0gbmV3IFFOYW1lKCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICByZXR1cm4gZkVsZW1lbnRzW2ZEZXB0aCsrXTsKLQotICAgICAgICB9IC8vIHB1c2hFbGVtZW50KFFOYW1lKTpRTmFtZQotCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFBvcHMgYW4gZWxlbWVudCBvZmYgb2YgdGhlIHN0YWNrIGJ5IHNldHRpbmcgdGhlIHZhbHVlcyBvZgotICAgICAgICAgKiB0aGUgc3BlY2lmaWVkIFFOYW1lLgotICAgICAgICAgKiA8cD4KLSAgICAgICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGUgb2JqZWN0IHJldHVybmVkIGlzIDxlbT5ub3Q8L2VtPgotICAgICAgICAgKiBvcnBoYW5lZCB0byB0aGUgY2FsbGVyLiBUaGVyZWZvcmUsIHRoZSBjYWxsZXIgc2hvdWxkIGNvbnNpZGVyCi0gICAgICAgICAqIHRoZSBvYmplY3QgdG8gYmUgcmVhZC1vbmx5LgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIFFOYW1lIHBvcEVsZW1lbnQoKSB7Ci0gICAgICAgICAgICAvL3JldHVybiB0aGUgc2FtZSBvYmplY3QgdGhhdCB3YXMgcHVzaGVkIC0tIHRoaXMgd291bGQgYXZvaWQKLSAgICAgICAgICAgIC8vc2V0dGluZyB0aGUgdmFsdWVzIGZvciBldmVyeSBlbmQgZWxlbWVudC4KLSAgICAgICAgICAgIC8vU1RST05HOiB0aGlzIG9iamVjdCBpcyByZWFkIG9ubHkgLS0gdGhpcyBvYmplY3QgcmVmZXJlbmNlIHNob3VsZG4ndCBiZSBzdG9yZWQuCi0gICAgICAgICAgICBpZihmU2tpcCB8fCBmQWRkICl7Ci0gICAgICAgICAgICAgICAgaWYoREVCVUdfU0tJUF9BTEdPUklUSE0pewotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlBPUFBJTkcgRWxlbWVudCwgYXQgcG9zaXRpb24gIiArIGZJbnRbZkRlcHRoXSArICIgZWxlbWVudCBhdCB0aGF0IGNvdW50IGlzID0gIiArIGZFbGVtZW50c1tmSW50W2ZEZXB0aF1dLnJhd25hbWUpOwotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIiIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICByZXR1cm4gZkVsZW1lbnRzW2ZJbnRbZkRlcHRoLS1dXTsKLSAgICAgICAgICAgIH0gZWxzZXsKLSAgICAgICAgICAgICAgICBpZihERUJVR19TS0lQX0FMR09SSVRITSl7Ci0gICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiUmV0cmlldmVpbmcgZWxlbWVudCBhdCBkZXB0aCA9ICIgKyBmRGVwdGggKyAiIGlzICIgKyBmRWxlbWVudHNbZkRlcHRoXS5yYXduYW1lICk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHJldHVybiBmRWxlbWVudHNbLS1mRGVwdGhdIDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vZWxlbWVudC5zZXRWYWx1ZXMoZkVsZW1lbnRzWy0tZkRlcHRoXSk7Ci0gICAgICAgIH0gLy8gcG9wRWxlbWVudChRTmFtZSkKLQotICAgICAgICAvKiogUmVwb3NpdGlvbiB0aGUgc3RhY2suIGZJbnQgW10gY29udGFpbnMgYWxsIHRoZSBvcGVuZWQgdGFncyBhdCBwYXJ0aWN1bGFyIGRlcHRoLgotICAgICAgICAgKiBUcmFuc2ZlciBhbGwgdGhlIG9wZW5lZCB0YWdzIHN0YXJ0aW5nIGZyb20gZGVwdGggJzInIHRvIHRoZSBjdXJyZW50IGRlcHRoIGFuZCByZXBvc2l0aW9uIHRoZW0KLSAgICAgICAgICphcyBwZXIgdGhlIGRlcHRoLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIHZvaWQgcmVwb3NpdGlvbigpewotICAgICAgICAgICAgZm9yKCBpbnQgaSA9IDIgOyBpIDw9IGZEZXB0aCA7IGkrKyl7Ci0gICAgICAgICAgICAgICAgZkVsZW1lbnRzW2ktMV0gPSBmRWxlbWVudHNbZkludFtpXV07Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZihERUJVR19TS0lQX0FMR09SSVRITSl7Ci0gICAgICAgICAgICAgICAgZm9yKCBpbnQgaSA9IDAgOyBpIDwgZkRlcHRoIDsgaSsrKXsKLSAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJmRWxlbWVudHNbIiArIGkgKyAiXSIgKyAiID0gIiArIGZFbGVtZW50c1tpXS5yYXduYW1lKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvKiogQ2xlYXJzIHRoZSBzdGFjayB3aXRob3V0IHRocm93aW5nIGF3YXkgZXhpc3RpbmcgUU5hbWUgb2JqZWN0cy4gKi8KLSAgICAgICAgcHVibGljIHZvaWQgY2xlYXIoKSB7Ci0gICAgICAgICAgICBmRGVwdGggPSAwOwotICAgICAgICAgICAgZkxhc3REZXB0aCA9IDA7Ci0gICAgICAgICAgICBmQ291bnQgPSAwIDsKLSAgICAgICAgICAgIGZQb3NpdGlvbiA9IGZNYXJrID0gMTsKLQotICAgICAgICB9IC8vIGNsZWFyKCkKLQotICAgICAgICAvKioKLSAgICAgICAgICogVGhpcyBmdW5jdGlvbiBpcyBhcyBhIHJlc3VsdCBvZiBvcHRpbWl6YXRpb24gZG9uZSBmb3IgZW5kRWxlbWVudCAtLQotICAgICAgICAgKiB3ZSBkb250IG5lZWQgdG8gc2V0IHRoZSB2YWx1ZSBmb3IgZXZlcnkgZW5kIGVsZW1lbnQgZW5jb3V0ZXJkLgotICAgICAgICAgKiBGb3IgV2VsbCBmb3JtZWRuZXNzIGNoZWNrcyB3ZSBjYW4gaGF2ZSB0aGUgc2FtZSBRTmFtZSBvYmplY3QgdGhhdCB3YXMgcHVzaGVkLgotICAgICAgICAgKiB0aGUgdmFsdWVzIHdpbGwgYmUgc2V0IG9ubHkgaWYgYXBwbGljYXRpb24gbmVlZCB0byBrbm93IGFib3V0IHRoZSBlbmRFbGVtZW50Ci0gICAgICAgICAqIC0tIG5lZXJhai5iYWphakBzdW4uY29tCi0gICAgICAgICAqLwotCi0gICAgICAgIHB1YmxpYyBRTmFtZSBnZXRMYXN0UG9wcGVkRWxlbWVudCgpewotICAgICAgICAgICAgcmV0dXJuIGZFbGVtZW50c1tmRGVwdGhdOwotICAgICAgICB9Ci0gICAgfSAvLyBjbGFzcyBFbGVtZW50U3RhY2sKLQotICAgIC8qKgotICAgICAqIERyaXZlcyB0aGUgcGFyc2VyIHRvIHRoZSBuZXh0IHN0YXRlL2V2ZW50IG9uIHRoZSBpbnB1dC4gUGFyc2VyIGlzIGd1YXJhbnRlZWQKLSAgICAgKiB0byBzdG9wIGF0IHRoZSBuZXh0IHN0YXRlL2V2ZW50LgotICAgICAqCi0gICAgICogSW50ZXJuYWxseSBYTUwgZG9jdW1lbnQgaXMgZGl2aWRlZCBpbnRvIHNldmVyYWwgc3RhdGVzLiBFYWNoIHN0YXRlIHJlcHJlc2VudHMKLSAgICAgKiBhIHNlY3Rpb25zIG9mIFhNTCBkb2N1bWVudC4gV2hlbiB0aGlzIGZ1bmN0aW9ucyByZXR1cm5zIG5vcm1hbGx5LCBpdCBoYXMgcmVhZAotICAgICAqIHRoZSBzZWN0aW9uIG9mIFhNTCBkb2N1bWVudCBhbmQgcmV0dXJucyB0aGUgc3RhdGUgY29ycmVzcG9uZGluZyB0byBzZWN0aW9uIG9mCi0gICAgICogZG9jdW1lbnQgd2hpY2ggaGFzIGJlZW4gcmVhZC4gRm9yIG9wdGltaXphdGlvbnMsIGEgcGFydGljdWxhciBkcml2ZXIKLSAgICAgKiBjYW4gcmVhZCBhaGVhZCBvZiB0aGUgc2VjdGlvbiBvZiBkb2N1bWVudCAoc3RhdGUgcmV0dXJuZWQpIGp1c3QgcmVhZCBhbmQKLSAgICAgKiBjYW4gbWFpbnRhaW4gYSBkaWZmZXJlbnQgaW50ZXJuYWwgc3RhdGUuCi0gICAgICoKLSAgICAgKgotICAgICAqIEBhdXRob3IgTmVlcmFqIEJhamFqLCBTdW4gTWljcm9zeXN0ZW1zCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGludGVyZmFjZSBEcml2ZXIgewotCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIERyaXZlcyB0aGUgcGFyc2VyIHRvIHRoZSBuZXh0IHN0YXRlL2V2ZW50IG9uIHRoZSBpbnB1dC4gUGFyc2VyIGlzIGd1YXJhbnRlZWQKLSAgICAgICAgICogdG8gc3RvcCBhdCB0aGUgbmV4dCBzdGF0ZS9ldmVudC4KLSAgICAgICAgICoKLSAgICAgICAgICogSW50ZXJuYWxseSBYTUwgZG9jdW1lbnQgaXMgZGl2aWRlZCBpbnRvIHNldmVyYWwgc3RhdGVzLiBFYWNoIHN0YXRlIHJlcHJlc2VudHMKLSAgICAgICAgICogYSBzZWN0aW9ucyBvZiBYTUwgZG9jdW1lbnQuIFdoZW4gdGhpcyBmdW5jdGlvbnMgcmV0dXJucyBub3JtYWxseSwgaXQgaGFzIHJlYWQKLSAgICAgICAgICogdGhlIHNlY3Rpb24gb2YgWE1MIGRvY3VtZW50IGFuZCByZXR1cm5zIHRoZSBzdGF0ZSBjb3JyZXNwb25kaW5nIHRvIHNlY3Rpb24gb2YKLSAgICAgICAgICogZG9jdW1lbnQgd2hpY2ggaGFzIGJlZW4gcmVhZC4gRm9yIG9wdGltaXphdGlvbnMsIGEgcGFydGljdWxhciBkcml2ZXIKLSAgICAgICAgICogY2FuIHJlYWQgYWhlYWQgb2YgdGhlIHNlY3Rpb24gb2YgZG9jdW1lbnQgKHN0YXRlIHJldHVybmVkKSBqdXN0IHJlYWQgYW5kCi0gICAgICAgICAqIGNhbiBtYWludGFpbiBhIGRpZmZlcmVudCBpbnRlcm5hbCBzdGF0ZS4KLSAgICAgICAgICoKLSAgICAgICAgICogQHJldHVybiBzdGF0ZSByZXByZXNlbnRpbmcgdGhlIHNlY3Rpb24gb2YgZG9jdW1lbnQganVzdCByZWFkLgotICAgICAgICAgKgotICAgICAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uICBUaHJvd24gb24gaS9vIGVycm9yLgotICAgICAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gb24gcGFyc2UgZXJyb3IuCi0gICAgICAgICAqLwotCi0gICAgICAgIHB1YmxpYyBpbnQgbmV4dCgpIHRocm93cyBJT0V4Y2VwdGlvbiwgWE5JRXhjZXB0aW9uOwotCi0gICAgfSAvLyBpbnRlcmZhY2UgRHJpdmVyCi0KLSAgICAvKioKLSAgICAgKiBEcml2ZXIgdG8gaGFuZGxlIGNvbnRlbnQgc2Nhbm5pbmcuIFRoaXMgZHJpdmVyIGlzIGNhcGFibGUgb2YgcmVhZGluZwotICAgICAqIHRoZSBmcmFnbWVudCBvZiBYTUwgZG9jdW1lbnQuIFdoZW4gaXQgaGFzIGZpbmlzaGVkIHJlYWRpbmcgZnJhZ21lbnQKLSAgICAgKiBvZiBYTUwgZG9jdW1lbnRzLCBpdCBjYW4gcGFzcyB0aGUgam9iIG9mIHJlYWRpbmcgdG8gYW5vdGhlciBkcml2ZXIuCi0gICAgICoKLSAgICAgKiBUaGlzIGNsYXNzIGhhcyBiZWVuIG1vZGlmaWVkIGFzIHBlciB0aGUgbmV3IGRlc2lnbiB3aGljaCBpcyBtb3JlIHN1aXRlZCB0bwotICAgICAqIGVmZmljaWVudGx5IGJ1aWxkIHB1bGwgcGFyc2VyLiBMb3Qgb2YgcGVyZm9ybWFuY2UgaW1wcm92ZW1lbnRzIGhhdmUgYmVlbiBkb25lIGFuZAotICAgICAqIHRoZSBjb2RlIGhhcyBiZWVuIGFkZGVkIHRvIHN1cHBvcnQgc3RheCBmdW5jdGlvbmFsaXR5L2ZlYXR1cmVzLgotICAgICAqCi0gICAgICogQGF1dGhvciBOZWVyYWogQmFqYWosIFN1biBNaWNyb3N5c3RlbXMKLSAgICAgKgotICAgICAqCi0gICAgICogQGF1dGhvciBBbmR5IENsYXJrLCBJQk0KLSAgICAgKiBAYXV0aG9yIEVyaWMgWWUsIElCTQotICAgICAqLwotICAgIHByb3RlY3RlZCBjbGFzcyBGcmFnbWVudENvbnRlbnREcml2ZXIKLSAgICAgICAgICAgIGltcGxlbWVudHMgRHJpdmVyIHsKLQotICAgICAgICAvLwotICAgICAgICAvLyBEcml2ZXIgbWV0aG9kcwotICAgICAgICAvLwotCi0gICAgICAgIC8qKgotICAgICAgICAgKiAgZGVjaWRlcyB0aGUgYXBwcm9wcmlhdGUgc3RhdGUgb2YgdGhlIHBhcnNlcgotICAgICAgICAgKi8KLSAgICAgICAgcHJpdmF0ZSB2b2lkIHN0YXJ0T2ZNYXJrdXAoKSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgICAgICAgICAgZk1hcmt1cERlcHRoKys7Ci0gICAgICAgICAgICBmaW5hbCBpbnQgY2ggPSBmRW50aXR5U2Nhbm5lci5wZWVrQ2hhcigpOwotCi0gICAgICAgICAgICBpZiAoaXNWYWxpZE5hbWVTdGFydENoYXIoY2gpIHx8IGlzVmFsaWROYW1lU3RhcnRIaWdoU3Vycm9nYXRlKGNoKSkgewotICAgICAgICAgICAgICAgIHNldFNjYW5uZXJTdGF0ZShTQ0FOTkVSX1NUQVRFX1NUQVJUX0VMRU1FTlRfVEFHKTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgc3dpdGNoKGNoKXsKLSAgICAgICAgICAgICAgICAgICAgY2FzZSAnPycgOnsKLSAgICAgICAgICAgICAgICAgICAgICAgIHNldFNjYW5uZXJTdGF0ZShTQ0FOTkVSX1NUQVRFX1BJKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZFbnRpdHlTY2FubmVyLnNraXBDaGFyKGNoLCBudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgJyEnIDp7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmRW50aXR5U2Nhbm5lci5za2lwQ2hhcihjaCwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZkVudGl0eVNjYW5uZXIuc2tpcENoYXIoJy0nLCBudWxsKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghZkVudGl0eVNjYW5uZXIuc2tpcENoYXIoJy0nLCBOYW1lVHlwZS5DT01NRU5UKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJJbnZhbGlkQ29tbWVudFN0YXJ0IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0U2Nhbm5lclN0YXRlKFNDQU5ORVJfU1RBVEVfQ09NTUVOVCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGZFbnRpdHlTY2FubmVyLnNraXBTdHJpbmcoY2RhdGEpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0U2Nhbm5lclN0YXRlKFNDQU5ORVJfU1RBVEVfQ0RBVEEgKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIXNjYW5Gb3JEb2N0eXBlSG9vaygpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiTWFya3VwTm90UmVjb2duaXplZEluQ29udGVudCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgJy8nIDp7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzZXRTY2FubmVyU3RhdGUoU0NBTk5FUl9TVEFURV9FTkRfRUxFTUVOVF9UQUcpOwotICAgICAgICAgICAgICAgICAgICAgICAgZkVudGl0eVNjYW5uZXIuc2tpcENoYXIoY2gsIE5hbWVUeXBlLkVMRU1FTlRFTkQpOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZGVmYXVsdCA6ewotICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiTWFya3VwTm90UmVjb2duaXplZEluQ29udGVudCIsIG51bGwpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgIH0vL3N0YXJ0T2ZNYXJrdXAKLQotICAgICAgICBwcml2YXRlIHZvaWQgc3RhcnRPZkNvbnRlbnQoKSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgICAgICAgICAgaWYgKGZFbnRpdHlTY2FubmVyLnNraXBDaGFyKCc8JywgbnVsbCkpIHsKLSAgICAgICAgICAgICAgICBzZXRTY2FubmVyU3RhdGUoU0NBTk5FUl9TVEFURV9TVEFSVF9PRl9NQVJLVVApOwotICAgICAgICAgICAgfSBlbHNlIGlmIChmRW50aXR5U2Nhbm5lci5za2lwQ2hhcignJicsIE5hbWVUeXBlLlJFRkVSRU5DRSkpIHsKLSAgICAgICAgICAgICAgICBzZXRTY2FubmVyU3RhdGUoU0NBTk5FUl9TVEFURV9SRUZFUkVOQ0UpIDsgLy9YTUxFdmVudC5FTlRJVFlfUkVGRVJFTkNFICk7IC8vU0NBTk5FUl9TVEFURV9SRUZFUkVOQ0UKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgLy9lbGVtZW50IGNvbnRlbnQgaXMgdGhlcmUuLgotICAgICAgICAgICAgICAgIHNldFNjYW5uZXJTdGF0ZShTQ0FOTkVSX1NUQVRFX0NIQVJBQ1RFUl9EQVRBKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfS8vc3RhcnRPZkNvbnRlbnQKLQotCi0gICAgICAgIC8qKgotICAgICAgICAgKgotICAgICAgICAgKiBTQ0FOTkVSX1NUQVRFX0NPTlRFTlQgYW5kIFNDQU5ORVJfU1RBVEVfU1RBUlRfT0ZfTUFSS1VQIGFyZSB0d28gc3VwZXIgc3RhdGVzIG9mIHRoZSBwYXJzZXIuCi0gICAgICAgICAqIEF0IGFueSBwb2ludCBvZiB0aW1lIHdoZW4gaW4gZG91YnQgb3ZlciB0aGUgY3VycmVudCBzdGF0ZSBvZiB0aGUgcGFyc2VyLCB0aGUgc3RhdGUgc2hvdWxkIGJlCi0gICAgICAgICAqIHNldCB0byBTQ0FOTkVSX1NUQVRFX0NPTlRFTlQuIFBhcnNlciB3aWxsIGF1dG9tYXRpY2FsbHkgcmV2aXZlIGl0c2VsZiBhbmQgd2lsbCBzZXQgc3RhdGUgb2YKLSAgICAgICAgICogdGhlIHBhcnNlciB0byBvbmUgb2YgaXRzIHN1YiBzdGF0ZS4KLSAgICAgICAgICogc3ViIHN0YXRlcyBhcmUgZGVmaW5lZCBpbiB0aGUgcGFyc2VyIG9uIHRoZSBiYXNpcyBvZiBkaWZmZXJlbnQgWE1MIGNvbXBvbmVudCBsaWtlCi0gICAgICAgICAqIFNDQU5ORVJfU1RBVEVfRU5USVRZX1JFRkVSRU5DRSAsIFNDQU5ORVJfU1RBVEVfU1RBUlRfRUxFTUVOVCwgU0NBTk5FUl9TVEFURV9DREFUQSBldGMuLgotICAgICAgICAgKiBUaGVzZSBzdWIgc3RhdGVzIGhlbHAgdGhlIHBhcnNlciB0byBoYXZlIGZpbmUgY29udHJvbCBvdmVyIHRoZSBwYXJzaW5nLiBUaGVzZSBhcmUgdGhlCi0gICAgICAgICAqIGRpZmZlcmVudCBtaWxlcG9zdCwgcGFyc2VyIHN0b3BzIGF0IGVhY2ggc3ViIHN0YXRlIChtaWxlcG9zdCkuIEJhc2VkIG9uIHRoaXMgc3RhdGUgaXQgaXMKLSAgICAgICAgICogZGVjaWRlZCBpZiBwYXJlc3IgbmVlZHMgdG8gc3RvcCBhdCBuZXh0IG1pbGVwb3N0ID8/Ci0gICAgICAgICAqCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgdm9pZCBkZWNpZGVTdWJTdGF0ZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgICAgICB3aGlsZSggZlNjYW5uZXJTdGF0ZSA9PSBTQ0FOTkVSX1NUQVRFX0NPTlRFTlQgfHwgZlNjYW5uZXJTdGF0ZSA9PSBTQ0FOTkVSX1NUQVRFX1NUQVJUX09GX01BUktVUCl7Ci0KLSAgICAgICAgICAgICAgICBzd2l0Y2ggKGZTY2FubmVyU3RhdGUpIHsKLQotICAgICAgICAgICAgICAgICAgICBjYXNlIFNDQU5ORVJfU1RBVEVfQ09OVEVOVDogewotICAgICAgICAgICAgICAgICAgICAgICAgc3RhcnRPZkNvbnRlbnQoKSA7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgIGNhc2UgU0NBTk5FUl9TVEFURV9TVEFSVF9PRl9NQVJLVVA6IHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0T2ZNYXJrdXAoKSA7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfS8vZGVjaWRlU3ViU3RhdGUKLQotICAgICAgICAvKioKLSAgICAgICAgICogRHJpdmVzIHRoZSBwYXJzZXIgdG8gdGhlIG5leHQgc3RhdGUvZXZlbnQgb24gdGhlIGlucHV0LiBQYXJzZXIgaXMgZ3VhcmFudGVlZAotICAgICAgICAgKiB0byBzdG9wIGF0IHRoZSBuZXh0IHN0YXRlL2V2ZW50LiBJbnRlcm5hbGx5IFhNTCBkb2N1bWVudAotICAgICAgICAgKiBpcyBkaXZpZGVkIGludG8gc2V2ZXJhbCBzdGF0ZXMuIEVhY2ggc3RhdGUgcmVwcmVzZW50cyBhIHNlY3Rpb25zIG9mIFhNTAotICAgICAgICAgKiBkb2N1bWVudC4gV2hlbiB0aGlzIGZ1bmN0aW9ucyByZXR1cm5zIG5vcm1hbGx5LCBpdCBoYXMgcmVhZCB0aGUgc2VjdGlvbgotICAgICAgICAgKiBvZiBYTUwgZG9jdW1lbnQgYW5kIHJldHVybnMgdGhlIHN0YXRlIGNvcnJlc3BvbmRpbmcgdG8gc2VjdGlvbiBvZgotICAgICAgICAgKiBkb2N1bWVudCB3aGljaCBoYXMgYmVlbiByZWFkLiBGb3Igb3B0aW1pemF0aW9ucywgYSBwYXJ0aWN1bGFyIGRyaXZlcgotICAgICAgICAgKiBjYW4gcmVhZCBhaGVhZCBvZiB0aGUgc2VjdGlvbiBvZiBkb2N1bWVudCAoc3RhdGUgcmV0dXJuZWQpIGp1c3QgcmVhZCBhbmQKLSAgICAgICAgICogY2FuIG1haW50YWluIGEgZGlmZmVyZW50IGludGVybmFsIHN0YXRlLgotICAgICAgICAgKgotICAgICAgICAgKiBTdGF0ZSByZXR1cm5lZCBjb3JyZXNwb25kcyB0byBTdGF4IHN0YXRlcy4KLSAgICAgICAgICoKLSAgICAgICAgICogQHJldHVybiBzdGF0ZSByZXByZXNlbnRpbmcgdGhlIHNlY3Rpb24gb2YgZG9jdW1lbnQganVzdCByZWFkLgotICAgICAgICAgKgotICAgICAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uICBUaHJvd24gb24gaS9vIGVycm9yLgotICAgICAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gb24gcGFyc2UgZXJyb3IuCi0gICAgICAgICAqLwotCi0gICAgICAgIHB1YmxpYyBpbnQgbmV4dCgpIHRocm93cyBJT0V4Y2VwdGlvbiwgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgICAgIHdoaWxlICh0cnVlKSB7Ci0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIGlmKERFQlVHX05FWFQpewotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIk5PVyBJTiBGcmFnbWVudENvbnRlbnREcml2ZXIiKTsKLSAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJFbnRlcmluZyB0aGUgRnJhZ21lbnRDb250ZW50RHJpdmVyIHdpdGggPSAiICsgZ2V0U2Nhbm5lclN0YXRlTmFtZShmU2Nhbm5lclN0YXRlKSk7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgLy9kZWNpZGUgdGhlIGFjdHVhbCBzdWIgc3RhdGUgb2YgdGhlIHNjYW5uZXIuRm9yIG1vcmUgaW5mb3JtYXRpb24gcmVmZXIgdG8gdGhlIGphdmFkb2Mgb2YKLSAgICAgICAgICAgICAgICAvL2RlY2lkZVN1YlN0YXRlLgotCi0gICAgICAgICAgICAgICAgc3dpdGNoIChmU2Nhbm5lclN0YXRlKSB7Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgU0NBTk5FUl9TVEFURV9DT05URU5UOiB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgY2ggPSBmRW50aXR5U2Nhbm5lci5wZWVrQ2hhcigpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNoID09ICc8JykgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZFbnRpdHlTY2FubmVyLnNjYW5DaGFyKG51bGwpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldFNjYW5uZXJTdGF0ZShTQ0FOTkVSX1NUQVRFX1NUQVJUX09GX01BUktVUCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNoID09ICcmJykgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZFbnRpdHlTY2FubmVyLnNjYW5DaGFyKE5hbWVUeXBlLlJFRkVSRU5DRSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0U2Nhbm5lclN0YXRlKFNDQU5ORVJfU1RBVEVfUkVGRVJFTkNFKSA7IC8vWE1MRXZlbnQuRU5USVRZX1JFRkVSRU5DRSApOyAvL1NDQU5ORVJfU1RBVEVfUkVGRVJFTkNFCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vZWxlbWVudCBjb250ZW50IGlzIHRoZXJlLi4KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRTY2FubmVyU3RhdGUoU0NBTk5FUl9TVEFURV9DSEFSQUNURVJfREFUQSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICBjYXNlIFNDQU5ORVJfU1RBVEVfU1RBUlRfT0ZfTUFSS1VQOiB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzdGFydE9mTWFya3VwKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgfS8vY2FzZTogU0NBTk5FUl9TVEFURV9TVEFSVF9PRl9NQVJLVVAKLQotICAgICAgICAgICAgICAgIH0vL2VuZCBvZiBzd2l0Y2gKLSAgICAgICAgICAgICAgICAvL2RlY2lkZVN1YlN0YXRlKCkgOwotCi0gICAgICAgICAgICAgICAgLy9kbyBzb21lIHNwZWNpYWwgaGFuZGxpbmcgaWYgaXNDb2FsZXNjZSBpcyBzZXQgdG8gdHJ1ZS4KLSAgICAgICAgICAgICAgICBpZihmSXNDb2FsZXNjZSl7Ci0gICAgICAgICAgICAgICAgICAgIGZVc2VidWZmZXIgPSB0cnVlIDsKLSAgICAgICAgICAgICAgICAgICAgLy9pZiB0aGUgbGFzdCBzZWN0aW9uIHdhcyBjaGFyYWN0ZXIgZGF0YQotICAgICAgICAgICAgICAgICAgICBpZihmTGFzdFNlY3Rpb25XYXNDaGFyYWN0ZXJEYXRhKXsKLQotICAgICAgICAgICAgICAgICAgICAgICAgLy9pZiB3ZSBkb250IGVuY291bnRlciBhbnkgQ0RBVEEgb3IgRU5JVFkgUkVGRVJFTkNFIGFuZCBjdXJyZW50IHN0YXRlIGlzIGFsc28gbm90IFNDQU5ORVJfU1RBVEVfQ0hBUkFDVEVSX0RBVEEKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vcmV0dXJuIHRoZSBsYXN0IHNjYW5uZWQgY2hhcmFjdHJlciBkYXRhLgotICAgICAgICAgICAgICAgICAgICAgICAgaWYoKGZTY2FubmVyU3RhdGUgIT0gU0NBTk5FUl9TVEFURV9DREFUQSkgJiYgKGZTY2FubmVyU3RhdGUgIT0gU0NBTk5FUl9TVEFURV9SRUZFUkVOQ0UpCi0gICAgICAgICAgICAgICAgICAgICAgICAmJiAoZlNjYW5uZXJTdGF0ZSAhPSBTQ0FOTkVSX1NUQVRFX0NIQVJBQ1RFUl9EQVRBKSl7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZkxhc3RTZWN0aW9uV2FzQ2hhcmFjdGVyRGF0YSA9IGZhbHNlOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBYTUxFdmVudC5DSEFSQUNURVJTOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ly9pZiBsYXN0IHNlY3Rpb24gd2FzIENEQVRBIG9yIEVOVElUWSBSRUZFUkVOQ0UKLSAgICAgICAgICAgICAgICAgICAgLy94eHg6IHRoZXJlIG1pZ2h0IGJlIGFub3RoZXIgZW50aXR5IHJlZmVyZW5jZSBvciBDREFUQSBhZnRlciB0aGlzCi0gICAgICAgICAgICAgICAgICAgIC8vPGZvbz5ibGFoIGJsYWggJmFtcDsmbHQ7PCFbQ0RBVEFbW2FhXV0+YmxhaCBibGFoPC9mb28+Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYoKGZMYXN0U2VjdGlvbldhc0NEYXRhIHx8IGZMYXN0U2VjdGlvbldhc0VudGl0eVJlZmVyZW5jZSkpewotICAgICAgICAgICAgICAgICAgICAgICAgLy9hbmQgY3VycmVudCBzdGF0ZSBpcyBub3QgU0NBTk5FUl9TVEFURV9DSEFSQUNURVJfREFUQQotICAgICAgICAgICAgICAgICAgICAgICAgLy9vciBTQ0FOTkVSX1NUQVRFX0NEQVRBIG9yIFNDQU5ORVJfU1RBVEVfUkVGRVJFTkNFCi0gICAgICAgICAgICAgICAgICAgICAgICAvL3RoaXMgbWVhbnMgdGhlcmUgaXMgbm90aGluZyBtb3JlIHRvIGJlIGNvYWxlc2NlZC4KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vcmV0dXJuIHRoZSBDSEFSQUNURVJTIGV2ZW50LgotICAgICAgICAgICAgICAgICAgICAgICAgaWYoKGZTY2FubmVyU3RhdGUgIT0gU0NBTk5FUl9TVEFURV9DREFUQSkgJiYgKGZTY2FubmVyU3RhdGUgIT0gU0NBTk5FUl9TVEFURV9SRUZFUkVOQ0UpCi0gICAgICAgICAgICAgICAgICAgICAgICAmJiAoZlNjYW5uZXJTdGF0ZSAhPSBTQ0FOTkVSX1NUQVRFX0NIQVJBQ1RFUl9EQVRBKSl7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmTGFzdFNlY3Rpb25XYXNDRGF0YSA9IGZhbHNlOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZMYXN0U2VjdGlvbldhc0VudGl0eVJlZmVyZW5jZSA9IGZhbHNlOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBYTUxFdmVudC5DSEFSQUNURVJTOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotCi0KLSAgICAgICAgICAgICAgICBpZihERUJVR19ORVhUKXsKLSAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJBY3R1YWwgc2Nhbm5lciBzdGF0ZSBzZXQgYnkgZGVjaWRlU3ViU3RhdGUgaXMgPSAiICsgZ2V0U2Nhbm5lclN0YXRlTmFtZShmU2Nhbm5lclN0YXRlKSk7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgc3dpdGNoKGZTY2FubmVyU3RhdGUpewotCi0gICAgICAgICAgICAgICAgICAgIGNhc2UgWE1MRXZlbnQuU1RBUlRfRE9DVU1FTlQgOgotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFhNTEV2ZW50LlNUQVJUX0RPQ1VNRU5UOwotCi0gICAgICAgICAgICAgICAgICAgIGNhc2UgU0NBTk5FUl9TVEFURV9TVEFSVF9FTEVNRU5UX1RBRyA6ewotCi0gICAgICAgICAgICAgICAgICAgICAgICAvL3h4eCB0aGlzIGZ1bmN0aW9uIHJldHVybnMgdHJ1ZSB3aGVuIGVsZW1lbnQgaXMgZW1wdHkuLiBjYW4gYmUgbGlua2VkIHRvIGVuZCBlbGVtZW50IGV2ZW50LgotICAgICAgICAgICAgICAgICAgICAgICAgLy9yZXR1cm5zIHRydWUgaWYgdGhlIGVsZW1lbnQgaXMgZW1wdHkKLSAgICAgICAgICAgICAgICAgICAgICAgIGZFbXB0eUVsZW1lbnQgPSBzY2FuU3RhcnRFbGVtZW50KCkgOwotICAgICAgICAgICAgICAgICAgICAgICAgLy9pZiB0aGUgZWxlbWVudCBpcyBlbXB0eSB0aGUgbmV4dCBldmVudCBpcyAiZW5kIGVsZW1lbnQiCi0gICAgICAgICAgICAgICAgICAgICAgICBpZihmRW1wdHlFbGVtZW50KXsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRTY2FubmVyU3RhdGUoU0NBTk5FUl9TVEFURV9FTkRfRUxFTUVOVF9UQUcpOwotICAgICAgICAgICAgICAgICAgICAgICAgfWVsc2V7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9zZXQgdGhlIG5leHQgcG9zc2libGUgc3RhdGUKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRTY2FubmVyU3RhdGUoU0NBTk5FUl9TVEFURV9DT05URU5UKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBYTUxFdmVudC5TVEFSVF9FTEVNRU5UIDsKLSAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgIGNhc2UgU0NBTk5FUl9TVEFURV9DSEFSQUNURVJfREFUQTogewotICAgICAgICAgICAgICAgICAgICAgICAgaWYoREVCVUdfQ09BTEVTQ0UpewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiZkxhc3RTZWN0aW9uV2FzQ0RhdGEgPSAiICsgZkxhc3RTZWN0aW9uV2FzQ0RhdGEpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiZklzQ29hbGVzY2UgPSAiICsgZklzQ29hbGVzY2UpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgLy9pZiBsYXN0IHNlY3Rpb24gd2FzIGVpdGhlciBlbnRpdHkgcmVmZXJlbmNlIG9yIGNkYXRhIG9yIGNoYXJhY3RlciBkYXRhIHdlIHNob3VsZCBiZSB1c2luZyBidWZmZXIKLSAgICAgICAgICAgICAgICAgICAgICAgIGZVc2VidWZmZXIgPSBmTGFzdFNlY3Rpb25XYXNFbnRpdHlSZWZlcmVuY2UgfHwgZkxhc3RTZWN0aW9uV2FzQ0RhdGEgfHwgZkxhc3RTZWN0aW9uV2FzQ2hhcmFjdGVyRGF0YSA7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vV2hlbiBjb2FsZXNjZSBpcyBzZXQgdG8gdHJ1ZSBhbmQgbGFzdCBzdGF0ZSB3YXMgUkVGRVJFTkNFIG9yIENEQVRBIG9yIENIQVJBQ1RFUl9EQVRBLCBidWZmZXIgc2hvdWxkIG5vdCBiZSBjbGVhcmVkLgotICAgICAgICAgICAgICAgICAgICAgICAgaWYoIGZJc0NvYWxlc2NlICYmIChmTGFzdFNlY3Rpb25XYXNFbnRpdHlSZWZlcmVuY2UgfHwgZkxhc3RTZWN0aW9uV2FzQ0RhdGEgfHwgZkxhc3RTZWN0aW9uV2FzQ2hhcmFjdGVyRGF0YSkgKXsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmTGFzdFNlY3Rpb25XYXNFbnRpdHlSZWZlcmVuY2UgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmTGFzdFNlY3Rpb25XYXNDRGF0YSA9IGZhbHNlOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZMYXN0U2VjdGlvbldhc0NoYXJhY3RlckRhdGEgPSB0cnVlIDsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmVXNlYnVmZmVyID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH1lbHNlewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vY2xlYXIgdGhlIGJ1ZmZlcgotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZDb250ZW50QnVmZmVyLmNsZWFyKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vc2V0IHRoZSBmVGVtcFN0cmluZyBsZW5ndGggdG8gMCBiZWZvcmUgcGFzc2luZyBpdCBvbiB0byBzY2FuQ29udGVudAotICAgICAgICAgICAgICAgICAgICAgICAgLy9zY2FuQ29udGVudCBzZXRzIHRoZSBjb3JyZWN0IGNvLW9yZGluYXRlcyBhcyBwZXIgdGhlIGNvbnRlbnQgcmVhZAotICAgICAgICAgICAgICAgICAgICAgICAgZlRlbXBTdHJpbmcubGVuZ3RoID0gMDsKLSAgICAgICAgICAgICAgICAgICAgICAgIGludCBjID0gZkVudGl0eVNjYW5uZXIuc2NhbkNvbnRlbnQoZlRlbXBTdHJpbmcpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYoREVCVUcpewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiZlRlbXBTdHJpbmcgPSAiICsgZlRlbXBTdHJpbmcpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgaWYoZkVudGl0eVNjYW5uZXIuc2tpcENoYXIoJzwnLCBudWxsKSl7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9jaGVjayBpZiB3ZSBoYXZlIHJlYWNoZWQgZW5kIG9mIGVsZW1lbnQKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihmRW50aXR5U2Nhbm5lci5za2lwQ2hhcignLycsIE5hbWVUeXBlLkVMRU1FTlRFTkQpKXsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9pbmNyZWFzZSB0aGUgbWFyayB1cCBkZXB0aAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmTWFya3VwRGVwdGgrKzsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkxhc3RTZWN0aW9uV2FzQ2hhcmFjdGVyRGF0YSA9IGZhbHNlOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRTY2FubmVyU3RhdGUoU0NBTk5FUl9TVEFURV9FTkRfRUxFTUVOVF9UQUcpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2NoZWNrIGlmIGl0cyBzdGFydCBvZiBuZXcgZWxlbWVudAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1lbHNlIGlmKFhNTENoYXIuaXNOYW1lU3RhcnQoZkVudGl0eVNjYW5uZXIucGVla0NoYXIoKSkpewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmTWFya3VwRGVwdGgrKzsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkxhc3RTZWN0aW9uV2FzQ2hhcmFjdGVyRGF0YSA9IGZhbHNlOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRTY2FubmVyU3RhdGUoU0NBTk5FUl9TVEFURV9TVEFSVF9FTEVNRU5UX1RBRyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfWVsc2V7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldFNjYW5uZXJTdGF0ZShTQ0FOTkVSX1NUQVRFX1NUQVJUX09GX01BUktVUCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vdGhlcmUgY2FuIGJlIGNkYXRhIGFoZWFkIGlmIGNvYWxlc2NlIGlzIHRydWUgd2Ugc2hvdWxkIGNhbGwgYWdhaW4KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoZklzQ29hbGVzY2UpewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZlVzZWJ1ZmZlciA9IHRydWU7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmTGFzdFNlY3Rpb25XYXNDaGFyYWN0ZXJEYXRhID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZDb250ZW50QnVmZmVyLmFwcGVuZChmVGVtcFN0cmluZyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmVGVtcFN0cmluZy5sZW5ndGggPSAwOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9pbiBjYXNlIGxhc3Qgc2VjdGlvbiB3YXMgZWl0aGVyIGVudGl0eSByZWZlcmVuY2Ugb3IgY2RhdGEgb3IgY2hhcmFjdGVyIGRhdGEgLS0gd2Ugc2hvdWxkIGJlIHVzaW5nIGJ1ZmZlcgotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKGZVc2VidWZmZXIpewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmQ29udGVudEJ1ZmZlci5hcHBlbmQoZlRlbXBTdHJpbmcpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmVGVtcFN0cmluZy5sZW5ndGggPSAwOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihERUJVRyl7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiTk9UIFVTSU5HIFRIRSBCVUZGRVIsIFNUUklORyA9ICIgKyBmVGVtcFN0cmluZy50b1N0cmluZygpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoZHRkR3JhbW1hclV0aWwhPSBudWxsICYmIGR0ZEdyYW1tYXJVdGlsLmlzSWdub3JhYmxlV2hpdGVTcGFjZShmQ29udGVudEJ1ZmZlcikpewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihERUJVRylTeXN0ZW0ub3V0LnByaW50bG4oIlJldHVybiBTUEFDRSBFVkVOVCIpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gWE1MRXZlbnQuU1BBQ0U7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfWVsc2UKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFhNTEV2ZW50LkNIQVJBQ1RFUlM7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZXsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmVXNlYnVmZmVyID0gdHJ1ZSA7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoREVCVUcpewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oImZDb250ZW50QnVmZmVyID0gIiArIGZDb250ZW50QnVmZmVyKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJmVGVtcFN0cmluZyA9ICIgKyBmVGVtcFN0cmluZyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZDb250ZW50QnVmZmVyLmFwcGVuZChmVGVtcFN0cmluZyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZlRlbXBTdHJpbmcubGVuZ3RoID0gMDsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjID09ICdccicpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihERUJVRyl7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiJ1xyJyBjaGFyYWN0ZXIgZm91bmQiKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaGFwcGVucyB3aGVuIHRoZXJlIGlzIHRoZSBjaGFyYWN0ZXIgcmVmZXJlbmNlICYjMTM7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy94eHg6IFdlIGtub3cgdGhlIG5leHQgY2hyYWN0ZXIuLiB3ZSBzaG91bGQganVzdCBza2lwIGl0IGFuZCBhZGQgJ10nIGRpcmVjdGxyeQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZFbnRpdHlTY2FubmVyLnNjYW5DaGFyKG51bGwpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZVc2VidWZmZXIgPSB0cnVlOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZDb250ZW50QnVmZmVyLmFwcGVuZCgoY2hhciljKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjID0gLTEgOwotICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjID09ICddJykgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vZlN0cmluZ0J1ZmZlci5jbGVhcigpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8veHh4OiBXZSBrbm93IHRoZSBuZXh0IGNocmFjdGVyLi4gd2Ugc2hvdWxkIGp1c3Qgc2tpcCBpdCBhbmQgYWRkICddJyBkaXJlY3RscnkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmVXNlYnVmZmVyID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmQ29udGVudEJ1ZmZlci5hcHBlbmQoKGNoYXIpZkVudGl0eVNjYW5uZXIuc2NhbkNoYXIobnVsbCkpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHJlbWVtYmVyIHdoZXJlIHdlIGFyZSBpbiBjYXNlIHdlIGdldCBhbiBlbmRFbnRpdHkgYmVmb3JlIHdlCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY291bGQgZmx1c2ggdGhlIGJ1ZmZlciBvdXQgLSB0aGlzIGhhcHBlbnMgd2hlbiB3ZSdyZSBwYXJzaW5nIGFuCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZW50aXR5IHdoaWNoIGVuZHMgd2l0aCBhIF0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmSW5TY2FuQ29udGVudCA9IHRydWU7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBXZSB3b3JrIG9uIGEgc2luZ2xlIGNoYXJhY3RlciBiYXNpcyB0byBoYW5kbGUgY2FzZXMgc3VjaCBhczoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAnXV1dPicgd2hpY2ggd2UgbWlnaHQgb3RoZXJ3aXNlIG1pc3MuCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZkVudGl0eVNjYW5uZXIuc2tpcENoYXIoJ10nLCBudWxsKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmQ29udGVudEJ1ZmZlci5hcHBlbmQoJ10nKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGZFbnRpdHlTY2FubmVyLnNraXBDaGFyKCddJywgbnVsbCkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZDb250ZW50QnVmZmVyLmFwcGVuZCgnXScpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmRW50aXR5U2Nhbm5lci5za2lwQ2hhcignPicsIG51bGwpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJDREVuZEluQ29udGVudCIsIG51bGwpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMgPSAtMSA7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZkluU2NhbkNvbnRlbnQgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAgICAgZG97Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy94eHg6IHdlIHNob3VsZCBiZSB1c2luZyBvbmx5IG9uZSBidWZmZXIuLgotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHdlIG5lZWQgbm90IHRvIGdyb3cgdGhlIGJ1ZmZlciBvbmx5IHdoZW4gaXNDb2FsZXNjZSgpIGlzIG5vdCB0cnVlOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGMgPT0gJzwnKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZFbnRpdHlTY2FubmVyLnNjYW5DaGFyKG51bGwpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRTY2FubmVyU3RhdGUoU0NBTk5FUl9TVEFURV9TVEFSVF9PRl9NQVJLVVApOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ly94eHggd2hhdCBzaG91bGQgYmUgdGhlIGJlaGF2aW9yIGlmIGVudGl0eSByZWZlcmVuY2UgaXMgcHJlc2VudCBpbiB0aGUgY29udGVudCA/Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoYyA9PSAnJicpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkVudGl0eVNjYW5uZXIuc2NhbkNoYXIoTmFtZVR5cGUuUkVGRVJFTkNFKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0U2Nhbm5lclN0YXRlKFNDQU5ORVJfU1RBVEVfUkVGRVJFTkNFKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfS8vL3h4eCBzaW5jZSB0aGlzIHBhcnQgaXMgYWxzbyBjaGFyYWN0ZXJzLCBpdCBzaG91bGQgYmUgbWVyZ2VkLi4uCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoYyAhPSAtMSAmJiBpc0ludmFsaWRMaXRlcmFsKGMpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChYTUxDaGFyLmlzSGlnaFN1cnJvZ2F0ZShjKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc3BlY2lhbCBjYXNlOiBzdXJyb2dhdGVzCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2FuU3Vycm9nYXRlcyhmQ29udGVudEJ1ZmZlcikgOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0U2Nhbm5lclN0YXRlKFNDQU5ORVJfU1RBVEVfQ09OVEVOVCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJJbnZhbGlkQ2hhckluQ29udGVudCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW50ZWdlci50b1N0cmluZyhjLCAxNil9KTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmRW50aXR5U2Nhbm5lci5zY2FuQ2hhcihudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy94eHg6IHNjYW5Db250ZW50IGFsc28gZ2l2ZXMgY2hhcmFjdGVyIGNhbGxiYWNrLgotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMgPSBzY2FuQ29udGVudChmQ29udGVudEJ1ZmZlcikgOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vd2Ugc2hvdWxkIG5vdCBiZSBpdGVyYXRpbmcgYWdhaW4gaWYgZklzQ29hbGVzY2UgaXMgbm90IHNldCB0byB0cnVlCi0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZighZklzQ29hbGVzY2UpewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRTY2FubmVyU3RhdGUoU0NBTk5FUl9TVEFURV9DT05URU5UKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgICAgICB9d2hpbGUodHJ1ZSk7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vaWYgKGZEb2N1bWVudEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gIGZEb2N1bWVudEhhbmRsZXIuY2hhcmFjdGVycyhmQ29udGVudEJ1ZmZlciwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvL30KLSAgICAgICAgICAgICAgICAgICAgICAgIGlmKERFQlVHKVN5c3RlbS5vdXQucHJpbnRsbigiVVNJTkcgVEhFIEJVRkZFUiwgU1RSSU5HIFNUQVJUPSIgKyBmQ29udGVudEJ1ZmZlci50b1N0cmluZygpICsiPUVORCIpOwotICAgICAgICAgICAgICAgICAgICAgICAgLy9pZiBmSXNDb2FsZXNjZSBpcyB0cnVlIHRoZXJlIG1pZ2h0IGJlIG1vcmUgZGF0YSBzbyBjYWxsIGZEcml2ZXIubmV4dCgpCi0gICAgICAgICAgICAgICAgICAgICAgICBpZihmSXNDb2FsZXNjZSl7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZkxhc3RTZWN0aW9uV2FzQ2hhcmFjdGVyRGF0YSA9IHRydWUgOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgICAgICAgICAgICAgfWVsc2V7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoZHRkR3JhbW1hclV0aWwhPSBudWxsICYmIGR0ZEdyYW1tYXJVdGlsLmlzSWdub3JhYmxlV2hpdGVTcGFjZShmQ29udGVudEJ1ZmZlcikpewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihERUJVRylTeXN0ZW0ub3V0LnByaW50bG4oIlJldHVybiBTUEFDRSBFVkVOVCIpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gWE1MRXZlbnQuU1BBQ0U7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBYTUxFdmVudC5DSEFSQUNURVJTIDsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgIGNhc2UgU0NBTk5FUl9TVEFURV9FTkRfRUxFTUVOVF9UQUcgOnsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmKGZFbXB0eUVsZW1lbnQpewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vc2V0IGl0IGJhY2sgdG8gZmFsc2UuCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZkVtcHR5RWxlbWVudCA9IGZhbHNlOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldFNjYW5uZXJTdGF0ZShTQ0FOTkVSX1NUQVRFX0NPTlRFTlQpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vY2hlY2sgdGhlIGNhc2Ugd2hlbiB0aGVyZSBpcyBjb21tZW50IGFmdGVyIHNpbmdsZSBlbGVtZW50IGRvY3VtZW50Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy88Zm9vLz4gYW5kIHNvbWUgY29tbWVudCBhZnRlciB0aGlzCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChmTWFya3VwRGVwdGggPT0gMCAmJiBlbGVtZW50RGVwdGhJc1plcm9Ib29rKCkgKSA/IFhNTEV2ZW50LkVORF9FTEVNRU5UIDogWE1MRXZlbnQuRU5EX0VMRU1FTlQgOwotCi0gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYoc2NhbkVuZEVsZW1lbnQoKSA9PSAwKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9JdCBpcyBsYXN0IGVsZW1lbnQgb2YgdGhlIGRvY3VtZW50Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVsZW1lbnREZXB0aElzWmVyb0hvb2soKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2lmIGVsZW1lbnQgZGVwdGggaXMgemVybyAsIGl0IGluZGljYXRlcyB0aGUgZW5kIG9mIHRoZSBkb2N1bWVudAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3RoZSBzdGF0ZSBzaG91bGRuJ3QgYmUgc2V0LCBiZWNhdXNlIGl0IGlzIHNldCBieSBlbGVtZW50RGVwdGhJc1plcm9Ib29rKCkgZnVuY3Rpb24KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy94eHggdW5kZXJzdGFuZCB0aGlzIHBvaW50IG9uY2UgYWdhaW4uLgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gWE1MRXZlbnQuRU5EX0VMRU1FTlQgOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgc2V0U2Nhbm5lclN0YXRlKFNDQU5ORVJfU1RBVEVfQ09OVEVOVCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gWE1MRXZlbnQuRU5EX0VMRU1FTlQgOwotICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgY2FzZSBTQ0FOTkVSX1NUQVRFX0NPTU1FTlQ6IHsgLy9TQ0FOTkVSX1NUQVRFX0NPTU1FTlQ6Ci0gICAgICAgICAgICAgICAgICAgICAgICBzY2FuQ29tbWVudCgpOwotICAgICAgICAgICAgICAgICAgICAgICAgc2V0U2Nhbm5lclN0YXRlKFNDQU5ORVJfU1RBVEVfQ09OVEVOVCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gWE1MRXZlbnQuQ09NTUVOVDsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgY2FzZSBTQ0FOTkVSX1NUQVRFX1BJOnsgLy9TQ0FOTkVSX1NUQVRFX1BJOiB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvL2NsZWFyIHRoZSBidWZmZXIgZmlyc3QKLSAgICAgICAgICAgICAgICAgICAgICAgIGZDb250ZW50QnVmZmVyLmNsZWFyKCkgOwotICAgICAgICAgICAgICAgICAgICAgICAgLy94eHg6IHdoaWNoIGJ1ZmZlciBzaG91bGQgYmUgcGFzc2VkLiBJZGVhbGx5IHdlIHNob3VsZG4ndCBoYXZlCi0gICAgICAgICAgICAgICAgICAgICAgICAvL21vcmUgdGhhbiB0d28gYnVmZmVycyAtLQotICAgICAgICAgICAgICAgICAgICAgICAgLy94eHg6IHdoZXJlIHNob3VsZCB3ZSBhZGQgdGhlIHN3aXRjaCBmb3IgYnVmZmVyaW5nLgotICAgICAgICAgICAgICAgICAgICAgICAgc2NhblBJKGZDb250ZW50QnVmZmVyKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHNldFNjYW5uZXJTdGF0ZShTQ0FOTkVSX1NUQVRFX0NPTlRFTlQpOwotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFhNTEV2ZW50LlBST0NFU1NJTkdfSU5TVFJVQ1RJT047Ci0gICAgICAgICAgICAgICAgICAgICAgICAvL2JyZWFrOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgU0NBTk5FUl9TVEFURV9DREFUQSA6eyAvL1NDQU5ORVJfU1RBVEVfQ0RBVEE6IHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8veHh4OiBXaGF0IGlmIENEQVRBIGlzIHRoZSBmaXJzdCBldmVudAotICAgICAgICAgICAgICAgICAgICAgICAgLy88Zm9vPjwhW0NEQVRBW2hlbGxvPD48Pl1dPmFwcGVuZDwvZm9vPgotCi0gICAgICAgICAgICAgICAgICAgICAgICAvL3dlIHNob3VsZCBub3QgY2xlYXIgdGhlIGJ1ZmZlciBvbmx5IHdoZW4gdGhlIGxhc3Qgc3RhdGUgd2FzIGVpdGhlciBTQ0FOTkVSX1NUQVRFX1JFRkVSRU5DRSBvcgotICAgICAgICAgICAgICAgICAgICAgICAgLy9TQ0FOTkVSX1NUQVRFX0NIQVJBQ1RFUl9EQVRBIG9yIFNDQU5ORVJfU1RBVEVfUkVGRVJFTkNFCi0gICAgICAgICAgICAgICAgICAgICAgICBpZihmSXNDb2FsZXNjZSAmJiAoIGZMYXN0U2VjdGlvbldhc0VudGl0eVJlZmVyZW5jZSB8fCBmTGFzdFNlY3Rpb25XYXNDRGF0YSB8fCBmTGFzdFNlY3Rpb25XYXNDaGFyYWN0ZXJEYXRhKSl7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZkxhc3RTZWN0aW9uV2FzQ0RhdGEgPSB0cnVlIDsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmTGFzdFNlY3Rpb25XYXNFbnRpdHlSZWZlcmVuY2UgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmTGFzdFNlY3Rpb25XYXNDaGFyYWN0ZXJEYXRhID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ly9pZiB3ZSBkb250IG5lZWQgdG8gY29hbGVzY2UgY2xlYXIgdGhlIGJ1ZmZlcgotICAgICAgICAgICAgICAgICAgICAgICAgZWxzZXsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmQ29udGVudEJ1ZmZlci5jbGVhcigpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgZlVzZWJ1ZmZlciA9IHRydWU7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvL0NEQVRBIHNlY3Rpb24gaXMgY29tcGxldGVseSByZWFkIGluIGFsbCB0aGUgY2FzZS4KLSAgICAgICAgICAgICAgICAgICAgICAgIHNjYW5DREFUQVNlY3Rpb24oZkNvbnRlbnRCdWZmZXIgLCB0cnVlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHNldFNjYW5uZXJTdGF0ZShTQ0FOTkVSX1NUQVRFX0NPTlRFTlQpOwotICAgICAgICAgICAgICAgICAgICAgICAgLy8xLiBpZiBmSXNDb2FsZXNjZSBpcyBzZXQgdG8gdHJ1ZSB3ZSBzZXQgdGhlIHZhcmlhYmxlIGZMYXN0U2VjdGlvbldhc0NEYXRhIHRvIHRydWUKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vYW5kIGp1c3QgY2FsbCBmRGlzcGF0Y2hlLm5leHQoKS4gU2luY2Ugd2UgaGF2ZSBzZXQgdGhlIHNjYW5uZXIgc3RhdGUgdG8KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vU0NBTk5FUl9TVEFURV9DT05URU5UIChzdXBlciBzdGF0ZSkgcGFyc2VyIHdpbGwgYXV0b21hdGljYWxseSByZWNvdmVyIGFuZAotICAgICAgICAgICAgICAgICAgICAgICAgLy9iZWhhdmUgYXBwcm9wcmlhdGVseS4gV2hlbiBpc0NvYWxlc2NlIGlzIHNldCB0byB0cnVlIHdlIGRvbnQgbmVlZCB0byByZXBvcnRDREFUQSBldmVudAotICAgICAgICAgICAgICAgICAgICAgICAgLy8yLiBDaGVjayBpZiBhcHBsaWNhdGlvbiBoYXMgc2V0IGZvciByZXBvcnRpbmcgQ0RBVEEgZXZlbnQKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vMy4gaWYgdGhlIGFwcGxpY2F0aW9uIGhhcyBuZWl0aGVyIHNldCB0aGUgZklzQ29hbGVzY2UgdG8gdHJ1ZSBub3IgZlJlcG9ydENkYXRhRXZlbnQKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vcmV0dXJuIHRoZSBjZGF0YSBldmVudCBhcyBjaGFyYWN0ZXJzLgotICAgICAgICAgICAgICAgICAgICAgICAgaWYoZklzQ29hbGVzY2UpewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZMYXN0U2VjdGlvbldhc0NEYXRhID0gdHJ1ZSA7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy90aGVyZSBtaWdodCBiZSBtb3JlIGRhdGEgdG8gY29hbGVzY2UuCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9ZWxzZSBpZihmUmVwb3J0Q2RhdGFFdmVudCl7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFhNTEV2ZW50LkNEQVRBOwotICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBYTUxFdmVudC5DSEFSQUNURVJTOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgY2FzZSBTQ0FOTkVSX1NUQVRFX1JFRkVSRU5DRSA6ewotICAgICAgICAgICAgICAgICAgICAgICAgZk1hcmt1cERlcHRoKys7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmb3VuZEJ1aWx0SW5SZWZzID0gZmFsc2U7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vd2Ugc2hvdWxkIG5vdCBjbGVhciB0aGUgYnVmZmVyIG9ubHkgd2hlbiB0aGUgbGFzdCBzdGF0ZSB3YXMgZWl0aGVyIENEQVRBIG9yCi0gICAgICAgICAgICAgICAgICAgICAgICAvL1NDQU5ORVJfU1RBVEVfQ0hBUkFDVEVSX0RBVEEgb3IgU0NBTk5FUl9TVEFURV9SRUZFUkVOQ0UKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmKGZJc0NvYWxlc2NlICYmICggZkxhc3RTZWN0aW9uV2FzRW50aXR5UmVmZXJlbmNlIHx8IGZMYXN0U2VjdGlvbldhc0NEYXRhIHx8IGZMYXN0U2VjdGlvbldhc0NoYXJhY3RlckRhdGEpKXsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2ZMYXN0U2VjdGlvbldhc0VudGl0eVJlZmVyZW5jZSBvciBmTGFzdFNlY3Rpb25XYXNDRGF0YSBhcmUgb25seQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vdXNlZCB3aGVuIGZJc0NvYWxlc2NlIGlzIHNldCB0byB0cnVlLgotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZMYXN0U2VjdGlvbldhc0VudGl0eVJlZmVyZW5jZSA9IHRydWUgOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZMYXN0U2VjdGlvbldhc0NEYXRhID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZkxhc3RTZWN0aW9uV2FzQ2hhcmFjdGVyRGF0YSA9IGZhbHNlOwotICAgICAgICAgICAgICAgICAgICAgICAgfS8vaWYgd2UgZG9udCBuZWVkIHRvIGNvYWxlc2NlIGNsZWFyIHRoZSBidWZmZXIKLSAgICAgICAgICAgICAgICAgICAgICAgIGVsc2V7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZkNvbnRlbnRCdWZmZXIuY2xlYXIoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGZVc2VidWZmZXIgPSB0cnVlIDsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vdGFrZSBjYXJlIG9mIGNoYXJhY3RlciByZWZlcmVuY2UKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmRW50aXR5U2Nhbm5lci5za2lwQ2hhcignIycsIE5hbWVUeXBlLlJFRkVSRU5DRSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2FuQ2hhclJlZmVyZW5jZVZhbHVlKGZDb250ZW50QnVmZmVyLCBudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmTWFya3VwRGVwdGgtLTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZighZklzQ29hbGVzY2UpewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRTY2FubmVyU3RhdGUoU0NBTk5FUl9TVEFURV9DT05URU5UKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFhNTEV2ZW50LkNIQVJBQ1RFUlM7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGlzIGZ1bmN0aW9uIGFsc28gc3RhcnRzIG5ldyBlbnRpdHkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2FuRW50aXR5UmVmZXJlbmNlKGZDb250ZW50QnVmZmVyKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2lmIHRoZXJlIHdhcyBidWlsdC1pbiBlbnRpdHkgcmVmZXJlbmNlICYgY29hbGVzY2UgaXMgbm90IHRydWUKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3JldHVybiBDSEFSQUNURVJTCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoZlNjYW5uZXJTdGF0ZSA9PSBTQ0FOTkVSX1NUQVRFX0JVSUxUX0lOX1JFRlMgJiYgIWZJc0NvYWxlc2NlKXsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0U2Nhbm5lclN0YXRlKFNDQU5ORVJfU1RBVEVfQ09OVEVOVCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBYTUxFdmVudC5DSEFSQUNURVJTOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vaWYgdGhlcmUgd2FzIGEgdGV4dCBkZWNsYXJhdGlvbiwgY2FsbCBuZXh0KCkgaXQgd2lsbCBiZSB0YWtlbiBjYXJlLgotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKGZTY2FubmVyU3RhdGUgPT0gU0NBTk5FUl9TVEFURV9URVhUX0RFQ0wpewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmTGFzdFNlY3Rpb25XYXNFbnRpdHlSZWZlcmVuY2UgPSB0cnVlIDsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoZlNjYW5uZXJTdGF0ZSA9PSBTQ0FOTkVSX1NUQVRFX1JFRkVSRU5DRSl7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldFNjYW5uZXJTdGF0ZShTQ0FOTkVSX1NUQVRFX0NPTlRFTlQpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZlJlcGxhY2VFbnRpdHlSZWZlcmVuY2VzICYmIGZFbnRpdHlTdG9yZS5pc0RlY2xhcmVkRW50aXR5KGZDdXJyZW50RW50aXR5TmFtZSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNraXAgdGhlIGVudGl0eSByZWZlcmVuY2UsIHdlIGRvbid0IGNhcmUKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBYTUxFdmVudC5FTlRJVFlfUkVGRVJFTkNFOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vV2V0aGVyIGl0IHdhcyBjaGFyYWN0ZXIgcmVmZXJlbmNlLCBlbnRpdHkgcmVmZXJlbmNlIG9yIGJ1aWx0LWluIGVudGl0eQotICAgICAgICAgICAgICAgICAgICAgICAgLy9zZXQgdGhlIG5leHQgcG9zc2libGUgc3RhdGUgdG8gU0NBTk5FUl9TVEFURV9DT05URU5UCi0gICAgICAgICAgICAgICAgICAgICAgICBzZXRTY2FubmVyU3RhdGUoU0NBTk5FUl9TVEFURV9DT05URU5UKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZMYXN0U2VjdGlvbldhc0VudGl0eVJlZmVyZW5jZSA9IHRydWUgOwotICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICBjYXNlIFNDQU5ORVJfU1RBVEVfVEVYVF9ERUNMOiB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBzY2FuIHRleHQgZGVjbAotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZFbnRpdHlTY2FubmVyLnNraXBTdHJpbmcoIjw/eG1sIikpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmTWFya3VwRGVwdGgrKzsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBOT1RFOiBzcGVjaWFsIGNhc2Ugd2hlcmUgZW50aXR5IHN0YXJ0cyB3aXRoIGEgUEkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgICAgICB3aG9zZSBuYW1lIHN0YXJ0cyB3aXRoICJ4bWwiIChlLmcuICJ4bWxmb28iKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc1ZhbGlkTmFtZUNoYXIoZkVudGl0eVNjYW5uZXIucGVla0NoYXIoKSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZlN0cmluZ0J1ZmZlci5jbGVhcigpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmU3RyaW5nQnVmZmVyLmFwcGVuZCgieG1sIik7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZOYW1lc3BhY2VzKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoaXNWYWxpZE5DTmFtZShmRW50aXR5U2Nhbm5lci5wZWVrQ2hhcigpKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZTdHJpbmdCdWZmZXIuYXBwZW5kKChjaGFyKWZFbnRpdHlTY2FubmVyLnNjYW5DaGFyKG51bGwpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChpc1ZhbGlkTmFtZUNoYXIoZkVudGl0eVNjYW5uZXIucGVla0NoYXIoKSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmU3RyaW5nQnVmZmVyLmFwcGVuZCgoY2hhcilmRW50aXR5U2Nhbm5lci5zY2FuQ2hhcihudWxsKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHRhcmdldCA9IGZTeW1ib2xUYWJsZS5hZGRTeW1ib2woZlN0cmluZ0J1ZmZlci5jaCwgZlN0cmluZ0J1ZmZlci5vZmZzZXQsIGZTdHJpbmdCdWZmZXIubGVuZ3RoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkNvbnRlbnRCdWZmZXIuY2xlYXIoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NhblBJRGF0YSh0YXJnZXQsIGZDb250ZW50QnVmZmVyKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzdGFuZGFyZCB0ZXh0IGRlY2xhcmF0aW9uCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8veHh4OiB0aGlzIGZ1bmN0aW9uIGdpdmVzIGNhbGxiYWNrCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjYW5YTUxEZWNsT3JUZXh0RGVjbCh0cnVlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBub3cgdGhhdCB3ZSd2ZSBzdHJhaWdodGVuZWQgb3V0IHRoZSByZWFkZXJzLCB3ZSBjYW4gcmVhZCBpbiBjaHVua3M6Ci0gICAgICAgICAgICAgICAgICAgICAgICBmRW50aXR5TWFuYWdlci5mQ3VycmVudEVudGl0eS5tYXlSZWFkQ2h1bmtzID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHNldFNjYW5uZXJTdGF0ZShTQ0FOTkVSX1NUQVRFX0NPTlRFTlQpOwotICAgICAgICAgICAgICAgICAgICAgICAgLy94eHg6IHdlIGRvbid0IHJldHVybiBhbnkgc3RhdGUsIHNvIGhvdyBkbyB3ZSBnZXQgdG8ga25vdyBhYm91dCBURVhUIGRlY2xhcmF0aW9ucy4KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vaXQgc2VlbXMgd2UgaGF2ZSB0byBjYXJlZnVsIHdoZW4gdG8gYWxsb3cgZnVuY3Rpb24gaXNzdWUgYSBjYWxsYmFjawotICAgICAgICAgICAgICAgICAgICAgICAgLy9hbmQgd2hlbiB0byBhbGxvdyBhZGFwdGVyIGlzc3VlIGEgY2FsbGJhY2suCi0gICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgICAgICAgICAgfQotCi0KLSAgICAgICAgICAgICAgICAgICAgY2FzZSBTQ0FOTkVSX1NUQVRFX1JPT1RfRUxFTUVOVDogewotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNjYW5Sb290RWxlbWVudEhvb2soKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZFbXB0eUVsZW1lbnQgPSB0cnVlOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vcmVzdCB3b3VsZCBiZSB0YWtlbiBjYXJlIGJ5IGZUcmFpbGluZ01pc2NEcml2ZXIgc2V0IGJ5IHNjYW5Sb290RWxlbWVudEhvb2sKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gWE1MRXZlbnQuU1RBUlRfRUxFTUVOVDsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIHNldFNjYW5uZXJTdGF0ZShTQ0FOTkVSX1NUQVRFX0NPTlRFTlQpOwotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFhNTEV2ZW50LlNUQVJUX0VMRU1FTlQgOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgU0NBTk5FUl9TVEFURV9DSEFSX1JFRkVSRU5DRSA6IHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZDb250ZW50QnVmZmVyLmNsZWFyKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzY2FuQ2hhclJlZmVyZW5jZVZhbHVlKGZDb250ZW50QnVmZmVyLCBudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZNYXJrdXBEZXB0aC0tOwotICAgICAgICAgICAgICAgICAgICAgICAgc2V0U2Nhbm5lclN0YXRlKFNDQU5ORVJfU1RBVEVfQ09OVEVOVCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gWE1MRXZlbnQuQ0hBUkFDVEVSUzsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgotICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFhOSUV4Y2VwdGlvbigiU2Nhbm5lciBTdGF0ZSAiICsgZlNjYW5uZXJTdGF0ZSArICIgbm90IFJlY29nbml6ZWQgIik7Ci0KLSAgICAgICAgICAgICAgICB9Ly9zd2l0Y2gKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIHByZW1hdHVyZSBlbmQgb2YgZmlsZQotICAgICAgICAgICAgY2F0Y2ggKEVPRkV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgZW5kT2ZGaWxlSG9vayhlKTsKLSAgICAgICAgICAgICAgICByZXR1cm4gLTE7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICB9IC8vd2hpbGUgbG9vcAotICAgICAgICB9Ly9uZXh0Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gUHJvdGVjdGVkIG1ldGhvZHMKLSAgICAgICAgLy8KLQotICAgICAgICAvLyBob29rcwotCi0gICAgICAgIC8vIE5PVEU6IFRoZXNlIGhvb2sgbWV0aG9kcyBhcmUgYWRkZWQgc28gdGhhdCB0aGUgZnVsbCBkb2N1bWVudAotICAgICAgICAvLyAgICAgICBzY2FubmVyIGNhbiBzaGFyZSB0aGUgbWFqb3JpdHkgb2YgY29kZSB3aXRoIHRoaXMgY2xhc3MuCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFNjYW4gZm9yIERPQ1RZUEUgaG9vay4gVGhpcyBtZXRob2QgaXMgYSBob29rIGZvciBzdWJjbGFzc2VzCi0gICAgICAgICAqIHRvIGFkZCBjb2RlIHRvIGhhbmRsZSBzY2FubmluZyBmb3IgYSB0aGUgIkRPQ1RZUEUiIHN0cmluZwotICAgICAgICAgKiBhZnRlciB0aGUgc3RyaW5nICI8ISIgaGFzIGJlZW4gc2Nhbm5lZC4KLSAgICAgICAgICoKLSAgICAgICAgICogQHJldHVybiBUcnVlIGlmIHRoZSAiRE9DVFlQRSIgd2FzIHNjYW5uZWQ7IGZhbHNlIGlmICJET0NUWVBFIgotICAgICAgICAgKiAgICAgICAgICB3YXMgbm90IHNjYW5uZWQuCi0gICAgICAgICAqLwotICAgICAgICBwcm90ZWN0ZWQgYm9vbGVhbiBzY2FuRm9yRG9jdHlwZUhvb2soKQotICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0gLy8gc2NhbkZvckRvY3R5cGVIb29rKCk6Ym9vbGVhbgotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBFbGVtZW50IGRlcHRoIGl6IHplcm8uIFRoaXMgbWV0aG9zIGlzIGEgaG9vayBmb3Igc3ViY2xhc3NlcwotICAgICAgICAgKiB0byBhZGQgY29kZSB0byBoYW5kbGUgd2hlbiB0aGUgZWxlbWVudCBkZXB0aCBoaXRzIHplcm8uIFdoZW4KLSAgICAgICAgICogc2Nhbm5pbmcgYSBkb2N1bWVudCBmcmFnbWVudCwgYW4gZWxlbWVudCBkZXB0aCBvZiB6ZXJvIGlzCi0gICAgICAgICAqIG5vcm1hbC4gSG93ZXZlciwgd2hlbiBzY2FubmluZyBhIGZ1bGwgWE1MIGRvY3VtZW50LCB0aGUKLSAgICAgICAgICogc2Nhbm5lciBtdXN0IGhhbmRsZSB0aGUgdHJhaWxpbmcgbWlzY2VsbGFub3VzIHNlY3Rpb24gb2YKLSAgICAgICAgICogdGhlIGRvY3VtZW50IGFmdGVyIHRoZSBlbmQgb2YgdGhlIGRvY3VtZW50J3Mgcm9vdCBlbGVtZW50LgotICAgICAgICAgKgotICAgICAgICAgKiBAcmV0dXJuIFRydWUgaWYgdGhlIGNhbGxlciBzaG91bGQgc3RvcCBhbmQgcmV0dXJuIHRydWUgd2hpY2gKLSAgICAgICAgICogICAgICAgICAgYWxsb3dzIHRoZSBzY2FubmVyIHRvIHN3aXRjaCB0byBhIG5ldyBzY2FubmluZwotICAgICAgICAgKiAgICAgICAgICBkcml2ZXIuIEEgcmV0dXJuIHZhbHVlIG9mIGZhbHNlIGluZGljYXRlcyB0aGF0Ci0gICAgICAgICAqICAgICAgICAgIHRoZSBjb250ZW50IGRyaXZlciBzaG91bGQgY29udGludWUgYXMgbm9ybWFsLgotICAgICAgICAgKi8KLSAgICAgICAgcHJvdGVjdGVkIGJvb2xlYW4gZWxlbWVudERlcHRoSXNaZXJvSG9vaygpCi0gICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfSAvLyBlbGVtZW50RGVwdGhJc1plcm9Ib29rKCk6Ym9vbGVhbgotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBTY2FuIGZvciByb290IGVsZW1lbnQgaG9vay4gVGhpcyBtZXRob2QgaXMgYSBob29rIGZvcgotICAgICAgICAgKiBzdWJjbGFzc2VzIHRvIGFkZCBjb2RlIHRoYXQgaGFuZGxlcyBzY2FubmluZyBmb3IgdGhlIHJvb3QKLSAgICAgICAgICogZWxlbWVudC4gV2hlbiBzY2FubmluZyBhIGRvY3VtZW50IGZyYWdtZW50LCB0aGVyZSBpcyBubwotICAgICAgICAgKiAicm9vdCIgZWxlbWVudC4gSG93ZXZlciwgd2hlbiBzY2FubmluZyBhIGZ1bGwgWE1MIGRvY3VtZW50LAotICAgICAgICAgKiB0aGUgc2Nhbm5lciBtdXN0IGhhbmRsZSB0aGUgcm9vdCBlbGVtZW50IHNwZWNpYWxseS4KLSAgICAgICAgICoKLSAgICAgICAgICogQHJldHVybiBUcnVlIGlmIHRoZSBjYWxsZXIgc2hvdWxkIHN0b3AgYW5kIHJldHVybiB0cnVlIHdoaWNoCi0gICAgICAgICAqICAgICAgICAgIGFsbG93cyB0aGUgc2Nhbm5lciB0byBzd2l0Y2ggdG8gYSBuZXcgc2Nhbm5pbmcKLSAgICAgICAgICogICAgICAgICAgZHJpdmVyLiBBIHJldHVybiB2YWx1ZSBvZiBmYWxzZSBpbmRpY2F0ZXMgdGhhdAotICAgICAgICAgKiAgICAgICAgICB0aGUgY29udGVudCBkcml2ZXIgc2hvdWxkIGNvbnRpbnVlIGFzIG5vcm1hbC4KLSAgICAgICAgICovCi0gICAgICAgIHByb3RlY3RlZCBib29sZWFuIHNjYW5Sb290RWxlbWVudEhvb2soKQotICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0gLy8gc2NhblJvb3RFbGVtZW50SG9vaygpOmJvb2xlYW4KLQotICAgICAgICAvKioKLSAgICAgICAgICogRW5kIG9mIGZpbGUgaG9vay4gVGhpcyBtZXRob2QgaXMgYSBob29rIGZvciBzdWJjbGFzc2VzIHRvCi0gICAgICAgICAqIGFkZCBjb2RlIHRoYXQgaGFuZGxlcyB0aGUgZW5kIG9mIGZpbGUuIFRoZSBlbmQgb2YgZmlsZSBpbgotICAgICAgICAgKiBhIGRvY3VtZW50IGZyYWdtZW50IGlzIE9LIGlmIHRoZSBtYXJrdXAgZGVwdGggaXMgemVyby4KLSAgICAgICAgICogSG93ZXZlciwgd2hlbiBzY2FubmluZyBhIGZ1bGwgWE1MIGRvY3VtZW50LCBhbiBlbmQgb2YgZmlsZQotICAgICAgICAgKiBpcyBhbHdheXMgcHJlbWF0dXJlLgotICAgICAgICAgKi8KLSAgICAgICAgcHJvdGVjdGVkIHZvaWQgZW5kT2ZGaWxlSG9vayhFT0ZFeGNlcHRpb24gZSkKLSAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBYTklFeGNlcHRpb24gewotCi0gICAgICAgICAgICAvLyBOT1RFOiBBbiBlbmQgb2YgZmlsZSBpcyBvbmx5IG9ubHkgYW4gZXJyb3IgaWYgd2Ugd2VyZQotICAgICAgICAgICAgLy8gICAgICAgaW4gdGhlIG1pZGRsZSBvZiBzY2FubmluZyBzb21lIG1hcmt1cC4gLUFjCi0gICAgICAgICAgICBpZiAoZk1hcmt1cERlcHRoICE9IDApIHsKLSAgICAgICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJQcmVtYXR1cmVFT0YiLCBudWxsKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICB9IC8vIGVuZE9mRmlsZUhvb2soKQotCi0gICAgfSAvLyBjbGFzcyBGcmFnbWVudENvbnRlbnREcml2ZXIKLQotICAgIHN0YXRpYyB2b2lkIHByKFN0cmluZyBzdHIpIHsKLSAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKHN0cikgOwotICAgIH0KLQotICAgIHByb3RlY3RlZCBib29sZWFuIGZVc2VidWZmZXIgOwotCi0gICAgLyoqIHRoaXMgZnVuY3Rpb24gZ2V0cyBhbiBYTUxTdHJpbmcgKHdoaWNoIGlzIHVzZWQgdG8gc3RvcmUgdGhlIGF0dHJpYnV0ZSB2YWx1ZSkgZnJvbSB0aGUgc3BlY2lhbCBwb29sCi0gICAgICogIG1haW50YWluZWQgZm9yIGF0dHJpYnV0ZXMuCi0gICAgICogIGZBdHRyaWJ1dGVDYWNoZVVzZWRDb3VudCB0cmFja3MgdGhlIG51bWJlciBvZiBhdHRyaWJ1dGVzIHRoYXQgaGFzIGJlZW4gY29uc3VtZWQgZnJvbSB0aGUgcG9vbC4KLSAgICAgKiAgaWYgYWxsIHRoZSBhdHRyaWJ1dGVzIGhhcyBiZWVuIGNvbnN1bWVkLCBpdCBhZGRzIGEgbmV3IFhNTFN0cmluZyBpbnRoZSBwb29sIGFuZCByZXR1cm5zIHRoZSBzYW1lCi0gICAgICogIFhNTFN0cmluZy4KLSAgICAgKgotICAgICAqIEByZXR1cm4gWE1MU3RyaW5nIFhNTFN0cmluZyB1c2VkIHRvIHN0b3JlIGFuIGF0dHJpYnV0ZSB2YWx1ZS4KLSAgICAgKi8KLQotICAgIHByb3RlY3RlZCBYTUxTdHJpbmcgZ2V0U3RyaW5nKCl7Ci0gICAgICAgIGlmKGZBdHRyaWJ1dGVDYWNoZVVzZWRDb3VudCA8IGluaXRpYWxDYWNoZUNvdW50IHx8IGZBdHRyaWJ1dGVDYWNoZVVzZWRDb3VudCA8IGF0dHJpYnV0ZVZhbHVlQ2FjaGUuc2l6ZSgpKXsKLSAgICAgICAgICAgIHJldHVybiBhdHRyaWJ1dGVWYWx1ZUNhY2hlLmdldChmQXR0cmlidXRlQ2FjaGVVc2VkQ291bnQrKyk7Ci0gICAgICAgIH0gZWxzZXsKLSAgICAgICAgICAgIFhNTFN0cmluZyBzdHIgPSBuZXcgWE1MU3RyaW5nKCk7Ci0gICAgICAgICAgICBmQXR0cmlidXRlQ2FjaGVVc2VkQ291bnQrKzsKLSAgICAgICAgICAgIGF0dHJpYnV0ZVZhbHVlQ2FjaGUuYWRkKHN0cik7Ci0gICAgICAgICAgICByZXR1cm4gc3RyOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSW1wbGVtZW50cyBYTUxCdWZmZXJMaXN0ZW5lciBpbnRlcmZhY2UuCi0gICAgICovCi0KLSAgICBwdWJsaWMgdm9pZCByZWZyZXNoKCl7Ci0gICAgICAgIHJlZnJlc2goMCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogcmVjZWl2ZXMgY2FsbGJhY2tzIGZyb20ge0BsaW5rIFhNTEVudGl0eVJlYWRlciB9IHdoZW4gYnVmZmVyCi0gICAgICogaXMgYmVpbmcgY2hhbmdlZC4KLSAgICAgKiBAcGFyYW0gcmVmcmVzaFBvc2l0aW9uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcmVmcmVzaChpbnQgcmVmcmVzaFBvc2l0aW9uKXsKLSAgICAgICAgLy9JZiB5b3UgYXJlIHJlYWRpbmcgYXR0cmlidXRlcyBhbmQgeW91IGdvdCBhIGNhbGxiYWNrCi0gICAgICAgIC8vY2FjaGUgYXZhaWxhYmxlIGF0dHJpYnV0ZXMuCi0gICAgICAgIGlmKGZSZWFkaW5nQXR0cmlidXRlcyl7Ci0gICAgICAgICAgICBmQXR0cmlidXRlcy5yZWZyZXNoKCk7Ci0gICAgICAgIH0KLSAgICAgICAgaWYoZlNjYW5uZXJTdGF0ZSA9PSBTQ0FOTkVSX1NUQVRFX0NIQVJBQ1RFUl9EQVRBKXsKLSAgICAgICAgICAgIC8vc2luY2UgZlRlbXBTdHJpbmcgZGlyZWN0bHkgbWF0Y2hlcyB0byB0aGUgdW5kZXJseWluZyBtYWluIGJ1ZmZlcgotICAgICAgICAgICAgLy9zdG9yZSB0aGUgZGF0YSBpbnRvIGJ1ZmZlcgotICAgICAgICAgICAgZkNvbnRlbnRCdWZmZXIuYXBwZW5kKGZUZW1wU3RyaW5nKTsKLSAgICAgICAgICAgIC8vY2xlYXIgdGhlIFhNTFN0cmluZyBzbyB0aGF0IGRhdGEgY2FuJ3QgYmUgYWRkZWQgYWdhaW4uCi0gICAgICAgICAgICBmVGVtcFN0cmluZy5sZW5ndGggPSAwOwotICAgICAgICAgICAgZlVzZWJ1ZmZlciA9IHRydWU7Ci0gICAgICAgIH0KLSAgICB9Ci0KLX0gLy8gY2xhc3MgWE1MRG9jdW1lbnRGcmFnbWVudFNjYW5uZXJJbXBsCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL1hNTERvY3VtZW50U2Nhbm5lckltcGwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvWE1MRG9jdW1lbnRTY2FubmVySW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2YzYyMzQ1Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvWE1MRG9jdW1lbnRTY2FubmVySW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTQ5OSArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDE2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICovCi0KLS8qCi0gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKLSAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAotICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgotICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKLSAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCi0gKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbDsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdGQuWE1MRFRERGVzY3JpcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnZhbGlkYXRpb24uVmFsaWRhdGlvbk1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLk5hbWVzcGFjZVN1cHBvcnQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlhNTENoYXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlhNTFJlc291cmNlSWRlbnRpZmllckltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlhNTFN0cmluZ0J1ZmZlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWxzLlNlY3VyaXR5U3VwcG9ydDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5BdWdtZW50YXRpb25zOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLk5hbWVzcGFjZUNvbnRleHQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MUmVzb3VyY2VJZGVudGlmaWVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhOSUV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MQ29tcG9uZW50TWFuYWdlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MRFREU2Nhbm5lcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MSW5wdXRTb3VyY2U7Ci1pbXBvcnQgY29tLnN1bi54bWwuaW50ZXJuYWwuc3RyZWFtLkVudGl0eTsKLWltcG9ydCBjb20uc3VuLnhtbC5pbnRlcm5hbC5zdHJlYW0uU3RheFhNTElucHV0U291cmNlOwotaW1wb3J0IGNvbS5zdW4ueG1sLmludGVybmFsLnN0cmVhbS5kdGQuRFRER3JhbW1hclV0aWw7Ci1pbXBvcnQgamF2YS5pby5FT0ZFeGNlcHRpb247Ci1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLlhNTElucHV0RmFjdG9yeTsKLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLmV2ZW50cy5YTUxFdmVudDsKLQotCi0vKioKLSAqIFRoaXMgY2xhc3MgaXMgcmVzcG9uc2libGUgZm9yIHNjYW5uaW5nIFhNTCBkb2N1bWVudCBzdHJ1Y3R1cmUKLSAqIGFuZCBjb250ZW50LgotICoKLSAqIFRoaXMgY2xhc3MgaGFzIGJlZW4gbW9kaWZpZWQgYXMgcGVyIHRoZSBuZXcgZGVzaWduIHdoaWNoIGlzIG1vcmUgc3VpdGVkIHRvCi0gKiBlZmZpY2llbnRseSBidWlsZCBwdWxsIHBhcnNlci4gTG90IG9mIGltcHJvdmVtZW50cyBoYXZlIGJlZW4gZG9uZSBhbmQKLSAqIHRoZSBjb2RlIGhhcyBiZWVuIGFkZGVkIHRvIHN1cHBvcnQgc3RheCBmdW5jdGlvbmFsaXR5L2ZlYXR1cmVzLgotICoKLSAqIEBhdXRob3IgTmVlcmFqIEJhamFqLCBTdW4gTWljcm9zeXN0ZW1zCi0gKiBAYXV0aG9yIEsuVmVudWdvcGFsLCBTdW4gTWljcm9zeXN0ZW1zCi0gKiBAYXV0aG9yIEdsZW5uIE1hcmN5LCBJQk0KLSAqIEBhdXRob3IgQW5keSBDbGFyaywgSUJNCi0gKiBAYXV0aG9yIEFybmF1ZCAgTGUgSG9ycywgSUJNCi0gKiBAYXV0aG9yIEVyaWMgWWUsIElCTQotICogQGF1dGhvciBTdW5pdGhhIFJlZGR5LCBTdW4gTWljcm9zeXN0ZW1zCi0gKgotICogUmVmZXIgdG8gdGhlIHRhYmxlIGluIHVuaXQtdGVzdCBqYXZheC54bWwuc3RyZWFtLlhNTFN0cmVhbVJlYWRlclRlc3QuU3VwcG9ydERURCBmb3IgY2hhbmdlcwotICogcmVsYXRlZCB0byBwcm9wZXJ0eSBTdXBwb3J0RFRELgotICogQGF1dGhvciBKb2UgV2FuZywgU3VuIE1pY3Jvc3lzdGVtcwotICogQHZlcnNpb24gJElkOiBYTUxEb2N1bWVudFNjYW5uZXJJbXBsLmphdmEsdiAxLjE3IDIwMTAtMTEtMDEgMDQ6Mzk6NDEgam9laHcgRXhwICQKLSAqLwotcHVibGljIGNsYXNzIFhNTERvY3VtZW50U2Nhbm5lckltcGwKLSAgICAgICAgZXh0ZW5kcyBYTUxEb2N1bWVudEZyYWdtZW50U2Nhbm5lckltcGx7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0YW50cwotICAgIC8vCi0KLSAgICAvLyBzY2FubmVyIHN0YXRlcwotCi0gICAgLyoqIFNjYW5uZXIgc3RhdGU6IFhNTCBkZWNsYXJhdGlvbi4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBTQ0FOTkVSX1NUQVRFX1hNTF9ERUNMID0gNDI7Ci0KLSAgICAvKiogU2Nhbm5lciBzdGF0ZTogcHJvbG9nLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgaW50IFNDQU5ORVJfU1RBVEVfUFJPTE9HID0gNDM7Ci0KLSAgICAvKiogU2Nhbm5lciBzdGF0ZTogdHJhaWxpbmcgbWlzYy4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBTQ0FOTkVSX1NUQVRFX1RSQUlMSU5HX01JU0MgPSA0NDsKLQotICAgIC8qKiBTY2FubmVyIHN0YXRlOiBEVEQgaW50ZXJuYWwgZGVjbGFyYXRpb25zLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgaW50IFNDQU5ORVJfU1RBVEVfRFREX0lOVEVSTkFMX0RFQ0xTID0gNDU7Ci0KLSAgICAvKiogU2Nhbm5lciBzdGF0ZTogb3BlbiBEVEQgZXh0ZXJuYWwgc3Vic2V0LiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgaW50IFNDQU5ORVJfU1RBVEVfRFREX0VYVEVSTkFMID0gNDY7Ci0KLSAgICAvKiogU2Nhbm5lciBzdGF0ZTogRFREIGV4dGVybmFsIGRlY2xhcmF0aW9ucy4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBTQ0FOTkVSX1NUQVRFX0RURF9FWFRFUk5BTF9ERUNMUyA9IDQ3OwotCi0gICAgLyoqIFNjYW5uZXIgc3RhdGU6IE5PIE1PUkUgRUxFTUVOVFMuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBpbnQgU0NBTk5FUl9TVEFURV9OT19TVUNIX0VMRU1FTlRfRVhDRVBUSU9OID0gNDg7Ci0KLSAgICAvLyBmZWF0dXJlIGlkZW50aWZpZXJzCi0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllciBkb2N1bWVudCBzY2FubmVyOiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIERPQ1VNRU5UX1NDQU5ORVIgPQotICAgICAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuRE9DVU1FTlRfU0NBTk5FUl9QUk9QRVJUWTsKLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IGxvYWQgZXh0ZXJuYWwgRFRELiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIExPQURfRVhURVJOQUxfRFREID0KLSAgICAgICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuTE9BRF9FWFRFUk5BTF9EVERfRkVBVFVSRTsKLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IGxvYWQgZXh0ZXJuYWwgRFRELiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIERJU0FMTE9XX0RPQ1RZUEVfREVDTF9GRUFUVVJFID0KLSAgICAgICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuRElTQUxMT1dfRE9DVFlQRV9ERUNMX0ZFQVRVUkU7Ci0KLSAgICAvLyBwcm9wZXJ0eSBpZGVudGlmaWVycwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IERURCBzY2FubmVyLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIERURF9TQ0FOTkVSID0KLSAgICAgICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLkRURF9TQ0FOTkVSX1BST1BFUlRZOwotCi0gICAgLy8gcHJvcGVydHkgaWRlbnRpZmllcjogIFZhbGlkYXRpb25NYW5hZ2VyCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgVkFMSURBVElPTl9NQU5BR0VSID0KLSAgICAgICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLlZBTElEQVRJT05fTUFOQUdFUl9QUk9QRVJUWTsKLQotICAgIC8qKiBwcm9wZXJ0eSBpZGVudGlmaWVyOiAgTmFtZXNwYWNlQ29udGV4dCAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIE5BTUVTUEFDRV9DT05URVhUID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuTkFNRVNQQUNFX0NPTlRFWFRfUFJPUEVSVFk7Ci0KLSAgICAvLyByZWNvZ25pemVkIGZlYXR1cmVzIGFuZCBwcm9wZXJ0aWVzCi0KLSAgICAvKiogUmVjb2duaXplZCBmZWF0dXJlcy4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSBSRUNPR05JWkVEX0ZFQVRVUkVTID0gewotICAgICAgICBMT0FEX0VYVEVSTkFMX0RURCwKLSAgICAgICAgICAgICAgICBESVNBTExPV19ET0NUWVBFX0RFQ0xfRkVBVFVSRSwKLSAgICB9OwotCi0gICAgLyoqIEZlYXR1cmUgZGVmYXVsdHMuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQm9vbGVhbltdIEZFQVRVUkVfREVGQVVMVFMgPSB7Ci0gICAgICAgIEJvb2xlYW4uVFJVRSwKLSAgICAgICAgICAgICAgICBCb29sZWFuLkZBTFNFLAotICAgIH07Ci0KLSAgICAvKiogUmVjb2duaXplZCBwcm9wZXJ0aWVzLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZ1tdIFJFQ09HTklaRURfUFJPUEVSVElFUyA9IHsKLSAgICAgICAgRFREX1NDQU5ORVIsCi0gICAgICAgICAgICAgICAgVkFMSURBVElPTl9NQU5BR0VSCi0gICAgfTsKLQotICAgIC8qKiBQcm9wZXJ0eSBkZWZhdWx0cy4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBPYmplY3RbXSBQUk9QRVJUWV9ERUZBVUxUUyA9IHsKLSAgICAgICAgICAgIG51bGwsCi0gICAgICAgICAgICAgICAgbnVsbAotICAgIH07Ci0KLSAgICAvLwotICAgIC8vIERhdGEoKEJvb2xlYW4pcHJvcGVydHlNYW5hZ2VyLmdldFByb3BlcnR5KFhNTElucHV0RmFjdG9yeS5JU19OQU1FU1BBQ0VfQVdBUkUpKS5ib29sZWFuVmFsdWUoKTsKLSAgICAvLwotCi0gICAgLy8gcHJvcGVydGllcwotCi0gICAgLyoqIERURCBzY2FubmVyLiAqLwotICAgIHByb3RlY3RlZCBYTUxEVERTY2FubmVyIGZEVERTY2FubmVyID0gbnVsbDsKLQotICAgIC8qKiBWYWxpZGF0aW9uIG1hbmFnZXIgLiAqLwotICAgIC8veHh4OiBmVmFsaWRhdGlvbk1hbmFnZXIgY29kZSBuZWVkcyB0byBiZSBhZGRlZCB5ZXQhCi0gICAgcHJvdGVjdGVkIFZhbGlkYXRpb25NYW5hZ2VyIGZWYWxpZGF0aW9uTWFuYWdlcjsKLQotICAgIHByb3RlY3RlZCBYTUxTdHJpbmdCdWZmZXIgZkRURERlY2wgPSBudWxsOwotICAgIHByb3RlY3RlZCBib29sZWFuIGZSZWFkaW5nRFREID0gZmFsc2U7Ci0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZkFkZGVkTGlzdGVuZXIgPSBmYWxzZTsKLQotICAgIC8vIHByb3RlY3RlZCBkYXRhCi0KLSAgICAvLyBvdGhlciBpbmZvCi0KLSAgICAvKiogRG9jdHlwZSBuYW1lLiAqLwotICAgIHByb3RlY3RlZCBTdHJpbmcgZkRvY3R5cGVOYW1lOwotCi0gICAgLyoqIERvY3R5cGUgZGVjbGFyYXRpb24gcHVibGljIGlkZW50aWZpZXIuICovCi0gICAgcHJvdGVjdGVkIFN0cmluZyBmRG9jdHlwZVB1YmxpY0lkOwotCi0gICAgLyoqIERvY3R5cGUgZGVjbGFyYXRpb24gc3lzdGVtIGlkZW50aWZpZXIuICovCi0gICAgcHJvdGVjdGVkIFN0cmluZyBmRG9jdHlwZVN5c3RlbUlkOwotCi0gICAgLyoqIE5hbWVzcGFjZSBzdXBwb3J0LiAqLwotICAgIHByb3RlY3RlZCBOYW1lc3BhY2VDb250ZXh0IGZOYW1lc3BhY2VDb250ZXh0ID0gbmV3IE5hbWVzcGFjZVN1cHBvcnQoKTsKLQotICAgIC8vIGZlYXR1cmVzCi0KLSAgICAvKiogTG9hZCBleHRlcm5hbCBEVEQuICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZkxvYWRFeHRlcm5hbERURCA9IHRydWU7Ci0KLSAgICAvLyBzdGF0ZQotCi0gICAgLyoqIFNlZW4gZG9jdHlwZSBkZWNsYXJhdGlvbi4gKi8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBmU2VlbkRvY3R5cGVEZWNsOwotCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZlNjYW5FbmRFbGVtZW50OwotCi0gICAgLy9wcm90ZWN0ZWQgaW50IGZTY2FubmVyTGFzdFN0YXRlIDsKLQotICAgIC8vIGRyaXZlcnMKLQotICAgIC8qKiBYTUwgZGVjbGFyYXRpb24gZHJpdmVyLiAqLwotICAgIHByb3RlY3RlZCBEcml2ZXIgZlhNTERlY2xEcml2ZXIgPSBuZXcgWE1MRGVjbERyaXZlcigpOwotCi0gICAgLyoqIFByb2xvZyBkcml2ZXIuICovCi0gICAgcHJvdGVjdGVkIERyaXZlciBmUHJvbG9nRHJpdmVyID0gbmV3IFByb2xvZ0RyaXZlcigpOwotCi0gICAgLyoqIERURCBkcml2ZXIuICovCi0gICAgcHJvdGVjdGVkIERyaXZlciBmRFRERHJpdmVyID0gbnVsbCA7Ci0KLSAgICAvKiogVHJhaWxpbmcgbWlzY2VsbGFuZW91cyBzZWN0aW9uIGRyaXZlci4gKi8KLSAgICBwcm90ZWN0ZWQgRHJpdmVyIGZUcmFpbGluZ01pc2NEcml2ZXIgPSBuZXcgVHJhaWxpbmdNaXNjRHJpdmVyKCk7Ci0gICAgcHJvdGVjdGVkIGludCBmU3RhcnRQb3MgPSAwOwotICAgIHByb3RlY3RlZCBpbnQgZkVuZFBvcyA9IDA7Ci0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZlNlZW5JbnRlcm5hbFN1YnNldD0gZmFsc2U7Ci0gICAgLy8gdGVtcG9yYXJ5IHZhcmlhYmxlcwotCi0gICAgLyoqIEFycmF5IG9mIDMgc3RyaW5ncy4gKi8KLSAgICBwcml2YXRlIFN0cmluZ1tdIGZTdHJpbmdzID0gbmV3IFN0cmluZ1szXTsKLQotICAgIC8qKiBFeHRlcm5hbCBzdWJzZXQgc291cmNlLiAqLwotICAgIHByaXZhdGUgWE1MSW5wdXRTb3VyY2UgZkV4dGVybmFsU3Vic2V0U291cmNlID0gbnVsbDsKLQotICAgIC8qKiBBIERURCBEZXNjcmlwdGlvbi4gKi8KLSAgICBwcml2YXRlIGZpbmFsIFhNTERURERlc2NyaXB0aW9uIGZEVEREZXNjcmlwdGlvbiA9IG5ldyBYTUxEVEREZXNjcmlwdGlvbihudWxsLCBudWxsLCBudWxsLCBudWxsLCBudWxsKTsKLQotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNoYXIgW10gRE9DVFlQRSA9IHsnRCcsJ08nLCdDJywnVCcsJ1knLCdQJywnRSd9OwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNoYXIgW10gQ09NTUVOVFNUUklORyA9IHsnLScsJy0nfTsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKiBEZWZhdWx0IGNvbnN0cnVjdG9yLiAqLwotICAgIHB1YmxpYyBYTUxEb2N1bWVudFNjYW5uZXJJbXBsKCkge30gLy8gPGluaXQ+KCkKLQotCi0gICAgLy8KLSAgICAvLyBYTUxEb2N1bWVudFNjYW5uZXIgbWV0aG9kcwotICAgIC8vCi0KLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIGlucHV0IHNvdXJjZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBpbnB1dFNvdXJjZSBUaGUgaW5wdXQgc291cmNlLgotICAgICAqCi0gICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBUaHJvd24gb24gaS9vIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldElucHV0U291cmNlKFhNTElucHV0U291cmNlIGlucHV0U291cmNlKSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgICAgICBmRW50aXR5TWFuYWdlci5zZXRFbnRpdHlIYW5kbGVyKHRoaXMpOwotICAgICAgICAvL3RoaXMgc3RhcnRzIGEgbmV3IGVudGl0eSBhbmQgc2V0cyB0aGUgY3VycmVudCBlbnRpdHkgdG8gdGhlIGRvY3VtZW50IGVudGl0eS4KLSAgICAgICAgZkVudGl0eU1hbmFnZXIuc3RhcnREb2N1bWVudEVudGl0eShpbnB1dFNvdXJjZSk7Ci0gICAgICAgIC8vIGZEb2N1bWVudFN5c3RlbUlkID0gZkVudGl0eU1hbmFnZXIuZXhwYW5kU3lzdGVtSWQoaW5wdXRTb3VyY2UuZ2V0U3lzdGVtSWQoKSk7Ci0gICAgICAgIHNldFNjYW5uZXJTdGF0ZShYTUxFdmVudC5TVEFSVF9ET0NVTUVOVCk7Ci0gICAgfSAvLyBzZXRJbnB1dFNvdXJjZShYTUxJbnB1dFNvdXJjZSkKLQotCi0KLSAgICAvKipyZXR1cm4gdGhlIHN0YXRlIG9mIHRoZSBzY2FubmVyICovCi0gICAgcHVibGljIGludCBnZXRTY2FubmV0U3RhdGUoKXsKLSAgICAgICAgcmV0dXJuIGZTY2FubmVyU3RhdGUgOwotICAgIH0KLQotCi0KLQotICAgIHB1YmxpYyB2b2lkIHJlc2V0KFByb3BlcnR5TWFuYWdlciBwcm9wZXJ0eU1hbmFnZXIpIHsKLSAgICAgICAgc3VwZXIucmVzZXQocHJvcGVydHlNYW5hZ2VyKTsKLSAgICAgICAgLy8gb3RoZXIgc2V0dGluZ3MKLSAgICAgICAgZkRvY3R5cGVOYW1lID0gbnVsbDsKLSAgICAgICAgZkRvY3R5cGVQdWJsaWNJZCA9IG51bGw7Ci0gICAgICAgIGZEb2N0eXBlU3lzdGVtSWQgPSBudWxsOwotICAgICAgICBmU2VlbkRvY3R5cGVEZWNsID0gZmFsc2U7Ci0gICAgICAgIGZOYW1lc3BhY2VDb250ZXh0LnJlc2V0KCk7Ci0gICAgICAgIGZTdXBwb3J0RFREID0gKChCb29sZWFuKXByb3BlcnR5TWFuYWdlci5nZXRQcm9wZXJ0eShYTUxJbnB1dEZhY3RvcnkuU1VQUE9SVF9EVEQpKS5ib29sZWFuVmFsdWUoKTsKLQotICAgICAgICAvLyB4ZXJjZXMgZmVhdHVyZXMKLSAgICAgICAgZkxvYWRFeHRlcm5hbERURCA9ICEoKEJvb2xlYW4pcHJvcGVydHlNYW5hZ2VyLmdldFByb3BlcnR5KENvbnN0YW50cy5aRVBIWVJfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLklHTk9SRV9FWFRFUk5BTF9EVEQpKS5ib29sZWFuVmFsdWUoKTsKLSAgICAgICAgc2V0U2Nhbm5lclN0YXRlKFhNTEV2ZW50LlNUQVJUX0RPQ1VNRU5UKTsKLSAgICAgICAgc2V0RHJpdmVyKGZYTUxEZWNsRHJpdmVyKTsKLSAgICAgICAgZlNlZW5JbnRlcm5hbFN1YnNldCA9IGZhbHNlOwotICAgICAgICBpZihmRFREU2Nhbm5lciAhPSBudWxsKXsKLSAgICAgICAgICAgICgoWE1MRFREU2Nhbm5lckltcGwpZkRURFNjYW5uZXIpLnJlc2V0KHByb3BlcnR5TWFuYWdlcik7Ci0gICAgICAgIH0KLSAgICAgICAgZkVuZFBvcyA9IDA7Ci0gICAgICAgIGZTdGFydFBvcyA9IDA7Ci0gICAgICAgIGlmKGZEVEREZWNsICE9IG51bGwpewotICAgICAgICAgICAgZkRURERlY2wuY2xlYXIoKTsKLSAgICAgICAgfQotCi0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmVzZXRzIHRoZSBjb21wb25lbnQuIFRoZSBjb21wb25lbnQgY2FuIHF1ZXJ5IHRoZSBjb21wb25lbnQgbWFuYWdlcgotICAgICAqIGFib3V0IGFueSBmZWF0dXJlcyBhbmQgcHJvcGVydGllcyB0aGF0IGFmZmVjdCB0aGUgb3BlcmF0aW9uIG9mIHRoZQotICAgICAqIGNvbXBvbmVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjb21wb25lbnRNYW5hZ2VyIFRoZSBjb21wb25lbnQgbWFuYWdlci4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uIFRocm93biBieSBjb21wb25lbnQgb24gaW5pdGlhbGl6YXRpb24gZXJyb3IuCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgRm9yIGV4YW1wbGUsIGlmIGEgZmVhdHVyZSBvciBwcm9wZXJ0eSBpcwotICAgICAqICAgICAgICAgICAgICAgICAgICAgIHJlcXVpcmVkIGZvciB0aGUgb3BlcmF0aW9uIG9mIHRoZSBjb21wb25lbnQsIHRoZQotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudCBtYW5hZ2VyIG1heSB0aHJvdyBhCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiBvciBhCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHJlc2V0KFhNTENvbXBvbmVudE1hbmFnZXIgY29tcG9uZW50TWFuYWdlcikKLSAgICB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgc3VwZXIucmVzZXQoY29tcG9uZW50TWFuYWdlcik7Ci0KLSAgICAgICAgLy8gb3RoZXIgc2V0dGluZ3MKLSAgICAgICAgZkRvY3R5cGVOYW1lID0gbnVsbDsKLSAgICAgICAgZkRvY3R5cGVQdWJsaWNJZCA9IG51bGw7Ci0gICAgICAgIGZEb2N0eXBlU3lzdGVtSWQgPSBudWxsOwotICAgICAgICBmU2VlbkRvY3R5cGVEZWNsID0gZmFsc2U7Ci0gICAgICAgIGZFeHRlcm5hbFN1YnNldFNvdXJjZSA9IG51bGw7Ci0KLSAgICAgICAgLy8geGVyY2VzIGZlYXR1cmVzCi0gICAgICAgIGZMb2FkRXh0ZXJuYWxEVEQgPSBjb21wb25lbnRNYW5hZ2VyLmdldEZlYXR1cmUoTE9BRF9FWFRFUk5BTF9EVEQsIHRydWUpOwotICAgICAgICBmRGlzYWxsb3dEb2N0eXBlID0gY29tcG9uZW50TWFuYWdlci5nZXRGZWF0dXJlKERJU0FMTE9XX0RPQ1RZUEVfREVDTF9GRUFUVVJFLCBmYWxzZSk7Ci0KLSAgICAgICAgZk5hbWVzcGFjZXMgPSBjb21wb25lbnRNYW5hZ2VyLmdldEZlYXR1cmUoTkFNRVNQQUNFUywgdHJ1ZSk7Ci0KLSAgICAgICAgZlNlZW5JbnRlcm5hbFN1YnNldCA9IGZhbHNlOwotICAgICAgICAvLyB4ZXJjZXMgcHJvcGVydGllcwotICAgICAgICBmRFREU2Nhbm5lciA9IChYTUxEVERTY2FubmVyKWNvbXBvbmVudE1hbmFnZXIuZ2V0UHJvcGVydHkoRFREX1NDQU5ORVIpOwotCi0gICAgICAgIGZWYWxpZGF0aW9uTWFuYWdlciA9IChWYWxpZGF0aW9uTWFuYWdlciljb21wb25lbnRNYW5hZ2VyLmdldFByb3BlcnR5KFZBTElEQVRJT05fTUFOQUdFUiwgbnVsbCk7Ci0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGZOYW1lc3BhY2VDb250ZXh0ID0gKE5hbWVzcGFjZUNvbnRleHQpY29tcG9uZW50TWFuYWdlci5nZXRQcm9wZXJ0eShOQU1FU1BBQ0VfQ09OVEVYVCk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gZSkgeyB9Ci0gICAgICAgIGlmIChmTmFtZXNwYWNlQ29udGV4dCA9PSBudWxsKSB7Ci0gICAgICAgICAgICBmTmFtZXNwYWNlQ29udGV4dCA9IG5ldyBOYW1lc3BhY2VTdXBwb3J0KCk7Ci0gICAgICAgIH0KLSAgICAgICAgZk5hbWVzcGFjZUNvbnRleHQucmVzZXQoKTsKLQotICAgICAgICBmRW5kUG9zID0gMDsKLSAgICAgICAgZlN0YXJ0UG9zID0gMDsKLSAgICAgICAgaWYoZkRURERlY2wgIT0gbnVsbCkKLSAgICAgICAgICAgIGZEVEREZWNsLmNsZWFyKCk7Ci0KLQotICAgICAgICAvL2ZFbnRpdHlTY2FubmVyLnJlZ2lzdGVyTGlzdGVuZXIoKFhNTEJ1ZmZlckxpc3RlbmVyKWNvbXBvbmVudE1hbmFnZXIuZ2V0UHJvcGVydHkoRE9DVU1FTlRfU0NBTk5FUikpOwotCi0gICAgICAgIC8vIHNldHVwIGRyaXZlcgotICAgICAgICBzZXRTY2FubmVyU3RhdGUoU0NBTk5FUl9TVEFURV9YTUxfREVDTCk7Ci0gICAgICAgIHNldERyaXZlcihmWE1MRGVjbERyaXZlcik7Ci0KLSAgICB9IC8vIHJlc2V0KFhNTENvbXBvbmVudE1hbmFnZXIpCi0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYSBsaXN0IG9mIGZlYXR1cmUgaWRlbnRpZmllcnMgdGhhdCBhcmUgcmVjb2duaXplZCBieQotICAgICAqIHRoaXMgY29tcG9uZW50LiBUaGlzIG1ldGhvZCBtYXkgcmV0dXJuIG51bGwgaWYgbm8gZmVhdHVyZXMKLSAgICAgKiBhcmUgcmVjb2duaXplZCBieSB0aGlzIGNvbXBvbmVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nW10gZ2V0UmVjb2duaXplZEZlYXR1cmVzKCkgewotICAgICAgICBTdHJpbmdbXSBmZWF0dXJlSWRzID0gc3VwZXIuZ2V0UmVjb2duaXplZEZlYXR1cmVzKCk7Ci0gICAgICAgIGludCBsZW5ndGggPSBmZWF0dXJlSWRzICE9IG51bGwgPyBmZWF0dXJlSWRzLmxlbmd0aCA6IDA7Ci0gICAgICAgIFN0cmluZ1tdIGNvbWJpbmVkRmVhdHVyZUlkcyA9IG5ldyBTdHJpbmdbbGVuZ3RoICsgUkVDT0dOSVpFRF9GRUFUVVJFUy5sZW5ndGhdOwotICAgICAgICBpZiAoZmVhdHVyZUlkcyAhPSBudWxsKSB7Ci0gICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGZlYXR1cmVJZHMsIDAsIGNvbWJpbmVkRmVhdHVyZUlkcywgMCwgZmVhdHVyZUlkcy5sZW5ndGgpOwotICAgICAgICB9Ci0gICAgICAgIFN5c3RlbS5hcnJheWNvcHkoUkVDT0dOSVpFRF9GRUFUVVJFUywgMCwgY29tYmluZWRGZWF0dXJlSWRzLCBsZW5ndGgsIFJFQ09HTklaRURfRkVBVFVSRVMubGVuZ3RoKTsKLSAgICAgICAgcmV0dXJuIGNvbWJpbmVkRmVhdHVyZUlkczsKLSAgICB9IC8vIGdldFJlY29nbml6ZWRGZWF0dXJlcygpOlN0cmluZ1tdCi0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSBzdGF0ZSBvZiBhIGZlYXR1cmUuIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSB0aGUgY29tcG9uZW50Ci0gICAgICogbWFuYWdlciBhbnkgdGltZSBhZnRlciByZXNldCB3aGVuIGEgZmVhdHVyZSBjaGFuZ2VzIHN0YXRlLgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gQ29tcG9uZW50cyBzaG91bGQgc2lsZW50bHkgaWdub3JlIGZlYXR1cmVzCi0gICAgICogdGhhdCBkbyBub3QgYWZmZWN0IHRoZSBvcGVyYXRpb24gb2YgdGhlIGNvbXBvbmVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBmZWF0dXJlSWQgVGhlIGZlYXR1cmUgaWRlbnRpZmllci4KLSAgICAgKiBAcGFyYW0gc3RhdGUgICAgIFRoZSBzdGF0ZSBvZiB0aGUgZmVhdHVyZS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiBUaGUgY29tcG9uZW50IHNob3VsZCBub3QgdGhyb3cKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcyBleGNlcHRpb24uCi0gICAgICogQHRocm93cyBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gVGhlIGNvbXBvbmVudCBzaG91bGQgbm90IHRocm93Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcyBleGNlcHRpb24uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RmVhdHVyZShTdHJpbmcgZmVhdHVyZUlkLCBib29sZWFuIHN0YXRlKQotICAgIHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIHsKLQotICAgICAgICBzdXBlci5zZXRGZWF0dXJlKGZlYXR1cmVJZCwgc3RhdGUpOwotCi0gICAgICAgIC8vIFhlcmNlcyBwcm9wZXJ0aWVzCi0gICAgICAgIGlmIChmZWF0dXJlSWQuc3RhcnRzV2l0aChDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYKSkgewotICAgICAgICAgICAgZmluYWwgaW50IHN1ZmZpeExlbmd0aCA9IGZlYXR1cmVJZC5sZW5ndGgoKSAtIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVgubGVuZ3RoKCk7Ci0KLSAgICAgICAgICAgIGlmIChzdWZmaXhMZW5ndGggPT0gQ29uc3RhbnRzLkxPQURfRVhURVJOQUxfRFREX0ZFQVRVUkUubGVuZ3RoKCkgJiYKLSAgICAgICAgICAgICAgICBmZWF0dXJlSWQuZW5kc1dpdGgoQ29uc3RhbnRzLkxPQURfRVhURVJOQUxfRFREX0ZFQVRVUkUpKSB7Ci0gICAgICAgICAgICAgICAgZkxvYWRFeHRlcm5hbERURCA9IHN0YXRlOwotICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKHN1ZmZpeExlbmd0aCA9PSBDb25zdGFudHMuRElTQUxMT1dfRE9DVFlQRV9ERUNMX0ZFQVRVUkUubGVuZ3RoKCkgJiYKLSAgICAgICAgICAgICAgICBmZWF0dXJlSWQuZW5kc1dpdGgoQ29uc3RhbnRzLkRJU0FMTE9XX0RPQ1RZUEVfREVDTF9GRUFUVVJFKSkgewotICAgICAgICAgICAgICAgIGZEaXNhbGxvd0RvY3R5cGUgPSBzdGF0ZTsKLSAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgIH0gLy8gc2V0RmVhdHVyZShTdHJpbmcsYm9vbGVhbikKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYSBsaXN0IG9mIHByb3BlcnR5IGlkZW50aWZpZXJzIHRoYXQgYXJlIHJlY29nbml6ZWQgYnkKLSAgICAgKiB0aGlzIGNvbXBvbmVudC4gVGhpcyBtZXRob2QgbWF5IHJldHVybiBudWxsIGlmIG5vIHByb3BlcnRpZXMKLSAgICAgKiBhcmUgcmVjb2duaXplZCBieSB0aGlzIGNvbXBvbmVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nW10gZ2V0UmVjb2duaXplZFByb3BlcnRpZXMoKSB7Ci0gICAgICAgIFN0cmluZ1tdIHByb3BlcnR5SWRzID0gc3VwZXIuZ2V0UmVjb2duaXplZFByb3BlcnRpZXMoKTsKLSAgICAgICAgaW50IGxlbmd0aCA9IHByb3BlcnR5SWRzICE9IG51bGwgPyBwcm9wZXJ0eUlkcy5sZW5ndGggOiAwOwotICAgICAgICBTdHJpbmdbXSBjb21iaW5lZFByb3BlcnR5SWRzID0gbmV3IFN0cmluZ1tsZW5ndGggKyBSRUNPR05JWkVEX1BST1BFUlRJRVMubGVuZ3RoXTsKLSAgICAgICAgaWYgKHByb3BlcnR5SWRzICE9IG51bGwpIHsKLSAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkocHJvcGVydHlJZHMsIDAsIGNvbWJpbmVkUHJvcGVydHlJZHMsIDAsIHByb3BlcnR5SWRzLmxlbmd0aCk7Ci0gICAgICAgIH0KLSAgICAgICAgU3lzdGVtLmFycmF5Y29weShSRUNPR05JWkVEX1BST1BFUlRJRVMsIDAsIGNvbWJpbmVkUHJvcGVydHlJZHMsIGxlbmd0aCwgUkVDT0dOSVpFRF9QUk9QRVJUSUVTLmxlbmd0aCk7Ci0gICAgICAgIHJldHVybiBjb21iaW5lZFByb3BlcnR5SWRzOwotICAgIH0gLy8gZ2V0UmVjb2duaXplZFByb3BlcnRpZXMoKTpTdHJpbmdbXQotCi0gICAgLyoqCi0gICAgICogU2V0cyB0aGUgdmFsdWUgb2YgYSBwcm9wZXJ0eS4gVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBjb21wb25lbnQKLSAgICAgKiBtYW5hZ2VyIGFueSB0aW1lIGFmdGVyIHJlc2V0IHdoZW4gYSBwcm9wZXJ0eSBjaGFuZ2VzIHZhbHVlLgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gQ29tcG9uZW50cyBzaG91bGQgc2lsZW50bHkgaWdub3JlIHByb3BlcnRpZXMKLSAgICAgKiB0aGF0IGRvIG5vdCBhZmZlY3QgdGhlIG9wZXJhdGlvbiBvZiB0aGUgY29tcG9uZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIHByb3BlcnR5SWQgVGhlIHByb3BlcnR5IGlkZW50aWZpZXIuCi0gICAgICogQHBhcmFtIHZhbHVlICAgICAgVGhlIHZhbHVlIG9mIHRoZSBwcm9wZXJ0eS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiBUaGUgY29tcG9uZW50IHNob3VsZCBub3QgdGhyb3cKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcyBleGNlcHRpb24uCi0gICAgICogQHRocm93cyBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gVGhlIGNvbXBvbmVudCBzaG91bGQgbm90IHRocm93Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcyBleGNlcHRpb24uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0UHJvcGVydHkoU3RyaW5nIHByb3BlcnR5SWQsIE9iamVjdCB2YWx1ZSkKLSAgICB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgc3VwZXIuc2V0UHJvcGVydHkocHJvcGVydHlJZCwgdmFsdWUpOwotCi0gICAgICAgIC8vIFhlcmNlcyBwcm9wZXJ0aWVzCi0gICAgICAgIGlmIChwcm9wZXJ0eUlkLnN0YXJ0c1dpdGgoQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVgpKSB7Ci0gICAgICAgICAgICBmaW5hbCBpbnQgc3VmZml4TGVuZ3RoID0gcHJvcGVydHlJZC5sZW5ndGgoKSAtIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYLmxlbmd0aCgpOwotCi0gICAgICAgICAgICBpZiAoc3VmZml4TGVuZ3RoID09IENvbnN0YW50cy5EVERfU0NBTk5FUl9QUk9QRVJUWS5sZW5ndGgoKSAmJgotICAgICAgICAgICAgICAgIHByb3BlcnR5SWQuZW5kc1dpdGgoQ29uc3RhbnRzLkRURF9TQ0FOTkVSX1BST1BFUlRZKSkgewotICAgICAgICAgICAgICAgIGZEVERTY2FubmVyID0gKFhNTERURFNjYW5uZXIpdmFsdWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoc3VmZml4TGVuZ3RoID09IENvbnN0YW50cy5OQU1FU1BBQ0VfQ09OVEVYVF9QUk9QRVJUWS5sZW5ndGgoKSAmJgotICAgICAgICAgICAgICAgIHByb3BlcnR5SWQuZW5kc1dpdGgoQ29uc3RhbnRzLk5BTUVTUEFDRV9DT05URVhUX1BST1BFUlRZKSkgewotICAgICAgICAgICAgICAgIGlmICh2YWx1ZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZOYW1lc3BhY2VDb250ZXh0ID0gKE5hbWVzcGFjZUNvbnRleHQpdmFsdWU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLQotICAgIH0gLy8gc2V0UHJvcGVydHkoU3RyaW5nLE9iamVjdCkKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIGRlZmF1bHQgc3RhdGUgZm9yIGEgZmVhdHVyZSwgb3IgbnVsbCBpZiB0aGlzCi0gICAgICogY29tcG9uZW50IGRvZXMgbm90IHdhbnQgdG8gcmVwb3J0IGEgZGVmYXVsdCB2YWx1ZSBmb3IgdGhpcwotICAgICAqIGZlYXR1cmUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZmVhdHVyZUlkIFRoZSBmZWF0dXJlIGlkZW50aWZpZXIuCi0gICAgICoKLSAgICAgKiBAc2luY2UgWGVyY2VzIDIuMi4wCi0gICAgICovCi0gICAgcHVibGljIEJvb2xlYW4gZ2V0RmVhdHVyZURlZmF1bHQoU3RyaW5nIGZlYXR1cmVJZCkgewotCi0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgUkVDT0dOSVpFRF9GRUFUVVJFUy5sZW5ndGg7IGkrKykgewotICAgICAgICAgICAgaWYgKFJFQ09HTklaRURfRkVBVFVSRVNbaV0uZXF1YWxzKGZlYXR1cmVJZCkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gRkVBVFVSRV9ERUZBVUxUU1tpXTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gc3VwZXIuZ2V0RmVhdHVyZURlZmF1bHQoZmVhdHVyZUlkKTsKLSAgICB9IC8vIGdldEZlYXR1cmVEZWZhdWx0KFN0cmluZyk6Qm9vbGVhbgotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgZGVmYXVsdCBzdGF0ZSBmb3IgYSBwcm9wZXJ0eSwgb3IgbnVsbCBpZiB0aGlzCi0gICAgICogY29tcG9uZW50IGRvZXMgbm90IHdhbnQgdG8gcmVwb3J0IGEgZGVmYXVsdCB2YWx1ZSBmb3IgdGhpcwotICAgICAqIHByb3BlcnR5LgotICAgICAqCi0gICAgICogQHBhcmFtIHByb3BlcnR5SWQgVGhlIHByb3BlcnR5IGlkZW50aWZpZXIuCi0gICAgICoKLSAgICAgKiBAc2luY2UgWGVyY2VzIDIuMi4wCi0gICAgICovCi0gICAgcHVibGljIE9iamVjdCBnZXRQcm9wZXJ0eURlZmF1bHQoU3RyaW5nIHByb3BlcnR5SWQpIHsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBSRUNPR05JWkVEX1BST1BFUlRJRVMubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgIGlmIChSRUNPR05JWkVEX1BST1BFUlRJRVNbaV0uZXF1YWxzKHByb3BlcnR5SWQpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIFBST1BFUlRZX0RFRkFVTFRTW2ldOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBzdXBlci5nZXRQcm9wZXJ0eURlZmF1bHQocHJvcGVydHlJZCk7Ci0gICAgfSAvLyBnZXRQcm9wZXJ0eURlZmF1bHQoU3RyaW5nKTpPYmplY3QKLQotICAgIC8vCi0gICAgLy8gWE1MRW50aXR5SGFuZGxlciBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIG5vdGlmaWVzIG9mIHRoZSBzdGFydCBvZiBhbiBlbnRpdHkuIFRoZSBEVEQgaGFzIHRoZQotICAgICAqIHBzZXVkby1uYW1lIG9mICJbZHRkXSIgcGFyYW1ldGVyIGVudGl0eSBuYW1lcyBzdGFydCB3aXRoICclJzsgYW5kCi0gICAgICogZ2VuZXJhbCBlbnRpdGllcyBhcmUganVzdCBzcGVjaWZpZWQgYnkgdGhlaXIgbmFtZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lICAgICBUaGUgbmFtZSBvZiB0aGUgZW50aXR5LgotICAgICAqIEBwYXJhbSBpZGVudGlmaWVyIFRoZSByZXNvdXJjZSBpZGVudGlmaWVyLgotICAgICAqIEBwYXJhbSBlbmNvZGluZyBUaGUgYXV0by1kZXRlY3RlZCBJQU5BIGVuY29kaW5nIG5hbWUgb2YgdGhlIGVudGl0eQotICAgICAqICAgICAgICAgICAgICAgICBzdHJlYW0uIFRoaXMgdmFsdWUgd2lsbCBiZSBudWxsIGluIHRob3NlIHNpdHVhdGlvbnMKLSAgICAgKiAgICAgICAgICAgICAgICAgd2hlcmUgdGhlIGVudGl0eSBlbmNvZGluZyBpcyBub3QgYXV0by1kZXRlY3RlZCAoZS5nLgotICAgICAqICAgICAgICAgICAgICAgICBpbnRlcm5hbCBlbnRpdGllcyBvciBhIGRvY3VtZW50IGVudGl0eSB0aGF0IGlzCi0gICAgICogICAgICAgICAgICAgICAgIHBhcnNlZCBmcm9tIGEgamF2YS5pby5SZWFkZXIpLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RW50aXR5KFN0cmluZyBuYW1lLAotICAgICAgICAgICAgWE1MUmVzb3VyY2VJZGVudGlmaWVyIGlkZW50aWZpZXIsCi0gICAgICAgICAgICBTdHJpbmcgZW5jb2RpbmcsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgc3VwZXIuc3RhcnRFbnRpdHkobmFtZSwgaWRlbnRpZmllciwgZW5jb2RpbmcsYXVncyk7Ci0KLSAgICAgICAgLy9yZWdpc3RlciBjdXJyZW50IGRvY3VtZW50IHNjYW5uZXIgYXMgYSBsaXN0ZW5lciBmb3IgWE1MRW50aXR5U2Nhbm5lcgotICAgICAgICBmRW50aXR5U2Nhbm5lci5yZWdpc3Rlckxpc3RlbmVyKHRoaXMpOwotCi0gICAgICAgIC8vIHByZXBhcmUgdG8gbG9vayBmb3IgYSBUZXh0RGVjbCBpZiBleHRlcm5hbCBnZW5lcmFsIGVudGl0eQotICAgICAgICBpZiAoIW5hbWUuZXF1YWxzKCJbeG1sXSIpICYmIGZFbnRpdHlTY2FubmVyLmlzRXh0ZXJuYWwoKSkgewotICAgICAgICAgICAgLy8gRG9uJ3QgZG8gdGhpcyBpZiB3ZSdyZSBza2lwcGluZyB0aGUgZW50aXR5IQotICAgICAgICAgICAgaWYgKGF1Z3MgPT0gbnVsbCB8fCAhKChCb29sZWFuKSBhdWdzLmdldEl0ZW0oQ29uc3RhbnRzLkVOVElUWV9TS0lQUEVEKSkuYm9vbGVhblZhbHVlKCkpIHsKLSAgICAgICAgICAgICAgICBzZXRTY2FubmVyU3RhdGUoU0NBTk5FUl9TVEFURV9URVhUX0RFQ0wpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gY2FsbCBoYW5kbGVyCi0gICAgICAgIC8qKiBjb21tZW50IHRoaXMgcGFydC4uIExPQ0FUT1IgcHJvYmxlbS4uICovCi0gICAgICAgIGlmIChmRG9jdW1lbnRIYW5kbGVyICE9IG51bGwgJiYgbmFtZS5lcXVhbHMoIlt4bWxdIikpIHsKLSAgICAgICAgICAgIGZEb2N1bWVudEhhbmRsZXIuc3RhcnREb2N1bWVudChmRW50aXR5U2Nhbm5lciwgZW5jb2RpbmcsIGZOYW1lc3BhY2VDb250ZXh0LCBudWxsKTsKLSAgICAgICAgfQotCi0gICAgfSAvLyBzdGFydEVudGl0eShTdHJpbmcsaWRlbnRpZmllcixTdHJpbmcpCi0KLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIG5vdGlmaWVzIHRoZSBlbmQgb2YgYW4gZW50aXR5LiBUaGUgRFREIGhhcyB0aGUgcHNldWRvLW5hbWUKLSAgICAgKiBvZiAiW2R0ZF0iIHBhcmFtZXRlciBlbnRpdHkgbmFtZXMgc3RhcnQgd2l0aCAnJSc7IGFuZCBnZW5lcmFsIGVudGl0aWVzCi0gICAgICogYXJlIGp1c3Qgc3BlY2lmaWVkIGJ5IHRoZWlyIG5hbWUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgZW50aXR5LgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZEVudGl0eShTdHJpbmcgbmFtZSwgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgSU9FeGNlcHRpb24sIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgc3VwZXIuZW5kRW50aXR5KG5hbWUsIGF1Z3MpOwotCi0gICAgICAgIGlmKG5hbWUuZXF1YWxzKCJbeG1sXSIpKXsKLSAgICAgICAgICAgIC8vaWYgZk1hcmt1cERlcHRoIGhhcyByZWFjaGVkIDAuCi0gICAgICAgICAgICAvL2FuZCBkcml2ZXIgaXMgZlRyYWlsaW5nTWlzY0RyaXZlciAod2hpY2gKLSAgICAgICAgICAgIC8vaGFuZGxlcyBlbmQgb2YgZG9jdW1lbnQgaW4gbm9ybWFsIGNhc2UpCi0gICAgICAgICAgICAvL3NldCB0aGUgc2Nhbm5lciBzdGF0ZSBvZiBTQ0FOTkVSX1NUQVRFX1RFUk1JTkFURUQKLSAgICAgICAgICAgIGlmKGZNYXJrdXBEZXB0aCA9PSAwICYmIGZEcml2ZXIgPT0gZlRyYWlsaW5nTWlzY0RyaXZlcil7Ci0gICAgICAgICAgICAgICAgLy9zZXQgdGhlIHNjYW5uZXIgc2V0IHRvIFNDQU5ORVJfU1RBVEVfVEVSTUlOQVRFRAotICAgICAgICAgICAgICAgIHNldFNjYW5uZXJTdGF0ZShTQ0FOTkVSX1NUQVRFX1RFUk1JTkFURUQpIDsKLSAgICAgICAgICAgIH0gZWxzZXsKLSAgICAgICAgICAgICAgICAvL2Vsc2Ugd2UgaGF2ZSByZWFjaGVkIHRoZSBlbmQgb2YgZG9jdW1lbnQgcHJlbWF0dXJlbHkKLSAgICAgICAgICAgICAgICAvL3NvIHRocm93IEVPRkV4Y2VwdGlvbi4KLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgamF2YS5pby5FT0ZFeGNlcHRpb24oKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy90aGlzIGlzIHRha2VuIGNhcmUgaW4gd3JhcHBlciB3aGljaCBnZW5lcmF0ZXMgWE5JIGNhbGxiYWNrcywgVGhlcmUgYXJlIG5vIG5leHQgZXZlbnRzCi0KLSAgICAgICAgICAgIC8vaWYgKGZEb2N1bWVudEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIC8vZkRvY3VtZW50SGFuZGxlci5lbmREb2N1bWVudChudWxsKTsKLSAgICAgICAgICAgIC8vfQotICAgICAgICB9Ci0gICAgfSAvLyBlbmRFbnRpdHkoU3RyaW5nKQotCi0KLSAgICBwdWJsaWMgWE1MU3RyaW5nQnVmZmVyIGdldERURERlY2woKXsKLSAgICAgICAgRW50aXR5IGVudGl0eSA9IGZFbnRpdHlTY2FubmVyLmdldEN1cnJlbnRFbnRpdHkoKTsKLSAgICAgICAgZkRURERlY2wuYXBwZW5kKCgoRW50aXR5LlNjYW5uZWRFbnRpdHkpZW50aXR5KS5jaCxmU3RhcnRQb3MgLCBmRW5kUG9zLWZTdGFydFBvcyk7Ci0gICAgICAgIGlmKGZTZWVuSW50ZXJuYWxTdWJzZXQpCi0gICAgICAgICAgICBmRFRERGVjbC5hcHBlbmQoIl0+Iik7Ci0gICAgICAgIHJldHVybiBmRFRERGVjbDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldENoYXJhY3RlckVuY29kaW5nU2NoZW1lKCl7Ci0gICAgICAgIHJldHVybiBmRGVjbGFyZWRFbmNvZGluZzsKLSAgICB9Ci0KLSAgICAvKiogcmV0dXJuIHRoZSBuZXh0IHN0YXRlIG9uIHRoZSBpbnB1dAotICAgICAqCi0gICAgICogQHJldHVybiBpbnQKLSAgICAgKi8KLQotICAgIHB1YmxpYyBpbnQgbmV4dCgpIHRocm93cyBJT0V4Y2VwdGlvbiwgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgcmV0dXJuIGZEcml2ZXIubmV4dCgpOwotICAgIH0KLQotICAgIC8vZ2V0TmFtZXNwYWNlQ29udGV4dAotICAgIHB1YmxpYyBOYW1lc3BhY2VDb250ZXh0IGdldE5hbWVzcGFjZUNvbnRleHQoKXsKLSAgICAgICAgcmV0dXJuIGZOYW1lc3BhY2VDb250ZXh0IDsKLSAgICB9Ci0KLQotCi0gICAgLy8KLSAgICAvLyBQcm90ZWN0ZWQgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvLyBkcml2ZXIgZmFjdG9yeSBtZXRob2RzCi0KLSAgICAvKiogQ3JlYXRlcyBhIGNvbnRlbnQgZHJpdmVyLiAqLwotICAgIHByb3RlY3RlZCBEcml2ZXIgY3JlYXRlQ29udGVudERyaXZlcigpIHsKLSAgICAgICAgcmV0dXJuIG5ldyBDb250ZW50RHJpdmVyKCk7Ci0gICAgfSAvLyBjcmVhdGVDb250ZW50RHJpdmVyKCk6RHJpdmVyCi0KLSAgICAvLyBzY2FubmluZyBtZXRob2RzCi0KLSAgICAvKiogU2NhbnMgYSBkb2N0eXBlIGRlY2xhcmF0aW9uLiAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIHNjYW5Eb2N0eXBlRGVjbChib29sZWFuIHN1cHBvcnREVEQpIHRocm93cyBJT0V4Y2VwdGlvbiwgWE5JRXhjZXB0aW9uIHsKLQotICAgICAgICAvLyBzcGFjZXMKLSAgICAgICAgaWYgKCFmRW50aXR5U2Nhbm5lci5za2lwU3BhY2VzKCkpIHsKLSAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIk1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfUk9PVF9FTEVNRU5UX1RZUEVfSU5fRE9DVFlQRURFQ0wiLAotICAgICAgICAgICAgICAgICAgICBudWxsKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIHJvb3QgZWxlbWVudCBuYW1lCi0gICAgICAgIGZEb2N0eXBlTmFtZSA9IGZFbnRpdHlTY2FubmVyLnNjYW5OYW1lKE5hbWVUeXBlLkRPQ1RZUEUpOwotICAgICAgICBpZiAoZkRvY3R5cGVOYW1lID09IG51bGwpIHsKLSAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIk1TR19ST09UX0VMRU1FTlRfVFlQRV9SRVFVSVJFRCIsIG51bGwpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gZXh0ZXJuYWwgaWQKLSAgICAgICAgaWYgKGZFbnRpdHlTY2FubmVyLnNraXBTcGFjZXMoKSkgewotICAgICAgICAgICAgc2NhbkV4dGVybmFsSUQoZlN0cmluZ3MsIGZhbHNlKTsKLSAgICAgICAgICAgIGZEb2N0eXBlU3lzdGVtSWQgPSBmU3RyaW5nc1swXTsKLSAgICAgICAgICAgIGZEb2N0eXBlUHVibGljSWQgPSBmU3RyaW5nc1sxXTsKLSAgICAgICAgICAgIGZFbnRpdHlTY2FubmVyLnNraXBTcGFjZXMoKTsKLSAgICAgICAgfQotCi0gICAgICAgIGZIYXNFeHRlcm5hbERURCA9IGZEb2N0eXBlU3lzdGVtSWQgIT0gbnVsbDsKLQotICAgICAgICAvLyBBdHRlbXB0IHRvIGxvY2F0ZSBhbiBleHRlcm5hbCBzdWJzZXQgd2l0aCBhbiBleHRlcm5hbCBzdWJzZXQgcmVzb2x2ZXIuCi0gICAgICAgIGlmIChzdXBwb3J0RFREICYmICFmSGFzRXh0ZXJuYWxEVEQgJiYgZkV4dGVybmFsU3Vic2V0UmVzb2x2ZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkRURERlc2NyaXB0aW9uLnNldFZhbHVlcyhudWxsLCBudWxsLCBmRW50aXR5TWFuYWdlci5nZXRDdXJyZW50UmVzb3VyY2VJZGVudGlmaWVyKCkuZ2V0RXhwYW5kZWRTeXN0ZW1JZCgpLCBudWxsKTsKLSAgICAgICAgICAgIGZEVEREZXNjcmlwdGlvbi5zZXRSb290TmFtZShmRG9jdHlwZU5hbWUpOwotICAgICAgICAgICAgZkV4dGVybmFsU3Vic2V0U291cmNlID0gZkV4dGVybmFsU3Vic2V0UmVzb2x2ZXIuZ2V0RXh0ZXJuYWxTdWJzZXQoZkRURERlc2NyaXB0aW9uKTsKLSAgICAgICAgICAgIGZIYXNFeHRlcm5hbERURCA9IGZFeHRlcm5hbFN1YnNldFNvdXJjZSAhPSBudWxsOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gY2FsbCBoYW5kbGVyCi0gICAgICAgIGlmIChzdXBwb3J0RFREICYmIGZEb2N1bWVudEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgLy8gTk9URTogSSBkb24ndCBsaWtlIGNhbGxpbmcgdGhlIGRvY3R5cGVEZWNsIGNhbGxiYWNrIHVudGlsCi0gICAgICAgICAgICAvLyAgICAgICBlbmQgb2YgdGhlICpmdWxsKiBkb2N0eXBlIGxpbmUgKGluY2x1ZGluZyBpbnRlcm5hbAotICAgICAgICAgICAgLy8gICAgICAgc3Vic2V0KSBpcyBwYXJzZWQgY29ycmVjdGx5IGJ1dCBTQVgyIHJlcXVpcmVzIHRoYXQKLSAgICAgICAgICAgIC8vICAgICAgIGl0IGtub3dzIHRoZSByb290IGVsZW1lbnQgbmFtZSBhbmQgcHVibGljIGFuZCBzeXN0ZW0KLSAgICAgICAgICAgIC8vICAgICAgIGlkZW50aWZpZXIgZm9yIHRoZSBzdGFydERURCBjYWxsLiAtQWMKLSAgICAgICAgICAgIGlmIChmRXh0ZXJuYWxTdWJzZXRTb3VyY2UgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZEb2N1bWVudEhhbmRsZXIuZG9jdHlwZURlY2woZkRvY3R5cGVOYW1lLCBmRG9jdHlwZVB1YmxpY0lkLCBmRG9jdHlwZVN5c3RlbUlkLCBudWxsKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIGZEb2N1bWVudEhhbmRsZXIuZG9jdHlwZURlY2woZkRvY3R5cGVOYW1lLCBmRXh0ZXJuYWxTdWJzZXRTb3VyY2UuZ2V0UHVibGljSWQoKSwgZkV4dGVybmFsU3Vic2V0U291cmNlLmdldFN5c3RlbUlkKCksIG51bGwpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gaXMgdGhlcmUgYW4gaW50ZXJuYWwgc3Vic2V0PwotICAgICAgICBib29sZWFuIGludGVybmFsU3Vic2V0ID0gdHJ1ZTsKLSAgICAgICAgaWYgKCFmRW50aXR5U2Nhbm5lci5za2lwQ2hhcignWycsIG51bGwpKSB7Ci0gICAgICAgICAgICBpbnRlcm5hbFN1YnNldCA9IGZhbHNlOwotICAgICAgICAgICAgZkVudGl0eVNjYW5uZXIuc2tpcFNwYWNlcygpOwotICAgICAgICAgICAgaWYgKCFmRW50aXR5U2Nhbm5lci5za2lwQ2hhcignPicsIG51bGwpKSB7Ci0gICAgICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiRG9jdHlwZWRlY2xVbnRlcm1pbmF0ZWQiLCBuZXcgT2JqZWN0W117ZkRvY3R5cGVOYW1lfSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmTWFya3VwRGVwdGgtLTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gaW50ZXJuYWxTdWJzZXQ7Ci0KLSAgICB9IC8vIHNjYW5Eb2N0eXBlRGVjbCgpOmJvb2xlYW4KLQotICAgIC8vCi0gICAgLy8gUHJpdmF0ZSBtZXRob2RzCi0gICAgLy8KLSAgICAvKiogU2V0IHRoZSBzY2FubmVyIHN0YXRlIGFmdGVyIHNjYW5uaW5nIERURCAqLwotICAgIHByb3RlY3RlZCB2b2lkIHNldEVuZERURFNjYW5TdGF0ZSgpIHsKLSAgICAgICAgc2V0U2Nhbm5lclN0YXRlKFNDQU5ORVJfU1RBVEVfUFJPTE9HKTsKLSAgICAgICAgc2V0RHJpdmVyKGZQcm9sb2dEcml2ZXIpOwotICAgICAgICBmRW50aXR5TWFuYWdlci5zZXRFbnRpdHlIYW5kbGVyKFhNTERvY3VtZW50U2Nhbm5lckltcGwudGhpcyk7Ci0gICAgICAgIGZSZWFkaW5nRFREPWZhbHNlOwotICAgIH0KLQotICAgIC8qKiBSZXR1cm5zIHRoZSBzY2FubmVyIHN0YXRlIG5hbWUuICovCi0gICAgcHJvdGVjdGVkIFN0cmluZyBnZXRTY2FubmVyU3RhdGVOYW1lKGludCBzdGF0ZSkgewotCi0gICAgICAgIHN3aXRjaCAoc3RhdGUpIHsKLSAgICAgICAgICAgIGNhc2UgU0NBTk5FUl9TVEFURV9YTUxfREVDTDogcmV0dXJuICJTQ0FOTkVSX1NUQVRFX1hNTF9ERUNMIjsKLSAgICAgICAgICAgIGNhc2UgU0NBTk5FUl9TVEFURV9QUk9MT0c6IHJldHVybiAiU0NBTk5FUl9TVEFURV9QUk9MT0ciOwotICAgICAgICAgICAgY2FzZSBTQ0FOTkVSX1NUQVRFX1RSQUlMSU5HX01JU0M6IHJldHVybiAiU0NBTk5FUl9TVEFURV9UUkFJTElOR19NSVNDIjsKLSAgICAgICAgICAgIGNhc2UgU0NBTk5FUl9TVEFURV9EVERfSU5URVJOQUxfREVDTFM6IHJldHVybiAiU0NBTk5FUl9TVEFURV9EVERfSU5URVJOQUxfREVDTFMiOwotICAgICAgICAgICAgY2FzZSBTQ0FOTkVSX1NUQVRFX0RURF9FWFRFUk5BTDogcmV0dXJuICJTQ0FOTkVSX1NUQVRFX0RURF9FWFRFUk5BTCI7Ci0gICAgICAgICAgICBjYXNlIFNDQU5ORVJfU1RBVEVfRFREX0VYVEVSTkFMX0RFQ0xTOiByZXR1cm4gIlNDQU5ORVJfU1RBVEVfRFREX0VYVEVSTkFMX0RFQ0xTIjsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gc3VwZXIuZ2V0U2Nhbm5lclN0YXRlTmFtZShzdGF0ZSk7Ci0KLSAgICB9IC8vIGdldFNjYW5uZXJTdGF0ZU5hbWUoaW50KTpTdHJpbmcKLQotICAgIC8vCi0gICAgLy8gQ2xhc3NlcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBEcml2ZXIgdG8gaGFuZGxlIFhNTERlY2wgc2Nhbm5pbmcuCi0gICAgICoKLSAgICAgKiBUaGlzIGNsYXNzIGhhcyBiZWVuIG1vZGlmaWVkIGFzIHBlciB0aGUgbmV3IGRlc2lnbiB3aGljaCBpcyBtb3JlIHN1aXRlZCB0bwotICAgICAqIGVmZmljaWVudGx5IGJ1aWxkIHB1bGwgcGFyc2VyLiBMb3RzIG9mIHBlcmZvcm1hbmNlIGltcHJvdmVtZW50cyBoYXZlIGJlZW4gZG9uZSBhbmQKLSAgICAgKiB0aGUgY29kZSBoYXMgYmVlbiBhZGRlZCB0byBzdXBwb3J0IHN0YXggZnVuY3Rpb25hbGl0eS9mZWF0dXJlcy4KLSAgICAgKgotICAgICAqIEBhdXRob3IgTmVlcmFqIEJhamFqLCBTdW4gTWljcm9zeXN0ZW1zLgotICAgICAqCi0gICAgICogQGF1dGhvciBBbmR5IENsYXJrLCBJQk0KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgZmluYWwgY2xhc3MgWE1MRGVjbERyaXZlcgotICAgICAgICAgICAgaW1wbGVtZW50cyBEcml2ZXIgewotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIERyaXZlciBtZXRob2RzCi0gICAgICAgIC8vCi0KLQotICAgICAgICBwdWJsaWMgaW50IG5leHQoKSB0aHJvd3MgSU9FeGNlcHRpb24sIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICBpZihERUJVR19ORVhUKXsKLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIk5PVyBJTiBYTUxEZWNsRHJpdmVyIik7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIG5leHQgZHJpdmVyIGlzIHByb2xvZyByZWdhcmRsZXNzIG9mIHdoZXRoZXIgdGhlcmUKLSAgICAgICAgICAgIC8vIGlzIGFuIFhNTERlY2wgaW4gdGhpcyBkb2N1bWVudAotICAgICAgICAgICAgc2V0U2Nhbm5lclN0YXRlKFNDQU5ORVJfU1RBVEVfUFJPTE9HKTsKLSAgICAgICAgICAgIHNldERyaXZlcihmUHJvbG9nRHJpdmVyKTsKLQotICAgICAgICAgICAgLy9TeXN0ZW0ub3V0LnByaW50bG4oImZFbnRpdHlTY2FubmVyID0gIiArIGZFbnRpdHlTY2FubmVyKTsKLSAgICAgICAgICAgIC8vIHNjYW4gWE1MRGVjbAotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICBpZiAoZkVudGl0eVNjYW5uZXIuc2tpcFN0cmluZyh4bWxEZWNsKSkgewotICAgICAgICAgICAgICAgICAgICBmTWFya3VwRGVwdGgrKzsKLSAgICAgICAgICAgICAgICAgICAgLy8gTk9URTogc3BlY2lhbCBjYXNlIHdoZXJlIGRvY3VtZW50IHN0YXJ0cyB3aXRoIGEgUEkKLSAgICAgICAgICAgICAgICAgICAgLy8gICAgICAgd2hvc2UgbmFtZSBzdGFydHMgd2l0aCAieG1sIiAoZS5nLiAieG1sZm9vIikKLSAgICAgICAgICAgICAgICAgICAgaWYgKFhNTENoYXIuaXNOYW1lKGZFbnRpdHlTY2FubmVyLnBlZWtDaGFyKCkpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmU3RyaW5nQnVmZmVyLmNsZWFyKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmU3RyaW5nQnVmZmVyLmFwcGVuZCgieG1sIik7Ci0gICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoWE1MQ2hhci5pc05hbWUoZkVudGl0eVNjYW5uZXIucGVla0NoYXIoKSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmU3RyaW5nQnVmZmVyLmFwcGVuZCgoY2hhcilmRW50aXR5U2Nhbm5lci5zY2FuQ2hhcihudWxsKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdGFyZ2V0ID0gZlN5bWJvbFRhYmxlLmFkZFN5bWJvbChmU3RyaW5nQnVmZmVyLmNoLCBmU3RyaW5nQnVmZmVyLm9mZnNldCwgZlN0cmluZ0J1ZmZlci5sZW5ndGgpOwotICAgICAgICAgICAgICAgICAgICAgICAgLy90aGlzIGZ1bmN0aW9uIHNob3VsZCBmaWxsIHRoZSBkYXRhLi4gYW5kIHNldCB0aGUgZkV2ZW50IG9iamVjdCB0byB0aGlzIGV2ZW50LgotICAgICAgICAgICAgICAgICAgICAgICAgZkNvbnRlbnRCdWZmZXIuY2xlYXIoKSA7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzY2FuUElEYXRhKHRhcmdldCwgZkNvbnRlbnRCdWZmZXIpOwotICAgICAgICAgICAgICAgICAgICAgICAgLy9SRVZJU0lUOndoZXJlIGVsc2Ugd2UgY2FuIHNldCB0aGlzIHZhbHVlIHRvICd0cnVlJwotICAgICAgICAgICAgICAgICAgICAgICAgZkVudGl0eU1hbmFnZXIuZkN1cnJlbnRFbnRpdHkubWF5UmVhZENodW5rcyA9IHRydWU7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvL3JldHVybiBQSSBldmVudCBzaW5jZSBQSSB3YXMgZW5jb3VudGVyZWQKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBYTUxFdmVudC5QUk9DRVNTSU5HX0lOU1RSVUNUSU9OIDsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAvLyBzdGFuZGFyZCBYTUwgZGVjbGFyYXRpb24KLSAgICAgICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzY2FuWE1MRGVjbE9yVGV4dERlY2woZmFsc2UpOwotICAgICAgICAgICAgICAgICAgICAgICAgLy9SRVZJU0lUOndoZXJlIGVsc2Ugd2UgY2FuIHNldCB0aGlzIHZhbHVlIHRvICd0cnVlJwotICAgICAgICAgICAgICAgICAgICAgICAgZkVudGl0eU1hbmFnZXIuZkN1cnJlbnRFbnRpdHkubWF5UmVhZENodW5rcyA9IHRydWU7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gWE1MRXZlbnQuU1RBUlRfRE9DVU1FTlQ7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9IGVsc2V7Ci0gICAgICAgICAgICAgICAgICAgIC8vUkVWSVNJVDp3aGVyZSBlbHNlIHdlIGNhbiBzZXQgdGhpcyB2YWx1ZSB0byAndHJ1ZScKLSAgICAgICAgICAgICAgICAgICAgZkVudGl0eU1hbmFnZXIuZkN1cnJlbnRFbnRpdHkubWF5UmVhZENodW5rcyA9IHRydWU7Ci0gICAgICAgICAgICAgICAgICAgIC8vSW4gYm90aCBjYXNlIHJldHVybiB0aGUgU1RBUlRfRE9DVU1FTlQuIG9ueSBkaWZmZXJlbmNlIGlzIHRoYXQgZmlyc3QgYmxvY2sgd2lsbAotICAgICAgICAgICAgICAgICAgICAvL2Nvc3VtZSB0aGUgWE1MIGRlY2xhcmF0aW9uIGlmIGFueS4KLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFhNTEV2ZW50LlNUQVJUX0RPQ1VNRU5UOwotICAgICAgICAgICAgICAgIH0KLQotCi0gICAgICAgICAgICAgICAgLy9TVEFSVF9PRl9USEVfRE9DVU1FTlQKLQotCi0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIHByZW1hdHVyZSBlbmQgb2YgZmlsZQotICAgICAgICAgICAgY2F0Y2ggKEVPRkV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiUHJlbWF0dXJlRU9GIiwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIC0xOwotICAgICAgICAgICAgICAgIC8vdGhyb3cgZTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICB9Ci0gICAgfSAvLyBjbGFzcyBYTUxEZWNsRHJpdmVyCi0KLSAgICAvKioKLSAgICAgKiBEcml2ZXIgdG8gaGFuZGxlIHByb2xvZyBzY2FubmluZy4KLSAgICAgKgotICAgICAqIEBhdXRob3IgQW5keSBDbGFyaywgSUJNCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGZpbmFsIGNsYXNzIFByb2xvZ0RyaXZlcgotICAgICAgICAgICAgaW1wbGVtZW50cyBEcml2ZXIgewotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBEcml2ZXMgdGhlIHBhcnNlciB0byB0aGUgbmV4dCBzdGF0ZS9ldmVudCBvbiB0aGUgaW5wdXQuIFBhcnNlciBpcyBndWFyYW50ZWVkCi0gICAgICAgICAqIHRvIHN0b3AgYXQgdGhlIG5leHQgc3RhdGUvZXZlbnQuCi0gICAgICAgICAqCi0gICAgICAgICAqIEludGVybmFsbHkgWE1MIGRvY3VtZW50IGlzIGRpdmlkZWQgaW50byBzZXZlcmFsIHN0YXRlcy4gRWFjaCBzdGF0ZSByZXByZXNlbnRzCi0gICAgICAgICAqIGEgc2VjdGlvbnMgb2YgWE1MIGRvY3VtZW50LiBXaGVuIHRoaXMgZnVuY3Rpb25zIHJldHVybnMgbm9ybWFsbHksIGl0IGhhcyByZWFkCi0gICAgICAgICAqIHRoZSBzZWN0aW9uIG9mIFhNTCBkb2N1bWVudCBhbmQgcmV0dXJucyB0aGUgc3RhdGUgY29ycmVzcG9uZGluZyB0byBzZWN0aW9uIG9mCi0gICAgICAgICAqIGRvY3VtZW50IHdoaWNoIGhhcyBiZWVuIHJlYWQuIEZvciBvcHRpbWl6YXRpb25zLCBhIHBhcnRpY3VsYXIgZHJpdmVyCi0gICAgICAgICAqIGNhbiByZWFkIGFoZWFkIG9mIHRoZSBzZWN0aW9uIG9mIGRvY3VtZW50IChzdGF0ZSByZXR1cm5lZCkganVzdCByZWFkIGFuZAotICAgICAgICAgKiBjYW4gbWFpbnRhaW4gYSBkaWZmZXJlbnQgaW50ZXJuYWwgc3RhdGUuCi0gICAgICAgICAqCi0gICAgICAgICAqIEByZXR1cm4gc3RhdGUgcmVwcmVzZW50aW5nIHRoZSBzZWN0aW9uIG9mIGRvY3VtZW50IGp1c3QgcmVhZC4KLSAgICAgICAgICoKLSAgICAgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiAgVGhyb3duIG9uIGkvbyBlcnJvci4KLSAgICAgICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIG9uIHBhcnNlIGVycm9yLgotICAgICAgICAgKi8KLQotICAgICAgICBwdWJsaWMgaW50IG5leHQoKSB0aHJvd3MgSU9FeGNlcHRpb24sIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICAvL1N5c3RlbS5vdXQucHJpbnRsbigiaGVyZSBpbiBuZXh0Iik7Ci0KLSAgICAgICAgICAgIGlmKERFQlVHX05FWFQpewotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiTk9XIElOIFByb2xvZ0RyaXZlciIpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICBkbyB7Ci0gICAgICAgICAgICAgICAgICAgIHN3aXRjaCAoZlNjYW5uZXJTdGF0ZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBTQ0FOTkVSX1NUQVRFX1BST0xPRzogewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZFbnRpdHlTY2FubmVyLnNraXBTcGFjZXMoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZkVudGl0eVNjYW5uZXIuc2tpcENoYXIoJzwnLCBudWxsKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRTY2FubmVyU3RhdGUoU0NBTk5FUl9TVEFURV9TVEFSVF9PRl9NQVJLVVApOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZkVudGl0eVNjYW5uZXIuc2tpcENoYXIoJyYnLCBOYW1lVHlwZS5SRUZFUkVOQ0UpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldFNjYW5uZXJTdGF0ZShTQ0FOTkVSX1NUQVRFX1JFRkVSRU5DRSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0U2Nhbm5lclN0YXRlKFNDQU5ORVJfU1RBVEVfQ09OVEVOVCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFNDQU5ORVJfU1RBVEVfU1RBUlRfT0ZfTUFSS1VQOiB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZk1hcmt1cERlcHRoKys7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzVmFsaWROYW1lU3RhcnRDaGFyKGZFbnRpdHlTY2FubmVyLnBlZWtDaGFyKCkpIHx8Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc1ZhbGlkTmFtZVN0YXJ0SGlnaFN1cnJvZ2F0ZShmRW50aXR5U2Nhbm5lci5wZWVrQ2hhcigpKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRTY2FubmVyU3RhdGUoU0NBTk5FUl9TVEFURV9ST09UX0VMRU1FTlQpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXREcml2ZXIoZkNvbnRlbnREcml2ZXIpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2Zyb20gbm93IG9ud2FyZHMgdGhpcyB3b3VsZCBiZSBoYW5kbGVkIGJ5IGZDb250ZW50RHJpdmVyLGluIHRoZSBzYW1lIG5leHQoKSBjYWxsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmQ29udGVudERyaXZlci5uZXh0KCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChmRW50aXR5U2Nhbm5lci5za2lwQ2hhcignIScsIG51bGwpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmRW50aXR5U2Nhbm5lci5za2lwQ2hhcignLScsIG51bGwpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWZFbnRpdHlTY2FubmVyLnNraXBDaGFyKCctJywgbnVsbCkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJJbnZhbGlkQ29tbWVudFN0YXJ0IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0U2Nhbm5lclN0YXRlKFNDQU5ORVJfU1RBVEVfQ09NTUVOVCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZkVudGl0eVNjYW5uZXIuc2tpcFN0cmluZyhET0NUWVBFKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0U2Nhbm5lclN0YXRlKFNDQU5ORVJfU1RBVEVfRE9DVFlQRSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFbnRpdHkgZW50aXR5ID0gZkVudGl0eVNjYW5uZXIuZ2V0Q3VycmVudEVudGl0eSgpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoZW50aXR5IGluc3RhbmNlb2YgRW50aXR5LlNjYW5uZWRFbnRpdHkpewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZTdGFydFBvcz0oKEVudGl0eS5TY2FubmVkRW50aXR5KWVudGl0eSkucG9zaXRpb247Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmUmVhZGluZ0RURD10cnVlOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoZkRURERlY2wgPT0gbnVsbCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmRFRERGVjbCA9IG5ldyBYTUxTdHJpbmdCdWZmZXIoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZEVEREZWNsLmFwcGVuZCgiPCFET0NUWVBFIik7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIk1hcmt1cE5vdFJlY29nbml6ZWRJblByb2xvZyIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChmRW50aXR5U2Nhbm5lci5za2lwQ2hhcignPycsIG51bGwpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldFNjYW5uZXJTdGF0ZShTQ0FOTkVSX1NUQVRFX1BJKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJNYXJrdXBOb3RSZWNvZ25pemVkSW5Qcm9sb2ciLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0gd2hpbGUgKGZTY2FubmVyU3RhdGUgPT0gU0NBTk5FUl9TVEFURV9QUk9MT0cgfHwgZlNjYW5uZXJTdGF0ZSA9PSBTQ0FOTkVSX1NUQVRFX1NUQVJUX09GX01BUktVUCApOwotCi0gICAgICAgICAgICAgICAgc3dpdGNoKGZTY2FubmVyU3RhdGUpewotICAgICAgICAgICAgICAgICAgICAvKioKLSAgICAgICAgICAgICAgICAgICAgLy90aGlzIHBhcnQgaXMgaGFuZGxlZCBieSBGcmFnbWVudENvbnRlbnRIYW5kbGVyCi0gICAgICAgICAgICAgICAgICAgIGNhc2UgU0NBTk5FUl9TVEFURV9ST09UX0VMRU1FTlQ6IHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vd2UgaGF2ZSByZWFkICc8JyBhbmQgYmVnaW5uaW5nIG9mIHJlYWRpbmcgdGhlIHN0YXJ0IGVsZW1lbnQgdGFnCi0gICAgICAgICAgICAgICAgICAgICAgICBzZXRTY2FubmVyU3RhdGUoU0NBTk5FUl9TVEFURV9TVEFSVF9FTEVNRU5UX1RBRyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzZXREcml2ZXIoZkNvbnRlbnREcml2ZXIpOwotICAgICAgICAgICAgICAgICAgICAgICAgLy9mcm9tIG5vdyBvbndhcmRzIHRoaXMgd291bGQgYmUgaGFuZGxlZCBieSBmQ29udGVudERyaXZlcixpbiB0aGUgc2FtZSBuZXh0KCkgY2FsbAotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZDb250ZW50RHJpdmVyLm5leHQoKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgKi8KLSAgICAgICAgICAgICAgICAgICAgY2FzZSBTQ0FOTkVSX1NUQVRFX0NPTU1FTlQ6IHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vdGhpcyBmdW5jdGlvbiBmaWxscyB0aGUgZGF0YS4uCi0gICAgICAgICAgICAgICAgICAgICAgICBzY2FuQ29tbWVudCgpOwotICAgICAgICAgICAgICAgICAgICAgICAgc2V0U2Nhbm5lclN0YXRlKFNDQU5ORVJfU1RBVEVfUFJPTE9HKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBYTUxFdmVudC5DT01NRU5UOwotICAgICAgICAgICAgICAgICAgICAgICAgLy9zZXRTY2FubmVyU3RhdGUoU0NBTk5FUl9TVEFURV9QUk9MT0cpOwotICAgICAgICAgICAgICAgICAgICAgICAgLy9icmVhazsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBjYXNlIFNDQU5ORVJfU1RBVEVfUEk6IHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZDb250ZW50QnVmZmVyLmNsZWFyKCkgOwotICAgICAgICAgICAgICAgICAgICAgICAgc2NhblBJKGZDb250ZW50QnVmZmVyKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHNldFNjYW5uZXJTdGF0ZShTQ0FOTkVSX1NUQVRFX1BST0xPRyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gWE1MRXZlbnQuUFJPQ0VTU0lOR19JTlNUUlVDVElPTjsKLSAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgIGNhc2UgU0NBTk5FUl9TVEFURV9ET0NUWVBFOiB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZkRpc2FsbG93RG9jdHlwZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIkRvY3R5cGVOb3RBbGxvd2VkIiwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmU2VlbkRvY3R5cGVEZWNsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiQWxyZWFkeVNlZW5Eb2N0eXBlIiwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBmU2VlbkRvY3R5cGVEZWNsID0gdHJ1ZTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2NhbkRvY3R5cGVEZWNsKCkgc2VuZHMgWE5JIGRvY3R5cGVEZWNsIGV2ZW50IHRoYXQKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGluIFNBWCBpcyBjb252ZXJ0ZWQgdG8gc3RhcnREVEQoKSBldmVudC4KLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzY2FuRG9jdHlwZURlY2woZlN1cHBvcnREVEQpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9hbGxvdyBwYXJzaW5nIG9mIGVudGl0eSBkZWNscyB0byBjb250aW51ZSBpbiBvcmRlciB0byBzdGF5IHdlbGwtZm9ybWVkCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0U2Nhbm5lclN0YXRlKFNDQU5ORVJfU1RBVEVfRFREX0lOVEVSTkFMX0RFQ0xTKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmU2VlbkludGVybmFsU3Vic2V0ID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihmRFRERHJpdmVyID09IG51bGwpewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmRFRERHJpdmVyID0gbmV3IERURERyaXZlcigpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXREcml2ZXIoZkNvbnRlbnREcml2ZXIpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vYWx3YXlzIHJldHVybiBEVEQgZXZlbnQsIHRoZSBldmVudCBob3dldmVyLCB3aWxsIG5vdCBjb250YWluIGFueSBlbnRpdGllcwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmRFRERHJpdmVyLm5leHQoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAgICAgaWYoZlNlZW5Eb2N0eXBlRGVjbCl7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgRW50aXR5IGVudGl0eSA9IGZFbnRpdHlTY2FubmVyLmdldEN1cnJlbnRFbnRpdHkoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihlbnRpdHkgaW5zdGFuY2VvZiBFbnRpdHkuU2Nhbm5lZEVudGl0eSl7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZFbmRQb3MgPSAoKEVudGl0eS5TY2FubmVkRW50aXR5KWVudGl0eSkucG9zaXRpb247Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZSZWFkaW5nRFREID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGhhbmRsZSBleHRlcm5hbCBzdWJzZXQKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmRG9jdHlwZVN5c3RlbUlkICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoKChmVmFsaWRhdGlvbiB8fCBmTG9hZEV4dGVybmFsRFREKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiAoZlZhbGlkYXRpb25NYW5hZ2VyID09IG51bGwgfHwgIWZWYWxpZGF0aW9uTWFuYWdlci5pc0NhY2hlZERURCgpKSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZTdXBwb3J0RFREKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRTY2FubmVyU3RhdGUoU0NBTk5FUl9TVEFURV9EVERfRVhURVJOQUwpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0U2Nhbm5lclN0YXRlKFNDQU5ORVJfU1RBVEVfUFJPTE9HKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldERyaXZlcihmQ29udGVudERyaXZlcik7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKGZEVEREcml2ZXIgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkRURERyaXZlciA9IG5ldyBEVEREcml2ZXIoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmRFRERHJpdmVyLm5leHQoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChmRXh0ZXJuYWxTdWJzZXRTb3VyY2UgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoKGZWYWxpZGF0aW9uIHx8IGZMb2FkRXh0ZXJuYWxEVEQpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmIChmVmFsaWRhdGlvbk1hbmFnZXIgPT0gbnVsbCB8fCAhZlZhbGlkYXRpb25NYW5hZ2VyLmlzQ2FjaGVkRFREKCkpKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGlzIGhhbmRsZXMgdGhlIGNhc2Ugb2YgYSBET0NUWVBFIHRoYXQgaGFkIG5laXRoZXIgYW4gaW50ZXJuYWwgc3Vic2V0IG9yIGFuIGV4dGVybmFsIHN1YnNldC4KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkRURFNjYW5uZXIuc2V0SW5wdXRTb3VyY2UoZkV4dGVybmFsU3Vic2V0U291cmNlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkV4dGVybmFsU3Vic2V0U291cmNlID0gbnVsbDsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZlN1cHBvcnREVEQpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldFNjYW5uZXJTdGF0ZShTQ0FOTkVSX1NUQVRFX0RURF9FWFRFUk5BTF9ERUNMUyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRTY2FubmVyU3RhdGUoU0NBTk5FUl9TVEFURV9QUk9MT0cpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldERyaXZlcihmQ29udGVudERyaXZlcik7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoZkRURERyaXZlciA9PSBudWxsKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmRFRERHJpdmVyID0gbmV3IERURERyaXZlcigpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmRFRERHJpdmVyLm5leHQoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNlbmQgZW5kRFREKCkgY2FsbCBpZjoKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGEpIHN5c3RlbUlkIGlzIG51bGwgb3IgaWYgYW4gZXh0ZXJuYWwgc3Vic2V0IHJlc29sdmVyIGNvdWxkIG5vdCBsb2NhdGUgYW4gZXh0ZXJuYWwgc3Vic2V0LgotICAgICAgICAgICAgICAgICAgICAgICAgLy8gYikgImxvYWQtZXh0ZXJuYWwtZHRkIiBhbmQgdmFsaWRhdGlvbiBhcmUgZmFsc2UKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGMpIERURCBncmFtbWFyIGlzIGNhY2hlZAotCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBpbiBYTkkgdGhpcyByZXN1bHRzIGluIDMgZXZlbnRzOiAgZG9jdHlwZURlY2wsIHN0YXJ0RFRELCBlbmREVEQKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGluIFNBWCB0aGlzIHJlc3VsdHMgaW4gMiBldmVudHM6IHN0YXJ0RFRELCBlbmREVEQKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmRFREU2Nhbm5lciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZkRURFNjYW5uZXIuc2V0SW5wdXRTb3VyY2UobnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBzZXRTY2FubmVyU3RhdGUoU0NBTk5FUl9TVEFURV9QUk9MT0cpOwotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFhNTEV2ZW50LkRURDsKLSAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgIGNhc2UgU0NBTk5FUl9TVEFURV9DT05URU5UOiB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJDb250ZW50SWxsZWdhbEluUHJvbG9nIiwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmRW50aXR5U2Nhbm5lci5zY2FuQ2hhcihudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBjYXNlIFNDQU5ORVJfU1RBVEVfUkVGRVJFTkNFOiB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJSZWZlcmVuY2VJbGxlZ2FsSW5Qcm9sb2ciLCBudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgIC8qKgotICAgICAgICAgICAgICAgICAgICAgKiBpZiAoY29tcGxldGUpIHsKLSAgICAgICAgICAgICAgICAgICAgICogaWYgKGZFbnRpdHlTY2FubmVyLnNjYW5DaGFyKCkgIT0gJzwnKSB7Ci0gICAgICAgICAgICAgICAgICAgICAqIHJlcG9ydEZhdGFsRXJyb3IoIlJvb3RFbGVtZW50UmVxdWlyZWQiLCBudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgICogfQotICAgICAgICAgICAgICAgICAgICAgKiBzZXRTY2FubmVyU3RhdGUoU0NBTk5FUl9TVEFURV9ST09UX0VMRU1FTlQpOwotICAgICAgICAgICAgICAgICAgICAgKiBzZXREcml2ZXIoZkNvbnRlbnREcml2ZXIpOwotICAgICAgICAgICAgICAgICAgICAgKiB9Ci0gICAgICAgICAgICAgICAgICAgICAqLwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIHByZW1hdHVyZSBlbmQgb2YgZmlsZQotICAgICAgICAgICAgY2F0Y2ggKEVPRkV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiUHJlbWF0dXJlRU9GIiwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgLy94eHggIHdoYXQgc2hvdWxkIGJlIHJldHVybmVkIGhlcmUuLi4uID8/PwotICAgICAgICAgICAgICAgIHJldHVybiAtMSA7Ci0gICAgICAgICAgICAgICAgLy90aHJvdyBlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy94eHggIHdoYXQgc2hvdWxkIGJlIHJldHVybmVkIGhlcmUuLi4uID8/PwotICAgICAgICAgICAgcmV0dXJuIC0xOwotCi0gICAgICAgIH0KLQotCi0gICAgfSAvLyBjbGFzcyBQcm9sb2dEcml2ZXIKLQotICAgIC8qKgotICAgICAqIERyaXZlciB0byBoYW5kbGUgdGhlIGludGVybmFsIGFuZCBleHRlcm5hbCBEVEQgc3Vic2V0cy4KLSAgICAgKgotICAgICAqIEBhdXRob3IgQW5keSBDbGFyaywgSUJNCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGZpbmFsIGNsYXNzIERURERyaXZlcgotICAgICAgICAgICAgaW1wbGVtZW50cyBEcml2ZXIgewotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIERyaXZlciBtZXRob2RzCi0gICAgICAgIC8vCi0KLSAgICAgICAgcHVibGljIGludCBuZXh0KCkgdGhyb3dzIElPRXhjZXB0aW9uLCBYTklFeGNlcHRpb257Ci0gICAgICAgICAgICAvLyB0aHJvdyBuZXcgWE5JRXhjZXB0aW9uKCJEVEQgUGFyc2luZyBpcyBjdXJyZW50bHkgbm90IHN1cHBvcnRlZCIpOwotICAgICAgICAgICAgaWYoREVCVUdfTkVYVCl7Ci0gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJOb3cgaW4gRFREIERyaXZlciIpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBkaXNwYXRjaCh0cnVlKTsKLQotICAgICAgICAgICAgaWYoREVCVUdfTkVYVCl7Ci0gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJBZnRlciBjYWxsaW5nIGRpc3BhdGNoKHRydWUpIC0tIEF0IHRoaXMgcG9pbnQgd2hvbGUgRFREIGlzIHJlYWQuIik7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8veHh4OiByZW1vdmUgdGhpcyBoYWNrIGFuZCBhbGlnbiB0aGlzIHdpdGggcmV1c2luZyBEVEQgY29tcG9uZW50cwotICAgICAgICAgICAgLy9jdXJyZW50bHkgdGhpcyByb3V0aW5lIHdpbGwgb25seSBiZSBleGVjdXRlZCBmcm9tIFN0YXgKLSAgICAgICAgICAgIGlmKGZQcm9wZXJ0eU1hbmFnZXIgIT0gbnVsbCl7Ci0gICAgICAgICAgICAgICAgZHRkR3JhbW1hclV0aWwgPSAgbmV3IERUREdyYW1tYXJVdGlsKCgoWE1MRFREU2Nhbm5lckltcGwpZkRURFNjYW5uZXIpLmdldEdyYW1tYXIoKSxmU3ltYm9sVGFibGUsIGZOYW1lc3BhY2VDb250ZXh0KTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgcmV0dXJuIFhNTEV2ZW50LkRURCA7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogRGlzcGF0Y2ggYW4gWE1MICJldmVudCIuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBjb21wbGV0ZSBUcnVlIGlmIHRoaXMgZHJpdmVyIGlzIGludGVuZGVkIHRvIHNjYW4KLSAgICAgICAgICogICAgICAgICAgICAgICAgIGFuZCBkaXNwYXRjaCBhcyBtdWNoIGFzIHBvc3NpYmxlLgotICAgICAgICAgKgotICAgICAgICAgKiBAcmV0dXJuIFRydWUgaWYgdGhlcmUgaXMgbW9yZSB0byBkaXNwYXRjaCBlaXRoZXIgZnJvbSB0aGlzCi0gICAgICAgICAqICAgICAgICAgIG9yIGEgYW5vdGhlciBkcml2ZXIuCi0gICAgICAgICAqCi0gICAgICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gIFRocm93biBvbiBpL28gZXJyb3IuCi0gICAgICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBvbiBwYXJzZSBlcnJvci4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBib29sZWFuIGRpc3BhdGNoKGJvb2xlYW4gY29tcGxldGUpCi0gICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgICAgIGZFbnRpdHlNYW5hZ2VyLnNldEVudGl0eUhhbmRsZXIobnVsbCk7Ci0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIGJvb2xlYW4gYWdhaW47Ci0gICAgICAgICAgICAgICAgWE1MUmVzb3VyY2VJZGVudGlmaWVySW1wbCByZXNvdXJjZUlkZW50aWZpZXIgPSBuZXcgWE1MUmVzb3VyY2VJZGVudGlmaWVySW1wbCgpOwotICAgICAgICAgICAgICAgIGlmKCBmRFREU2Nhbm5lciA9PSBudWxsKXsKLQotICAgICAgICAgICAgICAgICAgICBpZiAoZkVudGl0eU1hbmFnZXIuZ2V0RW50aXR5U2Nhbm5lcigpIGluc3RhbmNlb2YgWE1MMTFFbnRpdHlTY2FubmVyKXsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZEVERTY2FubmVyID0gbmV3IFhNTDExRFREU2Nhbm5lckltcGwoKTsKLSAgICAgICAgICAgICAgICAgICAgfSBlbHNlCi0KLSAgICAgICAgICAgICAgICAgICAgZkRURFNjYW5uZXIgPSBuZXcgWE1MRFREU2Nhbm5lckltcGwoKTsKLQotICAgICAgICAgICAgICAgICAgICAoKFhNTERURFNjYW5uZXJJbXBsKWZEVERTY2FubmVyKS5yZXNldChmUHJvcGVydHlNYW5hZ2VyKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBmRFREU2Nhbm5lci5zZXRMaW1pdEFuYWx5emVyKGZMaW1pdEFuYWx5emVyKTsKLSAgICAgICAgICAgICAgICBkbyB7Ci0gICAgICAgICAgICAgICAgICAgIGFnYWluID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgICAgIHN3aXRjaCAoZlNjYW5uZXJTdGF0ZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBTQ0FOTkVSX1NUQVRFX0RURF9JTlRFUk5BTF9ERUNMUzogewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gbW9yZVRvU2NhbiA9IGZhbHNlOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghZkRURFNjYW5uZXIuc2tpcERURChmU3VwcG9ydERURCkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBSRVZJU0lUOiBTaG91bGQgdGhlcmUgYmUgYSBmZWF0dXJlIGZvcgotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgICAgICAgIHRoZSAiY29tcGxldGUiIHBhcmFtZXRlcj8KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGNvbXBsZXRlRFREID0gdHJ1ZTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb3JlVG9TY2FuID0gZkRURFNjYW5uZXIuc2NhbkRUREludGVybmFsU3Vic2V0KGNvbXBsZXRlRFRELCBmU3RhbmRhbG9uZSwgZkhhc0V4dGVybmFsRFREICYmIGZMb2FkRXh0ZXJuYWxEVEQpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBFbnRpdHkgZW50aXR5ID0gZkVudGl0eVNjYW5uZXIuZ2V0Q3VycmVudEVudGl0eSgpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKGVudGl0eSBpbnN0YW5jZW9mIEVudGl0eS5TY2FubmVkRW50aXR5KXsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkVuZFBvcz0oKEVudGl0eS5TY2FubmVkRW50aXR5KWVudGl0eSkucG9zaXRpb247Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZSZWFkaW5nRFREPWZhbHNlOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghbW9yZVRvU2NhbikgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBlbmQgZG9jdHlwZSBkZWNsYXJhdGlvbgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWZFbnRpdHlTY2FubmVyLnNraXBDaGFyKCddJywgbnVsbCkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIkRvY3R5cGVkZWNsTm90Q2xvc2VkIiwgbmV3IE9iamVjdFtde2ZEb2N0eXBlTmFtZX0pOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZFbnRpdHlTY2FubmVyLnNraXBTcGFjZXMoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFmRW50aXR5U2Nhbm5lci5za2lwQ2hhcignPicsIG51bGwpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJEb2N0eXBlZGVjbFVudGVybWluYXRlZCIsIG5ldyBPYmplY3RbXXtmRG9jdHlwZU5hbWV9KTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmTWFya3VwRGVwdGgtLTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWZTdXBwb3J0RFREKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3NpbXBseSByZXNldCB0aGUgZW50aXR5IHN0b3JlIHdpdGhvdXQgaGF2aW5nIHRvIG1lc3MgYXJvdW5kCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3dpdGggdGhlIERURCBTY2FubmVyIGNvZGUKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZFbnRpdHlTdG9yZSA9IGZFbnRpdHlNYW5hZ2VyLmdldEVudGl0eVN0b3JlKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmRW50aXR5U3RvcmUucmVzZXQoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNjYW4gZXh0ZXJuYWwgc3Vic2V0IG5leHQgdW5sZXNzIHdlIGFyZSBpZ25vcmluZyBEVERzCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZkRvY3R5cGVTeXN0ZW1JZCAhPSBudWxsICYmIChmVmFsaWRhdGlvbiB8fCBmTG9hZEV4dGVybmFsRFREKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldFNjYW5uZXJTdGF0ZShTQ0FOTkVSX1NUQVRFX0RURF9FWFRFUk5BTCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRFbmREVERTY2FuU3RhdGUoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFNDQU5ORVJfU1RBVEVfRFREX0VYVEVSTkFMOiB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLyoqCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZkRURERlc2NyaXB0aW9uLnNldFZhbHVlcyhmRG9jdHlwZVB1YmxpY0lkLCBmRG9jdHlwZVN5c3RlbUlkLCBudWxsLCBudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmRFRERGVzY3JpcHRpb24uc2V0Um9vdE5hbWUoZkRvY3R5cGVOYW1lKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxJbnB1dFNvdXJjZSB4bWxJbnB1dFNvdXJjZSA9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZFbnRpdHlNYW5hZ2VyLnJlc29sdmVFbnRpdHkoZkRURERlc2NyaXB0aW9uKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmRFREU2Nhbm5lci5zZXRJbnB1dFNvdXJjZSh4bWxJbnB1dFNvdXJjZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0U2Nhbm5lclN0YXRlKFNDQU5ORVJfU1RBVEVfRFREX0VYVEVSTkFMX0RFQ0xTKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZ2FpbiA9IHRydWU7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvdXJjZUlkZW50aWZpZXIuc2V0VmFsdWVzKGZEb2N0eXBlUHVibGljSWQsIGZEb2N0eXBlU3lzdGVtSWQsIG51bGwsIG51bGwpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTElucHV0U291cmNlIHhtbElucHV0U291cmNlID0gbnVsbCA7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RheFhNTElucHV0U291cmNlIHN0YXhJbnB1dFNvdXJjZSA9ICBmRW50aXR5TWFuYWdlci5yZXNvbHZlRW50aXR5QXNQZXJTdGF4KHJlc291cmNlSWRlbnRpZmllcik7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBDaGVjayBhY2Nlc3MgcGVybWlzc2lvbi4gSWYgdGhlIHNvdXJjZSBpcyByZXNvbHZlZCBieSBhIHJlc29sdmVyLCB0aGUgY2hlY2sgaXMgc2tpcHBlZC4KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXN0YXhJbnB1dFNvdXJjZS5oYXNSZXNvbHZlcigpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBhY2Nlc3NFcnJvciA9IGNoZWNrQWNjZXNzKGZEb2N0eXBlU3lzdGVtSWQsIGZBY2Nlc3NFeHRlcm5hbERURCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhY2Nlc3NFcnJvciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJBY2Nlc3NFeHRlcm5hbERURCIsIG5ldyBPYmplY3RbXXsgU2VjdXJpdHlTdXBwb3J0LnNhbml0aXplUGF0aChmRG9jdHlwZVN5c3RlbUlkKSwgYWNjZXNzRXJyb3IgfSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sSW5wdXRTb3VyY2UgPSBzdGF4SW5wdXRTb3VyY2UuZ2V0WE1MSW5wdXRTb3VyY2UoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmRFREU2Nhbm5lci5zZXRJbnB1dFNvdXJjZSh4bWxJbnB1dFNvdXJjZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZFbnRpdHlTY2FubmVyLmZDdXJyZW50RW50aXR5ICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0U2Nhbm5lclN0YXRlKFNDQU5ORVJfU1RBVEVfRFREX0VYVEVSTkFMX0RFQ0xTKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRTY2FubmVyU3RhdGUoU0NBTk5FUl9TVEFURV9QUk9MT0cpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZ2FpbiA9IHRydWU7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFNDQU5ORVJfU1RBVEVfRFREX0VYVEVSTkFMX0RFQ0xTOiB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUkVWSVNJVDogU2hvdWxkIHRoZXJlIGJlIGEgZmVhdHVyZSBmb3IKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgICAgICAgICB0aGUgImNvbXBsZXRlIiBwYXJhbWV0ZXI/Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBjb21wbGV0ZURURCA9IHRydWU7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBtb3JlVG9TY2FuID0gZkRURFNjYW5uZXIuc2NhbkRUREV4dGVybmFsU3Vic2V0KGNvbXBsZXRlRFREKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIW1vcmVUb1NjYW4pIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0RW5kRFREU2NhblN0YXRlKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgU0NBTk5FUl9TVEFURV9QUk9MT0cgOiB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2tpcCBlbnRpdHkgZGVjbHMKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRFbmREVERTY2FuU3RhdGUoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWE5JRXhjZXB0aW9uKCJEVEREcml2ZXIjZGlzcGF0Y2g6IHNjYW5uZXIgc3RhdGU9IitmU2Nhbm5lclN0YXRlKyIgKCIrZ2V0U2Nhbm5lclN0YXRlTmFtZShmU2Nhbm5lclN0YXRlKSsnKScpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfSB3aGlsZSAoY29tcGxldGUgfHwgYWdhaW4pOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBwcmVtYXR1cmUgZW5kIG9mIGZpbGUKLSAgICAgICAgICAgIGNhdGNoIChFT0ZFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiUHJlbWF0dXJlRU9GIiwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgICAgIC8vdGhyb3cgZTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gY2xlYW51cAotICAgICAgICAgICAgZmluYWxseSB7Ci0gICAgICAgICAgICAgICAgZkVudGl0eU1hbmFnZXIuc2V0RW50aXR5SGFuZGxlcihYTUxEb2N1bWVudFNjYW5uZXJJbXBsLnRoaXMpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gZGlzcGF0Y2goYm9vbGVhbik6Ym9vbGVhbgotCi0gICAgfSAvLyBjbGFzcyBEVEREcml2ZXIKLQotICAgIC8qKgotICAgICAqIERyaXZlciB0byBoYW5kbGUgY29udGVudCBzY2FubmluZy4KLSAgICAgKgotICAgICAqIEBhdXRob3IgQW5keSBDbGFyaywgSUJNCi0gICAgICogQGF1dGhvciBFcmljIFllLCBJQk0KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgY2xhc3MgQ29udGVudERyaXZlcgotICAgICAgICAgICAgZXh0ZW5kcyBGcmFnbWVudENvbnRlbnREcml2ZXIgewotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIFByb3RlY3RlZCBtZXRob2RzCi0gICAgICAgIC8vCi0KLSAgICAgICAgLy8gaG9va3MKLQotICAgICAgICAvLyBOT1RFOiBUaGVzZSBob29rIG1ldGhvZHMgYXJlIGFkZGVkIHNvIHRoYXQgdGhlIGZ1bGwgZG9jdW1lbnQKLSAgICAgICAgLy8gICAgICAgc2Nhbm5lciBjYW4gc2hhcmUgdGhlIG1ham9yaXR5IG9mIGNvZGUgd2l0aCB0aGlzIGNsYXNzLgotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBTY2FuIGZvciBET0NUWVBFIGhvb2suIFRoaXMgbWV0aG9kIGlzIGEgaG9vayBmb3Igc3ViY2xhc3NlcwotICAgICAgICAgKiB0byBhZGQgY29kZSB0byBoYW5kbGUgc2Nhbm5pbmcgZm9yIGEgdGhlICJET0NUWVBFIiBzdHJpbmcKLSAgICAgICAgICogYWZ0ZXIgdGhlIHN0cmluZyAiPCEiIGhhcyBiZWVuIHNjYW5uZWQuCi0gICAgICAgICAqCi0gICAgICAgICAqIEByZXR1cm4gVHJ1ZSBpZiB0aGUgIkRPQ1RZUEUiIHdhcyBzY2FubmVkOyBmYWxzZSBpZiAiRE9DVFlQRSIKLSAgICAgICAgICogICAgICAgICAgd2FzIG5vdCBzY2FubmVkLgotICAgICAgICAgKi8KLSAgICAgICAgcHJvdGVjdGVkIGJvb2xlYW4gc2NhbkZvckRvY3R5cGVIb29rKCkKLSAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBYTklFeGNlcHRpb24gewotCi0gICAgICAgICAgICBpZiAoZkVudGl0eVNjYW5uZXIuc2tpcFN0cmluZyhET0NUWVBFKSkgewotICAgICAgICAgICAgICAgIHNldFNjYW5uZXJTdGF0ZShTQ0FOTkVSX1NUQVRFX0RPQ1RZUEUpOwotICAgICAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgIGZFbnRpdHlTY2FubmVyLm1hcmtTdGFydE9mRFREKCk7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0KLSAgICAgICAgfSAvLyBzY2FuRm9yRG9jdHlwZUhvb2soKTpib29sZWFuCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIEVsZW1lbnQgZGVwdGggaXogemVyby4gVGhpcyBtZXRob3MgaXMgYSBob29rIGZvciBzdWJjbGFzc2VzCi0gICAgICAgICAqIHRvIGFkZCBjb2RlIHRvIGhhbmRsZSB3aGVuIHRoZSBlbGVtZW50IGRlcHRoIGhpdHMgemVyby4gV2hlbgotICAgICAgICAgKiBzY2FubmluZyBhIGRvY3VtZW50IGZyYWdtZW50LCBhbiBlbGVtZW50IGRlcHRoIG9mIHplcm8gaXMKLSAgICAgICAgICogbm9ybWFsLiBIb3dldmVyLCB3aGVuIHNjYW5uaW5nIGEgZnVsbCBYTUwgZG9jdW1lbnQsIHRoZQotICAgICAgICAgKiBzY2FubmVyIG11c3QgaGFuZGxlIHRoZSB0cmFpbGluZyBtaXNjZWxsYW5vdXMgc2VjdGlvbiBvZgotICAgICAgICAgKiB0aGUgZG9jdW1lbnQgYWZ0ZXIgdGhlIGVuZCBvZiB0aGUgZG9jdW1lbnQncyByb290IGVsZW1lbnQuCi0gICAgICAgICAqCi0gICAgICAgICAqIEByZXR1cm4gVHJ1ZSBpZiB0aGUgY2FsbGVyIHNob3VsZCBzdG9wIGFuZCByZXR1cm4gdHJ1ZSB3aGljaAotICAgICAgICAgKiAgICAgICAgICBhbGxvd3MgdGhlIHNjYW5uZXIgdG8gc3dpdGNoIHRvIGEgbmV3IHNjYW5uaW5nCi0gICAgICAgICAqICAgICAgICAgIGRyaXZlci4gQSByZXR1cm4gdmFsdWUgb2YgZmFsc2UgaW5kaWNhdGVzIHRoYXQKLSAgICAgICAgICogICAgICAgICAgdGhlIGNvbnRlbnQgZHJpdmVyIHNob3VsZCBjb250aW51ZSBhcyBub3JtYWwuCi0gICAgICAgICAqLwotICAgICAgICBwcm90ZWN0ZWQgYm9vbGVhbiBlbGVtZW50RGVwdGhJc1plcm9Ib29rKCkKLSAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBYTklFeGNlcHRpb24gewotCi0gICAgICAgICAgICBzZXRTY2FubmVyU3RhdGUoU0NBTk5FUl9TVEFURV9UUkFJTElOR19NSVNDKTsKLSAgICAgICAgICAgIHNldERyaXZlcihmVHJhaWxpbmdNaXNjRHJpdmVyKTsKLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotCi0gICAgICAgIH0gLy8gZWxlbWVudERlcHRoSXNaZXJvSG9vaygpOmJvb2xlYW4KLQotICAgICAgICAvKioKLSAgICAgICAgICogU2NhbiBmb3Igcm9vdCBlbGVtZW50IGhvb2suIFRoaXMgbWV0aG9kIGlzIGEgaG9vayBmb3IKLSAgICAgICAgICogc3ViY2xhc3NlcyB0byBhZGQgY29kZSB0aGF0IGhhbmRsZXMgc2Nhbm5pbmcgZm9yIHRoZSByb290Ci0gICAgICAgICAqIGVsZW1lbnQuIFdoZW4gc2Nhbm5pbmcgYSBkb2N1bWVudCBmcmFnbWVudCwgdGhlcmUgaXMgbm8KLSAgICAgICAgICogInJvb3QiIGVsZW1lbnQuIEhvd2V2ZXIsIHdoZW4gc2Nhbm5pbmcgYSBmdWxsIFhNTCBkb2N1bWVudCwKLSAgICAgICAgICogdGhlIHNjYW5uZXIgbXVzdCBoYW5kbGUgdGhlIHJvb3QgZWxlbWVudCBzcGVjaWFsbHkuCi0gICAgICAgICAqCi0gICAgICAgICAqIEByZXR1cm4gVHJ1ZSBpZiB0aGUgY2FsbGVyIHNob3VsZCBzdG9wIGFuZCByZXR1cm4gdHJ1ZSB3aGljaAotICAgICAgICAgKiAgICAgICAgICBhbGxvd3MgdGhlIHNjYW5uZXIgdG8gc3dpdGNoIHRvIGEgbmV3IHNjYW5uaW5nCi0gICAgICAgICAqICAgICAgICAgIGRyaXZlci4gQSByZXR1cm4gdmFsdWUgb2YgZmFsc2UgaW5kaWNhdGVzIHRoYXQKLSAgICAgICAgICogICAgICAgICAgdGhlIGNvbnRlbnQgZHJpdmVyIHNob3VsZCBjb250aW51ZSBhcyBub3JtYWwuCi0gICAgICAgICAqLwotICAgICAgICBwcm90ZWN0ZWQgYm9vbGVhbiBzY2FuUm9vdEVsZW1lbnRIb29rKCkKLSAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBYTklFeGNlcHRpb24gewotCi0gICAgICAgICAgICBpZiAoc2NhblN0YXJ0RWxlbWVudCgpKSB7Ci0gICAgICAgICAgICAgICAgc2V0U2Nhbm5lclN0YXRlKFNDQU5ORVJfU1RBVEVfVFJBSUxJTkdfTUlTQyk7Ci0gICAgICAgICAgICAgICAgc2V0RHJpdmVyKGZUcmFpbGluZ01pc2NEcml2ZXIpOwotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotCi0gICAgICAgIH0gLy8gc2NhblJvb3RFbGVtZW50SG9vaygpOmJvb2xlYW4KLQotICAgICAgICAvKioKLSAgICAgICAgICogRW5kIG9mIGZpbGUgaG9vay4gVGhpcyBtZXRob2QgaXMgYSBob29rIGZvciBzdWJjbGFzc2VzIHRvCi0gICAgICAgICAqIGFkZCBjb2RlIHRoYXQgaGFuZGxlcyB0aGUgZW5kIG9mIGZpbGUuIFRoZSBlbmQgb2YgZmlsZSBpbgotICAgICAgICAgKiBhIGRvY3VtZW50IGZyYWdtZW50IGlzIE9LIGlmIHRoZSBtYXJrdXAgZGVwdGggaXMgemVyby4KLSAgICAgICAgICogSG93ZXZlciwgd2hlbiBzY2FubmluZyBhIGZ1bGwgWE1MIGRvY3VtZW50LCBhbiBlbmQgb2YgZmlsZQotICAgICAgICAgKiBpcyBhbHdheXMgcHJlbWF0dXJlLgotICAgICAgICAgKi8KLSAgICAgICAgcHJvdGVjdGVkIHZvaWQgZW5kT2ZGaWxlSG9vayhFT0ZFeGNlcHRpb24gZSkKLSAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBYTklFeGNlcHRpb24gewotCi0gICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJQcmVtYXR1cmVFT0YiLCBudWxsKTsKLSAgICAgICAgICAgIC8vIGluIGNhc2UgY29udGludWUtYWZ0ZXItZmF0YWwtZXJyb3Igc2V0LCBzaG91bGQgbm90IGRvIHRoaXMuLi4KLSAgICAgICAgICAgIC8vdGhyb3cgZTsKLQotICAgICAgICB9IC8vIGVuZE9mRmlsZUhvb2soKQotCi0gICAgICAgIHByb3RlY3RlZCB2b2lkIHJlc29sdmVFeHRlcm5hbFN1YnNldEFuZFJlYWQoKQotICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgICAgIGZEVEREZXNjcmlwdGlvbi5zZXRWYWx1ZXMobnVsbCwgbnVsbCwgZkVudGl0eU1hbmFnZXIuZ2V0Q3VycmVudFJlc291cmNlSWRlbnRpZmllcigpLmdldEV4cGFuZGVkU3lzdGVtSWQoKSwgbnVsbCk7Ci0gICAgICAgICAgICBmRFRERGVzY3JpcHRpb24uc2V0Um9vdE5hbWUoZkVsZW1lbnRRTmFtZS5yYXduYW1lKTsKLSAgICAgICAgICAgIFhNTElucHV0U291cmNlIHNyYyA9IGZFeHRlcm5hbFN1YnNldFJlc29sdmVyLmdldEV4dGVybmFsU3Vic2V0KGZEVEREZXNjcmlwdGlvbik7Ci0KLSAgICAgICAgICAgIGlmIChzcmMgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZEb2N0eXBlTmFtZSA9IGZFbGVtZW50UU5hbWUucmF3bmFtZTsKLSAgICAgICAgICAgICAgICBmRG9jdHlwZVB1YmxpY0lkID0gc3JjLmdldFB1YmxpY0lkKCk7Ci0gICAgICAgICAgICAgICAgZkRvY3R5cGVTeXN0ZW1JZCA9IHNyYy5nZXRTeXN0ZW1JZCgpOwotICAgICAgICAgICAgICAgIC8vIGNhbGwgZG9jdW1lbnQgaGFuZGxlcgotICAgICAgICAgICAgICAgIGlmIChmRG9jdW1lbnRIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gVGhpcyBpbnNlcnRzIGEgZG9jdHlwZURlY2wgZXZlbnQgaW50byB0aGUgc3RyZWFtIHRob3VnaCBubwotICAgICAgICAgICAgICAgICAgICAvLyBET0NUWVBFIGV4aXN0ZWQgaW4gdGhlIGluc3RhbmNlIGRvY3VtZW50LgotICAgICAgICAgICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLmRvY3R5cGVEZWNsKGZEb2N0eXBlTmFtZSwgZkRvY3R5cGVQdWJsaWNJZCwgZkRvY3R5cGVTeXN0ZW1JZCwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgIGZEVERTY2FubmVyLnNldElucHV0U291cmNlKHNyYyk7Ci0gICAgICAgICAgICAgICAgICAgIHdoaWxlIChmRFREU2Nhbm5lci5zY2FuRFRERXh0ZXJuYWxTdWJzZXQodHJ1ZSkpOwotICAgICAgICAgICAgICAgIH0gZmluYWxseSB7Ci0gICAgICAgICAgICAgICAgICAgIGZFbnRpdHlNYW5hZ2VyLnNldEVudGl0eUhhbmRsZXIoWE1MRG9jdW1lbnRTY2FubmVySW1wbC50aGlzKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gLy8gcmVzb2x2ZUV4dGVybmFsU3Vic2V0QW5kUmVhZCgpCi0KLQotCi0gICAgfSAvLyBjbGFzcyBDb250ZW50RHJpdmVyCi0KLSAgICAvKioKLSAgICAgKiBEcml2ZXIgdG8gaGFuZGxlIHRyYWlsaW5nIG1pc2NlbGxhbmVvdXMgc2VjdGlvbiBzY2FubmluZy4KLSAgICAgKgotICAgICAqIEBhdXRob3IgQW5keSBDbGFyaywgSUJNCi0gICAgICogQGF1dGhvciBFcmljIFllLCBJQk0KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgZmluYWwgY2xhc3MgVHJhaWxpbmdNaXNjRHJpdmVyCi0gICAgICAgICAgICBpbXBsZW1lbnRzIERyaXZlciB7Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gRHJpdmVyIG1ldGhvZHMKLSAgICAgICAgLy8KLSAgICAgICAgcHVibGljIGludCBuZXh0KCkgdGhyb3dzIElPRXhjZXB0aW9uLCBYTklFeGNlcHRpb257Ci0gICAgICAgICAgICAvL3RoaXMgY291bGQgZm9yIGNhc2VzIGxpa2UgPGZvby8+Ci0gICAgICAgICAgICAvL2xvb2sgYXQgc2NhblJvb3RFbGVtZW50SG9vawotICAgICAgICAgICAgaWYoZkVtcHR5RWxlbWVudCl7Ci0gICAgICAgICAgICAgICAgZkVtcHR5RWxlbWVudCA9IGZhbHNlOwotICAgICAgICAgICAgICAgIHJldHVybiBYTUxFdmVudC5FTkRfRUxFTUVOVDsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICBpZihmU2Nhbm5lclN0YXRlID09IFNDQU5ORVJfU1RBVEVfVEVSTUlOQVRFRCl7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBYTUxFdmVudC5FTkRfRE9DVU1FTlQgO30KLSAgICAgICAgICAgICAgICBkbyB7Ci0gICAgICAgICAgICAgICAgICAgIHN3aXRjaCAoZlNjYW5uZXJTdGF0ZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBTQ0FOTkVSX1NUQVRFX1RSQUlMSU5HX01JU0M6IHsKLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZFbnRpdHlTY2FubmVyLnNraXBTcGFjZXMoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3dlIHNob3VsZCBoYXZlIHJlYWNoZWQgdGhlIGVuZCBvZiB0aGUgZG9jdW1lbnQgaW4KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL21vc3QgY2FzZXMuCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoZlNjYW5uZXJTdGF0ZSA9PSBTQ0FOTkVSX1NUQVRFX1RFUk1JTkFURUQgKXsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFhNTEV2ZW50LkVORF9ET0NVTUVOVCA7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmRW50aXR5U2Nhbm5lci5za2lwQ2hhcignPCcsIG51bGwpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldFNjYW5uZXJTdGF0ZShTQ0FOTkVSX1NUQVRFX1NUQVJUX09GX01BUktVUCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0U2Nhbm5lclN0YXRlKFNDQU5ORVJfU1RBVEVfQ09OVEVOVCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBTQ0FOTkVSX1NUQVRFX1NUQVJUX09GX01BUktVUDogewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZNYXJrdXBEZXB0aCsrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmRW50aXR5U2Nhbm5lci5za2lwQ2hhcignPycsIG51bGwpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldFNjYW5uZXJTdGF0ZShTQ0FOTkVSX1NUQVRFX1BJKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGZFbnRpdHlTY2FubmVyLnNraXBDaGFyKCchJywgbnVsbCkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0U2Nhbm5lclN0YXRlKFNDQU5ORVJfU1RBVEVfQ09NTUVOVCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChmRW50aXR5U2Nhbm5lci5za2lwQ2hhcignLycsIG51bGwpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIk1hcmt1cE5vdFJlY29nbml6ZWRJbk1pc2MiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNWYWxpZE5hbWVTdGFydENoYXIoZkVudGl0eVNjYW5uZXIucGVla0NoYXIoKSkgfHwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzVmFsaWROYW1lU3RhcnRIaWdoU3Vycm9nYXRlKGZFbnRpdHlTY2FubmVyLnBlZWtDaGFyKCkpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIk1hcmt1cE5vdFJlY29nbml6ZWRJbk1pc2MiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2FuU3RhcnRFbGVtZW50KCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldFNjYW5uZXJTdGF0ZShTQ0FOTkVSX1NUQVRFX0NPTlRFTlQpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIk1hcmt1cE5vdFJlY29nbml6ZWRJbk1pc2MiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH13aGlsZShmU2Nhbm5lclN0YXRlID09IFNDQU5ORVJfU1RBVEVfU1RBUlRfT0ZfTUFSS1VQIHx8IGZTY2FubmVyU3RhdGUgPT0gU0NBTk5FUl9TVEFURV9UUkFJTElOR19NSVNDKTsKLSAgICAgICAgICAgICAgICBpZihERUJVR19ORVhUKXsKLSAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJTdGF0ZSBzZXQgYnkgZGVjaWRpbmcgd2hpbGUgbG9vcCBbVHJhaWxpbmdNaXNjZWxsYW5lb3VzXSBpcyA9ICIgKyBnZXRTY2FubmVyU3RhdGVOYW1lKGZTY2FubmVyU3RhdGUpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgc3dpdGNoIChmU2Nhbm5lclN0YXRlKXsKLSAgICAgICAgICAgICAgICAgICAgY2FzZSBTQ0FOTkVSX1NUQVRFX1BJOiB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmQ29udGVudEJ1ZmZlci5jbGVhcigpOwotICAgICAgICAgICAgICAgICAgICAgICAgc2NhblBJKGZDb250ZW50QnVmZmVyKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHNldFNjYW5uZXJTdGF0ZShTQ0FOTkVSX1NUQVRFX1RSQUlMSU5HX01JU0MpOwotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFhNTEV2ZW50LlBST0NFU1NJTkdfSU5TVFJVQ1RJT04gOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgU0NBTk5FUl9TVEFURV9DT01NRU5UOiB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWZFbnRpdHlTY2FubmVyLnNraXBTdHJpbmcoQ09NTUVOVFNUUklORykpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJJbnZhbGlkQ29tbWVudFN0YXJ0IiwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBzY2FuQ29tbWVudCgpOwotICAgICAgICAgICAgICAgICAgICAgICAgc2V0U2Nhbm5lclN0YXRlKFNDQU5ORVJfU1RBVEVfVFJBSUxJTkdfTUlTQyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gWE1MRXZlbnQuQ09NTUVOVDsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBjYXNlIFNDQU5ORVJfU1RBVEVfQ09OVEVOVDogewotICAgICAgICAgICAgICAgICAgICAgICAgaW50IGNoID0gZkVudGl0eVNjYW5uZXIucGVla0NoYXIoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjaCA9PSAtMSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldFNjYW5uZXJTdGF0ZShTQ0FOTkVSX1NUQVRFX1RFUk1JTkFURUQpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBYTUxFdmVudC5FTkRfRE9DVU1FTlQgOwotICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIkNvbnRlbnRJbGxlZ2FsSW5UcmFpbGluZ01pc2MiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZkVudGl0eVNjYW5uZXIuc2NhbkNoYXIobnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0U2Nhbm5lclN0YXRlKFNDQU5ORVJfU1RBVEVfVFJBSUxJTkdfTUlTQyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFhNTEV2ZW50LkNIQVJBQ1RFUlM7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBjYXNlIFNDQU5ORVJfU1RBVEVfUkVGRVJFTkNFOiB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJSZWZlcmVuY2VJbGxlZ2FsSW5UcmFpbGluZ01pc2MiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHNldFNjYW5uZXJTdGF0ZShTQ0FOTkVSX1NUQVRFX1RSQUlMSU5HX01JU0MpOwotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFhNTEV2ZW50LkVOVElUWV9SRUZFUkVOQ0UgOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgU0NBTk5FUl9TVEFURV9URVJNSU5BVEVEOiB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvL3RoZXJlIGNhbid0IGJlIGFueSBlbGVtZW50IGFmdGVyIFNDQU5ORVJfU1RBVEVfVEVSTUlOQVRFRCBvciB3aGVuIHRoZSBwYXJzZXIKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vaGFzIHJlYWNoZWQgdGhlIGVuZCBvZiBkb2N1bWVudAotICAgICAgICAgICAgICAgICAgICAgICAgc2V0U2Nhbm5lclN0YXRlKFNDQU5ORVJfU1RBVEVfTk9fU1VDSF9FTEVNRU5UX0VYQ0VQVElPTik7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvL3h4eCB3aGF0IHRvIGRvIHdoZW4gdGhlIHNjYW5uZXIgaGFzIHJlYWNoZWQgdGhlIHRlcm1pbmF0aW5nIHN0YXRlLgotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFhNTEV2ZW50LkVORF9ET0NVTUVOVCA7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgY2FzZSBTQ0FOTkVSX1NUQVRFX05PX1NVQ0hfRUxFTUVOVF9FWENFUFRJT046ewotICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IGphdmEudXRpbC5Ob1N1Y2hFbGVtZW50RXhjZXB0aW9uKCJObyBtb3JlIGV2ZW50cyB0byBiZSBwYXJzZWQiKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OiB0aHJvdyBuZXcgWE5JRXhjZXB0aW9uKCJTY2FubmVyIFN0YXRlICIgKyBmU2Nhbm5lclN0YXRlICsgIiBub3QgUmVjb2duaXplZCAiKTsKLSAgICAgICAgICAgICAgICB9Ly9zd2l0Y2gKLQotICAgICAgICAgICAgfSBjYXRjaCAoRU9GRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICAvLyBOT1RFOiBUaGlzIGlzIHRoZSBvbmx5IHBsYWNlIHdlJ3JlIGFsbG93ZWQgdG8gcmVhY2gKLSAgICAgICAgICAgICAgICAvLyAgICAgICB0aGUgcmVhbCBlbmQgb2YgdGhlIGRvY3VtZW50IHN0cmVhbS4gVW5sZXNzIHRoZQotICAgICAgICAgICAgICAgIC8vICAgICAgIGVuZCBvZiBmaWxlIHdhcyByZWFjaGVkIHByZW1hdHVyZWx5LgotICAgICAgICAgICAgICAgIGlmIChmTWFya3VwRGVwdGggIT0gMCkgewotICAgICAgICAgICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJQcmVtYXR1cmVFT0YiLCBudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xOwotICAgICAgICAgICAgICAgICAgICAvL3Rocm93IGU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIC8vU3lzdGVtLm91dC5wcmludGxuKCJFT0ZFeGNlcHRpb24gdGhyb3duIikgOwotICAgICAgICAgICAgICAgIHNldFNjYW5uZXJTdGF0ZShTQ0FOTkVSX1NUQVRFX1RFUk1JTkFURUQpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICByZXR1cm4gWE1MRXZlbnQuRU5EX0RPQ1VNRU5UOwotCi0gICAgICAgIH0vL25leHQKLQotICAgIH0gLy8gY2xhc3MgVHJhaWxpbmdNaXNjRHJpdmVyCi0KLSAgICAvKioKLSAgICAgKiBJbXBsZW1lbnRzIFhNTEJ1ZmZlckxpc3RlbmVyIGludGVyZmFjZS4KLSAgICAgKi8KLQotCi0gICAgLyoqCi0gICAgICogcmVjZWl2ZXMgY2FsbGJhY2tzIGZyb20ge0BsaW5rIFhNTEVudGl0eVJlYWRlciB9IHdoZW4gYnVmZmVyCi0gICAgICogaXMgYmVpbmcgY2hhbmdlZC4KLSAgICAgKiBAcGFyYW0gcmVmcmVzaFBvc2l0aW9uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcmVmcmVzaChpbnQgcmVmcmVzaFBvc2l0aW9uKXsKLSAgICAgICAgc3VwZXIucmVmcmVzaChyZWZyZXNoUG9zaXRpb24pOwotICAgICAgICBpZihmUmVhZGluZ0RURCl7Ci0gICAgICAgICAgICBFbnRpdHkgZW50aXR5ID0gZkVudGl0eVNjYW5uZXIuZ2V0Q3VycmVudEVudGl0eSgpOwotICAgICAgICAgICAgaWYoZW50aXR5IGluc3RhbmNlb2YgRW50aXR5LlNjYW5uZWRFbnRpdHkpewotICAgICAgICAgICAgICAgIGZFbmRQb3M9KChFbnRpdHkuU2Nhbm5lZEVudGl0eSllbnRpdHkpLnBvc2l0aW9uOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZkRURERlY2wuYXBwZW5kKCgoRW50aXR5LlNjYW5uZWRFbnRpdHkpZW50aXR5KS5jaCxmU3RhcnRQb3MgLCBmRW5kUG9zLWZTdGFydFBvcyk7Ci0gICAgICAgICAgICBmU3RhcnRQb3MgPSByZWZyZXNoUG9zaXRpb247Ci0gICAgICAgIH0KLSAgICB9Ci0KLX0gLy8gY2xhc3MgWE1MRG9jdW1lbnRTY2FubmVySW1wbApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9YTUxFbnRpdHlEZXNjcmlwdGlvbi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9YTUxFbnRpdHlEZXNjcmlwdGlvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiOTRlMDhhLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvWE1MRW50aXR5RGVzY3JpcHRpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDUwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbDsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTFJlc291cmNlSWRlbnRpZmllcjsKLQotLyoqCi0gKiA8cD5UaGlzIGludGVyZmFjZSBkZXNjcmliZXMgdGhlIHByb3BlcnRpZXMgb2YgZW50aXRpZXMtLXRoZWlyCi0gKiBwaHlzaWNhbCBsb2NhdGlvbiBhbmQgdGhlaXIgbmFtZS48L3A+Ci0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgTWljaGFlbCBHbGF2YXNzZXZpY2gsIElCTQotICoKLSAqLwotcHVibGljIGludGVyZmFjZSBYTUxFbnRpdHlEZXNjcmlwdGlvbiBleHRlbmRzIFhNTFJlc291cmNlSWRlbnRpZmllciB7Ci0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSBuYW1lIG9mIHRoZSBlbnRpdHkuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSB0aGUgbmFtZSBvZiB0aGUgZW50aXR5Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RW50aXR5TmFtZShTdHJpbmcgbmFtZSk7Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSBlbnRpdHkuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRoZSBuYW1lIG9mIHRoZSBlbnRpdHkKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEVudGl0eU5hbWUoKTsKLQotfSAvLyBYTUxFbnRpdHlEZXNjcmlwdGlvbgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9YTUxFbnRpdHlIYW5kbGVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL1hNTEVudGl0eUhhbmRsZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYTk5YTc0OS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL1hNTEVudGl0eUhhbmRsZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExOSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAwLTIwMDIgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYZXJjZXMiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIEludGVybmF0aW9uYWwKLSAqIEJ1c2luZXNzIE1hY2hpbmVzLCBJbmMuLCBodHRwOi8vd3d3LmFwYWNoZS5vcmcuICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGw7Ci0KLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLkF1Z21lbnRhdGlvbnM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MUmVzb3VyY2VJZGVudGlmaWVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhOSUV4Y2VwdGlvbjsKLQotLyoqCi0gKiBUaGUgZW50aXR5IGhhbmRsZXIgaW50ZXJmYWNlIGRlZmluZXMgbWV0aG9kcyB0byByZXBvcnQgaW5mb3JtYXRpb24KLSAqIGFib3V0IHRoZSBzdGFydCBhbmQgZW5kIG9mIGVudGl0aWVzLgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5YTUxFbnRpdHlTY2FubmVyCi0gKgotICogQGF1dGhvciBBbmR5IENsYXJrLCBJQk0KLSAqCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgWE1MRW50aXR5SGFuZGxlciB7Ci0KLSAgICAvLwotICAgIC8vIFhNTEVudGl0eUhhbmRsZXIgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBub3RpZmllcyBvZiB0aGUgc3RhcnQgb2YgYW4gZW50aXR5LiBUaGUgRFREIGhhcyB0aGUKLSAgICAgKiBwc2V1ZG8tbmFtZSBvZiAiW2R0ZF0iIHBhcmFtZXRlciBlbnRpdHkgbmFtZXMgc3RhcnQgd2l0aCAnJSc7IGFuZAotICAgICAqIGdlbmVyYWwgZW50aXRpZXMgYXJlIGp1c3Qgc3BlY2lmaWVkIGJ5IHRoZWlyIG5hbWUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSAgICAgVGhlIG5hbWUgb2YgdGhlIGVudGl0eS4KLSAgICAgKiBAcGFyYW0gaWRlbnRpZmllciBUaGUgcmVzb3VyY2UgaWRlbnRpZmllci4KLSAgICAgKiBAcGFyYW0gZW5jb2RpbmcgVGhlIGF1dG8tZGV0ZWN0ZWQgSUFOQSBlbmNvZGluZyBuYW1lIG9mIHRoZSBlbnRpdHkKLSAgICAgKiAgICAgICAgICAgICAgICAgc3RyZWFtLiBUaGlzIHZhbHVlIHdpbGwgYmUgbnVsbCBpbiB0aG9zZSBzaXR1YXRpb25zCi0gICAgICogICAgICAgICAgICAgICAgIHdoZXJlIHRoZSBlbnRpdHkgZW5jb2RpbmcgaXMgbm90IGF1dG8tZGV0ZWN0ZWQgKGUuZy4KLSAgICAgKiAgICAgICAgICAgICAgICAgaW50ZXJuYWwgZW50aXRpZXMgb3IgYSBkb2N1bWVudCBlbnRpdHkgdGhhdCBpcwotICAgICAqICAgICAgICAgICAgICAgICBwYXJzZWQgZnJvbSBhIGphdmEuaW8uUmVhZGVyKS4KLSAgICAgKiBAcGFyYW0gYXVncyAgICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RW50aXR5KFN0cmluZyBuYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTFJlc291cmNlSWRlbnRpZmllciBpZGVudGlmaWVyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBlbmNvZGluZywgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2Qgbm90aWZpZXMgdGhlIGVuZCBvZiBhbiBlbnRpdHkuIFRoZSBEVEQgaGFzIHRoZSBwc2V1ZG8tbmFtZQotICAgICAqIG9mICJbZHRkXSIgcGFyYW1ldGVyIGVudGl0eSBuYW1lcyBzdGFydCB3aXRoICclJzsgYW5kIGdlbmVyYWwgZW50aXRpZXMKLSAgICAgKiBhcmUganVzdCBzcGVjaWZpZWQgYnkgdGhlaXIgbmFtZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBlbnRpdHkuCi0gICAgICogQHBhcmFtIGF1Z3MgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBUaGlzIGV4Y2VwdGlvbiBtaWdodCBiZSB0aHJvd24gd2hlbiB0aGVyZSBpcyBwcmVtYXR1cmUgZW5kIG9mIGVudGl0eQotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbmRFbnRpdHkoU3RyaW5nIG5hbWUsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIElPRXhjZXB0aW9uLCBYTklFeGNlcHRpb247Ci0KLX0gLy8gaW50ZXJmYWNlIFhNTEVudGl0eUhhbmRsZXIKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvWE1MRW50aXR5TWFuYWdlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9YTUxFbnRpdHlNYW5hZ2VyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDU3MGUyYTYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9YTUxFbnRpdHlNYW5hZ2VyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzMDM1ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDMsIDIwMTYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKi8KLS8qCi0gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKLSAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAotICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgotICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKLSAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCi0gKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbCA7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuaW8uQVNDSUlSZWFkZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmlvLlVDU1JlYWRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuaW8uVVRGOFJlYWRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwubXNnLlhNTE1lc3NhZ2VGb3JtYXR0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnZhbGlkYXRpb24uVmFsaWRhdGlvbk1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLio7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlVSSTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWxzLlNlY3VyaXR5U3VwcG9ydDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWxzLlhNTExpbWl0QW5hbHl6ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlscy5YTUxTZWN1cml0eU1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlscy5YTUxTZWN1cml0eVByb3BlcnR5TWFuYWdlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5BdWdtZW50YXRpb25zOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTFJlc291cmNlSWRlbnRpZmllcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTklFeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLio7Ci1pbXBvcnQgY29tLnN1bi54bWwuaW50ZXJuYWwuc3RyZWFtLkVudGl0eTsKLWltcG9ydCBjb20uc3VuLnhtbC5pbnRlcm5hbC5zdHJlYW0uU3RheEVudGl0eVJlc29sdmVyV3JhcHBlcjsKLWltcG9ydCBjb20uc3VuLnhtbC5pbnRlcm5hbC5zdHJlYW0uU3RheFhNTElucHV0U291cmNlOwotaW1wb3J0IGNvbS5zdW4ueG1sLmludGVybmFsLnN0cmVhbS5YTUxFbnRpdHlTdG9yYWdlOwotaW1wb3J0IGphdmEuaW8uKjsKLWltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2Q7Ci1pbXBvcnQgamF2YS5uZXQuSHR0cFVSTENvbm5lY3Rpb247Ci1pbXBvcnQgamF2YS5uZXQuVVJJU3ludGF4RXhjZXB0aW9uOwotaW1wb3J0IGphdmEubmV0LlVSTDsKLWltcG9ydCBqYXZhLm5ldC5VUkxDb25uZWN0aW9uOwotaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwotaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKLWltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwotaW1wb3J0IGphdmEudXRpbC5NYXA7Ci1pbXBvcnQgamF2YS51dGlsLlN0YWNrOwotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uWE1MSW5wdXRGYWN0b3J5OwotCi0KLS8qKgotICogV2lsbCBrZWVwIHRyYWNrIG9mIGN1cnJlbnQgZW50aXR5LgotICoKLSAqIFRoZSBlbnRpdHkgbWFuYWdlciBoYW5kbGVzIHRoZSByZWdpc3RyYXRpb24gb2YgZ2VuZXJhbCBhbmQgcGFyYW1ldGVyCi0gKiBlbnRpdGllczsgcmVzb2x2ZXMgZW50aXRpZXM7IGFuZCBzdGFydHMgZW50aXRpZXMuIFRoZSBlbnRpdHkgbWFuYWdlcgotICogaXMgYSBjZW50cmFsIGNvbXBvbmVudCBpbiBhIHN0YW5kYXJkIHBhcnNlciBjb25maWd1cmF0aW9uIGFuZCB0aGlzCi0gKiBjbGFzcyB3b3JrcyBkaXJlY3RseSB3aXRoIHRoZSBlbnRpdHkgc2Nhbm5lciB0byBtYW5hZ2UgdGhlIHVuZGVybHlpbmcKLSAqIHhuaS4KLSAqIDxwPgotICogVGhpcyBjb21wb25lbnQgcmVxdWlyZXMgdGhlIGZvbGxvd2luZyBmZWF0dXJlcyBhbmQgcHJvcGVydGllcyBmcm9tIHRoZQotICogY29tcG9uZW50IG1hbmFnZXIgdGhhdCB1c2VzIGl0OgotICogPHVsPgotICogIDxsaT5odHRwOi8veG1sLm9yZy9zYXgvZmVhdHVyZXMvdmFsaWRhdGlvbjwvbGk+Ci0gKiAgPGxpPmh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy9leHRlcm5hbC1nZW5lcmFsLWVudGl0aWVzPC9saT4KLSAqICA8bGk+aHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL2V4dGVybmFsLXBhcmFtZXRlci1lbnRpdGllczwvbGk+Ci0gKiAgPGxpPmh0dHA6Ly9hcGFjaGUub3JnL3htbC9mZWF0dXJlcy9hbGxvdy1qYXZhLWVuY29kaW5nczwvbGk+Ci0gKiAgPGxpPmh0dHA6Ly9hcGFjaGUub3JnL3htbC9wcm9wZXJ0aWVzL2ludGVybmFsL3N5bWJvbC10YWJsZTwvbGk+Ci0gKiAgPGxpPmh0dHA6Ly9hcGFjaGUub3JnL3htbC9wcm9wZXJ0aWVzL2ludGVybmFsL2Vycm9yLXJlcG9ydGVyPC9saT4KLSAqICA8bGk+aHR0cDovL2FwYWNoZS5vcmcveG1sL3Byb3BlcnRpZXMvaW50ZXJuYWwvZW50aXR5LXJlc29sdmVyPC9saT4KLSAqIDwvdWw+Ci0gKgotICoKLSAqIEBhdXRob3IgQW5keSBDbGFyaywgSUJNCi0gKiBAYXV0aG9yIEFybmF1ZCAgTGUgSG9ycywgSUJNCi0gKiBAYXV0aG9yIEsuVmVudWdvcGFsIFNVTiBNaWNyb3N5c3RlbXMKLSAqIEBhdXRob3IgTmVlcmFqIEJhamFqIFNVTiBNaWNyb3N5c3RlbXMKLSAqIEBhdXRob3IgU3VuaXRoYSBSZWRkeSBTVU4gTWljcm9zeXN0ZW1zCi0gKiBAdmVyc2lvbiAkSWQ6IFhNTEVudGl0eU1hbmFnZXIuamF2YSx2IDEuMTcgMjAxMC0xMS0wMSAwNDozOTo0MSBqb2VodyBFeHAgJAotICovCi1wdWJsaWMgY2xhc3MgWE1MRW50aXR5TWFuYWdlciBpbXBsZW1lbnRzIFhNTENvbXBvbmVudCwgWE1MRW50aXR5UmVzb2x2ZXIgewotCi0gICAgLy8KLSAgICAvLyBDb25zdGFudHMKLSAgICAvLwotCi0gICAgLyoqIERlZmF1bHQgYnVmZmVyIHNpemUgKDIwNDgpLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFRkFVTFRfQlVGRkVSX1NJWkUgPSA4MTkyOwotCi0gICAgLyoqIERlZmF1bHQgYnVmZmVyIHNpemUgYmVmb3JlIHdlJ3ZlIGZpbmlzaGVkIHdpdGggdGhlIFhNTERlY2w6ICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFRkFVTFRfWE1MREVDTF9CVUZGRVJfU0laRSA9IDY0OwotCi0gICAgLyoqIERlZmF1bHQgaW50ZXJuYWwgZW50aXR5IGJ1ZmZlciBzaXplICgxMDI0KS4gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBERUZBVUxUX0lOVEVSTkFMX0JVRkZFUl9TSVpFID0gMTAyNDsKLQotICAgIC8vIGZlYXR1cmUgaWRlbnRpZmllcnMKLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IHZhbGlkYXRpb24uICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgVkFMSURBVElPTiA9Ci0gICAgICAgICAgICBDb25zdGFudHMuU0FYX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLlZBTElEQVRJT05fRkVBVFVSRTsKLQotICAgIC8qKgotICAgICAqIHN0YW5kYXJkIHVyaSBjb25mb3JtYW50IChzdHJpY3QgdXJpKS4KLSAgICAgKiBodHRwOi8vYXBhY2hlLm9yZy94bWwvZmVhdHVyZXMvc3RhbmRhcmQtdXJpLWNvbmZvcm1hbnQKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBmU3RyaWN0VVJJOwotCi0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiBleHRlcm5hbCBnZW5lcmFsIGVudGl0aWVzLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIEVYVEVSTkFMX0dFTkVSQUxfRU5USVRJRVMgPQotICAgICAgICAgICAgQ29uc3RhbnRzLlNBWF9GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5FWFRFUk5BTF9HRU5FUkFMX0VOVElUSUVTX0ZFQVRVUkU7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiBleHRlcm5hbCBwYXJhbWV0ZXIgZW50aXRpZXMuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVhURVJOQUxfUEFSQU1FVEVSX0VOVElUSUVTID0KLSAgICAgICAgICAgIENvbnN0YW50cy5TQVhfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuRVhURVJOQUxfUEFSQU1FVEVSX0VOVElUSUVTX0ZFQVRVUkU7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiBhbGxvdyBKYXZhIGVuY29kaW5ncy4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBBTExPV19KQVZBX0VOQ09ESU5HUyA9Ci0gICAgICAgICAgICBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLkFMTE9XX0pBVkFfRU5DT0RJTkdTX0ZFQVRVUkU7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiB3YXJuIG9uIGR1cGxpY2F0ZSBFbnRpdHlEZWYgKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBXQVJOX09OX0RVUExJQ0FURV9FTlRJVFlERUYgPQotICAgICAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArQ29uc3RhbnRzLldBUk5fT05fRFVQTElDQVRFX0VOVElUWURFRl9GRUFUVVJFOwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogbG9hZCBleHRlcm5hbCBEVEQuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgTE9BRF9FWFRFUk5BTF9EVEQgPQotICAgICAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5MT0FEX0VYVEVSTkFMX0RURF9GRUFUVVJFOwotCi0gICAgLy8gcHJvcGVydHkgaWRlbnRpZmllcnMKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBzeW1ib2wgdGFibGUuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1lNQk9MX1RBQkxFID0KLSAgICAgICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLlNZTUJPTF9UQUJMRV9QUk9QRVJUWTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBlcnJvciByZXBvcnRlci4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJPUl9SRVBPUlRFUiA9Ci0gICAgICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5FUlJPUl9SRVBPUlRFUl9QUk9QRVJUWTsKLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IHN0YW5kYXJkIHVyaSBjb25mb3JtYW50ICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1RBTkRBUkRfVVJJX0NPTkZPUk1BTlQgPQotICAgICAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArQ29uc3RhbnRzLlNUQU5EQVJEX1VSSV9DT05GT1JNQU5UX0ZFQVRVUkU7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogZW50aXR5IHJlc29sdmVyLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIEVOVElUWV9SRVNPTFZFUiA9Ci0gICAgICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5FTlRJVFlfUkVTT0xWRVJfUFJPUEVSVFk7Ci0KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBTVEFYX0VOVElUWV9SRVNPTFZFUiA9Ci0gICAgICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5TVEFYX0VOVElUWV9SRVNPTFZFUl9QUk9QRVJUWTsKLQotICAgIC8vIHByb3BlcnR5IGlkZW50aWZpZXI6ICBWYWxpZGF0aW9uTWFuYWdlcgotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFZBTElEQVRJT05fTUFOQUdFUiA9Ci0gICAgICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5WQUxJREFUSU9OX01BTkFHRVJfUFJPUEVSVFk7Ci0KLSAgICAvKiogcHJvcGVydHkgaWRlbnRpZmllcjogYnVmZmVyIHNpemUuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgQlVGRkVSX1NJWkUgPQotICAgICAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuQlVGRkVSX1NJWkVfUFJPUEVSVFk7Ci0KLSAgICAvKiogcHJvcGVydHkgaWRlbnRpZmllcjogc2VjdXJpdHkgbWFuYWdlci4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBTRUNVUklUWV9NQU5BR0VSID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuU0VDVVJJVFlfTUFOQUdFUl9QUk9QRVJUWTsKLQotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFBBUlNFUl9TRVRUSU5HUyA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuUEFSU0VSX1NFVFRJTkdTOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IFNlY3VyaXR5IHByb3BlcnR5IG1hbmFnZXIuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFhNTF9TRUNVUklUWV9QUk9QRVJUWV9NQU5BR0VSID0KLSAgICAgICAgICAgIENvbnN0YW50cy5YTUxfU0VDVVJJVFlfUFJPUEVSVFlfTUFOQUdFUjsKLQotICAgIC8qKiBhY2Nlc3MgZXh0ZXJuYWwgZHRkOiBmaWxlIHByb3RvY29sICovCi0gICAgc3RhdGljIGZpbmFsIFN0cmluZyBFWFRFUk5BTF9BQ0NFU1NfREVGQVVMVCA9IENvbnN0YW50cy5FWFRFUk5BTF9BQ0NFU1NfREVGQVVMVDsKLQotICAgIC8vIHJlY29nbml6ZWQgZmVhdHVyZXMgYW5kIHByb3BlcnRpZXMKLQotICAgIC8qKiBSZWNvZ25pemVkIGZlYXR1cmVzLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZ1tdIFJFQ09HTklaRURfRkVBVFVSRVMgPSB7Ci0gICAgICAgICAgICAgICAgVkFMSURBVElPTiwKLSAgICAgICAgICAgICAgICBFWFRFUk5BTF9HRU5FUkFMX0VOVElUSUVTLAotICAgICAgICAgICAgICAgIEVYVEVSTkFMX1BBUkFNRVRFUl9FTlRJVElFUywKLSAgICAgICAgICAgICAgICBBTExPV19KQVZBX0VOQ09ESU5HUywKLSAgICAgICAgICAgICAgICBXQVJOX09OX0RVUExJQ0FURV9FTlRJVFlERUYsCi0gICAgICAgICAgICAgICAgU1RBTkRBUkRfVVJJX0NPTkZPUk1BTlQKLSAgICB9OwotCi0gICAgLyoqIEZlYXR1cmUgZGVmYXVsdHMuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQm9vbGVhbltdIEZFQVRVUkVfREVGQVVMVFMgPSB7Ci0gICAgICAgICAgICAgICAgbnVsbCwKLSAgICAgICAgICAgICAgICBCb29sZWFuLlRSVUUsCi0gICAgICAgICAgICAgICAgQm9vbGVhbi5UUlVFLAotICAgICAgICAgICAgICAgIEJvb2xlYW4uVFJVRSwKLSAgICAgICAgICAgICAgICBCb29sZWFuLkZBTFNFLAotICAgICAgICAgICAgICAgIEJvb2xlYW4uRkFMU0UKLSAgICB9OwotCi0gICAgLyoqIFJlY29nbml6ZWQgcHJvcGVydGllcy4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSBSRUNPR05JWkVEX1BST1BFUlRJRVMgPSB7Ci0gICAgICAgICAgICAgICAgU1lNQk9MX1RBQkxFLAotICAgICAgICAgICAgICAgIEVSUk9SX1JFUE9SVEVSLAotICAgICAgICAgICAgICAgIEVOVElUWV9SRVNPTFZFUiwKLSAgICAgICAgICAgICAgICBWQUxJREFUSU9OX01BTkFHRVIsCi0gICAgICAgICAgICAgICAgQlVGRkVSX1NJWkUsCi0gICAgICAgICAgICAgICAgU0VDVVJJVFlfTUFOQUdFUiwKLSAgICAgICAgICAgICAgICBYTUxfU0VDVVJJVFlfUFJPUEVSVFlfTUFOQUdFUgotICAgIH07Ci0KLSAgICAvKiogUHJvcGVydHkgZGVmYXVsdHMuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgT2JqZWN0W10gUFJPUEVSVFlfREVGQVVMVFMgPSB7Ci0gICAgICAgICAgICAgICAgbnVsbCwKLSAgICAgICAgICAgICAgICBudWxsLAotICAgICAgICAgICAgICAgIG51bGwsCi0gICAgICAgICAgICAgICAgbnVsbCwKLSAgICAgICAgICAgICAgICBuZXcgSW50ZWdlcihERUZBVUxUX0JVRkZFUl9TSVpFKSwKLSAgICAgICAgICAgICAgICBudWxsLAotICAgICAgICAgICAgICAgIG51bGwKLSAgICB9OwotCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFhNTEVudGl0eSA9ICJbeG1sXSIuaW50ZXJuKCk7Ci0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIERUREVudGl0eSA9ICJbZHRkXSIuaW50ZXJuKCk7Ci0KLSAgICAvLyBkZWJ1Z2dpbmcKLQotICAgIC8qKgotICAgICAqIERlYnVnIHByaW50aW5nIG9mIGJ1ZmZlci4gVGhpcyBkZWJ1Z2dpbmcgZmxhZyB3b3JrcyBiZXN0IHdoZW4geW91Ci0gICAgICogcmVzaXplIHRoZSBERUZBVUxUX0JVRkZFUl9TSVpFIGRvd24gdG8gc29tZXRoaW5nIHJlYXNvbmFibGUgbGlrZQotICAgICAqIDY0IGNoYXJhY3RlcnMuCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbiBERUJVR19CVUZGRVIgPSBmYWxzZTsKLQotICAgIC8qKiB3YXJuIG9uIGR1cGxpY2F0ZSBFbnRpdHkgZGVjbGFyYXRpb24uCi0gICAgICogIGh0dHA6Ly9hcGFjaGUub3JnL3htbC9mZWF0dXJlcy93YXJuLW9uLWR1cGxpY2F0ZS1lbnRpdHlkZWYKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBmV2FybkR1cGxpY2F0ZUVudGl0eURlZjsKLQotICAgIC8qKiBEZWJ1ZyBzb21lIGJhc2ljIGVudGl0aWVzLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW4gREVCVUdfRU5USVRJRVMgPSBmYWxzZTsKLQotICAgIC8qKiBEZWJ1ZyBzd2l0Y2hpbmcgcmVhZGVycyBmb3IgZW5jb2RpbmdzLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW4gREVCVUdfRU5DT0RJTkdTID0gZmFsc2U7Ci0KLSAgICAvLyBzaG91bGQgYmUgZGlwbGF5ZWQgdHJhY2UgcmVzb2x2aW5nIG1lc3NhZ2VzCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbiBERUJVR19SRVNPTFZFUiA9IGZhbHNlIDsKLQotICAgIC8vCi0gICAgLy8gRGF0YQotICAgIC8vCi0KLSAgICAvLyBmZWF0dXJlcwotCi0gICAgLyoqCi0gICAgICogVmFsaWRhdGlvbi4gVGhpcyBmZWF0dXJlIGlkZW50aWZpZXIgaXM6Ci0gICAgICogaHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL3ZhbGlkYXRpb24KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBmVmFsaWRhdGlvbjsKLQotICAgIC8qKgotICAgICAqIEV4dGVybmFsIGdlbmVyYWwgZW50aXRpZXMuIFRoaXMgZmVhdHVyZSBpZGVudGlmaWVyIGlzOgotICAgICAqIGh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy9leHRlcm5hbC1nZW5lcmFsLWVudGl0aWVzCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZkV4dGVybmFsR2VuZXJhbEVudGl0aWVzOwotCi0gICAgLyoqCi0gICAgICogRXh0ZXJuYWwgcGFyYW1ldGVyIGVudGl0aWVzLiBUaGlzIGZlYXR1cmUgaWRlbnRpZmllciBpczoKLSAgICAgKiBodHRwOi8veG1sLm9yZy9zYXgvZmVhdHVyZXMvZXh0ZXJuYWwtcGFyYW1ldGVyLWVudGl0aWVzCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZkV4dGVybmFsUGFyYW1ldGVyRW50aXRpZXM7Ci0KLSAgICAvKioKLSAgICAgKiBBbGxvdyBKYXZhIGVuY29kaW5nIG5hbWVzLiBUaGlzIGZlYXR1cmUgaWRlbnRpZmllciBpczoKLSAgICAgKiBodHRwOi8vYXBhY2hlLm9yZy94bWwvZmVhdHVyZXMvYWxsb3ctamF2YS1lbmNvZGluZ3MKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBmQWxsb3dKYXZhRW5jb2RpbmdzID0gdHJ1ZSA7Ci0KLSAgICAvKiogTG9hZCBleHRlcm5hbCBEVEQuICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZkxvYWRFeHRlcm5hbERURCA9IHRydWU7Ci0KLSAgICAvLyBwcm9wZXJ0aWVzCi0KLSAgICAvKioKLSAgICAgKiBTeW1ib2wgdGFibGUuIFRoaXMgcHJvcGVydHkgaWRlbnRpZmllciBpczoKLSAgICAgKiBodHRwOi8vYXBhY2hlLm9yZy94bWwvcHJvcGVydGllcy9pbnRlcm5hbC9zeW1ib2wtdGFibGUKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgU3ltYm9sVGFibGUgZlN5bWJvbFRhYmxlOwotCi0gICAgLyoqCi0gICAgICogRXJyb3IgcmVwb3J0ZXIuIFRoaXMgcHJvcGVydHkgaWRlbnRpZmllciBpczoKLSAgICAgKiBodHRwOi8vYXBhY2hlLm9yZy94bWwvcHJvcGVydGllcy9pbnRlcm5hbC9lcnJvci1yZXBvcnRlcgotICAgICAqLwotICAgIHByb3RlY3RlZCBYTUxFcnJvclJlcG9ydGVyIGZFcnJvclJlcG9ydGVyOwotCi0gICAgLyoqCi0gICAgICogRW50aXR5IHJlc29sdmVyLiBUaGlzIHByb3BlcnR5IGlkZW50aWZpZXIgaXM6Ci0gICAgICogaHR0cDovL2FwYWNoZS5vcmcveG1sL3Byb3BlcnRpZXMvaW50ZXJuYWwvZW50aXR5LXJlc29sdmVyCi0gICAgICovCi0gICAgcHJvdGVjdGVkIFhNTEVudGl0eVJlc29sdmVyIGZFbnRpdHlSZXNvbHZlcjsKLQotICAgIC8qKiBTdGF4IEVudGl0eSBSZXNvbHZlci4gVGhpcyBwcm9wZXJ0eSBpZGVudGlmaWVyIGlzIFhNTElucHV0RmFjdG9yeS5FTlRJVFlfUkVTT0xWRVIgKi8KLQotICAgIHByb3RlY3RlZCBTdGF4RW50aXR5UmVzb2x2ZXJXcmFwcGVyIGZTdGF4RW50aXR5UmVzb2x2ZXI7Ci0KLSAgICAvKiogUHJvcGVydHkgTWFuYWdlci4gVGhpcyBpcyB1c2VkIGZyb20gU3RheCAqLwotICAgIHByb3RlY3RlZCBQcm9wZXJ0eU1hbmFnZXIgZlByb3BlcnR5TWFuYWdlciA7Ci0KLSAgICAvKiogU3RBWCBwcm9wZXJ0aWVzICovCi0gICAgYm9vbGVhbiBmU3VwcG9ydERURCA9IHRydWU7Ci0gICAgYm9vbGVhbiBmUmVwbGFjZUVudGl0eVJlZmVyZW5jZXMgPSB0cnVlOwotICAgIGJvb2xlYW4gZlN1cHBvcnRFeHRlcm5hbEVudGl0aWVzID0gdHJ1ZTsKLQotICAgIC8qKiB1c2VkIHRvIHJlc3RyaWN0IGV4dGVybmFsIGFjY2VzcyAqLwotICAgIHByb3RlY3RlZCBTdHJpbmcgZkFjY2Vzc0V4dGVybmFsRFREID0gRVhURVJOQUxfQUNDRVNTX0RFRkFVTFQ7Ci0KLSAgICAvLyBzZXR0aW5ncwotCi0gICAgLyoqCi0gICAgICogVmFsaWRhdGlvbiBtYW5hZ2VyLiBUaGlzIHByb3BlcnR5IGlkZW50aWZpZXIgaXM6Ci0gICAgICogaHR0cDovL2FwYWNoZS5vcmcveG1sL3Byb3BlcnRpZXMvaW50ZXJuYWwvdmFsaWRhdGlvbi1tYW5hZ2VyCi0gICAgICovCi0gICAgcHJvdGVjdGVkIFZhbGlkYXRpb25NYW5hZ2VyIGZWYWxpZGF0aW9uTWFuYWdlcjsKLQotICAgIC8vIHNldHRpbmdzCi0KLSAgICAvKioKLSAgICAgKiBCdWZmZXIgc2l6ZS4gV2UgZ2V0IHRoaXMgdmFsdWUgZnJvbSBhIHByb3BlcnR5LiBUaGUgZGVmYXVsdCBzaXplCi0gICAgICogaXMgdXNlZCBpZiB0aGUgaW5wdXQgYnVmZmVyIHNpemUgcHJvcGVydHkgaXMgbm90IHNwZWNpZmllZC4KLSAgICAgKiBSRVZJU0lUOiBkbyB3ZSBuZWVkIGEgcHJvcGVydHkgZm9yIGludGVybmFsIGVudGl0eSBidWZmZXIgc2l6ZT8KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgaW50IGZCdWZmZXJTaXplID0gREVGQVVMVF9CVUZGRVJfU0laRTsKLQotICAgIC8qKiBTZWN1cml0eSBNYW5hZ2VyICovCi0gICAgcHJvdGVjdGVkIFhNTFNlY3VyaXR5TWFuYWdlciBmU2VjdXJpdHlNYW5hZ2VyID0gbnVsbDsKLQotICAgIHByb3RlY3RlZCBYTUxMaW1pdEFuYWx5emVyIGZMaW1pdEFuYWx5emVyID0gbnVsbDsKLQotICAgIHByb3RlY3RlZCBpbnQgZW50aXR5RXhwYW5zaW9uSW5kZXg7Ci0KLSAgICAvKioKLSAgICAgKiBUcnVlIGlmIHRoZSBkb2N1bWVudCBlbnRpdHkgaXMgc3RhbmRhbG9uZS4gVGhpcyBzaG91bGQgcmVhbGx5Ci0gICAgICogb25seSBiZSBzZXQgYnkgdGhlIGRvY3VtZW50IHNvdXJjZSAoZS5nLiBYTUxEb2N1bWVudFNjYW5uZXIpLgotICAgICAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIGZTdGFuZGFsb25lOwotCi0gICAgLy8gYXJlIHRoZSBlbnRpdGllcyBiZWluZyBwYXJzZWQgaW4gdGhlIGV4dGVybmFsIHN1YnNldD8KLSAgICAvLyBOT1RFOiAgdGhpcyAqaXMgbm90KiB0aGUgc2FtZSBhcyB3aGV0aGVyIHRoZXkncmUgZXh0ZXJuYWwgZW50aXRpZXMhCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZkluRXh0ZXJuYWxTdWJzZXQgPSBmYWxzZTsKLQotCi0gICAgLy8gaGFuZGxlcnMKLSAgICAvKiogRW50aXR5IGhhbmRsZXIuICovCi0gICAgcHJvdGVjdGVkIFhNTEVudGl0eUhhbmRsZXIgZkVudGl0eUhhbmRsZXI7Ci0KLSAgICAvKiogQ3VycmVudCBlbnRpdHkgc2Nhbm5lciAqLwotICAgIHByb3RlY3RlZCBYTUxFbnRpdHlTY2FubmVyIGZFbnRpdHlTY2FubmVyIDsKLQotICAgIC8qKiBYTUwgMS4wIGVudGl0eSBzY2FubmVyLiAqLwotICAgIHByb3RlY3RlZCBYTUxFbnRpdHlTY2FubmVyIGZYTUwxMEVudGl0eVNjYW5uZXI7Ci0KLSAgICAvKiogWE1MIDEuMSBlbnRpdHkgc2Nhbm5lci4gKi8KLSAgICBwcm90ZWN0ZWQgWE1MRW50aXR5U2Nhbm5lciBmWE1MMTFFbnRpdHlTY2FubmVyOwotCi0gICAgLyoqIGNvdW50IG9mIGVudGl0aWVzIGV4cGFuZGVkOiAqLwotICAgIHByb3RlY3RlZCBpbnQgZkVudGl0eUV4cGFuc2lvbkNvdW50ID0gMDsKLQotICAgIC8vIGVudGl0aWVzCi0KLSAgICAvKiogRW50aXRpZXMuICovCi0gICAgcHJvdGVjdGVkIE1hcDxTdHJpbmcsIEVudGl0eT4gZkVudGl0aWVzID0gbmV3IEhhc2hNYXA8PigpOwotCi0gICAgLyoqIEVudGl0eSBzdGFjay4gKi8KLSAgICBwcm90ZWN0ZWQgU3RhY2s8RW50aXR5PiBmRW50aXR5U3RhY2sgPSBuZXcgU3RhY2s8PigpOwotCi0gICAgLyoqIEN1cnJlbnQgZW50aXR5LiAqLwotICAgIHByb3RlY3RlZCBFbnRpdHkuU2Nhbm5lZEVudGl0eSBmQ3VycmVudEVudGl0eSA9IG51bGw7Ci0KLSAgICAvKiogaWRlbnRpZnkgaWYgdGhlIElucHV0U291cmNlIGlzIGNyZWF0ZWQgYnkgYSByZXNvbHZlciAqLwotICAgIGJvb2xlYW4gZklTQ3JlYXRlZEJ5UmVzb2x2ZXIgPSBmYWxzZTsKLQotICAgIC8vIHNoYXJlZCBjb250ZXh0Ci0KLSAgICBwcm90ZWN0ZWQgWE1MRW50aXR5U3RvcmFnZSBmRW50aXR5U3RvcmFnZSA7Ci0KLSAgICBwcm90ZWN0ZWQgZmluYWwgT2JqZWN0IFtdIGRlZmF1bHRFbmNvZGluZyA9IG5ldyBPYmplY3RbXXsiVVRGLTgiLCBudWxsfTsKLQotCi0gICAgLy8gdGVtcCB2YXJzCi0KLSAgICAvKiogUmVzb3VyY2UgaWRlbnRpZmVyLiAqLwotICAgIHByaXZhdGUgZmluYWwgWE1MUmVzb3VyY2VJZGVudGlmaWVySW1wbCBmUmVzb3VyY2VJZGVudGlmaWVyID0gbmV3IFhNTFJlc291cmNlSWRlbnRpZmllckltcGwoKTsKLQotICAgIC8qKiBBdWdtZW50YXRpb25zIGZvciBlbnRpdGllcy4gKi8KLSAgICBwcml2YXRlIGZpbmFsIEF1Z21lbnRhdGlvbnMgZkVudGl0eUF1Z3MgPSBuZXcgQXVnbWVudGF0aW9uc0ltcGwoKTsKLQotICAgIC8qKiBQb29sIG9mIGNoYXJhY3RlciBidWZmZXJzLiAqLwotICAgIHByaXZhdGUgQ2hhcmFjdGVyQnVmZmVyUG9vbCBmQnVmZmVyUG9vbCA9IG5ldyBDaGFyYWN0ZXJCdWZmZXJQb29sKGZCdWZmZXJTaXplLCBERUZBVUxUX0lOVEVSTkFMX0JVRkZFUl9TSVpFKTsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIElmIHRoaXMgY29uc3RydWN0b3IgaXMgdXNlZCB0byBjcmVhdGUgdGhlIG9iamVjdCwgcmVzZXQoKSBzaG91bGQgYmUgaW52b2tlZCBvbiB0aGlzIG9iamVjdAotICAgICAqLwotICAgIHB1YmxpYyBYTUxFbnRpdHlNYW5hZ2VyKCkgewotICAgICAgICAvL2ZvciBlbnRpdHkgbWFuYWdlcnMgbm90IGNyZWF0ZWQgYnkgcGFyc2VycwotICAgICAgICBmU2VjdXJpdHlNYW5hZ2VyID0gbmV3IFhNTFNlY3VyaXR5TWFuYWdlcih0cnVlKTsKLSAgICAgICAgZkVudGl0eVN0b3JhZ2UgPSBuZXcgWE1MRW50aXR5U3RvcmFnZSh0aGlzKSA7Ci0gICAgICAgIHNldFNjYW5uZXJWZXJzaW9uKENvbnN0YW50cy5YTUxfVkVSU0lPTl8xXzApOwotICAgIH0gLy8gPGluaXQ+KCkKLQotICAgIC8qKiBEZWZhdWx0IGNvbnN0cnVjdG9yLiAqLwotICAgIHB1YmxpYyBYTUxFbnRpdHlNYW5hZ2VyKFByb3BlcnR5TWFuYWdlciBwcm9wZXJ0eU1hbmFnZXIpIHsKLSAgICAgICAgZlByb3BlcnR5TWFuYWdlciA9IHByb3BlcnR5TWFuYWdlciA7Ci0gICAgICAgIC8vcGFzcyBhIHJlZmVyZW5jZSB0byBjdXJyZW50IGVudGl0eSBiZWluZyBzY2FubmVkCi0gICAgICAgIC8vZkVudGl0eVN0b3JhZ2UgPSBuZXcgWE1MRW50aXR5U3RvcmFnZShmQ3VycmVudEVudGl0eSkgOwotICAgICAgICBmRW50aXR5U3RvcmFnZSA9IG5ldyBYTUxFbnRpdHlTdG9yYWdlKHRoaXMpIDsKLSAgICAgICAgZkVudGl0eVNjYW5uZXIgPSBuZXcgWE1MRW50aXR5U2Nhbm5lcihwcm9wZXJ0eU1hbmFnZXIsIHRoaXMpIDsKLSAgICAgICAgcmVzZXQocHJvcGVydHlNYW5hZ2VyKTsKLSAgICB9IC8vIDxpbml0PigpCi0KLSAgICAvKioKLSAgICAgKiBBZGRzIGFuIGludGVybmFsIGVudGl0eSBkZWNsYXJhdGlvbi4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoaXMgbWV0aG9kIGlnbm9yZXMgc3Vic2VxdWVudCBlbnRpdHkKLSAgICAgKiBkZWNsYXJhdGlvbnMuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGUgbmFtZSBzaG91bGQgYmUgYSB1bmlxdWUgc3ltYm9sLiBUaGUKLSAgICAgKiBTeW1ib2xUYWJsZSBjYW4gYmUgdXNlZCBmb3IgdGhpcyBwdXJwb3NlLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGVudGl0eS4KLSAgICAgKiBAcGFyYW0gdGV4dCBUaGUgdGV4dCBvZiB0aGUgZW50aXR5LgotICAgICAqCi0gICAgICogQHNlZSBTeW1ib2xUYWJsZQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGFkZEludGVybmFsRW50aXR5KFN0cmluZyBuYW1lLCBTdHJpbmcgdGV4dCkgewotICAgICAgICBpZiAoIWZFbnRpdGllcy5jb250YWluc0tleShuYW1lKSkgewotICAgICAgICAgICAgRW50aXR5IGVudGl0eSA9IG5ldyBFbnRpdHkuSW50ZXJuYWxFbnRpdHkobmFtZSwgdGV4dCwgZkluRXh0ZXJuYWxTdWJzZXQpOwotICAgICAgICAgICAgZkVudGl0aWVzLnB1dChuYW1lLCBlbnRpdHkpOwotICAgICAgICB9IGVsc2V7Ci0gICAgICAgICAgICBpZihmV2FybkR1cGxpY2F0ZUVudGl0eURlZil7Ci0gICAgICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgIk1TR19EVVBMSUNBVEVfRU5USVRZX0RFRklOSVRJT04iLAotICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdeyBuYW1lIH0sCi0gICAgICAgICAgICAgICAgICAgICAgICBYTUxFcnJvclJlcG9ydGVyLlNFVkVSSVRZX1dBUk5JTkcgKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgfSAvLyBhZGRJbnRlcm5hbEVudGl0eShTdHJpbmcsU3RyaW5nKQotCi0gICAgLyoqCi0gICAgICogQWRkcyBhbiBleHRlcm5hbCBlbnRpdHkgZGVjbGFyYXRpb24uCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGlzIG1ldGhvZCBpZ25vcmVzIHN1YnNlcXVlbnQgZW50aXR5Ci0gICAgICogZGVjbGFyYXRpb25zLgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gVGhlIG5hbWUgc2hvdWxkIGJlIGEgdW5pcXVlIHN5bWJvbC4gVGhlCi0gICAgICogU3ltYm9sVGFibGUgY2FuIGJlIHVzZWQgZm9yIHRoaXMgcHVycG9zZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lICAgICAgICAgVGhlIG5hbWUgb2YgdGhlIGVudGl0eS4KLSAgICAgKiBAcGFyYW0gcHVibGljSWQgICAgIFRoZSBwdWJsaWMgaWRlbnRpZmllciBvZiB0aGUgZW50aXR5LgotICAgICAqIEBwYXJhbSBsaXRlcmFsU3lzdGVtSWQgICAgIFRoZSBzeXN0ZW0gaWRlbnRpZmllciBvZiB0aGUgZW50aXR5LgotICAgICAqIEBwYXJhbSBiYXNlU3lzdGVtSWQgVGhlIGJhc2Ugc3lzdGVtIGlkZW50aWZpZXIgb2YgdGhlIGVudGl0eS4KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgIFRoaXMgaXMgdGhlIHN5c3RlbSBpZGVudGlmaWVyIG9mIHRoZSBlbnRpdHkKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgIHdoZXJlIDxlbT50aGUgZW50aXR5IGJlaW5nIGFkZGVkPC9lbT4gYW5kCi0gICAgICogICAgICAgICAgICAgICAgICAgICBpcyB1c2VkIHRvIGV4cGFuZCB0aGUgc3lzdGVtIGlkZW50aWZpZXIgd2hlbgotICAgICAqICAgICAgICAgICAgICAgICAgICAgdGhlIHN5c3RlbSBpZGVudGlmaWVyIGlzIGEgcmVsYXRpdmUgVVJJLgotICAgICAqICAgICAgICAgICAgICAgICAgICAgV2hlbiBudWxsIHRoZSBzeXN0ZW0gaWRlbnRpZmllciBvZiB0aGUgZmlyc3QKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgIGV4dGVybmFsIGVudGl0eSBvbiB0aGUgc3RhY2sgaXMgdXNlZCBpbnN0ZWFkLgotICAgICAqCi0gICAgICogQHNlZSBTeW1ib2xUYWJsZQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGFkZEV4dGVybmFsRW50aXR5KFN0cmluZyBuYW1lLAotICAgICAgICAgICAgU3RyaW5nIHB1YmxpY0lkLCBTdHJpbmcgbGl0ZXJhbFN5c3RlbUlkLAotICAgICAgICAgICAgU3RyaW5nIGJhc2VTeXN0ZW1JZCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKCFmRW50aXRpZXMuY29udGFpbnNLZXkobmFtZSkpIHsKLSAgICAgICAgICAgIGlmIChiYXNlU3lzdGVtSWQgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIC8vIHNlYXJjaCBmb3IgdGhlIGZpcnN0IGV4dGVybmFsIGVudGl0eSBvbiB0aGUgc3RhY2sKLSAgICAgICAgICAgICAgICBpbnQgc2l6ZSA9IGZFbnRpdHlTdGFjay5zaXplKCk7Ci0gICAgICAgICAgICAgICAgaWYgKHNpemUgPT0gMCAmJiBmQ3VycmVudEVudGl0eSAhPSBudWxsICYmIGZDdXJyZW50RW50aXR5LmVudGl0eUxvY2F0aW9uICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgYmFzZVN5c3RlbUlkID0gZkN1cnJlbnRFbnRpdHkuZW50aXR5TG9jYXRpb24uZ2V0RXhwYW5kZWRTeXN0ZW1JZCgpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gc2l6ZSAtIDE7IGkgPj0gMCA7IGktLSkgewotICAgICAgICAgICAgICAgICAgICBFbnRpdHkuU2Nhbm5lZEVudGl0eSBleHRlcm5hbEVudGl0eSA9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgKEVudGl0eS5TY2FubmVkRW50aXR5KWZFbnRpdHlTdGFjay5lbGVtZW50QXQoaSk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChleHRlcm5hbEVudGl0eS5lbnRpdHlMb2NhdGlvbiAhPSBudWxsICYmIGV4dGVybmFsRW50aXR5LmVudGl0eUxvY2F0aW9uLmdldEV4cGFuZGVkU3lzdGVtSWQoKSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBiYXNlU3lzdGVtSWQgPSBleHRlcm5hbEVudGl0eS5lbnRpdHlMb2NhdGlvbi5nZXRFeHBhbmRlZFN5c3RlbUlkKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIEVudGl0eSBlbnRpdHkgPSBuZXcgRW50aXR5LkV4dGVybmFsRW50aXR5KG5hbWUsCi0gICAgICAgICAgICAgICAgICAgIG5ldyBYTUxFbnRpdHlEZXNjcmlwdGlvbkltcGwobmFtZSwgcHVibGljSWQsIGxpdGVyYWxTeXN0ZW1JZCwgYmFzZVN5c3RlbUlkLAotICAgICAgICAgICAgICAgICAgICBleHBhbmRTeXN0ZW1JZChsaXRlcmFsU3lzdGVtSWQsIGJhc2VTeXN0ZW1JZCwgZmFsc2UpKSwgbnVsbCwgZkluRXh0ZXJuYWxTdWJzZXQpOwotICAgICAgICAgICAgZkVudGl0aWVzLnB1dChuYW1lLCBlbnRpdHkpOwotICAgICAgICB9IGVsc2V7Ci0gICAgICAgICAgICBpZihmV2FybkR1cGxpY2F0ZUVudGl0eURlZil7Ci0gICAgICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgIk1TR19EVVBMSUNBVEVfRU5USVRZX0RFRklOSVRJT04iLAotICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdeyBuYW1lIH0sCi0gICAgICAgICAgICAgICAgICAgICAgICBYTUxFcnJvclJlcG9ydGVyLlNFVkVSSVRZX1dBUk5JTkcgKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgfSAvLyBhZGRFeHRlcm5hbEVudGl0eShTdHJpbmcsU3RyaW5nLFN0cmluZyxTdHJpbmcpCi0KLQotICAgIC8qKgotICAgICAqIEFkZHMgYW4gdW5wYXJzZWQgZW50aXR5IGRlY2xhcmF0aW9uLgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gVGhpcyBtZXRob2QgaWdub3JlcyBzdWJzZXF1ZW50IGVudGl0eQotICAgICAqIGRlY2xhcmF0aW9ucy4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoZSBuYW1lIHNob3VsZCBiZSBhIHVuaXF1ZSBzeW1ib2wuIFRoZQotICAgICAqIFN5bWJvbFRhYmxlIGNhbiBiZSB1c2VkIGZvciB0aGlzIHB1cnBvc2UuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSAgICAgVGhlIG5hbWUgb2YgdGhlIGVudGl0eS4KLSAgICAgKiBAcGFyYW0gcHVibGljSWQgVGhlIHB1YmxpYyBpZGVudGlmaWVyIG9mIHRoZSBlbnRpdHkuCi0gICAgICogQHBhcmFtIHN5c3RlbUlkIFRoZSBzeXN0ZW0gaWRlbnRpZmllciBvZiB0aGUgZW50aXR5LgotICAgICAqIEBwYXJhbSBub3RhdGlvbiBUaGUgbmFtZSBvZiB0aGUgbm90YXRpb24uCi0gICAgICoKLSAgICAgKiBAc2VlIFN5bWJvbFRhYmxlCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgYWRkVW5wYXJzZWRFbnRpdHkoU3RyaW5nIG5hbWUsCi0gICAgICAgICAgICBTdHJpbmcgcHVibGljSWQsIFN0cmluZyBzeXN0ZW1JZCwKLSAgICAgICAgICAgIFN0cmluZyBiYXNlU3lzdGVtSWQsIFN0cmluZyBub3RhdGlvbikgewotICAgICAgICBpZiAoIWZFbnRpdGllcy5jb250YWluc0tleShuYW1lKSkgewotICAgICAgICAgICAgRW50aXR5LkV4dGVybmFsRW50aXR5IGVudGl0eSA9IG5ldyBFbnRpdHkuRXh0ZXJuYWxFbnRpdHkobmFtZSwKLSAgICAgICAgICAgICAgICAgICAgbmV3IFhNTEVudGl0eURlc2NyaXB0aW9uSW1wbChuYW1lLCBwdWJsaWNJZCwgc3lzdGVtSWQsIGJhc2VTeXN0ZW1JZCwgbnVsbCksCi0gICAgICAgICAgICAgICAgICAgIG5vdGF0aW9uLCBmSW5FeHRlcm5hbFN1YnNldCk7Ci0gICAgICAgICAgICBmRW50aXRpZXMucHV0KG5hbWUsIGVudGl0eSk7Ci0gICAgICAgIH0gZWxzZXsKLSAgICAgICAgICAgIGlmKGZXYXJuRHVwbGljYXRlRW50aXR5RGVmKXsKLSAgICAgICAgICAgICAgICBmRXJyb3JSZXBvcnRlci5yZXBvcnRFcnJvcihYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAiTVNHX0RVUExJQ0FURV9FTlRJVFlfREVGSU5JVElPTiIsCi0gICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117IG5hbWUgfSwKLSAgICAgICAgICAgICAgICAgICAgICAgIFhNTEVycm9yUmVwb3J0ZXIuU0VWRVJJVFlfV0FSTklORyApOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfSAvLyBhZGRVbnBhcnNlZEVudGl0eShTdHJpbmcsU3RyaW5nLFN0cmluZyxTdHJpbmcpCi0KLQotICAgIC8qKiBnZXQgdGhlIGVudGl0eSBzdG9yYWdlIG9iamVjdCBmcm9tIGVudGl0eSBtYW5hZ2VyICovCi0gICAgcHVibGljIFhNTEVudGl0eVN0b3JhZ2UgZ2V0RW50aXR5U3RvcmUoKXsKLSAgICAgICAgcmV0dXJuIGZFbnRpdHlTdG9yYWdlIDsKLSAgICB9Ci0KLSAgICAvKiogcmV0dXJuIHRoZSBlbnRpdHkgcmVzcG9uc2libGUgZm9yIHJlYWRpbmcgdGhlIGVudGl0eSAqLwotICAgIHB1YmxpYyBYTUxFbnRpdHlTY2FubmVyIGdldEVudGl0eVNjYW5uZXIoKXsKLSAgICAgICAgaWYoZkVudGl0eVNjYW5uZXIgPT0gbnVsbCkgewotICAgICAgICAgICAgLy8gZGVmYXVsdCB0byAxLjAKLSAgICAgICAgICAgIGlmKGZYTUwxMEVudGl0eVNjYW5uZXIgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZYTUwxMEVudGl0eVNjYW5uZXIgPSBuZXcgWE1MRW50aXR5U2Nhbm5lcigpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZlhNTDEwRW50aXR5U2Nhbm5lci5yZXNldChmU3ltYm9sVGFibGUsIHRoaXMsIGZFcnJvclJlcG9ydGVyKTsKLSAgICAgICAgICAgIGZFbnRpdHlTY2FubmVyID0gZlhNTDEwRW50aXR5U2Nhbm5lcjsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZkVudGl0eVNjYW5uZXI7Ci0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRTY2FubmVyVmVyc2lvbihzaG9ydCB2ZXJzaW9uKSB7Ci0KLSAgICAgICAgaWYodmVyc2lvbiA9PSBDb25zdGFudHMuWE1MX1ZFUlNJT05fMV8wKSB7Ci0gICAgICAgICAgICBpZihmWE1MMTBFbnRpdHlTY2FubmVyID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmWE1MMTBFbnRpdHlTY2FubmVyID0gbmV3IFhNTEVudGl0eVNjYW5uZXIoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGZYTUwxMEVudGl0eVNjYW5uZXIucmVzZXQoZlN5bWJvbFRhYmxlLCB0aGlzLCBmRXJyb3JSZXBvcnRlcik7Ci0gICAgICAgICAgICBmRW50aXR5U2Nhbm5lciA9IGZYTUwxMEVudGl0eVNjYW5uZXI7Ci0gICAgICAgICAgICBmRW50aXR5U2Nhbm5lci5zZXRDdXJyZW50RW50aXR5KGZDdXJyZW50RW50aXR5KTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIGlmKGZYTUwxMUVudGl0eVNjYW5uZXIgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZYTUwxMUVudGl0eVNjYW5uZXIgPSBuZXcgWE1MMTFFbnRpdHlTY2FubmVyKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmWE1MMTFFbnRpdHlTY2FubmVyLnJlc2V0KGZTeW1ib2xUYWJsZSwgdGhpcywgZkVycm9yUmVwb3J0ZXIpOwotICAgICAgICAgICAgZkVudGl0eVNjYW5uZXIgPSBmWE1MMTFFbnRpdHlTY2FubmVyOwotICAgICAgICAgICAgZkVudGl0eVNjYW5uZXIuc2V0Q3VycmVudEVudGl0eShmQ3VycmVudEVudGl0eSk7Ci0gICAgICAgIH0KLQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIHVzZXMgdGhlIHBhc3NlZC1pbiBYTUxJbnB1dFNvdXJjZSB0byBtYWtlCi0gICAgICogZkN1cnJlbnRFbnRpdHkgdXNhYmxlIGZvciByZWFkaW5nLgotICAgICAqCi0gICAgICogQHBhcmFtIHJlZmVyZW5jZSBmbGFnIHRvIGluZGljYXRlIHdoZXRoZXIgdGhlIGVudGl0eSBpcyBhbiBFbnRpdHkgUmVmZXJlbmNlLgotICAgICAqIEBwYXJhbSBuYW1lICBuYW1lIG9mIHRoZSBlbnRpdHkgKFhNTCBpcyBpdCdzIHRoZSBkb2N1bWVudCBlbnRpdHkpCi0gICAgICogQHBhcmFtIHhtbElucHV0U291cmNlICAgIHRoZSBpbnB1dCBzb3VyY2UsIHdpdGggc3VmZmljaWVudCBpbmZvcm1hdGlvbgotICAgICAqICAgICAgdG8gYmVnaW4gc2Nhbm5pbmcgY2hhcmFjdGVycy4KLSAgICAgKiBAcGFyYW0gbGl0ZXJhbCAgICAgICAgVHJ1ZSBpZiB0aGlzIGVudGl0eSBpcyBzdGFydGVkIHdpdGhpbiBhCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgIGxpdGVyYWwgdmFsdWUuCi0gICAgICogQHBhcmFtIGlzRXh0ZXJuYWwgICAgd2hldGhlciB0aGlzIGVudGl0eSBzaG91bGQgYmUgdHJlYXRlZCBhcyBhbiBpbnRlcm5hbCBvciBleHRlcm5hbCBlbnRpdHkuCi0gICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiAgaWYgYW55dGhpbmcgY2FuJ3QgYmUgcmVhZAotICAgICAqICBYTklFeGNlcHRpb24gICAgSWYgYW55IHBhcnNlci1zcGVjaWZpYyBnb2VzIHdyb25nLgotICAgICAqIEByZXR1cm4gdGhlIGVuY29kaW5nIG9mIHRoZSBuZXcgZW50aXR5IG9yIG51bGwgaWYgYSBjaGFyYWN0ZXIgc3RyZWFtIHdhcyBlbXBsb3llZAotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgc2V0dXBDdXJyZW50RW50aXR5KGJvb2xlYW4gcmVmZXJlbmNlLCBTdHJpbmcgbmFtZSwgWE1MSW5wdXRTb3VyY2UgeG1sSW5wdXRTb3VyY2UsCi0gICAgICAgICAgICBib29sZWFuIGxpdGVyYWwsIGJvb2xlYW4gaXNFeHRlcm5hbCkKLSAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgLy8gZ2V0IGluZm9ybWF0aW9uCi0KLSAgICAgICAgZmluYWwgU3RyaW5nIHB1YmxpY0lkID0geG1sSW5wdXRTb3VyY2UuZ2V0UHVibGljSWQoKTsKLSAgICAgICAgU3RyaW5nIGxpdGVyYWxTeXN0ZW1JZCA9IHhtbElucHV0U291cmNlLmdldFN5c3RlbUlkKCk7Ci0gICAgICAgIFN0cmluZyBiYXNlU3lzdGVtSWQgPSB4bWxJbnB1dFNvdXJjZS5nZXRCYXNlU3lzdGVtSWQoKTsKLSAgICAgICAgU3RyaW5nIGVuY29kaW5nID0geG1sSW5wdXRTb3VyY2UuZ2V0RW5jb2RpbmcoKTsKLSAgICAgICAgZmluYWwgYm9vbGVhbiBlbmNvZGluZ0V4dGVybmFsbHlTcGVjaWZpZWQgPSAoZW5jb2RpbmcgIT0gbnVsbCk7Ci0gICAgICAgIEJvb2xlYW4gaXNCaWdFbmRpYW4gPSBudWxsOwotCi0gICAgICAgIC8vIGNyZWF0ZSByZWFkZXIKLSAgICAgICAgSW5wdXRTdHJlYW0gc3RyZWFtID0gbnVsbDsKLSAgICAgICAgUmVhZGVyIHJlYWRlciA9IHhtbElucHV0U291cmNlLmdldENoYXJhY3RlclN0cmVhbSgpOwotCi0gICAgICAgIC8vIEZpcnN0IGNoYW5jZSBjaGVja2luZyBzdHJpY3QgVVJJCi0gICAgICAgIFN0cmluZyBleHBhbmRlZFN5c3RlbUlkID0gZXhwYW5kU3lzdGVtSWQobGl0ZXJhbFN5c3RlbUlkLCBiYXNlU3lzdGVtSWQsIGZTdHJpY3RVUkkpOwotICAgICAgICBpZiAoYmFzZVN5c3RlbUlkID09IG51bGwpIHsKLSAgICAgICAgICAgIGJhc2VTeXN0ZW1JZCA9IGV4cGFuZGVkU3lzdGVtSWQ7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKHJlYWRlciA9PSBudWxsKSB7Ci0gICAgICAgICAgICBzdHJlYW0gPSB4bWxJbnB1dFNvdXJjZS5nZXRCeXRlU3RyZWFtKCk7Ci0gICAgICAgICAgICBpZiAoc3RyZWFtID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBVUkwgbG9jYXRpb24gPSBuZXcgVVJMKGV4cGFuZGVkU3lzdGVtSWQpOwotICAgICAgICAgICAgICAgIFVSTENvbm5lY3Rpb24gY29ubmVjdCA9IGxvY2F0aW9uLm9wZW5Db25uZWN0aW9uKCk7Ci0gICAgICAgICAgICAgICAgaWYgKCEoY29ubmVjdCBpbnN0YW5jZW9mIEh0dHBVUkxDb25uZWN0aW9uKSkgewotICAgICAgICAgICAgICAgICAgICBzdHJlYW0gPSBjb25uZWN0LmdldElucHV0U3RyZWFtKCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICBib29sZWFuIGZvbGxvd1JlZGlyZWN0cyA9IHRydWU7Ci0KLSAgICAgICAgICAgICAgICAgICAgLy8gc2V0dXAgVVJMQ29ubmVjdGlvbiBpZiB3ZSBoYXZlIGFuIEhUVFBJbnB1dFNvdXJjZQotICAgICAgICAgICAgICAgICAgICBpZiAoeG1sSW5wdXRTb3VyY2UgaW5zdGFuY2VvZiBIVFRQSW5wdXRTb3VyY2UpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIEh0dHBVUkxDb25uZWN0aW9uIHVybENvbm5lY3Rpb24gPSAoSHR0cFVSTENvbm5lY3Rpb24pIGNvbm5lY3Q7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBIVFRQSW5wdXRTb3VyY2UgaHR0cElucHV0U291cmNlID0gKEhUVFBJbnB1dFNvdXJjZSkgeG1sSW5wdXRTb3VyY2U7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNldCByZXF1ZXN0IHByb3BlcnRpZXMKLSAgICAgICAgICAgICAgICAgICAgICAgIEl0ZXJhdG9yPE1hcC5FbnRyeTxTdHJpbmcsIFN0cmluZz4+IHByb3BJdGVyID0gaHR0cElucHV0U291cmNlLmdldEhUVFBSZXF1ZXN0UHJvcGVydGllcygpOwotICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHByb3BJdGVyLmhhc05leHQoKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hcC5FbnRyeTxTdHJpbmcsIFN0cmluZz4gZW50cnkgPSBwcm9wSXRlci5uZXh0KCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgdXJsQ29ubmVjdGlvbi5zZXRSZXF1ZXN0UHJvcGVydHkoZW50cnkuZ2V0S2V5KCksIGVudHJ5LmdldFZhbHVlKCkpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBzZXQgcHJlZmVyZW5jZSBmb3IgcmVkaXJlY3Rpb24KLSAgICAgICAgICAgICAgICAgICAgICAgIGZvbGxvd1JlZGlyZWN0cyA9IGh0dHBJbnB1dFNvdXJjZS5nZXRGb2xsb3dIVFRQUmVkaXJlY3RzKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWZvbGxvd1JlZGlyZWN0cykgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldEluc3RhbmNlRm9sbG93UmVkaXJlY3RzKHVybENvbm5lY3Rpb24sIGZvbGxvd1JlZGlyZWN0cyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICBzdHJlYW0gPSBjb25uZWN0LmdldElucHV0U3RyZWFtKCk7Ci0KLSAgICAgICAgICAgICAgICAgICAgLy8gUkVWSVNJVDogSWYgdGhlIFVSTENvbm5lY3Rpb24gaGFzIGV4dGVybmFsIGVuY29kaW5nCi0gICAgICAgICAgICAgICAgICAgIC8vIGluZm9ybWF0aW9uLCB3ZSBzaG91bGQgYmUgcmVhZGluZyBpdCBoZXJlLiBJdCdzIGxvY2F0ZWQKLSAgICAgICAgICAgICAgICAgICAgLy8gaW4gdGhlIGNoYXJzZXQgcGFyYW1ldGVyIG9mIENvbnRlbnQtVHlwZS4gLS0gbXJnbGF2YXMKLQotICAgICAgICAgICAgICAgICAgICBpZiAoZm9sbG93UmVkaXJlY3RzKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcmVkaXJlY3QgPSBjb25uZWN0LmdldFVSTCgpLnRvU3RyaW5nKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBFNDM6IENoZWNrIGlmIHRoZSBVUkwgd2FzIHJlZGlyZWN0ZWQsIGFuZCB0aGVuCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyB1cGRhdGUgbGl0ZXJhbCBhbmQgZXhwYW5kZWQgc3lzdGVtIElEcyBpZiBuZWVkZWQuCi0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXJlZGlyZWN0LmVxdWFscyhleHBhbmRlZFN5c3RlbUlkKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpdGVyYWxTeXN0ZW1JZCA9IHJlZGlyZWN0OwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cGFuZGVkU3lzdGVtSWQgPSByZWRpcmVjdDsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gd3JhcCB0aGlzIHN0cmVhbSBpbiBSZXdpbmRhYmxlSW5wdXRTdHJlYW0KLSAgICAgICAgICAgIHN0cmVhbSA9IG5ldyBSZXdpbmRhYmxlSW5wdXRTdHJlYW0oc3RyZWFtKTsKLQotICAgICAgICAgICAgLy8gcGVyZm9ybSBhdXRvLWRldGVjdCBvZiBlbmNvZGluZyBpZiBuZWNlc3NhcnkKLSAgICAgICAgICAgIGlmIChlbmNvZGluZyA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgLy8gcmVhZCBmaXJzdCBmb3VyIGJ5dGVzIGFuZCBkZXRlcm1pbmUgZW5jb2RpbmcKLSAgICAgICAgICAgICAgICBmaW5hbCBieXRlW10gYjQgPSBuZXcgYnl0ZVs0XTsKLSAgICAgICAgICAgICAgICBpbnQgY291bnQgPSAwOwotICAgICAgICAgICAgICAgIGZvciAoOyBjb3VudDw0OyBjb3VudCsrICkgewotICAgICAgICAgICAgICAgICAgICBiNFtjb3VudF0gPSAoYnl0ZSlzdHJlYW0ucmVhZCgpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpZiAoY291bnQgPT0gNCkgewotICAgICAgICAgICAgICAgICAgICBPYmplY3QgW10gZW5jb2RpbmdEZXNjID0gZ2V0RW5jb2RpbmdOYW1lKGI0LCBjb3VudCk7Ci0gICAgICAgICAgICAgICAgICAgIGVuY29kaW5nID0gKFN0cmluZykoZW5jb2RpbmdEZXNjWzBdKTsKLSAgICAgICAgICAgICAgICAgICAgaXNCaWdFbmRpYW4gPSAoQm9vbGVhbikoZW5jb2RpbmdEZXNjWzFdKTsKLQotICAgICAgICAgICAgICAgICAgICBzdHJlYW0ucmVzZXQoKTsKLSAgICAgICAgICAgICAgICAgICAgLy8gU3BlY2lhbCBjYXNlIFVURi04IGZpbGVzIHdpdGggQk9NIGNyZWF0ZWQgYnkgTWljcm9zb2Z0Ci0gICAgICAgICAgICAgICAgICAgIC8vIHRvb2xzLiBJdCdzIG1vcmUgZWZmaWNpZW50IHRvIGNvbnN1bWUgdGhlIEJPTSB0aGFuIG1ha2UKLSAgICAgICAgICAgICAgICAgICAgLy8gdGhlIHJlYWRlciBwZXJmb3JtIGV4dHJhIGNoZWNrcy4gLUFjCi0gICAgICAgICAgICAgICAgICAgIGlmIChjb3VudCA+IDIgJiYgZW5jb2RpbmcuZXF1YWxzKCJVVEYtOCIpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpbnQgYjAgPSBiNFswXSAmIDB4RkY7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpbnQgYjEgPSBiNFsxXSAmIDB4RkY7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpbnQgYjIgPSBiNFsyXSAmIDB4RkY7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYjAgPT0gMHhFRiAmJiBiMSA9PSAweEJCICYmIGIyID09IDB4QkYpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpZ25vcmUgZmlyc3QgdGhyZWUgYnl0ZXMuLi4KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW0uc2tpcCgzKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICByZWFkZXIgPSBjcmVhdGVSZWFkZXIoc3RyZWFtLCBlbmNvZGluZywgaXNCaWdFbmRpYW4pOwotICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIHJlYWRlciA9IGNyZWF0ZVJlYWRlcihzdHJlYW0sIGVuY29kaW5nLCBpc0JpZ0VuZGlhbik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyB1c2Ugc3BlY2lmaWVkIGVuY29kaW5nCi0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBlbmNvZGluZyA9IGVuY29kaW5nLnRvVXBwZXJDYXNlKExvY2FsZS5FTkdMSVNIKTsKLQotICAgICAgICAgICAgICAgIC8vIElmIGVuY29kaW5nIGlzIFVURi04LCBjb25zdW1lIEJPTSBpZiBvbmUgaXMgcHJlc2VudC4KLSAgICAgICAgICAgICAgICBpZiAoZW5jb2RpbmcuZXF1YWxzKCJVVEYtOCIpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZpbmFsIGludFtdIGIzID0gbmV3IGludFszXTsKLSAgICAgICAgICAgICAgICAgICAgaW50IGNvdW50ID0gMDsKLSAgICAgICAgICAgICAgICAgICAgZm9yICg7IGNvdW50IDwgMzsgKytjb3VudCkgewotICAgICAgICAgICAgICAgICAgICAgICAgYjNbY291bnRdID0gc3RyZWFtLnJlYWQoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChiM1tjb3VudF0gPT0gLTEpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgaWYgKGNvdW50ID09IDMpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChiM1swXSAhPSAweEVGIHx8IGIzWzFdICE9IDB4QkIgfHwgYjNbMl0gIT0gMHhCRikgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEZpcnN0IHRocmVlIGJ5dGVzIGFyZSBub3QgQk9NLCBzbyByZXNldC4KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW0ucmVzZXQoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbS5yZXNldCgpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIC8vIElmIGVuY29kaW5nIGlzIFVURi0xNiwgd2Ugc3RpbGwgbmVlZCB0byByZWFkIHRoZSBmaXJzdCBmb3VyIGJ5dGVzCi0gICAgICAgICAgICAgICAgLy8gaW4gb3JkZXIgdG8gZGlzY292ZXIgdGhlIGJ5dGUgb3JkZXIuCi0gICAgICAgICAgICAgICAgZWxzZSBpZiAoZW5jb2RpbmcuZXF1YWxzKCJVVEYtMTYiKSkgewotICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnRbXSBiNCA9IG5ldyBpbnRbNF07Ci0gICAgICAgICAgICAgICAgICAgIGludCBjb3VudCA9IDA7Ci0gICAgICAgICAgICAgICAgICAgIGZvciAoOyBjb3VudCA8IDQ7ICsrY291bnQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGI0W2NvdW50XSA9IHN0cmVhbS5yZWFkKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYjRbY291bnRdID09IC0xKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIHN0cmVhbS5yZXNldCgpOwotCi0gICAgICAgICAgICAgICAgICAgIFN0cmluZyB1dGYxNkVuY29kaW5nID0gIlVURi0xNiI7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChjb3VudCA+PSAyKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgYjAgPSBiNFswXTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCBiMSA9IGI0WzFdOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGIwID09IDB4RkUgJiYgYjEgPT0gMHhGRikgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFVURi0xNiwgYmlnLWVuZGlhbgotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHV0ZjE2RW5jb2RpbmcgPSAiVVRGLTE2QkUiOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzQmlnRW5kaWFuID0gQm9vbGVhbi5UUlVFOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoYjAgPT0gMHhGRiAmJiBiMSA9PSAweEZFKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVVRGLTE2LCBsaXR0bGUtZW5kaWFuCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgdXRmMTZFbmNvZGluZyA9ICJVVEYtMTZMRSI7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNCaWdFbmRpYW4gPSBCb29sZWFuLkZBTFNFOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoY291bnQgPT0gNCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCBiMiA9IGI0WzJdOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCBiMyA9IGI0WzNdOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChiMCA9PSAweDAwICYmIGIxID09IDB4M0MgJiYgYjIgPT0gMHgwMCAmJiBiMyA9PSAweDNGKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFVURi0xNiwgYmlnLWVuZGlhbiwgbm8gQk9NCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHV0ZjE2RW5jb2RpbmcgPSAiVVRGLTE2QkUiOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc0JpZ0VuZGlhbiA9IEJvb2xlYW4uVFJVRTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGIwID09IDB4M0MgJiYgYjEgPT0gMHgwMCAmJiBiMiA9PSAweDNGICYmIGIzID09IDB4MDApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVVRGLTE2LCBsaXR0bGUtZW5kaWFuLCBubyBCT00KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXRmMTZFbmNvZGluZyA9ICJVVEYtMTZMRSI7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzQmlnRW5kaWFuID0gQm9vbGVhbi5GQUxTRTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgcmVhZGVyID0gY3JlYXRlUmVhZGVyKHN0cmVhbSwgdXRmMTZFbmNvZGluZywgaXNCaWdFbmRpYW4pOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvLyBJZiBlbmNvZGluZyBpcyBVQ1MtNCwgd2Ugc3RpbGwgbmVlZCB0byByZWFkIHRoZSBmaXJzdCBmb3VyIGJ5dGVzCi0gICAgICAgICAgICAgICAgLy8gaW4gb3JkZXIgdG8gZGlzY292ZXIgdGhlIGJ5dGUgb3JkZXIuCi0gICAgICAgICAgICAgICAgZWxzZSBpZiAoZW5jb2RpbmcuZXF1YWxzKCJJU08tMTA2NDYtVUNTLTQiKSkgewotICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnRbXSBiNCA9IG5ldyBpbnRbNF07Ci0gICAgICAgICAgICAgICAgICAgIGludCBjb3VudCA9IDA7Ci0gICAgICAgICAgICAgICAgICAgIGZvciAoOyBjb3VudCA8IDQ7ICsrY291bnQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGI0W2NvdW50XSA9IHN0cmVhbS5yZWFkKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYjRbY291bnRdID09IC0xKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIHN0cmVhbS5yZXNldCgpOwotCi0gICAgICAgICAgICAgICAgICAgIC8vIElnbm9yZSB1bnVzdWFsIG9jdGV0IG9yZGVyIGZvciBub3cuCi0gICAgICAgICAgICAgICAgICAgIGlmIChjb3VudCA9PSA0KSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBVQ1MtNCwgYmlnIGVuZGlhbiAoMTIzNCkKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChiNFswXSA9PSAweDAwICYmIGI0WzFdID09IDB4MDAgJiYgYjRbMl0gPT0gMHgwMCAmJiBiNFszXSA9PSAweDNDKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNCaWdFbmRpYW4gPSBCb29sZWFuLlRSVUU7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBVQ1MtNCwgbGl0dGxlIGVuZGlhbiAoMTIzNCkKLSAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGI0WzBdID09IDB4M0MgJiYgYjRbMV0gPT0gMHgwMCAmJiBiNFsyXSA9PSAweDAwICYmIGI0WzNdID09IDB4MDApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc0JpZ0VuZGlhbiA9IEJvb2xlYW4uRkFMU0U7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLy8gSWYgZW5jb2RpbmcgaXMgVUNTLTIsIHdlIHN0aWxsIG5lZWQgdG8gcmVhZCB0aGUgZmlyc3QgZm91ciBieXRlcwotICAgICAgICAgICAgICAgIC8vIGluIG9yZGVyIHRvIGRpc2NvdmVyIHRoZSBieXRlIG9yZGVyLgotICAgICAgICAgICAgICAgIGVsc2UgaWYgKGVuY29kaW5nLmVxdWFscygiSVNPLTEwNjQ2LVVDUy0yIikpIHsKLSAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50W10gYjQgPSBuZXcgaW50WzRdOwotICAgICAgICAgICAgICAgICAgICBpbnQgY291bnQgPSAwOwotICAgICAgICAgICAgICAgICAgICBmb3IgKDsgY291bnQgPCA0OyArK2NvdW50KSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBiNFtjb3VudF0gPSBzdHJlYW0ucmVhZCgpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGI0W2NvdW50XSA9PSAtMSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBzdHJlYW0ucmVzZXQoKTsKLQotICAgICAgICAgICAgICAgICAgICBpZiAoY291bnQgPT0gNCkgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gVUNTLTIsIGJpZyBlbmRpYW4KLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChiNFswXSA9PSAweDAwICYmIGI0WzFdID09IDB4M0MgJiYgYjRbMl0gPT0gMHgwMCAmJiBiNFszXSA9PSAweDNGKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNCaWdFbmRpYW4gPSBCb29sZWFuLlRSVUU7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBVQ1MtMiwgbGl0dGxlIGVuZGlhbgotICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoYjRbMF0gPT0gMHgzQyAmJiBiNFsxXSA9PSAweDAwICYmIGI0WzJdID09IDB4M0YgJiYgYjRbM10gPT0gMHgwMCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzQmlnRW5kaWFuID0gQm9vbGVhbi5GQUxTRTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIHJlYWRlciA9IGNyZWF0ZVJlYWRlcihzdHJlYW0sIGVuY29kaW5nLCBpc0JpZ0VuZGlhbik7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIHJlYWQgb25lIGNoYXJhY3RlciBhdCBhIHRpbWUgc28gd2UgZG9uJ3QganVtcCB0b28gZmFyCi0gICAgICAgICAgICAvLyBhaGVhZCwgY29udmVydGluZyBjaGFyYWN0ZXJzIGZyb20gdGhlIGJ5dGUgc3RyZWFtIGluCi0gICAgICAgICAgICAvLyB0aGUgd3JvbmcgZW5jb2RpbmcKLSAgICAgICAgICAgIGlmIChERUJVR19FTkNPRElOR1MpIHsKLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIiQkJCBubyBsb25nZXIgd3JhcHBpbmcgcmVhZGVyIGluIE9uZUNoYXJSZWFkZXIiKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vcmVhZGVyID0gbmV3IE9uZUNoYXJSZWFkZXIocmVhZGVyKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIFdlJ3ZlIHNlZW4gYSBuZXcgUmVhZGVyLgotICAgICAgICAvLyBQdXNoIGl0IG9uIHRoZSBzdGFjayBzbyB3ZSBjYW4gY2xvc2UgaXQgbGF0ZXIuCi0gICAgICAgIC8vZk93blJlYWRlcnMuYWRkKHJlYWRlcik7Ci0KLSAgICAgICAgLy8gcHVzaCBlbnRpdHkgb24gc3RhY2sKLSAgICAgICAgaWYgKGZDdXJyZW50RW50aXR5ICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZFbnRpdHlTdGFjay5wdXNoKGZDdXJyZW50RW50aXR5KTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIGNyZWF0ZSBlbnRpdHkKLSAgICAgICAgLyogaWYgZW5jb2RpbmcgaXMgc3BlY2lmaWVkIGV4dGVybmFsbHksICdlbmNvZGluZycgaW5mb3JtYXRpb24gcHJlc2VudAotICAgICAgICAgKiBpbiB0aGUgcHJvbG9nIG9mIHRoZSBYTUwgZG9jdW1lbnQgaXMgbm90IGNvbnNpZGVyZWQuIEhlbmNlLCBwcm9sb2cgY2FuCi0gICAgICAgICAqIGJlIHJlYWQgaW4gQ2h1bmtzIG9mIGRhdGEgaW5zdGVhZCBvZiBieXRlIGJ5IGJ5dGUuCi0gICAgICAgICAqLwotICAgICAgICBmQ3VycmVudEVudGl0eSA9IG5ldyBFbnRpdHkuU2Nhbm5lZEVudGl0eShyZWZlcmVuY2UsIG5hbWUsCi0gICAgICAgICAgICAgICAgbmV3IFhNTFJlc291cmNlSWRlbnRpZmllckltcGwocHVibGljSWQsIGxpdGVyYWxTeXN0ZW1JZCwgYmFzZVN5c3RlbUlkLCBleHBhbmRlZFN5c3RlbUlkKSwKLSAgICAgICAgICAgICAgICBzdHJlYW0sIHJlYWRlciwgZW5jb2RpbmcsIGxpdGVyYWwsIGVuY29kaW5nRXh0ZXJuYWxseVNwZWNpZmllZCwgaXNFeHRlcm5hbCk7Ci0gICAgICAgIGZDdXJyZW50RW50aXR5LnNldEVuY29kaW5nRXh0ZXJuYWxseVNwZWNpZmllZChlbmNvZGluZ0V4dGVybmFsbHlTcGVjaWZpZWQpOwotICAgICAgICBmRW50aXR5U2Nhbm5lci5zZXRDdXJyZW50RW50aXR5KGZDdXJyZW50RW50aXR5KTsKLSAgICAgICAgZlJlc291cmNlSWRlbnRpZmllci5zZXRWYWx1ZXMocHVibGljSWQsIGxpdGVyYWxTeXN0ZW1JZCwgYmFzZVN5c3RlbUlkLCBleHBhbmRlZFN5c3RlbUlkKTsKLSAgICAgICAgaWYgKGZMaW1pdEFuYWx5emVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZMaW1pdEFuYWx5emVyLnN0YXJ0RW50aXR5KG5hbWUpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBlbmNvZGluZzsKLSAgICB9IC8vc2V0dXBDdXJyZW50RW50aXR5KFN0cmluZywgWE1MSW5wdXRTb3VyY2UsIGJvb2xlYW4sIGJvb2xlYW4pOiAgU3RyaW5nCi0KLQotICAgIC8qKgotICAgICAqIENoZWNrcyB3aGV0aGVyIGFuIGVudGl0eSBnaXZlbiBieSBuYW1lIGlzIGV4dGVybmFsLgotICAgICAqCi0gICAgICogQHBhcmFtIGVudGl0eU5hbWUgVGhlIG5hbWUgb2YgdGhlIGVudGl0eSB0byBjaGVjay4KLSAgICAgKiBAcmV0dXJuIFRydWUgaWYgdGhlIGVudGl0eSBpcyBleHRlcm5hbCwgZmFsc2Ugb3RoZXJ3aXNlCi0gICAgICogKGluY2x1ZGluZyB3aGVuIHRoZSBlbnRpdHkgaXMgbm90IGRlY2xhcmVkKS4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0V4dGVybmFsRW50aXR5KFN0cmluZyBlbnRpdHlOYW1lKSB7Ci0KLSAgICAgICAgRW50aXR5IGVudGl0eSA9IGZFbnRpdGllcy5nZXQoZW50aXR5TmFtZSk7Ci0gICAgICAgIGlmIChlbnRpdHkgPT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBlbnRpdHkuaXNFeHRlcm5hbCgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENoZWNrcyB3aGV0aGVyIHRoZSBkZWNsYXJhdGlvbiBvZiBhbiBlbnRpdHkgZ2l2ZW4gYnkgbmFtZSBpcwotICAgICAqIC8vIGluIHRoZSBleHRlcm5hbCBzdWJzZXQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZW50aXR5TmFtZSBUaGUgbmFtZSBvZiB0aGUgZW50aXR5IHRvIGNoZWNrLgotICAgICAqIEByZXR1cm4gVHJ1ZSBpZiB0aGUgZW50aXR5IHdhcyBkZWNsYXJlZCBpbiB0aGUgZXh0ZXJuYWwgc3Vic2V0LCBmYWxzZSBvdGhlcndpc2UKLSAgICAgKiAgICAgICAgICAgKGluY2x1ZGluZyB3aGVuIHRoZSBlbnRpdHkgaXMgbm90IGRlY2xhcmVkKS4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0VudGl0eURlY2xJbkV4dGVybmFsU3Vic2V0KFN0cmluZyBlbnRpdHlOYW1lKSB7Ci0KLSAgICAgICAgRW50aXR5IGVudGl0eSA9IGZFbnRpdGllcy5nZXQoZW50aXR5TmFtZSk7Ci0gICAgICAgIGlmIChlbnRpdHkgPT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBlbnRpdHkuaXNFbnRpdHlEZWNsSW5FeHRlcm5hbFN1YnNldCgpOwotICAgIH0KLQotCi0KLSAgICAvLwotICAgIC8vIFB1YmxpYyBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFNldHMgd2hldGhlciB0aGUgZG9jdW1lbnQgZW50aXR5IGlzIHN0YW5kYWxvbmUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc3RhbmRhbG9uZSBUcnVlIGlmIGRvY3VtZW50IGVudGl0eSBpcyBzdGFuZGFsb25lLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFN0YW5kYWxvbmUoYm9vbGVhbiBzdGFuZGFsb25lKSB7Ci0gICAgICAgIGZTdGFuZGFsb25lID0gc3RhbmRhbG9uZTsKLSAgICB9Ci0gICAgLy8gc2V0U3RhbmRhbG9uZShib29sZWFuKQotCi0gICAgLyoqIFJldHVybnMgdHJ1ZSBpZiB0aGUgZG9jdW1lbnQgZW50aXR5IGlzIHN0YW5kYWxvbmUuICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNTdGFuZGFsb25lKCkgewotICAgICAgICByZXR1cm4gZlN0YW5kYWxvbmU7Ci0gICAgfSAgLy9pc1N0YW5kYWxvbmUoKTpib29sZWFuCi0KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0RlY2xhcmVkRW50aXR5KFN0cmluZyBlbnRpdHlOYW1lKSB7Ci0KLSAgICAgICAgRW50aXR5IGVudGl0eSA9IGZFbnRpdGllcy5nZXQoZW50aXR5TmFtZSk7Ci0gICAgICAgIHJldHVybiBlbnRpdHkgIT0gbnVsbDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBpc1VucGFyc2VkRW50aXR5KFN0cmluZyBlbnRpdHlOYW1lKSB7Ci0KLSAgICAgICAgRW50aXR5IGVudGl0eSA9IGZFbnRpdGllcy5nZXQoZW50aXR5TmFtZSk7Ci0gICAgICAgIGlmIChlbnRpdHkgPT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBlbnRpdHkuaXNVbnBhcnNlZCgpOwotICAgIH0KLQotCi0KLSAgICAvLyB0aGlzIHNpbXBseSByZXR1cm5zIHRoZSBmUmVzb3VyY2VJZGVudGlmaWVyIG9iamVjdDsKLSAgICAvLyB0aGlzIHNob3VsZCBvbmx5IGJlIHVzZWQgd2l0aCBjYXV0aW9uIGJ5IGNhbGxlcnMgdGhhdAotICAgIC8vIGNhcmVmdWxseSBtYW5hZ2UgdGhlIGVudGl0eSBtYW5hZ2VyJ3MgYmVoYXZpb3VyLCBzbyB0aGF0Ci0gICAgLy8gdGhpcyBkb2Vzbid0IHJldHVybmluZyBtZWFuaW5nbGVzcyBvciBtaXNsZWFkaW5nIGRhdGEuCi0gICAgLy8gQHJldHVybiAgYSByZWZlcmVuY2UgdG8gdGhlIGN1cnJlbnQgZlJlc291cmNlSWRlbnRpZmllciBvYmplY3QKLSAgICBwdWJsaWMgWE1MUmVzb3VyY2VJZGVudGlmaWVyIGdldEN1cnJlbnRSZXNvdXJjZUlkZW50aWZpZXIoKSB7Ci0gICAgICAgIHJldHVybiBmUmVzb3VyY2VJZGVudGlmaWVyOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIGVudGl0eSBoYW5kbGVyLiBXaGVuIGFuIGVudGl0eSBzdGFydHMgYW5kIGVuZHMsIHRoZQotICAgICAqIGVudGl0eSBoYW5kbGVyIGlzIG5vdGlmaWVkIG9mIHRoZSBjaGFuZ2UuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZW50aXR5SGFuZGxlciBUaGUgbmV3IGVudGl0eSBoYW5kbGVyLgotICAgICAqLwotCi0gICAgcHVibGljIHZvaWQgc2V0RW50aXR5SGFuZGxlcihjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuWE1MRW50aXR5SGFuZGxlciBlbnRpdHlIYW5kbGVyKSB7Ci0gICAgICAgIGZFbnRpdHlIYW5kbGVyID0gKFhNTEVudGl0eUhhbmRsZXIpIGVudGl0eUhhbmRsZXI7Ci0gICAgfSAvLyBzZXRFbnRpdHlIYW5kbGVyKFhNTEVudGl0eUhhbmRsZXIpCi0KLSAgICAvL3RoaXMgZnVuY3Rpb24gcmV0dXJucyBTdGF4WE1MSW5wdXRTb3VyY2UKLSAgICBwdWJsaWMgU3RheFhNTElucHV0U291cmNlIHJlc29sdmVFbnRpdHlBc1BlclN0YXgoWE1MUmVzb3VyY2VJZGVudGlmaWVyIHJlc291cmNlSWRlbnRpZmllcikgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb257Ci0KLSAgICAgICAgaWYocmVzb3VyY2VJZGVudGlmaWVyID09IG51bGwgKSByZXR1cm4gbnVsbDsKLQotICAgICAgICBTdHJpbmcgcHVibGljSWQgPSByZXNvdXJjZUlkZW50aWZpZXIuZ2V0UHVibGljSWQoKTsKLSAgICAgICAgU3RyaW5nIGxpdGVyYWxTeXN0ZW1JZCA9IHJlc291cmNlSWRlbnRpZmllci5nZXRMaXRlcmFsU3lzdGVtSWQoKTsKLSAgICAgICAgU3RyaW5nIGJhc2VTeXN0ZW1JZCA9IHJlc291cmNlSWRlbnRpZmllci5nZXRCYXNlU3lzdGVtSWQoKTsKLSAgICAgICAgU3RyaW5nIGV4cGFuZGVkU3lzdGVtSWQgPSByZXNvdXJjZUlkZW50aWZpZXIuZ2V0RXhwYW5kZWRTeXN0ZW1JZCgpOwotICAgICAgICAvLyBpZiBubyBiYXNlIHN5c3RlbUlkIGdpdmVuLCBhc3N1bWUgdGhhdCBpdCdzIHJlbGF0aXZlCi0gICAgICAgIC8vIHRvIHRoZSBzeXN0ZW1JZCBvZiB0aGUgY3VycmVudCBzY2FubmVkIGVudGl0eQotICAgICAgICAvLyBTb21ldGltZXMgdGhlIHN5c3RlbSBpZCBpcyBub3QgKHByb3Blcmx5KSBleHBhbmRlZC4KLSAgICAgICAgLy8gV2UgbmVlZCB0byBleHBhbmQgdGhlIHN5c3RlbSBpZCBpZjoKLSAgICAgICAgLy8gYS4gdGhlIGV4cGFuZGVkIG9uZSB3YXMgbnVsbDsgb3IKLSAgICAgICAgLy8gYi4gdGhlIGJhc2Ugc3lzdGVtIGlkIHdhcyBudWxsLCBidXQgYmVjb21lcyBub24tbnVsbCBmcm9tIHRoZSBjdXJyZW50IGVudGl0eS4KLSAgICAgICAgYm9vbGVhbiBuZWVkRXhwYW5kID0gKGV4cGFuZGVkU3lzdGVtSWQgPT0gbnVsbCk7Ci0gICAgICAgIC8vIFJFVklTSVQ6ICB3aHkgd291bGQgdGhlIGJhc2VTeXN0ZW1JZCBldmVyIGJlIG51bGw/ICBpZiB3ZQotICAgICAgICAvLyBkaWRuJ3QgaGF2ZSB0byBtYWtlIHRoaXMgY2hlY2sgd2Ugd291bGRuJ3QgaGF2ZSB0byByZXVzZSB0aGUKLSAgICAgICAgLy8gZlhNTFJlc291cmNlSWRlbnRpZmllciBvYmplY3QuLi4KLSAgICAgICAgaWYgKGJhc2VTeXN0ZW1JZCA9PSBudWxsICYmIGZDdXJyZW50RW50aXR5ICE9IG51bGwgJiYgZkN1cnJlbnRFbnRpdHkuZW50aXR5TG9jYXRpb24gIT0gbnVsbCkgewotICAgICAgICAgICAgYmFzZVN5c3RlbUlkID0gZkN1cnJlbnRFbnRpdHkuZW50aXR5TG9jYXRpb24uZ2V0RXhwYW5kZWRTeXN0ZW1JZCgpOwotICAgICAgICAgICAgaWYgKGJhc2VTeXN0ZW1JZCAhPSBudWxsKQotICAgICAgICAgICAgICAgIG5lZWRFeHBhbmQgPSB0cnVlOwotICAgICAgICB9Ci0gICAgICAgIGlmIChuZWVkRXhwYW5kKQotICAgICAgICAgICAgZXhwYW5kZWRTeXN0ZW1JZCA9IGV4cGFuZFN5c3RlbUlkKGxpdGVyYWxTeXN0ZW1JZCwgYmFzZVN5c3RlbUlkLGZhbHNlKTsKLQotICAgICAgICAvLyBnaXZlIHRoZSBlbnRpdHkgcmVzb2x2ZXIgYSBjaGFuY2UKLSAgICAgICAgU3RheFhNTElucHV0U291cmNlIHN0YXhJbnB1dFNvdXJjZSA9IG51bGw7Ci0gICAgICAgIFhNTElucHV0U291cmNlIHhtbElucHV0U291cmNlID0gbnVsbDsKLQotICAgICAgICBYTUxSZXNvdXJjZUlkZW50aWZpZXJJbXBsIHJpID0gbnVsbDsKLQotICAgICAgICBpZiAocmVzb3VyY2VJZGVudGlmaWVyIGluc3RhbmNlb2YgWE1MUmVzb3VyY2VJZGVudGlmaWVySW1wbCkgewotICAgICAgICAgICAgcmkgPSAoWE1MUmVzb3VyY2VJZGVudGlmaWVySW1wbClyZXNvdXJjZUlkZW50aWZpZXI7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBmUmVzb3VyY2VJZGVudGlmaWVyLmNsZWFyKCk7Ci0gICAgICAgICAgICByaSA9IGZSZXNvdXJjZUlkZW50aWZpZXI7Ci0gICAgICAgIH0KLSAgICAgICAgcmkuc2V0VmFsdWVzKHB1YmxpY0lkLCBsaXRlcmFsU3lzdGVtSWQsIGJhc2VTeXN0ZW1JZCwgZXhwYW5kZWRTeXN0ZW1JZCk7Ci0gICAgICAgIGlmKERFQlVHX1JFU09MVkVSKXsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiQkVGT1JFIENhbGxpbmcgcmVzb2x2ZUVudGl0eSIpIDsKLSAgICAgICAgfQotCi0gICAgICAgIGZJU0NyZWF0ZWRCeVJlc29sdmVyID0gZmFsc2U7Ci0gICAgICAgIC8vZWl0aGVyIG9mIFN0YXggb3IgWGVyY2VzIHdvdWxkIGJlIG51bGwKLSAgICAgICAgaWYoZlN0YXhFbnRpdHlSZXNvbHZlciAhPSBudWxsKXsKLSAgICAgICAgICAgIHN0YXhJbnB1dFNvdXJjZSA9IGZTdGF4RW50aXR5UmVzb2x2ZXIucmVzb2x2ZUVudGl0eShyaSk7Ci0gICAgICAgICAgICBpZihzdGF4SW5wdXRTb3VyY2UgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZJU0NyZWF0ZWRCeVJlc29sdmVyID0gdHJ1ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGlmKGZFbnRpdHlSZXNvbHZlciAhPSBudWxsKXsKLSAgICAgICAgICAgIHhtbElucHV0U291cmNlID0gZkVudGl0eVJlc29sdmVyLnJlc29sdmVFbnRpdHkocmkpOwotICAgICAgICAgICAgaWYoeG1sSW5wdXRTb3VyY2UgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZJU0NyZWF0ZWRCeVJlc29sdmVyID0gdHJ1ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGlmKHhtbElucHV0U291cmNlICE9IG51bGwpewotICAgICAgICAgICAgLy93cmFwIHRoaXMgWE1MSW5wdXRTb3VyY2UgdG8gU3RheElucHV0U291cmNlCi0gICAgICAgICAgICBzdGF4SW5wdXRTb3VyY2UgPSBuZXcgU3RheFhNTElucHV0U291cmNlKHhtbElucHV0U291cmNlLCBmSVNDcmVhdGVkQnlSZXNvbHZlcik7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBkbyBkZWZhdWx0IHJlc29sdXRpb24KLSAgICAgICAgLy90aGlzIHdvcmtzIGZvciBib3RoIHN0YXggJiBYZXJjZXMsIGlmIHN0YXhJbnB1dFNvdXJjZSBpcyBudWxsLCBpdCBtZWFucyBwYXJzZXIgbmVlZCB0byByZXZlcnQgdG8gZGVmYXVsdCByZXNvbHV0aW9uCi0gICAgICAgIGlmIChzdGF4SW5wdXRTb3VyY2UgPT0gbnVsbCkgewotICAgICAgICAgICAgLy8gUkVWSVNJVDogd2hlbiBzeXN0ZW1JZCBpcyBudWxsLCBJIHRoaW5rIHdlIHNob3VsZCByZXR1cm4gbnVsbC4KLSAgICAgICAgICAgIC8vICAgICAgICAgIGlzIHRoaXMgdGhlIHJpZ2h0IHNvbHV0aW9uPyAtU0cKLSAgICAgICAgICAgIC8vaWYgKHN5c3RlbUlkICE9IG51bGwpCi0gICAgICAgICAgICBzdGF4SW5wdXRTb3VyY2UgPSBuZXcgU3RheFhNTElucHV0U291cmNlKG5ldyBYTUxJbnB1dFNvdXJjZShwdWJsaWNJZCwgbGl0ZXJhbFN5c3RlbUlkLCBiYXNlU3lzdGVtSWQpKTsKLSAgICAgICAgfWVsc2UgaWYoc3RheElucHV0U291cmNlLmhhc1hNTFN0cmVhbU9yWE1MRXZlbnRSZWFkZXIoKSl7Ci0gICAgICAgICAgICAvL1dhaXRpbmcgZm9yIHRoZSBjbGFyaWZpY2F0aW9uIGZyb20gRUcuIC0gbmIKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChERUJVR19SRVNPTFZFUikgewotICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJYTUxFbnRpdHlNYW5hZ2VyLnJlc29sdmVFbnRpdHkoIiArIHB1YmxpY0lkICsgIikiKTsKLSAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiID0gIiArIHhtbElucHV0U291cmNlKTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBzdGF4SW5wdXRTb3VyY2U7Ci0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXNvbHZlcyB0aGUgc3BlY2lmaWVkIHB1YmxpYyBhbmQgc3lzdGVtIGlkZW50aWZpZXJzLiBUaGlzCi0gICAgICogbWV0aG9kIGZpcnN0IGF0dGVtcHRzIHRvIHJlc29sdmUgdGhlIGVudGl0eSBiYXNlZCBvbiB0aGUKLSAgICAgKiBFbnRpdHlSZXNvbHZlciByZWdpc3RlcmVkIGJ5IHRoZSBhcHBsaWNhdGlvbi4gSWYgbm8gZW50aXR5Ci0gICAgICogcmVzb2x2ZXIgaXMgcmVnaXN0ZXJlZCBvciBpZiB0aGUgcmVnaXN0ZXJlZCBlbnRpdHkgaGFuZGxlcgotICAgICAqIGlzIHVuYWJsZSB0byByZXNvbHZlIHRoZSBlbnRpdHksIHRoZW4gZGVmYXVsdCBlbnRpdHkKLSAgICAgKiByZXNvbHV0aW9uIHdpbGwgb2NjdXIuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcHVibGljSWQgICAgIFRoZSBwdWJsaWMgaWRlbnRpZmllciBvZiB0aGUgZW50aXR5LgotICAgICAqIEBwYXJhbSBzeXN0ZW1JZCAgICAgVGhlIHN5c3RlbSBpZGVudGlmaWVyIG9mIHRoZSBlbnRpdHkuCi0gICAgICogQHBhcmFtIGJhc2VTeXN0ZW1JZCBUaGUgYmFzZSBzeXN0ZW0gaWRlbnRpZmllciBvZiB0aGUgZW50aXR5LgotICAgICAqICAgICAgICAgICAgICAgICAgICAgVGhpcyBpcyB0aGUgc3lzdGVtIGlkZW50aWZpZXIgb2YgdGhlIGN1cnJlbnQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgIGVudGl0eSBhbmQgaXMgdXNlZCB0byBleHBhbmQgdGhlIHN5c3RlbQotICAgICAqICAgICAgICAgICAgICAgICAgICAgaWRlbnRpZmllciB3aGVuIHRoZSBzeXN0ZW0gaWRlbnRpZmllciBpcyBhCi0gICAgICogICAgICAgICAgICAgICAgICAgICByZWxhdGl2ZSBVUkkuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFJldHVybnMgYW4gaW5wdXQgc291cmNlIHRoYXQgd3JhcHMgdGhlIHJlc29sdmVkIGVudGl0eS4KLSAgICAgKiAgICAgICAgIFRoaXMgbWV0aG9kIHdpbGwgbmV2ZXIgcmV0dXJuIG51bGwuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uICBUaHJvd24gb24gaS9vIGVycm9yLgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBlbnRpdHkgcmVzb2x2ZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyBYTUxJbnB1dFNvdXJjZSByZXNvbHZlRW50aXR5KFhNTFJlc291cmNlSWRlbnRpZmllciByZXNvdXJjZUlkZW50aWZpZXIpIHRocm93cyBJT0V4Y2VwdGlvbiwgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgaWYocmVzb3VyY2VJZGVudGlmaWVyID09IG51bGwgKSByZXR1cm4gbnVsbDsKLSAgICAgICAgU3RyaW5nIHB1YmxpY0lkID0gcmVzb3VyY2VJZGVudGlmaWVyLmdldFB1YmxpY0lkKCk7Ci0gICAgICAgIFN0cmluZyBsaXRlcmFsU3lzdGVtSWQgPSByZXNvdXJjZUlkZW50aWZpZXIuZ2V0TGl0ZXJhbFN5c3RlbUlkKCk7Ci0gICAgICAgIFN0cmluZyBiYXNlU3lzdGVtSWQgPSByZXNvdXJjZUlkZW50aWZpZXIuZ2V0QmFzZVN5c3RlbUlkKCk7Ci0gICAgICAgIFN0cmluZyBleHBhbmRlZFN5c3RlbUlkID0gcmVzb3VyY2VJZGVudGlmaWVyLmdldEV4cGFuZGVkU3lzdGVtSWQoKTsKLQotICAgICAgICAvLyBpZiBubyBiYXNlIHN5c3RlbUlkIGdpdmVuLCBhc3N1bWUgdGhhdCBpdCdzIHJlbGF0aXZlCi0gICAgICAgIC8vIHRvIHRoZSBzeXN0ZW1JZCBvZiB0aGUgY3VycmVudCBzY2FubmVkIGVudGl0eQotICAgICAgICAvLyBTb21ldGltZXMgdGhlIHN5c3RlbSBpZCBpcyBub3QgKHByb3Blcmx5KSBleHBhbmRlZC4KLSAgICAgICAgLy8gV2UgbmVlZCB0byBleHBhbmQgdGhlIHN5c3RlbSBpZCBpZjoKLSAgICAgICAgLy8gYS4gdGhlIGV4cGFuZGVkIG9uZSB3YXMgbnVsbDsgb3IKLSAgICAgICAgLy8gYi4gdGhlIGJhc2Ugc3lzdGVtIGlkIHdhcyBudWxsLCBidXQgYmVjb21lcyBub24tbnVsbCBmcm9tIHRoZSBjdXJyZW50IGVudGl0eS4KLSAgICAgICAgYm9vbGVhbiBuZWVkRXhwYW5kID0gKGV4cGFuZGVkU3lzdGVtSWQgPT0gbnVsbCk7Ci0gICAgICAgIC8vIFJFVklTSVQ6ICB3aHkgd291bGQgdGhlIGJhc2VTeXN0ZW1JZCBldmVyIGJlIG51bGw/ICBpZiB3ZQotICAgICAgICAvLyBkaWRuJ3QgaGF2ZSB0byBtYWtlIHRoaXMgY2hlY2sgd2Ugd291bGRuJ3QgaGF2ZSB0byByZXVzZSB0aGUKLSAgICAgICAgLy8gZlhNTFJlc291cmNlSWRlbnRpZmllciBvYmplY3QuLi4KLSAgICAgICAgaWYgKGJhc2VTeXN0ZW1JZCA9PSBudWxsICYmIGZDdXJyZW50RW50aXR5ICE9IG51bGwgJiYgZkN1cnJlbnRFbnRpdHkuZW50aXR5TG9jYXRpb24gIT0gbnVsbCkgewotICAgICAgICAgICAgYmFzZVN5c3RlbUlkID0gZkN1cnJlbnRFbnRpdHkuZW50aXR5TG9jYXRpb24uZ2V0RXhwYW5kZWRTeXN0ZW1JZCgpOwotICAgICAgICAgICAgaWYgKGJhc2VTeXN0ZW1JZCAhPSBudWxsKQotICAgICAgICAgICAgICAgIG5lZWRFeHBhbmQgPSB0cnVlOwotICAgICAgICB9Ci0gICAgICAgIGlmIChuZWVkRXhwYW5kKQotICAgICAgICAgICAgZXhwYW5kZWRTeXN0ZW1JZCA9IGV4cGFuZFN5c3RlbUlkKGxpdGVyYWxTeXN0ZW1JZCwgYmFzZVN5c3RlbUlkLGZhbHNlKTsKLQotICAgICAgICAvLyBnaXZlIHRoZSBlbnRpdHkgcmVzb2x2ZXIgYSBjaGFuY2UKLSAgICAgICAgWE1MSW5wdXRTb3VyY2UgeG1sSW5wdXRTb3VyY2UgPSBudWxsOwotCi0gICAgICAgIGlmIChmRW50aXR5UmVzb2x2ZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgcmVzb3VyY2VJZGVudGlmaWVyLnNldEJhc2VTeXN0ZW1JZChiYXNlU3lzdGVtSWQpOwotICAgICAgICAgICAgcmVzb3VyY2VJZGVudGlmaWVyLnNldEV4cGFuZGVkU3lzdGVtSWQoZXhwYW5kZWRTeXN0ZW1JZCk7Ci0gICAgICAgICAgICB4bWxJbnB1dFNvdXJjZSA9IGZFbnRpdHlSZXNvbHZlci5yZXNvbHZlRW50aXR5KHJlc291cmNlSWRlbnRpZmllcik7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBkbyBkZWZhdWx0IHJlc29sdXRpb24KLSAgICAgICAgLy8gUkVWSVNJVDogd2hhdCdzIHRoZSBjb3JyZWN0IGJlaGF2aW9yIGlmIHRoZSB1c2VyIHByb3ZpZGVkIGFuIGVudGl0eQotICAgICAgICAvLyByZXNvbHZlciAoZkVudGl0eVJlc29sdmVyICE9IG51bGwpLCBidXQgcmVzb2x2ZUVudGl0eSBkb2Vzbid0IHJldHVybgotICAgICAgICAvLyBhbiBpbnB1dCBzb3VyY2UgKHhtbElucHV0U291cmNlID09IG51bGwpPwotICAgICAgICAvLyBkbyB3ZSBkbyBkZWZhdWx0IHJlc29sdXRpb24sIG9yIGRvIHdlIGp1c3QgcmV0dXJuIG51bGw/IC1TRwotICAgICAgICBpZiAoeG1sSW5wdXRTb3VyY2UgPT0gbnVsbCkgewotICAgICAgICAgICAgLy8gUkVWSVNJVDogd2hlbiBzeXN0ZW1JZCBpcyBudWxsLCBJIHRoaW5rIHdlIHNob3VsZCByZXR1cm4gbnVsbC4KLSAgICAgICAgICAgIC8vICAgICAgICAgIGlzIHRoaXMgdGhlIHJpZ2h0IHNvbHV0aW9uPyAtU0cKLSAgICAgICAgICAgIC8vaWYgKHN5c3RlbUlkICE9IG51bGwpCi0gICAgICAgICAgICB4bWxJbnB1dFNvdXJjZSA9IG5ldyBYTUxJbnB1dFNvdXJjZShwdWJsaWNJZCwgbGl0ZXJhbFN5c3RlbUlkLCBiYXNlU3lzdGVtSWQpOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKERFQlVHX1JFU09MVkVSKSB7Ci0gICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIlhNTEVudGl0eU1hbmFnZXIucmVzb2x2ZUVudGl0eSgiICsgcHVibGljSWQgKyAiKSIpOwotICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCIgPSAiICsgeG1sSW5wdXRTb3VyY2UpOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIHhtbElucHV0U291cmNlOwotCi0gICAgfSAvLyByZXNvbHZlRW50aXR5KFhNTFJlc291cmNlSWRlbnRpZmllcik6WE1MSW5wdXRTb3VyY2UKLQotICAgIC8qKgotICAgICAqIFN0YXJ0cyBhIG5hbWVkIGVudGl0eS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBpc0dFIGZsYWcgdG8gaW5kaWNhdGUgd2hldGhlciB0aGUgZW50aXR5IGlzIGEgR2VuZXJhbCBFbnRpdHkKLSAgICAgKiBAcGFyYW0gZW50aXR5TmFtZSBUaGUgbmFtZSBvZiB0aGUgZW50aXR5IHRvIHN0YXJ0LgotICAgICAqIEBwYXJhbSBsaXRlcmFsICAgIFRydWUgaWYgdGhpcyBlbnRpdHkgaXMgc3RhcnRlZCB3aXRoaW4gYSBsaXRlcmFsCi0gICAgICogICAgICAgICAgICAgICAgICAgdmFsdWUuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uICBUaHJvd24gb24gaS9vIGVycm9yLgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBlbnRpdHkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnRFbnRpdHkoYm9vbGVhbiBpc0dFLCBTdHJpbmcgZW50aXR5TmFtZSwgYm9vbGVhbiBsaXRlcmFsKQotICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgWE5JRXhjZXB0aW9uIHsKLQotICAgICAgICAvLyB3YXMgZW50aXR5IGRlY2xhcmVkPwotICAgICAgICBFbnRpdHkgZW50aXR5ID0gZkVudGl0eVN0b3JhZ2UuZ2V0RW50aXR5KGVudGl0eU5hbWUpOwotICAgICAgICBpZiAoZW50aXR5ID09IG51bGwpIHsKLSAgICAgICAgICAgIGlmIChmRW50aXR5SGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIGVuY29kaW5nID0gbnVsbDsKLSAgICAgICAgICAgICAgICBmUmVzb3VyY2VJZGVudGlmaWVyLmNsZWFyKCk7Ci0gICAgICAgICAgICAgICAgZkVudGl0eUF1Z3MucmVtb3ZlQWxsSXRlbXMoKTsKLSAgICAgICAgICAgICAgICBmRW50aXR5QXVncy5wdXRJdGVtKENvbnN0YW50cy5FTlRJVFlfU0tJUFBFRCwgQm9vbGVhbi5UUlVFKTsKLSAgICAgICAgICAgICAgICBmRW50aXR5SGFuZGxlci5zdGFydEVudGl0eShlbnRpdHlOYW1lLCBmUmVzb3VyY2VJZGVudGlmaWVyLCBlbmNvZGluZywgZkVudGl0eUF1Z3MpOwotICAgICAgICAgICAgICAgIGZFbnRpdHlBdWdzLnJlbW92ZUFsbEl0ZW1zKCk7Ci0gICAgICAgICAgICAgICAgZkVudGl0eUF1Z3MucHV0SXRlbShDb25zdGFudHMuRU5USVRZX1NLSVBQRUQsIEJvb2xlYW4uVFJVRSk7Ci0gICAgICAgICAgICAgICAgZkVudGl0eUhhbmRsZXIuZW5kRW50aXR5KGVudGl0eU5hbWUsIGZFbnRpdHlBdWdzKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIHNob3VsZCB3ZSBza2lwIGV4dGVybmFsIGVudGl0aWVzPwotICAgICAgICBib29sZWFuIGV4dGVybmFsID0gZW50aXR5LmlzRXh0ZXJuYWwoKTsKLSAgICAgICAgRW50aXR5LkV4dGVybmFsRW50aXR5IGV4dGVybmFsRW50aXR5ID0gbnVsbDsKLSAgICAgICAgU3RyaW5nIGV4dExpdFN5c0lkID0gbnVsbCwgZXh0QmFzZVN5c0lkID0gbnVsbCwgZXhwYW5kZWRTeXN0ZW1JZCA9IG51bGw7Ci0gICAgICAgIGlmIChleHRlcm5hbCkgewotICAgICAgICAgICAgZXh0ZXJuYWxFbnRpdHkgPSAoRW50aXR5LkV4dGVybmFsRW50aXR5KWVudGl0eTsKLSAgICAgICAgICAgIGV4dExpdFN5c0lkID0gKGV4dGVybmFsRW50aXR5LmVudGl0eUxvY2F0aW9uICE9IG51bGwgPyBleHRlcm5hbEVudGl0eS5lbnRpdHlMb2NhdGlvbi5nZXRMaXRlcmFsU3lzdGVtSWQoKSA6IG51bGwpOwotICAgICAgICAgICAgZXh0QmFzZVN5c0lkID0gKGV4dGVybmFsRW50aXR5LmVudGl0eUxvY2F0aW9uICE9IG51bGwgPyBleHRlcm5hbEVudGl0eS5lbnRpdHlMb2NhdGlvbi5nZXRCYXNlU3lzdGVtSWQoKSA6IG51bGwpOwotICAgICAgICAgICAgZXhwYW5kZWRTeXN0ZW1JZCA9IGV4cGFuZFN5c3RlbUlkKGV4dExpdFN5c0lkLCBleHRCYXNlU3lzSWQpOwotICAgICAgICAgICAgYm9vbGVhbiB1bnBhcnNlZCA9IGVudGl0eS5pc1VucGFyc2VkKCk7Ci0gICAgICAgICAgICBib29sZWFuIHBhcmFtZXRlciA9IGVudGl0eU5hbWUuc3RhcnRzV2l0aCgiJSIpOwotICAgICAgICAgICAgYm9vbGVhbiBnZW5lcmFsID0gIXBhcmFtZXRlcjsKLSAgICAgICAgICAgIGlmICh1bnBhcnNlZCB8fCAoZ2VuZXJhbCAmJiAhZkV4dGVybmFsR2VuZXJhbEVudGl0aWVzKSB8fAotICAgICAgICAgICAgICAgICAgICAocGFyYW1ldGVyICYmICFmRXh0ZXJuYWxQYXJhbWV0ZXJFbnRpdGllcykgfHwKLSAgICAgICAgICAgICAgICAgICAgIWZTdXBwb3J0RFREIHx8ICFmU3VwcG9ydEV4dGVybmFsRW50aXRpZXMpIHsKLQotICAgICAgICAgICAgICAgIGlmIChmRW50aXR5SGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZSZXNvdXJjZUlkZW50aWZpZXIuY2xlYXIoKTsKLSAgICAgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIGVuY29kaW5nID0gbnVsbDsKLSAgICAgICAgICAgICAgICAgICAgZlJlc291cmNlSWRlbnRpZmllci5zZXRWYWx1ZXMoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGV4dGVybmFsRW50aXR5LmVudGl0eUxvY2F0aW9uICE9IG51bGwgPyBleHRlcm5hbEVudGl0eS5lbnRpdHlMb2NhdGlvbi5nZXRQdWJsaWNJZCgpIDogbnVsbCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0TGl0U3lzSWQsIGV4dEJhc2VTeXNJZCwgZXhwYW5kZWRTeXN0ZW1JZCk7Ci0gICAgICAgICAgICAgICAgICAgIGZFbnRpdHlBdWdzLnJlbW92ZUFsbEl0ZW1zKCk7Ci0gICAgICAgICAgICAgICAgICAgIGZFbnRpdHlBdWdzLnB1dEl0ZW0oQ29uc3RhbnRzLkVOVElUWV9TS0lQUEVELCBCb29sZWFuLlRSVUUpOwotICAgICAgICAgICAgICAgICAgICBmRW50aXR5SGFuZGxlci5zdGFydEVudGl0eShlbnRpdHlOYW1lLCBmUmVzb3VyY2VJZGVudGlmaWVyLCBlbmNvZGluZywgZkVudGl0eUF1Z3MpOwotICAgICAgICAgICAgICAgICAgICBmRW50aXR5QXVncy5yZW1vdmVBbGxJdGVtcygpOwotICAgICAgICAgICAgICAgICAgICBmRW50aXR5QXVncy5wdXRJdGVtKENvbnN0YW50cy5FTlRJVFlfU0tJUFBFRCwgQm9vbGVhbi5UUlVFKTsKLSAgICAgICAgICAgICAgICAgICAgZkVudGl0eUhhbmRsZXIuZW5kRW50aXR5KGVudGl0eU5hbWUsIGZFbnRpdHlBdWdzKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gaXMgZW50aXR5IHJlY3Vyc2l2ZT8KLSAgICAgICAgaW50IHNpemUgPSBmRW50aXR5U3RhY2suc2l6ZSgpOwotICAgICAgICBmb3IgKGludCBpID0gc2l6ZTsgaSA+PSAwOyBpLS0pIHsKLSAgICAgICAgICAgIEVudGl0eSBhY3RpdmVFbnRpdHkgPSBpID09IHNpemUKLSAgICAgICAgICAgICAgICAgICAgPyBmQ3VycmVudEVudGl0eQotICAgICAgICAgICAgICAgICAgICA6IChFbnRpdHkpZkVudGl0eVN0YWNrLmVsZW1lbnRBdChpKTsKLSAgICAgICAgICAgIGlmIChhY3RpdmVFbnRpdHkubmFtZSA9PSBlbnRpdHlOYW1lKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIHBhdGggPSBlbnRpdHlOYW1lOwotICAgICAgICAgICAgICAgIGZvciAoaW50IGogPSBpICsgMTsgaiA8IHNpemU7IGorKykgewotICAgICAgICAgICAgICAgICAgICBhY3RpdmVFbnRpdHkgPSAoRW50aXR5KWZFbnRpdHlTdGFjay5lbGVtZW50QXQoaik7Ci0gICAgICAgICAgICAgICAgICAgIHBhdGggPSBwYXRoICsgIiAtPiAiICsgYWN0aXZlRW50aXR5Lm5hbWU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHBhdGggPSBwYXRoICsgIiAtPiAiICsgZkN1cnJlbnRFbnRpdHkubmFtZTsKLSAgICAgICAgICAgICAgICBwYXRoID0gcGF0aCArICIgLT4gIiArIGVudGl0eU5hbWU7Ci0gICAgICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IodGhpcy5nZXRFbnRpdHlTY2FubmVyKCksWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgIlJlY3Vyc2l2ZVJlZmVyZW5jZSIsCi0gICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBlbnRpdHlOYW1lLCBwYXRoIH0sCi0gICAgICAgICAgICAgICAgICAgICAgICBYTUxFcnJvclJlcG9ydGVyLlNFVkVSSVRZX0ZBVEFMX0VSUk9SKTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZFbnRpdHlIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmUmVzb3VyY2VJZGVudGlmaWVyLmNsZWFyKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIGVuY29kaW5nID0gbnVsbDsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXh0ZXJuYWwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZlJlc291cmNlSWRlbnRpZmllci5zZXRWYWx1ZXMoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGV4dGVybmFsRW50aXR5LmVudGl0eUxvY2F0aW9uICE9IG51bGwgPyBleHRlcm5hbEVudGl0eS5lbnRpdHlMb2NhdGlvbi5nZXRQdWJsaWNJZCgpIDogbnVsbCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0TGl0U3lzSWQsIGV4dEJhc2VTeXNJZCwgZXhwYW5kZWRTeXN0ZW1JZCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZFbnRpdHlBdWdzLnJlbW92ZUFsbEl0ZW1zKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZkVudGl0eUF1Z3MucHV0SXRlbShDb25zdGFudHMuRU5USVRZX1NLSVBQRUQsIEJvb2xlYW4uVFJVRSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZkVudGl0eUhhbmRsZXIuc3RhcnRFbnRpdHkoZW50aXR5TmFtZSwgZlJlc291cmNlSWRlbnRpZmllciwgZW5jb2RpbmcsIGZFbnRpdHlBdWdzKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmRW50aXR5QXVncy5yZW1vdmVBbGxJdGVtcygpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZFbnRpdHlBdWdzLnB1dEl0ZW0oQ29uc3RhbnRzLkVOVElUWV9TS0lQUEVELCBCb29sZWFuLlRSVUUpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZFbnRpdHlIYW5kbGVyLmVuZEVudGl0eShlbnRpdHlOYW1lLCBmRW50aXR5QXVncyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIHJlc29sdmUgZXh0ZXJuYWwgZW50aXR5Ci0gICAgICAgIFN0YXhYTUxJbnB1dFNvdXJjZSBzdGF4SW5wdXRTb3VyY2UgPSBudWxsOwotICAgICAgICBYTUxJbnB1dFNvdXJjZSB4bWxJbnB1dFNvdXJjZSA9IG51bGwgOwotCi0gICAgICAgIGlmIChleHRlcm5hbCkgewotICAgICAgICAgICAgc3RheElucHV0U291cmNlID0gcmVzb2x2ZUVudGl0eUFzUGVyU3RheChleHRlcm5hbEVudGl0eS5lbnRpdHlMb2NhdGlvbik7Ci0gICAgICAgICAgICAvKiogeHh4OiAgV2FpdGluZyBmcm9tIHRoZSBFRwotICAgICAgICAgICAgICogLy9zaW1wbHkgcmV0dXJuIGlmIHRoZXJlIHdhcyBlbnRpdHkgcmVzb2x2ZXIgcmVnaXN0ZXJlZCBhbmQgYXBwbGljYXRpb24KLSAgICAgICAgICAgICAqIC8vcmV0dXJucyBlaXRoZXIgWE1MU3RyZWFtUmVhZGVyIG9yIFhNTEV2ZW50UmVhZGVyLgotICAgICAgICAgICAgICogaWYoc3RheElucHV0U291cmNlLmhhc1hNTFN0cmVhbU9yWE1MRXZlbnRSZWFkZXIoKSkgcmV0dXJuIDsKLSAgICAgICAgICAgICAqLwotICAgICAgICAgICAgeG1sSW5wdXRTb3VyY2UgPSBzdGF4SW5wdXRTb3VyY2UuZ2V0WE1MSW5wdXRTb3VyY2UoKSA7Ci0gICAgICAgICAgICBpZiAoIWZJU0NyZWF0ZWRCeVJlc29sdmVyKSB7Ci0gICAgICAgICAgICAgICAgLy9sZXQgdGhlIG5vdC1Mb2FkRXh0ZXJuYWxEVEQgb3Igbm90LVN1cHBvcnREVEQgcHJvY2VzcyB0byBoYW5kbGUgdGhlIHNpdHVhdGlvbgotICAgICAgICAgICAgICAgIGlmIChmTG9hZEV4dGVybmFsRFREKSB7Ci0gICAgICAgICAgICAgICAgICAgIFN0cmluZyBhY2Nlc3NFcnJvciA9IFNlY3VyaXR5U3VwcG9ydC5jaGVja0FjY2VzcyhleHBhbmRlZFN5c3RlbUlkLCBmQWNjZXNzRXh0ZXJuYWxEVEQsIENvbnN0YW50cy5BQ0NFU1NfRVhURVJOQUxfQUxMKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGFjY2Vzc0Vycm9yICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKHRoaXMuZ2V0RW50aXR5U2Nhbm5lcigpLFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkFjY2Vzc0V4dGVybmFsRW50aXR5IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgU2VjdXJpdHlTdXBwb3J0LnNhbml0aXplUGF0aChleHBhbmRlZFN5c3RlbUlkKSwgYWNjZXNzRXJyb3IgfSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9GQVRBTF9FUlJPUik7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgLy8gd3JhcCBpbnRlcm5hbCBlbnRpdHkKLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBFbnRpdHkuSW50ZXJuYWxFbnRpdHkgaW50ZXJuYWxFbnRpdHkgPSAoRW50aXR5LkludGVybmFsRW50aXR5KWVudGl0eTsKLSAgICAgICAgICAgIFJlYWRlciByZWFkZXIgPSBuZXcgU3RyaW5nUmVhZGVyKGludGVybmFsRW50aXR5LnRleHQpOwotICAgICAgICAgICAgeG1sSW5wdXRTb3VyY2UgPSBuZXcgWE1MSW5wdXRTb3VyY2UobnVsbCwgbnVsbCwgbnVsbCwgcmVhZGVyLCBudWxsKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIHN0YXJ0IHRoZSBlbnRpdHkKLSAgICAgICAgc3RhcnRFbnRpdHkoaXNHRSwgZW50aXR5TmFtZSwgeG1sSW5wdXRTb3VyY2UsIGxpdGVyYWwsIGV4dGVybmFsKTsKLQotICAgIH0gLy8gc3RhcnRFbnRpdHkoU3RyaW5nLGJvb2xlYW4pCi0KLSAgICAvKioKLSAgICAgKiBTdGFydHMgdGhlIGRvY3VtZW50IGVudGl0eS4gVGhlIGRvY3VtZW50IGVudGl0eSBoYXMgdGhlICJbeG1sXSIKLSAgICAgKiBwc2V1ZG8tbmFtZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSB4bWxJbnB1dFNvdXJjZSBUaGUgaW5wdXQgc291cmNlIG9mIHRoZSBkb2N1bWVudCBlbnRpdHkuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uICBUaHJvd24gb24gaS9vIGVycm9yLgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBlbnRpdHkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnREb2N1bWVudEVudGl0eShYTUxJbnB1dFNvdXJjZSB4bWxJbnB1dFNvdXJjZSkKLSAgICB0aHJvd3MgSU9FeGNlcHRpb24sIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIHN0YXJ0RW50aXR5KGZhbHNlLCBYTUxFbnRpdHksIHhtbElucHV0U291cmNlLCBmYWxzZSwgdHJ1ZSk7Ci0gICAgfSAvLyBzdGFydERvY3VtZW50RW50aXR5KFhNTElucHV0U291cmNlKQotCi0gICAgLy94eHggdGhlc2UgbWV0aG9kcyBhcmUgbm90IHJlcXVpcmVkLgotICAgIC8qKgotICAgICAqIFN0YXJ0cyB0aGUgRFREIGVudGl0eS4gVGhlIERURCBlbnRpdHkgaGFzIHRoZSAiW2R0ZF0iCi0gICAgICogcHNldWRvLW5hbWUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0geG1sSW5wdXRTb3VyY2UgVGhlIGlucHV0IHNvdXJjZSBvZiB0aGUgRFREIGVudGl0eS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gIFRocm93biBvbiBpL28gZXJyb3IuCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGVudGl0eSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydERUREVudGl0eShYTUxJbnB1dFNvdXJjZSB4bWxJbnB1dFNvdXJjZSkKLSAgICB0aHJvd3MgSU9FeGNlcHRpb24sIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIHN0YXJ0RW50aXR5KGZhbHNlLCBEVERFbnRpdHksIHhtbElucHV0U291cmNlLCBmYWxzZSwgdHJ1ZSk7Ci0gICAgfSAvLyBzdGFydERUREVudGl0eShYTUxJbnB1dFNvdXJjZSkKLQotICAgIC8vIGluZGljYXRlIHN0YXJ0IG9mIGV4dGVybmFsIHN1YnNldCBzbyB0aGF0Ci0gICAgLy8gbG9jYXRpb24gb2YgZW50aXR5IGRlY2xzIGNhbiBiZSB0cmFja2VkCi0gICAgcHVibGljIHZvaWQgc3RhcnRFeHRlcm5hbFN1YnNldCgpIHsKLSAgICAgICAgZkluRXh0ZXJuYWxTdWJzZXQgPSB0cnVlOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGVuZEV4dGVybmFsU3Vic2V0KCkgewotICAgICAgICBmSW5FeHRlcm5hbFN1YnNldCA9IGZhbHNlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFN0YXJ0cyBhbiBlbnRpdHkuCi0gICAgICogPHA+Ci0gICAgICogVGhpcyBtZXRob2QgY2FuIGJlIHVzZWQgdG8gaW5zZXJ0IGFuIGFwcGxpY2F0aW9uIGRlZmluZWQgWE1MCi0gICAgICogZW50aXR5IHN0cmVhbSBpbnRvIHRoZSBwYXJzaW5nIHN0cmVhbS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBpc0dFIGZsYWcgdG8gaW5kaWNhdGUgd2hldGhlciB0aGUgZW50aXR5IGlzIGEgR2VuZXJhbCBFbnRpdHkKLSAgICAgKiBAcGFyYW0gbmFtZSAgICAgICAgICAgVGhlIG5hbWUgb2YgdGhlIGVudGl0eS4KLSAgICAgKiBAcGFyYW0geG1sSW5wdXRTb3VyY2UgVGhlIGlucHV0IHNvdXJjZSBvZiB0aGUgZW50aXR5LgotICAgICAqIEBwYXJhbSBsaXRlcmFsICAgICAgICBUcnVlIGlmIHRoaXMgZW50aXR5IGlzIHN0YXJ0ZWQgd2l0aGluIGEKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgbGl0ZXJhbCB2YWx1ZS4KLSAgICAgKiBAcGFyYW0gaXNFeHRlcm5hbCAgICB3aGV0aGVyIHRoaXMgZW50aXR5IHNob3VsZCBiZSB0cmVhdGVkIGFzIGFuIGludGVybmFsIG9yIGV4dGVybmFsIGVudGl0eS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gIFRocm93biBvbiBpL28gZXJyb3IuCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGVudGl0eSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydEVudGl0eShib29sZWFuIGlzR0UsIFN0cmluZyBuYW1lLAotICAgICAgICAgICAgWE1MSW5wdXRTb3VyY2UgeG1sSW5wdXRTb3VyY2UsCi0gICAgICAgICAgICBib29sZWFuIGxpdGVyYWwsIGJvb2xlYW4gaXNFeHRlcm5hbCkKLSAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgWE5JRXhjZXB0aW9uIHsKLQotICAgICAgICBTdHJpbmcgZW5jb2RpbmcgPSBzZXR1cEN1cnJlbnRFbnRpdHkoaXNHRSwgbmFtZSwgeG1sSW5wdXRTb3VyY2UsIGxpdGVyYWwsIGlzRXh0ZXJuYWwpOwotCi0gICAgICAgIC8vd2hlbiBlbnRpdHkgZXhwYW5zaW9uIGxpbWl0IGlzIHNldCBieSB0aGUgQXBwbGljYXRpb24sIHdlIG5lZWQgdG8KLSAgICAgICAgLy9jaGVjayBmb3IgdGhlIGVudGl0eSBleHBhbnNpb24gbGltaXQgc2V0IGJ5IHRoZSBwYXJzZXIsIGlmIG51bWJlciBvZiBlbnRpdHkKLSAgICAgICAgLy9leHBhbnNpb25zIGV4Y2VlZHMgdGhlIGVudGl0eSBleHBhbnNpb24gbGltaXQsIHBhcnNlciB3aWxsIHRocm93IGZhdGFsIGVycm9yLgotICAgICAgICAvLyBOb3RlIHRoYXQgdGhpcyByZXByZXNlbnRzIHRoZSBuZXN0aW5nIGxldmVsIG9mIG9wZW4gZW50aXRpZXMuCi0gICAgICAgIGZFbnRpdHlFeHBhbnNpb25Db3VudCsrOwotICAgICAgICBpZihmTGltaXRBbmFseXplciAhPSBudWxsKSB7Ci0gICAgICAgICAgIGZMaW1pdEFuYWx5emVyLmFkZFZhbHVlKGVudGl0eUV4cGFuc2lvbkluZGV4LCBuYW1lLCAxKTsKLSAgICAgICAgfQotICAgICAgICBpZiggZlNlY3VyaXR5TWFuYWdlciAhPSBudWxsICYmIGZTZWN1cml0eU1hbmFnZXIuaXNPdmVyTGltaXQoZW50aXR5RXhwYW5zaW9uSW5kZXgsIGZMaW1pdEFuYWx5emVyKSl7Ci0gICAgICAgICAgICBmU2VjdXJpdHlNYW5hZ2VyLmRlYnVnUHJpbnQoZkxpbWl0QW5hbHl6ZXIpOwotICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLCJFbnRpdHlFeHBhbnNpb25MaW1pdCIsCi0gICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXtmU2VjdXJpdHlNYW5hZ2VyLmdldExpbWl0VmFsdWVCeUluZGV4KGVudGl0eUV4cGFuc2lvbkluZGV4KX0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxFcnJvclJlcG9ydGVyLlNFVkVSSVRZX0ZBVEFMX0VSUk9SICk7Ci0gICAgICAgICAgICAvLyBpcyB0aGVyZSBhbnl0aGluZyBiZXR0ZXIgdG8gZG8gdGhhbiByZXNldCB0aGUgY291bnRlcj8KLSAgICAgICAgICAgIC8vIGF0IGxlYXN0IG9uZSBjYW4gZW52aXNpb24gZGVidWdnaW5nIGFwcGxpY2F0aW9ucyB3aGVyZSB0aGlzIG1pZ2h0Ci0gICAgICAgICAgICAvLyBiZSB1c2VmdWwuLi4KLSAgICAgICAgICAgIGZFbnRpdHlFeHBhbnNpb25Db3VudCA9IDA7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBjYWxsIGhhbmRsZXIKLSAgICAgICAgaWYgKGZFbnRpdHlIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZFbnRpdHlIYW5kbGVyLnN0YXJ0RW50aXR5KG5hbWUsIGZSZXNvdXJjZUlkZW50aWZpZXIsIGVuY29kaW5nLCBudWxsKTsKLSAgICAgICAgfQotCi0gICAgfSAvLyBzdGFydEVudGl0eShTdHJpbmcsWE1MSW5wdXRTb3VyY2UpCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIGN1cnJlbnQgZW50aXR5IGJlaW5nIHNjYW5uZWQuIEN1cnJlbnQgZW50aXR5IGlzIFNFVCB1c2luZyBzdGFydEVudGl0eSBmdW5jdGlvbi4KLSAgICAgKiBAcmV0dXJuIEVudGl0eS5TY2FubmVkRW50aXR5Ci0gICAgICovCi0KLSAgICBwdWJsaWMgRW50aXR5LlNjYW5uZWRFbnRpdHkgZ2V0Q3VycmVudEVudGl0eSgpewotICAgICAgICByZXR1cm4gZkN1cnJlbnRFbnRpdHkgOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybiB0aGUgdG9wIGxldmVsIGVudGl0eSBoYW5kbGVkIGJ5IHRoaXMgbWFuYWdlciwgb3IgbnVsbAotICAgICAqIGlmIG5vIGVudGl0eSB3YXMgYWRkZWQuCi0gICAgICovCi0gICAgcHVibGljIEVudGl0eS5TY2FubmVkRW50aXR5IGdldFRvcExldmVsRW50aXR5KCkgewotICAgICAgICByZXR1cm4gKEVudGl0eS5TY2FubmVkRW50aXR5KQotICAgICAgICAgICAgKGZFbnRpdHlTdGFjay5lbXB0eSgpID8gbnVsbCA6IGZFbnRpdHlTdGFjay5lbGVtZW50QXQoMCkpOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogQ2xvc2UgYWxsIG9wZW5lZCBJbnB1dFN0cmVhbXMgYW5kIFJlYWRlcnMgb3BlbmVkIGJ5IHRoaXMgcGFyc2VyLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGNsb3NlUmVhZGVycygpIHsKLSAgICAgICAgLyoqIHRoaXMgY2FsbCBhY3R1YWxseSBkb2VzIG5vdGhpbmcsIHJlYWRlcnMgYXJlIGNsb3NlZCBpbiB0aGUgZW5kRW50aXR5IG1ldGhvZAotICAgICAgICAgKiB0aHJvdWdoIHRoZSBjdXJyZW50IGVudGl0eS4KLSAgICAgICAgICogVGhlIGNoYW5nZSBzZWVtcyB0byBoYXZlIGhhcHBlbmVkIGR1cmluZyB0aGUgamRrNiBkZXZlbG9wbWVudCB3aXRoIHRoZQotICAgICAgICAgKiBhZGRpdGlvbiBvZiBTdEFYCi0gICAgICAgICoqLwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGVuZEVudGl0eSgpIHRocm93cyBJT0V4Y2VwdGlvbiwgWE5JRXhjZXB0aW9uIHsKLQotICAgICAgICAvLyBjYWxsIGhhbmRsZXIKLSAgICAgICAgaWYgKERFQlVHX0JVRkZFUikgewotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiKGVuZEVudGl0eTogIik7Ci0gICAgICAgICAgICBwcmludCgpOwotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCk7Ci0gICAgICAgIH0KLSAgICAgICAgLy9wb3AgdGhlIGVudGl0eSBmcm9tIHRoZSBzdGFjawotICAgICAgICBFbnRpdHkuU2Nhbm5lZEVudGl0eSBlbnRpdHkgPSBmRW50aXR5U3RhY2suc2l6ZSgpID4gMCA/IChFbnRpdHkuU2Nhbm5lZEVudGl0eSlmRW50aXR5U3RhY2sucG9wKCkgOiBudWxsIDsKLQotICAgICAgICAvKiogbmVlZCB0byBjbG9zZSB0aGUgcmVhZGVyIGZpcnN0IHNpbmNlIHRoZSBwcm9ncmFtIGNhbiBlbmQKLSAgICAgICAgICogIHByZW1hdHVyZWx5IChlLmcuIGZFbnRpdHlIYW5kbGVyLmVuZEVudGl0eSBtYXkgdGhyb3cgZXhjZXB0aW9uKQotICAgICAgICAgKiAgbGVhdmluZyB0aGUgcmVhZGVyIG9wZW4KLSAgICAgICAgICovCi0gICAgICAgIC8vY2xvc2UgdGhlIHJlYWRlcgotICAgICAgICBpZihmQ3VycmVudEVudGl0eSAhPSBudWxsKXsKLSAgICAgICAgICAgIC8vY2xvc2UgdGhlIHJlYWRlcgotICAgICAgICAgICAgdHJ5ewotICAgICAgICAgICAgICAgIGlmIChmTGltaXRBbmFseXplciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZMaW1pdEFuYWx5emVyLmVuZEVudGl0eShYTUxTZWN1cml0eU1hbmFnZXIuTGltaXQuR0VORVJBTF9FTlRJVFlfU0laRV9MSU1JVCwgZkN1cnJlbnRFbnRpdHkubmFtZSk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChmQ3VycmVudEVudGl0eS5uYW1lLmVxdWFscygiW3htbF0iKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgZlNlY3VyaXR5TWFuYWdlci5kZWJ1Z1ByaW50KGZMaW1pdEFuYWx5emVyKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5jbG9zZSgpOwotICAgICAgICAgICAgfWNhdGNoKElPRXhjZXB0aW9uIGV4KXsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWE5JRXhjZXB0aW9uKGV4KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGlmIChmRW50aXR5SGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAvL3NvIHRoaXMgaXMgdGhlIGxhc3Qgb3BlbmVkIGVudGl0eSwgc2lnbmFsIGl0IHRvIGN1cnJlbnQgZkVudGl0eUhhbmRsZXIgdXNpbmcgQXVnbWVudGF0aW9uCi0gICAgICAgICAgICBpZihlbnRpdHkgPT0gbnVsbCl7Ci0gICAgICAgICAgICAgICAgZkVudGl0eUF1Z3MucmVtb3ZlQWxsSXRlbXMoKTsKLSAgICAgICAgICAgICAgICBmRW50aXR5QXVncy5wdXRJdGVtKENvbnN0YW50cy5MQVNUX0VOVElUWSwgQm9vbGVhbi5UUlVFKTsKLSAgICAgICAgICAgICAgICBmRW50aXR5SGFuZGxlci5lbmRFbnRpdHkoZkN1cnJlbnRFbnRpdHkubmFtZSwgZkVudGl0eUF1Z3MpOwotICAgICAgICAgICAgICAgIGZFbnRpdHlBdWdzLnJlbW92ZUFsbEl0ZW1zKCk7Ci0gICAgICAgICAgICB9ZWxzZXsKLSAgICAgICAgICAgICAgICBmRW50aXR5SGFuZGxlci5lbmRFbnRpdHkoZkN1cnJlbnRFbnRpdHkubmFtZSwgbnVsbCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgLy9jaGVjayBpZiBpdCBpcyBhIGRvY3VtZW50IGVudGl0eQotICAgICAgICBib29sZWFuIGRvY3VtZW50RW50aXR5ID0gZkN1cnJlbnRFbnRpdHkubmFtZSA9PSBYTUxFbnRpdHk7Ci0KLSAgICAgICAgLy9zZXQgcG9wcGVkIGVudGl0eSBhcyBjdXJyZW50IGVudGl0eQotICAgICAgICBmQ3VycmVudEVudGl0eSA9IGVudGl0eTsKLSAgICAgICAgZkVudGl0eVNjYW5uZXIuc2V0Q3VycmVudEVudGl0eShmQ3VycmVudEVudGl0eSk7Ci0KLSAgICAgICAgLy9jaGVjayBpZiB0aGVyZSBhcmUgYW55IGVudGl0eSBsZWZ0IGluIHRoZSBzdGFjayAtLSBpZiB0aGVyZSBhcmUKLSAgICAgICAgLy9ubyBlbnRyaWVzIEVPRiBoYXMgYmVlbiByZWFjaGVkLgotICAgICAgICAvLyB0aHJvdyBleGNlcHRpb24gd2hlbiBpdCBpcyB0aGUgbGFzdCBlbnRpdHkgYnV0IGl0IGlzIG5vdCBhIGRvY3VtZW50IGVudGl0eQotCi0gICAgICAgIGlmKGZDdXJyZW50RW50aXR5ID09IG51bGwgJiAhZG9jdW1lbnRFbnRpdHkpewotICAgICAgICAgICAgdGhyb3cgbmV3IEVPRkV4Y2VwdGlvbigpIDsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChERUJVR19CVUZGRVIpIHsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIillbmRFbnRpdHk6ICIpOwotICAgICAgICAgICAgcHJpbnQoKTsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigpOwotICAgICAgICB9Ci0KLSAgICB9IC8vIGVuZEVudGl0eSgpCi0KLQotICAgIC8vCi0gICAgLy8gWE1MQ29tcG9uZW50IG1ldGhvZHMKLSAgICAvLwotICAgIHB1YmxpYyB2b2lkIHJlc2V0KFByb3BlcnR5TWFuYWdlciBwcm9wZXJ0eU1hbmFnZXIpewotICAgICAgICAvLyB4ZXJjZXMgcHJvcGVydGllcwotICAgICAgICBmU3ltYm9sVGFibGUgPSAoU3ltYm9sVGFibGUpcHJvcGVydHlNYW5hZ2VyLmdldFByb3BlcnR5KENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLlNZTUJPTF9UQUJMRV9QUk9QRVJUWSk7Ci0gICAgICAgIGZFcnJvclJlcG9ydGVyID0gKFhNTEVycm9yUmVwb3J0ZXIpcHJvcGVydHlNYW5hZ2VyLmdldFByb3BlcnR5KENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLkVSUk9SX1JFUE9SVEVSX1BST1BFUlRZKTsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGZTdGF4RW50aXR5UmVzb2x2ZXIgPSAoU3RheEVudGl0eVJlc29sdmVyV3JhcHBlcilwcm9wZXJ0eU1hbmFnZXIuZ2V0UHJvcGVydHkoU1RBWF9FTlRJVFlfUkVTT0xWRVIpOwotICAgICAgICB9IGNhdGNoIChYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIGZTdGF4RW50aXR5UmVzb2x2ZXIgPSBudWxsOwotICAgICAgICB9Ci0KLSAgICAgICAgZlN1cHBvcnREVEQgPSAoKEJvb2xlYW4pcHJvcGVydHlNYW5hZ2VyLmdldFByb3BlcnR5KFhNTElucHV0RmFjdG9yeS5TVVBQT1JUX0RURCkpLmJvb2xlYW5WYWx1ZSgpOwotICAgICAgICBmUmVwbGFjZUVudGl0eVJlZmVyZW5jZXMgPSAoKEJvb2xlYW4pcHJvcGVydHlNYW5hZ2VyLmdldFByb3BlcnR5KFhNTElucHV0RmFjdG9yeS5JU19SRVBMQUNJTkdfRU5USVRZX1JFRkVSRU5DRVMpKS5ib29sZWFuVmFsdWUoKTsKLSAgICAgICAgZlN1cHBvcnRFeHRlcm5hbEVudGl0aWVzID0gKChCb29sZWFuKXByb3BlcnR5TWFuYWdlci5nZXRQcm9wZXJ0eShYTUxJbnB1dEZhY3RvcnkuSVNfU1VQUE9SVElOR19FWFRFUk5BTF9FTlRJVElFUykpLmJvb2xlYW5WYWx1ZSgpOwotCi0gICAgICAgIC8vIFplcGh5ciBmZWF0dXJlIGlnbm9yZS1leHRlcm5hbC1kdGQgaXMgdGhlIG9wcG9zaXRlIG9mIFhlcmNlcycgbG9hZC1leHRlcm5hbC1kdGQKLSAgICAgICAgZkxvYWRFeHRlcm5hbERURCA9ICEoKEJvb2xlYW4pcHJvcGVydHlNYW5hZ2VyLmdldFByb3BlcnR5KENvbnN0YW50cy5aRVBIWVJfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLklHTk9SRV9FWFRFUk5BTF9EVEQpKS5ib29sZWFuVmFsdWUoKTsKLQotICAgICAgICAvLyBKQVhQIDEuNSBmZWF0dXJlCi0gICAgICAgIFhNTFNlY3VyaXR5UHJvcGVydHlNYW5hZ2VyIHNwbSA9IChYTUxTZWN1cml0eVByb3BlcnR5TWFuYWdlcikgcHJvcGVydHlNYW5hZ2VyLmdldFByb3BlcnR5KFhNTF9TRUNVUklUWV9QUk9QRVJUWV9NQU5BR0VSKTsKLSAgICAgICAgZkFjY2Vzc0V4dGVybmFsRFREID0gc3BtLmdldFZhbHVlKFhNTFNlY3VyaXR5UHJvcGVydHlNYW5hZ2VyLlByb3BlcnR5LkFDQ0VTU19FWFRFUk5BTF9EVEQpOwotCi0gICAgICAgIGZTZWN1cml0eU1hbmFnZXIgPSAoWE1MU2VjdXJpdHlNYW5hZ2VyKXByb3BlcnR5TWFuYWdlci5nZXRQcm9wZXJ0eShTRUNVUklUWV9NQU5BR0VSKTsKLQotICAgICAgICBmTGltaXRBbmFseXplciA9IG5ldyBYTUxMaW1pdEFuYWx5emVyKCk7Ci0gICAgICAgIC8vcmVzZXQgZkVudGl0eVN0b3JhZ2UKLSAgICAgICAgZkVudGl0eVN0b3JhZ2UucmVzZXQocHJvcGVydHlNYW5hZ2VyKTsKLSAgICAgICAgLy9yZXNldCBYTUxFbnRpdHlSZWFkZXJJbXBsCi0gICAgICAgIGZFbnRpdHlTY2FubmVyLnJlc2V0KHByb3BlcnR5TWFuYWdlcik7Ci0KLSAgICAgICAgLy8gaW5pdGlhbGl6ZSBzdGF0ZQotICAgICAgICAvL2ZTdGFuZGFsb25lID0gZmFsc2U7Ci0gICAgICAgIGZFbnRpdGllcy5jbGVhcigpOwotICAgICAgICBmRW50aXR5U3RhY2sucmVtb3ZlQWxsRWxlbWVudHMoKTsKLSAgICAgICAgZkN1cnJlbnRFbnRpdHkgPSBudWxsOwotICAgICAgICBmVmFsaWRhdGlvbiA9IGZhbHNlOwotICAgICAgICBmRXh0ZXJuYWxHZW5lcmFsRW50aXRpZXMgPSB0cnVlOwotICAgICAgICBmRXh0ZXJuYWxQYXJhbWV0ZXJFbnRpdGllcyA9IHRydWU7Ci0gICAgICAgIGZBbGxvd0phdmFFbmNvZGluZ3MgPSB0cnVlIDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXNldHMgdGhlIGNvbXBvbmVudC4gVGhlIGNvbXBvbmVudCBjYW4gcXVlcnkgdGhlIGNvbXBvbmVudCBtYW5hZ2VyCi0gICAgICogYWJvdXQgYW55IGZlYXR1cmVzIGFuZCBwcm9wZXJ0aWVzIHRoYXQgYWZmZWN0IHRoZSBvcGVyYXRpb24gb2YgdGhlCi0gICAgICogY29tcG9uZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIGNvbXBvbmVudE1hbmFnZXIgVGhlIGNvbXBvbmVudCBtYW5hZ2VyLgotICAgICAqCi0gICAgICogQHRocm93cyBTQVhFeGNlcHRpb24gVGhyb3duIGJ5IGNvbXBvbmVudCBvbiBpbml0aWFsaXphdGlvbiBlcnJvci4KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBGb3IgZXhhbXBsZSwgaWYgYSBmZWF0dXJlIG9yIHByb3BlcnR5IGlzCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgcmVxdWlyZWQgZm9yIHRoZSBvcGVyYXRpb24gb2YgdGhlIGNvbXBvbmVudCwgdGhlCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgY29tcG9uZW50IG1hbmFnZXIgbWF5IHRocm93IGEKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIG9yIGEKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcmVzZXQoWE1MQ29tcG9uZW50TWFuYWdlciBjb21wb25lbnRNYW5hZ2VyKQotICAgIHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIHsKLQotICAgICAgICBib29sZWFuIHBhcnNlcl9zZXR0aW5ncyA9IGNvbXBvbmVudE1hbmFnZXIuZ2V0RmVhdHVyZShQQVJTRVJfU0VUVElOR1MsIHRydWUpOwotCi0gICAgICAgIGlmICghcGFyc2VyX3NldHRpbmdzKSB7Ci0gICAgICAgICAgICAvLyBwYXJzZXIgc2V0dGluZ3MgaGF2ZSBub3QgYmVlbiBjaGFuZ2VkCi0gICAgICAgICAgICByZXNldCgpOwotICAgICAgICAgICAgaWYoZkVudGl0eVNjYW5uZXIgIT0gbnVsbCl7Ci0gICAgICAgICAgICAgICAgZkVudGl0eVNjYW5uZXIucmVzZXQoY29tcG9uZW50TWFuYWdlcik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZihmRW50aXR5U3RvcmFnZSAhPSBudWxsKXsKLSAgICAgICAgICAgICAgICBmRW50aXR5U3RvcmFnZS5yZXNldChjb21wb25lbnRNYW5hZ2VyKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIHNheCBmZWF0dXJlcwotICAgICAgICBmVmFsaWRhdGlvbiA9IGNvbXBvbmVudE1hbmFnZXIuZ2V0RmVhdHVyZShWQUxJREFUSU9OLCBmYWxzZSk7Ci0gICAgICAgIGZFeHRlcm5hbEdlbmVyYWxFbnRpdGllcyA9IGNvbXBvbmVudE1hbmFnZXIuZ2V0RmVhdHVyZShFWFRFUk5BTF9HRU5FUkFMX0VOVElUSUVTLCB0cnVlKTsKLSAgICAgICAgZkV4dGVybmFsUGFyYW1ldGVyRW50aXRpZXMgPSBjb21wb25lbnRNYW5hZ2VyLmdldEZlYXR1cmUoRVhURVJOQUxfUEFSQU1FVEVSX0VOVElUSUVTLCB0cnVlKTsKLQotICAgICAgICAvLyB4ZXJjZXMgZmVhdHVyZXMKLSAgICAgICAgZkFsbG93SmF2YUVuY29kaW5ncyA9IGNvbXBvbmVudE1hbmFnZXIuZ2V0RmVhdHVyZShBTExPV19KQVZBX0VOQ09ESU5HUywgZmFsc2UpOwotICAgICAgICBmV2FybkR1cGxpY2F0ZUVudGl0eURlZiA9IGNvbXBvbmVudE1hbmFnZXIuZ2V0RmVhdHVyZShXQVJOX09OX0RVUExJQ0FURV9FTlRJVFlERUYsIGZhbHNlKTsKLSAgICAgICAgZlN0cmljdFVSSSA9IGNvbXBvbmVudE1hbmFnZXIuZ2V0RmVhdHVyZShTVEFOREFSRF9VUklfQ09ORk9STUFOVCwgZmFsc2UpOwotICAgICAgICBmTG9hZEV4dGVybmFsRFREID0gY29tcG9uZW50TWFuYWdlci5nZXRGZWF0dXJlKExPQURfRVhURVJOQUxfRFRELCB0cnVlKTsKLQotICAgICAgICAvLyB4ZXJjZXMgcHJvcGVydGllcwotICAgICAgICBmU3ltYm9sVGFibGUgPSAoU3ltYm9sVGFibGUpY29tcG9uZW50TWFuYWdlci5nZXRQcm9wZXJ0eShTWU1CT0xfVEFCTEUpOwotICAgICAgICBmRXJyb3JSZXBvcnRlciA9IChYTUxFcnJvclJlcG9ydGVyKWNvbXBvbmVudE1hbmFnZXIuZ2V0UHJvcGVydHkoRVJST1JfUkVQT1JURVIpOwotICAgICAgICBmRW50aXR5UmVzb2x2ZXIgPSAoWE1MRW50aXR5UmVzb2x2ZXIpY29tcG9uZW50TWFuYWdlci5nZXRQcm9wZXJ0eShFTlRJVFlfUkVTT0xWRVIsIG51bGwpOwotICAgICAgICBmU3RheEVudGl0eVJlc29sdmVyID0gKFN0YXhFbnRpdHlSZXNvbHZlcldyYXBwZXIpY29tcG9uZW50TWFuYWdlci5nZXRQcm9wZXJ0eShTVEFYX0VOVElUWV9SRVNPTFZFUiwgbnVsbCk7Ci0gICAgICAgIGZWYWxpZGF0aW9uTWFuYWdlciA9IChWYWxpZGF0aW9uTWFuYWdlciljb21wb25lbnRNYW5hZ2VyLmdldFByb3BlcnR5KFZBTElEQVRJT05fTUFOQUdFUiwgbnVsbCk7Ci0gICAgICAgIGZTZWN1cml0eU1hbmFnZXIgPSAoWE1MU2VjdXJpdHlNYW5hZ2VyKWNvbXBvbmVudE1hbmFnZXIuZ2V0UHJvcGVydHkoU0VDVVJJVFlfTUFOQUdFUiwgbnVsbCk7Ci0gICAgICAgIGVudGl0eUV4cGFuc2lvbkluZGV4ID0gZlNlY3VyaXR5TWFuYWdlci5nZXRJbmRleChDb25zdGFudHMuSkRLX0VOVElUWV9FWFBBTlNJT05fTElNSVQpOwotCi0gICAgICAgIC8vU3RBWCBQcm9wZXJ0eQotICAgICAgICBmU3VwcG9ydERURCA9IHRydWU7Ci0gICAgICAgIGZSZXBsYWNlRW50aXR5UmVmZXJlbmNlcyA9IHRydWU7Ci0gICAgICAgIGZTdXBwb3J0RXh0ZXJuYWxFbnRpdGllcyA9IHRydWU7Ci0KLSAgICAgICAgLy8gSkFYUCAxLjUgZmVhdHVyZQotICAgICAgICBYTUxTZWN1cml0eVByb3BlcnR5TWFuYWdlciBzcG0gPSAoWE1MU2VjdXJpdHlQcm9wZXJ0eU1hbmFnZXIpIGNvbXBvbmVudE1hbmFnZXIuZ2V0UHJvcGVydHkoWE1MX1NFQ1VSSVRZX1BST1BFUlRZX01BTkFHRVIsIG51bGwpOwotICAgICAgICBpZiAoc3BtID09IG51bGwpIHsKLSAgICAgICAgICAgIHNwbSA9IG5ldyBYTUxTZWN1cml0eVByb3BlcnR5TWFuYWdlcigpOwotICAgICAgICB9Ci0gICAgICAgIGZBY2Nlc3NFeHRlcm5hbERURCA9IHNwbS5nZXRWYWx1ZShYTUxTZWN1cml0eVByb3BlcnR5TWFuYWdlci5Qcm9wZXJ0eS5BQ0NFU1NfRVhURVJOQUxfRFREKTsKLQotICAgICAgICAvL3Jlc2V0IGdlbmVyYWwgc3RhdGUKLSAgICAgICAgcmVzZXQoKTsKLQotICAgICAgICBmRW50aXR5U2Nhbm5lci5yZXNldChjb21wb25lbnRNYW5hZ2VyKTsKLSAgICAgICAgZkVudGl0eVN0b3JhZ2UucmVzZXQoY29tcG9uZW50TWFuYWdlcik7Ci0KLSAgICB9IC8vIHJlc2V0KFhNTENvbXBvbmVudE1hbmFnZXIpCi0KLSAgICAvLyByZXNldCBnZW5lcmFsIHN0YXRlLiAgU2hvdWxkIG5vdCBiZSBjYWxsZWQgb3RoZXIgdGhhbiBieQotICAgIC8vIGEgY2xhc3MgYWN0aW5nIGFzIGEgY29tcG9uZW50IG1hbmFnZXIgYnV0IG5vdAotICAgIC8vIGltcGxlbWVudGluZyB0aGF0IGludGVyZmFjZSBmb3Igd2hhdGV2ZXIgcmVhc29uLgotICAgIHB1YmxpYyB2b2lkIHJlc2V0KCkgewotICAgICAgICBmTGltaXRBbmFseXplciA9IG5ldyBYTUxMaW1pdEFuYWx5emVyKCk7Ci0gICAgICAgIC8vIGluaXRpYWxpemUgc3RhdGUKLSAgICAgICAgZlN0YW5kYWxvbmUgPSBmYWxzZTsKLSAgICAgICAgZkVudGl0aWVzLmNsZWFyKCk7Ci0gICAgICAgIGZFbnRpdHlTdGFjay5yZW1vdmVBbGxFbGVtZW50cygpOwotICAgICAgICBmRW50aXR5RXhwYW5zaW9uQ291bnQgPSAwOwotCi0gICAgICAgIGZDdXJyZW50RW50aXR5ID0gbnVsbDsKLSAgICAgICAgLy8gcmVzZXQgc2Nhbm5lcgotICAgICAgICBpZihmWE1MMTBFbnRpdHlTY2FubmVyICE9IG51bGwpewotICAgICAgICAgICAgZlhNTDEwRW50aXR5U2Nhbm5lci5yZXNldChmU3ltYm9sVGFibGUsIHRoaXMsIGZFcnJvclJlcG9ydGVyKTsKLSAgICAgICAgfQotICAgICAgICBpZihmWE1MMTFFbnRpdHlTY2FubmVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZYTUwxMUVudGl0eVNjYW5uZXIucmVzZXQoZlN5bWJvbFRhYmxlLCB0aGlzLCBmRXJyb3JSZXBvcnRlcik7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBERUJVRwotICAgICAgICBpZiAoREVCVUdfRU5USVRJRVMpIHsKLSAgICAgICAgICAgIGFkZEludGVybmFsRW50aXR5KCJ0ZXh0IiwgIkhlbGxvLCBXb3JsZC4iKTsKLSAgICAgICAgICAgIGFkZEludGVybmFsRW50aXR5KCJlbXB0eS1lbGVtZW50IiwgIjxmb28vPiIpOwotICAgICAgICAgICAgYWRkSW50ZXJuYWxFbnRpdHkoImJhbGFuY2VkLWVsZW1lbnQiLCAiPGZvbz48L2Zvbz4iKTsKLSAgICAgICAgICAgIGFkZEludGVybmFsRW50aXR5KCJiYWxhbmNlZC1lbGVtZW50LXdpdGgtdGV4dCIsICI8Zm9vPkhlbGxvLCBXb3JsZDwvZm9vPiIpOwotICAgICAgICAgICAgYWRkSW50ZXJuYWxFbnRpdHkoImJhbGFuY2VkLWVsZW1lbnQtd2l0aC1lbnRpdHkiLCAiPGZvbz4mdGV4dDs8L2Zvbz4iKTsKLSAgICAgICAgICAgIGFkZEludGVybmFsRW50aXR5KCJ1bmJhbGFuY2VkLWVudGl0eSIsICI8Zm9vPiIpOwotICAgICAgICAgICAgYWRkSW50ZXJuYWxFbnRpdHkoInJlY3Vyc2l2ZS1lbnRpdHkiLCAiPGZvbz4mcmVjdXJzaXZlLWVudGl0eTI7PC9mb28+Iik7Ci0gICAgICAgICAgICBhZGRJbnRlcm5hbEVudGl0eSgicmVjdXJzaXZlLWVudGl0eTIiLCAiPGJhcj4mcmVjdXJzaXZlLWVudGl0eTM7PC9iYXI+Iik7Ci0gICAgICAgICAgICBhZGRJbnRlcm5hbEVudGl0eSgicmVjdXJzaXZlLWVudGl0eTMiLCAiPGJhej4mcmVjdXJzaXZlLWVudGl0eTs8L2Jhej4iKTsKLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgYWRkRXh0ZXJuYWxFbnRpdHkoImV4dGVybmFsLXRleHQiLCBudWxsLCAiZXh0ZXJuYWwtdGV4dC5lbnQiLCAidGVzdC9leHRlcm5hbC10ZXh0LnhtbCIpOwotICAgICAgICAgICAgICAgIGFkZEV4dGVybmFsRW50aXR5KCJleHRlcm5hbC1iYWxhbmNlZC1lbGVtZW50IiwgbnVsbCwgImV4dGVybmFsLWJhbGFuY2VkLWVsZW1lbnQuZW50IiwgInRlc3QvZXh0ZXJuYWwtYmFsYW5jZWQtZWxlbWVudC54bWwiKTsKLSAgICAgICAgICAgICAgICBhZGRFeHRlcm5hbEVudGl0eSgib25lIiwgbnVsbCwgImVudC9vbmUuZW50IiwgInRlc3QvZXh0ZXJuYWwtZW50aXR5LnhtbCIpOwotICAgICAgICAgICAgICAgIGFkZEV4dGVybmFsRW50aXR5KCJ0d28iLCBudWxsLCAiZW50L3R3by5lbnQiLCAidGVzdC9lbnQvb25lLnhtbCIpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7Ci0gICAgICAgICAgICAgICAgLy8gc2hvdWxkIG5ldmVyIGhhcHBlbgotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgZkVudGl0eUhhbmRsZXIgPSBudWxsOwotCi0gICAgICAgIC8vIHJlc2V0IHNjYW5uZXIKLSAgICAgICAgLy9pZihmRW50aXR5U2Nhbm5lciE9bnVsbCkKLSAgICAgICAgICAvLyAgZkVudGl0eVNjYW5uZXIucmVzZXQoZlN5bWJvbFRhYmxlLCB0aGlzLGZFcnJvclJlcG9ydGVyKTsKLQotICAgIH0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGEgbGlzdCBvZiBmZWF0dXJlIGlkZW50aWZpZXJzIHRoYXQgYXJlIHJlY29nbml6ZWQgYnkKLSAgICAgKiB0aGlzIGNvbXBvbmVudC4gVGhpcyBtZXRob2QgbWF5IHJldHVybiBudWxsIGlmIG5vIGZlYXR1cmVzCi0gICAgICogYXJlIHJlY29nbml6ZWQgYnkgdGhpcyBjb21wb25lbnQuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZ1tdIGdldFJlY29nbml6ZWRGZWF0dXJlcygpIHsKLSAgICAgICAgcmV0dXJuIChTdHJpbmdbXSkoUkVDT0dOSVpFRF9GRUFUVVJFUy5jbG9uZSgpKTsKLSAgICB9IC8vIGdldFJlY29nbml6ZWRGZWF0dXJlcygpOlN0cmluZ1tdCi0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSBzdGF0ZSBvZiBhIGZlYXR1cmUuIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSB0aGUgY29tcG9uZW50Ci0gICAgICogbWFuYWdlciBhbnkgdGltZSBhZnRlciByZXNldCB3aGVuIGEgZmVhdHVyZSBjaGFuZ2VzIHN0YXRlLgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gQ29tcG9uZW50cyBzaG91bGQgc2lsZW50bHkgaWdub3JlIGZlYXR1cmVzCi0gICAgICogdGhhdCBkbyBub3QgYWZmZWN0IHRoZSBvcGVyYXRpb24gb2YgdGhlIGNvbXBvbmVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBmZWF0dXJlSWQgVGhlIGZlYXR1cmUgaWRlbnRpZmllci4KLSAgICAgKiBAcGFyYW0gc3RhdGUgICAgIFRoZSBzdGF0ZSBvZiB0aGUgZmVhdHVyZS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiBUaGUgY29tcG9uZW50IHNob3VsZCBub3QgdGhyb3cKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcyBleGNlcHRpb24uCi0gICAgICogQHRocm93cyBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gVGhlIGNvbXBvbmVudCBzaG91bGQgbm90IHRocm93Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcyBleGNlcHRpb24uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RmVhdHVyZShTdHJpbmcgZmVhdHVyZUlkLCBib29sZWFuIHN0YXRlKQotICAgIHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIHsKLQotICAgICAgICAvLyB4ZXJjZXMgZmVhdHVyZXMKLSAgICAgICAgaWYgKGZlYXR1cmVJZC5zdGFydHNXaXRoKENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVgpKSB7Ci0gICAgICAgICAgICBmaW5hbCBpbnQgc3VmZml4TGVuZ3RoID0gZmVhdHVyZUlkLmxlbmd0aCgpIC0gQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWC5sZW5ndGgoKTsKLSAgICAgICAgICAgIGlmIChzdWZmaXhMZW5ndGggPT0gQ29uc3RhbnRzLkFMTE9XX0pBVkFfRU5DT0RJTkdTX0ZFQVRVUkUubGVuZ3RoKCkgJiYKLSAgICAgICAgICAgICAgICBmZWF0dXJlSWQuZW5kc1dpdGgoQ29uc3RhbnRzLkFMTE9XX0pBVkFfRU5DT0RJTkdTX0ZFQVRVUkUpKSB7Ci0gICAgICAgICAgICAgICAgZkFsbG93SmF2YUVuY29kaW5ncyA9IHN0YXRlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKHN1ZmZpeExlbmd0aCA9PSBDb25zdGFudHMuTE9BRF9FWFRFUk5BTF9EVERfRkVBVFVSRS5sZW5ndGgoKSAmJgotICAgICAgICAgICAgICAgIGZlYXR1cmVJZC5lbmRzV2l0aChDb25zdGFudHMuTE9BRF9FWFRFUk5BTF9EVERfRkVBVFVSRSkpIHsKLSAgICAgICAgICAgICAgICBmTG9hZEV4dGVybmFsRFREID0gc3RhdGU7Ci0gICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICB9IC8vIHNldEZlYXR1cmUoU3RyaW5nLGJvb2xlYW4pCi0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiBhIHByb3BlcnR5LiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgdGhlIGNvbXBvbmVudAotICAgICAqIG1hbmFnZXIgYW55IHRpbWUgYWZ0ZXIgcmVzZXQgd2hlbiBhIHByb3BlcnR5IGNoYW5nZXMgdmFsdWUuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBDb21wb25lbnRzIHNob3VsZCBzaWxlbnRseSBpZ25vcmUgcHJvcGVydGllcwotICAgICAqIHRoYXQgZG8gbm90IGFmZmVjdCB0aGUgb3BlcmF0aW9uIG9mIHRoZSBjb21wb25lbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcHJvcGVydHlJZCBUaGUgcHJvcGVydHkgaWRlbnRpZmllci4KLSAgICAgKiBAcGFyYW0gdmFsdWUgICAgICBUaGUgdmFsdWUgb2YgdGhlIHByb3BlcnR5LgotICAgICAqCi0gICAgICogQHRocm93cyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIFRoZSBjb21wb25lbnQgc2hvdWxkIG5vdCB0aHJvdwotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzIGV4Y2VwdGlvbi4KLSAgICAgKiBAdGhyb3dzIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBUaGUgY29tcG9uZW50IHNob3VsZCBub3QgdGhyb3cKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzIGV4Y2VwdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRQcm9wZXJ0eShTdHJpbmcgcHJvcGVydHlJZCwgT2JqZWN0IHZhbHVlKXsKLSAgICAgICAgLy8gWGVyY2VzIHByb3BlcnRpZXMKLSAgICAgICAgaWYgKHByb3BlcnR5SWQuc3RhcnRzV2l0aChDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCkpIHsKLSAgICAgICAgICAgIGZpbmFsIGludCBzdWZmaXhMZW5ndGggPSBwcm9wZXJ0eUlkLmxlbmd0aCgpIC0gQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVgubGVuZ3RoKCk7Ci0KLSAgICAgICAgICAgIGlmIChzdWZmaXhMZW5ndGggPT0gQ29uc3RhbnRzLlNZTUJPTF9UQUJMRV9QUk9QRVJUWS5sZW5ndGgoKSAmJgotICAgICAgICAgICAgICAgIHByb3BlcnR5SWQuZW5kc1dpdGgoQ29uc3RhbnRzLlNZTUJPTF9UQUJMRV9QUk9QRVJUWSkpIHsKLSAgICAgICAgICAgICAgICBmU3ltYm9sVGFibGUgPSAoU3ltYm9sVGFibGUpdmFsdWU7Ci0gICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKHN1ZmZpeExlbmd0aCA9PSBDb25zdGFudHMuRVJST1JfUkVQT1JURVJfUFJPUEVSVFkubGVuZ3RoKCkgJiYKLSAgICAgICAgICAgICAgICBwcm9wZXJ0eUlkLmVuZHNXaXRoKENvbnN0YW50cy5FUlJPUl9SRVBPUlRFUl9QUk9QRVJUWSkpIHsKLSAgICAgICAgICAgICAgICBmRXJyb3JSZXBvcnRlciA9IChYTUxFcnJvclJlcG9ydGVyKXZhbHVlOwotICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChzdWZmaXhMZW5ndGggPT0gQ29uc3RhbnRzLkVOVElUWV9SRVNPTFZFUl9QUk9QRVJUWS5sZW5ndGgoKSAmJgotICAgICAgICAgICAgICAgIHByb3BlcnR5SWQuZW5kc1dpdGgoQ29uc3RhbnRzLkVOVElUWV9SRVNPTFZFUl9QUk9QRVJUWSkpIHsKLSAgICAgICAgICAgICAgICBmRW50aXR5UmVzb2x2ZXIgPSAoWE1MRW50aXR5UmVzb2x2ZXIpdmFsdWU7Ci0gICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKHN1ZmZpeExlbmd0aCA9PSBDb25zdGFudHMuQlVGRkVSX1NJWkVfUFJPUEVSVFkubGVuZ3RoKCkgJiYKLSAgICAgICAgICAgICAgICBwcm9wZXJ0eUlkLmVuZHNXaXRoKENvbnN0YW50cy5CVUZGRVJfU0laRV9QUk9QRVJUWSkpIHsKLSAgICAgICAgICAgICAgICBJbnRlZ2VyIGJ1ZmZlclNpemUgPSAoSW50ZWdlcil2YWx1ZTsKLSAgICAgICAgICAgICAgICBpZiAoYnVmZmVyU2l6ZSAhPSBudWxsICYmCi0gICAgICAgICAgICAgICAgICAgIGJ1ZmZlclNpemUuaW50VmFsdWUoKSA+IERFRkFVTFRfWE1MREVDTF9CVUZGRVJfU0laRSkgewotICAgICAgICAgICAgICAgICAgICBmQnVmZmVyU2l6ZSA9IGJ1ZmZlclNpemUuaW50VmFsdWUoKTsKLSAgICAgICAgICAgICAgICAgICAgZkVudGl0eVNjYW5uZXIuc2V0QnVmZmVyU2l6ZShmQnVmZmVyU2l6ZSk7Ci0gICAgICAgICAgICAgICAgICAgIGZCdWZmZXJQb29sLnNldEV4dGVybmFsQnVmZmVyU2l6ZShmQnVmZmVyU2l6ZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKHN1ZmZpeExlbmd0aCA9PSBDb25zdGFudHMuU0VDVVJJVFlfTUFOQUdFUl9QUk9QRVJUWS5sZW5ndGgoKSAmJgotICAgICAgICAgICAgICAgIHByb3BlcnR5SWQuZW5kc1dpdGgoQ29uc3RhbnRzLlNFQ1VSSVRZX01BTkFHRVJfUFJPUEVSVFkpKSB7Ci0gICAgICAgICAgICAgICAgZlNlY3VyaXR5TWFuYWdlciA9IChYTUxTZWN1cml0eU1hbmFnZXIpdmFsdWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvL0pBWFAgMS41IHByb3BlcnRpZXMKLSAgICAgICAgaWYgKHByb3BlcnR5SWQuZXF1YWxzKFhNTF9TRUNVUklUWV9QUk9QRVJUWV9NQU5BR0VSKSkKLSAgICAgICAgewotICAgICAgICAgICAgWE1MU2VjdXJpdHlQcm9wZXJ0eU1hbmFnZXIgc3BtID0gKFhNTFNlY3VyaXR5UHJvcGVydHlNYW5hZ2VyKXZhbHVlOwotICAgICAgICAgICAgZkFjY2Vzc0V4dGVybmFsRFREID0gc3BtLmdldFZhbHVlKFhNTFNlY3VyaXR5UHJvcGVydHlNYW5hZ2VyLlByb3BlcnR5LkFDQ0VTU19FWFRFUk5BTF9EVEQpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0TGltaXRBbmFseXplcihYTUxMaW1pdEFuYWx5emVyIGZMaW1pdEFuYWx5emVyKSB7Ci0gICAgICAgIHRoaXMuZkxpbWl0QW5hbHl6ZXIgPSBmTGltaXRBbmFseXplcjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGEgbGlzdCBvZiBwcm9wZXJ0eSBpZGVudGlmaWVycyB0aGF0IGFyZSByZWNvZ25pemVkIGJ5Ci0gICAgICogdGhpcyBjb21wb25lbnQuIFRoaXMgbWV0aG9kIG1heSByZXR1cm4gbnVsbCBpZiBubyBwcm9wZXJ0aWVzCi0gICAgICogYXJlIHJlY29nbml6ZWQgYnkgdGhpcyBjb21wb25lbnQuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZ1tdIGdldFJlY29nbml6ZWRQcm9wZXJ0aWVzKCkgewotICAgICAgICByZXR1cm4gKFN0cmluZ1tdKShSRUNPR05JWkVEX1BST1BFUlRJRVMuY2xvbmUoKSk7Ci0gICAgfSAvLyBnZXRSZWNvZ25pemVkUHJvcGVydGllcygpOlN0cmluZ1tdCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgZGVmYXVsdCBzdGF0ZSBmb3IgYSBmZWF0dXJlLCBvciBudWxsIGlmIHRoaXMKLSAgICAgKiBjb21wb25lbnQgZG9lcyBub3Qgd2FudCB0byByZXBvcnQgYSBkZWZhdWx0IHZhbHVlIGZvciB0aGlzCi0gICAgICogZmVhdHVyZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBmZWF0dXJlSWQgVGhlIGZlYXR1cmUgaWRlbnRpZmllci4KLSAgICAgKgotICAgICAqIEBzaW5jZSBYZXJjZXMgMi4yLjAKLSAgICAgKi8KLSAgICBwdWJsaWMgQm9vbGVhbiBnZXRGZWF0dXJlRGVmYXVsdChTdHJpbmcgZmVhdHVyZUlkKSB7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgUkVDT0dOSVpFRF9GRUFUVVJFUy5sZW5ndGg7IGkrKykgewotICAgICAgICAgICAgaWYgKFJFQ09HTklaRURfRkVBVFVSRVNbaV0uZXF1YWxzKGZlYXR1cmVJZCkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gRkVBVFVSRV9ERUZBVUxUU1tpXTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9IC8vIGdldEZlYXR1cmVEZWZhdWx0KFN0cmluZyk6Qm9vbGVhbgotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgZGVmYXVsdCBzdGF0ZSBmb3IgYSBwcm9wZXJ0eSwgb3IgbnVsbCBpZiB0aGlzCi0gICAgICogY29tcG9uZW50IGRvZXMgbm90IHdhbnQgdG8gcmVwb3J0IGEgZGVmYXVsdCB2YWx1ZSBmb3IgdGhpcwotICAgICAqIHByb3BlcnR5LgotICAgICAqCi0gICAgICogQHBhcmFtIHByb3BlcnR5SWQgVGhlIHByb3BlcnR5IGlkZW50aWZpZXIuCi0gICAgICoKLSAgICAgKiBAc2luY2UgWGVyY2VzIDIuMi4wCi0gICAgICovCi0gICAgcHVibGljIE9iamVjdCBnZXRQcm9wZXJ0eURlZmF1bHQoU3RyaW5nIHByb3BlcnR5SWQpIHsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBSRUNPR05JWkVEX1BST1BFUlRJRVMubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgIGlmIChSRUNPR05JWkVEX1BST1BFUlRJRVNbaV0uZXF1YWxzKHByb3BlcnR5SWQpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIFBST1BFUlRZX0RFRkFVTFRTW2ldOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0gLy8gZ2V0UHJvcGVydHlEZWZhdWx0KFN0cmluZyk6T2JqZWN0Ci0KLSAgICAvLwotICAgIC8vIFB1YmxpYyBzdGF0aWMgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBFeHBhbmRzIGEgc3lzdGVtIGlkIGFuZCByZXR1cm5zIHRoZSBzeXN0ZW0gaWQgYXMgYSBVUkksIGlmCi0gICAgICogaXQgY2FuIGJlIGV4cGFuZGVkLiBBIHJldHVybiB2YWx1ZSBvZiBudWxsIG1lYW5zIHRoYXQgdGhlCi0gICAgICogaWRlbnRpZmllciBpcyBhbHJlYWR5IGV4cGFuZGVkLiBBbiBleGNlcHRpb24gdGhyb3duCi0gICAgICogaW5kaWNhdGVzIGEgZmFpbHVyZSB0byBleHBhbmQgdGhlIGlkLgotICAgICAqCi0gICAgICogQHBhcmFtIHN5c3RlbUlkIFRoZSBzeXN0ZW1JZCB0byBiZSBleHBhbmRlZC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gUmV0dXJucyB0aGUgVVJJIHN0cmluZyByZXByZXNlbnRpbmcgdGhlIGV4cGFuZGVkIHN5c3RlbQotICAgICAqICAgICAgICAgaWRlbnRpZmllci4gQSBudWxsIHZhbHVlIGluZGljYXRlcyB0aGF0IHRoZSBnaXZlbgotICAgICAqICAgICAgICAgc3lzdGVtIGlkZW50aWZpZXIgaXMgYWxyZWFkeSBleHBhbmRlZC4KLSAgICAgKgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGV4cGFuZFN5c3RlbUlkKFN0cmluZyBzeXN0ZW1JZCkgewotICAgICAgICByZXR1cm4gZXhwYW5kU3lzdGVtSWQoc3lzdGVtSWQsIG51bGwpOwotICAgIH0gLy8gZXhwYW5kU3lzdGVtSWQoU3RyaW5nKTpTdHJpbmcKLQotICAgIC8vCi0gICAgLy8gUHVibGljIHN0YXRpYyBtZXRob2RzCi0gICAgLy8KLQotICAgIC8vIGN1cnJlbnQgdmFsdWUgb2YgdGhlICJ1c2VyLmRpciIgcHJvcGVydHkKLSAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgZ1VzZXJEaXI7Ci0gICAgLy8gY2FjaGVkIFVSSSBvYmplY3QgZm9yIHRoZSBjdXJyZW50IHZhbHVlIG9mIHRoZSBlc2NhcGVkICJ1c2VyLmRpciIgcHJvcGVydHkgc3RvcmVkIGFzIGEgVVJJCi0gICAgcHJpdmF0ZSBzdGF0aWMgVVJJIGdVc2VyRGlyVVJJOwotICAgIC8vIHdoaWNoIEFTQ0lJIGNoYXJhY3RlcnMgbmVlZCB0byBiZSBlc2NhcGVkCi0gICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBnTmVlZEVzY2FwaW5nW10gPSBuZXcgYm9vbGVhblsxMjhdOwotICAgIC8vIHRoZSBmaXJzdCBoZXggY2hhcmFjdGVyIGlmIGEgY2hhcmFjdGVyIG5lZWRzIHRvIGJlIGVzY2FwZWQKLSAgICBwcml2YXRlIHN0YXRpYyBjaGFyIGdBZnRlckVzY2FwaW5nMVtdID0gbmV3IGNoYXJbMTI4XTsKLSAgICAvLyB0aGUgc2Vjb25kIGhleCBjaGFyYWN0ZXIgaWYgYSBjaGFyYWN0ZXIgbmVlZHMgdG8gYmUgZXNjYXBlZAotICAgIHByaXZhdGUgc3RhdGljIGNoYXIgZ0FmdGVyRXNjYXBpbmcyW10gPSBuZXcgY2hhclsxMjhdOwotICAgIHByaXZhdGUgc3RhdGljIGNoYXJbXSBnSGV4Q2hzID0geycwJywgJzEnLCAnMicsICczJywgJzQnLCAnNScsICc2JywgJzcnLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICc4JywgJzknLCAnQScsICdCJywgJ0MnLCAnRCcsICdFJywgJ0YnfTsKLSAgICAvLyBpbml0aWFsaXplIHRoZSBhYm92ZSAzIGFycmF5cwotICAgIHN0YXRpYyB7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDw9IDB4MWY7IGkrKykgewotICAgICAgICAgICAgZ05lZWRFc2NhcGluZ1tpXSA9IHRydWU7Ci0gICAgICAgICAgICBnQWZ0ZXJFc2NhcGluZzFbaV0gPSBnSGV4Q2hzW2kgPj4gNF07Ci0gICAgICAgICAgICBnQWZ0ZXJFc2NhcGluZzJbaV0gPSBnSGV4Q2hzW2kgJiAweGZdOwotICAgICAgICB9Ci0gICAgICAgIGdOZWVkRXNjYXBpbmdbMHg3Zl0gPSB0cnVlOwotICAgICAgICBnQWZ0ZXJFc2NhcGluZzFbMHg3Zl0gPSAnNyc7Ci0gICAgICAgIGdBZnRlckVzY2FwaW5nMlsweDdmXSA9ICdGJzsKLSAgICAgICAgY2hhcltdIGVzY0NocyA9IHsnICcsICc8JywgJz4nLCAnIycsICclJywgJyInLCAneycsICd9JywKLSAgICAgICAgICAgICAgICAgICAgICAgICAnfCcsICdcXCcsICdeJywgJ34nLCAnWycsICddJywgJ2AnfTsKLSAgICAgICAgaW50IGxlbiA9IGVzY0Nocy5sZW5ndGg7Ci0gICAgICAgIGNoYXIgY2g7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKLSAgICAgICAgICAgIGNoID0gZXNjQ2hzW2ldOwotICAgICAgICAgICAgZ05lZWRFc2NhcGluZ1tjaF0gPSB0cnVlOwotICAgICAgICAgICAgZ0FmdGVyRXNjYXBpbmcxW2NoXSA9IGdIZXhDaHNbY2ggPj4gNF07Ci0gICAgICAgICAgICBnQWZ0ZXJFc2NhcGluZzJbY2hdID0gZ0hleENoc1tjaCAmIDB4Zl07Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvLyBUbyBlc2NhcGUgdGhlICJ1c2VyLmRpciIgc3lzdGVtIHByb3BlcnR5LCBieSB1c2luZyAlSEggdG8gcmVwcmVzZW50Ci0gICAgLy8gc3BlY2lhbCBBU0NJSSBjaGFyYWN0ZXJzOiAweDAwfjB4MUYsIDB4N0YsICcgJywgJzwnLCAnPicsICcjJywgJyUnCi0gICAgLy8gYW5kICciJy4gSXQncyBhIHN0YXRpYyBtZXRob2QsIHNvIG5lZWRzIHRvIGJlIHN5bmNocm9uaXplZC4KLSAgICAvLyB0aGlzIG1ldGhvZCBsb29rcyBoZWF2eSwgYnV0IHNpbmNlIHRoZSBzeXN0ZW0gcHJvcGVydHkgaXNuJ3QgZXhwZWN0ZWQKLSAgICAvLyB0byBjaGFuZ2Ugb2Z0ZW4sIHNvIGluIG1vc3QgY2FzZXMsIHdlIG9ubHkgbmVlZCB0byByZXR1cm4gdGhlIFVSSQotICAgIC8vIHRoYXQgd2FzIGVzY2FwZWQgYmVmb3JlLgotICAgIC8vIEFjY29yZGluZyB0byB0aGUgVVJJIHNwZWMsIG5vbi1BU0NJSSBjaGFyYWN0ZXJzICh3aG9zZSB2YWx1ZSA+PSAxMjgpCi0gICAgLy8gbmVlZCB0byBiZSBlc2NhcGVkIHRvby4KLSAgICAvLyBSRVZJU0lUOiBkb24ndCBrbm93IGhvdyB0byBlc2NhcGUgbm9uLUFTQ0lJIGNoYXJhY3RlcnMsIGVzcGVjaWFsbHkKLSAgICAvLyB3aGljaCBlbmNvZGluZyB0byB1c2UuIExlYXZlIHRoZW0gZm9yIG5vdy4KLSAgICBwcml2YXRlIHN0YXRpYyBzeW5jaHJvbml6ZWQgVVJJIGdldFVzZXJEaXIoKSB0aHJvd3MgVVJJLk1hbGZvcm1lZFVSSUV4Y2VwdGlvbiB7Ci0gICAgICAgIC8vIGdldCB0aGUgdXNlci5kaXIgcHJvcGVydHkKLSAgICAgICAgU3RyaW5nIHVzZXJEaXIgPSAiIjsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIHVzZXJEaXIgPSBTZWN1cml0eVN1cHBvcnQuZ2V0U3lzdGVtUHJvcGVydHkoInVzZXIuZGlyIik7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIHNlKSB7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyByZXR1cm4gZW1wdHkgc3RyaW5nIGlmIHByb3BlcnR5IHZhbHVlIGlzIGVtcHR5IHN0cmluZy4KLSAgICAgICAgaWYgKHVzZXJEaXIubGVuZ3RoKCkgPT0gMCkKLSAgICAgICAgICAgIHJldHVybiBuZXcgVVJJKCJmaWxlIiwgIiIsICIiLCBudWxsLCBudWxsKTsKLSAgICAgICAgLy8gY29tcHV0ZSB0aGUgbmV3IGVzY2FwZWQgdmFsdWUgaWYgdGhlIG5ldyBwcm9wZXJ0eSB2YWx1ZSBkb2Vzbid0Ci0gICAgICAgIC8vIG1hdGNoIHRoZSBwcmV2aW91cyBvbmUKLSAgICAgICAgaWYgKGdVc2VyRGlyVVJJICE9IG51bGwgJiYgdXNlckRpci5lcXVhbHMoZ1VzZXJEaXIpKSB7Ci0gICAgICAgICAgICByZXR1cm4gZ1VzZXJEaXJVUkk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyByZWNvcmQgdGhlIG5ldyB2YWx1ZSBhcyB0aGUgZ2xvYmFsIHByb3BlcnR5IHZhbHVlCi0gICAgICAgIGdVc2VyRGlyID0gdXNlckRpcjsKLQotICAgICAgICBjaGFyIHNlcGFyYXRvciA9IGphdmEuaW8uRmlsZS5zZXBhcmF0b3JDaGFyOwotICAgICAgICB1c2VyRGlyID0gdXNlckRpci5yZXBsYWNlKHNlcGFyYXRvciwgJy8nKTsKLQotICAgICAgICBpbnQgbGVuID0gdXNlckRpci5sZW5ndGgoKSwgY2g7Ci0gICAgICAgIFN0cmluZ0J1ZmZlciBidWZmZXIgPSBuZXcgU3RyaW5nQnVmZmVyKGxlbiozKTsKLSAgICAgICAgLy8gY2hhbmdlIEM6L2JsYWggdG8gL0M6L2JsYWgKLSAgICAgICAgaWYgKGxlbiA+PSAyICYmIHVzZXJEaXIuY2hhckF0KDEpID09ICc6JykgewotICAgICAgICAgICAgY2ggPSBDaGFyYWN0ZXIudG9VcHBlckNhc2UodXNlckRpci5jaGFyQXQoMCkpOwotICAgICAgICAgICAgaWYgKGNoID49ICdBJyAmJiBjaCA8PSAnWicpIHsKLSAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCcvJyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBmb3IgZWFjaCBjaGFyYWN0ZXIgaW4gdGhlIHBhdGgKLSAgICAgICAgaW50IGkgPSAwOwotICAgICAgICBmb3IgKDsgaSA8IGxlbjsgaSsrKSB7Ci0gICAgICAgICAgICBjaCA9IHVzZXJEaXIuY2hhckF0KGkpOwotICAgICAgICAgICAgLy8gaWYgaXQncyBub3QgYW4gQVNDSUkgY2hhcmFjdGVyLCBicmVhayBoZXJlLCBhbmQgdXNlIFVURi04IGVuY29kaW5nCi0gICAgICAgICAgICBpZiAoY2ggPj0gMTI4KQotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgaWYgKGdOZWVkRXNjYXBpbmdbY2hdKSB7Ci0gICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgnJScpOwotICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoZ0FmdGVyRXNjYXBpbmcxW2NoXSk7Ci0gICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZChnQWZ0ZXJFc2NhcGluZzJbY2hdKTsKLSAgICAgICAgICAgICAgICAvLyByZWNvcmQgdGhlIGZhY3QgdGhhdCBpdCdzIGVzY2FwZWQKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoKGNoYXIpY2gpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gd2Ugc2F3IHNvbWUgbm9uLWFzY2lpIGNoYXJhY3RlcgotICAgICAgICBpZiAoaSA8IGxlbikgewotICAgICAgICAgICAgLy8gZ2V0IFVURi04IGJ5dGVzIGZvciB0aGUgcmVtYWluaW5nIHN1Yi1zdHJpbmcKLSAgICAgICAgICAgIGJ5dGVbXSBieXRlcyA9IG51bGw7Ci0gICAgICAgICAgICBieXRlIGI7Ci0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIGJ5dGVzID0gdXNlckRpci5zdWJzdHJpbmcoaSkuZ2V0Qnl0ZXMoIlVURi04Iik7Ci0gICAgICAgICAgICB9IGNhdGNoIChqYXZhLmlvLlVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgIC8vIHNob3VsZCBuZXZlciBoYXBwZW4KLSAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFVSSSgiZmlsZSIsICIiLCB1c2VyRGlyLCBudWxsLCBudWxsKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGxlbiA9IGJ5dGVzLmxlbmd0aDsKLQotICAgICAgICAgICAgLy8gZm9yIGVhY2ggYnl0ZQotICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgYiA9IGJ5dGVzW2ldOwotICAgICAgICAgICAgICAgIC8vIGZvciBub24tYXNjaWkgY2hhcmFjdGVyOiBtYWtlIGl0IHBvc2l0aXZlLCB0aGVuIGVzY2FwZQotICAgICAgICAgICAgICAgIGlmIChiIDwgMCkgewotICAgICAgICAgICAgICAgICAgICBjaCA9IGIgKyAyNTY7Ci0gICAgICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoJyUnKTsKLSAgICAgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZChnSGV4Q2hzW2NoID4+IDRdKTsKLSAgICAgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZChnSGV4Q2hzW2NoICYgMHhmXSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgaWYgKGdOZWVkRXNjYXBpbmdbYl0pIHsKLSAgICAgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgnJScpOwotICAgICAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKGdBZnRlckVzY2FwaW5nMVtiXSk7Ci0gICAgICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoZ0FmdGVyRXNjYXBpbmcyW2JdKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoKGNoYXIpYik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gY2hhbmdlIGJsYWgvYmxhaCB0byBibGFoL2JsYWgvCi0gICAgICAgIGlmICghdXNlckRpci5lbmRzV2l0aCgiLyIpKQotICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgnLycpOwotCi0gICAgICAgIGdVc2VyRGlyVVJJID0gbmV3IFVSSSgiZmlsZSIsICIiLCBidWZmZXIudG9TdHJpbmcoKSwgbnVsbCwgbnVsbCk7Ci0KLSAgICAgICAgcmV0dXJuIGdVc2VyRGlyVVJJOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEFic29sdXRpemVzIGEgVVJJIHVzaW5nIHRoZSBjdXJyZW50IHZhbHVlCi0gICAgICogb2YgdGhlICJ1c2VyLmRpciIgcHJvcGVydHkgYXMgdGhlIGJhc2UgVVJJLiBJZgotICAgICAqIHRoZSBVUkkgaXMgYWxyZWFkeSBhYnNvbHV0ZSwgdGhpcyBpcyBhIG5vLW9wLgotICAgICAqCi0gICAgICogQHBhcmFtIHVyaSB0aGUgVVJJIHRvIGFic29sdXRpemUKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIHZvaWQgYWJzb2x1dGl6ZUFnYWluc3RVc2VyRGlyKFVSSSB1cmkpCi0gICAgICAgIHRocm93cyBVUkkuTWFsZm9ybWVkVVJJRXhjZXB0aW9uIHsKLSAgICAgICAgdXJpLmFic29sdXRpemUoZ2V0VXNlckRpcigpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBFeHBhbmRzIGEgc3lzdGVtIGlkIGFuZCByZXR1cm5zIHRoZSBzeXN0ZW0gaWQgYXMgYSBVUkksIGlmCi0gICAgICogaXQgY2FuIGJlIGV4cGFuZGVkLiBBIHJldHVybiB2YWx1ZSBvZiBudWxsIG1lYW5zIHRoYXQgdGhlCi0gICAgICogaWRlbnRpZmllciBpcyBhbHJlYWR5IGV4cGFuZGVkLiBBbiBleGNlcHRpb24gdGhyb3duCi0gICAgICogaW5kaWNhdGVzIGEgZmFpbHVyZSB0byBleHBhbmQgdGhlIGlkLgotICAgICAqCi0gICAgICogQHBhcmFtIHN5c3RlbUlkIFRoZSBzeXN0ZW1JZCB0byBiZSBleHBhbmRlZC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gUmV0dXJucyB0aGUgVVJJIHN0cmluZyByZXByZXNlbnRpbmcgdGhlIGV4cGFuZGVkIHN5c3RlbQotICAgICAqICAgICAgICAgaWRlbnRpZmllci4gQSBudWxsIHZhbHVlIGluZGljYXRlcyB0aGF0IHRoZSBnaXZlbgotICAgICAqICAgICAgICAgc3lzdGVtIGlkZW50aWZpZXIgaXMgYWxyZWFkeSBleHBhbmRlZC4KLSAgICAgKgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGV4cGFuZFN5c3RlbUlkKFN0cmluZyBzeXN0ZW1JZCwgU3RyaW5nIGJhc2VTeXN0ZW1JZCkgewotCi0gICAgICAgIC8vIGNoZWNrIGZvciBiYWQgcGFyYW1ldGVycyBpZAotICAgICAgICBpZiAoc3lzdGVtSWQgPT0gbnVsbCB8fCBzeXN0ZW1JZC5sZW5ndGgoKSA9PSAwKSB7Ci0gICAgICAgICAgICByZXR1cm4gc3lzdGVtSWQ7Ci0gICAgICAgIH0KLSAgICAgICAgLy8gaWYgaWQgYWxyZWFkeSBleHBhbmRlZCwgcmV0dXJuCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBVUkkgdXJpID0gbmV3IFVSSShzeXN0ZW1JZCk7Ci0gICAgICAgICAgICBpZiAodXJpICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gc3lzdGVtSWQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gY2F0Y2ggKFVSSS5NYWxmb3JtZWRVUklFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgLy8gY29udGludWUgb24uLi4KLSAgICAgICAgfQotICAgICAgICAvLyBub3JtYWxpemUgaWQKLSAgICAgICAgU3RyaW5nIGlkID0gZml4VVJJKHN5c3RlbUlkKTsKLQotICAgICAgICAvLyBub3JtYWxpemUgYmFzZQotICAgICAgICBVUkkgYmFzZSA9IG51bGw7Ci0gICAgICAgIFVSSSB1cmkgPSBudWxsOwotICAgICAgICB0cnkgewotICAgICAgICAgICAgaWYgKGJhc2VTeXN0ZW1JZCA9PSBudWxsIHx8IGJhc2VTeXN0ZW1JZC5sZW5ndGgoKSA9PSAwIHx8Ci0gICAgICAgICAgICAgICAgICAgIGJhc2VTeXN0ZW1JZC5lcXVhbHMoc3lzdGVtSWQpKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIGRpciA9IGdldFVzZXJEaXIoKS50b1N0cmluZygpOwotICAgICAgICAgICAgICAgIGJhc2UgPSBuZXcgVVJJKCJmaWxlIiwgIiIsIGRpciwgbnVsbCwgbnVsbCk7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgIGJhc2UgPSBuZXcgVVJJKGZpeFVSSShiYXNlU3lzdGVtSWQpKTsKLSAgICAgICAgICAgICAgICB9IGNhdGNoIChVUkkuTWFsZm9ybWVkVVJJRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGJhc2VTeXN0ZW1JZC5pbmRleE9mKCc6JykgIT0gLTEpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZvciB4bWwgc2NoZW1hcyB3ZSBtaWdodCBoYXZlIGJhc2VVUkkgd2l0aAotICAgICAgICAgICAgICAgICAgICAgICAgLy8gYSBzcGVjaWZpZWQgZHJpdmUKLSAgICAgICAgICAgICAgICAgICAgICAgIGJhc2UgPSBuZXcgVVJJKCJmaWxlIiwgIiIsIGZpeFVSSShiYXNlU3lzdGVtSWQpLCBudWxsLCBudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBkaXIgPSBnZXRVc2VyRGlyKCkudG9TdHJpbmcoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGRpciA9IGRpciArIGZpeFVSSShiYXNlU3lzdGVtSWQpOwotICAgICAgICAgICAgICAgICAgICAgICAgYmFzZSA9IG5ldyBVUkkoImZpbGUiLCAiIiwgZGlyLCBudWxsLCBudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIGV4cGFuZCBpZAotICAgICAgICAgICAgdXJpID0gbmV3IFVSSShiYXNlLCBpZCk7Ci0gICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAvLyBsZXQgaXQgZ28gdGhyb3VnaAotCi0gICAgICAgIH0KLQotICAgICAgICBpZiAodXJpID09IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBzeXN0ZW1JZDsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gdXJpLnRvU3RyaW5nKCk7Ci0KLSAgICB9IC8vIGV4cGFuZFN5c3RlbUlkKFN0cmluZyxTdHJpbmcpOlN0cmluZwotCi0gICAgLyoqCi0gICAgICogRXhwYW5kcyBhIHN5c3RlbSBpZCBhbmQgcmV0dXJucyB0aGUgc3lzdGVtIGlkIGFzIGEgVVJJLCBpZgotICAgICAqIGl0IGNhbiBiZSBleHBhbmRlZC4gQSByZXR1cm4gdmFsdWUgb2YgbnVsbCBtZWFucyB0aGF0IHRoZQotICAgICAqIGlkZW50aWZpZXIgaXMgYWxyZWFkeSBleHBhbmRlZC4gQW4gZXhjZXB0aW9uIHRocm93bgotICAgICAqIGluZGljYXRlcyBhIGZhaWx1cmUgdG8gZXhwYW5kIHRoZSBpZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzeXN0ZW1JZCBUaGUgc3lzdGVtSWQgdG8gYmUgZXhwYW5kZWQuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFJldHVybnMgdGhlIFVSSSBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBleHBhbmRlZCBzeXN0ZW0KLSAgICAgKiAgICAgICAgIGlkZW50aWZpZXIuIEEgbnVsbCB2YWx1ZSBpbmRpY2F0ZXMgdGhhdCB0aGUgZ2l2ZW4KLSAgICAgKiAgICAgICAgIHN5c3RlbSBpZGVudGlmaWVyIGlzIGFscmVhZHkgZXhwYW5kZWQuCi0gICAgICoKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBleHBhbmRTeXN0ZW1JZChTdHJpbmcgc3lzdGVtSWQsIFN0cmluZyBiYXNlU3lzdGVtSWQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBzdHJpY3QpCi0gICAgICAgICAgICB0aHJvd3MgVVJJLk1hbGZvcm1lZFVSSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy8gY2hlY2sgaWYgdGhlcmUgaXMgYSBzeXN0ZW0gaWQgYmVmb3JlCi0gICAgICAgIC8vIHRyeWluZyB0byBleHBhbmQgaXQuCi0gICAgICAgIGlmIChzeXN0ZW1JZCA9PSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIHN5c3RlbSBpZCBoYXMgdG8gYmUgYSB2YWxpZCBVUkkKLSAgICAgICAgaWYgKHN0cmljdCkgewotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAvLyBpZiBpdCdzIGFscmVhZHkgYW4gYWJzb2x1dGUgb25lLCByZXR1cm4gaXQKLSAgICAgICAgICAgICAgICBuZXcgVVJJKHN5c3RlbUlkKTsKLSAgICAgICAgICAgICAgICByZXR1cm4gc3lzdGVtSWQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXRjaCAoVVJJLk1hbGZvcm1lZFVSSUV4Y2VwdGlvbiBleCkgewotICAgICAgICAgICAgfQotICAgICAgICAgICAgVVJJIGJhc2UgPSBudWxsOwotICAgICAgICAgICAgLy8gaWYgdGhlcmUgaXNuJ3QgYSBiYXNlIHVyaSwgdXNlIHRoZSB3b3JraW5nIGRpcmVjdG9yeQotICAgICAgICAgICAgaWYgKGJhc2VTeXN0ZW1JZCA9PSBudWxsIHx8IGJhc2VTeXN0ZW1JZC5sZW5ndGgoKSA9PSAwKSB7Ci0gICAgICAgICAgICAgICAgYmFzZSA9IG5ldyBVUkkoImZpbGUiLCAiIiwgZ2V0VXNlckRpcigpLnRvU3RyaW5nKCksIG51bGwsIG51bGwpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gb3RoZXJ3aXNlLCB1c2UgdGhlIGJhc2UgdXJpCi0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICBiYXNlID0gbmV3IFVSSShiYXNlU3lzdGVtSWQpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBjYXRjaCAoVVJJLk1hbGZvcm1lZFVSSUV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIGFzc3VtZSAiYmFzZSIgaXMgYWxzbyBhIHJlbGF0aXZlIHVyaQotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgZGlyID0gZ2V0VXNlckRpcigpLnRvU3RyaW5nKCk7Ci0gICAgICAgICAgICAgICAgICAgIGRpciA9IGRpciArIGJhc2VTeXN0ZW1JZDsKLSAgICAgICAgICAgICAgICAgICAgYmFzZSA9IG5ldyBVUkkoImZpbGUiLCAiIiwgZGlyLCBudWxsLCBudWxsKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyBhYnNvbHV0aXplIHRoZSBzeXN0ZW0gaWQgdXNpbmcgdGhlIGJhc2UKLSAgICAgICAgICAgIFVSSSB1cmkgPSBuZXcgVVJJKGJhc2UsIHN5c3RlbUlkKTsKLSAgICAgICAgICAgIC8vIHJldHVybiB0aGUgc3RyaW5nIHJlcCBvZiB0aGUgbmV3IHVyaSAoYW4gYWJzb2x1dGUgb25lKQotICAgICAgICAgICAgcmV0dXJuIHVyaS50b1N0cmluZygpOwotCi0gICAgICAgICAgICAvLyBpZiBhbnkgZXhjZXB0aW9uIGlzIHRocm93biwgaXQnbGwgZ2V0IHRocm93biB0byB0aGUgY2FsbGVyLgotICAgICAgICB9Ci0KLSAgICAgICAgLy8gQXNzdW1lIHRoZSBVUklzIGFyZSB3ZWxsLWZvcm1lZC4gSWYgaXQgdHVybnMgb3V0IHRoZXkncmUgbm90LCB0cnkgZml4aW5nIHRoZW0gdXAuCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgcmV0dXJuIGV4cGFuZFN5c3RlbUlkU3RyaWN0T2ZmKHN5c3RlbUlkLCBiYXNlU3lzdGVtSWQpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChVUkkuTWFsZm9ybWVkVVJJRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIC8qKiBYZXJjZXMgVVJJIHJlamVjdHMgdW5pY29kZSwgdHJ5IGphdmEubmV0LlVSSQotICAgICAgICAgICAgICogdGhpcyBpcyBub3QgaWRlYWwgc29sdXRpb24sIGJ1dCBpdCBjb3ZlcnMga25vd24gY2FzZXMgd2hpY2ggZWl0aGVyCi0gICAgICAgICAgICAgKiBYZXJjZXMgVVJJIG9yIGphdmEubmV0LlVSSSBjYW4gaGFuZGxlIGFsb25lCi0gICAgICAgICAgICAgKiB3aWxsIGZpbGUgYnVnIGFnYWluc3QgamF2YS5uZXQuVVJJCi0gICAgICAgICAgICAgKi8KLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGV4cGFuZFN5c3RlbUlkU3RyaWN0T2ZmMShzeXN0ZW1JZCwgYmFzZVN5c3RlbUlkKTsKLSAgICAgICAgICAgIH0gY2F0Y2ggKFVSSVN5bnRheEV4Y2VwdGlvbiBleCkgewotICAgICAgICAgICAgICAgIC8vIGNvbnRpbnVlIG9uLi4uCi0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgLy8gY2hlY2sgZm9yIGJhZCBwYXJhbWV0ZXJzIGlkCi0gICAgICAgIGlmIChzeXN0ZW1JZC5sZW5ndGgoKSA9PSAwKSB7Ci0gICAgICAgICAgICByZXR1cm4gc3lzdGVtSWQ7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBub3JtYWxpemUgaWQKLSAgICAgICAgU3RyaW5nIGlkID0gZml4VVJJKHN5c3RlbUlkKTsKLQotICAgICAgICAvLyBub3JtYWxpemUgYmFzZQotICAgICAgICBVUkkgYmFzZSA9IG51bGw7Ci0gICAgICAgIFVSSSB1cmkgPSBudWxsOwotICAgICAgICB0cnkgewotICAgICAgICAgICAgaWYgKGJhc2VTeXN0ZW1JZCA9PSBudWxsIHx8IGJhc2VTeXN0ZW1JZC5sZW5ndGgoKSA9PSAwIHx8Ci0gICAgICAgICAgICAgICAgYmFzZVN5c3RlbUlkLmVxdWFscyhzeXN0ZW1JZCkpIHsKLSAgICAgICAgICAgICAgICBiYXNlID0gZ2V0VXNlckRpcigpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgYmFzZSA9IG5ldyBVUkkoZml4VVJJKGJhc2VTeXN0ZW1JZCkudHJpbSgpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgY2F0Y2ggKFVSSS5NYWxmb3JtZWRVUklFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgICAgICBpZiAoYmFzZVN5c3RlbUlkLmluZGV4T2YoJzonKSAhPSAtMSkgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gZm9yIHhtbCBzY2hlbWFzIHdlIG1pZ2h0IGhhdmUgYmFzZVVSSSB3aXRoCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBhIHNwZWNpZmllZCBkcml2ZQotICAgICAgICAgICAgICAgICAgICAgICAgYmFzZSA9IG5ldyBVUkkoImZpbGUiLCAiIiwgZml4VVJJKGJhc2VTeXN0ZW1JZCkudHJpbSgpLCBudWxsLCBudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJhc2UgPSBuZXcgVVJJKGdldFVzZXJEaXIoKSwgZml4VVJJKGJhc2VTeXN0ZW1JZCkpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAvLyBleHBhbmQgaWQKLSAgICAgICAgICAgICB1cmkgPSBuZXcgVVJJKGJhc2UsIGlkLnRyaW0oKSk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAvLyBsZXQgaXQgZ28gdGhyb3VnaAotCi0gICAgICAgIH0KLQotICAgICAgICBpZiAodXJpID09IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBzeXN0ZW1JZDsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gdXJpLnRvU3RyaW5nKCk7Ci0KLSAgICB9IC8vIGV4cGFuZFN5c3RlbUlkKFN0cmluZyxTdHJpbmcsYm9vbGVhbik6U3RyaW5nCi0KLSAgICAvKioKLSAgICAgKiBIZWxwZXIgbWV0aG9kIGZvciBleHBhbmRTeXN0ZW1JZChTdHJpbmcsU3RyaW5nLGJvb2xlYW4pOlN0cmluZwotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBleHBhbmRTeXN0ZW1JZFN0cmljdE9uKFN0cmluZyBzeXN0ZW1JZCwgU3RyaW5nIGJhc2VTeXN0ZW1JZCkKLSAgICAgICAgdGhyb3dzIFVSSS5NYWxmb3JtZWRVUklFeGNlcHRpb24gewotCi0gICAgICAgIFVSSSBzeXN0ZW1VUkkgPSBuZXcgVVJJKHN5c3RlbUlkLCB0cnVlKTsKLSAgICAgICAgLy8gSWYgaXQncyBhbHJlYWR5IGFuIGFic29sdXRlIG9uZSwgcmV0dXJuIGl0Ci0gICAgICAgIGlmIChzeXN0ZW1VUkkuaXNBYnNvbHV0ZVVSSSgpKSB7Ci0gICAgICAgICAgICByZXR1cm4gc3lzdGVtSWQ7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBJZiB0aGVyZSBpc24ndCBhIGJhc2UgVVJJLCB1c2UgdGhlIHdvcmtpbmcgZGlyZWN0b3J5Ci0gICAgICAgIFVSSSBiYXNlVVJJID0gbnVsbDsKLSAgICAgICAgaWYgKGJhc2VTeXN0ZW1JZCA9PSBudWxsIHx8IGJhc2VTeXN0ZW1JZC5sZW5ndGgoKSA9PSAwKSB7Ci0gICAgICAgICAgICBiYXNlVVJJID0gZ2V0VXNlckRpcigpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgYmFzZVVSSSA9IG5ldyBVUkkoYmFzZVN5c3RlbUlkLCB0cnVlKTsKLSAgICAgICAgICAgIGlmICghYmFzZVVSSS5pc0Fic29sdXRlVVJJKCkpIHsKLSAgICAgICAgICAgICAgICAvLyBhc3N1bWUgImJhc2UiIGlzIGFsc28gYSByZWxhdGl2ZSB1cmkKLSAgICAgICAgICAgICAgICBiYXNlVVJJLmFic29sdXRpemUoZ2V0VXNlckRpcigpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIGFic29sdXRpemUgdGhlIHN5c3RlbSBpZGVudGlmaWVyIHVzaW5nIHRoZSBiYXNlIFVSSQotICAgICAgICBzeXN0ZW1VUkkuYWJzb2x1dGl6ZShiYXNlVVJJKTsKLQotICAgICAgICAvLyByZXR1cm4gdGhlIHN0cmluZyByZXAgb2YgdGhlIG5ldyB1cmkgKGFuIGFic29sdXRlIG9uZSkKLSAgICAgICAgcmV0dXJuIHN5c3RlbVVSSS50b1N0cmluZygpOwotCi0gICAgICAgIC8vIGlmIGFueSBleGNlcHRpb24gaXMgdGhyb3duLCBpdCdsbCBnZXQgdGhyb3duIHRvIHRoZSBjYWxsZXIuCi0KLSAgICB9IC8vIGV4cGFuZFN5c3RlbUlkU3RyaWN0T24oU3RyaW5nLFN0cmluZyk6U3RyaW5nCi0KLSAgICAvKioKLSAgICAgKiBBdHRlbXB0IHRvIHNldCB3aGV0aGVyIHJlZGlyZWN0cyB3aWxsIGJlIGZvbGxvd2VkIGZvciBhbiA8Y29kZT5IdHRwVVJMQ29ubmVjdGlvbjwvY29kZT4uCi0gICAgICogVGhpcyBtYXkgZmFpbCBvbiBlYXJsaWVyIEpES3Mgd2hpY2ggZG8gbm90IHN1cHBvcnQgc2V0dGluZyB0aGlzIHByZWZlcmVuY2UuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyB2b2lkIHNldEluc3RhbmNlRm9sbG93UmVkaXJlY3RzKEh0dHBVUkxDb25uZWN0aW9uIHVybENvbiwgYm9vbGVhbiBmb2xsb3dSZWRpcmVjdHMpIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIE1ldGhvZCBtZXRob2QgPSBIdHRwVVJMQ29ubmVjdGlvbi5jbGFzcy5nZXRNZXRob2QoInNldEluc3RhbmNlRm9sbG93UmVkaXJlY3RzIiwgbmV3IENsYXNzW10ge0Jvb2xlYW4uVFlQRX0pOwotICAgICAgICAgICAgbWV0aG9kLmludm9rZSh1cmxDb24sIG5ldyBPYmplY3RbXSB7Zm9sbG93UmVkaXJlY3RzID8gQm9vbGVhbi5UUlVFIDogQm9vbGVhbi5GQUxTRX0pOwotICAgICAgICB9Ci0gICAgICAgIC8vIHNldEluc3RhbmNlRm9sbG93UmVkaXJlY3RzIGRvZXNuJ3QgZXhpc3QuCi0gICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXhjKSB7fQotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogSGVscGVyIG1ldGhvZCBmb3IgZXhwYW5kU3lzdGVtSWQoU3RyaW5nLFN0cmluZyxib29sZWFuKTpTdHJpbmcKLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgZXhwYW5kU3lzdGVtSWRTdHJpY3RPZmYoU3RyaW5nIHN5c3RlbUlkLCBTdHJpbmcgYmFzZVN5c3RlbUlkKQotICAgICAgICB0aHJvd3MgVVJJLk1hbGZvcm1lZFVSSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgVVJJIHN5c3RlbVVSSSA9IG5ldyBVUkkoc3lzdGVtSWQsIHRydWUpOwotICAgICAgICAvLyBJZiBpdCdzIGFscmVhZHkgYW4gYWJzb2x1dGUgb25lLCByZXR1cm4gaXQKLSAgICAgICAgaWYgKHN5c3RlbVVSSS5pc0Fic29sdXRlVVJJKCkpIHsKLSAgICAgICAgICAgIGlmIChzeXN0ZW1VUkkuZ2V0U2NoZW1lKCkubGVuZ3RoKCkgPiAxKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHN5c3RlbUlkOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLyoqCi0gICAgICAgICAgICAgKiBJZiB0aGUgc2NoZW1lJ3MgbGVuZ3RoIGlzIG9ubHkgb25lIGNoYXJhY3RlciwKLSAgICAgICAgICAgICAqIGl0J3MgbGlrZWx5IHRoYXQgdGhpcyB3YXMgaW50ZW5kZWQgYXMgYSBmaWxlCi0gICAgICAgICAgICAgKiBwYXRoLiBGaXhpbmcgdGhpcyB1cCBpbiBleHBhbmRTeXN0ZW1JZCB0bwotICAgICAgICAgICAgICogbWFpbnRhaW4gYmFja3dhcmRzIGNvbXBhdGliaWxpdHkuCi0gICAgICAgICAgICAgKi8KLSAgICAgICAgICAgIHRocm93IG5ldyBVUkkuTWFsZm9ybWVkVVJJRXhjZXB0aW9uKCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBJZiB0aGVyZSBpc24ndCBhIGJhc2UgVVJJLCB1c2UgdGhlIHdvcmtpbmcgZGlyZWN0b3J5Ci0gICAgICAgIFVSSSBiYXNlVVJJID0gbnVsbDsKLSAgICAgICAgaWYgKGJhc2VTeXN0ZW1JZCA9PSBudWxsIHx8IGJhc2VTeXN0ZW1JZC5sZW5ndGgoKSA9PSAwKSB7Ci0gICAgICAgICAgICBiYXNlVVJJID0gZ2V0VXNlckRpcigpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgYmFzZVVSSSA9IG5ldyBVUkkoYmFzZVN5c3RlbUlkLCB0cnVlKTsKLSAgICAgICAgICAgIGlmICghYmFzZVVSSS5pc0Fic29sdXRlVVJJKCkpIHsKLSAgICAgICAgICAgICAgICAvLyBhc3N1bWUgImJhc2UiIGlzIGFsc28gYSByZWxhdGl2ZSB1cmkKLSAgICAgICAgICAgICAgICBiYXNlVVJJLmFic29sdXRpemUoZ2V0VXNlckRpcigpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIGFic29sdXRpemUgdGhlIHN5c3RlbSBpZGVudGlmaWVyIHVzaW5nIHRoZSBiYXNlIFVSSQotICAgICAgICBzeXN0ZW1VUkkuYWJzb2x1dGl6ZShiYXNlVVJJKTsKLQotICAgICAgICAvLyByZXR1cm4gdGhlIHN0cmluZyByZXAgb2YgdGhlIG5ldyB1cmkgKGFuIGFic29sdXRlIG9uZSkKLSAgICAgICAgcmV0dXJuIHN5c3RlbVVSSS50b1N0cmluZygpOwotCi0gICAgICAgIC8vIGlmIGFueSBleGNlcHRpb24gaXMgdGhyb3duLCBpdCdsbCBnZXQgdGhyb3duIHRvIHRoZSBjYWxsZXIuCi0KLSAgICB9IC8vIGV4cGFuZFN5c3RlbUlkU3RyaWN0T2ZmKFN0cmluZyxTdHJpbmcpOlN0cmluZwotCi0gICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGV4cGFuZFN5c3RlbUlkU3RyaWN0T2ZmMShTdHJpbmcgc3lzdGVtSWQsIFN0cmluZyBiYXNlU3lzdGVtSWQpCi0gICAgICAgIHRocm93cyBVUklTeW50YXhFeGNlcHRpb24sIFVSSS5NYWxmb3JtZWRVUklFeGNlcHRpb24gewotCi0gICAgICAgICAgICBqYXZhLm5ldC5VUkkgc3lzdGVtVVJJID0gbmV3IGphdmEubmV0LlVSSShzeXN0ZW1JZCk7Ci0gICAgICAgIC8vIElmIGl0J3MgYWxyZWFkeSBhbiBhYnNvbHV0ZSBvbmUsIHJldHVybiBpdAotICAgICAgICBpZiAoc3lzdGVtVVJJLmlzQWJzb2x1dGUoKSkgewotICAgICAgICAgICAgaWYgKHN5c3RlbVVSSS5nZXRTY2hlbWUoKS5sZW5ndGgoKSA+IDEpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gc3lzdGVtSWQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvKioKLSAgICAgICAgICAgICAqIElmIHRoZSBzY2hlbWUncyBsZW5ndGggaXMgb25seSBvbmUgY2hhcmFjdGVyLAotICAgICAgICAgICAgICogaXQncyBsaWtlbHkgdGhhdCB0aGlzIHdhcyBpbnRlbmRlZCBhcyBhIGZpbGUKLSAgICAgICAgICAgICAqIHBhdGguIEZpeGluZyB0aGlzIHVwIGluIGV4cGFuZFN5c3RlbUlkIHRvCi0gICAgICAgICAgICAgKiBtYWludGFpbiBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eS4KLSAgICAgICAgICAgICAqLwotICAgICAgICAgICAgdGhyb3cgbmV3IFVSSVN5bnRheEV4Y2VwdGlvbihzeXN0ZW1JZCwgInRoZSBzY2hlbWUncyBsZW5ndGggaXMgb25seSBvbmUgY2hhcmFjdGVyIik7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBJZiB0aGVyZSBpc24ndCBhIGJhc2UgVVJJLCB1c2UgdGhlIHdvcmtpbmcgZGlyZWN0b3J5Ci0gICAgICAgIFVSSSBiYXNlVVJJID0gbnVsbDsKLSAgICAgICAgaWYgKGJhc2VTeXN0ZW1JZCA9PSBudWxsIHx8IGJhc2VTeXN0ZW1JZC5sZW5ndGgoKSA9PSAwKSB7Ci0gICAgICAgICAgICBiYXNlVVJJID0gZ2V0VXNlckRpcigpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgYmFzZVVSSSA9IG5ldyBVUkkoYmFzZVN5c3RlbUlkLCB0cnVlKTsKLSAgICAgICAgICAgIGlmICghYmFzZVVSSS5pc0Fic29sdXRlVVJJKCkpIHsKLSAgICAgICAgICAgICAgICAvLyBhc3N1bWUgImJhc2UiIGlzIGFsc28gYSByZWxhdGl2ZSB1cmkKLSAgICAgICAgICAgICAgICBiYXNlVVJJLmFic29sdXRpemUoZ2V0VXNlckRpcigpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIGFic29sdXRpemUgdGhlIHN5c3RlbSBpZGVudGlmaWVyIHVzaW5nIHRoZSBiYXNlIFVSSQotLy8gICAgICAgIHN5c3RlbVVSSS5hYnNvbHV0aXplKGJhc2VVUkkpOwotICAgICAgICBzeXN0ZW1VUkkgPSAobmV3IGphdmEubmV0LlVSSShiYXNlVVJJLnRvU3RyaW5nKCkpKS5yZXNvbHZlKHN5c3RlbVVSSSk7Ci0KLSAgICAgICAgLy8gcmV0dXJuIHRoZSBzdHJpbmcgcmVwIG9mIHRoZSBuZXcgdXJpIChhbiBhYnNvbHV0ZSBvbmUpCi0gICAgICAgIHJldHVybiBzeXN0ZW1VUkkudG9TdHJpbmcoKTsKLQotICAgICAgICAvLyBpZiBhbnkgZXhjZXB0aW9uIGlzIHRocm93biwgaXQnbGwgZ2V0IHRocm93biB0byB0aGUgY2FsbGVyLgotCi0gICAgfSAvLyBleHBhbmRTeXN0ZW1JZFN0cmljdE9mZihTdHJpbmcsU3RyaW5nKTpTdHJpbmcKLQotICAgIC8vCi0gICAgLy8gUHJvdGVjdGVkIG1ldGhvZHMKLSAgICAvLwotCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBJQU5BIGVuY29kaW5nIG5hbWUgdGhhdCBpcyBhdXRvLWRldGVjdGVkIGZyb20KLSAgICAgKiB0aGUgYnl0ZXMgc3BlY2lmaWVkLCB3aXRoIHRoZSBlbmRpYW4tbmVzcyBvZiB0aGF0IGVuY29kaW5nIHdoZXJlIGFwcHJvcHJpYXRlLgotICAgICAqCi0gICAgICogQHBhcmFtIGI0ICAgIFRoZSBmaXJzdCBmb3VyIGJ5dGVzIG9mIHRoZSBpbnB1dC4KLSAgICAgKiBAcGFyYW0gY291bnQgVGhlIG51bWJlciBvZiBieXRlcyBhY3R1YWxseSByZWFkLgotICAgICAqIEByZXR1cm4gYSAyLWVsZW1lbnQgYXJyYXk6ICB0aGUgZmlyc3QgZWxlbWVudCwgYW4gSUFOQS1lbmNvZGluZyBzdHJpbmcsCi0gICAgICogIHRoZSBzZWNvbmQgZWxlbWVudCBhIEJvb2xlYW4gd2hpY2ggaXMgdHJ1ZSBpZmYgdGhlIGRvY3VtZW50IGlzIGJpZyBlbmRpYW4sIGZhbHNlCi0gICAgICogIGlmIGl0J3MgbGl0dGxlLWVuZGlhbiwgYW5kIG51bGwgaWYgdGhlIGRpc3RpbmN0aW9uIGlzbid0IHJlbGV2YW50LgotICAgICAqLwotICAgIHByb3RlY3RlZCBPYmplY3RbXSBnZXRFbmNvZGluZ05hbWUoYnl0ZVtdIGI0LCBpbnQgY291bnQpIHsKLQotICAgICAgICBpZiAoY291bnQgPCAyKSB7Ci0gICAgICAgICAgICByZXR1cm4gZGVmYXVsdEVuY29kaW5nOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gVVRGLTE2LCB3aXRoIEJPTQotICAgICAgICBpbnQgYjAgPSBiNFswXSAmIDB4RkY7Ci0gICAgICAgIGludCBiMSA9IGI0WzFdICYgMHhGRjsKLSAgICAgICAgaWYgKGIwID09IDB4RkUgJiYgYjEgPT0gMHhGRikgewotICAgICAgICAgICAgLy8gVVRGLTE2LCBiaWctZW5kaWFuCi0gICAgICAgICAgICByZXR1cm4gbmV3IE9iamVjdCBbXSB7IlVURi0xNkJFIiwgbmV3IEJvb2xlYW4odHJ1ZSl9OwotICAgICAgICB9Ci0gICAgICAgIGlmIChiMCA9PSAweEZGICYmIGIxID09IDB4RkUpIHsKLSAgICAgICAgICAgIC8vIFVURi0xNiwgbGl0dGxlLWVuZGlhbgotICAgICAgICAgICAgcmV0dXJuIG5ldyBPYmplY3QgW10geyJVVEYtMTZMRSIsIG5ldyBCb29sZWFuKGZhbHNlKX07Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBkZWZhdWx0IHRvIFVURi04IGlmIHdlIGRvbid0IGhhdmUgZW5vdWdoIGJ5dGVzIHRvIG1ha2UgYQotICAgICAgICAvLyBnb29kIGRldGVybWluYXRpb24gb2YgdGhlIGVuY29kaW5nCi0gICAgICAgIGlmIChjb3VudCA8IDMpIHsKLSAgICAgICAgICAgIHJldHVybiBkZWZhdWx0RW5jb2Rpbmc7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBVVEYtOCB3aXRoIGEgQk9NCi0gICAgICAgIGludCBiMiA9IGI0WzJdICYgMHhGRjsKLSAgICAgICAgaWYgKGIwID09IDB4RUYgJiYgYjEgPT0gMHhCQiAmJiBiMiA9PSAweEJGKSB7Ci0gICAgICAgICAgICByZXR1cm4gZGVmYXVsdEVuY29kaW5nOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gZGVmYXVsdCB0byBVVEYtOCBpZiB3ZSBkb24ndCBoYXZlIGVub3VnaCBieXRlcyB0byBtYWtlIGEKLSAgICAgICAgLy8gZ29vZCBkZXRlcm1pbmF0aW9uIG9mIHRoZSBlbmNvZGluZwotICAgICAgICBpZiAoY291bnQgPCA0KSB7Ci0gICAgICAgICAgICByZXR1cm4gZGVmYXVsdEVuY29kaW5nOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gb3RoZXIgZW5jb2RpbmdzCi0gICAgICAgIGludCBiMyA9IGI0WzNdICYgMHhGRjsKLSAgICAgICAgaWYgKGIwID09IDB4MDAgJiYgYjEgPT0gMHgwMCAmJiBiMiA9PSAweDAwICYmIGIzID09IDB4M0MpIHsKLSAgICAgICAgICAgIC8vIFVDUy00LCBiaWcgZW5kaWFuICgxMjM0KQotICAgICAgICAgICAgcmV0dXJuIG5ldyBPYmplY3QgW10geyJJU08tMTA2NDYtVUNTLTQiLCBuZXcgQm9vbGVhbih0cnVlKX07Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGIwID09IDB4M0MgJiYgYjEgPT0gMHgwMCAmJiBiMiA9PSAweDAwICYmIGIzID09IDB4MDApIHsKLSAgICAgICAgICAgIC8vIFVDUy00LCBsaXR0bGUgZW5kaWFuICg0MzIxKQotICAgICAgICAgICAgcmV0dXJuIG5ldyBPYmplY3QgW10geyJJU08tMTA2NDYtVUNTLTQiLCBuZXcgQm9vbGVhbihmYWxzZSl9OwotICAgICAgICB9Ci0gICAgICAgIGlmIChiMCA9PSAweDAwICYmIGIxID09IDB4MDAgJiYgYjIgPT0gMHgzQyAmJiBiMyA9PSAweDAwKSB7Ci0gICAgICAgICAgICAvLyBVQ1MtNCwgdW51c3VhbCBvY3RldCBvcmRlciAoMjE0MykKLSAgICAgICAgICAgIC8vIFJFVklTSVQ6IFdoYXQgc2hvdWxkIHRoaXMgYmU/Ci0gICAgICAgICAgICByZXR1cm4gbmV3IE9iamVjdCBbXSB7IklTTy0xMDY0Ni1VQ1MtNCIsIG51bGx9OwotICAgICAgICB9Ci0gICAgICAgIGlmIChiMCA9PSAweDAwICYmIGIxID09IDB4M0MgJiYgYjIgPT0gMHgwMCAmJiBiMyA9PSAweDAwKSB7Ci0gICAgICAgICAgICAvLyBVQ1MtNCwgdW51c3VhbCBvY3RlY3Qgb3JkZXIgKDM0MTIpCi0gICAgICAgICAgICAvLyBSRVZJU0lUOiBXaGF0IHNob3VsZCB0aGlzIGJlPwotICAgICAgICAgICAgcmV0dXJuIG5ldyBPYmplY3QgW10geyJJU08tMTA2NDYtVUNTLTQiLCBudWxsfTsKLSAgICAgICAgfQotICAgICAgICBpZiAoYjAgPT0gMHgwMCAmJiBiMSA9PSAweDNDICYmIGIyID09IDB4MDAgJiYgYjMgPT0gMHgzRikgewotICAgICAgICAgICAgLy8gVVRGLTE2LCBiaWctZW5kaWFuLCBubyBCT00KLSAgICAgICAgICAgIC8vIChvciBjb3VsZCB0dXJuIG91dCB0byBiZSBVQ1MtMi4uLgotICAgICAgICAgICAgLy8gUkVWSVNJVDogV2hhdCBzaG91bGQgdGhpcyBiZT8KLSAgICAgICAgICAgIHJldHVybiBuZXcgT2JqZWN0IFtdIHsiVVRGLTE2QkUiLCBuZXcgQm9vbGVhbih0cnVlKX07Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGIwID09IDB4M0MgJiYgYjEgPT0gMHgwMCAmJiBiMiA9PSAweDNGICYmIGIzID09IDB4MDApIHsKLSAgICAgICAgICAgIC8vIFVURi0xNiwgbGl0dGxlLWVuZGlhbiwgbm8gQk9NCi0gICAgICAgICAgICAvLyAob3IgY291bGQgdHVybiBvdXQgdG8gYmUgVUNTLTIuLi4KLSAgICAgICAgICAgIHJldHVybiBuZXcgT2JqZWN0IFtdIHsiVVRGLTE2TEUiLCBuZXcgQm9vbGVhbihmYWxzZSl9OwotICAgICAgICB9Ci0gICAgICAgIGlmIChiMCA9PSAweDRDICYmIGIxID09IDB4NkYgJiYgYjIgPT0gMHhBNyAmJiBiMyA9PSAweDk0KSB7Ci0gICAgICAgICAgICAvLyBFQkNESUMKLSAgICAgICAgICAgIC8vIGEgbGEgeGVyY2VzMSwgcmV0dXJuIENQMDM3IGluc3RlYWQgb2YgRUJDRElDIGhlcmUKLSAgICAgICAgICAgIHJldHVybiBuZXcgT2JqZWN0IFtdIHsiQ1AwMzciLCBudWxsfTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBkZWZhdWx0RW5jb2Rpbmc7Ci0KLSAgICB9IC8vIGdldEVuY29kaW5nTmFtZShieXRlW10saW50KTpPYmplY3RbXQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlcyBhIHJlYWRlciBjYXBhYmxlIG9mIHJlYWRpbmcgdGhlIGdpdmVuIGlucHV0IHN0cmVhbSBpbgotICAgICAqIHRoZSBzcGVjaWZpZWQgZW5jb2RpbmcuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaW5wdXRTdHJlYW0gIFRoZSBpbnB1dCBzdHJlYW0uCi0gICAgICogQHBhcmFtIGVuY29kaW5nICAgICBUaGUgZW5jb2RpbmcgbmFtZSB0aGF0IHRoZSBpbnB1dCBzdHJlYW0gaXMKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgIGVuY29kZWQgdXNpbmcuIElmIHRoZSB1c2VyIGhhcyBzcGVjaWZpZWQgdGhhdAotICAgICAqICAgICAgICAgICAgICAgICAgICAgSmF2YSBlbmNvZGluZyBuYW1lcyBhcmUgYWxsb3dlZCwgdGhlbiB0aGUKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgIGVuY29kaW5nIG5hbWUgbWF5IGJlIGEgSmF2YSBlbmNvZGluZyBuYW1lOwotICAgICAqICAgICAgICAgICAgICAgICAgICAgb3RoZXJ3aXNlLCBpdCBpcyBhbiBpYW5hRW5jb2RpbmcgbmFtZS4KLSAgICAgKiBAcGFyYW0gaXNCaWdFbmRpYW4gICBGb3IgZW5jb2RpbmdzIChsaWtlIHVDUy00KSwgd2hvc2UgbmFtZXMgY2Fubm90Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgc3BlY2lmeSBhIGJ5dGUgb3JkZXIsIHRoaXMgdGVsbHMgd2hldGhlciB0aGUgb3JkZXIgaXMgYmlnRW5kaWFuLiAgbnVsbCBtZW5hcwotICAgICAqICAgICAgICAgICAgICAgICAgICAgIHVua25vd24gb3Igbm90IHJlbGV2YW50LgotICAgICAqCi0gICAgICogQHJldHVybiBSZXR1cm5zIGEgcmVhZGVyLgotICAgICAqLwotICAgIHByb3RlY3RlZCBSZWFkZXIgY3JlYXRlUmVhZGVyKElucHV0U3RyZWFtIGlucHV0U3RyZWFtLCBTdHJpbmcgZW5jb2RpbmcsIEJvb2xlYW4gaXNCaWdFbmRpYW4pCi0gICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKLQotICAgICAgICAvLyBub3JtYWxpemUgZW5jb2RpbmcgbmFtZQotICAgICAgICBpZiAoZW5jb2RpbmcgPT0gbnVsbCkgewotICAgICAgICAgICAgZW5jb2RpbmcgPSAiVVRGLTgiOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gdHJ5IHRvIHVzZSBhbiBvcHRpbWl6ZWQgcmVhZGVyCi0gICAgICAgIFN0cmluZyBFTkNPRElORyA9IGVuY29kaW5nLnRvVXBwZXJDYXNlKExvY2FsZS5FTkdMSVNIKTsKLSAgICAgICAgaWYgKEVOQ09ESU5HLmVxdWFscygiVVRGLTgiKSkgewotICAgICAgICAgICAgaWYgKERFQlVHX0VOQ09ESU5HUykgewotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiJCQkIGNyZWF0aW5nIFVURjhSZWFkZXIiKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiBuZXcgVVRGOFJlYWRlcihpbnB1dFN0cmVhbSwgZkJ1ZmZlclNpemUsIGZFcnJvclJlcG9ydGVyLmdldE1lc3NhZ2VGb3JtYXR0ZXIoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOKSwgZkVycm9yUmVwb3J0ZXIuZ2V0TG9jYWxlKCkgKTsKLSAgICAgICAgfQotICAgICAgICBpZiAoRU5DT0RJTkcuZXF1YWxzKCJVUy1BU0NJSSIpKSB7Ci0gICAgICAgICAgICBpZiAoREVCVUdfRU5DT0RJTkdTKSB7Ci0gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCIkJCQgY3JlYXRpbmcgQVNDSUlSZWFkZXIiKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiBuZXcgQVNDSUlSZWFkZXIoaW5wdXRTdHJlYW0sIGZCdWZmZXJTaXplLCBmRXJyb3JSZXBvcnRlci5nZXRNZXNzYWdlRm9ybWF0dGVyKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiksIGZFcnJvclJlcG9ydGVyLmdldExvY2FsZSgpKTsKLSAgICAgICAgfQotICAgICAgICBpZihFTkNPRElORy5lcXVhbHMoIklTTy0xMDY0Ni1VQ1MtNCIpKSB7Ci0gICAgICAgICAgICBpZihpc0JpZ0VuZGlhbiAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgYm9vbGVhbiBpc0JFID0gaXNCaWdFbmRpYW4uYm9vbGVhblZhbHVlKCk7Ci0gICAgICAgICAgICAgICAgaWYoaXNCRSkgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFVDU1JlYWRlcihpbnB1dFN0cmVhbSwgVUNTUmVhZGVyLlVDUzRCRSk7Ci0gICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBVQ1NSZWFkZXIoaW5wdXRTdHJlYW0sIFVDU1JlYWRlci5VQ1M0TEUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IodGhpcy5nZXRFbnRpdHlTY2FubmVyKCksWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgIkVuY29kaW5nQnl0ZU9yZGVyVW5zdXBwb3J0ZWQiLAotICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgZW5jb2RpbmcgfSwKLSAgICAgICAgICAgICAgICAgICAgICAgIFhNTEVycm9yUmVwb3J0ZXIuU0VWRVJJVFlfRkFUQUxfRVJST1IpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGlmKEVOQ09ESU5HLmVxdWFscygiSVNPLTEwNjQ2LVVDUy0yIikpIHsKLSAgICAgICAgICAgIGlmKGlzQmlnRW5kaWFuICE9IG51bGwpIHsgLy8gc291bGQgbmV2ZXIgaGFwcGVuIHdpdGggdGhpcyBlbmNvZGluZy4uLgotICAgICAgICAgICAgICAgIGJvb2xlYW4gaXNCRSA9IGlzQmlnRW5kaWFuLmJvb2xlYW5WYWx1ZSgpOwotICAgICAgICAgICAgICAgIGlmKGlzQkUpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBVQ1NSZWFkZXIoaW5wdXRTdHJlYW0sIFVDU1JlYWRlci5VQ1MyQkUpOwotICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgVUNTUmVhZGVyKGlucHV0U3RyZWFtLCBVQ1NSZWFkZXIuVUNTMkxFKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKHRoaXMuZ2V0RW50aXR5U2Nhbm5lcigpLFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICJFbmNvZGluZ0J5dGVPcmRlclVuc3VwcG9ydGVkIiwKLSAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7IGVuY29kaW5nIH0sCi0gICAgICAgICAgICAgICAgICAgICAgICBYTUxFcnJvclJlcG9ydGVyLlNFVkVSSVRZX0ZBVEFMX0VSUk9SKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIGNoZWNrIGZvciB2YWxpZCBuYW1lCi0gICAgICAgIGJvb2xlYW4gdmFsaWRJQU5BID0gWE1MQ2hhci5pc1ZhbGlkSUFOQUVuY29kaW5nKGVuY29kaW5nKTsKLSAgICAgICAgYm9vbGVhbiB2YWxpZEphdmEgPSBYTUxDaGFyLmlzVmFsaWRKYXZhRW5jb2RpbmcoZW5jb2RpbmcpOwotICAgICAgICBpZiAoIXZhbGlkSUFOQSB8fCAoZkFsbG93SmF2YUVuY29kaW5ncyAmJiAhdmFsaWRKYXZhKSkgewotICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IodGhpcy5nZXRFbnRpdHlTY2FubmVyKCksWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAiRW5jb2RpbmdEZWNsSW52YWxpZCIsCi0gICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7IGVuY29kaW5nIH0sCi0gICAgICAgICAgICAgICAgICAgIFhNTEVycm9yUmVwb3J0ZXIuU0VWRVJJVFlfRkFUQUxfRVJST1IpOwotICAgICAgICAgICAgICAgICAgICAvLyBOT1RFOiBBbmR5SCBzdWdnZXN0ZWQgdGhhdCwgb24gZmFpbHVyZSwgd2UgdXNlIElTTyBMYXRpbiAxCi0gICAgICAgICAgICAgICAgICAgIC8vICAgICAgIGJlY2F1c2UgZXZlcnkgYnl0ZSBpcyBhIHZhbGlkIElTTyBMYXRpbiAxIGNoYXJhY3Rlci4KLSAgICAgICAgICAgICAgICAgICAgLy8gICAgICAgSXQgbWF5IG5vdCB0cmFuc2xhdGUgY29ycmVjdGx5IGJ1dCBpZiB3ZSBmYWlsZWQgb24KLSAgICAgICAgICAgICAgICAgICAgLy8gICAgICAgdGhlIGVuY29kaW5nIGFueXdheSwgdGhlbiB3ZSdyZSBleHBlY3RpbmcgdGhlIGNvbnRlbnQKLSAgICAgICAgICAgICAgICAgICAgLy8gICAgICAgb2YgdGhlIGRvY3VtZW50IHRvIGJlIGJhZC4gVGhpcyB3aWxsIGp1c3QgcHJldmVudCBhbgotICAgICAgICAgICAgICAgICAgICAvLyAgICAgICBpbnZhbGlkIFVURi04IHNlcXVlbmNlIHRvIGJlIGRldGVjdGVkLiBUaGlzIGlzIG9ubHkKLSAgICAgICAgICAgICAgICAgICAgLy8gICAgICAgaW1wb3J0YW50IHdoZW4gY29udGludWUtYWZ0ZXItZmF0YWwtZXJyb3IgaXMgdHVybmVkCi0gICAgICAgICAgICAgICAgICAgIC8vICAgICAgIG9uLiAtQWMKLSAgICAgICAgICAgICAgICAgICAgZW5jb2RpbmcgPSAiSVNPLTg4NTktMSI7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyB0cnkgdG8gdXNlIGEgSmF2YSByZWFkZXIKLSAgICAgICAgU3RyaW5nIGphdmFFbmNvZGluZyA9IEVuY29kaW5nTWFwLmdldElBTkEySmF2YU1hcHBpbmcoRU5DT0RJTkcpOwotICAgICAgICBpZiAoamF2YUVuY29kaW5nID09IG51bGwpIHsKLSAgICAgICAgICAgIGlmKGZBbGxvd0phdmFFbmNvZGluZ3MpIHsKLSAgICAgICAgICAgICAgICBqYXZhRW5jb2RpbmcgPSBlbmNvZGluZzsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IodGhpcy5nZXRFbnRpdHlTY2FubmVyKCksWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgIkVuY29kaW5nRGVjbEludmFsaWQiLAotICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgZW5jb2RpbmcgfSwKLSAgICAgICAgICAgICAgICAgICAgICAgIFhNTEVycm9yUmVwb3J0ZXIuU0VWRVJJVFlfRkFUQUxfRVJST1IpOwotICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2VlIGNvbW1lbnQgYWJvdmUuCi0gICAgICAgICAgICAgICAgICAgICAgICBqYXZhRW5jb2RpbmcgPSAiSVNPODg1OV8xIjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBpZiAoREVCVUdfRU5DT0RJTkdTKSB7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCIkJCQgY3JlYXRpbmcgSmF2YSBJbnB1dFN0cmVhbVJlYWRlcjogZW5jb2Rpbmc9IitqYXZhRW5jb2RpbmcpOwotICAgICAgICAgICAgaWYgKGphdmFFbmNvZGluZyA9PSBlbmNvZGluZykgewotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIiAoSUFOQSBlbmNvZGluZykiKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBuZXcgQnVmZmVyZWRSZWFkZXIoIG5ldyBJbnB1dFN0cmVhbVJlYWRlcihpbnB1dFN0cmVhbSwgamF2YUVuY29kaW5nKSk7Ci0KLSAgICB9IC8vIGNyZWF0ZVJlYWRlcihJbnB1dFN0cmVhbSxTdHJpbmcsIEJvb2xlYW4pOiBSZWFkZXIKLQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSBwdWJsaWMgaWRlbnRpZmllciBmb3IgdGhlIGN1cnJlbnQgZG9jdW1lbnQgZXZlbnQuCi0gICAgICogPHA+Ci0gICAgICogVGhlIHJldHVybiB2YWx1ZSBpcyB0aGUgcHVibGljIGlkZW50aWZpZXIgb2YgdGhlIGRvY3VtZW50Ci0gICAgICogZW50aXR5IG9yIG9mIHRoZSBleHRlcm5hbCBwYXJzZWQgZW50aXR5IGluIHdoaWNoIHRoZSBtYXJrdXAKLSAgICAgKiB0cmlnZ2VyaW5nIHRoZSBldmVudCBhcHBlYXJzLgotICAgICAqCi0gICAgICogQHJldHVybiBBIHN0cmluZyBjb250YWluaW5nIHRoZSBwdWJsaWMgaWRlbnRpZmllciwgb3IKLSAgICAgKiAgICAgICAgIG51bGwgaWYgbm9uZSBpcyBhdmFpbGFibGUuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRQdWJsaWNJZCgpIHsKLSAgICAgICAgcmV0dXJuIChmQ3VycmVudEVudGl0eSAhPSBudWxsICYmIGZDdXJyZW50RW50aXR5LmVudGl0eUxvY2F0aW9uICE9IG51bGwpID8gZkN1cnJlbnRFbnRpdHkuZW50aXR5TG9jYXRpb24uZ2V0UHVibGljSWQoKSA6IG51bGw7Ci0gICAgfSAvLyBnZXRQdWJsaWNJZCgpOlN0cmluZwotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSBleHBhbmRlZCBzeXN0ZW0gaWRlbnRpZmllciBmb3IgdGhlIGN1cnJlbnQgZG9jdW1lbnQgZXZlbnQuCi0gICAgICogPHA+Ci0gICAgICogVGhlIHJldHVybiB2YWx1ZSBpcyB0aGUgZXhwYW5kZWQgc3lzdGVtIGlkZW50aWZpZXIgb2YgdGhlIGRvY3VtZW50Ci0gICAgICogZW50aXR5IG9yIG9mIHRoZSBleHRlcm5hbCBwYXJzZWQgZW50aXR5IGluIHdoaWNoIHRoZSBtYXJrdXAKLSAgICAgKiB0cmlnZ2VyaW5nIHRoZSBldmVudCBhcHBlYXJzLgotICAgICAqIDxwPgotICAgICAqIElmIHRoZSBzeXN0ZW0gaWRlbnRpZmllciBpcyBhIFVSTCwgdGhlIHBhcnNlciBtdXN0IHJlc29sdmUgaXQKLSAgICAgKiBmdWxseSBiZWZvcmUgcGFzc2luZyBpdCB0byB0aGUgYXBwbGljYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIEEgc3RyaW5nIGNvbnRhaW5pbmcgdGhlIGV4cGFuZGVkIHN5c3RlbSBpZGVudGlmaWVyLCBvciBudWxsCi0gICAgICogICAgICAgICBpZiBub25lIGlzIGF2YWlsYWJsZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEV4cGFuZGVkU3lzdGVtSWQoKSB7Ci0gICAgICAgIGlmIChmQ3VycmVudEVudGl0eSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAoZkN1cnJlbnRFbnRpdHkuZW50aXR5TG9jYXRpb24gIT0gbnVsbCAmJgotICAgICAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5lbnRpdHlMb2NhdGlvbi5nZXRFeHBhbmRlZFN5c3RlbUlkKCkgIT0gbnVsbCApIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZkN1cnJlbnRFbnRpdHkuZW50aXR5TG9jYXRpb24uZ2V0RXhwYW5kZWRTeXN0ZW1JZCgpOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAvLyBzZWFyY2ggZm9yIHRoZSBmaXJzdCBleHRlcm5hbCBlbnRpdHkgb24gdGhlIHN0YWNrCi0gICAgICAgICAgICAgICAgaW50IHNpemUgPSBmRW50aXR5U3RhY2suc2l6ZSgpOwotICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSBzaXplIC0gMTsgaSA+PSAwIDsgaS0tKSB7Ci0gICAgICAgICAgICAgICAgICAgIEVudGl0eS5TY2FubmVkRW50aXR5IGV4dGVybmFsRW50aXR5ID0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAoRW50aXR5LlNjYW5uZWRFbnRpdHkpZkVudGl0eVN0YWNrLmVsZW1lbnRBdChpKTsKLQotICAgICAgICAgICAgICAgICAgICBpZiAoZXh0ZXJuYWxFbnRpdHkuZW50aXR5TG9jYXRpb24gIT0gbnVsbCAmJgotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVybmFsRW50aXR5LmVudGl0eUxvY2F0aW9uLmdldEV4cGFuZGVkU3lzdGVtSWQoKSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZXh0ZXJuYWxFbnRpdHkuZW50aXR5TG9jYXRpb24uZ2V0RXhwYW5kZWRTeXN0ZW1JZCgpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0gLy8gZ2V0RXhwYW5kZWRTeXN0ZW1JZCgpOlN0cmluZwotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSBsaXRlcmFsIHN5c3RlbSBpZGVudGlmaWVyIGZvciB0aGUgY3VycmVudCBkb2N1bWVudCBldmVudC4KLSAgICAgKiA8cD4KLSAgICAgKiBUaGUgcmV0dXJuIHZhbHVlIGlzIHRoZSBsaXRlcmFsIHN5c3RlbSBpZGVudGlmaWVyIG9mIHRoZSBkb2N1bWVudAotICAgICAqIGVudGl0eSBvciBvZiB0aGUgZXh0ZXJuYWwgcGFyc2VkIGVudGl0eSBpbiB3aGljaCB0aGUgbWFya3VwCi0gICAgICogdHJpZ2dlcmluZyB0aGUgZXZlbnQgYXBwZWFycy4KLSAgICAgKiA8cD4KLSAgICAgKiBAcmV0dXJuIEEgc3RyaW5nIGNvbnRhaW5pbmcgdGhlIGxpdGVyYWwgc3lzdGVtIGlkZW50aWZpZXIsIG9yIG51bGwKLSAgICAgKiAgICAgICAgIGlmIG5vbmUgaXMgYXZhaWxhYmxlLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TGl0ZXJhbFN5c3RlbUlkKCkgewotICAgICAgICBpZiAoZkN1cnJlbnRFbnRpdHkgIT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKGZDdXJyZW50RW50aXR5LmVudGl0eUxvY2F0aW9uICE9IG51bGwgJiYKLSAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkuZW50aXR5TG9jYXRpb24uZ2V0TGl0ZXJhbFN5c3RlbUlkKCkgIT0gbnVsbCApIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZkN1cnJlbnRFbnRpdHkuZW50aXR5TG9jYXRpb24uZ2V0TGl0ZXJhbFN5c3RlbUlkKCk7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIC8vIHNlYXJjaCBmb3IgdGhlIGZpcnN0IGV4dGVybmFsIGVudGl0eSBvbiB0aGUgc3RhY2sKLSAgICAgICAgICAgICAgICBpbnQgc2l6ZSA9IGZFbnRpdHlTdGFjay5zaXplKCk7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IHNpemUgLSAxOyBpID49IDAgOyBpLS0pIHsKLSAgICAgICAgICAgICAgICAgICAgRW50aXR5LlNjYW5uZWRFbnRpdHkgZXh0ZXJuYWxFbnRpdHkgPQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIChFbnRpdHkuU2Nhbm5lZEVudGl0eSlmRW50aXR5U3RhY2suZWxlbWVudEF0KGkpOwotCi0gICAgICAgICAgICAgICAgICAgIGlmIChleHRlcm5hbEVudGl0eS5lbnRpdHlMb2NhdGlvbiAhPSBudWxsICYmCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZXJuYWxFbnRpdHkuZW50aXR5TG9jYXRpb24uZ2V0TGl0ZXJhbFN5c3RlbUlkKCkgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGV4dGVybmFsRW50aXR5LmVudGl0eUxvY2F0aW9uLmdldExpdGVyYWxTeXN0ZW1JZCgpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0gLy8gZ2V0TGl0ZXJhbFN5c3RlbUlkKCk6U3RyaW5nCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIGxpbmUgbnVtYmVyIHdoZXJlIHRoZSBjdXJyZW50IGRvY3VtZW50IGV2ZW50IGVuZHMuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5XYXJuaW5nOjwvc3Ryb25nPiBUaGUgcmV0dXJuIHZhbHVlIGZyb20gdGhlIG1ldGhvZAotICAgICAqIGlzIGludGVuZGVkIG9ubHkgYXMgYW4gYXBwcm94aW1hdGlvbiBmb3IgdGhlIHNha2Ugb2YgZXJyb3IKLSAgICAgKiByZXBvcnRpbmc7IGl0IGlzIG5vdCBpbnRlbmRlZCB0byBwcm92aWRlIHN1ZmZpY2llbnQgaW5mb3JtYXRpb24KLSAgICAgKiB0byBlZGl0IHRoZSBjaGFyYWN0ZXIgY29udGVudCBvZiB0aGUgb3JpZ2luYWwgWE1MIGRvY3VtZW50LgotICAgICAqIDxwPgotICAgICAqIFRoZSByZXR1cm4gdmFsdWUgaXMgYW4gYXBwcm94aW1hdGlvbiBvZiB0aGUgbGluZSBudW1iZXIKLSAgICAgKiBpbiB0aGUgZG9jdW1lbnQgZW50aXR5IG9yIGV4dGVybmFsIHBhcnNlZCBlbnRpdHkgd2hlcmUgdGhlCi0gICAgICogbWFya3VwIHRyaWdnZXJpbmcgdGhlIGV2ZW50IGFwcGVhcnMuCi0gICAgICogPHA+Ci0gICAgICogSWYgcG9zc2libGUsIHRoZSBTQVggZHJpdmVyIHNob3VsZCBwcm92aWRlIHRoZSBsaW5lIHBvc2l0aW9uCi0gICAgICogb2YgdGhlIGZpcnN0IGNoYXJhY3RlciBhZnRlciB0aGUgdGV4dCBhc3NvY2lhdGVkIHdpdGggdGhlIGRvY3VtZW50Ci0gICAgICogZXZlbnQuICBUaGUgZmlyc3QgbGluZSBpbiB0aGUgZG9jdW1lbnQgaXMgbGluZSAxLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgbGluZSBudW1iZXIsIG9yIC0xIGlmIG5vbmUgaXMgYXZhaWxhYmxlLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0TGluZU51bWJlcigpIHsKLSAgICAgICAgaWYgKGZDdXJyZW50RW50aXR5ICE9IG51bGwpIHsKLSAgICAgICAgICAgIGlmIChmQ3VycmVudEVudGl0eS5pc0V4dGVybmFsKCkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZkN1cnJlbnRFbnRpdHkubGluZU51bWJlcjsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgLy8gc2VhcmNoIGZvciB0aGUgZmlyc3QgZXh0ZXJuYWwgZW50aXR5IG9uIHRoZSBzdGFjawotICAgICAgICAgICAgICAgIGludCBzaXplID0gZkVudGl0eVN0YWNrLnNpemUoKTsKLSAgICAgICAgICAgICAgICBmb3IgKGludCBpPXNpemUtMTsgaT4wIDsgaS0tKSB7Ci0gICAgICAgICAgICAgICAgICAgIEVudGl0eS5TY2FubmVkRW50aXR5IGZpcnN0RXh0ZXJuYWxFbnRpdHkgPSAoRW50aXR5LlNjYW5uZWRFbnRpdHkpZkVudGl0eVN0YWNrLmVsZW1lbnRBdChpKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGZpcnN0RXh0ZXJuYWxFbnRpdHkuaXNFeHRlcm5hbCgpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmlyc3RFeHRlcm5hbEVudGl0eS5saW5lTnVtYmVyOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIC0xOwotCi0gICAgfSAvLyBnZXRMaW5lTnVtYmVyKCk6aW50Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIGNvbHVtbiBudW1iZXIgd2hlcmUgdGhlIGN1cnJlbnQgZG9jdW1lbnQgZXZlbnQgZW5kcy4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPldhcm5pbmc6PC9zdHJvbmc+IFRoZSByZXR1cm4gdmFsdWUgZnJvbSB0aGUgbWV0aG9kCi0gICAgICogaXMgaW50ZW5kZWQgb25seSBhcyBhbiBhcHByb3hpbWF0aW9uIGZvciB0aGUgc2FrZSBvZiBlcnJvcgotICAgICAqIHJlcG9ydGluZzsgaXQgaXMgbm90IGludGVuZGVkIHRvIHByb3ZpZGUgc3VmZmljaWVudCBpbmZvcm1hdGlvbgotICAgICAqIHRvIGVkaXQgdGhlIGNoYXJhY3RlciBjb250ZW50IG9mIHRoZSBvcmlnaW5hbCBYTUwgZG9jdW1lbnQuCi0gICAgICogPHA+Ci0gICAgICogVGhlIHJldHVybiB2YWx1ZSBpcyBhbiBhcHByb3hpbWF0aW9uIG9mIHRoZSBjb2x1bW4gbnVtYmVyCi0gICAgICogaW4gdGhlIGRvY3VtZW50IGVudGl0eSBvciBleHRlcm5hbCBwYXJzZWQgZW50aXR5IHdoZXJlIHRoZQotICAgICAqIG1hcmt1cCB0cmlnZ2VyaW5nIHRoZSBldmVudCBhcHBlYXJzLgotICAgICAqIDxwPgotICAgICAqIElmIHBvc3NpYmxlLCB0aGUgU0FYIGRyaXZlciBzaG91bGQgcHJvdmlkZSB0aGUgbGluZSBwb3NpdGlvbgotICAgICAqIG9mIHRoZSBmaXJzdCBjaGFyYWN0ZXIgYWZ0ZXIgdGhlIHRleHQgYXNzb2NpYXRlZCB3aXRoIHRoZSBkb2N1bWVudAotICAgICAqIGV2ZW50LgotICAgICAqIDxwPgotICAgICAqIElmIHBvc3NpYmxlLCB0aGUgU0FYIGRyaXZlciBzaG91bGQgcHJvdmlkZSB0aGUgbGluZSBwb3NpdGlvbgotICAgICAqIG9mIHRoZSBmaXJzdCBjaGFyYWN0ZXIgYWZ0ZXIgdGhlIHRleHQgYXNzb2NpYXRlZCB3aXRoIHRoZSBkb2N1bWVudAotICAgICAqIGV2ZW50LiAgVGhlIGZpcnN0IGNvbHVtbiBpbiBlYWNoIGxpbmUgaXMgY29sdW1uIDEuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBjb2x1bW4gbnVtYmVyLCBvciAtMSBpZiBub25lIGlzIGF2YWlsYWJsZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldENvbHVtbk51bWJlcigpIHsKLSAgICAgICAgaWYgKGZDdXJyZW50RW50aXR5ICE9IG51bGwpIHsKLSAgICAgICAgICAgIGlmIChmQ3VycmVudEVudGl0eS5pc0V4dGVybmFsKCkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZkN1cnJlbnRFbnRpdHkuY29sdW1uTnVtYmVyOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAvLyBzZWFyY2ggZm9yIHRoZSBmaXJzdCBleHRlcm5hbCBlbnRpdHkgb24gdGhlIHN0YWNrCi0gICAgICAgICAgICAgICAgaW50IHNpemUgPSBmRW50aXR5U3RhY2suc2l6ZSgpOwotICAgICAgICAgICAgICAgIGZvciAoaW50IGk9c2l6ZS0xOyBpPjAgOyBpLS0pIHsKLSAgICAgICAgICAgICAgICAgICAgRW50aXR5LlNjYW5uZWRFbnRpdHkgZmlyc3RFeHRlcm5hbEVudGl0eSA9IChFbnRpdHkuU2Nhbm5lZEVudGl0eSlmRW50aXR5U3RhY2suZWxlbWVudEF0KGkpOwotICAgICAgICAgICAgICAgICAgICBpZiAoZmlyc3RFeHRlcm5hbEVudGl0eS5pc0V4dGVybmFsKCkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmaXJzdEV4dGVybmFsRW50aXR5LmNvbHVtbk51bWJlcjsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiAtMTsKLSAgICB9IC8vIGdldENvbHVtbk51bWJlcigpOmludAotCi0KLSAgICAvLwotICAgIC8vIFByb3RlY3RlZCBzdGF0aWMgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBGaXhlcyBhIHBsYXRmb3JtIGRlcGVuZGVudCBmaWxlbmFtZSB0byBzdGFuZGFyZCBVUkkgZm9ybS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzdHIgVGhlIHN0cmluZyB0byBmaXguCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFJldHVybnMgdGhlIGZpeGVkIFVSSSBzdHJpbmcuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBTdHJpbmcgZml4VVJJKFN0cmluZyBzdHIpIHsKLQotICAgICAgICAvLyBoYW5kbGUgcGxhdGZvcm0gZGVwZW5kZW50IHN0cmluZ3MKLSAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UoamF2YS5pby5GaWxlLnNlcGFyYXRvckNoYXIsICcvJyk7Ci0KLSAgICAgICAgLy8gV2luZG93cyBmaXgKLSAgICAgICAgaWYgKHN0ci5sZW5ndGgoKSA+PSAyKSB7Ci0gICAgICAgICAgICBjaGFyIGNoMSA9IHN0ci5jaGFyQXQoMSk7Ci0gICAgICAgICAgICAvLyBjaGFuZ2UgIkM6YmxhaCIgdG8gIi9DOmJsYWgiCi0gICAgICAgICAgICBpZiAoY2gxID09ICc6JykgewotICAgICAgICAgICAgICAgIGNoYXIgY2gwID0gQ2hhcmFjdGVyLnRvVXBwZXJDYXNlKHN0ci5jaGFyQXQoMCkpOwotICAgICAgICAgICAgICAgIGlmIChjaDAgPj0gJ0EnICYmIGNoMCA8PSAnWicpIHsKLSAgICAgICAgICAgICAgICAgICAgc3RyID0gIi8iICsgc3RyOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIGNoYW5nZSAiLy9ibGFoIiB0byAiZmlsZTovL2JsYWgiCi0gICAgICAgICAgICBlbHNlIGlmIChjaDEgPT0gJy8nICYmIHN0ci5jaGFyQXQoMCkgPT0gJy8nKSB7Ci0gICAgICAgICAgICAgICAgc3RyID0gImZpbGU6IiArIHN0cjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIHJlcGxhY2Ugc3BhY2VzIGluIGZpbGUgbmFtZXMgd2l0aCAlMjAuCi0gICAgICAgIC8vIE9yaWdpbmFsIGNvbW1lbnQgZnJvbSBKREs1OiB0aGUgZm9sbG93aW5nIGFsZ29yaXRobSBtaWdodCBub3QgYmUKLSAgICAgICAgLy8gdmVyeSBwZXJmb3JtYW50LCBidXQgcGVvcGxlIHdobyB3YW50IHRvIHVzZSBpbnZhbGlkIFVSSSdzIGhhdmUgdG8KLSAgICAgICAgLy8gcGF5IHRoZSBwcmljZS4KLSAgICAgICAgaW50IHBvcyA9IHN0ci5pbmRleE9mKCcgJyk7Ci0gICAgICAgIGlmIChwb3MgPj0gMCkgewotICAgICAgICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKHN0ci5sZW5ndGgoKSk7Ci0gICAgICAgICAgICAvLyBwdXQgY2hhcmFjdGVycyBiZWZvcmUgJyAnIGludG8gdGhlIHN0cmluZyBidWlsZGVyCi0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBvczsgaSsrKQotICAgICAgICAgICAgICAgIHNiLmFwcGVuZChzdHIuY2hhckF0KGkpKTsKLSAgICAgICAgICAgIC8vIGFuZCAlMjAgZm9yIHRoZSBzcGFjZQotICAgICAgICAgICAgc2IuYXBwZW5kKCIlMjAiKTsKLSAgICAgICAgICAgIC8vIGZvciB0aGUgcmVtYW1pbmluZyBwYXJ0LCBhbHNvIGNvbnZlcnQgJyAnIHRvICIlMjAiLgotICAgICAgICAgICAgZm9yIChpbnQgaSA9IHBvcysxOyBpIDwgc3RyLmxlbmd0aCgpOyBpKyspIHsKLSAgICAgICAgICAgICAgICBpZiAoc3RyLmNoYXJBdChpKSA9PSAnICcpCi0gICAgICAgICAgICAgICAgICAgIHNiLmFwcGVuZCgiJTIwIik7Ci0gICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICBzYi5hcHBlbmQoc3RyLmNoYXJBdChpKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBzdHIgPSBzYi50b1N0cmluZygpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gZG9uZQotICAgICAgICByZXR1cm4gc3RyOwotCi0gICAgfSAvLyBmaXhVUkkoU3RyaW5nKTpTdHJpbmcKLQotCi0gICAgLy8KLSAgICAvLyBQYWNrYWdlIHZpc2libGUgbWV0aG9kcwotICAgIC8vCi0gICAgLyoqIFByaW50cyB0aGUgY29udGVudHMgb2YgdGhlIGJ1ZmZlci4gKi8KLSAgICBmaW5hbCB2b2lkIHByaW50KCkgewotICAgICAgICBpZiAoREVCVUdfQlVGRkVSKSB7Ci0gICAgICAgICAgICBpZiAoZkN1cnJlbnRFbnRpdHkgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoJ1snKTsKLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KGZDdXJyZW50RW50aXR5LmNvdW50KTsKLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCcgJyk7Ci0gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludChmQ3VycmVudEVudGl0eS5wb3NpdGlvbik7Ci0gICAgICAgICAgICAgICAgaWYgKGZDdXJyZW50RW50aXR5LmNvdW50ID4gMCkgewotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCIgXCIiKTsKLSAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmQ3VycmVudEVudGl0eS5jb3VudDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaSA9PSBmQ3VycmVudEVudGl0eS5wb3NpdGlvbikgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoJ14nKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGNoYXIgYyA9IGZDdXJyZW50RW50aXR5LmNoW2ldOwotICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChjKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnXG4nOiB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIlxcbiIpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnXHInOiB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIlxcciIpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnXHQnOiB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIlxcdCIpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnXFwnOiB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIlxcXFwiKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludChjKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgaWYgKGZDdXJyZW50RW50aXR5LnBvc2l0aW9uID09IGZDdXJyZW50RW50aXR5LmNvdW50KSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCdeJyk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgnIicpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCddJyk7Ci0gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiIEAgIik7Ci0gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludChmQ3VycmVudEVudGl0eS5saW5lTnVtYmVyKTsKLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCcsJyk7Ci0gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludChmQ3VycmVudEVudGl0eS5jb2x1bW5OdW1iZXIpOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCIqTk8gQ1VSUkVOVCBFTlRJVFkqIik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9IC8vIHByaW50KCkKLQotICAgIC8qKgotICAgICAqIEJ1ZmZlciB1c2VkIGluIGVudGl0eSBtYW5hZ2VyIHRvIHJldXNlIGNoYXJhY3RlciBhcnJheXMgaW5zdGVhZAotICAgICAqIG9mIGNyZWF0aW5nIG5ldyBvbmVzIGV2ZXJ5IHRpbWUuCi0gICAgICoKLSAgICAgKiBAeGVyY2VzLmludGVybmFsCi0gICAgICoKLSAgICAgKiBAYXV0aG9yIEFua2l0IFBhc3JpY2hhLCBJQk0KLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBDaGFyYWN0ZXJCdWZmZXIgewotCi0gICAgICAgIC8qKiBjaGFyYWN0ZXIgYnVmZmVyICovCi0gICAgICAgIHByaXZhdGUgY2hhcltdIGNoOwotCi0gICAgICAgIC8qKiB3aGV0aGVyIHRoZSBidWZmZXIgaXMgZm9yIGFuIGV4dGVybmFsIG9yIGludGVybmFsIHNjYW5uZWQgZW50aXR5ICovCi0gICAgICAgIHByaXZhdGUgYm9vbGVhbiBpc0V4dGVybmFsOwotCi0gICAgICAgIHB1YmxpYyBDaGFyYWN0ZXJCdWZmZXIoYm9vbGVhbiBpc0V4dGVybmFsLCBpbnQgc2l6ZSkgewotICAgICAgICAgICAgdGhpcy5pc0V4dGVybmFsID0gaXNFeHRlcm5hbDsKLSAgICAgICAgICAgIGNoID0gbmV3IGNoYXJbc2l6ZV07Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgICAvKioKLSAgICAgKiBTdG9yZXMgYSBudW1iZXIgb2YgY2hhcmFjdGVyIGJ1ZmZlcnMgYW5kIHByb3ZpZGVzIGl0IHRvIHRoZSBlbnRpdHkKLSAgICAgKiBtYW5hZ2VyIHRvIHVzZSB3aGVuIGFuIGVudGl0eSBpcyBzZWVuLgotICAgICAqCi0gICAgICogQHhlcmNlcy5pbnRlcm5hbAotICAgICAqCi0gICAgICogQGF1dGhvciBBbmtpdCBQYXNyaWNoYSwgSUJNCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgQ2hhcmFjdGVyQnVmZmVyUG9vbCB7Ci0KLSAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IERFRkFVTFRfUE9PTF9TSVpFID0gMzsKLQotICAgICAgICBwcml2YXRlIENoYXJhY3RlckJ1ZmZlcltdIGZJbnRlcm5hbEJ1ZmZlclBvb2w7Ci0gICAgICAgIHByaXZhdGUgQ2hhcmFjdGVyQnVmZmVyW10gZkV4dGVybmFsQnVmZmVyUG9vbDsKLQotICAgICAgICBwcml2YXRlIGludCBmRXh0ZXJuYWxCdWZmZXJTaXplOwotICAgICAgICBwcml2YXRlIGludCBmSW50ZXJuYWxCdWZmZXJTaXplOwotICAgICAgICBwcml2YXRlIGludCBwb29sU2l6ZTsKLQotICAgICAgICBwcml2YXRlIGludCBmSW50ZXJuYWxUb3A7Ci0gICAgICAgIHByaXZhdGUgaW50IGZFeHRlcm5hbFRvcDsKLQotICAgICAgICBwdWJsaWMgQ2hhcmFjdGVyQnVmZmVyUG9vbChpbnQgZXh0ZXJuYWxCdWZmZXJTaXplLCBpbnQgaW50ZXJuYWxCdWZmZXJTaXplKSB7Ci0gICAgICAgICAgICB0aGlzKERFRkFVTFRfUE9PTF9TSVpFLCBleHRlcm5hbEJ1ZmZlclNpemUsIGludGVybmFsQnVmZmVyU2l6ZSk7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgQ2hhcmFjdGVyQnVmZmVyUG9vbChpbnQgcG9vbFNpemUsIGludCBleHRlcm5hbEJ1ZmZlclNpemUsIGludCBpbnRlcm5hbEJ1ZmZlclNpemUpIHsKLSAgICAgICAgICAgIGZFeHRlcm5hbEJ1ZmZlclNpemUgPSBleHRlcm5hbEJ1ZmZlclNpemU7Ci0gICAgICAgICAgICBmSW50ZXJuYWxCdWZmZXJTaXplID0gaW50ZXJuYWxCdWZmZXJTaXplOwotICAgICAgICAgICAgdGhpcy5wb29sU2l6ZSA9IHBvb2xTaXplOwotICAgICAgICAgICAgaW5pdCgpOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqIEluaXRpYWxpemVzIGJ1ZmZlciBwb29sLiAqKi8KLSAgICAgICAgcHJpdmF0ZSB2b2lkIGluaXQoKSB7Ci0gICAgICAgICAgICBmSW50ZXJuYWxCdWZmZXJQb29sID0gbmV3IENoYXJhY3RlckJ1ZmZlcltwb29sU2l6ZV07Ci0gICAgICAgICAgICBmRXh0ZXJuYWxCdWZmZXJQb29sID0gbmV3IENoYXJhY3RlckJ1ZmZlcltwb29sU2l6ZV07Ci0gICAgICAgICAgICBmSW50ZXJuYWxUb3AgPSAtMTsKLSAgICAgICAgICAgIGZFeHRlcm5hbFRvcCA9IC0xOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqIFJldHJpZXZlcyBidWZmZXIgZnJvbSBwb29sLiAqKi8KLSAgICAgICAgcHVibGljIENoYXJhY3RlckJ1ZmZlciBnZXRCdWZmZXIoYm9vbGVhbiBleHRlcm5hbCkgewotICAgICAgICAgICAgaWYgKGV4dGVybmFsKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGZFeHRlcm5hbFRvcCA+IC0xKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiAoQ2hhcmFjdGVyQnVmZmVyKWZFeHRlcm5hbEJ1ZmZlclBvb2xbZkV4dGVybmFsVG9wLS1dOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBDaGFyYWN0ZXJCdWZmZXIodHJ1ZSwgZkV4dGVybmFsQnVmZmVyU2l6ZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgaWYgKGZJbnRlcm5hbFRvcCA+IC0xKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiAoQ2hhcmFjdGVyQnVmZmVyKWZJbnRlcm5hbEJ1ZmZlclBvb2xbZkludGVybmFsVG9wLS1dOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBDaGFyYWN0ZXJCdWZmZXIoZmFsc2UsIGZJbnRlcm5hbEJ1ZmZlclNpemUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8qKiBSZXR1cm5zIGJ1ZmZlciB0byBwb29sLiAqKi8KLSAgICAgICAgcHVibGljIHZvaWQgcmV0dXJuVG9Qb29sKENoYXJhY3RlckJ1ZmZlciBidWZmZXIpIHsKLSAgICAgICAgICAgIGlmIChidWZmZXIuaXNFeHRlcm5hbCkgewotICAgICAgICAgICAgICAgIGlmIChmRXh0ZXJuYWxUb3AgPCBmRXh0ZXJuYWxCdWZmZXJQb29sLmxlbmd0aCAtIDEpIHsKLSAgICAgICAgICAgICAgICAgICAgZkV4dGVybmFsQnVmZmVyUG9vbFsrK2ZFeHRlcm5hbFRvcF0gPSBidWZmZXI7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoZkludGVybmFsVG9wIDwgZkludGVybmFsQnVmZmVyUG9vbC5sZW5ndGggLSAxKSB7Ci0gICAgICAgICAgICAgICAgZkludGVybmFsQnVmZmVyUG9vbFsrK2ZJbnRlcm5hbFRvcF0gPSBidWZmZXI7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvKiogU2V0cyB0aGUgc2l6ZSBvZiBleHRlcm5hbCBidWZmZXJzIGFuZCBkdW1wcyB0aGUgb2xkIHBvb2wuICoqLwotICAgICAgICBwdWJsaWMgdm9pZCBzZXRFeHRlcm5hbEJ1ZmZlclNpemUoaW50IGJ1ZmZlclNpemUpIHsKLSAgICAgICAgICAgIGZFeHRlcm5hbEJ1ZmZlclNpemUgPSBidWZmZXJTaXplOwotICAgICAgICAgICAgZkV4dGVybmFsQnVmZmVyUG9vbCA9IG5ldyBDaGFyYWN0ZXJCdWZmZXJbcG9vbFNpemVdOwotICAgICAgICAgICAgZkV4dGVybmFsVG9wID0gLTE7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAqIFRoaXMgY2xhc3Mgd3JhcHMgdGhlIGJ5dGUgaW5wdXRzdHJlYW1zIHdlJ3JlIHByZXNlbnRlZCB3aXRoLgotICAgICogV2UgbmVlZCBpdCBiZWNhdXNlIGphdmEuaW8uSW5wdXRTdHJlYW1zIGRvbid0IHByb3ZpZGUKLSAgICAqIGZ1bmN0aW9uYWxpdHkgdG8gcmVyZWFkIHByb2Nlc3NlZCBieXRlcywgYW5kIHRoZXkgaGF2ZSBhIGhhYml0Ci0gICAgKiBvZiByZWFkaW5nIG1vcmUgdGhhbiBvbmUgY2hhcmFjdGVyIHdoZW4geW91IGNhbGwgdGhlaXIgcmVhZCgpCi0gICAgKiBtZXRob2RzLiAgVGhpcyBtZWFucyB0aGF0LCBvbmNlIHdlIGRpc2NvdmVyIHRoZSB0cnVlIChkZWNsYXJlZCkKLSAgICAqIGVuY29kaW5nIG9mIGEgZG9jdW1lbnQsIHdlIGNhbiBuZWl0aGVyIGJhY2t0cmFjayB0byByZWFkIHRoZQotICAgICogd2hvbGUgZG9jIGFnYWluIG5vciBzdGFydCByZWFkaW5nIHdoZXJlIHdlIGFyZSB3aXRoIGEgbmV3Ci0gICAgKiByZWFkZXIuCi0gICAgKgotICAgICogVGhpcyBjbGFzcyBhbGxvd3MgcmV3aW5kaW5nIGFuIGlucHV0U3RyZWFtIGJ5IGFsbG93aW5nIGEgbWFyawotICAgICogdG8gYmUgc2V0LCBhbmQgdGhlIHN0cmVhbSByZXNldCB0byB0aGF0IHBvc2l0aW9uLiAgPHN0cm9uZz5UaGUKLSAgICAqIGNsYXNzIGFzc3VtZXMgdGhhdCBpdCBuZWVkcyB0byByZWFkIG9uZSBjaGFyYWN0ZXIgcGVyCi0gICAgKiBpbnZvY2F0aW9uIHdoZW4gaXQncyByZWFkKCkgbWV0aG9kIGlzIGlub3ZrZWQsIGJ1dCB1c2VzIHRoZQotICAgICogdW5kZXJseWluZyBJbnB1dFN0cmVhbSdzIHJlYWQoY2hhcltdLCBvZmZzZXQgbGVuZ3RoKSBtZXRob2QtLWl0Ci0gICAgKiB3b24ndCBidWZmZXIgZGF0YSByZWFkIHRoaXMgd2F5ITwvc3Ryb25nPgotICAgICoKLSAgICAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAgICAqCi0gICAgKiBAYXV0aG9yIE5laWwgR3JhaGFtLCBJQk0KLSAgICAqIEBhdXRob3IgR2xlbm4gTWFyY3ksIElCTQotICAgICovCi0KLSAgICBwcm90ZWN0ZWQgZmluYWwgY2xhc3MgUmV3aW5kYWJsZUlucHV0U3RyZWFtIGV4dGVuZHMgSW5wdXRTdHJlYW0gewotCi0gICAgICAgIHByaXZhdGUgSW5wdXRTdHJlYW0gZklucHV0U3RyZWFtOwotICAgICAgICBwcml2YXRlIGJ5dGVbXSBmRGF0YTsKLSAgICAgICAgcHJpdmF0ZSBpbnQgZlN0YXJ0T2Zmc2V0OwotICAgICAgICBwcml2YXRlIGludCBmRW5kT2Zmc2V0OwotICAgICAgICBwcml2YXRlIGludCBmT2Zmc2V0OwotICAgICAgICBwcml2YXRlIGludCBmTGVuZ3RoOwotICAgICAgICBwcml2YXRlIGludCBmTWFyazsKLQotICAgICAgICBwdWJsaWMgUmV3aW5kYWJsZUlucHV0U3RyZWFtKElucHV0U3RyZWFtIGlzKSB7Ci0gICAgICAgICAgICBmRGF0YSA9IG5ldyBieXRlW0RFRkFVTFRfWE1MREVDTF9CVUZGRVJfU0laRV07Ci0gICAgICAgICAgICBmSW5wdXRTdHJlYW0gPSBpczsKLSAgICAgICAgICAgIGZTdGFydE9mZnNldCA9IDA7Ci0gICAgICAgICAgICBmRW5kT2Zmc2V0ID0gLTE7Ci0gICAgICAgICAgICBmT2Zmc2V0ID0gMDsKLSAgICAgICAgICAgIGZMZW5ndGggPSAwOwotICAgICAgICAgICAgZk1hcmsgPSAwOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIHZvaWQgc2V0U3RhcnRPZmZzZXQoaW50IG9mZnNldCkgewotICAgICAgICAgICAgZlN0YXJ0T2Zmc2V0ID0gb2Zmc2V0OwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIHZvaWQgcmV3aW5kKCkgewotICAgICAgICAgICAgZk9mZnNldCA9IGZTdGFydE9mZnNldDsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyBpbnQgcmVhZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgICAgICBpbnQgYiA9IDA7Ci0gICAgICAgICAgICBpZiAoZk9mZnNldCA8IGZMZW5ndGgpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZkRhdGFbZk9mZnNldCsrXSAmIDB4ZmY7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoZk9mZnNldCA9PSBmRW5kT2Zmc2V0KSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIC0xOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKGZPZmZzZXQgPT0gZkRhdGEubGVuZ3RoKSB7Ci0gICAgICAgICAgICAgICAgYnl0ZVtdIG5ld0RhdGEgPSBuZXcgYnl0ZVtmT2Zmc2V0IDw8IDFdOwotICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZkRhdGEsIDAsIG5ld0RhdGEsIDAsIGZPZmZzZXQpOwotICAgICAgICAgICAgICAgIGZEYXRhID0gbmV3RGF0YTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGIgPSBmSW5wdXRTdHJlYW0ucmVhZCgpOwotICAgICAgICAgICAgaWYgKGIgPT0gLTEpIHsKLSAgICAgICAgICAgICAgICBmRW5kT2Zmc2V0ID0gZk9mZnNldDsKLSAgICAgICAgICAgICAgICByZXR1cm4gLTE7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmRGF0YVtmTGVuZ3RoKytdID0gKGJ5dGUpYjsKLSAgICAgICAgICAgIGZPZmZzZXQrKzsKLSAgICAgICAgICAgIHJldHVybiBiICYgMHhmZjsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyBpbnQgcmVhZChieXRlW10gYiwgaW50IG9mZiwgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKLSAgICAgICAgICAgIGludCBieXRlc0xlZnQgPSBmTGVuZ3RoIC0gZk9mZnNldDsKLSAgICAgICAgICAgIGlmIChieXRlc0xlZnQgPT0gMCkgewotICAgICAgICAgICAgICAgIGlmIChmT2Zmc2V0ID09IGZFbmRPZmZzZXQpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8qKgotICAgICAgICAgICAgICAgICAqIC8vU3lzdGVtLm91dC5wcmludGxuKCJmQ3VycmVudEVudGl0dHkgPSAiICsgZkN1cnJlbnRFbnRpdHkgKTsKLSAgICAgICAgICAgICAgICAgKiAvL1N5c3RlbS5vdXQucHJpbnRsbigiZklucHV0U3RyZWFtID0gIiArIGZJbnB1dFN0cmVhbSApOwotICAgICAgICAgICAgICAgICAqIC8vIGJldHRlciBnZXQgc29tZSBtb3JlIGZvciB0aGUgdm9yYWNpb3VzIHJlYWRlci4uLiAqLwotCi0gICAgICAgICAgICAgICAgaWYoZkN1cnJlbnRFbnRpdHkubWF5UmVhZENodW5rcyB8fCAhZkN1cnJlbnRFbnRpdHkueG1sRGVjbENodW5rUmVhZCkgewotCi0gICAgICAgICAgICAgICAgICAgIGlmICghZkN1cnJlbnRFbnRpdHkueG1sRGVjbENodW5rUmVhZCkKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkueG1sRGVjbENodW5rUmVhZCA9IHRydWU7Ci0gICAgICAgICAgICAgICAgICAgICAgICBsZW4gPSBFbnRpdHkuU2Nhbm5lZEVudGl0eS5ERUZBVUxUX1hNTERFQ0xfQlVGRkVSX1NJWkU7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZJbnB1dFN0cmVhbS5yZWFkKGIsIG9mZiwgbGVuKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBpbnQgcmV0dXJuZWRWYWwgPSByZWFkKCk7Ci0gICAgICAgICAgICAgICAgaWYocmV0dXJuZWRWYWwgPT0gLTEpIHsKLSAgICAgICAgICAgICAgICAgIGZFbmRPZmZzZXQgPSBmT2Zmc2V0OwotICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBiW29mZl0gPSAoYnl0ZSlyZXR1cm5lZFZhbDsKLSAgICAgICAgICAgICAgICByZXR1cm4gMTsKLQotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKGxlbiA8IGJ5dGVzTGVmdCkgewotICAgICAgICAgICAgICAgIGlmIChsZW4gPD0gMCkgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gMDsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIGxlbiA9IGJ5dGVzTGVmdDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChiICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGZEYXRhLCBmT2Zmc2V0LCBiLCBvZmYsIGxlbik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmT2Zmc2V0ICs9IGxlbjsKLSAgICAgICAgICAgIHJldHVybiBsZW47Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgbG9uZyBza2lwKGxvbmcgbikKLSAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKLSAgICAgICAgICAgIGludCBieXRlc0xlZnQ7Ci0gICAgICAgICAgICBpZiAobiA8PSAwKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIDA7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBieXRlc0xlZnQgPSBmTGVuZ3RoIC0gZk9mZnNldDsKLSAgICAgICAgICAgIGlmIChieXRlc0xlZnQgPT0gMCkgewotICAgICAgICAgICAgICAgIGlmIChmT2Zmc2V0ID09IGZFbmRPZmZzZXQpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDA7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHJldHVybiBmSW5wdXRTdHJlYW0uc2tpcChuKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChuIDw9IGJ5dGVzTGVmdCkgewotICAgICAgICAgICAgICAgIGZPZmZzZXQgKz0gbjsKLSAgICAgICAgICAgICAgICByZXR1cm4gbjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGZPZmZzZXQgKz0gYnl0ZXNMZWZ0OwotICAgICAgICAgICAgaWYgKGZPZmZzZXQgPT0gZkVuZE9mZnNldCkgewotICAgICAgICAgICAgICAgIHJldHVybiBieXRlc0xlZnQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBuIC09IGJ5dGVzTGVmdDsKLSAgICAgICAgICAgIC8qCi0gICAgICAgICAgICAqIEluIGEgbWFubmVyIG9mIHNwZWFraW5nLCB3aGVuIHRoaXMgY2xhc3MgaXNuJ3QgcGVybWl0dGluZyBtb3JlCi0gICAgICAgICAgICAqIHRoYW4gb25lIGJ5dGUgYXQgYSB0aW1lIHRvIGJlIHJlYWQsIGl0IGlzICJibG9ja2luZyIuICBUaGUKLSAgICAgICAgICAgICogYXZhaWxhYmxlKCkgbWV0aG9kIHNob3VsZCBpbmRpY2F0ZSBob3cgbXVjaCBjYW4gYmUgcmVhZCB3aXRob3V0Ci0gICAgICAgICAgICAqIGJsb2NraW5nLCBzbyB3aGlsZSB3ZSdyZSBpbiB0aGlzIG1vZGUsIGl0IHNob3VsZCBvbmx5IGluZGljYXRlCi0gICAgICAgICAgICAqIHRoYXQgYnl0ZXMgaW4gaXRzIGJ1ZmZlciBhcmUgYXZhaWxhYmxlOyBvdGhlcndpc2UsIHRoZSByZXN1bHQgb2YKLSAgICAgICAgICAgICogYXZhaWxhYmxlKCkgb24gdGhlIHVuZGVybHlpbmcgSW5wdXRTdHJlYW0gaXMgYXBwcm9wcmlhdGUuCi0gICAgICAgICAgICAqLwotICAgICAgICAgICAgcmV0dXJuIGZJbnB1dFN0cmVhbS5za2lwKG4pICsgYnl0ZXNMZWZ0OwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIGludCBhdmFpbGFibGUoKSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgICAgICAgICAgaW50IGJ5dGVzTGVmdCA9IGZMZW5ndGggLSBmT2Zmc2V0OwotICAgICAgICAgICAgaWYgKGJ5dGVzTGVmdCA9PSAwKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGZPZmZzZXQgPT0gZkVuZE9mZnNldCkgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHJldHVybiBmQ3VycmVudEVudGl0eS5tYXlSZWFkQ2h1bmtzID8gZklucHV0U3RyZWFtLmF2YWlsYWJsZSgpCi0gICAgICAgICAgICAgICAgOiAwOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIGJ5dGVzTGVmdDsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyB2b2lkIG1hcmsoaW50IGhvd011Y2gpIHsKLSAgICAgICAgICAgIGZNYXJrID0gZk9mZnNldDsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyB2b2lkIHJlc2V0KCkgewotICAgICAgICAgICAgZk9mZnNldCA9IGZNYXJrOwotICAgICAgICAgICAgLy90ZXN0KCk7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgYm9vbGVhbiBtYXJrU3VwcG9ydGVkKCkgewotICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgICAgICBpZiAoZklucHV0U3RyZWFtICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmSW5wdXRTdHJlYW0uY2xvc2UoKTsKLSAgICAgICAgICAgICAgICBmSW5wdXRTdHJlYW0gPSBudWxsOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfSAvLyBlbmQgb2YgUmV3aW5kYWJsZUlucHV0U3RyZWFtIGNsYXNzCi0KLSAgICBwdWJsaWMgdm9pZCB0ZXN0KCl7Ci0gICAgICAgIC8vU3lzdGVtLm91dC5wcmludGxuKCJURVNUSU5HOiBBZGRlZCBmYW1pbHl0cmVlIHRvIGVudGl0eU1hbmFnZXIiKTsKLSAgICAgICAgLy9Vc2VjYXNlMQotICAgICAgICBmRW50aXR5U3RvcmFnZS5hZGRFeHRlcm5hbEVudGl0eSgiZW50aXR5VXNlY2FzZTEiLG51bGwsCi0gICAgICAgICAgICAgICAgIi9zcGFjZS9ob21lL3N0YXgvc3VuLzZ0aEphbjIwMDQvemVwaHlyL2RhdGEvdGVzdC50eHQiLAotICAgICAgICAgICAgICAgICIvc3BhY2UvaG9tZS9zdGF4L3N1bi82dGhKYW4yMDA0L3plcGh5ci9kYXRhL2VudGl0eS54bWwiKTsKLQotICAgICAgICAvL1VzZWNhc2UyCi0gICAgICAgIGZFbnRpdHlTdG9yYWdlLmFkZEludGVybmFsRW50aXR5KCJlbnRpdHlVc2VjYXNlMiIsIjxUZXN0PnZhbHVlPC9UZXN0PiIpOwotICAgICAgICBmRW50aXR5U3RvcmFnZS5hZGRJbnRlcm5hbEVudGl0eSgiZW50aXR5VXNlY2FzZTMiLCJ2YWx1ZTMiKTsKLSAgICAgICAgZkVudGl0eVN0b3JhZ2UuYWRkSW50ZXJuYWxFbnRpdHkoInRleHQiLCAiSGVsbG8gV29ybGQuIik7Ci0gICAgICAgIGZFbnRpdHlTdG9yYWdlLmFkZEludGVybmFsRW50aXR5KCJlbXB0eS1lbGVtZW50IiwgIjxmb28vPiIpOwotICAgICAgICBmRW50aXR5U3RvcmFnZS5hZGRJbnRlcm5hbEVudGl0eSgiYmFsYW5jZWQtZWxlbWVudCIsICI8Zm9vPjwvZm9vPiIpOwotICAgICAgICBmRW50aXR5U3RvcmFnZS5hZGRJbnRlcm5hbEVudGl0eSgiYmFsYW5jZWQtZWxlbWVudC13aXRoLXRleHQiLCAiPGZvbz5IZWxsbywgV29ybGQ8L2Zvbz4iKTsKLSAgICAgICAgZkVudGl0eVN0b3JhZ2UuYWRkSW50ZXJuYWxFbnRpdHkoImJhbGFuY2VkLWVsZW1lbnQtd2l0aC1lbnRpdHkiLCAiPGZvbz4mdGV4dDs8L2Zvbz4iKTsKLSAgICAgICAgZkVudGl0eVN0b3JhZ2UuYWRkSW50ZXJuYWxFbnRpdHkoInVuYmFsYW5jZWQtZW50aXR5IiwgIjxmb28+Iik7Ci0gICAgICAgIGZFbnRpdHlTdG9yYWdlLmFkZEludGVybmFsRW50aXR5KCJyZWN1cnNpdmUtZW50aXR5IiwgIjxmb28+JnJlY3Vyc2l2ZS1lbnRpdHkyOzwvZm9vPiIpOwotICAgICAgICBmRW50aXR5U3RvcmFnZS5hZGRJbnRlcm5hbEVudGl0eSgicmVjdXJzaXZlLWVudGl0eTIiLCAiPGJhcj4mcmVjdXJzaXZlLWVudGl0eTM7PC9iYXI+Iik7Ci0gICAgICAgIGZFbnRpdHlTdG9yYWdlLmFkZEludGVybmFsRW50aXR5KCJyZWN1cnNpdmUtZW50aXR5MyIsICI8YmF6PiZyZWN1cnNpdmUtZW50aXR5OzwvYmF6PiIpOwotICAgICAgICBmRW50aXR5U3RvcmFnZS5hZGRJbnRlcm5hbEVudGl0eSgiY2giLCImI3gwMEE5OyIpOwotICAgICAgICBmRW50aXR5U3RvcmFnZS5hZGRJbnRlcm5hbEVudGl0eSgiY2gxIiwiJiM4NDsiKTsKLSAgICAgICAgZkVudGl0eVN0b3JhZ2UuYWRkSW50ZXJuYWxFbnRpdHkoIiUgY2gyIiwicGFyYW0iKTsKLSAgICB9Ci0KLX0gLy8gY2xhc3MgWE1MRW50aXR5TWFuYWdlcgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9YTUxFbnRpdHlTY2FubmVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL1hNTEVudGl0eVNjYW5uZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZmYwMmJiYS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL1hNTEVudGl0eVNjYW5uZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIzMTggKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwMywgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqLwotLyoKLSAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQotICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCi0gKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCi0gKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAotICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKLSAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbDsKLQotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLlhNTFNjYW5uZXIuTmFtZVR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmlvLkFTQ0lJUmVhZGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5pby5VQ1NSZWFkZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmlvLlVURjhSZWFkZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLm1zZy5YTUxNZXNzYWdlRm9ybWF0dGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5FbmNvZGluZ01hcDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuU3ltYm9sVGFibGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlhNTENoYXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlhNTFN0cmluZ0J1ZmZlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWxzLlhNTExpbWl0QW5hbHl6ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlscy5YTUxTZWN1cml0eU1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlscy5YTUxTZWN1cml0eU1hbmFnZXIuTGltaXQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuKjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MQ29tcG9uZW50TWFuYWdlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLnhtbC5pbnRlcm5hbC5zdHJlYW0uRW50aXR5OwotaW1wb3J0IGNvbS5zdW4ueG1sLmludGVybmFsLnN0cmVhbS5FbnRpdHkuU2Nhbm5lZEVudGl0eTsKLWltcG9ydCBjb20uc3VuLnhtbC5pbnRlcm5hbC5zdHJlYW0uWE1MQnVmZmVyTGlzdGVuZXI7Ci1pbXBvcnQgamF2YS5pby5FT0ZFeGNlcHRpb247Ci1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW1SZWFkZXI7Ci1pbXBvcnQgamF2YS5pby5SZWFkZXI7Ci1pbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKLWltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwotCi0vKioKLSAqIEltcGxlbWVudHMgdGhlIGVudGl0eSBzY2FubmVyIG1ldGhvZHMuCi0gKgotICogQGF1dGhvciBOZWVyYWogQmFqYWosIFN1biBNaWNyb3N5c3RlbXMKLSAqIEBhdXRob3IgQW5keSBDbGFyaywgSUJNCi0gKiBAYXV0aG9yIEFybmF1ZCAgTGUgSG9ycywgSUJNCi0gKiBAYXV0aG9yIEsuVmVudWdvcGFsIFN1biBNaWNyb3N5c3RlbXMKLSAqCi0gKi8KLXB1YmxpYyBjbGFzcyBYTUxFbnRpdHlTY2FubmVyIGltcGxlbWVudHMgWE1MTG9jYXRvciAgewotCi0gICAgcHJvdGVjdGVkIEVudGl0eS5TY2FubmVkRW50aXR5IGZDdXJyZW50RW50aXR5ID0gbnVsbDsKLSAgICBwcm90ZWN0ZWQgaW50IGZCdWZmZXJTaXplID0gWE1MRW50aXR5TWFuYWdlci5ERUZBVUxUX0JVRkZFUl9TSVpFOwotCi0gICAgcHJvdGVjdGVkIFhNTEVudGl0eU1hbmFnZXIgZkVudGl0eU1hbmFnZXI7Ci0KLSAgICAvKiogU2VjdXJpdHkgbWFuYWdlci4gKi8KLSAgICBwcm90ZWN0ZWQgWE1MU2VjdXJpdHlNYW5hZ2VyIGZTZWN1cml0eU1hbmFnZXIgPSBudWxsOwotCi0gICAgLyoqIExpbWl0IGFuYWx5emVyLiAqLwotICAgIHByb3RlY3RlZCBYTUxMaW1pdEFuYWx5emVyIGZMaW1pdEFuYWx5emVyID0gbnVsbDsKLQotICAgIC8qKiBEZWJ1ZyBzd2l0Y2hpbmcgcmVhZGVycyBmb3IgZW5jb2RpbmdzLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW4gREVCVUdfRU5DT0RJTkdTID0gZmFsc2U7Ci0KLSAgICAvKiogTGlzdGVuZXJzIHdoaWNoIHNob3VsZCBrbm93IHdoZW4gbG9hZCBpcyBiZWluZyBjYWxsZWQgKi8KLSAgICBwcml2YXRlIEFycmF5TGlzdDxYTUxCdWZmZXJMaXN0ZW5lcj4gbGlzdGVuZXJzID0gbmV3IEFycmF5TGlzdDw+KCk7Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIFtdIFZBTElEX05BTUVTID0gbmV3IGJvb2xlYW5bMTI3XTsKLQotICAgIC8qKgotICAgICAqIERlYnVnIHByaW50aW5nIG9mIGJ1ZmZlci4gVGhpcyBkZWJ1Z2dpbmcgZmxhZyB3b3JrcyBiZXN0IHdoZW4geW91Ci0gICAgICogcmVzaXplIHRoZSBERUZBVUxUX0JVRkZFUl9TSVpFIGRvd24gdG8gc29tZXRoaW5nIHJlYXNvbmFibGUgbGlrZQotICAgICAqIDY0IGNoYXJhY3RlcnMuCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbiBERUJVR19CVUZGRVIgPSBmYWxzZTsKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIERFQlVHX1NLSVBfU1RSSU5HID0gZmFsc2U7Ci0gICAgLyoqCi0gICAgICogVG8gc2lnbmFsIHRoZSBlbmQgb2YgdGhlIGRvY3VtZW50IGVudGl0eSwgdGhpcyBleGNlcHRpb24gd2lsbCBiZSB0aHJvd24uCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRU9GRXhjZXB0aW9uIEVORF9PRl9ET0NVTUVOVF9FTlRJVFkgPSBuZXcgRU9GRXhjZXB0aW9uKCkgewotICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA5ODAzMzc3NzEyMjQ2NzUyNjhMOwotICAgICAgICBwdWJsaWMgVGhyb3dhYmxlIGZpbGxJblN0YWNrVHJhY2UoKSB7Ci0gICAgICAgICAgICByZXR1cm4gdGhpczsKLSAgICAgICAgfQotICAgIH07Ci0KLSAgICBwcm90ZWN0ZWQgU3ltYm9sVGFibGUgZlN5bWJvbFRhYmxlID0gbnVsbDsKLSAgICBwcm90ZWN0ZWQgWE1MRXJyb3JSZXBvcnRlciBmRXJyb3JSZXBvcnRlciA9IG51bGw7Ci0gICAgaW50IFtdIHdoaXRlU3BhY2VMb29rdXAgPSBuZXcgaW50WzEwMF07Ci0gICAgaW50IHdoaXRlU3BhY2VMZW4gPSAwOwotICAgIGJvb2xlYW4gd2hpdGVTcGFjZUluZm9OZWVkZWQgPSB0cnVlOwotCi0gICAgLyoqCi0gICAgICogQWxsb3cgSmF2YSBlbmNvZGluZyBuYW1lcy4gVGhpcyBmZWF0dXJlIGlkZW50aWZpZXIgaXM6Ci0gICAgICogaHR0cDovL2FwYWNoZS5vcmcveG1sL2ZlYXR1cmVzL2FsbG93LWphdmEtZW5jb2RpbmdzCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZkFsbG93SmF2YUVuY29kaW5nczsKLQotICAgIC8vV2lsbCBiZSB1c2VkIG9ubHkgZHVyaW5nIGludGVybmFsIHN1YnNldHMuCi0gICAgLy9mb3IgYXBwZW5kaW5nIGRhdGEuCi0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogc3ltYm9sIHRhYmxlLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFNZTUJPTF9UQUJMRSA9Ci0gICAgICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5TWU1CT0xfVEFCTEVfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogZXJyb3IgcmVwb3J0ZXIuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJST1JfUkVQT1JURVIgPQotICAgICAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuRVJST1JfUkVQT1JURVJfUFJPUEVSVFk7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiBhbGxvdyBKYXZhIGVuY29kaW5ncy4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBBTExPV19KQVZBX0VOQ09ESU5HUyA9Ci0gICAgICAgICAgICBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLkFMTE9XX0pBVkFfRU5DT0RJTkdTX0ZFQVRVUkU7Ci0KLSAgICBwcm90ZWN0ZWQgUHJvcGVydHlNYW5hZ2VyIGZQcm9wZXJ0eU1hbmFnZXIgPSBudWxsIDsKLQotICAgIGJvb2xlYW4gaXNFeHRlcm5hbCA9IGZhbHNlOwotICAgIHN0YXRpYyB7Ci0KLSAgICAgICAgZm9yKGludCBpPTB4MDA0MTtpPD0weDAwNUEgOyBpKyspewotICAgICAgICAgICAgVkFMSURfTkFNRVNbaV09dHJ1ZTsKLSAgICAgICAgfQotICAgICAgICBmb3IoaW50IGk9MHgwMDYxO2k8PTB4MDA3QTsgaSsrKXsKLSAgICAgICAgICAgIFZBTElEX05BTUVTW2ldPXRydWU7Ci0gICAgICAgIH0KLSAgICAgICAgZm9yKGludCBpPTB4MDAzMDtpPD0weDAwMzk7IGkrKyl7Ci0gICAgICAgICAgICBWQUxJRF9OQU1FU1tpXT10cnVlOwotICAgICAgICB9Ci0gICAgICAgIFZBTElEX05BTUVTWzQ1XT10cnVlOwotICAgICAgICBWQUxJRF9OQU1FU1s0Nl09dHJ1ZTsKLSAgICAgICAgVkFMSURfTkFNRVNbNThdPXRydWU7Ci0gICAgICAgIFZBTElEX05BTUVTWzk1XT10cnVlOwotICAgIH0KLQotICAgIC8vIFJlbWVtYmVyLCB0aGF0IHRoZSBYTUwgdmVyc2lvbiBoYXMgZXhwbGljaXRseSBiZWVuIHNldCwKLSAgICAvLyBzbyB0aGF0IFhNTFN0cmVhbVJlYWRlci5nZXRWZXJzaW9uKCkgY2FuIGZpbmQgdGhhdCBvdXQuCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4geG1sVmVyc2lvblNldEV4cGxpY2l0bHkgPSBmYWxzZTsKLQotICAgIC8vIGluZGljYXRlcyB0aGF0IHRoZSBvcGVyYXRpb24gaXMgZm9yIGRldGVjdGluZyBYTUwgdmVyc2lvbgotICAgIGJvb2xlYW4gZGV0ZWN0aW5nVmVyc2lvbiA9IGZhbHNlOwotCi0gICAgLy8KLSAgICAvLyBDb25zdHJ1Y3RvcnMKLSAgICAvLwotCi0gICAgLyoqIERlZmF1bHQgY29uc3RydWN0b3IuICovCi0gICAgcHVibGljIFhNTEVudGl0eVNjYW5uZXIoKSB7Ci0gICAgfSAvLyA8aW5pdD4oKQotCi0KLSAgICAvKiogIHByaXZhdGUgY29uc3RydWN0b3IsIHRoaXMgY2xhc3MgY2FuIG9ubHkgYmUgaW5zdGFudGlhdGVkIHdpdGhpbiB0aGlzIGNsYXNzLiBJbnN0YW5jZSBvZiB0aGlzIGNsYXNzIHNob3VsZAotICAgICAqICAgIGJlIG9idGFpbmVkIHVzaW5nIGdldEVudGl0eVNjYW5uZXIoKSBvciBnZXRFbnRpdHlTY2FubmVyKFNjYW5uZWRFbnRpdHkgc2Nhbm5lZEVudGl0eSkKLSAgICAgKiAgICBAc2VlIGdldEVudGl0eVNjYW5uZXIoKQotICAgICAqICAgIEBzZWUgZ2V0RW50aXR5U2Nhbm5lcihTY2FubmVkRW50aXR5KQotICAgICAqLwotICAgIHB1YmxpYyBYTUxFbnRpdHlTY2FubmVyKFByb3BlcnR5TWFuYWdlciBwcm9wZXJ0eU1hbmFnZXIsIFhNTEVudGl0eU1hbmFnZXIgZW50aXR5TWFuYWdlcikgewotICAgICAgICBmRW50aXR5TWFuYWdlciA9IGVudGl0eU1hbmFnZXIgOwotICAgICAgICByZXNldChwcm9wZXJ0eU1hbmFnZXIpOwotICAgIH0gLy8gPGluaXQ+KCkKLQotCi0gICAgLy8gc2V0IGJ1ZmZlciBzaXplOgotICAgIHB1YmxpYyBmaW5hbCB2b2lkIHNldEJ1ZmZlclNpemUoaW50IHNpemUpIHsKLSAgICAgICAgLy8gUkVWSVNJVDogQnVmZmVyIHNpemUgcGFzc2VkIHRvIGVudGl0eSBzY2FubmVyCi0gICAgICAgIC8vIHdhcyBub3QgYmVpbmcga2VwdCBpbiBzeW5jaCB3aXRoIHRoZSBhY3R1YWwgc2l6ZQotICAgICAgICAvLyBvZiB0aGUgYnVmZmVycyBpbiBlYWNoIHNjYW5uZWQgZW50aXR5LiBJZiBhbnkKLSAgICAgICAgLy8gb2YgdGhlIGJ1ZmZlcnMgd2VyZSBhY3R1YWxseSByZXNpemVkLCBpdCB3YXMgcG9zc2libGUKLSAgICAgICAgLy8gdGhhdCB0aGUgcGFyc2VyIHdvdWxkIHRocm93IGFuIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgotICAgICAgICAvLyBmb3IgZG9jdW1lbnRzIHdoaWNoIGNvbnRhaW5lZCBuYW1lcyB3aGljaCBhcmUgbG9uZ2VyIHRoYW4KLSAgICAgICAgLy8gdGhlIGN1cnJlbnQgYnVmZmVyIHNpemUuIENvbmNlaXZhYmx5IHRoZSBidWZmZXIgc2l6ZSBwYXNzZWQKLSAgICAgICAgLy8gdG8gZW50aXR5IHNjYW5uZXIgY291bGQgYmUgdXNlZCB0byBkZXRlcm1pbmUgYSBtaW5pbXVtIHNpemUKLSAgICAgICAgLy8gZm9yIHJlc2l6aW5nLCBpZiBkb3VibGluZyBpdHMgc2l6ZSBpcyBzbWFsbGVyIHRoYW4gdGhpcwotICAgICAgICAvLyBtaW5pbXVtLiAtLSBtcmdsYXZhcwotICAgICAgICBmQnVmZmVyU2l6ZSA9IHNpemU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmVzZXRzIHRoZSBjb21wb25lbnRzLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHJlc2V0KFByb3BlcnR5TWFuYWdlciBwcm9wZXJ0eU1hbmFnZXIpewotICAgICAgICBmU3ltYm9sVGFibGUgPSAoU3ltYm9sVGFibGUpcHJvcGVydHlNYW5hZ2VyLmdldFByb3BlcnR5KFNZTUJPTF9UQUJMRSkgOwotICAgICAgICBmRXJyb3JSZXBvcnRlciA9IChYTUxFcnJvclJlcG9ydGVyKXByb3BlcnR5TWFuYWdlci5nZXRQcm9wZXJ0eShFUlJPUl9SRVBPUlRFUikgOwotICAgICAgICByZXNldENvbW1vbigpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJlc2V0cyB0aGUgY29tcG9uZW50LiBUaGUgY29tcG9uZW50IGNhbiBxdWVyeSB0aGUgY29tcG9uZW50IG1hbmFnZXIKLSAgICAgKiBhYm91dCBhbnkgZmVhdHVyZXMgYW5kIHByb3BlcnRpZXMgdGhhdCBhZmZlY3QgdGhlIG9wZXJhdGlvbiBvZiB0aGUKLSAgICAgKiBjb21wb25lbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29tcG9uZW50TWFuYWdlciBUaGUgY29tcG9uZW50IG1hbmFnZXIuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBUaHJvd24gYnkgY29tcG9uZW50IG9uIGluaXRpYWxpemF0aW9uIGVycm9yLgotICAgICAqICAgICAgICAgICAgICAgICAgICAgIEZvciBleGFtcGxlLCBpZiBhIGZlYXR1cmUgb3IgcHJvcGVydHkgaXMKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICByZXF1aXJlZCBmb3IgdGhlIG9wZXJhdGlvbiBvZiB0aGUgY29tcG9uZW50LCB0aGUKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBjb21wb25lbnQgbWFuYWdlciBtYXkgdGhyb3cgYQotICAgICAqICAgICAgICAgICAgICAgICAgICAgIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24gb3IgYQotICAgICAqICAgICAgICAgICAgICAgICAgICAgIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCByZXNldChYTUxDb21wb25lbnRNYW5hZ2VyIGNvbXBvbmVudE1hbmFnZXIpCi0gICAgdGhyb3dzIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gewotICAgICAgICAvLyB4ZXJjZXMgZmVhdHVyZXMKLSAgICAgICAgZkFsbG93SmF2YUVuY29kaW5ncyA9IGNvbXBvbmVudE1hbmFnZXIuZ2V0RmVhdHVyZShBTExPV19KQVZBX0VOQ09ESU5HUywgZmFsc2UpOwotCi0gICAgICAgIC8veGVyY2VzIHByb3BlcnRpZXMKLSAgICAgICAgZlN5bWJvbFRhYmxlID0gKFN5bWJvbFRhYmxlKWNvbXBvbmVudE1hbmFnZXIuZ2V0UHJvcGVydHkoU1lNQk9MX1RBQkxFKTsKLSAgICAgICAgZkVycm9yUmVwb3J0ZXIgPSAoWE1MRXJyb3JSZXBvcnRlciljb21wb25lbnRNYW5hZ2VyLmdldFByb3BlcnR5KEVSUk9SX1JFUE9SVEVSKTsKLSAgICAgICAgcmVzZXRDb21tb24oKTsKLSAgICB9IC8vIHJlc2V0KFhNTENvbXBvbmVudE1hbmFnZXIpCi0KLQotICAgIHB1YmxpYyBmaW5hbCB2b2lkIHJlc2V0KFN5bWJvbFRhYmxlIHN5bWJvbFRhYmxlLCBYTUxFbnRpdHlNYW5hZ2VyIGVudGl0eU1hbmFnZXIsCi0gICAgICAgICAgICBYTUxFcnJvclJlcG9ydGVyIHJlcG9ydGVyKSB7Ci0gICAgICAgIGZDdXJyZW50RW50aXR5ID0gbnVsbDsKLSAgICAgICAgZlN5bWJvbFRhYmxlID0gc3ltYm9sVGFibGU7Ci0gICAgICAgIGZFbnRpdHlNYW5hZ2VyID0gZW50aXR5TWFuYWdlcjsKLSAgICAgICAgZkVycm9yUmVwb3J0ZXIgPSByZXBvcnRlcjsKLSAgICAgICAgZkxpbWl0QW5hbHl6ZXIgPSBmRW50aXR5TWFuYWdlci5mTGltaXRBbmFseXplcjsKLSAgICAgICAgZlNlY3VyaXR5TWFuYWdlciA9IGZFbnRpdHlNYW5hZ2VyLmZTZWN1cml0eU1hbmFnZXI7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIHJlc2V0Q29tbW9uKCkgewotICAgICAgICBmQ3VycmVudEVudGl0eSA9IG51bGw7Ci0gICAgICAgIHdoaXRlU3BhY2VMZW4gPSAwOwotICAgICAgICB3aGl0ZVNwYWNlSW5mb05lZWRlZCA9IHRydWU7Ci0gICAgICAgIGxpc3RlbmVycy5jbGVhcigpOwotICAgICAgICBmTGltaXRBbmFseXplciA9IGZFbnRpdHlNYW5hZ2VyLmZMaW1pdEFuYWx5emVyOwotICAgICAgICBmU2VjdXJpdHlNYW5hZ2VyID0gZkVudGl0eU1hbmFnZXIuZlNlY3VyaXR5TWFuYWdlcjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBYTUwgdmVyc2lvbiBvZiB0aGUgY3VycmVudCBlbnRpdHkuIFRoaXMgd2lsbCBub3JtYWxseSBiZSB0aGUKLSAgICAgKiB2YWx1ZSBmcm9tIHRoZSBYTUwgb3IgdGV4dCBkZWNsYXJhdGlvbiBvciBkZWZhdWx0ZWQgYnkgdGhlIHBhcnNlci4gTm90ZSB0aGF0Ci0gICAgICogdGhhdCB0aGlzIHZhbHVlIG1heSBiZSBkaWZmZXJlbnQgdGhhbiB0aGUgdmVyc2lvbiBvZiB0aGUgcHJvY2Vzc2luZyBydWxlcwotICAgICAqIGFwcGxpZWQgdG8gdGhlIGN1cnJlbnQgZW50aXR5LiBGb3IgaW5zdGFuY2UsIGFuIFhNTCAxLjEgZG9jdW1lbnQgbWF5IHJlZmVyIHRvCi0gICAgICogWE1MIDEuMCBlbnRpdGllcy4gSW4gc3VjaCBhIGNhc2UgdGhlIHJ1bGVzIG9mIFhNTCAxLjEgYXJlIGFwcGxpZWQgdG8gdGhlIGVudGlyZQotICAgICAqIGRvY3VtZW50LiBBbHNvIG5vdGUgdGhhdCwgZm9yIGEgZ2l2ZW4gZW50aXR5LCB0aGlzIHZhbHVlIGNhbiBvbmx5IGJlIGNvbnNpZGVyZWQKLSAgICAgKiBmaW5hbCBvbmNlIHRoZSBYTUwgb3IgdGV4dCBkZWNsYXJhdGlvbiBoYXMgYmVlbiByZWFkIG9yIG9uY2UgaXQgaGFzIGJlZW4KLSAgICAgKiBkZXRlcm1pbmVkIHRoYXQgdGhlcmUgaXMgbm8gc3VjaCBkZWNsYXJhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgZmluYWwgU3RyaW5nIGdldFhNTFZlcnNpb24oKSB7Ci0gICAgICAgIGlmIChmQ3VycmVudEVudGl0eSAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gZkN1cnJlbnRFbnRpdHkueG1sVmVyc2lvbjsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9IC8vIGdldFhNTFZlcnNpb24oKTpTdHJpbmcKLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIFhNTCB2ZXJzaW9uLiBUaGlzIG1ldGhvZCBpcyB1c2VkIGJ5IHRoZQotICAgICAqIHNjYW5uZXJzIHRvIHJlcG9ydCB0aGUgdmFsdWUgb2YgdGhlIHZlcnNpb24gcHNldWRvLWF0dHJpYnV0ZQotICAgICAqIGluIGFuIFhNTCBvciB0ZXh0IGRlY2xhcmF0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIHhtbFZlcnNpb24gdGhlIFhNTCB2ZXJzaW9uIG9mIHRoZSBjdXJyZW50IGVudGl0eQotICAgICAqLwotICAgIHB1YmxpYyBmaW5hbCB2b2lkIHNldFhNTFZlcnNpb24oU3RyaW5nIHhtbFZlcnNpb24pIHsKLSAgICAgICAgeG1sVmVyc2lvblNldEV4cGxpY2l0bHkgPSB0cnVlOwotICAgICAgICBmQ3VycmVudEVudGl0eS54bWxWZXJzaW9uID0geG1sVmVyc2lvbjsKLSAgICB9IC8vIHNldFhNTFZlcnNpb24oU3RyaW5nKQotCi0KLSAgICAvKiogc2V0IHRoZSBpbnN0YW5jZSBvZiBjdXJyZW50IHNjYW5uZWQgZW50aXR5LgotICAgICAqICAgQHBhcmFtIFNjYW5uZWRFbnRpdHkKLSAgICAgKi8KLQotICAgIHB1YmxpYyBmaW5hbCB2b2lkIHNldEN1cnJlbnRFbnRpdHkoRW50aXR5LlNjYW5uZWRFbnRpdHkgc2Nhbm5lZEVudGl0eSl7Ci0gICAgICAgIGZDdXJyZW50RW50aXR5ID0gc2Nhbm5lZEVudGl0eSA7Ci0gICAgICAgIGlmKGZDdXJyZW50RW50aXR5ICE9IG51bGwpewotICAgICAgICAgICAgaXNFeHRlcm5hbCA9IGZDdXJyZW50RW50aXR5LmlzRXh0ZXJuYWwoKTsKLSAgICAgICAgICAgIGlmKERFQlVHX0JVRkZFUikKLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkN1cnJlbnQgRW50aXR5IGlzICIrc2Nhbm5lZEVudGl0eS5uYW1lKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyAgRW50aXR5LlNjYW5uZWRFbnRpdHkgZ2V0Q3VycmVudEVudGl0eSgpewotICAgICAgICByZXR1cm4gZkN1cnJlbnRFbnRpdHkgOwotICAgIH0KLSAgICAvLwotICAgIC8vIFhNTEVudGl0eVJlYWRlciBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIGJhc2Ugc3lzdGVtIGlkZW50aWZpZXIgb2YgdGhlIGN1cnJlbnRseSBzY2FubmVkCi0gICAgICogZW50aXR5LCBvciBudWxsIGlmIG5vbmUgaXMgYXZhaWxhYmxlLgotICAgICAqLwotICAgIHB1YmxpYyBmaW5hbCBTdHJpbmcgZ2V0QmFzZVN5c3RlbUlkKCkgewotICAgICAgICByZXR1cm4gKGZDdXJyZW50RW50aXR5ICE9IG51bGwgJiYgZkN1cnJlbnRFbnRpdHkuZW50aXR5TG9jYXRpb24gIT0gbnVsbCkgPyBmQ3VycmVudEVudGl0eS5lbnRpdHlMb2NhdGlvbi5nZXRFeHBhbmRlZFN5c3RlbUlkKCkgOiBudWxsOwotICAgIH0gLy8gZ2V0QmFzZVN5c3RlbUlkKCk6U3RyaW5nCi0KLSAgICAvKioKLSAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTFJlc291cmNlSWRlbnRpZmllciNzZXRCYXNlU3lzdGVtSWQoU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEJhc2VTeXN0ZW1JZChTdHJpbmcgc3lzdGVtSWQpIHsKLSAgICAgICAgLy9uby1vcAotICAgIH0KLQotICAgIC8vLy8vLy8vLy8vLy8gTG9jYXRvciBtZXRob2RzIHN0YXJ0LgotICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0TGluZU51bWJlcigpewotICAgICAgICAvL2lmIHRoZSBlbnRpdHkgaXMgY2xvc2VkLCB3ZSBzaG91bGQgcmV0dXJuIC0xCi0gICAgICAgIC8veHh4IGF0IGZpcnN0IHBsYWNlIHdoeSBzdWNoIGNhbGwgc2hvdWxkIGJlIHRoZXJlLi4uCi0gICAgICAgIHJldHVybiBmQ3VycmVudEVudGl0eSAhPSBudWxsID8gZkN1cnJlbnRFbnRpdHkubGluZU51bWJlciA6IC0xIDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTExvY2F0b3Ijc2V0TGluZU51bWJlcihpbnQpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0TGluZU51bWJlcihpbnQgbGluZSkgewotICAgICAgICAvL25vLW9wCi0gICAgfQotCi0KLSAgICBwdWJsaWMgZmluYWwgaW50IGdldENvbHVtbk51bWJlcigpewotICAgICAgICAvL2lmIHRoZSBlbnRpdHkgaXMgY2xvc2VkLCB3ZSBzaG91bGQgcmV0dXJuIC0xCi0gICAgICAgIC8veHh4IGF0IGZpcnN0IHBsYWNlIHdoeSBzdWNoIGNhbGwgc2hvdWxkIGJlIHRoZXJlLi4uCi0gICAgICAgIHJldHVybiBmQ3VycmVudEVudGl0eSAhPSBudWxsID8gZkN1cnJlbnRFbnRpdHkuY29sdW1uTnVtYmVyIDogLTEgOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MTG9jYXRvciNzZXRDb2x1bW5OdW1iZXIoaW50KQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldENvbHVtbk51bWJlcihpbnQgY29sKSB7Ci0gICAgICAgIC8vIG5vLW9wCi0gICAgfQotCi0KLSAgICBwdWJsaWMgZmluYWwgaW50IGdldENoYXJhY3Rlck9mZnNldCgpewotICAgICAgICByZXR1cm4gZkN1cnJlbnRFbnRpdHkgIT0gbnVsbCA/IGZDdXJyZW50RW50aXR5LmZUb3RhbENvdW50VGlsbExhc3RMb2FkICsgZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gOiAtMSA7Ci0gICAgfQotCi0gICAgLyoqIFJldHVybnMgdGhlIGV4cGFuZGVkIHN5c3RlbSBpZGVudGlmaWVyLiAgKi8KLSAgICBwdWJsaWMgZmluYWwgU3RyaW5nIGdldEV4cGFuZGVkU3lzdGVtSWQoKSB7Ci0gICAgICAgIHJldHVybiAoZkN1cnJlbnRFbnRpdHkgIT0gbnVsbCAmJiBmQ3VycmVudEVudGl0eS5lbnRpdHlMb2NhdGlvbiAhPSBudWxsKSA/IGZDdXJyZW50RW50aXR5LmVudGl0eUxvY2F0aW9uLmdldEV4cGFuZGVkU3lzdGVtSWQoKSA6IG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxSZXNvdXJjZUlkZW50aWZpZXIjc2V0RXhwYW5kZWRTeXN0ZW1JZChTdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RXhwYW5kZWRTeXN0ZW1JZChTdHJpbmcgc3lzdGVtSWQpIHsKLSAgICAgICAgLy9uby1vcAotICAgIH0KLQotICAgIC8qKiBSZXR1cm5zIHRoZSBsaXRlcmFsIHN5c3RlbSBpZGVudGlmaWVyLiAgKi8KLSAgICBwdWJsaWMgZmluYWwgU3RyaW5nIGdldExpdGVyYWxTeXN0ZW1JZCgpIHsKLSAgICAgICAgcmV0dXJuIChmQ3VycmVudEVudGl0eSAhPSBudWxsICYmIGZDdXJyZW50RW50aXR5LmVudGl0eUxvY2F0aW9uICE9IG51bGwpID8gZkN1cnJlbnRFbnRpdHkuZW50aXR5TG9jYXRpb24uZ2V0TGl0ZXJhbFN5c3RlbUlkKCkgOiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MUmVzb3VyY2VJZGVudGlmaWVyI3NldExpdGVyYWxTeXN0ZW1JZChTdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0TGl0ZXJhbFN5c3RlbUlkKFN0cmluZyBzeXN0ZW1JZCkgewotICAgICAgICAvL25vLW9wCi0gICAgfQotCi0gICAgLyoqIFJldHVybnMgdGhlIHB1YmxpYyBpZGVudGlmaWVyLiAgKi8KLSAgICBwdWJsaWMgZmluYWwgU3RyaW5nIGdldFB1YmxpY0lkKCkgewotICAgICAgICByZXR1cm4gKGZDdXJyZW50RW50aXR5ICE9IG51bGwgJiYgZkN1cnJlbnRFbnRpdHkuZW50aXR5TG9jYXRpb24gIT0gbnVsbCkgPyBmQ3VycmVudEVudGl0eS5lbnRpdHlMb2NhdGlvbi5nZXRQdWJsaWNJZCgpIDogbnVsbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTFJlc291cmNlSWRlbnRpZmllciNzZXRQdWJsaWNJZChTdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0UHVibGljSWQoU3RyaW5nIHB1YmxpY0lkKSB7Ci0gICAgICAgIC8vbm8tb3AKLSAgICB9Ci0KLSAgICAvLy8vLy8vLy8vLy8vLy8vLyBMb2NhdG9yIG1ldGhvZHMgZmluaXNoZWQuCi0KLSAgICAvKiogdGhlIHZlcnNpb24gb2YgdGhlIGN1cnJlbnQgZW50aXR5IGJlaW5nIHNjYW5uZWQgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRWZXJzaW9uKFN0cmluZyB2ZXJzaW9uKXsKLSAgICAgICAgZkN1cnJlbnRFbnRpdHkudmVyc2lvbiA9IHZlcnNpb247Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRWZXJzaW9uKCl7Ci0gICAgICAgIGlmIChmQ3VycmVudEVudGl0eSAhPSBudWxsKQotICAgICAgICAgICAgcmV0dXJuIGZDdXJyZW50RW50aXR5LnZlcnNpb24gOwotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBlbmNvZGluZyBvZiB0aGUgY3VycmVudCBlbnRpdHkuCi0gICAgICogTm90ZSB0aGF0LCBmb3IgYSBnaXZlbiBlbnRpdHksIHRoaXMgdmFsdWUgY2FuIG9ubHkgYmUKLSAgICAgKiBjb25zaWRlcmVkIGZpbmFsIG9uY2UgdGhlIGVuY29kaW5nIGRlY2xhcmF0aW9uIGhhcyBiZWVuIHJlYWQgKG9yIG9uY2UgaXQKLSAgICAgKiBoYXMgYmVlbiBkZXRlcm1pbmVkIHRoYXQgdGhlcmUgaXMgbm8gc3VjaCBkZWNsYXJhdGlvbikgc2luY2UsIG5vIGVuY29kaW5nCi0gICAgICogaGF2aW5nIGJlZW4gc3BlY2lmaWVkIG9uIHRoZSBYTUxJbnB1dFNvdXJjZSwgdGhlIHBhcnNlcgotICAgICAqIHdpbGwgbWFrZSBhbiBpbml0aWFsICJndWVzcyIgd2hpY2ggY291bGQgYmUgaW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIFN0cmluZyBnZXRFbmNvZGluZygpIHsKLSAgICAgICAgaWYgKGZDdXJyZW50RW50aXR5ICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBmQ3VycmVudEVudGl0eS5lbmNvZGluZzsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9IC8vIGdldEVuY29kaW5nKCk6U3RyaW5nCi0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSBlbmNvZGluZyBvZiB0aGUgc2Nhbm5lci4gVGhpcyBtZXRob2QgaXMgdXNlZCBieSB0aGUKLSAgICAgKiBzY2FubmVycyBpZiB0aGUgWE1MRGVjbCBvciBUZXh0RGVjbCBsaW5lIGNvbnRhaW5zIGFuIGVuY29kaW5nCi0gICAgICogcHNldWRvLWF0dHJpYnV0ZS4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoZSB1bmRlcmx5aW5nIGNoYXJhY3RlciByZWFkZXIgb24gdGhlCi0gICAgICogY3VycmVudCBlbnRpdHkgd2lsbCBiZSBjaGFuZ2VkIHRvIGFjY29tb2RhdGUgdGhlIG5ldyBlbmNvZGluZy4KLSAgICAgKiBIb3dldmVyLCB0aGUgbmV3IGVuY29kaW5nIGlzIGlnbm9yZWQgaWYgdGhlIGN1cnJlbnQgcmVhZGVyIHdhcwotICAgICAqIG5vdCBjb25zdHJ1Y3RlZCBmcm9tIGFuIGlucHV0IHN0cmVhbSAoZS5nLiBhbiBleHRlcm5hbCBlbnRpdHkKLSAgICAgKiB0aGF0IGlzIHJlc29sdmVkIGRpcmVjdGx5IHRvIHRoZSBhcHByb3ByaWF0ZSBqYXZhLmlvLlJlYWRlcgotICAgICAqIG9iamVjdCkuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZW5jb2RpbmcgVGhlIElBTkEgZW5jb2RpbmcgbmFtZSBvZiB0aGUgbmV3IGVuY29kaW5nLgotICAgICAqCi0gICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBUaHJvd24gaWYgdGhlIG5ldyBlbmNvZGluZyBpcyBub3Qgc3VwcG9ydGVkLgotICAgICAqCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuRW5jb2RpbmdNYXAKLSAgICAgKi8KLSAgICBwdWJsaWMgZmluYWwgdm9pZCBzZXRFbmNvZGluZyhTdHJpbmcgZW5jb2RpbmcpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0KLSAgICAgICAgaWYgKERFQlVHX0VOQ09ESU5HUykgewotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCIkJCQgc2V0RW5jb2Rpbmc6ICIrZW5jb2RpbmcpOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKGZDdXJyZW50RW50aXR5LnN0cmVhbSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAvLyBpZiB0aGUgZW5jb2RpbmcgaXMgdGhlIHNhbWUsIGRvbid0IGNoYW5nZSB0aGUgcmVhZGVyIGFuZAotICAgICAgICAgICAgLy8gcmUtdXNlIHRoZSBvcmlnaW5hbCByZWFkZXIgdXNlZCBieSB0aGUgT25lQ2hhclJlYWRlcgotICAgICAgICAgICAgLy8gTk9URTogQmVzaWRlcyBzYXZpbmcgYW4gb2JqZWN0LCB0aGlzIG92ZXJjb21lcyBkZWZpY2llbmNpZXMKLSAgICAgICAgICAgIC8vICAgICAgIGluIHRoZSBVVEYtMTYgcmVhZGVyIHN1cHBsaWVkIHdpdGggdGhlIHN0YW5kYXJkIEphdmEKLSAgICAgICAgICAgIC8vICAgICAgIGRpc3RyaWJ1dGlvbiAodXAgdG8gYW5kIGluY2x1ZGluZyAxLjMpLiBUaGUgVVRGLTE2Ci0gICAgICAgICAgICAvLyAgICAgICBkZWNvZGVyIGJ1ZmZlcnMgOEsgYmxvY2tzIGV2ZW4gd2hlbiBvbmx5IGFza2VkIHRvIHJlYWQKLSAgICAgICAgICAgIC8vICAgICAgIGEgc2luZ2xlIGNoYXIhIC1BYwotICAgICAgICAgICAgaWYgKGZDdXJyZW50RW50aXR5LmVuY29kaW5nID09IG51bGwgfHwKLSAgICAgICAgICAgICAgICAgICAgIWZDdXJyZW50RW50aXR5LmVuY29kaW5nLmVxdWFscyhlbmNvZGluZykpIHsKLSAgICAgICAgICAgICAgICAvLyBVVEYtMTYgaXMgYSBiaXQgb2YgYSBzcGVjaWFsIGNhc2UuICBJZiB0aGUgZW5jb2RpbmcgaXMgVVRGLTE2LAotICAgICAgICAgICAgICAgIC8vIGFuZCB3ZSBrbm93IHRoZSBlbmRpYW4tbmVzcywgd2Ugc2hvdWxkbid0IGNoYW5nZSByZWFkZXJzLgotICAgICAgICAgICAgICAgIC8vIElmIGl0J3MgSVNPLTEwNjQ2LVVDUy0oMnw0KSwgdGhlbiB3ZSdsbCBoYXZlIHRvIGRlZHVjZQotICAgICAgICAgICAgICAgIC8vIHRoZSBlbmRpYW4tbmVzcyBmcm9tIHRoZSBlbmNvZGluZyB3ZSBwcmVzZW50bHkgaGF2ZS4KLSAgICAgICAgICAgICAgICBpZihmQ3VycmVudEVudGl0eS5lbmNvZGluZyAhPSBudWxsICYmIGZDdXJyZW50RW50aXR5LmVuY29kaW5nLnN0YXJ0c1dpdGgoIlVURi0xNiIpKSB7Ci0gICAgICAgICAgICAgICAgICAgIFN0cmluZyBFTkNPRElORyA9IGVuY29kaW5nLnRvVXBwZXJDYXNlKExvY2FsZS5FTkdMSVNIKTsKLSAgICAgICAgICAgICAgICAgICAgaWYoRU5DT0RJTkcuZXF1YWxzKCJVVEYtMTYiKSkgcmV0dXJuOwotICAgICAgICAgICAgICAgICAgICBpZihFTkNPRElORy5lcXVhbHMoIklTTy0xMDY0Ni1VQ1MtNCIpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZihmQ3VycmVudEVudGl0eS5lbmNvZGluZy5lcXVhbHMoIlVURi0xNkJFIikpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5yZWFkZXIgPSBuZXcgVUNTUmVhZGVyKGZDdXJyZW50RW50aXR5LnN0cmVhbSwgVUNTUmVhZGVyLlVDUzRCRSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LnJlYWRlciA9IG5ldyBVQ1NSZWFkZXIoZkN1cnJlbnRFbnRpdHkuc3RyZWFtLCBVQ1NSZWFkZXIuVUNTNExFKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBpZihFTkNPRElORy5lcXVhbHMoIklTTy0xMDY0Ni1VQ1MtMiIpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZihmQ3VycmVudEVudGl0eS5lbmNvZGluZy5lcXVhbHMoIlVURi0xNkJFIikpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5yZWFkZXIgPSBuZXcgVUNTUmVhZGVyKGZDdXJyZW50RW50aXR5LnN0cmVhbSwgVUNTUmVhZGVyLlVDUzJCRSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LnJlYWRlciA9IG5ldyBVQ1NSZWFkZXIoZkN1cnJlbnRFbnRpdHkuc3RyZWFtLCBVQ1NSZWFkZXIuVUNTMkxFKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvLyB3cmFwIGEgbmV3IHJlYWRlciBhcm91bmQgdGhlIGlucHV0IHN0cmVhbSwgY2hhbmdpbmcKLSAgICAgICAgICAgICAgICAvLyB0aGUgZW5jb2RpbmcKLSAgICAgICAgICAgICAgICBpZiAoREVCVUdfRU5DT0RJTkdTKSB7Ci0gICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiJCQkIGNyZWF0aW5nIG5ldyByZWFkZXIgZnJvbSBzdHJlYW06ICIrCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkuc3RyZWFtKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLy9mQ3VycmVudEVudGl0eS5zdHJlYW0ucmVzZXQoKTsKLSAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5yZWFkZXIgPSBjcmVhdGVSZWFkZXIoZkN1cnJlbnRFbnRpdHkuc3RyZWFtLCBlbmNvZGluZywgbnVsbCk7Ci0gICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkuZW5jb2RpbmcgPSBlbmNvZGluZzsKLQotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBpZiAoREVCVUdfRU5DT0RJTkdTKQotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIiQkJCByZXVzaW5nIG9sZCByZWFkZXIgb24gc3RyZWFtIik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgIH0gLy8gc2V0RW5jb2RpbmcoU3RyaW5nKQotCi0gICAgLyoqIFJldHVybnMgdHJ1ZSBpZiB0aGUgY3VycmVudCBlbnRpdHkgYmVpbmcgc2Nhbm5lZCBpcyBleHRlcm5hbC4gKi8KLSAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0V4dGVybmFsKCkgewotICAgICAgICByZXR1cm4gZkN1cnJlbnRFbnRpdHkuaXNFeHRlcm5hbCgpOwotICAgIH0gLy8gaXNFeHRlcm5hbCgpOmJvb2xlYW4KLQotICAgIHB1YmxpYyBpbnQgZ2V0Q2hhcihpbnQgcmVsYXRpdmUpIHRocm93cyBJT0V4Y2VwdGlvbnsKLSAgICAgICAgaWYoYXJyYW5nZUNhcGFjaXR5KHJlbGF0aXZlICsgMSwgZmFsc2UpKXsKLSAgICAgICAgICAgIHJldHVybiBmQ3VycmVudEVudGl0eS5jaFtmQ3VycmVudEVudGl0eS5wb3NpdGlvbiArIHJlbGF0aXZlXTsKLSAgICAgICAgfWVsc2V7Ci0gICAgICAgICAgICByZXR1cm4gLTE7Ci0gICAgICAgIH0KLSAgICB9Ly9nZXRDaGFyKCkKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIG5leHQgY2hhcmFjdGVyIG9uIHRoZSBpbnB1dC4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoZSBjaGFyYWN0ZXIgaXMgPGVtPm5vdDwvZW0+IGNvbnN1bWVkLgotICAgICAqCi0gICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiAgVGhyb3duIGlmIGkvbyBlcnJvciBvY2N1cnMuCi0gICAgICogQHRocm93cyBFT0ZFeGNlcHRpb24gVGhyb3duIG9uIGVuZCBvZiBmaWxlLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgcGVla0NoYXIoKSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgICAgICBpZiAoREVCVUdfQlVGRkVSKSB7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCIocGVla0NoYXI6ICIpOwotICAgICAgICAgICAgcHJpbnQoKTsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gbG9hZCBtb3JlIGNoYXJhY3RlcnMsIGlmIG5lZWRlZAotICAgICAgICBpZiAoZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gPT0gZkN1cnJlbnRFbnRpdHkuY291bnQpIHsKLSAgICAgICAgICAgIGxvYWQoMCwgdHJ1ZSwgdHJ1ZSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBwZWVrIGF0IGNoYXJhY3RlcgotICAgICAgICBpbnQgYyA9IGZDdXJyZW50RW50aXR5LmNoW2ZDdXJyZW50RW50aXR5LnBvc2l0aW9uXTsKLQotICAgICAgICAvLyByZXR1cm4gcGVla2VkIGNoYXJhY3RlcgotICAgICAgICBpZiAoREVCVUdfQlVGRkVSKSB7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCIpcGVla0NoYXI6ICIpOwotICAgICAgICAgICAgcHJpbnQoKTsKLSAgICAgICAgICAgIGlmIChpc0V4dGVybmFsKSB7Ci0gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCIgLT4gJyIrKGMhPSdccic/KGNoYXIpYzonXG4nKSsiJyIpOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIiAtPiAnIisoY2hhciljKyInIik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGlzRXh0ZXJuYWwpIHsKLSAgICAgICAgICAgIHJldHVybiBjICE9ICdccicgPyBjIDogJ1xuJzsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiBjOwotICAgICAgICB9Ci0KLSAgICB9IC8vIHBlZWtDaGFyKCk6aW50Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBuZXh0IGNoYXJhY3RlciBvbiB0aGUgaW5wdXQuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGUgY2hhcmFjdGVyIGlzIGNvbnN1bWVkLgotICAgICAqCi0gICAgICogQHBhcmFtIG50IFRoZSB0eXBlIG9mIHRoZSBuYW1lIChlbGVtZW50IG9yIGF0dHJpYnV0ZSkKLSAgICAgKgotICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gIFRocm93biBpZiBpL28gZXJyb3Igb2NjdXJzLgotICAgICAqIEB0aHJvd3MgRU9GRXhjZXB0aW9uIFRocm93biBvbiBlbmQgb2YgZmlsZS4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgaW50IHNjYW5DaGFyKE5hbWVUeXBlIG50KSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgICAgICBpZiAoREVCVUdfQlVGRkVSKSB7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCIoc2NhbkNoYXI6ICIpOwotICAgICAgICAgICAgcHJpbnQoKTsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gbG9hZCBtb3JlIGNoYXJhY3RlcnMsIGlmIG5lZWRlZAotICAgICAgICBpZiAoZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gPT0gZkN1cnJlbnRFbnRpdHkuY291bnQpIHsKLSAgICAgICAgICAgIGxvYWQoMCwgdHJ1ZSwgdHJ1ZSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBzY2FuIGNoYXJhY3RlcgotICAgICAgICBpbnQgb2Zmc2V0ID0gZkN1cnJlbnRFbnRpdHkucG9zaXRpb247Ci0gICAgICAgIGludCBjID0gZkN1cnJlbnRFbnRpdHkuY2hbZkN1cnJlbnRFbnRpdHkucG9zaXRpb24rK107Ci0gICAgICAgIGlmIChjID09ICdcbicgfHwgKGMgPT0gJ1xyJyAmJiBpc0V4dGVybmFsKSkgewotICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkubGluZU51bWJlcisrOwotICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkuY29sdW1uTnVtYmVyID0gMTsKLSAgICAgICAgICAgIGlmIChmQ3VycmVudEVudGl0eS5wb3NpdGlvbiA9PSBmQ3VycmVudEVudGl0eS5jb3VudCkgewotICAgICAgICAgICAgICAgIGludm9rZUxpc3RlbmVycygxKTsKLSAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5jaFswXSA9IChjaGFyKWM7Ci0gICAgICAgICAgICAgICAgbG9hZCgxLCBmYWxzZSwgZmFsc2UpOwotICAgICAgICAgICAgICAgIG9mZnNldCA9IDA7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoYyA9PSAnXHInICYmIGlzRXh0ZXJuYWwpIHsKLSAgICAgICAgICAgICAgICBpZiAoZkN1cnJlbnRFbnRpdHkuY2hbZkN1cnJlbnRFbnRpdHkucG9zaXRpb24rK10gIT0gJ1xuJykgewotICAgICAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5wb3NpdGlvbi0tOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBjID0gJ1xuJzsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIHJldHVybiBjaGFyYWN0ZXIgdGhhdCB3YXMgc2Nhbm5lZAotICAgICAgICBpZiAoREVCVUdfQlVGRkVSKSB7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCIpc2NhbkNoYXI6ICIpOwotICAgICAgICAgICAgcHJpbnQoKTsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiIC0+ICciKyhjaGFyKWMrIiciKTsKLSAgICAgICAgfQotICAgICAgICBmQ3VycmVudEVudGl0eS5jb2x1bW5OdW1iZXIrKzsKLSAgICAgICAgaWYgKCFkZXRlY3RpbmdWZXJzaW9uKSB7Ci0gICAgICAgICAgICBjaGVja0VudGl0eUxpbWl0KG50LCBmQ3VycmVudEVudGl0eSwgb2Zmc2V0LCBmQ3VycmVudEVudGl0eS5wb3NpdGlvbiAtIG9mZnNldCk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGM7Ci0KLSAgICB9IC8vIHNjYW5DaGFyKCk6aW50Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGEgc3RyaW5nIG1hdGNoaW5nIHRoZSBOTVRPS0VOIHByb2R1Y3Rpb24gYXBwZWFyaW5nIGltbWVkaWF0ZWx5Ci0gICAgICogb24gdGhlIGlucHV0IGFzIGEgc3ltYm9sLCBvciBudWxsIGlmIE5NVE9LRU4gTmFtZSBzdHJpbmcgaXMgcHJlc2VudC4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoZSBOTVRPS0VOIGNoYXJhY3RlcnMgYXJlIGNvbnN1bWVkLgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gVGhlIHN0cmluZyByZXR1cm5lZCBtdXN0IGJlIGEgc3ltYm9sLiBUaGUKLSAgICAgKiBTeW1ib2xUYWJsZSBjYW4gYmUgdXNlZCBmb3IgdGhpcyBwdXJwb3NlLgotICAgICAqCi0gICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiAgVGhyb3duIGlmIGkvbyBlcnJvciBvY2N1cnMuCi0gICAgICogQHRocm93cyBFT0ZFeGNlcHRpb24gVGhyb3duIG9uIGVuZCBvZiBmaWxlLgotICAgICAqCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuU3ltYm9sVGFibGUKLSAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5YTUxDaGFyI2lzTmFtZQotICAgICAqLwotICAgIHByb3RlY3RlZCBTdHJpbmcgc2Nhbk5tdG9rZW4oKSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgICAgICBpZiAoREVCVUdfQlVGRkVSKSB7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCIoc2Nhbk5tdG9rZW46ICIpOwotICAgICAgICAgICAgcHJpbnQoKTsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gbG9hZCBtb3JlIGNoYXJhY3RlcnMsIGlmIG5lZWRlZAotICAgICAgICBpZiAoZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gPT0gZkN1cnJlbnRFbnRpdHkuY291bnQpIHsKLSAgICAgICAgICAgIGxvYWQoMCwgdHJ1ZSwgdHJ1ZSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBzY2FuIG5tdG9rZW4KLSAgICAgICAgaW50IG9mZnNldCA9IGZDdXJyZW50RW50aXR5LnBvc2l0aW9uOwotICAgICAgICBib29sZWFuIHZjID0gZmFsc2U7Ci0gICAgICAgIGNoYXIgYzsKLSAgICAgICAgd2hpbGUgKHRydWUpewotICAgICAgICAgICAgLy93aGlsZSAoWE1MQ2hhci5pc05hbWUoZkN1cnJlbnRFbnRpdHkuY2hbZkN1cnJlbnRFbnRpdHkucG9zaXRpb25dKSkgewotICAgICAgICAgICAgYyA9IGZDdXJyZW50RW50aXR5LmNoW2ZDdXJyZW50RW50aXR5LnBvc2l0aW9uXTsKLSAgICAgICAgICAgIGlmKGMgPCAxMjcpewotICAgICAgICAgICAgICAgIHZjID0gVkFMSURfTkFNRVNbY107Ci0gICAgICAgICAgICB9ZWxzZXsKLSAgICAgICAgICAgICAgICB2YyA9IFhNTENoYXIuaXNOYW1lKGMpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYoIXZjKWJyZWFrOwotCi0gICAgICAgICAgICBpZiAoKytmQ3VycmVudEVudGl0eS5wb3NpdGlvbiA9PSBmQ3VycmVudEVudGl0eS5jb3VudCkgewotICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBmQ3VycmVudEVudGl0eS5wb3NpdGlvbiAtIG9mZnNldDsKLSAgICAgICAgICAgICAgICBpbnZva2VMaXN0ZW5lcnMobGVuZ3RoKTsKLSAgICAgICAgICAgICAgICBpZiAobGVuZ3RoID09IGZDdXJyZW50RW50aXR5LmZCdWZmZXJTaXplKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIGJhZCBsdWNrIHdlIGhhdmUgdG8gcmVzaXplIG91ciBidWZmZXIKLSAgICAgICAgICAgICAgICAgICAgY2hhcltdIHRtcCA9IG5ldyBjaGFyW2ZDdXJyZW50RW50aXR5LmZCdWZmZXJTaXplICogMl07Ci0gICAgICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZkN1cnJlbnRFbnRpdHkuY2gsIG9mZnNldCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB0bXAsIDAsIGxlbmd0aCk7Ci0gICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LmNoID0gdG1wOwotICAgICAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5mQnVmZmVyU2l6ZSAqPSAyOwotICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZkN1cnJlbnRFbnRpdHkuY2gsIG9mZnNldCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5jaCwgMCwgbGVuZ3RoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgb2Zmc2V0ID0gMDsKLSAgICAgICAgICAgICAgICBpZiAobG9hZChsZW5ndGgsIGZhbHNlLCBmYWxzZSkpIHsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGludCBsZW5ndGggPSBmQ3VycmVudEVudGl0eS5wb3NpdGlvbiAtIG9mZnNldDsKLSAgICAgICAgZkN1cnJlbnRFbnRpdHkuY29sdW1uTnVtYmVyICs9IGxlbmd0aDsKLQotICAgICAgICAvLyByZXR1cm4gbm10b2tlbgotICAgICAgICBTdHJpbmcgc3ltYm9sID0gbnVsbDsKLSAgICAgICAgaWYgKGxlbmd0aCA+IDApIHsKLSAgICAgICAgICAgIHN5bWJvbCA9IGZTeW1ib2xUYWJsZS5hZGRTeW1ib2woZkN1cnJlbnRFbnRpdHkuY2gsIG9mZnNldCwgbGVuZ3RoKTsKLSAgICAgICAgfQotICAgICAgICBpZiAoREVCVUdfQlVGRkVSKSB7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCIpc2Nhbk5tdG9rZW46ICIpOwotICAgICAgICAgICAgcHJpbnQoKTsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiIC0+ICIrU3RyaW5nLnZhbHVlT2Yoc3ltYm9sKSk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHN5bWJvbDsKLQotICAgIH0gLy8gc2Nhbk5tdG9rZW4oKTpTdHJpbmcKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYSBzdHJpbmcgbWF0Y2hpbmcgdGhlIE5hbWUgcHJvZHVjdGlvbiBhcHBlYXJpbmcgaW1tZWRpYXRlbHkKLSAgICAgKiBvbiB0aGUgaW5wdXQgYXMgYSBzeW1ib2wsIG9yIG51bGwgaWYgbm8gTmFtZSBzdHJpbmcgaXMgcHJlc2VudC4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoZSBOYW1lIGNoYXJhY3RlcnMgYXJlIGNvbnN1bWVkLgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gVGhlIHN0cmluZyByZXR1cm5lZCBtdXN0IGJlIGEgc3ltYm9sLiBUaGUKLSAgICAgKiBTeW1ib2xUYWJsZSBjYW4gYmUgdXNlZCBmb3IgdGhpcyBwdXJwb3NlLgotICAgICAqCi0gICAgICogQHBhcmFtIG50IFRoZSB0eXBlIG9mIHRoZSBuYW1lIChlbGVtZW50IG9yIGF0dHJpYnV0ZSkKLSAgICAgKgotICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gIFRocm93biBpZiBpL28gZXJyb3Igb2NjdXJzLgotICAgICAqIEB0aHJvd3MgRU9GRXhjZXB0aW9uIFRocm93biBvbiBlbmQgb2YgZmlsZS4KLSAgICAgKgotICAgICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlN5bWJvbFRhYmxlCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuWE1MQ2hhciNpc05hbWUKLSAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5YTUxDaGFyI2lzTmFtZVN0YXJ0Ci0gICAgICovCi0gICAgcHJvdGVjdGVkIFN0cmluZyBzY2FuTmFtZShOYW1lVHlwZSBudCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKERFQlVHX0JVRkZFUikgewotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiKHNjYW5OYW1lOiAiKTsKLSAgICAgICAgICAgIHByaW50KCk7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIGxvYWQgbW9yZSBjaGFyYWN0ZXJzLCBpZiBuZWVkZWQKLSAgICAgICAgaWYgKGZDdXJyZW50RW50aXR5LnBvc2l0aW9uID09IGZDdXJyZW50RW50aXR5LmNvdW50KSB7Ci0gICAgICAgICAgICBsb2FkKDAsIHRydWUsIHRydWUpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gc2NhbiBuYW1lCi0gICAgICAgIGludCBvZmZzZXQgPSBmQ3VycmVudEVudGl0eS5wb3NpdGlvbjsKLSAgICAgICAgaW50IGxlbmd0aDsKLSAgICAgICAgaWYgKFhNTENoYXIuaXNOYW1lU3RhcnQoZkN1cnJlbnRFbnRpdHkuY2hbb2Zmc2V0XSkpIHsKLSAgICAgICAgICAgIGlmICgrK2ZDdXJyZW50RW50aXR5LnBvc2l0aW9uID09IGZDdXJyZW50RW50aXR5LmNvdW50KSB7Ci0gICAgICAgICAgICAgICAgaW52b2tlTGlzdGVuZXJzKDEpOwotICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LmNoWzBdID0gZkN1cnJlbnRFbnRpdHkuY2hbb2Zmc2V0XTsKLSAgICAgICAgICAgICAgICBvZmZzZXQgPSAwOwotICAgICAgICAgICAgICAgIGlmIChsb2FkKDEsIGZhbHNlLCBmYWxzZSkpIHsKLSAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkuY29sdW1uTnVtYmVyKys7Ci0gICAgICAgICAgICAgICAgICAgIFN0cmluZyBzeW1ib2wgPSBmU3ltYm9sVGFibGUuYWRkU3ltYm9sKGZDdXJyZW50RW50aXR5LmNoLCAwLCAxKTsKLQotICAgICAgICAgICAgICAgICAgICBpZiAoREVCVUdfQlVGRkVSKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCIpc2Nhbk5hbWU6ICIpOwotICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnQoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiIC0+ICIrU3RyaW5nLnZhbHVlT2Yoc3ltYm9sKSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN5bWJvbDsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBib29sZWFuIHZjID1mYWxzZTsKLSAgICAgICAgICAgIHdoaWxlICh0cnVlICl7Ci0gICAgICAgICAgICAgICAgLy9YTUxDaGFyLmlzTmFtZShmQ3VycmVudEVudGl0eS5jaFtmQ3VycmVudEVudGl0eS5wb3NpdGlvbl0pKSA7Ci0gICAgICAgICAgICAgICAgY2hhciBjID0gZkN1cnJlbnRFbnRpdHkuY2hbZkN1cnJlbnRFbnRpdHkucG9zaXRpb25dOwotICAgICAgICAgICAgICAgIGlmKGMgPCAxMjcpewotICAgICAgICAgICAgICAgICAgICB2YyA9IFZBTElEX05BTUVTW2NdOwotICAgICAgICAgICAgICAgIH1lbHNlewotICAgICAgICAgICAgICAgICAgICB2YyA9IFhNTENoYXIuaXNOYW1lKGMpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpZighdmMpYnJlYWs7Ci0gICAgICAgICAgICAgICAgaWYgKChsZW5ndGggPSBjaGVja0JlZm9yZUxvYWQoZkN1cnJlbnRFbnRpdHksIG9mZnNldCwgb2Zmc2V0KSkgPiAwKSB7Ci0gICAgICAgICAgICAgICAgICAgIG9mZnNldCA9IDA7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChsb2FkKGxlbmd0aCwgZmFsc2UsIGZhbHNlKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgbGVuZ3RoID0gZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gLSBvZmZzZXQ7Ci0gICAgICAgIGZDdXJyZW50RW50aXR5LmNvbHVtbk51bWJlciArPSBsZW5ndGg7Ci0KLSAgICAgICAgLy8gcmV0dXJuIG5hbWUKLSAgICAgICAgU3RyaW5nIHN5bWJvbDsKLSAgICAgICAgaWYgKGxlbmd0aCA+IDApIHsKLSAgICAgICAgICAgIGNoZWNrTGltaXQoTGltaXQuTUFYX05BTUVfTElNSVQsIGZDdXJyZW50RW50aXR5LCBvZmZzZXQsIGxlbmd0aCk7Ci0gICAgICAgICAgICBjaGVja0VudGl0eUxpbWl0KG50LCBmQ3VycmVudEVudGl0eSwgb2Zmc2V0LCBsZW5ndGgpOwotICAgICAgICAgICAgc3ltYm9sID0gZlN5bWJvbFRhYmxlLmFkZFN5bWJvbChmQ3VycmVudEVudGl0eS5jaCwgb2Zmc2V0LCBsZW5ndGgpOwotICAgICAgICB9IGVsc2UKLSAgICAgICAgICAgIHN5bWJvbCA9IG51bGw7Ci0gICAgICAgIGlmIChERUJVR19CVUZGRVIpIHsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIilzY2FuTmFtZTogIik7Ci0gICAgICAgICAgICBwcmludCgpOwotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCIgLT4gIitTdHJpbmcudmFsdWVPZihzeW1ib2wpKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gc3ltYm9sOwotCi0gICAgfSAvLyBzY2FuTmFtZSgpOlN0cmluZwotCi0gICAgLyoqCi0gICAgICogU2NhbnMgYSBxdWFsaWZpZWQgbmFtZSBmcm9tIHRoZSBpbnB1dCwgc2V0dGluZyB0aGUgZmllbGRzIG9mIHRoZQotICAgICAqIFFOYW1lIHN0cnVjdHVyZSBhcHByb3ByaWF0ZWx5LgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gVGhlIHF1YWxpZmllZCBuYW1lIGNoYXJhY3RlcnMgYXJlIGNvbnN1bWVkLgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gVGhlIHN0cmluZ3MgdXNlZCB0byBzZXQgdGhlIHZhbHVlcyBvZiB0aGUKLSAgICAgKiBRTmFtZSBzdHJ1Y3R1cmUgbXVzdCBiZSBzeW1ib2xzLiBUaGUgU3ltYm9sVGFibGUgY2FuIGJlIHVzZWQgZm9yCi0gICAgICogdGhpcyBwdXJwb3NlLgotICAgICAqCi0gICAgICogQHBhcmFtIHFuYW1lIFRoZSBxdWFsaWZpZWQgbmFtZSBzdHJ1Y3R1cmUgdG8gZmlsbC4KLSAgICAgKiBAcGFyYW0gbnQgVGhlIHR5cGUgb2YgdGhlIG5hbWUgKGVsZW1lbnQgb3IgYXR0cmlidXRlKQotICAgICAqCi0gICAgICogQHJldHVybiBSZXR1cm5zIHRydWUgaWYgYSBxdWFsaWZpZWQgbmFtZSBhcHBlYXJlZCBpbW1lZGlhdGVseSBvbgotICAgICAqICAgICAgICAgdGhlIGlucHV0IGFuZCB3YXMgc2Nhbm5lZCwgZmFsc2Ugb3RoZXJ3aXNlLgotICAgICAqCi0gICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiAgVGhyb3duIGlmIGkvbyBlcnJvciBvY2N1cnMuCi0gICAgICogQHRocm93cyBFT0ZFeGNlcHRpb24gVGhyb3duIG9uIGVuZCBvZiBmaWxlLgotICAgICAqCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuU3ltYm9sVGFibGUKLSAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5YTUxDaGFyI2lzTmFtZQotICAgICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlhNTENoYXIjaXNOYW1lU3RhcnQKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBzY2FuUU5hbWUoUU5hbWUgcW5hbWUsIE5hbWVUeXBlIG50KSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgICAgICBpZiAoREVCVUdfQlVGRkVSKSB7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCIoc2NhblFOYW1lLCAiK3FuYW1lKyI6ICIpOwotICAgICAgICAgICAgcHJpbnQoKTsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gbG9hZCBtb3JlIGNoYXJhY3RlcnMsIGlmIG5lZWRlZAotICAgICAgICBpZiAoZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gPT0gZkN1cnJlbnRFbnRpdHkuY291bnQpIHsKLSAgICAgICAgICAgIGxvYWQoMCwgdHJ1ZSwgdHJ1ZSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBzY2FuIHF1YWxpZmllZCBuYW1lCi0gICAgICAgIGludCBvZmZzZXQgPSBmQ3VycmVudEVudGl0eS5wb3NpdGlvbjsKLQotICAgICAgICAvL21ha2luZyBhIGNoZWNrIGlmIGlmIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyIGlzIGEgdmFsaWQgbmFtZSBzdGFydCBjaGFyYWN0ZXIKLSAgICAgICAgLy9hcyBkZWZpbmVkIGJ5IHByb2R1Y3Rpb24gWzVdIGluIHRoZSBYTUwgMS4wIHNwZWNpZmljYXRpb24uCi0gICAgICAgIC8vIE5hbWUgOjo9IChMZXR0ZXIgfCAnXycgfCAnOicpIChOYW1lQ2hhcikqCi0KLSAgICAgICAgaWYgKFhNTENoYXIuaXNOYW1lU3RhcnQoZkN1cnJlbnRFbnRpdHkuY2hbb2Zmc2V0XSkpIHsKLSAgICAgICAgICAgIGlmICgrK2ZDdXJyZW50RW50aXR5LnBvc2l0aW9uID09IGZDdXJyZW50RW50aXR5LmNvdW50KSB7Ci0gICAgICAgICAgICAgICAgaW52b2tlTGlzdGVuZXJzKDEpOwotICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LmNoWzBdID0gZkN1cnJlbnRFbnRpdHkuY2hbb2Zmc2V0XTsKLSAgICAgICAgICAgICAgICBvZmZzZXQgPSAwOwotCi0gICAgICAgICAgICAgICAgaWYgKGxvYWQoMSwgZmFsc2UsIGZhbHNlKSkgewotICAgICAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5jb2x1bW5OdW1iZXIrKzsKLSAgICAgICAgICAgICAgICAgICAgLy9hZGRpbmcgaW50byBzeW1ib2wgdGFibGUuCi0gICAgICAgICAgICAgICAgICAgIC8vWFhYIFdlIGFyZSB0cnlpbmcgdG8gYWRkIHNpbmdsZSBjaGFyYWN0ZXIgaW4gU3ltYm9sVGFibGU/Pz8/Pz8KLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG5hbWUgPSBmU3ltYm9sVGFibGUuYWRkU3ltYm9sKGZDdXJyZW50RW50aXR5LmNoLCAwLCAxKTsKLSAgICAgICAgICAgICAgICAgICAgcW5hbWUuc2V0VmFsdWVzKG51bGwsIG5hbWUsIG5hbWUsIG51bGwpOwotICAgICAgICAgICAgICAgICAgICBpZiAoREVCVUdfQlVGRkVSKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCIpc2NhblFOYW1lLCAiK3FuYW1lKyI6ICIpOwotICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnQoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiIC0+IHRydWUiKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBjaGVja0VudGl0eUxpbWl0KG50LCBmQ3VycmVudEVudGl0eSwgMCwgMSk7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGludCBpbmRleCA9IC0xOwotICAgICAgICAgICAgYm9vbGVhbiB2YyA9IGZhbHNlOwotICAgICAgICAgICAgaW50IGxlbmd0aDsKLSAgICAgICAgICAgIHdoaWxlICggdHJ1ZSl7Ci0KLSAgICAgICAgICAgICAgICAvL1hNTENoYXIuaXNOYW1lKGZDdXJyZW50RW50aXR5LmNoW2ZDdXJyZW50RW50aXR5LnBvc2l0aW9uXSkpIDsKLSAgICAgICAgICAgICAgICBjaGFyIGMgPSBmQ3VycmVudEVudGl0eS5jaFtmQ3VycmVudEVudGl0eS5wb3NpdGlvbl07Ci0gICAgICAgICAgICAgICAgaWYoYyA8IDEyNyl7Ci0gICAgICAgICAgICAgICAgICAgIHZjID0gVkFMSURfTkFNRVNbY107Ci0gICAgICAgICAgICAgICAgfWVsc2V7Ci0gICAgICAgICAgICAgICAgICAgIHZjID0gWE1MQ2hhci5pc05hbWUoYyk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGlmKCF2YylicmVhazsKLSAgICAgICAgICAgICAgICBpZiAoYyA9PSAnOicpIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGluZGV4ICE9IC0xKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBpbmRleCA9IGZDdXJyZW50RW50aXR5LnBvc2l0aW9uOwotICAgICAgICAgICAgICAgICAgICAvL2NoZWNrIHByZWZpeCBiZWZvcmUgZnVydGhlciByZWFkCi0gICAgICAgICAgICAgICAgICAgIGNoZWNrTGltaXQoTGltaXQuTUFYX05BTUVfTElNSVQsIGZDdXJyZW50RW50aXR5LCBvZmZzZXQsIGluZGV4IC0gb2Zmc2V0KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaWYgKChsZW5ndGggPSBjaGVja0JlZm9yZUxvYWQoZkN1cnJlbnRFbnRpdHksIG9mZnNldCwgaW5kZXgpKSA+IDApIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGluZGV4ICE9IC0xKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpbmRleCA9IGluZGV4IC0gb2Zmc2V0OwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIG9mZnNldCA9IDA7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChsb2FkKGxlbmd0aCwgZmFsc2UsIGZhbHNlKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBsZW5ndGggPSBmQ3VycmVudEVudGl0eS5wb3NpdGlvbiAtIG9mZnNldDsKLSAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LmNvbHVtbk51bWJlciArPSBsZW5ndGg7Ci0gICAgICAgICAgICBpZiAobGVuZ3RoID4gMCkgewotICAgICAgICAgICAgICAgIFN0cmluZyBwcmVmaXggPSBudWxsOwotICAgICAgICAgICAgICAgIFN0cmluZyBsb2NhbHBhcnQgPSBudWxsOwotICAgICAgICAgICAgICAgIFN0cmluZyByYXduYW1lID0gZlN5bWJvbFRhYmxlLmFkZFN5bWJvbChmQ3VycmVudEVudGl0eS5jaCwKLSAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldCwgbGVuZ3RoKTsKLQotICAgICAgICAgICAgICAgIGlmIChpbmRleCAhPSAtMSkgewotICAgICAgICAgICAgICAgICAgICBpbnQgcHJlZml4TGVuZ3RoID0gaW5kZXggLSBvZmZzZXQ7Ci0gICAgICAgICAgICAgICAgICAgIC8vY2hlY2sgdGhlIHJlc3VsdDogcHJlZml4Ci0gICAgICAgICAgICAgICAgICAgIGNoZWNrTGltaXQoTGltaXQuTUFYX05BTUVfTElNSVQsIGZDdXJyZW50RW50aXR5LCBvZmZzZXQsIHByZWZpeExlbmd0aCk7Ci0gICAgICAgICAgICAgICAgICAgIHByZWZpeCA9IGZTeW1ib2xUYWJsZS5hZGRTeW1ib2woZkN1cnJlbnRFbnRpdHkuY2gsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0LCBwcmVmaXhMZW5ndGgpOwotICAgICAgICAgICAgICAgICAgICBpbnQgbGVuID0gbGVuZ3RoIC0gcHJlZml4TGVuZ3RoIC0gMTsKLSAgICAgICAgICAgICAgICAgICAgLy9jaGVjayB0aGUgcmVzdWx0OiBsb2NhbHBhcnQKLSAgICAgICAgICAgICAgICAgICAgY2hlY2tMaW1pdChMaW1pdC5NQVhfTkFNRV9MSU1JVCwgZkN1cnJlbnRFbnRpdHksIGluZGV4ICsgMSwgbGVuKTsKLSAgICAgICAgICAgICAgICAgICAgbG9jYWxwYXJ0ID0gZlN5bWJvbFRhYmxlLmFkZFN5bWJvbChmQ3VycmVudEVudGl0eS5jaCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmRleCArIDEsIGxlbik7Ci0KLSAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICBsb2NhbHBhcnQgPSByYXduYW1lOwotICAgICAgICAgICAgICAgICAgICAvL2NoZWNrIHRoZSByZXN1bHQ6IGxvY2FscGFydAotICAgICAgICAgICAgICAgICAgICBjaGVja0xpbWl0KExpbWl0Lk1BWF9OQU1FX0xJTUlULCBmQ3VycmVudEVudGl0eSwgb2Zmc2V0LCBsZW5ndGgpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBxbmFtZS5zZXRWYWx1ZXMocHJlZml4LCBsb2NhbHBhcnQsIHJhd25hbWUsIG51bGwpOwotICAgICAgICAgICAgICAgIGlmIChERUJVR19CVUZGRVIpIHsKLSAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiKXNjYW5RTmFtZSwgIitxbmFtZSsiOiAiKTsKLSAgICAgICAgICAgICAgICAgICAgcHJpbnQoKTsKLSAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCIgLT4gdHJ1ZSIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBjaGVja0VudGl0eUxpbWl0KG50LCBmQ3VycmVudEVudGl0eSwgb2Zmc2V0LCBsZW5ndGgpOwotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gbm8gcXVhbGlmaWVkIG5hbWUgZm91bmQKLSAgICAgICAgaWYgKERFQlVHX0JVRkZFUikgewotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiKXNjYW5RTmFtZSwgIitxbmFtZSsiOiAiKTsKLSAgICAgICAgICAgIHByaW50KCk7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIiAtPiBmYWxzZSIpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLQotICAgIH0gLy8gc2NhblFOYW1lKFFOYW1lKTpib29sZWFuCi0KLSAgICAvKioKLSAgICAgKiBDaGVja3Mgd2hldGhlciB0aGUgZW5kIG9mIHRoZSBlbnRpdHkgYnVmZmVyIGhhcyBiZWVuIHJlYWNoZWQuIElmIHllcywKLSAgICAgKiBjaGVja3MgYWdhaW5zdCB0aGUgbGltaXQgYW5kIGJ1ZmZlciBzaXplIGJlZm9yZSBsb2FkaW5nIG1vcmUgY2hhcmFjdGVycy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlbnRpdHkgdGhlIGN1cnJlbnQgZW50aXR5Ci0gICAgICogQHBhcmFtIG9mZnNldCB0aGUgb2Zmc2V0IGZyb20gd2hpY2ggdGhlIGN1cnJlbnQgcmVhZCB3YXMgc3RhcnRlZAotICAgICAqIEBwYXJhbSBuYW1lT2Zmc2V0IHRoZSBvZmZzZXQgZnJvbSB3aGljaCB0aGUgY3VycmVudCBuYW1lIHN0YXJ0cwotICAgICAqIEByZXR1cm4gdGhlIGxlbmd0aCBvZiBjaGFyYWN0ZXJzIHNjYW5uZWQgYmVmb3JlIHRoZSBlbmQgb2YgdGhlIGJ1ZmZlciwKLSAgICAgKiB6ZXJvIGlmIHRoZXJlIGlzIG1vcmUgdG8gYmUgcmVhZCBpbiB0aGUgYnVmZmVyCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGludCBjaGVja0JlZm9yZUxvYWQoRW50aXR5LlNjYW5uZWRFbnRpdHkgZW50aXR5LCBpbnQgb2Zmc2V0LAotICAgICAgICAgICAgaW50IG5hbWVPZmZzZXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgIGludCBsZW5ndGggPSAwOwotICAgICAgICBpZiAoKytlbnRpdHkucG9zaXRpb24gPT0gZW50aXR5LmNvdW50KSB7Ci0gICAgICAgICAgICBsZW5ndGggPSBlbnRpdHkucG9zaXRpb24gLSBvZmZzZXQ7Ci0gICAgICAgICAgICBpbnQgbmFtZUxlbmd0aCA9IGxlbmd0aDsKLSAgICAgICAgICAgIGlmIChuYW1lT2Zmc2V0ICE9IC0xKSB7Ci0gICAgICAgICAgICAgICAgbmFtZU9mZnNldCA9IG5hbWVPZmZzZXQgLSBvZmZzZXQ7Ci0gICAgICAgICAgICAgICAgbmFtZUxlbmd0aCA9IGxlbmd0aCAtIG5hbWVPZmZzZXQ7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIG5hbWVPZmZzZXQgPSBvZmZzZXQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvL2NoZWNrIGxpbWl0IGJlZm9yZSBsb2FkaW5nIG1vcmUgZGF0YQotICAgICAgICAgICAgY2hlY2tMaW1pdChMaW1pdC5NQVhfTkFNRV9MSU1JVCwgZW50aXR5LCBuYW1lT2Zmc2V0LCBuYW1lTGVuZ3RoKTsKLSAgICAgICAgICAgIGludm9rZUxpc3RlbmVycyhsZW5ndGgpOwotICAgICAgICAgICAgaWYgKGxlbmd0aCA9PSBlbnRpdHkuY2gubGVuZ3RoKSB7Ci0gICAgICAgICAgICAgICAgLy8gYmFkIGx1Y2sgd2UgaGF2ZSB0byByZXNpemUgb3VyIGJ1ZmZlcgotICAgICAgICAgICAgICAgIGNoYXJbXSB0bXAgPSBuZXcgY2hhcltlbnRpdHkuZkJ1ZmZlclNpemUgKiAyXTsKLSAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGVudGl0eS5jaCwgb2Zmc2V0LCB0bXAsIDAsIGxlbmd0aCk7Ci0gICAgICAgICAgICAgICAgZW50aXR5LmNoID0gdG1wOwotICAgICAgICAgICAgICAgIGVudGl0eS5mQnVmZmVyU2l6ZSAqPSAyOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShlbnRpdHkuY2gsIG9mZnNldCwgZW50aXR5LmNoLCAwLCBsZW5ndGgpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBsZW5ndGg7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSWYgdGhlIGN1cnJlbnQgZW50aXR5IGlzIGFuIEVudGl0eSByZWZlcmVuY2UsIGNoZWNrIHRoZSBhY2N1bXVsYXRlZCBzaXplCi0gICAgICogYWdhaW5zdCB0aGUgbGltaXQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbnQgdHlwZSBvZiBuYW1lIChlbGVtZW50LCBhdHRyaWJ1dGUgb3IgZW50aXR5KQotICAgICAqIEBwYXJhbSBlbnRpdHkgVGhlIGN1cnJlbnQgZW50aXR5Ci0gICAgICogQHBhcmFtIG9mZnNldCBUaGUgaW5kZXggb2YgdGhlIGZpcnN0IGJ5dGUKLSAgICAgKiBAcGFyYW0gbGVuZ3RoIFRoZSBsZW5ndGggb2YgdGhlIGVudGl0eSBzY2FubmVkCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgY2hlY2tFbnRpdHlMaW1pdChOYW1lVHlwZSBudCwgU2Nhbm5lZEVudGl0eSBlbnRpdHksIGludCBvZmZzZXQsIGludCBsZW5ndGgpIHsKLSAgICAgICAgaWYgKGVudGl0eSA9PSBudWxsIHx8ICFlbnRpdHkuaXNHRSkgewotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKG50ICE9IE5hbWVUeXBlLlJFRkVSRU5DRSkgewotICAgICAgICAgICAgY2hlY2tMaW1pdChMaW1pdC5HRU5FUkFMX0VOVElUWV9TSVpFX0xJTUlULCBlbnRpdHksIG9mZnNldCwgbGVuZ3RoKTsKLSAgICAgICAgfQotICAgICAgICBpZiAobnQgPT0gTmFtZVR5cGUuRUxFTUVOVFNUQVJUIHx8IG50ID09IE5hbWVUeXBlLkFUVFJJQlVURU5BTUUpIHsKLSAgICAgICAgICAgIGNoZWNrTm9kZUNvdW50KGVudGl0eSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJZiB0aGUgY3VycmVudCBlbnRpdHkgaXMgYW4gRW50aXR5IHJlZmVyZW5jZSwgY291bnRzIHRoZSB0b3RhbCBub2RlcyBpbgotICAgICAqIHRoZSBlbnRpdHkgYW5kIGNoZWNrcyB0aGUgYWNjdW11bGF0ZWQgdmFsdWUgYWdhaW5zdCB0aGUgbGltaXQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZW50aXR5IFRoZSBjdXJyZW50IGVudGl0eQotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIGNoZWNrTm9kZUNvdW50KFNjYW5uZWRFbnRpdHkgZW50aXR5KSB7Ci0gICAgICAgIGlmIChlbnRpdHkgIT0gbnVsbCAmJiBlbnRpdHkuaXNHRSkgewotICAgICAgICAgICAgY2hlY2tMaW1pdChMaW1pdC5FTlRJVFlfUkVQTEFDRU1FTlRfTElNSVQsIGVudGl0eSwgMCwgMSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDaGVja3Mgd2hldGhlciB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBMaW1pdCBleGNlZWRzIGl0cyBsaW1pdAotICAgICAqCi0gICAgICogQHBhcmFtIGxpbWl0IFRoZSBMaW1pdCB0byBiZSBjaGVja2VkCi0gICAgICogQHBhcmFtIGVudGl0eSBUaGUgY3VycmVudCBlbnRpdHkKLSAgICAgKiBAcGFyYW0gb2Zmc2V0IFRoZSBpbmRleCBvZiB0aGUgZmlyc3QgYnl0ZQotICAgICAqIEBwYXJhbSBsZW5ndGggVGhlIGxlbmd0aCBvZiB0aGUgZW50aXR5IHNjYW5uZWQKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCBjaGVja0xpbWl0KExpbWl0IGxpbWl0LCBTY2FubmVkRW50aXR5IGVudGl0eSwgaW50IG9mZnNldCwgaW50IGxlbmd0aCkgewotICAgICAgICBmTGltaXRBbmFseXplci5hZGRWYWx1ZShsaW1pdCwgZW50aXR5Lm5hbWUsIGxlbmd0aCk7Ci0gICAgICAgIGlmIChmU2VjdXJpdHlNYW5hZ2VyLmlzT3ZlckxpbWl0KGxpbWl0LCBmTGltaXRBbmFseXplcikpIHsKLSAgICAgICAgICAgIGZTZWN1cml0eU1hbmFnZXIuZGVidWdQcmludChmTGltaXRBbmFseXplcik7Ci0gICAgICAgICAgICBPYmplY3RbXSBlID0gKGxpbWl0ID09IExpbWl0LkVOVElUWV9SRVBMQUNFTUVOVF9MSU1JVCkgPwotICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117ZkxpbWl0QW5hbHl6ZXIuZ2V0VmFsdWUobGltaXQpLAotICAgICAgICAgICAgICAgICAgICAgICAgZlNlY3VyaXR5TWFuYWdlci5nZXRMaW1pdChsaW1pdCksIGZTZWN1cml0eU1hbmFnZXIuZ2V0U3RhdGVMaXRlcmFsKGxpbWl0KX0gOgotICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117ZW50aXR5Lm5hbWUsIGZMaW1pdEFuYWx5emVyLmdldFZhbHVlKGxpbWl0KSwKLSAgICAgICAgICAgICAgICAgICAgICAgIGZTZWN1cml0eU1hbmFnZXIuZ2V0TGltaXQobGltaXQpLCBmU2VjdXJpdHlNYW5hZ2VyLmdldFN0YXRlTGl0ZXJhbChsaW1pdCl9OwotICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLCBsaW1pdC5rZXkoKSwKLSAgICAgICAgICAgICAgICAgICAgZSwgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9GQVRBTF9FUlJPUik7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGZTZWN1cml0eU1hbmFnZXIuaXNPdmVyTGltaXQoTGltaXQuVE9UQUxfRU5USVRZX1NJWkVfTElNSVQsIGZMaW1pdEFuYWx5emVyKSkgewotICAgICAgICAgICAgZlNlY3VyaXR5TWFuYWdlci5kZWJ1Z1ByaW50KGZMaW1pdEFuYWx5emVyKTsKLSAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwgIlRvdGFsRW50aXR5U2l6ZUxpbWl0IiwKLSAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde2ZMaW1pdEFuYWx5emVyLmdldFRvdGFsVmFsdWUoTGltaXQuVE9UQUxfRU5USVRZX1NJWkVfTElNSVQpLAotICAgICAgICAgICAgICAgIGZTZWN1cml0eU1hbmFnZXIuZ2V0TGltaXQoTGltaXQuVE9UQUxfRU5USVRZX1NJWkVfTElNSVQpLAotICAgICAgICAgICAgICAgIGZTZWN1cml0eU1hbmFnZXIuZ2V0U3RhdGVMaXRlcmFsKExpbWl0LlRPVEFMX0VOVElUWV9TSVpFX0xJTUlUKX0sCi0gICAgICAgICAgICAgICAgICAgIFhNTEVycm9yUmVwb3J0ZXIuU0VWRVJJVFlfRkFUQUxfRVJST1IpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ0hBTkdFRDoKLSAgICAgKiBTY2FucyBhIHJhbmdlIG9mIHBhcnNlZCBjaGFyYWN0ZXIgZGF0YSwgVGhpcyBmdW5jdGlvbiBhcHBlbmRzIHRoZSBjaGFyYWN0ZXIgZGF0YSB0bwotICAgICAqIHRoZSBzdXBwbGllZCBidWZmZXIuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGUgY2hhcmFjdGVycyBhcmUgY29uc3VtZWQuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGlzIG1ldGhvZCBkb2VzIG5vdCBndWFyYW50ZWUgdG8gcmV0dXJuCi0gICAgICogdGhlIGxvbmdlc3QgcnVuIG9mIHBhcnNlZCBjaGFyYWN0ZXIgZGF0YS4gVGhpcyBtZXRob2QgbWF5IHJldHVybgotICAgICAqIGJlZm9yZSBtYXJrdXAgZHVlIHRvIHJlYWNoaW5nIHRoZSBlbmQgb2YgdGhlIGlucHV0IGJ1ZmZlciBvciBhbnkKLSAgICAgKiBvdGhlciByZWFzb24uCi0gICAgICogPHA+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gY29udGVudCBUaGUgY29udGVudCBzdHJ1Y3R1cmUgdG8gZmlsbC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gUmV0dXJucyB0aGUgbmV4dCBjaGFyYWN0ZXIgb24gdGhlIGlucHV0LCBpZiBrbm93bi4gVGhpcwotICAgICAqICAgICAgICAgdmFsdWUgbWF5IGJlIC0xIGJ1dCB0aGlzIGRvZXMgPGVtPm5vdGU8L2VtPiBkZXNpZ25hdGUKLSAgICAgKiAgICAgICAgIGVuZCBvZiBmaWxlLgotICAgICAqCi0gICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiAgVGhyb3duIGlmIGkvbyBlcnJvciBvY2N1cnMuCi0gICAgICogQHRocm93cyBFT0ZFeGNlcHRpb24gVGhyb3duIG9uIGVuZCBvZiBmaWxlLgotICAgICAqLwotICAgIHByb3RlY3RlZCBpbnQgc2NhbkNvbnRlbnQoWE1MU3RyaW5nIGNvbnRlbnQpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChERUJVR19CVUZGRVIpIHsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIihzY2FuQ29udGVudDogIik7Ci0gICAgICAgICAgICBwcmludCgpOwotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBsb2FkIG1vcmUgY2hhcmFjdGVycywgaWYgbmVlZGVkCi0gICAgICAgIGlmIChmQ3VycmVudEVudGl0eS5wb3NpdGlvbiA9PSBmQ3VycmVudEVudGl0eS5jb3VudCkgewotICAgICAgICAgICAgbG9hZCgwLCB0cnVlLCB0cnVlKTsKLSAgICAgICAgfSBlbHNlIGlmIChmQ3VycmVudEVudGl0eS5wb3NpdGlvbiA9PSBmQ3VycmVudEVudGl0eS5jb3VudCAtIDEpIHsKLSAgICAgICAgICAgIGludm9rZUxpc3RlbmVycygxKTsKLSAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LmNoWzBdID0gZkN1cnJlbnRFbnRpdHkuY2hbZkN1cnJlbnRFbnRpdHkuY291bnQgLSAxXTsKLSAgICAgICAgICAgIGxvYWQoMSwgZmFsc2UsIGZhbHNlKTsKLSAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LnBvc2l0aW9uID0gMDsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIG5vcm1hbGl6ZSBuZXdsaW5lcwotICAgICAgICBpbnQgb2Zmc2V0ID0gZkN1cnJlbnRFbnRpdHkucG9zaXRpb247Ci0gICAgICAgIGludCBjID0gZkN1cnJlbnRFbnRpdHkuY2hbb2Zmc2V0XTsKLSAgICAgICAgaW50IG5ld2xpbmVzID0gMDsKLSAgICAgICAgYm9vbGVhbiBjb3VudGVkID0gZmFsc2U7Ci0gICAgICAgIGlmIChjID09ICdcbicgfHwgKGMgPT0gJ1xyJyAmJiBpc0V4dGVybmFsKSkgewotICAgICAgICAgICAgaWYgKERFQlVHX0JVRkZFUikgewotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIltuZXdsaW5lLCAiK29mZnNldCsiLCAiK2ZDdXJyZW50RW50aXR5LnBvc2l0aW9uKyI6ICIpOwotICAgICAgICAgICAgICAgIHByaW50KCk7Ci0gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBkbyB7Ci0gICAgICAgICAgICAgICAgYyA9IGZDdXJyZW50RW50aXR5LmNoW2ZDdXJyZW50RW50aXR5LnBvc2l0aW9uKytdOwotICAgICAgICAgICAgICAgIGlmIChjID09ICdccicgJiYgaXNFeHRlcm5hbCkgewotICAgICAgICAgICAgICAgICAgICBuZXdsaW5lcysrOwotICAgICAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5saW5lTnVtYmVyKys7Ci0gICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LmNvbHVtbk51bWJlciA9IDE7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChmQ3VycmVudEVudGl0eS5wb3NpdGlvbiA9PSBmQ3VycmVudEVudGl0eS5jb3VudCkgewotICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tFbnRpdHlMaW1pdChudWxsLCBmQ3VycmVudEVudGl0eSwgb2Zmc2V0LCBuZXdsaW5lcyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQgPSAwOwotICAgICAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gPSBuZXdsaW5lczsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsb2FkKG5ld2xpbmVzLCBmYWxzZSwgdHJ1ZSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3VudGVkID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBpZiAoZkN1cnJlbnRFbnRpdHkuY2hbZkN1cnJlbnRFbnRpdHkucG9zaXRpb25dID09ICdcbicpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LnBvc2l0aW9uKys7Ci0gICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQrKzsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAvKioqIE5FV0xJTkUgTk9STUFMSVpBVElPTiAqKiovCi0gICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgbmV3bGluZXMrKzsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYyA9PSAnXG4nKSB7Ci0gICAgICAgICAgICAgICAgICAgIG5ld2xpbmVzKys7Ci0gICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LmxpbmVOdW1iZXIrKzsKLSAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkuY29sdW1uTnVtYmVyID0gMTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGZDdXJyZW50RW50aXR5LnBvc2l0aW9uID09IGZDdXJyZW50RW50aXR5LmNvdW50KSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBjaGVja0VudGl0eUxpbWl0KG51bGwsIGZDdXJyZW50RW50aXR5LCBvZmZzZXQsIG5ld2xpbmVzKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldCA9IDA7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5wb3NpdGlvbiA9IG5ld2xpbmVzOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxvYWQobmV3bGluZXMsIGZhbHNlLCB0cnVlKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50ZWQgPSB0cnVlOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkucG9zaXRpb24tLTsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfSB3aGlsZSAoZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gPCBmQ3VycmVudEVudGl0eS5jb3VudCAtIDEpOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IG9mZnNldDsgaSA8IGZDdXJyZW50RW50aXR5LnBvc2l0aW9uOyBpKyspIHsKLSAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5jaFtpXSA9ICdcbic7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpbnQgbGVuZ3RoID0gZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gLSBvZmZzZXQ7Ci0gICAgICAgICAgICBpZiAoZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gPT0gZkN1cnJlbnRFbnRpdHkuY291bnQgLSAxKSB7Ci0gICAgICAgICAgICAgICAgY2hlY2tFbnRpdHlMaW1pdChudWxsLCBmQ3VycmVudEVudGl0eSwgb2Zmc2V0LCBsZW5ndGgpOwotICAgICAgICAgICAgICAgIC8vQ0hBTkdFRDogZG9udCByZXBsYWNlIHRoZSB2YWx1ZS4uIGFwcGVuZCB0byB0aGUgYnVmZmVyLiBUaGlzIGdpdmVzIGNvbnRyb2wgdG8gdGhlIGNhbGxlZQotICAgICAgICAgICAgICAgIC8vb24gYnVmZmVyaW5nIHRoZSBkYXRhLi4KLSAgICAgICAgICAgICAgICBjb250ZW50LnNldFZhbHVlcyhmQ3VycmVudEVudGl0eS5jaCwgb2Zmc2V0LCBsZW5ndGgpOwotICAgICAgICAgICAgICAgIC8vY29udGVudC5hcHBlbmQoZkN1cnJlbnRFbnRpdHkuY2gsIG9mZnNldCwgbGVuZ3RoKTsKLSAgICAgICAgICAgICAgICBpZiAoREVCVUdfQlVGRkVSKSB7Ci0gICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIl1uZXdsaW5lLCAiK29mZnNldCsiLCAiK2ZDdXJyZW50RW50aXR5LnBvc2l0aW9uKyI6ICIpOwotICAgICAgICAgICAgICAgICAgICBwcmludCgpOwotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgcmV0dXJuIC0xOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKERFQlVHX0JVRkZFUikgewotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIl1uZXdsaW5lLCAiK29mZnNldCsiLCAiK2ZDdXJyZW50RW50aXR5LnBvc2l0aW9uKyI6ICIpOwotICAgICAgICAgICAgICAgIHByaW50KCk7Ci0gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICB3aGlsZSAoZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gPCBmQ3VycmVudEVudGl0eS5jb3VudCkgewotICAgICAgICAgICAgYyA9IGZDdXJyZW50RW50aXR5LmNoW2ZDdXJyZW50RW50aXR5LnBvc2l0aW9uKytdOwotICAgICAgICAgICAgaWYgKCFYTUxDaGFyLmlzQ29udGVudChjKSkgewotICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LnBvc2l0aW9uLS07Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgaW50IGxlbmd0aCA9IGZDdXJyZW50RW50aXR5LnBvc2l0aW9uIC0gb2Zmc2V0OwotICAgICAgICBmQ3VycmVudEVudGl0eS5jb2x1bW5OdW1iZXIgKz0gbGVuZ3RoIC0gbmV3bGluZXM7Ci0gICAgICAgIGlmICghY291bnRlZCkgewotICAgICAgICAgICAgY2hlY2tFbnRpdHlMaW1pdChudWxsLCBmQ3VycmVudEVudGl0eSwgb2Zmc2V0LCBsZW5ndGgpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy9DSEFOR0VEOiBkb250IHJlcGxhY2UgdGhlIHZhbHVlLi4gYXBwZW5kIHRvIHRoZSBidWZmZXIuIFRoaXMgZ2l2ZXMgY29udHJvbCB0byB0aGUgY2FsbGVlCi0gICAgICAgIC8vb24gYnVmZmVyaW5nIHRoZSBkYXRhLi4KLSAgICAgICAgY29udGVudC5zZXRWYWx1ZXMoZkN1cnJlbnRFbnRpdHkuY2gsIG9mZnNldCwgbGVuZ3RoKTsKLSAgICAgICAgLy9jb250ZW50LmFwcGVuZChmQ3VycmVudEVudGl0eS5jaCwgb2Zmc2V0LCBsZW5ndGgpOwotICAgICAgICAvLyByZXR1cm4gbmV4dCBjaGFyYWN0ZXIKLSAgICAgICAgaWYgKGZDdXJyZW50RW50aXR5LnBvc2l0aW9uICE9IGZDdXJyZW50RW50aXR5LmNvdW50KSB7Ci0gICAgICAgICAgICBjID0gZkN1cnJlbnRFbnRpdHkuY2hbZkN1cnJlbnRFbnRpdHkucG9zaXRpb25dOwotICAgICAgICAgICAgLy8gUkVWSVNJVDogRG9lcyB0aGlzIG5lZWQgdG8gYmUgdXBkYXRlZCB0byBmaXggdGhlCi0gICAgICAgICAgICAvLyAgICAgICAgICAjeDBEIF4jeDBBIG5ld2xpbmUgbm9ybWFsaXphdGlvbiBwcm9ibGVtPyAtQWMKLSAgICAgICAgICAgIGlmIChjID09ICdccicgJiYgaXNFeHRlcm5hbCkgewotICAgICAgICAgICAgICAgIGMgPSAnXG4nOwotICAgICAgICAgICAgfQotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgYyA9IC0xOwotICAgICAgICB9Ci0gICAgICAgIGlmIChERUJVR19CVUZGRVIpIHsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIilzY2FuQ29udGVudDogIik7Ci0gICAgICAgICAgICBwcmludCgpOwotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCIgLT4gJyIrKGNoYXIpYysiJyIpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBjOwotCi0gICAgfSAvLyBzY2FuQ29udGVudChYTUxTdHJpbmcpOmludAotCi0gICAgLyoqCi0gICAgICogU2NhbnMgYSByYW5nZSBvZiBhdHRyaWJ1dGUgdmFsdWUgZGF0YSwgc2V0dGluZyB0aGUgZmllbGRzIG9mIHRoZQotICAgICAqIFhNTFN0cmluZyBzdHJ1Y3R1cmUsIGFwcHJvcHJpYXRlbHkuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGUgY2hhcmFjdGVycyBhcmUgY29uc3VtZWQuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGlzIG1ldGhvZCBkb2VzIG5vdCBndWFyYW50ZWUgdG8gcmV0dXJuCi0gICAgICogdGhlIGxvbmdlc3QgcnVuIG9mIGF0dHJpYnV0ZSB2YWx1ZSBkYXRhLiBUaGlzIG1ldGhvZCBtYXkgcmV0dXJuCi0gICAgICogYmVmb3JlIHRoZSBxdW90ZSBjaGFyYWN0ZXIgZHVlIHRvIHJlYWNoaW5nIHRoZSBlbmQgb2YgdGhlIGlucHV0Ci0gICAgICogYnVmZmVyIG9yIGFueSBvdGhlciByZWFzb24uCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGUgZmllbGRzIGNvbnRhaW5lZCBpbiB0aGUgWE1MU3RyaW5nCi0gICAgICogc3RydWN0dXJlIGFyZSBub3QgZ3VhcmFudGVlZCB0byByZW1haW4gdmFsaWQgdXBvbiBzdWJzZXF1ZW50IGNhbGxzCi0gICAgICogdG8gdGhlIGVudGl0eSBzY2FubmVyLiBUaGVyZWZvcmUsIHRoZSBjYWxsZXIgaXMgcmVzcG9uc2libGUgZm9yCi0gICAgICogaW1tZWRpYXRlbHkgdXNpbmcgdGhlIHJldHVybmVkIGNoYXJhY3RlciBkYXRhIG9yIG1ha2luZyBhIGNvcHkgb2YKLSAgICAgKiB0aGUgY2hhcmFjdGVyIGRhdGEuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcXVvdGUgICBUaGUgcXVvdGUgY2hhcmFjdGVyIHRoYXQgc2lnbmlmaWVzIHRoZSBlbmQgb2YgdGhlCi0gICAgICogICAgICAgICAgICAgICAgYXR0cmlidXRlIHZhbHVlIGRhdGEuCi0gICAgICogQHBhcmFtIGNvbnRlbnQgVGhlIGNvbnRlbnQgc3RydWN0dXJlIHRvIGZpbGwuCi0gICAgICogQHBhcmFtIGlzTlNVUkkgYSBmbGFnIGluZGljYXRpbmcgd2hldGhlciB0aGUgY29udGVudCBpcyBhIE5hbWVzcGFjZSBVUkkKLSAgICAgKgotICAgICAqIEByZXR1cm4gUmV0dXJucyB0aGUgbmV4dCBjaGFyYWN0ZXIgb24gdGhlIGlucHV0LCBpZiBrbm93bi4gVGhpcwotICAgICAqICAgICAgICAgdmFsdWUgbWF5IGJlIC0xIGJ1dCB0aGlzIGRvZXMgPGVtPm5vdGU8L2VtPiBkZXNpZ25hdGUKLSAgICAgKiAgICAgICAgIGVuZCBvZiBmaWxlLgotICAgICAqCi0gICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiAgVGhyb3duIGlmIGkvbyBlcnJvciBvY2N1cnMuCi0gICAgICogQHRocm93cyBFT0ZFeGNlcHRpb24gVGhyb3duIG9uIGVuZCBvZiBmaWxlLgotICAgICAqLwotICAgIHByb3RlY3RlZCBpbnQgc2NhbkxpdGVyYWwoaW50IHF1b3RlLCBYTUxTdHJpbmcgY29udGVudCwgYm9vbGVhbiBpc05TVVJJKQotICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChERUJVR19CVUZGRVIpIHsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIihzY2FuTGl0ZXJhbCwgJyIrKGNoYXIpcXVvdGUrIic6ICIpOwotICAgICAgICAgICAgcHJpbnQoKTsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigpOwotICAgICAgICB9Ci0gICAgICAgIC8vIGxvYWQgbW9yZSBjaGFyYWN0ZXJzLCBpZiBuZWVkZWQKLSAgICAgICAgaWYgKGZDdXJyZW50RW50aXR5LnBvc2l0aW9uID09IGZDdXJyZW50RW50aXR5LmNvdW50KSB7Ci0gICAgICAgICAgICBsb2FkKDAsIHRydWUsIHRydWUpOwotICAgICAgICB9IGVsc2UgaWYgKGZDdXJyZW50RW50aXR5LnBvc2l0aW9uID09IGZDdXJyZW50RW50aXR5LmNvdW50IC0gMSkgewotICAgICAgICAgICAgaW52b2tlTGlzdGVuZXJzKDEpOwotICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkuY2hbMF0gPSBmQ3VycmVudEVudGl0eS5jaFtmQ3VycmVudEVudGl0eS5jb3VudCAtIDFdOwotICAgICAgICAgICAgbG9hZCgxLCBmYWxzZSwgZmFsc2UpOwotICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gPSAwOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gbm9ybWFsaXplIG5ld2xpbmVzCi0gICAgICAgIGludCBvZmZzZXQgPSBmQ3VycmVudEVudGl0eS5wb3NpdGlvbjsKLSAgICAgICAgaW50IGMgPSBmQ3VycmVudEVudGl0eS5jaFtvZmZzZXRdOwotICAgICAgICBpbnQgbmV3bGluZXMgPSAwOwotICAgICAgICBpZih3aGl0ZVNwYWNlSW5mb05lZWRlZCkKLSAgICAgICAgICAgIHdoaXRlU3BhY2VMZW49MDsKLSAgICAgICAgaWYgKGMgPT0gJ1xuJyB8fCAoYyA9PSAnXHInICYmIGlzRXh0ZXJuYWwpKSB7Ci0gICAgICAgICAgICBpZiAoREVCVUdfQlVGRkVSKSB7Ci0gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiW25ld2xpbmUsICIrb2Zmc2V0KyIsICIrZkN1cnJlbnRFbnRpdHkucG9zaXRpb24rIjogIik7Ci0gICAgICAgICAgICAgICAgcHJpbnQoKTsKLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGRvIHsKLSAgICAgICAgICAgICAgICBjID0gZkN1cnJlbnRFbnRpdHkuY2hbZkN1cnJlbnRFbnRpdHkucG9zaXRpb24rK107Ci0gICAgICAgICAgICAgICAgaWYgKGMgPT0gJ1xyJyAmJiBpc0V4dGVybmFsKSB7Ci0gICAgICAgICAgICAgICAgICAgIG5ld2xpbmVzKys7Ci0gICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LmxpbmVOdW1iZXIrKzsKLSAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkuY29sdW1uTnVtYmVyID0gMTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGZDdXJyZW50RW50aXR5LnBvc2l0aW9uID09IGZDdXJyZW50RW50aXR5LmNvdW50KSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQgPSAwOwotICAgICAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gPSBuZXdsaW5lczsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsb2FkKG5ld2xpbmVzLCBmYWxzZSwgdHJ1ZSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBpZiAoZkN1cnJlbnRFbnRpdHkuY2hbZkN1cnJlbnRFbnRpdHkucG9zaXRpb25dID09ICdcbicpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LnBvc2l0aW9uKys7Ci0gICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQrKzsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAvKioqIE5FV0xJTkUgTk9STUFMSVpBVElPTiAqKiovCi0gICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgbmV3bGluZXMrKzsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAvKioqLwotICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYyA9PSAnXG4nKSB7Ci0gICAgICAgICAgICAgICAgICAgIG5ld2xpbmVzKys7Ci0gICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LmxpbmVOdW1iZXIrKzsKLSAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkuY29sdW1uTnVtYmVyID0gMTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGZDdXJyZW50RW50aXR5LnBvc2l0aW9uID09IGZDdXJyZW50RW50aXR5LmNvdW50KSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQgPSAwOwotICAgICAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gPSBuZXdsaW5lczsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsb2FkKG5ld2xpbmVzLCBmYWxzZSwgdHJ1ZSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAvKioqIE5FV0xJTkUgTk9STUFMSVpBVElPTiAqKioKLSAgICAgICAgICAgICAgICAgICAgICogaWYgKGZDdXJyZW50RW50aXR5LmNoW2ZDdXJyZW50RW50aXR5LnBvc2l0aW9uXSA9PSAnXHInCi0gICAgICAgICAgICAgICAgICAgICAqICYmIGV4dGVybmFsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAqIGZDdXJyZW50RW50aXR5LnBvc2l0aW9uKys7Ci0gICAgICAgICAgICAgICAgICAgICAqIG9mZnNldCsrOwotICAgICAgICAgICAgICAgICAgICAgKiB9Ci0gICAgICAgICAgICAgICAgICAgICAqIC8qKiovCi0gICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkucG9zaXRpb24tLTsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfSB3aGlsZSAoZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gPCBmQ3VycmVudEVudGl0eS5jb3VudCAtIDEpOwotICAgICAgICAgICAgaW50IGk9MDsKLSAgICAgICAgICAgIGZvciAoIGkgPSBvZmZzZXQ7IGkgPCBmQ3VycmVudEVudGl0eS5wb3NpdGlvbjsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkuY2hbaV0gPSAnXG4nOwotICAgICAgICAgICAgICAgIHN0b3JlV2hpdGVTcGFjZShpKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaW50IGxlbmd0aCA9IGZDdXJyZW50RW50aXR5LnBvc2l0aW9uIC0gb2Zmc2V0OwotICAgICAgICAgICAgaWYgKGZDdXJyZW50RW50aXR5LnBvc2l0aW9uID09IGZDdXJyZW50RW50aXR5LmNvdW50IC0gMSkgewotICAgICAgICAgICAgICAgIGNvbnRlbnQuc2V0VmFsdWVzKGZDdXJyZW50RW50aXR5LmNoLCBvZmZzZXQsIGxlbmd0aCk7Ci0gICAgICAgICAgICAgICAgaWYgKERFQlVHX0JVRkZFUikgewotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCJdbmV3bGluZSwgIitvZmZzZXQrIiwgIitmQ3VycmVudEVudGl0eS5wb3NpdGlvbisiOiAiKTsKLSAgICAgICAgICAgICAgICAgICAgcHJpbnQoKTsKLSAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHJldHVybiAtMTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChERUJVR19CVUZGRVIpIHsKLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCJdbmV3bGluZSwgIitvZmZzZXQrIiwgIitmQ3VycmVudEVudGl0eS5wb3NpdGlvbisiOiAiKTsKLSAgICAgICAgICAgICAgICBwcmludCgpOwotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gc2NhbiBsaXRlcmFsIHZhbHVlCi0gICAgICAgIGZvciAoOyBmQ3VycmVudEVudGl0eS5wb3NpdGlvbjxmQ3VycmVudEVudGl0eS5jb3VudDsgZkN1cnJlbnRFbnRpdHkucG9zaXRpb24rKykgewotICAgICAgICAgICAgYyA9IGZDdXJyZW50RW50aXR5LmNoW2ZDdXJyZW50RW50aXR5LnBvc2l0aW9uXTsKLSAgICAgICAgICAgIGlmICgoYyA9PSBxdW90ZSAmJgotICAgICAgICAgICAgICAgICAgICAoIWZDdXJyZW50RW50aXR5LmxpdGVyYWwgfHwgaXNFeHRlcm5hbCkpIHx8Ci0gICAgICAgICAgICAgICAgICAgIGMgPT0gJyUnIHx8ICFYTUxDaGFyLmlzQ29udGVudChjKSkgewotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKHdoaXRlU3BhY2VJbmZvTmVlZGVkICYmIGMgPT0gJ1x0JykgewotICAgICAgICAgICAgICAgIHN0b3JlV2hpdGVTcGFjZShmQ3VycmVudEVudGl0eS5wb3NpdGlvbik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgaW50IGxlbmd0aCA9IGZDdXJyZW50RW50aXR5LnBvc2l0aW9uIC0gb2Zmc2V0OwotICAgICAgICBmQ3VycmVudEVudGl0eS5jb2x1bW5OdW1iZXIgKz0gbGVuZ3RoIC0gbmV3bGluZXM7Ci0KLSAgICAgICAgY2hlY2tFbnRpdHlMaW1pdChudWxsLCBmQ3VycmVudEVudGl0eSwgb2Zmc2V0LCBsZW5ndGgpOwotICAgICAgICBpZiAoaXNOU1VSSSkgewotICAgICAgICAgICAgY2hlY2tMaW1pdChMaW1pdC5NQVhfTkFNRV9MSU1JVCwgZkN1cnJlbnRFbnRpdHksIG9mZnNldCwgbGVuZ3RoKTsKLSAgICAgICAgfQotICAgICAgICBjb250ZW50LnNldFZhbHVlcyhmQ3VycmVudEVudGl0eS5jaCwgb2Zmc2V0LCBsZW5ndGgpOwotCi0gICAgICAgIC8vIHJldHVybiBuZXh0IGNoYXJhY3RlcgotICAgICAgICBpZiAoZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gIT0gZkN1cnJlbnRFbnRpdHkuY291bnQpIHsKLSAgICAgICAgICAgIGMgPSBmQ3VycmVudEVudGl0eS5jaFtmQ3VycmVudEVudGl0eS5wb3NpdGlvbl07Ci0gICAgICAgICAgICAvLyBOT1RFOiBXZSBkb24ndCB3YW50IHRvIGFjY2lkZW50YWxseSBzaWduYWwgdGhlCi0gICAgICAgICAgICAvLyAgICAgICBlbmQgb2YgdGhlIGxpdGVyYWwgaWYgd2UncmUgZXhwYW5kaW5nIGFuCi0gICAgICAgICAgICAvLyAgICAgICBlbnRpdHkgYXBwZWFyaW5nIGluIHRoZSBsaXRlcmFsLiAtQWMKLSAgICAgICAgICAgIGlmIChjID09IHF1b3RlICYmIGZDdXJyZW50RW50aXR5LmxpdGVyYWwpIHsKLSAgICAgICAgICAgICAgICBjID0gLTE7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBjID0gLTE7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKERFQlVHX0JVRkZFUikgewotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiKXNjYW5MaXRlcmFsLCAnIisoY2hhcilxdW90ZSsiJzogIik7Ci0gICAgICAgICAgICBwcmludCgpOwotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCIgLT4gJyIrKGNoYXIpYysiJyIpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBjOwotCi0gICAgfSAvLyBzY2FuTGl0ZXJhbChpbnQsWE1MU3RyaW5nKTppbnQKLQotICAgIC8qKgotICAgICAqIFNhdmUgd2hpdGVzcGFjZSBpbmZvcm1hdGlvbi4gSW5jcmVhc2UgdGhlIHdoaXRlc3BhY2UgYnVmZmVyIGJ5IDEwMAotICAgICAqIHdoZW4gbmVlZGVkLgotICAgICAqCi0gICAgICogRm9yIFhNTCAxLjAsIGxlZ2FsIGNoYXJhY3RlcnMgYmVsb3cgMHgyMCBhcmUgMHgwOSAoVEFCKSwgMHgwQSAoTEYpIGFuZCAweDBEIChDUikuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gd2hpdGVTcGFjZVBvcyBwb3NpdGlvbiBvZiBhIHdoaXRlc3BhY2UgaW4gdGhlIHNjYW5uZXIgZW50aXR5IGJ1ZmZlcgotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCBzdG9yZVdoaXRlU3BhY2UoaW50IHdoaXRlU3BhY2VQb3MpIHsKLSAgICAgICAgaWYgKHdoaXRlU3BhY2VMZW4gPj0gd2hpdGVTcGFjZUxvb2t1cC5sZW5ndGgpIHsKLSAgICAgICAgICAgIGludCBbXSB0bXAgPSBuZXcgaW50W3doaXRlU3BhY2VMb29rdXAubGVuZ3RoICsgMTAwXTsKLSAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkod2hpdGVTcGFjZUxvb2t1cCwgMCwgdG1wLCAwLCB3aGl0ZVNwYWNlTG9va3VwLmxlbmd0aCk7Ci0gICAgICAgICAgICB3aGl0ZVNwYWNlTG9va3VwID0gdG1wOwotICAgICAgICB9Ci0KLSAgICAgICAgd2hpdGVTcGFjZUxvb2t1cFt3aGl0ZVNwYWNlTGVuKytdID0gd2hpdGVTcGFjZVBvczsKLSAgICB9Ci0KLSAgICAvL0NIQU5HRUQ6Ci0gICAgLyoqCi0gICAgICogU2NhbnMgYSByYW5nZSBvZiBjaGFyYWN0ZXIgZGF0YSB1cCB0byB0aGUgc3BlY2lmaWVkIGRlbGltaXRlciwKLSAgICAgKiBzZXR0aW5nIHRoZSBmaWVsZHMgb2YgdGhlIFhNTFN0cmluZyBzdHJ1Y3R1cmUsIGFwcHJvcHJpYXRlbHkuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGUgY2hhcmFjdGVycyBhcmUgY29uc3VtZWQuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGlzIGFzc3VtZXMgdGhhdCB0aGUgZGVsaW1pdGVyIGNvbnRhaW5zIGF0Ci0gICAgICogbGVhc3Qgb25lIGNoYXJhY3Rlci4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoaXMgbWV0aG9kIGRvZXMgbm90IGd1YXJhbnRlZSB0byByZXR1cm4KLSAgICAgKiB0aGUgbG9uZ2VzdCBydW4gb2YgY2hhcmFjdGVyIGRhdGEuIFRoaXMgbWV0aG9kIG1heSByZXR1cm4gYmVmb3JlCi0gICAgICogdGhlIGRlbGltaXRlciBkdWUgdG8gcmVhY2hpbmcgdGhlIGVuZCBvZiB0aGUgaW5wdXQgYnVmZmVyIG9yIGFueQotICAgICAqIG90aGVyIHJlYXNvbi4KLSAgICAgKiA8cD4KLSAgICAgKiBAcGFyYW0gZGVsaW1pdGVyIFRoZSBzdHJpbmcgdGhhdCBzaWduaWZpZXMgdGhlIGVuZCBvZiB0aGUgY2hhcmFjdGVyCi0gICAgICogICAgICAgICAgICAgICAgICBkYXRhIHRvIGJlIHNjYW5uZWQuCi0gICAgICogQHBhcmFtIGJ1ZmZlciAgICBUaGUgWE1MU3RyaW5nQnVmZmVyIHRvIGZpbGwuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFJldHVybnMgdHJ1ZSBpZiB0aGVyZSBpcyBtb3JlIGRhdGEgdG8gc2NhbiwgZmFsc2Ugb3RoZXJ3aXNlLgotICAgICAqCi0gICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiAgVGhyb3duIGlmIGkvbyBlcnJvciBvY2N1cnMuCi0gICAgICogQHRocm93cyBFT0ZFeGNlcHRpb24gVGhyb3duIG9uIGVuZCBvZiBmaWxlLgotICAgICAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIHNjYW5EYXRhKFN0cmluZyBkZWxpbWl0ZXIsIFhNTFN0cmluZ0J1ZmZlciBidWZmZXIpCi0gICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKLQotICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKLSAgICAgICAgaW50IGRlbGltTGVuID0gZGVsaW1pdGVyLmxlbmd0aCgpOwotICAgICAgICBjaGFyIGNoYXJBdDAgPSBkZWxpbWl0ZXIuY2hhckF0KDApOwotICAgICAgICBkbyB7Ci0gICAgICAgICAgICBpZiAoREVCVUdfQlVGRkVSKSB7Ci0gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiKHNjYW5EYXRhOiAiKTsKLSAgICAgICAgICAgICAgICBwcmludCgpOwotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBsb2FkIG1vcmUgY2hhcmFjdGVycywgaWYgbmVlZGVkCi0KLSAgICAgICAgICAgIGlmIChmQ3VycmVudEVudGl0eS5wb3NpdGlvbiA9PSBmQ3VycmVudEVudGl0eS5jb3VudCkgewotICAgICAgICAgICAgICAgIGxvYWQoMCwgdHJ1ZSwgZmFsc2UpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBib29sZWFuIGJOZXh0RW50aXR5ID0gZmFsc2U7Ci0KLSAgICAgICAgICAgIHdoaWxlICgoZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gPiBmQ3VycmVudEVudGl0eS5jb3VudCAtIGRlbGltTGVuKQotICAgICAgICAgICAgICAgICYmICghYk5leHRFbnRpdHkpKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGZDdXJyZW50RW50aXR5LmNoLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LnBvc2l0aW9uLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LmNoLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkuY291bnQgLSBmQ3VycmVudEVudGl0eS5wb3NpdGlvbik7Ci0KLSAgICAgICAgICAgICAgYk5leHRFbnRpdHkgPSBsb2FkKGZDdXJyZW50RW50aXR5LmNvdW50IC0gZkN1cnJlbnRFbnRpdHkucG9zaXRpb24sIGZhbHNlLCBmYWxzZSk7Ci0gICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LnBvc2l0aW9uID0gMDsKLSAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkuc3RhcnRQb3NpdGlvbiA9IDA7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmIChmQ3VycmVudEVudGl0eS5wb3NpdGlvbiA+IGZDdXJyZW50RW50aXR5LmNvdW50IC0gZGVsaW1MZW4pIHsKLSAgICAgICAgICAgICAgICAvLyBzb21ldGhpbmcgbXVzdCBiZSB3cm9uZyB3aXRoIHRoZSBpbnB1dDogIGUuZy4sIGZpbGUgZW5kcyBpbiBhbiB1bnRlcm1pbmF0ZWQgY29tbWVudAotICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBmQ3VycmVudEVudGl0eS5jb3VudCAtIGZDdXJyZW50RW50aXR5LnBvc2l0aW9uOwotICAgICAgICAgICAgICAgIGNoZWNrRW50aXR5TGltaXQoTmFtZVR5cGUuQ09NTUVOVCwgZkN1cnJlbnRFbnRpdHksIGZDdXJyZW50RW50aXR5LnBvc2l0aW9uLCBsZW5ndGgpOwotICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQgKGZDdXJyZW50RW50aXR5LmNoLCBmQ3VycmVudEVudGl0eS5wb3NpdGlvbiwgbGVuZ3RoKTsKLSAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5jb2x1bW5OdW1iZXIgKz0gZkN1cnJlbnRFbnRpdHkuY291bnQ7Ci0gICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkuYmFzZUNoYXJPZmZzZXQgKz0gKGZDdXJyZW50RW50aXR5LnBvc2l0aW9uIC0gZkN1cnJlbnRFbnRpdHkuc3RhcnRQb3NpdGlvbik7Ci0gICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gPSBmQ3VycmVudEVudGl0eS5jb3VudDsKLSAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5zdGFydFBvc2l0aW9uID0gZkN1cnJlbnRFbnRpdHkuY291bnQ7Ci0gICAgICAgICAgICAgICAgbG9hZCgwLCB0cnVlLCBmYWxzZSk7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBub3JtYWxpemUgbmV3bGluZXMKLSAgICAgICAgICAgIGludCBvZmZzZXQgPSBmQ3VycmVudEVudGl0eS5wb3NpdGlvbjsKLSAgICAgICAgICAgIGludCBjID0gZkN1cnJlbnRFbnRpdHkuY2hbb2Zmc2V0XTsKLSAgICAgICAgICAgIGludCBuZXdsaW5lcyA9IDA7Ci0gICAgICAgICAgICBpZiAoYyA9PSAnXG4nIHx8IChjID09ICdccicgJiYgaXNFeHRlcm5hbCkpIHsKLSAgICAgICAgICAgICAgICBpZiAoREVCVUdfQlVGRkVSKSB7Ci0gICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIltuZXdsaW5lLCAiK29mZnNldCsiLCAiK2ZDdXJyZW50RW50aXR5LnBvc2l0aW9uKyI6ICIpOwotICAgICAgICAgICAgICAgICAgICBwcmludCgpOwotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZG8gewotICAgICAgICAgICAgICAgICAgICBjID0gZkN1cnJlbnRFbnRpdHkuY2hbZkN1cnJlbnRFbnRpdHkucG9zaXRpb24rK107Ci0gICAgICAgICAgICAgICAgICAgIGlmIChjID09ICdccicgJiYgaXNFeHRlcm5hbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgbmV3bGluZXMrKzsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LmxpbmVOdW1iZXIrKzsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LmNvbHVtbk51bWJlciA9IDE7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gPT0gZkN1cnJlbnRFbnRpdHkuY291bnQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQgPSAwOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LnBvc2l0aW9uID0gbmV3bGluZXM7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxvYWQobmV3bGluZXMsIGZhbHNlLCB0cnVlKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZkN1cnJlbnRFbnRpdHkuY2hbZkN1cnJlbnRFbnRpdHkucG9zaXRpb25dID09ICdcbicpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5wb3NpdGlvbisrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldCsrOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgLyoqKiBORVdMSU5FIE5PUk1BTElaQVRJT04gKioqLwotICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3bGluZXMrKzsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjID09ICdcbicpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIG5ld2xpbmVzKys7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5saW5lTnVtYmVyKys7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5jb2x1bW5OdW1iZXIgPSAxOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZDdXJyZW50RW50aXR5LnBvc2l0aW9uID09IGZDdXJyZW50RW50aXR5LmNvdW50KSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0ID0gMDsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5wb3NpdGlvbiA9IG5ld2xpbmVzOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LmNvdW50ID0gbmV3bGluZXM7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxvYWQobmV3bGluZXMsIGZhbHNlLCB0cnVlKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5wb3NpdGlvbi0tOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9IHdoaWxlIChmQ3VycmVudEVudGl0eS5wb3NpdGlvbiA8IGZDdXJyZW50RW50aXR5LmNvdW50IC0gMSk7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IG9mZnNldDsgaSA8IGZDdXJyZW50RW50aXR5LnBvc2l0aW9uOyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkuY2hbaV0gPSAnXG4nOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gLSBvZmZzZXQ7Ci0gICAgICAgICAgICAgICAgaWYgKGZDdXJyZW50RW50aXR5LnBvc2l0aW9uID09IGZDdXJyZW50RW50aXR5LmNvdW50IC0gMSkgewotICAgICAgICAgICAgICAgICAgICBjaGVja0VudGl0eUxpbWl0KE5hbWVUeXBlLkNPTU1FTlQsIGZDdXJyZW50RW50aXR5LCBvZmZzZXQsIGxlbmd0aCk7Ci0gICAgICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoZkN1cnJlbnRFbnRpdHkuY2gsIG9mZnNldCwgbGVuZ3RoKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKERFQlVHX0JVRkZFUikgewotICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiXW5ld2xpbmUsICIrb2Zmc2V0KyIsICIrZkN1cnJlbnRFbnRpdHkucG9zaXRpb24rIjogIik7Ci0gICAgICAgICAgICAgICAgICAgICAgICBwcmludCgpOwotICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGlmIChERUJVR19CVUZGRVIpIHsKLSAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiXW5ld2xpbmUsICIrb2Zmc2V0KyIsICIrZkN1cnJlbnRFbnRpdHkucG9zaXRpb24rIjogIik7Ci0gICAgICAgICAgICAgICAgICAgIHByaW50KCk7Ci0gICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gaXRlcmF0ZSBvdmVyIGJ1ZmZlciBsb29raW5nIGZvciBkZWxpbWl0ZXIKLSAgICAgICAgICAgIE9VVEVSOiB3aGlsZSAoZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gPCBmQ3VycmVudEVudGl0eS5jb3VudCkgewotICAgICAgICAgICAgICAgIGMgPSBmQ3VycmVudEVudGl0eS5jaFtmQ3VycmVudEVudGl0eS5wb3NpdGlvbisrXTsKLSAgICAgICAgICAgICAgICBpZiAoYyA9PSBjaGFyQXQwKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIGxvb2tzIGxpa2Ugd2UganVzdCBoaXQgdGhlIGRlbGltaXRlcgotICAgICAgICAgICAgICAgICAgICBpbnQgZGVsaW1PZmZzZXQgPSBmQ3VycmVudEVudGl0eS5wb3NpdGlvbiAtIDE7Ci0gICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAxOyBpIDwgZGVsaW1MZW47IGkrKykgewotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZDdXJyZW50RW50aXR5LnBvc2l0aW9uID09IGZDdXJyZW50RW50aXR5LmNvdW50KSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gLT0gaTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhayBPVVRFUjsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGMgPSBmQ3VycmVudEVudGl0eS5jaFtmQ3VycmVudEVudGl0eS5wb3NpdGlvbisrXTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkZWxpbWl0ZXIuY2hhckF0KGkpICE9IGMpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5wb3NpdGlvbiAtPSBpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGlmIChmQ3VycmVudEVudGl0eS5wb3NpdGlvbiA9PSBkZWxpbU9mZnNldCArIGRlbGltTGVuKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjID09ICdcbicgfHwgKGlzRXh0ZXJuYWwgJiYgYyA9PSAnXHInKSkgewotICAgICAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5wb3NpdGlvbi0tOwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKFhNTENoYXIuaXNJbnZhbGlkKGMpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LnBvc2l0aW9uLS07Ci0gICAgICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBmQ3VycmVudEVudGl0eS5wb3NpdGlvbiAtIG9mZnNldDsKLSAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkuY29sdW1uTnVtYmVyICs9IGxlbmd0aCAtIG5ld2xpbmVzOwotICAgICAgICAgICAgICAgICAgICBjaGVja0VudGl0eUxpbWl0KE5hbWVUeXBlLkNPTU1FTlQsIGZDdXJyZW50RW50aXR5LCBvZmZzZXQsIGxlbmd0aCk7Ci0gICAgICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoZkN1cnJlbnRFbnRpdHkuY2gsIG9mZnNldCwgbGVuZ3RoKTsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgaW50IGxlbmd0aCA9IGZDdXJyZW50RW50aXR5LnBvc2l0aW9uIC0gb2Zmc2V0OwotICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkuY29sdW1uTnVtYmVyICs9IGxlbmd0aCAtIG5ld2xpbmVzOwotICAgICAgICAgICAgY2hlY2tFbnRpdHlMaW1pdChOYW1lVHlwZS5DT01NRU5ULCBmQ3VycmVudEVudGl0eSwgb2Zmc2V0LCBsZW5ndGgpOwotICAgICAgICAgICAgaWYgKGRvbmUpIHsKLSAgICAgICAgICAgICAgICBsZW5ndGggLT0gZGVsaW1MZW47Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBidWZmZXIuYXBwZW5kKGZDdXJyZW50RW50aXR5LmNoLCBvZmZzZXQsIGxlbmd0aCk7Ci0KLSAgICAgICAgICAgIC8vIHJldHVybiB0cnVlIGlmIHN0cmluZyB3YXMgc2tpcHBlZAotICAgICAgICAgICAgaWYgKERFQlVHX0JVRkZFUikgewotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIilzY2FuRGF0YTogIik7Ci0gICAgICAgICAgICAgICAgcHJpbnQoKTsKLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIiAtPiAiICsgZG9uZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gd2hpbGUgKCFkb25lKTsKLSAgICAgICAgcmV0dXJuICFkb25lOwotCi0gICAgfSAvLyBzY2FuRGF0YShTdHJpbmcsIFhNTFN0cmluZ0J1ZmZlcikKLQotICAgIC8qKgotICAgICAqIFNraXBzIGEgY2hhcmFjdGVyIGFwcGVhcmluZyBpbW1lZGlhdGVseSBvbiB0aGUgaW5wdXQuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGUgY2hhcmFjdGVyIGlzIGNvbnN1bWVkIG9ubHkgaWYgaXQgbWF0Y2hlcwotICAgICAqIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyLgotICAgICAqCi0gICAgICogQHBhcmFtIGMgVGhlIGNoYXJhY3RlciB0byBza2lwLgotICAgICAqIEBwYXJhbSBudCBUaGUgdHlwZSBvZiB0aGUgbmFtZSAoZWxlbWVudCBvciBhdHRyaWJ1dGUpCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFJldHVybnMgdHJ1ZSBpZiB0aGUgY2hhcmFjdGVyIHdhcyBza2lwcGVkLgotICAgICAqCi0gICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiAgVGhyb3duIGlmIGkvbyBlcnJvciBvY2N1cnMuCi0gICAgICogQHRocm93cyBFT0ZFeGNlcHRpb24gVGhyb3duIG9uIGVuZCBvZiBmaWxlLgotICAgICAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIHNraXBDaGFyKGludCBjLCBOYW1lVHlwZSBudCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKERFQlVHX0JVRkZFUikgewotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiKHNraXBDaGFyLCAnIisoY2hhciljKyInOiAiKTsKLSAgICAgICAgICAgIHByaW50KCk7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIGxvYWQgbW9yZSBjaGFyYWN0ZXJzLCBpZiBuZWVkZWQKLSAgICAgICAgaWYgKGZDdXJyZW50RW50aXR5LnBvc2l0aW9uID09IGZDdXJyZW50RW50aXR5LmNvdW50KSB7Ci0gICAgICAgICAgICBsb2FkKDAsIHRydWUsIHRydWUpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gc2tpcCBjaGFyYWN0ZXIKLSAgICAgICAgaW50IG9mZnNldCA9IGZDdXJyZW50RW50aXR5LnBvc2l0aW9uOwotICAgICAgICBpbnQgY2MgPSBmQ3VycmVudEVudGl0eS5jaFtmQ3VycmVudEVudGl0eS5wb3NpdGlvbl07Ci0gICAgICAgIGlmIChjYyA9PSBjKSB7Ci0gICAgICAgICAgICBmQ3VycmVudEVudGl0eS5wb3NpdGlvbisrOwotICAgICAgICAgICAgaWYgKGMgPT0gJ1xuJykgewotICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LmxpbmVOdW1iZXIrKzsKLSAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5jb2x1bW5OdW1iZXIgPSAxOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5jb2x1bW5OdW1iZXIrKzsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChERUJVR19CVUZGRVIpIHsKLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCIpc2tpcENoYXIsICciKyhjaGFyKWMrIic6ICIpOwotICAgICAgICAgICAgICAgIHByaW50KCk7Ci0gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCIgLT4gdHJ1ZSIpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2hlY2tFbnRpdHlMaW1pdChudCwgZkN1cnJlbnRFbnRpdHksIG9mZnNldCwgZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gLSBvZmZzZXQpOwotICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgIH0gZWxzZSBpZiAoYyA9PSAnXG4nICYmIGNjID09ICdccicgJiYgaXNFeHRlcm5hbCkgewotICAgICAgICAgICAgLy8gaGFuZGxlIG5ld2xpbmVzCi0gICAgICAgICAgICBpZiAoZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gPT0gZkN1cnJlbnRFbnRpdHkuY291bnQpIHsKLSAgICAgICAgICAgICAgICBpbnZva2VMaXN0ZW5lcnMoMSk7Ci0gICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkuY2hbMF0gPSAoY2hhciljYzsKLSAgICAgICAgICAgICAgICBsb2FkKDEsIGZhbHNlLCBmYWxzZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmQ3VycmVudEVudGl0eS5wb3NpdGlvbisrOwotICAgICAgICAgICAgaWYgKGZDdXJyZW50RW50aXR5LmNoW2ZDdXJyZW50RW50aXR5LnBvc2l0aW9uXSA9PSAnXG4nKSB7Ci0gICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkucG9zaXRpb24rKzsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LmxpbmVOdW1iZXIrKzsKLSAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LmNvbHVtbk51bWJlciA9IDE7Ci0gICAgICAgICAgICBpZiAoREVCVUdfQlVGRkVSKSB7Ci0gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiKXNraXBDaGFyLCAnIisoY2hhciljKyInOiAiKTsKLSAgICAgICAgICAgICAgICBwcmludCgpOwotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiIC0+IHRydWUiKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNoZWNrRW50aXR5TGltaXQobnQsIGZDdXJyZW50RW50aXR5LCBvZmZzZXQsIGZDdXJyZW50RW50aXR5LnBvc2l0aW9uIC0gb2Zmc2V0KTsKLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gY2hhcmFjdGVyIHdhcyBub3Qgc2tpcHBlZAotICAgICAgICBpZiAoREVCVUdfQlVGRkVSKSB7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCIpc2tpcENoYXIsICciKyhjaGFyKWMrIic6ICIpOwotICAgICAgICAgICAgcHJpbnQoKTsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiIC0+IGZhbHNlIik7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGZhbHNlOwotCi0gICAgfSAvLyBza2lwQ2hhcihpbnQpOmJvb2xlYW4KLQotICAgIHB1YmxpYyBib29sZWFuIGlzU3BhY2UoY2hhciBjaCl7Ci0gICAgICAgIHJldHVybiAoY2ggPT0gJyAnKSB8fCAoY2ggPT0gJ1xuJykgfHwgKGNoID09ICdcdCcpIHx8IChjaCA9PSAnXHInKTsKLSAgICB9Ci0gICAgLyoqCi0gICAgICogU2tpcHMgc3BhY2UgY2hhcmFjdGVycyBhcHBlYXJpbmcgaW1tZWRpYXRlbHkgb24gdGhlIGlucHV0LgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gVGhlIGNoYXJhY3RlcnMgYXJlIGNvbnN1bWVkIG9ubHkgaWYgdGhleSBhcmUKLSAgICAgKiBzcGFjZSBjaGFyYWN0ZXJzLgotICAgICAqCi0gICAgICogQHJldHVybiBSZXR1cm5zIHRydWUgaWYgYXQgbGVhc3Qgb25lIHNwYWNlIGNoYXJhY3RlciB3YXMgc2tpcHBlZC4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gIFRocm93biBpZiBpL28gZXJyb3Igb2NjdXJzLgotICAgICAqIEB0aHJvd3MgRU9GRXhjZXB0aW9uIFRocm93biBvbiBlbmQgb2YgZmlsZS4KLSAgICAgKgotICAgICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlhNTENoYXIjaXNTcGFjZQotICAgICAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIHNraXBTcGFjZXMoKSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgICAgICBpZiAoREVCVUdfQlVGRkVSKSB7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCIoc2tpcFNwYWNlczogIik7Ci0gICAgICAgICAgICBwcmludCgpOwotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCk7Ci0gICAgICAgIH0KLSAgICAgICAgLy9ib29sZWFuIGVudGl0eUNoYW5nZWQgPSBmYWxzZTsKLSAgICAgICAgLy8gbG9hZCBtb3JlIGNoYXJhY3RlcnMsIGlmIG5lZWRlZAotICAgICAgICBpZiAoZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gPT0gZkN1cnJlbnRFbnRpdHkuY291bnQpIHsKLSAgICAgICAgICAgIGxvYWQoMCwgdHJ1ZSwgdHJ1ZSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvL3dlIGFyZSBkb2luZyB0aGlzIGNoZWNrIG9ubHkgaW4gc2tpcFNwYWNlKCkgYmVjYXVzZSBpdCBpcyBjYWxsZWQgYnkKLSAgICAgICAgLy9mTWlzY0Rpc3BhdGNoZXIgYW5kIHdlIHdhbnQgdGhlIHBhcnNlciB0byBleGl0IGdyYWNlZnVsbHkgd2hlbiBkb2N1bWVudAotICAgICAgICAvL2lzIHdlbGwtZm9ybWVkLgotICAgICAgICAvL2l0IGlzIHBvc3NpYmxlIHRoYXQgZW5kIG9mIGRvY3VtZW50IGlzIHJlYWNoZWQgYW5kCi0gICAgICAgIC8vZkN1cnJlbnRFbnRpdHkgYmVjb21lcyBudWxsCi0gICAgICAgIC8vbm90aGluZyB3YXMgcmVhZCBzbyBlbnRpdHkgY2hhbmdlZCAgJ2ZhbHNlJyBzaG91bGQgYmUgcmV0dXJuZWQuCi0gICAgICAgIGlmKGZDdXJyZW50RW50aXR5ID09IG51bGwpewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlIDsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIHNraXAgc3BhY2VzCi0gICAgICAgIGludCBjID0gZkN1cnJlbnRFbnRpdHkuY2hbZkN1cnJlbnRFbnRpdHkucG9zaXRpb25dOwotICAgICAgICBpbnQgb2Zmc2V0ID0gZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gLSAxOwotICAgICAgICBpZiAoWE1MQ2hhci5pc1NwYWNlKGMpKSB7Ci0gICAgICAgICAgICBkbyB7Ci0gICAgICAgICAgICAgICAgYm9vbGVhbiBlbnRpdHlDaGFuZ2VkID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgLy8gaGFuZGxlIG5ld2xpbmVzCi0gICAgICAgICAgICAgICAgaWYgKGMgPT0gJ1xuJyB8fCAoaXNFeHRlcm5hbCAmJiBjID09ICdccicpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LmxpbmVOdW1iZXIrKzsKLSAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkuY29sdW1uTnVtYmVyID0gMTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGZDdXJyZW50RW50aXR5LnBvc2l0aW9uID09IGZDdXJyZW50RW50aXR5LmNvdW50IC0gMSkgewotICAgICAgICAgICAgICAgICAgICAgICAgaW52b2tlTGlzdGVuZXJzKDEpOwotICAgICAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkuY2hbMF0gPSAoY2hhciljOwotICAgICAgICAgICAgICAgICAgICAgICAgZW50aXR5Q2hhbmdlZCA9IGxvYWQoMSwgdHJ1ZSwgZmFsc2UpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFlbnRpdHlDaGFuZ2VkKXsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGUgbG9hZCBjaGFuZ2UgdGhlIHBvc2l0aW9uIHRvIGJlIDEsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbmVlZCB0byByZXN0b3JlIGl0IHdoZW4gZW50aXR5IG5vdCBjaGFuZ2VkCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gPSAwOwotICAgICAgICAgICAgICAgICAgICAgICAgfWVsc2UgaWYoZkN1cnJlbnRFbnRpdHkgPT0gbnVsbCl7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWUgOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGlmIChjID09ICdccicgJiYgaXNFeHRlcm5hbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gUkVWSVNJVDogRG9lcyB0aGlzIG5lZWQgdG8gYmUgdXBkYXRlZCB0byBmaXggdGhlCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyAgICAgICAgICAjeDBEIF4jeDBBIG5ld2xpbmUgbm9ybWFsaXphdGlvbiBwcm9ibGVtPyAtQWMKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmQ3VycmVudEVudGl0eS5jaFsrK2ZDdXJyZW50RW50aXR5LnBvc2l0aW9uXSAhPSAnXG4nKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkucG9zaXRpb24tLTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LmNvbHVtbk51bWJlcisrOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8vSWYgdGhpcyBpcyBhIGdlbmVyYWwgZW50aXR5LCBzcGFjZXMgd2l0aGluIGEgc3RhcnQgZWxlbWVudCBzaG91bGQgYmUgY291bnRlZAotICAgICAgICAgICAgICAgIGNoZWNrRW50aXR5TGltaXQobnVsbCwgZkN1cnJlbnRFbnRpdHksIG9mZnNldCwgZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gLSBvZmZzZXQpOwotICAgICAgICAgICAgICAgIG9mZnNldCA9IGZDdXJyZW50RW50aXR5LnBvc2l0aW9uOwotCi0gICAgICAgICAgICAgICAgLy8gbG9hZCBtb3JlIGNoYXJhY3RlcnMsIGlmIG5lZWRlZAotICAgICAgICAgICAgICAgIGlmICghZW50aXR5Q2hhbmdlZCl7Ci0gICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LnBvc2l0aW9uKys7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgaWYgKGZDdXJyZW50RW50aXR5LnBvc2l0aW9uID09IGZDdXJyZW50RW50aXR5LmNvdW50KSB7Ci0gICAgICAgICAgICAgICAgICAgIGxvYWQoMCwgdHJ1ZSwgdHJ1ZSk7Ci0KLSAgICAgICAgICAgICAgICAgICAgLy93ZSBhcmUgZG9pbmcgdGhpcyBjaGVjayBvbmx5IGluIHNraXBTcGFjZSgpIGJlY2F1c2UgaXQgaXMgY2FsbGVkIGJ5Ci0gICAgICAgICAgICAgICAgICAgIC8vZk1pc2NEaXNwYXRjaGVyIGFuZCB3ZSB3YW50IHRoZSBwYXJzZXIgdG8gZXhpdCBncmFjZWZ1bGx5IHdoZW4gZG9jdW1lbnQKLSAgICAgICAgICAgICAgICAgICAgLy9pcyB3ZWxsLWZvcm1lZC4KLQotICAgICAgICAgICAgICAgICAgICAvL2l0IGlzIHBvc3NpYmxlIHRoYXQgZW5kIG9mIGRvY3VtZW50IGlzIHJlYWNoZWQgYW5kCi0gICAgICAgICAgICAgICAgICAgIC8vZkN1cnJlbnRFbnRpdHkgYmVjb21lcyBudWxsCi0gICAgICAgICAgICAgICAgICAgIC8vbm90aGluZyB3YXMgcmVhZCBzbyBlbnRpdHkgY2hhbmdlZCAgJ2ZhbHNlJyBzaG91bGQgYmUgcmV0dXJuZWQuCi0gICAgICAgICAgICAgICAgICAgIGlmKGZDdXJyZW50RW50aXR5ID09IG51bGwpewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWUgOwotICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9IHdoaWxlIChYTUxDaGFyLmlzU3BhY2UoYyA9IGZDdXJyZW50RW50aXR5LmNoW2ZDdXJyZW50RW50aXR5LnBvc2l0aW9uXSkpOwotICAgICAgICAgICAgaWYgKERFQlVHX0JVRkZFUikgewotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIilza2lwU3BhY2VzOiAiKTsKLSAgICAgICAgICAgICAgICBwcmludCgpOwotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiIC0+IHRydWUiKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gbm8gc3BhY2VzIHdlcmUgZm91bmQKLSAgICAgICAgaWYgKERFQlVHX0JVRkZFUikgewotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiKXNraXBTcGFjZXM6ICIpOwotICAgICAgICAgICAgcHJpbnQoKTsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiIC0+IGZhbHNlIik7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGZhbHNlOwotCi0gICAgfSAvLyBza2lwU3BhY2VzKCk6Ym9vbGVhbgotCi0KLSAgICAvKioKLSAgICAgKiBAcGFyYW0gbGVuZ3RoIFRoaXMgZnVuY3Rpb24gY2hlY2tzIHRoYXQgZm9sbG93aW5nIG51bWJlciBvZiBjaGFyYWN0ZXJzIGFyZSBhdmFpbGFibGUuCi0gICAgICogdG8gdGhlIHVuZGVybHlpbmcgYnVmZmVyLgotICAgICAqIEByZXR1cm4gVGhpcyBmdW5jdGlvbiByZXR1cm5zIHRydWUgaWYgY2FwYWNpdHkgYXNrZWQgaXMgYXZhaWxhYmxlLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGFycmFuZ2VDYXBhY2l0eShpbnQgbGVuZ3RoKSB0aHJvd3MgSU9FeGNlcHRpb257Ci0gICAgICAgIHJldHVybiBhcnJhbmdlQ2FwYWNpdHkobGVuZ3RoLCBmYWxzZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHBhcmFtIGxlbmd0aCBUaGlzIGZ1bmN0aW9uIGNoZWNrcyB0aGF0IGZvbGxvd2luZyBudW1iZXIgb2YgY2hhcmFjdGVycyBhcmUgYXZhaWxhYmxlLgotICAgICAqIHRvIHRoZSB1bmRlcmx5aW5nIGJ1ZmZlci4KLSAgICAgKiBAcGFyYW0gY2hhbmdlRW50aXR5IGEgZmxhZyB0byBpbmRpY2F0ZSB0aGF0IHRoZSB1bmRlcmx5aW5nIGZ1bmN0aW9uIHNob3VsZCBjaGFuZ2UgdGhlIGVudGl0eQotICAgICAqIEByZXR1cm4gVGhpcyBmdW5jdGlvbiByZXR1cm5zIHRydWUgaWYgY2FwYWNpdHkgYXNrZWQgaXMgYXZhaWxhYmxlLgotICAgICAqCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gYXJyYW5nZUNhcGFjaXR5KGludCBsZW5ndGgsIGJvb2xlYW4gY2hhbmdlRW50aXR5KSB0aHJvd3MgSU9FeGNlcHRpb257Ci0gICAgICAgIC8vY2hlY2sgaWYgdGhlIGNhcGFjaXR5IGlzIGF2YWlsYmxlIGluIHRoZSBjdXJyZW50IGJ1ZmZlcgotICAgICAgICAvL2NvdW50IGlzIG5vLiBvZiBjaGFyYWN0ZXJzIGluIHRoZSBidWZmZXIgICBbeF1bbV1bbF0KLSAgICAgICAgLy9wb3NpdGlvbiBpcyAnMCcgYmFzZWQKLSAgICAgICAgLy9TeXN0ZW0ub3V0LnByaW50bG4oImZDdXJyZW50IEVudGl0eSAiICsgZkN1cnJlbnRFbnRpdHkpOwotICAgICAgICBpZigoZkN1cnJlbnRFbnRpdHkuY291bnQgLSBmQ3VycmVudEVudGl0eS5wb3NpdGlvbikgPj0gbGVuZ3RoKSB7Ci0gICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgfQotICAgICAgICBpZihERUJVR19TS0lQX1NUUklORyl7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oImZDdXJyZW50RW50aXR5LmNvdW50ID0gIiArIGZDdXJyZW50RW50aXR5LmNvdW50KTsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gPSAiICsgZkN1cnJlbnRFbnRpdHkucG9zaXRpb24pOwotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJsZW5ndGggPSAiICsgbGVuZ3RoKTsKLSAgICAgICAgfQotICAgICAgICBib29sZWFuIGVudGl0eUNoYW5nZWQgPSBmYWxzZTsKLSAgICAgICAgLy9sb2FkIG1vcmUgY2hhcmFjdGVycyAtLSB0aGlzIGZ1bmN0aW9uIHNob3VsZG4ndCBjaGFuZ2UgdGhlIGVudGl0eQotICAgICAgICB3aGlsZSgoZkN1cnJlbnRFbnRpdHkuY291bnQgLSBmQ3VycmVudEVudGl0eS5wb3NpdGlvbikgPCBsZW5ndGgpewotICAgICAgICAgICAgaWYoIChmQ3VycmVudEVudGl0eS5jaC5sZW5ndGggLSBmQ3VycmVudEVudGl0eS5wb3NpdGlvbikgPCBsZW5ndGgpewotICAgICAgICAgICAgICAgIGludm9rZUxpc3RlbmVycygwKTsKLSAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGZDdXJyZW50RW50aXR5LmNoLCBmQ3VycmVudEVudGl0eS5wb3NpdGlvbiwgZkN1cnJlbnRFbnRpdHkuY2gsMCxmQ3VycmVudEVudGl0eS5jb3VudCAtIGZDdXJyZW50RW50aXR5LnBvc2l0aW9uKTsKLSAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5jb3VudCA9IGZDdXJyZW50RW50aXR5LmNvdW50IC0gZkN1cnJlbnRFbnRpdHkucG9zaXRpb247Ci0gICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gPSAwOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZigoZkN1cnJlbnRFbnRpdHkuY291bnQgLSBmQ3VycmVudEVudGl0eS5wb3NpdGlvbikgPCBsZW5ndGgpewotICAgICAgICAgICAgICAgIGludCBwb3MgPSBmQ3VycmVudEVudGl0eS5wb3NpdGlvbjsKLSAgICAgICAgICAgICAgICBpbnZva2VMaXN0ZW5lcnMocG9zKTsKLSAgICAgICAgICAgICAgICBlbnRpdHlDaGFuZ2VkID0gbG9hZChmQ3VycmVudEVudGl0eS5jb3VudCwgY2hhbmdlRW50aXR5LCBmYWxzZSk7Ci0gICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gPSBwb3M7Ci0gICAgICAgICAgICAgICAgaWYoZW50aXR5Q2hhbmdlZClicmVhazsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmKERFQlVHX1NLSVBfU1RSSU5HKXsKLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oImZDdXJyZW50RW50aXR5LmNvdW50ID0gIiArIGZDdXJyZW50RW50aXR5LmNvdW50KTsKLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oImZDdXJyZW50RW50aXR5LnBvc2l0aW9uID0gIiArIGZDdXJyZW50RW50aXR5LnBvc2l0aW9uKTsKLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oImxlbmd0aCA9ICIgKyBsZW5ndGgpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIC8vbG9hZCBjaGFuZ2VzIHRoZSBwb3NpdGlvbi4uIHNldCBpdCBiYWNrIHRvIHRoZSBwb2ludCB3aGVyZSB3ZSBzdGFydGVkLgotCi0gICAgICAgIC8vYWZ0ZXIgbG9hZGluZyBjaGVjayBhZ2Fpbi4KLSAgICAgICAgaWYoKGZDdXJyZW50RW50aXR5LmNvdW50IC0gZkN1cnJlbnRFbnRpdHkucG9zaXRpb24pID49IGxlbmd0aCkgewotICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTa2lwcyB0aGUgc3BlY2lmaWVkIHN0cmluZyBhcHBlYXJpbmcgaW1tZWRpYXRlbHkgb24gdGhlIGlucHV0LgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gVGhlIGNoYXJhY3RlcnMgYXJlIGNvbnN1bWVkIG9ubHkgaWYgYWxsCi0gICAgICogdGhlIGNoYXJhY3RlcnMgYXJlIHNraXBwZWQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcyBUaGUgc3RyaW5nIHRvIHNraXAuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFJldHVybnMgdHJ1ZSBpZiB0aGUgc3RyaW5nIHdhcyBza2lwcGVkLgotICAgICAqCi0gICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiAgVGhyb3duIGlmIGkvbyBlcnJvciBvY2N1cnMuCi0gICAgICogQHRocm93cyBFT0ZFeGNlcHRpb24gVGhyb3duIG9uIGVuZCBvZiBmaWxlLgotICAgICAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIHNraXBTdHJpbmcoU3RyaW5nIHMpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0KLSAgICAgICAgZmluYWwgaW50IGxlbmd0aCA9IHMubGVuZ3RoKCk7Ci0KLSAgICAgICAgLy9maXJzdCBtYWtlIHN1cmUgdGhhdCByZXF1aXJlZCBjYXBhY2l0eSBpcyBhdmFpYmxlCi0gICAgICAgIGlmKGFycmFuZ2VDYXBhY2l0eShsZW5ndGgsIGZhbHNlKSl7Ci0gICAgICAgICAgICBmaW5hbCBpbnQgYmVmb3JlU2tpcCA9IGZDdXJyZW50RW50aXR5LnBvc2l0aW9uIDsKLSAgICAgICAgICAgIGludCBhZnRlclNraXAgPSBmQ3VycmVudEVudGl0eS5wb3NpdGlvbiArIGxlbmd0aCAtIDEgOwotICAgICAgICAgICAgaWYoREVCVUdfU0tJUF9TVFJJTkcpewotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigic2tpcFN0cmluZyxsZW5ndGggPSAiICsgcyArICIsIiArIGxlbmd0aCk7Ci0gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJCdWZmZXIgc3RyaW5nIHRvIGJlIHNraXBwZWQgPSAiICsgbmV3IFN0cmluZyhmQ3VycmVudEVudGl0eS5jaCwgYmVmb3JlU2tpcCwgIGxlbmd0aCkpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvL3MuY2hhckF0KCkgaW5kZXhlcyBhcmUgMCB0byAnTGVuZ3RoIC0xJyBiYXNlZC4KLSAgICAgICAgICAgIGludCBpID0gbGVuZ3RoIC0gMSA7Ci0gICAgICAgICAgICAvL2NoZWNrIGZyb20gcmV2ZXJzZQotICAgICAgICAgICAgd2hpbGUocy5jaGFyQXQoaS0tKSA9PSBmQ3VycmVudEVudGl0eS5jaFthZnRlclNraXBdKXsKLSAgICAgICAgICAgICAgICBpZihhZnRlclNraXAtLSA9PSBiZWZvcmVTa2lwKXsKLSAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gPSBmQ3VycmVudEVudGl0eS5wb3NpdGlvbiArIGxlbmd0aCA7Ci0gICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LmNvbHVtbk51bWJlciArPSBsZW5ndGg7Ci0gICAgICAgICAgICAgICAgICAgIGlmICghZGV0ZWN0aW5nVmVyc2lvbikgewotICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tFbnRpdHlMaW1pdChudWxsLCBmQ3VycmVudEVudGl0eSwgYmVmb3JlU2tpcCwgbGVuZ3RoKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfSAvLyBza2lwU3RyaW5nKFN0cmluZyk6Ym9vbGVhbgotCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gc2tpcFN0cmluZyhjaGFyIFtdIHMpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0KLSAgICAgICAgZmluYWwgaW50IGxlbmd0aCA9IHMubGVuZ3RoOwotICAgICAgICAvL2ZpcnN0IG1ha2Ugc3VyZSB0aGF0IHJlcXVpcmVkIGNhcGFjaXR5IGlzIGF2YWlibGUKLSAgICAgICAgaWYoYXJyYW5nZUNhcGFjaXR5KGxlbmd0aCwgZmFsc2UpKXsKLSAgICAgICAgICAgIGludCBiZWZvcmVTa2lwID0gZkN1cnJlbnRFbnRpdHkucG9zaXRpb247Ci0KLSAgICAgICAgICAgIGlmKERFQlVHX1NLSVBfU1RSSU5HKXsKLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oInNraXBTdHJpbmcsbGVuZ3RoID0gIiArIG5ldyBTdHJpbmcocykgKyAiLCIgKyBsZW5ndGgpOwotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigic2tpcFN0cmluZyxsZW5ndGggPSAiICsgbmV3IFN0cmluZyhzKSArICIsIiArIGxlbmd0aCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGZvcihpbnQgaT0wO2k8bGVuZ3RoO2krKyl7Ci0gICAgICAgICAgICAgICAgaWYoIShmQ3VycmVudEVudGl0eS5jaFtiZWZvcmVTa2lwKytdPT1zW2ldKSl7Ci0gICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LnBvc2l0aW9uID0gZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gKyBsZW5ndGggOwotICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkuY29sdW1uTnVtYmVyICs9IGxlbmd0aDsKLSAgICAgICAgICAgIGlmICghZGV0ZWN0aW5nVmVyc2lvbikgewotICAgICAgICAgICAgICAgIGNoZWNrRW50aXR5TGltaXQobnVsbCwgZkN1cnJlbnRFbnRpdHksIGJlZm9yZVNraXAsIGxlbmd0aCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLQotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIC8vCi0gICAgLy8gTG9jYXRvciBtZXRob2RzCi0gICAgLy8KLSAgICAvLwotICAgIC8vIFByaXZhdGUgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBMb2FkcyBhIGNodW5rIG9mIHRleHQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gb2Zmc2V0ICAgICAgIFRoZSBvZmZzZXQgaW50byB0aGUgY2hhcmFjdGVyIGJ1ZmZlciB0bwotICAgICAqICAgICAgICAgICAgICAgICAgICAgcmVhZCB0aGUgbmV4dCBiYXRjaCBvZiBjaGFyYWN0ZXJzLgotICAgICAqIEBwYXJhbSBjaGFuZ2VFbnRpdHkgVHJ1ZSBpZiB0aGUgbG9hZCBzaG91bGQgY2hhbmdlIGVudGl0aWVzCi0gICAgICogICAgICAgICAgICAgICAgICAgICBhdCB0aGUgZW5kIG9mIHRoZSBlbnRpdHksIG90aGVyd2lzZSBsZWF2ZQotICAgICAqICAgICAgICAgICAgICAgICAgICAgdGhlIGN1cnJlbnQgZW50aXR5IGluIHBsYWNlIGFuZCB0aGUgZW50aXR5Ci0gICAgICogICAgICAgICAgICAgICAgICAgICBib3VuZGFyeSB3aWxsIGJlIHNpZ25hbGVkIGJ5IHRoZSByZXR1cm4KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgIHZhbHVlLgotICAgICAqIEBwYXJhbSBub3RpZnkgICAgICAgRGV0ZXJtaW5lIHdoZXRoZXIgdG8gbm90aWZ5IGxpc3RlbmVycyBvZgotICAgICAqICAgICAgICAgICAgICAgICAgICAgdGhlIGV2ZW50Ci0gICAgICoKLSAgICAgKiBAcmV0dXJucyBSZXR1cm5zIHRydWUgaWYgdGhlIGVudGl0eSBjaGFuZ2VkIGFzIGEgcmVzdWx0IG9mIHRoaXMKLSAgICAgKiAgICAgICAgICBsb2FkIG9wZXJhdGlvbi4KLSAgICAgKi8KLSAgICBmaW5hbCBib29sZWFuIGxvYWQoaW50IG9mZnNldCwgYm9vbGVhbiBjaGFuZ2VFbnRpdHksIGJvb2xlYW4gbm90aWZ5KQotICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChERUJVR19CVUZGRVIpIHsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIihsb2FkLCAiK29mZnNldCsiOiAiKTsKLSAgICAgICAgICAgIHByaW50KCk7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oKTsKLSAgICAgICAgfQotICAgICAgICBpZiAobm90aWZ5KSB7Ci0gICAgICAgICAgICBpbnZva2VMaXN0ZW5lcnMob2Zmc2V0KTsKLSAgICAgICAgfQotICAgICAgICAvL21haW50YWluZyB0aGUgY291bnQgdGlsbCBsYXN0IGxvYWQKLSAgICAgICAgZkN1cnJlbnRFbnRpdHkuZlRvdGFsQ291bnRUaWxsTGFzdExvYWQgPSBmQ3VycmVudEVudGl0eS5mVG90YWxDb3VudFRpbGxMYXN0TG9hZCArIGZDdXJyZW50RW50aXR5LmZMYXN0Q291bnQgOwotICAgICAgICAvLyByZWFkIGNoYXJhY3RlcnMKLSAgICAgICAgaW50IGxlbmd0aCA9IGZDdXJyZW50RW50aXR5LmNoLmxlbmd0aCAtIG9mZnNldDsKLSAgICAgICAgaWYgKCFmQ3VycmVudEVudGl0eS5tYXlSZWFkQ2h1bmtzICYmIGxlbmd0aCA+IFhNTEVudGl0eU1hbmFnZXIuREVGQVVMVF9YTUxERUNMX0JVRkZFUl9TSVpFKSB7Ci0gICAgICAgICAgICBsZW5ndGggPSBYTUxFbnRpdHlNYW5hZ2VyLkRFRkFVTFRfWE1MREVDTF9CVUZGRVJfU0laRTsKLSAgICAgICAgfQotICAgICAgICBpZiAoREVCVUdfQlVGRkVSKSBTeXN0ZW0ub3V0LnByaW50bG4oIiAgbGVuZ3RoIHRvIHRyeSB0byByZWFkOiAiK2xlbmd0aCk7Ci0gICAgICAgIGludCBjb3VudCA9IGZDdXJyZW50RW50aXR5LnJlYWRlci5yZWFkKGZDdXJyZW50RW50aXR5LmNoLCBvZmZzZXQsIGxlbmd0aCk7Ci0gICAgICAgIGlmIChERUJVR19CVUZGRVIpIFN5c3RlbS5vdXQucHJpbnRsbigiICBsZW5ndGggYWN0dWFsbHkgcmVhZDogICIrY291bnQpOwotCi0gICAgICAgIC8vIHJlc2V0IGNvdW50IGFuZCBwb3NpdGlvbgotICAgICAgICBib29sZWFuIGVudGl0eUNoYW5nZWQgPSBmYWxzZTsKLSAgICAgICAgaWYgKGNvdW50ICE9IC0xKSB7Ci0gICAgICAgICAgICBpZiAoY291bnQgIT0gMCkgewotICAgICAgICAgICAgICAgIC8vIHJlY29yZCB0aGUgbGFzdCBjb3VudAotICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LmZMYXN0Q291bnQgPSBjb3VudDsKLSAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5jb3VudCA9IGNvdW50ICsgb2Zmc2V0OwotICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LnBvc2l0aW9uID0gb2Zmc2V0OwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIC8vIGVuZCBvZiB0aGlzIGVudGl0eQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LmNvdW50ID0gb2Zmc2V0OwotICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gPSBvZmZzZXQ7Ci0gICAgICAgICAgICBlbnRpdHlDaGFuZ2VkID0gdHJ1ZTsKLQotICAgICAgICAgICAgaWYgKGNoYW5nZUVudGl0eSkgewotICAgICAgICAgICAgICAgIC8vbm90aWZ5IHRoZSBlbnRpdHkgbWFuYWdlciBhYm91dCB0aGUgZW5kIG9mIGVudGl0eQotICAgICAgICAgICAgICAgIGZFbnRpdHlNYW5hZ2VyLmVuZEVudGl0eSgpOwotICAgICAgICAgICAgICAgIC8vcmV0dXJuIGlmIHRoZSBjdXJyZW50IGVudGl0eSBiZWNvbWVzIG51bGwKLSAgICAgICAgICAgICAgICBpZihmQ3VycmVudEVudGl0eSA9PSBudWxsKXsKLSAgICAgICAgICAgICAgICAgICAgdGhyb3cgRU5EX09GX0RPQ1VNRU5UX0VOVElUWTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLy8gaGFuZGxlIHRoZSB0cmFpbGluZyBlZGdlcwotICAgICAgICAgICAgICAgIGlmIChmQ3VycmVudEVudGl0eS5wb3NpdGlvbiA9PSBmQ3VycmVudEVudGl0eS5jb3VudCkgewotICAgICAgICAgICAgICAgICAgICBsb2FkKDAsIHRydWUsIGZhbHNlKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgfQotICAgICAgICBpZiAoREVCVUdfQlVGRkVSKSB7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCIpbG9hZCwgIitvZmZzZXQrIjogIik7Ci0gICAgICAgICAgICBwcmludCgpOwotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCk7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gZW50aXR5Q2hhbmdlZDsKLQotICAgIH0gLy8gbG9hZChpbnQsIGJvb2xlYW4pOmJvb2xlYW4KLQotICAgIC8qKgotICAgICAqIENyZWF0ZXMgYSByZWFkZXIgY2FwYWJsZSBvZiByZWFkaW5nIHRoZSBnaXZlbiBpbnB1dCBzdHJlYW0gaW4KLSAgICAgKiB0aGUgc3BlY2lmaWVkIGVuY29kaW5nLgotICAgICAqCi0gICAgICogQHBhcmFtIGlucHV0U3RyZWFtICBUaGUgaW5wdXQgc3RyZWFtLgotICAgICAqIEBwYXJhbSBlbmNvZGluZyAgICAgVGhlIGVuY29kaW5nIG5hbWUgdGhhdCB0aGUgaW5wdXQgc3RyZWFtIGlzCi0gICAgICogICAgICAgICAgICAgICAgICAgICBlbmNvZGVkIHVzaW5nLiBJZiB0aGUgdXNlciBoYXMgc3BlY2lmaWVkIHRoYXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgIEphdmEgZW5jb2RpbmcgbmFtZXMgYXJlIGFsbG93ZWQsIHRoZW4gdGhlCi0gICAgICogICAgICAgICAgICAgICAgICAgICBlbmNvZGluZyBuYW1lIG1heSBiZSBhIEphdmEgZW5jb2RpbmcgbmFtZTsKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgIG90aGVyd2lzZSwgaXQgaXMgYW4gaWFuYUVuY29kaW5nIG5hbWUuCi0gICAgICogQHBhcmFtIGlzQmlnRW5kaWFuICAgRm9yIGVuY29kaW5ncyAobGlrZSB1Q1MtNCksIHdob3NlIG5hbWVzIGNhbm5vdAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIHNwZWNpZnkgYSBieXRlIG9yZGVyLCB0aGlzIHRlbGxzIHdoZXRoZXIgdGhlIG9yZGVyIGlzIGJpZ0VuZGlhbi4gIG51bGwgbWVuYXMKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICB1bmtub3duIG9yIG5vdCByZWxldmFudC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gUmV0dXJucyBhIHJlYWRlci4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgUmVhZGVyIGNyZWF0ZVJlYWRlcihJbnB1dFN0cmVhbSBpbnB1dFN0cmVhbSwgU3RyaW5nIGVuY29kaW5nLCBCb29sZWFuIGlzQmlnRW5kaWFuKQotICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy8gbm9ybWFsaXplIGVuY29kaW5nIG5hbWUKLSAgICAgICAgaWYgKGVuY29kaW5nID09IG51bGwpIHsKLSAgICAgICAgICAgIGVuY29kaW5nID0gIlVURi04IjsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIHRyeSB0byB1c2UgYW4gb3B0aW1pemVkIHJlYWRlcgotICAgICAgICBTdHJpbmcgRU5DT0RJTkcgPSBlbmNvZGluZy50b1VwcGVyQ2FzZShMb2NhbGUuRU5HTElTSCk7Ci0gICAgICAgIGlmIChFTkNPRElORy5lcXVhbHMoIlVURi04IikpIHsKLSAgICAgICAgICAgIGlmIChERUJVR19FTkNPRElOR1MpIHsKLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIiQkJCBjcmVhdGluZyBVVEY4UmVhZGVyIik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gbmV3IFVURjhSZWFkZXIoaW5wdXRTdHJlYW0sIGZDdXJyZW50RW50aXR5LmZCdWZmZXJTaXplLCBmRXJyb3JSZXBvcnRlci5nZXRNZXNzYWdlRm9ybWF0dGVyKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiksIGZFcnJvclJlcG9ydGVyLmdldExvY2FsZSgpICk7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKEVOQ09ESU5HLmVxdWFscygiVVMtQVNDSUkiKSkgewotICAgICAgICAgICAgaWYgKERFQlVHX0VOQ09ESU5HUykgewotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiJCQkIGNyZWF0aW5nIEFTQ0lJUmVhZGVyIik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gbmV3IEFTQ0lJUmVhZGVyKGlucHV0U3RyZWFtLCBmQ3VycmVudEVudGl0eS5mQnVmZmVyU2l6ZSwgZkVycm9yUmVwb3J0ZXIuZ2V0TWVzc2FnZUZvcm1hdHRlcihYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4pLCBmRXJyb3JSZXBvcnRlci5nZXRMb2NhbGUoKSk7Ci0gICAgICAgIH0KLSAgICAgICAgaWYoRU5DT0RJTkcuZXF1YWxzKCJJU08tMTA2NDYtVUNTLTQiKSkgewotICAgICAgICAgICAgaWYoaXNCaWdFbmRpYW4gIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGJvb2xlYW4gaXNCRSA9IGlzQmlnRW5kaWFuLmJvb2xlYW5WYWx1ZSgpOwotICAgICAgICAgICAgICAgIGlmKGlzQkUpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBVQ1NSZWFkZXIoaW5wdXRTdHJlYW0sIFVDU1JlYWRlci5VQ1M0QkUpOwotICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgVUNTUmVhZGVyKGlucHV0U3RyZWFtLCBVQ1NSZWFkZXIuVUNTNExFKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICJFbmNvZGluZ0J5dGVPcmRlclVuc3VwcG9ydGVkIiwKLSAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7IGVuY29kaW5nIH0sCi0gICAgICAgICAgICAgICAgICAgICAgICBYTUxFcnJvclJlcG9ydGVyLlNFVkVSSVRZX0ZBVEFMX0VSUk9SKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBpZihFTkNPRElORy5lcXVhbHMoIklTTy0xMDY0Ni1VQ1MtMiIpKSB7Ci0gICAgICAgICAgICBpZihpc0JpZ0VuZGlhbiAhPSBudWxsKSB7IC8vIHNvdWxkIG5ldmVyIGhhcHBlbiB3aXRoIHRoaXMgZW5jb2RpbmcuLi4KLSAgICAgICAgICAgICAgICBib29sZWFuIGlzQkUgPSBpc0JpZ0VuZGlhbi5ib29sZWFuVmFsdWUoKTsKLSAgICAgICAgICAgICAgICBpZihpc0JFKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgVUNTUmVhZGVyKGlucHV0U3RyZWFtLCBVQ1NSZWFkZXIuVUNTMkJFKTsKLSAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFVDU1JlYWRlcihpbnB1dFN0cmVhbSwgVUNTUmVhZGVyLlVDUzJMRSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBmRXJyb3JSZXBvcnRlci5yZXBvcnRFcnJvcihYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAiRW5jb2RpbmdCeXRlT3JkZXJVbnN1cHBvcnRlZCIsCi0gICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBlbmNvZGluZyB9LAotICAgICAgICAgICAgICAgICAgICAgICAgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9GQVRBTF9FUlJPUik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBjaGVjayBmb3IgdmFsaWQgbmFtZQotICAgICAgICBib29sZWFuIHZhbGlkSUFOQSA9IFhNTENoYXIuaXNWYWxpZElBTkFFbmNvZGluZyhlbmNvZGluZyk7Ci0gICAgICAgIGJvb2xlYW4gdmFsaWRKYXZhID0gWE1MQ2hhci5pc1ZhbGlkSmF2YUVuY29kaW5nKGVuY29kaW5nKTsKLSAgICAgICAgaWYgKCF2YWxpZElBTkEgfHwgKGZBbGxvd0phdmFFbmNvZGluZ3MgJiYgIXZhbGlkSmF2YSkpIHsKLSAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgIkVuY29kaW5nRGVjbEludmFsaWQiLAotICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBlbmNvZGluZyB9LAotICAgICAgICAgICAgICAgICAgICBYTUxFcnJvclJlcG9ydGVyLlNFVkVSSVRZX0ZBVEFMX0VSUk9SKTsKLSAgICAgICAgICAgICAgICAgICAgLy8gTk9URTogQW5keUggc3VnZ2VzdGVkIHRoYXQsIG9uIGZhaWx1cmUsIHdlIHVzZSBJU08gTGF0aW4gMQotICAgICAgICAgICAgICAgICAgICAvLyAgICAgICBiZWNhdXNlIGV2ZXJ5IGJ5dGUgaXMgYSB2YWxpZCBJU08gTGF0aW4gMSBjaGFyYWN0ZXIuCi0gICAgICAgICAgICAgICAgICAgIC8vICAgICAgIEl0IG1heSBub3QgdHJhbnNsYXRlIGNvcnJlY3RseSBidXQgaWYgd2UgZmFpbGVkIG9uCi0gICAgICAgICAgICAgICAgICAgIC8vICAgICAgIHRoZSBlbmNvZGluZyBhbnl3YXksIHRoZW4gd2UncmUgZXhwZWN0aW5nIHRoZSBjb250ZW50Ci0gICAgICAgICAgICAgICAgICAgIC8vICAgICAgIG9mIHRoZSBkb2N1bWVudCB0byBiZSBiYWQuIFRoaXMgd2lsbCBqdXN0IHByZXZlbnQgYW4KLSAgICAgICAgICAgICAgICAgICAgLy8gICAgICAgaW52YWxpZCBVVEYtOCBzZXF1ZW5jZSB0byBiZSBkZXRlY3RlZC4gVGhpcyBpcyBvbmx5Ci0gICAgICAgICAgICAgICAgICAgIC8vICAgICAgIGltcG9ydGFudCB3aGVuIGNvbnRpbnVlLWFmdGVyLWZhdGFsLWVycm9yIGlzIHR1cm5lZAotICAgICAgICAgICAgICAgICAgICAvLyAgICAgICBvbi4gLUFjCi0gICAgICAgICAgICAgICAgICAgIGVuY29kaW5nID0gIklTTy04ODU5LTEiOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gdHJ5IHRvIHVzZSBhIEphdmEgcmVhZGVyCi0gICAgICAgIFN0cmluZyBqYXZhRW5jb2RpbmcgPSBFbmNvZGluZ01hcC5nZXRJQU5BMkphdmFNYXBwaW5nKEVOQ09ESU5HKTsKLSAgICAgICAgaWYgKGphdmFFbmNvZGluZyA9PSBudWxsKSB7Ci0gICAgICAgICAgICBpZihmQWxsb3dKYXZhRW5jb2RpbmdzKSB7Ci0gICAgICAgICAgICAgICAgamF2YUVuY29kaW5nID0gZW5jb2Rpbmc7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICJFbmNvZGluZ0RlY2xJbnZhbGlkIiwKLSAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7IGVuY29kaW5nIH0sCi0gICAgICAgICAgICAgICAgICAgICAgICBYTUxFcnJvclJlcG9ydGVyLlNFVkVSSVRZX0ZBVEFMX0VSUk9SKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNlZSBjb21tZW50IGFib3ZlLgotICAgICAgICAgICAgICAgICAgICAgICAgamF2YUVuY29kaW5nID0gIklTTzg4NTlfMSI7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoamF2YUVuY29kaW5nLmVxdWFscygiQVNDSUkiKSkgewotICAgICAgICAgICAgaWYgKERFQlVHX0VOQ09ESU5HUykgewotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiJCQkIGNyZWF0aW5nIEFTQ0lJUmVhZGVyIik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gbmV3IEFTQ0lJUmVhZGVyKGlucHV0U3RyZWFtLCBmQnVmZmVyU2l6ZSwgZkVycm9yUmVwb3J0ZXIuZ2V0TWVzc2FnZUZvcm1hdHRlcihYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4pLCBmRXJyb3JSZXBvcnRlci5nZXRMb2NhbGUoKSk7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoREVCVUdfRU5DT0RJTkdTKSB7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCIkJCQgY3JlYXRpbmcgSmF2YSBJbnB1dFN0cmVhbVJlYWRlcjogZW5jb2Rpbmc9IitqYXZhRW5jb2RpbmcpOwotICAgICAgICAgICAgaWYgKGphdmFFbmNvZGluZyA9PSBlbmNvZGluZykgewotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIiAoSUFOQSBlbmNvZGluZykiKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBuZXcgSW5wdXRTdHJlYW1SZWFkZXIoaW5wdXRTdHJlYW0sIGphdmFFbmNvZGluZyk7Ci0KLSAgICB9IC8vIGNyZWF0ZVJlYWRlcihJbnB1dFN0cmVhbSxTdHJpbmcsIEJvb2xlYW4pOiBSZWFkZXIKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIElBTkEgZW5jb2RpbmcgbmFtZSB0aGF0IGlzIGF1dG8tZGV0ZWN0ZWQgZnJvbQotICAgICAqIHRoZSBieXRlcyBzcGVjaWZpZWQsIHdpdGggdGhlIGVuZGlhbi1uZXNzIG9mIHRoYXQgZW5jb2Rpbmcgd2hlcmUgYXBwcm9wcmlhdGUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYjQgICAgVGhlIGZpcnN0IGZvdXIgYnl0ZXMgb2YgdGhlIGlucHV0LgotICAgICAqIEBwYXJhbSBjb3VudCBUaGUgbnVtYmVyIG9mIGJ5dGVzIGFjdHVhbGx5IHJlYWQuCi0gICAgICogQHJldHVybiBhIDItZWxlbWVudCBhcnJheTogIHRoZSBmaXJzdCBlbGVtZW50LCBhbiBJQU5BLWVuY29kaW5nIHN0cmluZywKLSAgICAgKiAgdGhlIHNlY29uZCBlbGVtZW50IGEgQm9vbGVhbiB3aGljaCBpcyB0cnVlIGlmZiB0aGUgZG9jdW1lbnQgaXMgYmlnIGVuZGlhbiwgZmFsc2UKLSAgICAgKiAgaWYgaXQncyBsaXR0bGUtZW5kaWFuLCBhbmQgbnVsbCBpZiB0aGUgZGlzdGluY3Rpb24gaXNuJ3QgcmVsZXZhbnQuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIE9iamVjdFtdIGdldEVuY29kaW5nTmFtZShieXRlW10gYjQsIGludCBjb3VudCkgewotCi0gICAgICAgIGlmIChjb3VudCA8IDIpIHsKLSAgICAgICAgICAgIHJldHVybiBuZXcgT2JqZWN0W117IlVURi04IiwgbnVsbH07Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBVVEYtMTYsIHdpdGggQk9NCi0gICAgICAgIGludCBiMCA9IGI0WzBdICYgMHhGRjsKLSAgICAgICAgaW50IGIxID0gYjRbMV0gJiAweEZGOwotICAgICAgICBpZiAoYjAgPT0gMHhGRSAmJiBiMSA9PSAweEZGKSB7Ci0gICAgICAgICAgICAvLyBVVEYtMTYsIGJpZy1lbmRpYW4KLSAgICAgICAgICAgIHJldHVybiBuZXcgT2JqZWN0IFtdIHsiVVRGLTE2QkUiLCBuZXcgQm9vbGVhbih0cnVlKX07Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGIwID09IDB4RkYgJiYgYjEgPT0gMHhGRSkgewotICAgICAgICAgICAgLy8gVVRGLTE2LCBsaXR0bGUtZW5kaWFuCi0gICAgICAgICAgICByZXR1cm4gbmV3IE9iamVjdCBbXSB7IlVURi0xNkxFIiwgbmV3IEJvb2xlYW4oZmFsc2UpfTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIGRlZmF1bHQgdG8gVVRGLTggaWYgd2UgZG9uJ3QgaGF2ZSBlbm91Z2ggYnl0ZXMgdG8gbWFrZSBhCi0gICAgICAgIC8vIGdvb2QgZGV0ZXJtaW5hdGlvbiBvZiB0aGUgZW5jb2RpbmcKLSAgICAgICAgaWYgKGNvdW50IDwgMykgewotICAgICAgICAgICAgcmV0dXJuIG5ldyBPYmplY3QgW10geyJVVEYtOCIsIG51bGx9OwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gVVRGLTggd2l0aCBhIEJPTQotICAgICAgICBpbnQgYjIgPSBiNFsyXSAmIDB4RkY7Ci0gICAgICAgIGlmIChiMCA9PSAweEVGICYmIGIxID09IDB4QkIgJiYgYjIgPT0gMHhCRikgewotICAgICAgICAgICAgcmV0dXJuIG5ldyBPYmplY3QgW10geyJVVEYtOCIsIG51bGx9OwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gZGVmYXVsdCB0byBVVEYtOCBpZiB3ZSBkb24ndCBoYXZlIGVub3VnaCBieXRlcyB0byBtYWtlIGEKLSAgICAgICAgLy8gZ29vZCBkZXRlcm1pbmF0aW9uIG9mIHRoZSBlbmNvZGluZwotICAgICAgICBpZiAoY291bnQgPCA0KSB7Ci0gICAgICAgICAgICByZXR1cm4gbmV3IE9iamVjdCBbXSB7IlVURi04IiwgbnVsbH07Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBvdGhlciBlbmNvZGluZ3MKLSAgICAgICAgaW50IGIzID0gYjRbM10gJiAweEZGOwotICAgICAgICBpZiAoYjAgPT0gMHgwMCAmJiBiMSA9PSAweDAwICYmIGIyID09IDB4MDAgJiYgYjMgPT0gMHgzQykgewotICAgICAgICAgICAgLy8gVUNTLTQsIGJpZyBlbmRpYW4gKDEyMzQpCi0gICAgICAgICAgICByZXR1cm4gbmV3IE9iamVjdCBbXSB7IklTTy0xMDY0Ni1VQ1MtNCIsIG5ldyBCb29sZWFuKHRydWUpfTsKLSAgICAgICAgfQotICAgICAgICBpZiAoYjAgPT0gMHgzQyAmJiBiMSA9PSAweDAwICYmIGIyID09IDB4MDAgJiYgYjMgPT0gMHgwMCkgewotICAgICAgICAgICAgLy8gVUNTLTQsIGxpdHRsZSBlbmRpYW4gKDQzMjEpCi0gICAgICAgICAgICByZXR1cm4gbmV3IE9iamVjdCBbXSB7IklTTy0xMDY0Ni1VQ1MtNCIsIG5ldyBCb29sZWFuKGZhbHNlKX07Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGIwID09IDB4MDAgJiYgYjEgPT0gMHgwMCAmJiBiMiA9PSAweDNDICYmIGIzID09IDB4MDApIHsKLSAgICAgICAgICAgIC8vIFVDUy00LCB1bnVzdWFsIG9jdGV0IG9yZGVyICgyMTQzKQotICAgICAgICAgICAgLy8gUkVWSVNJVDogV2hhdCBzaG91bGQgdGhpcyBiZT8KLSAgICAgICAgICAgIHJldHVybiBuZXcgT2JqZWN0IFtdIHsiSVNPLTEwNjQ2LVVDUy00IiwgbnVsbH07Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGIwID09IDB4MDAgJiYgYjEgPT0gMHgzQyAmJiBiMiA9PSAweDAwICYmIGIzID09IDB4MDApIHsKLSAgICAgICAgICAgIC8vIFVDUy00LCB1bnVzdWFsIG9jdGVjdCBvcmRlciAoMzQxMikKLSAgICAgICAgICAgIC8vIFJFVklTSVQ6IFdoYXQgc2hvdWxkIHRoaXMgYmU/Ci0gICAgICAgICAgICByZXR1cm4gbmV3IE9iamVjdCBbXSB7IklTTy0xMDY0Ni1VQ1MtNCIsIG51bGx9OwotICAgICAgICB9Ci0gICAgICAgIGlmIChiMCA9PSAweDAwICYmIGIxID09IDB4M0MgJiYgYjIgPT0gMHgwMCAmJiBiMyA9PSAweDNGKSB7Ci0gICAgICAgICAgICAvLyBVVEYtMTYsIGJpZy1lbmRpYW4sIG5vIEJPTQotICAgICAgICAgICAgLy8gKG9yIGNvdWxkIHR1cm4gb3V0IHRvIGJlIFVDUy0yLi4uCi0gICAgICAgICAgICAvLyBSRVZJU0lUOiBXaGF0IHNob3VsZCB0aGlzIGJlPwotICAgICAgICAgICAgcmV0dXJuIG5ldyBPYmplY3QgW10geyJVVEYtMTZCRSIsIG5ldyBCb29sZWFuKHRydWUpfTsKLSAgICAgICAgfQotICAgICAgICBpZiAoYjAgPT0gMHgzQyAmJiBiMSA9PSAweDAwICYmIGIyID09IDB4M0YgJiYgYjMgPT0gMHgwMCkgewotICAgICAgICAgICAgLy8gVVRGLTE2LCBsaXR0bGUtZW5kaWFuLCBubyBCT00KLSAgICAgICAgICAgIC8vIChvciBjb3VsZCB0dXJuIG91dCB0byBiZSBVQ1MtMi4uLgotICAgICAgICAgICAgcmV0dXJuIG5ldyBPYmplY3QgW10geyJVVEYtMTZMRSIsIG5ldyBCb29sZWFuKGZhbHNlKX07Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGIwID09IDB4NEMgJiYgYjEgPT0gMHg2RiAmJiBiMiA9PSAweEE3ICYmIGIzID09IDB4OTQpIHsKLSAgICAgICAgICAgIC8vIEVCQ0RJQwotICAgICAgICAgICAgLy8gYSBsYSB4ZXJjZXMxLCByZXR1cm4gQ1AwMzcgaW5zdGVhZCBvZiBFQkNESUMgaGVyZQotICAgICAgICAgICAgcmV0dXJuIG5ldyBPYmplY3QgW10geyJDUDAzNyIsIG51bGx9OwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gZGVmYXVsdCBlbmNvZGluZwotICAgICAgICByZXR1cm4gbmV3IE9iamVjdCBbXSB7IlVURi04IiwgbnVsbH07Ci0KLSAgICB9IC8vIGdldEVuY29kaW5nTmFtZShieXRlW10saW50KTpPYmplY3RbXQotCi0gICAgLyoqCi0gICAgICogeHh4IG5vdCByZW1vdmluZyBlbmRFbnRpdHkoKSBzbyB0aGF0IGkgcmVtZW1iZXIgdGhhdCB3ZSBuZWVkIHRvIGltcGxlbWVudCBpdC4KLSAgICAgKiBFbmRzIGFuIGVudGl0eS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBlbnRpdHkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgLy8KLSAgICAvKiogUHJpbnRzIHRoZSBjb250ZW50cyBvZiB0aGUgYnVmZmVyLiAqLwotICAgIGZpbmFsIHZvaWQgcHJpbnQoKSB7Ci0gICAgICAgIGlmIChERUJVR19CVUZGRVIpIHsKLSAgICAgICAgICAgIGlmIChmQ3VycmVudEVudGl0eSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgnWycpOwotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoZkN1cnJlbnRFbnRpdHkuY291bnQpOwotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoJyAnKTsKLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KGZDdXJyZW50RW50aXR5LnBvc2l0aW9uKTsKLSAgICAgICAgICAgICAgICBpZiAoZkN1cnJlbnRFbnRpdHkuY291bnQgPiAwKSB7Ci0gICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIiBcIiIpOwotICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZDdXJyZW50RW50aXR5LmNvdW50OyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpID09IGZDdXJyZW50RW50aXR5LnBvc2l0aW9uKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgnXicpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgY2hhciBjID0gZkN1cnJlbnRFbnRpdHkuY2hbaV07Ci0gICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGMpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdcbic6IHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiXFxuIik7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdccic6IHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiXFxyIik7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdcdCc6IHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiXFx0Iik7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdcXCc6IHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiXFxcXCIpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDogewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KGMpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBpZiAoZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gPT0gZkN1cnJlbnRFbnRpdHkuY291bnQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoJ14nKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCciJyk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoJ10nKTsKLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCIgQCAiKTsKLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KGZDdXJyZW50RW50aXR5LmxpbmVOdW1iZXIpOwotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoJywnKTsKLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KGZDdXJyZW50RW50aXR5LmNvbHVtbk51bWJlcik7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIipOTyBDVVJSRU5UIEVOVElUWSoiKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJlZ2lzdGVycyB0aGUgbGlzdGVuZXIgb2JqZWN0IGFuZCBwcm92aWRlcyBjYWxsYmFjay4KLSAgICAgKiBAcGFyYW0gbGlzdGVuZXIgbGlzdGVuZXIgdG8gd2hpY2ggY2FsbCBiYWNrIHNob3VsZCBiZSBwcm92aWRlZCB3aGVuIHNjYW5uZXIgYnVmZmVyCi0gICAgICogaXMgYmVpbmcgY2hhbmdlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCByZWdpc3Rlckxpc3RlbmVyKFhNTEJ1ZmZlckxpc3RlbmVyIGxpc3RlbmVyKSB7Ci0gICAgICAgIGlmICghbGlzdGVuZXJzLmNvbnRhaW5zKGxpc3RlbmVyKSkgewotICAgICAgICAgICAgbGlzdGVuZXJzLmFkZChsaXN0ZW5lcik7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKgotICAgICAqIEBwYXJhbSBsb2FkUG9zIFN0YXJ0aW5nIHBvc2l0aW9uIGZyb20gd2hpY2ggbmV3IGRhdGEgaXMgYmVpbmcgbG9hZGVkIGludG8gc2Nhbm5lciBidWZmZXIuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgaW52b2tlTGlzdGVuZXJzKGludCBsb2FkUG9zKXsKLSAgICAgICAgZm9yIChpbnQgaT0wOyBpPGxpc3RlbmVycy5zaXplKCk7IGkrKykgewotICAgICAgICAgICAgbGlzdGVuZXJzLmdldChpKS5yZWZyZXNoKGxvYWRQb3MpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2tpcHMgc3BhY2UgY2hhcmFjdGVycyBhcHBlYXJpbmcgaW1tZWRpYXRlbHkgb24gdGhlIGlucHV0IHRoYXQgd291bGQKLSAgICAgKiBtYXRjaCBub24tdGVybWluYWwgUyAoMHgwOSwgMHgwQSwgMHgwRCwgMHgyMCkgYmVmb3JlIGVuZCBvZiBsaW5lCi0gICAgICogbm9ybWFsaXphdGlvbiBpcyBwZXJmb3JtZWQuIFRoaXMgaXMgdXNlZnVsIHdoZW4gc2Nhbm5pbmcgc3RydWN0dXJlcwotICAgICAqIHN1Y2ggYXMgdGhlIFhNTERlY2wgYW5kIFRleHREZWNsIHRoYXQgY2FuIG9ubHkgY29udGFpbiBVUy1BU0NJSQotICAgICAqIGNoYXJhY3RlcnMuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGUgY2hhcmFjdGVycyBhcmUgY29uc3VtZWQgb25seSBpZiB0aGV5IHdvdWxkCi0gICAgICogbWF0Y2ggbm9uLXRlcm1pbmFsIFMgYmVmb3JlIGVuZCBvZiBsaW5lIG5vcm1hbGl6YXRpb24gaXMgcGVyZm9ybWVkLgotICAgICAqCi0gICAgICogQHJldHVybiBSZXR1cm5zIHRydWUgaWYgYXQgbGVhc3Qgb25lIHNwYWNlIGNoYXJhY3RlciB3YXMgc2tpcHBlZC4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gIFRocm93biBpZiBpL28gZXJyb3Igb2NjdXJzLgotICAgICAqIEB0aHJvd3MgRU9GRXhjZXB0aW9uIFRocm93biBvbiBlbmQgb2YgZmlsZS4KLSAgICAgKgotICAgICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlhNTENoYXIjaXNTcGFjZQotICAgICAqLwotICAgIHByb3RlY3RlZCBmaW5hbCBib29sZWFuIHNraXBEZWNsU3BhY2VzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKERFQlVHX0JVRkZFUikgewotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiKHNraXBEZWNsU3BhY2VzOiAiKTsKLSAgICAgICAgICAgIC8vWE1MRW50aXR5TWFuYWdlci5wcmludChmQ3VycmVudEVudGl0eSk7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIGxvYWQgbW9yZSBjaGFyYWN0ZXJzLCBpZiBuZWVkZWQKLSAgICAgICAgaWYgKGZDdXJyZW50RW50aXR5LnBvc2l0aW9uID09IGZDdXJyZW50RW50aXR5LmNvdW50KSB7Ci0gICAgICAgICAgICBsb2FkKDAsIHRydWUsIGZhbHNlKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIHNraXAgc3BhY2VzCi0gICAgICAgIGludCBjID0gZkN1cnJlbnRFbnRpdHkuY2hbZkN1cnJlbnRFbnRpdHkucG9zaXRpb25dOwotICAgICAgICBpZiAoWE1MQ2hhci5pc1NwYWNlKGMpKSB7Ci0gICAgICAgICAgICBib29sZWFuIGV4dGVybmFsID0gZkN1cnJlbnRFbnRpdHkuaXNFeHRlcm5hbCgpOwotICAgICAgICAgICAgZG8gewotICAgICAgICAgICAgICAgIGJvb2xlYW4gZW50aXR5Q2hhbmdlZCA9IGZhbHNlOwotICAgICAgICAgICAgICAgIC8vIGhhbmRsZSBuZXdsaW5lcwotICAgICAgICAgICAgICAgIGlmIChjID09ICdcbicgfHwgKGV4dGVybmFsICYmIGMgPT0gJ1xyJykpIHsKLSAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkubGluZU51bWJlcisrOwotICAgICAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5jb2x1bW5OdW1iZXIgPSAxOwotICAgICAgICAgICAgICAgICAgICBpZiAoZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gPT0gZkN1cnJlbnRFbnRpdHkuY291bnQgLSAxKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5jaFswXSA9IChjaGFyKWM7Ci0gICAgICAgICAgICAgICAgICAgICAgICBlbnRpdHlDaGFuZ2VkID0gbG9hZCgxLCB0cnVlLCBmYWxzZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWVudGl0eUNoYW5nZWQpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhlIGxvYWQgY2hhbmdlIHRoZSBwb3NpdGlvbiB0byBiZSAxLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG5lZWQgdG8gcmVzdG9yZSBpdCB3aGVuIGVudGl0eSBub3QgY2hhbmdlZAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5LnBvc2l0aW9uID0gMDsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBpZiAoYyA9PSAnXHInICYmIGV4dGVybmFsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBSRVZJU0lUOiBEb2VzIHRoaXMgbmVlZCB0byBiZSB1cGRhdGVkIHRvIGZpeCB0aGUKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgICAgICAgICN4MEQgXiN4MEEgbmV3bGluZSBub3JtYWxpemF0aW9uIHByb2JsZW0/IC1BYwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZDdXJyZW50RW50aXR5LmNoWysrZkN1cnJlbnRFbnRpdHkucG9zaXRpb25dICE9ICdcbicpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5wb3NpdGlvbi0tOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIC8qKiogTkVXTElORSBOT1JNQUxJWkFUSU9OICoqKgotICAgICAgICAgICAgICAgICAgICAgKiBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICogaWYgKGZDdXJyZW50RW50aXR5LmNoW2ZDdXJyZW50RW50aXR5LnBvc2l0aW9uICsgMV0gPT0gJ1xyJwotICAgICAgICAgICAgICAgICAgICAgKiAmJiBleHRlcm5hbCkgewotICAgICAgICAgICAgICAgICAgICAgKiBmQ3VycmVudEVudGl0eS5wb3NpdGlvbisrOwotICAgICAgICAgICAgICAgICAgICAgKiB9Ci0gICAgICAgICAgICAgICAgICAgICAqIH0KLSAgICAgICAgICAgICAgICAgICAgICogLyoqKi8KLSAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5jb2x1bW5OdW1iZXIrKzsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLy8gbG9hZCBtb3JlIGNoYXJhY3RlcnMsIGlmIG5lZWRlZAotICAgICAgICAgICAgICAgIGlmICghZW50aXR5Q2hhbmdlZCkKLSAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkucG9zaXRpb24rKzsKLSAgICAgICAgICAgICAgICBpZiAoZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gPT0gZkN1cnJlbnRFbnRpdHkuY291bnQpIHsKLSAgICAgICAgICAgICAgICAgICAgbG9hZCgwLCB0cnVlLCBmYWxzZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfSB3aGlsZSAoWE1MQ2hhci5pc1NwYWNlKGMgPSBmQ3VycmVudEVudGl0eS5jaFtmQ3VycmVudEVudGl0eS5wb3NpdGlvbl0pKTsKLSAgICAgICAgICAgIGlmIChERUJVR19CVUZGRVIpIHsKLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCIpc2tpcERlY2xTcGFjZXM6ICIpOwotICAgICAgICAgICAgICAgIC8vICBYTUxFbnRpdHlNYW5hZ2VyLnByaW50KGZDdXJyZW50RW50aXR5KTsKLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIiAtPiB0cnVlIik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIG5vIHNwYWNlcyB3ZXJlIGZvdW5kCi0gICAgICAgIGlmIChERUJVR19CVUZGRVIpIHsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIilza2lwRGVjbFNwYWNlczogIik7Ci0gICAgICAgICAgICAvL1hNTEVudGl0eU1hbmFnZXIucHJpbnQoZkN1cnJlbnRFbnRpdHkpOwotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCIgLT4gZmFsc2UiKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZmFsc2U7Ci0KLSAgICB9IC8vIHNraXBEZWNsU3BhY2VzKCk6Ym9vbGVhbgotCi0KLX0gLy8gY2xhc3MgWE1MRW50aXR5U2Nhbm5lcgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9YTUxFcnJvclJlcG9ydGVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL1hNTEVycm9yUmVwb3J0ZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMTMzM2E2OC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL1hNTEVycm9yUmVwb3J0ZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDYxMiArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDE1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICovCi0vKgotICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCi0gKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKLSAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KLSAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCi0gKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAotICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLkRlZmF1bHRFcnJvckhhbmRsZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLkVycm9ySGFuZGxlclByb3h5OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5NZXNzYWdlRm9ybWF0dGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTExvY2F0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE5JRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxDb21wb25lbnQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTENvbXBvbmVudE1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTEVycm9ySGFuZGxlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MUGFyc2VFeGNlcHRpb247Ci1pbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7Ci1pbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKLWltcG9ydCBqYXZhLnV0aWwuTWFwOwotaW1wb3J0IG9yZy54bWwuc2F4LkVycm9ySGFuZGxlcjsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGlzIGEgY29tbW9uIGVsZW1lbnQgb2YgYWxsIHBhcnNlciBjb25maWd1cmF0aW9ucyBhbmQgaXMKLSAqIHVzZWQgdG8gcmVwb3J0IGVycm9ycyB0aGF0IG9jY3VyLiBUaGlzIGNvbXBvbmVudCBjYW4gYmUgcXVlcmllZCBieQotICogcGFyc2VyIGNvbXBvbmVudHMgZnJvbSB0aGUgY29tcG9uZW50IG1hbmFnZXIgdXNpbmcgdGhlIGZvbGxvd2luZwotICogcHJvcGVydHkgSUQ6Ci0gKiA8cHJlPgotICogICBodHRwOi8vYXBhY2hlLm9yZy94bWwvcHJvcGVydGllcy9pbnRlcm5hbC9lcnJvci1yZXBvcnRlcgotICogPC9wcmU+Ci0gKiA8cD4KLSAqIEVycm9ycyBhcmUgc2VwYXJhdGVkIGludG8gZG9tYWlucyB0aGF0IGNhdGVnb3JpemUgYSBjbGFzcyBvZiBlcnJvcnMuCi0gKiBJbiBhIHBhcnNlciBjb25maWd1cmF0aW9uLCB0aGUgcGFyc2VyIHdvdWxkIHJlZ2lzdGVyIGEKLSAqIDxjb2RlPk1lc3NhZ2VGb3JtYXR0ZXI8L2NvZGU+IGZvciBlYWNoIGRvbWFpbiB0aGF0IGlzIGNhcGFibGUgb2YKLSAqIGxvY2FsaXppbmcgZXJyb3IgbWVzc2FnZXMgYW5kIGZvcm1hdHRpbmcgdGhlbSBiYXNlZCBvbiBpbmZvcm1hdGlvbgotICogYWJvdXQgdGhlIGVycm9yLiBBbnkgcGFyc2VyIGNvbXBvbmVudCBjYW4gaW52ZW50IG5ldyBlcnJvciBkb21haW5zCi0gKiBhbmQgcmVnaXN0ZXIgYWRkaXRpb25hbCBtZXNzYWdlIGZvcm1hdHRlcnMgdG8gbG9jYWxpemUgbWVzc2FnZXMgaW4KLSAqIHRob3NlIGRvbWFpbnMuCi0gKiA8cD4KLSAqIFRoaXMgY29tcG9uZW50IHJlcXVpcmVzIHRoZSBmb2xsb3dpbmcgZmVhdHVyZXMgYW5kIHByb3BlcnRpZXMgZnJvbSB0aGUKLSAqIGNvbXBvbmVudCBtYW5hZ2VyIHRoYXQgdXNlcyBpdDoKLSAqIDx1bD4KLSAqICA8bGk+aHR0cDovL2FwYWNoZS5vcmcveG1sL3Byb3BlcnRpZXMvaW50ZXJuYWwvZXJyb3ItaGFuZGxlcjwvbGk+Ci0gKiA8L3VsPgotICogPHA+Ci0gKiBUaGlzIGNvbXBvbmVudCBjYW4gdXNlIHRoZSBmb2xsb3dpbmcgZmVhdHVyZXMgYW5kIHByb3BlcnRpZXMgYnV0IHRoZXkKLSAqIGFyZSBub3QgcmVxdWlyZWQ6Ci0gKiA8dWw+Ci0gKiAgPGxpPmh0dHA6Ly9hcGFjaGUub3JnL3htbC9mZWF0dXJlcy9jb250aW51ZS1hZnRlci1mYXRhbC1lcnJvcjwvbGk+Ci0gKiA8L3VsPgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAc2VlIE1lc3NhZ2VGb3JtYXR0ZXIKLSAqCi0gKiBAYXV0aG9yIEVyaWMgWWUsIElCTQotICogQGF1dGhvciBBbmR5IENsYXJrLCBJQk0KLSAqCi0gKiBAdmVyc2lvbiAkSWQ6IFhNTEVycm9yUmVwb3J0ZXIuamF2YSx2IDEuNSAyMDEwLTExLTAxIDA0OjM5OjQxIGpvZWh3IEV4cCAkCi0gKi8KLXB1YmxpYyBjbGFzcyBYTUxFcnJvclJlcG9ydGVyCi0gICAgaW1wbGVtZW50cyBYTUxDb21wb25lbnQgewotCi0gICAgLy8KLSAgICAvLyBDb25zdGFudHMKLSAgICAvLwotCi0gICAgLy8gc2V2ZXJpdHkKLQotICAgIC8qKgotICAgICAqIFNldmVyaXR5OiB3YXJuaW5nLiBXYXJuaW5ncyByZXByZXNlbnQgaW5mb3JtYXRpb25hbCBtZXNzYWdlcyBvbmx5Ci0gICAgICogdGhhdCBzaG91bGQgbm90IGJlIGNvbnNpZGVyZWQgc2VyaW91cyBlbm91Z2ggdG8gc3RvcCBwYXJzaW5nIG9yCi0gICAgICogaW5kaWNhdGUgYW4gZXJyb3IgaW4gdGhlIGRvY3VtZW50J3MgdmFsaWRpdHkuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBTRVZFUklUWV9XQVJOSU5HID0gMDsKLQotICAgIC8qKgotICAgICAqIFNldmVyaXR5OiBlcnJvci4gQ29tbW9uIGNhdXNlcyBvZiBlcnJvcnMgYXJlIGRvY3VtZW50IHN0cnVjdHVyZSBhbmQvb3IKLSAgICAgKiBjb250ZW50IHRoYXQgdGhhdCBkb2VzIG5vdCBjb25mb3JtIHRvIHRoZSBncmFtbWFyIHJ1bGVzIHNwZWNpZmllZCBmb3IKLSAgICAgKiB0aGUgZG9jdW1lbnQuIFRoZXNlIGFyZSB0eXBpY2FsbHkgdmFsaWRhdGlvbiBlcnJvcnMuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBTRVZFUklUWV9FUlJPUiA9IDE7Ci0KLSAgICAvKioKLSAgICAgKiBTZXZlcml0eTogZmF0YWwgZXJyb3IuIEZhdGFsIGVycm9ycyBhcmUgZXJyb3JzIGluIHRoZSBzeW50YXggb2YgdGhlCi0gICAgICogWE1MIGRvY3VtZW50IG9yIGludmFsaWQgYnl0ZSBzZXF1ZW5jZXMgZm9yIGEgZ2l2ZW4gZW5jb2RpbmcuIFRoZQotICAgICAqIFhNTCAxLjAgU3BlY2lmaWNhdGlvbiBtYW5kYXRlcyB0aGF0IGVycm9ycyBvZiB0aGlzIHR5cGUgYXJlIG5vdAotICAgICAqIHJlY292ZXJhYmxlLgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gVGhlIHBhcnNlciBkb2VzIGhhdmUgYSAiY29udGludWUgYWZ0ZXIgZmF0YWwKLSAgICAgKiBlcnJvciIgZmVhdHVyZSBidXQgaXQgc2hvdWxkIGJlIHVzZWQgd2l0aCBleHRyZW1lIGNhdXRpb24gYW5kIGNhcmUuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBTRVZFUklUWV9GQVRBTF9FUlJPUiA9IDI7Ci0KLSAgICAvLyBmZWF0dXJlIGlkZW50aWZpZXJzCi0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiBjb250aW51ZSBhZnRlciBmYXRhbCBlcnJvci4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBDT05USU5VRV9BRlRFUl9GQVRBTF9FUlJPUiA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuQ09OVElOVUVfQUZURVJfRkFUQUxfRVJST1JfRkVBVFVSRTsKLQotICAgIC8vIHByb3BlcnR5IGlkZW50aWZpZXJzCi0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogZXJyb3IgaGFuZGxlci4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJPUl9IQU5ETEVSID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuRVJST1JfSEFORExFUl9QUk9QRVJUWTsKLQotICAgIC8vIHJlY29nbml6ZWQgZmVhdHVyZXMgYW5kIHByb3BlcnRpZXMKLQotICAgIC8qKiBSZWNvZ25pemVkIGZlYXR1cmVzLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZ1tdIFJFQ09HTklaRURfRkVBVFVSRVMgPSB7Ci0gICAgICAgIENPTlRJTlVFX0FGVEVSX0ZBVEFMX0VSUk9SLAotICAgIH07Ci0KLSAgICAvKiogRmVhdHVyZSBkZWZhdWx0cy4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBCb29sZWFuW10gRkVBVFVSRV9ERUZBVUxUUyA9IHsKLSAgICAgICAgbnVsbCwKLSAgICB9OwotCi0gICAgLyoqIFJlY29nbml6ZWQgcHJvcGVydGllcy4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSBSRUNPR05JWkVEX1BST1BFUlRJRVMgPSB7Ci0gICAgICAgIEVSUk9SX0hBTkRMRVIsCi0gICAgfTsKLQotICAgIC8qKiBQcm9wZXJ0eSBkZWZhdWx0cy4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBPYmplY3RbXSBQUk9QRVJUWV9ERUZBVUxUUyA9IHsKLSAgICAgICAgbnVsbCwKLSAgICB9OwotCi0gICAgLy8KLSAgICAvLyBEYXRhCi0gICAgLy8KLQotICAgIC8qKiBUaGUgbG9jYWxlIHRvIGJlIHVzZWQgdG8gZm9ybWF0IGVycm9yIG1lc3NhZ2VzLiAqLwotICAgIHByb3RlY3RlZCBMb2NhbGUgZkxvY2FsZTsKLQotICAgIC8qKiBNYXBwaW5nIG9mIE1lc3NhZ2UgZm9ybWF0dGVycyBmb3IgZG9tYWlucy4gKi8KLSAgICBwcm90ZWN0ZWQgTWFwPFN0cmluZywgTWVzc2FnZUZvcm1hdHRlcj4gZk1lc3NhZ2VGb3JtYXR0ZXJzOwotCi0gICAgLyoqIEVycm9yIGhhbmRsZXIuICovCi0gICAgcHJvdGVjdGVkIFhNTEVycm9ySGFuZGxlciBmRXJyb3JIYW5kbGVyOwotCi0gICAgLyoqIERvY3VtZW50IGxvY2F0b3IuICovCi0gICAgcHJvdGVjdGVkIFhNTExvY2F0b3IgZkxvY2F0b3I7Ci0KLSAgICAvKiogQ29udGludWUgYWZ0ZXIgZmF0YWwgZXJyb3IgZmVhdHVyZS4gKi8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBmQ29udGludWVBZnRlckZhdGFsRXJyb3I7Ci0KLSAgICAvKioKLSAgICAgKiBEZWZhdWx0IGVycm9yIGhhbmRsZXIuIFRoaXMgZXJyb3IgaGFuZGxlciBpcyBvbmx5IHVzZWQgaW4gdGhlCi0gICAgICogYWJzZW5jZSBvZiBhIHJlZ2lzdGVyZWQgZXJyb3IgaGFuZGxlciBzbyB0aGF0IGVycm9ycyBhcmUgbm90Ci0gICAgICogInN3YWxsb3dlZCIgc2lsZW50bHkuIFRoaXMgaXMgb25lIG9mIHRoZSBtb3N0IGNvbW1vbiAicHJvYmxlbXMiCi0gICAgICogcmVwb3J0ZWQgYnkgdXNlcnMgb2YgdGhlIHBhcnNlci4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgWE1MRXJyb3JIYW5kbGVyIGZEZWZhdWx0RXJyb3JIYW5kbGVyOwotCi0gICAgLyoqIEEgU0FYIHByb3h5IHRvIHRoZSBlcnJvciBoYW5kbGVyIGNvbnRhaW5lZCBpbiB0aGlzIGVycm9yIHJlcG9ydGVyLiAqLwotICAgIHByaXZhdGUgRXJyb3JIYW5kbGVyIGZTYXhQcm94eSA9IG51bGw7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0cnVjdG9ycwotICAgIC8vCi0KLSAgICAvKiogQ29uc3RydWN0cyBhbiBlcnJvciByZXBvcnRlciB3aXRoIGEgbG9jYXRvci4gKi8KLSAgICBwdWJsaWMgWE1MRXJyb3JSZXBvcnRlcigpIHsKLQotICAgICAgICAvLyBSRVZJU0lUOiBbUV0gU2hvdWxkIHRoZSBsb2NhdG9yIGJlIHBhc3NlZCB0byB0aGUgcmVwb3J0RXJyb3IKLSAgICAgICAgLy8gICAgICAgICAgICAgIG1ldGhvZD8gT3RoZXJ3aXNlLCB0aGVyZSBpcyBubyB3YXkgZm9yIGEgcGFyc2VyCi0gICAgICAgIC8vICAgICAgICAgICAgICBjb21wb25lbnQgdG8gc3RvcmUgaW5mb3JtYXRpb24gYWJvdXQgd2hlcmUgYW4KLSAgICAgICAgLy8gICAgICAgICAgICAgIGVycm9yIG9jY3VycmVkIHNvIGFzIHRvIHJlcG9ydCBpdCBsYXRlci4KLSAgICAgICAgLy8KLSAgICAgICAgLy8gICAgICAgICAgICAgIEFuIGV4YW1wbGUgd291bGQgYmUgdG8gcmVjb3JkIHRoZSBsb2NhdGlvbiBvZgotICAgICAgICAvLyAgICAgICAgICAgICAgSURSRUZzIHNvIHRoYXQsIGF0IHRoZSBlbmQgb2YgdGhlIGRvY3VtZW50LCBpZgotICAgICAgICAvLyAgICAgICAgICAgICAgdGhlcmUgaXMgbm8gYXNzb2NpYXRlZCBJRCBkZWNsYXJlZCwgdGhlIGVycm9yCi0gICAgICAgIC8vICAgICAgICAgICAgICBjb3VsZCByZXBvcnQgdGhlIGxvY2F0aW9uIGluZm9ybWF0aW9uIG9mIHRoZQotICAgICAgICAvLyAgICAgICAgICAgICAgcmVmZXJlbmNlLiAtQWMKLSAgICAgICAgLy8KLSAgICAgICAgLy8gTk9URTogSSBhZGRlZCBhbm90aGVyIHJlcG9ydEVycm9yIG1ldGhvZCB0aGF0IGFsbG93cyB0aGUKLSAgICAgICAgLy8gICAgICAgY2FsbGVyIHRvIHNwZWNpZnkgdGhlIGxvY2F0aW9uIG9mIHRoZSBlcnJvciBiZWluZwotICAgICAgICAvLyAgICAgICByZXBvcnRlZC4gLUFjCi0KLSAgICAgICAgZk1lc3NhZ2VGb3JtYXR0ZXJzID0gbmV3IEhhc2hNYXA8PigpOwotCi0gICAgfSAvLyA8aW5pdD4oKQotCi0gICAgLy8KLSAgICAvLyBNZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIGN1cnJlbnQgbG9jYWxlLgotICAgICAqCi0gICAgICogQHBhcmFtIGxvY2FsZSBUaGUgbmV3IGxvY2FsZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRMb2NhbGUoTG9jYWxlIGxvY2FsZSkgewotICAgICAgICBmTG9jYWxlID0gbG9jYWxlOwotICAgIH0gLy8gc2V0TG9jYWxlKExvY2FsZSkKLQotICAgIC8qKgotICAgICAqIEdldHMgdGhlIGN1cnJlbnQgbG9jYWxlLgotICAgICAqCi0gICAgICogQHJldHVybiB0aGUgY3VycmVudCBMb2NhbGUKLSAgICAgKi8KLSAgICBwdWJsaWMgTG9jYWxlIGdldExvY2FsZSgpIHsKLSAgICAgICAgcmV0dXJuIGZMb2NhbGUgOwotICAgIH0gLy8gZ2V0TG9jYWxlKCk6ICBMb2NhbGUKLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIGRvY3VtZW50IGxvY2F0b3IuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbG9jYXRvciBUaGUgbG9jYXRvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXREb2N1bWVudExvY2F0b3IoWE1MTG9jYXRvciBsb2NhdG9yKSB7Ci0gICAgICAgIGZMb2NhdG9yID0gbG9jYXRvcjsKLSAgICB9IC8vIHNldERvY3VtZW50TG9jYXRvcihYTUxMb2NhdG9yKQotCi0gICAgLyoqCi0gICAgICogUmVnaXN0ZXJzIGEgbWVzc2FnZSBmb3JtYXR0ZXIgZm9yIHRoZSBzcGVjaWZpZWQgZG9tYWluLgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gUmVnaXN0ZXJpbmcgYSBtZXNzYWdlIGZvcm1hdHRlciBmb3IgYSBkb21haW4KLSAgICAgKiB3aGVuIHRoZXJlIGlzIGFscmVhZHkgYSBmb3JtYXR0ZXIgcmVnaXN0ZXJlZCB3aWxsIGNhdXNlIHRoZSBwcmV2aW91cwotICAgICAqIGZvcm1hdHRlciB0byBiZSBsb3N0LiBUaGlzIG1ldGhvZCByZXBsYWNlcyBhbnkgcHJldmlvdXNseSByZWdpc3RlcmVkCi0gICAgICogbWVzc2FnZSBmb3JtYXR0ZXIgZm9yIHRoZSBzcGVjaWZpZWQgZG9tYWluLgotICAgICAqCi0gICAgICogQHBhcmFtIGRvbWFpbgotICAgICAqIEBwYXJhbSBtZXNzYWdlRm9ybWF0dGVyCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcHV0TWVzc2FnZUZvcm1hdHRlcihTdHJpbmcgZG9tYWluLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUZvcm1hdHRlciBtZXNzYWdlRm9ybWF0dGVyKSB7Ci0gICAgICAgIGZNZXNzYWdlRm9ybWF0dGVycy5wdXQoZG9tYWluLCBtZXNzYWdlRm9ybWF0dGVyKTsKLSAgICB9IC8vIHB1dE1lc3NhZ2VGb3JtYXR0ZXIoU3RyaW5nLE1lc3NhZ2VGb3JtYXR0ZXIpCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBtZXNzYWdlIGZvcm1hdHRlciBhc3NvY2lhdGVkIHdpdGggdGhlIHNwZWNpZmllZCBkb21haW4sCi0gICAgICogb3IgbnVsbCBpZiBubyBtZXNzYWdlIGZvcm1hdHRlciBpcyByZWdpc3RlcmVkIGZvciB0aGF0IGRvbWFpbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBkb21haW4gVGhlIGRvbWFpbiBvZiB0aGUgbWVzc2FnZSBmb3JtYXR0ZXIuCi0gICAgICovCi0gICAgcHVibGljIE1lc3NhZ2VGb3JtYXR0ZXIgZ2V0TWVzc2FnZUZvcm1hdHRlcihTdHJpbmcgZG9tYWluKSB7Ci0gICAgICAgIHJldHVybiBmTWVzc2FnZUZvcm1hdHRlcnMuZ2V0KGRvbWFpbik7Ci0gICAgfSAvLyBnZXRNZXNzYWdlRm9ybWF0dGVyKFN0cmluZyk6TWVzc2FnZUZvcm1hdHRlcgotCi0gICAgLyoqCi0gICAgICogUmVtb3ZlcyB0aGUgbWVzc2FnZSBmb3JtYXR0ZXIgZm9yIHRoZSBzcGVjaWZpZWQgZG9tYWluIGFuZAotICAgICAqIHJldHVybnMgdGhlIHJlbW92ZWQgbWVzc2FnZSBmb3JtYXR0ZXIuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZG9tYWluIFRoZSBkb21haW4gb2YgdGhlIG1lc3NhZ2UgZm9ybWF0dGVyLgotICAgICAqLwotICAgIHB1YmxpYyBNZXNzYWdlRm9ybWF0dGVyIHJlbW92ZU1lc3NhZ2VGb3JtYXR0ZXIoU3RyaW5nIGRvbWFpbikgewotICAgICAgICByZXR1cm4gZk1lc3NhZ2VGb3JtYXR0ZXJzLnJlbW92ZShkb21haW4pOwotICAgIH0gLy8gcmVtb3ZlTWVzc2FnZUZvcm1hdHRlcihTdHJpbmcpOk1lc3NhZ2VGb3JtYXR0ZXIKLQotICAgIC8qKgotICAgICAqIFJlcG9ydHMgYW4gZXJyb3IuIFRoZSBlcnJvciBtZXNzYWdlIHBhc3NlZCB0byB0aGUgZXJyb3IgaGFuZGxlcgotICAgICAqIGlzIGZvcm1hdHRlZCBmb3IgdGhlIGxvY2FsZSBieSB0aGUgbWVzc2FnZSBmb3JtYXR0ZXIgaW5zdGFsbGVkCi0gICAgICogZm9yIHRoZSBzcGVjaWZpZWQgZXJyb3IgZG9tYWluLgotICAgICAqCi0gICAgICogQHBhcmFtIGRvbWFpbiAgICBUaGUgZXJyb3IgZG9tYWluLgotICAgICAqIEBwYXJhbSBrZXkgICAgICAgVGhlIGtleSBvZiB0aGUgZXJyb3IgbWVzc2FnZS4KLSAgICAgKiBAcGFyYW0gYXJndW1lbnRzIFRoZSByZXBsYWNlbWVudCBhcmd1bWVudHMgZm9yIHRoZSBlcnJvciBtZXNzYWdlLAotICAgICAqICAgICAgICAgICAgICAgICAgaWYgbmVlZGVkLgotICAgICAqIEBwYXJhbSBzZXZlcml0eSAgVGhlIHNldmVyaXR5IG9mIHRoZSBlcnJvci4KLSAgICAgKiBAcmV0dXJuICAgICAgICAgIFRoZSBmb3JtYXR0ZWQgZXJyb3IgbWVzc2FnZS4KLSAgICAgKgotICAgICAqIEBzZWUgI1NFVkVSSVRZX1dBUk5JTkcKLSAgICAgKiBAc2VlICNTRVZFUklUWV9FUlJPUgotICAgICAqIEBzZWUgI1NFVkVSSVRZX0ZBVEFMX0VSUk9SCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyByZXBvcnRFcnJvcihTdHJpbmcgZG9tYWluLCBTdHJpbmcga2V5LCBPYmplY3RbXSBhcmd1bWVudHMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hvcnQgc2V2ZXJpdHkpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICByZXR1cm4gcmVwb3J0RXJyb3IoZkxvY2F0b3IsIGRvbWFpbiwga2V5LCBhcmd1bWVudHMsIHNldmVyaXR5KTsKLSAgICB9IC8vIHJlcG9ydEVycm9yKFN0cmluZyxTdHJpbmcsT2JqZWN0W10sc2hvcnQpOlN0cmluZwotCi0gICAgLyoqCi0gICAgICogUmVwb3J0cyBhbiBlcnJvci4gVGhlIGVycm9yIG1lc3NhZ2UgcGFzc2VkIHRvIHRoZSBlcnJvciBoYW5kbGVyCi0gICAgICogaXMgZm9ybWF0dGVkIGZvciB0aGUgbG9jYWxlIGJ5IHRoZSBtZXNzYWdlIGZvcm1hdHRlciBpbnN0YWxsZWQKLSAgICAgKiBmb3IgdGhlIHNwZWNpZmllZCBlcnJvciBkb21haW4uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZG9tYWluICAgIFRoZSBlcnJvciBkb21haW4uCi0gICAgICogQHBhcmFtIGtleSAgICAgICBUaGUga2V5IG9mIHRoZSBlcnJvciBtZXNzYWdlLgotICAgICAqIEBwYXJhbSBhcmd1bWVudHMgVGhlIHJlcGxhY2VtZW50IGFyZ3VtZW50cyBmb3IgdGhlIGVycm9yIG1lc3NhZ2UsCi0gICAgICogICAgICAgICAgICAgICAgICBpZiBuZWVkZWQuCi0gICAgICogQHBhcmFtIHNldmVyaXR5ICBUaGUgc2V2ZXJpdHkgb2YgdGhlIGVycm9yLgotICAgICAqIEBwYXJhbSBleGNlcHRpb24gVGhlIGV4Y2VwdGlvbiB0byB3cmFwLgotICAgICAqIEByZXR1cm4gICAgICAgICAgVGhlIGZvcm1hdHRlZCBlcnJvciBtZXNzYWdlLgotICAgICAqCi0gICAgICogQHNlZSAjU0VWRVJJVFlfV0FSTklORwotICAgICAqIEBzZWUgI1NFVkVSSVRZX0VSUk9SCi0gICAgICogQHNlZSAjU0VWRVJJVFlfRkFUQUxfRVJST1IKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIHJlcG9ydEVycm9yKFN0cmluZyBkb21haW4sIFN0cmluZyBrZXksIE9iamVjdFtdIGFyZ3VtZW50cywKLSAgICAgICAgICAgIHNob3J0IHNldmVyaXR5LCBFeGNlcHRpb24gZXhjZXB0aW9uKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgcmV0dXJuIHJlcG9ydEVycm9yKGZMb2NhdG9yLCBkb21haW4sIGtleSwgYXJndW1lbnRzLCBzZXZlcml0eSwgZXhjZXB0aW9uKTsKLSAgICB9IC8vIHJlcG9ydEVycm9yKFN0cmluZyxTdHJpbmcsT2JqZWN0W10sc2hvcnQsRXhjZXB0aW9uKTpTdHJpbmcKLQotICAgIC8qKgotICAgICAqIFJlcG9ydHMgYW4gZXJyb3IgYXQgYSBzcGVjaWZpYyBsb2NhdGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBsb2NhdGlvbiAgVGhlIGVycm9yIGxvY2F0aW9uLgotICAgICAqIEBwYXJhbSBkb21haW4gICAgVGhlIGVycm9yIGRvbWFpbi4KLSAgICAgKiBAcGFyYW0ga2V5ICAgICAgIFRoZSBrZXkgb2YgdGhlIGVycm9yIG1lc3NhZ2UuCi0gICAgICogQHBhcmFtIGFyZ3VtZW50cyBUaGUgcmVwbGFjZW1lbnQgYXJndW1lbnRzIGZvciB0aGUgZXJyb3IgbWVzc2FnZSwKLSAgICAgKiAgICAgICAgICAgICAgICAgIGlmIG5lZWRlZC4KLSAgICAgKiBAcGFyYW0gc2V2ZXJpdHkgIFRoZSBzZXZlcml0eSBvZiB0aGUgZXJyb3IuCi0gICAgICogQHJldHVybiAgICAgICAgICBUaGUgZm9ybWF0dGVkIGVycm9yIG1lc3NhZ2UuCi0gICAgICoKLSAgICAgKiBAc2VlICNTRVZFUklUWV9XQVJOSU5HCi0gICAgICogQHNlZSAjU0VWRVJJVFlfRVJST1IKLSAgICAgKiBAc2VlICNTRVZFUklUWV9GQVRBTF9FUlJPUgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgcmVwb3J0RXJyb3IoWE1MTG9jYXRvciBsb2NhdGlvbiwKLSAgICAgICAgICAgIFN0cmluZyBkb21haW4sIFN0cmluZyBrZXksIE9iamVjdFtdIGFyZ3VtZW50cywKLSAgICAgICAgICAgIHNob3J0IHNldmVyaXR5KSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgcmV0dXJuIHJlcG9ydEVycm9yKGxvY2F0aW9uLCBkb21haW4sIGtleSwgYXJndW1lbnRzLCBzZXZlcml0eSwgbnVsbCk7Ci0gICAgfSAvLyByZXBvcnRFcnJvcihYTUxMb2NhdG9yLFN0cmluZyxTdHJpbmcsT2JqZWN0W10sc2hvcnQpOlN0cmluZwotCi0gICAgLyoqCi0gICAgICogUmVwb3J0cyBhbiBlcnJvciBhdCBhIHNwZWNpZmljIGxvY2F0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIGxvY2F0aW9uICBUaGUgZXJyb3IgbG9jYXRpb24uCi0gICAgICogQHBhcmFtIGRvbWFpbiAgICBUaGUgZXJyb3IgZG9tYWluLgotICAgICAqIEBwYXJhbSBrZXkgICAgICAgVGhlIGtleSBvZiB0aGUgZXJyb3IgbWVzc2FnZS4KLSAgICAgKiBAcGFyYW0gYXJndW1lbnRzIFRoZSByZXBsYWNlbWVudCBhcmd1bWVudHMgZm9yIHRoZSBlcnJvciBtZXNzYWdlLAotICAgICAqICAgICAgICAgICAgICAgICAgaWYgbmVlZGVkLgotICAgICAqIEBwYXJhbSBzZXZlcml0eSAgVGhlIHNldmVyaXR5IG9mIHRoZSBlcnJvci4KLSAgICAgKiBAcGFyYW0gZXhjZXB0aW9uIFRoZSBleGNlcHRpb24gdG8gd3JhcC4KLSAgICAgKiBAcmV0dXJuICAgICAgICAgIFRoZSBmb3JtYXR0ZWQgZXJyb3IgbWVzc2FnZS4KLSAgICAgKgotICAgICAqIEBzZWUgI1NFVkVSSVRZX1dBUk5JTkcKLSAgICAgKiBAc2VlICNTRVZFUklUWV9FUlJPUgotICAgICAqIEBzZWUgI1NFVkVSSVRZX0ZBVEFMX0VSUk9SCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyByZXBvcnRFcnJvcihYTUxMb2NhdG9yIGxvY2F0aW9uLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBkb21haW4sIFN0cmluZyBrZXksIE9iamVjdFtdIGFyZ3VtZW50cywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaG9ydCBzZXZlcml0eSwgRXhjZXB0aW9uIGV4Y2VwdGlvbikgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy8gUkVWSVNJVDogW1FdIFNob3VsZCB3ZSBkbyBhbnl0aGluZyBhYm91dCBpbnZhbGlkIHNldmVyaXR5Ci0gICAgICAgIC8vICAgICAgICAgICAgICBwYXJhbWV0ZXI/IC1BYwotCi0gICAgICAgIC8vIGZvcm1hdCBlcnJvciBtZXNzYWdlIGFuZCBjcmVhdGUgcGFyc2UgZXhjZXB0aW9uCi0gICAgICAgIE1lc3NhZ2VGb3JtYXR0ZXIgbWVzc2FnZUZvcm1hdHRlciA9IGdldE1lc3NhZ2VGb3JtYXR0ZXIoZG9tYWluKTsKLSAgICAgICAgU3RyaW5nIG1lc3NhZ2U7Ci0gICAgICAgIGlmIChtZXNzYWdlRm9ybWF0dGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIG1lc3NhZ2UgPSBtZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoZkxvY2FsZSwga2V5LCBhcmd1bWVudHMpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgU3RyaW5nQnVmZmVyIHN0ciA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLSAgICAgICAgICAgIHN0ci5hcHBlbmQoZG9tYWluKTsKLSAgICAgICAgICAgIHN0ci5hcHBlbmQoJyMnKTsKLSAgICAgICAgICAgIHN0ci5hcHBlbmQoa2V5KTsKLSAgICAgICAgICAgIGludCBhcmdDb3VudCA9IGFyZ3VtZW50cyAhPSBudWxsID8gYXJndW1lbnRzLmxlbmd0aCA6IDA7Ci0gICAgICAgICAgICBpZiAoYXJnQ291bnQgPiAwKSB7Ci0gICAgICAgICAgICAgICAgc3RyLmFwcGVuZCgnPycpOwotICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYXJnQ291bnQ7IGkrKykgewotICAgICAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKGFyZ3VtZW50c1tpXSk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChpIDwgYXJnQ291bnQgLTEpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHN0ci5hcHBlbmQoJyYnKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIG1lc3NhZ2UgPSBzdHIudG9TdHJpbmcoKTsKLSAgICAgICAgfQotICAgICAgICBYTUxQYXJzZUV4Y2VwdGlvbiBwYXJzZUV4Y2VwdGlvbiA9IChleGNlcHRpb24gIT0gbnVsbCkgPwotICAgICAgICAgICAgbmV3IFhNTFBhcnNlRXhjZXB0aW9uKGxvY2F0aW9uLCBtZXNzYWdlLCBleGNlcHRpb24pIDoKLSAgICAgICAgICAgIG5ldyBYTUxQYXJzZUV4Y2VwdGlvbihsb2NhdGlvbiwgbWVzc2FnZSk7Ci0KLSAgICAgICAgLy8gZ2V0IGVycm9yIGhhbmRsZXIKLSAgICAgICAgWE1MRXJyb3JIYW5kbGVyIGVycm9ySGFuZGxlciA9IGZFcnJvckhhbmRsZXI7Ci0gICAgICAgIGlmIChlcnJvckhhbmRsZXIgPT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKGZEZWZhdWx0RXJyb3JIYW5kbGVyID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmRGVmYXVsdEVycm9ySGFuZGxlciA9IG5ldyBEZWZhdWx0RXJyb3JIYW5kbGVyKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlcnJvckhhbmRsZXIgPSBmRGVmYXVsdEVycm9ySGFuZGxlcjsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIGNhbGwgZXJyb3IgaGFuZGxlcgotICAgICAgICBzd2l0Y2ggKHNldmVyaXR5KSB7Ci0gICAgICAgICAgICBjYXNlIFNFVkVSSVRZX1dBUk5JTkc6IHsKLSAgICAgICAgICAgICAgICBlcnJvckhhbmRsZXIud2FybmluZyhkb21haW4sIGtleSwgcGFyc2VFeGNlcHRpb24pOwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2FzZSBTRVZFUklUWV9FUlJPUjogewotICAgICAgICAgICAgICAgIGVycm9ySGFuZGxlci5lcnJvcihkb21haW4sIGtleSwgcGFyc2VFeGNlcHRpb24pOwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2FzZSBTRVZFUklUWV9GQVRBTF9FUlJPUjogewotICAgICAgICAgICAgICAgIGVycm9ySGFuZGxlci5mYXRhbEVycm9yKGRvbWFpbiwga2V5LCBwYXJzZUV4Y2VwdGlvbik7Ci0gICAgICAgICAgICAgICAgaWYgKCFmQ29udGludWVBZnRlckZhdGFsRXJyb3IpIHsKLSAgICAgICAgICAgICAgICAgICAgdGhyb3cgcGFyc2VFeGNlcHRpb247Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBtZXNzYWdlOwotCi0gICAgfSAvLyByZXBvcnRFcnJvcihYTUxMb2NhdG9yLFN0cmluZyxTdHJpbmcsT2JqZWN0W10sc2hvcnQsRXhjZXB0aW9uKTpTdHJpbmcKLQotICAgIC8vCi0gICAgLy8gWE1MQ29tcG9uZW50IG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogUmVzZXRzIHRoZSBjb21wb25lbnQuIFRoZSBjb21wb25lbnQgY2FuIHF1ZXJ5IHRoZSBjb21wb25lbnQgbWFuYWdlcgotICAgICAqIGFib3V0IGFueSBmZWF0dXJlcyBhbmQgcHJvcGVydGllcyB0aGF0IGFmZmVjdCB0aGUgb3BlcmF0aW9uIG9mIHRoZQotICAgICAqIGNvbXBvbmVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjb21wb25lbnRNYW5hZ2VyIFRoZSBjb21wb25lbnQgbWFuYWdlci4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uIFRocm93biBieSBjb21wb25lbnQgb24gaW5pdGlhbGl6YXRpb24gZXJyb3IuCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgRm9yIGV4YW1wbGUsIGlmIGEgZmVhdHVyZSBvciBwcm9wZXJ0eSBpcwotICAgICAqICAgICAgICAgICAgICAgICAgICAgIHJlcXVpcmVkIGZvciB0aGUgb3BlcmF0aW9uIG9mIHRoZSBjb21wb25lbnQsIHRoZQotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudCBtYW5hZ2VyIG1heSB0aHJvdyBhCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiBvciBhCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHJlc2V0KFhNTENvbXBvbmVudE1hbmFnZXIgY29tcG9uZW50TWFuYWdlcikKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy8gZmVhdHVyZXMKLSAgICAgICAgZkNvbnRpbnVlQWZ0ZXJGYXRhbEVycm9yID0gY29tcG9uZW50TWFuYWdlci5nZXRGZWF0dXJlKENPTlRJTlVFX0FGVEVSX0ZBVEFMX0VSUk9SLCBmYWxzZSk7Ci0KLSAgICAgICAgLy8gcHJvcGVydGllcwotICAgICAgICBmRXJyb3JIYW5kbGVyID0gKFhNTEVycm9ySGFuZGxlciljb21wb25lbnRNYW5hZ2VyLmdldFByb3BlcnR5KEVSUk9SX0hBTkRMRVIpOwotCi0gICAgfSAvLyByZXNldChYTUxDb21wb25lbnRNYW5hZ2VyKQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhIGxpc3Qgb2YgZmVhdHVyZSBpZGVudGlmaWVycyB0aGF0IGFyZSByZWNvZ25pemVkIGJ5Ci0gICAgICogdGhpcyBjb21wb25lbnQuIFRoaXMgbWV0aG9kIG1heSByZXR1cm4gbnVsbCBpZiBubyBmZWF0dXJlcwotICAgICAqIGFyZSByZWNvZ25pemVkIGJ5IHRoaXMgY29tcG9uZW50LgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmdbXSBnZXRSZWNvZ25pemVkRmVhdHVyZXMoKSB7Ci0gICAgICAgIHJldHVybiAoU3RyaW5nW10pKFJFQ09HTklaRURfRkVBVFVSRVMuY2xvbmUoKSk7Ci0gICAgfSAvLyBnZXRSZWNvZ25pemVkRmVhdHVyZXMoKTpTdHJpbmdbXQotCi0gICAgLyoqCi0gICAgICogU2V0cyB0aGUgc3RhdGUgb2YgYSBmZWF0dXJlLiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgdGhlIGNvbXBvbmVudAotICAgICAqIG1hbmFnZXIgYW55IHRpbWUgYWZ0ZXIgcmVzZXQgd2hlbiBhIGZlYXR1cmUgY2hhbmdlcyBzdGF0ZS4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IENvbXBvbmVudHMgc2hvdWxkIHNpbGVudGx5IGlnbm9yZSBmZWF0dXJlcwotICAgICAqIHRoYXQgZG8gbm90IGFmZmVjdCB0aGUgb3BlcmF0aW9uIG9mIHRoZSBjb21wb25lbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZmVhdHVyZUlkIFRoZSBmZWF0dXJlIGlkZW50aWZpZXIuCi0gICAgICogQHBhcmFtIHN0YXRlICAgICBUaGUgc3RhdGUgb2YgdGhlIGZlYXR1cmUuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24gVGhlIGNvbXBvbmVudCBzaG91bGQgbm90IHRocm93Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMgZXhjZXB0aW9uLgotICAgICAqIEB0aHJvd3MgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIFRoZSBjb21wb25lbnQgc2hvdWxkIG5vdCB0aHJvdwotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMgZXhjZXB0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEZlYXR1cmUoU3RyaW5nIGZlYXR1cmVJZCwgYm9vbGVhbiBzdGF0ZSkKLSAgICAgICAgdGhyb3dzIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gewotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIFhlcmNlcyBmZWF0dXJlcwotICAgICAgICAvLwotCi0gICAgICAgIGlmIChmZWF0dXJlSWQuc3RhcnRzV2l0aChDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYKSkgewotICAgICAgICAgICAgZmluYWwgaW50IHN1ZmZpeExlbmd0aCA9IGZlYXR1cmVJZC5sZW5ndGgoKSAtIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVgubGVuZ3RoKCk7Ci0KLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAvLyBodHRwOi8vYXBhY2hlLm9yZy94bWwvZmVhdHVyZXMvY29udGludWUtYWZ0ZXItZmF0YWwtZXJyb3IKLSAgICAgICAgICAgIC8vICAgQWxsb3dzIHRoZSBwYXJzZXIgdG8gY29udGludWUgYWZ0ZXIgYSBmYXRhbCBlcnJvci4KLSAgICAgICAgICAgIC8vICAgTm9ybWFsbHksIGEgZmF0YWwgZXJyb3Igd291bGQgc3RvcCB0aGUgcGFyc2UuCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgaWYgKHN1ZmZpeExlbmd0aCA9PSBDb25zdGFudHMuQ09OVElOVUVfQUZURVJfRkFUQUxfRVJST1JfRkVBVFVSRS5sZW5ndGgoKSAmJgotICAgICAgICAgICAgICAgIGZlYXR1cmVJZC5lbmRzV2l0aChDb25zdGFudHMuQ09OVElOVUVfQUZURVJfRkFUQUxfRVJST1JfRkVBVFVSRSkpIHsKLSAgICAgICAgICAgICAgICBmQ29udGludWVBZnRlckZhdGFsRXJyb3IgPSBzdGF0ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgfSAvLyBzZXRGZWF0dXJlKFN0cmluZyxib29sZWFuKQotCi0gICAgLy8gcmV0dXJuIHN0YXRlIG9mIGdpdmVuIGZlYXR1cmUgb3IgZmFsc2UgaWYgdW5zdXBwb3J0ZWQuCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0RmVhdHVyZShTdHJpbmcgZmVhdHVyZUlkKQotICAgICAgICB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gWGVyY2VzIGZlYXR1cmVzCi0gICAgICAgIC8vCi0KLSAgICAgICAgaWYgKGZlYXR1cmVJZC5zdGFydHNXaXRoKENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVgpKSB7Ci0gICAgICAgICAgICAgICAgZmluYWwgaW50IHN1ZmZpeExlbmd0aCA9IGZlYXR1cmVJZC5sZW5ndGgoKSAtIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVgubGVuZ3RoKCk7Ci0KLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAvLyBodHRwOi8vYXBhY2hlLm9yZy94bWwvZmVhdHVyZXMvY29udGludWUtYWZ0ZXItZmF0YWwtZXJyb3IKLSAgICAgICAgICAgIC8vICAgQWxsb3dzIHRoZSBwYXJzZXIgdG8gY29udGludWUgYWZ0ZXIgYSBmYXRhbCBlcnJvci4KLSAgICAgICAgICAgIC8vICAgTm9ybWFsbHksIGEgZmF0YWwgZXJyb3Igd291bGQgc3RvcCB0aGUgcGFyc2UuCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgaWYgKHN1ZmZpeExlbmd0aCA9PSBDb25zdGFudHMuQ09OVElOVUVfQUZURVJfRkFUQUxfRVJST1JfRkVBVFVSRS5sZW5ndGgoKSAmJgotICAgICAgICAgICAgICAgIGZlYXR1cmVJZC5lbmRzV2l0aChDb25zdGFudHMuQ09OVElOVUVfQUZURVJfRkFUQUxfRVJST1JfRkVBVFVSRSkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZkNvbnRpbnVlQWZ0ZXJGYXRhbEVycm9yIDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZmFsc2U7Ci0KLSAgICB9IC8vIHNldEZlYXR1cmUoU3RyaW5nLGJvb2xlYW4pCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGEgbGlzdCBvZiBwcm9wZXJ0eSBpZGVudGlmaWVycyB0aGF0IGFyZSByZWNvZ25pemVkIGJ5Ci0gICAgICogdGhpcyBjb21wb25lbnQuIFRoaXMgbWV0aG9kIG1heSByZXR1cm4gbnVsbCBpZiBubyBwcm9wZXJ0aWVzCi0gICAgICogYXJlIHJlY29nbml6ZWQgYnkgdGhpcyBjb21wb25lbnQuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZ1tdIGdldFJlY29nbml6ZWRQcm9wZXJ0aWVzKCkgewotICAgICAgICByZXR1cm4gKFN0cmluZ1tdKShSRUNPR05JWkVEX1BST1BFUlRJRVMuY2xvbmUoKSk7Ci0gICAgfSAvLyBnZXRSZWNvZ25pemVkUHJvcGVydGllcygpOlN0cmluZ1tdCi0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiBhIHByb3BlcnR5LiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgdGhlIGNvbXBvbmVudAotICAgICAqIG1hbmFnZXIgYW55IHRpbWUgYWZ0ZXIgcmVzZXQgd2hlbiBhIHByb3BlcnR5IGNoYW5nZXMgdmFsdWUuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBDb21wb25lbnRzIHNob3VsZCBzaWxlbnRseSBpZ25vcmUgcHJvcGVydGllcwotICAgICAqIHRoYXQgZG8gbm90IGFmZmVjdCB0aGUgb3BlcmF0aW9uIG9mIHRoZSBjb21wb25lbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcHJvcGVydHlJZCBUaGUgcHJvcGVydHkgaWRlbnRpZmllci4KLSAgICAgKiBAcGFyYW0gdmFsdWUgICAgICBUaGUgdmFsdWUgb2YgdGhlIHByb3BlcnR5LgotICAgICAqCi0gICAgICogQHRocm93cyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIFRoZSBjb21wb25lbnQgc2hvdWxkIG5vdCB0aHJvdwotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzIGV4Y2VwdGlvbi4KLSAgICAgKiBAdGhyb3dzIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBUaGUgY29tcG9uZW50IHNob3VsZCBub3QgdGhyb3cKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzIGV4Y2VwdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRQcm9wZXJ0eShTdHJpbmcgcHJvcGVydHlJZCwgT2JqZWN0IHZhbHVlKQotICAgICAgICB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gWGVyY2VzIHByb3BlcnRpZXMKLSAgICAgICAgLy8KLQotICAgICAgICBpZiAocHJvcGVydHlJZC5zdGFydHNXaXRoKENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYKSkgewotICAgICAgICAgICAgZmluYWwgaW50IHN1ZmZpeExlbmd0aCA9IHByb3BlcnR5SWQubGVuZ3RoKCkgLSBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWC5sZW5ndGgoKTsKLQotICAgICAgICAgICAgaWYgKHN1ZmZpeExlbmd0aCA9PSBDb25zdGFudHMuRVJST1JfSEFORExFUl9QUk9QRVJUWS5sZW5ndGgoKSAmJgotICAgICAgICAgICAgICAgIHByb3BlcnR5SWQuZW5kc1dpdGgoQ29uc3RhbnRzLkVSUk9SX0hBTkRMRVJfUFJPUEVSVFkpKSB7Ci0gICAgICAgICAgICAgICAgZkVycm9ySGFuZGxlciA9IChYTUxFcnJvckhhbmRsZXIpdmFsdWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgIH0gLy8gc2V0UHJvcGVydHkoU3RyaW5nLE9iamVjdCkKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIGRlZmF1bHQgc3RhdGUgZm9yIGEgZmVhdHVyZSwgb3IgbnVsbCBpZiB0aGlzCi0gICAgICogY29tcG9uZW50IGRvZXMgbm90IHdhbnQgdG8gcmVwb3J0IGEgZGVmYXVsdCB2YWx1ZSBmb3IgdGhpcwotICAgICAqIGZlYXR1cmUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZmVhdHVyZUlkIFRoZSBmZWF0dXJlIGlkZW50aWZpZXIuCi0gICAgICoKLSAgICAgKiBAc2luY2UgWGVyY2VzIDIuMi4wCi0gICAgICovCi0gICAgcHVibGljIEJvb2xlYW4gZ2V0RmVhdHVyZURlZmF1bHQoU3RyaW5nIGZlYXR1cmVJZCkgewotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IFJFQ09HTklaRURfRkVBVFVSRVMubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgIGlmIChSRUNPR05JWkVEX0ZFQVRVUkVTW2ldLmVxdWFscyhmZWF0dXJlSWQpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIEZFQVRVUkVfREVGQVVMVFNbaV07Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfSAvLyBnZXRGZWF0dXJlRGVmYXVsdChTdHJpbmcpOkJvb2xlYW4KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIGRlZmF1bHQgc3RhdGUgZm9yIGEgcHJvcGVydHksIG9yIG51bGwgaWYgdGhpcwotICAgICAqIGNvbXBvbmVudCBkb2VzIG5vdCB3YW50IHRvIHJlcG9ydCBhIGRlZmF1bHQgdmFsdWUgZm9yIHRoaXMKLSAgICAgKiBwcm9wZXJ0eS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBwcm9wZXJ0eUlkIFRoZSBwcm9wZXJ0eSBpZGVudGlmaWVyLgotICAgICAqCi0gICAgICogQHNpbmNlIFhlcmNlcyAyLjIuMAotICAgICAqLwotICAgIHB1YmxpYyBPYmplY3QgZ2V0UHJvcGVydHlEZWZhdWx0KFN0cmluZyBwcm9wZXJ0eUlkKSB7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgUkVDT0dOSVpFRF9QUk9QRVJUSUVTLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICBpZiAoUkVDT0dOSVpFRF9QUk9QRVJUSUVTW2ldLmVxdWFscyhwcm9wZXJ0eUlkKSkgewotICAgICAgICAgICAgICAgIHJldHVybiBQUk9QRVJUWV9ERUZBVUxUU1tpXTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9IC8vIGdldFByb3BlcnR5RGVmYXVsdChTdHJpbmcpOk9iamVjdAotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBpbnRlcm5hbCBYTUxFcnJyb3JIYW5kbGVyLgotICAgICAqLwotICAgIHB1YmxpYyBYTUxFcnJvckhhbmRsZXIgZ2V0RXJyb3JIYW5kbGVyKCkgewotICAgICAgICByZXR1cm4gZkVycm9ySGFuZGxlcjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXRzIHRoZSBpbnRlcm5hbCBYTUxFcnJvckhhbmRsZXIKLSAgICAgKiBhcyBTQVggRXJyb3JIYW5kbGVyLgotICAgICAqLwotICAgIHB1YmxpYyBFcnJvckhhbmRsZXIgZ2V0U0FYRXJyb3JIYW5kbGVyKCkgewotICAgICAgICBpZiAoZlNheFByb3h5ID09IG51bGwpIHsKLSAgICAgICAgICAgIGZTYXhQcm94eSA9IG5ldyBFcnJvckhhbmRsZXJQcm94eSgpIHsKLSAgICAgICAgICAgICAgICBwcm90ZWN0ZWQgWE1MRXJyb3JIYW5kbGVyIGdldEVycm9ySGFuZGxlcigpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZFcnJvckhhbmRsZXI7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZlNheFByb3h5OwotICAgIH0KLQotfSAvLyBjbGFzcyBYTUxFcnJvclJlcG9ydGVyCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL1hNTE5TRG9jdW1lbnRTY2FubmVySW1wbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9YTUxOU0RvY3VtZW50U2Nhbm5lckltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMjY0YjkwOC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL1hNTE5TRG9jdW1lbnRTY2FubmVySW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNjQ4ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDMsIDIwMTYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKi8KLQotLyoKLSAqIENvcHlyaWdodCAyMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGw7Ci0KLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTFN0cmluZzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHRkLlhNTERURFZhbGlkYXRvckZpbHRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwubXNnLlhNTE1lc3NhZ2VGb3JtYXR0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlhNTEF0dHJpYnV0ZXNJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5YTUxTeW1ib2xzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLk5hbWVzcGFjZUNvbnRleHQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuUU5hbWU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE5JRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxDb21wb25lbnRNYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTERvY3VtZW50SGFuZGxlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MRG9jdW1lbnRTb3VyY2U7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlscy5YTUxTZWN1cml0eU1hbmFnZXI7Ci0KLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLmV2ZW50cy5YTUxFdmVudDsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGFkZHMgdGhlIGZ1bmN0aW9uYWxpdHkgb2YgbmFtZXNwYWNlIHByb2Nlc3NpbmcuCi0gKgotICogVGhpcyBjbGFzcyBoYXMgYmVlbiBtb2RpZmllZCBhcyBwZXIgdGhlIG5ldyBkZXNpZ24gd2hpY2ggaXMgbW9yZSBzdWl0ZWQgdG8KLSAqIGVmZmljaWVudGx5IGJ1aWxkIHB1bGwgcGFyc2VyLiBMb3Qgb2YgaW1wcm92ZW1lbnRzIGhhdmUgYmVlbiBkb25lIGFuZAotICogdGhlIGNvZGUgaGFzIGJlZW4gYWRkZWQgdG8gc3VwcG9ydCBzdGF4IGZ1bmN0aW9uYWxpdHkvZmVhdHVyZXMuCi0gKgotICoKLSAqIFRoaXMgY2xhc3Mgc2NhbnMgYW4gWE1MIGRvY3VtZW50LCBjaGVja3MgaWYgZG9jdW1lbnQgaGFzIGEgRFRELCBhbmQgaWYKLSAqIERURCBpcyBub3QgZm91bmQgdGhlIHNjYW5uZXIgd2lsbCByZW1vdmUgdGhlIERURCBWYWxpZGF0b3IgZnJvbSB0aGUgcGlwZWxpbmUgYW5kIHBlcmZvcm0KLSAqIG5hbWVzcGFjZSBiaW5kaW5nLgotICoKLSAqCi0gKiBAYXV0aG9yIE5lZXJhaiBCYWphaiwgU3VuIE1pY3Jvc3lzdGVtcwotICogQGF1dGhvciBWZW51Z29wYWwgUmFvIEssIFN1biBNaWNyb3N5c3RlbXMKLSAqIEBhdXRob3IgRWxlbmEgTGl0YW5pLCBJQk0KLSAqIEB2ZXJzaW9uICRJZDogWE1MTlNEb2N1bWVudFNjYW5uZXJJbXBsLmphdmEsdiAxLjExIDIwMTAtMTEtMDEgMDQ6Mzk6NDEgam9laHcgRXhwICQKLSAqLwotcHVibGljIGNsYXNzIFhNTE5TRG9jdW1lbnRTY2FubmVySW1wbAotICAgICAgICBleHRlbmRzIFhNTERvY3VtZW50U2Nhbm5lckltcGwgewotCi0gICAgLyoqCi0gICAgICogSWYgaXMgdHJ1ZSwgdGhlIGR0ZCB2YWxpZGF0b3IgaXMgbm8gbG9uZ2VyIGluIHRoZSBwaXBlbGluZQotICAgICAqIGFuZCB0aGUgc2Nhbm5lciBzaG91bGQgYmluZCBuYW1lc3BhY2VzCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZkJpbmROYW1lc3BhY2VzOwotCi0gICAgLyoqIElmIHZhbGlkYXRpbmcgcGFyc2VyLCBtYWtlIHN1cmUgd2UgcmVwb3J0IGFuIGVycm9yIGluIHRoZQotICAgICAqICAgc2Nhbm5lciBpZiBEVEQgZ3JhbW1hciBpcyBtaXNzaW5nLiovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZlBlcmZvcm1WYWxpZGF0aW9uOwotCi0KLSAgICAvKiogRGVmYXVsdCB2YWx1ZSBvZiB0aGlzIGZlYXR1cmUgaXMgZmFsc2UsIHdoZW4gaW4gU3RheCBtb2RlIHRoaXMgc2hvdWxkIGJlIHRydWUgKi8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBmTm90QWRkTlNEZWNsQXNBdHRyaWJ1dGUgPSBmYWxzZTsKLQotICAgIC8qKiBEVEQgdmFsaWRhdG9yICovCi0gICAgIHByaXZhdGUgWE1MRFREVmFsaWRhdG9yRmlsdGVyIGZEVERWYWxpZGF0b3I7Ci0KLSAgICAgLyoqIHhtbG5zLCBkZWZhdWx0IE5hbWVzcGFjZSwgZGVjbGFyZWQgKi8KLSAgICAgcHJpdmF0ZSBib29sZWFuIGZYbWxuc0RlY2xhcmVkID0gZmFsc2U7Ci0KLSAgICAvKiogUmVzZXRzIHRoZSBmaWVsZHMgb2YgdGhpcyBzY2FubmVyLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHJlc2V0KFByb3BlcnR5TWFuYWdlciBwcm9wZXJ0eU1hbmFnZXIpIHsKLSAgICAgICAgc2V0UHJvcGVydHlNYW5hZ2VyKHByb3BlcnR5TWFuYWdlcik7Ci0gICAgICAgIHN1cGVyLnJlc2V0KHByb3BlcnR5TWFuYWdlcik7Ci0gICAgICAgIGZCaW5kTmFtZXNwYWNlcyA9IGZhbHNlOwotICAgICAgICBmTm90QWRkTlNEZWNsQXNBdHRyaWJ1dGUgPSAhKChCb29sZWFuKXByb3BlcnR5TWFuYWdlci5nZXRQcm9wZXJ0eShDb25zdGFudHMuQUREX05BTUVTUEFDRV9ERUNMX0FTX0FUVFJJQlVURSkpLmJvb2xlYW5WYWx1ZSgpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHJlc2V0KFhNTENvbXBvbmVudE1hbmFnZXIgY29tcG9uZW50TWFuYWdlcikKLSAgICB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiB7Ci0gICAgICAgIHN1cGVyLnJlc2V0KGNvbXBvbmVudE1hbmFnZXIpOwotICAgICAgICBmTm90QWRkTlNEZWNsQXNBdHRyaWJ1dGUgPSBmYWxzZSA7Ci0gICAgICAgIGZQZXJmb3JtVmFsaWRhdGlvbiA9IGZhbHNlOwotICAgICAgICBmQmluZE5hbWVzcGFjZXMgPSBmYWxzZTsKLSAgICB9Ci0KLSAgICAvKiogcmV0dXJuIHRoZSBuZXh0IHN0YXRlIG9uIHRoZSBpbnB1dAotICAgICAqCi0gICAgICogQHJldHVybiBpbnQKLSAgICAgKi8KLQotICAgIHB1YmxpYyBpbnQgbmV4dCgpIHRocm93cyBJT0V4Y2VwdGlvbiwgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgLy9zaW5jZSBuYW1lc3BhY2UgY29udGV4dCBzaG91bGQgc3RpbGwgYmUgdmFsaWQgd2hlbiB0aGUgcGFyc2VyIGlzIGF0IHRoZSBlbmQgZWxlbWVudCBzdGF0ZSB0aGVyZWZvcmUKLSAgICAgICAgLy93ZSBwb3AgdGhlIGNvbnRleHQgb25seSB3aGVuIG5leHQoKSBoYXMgYmVlbiBjYWxsZWQgYWZ0ZXIgdGhlIGVuZCBlbGVtZW50IHN0YXRlIHdhcyBlbmNvdW50ZXJlZC4gLSBuYi4KLQotICAgICAgICBpZigoZlNjYW5uZXJMYXN0U3RhdGUgPT0gWE1MRXZlbnQuRU5EX0VMRU1FTlQpICYmIGZCaW5kTmFtZXNwYWNlcyl7Ci0gICAgICAgICAgICBmU2Nhbm5lckxhc3RTdGF0ZSA9IC0xOwotICAgICAgICAgICAgZk5hbWVzcGFjZUNvbnRleHQucG9wQ29udGV4dCgpOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIGZTY2FubmVyTGFzdFN0YXRlID0gc3VwZXIubmV4dCgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoZSBzY2FubmVyIGlzIHJlc3BvbnNpYmxlIGZvciByZW1vdmluZyBEVEQgdmFsaWRhdG9yCi0gICAgICogZnJvbSB0aGUgcGlwZWxpbmUgaWYgaXQgaXMgbm90IG5lZWRlZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBwcmV2aW91cyBUaGUgZmlsdGVyIGNvbXBvbmVudCBiZWZvcmUgRFREVmFsaWRhdG9yCi0gICAgICogQHBhcmFtIGR0ZFZhbGlkYXRvcgotICAgICAqICAgICAgICAgICAgICAgICBUaGUgRFREVmFsaWRhdG9yCi0gICAgICogQHBhcmFtIG5leHQgICAgIFRoZSBkb2N1bWVudEhhbmRsZXIgYWZ0ZXIgdGhlIERURFZhbGlkYXRvcgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldERURFZhbGlkYXRvcihYTUxEVERWYWxpZGF0b3JGaWx0ZXIgZHRkKXsKLSAgICAgICAgZkRURFZhbGlkYXRvciA9IGR0ZDsKLSAgICB9Ci0KLQotCi0gICAgLyoqCi0gICAgICogU2NhbnMgYSBzdGFydCBlbGVtZW50LiBUaGlzIG1ldGhvZCB3aWxsIGhhbmRsZSB0aGUgYmluZGluZyBvZgotICAgICAqIG5hbWVzcGFjZSBpbmZvcm1hdGlvbiBhbmQgbm90aWZ5aW5nIHRoZSBoYW5kbGVyIG9mIHRoZSBzdGFydAotICAgICAqIG9mIHRoZSBlbGVtZW50LgotICAgICAqIDxwPgotICAgICAqIDxwcmU+Ci0gICAgICogWzQ0XSBFbXB0eUVsZW1UYWcgOjo9ICcmbHQ7JyBOYW1lIChTIEF0dHJpYnV0ZSkqIFM/ICcvPicKLSAgICAgKiBbNDBdIFNUYWcgOjo9ICcmbHQ7JyBOYW1lIChTIEF0dHJpYnV0ZSkqIFM/ICc+JwotICAgICAqIDwvcHJlPgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gVGhpcyBtZXRob2QgYXNzdW1lcyB0aGF0IHRoZSBsZWFkaW5nCi0gICAgICogJyZsdDsnIGNoYXJhY3RlciBoYXMgYmVlbiBjb25zdW1lZC4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoaXMgbWV0aG9kIHVzZXMgdGhlIGZFbGVtZW50UU5hbWUgYW5kCi0gICAgICogZkF0dHJpYnV0ZXMgdmFyaWFibGVzLiBUaGUgY29udGVudHMgb2YgdGhlc2UgdmFyaWFibGVzIHdpbGwgYmUKLSAgICAgKiBkZXN0cm95ZWQuIFRoZSBjYWxsZXIgc2hvdWxkIGNvcHkgaW1wb3J0YW50IGluZm9ybWF0aW9uIG91dCBvZgotICAgICAqIHRoZXNlIHZhcmlhYmxlcyBiZWZvcmUgY2FsbGluZyB0aGlzIG1ldGhvZC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVHJ1ZSBpZiBlbGVtZW50IGlzIGVtcHR5LiAoaS5lLiBJdCBtYXRjaGVzCi0gICAgICogICAgICAgICAgcHJvZHVjdGlvbiBbNDRdLgotICAgICAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIHNjYW5TdGFydEVsZW1lbnQoKQotICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgWE5JRXhjZXB0aW9uIHsKLQotICAgICAgICBpZiAoREVCVUdfU1RBUlRfRU5EX0VMRU1FTlQpIFN5c3RlbS5vdXQucHJpbnRsbih0aGlzLmdldENsYXNzKCkudG9TdHJpbmcoKSArIj4+PiBzY2FuU3RhcnRFbGVtZW50KCkiKTsKLSAgICAgICAgLy93aGVuIHNraXBwaW5nIGlzIHRydWUgYW5kIG5vIG1vcmUgZWxlbWVudHMgc2hvdWxkIGJlIGFkZGVkCi0gICAgICAgIGlmKGZTa2lwICYmICFmQWRkKXsKLSAgICAgICAgICAgIC8vZ2V0IHRoZSBzdG9yZWQgZWxlbWVudCAtLSBpZiBldmVyeXRoaW5nIGdvZXMgcmlnaHQgdGhpcyBzaG91bGQgbWF0Y2ggdGhlCi0gICAgICAgICAgICAvL3Rva2VuIGluIHRoZSBidWZmZXIKLQotICAgICAgICAgICAgUU5hbWUgbmFtZSA9IGZFbGVtZW50U3RhY2suZ2V0TmV4dCgpOwotCi0gICAgICAgICAgICBpZihERUJVR19TS0lQX0FMR09SSVRITSl7Ci0gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJUcnlpbmcgdG8gc2tpcCBTdHJpbmcgPSAiICsgbmFtZS5yYXduYW1lKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy9CZSBjb25zZXJ2YXRpdmUgLS0gaWYgc2tpcHBpbmcgZmFpbHMgLS0gc3RvcC4KLSAgICAgICAgICAgIGZTa2lwID0gZkVudGl0eVNjYW5uZXIuc2tpcFN0cmluZyhuYW1lLnJhd25hbWUpOyAvLyBza2lwUUVsZW1lbnQobmFtZSk7Ci0KLSAgICAgICAgICAgIGlmKGZTa2lwKXsKLSAgICAgICAgICAgICAgICBpZihERUJVR19TS0lQX0FMR09SSVRITSl7Ci0gICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiRWxlbWVudCBTVUNFU1NGVUxMWSBza2lwcGVkID0gIiArIG5hbWUucmF3bmFtZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGZFbGVtZW50U3RhY2sucHVzaCgpOwotICAgICAgICAgICAgICAgIGZFbGVtZW50UU5hbWUgPSBuYW1lOwotICAgICAgICAgICAgfWVsc2V7Ci0gICAgICAgICAgICAgICAgLy9pZiBza2lwcGluZyBmYWlscyByZXBvc2l0aW9uIHRoZSBzdGFjayBvciBmYWxsYmFjayB0byBub3JtYWwgd2F5IG9mIHByb2Nlc3NpbmcKLSAgICAgICAgICAgICAgICBmRWxlbWVudFN0YWNrLnJlcG9zaXRpb24oKTsKLSAgICAgICAgICAgICAgICBpZihERUJVR19TS0lQX0FMR09SSVRITSl7Ci0gICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiRWxlbWVudCB3YXMgTk9UIHNraXBwZWQsIFJFUE9TSVRJT05JTkcgc3RhY2siICk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy93ZSBhcmUgc3RpbGwgYXQgdGhlIHN0YWdlIG9mIGFkZGluZyBlbGVtZW50cwotICAgICAgICAvL3RoZSBlbGVtZW50cyB3ZXJlIG5vdCBtYXRjaGVkIG9yCi0gICAgICAgIC8vZlNraXAgaXMgbm90IHNldCB0byB0cnVlCi0gICAgICAgIGlmKCFmU2tpcCB8fCBmQWRkKXsKLSAgICAgICAgICAgIC8vZ2V0IHRoZSBuZXh0IGVsZW1lbnQgZnJvbSB0aGUgc3RhY2sKLSAgICAgICAgICAgIGZFbGVtZW50UU5hbWUgPSBmRWxlbWVudFN0YWNrLm5leHRFbGVtZW50KCk7Ci0gICAgICAgICAgICAvLyBUaGVyZSBhcmUgdHdvIHZhcmlhYmxlcyxmTmFtZXNwYWNlcyBhbmQgZkJpbmROYW1lc3BhY2VzCi0gICAgICAgICAgICAvL1N0QVggdXNlcyBYTUxOU0RvY3VtZW50U2Nhbm5lckltcGwgc28gdGhpcyBkaXN0aW5jdGlvbiBuZWVkcyB0byBiZSBtYWludGFpbmVkCi0gICAgICAgICAgICBpZiAoZk5hbWVzcGFjZXMpIHsKLSAgICAgICAgICAgICAgICBmRW50aXR5U2Nhbm5lci5zY2FuUU5hbWUoZkVsZW1lbnRRTmFtZSwgTmFtZVR5cGUuRUxFTUVOVFNUQVJUKTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIG5hbWUgPSBmRW50aXR5U2Nhbm5lci5zY2FuTmFtZShOYW1lVHlwZS5FTEVNRU5UU1RBUlQpOwotICAgICAgICAgICAgICAgIGZFbGVtZW50UU5hbWUuc2V0VmFsdWVzKG51bGwsIG5hbWUsIG5hbWUsIG51bGwpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZihERUJVRylTeXN0ZW0ub3V0LnByaW50bG4oIkVsZW1lbnQgc2Nhbm5lZCBpbiBzdGFydCBlbGVtZW50IGlzICIgKyBmRWxlbWVudFFOYW1lLnRvU3RyaW5nKCkpOwotICAgICAgICAgICAgaWYoREVCVUdfU0tJUF9BTEdPUklUSE0pewotICAgICAgICAgICAgICAgIGlmKGZBZGQpewotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkVsZW1lbnRzIGFyZSBiZWluZyBBRERFRCAtLSBlbGVtZXQgYWRkZWQgaXMgPSAiICsgZkVsZW1lbnRRTmFtZS5yYXduYW1lICsgIiBhdCBjb3VudCA9ICIgKyBmRWxlbWVudFN0YWNrLmZDb3VudCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgIH0KLQotICAgICAgICAvL3doZW4gdGhlIGVsZW1lbnRzIGFyZSBiZWluZyBhZGRlZCAsIHdlIG5lZWQgdG8gY2hlY2sgaWYgd2UgYXJlIHNldCBmb3Igc2tpcHBpbmcgdGhlIGVsZW1lbnRzCi0gICAgICAgIGlmKGZBZGQpewotICAgICAgICAgICAgLy90aGlzIHNldHMgdGhlIHZhbHVlIG9mIGZBZGQgdmFyaWFibGUKLSAgICAgICAgICAgIGZFbGVtZW50U3RhY2subWF0Y2hFbGVtZW50KGZFbGVtZW50UU5hbWUpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy94eHg6IFdlIGRvbnQgbmVlZCBhbm90aGVyIHBvaW50ZXIsIGZDdXJyZW50RWxlbWVudCwgd2UgY2FuIHVzZSBmRWxlbWVudFFOYW1lCi0gICAgICAgIGZDdXJyZW50RWxlbWVudCA9IGZFbGVtZW50UU5hbWU7Ci0KLSAgICAgICAgU3RyaW5nIHJhd25hbWUgPSBmRWxlbWVudFFOYW1lLnJhd25hbWU7Ci0gICAgICAgIGNoZWNrRGVwdGgocmF3bmFtZSk7Ci0gICAgICAgIGlmIChmQmluZE5hbWVzcGFjZXMpIHsKLSAgICAgICAgICAgIGZOYW1lc3BhY2VDb250ZXh0LnB1c2hDb250ZXh0KCk7Ci0gICAgICAgICAgICBpZiAoZlNjYW5uZXJTdGF0ZSA9PSBTQ0FOTkVSX1NUQVRFX1JPT1RfRUxFTUVOVCkgewotICAgICAgICAgICAgICAgIGlmIChmUGVyZm9ybVZhbGlkYXRpb24pIHsKLSAgICAgICAgICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNU0dfR1JBTU1BUl9OT1RfRk9VTkQiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXsgcmF3bmFtZX0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9FUlJPUik7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZkRvY3R5cGVOYW1lID09IG51bGwgfHwgIWZEb2N0eXBlTmFtZS5lcXVhbHMocmF3bmFtZSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IoIFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUm9vdEVsZW1lbnRUeXBlTXVzdE1hdGNoRG9jdHlwZWRlY2wiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXtmRG9jdHlwZU5hbWUsIHJhd25hbWV9LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTEVycm9yUmVwb3J0ZXIuU0VWRVJJVFlfRVJST1IpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotCi0gICAgICAgIGZFbXB0eUVsZW1lbnQgPSBmYWxzZTsKLSAgICAgICAgZkF0dHJpYnV0ZXMucmVtb3ZlQWxsQXR0cmlidXRlcygpOwotCi0gICAgICAgIGlmKCFzZWVrQ2xvc2VPZlN0YXJ0VGFnKCkpewotICAgICAgICAgICAgZlJlYWRpbmdBdHRyaWJ1dGVzID0gdHJ1ZTsKLSAgICAgICAgICAgIGZBdHRyaWJ1dGVDYWNoZVVzZWRDb3VudCA9MDsKLSAgICAgICAgICAgIGZTdHJpbmdCdWZmZXJJbmRleCA9MDsKLSAgICAgICAgICAgIGZBZGREZWZhdWx0QXR0ciA9IHRydWU7Ci0gICAgICAgICAgICBmWG1sbnNEZWNsYXJlZCA9IGZhbHNlOwotCi0gICAgICAgICAgICBkbyB7Ci0gICAgICAgICAgICAgICAgc2NhbkF0dHJpYnV0ZShmQXR0cmlidXRlcyk7Ci0gICAgICAgICAgICAgICAgaWYgKGZTZWN1cml0eU1hbmFnZXIgIT0gbnVsbCAmJiAoIWZTZWN1cml0eU1hbmFnZXIuaXNOb0xpbWl0KGZFbGVtZW50QXR0cmlidXRlTGltaXQpKSAmJgotICAgICAgICAgICAgICAgICAgICAgICAgZkF0dHJpYnV0ZXMuZ2V0TGVuZ3RoKCkgPiBmRWxlbWVudEF0dHJpYnV0ZUxpbWl0KXsKLSAgICAgICAgICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJFbGVtZW50QXR0cmlidXRlTGltaXQiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXtyYXduYW1lLCBmRWxlbWVudEF0dHJpYnV0ZUxpbWl0IH0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9GQVRBTF9FUlJPUiApOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgfSB3aGlsZSAoIXNlZWtDbG9zZU9mU3RhcnRUYWcoKSk7Ci0gICAgICAgICAgICBmUmVhZGluZ0F0dHJpYnV0ZXM9ZmFsc2U7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoZkJpbmROYW1lc3BhY2VzKSB7Ci0gICAgICAgICAgICAvLyBSRVZJU0lUOiBpcyBpdCByZXF1aXJlZD8gZm9yYml0IHhtbG5zIHByZWZpeCBmb3IgZWxlbWVudAotICAgICAgICAgICAgaWYgKGZFbGVtZW50UU5hbWUucHJlZml4ID09IFhNTFN5bWJvbHMuUFJFRklYX1hNTE5TKSB7Ci0gICAgICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxOU19ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAiRWxlbWVudFhNTE5TUHJlZml4IiwKLSAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXtmRWxlbWVudFFOYW1lLnJhd25hbWV9LAotICAgICAgICAgICAgICAgICAgICAgICAgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9GQVRBTF9FUlJPUik7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIGJpbmQgdGhlIGVsZW1lbnQKLSAgICAgICAgICAgIFN0cmluZyBwcmVmaXggPSBmRWxlbWVudFFOYW1lLnByZWZpeCAhPSBudWxsCi0gICAgICAgICAgICAgICAgICAgID8gZkVsZW1lbnRRTmFtZS5wcmVmaXggOiBYTUxTeW1ib2xzLkVNUFRZX1NUUklORzsKLSAgICAgICAgICAgIC8vIGFzc2lnbiB1cmkgdG8gdGhlIGVsZW1lbnQKLSAgICAgICAgICAgIGZFbGVtZW50UU5hbWUudXJpID0gZk5hbWVzcGFjZUNvbnRleHQuZ2V0VVJJKHByZWZpeCk7Ci0gICAgICAgICAgICAvLyBtYWtlIHN1cmUgdGhhdCBvYmplY3QgaW4gdGhlIGVsZW1lbnQgc3RhY2sgaXMgdXBkYXRlZCBhcyB3ZWxsCi0gICAgICAgICAgICBmQ3VycmVudEVsZW1lbnQudXJpID0gZkVsZW1lbnRRTmFtZS51cmk7Ci0KLSAgICAgICAgICAgIGlmIChmRWxlbWVudFFOYW1lLnByZWZpeCA9PSBudWxsICYmIGZFbGVtZW50UU5hbWUudXJpICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmRWxlbWVudFFOYW1lLnByZWZpeCA9IFhNTFN5bWJvbHMuRU1QVFlfU1RSSU5HOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKGZFbGVtZW50UU5hbWUucHJlZml4ICE9IG51bGwgJiYgZkVsZW1lbnRRTmFtZS51cmkgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MTlNfRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgIkVsZW1lbnRQcmVmaXhVbmJvdW5kIiwKLSAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXtmRWxlbWVudFFOYW1lLnByZWZpeCwgZkVsZW1lbnRRTmFtZS5yYXduYW1lfSwKLSAgICAgICAgICAgICAgICAgICAgICAgIFhNTEVycm9yUmVwb3J0ZXIuU0VWRVJJVFlfRkFUQUxfRVJST1IpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBiaW5kIGF0dHJpYnV0ZXMgKHhtbG5zIGFyZSBhbHJlYWR5IGJvdW5kIGJlbGxvdykKLSAgICAgICAgICAgIGludCBsZW5ndGggPSBmQXR0cmlidXRlcy5nZXRMZW5ndGgoKTsKLSAgICAgICAgICAgIC8vIGZMZW5ndGggPSAwOyAvL2luaXRpYWxpemUgc3RydWN0dXJlCi0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgZkF0dHJpYnV0ZXMuZ2V0TmFtZShpLCBmQXR0cmlidXRlUU5hbWUpOwotCi0gICAgICAgICAgICAgICAgU3RyaW5nIGFwcmVmaXggPSBmQXR0cmlidXRlUU5hbWUucHJlZml4ICE9IG51bGwKLSAgICAgICAgICAgICAgICAgICAgICAgID8gZkF0dHJpYnV0ZVFOYW1lLnByZWZpeCA6IFhNTFN5bWJvbHMuRU1QVFlfU1RSSU5HOwotICAgICAgICAgICAgICAgIFN0cmluZyB1cmkgPSBmTmFtZXNwYWNlQ29udGV4dC5nZXRVUkkoYXByZWZpeCk7Ci0gICAgICAgICAgICAgICAgLy8gUkVWSVNJVDogdHJ5IHJlbW92aW5nIHRoZSBmaXJzdCAiaWYiIGFuZCBzZWUgaWYgaXQgaXMgZmFzdGVyLgotICAgICAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAgICAgaWYgKGZBdHRyaWJ1dGVRTmFtZS51cmkgIT0gbnVsbCAmJiBmQXR0cmlidXRlUU5hbWUudXJpID09IHVyaSkgewotICAgICAgICAgICAgICAgICAgICAvLyBjaGVja0R1cGxpY2F0ZXMoZkF0dHJpYnV0ZVFOYW1lLCBmQXR0cmlidXRlcyk7Ci0gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpZiAoYXByZWZpeCAhPSBYTUxTeW1ib2xzLkVNUFRZX1NUUklORykgewotICAgICAgICAgICAgICAgICAgICBmQXR0cmlidXRlUU5hbWUudXJpID0gdXJpOwotICAgICAgICAgICAgICAgICAgICBpZiAodXJpID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MTlNfRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQXR0cmlidXRlUHJlZml4VW5ib3VuZCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXtmRWxlbWVudFFOYW1lLnJhd25hbWUsZkF0dHJpYnV0ZVFOYW1lLnJhd25hbWUsYXByZWZpeH0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTEVycm9yUmVwb3J0ZXIuU0VWRVJJVFlfRkFUQUxfRVJST1IpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGZBdHRyaWJ1dGVzLnNldFVSSShpLCB1cmkpOwotICAgICAgICAgICAgICAgICAgICAvLyBjaGVja0R1cGxpY2F0ZXMoZkF0dHJpYnV0ZVFOYW1lLCBmQXR0cmlidXRlcyk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAobGVuZ3RoID4gMSkgewotICAgICAgICAgICAgICAgIFFOYW1lIG5hbWUgPSBmQXR0cmlidXRlcy5jaGVja0R1cGxpY2F0ZXNOUygpOwotICAgICAgICAgICAgICAgIGlmIChuYW1lICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKG5hbWUudXJpICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MTlNfRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQXR0cmlidXRlTlNOb3RVbmlxdWUiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117ZkVsZW1lbnRRTmFtZS5yYXduYW1lLCBuYW1lLmxvY2FscGFydCwgbmFtZS51cml9LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxFcnJvclJlcG9ydGVyLlNFVkVSSVRZX0ZBVEFMX0VSUk9SKTsKLSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MTlNfRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQXR0cmlidXRlTm90VW5pcXVlIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde2ZFbGVtZW50UU5hbWUucmF3bmFtZSwgbmFtZS5yYXduYW1lfSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9GQVRBTF9FUlJPUik7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotCi0gICAgICAgIGlmIChmRW1wdHlFbGVtZW50KSB7Ci0gICAgICAgICAgICAvL2RlY3JlYXNlIHRoZSBtYXJrdXAgZGVwdGguLgotICAgICAgICAgICAgZk1hcmt1cERlcHRoLS07Ci0KLSAgICAgICAgICAgIC8vIGNoZWNrIHRoYXQgdGhpcyBlbGVtZW50IHdhcyBvcGVuZWQgaW4gdGhlIHNhbWUgZW50aXR5Ci0gICAgICAgICAgICBpZiAoZk1hcmt1cERlcHRoIDwgZkVudGl0eVN0YWNrW2ZFbnRpdHlEZXB0aCAtIDFdKSB7Ci0gICAgICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiRWxlbWVudEVudGl0eU1pc21hdGNoIiwKLSAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXtmQ3VycmVudEVsZW1lbnQucmF3bmFtZX0pOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gY2FsbCBoYW5kbGVyCi0gICAgICAgICAgICBpZiAoZkRvY3VtZW50SGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgaWYoREVCVUcpCi0gICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiZW1wdHlFbGVtZW50ID0gIiArIGZFbGVtZW50UU5hbWUpOwotCi0gICAgICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci5lbXB0eUVsZW1lbnQoZkVsZW1lbnRRTmFtZSwgZkF0dHJpYnV0ZXMsIG51bGwpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvL1dlIHNob3VsZCBub3QgYmUgcG9wcGluZyBvdXQgdGhlIGNvbnRleHQgaGVyZSBpbiBlbmRFTGVtZW50IGJlY2FhdXNlIHRoZSBuYW1lc3BhY2UgY29udGV4dCBpcyBzdGlsbAotICAgICAgICAgICAgLy92YWxpZCB3aGVuIHBhcnNlciBpcyBhdCB0aGUgZW5kRWxlbWVudCBzdGF0ZS4KLSAgICAgICAgICAgIGZTY2FuRW5kRWxlbWVudCA9IHRydWU7Ci0gICAgICAgICAgICAvL2lmIChmQmluZE5hbWVzcGFjZXMpIHsKLSAgICAgICAgICAgIC8vICBmTmFtZXNwYWNlQ29udGV4dC5wb3BDb250ZXh0KCk7Ci0gICAgICAgICAgICAvL30KLQotICAgICAgICAgICAgLy9wb3AgdGhlIGVsZW1lbnQgb2ZmIHRoZSBzdGFjay4uCi0gICAgICAgICAgICBmRWxlbWVudFN0YWNrLnBvcEVsZW1lbnQoKTsKLQotICAgICAgICB9IGVsc2UgewotCi0gICAgICAgICAgICBpZihkdGRHcmFtbWFyVXRpbCAhPSBudWxsKQotICAgICAgICAgICAgICAgIGR0ZEdyYW1tYXJVdGlsLnN0YXJ0RWxlbWVudChmRWxlbWVudFFOYW1lLGZBdHRyaWJ1dGVzKTsKLSAgICAgICAgICAgIGlmKGZEb2N1bWVudEhhbmRsZXIgIT0gbnVsbCl7Ci0gICAgICAgICAgICAgICAgLy9jb21wbGV0ZSBlbGVtZW50IGFuZCBhdHRyaWJ1dGVzIGFyZSB0cmF2ZXJzZWQgaW4gdGhpcyBmdW5jdGlvbiBzbyB3ZSBjYW4gc2VuZCBhIGNhbGxiYWNrCi0gICAgICAgICAgICAgICAgLy9oZXJlLgotICAgICAgICAgICAgICAgIC8vPHN0cm9uZz53ZSBzaG91bGRuJ3QgYmUgc2VuZGluZyBjYWxsYmFjayBpbiBzY2FuRG9jdW1lbnQoKTwvc3Ryb25nPgotICAgICAgICAgICAgICAgIGlmKERFQlVHKQotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oInN0YXJ0RWxlbWVudCA9ICIgKyBmRWxlbWVudFFOYW1lKTsKLSAgICAgICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLnN0YXJ0RWxlbWVudChmRWxlbWVudFFOYW1lLCBmQXR0cmlidXRlcywgbnVsbCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotCi0gICAgICAgIGlmIChERUJVR19TVEFSVF9FTkRfRUxFTUVOVCkgU3lzdGVtLm91dC5wcmludGxuKHRoaXMuZ2V0Q2xhc3MoKS50b1N0cmluZygpICsiPDw8IHNjYW5TdGFydEVsZW1lbnQoKTogIitmRW1wdHlFbGVtZW50KTsKLSAgICAgICAgcmV0dXJuIGZFbXB0eUVsZW1lbnQ7Ci0KLSAgICB9IC8vIHNjYW5TdGFydEVsZW1lbnQoKTpib29sZWFuCi0KLQotCi0gICAgLyoqCi0gICAgICogU2NhbnMgYW4gYXR0cmlidXRlLgotICAgICAqIDxwPgotICAgICAqIDxwcmU+Ci0gICAgICogWzQxXSBBdHRyaWJ1dGUgOjo9IE5hbWUgRXEgQXR0VmFsdWUKLSAgICAgKiA8L3ByZT4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoaXMgbWV0aG9kIGFzc3VtZXMgdGhhdCB0aGUgbmV4dAotICAgICAqIGNoYXJhY3RlciBvbiB0aGUgc3RyZWFtIGlzIHRoZSBmaXJzdCBjaGFyYWN0ZXIgb2YgdGhlIGF0dHJpYnV0ZQotICAgICAqIG5hbWUuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGlzIG1ldGhvZCB1c2VzIHRoZSBmQXR0cmlidXRlUU5hbWUgYW5kCi0gICAgICogZlFOYW1lIHZhcmlhYmxlcy4gVGhlIGNvbnRlbnRzIG9mIHRoZXNlIHZhcmlhYmxlcyB3aWxsIGJlCi0gICAgICogZGVzdHJveWVkLgotICAgICAqCi0gICAgICogQHBhcmFtIGF0dHJpYnV0ZXMgVGhlIGF0dHJpYnV0ZXMgbGlzdCBmb3IgdGhlIHNjYW5uZWQgYXR0cmlidXRlLgotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIHNjYW5BdHRyaWJ1dGUoWE1MQXR0cmlidXRlc0ltcGwgYXR0cmlidXRlcykKLSAgICB0aHJvd3MgSU9FeGNlcHRpb24sIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChERUJVR19TVEFSVF9FTkRfRUxFTUVOVCkgU3lzdGVtLm91dC5wcmludGxuKHRoaXMuZ2V0Q2xhc3MoKS50b1N0cmluZygpICsiPj4+IHNjYW5BdHRyaWJ1dGUoKSIpOwotCi0gICAgICAgIC8vIG5hbWUKLSAgICAgICAgZkVudGl0eVNjYW5uZXIuc2NhblFOYW1lKGZBdHRyaWJ1dGVRTmFtZSwgTmFtZVR5cGUuQVRUUklCVVRFKTsKLQotICAgICAgICAvLyBlcXVhbHMKLSAgICAgICAgZkVudGl0eVNjYW5uZXIuc2tpcFNwYWNlcygpOwotICAgICAgICBpZiAoIWZFbnRpdHlTY2FubmVyLnNraXBDaGFyKCc9JywgTmFtZVR5cGUuQVRUUklCVVRFKSkgewotICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiRXFSZXF1aXJlZEluQXR0cmlidXRlIiwKLSAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde2ZDdXJyZW50RWxlbWVudC5yYXduYW1lLGZBdHRyaWJ1dGVRTmFtZS5yYXduYW1lfSk7Ci0gICAgICAgIH0KLSAgICAgICAgZkVudGl0eVNjYW5uZXIuc2tpcFNwYWNlcygpOwotCi0gICAgICAgIC8vIGNvbnRlbnQKLSAgICAgICAgaW50IGF0dHJJbmRleCA9IDAgOwotCi0KLSAgICAgICAgLy9SRVZJU0lUOiBvbmUgbW9yZSBjYXNlIG5lZWRzIHRvIGJlIGluY2x1ZGVkOiBleHRlcm5hbCBQRSBhbmQgc3RhbmRhbG9uZSBpcyBubwotICAgICAgICBib29sZWFuIGlzVkMgPSAgZkhhc0V4dGVybmFsRFREICYmICFmU3RhbmRhbG9uZTsKLQotICAgICAgICAvLyBSRVZJU0lUOiBpdCBzZWVtcyB0aGF0IHRoaXMgZnVuY3Rpb24gc2hvdWxkIG5vdCB0YWtlIGF0dHJpYnV0ZXMsIGFuZCBsZW5ndGgKLSAgICAgICAgLy9mVGVtcFN0cmluZyB3b3VsZCBzdG9yZSBhdHRyaWJ1dGUgdmFsdWUKLSAgICAgICAgLy8vZlRlbXBTdHJpbmcyIHdvdWxkIHN0b3JlIGF0dHJpYnV0ZSBub24tbm9ybWFsaXplZCB2YWx1ZQotCi0gICAgICAgIC8vdGhpcyBmdW5jdGlvbiBkb2Vzbid0IHVzZSAnYXR0SW5kZXgnLiBXZSBhcmUgYWRkaW5nIHRoZSBhdHRyaWJ1dGUgbGF0ZXIKLSAgICAgICAgLy9hZnRlciB3ZSBoYXZlIGZpZ3VyZWQgb3V0IHRoYXQgY3VycmVudCBhdHRyaWJ1dGUgaXMgbm90IG5hbWVzcGFjZSBkZWNsYXJhdGlvbgotICAgICAgICAvL3NpbmNlIHNjYW5BdHRyaWJ1dGVWYWx1ZSBkb2Vzbid0IHVzZSBhdHRJbmRleCBwYXJhbWV0ZXIgdGhlcmVmb3JlIHdlCi0gICAgICAgIC8vY2FuIHNhZmVseSBhZGQgdGhlIGF0dHJpYnV0ZSBsYXRlci4uCi0gICAgICAgIFhNTFN0cmluZyB0bXBTdHIgPSBnZXRTdHJpbmcoKTsKLQotICAgICAgICAvKioKLSAgICAgICAgICogRGV0ZXJtaW5lIHdoZXRoZXIgdGhpcyBpcyBhIG5hbWVzcGFjZSBkZWNsYXJhdGlvbiB0aGF0IHdpbGwgYmUgc3ViamVjdAotICAgICAgICAgKiB0byB0aGUgbmFtZSBsaW1pdCBjaGVjayBpbiB0aGUgc2NhbkF0dHJpYnV0ZVZhbHVlIG9wZXJhdGlvbi4KLSAgICAgICAgICogTmFtZXNwYWNlIGRlY2xhcmF0aW9uIGZvcm1hdDogeG1sbnM9Ii4uLiIgb3IgeG1sbnM6cHJlZml4PSIuLi4iCi0gICAgICAgICAqIE5vdGUgdGhhdCBwcmVmaXg6eG1sbnM9Ii4uLiIgaXNuJ3QgYSBuYW1lc3BhY2UuCi0gICAgICAgICAqLwotICAgICAgICBTdHJpbmcgbG9jYWxwYXJ0ID0gZkF0dHJpYnV0ZVFOYW1lLmxvY2FscGFydDsKLSAgICAgICAgU3RyaW5nIHByZWZpeCA9IGZBdHRyaWJ1dGVRTmFtZS5wcmVmaXggIT0gbnVsbAotICAgICAgICAgICAgICAgID8gZkF0dHJpYnV0ZVFOYW1lLnByZWZpeCA6IFhNTFN5bWJvbHMuRU1QVFlfU1RSSU5HOwotICAgICAgICBib29sZWFuIGlzTlNEZWNsID0gZkJpbmROYW1lc3BhY2VzICYgKHByZWZpeCA9PSBYTUxTeW1ib2xzLlBSRUZJWF9YTUxOUyB8fAotICAgICAgICAgICAgICAgICAgICBwcmVmaXggPT0gWE1MU3ltYm9scy5FTVBUWV9TVFJJTkcgJiYgbG9jYWxwYXJ0ID09IFhNTFN5bWJvbHMuUFJFRklYX1hNTE5TKTsKLQotICAgICAgICBzY2FuQXR0cmlidXRlVmFsdWUodG1wU3RyLCBmVGVtcFN0cmluZzIsIGZBdHRyaWJ1dGVRTmFtZS5yYXduYW1lLCBhdHRyaWJ1dGVzLAotICAgICAgICAgICAgICAgIGF0dHJJbmRleCwgaXNWQywgZkN1cnJlbnRFbGVtZW50LnJhd25hbWUsIGlzTlNEZWNsKTsKLQotICAgICAgICBTdHJpbmcgdmFsdWUgPSBudWxsOwotICAgICAgICAvL2ZUZW1wU3RyaW5nLnRvU3RyaW5nKCk7Ci0KLSAgICAgICAgLy8gcmVjb3JkIG5hbWVzcGFjZSBkZWNsYXJhdGlvbnMgaWYgYW55LgotICAgICAgICBpZiAoZkJpbmROYW1lc3BhY2VzKSB7Ci0gICAgICAgICAgICBpZiAoaXNOU0RlY2wpIHsKLSAgICAgICAgICAgICAgICAvL2NoZWNrIHRoZSBsZW5ndGggb2YgVVJJCi0gICAgICAgICAgICAgICAgaWYgKHRtcFN0ci5sZW5ndGggPiBmWE1MTmFtZUxpbWl0KSB7Ci0gICAgICAgICAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTWF4WE1MTmFtZUxpbWl0IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117bmV3IFN0cmluZyh0bXBTdHIuY2gsdG1wU3RyLm9mZnNldCx0bXBTdHIubGVuZ3RoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB0bXBTdHIubGVuZ3RoLCBmWE1MTmFtZUxpbWl0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZTZWN1cml0eU1hbmFnZXIuZ2V0U3RhdGVMaXRlcmFsKFhNTFNlY3VyaXR5TWFuYWdlci5MaW1pdC5NQVhfTkFNRV9MSU1JVCl9LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTEVycm9yUmVwb3J0ZXIuU0VWRVJJVFlfRkFUQUxfRVJST1IpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvLyBnZXQgdGhlIGludGVybmFsaXplZCB2YWx1ZSBvZiB0aGlzIGF0dHJpYnV0ZQotICAgICAgICAgICAgICAgIFN0cmluZyB1cmkgPSBmU3ltYm9sVGFibGUuYWRkU3ltYm9sKHRtcFN0ci5jaCx0bXBTdHIub2Zmc2V0LHRtcFN0ci5sZW5ndGgpOwotICAgICAgICAgICAgICAgIHZhbHVlID0gdXJpOwotICAgICAgICAgICAgICAgIC8vIDEuICJ4bWxucyIgY2FuJ3QgYmUgYm91bmQgdG8gYW55IG5hbWVzcGFjZQotICAgICAgICAgICAgICAgIGlmIChwcmVmaXggPT0gWE1MU3ltYm9scy5QUkVGSVhfWE1MTlMgJiYgbG9jYWxwYXJ0ID09IFhNTFN5bWJvbHMuUFJFRklYX1hNTE5TKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MTlNfRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDYW50QmluZFhNTE5TIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117ZkF0dHJpYnV0ZVFOYW1lfSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxFcnJvclJlcG9ydGVyLlNFVkVSSVRZX0ZBVEFMX0VSUk9SKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyAyLiB0aGUgbmFtZXNwYWNlIGZvciAieG1sbnMiIGNhbid0IGJlIGJvdW5kIHRvIGFueSBwcmVmaXgKLSAgICAgICAgICAgICAgICBpZiAodXJpID09IE5hbWVzcGFjZUNvbnRleHQuWE1MTlNfVVJJKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MTlNfRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDYW50QmluZFhNTE5TIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117ZkF0dHJpYnV0ZVFOYW1lfSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxFcnJvclJlcG9ydGVyLlNFVkVSSVRZX0ZBVEFMX0VSUk9SKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyAzLiAieG1sIiBjYW4ndCBiZSBib3VuZCB0byBhbnkgb3RoZXIgbmFtZXNwYWNlIHRoYW4gaXQncyBvd24KLSAgICAgICAgICAgICAgICBpZiAobG9jYWxwYXJ0ID09IFhNTFN5bWJvbHMuUFJFRklYX1hNTCkgewotICAgICAgICAgICAgICAgICAgICBpZiAodXJpICE9IE5hbWVzcGFjZUNvbnRleHQuWE1MX1VSSSkgewotICAgICAgICAgICAgICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxOU19ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDYW50QmluZFhNTCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXtmQXR0cmlidXRlUU5hbWV9LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxFcnJvclJlcG9ydGVyLlNFVkVSSVRZX0ZBVEFMX0VSUk9SKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvLyA0LiB0aGUgbmFtZXNwYWNlIGZvciAieG1sIiBjYW4ndCBiZSBib3VuZCB0byBhbnkgb3RoZXIgcHJlZml4Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmICh1cmkgPT1OYW1lc3BhY2VDb250ZXh0LlhNTF9VUkkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MTlNfRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ2FudEJpbmRYTUwiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117ZkF0dHJpYnV0ZVFOYW1lfSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9GQVRBTF9FUlJPUik7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgcHJlZml4ID0gbG9jYWxwYXJ0ICE9IFhNTFN5bWJvbHMuUFJFRklYX1hNTE5TID8gbG9jYWxwYXJ0IDogWE1MU3ltYm9scy5FTVBUWV9TVFJJTkc7Ci0gICAgICAgICAgICAgICAgLy9zZXQgaXQgZXF1YWwgdG8gWE1MU3ltYm9scy5QUkVGSVhfWE1MTlMgd2hlbiBuYW1lc3BhY2UgZGVjbGFyYXRpb24KLSAgICAgICAgICAgICAgICAvLyBpcyBvZiB0eXBlIHhtbG5zID0gIi4uIiwgaW4gdGhpcyBjYXNlIHByZWZpeCA9ICIiIGFuZCBsb2NhbG5hbWUgPSBYTUxTeW1ib2xzLlBSRUZJWF9YTUxOUwotICAgICAgICAgICAgICAgIC8vdGhpcyBzcGVjaWFsIGJlaGF2aW9yIGlzIGJlY2F1c2Ugb2YgZGVwZW5kZW5jeSBvbiB0aGlzIGJlaGF2aW9yIGluIERPTSBjb21wb25lbnRzCi0gICAgICAgICAgICAgICAgaWYocHJlZml4ID09IFhNTFN5bWJvbHMuRU1QVFlfU1RSSU5HICYmIGxvY2FscGFydCA9PSBYTUxTeW1ib2xzLlBSRUZJWF9YTUxOUyl7Ci0gICAgICAgICAgICAgICAgICAgIGZBdHRyaWJ1dGVRTmFtZS5wcmVmaXggPSBYTUxTeW1ib2xzLlBSRUZJWF9YTUxOUzsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLy8gaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OS9SRUMteG1sLW5hbWVzLTE5OTkwMTE0LyNkdC1wcmVmaXgKLSAgICAgICAgICAgICAgICAvLyBXZSBzaG91bGQgb25seSByZXBvcnQgYW4gZXJyb3IgaWYgdGhlcmUgaXMgYSBwcmVmaXgsCi0gICAgICAgICAgICAgICAgLy8gdGhhdCBpcywgdGhlIGxvY2FsIHBhcnQgaXMgbm90ICJ4bWxucyIuIC1TRwotICAgICAgICAgICAgICAgIGlmICh1cmkgPT0gWE1MU3ltYm9scy5FTVBUWV9TVFJJTkcgJiYgbG9jYWxwYXJ0ICE9IFhNTFN5bWJvbHMuUFJFRklYX1hNTE5TKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MTlNfRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICJFbXB0eVByZWZpeGVkQXR0TmFtZSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde2ZBdHRyaWJ1dGVRTmFtZX0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9GQVRBTF9FUlJPUik7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgLy8gY2hlY2sgZm9yIGR1cGxpY2F0ZSBwcmVmaXggYmluZGluZ3MKLSAgICAgICAgICAgICAgICBpZiAoKChjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuTmFtZXNwYWNlU3VwcG9ydCkgZk5hbWVzcGFjZUNvbnRleHQpLmNvbnRhaW5zUHJlZml4SW5DdXJyZW50Q29udGV4dChwcmVmaXgpKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIkF0dHJpYnV0ZU5vdFVuaXF1ZSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde2ZDdXJyZW50RWxlbWVudC5yYXduYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZBdHRyaWJ1dGVRTmFtZS5yYXduYW1lfSk7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgLy8gZGVjbGFyZSBwcmVmaXggaW4gY29udGV4dAotICAgICAgICAgICAgICAgIGJvb2xlYW4gZGVjbGFyZWQgPSBmTmFtZXNwYWNlQ29udGV4dC5kZWNsYXJlUHJlZml4KHByZWZpeCwgdXJpLmxlbmd0aCgpICE9IDAgPyB1cmkgOiBudWxsKTsKLQotICAgICAgICAgICAgICAgIC8vIGNoZWNrIGZvciBkdXBsaWNhdGUgeG1sbnMgZGVjbGFyYXRpb25zCi0gICAgICAgICAgICAgICAgaWYgKCFkZWNsYXJlZCkgeyAvLyBieSBjb252ZW50aW9uLCBwcmVmaXggPT0gInhtbG5zIiB8ICJ4bWwiCi0gICAgICAgICAgICAgICAgICAgIC8vIGVycm9yIGlmIGR1cGxpY2F0ZSBkZWNsYXJhdGlvbgotICAgICAgICAgICAgICAgICAgICBpZiAoZlhtbG5zRGVjbGFyZWQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIkF0dHJpYnV0ZU5vdFVuaXF1ZSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXtmQ3VycmVudEVsZW1lbnQucmF3bmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkF0dHJpYnV0ZVFOYW1lLnJhd25hbWV9KTsKLSAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgIC8vIHhtbG5zIGRlY2xhcmVkCi0gICAgICAgICAgICAgICAgICAgIGZYbWxuc0RlY2xhcmVkID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvL3hlcmNlcyBpbnRlcm5hbHMgKFhTQXR0cmlidXRlQ2hlY2tlcikgaGFzIGRlcGVuZGVuY3kgb24gbmFtZXNwYWNlIGRlY2xhcmF0aW9uIHJldHVybmVkCi0gICAgICAgICAgICAgICAgLy9hcyBwYXJ0IG9mIFhNTEF0dHJpYnV0ZXMuCi0gICAgICAgICAgICAgICAgLy9hZGRpdGlvbiBvZiBuYW1lc3BhY2UgZGVjbGFyYXRpb24gdG8gdGhlIGF0dHJpYnV0ZSBsaXN0IGlzIGNvbnRyb2xsZWQgYnkgZk5vdEFkZE5TRGVjbEFzQXR0cmlidXRlCi0gICAgICAgICAgICAgICAgLy9mZWF0dXJlLiBUaGlzIGlzIHJlcXVpcmVkIGluIFN0YXggd2hlcmUgbmFtZXNwYWNlIGRlY2xhcmF0aW9ucyBhcmUgbm90IGNvbnNpZGVyZWQgYXMgYXR0cmlidXRlCi0KLSAgICAgICAgICAgICAgICBpZihmTm90QWRkTlNEZWNsQXNBdHRyaWJ1dGUpewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vYWRkIHRoZSBhdHRyaWJ1dGVzIHRvIHRoZSBsaXN0IG9mIGF0dHJpYnV0ZXMKLSAgICAgICAgaWYgKGZCaW5kTmFtZXNwYWNlcykgewotICAgICAgICAgICAgYXR0ckluZGV4ID0gYXR0cmlidXRlcy5nZXRMZW5ndGgoKTsKLSAgICAgICAgICAgIGF0dHJpYnV0ZXMuYWRkQXR0cmlidXRlTlMoZkF0dHJpYnV0ZVFOYW1lLCBYTUxTeW1ib2xzLmZDREFUQVN5bWJvbCwgbnVsbCk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBpbnQgb2xkTGVuID0gYXR0cmlidXRlcy5nZXRMZW5ndGgoKTsKLSAgICAgICAgICAgIGF0dHJJbmRleCA9IGF0dHJpYnV0ZXMuYWRkQXR0cmlidXRlKGZBdHRyaWJ1dGVRTmFtZSwgWE1MU3ltYm9scy5mQ0RBVEFTeW1ib2wsIG51bGwpOwotCi0gICAgICAgICAgICAvLyBXRkM6IFVuaXF1ZSBBdHQgU3BlYwotICAgICAgICAgICAgaWYgKG9sZExlbiA9PSBhdHRyaWJ1dGVzLmdldExlbmd0aCgpKSB7Ci0gICAgICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiQXR0cmlidXRlTm90VW5pcXVlIiwKLSAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXtmQ3VycmVudEVsZW1lbnQucmF3bmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkF0dHJpYnV0ZVFOYW1lLnJhd25hbWV9KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGF0dHJpYnV0ZXMuc2V0VmFsdWUoYXR0ckluZGV4LCB2YWx1ZSx0bXBTdHIpOwotICAgICAgICAvL2F0dHJpYnV0ZXMuc2V0Tm9uTm9ybWFsaXplZFZhbHVlKGF0dHJJbmRleCwgZlRlbXBTdHJpbmcyLnRvU3RyaW5nKCkpOwotICAgICAgICAvL3JlbW92aW5nICBhcyB3ZSBhcmUgbm90IHVzaW5nIG5vbi1ub3JtYWxpemVkIHZhbHVlcyAuIC1WZW51Ci0gICAgICAgIGF0dHJpYnV0ZXMuc2V0U3BlY2lmaWVkKGF0dHJJbmRleCwgdHJ1ZSk7Ci0KLSAgICAgICAgLy8gYXR0ZW1wdCB0byBiaW5kIGF0dHJpYnV0ZQotICAgICAgICBpZiAoZkF0dHJpYnV0ZVFOYW1lLnByZWZpeCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBhdHRyaWJ1dGVzLnNldFVSSShhdHRySW5kZXgsIGZOYW1lc3BhY2VDb250ZXh0LmdldFVSSShmQXR0cmlidXRlUU5hbWUucHJlZml4KSk7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoREVCVUdfU1RBUlRfRU5EX0VMRU1FTlQpIFN5c3RlbS5vdXQucHJpbnRsbih0aGlzLmdldENsYXNzKCkudG9TdHJpbmcoKSArIjw8PCBzY2FuQXR0cmlidXRlKCkiKTsKLSAgICB9IC8vIHNjYW5BdHRyaWJ1dGUoWE1MQXR0cmlidXRlcykKLQotCi0KLQotCi0gICAgLyoqIENyZWF0ZXMgYSBjb250ZW50IGRyaXZlci4gKi8KLSAgICBwcm90ZWN0ZWQgRHJpdmVyIGNyZWF0ZUNvbnRlbnREcml2ZXIoKSB7Ci0gICAgICAgIHJldHVybiBuZXcgTlNDb250ZW50RHJpdmVyKCk7Ci0gICAgfSAvLyBjcmVhdGVDb250ZW50RHJpdmVyKCk6RHJpdmVyCi0KLSAgICAvKioKLSAgICAgKiBEcml2ZXIgdG8gaGFuZGxlIGNvbnRlbnQgc2Nhbm5pbmcuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGZpbmFsIGNsYXNzIE5TQ29udGVudERyaXZlcgotICAgICAgICAgICAgZXh0ZW5kcyBDb250ZW50RHJpdmVyIHsKLSAgICAgICAgLyoqCi0gICAgICAgICAqIFNjYW4gZm9yIHJvb3QgZWxlbWVudCBob29rLiBUaGlzIG1ldGhvZCBpcyBhIGhvb2sgZm9yCi0gICAgICAgICAqIHN1YmNsYXNzZXMgdG8gYWRkIGNvZGUgdGhhdCBoYW5kbGVzIHNjYW5uaW5nIGZvciB0aGUgcm9vdAotICAgICAgICAgKiBlbGVtZW50LiBUaGlzIG1ldGhvZCB3aWxsIGFsc28gYXR0ZW1wdCB0byByZW1vdmUgRFREIHZhbGlkYXRvcgotICAgICAgICAgKiBmcm9tIHRoZSBwaXBlbGluZSwgaWYgdGhlcmUgaXMgbm8gRFREIGdyYW1tYXIuIElmIERURCB2YWxpZGF0b3IKLSAgICAgICAgICogaXMgbm8gbG9uZ2VyIGluIHRoZSBwaXBlbGluZSBiaW5kIG5hbWVzcGFjZXMgaW4gdGhlIHNjYW5uZXIuCi0gICAgICAgICAqCi0gICAgICAgICAqCi0gICAgICAgICAqIEByZXR1cm4gVHJ1ZSBpZiB0aGUgY2FsbGVyIHNob3VsZCBzdG9wIGFuZCByZXR1cm4gdHJ1ZSB3aGljaAotICAgICAgICAgKiAgICAgICAgICBhbGxvd3MgdGhlIHNjYW5uZXIgdG8gc3dpdGNoIHRvIGEgbmV3IHNjYW5uaW5nCi0gICAgICAgICAqICAgICAgICAgIGRyaXZlci4gQSByZXR1cm4gdmFsdWUgb2YgZmFsc2UgaW5kaWNhdGVzIHRoYXQKLSAgICAgICAgICogICAgICAgICAgdGhlIGNvbnRlbnQgZHJpdmVyIHNob3VsZCBjb250aW51ZSBhcyBub3JtYWwuCi0gICAgICAgICAqLwotICAgICAgICBwcm90ZWN0ZWQgYm9vbGVhbiBzY2FuUm9vdEVsZW1lbnRIb29rKCkKLSAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBYTklFeGNlcHRpb24gewotCi0gICAgICAgICAgICByZWNvbmZpZ3VyZVBpcGVsaW5lKCk7Ci0gICAgICAgICAgICBpZiAoc2NhblN0YXJ0RWxlbWVudCgpKSB7Ci0gICAgICAgICAgICAgICAgc2V0U2Nhbm5lclN0YXRlKFNDQU5ORVJfU1RBVEVfVFJBSUxJTkdfTUlTQyk7Ci0gICAgICAgICAgICAgICAgc2V0RHJpdmVyKGZUcmFpbGluZ01pc2NEcml2ZXIpOwotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotCi0gICAgICAgIH0gLy8gc2NhblJvb3RFbGVtZW50SG9vaygpOmJvb2xlYW4KLQotICAgICAgICAvKioKLSAgICAgICAgICogUmUtY29uZmlndXJlcyBwaXBlbGluZSBieSByZW1vdmluZyB0aGUgRFREIHZhbGlkYXRvcgotICAgICAgICAgKiBpZiBubyBEVEQgZ3JhbW1hciBleGlzdHMuIElmIG5vIHZhbGlkYXRvciBleGlzdHMgaW4gdGhlCi0gICAgICAgICAqIHBpcGVsaW5lIG9yIHRoZXJlIGlzIG5vIERURCBncmFtbWFyLCBuYW1lc3BhY2UgYmluZGluZwotICAgICAgICAgKiBpcyBwZXJmb3JtZWQgYnkgdGhlIHNjYW5uZXIgaW4gdGhlIGVuY2xvc2luZyBjbGFzcy4KLSAgICAgICAgICovCi0gICAgICAgIHByaXZhdGUgdm9pZCByZWNvbmZpZ3VyZVBpcGVsaW5lKCkgewotICAgICAgICAgICAgLy9mRFREVmFsaWRhdG9yIHdpbGwgYmUgbnVsbCBpbiBTdGF4IG1vZGUKLSAgICAgICAgICAgIGlmIChmTmFtZXNwYWNlcyAmJiBmRFREVmFsaWRhdG9yID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmQmluZE5hbWVzcGFjZXMgPSB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoZk5hbWVzcGFjZXMgJiYgIWZEVERWYWxpZGF0b3IuaGFzR3JhbW1hcigpICkgewotICAgICAgICAgICAgICAgIGZCaW5kTmFtZXNwYWNlcyA9IHRydWU7Ci0gICAgICAgICAgICAgICAgZlBlcmZvcm1WYWxpZGF0aW9uID0gZkRURFZhbGlkYXRvci52YWxpZGF0ZSgpOwotICAgICAgICAgICAgICAgIC8vIHJlLWNvbmZpZ3VyZSBwaXBlbGluZSBieSByZW1vdmluZyBEVERWYWxpZGF0b3IKLSAgICAgICAgICAgICAgICBYTUxEb2N1bWVudFNvdXJjZSBzb3VyY2UgPSBmRFREVmFsaWRhdG9yLmdldERvY3VtZW50U291cmNlKCk7Ci0gICAgICAgICAgICAgICAgWE1MRG9jdW1lbnRIYW5kbGVyIGhhbmRsZXIgPSBmRFREVmFsaWRhdG9yLmdldERvY3VtZW50SGFuZGxlcigpOwotICAgICAgICAgICAgICAgIHNvdXJjZS5zZXREb2N1bWVudEhhbmRsZXIoaGFuZGxlcik7Ci0gICAgICAgICAgICAgICAgaWYgKGhhbmRsZXIgIT0gbnVsbCkKLSAgICAgICAgICAgICAgICAgICAgaGFuZGxlci5zZXREb2N1bWVudFNvdXJjZShzb3VyY2UpOwotICAgICAgICAgICAgICAgIGZEVERWYWxpZGF0b3Iuc2V0RG9jdW1lbnRTb3VyY2UobnVsbCk7Ci0gICAgICAgICAgICAgICAgZkRURFZhbGlkYXRvci5zZXREb2N1bWVudEhhbmRsZXIobnVsbCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gLy8gcmVjb25maWd1cmVQaXBlbGluZSgpCi0gICAgfQotCi19IC8vIGNsYXNzIFhNTE5TRG9jdW1lbnRTY2FubmVySW1wbApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9YTUxOYW1lc3BhY2VCaW5kZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvWE1MTmFtZXNwYWNlQmluZGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDEzYzI3YmMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9YTUxOYW1lc3BhY2VCaW5kZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDg4OSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAwLTIwMDIgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYZXJjZXMiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIEludGVybmF0aW9uYWwKLSAqIEJ1c2luZXNzIE1hY2hpbmVzLCBJbmMuLCBodHRwOi8vd3d3LmFwYWNoZS5vcmcuICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGw7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwubXNnLlhNTE1lc3NhZ2VGb3JtYXR0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlN5bWJvbFRhYmxlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5YTUxTeW1ib2xzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLkF1Z21lbnRhdGlvbnM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuTmFtZXNwYWNlQ29udGV4dDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5RTmFtZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxBdHRyaWJ1dGVzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTERvY3VtZW50SGFuZGxlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxMb2NhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTFJlc291cmNlSWRlbnRpZmllcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxTdHJpbmc7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE5JRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxDb21wb25lbnQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTENvbXBvbmVudE1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTERvY3VtZW50RmlsdGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxEb2N1bWVudFNvdXJjZTsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIHBlcmZvcm1zIG5hbWVzcGFjZSBiaW5kaW5nIG9uIHRoZSBzdGFydEVsZW1lbnQgYW5kIGVuZEVsZW1lbnQKLSAqIG1ldGhvZCBjYWxscyBhbmQgcGFzc2VzIGFsbCBvdGhlciBtZXRob2RzIHRocm91Z2ggdG8gdGhlIHJlZ2lzdGVyZWQKLSAqIGRvY3VtZW50IGhhbmRsZXIuIFRoaXMgY2xhc3MgY2FuIGJlIGNvbmZpZ3VyZWQgdG8gb25seSBwYXNzIHRoZQotICogc3RhcnQgYW5kIGVuZCBwcmVmaXggbWFwcGluZ3MgKHN0YXJ0L2VuZFByZWZpeE1hcHBpbmcpLgotICogPHA+Ci0gKiBUaGlzIGNvbXBvbmVudCByZXF1aXJlcyB0aGUgZm9sbG93aW5nIGZlYXR1cmVzIGFuZCBwcm9wZXJ0aWVzIGZyb20gdGhlCi0gKiBjb21wb25lbnQgbWFuYWdlciB0aGF0IHVzZXMgaXQ6Ci0gKiA8dWw+Ci0gKiAgPGxpPmh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy9uYW1lc3BhY2VzPC9saT4KLSAqICA8bGk+aHR0cDovL2FwYWNoZS5vcmcveG1sL3Byb3BlcnRpZXMvaW50ZXJuYWwvc3ltYm9sLXRhYmxlPC9saT4KLSAqICA8bGk+aHR0cDovL2FwYWNoZS5vcmcveG1sL3Byb3BlcnRpZXMvaW50ZXJuYWwvZXJyb3ItcmVwb3J0ZXI8L2xpPgotICogPC91bD4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBBbmR5IENsYXJrLCBJQk0KLSAqCi0gKiBAdmVyc2lvbiAkSWQ6IFhNTE5hbWVzcGFjZUJpbmRlci5qYXZhLHYgMS40IDIwMTAtMTEtMDEgMDQ6Mzk6NDEgam9laHcgRXhwICQKLSAqLwotcHVibGljIGNsYXNzIFhNTE5hbWVzcGFjZUJpbmRlcgotICAgIGltcGxlbWVudHMgWE1MQ29tcG9uZW50LCBYTUxEb2N1bWVudEZpbHRlciB7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0YW50cwotICAgIC8vCi0KLSAgICAvLyBmZWF0dXJlIGlkZW50aWZpZXJzCi0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiBuYW1lc3BhY2VzLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIE5BTUVTUEFDRVMgPQotICAgICAgICBDb25zdGFudHMuU0FYX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLk5BTUVTUEFDRVNfRkVBVFVSRTsKLQotICAgIC8vIHByb3BlcnR5IGlkZW50aWZpZXJzCi0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogc3ltYm9sIHRhYmxlLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFNZTUJPTF9UQUJMRSA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLlNZTUJPTF9UQUJMRV9QUk9QRVJUWTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBlcnJvciByZXBvcnRlci4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJPUl9SRVBPUlRFUiA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLkVSUk9SX1JFUE9SVEVSX1BST1BFUlRZOwotCi0gICAgLy8gcmVjb2duaXplZCBmZWF0dXJlcyBhbmQgcHJvcGVydGllcwotCi0gICAgLyoqIFJlY29nbml6ZWQgZmVhdHVyZXMuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nW10gUkVDT0dOSVpFRF9GRUFUVVJFUyA9IHsKLSAgICAgICAgTkFNRVNQQUNFUywKLSAgICB9OwotCi0gICAgLyoqIEZlYXR1cmUgZGVmYXVsdHMuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQm9vbGVhbltdIEZFQVRVUkVfREVGQVVMVFMgPSB7Ci0gICAgICAgIG51bGwsCi0gICAgfTsKLQotICAgIC8qKiBSZWNvZ25pemVkIHByb3BlcnRpZXMuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nW10gUkVDT0dOSVpFRF9QUk9QRVJUSUVTID0gewotICAgICAgICBTWU1CT0xfVEFCTEUsCi0gICAgICAgIEVSUk9SX1JFUE9SVEVSLAotICAgIH07Ci0KLSAgICAvKiogUHJvcGVydHkgZGVmYXVsdHMuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgT2JqZWN0W10gUFJPUEVSVFlfREVGQVVMVFMgPSB7Ci0gICAgICAgIG51bGwsCi0gICAgICAgIG51bGwsCi0gICAgfTsKLQotICAgIC8vCi0gICAgLy8gRGF0YQotICAgIC8vCi0KLSAgICAvLyBmZWF0dXJlcwotCi0gICAgLyoqIE5hbWVzcGFjZXMuICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZk5hbWVzcGFjZXM7Ci0KLSAgICAvLyBwcm9wZXJ0aWVzCi0KLSAgICAvKiogU3ltYm9sIHRhYmxlLiAqLwotICAgIHByb3RlY3RlZCBTeW1ib2xUYWJsZSBmU3ltYm9sVGFibGU7Ci0KLSAgICAvKiogRXJyb3IgcmVwb3J0ZXIuICovCi0gICAgcHJvdGVjdGVkIFhNTEVycm9yUmVwb3J0ZXIgZkVycm9yUmVwb3J0ZXI7Ci0KLSAgICAvLyBoYW5kbGVycwotCi0gICAgLyoqIERvY3VtZW50IGhhbmRsZXIuICovCi0gICAgcHJvdGVjdGVkIFhNTERvY3VtZW50SGFuZGxlciBmRG9jdW1lbnRIYW5kbGVyOwotCi0gICAgcHJvdGVjdGVkIFhNTERvY3VtZW50U291cmNlIGZEb2N1bWVudFNvdXJjZTsKLQotICAgIC8vIHNldHRpbmdzCi0KLSAgICAvKiogT25seSBwYXNzIHN0YXJ0IGFuZCBlbmQgcHJlZml4IG1hcHBpbmcgZXZlbnRzLiAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIGZPbmx5UGFzc1ByZWZpeE1hcHBpbmdFdmVudHM7Ci0KLSAgICAvLyBzaGFyZWQgY29udGV4dAotCi0gICAgLyoqIE5hbWVzcGFjZSBjb250ZXh0LiAqLwotICAgIHByaXZhdGUgTmFtZXNwYWNlQ29udGV4dCBmTmFtZXNwYWNlQ29udGV4dDsKLQotICAgIC8vIHRlbXAgdmFycwotCi0gICAgLyoqIEF0dHJpYnV0ZSBRTmFtZS4gKi8KLSAgICBwcml2YXRlIFFOYW1lIGZBdHRyaWJ1dGVRTmFtZSA9IG5ldyBRTmFtZSgpOwotCi0gICAgLy8KLSAgICAvLyBDb25zdHJ1Y3RvcnMKLSAgICAvLwotCi0gICAgLyoqIERlZmF1bHQgY29uc3RydWN0b3IuICovCi0gICAgcHVibGljIFhNTE5hbWVzcGFjZUJpbmRlcigpIHsKLSAgICB9IC8vIDxpbml0PigpCi0KLSAgICAvLwotICAgIC8vIFB1YmxpYyBtZXRob2RzCi0gICAgLy8KLQotICAgIC8vIHNldHRpbmdzCi0KLSAgICAvKioKLSAgICAgKiBTZXRzIHdoZXRoZXIgdGhlIG5hbWVzcGFjZSBiaW5kZXIgb25seSBwYXNzZXMgdGhlIHByZWZpeCBtYXBwaW5nCi0gICAgICogZXZlbnRzIHRvIHRoZSByZWdpc3RlcmVkIGRvY3VtZW50IGhhbmRsZXIgb3IgcGFzc2VzIGFsbCBkb2N1bWVudAotICAgICAqIGV2ZW50cy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBvbmx5UGFzc1ByZWZpeE1hcHBpbmdFdmVudHMgVHJ1ZSB0byBwYXNzIG9ubHkgdGhlIHByZWZpeAotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFwcGluZyBldmVudHM7IGZhbHNlIHRvIHBhc3MKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsbCBldmVudHMuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0T25seVBhc3NQcmVmaXhNYXBwaW5nRXZlbnRzKGJvb2xlYW4gb25seVBhc3NQcmVmaXhNYXBwaW5nRXZlbnRzKSB7Ci0gICAgICAgIGZPbmx5UGFzc1ByZWZpeE1hcHBpbmdFdmVudHMgPSBvbmx5UGFzc1ByZWZpeE1hcHBpbmdFdmVudHM7Ci0gICAgfSAvLyBzZXRPbmx5UGFzc1ByZWZpeE1hcHBpbmdFdmVudHMoYm9vbGVhbikKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgbmFtZXNwYWNlIGJpbmRlciBvbmx5IHBhc3NlcyB0aGUgcHJlZml4IG1hcHBpbmcKLSAgICAgKiBldmVudHMgdG8gdGhlIHJlZ2lzdGVyZWQgZG9jdW1lbnQgaGFuZGxlcjsgZmFsc2UgaWYgdGhlIG5hbWVzcGFjZQotICAgICAqIGJpbmRlciBwYXNzZXMgYWxsIGRvY3VtZW50IGV2ZW50cy4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXRPbmx5UGFzc1ByZWZpeE1hcHBpbmdFdmVudHMoKSB7Ci0gICAgICAgIHJldHVybiBmT25seVBhc3NQcmVmaXhNYXBwaW5nRXZlbnRzOwotICAgIH0gLy8gZ2V0T25seVBhc3NQcmVmaXhNYXBwaW5nRXZlbnRzKCk6Ym9vbGVhbgotCi0gICAgLy8KLSAgICAvLyBYTUxDb21wb25lbnQgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBSZXNldHMgdGhlIGNvbXBvbmVudC4gVGhlIGNvbXBvbmVudCBjYW4gcXVlcnkgdGhlIGNvbXBvbmVudCBtYW5hZ2VyCi0gICAgICogYWJvdXQgYW55IGZlYXR1cmVzIGFuZCBwcm9wZXJ0aWVzIHRoYXQgYWZmZWN0IHRoZSBvcGVyYXRpb24gb2YgdGhlCi0gICAgICogY29tcG9uZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIGNvbXBvbmVudE1hbmFnZXIgVGhlIGNvbXBvbmVudCBtYW5hZ2VyLgotICAgICAqCi0gICAgICogQHRocm93cyBTQVhFeGNlcHRpb24gVGhyb3duIGJ5IGNvbXBvbmVudCBvbiBpbml0aWFsaXphdGlvbiBlcnJvci4KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBGb3IgZXhhbXBsZSwgaWYgYSBmZWF0dXJlIG9yIHByb3BlcnR5IGlzCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgcmVxdWlyZWQgZm9yIHRoZSBvcGVyYXRpb24gb2YgdGhlIGNvbXBvbmVudCwgdGhlCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgY29tcG9uZW50IG1hbmFnZXIgbWF5IHRocm93IGEKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIG9yIGEKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcmVzZXQoWE1MQ29tcG9uZW50TWFuYWdlciBjb21wb25lbnRNYW5hZ2VyKQotICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLQotICAgICAgICAvLyBmZWF0dXJlcwotICAgICAgICBmTmFtZXNwYWNlcyA9IGNvbXBvbmVudE1hbmFnZXIuZ2V0RmVhdHVyZShOQU1FU1BBQ0VTLCB0cnVlKTsKLQotICAgICAgICAvLyBYZXJjZXMgcHJvcGVydGllcwotICAgICAgICBmU3ltYm9sVGFibGUgPSAoU3ltYm9sVGFibGUpY29tcG9uZW50TWFuYWdlci5nZXRQcm9wZXJ0eShTWU1CT0xfVEFCTEUpOwotICAgICAgICBmRXJyb3JSZXBvcnRlciA9IChYTUxFcnJvclJlcG9ydGVyKWNvbXBvbmVudE1hbmFnZXIuZ2V0UHJvcGVydHkoRVJST1JfUkVQT1JURVIpOwotCi0gICAgfSAvLyByZXNldChYTUxDb21wb25lbnRNYW5hZ2VyKQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhIGxpc3Qgb2YgZmVhdHVyZSBpZGVudGlmaWVycyB0aGF0IGFyZSByZWNvZ25pemVkIGJ5Ci0gICAgICogdGhpcyBjb21wb25lbnQuIFRoaXMgbWV0aG9kIG1heSByZXR1cm4gbnVsbCBpZiBubyBmZWF0dXJlcwotICAgICAqIGFyZSByZWNvZ25pemVkIGJ5IHRoaXMgY29tcG9uZW50LgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmdbXSBnZXRSZWNvZ25pemVkRmVhdHVyZXMoKSB7Ci0gICAgICAgIHJldHVybiAoU3RyaW5nW10pKFJFQ09HTklaRURfRkVBVFVSRVMuY2xvbmUoKSk7Ci0gICAgfSAvLyBnZXRSZWNvZ25pemVkRmVhdHVyZXMoKTpTdHJpbmdbXQotCi0gICAgLyoqCi0gICAgICogU2V0cyB0aGUgc3RhdGUgb2YgYSBmZWF0dXJlLiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgdGhlIGNvbXBvbmVudAotICAgICAqIG1hbmFnZXIgYW55IHRpbWUgYWZ0ZXIgcmVzZXQgd2hlbiBhIGZlYXR1cmUgY2hhbmdlcyBzdGF0ZS4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IENvbXBvbmVudHMgc2hvdWxkIHNpbGVudGx5IGlnbm9yZSBmZWF0dXJlcwotICAgICAqIHRoYXQgZG8gbm90IGFmZmVjdCB0aGUgb3BlcmF0aW9uIG9mIHRoZSBjb21wb25lbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZmVhdHVyZUlkIFRoZSBmZWF0dXJlIGlkZW50aWZpZXIuCi0gICAgICogQHBhcmFtIHN0YXRlICAgICBUaGUgc3RhdGUgb2YgdGhlIGZlYXR1cmUuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24gVGhlIGNvbXBvbmVudCBzaG91bGQgbm90IHRocm93Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMgZXhjZXB0aW9uLgotICAgICAqIEB0aHJvd3MgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIFRoZSBjb21wb25lbnQgc2hvdWxkIG5vdCB0aHJvdwotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMgZXhjZXB0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEZlYXR1cmUoU3RyaW5nIGZlYXR1cmVJZCwgYm9vbGVhbiBzdGF0ZSkKLSAgICAgICAgdGhyb3dzIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gewotICAgIH0gLy8gc2V0RmVhdHVyZShTdHJpbmcsYm9vbGVhbikKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYSBsaXN0IG9mIHByb3BlcnR5IGlkZW50aWZpZXJzIHRoYXQgYXJlIHJlY29nbml6ZWQgYnkKLSAgICAgKiB0aGlzIGNvbXBvbmVudC4gVGhpcyBtZXRob2QgbWF5IHJldHVybiBudWxsIGlmIG5vIHByb3BlcnRpZXMKLSAgICAgKiBhcmUgcmVjb2duaXplZCBieSB0aGlzIGNvbXBvbmVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nW10gZ2V0UmVjb2duaXplZFByb3BlcnRpZXMoKSB7Ci0gICAgICAgIHJldHVybiAoU3RyaW5nW10pKFJFQ09HTklaRURfUFJPUEVSVElFUy5jbG9uZSgpKTsKLSAgICB9IC8vIGdldFJlY29nbml6ZWRQcm9wZXJ0aWVzKCk6U3RyaW5nW10KLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIGEgcHJvcGVydHkgZHVyaW5nIHBhcnNpbmcuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcHJvcGVydHlJZAotICAgICAqIEBwYXJhbSB2YWx1ZQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFByb3BlcnR5KFN0cmluZyBwcm9wZXJ0eUlkLCBPYmplY3QgdmFsdWUpCi0gICAgICAgIHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIHsKLQotICAgICAgICAvLyBYZXJjZXMgcHJvcGVydGllcwotICAgICAgICBpZiAocHJvcGVydHlJZC5zdGFydHNXaXRoKENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYKSkgewotICAgICAgICAgICAgICAgIGZpbmFsIGludCBzdWZmaXhMZW5ndGggPSBwcm9wZXJ0eUlkLmxlbmd0aCgpIC0gQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVgubGVuZ3RoKCk7Ci0KLSAgICAgICAgICAgIGlmIChzdWZmaXhMZW5ndGggPT0gQ29uc3RhbnRzLlNZTUJPTF9UQUJMRV9QUk9QRVJUWS5sZW5ndGgoKSAmJgotICAgICAgICAgICAgICAgIHByb3BlcnR5SWQuZW5kc1dpdGgoQ29uc3RhbnRzLlNZTUJPTF9UQUJMRV9QUk9QRVJUWSkpIHsKLSAgICAgICAgICAgICAgICBmU3ltYm9sVGFibGUgPSAoU3ltYm9sVGFibGUpdmFsdWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChzdWZmaXhMZW5ndGggPT0gQ29uc3RhbnRzLkVSUk9SX1JFUE9SVEVSX1BST1BFUlRZLmxlbmd0aCgpICYmCi0gICAgICAgICAgICAgICAgcHJvcGVydHlJZC5lbmRzV2l0aChDb25zdGFudHMuRVJST1JfUkVQT1JURVJfUFJPUEVSVFkpKSB7Ci0gICAgICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIgPSAoWE1MRXJyb3JSZXBvcnRlcil2YWx1ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotCi0gICAgfSAvLyBzZXRQcm9wZXJ0eShTdHJpbmcsT2JqZWN0KQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgZGVmYXVsdCBzdGF0ZSBmb3IgYSBmZWF0dXJlLCBvciBudWxsIGlmIHRoaXMKLSAgICAgKiBjb21wb25lbnQgZG9lcyBub3Qgd2FudCB0byByZXBvcnQgYSBkZWZhdWx0IHZhbHVlIGZvciB0aGlzCi0gICAgICogZmVhdHVyZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBmZWF0dXJlSWQgVGhlIGZlYXR1cmUgaWRlbnRpZmllci4KLSAgICAgKgotICAgICAqIEBzaW5jZSBYZXJjZXMgMi4yLjAKLSAgICAgKi8KLSAgICBwdWJsaWMgQm9vbGVhbiBnZXRGZWF0dXJlRGVmYXVsdChTdHJpbmcgZmVhdHVyZUlkKSB7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgUkVDT0dOSVpFRF9GRUFUVVJFUy5sZW5ndGg7IGkrKykgewotICAgICAgICAgICAgaWYgKFJFQ09HTklaRURfRkVBVFVSRVNbaV0uZXF1YWxzKGZlYXR1cmVJZCkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gRkVBVFVSRV9ERUZBVUxUU1tpXTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9IC8vIGdldEZlYXR1cmVEZWZhdWx0KFN0cmluZyk6Qm9vbGVhbgotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgZGVmYXVsdCBzdGF0ZSBmb3IgYSBwcm9wZXJ0eSwgb3IgbnVsbCBpZiB0aGlzCi0gICAgICogY29tcG9uZW50IGRvZXMgbm90IHdhbnQgdG8gcmVwb3J0IGEgZGVmYXVsdCB2YWx1ZSBmb3IgdGhpcwotICAgICAqIHByb3BlcnR5LgotICAgICAqCi0gICAgICogQHBhcmFtIHByb3BlcnR5SWQgVGhlIHByb3BlcnR5IGlkZW50aWZpZXIuCi0gICAgICoKLSAgICAgKiBAc2luY2UgWGVyY2VzIDIuMi4wCi0gICAgICovCi0gICAgcHVibGljIE9iamVjdCBnZXRQcm9wZXJ0eURlZmF1bHQoU3RyaW5nIHByb3BlcnR5SWQpIHsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBSRUNPR05JWkVEX1BST1BFUlRJRVMubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgIGlmIChSRUNPR05JWkVEX1BST1BFUlRJRVNbaV0uZXF1YWxzKHByb3BlcnR5SWQpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIFBST1BFUlRZX0RFRkFVTFRTW2ldOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0gLy8gZ2V0UHJvcGVydHlEZWZhdWx0KFN0cmluZyk6T2JqZWN0Ci0KLSAgICAvLwotICAgIC8vIFhNTERvY3VtZW50U291cmNlIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqIFNldHMgdGhlIGRvY3VtZW50IGhhbmRsZXIgdG8gcmVjZWl2ZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgZG9jdW1lbnQuICovCi0gICAgcHVibGljIHZvaWQgc2V0RG9jdW1lbnRIYW5kbGVyKFhNTERvY3VtZW50SGFuZGxlciBkb2N1bWVudEhhbmRsZXIpIHsKLSAgICAgICAgZkRvY3VtZW50SGFuZGxlciA9IGRvY3VtZW50SGFuZGxlcjsKLSAgICB9IC8vIHNldERvY3VtZW50SGFuZGxlcihYTUxEb2N1bWVudEhhbmRsZXIpCi0KLSAgICAvKiogUmV0dXJucyB0aGUgZG9jdW1lbnQgaGFuZGxlciAqLwotICAgIHB1YmxpYyBYTUxEb2N1bWVudEhhbmRsZXIgZ2V0RG9jdW1lbnRIYW5kbGVyKCkgewotICAgICAgICByZXR1cm4gZkRvY3VtZW50SGFuZGxlcjsKLSAgICB9IC8vIHNldERvY3VtZW50SGFuZGxlcihYTUxEb2N1bWVudEhhbmRsZXIpCi0KLQotICAgIC8vCi0gICAgLy8gWE1MRG9jdW1lbnRIYW5kbGVyIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqIFNldHMgdGhlIGRvY3VtZW50IHNvdXJjZSAqLwotICAgIHB1YmxpYyB2b2lkIHNldERvY3VtZW50U291cmNlKFhNTERvY3VtZW50U291cmNlIHNvdXJjZSl7Ci0gICAgICAgIGZEb2N1bWVudFNvdXJjZSA9IHNvdXJjZTsKLSAgICB9IC8vIHNldERvY3VtZW50U291cmNlCi0KLSAgICAvKiogUmV0dXJucyB0aGUgZG9jdW1lbnQgc291cmNlICovCi0gICAgcHVibGljIFhNTERvY3VtZW50U291cmNlIGdldERvY3VtZW50U291cmNlICgpewotICAgICAgICByZXR1cm4gZkRvY3VtZW50U291cmNlOwotICAgIH0gLy8gZ2V0RG9jdW1lbnRTb3VyY2UKLQotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2Qgbm90aWZpZXMgdGhlIHN0YXJ0IG9mIGEgZ2VuZXJhbCBlbnRpdHkuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGlzIG1ldGhvZCBpcyBub3QgY2FsbGVkIGZvciBlbnRpdHkgcmVmZXJlbmNlcwotICAgICAqIGFwcGVhcmluZyBhcyBwYXJ0IG9mIGF0dHJpYnV0ZSB2YWx1ZXMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSAgICAgVGhlIG5hbWUgb2YgdGhlIGdlbmVyYWwgZW50aXR5LgotICAgICAqIEBwYXJhbSBpZGVudGlmaWVyIFRoZSByZXNvdXJjZSBpZGVudGlmaWVyLgotICAgICAqIEBwYXJhbSBlbmNvZGluZyBUaGUgYXV0by1kZXRlY3RlZCBJQU5BIGVuY29kaW5nIG5hbWUgb2YgdGhlIGVudGl0eQotICAgICAqICAgICAgICAgICAgICAgICBzdHJlYW0uIFRoaXMgdmFsdWUgd2lsbCBiZSBudWxsIGluIHRob3NlIHNpdHVhdGlvbnMKLSAgICAgKiAgICAgICAgICAgICAgICAgd2hlcmUgdGhlIGVudGl0eSBlbmNvZGluZyBpcyBub3QgYXV0by1kZXRlY3RlZCAoZS5nLgotICAgICAqICAgICAgICAgICAgICAgICBpbnRlcm5hbCBlbnRpdGllcyBvciBhIGRvY3VtZW50IGVudGl0eSB0aGF0IGlzCi0gICAgICogICAgICAgICAgICAgICAgIHBhcnNlZCBmcm9tIGEgamF2YS5pby5SZWFkZXIpLgotICAgICAqIEBwYXJhbSBhdWdzICAgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnRHZW5lcmFsRW50aXR5KFN0cmluZyBuYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxSZXNvdXJjZUlkZW50aWZpZXIgaWRlbnRpZmllciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGVuY29kaW5nLCBBdWdtZW50YXRpb25zIGF1Z3MpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBpZiAoZkRvY3VtZW50SGFuZGxlciAhPSBudWxsICYmICFmT25seVBhc3NQcmVmaXhNYXBwaW5nRXZlbnRzKSB7Ci0gICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLnN0YXJ0R2VuZXJhbEVudGl0eShuYW1lLCBpZGVudGlmaWVyLCBlbmNvZGluZywgYXVncyk7Ci0gICAgICAgIH0KLSAgICB9IC8vIHN0YXJ0RW50aXR5KFN0cmluZyxTdHJpbmcsU3RyaW5nLFN0cmluZyxTdHJpbmcpCi0KLSAgICAvKioKLSAgICAgKiBOb3RpZmllcyBvZiB0aGUgcHJlc2VuY2Ugb2YgYSBUZXh0RGVjbCBsaW5lIGluIGFuIGVudGl0eS4gSWYgcHJlc2VudCwKLSAgICAgKiB0aGlzIG1ldGhvZCB3aWxsIGJlIGNhbGxlZCBpbW1lZGlhdGVseSBmb2xsb3dpbmcgdGhlIHN0YXJ0RW50aXR5IGNhbGwuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGlzIG1ldGhvZCB3aWxsIG5ldmVyIGJlIGNhbGxlZCBmb3IgdGhlCi0gICAgICogZG9jdW1lbnQgZW50aXR5OyBpdCBpcyBvbmx5IGNhbGxlZCBmb3IgZXh0ZXJuYWwgZ2VuZXJhbCBlbnRpdGllcwotICAgICAqIHJlZmVyZW5jZWQgaW4gZG9jdW1lbnQgY29udGVudC4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoaXMgbWV0aG9kIGlzIG5vdCBjYWxsZWQgZm9yIGVudGl0eSByZWZlcmVuY2VzCi0gICAgICogYXBwZWFyaW5nIGFzIHBhcnQgb2YgYXR0cmlidXRlIHZhbHVlcy4KLSAgICAgKgotICAgICAqIEBwYXJhbSB2ZXJzaW9uICBUaGUgWE1MIHZlcnNpb24sIG9yIG51bGwgaWYgbm90IHNwZWNpZmllZC4KLSAgICAgKiBAcGFyYW0gZW5jb2RpbmcgVGhlIElBTkEgZW5jb2RpbmcgbmFtZSBvZiB0aGUgZW50aXR5LgotICAgICAqIEBwYXJhbSBhdWdzICAgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdGV4dERlY2woU3RyaW5nIHZlcnNpb24sIFN0cmluZyBlbmNvZGluZywgQXVnbWVudGF0aW9ucyBhdWdzKQotICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKGZEb2N1bWVudEhhbmRsZXIgIT0gbnVsbCAmJiAhZk9ubHlQYXNzUHJlZml4TWFwcGluZ0V2ZW50cykgewotICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci50ZXh0RGVjbCh2ZXJzaW9uLCBlbmNvZGluZywgYXVncyk7Ci0gICAgICAgIH0KLSAgICB9IC8vIHRleHREZWNsKFN0cmluZyxTdHJpbmcpCi0KLSAgICAvKioKLSAgICAgKiBUaGUgc3RhcnQgb2YgdGhlIGRvY3VtZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIGxvY2F0b3IgIFRoZSBzeXN0ZW0gaWRlbnRpZmllciBvZiB0aGUgZW50aXR5IGlmIHRoZSBlbnRpdHkKLSAgICAgKiAgICAgICAgICAgICAgICAgaXMgZXh0ZXJuYWwsIG51bGwgb3RoZXJ3aXNlLgotICAgICAqIEBwYXJhbSBlbmNvZGluZyBUaGUgYXV0by1kZXRlY3RlZCBJQU5BIGVuY29kaW5nIG5hbWUgb2YgdGhlIGVudGl0eQotICAgICAqICAgICAgICAgICAgICAgICBzdHJlYW0uIFRoaXMgdmFsdWUgd2lsbCBiZSBudWxsIGluIHRob3NlIHNpdHVhdGlvbnMKLSAgICAgKiAgICAgICAgICAgICAgICAgd2hlcmUgdGhlIGVudGl0eSBlbmNvZGluZyBpcyBub3QgYXV0by1kZXRlY3RlZCAoZS5nLgotICAgICAqICAgICAgICAgICAgICAgICBpbnRlcm5hbCBlbnRpdGllcyBvciBhIGRvY3VtZW50IGVudGl0eSB0aGF0IGlzCi0gICAgICogICAgICAgICAgICAgICAgIHBhcnNlZCBmcm9tIGEgamF2YS5pby5SZWFkZXIpLgotICAgICAqIEBwYXJhbSBuYW1lc3BhY2VDb250ZXh0Ci0gICAgICogICAgICAgICAgICAgICAgIFRoZSBuYW1lc3BhY2UgY29udGV4dCBpbiBlZmZlY3QgYXQgdGhlCi0gICAgICogICAgICAgICAgICAgICAgIHN0YXJ0IG9mIHRoaXMgZG9jdW1lbnQuCi0gICAgICogICAgICAgICAgICAgICAgIFRoaXMgb2JqZWN0IHJlcHJlc2VudHMgdGhlIGN1cnJlbnQgY29udGV4dC4KLSAgICAgKiAgICAgICAgICAgICAgICAgSW1wbGVtZW50b3JzIG9mIHRoaXMgY2xhc3MgYXJlIHJlc3BvbnNpYmxlCi0gICAgICogICAgICAgICAgICAgICAgIGZvciBjb3B5aW5nIHRoZSBuYW1lc3BhY2UgYmluZGluZ3MgZnJvbSB0aGUKLSAgICAgKiAgICAgICAgICAgICAgICAgdGhlIGN1cnJlbnQgY29udGV4dCAoYW5kIGl0cyBwYXJlbnQgY29udGV4dHMpCi0gICAgICogICAgICAgICAgICAgICAgIGlmIHRoYXQgaW5mb3JtYXRpb24gaXMgaW1wb3J0YW50LgotICAgICAqIEBwYXJhbSBhdWdzICAgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgICAgIHB1YmxpYyB2b2lkIHN0YXJ0RG9jdW1lbnQoWE1MTG9jYXRvciBsb2NhdG9yLCBTdHJpbmcgZW5jb2RpbmcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5hbWVzcGFjZUNvbnRleHQgbmFtZXNwYWNlQ29udGV4dCwgQXVnbWVudGF0aW9ucyBhdWdzKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgICAgICAgICBmTmFtZXNwYWNlQ29udGV4dCA9IG5hbWVzcGFjZUNvbnRleHQ7Ci0KLSAgICAgICAgICAgICAgICBpZiAoZkRvY3VtZW50SGFuZGxlciAhPSBudWxsICYmICFmT25seVBhc3NQcmVmaXhNYXBwaW5nRXZlbnRzKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLnN0YXJ0RG9jdW1lbnQobG9jYXRvciwgZW5jb2RpbmcsIG5hbWVzcGFjZUNvbnRleHQsIGF1Z3MpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgfSAvLyBzdGFydERvY3VtZW50KFhNTExvY2F0b3IsU3RyaW5nKQotCi0gICAgLyoqCi0gICAgICogTm90aWZpZXMgb2YgdGhlIHByZXNlbmNlIG9mIGFuIFhNTERlY2wgbGluZSBpbiB0aGUgZG9jdW1lbnQuIElmCi0gICAgICogcHJlc2VudCwgdGhpcyBtZXRob2Qgd2lsbCBiZSBjYWxsZWQgaW1tZWRpYXRlbHkgZm9sbG93aW5nIHRoZQotICAgICAqIHN0YXJ0RG9jdW1lbnQgY2FsbC4KLSAgICAgKgotICAgICAqIEBwYXJhbSB2ZXJzaW9uICAgIFRoZSBYTUwgdmVyc2lvbi4KLSAgICAgKiBAcGFyYW0gZW5jb2RpbmcgICBUaGUgSUFOQSBlbmNvZGluZyBuYW1lIG9mIHRoZSBkb2N1bWVudCwgb3IgbnVsbCBpZgotICAgICAqICAgICAgICAgICAgICAgICAgIG5vdCBzcGVjaWZpZWQuCi0gICAgICogQHBhcmFtIHN0YW5kYWxvbmUgVGhlIHN0YW5kYWxvbmUgdmFsdWUsIG9yIG51bGwgaWYgbm90IHNwZWNpZmllZC4KLSAgICAgKiBAcGFyYW0gYXVncyAgICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHhtbERlY2woU3RyaW5nIHZlcnNpb24sIFN0cmluZyBlbmNvZGluZywgU3RyaW5nIHN0YW5kYWxvbmUsIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChmRG9jdW1lbnRIYW5kbGVyICE9IG51bGwgJiYgIWZPbmx5UGFzc1ByZWZpeE1hcHBpbmdFdmVudHMpIHsKLSAgICAgICAgICAgIGZEb2N1bWVudEhhbmRsZXIueG1sRGVjbCh2ZXJzaW9uLCBlbmNvZGluZywgc3RhbmRhbG9uZSwgYXVncyk7Ci0gICAgICAgIH0KLSAgICB9IC8vIHhtbERlY2woU3RyaW5nLFN0cmluZyxTdHJpbmcpCi0KLSAgICAvKioKLSAgICAgKiBOb3RpZmllcyBvZiB0aGUgcHJlc2VuY2Ugb2YgdGhlIERPQ1RZUEUgbGluZSBpbiB0aGUgZG9jdW1lbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcm9vdEVsZW1lbnQgVGhlIG5hbWUgb2YgdGhlIHJvb3QgZWxlbWVudC4KLSAgICAgKiBAcGFyYW0gcHVibGljSWQgICAgVGhlIHB1YmxpYyBpZGVudGlmaWVyIGlmIGFuIGV4dGVybmFsIERURCBvciBudWxsCi0gICAgICogICAgICAgICAgICAgICAgICAgIGlmIHRoZSBleHRlcm5hbCBEVEQgaXMgc3BlY2lmaWVkIHVzaW5nIFNZU1RFTS4KLSAgICAgKiBAcGFyYW0gc3lzdGVtSWQgICAgVGhlIHN5c3RlbSBpZGVudGlmaWVyIGlmIGFuIGV4dGVybmFsIERURCwgbnVsbAotICAgICAqICAgICAgICAgICAgICAgICAgICBvdGhlcndpc2UuCi0gICAgICogQHBhcmFtIGF1Z3MgICAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBkb2N0eXBlRGVjbChTdHJpbmcgcm9vdEVsZW1lbnQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHB1YmxpY0lkLCBTdHJpbmcgc3lzdGVtSWQsIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChmRG9jdW1lbnRIYW5kbGVyICE9IG51bGwgJiYgIWZPbmx5UGFzc1ByZWZpeE1hcHBpbmdFdmVudHMpIHsKLSAgICAgICAgICAgIGZEb2N1bWVudEhhbmRsZXIuZG9jdHlwZURlY2wocm9vdEVsZW1lbnQsIHB1YmxpY0lkLCBzeXN0ZW1JZCwgYXVncyk7Ci0gICAgICAgIH0KLSAgICB9IC8vIGRvY3R5cGVEZWNsKFN0cmluZyxTdHJpbmcsU3RyaW5nKQotCi0gICAgLyoqCi0gICAgICogQSBjb21tZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIHRleHQgVGhlIHRleHQgaW4gdGhlIGNvbW1lbnQuCi0gICAgICogQHBhcmFtIGF1Z3MgICAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBhcHBsaWNhdGlvbiB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY29tbWVudChYTUxTdHJpbmcgdGV4dCwgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKGZEb2N1bWVudEhhbmRsZXIgIT0gbnVsbCAmJiAhZk9ubHlQYXNzUHJlZml4TWFwcGluZ0V2ZW50cykgewotICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci5jb21tZW50KHRleHQsIGF1Z3MpOwotICAgICAgICB9Ci0gICAgfSAvLyBjb21tZW50KFhNTFN0cmluZykKLQotICAgIC8qKgotICAgICAqIEEgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbi4gUHJvY2Vzc2luZyBpbnN0cnVjdGlvbnMgY29uc2lzdCBvZiBhCi0gICAgICogdGFyZ2V0IG5hbWUgYW5kLCBvcHRpb25hbGx5LCB0ZXh0IGRhdGEuIFRoZSBkYXRhIGlzIG9ubHkgbWVhbmluZ2Z1bAotICAgICAqIHRvIHRoZSBhcHBsaWNhdGlvbi4KLSAgICAgKiA8cD4KLSAgICAgKiBUeXBpY2FsbHksIGEgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbidzIGRhdGEgd2lsbCBjb250YWluIGEgc2VyaWVzCi0gICAgICogb2YgcHNldWRvLWF0dHJpYnV0ZXMuIFRoZXNlIHBzZXVkby1hdHRyaWJ1dGVzIGZvbGxvdyB0aGUgZm9ybSBvZgotICAgICAqIGVsZW1lbnQgYXR0cmlidXRlcyBidXQgYXJlIDxzdHJvbmc+bm90PC9zdHJvbmc+IHBhcnNlZCBvciBwcmVzZW50ZWQKLSAgICAgKiB0byB0aGUgYXBwbGljYXRpb24gYXMgYW55dGhpbmcgb3RoZXIgdGhhbiB0ZXh0LiBUaGUgYXBwbGljYXRpb24gaXMKLSAgICAgKiByZXNwb25zaWJsZSBmb3IgcGFyc2luZyB0aGUgZGF0YS4KLSAgICAgKgotICAgICAqIEBwYXJhbSB0YXJnZXQgVGhlIHRhcmdldC4KLSAgICAgKiBAcGFyYW0gZGF0YSAgIFRoZSBkYXRhIG9yIG51bGwgaWYgbm9uZSBzcGVjaWZpZWQuCi0gICAgICogQHBhcmFtIGF1Z3MgICAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oU3RyaW5nIHRhcmdldCwgWE1MU3RyaW5nIGRhdGEsIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChmRG9jdW1lbnRIYW5kbGVyICE9IG51bGwgJiYgIWZPbmx5UGFzc1ByZWZpeE1hcHBpbmdFdmVudHMpIHsKLSAgICAgICAgICAgIGZEb2N1bWVudEhhbmRsZXIucHJvY2Vzc2luZ0luc3RydWN0aW9uKHRhcmdldCwgZGF0YSwgYXVncyk7Ci0gICAgICAgIH0KLSAgICB9IC8vIHByb2Nlc3NpbmdJbnN0cnVjdGlvbihTdHJpbmcsWE1MU3RyaW5nKQotCi0KLSAgICAvKioKLSAgICAgKiBCaW5kcyB0aGUgbmFtZXNwYWNlcy4gVGhpcyBtZXRob2Qgd2lsbCBoYW5kbGUgY2FsbGluZyB0aGUKLSAgICAgKiBkb2N1bWVudCBoYW5kbGVyIHRvIHN0YXJ0IHRoZSBwcmVmaXggbWFwcGluZ3MuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGlzIG1ldGhvZCBtYWtlcyB1c2Ugb2YgdGhlCi0gICAgICogZkF0dHJpYnV0ZVFOYW1lIHZhcmlhYmxlLiBBbnkgY29udGVudHMgb2YgdGhlIHZhcmlhYmxlIHdpbGwKLSAgICAgKiBiZSBkZXN0cm95ZWQuIENhbGxlciBzaG91bGQgY29weSB0aGUgdmFsdWVzIG91dCBvZiB0aGlzCi0gICAgICogdGVtcG9yYXJ5IHZhcmlhYmxlIGJlZm9yZSBjYWxsaW5nIHRoaXMgbWV0aG9kLgotICAgICAqCi0gICAgICogQHBhcmFtIGVsZW1lbnQgICAgVGhlIG5hbWUgb2YgdGhlIGVsZW1lbnQuCi0gICAgICogQHBhcmFtIGF0dHJpYnV0ZXMgVGhlIGVsZW1lbnQgYXR0cmlidXRlcy4KLSAgICAgKiBAcGFyYW0gYXVncyAgICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudChRTmFtZSBlbGVtZW50LCBYTUxBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMsIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgaWYgKGZOYW1lc3BhY2VzKSB7Ci0gICAgICAgICAgICBoYW5kbGVTdGFydEVsZW1lbnQoZWxlbWVudCwgYXR0cmlidXRlcywgYXVncywgZmFsc2UpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKGZEb2N1bWVudEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci5zdGFydEVsZW1lbnQoZWxlbWVudCwgYXR0cmlidXRlcywgYXVncyk7Ci0gICAgICAgIH0KLQotCi0gICAgfSAvLyBzdGFydEVsZW1lbnQoUU5hbWUsWE1MQXR0cmlidXRlcykKLQotICAgIC8qKgotICAgICAqIEFuIGVtcHR5IGVsZW1lbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZWxlbWVudCAgICBUaGUgbmFtZSBvZiB0aGUgZWxlbWVudC4KLSAgICAgKiBAcGFyYW0gYXR0cmlidXRlcyBUaGUgZWxlbWVudCBhdHRyaWJ1dGVzLgotICAgICAqIEBwYXJhbSBhdWdzICAgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW1wdHlFbGVtZW50KFFOYW1lIGVsZW1lbnQsIFhNTEF0dHJpYnV0ZXMgYXR0cmlidXRlcywgQXVnbWVudGF0aW9ucyBhdWdzKQotICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLQotICAgICAgICBpZiAoZk5hbWVzcGFjZXMpIHsKLSAgICAgICAgICAgIGhhbmRsZVN0YXJ0RWxlbWVudChlbGVtZW50LCBhdHRyaWJ1dGVzLCBhdWdzLCB0cnVlKTsKLSAgICAgICAgICAgIGhhbmRsZUVuZEVsZW1lbnQoZWxlbWVudCwgYXVncywgdHJ1ZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoZkRvY3VtZW50SGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLmVtcHR5RWxlbWVudChlbGVtZW50LCBhdHRyaWJ1dGVzLCBhdWdzKTsKLSAgICAgICAgfQotCi0gICAgfSAvLyBlbXB0eUVsZW1lbnQoUU5hbWUsWE1MQXR0cmlidXRlcykKLQotICAgIC8qKgotICAgICAqIENoYXJhY3RlciBjb250ZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIHRleHQgVGhlIGNvbnRlbnQuCi0gICAgICogQHBhcmFtIGF1Z3MgICAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBjaGFyYWN0ZXJzKFhNTFN0cmluZyB0ZXh0LCBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBpZiAoZkRvY3VtZW50SGFuZGxlciAhPSBudWxsICYmICFmT25seVBhc3NQcmVmaXhNYXBwaW5nRXZlbnRzKSB7Ci0gICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLmNoYXJhY3RlcnModGV4dCwgYXVncyk7Ci0gICAgICAgIH0KLSAgICB9IC8vIGNoYXJhY3RlcnMoWE1MU3RyaW5nKQotCi0gICAgLyoqCi0gICAgICogSWdub3JhYmxlIHdoaXRlc3BhY2UuIEZvciB0aGlzIG1ldGhvZCB0byBiZSBjYWxsZWQsIHRoZSBkb2N1bWVudAotICAgICAqIHNvdXJjZSBtdXN0IGhhdmUgc29tZSB3YXkgb2YgZGV0ZXJtaW5pbmcgdGhhdCB0aGUgdGV4dCBjb250YWluaW5nCi0gICAgICogb25seSB3aGl0ZXNwYWNlIGNoYXJhY3RlcnMgc2hvdWxkIGJlIGNvbnNpZGVyZWQgaWdub3JhYmxlLiBGb3IKLSAgICAgKiBleGFtcGxlLCB0aGUgdmFsaWRhdG9yIGNhbiBkZXRlcm1pbmUgaWYgYSBsZW5ndGggb2Ygd2hpdGVzcGFjZQotICAgICAqIGNoYXJhY3RlcnMgaW4gdGhlIGRvY3VtZW50IGFyZSBpZ25vcmFibGUgYmFzZWQgb24gdGhlIGVsZW1lbnQKLSAgICAgKiBjb250ZW50IG1vZGVsLgotICAgICAqCi0gICAgICogQHBhcmFtIHRleHQgVGhlIGlnbm9yYWJsZSB3aGl0ZXNwYWNlLgotICAgICAqIEBwYXJhbSBhdWdzICAgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgaWdub3JhYmxlV2hpdGVzcGFjZShYTUxTdHJpbmcgdGV4dCwgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKGZEb2N1bWVudEhhbmRsZXIgIT0gbnVsbCAmJiAhZk9ubHlQYXNzUHJlZml4TWFwcGluZ0V2ZW50cykgewotICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci5pZ25vcmFibGVXaGl0ZXNwYWNlKHRleHQsIGF1Z3MpOwotICAgICAgICB9Ci0gICAgfSAvLyBpZ25vcmFibGVXaGl0ZXNwYWNlKFhNTFN0cmluZykKLQotICAgIC8qKgotICAgICAqIFRoZSBlbmQgb2YgYW4gZWxlbWVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlbGVtZW50IFRoZSBuYW1lIG9mIHRoZSBlbGVtZW50LgotICAgICAqIEBwYXJhbSBhdWdzICAgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kRWxlbWVudChRTmFtZSBlbGVtZW50LCBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotCi0gICAgICAgIGlmIChmTmFtZXNwYWNlcykgewotICAgICAgICAgICAgaGFuZGxlRW5kRWxlbWVudChlbGVtZW50LCBhdWdzLCBmYWxzZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoZkRvY3VtZW50SGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLmVuZEVsZW1lbnQoZWxlbWVudCwgYXVncyk7Ci0gICAgICAgIH0KLQotICAgIH0gLy8gZW5kRWxlbWVudChRTmFtZSkKLQotICAgIC8qKgotICAgICAqIFRoZSBzdGFydCBvZiBhIENEQVRBIHNlY3Rpb24uCi0gICAgICogQHBhcmFtIGF1Z3MgICAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydENEQVRBKEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChmRG9jdW1lbnRIYW5kbGVyICE9IG51bGwgJiYgIWZPbmx5UGFzc1ByZWZpeE1hcHBpbmdFdmVudHMpIHsKLSAgICAgICAgICAgIGZEb2N1bWVudEhhbmRsZXIuc3RhcnRDREFUQShhdWdzKTsKLSAgICAgICAgfQotICAgIH0gLy8gc3RhcnRDREFUQSgpCi0KLSAgICAvKioKLSAgICAgKiBUaGUgZW5kIG9mIGEgQ0RBVEEgc2VjdGlvbi4KLSAgICAgKiBAcGFyYW0gYXVncyAgICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZENEQVRBKEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChmRG9jdW1lbnRIYW5kbGVyICE9IG51bGwgJiYgIWZPbmx5UGFzc1ByZWZpeE1hcHBpbmdFdmVudHMpIHsKLSAgICAgICAgICAgIGZEb2N1bWVudEhhbmRsZXIuZW5kQ0RBVEEoYXVncyk7Ci0gICAgICAgIH0KLSAgICB9IC8vIGVuZENEQVRBKCkKLQotICAgIC8qKgotICAgICAqIFRoZSBlbmQgb2YgdGhlIGRvY3VtZW50LgotICAgICAqIEBwYXJhbSBhdWdzICAgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kRG9jdW1lbnQoQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKGZEb2N1bWVudEhhbmRsZXIgIT0gbnVsbCAmJiAhZk9ubHlQYXNzUHJlZml4TWFwcGluZ0V2ZW50cykgewotICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci5lbmREb2N1bWVudChhdWdzKTsKLSAgICAgICAgfQotICAgIH0gLy8gZW5kRG9jdW1lbnQoKQotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2Qgbm90aWZpZXMgdGhlIGVuZCBvZiBhIGdlbmVyYWwgZW50aXR5LgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gVGhpcyBtZXRob2QgaXMgbm90IGNhbGxlZCBmb3IgZW50aXR5IHJlZmVyZW5jZXMKLSAgICAgKiBhcHBlYXJpbmcgYXMgcGFydCBvZiBhdHRyaWJ1dGUgdmFsdWVzLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgICBUaGUgbmFtZSBvZiB0aGUgZW50aXR5LgotICAgICAqIEBwYXJhbSBhdWdzICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBYTklFeGNlcHRpb24KLSAgICAgKiAgICAgICAgICAgICAgICAgICBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kR2VuZXJhbEVudGl0eShTdHJpbmcgbmFtZSwgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKGZEb2N1bWVudEhhbmRsZXIgIT0gbnVsbCAmJiAhZk9ubHlQYXNzUHJlZml4TWFwcGluZ0V2ZW50cykgewotICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci5lbmRHZW5lcmFsRW50aXR5KG5hbWUsIGF1Z3MpOwotICAgICAgICB9Ci0gICAgfSAvLyBlbmRFbnRpdHkoU3RyaW5nKQotCi0gICAgLy8KLSAgICAvLyBQcm90ZWN0ZWQgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKiogSGFuZGxlcyBzdGFydCBlbGVtZW50LiAqLwotICAgIHByb3RlY3RlZCB2b2lkIGhhbmRsZVN0YXJ0RWxlbWVudChRTmFtZSBlbGVtZW50LCBYTUxBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF1Z21lbnRhdGlvbnMgYXVncywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBpc0VtcHR5KSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLQotICAgICAgICAvLyBhZGQgbmV3IG5hbWVzcGFjZSBjb250ZXh0Ci0gICAgICAgIGZOYW1lc3BhY2VDb250ZXh0LnB1c2hDb250ZXh0KCk7Ci0KLSAgICAgICAgaWYgKGVsZW1lbnQucHJlZml4ID09IFhNTFN5bWJvbHMuUFJFRklYX1hNTE5TKSB7Ci0gICAgICAgICAgICBmRXJyb3JSZXBvcnRlci5yZXBvcnRFcnJvcihYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTE5TX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJFbGVtZW50WE1MTlNQcmVmaXgiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde2VsZW1lbnQucmF3bmFtZX0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxFcnJvclJlcG9ydGVyLlNFVkVSSVRZX0ZBVEFMX0VSUk9SKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIHNlYXJjaCBmb3IgbmV3IG5hbWVzcGFjZSBiaW5kaW5ncwotICAgICAgICBpbnQgbGVuZ3RoID0gYXR0cmlidXRlcy5nZXRMZW5ndGgoKTsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykgewotICAgICAgICAgICAgU3RyaW5nIGxvY2FscGFydCA9IGF0dHJpYnV0ZXMuZ2V0TG9jYWxOYW1lKGkpOwotICAgICAgICAgICAgU3RyaW5nIHByZWZpeCA9IGF0dHJpYnV0ZXMuZ2V0UHJlZml4KGkpOwotICAgICAgICAgICAgLy8gd2hlbiBpdCdzIG9mIGZvcm0geG1sbnM9Ii4uLiIgb3IgeG1sbnM6cHJlZml4PSIuLi4iLAotICAgICAgICAgICAgLy8gaXQncyBhIG5hbWVzcGFjZSBkZWNsYXJhdGlvbi4gYnV0IHByZWZpeDp4bWxucz0iLi4uIiBpc24ndC4KLSAgICAgICAgICAgIGlmIChwcmVmaXggPT0gWE1MU3ltYm9scy5QUkVGSVhfWE1MTlMgfHwKLSAgICAgICAgICAgICAgICBwcmVmaXggPT0gWE1MU3ltYm9scy5FTVBUWV9TVFJJTkcgJiYgbG9jYWxwYXJ0ID09IFhNTFN5bWJvbHMuUFJFRklYX1hNTE5TKSB7Ci0KLSAgICAgICAgICAgICAgICAvLyBnZXQgdGhlIGludGVybmFsaXplZCB2YWx1ZSBvZiB0aGlzIGF0dHJpYnV0ZQotICAgICAgICAgICAgICAgIFN0cmluZyB1cmkgPSBmU3ltYm9sVGFibGUuYWRkU3ltYm9sKGF0dHJpYnV0ZXMuZ2V0VmFsdWUoaSkpOwotCi0gICAgICAgICAgICAgICAgLy8gMS4gInhtbG5zIiBjYW4ndCBiZSBib3VuZCB0byBhbnkgbmFtZXNwYWNlCi0gICAgICAgICAgICAgICAgaWYgKHByZWZpeCA9PSBYTUxTeW1ib2xzLlBSRUZJWF9YTUxOUyAmJiBsb2NhbHBhcnQgPT0gWE1MU3ltYm9scy5QUkVGSVhfWE1MTlMpIHsKLSAgICAgICAgICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxOU19ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDYW50QmluZFhNTE5TIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde2F0dHJpYnV0ZXMuZ2V0UU5hbWUoaSl9LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxFcnJvclJlcG9ydGVyLlNFVkVSSVRZX0ZBVEFMX0VSUk9SKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyAyLiB0aGUgbmFtZXNwYWNlIGZvciAieG1sbnMiIGNhbid0IGJlIGJvdW5kIHRvIGFueSBwcmVmaXgKLSAgICAgICAgICAgICAgICBpZiAodXJpID09IE5hbWVzcGFjZUNvbnRleHQuWE1MTlNfVVJJKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MTlNfRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ2FudEJpbmRYTUxOUyIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXthdHRyaWJ1dGVzLmdldFFOYW1lKGkpfSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9GQVRBTF9FUlJPUik7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgLy8gMy4gInhtbCIgY2FuJ3QgYmUgYm91bmQgdG8gYW55IG90aGVyIG5hbWVzcGFjZSB0aGFuIGl0J3Mgb3duCi0gICAgICAgICAgICAgICAgaWYgKGxvY2FscGFydCA9PSBYTUxTeW1ib2xzLlBSRUZJWF9YTUwpIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKHVyaSAhPSBOYW1lc3BhY2VDb250ZXh0LlhNTF9VUkkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MTlNfRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNhbnRCaW5kWE1MIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXthdHRyaWJ1dGVzLmdldFFOYW1lKGkpfSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTEVycm9yUmVwb3J0ZXIuU0VWRVJJVFlfRkFUQUxfRVJST1IpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIC8vIDQuIHRoZSBuYW1lc3BhY2UgZm9yICJ4bWwiIGNhbid0IGJlIGJvdW5kIHRvIGFueSBvdGhlciBwcmVmaXgKLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKHVyaSA9PU5hbWVzcGFjZUNvbnRleHQuWE1MX1VSSSkgewotICAgICAgICAgICAgICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxOU19ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ2FudEJpbmRYTUwiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde2F0dHJpYnV0ZXMuZ2V0UU5hbWUoaSl9LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9GQVRBTF9FUlJPUik7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBwcmVmaXggPSBsb2NhbHBhcnQgIT0gWE1MU3ltYm9scy5QUkVGSVhfWE1MTlMgPyBsb2NhbHBhcnQgOiBYTUxTeW1ib2xzLkVNUFRZX1NUUklORzsKLQotICAgICAgICAgICAgICAgIC8vIGh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTkvUkVDLXhtbC1uYW1lcy0xOTk5MDExNC8jZHQtcHJlZml4Ci0gICAgICAgICAgICAgICAgLy8gV2Ugc2hvdWxkIG9ubHkgcmVwb3J0IGFuIGVycm9yIGlmIHRoZXJlIGlzIGEgcHJlZml4LAotICAgICAgICAgICAgICAgIC8vIHRoYXQgaXMsIHRoZSBsb2NhbCBwYXJ0IGlzIG5vdCAieG1sbnMiLiAtU0cKLSAgICAgICAgICAgICAgICAvLyBTaW5jZSB0aGlzIGlzIGFuIGVycm9yIGNvbmRpdGlvbiBpbiBYTUwgMS4wLAotICAgICAgICAgICAgICAgIC8vIGFuZCBzaG91bGQgYmUgcmVsYXRpdmVseSB1bmNvbW1vbiBpbiBYTUwgMS4xLAotICAgICAgICAgICAgICAgIC8vIG1ha2luZyB0aGlzIHRlc3QgaW50byBhIG1ldGhvZCBjYWxsIHRvIHJldXNlIGNvZGUKLSAgICAgICAgICAgICAgICAvLyBzaG91bGQgYmUgYWNjZXB0YWJsZS4gIC0gTkcKLSAgICAgICAgICAgICAgICBpZihwcmVmaXhCb3VuZFRvTnVsbFVSSSh1cmksIGxvY2FscGFydCkpIHsKLSAgICAgICAgICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxOU19ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJFbXB0eVByZWZpeGVkQXR0TmFtZSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXthdHRyaWJ1dGVzLmdldFFOYW1lKGkpfSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9GQVRBTF9FUlJPUik7Ci0gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8vIGRlY2xhcmUgcHJlZml4IGluIGNvbnRleHQKLSAgICAgICAgICAgICAgICBmTmFtZXNwYWNlQ29udGV4dC5kZWNsYXJlUHJlZml4KHByZWZpeCwgdXJpLmxlbmd0aCgpICE9IDAgPyB1cmkgOiBudWxsKTsKLQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gYmluZCB0aGUgZWxlbWVudAotICAgICAgICBTdHJpbmcgcHJlZml4ID0gZWxlbWVudC5wcmVmaXggIT0gbnVsbAotICAgICAgICAgICAgICAgICAgICAgID8gZWxlbWVudC5wcmVmaXggOiBYTUxTeW1ib2xzLkVNUFRZX1NUUklORzsKLSAgICAgICAgZWxlbWVudC51cmkgPSBmTmFtZXNwYWNlQ29udGV4dC5nZXRVUkkocHJlZml4KTsKLSAgICAgICAgaWYgKGVsZW1lbnQucHJlZml4ID09IG51bGwgJiYgZWxlbWVudC51cmkgIT0gbnVsbCkgewotICAgICAgICAgICAgZWxlbWVudC5wcmVmaXggPSBYTUxTeW1ib2xzLkVNUFRZX1NUUklORzsKLSAgICAgICAgfQotICAgICAgICBpZiAoZWxlbWVudC5wcmVmaXggIT0gbnVsbCAmJiBlbGVtZW50LnVyaSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBmRXJyb3JSZXBvcnRlci5yZXBvcnRFcnJvcihYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTE5TX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJFbGVtZW50UHJlZml4VW5ib3VuZCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117ZWxlbWVudC5wcmVmaXgsIGVsZW1lbnQucmF3bmFtZX0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxFcnJvclJlcG9ydGVyLlNFVkVSSVRZX0ZBVEFMX0VSUk9SKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIGJpbmQgdGhlIGF0dHJpYnV0ZXMKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykgewotICAgICAgICAgICAgYXR0cmlidXRlcy5nZXROYW1lKGksIGZBdHRyaWJ1dGVRTmFtZSk7Ci0gICAgICAgICAgICBTdHJpbmcgYXByZWZpeCA9IGZBdHRyaWJ1dGVRTmFtZS5wcmVmaXggIT0gbnVsbAotICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBmQXR0cmlidXRlUU5hbWUucHJlZml4IDogWE1MU3ltYm9scy5FTVBUWV9TVFJJTkc7Ci0gICAgICAgICAgICBTdHJpbmcgYXJhd25hbWUgPSBmQXR0cmlidXRlUU5hbWUucmF3bmFtZTsKLSAgICAgICAgICAgIGlmIChhcmF3bmFtZSA9PSBYTUxTeW1ib2xzLlBSRUZJWF9YTUxOUykgewotICAgICAgICAgICAgICAgIGZBdHRyaWJ1dGVRTmFtZS51cmkgPSBmTmFtZXNwYWNlQ29udGV4dC5nZXRVUkkoWE1MU3ltYm9scy5QUkVGSVhfWE1MTlMpOwotICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXMuc2V0TmFtZShpLCBmQXR0cmlidXRlUU5hbWUpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoYXByZWZpeCAhPSBYTUxTeW1ib2xzLkVNUFRZX1NUUklORykgewotICAgICAgICAgICAgICAgIGZBdHRyaWJ1dGVRTmFtZS51cmkgPSBmTmFtZXNwYWNlQ29udGV4dC5nZXRVUkkoYXByZWZpeCk7Ci0gICAgICAgICAgICAgICAgaWYgKGZBdHRyaWJ1dGVRTmFtZS51cmkgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBmRXJyb3JSZXBvcnRlci5yZXBvcnRFcnJvcihYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTE5TX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkF0dHJpYnV0ZVByZWZpeFVuYm91bmQiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117ZWxlbWVudC5yYXduYW1lLGFyYXduYW1lLGFwcmVmaXh9LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxFcnJvclJlcG9ydGVyLlNFVkVSSVRZX0ZBVEFMX0VSUk9SKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgYXR0cmlidXRlcy5zZXROYW1lKGksIGZBdHRyaWJ1dGVRTmFtZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyB2ZXJpZnkgdGhhdCBkdXBsaWNhdGUgYXR0cmlidXRlcyBkb24ndCBleGlzdAotICAgICAgICAvLyBFeGFtcGxlOiA8Zm9vIHhtbG5zOmE9J05TJyB4bWxuczpiPSdOUycgYTphdHRyPSd2MScgYjphdHRyPSd2MicvPgotICAgICAgICBpbnQgYXR0ckNvdW50ID0gYXR0cmlidXRlcy5nZXRMZW5ndGgoKTsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhdHRyQ291bnQgLSAxOyBpKyspIHsKLSAgICAgICAgICAgIFN0cmluZyBhdXJpID0gYXR0cmlidXRlcy5nZXRVUkkoaSk7Ci0gICAgICAgICAgICBpZiAoYXVyaSA9PSBudWxsIHx8IGF1cmkgPT0gTmFtZXNwYWNlQ29udGV4dC5YTUxOU19VUkkpIHsKLSAgICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIFN0cmluZyBhbG9jYWxwYXJ0ID0gYXR0cmlidXRlcy5nZXRMb2NhbE5hbWUoaSk7Ci0gICAgICAgICAgICBmb3IgKGludCBqID0gaSArIDE7IGogPCBhdHRyQ291bnQ7IGorKykgewotICAgICAgICAgICAgICAgIFN0cmluZyBibG9jYWxwYXJ0ID0gYXR0cmlidXRlcy5nZXRMb2NhbE5hbWUoaik7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIGJ1cmkgPSBhdHRyaWJ1dGVzLmdldFVSSShqKTsKLSAgICAgICAgICAgICAgICBpZiAoYWxvY2FscGFydCA9PSBibG9jYWxwYXJ0ICYmIGF1cmkgPT0gYnVyaSkgewotICAgICAgICAgICAgICAgICAgICBmRXJyb3JSZXBvcnRlci5yZXBvcnRFcnJvcihYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTE5TX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkF0dHJpYnV0ZU5TTm90VW5pcXVlIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde2VsZW1lbnQucmF3bmFtZSxhbG9jYWxwYXJ0LCBhdXJpfSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9GQVRBTF9FUlJPUik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gY2FsbCBoYW5kbGVyCi0gICAgICAgIGlmIChmRG9jdW1lbnRIYW5kbGVyICE9IG51bGwgJiYgIWZPbmx5UGFzc1ByZWZpeE1hcHBpbmdFdmVudHMpIHsKLSAgICAgICAgICAgIGlmIChpc0VtcHR5KSB7Ci0gICAgICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci5lbXB0eUVsZW1lbnQoZWxlbWVudCwgYXR0cmlidXRlcywgYXVncyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLnN0YXJ0RWxlbWVudChlbGVtZW50LCBhdHRyaWJ1dGVzLCBhdWdzKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0KLSAgICB9IC8vIGhhbmRsZVN0YXJ0RWxlbWVudChRTmFtZSxYTUxBdHRyaWJ1dGVzLGJvb2xlYW4pCi0KLSAgICAvKiogSGFuZGxlcyBlbmQgZWxlbWVudC4gKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCBoYW5kbGVFbmRFbGVtZW50KFFOYW1lIGVsZW1lbnQsIEF1Z21lbnRhdGlvbnMgYXVncywgYm9vbGVhbiBpc0VtcHR5KQotICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLQotICAgICAgICAvLyBiaW5kIGVsZW1lbnQKLSAgICAgICAgU3RyaW5nIGVwcmVmaXggPSBlbGVtZW50LnByZWZpeCAhPSBudWxsID8gZWxlbWVudC5wcmVmaXggOiBYTUxTeW1ib2xzLkVNUFRZX1NUUklORzsKLSAgICAgICAgZWxlbWVudC51cmkgPSBmTmFtZXNwYWNlQ29udGV4dC5nZXRVUkkoZXByZWZpeCk7Ci0gICAgICAgIGlmIChlbGVtZW50LnVyaSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBlbGVtZW50LnByZWZpeCA9IGVwcmVmaXg7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBjYWxsIGhhbmRsZXJzCi0gICAgICAgIGlmIChmRG9jdW1lbnRIYW5kbGVyICE9IG51bGwgJiYgIWZPbmx5UGFzc1ByZWZpeE1hcHBpbmdFdmVudHMpIHsKLSAgICAgICAgICAgIGlmICghaXNFbXB0eSkgewotICAgICAgICAgICAgICAgIGZEb2N1bWVudEhhbmRsZXIuZW5kRWxlbWVudChlbGVtZW50LCBhdWdzKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIHBvcCBjb250ZXh0Ci0gICAgICAgIGZOYW1lc3BhY2VDb250ZXh0LnBvcENvbnRleHQoKTsKLQotICAgIH0gLy8gaGFuZGxlRW5kRWxlbWVudChRTmFtZSxib29sZWFuKQotCi0gICAgLy8gcmV0dXJucyB0cnVlIGlmZiB0aGUgZ2l2ZW4gcHJlZml4IGlzIGJvdW5kIHRvICIiICphbmQqCi0gICAgLy8gdGhpcyBpcyBkaXNhbGxvd2VkIGJ5IHRoZSB2ZXJzaW9uIG9mIFhNTCBuYW1lc3BhY2VzIGluIHVzZS4KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBwcmVmaXhCb3VuZFRvTnVsbFVSSShTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxwYXJ0KSB7Ci0gICAgICAgIHJldHVybiAodXJpID09IFhNTFN5bWJvbHMuRU1QVFlfU1RSSU5HICYmIGxvY2FscGFydCAhPSBYTUxTeW1ib2xzLlBSRUZJWF9YTUxOUyk7Ci0gICAgfSAvLyBwcmVmaXhCb3VuZFRvTnVsbFVSSShTdHJpbmcsIFN0cmluZyk6ICBib29sZWFuCi0KLX0gLy8gY2xhc3MgWE1MTmFtZXNwYWNlQmluZGVyCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL1hNTFNjYW5uZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvWE1MU2Nhbm5lci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmYjEyYjQyLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvWE1MU2Nhbm5lci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTU1NyArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDE2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICovCi0KLS8qCi0gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKLSAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAotICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgotICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKLSAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCi0gKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbDsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5TdGF0dXM7Ci1pbXBvcnQgY29tLnN1bi54bWwuaW50ZXJuYWwuc3RyZWFtLlhNTEVudGl0eVN0b3JhZ2U7Ci1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uZXZlbnRzLlhNTEV2ZW50OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5tc2cuWE1MTWVzc2FnZUZvcm1hdHRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuU3ltYm9sVGFibGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlhNTENoYXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlhNTFJlc291cmNlSWRlbnRpZmllckltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlhNTFN0cmluZ0J1ZmZlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWxzLlhNTExpbWl0QW5hbHl6ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlscy5YTUxTZWN1cml0eU1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuQXVnbWVudGF0aW9uczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxBdHRyaWJ1dGVzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTFJlc291cmNlSWRlbnRpZmllcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxTdHJpbmc7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE5JRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxDb21wb25lbnQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTENvbXBvbmVudE1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi54bWwuaW50ZXJuYWwuc3RyZWFtLkVudGl0eTsKLQotLy9pbXBvcnQgY29tLnN1bi54bWwuc3RyZWFtLlhNTEVudGl0eU1hbmFnZXI7Ci0vL2ltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuWE1MRXJyb3JSZXBvcnRlcjsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGlzIHJlc3BvbnNpYmxlIGZvciBob2xkaW5nIHNjYW5uaW5nIG1ldGhvZHMgY29tbW9uIHRvCi0gKiBzY2FubmluZyB0aGUgWE1MIGRvY3VtZW50IHN0cnVjdHVyZSBhbmQgY29udGVudCBhcyB3ZWxsIGFzIHRoZSBEVEQKLSAqIHN0cnVjdHVyZSBhbmQgY29udGVudC4gQm90aCBYTUxEb2N1bWVudFNjYW5uZXIgYW5kIFhNTERURFNjYW5uZXIgaW5oZXJpdAotICogZnJvbSB0aGlzIGJhc2UgY2xhc3MuCi0gKgotICogPHA+Ci0gKiBUaGlzIGNvbXBvbmVudCByZXF1aXJlcyB0aGUgZm9sbG93aW5nIGZlYXR1cmVzIGFuZCBwcm9wZXJ0aWVzIGZyb20gdGhlCi0gKiBjb21wb25lbnQgbWFuYWdlciB0aGF0IHVzZXMgaXQ6Ci0gKiA8dWw+Ci0gKiAgPGxpPmh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy92YWxpZGF0aW9uPC9saT4KLSAqICA8bGk+aHR0cDovL2FwYWNoZS5vcmcveG1sL2ZlYXR1cmVzL3NjYW5uZXIvbm90aWZ5LWNoYXItcmVmczwvbGk+Ci0gKiAgPGxpPmh0dHA6Ly9hcGFjaGUub3JnL3htbC9wcm9wZXJ0aWVzL2ludGVybmFsL3N5bWJvbC10YWJsZTwvbGk+Ci0gKiAgPGxpPmh0dHA6Ly9hcGFjaGUub3JnL3htbC9wcm9wZXJ0aWVzL2ludGVybmFsL2Vycm9yLXJlcG9ydGVyPC9saT4KLSAqICA8bGk+aHR0cDovL2FwYWNoZS5vcmcveG1sL3Byb3BlcnRpZXMvaW50ZXJuYWwvZW50aXR5LW1hbmFnZXI8L2xpPgotICogPC91bD4KLSAqCi0gKiBAYXV0aG9yIEFuZHkgQ2xhcmssIElCTQotICogQGF1dGhvciBBcm5hdWQgIExlIEhvcnMsIElCTQotICogQGF1dGhvciBFcmljIFllLCBJQk0KLSAqIEBhdXRob3IgSy5WZW51Z29wYWwgU1VOIE1pY3Jvc3lzdGVtcwotICogQGF1dGhvciBTdW5pdGhhIFJlZGR5LCBTVU4gTWljcm9zeXN0ZW1zCi0gKiBAdmVyc2lvbiAkSWQ6IFhNTFNjYW5uZXIuamF2YSx2IDEuMTIgMjAxMC0xMS0wMSAwNDozOTo0MSBqb2VodyBFeHAgJAotICovCi1wdWJsaWMgYWJzdHJhY3QgY2xhc3MgWE1MU2Nhbm5lcgotICAgICAgICBpbXBsZW1lbnRzIFhNTENvbXBvbmVudCB7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0YW50cwotICAgIC8vCi0KLSAgICAvLyBmZWF0dXJlIGlkZW50aWZpZXJzCi0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiBuYW1lc3BhY2VzLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIE5BTUVTUEFDRVMgPQotICAgICAgICAgICAgQ29uc3RhbnRzLlNBWF9GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5OQU1FU1BBQ0VTX0ZFQVRVUkU7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiB2YWxpZGF0aW9uLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFZBTElEQVRJT04gPQotICAgICAgICAgICAgQ29uc3RhbnRzLlNBWF9GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5WQUxJREFUSU9OX0ZFQVRVUkU7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiBub3RpZnkgY2hhcmFjdGVyIHJlZmVyZW5jZXMuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgTk9USUZZX0NIQVJfUkVGUyA9Ci0gICAgICAgICAgICBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLk5PVElGWV9DSEFSX1JFRlNfRkVBVFVSRTsKLQotICAgIC8vIHByb3BlcnR5IGlkZW50aWZpZXJzCi0KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBQQVJTRVJfU0VUVElOR1MgPQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLlBBUlNFUl9TRVRUSU5HUzsKLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogc3ltYm9sIHRhYmxlLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFNZTUJPTF9UQUJMRSA9Ci0gICAgICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5TWU1CT0xfVEFCTEVfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogZXJyb3IgcmVwb3J0ZXIuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJST1JfUkVQT1JURVIgPQotICAgICAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuRVJST1JfUkVQT1JURVJfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogZW50aXR5IG1hbmFnZXIuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgRU5USVRZX01BTkFHRVIgPQotICAgICAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuRU5USVRZX01BTkFHRVJfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogU2VjdXJpdHkgbWFuYWdlci4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgU0VDVVJJVFlfTUFOQUdFUiA9IENvbnN0YW50cy5TRUNVUklUWV9NQU5BR0VSOwotCi0gICAgLy8gZGVidWdnaW5nCi0KLSAgICAvKiogRGVidWcgYXR0cmlidXRlIG5vcm1hbGl6YXRpb24uICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBib29sZWFuIERFQlVHX0FUVFJfTk9STUFMSVpBVElPTiA9IGZhbHNlOwotCi0gICAgLyoqCi0gICAgICogVHlwZSBvZiBuYW1lcwotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZW51bSBOYW1lVHlwZSB7Ci0gICAgICAgIEFUVFJJQlVURSgiYXR0cmlidXRlIiksCi0gICAgICAgIEFUVFJJQlVURU5BTUUoImF0dHJpYnV0ZSBuYW1lIiksCi0gICAgICAgIENPTU1FTlQoImNvbW1lbnQiKSwKLSAgICAgICAgRE9DVFlQRSgiZG9jdHlwZSIpLAotICAgICAgICBFTEVNRU5UU1RBUlQoInN0YXJ0ZWxlbWVudCIpLAotICAgICAgICBFTEVNRU5URU5EKCJlbmRlbGVtZW50IiksCi0gICAgICAgIEVOVElUWSgiZW50aXR5IiksCi0gICAgICAgIE5PVEFUSU9OKCJub3RhdGlvbiIpLAotICAgICAgICBQSSgicGkiKSwKLSAgICAgICAgUkVGRVJFTkNFKCJyZWZlcmVuY2UiKTsKLQotICAgICAgICBmaW5hbCBTdHJpbmcgbGl0ZXJhbDsKLSAgICAgICAgTmFtZVR5cGUoU3RyaW5nIGxpdGVyYWwpIHsKLSAgICAgICAgICAgIHRoaXMubGl0ZXJhbCA9IGxpdGVyYWw7Ci0gICAgICAgIH0KLQotICAgICAgICBTdHJpbmcgbGl0ZXJhbCgpIHsKLSAgICAgICAgICAgIHJldHVybiBsaXRlcmFsOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLy94eHg6IHNldHRpbmcgdGhlIGRlZmF1bHQgdmFsdWUgYXMgZmFsc2UsIGFzIHdlIGRvbnQgbmVlZCB0byBjYWxjdWxhdGUgdGhpcyB2YWx1ZQotICAgIC8vd2Ugc2hvdWxkIGhhdmUgYSBmZWF0dXJlIHdoZW4gc2V0IHRvIHRydWUgY29tcHV0ZXMgdGhpcyB2YWx1ZQotICAgIHByaXZhdGUgYm9vbGVhbiBmTmVlZE5vbk5vcm1hbGl6ZWRWYWx1ZSA9IGZhbHNlOwotCi0gICAgcHJvdGVjdGVkIEFycmF5TGlzdDxYTUxTdHJpbmc+IGF0dHJpYnV0ZVZhbHVlQ2FjaGUgPSBuZXcgQXJyYXlMaXN0PD4oKTsKLSAgICBwcm90ZWN0ZWQgQXJyYXlMaXN0PFhNTFN0cmluZ0J1ZmZlcj4gc3RyaW5nQnVmZmVyQ2FjaGUgPSBuZXcgQXJyYXlMaXN0PD4oKTsKLSAgICBwcm90ZWN0ZWQgaW50IGZTdHJpbmdCdWZmZXJJbmRleCA9IDA7Ci0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZkF0dHJpYnV0ZUNhY2hlSW5pdERvbmUgPSBmYWxzZTsKLSAgICBwcm90ZWN0ZWQgaW50IGZBdHRyaWJ1dGVDYWNoZVVzZWRDb3VudCA9IDA7Ci0KLSAgICAvLwotICAgIC8vIERhdGEKLSAgICAvLwotCi0gICAgLy8gZmVhdHVyZXMKLQotICAgIC8qKgotICAgICAqIFZhbGlkYXRpb24uIFRoaXMgZmVhdHVyZSBpZGVudGlmaWVyIGlzOgotICAgICAqIGh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy92YWxpZGF0aW9uCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZlZhbGlkYXRpb24gPSBmYWxzZTsKLQotICAgIC8qKiBOYW1lc3BhY2VzLiAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIGZOYW1lc3BhY2VzOwotCi0gICAgLyoqIENoYXJhY3RlciByZWZlcmVuY2VzIG5vdGlmaWNhdGlvbi4gKi8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBmTm90aWZ5Q2hhclJlZnMgPSBmYWxzZTsKLQotICAgIC8qKiBJbnRlcm5hbCBwYXJzZXItc2V0dGluZ3MgZmVhdHVyZSAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIGZQYXJzZXJTZXR0aW5ncyA9IHRydWU7Ci0KLSAgICAvLyBwcm9wZXJ0aWVzCi0KLSAgICBwcm90ZWN0ZWQgUHJvcGVydHlNYW5hZ2VyIGZQcm9wZXJ0eU1hbmFnZXIgPSBudWxsIDsKLSAgICAvKiogU3ltYm9sIHRhYmxlLiAqLwotICAgIHByb3RlY3RlZCBTeW1ib2xUYWJsZSBmU3ltYm9sVGFibGU7Ci0KLSAgICAvKiogRXJyb3IgcmVwb3J0ZXIuICovCi0gICAgcHJvdGVjdGVkIFhNTEVycm9yUmVwb3J0ZXIgZkVycm9yUmVwb3J0ZXI7Ci0KLSAgICAvKiogRW50aXR5IG1hbmFnZXIuICovCi0gICAgLy9wcm90ZWN0ZWQgWE1MRW50aXR5TWFuYWdlciBmRW50aXR5TWFuYWdlciA9IFByb3BlcnR5TWFuYWdlci5nZXRFbnRpdHlNYW5hZ2VyKCk7Ci0gICAgcHJvdGVjdGVkIFhNTEVudGl0eU1hbmFnZXIgZkVudGl0eU1hbmFnZXIgPSBudWxsIDsKLQotICAgIC8qKiB4eHggdGhpcyBzaG91bGQgYmUgYXZhaWxhYmxlIGZyb20gRW50aXR5TWFuYWdlciBFbnRpdHkgc3RvcmFnZSAqLwotICAgIHByb3RlY3RlZCBYTUxFbnRpdHlTdG9yYWdlIGZFbnRpdHlTdG9yZSA9IG51bGwgOwotCi0gICAgLyoqIFNlY3VyaXR5IG1hbmFnZXIuICovCi0gICAgcHJvdGVjdGVkIFhNTFNlY3VyaXR5TWFuYWdlciBmU2VjdXJpdHlNYW5hZ2VyID0gbnVsbDsKLQotICAgIC8qKiBMaW1pdCBhbmFseXplci4gKi8KLSAgICBwcm90ZWN0ZWQgWE1MTGltaXRBbmFseXplciBmTGltaXRBbmFseXplciA9IG51bGw7Ci0KLSAgICAvLyBwcm90ZWN0ZWQgZGF0YQotCi0gICAgLyoqIGV2ZW50IHR5cGUgKi8KLSAgICBwcm90ZWN0ZWQgWE1MRXZlbnQgZkV2ZW50IDsKLQotICAgIC8qKiBFbnRpdHkgc2Nhbm5lciwgdGhpcyBhbHdheXMgd29ya3Mgb24gbGFzdCBlbnRpdHkgdGhhdCB3YXMgb3BlbmVkLiAqLwotICAgIHByb3RlY3RlZCBYTUxFbnRpdHlTY2FubmVyIGZFbnRpdHlTY2FubmVyID0gbnVsbDsKLQotICAgIC8qKiBFbnRpdHkgZGVwdGguICovCi0gICAgcHJvdGVjdGVkIGludCBmRW50aXR5RGVwdGg7Ci0KLSAgICAvKiogTGl0ZXJhbCB2YWx1ZSBvZiB0aGUgbGFzdCBjaGFyYWN0ZXIgcmVmZXJlbmNlIHNjYW5uZWQuICovCi0gICAgcHJvdGVjdGVkIFN0cmluZyBmQ2hhclJlZkxpdGVyYWwgPSBudWxsOwotCi0gICAgLyoqIFNjYW5uaW5nIGF0dHJpYnV0ZS4gKi8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBmU2Nhbm5pbmdBdHRyaWJ1dGU7Ci0KLSAgICAvKiogUmVwb3J0IGVudGl0eSBib3VuZGFyeS4gKi8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBmUmVwb3J0RW50aXR5OwotCi0gICAgLy8gc3ltYm9scwotCi0gICAgLyoqIFN5bWJvbDogInZlcnNpb24iLiAqLwotICAgIHByb3RlY3RlZCBmaW5hbCBzdGF0aWMgU3RyaW5nIGZWZXJzaW9uU3ltYm9sID0gInZlcnNpb24iLmludGVybigpOwotCi0gICAgLyoqIFN5bWJvbDogImVuY29kaW5nIi4gKi8KLSAgICBwcm90ZWN0ZWQgZmluYWwgc3RhdGljIFN0cmluZyBmRW5jb2RpbmdTeW1ib2wgPSAiZW5jb2RpbmciLmludGVybigpOwotCi0gICAgLyoqIFN5bWJvbDogInN0YW5kYWxvbmUiLiAqLwotICAgIHByb3RlY3RlZCBmaW5hbCBzdGF0aWMgU3RyaW5nIGZTdGFuZGFsb25lU3ltYm9sID0gInN0YW5kYWxvbmUiLmludGVybigpOwotCi0gICAgLyoqIFN5bWJvbDogImFtcCIuICovCi0gICAgcHJvdGVjdGVkIGZpbmFsIHN0YXRpYyBTdHJpbmcgZkFtcFN5bWJvbCA9ICJhbXAiLmludGVybigpOwotCi0gICAgLyoqIFN5bWJvbDogImx0Ii4gKi8KLSAgICBwcm90ZWN0ZWQgZmluYWwgc3RhdGljIFN0cmluZyBmTHRTeW1ib2wgPSAibHQiLmludGVybigpOwotCi0gICAgLyoqIFN5bWJvbDogImd0Ii4gKi8KLSAgICBwcm90ZWN0ZWQgZmluYWwgc3RhdGljIFN0cmluZyBmR3RTeW1ib2wgPSAiZ3QiLmludGVybigpOwotCi0gICAgLyoqIFN5bWJvbDogInF1b3QiLiAqLwotICAgIHByb3RlY3RlZCBmaW5hbCBzdGF0aWMgU3RyaW5nIGZRdW90U3ltYm9sID0gInF1b3QiLmludGVybigpOwotCi0gICAgLyoqIFN5bWJvbDogImFwb3MiLiAqLwotICAgIHByb3RlY3RlZCBmaW5hbCBzdGF0aWMgU3RyaW5nIGZBcG9zU3ltYm9sID0gImFwb3MiLmludGVybigpOwotCi0gICAgLy8gdGVtcG9yYXJ5IHZhcmlhYmxlcwotCi0gICAgLy8gTk9URTogVGhlc2Ugb2JqZWN0cyBhcmUgcHJpdmF0ZSB0byBoZWxwIHByZXZlbnQgYWNjaWRlbnRhbCBtb2RpZmljYXRpb24KLSAgICAvLyAgICAgICBvZiB2YWx1ZXMgYnkgYSBzdWJjbGFzcy4gSWYgdGhlcmUgd2VyZSBwcm90ZWN0ZWQgKmFuZCogdGhlIHN1Yi0KLSAgICAvLyAgICAgICBtb2RpZmllZCB0aGUgdmFsdWVzLCBpdCB3b3VsZCBiZSBkaWZmaWN1bHQgdG8gdHJhY2sgZG93biB0aGUgcmVhbAotICAgIC8vICAgICAgIGNhdXNlIG9mIHRoZSBidWcuIEJ5IG1ha2luZyB0aGVzZSBwcml2YXRlLCB3ZSBhdm9pZCB0aGlzCi0gICAgLy8gICAgICAgcG9zc2liaWxpdHkuCi0KLSAgICAvKiogU3RyaW5nLiAqLwotICAgIHByaXZhdGUgWE1MU3RyaW5nIGZTdHJpbmcgPSBuZXcgWE1MU3RyaW5nKCk7Ci0KLSAgICAvKiogU3RyaW5nIGJ1ZmZlci4gKi8KLSAgICBwcml2YXRlIFhNTFN0cmluZ0J1ZmZlciBmU3RyaW5nQnVmZmVyID0gbmV3IFhNTFN0cmluZ0J1ZmZlcigpOwotCi0gICAgLyoqIFN0cmluZyBidWZmZXIuICovCi0gICAgcHJpdmF0ZSBYTUxTdHJpbmdCdWZmZXIgZlN0cmluZ0J1ZmZlcjIgPSBuZXcgWE1MU3RyaW5nQnVmZmVyKCk7Ci0KLSAgICAvKiogU3RyaW5nIGJ1ZmZlci4gKi8KLSAgICBwcml2YXRlIFhNTFN0cmluZ0J1ZmZlciBmU3RyaW5nQnVmZmVyMyA9IG5ldyBYTUxTdHJpbmdCdWZmZXIoKTsKLQotICAgIC8vIHRlbXBvcmFyeSBsb2NhdGlvbiBmb3IgUmVzb3VyY2UgaWRlbnRpZmljYXRpb24gaW5mb3JtYXRpb24uCi0gICAgcHJvdGVjdGVkIFhNTFJlc291cmNlSWRlbnRpZmllckltcGwgZlJlc291cmNlSWRlbnRpZmllciA9IG5ldyBYTUxSZXNvdXJjZUlkZW50aWZpZXJJbXBsKCk7Ci0gICAgaW50IGluaXRpYWxDYWNoZUNvdW50ID0gNjsKLSAgICAvLwotICAgIC8vIFhNTENvbXBvbmVudCBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29tcG9uZW50TWFuYWdlciBUaGUgY29tcG9uZW50IG1hbmFnZXIuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBUaHJvd3MgZXhjZXB0aW9uIGlmIHJlcXVpcmVkIGZlYXR1cmVzIGFuZAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIHByb3BlcnRpZXMgY2Fubm90IGJlIGZvdW5kLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHJlc2V0KFhNTENvbXBvbmVudE1hbmFnZXIgY29tcG9uZW50TWFuYWdlcikKLSAgICB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgICAgICAgICBmUGFyc2VyU2V0dGluZ3MgPSBjb21wb25lbnRNYW5hZ2VyLmdldEZlYXR1cmUoUEFSU0VSX1NFVFRJTkdTLCB0cnVlKTsKLQotICAgICAgICAgICAgICAgIGlmICghZlBhcnNlclNldHRpbmdzKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBwYXJzZXIgc2V0dGluZ3MgaGF2ZSBub3QgYmVlbiBjaGFuZ2VkCi0gICAgICAgICAgICAgICAgICAgICAgICBpbml0KCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICAgICAgfQotCi0KLSAgICAgICAgLy8gWGVyY2VzIHByb3BlcnRpZXMKLSAgICAgICAgZlN5bWJvbFRhYmxlID0gKFN5bWJvbFRhYmxlKWNvbXBvbmVudE1hbmFnZXIuZ2V0UHJvcGVydHkoU1lNQk9MX1RBQkxFKTsKLSAgICAgICAgZkVycm9yUmVwb3J0ZXIgPSAoWE1MRXJyb3JSZXBvcnRlciljb21wb25lbnRNYW5hZ2VyLmdldFByb3BlcnR5KEVSUk9SX1JFUE9SVEVSKTsKLSAgICAgICAgZkVudGl0eU1hbmFnZXIgPSAoWE1MRW50aXR5TWFuYWdlciljb21wb25lbnRNYW5hZ2VyLmdldFByb3BlcnR5KEVOVElUWV9NQU5BR0VSKTsKLSAgICAgICAgZlNlY3VyaXR5TWFuYWdlciA9IChYTUxTZWN1cml0eU1hbmFnZXIpY29tcG9uZW50TWFuYWdlci5nZXRQcm9wZXJ0eShTRUNVUklUWV9NQU5BR0VSKTsKLQotICAgICAgICAvL3RoaXMgc3RlcCBpcyBleHRyYSBiZWNhdXNlIHdlIGhhdmUgc2VwYXJhdGVkIHRoZSBzdG9yYWdlIG9mIGVudGl0eQotICAgICAgICBmRW50aXR5U3RvcmUgPSBmRW50aXR5TWFuYWdlci5nZXRFbnRpdHlTdG9yZSgpIDsKLQotICAgICAgICAvLyBzYXggZmVhdHVyZXMKLSAgICAgICAgZlZhbGlkYXRpb24gPSBjb21wb25lbnRNYW5hZ2VyLmdldEZlYXR1cmUoVkFMSURBVElPTiwgZmFsc2UpOwotICAgICAgICBmTmFtZXNwYWNlcyA9IGNvbXBvbmVudE1hbmFnZXIuZ2V0RmVhdHVyZShOQU1FU1BBQ0VTLCB0cnVlKTsKLSAgICAgICAgZk5vdGlmeUNoYXJSZWZzID0gY29tcG9uZW50TWFuYWdlci5nZXRGZWF0dXJlKE5PVElGWV9DSEFSX1JFRlMsIGZhbHNlKTsKLQotICAgICAgICBpbml0KCk7Ci0gICAgfSAvLyByZXNldChYTUxDb21wb25lbnRNYW5hZ2VyKQotCi0gICAgcHJvdGVjdGVkIHZvaWQgc2V0UHJvcGVydHlNYW5hZ2VyKFByb3BlcnR5TWFuYWdlciBwcm9wZXJ0eU1hbmFnZXIpewotICAgICAgICBmUHJvcGVydHlNYW5hZ2VyID0gcHJvcGVydHlNYW5hZ2VyIDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiBhIHByb3BlcnR5IGR1cmluZyBwYXJzaW5nLgotICAgICAqCi0gICAgICogQHBhcmFtIHByb3BlcnR5SWQKLSAgICAgKiBAcGFyYW0gdmFsdWUKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRQcm9wZXJ0eShTdHJpbmcgcHJvcGVydHlJZCwgT2JqZWN0IHZhbHVlKQotICAgIHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIHsKLQotICAgICAgICAvLyBYZXJjZXMgcHJvcGVydGllcwotICAgICAgICBpZiAocHJvcGVydHlJZC5zdGFydHNXaXRoKENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYKSkgewotICAgICAgICAgICAgU3RyaW5nIHByb3BlcnR5ID0KLSAgICAgICAgICAgICAgICAgICAgcHJvcGVydHlJZC5zdWJzdHJpbmcoQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVgubGVuZ3RoKCkpOwotICAgICAgICAgICAgaWYgKHByb3BlcnR5LmVxdWFscyhDb25zdGFudHMuU1lNQk9MX1RBQkxFX1BST1BFUlRZKSkgewotICAgICAgICAgICAgICAgIGZTeW1ib2xUYWJsZSA9IChTeW1ib2xUYWJsZSl2YWx1ZTsKLSAgICAgICAgICAgIH0gZWxzZSBpZiAocHJvcGVydHkuZXF1YWxzKENvbnN0YW50cy5FUlJPUl9SRVBPUlRFUl9QUk9QRVJUWSkpIHsKLSAgICAgICAgICAgICAgICBmRXJyb3JSZXBvcnRlciA9IChYTUxFcnJvclJlcG9ydGVyKXZhbHVlOwotICAgICAgICAgICAgfSBlbHNlIGlmIChwcm9wZXJ0eS5lcXVhbHMoQ29uc3RhbnRzLkVOVElUWV9NQU5BR0VSX1BST1BFUlRZKSkgewotICAgICAgICAgICAgICAgIGZFbnRpdHlNYW5hZ2VyID0gKFhNTEVudGl0eU1hbmFnZXIpdmFsdWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAocHJvcGVydHlJZC5lcXVhbHMoU0VDVVJJVFlfTUFOQUdFUikpIHsKLSAgICAgICAgICAgIGZTZWN1cml0eU1hbmFnZXIgPSAoWE1MU2VjdXJpdHlNYW5hZ2VyKXZhbHVlOwotICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLyplbHNlIGlmKHByb3BlcnR5SWQuZXF1YWxzKENvbnN0YW50cy5TVEFYX1BST1BFUlRJRVMpKXsKLSAgICAgICAgICAgIGZTdGF4UHJvcGVydGllcyA9IChIYXNoTWFwKXZhbHVlOwotICAgICAgICAgICAgLy9UT0RPOjpkaXNjdXNzIHdpdGggbmVlcmFqIHdoYXQgYXJlIGhpcyB0aG91Z2h0cyBvbiBwYXNzaW5nIHByb3BlcnRpZXMuCi0gICAgICAgICAgICAvL0ZvciBub3cgdXNlIHRoaXMKLSAgICAgICAgfSovCi0KLSAgICB9IC8vIHNldFByb3BlcnR5KFN0cmluZyxPYmplY3QpCi0KLSAgICAvKgotICAgICAqIFNldHMgdGhlIGZlYXR1cmUgb2YgdGhlIHNjYW5uZXIuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RmVhdHVyZShTdHJpbmcgZmVhdHVyZUlkLCBib29sZWFuIHZhbHVlKQotICAgIHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIHsKLQotICAgICAgICBpZiAoVkFMSURBVElPTi5lcXVhbHMoZmVhdHVyZUlkKSkgewotICAgICAgICAgICAgZlZhbGlkYXRpb24gPSB2YWx1ZTsKLSAgICAgICAgfSBlbHNlIGlmIChOT1RJRllfQ0hBUl9SRUZTLmVxdWFscyhmZWF0dXJlSWQpKSB7Ci0gICAgICAgICAgICBmTm90aWZ5Q2hhclJlZnMgPSB2YWx1ZTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qCi0gICAgICogR2V0cyB0aGUgc3RhdGUgb2YgdGhlIGZlYXR1cmUgb2YgdGhlIHNjYW5uZXIuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0RmVhdHVyZShTdHJpbmcgZmVhdHVyZUlkKQotICAgIHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIHsKLQotICAgICAgICBpZiAoVkFMSURBVElPTi5lcXVhbHMoZmVhdHVyZUlkKSkgewotICAgICAgICAgICAgcmV0dXJuIGZWYWxpZGF0aW9uOwotICAgICAgICB9IGVsc2UgaWYgKE5PVElGWV9DSEFSX1JFRlMuZXF1YWxzKGZlYXR1cmVJZCkpIHsKLSAgICAgICAgICAgIHJldHVybiBmTm90aWZ5Q2hhclJlZnM7Ci0gICAgICAgIH0KLSAgICAgICAgdGhyb3cgbmV3IFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24oU3RhdHVzLk5PVF9SRUNPR05JWkVELCBmZWF0dXJlSWQpOwotICAgIH0KLQotICAgIC8vCi0gICAgLy8gUHJvdGVjdGVkIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLy8gYW55Ym9keSBjYWxsaW5nIHRoaXMgaGFkIGJldHRlciBoYXZlIHNldCBTeW10b2x0YWJsZSEKLSAgICBwcm90ZWN0ZWQgdm9pZCByZXNldCgpIHsKLSAgICAgICAgaW5pdCgpOwotCi0gICAgICAgIC8vIERURCBwcmVwYXJzaW5nIGRlZmF1bHRzOgotICAgICAgICBmVmFsaWRhdGlvbiA9IHRydWU7Ci0gICAgICAgIGZOb3RpZnlDaGFyUmVmcyA9IGZhbHNlOwotCi0gICAgfQotCi0gICAgcHVibGljIHZvaWQgcmVzZXQoUHJvcGVydHlNYW5hZ2VyIHByb3BlcnR5TWFuYWdlcikgewotICAgICAgICBpbml0KCk7Ci0gICAgICAgIC8vIFhlcmNlcyBwcm9wZXJ0aWVzCi0gICAgICAgIGZTeW1ib2xUYWJsZSA9IChTeW1ib2xUYWJsZSlwcm9wZXJ0eU1hbmFnZXIuZ2V0UHJvcGVydHkoQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuU1lNQk9MX1RBQkxFX1BST1BFUlRZKTsKLQotICAgICAgICBmRXJyb3JSZXBvcnRlciA9IChYTUxFcnJvclJlcG9ydGVyKXByb3BlcnR5TWFuYWdlci5nZXRQcm9wZXJ0eShDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5FUlJPUl9SRVBPUlRFUl9QUk9QRVJUWSk7Ci0KLSAgICAgICAgZkVudGl0eU1hbmFnZXIgPSAoWE1MRW50aXR5TWFuYWdlcilwcm9wZXJ0eU1hbmFnZXIuZ2V0UHJvcGVydHkoRU5USVRZX01BTkFHRVIpOwotICAgICAgICBmRW50aXR5U3RvcmUgPSBmRW50aXR5TWFuYWdlci5nZXRFbnRpdHlTdG9yZSgpIDsKLSAgICAgICAgZkVudGl0eVNjYW5uZXIgPSAoWE1MRW50aXR5U2Nhbm5lcilmRW50aXR5TWFuYWdlci5nZXRFbnRpdHlTY2FubmVyKCkgOwotICAgICAgICBmU2VjdXJpdHlNYW5hZ2VyID0gKFhNTFNlY3VyaXR5TWFuYWdlcilwcm9wZXJ0eU1hbmFnZXIuZ2V0UHJvcGVydHkoU0VDVVJJVFlfTUFOQUdFUik7Ci0KLSAgICAgICAgLy9mRW50aXR5TWFuYWdlci5yZXNldCgpOwotICAgICAgICAvLyBEVEQgcHJlcGFyc2luZyBkZWZhdWx0czoKLSAgICAgICAgZlZhbGlkYXRpb24gPSBmYWxzZTsKLSAgICAgICAgZk5vdGlmeUNoYXJSZWZzID0gZmFsc2U7Ci0KLSAgICB9Ci0gICAgLy8gY29tbW9uIHNjYW5uaW5nIG1ldGhvZHMKLQotICAgIC8qKgotICAgICAqIFNjYW5zIGFuIFhNTCBvciB0ZXh0IGRlY2xhcmF0aW9uLgotICAgICAqIDxwPgotICAgICAqIDxwcmU+Ci0gICAgICogWzIzXSBYTUxEZWNsIDo6PSAnPD94bWwnIFZlcnNpb25JbmZvIEVuY29kaW5nRGVjbD8gU0REZWNsPyBTPyAnPz4nCi0gICAgICogWzI0XSBWZXJzaW9uSW5mbyA6Oj0gUyAndmVyc2lvbicgRXEgKCcgVmVyc2lvbk51bSAnIHwgIiBWZXJzaW9uTnVtICIpCi0gICAgICogWzgwXSBFbmNvZGluZ0RlY2wgOjo9IFMgJ2VuY29kaW5nJyBFcSAoJyInIEVuY05hbWUgJyInIHwgICInIiBFbmNOYW1lICInIiApCi0gICAgICogWzgxXSBFbmNOYW1lIDo6PSBbQS1aYS16XSAoW0EtWmEtejAtOS5fXSB8ICctJykqCi0gICAgICogWzMyXSBTRERlY2wgOjo9IFMgJ3N0YW5kYWxvbmUnIEVxICgoIiciICgneWVzJyB8ICdubycpICInIikKLSAgICAgKiAgICAgICAgICAgICAgICAgfCAoJyInICgneWVzJyB8ICdubycpICciJykpCi0gICAgICoKLSAgICAgKiBbNzddIFRleHREZWNsIDo6PSAnPD94bWwnIFZlcnNpb25JbmZvPyBFbmNvZGluZ0RlY2wgUz8gJz8+JwotICAgICAqIDwvcHJlPgotICAgICAqCi0gICAgICogQHBhcmFtIHNjYW5uaW5nVGV4dERlY2wgVHJ1ZSBpZiBhIHRleHQgZGVjbGFyYXRpb24gaXMgdG8KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBiZSBzY2FubmVkIGluc3RlYWQgb2YgYW4gWE1MCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgZGVjbGFyYXRpb24uCi0gICAgICogQHBhcmFtIHBzZXVkb0F0dHJpYnV0ZVZhbHVlcyBBbiBhcnJheSBvZiBzaXplIDMgdG8gcmV0dXJuIHRoZSB2ZXJzaW9uLAotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIGVuY29kaW5nIGFuZCBzdGFuZGFsb25lIHBzZXVkbyBhdHRyaWJ1dGUgdmFsdWVzCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgKGluIHRoYXQgb3JkZXIpLgotICAgICAqCi0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGlzIG1ldGhvZCB1c2VzIGZTdHJpbmcsIGFueXRoaW5nIGluIGl0Ci0gICAgICogYXQgdGhlIHRpbWUgb2YgY2FsbGluZyBpcyBsb3N0LgotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIHNjYW5YTUxEZWNsT3JUZXh0RGVjbChib29sZWFuIHNjYW5uaW5nVGV4dERlY2wsCi0gICAgICAgICAgICBTdHJpbmdbXSBwc2V1ZG9BdHRyaWJ1dGVWYWx1ZXMpCi0gICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy8gcHNldWRvLWF0dHJpYnV0ZSB2YWx1ZXMKLSAgICAgICAgU3RyaW5nIHZlcnNpb24gPSBudWxsOwotICAgICAgICBTdHJpbmcgZW5jb2RpbmcgPSBudWxsOwotICAgICAgICBTdHJpbmcgc3RhbmRhbG9uZSA9IG51bGw7Ci0KLSAgICAgICAgLy8gc2NhbiBwc2V1ZG8tYXR0cmlidXRlcwotICAgICAgICBmaW5hbCBpbnQgU1RBVEVfVkVSU0lPTiA9IDA7Ci0gICAgICAgIGZpbmFsIGludCBTVEFURV9FTkNPRElORyA9IDE7Ci0gICAgICAgIGZpbmFsIGludCBTVEFURV9TVEFOREFMT05FID0gMjsKLSAgICAgICAgZmluYWwgaW50IFNUQVRFX0RPTkUgPSAzOwotICAgICAgICBpbnQgc3RhdGUgPSBTVEFURV9WRVJTSU9OOwotCi0gICAgICAgIGJvb2xlYW4gZGF0YUZvdW5kRm9yVGFyZ2V0ID0gZmFsc2U7Ci0gICAgICAgIGJvb2xlYW4gc2F3U3BhY2UgPSBmRW50aXR5U2Nhbm5lci5za2lwU3BhY2VzKCk7Ci0gICAgICAgIC8vIHNpbmNlIHBzZXVkb2F0dHJpYnV0ZXMgYXJlICpub3QqIGF0dHJpYnV0ZXMsCi0gICAgICAgIC8vIHRoZWlyIHF1b3RlcyBkb24ndCBuZWVkIHRvIGJlIHByZXNlcnZlZCBpbiBleHRlcm5hbCBwYXJhbWV0ZXIgZW50aXRpZXMuCi0gICAgICAgIC8vIHRoZSBYTUxFbnRpdHlTY2FubmVyI3NjYW5MaXRlcmFsIG1ldGhvZCB3aWxsIGNvbnRpbnVlIHRvCi0gICAgICAgIC8vIGVtaXQgLTEgaW4gc3VjaCBjYXNlcyB3aGVuIGl0IGZpbmRzIGEgcXVvdGU7IHRoaXMgaXMKLSAgICAgICAgLy8gZmluZSBmb3Igb3RoZXIgbWV0aG9kcyB0aGF0IHBhcnNlIHNjYW5uZWQgZW50aXRpZXMsCi0gICAgICAgIC8vIGJ1dCBub3QgZm9yIHRoZSBzY2FubmluZyBvZiBwc2V1ZG9hdHRyaWJ1dGVzLiAgU28sCi0gICAgICAgIC8vIHRlbXBvcmFyaWx5LCB3ZSBtdXN0IG1hcmsgdGhlIGN1cnJlbnQgZW50aXR5IGFzIG5vdCBiZWluZyAibGl0ZXJhbCIKLSAgICAgICAgRW50aXR5LlNjYW5uZWRFbnRpdHkgY3VyckVudCA9IGZFbnRpdHlNYW5hZ2VyLmdldEN1cnJlbnRFbnRpdHkoKTsKLSAgICAgICAgYm9vbGVhbiBjdXJyTGl0ZXJhbCA9IGN1cnJFbnQubGl0ZXJhbDsKLSAgICAgICAgY3VyckVudC5saXRlcmFsID0gZmFsc2U7Ci0gICAgICAgIHdoaWxlIChmRW50aXR5U2Nhbm5lci5wZWVrQ2hhcigpICE9ICc/JykgewotICAgICAgICAgICAgZGF0YUZvdW5kRm9yVGFyZ2V0ID0gdHJ1ZTsKLSAgICAgICAgICAgIFN0cmluZyBuYW1lID0gc2NhblBzZXVkb0F0dHJpYnV0ZShzY2FubmluZ1RleHREZWNsLCBmU3RyaW5nKTsKLSAgICAgICAgICAgIHN3aXRjaCAoc3RhdGUpIHsKLSAgICAgICAgICAgICAgICBjYXNlIFNUQVRFX1ZFUlNJT046IHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKG5hbWUuZXF1YWxzKGZWZXJzaW9uU3ltYm9sKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFzYXdTcGFjZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3Ioc2Nhbm5pbmdUZXh0RGVjbAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyAiU3BhY2VSZXF1aXJlZEJlZm9yZVZlcnNpb25JblRleHREZWNsIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAiU3BhY2VSZXF1aXJlZEJlZm9yZVZlcnNpb25JblhNTERlY2wiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICB2ZXJzaW9uID0gZlN0cmluZy50b1N0cmluZygpOwotICAgICAgICAgICAgICAgICAgICAgICAgc3RhdGUgPSBTVEFURV9FTkNPRElORzsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdmVyc2lvblN1cHBvcnRlZCh2ZXJzaW9uKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIlZlcnNpb25Ob3RTdXBwb3J0ZWQiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde3ZlcnNpb259KTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHZlcnNpb24uZXF1YWxzKCIxLjEiKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVudGl0eS5TY2FubmVkRW50aXR5IHRvcCA9IGZFbnRpdHlNYW5hZ2VyLmdldFRvcExldmVsRW50aXR5KCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRvcCAhPSBudWxsICYmICh0b3AudmVyc2lvbiA9PSBudWxsIHx8IHRvcC52ZXJzaW9uLmVxdWFscygiMS4wIikpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIlZlcnNpb25NaXNtYXRjaCIsIG51bGwpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmRW50aXR5TWFuYWdlci5zZXRTY2FubmVyVmVyc2lvbihDb25zdGFudHMuWE1MX1ZFUlNJT05fMV8xKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG5hbWUuZXF1YWxzKGZFbmNvZGluZ1N5bWJvbCkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmICghc2Nhbm5pbmdUZXh0RGVjbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIlZlcnNpb25JbmZvUmVxdWlyZWQiLCBudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGlmICghc2F3U3BhY2UpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKHNjYW5uaW5nVGV4dERlY2wKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gIlNwYWNlUmVxdWlyZWRCZWZvcmVFbmNvZGluZ0luVGV4dERlY2wiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6ICJTcGFjZVJlcXVpcmVkQmVmb3JlRW5jb2RpbmdJblhNTERlY2wiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBlbmNvZGluZyA9IGZTdHJpbmcudG9TdHJpbmcoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlID0gc2Nhbm5pbmdUZXh0RGVjbCA/IFNUQVRFX0RPTkUgOiBTVEFURV9TVEFOREFMT05FOwotICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNjYW5uaW5nVGV4dERlY2wpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJFbmNvZGluZ0RlY2xSZXF1aXJlZCIsIG51bGwpOwotICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJWZXJzaW9uSW5mb1JlcXVpcmVkIiwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGNhc2UgU1RBVEVfRU5DT0RJTkc6IHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKG5hbWUuZXF1YWxzKGZFbmNvZGluZ1N5bWJvbCkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmICghc2F3U3BhY2UpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKHNjYW5uaW5nVGV4dERlY2wKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gIlNwYWNlUmVxdWlyZWRCZWZvcmVFbmNvZGluZ0luVGV4dERlY2wiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6ICJTcGFjZVJlcXVpcmVkQmVmb3JlRW5jb2RpbmdJblhNTERlY2wiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBlbmNvZGluZyA9IGZTdHJpbmcudG9TdHJpbmcoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlID0gc2Nhbm5pbmdUZXh0RGVjbCA/IFNUQVRFX0RPTkUgOiBTVEFURV9TVEFOREFMT05FOwotICAgICAgICAgICAgICAgICAgICAgICAgLy8gVE9ETzogY2hlY2sgZW5jb2RpbmcgbmFtZTsgc2V0IGVuY29kaW5nIG9uCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyAgICAgICBlbnRpdHkgc2Nhbm5lcgotICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCFzY2FubmluZ1RleHREZWNsICYmIG5hbWUuZXF1YWxzKGZTdGFuZGFsb25lU3ltYm9sKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFzYXdTcGFjZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIlNwYWNlUmVxdWlyZWRCZWZvcmVTdGFuZGFsb25lIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgc3RhbmRhbG9uZSA9IGZTdHJpbmcudG9TdHJpbmcoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlID0gU1RBVEVfRE9ORTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmICghc3RhbmRhbG9uZS5lcXVhbHMoInllcyIpICYmICFzdGFuZGFsb25lLmVxdWFscygibm8iKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIlNERGVjbEludmFsaWQiLCBuZXcgT2JqZWN0W10ge3N0YW5kYWxvbmV9KTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIkVuY29kaW5nRGVjbFJlcXVpcmVkIiwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGNhc2UgU1RBVEVfU1RBTkRBTE9ORTogewotICAgICAgICAgICAgICAgICAgICBpZiAobmFtZS5lcXVhbHMoZlN0YW5kYWxvbmVTeW1ib2wpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXNhd1NwYWNlKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiU3BhY2VSZXF1aXJlZEJlZm9yZVN0YW5kYWxvbmUiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBzdGFuZGFsb25lID0gZlN0cmluZy50b1N0cmluZygpOwotICAgICAgICAgICAgICAgICAgICAgICAgc3RhdGUgPSBTVEFURV9ET05FOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFzdGFuZGFsb25lLmVxdWFscygieWVzIikgJiYgIXN0YW5kYWxvbmUuZXF1YWxzKCJubyIpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiU0REZWNsSW52YWxpZCIsICBuZXcgT2JqZWN0W10ge3N0YW5kYWxvbmV9KTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIlNERGVjbE5hbWVJbnZhbGlkIiwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHsKLSAgICAgICAgICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiTm9Nb3JlUHNldWRvQXR0cmlidXRlcyIsIG51bGwpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHNhd1NwYWNlID0gZkVudGl0eVNjYW5uZXIuc2tpcFNwYWNlcygpOwotICAgICAgICB9Ci0gICAgICAgIC8vIHJlc3RvcmUgb3JpZ2luYWwgbGl0ZXJhbCB2YWx1ZQotICAgICAgICBpZihjdXJyTGl0ZXJhbCkgewotICAgICAgICAgICAgY3VyckVudC5saXRlcmFsID0gdHJ1ZTsKLSAgICAgICAgfQotICAgICAgICAvLyBSRVZJU0lUOiBzaG91bGQgd2UgcmVtb3ZlIHRoaXMgZXJyb3IgcmVwb3J0aW5nPwotICAgICAgICBpZiAoc2Nhbm5pbmdUZXh0RGVjbCAmJiBzdGF0ZSAhPSBTVEFURV9ET05FKSB7Ci0gICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJNb3JlUHNldWRvQXR0cmlidXRlcyIsIG51bGwpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gSWYgdGhlcmUgaXMgbm8gZGF0YSBpbiB0aGUgeG1sIG9yIHRleHQgZGVjbCB0aGVuIHdlIGZhaWwgdG8gcmVwb3J0IGVycm9yCi0gICAgICAgIC8vIGZvciB2ZXJzaW9uIG9yIGVuY29kaW5nIGluZm8gYWJvdmUuCi0gICAgICAgIGlmIChzY2FubmluZ1RleHREZWNsKSB7Ci0gICAgICAgICAgICBpZiAoIWRhdGFGb3VuZEZvclRhcmdldCAmJiBlbmNvZGluZyA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiRW5jb2RpbmdEZWNsUmVxdWlyZWQiLCBudWxsKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIGlmICghZGF0YUZvdW5kRm9yVGFyZ2V0ICYmIHZlcnNpb24gPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIlZlcnNpb25JbmZvUmVxdWlyZWQiLCBudWxsKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIGVuZAotICAgICAgICBpZiAoIWZFbnRpdHlTY2FubmVyLnNraXBDaGFyKCc/JywgbnVsbCkpIHsKLSAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIlhNTERlY2xVbnRlcm1pbmF0ZWQiLCBudWxsKTsKLSAgICAgICAgfQotICAgICAgICBpZiAoIWZFbnRpdHlTY2FubmVyLnNraXBDaGFyKCc+JywgbnVsbCkpIHsKLSAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIlhNTERlY2xVbnRlcm1pbmF0ZWQiLCBudWxsKTsKLQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gZmlsbCBpbiByZXR1cm4gYXJyYXkKLSAgICAgICAgcHNldWRvQXR0cmlidXRlVmFsdWVzWzBdID0gdmVyc2lvbjsKLSAgICAgICAgcHNldWRvQXR0cmlidXRlVmFsdWVzWzFdID0gZW5jb2Rpbmc7Ci0gICAgICAgIHBzZXVkb0F0dHJpYnV0ZVZhbHVlc1syXSA9IHN0YW5kYWxvbmU7Ci0KLSAgICB9IC8vIHNjYW5YTUxEZWNsT3JUZXh0RGVjbChib29sZWFuKQotCi0gICAgLyoqCi0gICAgICogU2NhbnMgYSBwc2V1ZG8gYXR0cmlidXRlLgotICAgICAqCi0gICAgICogQHBhcmFtIHNjYW5uaW5nVGV4dERlY2wgVHJ1ZSBpZiBzY2FubmluZyB0aGlzIHBzZXVkby1hdHRyaWJ1dGUgZm9yIGEKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBUZXh0RGVjbDsgZmFsc2UgaWYgc2Nhbm5pbmcgWE1MRGVjbC4gVGhpcwotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIGZsYWcgaXMgbmVlZGVkIHRvIHJlcG9ydCB0aGUgY29ycmVjdCB0eXBlIG9mCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IuCi0gICAgICogQHBhcmFtIHZhbHVlICAgICAgICAgICAgVGhlIHN0cmluZyB0byBmaWxsIGluIHdpdGggdGhlIGF0dHJpYnV0ZQotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlCi0gICAgICoKLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoaXMgbWV0aG9kIHVzZXMgZlN0cmluZ0J1ZmZlcjIsIGFueXRoaW5nIGluIGl0Ci0gICAgICogYXQgdGhlIHRpbWUgb2YgY2FsbGluZyBpcyBsb3N0LgotICAgICAqLwotICAgIHByb3RlY3RlZCBTdHJpbmcgc2NhblBzZXVkb0F0dHJpYnV0ZShib29sZWFuIHNjYW5uaW5nVGV4dERlY2wsCi0gICAgICAgICAgICBYTUxTdHJpbmcgdmFsdWUpCi0gICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgU3RyaW5nIG5hbWUgPSBzY2FuUHNldWRvQXR0cmlidXRlTmFtZSgpOwotICAgICAgICAvLyBYTUxFbnRpdHlNYW5hZ2VyLnByaW50KGZFbnRpdHlNYW5hZ2VyLmdldEN1cnJlbnRFbnRpdHkoKSk7Ci0KLSAgICAgICAgaWYgKG5hbWUgPT0gbnVsbCkgewotICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiUHNldWRvQXR0ck5hbWVFeHBlY3RlZCIsIG51bGwpOwotICAgICAgICB9Ci0gICAgICAgIGZFbnRpdHlTY2FubmVyLnNraXBTcGFjZXMoKTsKLSAgICAgICAgaWYgKCFmRW50aXR5U2Nhbm5lci5za2lwQ2hhcignPScsIG51bGwpKSB7Ci0gICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKHNjYW5uaW5nVGV4dERlY2wgPyAiRXFSZXF1aXJlZEluVGV4dERlY2wiCi0gICAgICAgICAgICAgICAgICAgIDogIkVxUmVxdWlyZWRJblhNTERlY2wiLCBuZXcgT2JqZWN0W117bmFtZX0pOwotICAgICAgICB9Ci0gICAgICAgIGZFbnRpdHlTY2FubmVyLnNraXBTcGFjZXMoKTsKLSAgICAgICAgaW50IHF1b3RlID0gZkVudGl0eVNjYW5uZXIucGVla0NoYXIoKTsKLSAgICAgICAgaWYgKHF1b3RlICE9ICdcJycgJiYgcXVvdGUgIT0gJyInKSB7Ci0gICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKHNjYW5uaW5nVGV4dERlY2wgPyAiUXVvdGVSZXF1aXJlZEluVGV4dERlY2wiCi0gICAgICAgICAgICAgICAgICAgIDogIlF1b3RlUmVxdWlyZWRJblhNTERlY2wiICwgbmV3IE9iamVjdFtde25hbWV9KTsKLSAgICAgICAgfQotICAgICAgICBmRW50aXR5U2Nhbm5lci5zY2FuQ2hhcihOYW1lVHlwZS5BVFRSSUJVVEUpOwotICAgICAgICBpbnQgYyA9IGZFbnRpdHlTY2FubmVyLnNjYW5MaXRlcmFsKHF1b3RlLCB2YWx1ZSwgZmFsc2UpOwotICAgICAgICBpZiAoYyAhPSBxdW90ZSkgewotICAgICAgICAgICAgZlN0cmluZ0J1ZmZlcjIuY2xlYXIoKTsKLSAgICAgICAgICAgIGRvIHsKLSAgICAgICAgICAgICAgICBmU3RyaW5nQnVmZmVyMi5hcHBlbmQodmFsdWUpOwotICAgICAgICAgICAgICAgIGlmIChjICE9IC0xKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChjID09ICcmJyB8fCBjID09ICclJyB8fCBjID09ICc8JyB8fCBjID09ICddJykgewotICAgICAgICAgICAgICAgICAgICAgICAgZlN0cmluZ0J1ZmZlcjIuYXBwZW5kKChjaGFyKWZFbnRpdHlTY2FubmVyLnNjYW5DaGFyKE5hbWVUeXBlLkFUVFJJQlVURSkpOwotICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKFhNTENoYXIuaXNIaWdoU3Vycm9nYXRlKGMpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzY2FuU3Vycm9nYXRlcyhmU3RyaW5nQnVmZmVyMik7Ci0gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNJbnZhbGlkTGl0ZXJhbChjKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGtleSA9IHNjYW5uaW5nVGV4dERlY2wKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyAiSW52YWxpZENoYXJJblRleHREZWNsIiA6ICJJbnZhbGlkQ2hhckluWE1MRGVjbCI7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKGtleSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHtJbnRlZ2VyLnRvU3RyaW5nKGMsIDE2KX0pOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmRW50aXR5U2Nhbm5lci5zY2FuQ2hhcihudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBjID0gZkVudGl0eVNjYW5uZXIuc2NhbkxpdGVyYWwocXVvdGUsIHZhbHVlLCBmYWxzZSk7Ci0gICAgICAgICAgICB9IHdoaWxlIChjICE9IHF1b3RlKTsKLSAgICAgICAgICAgIGZTdHJpbmdCdWZmZXIyLmFwcGVuZCh2YWx1ZSk7Ci0gICAgICAgICAgICB2YWx1ZS5zZXRWYWx1ZXMoZlN0cmluZ0J1ZmZlcjIpOwotICAgICAgICB9Ci0gICAgICAgIGlmICghZkVudGl0eVNjYW5uZXIuc2tpcENoYXIocXVvdGUsIG51bGwpKSB7Ci0gICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKHNjYW5uaW5nVGV4dERlY2wgPyAiQ2xvc2VRdW90ZU1pc3NpbmdJblRleHREZWNsIgotICAgICAgICAgICAgICAgICAgICA6ICJDbG9zZVF1b3RlTWlzc2luZ0luWE1MRGVjbCIsCi0gICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXtuYW1lfSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyByZXR1cm4KLSAgICAgICAgcmV0dXJuIG5hbWU7Ci0KLSAgICB9IC8vIHNjYW5Qc2V1ZG9BdHRyaWJ1dGUoWE1MU3RyaW5nKTpTdHJpbmcKLQotICAgIC8qKgotICAgICAqIFNjYW5zIHRoZSBuYW1lIG9mIGEgcHNldWRvIGF0dHJpYnV0ZS4gVGhlIG9ubHkgbGVnYWwgbmFtZXMKLSAgICAgKiBpbiBYTUwgMS4wLzEuMSBkb2N1bWVudHMgYXJlICd2ZXJzaW9uJywgJ2VuY29kaW5nJyBhbmQgJ3N0YW5kYWxvbmUnLgotICAgICAqCi0gICAgICogQHJldHVybiB0aGUgbmFtZSBvZiB0aGUgcHNldWRvIGF0dHJpYnV0ZSBvciA8Y29kZT5udWxsPC9jb2RlPgotICAgICAqIGlmIGEgbGVnYWwgcHNldWRvIGF0dHJpYnV0ZSBuYW1lIGNvdWxkIG5vdCBiZSBzY2FubmVkLgotICAgICAqLwotICAgIHByaXZhdGUgU3RyaW5nIHNjYW5Qc2V1ZG9BdHRyaWJ1dGVOYW1lKCkgdGhyb3dzIElPRXhjZXB0aW9uLCBYTklFeGNlcHRpb24gewotICAgICAgICBmaW5hbCBpbnQgY2ggPSBmRW50aXR5U2Nhbm5lci5wZWVrQ2hhcigpOwotICAgICAgICBzd2l0Y2ggKGNoKSB7Ci0gICAgICAgICAgICBjYXNlICd2JzoKLSAgICAgICAgICAgICAgICBpZiAoZkVudGl0eVNjYW5uZXIuc2tpcFN0cmluZyhmVmVyc2lvblN5bWJvbCkpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZWZXJzaW9uU3ltYm9sOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIGNhc2UgJ2UnOgotICAgICAgICAgICAgICAgIGlmIChmRW50aXR5U2Nhbm5lci5za2lwU3RyaW5nKGZFbmNvZGluZ1N5bWJvbCkpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZFbmNvZGluZ1N5bWJvbDsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICBjYXNlICdzJzoKLSAgICAgICAgICAgICAgICBpZiAoZkVudGl0eVNjYW5uZXIuc2tpcFN0cmluZyhmU3RhbmRhbG9uZVN5bWJvbCkpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZTdGFuZGFsb25lU3ltYm9sOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9IC8vIHNjYW5Qc2V1ZG9BdHRyaWJ1dGVOYW1lKCkKLQotICAgIC8qKgotICAgICAqIFNjYW5zIGEgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbi4KLSAgICAgKiA8cD4KLSAgICAgKiA8cHJlPgotICAgICAqIFsxNl0gUEkgOjo9ICcmbHQ7PycgUElUYXJnZXQgKFMgKENoYXIqIC0gKENoYXIqICc/PicgQ2hhciopKSk/ICc/PicKLSAgICAgKiBbMTddIFBJVGFyZ2V0IDo6PSBOYW1lIC0gKCgnWCcgfCAneCcpICgnTScgfCAnbScpICgnTCcgfCAnbCcpKQotICAgICAqIDwvcHJlPgotICAgICAqLwotICAgIC8vQ0hBTkdFRDoKLSAgICAvL0VBUkxJRVI6IHNjYW5QSSgpCi0gICAgLy9OT1c6IHNjYW5QSShYTUxTdHJpbmdCdWZmZXIpCi0gICAgLy9pdCBtYWtlcyB0aGluZ3MgbW9yZSBlYXN5IGlmIFhNTFN0cmluZ0JVZmZlciBpcyBwYXNzZWQuIE1vdGl2YXRpb24gZm9yIHRoaXMgY2hhbmdlIGlzIHNhbWUKLSAgICAvLyBhcyB0aGF0IGZvciBzY2FuQ29udGVudCgpCi0KLSAgICBwcm90ZWN0ZWQgdm9pZCBzY2FuUEkoWE1MU3RyaW5nQnVmZmVyIGRhdGEpIHRocm93cyBJT0V4Y2VwdGlvbiwgWE5JRXhjZXB0aW9uIHsKLQotICAgICAgICAvLyB0YXJnZXQKLSAgICAgICAgZlJlcG9ydEVudGl0eSA9IGZhbHNlOwotICAgICAgICBTdHJpbmcgdGFyZ2V0ID0gZkVudGl0eVNjYW5uZXIuc2Nhbk5hbWUoTmFtZVR5cGUuUEkpOwotICAgICAgICBpZiAodGFyZ2V0ID09IG51bGwpIHsKLSAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIlBJVGFyZ2V0UmVxdWlyZWQiLCBudWxsKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIHNjYW4gZGF0YQotICAgICAgICBzY2FuUElEYXRhKHRhcmdldCwgZGF0YSk7Ci0gICAgICAgIGZSZXBvcnRFbnRpdHkgPSB0cnVlOwotCi0gICAgfSAvLyBzY2FuUEkoWE1MU3RyaW5nQnVmZmVyKQotCi0gICAgLyoqCi0gICAgICogU2NhbnMgYSBwcm9jZXNzaW5nIGRhdGEuIFRoaXMgaXMgbmVlZGVkIHRvIGhhbmRsZSB0aGUgc2l0dWF0aW9uCi0gICAgICogd2hlcmUgYSBkb2N1bWVudCBzdGFydHMgd2l0aCBhIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gd2hvc2UKLSAgICAgKiB0YXJnZXQgbmFtZSA8ZW0+c3RhcnRzIHdpdGg8L2VtPiAieG1sIi4gKGUuZy4geG1sZm9vKQotICAgICAqCi0gICAgICogVGhpcyBtZXRob2Qgd291bGQgYWx3YXlzIHJlYWQgdGhlIHdob2xlIGRhdGEuIFdlIGhhdmUgd2hpbGUgbG9vcCBhbmQgZGF0YSBpcyBidWZmZXJlZAotICAgICAqIHVudGlsIGRlbGltZXRlciBpcyBlbmNvdW50ZXJlZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSB0YXJnZXQgVGhlIFBJIHRhcmdldAotICAgICAqIEBwYXJhbSBkYXRhIFRoZSBzdHJpbmcgdG8gZmlsbCBpbiB3aXRoIHRoZSBkYXRhCi0gICAgICovCi0KLSAgICAvL0NIQU5HRUQ6Ci0gICAgLy9FYXJsaWVyOlRoaXMgbWV0aG9kIHVzZXMgdGhlIGZTdHJpbmdCdWZmZXIgYW5kIGxhdGVyIGJ1ZmZlciB2YWx1ZXMgYXJlIHNldCB0bwotICAgIC8vdGhlIHN1cHBsaWVkIFhNTFN0cmluZy4uLi4KLSAgICAvL05vdzogQ2hhbmdlZCB0aGUgc2lnbmF0dXJlIG9mIHRoaXMgZnVuY3Rpb24gdG8gcGFzcyBYTUxTdHJpbmdCdWZmZXIuLiBhbmQgZGF0YSB3b3VsZAotICAgIC8vYmUgYXBwZW5kZWQgdG8gdGhhdCBidWZmZXIKLQotICAgIHByb3RlY3RlZCB2b2lkIHNjYW5QSURhdGEoU3RyaW5nIHRhcmdldCwgWE1MU3RyaW5nQnVmZmVyIGRhdGEpCi0gICAgdGhyb3dzIElPRXhjZXB0aW9uLCBYTklFeGNlcHRpb24gewotCi0gICAgICAgIC8vIGNoZWNrIHRhcmdldAotICAgICAgICBpZiAodGFyZ2V0Lmxlbmd0aCgpID09IDMpIHsKLSAgICAgICAgICAgIGNoYXIgYzAgPSBDaGFyYWN0ZXIudG9Mb3dlckNhc2UodGFyZ2V0LmNoYXJBdCgwKSk7Ci0gICAgICAgICAgICBjaGFyIGMxID0gQ2hhcmFjdGVyLnRvTG93ZXJDYXNlKHRhcmdldC5jaGFyQXQoMSkpOwotICAgICAgICAgICAgY2hhciBjMiA9IENoYXJhY3Rlci50b0xvd2VyQ2FzZSh0YXJnZXQuY2hhckF0KDIpKTsKLSAgICAgICAgICAgIGlmIChjMCA9PSAneCcgJiYgYzEgPT0gJ20nICYmIGMyID09ICdsJykgewotICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIlJlc2VydmVkUElUYXJnZXQiLCBudWxsKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIHNwYWNlcwotICAgICAgICBpZiAoIWZFbnRpdHlTY2FubmVyLnNraXBTcGFjZXMoKSkgewotICAgICAgICAgICAgaWYgKGZFbnRpdHlTY2FubmVyLnNraXBTdHJpbmcoIj8+IikpIHsKLSAgICAgICAgICAgICAgICAvLyB3ZSBmb3VuZCB0aGUgZW5kLCB0aGVyZSBpcyBubyBkYXRhIGp1c3QgcmV0dXJuCi0gICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAvLyBpZiB0aGVyZSBpcyBkYXRhIHRoZXJlIHNob3VsZCBiZSBzb21lIHNwYWNlCi0gICAgICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiU3BhY2VSZXF1aXJlZEluUEkiLCBudWxsKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIHNpbmNlIHNjYW5EYXRhIGFwcGVuZHMgdGhlIHBhcnNlZCBkYXRhIHRvIHRoZSBidWZmZXIgcGFzc2VkCi0gICAgICAgIC8vIGEgd2hpbGUgbG9vcCB3b3VsZCBhcHBlbmQgdGhlIHdob2xlIG9mIHBhcnNlZCBkYXRhIHRvIHRoZSBidWZmZXIoZGF0YTpYTUxTdHJpbmdCdWZmZXIpCi0gICAgICAgIC8vdW50aWwgYWxsIG9mIHRoZSBkYXRhIGlzIGJ1ZmZlcmVkLgotICAgICAgICBpZiAoZkVudGl0eVNjYW5uZXIuc2NhbkRhdGEoIj8+IiwgZGF0YSkpIHsKLSAgICAgICAgICAgIGRvIHsKLSAgICAgICAgICAgICAgICBpbnQgYyA9IGZFbnRpdHlTY2FubmVyLnBlZWtDaGFyKCk7Ci0gICAgICAgICAgICAgICAgaWYgKGMgIT0gLTEpIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKFhNTENoYXIuaXNIaWdoU3Vycm9nYXRlKGMpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzY2FuU3Vycm9nYXRlcyhkYXRhKTsKLSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChpc0ludmFsaWRMaXRlcmFsKGMpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJJbnZhbGlkQ2hhckluUEkiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117SW50ZWdlci50b0hleFN0cmluZyhjKX0pOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmRW50aXR5U2Nhbm5lci5zY2FuQ2hhcihudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0gd2hpbGUgKGZFbnRpdHlTY2FubmVyLnNjYW5EYXRhKCI/PiIsIGRhdGEpKTsKLSAgICAgICAgfQotCi0gICAgfSAvLyBzY2FuUElEYXRhKFN0cmluZyxYTUxTdHJpbmcpCi0KLSAgICAvKioKLSAgICAgKiBTY2FucyBhIGNvbW1lbnQuCi0gICAgICogPHA+Ci0gICAgICogPHByZT4KLSAgICAgKiBbMTVdIENvbW1lbnQgOjo9ICcmbHQhLS0nICgoQ2hhciAtICctJykgfCAoJy0nIChDaGFyIC0gJy0nKSkpKiAnLS0+JwotICAgICAqIDwvcHJlPgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gQ2FsbGVkIGFmdGVyIHNjYW5uaW5nIHBhc3QgJyZsdDshLS0nCi0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGlzIG1ldGhvZCB1c2VzIGZTdHJpbmcsIGFueXRoaW5nIGluIGl0Ci0gICAgICogYXQgdGhlIHRpbWUgb2YgY2FsbGluZyBpcyBsb3N0LgotICAgICAqCi0gICAgICogQHBhcmFtIHRleHQgVGhlIGJ1ZmZlciB0byBmaWxsIGluIHdpdGggdGhlIHRleHQuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgc2NhbkNvbW1lbnQoWE1MU3RyaW5nQnVmZmVyIHRleHQpCi0gICAgdGhyb3dzIElPRXhjZXB0aW9uLCBYTklFeGNlcHRpb24gewotCi0gICAgICAgIC8vU3lzdGVtLm91dC5wcmludGxuKCAiWE1MU2Nhbm5lciNzY2FuQ29tbWVudCMgSW4gU2NhbiBDb21tZW50IiApOwotICAgICAgICAvLyB0ZXh0Ci0gICAgICAgIC8vIFJFVklTSVQ6IGhhbmRsZSBpbnZhbGlkIGNoYXJhY3RlciwgZW9mCi0gICAgICAgIHRleHQuY2xlYXIoKTsKLSAgICAgICAgd2hpbGUgKGZFbnRpdHlTY2FubmVyLnNjYW5EYXRhKCItLSIsIHRleHQpKSB7Ci0gICAgICAgICAgICBpbnQgYyA9IGZFbnRpdHlTY2FubmVyLnBlZWtDaGFyKCk7Ci0KLSAgICAgICAgICAgIC8vU3lzdGVtLm91dC5wcmludGxuKCAiWE1MU2Nhbm5lciNzY2FuQ29tbWVudCN0ZXh0LnRvU3RyaW5nKCkgPT0gIiArIHRleHQudG9TdHJpbmcoKSApOwotICAgICAgICAgICAgLy9TeXN0ZW0ub3V0LnByaW50bG4oICJYTUxTY2FubmVyI3NjYW5Db21tZW50I2MgPT0gIiArIGMgKTsKLQotICAgICAgICAgICAgaWYgKGMgIT0gLTEpIHsKLSAgICAgICAgICAgICAgICBpZiAoWE1MQ2hhci5pc0hpZ2hTdXJyb2dhdGUoYykpIHsKLSAgICAgICAgICAgICAgICAgICAgc2NhblN1cnJvZ2F0ZXModGV4dCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgaWYgKGlzSW52YWxpZExpdGVyYWwoYykpIHsKLSAgICAgICAgICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiSW52YWxpZENoYXJJbkNvbW1lbnQiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7IEludGVnZXIudG9IZXhTdHJpbmcoYykgfSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZkVudGl0eVNjYW5uZXIuc2NhbkNoYXIoTmFtZVR5cGUuQ09NTUVOVCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGlmICghZkVudGl0eVNjYW5uZXIuc2tpcENoYXIoJz4nLCBOYW1lVHlwZS5DT01NRU5UKSkgewotICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiRGFzaERhc2hJbkNvbW1lbnQiLCBudWxsKTsKLSAgICAgICAgfQotCi0gICAgfSAvLyBzY2FuQ29tbWVudCgpCi0KLSAgICAvKioKLSAgICAgKiBTY2FucyBhbiBhdHRyaWJ1dGUgdmFsdWUgYW5kIG5vcm1hbGl6ZXMgd2hpdGVzcGFjZSBjb252ZXJ0aW5nIGFsbAotICAgICAqIHdoaXRlc3BhY2UgY2hhcmFjdGVycyB0byBzcGFjZSBjaGFyYWN0ZXJzLgotICAgICAqCi0gICAgICogWzEwXSBBdHRWYWx1ZSA6Oj0gJyInIChbXjwmIl0gfCBSZWZlcmVuY2UpKiAnIicgfCAiJyIgKFtePCYnXSB8IFJlZmVyZW5jZSkqICInIgotICAgICAqCi0gICAgICogQHBhcmFtIHZhbHVlIFRoZSBYTUxTdHJpbmcgdG8gZmlsbCBpbiB3aXRoIHRoZSB2YWx1ZS4KLSAgICAgKiBAcGFyYW0gbm9uTm9ybWFsaXplZFZhbHVlIFRoZSBYTUxTdHJpbmcgdG8gZmlsbCBpbiB3aXRoIHRoZQotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9uLW5vcm1hbGl6ZWQgdmFsdWUuCi0gICAgICogQHBhcmFtIGF0TmFtZSBUaGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlIGJlaW5nIHBhcnNlZCAoZm9yIGVycm9yIG1zZ3MpLgotICAgICAqIEBwYXJhbSBhdHRyaWJ1dGVzIFRoZSBhdHRyaWJ1dGVzIGxpc3QgZm9yIHRoZSBzY2FubmVkIGF0dHJpYnV0ZS4KLSAgICAgKiBAcGFyYW0gYXR0ckluZGV4IFRoZSBpbmRleCBvZiB0aGUgYXR0cmlidXRlIHRvIHVzZSBmcm9tIHRoZSBsaXN0LgotICAgICAqIEBwYXJhbSBjaGVja0VudGl0aWVzIHRydWUgaWYgdW5kZWNsYXJlZCBlbnRpdGllcyBzaG91bGQgYmUgcmVwb3J0ZWQgYXMgVkMgdmlvbGF0aW9uLAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGZhbHNlIGlmIHVuZGVjbGFyZWQgZW50aXRpZXMgc2hvdWxkIGJlIHJlcG9ydGVkIGFzIFdGQyB2aW9sYXRpb24uCi0gICAgICogQHBhcmFtIGVsZU5hbWUgVGhlIG5hbWUgb2YgZWxlbWVudCB0byB3aGljaCB0aGlzIGF0dHJpYnV0ZSBiZWxvbmdzLgotICAgICAqIEBwYXJhbSBpc05TVVJJIGEgZmxhZyBpbmRpY2F0aW5nIHdoZXRoZXIgdGhlIGNvbnRlbnQgaXMgYSBOYW1lc3BhY2UgVVJJCi0gICAgICoKLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoaXMgbWV0aG9kIHVzZXMgZlN0cmluZ0J1ZmZlcjIsIGFueXRoaW5nIGluIGl0Ci0gICAgICogYXQgdGhlIHRpbWUgb2YgY2FsbGluZyBpcyBsb3N0LgotICAgICAqKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCBzY2FuQXR0cmlidXRlVmFsdWUoWE1MU3RyaW5nIHZhbHVlLCBYTUxTdHJpbmcgbm9uTm9ybWFsaXplZFZhbHVlLAotICAgICAgICAgICAgU3RyaW5nIGF0TmFtZSwgWE1MQXR0cmlidXRlcyBhdHRyaWJ1dGVzLCBpbnQgYXR0ckluZGV4LCBib29sZWFuIGNoZWNrRW50aXRpZXMsCi0gICAgICAgICAgICBTdHJpbmcgZWxlTmFtZSwgYm9vbGVhbiBpc05TVVJJKQotICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBYTklFeGNlcHRpb24gewotICAgICAgICBYTUxTdHJpbmdCdWZmZXIgc3RyaW5nQnVmZmVyID0gbnVsbDsKLSAgICAgICAgLy8gcXVvdGUKLSAgICAgICAgaW50IHF1b3RlID0gZkVudGl0eVNjYW5uZXIucGVla0NoYXIoKTsKLSAgICAgICAgaWYgKHF1b3RlICE9ICdcJycgJiYgcXVvdGUgIT0gJyInKSB7Ci0gICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJPcGVuUXVvdGVFeHBlY3RlZCIsIG5ldyBPYmplY3RbXXtlbGVOYW1lLCBhdE5hbWV9KTsKLSAgICAgICAgfQotCi0gICAgICAgIGZFbnRpdHlTY2FubmVyLnNjYW5DaGFyKE5hbWVUeXBlLkFUVFJJQlVURSk7Ci0gICAgICAgIGludCBlbnRpdHlEZXB0aCA9IGZFbnRpdHlEZXB0aDsKLQotICAgICAgICBpbnQgYyA9IGZFbnRpdHlTY2FubmVyLnNjYW5MaXRlcmFsKHF1b3RlLCB2YWx1ZSwgaXNOU1VSSSk7Ci0gICAgICAgIGlmIChERUJVR19BVFRSX05PUk1BTElaQVRJT04pIHsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiKiogc2NhbkxpdGVyYWwgLT4gXCIiCi0gICAgICAgICAgICAgICAgICAgICsgdmFsdWUudG9TdHJpbmcoKSArICJcIiIpOwotICAgICAgICB9Ci0gICAgICAgIGlmKGZOZWVkTm9uTm9ybWFsaXplZFZhbHVlKXsKLSAgICAgICAgICAgIGZTdHJpbmdCdWZmZXIyLmNsZWFyKCk7Ci0gICAgICAgICAgICBmU3RyaW5nQnVmZmVyMi5hcHBlbmQodmFsdWUpOwotICAgICAgICB9Ci0gICAgICAgIGlmKGZFbnRpdHlTY2FubmVyLndoaXRlU3BhY2VMZW4gPiAwKQotICAgICAgICAgICAgbm9ybWFsaXplV2hpdGVzcGFjZSh2YWx1ZSk7Ci0gICAgICAgIGlmIChERUJVR19BVFRSX05PUk1BTElaQVRJT04pIHsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiKiogbm9ybWFsaXplV2hpdGVzcGFjZSAtPiBcIiIKLSAgICAgICAgICAgICAgICAgICAgKyB2YWx1ZS50b1N0cmluZygpICsgIlwiIik7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGMgIT0gcXVvdGUpIHsKLSAgICAgICAgICAgIGZTY2FubmluZ0F0dHJpYnV0ZSA9IHRydWU7Ci0gICAgICAgICAgICBzdHJpbmdCdWZmZXIgPSBnZXRTdHJpbmdCdWZmZXIoKTsKLSAgICAgICAgICAgIHN0cmluZ0J1ZmZlci5jbGVhcigpOwotICAgICAgICAgICAgZG8gewotICAgICAgICAgICAgICAgIHN0cmluZ0J1ZmZlci5hcHBlbmQodmFsdWUpOwotICAgICAgICAgICAgICAgIGlmIChERUJVR19BVFRSX05PUk1BTElaQVRJT04pIHsKLSAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCIqKiB2YWx1ZTI6IFwiIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgc3RyaW5nQnVmZmVyLnRvU3RyaW5nKCkgKyAiXCIiKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaWYgKGMgPT0gJyYnKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZFbnRpdHlTY2FubmVyLnNraXBDaGFyKCcmJywgTmFtZVR5cGUuUkVGRVJFTkNFKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGVudGl0eURlcHRoID09IGZFbnRpdHlEZXB0aCAmJiBmTmVlZE5vbk5vcm1hbGl6ZWRWYWx1ZSApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZTdHJpbmdCdWZmZXIyLmFwcGVuZCgnJicpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGlmIChmRW50aXR5U2Nhbm5lci5za2lwQ2hhcignIycsIE5hbWVUeXBlLlJFRkVSRU5DRSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlbnRpdHlEZXB0aCA9PSBmRW50aXR5RGVwdGggJiYgZk5lZWROb25Ob3JtYWxpemVkVmFsdWUgKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZlN0cmluZ0J1ZmZlcjIuYXBwZW5kKCcjJyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBpbnQgY2ggOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZOZWVkTm9uTm9ybWFsaXplZFZhbHVlKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoID0gc2NhbkNoYXJSZWZlcmVuY2VWYWx1ZShzdHJpbmdCdWZmZXIsIGZTdHJpbmdCdWZmZXIyKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaCA9IHNjYW5DaGFyUmVmZXJlbmNlVmFsdWUoc3RyaW5nQnVmZmVyLCBudWxsKTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNoICE9IC0xKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKERFQlVHX0FUVFJfTk9STUFMSVpBVElPTikgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIioqIHZhbHVlMzogXCIiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBzdHJpbmdCdWZmZXIudG9TdHJpbmcoKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIlwiIik7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGVudGl0eU5hbWUgPSBmRW50aXR5U2Nhbm5lci5zY2FuTmFtZShOYW1lVHlwZS5FTlRJVFkpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVudGl0eU5hbWUgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIk5hbWVSZXF1aXJlZEluUmVmZXJlbmNlIiwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGVudGl0eURlcHRoID09IGZFbnRpdHlEZXB0aCAmJiBmTmVlZE5vbk5vcm1hbGl6ZWRWYWx1ZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZTdHJpbmdCdWZmZXIyLmFwcGVuZChlbnRpdHlOYW1lKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGlmICghZkVudGl0eVNjYW5uZXIuc2tpcENoYXIoJzsnLCBOYW1lVHlwZS5SRUZFUkVOQ0UpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiU2VtaWNvbG9uUmVxdWlyZWRJblJlZmVyZW5jZSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0IFtde2VudGl0eU5hbWV9KTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZW50aXR5RGVwdGggPT0gZkVudGl0eURlcHRoICYmIGZOZWVkTm9uTm9ybWFsaXplZFZhbHVlKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZlN0cmluZ0J1ZmZlcjIuYXBwZW5kKCc7Jyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVzb2x2ZUNoYXJhY3RlcihlbnRpdHlOYW1lLCBzdHJpbmdCdWZmZXIpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tFbnRpdHlMaW1pdChmYWxzZSwgZkVudGl0eVNjYW5uZXIuZkN1cnJlbnRFbnRpdHkubmFtZSwgMSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmRW50aXR5U3RvcmUuaXNFeHRlcm5hbEVudGl0eShlbnRpdHlOYW1lKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJSZWZlcmVuY2VUb0V4dGVybmFsRW50aXR5IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBlbnRpdHlOYW1lIH0pOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghZkVudGl0eVN0b3JlLmlzRGVjbGFyZWRFbnRpdHkoZW50aXR5TmFtZSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vV0ZDICYgVkM6IEVudGl0eSBEZWNsYXJlZAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNoZWNrRW50aXRpZXMpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZlZhbGlkYXRpb24pIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IoZkVudGl0eVNjYW5uZXIsWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJFbnRpdHlOb3REZWNsYXJlZCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde2VudGl0eU5hbWV9LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTEVycm9yUmVwb3J0ZXIuU0VWRVJJVFlfRVJST1IpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiRW50aXR5Tm90RGVjbGFyZWQiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde2VudGl0eU5hbWV9KTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmRW50aXR5TWFuYWdlci5zdGFydEVudGl0eSh0cnVlLCBlbnRpdHlOYW1lLCB0cnVlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGMgPT0gJzwnKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIkxlc3N0aGFuSW5BdHRWYWx1ZSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgZWxlTmFtZSwgYXROYW1lIH0pOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZFbnRpdHlTY2FubmVyLnNjYW5DaGFyKG51bGwpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlbnRpdHlEZXB0aCA9PSBmRW50aXR5RGVwdGggJiYgZk5lZWROb25Ob3JtYWxpemVkVmFsdWUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZlN0cmluZ0J1ZmZlcjIuYXBwZW5kKChjaGFyKWMpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGMgPT0gJyUnIHx8IGMgPT0gJ10nKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZFbnRpdHlTY2FubmVyLnNjYW5DaGFyKG51bGwpOwotICAgICAgICAgICAgICAgICAgICBzdHJpbmdCdWZmZXIuYXBwZW5kKChjaGFyKWMpOwotICAgICAgICAgICAgICAgICAgICBpZiAoZW50aXR5RGVwdGggPT0gZkVudGl0eURlcHRoICYmIGZOZWVkTm9uTm9ybWFsaXplZFZhbHVlKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmU3RyaW5nQnVmZmVyMi5hcHBlbmQoKGNoYXIpYyk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgaWYgKERFQlVHX0FUVFJfTk9STUFMSVpBVElPTikgewotICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCIqKiB2YWx1ZUY6IFwiIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIHN0cmluZ0J1ZmZlci50b1N0cmluZygpICsgIlwiIik7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGMgPT0gJ1xuJyB8fCBjID09ICdccicpIHsKLSAgICAgICAgICAgICAgICAgICAgZkVudGl0eVNjYW5uZXIuc2NhbkNoYXIobnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgIHN0cmluZ0J1ZmZlci5hcHBlbmQoJyAnKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGVudGl0eURlcHRoID09IGZFbnRpdHlEZXB0aCAmJiBmTmVlZE5vbk5vcm1hbGl6ZWRWYWx1ZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgZlN0cmluZ0J1ZmZlcjIuYXBwZW5kKCdcbicpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjICE9IC0xICYmIFhNTENoYXIuaXNIaWdoU3Vycm9nYXRlKGMpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZTdHJpbmdCdWZmZXIzLmNsZWFyKCk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChzY2FuU3Vycm9nYXRlcyhmU3RyaW5nQnVmZmVyMykpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZ0J1ZmZlci5hcHBlbmQoZlN0cmluZ0J1ZmZlcjMpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVudGl0eURlcHRoID09IGZFbnRpdHlEZXB0aCAmJiBmTmVlZE5vbk5vcm1hbGl6ZWRWYWx1ZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZTdHJpbmdCdWZmZXIyLmFwcGVuZChmU3RyaW5nQnVmZmVyMyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoREVCVUdfQVRUUl9OT1JNQUxJWkFUSU9OKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCIqKiB2YWx1ZUk6IFwiIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBzdHJpbmdCdWZmZXIudG9TdHJpbmcoKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiXCIiKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYyAhPSAtMSAmJiBpc0ludmFsaWRMaXRlcmFsKGMpKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIkludmFsaWRDaGFySW5BdHRWYWx1ZSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHtlbGVOYW1lLCBhdE5hbWUsIEludGVnZXIudG9TdHJpbmcoYywgMTYpfSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZkVudGl0eVNjYW5uZXIuc2NhbkNoYXIobnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVudGl0eURlcHRoID09IGZFbnRpdHlEZXB0aCAmJiBmTmVlZE5vbk5vcm1hbGl6ZWRWYWx1ZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmU3RyaW5nQnVmZmVyMi5hcHBlbmQoKGNoYXIpYyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBjID0gZkVudGl0eVNjYW5uZXIuc2NhbkxpdGVyYWwocXVvdGUsIHZhbHVlLCBpc05TVVJJKTsKLSAgICAgICAgICAgICAgICBpZiAoZW50aXR5RGVwdGggPT0gZkVudGl0eURlcHRoICYmIGZOZWVkTm9uTm9ybWFsaXplZFZhbHVlKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZTdHJpbmdCdWZmZXIyLmFwcGVuZCh2YWx1ZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGlmKGZFbnRpdHlTY2FubmVyLndoaXRlU3BhY2VMZW4gPiAwKQotICAgICAgICAgICAgICAgICAgICBub3JtYWxpemVXaGl0ZXNwYWNlKHZhbHVlKTsKLSAgICAgICAgICAgICAgICAvL1RvZG8gOjpNb3ZlIHRoaXMgY2hlY2sgIHRvIEF0dHJpYnV0ZXMgLCBkbyBjb252ZXJzaW9uCi0gICAgICAgICAgICAgICAgLy9vbmx5IGlmIGF0dHJpYnV0ZSBpcyBiZWluZyBhY2Nlc3NlZC4gLVZlbnUKLSAgICAgICAgICAgIH0gd2hpbGUgKGMgIT0gcXVvdGUgfHwgZW50aXR5RGVwdGggIT0gZkVudGl0eURlcHRoKTsKLSAgICAgICAgICAgIHN0cmluZ0J1ZmZlci5hcHBlbmQodmFsdWUpOwotICAgICAgICAgICAgaWYgKERFQlVHX0FUVFJfTk9STUFMSVpBVElPTikgewotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiKiogdmFsdWVOOiBcIiIKLSAgICAgICAgICAgICAgICAgICAgICAgICsgc3RyaW5nQnVmZmVyLnRvU3RyaW5nKCkgKyAiXCIiKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHZhbHVlLnNldFZhbHVlcyhzdHJpbmdCdWZmZXIpOwotICAgICAgICAgICAgZlNjYW5uaW5nQXR0cmlidXRlID0gZmFsc2U7Ci0gICAgICAgIH0KLSAgICAgICAgaWYoZk5lZWROb25Ob3JtYWxpemVkVmFsdWUpCi0gICAgICAgICAgICBub25Ob3JtYWxpemVkVmFsdWUuc2V0VmFsdWVzKGZTdHJpbmdCdWZmZXIyKTsKLQotICAgICAgICAvLyBxdW90ZQotICAgICAgICBpbnQgY3F1b3RlID0gZkVudGl0eVNjYW5uZXIuc2NhbkNoYXIoTmFtZVR5cGUuQVRUUklCVVRFKTsKLSAgICAgICAgaWYgKGNxdW90ZSAhPSBxdW90ZSkgewotICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiQ2xvc2VRdW90ZUV4cGVjdGVkIiwgbmV3IE9iamVjdFtde2VsZU5hbWUsIGF0TmFtZX0pOwotICAgICAgICB9Ci0gICAgfSAvLyBzY2FuQXR0cmlidXRlVmFsdWUoKQotCi0KLSAgICAvKioKLSAgICAgKiBSZXNvbHZlcyBjaGFyYWN0ZXIgZW50aXR5IHJlZmVyZW5jZXMuCi0gICAgICogQHBhcmFtIGVudGl0eU5hbWUgdGhlIG5hbWUgb2YgdGhlIGVudGl0eQotICAgICAqIEBwYXJhbSBzdHJpbmdCdWZmZXIgdGhlIGN1cnJlbnQgWE1MU3RyaW5nQnVmZmVyIHRvIGFwcGVuZCB0aGUgY2hhcmFjdGVyIHRvLgotICAgICAqIEByZXR1cm4gdHJ1ZSBpZiByZXNvbHZlZCwgZmFsc2Ugb3RoZXJ3aXNlCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gcmVzb2x2ZUNoYXJhY3RlcihTdHJpbmcgZW50aXR5TmFtZSwgWE1MU3RyaW5nQnVmZmVyIHN0cmluZ0J1ZmZlcikgewotICAgICAgICAvKioKLSAgICAgICAgICogZW50aXR5TmFtZXMgKHN5bWJvbHMpIGFyZSBpbnRlcm5lZC4gVGhlIGVxdWFscyBtZXRob2Qgd291bGQgZG8gdGhlIHNhbWUsCi0gICAgICAgICAqIGJ1dCBJJ20gbGVhdmluZyBpdCBhcyBjb21wYXJpc29ucyBieSByZWZlcmVuY2VzIGFyZSBjb21tb24gaW4gdGhlIGltcGwKLSAgICAgICAgICogYW5kIGl0IG1hZGUgaXQgZXhwbGljaXQgdG8gb3RoZXJzIHdobyByZWFkIHRoaXMgY29kZS4KLSAgICAgICAgICovCi0gICAgICAgIGlmIChlbnRpdHlOYW1lID09IGZBbXBTeW1ib2wpIHsKLSAgICAgICAgICAgIHN0cmluZ0J1ZmZlci5hcHBlbmQoJyYnKTsKLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9IGVsc2UgaWYgKGVudGl0eU5hbWUgPT0gZkFwb3NTeW1ib2wpIHsKLSAgICAgICAgICAgIHN0cmluZ0J1ZmZlci5hcHBlbmQoJ1wnJyk7Ci0gICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgfSBlbHNlIGlmIChlbnRpdHlOYW1lID09IGZMdFN5bWJvbCkgewotICAgICAgICAgICAgc3RyaW5nQnVmZmVyLmFwcGVuZCgnPCcpOwotICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgIH0gZWxzZSBpZiAoZW50aXR5TmFtZSA9PSBmR3RTeW1ib2wpIHsKLSAgICAgICAgICAgIGNoZWNrRW50aXR5TGltaXQoZmFsc2UsIGZFbnRpdHlTY2FubmVyLmZDdXJyZW50RW50aXR5Lm5hbWUsIDEpOwotICAgICAgICAgICAgc3RyaW5nQnVmZmVyLmFwcGVuZCgnPicpOwotICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgIH0gZWxzZSBpZiAoZW50aXR5TmFtZSA9PSBmUXVvdFN5bWJvbCkgewotICAgICAgICAgICAgY2hlY2tFbnRpdHlMaW1pdChmYWxzZSwgZkVudGl0eVNjYW5uZXIuZkN1cnJlbnRFbnRpdHkubmFtZSwgMSk7Ci0gICAgICAgICAgICBzdHJpbmdCdWZmZXIuYXBwZW5kKCciJyk7Ci0gICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2NhbnMgRXh0ZXJuYWwgSUQgYW5kIHJldHVybiB0aGUgcHVibGljIGFuZCBzeXN0ZW0gSURzLgotICAgICAqCi0gICAgICogQHBhcmFtIGlkZW50aWZpZXJzIEFuIGFycmF5IG9mIHNpemUgMiB0byByZXR1cm4gdGhlIHN5c3RlbSBpZCwKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgYW5kIHB1YmxpYyBpZCAoaW4gdGhhdCBvcmRlcikuCi0gICAgICogQHBhcmFtIG9wdGlvbmFsU3lzdGVtSWQgU3BlY2lmaWVzIHdoZXRoZXIgdGhlIHN5c3RlbSBpZCBpcyBvcHRpb25hbC4KLSAgICAgKgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gVGhpcyBtZXRob2QgdXNlcyBmU3RyaW5nIGFuZCBmU3RyaW5nQnVmZmVyLAotICAgICAqIGFueXRoaW5nIGluIHRoZW0gYXQgdGhlIHRpbWUgb2YgY2FsbGluZyBpcyBsb3N0LgotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIHNjYW5FeHRlcm5hbElEKFN0cmluZ1tdIGlkZW50aWZpZXJzLAotICAgICAgICAgICAgYm9vbGVhbiBvcHRpb25hbFN5c3RlbUlkKQotICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBYTklFeGNlcHRpb24gewotCi0gICAgICAgIFN0cmluZyBzeXN0ZW1JZCA9IG51bGw7Ci0gICAgICAgIFN0cmluZyBwdWJsaWNJZCA9IG51bGw7Ci0gICAgICAgIGlmIChmRW50aXR5U2Nhbm5lci5za2lwU3RyaW5nKCJQVUJMSUMiKSkgewotICAgICAgICAgICAgaWYgKCFmRW50aXR5U2Nhbm5lci5za2lwU3BhY2VzKCkpIHsKLSAgICAgICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJTcGFjZVJlcXVpcmVkQWZ0ZXJQVUJMSUMiLCBudWxsKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHNjYW5QdWJpZExpdGVyYWwoZlN0cmluZyk7Ci0gICAgICAgICAgICBwdWJsaWNJZCA9IGZTdHJpbmcudG9TdHJpbmcoKTsKLQotICAgICAgICAgICAgaWYgKCFmRW50aXR5U2Nhbm5lci5za2lwU3BhY2VzKCkgJiYgIW9wdGlvbmFsU3lzdGVtSWQpIHsKLSAgICAgICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJTcGFjZVJlcXVpcmVkQmV0d2VlblB1YmxpY0FuZFN5c3RlbSIsIG51bGwpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKHB1YmxpY0lkICE9IG51bGwgfHwgZkVudGl0eVNjYW5uZXIuc2tpcFN0cmluZygiU1lTVEVNIikpIHsKLSAgICAgICAgICAgIGlmIChwdWJsaWNJZCA9PSBudWxsICYmICFmRW50aXR5U2Nhbm5lci5za2lwU3BhY2VzKCkpIHsKLSAgICAgICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJTcGFjZVJlcXVpcmVkQWZ0ZXJTWVNURU0iLCBudWxsKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGludCBxdW90ZSA9IGZFbnRpdHlTY2FubmVyLnBlZWtDaGFyKCk7Ci0gICAgICAgICAgICBpZiAocXVvdGUgIT0gJ1wnJyAmJiBxdW90ZSAhPSAnIicpIHsKLSAgICAgICAgICAgICAgICBpZiAocHVibGljSWQgIT0gbnVsbCAmJiBvcHRpb25hbFN5c3RlbUlkKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIGxvb2tzIGxpa2Ugd2UgZG9uJ3QgaGF2ZSBhbnkgc3lzdGVtIGlkCi0gICAgICAgICAgICAgICAgICAgIC8vIHNpbXBseSByZXR1cm4gdGhlIHB1YmxpYyBpZAotICAgICAgICAgICAgICAgICAgICBpZGVudGlmaWVyc1swXSA9IG51bGw7Ci0gICAgICAgICAgICAgICAgICAgIGlkZW50aWZpZXJzWzFdID0gcHVibGljSWQ7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiUXVvdGVSZXF1aXJlZEluU3lzdGVtSUQiLCBudWxsKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGZFbnRpdHlTY2FubmVyLnNjYW5DaGFyKG51bGwpOwotICAgICAgICAgICAgWE1MU3RyaW5nIGlkZW50ID0gZlN0cmluZzsKLSAgICAgICAgICAgIGlmIChmRW50aXR5U2Nhbm5lci5zY2FuTGl0ZXJhbChxdW90ZSwgaWRlbnQsIGZhbHNlKSAhPSBxdW90ZSkgewotICAgICAgICAgICAgICAgIGZTdHJpbmdCdWZmZXIuY2xlYXIoKTsKLSAgICAgICAgICAgICAgICBkbyB7Ci0gICAgICAgICAgICAgICAgICAgIGZTdHJpbmdCdWZmZXIuYXBwZW5kKGlkZW50KTsKLSAgICAgICAgICAgICAgICAgICAgaW50IGMgPSBmRW50aXR5U2Nhbm5lci5wZWVrQ2hhcigpOwotICAgICAgICAgICAgICAgICAgICBpZiAoWE1MQ2hhci5pc01hcmt1cChjKSB8fCBjID09ICddJykgewotICAgICAgICAgICAgICAgICAgICAgICAgZlN0cmluZ0J1ZmZlci5hcHBlbmQoKGNoYXIpZkVudGl0eVNjYW5uZXIuc2NhbkNoYXIobnVsbCkpOwotICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGMgIT0gLTEgJiYgaXNJbnZhbGlkTGl0ZXJhbChjKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiSW52YWxpZENoYXJJblN5c3RlbUlEIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10ge0ludGVnZXIudG9TdHJpbmcoYywgMTYpfSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9IHdoaWxlIChmRW50aXR5U2Nhbm5lci5zY2FuTGl0ZXJhbChxdW90ZSwgaWRlbnQsIGZhbHNlKSAhPSBxdW90ZSk7Ci0gICAgICAgICAgICAgICAgZlN0cmluZ0J1ZmZlci5hcHBlbmQoaWRlbnQpOwotICAgICAgICAgICAgICAgIGlkZW50ID0gZlN0cmluZ0J1ZmZlcjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHN5c3RlbUlkID0gaWRlbnQudG9TdHJpbmcoKTsKLSAgICAgICAgICAgIGlmICghZkVudGl0eVNjYW5uZXIuc2tpcENoYXIocXVvdGUsIG51bGwpKSB7Ci0gICAgICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiU3lzdGVtSURVbnRlcm1pbmF0ZWQiLCBudWxsKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIHN0b3JlIHJlc3VsdCBpbiBhcnJheQotICAgICAgICBpZGVudGlmaWVyc1swXSA9IHN5c3RlbUlkOwotICAgICAgICBpZGVudGlmaWVyc1sxXSA9IHB1YmxpY0lkOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogU2NhbnMgcHVibGljIElEIGxpdGVyYWwuCi0gICAgICoKLSAgICAgKiBbMTJdIFB1YmlkTGl0ZXJhbCA6Oj0gJyInIFB1YmlkQ2hhciogJyInIHwgIiciIChQdWJpZENoYXIgLSAiJyIpKiAiJyIKLSAgICAgKiBbMTNdIFB1YmlkQ2hhcjo6PSAjeDIwIHwgI3hEIHwgI3hBIHwgW2EtekEtWjAtOV0gfCBbLScoKSssLi86PT87ISojQCRfJV0KLSAgICAgKgotICAgICAqIFRoZSByZXR1cm5lZCBzdHJpbmcgaXMgbm9ybWFsaXplZCBhY2NvcmRpbmcgdG8gdGhlIGZvbGxvd2luZyBydWxlLAotICAgICAqIGZyb20gaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLXhtbCNkdC1wdWJpZDoKLSAgICAgKgotICAgICAqIEJlZm9yZSBhIG1hdGNoIGlzIGF0dGVtcHRlZCwgYWxsIHN0cmluZ3Mgb2Ygd2hpdGUgc3BhY2UgaW4gdGhlIHB1YmxpYwotICAgICAqIGlkZW50aWZpZXIgbXVzdCBiZSBub3JtYWxpemVkIHRvIHNpbmdsZSBzcGFjZSBjaGFyYWN0ZXJzICgjeDIwKSwgYW5kCi0gICAgICogbGVhZGluZyBhbmQgdHJhaWxpbmcgd2hpdGUgc3BhY2UgbXVzdCBiZSByZW1vdmVkLgotICAgICAqCi0gICAgICogQHBhcmFtIGxpdGVyYWwgVGhlIHN0cmluZyB0byBmaWxsIGluIHdpdGggdGhlIHB1YmxpYyBJRCBsaXRlcmFsLgotICAgICAqIEByZXR1cm4gVHJ1ZSBvbiBzdWNjZXNzLgotICAgICAqCi0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGlzIG1ldGhvZCB1c2VzIGZTdHJpbmdCdWZmZXIsIGFueXRoaW5nIGluIGl0IGF0Ci0gICAgICogdGhlIHRpbWUgb2YgY2FsbGluZyBpcyBsb3N0LgotICAgICAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIHNjYW5QdWJpZExpdGVyYWwoWE1MU3RyaW5nIGxpdGVyYWwpCi0gICAgdGhyb3dzIElPRXhjZXB0aW9uLCBYTklFeGNlcHRpb24gewotICAgICAgICBpbnQgcXVvdGUgPSBmRW50aXR5U2Nhbm5lci5zY2FuQ2hhcihudWxsKTsKLSAgICAgICAgaWYgKHF1b3RlICE9ICdcJycgJiYgcXVvdGUgIT0gJyInKSB7Ci0gICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJRdW90ZVJlcXVpcmVkSW5QdWJsaWNJRCIsIG51bGwpOwotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0KLSAgICAgICAgZlN0cmluZ0J1ZmZlci5jbGVhcigpOwotICAgICAgICAvLyBza2lwIGxlYWRpbmcgd2hpdGVzcGFjZQotICAgICAgICBib29sZWFuIHNraXBTcGFjZSA9IHRydWU7Ci0gICAgICAgIGJvb2xlYW4gZGF0YW9rID0gdHJ1ZTsKLSAgICAgICAgd2hpbGUgKHRydWUpIHsKLSAgICAgICAgICAgIGludCBjID0gZkVudGl0eVNjYW5uZXIuc2NhbkNoYXIobnVsbCk7Ci0gICAgICAgICAgICBpZiAoYyA9PSAnICcgfHwgYyA9PSAnXG4nIHx8IGMgPT0gJ1xyJykgewotICAgICAgICAgICAgICAgIGlmICghc2tpcFNwYWNlKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIHRha2UgdGhlIGZpcnN0IHdoaXRlc3BhY2UgYXMgYSBzcGFjZSBhbmQgc2tpcCB0aGUgb3RoZXJzCi0gICAgICAgICAgICAgICAgICAgIGZTdHJpbmdCdWZmZXIuYXBwZW5kKCcgJyk7Ci0gICAgICAgICAgICAgICAgICAgIHNraXBTcGFjZSA9IHRydWU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfSBlbHNlIGlmIChjID09IHF1b3RlKSB7Ci0gICAgICAgICAgICAgICAgaWYgKHNraXBTcGFjZSkgewotICAgICAgICAgICAgICAgICAgICAvLyBpZiB3ZSBmaW5pc2hlZCBvbiBhIHNwYWNlIGxldCdzIHRyaW0gaXQKLSAgICAgICAgICAgICAgICAgICAgZlN0cmluZ0J1ZmZlci5sZW5ndGgtLTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgbGl0ZXJhbC5zZXRWYWx1ZXMoZlN0cmluZ0J1ZmZlcik7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9IGVsc2UgaWYgKFhNTENoYXIuaXNQdWJpZChjKSkgewotICAgICAgICAgICAgICAgIGZTdHJpbmdCdWZmZXIuYXBwZW5kKChjaGFyKWMpOwotICAgICAgICAgICAgICAgIHNraXBTcGFjZSA9IGZhbHNlOwotICAgICAgICAgICAgfSBlbHNlIGlmIChjID09IC0xKSB7Ci0gICAgICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiUHVibGljSURVbnRlcm1pbmF0ZWQiLCBudWxsKTsKLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIGRhdGFvayA9IGZhbHNlOwotICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIkludmFsaWRDaGFySW5QdWJsaWNJRCIsCi0gICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117SW50ZWdlci50b0hleFN0cmluZyhjKX0pOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBkYXRhb2s7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBOb3JtYWxpemUgd2hpdGVzcGFjZSBpbiBhbiBYTUxTdHJpbmcgY29udmVydGluZyBhbGwgd2hpdGVzcGFjZQotICAgICAqIGNoYXJhY3RlcnMgdG8gc3BhY2UgY2hhcmFjdGVycy4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCBub3JtYWxpemVXaGl0ZXNwYWNlKFhNTFN0cmluZyB2YWx1ZSkgewotICAgICAgICBpbnQgaT0wOwotICAgICAgICBpbnQgaj0wOwotICAgICAgICBpbnQgW10gYnVmZiA9IGZFbnRpdHlTY2FubmVyLndoaXRlU3BhY2VMb29rdXA7Ci0gICAgICAgIGludCBidWZmTGVuID0gZkVudGl0eVNjYW5uZXIud2hpdGVTcGFjZUxlbjsKLSAgICAgICAgaW50IGVuZCA9IHZhbHVlLm9mZnNldCArIHZhbHVlLmxlbmd0aDsKLSAgICAgICAgd2hpbGUoaSA8IGJ1ZmZMZW4pewotICAgICAgICAgICAgaiA9IGJ1ZmZbaV07Ci0gICAgICAgICAgICBpZihqIDwgZW5kICl7Ci0gICAgICAgICAgICAgICAgdmFsdWUuY2hbal0gPSAnICc7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpKys7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvLwotICAgIC8vIFhNTEVudGl0eUhhbmRsZXIgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBub3RpZmllcyBvZiB0aGUgc3RhcnQgb2YgYW4gZW50aXR5LiBUaGUgZG9jdW1lbnQgZW50aXR5Ci0gICAgICogaGFzIHRoZSBwc2V1ZG8tbmFtZSBvZiAiW3htbF0iIHRoZSBEVEQgaGFzIHRoZSBwc2V1ZG8tbmFtZSBvZiAiW2R0ZF0iCi0gICAgICogcGFyYW1ldGVyIGVudGl0eSBuYW1lcyBzdGFydCB3aXRoICclJzsgYW5kIGdlbmVyYWwgZW50aXRpZXMgYXJlIGp1c3QKLSAgICAgKiBzcGVjaWZpZWQgYnkgdGhlaXIgbmFtZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lICAgICBUaGUgbmFtZSBvZiB0aGUgZW50aXR5LgotICAgICAqIEBwYXJhbSBpZGVudGlmaWVyIFRoZSByZXNvdXJjZSBpZGVudGlmaWVyLgotICAgICAqIEBwYXJhbSBlbmNvZGluZyBUaGUgYXV0by1kZXRlY3RlZCBJQU5BIGVuY29kaW5nIG5hbWUgb2YgdGhlIGVudGl0eQotICAgICAqICAgICAgICAgICAgICAgICBzdHJlYW0uIFRoaXMgdmFsdWUgd2lsbCBiZSBudWxsIGluIHRob3NlIHNpdHVhdGlvbnMKLSAgICAgKiAgICAgICAgICAgICAgICAgd2hlcmUgdGhlIGVudGl0eSBlbmNvZGluZyBpcyBub3QgYXV0by1kZXRlY3RlZCAoZS5nLgotICAgICAqICAgICAgICAgICAgICAgICBpbnRlcm5hbCBlbnRpdGllcyBvciBhIGRvY3VtZW50IGVudGl0eSB0aGF0IGlzCi0gICAgICogICAgICAgICAgICAgICAgIHBhcnNlZCBmcm9tIGEgamF2YS5pby5SZWFkZXIpLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RW50aXR5KFN0cmluZyBuYW1lLAotICAgICAgICAgICAgWE1MUmVzb3VyY2VJZGVudGlmaWVyIGlkZW50aWZpZXIsCi0gICAgICAgICAgICBTdHJpbmcgZW5jb2RpbmcsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy8ga2VlcCB0cmFjayBvZiB0aGUgZW50aXR5IGRlcHRoCi0gICAgICAgIGZFbnRpdHlEZXB0aCsrOwotICAgICAgICAvLyBtdXN0IHJlc2V0IGVudGl0eSBzY2FubmVyCi0gICAgICAgIGZFbnRpdHlTY2FubmVyID0gZkVudGl0eU1hbmFnZXIuZ2V0RW50aXR5U2Nhbm5lcigpOwotICAgICAgICBmRW50aXR5U3RvcmUgPSBmRW50aXR5TWFuYWdlci5nZXRFbnRpdHlTdG9yZSgpIDsKLSAgICB9IC8vIHN0YXJ0RW50aXR5KFN0cmluZyxYTUxSZXNvdXJjZUlkZW50aWZpZXIsU3RyaW5nKQotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2Qgbm90aWZpZXMgdGhlIGVuZCBvZiBhbiBlbnRpdHkuIFRoZSBkb2N1bWVudCBlbnRpdHkgaGFzCi0gICAgICogdGhlIHBzZXVkby1uYW1lIG9mICJbeG1sXSIgdGhlIERURCBoYXMgdGhlIHBzZXVkby1uYW1lIG9mICJbZHRkXSIKLSAgICAgKiBwYXJhbWV0ZXIgZW50aXR5IG5hbWVzIHN0YXJ0IHdpdGggJyUnOyBhbmQgZ2VuZXJhbCBlbnRpdGllcyBhcmUganVzdAotICAgICAqIHNwZWNpZmllZCBieSB0aGVpciBuYW1lLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGVudGl0eS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbmRFbnRpdHkoU3RyaW5nIG5hbWUsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIElPRXhjZXB0aW9uLCBYTklFeGNlcHRpb24gewotCi0gICAgICAgIC8vIGtlZXAgdHJhY2sgb2YgdGhlIGVudGl0eSBkZXB0aAotICAgICAgICBmRW50aXR5RGVwdGgtLTsKLQotICAgIH0gLy8gZW5kRW50aXR5KFN0cmluZykKLQotICAgIC8qKgotICAgICAqIFNjYW5zIGEgY2hhcmFjdGVyIHJlZmVyZW5jZSBhbmQgYXBwZW5kIHRoZSBjb3JyZXNwb25kaW5nIGNoYXJzIHRvIHRoZQotICAgICAqIHNwZWNpZmllZCBidWZmZXIuCi0gICAgICoKLSAgICAgKiA8cD4KLSAgICAgKiA8cHJlPgotICAgICAqIFs2Nl0gQ2hhclJlZiA6Oj0gJyYjJyBbMC05XSsgJzsnIHwgJyYjeCcgWzAtOWEtZkEtRl0rICc7JwotICAgICAqIDwvcHJlPgotICAgICAqCi0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGlzIG1ldGhvZCB1c2VzIGZTdHJpbmdCdWZmZXIsIGFueXRoaW5nIGluIGl0Ci0gICAgICogYXQgdGhlIHRpbWUgb2YgY2FsbGluZyBpcyBsb3N0LgotICAgICAqCi0gICAgICogQHBhcmFtIGJ1ZiB0aGUgY2hhcmFjdGVyIGJ1ZmZlciB0byBhcHBlbmQgY2hhcnMgdG8KLSAgICAgKiBAcGFyYW0gYnVmMiB0aGUgY2hhcmFjdGVyIGJ1ZmZlciB0byBhcHBlbmQgbm9uLW5vcm1hbGl6ZWQgY2hhcnMgdG8KLSAgICAgKgotICAgICAqIEByZXR1cm4gdGhlIGNoYXJhY3RlciB2YWx1ZSBvciAoLTEpIG9uIGNvbnZlcnNpb24gZmFpbHVyZQotICAgICAqLwotICAgIHByb3RlY3RlZCBpbnQgc2NhbkNoYXJSZWZlcmVuY2VWYWx1ZShYTUxTdHJpbmdCdWZmZXIgYnVmLCBYTUxTdHJpbmdCdWZmZXIgYnVmMikKLSAgICB0aHJvd3MgSU9FeGNlcHRpb24sIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIGludCBpbml0TGVuID0gYnVmLmxlbmd0aDsKLSAgICAgICAgLy8gc2NhbiBoZXhhZGVjaW1hbCB2YWx1ZQotICAgICAgICBib29sZWFuIGhleCA9IGZhbHNlOwotICAgICAgICBpZiAoZkVudGl0eVNjYW5uZXIuc2tpcENoYXIoJ3gnLCBOYW1lVHlwZS5SRUZFUkVOQ0UpKSB7Ci0gICAgICAgICAgICBpZiAoYnVmMiAhPSBudWxsKSB7IGJ1ZjIuYXBwZW5kKCd4Jyk7IH0KLSAgICAgICAgICAgIGhleCA9IHRydWU7Ci0gICAgICAgICAgICBmU3RyaW5nQnVmZmVyMy5jbGVhcigpOwotICAgICAgICAgICAgYm9vbGVhbiBkaWdpdCA9IHRydWU7Ci0KLSAgICAgICAgICAgIGludCBjID0gZkVudGl0eVNjYW5uZXIucGVla0NoYXIoKTsKLSAgICAgICAgICAgIGRpZ2l0ID0gKGMgPj0gJzAnICYmIGMgPD0gJzknKSB8fAotICAgICAgICAgICAgICAgICAgICAoYyA+PSAnYScgJiYgYyA8PSAnZicpIHx8Ci0gICAgICAgICAgICAgICAgICAgIChjID49ICdBJyAmJiBjIDw9ICdGJyk7Ci0gICAgICAgICAgICBpZiAoZGlnaXQpIHsKLSAgICAgICAgICAgICAgICBpZiAoYnVmMiAhPSBudWxsKSB7IGJ1ZjIuYXBwZW5kKChjaGFyKWMpOyB9Ci0gICAgICAgICAgICAgICAgZkVudGl0eVNjYW5uZXIuc2NhbkNoYXIoTmFtZVR5cGUuUkVGRVJFTkNFKTsKLSAgICAgICAgICAgICAgICBmU3RyaW5nQnVmZmVyMy5hcHBlbmQoKGNoYXIpYyk7Ci0KLSAgICAgICAgICAgICAgICBkbyB7Ci0gICAgICAgICAgICAgICAgICAgIGMgPSBmRW50aXR5U2Nhbm5lci5wZWVrQ2hhcigpOwotICAgICAgICAgICAgICAgICAgICBkaWdpdCA9IChjID49ICcwJyAmJiBjIDw9ICc5JykgfHwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYyA+PSAnYScgJiYgYyA8PSAnZicpIHx8Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGMgPj0gJ0EnICYmIGMgPD0gJ0YnKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGRpZ2l0KSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYnVmMiAhPSBudWxsKSB7IGJ1ZjIuYXBwZW5kKChjaGFyKWMpOyB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBmRW50aXR5U2Nhbm5lci5zY2FuQ2hhcihOYW1lVHlwZS5SRUZFUkVOQ0UpOwotICAgICAgICAgICAgICAgICAgICAgICAgZlN0cmluZ0J1ZmZlcjMuYXBwZW5kKChjaGFyKWMpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfSB3aGlsZSAoZGlnaXQpOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJIZXhkaWdpdFJlcXVpcmVkSW5DaGFyUmVmIiwgbnVsbCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBzY2FuIGRlY2ltYWwgdmFsdWUKLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBmU3RyaW5nQnVmZmVyMy5jbGVhcigpOwotICAgICAgICAgICAgYm9vbGVhbiBkaWdpdCA9IHRydWU7Ci0KLSAgICAgICAgICAgIGludCBjID0gZkVudGl0eVNjYW5uZXIucGVla0NoYXIoKTsKLSAgICAgICAgICAgIGRpZ2l0ID0gYyA+PSAnMCcgJiYgYyA8PSAnOSc7Ci0gICAgICAgICAgICBpZiAoZGlnaXQpIHsKLSAgICAgICAgICAgICAgICBpZiAoYnVmMiAhPSBudWxsKSB7IGJ1ZjIuYXBwZW5kKChjaGFyKWMpOyB9Ci0gICAgICAgICAgICAgICAgZkVudGl0eVNjYW5uZXIuc2NhbkNoYXIoTmFtZVR5cGUuUkVGRVJFTkNFKTsKLSAgICAgICAgICAgICAgICBmU3RyaW5nQnVmZmVyMy5hcHBlbmQoKGNoYXIpYyk7Ci0KLSAgICAgICAgICAgICAgICBkbyB7Ci0gICAgICAgICAgICAgICAgICAgIGMgPSBmRW50aXR5U2Nhbm5lci5wZWVrQ2hhcigpOwotICAgICAgICAgICAgICAgICAgICBkaWdpdCA9IGMgPj0gJzAnICYmIGMgPD0gJzknOwotICAgICAgICAgICAgICAgICAgICBpZiAoZGlnaXQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChidWYyICE9IG51bGwpIHsgYnVmMi5hcHBlbmQoKGNoYXIpYyk7IH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGZFbnRpdHlTY2FubmVyLnNjYW5DaGFyKE5hbWVUeXBlLlJFRkVSRU5DRSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmU3RyaW5nQnVmZmVyMy5hcHBlbmQoKGNoYXIpYyk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9IHdoaWxlIChkaWdpdCk7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIkRpZ2l0UmVxdWlyZWRJbkNoYXJSZWYiLCBudWxsKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIGVuZAotICAgICAgICBpZiAoIWZFbnRpdHlTY2FubmVyLnNraXBDaGFyKCc7JywgTmFtZVR5cGUuUkVGRVJFTkNFKSkgewotICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiU2VtaWNvbG9uUmVxdWlyZWRJbkNoYXJSZWYiLCBudWxsKTsKLSAgICAgICAgfQotICAgICAgICBpZiAoYnVmMiAhPSBudWxsKSB7IGJ1ZjIuYXBwZW5kKCc7Jyk7IH0KLQotICAgICAgICAvLyBjb252ZXJ0IHN0cmluZyB0byBudW1iZXIKLSAgICAgICAgaW50IHZhbHVlID0gLTE7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICB2YWx1ZSA9IEludGVnZXIucGFyc2VJbnQoZlN0cmluZ0J1ZmZlcjMudG9TdHJpbmcoKSwKLSAgICAgICAgICAgICAgICAgICAgaGV4ID8gMTYgOiAxMCk7Ci0KLSAgICAgICAgICAgIC8vIGNoYXJhY3RlciByZWZlcmVuY2UgbXVzdCBiZSBhIHZhbGlkIFhNTCBjaGFyYWN0ZXIKLSAgICAgICAgICAgIGlmIChpc0ludmFsaWQodmFsdWUpKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nQnVmZmVyIGVycm9yQnVmID0gbmV3IFN0cmluZ0J1ZmZlcihmU3RyaW5nQnVmZmVyMy5sZW5ndGggKyAxKTsKLSAgICAgICAgICAgICAgICBpZiAoaGV4KSBlcnJvckJ1Zi5hcHBlbmQoJ3gnKTsKLSAgICAgICAgICAgICAgICBlcnJvckJ1Zi5hcHBlbmQoZlN0cmluZ0J1ZmZlcjMuY2gsIGZTdHJpbmdCdWZmZXIzLm9mZnNldCwgZlN0cmluZ0J1ZmZlcjMubGVuZ3RoKTsKLSAgICAgICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJJbnZhbGlkQ2hhclJlZiIsCi0gICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117ZXJyb3JCdWYudG9TdHJpbmcoKX0pOwotICAgICAgICAgICAgfQotICAgICAgICB9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgLy8gQ29udmVyc2lvbiBmYWlsZWQsIGxldCAtMSB2YWx1ZSBkcm9wIHRocm91Z2guCi0gICAgICAgICAgICAvLyBJZiB3ZSBlbmQgdXAgaGVyZSwgdGhlIGNoYXJhY3RlciByZWZlcmVuY2Ugd2FzIGludmFsaWQuCi0gICAgICAgICAgICBTdHJpbmdCdWZmZXIgZXJyb3JCdWYgPSBuZXcgU3RyaW5nQnVmZmVyKGZTdHJpbmdCdWZmZXIzLmxlbmd0aCArIDEpOwotICAgICAgICAgICAgaWYgKGhleCkgZXJyb3JCdWYuYXBwZW5kKCd4Jyk7Ci0gICAgICAgICAgICBlcnJvckJ1Zi5hcHBlbmQoZlN0cmluZ0J1ZmZlcjMuY2gsIGZTdHJpbmdCdWZmZXIzLm9mZnNldCwgZlN0cmluZ0J1ZmZlcjMubGVuZ3RoKTsKLSAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIkludmFsaWRDaGFyUmVmIiwKLSAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde2Vycm9yQnVmLnRvU3RyaW5nKCl9KTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIGFwcGVuZCBjb3JyZXNwb25kaW5nIGNoYXJzIHRvIHRoZSBnaXZlbiBidWZmZXIKLSAgICAgICAgaWYgKCFYTUxDaGFyLmlzU3VwcGxlbWVudGFsKHZhbHVlKSkgewotICAgICAgICAgICAgYnVmLmFwcGVuZCgoY2hhcikgdmFsdWUpOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgLy8gY2hhcmFjdGVyIGlzIHN1cHBsZW1lbnRhbCwgc3BsaXQgaXQgaW50byBzdXJyb2dhdGUgY2hhcnMKLSAgICAgICAgICAgIGJ1Zi5hcHBlbmQoWE1MQ2hhci5oaWdoU3Vycm9nYXRlKHZhbHVlKSk7Ci0gICAgICAgICAgICBidWYuYXBwZW5kKFhNTENoYXIubG93U3Vycm9nYXRlKHZhbHVlKSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBjaGFyIHJlZnMgbm90aWZpY2F0aW9uIGNvZGUKLSAgICAgICAgaWYgKGZOb3RpZnlDaGFyUmVmcyAmJiB2YWx1ZSAhPSAtMSkgewotICAgICAgICAgICAgU3RyaW5nIGxpdGVyYWwgPSAiIyIgKyAoaGV4ID8gIngiIDogIiIpICsgZlN0cmluZ0J1ZmZlcjMudG9TdHJpbmcoKTsKLSAgICAgICAgICAgIGlmICghZlNjYW5uaW5nQXR0cmlidXRlKSB7Ci0gICAgICAgICAgICAgICAgZkNoYXJSZWZMaXRlcmFsID0gbGl0ZXJhbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGlmIChmRW50aXR5U2Nhbm5lci5mQ3VycmVudEVudGl0eS5pc0dFKSB7Ci0gICAgICAgICAgICBjaGVja0VudGl0eUxpbWl0KGZhbHNlLCBmRW50aXR5U2Nhbm5lci5mQ3VycmVudEVudGl0eS5uYW1lLCBidWYubGVuZ3RoIC0gaW5pdExlbik7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHZhbHVlOwotICAgIH0KLSAgICAvLyByZXR1cm5zIHRydWUgaWYgdGhlIGdpdmVuIGNoYXJhY3RlciBpcyBub3QKLSAgICAvLyB2YWxpZCB3aXRoIHJlc3BlY3QgdG8gdGhlIHZlcnNpb24gb2YKLSAgICAvLyBYTUwgdW5kZXJzdG9vZCBieSB0aGlzIHNjYW5uZXIuCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gaXNJbnZhbGlkKGludCB2YWx1ZSkgewotICAgICAgICByZXR1cm4gKFhNTENoYXIuaXNJbnZhbGlkKHZhbHVlKSk7Ci0gICAgfSAvLyBpc0ludmFsaWQoaW50KTogIGJvb2xlYW4KLQotICAgIC8vIHJldHVybnMgdHJ1ZSBpZiB0aGUgZ2l2ZW4gY2hhcmFjdGVyIGlzIG5vdAotICAgIC8vIHZhbGlkIG9yIG1heSBub3QgYmUgdXNlZCBvdXRzaWRlIGEgY2hhcmFjdGVyIHJlZmVyZW5jZQotICAgIC8vIHdpdGggcmVzcGVjdCB0byB0aGUgdmVyc2lvbiBvZiBYTUwgdW5kZXJzdG9vZCBieSB0aGlzIHNjYW5uZXIuCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gaXNJbnZhbGlkTGl0ZXJhbChpbnQgdmFsdWUpIHsKLSAgICAgICAgcmV0dXJuIChYTUxDaGFyLmlzSW52YWxpZCh2YWx1ZSkpOwotICAgIH0gLy8gaXNJbnZhbGlkTGl0ZXJhbChpbnQpOiAgYm9vbGVhbgotCi0gICAgLy8gcmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiBjaGFyYWN0ZXIgaXMKLSAgICAvLyBhIHZhbGlkIG5hbWVDaGFyIHdpdGggcmVzcGVjdCB0byB0aGUgdmVyc2lvbiBvZgotICAgIC8vIFhNTCB1bmRlcnN0b29kIGJ5IHRoaXMgc2Nhbm5lci4KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBpc1ZhbGlkTmFtZUNoYXIoaW50IHZhbHVlKSB7Ci0gICAgICAgIHJldHVybiAoWE1MQ2hhci5pc05hbWUodmFsdWUpKTsKLSAgICB9IC8vIGlzVmFsaWROYW1lQ2hhcihpbnQpOiAgYm9vbGVhbgotCi0gICAgLy8gcmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiBjaGFyYWN0ZXIgaXMKLSAgICAvLyBhIHZhbGlkIE5DTmFtZSBjaGFyYWN0ZXIgd2l0aCByZXNwZWN0IHRvIHRoZSB2ZXJzaW9uIG9mCi0gICAgLy8gWE1MIHVuZGVyc3Rvb2QgYnkgdGhpcyBzY2FubmVyLgotICAgIHByb3RlY3RlZCBib29sZWFuIGlzVmFsaWROQ05hbWUoaW50IHZhbHVlKSB7Ci0gICAgICAgIHJldHVybiAoWE1MQ2hhci5pc05DTmFtZSh2YWx1ZSkpOwotICAgIH0gLy8gaXNWYWxpZE5DTmFtZShpbnQpOiAgYm9vbGVhbgotCi0gICAgLy8gcmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiBjaGFyYWN0ZXIgaXMKLSAgICAvLyBhIHZhbGlkIG5hbWVTdGFydENoYXIgd2l0aCByZXNwZWN0IHRvIHRoZSB2ZXJzaW9uIG9mCi0gICAgLy8gWE1MIHVuZGVyc3Rvb2QgYnkgdGhpcyBzY2FubmVyLgotICAgIHByb3RlY3RlZCBib29sZWFuIGlzVmFsaWROYW1lU3RhcnRDaGFyKGludCB2YWx1ZSkgewotICAgICAgICByZXR1cm4gKFhNTENoYXIuaXNOYW1lU3RhcnQodmFsdWUpKTsKLSAgICB9IC8vIGlzVmFsaWROYW1lU3RhcnRDaGFyKGludCk6ICBib29sZWFuCi0KLSAgICAvLyByZXR1cm5zIHRydWUgaWYgdGhlIGdpdmVuIGNoYXJhY3RlciBpcwotICAgIC8vIGEgdmFsaWQgaGlnaCBzdXJyb2dhdGUgZm9yIGEgbmFtZVN0YXJ0Q2hhcgotICAgIC8vIHdpdGggcmVzcGVjdCB0byB0aGUgdmVyc2lvbiBvZiBYTUwgdW5kZXJzdG9vZAotICAgIC8vIGJ5IHRoaXMgc2Nhbm5lci4KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBpc1ZhbGlkTmFtZVN0YXJ0SGlnaFN1cnJvZ2F0ZShpbnQgdmFsdWUpIHsKLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0gLy8gaXNWYWxpZE5hbWVTdGFydEhpZ2hTdXJyb2dhdGUoaW50KTogIGJvb2xlYW4KLQotICAgIHByb3RlY3RlZCBib29sZWFuIHZlcnNpb25TdXBwb3J0ZWQoU3RyaW5nIHZlcnNpb24gKSB7Ci0gICAgICAgIHJldHVybiB2ZXJzaW9uLmVxdWFscygiMS4wIikgfHwgdmVyc2lvbi5lcXVhbHMoIjEuMSIpOwotICAgIH0gLy8gdmVyc2lvbiBTdXBwb3J0ZWQKLQotICAgIC8qKgotICAgICAqIFNjYW5zIHN1cnJvZ2F0ZXMgYW5kIGFwcGVuZCB0aGVtIHRvIHRoZSBzcGVjaWZpZWQgYnVmZmVyLgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gVGhpcyBhc3N1bWVzIHRoZSBjdXJyZW50IGNoYXIgaGFzIGFscmVhZHkgYmVlbgotICAgICAqIGlkZW50aWZpZWQgYXMgYSBoaWdoIHN1cnJvZ2F0ZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBidWYgVGhlIFN0cmluZ0J1ZmZlciB0byBhcHBlbmQgdGhlIHJlYWQgc3Vycm9nYXRlcyB0by4KLSAgICAgKiBAcmV0dXJuIFRydWUgaWYgaXQgc3VjY2VlZGVkLgotICAgICAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIHNjYW5TdXJyb2dhdGVzKFhNTFN0cmluZ0J1ZmZlciBidWYpCi0gICAgdGhyb3dzIElPRXhjZXB0aW9uLCBYTklFeGNlcHRpb24gewotCi0gICAgICAgIGludCBoaWdoID0gZkVudGl0eVNjYW5uZXIuc2NhbkNoYXIobnVsbCk7Ci0gICAgICAgIGludCBsb3cgPSBmRW50aXR5U2Nhbm5lci5wZWVrQ2hhcigpOwotICAgICAgICBpZiAoIVhNTENoYXIuaXNMb3dTdXJyb2dhdGUobG93KSkgewotICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiSW52YWxpZENoYXJJbkNvbnRlbnQiLAotICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10ge0ludGVnZXIudG9TdHJpbmcoaGlnaCwgMTYpfSk7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotICAgICAgICBmRW50aXR5U2Nhbm5lci5zY2FuQ2hhcihudWxsKTsKLQotICAgICAgICAvLyBjb252ZXJ0IHN1cnJvZ2F0ZXMgdG8gc3VwcGxlbWVudGFsIGNoYXJhY3RlcgotICAgICAgICBpbnQgYyA9IFhNTENoYXIuc3VwcGxlbWVudGFsKChjaGFyKWhpZ2gsIChjaGFyKWxvdyk7Ci0KLSAgICAgICAgLy8gc3VwcGxlbWVudGFsIGNoYXJhY3RlciBtdXN0IGJlIGEgdmFsaWQgWE1MIGNoYXJhY3RlcgotICAgICAgICBpZiAoaXNJbnZhbGlkKGMpKSB7Ci0gICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJJbnZhbGlkQ2hhckluQ29udGVudCIsCi0gICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXtJbnRlZ2VyLnRvU3RyaW5nKGMsIDE2KX0pOwotICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBmaWxsIGluIHRoZSBidWZmZXIKLSAgICAgICAgYnVmLmFwcGVuZCgoY2hhciloaWdoKTsKLSAgICAgICAgYnVmLmFwcGVuZCgoY2hhcilsb3cpOwotCi0gICAgICAgIHJldHVybiB0cnVlOwotCi0gICAgfSAvLyBzY2FuU3Vycm9nYXRlcygpOmJvb2xlYW4KLQotCi0gICAgLyoqCi0gICAgICogQ29udmVuaWVuY2UgZnVuY3Rpb24gdXNlZCBpbiBhbGwgWE1MIHNjYW5uZXJzLgotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIHJlcG9ydEZhdGFsRXJyb3IoU3RyaW5nIG1zZ0lkLCBPYmplY3RbXSBhcmdzKQotICAgIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBmRXJyb3JSZXBvcnRlci5yZXBvcnRFcnJvcihmRW50aXR5U2Nhbm5lciwgWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLAotICAgICAgICAgICAgICAgIG1zZ0lkLCBhcmdzLAotICAgICAgICAgICAgICAgIFhNTEVycm9yUmVwb3J0ZXIuU0VWRVJJVFlfRkFUQUxfRVJST1IpOwotICAgIH0KLQotICAgIC8vIHByaXZhdGUgbWV0aG9kcwotICAgIHByaXZhdGUgdm9pZCBpbml0KCkgewotICAgICAgICAvLyBpbml0aWFsaXplIHNjYW5uZXIKLSAgICAgICAgZkVudGl0eVNjYW5uZXIgPSBudWxsOwotICAgICAgICAvLyBpbml0aWFsaXplIHZhcnMKLSAgICAgICAgZkVudGl0eURlcHRoID0gMDsKLSAgICAgICAgZlJlcG9ydEVudGl0eSA9IHRydWU7Ci0gICAgICAgIGZSZXNvdXJjZUlkZW50aWZpZXIuY2xlYXIoKTsKLQotICAgICAgICBpZighZkF0dHJpYnV0ZUNhY2hlSW5pdERvbmUpewotICAgICAgICAgICAgZm9yKGludCBpID0gMDsgaSA8IGluaXRpYWxDYWNoZUNvdW50OyBpKyspewotICAgICAgICAgICAgICAgIGF0dHJpYnV0ZVZhbHVlQ2FjaGUuYWRkKG5ldyBYTUxTdHJpbmcoKSk7Ci0gICAgICAgICAgICAgICAgc3RyaW5nQnVmZmVyQ2FjaGUuYWRkKG5ldyBYTUxTdHJpbmdCdWZmZXIoKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmQXR0cmlidXRlQ2FjaGVJbml0RG9uZSA9IHRydWU7Ci0gICAgICAgIH0KLSAgICAgICAgZlN0cmluZ0J1ZmZlckluZGV4ID0gMDsKLSAgICAgICAgZkF0dHJpYnV0ZUNhY2hlVXNlZENvdW50ID0gMDsKLQotICAgIH0KLQotICAgIFhNTFN0cmluZ0J1ZmZlciBnZXRTdHJpbmdCdWZmZXIoKXsKLSAgICAgICAgaWYoKGZTdHJpbmdCdWZmZXJJbmRleCA8IGluaXRpYWxDYWNoZUNvdW50ICl8fCAoZlN0cmluZ0J1ZmZlckluZGV4IDwgc3RyaW5nQnVmZmVyQ2FjaGUuc2l6ZSgpKSl7Ci0gICAgICAgICAgICByZXR1cm4gc3RyaW5nQnVmZmVyQ2FjaGUuZ2V0KGZTdHJpbmdCdWZmZXJJbmRleCsrKTsKLSAgICAgICAgfWVsc2V7Ci0gICAgICAgICAgICBYTUxTdHJpbmdCdWZmZXIgdG1wT2JqID0gbmV3IFhNTFN0cmluZ0J1ZmZlcigpOwotICAgICAgICAgICAgZlN0cmluZ0J1ZmZlckluZGV4Kys7Ci0gICAgICAgICAgICBzdHJpbmdCdWZmZXJDYWNoZS5hZGQodG1wT2JqKTsKLSAgICAgICAgICAgIHJldHVybiB0bXBPYmo7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBZGQgdGhlIGNvdW50IG9mIHRoZSBjb250ZW50IGJ1ZmZlciBhbmQgY2hlY2sgaWYgdGhlIGFjY3VtdWxhdGVkCi0gICAgICogdmFsdWUgZXhjZWVkcyB0aGUgbGltaXQKLSAgICAgKiBAcGFyYW0gaXNQRURlY2wgYSBmbGFnIHRvIGluZGljYXRlIHdoZXRoZXIgdGhlIGVudGl0eSBpcyBwYXJhbWV0ZXIKLSAgICAgKiBAcGFyYW0gZW50aXR5TmFtZSBlbnRpdHkgbmFtZQotICAgICAqIEBwYXJhbSBidWZmZXIgY29udGVudCBidWZmZXIKLSAgICAgKi8KLSAgICB2b2lkIGNoZWNrRW50aXR5TGltaXQoYm9vbGVhbiBpc1BFRGVjbCwgU3RyaW5nIGVudGl0eU5hbWUsIFhNTFN0cmluZyBidWZmZXIpIHsKLSAgICAgICAgY2hlY2tFbnRpdHlMaW1pdChpc1BFRGVjbCwgZW50aXR5TmFtZSwgYnVmZmVyLmxlbmd0aCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQWRkIHRoZSBjb3VudCBhbmQgY2hlY2sgbGltaXQKLSAgICAgKiBAcGFyYW0gaXNQRURlY2wgYSBmbGFnIHRvIGluZGljYXRlIHdoZXRoZXIgdGhlIGVudGl0eSBpcyBwYXJhbWV0ZXIKLSAgICAgKiBAcGFyYW0gZW50aXR5TmFtZSBlbnRpdHkgbmFtZQotICAgICAqIEBwYXJhbSBsZW4gbGVuZ3RoIG9mIHRoZSBidWZmZXIKLSAgICAgKi8KLSAgICB2b2lkIGNoZWNrRW50aXR5TGltaXQoYm9vbGVhbiBpc1BFRGVjbCwgU3RyaW5nIGVudGl0eU5hbWUsIGludCBsZW4pIHsKLSAgICAgICAgaWYgKGZMaW1pdEFuYWx5emVyID09IG51bGwpIHsKLSAgICAgICAgICAgIGZMaW1pdEFuYWx5emVyID0gZkVudGl0eU1hbmFnZXIuZkxpbWl0QW5hbHl6ZXI7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGlzUEVEZWNsKSB7Ci0gICAgICAgICAgICBmTGltaXRBbmFseXplci5hZGRWYWx1ZShYTUxTZWN1cml0eU1hbmFnZXIuTGltaXQuUEFSQU1FVEVSX0VOVElUWV9TSVpFX0xJTUlULCAiJSIgKyBlbnRpdHlOYW1lLCBsZW4pOwotICAgICAgICAgICAgaWYgKGZTZWN1cml0eU1hbmFnZXIuaXNPdmVyTGltaXQoWE1MU2VjdXJpdHlNYW5hZ2VyLkxpbWl0LlBBUkFNRVRFUl9FTlRJVFlfU0laRV9MSU1JVCwgZkxpbWl0QW5hbHl6ZXIpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmU2VjdXJpdHlNYW5hZ2VyLmRlYnVnUHJpbnQoZkxpbWl0QW5hbHl6ZXIpOwotICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIk1heEVudGl0eVNpemVMaW1pdCIsIG5ldyBPYmplY3RbXXsiJSIgKyBlbnRpdHlOYW1lLAotICAgICAgICAgICAgICAgICAgICBmTGltaXRBbmFseXplci5nZXRWYWx1ZShYTUxTZWN1cml0eU1hbmFnZXIuTGltaXQuUEFSQU1FVEVSX0VOVElUWV9TSVpFX0xJTUlUKSwKLSAgICAgICAgICAgICAgICAgICAgZlNlY3VyaXR5TWFuYWdlci5nZXRMaW1pdChYTUxTZWN1cml0eU1hbmFnZXIuTGltaXQuUEFSQU1FVEVSX0VOVElUWV9TSVpFX0xJTUlUKSwKLSAgICAgICAgICAgICAgICAgICAgZlNlY3VyaXR5TWFuYWdlci5nZXRTdGF0ZUxpdGVyYWwoWE1MU2VjdXJpdHlNYW5hZ2VyLkxpbWl0LlBBUkFNRVRFUl9FTlRJVFlfU0laRV9MSU1JVCl9KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIGZMaW1pdEFuYWx5emVyLmFkZFZhbHVlKFhNTFNlY3VyaXR5TWFuYWdlci5MaW1pdC5HRU5FUkFMX0VOVElUWV9TSVpFX0xJTUlULCBlbnRpdHlOYW1lLCBsZW4pOwotICAgICAgICAgICAgaWYgKGZTZWN1cml0eU1hbmFnZXIuaXNPdmVyTGltaXQoWE1MU2VjdXJpdHlNYW5hZ2VyLkxpbWl0LkdFTkVSQUxfRU5USVRZX1NJWkVfTElNSVQsIGZMaW1pdEFuYWx5emVyKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgZlNlY3VyaXR5TWFuYWdlci5kZWJ1Z1ByaW50KGZMaW1pdEFuYWx5emVyKTsKLSAgICAgICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJNYXhFbnRpdHlTaXplTGltaXQiLCBuZXcgT2JqZWN0W117ZW50aXR5TmFtZSwKLSAgICAgICAgICAgICAgICAgICAgZkxpbWl0QW5hbHl6ZXIuZ2V0VmFsdWUoWE1MU2VjdXJpdHlNYW5hZ2VyLkxpbWl0LkdFTkVSQUxfRU5USVRZX1NJWkVfTElNSVQpLAotICAgICAgICAgICAgICAgICAgICBmU2VjdXJpdHlNYW5hZ2VyLmdldExpbWl0KFhNTFNlY3VyaXR5TWFuYWdlci5MaW1pdC5HRU5FUkFMX0VOVElUWV9TSVpFX0xJTUlUKSwKLSAgICAgICAgICAgICAgICAgICAgZlNlY3VyaXR5TWFuYWdlci5nZXRTdGF0ZUxpdGVyYWwoWE1MU2VjdXJpdHlNYW5hZ2VyLkxpbWl0LkdFTkVSQUxfRU5USVRZX1NJWkVfTElNSVQpfSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGZTZWN1cml0eU1hbmFnZXIuaXNPdmVyTGltaXQoWE1MU2VjdXJpdHlNYW5hZ2VyLkxpbWl0LlRPVEFMX0VOVElUWV9TSVpFX0xJTUlULCBmTGltaXRBbmFseXplcikpIHsKLSAgICAgICAgICAgIGZTZWN1cml0eU1hbmFnZXIuZGVidWdQcmludChmTGltaXRBbmFseXplcik7Ci0gICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJUb3RhbEVudGl0eVNpemVMaW1pdCIsCi0gICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde2ZMaW1pdEFuYWx5emVyLmdldFRvdGFsVmFsdWUoWE1MU2VjdXJpdHlNYW5hZ2VyLkxpbWl0LlRPVEFMX0VOVElUWV9TSVpFX0xJTUlUKSwKLSAgICAgICAgICAgICAgICBmU2VjdXJpdHlNYW5hZ2VyLmdldExpbWl0KFhNTFNlY3VyaXR5TWFuYWdlci5MaW1pdC5UT1RBTF9FTlRJVFlfU0laRV9MSU1JVCksCi0gICAgICAgICAgICAgICAgZlNlY3VyaXR5TWFuYWdlci5nZXRTdGF0ZUxpdGVyYWwoWE1MU2VjdXJpdHlNYW5hZ2VyLkxpbWl0LlRPVEFMX0VOVElUWV9TSVpFX0xJTUlUKX0pOwotICAgICAgICB9Ci0gICAgfQotfSAvLyBjbGFzcyBYTUxTY2FubmVyCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL1hNTFN0cmVhbUZpbHRlckltcGwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvWE1MU3RyZWFtRmlsdGVySW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkMTQ3Y2M5Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvWE1MU3RyZWFtRmlsdGVySW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTMzICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMDYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsOwotCi1pbXBvcnQgamF2YXgueG1sLlhNTENvbnN0YW50czsKLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLkxvY2F0aW9uOwotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uWE1MU3RyZWFtUmVhZGVyOwotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uU3RyZWFtRmlsdGVyOwotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uWE1MU3RyZWFtRXhjZXB0aW9uOwotaW1wb3J0IGphdmF4LnhtbC5uYW1lc3BhY2UuUU5hbWU7Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5ldmVudHMuWE1MRXZlbnQ7Ci0KLQotLyoqCi0gKgotICogQGF1dGhvciBKb2UgV2FuZzoKLSAqIFRoaXMgaXMgYSByZXdyaXRlIG9mIHRoZSBvcmlnaW5hbCBjbGFzcy4gVGhlIGZvY3VzIGlzIG9uIHJlbW92aW5nIGNhY2hpbmcsIGFuZCBtYWtlIHRoZSBmaWx0ZXJlZAotICogc3RyZWFtIHJlYWRlciBtb3JlIGNvbXBhdGlibGUgd2l0aCB0aG9zZSBpbiBvdGhlciBpbXBsZW1lbnRhdGlvbnMuIE5vdGUgaG93ZXZlciwgdGhhdCB0aGlzIHZlcnNpb24KLSAqIHdpbGwgbm90IHNvbHZlIGFsbCB0aGUgaXNzdWVzIHJlbGF0ZWQgdG8gdGhlIHVuZGVmaW5lZCBjb25kaXRpb24gaW4gdGhlIHNwZWMuIFRoZSBwcmlvcml0eSBpcwotICogdG8gcGFzcyB0aGUgVENLLiBJc3N1ZXMgYXJpc2luZyBkdWUgdG8gdGhlIHJlcXVpcmVtZW50LCB0aGF0IGlzLCAoMSkgc2hvdWxkIGl0IGluaXRpYXRlIGF0IEJFR0lOX0RPQ1VNRU5UCi0gKiBvciBhbiBhY2NlcHRlZCBldmVudDsgKDIpIHNob3VsZCBoYXNOZXh0KCkgYWR2YW5jZSB0aGUgdW5kZXJsaW5pbmcgc3RyZWFtIGluIG9yZGVyIHRvIGZpbmQgYW4gYWNjZXB0YWJsZQotICogZXZlbnQsIHdvdWxkIGhhdmUgdG8gd2FpdCB1bnRpbCAxLjEgb2YgU3RBWCBpbiB3aGljaCB0aGUgZmlsdGVyZWQgc3RyZWFtIHJlYWRlciB3b3VsZCBiZSBkZWZpbmVkIG1vcmUgY2xlYXJseS4KLSAqLwotCi1wdWJsaWMgY2xhc3MgWE1MU3RyZWFtRmlsdGVySW1wbCBpbXBsZW1lbnRzIGphdmF4LnhtbC5zdHJlYW0uWE1MU3RyZWFtUmVhZGVyIHsKLQotICAgIHByaXZhdGUgU3RyZWFtRmlsdGVyIGZTdHJlYW1GaWx0ZXIgPSBudWxsOwotICAgIHByaXZhdGUgWE1MU3RyZWFtUmVhZGVyIGZTdHJlYW1SZWFkZXIgPSBudWxsOwotICAgIHByaXZhdGUgaW50IGZDdXJyZW50RXZlbnQ7Ci0gICAgcHJpdmF0ZSBib29sZWFuIGZFdmVudEFjY2VwdGVkID0gZmFsc2U7Ci0KLSAgICAvKip0aGUgdmVyeSBpc3N1ZSBhcm91bmQgYSBsb25nIGRpc2N1c3Npb24uIGJ1dCBzaW5jZSB3ZSBtdXN0IHBhc3MgdGhlIFRDSywgd2UgaGF2ZSB0byBhbGxvdwotICAgICAqIGhhc05leHQoKSB0byBhZHZhbmNlIHRoZSB1bmRlcmxpbmluZyBzdHJlYW0gaW4gb3JkZXIgdG8gZmluZCB0aGUgbmV4dCBhY2NlcHRhYmxlIGV2ZW50Ci0gICAgICovCi0gICAgcHJpdmF0ZSBib29sZWFuIGZTdHJlYW1BZHZhbmNlZEJ5SGFzTmV4dCA9IGZhbHNlOwotICAgIC8qKiBDcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIFhNTFN0cmVhbUZpbHRlckltcGwgKi8KLQotICAgIHB1YmxpYyBYTUxTdHJlYW1GaWx0ZXJJbXBsKFhNTFN0cmVhbVJlYWRlciByZWFkZXIsU3RyZWFtRmlsdGVyIGZpbHRlcil7Ci0gICAgICAgIGZTdHJlYW1SZWFkZXIgPSByZWFkZXI7Ci0gICAgICAgIHRoaXMuZlN0cmVhbUZpbHRlciA9IGZpbHRlcjsKLQotICAgICAgICAvL3RoaXMgaXMgZGViYXRhYmxlIHRvIGluaXRpYXRlIGF0IGFuIGFjY2VwdGFibGUgZXZlbnQsCi0gICAgICAgIC8vYnV0IGl0J3MgbmVjY2Vzc2FyeSBpbiBvcmRlciB0byBwYXNzIHRoZSBUQ0sgYW5kIHlldCBhdm9pZCBza2lwcGluZyBlbGVtZW50Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBpZiAoZlN0cmVhbUZpbHRlci5hY2NlcHQoZlN0cmVhbVJlYWRlcikpIHsKLSAgICAgICAgICAgICAgICBmRXZlbnRBY2NlcHRlZCA9IHRydWU7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIGZpbmROZXh0RXZlbnQoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfWNhdGNoKFhNTFN0cmVhbUV4Y2VwdGlvbiB4cyl7Ci0gICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIkVycm9yIHdoaWxlIGNyZWF0aW5nIGEgc3RyZWFtIEZpbHRlciIreHMpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc2YKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCBzZXRTdHJlYW1GaWx0ZXIoU3RyZWFtRmlsdGVyIHNmKXsKLSAgICAgICAgdGhpcy5mU3RyZWFtRmlsdGVyID0gc2Y7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICoKLSAgICAgKiBAcmV0dXJuCi0gICAgICogQHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IG5leHQoKSB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKGZTdHJlYW1BZHZhbmNlZEJ5SGFzTmV4dCAmJiBmRXZlbnRBY2NlcHRlZCkgewotICAgICAgICAgICAgZlN0cmVhbUFkdmFuY2VkQnlIYXNOZXh0ID0gZmFsc2U7Ci0gICAgICAgICAgICByZXR1cm4gZkN1cnJlbnRFdmVudDsKLSAgICAgICAgfQotICAgICAgICBpbnQgZXZlbnQgPSBmaW5kTmV4dEV2ZW50KCk7Ci0gICAgICAgIGlmIChldmVudCAhPSAtMSkgewotICAgICAgICAgICAgcmV0dXJuIGV2ZW50OwotICAgICAgICB9Ci0KLSAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiVGhlIHN0cmVhbSByZWFkZXIgaGFzIHJlYWNoZWQgdGhlIGVuZCBvZiB0aGUgZG9jdW1lbnQsIG9yIHRoZXJlIGFyZSBubyBtb3JlICIrCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIGl0ZW1zIHRvIHJldHVybiIpOwotICAgIH0KLSAgICAvKioKLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uCi0gICAgICogQHJldHVybgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgbmV4dFRhZygpIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24gewotICAgICAgICBpZiAoZlN0cmVhbUFkdmFuY2VkQnlIYXNOZXh0ICYmIGZFdmVudEFjY2VwdGVkICYmCi0gICAgICAgICAgICAgICAgKGZDdXJyZW50RXZlbnQgPT0gWE1MRXZlbnQuU1RBUlRfRUxFTUVOVCB8fCBmQ3VycmVudEV2ZW50ID09IFhNTEV2ZW50LlNUQVJUX0VMRU1FTlQpKSB7Ci0gICAgICAgICAgICBmU3RyZWFtQWR2YW5jZWRCeUhhc05leHQgPSBmYWxzZTsKLSAgICAgICAgICAgIHJldHVybiBmQ3VycmVudEV2ZW50OwotICAgICAgICB9Ci0KLSAgICAgICAgaW50IGV2ZW50ID0gZmluZE5leHRUYWcoKTsKLSAgICAgICAgaWYgKGV2ZW50ICE9IC0xKSB7Ci0gICAgICAgICAgICByZXR1cm4gZXZlbnQ7Ci0gICAgICAgIH0KLSAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiVGhlIHN0cmVhbSByZWFkZXIgaGFzIHJlYWNoZWQgdGhlIGVuZCBvZiB0aGUgZG9jdW1lbnQsIG9yIHRoZXJlIGFyZSBubyBtb3JlICIrCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIGl0ZW1zIHRvIHJldHVybiIpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqCi0gICAgICogQHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24KLSAgICAgKiBAcmV0dXJuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaGFzTmV4dCgpIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24gewotICAgICAgICBpZiAoZlN0cmVhbVJlYWRlci5oYXNOZXh0KCkpIHsKLSAgICAgICAgICAgIGlmICghZkV2ZW50QWNjZXB0ZWQpIHsKLSAgICAgICAgICAgICAgICBpZiAoKGZDdXJyZW50RXZlbnQgPSBmaW5kTmV4dEV2ZW50KCkpID09IC0xKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICBmU3RyZWFtQWR2YW5jZWRCeUhhc05leHQgPSB0cnVlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIGludCBmaW5kTmV4dEV2ZW50KCkgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbiB7Ci0gICAgICAgIGZTdHJlYW1BZHZhbmNlZEJ5SGFzTmV4dCA9IGZhbHNlOwotICAgICAgICB3aGlsZShmU3RyZWFtUmVhZGVyLmhhc05leHQoKSl7Ci0gICAgICAgICAgICBmQ3VycmVudEV2ZW50ID0gZlN0cmVhbVJlYWRlci5uZXh0KCk7Ci0gICAgICAgICAgICBpZihmU3RyZWFtRmlsdGVyLmFjY2VwdChmU3RyZWFtUmVhZGVyKSl7Ci0gICAgICAgICAgICAgICAgZkV2ZW50QWNjZXB0ZWQgPSB0cnVlOwotICAgICAgICAgICAgICAgIHJldHVybiBmQ3VycmVudEV2ZW50OwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIC8vYWx0aG91Z2ggaXQgc2VlbXMgdGhhdCBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gc2hvdWxkIGJlIHRocm93biB3aGVuIG5leHQoKSBpcyBjYWxsZWQKLSAgICAgICAgLy9vbiBhIHN0cmVhbSB0aGF0IGhhcyBubyBtb3JlIGl0ZW1zLCB3ZSBoYXZlIHRvIGFzc3VtZSBFTkRfRE9DVU1FTlQgaXMgYWx3YXlzIGFjY2VwdGVkCi0gICAgICAgIC8vaW4gb3JkZXIgdG8gcGFzcyB0aGUgVENLCi0gICAgICAgIGlmIChmQ3VycmVudEV2ZW50ID09IFhNTEV2ZW50LkVORF9ET0NVTUVOVCkKLSAgICAgICAgICAgIHJldHVybiBmQ3VycmVudEV2ZW50OwotICAgICAgICBlbHNlCi0gICAgICAgICAgICByZXR1cm4gLTE7Ci0gICAgfQotICAgIHByaXZhdGUgaW50IGZpbmROZXh0VGFnKCkgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbiB7Ci0gICAgICAgIGZTdHJlYW1BZHZhbmNlZEJ5SGFzTmV4dCA9IGZhbHNlOwotICAgICAgICB3aGlsZShmU3RyZWFtUmVhZGVyLmhhc05leHQoKSl7Ci0gICAgICAgICAgICBmQ3VycmVudEV2ZW50ID0gZlN0cmVhbVJlYWRlci5uZXh0VGFnKCk7Ci0gICAgICAgICAgICBpZihmU3RyZWFtRmlsdGVyLmFjY2VwdChmU3RyZWFtUmVhZGVyKSl7Ci0gICAgICAgICAgICAgICAgZkV2ZW50QWNjZXB0ZWQgPSB0cnVlOwotICAgICAgICAgICAgICAgIHJldHVybiBmQ3VycmVudEV2ZW50OwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGlmIChmQ3VycmVudEV2ZW50ID09IFhNTEV2ZW50LkVORF9ET0NVTUVOVCkKLSAgICAgICAgICAgIHJldHVybiBmQ3VycmVudEV2ZW50OwotICAgICAgICBlbHNlCi0gICAgICAgICAgICByZXR1cm4gLTE7Ci0gICAgfQotICAgIC8qKgotICAgICAqCi0gICAgICogQHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24gewotICAgICAgICBmU3RyZWFtUmVhZGVyLmNsb3NlKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICoKLSAgICAgKiBAcmV0dXJuCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRBdHRyaWJ1dGVDb3VudCgpIHsKLSAgICAgICAgcmV0dXJuIGZTdHJlYW1SZWFkZXIuZ2V0QXR0cmlidXRlQ291bnQoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKgotICAgICAqIEBwYXJhbSBpbmRleAotICAgICAqIEByZXR1cm4KLSAgICAgKi8KLSAgICBwdWJsaWMgUU5hbWUgZ2V0QXR0cmlidXRlTmFtZShpbnQgaW5kZXgpIHsKLSAgICAgICAgcmV0dXJuIGZTdHJlYW1SZWFkZXIuZ2V0QXR0cmlidXRlTmFtZShpbmRleCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaW5kZXgKLSAgICAgKiBAcmV0dXJuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRBdHRyaWJ1dGVOYW1lc3BhY2UoaW50IGluZGV4KSB7Ci0gICAgICAgIHJldHVybiBmU3RyZWFtUmVhZGVyLmdldEF0dHJpYnV0ZU5hbWVzcGFjZShpbmRleCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaW5kZXgKLSAgICAgKiBAcmV0dXJuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRBdHRyaWJ1dGVQcmVmaXgoaW50IGluZGV4KSB7Ci0gICAgICAgIHJldHVybiBmU3RyZWFtUmVhZGVyLmdldEF0dHJpYnV0ZVByZWZpeChpbmRleCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaW5kZXgKLSAgICAgKiBAcmV0dXJuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRBdHRyaWJ1dGVUeXBlKGludCBpbmRleCkgewotICAgICAgICByZXR1cm4gZlN0cmVhbVJlYWRlci5nZXRBdHRyaWJ1dGVUeXBlKGluZGV4KTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKgotICAgICAqIEBwYXJhbSBpbmRleAotICAgICAqIEByZXR1cm4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEF0dHJpYnV0ZVZhbHVlKGludCBpbmRleCkgewotICAgICAgICByZXR1cm4gZlN0cmVhbVJlYWRlci5nZXRBdHRyaWJ1dGVWYWx1ZShpbmRleCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZXNwYWNlVVJJCi0gICAgICogQHBhcmFtIGxvY2FsTmFtZQotICAgICAqIEByZXR1cm4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEF0dHJpYnV0ZVZhbHVlKFN0cmluZyBuYW1lc3BhY2VVUkksIFN0cmluZyBsb2NhbE5hbWUpIHsKLSAgICAgICAgcmV0dXJuIGZTdHJlYW1SZWFkZXIuZ2V0QXR0cmlidXRlVmFsdWUobmFtZXNwYWNlVVJJLGxvY2FsTmFtZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICoKLSAgICAgKiBAcmV0dXJuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRDaGFyYWN0ZXJFbmNvZGluZ1NjaGVtZSgpIHsKLSAgICAgICAgcmV0dXJuIGZTdHJlYW1SZWFkZXIuZ2V0Q2hhcmFjdGVyRW5jb2RpbmdTY2hlbWUoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uCi0gICAgICogQHJldHVybgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0RWxlbWVudFRleHQoKSB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uIHsKLSAgICAgICAgcmV0dXJuIGZTdHJlYW1SZWFkZXIuZ2V0RWxlbWVudFRleHQoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKgotICAgICAqIEByZXR1cm4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEVuY29kaW5nKCkgewotICAgICAgICByZXR1cm4gZlN0cmVhbVJlYWRlci5nZXRFbmNvZGluZygpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqCi0gICAgICogQHJldHVybgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0RXZlbnRUeXBlKCkgewotICAgICAgICByZXR1cm4gZlN0cmVhbVJlYWRlci5nZXRFdmVudFR5cGUoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKgotICAgICAqIEByZXR1cm4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldExvY2FsTmFtZSgpIHsKLSAgICAgICAgcmV0dXJuIGZTdHJlYW1SZWFkZXIuZ2V0TG9jYWxOYW1lKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICoKLSAgICAgKiBAcmV0dXJuCi0gICAgICovCi0gICAgcHVibGljIGphdmF4LnhtbC5zdHJlYW0uTG9jYXRpb24gZ2V0TG9jYXRpb24oKSB7Ci0gICAgICAgIHJldHVybiBmU3RyZWFtUmVhZGVyLmdldExvY2F0aW9uKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICoKLSAgICAgKiBAcmV0dXJuCi0gICAgICovCi0gICAgcHVibGljIGphdmF4LnhtbC5uYW1lc3BhY2UuUU5hbWUgZ2V0TmFtZSgpIHsKLSAgICAgICAgcmV0dXJuIGZTdHJlYW1SZWFkZXIuZ2V0TmFtZSgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqCi0gICAgICogQHJldHVybgotICAgICAqLwotICAgIHB1YmxpYyBqYXZheC54bWwubmFtZXNwYWNlLk5hbWVzcGFjZUNvbnRleHQgZ2V0TmFtZXNwYWNlQ29udGV4dCgpIHsKLSAgICAgICAgcmV0dXJuIGZTdHJlYW1SZWFkZXIuZ2V0TmFtZXNwYWNlQ29udGV4dCgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqCi0gICAgICogQHJldHVybgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0TmFtZXNwYWNlQ291bnQoKSB7Ci0gICAgICAgIHJldHVybiBmU3RyZWFtUmVhZGVyLmdldE5hbWVzcGFjZUNvdW50KCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaW5kZXgKLSAgICAgKiBAcmV0dXJuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXROYW1lc3BhY2VQcmVmaXgoaW50IGluZGV4KSB7Ci0gICAgICAgIHJldHVybiBmU3RyZWFtUmVhZGVyLmdldE5hbWVzcGFjZVByZWZpeChpbmRleCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICoKLSAgICAgKiBAcmV0dXJuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXROYW1lc3BhY2VVUkkoKSB7Ci0gICAgICAgIHJldHVybiBmU3RyZWFtUmVhZGVyLmdldE5hbWVzcGFjZVVSSSgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqCi0gICAgICogQHBhcmFtIGluZGV4Ci0gICAgICogQHJldHVybgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZXNwYWNlVVJJKGludCBpbmRleCkgewotICAgICAgICByZXR1cm4gZlN0cmVhbVJlYWRlci5nZXROYW1lc3BhY2VVUkkoaW5kZXgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqCi0gICAgICogQHBhcmFtIHByZWZpeAotICAgICAqIEByZXR1cm4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWVzcGFjZVVSSShTdHJpbmcgcHJlZml4KSB7Ci0gICAgICAgIHJldHVybiBmU3RyZWFtUmVhZGVyLmdldE5hbWVzcGFjZVVSSShwcmVmaXgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqCi0gICAgICogQHJldHVybgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0UElEYXRhKCkgewotICAgICAgICByZXR1cm4gZlN0cmVhbVJlYWRlci5nZXRQSURhdGEoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKgotICAgICAqIEByZXR1cm4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFBJVGFyZ2V0KCkgewotICAgICAgICByZXR1cm4gZlN0cmVhbVJlYWRlci5nZXRQSVRhcmdldCgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqCi0gICAgICogQHJldHVybgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0UHJlZml4KCkgewotICAgICAgICByZXR1cm4gZlN0cmVhbVJlYWRlci5nZXRQcmVmaXgoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lCi0gICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KLSAgICAgKiBAcmV0dXJuCi0gICAgICovCi0gICAgcHVibGljIE9iamVjdCBnZXRQcm9wZXJ0eShqYXZhLmxhbmcuU3RyaW5nIG5hbWUpIHRocm93cyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHsKLSAgICAgICAgcmV0dXJuIGZTdHJlYW1SZWFkZXIuZ2V0UHJvcGVydHkobmFtZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICoKLSAgICAgKiBAcmV0dXJuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRUZXh0KCkgewotICAgICAgICByZXR1cm4gZlN0cmVhbVJlYWRlci5nZXRUZXh0KCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICoKLSAgICAgKiBAcmV0dXJuCi0gICAgICovCi0gICAgcHVibGljIGNoYXJbXSBnZXRUZXh0Q2hhcmFjdGVycygpIHsKLSAgICAgICAgcmV0dXJuIGZTdHJlYW1SZWFkZXIuZ2V0VGV4dENoYXJhY3RlcnMoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKgotICAgICAqIEBwYXJhbSBzb3VyY2VTdGFydAotICAgICAqIEBwYXJhbSB0YXJnZXQKLSAgICAgKiBAcGFyYW0gdGFyZ2V0U3RhcnQKLSAgICAgKiBAcGFyYW0gbGVuZ3RoCi0gICAgICogQHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24KLSAgICAgKiBAcmV0dXJuCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRUZXh0Q2hhcmFjdGVycyhpbnQgc291cmNlU3RhcnQsIGNoYXJbXSB0YXJnZXQsIGludCB0YXJnZXRTdGFydCwgaW50IGxlbmd0aCkgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbiB7Ci0gICAgICAgIHJldHVybiBmU3RyZWFtUmVhZGVyLmdldFRleHRDaGFyYWN0ZXJzKHNvdXJjZVN0YXJ0LCB0YXJnZXQsdGFyZ2V0U3RhcnQsbGVuZ3RoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKgotICAgICAqIEByZXR1cm4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldFRleHRMZW5ndGgoKSB7Ci0gICAgICAgIHJldHVybiBmU3RyZWFtUmVhZGVyLmdldFRleHRMZW5ndGgoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKgotICAgICAqIEByZXR1cm4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldFRleHRTdGFydCgpIHsKLSAgICAgICAgcmV0dXJuIGZTdHJlYW1SZWFkZXIuZ2V0VGV4dFN0YXJ0KCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICoKLSAgICAgKiBAcmV0dXJuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRWZXJzaW9uKCkgewotICAgICAgICByZXR1cm4gZlN0cmVhbVJlYWRlci5nZXRWZXJzaW9uKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICoKLSAgICAgKiBAcmV0dXJuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaGFzTmFtZSgpIHsKLSAgICAgICAgcmV0dXJuIGZTdHJlYW1SZWFkZXIuaGFzTmFtZSgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqCi0gICAgICogQHJldHVybgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGhhc1RleHQoKSB7Ci0gICAgICAgIHJldHVybiBmU3RyZWFtUmVhZGVyLmhhc1RleHQoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKgotICAgICAqIEByZXR1cm4KLSAgICAgKiBAcGFyYW0gaW5kZXgKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0F0dHJpYnV0ZVNwZWNpZmllZChpbnQgaW5kZXgpIHsKLSAgICAgICAgcmV0dXJuIGZTdHJlYW1SZWFkZXIuaXNBdHRyaWJ1dGVTcGVjaWZpZWQoaW5kZXgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqCi0gICAgICogQHJldHVybgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzQ2hhcmFjdGVycygpIHsKLSAgICAgICAgcmV0dXJuIGZTdHJlYW1SZWFkZXIuaXNDaGFyYWN0ZXJzKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICoKLSAgICAgKiBAcmV0dXJuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNFbmRFbGVtZW50KCkgewotICAgICAgICByZXR1cm4gZlN0cmVhbVJlYWRlci5pc0VuZEVsZW1lbnQoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKgotICAgICAqIEByZXR1cm4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc1N0YW5kYWxvbmUoKSB7Ci0gICAgICAgIHJldHVybiBmU3RyZWFtUmVhZGVyLmlzU3RhbmRhbG9uZSgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqCi0gICAgICogQHJldHVybgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzU3RhcnRFbGVtZW50KCkgewotICAgICAgICByZXR1cm4gZlN0cmVhbVJlYWRlci5pc1N0YXJ0RWxlbWVudCgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqCi0gICAgICogQHJldHVybgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzV2hpdGVTcGFjZSgpIHsKLSAgICAgICAgcmV0dXJuIGZTdHJlYW1SZWFkZXIuaXNXaGl0ZVNwYWNlKCk7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKgotICAgICAqIEBwYXJhbSB0eXBlCi0gICAgICogQHBhcmFtIG5hbWVzcGFjZVVSSQotICAgICAqIEBwYXJhbSBsb2NhbE5hbWUKLSAgICAgKiBAdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHJlcXVpcmUoaW50IHR5cGUsIFN0cmluZyBuYW1lc3BhY2VVUkksIFN0cmluZyBsb2NhbE5hbWUpIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24gewotICAgICAgICBmU3RyZWFtUmVhZGVyLnJlcXVpcmUodHlwZSxuYW1lc3BhY2VVUkksbG9jYWxOYW1lKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKgotICAgICAqIEByZXR1cm4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBzdGFuZGFsb25lU2V0KCkgewotICAgICAgICByZXR1cm4gZlN0cmVhbVJlYWRlci5zdGFuZGFsb25lU2V0KCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaW5kZXgKLSAgICAgKiBAcmV0dXJuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRBdHRyaWJ1dGVMb2NhbE5hbWUoaW50IGluZGV4KXsKLSAgICAgICAgcmV0dXJuIGZTdHJlYW1SZWFkZXIuZ2V0QXR0cmlidXRlTG9jYWxOYW1lKGluZGV4KTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL1hNTFN0cmVhbVJlYWRlckltcGwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvWE1MU3RyZWFtUmVhZGVySW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzNTBhODdjLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvWE1MU3RyZWFtUmVhZGVySW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTM2NiArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDE1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbDsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5OYW1lc3BhY2VDb250ZXh0V3JhcHBlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuTmFtZXNwYWNlU3VwcG9ydDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuU3ltYm9sVGFibGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlhNTEF0dHJpYnV0ZXNJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5YTUxDaGFyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5YTUxTdHJpbmdCdWZmZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE5JRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxJbnB1dFNvdXJjZTsKLWltcG9ydCBjb20uc3VuLnhtbC5pbnRlcm5hbC5zdHJlYW0uRW50aXR5OwotaW1wb3J0IGNvbS5zdW4ueG1sLmludGVybmFsLnN0cmVhbS5TdGF4RXJyb3JSZXBvcnRlcjsKLWltcG9ydCBjb20uc3VuLnhtbC5pbnRlcm5hbC5zdHJlYW0uWE1MRW50aXR5U3RvcmFnZTsKLWltcG9ydCBjb20uc3VuLnhtbC5pbnRlcm5hbC5zdHJlYW0uZHRkLm5vbnZhbGlkYXRpbmcuRFRER3JhbW1hcjsKLWltcG9ydCBjb20uc3VuLnhtbC5pbnRlcm5hbC5zdHJlYW0uZHRkLm5vbnZhbGlkYXRpbmcuWE1MTm90YXRpb25EZWNsOwotaW1wb3J0IGNvbS5zdW4ueG1sLmludGVybmFsLnN0cmVhbS5ldmVudHMuRW50aXR5RGVjbGFyYXRpb25JbXBsOwotaW1wb3J0IGNvbS5zdW4ueG1sLmludGVybmFsLnN0cmVhbS5ldmVudHMuTm90YXRpb25EZWNsYXJhdGlvbkltcGw7Ci1pbXBvcnQgamF2YS5pby5CdWZmZXJlZElucHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRSZWFkZXI7Ci1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uUmVhZGVyOwotaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7Ci1pbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOwotaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKLWltcG9ydCBqYXZhLnV0aWwuTGlzdDsKLWltcG9ydCBqYXZheC54bWwuWE1MQ29uc3RhbnRzOwotaW1wb3J0IGphdmF4LnhtbC5uYW1lc3BhY2UuTmFtZXNwYWNlQ29udGV4dDsKLWltcG9ydCBqYXZheC54bWwubmFtZXNwYWNlLlFOYW1lOwotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uTG9jYXRpb247Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5YTUxJbnB1dEZhY3Rvcnk7Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5YTUxTdHJlYW1Db25zdGFudHM7Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5YTUxTdHJlYW1FeGNlcHRpb247Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5ldmVudHMuWE1MRXZlbnQ7Ci0KLS8qKiBUaGlzIGNsYXNzIGltcGxlbWVudHMgamF2YXgueG1sLnN0cmVhbS5YTUxTdHJlYW1SZWFkZXIuIEl0IG1ha2VzIHVzZSBvZiBYTUwqU2Nhbm5lciBjbGFzc2VzIHRvCi0gKiBkZXJpdmUgbW9zdCBvZiBpdHMgZnVuY3Rpb25hbGl0eS4gSWYgZGVzaXJlZCwgQXBwbGljYXRpb24gY2FuIHJldXNlIHRoaXMgaW5zdGFuY2UgYnkgY2FsbGluZwotICogcmVzZXQoKSBhbmQgc2V0SW5wdXRTb3VyY2UoKS4KLSAqCi0gKiBAYXV0aG9yIE5lZXJhaiBCYWphaiBTdW4gTWljcm9zeXN0ZW1zLEluYy4KLSAqIEBhdXRob3IgSy5WZW51Z29wYWwgU3VuIE1pY3Jvc3lzdGVtcyxJbmMuCi0gKiBAYXV0aG9yIFN1bml0aGEgUmVkZHkgU3VuIE1pY3Jvc3lzdGVtcyxJbmMuCi0gKi8KLXB1YmxpYyBjbGFzcyBYTUxTdHJlYW1SZWFkZXJJbXBsIGltcGxlbWVudHMgamF2YXgueG1sLnN0cmVhbS5YTUxTdHJlYW1SZWFkZXIgewotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IGVudGl0eSBtYW5hZ2VyLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIEVOVElUWV9NQU5BR0VSID0KLSAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5FTlRJVFlfTUFOQUdFUl9QUk9QRVJUWTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBFcnJvciBSZXBvcnRlci4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJPUl9SRVBPUlRFUiA9Ci0gICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuRVJST1JfUkVQT1JURVJfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogU3ltYm9sIHRhYmxlLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFNZTUJPTF9UQUJMRSA9Ci0gICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuU1lNQk9MX1RBQkxFX1BST1BFUlRZOwotCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgUkVBREVSX0lOX0RFRklORURfU1RBVEUgPQotICAgIENvbnN0YW50cy5SRUFERVJfSU5fREVGSU5FRF9TVEFURTsKLQotICAgIHByaXZhdGUgU3ltYm9sVGFibGUgZlN5bWJvbFRhYmxlID0gbmV3IFN5bWJvbFRhYmxlKCk7Ci0KLSAgICAvKiogRG9jdW1lbnQgc2Nhbm5lci4gKi8KLSAgICBwcm90ZWN0ZWQgWE1MRG9jdW1lbnRTY2FubmVySW1wbCBmU2Nhbm5lciA9IG5ldyBYTUxOU0RvY3VtZW50U2Nhbm5lckltcGwoKTsKLQotICAgIC8vbWFrZSBHbG9iYWwgTmFtZXNwYWNlQ29udGV4dFdyYXBwZXIgb2JqZWN0LCAgZlNjYW5uZXIuZ2V0TmFtZXNwYWNlQ29udGV4dCgpIGlzIGR5bmFtaWMgb2JqZWN0IGFuZCBpdGEgdmFsdWUgY2hhbmdlcwotICAgIC8vYXMgcGVyIHRoZSBzdGF0ZSBvZiB0aGUgcGFyc2VyLgotICAgIHByb3RlY3RlZCBOYW1lc3BhY2VDb250ZXh0V3JhcHBlciBmTmFtZXNwYWNlQ29udGV4dFdyYXBwZXIgPSBuZXcgTmFtZXNwYWNlQ29udGV4dFdyYXBwZXIoKE5hbWVzcGFjZVN1cHBvcnQpZlNjYW5uZXIuZ2V0TmFtZXNwYWNlQ29udGV4dCgpKSA7Ci0gICAgcHJvdGVjdGVkIFhNTEVudGl0eU1hbmFnZXIgZkVudGl0eU1hbmFnZXIgPSBuZXcgWE1MRW50aXR5TWFuYWdlcigpOwotICAgIHByb3RlY3RlZCBTdGF4RXJyb3JSZXBvcnRlciBmRXJyb3JSZXBvcnRlciA9IG5ldyBTdGF4RXJyb3JSZXBvcnRlcigpOwotCi0KLSAgICAvKiogRW50aXR5IHNjYW5uZXIsIHRoaXMgYWx3YXN5IHdvcmtzIG9uIGxhc3QgZW50aXR5IHRoYXQgd2FzIG9wZW5lZC4gKi8KLSAgICBwcm90ZWN0ZWQgWE1MRW50aXR5U2Nhbm5lciBmRW50aXR5U2Nhbm5lciA9IG51bGw7Ci0KLSAgICAvKiogSW5wdXQgU291cmNlICovCi0gICAgcHJvdGVjdGVkIFhNTElucHV0U291cmNlIGZJbnB1dFNvdXJjZSA9IG51bGw7Ci0gICAgLyoqIFN0b3JlIHByb3BlcnRpZXMqLwotICAgIHByb3RlY3RlZCBQcm9wZXJ0eU1hbmFnZXIgZlByb3BlcnR5TWFuYWdlciA9IG51bGwgOwotCi0gICAgLyoqIGN1cnJlbnQgZXZlbnQgdHlwZSAqLwotICAgIHByaXZhdGUgaW50IGZFdmVudFR5cGUgOwotICAgIC8qKiBkZWJ1ZyBmbGFnKi8KLSAgICBzdGF0aWMgZmluYWwgYm9vbGVhbiBERUJVRyA9IGZhbHNlIDsKLSAgICAvKiogbW9yZSB0byBzY2FuICovCi0gICAgcHJpdmF0ZSBib29sZWFuIGZSZXVzZSA9IHRydWU7Ci0gICAgcHJpdmF0ZSBib29sZWFuIGZSZWFkZXJJbkRlZmluZWRTdGF0ZSA9IHRydWUgOwotICAgIHByaXZhdGUgYm9vbGVhbiBmQmluZE5hbWVzcGFjZXMgPSB0cnVlOwotICAgIHByaXZhdGUgU3RyaW5nIGZEVEREZWNsID0gbnVsbDsKLSAgICBwcml2YXRlIFN0cmluZyB2ZXJzaW9uU3RyID0gbnVsbDsKLQotICAgIC8qKgotICAgICAqIEBwYXJhbSBpbnB1dFN0cmVhbQotICAgICAqIEBwYXJhbSBwcm9wcwotICAgICAqIEB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uCi0gICAgICovCi0gICAgcHVibGljIFhNTFN0cmVhbVJlYWRlckltcGwoSW5wdXRTdHJlYW0gaW5wdXRTdHJlYW0sIFByb3BlcnR5TWFuYWdlciBwcm9wcykgdGhyb3dzICBYTUxTdHJlYW1FeGNlcHRpb24gewotICAgICAgICBpbml0KHByb3BzKTsKLSAgICAgICAgLy9wdWJsaWNJZCwgc3lzdGVtaWQsIGJhc2VTeXN0ZW1JZCwgaW5wdXRTdHJlYW0sIGVub2NkaW5nCi0gICAgICAgIFhNTElucHV0U291cmNlIGlucHV0U291cmNlID0gbmV3IFhNTElucHV0U291cmNlKG51bGwsbnVsbCxudWxsLGlucHV0U3RyZWFtLG51bGwpOwotICAgICAgICAvL3Bhc3MgdGhlIGlucHV0IHNvdXJjZSB0byBkb2N1bWVudCBzY2FubmVyIGltcGwuCi0gICAgICAgIHNldElucHV0U291cmNlKGlucHV0U291cmNlKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgWE1MRG9jdW1lbnRTY2FubmVySW1wbCBnZXRTY2FubmVyKCl7Ci0gICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigicmV0dXJuaW5nIHNjYW5uZXIiKTsKLSAgICAgICAgcmV0dXJuIGZTY2FubmVyOwotICAgIH0KLSAgICAvKioKLSAgICAgKiBAcGFyYW0gc3lzdGVtaWQKLSAgICAgKiBAcGFyYW0gcHJvcHMKLSAgICAgKiBAdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbgotICAgICAqLwotICAgIHB1YmxpYyBYTUxTdHJlYW1SZWFkZXJJbXBsKFN0cmluZyBzeXN0ZW1pZCwgUHJvcGVydHlNYW5hZ2VyIHByb3BzKSB0aHJvd3MgIFhNTFN0cmVhbUV4Y2VwdGlvbiB7Ci0gICAgICAgIGluaXQocHJvcHMpOwotICAgICAgICAvL3B1YmxpY0lkLCBzeXN0ZW1pZCwgYmFzZVN5c3RlbUlkLCBpbnB1dFN0cmVhbSwgZW5vY2RpbmcKLSAgICAgICAgWE1MSW5wdXRTb3VyY2UgaW5wdXRTb3VyY2UgPSBuZXcgWE1MSW5wdXRTb3VyY2UobnVsbCxzeXN0ZW1pZCxudWxsKTsKLSAgICAgICAgLy9wYXNzIHRoZSBpbnB1dCBzb3VyY2UgdG8gZG9jdW1lbnQgc2Nhbm5lciBpbXBsLgotICAgICAgICBzZXRJbnB1dFNvdXJjZShpbnB1dFNvdXJjZSk7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBAcGFyYW0gaW5wdXRTdHJlYW0KLSAgICAgKiBAcGFyYW0gZW5jb2RpbmcKLSAgICAgKiBAcGFyYW0gcHJvcHMKLSAgICAgKiBAdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbgotICAgICAqLwotICAgIHB1YmxpYyBYTUxTdHJlYW1SZWFkZXJJbXBsKElucHV0U3RyZWFtIGlucHV0U3RyZWFtLCBTdHJpbmcgZW5jb2RpbmcsIFByb3BlcnR5TWFuYWdlciBwcm9wcyApIHRocm93cyAgWE1MU3RyZWFtRXhjZXB0aW9uIHsKLSAgICAgICAgaW5pdChwcm9wcyk7Ci0gICAgICAgIC8vcHVibGljSWQsIHN5c3RlbWlkLCBiYXNlU3lzdGVtSWQsIGlucHV0U3RyZWFtLCBlbm9jZGluZwotICAgICAgICBYTUxJbnB1dFNvdXJjZSBpbnB1dFNvdXJjZSA9IG5ldyBYTUxJbnB1dFNvdXJjZShudWxsLG51bGwsbnVsbCwgbmV3IEJ1ZmZlcmVkSW5wdXRTdHJlYW0oaW5wdXRTdHJlYW0pLGVuY29kaW5nICk7Ci0gICAgICAgIC8vcGFzcyB0aGUgaW5wdXQgc291cmNlIHRvIGRvY3VtZW50IHNjYW5uZXIgaW1wbC4KLSAgICAgICAgc2V0SW5wdXRTb3VyY2UoaW5wdXRTb3VyY2UpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBwYXJhbSByZWFkZXIKLSAgICAgKiBAcGFyYW0gcHJvcHMKLSAgICAgKiBAdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbgotICAgICAqLwotICAgIHB1YmxpYyBYTUxTdHJlYW1SZWFkZXJJbXBsKFJlYWRlciByZWFkZXIsIFByb3BlcnR5TWFuYWdlciBwcm9wcykgdGhyb3dzICBYTUxTdHJlYW1FeGNlcHRpb24gewotICAgICAgICBpbml0KHByb3BzKTsKLSAgICAgICAgLy9wdWJsaWNJZCwgc3lzdGVtaWQsIGJhc2VTeXN0ZW1JZCwgaW5wdXRTdHJlYW0sIGVub2NkaW5nCi0gICAgICAgIC8veHh4OiBVc2luZyBidWZmZXJlZCByZWFkZXIKLSAgICAgICAgWE1MSW5wdXRTb3VyY2UgaW5wdXRTb3VyY2UgPSBuZXcgWE1MSW5wdXRTb3VyY2UobnVsbCxudWxsLG51bGwsbmV3IEJ1ZmZlcmVkUmVhZGVyKHJlYWRlciksbnVsbCk7Ci0gICAgICAgIC8vcGFzcyB0aGUgaW5wdXQgc291cmNlIHRvIGRvY3VtZW50IHNjYW5uZXIgaW1wbC4KLSAgICAgICAgc2V0SW5wdXRTb3VyY2UoaW5wdXRTb3VyY2UpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBwYXJhbSBpbnB1dFNvdXJjZQotICAgICAqIEBwYXJhbSBwcm9wcwotICAgICAqIEB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uCi0gICAgICovCi0gICAgcHVibGljIFhNTFN0cmVhbVJlYWRlckltcGwoWE1MSW5wdXRTb3VyY2UgaW5wdXRTb3VyY2UsIFByb3BlcnR5TWFuYWdlciBwcm9wcykgdGhyb3dzICBYTUxTdHJlYW1FeGNlcHRpb24gewotICAgICAgICBpbml0KHByb3BzKTsKLSAgICAgICAgLy9wYXNzIHRoZSBpbnB1dCBzb3VyY2UgdG8gZG9jdW1lbnQgc2Nhbm5lciBpbXBsLgotICAgICAgICBzZXRJbnB1dFNvdXJjZShpbnB1dFNvdXJjZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHBhcmFtIGlucHV0U291cmNlCi0gICAgICogQHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRJbnB1dFNvdXJjZShYTUxJbnB1dFNvdXJjZSBpbnB1dFNvdXJjZSApIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24gewotICAgICAgICAvL29uY2Ugc2V0SW5wdXRTb3VyY2UoKSBpcyBjYWxsZWQgdGhpcyBpbnN0YW5jZSBpcyBidXN5IHBhcnNpbmcgdGhlIGlucHV0c291cmNlIHN1cHBsaWVkCi0gICAgICAgIC8vdGhpcyBpbnN0YW5jZXMgaXMgZnJlZSBmb3IgcmV1c2UgaWYgcGFyc2VyIGhhcyByZWFjaGVkIEVORF9ET0NVTUVOVCBzdGF0ZSBvciBhcHBsaWNhdGlvbiBoYXMKLSAgICAgICAgLy9jYWxsZWQgY2xvc2UoKQotICAgICAgICBmUmV1c2UgPSBmYWxzZTsKLQotICAgICAgICB0cnl7Ci0KLSAgICAgICAgICAgIGZTY2FubmVyLnNldElucHV0U291cmNlKGlucHV0U291cmNlKSA7Ci0gICAgICAgICAgICAvL1hNTFN0cmVhbVJlYWRlciBzaG91bGQgYmUgaW4gZGVmaW5lZCBzdGF0ZQotICAgICAgICAgICAgaWYoZlJlYWRlckluRGVmaW5lZFN0YXRlKXsKLSAgICAgICAgICAgICAgICBmRXZlbnRUeXBlID0gZlNjYW5uZXIubmV4dCgpOwotICAgICAgICAgICAgICAgIGlmICh2ZXJzaW9uU3RyID09IG51bGwpCi0gICAgICAgICAgICAgICAgICAgIHZlcnNpb25TdHIgPSBnZXRWZXJzaW9uKCk7Ci0KLSAgICAgICAgICAgICAgICBpZiAoZkV2ZW50VHlwZSA9PSBYTUxTdHJlYW1Db25zdGFudHMuU1RBUlRfRE9DVU1FTlQgJiYgdmVyc2lvblN0ciAhPSBudWxsICYmIHZlcnNpb25TdHIuZXF1YWxzKCIxLjEiKSl7Ci0gICAgICAgICAgICAgICAgICAgIHN3aXRjaFRvWE1MMTFTY2FubmVyKCk7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICB9Ci0gICAgICAgIH1jYXRjaChqYXZhLmlvLklPRXhjZXB0aW9uIGV4KXsKLSAgICAgICAgICAgIHRocm93IG5ldyBYTUxTdHJlYW1FeGNlcHRpb24oZXgpOwotICAgICAgICB9IGNhdGNoKFhOSUV4Y2VwdGlvbiBleCl7IC8vSXNzdWUgNTYgWE5JRXhjZXB0aW9uIG5vdCBjYXVnaHQKLSAgICAgICAgICAgIHRocm93IG5ldyBYTUxTdHJlYW1FeGNlcHRpb24oZXguZ2V0TWVzc2FnZSgpLCBnZXRMb2NhdGlvbigpLCBleC5nZXRFeGNlcHRpb24oKSk7Ci0gICAgICAgIH0KLSAgICB9Ly9zZXRJbnB1dFNvdXJjZQotCi0gICAgdm9pZCBpbml0KFByb3BlcnR5TWFuYWdlciBwcm9wZXJ0eU1hbmFnZXIpIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24gewotICAgICAgICBmUHJvcGVydHlNYW5hZ2VyID0gcHJvcGVydHlNYW5hZ2VyOwotICAgICAgICAvL3NldCBTdGF4IGludGVybmFsIHByb3BlcnRpZXMgLS0gTm90ZSB0aGF0IHRoZXNlIGluc3RhbmNlcyBhcmUgYmVpbmcgY3JlYXRlZCBpbiBYTUxSZWFkZXJJbXBsLgotICAgICAgICAvLzEuU3ltYm9sVGFibGUKLSAgICAgICAgLy8yLlhNTE1lc3NhZ2VGb3JtYXR0ZXIKLSAgICAgICAgLy8zLlhNTEVudGl0eU1hbmFnZXIKLSAgICAgICAgLy80LiBjYWxsIHJlc2V0KCkKLSAgICAgICAgLy8xLgotICAgICAgICBwcm9wZXJ0eU1hbmFnZXIuc2V0UHJvcGVydHkoU1lNQk9MX1RBQkxFLCAgZlN5bWJvbFRhYmxlICkgOwotICAgICAgICAvLzIuCi0gICAgICAgIHByb3BlcnR5TWFuYWdlci5zZXRQcm9wZXJ0eShFUlJPUl9SRVBPUlRFUiwgIGZFcnJvclJlcG9ydGVyICkgOwotICAgICAgICAvLzMuCi0gICAgICAgIHByb3BlcnR5TWFuYWdlci5zZXRQcm9wZXJ0eShFTlRJVFlfTUFOQUdFUiwgZkVudGl0eU1hbmFnZXIpOwotICAgICAgICAvLzQuCi0gICAgICAgIHJlc2V0KCk7Ci0gICAgfQotCi0gICAgLyoqIFRoaXMgZnVuY3Rpb24gdGVsbHMgaWYgdGhpcyBpbnN0YW5jZXMgaXMgYXZhaWxhYmxlIGZvciByZXVzZS4KLSAgICAgKiBPbmUgbXVzdCBjYWxsIHJlc2V0KCkgYW5kIHNldElucHV0U291cmNlKCkgdG8gYmUgYWJsZSB0byByZXVzZQotICAgICAqIHRoaXMgaW5zdGFuY2UuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gY2FuUmV1c2UoKXsKLSAgICAgICAgaWYoREVCVUcpewotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJmUmV1c2UgPSAiICsgZlJldXNlKTsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiZkV2ZW50VHlwZSA9ICIgKyBnZXRFdmVudFR5cGVTdHJpbmcoZkV2ZW50VHlwZSkgKTsKLSAgICAgICAgfQotICAgICAgICAvL3doZW4gcGFyc2luZyBiZWdpbnMsIGZSZXVzZSBpcyBzZXQgdG8gZmFsc2UKLSAgICAgICAgLy9mUmV1c2UgaXMgc2V0IHRvICd0cnVlJyB3aGVuIGFwcGxpY2F0aW9uIGNhbGxzIGNsb3NlKCkKLSAgICAgICAgcmV0dXJuIGZSZXVzZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXNldHMgdGhpcyBpbnN0YW5jZSBzbyB0aGF0IHRoaXMgaW5zdGFuY2UgaXMgcmVhZHkgZm9yIHJldXNlLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHJlc2V0KCl7Ci0gICAgICAgIGZSZXVzZSA9IHRydWU7Ci0gICAgICAgIGZFdmVudFR5cGUgPSAwIDsKLSAgICAgICAgLy9yZXNldCBlbnRpdHkgbWFuYWdlcgotICAgICAgICBmRW50aXR5TWFuYWdlci5yZXNldChmUHJvcGVydHlNYW5hZ2VyKTsKLSAgICAgICAgLy9yZXNldCB0aGUgc2Nhbm5lcgotICAgICAgICBmU2Nhbm5lci5yZXNldChmUHJvcGVydHlNYW5hZ2VyKTsKLSAgICAgICAgLy9SRVZJU0lUOnRoaXMgaXMgdG9vIHVnbHkgLS0gd2UgYXJlIGdldHRpbmcgWE1MRW50aXR5TWFuYWdlciBhbmQgWE1MRW50aXR5UmVhZGVyIGZyb20KLSAgICAgICAgLy9wcm9wZXJ0eSBtYW5hZ2VyLCBpdCBzaG91bGQgYmUgb25seSBYTUxFbnRpdHlNYW5hZ2VyCi0gICAgICAgIGZEVEREZWNsID0gbnVsbDsKLSAgICAgICAgZkVudGl0eVNjYW5uZXIgPSAoWE1MRW50aXR5U2Nhbm5lcilmRW50aXR5TWFuYWdlci5nZXRFbnRpdHlTY2FubmVyKCkgIDsKLSAgICAgICAgLy9kZWZhdWx0IHZhbHVlIGZvciB0aGlzIHByb3BlcnR5IGlzIHRydWUuIEhvd2V2ZXIsIHRoaXMgc2hvdWxkIGJlIGZhbHNlIHdoZW4gdXNpbmcgWE1MRXZlbnRSZWFkZXIuLi4gVWdoLi4KLSAgICAgICAgLy9iZWNhdXNlIFhNTEV2ZW50UmVhZGVyIHNob3VsZCBub3QgaGF2ZSBkZWZpbmVkIHN0YXRlLgotICAgICAgICBmUmVhZGVySW5EZWZpbmVkU3RhdGUgPSAoKEJvb2xlYW4pZlByb3BlcnR5TWFuYWdlci5nZXRQcm9wZXJ0eShSRUFERVJfSU5fREVGSU5FRF9TVEFURSkpLmJvb2xlYW5WYWx1ZSgpOwotICAgICAgICBmQmluZE5hbWVzcGFjZXMgPSAoKEJvb2xlYW4pZlByb3BlcnR5TWFuYWdlci5nZXRQcm9wZXJ0eShYTUxJbnB1dEZhY3RvcnkuSVNfTkFNRVNQQUNFX0FXQVJFKSkuYm9vbGVhblZhbHVlKCk7Ci0gICAgICAgIHZlcnNpb25TdHIgPSBudWxsOwotICAgIH0KLQotCi0gICAgLyoqIEZyZWVzIGFueSByZXNvdXJjZXMgYXNzb2NpYXRlZCB3aXRoIHRoaXMgUmVhZGVyLiBUaGlzIG1ldGhvZCBkb2VzIG5vdCBjbG9zZSB0aGUgdW5kZXJseWluZyBpbnB1dCBzb3VyY2UuCi0gICAgICogQHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24gaWYgdGhlcmUgYXJlIGVycm9ycyBmcmVlaW5nIGFzc29jaWF0ZWQgcmVzb3VyY2VzCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uIHsKLSAgICAgICAgLy94eHg6IENoZWNrIHdoYXQgdGhpcyBmdW5jdGlvbiBpcyBpbnRlbmRlZCB0byBkby4KLSAgICAgICAgLy9yZXNldCgpOwotICAgICAgICBmUmV1c2UgPSB0cnVlIDsKLSAgICB9Ci0KLQotICAgIC8qKiBSZXR1cm5zIHRoZSBjaGFyYWN0ZXIgZW5jb2RpbmcgZGVjbGFyZWQgb24gdGhlIHhtbCBkZWNsYXJhdGlvbiBSZXR1cm5zIG51bGwgaWYgbm9uZSB3YXMgZGVjbGFyZWQKLSAgICAgKiBAcmV0dXJuIHRoZSBlbmNvZGluZyBkZWNsYXJlZCBpbiB0aGUgZG9jdW1lbnQgb3IgbnVsbAotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q2hhcmFjdGVyRW5jb2RpbmdTY2hlbWUoKSB7Ci0gICAgICAgIHJldHVybiBmU2Nhbm5lci5nZXRDaGFyYWN0ZXJFbmNvZGluZ1NjaGVtZSgpOwotCi0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBAcmV0dXJuCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRDb2x1bW5OdW1iZXIoKSB7Ci0gICAgICAgIHJldHVybiBmRW50aXR5U2Nhbm5lci5nZXRDb2x1bW5OdW1iZXIoKTsKLSAgICB9Ly9nZXRDb2x1bW5OdW1iZXIKLQotICAgIC8qKiBSZXR1cm4gaW5wdXQgZW5jb2RpbmcgaWYga25vd24gb3IgbnVsbCBpZiB1bmtub3duLgotICAgICAqIEByZXR1cm4gdGhlIGVuY29kaW5nIG9mIHRoaXMgaW5zdGFuY2Ugb3IgbnVsbAotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0RW5jb2RpbmcoKSB7Ci0gICAgICAgIHJldHVybiBmRW50aXR5U2Nhbm5lci5nZXRFbmNvZGluZygpOwotICAgIH0vL2dldEVuY29kaW5nCi0KLSAgICAvKiogUmV0dXJucyB0aGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgcGFyc2UgZXZlbnQgYXMgYSBzdHJpbmcsIHRoaXMgcmV0dXJucyB0aGUgc3RyaW5nIHZhbHVlIG9mIGEgQ0hBUkFDVEVSUyBldmVudCwgcmV0dXJucyB0aGUgdmFsdWUgb2YgYSBDT01NRU5ULCB0aGUgcmVwbGFjZW1lbnQgdmFsdWUgZm9yIGFuIEVOVElUWV9SRUZFUkVOQ0UsIHRoZSBzdHJpbmcgdmFsdWUgb2YgYSBDREFUQSBzZWN0aW9uLCB0aGUgc3RyaW5nIHZhbHVlIGZvciBhIFNQQUNFIGV2ZW50LCBvciB0aGUgU3RyaW5nIHZhbHVlIG9mIHRoZSBpbnRlcm5hbCBzdWJzZXQgb2YgdGhlIERURC4gSWYgYW4gRU5USVRZX1JFRkVSRU5DRSBoYXMgYmVlbiByZXNvbHZlZCwgYW55IGNoYXJhY3RlciBkYXRhIHdpbGwgYmUgcmVwb3J0ZWQgYXMgQ0hBUkFDVEVSUyBldmVudHMuCi0gICAgICogQHJldHVybiB0aGUgY3VycmVudCB0ZXh0IG9yIG51bGwKLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldEV2ZW50VHlwZSgpIHsKLSAgICAgICAgcmV0dXJuIGZFdmVudFR5cGUgOwotICAgIH0vL2dldEV2ZW50VHlwZQotCi0gICAgLyoqCi0gICAgICogQHJldHVybgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0TGluZU51bWJlcigpIHsKLSAgICAgICAgcmV0dXJuIGZFbnRpdHlTY2FubmVyLmdldExpbmVOdW1iZXIoKSA7Ci0gICAgfS8vZ2V0TGluZU51bWJlcgotCi0gICAgcHVibGljIFN0cmluZyBnZXRMb2NhbE5hbWUoKSB7Ci0gICAgICAgIGlmKGZFdmVudFR5cGUgPT0gWE1MRXZlbnQuU1RBUlRfRUxFTUVOVCB8fCBmRXZlbnRUeXBlID09IFhNTEV2ZW50LkVORF9FTEVNRU5UKXsKLSAgICAgICAgICAgIC8veHh4IGNoZWNrIHdoYXRzIHRoZSB2YWx1ZSBvZiBmQ3VycmVudEVsZW1lbnQKLSAgICAgICAgICAgIHJldHVybiBmU2Nhbm5lci5nZXRFbGVtZW50UU5hbWUoKS5sb2NhbHBhcnQgOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYoZkV2ZW50VHlwZSA9PSBYTUxFdmVudC5FTlRJVFlfUkVGRVJFTkNFKXsKLSAgICAgICAgICAgIHJldHVybiBmU2Nhbm5lci5nZXRFbnRpdHlOYW1lKCk7Ci0gICAgICAgIH0KLSAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiTWV0aG9kIGdldExvY2FsTmFtZSgpIGNhbm5vdCBiZSBjYWxsZWQgZm9yICIgKwotICAgICAgICAgICAgZ2V0RXZlbnRUeXBlU3RyaW5nKGZFdmVudFR5cGUpICsgIiBldmVudC4iKTsKLSAgICB9Ly9nZXRMb2NhbE5hbWUoKQotCi0gICAgLyoqCi0gICAgICogQHJldHVybgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZXNwYWNlVVJJKCkgewotICAgICAgICAvL2RvZXNuJ3QgdGFrZSBjYXJlIG9mIEF0dHJpYnV0ZSBhcyBzZXBhcnRlIGV2ZW50Ci0gICAgICAgIGlmKGZFdmVudFR5cGUgPT0gWE1MRXZlbnQuU1RBUlRfRUxFTUVOVCB8fCBmRXZlbnRUeXBlID09IFhNTEV2ZW50LkVORF9FTEVNRU5UKXsKLSAgICAgICAgICAgIHJldHVybiBmU2Nhbm5lci5nZXRFbGVtZW50UU5hbWUoKS51cmkgOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBudWxsIDsKLSAgICB9Ly9nZXROYW1lc3BhY2VVUkkKLQotICAgIC8qKiBHZXQgdGhlIGRhdGEgc2VjdGlvbiBvZiBhIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24KLSAgICAgKiBAcmV0dXJuIHRoZSBkYXRhIG9yIG51bGwKLSAgICAgKi8KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0UElEYXRhKCkgewotICAgICAgICBpZiggZkV2ZW50VHlwZSA9PSBYTUxFdmVudC5QUk9DRVNTSU5HX0lOU1RSVUNUSU9OKXsKLSAgICAgICAgICAgIHJldHVybiBmU2Nhbm5lci5nZXRQSURhdGEoKS50b1N0cmluZygpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsU3RhdGVFeGNlcHRpb24oIkN1cnJlbnQgc3RhdGUgb2YgdGhlIHBhcnNlciBpcyAiICsgZ2V0RXZlbnRUeXBlU3RyaW5nKGZFdmVudFR5cGUpICsKLSAgICAgICAgIiBCdXQgRXhwZWN0ZWQgc3RhdGUgaXMgIiArIFhNTEV2ZW50LlBST0NFU1NJTkdfSU5TVFJVQ1RJT04gICkgOwotICAgIH0vL2dldFBJRGF0YQotCi0KLSAgICAvKiogR2V0IHRoZSB0YXJnZXQgb2YgYSBwcm9jZXNzaW5nIGluc3RydWN0aW9uCi0gICAgICogQHJldHVybiB0aGUgdGFyZ2V0IG9yIG51bGwKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFBJVGFyZ2V0KCkgewotICAgICAgICBpZiggZkV2ZW50VHlwZSA9PSBYTUxFdmVudC5QUk9DRVNTSU5HX0lOU1RSVUNUSU9OKXsKLSAgICAgICAgICAgIHJldHVybiBmU2Nhbm5lci5nZXRQSVRhcmdldCgpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsU3RhdGVFeGNlcHRpb24oIkN1cnJlbnQgc3RhdGUgb2YgdGhlIHBhcnNlciBpcyAiICsgZ2V0RXZlbnRUeXBlU3RyaW5nKGZFdmVudFR5cGUpICsKLSAgICAgICAgIiBCdXQgRXhwZWN0ZWQgc3RhdGUgaXMgIiArIFhNTEV2ZW50LlBST0NFU1NJTkdfSU5TVFJVQ1RJT04gICkgOwotCi0gICAgfS8vZ2V0UElUYXJnZXQKLQotCi0gICAgLyoqCi0gICAgKiBAcmV0dXJuIHRoZSBwcmVmaXggb2YgdGhlIGN1cnJlbnQgZXZlbnQsIG9yIG51bGwgaWYgdGhlIGV2ZW50IGRvZXMKLSAgICAqIG5vdCBoYXZlIGEgcHJlZml4LiBGb3IgU1RBUlRfRUxFTUVOVCBhbmQgRU5EX0VMRU1FTlQsIHJldHVybgotICAgICogWE1MQ29uc3RhbnRzLkRFRkFVTFRfTlNfUFJFRklYIHdoZW4gbm8gcHJlZml4IGlzIGF2YWlsYWJsZS4KLSAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0UHJlZml4KCkgewotICAgICAgICBpZihmRXZlbnRUeXBlID09IFhNTEV2ZW50LlNUQVJUX0VMRU1FTlQgfHwgZkV2ZW50VHlwZSA9PSBYTUxFdmVudC5FTkRfRUxFTUVOVCl7Ci0gICAgICAgICAgICBTdHJpbmcgcHJlZml4ID0gZlNjYW5uZXIuZ2V0RWxlbWVudFFOYW1lKCkucHJlZml4OwotICAgICAgICAgICAgcmV0dXJuIHByZWZpeCA9PSBudWxsID8gWE1MQ29uc3RhbnRzLkRFRkFVTFRfTlNfUFJFRklYIDogcHJlZml4OwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBudWxsIDsKLSAgICB9Ly9nZXRQcmVmaXgoKQotCi0KLQotICAgIC8qKgotICAgICAqIEByZXR1cm4KLSAgICAgKi8KLSAgICBwdWJsaWMgY2hhcltdIGdldFRleHRDaGFyYWN0ZXJzKCkgewotICAgICAgICBpZiggZkV2ZW50VHlwZSA9PSBYTUxFdmVudC5DSEFSQUNURVJTIHx8IGZFdmVudFR5cGUgPT0gWE1MRXZlbnQuQ09NTUVOVAotICAgICAgICAgICAgICAgICB8fCBmRXZlbnRUeXBlID09IFhNTEV2ZW50LkNEQVRBIHx8IGZFdmVudFR5cGUgPT0gWE1MRXZlbnQuU1BBQ0UpewotICAgICAgICAgICAgIHJldHVybiBmU2Nhbm5lci5nZXRDaGFyYWN0ZXJEYXRhKCkuY2g7Ci0gICAgICAgICB9IGVsc2V7Ci0gICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiQ3VycmVudCBzdGF0ZSA9ICIgKyBnZXRFdmVudFR5cGVTdHJpbmcoZkV2ZW50VHlwZSkKLSAgICAgICAgICAgICArICIgaXMgbm90IGFtb25nIHRoZSBzdGF0ZXMgIiArIGdldEV2ZW50VHlwZVN0cmluZyhYTUxFdmVudC5DSEFSQUNURVJTKSArICIgLCAiCi0gICAgICAgICAgICAgICAgICAgICArIGdldEV2ZW50VHlwZVN0cmluZyhYTUxFdmVudC5DT01NRU5UKSArICIgLCAiICsgZ2V0RXZlbnRUeXBlU3RyaW5nKFhNTEV2ZW50LkNEQVRBKQotICAgICAgICAgICAgICAgICAgICAgKyAiICwgIiArIGdldEV2ZW50VHlwZVN0cmluZyhYTUxFdmVudC5TUEFDRSkgKyIgdmFsaWQgZm9yIGdldFRleHRDaGFyYWN0ZXJzKCkgIiApIDsKLSAgICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAcmV0dXJuCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRUZXh0TGVuZ3RoKCkgewotICAgICAgICBpZiggZkV2ZW50VHlwZSA9PSBYTUxFdmVudC5DSEFSQUNURVJTIHx8IGZFdmVudFR5cGUgPT0gWE1MRXZlbnQuQ09NTUVOVAotICAgICAgICAgICAgICAgICB8fCBmRXZlbnRUeXBlID09IFhNTEV2ZW50LkNEQVRBIHx8IGZFdmVudFR5cGUgPT0gWE1MRXZlbnQuU1BBQ0UpewotICAgICAgICAgICAgIHJldHVybiBmU2Nhbm5lci5nZXRDaGFyYWN0ZXJEYXRhKCkubGVuZ3RoOwotICAgICAgICAgfSBlbHNlewotICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oIkN1cnJlbnQgc3RhdGUgPSAiICsgZ2V0RXZlbnRUeXBlU3RyaW5nKGZFdmVudFR5cGUpCi0gICAgICAgICAgICAgKyAiIGlzIG5vdCBhbW9uZyB0aGUgc3RhdGVzICIgKyBnZXRFdmVudFR5cGVTdHJpbmcoWE1MRXZlbnQuQ0hBUkFDVEVSUykgKyAiICwgIgotICAgICAgICAgICAgICAgICAgICAgKyBnZXRFdmVudFR5cGVTdHJpbmcoWE1MRXZlbnQuQ09NTUVOVCkgKyAiICwgIiArIGdldEV2ZW50VHlwZVN0cmluZyhYTUxFdmVudC5DREFUQSkKLSAgICAgICAgICAgICAgICAgICAgICsgIiAsICIgKyBnZXRFdmVudFR5cGVTdHJpbmcoWE1MRXZlbnQuU1BBQ0UpICsiIHZhbGlkIGZvciBnZXRUZXh0TGVuZ3RoKCkgIiApIDsKLSAgICAgICAgIH0KLQotICAgfQotCi0gICAgLyoqCi0gICAgICogQHJldHVybgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0VGV4dFN0YXJ0KCkgewotICAgICAgICBpZiggZkV2ZW50VHlwZSA9PSBYTUxFdmVudC5DSEFSQUNURVJTIHx8IGZFdmVudFR5cGUgPT0gWE1MRXZlbnQuQ09NTUVOVCB8fCBmRXZlbnRUeXBlID09IFhNTEV2ZW50LkNEQVRBIHx8IGZFdmVudFR5cGUgPT0gWE1MRXZlbnQuU1BBQ0UpewotICAgICAgICAgICAgIHJldHVybiAgZlNjYW5uZXIuZ2V0Q2hhcmFjdGVyRGF0YSgpLm9mZnNldDsKLSAgICAgICAgIH0gZWxzZXsKLSAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJDdXJyZW50IHN0YXRlID0gIiArIGdldEV2ZW50VHlwZVN0cmluZyhmRXZlbnRUeXBlKQotICAgICAgICAgICAgICsgIiBpcyBub3QgYW1vbmcgdGhlIHN0YXRlcyAiICsgZ2V0RXZlbnRUeXBlU3RyaW5nKFhNTEV2ZW50LkNIQVJBQ1RFUlMpICsgIiAsICIKLSAgICAgICAgICAgICAgICAgICAgICsgZ2V0RXZlbnRUeXBlU3RyaW5nKFhNTEV2ZW50LkNPTU1FTlQpICsgIiAsICIgKyBnZXRFdmVudFR5cGVTdHJpbmcoWE1MRXZlbnQuQ0RBVEEpCi0gICAgICAgICAgICAgICAgICAgICArICIgLCAiICsgZ2V0RXZlbnRUeXBlU3RyaW5nKFhNTEV2ZW50LlNQQUNFKSArIiB2YWxpZCBmb3IgZ2V0VGV4dFN0YXJ0KCkgIiApIDsKLSAgICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAcmV0dXJuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRWYWx1ZSgpIHsKLSAgICAgICAgaWYoZkV2ZW50VHlwZSA9PSBYTUxFdmVudC5QUk9DRVNTSU5HX0lOU1RSVUNUSU9OKXsKLSAgICAgICAgICAgIHJldHVybiBmU2Nhbm5lci5nZXRQSURhdGEoKS50b1N0cmluZygpOwotICAgICAgICB9IGVsc2UgaWYoZkV2ZW50VHlwZSA9PSBYTUxFdmVudC5DT01NRU5UKXsKLSAgICAgICAgICAgIHJldHVybiBmU2Nhbm5lci5nZXRDb21tZW50KCk7Ci0gICAgICAgIH0gZWxzZSBpZihmRXZlbnRUeXBlID09IFhNTEV2ZW50LlNUQVJUX0VMRU1FTlQgfHwgZkV2ZW50VHlwZSA9PSBYTUxFdmVudC5FTkRfRUxFTUVOVCl7Ci0gICAgICAgICAgICByZXR1cm4gZlNjYW5uZXIuZ2V0RWxlbWVudFFOYW1lKCkubG9jYWxwYXJ0IDsKLSAgICAgICAgfSBlbHNlIGlmKGZFdmVudFR5cGUgPT0gWE1MRXZlbnQuQ0hBUkFDVEVSUyl7Ci0gICAgICAgICAgICByZXR1cm4gZlNjYW5uZXIuZ2V0Q2hhcmFjdGVyRGF0YSgpLnRvU3RyaW5nKCk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfS8vZ2V0VmFsdWUoKQotCi0gICAgLyoqIEdldCB0aGUgWE1MIGxhbmd1YWdlIHZlcnNpb24gb2YgdGhlIGN1cnJlbnQgZG9jdW1lbnQgYmVpbmcgcGFyc2VkICovCi0gICAgcHVibGljIFN0cmluZyBnZXRWZXJzaW9uKCkgewotICAgICAgICAvL2FwcGx5IFNBUCdzIHBhdGNoOiB0aGUgZGVmYXVsdCB2ZXJzaW9uIGluIHRoZSBzY2FubmVyIHdhcyBzZXQgdG8gMS4wIGJlY2F1c2Ugb2YgRE9NIGFuZCBTQVgKLSAgICAgICAgLy9zbyB0aGlzIHBhdGNoIGlzIGEgd29ya2Fyb3VuZCBvZiB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIFN0QVggYW5kIERPTQotICAgICAgICAvLyBTQVBKVk06IFJldHVybiBudWxsIGlmIHRoZSBYTUwgdmVyc2lvbiBoYXMgbm90IGJlZW4gZGVjbGFyZWQgKGFzIHNwZWNpZmllZCBpbiB0aGUgSmF2YURvYykuCi0KLSAgICAgICAgU3RyaW5nIHZlcnNpb24gPSBmRW50aXR5U2Nhbm5lci5nZXRYTUxWZXJzaW9uKCk7Ci0KLSAgICAgICAgcmV0dXJuICIxLjAiLmVxdWFscyh2ZXJzaW9uKSAmJiAhZkVudGl0eVNjYW5uZXIueG1sVmVyc2lvblNldEV4cGxpY2l0bHkgPyBudWxsIDogdmVyc2lvbjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAcmV0dXJuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaGFzQXR0cmlidXRlcygpIHsKLSAgICAgICAgcmV0dXJuIGZTY2FubmVyLmdldEF0dHJpYnV0ZUl0ZXJhdG9yKCkuZ2V0TGVuZ3RoKCkgPiAwID8gdHJ1ZSA6IGZhbHNlIDsKLSAgICB9Ci0KLSAgICAvKiogdGhpcyBGdW50aW9uIHJldHVybnMgdHJ1ZSBpZiB0aGUgY3VycmVudCBldmVudCBoYXMgbmFtZSAqLwotICAgIHB1YmxpYyBib29sZWFuIGhhc05hbWUoKSB7Ci0gICAgICAgIGlmKGZFdmVudFR5cGUgPT0gWE1MRXZlbnQuU1RBUlRfRUxFTUVOVCB8fCBmRXZlbnRUeXBlID09IFhNTEV2ZW50LkVORF9FTEVNRU5UKSB7Ci0gICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgfSAgZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLSAgICB9Ly9oYXNOYW1lKCkKLQotICAgIC8qKgotICAgICAqIEB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uCi0gICAgICogQHJldHVybgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGhhc05leHQoKSB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uIHsKLSAgICAgICAgLy90aGUgc2Nhbm5lciByZXR1cm5zIC0xIHdoZW4gaXQgZGV0ZWN0cyBhIGJyb2tlbiBzdHJlYW0KLSAgICAgICAgaWYgKGZFdmVudFR5cGUgPT0gLTEpIHJldHVybiBmYWxzZTsKLSAgICAgICAgLy93ZSBjYW4gY2hlY2sgaW4gc2Nhbm5lcnMgaWYgdGhlIHNjYW5uZXIgc3RhdGUgaXMgbm90IHNldCB0bwotICAgICAgICAvL3Rlcm1pbmF0aW5nLCB3ZSBzdGlsbCBoYXZlIG1vcmUgZXZlbnRzLgotICAgICAgICByZXR1cm4gZkV2ZW50VHlwZSAhPSBYTUxFdmVudC5FTkRfRE9DVU1FTlQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHJldHVybgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGhhc1ZhbHVlKCkgewotICAgICAgICBpZihmRXZlbnRUeXBlID09IFhNTEV2ZW50LlNUQVJUX0VMRU1FTlQgfHwgZkV2ZW50VHlwZSA9PSBYTUxFdmVudC5FTkRfRUxFTUVOVAotICAgICAgICB8fCBmRXZlbnRUeXBlID09IFhNTEV2ZW50LkVOVElUWV9SRUZFUkVOQ0UgfHwgZkV2ZW50VHlwZSA9PSBYTUxFdmVudC5QUk9DRVNTSU5HX0lOU1RSVUNUSU9OCi0gICAgICAgIHx8IGZFdmVudFR5cGUgPT0gWE1MRXZlbnQuQ09NTUVOVCB8fCBmRXZlbnRUeXBlID09IFhNTEV2ZW50LkNIQVJBQ1RFUlMpIHsKLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAcmV0dXJuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNFbmRFbGVtZW50KCkgewotICAgICAgICByZXR1cm4gZkV2ZW50VHlwZSA9PSBYTUxFdmVudC5FTkRfRUxFTUVOVDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAcmV0dXJuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNTdGFuZGFsb25lKCkgewotICAgICAgICByZXR1cm4gZlNjYW5uZXIuaXNTdGFuZEFsb25lKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHJldHVybgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzU3RhcnRFbGVtZW50KCkgewotICAgICAgICByZXR1cm4gZkV2ZW50VHlwZSA9PSBYTUxFdmVudC5TVEFSVF9FTEVNRU5UOwotICAgIH0KLQotICAgIC8qKgotICAgICAqICBSZXR1cm5zIHRydWUgaWYgdGhlIGN1cnNvciBwb2ludHMgdG8gYSBjaGFyYWN0ZXIgZGF0YSBldmVudCB0aGF0IGNvbnNpc3RzIG9mIGFsbCB3aGl0ZXNwYWNlCi0gICAgICogIEFwcGxpY2F0aW9uIGNhbGxpbmcgdGhpcyBtZXRob2QgbmVlZHMgdG8gY2FjaGUgdGhlIHZhbHVlIGFuZCBhdm9pZCBjYWxsaW5nIHRoaXMgbWV0aG9kIGFnYWluCi0gICAgICogIGZvciB0aGUgc2FtZSBldmVudC4KLSAgICAgKiBAcmV0dXJuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNXaGl0ZVNwYWNlKCkgewotICAgICAgICBpZihpc0NoYXJhY3RlcnMoKSB8fCAoZkV2ZW50VHlwZSA9PSBYTUxTdHJlYW1Db25zdGFudHMuQ0RBVEEpKXsKLSAgICAgICAgICAgIGNoYXIgW10gY2ggPSB0aGlzLmdldFRleHRDaGFyYWN0ZXJzKCk7Ci0gICAgICAgICAgICBmaW5hbCBpbnQgc3RhcnQgPSB0aGlzLmdldFRleHRTdGFydCgpOwotICAgICAgICAgICAgZmluYWwgaW50IGVuZCA9IHN0YXJ0ICsgdGhpcy5nZXRUZXh0TGVuZ3RoKCk7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKyl7Ci0gICAgICAgICAgICAgICAgaWYoIVhNTENoYXIuaXNTcGFjZShjaFtpXSkpewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotCi0KLSAgICAvKioKLSAgICAgKiBAdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbgotICAgICAqIEByZXR1cm4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IG5leHQoKSB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uIHsKLSAgICAgICAgaWYoICFoYXNOZXh0KCkgKSB7Ci0gICAgICAgICAgICBpZiAoZkV2ZW50VHlwZSAhPSAtMSkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBqYXZhLnV0aWwuTm9TdWNoRWxlbWVudEV4Y2VwdGlvbiggIkVORF9ET0NVTUVOVCByZWFjaGVkOiBubyBtb3JlIGVsZW1lbnRzIG9uIHRoZSBzdHJlYW0uIiApOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWE1MU3RyZWFtRXhjZXB0aW9uKCAiRXJyb3IgcHJvY2Vzc2luZyBpbnB1dCBzb3VyY2UuIFRoZSBpbnB1dCBzdHJlYW0gaXMgbm90IGNvbXBsZXRlLiIgKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICB0cnkgewotICAgICAgICAgICAgZkV2ZW50VHlwZSA9IGZTY2FubmVyLm5leHQoKTsKLQotICAgICAgICAgICAgaWYgKHZlcnNpb25TdHIgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHZlcnNpb25TdHIgPSBnZXRWZXJzaW9uKCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmIChmRXZlbnRUeXBlID09IFhNTFN0cmVhbUNvbnN0YW50cy5TVEFSVF9ET0NVTUVOVAotICAgICAgICAgICAgICAgICAgICAmJiB2ZXJzaW9uU3RyICE9IG51bGwKLSAgICAgICAgICAgICAgICAgICAgJiYgdmVyc2lvblN0ci5lcXVhbHMoIjEuMSIpKSB7Ci0gICAgICAgICAgICAgICAgc3dpdGNoVG9YTUwxMVNjYW5uZXIoKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgcmV0dXJuIGZFdmVudFR5cGU7Ci0gICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7Ci0gICAgICAgICAgICAvLyBpZiB0aGlzIGVycm9yIG9jY3VyZWQgdHJ5aW5nIHRvIHJlc29sdmUgdGhlIGV4dGVybmFsIERURCBzdWJzZXQKLSAgICAgICAgICAgIC8vIGFuZCBJU19WQUxJREFUSU5HID09IGZhbHNlLCB0aGVuIHRoaXMgaXMgbm90IGFuIFhNTCBlcnJvcgotICAgICAgICAgICAgaWYgKGZTY2FubmVyLmZTY2FubmVyU3RhdGUgPT0gZlNjYW5uZXIuU0NBTk5FUl9TVEFURV9EVERfRVhURVJOQUwpIHsKLSAgICAgICAgICAgICAgICBCb29sZWFuIGlzVmFsaWRhdGluZyA9IChCb29sZWFuKSBmUHJvcGVydHlNYW5hZ2VyLmdldFByb3BlcnR5KAotICAgICAgICAgICAgICAgICAgICAgICAgWE1MSW5wdXRGYWN0b3J5LklTX1ZBTElEQVRJTkcpOwotICAgICAgICAgICAgICAgIGlmIChpc1ZhbGlkYXRpbmcgIT0gbnVsbAotICAgICAgICAgICAgICAgICAgICAgICAgJiYgIWlzVmFsaWRhdGluZy5ib29sZWFuVmFsdWUoKSkgewotICAgICAgICAgICAgICAgICAgICAvLyBpZ25vcmUgdGhlIGVycm9yLCBzZXQgc2Nhbm5lciB0byBrbm93biBzdGF0ZQotICAgICAgICAgICAgICAgICAgICBmRXZlbnRUeXBlID0gWE1MRXZlbnQuRFREOwotICAgICAgICAgICAgICAgICAgICBmU2Nhbm5lci5zZXRTY2FubmVyU3RhdGUoZlNjYW5uZXIuU0NBTk5FUl9TVEFURV9QUk9MT0cpOwotICAgICAgICAgICAgICAgICAgICBmU2Nhbm5lci5zZXREcml2ZXIoZlNjYW5uZXIuZlByb2xvZ0RyaXZlcik7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChmRFRERGVjbCA9PSBudWxsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgZkRURERlY2wubGVuZ3RoKCkgPT0gMCkgewotICAgICAgICAgICAgICAgICAgICAgICAgZkRURERlY2wgPSAiPCEtLSAiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIkV4Y2VwdGlvbiBzY2FubmluZyBFeHRlcm5hbCBEVEQgU3Vic2V0LiAgIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICJUcnVlIGNvbnRlbnRzIG9mIERURCBjYW5ub3QgYmUgZGV0ZXJtaW5lZC4gICIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiUHJvY2Vzc2luZyB3aWxsIGNvbnRpbnVlIGFzIFhNTElucHV0RmFjdG9yeS5JU19WQUxJREFUSU5HID09IGZhbHNlLiIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiIC0tPiI7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFhNTEV2ZW50LkRURDsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIGVsc2UgcmVhbCBlcnJvcgotICAgICAgICAgICAgdGhyb3cgbmV3IFhNTFN0cmVhbUV4Y2VwdGlvbihleC5nZXRNZXNzYWdlKCksIGdldExvY2F0aW9uKCksIGV4KTsKLSAgICAgICAgfSBjYXRjaCAoWE5JRXhjZXB0aW9uIGV4KSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWE1MU3RyZWFtRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICBleC5nZXRNZXNzYWdlKCksCi0gICAgICAgICAgICAgICAgICAgIGdldExvY2F0aW9uKCksCi0gICAgICAgICAgICAgICAgICAgIGV4LmdldEV4Y2VwdGlvbigpKTsKLSAgICAgICAgfQotICAgIH0gLy9uZXh0KCkKLQotICAgIHByaXZhdGUgdm9pZCBzd2l0Y2hUb1hNTDExU2Nhbm5lcigpIHRocm93cyBJT0V4Y2VwdGlvbnsKLQotICAgICAgICBpbnQgb2xkRW50aXR5RGVwdGggPSBmU2Nhbm5lci5mRW50aXR5RGVwdGg7Ci0gICAgICAgIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLk5hbWVzcGFjZUNvbnRleHQgb2xkTmFtZXNwYWNlQ29udGV4dCA9IGZTY2FubmVyLmZOYW1lc3BhY2VDb250ZXh0OwotCi0gICAgICAgIGZTY2FubmVyID0gbmV3IFhNTDExTlNEb2N1bWVudFNjYW5uZXJJbXBsKCk7Ci0KLSAgICAgICAgLy9nZXQgdGhlIG5ldyBzY2FubmVyIHN0YXRlIHRvIG9sZCBzY2FubmVyJ3MgcHJldmlvdXMgc3RhdGUKLSAgICAgICAgZlNjYW5uZXIucmVzZXQoZlByb3BlcnR5TWFuYWdlcik7Ci0gICAgICAgIGZTY2FubmVyLnNldFByb3BlcnR5TWFuYWdlcihmUHJvcGVydHlNYW5hZ2VyKTsKLSAgICAgICAgZkVudGl0eVNjYW5uZXIgPSAoWE1MRW50aXR5U2Nhbm5lcilmRW50aXR5TWFuYWdlci5nZXRFbnRpdHlTY2FubmVyKCkgIDsKLSAgICAgICAgZkVudGl0eU1hbmFnZXIuZkN1cnJlbnRFbnRpdHkubWF5UmVhZENodW5rcyA9IHRydWU7Ci0gICAgICAgIGZTY2FubmVyLnNldFNjYW5uZXJTdGF0ZShYTUxFdmVudC5TVEFSVF9ET0NVTUVOVCk7Ci0KLSAgICAgICAgZlNjYW5uZXIuZkVudGl0eURlcHRoID0gb2xkRW50aXR5RGVwdGg7Ci0gICAgICAgIGZTY2FubmVyLmZOYW1lc3BhY2VDb250ZXh0ID0gb2xkTmFtZXNwYWNlQ29udGV4dDsKLSAgICAgICAgZkV2ZW50VHlwZSA9IGZTY2FubmVyLm5leHQoKTsKLSAgICB9Ci0KLQotCi0gICAgZmluYWwgc3RhdGljIFN0cmluZyBnZXRFdmVudFR5cGVTdHJpbmcoaW50IGV2ZW50VHlwZSkgewotICAgICAgICBzd2l0Y2ggKGV2ZW50VHlwZSl7Ci0gICAgICAgICAgICBjYXNlIFhNTEV2ZW50LlNUQVJUX0VMRU1FTlQ6Ci0gICAgICAgICAgICAgICAgcmV0dXJuICJTVEFSVF9FTEVNRU5UIjsKLSAgICAgICAgICAgIGNhc2UgWE1MRXZlbnQuRU5EX0VMRU1FTlQ6Ci0gICAgICAgICAgICAgICAgcmV0dXJuICJFTkRfRUxFTUVOVCI7Ci0gICAgICAgICAgICBjYXNlIFhNTEV2ZW50LlBST0NFU1NJTkdfSU5TVFJVQ1RJT046Ci0gICAgICAgICAgICAgICAgcmV0dXJuICJQUk9DRVNTSU5HX0lOU1RSVUNUSU9OIjsKLSAgICAgICAgICAgIGNhc2UgWE1MRXZlbnQuQ0hBUkFDVEVSUzoKLSAgICAgICAgICAgICAgICByZXR1cm4gIkNIQVJBQ1RFUlMiOwotICAgICAgICAgICAgY2FzZSBYTUxFdmVudC5DT01NRU5UOgotICAgICAgICAgICAgICAgIHJldHVybiAiQ09NTUVOVCI7Ci0gICAgICAgICAgICBjYXNlIFhNTEV2ZW50LlNUQVJUX0RPQ1VNRU5UOgotICAgICAgICAgICAgICAgIHJldHVybiAiU1RBUlRfRE9DVU1FTlQiOwotICAgICAgICAgICAgY2FzZSBYTUxFdmVudC5FTkRfRE9DVU1FTlQ6Ci0gICAgICAgICAgICAgICAgcmV0dXJuICJFTkRfRE9DVU1FTlQiOwotICAgICAgICAgICAgY2FzZSBYTUxFdmVudC5FTlRJVFlfUkVGRVJFTkNFOgotICAgICAgICAgICAgICAgIHJldHVybiAiRU5USVRZX1JFRkVSRU5DRSI7Ci0gICAgICAgICAgICBjYXNlIFhNTEV2ZW50LkFUVFJJQlVURToKLSAgICAgICAgICAgICAgICByZXR1cm4gIkFUVFJJQlVURSI7Ci0gICAgICAgICAgICBjYXNlIFhNTEV2ZW50LkRURDoKLSAgICAgICAgICAgICAgICByZXR1cm4gIkRURCI7Ci0gICAgICAgICAgICBjYXNlIFhNTEV2ZW50LkNEQVRBOgotICAgICAgICAgICAgICAgIHJldHVybiAiQ0RBVEEiOwotICAgICAgICAgICAgY2FzZSBYTUxFdmVudC5TUEFDRToKLSAgICAgICAgICAgICAgICByZXR1cm4gIlNQQUNFIjsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gIlVOS05PV05fRVZFTlRfVFlQRSwgIiArIFN0cmluZy52YWx1ZU9mKGV2ZW50VHlwZSk7Ci0gICAgfQotCi0gICAgLyoqIFJldHVybnMgdGhlIGNvdW50IG9mIGF0dHJpYnV0ZXMgb24gdGhpcyBTVEFSVF9FTEVNRU5ULAotICAgICAqIHRoaXMgbWV0aG9kIGlzIG9ubHkgdmFsaWQgb24gYSBTVEFSVF9FTEVNRU5UIG9yIEFUVFJJQlVURS4gIFRoaXMKLSAgICAgKiBjb3VudCBleGNsdWRlcyBuYW1lc3BhY2UgZGVmaW5pdGlvbnMuICBBdHRyaWJ1dGUgaW5kaWNlcyBhcmUKLSAgICAgKiB6ZXJvLWJhc2VkLgotICAgICAqIEByZXR1cm4gcmV0dXJucyB0aGUgbnVtYmVyIG9mIGF0dHJpYnV0ZXMKLSAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGlzIGlzIG5vdCBhIFNUQVJUX0VMRU1FTlQgb3IgQVRUUklCVVRFCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRBdHRyaWJ1dGVDb3VudCgpIHsKLSAgICAgICAgLy94eHg6IHJlY29nbml6ZSBTQVggcHJvcGVydGllcyBuYW1lc3BhY2UsIG5hbWVzcGFjZS1wcmVmaXggdG8gZ2V0IFhNTCBOYW1lc3BhY2UgZGVjbGFyYXRpb25zCi0gICAgICAgIC8vZG9lcyBsZW5ndGggaW5jbHVkZXMgbmFtZXNwYWNlIGRlY2xhcmF0aW9ucyA/Ci0KLSAgICAgICAgLy9TdGF0ZSBzaG91bGQgYmUgZWl0aGVyIFNUQVJUX0VMRU1FTlQgb3IgQVRUUklCVVRFCi0gICAgICAgIGlmKCBmRXZlbnRUeXBlID09IFhNTEV2ZW50LlNUQVJUX0VMRU1FTlQgfHwgZkV2ZW50VHlwZSA9PSBYTUxFdmVudC5BVFRSSUJVVEUpIHsKLSAgICAgICAgICAgIHJldHVybiBmU2Nhbm5lci5nZXRBdHRyaWJ1dGVJdGVyYXRvcigpLmdldExlbmd0aCgpIDsKLSAgICAgICAgfSBlbHNlewotICAgICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsU3RhdGVFeGNlcHRpb24oICJDdXJyZW50IHN0YXRlIGlzIG5vdCBhbW9uZyB0aGUgc3RhdGVzICIKLSAgICAgICAgICAgICAgICAgICAgICsgZ2V0RXZlbnRUeXBlU3RyaW5nKFhNTEV2ZW50LlNUQVJUX0VMRU1FTlQpICsgIiAsICIKLSAgICAgICAgICAgICAgICAgICAgICsgZ2V0RXZlbnRUeXBlU3RyaW5nKFhNTEV2ZW50LkFUVFJJQlVURSkKLSAgICAgICAgICAgICAgICAgICAgICsgInZhbGlkIGZvciBnZXRBdHRyaWJ1dGVDb3VudCgpIikgOwotICAgICAgICB9Ci0gICAgfS8vZ2V0QXR0cmlidXRlQ291bnQKLQotICAgIC8qKiBSZXR1cm5zIHRoZSBsb2NhbE5hbWUgb2YgdGhlIGF0dHJpYnV0ZSBhdCB0aGUgcHJvdmlkZWQKLSAgICAgKiBpbmRleAotICAgICAqIEBwYXJhbSBpbmRleCB0aGUgcG9zaXRpb24gb2YgdGhlIGF0dHJpYnV0ZQotICAgICAqIEByZXR1cm4gdGhlIGxvY2FsTmFtZSBvZiB0aGUgYXR0cmlidXRlCi0gICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBpcyBub3QgYSBTVEFSVF9FTEVNRU5UIG9yIEFUVFJJQlVURQotICAgICAqLwotICAgIHB1YmxpYyBRTmFtZSBnZXRBdHRyaWJ1dGVOYW1lKGludCBpbmRleCkgewotICAgICAgICAvL1N0YXRlIHNob3VsZCBiZSBlaXRoZXIgU1RBUlRfRUxFTUVOVCBvciBBVFRSSUJVVEUKLSAgICAgICAgaWYoIGZFdmVudFR5cGUgPT0gWE1MRXZlbnQuU1RBUlRfRUxFTUVOVCB8fCBmRXZlbnRUeXBlID09IFhNTEV2ZW50LkFUVFJJQlVURSkgewotICAgICAgICAgICAgcmV0dXJuIGNvbnZlcnRYTklRTmFtZXRvSmF2YXhRTmFtZShmU2Nhbm5lci5nZXRBdHRyaWJ1dGVJdGVyYXRvcigpLmdldFF1YWxpZmllZE5hbWUoaW5kZXgpKSA7Ci0gICAgICAgIH0gZWxzZXsKLSAgICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJDdXJyZW50IHN0YXRlIGlzIG5vdCBhbW9uZyB0aGUgc3RhdGVzICIKLSAgICAgICAgICAgICAgICAgICAgICsgZ2V0RXZlbnRUeXBlU3RyaW5nKFhNTEV2ZW50LlNUQVJUX0VMRU1FTlQpICsgIiAsICIKLSAgICAgICAgICAgICAgICAgICAgICsgZ2V0RXZlbnRUeXBlU3RyaW5nKFhNTEV2ZW50LkFUVFJJQlVURSkKLSAgICAgICAgICAgICAgICAgICAgICsgInZhbGlkIGZvciBnZXRBdHRyaWJ1dGVOYW1lKCkiKSA7Ci0gICAgICAgIH0KLSAgICB9Ly9nZXRBdHRyaWJ1dGVOYW1lCi0KLSAgICAvKioKLSAgICAgKiBAcGFyYW0gaW5kZXgKLSAgICAgKiBAcmV0dXJuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRBdHRyaWJ1dGVMb2NhbE5hbWUoaW50IGluZGV4KSB7Ci0gICAgICAgIC8vU3RhdGUgc2hvdWxkIGJlIGVpdGhlciBTVEFSVF9FTEVNRU5UIG9yIEFUVFJJQlVURQotICAgICAgICBpZiggZkV2ZW50VHlwZSA9PSBYTUxFdmVudC5TVEFSVF9FTEVNRU5UIHx8IGZFdmVudFR5cGUgPT0gWE1MRXZlbnQuQVRUUklCVVRFKSB7Ci0gICAgICAgICAgICByZXR1cm4gZlNjYW5uZXIuZ2V0QXR0cmlidXRlSXRlcmF0b3IoKS5nZXRMb2NhbE5hbWUoaW5kZXgpIDsKLSAgICAgICAgfSBlbHNlewotICAgICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsU3RhdGVFeGNlcHRpb24oKSA7Ci0gICAgICAgIH0KLSAgICB9Ly9nZXRBdHRyaWJ1dGVOYW1lCi0KLSAgICAvKiogUmV0dXJucyB0aGUgbmFtZXNwYWNlIG9mIHRoZSBhdHRyaWJ1dGUgYXQgdGhlIHByb3ZpZGVkCi0gICAgICogaW5kZXgKLSAgICAgKiBAcGFyYW0gaW5kZXggdGhlIHBvc2l0aW9uIG9mIHRoZSBhdHRyaWJ1dGUKLSAgICAgKiBAcmV0dXJuIHRoZSBuYW1lc3BhY2UgVVJJIChjYW4gYmUgbnVsbCkKLSAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGlzIGlzIG5vdCBhIFNUQVJUX0VMRU1FTlQgb3IgQVRUUklCVVRFCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRBdHRyaWJ1dGVOYW1lc3BhY2UoaW50IGluZGV4KSB7Ci0gICAgICAgIC8vU3RhdGUgc2hvdWxkIGJlIGVpdGhlciBTVEFSVF9FTEVNRU5UIG9yIEFUVFJJQlVURQotICAgICAgICBpZiggZkV2ZW50VHlwZSA9PSBYTUxFdmVudC5TVEFSVF9FTEVNRU5UIHx8IGZFdmVudFR5cGUgPT0gWE1MRXZlbnQuQVRUUklCVVRFKSB7Ci0gICAgICAgICAgICByZXR1cm4gZlNjYW5uZXIuZ2V0QXR0cmlidXRlSXRlcmF0b3IoKS5nZXRVUkkoaW5kZXgpOwotICAgICAgICB9IGVsc2V7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiQ3VycmVudCBzdGF0ZSBpcyBub3QgYW1vbmcgdGhlIHN0YXRlcyAiCi0gICAgICAgICAgICAgICAgICAgICArIGdldEV2ZW50VHlwZVN0cmluZyhYTUxFdmVudC5TVEFSVF9FTEVNRU5UKSArICIgLCAiCi0gICAgICAgICAgICAgICAgICAgICArIGdldEV2ZW50VHlwZVN0cmluZyhYTUxFdmVudC5BVFRSSUJVVEUpCi0gICAgICAgICAgICAgICAgICAgICArICJ2YWxpZCBmb3IgZ2V0QXR0cmlidXRlTmFtZXNwYWNlKCkiKSA7Ci0gICAgICAgIH0KLQotICAgIH0vL2dldEF0dHJpYnV0ZU5hbWVzcGFjZQotCi0gICAgLyoqIFJldHVybnMgdGhlIHByZWZpeCBvZiB0aGlzIGF0dHJpYnV0ZSBhdCB0aGUKLSAgICAgKiBwcm92aWRlZCBpbmRleAotICAgICAqIEBwYXJhbSBpbmRleCB0aGUgcG9zaXRpb24gb2YgdGhlIGF0dHJpYnV0ZQotICAgICAqIEByZXR1cm4gdGhlIHByZWZpeCBvZiB0aGUgYXR0cmlidXRlCi0gICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBpcyBub3QgYSBTVEFSVF9FTEVNRU5UIG9yIEFUVFJJQlVURQotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0QXR0cmlidXRlUHJlZml4KGludCBpbmRleCkgewotICAgICAgICAvL1N0YXRlIHNob3VsZCBiZSBlaXRoZXIgU1RBUlRfRUxFTUVOVCBvciBBVFRSSUJVVEUKLSAgICAgICAgaWYoIGZFdmVudFR5cGUgPT0gWE1MRXZlbnQuU1RBUlRfRUxFTUVOVCB8fCBmRXZlbnRUeXBlID09IFhNTEV2ZW50LkFUVFJJQlVURSkgewotICAgICAgICAgICAgcmV0dXJuIGZTY2FubmVyLmdldEF0dHJpYnV0ZUl0ZXJhdG9yKCkuZ2V0UHJlZml4KGluZGV4KTsKLSAgICAgICAgfSBlbHNlewotICAgICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsU3RhdGVFeGNlcHRpb24oIkN1cnJlbnQgc3RhdGUgaXMgbm90IGFtb25nIHRoZSBzdGF0ZXMgIgotICAgICAgICAgICAgICAgICAgICAgKyBnZXRFdmVudFR5cGVTdHJpbmcoWE1MRXZlbnQuU1RBUlRfRUxFTUVOVCkgKyAiICwgIgotICAgICAgICAgICAgICAgICAgICAgKyBnZXRFdmVudFR5cGVTdHJpbmcoWE1MRXZlbnQuQVRUUklCVVRFKQotICAgICAgICAgICAgICAgICAgICAgKyAidmFsaWQgZm9yIGdldEF0dHJpYnV0ZVByZWZpeCgpIikgOwotICAgICAgICB9Ci0gICAgfS8vZ2V0QXR0cmlidXRlUHJlZml4Ci0KLSAgICAvKiogUmV0dXJucyB0aGUgcW5hbWUgb2YgdGhlIGF0dHJpYnV0ZSBhdCB0aGUgcHJvdmlkZWQgaW5kZXgKLSAgICAgKgotICAgICAqIEBwYXJhbSBpbmRleCB0aGUgcG9zaXRpb24gb2YgdGhlIGF0dHJpYnV0ZQotICAgICAqIEByZXR1cm4gdGhlIFFOYW1lIG9mIHRoZSBhdHRyaWJ1dGUKLSAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGlzIGlzIG5vdCBhIFNUQVJUX0VMRU1FTlQgb3IgQVRUUklCVVRFCi0gICAgICovCi0gICAgcHVibGljIGphdmF4LnhtbC5uYW1lc3BhY2UuUU5hbWUgZ2V0QXR0cmlidXRlUU5hbWUoaW50IGluZGV4KSB7Ci0gICAgICAgIC8vU3RhdGUgc2hvdWxkIGJlIGVpdGhlciBTVEFSVF9FTEVNRU5UIG9yIEFUVFJJQlVURQotICAgICAgICBpZiggZkV2ZW50VHlwZSA9PSBYTUxFdmVudC5TVEFSVF9FTEVNRU5UIHx8IGZFdmVudFR5cGUgPT0gWE1MRXZlbnQuQVRUUklCVVRFKSB7Ci0gICAgICAgICAgICAvLyBjcmVhdGUgbmV3IG9iamVjdCBhdCBydW50aW1lLi4KLSAgICAgICAgICAgIFN0cmluZyBsb2NhbE5hbWUgPSBmU2Nhbm5lci5nZXRBdHRyaWJ1dGVJdGVyYXRvcigpLmdldExvY2FsTmFtZShpbmRleCkgOwotICAgICAgICAgICAgU3RyaW5nIHVyaSA9IGZTY2FubmVyLmdldEF0dHJpYnV0ZUl0ZXJhdG9yKCkuZ2V0VVJJKGluZGV4KSA7Ci0gICAgICAgICAgICByZXR1cm4gbmV3IGphdmF4LnhtbC5uYW1lc3BhY2UuUU5hbWUodXJpLCBsb2NhbE5hbWUpIDsKLSAgICAgICAgfSBlbHNlewotICAgICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsU3RhdGVFeGNlcHRpb24oIkN1cnJlbnQgc3RhdGUgaXMgbm90IGFtb25nIHRoZSBzdGF0ZXMgIgotICAgICAgICAgICAgICAgICAgICAgKyBnZXRFdmVudFR5cGVTdHJpbmcoWE1MRXZlbnQuU1RBUlRfRUxFTUVOVCkgKyAiICwgIgotICAgICAgICAgICAgICAgICAgICAgKyBnZXRFdmVudFR5cGVTdHJpbmcoWE1MRXZlbnQuQVRUUklCVVRFKQotICAgICAgICAgICAgICAgICAgICAgKyAidmFsaWQgZm9yIGdldEF0dHJpYnV0ZVFOYW1lKCkiKSA7Ci0gICAgICAgIH0KLSAgICB9Ly9nZXRBdHRyaWJ1dGVRTmFtZQotCi0gICAgLyoqIFJldHVybnMgdGhlIFhNTCB0eXBlIG9mIHRoZSBhdHRyaWJ1dGUgYXQgdGhlIHByb3ZpZGVkCi0gICAgICogaW5kZXgKLSAgICAgKiBAcGFyYW0gaW5kZXggdGhlIHBvc2l0aW9uIG9mIHRoZSBhdHRyaWJ1dGUKLSAgICAgKiBAcmV0dXJuIHRoZSBYTUwgdHlwZSBvZiB0aGUgYXR0cmlidXRlCi0gICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBpcyBub3QgYSBTVEFSVF9FTEVNRU5UIG9yIEFUVFJJQlVURQotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0QXR0cmlidXRlVHlwZShpbnQgaW5kZXgpIHsKLSAgICAgICAgLy9TdGF0ZSBzaG91bGQgYmUgZWl0aGVyIFNUQVJUX0VMRU1FTlQgb3IgQVRUUklCVVRFCi0gICAgICAgIGlmKCBmRXZlbnRUeXBlID09IFhNTEV2ZW50LlNUQVJUX0VMRU1FTlQgfHwgZkV2ZW50VHlwZSA9PSBYTUxFdmVudC5BVFRSSUJVVEUpIHsKLSAgICAgICAgICAgIHJldHVybiBmU2Nhbm5lci5nZXRBdHRyaWJ1dGVJdGVyYXRvcigpLmdldFR5cGUoaW5kZXgpIDsKLSAgICAgICAgfSBlbHNlewotICAgICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsU3RhdGVFeGNlcHRpb24oIkN1cnJlbnQgc3RhdGUgaXMgbm90IGFtb25nIHRoZSBzdGF0ZXMgIgotICAgICAgICAgICAgICAgICAgICAgKyBnZXRFdmVudFR5cGVTdHJpbmcoWE1MRXZlbnQuU1RBUlRfRUxFTUVOVCkgKyAiICwgIgotICAgICAgICAgICAgICAgICAgICAgKyBnZXRFdmVudFR5cGVTdHJpbmcoWE1MRXZlbnQuQVRUUklCVVRFKQotICAgICAgICAgICAgICAgICAgICAgKyAidmFsaWQgZm9yIGdldEF0dHJpYnV0ZVR5cGUoKSIpIDsKLSAgICAgICAgfQotCi0gICAgfS8vZ2V0QXR0cmlidXRlVHlwZQotCi0gICAgLyoqIFJldHVybnMgdGhlIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUgYXQgdGhlCi0gICAgICogaW5kZXgKLSAgICAgKiBAcGFyYW0gaW5kZXggdGhlIHBvc2l0aW9uIG9mIHRoZSBhdHRyaWJ1dGUKLSAgICAgKiBAcmV0dXJuIHRoZSBhdHRyaWJ1dGUgdmFsdWUKLSAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGlzIGlzIG5vdCBhIFNUQVJUX0VMRU1FTlQgb3IgQVRUUklCVVRFCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRBdHRyaWJ1dGVWYWx1ZShpbnQgaW5kZXgpIHsKLSAgICAgICAgLy9TdGF0ZSBzaG91bGQgYmUgZWl0aGVyIFNUQVJUX0VMRU1FTlQgb3IgQVRUUklCVVRFCi0gICAgICAgIGlmKCBmRXZlbnRUeXBlID09IFhNTEV2ZW50LlNUQVJUX0VMRU1FTlQgfHwgZkV2ZW50VHlwZSA9PSBYTUxFdmVudC5BVFRSSUJVVEUpIHsKLSAgICAgICAgICAgIHJldHVybiBmU2Nhbm5lci5nZXRBdHRyaWJ1dGVJdGVyYXRvcigpLmdldFZhbHVlKGluZGV4KSA7Ci0gICAgICAgIH0gZWxzZXsKLSAgICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJDdXJyZW50IHN0YXRlIGlzIG5vdCBhbW9uZyB0aGUgc3RhdGVzICIKLSAgICAgICAgICAgICAgICAgICAgICsgZ2V0RXZlbnRUeXBlU3RyaW5nKFhNTEV2ZW50LlNUQVJUX0VMRU1FTlQpICsgIiAsICIKLSAgICAgICAgICAgICAgICAgICAgICsgZ2V0RXZlbnRUeXBlU3RyaW5nKFhNTEV2ZW50LkFUVFJJQlVURSkKLSAgICAgICAgICAgICAgICAgICAgICsgInZhbGlkIGZvciBnZXRBdHRyaWJ1dGVWYWx1ZSgpIikgOwotICAgICAgICB9Ci0KLSAgICB9Ly9nZXRBdHRyaWJ1dGVWYWx1ZQotCi0gICAgLyoqCi0gICAgICogQHBhcmFtIG5hbWVzcGFjZVVSSQotICAgICAqIEBwYXJhbSBsb2NhbE5hbWUKLSAgICAgKiBAcmV0dXJuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRBdHRyaWJ1dGVWYWx1ZShTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgbG9jYWxOYW1lKSB7Ci0gICAgICAgIC8vU3RhdGUgc2hvdWxkIGJlIGVpdGhlciBTVEFSVF9FTEVNRU5UIG9yIEFUVFJJQlVURQotICAgICAgICBpZiggZkV2ZW50VHlwZSA9PSBYTUxFdmVudC5TVEFSVF9FTEVNRU5UIHx8IGZFdmVudFR5cGUgPT0gWE1MRXZlbnQuQVRUUklCVVRFKSB7Ci0gICAgICAgICAgICBYTUxBdHRyaWJ1dGVzSW1wbCBhdHRyaWJ1dGVzID0gZlNjYW5uZXIuZ2V0QXR0cmlidXRlSXRlcmF0b3IoKTsKLSAgICAgICAgICAgIGlmIChuYW1lc3BhY2VVUkkgPT0gbnVsbCkgeyAvL3Nqc3hwIGlzc3VlIDcwCi0gICAgICAgICAgICAgICAgcmV0dXJuIGF0dHJpYnV0ZXMuZ2V0VmFsdWUoYXR0cmlidXRlcy5nZXRJbmRleEJ5TG9jYWxOYW1lKGxvY2FsTmFtZSkpIDsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZTY2FubmVyLmdldEF0dHJpYnV0ZUl0ZXJhdG9yKCkuZ2V0VmFsdWUoCi0gICAgICAgICAgICAgICAgICAgICAgICBuYW1lc3BhY2VVUkkubGVuZ3RoKCkgPT0gMCA/IG51bGwgOiBuYW1lc3BhY2VVUkksIGxvY2FsTmFtZSkgOwotICAgICAgICAgICAgfQotCi0gICAgICAgIH0gZWxzZXsKLSAgICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJDdXJyZW50IHN0YXRlIGlzIG5vdCBhbW9uZyB0aGUgc3RhdGVzICIKLSAgICAgICAgICAgICAgICAgICAgICsgZ2V0RXZlbnRUeXBlU3RyaW5nKFhNTEV2ZW50LlNUQVJUX0VMRU1FTlQpICsgIiAsICIKLSAgICAgICAgICAgICAgICAgICAgICsgZ2V0RXZlbnRUeXBlU3RyaW5nKFhNTEV2ZW50LkFUVFJJQlVURSkKLSAgICAgICAgICAgICAgICAgICAgICsgInZhbGlkIGZvciBnZXRBdHRyaWJ1dGVWYWx1ZSgpIikgOwotICAgICAgICB9Ci0KLSAgICB9Ci0KLSAgICAvKiogUmVhZHMgdGhlIGNvbnRlbnQgb2YgYSB0ZXh0LW9ubHkgZWxlbWVudC4gUHJlY29uZGl0aW9uOgotICAgICAqIHRoZSBjdXJyZW50IGV2ZW50IGlzIFNUQVJUX0VMRU1FTlQuIFBvc3Rjb25kaXRpb246Ci0gICAgICogVGhlIGN1cnJlbnQgZXZlbnQgaXMgdGhlIGNvcnJlc3BvbmRpbmcgRU5EX0VMRU1FTlQuCi0gICAgICogQHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24gaWYgdGhlIGN1cnJlbnQgZXZlbnQgaXMgbm90IGEgU1RBUlRfRUxFTUVOVCBvciBpZgotICAgICAqIGEgbm9uIHRleHQgZWxlbWVudCBpcyBlbmNvdW50ZXJlZAotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0RWxlbWVudFRleHQoKSB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uIHsKLQotICAgICAgICBpZihnZXRFdmVudFR5cGUoKSAhPSBYTUxTdHJlYW1Db25zdGFudHMuU1RBUlRfRUxFTUVOVCkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFhNTFN0cmVhbUV4Y2VwdGlvbigKLSAgICAgICAgICAgICJwYXJzZXIgbXVzdCBiZSBvbiBTVEFSVF9FTEVNRU5UIHRvIHJlYWQgbmV4dCB0ZXh0IiwgZ2V0TG9jYXRpb24oKSk7Ci0gICAgICAgIH0KLSAgICAgICAgaW50IGV2ZW50VHlwZSA9IG5leHQoKTsKLSAgICAgICAgU3RyaW5nQnVmZmVyIGNvbnRlbnQgPSBuZXcgU3RyaW5nQnVmZmVyKCk7Ci0gICAgICAgIHdoaWxlKGV2ZW50VHlwZSAhPSBYTUxTdHJlYW1Db25zdGFudHMuRU5EX0VMRU1FTlQgKSB7Ci0gICAgICAgICAgICBpZihldmVudFR5cGUgPT0gWE1MU3RyZWFtQ29uc3RhbnRzLkNIQVJBQ1RFUlMKLSAgICAgICAgICAgIHx8IGV2ZW50VHlwZSA9PSBYTUxTdHJlYW1Db25zdGFudHMuQ0RBVEEKLSAgICAgICAgICAgIHx8IGV2ZW50VHlwZSA9PSBYTUxTdHJlYW1Db25zdGFudHMuU1BBQ0UKLSAgICAgICAgICAgIHx8IGV2ZW50VHlwZSA9PSBYTUxTdHJlYW1Db25zdGFudHMuRU5USVRZX1JFRkVSRU5DRSkgewotICAgICAgICAgICAgICAgIGNvbnRlbnQuYXBwZW5kKGdldFRleHQoKSk7Ci0gICAgICAgICAgICB9IGVsc2UgaWYoZXZlbnRUeXBlID09IFhNTFN0cmVhbUNvbnN0YW50cy5QUk9DRVNTSU5HX0lOU1RSVUNUSU9OCi0gICAgICAgICAgICB8fCBldmVudFR5cGUgPT0gWE1MU3RyZWFtQ29uc3RhbnRzLkNPTU1FTlQpIHsKLSAgICAgICAgICAgICAgICAvLyBza2lwcGluZwotICAgICAgICAgICAgfSBlbHNlIGlmKGV2ZW50VHlwZSA9PSBYTUxTdHJlYW1Db25zdGFudHMuRU5EX0RPQ1VNRU5UKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFhNTFN0cmVhbUV4Y2VwdGlvbigidW5leHBlY3RlZCBlbmQgb2YgZG9jdW1lbnQgd2hlbiByZWFkaW5nIGVsZW1lbnQgdGV4dCBjb250ZW50Iik7Ci0gICAgICAgICAgICB9IGVsc2UgaWYoZXZlbnRUeXBlID09IFhNTFN0cmVhbUNvbnN0YW50cy5TVEFSVF9FTEVNRU5UKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFhNTFN0cmVhbUV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAiZWxlbWVudEdldFRleHQoKSBmdW5jdGlvbiBleHBlY3RzIHRleHQgb25seSBlbG1lbnQgYnV0IFNUQVJUX0VMRU1FTlQgd2FzIGVuY291bnRlcmVkLiIsIGdldExvY2F0aW9uKCkpOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWE1MU3RyZWFtRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICJVbmV4cGVjdGVkIGV2ZW50IHR5cGUgIisgZXZlbnRUeXBlLCBnZXRMb2NhdGlvbigpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGV2ZW50VHlwZSA9IG5leHQoKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gY29udGVudC50b1N0cmluZygpOwotICAgIH0KLQotICAgIC8qKiBSZXR1cm4gdGhlIGN1cnJlbnQgbG9jYXRpb24gb2YgdGhlIHByb2Nlc3Nvci4KLSAgICAgKiBJZiB0aGUgTG9jYXRpb24gaXMgdW5rbm93biB0aGUgcHJvY2Vzc29yIHNob3VsZCByZXR1cm4KLSAgICAgKiBhbiBpbXBsZW1lbnRhdGlvbiBvZiBMb2NhdGlvbiB0aGF0IHJldHVybnMgLTEgZm9yIHRoZQotICAgICAqIGxvY2F0aW9uIGFuZCBudWxsIGZvciB0aGUgcHVibGljSWQgYW5kIHN5c3RlbUlkLgotICAgICAqIFRoZSBsb2NhdGlvbiBpbmZvcm1hdGlvbiBpcyBvbmx5IHZhbGlkIHVudGlsIG5leHQoKSBpcwotICAgICAqIGNhbGxlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgTG9jYXRpb24gZ2V0TG9jYXRpb24oKSB7Ci0gICAgICAgIHJldHVybiBuZXcgTG9jYXRpb24oKSB7Ci0gICAgICAgICAgICBTdHJpbmcgX3N5c3RlbUlkID0gZkVudGl0eVNjYW5uZXIuZ2V0RXhwYW5kZWRTeXN0ZW1JZCgpOwotICAgICAgICAgICAgU3RyaW5nIF9wdWJsaWNJZCA9IGZFbnRpdHlTY2FubmVyLmdldFB1YmxpY0lkKCk7Ci0gICAgICAgICAgICBpbnQgX29mZnNldCA9IGZFbnRpdHlTY2FubmVyLmdldENoYXJhY3Rlck9mZnNldCgpOwotICAgICAgICAgICAgaW50IF9jb2x1bW5OdW1iZXIgPSBmRW50aXR5U2Nhbm5lci5nZXRDb2x1bW5OdW1iZXIoKTsKLSAgICAgICAgICAgIGludCBfbGluZU51bWJlciA9IGZFbnRpdHlTY2FubmVyLmdldExpbmVOdW1iZXIoKTsKLSAgICAgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0TG9jYXRpb25VUkkoKXsKLSAgICAgICAgICAgICAgICByZXR1cm4gX3N5c3RlbUlkOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBwdWJsaWMgaW50IGdldENoYXJhY3Rlck9mZnNldCgpewotICAgICAgICAgICAgICAgIHJldHVybiBfb2Zmc2V0OwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBwdWJsaWMgaW50IGdldENvbHVtbk51bWJlcigpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gX2NvbHVtbk51bWJlcjsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgcHVibGljIGludCBnZXRMaW5lTnVtYmVyKCl7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIF9saW5lTnVtYmVyOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFB1YmxpY0lkKCl7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIF9wdWJsaWNJZDsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgcHVibGljIFN0cmluZyBnZXRTeXN0ZW1JZCgpewotICAgICAgICAgICAgICAgIHJldHVybiBfc3lzdGVtSWQ7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKXsKLSAgICAgICAgICAgICAgICBTdHJpbmdCdWZmZXIgc2J1ZmZlciA9IG5ldyBTdHJpbmdCdWZmZXIoKSA7Ci0gICAgICAgICAgICAgICAgc2J1ZmZlci5hcHBlbmQoIkxpbmUgbnVtYmVyID0gIiArIGdldExpbmVOdW1iZXIoKSk7Ci0gICAgICAgICAgICAgICAgc2J1ZmZlci5hcHBlbmQoIlxuIikgOwotICAgICAgICAgICAgICAgIHNidWZmZXIuYXBwZW5kKCJDb2x1bW4gbnVtYmVyID0gIiArIGdldENvbHVtbk51bWJlcigpKTsKLSAgICAgICAgICAgICAgICBzYnVmZmVyLmFwcGVuZCgiXG4iKSA7Ci0gICAgICAgICAgICAgICAgc2J1ZmZlci5hcHBlbmQoIlN5c3RlbSBJZCA9ICIgKyBnZXRTeXN0ZW1JZCgpKTsKLSAgICAgICAgICAgICAgICBzYnVmZmVyLmFwcGVuZCgiXG4iKSA7Ci0gICAgICAgICAgICAgICAgc2J1ZmZlci5hcHBlbmQoIlB1YmxpYyBJZCA9ICIgKyBnZXRQdWJsaWNJZCgpKTsKLSAgICAgICAgICAgICAgICBzYnVmZmVyLmFwcGVuZCgiXG4iKSA7Ci0gICAgICAgICAgICAgICAgc2J1ZmZlci5hcHBlbmQoIkxvY2F0aW9uIFVyaT0gIiArIGdldExvY2F0aW9uVVJJKCkpOwotICAgICAgICAgICAgICAgIHNidWZmZXIuYXBwZW5kKCJcbiIpIDsKLSAgICAgICAgICAgICAgICBzYnVmZmVyLmFwcGVuZCgiQ2hhcmFjdGVyT2Zmc2V0ID0gIiArIGdldENoYXJhY3Rlck9mZnNldCgpKTsKLSAgICAgICAgICAgICAgICBzYnVmZmVyLmFwcGVuZCgiXG4iKSA7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHNidWZmZXIudG9TdHJpbmcoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSA7Ci0KLSAgICB9Ci0KLSAgICAvKiogUmV0dXJucyBhIFFOYW1lIGZvciB0aGUgY3VycmVudCBTVEFSVF9FTEVNRU5UIG9yIEVORF9FTEVNRU5UIGV2ZW50Ci0gICAgICogQHJldHVybiB0aGUgUU5hbWUgZm9yIHRoZSBjdXJyZW50IFNUQVJUX0VMRU1FTlQgb3IgRU5EX0VMRU1FTlQgZXZlbnQKLSAgICAgKi8KLSAgICBwdWJsaWMgamF2YXgueG1sLm5hbWVzcGFjZS5RTmFtZSBnZXROYW1lKCkgewotICAgICAgICBpZihmRXZlbnRUeXBlID09IFhNTEV2ZW50LlNUQVJUX0VMRU1FTlQgfHwgZkV2ZW50VHlwZSA9PSBYTUxFdmVudC5FTkRfRUxFTUVOVCkKLSAgICAgICAgICAgIHJldHVybiBjb252ZXJ0WE5JUU5hbWV0b0phdmF4UU5hbWUoZlNjYW5uZXIuZ2V0RWxlbWVudFFOYW1lKCkpOwotICAgICAgICBlbHNlCi0gICAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiSWxsZWdhbCB0byBjYWxsIGdldE5hbWUoKSAiKwotICAgICAgICAgICAgIndoZW4gZXZlbnQgdHlwZSBpcyAiKyBnZXRFdmVudFR5cGVTdHJpbmcoZkV2ZW50VHlwZSkgKyAiLiIKLSAgICAgICAgICAgICAgICAgICAgICsgIiBWYWxpZCBzdGF0ZXMgYXJlICIgKyBnZXRFdmVudFR5cGVTdHJpbmcoWE1MRXZlbnQuU1RBUlRfRUxFTUVOVCkgKyAiLCAiCi0gICAgICAgICAgICAgICAgICAgICArIGdldEV2ZW50VHlwZVN0cmluZyhYTUxFdmVudC5FTkRfRUxFTUVOVCkpOwotICAgIH0KLQotICAgIC8qKiBSZXR1cm5zIGEgcmVhZCBvbmx5IG5hbWVzcGFjZSBjb250ZXh0IGZvciB0aGUgY3VycmVudAotICAgICAqIHBvc2l0aW9uLiAgVGhlIGNvbnRleHQgaXMgdHJhbnNpZW50IGFuZCBvbmx5IHZhbGlkIHVudGlsCi0gICAgICogYSBjYWxsIHRvIG5leHQoKSBjaGFuZ2VzIHRoZSBzdGF0ZSBvZiB0aGUgcmVhZGVyLgotICAgICAqIEByZXR1cm4gcmV0dXJuIGEgbmFtZXNwYWNlIGNvbnRleHQKLSAgICAgKi8KLSAgICBwdWJsaWMgTmFtZXNwYWNlQ29udGV4dCBnZXROYW1lc3BhY2VDb250ZXh0KCkgewotICAgICAgICByZXR1cm4gZk5hbWVzcGFjZUNvbnRleHRXcmFwcGVyIDsKLSAgICB9Ci0KLSAgICAvKiogUmV0dXJucyB0aGUgY291bnQgb2YgbmFtZXNwYWNlcyBkZWNsYXJlZCBvbiB0aGlzIFNUQVJUX0VMRU1FTlQgb3IgRU5EX0VMRU1FTlQsCi0gICAgICogdGhpcyBtZXRob2QgaXMgb25seSB2YWxpZCBvbiBhIFNUQVJUX0VMRU1FTlQsIEVORF9FTEVNRU5UIG9yIE5BTUVTUEFDRS4gT24KLSAgICAgKiBhbiBFTkRfRUxFTUVOVCB0aGUgY291bnQgaXMgb2YgdGhlIG5hbWVzcGFjZXMgdGhhdCBhcmUgYWJvdXQgdG8gZ28KLSAgICAgKiBvdXQgb2Ygc2NvcGUuICBUaGlzIGlzIHRoZSBlcXVpdmFsZW50IG9mIHRoZSBpbmZvcm1hdGlvbiByZXBvcnRlZAotICAgICAqIGJ5IFNBWCBjYWxsYmFjayBmb3IgYW4gZW5kIGVsZW1lbnQgZXZlbnQuCi0gICAgICogQHJldHVybiByZXR1cm5zIHRoZSBudW1iZXIgb2YgbmFtZXNwYWNlIGRlY2xhcmF0aW9ucyBvbiB0aGlzIHNwZWNpZmljIGVsZW1lbnQKLSAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGlzIGlzIG5vdCBhIFNUQVJUX0VMRU1FTlQsIEVORF9FTEVNRU5UIG9yIE5BTUVTUEFDRQotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0TmFtZXNwYWNlQ291bnQoKSB7Ci0gICAgICAgIC8vbmFtZXNwYWNlQ29udGV4dCBpcyBkeW5hbWljIG9iamVjdC4KLSAgICAgICAgLy9SRVZJU0lUOiBjaGVjayBpZiBpdCBzcGVjaWZpZXMgYWxsIGNvbmRpdGlvbnMgbWVudGlvbmVkIGluIHRoZSBqYXZhZG9jCi0gICAgICAgIGlmKGZFdmVudFR5cGUgPT0gWE1MRXZlbnQuU1RBUlRfRUxFTUVOVCB8fCBmRXZlbnRUeXBlID09IFhNTEV2ZW50LkVORF9FTEVNRU5UIHx8IGZFdmVudFR5cGUgPT0gWE1MRXZlbnQuTkFNRVNQQUNFKXsKLSAgICAgICAgICAgIHJldHVybiBmU2Nhbm5lci5nZXROYW1lc3BhY2VDb250ZXh0KCkuZ2V0RGVjbGFyZWRQcmVmaXhDb3VudCgpIDsKLSAgICAgICAgfSBlbHNlewotICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiQ3VycmVudCBldmVudCBzdGF0ZSBpcyAiICsgZ2V0RXZlbnRUeXBlU3RyaW5nKGZFdmVudFR5cGUpCi0gICAgICAgICAgICAgKyAiIGlzIG5vdCBhbW9uZyB0aGUgc3RhdGVzICIgKyBnZXRFdmVudFR5cGVTdHJpbmcoWE1MRXZlbnQuU1RBUlRfRUxFTUVOVCkKLSAgICAgICAgICAgICArICIsICIgKyBnZXRFdmVudFR5cGVTdHJpbmcoWE1MRXZlbnQuRU5EX0VMRU1FTlQpICsgIiwgIgotICAgICAgICAgICAgICAgICAgICAgKyBnZXRFdmVudFR5cGVTdHJpbmcoWE1MRXZlbnQuTkFNRVNQQUNFKQotICAgICAgICAgICAgICsgIiB2YWxpZCBmb3IgZ2V0TmFtZXNwYWNlQ291bnQoKS4iICk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKiogUmV0dXJucyB0aGUgcHJlZml4IGZvciB0aGUgbmFtZXNwYWNlIGRlY2xhcmVkIGF0IHRoZQotICAgICAqIGluZGV4LiAgUmV0dXJucyBudWxsIGlmIHRoaXMgaXMgdGhlIGRlZmF1bHQgbmFtZXNwYWNlCi0gICAgICogZGVjbGFyYXRpb24KLSAgICAgKgotICAgICAqIEBwYXJhbSBpbmRleCB0aGUgcG9zaXRpb24gb2YgdGhlIG5hbWVzcGFjZSBkZWNsYXJhdGlvbgotICAgICAqIEByZXR1cm4gcmV0dXJucyB0aGUgbmFtZXNwYWNlIHByZWZpeAotICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgaXMgbm90IGEgU1RBUlRfRUxFTUVOVCwgRU5EX0VMRU1FTlQgb3IgTkFNRVNQQUNFCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXROYW1lc3BhY2VQcmVmaXgoaW50IGluZGV4KSB7Ci0gICAgICAgIGlmKGZFdmVudFR5cGUgPT0gWE1MRXZlbnQuU1RBUlRfRUxFTUVOVCB8fCBmRXZlbnRUeXBlID09IFhNTEV2ZW50LkVORF9FTEVNRU5UIHx8IGZFdmVudFR5cGUgPT0gWE1MRXZlbnQuTkFNRVNQQUNFKXsKLSAgICAgICAgICAgIC8vbmFtZXNwYWNlQ29udGV4dCBpcyBkeW5hbWljIG9iamVjdC4KLSAgICAgICAgICAgIFN0cmluZyBwcmVmaXggPSBmU2Nhbm5lci5nZXROYW1lc3BhY2VDb250ZXh0KCkuZ2V0RGVjbGFyZWRQcmVmaXhBdChpbmRleCkgOwotICAgICAgICAgICAgcmV0dXJuIHByZWZpeC5lcXVhbHMoIiIpID8gbnVsbCA6IHByZWZpeCA7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZXsKLSAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oIkN1cnJlbnQgc3RhdGUgIiArIGdldEV2ZW50VHlwZVN0cmluZyhmRXZlbnRUeXBlKQotICAgICAgICAgICAgICsgIiBpcyBub3QgYW1vbmcgdGhlIHN0YXRlcyAiICsgZ2V0RXZlbnRUeXBlU3RyaW5nKFhNTEV2ZW50LlNUQVJUX0VMRU1FTlQpCi0gICAgICAgICAgICAgKyAiLCAiICsgZ2V0RXZlbnRUeXBlU3RyaW5nKFhNTEV2ZW50LkVORF9FTEVNRU5UKSArICIsICIKLSAgICAgICAgICAgICAgICAgICAgICsgZ2V0RXZlbnRUeXBlU3RyaW5nKFhNTEV2ZW50Lk5BTUVTUEFDRSkKLSAgICAgICAgICAgICArICIgdmFsaWQgZm9yIGdldE5hbWVzcGFjZVByZWZpeCgpLiIgKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKiBSZXR1cm5zIHRoZSB1cmkgZm9yIHRoZSBuYW1lc3BhY2UgZGVjbGFyZWQgYXQgdGhlCi0gICAgICogaW5kZXguCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaW5kZXggdGhlIHBvc2l0aW9uIG9mIHRoZSBuYW1lc3BhY2UgZGVjbGFyYXRpb24KLSAgICAgKiBAcmV0dXJuIHJldHVybnMgdGhlIG5hbWVzcGFjZSB1cmkKLSAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGlzIGlzIG5vdCBhIFNUQVJUX0VMRU1FTlQsIEVORF9FTEVNRU5UIG9yIE5BTUVTUEFDRQotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZXNwYWNlVVJJKGludCBpbmRleCkgewotICAgICAgICBpZihmRXZlbnRUeXBlID09IFhNTEV2ZW50LlNUQVJUX0VMRU1FTlQgfHwgZkV2ZW50VHlwZSA9PSBYTUxFdmVudC5FTkRfRUxFTUVOVCB8fCBmRXZlbnRUeXBlID09IFhNTEV2ZW50Lk5BTUVTUEFDRSl7Ci0gICAgICAgICAgICAvL25hbWVzcGFjZUNvbnRleHQgaXMgZHluYW1pYyBvYmplY3QuCi0gICAgICAgICAgICByZXR1cm4gZlNjYW5uZXIuZ2V0TmFtZXNwYWNlQ29udGV4dCgpLmdldFVSSShmU2Nhbm5lci5nZXROYW1lc3BhY2VDb250ZXh0KCkuZ2V0RGVjbGFyZWRQcmVmaXhBdChpbmRleCkpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2V7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJDdXJyZW50IHN0YXRlICIgKyBnZXRFdmVudFR5cGVTdHJpbmcoZkV2ZW50VHlwZSkKLSAgICAgICAgICAgICArICIgaXMgbm90IGFtb25nIHRoZSBzdGF0ZXMgIiArIGdldEV2ZW50VHlwZVN0cmluZyhYTUxFdmVudC5TVEFSVF9FTEVNRU5UKQotICAgICAgICAgICAgICsgIiwgIiArIGdldEV2ZW50VHlwZVN0cmluZyhYTUxFdmVudC5FTkRfRUxFTUVOVCkgKyAiLCAiCi0gICAgICAgICAgICAgICAgICAgICArIGdldEV2ZW50VHlwZVN0cmluZyhYTUxFdmVudC5OQU1FU1BBQ0UpCi0gICAgICAgICAgICAgKyAiIHZhbGlkIGZvciBnZXROYW1lc3BhY2VVUkkoKS4iICk7Ci0gICAgICAgIH0KLQotICAgIH0KLQotICAgIC8qKiBHZXQgdGhlIHZhbHVlIG9mIGEgZmVhdHVyZS9wcm9wZXJ0eSBmcm9tIHRoZSB1bmRlcmx5aW5nIGltcGxlbWVudGF0aW9uCi0gICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIHByb3BlcnR5LCBtYXkgbm90IGJlIG51bGwKLSAgICAgKiBAcmV0dXJuIFRoZSB2YWx1ZSBvZiB0aGUgcHJvcGVydHkKLSAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiBuYW1lIGlzIG51bGwKLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0IGdldFByb3BlcnR5KGphdmEubGFuZy5TdHJpbmcgbmFtZSkgdGhyb3dzIGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gewotICAgICAgICBpZihuYW1lID09IG51bGwpIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCkgOwotICAgICAgICBpZiAoZlByb3BlcnR5TWFuYWdlciAhPSBudWxsICl7Ci0gICAgICAgICAgICBpZihuYW1lLmVxdWFscyhmUHJvcGVydHlNYW5hZ2VyLlNUQVhfTk9UQVRJT05TKSl7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGdldE5vdGF0aW9uRGVjbHMoKTsKLSAgICAgICAgICAgIH1lbHNlIGlmKG5hbWUuZXF1YWxzKGZQcm9wZXJ0eU1hbmFnZXIuU1RBWF9FTlRJVElFUykpewotICAgICAgICAgICAgICAgIHJldHVybiBnZXRFbnRpdHlEZWNscygpOwotICAgICAgICAgICAgfWVsc2UKLSAgICAgICAgICAgICAgICByZXR1cm4gZlByb3BlcnR5TWFuYWdlci5nZXRQcm9wZXJ0eShuYW1lKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICAvKiogUmV0dXJucyB0aGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgcGFyc2UgZXZlbnQgYXMgYSBzdHJpbmcsCi0gICAgICogdGhpcyByZXR1cm5zIHRoZSBzdHJpbmcgdmFsdWUgb2YgYSBDSEFSQUNURVJTIGV2ZW50LAotICAgICAqIHJldHVybnMgdGhlIHZhbHVlIG9mIGEgQ09NTUVOVCwgdGhlIHJlcGxhY2VtZW50IHZhbHVlCi0gICAgICogZm9yIGFuIEVOVElUWV9SRUZFUkVOQ0UsCi0gICAgICogb3IgdGhlIFN0cmluZyB2YWx1ZSBvZiB0aGUgRFRECi0gICAgICogQHJldHVybiB0aGUgY3VycmVudCB0ZXh0IG9yIG51bGwKLSAgICAgKiBAdGhyb3dzIGphdmEubGFuZy5JbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBzdGF0ZSBpcyBub3QKLSAgICAgKiBhIHZhbGlkIHRleHQgc3RhdGUuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRUZXh0KCkgewotICAgICAgICBpZiggZkV2ZW50VHlwZSA9PSBYTUxFdmVudC5DSEFSQUNURVJTIHx8IGZFdmVudFR5cGUgPT0gWE1MRXZlbnQuQ09NTUVOVAotICAgICAgICAgICAgICAgIHx8IGZFdmVudFR5cGUgPT0gWE1MRXZlbnQuQ0RBVEEgfHwgZkV2ZW50VHlwZSA9PSBYTUxFdmVudC5TUEFDRSl7Ci0gICAgICAgICAgICAvL3RoaXMgcmVxdWlyZXMgY3JlYXRpb24gb2YgbmV3IHN0cmluZwotICAgICAgICAgICAgLy9mRXZlbnRUeXBlID09IFhNTEV2ZW50LkVOVElUWV9SRUZFUkVOQ0UKLSAgICAgICAgICAgIHJldHVybiBmU2Nhbm5lci5nZXRDaGFyYWN0ZXJEYXRhKCkudG9TdHJpbmcoKSA7Ci0gICAgICAgIH0gZWxzZSBpZihmRXZlbnRUeXBlID09IFhNTEV2ZW50LkVOVElUWV9SRUZFUkVOQ0UpewotICAgICAgICAgICAgU3RyaW5nIG5hbWUgPSBmU2Nhbm5lci5nZXRFbnRpdHlOYW1lKCk7Ci0gICAgICAgICAgICBpZihuYW1lICE9IG51bGwpewotICAgICAgICAgICAgICAgIGlmKGZTY2FubmVyLmZvdW5kQnVpbHRJblJlZnMpCi0gICAgICAgICAgICAgICAgICAgIHJldHVybiBmU2Nhbm5lci5nZXRDaGFyYWN0ZXJEYXRhKCkudG9TdHJpbmcoKTsKLQotICAgICAgICAgICAgICAgIFhNTEVudGl0eVN0b3JhZ2UgZW50aXR5U3RvcmUgPSBmRW50aXR5TWFuYWdlci5nZXRFbnRpdHlTdG9yZSgpOwotICAgICAgICAgICAgICAgIEVudGl0eSBlbiA9IGVudGl0eVN0b3JlLmdldEVudGl0eShuYW1lKTsKLSAgICAgICAgICAgICAgICBpZihlbiA9PSBudWxsKQotICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgICAgICAgICBpZihlbi5pc0V4dGVybmFsKCkpCi0gICAgICAgICAgICAgICAgICAgIHJldHVybiAoKEVudGl0eS5FeHRlcm5hbEVudGl0eSllbikuZW50aXR5TG9jYXRpb24uZ2V0RXhwYW5kZWRTeXN0ZW1JZCgpOwotICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuICgoRW50aXR5LkludGVybmFsRW50aXR5KWVuKS50ZXh0OwotICAgICAgICAgICAgfWVsc2UKLSAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmKGZFdmVudFR5cGUgPT0gWE1MRXZlbnQuRFREKXsKLSAgICAgICAgICAgICAgICBpZihmRFRERGVjbCAhPSBudWxsKXsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZEVEREZWNsOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBYTUxTdHJpbmdCdWZmZXIgdG1wQnVmZmVyID0gZlNjYW5uZXIuZ2V0RFRERGVjbCgpOwotICAgICAgICAgICAgICAgIGZEVEREZWNsID0gdG1wQnVmZmVyLnRvU3RyaW5nKCk7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZEVEREZWNsOwotICAgICAgICB9IGVsc2V7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiQ3VycmVudCBzdGF0ZSAiICsgZ2V0RXZlbnRUeXBlU3RyaW5nKGZFdmVudFR5cGUpCi0gICAgICAgICAgICAgICAgICAgICArICIgaXMgbm90IGFtb25nIHRoZSBzdGF0ZXMiICsgZ2V0RXZlbnRUeXBlU3RyaW5nKFhNTEV2ZW50LkNIQVJBQ1RFUlMpICsgIiwgIgotICAgICAgICAgICAgICAgICAgICAgKyBnZXRFdmVudFR5cGVTdHJpbmcoWE1MRXZlbnQuQ09NTUVOVCkgKyAiLCAiCi0gICAgICAgICAgICAgICAgICAgICArIGdldEV2ZW50VHlwZVN0cmluZyhYTUxFdmVudC5DREFUQSkgKyAiLCAiCi0gICAgICAgICAgICAgICAgICAgICArIGdldEV2ZW50VHlwZVN0cmluZyhYTUxFdmVudC5TUEFDRSkgKyAiLCAiCi0gICAgICAgICAgICAgICAgICAgICArIGdldEV2ZW50VHlwZVN0cmluZyhYTUxFdmVudC5FTlRJVFlfUkVGRVJFTkNFKSArICIsICIKLSAgICAgICAgICAgICAgICAgICAgICsgZ2V0RXZlbnRUeXBlU3RyaW5nKFhNTEV2ZW50LkRURCkgKyAiIHZhbGlkIGZvciBnZXRUZXh0KCkgIiApIDsKLSAgICAgICAgfQotICAgIH0vL2dldFRleHQKLQotCi0gICAgLyoqIFRlc3QgaWYgdGhlIGN1cnJlbnQgZXZlbnQgaXMgb2YgdGhlIGdpdmVuIHR5cGUgYW5kIGlmIHRoZSBuYW1lc3BhY2UgYW5kIG5hbWUgbWF0Y2ggdGhlIGN1cnJlbnQgbmFtZXNwYWNlIGFuZCBuYW1lIG9mIHRoZSBjdXJyZW50IGV2ZW50LgotICAgICAqIElmIHRoZSBuYW1lc3BhY2VVUkkgaXMgbnVsbCBpdCBpcyBub3QgY2hlY2tlZCBmb3IgZXF1YWxpdHksIGlmIHRoZSBsb2NhbE5hbWUgaXMgbnVsbCBpdCBpcyBub3QgY2hlY2tlZCBmb3IgZXF1YWxpdHkuCi0gICAgICogQHBhcmFtIHR5cGUgdGhlIGV2ZW50IHR5cGUKLSAgICAgKiBAcGFyYW0gbmFtZXNwYWNlVVJJIHRoZSB1cmkgb2YgdGhlIGV2ZW50LCBtYXkgYmUgbnVsbAotICAgICAqIEBwYXJhbSBsb2NhbE5hbWUgdGhlIGxvY2FsTmFtZSBvZiB0aGUgZXZlbnQsIG1heSBiZSBudWxsCi0gICAgICogQHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24gaWYgdGhlIHJlcXVpcmVkIHZhbHVlcyBhcmUgbm90IG1hdGNoZWQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcmVxdWlyZShpbnQgdHlwZSwgU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIGxvY2FsTmFtZSkgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmKCB0eXBlICE9IGZFdmVudFR5cGUpCi0gICAgICAgICAgICAgdGhyb3cgbmV3IFhNTFN0cmVhbUV4Y2VwdGlvbigiRXZlbnQgdHlwZSAiICsgZ2V0RXZlbnRUeXBlU3RyaW5nKHR5cGUpICsgIiBzcGVjaWZpZWQgZGlkICIgKwotICAgICAgICAgICAgICAgICAgICAgIm5vdCBtYXRjaCB3aXRoIGN1cnJlbnQgcGFyc2VyIGV2ZW50ICIgKyBnZXRFdmVudFR5cGVTdHJpbmcoZkV2ZW50VHlwZSkpOwotICAgICAgICAgIGlmKCBuYW1lc3BhY2VVUkkgIT0gbnVsbCAmJiAhbmFtZXNwYWNlVVJJLmVxdWFscyhnZXROYW1lc3BhY2VVUkkoKSkgKQotICAgICAgICAgICAgIHRocm93IG5ldyBYTUxTdHJlYW1FeGNlcHRpb24oIk5hbWVzcGFjZSBVUkkgIiArIG5hbWVzcGFjZVVSSSArIiBzcGVjaWZpZWQgZGlkIG5vdCBtYXRjaCAiICsKLSAgICAgICAgICAgICAgICAgICAgICJ3aXRoIGN1cnJlbnQgbmFtZXNwYWNlIFVSSSIpOwotICAgICAgICAgIGlmKGxvY2FsTmFtZSAhPSBudWxsICYmICFsb2NhbE5hbWUuZXF1YWxzKGdldExvY2FsTmFtZSgpKSkKLSAgICAgICAgICAgICB0aHJvdyBuZXcgWE1MU3RyZWFtRXhjZXB0aW9uKCJMb2NhbE5hbWUgIiArIGxvY2FsTmFtZSArIiBzcGVjaWZpZWQgZGlkIG5vdCBtYXRjaCB3aXRoICIgKwotICAgICAgICAgICAgICAgICAgICAgImN1cnJlbnQgbG9jYWwgbmFtZSIpOwotICAgICAgICByZXR1cm47Ci0gICAgfQotCi0gICAgLyoqIEdldHMgdGhlIHRoZSB0ZXh0IGFzc29jaWF0ZWQgd2l0aCBhIENIQVJBQ1RFUlMsIFNQQUNFIG9yIENEQVRBIGV2ZW50LgotICAgICAqIFRleHQgc3RhcnRpbmcgYSAic291cmNlU3RhcnQiIGlzIGNvcGllZCBpbnRvICJkZXN0aW5hdGlvbiIgc3RhcnRpbmcgYXQgInRhcmdldFN0YXJ0Ii4KLSAgICAgKiBVcCB0byAibGVuZ3RoIiBjaGFyYWN0ZXJzIGFyZSBjb3BpZWQuICBUaGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgYWN0dWFsbHkgY29waWVkIGlzIHJldHVybmVkLgotICAgICAqCi0gICAgICogVGhlICJzb3VyY2VTdGFydCIgYXJndW1lbnQgbXVzdCBiZSBncmVhdGVyIG9yIGVxdWFsIHRvIDAgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0bwotICAgICAqIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyBhc3NvY2lhdGVkIHdpdGggdGhlIGV2ZW50LiAgVXN1YWxseSwgb25lIHJlcXVlc3RzIHRleHQgc3RhcnRpbmcgYXQgYSAic291cmNlU3RhcnQiIG9mIDAuCi0gICAgICogSWYgdGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIGFjdHVhbGx5IGNvcGllZCBpcyBsZXNzIHRoYW4gdGhlICJsZW5ndGgiLCB0aGVuIHRoZXJlIGlzIG5vIG1vcmUgdGV4dC4KLSAgICAgKiBPdGhlcndpc2UsIHN1YnNlcXVlbnQgY2FsbHMgbmVlZCB0byBiZSBtYWRlIHVudGlsIGFsbCB0ZXh0IGhhcyBiZWVuIHJldHJpZXZlZC4gRm9yIGV4YW1wbGU6Ci0gICAgICoKLSAgICAgKiA8Y29kZT4KLSAgICAgKiBpbnQgbGVuZ3RoID0gMTAyNDsKLSAgICAgKiBjaGFyW10gbXlCdWZmZXIgPSBuZXcgY2hhclsgbGVuZ3RoIF07Ci0gICAgICoKLSAgICAgKiBmb3IgKCBpbnQgc291cmNlU3RhcnQgPSAwIDsgOyBzb3VyY2VTdGFydCArPSBsZW5ndGggKQotICAgICAqIHsKLSAgICAgKiAgICBpbnQgbkNvcGllZCA9IHN0cmVhbS5nZXRUZXh0Q2hhcmFjdGVycyggc291cmNlU3RhcnQsIG15QnVmZmVyLCAwLCBsZW5ndGggKTsKLSAgICAgKgotICAgICAqICAgaWYgKG5Db3BpZWQgPCBsZW5ndGgpCi0gICAgICogICAgICAgYnJlYWs7Ci0gICAgICogfQotICAgICAqIDwvY29kZT4KLSAgICAgKiBYTUxTdHJlYW1FeGNlcHRpb24gbWF5IGJlIHRocm93biBpZiB0aGVyZSBhcmUgYW55IFhNTCBlcnJvcnMgaW4gdGhlIHVuZGVybHlpbmcgc291cmNlLgotICAgICAqIFRoZSAidGFyZ2V0U3RhcnQiIGFyZ3VtZW50IG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIDAgYW5kIGxlc3MgdGhhbiB0aGUgbGVuZ3RoIG9mICJ0YXJnZXQiLAotICAgICAqIExlbmd0aCBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAwIGFuZCAidGFyZ2V0U3RhcnQgKyBsZW5ndGgiIG11c3QgYmUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIGxlbmd0aCBvZiAidGFyZ2V0Ii4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzb3VyY2VTdGFydCB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IGNoYXJhY3RlciBpbiB0aGUgc291cmNlIGFycmF5IHRvIGNvcHkKLSAgICAgKiBAcGFyYW0gdGFyZ2V0IHRoZSBkZXN0aW5hdGlvbiBhcnJheQotICAgICAqIEBwYXJhbSB0YXJnZXRTdGFydCB0aGUgc3RhcnQgb2Zmc2V0IGluIHRoZSB0YXJnZXQgYXJyYXkKLSAgICAgKiBAcGFyYW0gbGVuZ3RoIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyB0byBjb3B5Ci0gICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgYWN0dWFsbHkgY29waWVkCi0gICAgICogQHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24gaWYgdGhlIHVuZGVybHlpbmcgWE1MIHNvdXJjZSBpcyBub3Qgd2VsbC1mb3JtZWQKLSAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaWYgdGFyZ2V0U3RhcnQgPCAwIG9yID4gdGhhbiB0aGUgbGVuZ3RoIG9mIHRhcmdldAotICAgICAqIEB0aHJvd3MgSW5kZXhPdXRPZkJvdW5kd2hpbGUoaXNDaGFyYWN0ZXJzKCkpIDtzRXhjZXB0aW9uIGlmIGxlbmd0aCA8IDAgb3IgdGFyZ2V0U3RhcnQgKyBsZW5ndGggPiBsZW5ndGggb2YgdGFyZ2V0Ci0gICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBpZiB0aGlzIG1ldGhvZCBpcyBub3Qgc3VwcG9ydGVkCi0gICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpcyBpZiB0YXJnZXQgaXMgbnVsbAotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0VGV4dENoYXJhY3RlcnMoaW50IHNvdXJjZVN0YXJ0LCBjaGFyW10gdGFyZ2V0LCBpbnQgdGFyZ2V0U3RhcnQsIGludCBsZW5ndGgpIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24gewotCi0gICAgICAgIGlmKHRhcmdldCA9PSBudWxsKXsKLSAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigidGFyZ2V0IGNoYXIgYXJyYXkgY2FuJ3QgYmUgbnVsbCIpIDsKLSAgICAgICAgfQotCi0gICAgICAgIGlmKHRhcmdldFN0YXJ0IDwgMCB8fCBsZW5ndGggPCAwIHx8IHNvdXJjZVN0YXJ0IDwgMCB8fCB0YXJnZXRTdGFydCA+PSB0YXJnZXQubGVuZ3RoIHx8Ci0gICAgICAgICAgICAodGFyZ2V0U3RhcnQgKyBsZW5ndGggKSA+IHRhcmdldC5sZW5ndGgpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvL2dldFRleHRTdGFydCgpICsgc291cmNlU3RhcnQgc2hvdWxkIG5vdCBiZSBncmVhdGVyIHRoYW4gdGhlIGxlbmdodCBvZiBudW1iZXIgb2YgY2hhcmFjdGVycwotICAgICAgICAvL3ByZXNlbnQKLSAgICAgICAgaW50IGNvcGllZExlbmd0aCA9IDA7Ci0gICAgICAgIC8vaW50IHByZXNlbnREYXRhTGVuID0gZ2V0VGV4dExlbmd0aCgpIC0gKGdldFRleHRTdGFydCgpK3NvdXJjZVN0YXJ0KTsKLSAgICAgICAgaW50IGF2YWlsYWJsZSA9IGdldFRleHRMZW5ndGgoKSAtIHNvdXJjZVN0YXJ0OwotICAgICAgICBpZihhdmFpbGFibGUgPCAwKXsKLSAgICAgICAgICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCJzb3VyY2VTdGFydCBpcyBncmVhdGVyIHRoYW4iICsKLSAgICAgICAgICAgICAgICAibnVtYmVyIG9mIGNoYXJhY3RlcnMgYXNzb2NpYXRlZCB3aXRoIHRoaXMgZXZlbnQiKTsKLSAgICAgICAgfQotICAgICAgICBpZihhdmFpbGFibGUgPCBsZW5ndGgpewotICAgICAgICAgICAgY29waWVkTGVuZ3RoID0gYXZhaWxhYmxlOwotICAgICAgICB9IGVsc2V7Ci0gICAgICAgICAgICBjb3BpZWRMZW5ndGggPSBsZW5ndGg7Ci0gICAgICAgIH0KLQotICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGdldFRleHRDaGFyYWN0ZXJzKCksIGdldFRleHRTdGFydCgpICsgc291cmNlU3RhcnQgLCB0YXJnZXQsIHRhcmdldFN0YXJ0LCBjb3BpZWRMZW5ndGgpOwotICAgICAgICByZXR1cm4gY29waWVkTGVuZ3RoOwotICAgIH0KLQotICAgIC8qKiBSZXR1cm4gdHJ1ZSBpZiB0aGUgY3VycmVudCBldmVudCBoYXMgdGV4dCwgZmFsc2Ugb3RoZXJ3aXNlCi0gICAgICogVGhlIGZvbGxvd2luZyBldmVudHMgaGF2ZSB0ZXh0OgotICAgICAqIENIQVJBQ1RFUlMsRFREICxFTlRJVFlfUkVGRVJFTkNFLCBDT01NRU5UCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaGFzVGV4dCgpIHsKLSAgICAgICAgaWYoREVCVUcpIHByKCJYTUxSZWFkZXJJbXBsI0VWRU5UIFRZUEUgPSAiICsgZkV2ZW50VHlwZSApIDsKLSAgICAgICAgaWYoIGZFdmVudFR5cGUgPT0gWE1MRXZlbnQuQ0hBUkFDVEVSUyB8fCBmRXZlbnRUeXBlID09IFhNTEV2ZW50LkNPTU1FTlQgfHwgZkV2ZW50VHlwZSA9PSBYTUxFdmVudC5DREFUQSkgewotICAgICAgICAgICAgcmV0dXJuIGZTY2FubmVyLmdldENoYXJhY3RlckRhdGEoKS5sZW5ndGggPiAwOwotICAgICAgICB9IGVsc2UgaWYoZkV2ZW50VHlwZSA9PSBYTUxFdmVudC5FTlRJVFlfUkVGRVJFTkNFKSB7Ci0gICAgICAgICAgICBTdHJpbmcgbmFtZSA9IGZTY2FubmVyLmdldEVudGl0eU5hbWUoKTsKLSAgICAgICAgICAgIGlmKG5hbWUgIT0gbnVsbCl7Ci0gICAgICAgICAgICAgICAgaWYoZlNjYW5uZXIuZm91bmRCdWlsdEluUmVmcykKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0KLSAgICAgICAgICAgICAgICBYTUxFbnRpdHlTdG9yYWdlIGVudGl0eVN0b3JlID0gZkVudGl0eU1hbmFnZXIuZ2V0RW50aXR5U3RvcmUoKTsKLSAgICAgICAgICAgICAgICBFbnRpdHkgZW4gPSBlbnRpdHlTdG9yZS5nZXRFbnRpdHkobmFtZSk7Ci0gICAgICAgICAgICAgICAgaWYoZW4gPT0gbnVsbCkKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgICAgIGlmKGVuLmlzRXh0ZXJuYWwoKSl7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiAoKEVudGl0eS5FeHRlcm5hbEVudGl0eSllbikuZW50aXR5TG9jYXRpb24uZ2V0RXhwYW5kZWRTeXN0ZW1JZCgpICE9IG51bGw7Ci0gICAgICAgICAgICAgICAgfSBlbHNlewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gKChFbnRpdHkuSW50ZXJuYWxFbnRpdHkpZW4pLnRleHQgIT0gbnVsbCA7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfWVsc2UKLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBpZihmRXZlbnRUeXBlID09IFhNTEV2ZW50LkRURCkKLSAgICAgICAgICAgICAgICByZXR1cm4gZlNjYW5uZXIuZlNlZW5Eb2N0eXBlRGVjbDsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgLyoqIFJldHVybnMgYSBib29sZWFuIHdoaWNoIGluZGljYXRlcyBpZiB0aGlzCi0gICAgICogYXR0cmlidXRlIHdhcyBjcmVhdGVkIGJ5IGRlZmF1bHQKLSAgICAgKiBAcGFyYW0gaW5kZXggdGhlIHBvc2l0aW9uIG9mIHRoZSBhdHRyaWJ1dGUKLSAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhpcyBpcyBhIGRlZmF1bHQgYXR0cmlidXRlCi0gICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBpcyBub3QgYSBTVEFSVF9FTEVNRU5UIG9yIEFUVFJJQlVURQotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzQXR0cmlidXRlU3BlY2lmaWVkKGludCBpbmRleCkgewotICAgICAgICAvL2NoZWNrIHRoYXQgY3VycmVudCBzdGF0ZSBzaG91bGQgYmUgZWl0aGVyIFNUQVJUX0VMRU1FTlQgb3IgQVRUUklCVVRFCi0gICAgICAgIGlmKCAoZkV2ZW50VHlwZSA9PSBYTUxFdmVudC5TVEFSVF9FTEVNRU5UKSB8fCAoZkV2ZW50VHlwZSA9PSBYTUxFdmVudC5BVFRSSUJVVEUpKXsKLSAgICAgICAgICAgIHJldHVybiBmU2Nhbm5lci5nZXRBdHRyaWJ1dGVJdGVyYXRvcigpLmlzU3BlY2lmaWVkKGluZGV4KSA7Ci0gICAgICAgIH0gZWxzZXsKLSAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oIkN1cnJlbnQgc3RhdGUgaXMgbm90IGFtb25nIHRoZSBzdGF0ZXMgIgotICAgICAgICAgICAgICAgICAgICAgKyBnZXRFdmVudFR5cGVTdHJpbmcoWE1MRXZlbnQuU1RBUlRfRUxFTUVOVCkgKyAiICwgIgotICAgICAgICAgICAgICAgICAgICAgKyBnZXRFdmVudFR5cGVTdHJpbmcoWE1MRXZlbnQuQVRUUklCVVRFKQotICAgICAgICAgICAgICAgICAgICAgKyAidmFsaWQgZm9yIGlzQXR0cmlidXRlU3BlY2lmaWVkKCkiKSAgOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqIFJldHVybnMgdHJ1ZSBpZiB0aGUgY3Vyc29yIHBvaW50cyB0byBhIGNoYXJhY3RlciBkYXRhIGV2ZW50Ci0gICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBjdXJzb3IgcG9pbnRzIHRvIGNoYXJhY3RlciBkYXRhLCBmYWxzZSBvdGhlcndpc2UKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0NoYXJhY3RlcnMoKSB7Ci0gICAgICAgIHJldHVybiBmRXZlbnRUeXBlID09IFhNTEV2ZW50LkNIQVJBQ1RFUlMgOwotICAgIH0KLQotICAgIC8qKiBTa2lwcyBhbnkgaW5zaWduaWZpY2FudCBldmVudHMgKENPTU1FTlQgYW5kIFBST0NFU1NJTkdfSU5TVFJVQ1RJT04pCi0gICAgICogdW50aWwgYSBTVEFSVF9FTEVNRU5UIG9yCi0gICAgICogRU5EX0VMRU1FTlQgaXMgcmVhY2hlZC4gSWYgb3RoZXIgdGhhbiBzcGFjZSBjaGFyYWN0ZXJzIGFyZQotICAgICAqIGVuY291bnRlcmVkLCBhbiBleGNlcHRpb24gaXMgdGhyb3duLiBUaGlzIG1ldGhvZCBzaG91bGQKLSAgICAgKiBiZSB1c2VkIHdoZW4gcHJvY2Vzc2luZyBlbGVtZW50LW9ubHkgY29udGVudCBiZWNhdXNlCi0gICAgICogdGhlIHBhcnNlciBpcyBub3QgYWJsZSB0byByZWNvZ25pemUgaWdub3JhYmxlIHdoaXRlc3BhY2UgaWYKLSAgICAgKiB0aGVuIERURCBpcyBtaXNzaW5nIG9yIG5vdCBpbnRlcnByZXRlZC4KLSAgICAgKiBAcmV0dXJuIHRoZSBldmVudCB0eXBlIG9mIHRoZSBlbGVtZW50IHJlYWQKLSAgICAgKiBAdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbiBpZiB0aGUgY3VycmVudCBldmVudCBpcyBub3Qgd2hpdGUgc3BhY2UKLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IG5leHRUYWcoKSB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uIHsKLQotICAgICAgICBpbnQgZXZlbnRUeXBlID0gbmV4dCgpOwotICAgICAgICB3aGlsZSgoZXZlbnRUeXBlID09IFhNTFN0cmVhbUNvbnN0YW50cy5DSEFSQUNURVJTICYmIGlzV2hpdGVTcGFjZSgpKSAvLyBza2lwIHdoaXRlc3BhY2UKLSAgICAgICAgfHwgKGV2ZW50VHlwZSA9PSBYTUxTdHJlYW1Db25zdGFudHMuQ0RBVEEgJiYgaXNXaGl0ZVNwYWNlKCkpCi0gICAgICAgIC8vIHNraXAgd2hpdGVzcGFjZQotICAgICAgICB8fCBldmVudFR5cGUgPT0gWE1MU3RyZWFtQ29uc3RhbnRzLlNQQUNFCi0gICAgICAgIHx8IGV2ZW50VHlwZSA9PSBYTUxTdHJlYW1Db25zdGFudHMuUFJPQ0VTU0lOR19JTlNUUlVDVElPTgotICAgICAgICB8fCBldmVudFR5cGUgPT0gWE1MU3RyZWFtQ29uc3RhbnRzLkNPTU1FTlQKLSAgICAgICAgKSB7Ci0gICAgICAgICAgICBldmVudFR5cGUgPSBuZXh0KCk7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoZXZlbnRUeXBlICE9IFhNTFN0cmVhbUNvbnN0YW50cy5TVEFSVF9FTEVNRU5UICYmIGV2ZW50VHlwZSAhPSBYTUxTdHJlYW1Db25zdGFudHMuRU5EX0VMRU1FTlQpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBYTUxTdHJlYW1FeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgICJmb3VuZDogIiArIGdldEV2ZW50VHlwZVN0cmluZyhldmVudFR5cGUpCi0gICAgICAgICAgICAgICAgICAgICsgIiwgZXhwZWN0ZWQgIiArIGdldEV2ZW50VHlwZVN0cmluZyhYTUxTdHJlYW1Db25zdGFudHMuU1RBUlRfRUxFTUVOVCkKLSAgICAgICAgICAgICAgICAgICAgKyAiIG9yICIgKyBnZXRFdmVudFR5cGVTdHJpbmcoWE1MU3RyZWFtQ29uc3RhbnRzLkVORF9FTEVNRU5UKSwKLSAgICAgICAgICAgICAgICAgICAgZ2V0TG9jYXRpb24oKSk7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gZXZlbnRUeXBlOwotICAgIH0KLQotICAgIC8qKiBDaGVja3MgaWYgc3RhbmRhbG9uZSB3YXMgc2V0IGluIHRoZSBkb2N1bWVudAotICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBzdGFuZGFsb25lIHdhcyBzZXQgaW4gdGhlIGRvY3VtZW50LCBvciBmYWxzZSBvdGhlcndpc2UKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBzdGFuZGFsb25lU2V0KCkgewotICAgICAgICAvL3h4eDogaXQgcmVxdWlyZXMgaWYgdGhlIHN0YW5kYWxvbmUgd2FzIHNldCBpbiB0aGUgZG9jdW1lbnQgPyBUaGlzIGlzIGRpZmZlcmVudCB0aGF0IGlmIHRoZSBkb2N1bWVudAotICAgICAgICAvLyBpcyBzdGFuZGFsb25lCi0gICAgICAgIHJldHVybiBmU2Nhbm5lci5zdGFuZGFsb25lU2V0KCkgOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBwYXJhbSBxbmFtZQotICAgICAqIEByZXR1cm4KLSAgICAgKi8KLSAgICBwdWJsaWMgamF2YXgueG1sLm5hbWVzcGFjZS5RTmFtZSBjb252ZXJ0WE5JUU5hbWV0b0phdmF4UU5hbWUoY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuUU5hbWUgcW5hbWUpewotICAgICAgICBpZiAocW5hbWUgPT0gbnVsbCkgcmV0dXJuIG51bGw7Ci0gICAgICAgIC8veHh4OiBwcmVmaXggZGVmaW5pdGlvbiA/Ci0gICAgICAgIGlmKHFuYW1lLnByZWZpeCA9PSBudWxsKXsKLSAgICAgICAgICAgIHJldHVybiBuZXcgamF2YXgueG1sLm5hbWVzcGFjZS5RTmFtZShxbmFtZS51cmksIHFuYW1lLmxvY2FscGFydCkgOwotICAgICAgICB9IGVsc2V7Ci0gICAgICAgICAgICByZXR1cm4gbmV3IGphdmF4LnhtbC5uYW1lc3BhY2UuUU5hbWUocW5hbWUudXJpLCBxbmFtZS5sb2NhbHBhcnQsIHFuYW1lLnByZWZpeCkgOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqIFJldHVybiB0aGUgdXJpIGZvciB0aGUgZ2l2ZW4gcHJlZml4LgotICAgICAqIFRoZSB1cmkgcmV0dXJuZWQgZGVwZW5kcyBvbiB0aGUgY3VycmVudCBzdGF0ZSBvZiB0aGUgcHJvY2Vzc29yLgotICAgICAqCi0gICAgICogPHA+PHN0cm9uZz5OT1RFOjwvc3Ryb25nPlRoZSAneG1sJyBwcmVmaXggaXMgYm91bmQgYXMgZGVmaW5lZCBpbgotICAgICAqIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy14bWwtbmFtZXMvI25zLXVzaW5nIj5OYW1lc3BhY2VzIGluIFhNTDwvYT4KLSAgICAgKiBzcGVjaWZpY2F0aW9uIHRvICJodHRwOi8vd3d3LnczLm9yZy9YTUwvMTk5OC9uYW1lc3BhY2UiLgotICAgICAqCi0gICAgICogPHA+PHN0cm9uZz5OT1RFOjwvc3Ryb25nPiBUaGUgJ3htbG5zJyBwcmVmaXggbXVzdCBiZSByZXNvbHZlZCB0byBmb2xsb3dpbmcgbmFtZXNwYWNlCi0gICAgICogPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvMjAwMC94bWxucy8iPmh0dHA6Ly93d3cudzMub3JnLzIwMDAveG1sbnMvPC9hPgotICAgICAqIEByZXR1cm4gdGhlIHVyaSBib3VuZCB0byB0aGUgZ2l2ZW4gcHJlZml4IG9yIG51bGwgaWYgaXQgaXMgbm90IGJvdW5kCi0gICAgICogQHBhcmFtIHByZWZpeCBUaGUgcHJlZml4IHRvIGxvb2t1cCwgbWF5IG5vdCBiZSBudWxsCi0gICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gLSBpZiB0aGUgcHJlZml4IGlzIG51bGwKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWVzcGFjZVVSSShTdHJpbmcgcHJlZml4KSB7Ci0gICAgICAgIGlmKHByZWZpeCA9PSBudWxsKSB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigicHJlZml4IGNhbm5vdCBiZSBudWxsLiIpIDsKLQotICAgICAgICAvL2ZpcnN0IGFkZCB0aGUgc3RyaW5nIHRvIHN5bWJvbCB0YWJsZS4uIHNpbmNlIGludGVybmFsbHkgaWRlbnRpdHkgY29tcGFyaXNvbnMgYXJlIGRvbmUuCi0gICAgICAgIHJldHVybiBmU2Nhbm5lci5nZXROYW1lc3BhY2VDb250ZXh0KCkuZ2V0VVJJKGZTeW1ib2xUYWJsZS5hZGRTeW1ib2wocHJlZml4KSkgOwotICAgIH0KLQotICAgIC8veHh4OiB0aGlzIGZ1bmN0aW9uIGlzIG5vdCBiZWluZyB1c2VkLgotICAgIHByb3RlY3RlZCB2b2lkIHNldFByb3BlcnR5TWFuYWdlcihQcm9wZXJ0eU1hbmFnZXIgcHJvcGVydHlNYW5hZ2VyKXsKLSAgICAgICAgZlByb3BlcnR5TWFuYWdlciA9IHByb3BlcnR5TWFuYWdlciA7Ci0gICAgICAgIC8vUkVWSVNJVDogd2Ugd2VyZSBzdXBwbHlpbmcgaGFzaG1hcCBlYWxpZXIKLSAgICAgICAgZlNjYW5uZXIuc2V0UHJvcGVydHkoInN0YXgtcHJvcGVydGllcyIscHJvcGVydHlNYW5hZ2VyKTsKLSAgICAgICAgZlNjYW5uZXIuc2V0UHJvcGVydHlNYW5hZ2VyKHByb3BlcnR5TWFuYWdlcikgOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEByZXR1cm4gcmV0dXJucyB0aGUgcmVmZXJlbmNlIHRvIHByb3BlcnR5IG1hbmFnZXIuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIFByb3BlcnR5TWFuYWdlciBnZXRQcm9wZXJ0eU1hbmFnZXIoKXsKLSAgICAgICAgcmV0dXJuIGZQcm9wZXJ0eU1hbmFnZXIgOwotICAgIH0KLQotICAgIHN0YXRpYyB2b2lkIHByKFN0cmluZyBzdHIpIHsKLSAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKHN0cikgOwotICAgIH0KLQotICAgIHByb3RlY3RlZCBMaXN0IGdldEVudGl0eURlY2xzKCl7Ci0gICAgICAgIGlmKGZFdmVudFR5cGUgPT0gWE1MU3RyZWFtQ29uc3RhbnRzLkRURCl7Ci0gICAgICAgICAgICBYTUxFbnRpdHlTdG9yYWdlIGVudGl0eVN0b3JlID0gZkVudGl0eU1hbmFnZXIuZ2V0RW50aXR5U3RvcmUoKTsKLSAgICAgICAgICAgIEFycmF5TGlzdCBsaXN0ID0gbnVsbDsKLSAgICAgICAgICAgIGlmKGVudGl0eVN0b3JlLmhhc0VudGl0aWVzKCkpewotICAgICAgICAgICAgICAgIEVudGl0eURlY2xhcmF0aW9uSW1wbCBkZWNsID0gbnVsbDsKLSAgICAgICAgICAgICAgICBsaXN0ID0gbmV3IEFycmF5TGlzdChlbnRpdHlTdG9yZS5nZXRFbnRpdHlTaXplKCkpOwotICAgICAgICAgICAgICAgIEVudW1lcmF0aW9uIGVudSA9IGVudGl0eVN0b3JlLmdldEVudGl0eUtleXMoKTsKLSAgICAgICAgICAgICAgICB3aGlsZShlbnUuaGFzTW9yZUVsZW1lbnRzKCkpewotICAgICAgICAgICAgICAgICAgICBTdHJpbmcga2V5ID0gKFN0cmluZyllbnUubmV4dEVsZW1lbnQoKTsKLSAgICAgICAgICAgICAgICAgICAgRW50aXR5IGVuID0gKEVudGl0eSllbnRpdHlTdG9yZS5nZXRFbnRpdHkoa2V5KTsKLSAgICAgICAgICAgICAgICAgICAgZGVjbCA9IG5ldyBFbnRpdHlEZWNsYXJhdGlvbkltcGwoKTsKLSAgICAgICAgICAgICAgICAgICAgZGVjbC5zZXRFbnRpdHlOYW1lKGtleSk7Ci0gICAgICAgICAgICAgICAgICAgIGlmKGVuLmlzRXh0ZXJuYWwoKSl7Ci0gICAgICAgICAgICAgICAgICAgICAgICBkZWNsLnNldFhNTFJlc291cmNlSWRlbnRpZmllcigoKEVudGl0eS5FeHRlcm5hbEVudGl0eSllbikuZW50aXR5TG9jYXRpb24pOwotICAgICAgICAgICAgICAgICAgICAgICAgZGVjbC5zZXROb3RhdGlvbk5hbWUoKChFbnRpdHkuRXh0ZXJuYWxFbnRpdHkpZW4pLm5vdGF0aW9uKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgICAgICBkZWNsLnNldEVudGl0eVJlcGxhY2VtZW50VGV4dCgoKEVudGl0eS5JbnRlcm5hbEVudGl0eSllbikudGV4dCk7Ci0gICAgICAgICAgICAgICAgICAgIGxpc3QuYWRkKGRlY2wpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiBsaXN0OwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIHByb3RlY3RlZCBMaXN0IGdldE5vdGF0aW9uRGVjbHMoKXsKLSAgICAgICAgaWYoZkV2ZW50VHlwZSA9PSBYTUxTdHJlYW1Db25zdGFudHMuRFREKXsKLSAgICAgICAgICAgIGlmKGZTY2FubmVyLmZEVERTY2FubmVyID09IG51bGwpIHJldHVybiBudWxsOwotICAgICAgICAgICAgRFRER3JhbW1hciBncmFtbWFyID0gKChYTUxEVERTY2FubmVySW1wbCkoZlNjYW5uZXIuZkRURFNjYW5uZXIpKS5nZXRHcmFtbWFyKCk7Ci0gICAgICAgICAgICBpZihncmFtbWFyID09IG51bGwpIHJldHVybiBudWxsOwotICAgICAgICAgICAgTGlzdCBub3RhdGlvbnMgPSBncmFtbWFyLmdldE5vdGF0aW9uRGVjbHMoKTsKLQotICAgICAgICAgICAgSXRlcmF0b3IgaXQgPSBub3RhdGlvbnMuaXRlcmF0b3IoKTsKLSAgICAgICAgICAgIEFycmF5TGlzdCBsaXN0ID0gbmV3IEFycmF5TGlzdCgpOwotICAgICAgICAgICAgd2hpbGUoaXQuaGFzTmV4dCgpKXsKLSAgICAgICAgICAgICAgICBYTUxOb3RhdGlvbkRlY2wgbmkgPSAoWE1MTm90YXRpb25EZWNsKWl0Lm5leHQoKTsKLSAgICAgICAgICAgICAgICBpZihuaSE9IG51bGwpewotICAgICAgICAgICAgICAgICAgICBsaXN0LmFkZChuZXcgTm90YXRpb25EZWNsYXJhdGlvbkltcGwobmkpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gbGlzdDsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLQotCi19Ly9YTUxSZWFkZXJJbXBsCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL1hNTFZlcnNpb25EZXRlY3Rvci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9YTUxWZXJzaW9uRGV0ZWN0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYTdhYjAyNy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL1hNTFZlcnNpb25EZXRlY3Rvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjM4ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMTYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKi8KLS8qCi0gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKLSAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAotICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgotICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKLSAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCi0gKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGw7Ci0KLWltcG9ydCBqYXZhLmlvLkVPRkV4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLm1zZy5YTUxNZXNzYWdlRm9ybWF0dGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5TeW1ib2xUYWJsZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxTdHJpbmc7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTENvbXBvbmVudE1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTElucHV0U291cmNlOwotaW1wb3J0IGNvbS5zdW4ueG1sLmludGVybmFsLnN0cmVhbS5FbnRpdHkuU2Nhbm5lZEVudGl0eTsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIHNjYW5zIHRoZSB2ZXJzaW9uIG9mIHRoZSBkb2N1bWVudCB0byBkZXRlcm1pbmUKLSAqIHdoaWNoIHNjYW5uZXIgdG8gdXNlOiBYTUwgMS4xIG9yIFhNTCAxLjAuCi0gKiBUaGUgdmVyc2lvbiBpcyBzY2FubmVkIHVzaW5nIFhNTCAxLjEuIHNjYW5uZXIuCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgTmVpbCBHcmFoYW0sIElCTQotICogQGF1dGhvciBFbGVuYSBMaXRhbmksIElCTQotICovCi1wdWJsaWMgY2xhc3MgWE1MVmVyc2lvbkRldGVjdG9yIHsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RhbnRzCi0gICAgLy8KLQotICAgIHByaXZhdGUgZmluYWwgc3RhdGljIGNoYXJbXSBYTUwxMV9WRVJTSU9OID0gbmV3IGNoYXJbXXsnMScsICcuJywgJzEnfTsKLQotCi0gICAgLy8gcHJvcGVydHkgaWRlbnRpZmllcnMKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBzeW1ib2wgdGFibGUuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1lNQk9MX1RBQkxFID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuU1lNQk9MX1RBQkxFX1BST1BFUlRZOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IGVycm9yIHJlcG9ydGVyLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUk9SX1JFUE9SVEVSID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuRVJST1JfUkVQT1JURVJfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogZW50aXR5IG1hbmFnZXIuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgRU5USVRZX01BTkFHRVIgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5FTlRJVFlfTUFOQUdFUl9QUk9QRVJUWTsKLQotICAgIC8vCi0gICAgLy8gRGF0YQotICAgIC8vCi0KLSAgICAvKiogU3ltYm9sOiAidmVyc2lvbiIuICovCi0gICAgcHJvdGVjdGVkIGZpbmFsIHN0YXRpYyBTdHJpbmcgZlZlcnNpb25TeW1ib2wgPSAidmVyc2lvbiIuaW50ZXJuKCk7Ci0KLSAgICAvLyBzeW1ib2w6ICBbeG1sXToKLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBmWE1MU3ltYm9sID0gIlt4bWxdIi5pbnRlcm4oKTsKLQotICAgIC8qKiBTeW1ib2wgdGFibGUuICovCi0gICAgcHJvdGVjdGVkIFN5bWJvbFRhYmxlIGZTeW1ib2xUYWJsZTsKLQotICAgIC8qKiBFcnJvciByZXBvcnRlci4gKi8KLSAgICBwcm90ZWN0ZWQgWE1MRXJyb3JSZXBvcnRlciBmRXJyb3JSZXBvcnRlcjsKLQotICAgIC8qKiBFbnRpdHkgbWFuYWdlci4gKi8KLSAgICBwcm90ZWN0ZWQgWE1MRW50aXR5TWFuYWdlciBmRW50aXR5TWFuYWdlcjsKLQotICAgIHByb3RlY3RlZCBTdHJpbmcgZkVuY29kaW5nID0gbnVsbDsKLQotICAgIHByaXZhdGUgWE1MU3RyaW5nIGZWZXJzaW9uTnVtID0gbmV3IFhNTFN0cmluZygpOwotCi0gICAgcHJpdmF0ZSBmaW5hbCBjaGFyIFtdIGZFeHBlY3RlZFZlcnNpb25TdHJpbmcgPSB7JzwnLCAnPycsICd4JywgJ20nLCAnbCcsICcgJywgJ3YnLCAnZScsICdyJywgJ3MnLAotICAgICAgICAgICAgICAgICAgICAnaScsICdvJywgJ24nLCAnPScsICcgJywgJyAnLCAnICcsICcgJywgJyAnfTsKLQotICAgIC8qKgotICAgICAqCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29tcG9uZW50TWFuYWdlciBUaGUgY29tcG9uZW50IG1hbmFnZXIuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBUaHJvd3MgZXhjZXB0aW9uIGlmIHJlcXVpcmVkIGZlYXR1cmVzIGFuZAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIHByb3BlcnRpZXMgY2Fubm90IGJlIGZvdW5kLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHJlc2V0KFhNTENvbXBvbmVudE1hbmFnZXIgY29tcG9uZW50TWFuYWdlcikKLSAgICAgICAgdGhyb3dzIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gewotCi0gICAgICAgIC8vIFhlcmNlcyBwcm9wZXJ0aWVzCi0gICAgICAgIGZTeW1ib2xUYWJsZSA9IChTeW1ib2xUYWJsZSljb21wb25lbnRNYW5hZ2VyLmdldFByb3BlcnR5KFNZTUJPTF9UQUJMRSk7Ci0gICAgICAgIGZFcnJvclJlcG9ydGVyID0gKFhNTEVycm9yUmVwb3J0ZXIpY29tcG9uZW50TWFuYWdlci5nZXRQcm9wZXJ0eShFUlJPUl9SRVBPUlRFUik7Ci0gICAgICAgIGZFbnRpdHlNYW5hZ2VyID0gKFhNTEVudGl0eU1hbmFnZXIpY29tcG9uZW50TWFuYWdlci5nZXRQcm9wZXJ0eShFTlRJVFlfTUFOQUdFUik7Ci0gICAgICAgIGZvcihpbnQgaT0xNDsgaTxmRXhwZWN0ZWRWZXJzaW9uU3RyaW5nLmxlbmd0aDsgaSsrICkKLSAgICAgICAgICAgIGZFeHBlY3RlZFZlcnNpb25TdHJpbmdbaV0gPSAnICc7Ci0gICAgfSAvLyByZXNldChYTUxDb21wb25lbnRNYW5hZ2VyKQotCi0gICAgLyoqCi0gICAgICogUmVzZXQgdGhlIHJlZmVyZW5jZSB0byB0aGUgYXBwcm9wcmlhdGUgc2Nhbm5lciBnaXZlbiB0aGUgdmVyc2lvbiBvZiB0aGUKLSAgICAgKiBkb2N1bWVudCBhbmQgc3RhcnQgZG9jdW1lbnQgc2Nhbm5pbmcuCi0gICAgICogQHBhcmFtIHNjYW5uZXIgLSB0aGUgc2Nhbm5lciB0byB1c2UKLSAgICAgKiBAcGFyYW0gdmVyc2lvbiAtIHRoZSB2ZXJzaW9uIG9mIHRoZSBkb2N1bWVudCAoWE1MIDEuMSBvciBYTUwgMS4wKS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydERvY3VtZW50UGFyc2luZyhYTUxFbnRpdHlIYW5kbGVyIHNjYW5uZXIsIHNob3J0IHZlcnNpb24pewotCi0gICAgICAgIGlmICh2ZXJzaW9uID09IENvbnN0YW50cy5YTUxfVkVSU0lPTl8xXzApewotICAgICAgICAgICAgZkVudGl0eU1hbmFnZXIuc2V0U2Nhbm5lclZlcnNpb24oQ29uc3RhbnRzLlhNTF9WRVJTSU9OXzFfMCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBmRW50aXR5TWFuYWdlci5zZXRTY2FubmVyVmVyc2lvbihDb25zdGFudHMuWE1MX1ZFUlNJT05fMV8xKTsKLSAgICAgICAgfQotICAgICAgICAvLyBNYWtlIHN1cmUgdGhlIGxvY2F0b3IgdXNlZCBieSB0aGUgZXJyb3IgcmVwb3J0ZXIgaXMgdGhlIGN1cnJlbnQgZW50aXR5IHNjYW5uZXIuCi0gICAgICAgIGZFcnJvclJlcG9ydGVyLnNldERvY3VtZW50TG9jYXRvcihmRW50aXR5TWFuYWdlci5nZXRFbnRpdHlTY2FubmVyKCkpOwotCi0gICAgICAgIC8vIE5vdGU6IGFib3ZlIHdlIHJlc2V0IGZFbnRpdHlTY2FubmVyIGluIHRoZSBlbnRpdHkgbWFuYWdlciwgdGh1cyBpbiBzdGFydEVudGl0eQotICAgICAgICAvLyBpbiBlYWNoIHNjYW5uZXIgZkVudGl0eVNjYW5uZXIgZmllbGQgbXVzdCBiZSByZXNldCB0byByZWZsZWN0IHRoZSBjaGFuZ2UuCi0gICAgICAgIC8vCi0gICAgICAgIGZFbnRpdHlNYW5hZ2VyLnNldEVudGl0eUhhbmRsZXIoc2Nhbm5lcik7Ci0KLSAgICAgICAgc2Nhbm5lci5zdGFydEVudGl0eShmWE1MU3ltYm9sLCBmRW50aXR5TWFuYWdlci5nZXRDdXJyZW50UmVzb3VyY2VJZGVudGlmaWVyKCksIGZFbmNvZGluZywgbnVsbCk7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZHMgc2NhbnMgdGhlIFhNTCBkZWNsYXJhdGlvbiB0byBmaW5kIG91dCB0aGUgdmVyc2lvbgotICAgICAqIChhbmQgcHJvdmlzaW9uYWwgZW5jb2RpbmcpICBvZiB0aGUgZG9jdW1lbnQuCi0gICAgICogVGhlIHNjYW5uaW5nIGlzIGRvaW5nIHVzaW5nIFhNTCAxLjEgc2Nhbm5lci4KLSAgICAgKiBAcGFyYW0gaW5wdXRTb3VyY2UKLSAgICAgKiBAcmV0dXJuIHNob3J0IC0gQ29uc3RhbnRzLlhNTF9WRVJTSU9OXzFfMSBpZiBkb2N1bWVudCB2ZXJzaW9uIDEuMSwKLSAgICAgKiAgICAgICAgICAgICAgICAgIG90aGVyd2lzZSBDb25zdGFudHMuWE1MX1ZFUlNJT05fMV8wCi0gICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgotICAgICAqLwotICAgIHB1YmxpYyBzaG9ydCBkZXRlcm1pbmVEb2NWZXJzaW9uKFhNTElucHV0U291cmNlIGlucHV0U291cmNlKSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgICAgICBmRW5jb2RpbmcgPSBmRW50aXR5TWFuYWdlci5zZXR1cEN1cnJlbnRFbnRpdHkoZmFsc2UsIGZYTUxTeW1ib2wsIGlucHV0U291cmNlLCBmYWxzZSwgdHJ1ZSk7Ci0KLSAgICAgICAgLy8gTXVzdCB1c2UgWE1MIDEuMCBzY2FubmVyIHRvIGhhbmRsZSB3aGl0ZXNwYWNlIGNvcnJlY3RseQotICAgICAgICAvLyBpbiB0aGUgWE1MIGRlY2xhcmF0aW9uLgotICAgICAgICBmRW50aXR5TWFuYWdlci5zZXRTY2FubmVyVmVyc2lvbihDb25zdGFudHMuWE1MX1ZFUlNJT05fMV8wKTsKLSAgICAgICAgWE1MRW50aXR5U2Nhbm5lciBzY2FubmVyID0gZkVudGl0eU1hbmFnZXIuZ2V0RW50aXR5U2Nhbm5lcigpOwotICAgICAgICBzY2FubmVyLmRldGVjdGluZ1ZlcnNpb24gPSB0cnVlOwotICAgICAgICB0cnkgewotICAgICAgICAgICAgaWYgKCFzY2FubmVyLnNraXBTdHJpbmcoIjw/eG1sIikpIHsKLSAgICAgICAgICAgICAgICAvLyBkZWZpbml0ZWx5IG5vdCBhIHdlbGwtZm9ybWVkIDEuMSBkb2MhCi0gICAgICAgICAgICAgICAgc2Nhbm5lci5kZXRlY3RpbmdWZXJzaW9uID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIENvbnN0YW50cy5YTUxfVkVSU0lPTl8xXzA7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoIXNjYW5uZXIuc2tpcERlY2xTcGFjZXMoKSkgewotICAgICAgICAgICAgICAgIGZpeHVwQ3VycmVudEVudGl0eShmRW50aXR5TWFuYWdlciwgZkV4cGVjdGVkVmVyc2lvblN0cmluZywgNSk7Ci0gICAgICAgICAgICAgICAgc2Nhbm5lci5kZXRlY3RpbmdWZXJzaW9uID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIENvbnN0YW50cy5YTUxfVkVSU0lPTl8xXzA7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoIXNjYW5uZXIuc2tpcFN0cmluZygidmVyc2lvbiIpKSB7Ci0gICAgICAgICAgICAgICAgZml4dXBDdXJyZW50RW50aXR5KGZFbnRpdHlNYW5hZ2VyLCBmRXhwZWN0ZWRWZXJzaW9uU3RyaW5nLCA2KTsKLSAgICAgICAgICAgICAgICBzY2FubmVyLmRldGVjdGluZ1ZlcnNpb24gPSBmYWxzZTsKLSAgICAgICAgICAgICAgICByZXR1cm4gQ29uc3RhbnRzLlhNTF9WRVJTSU9OXzFfMDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHNjYW5uZXIuc2tpcERlY2xTcGFjZXMoKTsKLSAgICAgICAgICAgIC8vIENoZWNrIGlmIHRoZSBuZXh0IGNoYXJhY3RlciBpcyAnPScuIElmIGl0IGlzIHRoZW4gY29uc3VtZSBpdC4KLSAgICAgICAgICAgIGlmIChzY2FubmVyLnBlZWtDaGFyKCkgIT0gJz0nKSB7Ci0gICAgICAgICAgICAgICAgZml4dXBDdXJyZW50RW50aXR5KGZFbnRpdHlNYW5hZ2VyLCBmRXhwZWN0ZWRWZXJzaW9uU3RyaW5nLCAxMyk7Ci0gICAgICAgICAgICAgICAgc2Nhbm5lci5kZXRlY3RpbmdWZXJzaW9uID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIENvbnN0YW50cy5YTUxfVkVSU0lPTl8xXzA7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBzY2FubmVyLnNjYW5DaGFyKG51bGwpOwotICAgICAgICAgICAgc2Nhbm5lci5za2lwRGVjbFNwYWNlcygpOwotICAgICAgICAgICAgaW50IHF1b3RlQ2hhciA9IHNjYW5uZXIuc2NhbkNoYXIobnVsbCk7Ci0gICAgICAgICAgICBmRXhwZWN0ZWRWZXJzaW9uU3RyaW5nWzE0XSA9IChjaGFyKSBxdW90ZUNoYXI7Ci0gICAgICAgICAgICBmb3IgKGludCB2ZXJzaW9uUG9zID0gMDsgdmVyc2lvblBvcyA8IFhNTDExX1ZFUlNJT04ubGVuZ3RoOyB2ZXJzaW9uUG9zKyspIHsKLSAgICAgICAgICAgICAgICBmRXhwZWN0ZWRWZXJzaW9uU3RyaW5nWzE1ICsgdmVyc2lvblBvc10gPSAoY2hhcikgc2Nhbm5lci5zY2FuQ2hhcihudWxsKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIFJFVklTSVQ6ICBzaG91bGQgd2UgY2hlY2sgd2hldGhlciB0aGlzIGVxdWFscyBxdW90ZUNoYXI/Ci0gICAgICAgICAgICBmRXhwZWN0ZWRWZXJzaW9uU3RyaW5nWzE4XSA9IChjaGFyKSBzY2FubmVyLnNjYW5DaGFyKG51bGwpOwotICAgICAgICAgICAgZml4dXBDdXJyZW50RW50aXR5KGZFbnRpdHlNYW5hZ2VyLCBmRXhwZWN0ZWRWZXJzaW9uU3RyaW5nLCAxOSk7Ci0gICAgICAgICAgICBpbnQgbWF0Y2hlZCA9IDA7Ci0gICAgICAgICAgICBmb3IgKDsgbWF0Y2hlZCA8IFhNTDExX1ZFUlNJT04ubGVuZ3RoOyBtYXRjaGVkKyspIHsKLSAgICAgICAgICAgICAgICBpZiAoZkV4cGVjdGVkVmVyc2lvblN0cmluZ1sxNSArIG1hdGNoZWRdICE9IFhNTDExX1ZFUlNJT05bbWF0Y2hlZF0pCi0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgc2Nhbm5lci5kZXRlY3RpbmdWZXJzaW9uID0gZmFsc2U7Ci0gICAgICAgICAgICBpZiAobWF0Y2hlZCA9PSBYTUwxMV9WRVJTSU9OLmxlbmd0aCkKLSAgICAgICAgICAgICAgICByZXR1cm4gQ29uc3RhbnRzLlhNTF9WRVJTSU9OXzFfMTsKLSAgICAgICAgICAgIHJldHVybiBDb25zdGFudHMuWE1MX1ZFUlNJT05fMV8wOwotICAgICAgICAgICAgLy8gcHJlbWF0dXJlIGVuZCBvZiBmaWxlCi0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKEVPRkV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICBmRXJyb3JSZXBvcnRlci5yZXBvcnRFcnJvcigKLSAgICAgICAgICAgICAgICBYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sCi0gICAgICAgICAgICAgICAgIlByZW1hdHVyZUVPRiIsCi0gICAgICAgICAgICAgICAgbnVsbCwKLSAgICAgICAgICAgICAgICBYTUxFcnJvclJlcG9ydGVyLlNFVkVSSVRZX0ZBVEFMX0VSUk9SKTsKLSAgICAgICAgICAgIHNjYW5uZXIuZGV0ZWN0aW5nVmVyc2lvbiA9IGZhbHNlOwotICAgICAgICAgICAgcmV0dXJuIENvbnN0YW50cy5YTUxfVkVSU0lPTl8xXzA7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvLyBUaGlzIG1ldGhvZCBwcmVwZW5kcyAibGVuZ3RoIiBjaGFycyBmcm9tIHRoZSBjaGFyIGFycmF5LAotICAgIC8vIGZyb20gb2Zmc2V0IDAsIHRvIHRoZSBtYW5hZ2VyJ3MgZkN1cnJlbnRFbnRpdHkuY2guCi0gICAgcHJpdmF0ZSB2b2lkIGZpeHVwQ3VycmVudEVudGl0eShYTUxFbnRpdHlNYW5hZ2VyIG1hbmFnZXIsCi0gICAgICAgICAgICAgICAgY2hhciBbXSBzY2FubmVkQ2hhcnMsIGludCBsZW5ndGgpIHsKLSAgICAgICAgU2Nhbm5lZEVudGl0eSBjdXJyZW50RW50aXR5ID0gbWFuYWdlci5nZXRDdXJyZW50RW50aXR5KCk7Ci0gICAgICAgIGlmKGN1cnJlbnRFbnRpdHkuY291bnQtY3VycmVudEVudGl0eS5wb3NpdGlvbitsZW5ndGggPiBjdXJyZW50RW50aXR5LmNoLmxlbmd0aCkgewotICAgICAgICAgICAgLy9yZXNpemUgYXJyYXk7IHRoaXMgY2FzZSBpcyBoYXJkIHRvIGltYWdpbmUuLi4KLSAgICAgICAgICAgIGNoYXJbXSB0ZW1wQ2ggPSBjdXJyZW50RW50aXR5LmNoOwotICAgICAgICAgICAgY3VycmVudEVudGl0eS5jaCA9IG5ldyBjaGFyW2xlbmd0aCtjdXJyZW50RW50aXR5LmNvdW50LWN1cnJlbnRFbnRpdHkucG9zaXRpb24rMV07Ci0gICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHRlbXBDaCwgMCwgY3VycmVudEVudGl0eS5jaCwgMCwgdGVtcENoLmxlbmd0aCk7Ci0gICAgICAgIH0KLSAgICAgICAgaWYoY3VycmVudEVudGl0eS5wb3NpdGlvbiA8IGxlbmd0aCkgewotICAgICAgICAgICAgLy8gaGF2ZSB0byBtb3ZlIHNlbnNpdGl2ZSBzdHVmZiBvdXQgb2YgdGhlIHdheS4uLgotICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShjdXJyZW50RW50aXR5LmNoLCBjdXJyZW50RW50aXR5LnBvc2l0aW9uLCBjdXJyZW50RW50aXR5LmNoLCBsZW5ndGgsIGN1cnJlbnRFbnRpdHkuY291bnQtY3VycmVudEVudGl0eS5wb3NpdGlvbik7Ci0gICAgICAgICAgICBjdXJyZW50RW50aXR5LmNvdW50ICs9IGxlbmd0aC1jdXJyZW50RW50aXR5LnBvc2l0aW9uOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgLy8gaGF2ZSB0byByZWludHJvZHVjZSBzb21lIHdoaXRlc3BhY2Ugc28gdGhpcyBwYXJzZXM6Ci0gICAgICAgICAgICBmb3IoaW50IGk9bGVuZ3RoOyBpPGN1cnJlbnRFbnRpdHkucG9zaXRpb247IGkrKykKLSAgICAgICAgICAgICAgICBjdXJyZW50RW50aXR5LmNoW2ldPScgJzsKLSAgICAgICAgfQotICAgICAgICAvLyBwcmVwZW5kIGNvbnRlbnRzLi4uCi0gICAgICAgIFN5c3RlbS5hcnJheWNvcHkoc2Nhbm5lZENoYXJzLCAwLCBjdXJyZW50RW50aXR5LmNoLCAwLCBsZW5ndGgpOwotICAgICAgICBjdXJyZW50RW50aXR5LnBvc2l0aW9uID0gMDsKLSAgICAgICAgY3VycmVudEVudGl0eS5iYXNlQ2hhck9mZnNldCA9IDA7Ci0gICAgICAgIGN1cnJlbnRFbnRpdHkuc3RhcnRQb3NpdGlvbiA9IDA7Ci0gICAgICAgIGN1cnJlbnRFbnRpdHkuY29sdW1uTnVtYmVyID0gY3VycmVudEVudGl0eS5saW5lTnVtYmVyID0gMTsKLSAgICB9Ci0KLX0gLy8gY2xhc3MgWE1MVmVyc2lvbkRldGVjdG9yCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R0ZC9CYWxhbmNlZERUREdyYW1tYXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHRkL0JhbGFuY2VkRFRER3JhbW1hci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwYjA5ZTM0Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHRkL0JhbGFuY2VkRFRER3JhbW1hci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjg4ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCi0gKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKLSAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KLSAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCi0gKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAotICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR0ZDsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5TeW1ib2xUYWJsZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5BdWdtZW50YXRpb25zOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTERURENvbnRlbnRNb2RlbEhhbmRsZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE5JRXhjZXB0aW9uOwotCi0vKioKLSAqIDxwPkEgRFREIGdyYW1tYXIgdGhhdCBwcm9kdWNlcyBiYWxhbmNlZCBzeW50YXggdHJlZXMuPC9wPgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIE1pY2hhZWwgR2xhdmFzc2V2aWNoLCBJQk0KLSAqIEB2ZXJzaW9uICRJZDogQmFsYW5jZWREVERHcmFtbWFyLmphdmEsdiAxLjEgMjAxMC8wOC8xMSAwNzoxODozOCBqb2VodyBFeHAgJAotICovCi1maW5hbCBjbGFzcyBCYWxhbmNlZERUREdyYW1tYXIgZXh0ZW5kcyBEVERHcmFtbWFyIHsKLQotICAgIC8vCi0gICAgLy8gRGF0YQotICAgIC8vCi0KLSAgICAvKiogTWl4ZWQuICovCi0gICAgcHJpdmF0ZSBib29sZWFuIGZNaXhlZDsKLQotICAgIC8qKiBTdGFjayBkZXB0aCAqLwotICAgIHByaXZhdGUgaW50IGZEZXB0aCA9IDA7Ci0KLSAgICAvKiogQ2hpbGRyZW4gY29udGVudCBtb2RlbCBvcGVyYXRpb24gc3RhY2suICovCi0gICAgcHJpdmF0ZSBzaG9ydCBbXSBmT3BTdGFjayA9IG51bGw7Ci0KLSAgICAvKiogSG9sZGVyIGZvciBjaG9pY2Uvc2VxdWVuY2UvbGVhZiBncm91cHMgYXQgZWFjaCBkZXB0aC4gKi8KLSAgICBwcml2YXRlIGludCBbXVtdIGZHcm91cEluZGV4U3RhY2s7Ci0KLSAgICAvKiogU2l6ZXMgb2YgdGhlIGFsbG9jYXRlZCBwb3J0aW9ucyBvZiBlYWNoIGludFtdIGluIGZHcm91cEluZGV4U3RhY2suICovCi0gICAgcHJpdmF0ZSBpbnQgW10gZkdyb3VwSW5kZXhTdGFja1NpemVzOwotCi0gICAgLy8KLSAgICAvLyBDb25zdHJ1Y3RvcnMKLSAgICAvLwotCi0gICAgLyoqIERlZmF1bHQgY29uc3RydWN0b3IuICovCi0gICAgcHVibGljIEJhbGFuY2VkRFRER3JhbW1hcihTeW1ib2xUYWJsZSBzeW1ib2xUYWJsZSwgWE1MRFRERGVzY3JpcHRpb24gZGVzYykgewotICAgICAgICBzdXBlcihzeW1ib2xUYWJsZSwgZGVzYyk7Ci0gICAgfSAvLyBCYWxhbmNlZERUREdyYW1tYXIoU3ltYm9sVGFibGUsWE1MRFRERGVzY3JpcHRpb24pCi0KLSAgICAvLwotICAgIC8vIFB1YmxpYyBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFRoZSBzdGFydCBvZiBhIGNvbnRlbnQgbW9kZWwuIERlcGVuZGluZyBvbiB0aGUgdHlwZSBvZiB0aGUgY29udGVudAotICAgICAqIG1vZGVsLCBzcGVjaWZpYyBtZXRob2RzIG1heSBiZSBjYWxsZWQgYmV0d2VlbiB0aGUgY2FsbCB0byB0aGUKLSAgICAgKiBzdGFydENvbnRlbnRNb2RlbCBtZXRob2QgYW5kIHRoZSBjYWxsIHRvIHRoZSBlbmRDb250ZW50TW9kZWwgbWV0aG9kLgotICAgICAqCi0gICAgICogQHBhcmFtIGVsZW1lbnROYW1lIFRoZSBuYW1lIG9mIHRoZSBlbGVtZW50LgotICAgICAqIEBwYXJhbSBhdWdzIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIHZvaWQgc3RhcnRDb250ZW50TW9kZWwoU3RyaW5nIGVsZW1lbnROYW1lLCBBdWdtZW50YXRpb25zIGF1Z3MpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBmRGVwdGggPSAwOwotICAgICAgICBpbml0aWFsaXplQ29udGVudE1vZGVsU3RhY2tzKCk7Ci0gICAgICAgIHN1cGVyLnN0YXJ0Q29udGVudE1vZGVsKGVsZW1lbnROYW1lLCBhdWdzKTsKLSAgICB9IC8vIHN0YXJ0Q29udGVudE1vZGVsKFN0cmluZykKLQotICAgIC8qKgotICAgICAqIEEgc3RhcnQgb2YgZWl0aGVyIGEgbWl4ZWQgb3IgY2hpbGRyZW4gY29udGVudCBtb2RlbC4gQSBtaXhlZAotICAgICAqIGNvbnRlbnQgbW9kZWwgd2lsbCBpbW1lZGlhdGVseSBiZSBmb2xsb3dlZCBieSBhIGNhbGwgdG8gdGhlCi0gICAgICogPGNvZGU+cGNkYXRhKCk8L2NvZGU+IG1ldGhvZC4gQSBjaGlsZHJlbiBjb250ZW50IG1vZGVsIHdpbGwKLSAgICAgKiBjb250YWluIGFkZGl0aW9uYWwgZ3JvdXBzIGFuZC9vciBlbGVtZW50cy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBhdWdzIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICoKLSAgICAgKiBAc2VlICNhbnkKLSAgICAgKiBAc2VlICNlbXB0eQotICAgICAqLwotICAgIHB1YmxpYyBmaW5hbCB2b2lkIHN0YXJ0R3JvdXAoQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgKytmRGVwdGg7Ci0gICAgICAgIGluaXRpYWxpemVDb250ZW50TW9kZWxTdGFja3MoKTsKLSAgICAgICAgZk1peGVkID0gZmFsc2U7Ci0gICAgfSAvLyBzdGFydEdyb3VwKCkKLQotICAgIC8qKgotICAgICAqIFRoZSBhcHBlYXJhbmNlIG9mICIjUENEQVRBIiB3aXRoaW4gYSBncm91cCBzaWduaWZ5aW5nIGEKLSAgICAgKiBtaXhlZCBjb250ZW50IG1vZGVsLiBUaGlzIG1ldGhvZCB3aWxsIGJlIHRoZSBmaXJzdCBjYWxsZWQKLSAgICAgKiBmb2xsb3dpbmcgdGhlIGNvbnRlbnQgbW9kZWwncyA8Y29kZT5zdGFydEdyb3VwKCk8L2NvZGU+LgotICAgICAqCi0gICAgICpAcGFyYW0gYXVncyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICoKLSAgICAgKiBAc2VlICNzdGFydEdyb3VwCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIHZvaWQgcGNkYXRhKEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIGZNaXhlZCA9IHRydWU7Ci0gICAgfSAvLyBwY2RhdGEoKQotCi0gICAgLyoqCi0gICAgICogQSByZWZlcmVuY2VkIGVsZW1lbnQgaW4gYSBtaXhlZCBvciBjaGlsZHJlbiBjb250ZW50IG1vZGVsLgotICAgICAqCi0gICAgICogQHBhcmFtIGVsZW1lbnROYW1lIFRoZSBuYW1lIG9mIHRoZSByZWZlcmVuY2VkIGVsZW1lbnQuCi0gICAgICogQHBhcmFtIGF1Z3MgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyBmaW5hbCB2b2lkIGVsZW1lbnQoU3RyaW5nIGVsZW1lbnROYW1lLCBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBhZGRUb0N1cnJlbnRHcm91cChhZGRVbmlxdWVMZWFmTm9kZShlbGVtZW50TmFtZSkpOwotICAgIH0gLy8gZWxlbWVudChTdHJpbmcpCi0KLSAgICAvKioKLSAgICAgKiBUaGUgc2VwYXJhdG9yIGJldHdlZW4gY2hvaWNlcyBvciBzZXF1ZW5jZXMgb2YgYSBtaXhlZCBvciBjaGlsZHJlbgotICAgICAqIGNvbnRlbnQgbW9kZWwuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc2VwYXJhdG9yIFRoZSB0eXBlIG9mIGNoaWxkcmVuIHNlcGFyYXRvci4KLSAgICAgKiBAcGFyYW0gYXVncyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqCi0gICAgICogQHNlZSBvcmcuYXBhY2hlLnhlcmNlcy54bmkuWE1MRFREQ29udGVudE1vZGVsSGFuZGxlciNTRVBBUkFUT1JfQ0hPSUNFCi0gICAgICogQHNlZSBvcmcuYXBhY2hlLnhlcmNlcy54bmkuWE1MRFREQ29udGVudE1vZGVsSGFuZGxlciNTRVBBUkFUT1JfU0VRVUVOQ0UKLSAgICAgKi8KLSAgICBwdWJsaWMgZmluYWwgdm9pZCBzZXBhcmF0b3Ioc2hvcnQgc2VwYXJhdG9yLCBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBpZiAoc2VwYXJhdG9yID09IFhNTERURENvbnRlbnRNb2RlbEhhbmRsZXIuU0VQQVJBVE9SX0NIT0lDRSkgewotICAgICAgICAgICAgZk9wU3RhY2tbZkRlcHRoXSA9IFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9DSE9JQ0U7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoc2VwYXJhdG9yID09IFhNTERURENvbnRlbnRNb2RlbEhhbmRsZXIuU0VQQVJBVE9SX1NFUVVFTkNFKSB7Ci0gICAgICAgICAgICBmT3BTdGFja1tmRGVwdGhdID0gWE1MQ29udGVudFNwZWMuQ09OVEVOVFNQRUNOT0RFX1NFUTsKLSAgICAgICAgfQotICAgIH0gLy8gc2VwYXJhdG9yKHNob3J0KQotCi0gICAgLyoqCi0gICAgICogVGhlIG9jY3VycmVuY2UgY291bnQgZm9yIGEgY2hpbGQgaW4gYSBjaGlsZHJlbiBjb250ZW50IG1vZGVsIG9yCi0gICAgICogZm9yIHRoZSBtaXhlZCBjb250ZW50IG1vZGVsIGdyb3VwLgotICAgICAqCi0gICAgICogQHBhcmFtIG9jY3VycmVuY2UgVGhlIG9jY3VycmVuY2UgY291bnQgZm9yIHRoZSBsYXN0IGVsZW1lbnQKLSAgICAgKiAgICAgICAgICAgICAgICAgICBvciBncm91cC4KLSAgICAgKiBAcGFyYW0gYXVncyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqCi0gICAgICogQHNlZSBvcmcuYXBhY2hlLnhlcmNlcy54bmkuWE1MRFREQ29udGVudE1vZGVsSGFuZGxlciNPQ0NVUlNfWkVST19PUl9PTkUKLSAgICAgKiBAc2VlIG9yZy5hcGFjaGUueGVyY2VzLnhuaS5YTUxEVERDb250ZW50TW9kZWxIYW5kbGVyI09DQ1VSU19aRVJPX09SX01PUkUKLSAgICAgKiBAc2VlIG9yZy5hcGFjaGUueGVyY2VzLnhuaS5YTUxEVERDb250ZW50TW9kZWxIYW5kbGVyI09DQ1VSU19PTkVfT1JfTU9SRQotICAgICAqLwotICAgIHB1YmxpYyBmaW5hbCB2b2lkIG9jY3VycmVuY2Uoc2hvcnQgb2NjdXJyZW5jZSwgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKCFmTWl4ZWQpIHsKLSAgICAgICAgICAgIGludCBjdXJyZW50SW5kZXggPSBmR3JvdXBJbmRleFN0YWNrU2l6ZXNbZkRlcHRoXSAtIDE7Ci0gICAgICAgICAgICBpZiAob2NjdXJyZW5jZSA9PSBYTUxEVERDb250ZW50TW9kZWxIYW5kbGVyLk9DQ1VSU19aRVJPX09SX09ORSkgewotICAgICAgICAgICAgICAgIGZHcm91cEluZGV4U3RhY2tbZkRlcHRoXVtjdXJyZW50SW5kZXhdID0gYWRkQ29udGVudFNwZWNOb2RlKFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9aRVJPX09SX09ORSwgZkdyb3VwSW5kZXhTdGFja1tmRGVwdGhdW2N1cnJlbnRJbmRleF0sIC0xKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKCBvY2N1cnJlbmNlID09IFhNTERURENvbnRlbnRNb2RlbEhhbmRsZXIuT0NDVVJTX1pFUk9fT1JfTU9SRSkgewotICAgICAgICAgICAgICAgIGZHcm91cEluZGV4U3RhY2tbZkRlcHRoXVtjdXJyZW50SW5kZXhdID0gYWRkQ29udGVudFNwZWNOb2RlKFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9aRVJPX09SX01PUkUsIGZHcm91cEluZGV4U3RhY2tbZkRlcHRoXVtjdXJyZW50SW5kZXhdLCAtMSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmICggb2NjdXJyZW5jZSA9PSBYTUxEVERDb250ZW50TW9kZWxIYW5kbGVyLk9DQ1VSU19PTkVfT1JfTU9SRSkgewotICAgICAgICAgICAgICAgIGZHcm91cEluZGV4U3RhY2tbZkRlcHRoXVtjdXJyZW50SW5kZXhdID0gYWRkQ29udGVudFNwZWNOb2RlKFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9PTkVfT1JfTU9SRSwgZkdyb3VwSW5kZXhTdGFja1tmRGVwdGhdW2N1cnJlbnRJbmRleF0sIC0xKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0gLy8gb2NjdXJyZW5jZShzaG9ydCkKLQotICAgIC8qKgotICAgICAqIFRoZSBlbmQgb2YgYSBncm91cCBmb3IgbWl4ZWQgb3IgY2hpbGRyZW4gY29udGVudCBtb2RlbHMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYXVncyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyBmaW5hbCB2b2lkIGVuZEdyb3VwKEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIGZpbmFsIGludCBsZW5ndGggPSBmR3JvdXBJbmRleFN0YWNrU2l6ZXNbZkRlcHRoXTsKLSAgICAgICAgZmluYWwgaW50IGdyb3VwID0gbGVuZ3RoID4gMCA/IGFkZENvbnRlbnRTcGVjTm9kZXMoMCwgbGVuZ3RoIC0gMSkgOiBhZGRVbmlxdWVMZWFmTm9kZShudWxsKTsKLSAgICAgICAgLS1mRGVwdGg7Ci0gICAgICAgIGFkZFRvQ3VycmVudEdyb3VwKGdyb3VwKTsKLSAgICB9IC8vIGVuZEdyb3VwKCkKLQotICAgIC8qKgotICAgICAqIFRoZSBlbmQgb2YgdGhlIERURC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBhdWdzIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIHZvaWQgZW5kRFREKEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIHN1cGVyLmVuZERURChhdWdzKTsKLSAgICAgICAgZk9wU3RhY2sgPSBudWxsOwotICAgICAgICBmR3JvdXBJbmRleFN0YWNrID0gbnVsbDsKLSAgICAgICAgZkdyb3VwSW5kZXhTdGFja1NpemVzID0gbnVsbDsKLSAgICB9IC8vIGVuZERURCgpCi0KLSAgICAvLwotICAgIC8vIFByb3RlY3RlZCBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIEFkZHMgdGhlIGNvbnRlbnQgc3BlYyB0byB0aGUgZ2l2ZW4gZWxlbWVudCBkZWNsYXJhdGlvbi4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgZmluYWwgdm9pZCBhZGRDb250ZW50U3BlY1RvRWxlbWVudChYTUxFbGVtZW50RGVjbCBlbGVtZW50RGVjbCkgewotICAgICAgICBpbnQgY29udGVudFNwZWMgPSBmR3JvdXBJbmRleFN0YWNrU2l6ZXNbMF0gPiAwID8gZkdyb3VwSW5kZXhTdGFja1swXVswXSA6IC0xOwotICAgICAgICBzZXRDb250ZW50U3BlY0luZGV4KGZDdXJyZW50RWxlbWVudEluZGV4LCBjb250ZW50U3BlYyk7Ci0gICAgfQotCi0gICAgLy8KLSAgICAvLyBQcml2YXRlIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlcyBhIHN1YnRyZWUgZnJvbSB0aGUgbGVhZiBub2RlcyBhdCB0aGUgY3VycmVudCBkZXB0aC4KLSAgICAgKi8KLSAgICBwcml2YXRlIGludCBhZGRDb250ZW50U3BlY05vZGVzKGludCBiZWdpbiwgaW50IGVuZCkgewotICAgICAgICBpZiAoYmVnaW4gPT0gZW5kKSB7Ci0gICAgICAgICAgICByZXR1cm4gZkdyb3VwSW5kZXhTdGFja1tmRGVwdGhdW2JlZ2luXTsKLSAgICAgICAgfQotICAgICAgICBmaW5hbCBpbnQgbWlkZGxlID0gKGJlZ2luICsgZW5kKSA+Pj4gMTsKLSAgICAgICAgcmV0dXJuIGFkZENvbnRlbnRTcGVjTm9kZShmT3BTdGFja1tmRGVwdGhdLAotICAgICAgICAgICAgICAgIGFkZENvbnRlbnRTcGVjTm9kZXMoYmVnaW4sIG1pZGRsZSksCi0gICAgICAgICAgICAgICAgYWRkQ29udGVudFNwZWNOb2RlcyhtaWRkbGUgKyAxLCBlbmQpKTsKLSAgICB9IC8vIGFkZENvbnRlbnRTcGVjTm9kZXMoaW50LGludCkKLQotICAgIC8qKgotICAgICAqIEluaXRpYWxpemUgdGhlIHN0YWNrcyB3aGljaCB0ZW1wb3JhcmlseSBob2xkIGNvbnRlbnQgbW9kZWxzLgotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCBpbml0aWFsaXplQ29udGVudE1vZGVsU3RhY2tzKCkgewotICAgICAgICBpZiAoZk9wU3RhY2sgPT0gbnVsbCkgewotICAgICAgICAgICAgZk9wU3RhY2sgPSBuZXcgc2hvcnRbOF07Ci0gICAgICAgICAgICBmR3JvdXBJbmRleFN0YWNrID0gbmV3IGludCBbOF1bXTsKLSAgICAgICAgICAgIGZHcm91cEluZGV4U3RhY2tTaXplcyA9IG5ldyBpbnQgWzhdOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKGZEZXB0aCA9PSBmT3BTdGFjay5sZW5ndGgpIHsKLSAgICAgICAgICAgIHNob3J0IFtdIG5ld09wU3RhY2sgPSBuZXcgc2hvcnRbZkRlcHRoICogMl07Ci0gICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGZPcFN0YWNrLCAwLCBuZXdPcFN0YWNrLCAwLCBmRGVwdGgpOwotICAgICAgICAgICAgZk9wU3RhY2sgPSBuZXdPcFN0YWNrOwotICAgICAgICAgICAgaW50IFtdW10gbmV3R3JvdXBJbmRleFN0YWNrID0gbmV3IGludFtmRGVwdGggKiAyXVtdOwotICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShmR3JvdXBJbmRleFN0YWNrLCAwLCBuZXdHcm91cEluZGV4U3RhY2ssIDAsIGZEZXB0aCk7Ci0gICAgICAgICAgICBmR3JvdXBJbmRleFN0YWNrID0gbmV3R3JvdXBJbmRleFN0YWNrOwotICAgICAgICAgICAgaW50IFtdIG5ld0dyb3VwSW5kZXhTdGFja0xlbmd0aHMgPSBuZXcgaW50W2ZEZXB0aCAqIDJdOwotICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShmR3JvdXBJbmRleFN0YWNrU2l6ZXMsIDAsIG5ld0dyb3VwSW5kZXhTdGFja0xlbmd0aHMsIDAsIGZEZXB0aCk7Ci0gICAgICAgICAgICBmR3JvdXBJbmRleFN0YWNrU2l6ZXMgPSBuZXdHcm91cEluZGV4U3RhY2tMZW5ndGhzOwotICAgICAgICB9Ci0gICAgICAgIGZPcFN0YWNrW2ZEZXB0aF0gPSAtMTsKLSAgICAgICAgZkdyb3VwSW5kZXhTdGFja1NpemVzW2ZEZXB0aF0gPSAwOwotICAgIH0gLy8gaW5pdGlhbGl6ZUNvbnRlbnRNb2RlbFN0YWNrcygpCi0KLSAgICAvKioKLSAgICAgKiBBZGQgWE1MQ29udGVudFNwZWMgdG8gdGhlIGN1cnJlbnQgZ3JvdXAuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29udGVudFNwZWMgaGFuZGxlIHRvIHRoZSBYTUxDb250ZW50U3BlYyB0byBhZGQgdG8gdGhlIGN1cnJlbnQgZ3JvdXAKLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgYWRkVG9DdXJyZW50R3JvdXAoaW50IGNvbnRlbnRTcGVjKSB7Ci0gICAgICAgIGludCBbXSBjdXJyZW50R3JvdXAgPSBmR3JvdXBJbmRleFN0YWNrW2ZEZXB0aF07Ci0gICAgICAgIGludCBsZW5ndGggPSBmR3JvdXBJbmRleFN0YWNrU2l6ZXNbZkRlcHRoXSsrOwotICAgICAgICBpZiAoY3VycmVudEdyb3VwID09IG51bGwpIHsKLSAgICAgICAgICAgIGN1cnJlbnRHcm91cCA9IG5ldyBpbnRbOF07Ci0gICAgICAgICAgICBmR3JvdXBJbmRleFN0YWNrW2ZEZXB0aF0gPSBjdXJyZW50R3JvdXA7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAobGVuZ3RoID09IGN1cnJlbnRHcm91cC5sZW5ndGgpIHsKLSAgICAgICAgICAgIGludCBbXSBuZXdHcm91cCA9IG5ldyBpbnRbY3VycmVudEdyb3VwLmxlbmd0aCAqIDJdOwotICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShjdXJyZW50R3JvdXAsIDAsIG5ld0dyb3VwLCAwLCBjdXJyZW50R3JvdXAubGVuZ3RoKTsKLSAgICAgICAgICAgIGN1cnJlbnRHcm91cCA9IG5ld0dyb3VwOwotICAgICAgICAgICAgZkdyb3VwSW5kZXhTdGFja1tmRGVwdGhdID0gY3VycmVudEdyb3VwOwotICAgICAgICB9Ci0gICAgICAgIGN1cnJlbnRHcm91cFtsZW5ndGhdID0gY29udGVudFNwZWM7Ci0gICAgfSAvLyBhZGRUb0N1cnJlbnRHcm91cChpbnQpCi0KLX0gLy8gY2xhc3MgQmFsYW5jZWREVERHcmFtbWFyCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R0ZC9EVERHcmFtbWFyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R0ZC9EVERHcmFtbWFyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAzNzY4YjMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdGQvRFRER3JhbW1hci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjY1MSArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDE1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICovCi0vKgotICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCi0gKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKLSAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KLSAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCi0gKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAotICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR0ZDsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdGQubW9kZWxzLkNNQW55OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdGQubW9kZWxzLkNNQmluT3A7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR0ZC5tb2RlbHMuQ01MZWFmOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdGQubW9kZWxzLkNNTm9kZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHRkLm1vZGVscy5DTVVuaU9wOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdGQubW9kZWxzLkNvbnRlbnRNb2RlbFZhbGlkYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHRkLm1vZGVscy5ERkFDb250ZW50TW9kZWw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR0ZC5tb2RlbHMuTWl4ZWRDb250ZW50TW9kZWw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR0ZC5tb2RlbHMuU2ltcGxlQ29udGVudE1vZGVsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5EYXRhdHlwZVZhbGlkYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwudmFsaWRhdGlvbi5FbnRpdHlTdGF0ZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuU3ltYm9sVGFibGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuQXVnbWVudGF0aW9uczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5RTmFtZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxEVERDb250ZW50TW9kZWxIYW5kbGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTERUREhhbmRsZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MTG9jYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxSZXNvdXJjZUlkZW50aWZpZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MU3RyaW5nOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhOSUV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5ncmFtbWFycy5HcmFtbWFyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLmdyYW1tYXJzLlhNTEdyYW1tYXJEZXNjcmlwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MRFREQ29udGVudE1vZGVsU291cmNlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxEVERTb3VyY2U7Ci1pbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKLWltcG9ydCBqYXZhLnV0aWwuTWFwOwotCi0vKioKLSAqIEEgRFREIGdyYW1tYXIuIFRoaXMgY2xhc3MgaW1wbGVtZW50cyB0aGUgWE5JIGhhbmRsZXIgaW50ZXJmYWNlcwotICogZm9yIERURCBpbmZvcm1hdGlvbiBzbyB0aGF0IGl0IGNhbiBidWlsZCB0aGUgYXBwcm9wcmlhdGUgdmFsaWRhdGlvbgotICogc3RydWN0dXJlcyBhdXRvbWF0aWNhbGx5IGZyb20gdGhlIGNhbGxiYWNrcy4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBFcmljIFllLCBJQk0KLSAqIEBhdXRob3IgSmVmZnJleSBSb2RyaWd1ZXosIElCTQotICogQGF1dGhvciBBbmR5IENsYXJrLCBJQk0KLSAqIEBhdXRob3IgTmVpbCBHcmFoYW0sIElCTQotICoKLSAqIEB2ZXJzaW9uICRJZDogRFRER3JhbW1hci5qYXZhLHYgMS40IDIwMTAvMDgvMTEgMDc6MTg6Mzcgam9laHcgRXhwICQKLSAqLwotcHVibGljIGNsYXNzIERUREdyYW1tYXIKLSAgICBpbXBsZW1lbnRzIFhNTERUREhhbmRsZXIsIFhNTERURENvbnRlbnRNb2RlbEhhbmRsZXIsIEVudGl0eVN0YXRlLCBHcmFtbWFyIHsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RhbnRzCi0gICAgLy8KLQotICAgIC8qKiBUb3AgbGV2ZWwgc2NvcGUgKC0xKS4gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUT1BfTEVWRUxfU0NPUEUgPSAtMTsKLQotICAgIC8vIHByaXZhdGUKLQotICAgIC8qKiBDaHVuayBzaGlmdCAoOCkuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IENIVU5LX1NISUZUID0gODsgLy8gMl44ID0gMjU2Ci0KLSAgICAvKiogQ2h1bmsgc2l6ZSAoMSA8PCBDSFVOS19TSElGVCkuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IENIVU5LX1NJWkUgPSAoMSA8PCBDSFVOS19TSElGVCk7Ci0KLSAgICAvKiogQ2h1bmsgbWFzayAoQ0hVTktfU0laRSAtIDEpLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBDSFVOS19NQVNLID0gQ0hVTktfU0laRSAtIDE7Ci0KLSAgICAvKiogSW5pdGlhbCBjaHVuayBjb3VudCAoMSA8PCAoMTAgLSBDSFVOS19TSElGVCkpLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBJTklUSUFMX0NIVU5LX0NPVU5UID0gKDEgPDwgKDEwIC0gQ0hVTktfU0hJRlQpKTsgLy8gMl4xMCA9IDFrCi0KLSAgICAvKiogTGlzdCBmbGFnICgweDgwKS4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBzaG9ydCBMSVNUX0ZMQUcgPSAweDgwOwotCi0gICAgLyoqIExpc3QgbWFzayAofkxJU1RfRkxBRykuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgc2hvcnQgTElTVF9NQVNLID0gfkxJU1RfRkxBRzsKLQotICAgIC8vIGRlYnVnZ2luZwotCi0gICAgLyoqIERlYnVnIERUREdyYW1tYXIuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbiBERUJVRyA9IGZhbHNlOwotCi0gICAgLy8KLSAgICAvLyBEYXRhCi0gICAgLy8KLQotICAgIHByb3RlY3RlZCBYTUxEVERTb3VyY2UgZkRURFNvdXJjZSA9IG51bGw7Ci0gICAgcHJvdGVjdGVkIFhNTERURENvbnRlbnRNb2RlbFNvdXJjZSBmRFREQ29udGVudE1vZGVsU291cmNlID0gbnVsbDsKLQotICAgIC8qKiBDdXJyZW50IGVsZW1lbnQgaW5kZXguICovCi0gICAgcHJvdGVjdGVkIGludCBmQ3VycmVudEVsZW1lbnRJbmRleDsKLQotICAgIC8qKiBDdXJyZW50IGF0dHJpYnV0ZSBpbmRleC4gKi8KLSAgICBwcm90ZWN0ZWQgaW50IGZDdXJyZW50QXR0cmlidXRlSW5kZXg7Ci0KLSAgICAvKiogZlJlYWRpbmdFeHRlcm5hbERURCAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIGZSZWFkaW5nRXh0ZXJuYWxEVEQgPSBmYWxzZTsKLQotICAgIC8qKiBTeW1ib2wgdGFibGUuICovCi0gICAgcHJpdmF0ZSBTeW1ib2xUYWJsZSBmU3ltYm9sVGFibGU7Ci0KLSAgICAvLyBUaGUgWE1MRFRERGVzY3JpcHRpb24gd2l0aCB3aGljaCB0aGlzIEdyYW1tYXIgaXMgYXNzb2NpYXRlZAotICAgIHByb3RlY3RlZCBYTUxEVEREZXNjcmlwdGlvbiBmR3JhbW1hckRlc2NyaXB0aW9uID0gbnVsbDsKLQotICAgIC8vIGVsZW1lbnQgZGVjbGFyYXRpb25zCi0KLSAgICAvKiogTnVtYmVyIG9mIGVsZW1lbnQgZGVjbGFyYXRpb25zLiAqLwotICAgIHByaXZhdGUgaW50IGZFbGVtZW50RGVjbENvdW50ID0gMDsKLQotICAgIC8qKiBFbGVtZW50IGRlY2xhcmF0aW9uIG5hbWUuICovCi0gICAgcHJpdmF0ZSBRTmFtZSBmRWxlbWVudERlY2xOYW1lW11bXSA9IG5ldyBRTmFtZVtJTklUSUFMX0NIVU5LX0NPVU5UXVtdOwotCi0gICAgLyoqCi0gICAgICogRWxlbWVudCBkZWNsYXJhdGlvbiB0eXBlLgotICAgICAqIEBzZWUgWE1MRWxlbWVudERlY2wKLSAgICAgKi8KLSAgICBwcml2YXRlIHNob3J0IGZFbGVtZW50RGVjbFR5cGVbXVtdID0gbmV3IHNob3J0W0lOSVRJQUxfQ0hVTktfQ09VTlRdW107Ci0KLSAgICAvKioKLSAgICAgKiBFbGVtZW50IGRlY2xhcmF0aW9uIGNvbnRlbnQgc3BlYyBpbmRleC4gVGhpcyBpbmRleCB2YWx1ZSBpcyB1c2VkCi0gICAgICogdG8gcmVmZXIgdG8gdGhlIGNvbnRlbnQgc3BlYyBpbmZvcm1hdGlvbiB0YWJsZXMuCi0gICAgICovCi0gICAgcHJpdmF0ZSBpbnQgZkVsZW1lbnREZWNsQ29udGVudFNwZWNJbmRleFtdW10gPSBuZXcgaW50W0lOSVRJQUxfQ0hVTktfQ09VTlRdW107Ci0KLSAgICAvKioKLSAgICAgKiBFbGVtZW50IGRlY2xhcmF0aW9uIGNvbnRlbnQgbW9kZWwgdmFsaWRhdG9yLiBUaGlzIHZhbGlkYXRvciBpcwotICAgICAqIGNvbnN0cnVjdGVkIGZyb20gdGhlIGNvbnRlbnQgc3BlYyBub2Rlcy4KLSAgICAgKi8KLSAgICBwcml2YXRlIENvbnRlbnRNb2RlbFZhbGlkYXRvciBmRWxlbWVudERlY2xDb250ZW50TW9kZWxWYWxpZGF0b3JbXVtdID0gbmV3IENvbnRlbnRNb2RlbFZhbGlkYXRvcltJTklUSUFMX0NIVU5LX0NPVU5UXVtdOwotCi0gICAgLyoqIEZpcnN0IGF0dHJpYnV0ZSBkZWNsYXJhdGlvbiBvZiBhbiBlbGVtZW50IGRlY2xhcmF0aW9uLiAqLwotICAgIHByaXZhdGUgaW50IGZFbGVtZW50RGVjbEZpcnN0QXR0cmlidXRlRGVjbEluZGV4W11bXSA9IG5ldyBpbnRbSU5JVElBTF9DSFVOS19DT1VOVF1bXTsKLQotICAgIC8qKiBMYXN0IGF0dHJpYnV0ZSBkZWNsYXJhdGlvbiBvZiBhbiBlbGVtZW50IGRlY2xhcmF0aW9uLiAqLwotICAgIHByaXZhdGUgaW50IGZFbGVtZW50RGVjbExhc3RBdHRyaWJ1dGVEZWNsSW5kZXhbXVtdID0gbmV3IGludFtJTklUSUFMX0NIVU5LX0NPVU5UXVtdOwotCi0gICAgLy8gYXR0cmlidXRlIGRlY2xhcmF0aW9ucwotCi0gICAgLyoqIE51bWJlciBvZiBhdHRyaWJ1dGUgZGVjbGFyYXRpb25zLiAqLwotICAgIHByaXZhdGUgaW50IGZBdHRyaWJ1dGVEZWNsQ291bnQgPSAwIDsKLQotICAgIC8qKiBBdHRyaWJ1dGUgZGVjbGFyYXRpb24gbmFtZS4gKi8KLSAgICBwcml2YXRlIFFOYW1lIGZBdHRyaWJ1dGVEZWNsTmFtZVtdW10gPSBuZXcgUU5hbWVbSU5JVElBTF9DSFVOS19DT1VOVF1bXTsKLQotICAgIC8vIGlzIHRoaXMgZ3JhbW1hciBpbW11dGFibGU/ICAoZnVsbHkgY29uc3RydWN0ZWQgYW5kIG5vdCBjaGFuZ2VhYmxlKQotICAgIHByaXZhdGUgYm9vbGVhbiBmSXNJbW11dGFibGUgPSBmYWxzZTsKLQotICAgIC8qKgotICAgICAqIEF0dHJpYnV0ZSBkZWNsYXJhdGlvbiB0eXBlLgotICAgICAqIEBzZWUgWE1MQXR0cmlidXRlRGVjbAotICAgICAqLwotICAgIHByaXZhdGUgc2hvcnQgZkF0dHJpYnV0ZURlY2xUeXBlW11bXSA9IG5ldyBzaG9ydFtJTklUSUFMX0NIVU5LX0NPVU5UXVtdOwotCi0gICAgLyoqIEF0dHJpYnV0ZSBkZWNsYXJhdGlvbiBlbnVtZXJhdGlvbiB2YWx1ZXMuICovCi0gICAgcHJpdmF0ZSBTdHJpbmdbXSBmQXR0cmlidXRlRGVjbEVudW1lcmF0aW9uW11bXSA9IG5ldyBTdHJpbmdbSU5JVElBTF9DSFVOS19DT1VOVF1bXVtdOwotICAgIHByaXZhdGUgc2hvcnQgZkF0dHJpYnV0ZURlY2xEZWZhdWx0VHlwZVtdW10gPSBuZXcgc2hvcnRbSU5JVElBTF9DSFVOS19DT1VOVF1bXTsKLSAgICBwcml2YXRlIERhdGF0eXBlVmFsaWRhdG9yIGZBdHRyaWJ1dGVEZWNsRGF0YXR5cGVWYWxpZGF0b3JbXVtdID0gbmV3IERhdGF0eXBlVmFsaWRhdG9yW0lOSVRJQUxfQ0hVTktfQ09VTlRdW107Ci0gICAgcHJpdmF0ZSBTdHJpbmcgZkF0dHJpYnV0ZURlY2xEZWZhdWx0VmFsdWVbXVtdID0gbmV3IFN0cmluZ1tJTklUSUFMX0NIVU5LX0NPVU5UXVtdOwotICAgIHByaXZhdGUgU3RyaW5nIGZBdHRyaWJ1dGVEZWNsTm9uTm9ybWFsaXplZERlZmF1bHRWYWx1ZVtdW10gPSBuZXcgU3RyaW5nW0lOSVRJQUxfQ0hVTktfQ09VTlRdW107Ci0gICAgcHJpdmF0ZSBpbnQgZkF0dHJpYnV0ZURlY2xOZXh0QXR0cmlidXRlRGVjbEluZGV4W11bXSA9IG5ldyBpbnRbSU5JVElBTF9DSFVOS19DT1VOVF1bXTsKLQotICAgIC8vIGNvbnRlbnQgc3BlY3MKLQotICAgIC8vIGhlcmUgc2F2ZXMgdGhlIGNvbnRlbnQgc3BlYyBiaW5hcnkgdHJlZXMgZm9yIGVsZW1lbnQgZGVjbHMsCi0gICAgLy8gZWFjaCBlbGVtZW50IHdpdGggYSBjb250ZW50IG1vZGVsIHdpbGwgaG9sZCBhIHBvaW50ZXIgd2hpY2ggaXMKLSAgICAvLyB0aGUgaW5kZXggb2YgdGhlIGhlYWQgbm9kZSBvZiB0aGUgY29udGVudCBzcGVjIHRyZWUuCi0KLSAgICBwcml2YXRlIGludCBmQ29udGVudFNwZWNDb3VudCA9IDA7Ci0gICAgcHJpdmF0ZSBzaG9ydCBmQ29udGVudFNwZWNUeXBlW11bXSA9IG5ldyBzaG9ydFtJTklUSUFMX0NIVU5LX0NPVU5UXVtdOwotICAgIHByaXZhdGUgT2JqZWN0IGZDb250ZW50U3BlY1ZhbHVlW11bXSA9IG5ldyBPYmplY3RbSU5JVElBTF9DSFVOS19DT1VOVF1bXTsKLSAgICBwcml2YXRlIE9iamVjdCBmQ29udGVudFNwZWNPdGhlclZhbHVlW11bXSA9IG5ldyBPYmplY3RbSU5JVElBTF9DSFVOS19DT1VOVF1bXTsKLQotICAgIC8vIGVudGl0aWVzCi0KLSAgICBwcml2YXRlIGludCBmRW50aXR5Q291bnQgPSAwOwotICAgIHByaXZhdGUgU3RyaW5nIGZFbnRpdHlOYW1lW11bXSA9IG5ldyBTdHJpbmdbSU5JVElBTF9DSFVOS19DT1VOVF1bXTsKLSAgICBwcml2YXRlIFN0cmluZ1tdW10gZkVudGl0eVZhbHVlID0gbmV3IFN0cmluZ1tJTklUSUFMX0NIVU5LX0NPVU5UXVtdOwotICAgIHByaXZhdGUgU3RyaW5nW11bXSBmRW50aXR5UHVibGljSWQgPSBuZXcgU3RyaW5nW0lOSVRJQUxfQ0hVTktfQ09VTlRdW107Ci0gICAgcHJpdmF0ZSBTdHJpbmdbXVtdIGZFbnRpdHlTeXN0ZW1JZCA9IG5ldyBTdHJpbmdbSU5JVElBTF9DSFVOS19DT1VOVF1bXTsKLSAgICBwcml2YXRlIFN0cmluZ1tdW10gZkVudGl0eUJhc2VTeXN0ZW1JZCA9IG5ldyBTdHJpbmdbSU5JVElBTF9DSFVOS19DT1VOVF1bXTsKLSAgICBwcml2YXRlIFN0cmluZ1tdW10gZkVudGl0eU5vdGF0aW9uID0gbmV3IFN0cmluZ1tJTklUSUFMX0NIVU5LX0NPVU5UXVtdOwotICAgIHByaXZhdGUgYnl0ZVtdW10gZkVudGl0eUlzUEUgPSBuZXcgYnl0ZVtJTklUSUFMX0NIVU5LX0NPVU5UXVtdOwotICAgIHByaXZhdGUgYnl0ZVtdW10gZkVudGl0eUluRXh0ZXJuYWwgPSBuZXcgYnl0ZVtJTklUSUFMX0NIVU5LX0NPVU5UXVtdOwotCi0gICAgLy8gbm90YXRpb25zCi0KLSAgICBwcml2YXRlIGludCBmTm90YXRpb25Db3VudCA9IDA7Ci0gICAgcHJpdmF0ZSBTdHJpbmcgZk5vdGF0aW9uTmFtZVtdW10gPSBuZXcgU3RyaW5nW0lOSVRJQUxfQ0hVTktfQ09VTlRdW107Ci0gICAgcHJpdmF0ZSBTdHJpbmdbXVtdIGZOb3RhdGlvblB1YmxpY0lkID0gbmV3IFN0cmluZ1tJTklUSUFMX0NIVU5LX0NPVU5UXVtdOwotICAgIHByaXZhdGUgU3RyaW5nW11bXSBmTm90YXRpb25TeXN0ZW1JZCA9IG5ldyBTdHJpbmdbSU5JVElBTF9DSFVOS19DT1VOVF1bXTsKLSAgICBwcml2YXRlIFN0cmluZ1tdW10gZk5vdGF0aW9uQmFzZVN5c3RlbUlkID0gbmV3IFN0cmluZ1tJTklUSUFMX0NIVU5LX0NPVU5UXVtdOwotCi0gICAgLy8gb3RoZXIgaW5mb3JtYXRpb24KLQotICAgIC8qKiBFbGVtZW50IGluZGV4IG1hcHBpbmcgdGFibGUuICovCi0gICAgcHJpdmF0ZSBmaW5hbCBNYXA8U3RyaW5nLCBJbnRlZ2VyPiBmRWxlbWVudEluZGV4TWFwID0gbmV3IEhhc2hNYXA8PigpOwotCi0gICAgLyoqIEVudGl0eSBpbmRleCBtYXBwaW5nIHRhYmxlLiAqLwotICAgIHByaXZhdGUgZmluYWwgTWFwPFN0cmluZywgSW50ZWdlcj4gZkVudGl0eUluZGV4TWFwID0gbmV3IEhhc2hNYXA8PigpOwotCi0gICAgLyoqIE5vdGF0aW9uIGluZGV4IG1hcHBpbmcgdGFibGUuICovCi0gICAgcHJpdmF0ZSBmaW5hbCBNYXA8U3RyaW5nLCBJbnRlZ2VyPiBmTm90YXRpb25JbmRleE1hcCA9IG5ldyBIYXNoTWFwPD4oKTsKLQotICAgIC8vIHRlbXAgdmFyaWFibGVzCi0KLSAgICAvKiogTWl4ZWQuICovCi0gICAgcHJpdmF0ZSBib29sZWFuIGZNaXhlZDsKLQotICAgIC8qKiBUZW1wb3JhcnkgcXVhbGlmaWVkIG5hbWUuICovCi0gICAgcHJpdmF0ZSBmaW5hbCBRTmFtZSBmUU5hbWUgPSBuZXcgUU5hbWUoKTsKLQotICAgIC8qKiBUZW1wb3JhcnkgcXVhbGlmaWVkIG5hbWUuICovCi0gICAgcHJpdmF0ZSBmaW5hbCBRTmFtZSBmUU5hbWUyID0gbmV3IFFOYW1lKCk7Ci0KLSAgICAvKiogVGVtcG9yYXJ5IEF0dHJpYnV0ZSBkZWNsLiAqLwotICAgIHByb3RlY3RlZCBmaW5hbCBYTUxBdHRyaWJ1dGVEZWNsIGZBdHRyaWJ1dGVEZWNsID0gbmV3IFhNTEF0dHJpYnV0ZURlY2woKTsKLQotICAgIC8vIGZvciBidWlsZFN5bnRheFRyZWUgbWV0aG9kCi0KLSAgICBwcml2YXRlIGludCBmTGVhZkNvdW50ID0gMDsKLSAgICBwcml2YXRlIGludCBmRXBzaWxvbkluZGV4ID0gLTE7Ci0KLSAgICAvKiogRWxlbWVudCBkZWNsYXJhdGlvbi4gKi8KLSAgICBwcml2YXRlIFhNTEVsZW1lbnREZWNsIGZFbGVtZW50RGVjbCA9IG5ldyBYTUxFbGVtZW50RGVjbCgpOwotCi0gICAgLyoqIEVudGl0eSBkZWNsYXJhdGlvbi4gKi8KLSAgICBwcml2YXRlIFhNTEVudGl0eURlY2wgZkVudGl0eURlY2wgPSBuZXcgWE1MRW50aXR5RGVjbCgpOwotCi0gICAgLyoqIFNpbXBsZSB0eXBlLiAqLwotICAgIHByaXZhdGUgWE1MU2ltcGxlVHlwZSBmU2ltcGxlVHlwZSA9IG5ldyBYTUxTaW1wbGVUeXBlKCk7Ci0KLSAgICAvKiogQ29udGVudCBzcGVjIG5vZGUuICovCi0gICAgcHJpdmF0ZSBYTUxDb250ZW50U3BlYyBmQ29udGVudFNwZWMgPSBuZXcgWE1MQ29udGVudFNwZWMoKTsKLQotICAgIC8qKiB0YWJsZSBvZiBYTUxFbGVtZW50RGVjbCAgICovCi0gICAgTWFwPFN0cmluZywgWE1MRWxlbWVudERlY2w+IGZFbGVtZW50RGVjbFRhYiA9IG5ldyBIYXNoTWFwPD4oKTsKLQotICAgIC8qKiBDaGlsZHJlbiBjb250ZW50IG1vZGVsIG9wZXJhdGlvbiBzdGFjay4gKi8KLSAgICBwcml2YXRlIHNob3J0W10gZk9wU3RhY2sgPSBudWxsOwotCi0gICAgLyoqIENoaWxkcmVuIGNvbnRlbnQgbW9kZWwgaW5kZXggc3RhY2suICovCi0gICAgcHJpdmF0ZSBpbnRbXSBmTm9kZUluZGV4U3RhY2sgPSBudWxsOwotCi0gICAgLyoqIENoaWxkcmVuIGNvbnRlbnQgbW9kZWwgcHJldmlvdXMgbm9kZSBpbmRleCBzdGFjay4gKi8KLSAgICBwcml2YXRlIGludFtdIGZQcmV2Tm9kZUluZGV4U3RhY2sgPSBudWxsOwotCi0gICAgLyoqIFN0YWNrIGRlcHRoICAgKi8KLSAgICBwcml2YXRlIGludCBmRGVwdGggPSAwOwotCi0gICAgLyoqIEVudGl0eSBzdGFjay4gKi8KLSAgICBwcml2YXRlIGJvb2xlYW5bXSBmUEVudGl0eVN0YWNrID0gbmV3IGJvb2xlYW5bNF07Ci0gICAgcHJpdmF0ZSBpbnQgZlBFRGVwdGggPSAwOwotCi0gICAgLy8gYWRkaXRpb25hbCBmaWVsZHMoY29sdW1ucykgZm9yIHRoZSBlbGVtZW50IERlY2wgcG9vbCBpbiB0aGUgR3JhbW1hcgotCi0gICAgLyoqIGZsYWcgaWYgdGhlIGVsZW1lbnREZWNsIGlzIEV4dGVybmFsLiAqLwotICAgIHByaXZhdGUgaW50IGZFbGVtZW50RGVjbElzRXh0ZXJuYWxbXVtdID0gbmV3IGludFtJTklUSUFMX0NIVU5LX0NPVU5UXVtdOwotCi0KLSAgICAvLyBhZGRpdGlvbmFsIGZpZWxkcyhjb2x1bW5zKSBmb3IgdGhlIGF0dHJpYnV0ZSBEZWNsIHBvb2wgaW4gdGhlIEdyYW1tYXIKLQotICAgIC8qKiBmbGFnIGlmIHRoZSBBdHRyaWJ1dGVEZWNsIGlzIEV4dGVybmFsLiAqLwotICAgIHByaXZhdGUgaW50IGZBdHRyaWJ1dGVEZWNsSXNFeHRlcm5hbFtdW10gPSBuZXcgaW50W0lOSVRJQUxfQ0hVTktfQ09VTlRdW107Ci0KLSAgICAvLyBmb3IgbWl4ZWRFbGVtZW50IG1ldGhvZAotCi0gICAgaW50IHZhbHVlSW5kZXggICAgICAgICAgICA9IC0xOwotICAgIGludCBwcmV2Tm9kZUluZGV4ICAgICAgICAgPSAtMTsKLSAgICBpbnQgbm9kZUluZGV4ICAgICAgICAgICAgID0gLTE7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0cnVjdG9ycwotICAgIC8vCi0KLSAgICAvKiogRGVmYXVsdCBjb25zdHJ1Y3Rvci4gKi8KLSAgICBwdWJsaWMgRFRER3JhbW1hcihTeW1ib2xUYWJsZSBzeW1ib2xUYWJsZSwgWE1MRFRERGVzY3JpcHRpb24gZGVzYykgewotICAgICAgICBmU3ltYm9sVGFibGUgPSBzeW1ib2xUYWJsZTsKLSAgICAgICAgZkdyYW1tYXJEZXNjcmlwdGlvbiA9IGRlc2M7Ci0gICAgfSAvLyA8aW5pdD4oU3ltYm9sVGFibGUpCi0KLSAgICAvLyBHcmFtbWFyIG1ldGhvZHMKLQotICAgIC8vIHJldHVybiB0aGUgWE1MRFRERGVzY3JpcHRpb24gb2JqZWN0IHdpdGggd2hpY2ggdGhpcyBpcyBhc3NvY2lhdGVkCi0gICAgcHVibGljIFhNTEdyYW1tYXJEZXNjcmlwdGlvbiBnZXRHcmFtbWFyRGVzY3JpcHRpb24oKSB7Ci0gICAgICAgIHJldHVybiBmR3JhbW1hckRlc2NyaXB0aW9uOwotICAgIH0gLy8gZ2V0R3JhbW1hckRlc2NyaXB0aW9uKCk6ICBYTUxHcmFtbWFyRGVzY3JpcHRpb24KLQotICAgIC8vCi0gICAgLy8gUHVibGljIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBkZWNsYXJhdGlvbiBpcyBleHRlcm5hbC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlbGVtZW50RGVjbEluZGV4IFRoZSBlbGVtZW50IGRlY2xhcmF0aW9uIGluZGV4LgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGdldEVsZW1lbnREZWNsSXNFeHRlcm5hbChpbnQgZWxlbWVudERlY2xJbmRleCkgewotCi0gICAgICAgIGlmIChlbGVtZW50RGVjbEluZGV4IDwgMCkgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0KLSAgICAgICAgaW50IGNodW5rID0gZWxlbWVudERlY2xJbmRleCA+PiBDSFVOS19TSElGVDsKLSAgICAgICAgaW50IGluZGV4ID0gZWxlbWVudERlY2xJbmRleCAmIENIVU5LX01BU0s7Ci0gICAgICAgIHJldHVybiAoZkVsZW1lbnREZWNsSXNFeHRlcm5hbFtjaHVua11baW5kZXhdICE9IDApOwotCi0gICAgfSAvLyBnZXRFbGVtZW50RGVjbElzRXh0ZXJuYWwoaW50KTpib29sZWFuCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIHNwZWNpZmllZCBhdHRyaWJ1dGUgZGVjbGFyYXRpb24gaXMgZXh0ZXJuYWwuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYXR0cmlidXRlRGVjbEluZGV4IEF0dHJpYnV0ZSBkZWNsYXJhdGlvbiBpbmRleC4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXRBdHRyaWJ1dGVEZWNsSXNFeHRlcm5hbChpbnQgYXR0cmlidXRlRGVjbEluZGV4KSB7Ci0KLSAgICAgICAgaWYgKGF0dHJpYnV0ZURlY2xJbmRleCA8IDApIHsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotCi0gICAgICAgIGludCBjaHVuayA9IGF0dHJpYnV0ZURlY2xJbmRleCA+PiBDSFVOS19TSElGVDsKLSAgICAgICAgaW50IGluZGV4ID0gYXR0cmlidXRlRGVjbEluZGV4ICYgQ0hVTktfTUFTSzsKLSAgICAgICAgcmV0dXJuIChmQXR0cmlidXRlRGVjbElzRXh0ZXJuYWxbY2h1bmtdW2luZGV4XSAhPSAwKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldEF0dHJpYnV0ZURlY2xJbmRleChpbnQgZWxlbWVudERlY2xJbmRleCwgU3RyaW5nIGF0dHJpYnV0ZURlY2xOYW1lKSB7Ci0gICAgICAgIGlmIChlbGVtZW50RGVjbEluZGV4ID09IC0xKSB7Ci0gICAgICAgICAgICByZXR1cm4gLTE7Ci0gICAgICAgIH0KLSAgICAgICAgaW50IGF0dERlZkluZGV4ID0gZ2V0Rmlyc3RBdHRyaWJ1dGVEZWNsSW5kZXgoZWxlbWVudERlY2xJbmRleCk7Ci0gICAgICAgIHdoaWxlIChhdHREZWZJbmRleCAhPSAtMSkgewotICAgICAgICAgICAgZ2V0QXR0cmlidXRlRGVjbChhdHREZWZJbmRleCwgZkF0dHJpYnV0ZURlY2wpOwotCi0gICAgICAgICAgICBpZiAoZkF0dHJpYnV0ZURlY2wubmFtZS5yYXduYW1lID09IGF0dHJpYnV0ZURlY2xOYW1lCi0gICAgICAgICAgICAgICAgfHwgYXR0cmlidXRlRGVjbE5hbWUuZXF1YWxzKGZBdHRyaWJ1dGVEZWNsLm5hbWUucmF3bmFtZSkgKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGF0dERlZkluZGV4OwotICAgICAgICAgICAgfQotICAgICAgICAgICAgYXR0RGVmSW5kZXggPSBnZXROZXh0QXR0cmlidXRlRGVjbEluZGV4KGF0dERlZkluZGV4KTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gLTE7Ci0gICAgfSAvLyBnZXRBdHRyaWJ1dGVEZWNsSW5kZXggKGludCxRTmFtZSkKLQotICAgIC8vCi0gICAgLy8gWE1MRFRESGFuZGxlciBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFRoZSBzdGFydCBvZiB0aGUgRFRELgotICAgICAqCi0gICAgICogQHBhcmFtIGxvY2F0b3IgIFRoZSBkb2N1bWVudCBsb2NhdG9yLCBvciBudWxsIGlmIHRoZSBkb2N1bWVudAotICAgICAqICAgICAgICAgICAgICAgICBsb2NhdGlvbiBjYW5ub3QgYmUgcmVwb3J0ZWQgZHVyaW5nIHRoZSBwYXJzaW5nIG9mCi0gICAgICogICAgICAgICAgICAgICAgIHRoZSBkb2N1bWVudCBEVEQuIEhvd2V2ZXIsIGl0IGlzIDxlbT5zdHJvbmdseTwvZW0+Ci0gICAgICogICAgICAgICAgICAgICAgIHJlY29tbWVuZGVkIHRoYXQgYSBsb2NhdG9yIGJlIHN1cHBsaWVkIHRoYXQgY2FuCi0gICAgICogICAgICAgICAgICAgICAgIGF0IGxlYXN0IHJlcG9ydCB0aGUgYmFzZSBzeXN0ZW0gaWRlbnRpZmllciBvZiB0aGUKLSAgICAgKiAgICAgICAgICAgICAgICAgRFRELgotICAgICAqCi0gICAgICogQHBhcmFtIGF1Z3MgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydERURChYTUxMb2NhdG9yIGxvY2F0b3IsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIC8vSW5pdGlhbGl6ZSBzdGFjawotICAgICAgICBmT3BTdGFjayA9IG51bGw7Ci0gICAgICAgIGZOb2RlSW5kZXhTdGFjayA9IG51bGw7Ci0gICAgICAgIGZQcmV2Tm9kZUluZGV4U3RhY2sgPSBudWxsOwotICAgIH0gLy8gc3RhcnREVEQoWE1MTG9jYXRvcikKLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIG5vdGlmaWVzIG9mIHRoZSBzdGFydCBvZiBhbiBlbnRpdHkuIFRoZSBEVEQgaGFzIHRoZQotICAgICAqIHBzZXVkby1uYW1lIG9mICJbZHRkXSIgYW5kIHBhcmFtZXRlciBlbnRpdHkgbmFtZXMgc3RhcnQgd2l0aCAnJScuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBTaW5jZSB0aGUgRFREIGlzIGFuIGVudGl0eSwgdGhlIGhhbmRsZXIKLSAgICAgKiB3aWxsIGJlIG5vdGlmaWVkIG9mIHRoZSBzdGFydCBvZiB0aGUgRFREIGVudGl0eSBieSBjYWxsaW5nIHRoZQotICAgICAqIHN0YXJ0UGFyYW1ldGVyRW50aXR5IG1ldGhvZCB3aXRoIHRoZSBlbnRpdHkgbmFtZSAiW2R0ZF0iIDxlbT5iZWZvcmU8L2VtPiBjYWxsaW5nCi0gICAgICogdGhlIHN0YXJ0RFREIG1ldGhvZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lICAgICBUaGUgbmFtZSBvZiB0aGUgcGFyYW1ldGVyIGVudGl0eS4KLSAgICAgKiBAcGFyYW0gaWRlbnRpZmllciBUaGUgcmVzb3VyY2UgaWRlbnRpZmllci4KLSAgICAgKiBAcGFyYW0gZW5jb2RpbmcgVGhlIGF1dG8tZGV0ZWN0ZWQgSUFOQSBlbmNvZGluZyBuYW1lIG9mIHRoZSBlbnRpdHkKLSAgICAgKiAgICAgICAgICAgICAgICAgc3RyZWFtLiBUaGlzIHZhbHVlIHdpbGwgYmUgbnVsbCBpbiB0aG9zZSBzaXR1YXRpb25zCi0gICAgICogICAgICAgICAgICAgICAgIHdoZXJlIHRoZSBlbnRpdHkgZW5jb2RpbmcgaXMgbm90IGF1dG8tZGV0ZWN0ZWQgKGUuZy4KLSAgICAgKiAgICAgICAgICAgICAgICAgaW50ZXJuYWwgcGFyYW1ldGVyIGVudGl0aWVzKS4KLSAgICAgKiBAcGFyYW0gYXVncyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnRQYXJhbWV0ZXJFbnRpdHkoU3RyaW5nIG5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MUmVzb3VyY2VJZGVudGlmaWVyIGlkZW50aWZpZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGVuY29kaW5nLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy8ga2VlcCB0cmFjayBvZiB0aGlzIGVudGl0eSBiZWZvcmUgZkVudGl0eURlcHRoIGlzIGluY3JlYXNlZAotICAgICAgICBpZiAoZlBFRGVwdGggPT0gZlBFbnRpdHlTdGFjay5sZW5ndGgpIHsKLSAgICAgICAgICAgIGJvb2xlYW5bXSBlbnRpdHlhcnJheSA9IG5ldyBib29sZWFuW2ZQRW50aXR5U3RhY2subGVuZ3RoICogMl07Ci0gICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGZQRW50aXR5U3RhY2ssIDAsIGVudGl0eWFycmF5LCAwLCBmUEVudGl0eVN0YWNrLmxlbmd0aCk7Ci0gICAgICAgICAgICBmUEVudGl0eVN0YWNrID0gZW50aXR5YXJyYXk7Ci0gICAgICAgIH0KLSAgICAgICAgZlBFbnRpdHlTdGFja1tmUEVEZXB0aF0gPSBmUmVhZGluZ0V4dGVybmFsRFREOwotICAgICAgICBmUEVEZXB0aCsrOwotCi0gICAgfSAvLyBzdGFydFBhcmFtZXRlckVudGl0eShTdHJpbmcsWE1MUmVzb3VyY2VJZGVudGlmaWVyLFN0cmluZyxBdWdtZW50YXRpb25zKQotCi0gICAgLyoqCi0gICAgICogVGhlIHN0YXJ0IG9mIHRoZSBEVEQgZXh0ZXJuYWwgc3Vic2V0LgotICAgICAqCi0gICAgICogQHBhcmFtIGF1Z3MgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RXh0ZXJuYWxTdWJzZXQoWE1MUmVzb3VyY2VJZGVudGlmaWVyIGlkZW50aWZpZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBmUmVhZGluZ0V4dGVybmFsRFREID0gdHJ1ZTsKLSAgICB9IC8vIHN0YXJ0RXh0ZXJuYWxTdWJzZXQoQXVnbWVudGF0aW9ucykKLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIG5vdGlmaWVzIHRoZSBlbmQgb2YgYW4gZW50aXR5LiBUaGUgRFREIGhhcyB0aGUgcHNldWRvLW5hbWUKLSAgICAgKiBvZiAiW2R0ZF0iIGFuZCBwYXJhbWV0ZXIgZW50aXR5IG5hbWVzIHN0YXJ0IHdpdGggJyUnLgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gU2luY2UgdGhlIERURCBpcyBhbiBlbnRpdHksIHRoZSBoYW5kbGVyCi0gICAgICogd2lsbCBiZSBub3RpZmllZCBvZiB0aGUgZW5kIG9mIHRoZSBEVEQgZW50aXR5IGJ5IGNhbGxpbmcgdGhlCi0gICAgICogZW5kRW50aXR5IG1ldGhvZCB3aXRoIHRoZSBlbnRpdHkgbmFtZSAiW2R0ZF0iIDxlbT5hZnRlcjwvZW0+IGNhbGxpbmcKLSAgICAgKiB0aGUgZW5kRFREIG1ldGhvZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBlbnRpdHkuCi0gICAgICogQHBhcmFtIGF1Z3MgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbmRQYXJhbWV0ZXJFbnRpdHkoU3RyaW5nIG5hbWUsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgZlBFRGVwdGgtLTsKLSAgICAgICAgZlJlYWRpbmdFeHRlcm5hbERURCA9IGZQRW50aXR5U3RhY2tbZlBFRGVwdGhdOwotCi0gICAgfSAvLyBlbmRQYXJhbWV0ZXJFbnRpdHkoU3RyaW5nLEF1Z21lbnRhdGlvbnMpCi0KLSAgICAvKioKLSAgICAgKiBUaGUgZW5kIG9mIHRoZSBEVEQgZXh0ZXJuYWwgc3Vic2V0LgotICAgICAqCi0gICAgICogQHBhcmFtIGF1Z3MgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZEV4dGVybmFsU3Vic2V0KEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIGZSZWFkaW5nRXh0ZXJuYWxEVEQgPSBmYWxzZTsKLSAgICB9IC8vIGVuZEV4dGVybmFsU3Vic2V0KEF1Z21lbnRhdGlvbnMpCi0KLSAgICAvKioKLSAgICAgKiBBbiBlbGVtZW50IGRlY2xhcmF0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgICAgICAgICBUaGUgbmFtZSBvZiB0aGUgZWxlbWVudC4KLSAgICAgKiBAcGFyYW0gY29udGVudE1vZGVsIFRoZSBlbGVtZW50IGNvbnRlbnQgbW9kZWwuCi0gICAgICogQHBhcmFtIGF1Z3MgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbGVtZW50RGVjbChTdHJpbmcgbmFtZSwgU3RyaW5nIGNvbnRlbnRNb2RlbCwgQXVnbWVudGF0aW9ucyBhdWdzKQotICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLQotICAgICAgICBYTUxFbGVtZW50RGVjbCB0bXBFbGVtZW50RGVjbCA9IGZFbGVtZW50RGVjbFRhYi5nZXQobmFtZSkgOwotCi0gICAgICAgIC8vIGNoZWNrIGlmIGl0IGlzIGFscmVhZHkgZGVmaW5lZAotICAgICAgICBpZiAoIHRtcEVsZW1lbnREZWNsICE9IG51bGwgKSB7Ci0gICAgICAgICAgICBpZiAodG1wRWxlbWVudERlY2wudHlwZSA9PSAtMSkgewotICAgICAgICAgICAgICAgIGZDdXJyZW50RWxlbWVudEluZGV4ID0gZ2V0RWxlbWVudERlY2xJbmRleChuYW1lKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIC8vIGR1cGxpY2F0ZSBlbGVtZW50LCBpZ25vcmVkLgotICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIGZDdXJyZW50RWxlbWVudEluZGV4ID0gY3JlYXRlRWxlbWVudERlY2woKTsvL2NyZWF0ZSBlbGVtZW50IGRlY2wKLSAgICAgICAgfQotCi0gICAgICAgIFhNTEVsZW1lbnREZWNsIGVsZW1lbnREZWNsICAgICAgID0gbmV3IFhNTEVsZW1lbnREZWNsKCk7Ci0KLSAgICAgICAgZlFOYW1lLnNldFZhbHVlcyhudWxsLCBuYW1lLCBuYW1lLCBudWxsKTsKLQotICAgICAgICBlbGVtZW50RGVjbC5uYW1lLnNldFZhbHVlcyhmUU5hbWUpOwotCi0gICAgICAgIGVsZW1lbnREZWNsLmNvbnRlbnRNb2RlbFZhbGlkYXRvciA9IG51bGw7Ci0gICAgICAgIGVsZW1lbnREZWNsLnNjb3BlPSAtMTsKLSAgICAgICAgaWYgKGNvbnRlbnRNb2RlbC5lcXVhbHMoIkVNUFRZIikpIHsKLSAgICAgICAgICAgIGVsZW1lbnREZWNsLnR5cGUgPSBYTUxFbGVtZW50RGVjbC5UWVBFX0VNUFRZOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKGNvbnRlbnRNb2RlbC5lcXVhbHMoIkFOWSIpKSB7Ci0gICAgICAgICAgICBlbGVtZW50RGVjbC50eXBlID0gWE1MRWxlbWVudERlY2wuVFlQRV9BTlk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoY29udGVudE1vZGVsLnN0YXJ0c1dpdGgoIigiKSApIHsKLSAgICAgICAgICAgIGlmIChjb250ZW50TW9kZWwuaW5kZXhPZigiI1BDREFUQSIpID4gMCApIHsKLSAgICAgICAgICAgICAgICBlbGVtZW50RGVjbC50eXBlID0gWE1MRWxlbWVudERlY2wuVFlQRV9NSVhFRDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIGVsZW1lbnREZWNsLnR5cGUgPSBYTUxFbGVtZW50RGVjbC5UWVBFX0NISUxEUkVOOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLQotICAgICAgICAvL2FkZChvciBzZXQpIHRoaXMgZWxlbWVudERlY2wgdG8gdGhlIGxvY2FsIGNhY2hlCi0gICAgICAgIHRoaXMuZkVsZW1lbnREZWNsVGFiLnB1dChuYW1lLCBlbGVtZW50RGVjbCApOwotCi0gICAgICAgIGZFbGVtZW50RGVjbCA9IGVsZW1lbnREZWNsOwotICAgICAgICBhZGRDb250ZW50U3BlY1RvRWxlbWVudChlbGVtZW50RGVjbCk7Ci0KLSAgICAgICAgaWYgKCBERUJVRyApIHsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbiggICJuYW1lID0gIiArIGZFbGVtZW50RGVjbC5uYW1lLmxvY2FscGFydCApOwotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCAgIlR5cGUgPSAiICsgZkVsZW1lbnREZWNsLnR5cGUgKTsKLSAgICAgICAgfQotCi0gICAgICAgIHNldEVsZW1lbnREZWNsKGZDdXJyZW50RWxlbWVudEluZGV4LCBmRWxlbWVudERlY2wgKTsvL3NldCBpbnRlcm5hbCBzdHJ1Y3R1cmUKLQotICAgICAgICBpbnQgY2h1bmsgPSBmQ3VycmVudEVsZW1lbnRJbmRleCA+PiBDSFVOS19TSElGVDsKLSAgICAgICAgaW50IGluZGV4ID0gZkN1cnJlbnRFbGVtZW50SW5kZXggJiBDSFVOS19NQVNLOwotICAgICAgICBlbnN1cmVFbGVtZW50RGVjbENhcGFjaXR5KGNodW5rKTsKLSAgICAgICAgZkVsZW1lbnREZWNsSXNFeHRlcm5hbFtjaHVua11baW5kZXhdID0gKGZSZWFkaW5nRXh0ZXJuYWxEVEQgfHwgZlBFRGVwdGggPiAwKSA/IDEgOiAwOwotCi0gICAgfSAvLyBlbGVtZW50RGVjbChTdHJpbmcsU3RyaW5nKQotCi0gICAgLyoqCi0gICAgICogQW4gYXR0cmlidXRlIGRlY2xhcmF0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIGVsZW1lbnROYW1lICAgVGhlIG5hbWUgb2YgdGhlIGVsZW1lbnQgdGhhdCB0aGlzIGF0dHJpYnV0ZQotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGlzIGFzc29jaWF0ZWQgd2l0aC4KLSAgICAgKiBAcGFyYW0gYXR0cmlidXRlTmFtZSBUaGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlLgotICAgICAqIEBwYXJhbSB0eXBlICAgICAgICAgIFRoZSBhdHRyaWJ1dGUgdHlwZS4gVGhpcyB2YWx1ZSB3aWxsIGJlIG9uZSBvZgotICAgICAqICAgICAgICAgICAgICAgICAgICAgIHRoZSBmb2xsb3dpbmc6ICJDREFUQSIsICJFTlRJVFkiLCAiRU5USVRJRVMiLAotICAgICAqICAgICAgICAgICAgICAgICAgICAgICJFTlVNRVJBVElPTiIsICJJRCIsICJJRFJFRiIsICJJRFJFRlMiLAotICAgICAqICAgICAgICAgICAgICAgICAgICAgICJOTVRPS0VOIiwgIk5NVE9LRU5TIiwgb3IgIk5PVEFUSU9OIi4KLSAgICAgKiBAcGFyYW0gZW51bWVyYXRpb24gICBJZiB0aGUgdHlwZSBoYXMgdGhlIHZhbHVlICJFTlVNRVJBVElPTiIsIHRoaXMKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhcnJheSBob2xkcyB0aGUgYWxsb3dlZCBhdHRyaWJ1dGUgdmFsdWVzOwotICAgICAqICAgICAgICAgICAgICAgICAgICAgIG90aGVyd2lzZSwgdGhpcyBhcnJheSBpcyBudWxsLgotICAgICAqIEBwYXJhbSBkZWZhdWx0VHlwZSAgIFRoZSBhdHRyaWJ1dGUgZGVmYXVsdCB0eXBlLiBUaGlzIHZhbHVlIHdpbGwgYmUKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBvbmUgb2YgdGhlIGZvbGxvd2luZzogIiNGSVhFRCIsICIjSU1QTElFRCIsCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgIiNSRVFVSVJFRCIsIG9yIG51bGwuCi0gICAgICogQHBhcmFtIGRlZmF1bHRWYWx1ZSAgVGhlIGF0dHJpYnV0ZSBkZWZhdWx0IHZhbHVlLCBvciBudWxsIGlmIG5vCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdCB2YWx1ZSBpcyBzcGVjaWZpZWQuCi0gICAgICogQHBhcmFtIG5vbk5vcm1hbGl6ZWREZWZhdWx0VmFsdWUgIFRoZSBhdHRyaWJ1dGUgZGVmYXVsdCB2YWx1ZSB3aXRoIG5vIG5vcm1hbGl6YXRpb24KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBwZXJmb3JtZWQsIG9yIG51bGwgaWYgbm8gZGVmYXVsdCB2YWx1ZSBpcyBzcGVjaWZpZWQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYXVncyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGF0dHJpYnV0ZURlY2woU3RyaW5nIGVsZW1lbnROYW1lLCBTdHJpbmcgYXR0cmlidXRlTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyB0eXBlLCBTdHJpbmdbXSBlbnVtZXJhdGlvbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBkZWZhdWx0VHlwZSwgWE1MU3RyaW5nIGRlZmF1bHRWYWx1ZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTFN0cmluZyBub25Ob3JtYWxpemVkRGVmYXVsdFZhbHVlLCBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotCi0gICAgICAgIGlmICggdGhpcy5mRWxlbWVudERlY2xUYWIuY29udGFpbnNLZXkoZWxlbWVudE5hbWUpICkgewotICAgICAgICAgICAgLy9pZiBFbGVtZW50RGVjbCBoYXMgYWxyZWFkeSBiZWluZyBjcmVhdGVkIGluIHRoZSBHcmFtbWFyIHRoZW4gcmVtb3ZlIGZyb20gdGFibGUsCi0gICAgICAgICAgICAvL3RoaXMuZkVsZW1lbnREZWNsVGFiLnJlbW92ZSggKFN0cmluZykgZWxlbWVudE5hbWUgKTsKLSAgICAgICAgfQotICAgICAgICAvLyB0aGVuIGl0IGlzIGZvcndhcmQgcmVmZXJlbmNlIHRvIGEgZWxlbWVudCBkZWNsLCBjcmVhdGUgdGhlIGVsZW1lbnREZWNsIGZpcnN0LgotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIGZDdXJyZW50RWxlbWVudEluZGV4ID0gY3JlYXRlRWxlbWVudERlY2woKTsvL2NyZWF0ZSBlbGVtZW50IGRlY2wKLQotICAgICAgICAgICAgWE1MRWxlbWVudERlY2wgZWxlbWVudERlY2wgICAgICAgPSBuZXcgWE1MRWxlbWVudERlY2woKTsKLSAgICAgICAgICAgIGVsZW1lbnREZWNsLm5hbWUuc2V0VmFsdWVzKG51bGwsIGVsZW1lbnROYW1lLCBlbGVtZW50TmFtZSwgbnVsbCk7Ci0KLSAgICAgICAgICAgIGVsZW1lbnREZWNsLnNjb3BlPSAtMTsKLQotICAgICAgICAgICAgLy9hZGQob3Igc2V0KSB0aGlzIGVsZW1lbnREZWNsIHRvIHRoZSBsb2NhbCBjYWNoZQotICAgICAgICAgICAgdGhpcy5mRWxlbWVudERlY2xUYWIucHV0KGVsZW1lbnROYW1lLCBlbGVtZW50RGVjbCApOwotCi0gICAgICAgICAgICAvL3NldCBpbnRlcm5hbCBzdHJ1Y3R1cmUKLSAgICAgICAgICAgIHNldEVsZW1lbnREZWNsKGZDdXJyZW50RWxlbWVudEluZGV4LCBlbGVtZW50RGVjbCApOwotICAgICAgICB9Ci0KLSAgICAgICAgLy9HZXQgR3JhbW1hciBpbmRleCB0byBncmFtbWFyIGFycmF5Ci0gICAgICAgIGludCBlbGVtZW50SW5kZXggICAgICAgPSBnZXRFbGVtZW50RGVjbEluZGV4KGVsZW1lbnROYW1lKTsKLQotICAgICAgICAvL3JldHVybiwgd2hlbiBtb3JlIHRoYW4gb25lIGRlZmluaXRpb24gaXMgcHJvdmlkZWQgZm9yIHRoZSBzYW1lIGF0dHJpYnV0ZSBvZiBnaXZlbiBlbGVtZW50IHR5cGUKLSAgICAgICAgLy9vbmx5IHRoZSBmaXJzdCBkZWNsYXJhdGlvbiBpcyBiaW5kaW5nIGFuZCBsYXRlciBkZWNsYXJhdGlvbnMgYXJlIGlnbm9yZWQKLSAgICAgICAgaWYgKGdldEF0dHJpYnV0ZURlY2xJbmRleChlbGVtZW50SW5kZXgsIGF0dHJpYnV0ZU5hbWUpICE9IC0xKSB7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLQotICAgICAgICBmQ3VycmVudEF0dHJpYnV0ZUluZGV4ID0gY3JlYXRlQXR0cmlidXRlRGVjbCgpOy8vIENyZWF0ZSBjdXJyZW50IEF0dHJpYnV0ZSBEZWNsCi0KLSAgICAgICAgZlNpbXBsZVR5cGUuY2xlYXIoKTsKLSAgICAgICAgaWYgKCBkZWZhdWx0VHlwZSAhPSBudWxsICkgewotICAgICAgICAgICAgaWYgKCBkZWZhdWx0VHlwZS5lcXVhbHMoICIjRklYRUQiKSApIHsKLSAgICAgICAgICAgICAgICBmU2ltcGxlVHlwZS5kZWZhdWx0VHlwZSA9IFhNTFNpbXBsZVR5cGUuREVGQVVMVF9UWVBFX0ZJWEVEOwotICAgICAgICAgICAgfSBlbHNlIGlmICggZGVmYXVsdFR5cGUuZXF1YWxzKCAiI0lNUExJRUQiKSApIHsKLSAgICAgICAgICAgICAgICBmU2ltcGxlVHlwZS5kZWZhdWx0VHlwZSA9IFhNTFNpbXBsZVR5cGUuREVGQVVMVF9UWVBFX0lNUExJRUQ7Ci0gICAgICAgICAgICB9IGVsc2UgaWYgKCBkZWZhdWx0VHlwZS5lcXVhbHMoICIjUkVRVUlSRUQiKSApIHsKLSAgICAgICAgICAgICAgICBmU2ltcGxlVHlwZS5kZWZhdWx0VHlwZSA9IFhNTFNpbXBsZVR5cGUuREVGQVVMVF9UWVBFX1JFUVVJUkVEOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGlmICggREVCVUcgKSB7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oImRlZmF1bHR2YWx1ZSA9ICIgKyBkZWZhdWx0VmFsdWUudG9TdHJpbmcoKSApOwotICAgICAgICB9Ci0gICAgICAgIGZTaW1wbGVUeXBlLmRlZmF1bHRWYWx1ZSAgICAgID0gZGVmYXVsdFZhbHVlIT1udWxsID8gIGRlZmF1bHRWYWx1ZS50b1N0cmluZygpIDogbnVsbDsKLSAgICAgICAgZlNpbXBsZVR5cGUubm9uTm9ybWFsaXplZERlZmF1bHRWYWx1ZSAgICAgID0gbm9uTm9ybWFsaXplZERlZmF1bHRWYWx1ZSE9bnVsbCA/ICBub25Ob3JtYWxpemVkRGVmYXVsdFZhbHVlLnRvU3RyaW5nKCkgOiBudWxsOwotICAgICAgICBmU2ltcGxlVHlwZS5lbnVtZXJhdGlvbiAgICAgICA9IGVudW1lcmF0aW9uOwotCi0gICAgICAgIGlmICh0eXBlLmVxdWFscygiQ0RBVEEiKSkgewotICAgICAgICAgICAgZlNpbXBsZVR5cGUudHlwZSA9IFhNTFNpbXBsZVR5cGUuVFlQRV9DREFUQTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICggdHlwZS5lcXVhbHMoIklEIikgKSB7Ci0gICAgICAgICAgICBmU2ltcGxlVHlwZS50eXBlID0gWE1MU2ltcGxlVHlwZS5UWVBFX0lEOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKCB0eXBlLnN0YXJ0c1dpdGgoIklEUkVGIikgKSB7Ci0gICAgICAgICAgICBmU2ltcGxlVHlwZS50eXBlID0gWE1MU2ltcGxlVHlwZS5UWVBFX0lEUkVGOwotICAgICAgICAgICAgaWYgKHR5cGUuaW5kZXhPZigiUyIpID4gMCkgewotICAgICAgICAgICAgICAgIGZTaW1wbGVUeXBlLmxpc3QgPSB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKHR5cGUuZXF1YWxzKCJFTlRJVElFUyIpKSB7Ci0gICAgICAgICAgICBmU2ltcGxlVHlwZS50eXBlID0gWE1MU2ltcGxlVHlwZS5UWVBFX0VOVElUWTsKLSAgICAgICAgICAgIGZTaW1wbGVUeXBlLmxpc3QgPSB0cnVlOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKHR5cGUuZXF1YWxzKCJFTlRJVFkiKSkgewotICAgICAgICAgICAgZlNpbXBsZVR5cGUudHlwZSA9IFhNTFNpbXBsZVR5cGUuVFlQRV9FTlRJVFk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAodHlwZS5lcXVhbHMoIk5NVE9LRU5TIikpIHsKLSAgICAgICAgICAgIGZTaW1wbGVUeXBlLnR5cGUgPSBYTUxTaW1wbGVUeXBlLlRZUEVfTk1UT0tFTjsKLSAgICAgICAgICAgIGZTaW1wbGVUeXBlLmxpc3QgPSB0cnVlOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKHR5cGUuZXF1YWxzKCJOTVRPS0VOIikpIHsKLSAgICAgICAgICAgIGZTaW1wbGVUeXBlLnR5cGUgPSBYTUxTaW1wbGVUeXBlLlRZUEVfTk1UT0tFTjsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICh0eXBlLnN0YXJ0c1dpdGgoIk5PVEFUSU9OIikgKSB7Ci0gICAgICAgICAgICBmU2ltcGxlVHlwZS50eXBlID0gWE1MU2ltcGxlVHlwZS5UWVBFX05PVEFUSU9OOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKHR5cGUuc3RhcnRzV2l0aCgiRU5VTUVSQVRJT04iKSApIHsKLSAgICAgICAgICAgIGZTaW1wbGVUeXBlLnR5cGUgPSBYTUxTaW1wbGVUeXBlLlRZUEVfRU5VTUVSQVRJT047Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAvLyBSRVZJU0lUOiBSZXBvcnQgZXJyb3IgbWVzc2FnZS4gLUFjCi0gICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIiEhISB1bmtub3duIGF0dHJpYnV0ZSB0eXBlICIrdHlwZSk7Ci0gICAgICAgIH0KLSAgICAgICAgLy8gUkVWSVNJVDogVGhlIGRhdGF0eXBlIHNob3VsZCBiZSBzdG9yZWQgd2l0aCB0aGUgYXR0cmlidXRlIHZhbHVlCi0gICAgICAgIC8vICAgICAgICAgIGFuZCBub3Qgc3BlY2lhbC1jYXNlZCBpbiB0aGUgWE1MVmFsaWRhdG9yLiAtQWMKLSAgICAgICAgLy9mU2ltcGxlVHlwZS5kYXRhdHlwZVZhbGlkYXRvciA9IGZEYXRhdHlwZVZhbGlkYXRvckZhY3RvcnkuY3JlYXRlRGF0YXR5cGVWYWxpZGF0b3IodHlwZSwgbnVsbCwgZmFjZXRzLCBmU2ltcGxlVHlwZS5saXN0KTsKLQotICAgICAgICBmUU5hbWUuc2V0VmFsdWVzKG51bGwsIGF0dHJpYnV0ZU5hbWUsIGF0dHJpYnV0ZU5hbWUsIG51bGwpOwotICAgICAgICBmQXR0cmlidXRlRGVjbC5zZXRWYWx1ZXMoIGZRTmFtZSwgZlNpbXBsZVR5cGUsIGZhbHNlICk7Ci0KLSAgICAgICAgc2V0QXR0cmlidXRlRGVjbChlbGVtZW50SW5kZXgsIGZDdXJyZW50QXR0cmlidXRlSW5kZXgsIGZBdHRyaWJ1dGVEZWNsKTsKLQotICAgICAgICBpbnQgY2h1bmsgPSBmQ3VycmVudEF0dHJpYnV0ZUluZGV4ID4+IENIVU5LX1NISUZUOwotICAgICAgICBpbnQgaW5kZXggPSBmQ3VycmVudEF0dHJpYnV0ZUluZGV4ICYgQ0hVTktfTUFTSzsKLSAgICAgICAgZW5zdXJlQXR0cmlidXRlRGVjbENhcGFjaXR5KGNodW5rKTsKLSAgICAgICAgZkF0dHJpYnV0ZURlY2xJc0V4dGVybmFsW2NodW5rXVtpbmRleF0gPSAoZlJlYWRpbmdFeHRlcm5hbERURCB8fCBmUEVEZXB0aCA+IDApID8gIDEgOiAwOwotCi0gICAgfSAvLyBhdHRyaWJ1dGVEZWNsKFN0cmluZyxTdHJpbmcsU3RyaW5nLFN0cmluZ1tdLFN0cmluZyxYTUxTdHJpbmcsWE1MU3RyaW5nLCBBdWdtZW50YXRpb25zKQotCi0gICAgLyoqCi0gICAgICogQW4gaW50ZXJuYWwgZW50aXR5IGRlY2xhcmF0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGVudGl0eS4gUGFyYW1ldGVyIGVudGl0eSBuYW1lcyBzdGFydCB3aXRoCi0gICAgICogICAgICAgICAgICAgJyUnLCB3aGVyZWFzIHRoZSBuYW1lIG9mIGEgZ2VuZXJhbCBlbnRpdHkgaXMganVzdCB0aGUKLSAgICAgKiAgICAgICAgICAgICBlbnRpdHkgbmFtZS4KLSAgICAgKiBAcGFyYW0gdGV4dCBUaGUgdmFsdWUgb2YgdGhlIGVudGl0eS4KLSAgICAgKiBAcGFyYW0gbm9uTm9ybWFsaXplZFRleHQgVGhlIG5vbi1ub3JtYWxpemVkIHZhbHVlIG9mIHRoZSBlbnRpdHkuIFRoaXMKLSAgICAgKiAgICAgICAgICAgICB2YWx1ZSBjb250YWlucyB0aGUgc2FtZSBzZXF1ZW5jZSBvZiBjaGFyYWN0ZXJzIHRoYXQgd2FzIGluCi0gICAgICogICAgICAgICAgICAgdGhlIGludGVybmFsIGVudGl0eSBkZWNsYXJhdGlvbiwgd2l0aG91dCBhbnkgZW50aXR5Ci0gICAgICogICAgICAgICAgICAgcmVmZXJlbmNlcyBleHBhbmRlZC4KLSAgICAgKiBAcGFyYW0gYXVncyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGludGVybmFsRW50aXR5RGVjbChTdHJpbmcgbmFtZSwgWE1MU3RyaW5nIHRleHQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTFN0cmluZyBub25Ob3JtYWxpemVkVGV4dCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLQotICAgICAgICBpbnQgZW50aXR5SW5kZXggPSBnZXRFbnRpdHlEZWNsSW5kZXgobmFtZSk7Ci0gICAgICAgIGlmKCBlbnRpdHlJbmRleCA9PSAtMSl7Ci0gICAgICAgICAgICBlbnRpdHlJbmRleCA9IGNyZWF0ZUVudGl0eURlY2woKTsKLSAgICAgICAgICAgIGJvb2xlYW4gaXNQRSA9IG5hbWUuc3RhcnRzV2l0aCgiJSIpOwotICAgICAgICAgICAgYm9vbGVhbiBpbkV4dGVybmFsID0gKGZSZWFkaW5nRXh0ZXJuYWxEVEQgfHwgZlBFRGVwdGggPiAwKTsKLSAgICAgICAgICAgIFhNTEVudGl0eURlY2wgIGVudGl0eURlY2wgPSBuZXcgWE1MRW50aXR5RGVjbCgpOwotICAgICAgICAgICAgZW50aXR5RGVjbC5zZXRWYWx1ZXMobmFtZSxudWxsLG51bGwsIG51bGwsIG51bGwsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0LnRvU3RyaW5nKCksIGlzUEUsIGluRXh0ZXJuYWwpOwotCi0gICAgICAgICAgICBzZXRFbnRpdHlEZWNsKGVudGl0eUluZGV4LCBlbnRpdHlEZWNsKTsKLSAgICAgICAgfQotCi0gICAgfSAvLyBpbnRlcm5hbEVudGl0eURlY2woU3RyaW5nLFhNTFN0cmluZyxYTUxTdHJpbmcpCi0KLSAgICAvKioKLSAgICAgKiBBbiBleHRlcm5hbCBlbnRpdHkgZGVjbGFyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSAgICAgVGhlIG5hbWUgb2YgdGhlIGVudGl0eS4gUGFyYW1ldGVyIGVudGl0eSBuYW1lcyBzdGFydAotICAgICAqICAgICAgICAgICAgICAgICB3aXRoICclJywgd2hlcmVhcyB0aGUgbmFtZSBvZiBhIGdlbmVyYWwgZW50aXR5IGlzIGp1c3QKLSAgICAgKiAgICAgICAgICAgICAgICAgdGhlIGVudGl0eSBuYW1lLgotICAgICAqIEBwYXJhbSBpZGVudGlmaWVyICAgIEFuIG9iamVjdCBjb250YWluaW5nIGFsbCBsb2NhdGlvbiBpbmZvcm1hdGlvbgotICAgICAqICAgICAgICAgICAgICAgICAgICAgIHBlcnRpbmVudCB0byB0aGlzIGV4dGVybmFsIGVudGl0eSBkZWNsYXJhdGlvbi4KLSAgICAgKiBAcGFyYW0gYXVncyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGV4dGVybmFsRW50aXR5RGVjbChTdHJpbmcgbmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MUmVzb3VyY2VJZGVudGlmaWVyIGlkZW50aWZpZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgaW50IGVudGl0eUluZGV4ID0gZ2V0RW50aXR5RGVjbEluZGV4KG5hbWUpOwotICAgICAgICBpZiggZW50aXR5SW5kZXggPT0gLTEpewotICAgICAgICAgICAgZW50aXR5SW5kZXggPSBjcmVhdGVFbnRpdHlEZWNsKCk7Ci0gICAgICAgICAgICBib29sZWFuIGlzUEUgPSBuYW1lLnN0YXJ0c1dpdGgoIiUiKTsKLSAgICAgICAgICAgIGJvb2xlYW4gaW5FeHRlcm5hbCA9IChmUmVhZGluZ0V4dGVybmFsRFREIHx8IGZQRURlcHRoID4gMCk7Ci0KLSAgICAgICAgICAgIFhNTEVudGl0eURlY2wgIGVudGl0eURlY2wgPSBuZXcgWE1MRW50aXR5RGVjbCgpOwotICAgICAgICAgICAgZW50aXR5RGVjbC5zZXRWYWx1ZXMobmFtZSwgaWRlbnRpZmllci5nZXRQdWJsaWNJZCgpLCBpZGVudGlmaWVyLmdldExpdGVyYWxTeXN0ZW1JZCgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZGVudGlmaWVyLmdldEJhc2VTeXN0ZW1JZCgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLCBudWxsLCBpc1BFLCBpbkV4dGVybmFsKTsKLQotICAgICAgICAgICAgc2V0RW50aXR5RGVjbChlbnRpdHlJbmRleCwgZW50aXR5RGVjbCk7Ci0gICAgICAgIH0KLSAgICB9IC8vIGV4dGVybmFsRW50aXR5RGVjbChTdHJpbmcsIFhNTFJlc291cmNlSWRlbnRpZmllciwgQXVnbWVudGF0aW9ucykKLQotICAgIC8qKgotICAgICAqIEFuIHVucGFyc2VkIGVudGl0eSBkZWNsYXJhdGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lICAgICBUaGUgbmFtZSBvZiB0aGUgZW50aXR5LgotICAgICAqIEBwYXJhbSBpZGVudGlmaWVyICAgIEFuIG9iamVjdCBjb250YWluaW5nIGFsbCBsb2NhdGlvbiBpbmZvcm1hdGlvbgotICAgICAqICAgICAgICAgICAgICAgICAgICAgIHBlcnRpbmVudCB0byB0aGlzIGVudGl0eS4KLSAgICAgKiBAcGFyYW0gbm90YXRpb24gVGhlIG5hbWUgb2YgdGhlIG5vdGF0aW9uLgotICAgICAqIEBwYXJhbSBhdWdzIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdW5wYXJzZWRFbnRpdHlEZWNsKFN0cmluZyBuYW1lLCBYTUxSZXNvdXJjZUlkZW50aWZpZXIgaWRlbnRpZmllciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG5vdGF0aW9uLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotCi0gICAgICAgIFhNTEVudGl0eURlY2wgIGVudGl0eURlY2wgPSBuZXcgWE1MRW50aXR5RGVjbCgpOwotICAgICAgICBib29sZWFuIGlzUEUgPSBuYW1lLnN0YXJ0c1dpdGgoIiUiKTsKLSAgICAgICAgYm9vbGVhbiBpbkV4dGVybmFsID0gKGZSZWFkaW5nRXh0ZXJuYWxEVEQgfHwgZlBFRGVwdGggPiAwKTsKLQotICAgICAgICBlbnRpdHlEZWNsLnNldFZhbHVlcyhuYW1lLGlkZW50aWZpZXIuZ2V0UHVibGljSWQoKSxpZGVudGlmaWVyLmdldExpdGVyYWxTeXN0ZW1JZCgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlkZW50aWZpZXIuZ2V0QmFzZVN5c3RlbUlkKCksIG5vdGF0aW9uLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsIGlzUEUsIGluRXh0ZXJuYWwpOwotICAgICAgICBpbnQgZW50aXR5SW5kZXggPSBnZXRFbnRpdHlEZWNsSW5kZXgobmFtZSk7Ci0gICAgICAgIGlmIChlbnRpdHlJbmRleCA9PSAtMSkgewotICAgICAgICAgICAgZW50aXR5SW5kZXggPSBjcmVhdGVFbnRpdHlEZWNsKCk7Ci0gICAgICAgICAgICBzZXRFbnRpdHlEZWNsKGVudGl0eUluZGV4LCBlbnRpdHlEZWNsKTsKLSAgICAgICAgfQotCi0gICAgfSAvLyB1bnBhcnNlZEVudGl0eURlY2woU3RyaW5nLFN0cmluZ1hNTFJlc291cmNlSWRlbnRpZmllcixBdWdtZW50YXRpb25zKQotCi0gICAgLyoqCi0gICAgICogQSBub3RhdGlvbiBkZWNsYXJhdGlvbgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgICAgIFRoZSBuYW1lIG9mIHRoZSBub3RhdGlvbi4KLSAgICAgKiBAcGFyYW0gaWRlbnRpZmllciAgICBBbiBvYmplY3QgY29udGFpbmluZyBhbGwgbG9jYXRpb24gaW5mb3JtYXRpb24KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBwZXJ0aW5lbnQgdG8gdGhpcyBub3RhdGlvbi4KLSAgICAgKiBAcGFyYW0gYXVncyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIG5vdGF0aW9uRGVjbChTdHJpbmcgbmFtZSwgWE1MUmVzb3VyY2VJZGVudGlmaWVyIGlkZW50aWZpZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgWE1MTm90YXRpb25EZWNsICBub3RhdGlvbkRlY2wgPSBuZXcgWE1MTm90YXRpb25EZWNsKCk7Ci0gICAgICAgIG5vdGF0aW9uRGVjbC5zZXRWYWx1ZXMobmFtZSxpZGVudGlmaWVyLmdldFB1YmxpY0lkKCksaWRlbnRpZmllci5nZXRMaXRlcmFsU3lzdGVtSWQoKSwKLSAgICAgICAgICAgICAgICBpZGVudGlmaWVyLmdldEJhc2VTeXN0ZW1JZCgpKTsKLSAgICAgICAgaW50IG5vdGF0aW9uSW5kZXggPSBnZXROb3RhdGlvbkRlY2xJbmRleChuYW1lKTsKLSAgICAgICAgaWYgKG5vdGF0aW9uSW5kZXggPT0gLTEpIHsKLSAgICAgICAgICAgIG5vdGF0aW9uSW5kZXggPSBjcmVhdGVOb3RhdGlvbkRlY2woKTsKLSAgICAgICAgICAgIHNldE5vdGF0aW9uRGVjbChub3RhdGlvbkluZGV4LCBub3RhdGlvbkRlY2wpOwotICAgICAgICB9Ci0KLSAgICB9IC8vIG5vdGF0aW9uRGVjbChTdHJpbmcsWE1MUmVzb3VyY2VJZGVudGlmaWVyLEF1Z21lbnRhdGlvbnMpCi0KLSAgICAvKioKLSAgICAgKiBUaGUgZW5kIG9mIHRoZSBEVEQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYXVncyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZERURChBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBmSXNJbW11dGFibGUgPSB0cnVlOwotICAgICAgICAvLyBtYWtlIHN1cmUgb3VyIGRlc2NyaXB0aW9uIGNvbnRhaW5zIHVzZWZ1bCBzdHVmZi4uLgotICAgICAgICBpZiAoZkdyYW1tYXJEZXNjcmlwdGlvbi5nZXRSb290TmFtZSgpID09IG51bGwpIHsKLSAgICAgICAgICAgIC8vIHdlIGRvbid0IGtub3cgd2hhdCB0aGUgcm9vdCBpczsgc28gdXNlIHBvc3NpYmxlUm9vdHMuLi4KLSAgICAgICAgICAgIGludCBjaHVuaywgaW5kZXggPSAwOwotICAgICAgICAgICAgU3RyaW5nIGN1cnJOYW1lID0gbnVsbDsKLSAgICAgICAgICAgIGZpbmFsIGludCBzaXplID0gZkVsZW1lbnREZWNsQ291bnQ7Ci0gICAgICAgICAgICBBcnJheUxpc3QgZWxlbWVudHMgPSBuZXcgQXJyYXlMaXN0KHNpemUpOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyArK2kpIHsKLSAgICAgICAgICAgICAgICBjaHVuayA9IGkgPj4gQ0hVTktfU0hJRlQ7Ci0gICAgICAgICAgICAgICAgaW5kZXggPSBpICYgQ0hVTktfTUFTSzsKLSAgICAgICAgICAgICAgICBjdXJyTmFtZSA9IGZFbGVtZW50RGVjbE5hbWVbY2h1bmtdW2luZGV4XS5yYXduYW1lOwotICAgICAgICAgICAgICAgIGVsZW1lbnRzLmFkZChjdXJyTmFtZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmR3JhbW1hckRlc2NyaXB0aW9uLnNldFBvc3NpYmxlUm9vdHMoZWxlbWVudHMpOwotICAgICAgICB9Ci0gICAgfSAvLyBlbmREVEQoKQotCi0gICAgLy8gc2V0cyB0aGUgc291cmNlIG9mIHRoaXMgaGFuZGxlcgotICAgIHB1YmxpYyB2b2lkIHNldERURFNvdXJjZShYTUxEVERTb3VyY2Ugc291cmNlKSB7Ci0gICAgICAgIGZEVERTb3VyY2UgPSBzb3VyY2U7Ci0gICAgfSAvLyBzZXREVERTb3VyY2UoWE1MRFREU291cmNlKQotCi0gICAgLy8gcmV0dXJucyB0aGUgc291cmNlIG9mIHRoaXMgaGFuZGxlcgotICAgIHB1YmxpYyBYTUxEVERTb3VyY2UgZ2V0RFREU291cmNlKCkgewotICAgICAgICByZXR1cm4gZkRURFNvdXJjZTsKLSAgICB9IC8vIGdldERURFNvdXJjZSgpOiAgWE1MRFREU291cmNlCi0KLSAgICAvLyBuby1vcCBtZXRob2RzCi0KLSAgICAvKioKLSAgICAgKiBOb3RpZmllcyBvZiB0aGUgcHJlc2VuY2Ugb2YgYSBUZXh0RGVjbCBsaW5lIGluIGFuIGVudGl0eS4gSWYgcHJlc2VudCwKLSAgICAgKiB0aGlzIG1ldGhvZCB3aWxsIGJlIGNhbGxlZCBpbW1lZGlhdGVseSBmb2xsb3dpbmcgdGhlIHN0YXJ0RW50aXR5IGNhbGwuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGlzIG1ldGhvZCBpcyBvbmx5IGNhbGxlZCBmb3IgZXh0ZXJuYWwKLSAgICAgKiBwYXJhbWV0ZXIgZW50aXRpZXMgcmVmZXJlbmNlZCBpbiB0aGUgRFRELgotICAgICAqCi0gICAgICogQHBhcmFtIHZlcnNpb24gIFRoZSBYTUwgdmVyc2lvbiwgb3IgbnVsbCBpZiBub3Qgc3BlY2lmaWVkLgotICAgICAqIEBwYXJhbSBlbmNvZGluZyBUaGUgSUFOQSBlbmNvZGluZyBuYW1lIG9mIHRoZSBlbnRpdHkuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYXVncyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRleHREZWNsKFN0cmluZyB2ZXJzaW9uLCBTdHJpbmcgZW5jb2RpbmcsIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7fQotCi0gICAgLyoqCi0gICAgICogQSBjb21tZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIHRleHQgVGhlIHRleHQgaW4gdGhlIGNvbW1lbnQuCi0gICAgICogQHBhcmFtIGF1Z3MgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBhcHBsaWNhdGlvbiB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY29tbWVudChYTUxTdHJpbmcgdGV4dCwgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHt9Ci0KLSAgICAvKioKLSAgICAgKiBBIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24uIFByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb25zIGNvbnNpc3Qgb2YgYQotICAgICAqIHRhcmdldCBuYW1lIGFuZCwgb3B0aW9uYWxseSwgdGV4dCBkYXRhLiBUaGUgZGF0YSBpcyBvbmx5IG1lYW5pbmdmdWwKLSAgICAgKiB0byB0aGUgYXBwbGljYXRpb24uCi0gICAgICogPHA+Ci0gICAgICogVHlwaWNhbGx5LCBhIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24ncyBkYXRhIHdpbGwgY29udGFpbiBhIHNlcmllcwotICAgICAqIG9mIHBzZXVkby1hdHRyaWJ1dGVzLiBUaGVzZSBwc2V1ZG8tYXR0cmlidXRlcyBmb2xsb3cgdGhlIGZvcm0gb2YKLSAgICAgKiBlbGVtZW50IGF0dHJpYnV0ZXMgYnV0IGFyZSA8c3Ryb25nPm5vdDwvc3Ryb25nPiBwYXJzZWQgb3IgcHJlc2VudGVkCi0gICAgICogdG8gdGhlIGFwcGxpY2F0aW9uIGFzIGFueXRoaW5nIG90aGVyIHRoYW4gdGV4dC4gVGhlIGFwcGxpY2F0aW9uIGlzCi0gICAgICogcmVzcG9uc2libGUgZm9yIHBhcnNpbmcgdGhlIGRhdGEuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdGFyZ2V0IFRoZSB0YXJnZXQuCi0gICAgICogQHBhcmFtIGRhdGEgICBUaGUgZGF0YSBvciBudWxsIGlmIG5vbmUgc3BlY2lmaWVkLgotICAgICAqIEBwYXJhbSBhdWdzIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcHJvY2Vzc2luZ0luc3RydWN0aW9uKFN0cmluZyB0YXJnZXQsIFhNTFN0cmluZyBkYXRhLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24ge30KLQotICAgIC8qKgotICAgICAqIFRoZSBzdGFydCBvZiBhbiBhdHRyaWJ1dGUgbGlzdC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlbGVtZW50TmFtZSBUaGUgbmFtZSBvZiB0aGUgZWxlbWVudCB0aGF0IHRoaXMgYXR0cmlidXRlCi0gICAgICogICAgICAgICAgICAgICAgICAgIGxpc3QgaXMgYXNzb2NpYXRlZCB3aXRoLgotICAgICAqIEBwYXJhbSBhdWdzIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnRBdHRsaXN0KFN0cmluZyBlbGVtZW50TmFtZSwgQXVnbWVudGF0aW9ucyBhdWdzKQotICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHt9Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgZW5kIG9mIGFuIGF0dHJpYnV0ZSBsaXN0LgotICAgICAqIEBwYXJhbSBhdWdzIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kQXR0bGlzdChBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24ge30KLQotICAgIC8qKgotICAgICAqIFRoZSBzdGFydCBvZiBhIGNvbmRpdGlvbmFsIHNlY3Rpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdHlwZSBUaGUgdHlwZSBvZiB0aGUgY29uZGl0aW9uYWwgc2VjdGlvbi4gVGhpcyB2YWx1ZSB3aWxsCi0gICAgICogICAgICAgICAgICAgZWl0aGVyIGJlIENPTkRJVElPTkFMX0lOQ0xVREUgb3IgQ09ORElUSU9OQUxfSUdOT1JFLgotICAgICAqIEBwYXJhbSBhdWdzIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICoKLSAgICAgKiBAc2VlIFhNTERUREhhbmRsZXIjQ09ORElUSU9OQUxfSU5DTFVERQotICAgICAqIEBzZWUgWE1MRFRESGFuZGxlciNDT05ESVRJT05BTF9JR05PUkUKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydENvbmRpdGlvbmFsKHNob3J0IHR5cGUsIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7fQotCi0gICAgLyoqCi0gICAgICogQ2hhcmFjdGVycyB3aXRoaW4gYW4gSUdOT1JFIGNvbmRpdGlvbmFsIHNlY3Rpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdGV4dCBUaGUgaWdub3JlZCB0ZXh0LgotICAgICAqIEBwYXJhbSBhdWdzIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBpZ25vcmVkQ2hhcmFjdGVycyhYTUxTdHJpbmcgdGV4dCwgQXVnbWVudGF0aW9ucyBhdWdzKQotICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHt9Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgZW5kIG9mIGEgY29uZGl0aW9uYWwgc2VjdGlvbi4KLSAgICAgKiBAcGFyYW0gYXVncyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZENvbmRpdGlvbmFsKEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7fQotCi0gICAgLy8KLSAgICAvLyBYTUxEVERDb250ZW50TW9kZWxIYW5kbGVyIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLy8gc2V0IGNvbnRlbnQgbW9kZWwgc291cmNlCi0gICAgcHVibGljIHZvaWQgc2V0RFREQ29udGVudE1vZGVsU291cmNlKFhNTERURENvbnRlbnRNb2RlbFNvdXJjZSBzb3VyY2UpIHsKLSAgICAgICAgZkRURENvbnRlbnRNb2RlbFNvdXJjZSA9IHNvdXJjZTsKLSAgICB9Ci0KLSAgICAvLyBnZXQgY29udGVudCBtb2RlbCBzb3VyY2UKLSAgICBwdWJsaWMgWE1MRFREQ29udGVudE1vZGVsU291cmNlIGdldERURENvbnRlbnRNb2RlbFNvdXJjZSgpIHsKLSAgICAgICAgcmV0dXJuIGZEVERDb250ZW50TW9kZWxTb3VyY2U7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhlIHN0YXJ0IG9mIGEgY29udGVudCBtb2RlbC4gRGVwZW5kaW5nIG9uIHRoZSB0eXBlIG9mIHRoZSBjb250ZW50Ci0gICAgICogbW9kZWwsIHNwZWNpZmljIG1ldGhvZHMgbWF5IGJlIGNhbGxlZCBiZXR3ZWVuIHRoZSBjYWxsIHRvIHRoZQotICAgICAqIHN0YXJ0Q29udGVudE1vZGVsIG1ldGhvZCBhbmQgdGhlIGNhbGwgdG8gdGhlIGVuZENvbnRlbnRNb2RlbCBtZXRob2QuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZWxlbWVudE5hbWUgVGhlIG5hbWUgb2YgdGhlIGVsZW1lbnQuCi0gICAgICogQHBhcmFtIGF1Z3MgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydENvbnRlbnRNb2RlbChTdHJpbmcgZWxlbWVudE5hbWUsIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgWE1MRWxlbWVudERlY2wgZWxlbWVudERlY2wgPSB0aGlzLmZFbGVtZW50RGVjbFRhYi5nZXQoZWxlbWVudE5hbWUpOwotICAgICAgICBpZiAoIGVsZW1lbnREZWNsICE9IG51bGwgKSB7Ci0gICAgICAgICAgICBmRWxlbWVudERlY2wgPSBlbGVtZW50RGVjbDsKLSAgICAgICAgfQotICAgICAgICBmRGVwdGggPSAwOwotICAgICAgICBpbml0aWFsaXplQ29udGVudE1vZGVsU3RhY2soKTsKLQotICAgIH0gLy8gc3RhcnRDb250ZW50TW9kZWwoU3RyaW5nKQotCi0gICAgLyoqCi0gICAgICogQSBzdGFydCBvZiBlaXRoZXIgYSBtaXhlZCBvciBjaGlsZHJlbiBjb250ZW50IG1vZGVsLiBBIG1peGVkCi0gICAgICogY29udGVudCBtb2RlbCB3aWxsIGltbWVkaWF0ZWx5IGJlIGZvbGxvd2VkIGJ5IGEgY2FsbCB0byB0aGUKLSAgICAgKiA8Y29kZT5wY2RhdGEoKTwvY29kZT4gbWV0aG9kLiBBIGNoaWxkcmVuIGNvbnRlbnQgbW9kZWwgd2lsbAotICAgICAqIGNvbnRhaW4gYWRkaXRpb25hbCBncm91cHMgYW5kL29yIGVsZW1lbnRzLgotICAgICAqCi0gICAgICogQHBhcmFtIGF1Z3MgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKgotICAgICAqIEBzZWUgI2FueQotICAgICAqIEBzZWUgI2VtcHR5Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnRHcm91cChBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBmRGVwdGgrKzsKLSAgICAgICAgaW5pdGlhbGl6ZUNvbnRlbnRNb2RlbFN0YWNrKCk7Ci0gICAgICAgIGZNaXhlZCA9IGZhbHNlOwotICAgIH0gLy8gc3RhcnRHcm91cCgpCi0KLSAgICAvKioKLSAgICAgKiBUaGUgYXBwZWFyYW5jZSBvZiAiI1BDREFUQSIgd2l0aGluIGEgZ3JvdXAgc2lnbmlmeWluZyBhCi0gICAgICogbWl4ZWQgY29udGVudCBtb2RlbC4gVGhpcyBtZXRob2Qgd2lsbCBiZSB0aGUgZmlyc3QgY2FsbGVkCi0gICAgICogZm9sbG93aW5nIHRoZSBjb250ZW50IG1vZGVsJ3MgPGNvZGU+c3RhcnRHcm91cCgpPC9jb2RlPi4KLSAgICAgKgotICAgICAqQHBhcmFtIGF1Z3MgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqCi0gICAgICogQHNlZSAjc3RhcnRHcm91cAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHBjZGF0YShBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBmTWl4ZWQgPSB0cnVlOwotICAgIH0gLy8gcGNkYXRhKCkKLQotICAgIC8qKgotICAgICAqIEEgcmVmZXJlbmNlZCBlbGVtZW50IGluIGEgbWl4ZWQgb3IgY2hpbGRyZW4gY29udGVudCBtb2RlbC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlbGVtZW50TmFtZSBUaGUgbmFtZSBvZiB0aGUgcmVmZXJlbmNlZCBlbGVtZW50LgotICAgICAqIEBwYXJhbSBhdWdzIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbGVtZW50KFN0cmluZyBlbGVtZW50TmFtZSwgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKGZNaXhlZCkgewotICAgICAgICAgICAgaWYgKGZOb2RlSW5kZXhTdGFja1tmRGVwdGhdID09IC0xICkgewotICAgICAgICAgICAgICAgIGZOb2RlSW5kZXhTdGFja1tmRGVwdGhdID0gYWRkVW5pcXVlTGVhZk5vZGUoZWxlbWVudE5hbWUpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgZk5vZGVJbmRleFN0YWNrW2ZEZXB0aF0gPSBhZGRDb250ZW50U3BlY05vZGUoWE1MQ29udGVudFNwZWMuQ09OVEVOVFNQRUNOT0RFX0NIT0lDRSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmTm9kZUluZGV4U3RhY2tbZkRlcHRoXSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRVbmlxdWVMZWFmTm9kZShlbGVtZW50TmFtZSkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgZk5vZGVJbmRleFN0YWNrW2ZEZXB0aF0gPSBhZGRDb250ZW50U3BlY05vZGUoWE1MQ29udGVudFNwZWMuQ09OVEVOVFNQRUNOT0RFX0xFQUYsIGVsZW1lbnROYW1lKTsKLSAgICAgICAgfQotICAgIH0gLy8gZWxlbWVudChTdHJpbmcpCi0KLSAgICAvKioKLSAgICAgKiBUaGUgc2VwYXJhdG9yIGJldHdlZW4gY2hvaWNlcyBvciBzZXF1ZW5jZXMgb2YgYSBtaXhlZCBvciBjaGlsZHJlbgotICAgICAqIGNvbnRlbnQgbW9kZWwuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc2VwYXJhdG9yIFRoZSB0eXBlIG9mIGNoaWxkcmVuIHNlcGFyYXRvci4KLSAgICAgKiBAcGFyYW0gYXVncyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqCi0gICAgICogQHNlZSBvcmcuYXBhY2hlLnhlcmNlcy54bmkuWE1MRFREQ29udGVudE1vZGVsSGFuZGxlciNTRVBBUkFUT1JfQ0hPSUNFCi0gICAgICogQHNlZSBvcmcuYXBhY2hlLnhlcmNlcy54bmkuWE1MRFREQ29udGVudE1vZGVsSGFuZGxlciNTRVBBUkFUT1JfU0VRVUVOQ0UKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXBhcmF0b3Ioc2hvcnQgc2VwYXJhdG9yLCBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotCi0gICAgICAgIGlmICghZk1peGVkKSB7Ci0gICAgICAgICAgICBpZiAoZk9wU3RhY2tbZkRlcHRoXSAhPSBYTUxDb250ZW50U3BlYy5DT05URU5UU1BFQ05PREVfU0VRICYmIHNlcGFyYXRvciA9PSBYTUxEVERDb250ZW50TW9kZWxIYW5kbGVyLlNFUEFSQVRPUl9DSE9JQ0UgKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGZQcmV2Tm9kZUluZGV4U3RhY2tbZkRlcHRoXSAhPSAtMSkgewotICAgICAgICAgICAgICAgICAgICBmTm9kZUluZGV4U3RhY2tbZkRlcHRoXSA9IGFkZENvbnRlbnRTcGVjTm9kZShmT3BTdGFja1tmRGVwdGhdLCBmUHJldk5vZGVJbmRleFN0YWNrW2ZEZXB0aF0sIGZOb2RlSW5kZXhTdGFja1tmRGVwdGhdKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZlByZXZOb2RlSW5kZXhTdGFja1tmRGVwdGhdID0gZk5vZGVJbmRleFN0YWNrW2ZEZXB0aF07Ci0gICAgICAgICAgICAgICAgZk9wU3RhY2tbZkRlcHRoXSA9IFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9DSE9JQ0U7Ci0gICAgICAgICAgICB9IGVsc2UgaWYgKGZPcFN0YWNrW2ZEZXB0aF0gIT0gWE1MQ29udGVudFNwZWMuQ09OVEVOVFNQRUNOT0RFX0NIT0lDRSAmJiBzZXBhcmF0b3IgPT0gWE1MRFREQ29udGVudE1vZGVsSGFuZGxlci5TRVBBUkFUT1JfU0VRVUVOQ0UpIHsKLSAgICAgICAgICAgICAgICBpZiAoZlByZXZOb2RlSW5kZXhTdGFja1tmRGVwdGhdICE9IC0xKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZOb2RlSW5kZXhTdGFja1tmRGVwdGhdID0gYWRkQ29udGVudFNwZWNOb2RlKGZPcFN0YWNrW2ZEZXB0aF0sIGZQcmV2Tm9kZUluZGV4U3RhY2tbZkRlcHRoXSwgZk5vZGVJbmRleFN0YWNrW2ZEZXB0aF0pOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBmUHJldk5vZGVJbmRleFN0YWNrW2ZEZXB0aF0gPSBmTm9kZUluZGV4U3RhY2tbZkRlcHRoXTsKLSAgICAgICAgICAgICAgICBmT3BTdGFja1tmRGVwdGhdID0gWE1MQ29udGVudFNwZWMuQ09OVEVOVFNQRUNOT0RFX1NFUTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgfSAvLyBzZXBhcmF0b3Ioc2hvcnQpCi0KLSAgICAvKioKLSAgICAgKiBUaGUgb2NjdXJyZW5jZSBjb3VudCBmb3IgYSBjaGlsZCBpbiBhIGNoaWxkcmVuIGNvbnRlbnQgbW9kZWwgb3IKLSAgICAgKiBmb3IgdGhlIG1peGVkIGNvbnRlbnQgbW9kZWwgZ3JvdXAuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gb2NjdXJyZW5jZSBUaGUgb2NjdXJyZW5jZSBjb3VudCBmb3IgdGhlIGxhc3QgZWxlbWVudAotICAgICAqICAgICAgICAgICAgICAgICAgIG9yIGdyb3VwLgotICAgICAqIEBwYXJhbSBhdWdzIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICoKLSAgICAgKiBAc2VlIG9yZy5hcGFjaGUueGVyY2VzLnhuaS5YTUxEVERDb250ZW50TW9kZWxIYW5kbGVyI09DQ1VSU19aRVJPX09SX09ORQotICAgICAqIEBzZWUgb3JnLmFwYWNoZS54ZXJjZXMueG5pLlhNTERURENvbnRlbnRNb2RlbEhhbmRsZXIjT0NDVVJTX1pFUk9fT1JfTU9SRQotICAgICAqIEBzZWUgb3JnLmFwYWNoZS54ZXJjZXMueG5pLlhNTERURENvbnRlbnRNb2RlbEhhbmRsZXIjT0NDVVJTX09ORV9PUl9NT1JFCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgb2NjdXJyZW5jZShzaG9ydCBvY2N1cnJlbmNlLCBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotCi0gICAgICAgIGlmICghZk1peGVkKSB7Ci0gICAgICAgICAgICBpZiAob2NjdXJyZW5jZSA9PSBYTUxEVERDb250ZW50TW9kZWxIYW5kbGVyLk9DQ1VSU19aRVJPX09SX09ORSApIHsKLSAgICAgICAgICAgICAgICBmTm9kZUluZGV4U3RhY2tbZkRlcHRoXSA9IGFkZENvbnRlbnRTcGVjTm9kZShYTUxDb250ZW50U3BlYy5DT05URU5UU1BFQ05PREVfWkVST19PUl9PTkUsIGZOb2RlSW5kZXhTdGFja1tmRGVwdGhdLCAtMSk7Ci0gICAgICAgICAgICB9IGVsc2UgaWYgKCBvY2N1cnJlbmNlID09IFhNTERURENvbnRlbnRNb2RlbEhhbmRsZXIuT0NDVVJTX1pFUk9fT1JfTU9SRSApIHsKLSAgICAgICAgICAgICAgICBmTm9kZUluZGV4U3RhY2tbZkRlcHRoXSA9IGFkZENvbnRlbnRTcGVjTm9kZShYTUxDb250ZW50U3BlYy5DT05URU5UU1BFQ05PREVfWkVST19PUl9NT1JFLCBmTm9kZUluZGV4U3RhY2tbZkRlcHRoXSwgLTEgKTsKLSAgICAgICAgICAgIH0gZWxzZSBpZiAoIG9jY3VycmVuY2UgPT0gWE1MRFREQ29udGVudE1vZGVsSGFuZGxlci5PQ0NVUlNfT05FX09SX01PUkUpIHsKLSAgICAgICAgICAgICAgICBmTm9kZUluZGV4U3RhY2tbZkRlcHRoXSA9IGFkZENvbnRlbnRTcGVjTm9kZShYTUxDb250ZW50U3BlYy5DT05URU5UU1BFQ05PREVfT05FX09SX01PUkUsIGZOb2RlSW5kZXhTdGFja1tmRGVwdGhdLCAtMSApOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICB9IC8vIG9jY3VycmVuY2Uoc2hvcnQpCi0KLSAgICAvKioKLSAgICAgKiBUaGUgZW5kIG9mIGEgZ3JvdXAgZm9yIG1peGVkIG9yIGNoaWxkcmVuIGNvbnRlbnQgbW9kZWxzLgotICAgICAqCi0gICAgICogQHBhcmFtIGF1Z3MgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbmRHcm91cChBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotCi0gICAgICAgIGlmICghZk1peGVkKSB7Ci0gICAgICAgICAgICBpZiAoZlByZXZOb2RlSW5kZXhTdGFja1tmRGVwdGhdICE9IC0xKSB7Ci0gICAgICAgICAgICAgICAgZk5vZGVJbmRleFN0YWNrW2ZEZXB0aF0gPSBhZGRDb250ZW50U3BlY05vZGUoZk9wU3RhY2tbZkRlcHRoXSwgZlByZXZOb2RlSW5kZXhTdGFja1tmRGVwdGhdLCBmTm9kZUluZGV4U3RhY2tbZkRlcHRoXSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpbnQgbm9kZUluZGV4ID0gZk5vZGVJbmRleFN0YWNrW2ZEZXB0aC0tXTsKLSAgICAgICAgICAgIGZOb2RlSW5kZXhTdGFja1tmRGVwdGhdID0gbm9kZUluZGV4OwotICAgICAgICB9Ci0KLSAgICB9IC8vIGVuZEdyb3VwKCkKLQotICAgIC8vIG5vLW9wIG1ldGhvZHMKLQotICAgIC8qKgotICAgICAqIEEgY29udGVudCBtb2RlbCBvZiBBTlkuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYXVncyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqCi0gICAgICogQHNlZSAjZW1wdHkKLSAgICAgKiBAc2VlICNzdGFydEdyb3VwCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgYW55KEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7fQotCi0gICAgLyoqCi0gICAgICogQSBjb250ZW50IG1vZGVsIG9mIEVNUFRZLgotICAgICAqCi0gICAgICogQHBhcmFtIGF1Z3MgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKgotICAgICAqIEBzZWUgI2FueQotICAgICAqIEBzZWUgI3N0YXJ0R3JvdXAKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbXB0eShBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24ge30KLQotICAgIC8qKgotICAgICAqIFRoZSBlbmQgb2YgYSBjb250ZW50IG1vZGVsLgotICAgICAqIEBwYXJhbSBhdWdzIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbmRDb250ZW50TW9kZWwoQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHt9Ci0KLSAgICAvLwotICAgIC8vIEdyYW1tYXIgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKiogUmV0dXJucyB0cnVlIGlmIHRoaXMgZ3JhbW1hciBpcyBuYW1lc3BhY2UgYXdhcmUuICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNOYW1lc3BhY2VBd2FyZSgpIHsKLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0gLy8gaXNOYW1lc3BhY2VBd2FyZSgpOmJvb2xlYW4KLQotICAgIC8qKiBSZXR1cm5zIHRoZSBzeW1ib2wgdGFibGUuICovCi0gICAgcHVibGljIFN5bWJvbFRhYmxlIGdldFN5bWJvbFRhYmxlKCkgewotICAgICAgICByZXR1cm4gZlN5bWJvbFRhYmxlOwotICAgIH0gLy8gZ2V0U3ltYm9sVGFibGUoKTpTeW1ib2xUYWJsZQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IGVsZW1lbnQgZGVjbGFyYXRpb24uIFRoaXMgaW5kZXgKLSAgICAgKiBpcyB0aGVuIHVzZWQgdG8gcXVlcnkgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgZWxlbWVudCBkZWNsYXJhdGlvbi4KLSAgICAgKgotICAgICAqIEBzZWUgI2dldE5leHRFbGVtZW50RGVjbEluZGV4Ci0gICAgICogQHNlZSAjZ2V0RWxlbWVudERlY2wKLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldEZpcnN0RWxlbWVudERlY2xJbmRleCgpIHsKLSAgICAgICAgcmV0dXJuIGZFbGVtZW50RGVjbENvdW50ID49IDAgPyAwIDogLTE7Ci0gICAgfSAvLyBnZXRGaXJzdEVsZW1lbnREZWNsSW5kZXgoKTppbnQKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIG5leHQgaW5kZXggb2YgdGhlIGVsZW1lbnQgZGVjbGFyYXRpb24gZm9sbG93aW5nIHRoZQotICAgICAqIHNwZWNpZmllZCBlbGVtZW50IGRlY2xhcmF0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIGVsZW1lbnREZWNsSW5kZXggVGhlIGVsZW1lbnQgZGVjbGFyYXRpb24gaW5kZXguCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXROZXh0RWxlbWVudERlY2xJbmRleChpbnQgZWxlbWVudERlY2xJbmRleCkgewotICAgICAgICByZXR1cm4gZWxlbWVudERlY2xJbmRleCA8IGZFbGVtZW50RGVjbENvdW50IC0gMQotICAgICAgICAgICAgID8gZWxlbWVudERlY2xJbmRleCArIDEgOiAtMTsKLSAgICB9IC8vIGdldE5leHRFbGVtZW50RGVjbEluZGV4KGludCk6aW50Ci0KLSAgICAvKioKLSAgICAgKiBnZXRFbGVtZW50RGVjbEluZGV4Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gZWxlbWVudERlY2xOYW1lCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIGluZGV4IG9mIHRoZSBlbGVtZW50RGVjbE5hbWUgaW4gc2NvcGUKLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldEVsZW1lbnREZWNsSW5kZXgoU3RyaW5nIGVsZW1lbnREZWNsTmFtZSkgewotICAgICAgICBJbnRlZ2VyIG1hcHBpbmcgPSBmRWxlbWVudEluZGV4TWFwLmdldChlbGVtZW50RGVjbE5hbWUpOwotICAgICAgICBpZiAobWFwcGluZyA9PSBudWxsKSB7Ci0gICAgICAgICAgICBtYXBwaW5nID0gLTE7Ci0gICAgICAgIH0KLSAgICAgICAgLy9TeXN0ZW0ub3V0LnByaW50bG4oImdldEVsZW1lbnREZWNsSW5kZXgoIitlbGVtZW50RGVjbE5hbWUrIikgLT4gIittYXBwaW5nKTsKLSAgICAgICAgcmV0dXJuIG1hcHBpbmc7Ci0gICAgfSAvLyBnZXRFbGVtZW50RGVjbEluZGV4KFN0cmluZyk6aW50Ci0KLSAgICAvKiogUmV0dXJucyB0aGUgZWxlbWVudCBkZWNsIGluZGV4LgotICAgICAqIEBwYXJhbSBlbGVtZW50RGVjbFFOYW1lIHF1YWxpbGZpZWQgbmFtZSBvZiB0aGUgZWxlbWVudAotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0RWxlbWVudERlY2xJbmRleChRTmFtZSBlbGVtZW50RGVjbFFOYW1lKSB7Ci0gICAgICAgIHJldHVybiBnZXRFbGVtZW50RGVjbEluZGV4KGVsZW1lbnREZWNsUU5hbWUucmF3bmFtZSk7Ci0gICAgfSAvLyBnZXRFbGVtZW50RGVjbEluZGV4KFFOYW1lKTppbnQKLQotICAgICAgICAgICAgICAgIC8qKiBtYWtlIHNlcGFyYXRlIGZ1bmN0aW9uIGZvciBnZXR0aW5nIGNvbnRlbnRTcGVjVHlwZSBvZiBlbGVtZW50LgotICAgICAgKiB3ZSBjYW4gYXZvaWQgc2V0dGluZyBvZiB0aGUgZWxlbWVudCB2YWx1ZXMuCi0gICAgICAgICAgICAgICAgKi8KLQotICAgICAgICAgICAgICAgIHB1YmxpYyBzaG9ydCBnZXRDb250ZW50U3BlY1R5cGUoaW50IGVsZW1lbnRJbmRleCl7Ci0gICAgICAgIGlmIChlbGVtZW50SW5kZXggPCAwIHx8IGVsZW1lbnRJbmRleCA+PSBmRWxlbWVudERlY2xDb3VudCkgewotICAgICAgICAgICAgcmV0dXJuIC0xIDsKLSAgICAgICAgfQotCi0gICAgICAgIGludCBjaHVuayA9IGVsZW1lbnRJbmRleCA+PiBDSFVOS19TSElGVDsKLSAgICAgICAgaW50IGluZGV4ID0gZWxlbWVudEluZGV4ICYgIENIVU5LX01BU0s7Ci0KLSAgICAgICAgaWYoZkVsZW1lbnREZWNsVHlwZVtjaHVua11baW5kZXhdID09IC0xKXsKLSAgICAgICAgICAgIHJldHVybiAtMSA7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICBlbHNlewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChzaG9ydCkgKGZFbGVtZW50RGVjbFR5cGVbY2h1bmtdW2luZGV4XSAmIExJU1RfTUFTSyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgfS8vZ2V0Q29udGVudFNwZWNUeXBlCi0KLSAgICAvKioKLSAgICAgKiBnZXRFbGVtZW50RGVjbAotICAgICAqCi0gICAgICogQHBhcmFtIGVsZW1lbnREZWNsSW5kZXgKLSAgICAgKiBAcGFyYW0gZWxlbWVudERlY2wgVGhlIHZhbHVlcyBvZiB0aGlzIHN0cnVjdHVyZSBhcmUgc2V0IGJ5IHRoaXMgY2FsbC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVHJ1ZSBpZiBmaW5kIHRoZSBlbGVtZW50LCBGYWxzZSBvdGhlcndpc2UuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0RWxlbWVudERlY2woaW50IGVsZW1lbnREZWNsSW5kZXgsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MRWxlbWVudERlY2wgZWxlbWVudERlY2wpIHsKLQotICAgICAgICBpZiAoZWxlbWVudERlY2xJbmRleCA8IDAgfHwgZWxlbWVudERlY2xJbmRleCA+PSBmRWxlbWVudERlY2xDb3VudCkgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0KLSAgICAgICAgaW50IGNodW5rID0gZWxlbWVudERlY2xJbmRleCA+PiBDSFVOS19TSElGVDsKLSAgICAgICAgaW50IGluZGV4ID0gZWxlbWVudERlY2xJbmRleCAmICBDSFVOS19NQVNLOwotCi0gICAgICAgIGVsZW1lbnREZWNsLm5hbWUuc2V0VmFsdWVzKGZFbGVtZW50RGVjbE5hbWVbY2h1bmtdW2luZGV4XSk7Ci0KLSAgICAgICAgaWYgKGZFbGVtZW50RGVjbFR5cGVbY2h1bmtdW2luZGV4XSA9PSAtMSkgewotICAgICAgICAgICAgZWxlbWVudERlY2wudHlwZSAgICAgICAgICAgICAgICAgICAgPSAtMTsKLSAgICAgICAgICAgIGVsZW1lbnREZWNsLnNpbXBsZVR5cGUubGlzdCA9IGZhbHNlOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgZWxlbWVudERlY2wudHlwZSAgICAgICAgICAgID0gKHNob3J0KSAoZkVsZW1lbnREZWNsVHlwZVtjaHVua11baW5kZXhdICYgTElTVF9NQVNLKTsKLSAgICAgICAgICAgIGVsZW1lbnREZWNsLnNpbXBsZVR5cGUubGlzdCA9IChmRWxlbWVudERlY2xUeXBlW2NodW5rXVtpbmRleF0gJiBMSVNUX0ZMQUcpICE9IDA7Ci0gICAgICAgIH0KLQotICAgICAgICAvKiBWYWxpZGF0b3JzIGFyZSBudWxsIHVudGlsIHdlIGFkZCB0aGF0IGNvZGUgKi8KLSAgICAgICAgaWYgKGVsZW1lbnREZWNsLnR5cGUgPT0gWE1MRWxlbWVudERlY2wuVFlQRV9DSElMRFJFTiB8fCBlbGVtZW50RGVjbC50eXBlID09IFhNTEVsZW1lbnREZWNsLlRZUEVfTUlYRUQpIHsKLSAgICAgICAgICAgIGVsZW1lbnREZWNsLmNvbnRlbnRNb2RlbFZhbGlkYXRvciA9IGdldEVsZW1lbnRDb250ZW50TW9kZWxWYWxpZGF0b3IoZWxlbWVudERlY2xJbmRleCk7Ci0gICAgICAgIH0KLQotICAgICAgICBlbGVtZW50RGVjbC5zaW1wbGVUeXBlLmRhdGF0eXBlVmFsaWRhdG9yID0gbnVsbDsKLSAgICAgICAgZWxlbWVudERlY2wuc2ltcGxlVHlwZS5kZWZhdWx0VHlwZSAgICAgICA9IC0xOwotICAgICAgICBlbGVtZW50RGVjbC5zaW1wbGVUeXBlLmRlZmF1bHRWYWx1ZSAgICAgID0gbnVsbDsKLQotICAgICAgICByZXR1cm4gdHJ1ZTsKLQotICAgIH0gLy8gZ2V0RWxlbWVudERlY2woaW50LFhNTEVsZW1lbnREZWNsKTpib29sZWFuCi0KLSAgICBRTmFtZSBnZXRFbGVtZW50RGVjbE5hbWUoaW50IGVsZW1lbnREZWNsSW5kZXgpIHsKLSAgICAgICAgaWYgKGVsZW1lbnREZWNsSW5kZXggPCAwIHx8IGVsZW1lbnREZWNsSW5kZXggPj0gZkVsZW1lbnREZWNsQ291bnQpIHsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgICAgIGludCBjaHVuayA9IGVsZW1lbnREZWNsSW5kZXggPj4gQ0hVTktfU0hJRlQ7Ci0gICAgICAgIGludCBpbmRleCA9IGVsZW1lbnREZWNsSW5kZXggJiAgQ0hVTktfTUFTSzsKLSAgICAgICAgcmV0dXJuIGZFbGVtZW50RGVjbE5hbWVbY2h1bmtdW2luZGV4XTsKLSAgICB9Ci0KLSAgICAvLyBSRVZJU0lUOiBNYWtlIHRoaXMgZ2V0QXR0cmlidXRlRGVjbENvdW50L2dldEF0dHJpYnV0ZURlY2xBdC4gLUFjCi0KLSAgICAvKioKLSAgICAgKiBnZXRGaXJzdEF0dHJpYnV0ZURlY2xJbmRleAotICAgICAqCi0gICAgICogQHBhcmFtIGVsZW1lbnREZWNsSW5kZXgKLSAgICAgKgotICAgICAqIEByZXR1cm4gaW5kZXggb2YgdGhlIGZpcnN0IGF0dHJpYnV0ZSBmb3IgZWxlbWVudCBkZWNsYXJhdGlvbiBlbGVtZW50RGVjbEluZGV4Ci0gICAgICovCi0gICAgcHVibGljIGludCBnZXRGaXJzdEF0dHJpYnV0ZURlY2xJbmRleChpbnQgZWxlbWVudERlY2xJbmRleCkgewotICAgICAgICBpbnQgY2h1bmsgPSBlbGVtZW50RGVjbEluZGV4ID4+IENIVU5LX1NISUZUOwotICAgICAgICBpbnQgaW5kZXggPSBlbGVtZW50RGVjbEluZGV4ICYgIENIVU5LX01BU0s7Ci0KLSAgICAgICAgcmV0dXJuICBmRWxlbWVudERlY2xGaXJzdEF0dHJpYnV0ZURlY2xJbmRleFtjaHVua11baW5kZXhdOwotICAgIH0gLy8gZ2V0Rmlyc3RBdHRyaWJ1dGVEZWNsSW5kZXgKLQotICAgIC8qKgotICAgICAqIGdldE5leHRBdHRyaWJ1dGVEZWNsSW5kZXgKLSAgICAgKgotICAgICAqIEBwYXJhbSBhdHRyaWJ1dGVEZWNsSW5kZXgKLSAgICAgKgotICAgICAqIEByZXR1cm4gaW5kZXggb2YgdGhlIG5leHQgYXR0cmlidXRlIG9mIHRoZSBhdHRyaWJ1dGUgYXQgYXR0cmlidXRlRGVjbEluZGV4Ci0gICAgICovCi0gICAgcHVibGljIGludCBnZXROZXh0QXR0cmlidXRlRGVjbEluZGV4KGludCBhdHRyaWJ1dGVEZWNsSW5kZXgpIHsKLSAgICAgICAgaW50IGNodW5rID0gYXR0cmlidXRlRGVjbEluZGV4ID4+IENIVU5LX1NISUZUOwotICAgICAgICBpbnQgaW5kZXggPSBhdHRyaWJ1dGVEZWNsSW5kZXggJiAgQ0hVTktfTUFTSzsKLQotICAgICAgICByZXR1cm4gZkF0dHJpYnV0ZURlY2xOZXh0QXR0cmlidXRlRGVjbEluZGV4W2NodW5rXVtpbmRleF07Ci0gICAgfSAvLyBnZXROZXh0QXR0cmlidXRlRGVjbEluZGV4Ci0KLSAgICAvKioKLSAgICAgKiBnZXRBdHRyaWJ1dGVEZWNsCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYXR0cmlidXRlRGVjbEluZGV4Ci0gICAgICogQHBhcmFtIGF0dHJpYnV0ZURlY2wgVGhlIHZhbHVlcyBvZiB0aGlzIHN0cnVjdHVyZSBhcmUgc2V0IGJ5IHRoaXMgY2FsbC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBnZXRBdHRyaWJ1dGVEZWNsIHdhcyBhYmxlIHRvIGZpbGwgaW4gdGhlIHZhbHVlIG9mIGF0dHJpYnV0ZURlY2wKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXRBdHRyaWJ1dGVEZWNsKGludCBhdHRyaWJ1dGVEZWNsSW5kZXgsIFhNTEF0dHJpYnV0ZURlY2wgYXR0cmlidXRlRGVjbCkgewotICAgICAgICBpZiAoYXR0cmlidXRlRGVjbEluZGV4IDwgMCB8fCBhdHRyaWJ1dGVEZWNsSW5kZXggPj0gZkF0dHJpYnV0ZURlY2xDb3VudCkgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0gICAgICAgIGludCBjaHVuayA9IGF0dHJpYnV0ZURlY2xJbmRleCA+PiBDSFVOS19TSElGVDsKLSAgICAgICAgaW50IGluZGV4ID0gYXR0cmlidXRlRGVjbEluZGV4ICYgQ0hVTktfTUFTSzsKLQotICAgICAgICBhdHRyaWJ1dGVEZWNsLm5hbWUuc2V0VmFsdWVzKGZBdHRyaWJ1dGVEZWNsTmFtZVtjaHVua11baW5kZXhdKTsKLQotICAgICAgICBzaG9ydCBhdHRyaWJ1dGVUeXBlOwotICAgICAgICBib29sZWFuIGlzTGlzdDsKLQotICAgICAgICBpZiAoZkF0dHJpYnV0ZURlY2xUeXBlW2NodW5rXVtpbmRleF0gPT0gLTEpIHsKLQotICAgICAgICAgICAgYXR0cmlidXRlVHlwZSA9IC0xOwotICAgICAgICAgICAgaXNMaXN0ID0gZmFsc2U7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBhdHRyaWJ1dGVUeXBlID0gKHNob3J0KSAoZkF0dHJpYnV0ZURlY2xUeXBlW2NodW5rXVtpbmRleF0gJiBMSVNUX01BU0spOwotICAgICAgICAgICAgaXNMaXN0ID0gKGZBdHRyaWJ1dGVEZWNsVHlwZVtjaHVua11baW5kZXhdICYgTElTVF9GTEFHKSAhPSAwOwotICAgICAgICB9Ci0gICAgICAgIGF0dHJpYnV0ZURlY2wuc2ltcGxlVHlwZS5zZXRWYWx1ZXMoYXR0cmlidXRlVHlwZSxmQXR0cmlidXRlRGVjbE5hbWVbY2h1bmtdW2luZGV4XS5sb2NhbHBhcnQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkF0dHJpYnV0ZURlY2xFbnVtZXJhdGlvbltjaHVua11baW5kZXhdLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzTGlzdCwgZkF0dHJpYnV0ZURlY2xEZWZhdWx0VHlwZVtjaHVua11baW5kZXhdLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZBdHRyaWJ1dGVEZWNsRGVmYXVsdFZhbHVlW2NodW5rXVtpbmRleF0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkF0dHJpYnV0ZURlY2xOb25Ob3JtYWxpemVkRGVmYXVsdFZhbHVlW2NodW5rXVtpbmRleF0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkF0dHJpYnV0ZURlY2xEYXRhdHlwZVZhbGlkYXRvcltjaHVua11baW5kZXhdKTsKLSAgICAgICAgcmV0dXJuIHRydWU7Ci0KLSAgICB9IC8vIGdldEF0dHJpYnV0ZURlY2wKLQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB3aGV0aGVyIHRoZSBnaXZlbiBhdHRyaWJ1dGUgaXMgb2YgdHlwZSBDREFUQSBvciBub3QKLSAgICAgKgotICAgICAqIEBwYXJhbSBlbE5hbWUgVGhlIGVsZW1lbnQgbmFtZS4KLSAgICAgKiBAcGFyYW0gYXROYW1lIFRoZSBhdHRyaWJ1dGUgbmFtZS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgYXR0cmlidXRlIGlzIG9mIHR5cGUgQ0RBVEEKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0NEQVRBQXR0cmlidXRlKFFOYW1lIGVsTmFtZSwgUU5hbWUgYXROYW1lKSB7Ci0gICAgICAgIGludCBlbERlY2xJZHggPSBnZXRFbGVtZW50RGVjbEluZGV4KGVsTmFtZSk7Ci0gICAgICAgIGlmIChnZXRBdHRyaWJ1dGVEZWNsKGVsRGVjbElkeCwgZkF0dHJpYnV0ZURlY2wpCi0gICAgICAgICAgICAmJiBmQXR0cmlidXRlRGVjbC5zaW1wbGVUeXBlLnR5cGUgIT0gWE1MU2ltcGxlVHlwZS5UWVBFX0NEQVRBKXsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBnZXRFbnRpdHlEZWNsSW5kZXgKLSAgICAgKgotICAgICAqIEBwYXJhbSBlbnRpdHlEZWNsTmFtZQotICAgICAqCi0gICAgICogQHJldHVybiB0aGUgaW5kZXggb2YgdGhlIEVudGl0eURlY2wKLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldEVudGl0eURlY2xJbmRleChTdHJpbmcgZW50aXR5RGVjbE5hbWUpIHsKLSAgICAgICAgaWYgKGVudGl0eURlY2xOYW1lID09IG51bGwgfHwgZkVudGl0eUluZGV4TWFwLmdldChlbnRpdHlEZWNsTmFtZSkgPT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIC0xOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIGZFbnRpdHlJbmRleE1hcC5nZXQoZW50aXR5RGVjbE5hbWUpOwotICAgIH0gLy8gZ2V0RW50aXR5RGVjbEluZGV4Ci0KLSAgICAvKioKLSAgICAgKiBnZXRFbnRpdHlEZWNsCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZW50aXR5RGVjbEluZGV4Ci0gICAgICogQHBhcmFtIGVudGl0eURlY2wKLSAgICAgKgotICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBnZXRFbnRpdHlEZWNsIHdhcyBhYmxlIHRvIGZpbGwgZW50aXR5RGVjbCB3aXRoIHRoZSBjb250ZW50cyBvZiB0aGUgZW50aXR5Ci0gICAgICogd2l0aCBpbmRleCBlbnRpdHlEZWNsSW5kZXgKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXRFbnRpdHlEZWNsKGludCBlbnRpdHlEZWNsSW5kZXgsIFhNTEVudGl0eURlY2wgZW50aXR5RGVjbCkgewotICAgICAgICBpZiAoZW50aXR5RGVjbEluZGV4IDwgMCB8fCBlbnRpdHlEZWNsSW5kZXggPj0gZkVudGl0eUNvdW50KSB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLSAgICAgICAgaW50IGNodW5rID0gZW50aXR5RGVjbEluZGV4ID4+IENIVU5LX1NISUZUOwotICAgICAgICBpbnQgaW5kZXggPSBlbnRpdHlEZWNsSW5kZXggJiBDSFVOS19NQVNLOwotCi0gICAgICAgIGVudGl0eURlY2wuc2V0VmFsdWVzKGZFbnRpdHlOYW1lW2NodW5rXVtpbmRleF0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZFbnRpdHlQdWJsaWNJZFtjaHVua11baW5kZXhdLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmRW50aXR5U3lzdGVtSWRbY2h1bmtdW2luZGV4XSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkVudGl0eUJhc2VTeXN0ZW1JZFtjaHVua11baW5kZXhdLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmRW50aXR5Tm90YXRpb25bY2h1bmtdW2luZGV4XSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkVudGl0eVZhbHVlW2NodW5rXVtpbmRleF0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZFbnRpdHlJc1BFW2NodW5rXVtpbmRleF0gPT0gMCA/IGZhbHNlIDogdHJ1ZSAsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZFbnRpdHlJbkV4dGVybmFsW2NodW5rXVtpbmRleF0gPT0gMCA/IGZhbHNlIDogdHJ1ZSApOwotCi0gICAgICAgIHJldHVybiB0cnVlOwotICAgIH0gLy8gZ2V0RW50aXR5RGVjbAotCi0gICAgLyoqCi0gICAgICogZ2V0Tm90YXRpb25EZWNsSW5kZXgKLSAgICAgKgotICAgICAqIEBwYXJhbSBub3RhdGlvbkRlY2xOYW1lCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRoZSBpbmRleCBpZiBmb3VuZCBhIG5vdGF0aW9uIHdpdGggdGhlIG5hbWUsIG90aGVyd2lzZSAtMS4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldE5vdGF0aW9uRGVjbEluZGV4KFN0cmluZyBub3RhdGlvbkRlY2xOYW1lKSB7Ci0gICAgICAgIGlmIChub3RhdGlvbkRlY2xOYW1lID09IG51bGwgfHwgZk5vdGF0aW9uSW5kZXhNYXAuZ2V0KG5vdGF0aW9uRGVjbE5hbWUpID09IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiAtMTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBmTm90YXRpb25JbmRleE1hcC5nZXQobm90YXRpb25EZWNsTmFtZSk7Ci0gICAgfSAvLyBnZXROb3RhdGlvbkRlY2xJbmRleAotCi0gICAgLyoqCi0gICAgICogZ2V0Tm90YXRpb25EZWNsCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbm90YXRpb25EZWNsSW5kZXgKLSAgICAgKiBAcGFyYW0gbm90YXRpb25EZWNsCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHJldHVybiB0cnVlIG9mIGdldE5vdGF0aW9uRGVjbCBjYW4gZmlsbCBub3RhdGlvbkRlY2wgd2l0aCBpbmZvcm1hdGlvbiBhYm91dAotICAgICAqIHRoZSBub3RhdGlvbiBhdCBub3RhdGlvbkRlY2xJbmRleC4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXROb3RhdGlvbkRlY2woaW50IG5vdGF0aW9uRGVjbEluZGV4LCBYTUxOb3RhdGlvbkRlY2wgbm90YXRpb25EZWNsKSB7Ci0gICAgICAgIGlmIChub3RhdGlvbkRlY2xJbmRleCA8IDAgfHwgbm90YXRpb25EZWNsSW5kZXggPj0gZk5vdGF0aW9uQ291bnQpIHsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotICAgICAgICBpbnQgY2h1bmsgPSBub3RhdGlvbkRlY2xJbmRleCA+PiBDSFVOS19TSElGVDsKLSAgICAgICAgaW50IGluZGV4ID0gbm90YXRpb25EZWNsSW5kZXggJiBDSFVOS19NQVNLOwotCi0gICAgICAgIG5vdGF0aW9uRGVjbC5zZXRWYWx1ZXMoZk5vdGF0aW9uTmFtZVtjaHVua11baW5kZXhdLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZOb3RhdGlvblB1YmxpY0lkW2NodW5rXVtpbmRleF0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZk5vdGF0aW9uU3lzdGVtSWRbY2h1bmtdW2luZGV4XSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmTm90YXRpb25CYXNlU3lzdGVtSWRbY2h1bmtdW2luZGV4XSk7Ci0KLSAgICAgICAgcmV0dXJuIHRydWU7Ci0KLSAgICB9IC8vIGdldE5vdGF0aW9uRGVjbAotCi0gICAgLyoqCi0gICAgICogZ2V0Q29udGVudFNwZWMKLSAgICAgKgotICAgICAqIEBwYXJhbSBjb250ZW50U3BlY0luZGV4Ci0gICAgICogQHBhcmFtIGNvbnRlbnRTcGVjCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRydWUgaWYgZmluZCB0aGUgcmVxdWVzdGVkIGNvbnRlbnRTcGVjIG5vZGUsIGZhbHNlIG90aGVyd2lzZQotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGdldENvbnRlbnRTcGVjKGludCBjb250ZW50U3BlY0luZGV4LCBYTUxDb250ZW50U3BlYyBjb250ZW50U3BlYykgewotICAgICAgICBpZiAoY29udGVudFNwZWNJbmRleCA8IDAgfHwgY29udGVudFNwZWNJbmRleCA+PSBmQ29udGVudFNwZWNDb3VudCApCi0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0KLSAgICAgICAgaW50IGNodW5rID0gY29udGVudFNwZWNJbmRleCA+PiBDSFVOS19TSElGVDsKLSAgICAgICAgaW50IGluZGV4ID0gY29udGVudFNwZWNJbmRleCAmIENIVU5LX01BU0s7Ci0KLSAgICAgICAgY29udGVudFNwZWMudHlwZSAgICAgICA9IGZDb250ZW50U3BlY1R5cGVbY2h1bmtdW2luZGV4XTsKLSAgICAgICAgY29udGVudFNwZWMudmFsdWUgICAgICA9IGZDb250ZW50U3BlY1ZhbHVlW2NodW5rXVtpbmRleF07Ci0gICAgICAgIGNvbnRlbnRTcGVjLm90aGVyVmFsdWUgPSBmQ29udGVudFNwZWNPdGhlclZhbHVlW2NodW5rXVtpbmRleF07Ci0gICAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIGluZGV4IHRvIHRoZSBjb250ZW50IHNwZWMgZm9yIHRoZSBnaXZlbiBlbGVtZW50Ci0gICAgICogZGVjbGFyYXRpb24sIG9yIDxjb2RlPi0xPC9jb2RlPiBpZiB0aGUgZWxlbWVudCBkZWNsYXJhdGlvbgotICAgICAqIGluZGV4IHdhcyBpbnZhbGlkLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0Q29udGVudFNwZWNJbmRleChpbnQgZWxlbWVudERlY2xJbmRleCkgewotICAgICAgICBpZiAoZWxlbWVudERlY2xJbmRleCA8IDAgfHwgZWxlbWVudERlY2xJbmRleCA+PSBmRWxlbWVudERlY2xDb3VudCkgewotICAgICAgICAgICAgcmV0dXJuIC0xOwotICAgICAgICB9Ci0gICAgICAgIGZpbmFsIGludCBjaHVuayA9IGVsZW1lbnREZWNsSW5kZXggPj4gQ0hVTktfU0hJRlQ7Ci0gICAgICAgIGZpbmFsIGludCBpbmRleCA9IGVsZW1lbnREZWNsSW5kZXggJiBDSFVOS19NQVNLOwotICAgICAgICByZXR1cm4gZkVsZW1lbnREZWNsQ29udGVudFNwZWNJbmRleFtjaHVua11baW5kZXhdOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIGdldENvbnRlbnRTcGVjQXNTdHJpbmcKLSAgICAgKgotICAgICAqIEBwYXJhbSBlbGVtZW50RGVjbEluZGV4Ci0gICAgICoKLSAgICAgKiBAcmV0dXJuIFN0cmluZwotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q29udGVudFNwZWNBc1N0cmluZyhpbnQgZWxlbWVudERlY2xJbmRleCl7Ci0KLSAgICAgICAgaWYgKGVsZW1lbnREZWNsSW5kZXggPCAwIHx8IGVsZW1lbnREZWNsSW5kZXggPj0gZkVsZW1lbnREZWNsQ291bnQpIHsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0KLSAgICAgICAgaW50IGNodW5rID0gZWxlbWVudERlY2xJbmRleCA+PiBDSFVOS19TSElGVDsKLSAgICAgICAgaW50IGluZGV4ID0gZWxlbWVudERlY2xJbmRleCAmICBDSFVOS19NQVNLOwotCi0gICAgICAgIGludCBjb250ZW50U3BlY0luZGV4ID0gZkVsZW1lbnREZWNsQ29udGVudFNwZWNJbmRleFtjaHVua11baW5kZXhdOwotCi0gICAgICAgIC8vIGxvb2t1cCBjb250ZW50IHNwZWMgbm9kZQotICAgICAgICBYTUxDb250ZW50U3BlYyBjb250ZW50U3BlYyA9IG5ldyBYTUxDb250ZW50U3BlYygpOwotCi0gICAgICAgIGlmIChnZXRDb250ZW50U3BlYyhjb250ZW50U3BlY0luZGV4LCBjb250ZW50U3BlYykpIHsKLQotICAgICAgICAgICAgLy8gYnVpbGQgc3RyaW5nCi0gICAgICAgICAgICBTdHJpbmdCdWZmZXIgc3RyID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotICAgICAgICAgICAgaW50ICAgIHBhcmVudENvbnRlbnRTcGVjVHlwZSA9IGNvbnRlbnRTcGVjLnR5cGUgJiAweDBmOwotICAgICAgICAgICAgaW50ICAgIG5leHRDb250ZW50U3BlYzsKLSAgICAgICAgICAgIHN3aXRjaCAocGFyZW50Q29udGVudFNwZWNUeXBlKSB7Ci0gICAgICAgICAgICAgICAgY2FzZSBYTUxDb250ZW50U3BlYy5DT05URU5UU1BFQ05PREVfTEVBRjogewotICAgICAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKCcoJyk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChjb250ZW50U3BlYy52YWx1ZSA9PSBudWxsICYmIGNvbnRlbnRTcGVjLm90aGVyVmFsdWUgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgc3RyLmFwcGVuZCgiI1BDREFUQSIpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgc3RyLmFwcGVuZChjb250ZW50U3BlYy52YWx1ZSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgc3RyLmFwcGVuZCgnKScpOwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgY2FzZSBYTUxDb250ZW50U3BlYy5DT05URU5UU1BFQ05PREVfWkVST19PUl9PTkU6IHsKLSAgICAgICAgICAgICAgICAgICAgZ2V0Q29udGVudFNwZWMoKChpbnRbXSljb250ZW50U3BlYy52YWx1ZSlbMF0sIGNvbnRlbnRTcGVjKTsKLSAgICAgICAgICAgICAgICAgICAgbmV4dENvbnRlbnRTcGVjID0gY29udGVudFNwZWMudHlwZTsKLQotICAgICAgICAgICAgICAgICAgICBpZiAobmV4dENvbnRlbnRTcGVjID09IFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9MRUFGKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKCcoJyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKGNvbnRlbnRTcGVjLnZhbHVlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHN0ci5hcHBlbmQoJyknKTsKLSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmKCBuZXh0Q29udGVudFNwZWMgPT0gWE1MQ29udGVudFNwZWMuQ09OVEVOVFNQRUNOT0RFX09ORV9PUl9NT1JFICB8fAotICAgICAgICAgICAgICAgICAgICAgICAgbmV4dENvbnRlbnRTcGVjID09IFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9aRVJPX09SX01PUkUgIHx8Ci0gICAgICAgICAgICAgICAgICAgICAgICBuZXh0Q29udGVudFNwZWMgPT0gWE1MQ29udGVudFNwZWMuQ09OVEVOVFNQRUNOT0RFX1pFUk9fT1JfT05FICkgewotICAgICAgICAgICAgICAgICAgICAgICAgc3RyLmFwcGVuZCgnKCcgKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGFwcGVuZENvbnRlbnRTcGVjKGNvbnRlbnRTcGVjLCBzdHIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlLCBwYXJlbnRDb250ZW50U3BlY1R5cGUgKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHN0ci5hcHBlbmQoJyknKTsKLSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGFwcGVuZENvbnRlbnRTcGVjKGNvbnRlbnRTcGVjLCBzdHIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlLCBwYXJlbnRDb250ZW50U3BlY1R5cGUgKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKCc/Jyk7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBjYXNlIFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9aRVJPX09SX01PUkU6IHsKLSAgICAgICAgICAgICAgICAgICAgZ2V0Q29udGVudFNwZWMoKChpbnRbXSljb250ZW50U3BlYy52YWx1ZSlbMF0sIGNvbnRlbnRTcGVjKTsKLSAgICAgICAgICAgICAgICAgICAgbmV4dENvbnRlbnRTcGVjID0gY29udGVudFNwZWMudHlwZTsKLQotICAgICAgICAgICAgICAgICAgICBpZiAoIG5leHRDb250ZW50U3BlYyA9PSBYTUxDb250ZW50U3BlYy5DT05URU5UU1BFQ05PREVfTEVBRikgewotICAgICAgICAgICAgICAgICAgICAgICAgc3RyLmFwcGVuZCgnKCcpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvbnRlbnRTcGVjLnZhbHVlID09IG51bGwgJiYgY29udGVudFNwZWMub3RoZXJWYWx1ZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyLmFwcGVuZCgiI1BDREFUQSIpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoY29udGVudFNwZWMub3RoZXJWYWx1ZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyLmFwcGVuZCgiIyNhbnk6dXJpPSIpLmFwcGVuZChjb250ZW50U3BlYy5vdGhlclZhbHVlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGNvbnRlbnRTcGVjLnZhbHVlID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKCIjI2FueSIpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXBwZW5kQ29udGVudFNwZWMoY29udGVudFNwZWMsIHN0ciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlLCBwYXJlbnRDb250ZW50U3BlY1R5cGUgKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIHN0ci5hcHBlbmQoJyknKTsKLSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmKCBuZXh0Q29udGVudFNwZWMgPT0gWE1MQ29udGVudFNwZWMuQ09OVEVOVFNQRUNOT0RFX09ORV9PUl9NT1JFICB8fAotICAgICAgICAgICAgICAgICAgICAgICAgbmV4dENvbnRlbnRTcGVjID09IFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9aRVJPX09SX01PUkUgIHx8Ci0gICAgICAgICAgICAgICAgICAgICAgICBuZXh0Q29udGVudFNwZWMgPT0gWE1MQ29udGVudFNwZWMuQ09OVEVOVFNQRUNOT0RFX1pFUk9fT1JfT05FICkgewotICAgICAgICAgICAgICAgICAgICAgICAgc3RyLmFwcGVuZCgnKCcgKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGFwcGVuZENvbnRlbnRTcGVjKGNvbnRlbnRTcGVjLCBzdHIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlLCBwYXJlbnRDb250ZW50U3BlY1R5cGUgKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHN0ci5hcHBlbmQoJyknKTsKLSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGFwcGVuZENvbnRlbnRTcGVjKGNvbnRlbnRTcGVjLCBzdHIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlLCBwYXJlbnRDb250ZW50U3BlY1R5cGUgKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKCcqJyk7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBjYXNlIFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9PTkVfT1JfTU9SRTogewotICAgICAgICAgICAgICAgICAgICBnZXRDb250ZW50U3BlYygoKGludFtdKWNvbnRlbnRTcGVjLnZhbHVlKVswXSwgY29udGVudFNwZWMpOwotICAgICAgICAgICAgICAgICAgICBuZXh0Q29udGVudFNwZWMgPSBjb250ZW50U3BlYy50eXBlOwotCi0gICAgICAgICAgICAgICAgICAgIGlmICggbmV4dENvbnRlbnRTcGVjID09IFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9MRUFGKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKCcoJyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29udGVudFNwZWMudmFsdWUgPT0gbnVsbCAmJiBjb250ZW50U3BlYy5vdGhlclZhbHVlID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKCIjUENEQVRBIik7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChjb250ZW50U3BlYy5vdGhlclZhbHVlICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKCIjI2FueTp1cmk9IikuYXBwZW5kKGNvbnRlbnRTcGVjLm90aGVyVmFsdWUpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoY29udGVudFNwZWMudmFsdWUgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ci5hcHBlbmQoIiMjYW55Iik7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKGNvbnRlbnRTcGVjLnZhbHVlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIHN0ci5hcHBlbmQoJyknKTsKLSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmKCBuZXh0Q29udGVudFNwZWMgPT0gWE1MQ29udGVudFNwZWMuQ09OVEVOVFNQRUNOT0RFX09ORV9PUl9NT1JFICB8fAotICAgICAgICAgICAgICAgICAgICAgICAgbmV4dENvbnRlbnRTcGVjID09IFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9aRVJPX09SX01PUkUgIHx8Ci0gICAgICAgICAgICAgICAgICAgICAgICBuZXh0Q29udGVudFNwZWMgPT0gWE1MQ29udGVudFNwZWMuQ09OVEVOVFNQRUNOT0RFX1pFUk9fT1JfT05FICkgewotICAgICAgICAgICAgICAgICAgICAgICAgc3RyLmFwcGVuZCgnKCcgKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGFwcGVuZENvbnRlbnRTcGVjKGNvbnRlbnRTcGVjLCBzdHIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlLCBwYXJlbnRDb250ZW50U3BlY1R5cGUgKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHN0ci5hcHBlbmQoJyknKTsKLSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGFwcGVuZENvbnRlbnRTcGVjKGNvbnRlbnRTcGVjLCBzdHIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlLCBwYXJlbnRDb250ZW50U3BlY1R5cGUpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIHN0ci5hcHBlbmQoJysnKTsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGNhc2UgWE1MQ29udGVudFNwZWMuQ09OVEVOVFNQRUNOT0RFX0NIT0lDRToKLSAgICAgICAgICAgICAgICBjYXNlIFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9TRVE6IHsKLSAgICAgICAgICAgICAgICAgICAgYXBwZW5kQ29udGVudFNwZWMoY29udGVudFNwZWMsIHN0ciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ1ZSwgcGFyZW50Q29udGVudFNwZWNUeXBlICk7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBjYXNlIFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9BTlk6IHsKLSAgICAgICAgICAgICAgICAgICAgc3RyLmFwcGVuZCgiIyNhbnkiKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGNvbnRlbnRTcGVjLm90aGVyVmFsdWUgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgc3RyLmFwcGVuZCgiOnVyaT0iKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHN0ci5hcHBlbmQoY29udGVudFNwZWMub3RoZXJWYWx1ZSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGNhc2UgWE1MQ29udGVudFNwZWMuQ09OVEVOVFNQRUNOT0RFX0FOWV9PVEhFUjogewotICAgICAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKCIjI290aGVyOnVyaT0iKTsKLSAgICAgICAgICAgICAgICAgICAgc3RyLmFwcGVuZChjb250ZW50U3BlYy5vdGhlclZhbHVlKTsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGNhc2UgWE1MQ29udGVudFNwZWMuQ09OVEVOVFNQRUNOT0RFX0FOWV9MT0NBTDogewotICAgICAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKCIjI2xvY2FsIik7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBkZWZhdWx0OiB7Ci0gICAgICAgICAgICAgICAgICAgIHN0ci5hcHBlbmQoIj8/PyIpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgfSAvLyBzd2l0Y2ggdHlwZQotCi0gICAgICAgICAgICAvLyByZXR1cm4gc3RyaW5nCi0gICAgICAgICAgICByZXR1cm4gc3RyLnRvU3RyaW5nKCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBub3QgZm91bmQKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0KLSAgICB9IC8vIGdldENvbnRlbnRTcGVjQXNTdHJpbmcoaW50KTpTdHJpbmcKLQotICAgIC8vIGRlYnVnZ2luZwotCi0gICAgcHVibGljIHZvaWQgcHJpbnRFbGVtZW50cyggICkgewotICAgICAgICBpbnQgZWxlbWVudERlY2xJbmRleCA9IDA7Ci0gICAgICAgIFhNTEVsZW1lbnREZWNsIGVsZW1lbnREZWNsID0gbmV3IFhNTEVsZW1lbnREZWNsKCk7Ci0gICAgICAgIHdoaWxlIChnZXRFbGVtZW50RGVjbChlbGVtZW50RGVjbEluZGV4KyssIGVsZW1lbnREZWNsKSkgewotCi0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oImVsZW1lbnQgZGVjbDogIitlbGVtZW50RGVjbC5uYW1lKwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIsICIrIGVsZW1lbnREZWNsLm5hbWUucmF3bmFtZSAgKTsKLQotICAgICAgICAgICAgLy8gICAgICAgICAgICAgICAgICAgIiwgIisgZWxlbWVudERlY2wuY29udGVudE1vZGVsVmFsaWRhdG9yLnRvU3RyaW5nKCkpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgcHJpbnRBdHRyaWJ1dGVzKGludCBlbGVtZW50RGVjbEluZGV4KSB7Ci0gICAgICAgIGludCBhdHRyaWJ1dGVEZWNsSW5kZXggPSBnZXRGaXJzdEF0dHJpYnV0ZURlY2xJbmRleChlbGVtZW50RGVjbEluZGV4KTsKLSAgICAgICAgU3lzdGVtLm91dC5wcmludChlbGVtZW50RGVjbEluZGV4KTsKLSAgICAgICAgU3lzdGVtLm91dC5wcmludCgiIFsiKTsKLSAgICAgICAgd2hpbGUgKGF0dHJpYnV0ZURlY2xJbmRleCAhPSAtMSkgewotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgnICcpOwotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludChhdHRyaWJ1dGVEZWNsSW5kZXgpOwotICAgICAgICAgICAgcHJpbnRBdHRyaWJ1dGUoYXR0cmlidXRlRGVjbEluZGV4KTsKLSAgICAgICAgICAgIGF0dHJpYnV0ZURlY2xJbmRleCA9IGdldE5leHRBdHRyaWJ1dGVEZWNsSW5kZXgoYXR0cmlidXRlRGVjbEluZGV4KTsKLSAgICAgICAgICAgIGlmIChhdHRyaWJ1dGVEZWNsSW5kZXggIT0gLTEpIHsKLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCIsIik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCIgXSIpOwotICAgIH0KLQotICAgIC8vCi0gICAgLy8gUHJvdGVjdGVkIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogQWRkcyB0aGUgY29udGVudCBzcGVjIHRvIHRoZSBnaXZlbiBlbGVtZW50IGRlY2xhcmF0aW9uLgotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIGFkZENvbnRlbnRTcGVjVG9FbGVtZW50KFhNTEVsZW1lbnREZWNsIGVsZW1lbnREZWNsKSB7Ci0gICAgICAgIGlmICgoZkRlcHRoID09IDAgfHwgKGZEZXB0aCA9PSAxICYmIGVsZW1lbnREZWNsLnR5cGUgPT0gWE1MRWxlbWVudERlY2wuVFlQRV9NSVhFRCkpICYmCi0gICAgICAgICAgICAgICAgZk5vZGVJbmRleFN0YWNrICE9IG51bGwpIHsKLSAgICAgICAgICAgIGlmIChlbGVtZW50RGVjbC50eXBlID09IFhNTEVsZW1lbnREZWNsLlRZUEVfTUlYRUQpIHsKLSAgICAgICAgICAgICAgICBpbnQgcGNkYXRhID0gYWRkVW5pcXVlTGVhZk5vZGUobnVsbCk7Ci0gICAgICAgICAgICAgICAgaWYgKGZOb2RlSW5kZXhTdGFja1swXSA9PSAtMSkgewotICAgICAgICAgICAgICAgICAgICBmTm9kZUluZGV4U3RhY2tbMF0gPSBwY2RhdGE7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICBmTm9kZUluZGV4U3RhY2tbMF0gPSBhZGRDb250ZW50U3BlY05vZGUoWE1MQ29udGVudFNwZWMuQ09OVEVOVFNQRUNOT0RFX0NIT0lDRSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBwY2RhdGEsIGZOb2RlSW5kZXhTdGFja1swXSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgc2V0Q29udGVudFNwZWNJbmRleChmQ3VycmVudEVsZW1lbnRJbmRleCwgZk5vZGVJbmRleFN0YWNrW2ZEZXB0aF0pOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogZ2V0RWxlbWVudENvbnRlbnRNb2RlbFZhbGlkYXRvcgotICAgICAqCi0gICAgICogQHBhcmFtIGVsZW1lbnREZWNsSW5kZXgKLSAgICAgKgotICAgICAqIEByZXR1cm4gaXRzIENvbnRlbnRNb2RlbFZhbGlkYXRvciBpZiBhbnkuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIENvbnRlbnRNb2RlbFZhbGlkYXRvciBnZXRFbGVtZW50Q29udGVudE1vZGVsVmFsaWRhdG9yKGludCBlbGVtZW50RGVjbEluZGV4KSB7Ci0KLSAgICAgICAgaW50IGNodW5rID0gZWxlbWVudERlY2xJbmRleCA+PiBDSFVOS19TSElGVDsKLSAgICAgICAgaW50IGluZGV4ID0gZWxlbWVudERlY2xJbmRleCAmIENIVU5LX01BU0s7Ci0KLSAgICAgICAgQ29udGVudE1vZGVsVmFsaWRhdG9yIGNvbnRlbnRNb2RlbCAgICA9ICBmRWxlbWVudERlY2xDb250ZW50TW9kZWxWYWxpZGF0b3JbY2h1bmtdW2luZGV4XTsKLQotICAgICAgICAvLyBJZiB3ZSBoYXZlIG9uZSwganVzdCByZXR1cm4gdGhhdC4gT3RoZXJ3aXNlLCBnb3R0YSBjcmVhdGUgb25lCi0gICAgICAgIGlmIChjb250ZW50TW9kZWwgIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIGNvbnRlbnRNb2RlbDsKLSAgICAgICAgfQotCi0gICAgICAgIGludCBjb250ZW50VHlwZSA9IGZFbGVtZW50RGVjbFR5cGVbY2h1bmtdW2luZGV4XTsKLSAgICAgICAgaWYgKGNvbnRlbnRUeXBlID09IFhNTEVsZW1lbnREZWNsLlRZUEVfU0lNUExFKSB7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIEdldCB0aGUgdHlwZSBvZiBjb250ZW50IHRoaXMgZWxlbWVudCBoYXMKLSAgICAgICAgaW50IGNvbnRlbnRTcGVjSW5kZXggPSBmRWxlbWVudERlY2xDb250ZW50U3BlY0luZGV4W2NodW5rXVtpbmRleF07Ci0KLSAgICAgICAgLyoqKgotICAgICAgICBpZiAoIGNvbnRlbnRTcGVjSW5kZXggPT0gLTEgKQotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIC8qKiovCi0KLSAgICAgICAgWE1MQ29udGVudFNwZWMgIGNvbnRlbnRTcGVjID0gbmV3IFhNTENvbnRlbnRTcGVjKCk7Ci0gICAgICAgIGdldENvbnRlbnRTcGVjKCBjb250ZW50U3BlY0luZGV4LCBjb250ZW50U3BlYyApOwotCi0gICAgICAgIC8vIEFuZCBjcmVhdGUgdGhlIGNvbnRlbnQgbW9kZWwgYWNjb3JkaW5nIHRvIHRoZSBzcGVjIHR5cGUKLSAgICAgICAgaWYgKCBjb250ZW50VHlwZSA9PSBYTUxFbGVtZW50RGVjbC5UWVBFX01JWEVEICkgewotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIC8vICBKdXN0IGNyZWF0ZSBhIG1peGVsIGNvbnRlbnQgbW9kZWwgb2JqZWN0LiBUaGlzIHR5cGUgb2YKLSAgICAgICAgICAgIC8vICBjb250ZW50IG1vZGVsIGlzIG9wdGltaXplZCBmb3IgbWl4ZWQgY29udGVudCB2YWxpZGF0aW9uLgotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIENoaWxkcmVuTGlzdCBjaGlsZHJlbiA9IG5ldyBDaGlsZHJlbkxpc3QoKTsKLSAgICAgICAgICAgIGNvbnRlbnRTcGVjVHJlZShjb250ZW50U3BlY0luZGV4LCBjb250ZW50U3BlYywgY2hpbGRyZW4pOwotICAgICAgICAgICAgY29udGVudE1vZGVsID0gbmV3IE1peGVkQ29udGVudE1vZGVsKGNoaWxkcmVuLnFuYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuLnR5cGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgY2hpbGRyZW4ubGVuZ3RoLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlKTsKLSAgICAgICAgfSBlbHNlIGlmIChjb250ZW50VHlwZSA9PSBYTUxFbGVtZW50RGVjbC5UWVBFX0NISUxEUkVOKSB7Ci0gICAgICAgICAgICAvLyAgVGhpcyBtZXRob2Qgd2lsbCBjcmVhdGUgYW4gb3B0aW1hbCBtb2RlbCBmb3IgdGhlIGNvbXBsZXhpdHkKLSAgICAgICAgICAgIC8vICBvZiB0aGUgZWxlbWVudCdzIGRlZmluZWQgbW9kZWwuIElmIGl0cyBzaW1wbGUsIGl0IHdpbGwgY3JlYXRlCi0gICAgICAgICAgICAvLyAgYSBTaW1wbGVDb250ZW50TW9kZWwgb2JqZWN0LiBJZiBpdHMgYSBzaW1wbGUgbGlzdCwgaXQgd2lsbAotICAgICAgICAgICAgLy8gIGNyZWF0ZSBhIFNpbXBsZUxpc3RDb250ZW50TW9kZWwgb2JqZWN0LiBJZiBpdHMgY29tcGxleCwgaXQKLSAgICAgICAgICAgIC8vICB3aWxsIGNyZWF0ZSBhIERGQUNvbnRlbnRNb2RlbCBvYmplY3QuCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgY29udGVudE1vZGVsID0gY3JlYXRlQ2hpbGRNb2RlbChjb250ZW50U3BlY0luZGV4KTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJVbmtub3duIGNvbnRlbnQgdHlwZSBmb3IgYSBlbGVtZW50IGRlY2wgIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgImluIGdldEVsZW1lbnRDb250ZW50TW9kZWxWYWxpZGF0b3IoKSBpbiBBYnN0cmFjdERUREdyYW1tYXIgY2xhc3MiKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIEFkZCB0aGUgbmV3IG1vZGVsIHRvIHRoZSBjb250ZW50IG1vZGVsIGZvciB0aGlzIGVsZW1lbnQKLSAgICAgICAgZkVsZW1lbnREZWNsQ29udGVudE1vZGVsVmFsaWRhdG9yW2NodW5rXVtpbmRleF0gPSBjb250ZW50TW9kZWw7Ci0KLSAgICAgICAgcmV0dXJuIGNvbnRlbnRNb2RlbDsKLQotICAgIH0gLy8gZ2V0RWxlbWVudENvbnRlbnRNb2RlbFZhbGlkYXRvcihpbnQpOkNvbnRlbnRNb2RlbFZhbGlkYXRvcgotCi0gICBwcm90ZWN0ZWQgaW50IGNyZWF0ZUVsZW1lbnREZWNsKCkgewotICAgICAgaW50IGNodW5rID0gZkVsZW1lbnREZWNsQ291bnQgPj4gQ0hVTktfU0hJRlQ7Ci0gICAgICBpbnQgaW5kZXggPSBmRWxlbWVudERlY2xDb3VudCAmIENIVU5LX01BU0s7Ci0gICAgICBlbnN1cmVFbGVtZW50RGVjbENhcGFjaXR5KGNodW5rKTsKLSAgICAgIGZFbGVtZW50RGVjbE5hbWVbY2h1bmtdW2luZGV4XSAgICAgICAgICAgICAgICAgICAgPSBuZXcgUU5hbWUoKTsKLSAgICAgIGZFbGVtZW50RGVjbFR5cGVbY2h1bmtdW2luZGV4XSAgICAgICAgICAgICAgICAgICAgPSAtMTsKLSAgICAgIGZFbGVtZW50RGVjbENvbnRlbnRNb2RlbFZhbGlkYXRvcltjaHVua11baW5kZXhdICAgPSBudWxsOwotICAgICAgZkVsZW1lbnREZWNsRmlyc3RBdHRyaWJ1dGVEZWNsSW5kZXhbY2h1bmtdW2luZGV4XSA9IC0xOwotICAgICAgZkVsZW1lbnREZWNsTGFzdEF0dHJpYnV0ZURlY2xJbmRleFtjaHVua11baW5kZXhdICA9IC0xOwotICAgICAgcmV0dXJuIGZFbGVtZW50RGVjbENvdW50Kys7Ci0gICB9Ci0KLSAgIHByb3RlY3RlZCB2b2lkIHNldEVsZW1lbnREZWNsKGludCBlbGVtZW50RGVjbEluZGV4LCBYTUxFbGVtZW50RGVjbCBlbGVtZW50RGVjbCkgewotICAgICAgaWYgKGVsZW1lbnREZWNsSW5kZXggPCAwIHx8IGVsZW1lbnREZWNsSW5kZXggPj0gZkVsZW1lbnREZWNsQ291bnQpIHsKLSAgICAgICAgIHJldHVybjsKLSAgICAgIH0KLSAgICAgIGludCAgICAgY2h1bmsgICAgICAgPSBlbGVtZW50RGVjbEluZGV4ID4+IENIVU5LX1NISUZUOwotICAgICAgaW50ICAgICBpbmRleCAgICAgICA9IGVsZW1lbnREZWNsSW5kZXggJiAgQ0hVTktfTUFTSzsKLQotICAgICAgZkVsZW1lbnREZWNsTmFtZVtjaHVua11baW5kZXhdLnNldFZhbHVlcyhlbGVtZW50RGVjbC5uYW1lKTsKLSAgICAgIGZFbGVtZW50RGVjbFR5cGVbY2h1bmtdW2luZGV4XSAgICAgICAgICAgICAgICAgID0gZWxlbWVudERlY2wudHlwZTsKLQotICAgICAgZkVsZW1lbnREZWNsQ29udGVudE1vZGVsVmFsaWRhdG9yW2NodW5rXVtpbmRleF0gPSBlbGVtZW50RGVjbC5jb250ZW50TW9kZWxWYWxpZGF0b3I7Ci0KLSAgICAgIGlmIChlbGVtZW50RGVjbC5zaW1wbGVUeXBlLmxpc3QgID09IHRydWUgKSB7Ci0gICAgICAgICBmRWxlbWVudERlY2xUeXBlW2NodW5rXVtpbmRleF0gfD0gTElTVF9GTEFHOwotICAgICAgfQotCi0gICAgICBmRWxlbWVudEluZGV4TWFwLnB1dChlbGVtZW50RGVjbC5uYW1lLnJhd25hbWUsIGVsZW1lbnREZWNsSW5kZXgpOwotICAgfQotCi0KLQotCi0gICBwcm90ZWN0ZWQgdm9pZCBwdXRFbGVtZW50TmFtZU1hcHBpbmcoUU5hbWUgbmFtZSwgaW50IHNjb3BlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBlbGVtZW50RGVjbEluZGV4KSB7Ci0gICB9Ci0KLSAgIHByb3RlY3RlZCB2b2lkIHNldEZpcnN0QXR0cmlidXRlRGVjbEluZGV4KGludCBlbGVtZW50RGVjbEluZGV4LCBpbnQgbmV3Rmlyc3RBdHRySW5kZXgpewotCi0gICAgICBpZiAoZWxlbWVudERlY2xJbmRleCA8IDAgfHwgZWxlbWVudERlY2xJbmRleCA+PSBmRWxlbWVudERlY2xDb3VudCkgewotICAgICAgICAgcmV0dXJuOwotICAgICAgfQotCi0gICAgICBpbnQgY2h1bmsgPSBlbGVtZW50RGVjbEluZGV4ID4+IENIVU5LX1NISUZUOwotICAgICAgaW50IGluZGV4ID0gZWxlbWVudERlY2xJbmRleCAmICBDSFVOS19NQVNLOwotCi0gICAgICBmRWxlbWVudERlY2xGaXJzdEF0dHJpYnV0ZURlY2xJbmRleFtjaHVua11baW5kZXhdID0gbmV3Rmlyc3RBdHRySW5kZXg7Ci0gICB9Ci0KLSAgIHByb3RlY3RlZCB2b2lkIHNldENvbnRlbnRTcGVjSW5kZXgoaW50IGVsZW1lbnREZWNsSW5kZXgsIGludCBjb250ZW50U3BlY0luZGV4KXsKLQotICAgICAgaWYgKGVsZW1lbnREZWNsSW5kZXggPCAwIHx8IGVsZW1lbnREZWNsSW5kZXggPj0gZkVsZW1lbnREZWNsQ291bnQpIHsKLSAgICAgICAgIHJldHVybjsKLSAgICAgIH0KLQotICAgICAgaW50IGNodW5rID0gZWxlbWVudERlY2xJbmRleCA+PiBDSFVOS19TSElGVDsKLSAgICAgIGludCBpbmRleCA9IGVsZW1lbnREZWNsSW5kZXggJiAgQ0hVTktfTUFTSzsKLQotICAgICAgZkVsZW1lbnREZWNsQ29udGVudFNwZWNJbmRleFtjaHVua11baW5kZXhdID0gY29udGVudFNwZWNJbmRleDsKLSAgIH0KLQotCi0gICBwcm90ZWN0ZWQgaW50IGNyZWF0ZUF0dHJpYnV0ZURlY2woKSB7Ci0gICAgICBpbnQgY2h1bmsgPSBmQXR0cmlidXRlRGVjbENvdW50ID4+IENIVU5LX1NISUZUOwotICAgICAgaW50IGluZGV4ID0gZkF0dHJpYnV0ZURlY2xDb3VudCAmIENIVU5LX01BU0s7Ci0KLSAgICAgIGVuc3VyZUF0dHJpYnV0ZURlY2xDYXBhY2l0eShjaHVuayk7Ci0gICAgICBmQXR0cmlidXRlRGVjbE5hbWVbY2h1bmtdW2luZGV4XSAgICAgICAgICAgICAgICAgICAgPSBuZXcgUU5hbWUoKTsKLSAgICAgIGZBdHRyaWJ1dGVEZWNsVHlwZVtjaHVua11baW5kZXhdICAgICAgICAgICAgICAgICAgICA9IC0xOwotICAgICAgZkF0dHJpYnV0ZURlY2xEYXRhdHlwZVZhbGlkYXRvcltjaHVua11baW5kZXhdICAgICAgID0gbnVsbDsKLSAgICAgIGZBdHRyaWJ1dGVEZWNsRW51bWVyYXRpb25bY2h1bmtdW2luZGV4XSAgICAgICAgICAgICA9IG51bGw7Ci0gICAgICBmQXR0cmlidXRlRGVjbERlZmF1bHRUeXBlW2NodW5rXVtpbmRleF0gICAgICAgICAgICAgPSBYTUxTaW1wbGVUeXBlLkRFRkFVTFRfVFlQRV9JTVBMSUVEOwotICAgICAgZkF0dHJpYnV0ZURlY2xEZWZhdWx0VmFsdWVbY2h1bmtdW2luZGV4XSAgICAgICAgICAgID0gbnVsbDsKLSAgICAgIGZBdHRyaWJ1dGVEZWNsTm9uTm9ybWFsaXplZERlZmF1bHRWYWx1ZVtjaHVua11baW5kZXhdICAgICAgICAgICAgPSBudWxsOwotICAgICAgZkF0dHJpYnV0ZURlY2xOZXh0QXR0cmlidXRlRGVjbEluZGV4W2NodW5rXVtpbmRleF0gID0gLTE7Ci0gICAgICByZXR1cm4gZkF0dHJpYnV0ZURlY2xDb3VudCsrOwotICAgfQotCi0KLSAgIHByb3RlY3RlZCB2b2lkIHNldEF0dHJpYnV0ZURlY2woaW50IGVsZW1lbnREZWNsSW5kZXgsIGludCBhdHRyaWJ1dGVEZWNsSW5kZXgsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTEF0dHJpYnV0ZURlY2wgYXR0cmlidXRlRGVjbCkgewotICAgICAgaW50IGF0dHJDaHVuayA9IGF0dHJpYnV0ZURlY2xJbmRleCA+PiBDSFVOS19TSElGVDsKLSAgICAgIGludCBhdHRySW5kZXggPSBhdHRyaWJ1dGVEZWNsSW5kZXggJiAgQ0hVTktfTUFTSzsKLSAgICAgIGZBdHRyaWJ1dGVEZWNsTmFtZVthdHRyQ2h1bmtdW2F0dHJJbmRleF0uc2V0VmFsdWVzKGF0dHJpYnV0ZURlY2wubmFtZSk7Ci0gICAgICBmQXR0cmlidXRlRGVjbFR5cGVbYXR0ckNodW5rXVthdHRySW5kZXhdICA9ICBhdHRyaWJ1dGVEZWNsLnNpbXBsZVR5cGUudHlwZTsKLQotICAgICAgaWYgKGF0dHJpYnV0ZURlY2wuc2ltcGxlVHlwZS5saXN0KSB7Ci0gICAgICAgICBmQXR0cmlidXRlRGVjbFR5cGVbYXR0ckNodW5rXVthdHRySW5kZXhdIHw9IExJU1RfRkxBRzsKLSAgICAgIH0KLSAgICAgIGZBdHRyaWJ1dGVEZWNsRW51bWVyYXRpb25bYXR0ckNodW5rXVthdHRySW5kZXhdICA9ICBhdHRyaWJ1dGVEZWNsLnNpbXBsZVR5cGUuZW51bWVyYXRpb247Ci0gICAgICBmQXR0cmlidXRlRGVjbERlZmF1bHRUeXBlW2F0dHJDaHVua11bYXR0ckluZGV4XSAgPSAgYXR0cmlidXRlRGVjbC5zaW1wbGVUeXBlLmRlZmF1bHRUeXBlOwotICAgICAgZkF0dHJpYnV0ZURlY2xEYXRhdHlwZVZhbGlkYXRvclthdHRyQ2h1bmtdW2F0dHJJbmRleF0gPSAgYXR0cmlidXRlRGVjbC5zaW1wbGVUeXBlLmRhdGF0eXBlVmFsaWRhdG9yOwotCi0gICAgICBmQXR0cmlidXRlRGVjbERlZmF1bHRWYWx1ZVthdHRyQ2h1bmtdW2F0dHJJbmRleF0gPSBhdHRyaWJ1dGVEZWNsLnNpbXBsZVR5cGUuZGVmYXVsdFZhbHVlOwotICAgICAgZkF0dHJpYnV0ZURlY2xOb25Ob3JtYWxpemVkRGVmYXVsdFZhbHVlW2F0dHJDaHVua11bYXR0ckluZGV4XSA9IGF0dHJpYnV0ZURlY2wuc2ltcGxlVHlwZS5ub25Ob3JtYWxpemVkRGVmYXVsdFZhbHVlOwotCi0gICAgICBpbnQgZWxlbUNodW5rICAgICA9IGVsZW1lbnREZWNsSW5kZXggPj4gQ0hVTktfU0hJRlQ7Ci0gICAgICBpbnQgZWxlbUluZGV4ICAgICA9IGVsZW1lbnREZWNsSW5kZXggJiAgQ0hVTktfTUFTSzsKLSAgICAgIGludCBpbmRleCAgICAgICAgID0gZkVsZW1lbnREZWNsRmlyc3RBdHRyaWJ1dGVEZWNsSW5kZXhbZWxlbUNodW5rXVtlbGVtSW5kZXhdOwotICAgICAgd2hpbGUgKGluZGV4ICE9IC0xKSB7Ci0gICAgICAgICBpZiAoaW5kZXggPT0gYXR0cmlidXRlRGVjbEluZGV4KSB7Ci0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgIH0KLSAgICAgICAgIGF0dHJDaHVuayA9IGluZGV4ID4+IENIVU5LX1NISUZUOwotICAgICAgICAgYXR0ckluZGV4ID0gaW5kZXggJiBDSFVOS19NQVNLOwotICAgICAgICAgaW5kZXggPSBmQXR0cmlidXRlRGVjbE5leHRBdHRyaWJ1dGVEZWNsSW5kZXhbYXR0ckNodW5rXVthdHRySW5kZXhdOwotICAgICAgfQotICAgICAgaWYgKGluZGV4ID09IC0xKSB7Ci0gICAgICAgICBpZiAoZkVsZW1lbnREZWNsRmlyc3RBdHRyaWJ1dGVEZWNsSW5kZXhbZWxlbUNodW5rXVtlbGVtSW5kZXhdID09IC0xKSB7Ci0gICAgICAgICAgICBmRWxlbWVudERlY2xGaXJzdEF0dHJpYnV0ZURlY2xJbmRleFtlbGVtQ2h1bmtdW2VsZW1JbmRleF0gPSBhdHRyaWJ1dGVEZWNsSW5kZXg7Ci0gICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgaW5kZXggPSBmRWxlbWVudERlY2xMYXN0QXR0cmlidXRlRGVjbEluZGV4W2VsZW1DaHVua11bZWxlbUluZGV4XTsKLSAgICAgICAgICAgIGF0dHJDaHVuayA9IGluZGV4ID4+IENIVU5LX1NISUZUOwotICAgICAgICAgICAgYXR0ckluZGV4ID0gaW5kZXggJiBDSFVOS19NQVNLOwotICAgICAgICAgICAgZkF0dHJpYnV0ZURlY2xOZXh0QXR0cmlidXRlRGVjbEluZGV4W2F0dHJDaHVua11bYXR0ckluZGV4XSA9IGF0dHJpYnV0ZURlY2xJbmRleDsKLSAgICAgICAgIH0KLSAgICAgICAgIGZFbGVtZW50RGVjbExhc3RBdHRyaWJ1dGVEZWNsSW5kZXhbZWxlbUNodW5rXVtlbGVtSW5kZXhdID0gYXR0cmlidXRlRGVjbEluZGV4OwotICAgICAgfQotICAgfQotCi0gICBwcm90ZWN0ZWQgaW50IGNyZWF0ZUNvbnRlbnRTcGVjKCkgewotICAgICAgaW50IGNodW5rID0gZkNvbnRlbnRTcGVjQ291bnQgPj4gQ0hVTktfU0hJRlQ7Ci0gICAgICBpbnQgaW5kZXggPSBmQ29udGVudFNwZWNDb3VudCAmIENIVU5LX01BU0s7Ci0KLSAgICAgIGVuc3VyZUNvbnRlbnRTcGVjQ2FwYWNpdHkoY2h1bmspOwotICAgICAgZkNvbnRlbnRTcGVjVHlwZVtjaHVua11baW5kZXhdICAgICAgID0gLTE7Ci0gICAgICBmQ29udGVudFNwZWNWYWx1ZVtjaHVua11baW5kZXhdICAgICAgPSBudWxsOwotICAgICAgZkNvbnRlbnRTcGVjT3RoZXJWYWx1ZVtjaHVua11baW5kZXhdID0gbnVsbDsKLQotICAgICAgcmV0dXJuIGZDb250ZW50U3BlY0NvdW50Kys7Ci0gICB9Ci0KLSAgIHByb3RlY3RlZCB2b2lkIHNldENvbnRlbnRTcGVjKGludCBjb250ZW50U3BlY0luZGV4LCBYTUxDb250ZW50U3BlYyBjb250ZW50U3BlYykgewotICAgICAgaW50ICAgY2h1bmsgPSBjb250ZW50U3BlY0luZGV4ID4+IENIVU5LX1NISUZUOwotICAgICAgaW50ICAgaW5kZXggPSBjb250ZW50U3BlY0luZGV4ICYgQ0hVTktfTUFTSzsKLQotICAgICAgZkNvbnRlbnRTcGVjVHlwZVtjaHVua11baW5kZXhdICAgICAgID0gY29udGVudFNwZWMudHlwZTsKLSAgICAgIGZDb250ZW50U3BlY1ZhbHVlW2NodW5rXVtpbmRleF0gICAgICA9IGNvbnRlbnRTcGVjLnZhbHVlOwotICAgICAgZkNvbnRlbnRTcGVjT3RoZXJWYWx1ZVtjaHVua11baW5kZXhdID0gY29udGVudFNwZWMub3RoZXJWYWx1ZTsKLSAgIH0KLQotCi0gICBwcm90ZWN0ZWQgaW50IGNyZWF0ZUVudGl0eURlY2woKSB7Ci0gICAgICAgaW50IGNodW5rID0gZkVudGl0eUNvdW50ID4+IENIVU5LX1NISUZUOwotICAgICAgIGludCBpbmRleCA9IGZFbnRpdHlDb3VudCAmIENIVU5LX01BU0s7Ci0KLSAgICAgIGVuc3VyZUVudGl0eURlY2xDYXBhY2l0eShjaHVuayk7Ci0gICAgICBmRW50aXR5SXNQRVtjaHVua11baW5kZXhdID0gMDsKLSAgICAgIGZFbnRpdHlJbkV4dGVybmFsW2NodW5rXVtpbmRleF0gPSAwOwotCi0gICAgICByZXR1cm4gZkVudGl0eUNvdW50Kys7Ci0gICB9Ci0KLSAgIHByb3RlY3RlZCB2b2lkIHNldEVudGl0eURlY2woaW50IGVudGl0eURlY2xJbmRleCwgWE1MRW50aXR5RGVjbCBlbnRpdHlEZWNsKSB7Ci0gICAgICAgaW50IGNodW5rID0gZW50aXR5RGVjbEluZGV4ID4+IENIVU5LX1NISUZUOwotICAgICAgIGludCBpbmRleCA9IGVudGl0eURlY2xJbmRleCAmIENIVU5LX01BU0s7Ci0KLSAgICAgICBmRW50aXR5TmFtZVtjaHVua11baW5kZXhdID0gZW50aXR5RGVjbC5uYW1lOwotICAgICAgIGZFbnRpdHlWYWx1ZVtjaHVua11baW5kZXhdID0gZW50aXR5RGVjbC52YWx1ZTsKLSAgICAgICBmRW50aXR5UHVibGljSWRbY2h1bmtdW2luZGV4XSA9IGVudGl0eURlY2wucHVibGljSWQ7Ci0gICAgICAgZkVudGl0eVN5c3RlbUlkW2NodW5rXVtpbmRleF0gPSBlbnRpdHlEZWNsLnN5c3RlbUlkOwotICAgICAgIGZFbnRpdHlCYXNlU3lzdGVtSWRbY2h1bmtdW2luZGV4XSA9IGVudGl0eURlY2wuYmFzZVN5c3RlbUlkOwotICAgICAgIGZFbnRpdHlOb3RhdGlvbltjaHVua11baW5kZXhdID0gZW50aXR5RGVjbC5ub3RhdGlvbjsKLSAgICAgICBmRW50aXR5SXNQRVtjaHVua11baW5kZXhdID0gZW50aXR5RGVjbC5pc1BFID8gKGJ5dGUpMSA6IChieXRlKTA7Ci0gICAgICAgZkVudGl0eUluRXh0ZXJuYWxbY2h1bmtdW2luZGV4XSA9IGVudGl0eURlY2wuaW5FeHRlcm5hbCA/IChieXRlKTEgOiAoYnl0ZSkwOwotCi0gICAgICAgZkVudGl0eUluZGV4TWFwLnB1dChlbnRpdHlEZWNsLm5hbWUsIGVudGl0eURlY2xJbmRleCk7Ci0gICB9Ci0KLSAgIHByb3RlY3RlZCBpbnQgY3JlYXRlTm90YXRpb25EZWNsKCkgewotICAgICAgIGludCBjaHVuayA9IGZOb3RhdGlvbkNvdW50ID4+IENIVU5LX1NISUZUOwotICAgICAgIGVuc3VyZU5vdGF0aW9uRGVjbENhcGFjaXR5KGNodW5rKTsKLSAgICAgICByZXR1cm4gZk5vdGF0aW9uQ291bnQrKzsKLSAgIH0KLQotICAgcHJvdGVjdGVkIHZvaWQgc2V0Tm90YXRpb25EZWNsKGludCBub3RhdGlvbkRlY2xJbmRleCwgWE1MTm90YXRpb25EZWNsIG5vdGF0aW9uRGVjbCkgewotICAgICAgIGludCBjaHVuayA9IG5vdGF0aW9uRGVjbEluZGV4ID4+IENIVU5LX1NISUZUOwotICAgICAgIGludCBpbmRleCA9IG5vdGF0aW9uRGVjbEluZGV4ICYgQ0hVTktfTUFTSzsKLQotICAgICAgIGZOb3RhdGlvbk5hbWVbY2h1bmtdW2luZGV4XSA9IG5vdGF0aW9uRGVjbC5uYW1lOwotICAgICAgIGZOb3RhdGlvblB1YmxpY0lkW2NodW5rXVtpbmRleF0gPSBub3RhdGlvbkRlY2wucHVibGljSWQ7Ci0gICAgICAgZk5vdGF0aW9uU3lzdGVtSWRbY2h1bmtdW2luZGV4XSA9IG5vdGF0aW9uRGVjbC5zeXN0ZW1JZDsKLSAgICAgICBmTm90YXRpb25CYXNlU3lzdGVtSWRbY2h1bmtdW2luZGV4XSA9IG5vdGF0aW9uRGVjbC5iYXNlU3lzdGVtSWQ7Ci0KLSAgICAgICBmTm90YXRpb25JbmRleE1hcC5wdXQobm90YXRpb25EZWNsLm5hbWUsIG5vdGF0aW9uRGVjbEluZGV4KTsKLSAgIH0KLQotICAgIC8qKgotICAgICAqIENyZWF0ZSBhbiBYTUxDb250ZW50U3BlYyBmb3IgYSBzaW5nbGUgbm9uLWxlYWYKLSAgICAgKgotICAgICAqIEBwYXJhbSBub2RlVHlwZSB0aGUgdHlwZSBvZiBYTUxDb250ZW50U3BlYyB0byBjcmVhdGUgLSBmcm9tIFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV8qCi0gICAgICogQHBhcmFtIG5vZGVWYWx1ZSBoYW5kbGUgdG8gYW4gWE1MQ29udGVudFNwZWMKLSAgICAgKiBAcmV0dXJuIGhhbmRsZSB0byB0aGUgbmV3bHkgY3JlYXRlIFhNTENvbnRlbnRTcGVjCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGludCBhZGRDb250ZW50U3BlY05vZGUoc2hvcnQgbm9kZVR5cGUsIFN0cmluZyBub2RlVmFsdWUpIHsKLQotICAgICAgICAvLyBjcmVhdGUgY29udGVudCBzcGVjIG5vZGUKLSAgICAgICAgaW50IGNvbnRlbnRTcGVjSW5kZXggPSBjcmVhdGVDb250ZW50U3BlYygpOwotCi0gICAgICAgIC8vIHNldCBjb250ZW50IHNwZWMgbm9kZSB2YWx1ZXMKLSAgICAgICAgZkNvbnRlbnRTcGVjLnNldFZhbHVlcyhub2RlVHlwZSwgbm9kZVZhbHVlLCBudWxsKTsKLSAgICAgICAgc2V0Q29udGVudFNwZWMoY29udGVudFNwZWNJbmRleCwgZkNvbnRlbnRTcGVjKTsKLQotICAgICAgICAvLyByZXR1cm4gaW5kZXgKLSAgICAgICAgcmV0dXJuIGNvbnRlbnRTcGVjSW5kZXg7Ci0KLSAgICB9IC8vIGFkZENvbnRlbnRTcGVjTm9kZShzaG9ydCxTdHJpbmcpOmludAotCi0gICAgLyoqCi0gICAgICogY3JlYXRlIGFuIFhNTENvbnRlbnRTcGVjIGZvciBhIGxlYWYKLSAgICAgKgotICAgICAqIEBwYXJhbSAgIGVsZW1lbnROYW1lICB0aGUgbmFtZSAoRWxlbWVudCkgZm9yIHRoZSBub2RlCi0gICAgICogQHJldHVybiBoYW5kbGUgdG8gdGhlIG5ld2x5IGNyZWF0ZSBYTUxDb250ZW50U3BlYwotICAgICAqLwotICAgIHByb3RlY3RlZCBpbnQgYWRkVW5pcXVlTGVhZk5vZGUoU3RyaW5nIGVsZW1lbnROYW1lKSB7Ci0KLSAgICAgICAgLy8gY3JlYXRlIGNvbnRlbnQgc3BlYyBub2RlCi0gICAgICAgIGludCBjb250ZW50U3BlY0luZGV4ID0gY3JlYXRlQ29udGVudFNwZWMoKTsKLQotICAgICAgICAvLyBzZXQgY29udGVudCBzcGVjIG5vZGUgdmFsdWVzCi0gICAgICAgIGZDb250ZW50U3BlYy5zZXRWYWx1ZXMoIFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9MRUFGLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50TmFtZSwgbnVsbCk7Ci0gICAgICAgIHNldENvbnRlbnRTcGVjKGNvbnRlbnRTcGVjSW5kZXgsIGZDb250ZW50U3BlYyk7Ci0KLSAgICAgICAgLy8gcmV0dXJuIGluZGV4Ci0gICAgICAgIHJldHVybiBjb250ZW50U3BlY0luZGV4OwotCi0gICAgfSAvLyBhZGRVbmlxdWVMZWFmTm9kZShTdHJpbmcpOmludAotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlIGFuIFhNTENvbnRlbnRTcGVjIGZvciBhIHR3byBjaGlsZCBsZWFmCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbm9kZVR5cGUgdGhlIHR5cGUgb2YgWE1MQ29udGVudFNwZWMgdG8gY3JlYXRlIC0gZnJvbSBYTUxDb250ZW50U3BlYy5DT05URU5UU1BFQ05PREVfKgotICAgICAqIEBwYXJhbSBsZWZ0Tm9kZUluZGV4IGhhbmRsZSB0byBhbiBYTUxDb250ZW50U3BlYwotICAgICAqIEBwYXJhbSByaWdodE5vZGVJbmRleCBoYW5kbGUgdG8gYW4gWE1MQ29udGVudFNwZWMKLSAgICAgKiBAcmV0dXJuIGhhbmRsZSB0byB0aGUgbmV3bHkgY3JlYXRlIFhNTENvbnRlbnRTcGVjCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGludCBhZGRDb250ZW50U3BlY05vZGUoc2hvcnQgbm9kZVR5cGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGxlZnROb2RlSW5kZXgsIGludCByaWdodE5vZGVJbmRleCkgewotCi0gICAgICAgIC8vIGNyZWF0ZSBjb250ZW50IHNwZWMgbm9kZQotICAgICAgICBpbnQgY29udGVudFNwZWNJbmRleCA9IGNyZWF0ZUNvbnRlbnRTcGVjKCk7Ci0KLSAgICAgICAgLy8gc2V0IGNvbnRlbnQgc3BlYyBub2RlIHZhbHVlcwotICAgICAgICBpbnRbXSBsZWZ0SW50QXJyYXkgID0gbmV3IGludFsxXTsKLSAgICAgICAgaW50W10gcmlnaHRJbnRBcnJheSA9IG5ldyBpbnRbMV07Ci0KLSAgICAgICAgbGVmdEludEFycmF5WzBdICAgICAgPSBsZWZ0Tm9kZUluZGV4OwotICAgICAgICByaWdodEludEFycmF5WzBdICAgID0gcmlnaHROb2RlSW5kZXg7Ci0gICAgICAgIGZDb250ZW50U3BlYy5zZXRWYWx1ZXMobm9kZVR5cGUsIGxlZnRJbnRBcnJheSwgcmlnaHRJbnRBcnJheSk7Ci0gICAgICAgIHNldENvbnRlbnRTcGVjKGNvbnRlbnRTcGVjSW5kZXgsIGZDb250ZW50U3BlYyk7Ci0KLSAgICAgICAgLy8gcmV0dXJuIGluZGV4Ci0gICAgICAgIHJldHVybiBjb250ZW50U3BlY0luZGV4OwotCi0gICAgfSAvLyBhZGRDb250ZW50U3BlY05vZGUoc2hvcnQsaW50LGludCk6aW50Ci0KLSAgICAvKiogSW5pdGlhbGl6ZSBjb250ZW50IG1vZGVsIHN0YWNrLiAqLwotICAgIHByb3RlY3RlZCB2b2lkIGluaXRpYWxpemVDb250ZW50TW9kZWxTdGFjaygpIHsKLQotICAgICAgICBpZiAoZk9wU3RhY2sgPT0gbnVsbCkgewotICAgICAgICAgICAgZk9wU3RhY2sgPSBuZXcgc2hvcnRbOF07Ci0gICAgICAgICAgICBmTm9kZUluZGV4U3RhY2sgPSBuZXcgaW50WzhdOwotICAgICAgICAgICAgZlByZXZOb2RlSW5kZXhTdGFjayA9IG5ldyBpbnRbOF07Ci0gICAgICAgIH0gZWxzZSBpZiAoZkRlcHRoID09IGZPcFN0YWNrLmxlbmd0aCkgewotICAgICAgICAgICAgc2hvcnRbXSBuZXdTdGFjayA9IG5ldyBzaG9ydFtmRGVwdGggKiAyXTsKLSAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZk9wU3RhY2ssIDAsIG5ld1N0YWNrLCAwLCBmRGVwdGgpOwotICAgICAgICAgICAgZk9wU3RhY2sgPSBuZXdTdGFjazsKLSAgICAgICAgICAgIGludFtdICAgbmV3SW50U3RhY2sgPSBuZXcgaW50W2ZEZXB0aCAqIDJdOwotICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShmTm9kZUluZGV4U3RhY2ssIDAsIG5ld0ludFN0YWNrLCAwLCBmRGVwdGgpOwotICAgICAgICAgICAgZk5vZGVJbmRleFN0YWNrID0gbmV3SW50U3RhY2s7Ci0gICAgICAgICAgICBuZXdJbnRTdGFjayA9IG5ldyBpbnRbZkRlcHRoICogMl07Ci0gICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGZQcmV2Tm9kZUluZGV4U3RhY2ssIDAsIG5ld0ludFN0YWNrLCAwLCBmRGVwdGgpOwotICAgICAgICAgICAgZlByZXZOb2RlSW5kZXhTdGFjayA9IG5ld0ludFN0YWNrOwotICAgICAgICB9Ci0gICAgICAgIGZPcFN0YWNrW2ZEZXB0aF0gPSAtMTsKLSAgICAgICAgZk5vZGVJbmRleFN0YWNrW2ZEZXB0aF0gPSAtMTsKLSAgICAgICAgZlByZXZOb2RlSW5kZXhTdGFja1tmRGVwdGhdID0gLTE7Ci0KLSAgICB9IC8vIGluaXRpYWxpemVDb250ZW50TW9kZWxTdGFjaygpCi0KLSAgICBib29sZWFuIGlzSW1tdXRhYmxlKCkgewotICAgICAgICByZXR1cm4gZklzSW1tdXRhYmxlOwotICAgIH0KLQotICAgIC8vCi0gICAgLy8gUHJpdmF0ZSBtZXRob2RzCi0gICAgLy8KLQotICAgIHByaXZhdGUgdm9pZCBhcHBlbmRDb250ZW50U3BlYyhYTUxDb250ZW50U3BlYyBjb250ZW50U3BlYywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nQnVmZmVyIHN0ciwgYm9vbGVhbiBwYXJlbnMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBwYXJlbnRDb250ZW50U3BlY1R5cGUgKSB7Ci0KLSAgICAgICAgaW50IHRoaXNDb250ZW50U3BlYyA9IGNvbnRlbnRTcGVjLnR5cGUgJiAweDBmOwotICAgICAgICBzd2l0Y2ggKHRoaXNDb250ZW50U3BlYykgewotICAgICAgICAgICAgY2FzZSBYTUxDb250ZW50U3BlYy5DT05URU5UU1BFQ05PREVfTEVBRjogewotICAgICAgICAgICAgICAgIGlmIChjb250ZW50U3BlYy52YWx1ZSA9PSBudWxsICYmIGNvbnRlbnRTcGVjLm90aGVyVmFsdWUgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKCIjUENEQVRBIik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgaWYgKGNvbnRlbnRTcGVjLnZhbHVlID09IG51bGwgJiYgY29udGVudFNwZWMub3RoZXJWYWx1ZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIHN0ci5hcHBlbmQoIiMjYW55OnVyaT0iKS5hcHBlbmQoY29udGVudFNwZWMub3RoZXJWYWx1ZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgaWYgKGNvbnRlbnRTcGVjLnZhbHVlID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgc3RyLmFwcGVuZCgiIyNhbnkiKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIHN0ci5hcHBlbmQoY29udGVudFNwZWMudmFsdWUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhc2UgWE1MQ29udGVudFNwZWMuQ09OVEVOVFNQRUNOT0RFX1pFUk9fT1JfT05FOiB7Ci0gICAgICAgICAgICAgICAgaWYgKHBhcmVudENvbnRlbnRTcGVjVHlwZSA9PSBYTUxDb250ZW50U3BlYy5DT05URU5UU1BFQ05PREVfT05FX09SX01PUkUgIHx8Ci0gICAgICAgICAgICAgICAgICAgIHBhcmVudENvbnRlbnRTcGVjVHlwZSA9PSBYTUxDb250ZW50U3BlYy5DT05URU5UU1BFQ05PREVfWkVST19PUl9NT1JFIHx8Ci0gICAgICAgICAgICAgICAgICAgIHBhcmVudENvbnRlbnRTcGVjVHlwZSA9PSBYTUxDb250ZW50U3BlYy5DT05URU5UU1BFQ05PREVfWkVST19PUl9PTkUgKSB7Ci0gICAgICAgICAgICAgICAgICAgIGdldENvbnRlbnRTcGVjKCgoaW50W10pY29udGVudFNwZWMudmFsdWUpWzBdLCBjb250ZW50U3BlYyk7Ci0gICAgICAgICAgICAgICAgICAgIHN0ci5hcHBlbmQoJygnKTsKLSAgICAgICAgICAgICAgICAgICAgYXBwZW5kQ29udGVudFNwZWMoY29udGVudFNwZWMsIHN0ciwgdHJ1ZSwgdGhpc0NvbnRlbnRTcGVjICk7Ci0gICAgICAgICAgICAgICAgICAgIHN0ci5hcHBlbmQoJyknKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIGdldENvbnRlbnRTcGVjKCgoaW50W10pY29udGVudFNwZWMudmFsdWUpWzBdLCBjb250ZW50U3BlYyk7Ci0gICAgICAgICAgICAgICAgICAgIGFwcGVuZENvbnRlbnRTcGVjKCBjb250ZW50U3BlYywgc3RyLCB0cnVlLCB0aGlzQ29udGVudFNwZWMgKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgc3RyLmFwcGVuZCgnPycpOwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2FzZSBYTUxDb250ZW50U3BlYy5DT05URU5UU1BFQ05PREVfWkVST19PUl9NT1JFOiB7Ci0gICAgICAgICAgICAgICAgaWYgKHBhcmVudENvbnRlbnRTcGVjVHlwZSA9PSBYTUxDb250ZW50U3BlYy5DT05URU5UU1BFQ05PREVfT05FX09SX01PUkUgfHwKLSAgICAgICAgICAgICAgICAgICAgcGFyZW50Q29udGVudFNwZWNUeXBlID09IFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9aRVJPX09SX01PUkUgfHwKLSAgICAgICAgICAgICAgICAgICAgcGFyZW50Q29udGVudFNwZWNUeXBlID09IFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9aRVJPX09SX09ORSApIHsKLSAgICAgICAgICAgICAgICAgICAgZ2V0Q29udGVudFNwZWMoKChpbnRbXSljb250ZW50U3BlYy52YWx1ZSlbMF0sIGNvbnRlbnRTcGVjKTsKLSAgICAgICAgICAgICAgICAgICAgc3RyLmFwcGVuZCgnKCcpOwotICAgICAgICAgICAgICAgICAgICBhcHBlbmRDb250ZW50U3BlYyhjb250ZW50U3BlYywgc3RyLCB0cnVlLCB0aGlzQ29udGVudFNwZWMpOwotICAgICAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKCcpJyApOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgZ2V0Q29udGVudFNwZWMoKChpbnRbXSljb250ZW50U3BlYy52YWx1ZSlbMF0sIGNvbnRlbnRTcGVjKTsKLSAgICAgICAgICAgICAgICAgICAgYXBwZW5kQ29udGVudFNwZWMoY29udGVudFNwZWMsIHN0ciwgdHJ1ZSwgdGhpc0NvbnRlbnRTcGVjKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgc3RyLmFwcGVuZCgnKicpOwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2FzZSBYTUxDb250ZW50U3BlYy5DT05URU5UU1BFQ05PREVfT05FX09SX01PUkU6IHsKLSAgICAgICAgICAgICAgICBpZiAocGFyZW50Q29udGVudFNwZWNUeXBlID09IFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9PTkVfT1JfTU9SRSAgIHx8Ci0gICAgICAgICAgICAgICAgICAgIHBhcmVudENvbnRlbnRTcGVjVHlwZSA9PSBYTUxDb250ZW50U3BlYy5DT05URU5UU1BFQ05PREVfWkVST19PUl9NT1JFICB8fAotICAgICAgICAgICAgICAgICAgICBwYXJlbnRDb250ZW50U3BlY1R5cGUgPT0gWE1MQ29udGVudFNwZWMuQ09OVEVOVFNQRUNOT0RFX1pFUk9fT1JfT05FICkgewotCi0gICAgICAgICAgICAgICAgICAgIHN0ci5hcHBlbmQoJygnKTsKLSAgICAgICAgICAgICAgICAgICAgZ2V0Q29udGVudFNwZWMoKChpbnRbXSljb250ZW50U3BlYy52YWx1ZSlbMF0sIGNvbnRlbnRTcGVjKTsKLSAgICAgICAgICAgICAgICAgICAgYXBwZW5kQ29udGVudFNwZWMoY29udGVudFNwZWMsIHN0ciwgdHJ1ZSwgdGhpc0NvbnRlbnRTcGVjKTsKLSAgICAgICAgICAgICAgICAgICAgc3RyLmFwcGVuZCgnKScgKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIGdldENvbnRlbnRTcGVjKCgoaW50W10pY29udGVudFNwZWMudmFsdWUpWzBdLCBjb250ZW50U3BlYyk7Ci0gICAgICAgICAgICAgICAgICAgIGFwcGVuZENvbnRlbnRTcGVjKGNvbnRlbnRTcGVjLCBzdHIsIHRydWUsIHRoaXNDb250ZW50U3BlYyk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHN0ci5hcHBlbmQoJysnKTsKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhc2UgWE1MQ29udGVudFNwZWMuQ09OVEVOVFNQRUNOT0RFX0NIT0lDRToKLSAgICAgICAgICAgIGNhc2UgWE1MQ29udGVudFNwZWMuQ09OVEVOVFNQRUNOT0RFX1NFUTogewotICAgICAgICAgICAgICAgIGlmIChwYXJlbnMpIHsKLSAgICAgICAgICAgICAgICAgICAgc3RyLmFwcGVuZCgnKCcpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpbnQgdHlwZSA9IGNvbnRlbnRTcGVjLnR5cGU7Ci0gICAgICAgICAgICAgICAgaW50IG90aGVyVmFsdWUgPSAoKGludFtdKWNvbnRlbnRTcGVjLm90aGVyVmFsdWUpWzBdOwotICAgICAgICAgICAgICAgIGdldENvbnRlbnRTcGVjKCgoaW50W10pY29udGVudFNwZWMudmFsdWUpWzBdLCBjb250ZW50U3BlYyk7Ci0gICAgICAgICAgICAgICAgYXBwZW5kQ29udGVudFNwZWMoY29udGVudFNwZWMsIHN0ciwgY29udGVudFNwZWMudHlwZSAhPSB0eXBlLCB0aGlzQ29udGVudFNwZWMpOwotICAgICAgICAgICAgICAgIGlmICh0eXBlID09IFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9DSE9JQ0UpIHsKLSAgICAgICAgICAgICAgICAgICAgc3RyLmFwcGVuZCgnfCcpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgc3RyLmFwcGVuZCgnLCcpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBnZXRDb250ZW50U3BlYyhvdGhlclZhbHVlLCBjb250ZW50U3BlYyk7Ci0gICAgICAgICAgICAgICAgYXBwZW5kQ29udGVudFNwZWMoY29udGVudFNwZWMsIHN0ciwgdHJ1ZSwgdGhpc0NvbnRlbnRTcGVjKTsKLSAgICAgICAgICAgICAgICBpZiAocGFyZW5zKSB7Ci0gICAgICAgICAgICAgICAgICAgIHN0ci5hcHBlbmQoJyknKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXNlIFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9BTlk6IHsKLSAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKCIjI2FueSIpOwotICAgICAgICAgICAgICAgIGlmIChjb250ZW50U3BlYy5vdGhlclZhbHVlICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgc3RyLmFwcGVuZCgiOnVyaT0iKTsKLSAgICAgICAgICAgICAgICAgICAgc3RyLmFwcGVuZChjb250ZW50U3BlYy5vdGhlclZhbHVlKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXNlIFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9BTllfT1RIRVI6IHsKLSAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKCIjI290aGVyOnVyaT0iKTsKLSAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKGNvbnRlbnRTcGVjLm90aGVyVmFsdWUpOwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2FzZSBYTUxDb250ZW50U3BlYy5DT05URU5UU1BFQ05PREVfQU5ZX0xPQ0FMOiB7Ci0gICAgICAgICAgICAgICAgc3RyLmFwcGVuZCgiIyNsb2NhbCIpOwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZGVmYXVsdDogewotICAgICAgICAgICAgICAgIHN0ci5hcHBlbmQoIj8/PyIpOwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotCi0gICAgICAgIH0gLy8gc3dpdGNoIHR5cGUKLQotICAgIH0gLy8gYXBwZW5kQ29udGVudFNwZWMoWE1MQ29udGVudFNwZWMuUHJvdmlkZXIsU3RyaW5nUG9vbCxYTUxDb250ZW50U3BlYyxTdHJpbmdCdWZmZXIsYm9vbGVhbikKLQotICAgIC8vIGRlYnVnZ2luZwotCi0gICAgcHJpdmF0ZSB2b2lkIHByaW50QXR0cmlidXRlKGludCBhdHRyaWJ1dGVEZWNsSW5kZXgpIHsKLQotICAgICAgICBYTUxBdHRyaWJ1dGVEZWNsIGF0dHJpYnV0ZURlY2wgPSBuZXcgWE1MQXR0cmlidXRlRGVjbCgpOwotICAgICAgICBpZiAoZ2V0QXR0cmlidXRlRGVjbChhdHRyaWJ1dGVEZWNsSW5kZXgsIGF0dHJpYnV0ZURlY2wpKSB7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCIgeyAiKTsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoYXR0cmlidXRlRGVjbC5uYW1lLmxvY2FscGFydCk7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCIgfSIpOwotICAgICAgICB9Ci0KLSAgICB9IC8vIHByaW50QXR0cmlidXRlKGludCkKLQotICAgIC8vIGNvbnRlbnQgbW9kZWxzCi0KLSAgICAvKioKLSAgICAgKiBXaGVuIHRoZSBlbGVtZW50IGhhcyBhICdDSElMRFJFTicgbW9kZWwsIHRoaXMgbWV0aG9kIGlzIGNhbGxlZCB0bwotICAgICAqIGNyZWF0ZSB0aGUgY29udGVudCBtb2RlbCBvYmplY3QuIEl0IGxvb2tzIGZvciBzb21lIHNwZWNpYWwgY2FzZSBzaW1wbGUKLSAgICAgKiBtb2RlbHMgYW5kIGNyZWF0ZXMgU2ltcGxlQ29udGVudE1vZGVsIG9iamVjdHMgZm9yIHRob3NlLiBGb3IgdGhlIHJlc3QKLSAgICAgKiBpdCBjcmVhdGVzIHRoZSBzdGFuZGFyZCBERkEgc3R5bGUgbW9kZWwuCi0gICAgICovCi0gICAgcHJpdmF0ZSBzeW5jaHJvbml6ZWQgQ29udGVudE1vZGVsVmFsaWRhdG9yIGNyZWF0ZUNoaWxkTW9kZWwoaW50IGNvbnRlbnRTcGVjSW5kZXgpIHsKLQotICAgICAgICAvLwotICAgICAgICAvLyAgR2V0IHRoZSBjb250ZW50IHNwZWMgbm9kZSBmb3IgdGhlIGVsZW1lbnQgd2UgYXJlIHdvcmtpbmcgb24uCi0gICAgICAgIC8vICBUaGlzIHdpbGwgdGVsbCB1cyB3aGF0IGtpbmQgb2Ygbm9kZSBpdCBpcywgd2hpY2ggdGVsbHMgdXMgd2hhdAotICAgICAgICAvLyAga2luZCBvZiBtb2RlbCB3ZSB3aWxsIHRyeSB0byBjcmVhdGUuCi0gICAgICAgIC8vCi0gICAgICAgIFhNTENvbnRlbnRTcGVjIGNvbnRlbnRTcGVjID0gbmV3IFhNTENvbnRlbnRTcGVjKCk7Ci0gICAgICAgIGdldENvbnRlbnRTcGVjKGNvbnRlbnRTcGVjSW5kZXgsIGNvbnRlbnRTcGVjKTsKLQotICAgICAgICBpZiAoKGNvbnRlbnRTcGVjLnR5cGUgJiAweDBmICkgPT0gWE1MQ29udGVudFNwZWMuQ09OVEVOVFNQRUNOT0RFX0FOWSB8fAotICAgICAgICAgICAgKGNvbnRlbnRTcGVjLnR5cGUgJiAweDBmICkgPT0gWE1MQ29udGVudFNwZWMuQ09OVEVOVFNQRUNOT0RFX0FOWV9PVEhFUiB8fAotICAgICAgICAgICAgKGNvbnRlbnRTcGVjLnR5cGUgJiAweDBmICkgPT0gWE1MQ29udGVudFNwZWMuQ09OVEVOVFNQRUNOT0RFX0FOWV9MT0NBTCkgewotICAgICAgICAgICAgLy8gbGV0IGZhbGwgdGhyb3VnaCB0byBidWlsZCBhIERGQUNvbnRlbnRNb2RlbAotICAgICAgICB9Ci0KLSAgICAgICAgZWxzZSBpZiAoY29udGVudFNwZWMudHlwZSA9PSBYTUxDb250ZW50U3BlYy5DT05URU5UU1BFQ05PREVfTEVBRikgewotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIC8vICBDaGVjayB0aGF0IHRoZSBsZWZ0IHZhbHVlIGlzIG5vdCAtMSwgc2luY2UgYW55IGNvbnRlbnQgbW9kZWwKLSAgICAgICAgICAgIC8vICB3aXRoIFBDREFUQSBzaG91bGQgYmUgTUlYRUQsIHNvIHdlIHNob3VsZCBub3QgaGF2ZSBnb3R0ZW4gaGVyZS4KLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICBpZiAoY29udGVudFNwZWMudmFsdWUgPT0gbnVsbCAmJiBjb250ZW50U3BlYy5vdGhlclZhbHVlID09IG51bGwpCi0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIkltcGxlbWVudGF0aW9uTWVzc2FnZXMuVkFMX05QQ0QiKTsKLQotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIC8vICBJdHMgYSBzaW5nbGUgbGVhZiwgc28gaXRzIGFuICdhJyB0eXBlIG9mIGNvbnRlbnQgbW9kZWwsIGkuZS4KLSAgICAgICAgICAgIC8vICBqdXN0IG9uZSBpbnN0YW5jZSBvZiBvbmUgZWxlbWVudC4gVGhhdCBvbmUgaXMgZGVmaW5pdGVseSBhCi0gICAgICAgICAgICAvLyAgc2ltcGxlIGNvbnRlbnQgbW9kZWwuCi0gICAgICAgICAgICAvLwotCi0gICAgICAgICAgICBmUU5hbWUuc2V0VmFsdWVzKG51bGwsIChTdHJpbmcpY29udGVudFNwZWMudmFsdWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoU3RyaW5nKWNvbnRlbnRTcGVjLnZhbHVlLCAoU3RyaW5nKWNvbnRlbnRTcGVjLm90aGVyVmFsdWUpOwotICAgICAgICAgICAgcmV0dXJuIG5ldyBTaW1wbGVDb250ZW50TW9kZWwoY29udGVudFNwZWMudHlwZSwgZlFOYW1lLCBudWxsKTsKLSAgICAgICAgfSBlbHNlIGlmICgoY29udGVudFNwZWMudHlwZSA9PSBYTUxDb250ZW50U3BlYy5DT05URU5UU1BFQ05PREVfQ0hPSUNFKQotICAgICAgICAgICAgICAgICAgICB8fCAgKGNvbnRlbnRTcGVjLnR5cGUgPT0gWE1MQ29udGVudFNwZWMuQ09OVEVOVFNQRUNOT0RFX1NFUSkpIHsKLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAvLyAgTGV0cyBzZWUgaWYgYm90aCBvZiB0aGUgY2hpbGRyZW4gYXJlIGxlYWZzLiBJZiBzbywgdGhlbiBpdAotICAgICAgICAgICAgLy8gIGl0IGhhcyB0byBiZSBhIHNpbXBsZSBjb250ZW50IG1vZGVsCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgWE1MQ29udGVudFNwZWMgY29udGVudFNwZWNMZWZ0ICA9IG5ldyBYTUxDb250ZW50U3BlYygpOwotICAgICAgICAgICAgWE1MQ29udGVudFNwZWMgY29udGVudFNwZWNSaWdodCA9IG5ldyBYTUxDb250ZW50U3BlYygpOwotCi0gICAgICAgICAgICBnZXRDb250ZW50U3BlYyggKChpbnRbXSljb250ZW50U3BlYy52YWx1ZSlbMF0sIGNvbnRlbnRTcGVjTGVmdCk7Ci0gICAgICAgICAgICBnZXRDb250ZW50U3BlYyggKChpbnRbXSljb250ZW50U3BlYy5vdGhlclZhbHVlKVswXSwgY29udGVudFNwZWNSaWdodCk7Ci0KLSAgICAgICAgICAgIGlmICgoY29udGVudFNwZWNMZWZ0LnR5cGUgPT0gWE1MQ29udGVudFNwZWMuQ09OVEVOVFNQRUNOT0RFX0xFQUYpCi0gICAgICAgICAgICAgICAgICYmICAoY29udGVudFNwZWNSaWdodC50eXBlID09IFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9MRUFGKSkgewotICAgICAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAgICAgLy8gIEl0cyBhIHNpbXBsZSBjaG9pY2Ugb3Igc2VxdWVuY2UsIHNvIHdlIGNhbiBkbyBhIHNpbXBsZQotICAgICAgICAgICAgICAgIC8vICBjb250ZW50IG1vZGVsIGZvciBpdC4KLSAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgIGZRTmFtZS5zZXRWYWx1ZXMobnVsbCwgKFN0cmluZyljb250ZW50U3BlY0xlZnQudmFsdWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFN0cmluZyljb250ZW50U3BlY0xlZnQudmFsdWUsIChTdHJpbmcpY29udGVudFNwZWNMZWZ0Lm90aGVyVmFsdWUpOwotICAgICAgICAgICAgICAgIGZRTmFtZTIuc2V0VmFsdWVzKG51bGwsIChTdHJpbmcpY29udGVudFNwZWNSaWdodC52YWx1ZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoU3RyaW5nKWNvbnRlbnRTcGVjUmlnaHQudmFsdWUsIChTdHJpbmcpY29udGVudFNwZWNSaWdodC5vdGhlclZhbHVlKTsKLSAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFNpbXBsZUNvbnRlbnRNb2RlbChjb250ZW50U3BlYy50eXBlLCBmUU5hbWUsIGZRTmFtZTIpOwotICAgICAgICAgICAgfQotICAgICAgICB9IGVsc2UgaWYgKChjb250ZW50U3BlYy50eXBlID09IFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9aRVJPX09SX09ORSkKLSAgICAgICAgICAgICAgICAgICAgfHwgIChjb250ZW50U3BlYy50eXBlID09IFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9aRVJPX09SX01PUkUpCi0gICAgICAgICAgICAgICAgICAgIHx8ICAoY29udGVudFNwZWMudHlwZSA9PSBYTUxDb250ZW50U3BlYy5DT05URU5UU1BFQ05PREVfT05FX09SX01PUkUpKSB7Ci0gICAgICAgICAgICAvLwotICAgICAgICAgICAgLy8gIEl0cyBhIHJlcGV0aXRpb24sIHNvIHNlZSBpZiBpdHMgb25lIGNoaWxkIGlzIGEgbGVhZi4gSWYgc28KLSAgICAgICAgICAgIC8vICBpdHMgYSByZXBldGl0aW9uIG9mIGEgc2luZ2xlIGVsZW1lbnQsIHNvIHdlIGNhbiBkbyBhIHNpbXBsZQotICAgICAgICAgICAgLy8gIGNvbnRlbnQgbW9kZWwgZm9yIHRoYXQuCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgWE1MQ29udGVudFNwZWMgY29udGVudFNwZWNMZWZ0ID0gbmV3IFhNTENvbnRlbnRTcGVjKCk7Ci0gICAgICAgICAgICBnZXRDb250ZW50U3BlYygoKGludFtdKWNvbnRlbnRTcGVjLnZhbHVlKVswXSwgY29udGVudFNwZWNMZWZ0KTsKLQotICAgICAgICAgICAgaWYgKGNvbnRlbnRTcGVjTGVmdC50eXBlID09IFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9MRUFGKSB7Ci0gICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICAvLyAgSXQgaXMsIHNvIHdlIGNhbiBjcmVhdGUgYSBzaW1wbGUgY29udGVudCBtb2RlbCBoZXJlIHRoYXQKLSAgICAgICAgICAgICAgICAvLyAgd2lsbCBjaGVjayBmb3IgdGhpcyByZXBldGl0aW9uLiBXZSBwYXNzIC0xIGZvciB0aGUgdW51c2VkCi0gICAgICAgICAgICAgICAgLy8gIHJpZ2h0IG5vZGUuCi0gICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICBmUU5hbWUuc2V0VmFsdWVzKG51bGwsIChTdHJpbmcpY29udGVudFNwZWNMZWZ0LnZhbHVlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChTdHJpbmcpY29udGVudFNwZWNMZWZ0LnZhbHVlLCAoU3RyaW5nKWNvbnRlbnRTcGVjTGVmdC5vdGhlclZhbHVlKTsKLSAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFNpbXBsZUNvbnRlbnRNb2RlbChjb250ZW50U3BlYy50eXBlLCBmUU5hbWUsIG51bGwpOwotICAgICAgICAgICAgfQotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIkltcGxlbWVudGF0aW9uTWVzc2FnZXMuVkFMX0NTVCIpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gIEl0cyBub3QgYSBzaW1wbGUgY29udGVudCBtb2RlbCwgc28gaGVyZSB3ZSBoYXZlIHRvIGNyZWF0ZSBhIERGQQotICAgICAgICAvLyAgZm9yIHRoaXMgZWxlbWVudC4gU28gd2UgY3JlYXRlIGEgREZBQ29udGVudE1vZGVsIG9iamVjdC4gSGUKLSAgICAgICAgLy8gIGVuY2Fwc3VsYXRlcyBhbGwgb2YgdGhlIHdvcmsgdG8gY3JlYXRlIHRoZSBERkEuCi0gICAgICAgIC8vCi0KLSAgICAgICAgZkxlYWZDb3VudCA9IDA7Ci0gICAgICAgIC8vaW50IGxlYWZDb3VudCA9IGNvdW50TGVhdmVzKGNvbnRlbnRTcGVjSW5kZXgpOwotICAgICAgICBmTGVhZkNvdW50ID0gMDsKLSAgICAgICAgQ01Ob2RlIGNtbiAgICA9IGJ1aWxkU3ludGF4VHJlZShjb250ZW50U3BlY0luZGV4LCBjb250ZW50U3BlYyk7Ci0KLSAgICAgICAgLy8gUkVWSVNJVDogaGFzIHRvIGJlIGZMZWFmQ291bnQgYmVjYXVzZSB3ZSBjb252ZXJ0IHgrIHRvIHgseCosIG9uZSBtb3JlIGxlYWYKLSAgICAgICAgcmV0dXJuIG5ldyBERkFDb250ZW50TW9kZWwoICBjbW4sIGZMZWFmQ291bnQsIGZhbHNlKTsKLQotICAgIH0gLy8gY3JlYXRlQ2hpbGRNb2RlbChpbnQpOkNvbnRlbnRNb2RlbFZhbGlkYXRvcgotCi0gICAgcHJpdmF0ZSBmaW5hbCBDTU5vZGUgYnVpbGRTeW50YXhUcmVlKGludCBzdGFydE5vZGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTENvbnRlbnRTcGVjIGNvbnRlbnRTcGVjKSB7Ci0KLSAgICAgICAgLy8gV2Ugd2lsbCBidWlsZCBhIG5vZGUgYXQgdGhpcyBsZXZlbCBmb3IgdGhlIG5ldyB0cmVlCi0gICAgICAgIENNTm9kZSBub2RlUmV0ID0gbnVsbDsKLSAgICAgICAgZ2V0Q29udGVudFNwZWMoc3RhcnROb2RlLCBjb250ZW50U3BlYyk7Ci0gICAgICAgIGlmICgoY29udGVudFNwZWMudHlwZSAmIDB4MGYpID09IFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9BTlkpIHsKLSAgICAgICAgICAgIC8vbm9kZVJldCA9IG5ldyBDTUFueShjb250ZW50U3BlYy50eXBlLCAtMSwgZkxlYWZDb3VudCsrKTsKLSAgICAgICAgICAgIG5vZGVSZXQgPSBuZXcgQ01BbnkoY29udGVudFNwZWMudHlwZSwgKFN0cmluZyljb250ZW50U3BlYy5vdGhlclZhbHVlLCBmTGVhZkNvdW50KyspOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKChjb250ZW50U3BlYy50eXBlICYgMHgwZikgPT0gWE1MQ29udGVudFNwZWMuQ09OVEVOVFNQRUNOT0RFX0FOWV9PVEhFUikgewotICAgICAgICAgICAgbm9kZVJldCA9IG5ldyBDTUFueShjb250ZW50U3BlYy50eXBlLCAoU3RyaW5nKWNvbnRlbnRTcGVjLm90aGVyVmFsdWUsIGZMZWFmQ291bnQrKyk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoKGNvbnRlbnRTcGVjLnR5cGUgJiAweDBmKSA9PSBYTUxDb250ZW50U3BlYy5DT05URU5UU1BFQ05PREVfQU5ZX0xPQ0FMKSB7Ci0gICAgICAgICAgICBub2RlUmV0ID0gbmV3IENNQW55KGNvbnRlbnRTcGVjLnR5cGUsIG51bGwsIGZMZWFmQ291bnQrKyk7Ci0gICAgICAgIH0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gIElmIHRoaXMgbm9kZSBpcyBhIGxlYWYsIHRoZW4gaXRzIGFuIGVhc3kgb25lLiBXZSBqdXN0IGFkZCBpdAotICAgICAgICAvLyAgdG8gdGhlIHRyZWUuCi0gICAgICAgIC8vCi0gICAgICAgIGVsc2UgaWYgKGNvbnRlbnRTcGVjLnR5cGUgPT0gWE1MQ29udGVudFNwZWMuQ09OVEVOVFNQRUNOT0RFX0xFQUYpIHsKLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAvLyAgQ3JlYXRlIGEgbmV3IGxlYWYgbm9kZSwgYW5kIHBhc3MgaXQgdGhlIGN1cnJlbnQgbGVhZiBjb3VudCwKLSAgICAgICAgICAgIC8vICB3aGljaCBpcyBpdHMgREZBIHN0YXRlIHBvc2l0aW9uLiBCdW1wIHRoZSBsZWFmIGNvdW50IGFmdGVyCi0gICAgICAgICAgICAvLyAgc3RvcmluZyBpdC4gVGhpcyBtYWtlcyB0aGUgcG9zaXRpb25zIHplcm8gYmFzZWQgc2luY2Ugd2UKLSAgICAgICAgICAgIC8vICBzdG9yZSBmaXJzdCBhbmQgdGhlbiBpbmNyZW1lbnQuCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgZlFOYW1lLnNldFZhbHVlcyhudWxsLCAoU3RyaW5nKWNvbnRlbnRTcGVjLnZhbHVlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFN0cmluZyljb250ZW50U3BlYy52YWx1ZSwgKFN0cmluZyljb250ZW50U3BlYy5vdGhlclZhbHVlKTsKLSAgICAgICAgICAgIG5vZGVSZXQgPSBuZXcgQ01MZWFmKGZRTmFtZSwgZkxlYWZDb3VudCsrKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAvLyAgSXRzIG5vdCBhIGxlYWYsIHNvIHdlIGhhdmUgdG8gcmVjdXJzZSBpdHMgbGVmdCBhbmQgbWF5YmUgcmlnaHQKLSAgICAgICAgICAgIC8vICBub2Rlcy4gU2F2ZSBib3RoIHZhbHVlcyBiZWZvcmUgd2UgcmVjdXJzZSBhbmQgdHJhc2ggdGhlIG5vZGUuCi0gICAgICAgICAgICBmaW5hbCBpbnQgbGVmdE5vZGUgPSAoKGludFtdKWNvbnRlbnRTcGVjLnZhbHVlKVswXTsKLSAgICAgICAgICAgIGZpbmFsIGludCByaWdodE5vZGUgPSAoKGludFtdKWNvbnRlbnRTcGVjLm90aGVyVmFsdWUpWzBdOwotCi0gICAgICAgICAgICBpZiAoKGNvbnRlbnRTcGVjLnR5cGUgPT0gWE1MQ29udGVudFNwZWMuQ09OVEVOVFNQRUNOT0RFX0NIT0lDRSkKLSAgICAgICAgICAgICAgICB8fCAgKGNvbnRlbnRTcGVjLnR5cGUgPT0gWE1MQ29udGVudFNwZWMuQ09OVEVOVFNQRUNOT0RFX1NFUSkpIHsKLSAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgIC8vICBSZWN1cnNlIG9uIGJvdGggY2hpbGRyZW4sIGFuZCByZXR1cm4gYSBiaW5hcnkgb3Agbm9kZQotICAgICAgICAgICAgICAgIC8vICB3aXRoIHRoZSB0d28gY3JlYXRlZCBzdWIgbm9kZXMgYXMgaXRzIGNoaWxkcmVuLiBUaGUgbm9kZQotICAgICAgICAgICAgICAgIC8vICB0eXBlIGlzIHRoZSBzYW1lIHR5cGUgYXMgdGhlIHNvdXJjZS4KLSAgICAgICAgICAgICAgICAvLwotCi0gICAgICAgICAgICAgICAgbm9kZVJldCA9IG5ldyBDTUJpbk9wKCBjb250ZW50U3BlYy50eXBlLCBidWlsZFN5bnRheFRyZWUobGVmdE5vZGUsIGNvbnRlbnRTcGVjKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLCBidWlsZFN5bnRheFRyZWUocmlnaHROb2RlLCBjb250ZW50U3BlYykpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoY29udGVudFNwZWMudHlwZSA9PSBYTUxDb250ZW50U3BlYy5DT05URU5UU1BFQ05PREVfWkVST19PUl9NT1JFKSB7Ci0gICAgICAgICAgICAgICAgbm9kZVJldCA9IG5ldyBDTVVuaU9wKCBjb250ZW50U3BlYy50eXBlLCBidWlsZFN5bnRheFRyZWUobGVmdE5vZGUsIGNvbnRlbnRTcGVjKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChjb250ZW50U3BlYy50eXBlID09IFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9aRVJPX09SX01PUkUKLSAgICAgICAgICAgICAgICAgIHx8IGNvbnRlbnRTcGVjLnR5cGUgPT0gWE1MQ29udGVudFNwZWMuQ09OVEVOVFNQRUNOT0RFX1pFUk9fT1JfT05FCi0gICAgICAgICAgICAgICAgICB8fCBjb250ZW50U3BlYy50eXBlID09IFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9PTkVfT1JfTU9SRSkgewotICAgICAgICAgICAgICAgIG5vZGVSZXQgPSBuZXcgQ01VbmlPcChjb250ZW50U3BlYy50eXBlLCBidWlsZFN5bnRheFRyZWUobGVmdE5vZGUsIGNvbnRlbnRTcGVjKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiSW1wbGVtZW50YXRpb25NZXNzYWdlcy5WQUxfQ1NUIik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgLy8gQW5kIHJldHVybiBvdXIgbmV3IG5vZGUgZm9yIHRoaXMgbGV2ZWwKLSAgICAgICAgcmV0dXJuIG5vZGVSZXQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQnVpbGQgYSB2ZWN0b3Igb2YgdmFsaWQgUU5hbWVzIGZyb20gQ29udGVudCBTcGVjCi0gICAgICogdGFibGUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29udGVudFNwZWNJbmRleAotICAgICAqICAgICAgICAgICAgICAgQ29udGVudCBTcGVjIGluZGV4Ci0gICAgICogQHBhcmFtIHZlY3RvclFOYW1lCi0gICAgICogICAgICAgICAgICAgICBBcnJheSBvZiBRTmFtZQotICAgICAqIEBleGNlcHRpb24gUnVudGltZUV4Y2VwdGlvbgotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCBjb250ZW50U3BlY1RyZWUoaW50IGNvbnRlbnRTcGVjSW5kZXgsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxDb250ZW50U3BlYyBjb250ZW50U3BlYywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENoaWxkcmVuTGlzdCBjaGlsZHJlbikgewotCi0gICAgICAgIC8vIEhhbmRsZSBhbnkgYW5kIGxlYWYgbm9kZXMKLSAgICAgICAgZ2V0Q29udGVudFNwZWMoIGNvbnRlbnRTcGVjSW5kZXgsIGNvbnRlbnRTcGVjKTsKLSAgICAgICAgaWYgKCBjb250ZW50U3BlYy50eXBlID09IFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9MRUFGIHx8Ci0gICAgICAgICAgICAoY29udGVudFNwZWMudHlwZSAmIDB4MGYpID09IFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9BTlkgfHwKLSAgICAgICAgICAgIChjb250ZW50U3BlYy50eXBlICYgMHgwZikgPT0gWE1MQ29udGVudFNwZWMuQ09OVEVOVFNQRUNOT0RFX0FOWV9MT0NBTCB8fAotICAgICAgICAgICAgKGNvbnRlbnRTcGVjLnR5cGUgJiAweDBmKSA9PSBYTUxDb250ZW50U3BlYy5DT05URU5UU1BFQ05PREVfQU5ZX09USEVSKSB7Ci0KLSAgICAgICAgICAgIC8vIHJlc2l6ZSBhcnJheXMsIGlmIG5lZWRlZAotICAgICAgICAgICAgaWYgKGNoaWxkcmVuLmxlbmd0aCA9PSBjaGlsZHJlbi5xbmFtZS5sZW5ndGgpIHsKLSAgICAgICAgICAgICAgICBRTmFtZVtdIG5ld1FOYW1lID0gbmV3IFFOYW1lW2NoaWxkcmVuLmxlbmd0aCAqIDJdOwotICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoY2hpbGRyZW4ucW5hbWUsIDAsIG5ld1FOYW1lLCAwLCBjaGlsZHJlbi5sZW5ndGgpOwotICAgICAgICAgICAgICAgIGNoaWxkcmVuLnFuYW1lID0gbmV3UU5hbWU7Ci0gICAgICAgICAgICAgICAgaW50W10gbmV3VHlwZSA9IG5ldyBpbnRbY2hpbGRyZW4ubGVuZ3RoICogMl07Ci0gICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShjaGlsZHJlbi50eXBlLCAwLCBuZXdUeXBlLCAwLCBjaGlsZHJlbi5sZW5ndGgpOwotICAgICAgICAgICAgICAgIGNoaWxkcmVuLnR5cGUgPSBuZXdUeXBlOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBzYXZlIHZhbHVlcyBhbmQgcmV0dXJuIGxlbmd0aAotICAgICAgICAgICAgY2hpbGRyZW4ucW5hbWVbY2hpbGRyZW4ubGVuZ3RoXSA9IG5ldyBRTmFtZShudWxsLCAoU3RyaW5nKWNvbnRlbnRTcGVjLnZhbHVlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoU3RyaW5nKSBjb250ZW50U3BlYy52YWx1ZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFN0cmluZykgY29udGVudFNwZWMub3RoZXJWYWx1ZSk7Ci0gICAgICAgICAgICBjaGlsZHJlbi50eXBlW2NoaWxkcmVuLmxlbmd0aF0gPSBjb250ZW50U3BlYy50eXBlOwotICAgICAgICAgICAgY2hpbGRyZW4ubGVuZ3RoKys7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLQotICAgICAgICAvLwotICAgICAgICAvLyAgSXRzIG5vdCBhIGxlYWYsIHNvIHdlIGhhdmUgdG8gcmVjdXJzZSBpdHMgbGVmdCBhbmQgbWF5YmUgcmlnaHQKLSAgICAgICAgLy8gIG5vZGVzLiBTYXZlIGJvdGggdmFsdWVzIGJlZm9yZSB3ZSByZWN1cnNlIGFuZCB0cmFzaCB0aGUgbm9kZS4KLSAgICAgICAgLy8KLSAgICAgICAgZmluYWwgaW50IGxlZnROb2RlID0gY29udGVudFNwZWMudmFsdWUgIT0gbnVsbAotICAgICAgICAgICAgICAgICAgICAgICAgICAgPyAoKGludFtdKShjb250ZW50U3BlYy52YWx1ZSkpWzBdIDogLTE7Ci0gICAgICAgIGludCByaWdodE5vZGUgPSAtMSA7Ci0gICAgICAgIGlmIChjb250ZW50U3BlYy5vdGhlclZhbHVlICE9IG51bGwgKQotICAgICAgICAgICAgcmlnaHROb2RlID0gKChpbnRbXSkoY29udGVudFNwZWMub3RoZXJWYWx1ZSkpWzBdOwotICAgICAgICBlbHNlCi0gICAgICAgICAgICByZXR1cm47Ci0KLSAgICAgICAgaWYgKGNvbnRlbnRTcGVjLnR5cGUgPT0gWE1MQ29udGVudFNwZWMuQ09OVEVOVFNQRUNOT0RFX0NIT0lDRSB8fAotICAgICAgICAgICAgY29udGVudFNwZWMudHlwZSA9PSBYTUxDb250ZW50U3BlYy5DT05URU5UU1BFQ05PREVfU0VRKSB7Ci0gICAgICAgICAgICBjb250ZW50U3BlY1RyZWUobGVmdE5vZGUsIGNvbnRlbnRTcGVjLCBjaGlsZHJlbik7Ci0gICAgICAgICAgICBjb250ZW50U3BlY1RyZWUocmlnaHROb2RlLCBjb250ZW50U3BlYywgY2hpbGRyZW4pOwotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKGNvbnRlbnRTcGVjLnR5cGUgPT0gWE1MQ29udGVudFNwZWMuQ09OVEVOVFNQRUNOT0RFX1pFUk9fT1JfT05FIHx8Ci0gICAgICAgICAgICBjb250ZW50U3BlYy50eXBlID09IFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9aRVJPX09SX01PUkUgfHwKLSAgICAgICAgICAgIGNvbnRlbnRTcGVjLnR5cGUgPT0gWE1MQ29udGVudFNwZWMuQ09OVEVOVFNQRUNOT0RFX09ORV9PUl9NT1JFKSB7Ci0gICAgICAgICAgICBjb250ZW50U3BlY1RyZWUobGVmdE5vZGUsIGNvbnRlbnRTcGVjLCBjaGlsZHJlbik7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBlcnJvcgotICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiSW52YWxpZCBjb250ZW50IHNwZWMgdHlwZSBzZWVuIGluIGNvbnRlbnRTcGVjVHJlZSgpIG1ldGhvZCBvZiBBYnN0cmFjdERUREdyYW1tYXIgY2xhc3MgOiAiK2NvbnRlbnRTcGVjLnR5cGUpOwotCi0gICAgfSAvLyBjb250ZW50U3BlY1RyZWUoaW50LFhNTENvbnRlbnRTcGVjLENoaWxkcmVuTGlzdCkKLQotICAgIC8vIGVuc3VyZSBjYXBhY2l0eQotCi0gICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUVsZW1lbnREZWNsQ2FwYWNpdHkoaW50IGNodW5rKSB7Ci0gICAgICAgIGlmIChjaHVuayA+PSBmRWxlbWVudERlY2xOYW1lLmxlbmd0aCkgewotICAgICAgICAgICAgZkVsZW1lbnREZWNsSXNFeHRlcm5hbCA9IHJlc2l6ZShmRWxlbWVudERlY2xJc0V4dGVybmFsLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZFbGVtZW50RGVjbElzRXh0ZXJuYWwubGVuZ3RoICogMik7Ci0KLSAgICAgICAgICAgIGZFbGVtZW50RGVjbE5hbWUgPSByZXNpemUoZkVsZW1lbnREZWNsTmFtZSwgZkVsZW1lbnREZWNsTmFtZS5sZW5ndGggKiAyKTsKLSAgICAgICAgICAgIGZFbGVtZW50RGVjbFR5cGUgPSByZXNpemUoZkVsZW1lbnREZWNsVHlwZSwgZkVsZW1lbnREZWNsVHlwZS5sZW5ndGggKiAyKTsKLSAgICAgICAgICAgIGZFbGVtZW50RGVjbENvbnRlbnRNb2RlbFZhbGlkYXRvciA9IHJlc2l6ZShmRWxlbWVudERlY2xDb250ZW50TW9kZWxWYWxpZGF0b3IsIGZFbGVtZW50RGVjbENvbnRlbnRNb2RlbFZhbGlkYXRvci5sZW5ndGggKiAyKTsKLSAgICAgICAgICAgIGZFbGVtZW50RGVjbENvbnRlbnRTcGVjSW5kZXggPSByZXNpemUoZkVsZW1lbnREZWNsQ29udGVudFNwZWNJbmRleCxmRWxlbWVudERlY2xDb250ZW50U3BlY0luZGV4Lmxlbmd0aCAqIDIpOwotICAgICAgICAgICAgZkVsZW1lbnREZWNsRmlyc3RBdHRyaWJ1dGVEZWNsSW5kZXggPSByZXNpemUoZkVsZW1lbnREZWNsRmlyc3RBdHRyaWJ1dGVEZWNsSW5kZXgsIGZFbGVtZW50RGVjbEZpcnN0QXR0cmlidXRlRGVjbEluZGV4Lmxlbmd0aCAqIDIpOwotICAgICAgICAgICAgZkVsZW1lbnREZWNsTGFzdEF0dHJpYnV0ZURlY2xJbmRleCA9IHJlc2l6ZShmRWxlbWVudERlY2xMYXN0QXR0cmlidXRlRGVjbEluZGV4LCBmRWxlbWVudERlY2xMYXN0QXR0cmlidXRlRGVjbEluZGV4Lmxlbmd0aCAqIDIpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKGZFbGVtZW50RGVjbE5hbWVbY2h1bmtdICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotCi0gICAgICAgIGZFbGVtZW50RGVjbElzRXh0ZXJuYWxbY2h1bmtdID0gbmV3IGludFtDSFVOS19TSVpFXTsKLSAgICAgICAgZkVsZW1lbnREZWNsTmFtZVtjaHVua10gPSBuZXcgUU5hbWVbQ0hVTktfU0laRV07Ci0gICAgICAgIGZFbGVtZW50RGVjbFR5cGVbY2h1bmtdID0gbmV3IHNob3J0W0NIVU5LX1NJWkVdOwotICAgICAgICBmRWxlbWVudERlY2xDb250ZW50TW9kZWxWYWxpZGF0b3JbY2h1bmtdID0gbmV3IENvbnRlbnRNb2RlbFZhbGlkYXRvcltDSFVOS19TSVpFXTsKLSAgICAgICAgZkVsZW1lbnREZWNsQ29udGVudFNwZWNJbmRleFtjaHVua10gPSBuZXcgaW50W0NIVU5LX1NJWkVdOwotICAgICAgICBmRWxlbWVudERlY2xGaXJzdEF0dHJpYnV0ZURlY2xJbmRleFtjaHVua10gPSBuZXcgaW50W0NIVU5LX1NJWkVdOwotICAgICAgICBmRWxlbWVudERlY2xMYXN0QXR0cmlidXRlRGVjbEluZGV4W2NodW5rXSA9IG5ldyBpbnRbQ0hVTktfU0laRV07Ci0gICAgICAgIHJldHVybjsKLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgZW5zdXJlQXR0cmlidXRlRGVjbENhcGFjaXR5KGludCBjaHVuaykgewotCi0gICAgICAgIGlmIChjaHVuayA+PSBmQXR0cmlidXRlRGVjbE5hbWUubGVuZ3RoKSB7Ci0gICAgICAgICAgICBmQXR0cmlidXRlRGVjbElzRXh0ZXJuYWwgPSByZXNpemUoZkF0dHJpYnV0ZURlY2xJc0V4dGVybmFsLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkF0dHJpYnV0ZURlY2xJc0V4dGVybmFsLmxlbmd0aCAqIDIpOwotICAgICAgICAgICAgZkF0dHJpYnV0ZURlY2xOYW1lID0gcmVzaXplKGZBdHRyaWJ1dGVEZWNsTmFtZSwgZkF0dHJpYnV0ZURlY2xOYW1lLmxlbmd0aCAqIDIpOwotICAgICAgICAgICAgZkF0dHJpYnV0ZURlY2xUeXBlID0gcmVzaXplKGZBdHRyaWJ1dGVEZWNsVHlwZSwgZkF0dHJpYnV0ZURlY2xUeXBlLmxlbmd0aCAqIDIpOwotICAgICAgICAgICAgZkF0dHJpYnV0ZURlY2xFbnVtZXJhdGlvbiA9IHJlc2l6ZShmQXR0cmlidXRlRGVjbEVudW1lcmF0aW9uLCBmQXR0cmlidXRlRGVjbEVudW1lcmF0aW9uLmxlbmd0aCAqIDIpOwotICAgICAgICAgICAgZkF0dHJpYnV0ZURlY2xEZWZhdWx0VHlwZSA9IHJlc2l6ZShmQXR0cmlidXRlRGVjbERlZmF1bHRUeXBlLCBmQXR0cmlidXRlRGVjbERlZmF1bHRUeXBlLmxlbmd0aCAqIDIpOwotICAgICAgICAgICAgZkF0dHJpYnV0ZURlY2xEYXRhdHlwZVZhbGlkYXRvciA9IHJlc2l6ZShmQXR0cmlidXRlRGVjbERhdGF0eXBlVmFsaWRhdG9yLCBmQXR0cmlidXRlRGVjbERhdGF0eXBlVmFsaWRhdG9yLmxlbmd0aCAqIDIpOwotICAgICAgICAgICAgZkF0dHJpYnV0ZURlY2xEZWZhdWx0VmFsdWUgPSByZXNpemUoZkF0dHJpYnV0ZURlY2xEZWZhdWx0VmFsdWUsIGZBdHRyaWJ1dGVEZWNsRGVmYXVsdFZhbHVlLmxlbmd0aCAqIDIpOwotICAgICAgICAgICAgZkF0dHJpYnV0ZURlY2xOb25Ob3JtYWxpemVkRGVmYXVsdFZhbHVlID0gcmVzaXplKGZBdHRyaWJ1dGVEZWNsTm9uTm9ybWFsaXplZERlZmF1bHRWYWx1ZSwgZkF0dHJpYnV0ZURlY2xOb25Ob3JtYWxpemVkRGVmYXVsdFZhbHVlLmxlbmd0aCAqIDIpOwotICAgICAgICAgICAgZkF0dHJpYnV0ZURlY2xOZXh0QXR0cmlidXRlRGVjbEluZGV4ID0gcmVzaXplKGZBdHRyaWJ1dGVEZWNsTmV4dEF0dHJpYnV0ZURlY2xJbmRleCwgZkF0dHJpYnV0ZURlY2xOZXh0QXR0cmlidXRlRGVjbEluZGV4Lmxlbmd0aCAqIDIpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKGZBdHRyaWJ1dGVEZWNsTmFtZVtjaHVua10gIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0KLSAgICAgICAgZkF0dHJpYnV0ZURlY2xJc0V4dGVybmFsW2NodW5rXSA9IG5ldyBpbnRbQ0hVTktfU0laRV07Ci0gICAgICAgIGZBdHRyaWJ1dGVEZWNsTmFtZVtjaHVua10gPSBuZXcgUU5hbWVbQ0hVTktfU0laRV07Ci0gICAgICAgIGZBdHRyaWJ1dGVEZWNsVHlwZVtjaHVua10gPSBuZXcgc2hvcnRbQ0hVTktfU0laRV07Ci0gICAgICAgIGZBdHRyaWJ1dGVEZWNsRW51bWVyYXRpb25bY2h1bmtdID0gbmV3IFN0cmluZ1tDSFVOS19TSVpFXVtdOwotICAgICAgICBmQXR0cmlidXRlRGVjbERlZmF1bHRUeXBlW2NodW5rXSA9IG5ldyBzaG9ydFtDSFVOS19TSVpFXTsKLSAgICAgICAgZkF0dHJpYnV0ZURlY2xEYXRhdHlwZVZhbGlkYXRvcltjaHVua10gPSBuZXcgRGF0YXR5cGVWYWxpZGF0b3JbQ0hVTktfU0laRV07Ci0gICAgICAgIGZBdHRyaWJ1dGVEZWNsRGVmYXVsdFZhbHVlW2NodW5rXSA9IG5ldyBTdHJpbmdbQ0hVTktfU0laRV07Ci0gICAgICAgIGZBdHRyaWJ1dGVEZWNsTm9uTm9ybWFsaXplZERlZmF1bHRWYWx1ZVtjaHVua10gPSBuZXcgU3RyaW5nW0NIVU5LX1NJWkVdOwotICAgICAgICBmQXR0cmlidXRlRGVjbE5leHRBdHRyaWJ1dGVEZWNsSW5kZXhbY2h1bmtdID0gbmV3IGludFtDSFVOS19TSVpFXTsKLSAgICAgICAgcmV0dXJuOwotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBlbnN1cmVFbnRpdHlEZWNsQ2FwYWNpdHkoaW50IGNodW5rKSB7Ci0gICAgICAgIGlmIChjaHVuayA+PSBmRW50aXR5TmFtZS5sZW5ndGgpIHsKLSAgICAgICAgICAgIGZFbnRpdHlOYW1lID0gcmVzaXplKGZFbnRpdHlOYW1lLCBmRW50aXR5TmFtZS5sZW5ndGggKiAyKTsKLSAgICAgICAgICAgIGZFbnRpdHlWYWx1ZSA9IHJlc2l6ZShmRW50aXR5VmFsdWUsIGZFbnRpdHlWYWx1ZS5sZW5ndGggKiAyKTsKLSAgICAgICAgICAgIGZFbnRpdHlQdWJsaWNJZCA9IHJlc2l6ZShmRW50aXR5UHVibGljSWQsIGZFbnRpdHlQdWJsaWNJZC5sZW5ndGggKiAyKTsKLSAgICAgICAgICAgIGZFbnRpdHlTeXN0ZW1JZCA9IHJlc2l6ZShmRW50aXR5U3lzdGVtSWQsIGZFbnRpdHlTeXN0ZW1JZC5sZW5ndGggKiAyKTsKLSAgICAgICAgICAgIGZFbnRpdHlCYXNlU3lzdGVtSWQgPSByZXNpemUoZkVudGl0eUJhc2VTeXN0ZW1JZCwgZkVudGl0eUJhc2VTeXN0ZW1JZC5sZW5ndGggKiAyKTsKLSAgICAgICAgICAgIGZFbnRpdHlOb3RhdGlvbiA9IHJlc2l6ZShmRW50aXR5Tm90YXRpb24sIGZFbnRpdHlOb3RhdGlvbi5sZW5ndGggKiAyKTsKLSAgICAgICAgICAgIGZFbnRpdHlJc1BFID0gcmVzaXplKGZFbnRpdHlJc1BFLCBmRW50aXR5SXNQRS5sZW5ndGggKiAyKTsKLSAgICAgICAgICAgIGZFbnRpdHlJbkV4dGVybmFsID0gcmVzaXplKGZFbnRpdHlJbkV4dGVybmFsLCBmRW50aXR5SW5FeHRlcm5hbC5sZW5ndGggKiAyKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChmRW50aXR5TmFtZVtjaHVua10gIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0KLSAgICAgICAgZkVudGl0eU5hbWVbY2h1bmtdID0gbmV3IFN0cmluZ1tDSFVOS19TSVpFXTsKLSAgICAgICAgZkVudGl0eVZhbHVlW2NodW5rXSA9IG5ldyBTdHJpbmdbQ0hVTktfU0laRV07Ci0gICAgICAgIGZFbnRpdHlQdWJsaWNJZFtjaHVua10gPSBuZXcgU3RyaW5nW0NIVU5LX1NJWkVdOwotICAgICAgICBmRW50aXR5U3lzdGVtSWRbY2h1bmtdID0gbmV3IFN0cmluZ1tDSFVOS19TSVpFXTsKLSAgICAgICAgZkVudGl0eUJhc2VTeXN0ZW1JZFtjaHVua10gPSBuZXcgU3RyaW5nW0NIVU5LX1NJWkVdOwotICAgICAgICBmRW50aXR5Tm90YXRpb25bY2h1bmtdID0gbmV3IFN0cmluZ1tDSFVOS19TSVpFXTsKLSAgICAgICAgZkVudGl0eUlzUEVbY2h1bmtdID0gbmV3IGJ5dGVbQ0hVTktfU0laRV07Ci0gICAgICAgIGZFbnRpdHlJbkV4dGVybmFsW2NodW5rXSA9IG5ldyBieXRlW0NIVU5LX1NJWkVdOwotICAgICAgICByZXR1cm47Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIGVuc3VyZU5vdGF0aW9uRGVjbENhcGFjaXR5KGludCBjaHVuaykgewotICAgICAgICBpZiAoY2h1bmsgPj0gZk5vdGF0aW9uTmFtZS5sZW5ndGgpIHsKLSAgICAgICAgICAgIGZOb3RhdGlvbk5hbWUgPSByZXNpemUoZk5vdGF0aW9uTmFtZSwgZk5vdGF0aW9uTmFtZS5sZW5ndGggKiAyKTsKLSAgICAgICAgICAgIGZOb3RhdGlvblB1YmxpY0lkID0gcmVzaXplKGZOb3RhdGlvblB1YmxpY0lkLCBmTm90YXRpb25QdWJsaWNJZC5sZW5ndGggKiAyKTsKLSAgICAgICAgICAgIGZOb3RhdGlvblN5c3RlbUlkID0gcmVzaXplKGZOb3RhdGlvblN5c3RlbUlkLCBmTm90YXRpb25TeXN0ZW1JZC5sZW5ndGggKiAyKTsKLSAgICAgICAgICAgIGZOb3RhdGlvbkJhc2VTeXN0ZW1JZCA9IHJlc2l6ZShmTm90YXRpb25CYXNlU3lzdGVtSWQsIGZOb3RhdGlvbkJhc2VTeXN0ZW1JZC5sZW5ndGggKiAyKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChmTm90YXRpb25OYW1lW2NodW5rXSAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLQotICAgICAgICBmTm90YXRpb25OYW1lW2NodW5rXSA9IG5ldyBTdHJpbmdbQ0hVTktfU0laRV07Ci0gICAgICAgIGZOb3RhdGlvblB1YmxpY0lkW2NodW5rXSA9IG5ldyBTdHJpbmdbQ0hVTktfU0laRV07Ci0gICAgICAgIGZOb3RhdGlvblN5c3RlbUlkW2NodW5rXSA9IG5ldyBTdHJpbmdbQ0hVTktfU0laRV07Ci0gICAgICAgIGZOb3RhdGlvbkJhc2VTeXN0ZW1JZFtjaHVua10gPSBuZXcgU3RyaW5nW0NIVU5LX1NJWkVdOwotICAgICAgICByZXR1cm47Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUNvbnRlbnRTcGVjQ2FwYWNpdHkoaW50IGNodW5rKSB7Ci0gICAgICAgIGlmIChjaHVuayA+PSBmQ29udGVudFNwZWNUeXBlLmxlbmd0aCkgewotICAgICAgICAgICAgZkNvbnRlbnRTcGVjVHlwZSA9IHJlc2l6ZShmQ29udGVudFNwZWNUeXBlLCBmQ29udGVudFNwZWNUeXBlLmxlbmd0aCAqIDIpOwotICAgICAgICAgICAgZkNvbnRlbnRTcGVjVmFsdWUgPSByZXNpemUoZkNvbnRlbnRTcGVjVmFsdWUsIGZDb250ZW50U3BlY1ZhbHVlLmxlbmd0aCAqIDIpOwotICAgICAgICAgICAgZkNvbnRlbnRTcGVjT3RoZXJWYWx1ZSA9IHJlc2l6ZShmQ29udGVudFNwZWNPdGhlclZhbHVlLCBmQ29udGVudFNwZWNPdGhlclZhbHVlLmxlbmd0aCAqIDIpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKGZDb250ZW50U3BlY1R5cGVbY2h1bmtdICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotCi0gICAgICAgIGZDb250ZW50U3BlY1R5cGVbY2h1bmtdID0gbmV3IHNob3J0W0NIVU5LX1NJWkVdOwotICAgICAgICBmQ29udGVudFNwZWNWYWx1ZVtjaHVua10gPSBuZXcgT2JqZWN0W0NIVU5LX1NJWkVdOwotICAgICAgICBmQ29udGVudFNwZWNPdGhlclZhbHVlW2NodW5rXSA9IG5ldyBPYmplY3RbQ0hVTktfU0laRV07Ci0gICAgICAgIHJldHVybjsKLSAgICB9Ci0KLSAgICAvLwotICAgIC8vIFByaXZhdGUgc3RhdGljIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLy8gcmVzaXplIGNodW5rcwotCi0gICAgcHJpdmF0ZSBzdGF0aWMgYnl0ZVtdW10gcmVzaXplKGJ5dGUgYXJyYXlbXVtdLCBpbnQgbmV3c2l6ZSkgewotICAgICAgICBieXRlIG5ld2FycmF5W11bXSA9IG5ldyBieXRlW25ld3NpemVdW107Ci0gICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYXJyYXksIDAsIG5ld2FycmF5LCAwLCBhcnJheS5sZW5ndGgpOwotICAgICAgICByZXR1cm4gbmV3YXJyYXk7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBzdGF0aWMgc2hvcnRbXVtdIHJlc2l6ZShzaG9ydCBhcnJheVtdW10sIGludCBuZXdzaXplKSB7Ci0gICAgICAgIHNob3J0IG5ld2FycmF5W11bXSA9IG5ldyBzaG9ydFtuZXdzaXplXVtdOwotICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGFycmF5LCAwLCBuZXdhcnJheSwgMCwgYXJyYXkubGVuZ3RoKTsKLSAgICAgICAgcmV0dXJuIG5ld2FycmF5OwotICAgIH0KLQotICAgIHByaXZhdGUgc3RhdGljIGludFtdW10gcmVzaXplKGludCBhcnJheVtdW10sIGludCBuZXdzaXplKSB7Ci0gICAgICAgIGludCBuZXdhcnJheVtdW10gPSBuZXcgaW50W25ld3NpemVdW107Ci0gICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYXJyYXksIDAsIG5ld2FycmF5LCAwLCBhcnJheS5sZW5ndGgpOwotICAgICAgICByZXR1cm4gbmV3YXJyYXk7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBzdGF0aWMgRGF0YXR5cGVWYWxpZGF0b3JbXVtdIHJlc2l6ZShEYXRhdHlwZVZhbGlkYXRvciBhcnJheVtdW10sIGludCBuZXdzaXplKSB7Ci0gICAgICAgIERhdGF0eXBlVmFsaWRhdG9yIG5ld2FycmF5W11bXSA9IG5ldyBEYXRhdHlwZVZhbGlkYXRvcltuZXdzaXplXVtdOwotICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGFycmF5LCAwLCBuZXdhcnJheSwgMCwgYXJyYXkubGVuZ3RoKTsKLSAgICAgICAgcmV0dXJuIG5ld2FycmF5OwotICAgIH0KLQotICAgIHByaXZhdGUgc3RhdGljIENvbnRlbnRNb2RlbFZhbGlkYXRvcltdW10gcmVzaXplKENvbnRlbnRNb2RlbFZhbGlkYXRvciBhcnJheVtdW10sIGludCBuZXdzaXplKSB7Ci0gICAgICAgIENvbnRlbnRNb2RlbFZhbGlkYXRvciBuZXdhcnJheVtdW10gPSBuZXcgQ29udGVudE1vZGVsVmFsaWRhdG9yW25ld3NpemVdW107Ci0gICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYXJyYXksIDAsIG5ld2FycmF5LCAwLCBhcnJheS5sZW5ndGgpOwotICAgICAgICByZXR1cm4gbmV3YXJyYXk7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBzdGF0aWMgT2JqZWN0W11bXSByZXNpemUoT2JqZWN0IGFycmF5W11bXSwgaW50IG5ld3NpemUpIHsKLSAgICAgICAgT2JqZWN0IG5ld2FycmF5W11bXSA9IG5ldyBPYmplY3RbbmV3c2l6ZV1bXTsKLSAgICAgICAgU3lzdGVtLmFycmF5Y29weShhcnJheSwgMCwgbmV3YXJyYXksIDAsIGFycmF5Lmxlbmd0aCk7Ci0gICAgICAgIHJldHVybiBuZXdhcnJheTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBRTmFtZVtdW10gcmVzaXplKFFOYW1lIGFycmF5W11bXSwgaW50IG5ld3NpemUpIHsKLSAgICAgICAgUU5hbWUgbmV3YXJyYXlbXVtdID0gbmV3IFFOYW1lW25ld3NpemVdW107Ci0gICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYXJyYXksIDAsIG5ld2FycmF5LCAwLCBhcnJheS5sZW5ndGgpOwotICAgICAgICByZXR1cm4gbmV3YXJyYXk7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nW11bXSByZXNpemUoU3RyaW5nIGFycmF5W11bXSwgaW50IG5ld3NpemUpIHsKLSAgICAgICAgU3RyaW5nIG5ld2FycmF5W11bXSA9IG5ldyBTdHJpbmdbbmV3c2l6ZV1bXTsKLSAgICAgICAgU3lzdGVtLmFycmF5Y29weShhcnJheSwgMCwgbmV3YXJyYXksIDAsIGFycmF5Lmxlbmd0aCk7Ci0gICAgICAgIHJldHVybiBuZXdhcnJheTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmdbXVtdW10gcmVzaXplKFN0cmluZyBhcnJheVtdW11bXSwgaW50IG5ld3NpemUpIHsKLSAgICAgICAgU3RyaW5nIG5ld2FycmF5W11bXVtdID0gbmV3IFN0cmluZ1tuZXdzaXplXSBbXVtdOwotICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGFycmF5LCAwLCBuZXdhcnJheSwgMCwgYXJyYXkubGVuZ3RoKTsKLSAgICAgICAgcmV0dXJuIG5ld2FycmF5OwotICAgIH0KLQotICAgIC8vCi0gICAgLy8gQ2xhc3NlcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBDaGlsZHJlbiBsaXN0IGZvciA8Y29kZT5jb250ZW50U3BlY1RyZWU8L2NvZGU+IG1ldGhvZC4KLSAgICAgKgotICAgICAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAgICAgKgotICAgICAqIEBhdXRob3IgRXJpYyBZZSwgSUJNCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgQ2hpbGRyZW5MaXN0IHsKLQotICAgICAgICAvLwotICAgICAgICAvLyBEYXRhCi0gICAgICAgIC8vCi0KLSAgICAgICAgLyoqIExlbmd0aC4gKi8KLSAgICAgICAgcHVibGljIGludCBsZW5ndGggPSAwOwotCi0gICAgICAgIC8vIE5PVEU6IFRoZSBmb2xsb3dpbmcgc2V0IG9mIGRhdGEgaXMgbXV0dWFsbHkgZXhjbHVzaXZlLiBJdCBpcwotICAgICAgICAvLyAgICAgICB3cml0dGVuIHRoaXMgd2F5IGJlY2F1c2UgSmF2YSBkb2Vzbid0IGhhdmUgYSBuYXRpdmUKLSAgICAgICAgLy8gICAgICAgdW5pb24gZGF0YSBzdHJ1Y3R1cmUuIC1BYwotCi0gICAgICAgIC8qKiBMZWZ0IGFuZCByaWdodCBjaGlsZHJlbiBuYW1lcy4gKi8KLSAgICAgICAgcHVibGljIFFOYW1lW10gcW5hbWUgPSBuZXcgUU5hbWVbMl07Ci0KLSAgICAgICAgLyoqIExlZnQgYW5kIHJpZ2h0IGNoaWxkcmVuIHR5cGVzLiAqLwotICAgICAgICBwdWJsaWMgaW50W10gdHlwZSA9IG5ldyBpbnRbMl07Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gQ29uc3RydWN0b3JzCi0gICAgICAgIC8vCi0KLSAgICAgICAgcHVibGljIENoaWxkcmVuTGlzdCAoKSB7fQotCi0gICAgfSAvLyBjbGFzcyBDaGlsZHJlbkxpc3QKLQotICAgIC8vCi0gICAgLy8gRW50aXR5U3RhdGUgbWV0aG9kcwotICAgIC8vCi0gICAgcHVibGljIGJvb2xlYW4gaXNFbnRpdHlEZWNsYXJlZCAoU3RyaW5nIG5hbWUpewotICAgICAgICByZXR1cm4gKGdldEVudGl0eURlY2xJbmRleChuYW1lKSE9LTEpP3RydWU6ZmFsc2U7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gaXNFbnRpdHlVbnBhcnNlZCAoU3RyaW5nIG5hbWUpewotICAgICAgICBpbnQgZW50aXR5SW5kZXggPSBnZXRFbnRpdHlEZWNsSW5kZXgobmFtZSk7Ci0gICAgICAgIGlmIChlbnRpdHlJbmRleCA+LTEpIHsKLSAgICAgICAgICAgIGludCBjaHVuayA9IGVudGl0eUluZGV4ID4+IENIVU5LX1NISUZUOwotICAgICAgICAgICAgaW50IGluZGV4ID0gZW50aXR5SW5kZXggJiBDSFVOS19NQVNLOwotICAgICAgICAgICAgLy9mb3IgdW5wYXJzZWQgZW50aXR5IG5vdGF0aW9uIT1udWxsCi0gICAgICAgICAgICByZXR1cm4gKGZFbnRpdHlOb3RhdGlvbltjaHVua11baW5kZXhdIT1udWxsKT90cnVlOmZhbHNlOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci19IC8vIGNsYXNzIERUREdyYW1tYXIKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHRkL0RUREdyYW1tYXJCdWNrZXQuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHRkL0RUREdyYW1tYXJCdWNrZXQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZmQ2NTZiYy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R0ZC9EVERHcmFtbWFyQnVja2V0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMTIgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAxNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqLwotLyoKLSAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQotICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCi0gKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCi0gKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAotICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKLSAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdGQ7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5ncmFtbWFycy5YTUxHcmFtbWFyRGVzY3JpcHRpb247Ci1pbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7Ci1pbXBvcnQgamF2YS51dGlsLk1hcDsKLQotLyoqCi0gKiBUaGlzIHZlcnkgc2ltcGxlIGNsYXNzIGlzIHRoZSBza2VsZXRvbiBvZiB3aGF0IHRoZSBEVERWYWxpZGF0b3IgY291bGQgdXNlCi0gKiB0byBzdG9yZSB2YXJpb3VzIGdyYW1tYXJzIHRoYXQgaXQgZ2V0cyBmcm9tIHRoZSBHcmFtbWFyUG9vbC4gIEFzIGluIHRoZQotICogY2FzZSBvZiBYU0dyYW1tYXJCdWNrZXQsIG9uZSB0aGlua3Mgb2YgdGhpcyBvYmplY3QgYXMgYmVpbmcgY2xvc2VseQotICogYXNzb2NpYXRlZCB3aXRoIGl0cyB2YWxpZGF0b3I7IHdoZW4gZnVsbHkgbWF0dXJlLCB0aGlzIGNsYXNzIHdpbGwgYmUKLSAqIGZpbGxlZCBmcm9tIHRoZSBHcmFtbWFyUG9vbCB3aGVuIHRoZSBEVERWYWxpZGF0b3IgaXMgaW52b2tlZCBvbiBhCi0gKiBkb2N1bWVudCwgYW5kLCBpZiBhIG5ldyBEVEQgZ3JhbW1hciBpcyBwYXJzZWQsIHRoZSBuZXcgc2V0IHdpbGwgYmUKLSAqIG9mZmVyZWQgYmFjayB0byB0aGUgR3JhbW1hclBvb2wgZm9yIHBvc3NpYmxlIGluY2x1c2lvbi4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBOZWlsIEdyYWhhbSwgSUJNCi0gKgotKi8KLXB1YmxpYyBjbGFzcyBEVERHcmFtbWFyQnVja2V0IHsKLQotICAgIC8vIFJFVklTSVQ6ICBtYWtlIHRoaXMgY2xhc3Mgc21hcnRlciBhbmQgKndheSogbW9yZSBjb21wbGV0ZSEKLQotICAgIC8vCi0gICAgLy8gRGF0YQotICAgIC8vCi0KLSAgICAvKiogR3JhbW1hcnMgYXNzb2NpYXRlZCB3aXRoIGVsZW1lbnQgcm9vdCBuYW1lLiAqLwotICAgIHByb3RlY3RlZCBNYXA8WE1MRFRERGVzY3JpcHRpb24sIERUREdyYW1tYXI+IGZHcmFtbWFyczsKLQotICAgIC8vIHRoZSB1bmlxdWUgZ3JhbW1hciBmcm9tIGZHcmFtbWFycyAob3IgdGhhdCB3ZSdyZQotICAgIC8vIGJ1aWxkaW5nKSB0aGF0IGlzIHVzZWQgaW4gdmFsaWRhdGlvbi4KLSAgICBwcm90ZWN0ZWQgRFRER3JhbW1hciBmQWN0aXZlR3JhbW1hcjsKLQotICAgIC8vIGlzIHRoZSAiYWN0aXZlIiBncmFtbWFyIHN0YW5kYWxvbmU/Ci0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZklzU3RhbmRhbG9uZTsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKiBEZWZhdWx0IGNvbnN0cnVjdG9yLiAqLwotICAgIHB1YmxpYyBEVERHcmFtbWFyQnVja2V0KCkgewotICAgICAgICBmR3JhbW1hcnMgPSBuZXcgSGFzaE1hcDw+KCk7Ci0gICAgfSAvLyA8aW5pdD4oKQotCi0gICAgLy8KLSAgICAvLyBQdWJsaWMgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBQdXRzIHRoZSBzcGVjaWZpZWQgZ3JhbW1hciBpbnRvIHRoZSBncmFtbWFyIHBvb2wgYW5kIGFzc29jaWF0ZSBpdCB0bwotICAgICAqIGEgcm9vdCBlbGVtZW50IG5hbWUgKHRoaXMgYmVpbmcgaW50ZXJuYWwsIHRoZSBsYWNrIG9mIGdlbmVyYWxpdHkgaXMgaXJyZWxldmFudCkuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZ3JhbW1hciAgICAgVGhlIGdyYW1tYXIuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcHV0R3JhbW1hcihEVERHcmFtbWFyIGdyYW1tYXIpIHsKLSAgICAgICAgWE1MRFRERGVzY3JpcHRpb24gZGVzYyA9IChYTUxEVEREZXNjcmlwdGlvbilncmFtbWFyLmdldEdyYW1tYXJEZXNjcmlwdGlvbigpOwotICAgICAgICBmR3JhbW1hcnMucHV0KGRlc2MsIGdyYW1tYXIpOwotICAgIH0gLy8gcHV0R3JhbW1hcihEVERHcmFtbWFyKQotCi0gICAgLy8gcmV0cmlldmUgYSBEVERHcmFtbWFyIGdpdmVuIGFuIFhNTERURERlc2NyaXB0aW9uCi0gICAgcHVibGljIERUREdyYW1tYXIgZ2V0R3JhbW1hcihYTUxHcmFtbWFyRGVzY3JpcHRpb24gZGVzYykgewotICAgICAgICByZXR1cm4gZkdyYW1tYXJzLmdldCgoWE1MRFRERGVzY3JpcHRpb24pZGVzYyk7Ci0gICAgfSAvLyBwdXRHcmFtbWFyKERUREdyYW1tYXIpCi0KLSAgICBwdWJsaWMgdm9pZCBjbGVhcigpIHsKLSAgICAgICAgZkdyYW1tYXJzLmNsZWFyKCk7Ci0gICAgICAgIGZBY3RpdmVHcmFtbWFyID0gbnVsbDsKLSAgICAgICAgZklzU3RhbmRhbG9uZSA9IGZhbHNlOwotICAgIH0gLy8gY2xlYXIoKQotCi0gICAgLy8gaXMgdGhlIGFjdGl2ZSBncmFtbWFyIHN0YW5kYWxvbmU/ICBUaGlzIG11c3QgbGl2ZSBoZXJlIGJlY2F1c2UKLSAgICAvLyBhdCB0aGUgdGltZSB0aGUgdmFsaWRhdG9yIGRpc2NvdmVycyB0aGlzIHdlIGRvbid0IHlldCBrbm93Ci0gICAgLy8gd2hhdCB0aGUgYWN0aXZlIGdyYW1tYXIgc2hvdWxkIGJlIChubyBpbmZvIGFib3V0IHJvb3QpCi0gICAgdm9pZCBzZXRTdGFuZGFsb25lKGJvb2xlYW4gc3RhbmRhbG9uZSkgewotICAgICAgICBmSXNTdGFuZGFsb25lID0gc3RhbmRhbG9uZTsKLSAgICB9Ci0KLSAgICBib29sZWFuIGdldFN0YW5kYWxvbmUoKSB7Ci0gICAgICAgIHJldHVybiBmSXNTdGFuZGFsb25lOwotICAgIH0KLQotICAgIC8vIHNldCB0aGUgImFjdGl2ZSIgZ3JhbW1hcjoKLSAgICB2b2lkIHNldEFjdGl2ZUdyYW1tYXIgKERUREdyYW1tYXIgZ3JhbW1hcikgewotICAgICAgICBmQWN0aXZlR3JhbW1hciA9IGdyYW1tYXI7Ci0gICAgfQotICAgIERUREdyYW1tYXIgZ2V0QWN0aXZlR3JhbW1hciAoKSB7Ci0gICAgICAgIHJldHVybiBmQWN0aXZlR3JhbW1hcjsKLSAgICB9Ci19IC8vIGNsYXNzIERUREdyYW1tYXJCdWNrZXQKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHRkL1hNTDExRFREUHJvY2Vzc29yLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R0ZC9YTUwxMURURFByb2Nlc3Nvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0MDc0OTg2Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHRkL1hNTDExRFREUHJvY2Vzc29yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMjggKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OS0yMDAyIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYZXJjZXMiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIEludGVybmF0aW9uYWwKLSAqIEJ1c2luZXNzIE1hY2hpbmVzLCBJbmMuLCBodHRwOi8vd3d3LmFwYWNoZS5vcmcuICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHRkOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLkNvbnN0YW50czsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuWE1MMTFEVERTY2FubmVySW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuWE1MRFREU2Nhbm5lckltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLlhNTEVudGl0eU1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLlhNTEVycm9yUmVwb3J0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlN5bWJvbFRhYmxlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5YTUwxMUNoYXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuZ3JhbW1hcnMuWE1MR3JhbW1hclBvb2w7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTEVudGl0eVJlc29sdmVyOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgZXh0ZW5kcyBYTUxEVERQcm9jZXNzb3IgYnkgZ2l2aW5nIGl0Ci0gKiB0aGUgYWJpbGl0eSB0byBwYXJzZSBYTUwgMS4xIGRvY3VtZW50cyBjb3JyZWN0bHkuICBJdCBjYW4gYWxzbyBiZSB1c2VkCi0gKiBhcyBhIERURCBsb2FkZXIsIHNvIHRoYXQgWE1MIDEuMSBleHRlcm5hbCBzdWJzZXRzIGNhbgotICogYmUgcHJvY2Vzc2VkIGNvcnJlY3RseSAoaGVuY2UgaXQncyByYXRoZXIgYW5vbWFsb3VzLWFwcGVhcmluZwotICogZGVyaXZhdGlvbiBmcm9tIFhNTERURExvYWRlcikuCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgTmVpbCBHcmFoYW0sIElCTQotICoKLSAqLwotcHVibGljIGNsYXNzIFhNTDExRFREUHJvY2Vzc29yIGV4dGVuZHMgWE1MRFRETG9hZGVyewotCi0gICAgLy8gY29uc3RydWN0b3JzCi0KLSAgICBwdWJsaWMgWE1MMTFEVERQcm9jZXNzb3IoKSB7Ci0gICAgICAgIHN1cGVyKCk7Ci0gICAgfSAvLyA8aW5pdD4oKQotCi0gICAgcHVibGljIFhNTDExRFREUHJvY2Vzc29yKFN5bWJvbFRhYmxlIHN5bWJvbFRhYmxlKSB7Ci0gICAgICAgIHN1cGVyKHN5bWJvbFRhYmxlKTsKLSAgICB9IC8vIGluaXQoU3ltYm9sVGFibGUpCi0KLSAgICBwdWJsaWMgWE1MMTFEVERQcm9jZXNzb3IoU3ltYm9sVGFibGUgc3ltYm9sVGFibGUsCi0gICAgICAgICAgICAgICAgWE1MR3JhbW1hclBvb2wgZ3JhbW1hclBvb2wpIHsKLSAgICAgICAgc3VwZXIoc3ltYm9sVGFibGUsIGdyYW1tYXJQb29sKTsKLSAgICB9IC8vIGluaXQoU3ltYm9sVGFibGUsIFhNTEdyYW1tYXJQb29sKQotCi0gICAgWE1MMTFEVERQcm9jZXNzb3IoU3ltYm9sVGFibGUgc3ltYm9sVGFibGUsCi0gICAgICAgICAgICAgICAgWE1MR3JhbW1hclBvb2wgZ3JhbW1hclBvb2wsIFhNTEVycm9yUmVwb3J0ZXIgZXJyb3JSZXBvcnRlciwKLSAgICAgICAgICAgICAgICBYTUxFbnRpdHlSZXNvbHZlciBlbnRpdHlSZXNvbHZlcikgewotICAgICAgICBzdXBlcihzeW1ib2xUYWJsZSwgZ3JhbW1hclBvb2wsIGVycm9yUmVwb3J0ZXIsIGVudGl0eVJlc29sdmVyKTsKLSAgICB9IC8vIGluaXQoU3ltYm9sVGFibGUsIFhNTEdyYW1tYXJQb29sLCBYTUxFcnJvclJlcG9ydGVyLCBYTUxFbnRpdHlSZXNvbHZlcikKLQotICAgIC8vIG92ZXJyaWRkZW4gbWV0aG9kcwotCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gaXNWYWxpZE5tdG9rZW4oU3RyaW5nIG5tdG9rZW4pIHsKLSAgICAgICAgcmV0dXJuIFhNTDExQ2hhci5pc1hNTDExVmFsaWRObXRva2VuKG5tdG9rZW4pOwotICAgIH0gLy8gaXNWYWxpZE5tdG9rZW4oU3RyaW5nKTogIGJvb2xlYW4KLQotICAgIHByb3RlY3RlZCBib29sZWFuIGlzVmFsaWROYW1lKFN0cmluZyBuYW1lKSB7Ci0gICAgICAgIHJldHVybiBYTUwxMUNoYXIuaXNYTUwxMVZhbGlkTmFtZShuYW1lKTsKLSAgICB9IC8vIGlzVmFsaWRObXRva2VuKFN0cmluZyk6ICBib29sZWFuCi0KLSAgICBwcm90ZWN0ZWQgWE1MRFREU2Nhbm5lckltcGwgY3JlYXRlRFREU2Nhbm5lcihTeW1ib2xUYWJsZSBzeW1ib2xUYWJsZSwKLSAgICAgICAgICAgIFhNTEVycm9yUmVwb3J0ZXIgZXJyb3JSZXBvcnRlciwgWE1MRW50aXR5TWFuYWdlciBlbnRpdHlNYW5hZ2VyKSB7Ci0gICAgICAgIHJldHVybiBuZXcgWE1MMTFEVERTY2FubmVySW1wbChzeW1ib2xUYWJsZSwgZXJyb3JSZXBvcnRlciwgZW50aXR5TWFuYWdlcik7Ci0gICAgfSAvLyBjcmVhdGVEVERTY2FubmVyKFN5bWJvbFRhYmxlLCBYTUxFcnJvclJlcG9ydGVyLCBYTUxFbnRpdHlNYW5hZ2VyKSA6IFhNTERURFNjYW5uZXJJbXBsCi0KLSAgICBwcm90ZWN0ZWQgc2hvcnQgZ2V0U2Nhbm5lclZlcnNpb24oKSB7Ci0gICAgICAgIHJldHVybiBDb25zdGFudHMuWE1MX1ZFUlNJT05fMV8xOwotICAgIH0gLy8gZ2V0U2Nhbm5lclZlcnNpb24oKSA6IHNob3J0Ci0KLX0gLy8gY2xhc3MgWE1MMTFEVERQcm9jZXNzb3IKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHRkL1hNTDExRFREVmFsaWRhdG9yLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R0ZC9YTUwxMURURFZhbGlkYXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhMzliYTBiLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHRkL1hNTDExRFREVmFsaWRhdG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMjYgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OS0yMDAzIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYZXJjZXMiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIEludGVybmF0aW9uYWwKLSAqIEJ1c2luZXNzIE1hY2hpbmVzLCBJbmMuLCBodHRwOi8vd3d3LmFwYWNoZS5vcmcuICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHRkOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLkNvbnN0YW50czsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MQ29tcG9uZW50TWFuYWdlcjsKLQotLyoqCi0gKiBUaGlzIGFsbG93cyB0aGUgdmFsaWRhdG9yIHRvIGNvcnJlY3RseWhhbmRsZSBYTUwgMS4xCi0gKiBkb2N1bWVudHMuCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgTmVpbCBHcmFoYW0KLSAqLwotcHVibGljIGNsYXNzIFhNTDExRFREVmFsaWRhdG9yIGV4dGVuZHMgWE1MRFREVmFsaWRhdG9yIHsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RhbnRzCi0gICAgLy8KLQotICAgIHByb3RlY3RlZCBmaW5hbCBzdGF0aWMgU3RyaW5nIERURF9WQUxJREFUT1JfUFJPUEVSVFkgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCtDb25zdGFudHMuRFREX1ZBTElEQVRPUl9QUk9QRVJUWTsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKiBEZWZhdWx0IGNvbnN0cnVjdG9yLiAqLwotICAgIHB1YmxpYyBYTUwxMURURFZhbGlkYXRvcigpIHsKLQotICAgICAgICBzdXBlcigpOwotICAgIH0gLy8gPGluaXQ+KCkKLQotICAgIC8vIG92ZXJyaWRkZW4gc28gdGhhdCB0aGlzIGNsYXNzIGhhcyBhY2Nlc3MgdG8gdGhlIHNhbWUKLSAgICAvLyBncmFtbWFyQnVja2V0IGFzIHRoZSBjb3JyZXNwb25kaW5nIERURFByb2Nlc3NvcgotICAgIC8vIHdpbGwgdHJ5IGFuZCB1c2UuLi4KLSAgICBwdWJsaWMgdm9pZCByZXNldChYTUxDb21wb25lbnRNYW5hZ2VyIG1hbmFnZXIpIHsKLSAgICAgICAgWE1MRFREVmFsaWRhdG9yIGN1cnIgPSBudWxsOwotICAgICAgICBpZigoY3VyciA9IChYTUxEVERWYWxpZGF0b3IpbWFuYWdlci5nZXRQcm9wZXJ0eShEVERfVkFMSURBVE9SX1BST1BFUlRZKSkgIT0gbnVsbCAmJgotICAgICAgICAgICAgICAgIGN1cnIgIT0gdGhpcykgewotICAgICAgICAgICAgZkdyYW1tYXJCdWNrZXQgPSBjdXJyLmdldEdyYW1tYXJCdWNrZXQoKTsKLSAgICAgICAgfQotICAgICAgICBzdXBlci5yZXNldChtYW5hZ2VyKTsKLSAgICB9IC8vcmVzZXQoWE1MQ29tcG9uZW50TWFuYWdlcikKLQotICAgIHByb3RlY3RlZCB2b2lkIGluaXQoKSB7Ci0gICAgICAgIGlmKGZWYWxpZGF0aW9uIHx8IGZEeW5hbWljVmFsaWRhdGlvbikgewotICAgICAgICAgICAgc3VwZXIuaW5pdCgpOwotICAgICAgICAgICAgLy8gbm93IG92ZXJ3cml0ZSBzb21lIGVudHJpZXMgaW4gcGFyZW50OgotCi0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIGZWYWxJRCAgICAgICA9IGZEYXRhdHlwZVZhbGlkYXRvckZhY3RvcnkuZ2V0QnVpbHRJbkRWKCJYTUwxMUlEIik7Ci0gICAgICAgICAgICAgICAgZlZhbElEUmVmICAgID0gZkRhdGF0eXBlVmFsaWRhdG9yRmFjdG9yeS5nZXRCdWlsdEluRFYoIlhNTDExSURSRUYiKTsKLSAgICAgICAgICAgICAgICBmVmFsSURSZWZzICAgPSBmRGF0YXR5cGVWYWxpZGF0b3JGYWN0b3J5LmdldEJ1aWx0SW5EVigiWE1MMTFJRFJFRlMiKTsKLSAgICAgICAgICAgICAgICBmVmFsTk1UT0tFTiAgPSBmRGF0YXR5cGVWYWxpZGF0b3JGYWN0b3J5LmdldEJ1aWx0SW5EVigiWE1MMTFOTVRPS0VOIik7Ci0gICAgICAgICAgICAgICAgZlZhbE5NVE9LRU5TID0gZkRhdGF0eXBlVmFsaWRhdG9yRmFjdG9yeS5nZXRCdWlsdEluRFYoIlhNTDExTk1UT0tFTlMiKTsKLQotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgLy8gc2hvdWxkIG5ldmVyIGhhcHBlbgotICAgICAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKFN5c3RlbS5lcnIpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfSAvLyBpbml0KCkKLQotfSAvLyBjbGFzcyBYTUwxMURURFZhbGlkYXRvcgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdGQvWE1MMTFOU0RURFZhbGlkYXRvci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdGQvWE1MMTFOU0RURFZhbGlkYXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmYzZkYzkxLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHRkL1hNTDExTlNEVERWYWxpZGF0b3IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI2NiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5LTIwMDMgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICogQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhlcmNlcyIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMiwgSW50ZXJuYXRpb25hbAotICogQnVzaW5lc3MgTWFjaGluZXMsIEluYy4sIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdGQ7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuWE1MRXJyb3JSZXBvcnRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwubXNnLlhNTE1lc3NhZ2VGb3JtYXR0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlhNTFN5bWJvbHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuQXVnbWVudGF0aW9uczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5OYW1lc3BhY2VDb250ZXh0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlFOYW1lOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTEF0dHJpYnV0ZXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE5JRXhjZXB0aW9uOwotCi0vKioKLSAqIFRoZSBEVEQgdmFsaWRhdG9yLiBUaGUgdmFsaWRhdG9yIGltcGxlbWVudHMgYSBkb2N1bWVudAotICogZmlsdGVyOiByZWNlaXZpbmcgZG9jdW1lbnQgZXZlbnRzIGZyb20gdGhlIHNjYW5uZXI7IHZhbGlkYXRpbmcKLSAqIHRoZSBjb250ZW50IGFuZCBzdHJ1Y3R1cmU7IGF1Z21lbnRpbmcgdGhlIEluZm9TZXQsIGlmIGFwcGxpY2FibGU7Ci0gKiBhbmQgbm90aWZ5aW5nIHRoZSBwYXJzZXIgb2YgdGhlIGluZm9ybWF0aW9uIHJlc3VsdGluZyBmcm9tIHRoZQotICogdmFsaWRhdGlvbiBwcm9jZXNzLgotICogPHA+IEZvcm1lcmx5LCB0aGlzIGNvbXBvbmVudCBhbHNvIGhhbmRsZWQgRFREIGV2ZW50cyBhbmQgZ3JhbW1hciBjb25zdHJ1Y3Rpb24uCi0gKiBUbyBmYWNpbGl0YXRlIHRoZSBkZXZlbG9wbWVudCBvZiBhIG1lYW5pbmdmdWwgRFREIGdyYW1tYXIgY2FjaGluZy9wcmVwYXJzaW5nCi0gKiBmcmFtZXdvcmssIHRoaXMgZnVuY3Rpb25hbGl0eSBoYXMgYmVlbiBtb3ZlZCBpbnRvIHRoZSBYTUxEVERMb2FkZXIKLSAqIGNsYXNzLiAgVGhlcmVmb3JlLCB0aGlzIGNsYXNzIG5vIGxvbmdlciBpbXBsZW1lbnRzIHRoZSBEVERGaWx0ZXIKLSAqIG9yIERURENvbnRlbnRNb2RlbEZpbHRlciBpbnRlcmZhY2VzLgotICogPHA+Ci0gKiBUaGlzIGNvbXBvbmVudCByZXF1aXJlcyB0aGUgZm9sbG93aW5nIGZlYXR1cmVzIGFuZCBwcm9wZXJ0aWVzIGZyb20gdGhlCi0gKiBjb21wb25lbnQgbWFuYWdlciB0aGF0IHVzZXMgaXQ6Ci0gKiA8dWw+Ci0gKiAgPGxpPmh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy9uYW1lc3BhY2VzPC9saT4KLSAqICA8bGk+aHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL3ZhbGlkYXRpb248L2xpPgotICogIDxsaT5odHRwOi8vYXBhY2hlLm9yZy94bWwvZmVhdHVyZXMvdmFsaWRhdGlvbi9keW5hbWljPC9saT4KLSAqICA8bGk+aHR0cDovL2FwYWNoZS5vcmcveG1sL3Byb3BlcnRpZXMvaW50ZXJuYWwvc3ltYm9sLXRhYmxlPC9saT4KLSAqICA8bGk+aHR0cDovL2FwYWNoZS5vcmcveG1sL3Byb3BlcnRpZXMvaW50ZXJuYWwvZXJyb3ItcmVwb3J0ZXI8L2xpPgotICogIDxsaT5odHRwOi8vYXBhY2hlLm9yZy94bWwvcHJvcGVydGllcy9pbnRlcm5hbC9ncmFtbWFyLXBvb2w8L2xpPgotICogIDxsaT5odHRwOi8vYXBhY2hlLm9yZy94bWwvcHJvcGVydGllcy9pbnRlcm5hbC9kYXRhdHlwZS12YWxpZGF0b3ItZmFjdG9yeTwvbGk+Ci0gKiA8L3VsPgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIEVsZW5hIExpdGFuaSwgSUJNCi0gKiBAYXV0aG9yIE1pY2hhZWwgR2xhdmFzc2V2aWNoLCBJQk0KLSAqCi0KLSAqLwotcHVibGljIGNsYXNzIFhNTDExTlNEVERWYWxpZGF0b3IgZXh0ZW5kcyBYTUwxMURURFZhbGlkYXRvciB7Ci0KLSAgICAvKiogQXR0cmlidXRlIFFOYW1lLiAqLwotICAgIHByaXZhdGUgUU5hbWUgZkF0dHJpYnV0ZVFOYW1lID0gbmV3IFFOYW1lKCk7Ci0KLSAgICAvKiogQmluZCBuYW1lc3BhY2VzICovCi0gICAgcHJvdGVjdGVkIGZpbmFsIHZvaWQgc3RhcnROYW1lc3BhY2VTY29wZShRTmFtZSBlbGVtZW50LCBYTUxBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMsIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy8gYWRkIG5ldyBuYW1lc3BhY2UgY29udGV4dAotICAgICAgICBmTmFtZXNwYWNlQ29udGV4dC5wdXNoQ29udGV4dCgpOwotCi0gICAgICAgIGlmIChlbGVtZW50LnByZWZpeCA9PSBYTUxTeW1ib2xzLlBSRUZJWF9YTUxOUykgewotICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IoCi0gICAgICAgICAgICAgICAgWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxOU19ET01BSU4sCi0gICAgICAgICAgICAgICAgIkVsZW1lbnRYTUxOU1ByZWZpeCIsCi0gICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgZWxlbWVudC5yYXduYW1lIH0sCi0gICAgICAgICAgICAgICAgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9GQVRBTF9FUlJPUik7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBzZWFyY2ggZm9yIG5ldyBuYW1lc3BhY2UgYmluZGluZ3MKLSAgICAgICAgaW50IGxlbmd0aCA9IGF0dHJpYnV0ZXMuZ2V0TGVuZ3RoKCk7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgIFN0cmluZyBsb2NhbHBhcnQgPSBhdHRyaWJ1dGVzLmdldExvY2FsTmFtZShpKTsKLSAgICAgICAgICAgIFN0cmluZyBwcmVmaXggPSBhdHRyaWJ1dGVzLmdldFByZWZpeChpKTsKLSAgICAgICAgICAgIC8vIHdoZW4gaXQncyBvZiBmb3JtIHhtbG5zPSIuLi4iIG9yIHhtbG5zOnByZWZpeD0iLi4uIiwKLSAgICAgICAgICAgIC8vIGl0J3MgYSBuYW1lc3BhY2UgZGVjbGFyYXRpb24uIGJ1dCBwcmVmaXg6eG1sbnM9Ii4uLiIgaXNuJ3QuCi0gICAgICAgICAgICBpZiAocHJlZml4ID09IFhNTFN5bWJvbHMuUFJFRklYX1hNTE5TIHx8IHByZWZpeCA9PSBYTUxTeW1ib2xzLkVNUFRZX1NUUklORwotICAgICAgICAgICAgICAgICYmIGxvY2FscGFydCA9PSBYTUxTeW1ib2xzLlBSRUZJWF9YTUxOUykgewotCi0gICAgICAgICAgICAgICAgLy8gZ2V0IHRoZSBpbnRlcm5hbGl6ZWQgdmFsdWUgb2YgdGhpcyBhdHRyaWJ1dGUKLSAgICAgICAgICAgICAgICBTdHJpbmcgdXJpID0gZlN5bWJvbFRhYmxlLmFkZFN5bWJvbChhdHRyaWJ1dGVzLmdldFZhbHVlKGkpKTsKLQotICAgICAgICAgICAgICAgIC8vIDEuICJ4bWxucyIgY2FuJ3QgYmUgYm91bmQgdG8gYW55IG5hbWVzcGFjZQotICAgICAgICAgICAgICAgIGlmIChwcmVmaXggPT0gWE1MU3ltYm9scy5QUkVGSVhfWE1MTlMgJiYgbG9jYWxwYXJ0ID09IFhNTFN5bWJvbHMuUFJFRklYX1hNTE5TKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKAotICAgICAgICAgICAgICAgICAgICAgICAgWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxOU19ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAiQ2FudEJpbmRYTUxOUyIsCi0gICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBhdHRyaWJ1dGVzLmdldFFOYW1lKGkpfSwKLSAgICAgICAgICAgICAgICAgICAgICAgIFhNTEVycm9yUmVwb3J0ZXIuU0VWRVJJVFlfRkFUQUxfRVJST1IpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8vIDIuIHRoZSBuYW1lc3BhY2UgZm9yICJ4bWxucyIgY2FuJ3QgYmUgYm91bmQgdG8gYW55IHByZWZpeAotICAgICAgICAgICAgICAgIGlmICh1cmkgPT0gTmFtZXNwYWNlQ29udGV4dC5YTUxOU19VUkkpIHsKLSAgICAgICAgICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IoCi0gICAgICAgICAgICAgICAgICAgICAgICBYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTE5TX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICJDYW50QmluZFhNTE5TIiwKLSAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7IGF0dHJpYnV0ZXMuZ2V0UU5hbWUoaSl9LAotICAgICAgICAgICAgICAgICAgICAgICAgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9GQVRBTF9FUlJPUik7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgLy8gMy4gInhtbCIgY2FuJ3QgYmUgYm91bmQgdG8gYW55IG90aGVyIG5hbWVzcGFjZSB0aGFuIGl0J3Mgb3duCi0gICAgICAgICAgICAgICAgaWYgKGxvY2FscGFydCA9PSBYTUxTeW1ib2xzLlBSRUZJWF9YTUwpIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKHVyaSAhPSBOYW1lc3BhY2VDb250ZXh0LlhNTF9VUkkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MTlNfRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDYW50QmluZFhNTCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgYXR0cmlidXRlcy5nZXRRTmFtZShpKX0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9GQVRBTF9FUlJPUik7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLy8gNC4gdGhlIG5hbWVzcGFjZSBmb3IgInhtbCIgY2FuJ3QgYmUgYm91bmQgdG8gYW55IG90aGVyIHByZWZpeAotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICBpZiAodXJpID09IE5hbWVzcGFjZUNvbnRleHQuWE1MX1VSSSkgewotICAgICAgICAgICAgICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxOU19ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNhbnRCaW5kWE1MIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBhdHRyaWJ1dGVzLmdldFFOYW1lKGkpfSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxFcnJvclJlcG9ydGVyLlNFVkVSSVRZX0ZBVEFMX0VSUk9SKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIHByZWZpeCA9IGxvY2FscGFydCAhPSBYTUxTeW1ib2xzLlBSRUZJWF9YTUxOUyA/IGxvY2FscGFydCA6IFhNTFN5bWJvbHMuRU1QVFlfU1RSSU5HOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIERlY2xhcmUgcHJlZml4IGluIGNvbnRleHQuIFJlbW92aW5nIHRoZSBhc3NvY2lhdGlvbiBiZXR3ZWVuIGEgcHJlZml4IGFuZCBhCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG5hbWVzcGFjZSBuYW1lIGlzIHBlcm1pdHRlZCBpbiBYTUwgMS4xLCBzbyBpZiB0aGUgdXJpIHZhbHVlIGlzIHRoZSBlbXB0eSBzdHJpbmcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoZSBwcmVmaXggaXMgYmVpbmcgdW5ib3VuZC4gLS0gbXJnbGF2YXMKLSAgICAgICAgICAgICAgICBmTmFtZXNwYWNlQ29udGV4dC5kZWNsYXJlUHJlZml4KHByZWZpeCwgdXJpLmxlbmd0aCgpICE9IDAgPyB1cmkgOiBudWxsKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIGJpbmQgdGhlIGVsZW1lbnQKLSAgICAgICAgU3RyaW5nIHByZWZpeCA9IGVsZW1lbnQucHJlZml4ICE9IG51bGwgPyBlbGVtZW50LnByZWZpeCA6IFhNTFN5bWJvbHMuRU1QVFlfU1RSSU5HOwotICAgICAgICBlbGVtZW50LnVyaSA9IGZOYW1lc3BhY2VDb250ZXh0LmdldFVSSShwcmVmaXgpOwotICAgICAgICBpZiAoZWxlbWVudC5wcmVmaXggPT0gbnVsbCAmJiBlbGVtZW50LnVyaSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBlbGVtZW50LnByZWZpeCA9IFhNTFN5bWJvbHMuRU1QVFlfU1RSSU5HOwotICAgICAgICB9Ci0gICAgICAgIGlmIChlbGVtZW50LnByZWZpeCAhPSBudWxsICYmIGVsZW1lbnQudXJpID09IG51bGwpIHsKLSAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKAotICAgICAgICAgICAgICAgIFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MTlNfRE9NQUlOLAotICAgICAgICAgICAgICAgICJFbGVtZW50UHJlZml4VW5ib3VuZCIsCi0gICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgZWxlbWVudC5wcmVmaXgsIGVsZW1lbnQucmF3bmFtZSB9LAotICAgICAgICAgICAgICAgIFhNTEVycm9yUmVwb3J0ZXIuU0VWRVJJVFlfRkFUQUxfRVJST1IpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gYmluZCB0aGUgYXR0cmlidXRlcwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICBhdHRyaWJ1dGVzLmdldE5hbWUoaSwgZkF0dHJpYnV0ZVFOYW1lKTsKLSAgICAgICAgICAgIFN0cmluZyBhcHJlZml4ID0gZkF0dHJpYnV0ZVFOYW1lLnByZWZpeCAhPSBudWxsID8gZkF0dHJpYnV0ZVFOYW1lLnByZWZpeCA6IFhNTFN5bWJvbHMuRU1QVFlfU1RSSU5HOwotICAgICAgICAgICAgU3RyaW5nIGFyYXduYW1lID0gZkF0dHJpYnV0ZVFOYW1lLnJhd25hbWU7Ci0gICAgICAgICAgICBpZiAoYXJhd25hbWUgPT0gWE1MU3ltYm9scy5QUkVGSVhfWE1MTlMpIHsKLSAgICAgICAgICAgICAgICBmQXR0cmlidXRlUU5hbWUudXJpID0gZk5hbWVzcGFjZUNvbnRleHQuZ2V0VVJJKFhNTFN5bWJvbHMuUFJFRklYX1hNTE5TKTsKLSAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzLnNldE5hbWUoaSwgZkF0dHJpYnV0ZVFOYW1lKTsKLSAgICAgICAgICAgIH0gZWxzZSBpZiAoYXByZWZpeCAhPSBYTUxTeW1ib2xzLkVNUFRZX1NUUklORykgewotICAgICAgICAgICAgICAgIGZBdHRyaWJ1dGVRTmFtZS51cmkgPSBmTmFtZXNwYWNlQ29udGV4dC5nZXRVUkkoYXByZWZpeCk7Ci0gICAgICAgICAgICAgICAgaWYgKGZBdHRyaWJ1dGVRTmFtZS51cmkgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBmRXJyb3JSZXBvcnRlci5yZXBvcnRFcnJvcigKLSAgICAgICAgICAgICAgICAgICAgICAgIFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MTlNfRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgIkF0dHJpYnV0ZVByZWZpeFVuYm91bmQiLAotICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgZWxlbWVudC5yYXduYW1lLCBhcmF3bmFtZSwgYXByZWZpeCB9LAotICAgICAgICAgICAgICAgICAgICAgICAgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9GQVRBTF9FUlJPUik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXMuc2V0TmFtZShpLCBmQXR0cmlidXRlUU5hbWUpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gdmVyaWZ5IHRoYXQgZHVwbGljYXRlIGF0dHJpYnV0ZXMgZG9uJ3QgZXhpc3QKLSAgICAgICAgLy8gRXhhbXBsZTogPGZvbyB4bWxuczphPSdOUycgeG1sbnM6Yj0nTlMnIGE6YXR0cj0ndjEnIGI6YXR0cj0ndjInLz4KLSAgICAgICAgaW50IGF0dHJDb3VudCA9IGF0dHJpYnV0ZXMuZ2V0TGVuZ3RoKCk7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYXR0ckNvdW50IC0gMTsgaSsrKSB7Ci0gICAgICAgICAgICBTdHJpbmcgYXVyaSA9IGF0dHJpYnV0ZXMuZ2V0VVJJKGkpOwotICAgICAgICAgICAgaWYgKGF1cmkgPT0gbnVsbCB8fCBhdXJpID09IE5hbWVzcGFjZUNvbnRleHQuWE1MTlNfVVJJKSB7Ci0gICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBTdHJpbmcgYWxvY2FscGFydCA9IGF0dHJpYnV0ZXMuZ2V0TG9jYWxOYW1lKGkpOwotICAgICAgICAgICAgZm9yIChpbnQgaiA9IGkgKyAxOyBqIDwgYXR0ckNvdW50OyBqKyspIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgYmxvY2FscGFydCA9IGF0dHJpYnV0ZXMuZ2V0TG9jYWxOYW1lKGopOwotICAgICAgICAgICAgICAgIFN0cmluZyBidXJpID0gYXR0cmlidXRlcy5nZXRVUkkoaik7Ci0gICAgICAgICAgICAgICAgaWYgKGFsb2NhbHBhcnQgPT0gYmxvY2FscGFydCAmJiBhdXJpID09IGJ1cmkpIHsKLSAgICAgICAgICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IoCi0gICAgICAgICAgICAgICAgICAgICAgICBYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTE5TX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICJBdHRyaWJ1dGVOU05vdFVuaXF1ZSIsCi0gICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBlbGVtZW50LnJhd25hbWUsIGFsb2NhbHBhcnQsIGF1cmkgfSwKLSAgICAgICAgICAgICAgICAgICAgICAgIFhNTEVycm9yUmVwb3J0ZXIuU0VWRVJJVFlfRkFUQUxfRVJST1IpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgfSAvLyBzdGFydE5hbWVzcGFjZVNjb3BlKFFOYW1lLFhNTEF0dHJpYnV0ZXMpCi0KLSAgICAvKiogSGFuZGxlcyBlbmQgZWxlbWVudC4gKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCBlbmROYW1lc3BhY2VTY29wZShRTmFtZSBlbGVtZW50LCBBdWdtZW50YXRpb25zIGF1Z3MsIGJvb2xlYW4gaXNFbXB0eSkKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy8gYmluZCBlbGVtZW50Ci0gICAgICAgIFN0cmluZyBlcHJlZml4ID0gZWxlbWVudC5wcmVmaXggIT0gbnVsbCA/IGVsZW1lbnQucHJlZml4IDogWE1MU3ltYm9scy5FTVBUWV9TVFJJTkc7Ci0gICAgICAgIGVsZW1lbnQudXJpID0gZk5hbWVzcGFjZUNvbnRleHQuZ2V0VVJJKGVwcmVmaXgpOwotICAgICAgICBpZiAoZWxlbWVudC51cmkgIT0gbnVsbCkgewotICAgICAgICAgICAgZWxlbWVudC5wcmVmaXggPSBlcHJlZml4OwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gY2FsbCBoYW5kbGVycwotICAgICAgICBpZiAoZkRvY3VtZW50SGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAoIWlzRW1wdHkpIHsKLSAgICAgICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLmVuZEVsZW1lbnQoZWxlbWVudCwgYXVncyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBwb3AgY29udGV4dAotICAgICAgICBmTmFtZXNwYWNlQ29udGV4dC5wb3BDb250ZXh0KCk7Ci0KLSAgICB9IC8vIGVuZE5hbWVzcGFjZVNjb3BlKFFOYW1lLGJvb2xlYW4pCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R0ZC9YTUxBdHRyaWJ1dGVEZWNsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R0ZC9YTUxBdHRyaWJ1dGVEZWNsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGEwNjhmZGMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdGQvWE1MQXR0cmlidXRlRGVjbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTEwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTktMjAwMiBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhlcmNlcyIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgSW50ZXJuYXRpb25hbAotICogQnVzaW5lc3MgTWFjaGluZXMsIEluYy4sIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdGQ7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5RTmFtZTsKLQotLyoqCi0KLSAqLwotcHVibGljIGNsYXNzIFhNTEF0dHJpYnV0ZURlY2wgewotCi0gICAgLy8KLSAgICAvLyBEYXRhCi0gICAgLy8KLQotICAgIC8qKiBuYW1lICovCi0gICAgcHVibGljIGZpbmFsIFFOYW1lIG5hbWUgPSBuZXcgUU5hbWUoKTsKLQotICAgIC8qKiBzaW1wbGVUeXBlICovCi0gICAgcHVibGljIGZpbmFsIFhNTFNpbXBsZVR5cGUgc2ltcGxlVHlwZSA9IG5ldyBYTUxTaW1wbGVUeXBlKCk7Ci0KLSAgICAvKiogb3B0aW9uYWwgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBvcHRpb25hbDsKLQotICAgIC8vCi0gICAgLy8gTWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBzZXRWYWx1ZXMKLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lCi0gICAgICogQHBhcmFtIHNpbXBsZVR5cGUKLSAgICAgKiBAcGFyYW0gb3B0aW9uYWwKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRWYWx1ZXMoUU5hbWUgbmFtZSwgWE1MU2ltcGxlVHlwZSBzaW1wbGVUeXBlLCBib29sZWFuIG9wdGlvbmFsKSB7Ci0gICAgICAgIHRoaXMubmFtZS5zZXRWYWx1ZXMobmFtZSk7Ci0gICAgICAgIHRoaXMuc2ltcGxlVHlwZS5zZXRWYWx1ZXMoc2ltcGxlVHlwZSk7Ci0gICAgICAgIHRoaXMub3B0aW9uYWwgICA9IG9wdGlvbmFsOwotICAgIH0gLy8gc2V0VmFsdWVzCi0KLSAgICAvKioKLSAgICAgKiBjbGVhcgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGNsZWFyKCkgewotICAgICAgICB0aGlzLm5hbWUuY2xlYXIoKTsKLSAgICAgICAgdGhpcy5zaW1wbGVUeXBlLmNsZWFyKCk7Ci0gICAgICAgIHRoaXMub3B0aW9uYWwgICA9IGZhbHNlOwotICAgIH0gLy8gY2xlYXIKLQotfSAvLyBjbGFzcyBYTUxBdHRyaWJ1dGVEZWNsCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R0ZC9YTUxDb250ZW50U3BlYy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdGQvWE1MQ29udGVudFNwZWMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMzlmNTFjOC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R0ZC9YTUxDb250ZW50U3BlYy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzM2ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTktMjAwMiBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhlcmNlcyIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgSW50ZXJuYXRpb25hbAotICogQnVzaW5lc3MgTWFjaGluZXMsIEluYy4sIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdGQ7Ci0KLS8qKgotICogQ29udGVudFNwZWMgcmVhbGx5IGV4aXN0cyB0byBhaWQgdGhlIHBhcnNlciBjbGFzc2VzIGluIGltcGxlbWVudGluZwotICogYWNjZXNzIHRvIHRoZSBncmFtbWFyLgotICogPHA+Ci0gKiBUaGlzIGNsYXNzIGlzIHVzZWQgYnkgdGhlIERURCBzY2FubmVyIGFuZCB0aGUgdmFsaWRhdG9yIGNsYXNzZXMsCi0gKiBhbGxvd2luZyB0aGVtIHRvIGJlIHVzZWQgc2VwYXJhdGVseSBvciB0b2dldGhlci4gIFRoaXMgInN0cnVjdCIKLSAqIGNsYXNzIGlzIHVzZWQgdG8gYnVpbGQgY29udGVudCBtb2RlbHMgZm9yIHZhbGlkYXRpb24sIHdoZXJlIGl0Ci0gKiBpcyBtb3JlIGVmZmljaWVudCB0byBmZXRjaCBhbGwgb2YgdGhlIGluZm9ybWF0aW9uIGZvciBlYWNoIG9mCi0gKiB0aGVzZSBjb250ZW50IG1vZGVsICJmcmFnbWVudHMiIHRoYW4gdG8gZmV0Y2ggZWFjaCBmaWVsZCBvbmUgYXQKLSAqIGEgdGltZS4gIFNpbmNlIGNvbmZpZ3VyYXRpb25zIGFyZSBhbGxvd2VkIHRvIGhhdmUgdmFsaWRhdG9ycwotICogd2l0aG91dCBhIERURCBzY2FubmVyIChpLmUuIGEgc2NoZW1hIHZhbGlkYXRvcikgYW5kIGEgRFREIHNjYW5uZXIKLSAqIHdpdGhvdXQgYSB2YWxpZGF0b3IgKG5vbi12YWxpZGF0aW5nIHByb2Nlc3NvciksIHRoaXMgY2xhc3MgY2FuIGJlCi0gKiB1c2VkIGJ5IGVhY2ggd2l0aG91dCByZXF1aXJpbmcgdGhlIHByZXNlbmNlIG9mIHRoZSBvdGhlci4KLSAqIDxwPgotICogV2hlbiBwcm9jZXNzaW5nIGVsZW1lbnQgZGVjbGFyYXRpb25zLCB0aGUgRFREIHNjYW5uZXIgd2lsbCBidWlsZAotICogdXAgYSByZXByZXNlbnRhdGlvbiBvZiB0aGUgY29udGVudCBtb2RlbCB1c2luZyB0aGUgbm9kZSB0eXBlcyB0aGF0Ci0gKiBhcmUgZGVmaW5lZCBoZXJlLiAgU2luY2UgYSBub24tdmFsaWRhdGluZyBwcm9jZXNzb3Igb25seSBuZWVkcyB0bwotICogcmVtZW1iZXIgdGhlIHR5cGUgb2YgY29udGVudCBtb2RlbCBkZWNsYXJlZCAoaS5lLiBBTlksIEVNUFRZLCBNSVhFRCwKLSAqIG9yIENISUxEUkVOKSwgaXQgaXMgZnJlZSB0byBkaXNjYXJkIHRoZSBzcGVjaWZpYyBkZXRhaWxzIG9mIHRoZQotICogTUlYRUQgYW5kIENISUxEUkVOIGNvbnRlbnQgbW9kZWxzIGRlc2NyaWJlZCB1c2luZyB0aGlzIGNsYXNzLgotICogPHA+Ci0gKiBJbiB0aGUgdHlwaWNhbCBjYXNlIG9mIGEgdmFsaWRhdGluZyBwcm9jZXNzb3IgcmVhZGluZyB0aGUgZ3JhbW1hcgotICogb2YgdGhlIGRvY3VtZW50IGZyb20gYSBEVEQsIHRoZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgY29udGVudCBtb2RlbAotICogZGVjbGFyZWQgd2lsbCBiZSBwcmVzZXJ2ZWQgYW5kIGxhdGVyICJjb21waWxlZCIgaW50byBhbiBlZmZpY2llbnQKLSAqIGZvcm0gZm9yIHVzZSBkdXJpbmcgZWxlbWVudCB2YWxpZGF0aW9uLiAgRWFjaCBjb250ZW50IHNwZWMgbm9kZQotICogdGhhdCBpcyBzYXZlZCBpcyBhc3NpZ25lZCBhIHVuaXF1ZSBpbmRleCB0aGF0IGlzIHVzZWQgYXMgYSBoYW5kbGUKLSAqIGZvciB0aGUgInZhbHVlIiBvciAib3RoZXJWYWx1ZSIgZmllbGRzIG9mIG90aGVyIGNvbnRlbnQgc3BlYyBub2Rlcy4KLSAqIEEgbGVhZiBub2RlIGhhcyBhICJ2YWx1ZSIgdGhhdCBpcyBlaXRoZXIgYW4gaW5kZXggaW4gdGhlIHN0cmluZwotICogcG9vbCBvZiB0aGUgZWxlbWVudCB0eXBlIG9mIHRoYXQgbGVhZiwgb3IgYSB2YWx1ZSBvZiAtMSB0byBpbmRpY2F0ZQotICogdGhlIHNwZWNpYWwgIiNQQ0RBVEEiIGxlYWYgdHlwZSB1c2VkIGluIGEgbWl4ZWQgY29udGVudCBtb2RlbC4KLSAqIDxwPgotICogRm9yIGEgbWl4ZWQgY29udGVudCBtb2RlbCwgdGhlIGNvbnRlbnQgc3BlYyB3aWxsIGJlIG1hZGUgdXAgb2YKLSAqIGxlYWYgYW5kIGNob2ljZSBjb250ZW50IHNwZWMgbm9kZXMsIHdpdGggYW4gb3B0aW9uYWwgInplcm8gb3IgbW9yZSIKLSAqIG5vZGUuICBGb3IgZXhhbXBsZSwgdGhlIG1peGVkIGNvbnRlbnQgZGVjbGFyYXRpb24gIigjUENEQVRBKSIgd291bGQKLSAqIGNvbnRhaW4gYSBzaW5nbGUgbGVhZiBub2RlIHdpdGggYSBub2RlIHZhbHVlIG9mIC0xLiAgQSBtaXhlZCBjb250ZW50Ci0gKiBkZWNsYXJhdGlvbiBvZiAiKCNQQ0RBVEF8Zm9vKSoiIHdvdWxkIGhhdmUgYSBjb250ZW50IHNwZWMgY29uc2lzdGluZwotICogb2YgdHdvIGxlYWYgbm9kZXMsIGZvciB0aGUgIiNQQ0RBVEEiIGFuZCAiZm9vIiBjaG9pY2VzLCBhIGNob2ljZSBub2RlCi0gKiB3aXRoIHRoZSAidmFsdWUiIHNldCB0byB0aGUgaW5kZXggb2YgdGhlICIjUENEQVRBIiBsZWFmIG5vZGUgYW5kIHRoZQotICogIm90aGVyVmFsdWUiIHNldCB0byB0aGUgaW5kZXggb2YgdGhlICJmb28iIGxlYWYgbm9kZSwgYW5kIGEgInplcm8gb3IKLSAqIG1vcmUiIG5vZGUgd2l0aCB0aGUgInZhbHVlIiBzZXQgdG8gdGhlIGluZGV4IG9mIHRoZSBjaG9pY2Ugbm9kZS4gIElmCi0gKiB0aGUgY29udGVudCBtb2RlbCBoYXMgbW9yZSBjaG9pY2VzLCBmb3IgZXhhbXBsZSAiKCNQQ0RBVEF8YXxiKSoiLCB0aGVuCi0gKiB0aGVyZSB3aWxsIGJlIG1vcmUgY29ycmVzcG9uZGluZyBjaG9pY2UgYW5kIGxlYWYgbm9kZXMsIHRoZSBjaG9pY2UKLSAqIG5vZGVzIHdpbGwgYmUgY2hhaW5lZCB0b2dldGhlciB0aHJvdWdoIHRoZSAidmFsdWUiIGZpZWxkIHdpdGggZWFjaAotICogbGVhZiBub2RlIHJlZmVyZW5jZWQgYnkgdGhlICJvdGhlclZhbHVlIiBmaWVsZC4KLSAqIDxwPgotICogRm9yIGVsZW1lbnQgY29udGVudCBtb2RlbHMsIHRoZXJlIGFyZSBzZXF1ZW5jZSBub2RlcyBhbmQgYWxzbyAiemVybyBvcgotICogb25lIiBhbmQgIm9uZSBvciBtb3JlIiBub2Rlcy4gIFRoZSBsZWFmIG5vZGVzIHdvdWxkIGFsd2F5cyBoYXZlIGEgdmFsaWQKLSAqIHN0cmluZyBwb29sIGluZGV4LCBhcyB0aGUgIiNQQ0RBVEEiIGxlYWYgaXMgbm90IHVzZWQgaW4gdGhlIGRlY2xhcmF0aW9ucwotICogZm9yIGVsZW1lbnQgY29udGVudCBtb2RlbHMuCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqLwotcHVibGljIGNsYXNzIFhNTENvbnRlbnRTcGVjIHsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RhbnRzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIE5hbWUgb3IgI1BDREFUQS4gTGVhZiBub2RlcyB0aGF0IHJlcHJlc2VudCBwYXJzZWQgY2hhcmFjdGVyCi0gICAgICogZGF0YSAoI1BDREFUQSkgaGF2ZSB2YWx1ZXMgb2YgLTEuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBDT05URU5UU1BFQ05PREVfTEVBRiA9IDA7Ci0KLSAgICAvKiogUmVwcmVzZW50cyBhIHplcm8gb3Igb25lIG9jY3VyZW5jZSBjb3VudCwgJz8nLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgQ09OVEVOVFNQRUNOT0RFX1pFUk9fT1JfT05FID0gMTsKLQotICAgIC8qKiBSZXByZXNlbnRzIGEgemVybyBvciBtb3JlIG9jY3VyZW5jZSBjb3VudCwgJyonLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgQ09OVEVOVFNQRUNOT0RFX1pFUk9fT1JfTU9SRSA9IDI7Ci0KLSAgICAvKiogUmVwcmVzZW50cyBhIG9uZSBvciBtb3JlIG9jY3VyZW5jZSBjb3VudCwgJysnLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgQ09OVEVOVFNQRUNOT0RFX09ORV9PUl9NT1JFID0gMzsKLQotICAgIC8qKiBSZXByZXNlbnRzIGNob2ljZSwgJ3wnLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgQ09OVEVOVFNQRUNOT0RFX0NIT0lDRSA9IDQ7Ci0KLSAgICAvKiogUmVwcmVzZW50cyBzZXF1ZW5jZSwgJywnLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgQ09OVEVOVFNQRUNOT0RFX1NFUSA9IDU7Ci0KLSAgICAvKioKLSAgICAgKiBSZXByZXNlbnRzIGFueSBuYW1lc3BhY2Ugc3BlY2lmaWVkIG5hbWVzcGFjZS4gV2hlbiB0aGUgZWxlbWVudAotICAgICAqIGZvdW5kIGluIHRoZSBkb2N1bWVudCBtdXN0IGJlbG9uZyB0byBhIHNwZWNpZmljIG5hbWVzcGFjZSwKLSAgICAgKiA8Y29kZT5vdGhlclZhbHVlPC9jb2RlPiB3aWxsIGNvbnRhaW4gdGhlIG5hbWUgb2YgdGhlIG5hbWVzcGFjZS4KLSAgICAgKiBJZiA8Y29kZT5vdGhlclZhbHVlPC9jb2RlPiBpcyA8Y29kZT4tMTwvY29kZT4gdGhlbiB0aGUgZWxlbWVudAotICAgICAqIGNhbiBiZSBmcm9tIGFueSBuYW1lc3BhY2UuCi0gICAgICogPHA+Ci0gICAgICogTGlzdHMgb2YgdmFsaWQgbmFtZXNwYWNlcyBhcmUgY3JlYXRlZCBmcm9tIGNob2ljZSBjb250ZW50IHNwZWMKLSAgICAgKiBub2RlcyB0aGF0IGhhdmUgYW55IGNvbnRlbnQgc3BlYyBub2RlcyBhcyBjaGlsZHJlbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IENPTlRFTlRTUEVDTk9ERV9BTlkgPSA2OwotCi0gICAgLyoqCi0gICAgICogUmVwcmVzZW50cyBhbnkgb3RoZXIgbmFtZXNwYWNlIChYTUwgU2NoZW1hOiAjI290aGVyKS4KLSAgICAgKiA8cD4KLSAgICAgKiBXaGVuIHRoZSBjb250ZW50IHNwZWMgbm9kZSB0eXBlIGlzIHNldCB0byBDT05URU5UU1BFQ05PREVfQU5ZX09USEVSLAotICAgICAqIDxjb2RlPnZhbHVlPC9jb2RlPiB3aWxsIGNvbnRhaW4gdGhlIG5hbWVzcGFjZSB0aGF0IDxlbT5jYW5ub3Q8L2VtPgotICAgICAqIG9jY3VyLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgQ09OVEVOVFNQRUNOT0RFX0FOWV9PVEhFUiA9IDc7Ci0KLSAgICAvKiogUmVwcmVzZW50cyBhbnkgbG9jYWwgZWxlbWVudCAoWE1MIFNjaGVtYTogIyNsb2NhbCkuICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBDT05URU5UU1BFQ05PREVfQU5ZX0xPQ0FMID0gODsKLQotICAgIC8qKiBwcmNlc3NDb250ZW50IGlzICdsYXgnICoqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgQ09OVEVOVFNQRUNOT0RFX0FOWV9MQVggPSAyMjsKLQotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgQ09OVEVOVFNQRUNOT0RFX0FOWV9PVEhFUl9MQVggPSAyMzsKLQotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgQ09OVEVOVFNQRUNOT0RFX0FOWV9MT0NBTF9MQVggPSAyNDsKLQotICAgIC8qKiBwcm9jZXNzQ29udGVudCBpcyAnc2tpcCcgKiovCi0KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IENPTlRFTlRTUEVDTk9ERV9BTllfU0tJUCA9IDM4OwotCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBDT05URU5UU1BFQ05PREVfQU5ZX09USEVSX1NLSVAgPSAzOTsKLQotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgQ09OVEVOVFNQRUNOT0RFX0FOWV9MT0NBTF9TS0lQID0gNDA7Ci0gICAgLy8KLSAgICAvLyBEYXRhCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFRoZSBjb250ZW50IHNwZWMgbm9kZSB0eXBlLgotICAgICAqCi0gICAgICogQHNlZSAjQ09OVEVOVFNQRUNOT0RFX0xFQUYKLSAgICAgKiBAc2VlICNDT05URU5UU1BFQ05PREVfWkVST19PUl9PTkUKLSAgICAgKiBAc2VlICNDT05URU5UU1BFQ05PREVfWkVST19PUl9NT1JFCi0gICAgICogQHNlZSAjQ09OVEVOVFNQRUNOT0RFX09ORV9PUl9NT1JFCi0gICAgICogQHNlZSAjQ09OVEVOVFNQRUNOT0RFX0NIT0lDRQotICAgICAqIEBzZWUgI0NPTlRFTlRTUEVDTk9ERV9TRVEKLSAgICAgKi8KLSAgICBwdWJsaWMgc2hvcnQgdHlwZTsKLQotICAgIC8qKgotICAgICAqIFRoZSAibGVmdCBoYW5kIiB2YWx1ZSBvYmplY3Qgb2YgdGhlIGNvbnRlbnQgc3BlYyBub2RlLgotICAgICAqIGxlYWYgbmFtZS5sb2NhbHBhcnQsIHNpbmdsZSBjaGlsZCBmb3IgdW5hcnkgb3BzLCBsZWZ0IGNoaWxkIGZvciBiaW5hcnkgb3BzLgotICAgICAqLwotICAgIHB1YmxpYyBPYmplY3QgdmFsdWU7Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgInJpZ2h0IGhhbmQiIHZhbHVlIG9mIHRoZSBjb250ZW50IHNwZWMgbm9kZS4KLSAgICAgKiAgbGVhZiBuYW1lLnVyaSwgcmlnaHQgY2hpbGQgZm9yIGJpbmFyeSBvcHMKLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0IG90aGVyVmFsdWU7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0cnVjdG9ycwotICAgIC8vCi0KLSAgICAvKiogRGVmYXVsdCBjb25zdHJ1Y3Rvci4gKi8KLSAgICBwdWJsaWMgWE1MQ29udGVudFNwZWMoKSB7Ci0gICAgICAgIGNsZWFyKCk7Ci0gICAgfQotCi0gICAgLyoqIENvbnN0cnVjdHMgYSBjb250ZW50IHNwZWMgd2l0aCB0aGUgc3BlY2lmaWVkIHZhbHVlcy4gKi8KLSAgICBwdWJsaWMgWE1MQ29udGVudFNwZWMoc2hvcnQgdHlwZSwgT2JqZWN0IHZhbHVlLCBPYmplY3Qgb3RoZXJWYWx1ZSkgewotICAgICAgICBzZXRWYWx1ZXModHlwZSwgdmFsdWUsIG90aGVyVmFsdWUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHMgYSBjb250ZW50IHNwZWMgZnJvbSB0aGUgdmFsdWVzIGluIHRoZSBzcGVjaWZpZWQgY29udGVudCBzcGVjLgotICAgICAqLwotICAgIHB1YmxpYyBYTUxDb250ZW50U3BlYyhYTUxDb250ZW50U3BlYyBjb250ZW50U3BlYykgewotICAgICAgICBzZXRWYWx1ZXMoY29udGVudFNwZWMpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHMgYSBjb250ZW50IHNwZWMgZnJvbSB0aGUgdmFsdWVzIHNwZWNpZmllZCBieSB0aGUgZ2l2ZW4KLSAgICAgKiBjb250ZW50IHNwZWMgcHJvdmlkZXIgYW5kIGlkZW50aWZpZXIuCi0gICAgICovCi0gICAgcHVibGljIFhNTENvbnRlbnRTcGVjKFhNTENvbnRlbnRTcGVjLlByb3ZpZGVyIHByb3ZpZGVyLAotICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgY29udGVudFNwZWNJbmRleCkgewotICAgICAgICBzZXRWYWx1ZXMocHJvdmlkZXIsIGNvbnRlbnRTcGVjSW5kZXgpOwotICAgIH0KLQotICAgIC8vCi0gICAgLy8gUHVibGljIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqIENsZWFycyB0aGUgdmFsdWVzLiAqLwotICAgIHB1YmxpYyB2b2lkIGNsZWFyKCkgewotICAgICAgICB0eXBlID0gLTE7Ci0gICAgICAgIHZhbHVlID0gbnVsbDsKLSAgICAgICAgb3RoZXJWYWx1ZSA9IG51bGw7Ci0gICAgfQotCi0gICAgLyoqIFNldHMgdGhlIHZhbHVlcy4gKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRWYWx1ZXMoc2hvcnQgdHlwZSwgT2JqZWN0IHZhbHVlLCBPYmplY3Qgb3RoZXJWYWx1ZSkgewotICAgICAgICB0aGlzLnR5cGUgPSB0eXBlOwotICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7Ci0gICAgICAgIHRoaXMub3RoZXJWYWx1ZSA9IG90aGVyVmFsdWU7Ci0gICAgfQotCi0gICAgLyoqIFNldHMgdGhlIHZhbHVlcyBvZiB0aGUgc3BlY2lmaWVkIGNvbnRlbnQgc3BlYy4gKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRWYWx1ZXMoWE1MQ29udGVudFNwZWMgY29udGVudFNwZWMpIHsKLSAgICAgICAgdHlwZSA9IGNvbnRlbnRTcGVjLnR5cGU7Ci0gICAgICAgIHZhbHVlID0gY29udGVudFNwZWMudmFsdWU7Ci0gICAgICAgIG90aGVyVmFsdWUgPSBjb250ZW50U3BlYy5vdGhlclZhbHVlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIHZhbHVlcyBmcm9tIHRoZSB2YWx1ZXMgc3BlY2lmaWVkIGJ5IHRoZSBnaXZlbiBjb250ZW50IHNwZWMKLSAgICAgKiBwcm92aWRlciBhbmQgaWRlbnRpZmllci4gSWYgdGhlIHNwZWNpZmllZCBjb250ZW50IHNwZWMgY2Fubm90IGJlCi0gICAgICogcHJvdmlkZWQsIHRoZSB2YWx1ZXMgb2YgdGhpcyBjb250ZW50IHNwZWMgYXJlIGNsZWFyZWQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0VmFsdWVzKFhNTENvbnRlbnRTcGVjLlByb3ZpZGVyIHByb3ZpZGVyLAotICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgY29udGVudFNwZWNJbmRleCkgewotICAgICAgICBpZiAoIXByb3ZpZGVyLmdldENvbnRlbnRTcGVjKGNvbnRlbnRTcGVjSW5kZXgsIHRoaXMpKSB7Ci0gICAgICAgICAgICBjbGVhcigpOwotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICAvLwotICAgIC8vIE9iamVjdCBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKiBSZXR1cm5zIGEgaGFzaCBjb2RlIGZvciB0aGlzIG5vZGUuICovCi0gICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKLSAgICAgICAgcmV0dXJuIHR5cGUgPDwgMTYgfAotICAgICAgICAgICAgICAgdmFsdWUuaGFzaENvZGUoKSA8PCA4IHwKLSAgICAgICAgICAgICAgIG90aGVyVmFsdWUuaGFzaENvZGUoKTsKLSAgICB9Ci0KLSAgICAvKiogUmV0dXJucyB0cnVlIGlmIHRoZSB0d28gb2JqZWN0cyBhcmUgZXF1YWwuICovCi0gICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmplY3QpIHsKLSAgICAgICAgaWYgKG9iamVjdCAhPSBudWxsICYmIG9iamVjdCBpbnN0YW5jZW9mIFhNTENvbnRlbnRTcGVjKSB7Ci0gICAgICAgICAgICBYTUxDb250ZW50U3BlYyBjb250ZW50U3BlYyA9IChYTUxDb250ZW50U3BlYylvYmplY3Q7Ci0gICAgICAgICAgICByZXR1cm4gdHlwZSA9PSBjb250ZW50U3BlYy50eXBlICYmCi0gICAgICAgICAgICAgICAgICAgdmFsdWUgPT0gY29udGVudFNwZWMudmFsdWUgJiYKLSAgICAgICAgICAgICAgICAgICBvdGhlclZhbHVlID09IGNvbnRlbnRTcGVjLm90aGVyVmFsdWU7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotCi0gICAgLy8KLSAgICAvLyBJbnRlcmZhY2VzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFByb3ZpZGVzIGEgbWVhbnMgZm9yIHdhbGtpbmcgdGhlIHN0cnVjdHVyZSBidWlsdCBvdXQgb2YKLSAgICAgKiBjb250ZW50IHNwZWMgIm5vZGVzIi4gVGhlIHVzZXIgb2YgdGhpcyBwcm92aWRlciBpbnRlcmZhY2UgaXMKLSAgICAgKiByZXNwb25zaWJsZSBmb3Iga25vd2luZyB3aGF0IHRoZSBjb250ZW50IHNwZWMgbm9kZSB2YWx1ZXMKLSAgICAgKiAibWVhbiIuIElmIHRob3NlIHZhbHVlcyByZWZlciB0byBjb250ZW50IHNwZWMgaWRlbnRpZmllcnMsCi0gICAgICogdGhlbiB0aGUgdXNlciBjYW4gY2FsbCBiYWNrIGludG8gdGhlIHByb3ZpZGVyIHRvIGdldCB0aGUKLSAgICAgKiBuZXh0IGNvbnRlbnQgc3BlYyBub2RlIGluIHRoZSBzdHJ1Y3R1cmUuCi0gICAgICoKLSAgICAgKiBAeGVyY2VzLmludGVybmFsCi0gICAgICovCi0gICAgcHVibGljIGludGVyZmFjZSBQcm92aWRlciB7Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gWE1MQ29udGVudFNwZWMuUHJvdmlkZXIgbWV0aG9kcwotICAgICAgICAvLwotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBGaWxscyBpbiB0aGUgcHJvdmlkZWQgY29udGVudCBzcGVjIHN0cnVjdHVyZSB3aXRoIGNvbnRlbnQgc3BlYwotICAgICAgICAgKiBpbmZvcm1hdGlvbiBmb3IgYSB1bmlxdWUgaWRlbnRpZmllci4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIGNvbnRlbnRTcGVjSW5kZXggVGhlIGNvbnRlbnQgc3BlYyBpZGVudGlmaWVyLiBBbGwgY29udGVudAotICAgICAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBzcGVjICJub2RlcyIgaGF2ZSBhIHVuaXF1ZSBpZGVudGlmaWVyLgotICAgICAgICAgKiBAcGFyYW0gY29udGVudFNwZWMgICAgICBUaGUgY29udGVudCBzcGVjIHN0cnVjdCB0byBmaWxsIGluIHdpdGgKLSAgICAgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgdGhlIGluZm9ybWF0aW9uLgotICAgICAgICAgKgotICAgICAgICAgKiBAcmV0dXJuIFJldHVybnMgdHJ1ZSBpZiB0aGUgY29udGVudFNwZWNJbmRleCB3YXMgZm91bmQuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgYm9vbGVhbiBnZXRDb250ZW50U3BlYyhpbnQgY29udGVudFNwZWNJbmRleCwgWE1MQ29udGVudFNwZWMgY29udGVudFNwZWMpOwotCi0gICAgfSAvLyBpbnRlcmZhY2UgUHJvdmlkZXIKLQotfSAvLyBjbGFzcyBYTUxDb250ZW50U3BlYwpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdGQvWE1MRFRERGVzY3JpcHRpb24uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHRkL1hNTERURERlc2NyaXB0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGI5ZTQ4ZTkuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdGQvWE1MRFRERGVzY3JpcHRpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIyOSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAwLTIwMDIgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYZXJjZXMiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIEludGVybmF0aW9uYWwKLSAqIEJ1c2luZXNzIE1hY2hpbmVzLCBJbmMuLCBodHRwOi8vd3d3LmFwYWNoZS5vcmcuICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHRkOwotCi1pbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuZ3JhbW1hcnMuWE1MR3JhbW1hckRlc2NyaXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTFJlc291cmNlSWRlbnRpZmllcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MSW5wdXRTb3VyY2U7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlhNTFJlc291cmNlSWRlbnRpZmllckltcGw7Ci0KLS8qKgotICogQWxsIGluZm9ybWF0aW9uIHNwZWNpZmljIHRvIERURCBncmFtbWFycy4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBOZWlsIEdyYWhhbSwgSUJNCi0gKiBAdmVyc2lvbiAkSWQ6IFhNTERURERlc2NyaXB0aW9uLmphdmEsdiAxLjQgMjAxMC8wOC8xMSAwNzoxODozOCBqb2VodyBFeHAgJAotICovCi1wdWJsaWMgY2xhc3MgWE1MRFRERGVzY3JpcHRpb24gZXh0ZW5kcyBYTUxSZXNvdXJjZUlkZW50aWZpZXJJbXBsCi0gICAgICAgIGltcGxlbWVudHMgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuZ3JhbW1hcnMuWE1MRFRERGVzY3JpcHRpb24gewotCi0gICAgLy8gRGF0YQotCi0gICAgLy8gcGllY2VzIG9mIGluZm9ybWF0aW9uIG5lZWRlZCB0byBtYWtlIHRoaXMgdXNhYmxlIGFzIGEgR3JhbW1hciBrZXkKLSAgICAvLyBpZiB3ZSBrbm93IHRoZSByb290IG9mIHRoaXMgZ3JhbW1hciwgaGVyZSdzIGl0cyBuYW1lOgotICAgIHByb3RlY3RlZCBTdHJpbmcgZlJvb3ROYW1lID0gbnVsbDsKLQotICAgIC8vIGlmIHdlIGRvbid0IGtub3cgdGhlIHJvb3QgbmFtZSwgdGhpcyBzdG9yZXMgYWxsIGVsZW1lbnRzIHRoYXQKLSAgICAvLyBjb3VsZCBzZXJ2ZTsgZlBvc3NpYmxlUm9vdHMgYW5kIGZSb290TmFtZSBjYW5ub3QgYm90aCBiZSBub24tbnVsbAotICAgIHByb3RlY3RlZCBBcnJheUxpc3QgZlBvc3NpYmxlUm9vdHMgPSBudWxsOwotCi0gICAgLy8gQ29uc3RydWN0b3JzOgotICAgIHB1YmxpYyBYTUxEVEREZXNjcmlwdGlvbihYTUxSZXNvdXJjZUlkZW50aWZpZXIgaWQsIFN0cmluZyByb290TmFtZSkgewotICAgICAgICB0aGlzLnNldFZhbHVlcyhpZC5nZXRQdWJsaWNJZCgpLCBpZC5nZXRMaXRlcmFsU3lzdGVtSWQoKSwKLSAgICAgICAgICAgICAgICBpZC5nZXRCYXNlU3lzdGVtSWQoKSwgaWQuZ2V0RXhwYW5kZWRTeXN0ZW1JZCgpKTsKLSAgICAgICAgdGhpcy5mUm9vdE5hbWUgPSByb290TmFtZTsKLSAgICAgICAgdGhpcy5mUG9zc2libGVSb290cyA9IG51bGw7Ci0gICAgfSAvLyBpbml0KFhNTFJlc291cmNlSWRlbnRpZmllciwgU3RyaW5nKQotCi0gICAgcHVibGljIFhNTERURERlc2NyaXB0aW9uKFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIGxpdGVyYWxJZCwKLSAgICAgICAgICAgICAgICBTdHJpbmcgYmFzZUlkLCBTdHJpbmcgZXhwYW5kZWRJZCwgU3RyaW5nIHJvb3ROYW1lKSB7Ci0gICAgICAgIHRoaXMuc2V0VmFsdWVzKHB1YmxpY0lkLCBsaXRlcmFsSWQsIGJhc2VJZCwgZXhwYW5kZWRJZCk7Ci0gICAgICAgIHRoaXMuZlJvb3ROYW1lID0gcm9vdE5hbWU7Ci0gICAgICAgIHRoaXMuZlBvc3NpYmxlUm9vdHMgPSBudWxsOwotICAgIH0gLy8gaW5pdChTdHJpbmcsIFN0cmluZywgU3RyaW5nLCBTdHJpbmcsIFN0cmluZykKLQotICAgIHB1YmxpYyBYTUxEVEREZXNjcmlwdGlvbihYTUxJbnB1dFNvdXJjZSBzb3VyY2UpIHsKLSAgICAgICAgdGhpcy5zZXRWYWx1ZXMoc291cmNlLmdldFB1YmxpY0lkKCksIG51bGwsCi0gICAgICAgICAgICAgICAgc291cmNlLmdldEJhc2VTeXN0ZW1JZCgpLCBzb3VyY2UuZ2V0U3lzdGVtSWQoKSk7Ci0gICAgICAgIHRoaXMuZlJvb3ROYW1lID0gbnVsbDsKLSAgICAgICAgdGhpcy5mUG9zc2libGVSb290cyA9IG51bGw7Ci0gICAgfSAvLyBpbml0KFhNTElucHV0U291cmNlKQotCi0gICAgLy8gWE1MR3JhbW1hckRlc2NyaXB0aW9uIG1ldGhvZHMKLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0R3JhbW1hclR5cGUgKCkgewotICAgICAgICByZXR1cm4gWE1MR3JhbW1hckRlc2NyaXB0aW9uLlhNTF9EVEQ7Ci0gICAgfSAvLyBnZXRHcmFtbWFyVHlwZSgpOiAgU3RyaW5nCi0KLSAgICAvKioKLSAgICAgKiBAcmV0dXJuIHRoZSByb290IG5hbWUgb2YgdGhpcyBEVEQgb3IgbnVsbCBpZiByb290IG5hbWUgaXMgdW5rbm93bgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Um9vdE5hbWUoKSB7Ci0gICAgICAgIHJldHVybiBmUm9vdE5hbWU7Ci0gICAgfSAvLyBnZXRSb290TmFtZSgpOiAgU3RyaW5nCi0KLSAgICAvKiogU2V0IHRoZSByb290IG5hbWUgKiovCi0gICAgcHVibGljIHZvaWQgc2V0Um9vdE5hbWUoU3RyaW5nIHJvb3ROYW1lKSB7Ci0gICAgICAgIGZSb290TmFtZSA9IHJvb3ROYW1lOwotICAgICAgICBmUG9zc2libGVSb290cyA9IG51bGw7Ci0gICAgfQotCi0gICAgLyoqIFNldCBwb3NzaWJsZSByb290cyAqKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRQb3NzaWJsZVJvb3RzKEFycmF5TGlzdCBwb3NzaWJsZVJvb3RzKSB7Ci0gICAgICAgIGZQb3NzaWJsZVJvb3RzID0gcG9zc2libGVSb290czsKLSAgICB9Ci0KLSAgICAvKiogU2V0IHBvc3NpYmxlIHJvb3RzICoqLwotICAgIHB1YmxpYyB2b2lkIHNldFBvc3NpYmxlUm9vdHMoVmVjdG9yIHBvc3NpYmxlUm9vdHMpIHsKLSAgICAgICAgZlBvc3NpYmxlUm9vdHMgPSAocG9zc2libGVSb290cyAhPSBudWxsKSA/IG5ldyBBcnJheUxpc3QocG9zc2libGVSb290cykgOiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbXBhcmVzIHRoaXMgZ3JhbW1hciB3aXRoIHRoZSBnaXZlbiBncmFtbWFyLiBDdXJyZW50bHksIHdlIGNvbXBhcmUKLSAgICAgKiBhcyBmb2xsb3dzOgotICAgICAqIC0gaWYgZ3JhbW1hciB0eXBlIG5vdCBlcXVhbCByZXR1cm4gZmFsc2UgaW1tZWRpYXRlbHkKLSAgICAgKiAtIHRyeSBhbmQgZmluZCBhIGNvbW1vbiByb290IG5hbWU6Ci0gICAgICogICAgLSBpZiBib3RoIGhhdmUgcm9vdHMsIHVzZSB0aGVtCi0gICAgICogICAgLSBlbHNlIGlmIG9uZSBoYXMgYSByb290LCBleGFtaW5lIG90aGVyJ3MgcG9zc2libGUgcm9vdCdzIGZvciBhIG1hdGNoOwotICAgICAqICAgIC0gZWxzZSB0cnkgYWxsIGNvbWJpbmF0aW9ucwotICAgICAqICAtIHRlc3QgZkV4cGFuZGVkU3lzdGVtSWQgYW5kIGZQdWJsaWNJZCBhcyBhYm92ZQotICAgICAqCi0gICAgICogQHBhcmFtIGRlc2MgVGhlIGRlc2NyaXB0aW9uIG9mIHRoZSBncmFtbWFyIHRvIGJlIGNvbXBhcmVkIHdpdGgKLSAgICAgKiBAcmV0dXJuICAgICBUcnVlIGlmIHRoZXkgYXJlIGVxdWFsLCBlbHNlIGZhbHNlCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBkZXNjKSB7Ci0gICAgICAgIGlmICghKGRlc2MgaW5zdGFuY2VvZiBYTUxHcmFtbWFyRGVzY3JpcHRpb24pKSByZXR1cm4gZmFsc2U7Ci0gICAgICAgIGlmICghZ2V0R3JhbW1hclR5cGUoKS5lcXVhbHMoKChYTUxHcmFtbWFyRGVzY3JpcHRpb24pZGVzYykuZ2V0R3JhbW1hclR5cGUoKSkpIHsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotICAgICAgICAvLyBhc3N1bWUgaXQncyBhIERURERlc2NyaXB0aW9uCi0gICAgICAgIFhNTERURERlc2NyaXB0aW9uIGR0ZERlc2MgPSAoWE1MRFRERGVzY3JpcHRpb24pZGVzYzsKLSAgICAgICAgaWYgKGZSb290TmFtZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAoKGR0ZERlc2MuZlJvb3ROYW1lKSAhPSBudWxsICYmICFkdGREZXNjLmZSb290TmFtZS5lcXVhbHMoZlJvb3ROYW1lKSkgewotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKGR0ZERlc2MuZlBvc3NpYmxlUm9vdHMgIT0gbnVsbCAmJiAhZHRkRGVzYy5mUG9zc2libGVSb290cy5jb250YWlucyhmUm9vdE5hbWUpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKGZQb3NzaWJsZVJvb3RzICE9IG51bGwpIHsKLSAgICAgICAgICAgIGlmIChkdGREZXNjLmZSb290TmFtZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgaWYgKCFmUG9zc2libGVSb290cy5jb250YWlucyhkdGREZXNjLmZSb290TmFtZSkpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKGR0ZERlc2MuZlBvc3NpYmxlUm9vdHMgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIGJvb2xlYW4gZm91bmQgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICBmaW5hbCBpbnQgc2l6ZSA9IGZQb3NzaWJsZVJvb3RzLnNpemUoKTsKLSAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNpemU7ICsraSkgewotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcm9vdCA9IChTdHJpbmcpIGZQb3NzaWJsZVJvb3RzLmdldChpKTsKLSAgICAgICAgICAgICAgICAgICAgZm91bmQgPSBkdGREZXNjLmZQb3NzaWJsZVJvb3RzLmNvbnRhaW5zKHJvb3QpOwotICAgICAgICAgICAgICAgICAgICBpZiAoZm91bmQpIGJyZWFrOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpZiAoIWZvdW5kKSByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgLy8gaWYgd2UgZ290IHRoaXMgZmFyIHdlJ3ZlIGdvdCBhIHJvb3QgbWF0Y2guLi4gdHJ5IG90aGVyIHR3byBmaWVsZHMsCi0gICAgICAgIC8vIHNpbmNlIHNvIG1hbnkgZGlmZmVyZW50IERURCdzIGhhdmUgcm9vdHMgaW4gY29tbW9uOgotICAgICAgICBpZiAoZkV4cGFuZGVkU3lzdGVtSWQgIT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKCFmRXhwYW5kZWRTeXN0ZW1JZC5lcXVhbHMoZHRkRGVzYy5mRXhwYW5kZWRTeXN0ZW1JZCkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoZHRkRGVzYy5mRXhwYW5kZWRTeXN0ZW1JZCAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGZQdWJsaWNJZCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAoIWZQdWJsaWNJZC5lcXVhbHMoZHRkRGVzYy5mUHVibGljSWQpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKGR0ZERlc2MuZlB1YmxpY0lkICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBoYXNoIGNvZGUgb2YgdGhpcyBncmFtbWFyCi0gICAgICogQmVjYXVzZSBvdXIgLmVxdWFscyBtZXRob2QgaXMgc28gY29tcGxleCwgd2UganVzdCByZXR1cm4gYSB2ZXJ5Ci0gICAgICogc2ltcGxlIGhhc2ggdGhhdCBtaWdodCBhdm9pZCBjYWxscyB0byB0aGUgZXF1YWxzIG1ldGhvZCBhIGJpdC4uLgotICAgICAqIEByZXR1cm4gVGhlIGhhc2ggY29kZQotICAgICAqLwotICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7Ci0gICAgICAgIGlmIChmRXhwYW5kZWRTeXN0ZW1JZCAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gZkV4cGFuZGVkU3lzdGVtSWQuaGFzaENvZGUoKTsKLSAgICAgICAgfQotICAgICAgICBpZiAoZlB1YmxpY0lkICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBmUHVibGljSWQuaGFzaENvZGUoKTsKLSAgICAgICAgfQotICAgICAgICAvLyBnaXZlIHVwOyBob3BlIC5lcXVhbHMgY2FuIGhhbmRsZSBpdDoKLSAgICAgICAgcmV0dXJuIDA7Ci0gICAgfQotfSAvLyBjbGFzcyBYTUxEVEREZXNjcmlwdGlvbgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdGQvWE1MRFRETG9hZGVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R0ZC9YTUxEVERMb2FkZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZWEzNDM5NC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R0ZC9YTUxEVERMb2FkZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDU1OSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5LTIwMDMgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICogQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhlcmNlcyIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgSW50ZXJuYXRpb25hbAotICogQnVzaW5lc3MgTWFjaGluZXMsIEluYy4sIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdGQ7Ci0KLWltcG9ydCBqYXZhLmlvLkVPRkV4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotaW1wb3J0IGphdmEuaW8uU3RyaW5nUmVhZGVyOwotaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5YTUxEVERTY2FubmVySW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuWE1MRXJyb3JSZXBvcnRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuWE1MRW50aXR5TWFuYWdlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwubXNnLlhNTE1lc3NhZ2VGb3JtYXR0ZXI7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuU3RhdHVzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5TeW1ib2xUYWJsZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuRGVmYXVsdEVycm9ySGFuZGxlcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhOSUV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5ncmFtbWFycy5YTUxHcmFtbWFyUG9vbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5ncmFtbWFycy5YTUxHcmFtbWFyTG9hZGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLmdyYW1tYXJzLkdyYW1tYXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTEVycm9ySGFuZGxlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MRW50aXR5UmVzb2x2ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTElucHV0U291cmNlOwotCi0KLS8qKgotICogVGhlIERURCBsb2FkZXIuIFRoZSBsb2FkZXIga25vd3MgaG93IHRvIGJ1aWxkIGdyYW1tYXJzIGZyb20gWE1MSW5wdXRTb3VyY2VzLgotICogSXQgZXh0ZW5kcyB0aGUgRFREIHByb2Nlc3NvciBpbiBvcmRlciB0byBkbyB0aGlzOyBpdCdzCi0gKiBhIHNlcGFyYXRlIGNsYXNzIGJlY2F1c2UgRFREIHByb2Nlc3NvcnMgZG9uJ3QgbmVlZCB0byBrbm93IGhvdwotICogdG8gdGFsayB0byB0aGUgb3V0c2lkZSB3b3JsZCBpbiB0aGVpciByb2xlIGFzIGluc3RhbmNlLWRvY3VtZW50Ci0gKiBoZWxwZXJzLgotICogPHA+Ci0gKiBUaGlzIGNvbXBvbmVudCByZXF1aXJlcyB0aGUgZm9sbG93aW5nIGZlYXR1cmVzIGFuZCBwcm9wZXJ0aWVzLiAgSXQKLSAqIGtub3cgaG8gdG8gc2V0IHRoZW0gaWYgbm8gb25lIGVsc2UgZG9lczpmcm9tIHRoZQotICogPHVsPgotICogIDxsaT5odHRwOi8veG1sLm9yZy9zYXgvZmVhdHVyZXMvbmFtZXNwYWNlczwvbGk+Ci0gKiAgPGxpPmh0dHA6Ly9hcGFjaGUub3JnL3htbC9wcm9wZXJ0aWVzL2ludGVybmFsL3N5bWJvbC10YWJsZTwvbGk+Ci0gKiAgPGxpPmh0dHA6Ly9hcGFjaGUub3JnL3htbC9wcm9wZXJ0aWVzL2ludGVybmFsL2Vycm9yLXJlcG9ydGVyPC9saT4KLSAqICA8bGk+aHR0cDovL2FwYWNoZS5vcmcveG1sL3Byb3BlcnRpZXMvaW50ZXJuYWwvZ3JhbW1hci1wb29sPC9saT4KLSAqICA8bGk+aHR0cDovL2FwYWNoZS5vcmcveG1sL3Byb3BlcnRpZXMvaW50ZXJuYWwvZGF0YXR5cGUtdmFsaWRhdG9yLWZhY3Rvcnk8L2xpPgotICogPC91bD4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBOZWlsIEdyYWhhbSwgSUJNCi0gKiBAYXV0aG9yIE1pY2hhZWwgR2xhdmFzc2V2aWNoLCBJQk0KLSAqCi0gKiBAdmVyc2lvbiAkSWQ6IFhNTERURExvYWRlci5qYXZhLHYgMS42IDIwMTAtMTEtMDEgMDQ6Mzk6NDIgam9laHcgRXhwICQKLSAqLwotcHVibGljIGNsYXNzIFhNTERURExvYWRlcgotICAgICAgICBleHRlbmRzIFhNTERURFByb2Nlc3NvcgotICAgICAgICBpbXBsZW1lbnRzIFhNTEdyYW1tYXJMb2FkZXIgewotCi0gICAgLy8KLSAgICAvLyBDb25zdGFudHMKLSAgICAvLwotCi0gICAgLy8gZmVhdHVyZSBpZGVudGlmaWVycwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogc3RhbmRhcmQgdXJpIGNvbmZvcm1hbnQgZmVhdHVyZS4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBTVEFOREFSRF9VUklfQ09ORk9STUFOVF9GRUFUVVJFID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5TVEFOREFSRF9VUklfQ09ORk9STUFOVF9GRUFUVVJFOwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogYmFsYW5jZSBzeW50YXggdHJlZXMuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgQkFMQU5DRV9TWU5UQVhfVFJFRVMgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLkJBTEFOQ0VfU1lOVEFYX1RSRUVTOwotCi0gICAgLy8gcmVjb2duaXplZCBmZWF0dXJlczoKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSBMT0FERVJfUkVDT0dOSVpFRF9GRUFUVVJFUyA9IHsKLSAgICAgICAgVkFMSURBVElPTiwKLSAgICAgICAgV0FSTl9PTl9EVVBMSUNBVEVfQVRUREVGLAotICAgICAgICBXQVJOX09OX1VOREVDTEFSRURfRUxFTURFRiwKLSAgICAgICAgTk9USUZZX0NIQVJfUkVGUywKLSAgICAgICAgU1RBTkRBUkRfVVJJX0NPTkZPUk1BTlRfRkVBVFVSRSwKLSAgICAgICAgQkFMQU5DRV9TWU5UQVhfVFJFRVMKLSAgICB9OwotCi0gICAgLy8gcHJvcGVydHkgaWRlbnRpZmllcnMKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBlcnJvciBoYW5kbGVyLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUk9SX0hBTkRMRVIgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5FUlJPUl9IQU5ETEVSX1BST1BFUlRZOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IGVudGl0eSByZXNvbHZlci4gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFTlRJVFlfUkVTT0xWRVIgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5FTlRJVFlfUkVTT0xWRVJfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogbG9jYWxlLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIExPQ0FMRSA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLkxPQ0FMRV9QUk9QRVJUWTsKLQotICAgIC8qKiBSZWNvZ25pemVkIHByb3BlcnRpZXMuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nW10gTE9BREVSX1JFQ09HTklaRURfUFJPUEVSVElFUyA9IHsKLSAgICAgICAgU1lNQk9MX1RBQkxFLAotICAgICAgICBFUlJPUl9SRVBPUlRFUiwKLSAgICAgICAgRVJST1JfSEFORExFUiwKLSAgICAgICAgRU5USVRZX1JFU09MVkVSLAotICAgICAgICBHUkFNTUFSX1BPT0wsCi0gICAgICAgIERURF9WQUxJREFUT1IsCi0gICAgICAgIExPQ0FMRQotICAgIH07Ci0KLSAgICAvLyBlbmZvcmNpbmcgc3RyaWN0IHVyaT8KLSAgICBwcml2YXRlIGJvb2xlYW4gZlN0cmljdFVSSSA9IGZhbHNlOwotCi0gICAgLyoqIENvbnRyb2xzIHdoZXRoZXIgdGhlIERURCBncmFtbWFyIHByb2R1Y2VzIGJhbGFuY2VkIHN5bnRheCB0cmVlcy4gKi8KLSAgICBwcml2YXRlIGJvb2xlYW4gZkJhbGFuY2VTeW50YXhUcmVlcyA9IGZhbHNlOwotCi0gICAgLyoqIEVudGl0eSByZXNvbHZlciAuICovCi0gICAgcHJvdGVjdGVkIFhNTEVudGl0eVJlc29sdmVyIGZFbnRpdHlSZXNvbHZlcjsKLQotICAgIC8vIHRoZSBzY2FubmVyIHdlIHVzZSB0byBhY3R1YWxseSByZWFkIHRoZSBEVEQKLSAgICBwcm90ZWN0ZWQgWE1MRFREU2Nhbm5lckltcGwgZkRURFNjYW5uZXI7Ci0KLSAgICAvLyB0aGUgZW50aXR5IG1hbmFnZXIgdGhlIHNjYW5uZXIgbmVlZHMuCi0gICAgcHJvdGVjdGVkIFhNTEVudGl0eU1hbmFnZXIgZkVudGl0eU1hbmFnZXI7Ci0KLSAgICAvLyB3aGF0J3Mgb3VyIExvY2FsZT8KLSAgICBwcm90ZWN0ZWQgTG9jYWxlIGZMb2NhbGU7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0cnVjdG9ycwotICAgIC8vCi0KLSAgICAvKiogRGVueSBkZWZhdWx0IGNvbnN0cnVjdGlvbjsgd2UgbmVlZCBhIFN5bXRvbFRhYmxlISAqLwotICAgIHB1YmxpYyBYTUxEVERMb2FkZXIoKSB7Ci0gICAgICAgIHRoaXMobmV3IFN5bWJvbFRhYmxlKCkpOwotICAgIH0gLy8gPGluaXQ+KCkKLQotICAgIHB1YmxpYyBYTUxEVERMb2FkZXIoU3ltYm9sVGFibGUgc3ltYm9sVGFibGUpIHsKLSAgICAgICAgdGhpcyhzeW1ib2xUYWJsZSwgbnVsbCk7Ci0gICAgfSAvLyBpbml0KFN5bWJvbFRhYmxlKQotCi0gICAgcHVibGljIFhNTERURExvYWRlcihTeW1ib2xUYWJsZSBzeW1ib2xUYWJsZSwKLSAgICAgICAgICAgICAgICBYTUxHcmFtbWFyUG9vbCBncmFtbWFyUG9vbCkgewotICAgICAgICB0aGlzKHN5bWJvbFRhYmxlLCBncmFtbWFyUG9vbCwgbnVsbCwgbmV3IFhNTEVudGl0eU1hbmFnZXIoKSk7Ci0gICAgfSAvLyBpbml0KFN5bWJvbFRhYmxlLCBYTUxHcmFtbWFyUG9vbCkKLQotICAgIFhNTERURExvYWRlcihTeW1ib2xUYWJsZSBzeW1ib2xUYWJsZSwKLSAgICAgICAgICAgICAgICBYTUxHcmFtbWFyUG9vbCBncmFtbWFyUG9vbCwgWE1MRXJyb3JSZXBvcnRlciBlcnJvclJlcG9ydGVyLAotICAgICAgICAgICAgICAgIFhNTEVudGl0eVJlc29sdmVyIGVudGl0eVJlc29sdmVyKSB7Ci0gICAgICAgIGZTeW1ib2xUYWJsZSA9IHN5bWJvbFRhYmxlOwotICAgICAgICBmR3JhbW1hclBvb2wgPSBncmFtbWFyUG9vbDsKLSAgICAgICAgaWYoZXJyb3JSZXBvcnRlciA9PSBudWxsKSB7Ci0gICAgICAgICAgICBlcnJvclJlcG9ydGVyID0gbmV3IFhNTEVycm9yUmVwb3J0ZXIoKTsKLSAgICAgICAgICAgIGVycm9yUmVwb3J0ZXIuc2V0UHJvcGVydHkoRVJST1JfSEFORExFUiwgbmV3IERlZmF1bHRFcnJvckhhbmRsZXIoKSk7Ci0gICAgICAgIH0KLSAgICAgICAgZkVycm9yUmVwb3J0ZXIgPSBlcnJvclJlcG9ydGVyOwotICAgICAgICAvLyBBZGQgWE1MIG1lc3NhZ2UgZm9ybWF0dGVyIGlmIHRoZXJlIGlzbid0IG9uZS4KLSAgICAgICAgaWYgKGZFcnJvclJlcG9ydGVyLmdldE1lc3NhZ2VGb3JtYXR0ZXIoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOKSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBYTUxNZXNzYWdlRm9ybWF0dGVyIHhtZnQgPSBuZXcgWE1MTWVzc2FnZUZvcm1hdHRlcigpOwotICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucHV0TWVzc2FnZUZvcm1hdHRlcihYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sIHhtZnQpOwotICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucHV0TWVzc2FnZUZvcm1hdHRlcihYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTE5TX0RPTUFJTiwgeG1mdCk7Ci0gICAgICAgIH0KLSAgICAgICAgZkVudGl0eVJlc29sdmVyID0gZW50aXR5UmVzb2x2ZXI7Ci0gICAgICAgIGlmKGZFbnRpdHlSZXNvbHZlciBpbnN0YW5jZW9mIFhNTEVudGl0eU1hbmFnZXIpIHsKLSAgICAgICAgICAgIGZFbnRpdHlNYW5hZ2VyID0gKFhNTEVudGl0eU1hbmFnZXIpZkVudGl0eVJlc29sdmVyOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgZkVudGl0eU1hbmFnZXIgPSBuZXcgWE1MRW50aXR5TWFuYWdlcigpOwotICAgICAgICB9Ci0gICAgICAgIGZFbnRpdHlNYW5hZ2VyLnNldFByb3BlcnR5KENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLkVSUk9SX1JFUE9SVEVSX1BST1BFUlRZLCBlcnJvclJlcG9ydGVyKTsKLSAgICAgICAgZkRURFNjYW5uZXIgPSBjcmVhdGVEVERTY2FubmVyKGZTeW1ib2xUYWJsZSwgZkVycm9yUmVwb3J0ZXIsIGZFbnRpdHlNYW5hZ2VyKTsKLSAgICAgICAgZkRURFNjYW5uZXIuc2V0RFRESGFuZGxlcih0aGlzKTsKLSAgICAgICAgZkRURFNjYW5uZXIuc2V0RFREQ29udGVudE1vZGVsSGFuZGxlcih0aGlzKTsKLSAgICAgICAgcmVzZXQoKTsKLSAgICB9IC8vIGluaXQoU3ltYm9sVGFibGUsIFhNTEdyYW1tYXJQb29sLCBYTUxFcnJvclJlcG9ydGVyLCBYTUxFbnRpdHlSZXNvbHZlcikKLQotICAgIC8vIFhNTEdyYW1tYXJMb2FkZXIgbWV0aG9kcwotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhIGxpc3Qgb2YgZmVhdHVyZSBpZGVudGlmaWVycyB0aGF0IGFyZSByZWNvZ25pemVkIGJ5Ci0gICAgICogdGhpcyBjb21wb25lbnQuIFRoaXMgbWV0aG9kIG1heSByZXR1cm4gbnVsbCBpZiBubyBmZWF0dXJlcwotICAgICAqIGFyZSByZWNvZ25pemVkIGJ5IHRoaXMgY29tcG9uZW50LgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmdbXSBnZXRSZWNvZ25pemVkRmVhdHVyZXMoKSB7Ci0gICAgICAgIHJldHVybiAoU3RyaW5nW10pKExPQURFUl9SRUNPR05JWkVEX0ZFQVRVUkVTLmNsb25lKCkpOwotICAgIH0gLy8gZ2V0UmVjb2duaXplZEZlYXR1cmVzKCk6U3RyaW5nW10KLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIHN0YXRlIG9mIGEgZmVhdHVyZS4gVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBjb21wb25lbnQKLSAgICAgKiBtYW5hZ2VyIGFueSB0aW1lIGFmdGVyIHJlc2V0IHdoZW4gYSBmZWF0dXJlIGNoYW5nZXMgc3RhdGUuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBDb21wb25lbnRzIHNob3VsZCBzaWxlbnRseSBpZ25vcmUgZmVhdHVyZXMKLSAgICAgKiB0aGF0IGRvIG5vdCBhZmZlY3QgdGhlIG9wZXJhdGlvbiBvZiB0aGUgY29tcG9uZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIGZlYXR1cmVJZCBUaGUgZmVhdHVyZSBpZGVudGlmaWVyLgotICAgICAqIEBwYXJhbSBzdGF0ZSAgICAgVGhlIHN0YXRlIG9mIHRoZSBmZWF0dXJlLgotICAgICAqCi0gICAgICogQHRocm93cyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIFRoZSBjb21wb25lbnQgc2hvdWxkIG5vdCB0aHJvdwotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzIGV4Y2VwdGlvbi4KLSAgICAgKiBAdGhyb3dzIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBUaGUgY29tcG9uZW50IHNob3VsZCBub3QgdGhyb3cKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzIGV4Y2VwdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRGZWF0dXJlKFN0cmluZyBmZWF0dXJlSWQsIGJvb2xlYW4gc3RhdGUpCi0gICAgICAgICAgICB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChmZWF0dXJlSWQuZXF1YWxzKFZBTElEQVRJT04pKSB7Ci0gICAgICAgICAgICBmVmFsaWRhdGlvbiA9IHN0YXRlOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKGZlYXR1cmVJZC5lcXVhbHMoV0FSTl9PTl9EVVBMSUNBVEVfQVRUREVGKSkgewotICAgICAgICAgICAgZldhcm5EdXBsaWNhdGVBdHRkZWYgPSBzdGF0ZTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChmZWF0dXJlSWQuZXF1YWxzKFdBUk5fT05fVU5ERUNMQVJFRF9FTEVNREVGKSkgewotICAgICAgICAgICAgZldhcm5PblVuZGVjbGFyZWRFbGVtZGVmID0gc3RhdGU7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoZmVhdHVyZUlkLmVxdWFscyhOT1RJRllfQ0hBUl9SRUZTKSkgewotICAgICAgICAgICAgZkRURFNjYW5uZXIuc2V0RmVhdHVyZShmZWF0dXJlSWQsIHN0YXRlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChmZWF0dXJlSWQuZXF1YWxzKFNUQU5EQVJEX1VSSV9DT05GT1JNQU5UX0ZFQVRVUkUpKSB7Ci0gICAgICAgICAgICBmU3RyaWN0VVJJID0gc3RhdGU7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoZmVhdHVyZUlkLmVxdWFscyhCQUxBTkNFX1NZTlRBWF9UUkVFUykpIHsKLSAgICAgICAgICAgIGZCYWxhbmNlU3ludGF4VHJlZXMgPSBzdGF0ZTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uKFN0YXR1cy5OT1RfUkVDT0dOSVpFRCwgZmVhdHVyZUlkKTsKLSAgICAgICAgfQotICAgIH0gLy8gc2V0RmVhdHVyZShTdHJpbmcsYm9vbGVhbikKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYSBsaXN0IG9mIHByb3BlcnR5IGlkZW50aWZpZXJzIHRoYXQgYXJlIHJlY29nbml6ZWQgYnkKLSAgICAgKiB0aGlzIGNvbXBvbmVudC4gVGhpcyBtZXRob2QgbWF5IHJldHVybiBudWxsIGlmIG5vIHByb3BlcnRpZXMKLSAgICAgKiBhcmUgcmVjb2duaXplZCBieSB0aGlzIGNvbXBvbmVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nW10gZ2V0UmVjb2duaXplZFByb3BlcnRpZXMoKSB7Ci0gICAgICAgIHJldHVybiAoU3RyaW5nW10pKExPQURFUl9SRUNPR05JWkVEX1BST1BFUlRJRVMuY2xvbmUoKSk7Ci0gICAgfSAvLyBnZXRSZWNvZ25pemVkUHJvcGVydGllcygpOlN0cmluZ1tdCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBzdGF0ZSBvZiBhIHByb3BlcnR5LgotICAgICAqCi0gICAgICogQHBhcmFtIHByb3BlcnR5SWQgVGhlIHByb3BlcnR5IGlkZW50aWZpZXIuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gVGhyb3duIG9uIGNvbmZpZ3VyYXRpb24gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIE9iamVjdCBnZXRQcm9wZXJ0eShTdHJpbmcgcHJvcGVydHlJZCkKLSAgICAgICAgICAgIHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKHByb3BlcnR5SWQuZXF1YWxzKFNZTUJPTF9UQUJMRSkpIHsKLSAgICAgICAgICAgIHJldHVybiBmU3ltYm9sVGFibGU7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAocHJvcGVydHlJZC5lcXVhbHMoRVJST1JfUkVQT1JURVIpKSB7Ci0gICAgICAgICAgICByZXR1cm4gZkVycm9yUmVwb3J0ZXI7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAocHJvcGVydHlJZC5lcXVhbHMoRVJST1JfSEFORExFUikpIHsKLSAgICAgICAgICAgIHJldHVybiBmRXJyb3JSZXBvcnRlci5nZXRFcnJvckhhbmRsZXIoKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChwcm9wZXJ0eUlkLmVxdWFscyhFTlRJVFlfUkVTT0xWRVIpKSB7Ci0gICAgICAgICAgICByZXR1cm4gZkVudGl0eVJlc29sdmVyOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKHByb3BlcnR5SWQuZXF1YWxzKExPQ0FMRSkpIHsKLSAgICAgICAgICAgIHJldHVybiBnZXRMb2NhbGUoKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChwcm9wZXJ0eUlkLmVxdWFscyhHUkFNTUFSX1BPT0wpKSB7Ci0gICAgICAgICAgICByZXR1cm4gZkdyYW1tYXJQb29sOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKHByb3BlcnR5SWQuZXF1YWxzKERURF9WQUxJREFUT1IpKSB7Ci0gICAgICAgICAgICByZXR1cm4gZlZhbGlkYXRvcjsKLSAgICAgICAgfQotICAgICAgICB0aHJvdyBuZXcgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbihTdGF0dXMuTk9UX1JFQ09HTklaRUQsIHByb3BlcnR5SWQpOwotICAgIH0gLy8gZ2V0UHJvcGVydHkoU3RyaW5nKTogIE9iamVjdAotCi0gICAgLyoqCi0gICAgICogU2V0cyB0aGUgdmFsdWUgb2YgYSBwcm9wZXJ0eS4gVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBjb21wb25lbnQKLSAgICAgKiBtYW5hZ2VyIGFueSB0aW1lIGFmdGVyIHJlc2V0IHdoZW4gYSBwcm9wZXJ0eSBjaGFuZ2VzIHZhbHVlLgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gQ29tcG9uZW50cyBzaG91bGQgc2lsZW50bHkgaWdub3JlIHByb3BlcnRpZXMKLSAgICAgKiB0aGF0IGRvIG5vdCBhZmZlY3QgdGhlIG9wZXJhdGlvbiBvZiB0aGUgY29tcG9uZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIHByb3BlcnR5SWQgVGhlIHByb3BlcnR5IGlkZW50aWZpZXIuCi0gICAgICogQHBhcmFtIHZhbHVlICAgICAgVGhlIHZhbHVlIG9mIHRoZSBwcm9wZXJ0eS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiBUaGUgY29tcG9uZW50IHNob3VsZCBub3QgdGhyb3cKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcyBleGNlcHRpb24uCi0gICAgICogQHRocm93cyBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gVGhlIGNvbXBvbmVudCBzaG91bGQgbm90IHRocm93Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcyBleGNlcHRpb24uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0UHJvcGVydHkoU3RyaW5nIHByb3BlcnR5SWQsIE9iamVjdCB2YWx1ZSkKLSAgICAgICAgICAgIHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKHByb3BlcnR5SWQuZXF1YWxzKFNZTUJPTF9UQUJMRSkpIHsKLSAgICAgICAgICAgIGZTeW1ib2xUYWJsZSA9IChTeW1ib2xUYWJsZSl2YWx1ZTsKLSAgICAgICAgICAgIGZEVERTY2FubmVyLnNldFByb3BlcnR5KHByb3BlcnR5SWQsIHZhbHVlKTsKLSAgICAgICAgICAgIGZFbnRpdHlNYW5hZ2VyLnNldFByb3BlcnR5KHByb3BlcnR5SWQsIHZhbHVlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmKHByb3BlcnR5SWQuZXF1YWxzKEVSUk9SX1JFUE9SVEVSKSkgewotICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIgPSAoWE1MRXJyb3JSZXBvcnRlcil2YWx1ZTsKLSAgICAgICAgICAgIC8vIEFkZCBYTUwgbWVzc2FnZSBmb3JtYXR0ZXIgaWYgdGhlcmUgaXNuJ3Qgb25lLgotICAgICAgICAgICAgaWYgKGZFcnJvclJlcG9ydGVyLmdldE1lc3NhZ2VGb3JtYXR0ZXIoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOKSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgWE1MTWVzc2FnZUZvcm1hdHRlciB4bWZ0ID0gbmV3IFhNTE1lc3NhZ2VGb3JtYXR0ZXIoKTsKLSAgICAgICAgICAgICAgICBmRXJyb3JSZXBvcnRlci5wdXRNZXNzYWdlRm9ybWF0dGVyKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwgeG1mdCk7Ci0gICAgICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucHV0TWVzc2FnZUZvcm1hdHRlcihYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTE5TX0RPTUFJTiwgeG1mdCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmRFREU2Nhbm5lci5zZXRQcm9wZXJ0eShwcm9wZXJ0eUlkLCB2YWx1ZSk7Ci0gICAgICAgICAgICBmRW50aXR5TWFuYWdlci5zZXRQcm9wZXJ0eShwcm9wZXJ0eUlkLCB2YWx1ZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAocHJvcGVydHlJZC5lcXVhbHMoRVJST1JfSEFORExFUikpIHsKLSAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnNldFByb3BlcnR5KHByb3BlcnR5SWQsIHZhbHVlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChwcm9wZXJ0eUlkLmVxdWFscyhFTlRJVFlfUkVTT0xWRVIpKSB7Ci0gICAgICAgICAgICBmRW50aXR5UmVzb2x2ZXIgPSAoWE1MRW50aXR5UmVzb2x2ZXIpdmFsdWU7Ci0gICAgICAgICAgICBmRW50aXR5TWFuYWdlci5zZXRQcm9wZXJ0eShwcm9wZXJ0eUlkLCB2YWx1ZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAocHJvcGVydHlJZC5lcXVhbHMoTE9DQUxFKSkgewotICAgICAgICAgICAgc2V0TG9jYWxlKChMb2NhbGUpIHZhbHVlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmKHByb3BlcnR5SWQuZXF1YWxzKEdSQU1NQVJfUE9PTCkpIHsKLSAgICAgICAgICAgIGZHcmFtbWFyUG9vbCA9IChYTUxHcmFtbWFyUG9vbCl2YWx1ZTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uKFN0YXR1cy5OT1RfUkVDT0dOSVpFRCwgcHJvcGVydHlJZCk7Ci0gICAgICAgIH0KLSAgICB9IC8vIHNldFByb3BlcnR5KFN0cmluZyxPYmplY3QpCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBzdGF0ZSBvZiBhIGZlYXR1cmUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZmVhdHVyZUlkIFRoZSBmZWF0dXJlIGlkZW50aWZpZXIuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gVGhyb3duIG9uIGNvbmZpZ3VyYXRpb24gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0RmVhdHVyZShTdHJpbmcgZmVhdHVyZUlkKQotICAgICAgICAgICAgdGhyb3dzIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gewotICAgICAgICBpZiAoZmVhdHVyZUlkLmVxdWFscyhWQUxJREFUSU9OKSkgewotICAgICAgICAgICAgcmV0dXJuIGZWYWxpZGF0aW9uOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKGZlYXR1cmVJZC5lcXVhbHMoV0FSTl9PTl9EVVBMSUNBVEVfQVRUREVGKSkgewotICAgICAgICAgICAgcmV0dXJuIGZXYXJuRHVwbGljYXRlQXR0ZGVmOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKGZlYXR1cmVJZC5lcXVhbHMoV0FSTl9PTl9VTkRFQ0xBUkVEX0VMRU1ERUYpKSB7Ci0gICAgICAgICAgICByZXR1cm4gZldhcm5PblVuZGVjbGFyZWRFbGVtZGVmOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKGZlYXR1cmVJZC5lcXVhbHMoTk9USUZZX0NIQVJfUkVGUykpIHsKLSAgICAgICAgICAgIHJldHVybiBmRFREU2Nhbm5lci5nZXRGZWF0dXJlKGZlYXR1cmVJZCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoZmVhdHVyZUlkLmVxdWFscyhTVEFOREFSRF9VUklfQ09ORk9STUFOVF9GRUFUVVJFKSkgewotICAgICAgICAgICAgcmV0dXJuIGZTdHJpY3RVUkk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoZmVhdHVyZUlkLmVxdWFscyhCQUxBTkNFX1NZTlRBWF9UUkVFUykpIHsKLSAgICAgICAgICAgIHJldHVybiBmQmFsYW5jZVN5bnRheFRyZWVzOwotICAgICAgICB9Ci0gICAgICAgIHRocm93IG5ldyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uKFN0YXR1cy5OT1RfUkVDT0dOSVpFRCwgZmVhdHVyZUlkKTsKLSAgICB9IC8vZ2V0RmVhdHVyZShTdHJpbmcpOiAgYm9vbGVhbgotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSBsb2NhbGUgdG8gdXNlIGZvciBtZXNzYWdlcy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBsb2NhbGUgVGhlIGxvY2FsZSBvYmplY3QgdG8gdXNlIGZvciBsb2NhbGl6YXRpb24gb2YgbWVzc2FnZXMuCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIFhOSUV4Y2VwdGlvbiBUaHJvd24gaWYgdGhlIHBhcnNlciBkb2VzIG5vdCBzdXBwb3J0IHRoZQotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIHNwZWNpZmllZCBsb2NhbGUuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0TG9jYWxlKExvY2FsZSBsb2NhbGUpIHsKLSAgICAgICAgZkxvY2FsZSA9IGxvY2FsZTsKLSAgICAgICAgZkVycm9yUmVwb3J0ZXIuc2V0TG9jYWxlKGxvY2FsZSk7Ci0gICAgfSAvLyBzZXRMb2NhbGUoTG9jYWxlKQotCi0gICAgLyoqIFJldHVybiB0aGUgTG9jYWxlIHRoZSBYTUxHcmFtbWFyTG9hZGVyIGlzIHVzaW5nLiAqLwotICAgIHB1YmxpYyBMb2NhbGUgZ2V0TG9jYWxlKCkgewotICAgICAgICByZXR1cm4gZkxvY2FsZTsKLSAgICB9IC8vIGdldExvY2FsZSgpOiAgTG9jYWxlCi0KLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIGVycm9yIGhhbmRsZXIuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZXJyb3JIYW5kbGVyIFRoZSBlcnJvciBoYW5kbGVyLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEVycm9ySGFuZGxlcihYTUxFcnJvckhhbmRsZXIgZXJyb3JIYW5kbGVyKSB7Ci0gICAgICAgIGZFcnJvclJlcG9ydGVyLnNldFByb3BlcnR5KEVSUk9SX0hBTkRMRVIsIGVycm9ySGFuZGxlcik7Ci0gICAgfSAvLyBzZXRFcnJvckhhbmRsZXIoWE1MRXJyb3JIYW5kbGVyKQotCi0gICAgLyoqIFJldHVybnMgdGhlIHJlZ2lzdGVyZWQgZXJyb3IgaGFuZGxlci4gICovCi0gICAgcHVibGljIFhNTEVycm9ySGFuZGxlciBnZXRFcnJvckhhbmRsZXIoKSB7Ci0gICAgICAgIHJldHVybiBmRXJyb3JSZXBvcnRlci5nZXRFcnJvckhhbmRsZXIoKTsKLSAgICB9IC8vIGdldEVycm9ySGFuZGxlcigpOiAgWE1MRXJyb3JIYW5kbGVyCi0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSBlbnRpdHkgcmVzb2x2ZXIuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZW50aXR5UmVzb2x2ZXIgVGhlIG5ldyBlbnRpdHkgcmVzb2x2ZXIuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RW50aXR5UmVzb2x2ZXIoWE1MRW50aXR5UmVzb2x2ZXIgZW50aXR5UmVzb2x2ZXIpIHsKLSAgICAgICAgZkVudGl0eVJlc29sdmVyID0gZW50aXR5UmVzb2x2ZXI7Ci0gICAgICAgIGZFbnRpdHlNYW5hZ2VyLnNldFByb3BlcnR5KEVOVElUWV9SRVNPTFZFUiwgZW50aXR5UmVzb2x2ZXIpOwotICAgIH0gLy8gc2V0RW50aXR5UmVzb2x2ZXIoWE1MRW50aXR5UmVzb2x2ZXIpCi0KLSAgICAvKiogUmV0dXJucyB0aGUgcmVnaXN0ZXJlZCBlbnRpdHkgcmVzb2x2ZXIuICAqLwotICAgIHB1YmxpYyBYTUxFbnRpdHlSZXNvbHZlciBnZXRFbnRpdHlSZXNvbHZlcigpIHsKLSAgICAgICAgcmV0dXJuIGZFbnRpdHlSZXNvbHZlcjsKLSAgICB9IC8vIGdldEVudGl0eVJlc29sdmVyKCk6ICBYTUxFbnRpdHlSZXNvbHZlcgotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhIEdyYW1tYXIgb2JqZWN0IGJ5IHBhcnNpbmcgdGhlIGNvbnRlbnRzIG9mIHRoZQotICAgICAqIGVudGl0eSBwb2ludGVkIHRvIGJ5IHNvdXJjZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzb3VyY2UgICAgICAgIHRoZSBsb2NhdGlvbiBvZiB0aGUgZW50aXR5IHdoaWNoIGZvcm1zCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSBzdGFydGluZyBwb2ludCBvZiB0aGUgZ3JhbW1hciB0byBiZSBjb25zdHJ1Y3RlZC4KLSAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uICAgICAgV2hlbiBhIHByb2JsZW0gaXMgZW5jb3VudGVyZWQgcmVhZGluZyB0aGUgZW50aXR5Ci0gICAgICogICAgICAgICAgWE5JRXhjZXB0aW9uICAgIFdoZW4gYSBjb25kaXRpb24gYXJpc2VzIChzdWNoIGFzIGEgRmF0YWxFcnJvcikgdGhhdCByZXF1aXJlcyBwYXJzaW5nCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZiB0aGUgZW50aXR5IGJlIHRlcm1pbmF0ZWQuCi0gICAgICovCi0gICAgcHVibGljIEdyYW1tYXIgbG9hZEdyYW1tYXIoWE1MSW5wdXRTb3VyY2Ugc291cmNlKQotICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBYTklFeGNlcHRpb24gewotICAgICAgICByZXNldCgpOwotICAgICAgICAvLyBGaXJzdCBjaGFuY2UgY2hlY2tpbmcgc3RyaWN0IFVSSQotICAgICAgICBTdHJpbmcgZWlkID0gWE1MRW50aXR5TWFuYWdlci5leHBhbmRTeXN0ZW1JZChzb3VyY2UuZ2V0U3lzdGVtSWQoKSwgc291cmNlLmdldEJhc2VTeXN0ZW1JZCgpLCBmU3RyaWN0VVJJKTsKLSAgICAgICAgWE1MRFRERGVzY3JpcHRpb24gZGVzYyA9IG5ldyBYTUxEVEREZXNjcmlwdGlvbihzb3VyY2UuZ2V0UHVibGljSWQoKSwgc291cmNlLmdldFN5c3RlbUlkKCksIHNvdXJjZS5nZXRCYXNlU3lzdGVtSWQoKSwgZWlkLCBudWxsKTsKLSAgICAgICAgaWYgKCFmQmFsYW5jZVN5bnRheFRyZWVzKSB7Ci0gICAgICAgICAgICBmRFRER3JhbW1hciA9IG5ldyBEVERHcmFtbWFyKGZTeW1ib2xUYWJsZSwgZGVzYyk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBmRFRER3JhbW1hciA9IG5ldyBCYWxhbmNlZERUREdyYW1tYXIoZlN5bWJvbFRhYmxlLCBkZXNjKTsKLSAgICAgICAgfQotICAgICAgICBmR3JhbW1hckJ1Y2tldCA9IG5ldyBEVERHcmFtbWFyQnVja2V0KCk7Ci0gICAgICAgIGZHcmFtbWFyQnVja2V0LnNldFN0YW5kYWxvbmUoZmFsc2UpOwotICAgICAgICBmR3JhbW1hckJ1Y2tldC5zZXRBY3RpdmVHcmFtbWFyKGZEVERHcmFtbWFyKTsKLSAgICAgICAgLy8gbm8gcmVhc29uIHRvIHVzZSBncmFtbWFyIGJ1Y2tldCdzICJwdXQiIG1ldGhvZC0td2UKLSAgICAgICAgLy8ga25vdyB3aGljaCBncmFtbWFyIGl0IGlzLCBhbmQgd2UgZG9uJ3Qga25vdyB0aGUgcm9vdCBuYW1lIGFueXdheS4uLgotCi0gICAgICAgIC8vIGFjdHVhbGx5IHN0YXJ0IHRoZSBwYXJzaW5nIQotICAgICAgICB0cnkgewotICAgICAgICAgICAgZkRURFNjYW5uZXIuc2V0SW5wdXRTb3VyY2Uoc291cmNlKTsKLSAgICAgICAgICAgIGZEVERTY2FubmVyLnNjYW5EVERFeHRlcm5hbFN1YnNldCh0cnVlKTsKLSAgICAgICAgfSBjYXRjaCAoRU9GRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIC8vIGV4cGVjdGVkIGJlaGF2aW91ci4uLgotICAgICAgICB9Ci0gICAgICAgIGZpbmFsbHkgewotICAgICAgICAgICAgLy8gQ2xvc2UgYWxsIHN0cmVhbXMgb3BlbmVkIGJ5IHRoZSBwYXJzZXIuCi0gICAgICAgICAgICBmRW50aXR5TWFuYWdlci5jbG9zZVJlYWRlcnMoKTsKLSAgICAgICAgfQotICAgICAgICBpZihmRFRER3JhbW1hciAhPSBudWxsICYmIGZHcmFtbWFyUG9vbCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmR3JhbW1hclBvb2wuY2FjaGVHcmFtbWFycyhYTUxEVEREZXNjcmlwdGlvbi5YTUxfRFRELCBuZXcgR3JhbW1hcltdIHtmRFRER3JhbW1hcn0pOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmRFRER3JhbW1hcjsKLSAgICB9IC8vIGxvYWRHcmFtbWFyKFhNTElucHV0U291cmNlKTogIEdyYW1tYXIKLQotICAgIC8qKgotICAgICAqIFBhcnNlIGEgRFREIGludGVybmFsIGFuZC9vciBleHRlcm5hbCBzdWJzZXQgYW5kIGluc2VydCB0aGUgY29udGVudAotICAgICAqIGludG8gdGhlIGV4aXN0aW5nIERURCBncmFtbWFyIG93bmVkIGJ5IHRoZSBnaXZlbiBEVERWYWxpZGF0b3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgbG9hZEdyYW1tYXJXaXRoQ29udGV4dChYTUxEVERWYWxpZGF0b3IgdmFsaWRhdG9yLCBTdHJpbmcgcm9vdE5hbWUsCi0gICAgICAgICAgICBTdHJpbmcgcHVibGljSWQsIFN0cmluZyBzeXN0ZW1JZCwgU3RyaW5nIGJhc2VTeXN0ZW1JZCwgU3RyaW5nIGludGVybmFsU3Vic2V0KQotICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIGZpbmFsIERUREdyYW1tYXJCdWNrZXQgZ3JhbW1hckJ1Y2tldCA9IHZhbGlkYXRvci5nZXRHcmFtbWFyQnVja2V0KCk7Ci0gICAgICAgIGZpbmFsIERUREdyYW1tYXIgYWN0aXZlR3JhbW1hciA9IGdyYW1tYXJCdWNrZXQuZ2V0QWN0aXZlR3JhbW1hcigpOwotICAgICAgICBpZiAoYWN0aXZlR3JhbW1hciAhPSBudWxsICYmICFhY3RpdmVHcmFtbWFyLmlzSW1tdXRhYmxlKCkpIHsKLSAgICAgICAgICAgIGZHcmFtbWFyQnVja2V0ID0gZ3JhbW1hckJ1Y2tldDsKLSAgICAgICAgICAgIGZFbnRpdHlNYW5hZ2VyLnNldFNjYW5uZXJWZXJzaW9uKGdldFNjYW5uZXJWZXJzaW9uKCkpOwotICAgICAgICAgICAgcmVzZXQoKTsKLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgLy8gcHJvY2VzcyBpbnRlcm5hbCBzdWJzZXQKLSAgICAgICAgICAgICAgICBpZiAoaW50ZXJuYWxTdWJzZXQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAvLyBUbyBnZXQgdGhlIERURCBzY2FubmVyIHRvIGVuZCBhdCB0aGUgcmlnaHQgcGxhY2Ugd2UgaGF2ZSB0byBmb29sCi0gICAgICAgICAgICAgICAgICAgIC8vIGl0IGludG8gdGhpbmtpbmcgdGhhdCBpdCByZWFjaGVkIHRoZSBlbmQgb2YgdGhlIGludGVybmFsIHN1YnNldAotICAgICAgICAgICAgICAgICAgICAvLyBpbiBhIHJlYWwgZG9jdW1lbnQuCi0gICAgICAgICAgICAgICAgICAgIFN0cmluZ0J1ZmZlciBidWZmZXIgPSBuZXcgU3RyaW5nQnVmZmVyKGludGVybmFsU3Vic2V0Lmxlbmd0aCgpICsgMik7Ci0gICAgICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoaW50ZXJuYWxTdWJzZXQpLmFwcGVuZCgiXT4iKTsKLSAgICAgICAgICAgICAgICAgICAgWE1MSW5wdXRTb3VyY2UgaXMgPSBuZXcgWE1MSW5wdXRTb3VyY2UobnVsbCwgYmFzZVN5c3RlbUlkLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsIG5ldyBTdHJpbmdSZWFkZXIoYnVmZmVyLnRvU3RyaW5nKCkpLCBudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgZkVudGl0eU1hbmFnZXIuc3RhcnREb2N1bWVudEVudGl0eShpcyk7Ci0gICAgICAgICAgICAgICAgICAgIGZEVERTY2FubmVyLnNjYW5EVERJbnRlcm5hbFN1YnNldCh0cnVlLCBmYWxzZSwgc3lzdGVtSWQgIT0gbnVsbCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIC8vIHByb2Nlc3MgZXh0ZXJuYWwgc3Vic2V0Ci0gICAgICAgICAgICAgICAgaWYgKHN5c3RlbUlkICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgWE1MRFRERGVzY3JpcHRpb24gZGVzYyA9IG5ldyBYTUxEVEREZXNjcmlwdGlvbihwdWJsaWNJZCwgc3lzdGVtSWQsIGJhc2VTeXN0ZW1JZCwgbnVsbCwgcm9vdE5hbWUpOwotICAgICAgICAgICAgICAgICAgICBYTUxJbnB1dFNvdXJjZSBzb3VyY2UgPSBmRW50aXR5TWFuYWdlci5yZXNvbHZlRW50aXR5KGRlc2MpOwotICAgICAgICAgICAgICAgICAgICBmRFREU2Nhbm5lci5zZXRJbnB1dFNvdXJjZShzb3VyY2UpOwotICAgICAgICAgICAgICAgICAgICBmRFREU2Nhbm5lci5zY2FuRFRERXh0ZXJuYWxTdWJzZXQodHJ1ZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2F0Y2ggKEVPRkV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgLy8gZXhwZWN0ZWQgYmVoYXZpb3VyLi4uCi0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmaW5hbGx5IHsKLSAgICAgICAgICAgICAgICAvLyBDbG9zZSBhbGwgc3RyZWFtcyBvcGVuZWQgYnkgdGhlIHBhcnNlci4KLSAgICAgICAgICAgICAgICBmRW50aXR5TWFuYWdlci5jbG9zZVJlYWRlcnMoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0gLy8gbG9hZEdyYW1tYXJXaXRoQ29udGV4dChYTUxEVERWYWxpZGF0b3IsIFN0cmluZywgU3RyaW5nLCBTdHJpbmcsIFN0cmluZywgU3RyaW5nKQotCi0gICAgLy8gcmVzZXQgYWxsIHRoZSBjb21wb25lbnRzIHRoYXQgd2UgcmVseSB1cG9uCi0gICAgcHJvdGVjdGVkIHZvaWQgcmVzZXQoKSB7Ci0gICAgICAgIHN1cGVyLnJlc2V0KCk7Ci0gICAgICAgIGZEVERTY2FubmVyLnJlc2V0KCk7Ci0gICAgICAgIGZFbnRpdHlNYW5hZ2VyLnJlc2V0KCk7Ci0gICAgICAgIGZFcnJvclJlcG9ydGVyLnNldERvY3VtZW50TG9jYXRvcihmRW50aXR5TWFuYWdlci5nZXRFbnRpdHlTY2FubmVyKCkpOwotICAgIH0KLQotICAgIHByb3RlY3RlZCBYTUxEVERTY2FubmVySW1wbCBjcmVhdGVEVERTY2FubmVyKFN5bWJvbFRhYmxlIHN5bWJvbFRhYmxlLAotICAgICAgICAgICAgWE1MRXJyb3JSZXBvcnRlciBlcnJvclJlcG9ydGVyLCBYTUxFbnRpdHlNYW5hZ2VyIGVudGl0eU1hbmFnZXIpIHsKLSAgICAgICAgcmV0dXJuIG5ldyBYTUxEVERTY2FubmVySW1wbChzeW1ib2xUYWJsZSwgZXJyb3JSZXBvcnRlciwgZW50aXR5TWFuYWdlcik7Ci0gICAgfSAvLyBjcmVhdGVEVERTY2FubmVyKFN5bWJvbFRhYmxlLCBYTUxFcnJvclJlcG9ydGVyLCBYTUxFbnRpdHlNYW5hZ2VyKSA6IFhNTERURFNjYW5uZXJJbXBsCi0KLSAgICBwcm90ZWN0ZWQgc2hvcnQgZ2V0U2Nhbm5lclZlcnNpb24oKSB7Ci0gICAgICAgIHJldHVybiBDb25zdGFudHMuWE1MX1ZFUlNJT05fMV8wOwotICAgIH0gLy8gZ2V0U2Nhbm5lclZlcnNpb24oKSA6IHNob3J0Ci0KLX0gLy8gY2xhc3MgWE1MRFRETG9hZGVyCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R0ZC9YTUxEVERQcm9jZXNzb3IuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHRkL1hNTERURFByb2Nlc3Nvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0NWUxYjMxLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHRkL1hNTERURFByb2Nlc3Nvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTc1MiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5LTIwMDIgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICogQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhlcmNlcyIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgSW50ZXJuYXRpb25hbAotICogQnVzaW5lc3MgTWFjaGluZXMsIEluYy4sIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdGQ7Ci0KLWltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwotaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwotaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKLWltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwotaW1wb3J0IGphdmEudXRpbC5NYXA7Ci1pbXBvcnQgamF2YS51dGlsLlN0cmluZ1Rva2VuaXplcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5Db25zdGFudHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLlhNTEVycm9yUmVwb3J0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLm1zZy5YTUxNZXNzYWdlRm9ybWF0dGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5TeW1ib2xUYWJsZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuWE1MQ2hhcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuWE1MU3ltYm9sczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5BdWdtZW50YXRpb25zOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTERURENvbnRlbnRNb2RlbEhhbmRsZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MRFRESGFuZGxlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxMb2NhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTFJlc291cmNlSWRlbnRpZmllcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxTdHJpbmc7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE5JRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLmdyYW1tYXJzLkdyYW1tYXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuZ3JhbW1hcnMuWE1MR3JhbW1hckRlc2NyaXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLmdyYW1tYXJzLlhNTEdyYW1tYXJQb29sOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxDb21wb25lbnQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTENvbXBvbmVudE1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTERURENvbnRlbnRNb2RlbEZpbHRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MRFREQ29udGVudE1vZGVsU291cmNlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxEVERGaWx0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTERURFNvdXJjZTsKLQotLyoqCi0gKiBUaGUgRFREIHByb2Nlc3Nvci4gVGhlIHByb2Nlc3NvciBpbXBsZW1lbnRzIGEgRFRECi0gKiBmaWx0ZXI6IHJlY2VpdmluZyBEVEQgZXZlbnRzIGZyb20gdGhlIERURCBzY2FubmVyOyB2YWxpZGF0aW5nCi0gKiB0aGUgY29udGVudCBhbmQgc3RydWN0dXJlOyBidWlsZGluZyBhIGdyYW1tYXIsIGlmIGFwcGxpY2FibGU7Ci0gKiBhbmQgbm90aWZ5aW5nIHRoZSBEVERIYW5kbGVyIG9mIHRoZSBpbmZvcm1hdGlvbiByZXN1bHRpbmcgZnJvbSB0aGUKLSAqIHByb2Nlc3MuCi0gKiA8cD4KLSAqIFRoaXMgY29tcG9uZW50IHJlcXVpcmVzIHRoZSBmb2xsb3dpbmcgZmVhdHVyZXMgYW5kIHByb3BlcnRpZXMgZnJvbSB0aGUKLSAqIGNvbXBvbmVudCBtYW5hZ2VyIHRoYXQgdXNlcyBpdDoKLSAqIDx1bD4KLSAqICA8bGk+aHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL25hbWVzcGFjZXM8L2xpPgotICogIDxsaT5odHRwOi8vYXBhY2hlLm9yZy94bWwvcHJvcGVydGllcy9pbnRlcm5hbC9zeW1ib2wtdGFibGU8L2xpPgotICogIDxsaT5odHRwOi8vYXBhY2hlLm9yZy94bWwvcHJvcGVydGllcy9pbnRlcm5hbC9lcnJvci1yZXBvcnRlcjwvbGk+Ci0gKiAgPGxpPmh0dHA6Ly9hcGFjaGUub3JnL3htbC9wcm9wZXJ0aWVzL2ludGVybmFsL2dyYW1tYXItcG9vbDwvbGk+Ci0gKiAgPGxpPmh0dHA6Ly9hcGFjaGUub3JnL3htbC9wcm9wZXJ0aWVzL2ludGVybmFsL2RhdGF0eXBlLXZhbGlkYXRvci1mYWN0b3J5PC9saT4KLSAqIDwvdWw+Ci0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgTmVpbCBHcmFoYW0sIElCTQotICoKLSAqIEB2ZXJzaW9uICRJZDogWE1MRFREUHJvY2Vzc29yLmphdmEsdiAxLjUgMjAxMC0xMS0wMSAwNDozOTo0MiBqb2VodyBFeHAgJAotICovCi1wdWJsaWMgY2xhc3MgWE1MRFREUHJvY2Vzc29yCi0gICAgICAgIGltcGxlbWVudHMgWE1MQ29tcG9uZW50LCBYTUxEVERGaWx0ZXIsIFhNTERURENvbnRlbnRNb2RlbEZpbHRlciB7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0YW50cwotICAgIC8vCi0KLSAgICAvKiogVG9wIGxldmVsIHNjb3BlICgtMSkuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFRPUF9MRVZFTF9TQ09QRSA9IC0xOwotCi0gICAgLy8gZmVhdHVyZSBpZGVudGlmaWVycwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogdmFsaWRhdGlvbi4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBWQUxJREFUSU9OID0KLSAgICAgICAgQ29uc3RhbnRzLlNBWF9GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5WQUxJREFUSU9OX0ZFQVRVUkU7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiBub3RpZnkgY2hhcmFjdGVyIHJlZmVyZW5jZXMuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgTk9USUZZX0NIQVJfUkVGUyA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuTk9USUZZX0NIQVJfUkVGU19GRUFUVVJFOwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogd2FybiBvbiBkdXBsaWNhdGUgYXR0ZGVmICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0FSTl9PTl9EVVBMSUNBVEVfQVRUREVGID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArQ29uc3RhbnRzLldBUk5fT05fRFVQTElDQVRFX0FUVERFRl9GRUFUVVJFOwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogd2FybiBvbiB1bmRlY2xhcmVkIGVsZW1lbnQgcmVmZXJlbmNlZCBpbiBjb250ZW50IG1vZGVsLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFdBUk5fT05fVU5ERUNMQVJFRF9FTEVNREVGID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5XQVJOX09OX1VOREVDTEFSRURfRUxFTURFRl9GRUFUVVJFOwotCi0gICAgICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFBBUlNFUl9TRVRUSU5HUyA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuUEFSU0VSX1NFVFRJTkdTOwotCi0gICAgLy8gcHJvcGVydHkgaWRlbnRpZmllcnMKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBzeW1ib2wgdGFibGUuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1lNQk9MX1RBQkxFID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuU1lNQk9MX1RBQkxFX1BST1BFUlRZOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IGVycm9yIHJlcG9ydGVyLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUk9SX1JFUE9SVEVSID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuRVJST1JfUkVQT1JURVJfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogZ3JhbW1hciBwb29sLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIEdSQU1NQVJfUE9PTCA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLlhNTEdSQU1NQVJfUE9PTF9QUk9QRVJUWTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiB2YWxpZGF0b3IgLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIERURF9WQUxJREFUT1IgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5EVERfVkFMSURBVE9SX1BST1BFUlRZOwotCi0gICAgLy8gcmVjb2duaXplZCBmZWF0dXJlcyBhbmQgcHJvcGVydGllcwotCi0gICAgLyoqIFJlY29nbml6ZWQgZmVhdHVyZXMuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nW10gUkVDT0dOSVpFRF9GRUFUVVJFUyA9IHsKLSAgICAgICAgVkFMSURBVElPTiwKLSAgICAgICAgV0FSTl9PTl9EVVBMSUNBVEVfQVRUREVGLAotICAgICAgICBXQVJOX09OX1VOREVDTEFSRURfRUxFTURFRiwKLSAgICAgICAgTk9USUZZX0NIQVJfUkVGUywKLSAgICB9OwotCi0gICAgLyoqIEZlYXR1cmUgZGVmYXVsdHMuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQm9vbGVhbltdIEZFQVRVUkVfREVGQVVMVFMgPSB7Ci0gICAgICAgIG51bGwsCi0gICAgICAgIEJvb2xlYW4uRkFMU0UsCi0gICAgICAgIEJvb2xlYW4uRkFMU0UsCi0gICAgICAgIG51bGwsCi0gICAgfTsKLQotICAgIC8qKiBSZWNvZ25pemVkIHByb3BlcnRpZXMuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nW10gUkVDT0dOSVpFRF9QUk9QRVJUSUVTID0gewotICAgICAgICBTWU1CT0xfVEFCTEUsCi0gICAgICAgIEVSUk9SX1JFUE9SVEVSLAotICAgICAgICBHUkFNTUFSX1BPT0wsCi0gICAgICAgIERURF9WQUxJREFUT1IsCi0gICAgfTsKLQotICAgIC8qKiBQcm9wZXJ0eSBkZWZhdWx0cy4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBPYmplY3RbXSBQUk9QRVJUWV9ERUZBVUxUUyA9IHsKLSAgICAgICAgbnVsbCwKLSAgICAgICAgbnVsbCwKLSAgICAgICAgbnVsbCwKLSAgICAgICAgbnVsbCwKLSAgICB9OwotCi0gICAgLy8gZGVidWdnaW5nCi0KLSAgICAvLwotICAgIC8vIERhdGEKLSAgICAvLwotCi0gICAgLy8gZmVhdHVyZXMKLQotICAgIC8qKiBWYWxpZGF0aW9uLiAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIGZWYWxpZGF0aW9uOwotCi0gICAgLyoqIFZhbGlkYXRpb24gYWdhaW5zdCBvbmx5IERURCAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIGZEVERWYWxpZGF0aW9uOwotCi0gICAgLyoqIHdhcm4gb24gZHVwbGljYXRlIGF0dHJpYnV0ZSBkZWZpbml0aW9uLCB0aGlzIGZlYXR1cmUgd29ya3Mgb25seSB3aGVuIHZhbGlkYXRpb24gaXMgdHJ1ZSAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIGZXYXJuRHVwbGljYXRlQXR0ZGVmOwotCi0gICAgLyoqIHdhcm4gb24gdW5kZWNsYXJlZCBlbGVtZW50IHJlZmVyZW5jZWQgaW4gY29udGVudCBtb2RlbCwgdGhpcyBmZWF0dXJlIG9ubHkgd29ya3Mgd2hlbiB2YWxpYXRpb24gaXMgdHJ1ZSAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIGZXYXJuT25VbmRlY2xhcmVkRWxlbWRlZjsKLQotICAgIC8vIHByb3BlcnRpZXMKLQotICAgIC8qKiBTeW1ib2wgdGFibGUuICovCi0gICAgcHJvdGVjdGVkIFN5bWJvbFRhYmxlIGZTeW1ib2xUYWJsZTsKLQotICAgIC8qKiBFcnJvciByZXBvcnRlci4gKi8KLSAgICBwcm90ZWN0ZWQgWE1MRXJyb3JSZXBvcnRlciBmRXJyb3JSZXBvcnRlcjsKLQotICAgIC8qKiBHcmFtbWFyIGJ1Y2tldC4gKi8KLSAgICBwcm90ZWN0ZWQgRFRER3JhbW1hckJ1Y2tldCBmR3JhbW1hckJ1Y2tldDsKLQotICAgIC8vIHRoZSB2YWxpZGF0b3IgdG8gd2hpY2ggd2UgbG9vayBmb3Igb3VyIGdyYW1tYXIgYnVja2V0ICh0aGUKLSAgICAvLyB2YWxpZGF0b3IgbmVlZHMgdG8gaG9sZCB0aGUgYnVja2V0IHNvIHRoYXQgaXQgY2FuIGluaXRpYWxpemUKLSAgICAvLyB0aGUgZ3JhbW1hciB3aXRoIGRldGFpbHMgbGlrZSB3aGV0aGVyIGl0J3MgZm9yIGEgc3RhbmRhbG9uZSBkb2N1bWVudC4uLgotICAgIHByb3RlY3RlZCBYTUxEVERWYWxpZGF0b3IgZlZhbGlkYXRvcjsKLQotICAgIC8vIHRoZSBncmFtbWFyIHBvb2wgd2UnbGwgdHJ5IHRvIGFkZCB0aGUgZ3JhbW1hciB0bzoKLSAgICBwcm90ZWN0ZWQgWE1MR3JhbW1hclBvb2wgZkdyYW1tYXJQb29sOwotCi0gICAgLy8gd2hhdCdzIG91ciBMb2NhbGU/Ci0gICAgcHJvdGVjdGVkIExvY2FsZSBmTG9jYWxlOwotCi0gICAgLy8gaGFuZGxlcnMKLQotICAgIC8qKiBEVEQgaGFuZGxlci4gKi8KLSAgICBwcm90ZWN0ZWQgWE1MRFRESGFuZGxlciBmRFRESGFuZGxlcjsKLQotICAgIC8qKiBEVEQgc291cmNlLiAqLwotICAgIHByb3RlY3RlZCBYTUxEVERTb3VyY2UgZkRURFNvdXJjZTsKLQotICAgIC8qKiBEVEQgY29udGVudCBtb2RlbCBoYW5kbGVyLiAqLwotICAgIHByb3RlY3RlZCBYTUxEVERDb250ZW50TW9kZWxIYW5kbGVyIGZEVERDb250ZW50TW9kZWxIYW5kbGVyOwotCi0gICAgLyoqIERURCBjb250ZW50IG1vZGVsIHNvdXJjZS4gKi8KLSAgICBwcm90ZWN0ZWQgWE1MRFREQ29udGVudE1vZGVsU291cmNlIGZEVERDb250ZW50TW9kZWxTb3VyY2U7Ci0KLSAgICAvLyBncmFtbWFycwotCi0gICAgLyoqIERURCBHcmFtbWFyLiAqLwotICAgIHByb3RlY3RlZCBEVERHcmFtbWFyIGZEVERHcmFtbWFyOwotCi0gICAgLy8gc3RhdGUKLQotICAgIC8qKiBQZXJmb3JtIHZhbGlkYXRpb24uICovCi0gICAgcHJpdmF0ZSBib29sZWFuIGZQZXJmb3JtVmFsaWRhdGlvbjsKLQotICAgIC8qKiBUcnVlIGlmIGluIGFuIGlnbm9yZSBjb25kaXRpb25hbCBzZWN0aW9uIG9mIHRoZSBEVEQuICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZkluRFRESWdub3JlOwotCi0gICAgLy8gaW5mb3JtYXRpb24gcmVnYXJkaW5nIHRoZSBjdXJyZW50IGVsZW1lbnQKLQotICAgIC8vIHZhbGlkYXRpb24gc3RhdGVzCi0KLSAgICAvKiogTWl4ZWQuICovCi0gICAgcHJpdmF0ZSBib29sZWFuIGZNaXhlZDsKLQotICAgIC8vIHRlbXBvcmFyeSB2YXJpYWJsZXMKLQotICAgIC8qKiBUZW1wb3JhcnkgZW50aXR5IGRlY2xhcmF0aW9uLiAqLwotICAgIHByaXZhdGUgZmluYWwgWE1MRW50aXR5RGVjbCBmRW50aXR5RGVjbCA9IG5ldyBYTUxFbnRpdHlEZWNsKCk7Ci0KLSAgICAvKiogTm90YXRpb24gZGVjbGFyYXRpb24gaGFzaC4gKi8KLSAgICBwcml2YXRlIGZpbmFsIEhhc2hNYXAgZk5EYXRhRGVjbE5vdGF0aW9ucyA9IG5ldyBIYXNoTWFwKCk7Ci0KLSAgICAvKiogRFREIGVsZW1lbnQgZGVjbGFyYXRpb24gbmFtZS4gKi8KLSAgICBwcml2YXRlIFN0cmluZyBmRFRERWxlbWVudERlY2xOYW1lID0gbnVsbDsKLQotICAgIC8qKiBNaXhlZCBlbGVtZW50IHR5cGUgImhhc2giLiAqLwotICAgIHByaXZhdGUgZmluYWwgQXJyYXlMaXN0IGZNaXhlZEVsZW1lbnRUeXBlcyA9IG5ldyBBcnJheUxpc3QoKTsKLQotICAgIC8qKiBFbGVtZW50IGRlY2xhcmF0aW9ucyBpbiBEVEQuICovCi0gICAgcHJpdmF0ZSBmaW5hbCBBcnJheUxpc3QgZkRUREVsZW1lbnREZWNscyA9IG5ldyBBcnJheUxpc3QoKTsKLQotICAgIC8vIHRvIGNoZWNrIGZvciBkdXBsaWNhdGUgSUQgb3IgQU5OT1RBVElPTiBhdHRyaWJ1dGUgZGVjbGFyZSBpbgotICAgIC8vIEFUVExJU1QsIGFuZCBtaXNjIFZDcwotCi0gICAgLyoqIElEIGF0dHJpYnV0ZSBuYW1lcy4gKi8KLSAgICBwcml2YXRlIEhhc2hNYXAgZlRhYmxlT2ZJREF0dHJpYnV0ZU5hbWVzOwotCi0gICAgLyoqIE5PVEFUSU9OIGF0dHJpYnV0ZSBuYW1lcy4gKi8KLSAgICBwcml2YXRlIEhhc2hNYXAgZlRhYmxlT2ZOT1RBVElPTkF0dHJpYnV0ZU5hbWVzOwotCi0gICAgLyoqIE5PVEFUSU9OIGVudW1lcmF0aW9uIHZhbHVlcy4gKi8KLSAgICBwcml2YXRlIEhhc2hNYXAgZk5vdGF0aW9uRW51bVZhbHM7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0cnVjdG9ycwotICAgIC8vCi0KLSAgICAvKiogRGVmYXVsdCBjb25zdHJ1Y3Rvci4gKi8KLSAgICBwdWJsaWMgWE1MRFREUHJvY2Vzc29yKCkgewotCi0gICAgICAgIC8vIGluaXRpYWxpemUgZGF0YQotCi0gICAgfSAvLyA8aW5pdD4oKQotCi0gICAgLy8KLSAgICAvLyBYTUxDb21wb25lbnQgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKgotICAgICAqIFJlc2V0cyB0aGUgY29tcG9uZW50LiBUaGUgY29tcG9uZW50IGNhbiBxdWVyeSB0aGUgY29tcG9uZW50IG1hbmFnZXIKLSAgICAgKiBhYm91dCBhbnkgZmVhdHVyZXMgYW5kIHByb3BlcnRpZXMgdGhhdCBhZmZlY3QgdGhlIG9wZXJhdGlvbiBvZiB0aGUKLSAgICAgKiBjb21wb25lbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29tcG9uZW50TWFuYWdlciBUaGUgY29tcG9uZW50IG1hbmFnZXIuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBUaHJvd24gYnkgY29tcG9uZW50IG9uIGZpbml0aWFsaXphdGlvbiBlcnJvci4KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBGb3IgZXhhbXBsZSwgaWYgYSBmZWF0dXJlIG9yIHByb3BlcnR5IGlzCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgcmVxdWlyZWQgZm9yIHRoZSBvcGVyYXRpb24gb2YgdGhlIGNvbXBvbmVudCwgdGhlCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgY29tcG9uZW50IG1hbmFnZXIgbWF5IHRocm93IGEKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIG9yIGEKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcmVzZXQoWE1MQ29tcG9uZW50TWFuYWdlciBjb21wb25lbnRNYW5hZ2VyKSB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgYm9vbGVhbiBwYXJzZXJfc2V0dGluZ3MgPSBjb21wb25lbnRNYW5hZ2VyLmdldEZlYXR1cmUoUEFSU0VSX1NFVFRJTkdTLCB0cnVlKTsKLQotICAgICAgICBpZiAoIXBhcnNlcl9zZXR0aW5ncykgewotICAgICAgICAgICAgLy8gcGFyc2VyIHNldHRpbmdzIGhhdmUgbm90IGJlZW4gY2hhbmdlZAotICAgICAgICAgICAgcmVzZXQoKTsKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIHNheCBmZWF0dXJlcwotICAgICAgICBmVmFsaWRhdGlvbiA9IGNvbXBvbmVudE1hbmFnZXIuZ2V0RmVhdHVyZShWQUxJREFUSU9OLCBmYWxzZSk7Ci0KLSAgICAgICAgZkRURFZhbGlkYXRpb24gPQotICAgICAgICAgICAgICAgICEoY29tcG9uZW50TWFuYWdlcgotICAgICAgICAgICAgICAgICAgICAuZ2V0RmVhdHVyZSgKLSAgICAgICAgICAgICAgICAgICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuU0NIRU1BX1ZBTElEQVRJT05fRkVBVFVSRSwgZmFsc2UpKTsKLQotICAgICAgICAvLyBYZXJjZXMgZmVhdHVyZXMKLQotICAgICAgICBmV2FybkR1cGxpY2F0ZUF0dGRlZiA9IGNvbXBvbmVudE1hbmFnZXIuZ2V0RmVhdHVyZShXQVJOX09OX0RVUExJQ0FURV9BVFRERUYsIGZhbHNlKTsKLSAgICAgICAgZldhcm5PblVuZGVjbGFyZWRFbGVtZGVmID0gY29tcG9uZW50TWFuYWdlci5nZXRGZWF0dXJlKFdBUk5fT05fVU5ERUNMQVJFRF9FTEVNREVGLCBmYWxzZSk7Ci0KLSAgICAgICAgLy8gZ2V0IG5lZWRlZCBjb21wb25lbnRzCi0gICAgICAgIGZFcnJvclJlcG9ydGVyID0KLSAgICAgICAgICAgIChYTUxFcnJvclJlcG9ydGVyKSBjb21wb25lbnRNYW5hZ2VyLmdldFByb3BlcnR5KAotICAgICAgICAgICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLkVSUk9SX1JFUE9SVEVSX1BST1BFUlRZKTsKLSAgICAgICAgZlN5bWJvbFRhYmxlID0KLSAgICAgICAgICAgIChTeW1ib2xUYWJsZSkgY29tcG9uZW50TWFuYWdlci5nZXRQcm9wZXJ0eSgKLSAgICAgICAgICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5TWU1CT0xfVEFCTEVfUFJPUEVSVFkpOwotCi0gICAgICAgIGZHcmFtbWFyUG9vbCA9IChYTUxHcmFtbWFyUG9vbCkgY29tcG9uZW50TWFuYWdlci5nZXRQcm9wZXJ0eShHUkFNTUFSX1BPT0wsIG51bGwpOwotCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBmVmFsaWRhdG9yID0gKFhNTERURFZhbGlkYXRvcikgY29tcG9uZW50TWFuYWdlci5nZXRQcm9wZXJ0eShEVERfVkFMSURBVE9SLCBudWxsKTsKLSAgICAgICAgfSBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIGZWYWxpZGF0b3IgPSBudWxsOwotICAgICAgICB9Ci0gICAgICAgIC8vIHdlIGdldCBvdXIgZ3JhbW1hckJ1Y2tldCBmcm9tIHRoZSB2YWxpZGF0b3IuLi4KLSAgICAgICAgaWYgKGZWYWxpZGF0b3IgIT0gbnVsbCkgewotICAgICAgICAgICAgZkdyYW1tYXJCdWNrZXQgPSBmVmFsaWRhdG9yLmdldEdyYW1tYXJCdWNrZXQoKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIGZHcmFtbWFyQnVja2V0ID0gbnVsbDsKLSAgICAgICAgfQotICAgICAgICByZXNldCgpOwotCi0gICAgfSAvLyByZXNldChYTUxDb21wb25lbnRNYW5hZ2VyKQotCi0gICAgcHJvdGVjdGVkIHZvaWQgcmVzZXQoKSB7Ci0gICAgICAgIC8vIGNsZWFyIGdyYW1tYXJzCi0gICAgICAgIGZEVERHcmFtbWFyID0gbnVsbDsKLSAgICAgICAgLy8gaW5pdGlhbGl6ZSBzdGF0ZQotICAgICAgICBmSW5EVERJZ25vcmUgPSBmYWxzZTsKLQotICAgICAgICBmTkRhdGFEZWNsTm90YXRpb25zLmNsZWFyKCk7Ci0KLSAgICAgICAgLy8gZGF0YXR5cGUgdmFsaWRhdG9ycwotICAgICAgICBpZiAoZlZhbGlkYXRpb24pIHsKLQotICAgICAgICAgICAgaWYgKGZOb3RhdGlvbkVudW1WYWxzID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmTm90YXRpb25FbnVtVmFscyA9IG5ldyBIYXNoTWFwKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmTm90YXRpb25FbnVtVmFscy5jbGVhcigpOwotCi0gICAgICAgICAgICBmVGFibGVPZklEQXR0cmlidXRlTmFtZXMgPSBuZXcgSGFzaE1hcCgpOwotICAgICAgICAgICAgZlRhYmxlT2ZOT1RBVElPTkF0dHJpYnV0ZU5hbWVzID0gbmV3IEhhc2hNYXAoKTsKLSAgICAgICAgfQotCi0gICAgfQotICAgIC8qKgotICAgICAqIFJldHVybnMgYSBsaXN0IG9mIGZlYXR1cmUgaWRlbnRpZmllcnMgdGhhdCBhcmUgcmVjb2duaXplZCBieQotICAgICAqIHRoaXMgY29tcG9uZW50LiBUaGlzIG1ldGhvZCBtYXkgcmV0dXJuIG51bGwgaWYgbm8gZmVhdHVyZXMKLSAgICAgKiBhcmUgcmVjb2duaXplZCBieSB0aGlzIGNvbXBvbmVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nW10gZ2V0UmVjb2duaXplZEZlYXR1cmVzKCkgewotICAgICAgICByZXR1cm4gKFN0cmluZ1tdKShSRUNPR05JWkVEX0ZFQVRVUkVTLmNsb25lKCkpOwotICAgIH0gLy8gZ2V0UmVjb2duaXplZEZlYXR1cmVzKCk6U3RyaW5nW10KLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIHN0YXRlIG9mIGEgZmVhdHVyZS4gVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBjb21wb25lbnQKLSAgICAgKiBtYW5hZ2VyIGFueSB0aW1lIGFmdGVyIHJlc2V0IHdoZW4gYSBmZWF0dXJlIGNoYW5nZXMgc3RhdGUuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBDb21wb25lbnRzIHNob3VsZCBzaWxlbnRseSBpZ25vcmUgZmVhdHVyZXMKLSAgICAgKiB0aGF0IGRvIG5vdCBhZmZlY3QgdGhlIG9wZXJhdGlvbiBvZiB0aGUgY29tcG9uZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIGZlYXR1cmVJZCBUaGUgZmVhdHVyZSBpZGVudGlmaWVyLgotICAgICAqIEBwYXJhbSBzdGF0ZSAgICAgVGhlIHN0YXRlIG9mIHRoZSBmZWF0dXJlLgotICAgICAqCi0gICAgICogQHRocm93cyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIFRoZSBjb21wb25lbnQgc2hvdWxkIG5vdCB0aHJvdwotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzIGV4Y2VwdGlvbi4KLSAgICAgKiBAdGhyb3dzIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBUaGUgY29tcG9uZW50IHNob3VsZCBub3QgdGhyb3cKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzIGV4Y2VwdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRGZWF0dXJlKFN0cmluZyBmZWF0dXJlSWQsIGJvb2xlYW4gc3RhdGUpCi0gICAgICAgICAgICB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiB7Ci0gICAgfSAvLyBzZXRGZWF0dXJlKFN0cmluZyxib29sZWFuKQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhIGxpc3Qgb2YgcHJvcGVydHkgaWRlbnRpZmllcnMgdGhhdCBhcmUgcmVjb2duaXplZCBieQotICAgICAqIHRoaXMgY29tcG9uZW50LiBUaGlzIG1ldGhvZCBtYXkgcmV0dXJuIG51bGwgaWYgbm8gcHJvcGVydGllcwotICAgICAqIGFyZSByZWNvZ25pemVkIGJ5IHRoaXMgY29tcG9uZW50LgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmdbXSBnZXRSZWNvZ25pemVkUHJvcGVydGllcygpIHsKLSAgICAgICAgcmV0dXJuIChTdHJpbmdbXSkoUkVDT0dOSVpFRF9QUk9QRVJUSUVTLmNsb25lKCkpOwotICAgIH0gLy8gZ2V0UmVjb2duaXplZFByb3BlcnRpZXMoKTpTdHJpbmdbXQotCi0gICAgLyoqCi0gICAgICogU2V0cyB0aGUgdmFsdWUgb2YgYSBwcm9wZXJ0eS4gVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBjb21wb25lbnQKLSAgICAgKiBtYW5hZ2VyIGFueSB0aW1lIGFmdGVyIHJlc2V0IHdoZW4gYSBwcm9wZXJ0eSBjaGFuZ2VzIHZhbHVlLgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gQ29tcG9uZW50cyBzaG91bGQgc2lsZW50bHkgaWdub3JlIHByb3BlcnRpZXMKLSAgICAgKiB0aGF0IGRvIG5vdCBhZmZlY3QgdGhlIG9wZXJhdGlvbiBvZiB0aGUgY29tcG9uZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIHByb3BlcnR5SWQgVGhlIHByb3BlcnR5IGlkZW50aWZpZXIuCi0gICAgICogQHBhcmFtIHZhbHVlICAgICAgVGhlIHZhbHVlIG9mIHRoZSBwcm9wZXJ0eS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiBUaGUgY29tcG9uZW50IHNob3VsZCBub3QgdGhyb3cKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcyBleGNlcHRpb24uCi0gICAgICogQHRocm93cyBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gVGhlIGNvbXBvbmVudCBzaG91bGQgbm90IHRocm93Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcyBleGNlcHRpb24uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0UHJvcGVydHkoU3RyaW5nIHByb3BlcnR5SWQsIE9iamVjdCB2YWx1ZSkKLSAgICAgICAgICAgIHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIHsKLSAgICB9IC8vIHNldFByb3BlcnR5KFN0cmluZyxPYmplY3QpCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBkZWZhdWx0IHN0YXRlIGZvciBhIGZlYXR1cmUsIG9yIG51bGwgaWYgdGhpcwotICAgICAqIGNvbXBvbmVudCBkb2VzIG5vdCB3YW50IHRvIHJlcG9ydCBhIGRlZmF1bHQgdmFsdWUgZm9yIHRoaXMKLSAgICAgKiBmZWF0dXJlLgotICAgICAqCi0gICAgICogQHBhcmFtIGZlYXR1cmVJZCBUaGUgZmVhdHVyZSBpZGVudGlmaWVyLgotICAgICAqCi0gICAgICogQHNpbmNlIFhlcmNlcyAyLjIuMAotICAgICAqLwotICAgIHB1YmxpYyBCb29sZWFuIGdldEZlYXR1cmVEZWZhdWx0KFN0cmluZyBmZWF0dXJlSWQpIHsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBSRUNPR05JWkVEX0ZFQVRVUkVTLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICBpZiAoUkVDT0dOSVpFRF9GRUFUVVJFU1tpXS5lcXVhbHMoZmVhdHVyZUlkKSkgewotICAgICAgICAgICAgICAgIHJldHVybiBGRUFUVVJFX0RFRkFVTFRTW2ldOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0gLy8gZ2V0RmVhdHVyZURlZmF1bHQoU3RyaW5nKTpCb29sZWFuCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBkZWZhdWx0IHN0YXRlIGZvciBhIHByb3BlcnR5LCBvciBudWxsIGlmIHRoaXMKLSAgICAgKiBjb21wb25lbnQgZG9lcyBub3Qgd2FudCB0byByZXBvcnQgYSBkZWZhdWx0IHZhbHVlIGZvciB0aGlzCi0gICAgICogcHJvcGVydHkuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcHJvcGVydHlJZCBUaGUgcHJvcGVydHkgaWRlbnRpZmllci4KLSAgICAgKgotICAgICAqIEBzaW5jZSBYZXJjZXMgMi4yLjAKLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0IGdldFByb3BlcnR5RGVmYXVsdChTdHJpbmcgcHJvcGVydHlJZCkgewotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IFJFQ09HTklaRURfUFJPUEVSVElFUy5sZW5ndGg7IGkrKykgewotICAgICAgICAgICAgaWYgKFJFQ09HTklaRURfUFJPUEVSVElFU1tpXS5lcXVhbHMocHJvcGVydHlJZCkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gUFJPUEVSVFlfREVGQVVMVFNbaV07Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfSAvLyBnZXRQcm9wZXJ0eURlZmF1bHQoU3RyaW5nKTpPYmplY3QKLQotICAgIC8vCi0gICAgLy8gWE1MRFREU291cmNlIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogU2V0cyB0aGUgRFREIGhhbmRsZXIuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZHRkSGFuZGxlciBUaGUgRFREIGhhbmRsZXIuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RFRESGFuZGxlcihYTUxEVERIYW5kbGVyIGR0ZEhhbmRsZXIpIHsKLSAgICAgICAgZkRUREhhbmRsZXIgPSBkdGRIYW5kbGVyOwotICAgIH0gLy8gc2V0RFRESGFuZGxlcihYTUxEVERIYW5kbGVyKQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgRFREIGhhbmRsZXIuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBEVEQgaGFuZGxlci4KLSAgICAgKi8KLSAgICBwdWJsaWMgWE1MRFRESGFuZGxlciBnZXREVERIYW5kbGVyKCkgewotICAgICAgICByZXR1cm4gZkRUREhhbmRsZXI7Ci0gICAgfSAvLyBnZXREVERIYW5kbGVyKCk6ICBYTUxEVERIYW5kbGVyCi0KLSAgICAvLwotICAgIC8vIFhNTERURENvbnRlbnRNb2RlbFNvdXJjZSBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIERURCBjb250ZW50IG1vZGVsIGhhbmRsZXIuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZHRkQ29udGVudE1vZGVsSGFuZGxlciBUaGUgRFREIGNvbnRlbnQgbW9kZWwgaGFuZGxlci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXREVERDb250ZW50TW9kZWxIYW5kbGVyKFhNTERURENvbnRlbnRNb2RlbEhhbmRsZXIgZHRkQ29udGVudE1vZGVsSGFuZGxlcikgewotICAgICAgICBmRFREQ29udGVudE1vZGVsSGFuZGxlciA9IGR0ZENvbnRlbnRNb2RlbEhhbmRsZXI7Ci0gICAgfSAvLyBzZXREVERDb250ZW50TW9kZWxIYW5kbGVyKFhNTERURENvbnRlbnRNb2RlbEhhbmRsZXIpCi0KLSAgICAvKioKLSAgICAgKiBHZXRzIHRoZSBEVEQgY29udGVudCBtb2RlbCBoYW5kbGVyLgotICAgICAqCi0gICAgICogQHJldHVybiBkdGRDb250ZW50TW9kZWxIYW5kbGVyIFRoZSBEVEQgY29udGVudCBtb2RlbCBoYW5kbGVyLgotICAgICAqLwotICAgIHB1YmxpYyBYTUxEVERDb250ZW50TW9kZWxIYW5kbGVyIGdldERURENvbnRlbnRNb2RlbEhhbmRsZXIoKSB7Ci0gICAgICAgIHJldHVybiBmRFREQ29udGVudE1vZGVsSGFuZGxlcjsKLSAgICB9IC8vIGdldERURENvbnRlbnRNb2RlbEhhbmRsZXIoKTogIFhNTERURENvbnRlbnRNb2RlbEhhbmRsZXIKLQotICAgIC8vCi0gICAgLy8gWE1MRFREQ29udGVudE1vZGVsSGFuZGxlciBhbmQgWE1MRFRESGFuZGxlciBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFRoZSBzdGFydCBvZiB0aGUgRFREIGV4dGVybmFsIHN1YnNldC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBhdWdzIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydEV4dGVybmFsU3Vic2V0KFhNTFJlc291cmNlSWRlbnRpZmllciBpZGVudGlmaWVyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgaWYoZkRUREdyYW1tYXIgIT0gbnVsbCkKLSAgICAgICAgICAgIGZEVERHcmFtbWFyLnN0YXJ0RXh0ZXJuYWxTdWJzZXQoaWRlbnRpZmllciwgYXVncyk7Ci0gICAgICAgIGlmKGZEVERIYW5kbGVyICE9IG51bGwpewotICAgICAgICAgICAgZkRUREhhbmRsZXIuc3RhcnRFeHRlcm5hbFN1YnNldChpZGVudGlmaWVyLCBhdWdzKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoZSBlbmQgb2YgdGhlIERURCBleHRlcm5hbCBzdWJzZXQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYXVncyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kRXh0ZXJuYWxTdWJzZXQoQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgaWYoZkRUREdyYW1tYXIgIT0gbnVsbCkKLSAgICAgICAgICAgIGZEVERHcmFtbWFyLmVuZEV4dGVybmFsU3Vic2V0KGF1Z3MpOwotICAgICAgICBpZihmRFRESGFuZGxlciAhPSBudWxsKXsKLSAgICAgICAgICAgIGZEVERIYW5kbGVyLmVuZEV4dGVybmFsU3Vic2V0KGF1Z3MpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ2hlY2sgc3RhbmRhbG9uZSBlbnRpdHkgcmVmZXJlbmNlLgotICAgICAqIE1hZGUgc3RhdGljIHRvIG1ha2UgY29tbW9uIGJldHdlZW4gdGhlIHZhbGlkYXRvciBhbmQgbG9hZGVyLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUKLSAgICAgKkBwYXJhbSBncmFtbWFyICAgIGdyYW1tYXIgdG8gd2hpY2ggZW50aXR5IGJlbG9uZ3MKLSAgICAgKiBAcGFyYW0gdGVtcEVudGl0eURlY2wgICAgZW1wdHkgZW50aXR5IGRlY2xhcmF0aW9uIHRvIHB1dCByZXN1bHRzIGluCi0gICAgICogQHBhcmFtIGVycm9yUmVwb3J0ZXIgICAgIGVycm9yIHJlcG9ydGVyIHRvIHNlbmQgZXJyb3JzIHRvCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgYXBwbGljYXRpb24gdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgdm9pZCBjaGVja1N0YW5kYWxvbmVFbnRpdHlSZWYoU3RyaW5nIG5hbWUsIERUREdyYW1tYXIgZ3JhbW1hciwKLSAgICAgICAgICAgICAgICAgICAgWE1MRW50aXR5RGVjbCB0ZW1wRW50aXR5RGVjbCwgWE1MRXJyb3JSZXBvcnRlciBlcnJvclJlcG9ydGVyKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgLy8gY2hlY2sgVkM6IFN0YW5kYWxvbmUgRG9jdW1lbnQgRGVjbGFydGlvbiwgZW50aXRpZXMgcmVmZXJlbmNlcyBhcHBlYXIgaW4gdGhlIGRvY3VtZW50LgotICAgICAgICBpbnQgZW50SW5kZXggPSBncmFtbWFyLmdldEVudGl0eURlY2xJbmRleChuYW1lKTsKLSAgICAgICAgaWYgKGVudEluZGV4ID4gLTEpIHsKLSAgICAgICAgICAgIGdyYW1tYXIuZ2V0RW50aXR5RGVjbChlbnRJbmRleCwgdGVtcEVudGl0eURlY2wpOwotICAgICAgICAgICAgaWYgKHRlbXBFbnRpdHlEZWNsLmluRXh0ZXJuYWwpIHsKLSAgICAgICAgICAgICAgICBlcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKCBYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNU0dfUkVGRVJFTkNFX1RPX0VYVEVSTkFMTFlfREVDTEFSRURfRU5USVRZX1dIRU5fU1RBTkRBTE9ORSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXtuYW1lfSwgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9FUlJPUik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBIGNvbW1lbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdGV4dCBUaGUgdGV4dCBpbiB0aGUgY29tbWVudC4KLSAgICAgKiBAcGFyYW0gYXVncyAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBhcHBsaWNhdGlvbiB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY29tbWVudChYTUxTdHJpbmcgdGV4dCwgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLQotICAgICAgICAvLyBjYWxsIGhhbmRsZXJzCi0gICAgICAgIGlmKGZEVERHcmFtbWFyICE9IG51bGwpCi0gICAgICAgICAgICBmRFRER3JhbW1hci5jb21tZW50KHRleHQsIGF1Z3MpOwotICAgICAgICBpZiAoZkRUREhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkRUREhhbmRsZXIuY29tbWVudCh0ZXh0LCBhdWdzKTsKLSAgICAgICAgfQotCi0gICAgfSAvLyBjb21tZW50KFhNTFN0cmluZykKLQotCi0gICAgLyoqCi0gICAgICogQSBwcm9jZXNzaW5nIGluc3RydWN0aW9uLiBQcm9jZXNzaW5nIGluc3RydWN0aW9ucyBjb25zaXN0IG9mIGEKLSAgICAgKiB0YXJnZXQgbmFtZSBhbmQsIG9wdGlvbmFsbHksIHRleHQgZGF0YS4gVGhlIGRhdGEgaXMgb25seSBtZWFuaW5nZnVsCi0gICAgICogdG8gdGhlIGFwcGxpY2F0aW9uLgotICAgICAqIDxwPgotICAgICAqIFR5cGljYWxseSwgYSBwcm9jZXNzaW5nIGluc3RydWN0aW9uJ3MgZGF0YSB3aWxsIGNvbnRhaW4gYSBzZXJpZXMKLSAgICAgKiBvZiBwc2V1ZG8tYXR0cmlidXRlcy4gVGhlc2UgcHNldWRvLWF0dHJpYnV0ZXMgZm9sbG93IHRoZSBmb3JtIG9mCi0gICAgICogZWxlbWVudCBhdHRyaWJ1dGVzIGJ1dCBhcmUgPHN0cm9uZz5ub3Q8L3N0cm9uZz4gcGFyc2VkIG9yIHByZXNlbnRlZAotICAgICAqIHRvIHRoZSBhcHBsaWNhdGlvbiBhcyBhbnl0aGluZyBvdGhlciB0aGFuIHRleHQuIFRoZSBhcHBsaWNhdGlvbiBpcwotICAgICAqIHJlc3BvbnNpYmxlIGZvciBwYXJzaW5nIHRoZSBkYXRhLgotICAgICAqCi0gICAgICogQHBhcmFtIHRhcmdldCBUaGUgdGFyZ2V0LgotICAgICAqIEBwYXJhbSBkYXRhICAgVGhlIGRhdGEgb3IgbnVsbCBpZiBub25lIHNwZWNpZmllZC4KLSAgICAgKiBAcGFyYW0gYXVncyAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oU3RyaW5nIHRhcmdldCwgWE1MU3RyaW5nIGRhdGEsIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLQotICAgICAgICAvLyBjYWxsIGhhbmRsZXJzCi0gICAgICAgIGlmKGZEVERHcmFtbWFyICE9IG51bGwpCi0gICAgICAgICAgICBmRFRER3JhbW1hci5wcm9jZXNzaW5nSW5zdHJ1Y3Rpb24odGFyZ2V0LCBkYXRhLCBhdWdzKTsKLSAgICAgICAgaWYgKGZEVERIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZEVERIYW5kbGVyLnByb2Nlc3NpbmdJbnN0cnVjdGlvbih0YXJnZXQsIGRhdGEsIGF1Z3MpOwotICAgICAgICB9Ci0gICAgfSAvLyBwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oU3RyaW5nLFhNTFN0cmluZykKLQotICAgIC8vCi0gICAgLy8gWE1MRFRESGFuZGxlciBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFRoZSBzdGFydCBvZiB0aGUgRFRELgotICAgICAqCi0gICAgICogQHBhcmFtIGxvY2F0b3IgIFRoZSBkb2N1bWVudCBsb2NhdG9yLCBvciBudWxsIGlmIHRoZSBkb2N1bWVudAotICAgICAqICAgICAgICAgICAgICAgICBsb2NhdGlvbiBjYW5ub3QgYmUgcmVwb3J0ZWQgZHVyaW5nIHRoZSBwYXJzaW5nIG9mCi0gICAgICogICAgICAgICAgICAgICAgIHRoZSBkb2N1bWVudCBEVEQuIEhvd2V2ZXIsIGl0IGlzIDxlbT5zdHJvbmdseTwvZW0+Ci0gICAgICogICAgICAgICAgICAgICAgIHJlY29tbWVuZGVkIHRoYXQgYSBsb2NhdG9yIGJlIHN1cHBsaWVkIHRoYXQgY2FuCi0gICAgICogICAgICAgICAgICAgICAgIGF0IGxlYXN0IHJlcG9ydCB0aGUgYmFzZSBzeXN0ZW0gaWRlbnRpZmllciBvZiB0aGUKLSAgICAgKiAgICAgICAgICAgICAgICAgRFRELgotICAgICAqIEBwYXJhbSBhdWdzIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydERURChYTUxMb2NhdG9yIGxvY2F0b3IsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLQotICAgICAgICAvLyBpbml0aWFsaXplIHN0YXRlCi0gICAgICAgIGZORGF0YURlY2xOb3RhdGlvbnMuY2xlYXIoKTsKLSAgICAgICAgZkRUREVsZW1lbnREZWNscy5jbGVhcigpOwotCi0gICAgICAgIC8vIHRoZSBncmFtbWFyIGJ1Y2tldCdzIERUREdyYW1tYXIgd2lsbCBub3cgYmUgdGhlCi0gICAgICAgIC8vIG9uZSB3ZSB3YW50LCB3aGV0aGVyIHdlJ3JlIGNvbnN0cnVjdGluZyBpdCBvciBub3QuCi0gICAgICAgIC8vIGlmIHdlJ3JlIG5vdCBjb25zdHJ1Y3RpbmcgaXQsIHRoZW4gd2Ugc2hvdWxkIG5vdCBoYXZlIGEgcmVmZXJlbmNlCi0gICAgICAgIC8vIHRvIGl0IQotICAgICAgIGlmKCAhZkdyYW1tYXJCdWNrZXQuZ2V0QWN0aXZlR3JhbW1hcigpLmlzSW1tdXRhYmxlKCkpIHsKLSAgICAgICAgICAgIGZEVERHcmFtbWFyID0gZkdyYW1tYXJCdWNrZXQuZ2V0QWN0aXZlR3JhbW1hcigpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gY2FsbCBoYW5kbGVycwotICAgICAgICBpZihmRFRER3JhbW1hciAhPSBudWxsICkKLSAgICAgICAgICAgIGZEVERHcmFtbWFyLnN0YXJ0RFREKGxvY2F0b3IsIGF1Z3MpOwotICAgICAgICBpZiAoZkRUREhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkRUREhhbmRsZXIuc3RhcnREVEQobG9jYXRvciwgYXVncyk7Ci0gICAgICAgIH0KLQotICAgIH0gLy8gc3RhcnREVEQoWE1MTG9jYXRvcikKLQotICAgIC8qKgotICAgICAqIENoYXJhY3RlcnMgd2l0aGluIGFuIElHTk9SRSBjb25kaXRpb25hbCBzZWN0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIHRleHQgVGhlIGlnbm9yZWQgdGV4dC4KLSAgICAgKiBAcGFyYW0gYXVncyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgaWdub3JlZENoYXJhY3RlcnMoWE1MU3RyaW5nIHRleHQsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy8gaWdub3JlZCBjaGFyYWN0ZXJzIGluIERURAotICAgICAgICBpZihmRFRER3JhbW1hciAhPSBudWxsICkKLSAgICAgICAgICAgIGZEVERHcmFtbWFyLmlnbm9yZWRDaGFyYWN0ZXJzKHRleHQsIGF1Z3MpOwotICAgICAgICBpZiAoZkRUREhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkRUREhhbmRsZXIuaWdub3JlZENoYXJhY3RlcnModGV4dCwgYXVncyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBOb3RpZmllcyBvZiB0aGUgcHJlc2VuY2Ugb2YgYSBUZXh0RGVjbCBsaW5lIGluIGFuIGVudGl0eS4gSWYgcHJlc2VudCwKLSAgICAgKiB0aGlzIG1ldGhvZCB3aWxsIGJlIGNhbGxlZCBpbW1lZGlhdGVseSBmb2xsb3dpbmcgdGhlIHN0YXJ0UGFyYW1ldGVyRW50aXR5IGNhbGwuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGlzIG1ldGhvZCBpcyBvbmx5IGNhbGxlZCBmb3IgZXh0ZXJuYWwKLSAgICAgKiBwYXJhbWV0ZXIgZW50aXRpZXMgcmVmZXJlbmNlZCBpbiB0aGUgRFRELgotICAgICAqCi0gICAgICogQHBhcmFtIHZlcnNpb24gIFRoZSBYTUwgdmVyc2lvbiwgb3IgbnVsbCBpZiBub3Qgc3BlY2lmaWVkLgotICAgICAqIEBwYXJhbSBlbmNvZGluZyBUaGUgSUFOQSBlbmNvZGluZyBuYW1lIG9mIHRoZSBlbnRpdHkuCi0gICAgICogQHBhcmFtIGF1Z3MgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRleHREZWNsKFN0cmluZyB2ZXJzaW9uLCBTdHJpbmcgZW5jb2RpbmcsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy8gY2FsbCBoYW5kbGVycwotICAgICAgICBpZihmRFRER3JhbW1hciAhPSBudWxsICkKLSAgICAgICAgICAgIGZEVERHcmFtbWFyLnRleHREZWNsKHZlcnNpb24sIGVuY29kaW5nLCBhdWdzKTsKLSAgICAgICAgaWYgKGZEVERIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZEVERIYW5kbGVyLnRleHREZWNsKHZlcnNpb24sIGVuY29kaW5nLCBhdWdzKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIG5vdGlmaWVzIG9mIHRoZSBzdGFydCBvZiBhIHBhcmFtZXRlciBlbnRpdHkuIFRoZSBwYXJhbWV0ZXIKLSAgICAgKiBlbnRpdHkgbmFtZSBzdGFydCB3aXRoIGEgJyUnIGNoYXJhY3Rlci4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lICAgICBUaGUgbmFtZSBvZiB0aGUgcGFyYW1ldGVyIGVudGl0eS4KLSAgICAgKiBAcGFyYW0gaWRlbnRpZmllciBUaGUgcmVzb3VyY2UgaWRlbnRpZmllci4KLSAgICAgKiBAcGFyYW0gZW5jb2RpbmcgVGhlIGF1dG8tZGV0ZWN0ZWQgSUFOQSBlbmNvZGluZyBuYW1lIG9mIHRoZSBlbnRpdHkKLSAgICAgKiAgICAgICAgICAgICAgICAgc3RyZWFtLiBUaGlzIHZhbHVlIHdpbGwgYmUgbnVsbCBpbiB0aG9zZSBzaXR1YXRpb25zCi0gICAgICogICAgICAgICAgICAgICAgIHdoZXJlIHRoZSBlbnRpdHkgZW5jb2RpbmcgaXMgbm90IGF1dG8tZGV0ZWN0ZWQgKGUuZy4KLSAgICAgKiAgICAgICAgICAgICAgICAgaW50ZXJuYWwgcGFyYW1ldGVyIGVudGl0aWVzKS4KLSAgICAgKiBAcGFyYW0gYXVncyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnRQYXJhbWV0ZXJFbnRpdHkoU3RyaW5nIG5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MUmVzb3VyY2VJZGVudGlmaWVyIGlkZW50aWZpZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGVuY29kaW5nLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgaWYgKGZQZXJmb3JtVmFsaWRhdGlvbiAmJiBmRFRER3JhbW1hciAhPSBudWxsICYmCi0gICAgICAgICAgICAgICAgZkdyYW1tYXJCdWNrZXQuZ2V0U3RhbmRhbG9uZSgpKSB7Ci0gICAgICAgICAgICBjaGVja1N0YW5kYWxvbmVFbnRpdHlSZWYobmFtZSwgZkRUREdyYW1tYXIsIGZFbnRpdHlEZWNsLCBmRXJyb3JSZXBvcnRlcik7Ci0gICAgICAgIH0KLSAgICAgICAgLy8gY2FsbCBoYW5kbGVycwotICAgICAgICBpZihmRFRER3JhbW1hciAhPSBudWxsICkKLSAgICAgICAgICAgIGZEVERHcmFtbWFyLnN0YXJ0UGFyYW1ldGVyRW50aXR5KG5hbWUsIGlkZW50aWZpZXIsIGVuY29kaW5nLCBhdWdzKTsKLSAgICAgICAgaWYgKGZEVERIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZEVERIYW5kbGVyLnN0YXJ0UGFyYW1ldGVyRW50aXR5KG5hbWUsIGlkZW50aWZpZXIsIGVuY29kaW5nLCBhdWdzKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIG5vdGlmaWVzIHRoZSBlbmQgb2YgYSBwYXJhbWV0ZXIgZW50aXR5LiBQYXJhbWV0ZXIgZW50aXR5Ci0gICAgICogbmFtZXMgYmVnaW4gd2l0aCBhICclJyBjaGFyYWN0ZXIuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgcGFyYW1ldGVyIGVudGl0eS4KLSAgICAgKiBAcGFyYW0gYXVncyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kUGFyYW1ldGVyRW50aXR5KFN0cmluZyBuYW1lLCBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotCi0gICAgICAgIC8vIGNhbGwgaGFuZGxlcnMKLSAgICAgICAgaWYoZkRUREdyYW1tYXIgIT0gbnVsbCApCi0gICAgICAgICAgICBmRFRER3JhbW1hci5lbmRQYXJhbWV0ZXJFbnRpdHkobmFtZSwgYXVncyk7Ci0gICAgICAgIGlmIChmRFRESGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmRFRESGFuZGxlci5lbmRQYXJhbWV0ZXJFbnRpdHkobmFtZSwgYXVncyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBbiBlbGVtZW50IGRlY2xhcmF0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgICAgICAgICBUaGUgbmFtZSBvZiB0aGUgZWxlbWVudC4KLSAgICAgKiBAcGFyYW0gY29udGVudE1vZGVsIFRoZSBlbGVtZW50IGNvbnRlbnQgbW9kZWwuCi0gICAgICogQHBhcmFtIGF1Z3MgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVsZW1lbnREZWNsKFN0cmluZyBuYW1lLCBTdHJpbmcgY29udGVudE1vZGVsLCBBdWdtZW50YXRpb25zIGF1Z3MpCi0gICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy9jaGVjayBWQzogVW5pcXVlIEVsZW1lbnQgRGVjbGFyYXRpb24KLSAgICAgICAgaWYgKGZWYWxpZGF0aW9uKSB7Ci0gICAgICAgICAgICBpZiAoZkRUREVsZW1lbnREZWNscy5jb250YWlucyhuYW1lKSkgewotICAgICAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTVNHX0VMRU1FTlRfQUxSRUFEWV9ERUNMQVJFRCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdeyBuYW1lfSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxFcnJvclJlcG9ydGVyLlNFVkVSSVRZX0VSUk9SKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIGZEVERFbGVtZW50RGVjbHMuYWRkKG5hbWUpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gY2FsbCBoYW5kbGVycwotICAgICAgICBpZihmRFRER3JhbW1hciAhPSBudWxsICkKLSAgICAgICAgICAgIGZEVERHcmFtbWFyLmVsZW1lbnREZWNsKG5hbWUsIGNvbnRlbnRNb2RlbCwgYXVncyk7Ci0gICAgICAgIGlmIChmRFRESGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmRFRESGFuZGxlci5lbGVtZW50RGVjbChuYW1lLCBjb250ZW50TW9kZWwsIGF1Z3MpOwotICAgICAgICB9Ci0KLSAgICB9IC8vIGVsZW1lbnREZWNsKFN0cmluZyxTdHJpbmcpCi0KLSAgICAvKioKLSAgICAgKiBUaGUgc3RhcnQgb2YgYW4gYXR0cmlidXRlIGxpc3QuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZWxlbWVudE5hbWUgVGhlIG5hbWUgb2YgdGhlIGVsZW1lbnQgdGhhdCB0aGlzIGF0dHJpYnV0ZQotICAgICAqICAgICAgICAgICAgICAgICAgICBsaXN0IGlzIGFzc29jaWF0ZWQgd2l0aC4KLSAgICAgKiBAcGFyYW0gYXVncyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnRBdHRsaXN0KFN0cmluZyBlbGVtZW50TmFtZSwgQXVnbWVudGF0aW9ucyBhdWdzKQotICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLQotICAgICAgICAvLyBjYWxsIGhhbmRsZXJzCi0gICAgICAgIGlmKGZEVERHcmFtbWFyICE9IG51bGwgKQotICAgICAgICAgICAgZkRUREdyYW1tYXIuc3RhcnRBdHRsaXN0KGVsZW1lbnROYW1lLCBhdWdzKTsKLSAgICAgICAgaWYgKGZEVERIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZEVERIYW5kbGVyLnN0YXJ0QXR0bGlzdChlbGVtZW50TmFtZSwgYXVncyk7Ci0gICAgICAgIH0KLQotICAgIH0gLy8gc3RhcnRBdHRsaXN0KFN0cmluZykKLQotICAgIC8qKgotICAgICAqIEFuIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlbGVtZW50TmFtZSAgIFRoZSBuYW1lIG9mIHRoZSBlbGVtZW50IHRoYXQgdGhpcyBhdHRyaWJ1dGUKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBpcyBhc3NvY2lhdGVkIHdpdGguCi0gICAgICogQHBhcmFtIGF0dHJpYnV0ZU5hbWUgVGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgKiBAcGFyYW0gdHlwZSAgICAgICAgICBUaGUgYXR0cmlidXRlIHR5cGUuIFRoaXMgdmFsdWUgd2lsbCBiZSBvbmUgb2YKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICB0aGUgZm9sbG93aW5nOiAiQ0RBVEEiLCAiRU5USVRZIiwgIkVOVElUSUVTIiwKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAiRU5VTUVSQVRJT04iLCAiSUQiLCAiSURSRUYiLCAiSURSRUZTIiwKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAiTk1UT0tFTiIsICJOTVRPS0VOUyIsIG9yICJOT1RBVElPTiIuCi0gICAgICogQHBhcmFtIGVudW1lcmF0aW9uICAgSWYgdGhlIHR5cGUgaGFzIHRoZSB2YWx1ZSAiRU5VTUVSQVRJT04iIG9yCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgIk5PVEFUSU9OIiwgdGhpcyBhcnJheSBob2xkcyB0aGUgYWxsb3dlZCBhdHRyaWJ1dGUKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICB2YWx1ZXM7IG90aGVyd2lzZSwgdGhpcyBhcnJheSBpcyBudWxsLgotICAgICAqIEBwYXJhbSBkZWZhdWx0VHlwZSAgIFRoZSBhdHRyaWJ1dGUgZGVmYXVsdCB0eXBlLiBUaGlzIHZhbHVlIHdpbGwgYmUKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBvbmUgb2YgdGhlIGZvbGxvd2luZzogIiNGSVhFRCIsICIjSU1QTElFRCIsCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgIiNSRVFVSVJFRCIsIG9yIG51bGwuCi0gICAgICogQHBhcmFtIGRlZmF1bHRWYWx1ZSAgVGhlIGF0dHJpYnV0ZSBkZWZhdWx0IHZhbHVlLCBvciBudWxsIGlmIG5vCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdCB2YWx1ZSBpcyBzcGVjaWZpZWQuCi0gICAgICogQHBhcmFtIG5vbk5vcm1hbGl6ZWREZWZhdWx0VmFsdWUgIFRoZSBhdHRyaWJ1dGUgZGVmYXVsdCB2YWx1ZSB3aXRoIG5vIG5vcm1hbGl6YXRpb24KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBwZXJmb3JtZWQsIG9yIG51bGwgaWYgbm8gZGVmYXVsdCB2YWx1ZSBpcyBzcGVjaWZpZWQuCi0gICAgICogQHBhcmFtIGF1Z3MgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGF0dHJpYnV0ZURlY2woU3RyaW5nIGVsZW1lbnROYW1lLCBTdHJpbmcgYXR0cmlidXRlTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyB0eXBlLCBTdHJpbmdbXSBlbnVtZXJhdGlvbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBkZWZhdWx0VHlwZSwgWE1MU3RyaW5nIGRlZmF1bHRWYWx1ZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTFN0cmluZyBub25Ob3JtYWxpemVkRGVmYXVsdFZhbHVlLCBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotCi0gICAgICAgIGlmICh0eXBlICE9IFhNTFN5bWJvbHMuZkNEQVRBU3ltYm9sICYmIGRlZmF1bHRWYWx1ZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBub3JtYWxpemVEZWZhdWx0QXR0clZhbHVlKGRlZmF1bHRWYWx1ZSk7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoZlZhbGlkYXRpb24pIHsKLQotICAgICAgICAgICAgICAgIGJvb2xlYW4gZHVwbGljYXRlQXR0cmlidXRlRGVmID0gZmFsc2UgOwotCi0gICAgICAgICAgICAgICAgLy9HZXQgR3JhbW1hciBpbmRleCB0byBncmFtbWFyIGFycmF5Ci0gICAgICAgICAgICAgICAgRFRER3JhbW1hciBncmFtbWFyID0gKGZEVERHcmFtbWFyICE9IG51bGw/IGZEVERHcmFtbWFyOmZHcmFtbWFyQnVja2V0LmdldEFjdGl2ZUdyYW1tYXIoKSk7Ci0gICAgICAgICAgICAgICAgaW50IGVsZW1lbnRJbmRleCAgICAgICA9IGdyYW1tYXIuZ2V0RWxlbWVudERlY2xJbmRleCggZWxlbWVudE5hbWUpOwotICAgICAgICAgICAgICAgIGlmIChncmFtbWFyLmdldEF0dHJpYnV0ZURlY2xJbmRleChlbGVtZW50SW5kZXgsIGF0dHJpYnV0ZU5hbWUpICE9IC0xKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vbW9yZSB0aGFuIG9uZSBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpcyBwcm92aWRlZCBmb3IgdGhlIHNhbWUgYXR0cmlidXRlIG9mIGEgZ2l2ZW4gZWxlbWVudCB0eXBlLgotICAgICAgICAgICAgICAgICAgICBkdXBsaWNhdGVBdHRyaWJ1dGVEZWYgPSB0cnVlIDsKLQotICAgICAgICAgICAgICAgICAgICAvL3RoaXMgZmVhdHVyZSB3b3JrcyBvbmx5IHdoZW4gdmFsaWRhdGlvbiBpcyB0cnVlLgotICAgICAgICAgICAgICAgICAgICBpZihmV2FybkR1cGxpY2F0ZUF0dGRlZil7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmRXJyb3JSZXBvcnRlci5yZXBvcnRFcnJvcihYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1TR19EVVBMSUNBVEVfQVRUUklCVVRFX0RFRklOSVRJT04iLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXsgZWxlbWVudE5hbWUsIGF0dHJpYnV0ZU5hbWUgfSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxFcnJvclJlcG9ydGVyLlNFVkVSSVRZX1dBUk5JTkcgKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLQotCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgLy8gYSkgVkM6IE9uZSBJRCBwZXIgRWxlbWVudCBUeXBlLCBJZiBkdXBsaWNhdGUgSUQgYXR0cmlidXRlCi0gICAgICAgICAgICAvLyBiKSBWQzogSUQgYXR0cmlidXRlIERlZmF1bHQuIGlmIHRoZXJlIGlzIGEgZGVjbGFyZWFyZWQgYXR0cmlidXRlCi0gICAgICAgICAgICAvLyAgICAgICAgZGVmYXVsdCBmb3IgSUQgaXQgc2hvdWxkIGJlIG9mIHR5cGUgI0lNUExJRUQgb3IgI1JFUVVJUkVECi0gICAgICAgICAgICBpZiAodHlwZSA9PSBYTUxTeW1ib2xzLmZJRFN5bWJvbCkgewotICAgICAgICAgICAgICAgIGlmIChkZWZhdWx0VmFsdWUgIT0gbnVsbCAmJiBkZWZhdWx0VmFsdWUubGVuZ3RoICE9IDApIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGRlZmF1bHRUeXBlID09IG51bGwgfHwKLSAgICAgICAgICAgICAgICAgICAgICAgICEoZGVmYXVsdFR5cGUgPT0gWE1MU3ltYm9scy5mSU1QTElFRFN5bWJvbCB8fAotICAgICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0VHlwZSA9PSBYTUxTeW1ib2xzLmZSRVFVSVJFRFN5bWJvbCkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJJRERlZmF1bHRUeXBlSW52YWxpZCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117IGF0dHJpYnV0ZU5hbWV9LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9FUlJPUik7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBpZiAoIWZUYWJsZU9mSURBdHRyaWJ1dGVOYW1lcy5jb250YWluc0tleShlbGVtZW50TmFtZSkpIHsKLSAgICAgICAgICAgICAgICAgICAgZlRhYmxlT2ZJREF0dHJpYnV0ZU5hbWVzLnB1dChlbGVtZW50TmFtZSwgYXR0cmlidXRlTmFtZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgLy93ZSBzaG91bGQgbm90IHJlcG9ydCBhbiBlcnJvciwgd2hlbiB0aGVyZSBpcyBkdXBsaWNhdGUgYXR0cmlidXRlIGRlZmluaXRpb24gZm9yIGdpdmVuIGVsZW1lbnQgdHlwZQotICAgICAgICAgICAgICAgICAgICAgICAgLy9hY2NvcmRpbmcgdG8gWE1MIDEuMCBzcGVjLCBXaGVuIG1vcmUgdGhhbiBvbmUgZGVmaW5pdGlvbiBpcyBwcm92aWRlZCBmb3IgdGhlIHNhbWUgYXR0cmlidXRlIG9mIGEgZ2l2ZW4KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vZWxlbWVudCB0eXBlLCB0aGUgZmlyc3QgZGVjbGFyYXRpb24gaXMgYmluZGluZyBhbmQgbGF0ZXIgZGVjbGFyYXRpb24gYXJlICppZ25vcmVkKi4gU28gcHJvY2Vzc29yIHNob3VsZAotICAgICAgICAgICAgICAgICAgICAgICAgLy9pZ25vcmUgdGhlIHNlY29uZCBkZWNsYXJhdGlvbnMsIGhvd2V2ZXIgYW4gYXBwbGljYXRpb24gd291bGQgYmUgd2FybmVkIG9mIHRoZSBkdXBsaWNhdGUgYXR0cmlidXRlIGRlZmludGlvbgotICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWYgaHR0cDovL2FwYWNoZS5vcmcveG1sL2ZlYXR1cmVzL3ZhbGlkYXRpb24vd2Fybi1vbi1kdXBsaWNhdGUtYXR0ZGVmIGZlYXR1cmUgaXMgc2V0IHRvIHRydWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBvbmUgdHlwaWNhbCBjYXNlIHdoZXJlIHRoaXMgY291bGQgYmUgYSAgcHJvYmxlbSwgd2hlbiBhbnkgWE1MIGZpbGUKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIHByb3ZpZGUgdGhlIElEIHR5cGUgaW5mb3JtYXRpb24gdGhyb3VnaCBpbnRlcm5hbCBzdWJzZXQgc28gdGhhdCBpdCBpcyBhdmFpbGFibGUgdG8gdGhlIHBhcnNlciB3aGljaCByZWFkCi0gICAgICAgICAgICAgICAgICAgICAgICAvL29ubHkgaW50ZXJuYWwgc3Vic2V0LiBOb3cgdGhhdCBhdHRyaWJ1dGUgZGVjbGFyYXRpb24oSUQgVHlwZSkgY2FuIGFnYWluIGJlIHBhcnQgb2YgZXh0ZXJuYWwgcGFyc2VkIGVudGl0eQotICAgICAgICAgICAgICAgICAgICAgICAgLy9yZWZlcmVuY2VkLiBBdCB0aGF0IHRpbWUgaWYgcGFyc2VyIGRvZXNuJ3QgbWFrZSB0aGlzIGRpc3RpbmN0aW9uIGl0IHdpbGwgdGhyb3cgYW4gZXJyb3IgZm9yIFZDIE9uZSBJRCBwZXIKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vRWxlbWVudCBUeXBlLCB3aGljaCAoc2Vjb25kIGRlZmludGlvbikgYWN0dWFsbHkgc2hvdWxkIGJlIGlnbm9yZWQuIEFwcGxpY2F0aW9uIGJlaGF2aW9yIG1heSBkaWZmZXIgb24gdGhlCi0gICAgICAgICAgICAgICAgICAgICAgICAvL2Jhc2lzIG9mIGVycm9yIG9yIHdhcm5pbmcgdGhyb3duLiAtIG5iLgotCi0gICAgICAgICAgICAgICAgICAgICAgICBpZighZHVwbGljYXRlQXR0cmlidXRlRGVmKXsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHByZXZpb3VzSURBdHRyaWJ1dGVOYW1lID0gKFN0cmluZylmVGFibGVPZklEQXR0cmlidXRlTmFtZXMuZ2V0KCBlbGVtZW50TmFtZSApOy8vcnVsZSBhKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmRXJyb3JSZXBvcnRlci5yZXBvcnRFcnJvcihYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNU0dfTU9SRV9USEFOX09ORV9JRF9BVFRSSUJVVEUiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117IGVsZW1lbnROYW1lLCBwcmV2aW91c0lEQXR0cmlidXRlTmFtZSwgYXR0cmlidXRlTmFtZX0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTEVycm9yUmVwb3J0ZXIuU0VWRVJJVFlfRVJST1IpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIC8vICBWQzogT25lIE5vdGF0aW9uIFBlciBFbGVtZW50IFR5cGUsIHNob3VsZCBjaGVjayBpZiB0aGVyZSBpcyBhCi0gICAgICAgICAgICAvLyAgICAgIGR1cGxpY2F0ZSBOT1RBVElPTiBhdHRyaWJ1dGUKLQotICAgICAgICAgICAgaWYgKHR5cGUgPT0gWE1MU3ltYm9scy5mTk9UQVRJT05TeW1ib2wpIHsKLSAgICAgICAgICAgICAgICAvLyBWQzogTm90YXRpb24gQXR0cmlidXRlczogYWxsIG5vdGF0aW9uIG5hbWVzIGluIHRoZQotICAgICAgICAgICAgICAgIC8vICAgICAoYXR0cmlidXRlKSBkZWNsYXJhdGlvbiBtdXN0IGJlIGRlY2xhcmVkLgotICAgICAgICAgICAgICAgIGZvciAoaW50IGk9MDsgaTxlbnVtZXJhdGlvbi5sZW5ndGg7IGkrKykgewotICAgICAgICAgICAgICAgICAgICBmTm90YXRpb25FbnVtVmFscy5wdXQoZW51bWVyYXRpb25baV0sIGF0dHJpYnV0ZU5hbWUpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIGlmIChmVGFibGVPZk5PVEFUSU9OQXR0cmlidXRlTmFtZXMuY29udGFpbnNLZXkoIGVsZW1lbnROYW1lICkgPT0gZmFsc2UpIHsKLSAgICAgICAgICAgICAgICAgICAgZlRhYmxlT2ZOT1RBVElPTkF0dHJpYnV0ZU5hbWVzLnB1dCggZWxlbWVudE5hbWUsIGF0dHJpYnV0ZU5hbWUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vd2Ugc2hvdWxkIG5vdCByZXBvcnQgYW4gZXJyb3IsIHdoZW4gdGhlcmUgaXMgZHVwbGljYXRlIGF0dHJpYnV0ZSBkZWZpbml0aW9uIGZvciBnaXZlbiBlbGVtZW50IHR5cGUKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vYWNjb3JkaW5nIHRvIFhNTCAxLjAgc3BlYywgV2hlbiBtb3JlIHRoYW4gb25lIGRlZmluaXRpb24gaXMgcHJvdmlkZWQgZm9yIHRoZSBzYW1lIGF0dHJpYnV0ZSBvZiBhIGdpdmVuCi0gICAgICAgICAgICAgICAgICAgICAgICAvL2VsZW1lbnQgdHlwZSwgdGhlIGZpcnN0IGRlY2xhcmF0aW9uIGlzIGJpbmRpbmcgYW5kIGxhdGVyIGRlY2xhcmF0aW9uIGFyZSAqaWdub3JlZCouIFNvIHByb2Nlc3NvciBzaG91bGQKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vaWdub3JlIHRoZSBzZWNvbmQgZGVjbGFyYXRpb25zLCBob3dldmVyIGFuIGFwcGxpY2F0aW9uIHdvdWxkIGJlIHdhcm5lZCBvZiB0aGUgZHVwbGljYXRlIGF0dHJpYnV0ZSBkZWZpbml0aW9uCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBpZiBodHRwOi8vYXBhY2hlLm9yZy94bWwvZmVhdHVyZXMvdmFsaWRhdGlvbi93YXJuLW9uLWR1cGxpY2F0ZS1hdHRkZWYgZmVhdHVyZSBpcyBzZXQgdG8gdHJ1ZSwgQXBwbGljYXRpb24gYmVoYXZpb3IgbWF5IGRpZmZlciBvbiB0aGUgYmFzaXMgb2YgZXJyb3Igb3IKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vd2FybmluZyB0aHJvd24uIC0gbmIuCi0KLSAgICAgICAgICAgICAgICAgICAgICAgIGlmKCFkdXBsaWNhdGVBdHRyaWJ1dGVEZWYpewotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBwcmV2aW91c05PVEFUSU9OQXR0cmlidXRlTmFtZSA9IChTdHJpbmcpIGZUYWJsZU9mTk9UQVRJT05BdHRyaWJ1dGVOYW1lcy5nZXQoIGVsZW1lbnROYW1lICk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1TR19NT1JFX1RIQU5fT05FX05PVEFUSU9OX0FUVFJJQlVURSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXsgZWxlbWVudE5hbWUsIHByZXZpb3VzTk9UQVRJT05BdHRyaWJ1dGVOYW1lLCBhdHRyaWJ1dGVOYW1lfSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9FUlJPUik7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gVkM6IE5vIER1cGxpY2F0ZSBUb2tlbnMKLSAgICAgICAgICAgIC8vIFhNTCAxLjAgU0UgRXJyYXRhIC0gRTIKLSAgICAgICAgICAgIGlmICh0eXBlID09IFhNTFN5bWJvbHMuZkVOVU1FUkFUSU9OU3ltYm9sIHx8IHR5cGUgPT0gWE1MU3ltYm9scy5mTk9UQVRJT05TeW1ib2wpIHsKLSAgICAgICAgICAgICAgICBvdXRlcjoKLSAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBlbnVtZXJhdGlvbi5sZW5ndGg7ICsraSkgewotICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaiA9IGkgKyAxOyBqIDwgZW51bWVyYXRpb24ubGVuZ3RoOyArK2opIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZW51bWVyYXRpb25baV0uZXF1YWxzKGVudW1lcmF0aW9uW2pdKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPbmx5IHJlcG9ydCB0aGUgZmlyc3QgdW5pcXVlbmVzcyB2aW9sYXRpb24uIFRoZXJlIGNvdWxkIGJlIG90aGVycywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYnV0IGFkZGl0aW9uYWwgb3ZlcmhlYWQgd291bGQgYmUgaW5jdXJyZWQgdHJhY2tpbmcgdW5pcXVlIHRva2VucwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGF0IGhhdmUgYWxyZWFkeSBiZWVuIGVuY291bnRlcmVkLiAtLSBtcmdsYXZhcwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmRXJyb3JSZXBvcnRlci5yZXBvcnRFcnJvcihYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUgPT0gWE1MU3ltYm9scy5mRU5VTUVSQVRJT05TeW1ib2wKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gIk1TR19ESVNUSU5DVF9UT0tFTlNfSU5fRU5VTUVSQVRJT04iCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6ICJNU0dfRElTVElOQ1RfTk9UQVRJT05fSU5fRU5VTUVSQVRJT04iLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117IGVsZW1lbnROYW1lLCBlbnVtZXJhdGlvbltpXSwgYXR0cmlidXRlTmFtZSB9LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxFcnJvclJlcG9ydGVyLlNFVkVSSVRZX0VSUk9SKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWsgb3V0ZXI7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIFZDOiBBdHRyaWJ1dGUgRGVmYXVsdCBMZWdhbAotICAgICAgICAgICAgYm9vbGVhbiBvayA9IHRydWU7Ci0gICAgICAgICAgICBpZiAoZGVmYXVsdFZhbHVlICE9IG51bGwgJiYKLSAgICAgICAgICAgICAgICAoZGVmYXVsdFR5cGUgPT0gbnVsbCB8fAotICAgICAgICAgICAgICAgICAoZGVmYXVsdFR5cGUgIT0gbnVsbCAmJiBkZWZhdWx0VHlwZSA9PSBYTUxTeW1ib2xzLmZGSVhFRFN5bWJvbCkpKSB7Ci0KLSAgICAgICAgICAgICAgICBTdHJpbmcgdmFsdWUgPSBkZWZhdWx0VmFsdWUudG9TdHJpbmcoKTsKLSAgICAgICAgICAgICAgICBpZiAodHlwZSA9PSBYTUxTeW1ib2xzLmZOTVRPS0VOU1N5bWJvbCB8fAotICAgICAgICAgICAgICAgICAgICB0eXBlID09IFhNTFN5bWJvbHMuZkVOVElUSUVTU3ltYm9sIHx8Ci0gICAgICAgICAgICAgICAgICAgIHR5cGUgPT0gWE1MU3ltYm9scy5mSURSRUZTU3ltYm9sKSB7Ci0KLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nVG9rZW5pemVyIHRva2VuaXplciA9IG5ldyBTdHJpbmdUb2tlbml6ZXIodmFsdWUsIiAiKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKHRva2VuaXplci5oYXNNb3JlVG9rZW5zKCkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlICh0cnVlKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG5tdG9rZW4gPSB0b2tlbml6ZXIubmV4dFRva2VuKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGUgPT0gWE1MU3ltYm9scy5mTk1UT0tFTlNTeW1ib2wpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFpc1ZhbGlkTm10b2tlbihubXRva2VuKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2sgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGUgPT0gWE1MU3ltYm9scy5mRU5USVRJRVNTeW1ib2wgfHwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlID09IFhNTFN5bWJvbHMuZklEUkVGU1N5bWJvbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWlzVmFsaWROYW1lKG5tdG9rZW4pKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvayA9IGZhbHNlOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF0b2tlbml6ZXIuaGFzTW9yZVRva2VucygpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICBpZiAodHlwZSA9PSBYTUxTeW1ib2xzLmZFTlRJVFlTeW1ib2wgfHwKLSAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUgPT0gWE1MU3ltYm9scy5mSURTeW1ib2wgfHwKLSAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUgPT0gWE1MU3ltYm9scy5mSURSRUZTeW1ib2wgfHwKLSAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUgPT0gWE1MU3ltYm9scy5mTk9UQVRJT05TeW1ib2wpIHsKLQotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFpc1ZhbGlkTmFtZSh2YWx1ZSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBvayA9IGZhbHNlOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAodHlwZSA9PSBYTUxTeW1ib2xzLmZOTVRPS0VOU3ltYm9sIHx8Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUgPT0gWE1MU3ltYm9scy5mRU5VTUVSQVRJT05TeW1ib2wpIHsKLQotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFpc1ZhbGlkTm10b2tlbih2YWx1ZSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBvayA9IGZhbHNlOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGUgPT0gWE1MU3ltYm9scy5mTk9UQVRJT05TeW1ib2wgfHwKLSAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUgPT0gWE1MU3ltYm9scy5mRU5VTUVSQVRJT05TeW1ib2wpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIG9rID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpPTA7IGk8ZW51bWVyYXRpb24ubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGVmYXVsdFZhbHVlLmVxdWFscyhlbnVtZXJhdGlvbltpXSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2sgPSB0cnVlOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGlmICghb2spIHsKLSAgICAgICAgICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTVNHX0FUVF9ERUZBVUxUX0lOVkFMSUQiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117YXR0cmlidXRlTmFtZSwgdmFsdWV9LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxFcnJvclJlcG9ydGVyLlNFVkVSSVRZX0VSUk9SKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBjYWxsIGhhbmRsZXJzCi0gICAgICAgIGlmKGZEVERHcmFtbWFyICE9IG51bGwpCi0gICAgICAgICAgICBmRFRER3JhbW1hci5hdHRyaWJ1dGVEZWNsKGVsZW1lbnROYW1lLCBhdHRyaWJ1dGVOYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUsIGVudW1lcmF0aW9uLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRUeXBlLCBkZWZhdWx0VmFsdWUsIG5vbk5vcm1hbGl6ZWREZWZhdWx0VmFsdWUsIGF1Z3MpOwotICAgICAgICBpZiAoZkRUREhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkRUREhhbmRsZXIuYXR0cmlidXRlRGVjbChlbGVtZW50TmFtZSwgYXR0cmlidXRlTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZSwgZW51bWVyYXRpb24sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRUeXBlLCBkZWZhdWx0VmFsdWUsIG5vbk5vcm1hbGl6ZWREZWZhdWx0VmFsdWUsIGF1Z3MpOwotICAgICAgICB9Ci0KLSAgICB9IC8vIGF0dHJpYnV0ZURlY2woU3RyaW5nLFN0cmluZyxTdHJpbmcsU3RyaW5nW10sU3RyaW5nLFhNTFN0cmluZywgWE1MU3RyaW5nLCBBdWdtZW50YXRpb25zKQotCi0gICAgLyoqCi0gICAgICogVGhlIGVuZCBvZiBhbiBhdHRyaWJ1dGUgbGlzdC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBhdWdzIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbmRBdHRsaXN0KEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy8gY2FsbCBoYW5kbGVycwotICAgICAgICBpZihmRFRER3JhbW1hciAhPSBudWxsKQotICAgICAgICAgICAgZkRUREdyYW1tYXIuZW5kQXR0bGlzdChhdWdzKTsKLSAgICAgICAgaWYgKGZEVERIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZEVERIYW5kbGVyLmVuZEF0dGxpc3QoYXVncyk7Ci0gICAgICAgIH0KLQotICAgIH0gLy8gZW5kQXR0bGlzdCgpCi0KLSAgICAvKioKLSAgICAgKiBBbiBpbnRlcm5hbCBlbnRpdHkgZGVjbGFyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgZW50aXR5LiBQYXJhbWV0ZXIgZW50aXR5IG5hbWVzIHN0YXJ0IHdpdGgKLSAgICAgKiAgICAgICAgICAgICAnJScsIHdoZXJlYXMgdGhlIG5hbWUgb2YgYSBnZW5lcmFsIGVudGl0eSBpcyBqdXN0IHRoZQotICAgICAqICAgICAgICAgICAgIGVudGl0eSBuYW1lLgotICAgICAqIEBwYXJhbSB0ZXh0IFRoZSB2YWx1ZSBvZiB0aGUgZW50aXR5LgotICAgICAqIEBwYXJhbSBub25Ob3JtYWxpemVkVGV4dCBUaGUgbm9uLW5vcm1hbGl6ZWQgdmFsdWUgb2YgdGhlIGVudGl0eS4gVGhpcwotICAgICAqICAgICAgICAgICAgIHZhbHVlIGNvbnRhaW5zIHRoZSBzYW1lIHNlcXVlbmNlIG9mIGNoYXJhY3RlcnMgdGhhdCB3YXMgaW4KLSAgICAgKiAgICAgICAgICAgICB0aGUgaW50ZXJuYWwgZW50aXR5IGRlY2xhcmF0aW9uLCB3aXRob3V0IGFueSBlbnRpdHkKLSAgICAgKiAgICAgICAgICAgICByZWZlcmVuY2VzIGV4cGFuZGVkLgotICAgICAqIEBwYXJhbSBhdWdzIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBpbnRlcm5hbEVudGl0eURlY2woU3RyaW5nIG5hbWUsIFhNTFN0cmluZyB0ZXh0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxTdHJpbmcgbm9uTm9ybWFsaXplZFRleHQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgRFRER3JhbW1hciBncmFtbWFyID0gKGZEVERHcmFtbWFyICE9IG51bGw/IGZEVERHcmFtbWFyOiBmR3JhbW1hckJ1Y2tldC5nZXRBY3RpdmVHcmFtbWFyKCkpOwotICAgICAgICBpbnQgaW5kZXggPSBncmFtbWFyLmdldEVudGl0eURlY2xJbmRleChuYW1lKSA7Ci0KLSAgICAgICAgLy9JZiB0aGUgc2FtZSBlbnRpdHkgaXMgZGVjbGFyZWQgbW9yZSB0aGFuIG9uY2UsIHRoZSBmaXJzdCBkZWNsYXJhdGlvbgotICAgICAgICAvL2VuY291bnRlcmVkIGlzIGJpbmRpbmcsIFNBWCByZXF1aXJlcyBvbmx5IGVmZmVjdGl2ZShmaXJzdCkgZGVjbGFyYXRpb24KLSAgICAgICAgLy90byBiZSByZXBvcnRlZCB0byB0aGUgYXBwbGljYXRpb24KLQotICAgICAgICAvL1JFVklTSVQ6IERvZXMgaXQgbWFrZSBzZW5zZSB0byBwYXNzIGR1cGxpY2F0ZSBFbnRpdHkgaW5mb3JtYXRpb24gYWNyb3NzCi0gICAgICAgIC8vdGhlIHBpcGVsaW5lIC0tIG5iPwotCi0gICAgICAgIC8vaXRzIGEgbmV3IGVudGl0eSBhbmQgaGFzbid0IGJlZW4gZGVjbGFyZWQuCi0gICAgICAgIGlmKGluZGV4ID09IC0xKXsKLSAgICAgICAgICAgIC8vc3RvcmUgaW50ZXJuYWwgZW50aXR5IGRlY2xhcmF0aW9uIGluIGdyYW1tYXIKLSAgICAgICAgICAgIGlmKGZEVERHcmFtbWFyICE9IG51bGwpCi0gICAgICAgICAgICAgICAgZkRUREdyYW1tYXIuaW50ZXJuYWxFbnRpdHlEZWNsKG5hbWUsIHRleHQsIG5vbk5vcm1hbGl6ZWRUZXh0LCBhdWdzKTsKLSAgICAgICAgICAgIC8vIGNhbGwgaGFuZGxlcnMKLSAgICAgICAgICAgIGlmIChmRFRESGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZkRUREhhbmRsZXIuaW50ZXJuYWxFbnRpdHlEZWNsKG5hbWUsIHRleHQsIG5vbk5vcm1hbGl6ZWRUZXh0LCBhdWdzKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgfSAvLyBpbnRlcm5hbEVudGl0eURlY2woU3RyaW5nLFhNTFN0cmluZyxYTUxTdHJpbmcpCi0KLQotICAgIC8qKgotICAgICAqIEFuIGV4dGVybmFsIGVudGl0eSBkZWNsYXJhdGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lICAgICBUaGUgbmFtZSBvZiB0aGUgZW50aXR5LiBQYXJhbWV0ZXIgZW50aXR5IG5hbWVzIHN0YXJ0Ci0gICAgICogICAgICAgICAgICAgICAgIHdpdGggJyUnLCB3aGVyZWFzIHRoZSBuYW1lIG9mIGEgZ2VuZXJhbCBlbnRpdHkgaXMganVzdAotICAgICAqICAgICAgICAgICAgICAgICB0aGUgZW50aXR5IG5hbWUuCi0gICAgICogQHBhcmFtIGlkZW50aWZpZXIgICAgQW4gb2JqZWN0IGNvbnRhaW5pbmcgYWxsIGxvY2F0aW9uIGluZm9ybWF0aW9uCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgcGVydGluZW50IHRvIHRoaXMgZXh0ZXJuYWwgZW50aXR5LgotICAgICAqIEBwYXJhbSBhdWdzIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBleHRlcm5hbEVudGl0eURlY2woU3RyaW5nIG5hbWUsIFhNTFJlc291cmNlSWRlbnRpZmllciBpZGVudGlmaWVyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotCi0gICAgICAgIERUREdyYW1tYXIgZ3JhbW1hciA9IChmRFRER3JhbW1hciAhPSBudWxsPyBmRFRER3JhbW1hcjogIGZHcmFtbWFyQnVja2V0LmdldEFjdGl2ZUdyYW1tYXIoKSk7Ci0gICAgICAgIGludCBpbmRleCA9IGdyYW1tYXIuZ2V0RW50aXR5RGVjbEluZGV4KG5hbWUpIDsKLQotICAgICAgICAvL0lmIHRoZSBzYW1lIGVudGl0eSBpcyBkZWNsYXJlZCBtb3JlIHRoYW4gb25jZSwgdGhlIGZpcnN0IGRlY2xhcmF0aW9uCi0gICAgICAgIC8vZW5jb3VudGVyZWQgaXMgYmluZGluZywgU0FYIHJlcXVpcmVzIG9ubHkgZWZmZWN0aXZlKGZpcnN0KSBkZWNsYXJhdGlvbgotICAgICAgICAvL3RvIGJlIHJlcG9ydGVkIHRvIHRoZSBhcHBsaWNhdGlvbgotCi0gICAgICAgIC8vUkVWSVNJVDogRG9lcyBpdCBtYWtlIHNlbnNlIHRvIHBhc3MgZHVwbGljYXRlIGVudGl0eSBpbmZvcm1hdGlvbiBhY3Jvc3MKLSAgICAgICAgLy90aGUgcGlwZWxpbmUgLS0gbmI/Ci0KLSAgICAgICAgLy9pdHMgYSBuZXcgZW50aXR5IGFuZCBoYXNuJ3QgYmVlbiBkZWNsYXJlZC4KLSAgICAgICAgaWYoaW5kZXggPT0gLTEpewotICAgICAgICAgICAgLy9zdG9yZSBleHRlcm5hbCBlbnRpdHkgZGVjbGFyYXRpb24gaW4gZ3JhbW1hcgotICAgICAgICAgICAgaWYoZkRUREdyYW1tYXIgIT0gbnVsbCkKLSAgICAgICAgICAgICAgICBmRFRER3JhbW1hci5leHRlcm5hbEVudGl0eURlY2wobmFtZSwgaWRlbnRpZmllciwgYXVncyk7Ci0gICAgICAgICAgICAvLyBjYWxsIGhhbmRsZXJzCi0gICAgICAgICAgICBpZiAoZkRUREhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZEVERIYW5kbGVyLmV4dGVybmFsRW50aXR5RGVjbChuYW1lLCBpZGVudGlmaWVyLCBhdWdzKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgfSAvLyBleHRlcm5hbEVudGl0eURlY2woU3RyaW5nLFhNTFJlc291cmNlSWRlbnRpZmllciwgQXVnbWVudGF0aW9ucykKLQotICAgIC8qKgotICAgICAqIEFuIHVucGFyc2VkIGVudGl0eSBkZWNsYXJhdGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lICAgICBUaGUgbmFtZSBvZiB0aGUgZW50aXR5LgotICAgICAqIEBwYXJhbSBpZGVudGlmaWVyICAgIEFuIG9iamVjdCBjb250YWluaW5nIGFsbCBsb2NhdGlvbiBpbmZvcm1hdGlvbgotICAgICAqICAgICAgICAgICAgICAgICAgICAgIHBlcnRpbmVudCB0byB0aGlzIGVudGl0eS4KLSAgICAgKiBAcGFyYW0gbm90YXRpb24gVGhlIG5hbWUgb2YgdGhlIG5vdGF0aW9uLgotICAgICAqIEBwYXJhbSBhdWdzIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB1bnBhcnNlZEVudGl0eURlY2woU3RyaW5nIG5hbWUsIFhNTFJlc291cmNlSWRlbnRpZmllciBpZGVudGlmaWVyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbm90YXRpb24sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy8gVkM6IE5vdGF0aW9uIGRlY2xhcmVkLCAgaW4gdGhlIHByb2R1Y3Rpb24gb2YgTkRhdGFEZWNsCi0gICAgICAgIGlmIChmVmFsaWRhdGlvbikgewotICAgICAgICAgICAgZk5EYXRhRGVjbE5vdGF0aW9ucy5wdXQobmFtZSwgbm90YXRpb24pOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gY2FsbCBoYW5kbGVycwotICAgICAgICBpZihmRFRER3JhbW1hciAhPSBudWxsKQotICAgICAgICAgICAgZkRUREdyYW1tYXIudW5wYXJzZWRFbnRpdHlEZWNsKG5hbWUsIGlkZW50aWZpZXIsIG5vdGF0aW9uLCBhdWdzKTsKLSAgICAgICAgaWYgKGZEVERIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZEVERIYW5kbGVyLnVucGFyc2VkRW50aXR5RGVjbChuYW1lLCBpZGVudGlmaWVyLCBub3RhdGlvbiwgYXVncyk7Ci0gICAgICAgIH0KLQotICAgIH0gLy8gdW5wYXJzZWRFbnRpdHlEZWNsKFN0cmluZyxYTUxSZXNvdXJjZUlkZW50aWZpZXIsU3RyaW5nLEF1Z21lbnRhdGlvbnMpCi0KLSAgICAvKioKLSAgICAgKiBBIG5vdGF0aW9uIGRlY2xhcmF0aW9uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSAgICAgVGhlIG5hbWUgb2YgdGhlIG5vdGF0aW9uLgotICAgICAqIEBwYXJhbSBpZGVudGlmaWVyICAgIEFuIG9iamVjdCBjb250YWluaW5nIGFsbCBsb2NhdGlvbiBpbmZvcm1hdGlvbgotICAgICAqICAgICAgICAgICAgICAgICAgICAgIHBlcnRpbmVudCB0byB0aGlzIG5vdGF0aW9uLgotICAgICAqIEBwYXJhbSBhdWdzIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBub3RhdGlvbkRlY2woU3RyaW5nIG5hbWUsIFhNTFJlc291cmNlSWRlbnRpZmllciBpZGVudGlmaWVyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotCi0gICAgICAgIC8vIFZDOiBVbmlxdWUgTm90YXRpb24gTmFtZQotICAgICAgICBpZiAoZlZhbGlkYXRpb24pIHsKLSAgICAgICAgICAgIERUREdyYW1tYXIgZ3JhbW1hciA9IChmRFRER3JhbW1hciAhPSBudWxsID8gZkRUREdyYW1tYXIgOiBmR3JhbW1hckJ1Y2tldC5nZXRBY3RpdmVHcmFtbWFyKCkpOwotICAgICAgICAgICAgaWYgKGdyYW1tYXIuZ2V0Tm90YXRpb25EZWNsSW5kZXgobmFtZSkgIT0gLTEpIHsKLSAgICAgICAgICAgICAgICBmRXJyb3JSZXBvcnRlci5yZXBvcnRFcnJvcihYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlVuaXF1ZU5vdGF0aW9uTmFtZSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde25hbWV9LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTEVycm9yUmVwb3J0ZXIuU0VWRVJJVFlfRVJST1IpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gY2FsbCBoYW5kbGVycwotICAgICAgICBpZihmRFRER3JhbW1hciAhPSBudWxsKQotICAgICAgICAgICAgZkRUREdyYW1tYXIubm90YXRpb25EZWNsKG5hbWUsIGlkZW50aWZpZXIsIGF1Z3MpOwotICAgICAgICBpZiAoZkRUREhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkRUREhhbmRsZXIubm90YXRpb25EZWNsKG5hbWUsIGlkZW50aWZpZXIsIGF1Z3MpOwotICAgICAgICB9Ci0KLSAgICB9IC8vIG5vdGF0aW9uRGVjbChTdHJpbmcsWE1MUmVzb3VyY2VJZGVudGlmaWVyLCBBdWdtZW50YXRpb25zKQotCi0gICAgLyoqCi0gICAgICogVGhlIHN0YXJ0IG9mIGEgY29uZGl0aW9uYWwgc2VjdGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSB0eXBlIFRoZSB0eXBlIG9mIHRoZSBjb25kaXRpb25hbCBzZWN0aW9uLiBUaGlzIHZhbHVlIHdpbGwKLSAgICAgKiAgICAgICAgICAgICBlaXRoZXIgYmUgQ09ORElUSU9OQUxfSU5DTFVERSBvciBDT05ESVRJT05BTF9JR05PUkUuCi0gICAgICogQHBhcmFtIGF1Z3MgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqCi0gICAgICogQHNlZSAjQ09ORElUSU9OQUxfSU5DTFVERQotICAgICAqIEBzZWUgI0NPTkRJVElPTkFMX0lHTk9SRQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0Q29uZGl0aW9uYWwoc2hvcnQgdHlwZSwgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLQotICAgICAgICAvLyBzZXQgc3RhdGUKLSAgICAgICAgZkluRFRESWdub3JlID0gdHlwZSA9PSBYTUxEVERIYW5kbGVyLkNPTkRJVElPTkFMX0lHTk9SRTsKLQotICAgICAgICAvLyBjYWxsIGhhbmRsZXJzCi0gICAgICAgIGlmKGZEVERHcmFtbWFyICE9IG51bGwpCi0gICAgICAgICAgICBmRFRER3JhbW1hci5zdGFydENvbmRpdGlvbmFsKHR5cGUsIGF1Z3MpOwotICAgICAgICBpZiAoZkRUREhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkRUREhhbmRsZXIuc3RhcnRDb25kaXRpb25hbCh0eXBlLCBhdWdzKTsKLSAgICAgICAgfQotCi0gICAgfSAvLyBzdGFydENvbmRpdGlvbmFsKHNob3J0KQotCi0gICAgLyoqCi0gICAgICogVGhlIGVuZCBvZiBhIGNvbmRpdGlvbmFsIHNlY3Rpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYXVncyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kQ29uZGl0aW9uYWwoQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLQotICAgICAgICAvLyBzZXQgc3RhdGUKLSAgICAgICAgZkluRFRESWdub3JlID0gZmFsc2U7Ci0KLSAgICAgICAgLy8gY2FsbCBoYW5kbGVycwotICAgICAgICBpZihmRFRER3JhbW1hciAhPSBudWxsKQotICAgICAgICAgICAgZkRUREdyYW1tYXIuZW5kQ29uZGl0aW9uYWwoYXVncyk7Ci0gICAgICAgIGlmIChmRFRESGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmRFRESGFuZGxlci5lbmRDb25kaXRpb25hbChhdWdzKTsKLSAgICAgICAgfQotCi0gICAgfSAvLyBlbmRDb25kaXRpb25hbCgpCi0KLSAgICAvKioKLSAgICAgKiBUaGUgZW5kIG9mIHRoZSBEVEQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYXVncyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kRFREKEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLQotICAgICAgICAvLyBzYXZlIGdyYW1tYXIKLSAgICAgICAgaWYoZkRUREdyYW1tYXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkRUREdyYW1tYXIuZW5kRFREKGF1Z3MpOwotICAgICAgICAgICAgaWYoZkdyYW1tYXJQb29sICE9IG51bGwpCi0gICAgICAgICAgICAgICAgZkdyYW1tYXJQb29sLmNhY2hlR3JhbW1hcnMoWE1MR3JhbW1hckRlc2NyaXB0aW9uLlhNTF9EVEQsIG5ldyBHcmFtbWFyW10ge2ZEVERHcmFtbWFyfSk7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGZWYWxpZGF0aW9uKSB7Ci0gICAgICAgICAgICBEVERHcmFtbWFyIGdyYW1tYXIgPSAoZkRUREdyYW1tYXIgIT0gbnVsbD8gZkRUREdyYW1tYXI6IGZHcmFtbWFyQnVja2V0LmdldEFjdGl2ZUdyYW1tYXIoKSk7Ci0KLSAgICAgICAgICAgIC8vIFZDIDogTm90YXRpb24gRGVjbGFyZWQuIGZvciBleHRlcm5hbCBlbnRpdHkgZGVjbGFyYXRpb24gW1Byb2R1Y3Rpb24gNzZdLgotICAgICAgICAgICAgSXRlcmF0b3IgZW50aXRpZXMgPSBmTkRhdGFEZWNsTm90YXRpb25zLmVudHJ5U2V0KCkuaXRlcmF0b3IoKTsKLSAgICAgICAgICAgIHdoaWxlIChlbnRpdGllcy5oYXNOZXh0KCkpIHsKLSAgICAgICAgICAgICAgICBNYXAuRW50cnkgZW50cnkgPSAoTWFwLkVudHJ5KSBlbnRpdGllcy5uZXh0KCk7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIG5vdGF0aW9uID0gKFN0cmluZykgZW50cnkuZ2V0VmFsdWUoKTsKLSAgICAgICAgICAgICAgICBpZiAoZ3JhbW1hci5nZXROb3RhdGlvbkRlY2xJbmRleChub3RhdGlvbikgPT0gLTEpIHsKLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGVudGl0eSA9IChTdHJpbmcpIGVudHJ5LmdldEtleSgpOwotICAgICAgICAgICAgICAgICAgICBmRXJyb3JSZXBvcnRlci5yZXBvcnRFcnJvcihYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNU0dfTk9UQVRJT05fTk9UX0RFQ0xBUkVEX0ZPUl9VTlBBUlNFRF9FTlRJVFlERUNMIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde2VudGl0eSwgbm90YXRpb259LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxFcnJvclJlcG9ydGVyLlNFVkVSSVRZX0VSUk9SKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIFZDOiBOb3RhdGlvbiBBdHRyaWJ1dGVzOgotICAgICAgICAgICAgLy8gICAgIGFsbCBub3RhdGlvbiBuYW1lcyBpbiB0aGUgKGF0dHJpYnV0ZSkgZGVjbGFyYXRpb24gbXVzdCBiZSBkZWNsYXJlZC4KLSAgICAgICAgICAgIEl0ZXJhdG9yIG5vdGF0aW9uVmFscyA9IGZOb3RhdGlvbkVudW1WYWxzLmVudHJ5U2V0KCkuaXRlcmF0b3IoKTsKLSAgICAgICAgICAgIHdoaWxlIChub3RhdGlvblZhbHMuaGFzTmV4dCgpKSB7Ci0gICAgICAgICAgICAgICAgTWFwLkVudHJ5IGVudHJ5ID0gKE1hcC5FbnRyeSkgbm90YXRpb25WYWxzLm5leHQoKTsKLSAgICAgICAgICAgICAgICBTdHJpbmcgbm90YXRpb24gPSAoU3RyaW5nKSBlbnRyeS5nZXRLZXkoKTsKLSAgICAgICAgICAgICAgICBpZiAoZ3JhbW1hci5nZXROb3RhdGlvbkRlY2xJbmRleChub3RhdGlvbikgPT0gLTEpIHsKLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGF0dHJpYnV0ZU5hbWUgPSAoU3RyaW5nKSBlbnRyeS5nZXRWYWx1ZSgpOwotICAgICAgICAgICAgICAgICAgICBmRXJyb3JSZXBvcnRlci5yZXBvcnRFcnJvcihYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNU0dfTk9UQVRJT05fTk9UX0RFQ0xBUkVEX0ZPUl9OT1RBVElPTlRZUEVfQVRUUklCVVRFIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde2F0dHJpYnV0ZU5hbWUsIG5vdGF0aW9ufSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9FUlJPUik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBWQzogTm8gTm90YXRpb24gb24gRW1wdHkgRWxlbWVudAotICAgICAgICAgICAgLy8gQW4gYXR0cmlidXRlIG9mIHR5cGUgTk9UQVRJT04gbXVzdCBub3QgYmUgZGVjbGFyZWQgb24gYW4gZWxlbWVudCBkZWNsYXJlZCBFTVBUWS4KLSAgICAgICAgICAgIEl0ZXJhdG9yIGVsZW1lbnRzV2l0aE5vdGF0aW9ucyA9IGZUYWJsZU9mTk9UQVRJT05BdHRyaWJ1dGVOYW1lcy5lbnRyeVNldCgpLml0ZXJhdG9yKCk7Ci0gICAgICAgICAgICB3aGlsZSAoZWxlbWVudHNXaXRoTm90YXRpb25zLmhhc05leHQoKSkgewotICAgICAgICAgICAgICAgIE1hcC5FbnRyeSBlbnRyeSA9IChNYXAuRW50cnkpIGVsZW1lbnRzV2l0aE5vdGF0aW9ucy5uZXh0KCk7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIGVsZW1lbnROYW1lID0gKFN0cmluZykgZW50cnkuZ2V0S2V5KCk7Ci0gICAgICAgICAgICAgICAgaW50IGVsZW1lbnRJbmRleCA9IGdyYW1tYXIuZ2V0RWxlbWVudERlY2xJbmRleChlbGVtZW50TmFtZSk7Ci0gICAgICAgICAgICAgICAgaWYgKGdyYW1tYXIuZ2V0Q29udGVudFNwZWNUeXBlKGVsZW1lbnRJbmRleCkgPT0gWE1MRWxlbWVudERlY2wuVFlQRV9FTVBUWSkgewotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgYXR0cmlidXRlTmFtZSA9IChTdHJpbmcpIGVudHJ5LmdldFZhbHVlKCk7Ci0gICAgICAgICAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5vTm90YXRpb25PbkVtcHR5RWxlbWVudCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXtlbGVtZW50TmFtZSwgYXR0cmlidXRlTmFtZX0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTEVycm9yUmVwb3J0ZXIuU0VWRVJJVFlfRVJST1IpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gc2hvdWxkIGJlIHNhZmUgdG8gcmVsZWFzZSB0aGVzZSByZWZlcmVuY2VzCi0gICAgICAgICAgICBmVGFibGVPZklEQXR0cmlidXRlTmFtZXMgPSBudWxsOwotICAgICAgICAgICAgZlRhYmxlT2ZOT1RBVElPTkF0dHJpYnV0ZU5hbWVzID0gbnVsbDsKLQotICAgICAgICAgICAgLy8gY2hlY2sgd2hldGhlciBlYWNoIGVsZW1lbnQgcmVmZXJlbmNlZCBpbiBhIGNvbnRlbnQgbW9kZWwgaXMgZGVjbGFyZWQKLSAgICAgICAgICAgIGlmIChmV2Fybk9uVW5kZWNsYXJlZEVsZW1kZWYpIHsKLSAgICAgICAgICAgICAgICBjaGVja0RlY2xhcmVkRWxlbWVudHMoZ3JhbW1hcik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBjYWxsIGhhbmRsZXJzCi0gICAgICAgIGlmIChmRFRESGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmRFRESGFuZGxlci5lbmREVEQoYXVncyk7Ci0gICAgICAgIH0KLQotICAgIH0gLy8gZW5kRFREKCkKLQotICAgIC8vIHNldHMgdGhlIFhNTERURFNvdXJjZSBvZiB0aGlzIGhhbmRsZXIKLSAgICBwdWJsaWMgdm9pZCBzZXREVERTb3VyY2UoWE1MRFREU291cmNlIHNvdXJjZSApIHsKLSAgICAgICAgZkRURFNvdXJjZSA9IHNvdXJjZTsKLSAgICB9IC8vIHNldERURFNvdXJjZShYTUxEVERTb3VyY2UpCi0KLSAgICAvLyByZXR1cm5zIHRoZSBYTUxEVERTb3VyY2Ugb2YgdGhpcyBoYW5kbGVyCi0gICAgcHVibGljIFhNTERURFNvdXJjZSBnZXREVERTb3VyY2UoKSB7Ci0gICAgICAgIHJldHVybiBmRFREU291cmNlOwotICAgIH0gLy8gZ2V0RFREU291cmNlKCk6ICBYTUxEVERTb3VyY2UKLQotICAgIC8vCi0gICAgLy8gWE1MRFREQ29udGVudE1vZGVsSGFuZGxlciBtZXRob2RzCi0gICAgLy8KLQotICAgIC8vIHNldHMgdGhlIFhNTENvbnRlbnRNb2RlbERURFNvdXJjZSBvZiB0aGlzIGhhbmRsZXIKLSAgICBwdWJsaWMgdm9pZCBzZXREVERDb250ZW50TW9kZWxTb3VyY2UoWE1MRFREQ29udGVudE1vZGVsU291cmNlIHNvdXJjZSApIHsKLSAgICAgICAgZkRURENvbnRlbnRNb2RlbFNvdXJjZSA9IHNvdXJjZTsKLSAgICB9IC8vIHNldERURENvbnRlbnRNb2RlbFNvdXJjZShYTUxEVERDb250ZW50TW9kZWxTb3VyY2UpCi0KLSAgICAvLyByZXR1cm5zIHRoZSBYTUxEVERTb3VyY2Ugb2YgdGhpcyBoYW5kbGVyCi0gICAgcHVibGljIFhNTERURENvbnRlbnRNb2RlbFNvdXJjZSBnZXREVERDb250ZW50TW9kZWxTb3VyY2UoKSB7Ci0gICAgICAgIHJldHVybiBmRFREQ29udGVudE1vZGVsU291cmNlOwotICAgIH0gLy8gZ2V0RFREQ29udGVudE1vZGVsU291cmNlKCk6ICBYTUxEVERDb250ZW50TW9kZWxTb3VyY2UKLQotCi0gICAgLyoqCi0gICAgICogVGhlIHN0YXJ0IG9mIGEgY29udGVudCBtb2RlbC4gRGVwZW5kaW5nIG9uIHRoZSB0eXBlIG9mIHRoZSBjb250ZW50Ci0gICAgICogbW9kZWwsIHNwZWNpZmljIG1ldGhvZHMgbWF5IGJlIGNhbGxlZCBiZXR3ZWVuIHRoZSBjYWxsIHRvIHRoZQotICAgICAqIHN0YXJ0Q29udGVudE1vZGVsIG1ldGhvZCBhbmQgdGhlIGNhbGwgdG8gdGhlIGVuZENvbnRlbnRNb2RlbCBtZXRob2QuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZWxlbWVudE5hbWUgVGhlIG5hbWUgb2YgdGhlIGVsZW1lbnQuCi0gICAgICogQHBhcmFtIGF1Z3MgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0Q29udGVudE1vZGVsKFN0cmluZyBlbGVtZW50TmFtZSwgQXVnbWVudGF0aW9ucyBhdWdzKQotICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLQotICAgICAgICBpZiAoZlZhbGlkYXRpb24pIHsKLSAgICAgICAgICAgIGZEVERFbGVtZW50RGVjbE5hbWUgPSBlbGVtZW50TmFtZTsKLSAgICAgICAgICAgIGZNaXhlZEVsZW1lbnRUeXBlcy5jbGVhcigpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gY2FsbCBoYW5kbGVycwotICAgICAgICBpZihmRFRER3JhbW1hciAhPSBudWxsKQotICAgICAgICAgICAgZkRUREdyYW1tYXIuc3RhcnRDb250ZW50TW9kZWwoZWxlbWVudE5hbWUsIGF1Z3MpOwotICAgICAgICBpZiAoZkRURENvbnRlbnRNb2RlbEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkRURENvbnRlbnRNb2RlbEhhbmRsZXIuc3RhcnRDb250ZW50TW9kZWwoZWxlbWVudE5hbWUsIGF1Z3MpOwotICAgICAgICB9Ci0KLSAgICB9IC8vIHN0YXJ0Q29udGVudE1vZGVsKFN0cmluZykKLQotICAgIC8qKgotICAgICAqIEEgY29udGVudCBtb2RlbCBvZiBBTlkuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYXVncyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICoKLSAgICAgKiBAc2VlICNlbXB0eQotICAgICAqIEBzZWUgI3N0YXJ0R3JvdXAKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBhbnkoQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgaWYoZkRUREdyYW1tYXIgIT0gbnVsbCkKLSAgICAgICAgICAgIGZEVERHcmFtbWFyLmFueShhdWdzKTsKLSAgICAgICAgaWYgKGZEVERDb250ZW50TW9kZWxIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZEVERDb250ZW50TW9kZWxIYW5kbGVyLmFueShhdWdzKTsKLSAgICAgICAgfQotICAgIH0gLy8gYW55KCkKLQotICAgIC8qKgotICAgICAqIEEgY29udGVudCBtb2RlbCBvZiBFTVBUWS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBhdWdzIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKgotICAgICAqIEBzZWUgI2FueQotICAgICAqIEBzZWUgI3N0YXJ0R3JvdXAKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbXB0eShBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBpZihmRFRER3JhbW1hciAhPSBudWxsKQotICAgICAgICAgICAgZkRUREdyYW1tYXIuZW1wdHkoYXVncyk7Ci0gICAgICAgIGlmIChmRFREQ29udGVudE1vZGVsSGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmRFREQ29udGVudE1vZGVsSGFuZGxlci5lbXB0eShhdWdzKTsKLSAgICAgICAgfQotICAgIH0gLy8gZW1wdHkoKQotCi0gICAgLyoqCi0gICAgICogQSBzdGFydCBvZiBlaXRoZXIgYSBtaXhlZCBvciBjaGlsZHJlbiBjb250ZW50IG1vZGVsLiBBIG1peGVkCi0gICAgICogY29udGVudCBtb2RlbCB3aWxsIGltbWVkaWF0ZWx5IGJlIGZvbGxvd2VkIGJ5IGEgY2FsbCB0byB0aGUKLSAgICAgKiA8Y29kZT5wY2RhdGEoKTwvY29kZT4gbWV0aG9kLiBBIGNoaWxkcmVuIGNvbnRlbnQgbW9kZWwgd2lsbAotICAgICAqIGNvbnRhaW4gYWRkaXRpb25hbCBncm91cHMgYW5kL29yIGVsZW1lbnRzLgotICAgICAqCi0gICAgICogQHBhcmFtIGF1Z3MgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqCi0gICAgICogQHNlZSAjYW55Ci0gICAgICogQHNlZSAjZW1wdHkKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydEdyb3VwKEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgZk1peGVkID0gZmFsc2U7Ci0gICAgICAgIC8vIGNhbGwgaGFuZGxlcnMKLSAgICAgICAgaWYoZkRUREdyYW1tYXIgIT0gbnVsbCkKLSAgICAgICAgICAgIGZEVERHcmFtbWFyLnN0YXJ0R3JvdXAoYXVncyk7Ci0gICAgICAgIGlmIChmRFREQ29udGVudE1vZGVsSGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmRFREQ29udGVudE1vZGVsSGFuZGxlci5zdGFydEdyb3VwKGF1Z3MpOwotICAgICAgICB9Ci0KLSAgICB9IC8vIHN0YXJ0R3JvdXAoKQotCi0gICAgLyoqCi0gICAgICogVGhlIGFwcGVhcmFuY2Ugb2YgIiNQQ0RBVEEiIHdpdGhpbiBhIGdyb3VwIHNpZ25pZnlpbmcgYQotICAgICAqIG1peGVkIGNvbnRlbnQgbW9kZWwuIFRoaXMgbWV0aG9kIHdpbGwgYmUgdGhlIGZpcnN0IGNhbGxlZAotICAgICAqIGZvbGxvd2luZyB0aGUgY29udGVudCBtb2RlbCdzIDxjb2RlPnN0YXJ0R3JvdXAoKTwvY29kZT4uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYXVncyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICoKLSAgICAgKiBAc2VlICNzdGFydEdyb3VwCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcGNkYXRhKEF1Z21lbnRhdGlvbnMgYXVncykgewotICAgICAgICBmTWl4ZWQgPSB0cnVlOwotICAgICAgICBpZihmRFRER3JhbW1hciAhPSBudWxsKQotICAgICAgICAgICAgZkRUREdyYW1tYXIucGNkYXRhKGF1Z3MpOwotICAgICAgICBpZiAoZkRURENvbnRlbnRNb2RlbEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkRURENvbnRlbnRNb2RlbEhhbmRsZXIucGNkYXRhKGF1Z3MpOwotICAgICAgICB9Ci0gICAgfSAvLyBwY2RhdGEoKQotCi0gICAgLyoqCi0gICAgICogQSByZWZlcmVuY2VkIGVsZW1lbnQgaW4gYSBtaXhlZCBvciBjaGlsZHJlbiBjb250ZW50IG1vZGVsLgotICAgICAqCi0gICAgICogQHBhcmFtIGVsZW1lbnROYW1lIFRoZSBuYW1lIG9mIHRoZSByZWZlcmVuY2VkIGVsZW1lbnQuCi0gICAgICogQHBhcmFtIGF1Z3MgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVsZW1lbnQoU3RyaW5nIGVsZW1lbnROYW1lLCBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotCi0gICAgICAgIC8vIGNoZWNrIFZDOiBObyBkdXBsaWNhdGUgVHlwZXMsIGluIGEgc2luZ2xlIG1peGVkLWNvbnRlbnQgZGVjbGFyYXRpb24KLSAgICAgICAgaWYgKGZNaXhlZCAmJiBmVmFsaWRhdGlvbikgewotICAgICAgICAgICAgaWYgKGZNaXhlZEVsZW1lbnRUeXBlcy5jb250YWlucyhlbGVtZW50TmFtZSkpIHsKLSAgICAgICAgICAgICAgICBmRXJyb3JSZXBvcnRlci5yZXBvcnRFcnJvcihYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkR1cGxpY2F0ZVR5cGVJbk1peGVkQ29udGVudCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde2ZEVERFbGVtZW50RGVjbE5hbWUsIGVsZW1lbnROYW1lfSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxFcnJvclJlcG9ydGVyLlNFVkVSSVRZX0VSUk9SKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIGZNaXhlZEVsZW1lbnRUeXBlcy5hZGQoZWxlbWVudE5hbWUpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gY2FsbCBoYW5kbGVycwotICAgICAgICBpZihmRFRER3JhbW1hciAhPSBudWxsKQotICAgICAgICAgICAgZkRUREdyYW1tYXIuZWxlbWVudChlbGVtZW50TmFtZSwgYXVncyk7Ci0gICAgICAgIGlmIChmRFREQ29udGVudE1vZGVsSGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmRFREQ29udGVudE1vZGVsSGFuZGxlci5lbGVtZW50KGVsZW1lbnROYW1lLCBhdWdzKTsKLSAgICAgICAgfQotCi0gICAgfSAvLyBjaGlsZHJlbkVsZW1lbnQoU3RyaW5nKQotCi0gICAgLyoqCi0gICAgICogVGhlIHNlcGFyYXRvciBiZXR3ZWVuIGNob2ljZXMgb3Igc2VxdWVuY2VzIG9mIGEgbWl4ZWQgb3IgY2hpbGRyZW4KLSAgICAgKiBjb250ZW50IG1vZGVsLgotICAgICAqCi0gICAgICogQHBhcmFtIHNlcGFyYXRvciBUaGUgdHlwZSBvZiBjaGlsZHJlbiBzZXBhcmF0b3IuCi0gICAgICogQHBhcmFtIGF1Z3MgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqCi0gICAgICogQHNlZSAjU0VQQVJBVE9SX0NIT0lDRQotICAgICAqIEBzZWUgI1NFUEFSQVRPUl9TRVFVRU5DRQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNlcGFyYXRvcihzaG9ydCBzZXBhcmF0b3IsIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy8gY2FsbCBoYW5kbGVycwotICAgICAgICBpZihmRFRER3JhbW1hciAhPSBudWxsKQotICAgICAgICAgICAgZkRUREdyYW1tYXIuc2VwYXJhdG9yKHNlcGFyYXRvciwgYXVncyk7Ci0gICAgICAgIGlmIChmRFREQ29udGVudE1vZGVsSGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmRFREQ29udGVudE1vZGVsSGFuZGxlci5zZXBhcmF0b3Ioc2VwYXJhdG9yLCBhdWdzKTsKLSAgICAgICAgfQotCi0gICAgfSAvLyBzZXBhcmF0b3Ioc2hvcnQpCi0KLSAgICAvKioKLSAgICAgKiBUaGUgb2NjdXJyZW5jZSBjb3VudCBmb3IgYSBjaGlsZCBpbiBhIGNoaWxkcmVuIGNvbnRlbnQgbW9kZWwgb3IKLSAgICAgKiBmb3IgdGhlIG1peGVkIGNvbnRlbnQgbW9kZWwgZ3JvdXAuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gb2NjdXJyZW5jZSBUaGUgb2NjdXJyZW5jZSBjb3VudCBmb3IgdGhlIGxhc3QgZWxlbWVudAotICAgICAqICAgICAgICAgICAgICAgICAgIG9yIGdyb3VwLgotICAgICAqIEBwYXJhbSBhdWdzIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKgotICAgICAqIEBzZWUgI09DQ1VSU19aRVJPX09SX09ORQotICAgICAqIEBzZWUgI09DQ1VSU19aRVJPX09SX01PUkUKLSAgICAgKiBAc2VlICNPQ0NVUlNfT05FX09SX01PUkUKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBvY2N1cnJlbmNlKHNob3J0IG9jY3VycmVuY2UsIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy8gY2FsbCBoYW5kbGVycwotICAgICAgICBpZihmRFRER3JhbW1hciAhPSBudWxsKQotICAgICAgICAgICAgZkRUREdyYW1tYXIub2NjdXJyZW5jZShvY2N1cnJlbmNlLCBhdWdzKTsKLSAgICAgICAgaWYgKGZEVERDb250ZW50TW9kZWxIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZEVERDb250ZW50TW9kZWxIYW5kbGVyLm9jY3VycmVuY2Uob2NjdXJyZW5jZSwgYXVncyk7Ci0gICAgICAgIH0KLQotICAgIH0gLy8gb2NjdXJyZW5jZShzaG9ydCkKLQotICAgIC8qKgotICAgICAqIFRoZSBlbmQgb2YgYSBncm91cCBmb3IgbWl4ZWQgb3IgY2hpbGRyZW4gY29udGVudCBtb2RlbHMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYXVncyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kR3JvdXAoQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLQotICAgICAgICAvLyBjYWxsIGhhbmRsZXJzCi0gICAgICAgIGlmKGZEVERHcmFtbWFyICE9IG51bGwpCi0gICAgICAgICAgICBmRFRER3JhbW1hci5lbmRHcm91cChhdWdzKTsKLSAgICAgICAgaWYgKGZEVERDb250ZW50TW9kZWxIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZEVERDb250ZW50TW9kZWxIYW5kbGVyLmVuZEdyb3VwKGF1Z3MpOwotICAgICAgICB9Ci0KLSAgICB9IC8vIGVuZEdyb3VwKCkKLQotICAgIC8qKgotICAgICAqIFRoZSBlbmQgb2YgYSBjb250ZW50IG1vZGVsLgotICAgICAqCi0gICAgICogQHBhcmFtIGF1Z3MgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZENvbnRlbnRNb2RlbChBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotCi0gICAgICAgIC8vIGNhbGwgaGFuZGxlcnMKLSAgICAgICAgaWYoZkRUREdyYW1tYXIgIT0gbnVsbCkKLSAgICAgICAgICAgIGZEVERHcmFtbWFyLmVuZENvbnRlbnRNb2RlbChhdWdzKTsKLSAgICAgICAgaWYgKGZEVERDb250ZW50TW9kZWxIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZEVERDb250ZW50TW9kZWxIYW5kbGVyLmVuZENvbnRlbnRNb2RlbChhdWdzKTsKLSAgICAgICAgfQotCi0gICAgfSAvLyBlbmRDb250ZW50TW9kZWwoKQotCi0gICAgLy8KLSAgICAvLyBQcml2YXRlIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogTm9ybWFsaXplIHRoZSBhdHRyaWJ1dGUgdmFsdWUgb2YgYSBub24gQ0RBVEEgZGVmYXVsdCBhdHRyaWJ1dGUKLSAgICAgKiBjb2xsYXBzaW5nIHNlcXVlbmNlcyBvZiBzcGFjZSBjaGFyYWN0ZXJzICh4MjApCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlIHRvIG5vcm1hbGl6ZQotICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgdmFsdWUgd2FzIGNoYW5nZWQgb3Igbm90LgotICAgICAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBub3JtYWxpemVEZWZhdWx0QXR0clZhbHVlKFhNTFN0cmluZyB2YWx1ZSkgewotCi0gICAgICAgIGJvb2xlYW4gc2tpcFNwYWNlID0gdHJ1ZTsgLy8gc2tpcCBsZWFkaW5nIHNwYWNlcwotICAgICAgICBpbnQgY3VycmVudCA9IHZhbHVlLm9mZnNldDsKLSAgICAgICAgaW50IGVuZCA9IHZhbHVlLm9mZnNldCArIHZhbHVlLmxlbmd0aDsKLSAgICAgICAgZm9yIChpbnQgaSA9IHZhbHVlLm9mZnNldDsgaSA8IGVuZDsgaSsrKSB7Ci0gICAgICAgICAgICBpZiAodmFsdWUuY2hbaV0gPT0gJyAnKSB7Ci0gICAgICAgICAgICAgICAgaWYgKCFza2lwU3BhY2UpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gdGFrZSB0aGUgZmlyc3Qgd2hpdGVzcGFjZSBhcyBhIHNwYWNlIGFuZCBza2lwIHRoZSBvdGhlcnMKLSAgICAgICAgICAgICAgICAgICAgdmFsdWUuY2hbY3VycmVudCsrXSA9ICcgJzsKLSAgICAgICAgICAgICAgICAgICAgc2tpcFNwYWNlID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIGp1c3Qgc2tpcCBpdC4KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAvLyBzaW1wbHkgc2hpZnQgbm9uIHNwYWNlIGNoYXJzIGlmIG5lZWRlZAotICAgICAgICAgICAgICAgIGlmIChjdXJyZW50ICE9IGkpIHsKLSAgICAgICAgICAgICAgICAgICAgdmFsdWUuY2hbY3VycmVudF0gPSB2YWx1ZS5jaFtpXTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgY3VycmVudCsrOwotICAgICAgICAgICAgICAgIHNraXBTcGFjZSA9IGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGlmIChjdXJyZW50ICE9IGVuZCkgewotICAgICAgICAgICAgaWYgKHNraXBTcGFjZSkgewotICAgICAgICAgICAgICAgIC8vIGlmIHdlIGZpbmlzaGVkIG9uIGEgc3BhY2UgdHJpbSBpdAotICAgICAgICAgICAgICAgIGN1cnJlbnQtLTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIHNldCB0aGUgbmV3IHZhbHVlIGxlbmd0aAotICAgICAgICAgICAgdmFsdWUubGVuZ3RoID0gY3VycmVudCAtIHZhbHVlLm9mZnNldDsKLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBpc1ZhbGlkTm10b2tlbihTdHJpbmcgbm10b2tlbikgewotICAgICAgICByZXR1cm4gWE1MQ2hhci5pc1ZhbGlkTm10b2tlbihubXRva2VuKTsKLSAgICB9IC8vIGlzVmFsaWRObXRva2VuKFN0cmluZyk6ICBib29sZWFuCi0KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBpc1ZhbGlkTmFtZShTdHJpbmcgbmFtZSkgewotICAgICAgICByZXR1cm4gWE1MQ2hhci5pc1ZhbGlkTmFtZShuYW1lKTsKLSAgICB9IC8vIGlzVmFsaWROYW1lKFN0cmluZyk6ICBib29sZWFuCi0KLSAgICAvKioKLSAgICAgKiBDaGVja3MgdGhhdCBhbGwgZWxlbWVudHMgcmVmZXJlbmNlZCBpbiBjb250ZW50IG1vZGVscyBoYXZlCi0gICAgICogYmVlbiBkZWNsYXJlZC4gVGhpcyBtZXRob2QgY2FsbHMgb3V0IHRvIHRoZSBlcnJvciBoYW5kbGVyCi0gICAgICogdG8gaW5kaWNhdGUgd2FybmluZ3MuCi0gICAgICovCi0gICAgcHJpdmF0ZSB2b2lkIGNoZWNrRGVjbGFyZWRFbGVtZW50cyhEVERHcmFtbWFyIGdyYW1tYXIpIHsKLSAgICAgICAgaW50IGVsZW1lbnRJbmRleCA9IGdyYW1tYXIuZ2V0Rmlyc3RFbGVtZW50RGVjbEluZGV4KCk7Ci0gICAgICAgIFhNTENvbnRlbnRTcGVjIGNvbnRlbnRTcGVjID0gbmV3IFhNTENvbnRlbnRTcGVjKCk7Ci0gICAgICAgIHdoaWxlIChlbGVtZW50SW5kZXggPj0gMCkgewotICAgICAgICAgICAgaW50IHR5cGUgPSBncmFtbWFyLmdldENvbnRlbnRTcGVjVHlwZShlbGVtZW50SW5kZXgpOwotICAgICAgICAgICAgaWYgKHR5cGUgPT0gWE1MRWxlbWVudERlY2wuVFlQRV9DSElMRFJFTiB8fCB0eXBlID09IFhNTEVsZW1lbnREZWNsLlRZUEVfTUlYRUQpIHsKLSAgICAgICAgICAgICAgICBjaGVja0RlY2xhcmVkRWxlbWVudHMoZ3JhbW1hciwKLSAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRJbmRleCwKLSAgICAgICAgICAgICAgICAgICAgICAgIGdyYW1tYXIuZ2V0Q29udGVudFNwZWNJbmRleChlbGVtZW50SW5kZXgpLAotICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudFNwZWMpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxlbWVudEluZGV4ID0gZ3JhbW1hci5nZXROZXh0RWxlbWVudERlY2xJbmRleChlbGVtZW50SW5kZXgpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRG9lcyBhIHJlY3Vyc2l2ZSAoaWYgbmVjZXNzYXJ5KSBjaGVjayBvbiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQncwotICAgICAqIGNvbnRlbnQgc3BlYyB0byBtYWtlIHN1cmUgdGhhdCBhbGwgY2hpbGRyZW4gcmVmZXIgdG8gZGVjbGFyZWQKLSAgICAgKiBlbGVtZW50cy4KLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgY2hlY2tEZWNsYXJlZEVsZW1lbnRzKERUREdyYW1tYXIgZ3JhbW1hciwgaW50IGVsZW1lbnRJbmRleCwKLSAgICAgICAgICAgIGludCBjb250ZW50U3BlY0luZGV4LCBYTUxDb250ZW50U3BlYyBjb250ZW50U3BlYykgewotICAgICAgICBncmFtbWFyLmdldENvbnRlbnRTcGVjKGNvbnRlbnRTcGVjSW5kZXgsIGNvbnRlbnRTcGVjKTsKLSAgICAgICAgaWYgKGNvbnRlbnRTcGVjLnR5cGUgPT0gWE1MQ29udGVudFNwZWMuQ09OVEVOVFNQRUNOT0RFX0xFQUYpIHsKLSAgICAgICAgICAgIFN0cmluZyB2YWx1ZSA9IChTdHJpbmcpIGNvbnRlbnRTcGVjLnZhbHVlOwotICAgICAgICAgICAgaWYgKHZhbHVlICE9IG51bGwgJiYgZ3JhbW1hci5nZXRFbGVtZW50RGVjbEluZGV4KHZhbHVlKSA9PSAtMSkgewotICAgICAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICJVbmRlY2xhcmVkRWxlbWVudEluQ29udGVudFNwZWMiLAotICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde2dyYW1tYXIuZ2V0RWxlbWVudERlY2xOYW1lKGVsZW1lbnRJbmRleCkucmF3bmFtZSwgdmFsdWV9LAotICAgICAgICAgICAgICAgICAgICAgICAgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9XQVJOSU5HKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICAvLyBJdCdzIG5vdCBhIGxlYWYsIHNvIHdlIGhhdmUgdG8gcmVjdXJzZSBpdHMgbGVmdCBhbmQgbWF5YmUgcmlnaHQKLSAgICAgICAgLy8gbm9kZXMuIFNhdmUgYm90aCB2YWx1ZXMgYmVmb3JlIHdlIHJlY3Vyc2UgYW5kIHRyYXNoIHRoZSBub2RlLgotICAgICAgICBlbHNlIGlmICgoY29udGVudFNwZWMudHlwZSA9PSBYTUxDb250ZW50U3BlYy5DT05URU5UU1BFQ05PREVfQ0hPSUNFKQotICAgICAgICAgICAgICAgIHx8IChjb250ZW50U3BlYy50eXBlID09IFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9TRVEpKSB7Ci0gICAgICAgICAgICBmaW5hbCBpbnQgbGVmdE5vZGUgPSAoKGludFtdKWNvbnRlbnRTcGVjLnZhbHVlKVswXTsKLSAgICAgICAgICAgIGZpbmFsIGludCByaWdodE5vZGUgPSAoKGludFtdKWNvbnRlbnRTcGVjLm90aGVyVmFsdWUpWzBdOwotICAgICAgICAgICAgLy8gIFJlY3Vyc2Ugb24gYm90aCBjaGlsZHJlbi4KLSAgICAgICAgICAgIGNoZWNrRGVjbGFyZWRFbGVtZW50cyhncmFtbWFyLCBlbGVtZW50SW5kZXgsIGxlZnROb2RlLCBjb250ZW50U3BlYyk7Ci0gICAgICAgICAgICBjaGVja0RlY2xhcmVkRWxlbWVudHMoZ3JhbW1hciwgZWxlbWVudEluZGV4LCByaWdodE5vZGUsIGNvbnRlbnRTcGVjKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChjb250ZW50U3BlYy50eXBlID09IFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9aRVJPX09SX01PUkUKLSAgICAgICAgICAgICAgICB8fCBjb250ZW50U3BlYy50eXBlID09IFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9aRVJPX09SX09ORQotICAgICAgICAgICAgICAgIHx8IGNvbnRlbnRTcGVjLnR5cGUgPT0gWE1MQ29udGVudFNwZWMuQ09OVEVOVFNQRUNOT0RFX09ORV9PUl9NT1JFKSB7Ci0gICAgICAgICAgICBmaW5hbCBpbnQgbGVmdE5vZGUgPSAoKGludFtdKWNvbnRlbnRTcGVjLnZhbHVlKVswXTsKLSAgICAgICAgICAgIGNoZWNrRGVjbGFyZWRFbGVtZW50cyhncmFtbWFyLCBlbGVtZW50SW5kZXgsIGxlZnROb2RlLCBjb250ZW50U3BlYyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLX0gLy8gY2xhc3MgWE1MRFREUHJvY2Vzc29yCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R0ZC9YTUxEVERWYWxpZGF0b3IuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHRkL1hNTERURFZhbGlkYXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyN2U3Y2RhLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHRkL1hNTERURFZhbGlkYXRvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjA2OSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdGQ7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5SZXZhbGlkYXRpb25IYW5kbGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5YTUxFbnRpdHlNYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5YTUxFcnJvclJlcG9ydGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdGQubW9kZWxzLkNvbnRlbnRNb2RlbFZhbGlkYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYuRFRERFZGYWN0b3J5OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5EYXRhdHlwZVZhbGlkYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYuSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLm1zZy5YTUxNZXNzYWdlRm9ybWF0dGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC52YWxpZGF0aW9uLlZhbGlkYXRpb25NYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC52YWxpZGF0aW9uLlZhbGlkYXRpb25TdGF0ZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuU3ltYm9sVGFibGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlhNTENoYXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlhNTFN5bWJvbHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuQXVnbWVudGF0aW9uczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5OYW1lc3BhY2VDb250ZXh0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlFOYW1lOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTEF0dHJpYnV0ZXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MRG9jdW1lbnRIYW5kbGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTExvY2F0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MUmVzb3VyY2VJZGVudGlmaWVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTFN0cmluZzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTklFeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuZ3JhbW1hcnMuR3JhbW1hcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5ncmFtbWFycy5YTUxHcmFtbWFyRGVzY3JpcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuZ3JhbW1hcnMuWE1MR3JhbW1hclBvb2w7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTENvbXBvbmVudDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MQ29tcG9uZW50TWFuYWdlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MRG9jdW1lbnRGaWx0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTERvY3VtZW50U291cmNlOwotCi0vKioKLSAqIFRoZSBEVEQgdmFsaWRhdG9yLiBUaGUgdmFsaWRhdG9yIGltcGxlbWVudHMgYSBkb2N1bWVudAotICogZmlsdGVyOiByZWNlaXZpbmcgZG9jdW1lbnQgZXZlbnRzIGZyb20gdGhlIHNjYW5uZXI7IHZhbGlkYXRpbmcKLSAqIHRoZSBjb250ZW50IGFuZCBzdHJ1Y3R1cmU7IGF1Z21lbnRpbmcgdGhlIEluZm9TZXQsIGlmIGFwcGxpY2FibGU7Ci0gKiBhbmQgbm90aWZ5aW5nIHRoZSBwYXJzZXIgb2YgdGhlIGluZm9ybWF0aW9uIHJlc3VsdGluZyBmcm9tIHRoZQotICogdmFsaWRhdGlvbiBwcm9jZXNzLgotICogPHA+IEZvcm1lcmx5LCB0aGlzIGNvbXBvbmVudCBhbHNvIGhhbmRsZWQgRFREIGV2ZW50cyBhbmQgZ3JhbW1hciBjb25zdHJ1Y3Rpb24uCi0gKiBUbyBmYWNpbGl0YXRlIHRoZSBkZXZlbG9wbWVudCBvZiBhIG1lYW5pbmdmdWwgRFREIGdyYW1tYXIgY2FjaGluZy9wcmVwYXJzaW5nCi0gKiBmcmFtZXdvcmssIHRoaXMgZnVuY3Rpb25hbGl0eSBoYXMgYmVlbiBtb3ZlZCBpbnRvIHRoZSBYTUxEVERMb2FkZXIKLSAqIGNsYXNzLiAgVGhlcmVmb3JlLCB0aGlzIGNsYXNzIG5vIGxvbmdlciBpbXBsZW1lbnRzIHRoZSBEVERGaWx0ZXIKLSAqIG9yIERURENvbnRlbnRNb2RlbEZpbHRlciBpbnRlcmZhY2VzLgotICogPHA+Ci0gKiBUaGlzIGNvbXBvbmVudCByZXF1aXJlcyB0aGUgZm9sbG93aW5nIGZlYXR1cmVzIGFuZCBwcm9wZXJ0aWVzIGZyb20gdGhlCi0gKiBjb21wb25lbnQgbWFuYWdlciB0aGF0IHVzZXMgaXQ6Ci0gKiA8dWw+Ci0gKiAgPGxpPmh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy9uYW1lc3BhY2VzPC9saT4KLSAqICA8bGk+aHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL3ZhbGlkYXRpb248L2xpPgotICogIDxsaT5odHRwOi8vYXBhY2hlLm9yZy94bWwvZmVhdHVyZXMvdmFsaWRhdGlvbi9keW5hbWljPC9saT4KLSAqICA8bGk+aHR0cDovL2FwYWNoZS5vcmcveG1sL3Byb3BlcnRpZXMvaW50ZXJuYWwvc3ltYm9sLXRhYmxlPC9saT4KLSAqICA8bGk+aHR0cDovL2FwYWNoZS5vcmcveG1sL3Byb3BlcnRpZXMvaW50ZXJuYWwvZXJyb3ItcmVwb3J0ZXI8L2xpPgotICogIDxsaT5odHRwOi8vYXBhY2hlLm9yZy94bWwvcHJvcGVydGllcy9pbnRlcm5hbC9ncmFtbWFyLXBvb2w8L2xpPgotICogIDxsaT5odHRwOi8vYXBhY2hlLm9yZy94bWwvcHJvcGVydGllcy9pbnRlcm5hbC9kYXRhdHlwZS12YWxpZGF0b3ItZmFjdG9yeTwvbGk+Ci0gKiA8L3VsPgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIEVyaWMgWWUsIElCTQotICogQGF1dGhvciBBbmR5IENsYXJrLCBJQk0KLSAqIEBhdXRob3IgSmVmZnJleSBSb2RyaWd1ZXogSUJNCi0gKiBAYXV0aG9yIE5laWwgR3JhaGFtLCBJQk0KLSAqCi0gKiBAdmVyc2lvbiAkSWQ6IFhNTERURFZhbGlkYXRvci5qYXZhLHYgMS44IDIwMTAtMTEtMDEgMDQ6Mzk6NDIgam9laHcgRXhwICQKLSAqLwotcHVibGljIGNsYXNzIFhNTERURFZhbGlkYXRvcgotICAgICAgICBpbXBsZW1lbnRzIFhNTENvbXBvbmVudCwgWE1MRG9jdW1lbnRGaWx0ZXIsIFhNTERURFZhbGlkYXRvckZpbHRlciwgUmV2YWxpZGF0aW9uSGFuZGxlciB7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0YW50cwotICAgIC8vCi0KLSAgICAvKiogU3ltYm9sOiAiJmx0OyZsdDtkYXRhdHlwZXM+PiIuICovCi0KLSAgICAvKiogVG9wIGxldmVsIHNjb3BlICgtMSkuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFRPUF9MRVZFTF9TQ09QRSA9IC0xOwotCi0gICAgLy8gZmVhdHVyZSBpZGVudGlmaWVycwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogbmFtZXNwYWNlcy4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBOQU1FU1BBQ0VTID0KLSAgICAgICAgQ29uc3RhbnRzLlNBWF9GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5OQU1FU1BBQ0VTX0ZFQVRVUkU7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiB2YWxpZGF0aW9uLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFZBTElEQVRJT04gPQotICAgICAgICBDb25zdGFudHMuU0FYX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLlZBTElEQVRJT05fRkVBVFVSRTsKLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IGR5bmFtaWMgdmFsaWRhdGlvbi4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBEWU5BTUlDX1ZBTElEQVRJT04gPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLkRZTkFNSUNfVkFMSURBVElPTl9GRUFUVVJFOwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogYmFsYW5jZSBzeW50YXggdHJlZXMuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgQkFMQU5DRV9TWU5UQVhfVFJFRVMgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLkJBTEFOQ0VfU1lOVEFYX1RSRUVTOwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogd2FybiBvbiBkdXBsaWNhdGUgYXR0ZGVmICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0FSTl9PTl9EVVBMSUNBVEVfQVRUREVGID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5XQVJOX09OX0RVUExJQ0FURV9BVFRERUZfRkVBVFVSRTsKLQotICAgICAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBQQVJTRVJfU0VUVElOR1MgPQotICAgICAgICAgICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuUEFSU0VSX1NFVFRJTkdTOwotCi0KLQotICAgIC8vIHByb3BlcnR5IGlkZW50aWZpZXJzCi0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogc3ltYm9sIHRhYmxlLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFNZTUJPTF9UQUJMRSA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLlNZTUJPTF9UQUJMRV9QUk9QRVJUWTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBlcnJvciByZXBvcnRlci4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJPUl9SRVBPUlRFUiA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLkVSUk9SX1JFUE9SVEVSX1BST1BFUlRZOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IGdyYW1tYXIgcG9vbC4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBHUkFNTUFSX1BPT0wgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5YTUxHUkFNTUFSX1BPT0xfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogZGF0YXR5cGUgdmFsaWRhdG9yIGZhY3RvcnkuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgREFUQVRZUEVfVkFMSURBVE9SX0ZBQ1RPUlkgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5EQVRBVFlQRV9WQUxJREFUT1JfRkFDVE9SWV9QUk9QRVJUWTsKLQotICAgIC8vIHByb3BlcnR5IGlkZW50aWZpZXI6ICBWYWxpZGF0aW9uTWFuYWdlcgotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFZBTElEQVRJT05fTUFOQUdFUiA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLlZBTElEQVRJT05fTUFOQUdFUl9QUk9QRVJUWTsKLQotICAgIC8vIHJlY29nbml6ZWQgZmVhdHVyZXMgYW5kIHByb3BlcnRpZXMKLQotICAgIC8qKiBSZWNvZ25pemVkIGZlYXR1cmVzLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZ1tdIFJFQ09HTklaRURfRkVBVFVSRVMgPSB7Ci0gICAgICAgIE5BTUVTUEFDRVMsCi0gICAgICAgIFZBTElEQVRJT04sCi0gICAgICAgIERZTkFNSUNfVkFMSURBVElPTiwKLSAgICAgICAgQkFMQU5DRV9TWU5UQVhfVFJFRVMKLSAgICB9OwotCi0gICAgLyoqIEZlYXR1cmUgZGVmYXVsdHMuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQm9vbGVhbltdIEZFQVRVUkVfREVGQVVMVFMgPSB7Ci0gICAgICAgIG51bGwsCi0gICAgICAgIG51bGwsCi0gICAgICAgIEJvb2xlYW4uRkFMU0UsCi0gICAgICAgIEJvb2xlYW4uRkFMU0UsCi0gICAgfTsKLQotICAgIC8qKiBSZWNvZ25pemVkIHByb3BlcnRpZXMuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nW10gUkVDT0dOSVpFRF9QUk9QRVJUSUVTID0gewotICAgICAgICBTWU1CT0xfVEFCTEUsCi0gICAgICAgIEVSUk9SX1JFUE9SVEVSLAotICAgICAgICBHUkFNTUFSX1BPT0wsCi0gICAgICAgIERBVEFUWVBFX1ZBTElEQVRPUl9GQUNUT1JZLAotICAgICAgICBWQUxJREFUSU9OX01BTkFHRVIKLSAgICB9OwotCi0gICAgLyoqIFByb3BlcnR5IGRlZmF1bHRzLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIE9iamVjdFtdIFBST1BFUlRZX0RFRkFVTFRTID0gewotICAgICAgICBudWxsLAotICAgICAgICBudWxsLAotICAgICAgICBudWxsLAotICAgICAgICBudWxsLAotICAgICAgICBudWxsLAotICAgIH07Ci0KLSAgICAvLyBkZWJ1Z2dpbmcKLQotICAgIC8qKiBDb21waWxlIHRvIHRydWUgdG8gZGVidWcgYXR0cmlidXRlcy4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIERFQlVHX0FUVFJJQlVURVMgPSBmYWxzZTsKLQotICAgIC8qKiBDb21waWxlIHRvIHRydWUgdG8gZGVidWcgZWxlbWVudCBjaGlsZHJlbi4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIERFQlVHX0VMRU1FTlRfQ0hJTERSRU4gPSBmYWxzZTsKLQotICAgIC8vCi0gICAgLy8gRGF0YQotICAgIC8vCi0KLSAgICAvLyB1cGRhdGVkIGR1cmluZyByZXNldAotICAgIHByb3RlY3RlZCBWYWxpZGF0aW9uTWFuYWdlciBmVmFsaWRhdGlvbk1hbmFnZXIgPSBudWxsOwotCi0gICAgLy8gdmFsaWRhdGlvbiBzdGF0ZQotICAgIHByb3RlY3RlZCBmaW5hbCBWYWxpZGF0aW9uU3RhdGUgZlZhbGlkYXRpb25TdGF0ZSA9IG5ldyBWYWxpZGF0aW9uU3RhdGUoKTsKLQotICAgIC8vIGZlYXR1cmVzCi0KLSAgICAvKiogTmFtZXNwYWNlcy4gKi8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBmTmFtZXNwYWNlczsKLQotICAgIC8qKiBWYWxpZGF0aW9uLiAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIGZWYWxpZGF0aW9uOwotCi0gICAgLyoqIFZhbGlkYXRpb24gYWdhaW5zdCBvbmx5IERURCAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIGZEVERWYWxpZGF0aW9uOwotCi0gICAgLyoqCi0gICAgICogRHluYW1pYyB2YWxpZGF0aW9uLiBUaGlzIHN0YXRlIG9mIHRoaXMgZmVhdHVyZSBpcyBvbmx5IHVzZWZ1bCB3aGVuCi0gICAgICogdGhlIHZhbGlkYXRpb24gZmVhdHVyZSBpcyBzZXQgdG8gPGNvZGU+dHJ1ZTwvY29kZT4uCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZkR5bmFtaWNWYWxpZGF0aW9uOwotCi0gICAgLyoqIENvbnRyb2xzIHdoZXRoZXIgdGhlIERURCBncmFtbWFyIHByb2R1Y2VzIGJhbGFuY2VkIHN5bnRheCB0cmVlcy4gKi8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBmQmFsYW5jZVN5bnRheFRyZWVzOwotCi0gICAgLyoqIHdhcm4gb24gZHVwbGljYXRlIGF0dHJpYnV0ZSBkZWZpbml0aW9uLCB0aGlzIGZlYXR1cmUgd29ya3Mgb25seSB3aGVuIHZhbGlkYXRpb24gaXMgdHJ1ZSAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIGZXYXJuRHVwbGljYXRlQXR0ZGVmOwotCi0gICAgLy8gcHJvcGVydGllcwotCi0gICAgLyoqIFN5bWJvbCB0YWJsZS4gKi8KLSAgICBwcm90ZWN0ZWQgU3ltYm9sVGFibGUgZlN5bWJvbFRhYmxlOwotCi0gICAgLyoqIEVycm9yIHJlcG9ydGVyLiAqLwotICAgIHByb3RlY3RlZCBYTUxFcnJvclJlcG9ydGVyIGZFcnJvclJlcG9ydGVyOwotCi0gICAgLy8gdGhlIGdyYW1tYXIgcG9vbAotICAgIHByb3RlY3RlZCBYTUxHcmFtbWFyUG9vbCBmR3JhbW1hclBvb2w7Ci0KLSAgICAvKiogR3JhbW1hciBidWNrZXQuICovCi0gICAgcHJvdGVjdGVkIERUREdyYW1tYXJCdWNrZXQgZkdyYW1tYXJCdWNrZXQ7Ci0KLSAgICAvKiBsb2NhdGlvbiBvZiB0aGUgZG9jdW1lbnQgYXMgcGFzc2VkIGluIGZyb20gc3RhcnREb2N1bWVudCBjYWxsICovCi0gICAgcHJvdGVjdGVkIFhNTExvY2F0b3IgZkRvY0xvY2F0aW9uOwotCi0gICAgLyoqIE5hbWVzcGFjZSBzdXBwb3J0LiAqLwotICAgIHByb3RlY3RlZCBOYW1lc3BhY2VDb250ZXh0IGZOYW1lc3BhY2VDb250ZXh0ID0gbnVsbDsKLQotICAgIC8qKiBEYXRhdHlwZSB2YWxpZGF0b3IgZmFjdG9yeS4gKi8KLSAgICBwcm90ZWN0ZWQgRFRERFZGYWN0b3J5IGZEYXRhdHlwZVZhbGlkYXRvckZhY3Rvcnk7Ci0KLSAgICAvLyBoYW5kbGVycwotCi0gICAgLyoqIERvY3VtZW50IGhhbmRsZXIuICovCi0gICAgcHJvdGVjdGVkIFhNTERvY3VtZW50SGFuZGxlciBmRG9jdW1lbnRIYW5kbGVyOwotCi0gICAgcHJvdGVjdGVkIFhNTERvY3VtZW50U291cmNlIGZEb2N1bWVudFNvdXJjZTsKLSAgICAvLyBncmFtbWFycwotCi0gICAgLyoqIERURCBHcmFtbWFyLiAqLwotICAgIHByb3RlY3RlZCBEVERHcmFtbWFyIGZEVERHcmFtbWFyOwotCi0gICAgLy8gc3RhdGUKLQotICAgIC8qKiBUcnVlIGlmIHNlZW4gRE9DVFlQRSBkZWNsYXJhdGlvbi4gKi8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBmU2VlbkRvY3R5cGVEZWNsID0gZmFsc2U7Ci0KLSAgICAvKiogUGVyZm9ybSB2YWxpZGF0aW9uLiAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBmUGVyZm9ybVZhbGlkYXRpb247Ci0KLSAgICAvKiogU2NoZW1hIHR5cGU6IE5vbmUsIERURCwgU2NoZW1hICovCi0gICAgcHJpdmF0ZSBTdHJpbmcgZlNjaGVtYVR5cGU7Ci0KLSAgICAvLyBpbmZvcm1hdGlvbiByZWdhcmRpbmcgdGhlIGN1cnJlbnQgZWxlbWVudAotCi0gICAgLyoqIEN1cnJlbnQgZWxlbWVudCBuYW1lLiAqLwotICAgIHByaXZhdGUgZmluYWwgUU5hbWUgZkN1cnJlbnRFbGVtZW50ID0gbmV3IFFOYW1lKCk7Ci0KLSAgICAvKiogQ3VycmVudCBlbGVtZW50IGluZGV4LiAqLwotICAgIHByaXZhdGUgaW50IGZDdXJyZW50RWxlbWVudEluZGV4ID0gLTE7Ci0KLSAgICAvKiogQ3VycmVudCBjb250ZW50IHNwZWMgdHlwZS4gKi8KLSAgICBwcml2YXRlIGludCBmQ3VycmVudENvbnRlbnRTcGVjVHlwZSA9IC0xOwotCi0gICAgLyoqIFRoZSByb290IGVsZW1lbnQgbmFtZS4gKi8KLSAgICBwcml2YXRlIGZpbmFsIFFOYW1lIGZSb290RWxlbWVudCA9IG5ldyBRTmFtZSgpOwotCi0gICAgcHJpdmF0ZSBib29sZWFuIGZJbkNEQVRBU2VjdGlvbiA9IGZhbHNlOwotICAgIC8vIGVsZW1lbnQgc3RhY2sKLQotICAgIC8qKiBFbGVtZW50IGluZGV4IHN0YWNrLiAqLwotICAgIHByaXZhdGUgaW50W10gZkVsZW1lbnRJbmRleFN0YWNrID0gbmV3IGludFs4XTsKLQotICAgIC8qKiBDb250ZW50IHNwZWMgdHlwZSBzdGFjay4gKi8KLSAgICBwcml2YXRlIGludFtdIGZDb250ZW50U3BlY1R5cGVTdGFjayA9IG5ldyBpbnRbOF07Ci0KLSAgICAvKiogRWxlbWVudCBuYW1lIHN0YWNrLiAqLwotICAgIHByaXZhdGUgUU5hbWVbXSBmRWxlbWVudFFOYW1lUGFydHNTdGFjayA9IG5ldyBRTmFtZVs4XTsKLQotICAgIC8vIGNoaWxkcmVuIGxpc3QgYW5kIG9mZnNldCBzdGFjawotCi0gICAgLyoqCi0gICAgICogRWxlbWVudCBjaGlsZHJlbi4gVGhpcyBkYXRhIHN0cnVjdHVyZSBpcyBhIGdyb3dpbmcgc3RhY2sgdGhhdAotICAgICAqIGhvbGRzIHRoZSBjaGlsZHJlbiBvZiBlbGVtZW50cyBmcm9tIHRoZSByb290IHRvIHRoZSBjdXJyZW50Ci0gICAgICogZWxlbWVudCBkZXB0aC4gVGhpcyBzdHJ1Y3R1cmUgbmV2ZXIgZ2V0cyAiZGVlcGVyIiB0aGFuIHRoZQotICAgICAqIGRlZXBlc3QgZWxlbWVudC4gU3BhY2UgaXMgcmUtdXNlZCBvbmNlIGVhY2ggZWxlbWVudCBpcyBjbG9zZWQuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGlzIGlzIG11Y2ggbW9yZSBlZmZpY2llbnQgdXNlIG9mIG1lbW9yeQotICAgICAqIHRoYW4gY3JlYXRpbmcgbmV3IGFycmF5cyBmb3IgZWFjaCBlbGVtZW50IGRlcHRoLgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gVGhlIHVzZSBvZiB0aGlzIGRhdGEgc3RydWN0dXJlIGlzIGZvcgotICAgICAqIHZhbGlkYXRpb24gIm9uIHRoZSB3YXkgb3V0Ii4gSWYgdGhlIHZhbGlkYXRpb24gbW9kZWwgY2hhbmdlcyB0bwotICAgICAqICJvbiB0aGUgd2F5IGluIiwgdGhlbiB0aGlzIGRhdGEgc3RydWN0dXJlIGlzIG5vdCBuZWVkZWQuCi0gICAgICovCi0gICAgcHJpdmF0ZSBRTmFtZVtdIGZFbGVtZW50Q2hpbGRyZW4gPSBuZXcgUU5hbWVbMzJdOwotCi0gICAgLyoqIEVsZW1lbnQgY2hpbGRyZW4gY291bnQuICovCi0gICAgcHJpdmF0ZSBpbnQgZkVsZW1lbnRDaGlsZHJlbkxlbmd0aCA9IDA7Ci0KLSAgICAvKioKLSAgICAgKiBFbGVtZW50IGNoaWxkcmVuIG9mZnNldCBzdGFjay4gVGhpcyBzdGFjayByZWZlcnMgdG8gb2Zmc2V0cwotICAgICAqIGludG8gdGhlIDxjb2RlPmZFbGVtZW50Q2hpbGRyZW48L2NvZGU+IGFycmF5LgotICAgICAqIEBzZWUgI2ZFbGVtZW50Q2hpbGRyZW4KLSAgICAgKi8KLSAgICBwcml2YXRlIGludFtdIGZFbGVtZW50Q2hpbGRyZW5PZmZzZXRTdGFjayA9IG5ldyBpbnRbMzJdOwotCi0gICAgLyoqIEVsZW1lbnQgZGVwdGguICovCi0gICAgcHJpdmF0ZSBpbnQgZkVsZW1lbnREZXB0aCA9IC0xOwotCi0gICAgLy8gdmFsaWRhdGlvbiBzdGF0ZXMKLQotICAgIC8qKiBUcnVlIGlmIHNlZW4gdGhlIHJvb3QgZWxlbWVudC4gKi8KLSAgICBwcml2YXRlIGJvb2xlYW4gZlNlZW5Sb290RWxlbWVudCA9IGZhbHNlOwotCi0gICAgLyoqIFRydWUgaWYgaW5zaWRlIG9mIGVsZW1lbnQgY29udGVudC4gKi8KLSAgICBwcml2YXRlIGJvb2xlYW4gZkluRWxlbWVudENvbnRlbnQgPSBmYWxzZTsKLQotICAgIC8vIHRlbXBvcmFyeSB2YXJpYWJsZXMKLQotICAgIC8qKiBUZW1wb3JhcnkgZWxlbWVudCBkZWNsYXJhdGlvbi4gKi8KLSAgICBwcml2YXRlIFhNTEVsZW1lbnREZWNsIGZUZW1wRWxlbWVudERlY2wgPSBuZXcgWE1MRWxlbWVudERlY2woKTsKLQotICAgIC8qKiBUZW1wb3JhcnkgYXRyaWJ1dGUgZGVjbGFyYXRpb24uICovCi0gICAgcHJpdmF0ZSBmaW5hbCBYTUxBdHRyaWJ1dGVEZWNsIGZUZW1wQXR0RGVjbCA9IG5ldyBYTUxBdHRyaWJ1dGVEZWNsKCk7Ci0KLSAgICAvKiogVGVtcG9yYXJ5IGVudGl0eSBkZWNsYXJhdGlvbi4gKi8KLSAgICBwcml2YXRlIGZpbmFsIFhNTEVudGl0eURlY2wgZkVudGl0eURlY2wgPSBuZXcgWE1MRW50aXR5RGVjbCgpOwotCi0gICAgLyoqIFRlbXBvcmFyeSBxdWFsaWZpZWQgbmFtZS4gKi8KLSAgICBwcml2YXRlIGZpbmFsIFFOYW1lIGZUZW1wUU5hbWUgPSBuZXcgUU5hbWUoKTsKLQotICAgIC8qKiBUZW1wb3Jhcnkgc3RyaW5nIGJ1ZmZlcnMuICovCi0gICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmdCdWZmZXIgZkJ1ZmZlciA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLQotICAgIC8vIHN5bWJvbHM6IGdlbmVyYWwKLQotICAgIC8vIGF0dHJpYnV0ZSB2YWxpZGF0b3JzCi0KLSAgICAvKiogRGF0YXR5cGUgdmFsaWRhdG9yOiBJRC4gKi8KLSAgICBwcm90ZWN0ZWQgRGF0YXR5cGVWYWxpZGF0b3IgZlZhbElEOwotCi0gICAgLyoqIERhdGF0eXBlIHZhbGlkYXRvcjogSURSRUYuICovCi0gICAgcHJvdGVjdGVkIERhdGF0eXBlVmFsaWRhdG9yIGZWYWxJRFJlZjsKLQotICAgIC8qKiBEYXRhdHlwZSB2YWxpZGF0b3I6IElEUkVGUy4gKi8KLSAgICBwcm90ZWN0ZWQgRGF0YXR5cGVWYWxpZGF0b3IgZlZhbElEUmVmczsKLQotICAgIC8qKiBEYXRhdHlwZSB2YWxpZGF0b3I6IEVOVElUWS4gKi8KLSAgICBwcm90ZWN0ZWQgRGF0YXR5cGVWYWxpZGF0b3IgZlZhbEVOVElUWTsKLQotICAgIC8qKiBEYXRhdHlwZSB2YWxpZGF0b3I6IEVOVElUSUVTLiAqLwotICAgIHByb3RlY3RlZCBEYXRhdHlwZVZhbGlkYXRvciBmVmFsRU5USVRJRVM7Ci0KLSAgICAvKiogRGF0YXR5cGUgdmFsaWRhdG9yOiBOTVRPS0VOLiAqLwotICAgIHByb3RlY3RlZCBEYXRhdHlwZVZhbGlkYXRvciBmVmFsTk1UT0tFTjsKLQotICAgIC8qKiBEYXRhdHlwZSB2YWxpZGF0b3I6IE5NVE9LRU5TLiAqLwotICAgIHByb3RlY3RlZCBEYXRhdHlwZVZhbGlkYXRvciBmVmFsTk1UT0tFTlM7Ci0KLSAgICAvKiogRGF0YXR5cGUgdmFsaWRhdG9yOiBOT1RBVElPTi4gKi8KLSAgICBwcm90ZWN0ZWQgRGF0YXR5cGVWYWxpZGF0b3IgZlZhbE5PVEFUSU9OOwotCi0gICAgLy8gdG8gY2hlY2sgZm9yIGR1cGxpY2F0ZSBJRCBvciBBTk5PVEFUSU9OIGF0dHJpYnV0ZSBkZWNsYXJlIGluCi0gICAgLy8gQVRUTElTVCwgYW5kIG1pc2MgVkNzCi0KLSAgICAvLwotICAgIC8vIENvbnN0cnVjdG9ycwotICAgIC8vCi0KLSAgICAvKiogRGVmYXVsdCBjb25zdHJ1Y3Rvci4gKi8KLSAgICBwdWJsaWMgWE1MRFREVmFsaWRhdG9yKCkgewotCi0gICAgICAgIC8vIGluaXRpYWxpemUgZGF0YQotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZFbGVtZW50UU5hbWVQYXJ0c1N0YWNrLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICBmRWxlbWVudFFOYW1lUGFydHNTdGFja1tpXSA9IG5ldyBRTmFtZSgpOwotICAgICAgICB9Ci0gICAgICAgIGZHcmFtbWFyQnVja2V0ID0gbmV3IERUREdyYW1tYXJCdWNrZXQoKTsKLQotICAgIH0gLy8gPGluaXQ+KCkKLQotICAgIERUREdyYW1tYXJCdWNrZXQgZ2V0R3JhbW1hckJ1Y2tldCgpIHsKLSAgICAgICAgcmV0dXJuIGZHcmFtbWFyQnVja2V0OwotICAgIH0gLy8gZ2V0R3JhbW1hckJ1Y2tldCgpOiAgRFRER3JhbW1hckJ1Y2tldAotCi0gICAgLy8KLSAgICAvLyBYTUxDb21wb25lbnQgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKgotICAgICAqIFJlc2V0cyB0aGUgY29tcG9uZW50LiBUaGUgY29tcG9uZW50IGNhbiBxdWVyeSB0aGUgY29tcG9uZW50IG1hbmFnZXIKLSAgICAgKiBhYm91dCBhbnkgZmVhdHVyZXMgYW5kIHByb3BlcnRpZXMgdGhhdCBhZmZlY3QgdGhlIG9wZXJhdGlvbiBvZiB0aGUKLSAgICAgKiBjb21wb25lbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29tcG9uZW50TWFuYWdlciBUaGUgY29tcG9uZW50IG1hbmFnZXIuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBUaHJvd24gYnkgY29tcG9uZW50IG9uIGZpbml0aWFsaXphdGlvbiBlcnJvci4KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBGb3IgZXhhbXBsZSwgaWYgYSBmZWF0dXJlIG9yIHByb3BlcnR5IGlzCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgcmVxdWlyZWQgZm9yIHRoZSBvcGVyYXRpb24gb2YgdGhlIGNvbXBvbmVudCwgdGhlCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgY29tcG9uZW50IG1hbmFnZXIgbWF5IHRocm93IGEKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIG9yIGEKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcmVzZXQoWE1MQ29tcG9uZW50TWFuYWdlciBjb21wb25lbnRNYW5hZ2VyKQotICAgIHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIHsKLQotICAgICAgICAvLyBjbGVhciBncmFtbWFycwotICAgICAgICBmRFRER3JhbW1hciA9IG51bGw7Ci0gICAgICAgIGZTZWVuRG9jdHlwZURlY2wgPSBmYWxzZTsKLSAgICAgICAgZkluQ0RBVEFTZWN0aW9uID0gZmFsc2U7Ci0gICAgICAgIC8vIGluaXRpYWxpemUgc3RhdGUKLSAgICAgICAgZlNlZW5Sb290RWxlbWVudCA9IGZhbHNlOwotICAgICAgICBmSW5FbGVtZW50Q29udGVudCA9IGZhbHNlOwotICAgICAgICBmQ3VycmVudEVsZW1lbnRJbmRleCA9IC0xOwotICAgICAgICBmQ3VycmVudENvbnRlbnRTcGVjVHlwZSA9IC0xOwotCi0gICAgICAgIGZSb290RWxlbWVudC5jbGVhcigpOwotCi0gICAgICAgICAgICAgICAgZlZhbGlkYXRpb25TdGF0ZS5yZXNldElEVGFibGVzKCk7Ci0KLSAgICAgICAgICAgICAgICBmR3JhbW1hckJ1Y2tldC5jbGVhcigpOwotICAgICAgICAgICAgICAgIGZFbGVtZW50RGVwdGggPSAtMTsKLSAgICAgICAgICAgICAgICBmRWxlbWVudENoaWxkcmVuTGVuZ3RoID0gMDsKLQotICAgICAgICBib29sZWFuIHBhcnNlcl9zZXR0aW5ncyA9IGNvbXBvbmVudE1hbmFnZXIuZ2V0RmVhdHVyZShQQVJTRVJfU0VUVElOR1MsIHRydWUpOwotCi0gICAgICAgIGlmICghcGFyc2VyX3NldHRpbmdzKXsKLSAgICAgICAgICAgICAgICAvLyBwYXJzZXIgc2V0dGluZ3MgaGF2ZSBub3QgYmVlbiBjaGFuZ2VkCi0gICAgICAgICAgICAgICAgICAgICAgICBmVmFsaWRhdGlvbk1hbmFnZXIuYWRkVmFsaWRhdGlvblN0YXRlKGZWYWxpZGF0aW9uU3RhdGUpOwotICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIHNheCBmZWF0dXJlcwotICAgICAgICBmTmFtZXNwYWNlcyA9IGNvbXBvbmVudE1hbmFnZXIuZ2V0RmVhdHVyZShOQU1FU1BBQ0VTLCB0cnVlKTsKLSAgICAgICAgZlZhbGlkYXRpb24gPSBjb21wb25lbnRNYW5hZ2VyLmdldEZlYXR1cmUoVkFMSURBVElPTiwgZmFsc2UpOwotICAgICAgICBmRFREVmFsaWRhdGlvbiA9ICEoY29tcG9uZW50TWFuYWdlci5nZXRGZWF0dXJlKENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuU0NIRU1BX1ZBTElEQVRJT05fRkVBVFVSRSwgZmFsc2UpKTsKLQotICAgICAgICAvLyBYZXJjZXMgZmVhdHVyZXMKLSAgICAgICAgZkR5bmFtaWNWYWxpZGF0aW9uID0gY29tcG9uZW50TWFuYWdlci5nZXRGZWF0dXJlKERZTkFNSUNfVkFMSURBVElPTiwgZmFsc2UpOwotICAgICAgICBmQmFsYW5jZVN5bnRheFRyZWVzID0gY29tcG9uZW50TWFuYWdlci5nZXRGZWF0dXJlKEJBTEFOQ0VfU1lOVEFYX1RSRUVTLCBmYWxzZSk7Ci0gICAgICAgIGZXYXJuRHVwbGljYXRlQXR0ZGVmID0gY29tcG9uZW50TWFuYWdlci5nZXRGZWF0dXJlKFdBUk5fT05fRFVQTElDQVRFX0FUVERFRiwgZmFsc2UpOwotCi0gICAgICAgIGZTY2hlbWFUeXBlID0gKFN0cmluZyljb21wb25lbnRNYW5hZ2VyLmdldFByb3BlcnR5IChDb25zdGFudHMuSkFYUF9QUk9QRVJUWV9QUkVGSVgKLSAgICAgICAgICAgICsgQ29uc3RhbnRzLlNDSEVNQV9MQU5HVUFHRSwgbnVsbCk7Ci0KLSAgICAgICAgZlZhbGlkYXRpb25NYW5hZ2VyPSAoVmFsaWRhdGlvbk1hbmFnZXIpY29tcG9uZW50TWFuYWdlci5nZXRQcm9wZXJ0eShWQUxJREFUSU9OX01BTkFHRVIpOwotICAgICAgICBmVmFsaWRhdGlvbk1hbmFnZXIuYWRkVmFsaWRhdGlvblN0YXRlKGZWYWxpZGF0aW9uU3RhdGUpOwotICAgICAgICBmVmFsaWRhdGlvblN0YXRlLnNldFVzaW5nTmFtZXNwYWNlcyhmTmFtZXNwYWNlcyk7Ci0KLSAgICAgICAgLy8gZ2V0IG5lZWRlZCBjb21wb25lbnRzCi0gICAgICAgIGZFcnJvclJlcG9ydGVyID0gKFhNTEVycm9yUmVwb3J0ZXIpY29tcG9uZW50TWFuYWdlci5nZXRQcm9wZXJ0eShDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCtDb25zdGFudHMuRVJST1JfUkVQT1JURVJfUFJPUEVSVFkpOwotICAgICAgICBmU3ltYm9sVGFibGUgPSAoU3ltYm9sVGFibGUpY29tcG9uZW50TWFuYWdlci5nZXRQcm9wZXJ0eShDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCtDb25zdGFudHMuU1lNQk9MX1RBQkxFX1BST1BFUlRZKTsKLSAgICAgICAgZkdyYW1tYXJQb29sPSAoWE1MR3JhbW1hclBvb2wpY29tcG9uZW50TWFuYWdlci5nZXRQcm9wZXJ0eShHUkFNTUFSX1BPT0wsIG51bGwpOwotCi0gICAgICAgIGZEYXRhdHlwZVZhbGlkYXRvckZhY3RvcnkgPSAoRFRERFZGYWN0b3J5KWNvbXBvbmVudE1hbmFnZXIuZ2V0UHJvcGVydHkoQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuREFUQVRZUEVfVkFMSURBVE9SX0ZBQ1RPUllfUFJPUEVSVFkpOwotICAgICAgICAgICAgICAgIGluaXQoKTsKLQotICAgIH0gLy8gcmVzZXQoWE1MQ29tcG9uZW50TWFuYWdlcikKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYSBsaXN0IG9mIGZlYXR1cmUgaWRlbnRpZmllcnMgdGhhdCBhcmUgcmVjb2duaXplZCBieQotICAgICAqIHRoaXMgY29tcG9uZW50LiBUaGlzIG1ldGhvZCBtYXkgcmV0dXJuIG51bGwgaWYgbm8gZmVhdHVyZXMKLSAgICAgKiBhcmUgcmVjb2duaXplZCBieSB0aGlzIGNvbXBvbmVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nW10gZ2V0UmVjb2duaXplZEZlYXR1cmVzKCkgewotICAgICAgICByZXR1cm4gKFN0cmluZ1tdKShSRUNPR05JWkVEX0ZFQVRVUkVTLmNsb25lKCkpOwotICAgIH0gLy8gZ2V0UmVjb2duaXplZEZlYXR1cmVzKCk6U3RyaW5nW10KLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIHN0YXRlIG9mIGEgZmVhdHVyZS4gVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBjb21wb25lbnQKLSAgICAgKiBtYW5hZ2VyIGFueSB0aW1lIGFmdGVyIHJlc2V0IHdoZW4gYSBmZWF0dXJlIGNoYW5nZXMgc3RhdGUuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBDb21wb25lbnRzIHNob3VsZCBzaWxlbnRseSBpZ25vcmUgZmVhdHVyZXMKLSAgICAgKiB0aGF0IGRvIG5vdCBhZmZlY3QgdGhlIG9wZXJhdGlvbiBvZiB0aGUgY29tcG9uZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIGZlYXR1cmVJZCBUaGUgZmVhdHVyZSBpZGVudGlmaWVyLgotICAgICAqIEBwYXJhbSBzdGF0ZSAgICAgVGhlIHN0YXRlIG9mIHRoZSBmZWF0dXJlLgotICAgICAqCi0gICAgICogQHRocm93cyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIFRoZSBjb21wb25lbnQgc2hvdWxkIG5vdCB0aHJvdwotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzIGV4Y2VwdGlvbi4KLSAgICAgKiBAdGhyb3dzIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBUaGUgY29tcG9uZW50IHNob3VsZCBub3QgdGhyb3cKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzIGV4Y2VwdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRGZWF0dXJlKFN0cmluZyBmZWF0dXJlSWQsIGJvb2xlYW4gc3RhdGUpCi0gICAgdGhyb3dzIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gewotICAgIH0gLy8gc2V0RmVhdHVyZShTdHJpbmcsYm9vbGVhbikKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYSBsaXN0IG9mIHByb3BlcnR5IGlkZW50aWZpZXJzIHRoYXQgYXJlIHJlY29nbml6ZWQgYnkKLSAgICAgKiB0aGlzIGNvbXBvbmVudC4gVGhpcyBtZXRob2QgbWF5IHJldHVybiBudWxsIGlmIG5vIHByb3BlcnRpZXMKLSAgICAgKiBhcmUgcmVjb2duaXplZCBieSB0aGlzIGNvbXBvbmVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nW10gZ2V0UmVjb2duaXplZFByb3BlcnRpZXMoKSB7Ci0gICAgICAgIHJldHVybiAoU3RyaW5nW10pKFJFQ09HTklaRURfUFJPUEVSVElFUy5jbG9uZSgpKTsKLSAgICB9IC8vIGdldFJlY29nbml6ZWRQcm9wZXJ0aWVzKCk6U3RyaW5nW10KLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIGEgcHJvcGVydHkuIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSB0aGUgY29tcG9uZW50Ci0gICAgICogbWFuYWdlciBhbnkgdGltZSBhZnRlciByZXNldCB3aGVuIGEgcHJvcGVydHkgY2hhbmdlcyB2YWx1ZS4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IENvbXBvbmVudHMgc2hvdWxkIHNpbGVudGx5IGlnbm9yZSBwcm9wZXJ0aWVzCi0gICAgICogdGhhdCBkbyBub3QgYWZmZWN0IHRoZSBvcGVyYXRpb24gb2YgdGhlIGNvbXBvbmVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBwcm9wZXJ0eUlkIFRoZSBwcm9wZXJ0eSBpZGVudGlmaWVyLgotICAgICAqIEBwYXJhbSB2YWx1ZSAgICAgIFRoZSB2YWx1ZSBvZiB0aGUgcHJvcGVydHkuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24gVGhlIGNvbXBvbmVudCBzaG91bGQgbm90IHRocm93Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMgZXhjZXB0aW9uLgotICAgICAqIEB0aHJvd3MgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIFRoZSBjb21wb25lbnQgc2hvdWxkIG5vdCB0aHJvdwotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMgZXhjZXB0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFByb3BlcnR5KFN0cmluZyBwcm9wZXJ0eUlkLCBPYmplY3QgdmFsdWUpCi0gICAgdGhyb3dzIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gewotICAgIH0gLy8gc2V0UHJvcGVydHkoU3RyaW5nLE9iamVjdCkKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIGRlZmF1bHQgc3RhdGUgZm9yIGEgZmVhdHVyZSwgb3IgbnVsbCBpZiB0aGlzCi0gICAgICogY29tcG9uZW50IGRvZXMgbm90IHdhbnQgdG8gcmVwb3J0IGEgZGVmYXVsdCB2YWx1ZSBmb3IgdGhpcwotICAgICAqIGZlYXR1cmUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZmVhdHVyZUlkIFRoZSBmZWF0dXJlIGlkZW50aWZpZXIuCi0gICAgICoKLSAgICAgKiBAc2luY2UgWGVyY2VzIDIuMi4wCi0gICAgICovCi0gICAgcHVibGljIEJvb2xlYW4gZ2V0RmVhdHVyZURlZmF1bHQoU3RyaW5nIGZlYXR1cmVJZCkgewotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IFJFQ09HTklaRURfRkVBVFVSRVMubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgIGlmIChSRUNPR05JWkVEX0ZFQVRVUkVTW2ldLmVxdWFscyhmZWF0dXJlSWQpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIEZFQVRVUkVfREVGQVVMVFNbaV07Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfSAvLyBnZXRGZWF0dXJlRGVmYXVsdChTdHJpbmcpOkJvb2xlYW4KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIGRlZmF1bHQgc3RhdGUgZm9yIGEgcHJvcGVydHksIG9yIG51bGwgaWYgdGhpcwotICAgICAqIGNvbXBvbmVudCBkb2VzIG5vdCB3YW50IHRvIHJlcG9ydCBhIGRlZmF1bHQgdmFsdWUgZm9yIHRoaXMKLSAgICAgKiBwcm9wZXJ0eS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBwcm9wZXJ0eUlkIFRoZSBwcm9wZXJ0eSBpZGVudGlmaWVyLgotICAgICAqCi0gICAgICogQHNpbmNlIFhlcmNlcyAyLjIuMAotICAgICAqLwotICAgIHB1YmxpYyBPYmplY3QgZ2V0UHJvcGVydHlEZWZhdWx0KFN0cmluZyBwcm9wZXJ0eUlkKSB7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgUkVDT0dOSVpFRF9QUk9QRVJUSUVTLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICBpZiAoUkVDT0dOSVpFRF9QUk9QRVJUSUVTW2ldLmVxdWFscyhwcm9wZXJ0eUlkKSkgewotICAgICAgICAgICAgICAgIHJldHVybiBQUk9QRVJUWV9ERUZBVUxUU1tpXTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9IC8vIGdldFByb3BlcnR5RGVmYXVsdChTdHJpbmcpOk9iamVjdAotCi0gICAgLy8KLSAgICAvLyBYTUxEb2N1bWVudFNvdXJjZSBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKiBTZXRzIHRoZSBkb2N1bWVudCBoYW5kbGVyIHRvIHJlY2VpdmUgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGRvY3VtZW50LiAqLwotICAgIHB1YmxpYyB2b2lkIHNldERvY3VtZW50SGFuZGxlcihYTUxEb2N1bWVudEhhbmRsZXIgZG9jdW1lbnRIYW5kbGVyKSB7Ci0gICAgICAgIGZEb2N1bWVudEhhbmRsZXIgPSBkb2N1bWVudEhhbmRsZXI7Ci0gICAgfSAvLyBzZXREb2N1bWVudEhhbmRsZXIoWE1MRG9jdW1lbnRIYW5kbGVyKQotCi0gICAgLyoqIFJldHVybnMgdGhlIGRvY3VtZW50IGhhbmRsZXIgKi8KLSAgICBwdWJsaWMgWE1MRG9jdW1lbnRIYW5kbGVyIGdldERvY3VtZW50SGFuZGxlcigpIHsKLSAgICAgICAgcmV0dXJuIGZEb2N1bWVudEhhbmRsZXI7Ci0gICAgfSAvLyBnZXREb2N1bWVudEhhbmRsZXIoKTogIFhNTERvY3VtZW50SGFuZGxlcgotCi0KLSAgICAvLwotICAgIC8vIFhNTERvY3VtZW50SGFuZGxlciBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKiBTZXRzIHRoZSBkb2N1bWVudCBzb3VyY2UgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXREb2N1bWVudFNvdXJjZShYTUxEb2N1bWVudFNvdXJjZSBzb3VyY2UpewotICAgICAgICBmRG9jdW1lbnRTb3VyY2UgPSBzb3VyY2U7Ci0gICAgfSAvLyBzZXREb2N1bWVudFNvdXJjZQotCi0gICAgLyoqIFJldHVybnMgdGhlIGRvY3VtZW50IHNvdXJjZSAqLwotICAgIHB1YmxpYyBYTUxEb2N1bWVudFNvdXJjZSBnZXREb2N1bWVudFNvdXJjZSAoKXsKLSAgICAgICAgcmV0dXJuIGZEb2N1bWVudFNvdXJjZTsKLSAgICB9IC8vIGdldERvY3VtZW50U291cmNlCi0KLSAgICAvKioKLSAgICAgKiBUaGUgc3RhcnQgb2YgdGhlIGRvY3VtZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIGxvY2F0b3IgVGhlIHN5c3RlbSBpZGVudGlmaWVyIG9mIHRoZSBlbnRpdHkgaWYgdGhlIGVudGl0eQotICAgICAqICAgICAgICAgICAgICAgICBpcyBleHRlcm5hbCwgbnVsbCBvdGhlcndpc2UuCi0gICAgICogQHBhcmFtIGVuY29kaW5nIFRoZSBhdXRvLWRldGVjdGVkIElBTkEgZW5jb2RpbmcgbmFtZSBvZiB0aGUgZW50aXR5Ci0gICAgICogICAgICAgICAgICAgICAgIHN0cmVhbS4gVGhpcyB2YWx1ZSB3aWxsIGJlIG51bGwgaW4gdGhvc2Ugc2l0dWF0aW9ucwotICAgICAqICAgICAgICAgICAgICAgICB3aGVyZSB0aGUgZW50aXR5IGVuY29kaW5nIGlzIG5vdCBhdXRvLWRldGVjdGVkIChlLmcuCi0gICAgICogICAgICAgICAgICAgICAgIGludGVybmFsIGVudGl0aWVzIG9yIGEgZG9jdW1lbnQgZW50aXR5IHRoYXQgaXMKLSAgICAgKiAgICAgICAgICAgICAgICAgcGFyc2VkIGZyb20gYSBqYXZhLmlvLlJlYWRlcikuCi0gICAgICogQHBhcmFtIG5hbWVzcGFjZUNvbnRleHQKLSAgICAgKiAgICAgICAgICAgICAgICAgVGhlIG5hbWVzcGFjZSBjb250ZXh0IGluIGVmZmVjdCBhdCB0aGUKLSAgICAgKiAgICAgICAgICAgICAgICAgc3RhcnQgb2YgdGhpcyBkb2N1bWVudC4KLSAgICAgKiAgICAgICAgICAgICAgICAgVGhpcyBvYmplY3QgcmVwcmVzZW50cyB0aGUgY3VycmVudCBjb250ZXh0LgotICAgICAqICAgICAgICAgICAgICAgICBJbXBsZW1lbnRvcnMgb2YgdGhpcyBjbGFzcyBhcmUgcmVzcG9uc2libGUKLSAgICAgKiAgICAgICAgICAgICAgICAgZm9yIGNvcHlpbmcgdGhlIG5hbWVzcGFjZSBiaW5kaW5ncyBmcm9tIHRoZQotICAgICAqICAgICAgICAgICAgICAgICB0aGUgY3VycmVudCBjb250ZXh0IChhbmQgaXRzIHBhcmVudCBjb250ZXh0cykKLSAgICAgKiAgICAgICAgICAgICAgICAgaWYgdGhhdCBpbmZvcm1hdGlvbiBpcyBpbXBvcnRhbnQuCi0gICAgICogQHBhcmFtIGF1Z3MgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnREb2N1bWVudChYTUxMb2NhdG9yIGxvY2F0b3IsIFN0cmluZyBlbmNvZGluZywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5hbWVzcGFjZUNvbnRleHQgbmFtZXNwYWNlQ29udGV4dCwgQXVnbWVudGF0aW9ucyBhdWdzKQotICAgIHRocm93cyBYTklFeGNlcHRpb24gewotCi0gICAgICAgIC8vIGNhbGwgaGFuZGxlcnMKLSAgICAgICAgLy8gZ2V0IGluaXRpYWwgZ3JhbW1hcnMKLSAgICAgICAgaWYgKGZHcmFtbWFyUG9vbCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBHcmFtbWFyIFtdIGdyYW1tYXJzID0gZkdyYW1tYXJQb29sLnJldHJpZXZlSW5pdGlhbEdyYW1tYXJTZXQoWE1MR3JhbW1hckRlc2NyaXB0aW9uLlhNTF9EVEQpOwotICAgICAgICAgICAgZmluYWwgaW50IGxlbmd0aCA9IChncmFtbWFycyAhPSBudWxsKSA/IGdyYW1tYXJzLmxlbmd0aCA6IDA7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7Ci0gICAgICAgICAgICAgICAgZkdyYW1tYXJCdWNrZXQucHV0R3JhbW1hcigoRFRER3JhbW1hcilncmFtbWFyc1tpXSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZkRvY0xvY2F0aW9uID0gbG9jYXRvcjsKLSAgICAgICAgZk5hbWVzcGFjZUNvbnRleHQgPSBuYW1lc3BhY2VDb250ZXh0OwotCi0gICAgICAgIGlmIChmRG9jdW1lbnRIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZEb2N1bWVudEhhbmRsZXIuc3RhcnREb2N1bWVudChsb2NhdG9yLCBlbmNvZGluZywgbmFtZXNwYWNlQ29udGV4dCwgYXVncyk7Ci0gICAgICAgIH0KLQotICAgIH0gLy8gc3RhcnREb2N1bWVudChYTUxMb2NhdG9yLFN0cmluZykKLQotICAgIC8qKgotICAgICAqIE5vdGlmaWVzIG9mIHRoZSBwcmVzZW5jZSBvZiBhbiBYTUxEZWNsIGxpbmUgaW4gdGhlIGRvY3VtZW50LiBJZgotICAgICAqIHByZXNlbnQsIHRoaXMgbWV0aG9kIHdpbGwgYmUgY2FsbGVkIGltbWVkaWF0ZWx5IGZvbGxvd2luZyB0aGUKLSAgICAgKiBzdGFydERvY3VtZW50IGNhbGwuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdmVyc2lvbiAgICBUaGUgWE1MIHZlcnNpb24uCi0gICAgICogQHBhcmFtIGVuY29kaW5nICAgVGhlIElBTkEgZW5jb2RpbmcgbmFtZSBvZiB0aGUgZG9jdW1lbnQsIG9yIG51bGwgaWYKLSAgICAgKiAgICAgICAgICAgICAgICAgICBub3Qgc3BlY2lmaWVkLgotICAgICAqIEBwYXJhbSBzdGFuZGFsb25lIFRoZSBzdGFuZGFsb25lIHZhbHVlLCBvciBudWxsIGlmIG5vdCBzcGVjaWZpZWQuCi0gICAgICogQHBhcmFtIGF1Z3MgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgeG1sRGVjbChTdHJpbmcgdmVyc2lvbiwgU3RyaW5nIGVuY29kaW5nLCBTdHJpbmcgc3RhbmRhbG9uZSwgQXVnbWVudGF0aW9ucyBhdWdzKQotICAgIHRocm93cyBYTklFeGNlcHRpb24gewotCi0gICAgICAgIC8vIHNhdmUgc3RhbmRhbG9uZSBzdGF0ZQotICAgICAgICBmR3JhbW1hckJ1Y2tldC5zZXRTdGFuZGFsb25lKHN0YW5kYWxvbmUgIT0gbnVsbCAmJiBzdGFuZGFsb25lLmVxdWFscygieWVzIikpOwotCi0gICAgICAgIC8vIGNhbGwgaGFuZGxlcnMKLSAgICAgICAgaWYgKGZEb2N1bWVudEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci54bWxEZWNsKHZlcnNpb24sIGVuY29kaW5nLCBzdGFuZGFsb25lLCBhdWdzKTsKLSAgICAgICAgfQotCi0gICAgfSAvLyB4bWxEZWNsKFN0cmluZyxTdHJpbmcsU3RyaW5nKQotCi0gICAgLyoqCi0gICAgICogTm90aWZpZXMgb2YgdGhlIHByZXNlbmNlIG9mIHRoZSBET0NUWVBFIGxpbmUgaW4gdGhlIGRvY3VtZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIHJvb3RFbGVtZW50IFRoZSBuYW1lIG9mIHRoZSByb290IGVsZW1lbnQuCi0gICAgICogQHBhcmFtIHB1YmxpY0lkICAgIFRoZSBwdWJsaWMgaWRlbnRpZmllciBpZiBhbiBleHRlcm5hbCBEVEQgb3IgbnVsbAotICAgICAqICAgICAgICAgICAgICAgICAgICBpZiB0aGUgZXh0ZXJuYWwgRFREIGlzIHNwZWNpZmllZCB1c2luZyBTWVNURU0uCi0gICAgICogQHBhcmFtIHN5c3RlbUlkICAgIFRoZSBzeXN0ZW0gaWRlbnRpZmllciBpZiBhbiBleHRlcm5hbCBEVEQsIG51bGwKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgb3RoZXJ3aXNlLgotICAgICAqIEBwYXJhbSBhdWdzICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGRvY3R5cGVEZWNsKFN0cmluZyByb290RWxlbWVudCwgU3RyaW5nIHB1YmxpY0lkLCBTdHJpbmcgc3lzdGVtSWQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgQXVnbWVudGF0aW9ucyBhdWdzKQotICAgIHRocm93cyBYTklFeGNlcHRpb24gewotCi0gICAgICAgIC8vIHNhdmUgcm9vdCBlbGVtZW50IHN0YXRlCi0gICAgICAgIGZTZWVuRG9jdHlwZURlY2wgPSB0cnVlOwotICAgICAgICBmUm9vdEVsZW1lbnQuc2V0VmFsdWVzKG51bGwsIHJvb3RFbGVtZW50LCByb290RWxlbWVudCwgbnVsbCk7Ci0gICAgICAgIC8vIGZpbmQgb3IgY3JlYXRlIGdyYW1tYXI6Ci0gICAgICAgIFN0cmluZyBlaWQgPSBudWxsOwotICAgICAgICB0cnkgewotICAgICAgICAgICAgZWlkID0gWE1MRW50aXR5TWFuYWdlci5leHBhbmRTeXN0ZW1JZChzeXN0ZW1JZCwgZkRvY0xvY2F0aW9uLmdldEV4cGFuZGVkU3lzdGVtSWQoKSwgZmFsc2UpOwotICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgfQotICAgICAgICBYTUxEVEREZXNjcmlwdGlvbiBncmFtbWFyRGVzYyA9IG5ldyBYTUxEVEREZXNjcmlwdGlvbihwdWJsaWNJZCwgc3lzdGVtSWQsIGZEb2NMb2NhdGlvbi5nZXRFeHBhbmRlZFN5c3RlbUlkKCksIGVpZCwgcm9vdEVsZW1lbnQpOwotICAgICAgICBmRFRER3JhbW1hciA9IGZHcmFtbWFyQnVja2V0LmdldEdyYW1tYXIoZ3JhbW1hckRlc2MpOwotICAgICAgICBpZihmRFRER3JhbW1hciA9PSBudWxsKSB7Ci0gICAgICAgICAgICAvLyBnaXZlIGdyYW1tYXIgcG9vbCBhIGNoYW5jZS4uLgotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIC8vIERvIG5vdCBib3RoZXIgY2hlY2tpbmcgdGhlIHBvb2wgaWYgbm8gcHVibGljIG9yIHN5c3RlbSBpZGVudGlmaWVyIHdhcyBwcm92aWRlZC4KLSAgICAgICAgICAgIC8vIFNpbmNlIHNvIG1hbnkgZGlmZmVyZW50IERURHMgaGF2ZSByb290cyBpbiBjb21tb24sIHVzaW5nIG9ubHkgYSByb290IG5hbWUgYXMgdGhlCi0gICAgICAgICAgICAvLyBrZXkgbWF5IGNhdXNlIGFuIHVuZXhwZWN0ZWQgZ3JhbW1hciB0byBiZSByZXRyaWV2ZWQgZnJvbSB0aGUgZ3JhbW1hciBwb29sLiBUaGlzIHNjZW5hcmlvCi0gICAgICAgICAgICAvLyB3b3VsZCBvY2N1ciB3aGVuIGFuIEV4dGVybmFsU3Vic2V0UmVzb2x2ZXIgaGFzIGJlZW4gcXVlcmllZCBhbmQgdGhlCi0gICAgICAgICAgICAvLyBYTUxJbnB1dFNvdXJjZSByZXR1cm5lZCBjb250YWlucyBhbiBpbnB1dCBzdHJlYW0gYnV0IG5vIGV4dGVybmFsIGlkZW50aWZpZXIuCi0gICAgICAgICAgICAvLyBUaGlzIGNhbiBuZXZlciBoYXBwZW4gd2hlbiB0aGUgaW5zdGFuY2UgZG9jdW1lbnQgc3BlY2lmaWVkIGEgRE9DVFlQRS4gLS0gbXJnbGF2YXMKLSAgICAgICAgICAgIGlmIChmR3JhbW1hclBvb2wgIT0gbnVsbCAmJiAoc3lzdGVtSWQgIT0gbnVsbCB8fCBwdWJsaWNJZCAhPSBudWxsKSkgewotICAgICAgICAgICAgICAgIGZEVERHcmFtbWFyID0gKERUREdyYW1tYXIpZkdyYW1tYXJQb29sLnJldHJpZXZlR3JhbW1hcihncmFtbWFyRGVzYyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgaWYoZkRUREdyYW1tYXIgPT0gbnVsbCkgewotICAgICAgICAgICAgLy8gd2UnbGwgaGF2ZSB0byBjcmVhdGUgaXQuLi4KLSAgICAgICAgICAgIGlmICghZkJhbGFuY2VTeW50YXhUcmVlcykgewotICAgICAgICAgICAgICAgIGZEVERHcmFtbWFyID0gbmV3IERUREdyYW1tYXIoZlN5bWJvbFRhYmxlLCBncmFtbWFyRGVzYyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBmRFRER3JhbW1hciA9IG5ldyBCYWxhbmNlZERUREdyYW1tYXIoZlN5bWJvbFRhYmxlLCBncmFtbWFyRGVzYyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAvLyB3ZSd2ZSBmb3VuZCBhIGNhY2hlZCBvbmU7c28gbGV0J3MgbWFrZSBzdXJlIG5vdCB0byByZWFkCi0gICAgICAgICAgICAvLyBhbnkgZXh0ZXJuYWwgc3Vic2V0IQotICAgICAgICAgICAgZlZhbGlkYXRpb25NYW5hZ2VyLnNldENhY2hlZERURCh0cnVlKTsKLSAgICAgICAgfQotICAgICAgICBmR3JhbW1hckJ1Y2tldC5zZXRBY3RpdmVHcmFtbWFyKGZEVERHcmFtbWFyKTsKLQotICAgICAgICAvLyBjYWxsIGhhbmRsZXJzCi0gICAgICAgIGlmIChmRG9jdW1lbnRIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZEb2N1bWVudEhhbmRsZXIuZG9jdHlwZURlY2wocm9vdEVsZW1lbnQsIHB1YmxpY0lkLCBzeXN0ZW1JZCwgYXVncyk7Ci0gICAgICAgIH0KLQotICAgIH0gLy8gZG9jdHlwZURlY2woU3RyaW5nLFN0cmluZyxTdHJpbmcsIEF1Z21lbnRhdGlvbnMpCi0KLQotICAgIC8qKgotICAgICAqIFRoZSBzdGFydCBvZiBhbiBlbGVtZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIGVsZW1lbnQgICAgVGhlIG5hbWUgb2YgdGhlIGVsZW1lbnQuCi0gICAgICogQHBhcmFtIGF0dHJpYnV0ZXMgVGhlIGVsZW1lbnQgYXR0cmlidXRlcy4KLSAgICAgKiBAcGFyYW0gYXVncyAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQoUU5hbWUgZWxlbWVudCwgWE1MQXR0cmlidXRlcyBhdHRyaWJ1dGVzLCBBdWdtZW50YXRpb25zIGF1Z3MpCi0gICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgaGFuZGxlU3RhcnRFbGVtZW50KGVsZW1lbnQsIGF0dHJpYnV0ZXMsIGF1Z3MpOwotICAgICAgICAvLyBjYWxsIGhhbmRsZXJzCi0gICAgICAgIGlmIChmRG9jdW1lbnRIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZEb2N1bWVudEhhbmRsZXIuc3RhcnRFbGVtZW50KGVsZW1lbnQsIGF0dHJpYnV0ZXMsIGF1Z3MpOwotCi0gICAgICAgIH0KLQotICAgIH0gLy8gc3RhcnRFbGVtZW50KFFOYW1lLFhNTEF0dHJpYnV0ZXMpCi0KLSAgICAvKioKLSAgICAgKiBBbiBlbXB0eSBlbGVtZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIGVsZW1lbnQgICAgVGhlIG5hbWUgb2YgdGhlIGVsZW1lbnQuCi0gICAgICogQHBhcmFtIGF0dHJpYnV0ZXMgVGhlIGVsZW1lbnQgYXR0cmlidXRlcy4KLSAgICAgKiBAcGFyYW0gYXVncyAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbXB0eUVsZW1lbnQoUU5hbWUgZWxlbWVudCwgWE1MQXR0cmlidXRlcyBhdHRyaWJ1dGVzLCBBdWdtZW50YXRpb25zIGF1Z3MpCi0gICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgYm9vbGVhbiByZW1vdmVkID0gaGFuZGxlU3RhcnRFbGVtZW50KGVsZW1lbnQsIGF0dHJpYnV0ZXMsIGF1Z3MpOwotCi0gICAgICAgIGlmIChmRG9jdW1lbnRIYW5kbGVyICE9bnVsbCkgewotICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci5lbXB0eUVsZW1lbnQoZWxlbWVudCwgYXR0cmlidXRlcywgYXVncyk7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKCFyZW1vdmVkKSB7Ci0gICAgICAgICAgICBoYW5kbGVFbmRFbGVtZW50KGVsZW1lbnQsIGF1Z3MsIHRydWUpOwotICAgICAgICB9Ci0KLQotICAgIH0gLy8gZW1wdHlFbGVtZW50KFFOYW1lLFhNTEF0dHJpYnV0ZXMpCi0KLSAgICAvKioKLSAgICAgKiBDaGFyYWN0ZXIgY29udGVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSB0ZXh0IFRoZSBjb250ZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIGF1Z3MgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY2hhcmFjdGVycyhYTUxTdHJpbmcgdGV4dCwgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLQotICAgICAgICBib29sZWFuIGNhbGxOZXh0Q2hhcmFjdGVycyA9IHRydWU7Ci0KLSAgICAgICAgLy8gUkVWSVNJVDogW1FdIElzIHRoZXJlIGEgbW9yZSBlZmZpY2llbnQgd2F5IG9mIGRvaW5nIHRoaXM/Ci0gICAgICAgIC8vICAgICAgICAgIFBlcmhhcHMgaWYgdGhlIHNjYW5uZXIgdG9sZCB1cyBzbyB3ZSBkb24ndCBoYXZlIHRvCi0gICAgICAgIC8vICAgICAgICAgIGxvb2sgYXQgdGhlIGNoYXJhY3RlcnMgYWdhaW4uIC1BYwotICAgICAgICBib29sZWFuIGFsbFdoaXRlU3BhY2UgPSB0cnVlOwotICAgICAgICBmb3IgKGludCBpPXRleHQub2Zmc2V0OyBpPCB0ZXh0Lm9mZnNldCt0ZXh0Lmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICBpZiAoIWlzU3BhY2UodGV4dC5jaFtpXSkpIHsKLSAgICAgICAgICAgICAgICBhbGxXaGl0ZVNwYWNlID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgLy8gY2FsbCB0aGUgaWdub3JlYWJsZVdoaXRlU3BhY2UgY2FsbGJhY2sKLSAgICAgICAgLy8gbmV2ZXIgY2FsbCBpZ25vcmFibGVXaGl0ZXNwYWNlIGlmIHdlIGFyZSBpbiBjZGF0YSBzZWN0aW9uCi0gICAgICAgIGlmIChmSW5FbGVtZW50Q29udGVudCAmJiBhbGxXaGl0ZVNwYWNlICYmICFmSW5DREFUQVNlY3Rpb24pIHsKLSAgICAgICAgICAgIGlmIChmRG9jdW1lbnRIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLmlnbm9yYWJsZVdoaXRlc3BhY2UodGV4dCwgYXVncyk7Ci0gICAgICAgICAgICAgICAgY2FsbE5leHRDaGFyYWN0ZXJzID0gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyB2YWxpZGF0ZQotICAgICAgICBpZiAoZlBlcmZvcm1WYWxpZGF0aW9uKSB7Ci0gICAgICAgICAgICBpZiAoZkluRWxlbWVudENvbnRlbnQpIHsKLSAgICAgICAgICAgICAgICBpZiAoZkdyYW1tYXJCdWNrZXQuZ2V0U3RhbmRhbG9uZSgpICYmCi0gICAgICAgICAgICAgICAgICAgIGZEVERHcmFtbWFyLmdldEVsZW1lbnREZWNsSXNFeHRlcm5hbChmQ3VycmVudEVsZW1lbnRJbmRleCkpIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGFsbFdoaXRlU3BhY2UpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKCBYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1TR19XSElURV9TUEFDRV9JTl9FTEVNRU5UX0NPTlRFTlRfV0hFTl9TVEFOREFMT05FIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLCBYTUxFcnJvclJlcG9ydGVyLlNFVkVSSVRZX0VSUk9SKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpZiAoIWFsbFdoaXRlU3BhY2UpIHsKLSAgICAgICAgICAgICAgICAgICAgY2hhckRhdGFJbkNvbnRlbnQoKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyBGb3IgRTE1LjIKLSAgICAgICAgICAgICAgICBpZiAoYXVncyAhPSBudWxsICYmIGF1Z3MuZ2V0SXRlbShDb25zdGFudHMuQ0hBUl9SRUZfUFJPQkFCTEVfV1MpID09IEJvb2xlYW4uVFJVRSkgewotICAgICAgICAgICAgICAgICAgICBmRXJyb3JSZXBvcnRlci5yZXBvcnRFcnJvcihYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNU0dfQ09OVEVOVF9JTlZBTElEX1NQRUNJRklFRCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXsgZkN1cnJlbnRFbGVtZW50LnJhd25hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmRFRER3JhbW1hci5nZXRDb250ZW50U3BlY0FzU3RyaW5nKGZFbGVtZW50RGVwdGgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImNoYXJhY3RlciByZWZlcmVuY2UifSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9FUlJPUik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAoZkN1cnJlbnRDb250ZW50U3BlY1R5cGUgPT0gWE1MRWxlbWVudERlY2wuVFlQRV9FTVBUWSkgewotICAgICAgICAgICAgICAgIGNoYXJEYXRhSW5Db250ZW50KCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBjYWxsIGhhbmRsZXJzCi0gICAgICAgIGlmIChjYWxsTmV4dENoYXJhY3RlcnMgJiYgZkRvY3VtZW50SGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLmNoYXJhY3RlcnModGV4dCwgYXVncyk7Ci0gICAgICAgIH0KLQotICAgIH0gLy8gY2hhcmFjdGVycyhYTUxTdHJpbmcpCi0KLQotCi0gICAgLyoqCi0gICAgICogSWdub3JhYmxlIHdoaXRlc3BhY2UuIEZvciB0aGlzIG1ldGhvZCB0byBiZSBjYWxsZWQsIHRoZSBkb2N1bWVudAotICAgICAqIHNvdXJjZSBtdXN0IGhhdmUgc29tZSB3YXkgb2YgZGV0ZXJtaW5pbmcgdGhhdCB0aGUgdGV4dCBjb250YWluaW5nCi0gICAgICogb25seSB3aGl0ZXNwYWNlIGNoYXJhY3RlcnMgc2hvdWxkIGJlIGNvbnNpZGVyZWQgaWdub3JhYmxlLiBGb3IKLSAgICAgKiBleGFtcGxlLCB0aGUgdmFsaWRhdG9yIGNhbiBkZXRlcm1pbmUgaWYgYSBsZW5ndGggb2Ygd2hpdGVzcGFjZQotICAgICAqIGNoYXJhY3RlcnMgaW4gdGhlIGRvY3VtZW50IGFyZSBpZ25vcmFibGUgYmFzZWQgb24gdGhlIGVsZW1lbnQKLSAgICAgKiBjb250ZW50IG1vZGVsLgotICAgICAqCi0gICAgICogQHBhcmFtIHRleHQgVGhlIGlnbm9yYWJsZSB3aGl0ZXNwYWNlLgotICAgICAqIEBwYXJhbSBhdWdzICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGlnbm9yYWJsZVdoaXRlc3BhY2UoWE1MU3RyaW5nIHRleHQsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy8gY2FsbCBoYW5kbGVycwotICAgICAgICBpZiAoZkRvY3VtZW50SGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLmlnbm9yYWJsZVdoaXRlc3BhY2UodGV4dCwgYXVncyk7Ci0gICAgICAgIH0KLQotICAgIH0gLy8gaWdub3JhYmxlV2hpdGVzcGFjZShYTUxTdHJpbmcpCi0KLSAgICAvKioKLSAgICAgKiBUaGUgZW5kIG9mIGFuIGVsZW1lbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZWxlbWVudCBUaGUgbmFtZSBvZiB0aGUgZWxlbWVudC4KLSAgICAgKiBAcGFyYW0gYXVncyAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbmRFbGVtZW50KFFOYW1lIGVsZW1lbnQsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgaGFuZGxlRW5kRWxlbWVudChlbGVtZW50LCAgYXVncywgZmFsc2UpOwotCi0gICAgfSAvLyBlbmRFbGVtZW50KFFOYW1lKQotCi0gICAgLyoqCi0gICAgICogVGhlIHN0YXJ0IG9mIGEgQ0RBVEEgc2VjdGlvbi4KLSAgICAgKiBAcGFyYW0gYXVncyAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydENEQVRBKEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgaWYgKGZQZXJmb3JtVmFsaWRhdGlvbiAmJiBmSW5FbGVtZW50Q29udGVudCkgewotICAgICAgICAgICAgY2hhckRhdGFJbkNvbnRlbnQoKTsKLSAgICAgICAgfQotICAgICAgICBmSW5DREFUQVNlY3Rpb24gPSB0cnVlOwotICAgICAgICAvLyBjYWxsIGhhbmRsZXJzCi0gICAgICAgIGlmIChmRG9jdW1lbnRIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZEb2N1bWVudEhhbmRsZXIuc3RhcnRDREFUQShhdWdzKTsKLSAgICAgICAgfQotCi0gICAgfSAvLyBzdGFydENEQVRBKCkKLQotICAgIC8qKgotICAgICAqIFRoZSBlbmQgb2YgYSBDREFUQSBzZWN0aW9uLgotICAgICAqIEBwYXJhbSBhdWdzICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZENEQVRBKEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgZkluQ0RBVEFTZWN0aW9uID0gZmFsc2U7Ci0gICAgICAgIC8vIGNhbGwgaGFuZGxlcnMKLSAgICAgICAgaWYgKGZEb2N1bWVudEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci5lbmRDREFUQShhdWdzKTsKLSAgICAgICAgfQotCi0gICAgfSAvLyBlbmRDREFUQSgpCi0KLSAgICAvKioKLSAgICAgKiBUaGUgZW5kIG9mIHRoZSBkb2N1bWVudC4KLSAgICAgKiBAcGFyYW0gYXVncyAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbmREb2N1bWVudChBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotCi0gICAgICAgIC8vIGNhbGwgaGFuZGxlcnMKLSAgICAgICAgaWYgKGZEb2N1bWVudEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci5lbmREb2N1bWVudChhdWdzKTsKLSAgICAgICAgfQotCi0gICAgfSAvLyBlbmREb2N1bWVudCgpCi0KLSAgICAvKioKLSAgICAgKiBBIGNvbW1lbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdGV4dCBUaGUgdGV4dCBpbiB0aGUgY29tbWVudC4KLSAgICAgKiBAcGFyYW0gYXVncyAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBhcHBsaWNhdGlvbiB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY29tbWVudChYTUxTdHJpbmcgdGV4dCwgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgLy8gZml4ZXMgRTE1LjEKLSAgICAgICAgaWYgKGZQZXJmb3JtVmFsaWRhdGlvbiAmJiBmRWxlbWVudERlcHRoID49IDAgJiYgZkRUREdyYW1tYXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkRUREdyYW1tYXIuZ2V0RWxlbWVudERlY2woZkN1cnJlbnRFbGVtZW50SW5kZXgsIGZUZW1wRWxlbWVudERlY2wpOwotICAgICAgICAgICAgaWYgKGZUZW1wRWxlbWVudERlY2wudHlwZSA9PSBYTUxFbGVtZW50RGVjbC5UWVBFX0VNUFRZKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1TR19DT05URU5UX0lOVkFMSURfU1BFQ0lGSUVEIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdeyBmQ3VycmVudEVsZW1lbnQucmF3bmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRU1QVFkiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJjb21tZW50In0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTEVycm9yUmVwb3J0ZXIuU0VWRVJJVFlfRVJST1IpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIC8vIGNhbGwgaGFuZGxlcnMKLSAgICAgICAgaWYgKGZEb2N1bWVudEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci5jb21tZW50KHRleHQsIGF1Z3MpOwotICAgICAgICB9Ci0KLSAgICB9IC8vIGNvbW1lbnQoWE1MU3RyaW5nKQotCi0KLSAgICAvKioKLSAgICAgKiBBIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24uIFByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb25zIGNvbnNpc3Qgb2YgYQotICAgICAqIHRhcmdldCBuYW1lIGFuZCwgb3B0aW9uYWxseSwgdGV4dCBkYXRhLiBUaGUgZGF0YSBpcyBvbmx5IG1lYW5pbmdmdWwKLSAgICAgKiB0byB0aGUgYXBwbGljYXRpb24uCi0gICAgICogPHA+Ci0gICAgICogVHlwaWNhbGx5LCBhIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24ncyBkYXRhIHdpbGwgY29udGFpbiBhIHNlcmllcwotICAgICAqIG9mIHBzZXVkby1hdHRyaWJ1dGVzLiBUaGVzZSBwc2V1ZG8tYXR0cmlidXRlcyBmb2xsb3cgdGhlIGZvcm0gb2YKLSAgICAgKiBlbGVtZW50IGF0dHJpYnV0ZXMgYnV0IGFyZSA8c3Ryb25nPm5vdDwvc3Ryb25nPiBwYXJzZWQgb3IgcHJlc2VudGVkCi0gICAgICogdG8gdGhlIGFwcGxpY2F0aW9uIGFzIGFueXRoaW5nIG90aGVyIHRoYW4gdGV4dC4gVGhlIGFwcGxpY2F0aW9uIGlzCi0gICAgICogcmVzcG9uc2libGUgZm9yIHBhcnNpbmcgdGhlIGRhdGEuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdGFyZ2V0IFRoZSB0YXJnZXQuCi0gICAgICogQHBhcmFtIGRhdGEgICBUaGUgZGF0YSBvciBudWxsIGlmIG5vbmUgc3BlY2lmaWVkLgotICAgICAqIEBwYXJhbSBhdWdzICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHByb2Nlc3NpbmdJbnN0cnVjdGlvbihTdHJpbmcgdGFyZ2V0LCBYTUxTdHJpbmcgZGF0YSwgQXVnbWVudGF0aW9ucyBhdWdzKQotICAgIHRocm93cyBYTklFeGNlcHRpb24gewotCi0gICAgICAgIC8vIGZpeGVzIEUxNS4xCi0gICAgICAgIGlmIChmUGVyZm9ybVZhbGlkYXRpb24gJiYgZkVsZW1lbnREZXB0aCA+PSAwICYmIGZEVERHcmFtbWFyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZEVERHcmFtbWFyLmdldEVsZW1lbnREZWNsKGZDdXJyZW50RWxlbWVudEluZGV4LCBmVGVtcEVsZW1lbnREZWNsKTsKLSAgICAgICAgICAgIGlmIChmVGVtcEVsZW1lbnREZWNsLnR5cGUgPT0gWE1MRWxlbWVudERlY2wuVFlQRV9FTVBUWSkgewotICAgICAgICAgICAgICAgICAgICBmRXJyb3JSZXBvcnRlci5yZXBvcnRFcnJvcihYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNU0dfQ09OVEVOVF9JTlZBTElEX1NQRUNJRklFRCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXsgZkN1cnJlbnRFbGVtZW50LnJhd25hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkVNUFRZIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAicHJvY2Vzc2luZyBpbnN0cnVjdGlvbiJ9LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxFcnJvclJlcG9ydGVyLlNFVkVSSVRZX0VSUk9SKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICAvLyBjYWxsIGhhbmRsZXJzCi0gICAgICAgIGlmIChmRG9jdW1lbnRIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZEb2N1bWVudEhhbmRsZXIucHJvY2Vzc2luZ0luc3RydWN0aW9uKHRhcmdldCwgZGF0YSwgYXVncyk7Ci0gICAgICAgIH0KLSAgICB9IC8vIHByb2Nlc3NpbmdJbnN0cnVjdGlvbihTdHJpbmcsWE1MU3RyaW5nKQotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2Qgbm90aWZpZXMgdGhlIHN0YXJ0IG9mIGEgZ2VuZXJhbCBlbnRpdHkuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGlzIG1ldGhvZCBpcyBub3QgY2FsbGVkIGZvciBlbnRpdHkgcmVmZXJlbmNlcwotICAgICAqIGFwcGVhcmluZyBhcyBwYXJ0IG9mIGF0dHJpYnV0ZSB2YWx1ZXMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSAgICAgVGhlIG5hbWUgb2YgdGhlIGdlbmVyYWwgZW50aXR5LgotICAgICAqIEBwYXJhbSBpZGVudGlmaWVyIFRoZSByZXNvdXJjZSBpZGVudGlmaWVyLgotICAgICAqIEBwYXJhbSBlbmNvZGluZyBUaGUgYXV0by1kZXRlY3RlZCBJQU5BIGVuY29kaW5nIG5hbWUgb2YgdGhlIGVudGl0eQotICAgICAqICAgICAgICAgICAgICAgICBzdHJlYW0uIFRoaXMgdmFsdWUgd2lsbCBiZSBudWxsIGluIHRob3NlIHNpdHVhdGlvbnMKLSAgICAgKiAgICAgICAgICAgICAgICAgd2hlcmUgdGhlIGVudGl0eSBlbmNvZGluZyBpcyBub3QgYXV0by1kZXRlY3RlZCAoZS5nLgotICAgICAqICAgICAgICAgICAgICAgICBpbnRlcm5hbCBlbnRpdGllcyBvciBhIGRvY3VtZW50IGVudGl0eSB0aGF0IGlzCi0gICAgICogICAgICAgICAgICAgICAgIHBhcnNlZCBmcm9tIGEgamF2YS5pby5SZWFkZXIpLgotICAgICAqIEBwYXJhbSBhdWdzICAgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnRHZW5lcmFsRW50aXR5KFN0cmluZyBuYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxSZXNvdXJjZUlkZW50aWZpZXIgaWRlbnRpZmllciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGVuY29kaW5nLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBpZiAoZlBlcmZvcm1WYWxpZGF0aW9uICYmIGZFbGVtZW50RGVwdGggPj0gMCAmJiBmRFRER3JhbW1hciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmRFRER3JhbW1hci5nZXRFbGVtZW50RGVjbChmQ3VycmVudEVsZW1lbnRJbmRleCwgZlRlbXBFbGVtZW50RGVjbCk7Ci0gICAgICAgICAgICAvLyBmaXhlcyBFMTUuMQotICAgICAgICAgICAgaWYgKGZUZW1wRWxlbWVudERlY2wudHlwZSA9PSBYTUxFbGVtZW50RGVjbC5UWVBFX0VNUFRZKSB7Ci0gICAgICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNU0dfQ09OVEVOVF9JTlZBTElEX1NQRUNJRklFRCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdeyBmQ3VycmVudEVsZW1lbnQucmF3bmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJFTVBUWSIsICJFTlRJVFkifSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxFcnJvclJlcG9ydGVyLlNFVkVSSVRZX0VSUk9SKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChmR3JhbW1hckJ1Y2tldC5nZXRTdGFuZGFsb25lKCkpIHsKLSAgICAgICAgICAgICAgICBYTUxEVERMb2FkZXIuY2hlY2tTdGFuZGFsb25lRW50aXR5UmVmKG5hbWUsIGZEVERHcmFtbWFyLCBmRW50aXR5RGVjbCwgZkVycm9yUmVwb3J0ZXIpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGlmIChmRG9jdW1lbnRIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZEb2N1bWVudEhhbmRsZXIuc3RhcnRHZW5lcmFsRW50aXR5KG5hbWUsIGlkZW50aWZpZXIsIGVuY29kaW5nLCBhdWdzKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIG5vdGlmaWVzIHRoZSBlbmQgb2YgYSBnZW5lcmFsIGVudGl0eS4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoaXMgbWV0aG9kIGlzIG5vdCBjYWxsZWQgZm9yIGVudGl0eSByZWZlcmVuY2VzCi0gICAgICogYXBwZWFyaW5nIGFzIHBhcnQgb2YgYXR0cmlidXRlIHZhbHVlcy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lICAgVGhlIG5hbWUgb2YgdGhlIGVudGl0eS4KLSAgICAgKiBAcGFyYW0gYXVncyAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKgotICAgICAqIEBleGNlcHRpb24gWE5JRXhjZXB0aW9uCi0gICAgICogICAgICAgICAgICAgICAgICAgVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZEdlbmVyYWxFbnRpdHkoU3RyaW5nIG5hbWUsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIC8vIGNhbGwgaGFuZGxlcnMKLSAgICAgICAgaWYgKGZEb2N1bWVudEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci5lbmRHZW5lcmFsRW50aXR5KG5hbWUsIGF1Z3MpOwotICAgICAgICB9Ci0gICAgfSAvLyBlbmRFbnRpdHkoU3RyaW5nKQotCi0gICAgLyoqCi0gICAgICogTm90aWZpZXMgb2YgdGhlIHByZXNlbmNlIG9mIGEgVGV4dERlY2wgbGluZSBpbiBhbiBlbnRpdHkuIElmIHByZXNlbnQsCi0gICAgICogdGhpcyBtZXRob2Qgd2lsbCBiZSBjYWxsZWQgaW1tZWRpYXRlbHkgZm9sbG93aW5nIHRoZSBzdGFydFBhcmFtZXRlckVudGl0eSBjYWxsLgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gVGhpcyBtZXRob2QgaXMgb25seSBjYWxsZWQgZm9yIGV4dGVybmFsCi0gICAgICogcGFyYW1ldGVyIGVudGl0aWVzIHJlZmVyZW5jZWQgaW4gdGhlIERURC4KLSAgICAgKgotICAgICAqIEBwYXJhbSB2ZXJzaW9uICBUaGUgWE1MIHZlcnNpb24sIG9yIG51bGwgaWYgbm90IHNwZWNpZmllZC4KLSAgICAgKiBAcGFyYW0gZW5jb2RpbmcgVGhlIElBTkEgZW5jb2RpbmcgbmFtZSBvZiB0aGUgZW50aXR5LgotICAgICAqIEBwYXJhbSBhdWdzIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0ZXh0RGVjbChTdHJpbmcgdmVyc2lvbiwgU3RyaW5nIGVuY29kaW5nLCBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotCi0gICAgICAgIC8vIGNhbGwgaGFuZGxlcnMKLSAgICAgICAgaWYgKGZEb2N1bWVudEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci50ZXh0RGVjbCh2ZXJzaW9uLCBlbmNvZGluZywgYXVncyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGhhc0dyYW1tYXIoKXsKLQotICAgICAgICByZXR1cm4gKGZEVERHcmFtbWFyICE9IG51bGwpOwotICAgIH0KLQotICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIHZhbGlkYXRlKCl7Ci0gICAgICAgIC8vIERvIHZhbGlkYXRpb24gaWYgYWxsIG9mIHRoZSBmb2xsb3dpbmcgYXJlIHRydWU6Ci0gICAgICAgIC8vIDEuIFRoZSBKQVhQIFNjaGVtYSBMYW5ndWFnZSBwcm9wZXJ0eSBpcyBub3QgWE1MIFNjaGVtYQotICAgICAgICAvLyAgICBSRVZJU0lUOiBzaW5jZSBvbmx5IERURCBhbmQgU2NoZW1hIGFyZSBzdXBwb3J0ZWQgYXQgdGhpcyB0aW1lLAotICAgICAgICAvLyAgICAgICAgICAgICBzdWNoIGNoZWNraW5nIGlzIHN1ZmZpY2llbnQuIGJ1dCBpZiBtb3JlIHNjaGVtYSB0eXBlcwotICAgICAgICAvLyAgICAgICAgICAgICBhcmUgaW50cm9kdWNlZCBpbiB0aGUgZnV0dXJlLCB3ZSdsbCBuZWVkIHRvIGNoYW5nZSBpdAotICAgICAgICAvLyAgICAgICAgICAgICB0byBzb21ldGhpbmcgbGlrZQotICAgICAgICAvLyAgICAgICAgICAgICAoZlNjaGVtYVR5cGUgPT0gbnVsbCB8fCBmU2NoZW1hVHlwZSA9PSBOU19YTUxfRFREKQotICAgICAgICAvLyAyLiBPbmUgb2YgdGhlIGZvbGxvd2luZyBpcyB0cnVlICh2YWxpZGF0aW9uIGZlYXR1cmVzKQotICAgICAgICAvLyAyLjEgRHluYW1pYyB2YWxpZGF0aW9uIGlzIG9mZiwgYW5kIHZhbGlkYXRpb24gaXMgb24KLSAgICAgICAgLy8gMi4yIER5bmFtaWMgdmFsaWRhdGlvbiBpcyBvbiwgYW5kIERPQ1RZUEUgd2FzIHNlZW4KLSAgICAgICAgLy8gMyBYZXJjZXMgc2NoZW1hIHZhbGlkYXRpb24gZmVhdHVyZSBpcyBvZmYsIG9yIERPQ1RZUEUgd2FzIHNlZW4uCi0gICAgICAgIHJldHVybiAoZlNjaGVtYVR5cGUgIT0gQ29uc3RhbnRzLk5TX1hNTFNDSEVNQSkgJiYKLSAgICAgICAgICAgICAgICghZkR5bmFtaWNWYWxpZGF0aW9uICYmIGZWYWxpZGF0aW9uIHx8Ci0gICAgICAgICAgICAgICAgZkR5bmFtaWNWYWxpZGF0aW9uICYmIGZTZWVuRG9jdHlwZURlY2wpICYmCi0gICAgICAgICAgICAgICAoZkRURFZhbGlkYXRpb24gfHwgZlNlZW5Eb2N0eXBlRGVjbCk7Ci0gICAgfQotCi0gICAgICAgICAgICAvL1JFVklTSVQ6d2UgY2FuIGNvbnZlcnQgaW50byBmdW5jdGlvbnMuLiBhZGRpbmcgZGVmYXVsdCBhdHRyaWJ1dGUgdmFsdWVzLi4gYW5kIG9uZSB2YWxpZGF0aW5nLgotCi0gICAgLyoqIEFkZCBkZWZhdWx0IGF0dHJpYnV0ZXMgYW5kIHZhbGlkYXRlLiAqLwotICAgIHByb3RlY3RlZCB2b2lkIGFkZERURERlZmF1bHRBdHRyc0FuZFZhbGlkYXRlKFFOYW1lIGVsZW1lbnROYW1lLCBpbnQgZWxlbWVudEluZGV4LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMpCi0gICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy8gaXMgdGhlcmUgYW55dGhpbmcgdG8gZG8/Ci0gICAgICAgIGlmIChlbGVtZW50SW5kZXggPT0gLTEgfHwgZkRUREdyYW1tYXIgPT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gQ2hlY2sgYWZ0ZXIgYWxsIHNwZWNpZmllZCBhdHRycyBhcmUgc2Nhbm5lZAotICAgICAgICAvLyAoMSkgcmVwb3J0IGVycm9yIGZvciBSRVFVSVJFRCBhdHRycyB0aGF0IGFyZSBtaXNzaW5nIChWX1RBR2MpCi0gICAgICAgIC8vICgyKSBhZGQgZGVmYXVsdCBhdHRycyAoRklYRUQgYW5kIE5PVF9GSVhFRCkKLSAgICAgICAgLy8KLSAgICAgICAgaW50IGF0dGxpc3RJbmRleCA9IGZEVERHcmFtbWFyLmdldEZpcnN0QXR0cmlidXRlRGVjbEluZGV4KGVsZW1lbnRJbmRleCk7Ci0KLSAgICAgICAgd2hpbGUgKGF0dGxpc3RJbmRleCAhPSAtMSkgewotCi0gICAgICAgICAgICBmRFRER3JhbW1hci5nZXRBdHRyaWJ1dGVEZWNsKGF0dGxpc3RJbmRleCwgZlRlbXBBdHREZWNsKTsKLQotICAgICAgICAgICAgaWYgKERFQlVHX0FUVFJJQlVURVMpIHsKLSAgICAgICAgICAgICAgICBpZiAoZlRlbXBBdHREZWNsICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgWE1MRWxlbWVudERlY2wgZWxlbWVudERlY2wgPSBuZXcgWE1MRWxlbWVudERlY2woKTsKLSAgICAgICAgICAgICAgICAgICAgZkRUREdyYW1tYXIuZ2V0RWxlbWVudERlY2woZWxlbWVudEluZGV4LCBlbGVtZW50RGVjbCk7Ci0gICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiZWxlbWVudDogIisoZWxlbWVudERlY2wubmFtZS5sb2NhbHBhcnQpKTsKLSAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJhdHRsaXN0SW5kZXggIiArIGF0dGxpc3RJbmRleCArICJcbiIrCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYXR0TmFtZSA6ICciKyhmVGVtcEF0dERlY2wubmFtZS5sb2NhbHBhcnQpICsgIidcbiIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgImF0dFR5cGUgOiAiK2ZUZW1wQXR0RGVjbC5zaW1wbGVUeXBlLnR5cGUgKyAiXG4iCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICJhdHREZWZhdWx0VHlwZSA6ICIrZlRlbXBBdHREZWNsLnNpbXBsZVR5cGUuZGVmYXVsdFR5cGUgKyAiXG4iCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICJhdHREZWZhdWx0VmFsdWUgOiAnIitmVGVtcEF0dERlY2wuc2ltcGxlVHlwZS5kZWZhdWx0VmFsdWUgKyAiJ1xuIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBhdHRyaWJ1dGVzLmdldExlbmd0aCgpICsiXG4iCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgU3RyaW5nIGF0dFByZWZpeCA9IGZUZW1wQXR0RGVjbC5uYW1lLnByZWZpeDsKLSAgICAgICAgICAgIFN0cmluZyBhdHRMb2NhbHBhcnQgPSBmVGVtcEF0dERlY2wubmFtZS5sb2NhbHBhcnQ7Ci0gICAgICAgICAgICBTdHJpbmcgYXR0UmF3TmFtZSA9IGZUZW1wQXR0RGVjbC5uYW1lLnJhd25hbWU7Ci0gICAgICAgICAgICBTdHJpbmcgYXR0VHlwZSA9IGdldEF0dHJpYnV0ZVR5cGVOYW1lKGZUZW1wQXR0RGVjbCk7Ci0gICAgICAgICAgICBpbnQgYXR0RGVmYXVsdFR5cGUgPWZUZW1wQXR0RGVjbC5zaW1wbGVUeXBlLmRlZmF1bHRUeXBlOwotICAgICAgICAgICAgU3RyaW5nIGF0dFZhbHVlID0gbnVsbDsKLQotICAgICAgICAgICAgaWYgKGZUZW1wQXR0RGVjbC5zaW1wbGVUeXBlLmRlZmF1bHRWYWx1ZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgYXR0VmFsdWUgPSBmVGVtcEF0dERlY2wuc2ltcGxlVHlwZS5kZWZhdWx0VmFsdWU7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGJvb2xlYW4gc3BlY2lmaWVkID0gZmFsc2U7Ci0gICAgICAgICAgICBib29sZWFuIHJlcXVpcmVkID0gYXR0RGVmYXVsdFR5cGUgPT0gWE1MU2ltcGxlVHlwZS5ERUZBVUxUX1RZUEVfUkVRVUlSRUQ7Ci0gICAgICAgICAgICBib29sZWFuIGNkYXRhID0gYXR0VHlwZSA9PSBYTUxTeW1ib2xzLmZDREFUQVN5bWJvbDsKLQotICAgICAgICAgICAgaWYgKCFjZGF0YSB8fCByZXF1aXJlZCB8fCBhdHRWYWx1ZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgaW50IGF0dHJDb3VudCA9IGF0dHJpYnV0ZXMuZ2V0TGVuZ3RoKCk7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhdHRyQ291bnQ7IGkrKykgewotICAgICAgICAgICAgICAgICAgICBpZiAoYXR0cmlidXRlcy5nZXRRTmFtZShpKSA9PSBhdHRSYXdOYW1lKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzcGVjaWZpZWQgPSB0cnVlOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmICghc3BlY2lmaWVkKSB7Ci0gICAgICAgICAgICAgICAgaWYgKHJlcXVpcmVkKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChmUGVyZm9ybVZhbGlkYXRpb24pIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIE9iamVjdFtdIGFyZ3MgPSB7ZWxlbWVudE5hbWUubG9jYWxwYXJ0LCBhdHRSYXdOYW1lfTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNU0dfUkVRVUlSRURfQVRUUklCVVRFX05PVF9TUEVDSUZJRUQiLCBhcmdzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9FUlJPUik7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSBpZiAoYXR0VmFsdWUgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBpZiAoZlBlcmZvcm1WYWxpZGF0aW9uICYmIGZHcmFtbWFyQnVja2V0LmdldFN0YW5kYWxvbmUoKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZEVERHcmFtbWFyLmdldEF0dHJpYnV0ZURlY2xJc0V4dGVybmFsKGF0dGxpc3RJbmRleCkpIHsKLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9iamVjdFtdIGFyZ3MgPSB7IGVsZW1lbnROYW1lLmxvY2FscGFydCwgYXR0UmF3TmFtZX07Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNU0dfREVGQVVMVEVEX0FUVFJJQlVURV9OT1RfU1BFQ0lGSUVEIiwgYXJncywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxFcnJvclJlcG9ydGVyLlNFVkVSSVRZX0VSUk9SKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgIC8vIGFkZCBuYW1lc3BhY2UgaW5mb3JtYXRpb24KLSAgICAgICAgICAgICAgICAgICAgaWYgKGZOYW1lc3BhY2VzKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpbnQgaW5kZXggPSBhdHRSYXdOYW1lLmluZGV4T2YoJzonKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbmRleCAhPSAtMSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dFByZWZpeCA9IGF0dFJhd05hbWUuc3Vic3RyaW5nKDAsIGluZGV4KTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRQcmVmaXggPSBmU3ltYm9sVGFibGUuYWRkU3ltYm9sKGF0dFByZWZpeCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0TG9jYWxwYXJ0ID0gYXR0UmF3TmFtZS5zdWJzdHJpbmcoaW5kZXggKyAxKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRMb2NhbHBhcnQgPSBmU3ltYm9sVGFibGUuYWRkU3ltYm9sKGF0dExvY2FscGFydCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAvLyBhZGQgYXR0cmlidXRlCi0gICAgICAgICAgICAgICAgICAgIGZUZW1wUU5hbWUuc2V0VmFsdWVzKGF0dFByZWZpeCwgYXR0TG9jYWxwYXJ0LCBhdHRSYXdOYW1lLCBmVGVtcEF0dERlY2wubmFtZS51cmkpOwotICAgICAgICAgICAgICAgICAgICBpbnQgbmV3QXR0ciA9IGF0dHJpYnV0ZXMuYWRkQXR0cmlidXRlKGZUZW1wUU5hbWUsIGF0dFR5cGUsIGF0dFZhbHVlKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyBnZXQgbmV4dCBhdHQgZGVjbCBpbiB0aGUgR3JhbW1hciBmb3IgdGhpcyBlbGVtZW50Ci0gICAgICAgICAgICBhdHRsaXN0SW5kZXggPSBmRFRER3JhbW1hci5nZXROZXh0QXR0cmlidXRlRGVjbEluZGV4KGF0dGxpc3RJbmRleCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBub3cgaXRlcmF0ZSB0aHJvdWdoIHRoZSBleHBhbmRlZCBhdHRyaWJ1dGVzIGZvcgotICAgICAgICAvLyAxLiBpZiBldmVyeSBhdHRyaWJ1dGUgc2VlbiBpcyBkZWNsYXJlZCBpbiB0aGUgRFRECi0gICAgICAgIC8vIDIuIGNoZWNrIGlmIHRoZSBWQzogZGVmYXVsdF9maXhlZCBob2xkcwotICAgICAgICAvLyAzLiB2YWxpZGF0ZSBldmVyeSBhdHRyaWJ1dGUuCi0gICAgICAgIGludCBhdHRyQ291bnQgPSBhdHRyaWJ1dGVzLmdldExlbmd0aCgpOwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGF0dHJDb3VudDsgaSsrKSB7Ci0gICAgICAgICAgICBTdHJpbmcgYXR0clJhd05hbWUgPSBhdHRyaWJ1dGVzLmdldFFOYW1lKGkpOwotICAgICAgICAgICAgYm9vbGVhbiBkZWNsYXJlZCA9IGZhbHNlOwotICAgICAgICAgICAgaWYgKGZQZXJmb3JtVmFsaWRhdGlvbikgewotICAgICAgICAgICAgICAgIGlmIChmR3JhbW1hckJ1Y2tldC5nZXRTdGFuZGFsb25lKCkpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gY2hlY2sgVkM6IFN0YW5kYWxvbmUgRG9jdW1lbnQgRGVjbGFyYXRpb24sIGVudGl0aWVzCi0gICAgICAgICAgICAgICAgICAgIC8vIHJlZmVyZW5jZXMgYXBwZWFyIGluIHRoZSBkb2N1bWVudC4KLSAgICAgICAgICAgICAgICAgICAgLy8gUkVWSVNJVDogdGhpcyBjYW4gYmUgY29tYmluZWQgdG8gYSBzaW5nbGUgY2hlY2sgaW4KLSAgICAgICAgICAgICAgICAgICAgLy8gc3RhcnRFbnRpdHkgaWYgd2UgYWRkIG9uZSBtb3JlIGFyZ3VtZW50IGluCi0gICAgICAgICAgICAgICAgICAgIC8vIHN0YXJ0RW5pdHksIGluQXR0clZhbHVlCi0gICAgICAgICAgICAgICAgICAgIFN0cmluZyBub25Ob3JtYWxpemVkVmFsdWUgPSBhdHRyaWJ1dGVzLmdldE5vbk5vcm1hbGl6ZWRWYWx1ZShpKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKG5vbk5vcm1hbGl6ZWRWYWx1ZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgZW50aXR5TmFtZSA9IGdldEV4dGVybmFsRW50aXR5UmVmSW5BdHRyVmFsdWUobm9uTm9ybWFsaXplZFZhbHVlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlbnRpdHlOYW1lICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmRXJyb3JSZXBvcnRlci5yZXBvcnRFcnJvcihYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1TR19SRUZFUkVOQ0VfVE9fRVhURVJOQUxMWV9ERUNMQVJFRF9FTlRJVFlfV0hFTl9TVEFOREFMT05FIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117ZW50aXR5TmFtZX0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9FUlJPUik7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpbnQgYXR0RGVmSW5kZXggPSAtMTsKLSAgICAgICAgICAgIGludCBwb3NpdGlvbiA9Ci0gICAgICAgICAgICBmRFRER3JhbW1hci5nZXRGaXJzdEF0dHJpYnV0ZURlY2xJbmRleChlbGVtZW50SW5kZXgpOwotICAgICAgICAgICAgd2hpbGUgKHBvc2l0aW9uICE9IC0xKSB7Ci0gICAgICAgICAgICAgICAgZkRUREdyYW1tYXIuZ2V0QXR0cmlidXRlRGVjbChwb3NpdGlvbiwgZlRlbXBBdHREZWNsKTsKLSAgICAgICAgICAgICAgICBpZiAoZlRlbXBBdHREZWNsLm5hbWUucmF3bmFtZSA9PSBhdHRyUmF3TmFtZSkgewotICAgICAgICAgICAgICAgICAgICAvLyBmb3VuZCB0aGUgbWF0Y2ggYXR0IGRlY2wsCi0gICAgICAgICAgICAgICAgICAgIGF0dERlZkluZGV4ID0gcG9zaXRpb247Ci0gICAgICAgICAgICAgICAgICAgIGRlY2xhcmVkID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHBvc2l0aW9uID0gZkRUREdyYW1tYXIuZ2V0TmV4dEF0dHJpYnV0ZURlY2xJbmRleChwb3NpdGlvbik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoIWRlY2xhcmVkKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGZQZXJmb3JtVmFsaWRhdGlvbikgewotICAgICAgICAgICAgICAgICAgICAvLyBSRVZJU0lUIC0gY2FjaGUgdGhlIGVsZW0vYXR0ciB0dXBsZSBzbyB0aGF0IHdlIG9ubHkKLSAgICAgICAgICAgICAgICAgICAgLy8gZ2l2ZSB0aGlzIGVycm9yIG9uY2UgZm9yIGVhY2ggdW5pcXVlIG9jY3VycmVuY2UKLSAgICAgICAgICAgICAgICAgICAgT2JqZWN0W10gYXJncyA9IHsgZWxlbWVudE5hbWUucmF3bmFtZSwgYXR0clJhd05hbWV9OwotCi0gICAgICAgICAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1TR19BVFRSSUJVVEVfTk9UX0RFQ0xBUkVEIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJncyxYTUxFcnJvclJlcG9ydGVyLlNFVkVSSVRZX0VSUk9SKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyBhdHRyaWJ1dGUgaXMgZGVjbGFyZWQKLQotICAgICAgICAgICAgLy8gZlRlbXBBdHREZWNsIHNob3VsZCBoYXZlIHRoZSByaWdodCB2YWx1ZSBzZXQgbm93LCBzbwotICAgICAgICAgICAgLy8gdGhlIGZvbGxvd2luZyBpcyBub3QgbmVlZGVkCi0gICAgICAgICAgICAvLyBmR3JhbW1hci5nZXRBdHRyaWJ1dGVEZWNsKGF0dERlZkluZGV4LGZUZW1wQXR0RGVjbCk7Ci0KLSAgICAgICAgICAgIFN0cmluZyB0eXBlID0gZ2V0QXR0cmlidXRlVHlwZU5hbWUoZlRlbXBBdHREZWNsKTsKLSAgICAgICAgICAgIGF0dHJpYnV0ZXMuc2V0VHlwZShpLCB0eXBlKTsKLSAgICAgICAgICAgIGF0dHJpYnV0ZXMuZ2V0QXVnbWVudGF0aW9ucyhpKS5wdXRJdGVtKENvbnN0YW50cy5BVFRSSUJVVEVfREVDTEFSRUQsIEJvb2xlYW4uVFJVRSk7Ci0KLSAgICAgICAgICAgIGJvb2xlYW4gY2hhbmdlZEJ5Tm9ybWFsaXphdGlvbiA9IGZhbHNlOwotICAgICAgICAgICAgU3RyaW5nIG9sZFZhbHVlID0gYXR0cmlidXRlcy5nZXRWYWx1ZShpKTsKLSAgICAgICAgICAgIFN0cmluZyBhdHRyVmFsdWUgPSBvbGRWYWx1ZTsKLSAgICAgICAgICAgIGlmIChhdHRyaWJ1dGVzLmlzU3BlY2lmaWVkKGkpICYmIHR5cGUgIT0gWE1MU3ltYm9scy5mQ0RBVEFTeW1ib2wpIHsKLSAgICAgICAgICAgICAgICBjaGFuZ2VkQnlOb3JtYWxpemF0aW9uID0gbm9ybWFsaXplQXR0clZhbHVlKGF0dHJpYnV0ZXMsIGkpOwotICAgICAgICAgICAgICAgIGF0dHJWYWx1ZSA9IGF0dHJpYnV0ZXMuZ2V0VmFsdWUoaSk7Ci0gICAgICAgICAgICAgICAgaWYgKGZQZXJmb3JtVmFsaWRhdGlvbiAmJiBmR3JhbW1hckJ1Y2tldC5nZXRTdGFuZGFsb25lKCkKLSAgICAgICAgICAgICAgICAgICAgJiYgY2hhbmdlZEJ5Tm9ybWFsaXphdGlvbgotICAgICAgICAgICAgICAgICAgICAmJiBmRFRER3JhbW1hci5nZXRBdHRyaWJ1dGVEZWNsSXNFeHRlcm5hbChwb3NpdGlvbikKLSAgICAgICAgICAgICAgICAgICApIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gY2hlY2sgVkM6IFN0YW5kYWxvbmUgRG9jdW1lbnQgRGVjbGFyYXRpb24KLSAgICAgICAgICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTVNHX0FUVFZBTFVFX0NIQU5HRURfRFVSSU5HX05PUk1BTElaQVRJT05fV0hFTl9TVEFOREFMT05FIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde2F0dHJSYXdOYW1lLCBvbGRWYWx1ZSwgYXR0clZhbHVlfSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9FUlJPUik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKCFmUGVyZm9ybVZhbGlkYXRpb24pIHsKLSAgICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChmVGVtcEF0dERlY2wuc2ltcGxlVHlwZS5kZWZhdWx0VHlwZSA9PQotICAgICAgICAgICAgICAgIFhNTFNpbXBsZVR5cGUuREVGQVVMVF9UWVBFX0ZJWEVEKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIGRlZmF1bHRWYWx1ZSA9IGZUZW1wQXR0RGVjbC5zaW1wbGVUeXBlLmRlZmF1bHRWYWx1ZTsKLQotICAgICAgICAgICAgICAgIGlmICghYXR0clZhbHVlLmVxdWFscyhkZWZhdWx0VmFsdWUpKSB7Ci0gICAgICAgICAgICAgICAgICAgIE9iamVjdFtdIGFyZ3MgPSB7ZWxlbWVudE5hbWUubG9jYWxwYXJ0LAotICAgICAgICAgICAgICAgICAgICAgICAgYXR0clJhd05hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICBhdHRyVmFsdWUsCi0gICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0VmFsdWV9OwotICAgICAgICAgICAgICAgICAgICBmRXJyb3JSZXBvcnRlci5yZXBvcnRFcnJvcihYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNU0dfRklYRURfQVRUVkFMVUVfSU5WQUxJRCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3MsIFhNTEVycm9yUmVwb3J0ZXIuU0VWRVJJVFlfRVJST1IpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKGZUZW1wQXR0RGVjbC5zaW1wbGVUeXBlLnR5cGUgPT0gWE1MU2ltcGxlVHlwZS5UWVBFX0VOVElUWSB8fAotICAgICAgICAgICAgICAgIGZUZW1wQXR0RGVjbC5zaW1wbGVUeXBlLnR5cGUgPT0gWE1MU2ltcGxlVHlwZS5UWVBFX0VOVU1FUkFUSU9OIHx8Ci0gICAgICAgICAgICAgICAgZlRlbXBBdHREZWNsLnNpbXBsZVR5cGUudHlwZSA9PSBYTUxTaW1wbGVUeXBlLlRZUEVfSUQgfHwKLSAgICAgICAgICAgICAgICBmVGVtcEF0dERlY2wuc2ltcGxlVHlwZS50eXBlID09IFhNTFNpbXBsZVR5cGUuVFlQRV9JRFJFRiB8fAotICAgICAgICAgICAgICAgIGZUZW1wQXR0RGVjbC5zaW1wbGVUeXBlLnR5cGUgPT0gWE1MU2ltcGxlVHlwZS5UWVBFX05NVE9LRU4gfHwKLSAgICAgICAgICAgICAgICBmVGVtcEF0dERlY2wuc2ltcGxlVHlwZS50eXBlID09IFhNTFNpbXBsZVR5cGUuVFlQRV9OT1RBVElPTgotICAgICAgICAgICAgICAgKSB7Ci0gICAgICAgICAgICAgICAgdmFsaWRhdGVEVERhdHRyaWJ1dGUoZWxlbWVudE5hbWUsIGF0dHJWYWx1ZSwgZlRlbXBBdHREZWNsKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSAvLyBmb3IgYWxsIGF0dHJpYnV0ZXMKLQotICAgIH0gLy8gYWRkRFRERGVmYXVsdEF0dHJzQW5kVmFsaWRhdGUoaW50LFhNTEF0dHJMaXN0KQotCi0gICAgLyoqIENoZWNrcyBlbnRpdGllcyBpbiBhdHRyaWJ1dGUgdmFsdWVzIGZvciBzdGFuZGFsb25lIFZDLiAqLwotICAgIHByb3RlY3RlZCBTdHJpbmcgZ2V0RXh0ZXJuYWxFbnRpdHlSZWZJbkF0dHJWYWx1ZShTdHJpbmcgbm9uTm9ybWFsaXplZFZhbHVlKSB7Ci0gICAgICAgIGludCB2YWxMZW5ndGggPSBub25Ob3JtYWxpemVkVmFsdWUubGVuZ3RoKCk7Ci0gICAgICAgIGludCBhbXBJbmRleCA9IG5vbk5vcm1hbGl6ZWRWYWx1ZS5pbmRleE9mKCcmJyk7Ci0gICAgICAgIHdoaWxlIChhbXBJbmRleCAhPSAtMSkgewotICAgICAgICAgICAgaWYgKGFtcEluZGV4ICsgMSA8IHZhbExlbmd0aCAmJgotICAgICAgICAgICAgICAgIG5vbk5vcm1hbGl6ZWRWYWx1ZS5jaGFyQXQoYW1wSW5kZXgrMSkgIT0gJyMnKSB7Ci0gICAgICAgICAgICAgICAgaW50IHNlbWljb2xvbkluZGV4ID0gbm9uTm9ybWFsaXplZFZhbHVlLmluZGV4T2YoJzsnLCBhbXBJbmRleCsxKTsKLSAgICAgICAgICAgICAgICBTdHJpbmcgZW50aXR5TmFtZSA9IG5vbk5vcm1hbGl6ZWRWYWx1ZS5zdWJzdHJpbmcoYW1wSW5kZXgrMSwgc2VtaWNvbG9uSW5kZXgpOwotICAgICAgICAgICAgICAgIGVudGl0eU5hbWUgPSBmU3ltYm9sVGFibGUuYWRkU3ltYm9sKGVudGl0eU5hbWUpOwotICAgICAgICAgICAgICAgIGludCBlbnRJbmRleCA9IGZEVERHcmFtbWFyLmdldEVudGl0eURlY2xJbmRleChlbnRpdHlOYW1lKTsKLSAgICAgICAgICAgICAgICBpZiAoZW50SW5kZXggPiAtMSkgewotICAgICAgICAgICAgICAgICAgICBmRFRER3JhbW1hci5nZXRFbnRpdHlEZWNsKGVudEluZGV4LCBmRW50aXR5RGVjbCk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChmRW50aXR5RGVjbC5pbkV4dGVybmFsIHx8Ci0gICAgICAgICAgICAgICAgICAgICAgICAoZW50aXR5TmFtZSA9IGdldEV4dGVybmFsRW50aXR5UmVmSW5BdHRyVmFsdWUoZkVudGl0eURlY2wudmFsdWUpKSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZW50aXR5TmFtZTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGFtcEluZGV4ID0gbm9uTm9ybWFsaXplZFZhbHVlLmluZGV4T2YoJyYnLCBhbXBJbmRleCsxKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9IC8vIGlzRXh0ZXJuYWxFbnRpdHlSZWZJbkF0dHJWYWx1ZShTdHJpbmcpOlN0cmluZwotCi0gICAgLyoqCi0gICAgICogVmFsaWRhdGUgYXR0cmlidXRlcyBpbiBEVEQgZmFzaGlvbi4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCB2YWxpZGF0ZURURGF0dHJpYnV0ZShRTmFtZSBlbGVtZW50LCBTdHJpbmcgYXR0VmFsdWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTEF0dHJpYnV0ZURlY2wgYXR0cmlidXRlRGVjbCkKLSAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLQotICAgICAgICBzd2l0Y2ggKGF0dHJpYnV0ZURlY2wuc2ltcGxlVHlwZS50eXBlKSB7Ci0gICAgICAgIGNhc2UgWE1MU2ltcGxlVHlwZS5UWVBFX0VOVElUWTogewotICAgICAgICAgICAgICAgIC8vIE5PVEU6IFNhdmUgdGhpcyBpbmZvcm1hdGlvbiBiZWNhdXNlIGludmFsaWRTdGFuZGFsb25lQXR0RGVmCi0gICAgICAgICAgICAgICAgYm9vbGVhbiBpc0FsaXN0QXR0cmlidXRlID0gYXR0cmlidXRlRGVjbC5zaW1wbGVUeXBlLmxpc3Q7Ci0KLSAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICBpZiAoaXNBbGlzdEF0dHJpYnV0ZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgZlZhbEVOVElUSUVTLnZhbGlkYXRlKGF0dFZhbHVlLCBmVmFsaWRhdGlvblN0YXRlKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZWYWxFTlRJVFkudmFsaWRhdGUoYXR0VmFsdWUsIGZWYWxpZGF0aW9uU3RhdGUpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGNhdGNoIChJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbiBleCkgewotICAgICAgICAgICAgICAgICAgICBmRXJyb3JSZXBvcnRlci5yZXBvcnRFcnJvcihYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4LmdldEtleSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleC5nZXRBcmdzKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTEVycm9yUmVwb3J0ZXIuU0VWRVJJVFlfRVJST1IgKTsKLQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLQotICAgICAgICBjYXNlIFhNTFNpbXBsZVR5cGUuVFlQRV9OT1RBVElPTjoKLSAgICAgICAgY2FzZSBYTUxTaW1wbGVUeXBlLlRZUEVfRU5VTUVSQVRJT046IHsKLSAgICAgICAgICAgICAgICBib29sZWFuIGZvdW5kID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIFtdIGVudW1WYWxzID0gYXR0cmlidXRlRGVjbC5zaW1wbGVUeXBlLmVudW1lcmF0aW9uOwotICAgICAgICAgICAgICAgIGlmIChlbnVtVmFscyA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZvdW5kID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBlbnVtVmFscy5sZW5ndGg7IGkrKykgewotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGF0dFZhbHVlID09IGVudW1WYWxzW2ldIHx8IGF0dFZhbHVlLmVxdWFscyhlbnVtVmFsc1tpXSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3VuZCA9IHRydWU7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIGlmICghZm91bmQpIHsKLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nQnVmZmVyIGVudW1WYWx1ZVN0cmluZyA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGVudW1WYWxzICE9IG51bGwpCi0gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGVudW1WYWxzLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZW51bVZhbHVlU3RyaW5nLmFwcGVuZChlbnVtVmFsc1tpXSsiICIpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBmRXJyb3JSZXBvcnRlci5yZXBvcnRFcnJvcihYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNU0dfQVRUUklCVVRFX1ZBTFVFX05PVF9JTl9MSVNUIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde2F0dHJpYnV0ZURlY2wubmFtZS5yYXduYW1lLCBhdHRWYWx1ZSwgZW51bVZhbHVlU3RyaW5nfSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9FUlJPUik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotCi0gICAgICAgIGNhc2UgWE1MU2ltcGxlVHlwZS5UWVBFX0lEOiB7Ci0gICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgZlZhbElELnZhbGlkYXRlKGF0dFZhbHVlLCBmVmFsaWRhdGlvblN0YXRlKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgY2F0Y2ggKEludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uIGV4KSB7Ci0gICAgICAgICAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXguZ2V0S2V5KCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4LmdldEFyZ3MoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9FUlJPUiApOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLQotICAgICAgICBjYXNlIFhNTFNpbXBsZVR5cGUuVFlQRV9JRFJFRjogewotICAgICAgICAgICAgICAgIGJvb2xlYW4gaXNBbGlzdEF0dHJpYnV0ZSA9IGF0dHJpYnV0ZURlY2wuc2ltcGxlVHlwZS5saXN0Oy8vQ2F2ZWF0IC0gU2F2ZSB0aGlzIGluZm9ybWF0aW9uIGJlY2F1c2UgaW52YWxpZFN0YW5kYWxvbmVBdHREZWYKLQotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChpc0FsaXN0QXR0cmlidXRlKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmVmFsSURSZWZzLnZhbGlkYXRlKGF0dFZhbHVlLCBmVmFsaWRhdGlvblN0YXRlKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZWYWxJRFJlZi52YWxpZGF0ZShhdHRWYWx1ZSwgZlZhbGlkYXRpb25TdGF0ZSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgY2F0Y2ggKEludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uIGV4KSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChpc0FsaXN0QXR0cmlidXRlKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmRXJyb3JSZXBvcnRlci5yZXBvcnRFcnJvcihYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiSURSRUZTSW52YWxpZCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117YXR0VmFsdWV9LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9FUlJPUiApOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXguZ2V0S2V5KCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleC5nZXRBcmdzKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxFcnJvclJlcG9ydGVyLlNFVkVSSVRZX0VSUk9SICk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLQotICAgICAgICBjYXNlIFhNTFNpbXBsZVR5cGUuVFlQRV9OTVRPS0VOOiB7Ci0gICAgICAgICAgICAgICAgYm9vbGVhbiBpc0FsaXN0QXR0cmlidXRlID0gYXR0cmlidXRlRGVjbC5zaW1wbGVUeXBlLmxpc3Q7Ly9DYXZlYXQgLSBTYXZlIHRoaXMgaW5mb3JtYXRpb24gYmVjYXVzZSBpbnZhbGlkU3RhbmRhbG9uZUF0dERlZgotICAgICAgICAgICAgICAgIC8vY2hhbmdlcyBmVGVtcEF0dERlZgotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChpc0FsaXN0QXR0cmlidXRlKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmVmFsTk1UT0tFTlMudmFsaWRhdGUoYXR0VmFsdWUsIGZWYWxpZGF0aW9uU3RhdGUpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgZlZhbE5NVE9LRU4udmFsaWRhdGUoYXR0VmFsdWUsIGZWYWxpZGF0aW9uU3RhdGUpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGNhdGNoIChJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbiBleCkgewotICAgICAgICAgICAgICAgICAgICBpZiAoaXNBbGlzdEF0dHJpYnV0ZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5NVE9LRU5TSW52YWxpZCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBhdHRWYWx1ZX0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxFcnJvclJlcG9ydGVyLlNFVkVSSVRZX0VSUk9SKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOTVRPS0VOSW52YWxpZCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBhdHRWYWx1ZX0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxFcnJvclJlcG9ydGVyLlNFVkVSSVRZX0VSUk9SKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLQotICAgICAgICB9IC8vIHN3aXRjaAotCi0gICAgfSAvLyB2YWxpZGF0ZURURGF0dHJpYnV0ZShRTmFtZSxTdHJpbmcsWE1MQXR0cmlidXRlRGVjbCkKLQotCi0gICAgLyoqIFJldHVybnMgdHJ1ZSBpZiBpbnZhbGlkIHN0YW5kYWxvbmUgYXR0cmlidXRlIGRlZmluaXRpb24uICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gaW52YWxpZFN0YW5kYWxvbmVBdHREZWYoUU5hbWUgZWxlbWVudCwgUU5hbWUgYXR0cmlidXRlKSB7Ci0gICAgICAgIC8vIFJFVklTSVQ6IFRoaXMgb2J2aW91c2x5IG5lZWRzIHRvIGJlIGZpeGVkISAtQWMKLSAgICAgICAgYm9vbGVhbiBzdGF0ZSA9IHRydWU7Ci0gICAgICAgIC8qCi0gICAgICAgaWYgKGZTdGFuZGFsb25lUmVhZGVyID09IC0xKSB7Ci0gICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgIH0KLSAgICAgICAvLyB3ZSBhcmUgbm9ybWFsaXppbmcgYSBkZWZhdWx0IGF0dCB2YWx1ZS4uLiAgdGhpcyBvaz8KLSAgICAgICBpZiAoZWxlbWVudC5yYXduYW1lID09IC0xKSB7Ci0gICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgIH0KLSAgICAgICByZXR1cm4gZ2V0QXR0RGVmSXNFeHRlcm5hbChlbGVtZW50LCBhdHRyaWJ1dGUpOwotICAgICAgICovCi0gICAgICAgIHJldHVybiBzdGF0ZTsKLSAgICB9Ci0KLQotICAgIC8vCi0gICAgLy8gUHJpdmF0ZSBtZXRob2RzCi0gICAgLy8KLQotCi0gICAgLyoqCi0gICAgICogTm9ybWFsaXplIHRoZSBhdHRyaWJ1dGUgdmFsdWUgb2YgYSBub24gQ0RBVEEgYXR0cmlidXRlcyBjb2xsYXBzaW5nCi0gICAgICogc2VxdWVuY2VzIG9mIHNwYWNlIGNoYXJhY3RlcnMgKHgyMCkKLSAgICAgKgotICAgICAqIEBwYXJhbSBhdHRyaWJ1dGVzIFRoZSBsaXN0IG9mIGF0dHJpYnV0ZXMKLSAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBhdHRyaWJ1dGUgdG8gbm9ybWFsaXplCi0gICAgICovCi0gICAgcHJpdmF0ZSBib29sZWFuIG5vcm1hbGl6ZUF0dHJWYWx1ZShYTUxBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMsIGludCBpbmRleCkgewotICAgICAgICAvLyB2YXJzCi0gICAgICAgIGJvb2xlYW4gbGVhZGluZ1NwYWNlID0gdHJ1ZTsKLSAgICAgICAgYm9vbGVhbiBzcGFjZVN0YXJ0ID0gZmFsc2U7Ci0gICAgICAgIGJvb2xlYW4gcmVhZGluZ05vblNwYWNlID0gZmFsc2U7Ci0gICAgICAgIGludCBjb3VudCA9IDA7Ci0gICAgICAgIGludCBlYXRlbiA9IDA7Ci0gICAgICAgIFN0cmluZyBhdHRyVmFsdWUgPSBhdHRyaWJ1dGVzLmdldFZhbHVlKGluZGV4KTsKLSAgICAgICAgY2hhcltdIGF0dFZhbHVlID0gbmV3IGNoYXJbYXR0clZhbHVlLmxlbmd0aCgpXTsKLQotICAgICAgICBmQnVmZmVyLnNldExlbmd0aCgwKTsKLSAgICAgICAgYXR0clZhbHVlLmdldENoYXJzKDAsIGF0dHJWYWx1ZS5sZW5ndGgoKSwgYXR0VmFsdWUsIDApOwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGF0dFZhbHVlLmxlbmd0aDsgaSsrKSB7Ci0KLSAgICAgICAgICAgIGlmIChhdHRWYWx1ZVtpXSA9PSAnICcpIHsKLQotICAgICAgICAgICAgICAgIC8vIG5vdyB0aGUgdHJpY2t5IHBhcnQKLSAgICAgICAgICAgICAgICBpZiAocmVhZGluZ05vblNwYWNlKSB7Ci0gICAgICAgICAgICAgICAgICAgIHNwYWNlU3RhcnQgPSB0cnVlOwotICAgICAgICAgICAgICAgICAgICByZWFkaW5nTm9uU3BhY2UgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBpZiAoc3BhY2VTdGFydCAmJiAhbGVhZGluZ1NwYWNlKSB7Ci0gICAgICAgICAgICAgICAgICAgIHNwYWNlU3RhcnQgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICAgICAgZkJ1ZmZlci5hcHBlbmQoYXR0VmFsdWVbaV0pOwotICAgICAgICAgICAgICAgICAgICBjb3VudCsrOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGxlYWRpbmdTcGFjZSB8fCAhc3BhY2VTdGFydCkgewotICAgICAgICAgICAgICAgICAgICAgICAgZWF0ZW4gKys7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvKioqIEJVRyAjMzUxMiAqKioKLSAgICAgICAgICAgICAgICAgICAgICAgIGludCBlbnRpdHlDb3VudCA9IGF0dHJpYnV0ZXMuZ2V0RW50aXR5Q291bnQoaW5kZXgpOwotICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaiA9IDA7ICBqIDwgZW50aXR5Q291bnQ7IGorKykgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBvZmZzZXQgPSBhdHRyaWJ1dGVzLmdldEVudGl0eU9mZnNldChpbmRleCwgaik7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGF0dHJpYnV0ZXMuZ2V0RW50aXR5TGVuZ3RoKGluZGV4LCBqKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAob2Zmc2V0IDw9IGktZWF0ZW4rMSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAob2Zmc2V0K2xlbmd0aCA+PSBpLWVhdGVuKzEpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsZW5ndGggPiAwKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlbmd0aC0tOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAob2Zmc2V0ID4gMCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldC0tOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzLnNldEVudGl0eU9mZnNldChpbmRleCwgaiwgb2Zmc2V0KTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzLnNldEVudGl0eUxlbmd0aChpbmRleCwgaiwgbGVuZ3RoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIC8qKiovCi0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIHJlYWRpbmdOb25TcGFjZSA9IHRydWU7Ci0gICAgICAgICAgICAgICAgc3BhY2VTdGFydCA9IGZhbHNlOwotICAgICAgICAgICAgICAgIGxlYWRpbmdTcGFjZSA9IGZhbHNlOwotICAgICAgICAgICAgICAgIGZCdWZmZXIuYXBwZW5kKGF0dFZhbHVlW2ldKTsKLSAgICAgICAgICAgICAgICBjb3VudCsrOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gY2hlY2sgaWYgdGhlIGxhc3QgYXBwZW5kZWQgY2hhcmFjdGVyIGlzIGEgc3BhY2UuCi0gICAgICAgIGlmIChjb3VudCA+IDAgJiYgZkJ1ZmZlci5jaGFyQXQoY291bnQtMSkgPT0gJyAnKSB7Ci0gICAgICAgICAgICBmQnVmZmVyLnNldExlbmd0aChjb3VudC0xKTsKLSAgICAgICAgICAgIC8qKiogQlVHICMzNTEyICoqKgotICAgICAgICAgICAgaW50IGVudGl0eUNvdW50ID0gYXR0cmlidXRlcy5nZXRFbnRpdHlDb3VudChpbmRleCk7Ci0gICAgICAgICAgICBmb3IgKGludCBqPTA7ICBqIDwgZW50aXR5Q291bnQ7IGorKykgewotICAgICAgICAgICAgICAgIGludCBvZmZzZXQgPSBhdHRyaWJ1dGVzLmdldEVudGl0eU9mZnNldChpbmRleCwgaik7Ci0gICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGF0dHJpYnV0ZXMuZ2V0RW50aXR5TGVuZ3RoKGluZGV4LCBqKTsKLSAgICAgICAgICAgICAgICBpZiAob2Zmc2V0IDwgY291bnQtMSkgewotICAgICAgICAgICAgICAgICAgICBpZiAob2Zmc2V0K2xlbmd0aCA9PSBjb3VudCkgewotICAgICAgICAgICAgICAgICAgICAgICAgbGVuZ3RoLS07Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIG9mZnNldC0tOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzLnNldEVudGl0eU9mZnNldChpbmRleCwgaiwgb2Zmc2V0KTsKLSAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzLnNldEVudGl0eUxlbmd0aChpbmRleCwgaiwgbGVuZ3RoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8qKiovCi0gICAgICAgIH0KLSAgICAgICAgU3RyaW5nIG5ld1ZhbHVlID0gZkJ1ZmZlci50b1N0cmluZygpOwotICAgICAgICBhdHRyaWJ1dGVzLnNldFZhbHVlKGluZGV4LCBuZXdWYWx1ZSk7Ci0gICAgICAgIHJldHVybiAhIGF0dHJWYWx1ZS5lcXVhbHMobmV3VmFsdWUpOwotICAgIH0KLQotICAgIC8qKiBSb290IGVsZW1lbnQgc3BlY2lmaWVkLiAqLwotICAgIHByaXZhdGUgZmluYWwgdm9pZCByb290RWxlbWVudFNwZWNpZmllZChRTmFtZSByb290RWxlbWVudCkgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChmUGVyZm9ybVZhbGlkYXRpb24pIHsKLSAgICAgICAgICAgIFN0cmluZyByb290MSA9IGZSb290RWxlbWVudC5yYXduYW1lOwotICAgICAgICAgICAgU3RyaW5nIHJvb3QyID0gcm9vdEVsZW1lbnQucmF3bmFtZTsKLSAgICAgICAgICAgIGlmIChyb290MSA9PSBudWxsIHx8ICFyb290MS5lcXVhbHMocm9vdDIpKSB7Ci0gICAgICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IoIFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlJvb3RFbGVtZW50VHlwZU11c3RNYXRjaERvY3R5cGVkZWNsIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde3Jvb3QxLCByb290Mn0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTEVycm9yUmVwb3J0ZXIuU0VWRVJJVFlfRVJST1IpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfSAvLyByb290RWxlbWVudFNwZWNpZmllZChRTmFtZSkKLQotICAgIC8qKgotICAgICAqIENoZWNrIHRoYXQgdGhlIGNvbnRlbnQgb2YgYW4gZWxlbWVudCBpcyB2YWxpZC4KLSAgICAgKiA8cD4KLSAgICAgKiBUaGlzIGlzIHRoZSBtZXRob2Qgb2YgcHJpbWFyeSBjb25jZXJuIHRvIHRoZSB2YWxpZGF0b3IuIFRoaXMgbWV0aG9kIGlzIGNhbGxlZAotICAgICAqIHVwb24gdGhlIHNjYW5uZXIgcmVhY2hpbmcgdGhlIGVuZCB0YWcgb2YgYW4gZWxlbWVudC4gQXQgdGhhdCB0aW1lLCB0aGUKLSAgICAgKiBlbGVtZW50J3MgY2hpbGRyZW4gbXVzdCBiZSBzdHJ1Y3R1cmFsbHkgdmFsaWRhdGVkLCBzbyBpdCBjYWxscyB0aGlzIG1ldGhvZC4KLSAgICAgKiBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgYmVpbmcgY2hlY2tlZCAoaW4gdGhlIGRlY2wgcG9vbCksIGlzIHByb3ZpZGVkIGFzCi0gICAgICogd2VsbCBhcyBhbiBhcnJheSBvZiBlbGVtZW50IG5hbWUgaW5kZXhlcyBvZiB0aGUgY2hpbGRyZW4uIFRoZSB2YWxpZGF0b3IgbXVzdAotICAgICAqIGNvbmZpcm0gdGhhdCB0aGlzIGVsZW1lbnQgY2FuIGhhdmUgdGhlc2UgY2hpbGRyZW4gaW4gdGhpcyBvcmRlci4KLSAgICAgKiA8cD4KLSAgICAgKiBUaGlzIGNhbiBhbHNvIGJlIGNhbGxlZCB0byBkbyAnd2hhdCBpZicgdGVzdGluZyBvZiBjb250ZW50IG1vZGVscyBqdXN0IHRvIHNlZQotICAgICAqIGlmIHRoZXkgd291bGQgYmUgdmFsaWQuCi0gICAgICogPHA+Ci0gICAgICogTm90ZSB0aGF0IHRoZSBlbGVtZW50IGluZGV4IGlzIGFuIGluZGV4IGludG8gdGhlIGVsZW1lbnQgZGVjbCBwb29sLCB3aGVyZWFzCi0gICAgICogdGhlIGNoaWxkcmVuIGluZGV4ZXMgYXJlIG5hbWUgaW5kZXhlcywgaS5lLiBpbnRvIHRoZSBzdHJpbmcgcG9vbC4KLSAgICAgKiA8cD4KLSAgICAgKiBBIHZhbHVlIG9mIC0xIGluIHRoZSBjaGlsZHJlbiBhcnJheSBpbmRpY2F0ZXMgYSBQQ0RBVEEgbm9kZS4gQWxsIG90aGVyCi0gICAgICogaW5kZXhlcyB3aWxsIGJlIHBvc2l0aXZlIGFuZCByZXByZXNlbnQgY2hpbGQgZWxlbWVudHMuIFRoZSBjb3VudCBjYW4gYmUKLSAgICAgKiB6ZXJvLCBzaW5jZSBzb21lIGVsZW1lbnRzIGhhdmUgdGhlIEVNUFRZIGNvbnRlbnQgbW9kZWwgYW5kIHRoYXQgbXVzdCBiZQotICAgICAqIGNvbmZpcm1lZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlbGVtZW50SW5kZXggVGhlIGluZGV4IHdpdGhpbiB0aGUgPGNvZGU+RWxlbWVudERlY2xQb29sPC9jb2RlPiBvZiB0aGlzCi0gICAgICogICAgICAgICAgICAgICAgICAgICBlbGVtZW50LgotICAgICAqIEBwYXJhbSBjaGlsZENvdW50IFRoZSBudW1iZXIgb2YgZW50cmllcyBpbiB0aGUgPGNvZGU+Y2hpbGRyZW48L2NvZGU+IGFycmF5LgotICAgICAqIEBwYXJhbSBjaGlsZHJlbiBUaGUgY2hpbGRyZW4gb2YgdGhpcyBlbGVtZW50LgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgdmFsdWUgLTEgaWYgZnVsbHkgdmFsaWQsIGVsc2UgdGhlIDAgYmFzZWQgaW5kZXggb2YgdGhlIGNoaWxkCi0gICAgICogICAgICAgICB0aGF0IGZpcnN0IGZhaWxlZC4gSWYgdGhlIHZhbHVlIHJldHVybmVkIGlzIGVxdWFsIHRvIHRoZSBudW1iZXIKLSAgICAgKiAgICAgICAgIG9mIGNoaWxkcmVuLCB0aGVuIGFkZGl0aW9uYWwgY29udGVudCBpcyByZXF1aXJlZCB0byByZWFjaCBhIHZhbGlkCi0gICAgICogICAgICAgICBlbmRpbmcgc3RhdGUuCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIEV4Y2VwdGlvbiBUaHJvd24gb24gZXJyb3IuCi0gICAgICovCi0gICAgcHJpdmF0ZSBpbnQgY2hlY2tDb250ZW50KGludCBlbGVtZW50SW5kZXgsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIFFOYW1lW10gY2hpbGRyZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBjaGlsZE9mZnNldCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGNoaWxkQ291bnQpIHRocm93cyBYTklFeGNlcHRpb24gewotCi0gICAgICAgIGZEVERHcmFtbWFyLmdldEVsZW1lbnREZWNsKGVsZW1lbnRJbmRleCwgZlRlbXBFbGVtZW50RGVjbCk7Ci0KLSAgICAgICAgLy8gR2V0IHRoZSBlbGVtZW50IG5hbWUgaW5kZXggZnJvbSB0aGUgZWxlbWVudAotICAgICAgICBmaW5hbCBTdHJpbmcgZWxlbWVudFR5cGUgPSBmQ3VycmVudEVsZW1lbnQucmF3bmFtZTsKLQotICAgICAgICAvLyBHZXQgb3V0IHRoZSBjb250ZW50IHNwZWMgZm9yIHRoaXMgZWxlbWVudAotICAgICAgICBmaW5hbCBpbnQgY29udGVudFR5cGUgPSBmQ3VycmVudENvbnRlbnRTcGVjVHlwZTsKLQotCi0gICAgICAgIC8vCi0gICAgICAgIC8vICBEZWFsIHdpdGggdGhlIHBvc3NpYmxlIHR5cGVzIG9mIGNvbnRlbnQuIFdlIHRyeSB0byBvcHRpbWl6ZWQgaGVyZQotICAgICAgICAvLyAgYnkgZGVhbGluZyBzcGVjaWFsbHkgd2l0aCBjb250ZW50IG1vZGVscyB0aGF0IGRvbid0IHJlcXVpcmUgdGhlCi0gICAgICAgIC8vICBmdWxsIERGQSB0cmVhdG1lbnQuCi0gICAgICAgIC8vCi0gICAgICAgIGlmIChjb250ZW50VHlwZSA9PSBYTUxFbGVtZW50RGVjbC5UWVBFX0VNUFRZKSB7Ci0gICAgICAgICAgICAvLwotICAgICAgICAgICAgLy8gIElmIHRoZSBjaGlsZCBjb3VudCBpcyBncmVhdGVyIHRoYW4gemVybywgdGhlbiB0aGlzIGlzCi0gICAgICAgICAgICAvLyAgYW4gZXJyb3IgcmlnaHQgb2ZmIHRoZSBiYXQgYXQgaW5kZXggMC4KLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICBpZiAoY2hpbGRDb3VudCAhPSAwKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIDA7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoY29udGVudFR5cGUgPT0gWE1MRWxlbWVudERlY2wuVFlQRV9BTlkpIHsKLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAvLyAgVGhpcyBvbmUgaXMgb3BlbiBnYW1lIHNvIHdlIGRvbid0IHBhc3MgYW55IGp1ZGdlbWVudCBvbiBpdAotICAgICAgICAgICAgLy8gIGF0IGFsbC4gSXRzIGFzc3VtZWQgdG8gZmluZSBzaW5jZSBpdCBjYW4gaG9sZCBhbnl0aGluZy4KLSAgICAgICAgICAgIC8vCi0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoY29udGVudFR5cGUgPT0gWE1MRWxlbWVudERlY2wuVFlQRV9NSVhFRCB8fAotICAgICAgICAgICAgICAgICBjb250ZW50VHlwZSA9PSBYTUxFbGVtZW50RGVjbC5UWVBFX0NISUxEUkVOKSB7Ci0gICAgICAgICAgICAvLyBHZXQgdGhlIGNvbnRlbnQgbW9kZWwgZm9yIHRoaXMgZWxlbWVudCwgZmF1bHRpbmcgaXQgaW4gaWYgbmVlZGVkCi0gICAgICAgICAgICBDb250ZW50TW9kZWxWYWxpZGF0b3IgY21FbGVtID0gbnVsbDsKLSAgICAgICAgICAgIGNtRWxlbSA9IGZUZW1wRWxlbWVudERlY2wuY29udGVudE1vZGVsVmFsaWRhdG9yOwotICAgICAgICAgICAgaW50IHJlc3VsdCA9IGNtRWxlbS52YWxpZGF0ZShjaGlsZHJlbiwgY2hpbGRPZmZzZXQsIGNoaWxkQ291bnQpOwotICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChjb250ZW50VHlwZSA9PSAtMSkgewotICAgICAgICAgICAgLy9SRVZJU0lUCi0gICAgICAgICAgICAvKioqKgotICAgICAgICAgICAgcmVwb3J0UmVjb3ZlcmFibGVYTUxFcnJvcihYTUxNZXNzYWdlcy5NU0dfRUxFTUVOVF9OT1RfREVDTEFSRUQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTE1lc3NhZ2VzLlZDX0VMRU1FTlRfVkFMSUQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRUeXBlKTsKLSAgICAgICAgICAgIC8qKioqLwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKGNvbnRlbnRUeXBlID09IFhNTEVsZW1lbnREZWNsLlRZUEVfU0lNUExFKSB7Ci0KLSAgICAgICAgICAgIC8vUkVWSVNJVAotICAgICAgICAgICAgLy8gdGhpcyBzaG91bGQgbmV2ZXIgYmUgcmVhY2hlZCBpbiB0aGUgY2FzZSBvZiBEVEQgdmFsaWRhdGlvbi4KLQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgLy9SRVZJU0lUCi0gICAgICAgICAgICAvKioqKgotICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IoZkVycm9yUmVwb3J0ZXIuZ2V0TG9jYXRvcigpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW1wbGVtZW50YXRpb25NZXNzYWdlcy5YRVJDRVNfSU1QTEVNRU5UQVRJT05fRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW1wbGVtZW50YXRpb25NZXNzYWdlcy5WQUxfQ1NULAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxFcnJvclJlcG9ydGVyLkVSUk9SVFlQRV9GQVRBTF9FUlJPUik7Ci0gICAgICAgICAgICAvKioqKi8KLSAgICAgICAgfQotCi0gICAgICAgIC8vIFdlIHN1Y2NlZWRlZAotICAgICAgICByZXR1cm4gLTE7Ci0KLSAgICB9IC8vIGNoZWNrQ29udGVudChpbnQsaW50LFFOYW1lW10pOmludAotCi0gICAgLyoqIFJldHVybnMgdGhlIGNvbnRlbnQgc3BlYyB0eXBlIGZvciBhbiBlbGVtZW50IGluZGV4LiAqLwotICAgIHByaXZhdGUgaW50IGdldENvbnRlbnRTcGVjVHlwZShpbnQgZWxlbWVudEluZGV4KSB7Ci0KLSAgICAgICAgaW50IGNvbnRlbnRTcGVjVHlwZSA9IC0xOwotICAgICAgICBpZiAoZWxlbWVudEluZGV4ID4gLTEpIHsKLSAgICAgICAgICAgIGlmIChmRFRER3JhbW1hci5nZXRFbGVtZW50RGVjbChlbGVtZW50SW5kZXgsZlRlbXBFbGVtZW50RGVjbCkpIHsKLSAgICAgICAgICAgICAgICBjb250ZW50U3BlY1R5cGUgPSBmVGVtcEVsZW1lbnREZWNsLnR5cGU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGNvbnRlbnRTcGVjVHlwZTsKLSAgICB9Ci0KLSAgICAvKiogQ2hhcmFjdGVyIGRhdGEgaW4gY29udGVudC4gKi8KLSAgICBwcml2YXRlIHZvaWQgY2hhckRhdGFJbkNvbnRlbnQoKSB7Ci0KLSAgICAgICAgaWYgKERFQlVHX0VMRU1FTlRfQ0hJTERSRU4pIHsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiY2hhckRhdGFJbkNvbnRlbnQoKSIpOwotICAgICAgICB9Ci0gICAgICAgIGlmIChmRWxlbWVudENoaWxkcmVuLmxlbmd0aCA8PSBmRWxlbWVudENoaWxkcmVuTGVuZ3RoKSB7Ci0gICAgICAgICAgICBRTmFtZVtdIG5ld2FycmF5ID0gbmV3IFFOYW1lW2ZFbGVtZW50Q2hpbGRyZW4ubGVuZ3RoICogMl07Ci0gICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGZFbGVtZW50Q2hpbGRyZW4sIDAsIG5ld2FycmF5LCAwLCBmRWxlbWVudENoaWxkcmVuLmxlbmd0aCk7Ci0gICAgICAgICAgICBmRWxlbWVudENoaWxkcmVuID0gbmV3YXJyYXk7Ci0gICAgICAgIH0KLSAgICAgICAgUU5hbWUgcW5hbWUgPSBmRWxlbWVudENoaWxkcmVuW2ZFbGVtZW50Q2hpbGRyZW5MZW5ndGhdOwotICAgICAgICBpZiAocW5hbWUgPT0gbnVsbCkgewotICAgICAgICAgICAgZm9yIChpbnQgaSA9IGZFbGVtZW50Q2hpbGRyZW5MZW5ndGg7IGkgPCBmRWxlbWVudENoaWxkcmVuLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgZkVsZW1lbnRDaGlsZHJlbltpXSA9IG5ldyBRTmFtZSgpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcW5hbWUgPSBmRWxlbWVudENoaWxkcmVuW2ZFbGVtZW50Q2hpbGRyZW5MZW5ndGhdOwotICAgICAgICB9Ci0gICAgICAgIHFuYW1lLmNsZWFyKCk7Ci0gICAgICAgIGZFbGVtZW50Q2hpbGRyZW5MZW5ndGgrKzsKLQotICAgIH0gLy8gY2hhckRhdGFJbkNvdW50KCkKLQotICAgIC8qKiBjb252ZXJ0IGF0dHJpYnV0ZSB0eXBlIGZyb20gaW50cyB0byBzdHJpbmdzICovCi0gICAgcHJpdmF0ZSBTdHJpbmcgZ2V0QXR0cmlidXRlVHlwZU5hbWUoWE1MQXR0cmlidXRlRGVjbCBhdHRyRGVjbCkgewotCi0gICAgICAgIHN3aXRjaCAoYXR0ckRlY2wuc2ltcGxlVHlwZS50eXBlKSB7Ci0gICAgICAgIGNhc2UgWE1MU2ltcGxlVHlwZS5UWVBFX0VOVElUWTogewotICAgICAgICAgICAgICAgIHJldHVybiBhdHRyRGVjbC5zaW1wbGVUeXBlLmxpc3QgPyBYTUxTeW1ib2xzLmZFTlRJVElFU1N5bWJvbCA6IFhNTFN5bWJvbHMuZkVOVElUWVN5bWJvbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgY2FzZSBYTUxTaW1wbGVUeXBlLlRZUEVfRU5VTUVSQVRJT046IHsKLSAgICAgICAgICAgICAgICBTdHJpbmdCdWZmZXIgYnVmZmVyID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoJygnKTsKLSAgICAgICAgICAgICAgICBmb3IgKGludCBpPTA7IGk8YXR0ckRlY2wuc2ltcGxlVHlwZS5lbnVtZXJhdGlvbi5sZW5ndGggOyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGkgPiAwKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCd8Jyk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZChhdHRyRGVjbC5zaW1wbGVUeXBlLmVudW1lcmF0aW9uW2ldKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgnKScpOwotICAgICAgICAgICAgICAgIHJldHVybiBmU3ltYm9sVGFibGUuYWRkU3ltYm9sKGJ1ZmZlci50b1N0cmluZygpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgY2FzZSBYTUxTaW1wbGVUeXBlLlRZUEVfSUQ6IHsKLSAgICAgICAgICAgICAgICByZXR1cm4gWE1MU3ltYm9scy5mSURTeW1ib2w7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIGNhc2UgWE1MU2ltcGxlVHlwZS5UWVBFX0lEUkVGOiB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGF0dHJEZWNsLnNpbXBsZVR5cGUubGlzdCA/IFhNTFN5bWJvbHMuZklEUkVGU1N5bWJvbCA6IFhNTFN5bWJvbHMuZklEUkVGU3ltYm9sOwotICAgICAgICAgICAgfQotICAgICAgICBjYXNlIFhNTFNpbXBsZVR5cGUuVFlQRV9OTVRPS0VOOiB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGF0dHJEZWNsLnNpbXBsZVR5cGUubGlzdCA/IFhNTFN5bWJvbHMuZk5NVE9LRU5TU3ltYm9sIDogWE1MU3ltYm9scy5mTk1UT0tFTlN5bWJvbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgY2FzZSBYTUxTaW1wbGVUeXBlLlRZUEVfTk9UQVRJT046IHsKLSAgICAgICAgICAgICAgICByZXR1cm4gWE1MU3ltYm9scy5mTk9UQVRJT05TeW1ib2w7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIFhNTFN5bWJvbHMuZkNEQVRBU3ltYm9sOwotCi0gICAgfSAvLyBnZXRBdHRyaWJ1dGVUeXBlTmFtZShYTUxBdHRyaWJ1dGVEZWNsKTpTdHJpbmcKLQotICAgIC8qKiBpbml0aWFsaXphdGlvbiAqLwotICAgIHByb3RlY3RlZCB2b2lkIGluaXQoKSB7Ci0KLSAgICAgICAgLy8gZGF0YXR5cGUgdmFsaWRhdG9ycwotICAgICAgICBpZiAoZlZhbGlkYXRpb24gfHwgZkR5bmFtaWNWYWxpZGF0aW9uKSB7Ci0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIC8vUkVWSVNJVDogZGF0YXR5cGVSZWdpc3RyeSArIGluaXRpYWxpemF0aW9uIG9mIGRhdGF0eXBlCi0gICAgICAgICAgICAgICAgLy8gICAgICAgICB3aHkgZG8gd2UgY2FzdCB0byBMaXN0RGF0YXR5cGVWYWxpZGF0b3I/Ci0gICAgICAgICAgICAgICAgZlZhbElEICAgICAgID0gZkRhdGF0eXBlVmFsaWRhdG9yRmFjdG9yeS5nZXRCdWlsdEluRFYoWE1MU3ltYm9scy5mSURTeW1ib2wpOwotICAgICAgICAgICAgICAgIGZWYWxJRFJlZiAgICA9IGZEYXRhdHlwZVZhbGlkYXRvckZhY3RvcnkuZ2V0QnVpbHRJbkRWKFhNTFN5bWJvbHMuZklEUkVGU3ltYm9sKTsKLSAgICAgICAgICAgICAgICBmVmFsSURSZWZzICAgPSBmRGF0YXR5cGVWYWxpZGF0b3JGYWN0b3J5LmdldEJ1aWx0SW5EVihYTUxTeW1ib2xzLmZJRFJFRlNTeW1ib2wpOwotICAgICAgICAgICAgICAgIGZWYWxFTlRJVFkgICA9IGZEYXRhdHlwZVZhbGlkYXRvckZhY3RvcnkuZ2V0QnVpbHRJbkRWKFhNTFN5bWJvbHMuZkVOVElUWVN5bWJvbCk7Ci0gICAgICAgICAgICAgICAgZlZhbEVOVElUSUVTID0gZkRhdGF0eXBlVmFsaWRhdG9yRmFjdG9yeS5nZXRCdWlsdEluRFYoWE1MU3ltYm9scy5mRU5USVRJRVNTeW1ib2wpOwotICAgICAgICAgICAgICAgIGZWYWxOTVRPS0VOICA9IGZEYXRhdHlwZVZhbGlkYXRvckZhY3RvcnkuZ2V0QnVpbHRJbkRWKFhNTFN5bWJvbHMuZk5NVE9LRU5TeW1ib2wpOwotICAgICAgICAgICAgICAgIGZWYWxOTVRPS0VOUyA9IGZEYXRhdHlwZVZhbGlkYXRvckZhY3RvcnkuZ2V0QnVpbHRJbkRWKFhNTFN5bWJvbHMuZk5NVE9LRU5TU3ltYm9sKTsKLSAgICAgICAgICAgICAgICBmVmFsTk9UQVRJT04gPSBmRGF0YXR5cGVWYWxpZGF0b3JGYWN0b3J5LmdldEJ1aWx0SW5EVihYTUxTeW1ib2xzLmZOT1RBVElPTlN5bWJvbCk7Ci0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgIC8vIHNob3VsZCBuZXZlciBoYXBwZW4KLSAgICAgICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZShTeXN0ZW0uZXJyKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICB9Ci0KLSAgICB9IC8vIGluaXQoKQotCi0gICAgLyoqIGVuc3VyZSBlbGVtZW50IHN0YWNrIGNhcGFjaXR5ICovCi0gICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVN0YWNrQ2FwYWNpdHkgKGludCBuZXdFbGVtZW50RGVwdGgpIHsKLSAgICAgICAgaWYgKG5ld0VsZW1lbnREZXB0aCA9PSBmRWxlbWVudFFOYW1lUGFydHNTdGFjay5sZW5ndGgpIHsKLQotICAgICAgICAgICAgUU5hbWVbXSBuZXdTdGFja09mUXVldWUgPSBuZXcgUU5hbWVbbmV3RWxlbWVudERlcHRoICogMl07Ci0gICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHRoaXMuZkVsZW1lbnRRTmFtZVBhcnRzU3RhY2ssIDAsIG5ld1N0YWNrT2ZRdWV1ZSwgMCwgbmV3RWxlbWVudERlcHRoICk7Ci0gICAgICAgICAgICBmRWxlbWVudFFOYW1lUGFydHNTdGFjayA9IG5ld1N0YWNrT2ZRdWV1ZTsKLQotICAgICAgICAgICAgUU5hbWUgcW5hbWUgPSBmRWxlbWVudFFOYW1lUGFydHNTdGFja1tuZXdFbGVtZW50RGVwdGhdOwotICAgICAgICAgICAgaWYgKHFuYW1lID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gbmV3RWxlbWVudERlcHRoOyBpIDwgZkVsZW1lbnRRTmFtZVBhcnRzU3RhY2subGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgZkVsZW1lbnRRTmFtZVBhcnRzU3RhY2tbaV0gPSBuZXcgUU5hbWUoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGludFtdIG5ld1N0YWNrID0gbmV3IGludFtuZXdFbGVtZW50RGVwdGggKiAyXTsKLSAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZkVsZW1lbnRJbmRleFN0YWNrLCAwLCBuZXdTdGFjaywgMCwgbmV3RWxlbWVudERlcHRoKTsKLSAgICAgICAgICAgIGZFbGVtZW50SW5kZXhTdGFjayA9IG5ld1N0YWNrOwotCi0gICAgICAgICAgICBuZXdTdGFjayA9IG5ldyBpbnRbbmV3RWxlbWVudERlcHRoICogMl07Ci0gICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGZDb250ZW50U3BlY1R5cGVTdGFjaywgMCwgbmV3U3RhY2ssIDAsIG5ld0VsZW1lbnREZXB0aCk7Ci0gICAgICAgICAgICBmQ29udGVudFNwZWNUeXBlU3RhY2sgPSBuZXdTdGFjazsKLQotICAgICAgICB9Ci0gICAgfSAvLyBlbnN1cmVTdGFja0NhcGFjaXR5Ci0KLQotICAgIC8vCi0gICAgLy8gUHJvdGVjdGVkIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqIEhhbmRsZSBlbGVtZW50Ci0gICAgICogQHJldHVybiB0cnVlIGlmIHZhbGlkYXRvciBpcyByZW1vdmVkIGZyb20gdGhlIHBpcGVsaW5lCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gaGFuZGxlU3RhcnRFbGVtZW50KFFOYW1lIGVsZW1lbnQsIFhNTEF0dHJpYnV0ZXMgYXR0cmlidXRlcywgQXVnbWVudGF0aW9ucyBhdWdzKQotICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLQotICAgICAgICAvLyBWQzogUm9vdCBFbGVtZW50IFR5cGUKLSAgICAgICAgLy8gc2VlIGlmIHRoZSByb290IGVsZW1lbnQncyBuYW1lIG1hdGNoZXMgdGhlIG9uZSBpbiBEb2N0eXBlRGVjbAotICAgICAgICBpZiAoIWZTZWVuUm9vdEVsZW1lbnQpIHsKLSAgICAgICAgICAgIC8vIFJFVklTSVQ6IEhlcmUgYXJlIGN1cnJlbnQgYXNzdW1wdGlvbnMgYWJvdXQgdmFsaWRhdGlvbiBmZWF0dXJlcwotICAgICAgICAgICAgLy8gICAgICAgICAgZ2l2ZW4gdGhhdCBYTUxTY2hlbWEgdmFsaWRhdG9yIGlzIGluIHRoZSBwaXBlbGluZQotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIC8vIGh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy92YWxpZGF0aW9uID0gdHJ1ZQotICAgICAgICAgICAgLy8gaHR0cDovL2FwYWNoZS5vcmcveG1sL2ZlYXR1cmVzL3ZhbGlkYXRpb24vc2NoZW1hID0gdHJ1ZQotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIC8vIFsxXSBYTUwgaW5zdGFuY2UgZG9jdW1lbnQgb25seSBoYXMgcmVmZXJlbmNlIHRvIGEgRFRECi0gICAgICAgICAgICAvLyAgT3V0Y29tZTogcmVwb3J0IHZhbGlkYXRpb24gZXJyb3JzIG9ubHkgYWdhaW5zdCBkdGQuCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgLy8gWzJdIFhNTCBpbnN0YW5jZSBkb2N1bWVudCBoYXMgb25seSBYTUwgU2NoZW1hIGdyYW1tYXJzOgotICAgICAgICAgICAgLy8gIE91dGNvbWU6IHJlcG9ydCB2YWxpZGF0aW9uIGVycm9ycyBvbmx5IGFnYWluc3Qgc2NoZW1hcyAobm8gZXJyb3JzIHByb2R1Y2VkIGZyb20gRFREIHZhbGlkYXRvcikKLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAvLyBbM10gWE1MIGluc3RhbmNlIGRvY3VtZW50IGhhcyBEVEQgYW5kIFhNTCBzY2hlbWFzOgotICAgICAgICAgICAgLy8gW2FdIGlmIHNjaGVtYSBsYW5ndWFnZSBpcyBub3Qgc2V0IG91dGNvbWUgLSB2YWxpZGF0aW9uIGVycm9ycyByZXBvcnRlZCBhZ2FpbnN0IGJvdGggZ3JhbW1hcnM6IERURCBhbmQgc2NoZW1hcy4KLSAgICAgICAgICAgIC8vIFtiXSBpZiBzY2hlbWEgbGFuZ3VhZ2UgaXMgc2V0IHRvIFhNTCBTY2hlbWEgLSBkbyBub3QgcmVwb3J0IHZhbGlkYXRpb24gZXJyb3JzCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgLy8gaWYgZHluYW1pYyB2YWxpZGF0aW9uIGlzIG9uCi0gICAgICAgICAgICAvLyAgICAgICAgICAgIHZhbGlkYXRlIG9ubHkgYWdhaW5zdCBncmFtbWFyIHdlJ3ZlIGZvdW5kIChkZXBlbmRpbmcgb24gc2V0dGluZ3MKLSAgICAgICAgICAgIC8vICAgICAgICAgICAgZm9yIHNjaGVtYSBmZWF0dXJlKQotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICBmUGVyZm9ybVZhbGlkYXRpb24gPSB2YWxpZGF0ZSgpOwotICAgICAgICAgICAgZlNlZW5Sb290RWxlbWVudCA9IHRydWU7Ci0gICAgICAgICAgICBmVmFsaWRhdGlvbk1hbmFnZXIuc2V0RW50aXR5U3RhdGUoZkRUREdyYW1tYXIpOwotICAgICAgICAgICAgZlZhbGlkYXRpb25NYW5hZ2VyLnNldEdyYW1tYXJGb3VuZChmU2VlbkRvY3R5cGVEZWNsKTsKLSAgICAgICAgICAgIHJvb3RFbGVtZW50U3BlY2lmaWVkKGVsZW1lbnQpOwotICAgICAgICB9Ci0gICAgICAgIGlmIChmRFRER3JhbW1hciA9PSBudWxsKSB7Ci0KLSAgICAgICAgICAgIGlmICghZlBlcmZvcm1WYWxpZGF0aW9uKSB7Ci0gICAgICAgICAgICAgICAgZkN1cnJlbnRFbGVtZW50SW5kZXggPSAtMTsKLSAgICAgICAgICAgICAgICBmQ3VycmVudENvbnRlbnRTcGVjVHlwZSA9IC0xOwotICAgICAgICAgICAgICAgIGZJbkVsZW1lbnRDb250ZW50ID0gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoZlBlcmZvcm1WYWxpZGF0aW9uKSB7Ci0gICAgICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNU0dfR1JBTU1BUl9OT1RfRk9VTkQiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXsgZWxlbWVudC5yYXduYW1lfSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxFcnJvclJlcG9ydGVyLlNFVkVSSVRZX0VSUk9SKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIG1vZGlmeSBwaXBlbGluZQotICAgICAgICAgICAgaWYgKGZEb2N1bWVudFNvdXJjZSAhPW51bGwgKSB7Ci0gICAgICAgICAgICAgICAgZkRvY3VtZW50U291cmNlLnNldERvY3VtZW50SGFuZGxlcihmRG9jdW1lbnRIYW5kbGVyKTsKLSAgICAgICAgICAgICAgICBpZiAoZkRvY3VtZW50SGFuZGxlciAhPSBudWxsKQotICAgICAgICAgICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLnNldERvY3VtZW50U291cmNlKGZEb2N1bWVudFNvdXJjZSk7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAvLyAgcmVzb2x2ZSB0aGUgZWxlbWVudAotICAgICAgICAgICAgZkN1cnJlbnRFbGVtZW50SW5kZXggPSBmRFRER3JhbW1hci5nZXRFbGVtZW50RGVjbEluZGV4KGVsZW1lbnQpOwotICAgICAgICAgICAgLy9jaGFuZ2VkIGhlcmUuLiBuZXcgZnVuY3Rpb24gZm9yIGdldENvbnRlbnRTcGVjVHlwZQotICAgICAgICAgICAgZkN1cnJlbnRDb250ZW50U3BlY1R5cGUgPSBmRFRER3JhbW1hci5nZXRDb250ZW50U3BlY1R5cGUoZkN1cnJlbnRFbGVtZW50SW5kZXgpOwotICAgICAgICAgICAgaWYgKGZDdXJyZW50Q29udGVudFNwZWNUeXBlID09IC0xICYmIGZQZXJmb3JtVmFsaWRhdGlvbikgewotICAgICAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTVNHX0VMRU1FTlRfTk9UX0RFQ0xBUkVEIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117IGVsZW1lbnQucmF3bmFtZX0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9FUlJPUik7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vICAwLiBpbnNlcnQgZGVmYXVsdCBhdHRyaWJ1dGVzCi0gICAgICAgICAgICAvLyAgMS4gbm9ybWFsaXplIHRoZSBhdHRyaWJ1dGVzCi0gICAgICAgICAgICAvLyAgMi4gdmFsaWRhdGUgdGhlIGF0dHJpdnV0ZSBsaXN0LgotICAgICAgICAgICAgLy8gVE8gRE86Ci0gICAgICAgICAgICAvL2NoYW5nZWQgaGVyZS4uIGFsc28gcGFzcyBlbGVtZW50IG5hbWUsCi0gICAgICAgICAgICBhZGREVEREZWZhdWx0QXR0cnNBbmRWYWxpZGF0ZShlbGVtZW50LCBmQ3VycmVudEVsZW1lbnRJbmRleCwgYXR0cmlidXRlcyk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBzZXQgZWxlbWVudCBjb250ZW50IHN0YXRlCi0gICAgICAgIGZJbkVsZW1lbnRDb250ZW50ID0gZkN1cnJlbnRDb250ZW50U3BlY1R5cGUgPT0gWE1MRWxlbWVudERlY2wuVFlQRV9DSElMRFJFTjsKLQotICAgICAgICAvLyBpbmNyZW1lbnQgdGhlIGVsZW1lbnQgZGVwdGgsIGFkZCB0aGlzIGVsZW1lbnQncwotICAgICAgICAvLyBRTmFtZSB0byBpdHMgZW5jbG9zaW5nIGVsZW1lbnQgJ3MgY2hpbGRyZW4gbGlzdAotICAgICAgICBmRWxlbWVudERlcHRoKys7Ci0gICAgICAgIGlmIChmUGVyZm9ybVZhbGlkYXRpb24pIHsKLSAgICAgICAgICAgIC8vIHB1c2ggY3VycmVudCBsZW5ndGggb250byBzdGFjawotICAgICAgICAgICAgaWYgKGZFbGVtZW50Q2hpbGRyZW5PZmZzZXRTdGFjay5sZW5ndGggPD0gZkVsZW1lbnREZXB0aCkgewotICAgICAgICAgICAgICAgIGludCBuZXdhcnJheVtdID0gbmV3IGludFtmRWxlbWVudENoaWxkcmVuT2Zmc2V0U3RhY2subGVuZ3RoICogMl07Ci0gICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShmRWxlbWVudENoaWxkcmVuT2Zmc2V0U3RhY2ssIDAsIG5ld2FycmF5LCAwLCBmRWxlbWVudENoaWxkcmVuT2Zmc2V0U3RhY2subGVuZ3RoKTsKLSAgICAgICAgICAgICAgICBmRWxlbWVudENoaWxkcmVuT2Zmc2V0U3RhY2sgPSBuZXdhcnJheTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGZFbGVtZW50Q2hpbGRyZW5PZmZzZXRTdGFja1tmRWxlbWVudERlcHRoXSA9IGZFbGVtZW50Q2hpbGRyZW5MZW5ndGg7Ci0KLSAgICAgICAgICAgIC8vIGFkZCB0aGlzIGVsZW1lbnQgdG8gY2hpbGRyZW4KLSAgICAgICAgICAgIGlmIChmRWxlbWVudENoaWxkcmVuLmxlbmd0aCA8PSBmRWxlbWVudENoaWxkcmVuTGVuZ3RoKSB7Ci0gICAgICAgICAgICAgICAgUU5hbWVbXSBuZXdhcnJheSA9IG5ldyBRTmFtZVtmRWxlbWVudENoaWxkcmVuTGVuZ3RoICogMl07Ci0gICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShmRWxlbWVudENoaWxkcmVuLCAwLCBuZXdhcnJheSwgMCwgZkVsZW1lbnRDaGlsZHJlbi5sZW5ndGgpOwotICAgICAgICAgICAgICAgIGZFbGVtZW50Q2hpbGRyZW4gPSBuZXdhcnJheTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIFFOYW1lIHFuYW1lID0gZkVsZW1lbnRDaGlsZHJlbltmRWxlbWVudENoaWxkcmVuTGVuZ3RoXTsKLSAgICAgICAgICAgIGlmIChxbmFtZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IGZFbGVtZW50Q2hpbGRyZW5MZW5ndGg7IGkgPCBmRWxlbWVudENoaWxkcmVuLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZFbGVtZW50Q2hpbGRyZW5baV0gPSBuZXcgUU5hbWUoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgcW5hbWUgPSBmRWxlbWVudENoaWxkcmVuW2ZFbGVtZW50Q2hpbGRyZW5MZW5ndGhdOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcW5hbWUuc2V0VmFsdWVzKGVsZW1lbnQpOwotICAgICAgICAgICAgZkVsZW1lbnRDaGlsZHJlbkxlbmd0aCsrOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gc2F2ZSBjdXJyZW50IGVsZW1lbnQgaW5mb3JtYXRpb24KLSAgICAgICAgZkN1cnJlbnRFbGVtZW50LnNldFZhbHVlcyhlbGVtZW50KTsKLSAgICAgICAgZW5zdXJlU3RhY2tDYXBhY2l0eShmRWxlbWVudERlcHRoKTsKLSAgICAgICAgZkVsZW1lbnRRTmFtZVBhcnRzU3RhY2tbZkVsZW1lbnREZXB0aF0uc2V0VmFsdWVzKGZDdXJyZW50RWxlbWVudCk7Ci0gICAgICAgIGZFbGVtZW50SW5kZXhTdGFja1tmRWxlbWVudERlcHRoXSA9IGZDdXJyZW50RWxlbWVudEluZGV4OwotICAgICAgICBmQ29udGVudFNwZWNUeXBlU3RhY2tbZkVsZW1lbnREZXB0aF0gPSBmQ3VycmVudENvbnRlbnRTcGVjVHlwZTsKLSAgICAgICAgc3RhcnROYW1lc3BhY2VTY29wZShlbGVtZW50LCBhdHRyaWJ1dGVzLCBhdWdzKTsKLSAgICAgICAgcmV0dXJuIGZhbHNlOwotCi0gICAgfSAvLyBoYW5kbGVTdGFydEVsZW1lbnQoUU5hbWUsWE1MQXR0cmlidXRlcykKLQotICAgIHByb3RlY3RlZCB2b2lkIHN0YXJ0TmFtZXNwYWNlU2NvcGUoUU5hbWUgZWxlbWVudCwgWE1MQXR0cmlidXRlcyBhdHRyaWJ1dGVzLCBBdWdtZW50YXRpb25zIGF1Z3MpewotICAgIH0KLQotICAgIC8qKiBIYW5kbGUgZW5kIGVsZW1lbnQuICovCi0gICAgcHJvdGVjdGVkIHZvaWQgaGFuZGxlRW5kRWxlbWVudChRTmFtZSBlbGVtZW50LCAgQXVnbWVudGF0aW9ucyBhdWdzLCBib29sZWFuIGlzRW1wdHkpCi0gICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy8gZGVjcmVhc2UgZWxlbWVudCBkZXB0aAotICAgICAgICBmRWxlbWVudERlcHRoLS07Ci0KLSAgICAgICAgLy8gdmFsaWRhdGUKLSAgICAgICAgaWYgKGZQZXJmb3JtVmFsaWRhdGlvbikgewotICAgICAgICAgICAgaW50IGVsZW1lbnRJbmRleCA9IGZDdXJyZW50RWxlbWVudEluZGV4OwotICAgICAgICAgICAgaWYgKGVsZW1lbnRJbmRleCAhPSAtMSAmJiBmQ3VycmVudENvbnRlbnRTcGVjVHlwZSAhPSAtMSkgewotICAgICAgICAgICAgICAgIFFOYW1lIGNoaWxkcmVuW10gPSBmRWxlbWVudENoaWxkcmVuOwotICAgICAgICAgICAgICAgIGludCBjaGlsZHJlbk9mZnNldCA9IGZFbGVtZW50Q2hpbGRyZW5PZmZzZXRTdGFja1tmRWxlbWVudERlcHRoICsgMV0gKyAxOwotICAgICAgICAgICAgICAgIGludCBjaGlsZHJlbkxlbmd0aCA9IGZFbGVtZW50Q2hpbGRyZW5MZW5ndGggLSBjaGlsZHJlbk9mZnNldDsKLSAgICAgICAgICAgICAgICBpbnQgcmVzdWx0ID0gY2hlY2tDb250ZW50KGVsZW1lbnRJbmRleCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuLCBjaGlsZHJlbk9mZnNldCwgY2hpbGRyZW5MZW5ndGgpOwotCi0gICAgICAgICAgICAgICAgaWYgKHJlc3VsdCAhPSAtMSkgewotICAgICAgICAgICAgICAgICAgICBmRFRER3JhbW1hci5nZXRFbGVtZW50RGVjbChlbGVtZW50SW5kZXgsIGZUZW1wRWxlbWVudERlY2wpOwotICAgICAgICAgICAgICAgICAgICBpZiAoZlRlbXBFbGVtZW50RGVjbC50eXBlID09IFhNTEVsZW1lbnREZWNsLlRZUEVfRU1QVFkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNU0dfQ09OVEVOVF9JTlZBTElEIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXsgZWxlbWVudC5yYXduYW1lLCAiRU1QVFkifSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTEVycm9yUmVwb3J0ZXIuU0VWRVJJVFlfRVJST1IpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG1lc3NhZ2VLZXkgPSByZXN1bHQgIT0gY2hpbGRyZW5MZW5ndGggPwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTVNHX0NPTlRFTlRfSU5WQUxJRCIgOiAiTVNHX0NPTlRFTlRfSU5DT01QTEVURSI7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmRXJyb3JSZXBvcnRlci5yZXBvcnRFcnJvcihYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlS2V5LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdeyBlbGVtZW50LnJhd25hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkRUREdyYW1tYXIuZ2V0Q29udGVudFNwZWNBc1N0cmluZyhlbGVtZW50SW5kZXgpfSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTEVycm9yUmVwb3J0ZXIuU0VWRVJJVFlfRVJST1IpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZkVsZW1lbnRDaGlsZHJlbkxlbmd0aCA9IGZFbGVtZW50Q2hpbGRyZW5PZmZzZXRTdGFja1tmRWxlbWVudERlcHRoICsgMV0gKyAxOwotICAgICAgICB9Ci0KLSAgICAgICAgZW5kTmFtZXNwYWNlU2NvcGUoZkN1cnJlbnRFbGVtZW50LCBhdWdzLCBpc0VtcHR5KTsKLQotICAgICAgICAvLyBub3cgcG9wIHRoaXMgZWxlbWVudCBvZmYgdGhlIHRvcCBvZiB0aGUgZWxlbWVudCBzdGFjawotICAgICAgICBpZiAoZkVsZW1lbnREZXB0aCA8IC0xKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiRldLMDA4IEVsZW1lbnQgc3RhY2sgdW5kZXJmbG93Iik7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGZFbGVtZW50RGVwdGggPCAwKSB7Ci0gICAgICAgICAgICBmQ3VycmVudEVsZW1lbnQuY2xlYXIoKTsKLSAgICAgICAgICAgIGZDdXJyZW50RWxlbWVudEluZGV4ID0gLTE7Ci0gICAgICAgICAgICBmQ3VycmVudENvbnRlbnRTcGVjVHlwZSA9IC0xOwotICAgICAgICAgICAgZkluRWxlbWVudENvbnRlbnQgPSBmYWxzZTsKLQotICAgICAgICAgICAgLy8gVE8gRE8gOiBmaXggdGhpcwotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIC8vIENoZWNrIGFmdGVyIGRvY3VtZW50IGlzIGZ1bGx5IHBhcnNlZAotICAgICAgICAgICAgLy8gKDEpIGNoZWNrIHRoYXQgdGhlcmUgd2FzIGFuIGVsZW1lbnQgd2l0aCBhIG1hdGNoaW5nIGlkIGZvciBldmVyeQotICAgICAgICAgICAgLy8gICBJRFJFRiBhbmQgSURSRUZTIGF0dHIgKFZfSURSRUYwKQotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIGlmIChmUGVyZm9ybVZhbGlkYXRpb24pIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgdmFsdWUgPSBmVmFsaWRhdGlvblN0YXRlLmNoZWNrSURSZWZJRCgpOwotICAgICAgICAgICAgICAgIGlmICh2YWx1ZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKCBYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTVNHX0VMRU1FTlRfV0lUSF9JRF9SRVFVSVJFRCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117dmFsdWV9LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9FUlJPUiApOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIElmIE5hbWVzcGFjZSBlbmFibGUgdGhlbiBsb2NhbE5hbWUgIT0gcmF3TmFtZQotICAgICAgICBmQ3VycmVudEVsZW1lbnQuc2V0VmFsdWVzKGZFbGVtZW50UU5hbWVQYXJ0c1N0YWNrW2ZFbGVtZW50RGVwdGhdKTsKLQotICAgICAgICBmQ3VycmVudEVsZW1lbnRJbmRleCA9IGZFbGVtZW50SW5kZXhTdGFja1tmRWxlbWVudERlcHRoXTsKLSAgICAgICAgZkN1cnJlbnRDb250ZW50U3BlY1R5cGUgPSBmQ29udGVudFNwZWNUeXBlU3RhY2tbZkVsZW1lbnREZXB0aF07Ci0gICAgICAgIGZJbkVsZW1lbnRDb250ZW50ID0gKGZDdXJyZW50Q29udGVudFNwZWNUeXBlID09IFhNTEVsZW1lbnREZWNsLlRZUEVfQ0hJTERSRU4pOwotCi0gICAgfSAvLyBoYW5kbGVFbmRFbGVtZW50KFFOYW1lLGJvb2xlYW4pCi0KLSAgICBwcm90ZWN0ZWQgdm9pZCBlbmROYW1lc3BhY2VTY29wZShRTmFtZSBlbGVtZW50LCAgQXVnbWVudGF0aW9ucyBhdWdzLCBib29sZWFuIGlzRW1wdHkpewotCi0gICAgICAgIC8vIGNhbGwgaGFuZGxlcnMKLSAgICAgICAgaWYgKGZEb2N1bWVudEhhbmRsZXIgIT0gbnVsbCAmJiAhaXNFbXB0eSkgewotICAgICAgICAgICAgLy8gTk9URTogVGhlIGJpbmRpbmcgb2YgdGhlIGVsZW1lbnQgZG9lc24ndCBhY3R1YWxseSBoYXBwZW4KLSAgICAgICAgICAgIC8vICAgICAgIHlldCBiZWNhdXNlIHRoZSBuYW1lc3BhY2UgYmluZGVyIGRvZXMgdGhhdC4gSG93ZXZlciwKLSAgICAgICAgICAgIC8vICAgICAgIGlmIGl0IGRvZXMgaXQgYmVmb3JlIHRoaXMgcG9pbnQsIHRoZW4gdGhlIGVuZFByZWZpeC0KLSAgICAgICAgICAgIC8vICAgICAgIE1hcHBpbmcgY2FsbHMgZ2V0IG1hZGUgdG9vIHNvb24hIEFzIGxvbmcgYXMgdGhlCi0gICAgICAgICAgICAvLyAgICAgICByYXduYW1lcyBtYXRjaCwgd2Uga25vdyBpdCdsbCBoYXZlIGEgZ29vZCBiaW5kaW5nLAotICAgICAgICAgICAgLy8gICAgICAgc28gd2UgY2FuIGp1c3QgdXNlIHRoZSBjdXJyZW50IGVsZW1lbnQuIC1BYwotICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci5lbmRFbGVtZW50KGZDdXJyZW50RWxlbWVudCwgYXVncyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvLyByZXR1cm5zIHdoZXRoZXIgYSBjaGFyYWN0ZXIgaXMgc3BhY2UgYWNjb3JkaW5nIHRvIHRoZQotICAgIC8vIHZlcnNpb24gb2YgWE1MIHRoaXMgdmFsaWRhdG9yIHN1cHBvcnRzLgotICAgIHByb3RlY3RlZCBib29sZWFuIGlzU3BhY2UoaW50IGMpIHsKLSAgICAgICAgcmV0dXJuIFhNTENoYXIuaXNTcGFjZShjKTsKLSAgICB9IC8vIGlzU3BhY2UoaW50KTogIGJvb2xlYW4KLQotICAgIHB1YmxpYyBib29sZWFuIGNoYXJhY3RlckRhdGEoU3RyaW5nIGRhdGEsIEF1Z21lbnRhdGlvbnMgYXVncykgewotICAgICAgICBjaGFyYWN0ZXJzKG5ldyBYTUxTdHJpbmcoZGF0YS50b0NoYXJBcnJheSgpLCAwLCBkYXRhLmxlbmd0aCgpKSwgYXVncyk7Ci0gICAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotfSAvLyBjbGFzcyBYTUxEVERWYWxpZGF0b3IKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHRkL1hNTERURFZhbGlkYXRvckZpbHRlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdGQvWE1MRFREVmFsaWRhdG9yRmlsdGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGYwNWFiYTUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdGQvWE1MRFREVmFsaWRhdG9yRmlsdGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5MyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxLCAyMDAyIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYZXJjZXMiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDIsIEludGVybmF0aW9uYWwKLSAqIEJ1c2luZXNzIE1hY2hpbmVzLCBJbmMuLCBodHRwOi8vd3d3LmFwYWNoZS5vcmcuICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHRkOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTERvY3VtZW50RmlsdGVyOwotCi0vKioKLSAqIERlZmluZXMgYSBEVEQgVmFsaWRhdG9yIGZpbHRlciB0byBhbGxvdwotICogY29tcG9uZW50cyB0byBxdWVyeSB0aGUgRFREIHZhbGlkYXRvci4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBFbGVuYSBMaXRhbmksIElCTQotICoKLSAqLwotcHVibGljIGludGVyZmFjZSBYTUxEVERWYWxpZGF0b3JGaWx0ZXIKLSAgICBleHRlbmRzIFhNTERvY3VtZW50RmlsdGVyIHsKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgdmFsaWRhdG9yIGhhcyBhIERURCBncmFtbWFyCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHZhbGlkYXRvciBoYXMgYSBEVEQgZ3JhbW1hcgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGhhc0dyYW1tYXIoKTsKLQotICAgIC8qKgotICAgICAqIFJldHVybiB0cnVlIGlmIHZhbGlkYXRvciBtdXN0IHZhbGlkYXRlIHRoZSBkb2N1bWVudAotICAgICAqCi0gICAgICogQHJldHVybiB0cnVlIGlmIHZhbGlkYXRvciBtdXN0IHZhbGlkYXRlIHRoZSBkb2N1bWVudAotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIHZhbGlkYXRlKCk7Ci0KLQotfSAvLyBpbnRlcmZhY2UgWE1MRFREVmFsaWRhdG9yRmlsdGVyCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R0ZC9YTUxFbGVtZW50RGVjbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdGQvWE1MRWxlbWVudERlY2wuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMjg3ZDEwZC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R0ZC9YTUxFbGVtZW50RGVjbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTQxICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTktMjAwMiBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhlcmNlcyIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgSW50ZXJuYXRpb25hbAotICogQnVzaW5lc3MgTWFjaGluZXMsIEluYy4sIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdGQ7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5RTmFtZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHRkLm1vZGVscy5Db250ZW50TW9kZWxWYWxpZGF0b3I7Ci0KLS8qKgotICovCi1wdWJsaWMgY2xhc3MgWE1MRWxlbWVudERlY2wgewotCi0gICAgLy8KLSAgICAvLyBDb25zdGFudHMKLSAgICAvLwotCi0gICAgLyoqIFRZUEVfQU5ZICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBUWVBFX0FOWSA9IDA7Ci0KLSAgICAvKiogVFlQRV9FTVBUWSAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgVFlQRV9FTVBUWSA9IDE7Ci0KLSAgICAvKiogVFlQRV9NSVhFRCAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgVFlQRV9NSVhFRCA9IDI7Ci0KLSAgICAvKiogVFlQRV9DSElMRFJFTiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgVFlQRV9DSElMRFJFTiA9IDM7Ci0KLSAgICAvKiogVFlQRV9TSU1QTEUgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFRZUEVfU0lNUExFID0gNDsKLQotICAgIC8vCi0gICAgLy8gRGF0YQotICAgIC8vCi0KLSAgICAvKiogbmFtZSAqLwotICAgIHB1YmxpYyBmaW5hbCBRTmFtZSBuYW1lID0gbmV3IFFOYW1lKCk7Ci0KLSAgICAvKiogc2NvcGUgKi8KLSAgICBwdWJsaWMgaW50IHNjb3BlID0gLTE7Ci0KLSAgICAvKiogdHlwZSAqLwotICAgIHB1YmxpYyBzaG9ydCB0eXBlID0gLTE7Ci0KLSAgICAvKiogY29udGVudE1vZGVsVmFsaWRhdG9yICovCi0gICAgcHVibGljIENvbnRlbnRNb2RlbFZhbGlkYXRvciBjb250ZW50TW9kZWxWYWxpZGF0b3I7Ci0KLSAgICAvKiogc2ltcGxlVHlwZSAqLwotICAgIHB1YmxpYyBmaW5hbCBYTUxTaW1wbGVUeXBlIHNpbXBsZVR5cGUgPSBuZXcgWE1MU2ltcGxlVHlwZSgpOwotCi0gICAgLy8KLSAgICAvLyBNZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIHNldFZhbHVlcwotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUKLSAgICAgKiBAcGFyYW0gc2NvcGUKLSAgICAgKiBAcGFyYW0gdHlwZQotICAgICAqIEBwYXJhbSBjb250ZW50TW9kZWxWYWxpZGF0b3IKLSAgICAgKiBAcGFyYW0gc2ltcGxlVHlwZQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFZhbHVlcyhRTmFtZSBuYW1lLCBpbnQgc2NvcGUsIHNob3J0IHR5cGUsIENvbnRlbnRNb2RlbFZhbGlkYXRvciBjb250ZW50TW9kZWxWYWxpZGF0b3IsIFhNTFNpbXBsZVR5cGUgc2ltcGxlVHlwZSkgewotICAgICAgICB0aGlzLm5hbWUuc2V0VmFsdWVzKG5hbWUpOwotICAgICAgICB0aGlzLnNjb3BlICAgICAgICAgICAgICAgICA9IHNjb3BlOwotICAgICAgICB0aGlzLnR5cGUgICAgICAgICAgICAgICAgICA9IHR5cGU7Ci0gICAgICAgIHRoaXMuY29udGVudE1vZGVsVmFsaWRhdG9yID0gY29udGVudE1vZGVsVmFsaWRhdG9yOwotICAgICAgICB0aGlzLnNpbXBsZVR5cGUuc2V0VmFsdWVzKHNpbXBsZVR5cGUpOwotICAgIH0gLy8gc2V0VmFsdWVzCi0KLSAgICAvKioKLSAgICAgKiBjbGVhcgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGNsZWFyKCkgewotICAgICAgICB0aGlzLm5hbWUuY2xlYXIoKTsKLSAgICAgICAgdGhpcy50eXBlICAgICAgICAgID0gLTE7Ci0gICAgICAgIHRoaXMuc2NvcGUgICAgICAgICA9IC0xOwotICAgICAgICB0aGlzLmNvbnRlbnRNb2RlbFZhbGlkYXRvciA9IG51bGw7Ci0gICAgICAgIHRoaXMuc2ltcGxlVHlwZS5jbGVhcigpOwotICAgIH0gLy8gY2xlYXIKLQotfSAvLyBjbGFzcyBYTUxFbGVtZW50RGVjbApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdGQvWE1MRW50aXR5RGVjbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdGQvWE1MRW50aXR5RGVjbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4NDk2ZGMxLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHRkL1hNTEVudGl0eURlY2wuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE1OCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5LTIwMDIgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYZXJjZXMiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIEludGVybmF0aW9uYWwKLSAqIEJ1c2luZXNzIE1hY2hpbmVzLCBJbmMuLCBodHRwOi8vd3d3LmFwYWNoZS5vcmcuICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHRkOwotCi0vKioKLSAqLwotcHVibGljIGNsYXNzIFhNTEVudGl0eURlY2wgewotCi0gICAgLy8KLSAgICAvLyBEYXRhCi0gICAgLy8KLQotICAgIC8qKiBuYW1lICovCi0gICAgcHVibGljIFN0cmluZyBuYW1lOwotCi0gICAgLyoqIHB1YmxpY0lkICovCi0gICAgcHVibGljIFN0cmluZyBwdWJsaWNJZDsKLQotICAgIC8qKiBzeXN0ZW1JZCAqLwotICAgIHB1YmxpYyBTdHJpbmcgc3lzdGVtSWQ7Ci0KLSAgICAvKiogYmFzZVN5c3RlbUlkICovCi0gICAgcHVibGljIFN0cmluZyBiYXNlU3lzdGVtSWQ7Ci0KLSAgICAvKiogbm90YXRpb24gKi8KLSAgICBwdWJsaWMgU3RyaW5nIG5vdGF0aW9uOwotCi0gICAgLyoqIGlzUEUgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc1BFOwotCi0gICAgLyoqIGluRXh0ZXJuYWwgKi8KLSAgICAvKiogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBmbGFnIG9mIHdoZXJlIHRoZSBlbnRpdHkgaXMgZGVmaW5lZCwgbm90IHdoZXRoZXIgaXQgaXMgYSBleHRlcm5hbCBlbnRpdHkgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpbkV4dGVybmFsOwotCi0gICAgLyoqIFZhbHVlLiAqLwotICAgIHB1YmxpYyBTdHJpbmcgdmFsdWU7Ci0KLSAgICAvLwotICAgIC8vIE1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogc2V0VmFsdWVzCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZQotICAgICAqIEBwYXJhbSBwdWJsaWNJZAotICAgICAqIEBwYXJhbSBzeXN0ZW1JZAotICAgICAqIEBwYXJhbSBiYXNlU3lzdGVtSWQKLSAgICAgKiBAcGFyYW0gbm90YXRpb24KLSAgICAgKiBAcGFyYW0gaXNQRQotICAgICAqIEBwYXJhbSBpbkV4dGVybmFsCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0VmFsdWVzKFN0cmluZyBuYW1lLCBTdHJpbmcgcHVibGljSWQsIFN0cmluZyBzeXN0ZW1JZCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGJhc2VTeXN0ZW1JZCwgU3RyaW5nIG5vdGF0aW9uLAotICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGlzUEUsIGJvb2xlYW4gaW5FeHRlcm5hbCkgewotICAgICAgICBzZXRWYWx1ZXMobmFtZSwgcHVibGljSWQsIHN5c3RlbUlkLCBiYXNlU3lzdGVtSWQsIG5vdGF0aW9uLCBudWxsLCBpc1BFLCBpbkV4dGVybmFsKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBzZXRWYWx1ZXMKLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lCi0gICAgICogQHBhcmFtIHB1YmxpY0lkCi0gICAgICogQHBhcmFtIHN5c3RlbUlkCi0gICAgICogQHBhcmFtIGJhc2VTeXN0ZW1JZAotICAgICAqIEBwYXJhbSB2YWx1ZQotICAgICAqIEBwYXJhbSBub3RhdGlvbgotICAgICAqIEBwYXJhbSBpc1BFCi0gICAgICogQHBhcmFtIGluRXh0ZXJuYWwKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRWYWx1ZXMoU3RyaW5nIG5hbWUsIFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkLAotICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgYmFzZVN5c3RlbUlkLCBTdHJpbmcgbm90YXRpb24sCi0gICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyB2YWx1ZSwgYm9vbGVhbiBpc1BFLCBib29sZWFuIGluRXh0ZXJuYWwpIHsKLSAgICAgICAgdGhpcy5uYW1lICAgICAgICAgPSBuYW1lOwotICAgICAgICB0aGlzLnB1YmxpY0lkICAgICA9IHB1YmxpY0lkOwotICAgICAgICB0aGlzLnN5c3RlbUlkICAgICA9IHN5c3RlbUlkOwotICAgICAgICB0aGlzLmJhc2VTeXN0ZW1JZCA9IGJhc2VTeXN0ZW1JZDsKLSAgICAgICAgdGhpcy5ub3RhdGlvbiAgICAgPSBub3RhdGlvbjsKLSAgICAgICAgdGhpcy52YWx1ZSAgICAgICAgPSB2YWx1ZTsKLSAgICAgICAgdGhpcy5pc1BFICAgICAgICAgPSBpc1BFOwotICAgICAgICB0aGlzLmluRXh0ZXJuYWwgICA9IGluRXh0ZXJuYWw7Ci0gICAgfSAvLyBzZXRWYWx1ZXMoU3RyaW5nLFN0cmluZyxTdHJpbmcsU3RyaW5nLFN0cmluZyxib29sZWFuLGJvb2xlYW4pCi0KLSAgICAvKioKLSAgICAgKiBjbGVhcgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGNsZWFyKCkgewotICAgICAgIHRoaXMubmFtZSAgICAgICAgID0gbnVsbDsKLSAgICAgICB0aGlzLnB1YmxpY0lkICAgICA9IG51bGw7Ci0gICAgICAgdGhpcy5zeXN0ZW1JZCAgICAgPSBudWxsOwotICAgICAgIHRoaXMuYmFzZVN5c3RlbUlkID0gbnVsbDsKLSAgICAgICB0aGlzLm5vdGF0aW9uICAgICA9IG51bGw7Ci0gICAgICAgdGhpcy52YWx1ZSAgICAgICAgPSBudWxsOwotICAgICAgIHRoaXMuaXNQRSAgICAgICAgID0gZmFsc2U7Ci0gICAgICAgdGhpcy5pbkV4dGVybmFsICAgPSBmYWxzZTsKLQotICAgIH0gLy8gY2xlYXIKLQotfSAvLyBjbGFzcyBYTUxFbnRpdHlEZWNsCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R0ZC9YTUxOU0RURFZhbGlkYXRvci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdGQvWE1MTlNEVERWYWxpZGF0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYmY0ZWNmOC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R0ZC9YTUxOU0RURFZhbGlkYXRvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjc1ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTktMjAwMiBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGVyY2VzIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBJbnRlcm5hdGlvbmFsCi0gKiBCdXNpbmVzcyBNYWNoaW5lcywgSW5jLiwgaHR0cDovL3d3dy5hcGFjaGUub3JnLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR0ZDsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5YTUxFcnJvclJlcG9ydGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5tc2cuWE1MTWVzc2FnZUZvcm1hdHRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuWE1MU3ltYm9sczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5BdWdtZW50YXRpb25zOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLk5hbWVzcGFjZUNvbnRleHQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuUU5hbWU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MQXR0cmlidXRlczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTklFeGNlcHRpb247Ci0KLQotLyoqCi0gKiBUaGUgRFREIHZhbGlkYXRvci4gVGhlIHZhbGlkYXRvciBpbXBsZW1lbnRzIGEgZG9jdW1lbnQKLSAqIGZpbHRlcjogcmVjZWl2aW5nIGRvY3VtZW50IGV2ZW50cyBmcm9tIHRoZSBzY2FubmVyOyB2YWxpZGF0aW5nCi0gKiB0aGUgY29udGVudCBhbmQgc3RydWN0dXJlOyBhdWdtZW50aW5nIHRoZSBJbmZvU2V0LCBpZiBhcHBsaWNhYmxlOwotICogYW5kIG5vdGlmeWluZyB0aGUgcGFyc2VyIG9mIHRoZSBpbmZvcm1hdGlvbiByZXN1bHRpbmcgZnJvbSB0aGUKLSAqIHZhbGlkYXRpb24gcHJvY2Vzcy4KLSAqIDxwPiBGb3JtZXJseSwgdGhpcyBjb21wb25lbnQgYWxzbyBoYW5kbGVkIERURCBldmVudHMgYW5kIGdyYW1tYXIgY29uc3RydWN0aW9uLgotICogVG8gZmFjaWxpdGF0ZSB0aGUgZGV2ZWxvcG1lbnQgb2YgYSBtZWFuaW5nZnVsIERURCBncmFtbWFyIGNhY2hpbmcvcHJlcGFyc2luZwotICogZnJhbWV3b3JrLCB0aGlzIGZ1bmN0aW9uYWxpdHkgaGFzIGJlZW4gbW92ZWQgaW50byB0aGUgWE1MRFRETG9hZGVyCi0gKiBjbGFzcy4gIFRoZXJlZm9yZSwgdGhpcyBjbGFzcyBubyBsb25nZXIgaW1wbGVtZW50cyB0aGUgRFRERmlsdGVyCi0gKiBvciBEVERDb250ZW50TW9kZWxGaWx0ZXIgaW50ZXJmYWNlcy4KLSAqIDxwPgotICogVGhpcyBjb21wb25lbnQgcmVxdWlyZXMgdGhlIGZvbGxvd2luZyBmZWF0dXJlcyBhbmQgcHJvcGVydGllcyBmcm9tIHRoZQotICogY29tcG9uZW50IG1hbmFnZXIgdGhhdCB1c2VzIGl0OgotICogPHVsPgotICogIDxsaT5odHRwOi8veG1sLm9yZy9zYXgvZmVhdHVyZXMvbmFtZXNwYWNlczwvbGk+Ci0gKiAgPGxpPmh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy92YWxpZGF0aW9uPC9saT4KLSAqICA8bGk+aHR0cDovL2FwYWNoZS5vcmcveG1sL2ZlYXR1cmVzL3ZhbGlkYXRpb24vZHluYW1pYzwvbGk+Ci0gKiAgPGxpPmh0dHA6Ly9hcGFjaGUub3JnL3htbC9wcm9wZXJ0aWVzL2ludGVybmFsL3N5bWJvbC10YWJsZTwvbGk+Ci0gKiAgPGxpPmh0dHA6Ly9hcGFjaGUub3JnL3htbC9wcm9wZXJ0aWVzL2ludGVybmFsL2Vycm9yLXJlcG9ydGVyPC9saT4KLSAqICA8bGk+aHR0cDovL2FwYWNoZS5vcmcveG1sL3Byb3BlcnRpZXMvaW50ZXJuYWwvZ3JhbW1hci1wb29sPC9saT4KLSAqICA8bGk+aHR0cDovL2FwYWNoZS5vcmcveG1sL3Byb3BlcnRpZXMvaW50ZXJuYWwvZGF0YXR5cGUtdmFsaWRhdG9yLWZhY3Rvcnk8L2xpPgotICogPC91bD4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBFbGVuYSBMaXRhbmksIElCTQotICoKLQotICovCi1wdWJsaWMgY2xhc3MgWE1MTlNEVERWYWxpZGF0b3IKLSAgICAgICAgICAgICAgZXh0ZW5kcyBYTUxEVERWYWxpZGF0b3J7Ci0KLSAgICAvKiogQXR0cmlidXRlIFFOYW1lLiAqLwotICAgIHByaXZhdGUgUU5hbWUgZkF0dHJpYnV0ZVFOYW1lID0gbmV3IFFOYW1lKCk7Ci0KLQotICAgIC8qKiBCaW5kIG5hbWVzcGFjZXMgKi8KLSAgICBwcm90ZWN0ZWQgZmluYWwgdm9pZCBzdGFydE5hbWVzcGFjZVNjb3BlIChRTmFtZSBlbGVtZW50LCBYTUxBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy8gYWRkIG5ldyBuYW1lc3BhY2UgY29udGV4dAotICAgICAgICBmTmFtZXNwYWNlQ29udGV4dC5wdXNoQ29udGV4dCgpOwotCi0gICAgICAgIGlmIChlbGVtZW50LnByZWZpeCA9PSBYTUxTeW1ib2xzLlBSRUZJWF9YTUxOUykgewotICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxOU19ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRWxlbWVudFhNTE5TUHJlZml4IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXtlbGVtZW50LnJhd25hbWV9LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9GQVRBTF9FUlJPUik7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBzZWFyY2ggZm9yIG5ldyBuYW1lc3BhY2UgYmluZGluZ3MKLSAgICAgICAgaW50IGxlbmd0aCA9IGF0dHJpYnV0ZXMuZ2V0TGVuZ3RoKCk7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgIFN0cmluZyBsb2NhbHBhcnQgPSBhdHRyaWJ1dGVzLmdldExvY2FsTmFtZShpKTsKLSAgICAgICAgICAgIFN0cmluZyBwcmVmaXggPSBhdHRyaWJ1dGVzLmdldFByZWZpeChpKTsKLSAgICAgICAgICAgIC8vIHdoZW4gaXQncyBvZiBmb3JtIHhtbG5zPSIuLi4iIG9yIHhtbG5zOnByZWZpeD0iLi4uIiwKLSAgICAgICAgICAgIC8vIGl0J3MgYSBuYW1lc3BhY2UgZGVjbGFyYXRpb24uIGJ1dCBwcmVmaXg6eG1sbnM9Ii4uLiIgaXNuJ3QuCi0gICAgICAgICAgICBpZiAocHJlZml4ID09IFhNTFN5bWJvbHMuUFJFRklYX1hNTE5TIHx8Ci0gICAgICAgICAgICAgICAgcHJlZml4ID09IFhNTFN5bWJvbHMuRU1QVFlfU1RSSU5HICYmIGxvY2FscGFydCA9PSBYTUxTeW1ib2xzLlBSRUZJWF9YTUxOUykgewotCi0gICAgICAgICAgICAgICAgLy8gZ2V0IHRoZSBpbnRlcm5hbGl6ZWQgdmFsdWUgb2YgdGhpcyBhdHRyaWJ1dGUKLSAgICAgICAgICAgICAgICBTdHJpbmcgdXJpID0gZlN5bWJvbFRhYmxlLmFkZFN5bWJvbChhdHRyaWJ1dGVzLmdldFZhbHVlKGkpKTsKLQotICAgICAgICAgICAgICAgIC8vIDEuICJ4bWxucyIgY2FuJ3QgYmUgYm91bmQgdG8gYW55IG5hbWVzcGFjZQotICAgICAgICAgICAgICAgIGlmIChwcmVmaXggPT0gWE1MU3ltYm9scy5QUkVGSVhfWE1MTlMgJiYgbG9jYWxwYXJ0ID09IFhNTFN5bWJvbHMuUFJFRklYX1hNTE5TKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MTlNfRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ2FudEJpbmRYTUxOUyIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXthdHRyaWJ1dGVzLmdldFFOYW1lKGkpfSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9GQVRBTF9FUlJPUik7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgLy8gMi4gdGhlIG5hbWVzcGFjZSBmb3IgInhtbG5zIiBjYW4ndCBiZSBib3VuZCB0byBhbnkgcHJlZml4Ci0gICAgICAgICAgICAgICAgaWYgKHVyaSA9PSBOYW1lc3BhY2VDb250ZXh0LlhNTE5TX1VSSSkgewotICAgICAgICAgICAgICAgICAgICBmRXJyb3JSZXBvcnRlci5yZXBvcnRFcnJvcihYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTE5TX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNhbnRCaW5kWE1MTlMiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117YXR0cmlidXRlcy5nZXRRTmFtZShpKX0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTEVycm9yUmVwb3J0ZXIuU0VWRVJJVFlfRkFUQUxfRVJST1IpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8vIDMuICJ4bWwiIGNhbid0IGJlIGJvdW5kIHRvIGFueSBvdGhlciBuYW1lc3BhY2UgdGhhbiBpdCdzIG93bgotICAgICAgICAgICAgICAgIGlmIChsb2NhbHBhcnQgPT0gWE1MU3ltYm9scy5QUkVGSVhfWE1MKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmICh1cmkgIT0gTmFtZXNwYWNlQ29udGV4dC5YTUxfVVJJKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmRXJyb3JSZXBvcnRlci5yZXBvcnRFcnJvcihYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTE5TX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDYW50QmluZFhNTCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117YXR0cmlidXRlcy5nZXRRTmFtZShpKX0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxFcnJvclJlcG9ydGVyLlNFVkVSSVRZX0ZBVEFMX0VSUk9SKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvLyA0LiB0aGUgbmFtZXNwYWNlIGZvciAieG1sIiBjYW4ndCBiZSBib3VuZCB0byBhbnkgb3RoZXIgcHJlZml4Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmICh1cmkgPT1OYW1lc3BhY2VDb250ZXh0LlhNTF9VUkkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MTlNfRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNhbnRCaW5kWE1MIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXthdHRyaWJ1dGVzLmdldFFOYW1lKGkpfSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTEVycm9yUmVwb3J0ZXIuU0VWRVJJVFlfRkFUQUxfRVJST1IpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgcHJlZml4ID0gbG9jYWxwYXJ0ICE9IFhNTFN5bWJvbHMuUFJFRklYX1hNTE5TID8gbG9jYWxwYXJ0IDogWE1MU3ltYm9scy5FTVBUWV9TVFJJTkc7Ci0KLSAgICAgICAgICAgICAgICAvLyBodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk5L1JFQy14bWwtbmFtZXMtMTk5OTAxMTQvI2R0LXByZWZpeAotICAgICAgICAgICAgICAgIC8vIFdlIHNob3VsZCBvbmx5IHJlcG9ydCBhbiBlcnJvciBpZiB0aGVyZSBpcyBhIHByZWZpeCwKLSAgICAgICAgICAgICAgICAvLyB0aGF0IGlzLCB0aGUgbG9jYWwgcGFydCBpcyBub3QgInhtbG5zIi4gLVNHCi0gICAgICAgICAgICAgICAgaWYgKHVyaSA9PSBYTUxTeW1ib2xzLkVNUFRZX1NUUklORyAmJiBsb2NhbHBhcnQgIT0gWE1MU3ltYm9scy5QUkVGSVhfWE1MTlMpIHsKLSAgICAgICAgICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxOU19ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJFbXB0eVByZWZpeGVkQXR0TmFtZSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXthdHRyaWJ1dGVzLmdldFFOYW1lKGkpfSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9GQVRBTF9FUlJPUik7Ci0gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8vIGRlY2xhcmUgcHJlZml4IGluIGNvbnRleHQKLSAgICAgICAgICAgICAgICBmTmFtZXNwYWNlQ29udGV4dC5kZWNsYXJlUHJlZml4KHByZWZpeCwgdXJpLmxlbmd0aCgpICE9IDAgPyB1cmkgOiBudWxsKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIGJpbmQgdGhlIGVsZW1lbnQKLSAgICAgICAgU3RyaW5nIHByZWZpeCA9IGVsZW1lbnQucHJlZml4ICE9IG51bGwKLSAgICAgICAgICAgICAgICAgICAgICA/IGVsZW1lbnQucHJlZml4IDogWE1MU3ltYm9scy5FTVBUWV9TVFJJTkc7Ci0gICAgICAgIGVsZW1lbnQudXJpID0gZk5hbWVzcGFjZUNvbnRleHQuZ2V0VVJJKHByZWZpeCk7Ci0gICAgICAgIGlmIChlbGVtZW50LnByZWZpeCA9PSBudWxsICYmIGVsZW1lbnQudXJpICE9IG51bGwpIHsKLSAgICAgICAgICAgIGVsZW1lbnQucHJlZml4ID0gWE1MU3ltYm9scy5FTVBUWV9TVFJJTkc7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGVsZW1lbnQucHJlZml4ICE9IG51bGwgJiYgZWxlbWVudC51cmkgPT0gbnVsbCkgewotICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxOU19ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRWxlbWVudFByZWZpeFVuYm91bmQiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde2VsZW1lbnQucHJlZml4LCBlbGVtZW50LnJhd25hbWV9LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9GQVRBTF9FUlJPUik7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBiaW5kIHRoZSBhdHRyaWJ1dGVzCi0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgIGF0dHJpYnV0ZXMuZ2V0TmFtZShpLCBmQXR0cmlidXRlUU5hbWUpOwotICAgICAgICAgICAgU3RyaW5nIGFwcmVmaXggPSBmQXR0cmlidXRlUU5hbWUucHJlZml4ICE9IG51bGwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgID8gZkF0dHJpYnV0ZVFOYW1lLnByZWZpeCA6IFhNTFN5bWJvbHMuRU1QVFlfU1RSSU5HOwotICAgICAgICAgICAgU3RyaW5nIGFyYXduYW1lID0gZkF0dHJpYnV0ZVFOYW1lLnJhd25hbWU7Ci0gICAgICAgICAgICBpZiAoYXJhd25hbWUgPT0gWE1MU3ltYm9scy5QUkVGSVhfWE1MTlMpIHsKLSAgICAgICAgICAgICAgICBmQXR0cmlidXRlUU5hbWUudXJpID0gZk5hbWVzcGFjZUNvbnRleHQuZ2V0VVJJKFhNTFN5bWJvbHMuUFJFRklYX1hNTE5TKTsKLSAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzLnNldE5hbWUoaSwgZkF0dHJpYnV0ZVFOYW1lKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKGFwcmVmaXggIT0gWE1MU3ltYm9scy5FTVBUWV9TVFJJTkcpIHsKLSAgICAgICAgICAgICAgICBmQXR0cmlidXRlUU5hbWUudXJpID0gZk5hbWVzcGFjZUNvbnRleHQuZ2V0VVJJKGFwcmVmaXgpOwotICAgICAgICAgICAgICAgIGlmIChmQXR0cmlidXRlUU5hbWUudXJpID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxOU19ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBdHRyaWJ1dGVQcmVmaXhVbmJvdW5kIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde2VsZW1lbnQucmF3bmFtZSxhcmF3bmFtZSxhcHJlZml4fSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9GQVRBTF9FUlJPUik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXMuc2V0TmFtZShpLCBmQXR0cmlidXRlUU5hbWUpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gdmVyaWZ5IHRoYXQgZHVwbGljYXRlIGF0dHJpYnV0ZXMgZG9uJ3QgZXhpc3QKLSAgICAgICAgLy8gRXhhbXBsZTogPGZvbyB4bWxuczphPSdOUycgeG1sbnM6Yj0nTlMnIGE6YXR0cj0ndjEnIGI6YXR0cj0ndjInLz4KLSAgICAgICAgaW50IGF0dHJDb3VudCA9IGF0dHJpYnV0ZXMuZ2V0TGVuZ3RoKCk7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYXR0ckNvdW50IC0gMTsgaSsrKSB7Ci0gICAgICAgICAgICBTdHJpbmcgYXVyaSA9IGF0dHJpYnV0ZXMuZ2V0VVJJKGkpOwotICAgICAgICAgICAgaWYgKGF1cmkgPT0gbnVsbCB8fCBhdXJpID09IE5hbWVzcGFjZUNvbnRleHQuWE1MTlNfVVJJKSB7Ci0gICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBTdHJpbmcgYWxvY2FscGFydCA9IGF0dHJpYnV0ZXMuZ2V0TG9jYWxOYW1lKGkpOwotICAgICAgICAgICAgZm9yIChpbnQgaiA9IGkgKyAxOyBqIDwgYXR0ckNvdW50OyBqKyspIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgYmxvY2FscGFydCA9IGF0dHJpYnV0ZXMuZ2V0TG9jYWxOYW1lKGopOwotICAgICAgICAgICAgICAgIFN0cmluZyBidXJpID0gYXR0cmlidXRlcy5nZXRVUkkoaik7Ci0gICAgICAgICAgICAgICAgaWYgKGFsb2NhbHBhcnQgPT0gYmxvY2FscGFydCAmJiBhdXJpID09IGJ1cmkpIHsKLSAgICAgICAgICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxOU19ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBdHRyaWJ1dGVOU05vdFVuaXF1ZSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXtlbGVtZW50LnJhd25hbWUsYWxvY2FscGFydCwgYXVyaX0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTEVycm9yUmVwb3J0ZXIuU0VWRVJJVFlfRkFUQUxfRVJST1IpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0KLSAgICB9IC8vIHN0YXJ0TmFtZXNwYWNlU2NvcGUoUU5hbWUsWE1MQXR0cmlidXRlcykKLQotCi0gICAgLyoqIEhhbmRsZXMgZW5kIGVsZW1lbnQuICovCi0gICAgcHJvdGVjdGVkIHZvaWQgZW5kTmFtZXNwYWNlU2NvcGUoUU5hbWUgZWxlbWVudCwgQXVnbWVudGF0aW9ucyBhdWdzLCBib29sZWFuIGlzRW1wdHkpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotCi0gICAgICAgIC8vIGJpbmQgZWxlbWVudAotICAgICAgICBTdHJpbmcgZXByZWZpeCA9IGVsZW1lbnQucHJlZml4ICE9IG51bGwgPyBlbGVtZW50LnByZWZpeCA6IFhNTFN5bWJvbHMuRU1QVFlfU1RSSU5HOwotICAgICAgICBlbGVtZW50LnVyaSA9IGZOYW1lc3BhY2VDb250ZXh0LmdldFVSSShlcHJlZml4KTsKLSAgICAgICAgaWYgKGVsZW1lbnQudXJpICE9IG51bGwpIHsKLSAgICAgICAgICAgIGVsZW1lbnQucHJlZml4ID0gZXByZWZpeDsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIGNhbGwgaGFuZGxlcnMKLSAgICAgICAgaWYgKGZEb2N1bWVudEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKCFpc0VtcHR5KSB7Ci0gICAgICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci5lbmRFbGVtZW50KGVsZW1lbnQsIGF1Z3MpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gcG9wIGNvbnRleHQKLSAgICAgICAgZk5hbWVzcGFjZUNvbnRleHQucG9wQ29udGV4dCgpOwotCi0gICAgfSAvLyBlbmROYW1lc3BhY2VTY29wZShRTmFtZSxib29sZWFuKQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R0ZC9YTUxOb3RhdGlvbkRlY2wuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHRkL1hNTE5vdGF0aW9uRGVjbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3NTQxODc1Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHRkL1hNTE5vdGF0aW9uRGVjbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTEyICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTktMjAwMiBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhlcmNlcyIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgSW50ZXJuYXRpb25hbAotICogQnVzaW5lc3MgTWFjaGluZXMsIEluYy4sIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdGQ7Ci0KLS8qKgotICovCi1wdWJsaWMgY2xhc3MgWE1MTm90YXRpb25EZWNsIHsKLQotICAgIC8vCi0gICAgLy8gRGF0YQotICAgIC8vCi0KLSAgICAvKiogbmFtZSAqLwotICAgIHB1YmxpYyBTdHJpbmcgbmFtZTsKLQotICAgIC8qKiBwdWJsaWNJZCAqLwotICAgIHB1YmxpYyBTdHJpbmcgcHVibGljSWQ7Ci0KLSAgICAvKiogc3lzdGVtSWQgKi8KLSAgICBwdWJsaWMgU3RyaW5nIHN5c3RlbUlkOwotCi0gICAgLyoqIGJhc2Ugc3lzdGVtSWQgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGJhc2VTeXN0ZW1JZDsKLQotICAgIC8vCi0gICAgLy8gTWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBzZXRWYWx1ZXMKLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lCi0gICAgICogQHBhcmFtIHB1YmxpY0lkCi0gICAgICogQHBhcmFtIHN5c3RlbUlkCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0VmFsdWVzKFN0cmluZyBuYW1lLCBTdHJpbmcgcHVibGljSWQsIFN0cmluZyBzeXN0ZW1JZCwgU3RyaW5nIGJhc2VTeXN0ZW1JZCkgewotICAgICAgICB0aGlzLm5hbWUgICAgID0gICBuYW1lOwotICAgICAgICB0aGlzLnB1YmxpY0lkID0gcHVibGljSWQ7Ci0gICAgICAgIHRoaXMuc3lzdGVtSWQgPSBzeXN0ZW1JZDsKLSAgICAgICAgdGhpcy5iYXNlU3lzdGVtSWQgPSBiYXNlU3lzdGVtSWQ7Ci0gICAgfSAvLyBzZXRWYWx1ZXMKLQotICAgIC8qKgotICAgICAqIGNsZWFyCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY2xlYXIoKSB7Ci0gICAgICAgIHRoaXMubmFtZSAgICAgPSBudWxsOwotICAgICAgICB0aGlzLnB1YmxpY0lkID0gbnVsbDsKLSAgICAgICAgdGhpcy5zeXN0ZW1JZCA9IG51bGw7Ci0gICAgICAgIHRoaXMuYmFzZVN5c3RlbUlkID0gbnVsbDsKLSAgICB9IC8vIGNsZWFyCi0KLX0gLy8gY2xhc3MgWE1MTm90YXRpb25EZWNsCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R0ZC9YTUxTaW1wbGVUeXBlLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R0ZC9YTUxTaW1wbGVUeXBlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGM3NTdlMzkuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdGQvWE1MU2ltcGxlVHlwZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjEyICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTktMjAwMiBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhlcmNlcyIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgSW50ZXJuYXRpb25hbAotICogQnVzaW5lc3MgTWFjaGluZXMsIEluYy4sIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdGQ7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYuRGF0YXR5cGVWYWxpZGF0b3I7Ci0KLS8qKgotICovCi1wdWJsaWMgY2xhc3MgWE1MU2ltcGxlVHlwZSB7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0YW50cwotICAgIC8vCi0KLSAgICAvKiogVFlQRV9DREFUQSAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgVFlQRV9DREFUQSA9IDA7Ci0KLSAgICAvKiogVFlQRV9FTlRJVFkgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFRZUEVfRU5USVRZID0gMTsKLQotICAgIC8qKiBUWVBFX0VOVU1FUkFUSU9OICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBUWVBFX0VOVU1FUkFUSU9OID0gMjsKLQotICAgIC8qKiBUWVBFX0lEICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBUWVBFX0lEID0gMzsKLQotICAgIC8qKiBUWVBFX0lEUkVGICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBUWVBFX0lEUkVGID0gNDsKLQotICAgIC8qKiBUWVBFX05NVE9LRU4gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFRZUEVfTk1UT0tFTiA9IDU7Ci0KLSAgICAvKiogVFlQRV9OT1RBVElPTiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgVFlQRV9OT1RBVElPTiA9IDY7Ci0KLSAgICAvKiogVFlQRV9OQU1FRCAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgVFlQRV9OQU1FRCA9IDc7Ci0KLSAgICAvKiogREVGQVVMVF9UWVBFX0RFRkFVTFQgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IERFRkFVTFRfVFlQRV9ERUZBVUxUID0gMzsKLQotICAgIC8qKiBERUZBVUxUX1RZUEVfRklYRUQgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IERFRkFVTFRfVFlQRV9GSVhFRCA9IDE7Ci0KLSAgICAvKiogREVGQVVMVF9UWVBFX0lNUExJRUQgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IERFRkFVTFRfVFlQRV9JTVBMSUVEID0gMDsKLQotICAgIC8qKiBERUZBVUxUX1RZUEVfUkVRVUlSRUQgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IERFRkFVTFRfVFlQRV9SRVFVSVJFRCA9IDI7Ci0KLSAgICAvLwotICAgIC8vIERhdGEKLSAgICAvLwotCi0gICAgLyoqIHR5cGUgKi8KLSAgICBwdWJsaWMgc2hvcnQgdHlwZTsKLQotICAgIC8qKiBuYW1lICovCi0gICAgcHVibGljIFN0cmluZyBuYW1lOwotCi0gICAgLyoqIGVudW1lcmF0aW9uICovCi0gICAgcHVibGljIFN0cmluZ1tdIGVudW1lcmF0aW9uOwotCi0gICAgLyoqIGxpc3QgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBsaXN0OwotCi0gICAgLyoqIGRlZmF1bHRUeXBlICovCi0gICAgcHVibGljIHNob3J0IGRlZmF1bHRUeXBlOwotCi0gICAgLyoqIGRlZmF1bHRWYWx1ZSAqLwotICAgIHB1YmxpYyBTdHJpbmcgZGVmYXVsdFZhbHVlOwotCi0gICAgLyoqIG5vbi1ub3JtYWxpemVkIGRlZmF1bHRWYWx1ZSAqLwotICAgIHB1YmxpYyBTdHJpbmcgbm9uTm9ybWFsaXplZERlZmF1bHRWYWx1ZTsKLQotICAgIC8qKiBkYXRhdHlwZVZhbGlkYXRvciAqLwotICAgIHB1YmxpYyBEYXRhdHlwZVZhbGlkYXRvciBkYXRhdHlwZVZhbGlkYXRvcjsKLQotICAgIC8vCi0gICAgLy8gTWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBzZXRWYWx1ZXMKLSAgICAgKgotICAgICAqIEBwYXJhbSB0eXBlCi0gICAgICogQHBhcmFtIG5hbWUKLSAgICAgKiBAcGFyYW0gZW51bWVyYXRpb24KLSAgICAgKiBAcGFyYW0gbGlzdAotICAgICAqIEBwYXJhbSBkZWZhdWx0VHlwZQotICAgICAqIEBwYXJhbSBkZWZhdWx0VmFsdWUKLSAgICAgKiBAcGFyYW0gbm9uTm9ybWFsaXplZERlZmF1bHRWYWx1ZQotICAgICAqIEBwYXJhbSBkYXRhdHlwZVZhbGlkYXRvcgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFZhbHVlcyhzaG9ydCB0eXBlLCBTdHJpbmcgbmFtZSwgU3RyaW5nW10gZW51bWVyYXRpb24sCi0gICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gbGlzdCwgc2hvcnQgZGVmYXVsdFR5cGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBkZWZhdWx0VmFsdWUsIFN0cmluZyBub25Ob3JtYWxpemVkRGVmYXVsdFZhbHVlLAotICAgICAgICAgICAgICAgICAgICAgICAgICBEYXRhdHlwZVZhbGlkYXRvciBkYXRhdHlwZVZhbGlkYXRvcikgewotCi0gICAgICAgIHRoaXMudHlwZSAgICAgICAgICAgICAgPSB0eXBlOwotICAgICAgICB0aGlzLm5hbWUgICAgICAgICAgICAgID0gbmFtZTsKLSAgICAgICAgLy8gUkVWSVNJVDogU2hvdWxkIHRoaXMgYmUgYSBjb3B5PyAtQWMKLSAgICAgICAgaWYgKGVudW1lcmF0aW9uICE9IG51bGwgJiYgZW51bWVyYXRpb24ubGVuZ3RoID4gMCkgewotICAgICAgICAgICAgdGhpcy5lbnVtZXJhdGlvbiA9IG5ldyBTdHJpbmdbZW51bWVyYXRpb24ubGVuZ3RoXTsKLSAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZW51bWVyYXRpb24sIDAsIHRoaXMuZW51bWVyYXRpb24sIDAsIHRoaXMuZW51bWVyYXRpb24ubGVuZ3RoKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHRoaXMuZW51bWVyYXRpb24gPSBudWxsOwotICAgICAgICB9Ci0gICAgICAgIHRoaXMubGlzdCAgICAgICAgICAgICAgPSBsaXN0OwotICAgICAgICB0aGlzLmRlZmF1bHRUeXBlICAgICAgID0gZGVmYXVsdFR5cGU7Ci0gICAgICAgIHRoaXMuZGVmYXVsdFZhbHVlICAgICAgPSBkZWZhdWx0VmFsdWU7Ci0gICAgICAgIHRoaXMubm9uTm9ybWFsaXplZERlZmF1bHRWYWx1ZSAgICAgID0gbm9uTm9ybWFsaXplZERlZmF1bHRWYWx1ZTsKLSAgICAgICAgdGhpcy5kYXRhdHlwZVZhbGlkYXRvciA9IGRhdGF0eXBlVmFsaWRhdG9yOwotCi0gICAgfSAvLyBzZXRWYWx1ZXMoc2hvcnQsU3RyaW5nLFN0cmluZ1tdLGJvb2xlYW4sc2hvcnQsU3RyaW5nLFN0cmluZyxEYXRhdHlwZVZhbGlkYXRvcikKLQotICAgIC8qKiBTZXQgdmFsdWVzLiAqLwotICAgIHB1YmxpYyB2b2lkIHNldFZhbHVlcyhYTUxTaW1wbGVUeXBlIHNpbXBsZVR5cGUpIHsKLQotICAgICAgICB0eXBlID0gc2ltcGxlVHlwZS50eXBlOwotICAgICAgICBuYW1lID0gc2ltcGxlVHlwZS5uYW1lOwotICAgICAgICAvLyBSRVZJU0lUOiBTaG91bGQgdGhpcyBiZSBhIGNvcHk/IC1BYwotICAgICAgICBpZiAoc2ltcGxlVHlwZS5lbnVtZXJhdGlvbiAhPSBudWxsICYmIHNpbXBsZVR5cGUuZW51bWVyYXRpb24ubGVuZ3RoID4gMCkgewotICAgICAgICAgICAgZW51bWVyYXRpb24gPSBuZXcgU3RyaW5nW3NpbXBsZVR5cGUuZW51bWVyYXRpb24ubGVuZ3RoXTsKLSAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoc2ltcGxlVHlwZS5lbnVtZXJhdGlvbiwgMCwgZW51bWVyYXRpb24sIDAsIGVudW1lcmF0aW9uLmxlbmd0aCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBlbnVtZXJhdGlvbiA9IG51bGw7Ci0gICAgICAgIH0KLSAgICAgICAgbGlzdCA9IHNpbXBsZVR5cGUubGlzdDsKLSAgICAgICAgZGVmYXVsdFR5cGUgPSBzaW1wbGVUeXBlLmRlZmF1bHRUeXBlOwotICAgICAgICBkZWZhdWx0VmFsdWUgPSBzaW1wbGVUeXBlLmRlZmF1bHRWYWx1ZTsKLSAgICAgICAgbm9uTm9ybWFsaXplZERlZmF1bHRWYWx1ZSA9IHNpbXBsZVR5cGUubm9uTm9ybWFsaXplZERlZmF1bHRWYWx1ZTsKLSAgICAgICAgZGF0YXR5cGVWYWxpZGF0b3IgPSBzaW1wbGVUeXBlLmRhdGF0eXBlVmFsaWRhdG9yOwotCi0gICAgfSAvLyBzZXRWYWx1ZXMoWE1MU2ltcGxlVHlwZSkKLQotICAgIC8qKgotICAgICAqIGNsZWFyCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY2xlYXIoKSB7Ci0gICAgICAgIHRoaXMudHlwZSAgICAgICAgICAgICAgPSAtMTsKLSAgICAgICAgdGhpcy5uYW1lICAgICAgICAgICAgICA9IG51bGw7Ci0gICAgICAgIHRoaXMuZW51bWVyYXRpb24gICAgICAgPSBudWxsOwotICAgICAgICB0aGlzLmxpc3QgICAgICAgICAgICAgID0gZmFsc2U7Ci0gICAgICAgIHRoaXMuZGVmYXVsdFR5cGUgICAgICAgPSAtMTsKLSAgICAgICAgdGhpcy5kZWZhdWx0VmFsdWUgICAgICA9IG51bGw7Ci0gICAgICAgIHRoaXMubm9uTm9ybWFsaXplZERlZmF1bHRWYWx1ZSAgICAgID0gbnVsbDsKLSAgICAgICAgdGhpcy5kYXRhdHlwZVZhbGlkYXRvciA9IG51bGw7Ci0gICAgfSAvLyBjbGVhcgotCi19IC8vIGNsYXNzIFhNTFNpbXBsZVR5cGUKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHRkL21vZGVscy9DTUFueS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdGQvbW9kZWxzL0NNQW55LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDVjNDdkMmUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdGQvbW9kZWxzL0NNQW55LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxOTIgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMC0yMDAyIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGVyY2VzIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBJbnRlcm5hdGlvbmFsCi0gKiBCdXNpbmVzcyBNYWNoaW5lcywgSW5jLiwgaHR0cDovL3d3dy5hcGFjaGUub3JnLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR0ZC5tb2RlbHM7Ci0KLQotLyoqCi0gKiBDb250ZW50IG1vZGVsIGFueSBub2RlLgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKi8KLXB1YmxpYyBjbGFzcyBDTUFueQotICAgIGV4dGVuZHMgQ01Ob2RlIHsKLQotICAgIC8vCi0gICAgLy8gRGF0YQotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBUaGUgYW55IGNvbnRlbnQgbW9kZWwgdHlwZS4gVGhpcyB2YWx1ZSBpcyBvbmUgb2YgdGhlIGZvbGxvd2luZzoKLSAgICAgKiBYTUxDb250ZW50U3BlYy5DT05URU5UU1BFQ05PREVfQU5ZLAotICAgICAqIFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9BTllfT1RIRVIsCi0gICAgICogWE1MQ29udGVudFNwZWMuQ09OVEVOVFNQRUNOT0RFX0FOWV9MT0NBTC4KLSAgICAgKi8KLSAgICBwcml2YXRlIGludCBmVHlwZTsKLQotICAgIC8qKgotICAgICAqIFVSSSBvZiB0aGUgYW55IGNvbnRlbnQgbW9kZWwuIFRoaXMgdmFsdWUgaXMgc2V0IGlmIHRoZSB0eXBlIGlzCi0gICAgICogb2YgdGhlIGZvbGxvd2luZzoKLSAgICAgKiBYTUxDb250ZW50U3BlYy5DT05URU5UU1BFQ05PREVfQU5ZLAotICAgICAqIFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9BTllfT1RIRVIuCi0gICAgICovCi0gICAgcHJpdmF0ZSBTdHJpbmcgZlVSSTsKLQotICAgIC8qKgotICAgICAqIFBhcnQgb2YgdGhlIGFsZ29yaXRobSB0byBjb252ZXJ0IGEgcmVnZXggZGlyZWN0bHkgdG8gYSBERkEKLSAgICAgKiBudW1iZXJzIGVhY2ggbGVhZiBzZXF1ZW50aWFsbHkuIElmIGl0cyAtMSwgdGhhdCBtZWFucyBpdHMgYW4KLSAgICAgKiBlcHNpbG9uIG5vZGUuIFplcm8gYW5kIGdyZWF0ZXIgYXJlIG5vbi1lcHNpbG9uIHBvc2l0aW9ucy4KLSAgICAgKi8KLSAgICBwcml2YXRlIGludCBmUG9zaXRpb24gPSAtMTsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKiBDb25zdHJ1Y3RzIGEgY29udGVudCBtb2RlbCBhbnkuICovCi0gICAgcHVibGljIENNQW55KGludCB0eXBlLCBTdHJpbmcgdXJpLCBpbnQgcG9zaXRpb24pICB7Ci0gICAgICAgIHN1cGVyKHR5cGUpOwotCi0gICAgICAgIC8vIFN0b3JlIHRoZSBpbmZvcm1hdGlvbgotICAgICAgICBmVHlwZSA9IHR5cGU7Ci0gICAgICAgIGZVUkkgPSB1cmk7Ci0gICAgICAgIGZQb3NpdGlvbiA9IHBvc2l0aW9uOwotICAgIH0KLQotICAgIC8vCi0gICAgLy8gUGFja2FnZSBtZXRob2RzCi0gICAgLy8KLQotICAgIGZpbmFsIGludCBnZXRUeXBlKCkgewotICAgICAgICByZXR1cm4gZlR5cGU7Ci0gICAgfQotCi0gICAgZmluYWwgU3RyaW5nIGdldFVSSSgpIHsKLSAgICAgICAgcmV0dXJuIGZVUkk7Ci0gICAgfQotCi0gICAgZmluYWwgaW50IGdldFBvc2l0aW9uKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBmUG9zaXRpb247Ci0gICAgfQotCi0gICAgZmluYWwgdm9pZCBzZXRQb3NpdGlvbihpbnQgbmV3UG9zaXRpb24pCi0gICAgewotICAgICAgICBmUG9zaXRpb24gPSBuZXdQb3NpdGlvbjsKLSAgICB9Ci0KLSAgICAvLwotICAgIC8vIENNTm9kZSBtZXRob2RzCi0gICAgLy8KLQotICAgIC8vIHBhY2thZ2UKLQotICAgIHB1YmxpYyBib29sZWFuIGlzTnVsbGFibGUoKQotICAgIHsKLSAgICAgICAgLy8gTGVhZiBub2RlcyBhcmUgbmV2ZXIgbnVsbGFibGUgdW5sZXNzIGl0cyBhbiBlcHNpbG9uIG5vZGUKLSAgICAgICAgcmV0dXJuIChmUG9zaXRpb24gPT0gLTEpOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKQotICAgIHsKLSAgICAgICAgU3RyaW5nQnVmZmVyIHN0clJldCA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLSAgICAgICAgc3RyUmV0LmFwcGVuZCgiKCIpOwotICAgICAgICBzdHJSZXQuYXBwZW5kKCIjI2FueTp1cmk9Iik7Ci0gICAgICAgIHN0clJldC5hcHBlbmQoZlVSSSk7Ci0gICAgICAgIHN0clJldC5hcHBlbmQoJyknKTsKLSAgICAgICAgaWYgKGZQb3NpdGlvbiA+PSAwKQotICAgICAgICB7Ci0gICAgICAgICAgICBzdHJSZXQuYXBwZW5kCi0gICAgICAgICAgICAoCi0gICAgICAgICAgICAgICAgIiAoUG9zOiIKLSAgICAgICAgICAgICAgICArIG5ldyBJbnRlZ2VyKGZQb3NpdGlvbikudG9TdHJpbmcoKQotICAgICAgICAgICAgICAgICsgIikiCi0gICAgICAgICAgICApOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBzdHJSZXQudG9TdHJpbmcoKTsKLSAgICB9Ci0KLSAgICAvLyBwcm90ZWN0ZWQKLQotICAgIHByb3RlY3RlZCB2b2lkIGNhbGNGaXJzdFBvcyhDTVN0YXRlU2V0IHRvU2V0KQotICAgIHsKLSAgICAgICAgLy8gSWYgd2UgYXJlIGFuIGVwc2lsb24gbm9kZSwgdGhlbiB0aGUgZmlyc3QgcG9zIGlzIGFuIGVtcHR5IHNldAotICAgICAgICBpZiAoZlBvc2l0aW9uID09IC0xKQotICAgICAgICAgICAgdG9TZXQuemVyb0JpdHMoKTsKLQotICAgICAgICAvLyBPdGhlcndpc2UsIGl0cyBqdXN0IHRoZSBvbmUgYml0IG9mIG91ciBwb3NpdGlvbgotICAgICAgICBlbHNlCi0gICAgICAgICAgICB0b1NldC5zZXRCaXQoZlBvc2l0aW9uKTsKLSAgICB9Ci0KLSAgICBwcm90ZWN0ZWQgdm9pZCBjYWxjTGFzdFBvcyhDTVN0YXRlU2V0IHRvU2V0KQotICAgIHsKLSAgICAgICAgLy8gSWYgd2UgYXJlIGFuIGVwc2lsb24gbm9kZSwgdGhlbiB0aGUgbGFzdCBwb3MgaXMgYW4gZW1wdHkgc2V0Ci0gICAgICAgIGlmIChmUG9zaXRpb24gPT0gLTEpCi0gICAgICAgICAgICB0b1NldC56ZXJvQml0cygpOwotCi0gICAgICAgIC8vIE90aGVyd2lzZSwgaXRzIGp1c3QgdGhlIG9uZSBiaXQgb2Ygb3VyIHBvc2l0aW9uCi0gICAgICAgIGVsc2UKLSAgICAgICAgICAgIHRvU2V0LnNldEJpdChmUG9zaXRpb24pOwotICAgIH0KLQotfSAvLyBjbGFzcyBDTUFueQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdGQvbW9kZWxzL0NNQmluT3AuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHRkL21vZGVscy9DTUJpbk9wLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDUxZGY4OGQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdGQvbW9kZWxzL0NNQmluT3AuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE5MSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5LTIwMDIgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYZXJjZXMiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIEludGVybmF0aW9uYWwKLSAqIEJ1c2luZXNzIE1hY2hpbmVzLCBJbmMuLCBodHRwOi8vd3d3LmFwYWNoZS5vcmcuICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHRkLm1vZGVsczsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdGQuWE1MQ29udGVudFNwZWM7Ci0KLS8qKgotICogQ29udGVudCBtb2RlbCBCaW4tT3Agbm9kZS4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICovCi1wdWJsaWMgY2xhc3MgQ01CaW5PcCBleHRlbmRzIENNTm9kZQotewotICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICAvLyAgQ29uc3RydWN0b3JzCi0gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgIHB1YmxpYyBDTUJpbk9wKGludCB0eXBlLCBDTU5vZGUgbGVmdE5vZGUsIENNTm9kZSByaWdodE5vZGUpCi0gICAgewotICAgICAgICBzdXBlcih0eXBlKTsKLQotICAgICAgICAvLyBJbnN1cmUgdGhhdCBpdHMgb25lIG9mIHRoZSB0eXBlcyB3ZSByZXF1aXJlCi0gICAgICAgIGlmICgodHlwZSgpICE9IFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9DSE9JQ0UpCi0gICAgICAgICYmICAodHlwZSgpICE9IFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9TRVEpKQotICAgICAgICB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiSW1wbGVtZW50YXRpb25NZXNzYWdlcy5WQUxfQlNUIik7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBTdG9yZSB0aGUgbm9kZXMgYW5kIGluaXQgYW55IGRhdGEgdGhhdCBuZWVkcyBpdAotICAgICAgICBmTGVmdENoaWxkID0gbGVmdE5vZGU7Ci0gICAgICAgIGZSaWdodENoaWxkID0gcmlnaHROb2RlOwotICAgIH0KLQotCi0gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgIC8vICBQYWNrYWdlLCBmaW5hbCBtZXRob2RzCi0gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgIGZpbmFsIENNTm9kZSBnZXRMZWZ0KCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBmTGVmdENoaWxkOwotICAgIH0KLQotICAgIGZpbmFsIENNTm9kZSBnZXRSaWdodCgpCi0gICAgewotICAgICAgICByZXR1cm4gZlJpZ2h0Q2hpbGQ7Ci0gICAgfQotCi0KLSAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgLy8gIFBhY2thZ2UsIGluaGVyaXRlZCBtZXRob2RzCi0gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgIHB1YmxpYyBib29sZWFuIGlzTnVsbGFibGUoKQotICAgIHsKLSAgICAgICAgLy8KLSAgICAgICAgLy8gIElmIGl0cyBhbiBhbHRlcm5hdGlvbiwgdGhlbiBpZiBlaXRoZXIgY2hpbGQgaXMgbnVsbGFibGUgdGhlbgotICAgICAgICAvLyAgdGhpcyBub2RlIGlzIG51bGxhYmxlLiBJZiBpdHMgYSBjb25jYXRlbmF0aW9uLCB0aGVuIGJvdGggb2YKLSAgICAgICAgLy8gIHRoZW0gaGF2ZSB0byBiZSBudWxsYWJsZS4KLSAgICAgICAgLy8KLSAgICAgICAgaWYgKHR5cGUoKSA9PSBYTUxDb250ZW50U3BlYy5DT05URU5UU1BFQ05PREVfQ0hPSUNFKQotICAgICAgICAgICAgcmV0dXJuIChmTGVmdENoaWxkLmlzTnVsbGFibGUoKSB8fCBmUmlnaHRDaGlsZC5pc051bGxhYmxlKCkpOwotICAgICAgICBlbHNlIGlmICh0eXBlKCkgPT0gWE1MQ29udGVudFNwZWMuQ09OVEVOVFNQRUNOT0RFX1NFUSkKLSAgICAgICAgICAgIHJldHVybiAoZkxlZnRDaGlsZC5pc051bGxhYmxlKCkgJiYgZlJpZ2h0Q2hpbGQuaXNOdWxsYWJsZSgpKTsKLSAgICAgICAgZWxzZQotICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIkltcGxlbWVudGF0aW9uTWVzc2FnZXMuVkFMX0JTVCIpOwotICAgIH0KLQotCi0gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgIC8vICBQcm90ZWN0ZWQsIGluaGVyaXRlZCBtZXRob2RzCi0gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgIHByb3RlY3RlZCB2b2lkIGNhbGNGaXJzdFBvcyhDTVN0YXRlU2V0IHRvU2V0KQotICAgIHsKLSAgICAgICAgaWYgKHR5cGUoKSA9PSBYTUxDb250ZW50U3BlYy5DT05URU5UU1BFQ05PREVfQ0hPSUNFKQotICAgICAgICB7Ci0gICAgICAgICAgICAvLyBJdHMgdGhlIHRoZSB1bmlvbiBvZiB0aGUgZmlyc3QgcG9zaXRpb25zIG9mIG91ciBjaGlsZHJlbi4KLSAgICAgICAgICAgIHRvU2V0LnNldFRvKGZMZWZ0Q2hpbGQuZmlyc3RQb3MoKSk7Ci0gICAgICAgICAgICB0b1NldC51bmlvbihmUmlnaHRDaGlsZC5maXJzdFBvcygpKTsKLSAgICAgICAgfQotICAgICAgICAgZWxzZSBpZiAodHlwZSgpID09IFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9TRVEpCi0gICAgICAgIHsKLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAvLyAgSWYgb3VyIGxlZnQgY2hpbGQgaXMgbnVsbGFibGUsIHRoZW4gaXRzIHRoZSB1bmlvbiBvZiBvdXIKLSAgICAgICAgICAgIC8vICBjaGlsZHJlbidzIGZpcnN0IHBvc2l0aW9ucy4gRWxzZSBpcyBvdXIgbGVmdCBjaGlsZCdzIGZpcnN0Ci0gICAgICAgICAgICAvLyAgcG9zaXRpb25zLgotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIHRvU2V0LnNldFRvKGZMZWZ0Q2hpbGQuZmlyc3RQb3MoKSk7Ci0gICAgICAgICAgICBpZiAoZkxlZnRDaGlsZC5pc051bGxhYmxlKCkpCi0gICAgICAgICAgICAgICAgdG9TZXQudW5pb24oZlJpZ2h0Q2hpbGQuZmlyc3RQb3MoKSk7Ci0gICAgICAgIH0KLSAgICAgICAgIGVsc2UKLSAgICAgICAgewotICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIkltcGxlbWVudGF0aW9uTWVzc2FnZXMuVkFMX0JTVCIpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHJvdGVjdGVkIHZvaWQgY2FsY0xhc3RQb3MoQ01TdGF0ZVNldCB0b1NldCkKLSAgICB7Ci0gICAgICAgIGlmICh0eXBlKCkgPT0gWE1MQ29udGVudFNwZWMuQ09OVEVOVFNQRUNOT0RFX0NIT0lDRSkKLSAgICAgICAgewotICAgICAgICAgICAgLy8gSXRzIHRoZSB0aGUgdW5pb24gb2YgdGhlIGZpcnN0IHBvc2l0aW9ucyBvZiBvdXIgY2hpbGRyZW4uCi0gICAgICAgICAgICB0b1NldC5zZXRUbyhmTGVmdENoaWxkLmxhc3RQb3MoKSk7Ci0gICAgICAgICAgICB0b1NldC51bmlvbihmUmlnaHRDaGlsZC5sYXN0UG9zKCkpOwotICAgICAgICB9Ci0gICAgICAgICBlbHNlIGlmICh0eXBlKCkgPT0gWE1MQ29udGVudFNwZWMuQ09OVEVOVFNQRUNOT0RFX1NFUSkKLSAgICAgICAgewotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIC8vICBJZiBvdXIgcmlnaHQgY2hpbGQgaXMgbnVsbGFibGUsIHRoZW4gaXRzIHRoZSB1bmlvbiBvZiBvdXIKLSAgICAgICAgICAgIC8vICBjaGlsZHJlbidzIGxhc3QgcG9zaXRpb25zLiBFbHNlIGlzIG91ciByaWdodCBjaGlsZCdzIGxhc3QKLSAgICAgICAgICAgIC8vICBwb3NpdGlvbnMuCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgdG9TZXQuc2V0VG8oZlJpZ2h0Q2hpbGQubGFzdFBvcygpKTsKLSAgICAgICAgICAgIGlmIChmUmlnaHRDaGlsZC5pc051bGxhYmxlKCkpCi0gICAgICAgICAgICAgICAgdG9TZXQudW5pb24oZkxlZnRDaGlsZC5sYXN0UG9zKCkpOwotICAgICAgICB9Ci0gICAgICAgICBlbHNlCi0gICAgICAgIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJJbXBsZW1lbnRhdGlvbk1lc3NhZ2VzLlZBTF9CU1QiKTsKLSAgICAgICAgfQotICAgIH0KLQotCi0gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgIC8vICBQcml2YXRlIGRhdGEgbWVtYmVycwotICAgIC8vCi0gICAgLy8gIGZMZWZ0Q2hpbGQKLSAgICAvLyAgZlJpZ2h0Q2hpbGQKLSAgICAvLyAgICAgIFRoZXNlIGFyZSB0aGUgcmVmZXJlbmNlcyB0byB0aGUgdHdvIG5vZGVzIHRoYXQgYXJlIG9uIGVpdGhlcgotICAgIC8vICAgICAgc2lkZSBvZiB0aGlzIGJpbmFyeSBvcGVyYXRpb24uCi0gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgIHByaXZhdGUgQ01Ob2RlICBmTGVmdENoaWxkOwotICAgIHByaXZhdGUgQ01Ob2RlICBmUmlnaHRDaGlsZDsKLX07CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R0ZC9tb2RlbHMvQ01MZWFmLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R0ZC9tb2RlbHMvQ01MZWFmLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDBjYzVkZmIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdGQvbW9kZWxzL0NNTGVhZi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTg2ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTktMjAwMiBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhlcmNlcyIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgSW50ZXJuYXRpb25hbAotICogQnVzaW5lc3MgTWFjaGluZXMsIEluYy4sIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdGQubW9kZWxzOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR0ZC5YTUxDb250ZW50U3BlYzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5RTmFtZTsKLQotLyoqCi0gKiBDb250ZW50IG1vZGVsIGxlYWYgbm9kZS4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICovCi1wdWJsaWMgY2xhc3MgQ01MZWFmCi0gICAgZXh0ZW5kcyBDTU5vZGUgewotCi0gICAgLy8KLSAgICAvLyBEYXRhCi0gICAgLy8KLQotICAgIC8qKiBUaGlzIGlzIHRoZSBlbGVtZW50IHRoYXQgdGhpcyBsZWFmIHJlcHJlc2VudHMuICovCi0gICAgcHJpdmF0ZSBRTmFtZSBmRWxlbWVudCA9IG5ldyBRTmFtZSgpOwotCi0gICAgLyoqCi0gICAgICogUGFydCBvZiB0aGUgYWxnb3JpdGhtIHRvIGNvbnZlcnQgYSByZWdleCBkaXJlY3RseSB0byBhIERGQQotICAgICAqIG51bWJlcnMgZWFjaCBsZWFmIHNlcXVlbnRpYWxseS4gSWYgaXRzIC0xLCB0aGF0IG1lYW5zIGl0cyBhbgotICAgICAqIGVwc2lsb24gbm9kZS4gWmVybyBhbmQgZ3JlYXRlciBhcmUgbm9uLWVwc2lsb24gcG9zaXRpb25zLgotICAgICAqLwotICAgIHByaXZhdGUgaW50IGZQb3NpdGlvbiA9IC0xOwotCi0gICAgLy8KLSAgICAvLyBDb25zdHJ1Y3RvcnMKLSAgICAvLwotCi0gICAgLyoqIENvbnN0cnVjdHMgYSBjb250ZW50IG1vZGVsIGxlYWYuICovCi0gICAgcHVibGljIENNTGVhZihRTmFtZSBlbGVtZW50LCBpbnQgcG9zaXRpb24pICB7Ci0gICAgICAgIHN1cGVyKFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9MRUFGKTsKLQotICAgICAgICAvLyBTdG9yZSB0aGUgZWxlbWVudCBpbmRleCBhbmQgcG9zaXRpb24KLSAgICAgICAgZkVsZW1lbnQuc2V0VmFsdWVzKGVsZW1lbnQpOwotICAgICAgICBmUG9zaXRpb24gPSBwb3NpdGlvbjsKLSAgICB9Ci0KLSAgICAvKiogQ29uc3RydWN0cyBhIGNvbnRlbnQgbW9kZWwgbGVhZi4gKi8KLSAgICBwdWJsaWMgQ01MZWFmKFFOYW1lIGVsZW1lbnQpICB7Ci0gICAgICAgIHN1cGVyKFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9MRUFGKTsKLQotICAgICAgICAvLyBTdG9yZSB0aGUgZWxlbWVudCBpbmRleCBhbmQgcG9zaXRpb24KLSAgICAgICAgZkVsZW1lbnQuc2V0VmFsdWVzKGVsZW1lbnQpOwotICAgIH0KLQotICAgIC8vCi0gICAgLy8gUGFja2FnZSBtZXRob2RzCi0gICAgLy8KLQotICAgIGZpbmFsIFFOYW1lIGdldEVsZW1lbnQoKQotICAgIHsKLSAgICAgICAgcmV0dXJuIGZFbGVtZW50OwotICAgIH0KLQotICAgIGZpbmFsIGludCBnZXRQb3NpdGlvbigpCi0gICAgewotICAgICAgICByZXR1cm4gZlBvc2l0aW9uOwotICAgIH0KLQotICAgIGZpbmFsIHZvaWQgc2V0UG9zaXRpb24oaW50IG5ld1Bvc2l0aW9uKQotICAgIHsKLSAgICAgICAgZlBvc2l0aW9uID0gbmV3UG9zaXRpb247Ci0gICAgfQotCi0gICAgLy8KLSAgICAvLyBDTU5vZGUgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvLyBwYWNrYWdlCi0KLSAgICBwdWJsaWMgYm9vbGVhbiBpc051bGxhYmxlKCkKLSAgICB7Ci0gICAgICAgIC8vIExlYWYgbm9kZXMgYXJlIG5ldmVyIG51bGxhYmxlIHVubGVzcyBpdHMgYW4gZXBzaWxvbiBub2RlCi0gICAgICAgIHJldHVybiAoZlBvc2l0aW9uID09IC0xKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkKLSAgICB7Ci0gICAgICAgIFN0cmluZ0J1ZmZlciBzdHJSZXQgPSBuZXcgU3RyaW5nQnVmZmVyKGZFbGVtZW50LnRvU3RyaW5nKCkpOwotICAgICAgICBzdHJSZXQuYXBwZW5kKCIgKCIpOwotICAgICAgICBzdHJSZXQuYXBwZW5kKGZFbGVtZW50LnVyaSk7Ci0gICAgICAgIHN0clJldC5hcHBlbmQoJywnKTsKLSAgICAgICAgc3RyUmV0LmFwcGVuZChmRWxlbWVudC5sb2NhbHBhcnQpOwotICAgICAgICBzdHJSZXQuYXBwZW5kKCcpJyk7Ci0gICAgICAgIGlmIChmUG9zaXRpb24gPj0gMCkKLSAgICAgICAgewotICAgICAgICAgICAgc3RyUmV0LmFwcGVuZAotICAgICAgICAgICAgKAotICAgICAgICAgICAgICAgICIgKFBvczoiCi0gICAgICAgICAgICAgICAgKyBuZXcgSW50ZWdlcihmUG9zaXRpb24pLnRvU3RyaW5nKCkKLSAgICAgICAgICAgICAgICArICIpIgotICAgICAgICAgICAgKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gc3RyUmV0LnRvU3RyaW5nKCk7Ci0gICAgfQotCi0gICAgLy8gcHJvdGVjdGVkCi0KLSAgICBwcm90ZWN0ZWQgdm9pZCBjYWxjRmlyc3RQb3MoQ01TdGF0ZVNldCB0b1NldCkKLSAgICB7Ci0gICAgICAgIC8vIElmIHdlIGFyZSBhbiBlcHNpbG9uIG5vZGUsIHRoZW4gdGhlIGZpcnN0IHBvcyBpcyBhbiBlbXB0eSBzZXQKLSAgICAgICAgaWYgKGZQb3NpdGlvbiA9PSAtMSkKLSAgICAgICAgICAgIHRvU2V0Lnplcm9CaXRzKCk7Ci0KLSAgICAgICAgLy8gT3RoZXJ3aXNlLCBpdHMganVzdCB0aGUgb25lIGJpdCBvZiBvdXIgcG9zaXRpb24KLSAgICAgICAgZWxzZQotICAgICAgICAgICAgdG9TZXQuc2V0Qml0KGZQb3NpdGlvbik7Ci0gICAgfQotCi0gICAgcHJvdGVjdGVkIHZvaWQgY2FsY0xhc3RQb3MoQ01TdGF0ZVNldCB0b1NldCkKLSAgICB7Ci0gICAgICAgIC8vIElmIHdlIGFyZSBhbiBlcHNpbG9uIG5vZGUsIHRoZW4gdGhlIGxhc3QgcG9zIGlzIGFuIGVtcHR5IHNldAotICAgICAgICBpZiAoZlBvc2l0aW9uID09IC0xKQotICAgICAgICAgICAgdG9TZXQuemVyb0JpdHMoKTsKLQotICAgICAgICAvLyBPdGhlcndpc2UsIGl0cyBqdXN0IHRoZSBvbmUgYml0IG9mIG91ciBwb3NpdGlvbgotICAgICAgICBlbHNlCi0gICAgICAgICAgICB0b1NldC5zZXRCaXQoZlBvc2l0aW9uKTsKLSAgICB9Ci0KLX0gLy8gY2xhc3MgQ01MZWFmCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R0ZC9tb2RlbHMvQ01Ob2RlLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R0ZC9tb2RlbHMvQ01Ob2RlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDI5YmZjNDMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdGQvbW9kZWxzL0NNTm9kZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTkwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTktMjAwMiBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhlcmNlcyIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgSW50ZXJuYXRpb25hbAotICogQnVzaW5lc3MgTWFjaGluZXMsIEluYy4sIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdGQubW9kZWxzOwotCi0vKioKLSAqIEEgY29udGVudCBtb2RlbCBub2RlLgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKi8KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBDTU5vZGUKLXsKLSAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgLy8gIENvbnN0cnVjdG9ycwotICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICBwdWJsaWMgQ01Ob2RlKGludCB0eXBlKQotICAgIHsKLSAgICAgICAgZlR5cGUgPSB0eXBlOwotICAgIH0KLQotCi0gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgIC8vICBQYWNrYWdlLCBhYnN0cmFjdCBtZXRob2RzCi0gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgIC8vIG1hZGUgdGhpcyBwdWJsaWMgc28gaXQgY291bGQgYmUgaW1wbGVtZW50ZWQgYW5kIHVzZWQgb3V0c2lkZSB0aGlzIHBhY2thZ2UgLW5laWxnLgotICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGlzTnVsbGFibGUoKSA7Ci0KLQotICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICAvLyAgUGFja2FnZSBmaW5hbCBtZXRob2RzCi0gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgIHB1YmxpYyBmaW5hbCBpbnQgdHlwZSgpCi0gICAgewotICAgICAgICByZXR1cm4gZlR5cGU7Ci0gICAgfQotCi0gICAgLy8gbWFkZSB0aGlzIHB1YmxpYyBzbyBpdCBjb3VsZCBiZSBpbXBsZW1lbnRlZCBhbmQgdXNlZCBvdXRzaWRlIHRoaXMgcGFja2FnZSAtbmVpbGcuCi0gICAgcHVibGljIGZpbmFsIENNU3RhdGVTZXQgZmlyc3RQb3MoKQotICAgIHsKLSAgICAgICAgaWYgKGZGaXJzdFBvcyA9PSBudWxsKQotICAgICAgICB7Ci0gICAgICAgICAgICBmRmlyc3RQb3MgPSBuZXcgQ01TdGF0ZVNldChmTWF4U3RhdGVzKTsKLSAgICAgICAgICAgIGNhbGNGaXJzdFBvcyhmRmlyc3RQb3MpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmRmlyc3RQb3M7Ci0gICAgfQotCi0gICAgLy8gbWFkZSB0aGlzIHB1YmxpYyBzbyBpdCBjb3VsZCBiZSBpbXBsZW1lbnRlZCBhbmQgdXNlZCBvdXRzaWRlIHRoaXMgcGFja2FnZSAtbmVpbGcuCi0gICAgcHVibGljIGZpbmFsIENNU3RhdGVTZXQgbGFzdFBvcygpCi0gICAgewotICAgICAgICBpZiAoZkxhc3RQb3MgPT0gbnVsbCkKLSAgICAgICAgewotICAgICAgICAgICAgZkxhc3RQb3MgPSBuZXcgQ01TdGF0ZVNldChmTWF4U3RhdGVzKTsKLSAgICAgICAgICAgIGNhbGNMYXN0UG9zKGZMYXN0UG9zKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZkxhc3RQb3M7Ci0gICAgfQotCi0gICAgZmluYWwgdm9pZCBzZXRGb2xsb3dQb3MoQ01TdGF0ZVNldCBzZXRUb0Fkb3B0KQotICAgIHsKLSAgICAgICAgZkZvbGxvd1BvcyA9IHNldFRvQWRvcHQ7Ci0gICAgfQotCi0gICAgcHVibGljIGZpbmFsIHZvaWQgc2V0TWF4U3RhdGVzKGludCBtYXhTdGF0ZXMpCi0gICAgewotICAgICAgICBmTWF4U3RhdGVzID0gbWF4U3RhdGVzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEFsbG93cyB0aGUgdXNlciB0byBzZXQgYXJiaXRyYXJ5IGRhdGEgb24gdGhpcyBjb250ZW50IG1vZGVsCi0gICAgICogbm9kZS4gVGhpcyBpcyB1c2VkIGJ5IHRoZSBhe24sbX0gb3B0aW1pemF0aW9uIHRoYXQgcnVucwotICAgICAqIGluIGNvbnN0YW50IHNwYWNlLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFVzZXJEYXRhKE9iamVjdCB1c2VyRGF0YSkgewotICAgICAgICBmVXNlckRhdGEgPSB1c2VyRGF0YTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBbGxvd3MgdGhlIHVzZXIgdG8gZ2V0IGFyYml0cmFyeSBkYXRhIHNldCBvbiB0aGlzIGNvbnRlbnQKLSAgICAgKiBtb2RlbCBub2RlLiBUaGlzIGlzIHVzZWQgYnkgdGhlIGF7bixtfSBvcHRpbWl6YXRpb24gdGhhdCBydW5zCi0gICAgICogaW4gY29uc3RhbnQgc3BhY2UuCi0gICAgICovCi0gICAgcHVibGljIE9iamVjdCBnZXRVc2VyRGF0YSgpIHsKLSAgICAgICAgcmV0dXJuIGZVc2VyRGF0YTsKLSAgICB9Ci0KLSAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgLy8gIFByb3RlY3RlZCwgYWJzdHJhY3QgbWV0aG9kcwotICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICBwcm90ZWN0ZWQgYWJzdHJhY3Qgdm9pZCBjYWxjRmlyc3RQb3MoQ01TdGF0ZVNldCB0b1NldCkgOwotCi0gICAgcHJvdGVjdGVkIGFic3RyYWN0IHZvaWQgY2FsY0xhc3RQb3MoQ01TdGF0ZVNldCB0b1NldCkgOwotCi0KLSAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgLy8gIFByaXZhdGUgZGF0YSBtZW1iZXJzCi0gICAgLy8KLSAgICAvLyAgZlR5cGUKLSAgICAvLyAgICAgIFRoZSB0eXBlIG9mIG5vZGUuIFRoaXMgaW5kaWNhdGVzIHdoZXRoZXIgaXRzIGEgbGVhZiBvciBhbgotICAgIC8vICAgICAgb3BlcmF0aW9uLiBUaG91Z2ggd2UgYWxzbyBkbyBkZXJpdmVkIGNsYXNzZXMgZm9yIHRoZXNlIHR5cGVzLAotICAgIC8vICAgICAgaXQgaXMgdG9vIGV4cGVuc2l2ZSB0byB1c2UgcnVudGltZSB0eXBpbmcgdG8gZmluZCB0aGlzIG91dC4KLSAgICAvLyAgICAgIFRoaXMgaXMgb25lIG9mIHRoZSBDb250ZW50U3BlY05vZGUuTk9ERV9YWFggdHlwZXMuCi0gICAgLy8KLSAgICAvLyAgZkZpcnN0UG9zCi0gICAgLy8gICAgICBUaGUgc2V0IG9mIE5GQSBzdGF0ZXMgdGhhdCByZXByZXNlbnQgdGhlIGVudHJ5IHN0YXRlcyBvZiB0aGlzCi0gICAgLy8gICAgICBub2RlIGluIHRoZSBERkEuCi0gICAgLy8KLSAgICAvLyAgZkZvbGxvd1BvcwotICAgIC8vICAgICAgVGhlIHNldCBvZiBORkEgc3RhdGVzIHRoYXQgY2FuIGJlIGdvdHRlbiB0byBmcm9tIGZyb20gdGhpcwotICAgIC8vICAgICAgbm9kZSBpbiB0aGUgREZBLgotICAgIC8vCi0gICAgLy8gIGZMYXN0UG9zCi0gICAgLy8gICAgICBUaGUgc2V0IG9mIE5GQSBzdGF0ZXMgdGhhdCByZXByZXNlbnQgdGhlIGZpbmFsIHN0YXRlcyBvZiB0aGlzCi0gICAgLy8gICAgICBub2RlIGluIHRoZSBERkEuCi0gICAgLy8KLSAgICAvLyAgZk1heFN0YXRlcwotICAgIC8vICAgICAgVGhlIG1heGltdW0gbnVtYmVyIG9mIHN0YXRlcyB0aGF0IHRoZSBORkEgaGFzLCB3aGljaCBtZWFucyB0aGUKLSAgICAvLyAgICAgIG1heCBudW1iZXIgb2YgTkZBIHN0YXRlcyB0aGF0IGhhdmUgdG8gYmUgdHJhY2VkIGluIHRoZSBzdGF0ZQotICAgIC8vICAgICAgc2V0cyBkdXJpbmcgdGhlIGJ1aWxkaW5nIG9mIHRoZSBERkEuIEl0cyB1bmZvcnR1bmF0ZSB0aGF0IGl0Ci0gICAgLy8gICAgICBoYXMgdG8gYmUgc3RvcmVkIHJlZHVuZGFudGx5LCBidXQgd2UgbmVlZCB0byBmYXVsdCBpbiB0aGUKLSAgICAvLyAgICAgIHN0YXRlIHNldCBtZW1iZXJzIGFuZCB0aGV5IGhhdmUgdG8gYmUgc2l6ZWQgdG8gdGhpcyBzaXplLiBXZQotICAgIC8vICAgICAgaW5pdCB0byB0byAtMSBzbyBpdCB3aWxsIGNhdXNlIGFuIGVycm9yIGlmIGl0cyB1c2VkIHdpdGhvdXQKLSAgICAvLyAgICAgIGJlaW5nIGluaXRpYWxpemVkLgotICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICBwcml2YXRlIGludCAgICAgICAgIGZUeXBlOwotICAgIHByaXZhdGUgQ01TdGF0ZVNldCAgZkZpcnN0UG9zICAgPSBudWxsOwotICAgIHByaXZhdGUgQ01TdGF0ZVNldCAgZkZvbGxvd1BvcyAgPSBudWxsOwotICAgIHByaXZhdGUgQ01TdGF0ZVNldCAgZkxhc3RQb3MgICAgPSBudWxsOwotICAgIHByaXZhdGUgaW50ICAgICAgICAgZk1heFN0YXRlcyAgPSAtMTsKLSAgICBwcml2YXRlIE9iamVjdCAgICAgIGZVc2VyRGF0YSAgID0gbnVsbDsKLX07CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R0ZC9tb2RlbHMvQ01TdGF0ZVNldC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdGQvbW9kZWxzL0NNU3RhdGVTZXQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZDIwYTNhOS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R0ZC9tb2RlbHMvQ01TdGF0ZVNldC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzQzICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTktMjAwMiBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhlcmNlcyIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgSW50ZXJuYXRpb25hbAotICogQnVzaW5lc3MgTWFjaGluZXMsIEluYy4sIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdGQubW9kZWxzOwotCi0KLS8qKgotICogVGhpcyBjbGFzcyBpcyBhIHZlcnkgc2ltcGxlIGJpdHNldCBjbGFzcy4gVGhlIERGQSBjb250ZW50IG1vZGVsIGNvZGUgbmVlZHMKLSAqIHRvIHN1cHBvcnQgYSBiaXQgc2V0LCBidXQgdGhlIGphdmEgQml0U2V0IGNsYXNzIGlzIHdheSwgd2F5IG92ZXJraWxsLiBPdXIKLSAqIGJpdHNldCBuZXZlciBuZWVkcyB0byBiZSBleHBhbmRlZCBhZnRlciBjcmVhdGlvbiwgaGFzaCBpdHNlbGYsIGV0Yy4uLgotICoKLSAqIFNpbmNlIHRoZSB2YXN0IG1ham9yaXR5IG9mIGNvbnRlbnQgbW9kZWxzIHdpbGwgbmV2ZXIgcmVxdWlyZSBtb3JlIHRoYW4gNjQKLSAqIGJpdHMsIGFuZCBzaW5jZSBhbGxvY2F0aW9uIG9mIGFueXRoaW5nIGluIEphdmEgaXMgZXhwZW5zaXZlLCB0aGlzIGNsYXNzCi0gKiBwcm92aWRlcyBhIGh5YnJpZCBpbXBsZW1lbnRhdGlvbiB0aGF0IHVzZXMgdHdvIGludHMgZm9yIGluc3RhbmNlcyB0aGF0IHVzZQotICogNjQgYml0cyBvciBmZXdlci4gSXQgaGFzIGEgYnl0ZSBhcnJheSByZWZlcmVuY2UgbWVtYmVyIHdoaWNoIHdpbGwgb25seSBiZQotICogdXNlZCBpZiBtb3JlIHRoYW4gNjQgYml0cyBhcmUgcmVxdWlyZWQuCi0gKgotICogTm90ZSB0aGF0IHRoZSBjb2RlIHRoYXQgdXNlcyB0aGlzIGNsYXNzIHdpbGwgbmV2ZXIgcGVyZm9ybSBvcGVyYXRpb25zCi0gKiBvbiBzZXRzIG9mIGRpZmZlcmVudCBzaXplcywgc28gdGhhdCBjaGVjayBkb2VzIG5vdCBoYXZlIHRvIGJlIG1hZGUgaGVyZS4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICovCi0vLyBtYWRlIHRoaXMgY2xhc3MgcHVibGljIHNvIGl0IGNhbiBiZSBhY2Nlc3NlZCBieQotLy8gdGhlIFhTIGNvbnRlbnQgbW9kZWxzIGZyb20gdGhlIHNjaGVtYSBwYWNrYWdlIC1uZWlsZy4KLXB1YmxpYyBjbGFzcyBDTVN0YXRlU2V0Ci17Ci0gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgIC8vICBDb25zdHJ1Y3RvcnMKLSAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgcHVibGljIENNU3RhdGVTZXQoaW50IGJpdENvdW50KQotICAgIHsKLSAgICAgICAgLy8gU3RvcmUgdGhlIHJlcXVpcmVkIGJpdCBjb3VudCBhbmQgaW5zdXJlIGl0cyBsZWdhbAotICAgICAgICBmQml0Q291bnQgPSBiaXRDb3VudDsKLSAgICAgICAgaWYgKGZCaXRDb3VudCA8IDApCi0gICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiSW1wbGVtZW50YXRpb25NZXNzYWdlcy5WQUxfQ01TSSIpOwotCi0gICAgICAgIC8vCi0gICAgICAgIC8vICBTZWUgaWYgd2UgbmVlZCB0byBhbGxvY2F0ZSB0aGUgYnl0ZSBhcnJheSBvciB3aGV0aGVyIHdlIGNhbiBsaXZlCi0gICAgICAgIC8vICB3aXRoaW4gdGhlIDY0IGJpdCBoaWdoIHBlcmZvcm1hbmNlIHNjaGVtZS4KLSAgICAgICAgLy8KLSAgICAgICAgaWYgKGZCaXRDb3VudCA+IDY0KQotICAgICAgICB7Ci0gICAgICAgICAgICBmQnl0ZUNvdW50ID0gZkJpdENvdW50IC8gODsKLSAgICAgICAgICAgIGlmIChmQml0Q291bnQgJSA4ICE9IDApCi0gICAgICAgICAgICAgICAgZkJ5dGVDb3VudCsrOwotICAgICAgICAgICAgZkJ5dGVBcnJheSA9IG5ldyBieXRlW2ZCeXRlQ291bnRdOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gSW5pdCBhbGwgdGhlIGJpdHMgdG8gemVybwotICAgICAgICB6ZXJvQml0cygpOwotICAgIH0KLQotCi0gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgIC8vICBQdWJsaWMgaW5oZXJpdGVkIG1ldGhvZHMKLSAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpCi0gICAgewotICAgICAgICBTdHJpbmdCdWZmZXIgc3RyUmV0ID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotICAgICAgICB0cnkKLSAgICAgICAgewotICAgICAgICAgICAgc3RyUmV0LmFwcGVuZCgieyIpOwotICAgICAgICAgICAgZm9yIChpbnQgaW5kZXggPSAwOyBpbmRleCA8IGZCaXRDb3VudDsgaW5kZXgrKykKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBpZiAoZ2V0Qml0KGluZGV4KSkKLSAgICAgICAgICAgICAgICAgICAgc3RyUmV0LmFwcGVuZCgiICIgKyBpbmRleCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBzdHJSZXQuYXBwZW5kKCIgfSIpOwotICAgICAgICB9Ci0KLSAgICAgICAgY2F0Y2goUnVudGltZUV4Y2VwdGlvbiBleFRvQ2F0Y2gpCi0gICAgICAgIHsKLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAvLyAgV2Uga25vdyB0aGlzIHdvbid0IGhhcHBlbiBidXQgd2UgaGF2ZSB0byBjYXRjaCBpdCB0byBhdm9pZCBpdAotICAgICAgICAgICAgLy8gIGhhdmluZyB0byBiZSBpbiBvdXIgJ3Rocm93cycgbGlzdC4KLSAgICAgICAgICAgIC8vCi0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHN0clJldC50b1N0cmluZygpOwotICAgIH0KLQotCi0gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgIC8vICBQYWNrYWdlIGZpbmFsIG1ldGhvZHMKLSAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0vLyB0aGUgWFMgY29udGVudCBtb2RlbHMgZnJvbSB0aGUgc2NoZW1hIHBhY2thZ2UgLW5laWxnLgotICAgIHB1YmxpYyBmaW5hbCB2b2lkIGludGVyc2VjdGlvbihDTVN0YXRlU2V0IHNldFRvQW5kKQotICAgIHsKLSAgICAgICAgaWYgKGZCaXRDb3VudCA8IDY1KQotICAgICAgICB7Ci0gICAgICAgICAgICBmQml0czEgJj0gc2V0VG9BbmQuZkJpdHMxOwotICAgICAgICAgICAgZkJpdHMyICY9IHNldFRvQW5kLmZCaXRzMjsKLSAgICAgICAgfQotICAgICAgICAgZWxzZQotICAgICAgICB7Ci0gICAgICAgICAgICBmb3IgKGludCBpbmRleCA9IGZCeXRlQ291bnQgLSAxOyBpbmRleCA+PSAwOyBpbmRleC0tKQotICAgICAgICAgICAgICAgIGZCeXRlQXJyYXlbaW5kZXhdICY9IHNldFRvQW5kLmZCeXRlQXJyYXlbaW5kZXhdOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIGZpbmFsIGJvb2xlYW4gZ2V0Qml0KGludCBiaXRUb0dldCkKLSAgICB7Ci0gICAgICAgIGlmIChiaXRUb0dldCA+PSBmQml0Q291bnQpCi0gICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiSW1wbGVtZW50YXRpb25NZXNzYWdlcy5WQUxfQ01TSSIpOwotCi0gICAgICAgIGlmIChmQml0Q291bnQgPCA2NSkKLSAgICAgICAgewotICAgICAgICAgICAgZmluYWwgaW50IG1hc2sgPSAoMHgxIDw8IChiaXRUb0dldCAlIDMyKSk7Ci0gICAgICAgICAgICBpZiAoYml0VG9HZXQgPCAzMikKLSAgICAgICAgICAgICAgICByZXR1cm4gKGZCaXRzMSAmIG1hc2spICE9IDA7Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgcmV0dXJuIChmQml0czIgJiBtYXNrKSAhPSAwOwotICAgICAgICB9Ci0gICAgICAgICBlbHNlCi0gICAgICAgIHsKLSAgICAgICAgICAgIC8vIENyZWF0ZSB0aGUgbWFzayBhbmQgYnl0ZSB2YWx1ZXMKLSAgICAgICAgICAgIGZpbmFsIGJ5dGUgbWFzayA9IChieXRlKSgweDEgPDwgKGJpdFRvR2V0ICUgOCkpOwotICAgICAgICAgICAgZmluYWwgaW50IG9mcyA9IGJpdFRvR2V0ID4+IDM7Ci0KLSAgICAgICAgICAgIC8vIEFuZCBhY2Nlc3MgdGhlIHJpZ2h0IGJpdCBhbmQgYnl0ZQotICAgICAgICAgICAgcmV0dXJuICgoZkJ5dGVBcnJheVtvZnNdICYgbWFzaykgIT0gMCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0VtcHR5KCkKLSAgICB7Ci0gICAgICAgIGlmIChmQml0Q291bnQgPCA2NSkKLSAgICAgICAgewotICAgICAgICAgICAgcmV0dXJuICgoZkJpdHMxID09IDApICYmIChmQml0czIgPT0gMCkpOwotICAgICAgICB9Ci0gICAgICAgICBlbHNlCi0gICAgICAgIHsKLSAgICAgICAgICAgIGZvciAoaW50IGluZGV4ID0gZkJ5dGVDb3VudCAtIDE7IGluZGV4ID49IDA7IGluZGV4LS0pCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgaWYgKGZCeXRlQXJyYXlbaW5kZXhdICE9IDApCi0gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICB9Ci0KLSAgICBmaW5hbCBib29sZWFuIGlzU2FtZVNldChDTVN0YXRlU2V0IHNldFRvQ29tcGFyZSkKLSAgICB7Ci0gICAgICAgIGlmIChmQml0Q291bnQgIT0gc2V0VG9Db21wYXJlLmZCaXRDb3VudCkKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLQotICAgICAgICBpZiAoZkJpdENvdW50IDwgNjUpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHJldHVybiAoKGZCaXRzMSA9PSBzZXRUb0NvbXBhcmUuZkJpdHMxKQotICAgICAgICAgICAgJiYgICAgICAoZkJpdHMyID09IHNldFRvQ29tcGFyZS5mQml0czIpKTsKLSAgICAgICAgfQotCi0gICAgICAgIGZvciAoaW50IGluZGV4ID0gZkJ5dGVDb3VudCAtIDE7IGluZGV4ID49IDA7IGluZGV4LS0pCi0gICAgICAgIHsKLSAgICAgICAgICAgIGlmIChmQnl0ZUFycmF5W2luZGV4XSAhPSBzZXRUb0NvbXBhcmUuZkJ5dGVBcnJheVtpbmRleF0pCi0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotLy8gdGhlIFhTIGNvbnRlbnQgbW9kZWxzIGZyb20gdGhlIHNjaGVtYSBwYWNrYWdlIC1uZWlsZy4KLSAgICBwdWJsaWMgZmluYWwgdm9pZCB1bmlvbihDTVN0YXRlU2V0IHNldFRvT3IpCi0gICAgewotICAgICAgICBpZiAoZkJpdENvdW50IDwgNjUpCi0gICAgICAgIHsKLSAgICAgICAgICAgIGZCaXRzMSB8PSBzZXRUb09yLmZCaXRzMTsKLSAgICAgICAgICAgIGZCaXRzMiB8PSBzZXRUb09yLmZCaXRzMjsKLSAgICAgICAgfQotICAgICAgICAgZWxzZQotICAgICAgICB7Ci0gICAgICAgICAgICBmb3IgKGludCBpbmRleCA9IGZCeXRlQ291bnQgLSAxOyBpbmRleCA+PSAwOyBpbmRleC0tKQotICAgICAgICAgICAgICAgIGZCeXRlQXJyYXlbaW5kZXhdIHw9IHNldFRvT3IuZkJ5dGVBcnJheVtpbmRleF07Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgZmluYWwgdm9pZCBzZXRCaXQoaW50IGJpdFRvU2V0KQotICAgIHsKLSAgICAgICAgaWYgKGJpdFRvU2V0ID49IGZCaXRDb3VudCkKLSAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJJbXBsZW1lbnRhdGlvbk1lc3NhZ2VzLlZBTF9DTVNJIik7Ci0KLSAgICAgICAgaWYgKGZCaXRDb3VudCA8IDY1KQotICAgICAgICB7Ci0gICAgICAgICAgICBmaW5hbCBpbnQgbWFzayA9ICgweDEgPDwgKGJpdFRvU2V0ICUgMzIpKTsKLSAgICAgICAgICAgIGlmIChiaXRUb1NldCA8IDMyKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIGZCaXRzMSAmPSB+bWFzazsKLSAgICAgICAgICAgICAgICBmQml0czEgfD0gbWFzazsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgZkJpdHMyICY9IH5tYXNrOwotICAgICAgICAgICAgICAgIGZCaXRzMiB8PSBtYXNrOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgICBlbHNlCi0gICAgICAgIHsKLSAgICAgICAgICAgIC8vIENyZWF0ZSB0aGUgbWFzayBhbmQgYnl0ZSB2YWx1ZXMKLSAgICAgICAgICAgIGZpbmFsIGJ5dGUgbWFzayA9IChieXRlKSgweDEgPDwgKGJpdFRvU2V0ICUgOCkpOwotICAgICAgICAgICAgZmluYWwgaW50IG9mcyA9IGJpdFRvU2V0ID4+IDM7Ci0KLSAgICAgICAgICAgIC8vIEFuZCBhY2Nlc3MgdGhlIHJpZ2h0IGJpdCBhbmQgYnl0ZQotICAgICAgICAgICAgZkJ5dGVBcnJheVtvZnNdICY9IH5tYXNrOwotICAgICAgICAgICAgZkJ5dGVBcnJheVtvZnNdIHw9IG1hc2s7Ci0gICAgICAgIH0KLSAgICB9Ci0KLS8vIHRoZSBYUyBjb250ZW50IG1vZGVscyBmcm9tIHRoZSBzY2hlbWEgcGFja2FnZSAtbmVpbGcuCi0gICAgcHVibGljIGZpbmFsIHZvaWQgc2V0VG8oQ01TdGF0ZVNldCBzcmNTZXQpCi0gICAgewotICAgICAgICAvLyBUaGV5IGhhdmUgdG8gYmUgdGhlIHNhbWUgc2l6ZQotICAgICAgICBpZiAoZkJpdENvdW50ICE9IHNyY1NldC5mQml0Q291bnQpCi0gICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiSW1wbGVtZW50YXRpb25NZXNzYWdlcy5WQUxfQ01TSSIpOwotCi0gICAgICAgIGlmIChmQml0Q291bnQgPCA2NSkKLSAgICAgICAgewotICAgICAgICAgICAgZkJpdHMxID0gc3JjU2V0LmZCaXRzMTsKLSAgICAgICAgICAgIGZCaXRzMiA9IHNyY1NldC5mQml0czI7Ci0gICAgICAgIH0KLSAgICAgICAgIGVsc2UKLSAgICAgICAgewotICAgICAgICAgICAgZm9yIChpbnQgaW5kZXggPSBmQnl0ZUNvdW50IC0gMTsgaW5kZXggPj0gMDsgaW5kZXgtLSkKLSAgICAgICAgICAgICAgICBmQnl0ZUFycmF5W2luZGV4XSA9IHNyY1NldC5mQnl0ZUFycmF5W2luZGV4XTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8vIGhhZCB0byBtYWtlIHRoaXMgbWV0aG9kIHB1YmxpYyBzbyBpdCBjb3VsZCBiZSBhY2Nlc3NlZCBmcm9tCi0gICAgLy8gc2NoZW1hIHBhY2thZ2UgLSBuZWlsZy4KLSAgICBwdWJsaWMgZmluYWwgdm9pZCB6ZXJvQml0cygpCi0gICAgewotICAgICAgICBpZiAoZkJpdENvdW50IDwgNjUpCi0gICAgICAgIHsKLSAgICAgICAgICAgIGZCaXRzMSA9IDA7Ci0gICAgICAgICAgICBmQml0czIgPSAwOwotICAgICAgICB9Ci0gICAgICAgICBlbHNlCi0gICAgICAgIHsKLSAgICAgICAgICAgIGZvciAoaW50IGluZGV4ID0gZkJ5dGVDb3VudCAtIDE7IGluZGV4ID49IDA7IGluZGV4LS0pCi0gICAgICAgICAgICAgICAgZkJ5dGVBcnJheVtpbmRleF0gPSAwOwotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgLy8gIFByaXZhdGUgZGF0YSBtZW1iZXJzCi0gICAgLy8KLSAgICAvLyAgZkJpdENvdW50Ci0gICAgLy8gICAgICBUaGUgY291bnQgb2YgYml0cyB0aGF0IHRoZSBvdXRzaWRlIHdvcmxkIHdhbnRzIHRvIHN1cHBvcnQsCi0gICAgLy8gICAgICBzbyBpdHMgdGhlIG1heCBiaXQgaW5kZXggcGx1cyBvbmUuCi0gICAgLy8KLSAgICAvLyAgZkJ5dGVDb3VudAotICAgIC8vICAgICAgSWYgdGhlIGJpdCBjb3VudCBpcyA+IDY0LCB0aGVuIHdlIHVzZSB0aGUgZkJ5dGVBcnJheSBtZW1iZXIgdG8KLSAgICAvLyAgICAgIHN0b3JlIHRoZSBiaXRzLCBhbmQgdGhpcyBpbmRpY2F0ZXMgaXRzIHNpemUgaW4gYnl0ZXMuIE90aGVyd2lzZQotICAgIC8vICAgICAgaXRzIHZhbHVlIGlzIG1lYW5pbmdsZXNzLgotICAgIC8vCi0gICAgLy8gIGZCaXRzMQotICAgIC8vICBmQml0czIKLSAgICAvLyAgICAgIFdoZW4gdGhlIGJpdCBjb3VudCBpcyA8IDY0ICh2ZXJ5IGNvbW1vbiksIHRoZXNlIGhvbGQgdGhlIGJpdHMuCi0gICAgLy8gICAgICBPdGhlcndpc2UsIHRoZSBmQnl0ZUFycmF5IG1lbWJlciBob2xkcyBodGVtLgotICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICBpbnQgICAgICAgICBmQml0Q291bnQ7Ci0gICAgaW50ICAgICAgICAgZkJ5dGVDb3VudDsKLSAgICBpbnQgICAgICAgICBmQml0czE7Ci0gICAgaW50ICAgICAgICAgZkJpdHMyOwotICAgIGJ5dGVbXSAgICAgIGZCeXRlQXJyYXk7Ci0gICAgLyogT3B0aW1pemF0aW9uKEphbiwgMjAwMSkgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG8pIHsKLSAgICAgICAgaWYgKCEobyBpbnN0YW5jZW9mIENNU3RhdGVTZXQpKSByZXR1cm4gZmFsc2U7Ci0gICAgICAgIHJldHVybiBpc1NhbWVTZXQoKENNU3RhdGVTZXQpbyk7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKLSAgICAgICAgaWYgKGZCaXRDb3VudCA8IDY1KQotICAgICAgICB7Ci0gICAgICAgICAgICByZXR1cm4gZkJpdHMxKyBmQml0czIgKiAzMTsKLSAgICAgICAgfQotICAgICAgICAgZWxzZQotICAgICAgICB7Ci0gICAgICAgICAgICBpbnQgaGFzaCA9IDA7Ci0gICAgICAgICAgICBmb3IgKGludCBpbmRleCA9IGZCeXRlQ291bnQgLSAxOyBpbmRleCA+PSAwOyBpbmRleC0tKQotICAgICAgICAgICAgICAgIGhhc2ggPSBmQnl0ZUFycmF5W2luZGV4XSArIGhhc2ggKiAzMTsKLSAgICAgICAgICAgIHJldHVybiBoYXNoOwotICAgICAgICB9Ci0gICAgfQotICAgLyogT3B0aW1pemF0aW9uKEphbiwgMjAwMSkgKi8KLX07CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R0ZC9tb2RlbHMvQ01VbmlPcC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdGQvbW9kZWxzL0NNVW5pT3AuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOTdmNTBjMS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R0ZC9tb2RlbHMvQ01VbmlPcC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTQzICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTktMjAwMiBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhlcmNlcyIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgSW50ZXJuYXRpb25hbAotICogQnVzaW5lc3MgTWFjaGluZXMsIEluYy4sIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdGQubW9kZWxzOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR0ZC5YTUxDb250ZW50U3BlYzsKLQotLyoqCi0gKiBDb250ZW50IG1vZGVsIFVuaS1PcCBub2RlLgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKi8KLXB1YmxpYyBjbGFzcyBDTVVuaU9wIGV4dGVuZHMgQ01Ob2RlCi17Ci0gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgIC8vICBDb25zdHJ1Y3RvcnMKLSAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgcHVibGljIENNVW5pT3AoaW50IHR5cGUsIENNTm9kZSBjaGlsZE5vZGUpCi0gICAgewotICAgICAgICBzdXBlcih0eXBlKTsKLQotICAgICAgICAvLyBJbnN1cmUgdGhhdCBpdHMgb25lIG9mIHRoZSB0eXBlcyB3ZSByZXF1aXJlCi0gICAgICAgIGlmICgodHlwZSgpICE9IFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9aRVJPX09SX09ORSkKLSAgICAgICAgJiYgICh0eXBlKCkgIT0gWE1MQ29udGVudFNwZWMuQ09OVEVOVFNQRUNOT0RFX1pFUk9fT1JfTU9SRSkKLSAgICAgICAgJiYgICh0eXBlKCkgIT0gWE1MQ29udGVudFNwZWMuQ09OVEVOVFNQRUNOT0RFX09ORV9PUl9NT1JFKSkKLSAgICAgICAgewotICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIkltcGxlbWVudGF0aW9uTWVzc2FnZXMuVkFMX1VTVCIpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gU3RvcmUgdGhlIG5vZGUgYW5kIGluaXQgYW55IGRhdGEgdGhhdCBuZWVkcyBpdAotICAgICAgICBmQ2hpbGQgPSBjaGlsZE5vZGU7Ci0gICAgfQotCi0KLSAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgLy8gIFBhY2thZ2UsIGZpbmFsIG1ldGhvZHMKLSAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgZmluYWwgQ01Ob2RlIGdldENoaWxkKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBmQ2hpbGQ7Ci0gICAgfQotCi0KLSAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgLy8gIFBhY2thZ2UsIGluaGVyaXRlZCBtZXRob2RzCi0gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgIHB1YmxpYyBib29sZWFuIGlzTnVsbGFibGUoKQotICAgIHsKLSAgICAgICAgLy8KLSAgICAgICAgLy8gIEZvciBkZWJ1Z2dpbmcgcHVycG9zZXMsIG1ha2Ugc3VyZSB3ZSBnb3QgcmlkIG9mIGFsbCBub24gJyonCi0gICAgICAgIC8vICByZXBldGl0aW9ucy4gT3RoZXJ3aXNlLCAnKicgc3R5bGUgbm9kZXMgYXJlIGFsd2F5cyBudWxsYWJsZS4KLSAgICAgICAgLy8KLSAgICAgICAgaWYgKHR5cGUoKSA9PSBYTUxDb250ZW50U3BlYy5DT05URU5UU1BFQ05PREVfT05FX09SX01PUkUpCi0gICAgICAgICAgICByZXR1cm4gZkNoaWxkLmlzTnVsbGFibGUoKTsKLSAgICAgICAgZWxzZQotICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotCi0KLSAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgLy8gIFByb3RlY3RlZCwgaW5oZXJpdGVkIG1ldGhvZHMKLSAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgcHJvdGVjdGVkIHZvaWQgY2FsY0ZpcnN0UG9zKENNU3RhdGVTZXQgdG9TZXQpCi0gICAgewotICAgICAgICAvLyBJdHMganVzdCBiYXNlZCBvbiBvdXIgY2hpbGQgbm9kZSdzIGZpcnN0IHBvcwotICAgICAgICB0b1NldC5zZXRUbyhmQ2hpbGQuZmlyc3RQb3MoKSk7Ci0gICAgfQotCi0gICAgcHJvdGVjdGVkIHZvaWQgY2FsY0xhc3RQb3MoQ01TdGF0ZVNldCB0b1NldCkKLSAgICB7Ci0gICAgICAgIC8vIEl0cyBqdXN0IGJhc2VkIG9uIG91ciBjaGlsZCBub2RlJ3MgbGFzdCBwb3MKLSAgICAgICAgdG9TZXQuc2V0VG8oZkNoaWxkLmxhc3RQb3MoKSk7Ci0gICAgfQotCi0KLSAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgLy8gIFByaXZhdGUgZGF0YSBtZW1iZXJzCi0gICAgLy8KLSAgICAvLyAgZkNoaWxkCi0gICAgLy8gICAgICBUaGlzIGlzIHRoZSByZWZlcmVuY2UgdG8gdGhlIG9uZSBjaGlsZCB0aGF0IHdlIGhhdmUgZm9yIHRoaXMKLSAgICAvLyAgICAgIHVuYXJ5IG9wZXJhdGlvbi4KLSAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgcHJpdmF0ZSBDTU5vZGUgIGZDaGlsZDsKLX07CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R0ZC9tb2RlbHMvQ29udGVudE1vZGVsVmFsaWRhdG9yLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R0ZC9tb2RlbHMvQ29udGVudE1vZGVsVmFsaWRhdG9yLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGI4MWY1YzEuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdGQvbW9kZWxzL0NvbnRlbnRNb2RlbFZhbGlkYXRvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsODggKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OS0yMDAyIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGVyY2VzIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBJbnRlcm5hdGlvbmFsCi0gKiBCdXNpbmVzcyBNYWNoaW5lcywgSW5jLiwgaHR0cDovL3d3dy5hcGFjaGUub3JnLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR0ZC5tb2RlbHM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5RTmFtZTsKLQotLyoqCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgQ29udGVudE1vZGVsVmFsaWRhdG9yIHsKLQotICAgIC8vCi0gICAgLy8gTWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiB2YWxpZGF0ZQotICAgICAqCi0gICAgICogQHBhcmFtIGNoaWxkcmVuCi0gICAgICogQHBhcmFtIG9mZnNldAotICAgICAqIEBwYXJhbSBsZW5ndGgKLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIHZhbHVlIC0xIGlmIGZ1bGx5IHZhbGlkLCBlbHNlIHRoZSAwIGJhc2VkIGluZGV4IG9mIHRoZSBjaGlsZAotICAgICAqICAgICAgICAgdGhhdCBmaXJzdCBmYWlsZWQuIElmIHRoZSB2YWx1ZSByZXR1cm5lZCBpcyBlcXVhbCB0byB0aGUgbnVtYmVyCi0gICAgICogICAgICAgICBvZiBjaGlsZHJlbiwgdGhlbiB0aGUgc3BlY2lmaWVkIGNoaWxkcmVuIGFyZSB2YWxpZCBidXQgYWRkaXRpb25hbAotICAgICAqICAgICAgICAgY29udGVudCBpcyByZXF1aXJlZCB0byByZWFjaCBhIHZhbGlkIGVuZGluZyBzdGF0ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IHZhbGlkYXRlKFFOYW1lW10gY2hpbGRyZW4sIGludCBvZmZzZXQsIGludCBsZW5ndGgpOwotCi19IC8vIGludGVyZmFjZSBDb250ZW50TW9kZWxWYWxpZGF0b3IKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHRkL21vZGVscy9ERkFDb250ZW50TW9kZWwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHRkL21vZGVscy9ERkFDb250ZW50TW9kZWwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOWE0ZTBmNS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R0ZC9tb2RlbHMvREZBQ29udGVudE1vZGVsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMDMzICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTktMjAwMiBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhlcmNlcyIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgSW50ZXJuYXRpb25hbAotICogQnVzaW5lc3MgTWFjaGluZXMsIEluYy4sIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdGQubW9kZWxzOwotCi1pbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHRkLlhNTENvbnRlbnRTcGVjOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlFOYW1lOwotCi0vKioKLQotICogQHZlcnNpb24gJElkOiBERkFDb250ZW50TW9kZWwuamF2YSx2IDEuNCAyMDEwLzA4LzA2IDIzOjQ5OjQzIGpvZWh3IEV4cCAkCi0gKiBERkFDb250ZW50TW9kZWwgaXMgdGhlIGRlcml2YXRpdmUgb2YgQ29udGVudE1vZGVsIHRoYXQgZG9lcwotICogYWxsIG9mIHRoZSBub24tdHJpdmlhbCBlbGVtZW50IGNvbnRlbnQgdmFsaWRhdGlvbi4gVGhpcyBjbGFzcyBkb2VzCi0gKiB0aGUgY29udmVyc2lvbiBmcm9tIHRoZSByZWd1bGFyIGV4cHJlc3Npb24gdG8gdGhlIERGQSB0aGF0Ci0gKiBpdCB0aGVuIHVzZXMgaW4gaXRzIHZhbGlkYXRpb24gYWxnb3JpdGhtLgotICogPHA+Ci0gKiA8Yj5Ob3RlOjwvYj4gVXBzdHJlYW0gd29yayBpbnN1cmVzIHRoYXQgdGhpcyBjbGFzcyB3aWxsIG5ldmVyIHNlZQotICogYSBjb250ZW50IG1vZGVsIHdpdGggUENEQVRBIGluIGl0LiBBbnkgbW9kZWwgd2l0aCBQQ0RBVEEgaXMgJ21peGVkJwotICogYW5kIGlzIGhhbmRsZWQgdmlhIHRoZSBNaXhlZENvbnRlbnRNb2RlbCBjbGFzcyBzaW5jZSBtaXhlZCBtb2RlbHMKLSAqIGFyZSB2ZXJ5IGNvbnN0cmFpbmVkIGluIGZvcm0gYW5kIGVhc2lseSBoYW5kbGVkIHZpYSBhIHNwZWNpYWwgY2FzZS4KLSAqIFRoaXMgYWxzbyBtYWtlcyBpbXBsZW1lbnRhdGlvbiBvZiB0aGlzIGNsYXNzIG11Y2ggZWFzaWVyLgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAdmVyc2lvbiAkSWQ6IERGQUNvbnRlbnRNb2RlbC5qYXZhLHYgMS40IDIwMTAvMDgvMDYgMjM6NDk6NDMgam9laHcgRXhwICQKLSAqLwotcHVibGljIGNsYXNzIERGQUNvbnRlbnRNb2RlbAotICAgIGltcGxlbWVudHMgQ29udGVudE1vZGVsVmFsaWRhdG9yIHsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RhbnRzCi0gICAgLy8KLSAgICAvLyBzcGVjaWFsIHN0cmluZ3MKLQotICAgIC8qKiBFcHNpbG9uIHN0cmluZy4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgZkVwc2lsb25TdHJpbmcgPSAiPDxDTU5PREVfRVBTSUxPTj4+IjsKLQotICAgIC8qKiBFbmQtb2YtY29udGVudCBzdHJpbmcuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGZFT0NTdHJpbmcgPSAiPDxDTU5PREVfRU9DPj4iOwotCi0gICAgLyoqIGluaXRpYWxpemluZyBzdGF0aWMgbWVtYmVycyAqKi8KLSAgICBzdGF0aWMgewotICAgICAgICBmRXBzaWxvblN0cmluZyA9IGZFcHNpbG9uU3RyaW5nLmludGVybigpOwotICAgICAgICBmRU9DU3RyaW5nID0gZkVPQ1N0cmluZy5pbnRlcm4oKTsKLSAgICB9Ci0KLSAgICAvLyBkZWJ1Z2dpbmcKLQotICAgIC8qKiBTZXQgdG8gdHJ1ZSB0byBkZWJ1ZyBjb250ZW50IG1vZGVsIHZhbGlkYXRpb24uICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbiBERUJVR19WQUxJREFURV9DT05URU5UID0gZmFsc2U7Ci0KLSAgICAvLwotICAgIC8vIERhdGEKLSAgICAvLwotCi0gICAgLyogdGhpcyBpcyB0aGUgRXF1aXZDbGFzc0NvbXBhcmF0b3Igb2JqZWN0ICovCi0gICAgLy9wcml2YXRlIEVxdWl2Q2xhc3NDb21wYXJhdG9yIGNvbXBhcmF0b3IgPSBudWxsOwotCi0gICAgLyoqCi0gICAgICogVGhpcyBpcyB0aGUgbWFwIG9mIHVuaXF1ZSBpbnB1dCBzeW1ib2wgZWxlbWVudHMgdG8gaW5kaWNlcyBpbnRvCi0gICAgICogZWFjaCBzdGF0ZSdzIHBlci1pbnB1dCBzeW1ib2wgdHJhbnNpdGlvbiB0YWJsZSBlbnRyeS4gVGhpcyBpcyBwYXJ0Ci0gICAgICogb2YgdGhlIGJ1aWx0IERGQSBpbmZvcm1hdGlvbiB0aGF0IG11c3QgYmUga2VwdCBhcm91bmQgdG8gZG8gdGhlCi0gICAgICogYWN0dWFsIHZhbGlkYXRpb24uCi0gICAgICovCi0gICAgcHJpdmF0ZSBRTmFtZSBmRWxlbU1hcFtdID0gbnVsbDsKLQotICAgIC8qKgotICAgICAqIFRoaXMgaXMgYSBtYXAgb2Ygd2hldGhlciB0aGUgZWxlbWVudCBtYXAgY29udGFpbnMgaW5mb3JtYXRpb24KLSAgICAgKiByZWxhdGVkIHRvIEFOWSBtb2RlbHMuCi0gICAgICovCi0gICAgcHJpdmF0ZSBpbnQgZkVsZW1NYXBUeXBlW10gPSBudWxsOwotCi0gICAgLyoqIFRoZSBlbGVtZW50IG1hcCBzaXplLiAqLwotICAgIHByaXZhdGUgaW50IGZFbGVtTWFwU2l6ZSA9IDA7Ci0KLSAgICAvKiogQm9vbGVhbiB0byBkaXN0aW5ndWlzaCBTY2hlbWEgTWl4ZWQgQ29udGVudCAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBmTWl4ZWQ7Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgTkZBIHBvc2l0aW9uIG9mIHRoZSBzcGVjaWFsIEVPQyAoZW5kIG9mIGNvbnRlbnQpIG5vZGUuIFRoaXMKLSAgICAgKiBpcyBzYXZlZCBhd2F5IHNpbmNlIGl0J3MgdXNlZCBkdXJpbmcgdGhlIERGQSBidWlsZC4KLSAgICAgKi8KLSAgICBwcml2YXRlIGludCBmRU9DUG9zID0gMDsKLQotCi0gICAgLyoqCi0gICAgICogVGhpcyBpcyBhbiBhcnJheSBvZiBib29sZWFucywgb25lIHBlciBzdGF0ZSAodGhlcmUgYXJlCi0gICAgICogZlRyYW5zVGFibGVTaXplIHN0YXRlcyBpbiB0aGUgREZBKSB0aGF0IGluZGljYXRlcyB3aGV0aGVyIHRoYXQKLSAgICAgKiBzdGF0ZSBpcyBhIGZpbmFsIHN0YXRlLgotICAgICAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBmRmluYWxTdGF0ZUZsYWdzW10gPSBudWxsOwotCi0gICAgLyoqCi0gICAgICogVGhlIGxpc3Qgb2YgZm9sbG93IHBvc2l0aW9ucyBmb3IgZWFjaCBORkEgcG9zaXRpb24gKGkuZS4gZm9yIGVhY2gKLSAgICAgKiBub24tZXBzaWxvbiBsZWFmIG5vZGUuKSBUaGlzIGlzIG9ubHkgdXNlZCBkdXJpbmcgdGhlIGJ1aWxkaW5nIG9mCi0gICAgICogdGhlIERGQSwgYW5kIGlzIGxldCBnbyBhZnRlcndhcmRzLgotICAgICAqLwotICAgIHByaXZhdGUgQ01TdGF0ZVNldCBmRm9sbG93TGlzdFtdID0gbnVsbDsKLQotICAgIC8qKgotICAgICAqIFRoaXMgaXMgdGhlIGhlYWQgbm9kZSBvZiBvdXIgaW50ZXJtZWRpYXRlIHJlcHJlc2VudGF0aW9uLiBJdCBpcwotICAgICAqIG9ubHkgbm9uLW51bGwgZHVyaW5nIHRoZSBidWlsZGluZyBvZiB0aGUgREZBIChqdXN0IHNvIHRoYXQgaXQKLSAgICAgKiBkb2VzIG5vdCBoYXZlIHRvIGJlIHBhc3NlZCBhbGwgYXJvdW5kLikgT25jZSB0aGUgREZBIGlzIGJ1aWx0LAotICAgICAqIHRoaXMgaXMgbm8gbG9uZ2VyIHJlcXVpcmVkIHNvIGl0cyBudWxsZWQgb3V0LgotICAgICAqLwotICAgIHByaXZhdGUgQ01Ob2RlIGZIZWFkTm9kZSA9IG51bGw7Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgY291bnQgb2YgbGVhZiBub2Rlcy4gVGhpcyBpcyBhbiBpbXBvcnRhbnQgbnVtYmVyIHRoYXQgc2V0IHNvbWUKLSAgICAgKiBsaW1pdHMgb24gdGhlIHNpemVzIG9mIGRhdGEgc3RydWN0dXJlcyBpbiB0aGUgREZBIHByb2Nlc3MuCi0gICAgICovCi0gICAgcHJpdmF0ZSBpbnQgZkxlYWZDb3VudCA9IDA7Ci0KLSAgICAvKioKLSAgICAgKiBBbiBhcnJheSBvZiBub24tZXBzaWxvbiBsZWFmIG5vZGVzLCB3aGljaCBpcyB1c2VkIGR1cmluZyB0aGUgREZBCi0gICAgICogYnVpbGQgb3BlcmF0aW9uLCB0aGVuIGRyb3BwZWQuCi0gICAgICovCi0gICAgcHJpdmF0ZSBDTUxlYWYgZkxlYWZMaXN0W10gPSBudWxsOwotCi0gICAgLyoqIEFycmF5IG1hcHBpbmcgQU5ZIHR5cGVzIHRvIHRoZSBsZWFmIGxpc3QuICovCi0gICAgcHJpdmF0ZSBpbnQgZkxlYWZMaXN0VHlwZVtdID0gbnVsbDsKLQotICAgIC8vcHJpdmF0ZSBDb250ZW50TGVhZk5hbWVUeXBlVmVjdG9yIGZMZWFmTmFtZVR5cGVWZWN0b3IgPSBudWxsOwotCi0gICAgLyoqCi0gICAgICogVGhlIHN0cmluZyBwb29sIG9mIG91ciBwYXJzZXIgc2Vzc2lvbi4gVGhpcyBpcyBzZXQgZHVyaW5nIGNvbnN0cnVjdGlvbgotICAgICAqIGFuZCBrZXB0IGFyb3VuZC4KLSAgICAgKi8KLSAgICAvL3ByaXZhdGUgU3RyaW5nUG9vbCBmU3RyaW5nUG9vbCA9IG51bGw7Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIGlzIHRoZSB0cmFuc2l0aW9uIHRhYmxlIHRoYXQgaXMgdGhlIG1haW4gYnkgcHJvZHVjdCBvZiBhbGwKLSAgICAgKiBvZiB0aGUgZWZmb3J0IGhlcmUuIEl0IGlzIGFuIGFycmF5IG9mIGFycmF5cyBvZiBpbnRzLiBUaGUgZmlyc3QKLSAgICAgKiBkaW1lbnNpb24gaXMgdGhlIG51bWJlciBvZiBzdGF0ZXMgd2UgZW5kIHVwIHdpdGggaW4gdGhlIERGQS4gVGhlCi0gICAgICogc2Vjb25kIGRpbWVuc2lvbnMgaXMgdGhlIG51bWJlciBvZiB1bmlxdWUgZWxlbWVudHMgaW4gdGhlIGNvbnRlbnQKLSAgICAgKiBtb2RlbCAoZkVsZW1NYXBTaXplKS4gRWFjaCBlbnRyeSBpbiB0aGUgc2Vjb25kIGRpbWVuc2lvbiBpbmRpY2F0ZXMKLSAgICAgKiB0aGUgbmV3IHN0YXRlIGdpdmVuIHRoYXQgaW5wdXQgZm9yIHRoZSBmaXJzdCBkaW1lbnNpb24ncyBzdGFydAotICAgICAqIHN0YXRlLgotICAgICAqIDxwPgotICAgICAqIFRoZSBmRWxlbU1hcCBhcnJheSBoYW5kbGVzIG1hcHBpbmcgZnJvbSBlbGVtZW50IGluZGV4ZXMgdG8KLSAgICAgKiBwb3NpdGlvbnMgaW4gdGhlIHNlY29uZCBkaW1lbnNpb24gb2YgdGhlIHRyYW5zaXRpb24gdGFibGUuCi0gICAgICovCi0gICAgcHJpdmF0ZSBpbnQgZlRyYW5zVGFibGVbXVtdID0gbnVsbDsKLQotICAgIC8qKgotICAgICAqIFRoZSBudW1iZXIgb2YgdmFsaWQgZW50cmllcyBpbiB0aGUgdHJhbnNpdGlvbiB0YWJsZSwgYW5kIGluIHRoZSBvdGhlcgotICAgICAqIHJlbGF0ZWQgdGFibGVzIHN1Y2ggYXMgZkZpbmFsU3RhdGVGbGFncy4KLSAgICAgKi8KLSAgICBwcml2YXRlIGludCBmVHJhbnNUYWJsZVNpemUgPSAwOwotCi0gICAgLyoqCi0gICAgICogRmxhZyB0aGF0IGluZGljYXRlcyB0aGF0IGV2ZW4gdGhvdWdoIHdlIGhhdmUgYSAiY29tcGxpY2F0ZWQiCi0gICAgICogY29udGVudCBtb2RlbCwgaXQgaXMgdmFsaWQgdG8gaGF2ZSBubyBjb250ZW50LiBJbiBvdGhlciB3b3JkcywKLSAgICAgKiBhbGwgcGFydHMgb2YgdGhlIGNvbnRlbnQgbW9kZWwgYXJlIG9wdGlvbmFsLiBGb3IgZXhhbXBsZToKLSAgICAgKiA8cHJlPgotICAgICAqICAgICAgJmx0OyFFTEVNRU5UIEFsbE9wdGlvbmFsIChPcHRpb25hbCosTm90UmVxdWlyZWQ/KSZndDsKLSAgICAgKiA8L3ByZT4KLSAgICAgKi8KLSAgICBwcml2YXRlIGJvb2xlYW4gZkVtcHR5Q29udGVudElzVmFsaWQgPSBmYWxzZTsKLQotICAgIC8vIHRlbXAgdmFyaWFibGVzCi0KLSAgICAvKiogVGVtcG9yYXJ5IHF1YWxpZmllZCBuYW1lLiAqLwotICAgIHByaXZhdGUgZmluYWwgUU5hbWUgZlFOYW1lID0gbmV3IFFOYW1lKCk7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0cnVjdG9ycwotICAgIC8vCi0KLQotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHMgYSBERkEgY29udGVudCBtb2RlbC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzeW50YXhUcmVlICAgIFRoZSBzeW50YXggdHJlZSBvZiB0aGUgY29udGVudCBtb2RlbC4KLSAgICAgKiBAcGFyYW0gbGVhZkNvdW50ICAgICBUaGUgbnVtYmVyIG9mIGxlYXZlcy4KLSAgICAgKiBAcGFyYW0gbWl4ZWQKLSAgICAgKgotICAgICAqLwotICAgIHB1YmxpYyBERkFDb250ZW50TW9kZWwoQ01Ob2RlIHN5bnRheFRyZWUsIGludCBsZWFmQ291bnQsIGJvb2xlYW4gbWl4ZWQpIHsKLSAgICAgICAgLy8gU3RvcmUgYXdheSBvdXIgaW5kZXggYW5kIHBvb2xzIGluIG1lbWJlcnMKLSAgICAgICAgLy9mU3RyaW5nUG9vbCA9IHN0cmluZ1Bvb2w7Ci0gICAgICAgIGZMZWFmQ291bnQgPSBsZWFmQ291bnQ7Ci0KLQotICAgICAgICAvLyB0aGlzIGlzIGZvciBTY2hlbWEgTWl4ZWQgQ29udGVudAotICAgICAgICBmTWl4ZWQgPSBtaXhlZDsKLQotICAgICAgICAvLwotICAgICAgICAvLyAgT2ssIHNvIGxldHMgZ3JpbmQgdGhyb3VnaCB0aGUgYnVpbGRpbmcgb2YgdGhlIERGQS4gVGhpcyBtZXRob2QKLSAgICAgICAgLy8gIGhhbmRsZXMgdGhlIGhpZ2ggbGV2ZWwgbG9naWMgb2YgdGhlIGFsZ29yaXRobSwgYnV0IGl0IHVzZXMgYQotICAgICAgICAvLyAgbnVtYmVyIG9mIGhlbHBlciBjbGFzc2VzIHRvIGRvIGl0cyB0aGluZy4KLSAgICAgICAgLy8KLSAgICAgICAgLy8gIEluIG9yZGVyIHRvIGF2b2lkIGhhdmluZyBodW5kcmVkcyBvZiByZWZlcmVuY2VzIHRvIHRoZSBlcnJvciBhbmQKLSAgICAgICAgLy8gIHN0cmluZyBoYW5kbGVycyBhcm91bmQsIHRoaXMgZ3V5IGFuZCBhbGwgb2YgaGlzIGhlbHBlciBjbGFzc2VzCi0gICAgICAgIC8vICBqdXN0IHRocm93IGEgc2ltcGxlIGV4Y2VwdGlvbiBhbmQgd2UgdGhlbiBwYXNzIGl0IGFsb25nLgotICAgICAgICAvLwotICAgICAgICBidWlsZERGQShzeW50YXhUcmVlKTsKLSAgICB9Ci0KLSAgICAvLwotICAgIC8vIENvbnRlbnRNb2RlbFZhbGlkYXRvciBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIENoZWNrIHRoYXQgdGhlIHNwZWNpZmllZCBjb250ZW50IGlzIHZhbGlkIGFjY29yZGluZyB0byB0aGlzCi0gICAgICogY29udGVudCBtb2RlbC4gVGhpcyBtZXRob2QgY2FuIGFsc28gYmUgY2FsbGVkIHRvIGRvICd3aGF0IGlmJwotICAgICAqIHRlc3Rpbmcgb2YgY29udGVudCBtb2RlbHMganVzdCB0byBzZWUgaWYgdGhleSB3b3VsZCBiZSB2YWxpZC4KLSAgICAgKiA8cD4KLSAgICAgKiBBIHZhbHVlIG9mIC0xIGluIHRoZSBjaGlsZHJlbiBhcnJheSBpbmRpY2F0ZXMgYSBQQ0RBVEEgbm9kZS4gQWxsIG90aGVyCi0gICAgICogaW5kZXhlcyB3aWxsIGJlIHBvc2l0aXZlIGFuZCByZXByZXNlbnQgY2hpbGQgZWxlbWVudHMuIFRoZSBjb3VudCBjYW4gYmUKLSAgICAgKiB6ZXJvLCBzaW5jZSBzb21lIGVsZW1lbnRzIGhhdmUgdGhlIEVNUFRZIGNvbnRlbnQgbW9kZWwgYW5kIHRoYXQgbXVzdCBiZQotICAgICAqIGNvbmZpcm1lZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjaGlsZHJlbiBUaGUgY2hpbGRyZW4gb2YgdGhpcyBlbGVtZW50LiAgRWFjaCBpbnRlZ2VyIGlzIGFuIGluZGV4IHdpdGhpbgotICAgICAqICAgICAgICAgICAgICAgICB0aGUgPGNvZGU+U3RyaW5nUG9vbDwvY29kZT4gb2YgdGhlIGNoaWxkIGVsZW1lbnQgbmFtZS4gIEFuIGluZGV4Ci0gICAgICogICAgICAgICAgICAgICAgIG9mIC0xIGlzIHVzZWQgdG8gaW5kaWNhdGUgYW4gb2NjdXJyZW5jZSBvZiBub24td2hpdGVzcGFjZSBjaGFyYWN0ZXIKLSAgICAgKiAgICAgICAgICAgICAgICAgZGF0YS4KLSAgICAgKiBAcGFyYW0gb2Zmc2V0IE9mZnNldCBpbnRvIHRoZSBhcnJheSB3aGVyZSB0aGUgY2hpbGRyZW4gc3RhcnRzLgotICAgICAqIEBwYXJhbSBsZW5ndGggVGhlIG51bWJlciBvZiBlbnRyaWVzIGluIHRoZSA8Y29kZT5jaGlsZHJlbjwvY29kZT4gYXJyYXkuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSB2YWx1ZSAtMSBpZiBmdWxseSB2YWxpZCwgZWxzZSB0aGUgMCBiYXNlZCBpbmRleCBvZiB0aGUgY2hpbGQKLSAgICAgKiAgICAgICAgIHRoYXQgZmlyc3QgZmFpbGVkLiBJZiB0aGUgdmFsdWUgcmV0dXJuZWQgaXMgZXF1YWwgdG8gdGhlIG51bWJlcgotICAgICAqICAgICAgICAgb2YgY2hpbGRyZW4sIHRoZW4gdGhlIHNwZWNpZmllZCBjaGlsZHJlbiBhcmUgdmFsaWQgYnV0IGFkZGl0aW9uYWwKLSAgICAgKiAgICAgICAgIGNvbnRlbnQgaXMgcmVxdWlyZWQgdG8gcmVhY2ggYSB2YWxpZCBlbmRpbmcgc3RhdGUuCi0gICAgICoKLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IHZhbGlkYXRlKFFOYW1lW10gY2hpbGRyZW4sIGludCBvZmZzZXQsIGludCBsZW5ndGgpIHsKLQotICAgICAgICBpZiAoREVCVUdfVkFMSURBVEVfQ09OVEVOVCkKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiREZBQ29udGVudE1vZGVsI3ZhbGlkYXRlQ29udGVudCIpOwotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIEEgREZBIGNvbnRlbnQgbW9kZWwgbXVzdCAqYWx3YXlzKiBoYXZlIGF0IGxlYXN0IDEgY2hpbGQKLSAgICAgICAgLy8gc28gYSBmYWlsdXJlIGlzIGdpdmVuIGlmIG5vIGNoaWxkcmVuIHByZXNlbnQuCi0gICAgICAgIC8vCi0gICAgICAgIC8vIERlZmVjdCA3ODI6IFRoaXMgaXMgYW4gaW5jb3JyZWN0IHN0YXRlbWVudCBiZWNhdXNlIGEgREZBCi0gICAgICAgIC8vIGNvbnRlbnQgbW9kZWwgaXMgYWxzbyB1c2VkIGZvciBjb25zdHJ1Y3Rpb25zIHN1Y2ggYXM6Ci0gICAgICAgIC8vCi0gICAgICAgIC8vICAgICAoT3B0aW9uYWwqLE5vdFJlcXVpcmVkPykKLSAgICAgICAgLy8KLSAgICAgICAgLy8gd2hlcmUgYSBwZXJmZWN0bHkgdmFsaWQgY29udGVudCB3b3VsZCBiZSBOTyBDSElMRFJFTi4KLSAgICAgICAgLy8gVGhlcmVmb3JlLCBpZiB0aGVyZSBhcmUgbm8gY2hpbGRyZW4sIHdlIG11c3QgY2hlY2sgdG8KLSAgICAgICAgLy8gc2VlIGlmIHRoZSBDTU5PREVfRU9DIG1hcmtlciBpcyBhIHZhbGlkIHN0YXJ0IHN0YXRlISAtQWMKLSAgICAgICAgLy8KLSAgICAgICAgaWYgKGxlbmd0aCA9PSAwKSB7Ci0gICAgICAgICAgICBpZiAoREVCVUdfVkFMSURBVEVfQ09OVEVOVCkgewotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiISEhIG5vIGNoaWxkcmVuIik7Ci0gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJlbGVtTWFwPSIrZkVsZW1NYXApOwotICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZkVsZW1NYXAubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHVyaSA9IGZFbGVtTWFwW2ldLnVyaTsKLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGxvY2FscGFydCA9IGZFbGVtTWFwW2ldLmxvY2FscGFydDsKLQotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oImZFbGVtTWFwWyIraSsiXT0iK3VyaSsiLCIrCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhbHBhcnQrIiAoIisKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVyaSsiLCAiKwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWxwYXJ0KwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJyknKTsKLQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkVPQ0luZGV4PSIrZkVPQ1N0cmluZyk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIHJldHVybiBmRW1wdHlDb250ZW50SXNWYWxpZCA/IC0xIDogMDsKLQotICAgICAgICB9IC8vIGlmIGNoaWxkIGNvdW50ID09IDAKLQotICAgICAgICAvLwotICAgICAgICAvLyAgTGV0cyBsb29wIHRocm91Z2ggdGhlIGNoaWxkcmVuIGluIHRoZSBhcnJheSBhbmQgbW92ZSBvdXIgd2F5Ci0gICAgICAgIC8vICB0aHJvdWdoIHRoZSBzdGF0ZXMuIE5vdGUgdGhhdCB3ZSB1c2UgdGhlIGZFbGVtTWFwIGFycmF5IHRvIG1hcAotICAgICAgICAvLyAgYW4gZWxlbWVudCBpbmRleCB0byBhIHN0YXRlIGluZGV4LgotICAgICAgICAvLwotICAgICAgICBpbnQgY3VyU3RhdGUgPSAwOwotICAgICAgICBmb3IgKGludCBjaGlsZEluZGV4ID0gMDsgY2hpbGRJbmRleCA8IGxlbmd0aDsgY2hpbGRJbmRleCsrKQotICAgICAgICB7Ci0gICAgICAgICAgICAvLyBHZXQgdGhlIGN1cnJlbnQgZWxlbWVudCBpbmRleCBvdXQKLSAgICAgICAgICAgIGZpbmFsIFFOYW1lIGN1ckVsZW0gPSBjaGlsZHJlbltvZmZzZXQgKyBjaGlsZEluZGV4XTsKLSAgICAgICAgICAgIC8vIGlnbm9yZSBtaXhlZCB0ZXh0Ci0gICAgICAgICAgICBpZiAoZk1peGVkICYmIGN1ckVsZW0ubG9jYWxwYXJ0ID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gTG9vayB1cCB0aGlzIGNoaWxkIGluIG91ciBlbGVtZW50IG1hcAotICAgICAgICAgICAgaW50IGVsZW1JbmRleCA9IDA7Ci0gICAgICAgICAgICBmb3IgKDsgZWxlbUluZGV4IDwgZkVsZW1NYXBTaXplOyBlbGVtSW5kZXgrKykKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBpbnQgdHlwZSA9IGZFbGVtTWFwVHlwZVtlbGVtSW5kZXhdICYgMHgwZiA7Ci0gICAgICAgICAgICAgICAgaWYgKHR5cGUgPT0gWE1MQ29udGVudFNwZWMuQ09OVEVOVFNQRUNOT0RFX0xFQUYpIHsKLSAgICAgICAgICAgICAgICAgICAgLy9TeXN0ZW0ub3V0LnByaW50bG4oImZFbGVtTWFwWyIrZWxlbUluZGV4KyJdOiAiK2ZFbGVtTWFwW2VsZW1JbmRleF0pOwotICAgICAgICAgICAgICAgICAgICBpZiAoZkVsZW1NYXBbZWxlbUluZGV4XS5yYXduYW1lID09IGN1ckVsZW0ucmF3bmFtZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSBpZiAodHlwZSA9PSBYTUxDb250ZW50U3BlYy5DT05URU5UU1BFQ05PREVfQU5ZKSB7Ci0gICAgICAgICAgICAgICAgICAgIFN0cmluZyB1cmkgPSBmRWxlbU1hcFtlbGVtSW5kZXhdLnVyaTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKHVyaSA9PSBudWxsIHx8IHVyaSA9PSBjdXJFbGVtLnVyaSkgewotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSBpZiAodHlwZSA9PSBYTUxDb250ZW50U3BlYy5DT05URU5UU1BFQ05PREVfQU5ZX0xPQ0FMKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChjdXJFbGVtLnVyaSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIGlmICh0eXBlID09IFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9BTllfT1RIRVIpIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGZFbGVtTWFwW2VsZW1JbmRleF0udXJpICE9IGN1ckVsZW0udXJpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gSWYgd2UgZGlkbid0IGZpbmQgaXQsIHRoZW4gb2J2aW91c2x5IG5vdCB2YWxpZAotICAgICAgICAgICAgaWYgKGVsZW1JbmRleCA9PSBmRWxlbU1hcFNpemUpIHsKLSAgICAgICAgICAgICAgICBpZiAoREVCVUdfVkFMSURBVEVfQ09OVEVOVCkgewotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIiEhISBkaWRuJ3QgZmluZCBpdCIpOwotCi0gICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiY3VyRWxlbSA6ICIgK2N1ckVsZW0gKTsKLSAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaT0wOyBpPGZFbGVtTWFwU2l6ZTsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oImZFbGVtTWFwWyIraSsiXSA9ICIgK2ZFbGVtTWFwW2ldICk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oImZFbGVtTWFwVHlwZVsiK2krIl0gPSAiICtmRWxlbU1hcFR5cGVbaV0gKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIHJldHVybiBjaGlsZEluZGV4OwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgLy8gIExvb2sgdXAgdGhlIG5leHQgc3RhdGUgZm9yIHRoaXMgaW5wdXQgc3ltYm9sIHdoZW4gaW4gdGhlCi0gICAgICAgICAgICAvLyAgY3VycmVudCBzdGF0ZS4KLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICBjdXJTdGF0ZSA9IGZUcmFuc1RhYmxlW2N1clN0YXRlXVtlbGVtSW5kZXhdOwotCi0gICAgICAgICAgICAvLyBJZiBpdHMgbm90IGEgbGVnYWwgdHJhbnNpdGlvbiwgdGhlbiBpbnZhbGlkCi0gICAgICAgICAgICBpZiAoY3VyU3RhdGUgPT0gLTEpIHsKLSAgICAgICAgICAgICAgICBpZiAoREVCVUdfVkFMSURBVEVfQ09OVEVOVCkKLSAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCIhISEgbm90IGEgbGVnYWwgdHJhbnNpdGlvbiIpOwotICAgICAgICAgICAgICAgIHJldHVybiBjaGlsZEluZGV4OwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gIFdlIHRyYW5zaXRpb25lZCBhbGwgdGhlIHdheSB0aHJvdWdoIHRoZSBpbnB1dCBsaXN0LiBIb3dldmVyLCB0aGF0Ci0gICAgICAgIC8vICBkb2VzIG5vdCBtZWFuIHRoYXQgd2UgZW5kZWQgaW4gYSBmaW5hbCBzdGF0ZS4gU28gY2hlY2sgd2hldGhlcgotICAgICAgICAvLyAgb3VyIGVuZGluZyBzdGF0ZSBpcyBhIGZpbmFsIHN0YXRlLgotICAgICAgICAvLwotICAgICAgICBpZiAoREVCVUdfVkFMSURBVEVfQ09OVEVOVCkKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiY3VyU3RhdGU9IitjdXJTdGF0ZSsiLCBjaGlsZENvdW50PSIrbGVuZ3RoKTsKLSAgICAgICAgaWYgKCFmRmluYWxTdGF0ZUZsYWdzW2N1clN0YXRlXSkKLSAgICAgICAgICAgIHJldHVybiBsZW5ndGg7Ci0KLSAgICAgICAgLy8gc3VjY2VzcyEKLSAgICAgICAgcmV0dXJuIC0xOwotICAgIH0gLy8gdmFsaWRhdGUKLQotCi0gICAgLy8KLSAgICAvLyBQcml2YXRlIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogQnVpbGRzIHRoZSBpbnRlcm5hbCBERkEgdHJhbnNpdGlvbiB0YWJsZSBmcm9tIHRoZSBnaXZlbiBzeW50YXggdHJlZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzeW50YXhUcmVlIFRoZSBzeW50YXggdHJlZS4KLSAgICAgKgotICAgICAqIEBleGNlcHRpb24gQ01FeGNlcHRpb24gVGhyb3duIGlmIERGQSBjYW5ub3QgYmUgYnVpbHQuCi0gICAgICovCi0gICAgcHJpdmF0ZSB2b2lkIGJ1aWxkREZBKENNTm9kZSBzeW50YXhUcmVlKQotICAgIHsKLSAgICAgICAgLy8KLSAgICAgICAgLy8gIFRoZSBmaXJzdCBzdGVwIHdlIG5lZWQgdG8gdGFrZSBpcyB0byByZXdyaXRlIHRoZSBjb250ZW50IG1vZGVsCi0gICAgICAgIC8vICB1c2luZyBvdXIgQ01Ob2RlIG9iamVjdHMsIGFuZCBpbiB0aGUgcHJvY2VzcyBnZXQgcmlkIG9mIGFueQotICAgICAgICAvLyAgcmVwZXRpdGlvbiBzaG9ydCBjdXRzLCBjb252ZXJ0aW5nIHRoZW0gaW50byAnKicgc3R5bGUgcmVwZXRpdGlvbnMKLSAgICAgICAgLy8gIG9yIGdldHRpbmcgcmlkIG9mIHJlcGV0aXRpb25zIGFsdG9nZXRoZXIuCi0gICAgICAgIC8vCi0gICAgICAgIC8vICBUaGUgY29udmVyc2lvbnMgZG9uZSBhcmU6Ci0gICAgICAgIC8vCi0gICAgICAgIC8vICB4KyAtPiAoeHx4KikKLSAgICAgICAgLy8gIHg/IC0+ICh4fGVwc2lsb24pCi0gICAgICAgIC8vCi0gICAgICAgIC8vICBUaGlzIGlzIGEgcmVsYXRpdmVseSBjb21wbGV4IHNjZW5hcmlvLiBXaGF0IGlzIGhhcHBlbmluZyBpcyB0aGF0Ci0gICAgICAgIC8vICB3ZSBjcmVhdGUgYSB0b3AgbGV2ZWwgYmluYXJ5IG5vZGUgb2Ygd2hpY2ggdGhlIHNwZWNpYWwgRU9DIHZhbHVlCi0gICAgICAgIC8vICBpcyBzZXQgYXMgdGhlIHJpZ2h0IHNpZGUgbm9kZS4gVGhlIHRoZSBsZWZ0IHNpZGUgaXMgc2V0IHRvIHRoZQotICAgICAgICAvLyAgcmV3cml0dGVuIHN5bnRheCB0cmVlLiBUaGUgc291cmNlIGlzIHRoZSBvcmlnaW5hbCBjb250ZW50IG1vZGVsCi0gICAgICAgIC8vICBpbmZvIGZyb20gdGhlIGRlY2wgcG9vbC4gVGhlIHJld3JpdGUgaXMgZG9uZSBieSBidWlsZFN5bnRheFRyZWUoKQotICAgICAgICAvLyAgd2hpY2ggcmVjdXJzZXMgdGhlIGRlY2wgcG9vbCdzIGNvbnRlbnQgb2YgdGhlIGVsZW1lbnQgYW5kIGJ1aWxkcwotICAgICAgICAvLyAgYSBuZXcgdHJlZSBpbiB0aGUgcHJvY2Vzcy4KLSAgICAgICAgLy8KLSAgICAgICAgLy8gIE5vdGUgdGhhdCwgZHVyaW5nIHRoaXMgb3BlcmF0aW9uLCB3ZSBzZXQgZWFjaCBub24tZXBzaWxvbiBsZWFmCi0gICAgICAgIC8vICBub2RlJ3MgREZBIHN0YXRlIHBvc2l0aW9uIGFuZCBjb3VudCB0aGUgbnVtYmVyIG9mIHN1Y2ggbGVhZnMsIHdoaWNoCi0gICAgICAgIC8vICBpcyBsZWZ0IGluIHRoZSBmTGVhZkNvdW50IG1lbWJlci4KLSAgICAgICAgLy8KLSAgICAgICAgLy8gIFRoZSBub2RlVG1wIG9iamVjdCBpcyBwYXNzZWQgaW4ganVzdCBhcyBhIHRlbXAgbm9kZSB0byB1c2UgZHVyaW5nCi0gICAgICAgIC8vICB0aGUgcmVjdXJzaW9uLiBPdGhlcndpc2UsIHdlJ2QgaGF2ZSB0byBjcmVhdGUgYSBuZXcgbm9kZSBvbiBldmVyeQotICAgICAgICAvLyAgbGV2ZWwgb2YgcmVjdXJzaW9uLCB3aGljaCB3b3VsZCBiZSBwaWdneSBpbiBKYXZhIChhcyBpcyBldmVyeXRoaW5nCi0gICAgICAgIC8vICBmb3IgdGhhdCBtYXR0ZXIuKQotICAgICAgICAvLwotCi0gICAgICAgIC8qIE1PRElGSUVEIChKYW4sIDIwMDEpCi0gICAgICAgICAqCi0gICAgICAgICAqIFVzZSBmb2xsb3dpbmcgcnVsZXMuCi0gICAgICAgICAqICAgbnVsbGFibGUoeCspIDo9IG51bGxhYmxlKHgpLCBmaXJzdCh4KykgOj0gZmlyc3QoeCksICBsYXN0KHgrKSA6PSBsYXN0KHgpCi0gICAgICAgICAqICAgbnVsbGFibGUoeD8pIDo9IHRydWUsIGZpcnN0KHg/KSA6PSBmaXJzdCh4KSwgIGxhc3QoeD8pIDo9IGxhc3QoeCkKLSAgICAgICAgICoKLSAgICAgICAgICogVGhlIHNhbWUgY29tcHV0YXRpb24gb2YgZm9sbG93IGFzIHgqIGlzIGFwcGxpZWQgdG8geCsKLSAgICAgICAgICoKLSAgICAgICAgICogVGhlIG1vZGlmaWNhdGlvbiBkcmFzdGljYWxseSByZWR1Y2VzIGNvbXB1dGF0aW9uIHRpbWUgb2YKLSAgICAgICAgICogIihhLCAoYiwgYSssIChjLCAoYiwgYSspKywgYSssIChkLCAgKGMsIChiLCBhKykrLCBhKykrLCAoYiwgYSspKywgYSspKykrKSspKyIKLSAgICAgICAgICovCi0KLSAgICAgICAgZlFOYW1lLnNldFZhbHVlcyhudWxsLCBmRU9DU3RyaW5nLCBmRU9DU3RyaW5nLCBudWxsKTsKLSAgICAgICAgQ01MZWFmIG5vZGVFT0MgPSBuZXcgQ01MZWFmKGZRTmFtZSk7Ci0gICAgICAgIGZIZWFkTm9kZSA9IG5ldyBDTUJpbk9wCi0gICAgICAgICgKLSAgICAgICAgICAgIFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9TRVEKLSAgICAgICAgICAgICwgc3ludGF4VHJlZQotICAgICAgICAgICAgLCBub2RlRU9DCi0gICAgICAgICk7Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gIEFuZCBoYW5kbGUgc3BlY2lhbGx5IHRoZSBFT0Mgbm9kZSwgd2hpY2ggYWxzbyBtdXN0IGJlIG51bWJlcmVkCi0gICAgICAgIC8vICBhbmQgY291bnRlZCBhcyBhIG5vbi1lcHNpbG9uIGxlYWYgbm9kZS4gSXQgY291bGQgbm90IGJlIGhhbmRsZWQKLSAgICAgICAgLy8gIGluIHRoZSBhYm92ZSB0cmVlIGJ1aWxkIGJlY2F1c2UgaXQgd2FzIGNyZWF0ZWQgYmVmb3JlIGFsbCB0aGF0Ci0gICAgICAgIC8vICBzdGFydGVkLiBXZSBzYXZlIHRoZSBFT0MgcG9zaXRpb24gc2luY2UgaXRzIHVzZWQgZHVyaW5nIHRoZSBERkEKLSAgICAgICAgLy8gIGJ1aWxkaW5nIGxvb3AuCi0gICAgICAgIC8vCi0gICAgICAgIGZFT0NQb3MgPSBmTGVhZkNvdW50OwotICAgICAgICBub2RlRU9DLnNldFBvc2l0aW9uKGZMZWFmQ291bnQrKyk7Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gIE9rLCBzbyBub3cgd2UgaGF2ZSB0byBpdGVyYXRlIHRoZSBuZXcgdHJlZSBhbmQgZG8gYSBsaXR0bGUgbW9yZQotICAgICAgICAvLyAgd29yayBub3cgdGhhdCB3ZSBrbm93IHRoZSBsZWFmIGNvdW50LiBPbmUgdGhpbmcgd2UgbmVlZCB0byBkbyBpcwotICAgICAgICAvLyAgdG8gY2FsY3VsYXRlIHRoZSBmaXJzdCBhbmQgbGFzdCBwb3NpdGlvbiBzZXRzIG9mIGVhY2ggbm9kZS4gVGhpcwotICAgICAgICAvLyAgaXMgY2FjaGVkIGF3YXkgaW4gZWFjaCBvZiB0aGUgbm9kZXMuCi0gICAgICAgIC8vCi0gICAgICAgIC8vICBBbG9uZyB0aGUgd2F5IHdlIGFsc28gc2V0IHRoZSBsZWFmIGNvdW50IGluIGVhY2ggbm9kZSBhcyB0aGUKLSAgICAgICAgLy8gIG1heGltdW0gc3RhdGUgY291bnQuIFRoZXkgbXVzdCBrbm93IHRoaXMgaW4gb3JkZXIgdG8gY3JlYXRlIHRoZWlyCi0gICAgICAgIC8vICBmaXJzdC9sYXN0IHBvcyBzZXRzLgotICAgICAgICAvLwotICAgICAgICAvLyAgV2UgYWxzbyBuZWVkIHRvIGJ1aWxkIGFuIGFycmF5IG9mIHJlZmVyZW5jZXMgdG8gdGhlIG5vbi1lcHNpbG9uCi0gICAgICAgIC8vICBsZWFmIG5vZGVzLiBTaW5jZSB3ZSBpdGVyYXRlIGl0IGluIHRoZSBzYW1lIHdheSBhcyBiZWZvcmUsIHRoaXMKLSAgICAgICAgLy8gIHdpbGwgcHV0IHRoZW0gaW4gdGhlIGFycmF5IGFjY29yZGluZyB0byB0aGVpciBwb3NpdGlvbiB2YWx1ZXMuCi0gICAgICAgIC8vCi0gICAgICAgIGZMZWFmTGlzdCA9IG5ldyBDTUxlYWZbZkxlYWZDb3VudF07Ci0gICAgICAgIGZMZWFmTGlzdFR5cGUgPSBuZXcgaW50W2ZMZWFmQ291bnRdOwotICAgICAgICBwb3N0VHJlZUJ1aWxkSW5pdChmSGVhZE5vZGUsIDApOwotCi0gICAgICAgIC8vCi0gICAgICAgIC8vICBBbmQsIG1vdmluZyBvbndhcmQuLi4gV2Ugbm93IG5lZWQgdG8gYnVpbGQgdGhlIGZvbGxvdyBwb3NpdGlvbgotICAgICAgICAvLyAgc2V0cyBmb3IgYWxsIHRoZSBub2Rlcy4gU28gd2UgYWxsb2NhdGUgYW4gYXJyYXkgb2Ygc3RhdGUgc2V0cywKLSAgICAgICAgLy8gIG9uZSBmb3IgZWFjaCBsZWFmIG5vZGUgKGkuZS4gZWFjaCBERkEgcG9zaXRpb24uKQotICAgICAgICAvLwotICAgICAgICBmRm9sbG93TGlzdCA9IG5ldyBDTVN0YXRlU2V0W2ZMZWFmQ291bnRdOwotICAgICAgICBmb3IgKGludCBpbmRleCA9IDA7IGluZGV4IDwgZkxlYWZDb3VudDsgaW5kZXgrKykKLSAgICAgICAgICAgIGZGb2xsb3dMaXN0W2luZGV4XSA9IG5ldyBDTVN0YXRlU2V0KGZMZWFmQ291bnQpOwotICAgICAgICBjYWxjRm9sbG93TGlzdChmSGVhZE5vZGUpOwotICAgICAgICAvLwotICAgICAgICAvLyAgQW5kIGZpbmFsbHkgdGhlIGJpZyBwdXNoLi4uIE5vdyB3ZSBidWlsZCB0aGUgREZBIHVzaW5nIGFsbCB0aGUKLSAgICAgICAgLy8gIHN0YXRlcyBhbmQgdGhlIHRyZWUgd2UndmUgYnVpbHQgdXAuIEZpcnN0IHdlIHNldCB1cCB0aGUgdmFyaW91cwotICAgICAgICAvLyAgZGF0YSBzdHJ1Y3R1cmVzIHdlIGFyZSBnb2luZyB0byB1c2Ugd2hpbGUgd2UgZG8gdGhpcy4KLSAgICAgICAgLy8KLSAgICAgICAgLy8gIEZpcnN0IG9mIGFsbCB3ZSBuZWVkIGFuIGFycmF5IG9mIHVuaXF1ZSBlbGVtZW50IG5hbWVzIGluIG91cgotICAgICAgICAvLyAgY29udGVudCBtb2RlbC4gRm9yIGVhY2ggdHJhbnNpdGlvbiB0YWJsZSBlbnRyeSwgd2UgbmVlZCBhIHNldCBvZgotICAgICAgICAvLyAgY29udGlndW91cyBpbmRpY2VzIHRvIHJlcHJlc2VudCB0aGUgdHJhbnNpdGlvbnMgZm9yIGEgcGFydGljdWxhcgotICAgICAgICAvLyAgaW5wdXQgZWxlbWVudC4gU28gd2UgbmVlZCB0byBhIHplcm8gYmFzZWQgcmFuZ2Ugb2YgaW5kZXhlcyB0aGF0Ci0gICAgICAgIC8vICBtYXAgdG8gZWxlbWVudCB0eXBlcy4gVGhpcyBlbGVtZW50IG1hcCBwcm92aWRlcyB0aGF0IG1hcHBpbmcuCi0gICAgICAgIC8vCi0gICAgICAgIGZFbGVtTWFwID0gbmV3IFFOYW1lW2ZMZWFmQ291bnRdOwotICAgICAgICBmRWxlbU1hcFR5cGUgPSBuZXcgaW50W2ZMZWFmQ291bnRdOwotICAgICAgICBmRWxlbU1hcFNpemUgPSAwOwotICAgICAgICBmb3IgKGludCBvdXRJbmRleCA9IDA7IG91dEluZGV4IDwgZkxlYWZDb3VudDsgb3V0SW5kZXgrKykKLSAgICAgICAgewotICAgICAgICAgICAgZkVsZW1NYXBbb3V0SW5kZXhdID0gbmV3IFFOYW1lKCk7Ci0KLSAgICAgICAgICAgIC8qKioqCi0gICAgICAgICAgICBpZiAoIChmTGVhZkxpc3RUeXBlW291dEluZGV4XSAmIDB4MGYpICE9IDAgKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGZMZWFmTmFtZVR5cGVWZWN0b3IgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBmTGVhZk5hbWVUeXBlVmVjdG9yID0gbmV3IENvbnRlbnRMZWFmTmFtZVR5cGVWZWN0b3IoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvKioqKi8KLQotICAgICAgICAgICAgLy8gR2V0IHRoZSBjdXJyZW50IGxlYWYncyBlbGVtZW50IGluZGV4Ci0gICAgICAgICAgICBmaW5hbCBRTmFtZSBlbGVtZW50ID0gZkxlYWZMaXN0W291dEluZGV4XS5nZXRFbGVtZW50KCk7Ci0KLSAgICAgICAgICAgIC8vIFNlZSBpZiB0aGUgY3VycmVudCBsZWFmIG5vZGUncyBlbGVtZW50IGluZGV4IGlzIGluIHRoZSBsaXN0Ci0gICAgICAgICAgICBpbnQgaW5JbmRleCA9IDA7Ci0gICAgICAgICAgICBmb3IgKDsgaW5JbmRleCA8IGZFbGVtTWFwU2l6ZTsgaW5JbmRleCsrKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIGlmIChmRWxlbU1hcFtpbkluZGV4XS5yYXduYW1lID09IGVsZW1lbnQucmF3bmFtZSkgewotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIElmIGl0IHdhcyBub3QgaW4gdGhlIGxpc3QsIHRoZW4gYWRkIGl0LCBpZiBub3QgdGhlIEVPQyBub2RlCi0gICAgICAgICAgICBpZiAoaW5JbmRleCA9PSBmRWxlbU1hcFNpemUpIHsKLSAgICAgICAgICAgICAgICBmRWxlbU1hcFtmRWxlbU1hcFNpemVdLnNldFZhbHVlcyhlbGVtZW50KTsKLSAgICAgICAgICAgICAgICBmRWxlbU1hcFR5cGVbZkVsZW1NYXBTaXplXSA9IGZMZWFmTGlzdFR5cGVbb3V0SW5kZXhdOwotICAgICAgICAgICAgICAgIGZFbGVtTWFwU2l6ZSsrOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIC8vIHNldCB1cCB0aGUgZkxlYWZOYW1lVHlwZVZlY3RvciBvYmplY3QgaWYgdGhlcmUgaXMgb25lLgotICAgICAgICAvKioqKioKLSAgICAgICAgaWYgKGZMZWFmTmFtZVR5cGVWZWN0b3IgIT0gbnVsbCkgewotICAgICAgICAgICAgZkxlYWZOYW1lVHlwZVZlY3Rvci5zZXRWYWx1ZXMoZkVsZW1NYXAsIGZFbGVtTWFwVHlwZSwgZkVsZW1NYXBTaXplKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKioKLSAgICAgICAgKiBPcHRpbWl6YXRpb24oSmFuLCAyMDAxKTsgV2Ugc29ydCBmTGVhZkxpc3QgYWNjb3JkaW5nIHRvCi0gICAgICAgICogZWxlbUluZGV4IHdoaWNoIGlzICp1bmlxdWVseSogYXNzb2NpYXRlZCB0byBlYWNoIGxlYWYuCi0gICAgICAgICogV2UgYXJlICphc3N1bWluZyogdGhhdCBlYWNoIGVsZW1lbnQgYXBwZWFycyBpbiBhdCBsZWFzdCBvbmUgbGVhZi4KLSAgICAgICAgKiovCi0KLSAgICAgICAgaW50W10gZkxlYWZTb3J0ZXIgPSBuZXcgaW50W2ZMZWFmQ291bnQgKyBmRWxlbU1hcFNpemVdOwotICAgICAgICBpbnQgZlNvcnRDb3VudCA9IDA7Ci0KLSAgICAgICAgZm9yIChpbnQgZWxlbUluZGV4ID0gMDsgZWxlbUluZGV4IDwgZkVsZW1NYXBTaXplOyBlbGVtSW5kZXgrKykgewotICAgICAgICAgICAgZm9yIChpbnQgbGVhZkluZGV4ID0gMDsgbGVhZkluZGV4IDwgZkxlYWZDb3VudDsgbGVhZkluZGV4KyspIHsKLSAgICAgICAgICAgICAgICAgICAgZmluYWwgUU5hbWUgbGVhZiA9IGZMZWFmTGlzdFtsZWFmSW5kZXhdLmdldEVsZW1lbnQoKTsKLSAgICAgICAgICAgICAgICAgICAgZmluYWwgUU5hbWUgZWxlbWVudCA9IGZFbGVtTWFwW2VsZW1JbmRleF07Ci0gICAgICAgICAgICAgICAgICAgIGlmIChsZWFmLnJhd25hbWUgPT0gZWxlbWVudC5yYXduYW1lKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZkxlYWZTb3J0ZXJbZlNvcnRDb3VudCsrXSA9IGxlYWZJbmRleDsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZkxlYWZTb3J0ZXJbZlNvcnRDb3VudCsrXSA9IC0xOwotICAgICAgICB9Ci0KLSAgICAgICAgLyogT3B0aW1pemF0aW9uKEphbiwgMjAwMSkgKi8KLQotICAgICAgICAvLwotICAgICAgICAvLyAgTmV4dCBsZXRzIGNyZWF0ZSBzb21lIGFycmF5cywgc29tZSB0aGF0IHRoYXQgaG9sZCB0cmFuc2llbnQKLSAgICAgICAgLy8gIGluZm9ybWF0aW9uIGR1cmluZyB0aGUgREZBIGJ1aWxkIGFuZCBzb21lIHRoYXQgYXJlIHBlcm1hbWVudC4KLSAgICAgICAgLy8gIFRoZXNlIGFyZSBraW5kIG9mIHN0aWNreSBzaW5jZSB3ZSBjYW5ub3Qga25vdyBob3cgYmlnIHRoZXkgd2lsbAotICAgICAgICAvLyAgZ2V0LCBidXQgd2UgZG9uJ3Qgd2FudCB0byB1c2UgYW55IEphdmEgY29sbGVjdGlvbnMgYmVjYXVzZSBvZgotICAgICAgICAvLyAgcGVyZm9ybWFuY2UuCi0gICAgICAgIC8vCi0gICAgICAgIC8vICBCYXNpY2FsbHkgdGhleSB3aWxsIHByb2JhYmx5IGJlIGFib3V0IGZMZWFmQ291bnQqMiBvbiBhdmVyYWdlLAotICAgICAgICAvLyAgYnV0IGNhbiBiZSBhcyBsYXJnZSBhcyAyXihmTGVhZkNvdW50KjIpLCB3b3JzdCBjYXNlLiBTbyB3ZSBzdGFydAotICAgICAgICAvLyAgd2l0aCBmTGVhZkNvdW50KjQgYXMgYSBtaWRkbGUgZ3JvdW5kLiBUaGlzIHdpbGwgYmUgdmVyeSB1bmxpa2VseQotICAgICAgICAvLyAgdG8gZXZlciBoYXZlIHRvIGV4cGFuZCwgdGhvdWdoIGl0IGlmIGRvZXMsIHRoZSBvdmVyaGVhZCB3aWxsIGJlCi0gICAgICAgIC8vICBzb21ld2hhdCB1Z2x5LgotICAgICAgICAvLwotICAgICAgICBpbnQgY3VyQXJyYXlTaXplID0gZkxlYWZDb3VudCAqIDQ7Ci0gICAgICAgIENNU3RhdGVTZXRbXSBzdGF0ZXNUb0RvID0gbmV3IENNU3RhdGVTZXRbY3VyQXJyYXlTaXplXTsKLSAgICAgICAgZkZpbmFsU3RhdGVGbGFncyA9IG5ldyBib29sZWFuW2N1ckFycmF5U2l6ZV07Ci0gICAgICAgIGZUcmFuc1RhYmxlID0gbmV3IGludFtjdXJBcnJheVNpemVdW107Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gIE9rIHdlIHN0YXJ0IHdpdGggdGhlIGluaXRpYWwgc2V0IGFzIHRoZSBmaXJzdCBwb3Mgc2V0IG9mIHRoZQotICAgICAgICAvLyAgaGVhZCBub2RlICh3aGljaCBpcyB0aGUgc2VxIG5vZGUgdGhhdCBob2xkcyB0aGUgY29udGVudCBtb2RlbAotICAgICAgICAvLyAgYW5kIHRoZSBFT0Mgbm9kZS4pCi0gICAgICAgIC8vCi0gICAgICAgIENNU3RhdGVTZXQgc2V0VCA9IGZIZWFkTm9kZS5maXJzdFBvcygpOwotCi0gICAgICAgIC8vCi0gICAgICAgIC8vICBJbml0IG91ciB0d28gc3RhdGUgZmxhZ3MuIEJhc2ljYWxseSB0aGUgdW5tYXJrZWQgc3RhdGUgY291bnRlcgotICAgICAgICAvLyAgaXMgYWx3YXlzIGNoYXNpbmcgdGhlIGN1cnJlbnQgc3RhdGUgY291bnRlci4gV2hlbiBpdCBjYXRjaGVzIHVwLAotICAgICAgICAvLyAgdGhhdCBtZWFucyB3ZSBtYWRlIGEgcGFzcyB0aHJvdWdoIHRoYXQgZGlkIG5vdCBhZGQgYW55IG5ldyBzdGF0ZXMKLSAgICAgICAgLy8gIHRvIHRoZSBsaXN0cywgYXQgd2hpY2ggdGltZSB3ZSBhcmUgZG9uZS4gV2UgY291bGQgaGF2ZSB1c2VkIGEKLSAgICAgICAgLy8gIGV4cGFuZGluZyBhcnJheSBvZiBmbGFncyB3aGljaCB3ZSB1c2VkIHRvIG1hcmsgb2ZmIHN0YXRlcyBhcyB3ZQotICAgICAgICAvLyAgY29tcGxldGUgdGhlbSwgYnV0IHRoaXMgaXMgZWFzaWVyIHRob3VnaCBsZXNzIHJlYWRhYmxlIG1heWJlLgotICAgICAgICAvLwotICAgICAgICBpbnQgdW5tYXJrZWRTdGF0ZSA9IDA7Ci0gICAgICAgIGludCBjdXJTdGF0ZSA9IDA7Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gIEluaXQgdGhlIGZpcnN0IHRyYW5zaXRpb24gdGFibGUgZW50cnksIGFuZCBwdXQgdGhlIGluaXRpYWwgc3RhdGUKLSAgICAgICAgLy8gIGludG8gdGhlIHN0YXRlcyB0byBkbyBsaXN0LCB0aGVuIGJ1bXAgdGhlIGN1cnJlbnQgc3RhdGUuCi0gICAgICAgIC8vCi0gICAgICAgIGZUcmFuc1RhYmxlW2N1clN0YXRlXSA9IG1ha2VEZWZTdGF0ZUxpc3QoKTsKLSAgICAgICAgc3RhdGVzVG9Eb1tjdXJTdGF0ZV0gPSBzZXRUOwotICAgICAgICBjdXJTdGF0ZSsrOwotCi0gICAgICAgICAgICAvKiBPcHRpbWl6YXRpb24oSmFuLCAyMDAxKTsgVGhpcyBpcyBmYXN0ZXIgZm9yCi0gICAgICAgICAgICAgKiBhIGxhcmdlIGNvbnRlbnQgbW9kZWwgc3VjaCBhcywgIih0MDAxK3x0MDAyK3wuLi4uIHx0NTAwKykiLgotICAgICAgICAgICAgICovCi0KLSAgICAgICAgSGFzaE1hcCBzdGF0ZVRhYmxlID0gbmV3IEhhc2hNYXAoKTsKLQotICAgICAgICAgICAgLyogT3B0aW1pemF0aW9uKEphbiwgMjAwMSkgKi8KLQotICAgICAgICAvLwotICAgICAgICAvLyAgT2ssIGFsbW9zdCBkb25lIHdpdGggdGhlIGFsZ29yaXRobS4uLiBXZSBub3cgZW50ZXIgdGhlCi0gICAgICAgIC8vICBsb29wIHdoZXJlIHdlIGdvIHVudGlsIHRoZSBzdGF0ZXMgZG9uZSBjb3VudGVyIGNhdGNoZXMgdXAgd2l0aAotICAgICAgICAvLyAgdGhlIHN0YXRlcyB0byBkbyBjb3VudGVyLgotICAgICAgICAvLwotICAgICAgICB3aGlsZSAodW5tYXJrZWRTdGF0ZSA8IGN1clN0YXRlKQotICAgICAgICB7Ci0gICAgICAgICAgICAvLwotICAgICAgICAgICAgLy8gIEdldCB0aGUgZmlyc3QgdW5tYXJrZWQgc3RhdGUgb3V0IG9mIHRoZSBsaXN0IG9mIHN0YXRlcyB0byBkby4KLSAgICAgICAgICAgIC8vICBBbmQgZ2V0IHRoZSBhc3NvY2lhdGVkIHRyYW5zaXRpb24gdGFibGUgZW50cnkuCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgc2V0VCA9IHN0YXRlc1RvRG9bdW5tYXJrZWRTdGF0ZV07Ci0gICAgICAgICAgICBpbnRbXSB0cmFuc0VudHJ5ID0gZlRyYW5zVGFibGVbdW5tYXJrZWRTdGF0ZV07Ci0KLSAgICAgICAgICAgIC8vIE1hcmsgdGhpcyBvbmUgZmluYWwgaWYgaXQgY29udGFpbnMgdGhlIEVPQyBzdGF0ZQotICAgICAgICAgICAgZkZpbmFsU3RhdGVGbGFnc1t1bm1hcmtlZFN0YXRlXSA9IHNldFQuZ2V0Qml0KGZFT0NQb3MpOwotCi0gICAgICAgICAgICAvLyBCdW1wIHVwIHRoZSB1bm1hcmtlZCBzdGF0ZSBjb3VudCwgbWFya2luZyB0aGlzIHN0YXRlIGRvbmUKLSAgICAgICAgICAgIHVubWFya2VkU3RhdGUrKzsKLQotICAgICAgICAgICAgLy8gTG9vcCB0aHJvdWdoIGVhY2ggcG9zc2libGUgaW5wdXQgc3ltYm9sIGluIHRoZSBlbGVtZW50IG1hcAotICAgICAgICAgICAgQ01TdGF0ZVNldCBuZXdTZXQgPSBudWxsOwotICAgICAgICAgICAgLyogT3B0aW1pemF0aW9uKEphbiwgMjAwMSkgKi8KLSAgICAgICAgICAgIGludCBzb3J0ZXJJbmRleCA9IDA7Ci0gICAgICAgICAgICAvKiBPcHRpbWl6YXRpb24oSmFuLCAyMDAxKSAqLwotICAgICAgICAgICAgZm9yIChpbnQgZWxlbUluZGV4ID0gMDsgZWxlbUluZGV4IDwgZkVsZW1NYXBTaXplOyBlbGVtSW5kZXgrKykKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgIC8vICBCdWlsZCB1cCBhIHNldCBvZiBzdGF0ZXMgd2hpY2ggaXMgdGhlIHVuaW9uIG9mIGFsbCBvZgotICAgICAgICAgICAgICAgIC8vICB0aGUgZm9sbG93IHNldHMgb2YgREZBIHBvc2l0aW9ucyB0aGF0IGFyZSBpbiB0aGUgY3VycmVudAotICAgICAgICAgICAgICAgIC8vICBzdGF0ZS4gSWYgd2UgZ2F2ZSBhd2F5IHRoZSBuZXcgc2V0IGxhc3QgdGltZSB0aHJvdWdoIHRoZW4KLSAgICAgICAgICAgICAgICAvLyAgY3JlYXRlIGEgbmV3IG9uZS4gT3RoZXJ3aXNlLCB6ZXJvIG91dCB0aGUgZXhpc3Rpbmcgb25lLgotICAgICAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAgICAgaWYgKG5ld1NldCA9PSBudWxsKQotICAgICAgICAgICAgICAgICAgICBuZXdTZXQgPSBuZXcgQ01TdGF0ZVNldChmTGVhZkNvdW50KTsKLSAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgIG5ld1NldC56ZXJvQml0cygpOwotCi0gICAgICAgICAgICAvKiBPcHRpbWl6YXRpb24oSmFuLCAyMDAxKSAqLwotICAgICAgICAgICAgICAgIGludCBsZWFmSW5kZXggPSBmTGVhZlNvcnRlcltzb3J0ZXJJbmRleCsrXTsKLQotICAgICAgICAgICAgICAgIHdoaWxlIChsZWFmSW5kZXggIT0gLTEpIHsKLSAgICAgICAgICAgICAgICAvLyBJZiB0aGlzIGxlYWYgaW5kZXggKERGQSBwb3NpdGlvbikgaXMgaW4gdGhlIGN1cnJlbnQgc2V0Li4uCi0gICAgICAgICAgICAgICAgICAgIGlmIChzZXRULmdldEJpdChsZWFmSW5kZXgpKQotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgICAgICAgICAgLy8gIElmIHRoaXMgbGVhZiBpcyB0aGUgY3VycmVudCBpbnB1dCBzeW1ib2wsIHRoZW4gd2UKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vICB3YW50IHRvIGFkZCBpdHMgZm9sbG93IGxpc3QgdG8gdGhlIHNldCBvZiBzdGF0ZXMgdG8KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vICB0cmFuc2l0aW9uIHRvIGZyb20gdGhlIGN1cnJlbnQgc3RhdGUuCi0gICAgICAgICAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdTZXQudW5pb24oZkZvbGxvd0xpc3RbbGVhZkluZGV4XSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgbGVhZkluZGV4ID0gZkxlYWZTb3J0ZXJbc29ydGVySW5kZXgrK107Ci0gICAgICAgIH0KLSAgICAgICAgICAgIC8qIE9wdGltaXphdGlvbihKYW4sIDIwMDEpICovCi0KLSAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgIC8vICBJZiB0aGlzIG5ldyBzZXQgaXMgbm90IGVtcHR5LCB0aGVuIHNlZSBpZiBpdHMgaW4gdGhlIGxpc3QKLSAgICAgICAgICAgICAgICAvLyAgb2Ygc3RhdGVzIHRvIGRvLiBJZiBub3QsIHRoZW4gYWRkIGl0LgotICAgICAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAgICAgaWYgKCFuZXdTZXQuaXNFbXB0eSgpKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICAgICAgLy8gIFNlYXJjaCB0aGUgJ3N0YXRlcyB0byBkbycgbGlzdCB0byBzZWUgaWYgdGhpcyBuZXcKLSAgICAgICAgICAgICAgICAgICAgLy8gIHN0YXRlIHNldCBpcyBhbHJlYWR5IGluIHRoZXJlLgotICAgICAgICAgICAgICAgICAgICAvLwotCi0gICAgICAgICAgICAvKiBPcHRpbWl6YXRpb24oSmFuLCAyMDAxKSAqLwotICAgICAgICAgICAgSW50ZWdlciBzdGF0ZU9iaiA9IChJbnRlZ2VyKXN0YXRlVGFibGUuZ2V0KG5ld1NldCk7Ci0gICAgICAgICAgICBpbnQgc3RhdGVJbmRleCA9IChzdGF0ZU9iaiA9PSBudWxsID8gY3VyU3RhdGUgOiBzdGF0ZU9iai5pbnRWYWx1ZSgpKTsKLSAgICAgICAgICAgIC8qIE9wdGltaXphdGlvbihKYW4sIDIwMDEpICovCi0KLSAgICAgICAgICAgICAgICAgICAgLy8gSWYgd2UgZGlkIG5vdCBmaW5kIGl0LCB0aGVuIGFkZCBpdAotICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdGVJbmRleCA9PSBjdXJTdGF0ZSkKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vICBQdXQgdGhpcyBuZXcgc3RhdGUgaW50byB0aGUgc3RhdGVzIHRvIGRvIGFuZCBpbml0Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyAgYSBuZXcgZW50cnkgYXQgdGhlIHNhbWUgaW5kZXggaW4gdGhlIHRyYW5zaXRpb24KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vICB0YWJsZS4KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAgICAgICAgICAgICBzdGF0ZXNUb0RvW2N1clN0YXRlXSA9IG5ld1NldDsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZUcmFuc1RhYmxlW2N1clN0YXRlXSA9IG1ha2VEZWZTdGF0ZUxpc3QoKTsKLQotICAgICAgICAgICAgLyogT3B0aW1pemF0aW9uKEphbiwgMjAwMSkgKi8KLSAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlVGFibGUucHV0KG5ld1NldCwgbmV3IEludGVnZXIoY3VyU3RhdGUpKTsKLSAgICAgICAgICAgIC8qIE9wdGltaXphdGlvbihKYW4sIDIwMDEpICovCi0KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdlIG5vdyBoYXZlIGEgbmV3IHN0YXRlIHRvIGRvIHNvIGJ1bXAgdGhlIGNvdW50Ci0gICAgICAgICAgICAgICAgICAgICAgICBjdXJTdGF0ZSsrOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgICAgICAgICAgLy8gIE51bGwgb3V0IHRoZSBuZXcgc2V0IHRvIGluZGljYXRlIHdlIGFkb3B0ZWQgaXQuCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyAgVGhpcyB3aWxsIGNhdXNlIHRoZSBjcmVhdGlvbiBvZiBhIG5ldyBzZXQgb24gdGhlCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyAgbmV4dCB0aW1lIGFyb3VuZCB0aGUgbG9vcC4KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAgICAgICAgICAgICBuZXdTZXQgPSBudWxsOwotICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICAgICAgLy8gIE5vdyBzZXQgdGhpcyBzdGF0ZSBpbiB0aGUgdHJhbnNpdGlvbiB0YWJsZSdzIGVudHJ5Ci0gICAgICAgICAgICAgICAgICAgIC8vICBmb3IgdGhpcyBlbGVtZW50ICh1c2luZyBpdHMgaW5kZXgpLCB3aXRoIHRoZSBERkEKLSAgICAgICAgICAgICAgICAgICAgLy8gIHN0YXRlIHdlIHdpbGwgbW92ZSB0byBmcm9tIHRoZSBjdXJyZW50IHN0YXRlIHdoZW4gd2UKLSAgICAgICAgICAgICAgICAgICAgLy8gIHNlZSB0aGlzIGlucHV0IGVsZW1lbnQuCi0gICAgICAgICAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAgICAgICAgIHRyYW5zRW50cnlbZWxlbUluZGV4XSA9IHN0YXRlSW5kZXg7Ci0KLSAgICAgICAgICAgICAgICAgICAgLy8gRXhwYW5kIHRoZSBhcnJheXMgaWYgd2UncmUgZnVsbAotICAgICAgICAgICAgICAgICAgICBpZiAoY3VyU3RhdGUgPT0gY3VyQXJyYXlTaXplKQotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgICAgICAgICAgLy8gIFlpa2VzLCB3ZSBvdmVyZmxvd2VkIHRoZSBpbml0aWFsIGFycmF5IHNpemUsIHNvCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyAgd2UndmUgZ290IHRvIGV4cGFuZCBhbGwgb2YgdGhlc2UgYXJyYXlzLiBTbyBhZGp1c3QKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vICB1cCB0aGUgc2l6ZSBieSA1MCUgYW5kIGFsbG9jYXRlIG5ldyBhcnJheXMuCi0gICAgICAgICAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IG5ld1NpemUgPSAoaW50KShjdXJBcnJheVNpemUgKiAxLjUpOwotICAgICAgICAgICAgICAgICAgICAgICAgQ01TdGF0ZVNldFtdIG5ld1RvRG8gPSBuZXcgQ01TdGF0ZVNldFtuZXdTaXplXTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW5bXSBuZXdGaW5hbEZsYWdzID0gbmV3IGJvb2xlYW5bbmV3U2l6ZV07Ci0gICAgICAgICAgICAgICAgICAgICAgICBpbnRbXVtdIG5ld1RyYW5zVGFibGUgPSBuZXcgaW50W25ld1NpemVdW107Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIENvcHkgb3ZlciBhbGwgb2YgdGhlIGV4aXN0aW5nIGNvbnRlbnQKLSAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoc3RhdGVzVG9EbywgMCwgbmV3VG9EbywgMCwgY3VyQXJyYXlTaXplKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZkZpbmFsU3RhdGVGbGFncywgMCwgbmV3RmluYWxGbGFncywgMCwgY3VyQXJyYXlTaXplKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZlRyYW5zVGFibGUsIDAsIG5ld1RyYW5zVGFibGUsIDAsIGN1ckFycmF5U2l6ZSk7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIFN0b3JlIHRoZSBuZXcgYXJyYXkgc2l6ZQotICAgICAgICAgICAgICAgICAgICAgICAgY3VyQXJyYXlTaXplID0gbmV3U2l6ZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlc1RvRG8gPSBuZXdUb0RvOwotICAgICAgICAgICAgICAgICAgICAgICAgZkZpbmFsU3RhdGVGbGFncyA9IG5ld0ZpbmFsRmxhZ3M7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmVHJhbnNUYWJsZSA9IG5ld1RyYW5zVGFibGU7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBDaGVjayB0byBzZWUgaWYgd2UgY2FuIHNldCB0aGUgZkVtcHR5Q29udGVudElzVmFsaWQgZmxhZy4KLSAgICAgICAgZkVtcHR5Q29udGVudElzVmFsaWQgPSAoKENNQmluT3ApZkhlYWROb2RlKS5nZXRMZWZ0KCkuaXNOdWxsYWJsZSgpOwotCi0gICAgICAgIC8vCi0gICAgICAgIC8vICBBbmQgbm93IHdlIGNhbiBzYXkgYnllIGJ5ZSB0byB0aGUgdGVtcCByZXByZXNlbnRhdGlvbiBzaW5jZSB3ZSd2ZQotICAgICAgICAvLyAgYnVpbHQgdGhlIERGQS4KLSAgICAgICAgLy8KLSAgICAgICAgaWYgKERFQlVHX1ZBTElEQVRFX0NPTlRFTlQpCi0gICAgICAgICAgICBkdW1wVHJlZShmSGVhZE5vZGUsIDApOwotICAgICAgICBmSGVhZE5vZGUgPSBudWxsOwotICAgICAgICBmTGVhZkxpc3QgPSBudWxsOwotICAgICAgICBmRm9sbG93TGlzdCA9IG51bGw7Ci0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDYWxjdWxhdGVzIHRoZSBmb2xsb3cgbGlzdCBvZiB0aGUgY3VycmVudCBub2RlLgotICAgICAqCi0gICAgICogQHBhcmFtIG5vZGVDdXIgVGhlIGN1cmVudCBub2RlLgotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBDTUV4Y2VwdGlvbiBUaHJvd24gaWYgZm9sbG93IGxpc3QgY2Fubm90IGJlIGNhbGN1bGF0ZWQuCi0gICAgICovCi0gICAgcHJpdmF0ZSB2b2lkIGNhbGNGb2xsb3dMaXN0KENNTm9kZSBub2RlQ3VyKQotICAgIHsKLSAgICAgICAgLy8gUmVjdXJzZSBhcyByZXF1aXJlZAotICAgICAgICBpZiAobm9kZUN1ci50eXBlKCkgPT0gWE1MQ29udGVudFNwZWMuQ09OVEVOVFNQRUNOT0RFX0NIT0lDRSkKLSAgICAgICAgewotICAgICAgICAgICAgLy8gUmVjdXJzZSBvbmx5Ci0gICAgICAgICAgICBjYWxjRm9sbG93TGlzdCgoKENNQmluT3Apbm9kZUN1cikuZ2V0TGVmdCgpKTsKLSAgICAgICAgICAgIGNhbGNGb2xsb3dMaXN0KCgoQ01CaW5PcClub2RlQ3VyKS5nZXRSaWdodCgpKTsKLSAgICAgICAgfQotICAgICAgICAgZWxzZSBpZiAobm9kZUN1ci50eXBlKCkgPT0gWE1MQ29udGVudFNwZWMuQ09OVEVOVFNQRUNOT0RFX1NFUSkKLSAgICAgICAgewotICAgICAgICAgICAgLy8gUmVjdXJzZSBmaXJzdAotICAgICAgICAgICAgY2FsY0ZvbGxvd0xpc3QoKChDTUJpbk9wKW5vZGVDdXIpLmdldExlZnQoKSk7Ci0gICAgICAgICAgICBjYWxjRm9sbG93TGlzdCgoKENNQmluT3Apbm9kZUN1cikuZ2V0UmlnaHQoKSk7Ci0KLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAvLyAgTm93IGhhbmRsZSBvdXIgbGV2ZWwuIFdlIHVzZSBvdXIgbGVmdCBjaGlsZCdzIGxhc3QgcG9zCi0gICAgICAgICAgICAvLyAgc2V0IGFuZCBvdXIgcmlnaHQgY2hpbGQncyBmaXJzdCBwb3Mgc2V0LCBzbyBnbyBhaGVhZCBhbmQKLSAgICAgICAgICAgIC8vICBnZXQgdGhlbSBhaGVhZCBvZiB0aW1lLgotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIGZpbmFsIENNU3RhdGVTZXQgbGFzdCAgPSAoKENNQmluT3Apbm9kZUN1cikuZ2V0TGVmdCgpLmxhc3RQb3MoKTsKLSAgICAgICAgICAgIGZpbmFsIENNU3RhdGVTZXQgZmlyc3QgPSAoKENNQmluT3Apbm9kZUN1cikuZ2V0UmlnaHQoKS5maXJzdFBvcygpOwotCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgLy8gIE5vdywgZm9yIGV2ZXJ5IHBvc2l0aW9uIHdoaWNoIGlzIGluIG91ciBsZWZ0IGNoaWxkJ3MgbGFzdCBzZXQKLSAgICAgICAgICAgIC8vICBhZGQgYWxsIG9mIHRoZSBzdGF0ZXMgaW4gb3VyIHJpZ2h0IGNoaWxkJ3MgZmlyc3Qgc2V0IHRvIHRoZQotICAgICAgICAgICAgLy8gIGZvbGxvdyBzZXQgZm9yIHRoYXQgcG9zaXRpb24uCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgZm9yIChpbnQgaW5kZXggPSAwOyBpbmRleCA8IGZMZWFmQ291bnQ7IGluZGV4KyspCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgaWYgKGxhc3QuZ2V0Qml0KGluZGV4KSkKLSAgICAgICAgICAgICAgICAgICAgZkZvbGxvd0xpc3RbaW5kZXhdLnVuaW9uKGZpcnN0KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICAgLyoqKgotICAgICAgICAgZWxzZSBpZiAobm9kZUN1ci50eXBlKCkgPT0gWE1MQ29udGVudFNwZWMuQ09OVEVOVFNQRUNOT0RFX1pFUk9fT1JfTU9SRSkKLSAgICAgICAgewotICAgICAgICAgICAgLy8gUmVjdXJzZSBmaXJzdAotICAgICAgICAgICAgY2FsY0ZvbGxvd0xpc3QoKChDTVVuaU9wKW5vZGVDdXIpLmdldENoaWxkKCkpOwotCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgLy8gIE5vdyBoYW5kbGUgb3VyIGxldmVsLiBXZSB1c2Ugb3VyIG93biBmaXJzdCBhbmQgbGFzdCBwb3NpdGlvbgotICAgICAgICAgICAgLy8gIHNldHMsIHNvIGdldCB0aGVtIHVwIGZyb250LgotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIGZpbmFsIENNU3RhdGVTZXQgZmlyc3QgPSBub2RlQ3VyLmZpcnN0UG9zKCk7Ci0gICAgICAgICAgICBmaW5hbCBDTVN0YXRlU2V0IGxhc3QgID0gbm9kZUN1ci5sYXN0UG9zKCk7Ci0KLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAvLyAgRm9yIGV2ZXJ5IHBvc2l0aW9uIHdoaWNoIGlzIGluIG91ciBsYXN0IHBvc2l0aW9uIHNldCwgYWRkIGFsbAotICAgICAgICAgICAgLy8gIG9mIG91ciBmaXJzdCBwb3NpdGlvbiBzdGF0ZXMgdG8gdGhlIGZvbGxvdyBzZXQgZm9yIHRoYXQKLSAgICAgICAgICAgIC8vICBwb3NpdGlvbi4KLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICBmb3IgKGludCBpbmRleCA9IDA7IGluZGV4IDwgZkxlYWZDb3VudDsgaW5kZXgrKykKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBpZiAobGFzdC5nZXRCaXQoaW5kZXgpKQotICAgICAgICAgICAgICAgICAgICBmRm9sbG93TGlzdFtpbmRleF0udW5pb24oZmlyc3QpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgICBlbHNlIGlmICgobm9kZUN1ci50eXBlKCkgPT0gWE1MQ29udGVudFNwZWMuQ09OVEVOVFNQRUNOT0RFX09ORV9PUl9NT1JFKQotICAgICAgICAgICAgICB8fCAgKG5vZGVDdXIudHlwZSgpID09IFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9aRVJPX09SX09ORSkpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJJbXBsZW1lbnRhdGlvbk1lc3NhZ2VzLlZBTF9OSUlDTSIpOwotICAgICAgICB9Ci0gICAgICAgIC8qKiovCi0gICAgICAgICBlbHNlIGlmIChub2RlQ3VyLnR5cGUoKSA9PSBYTUxDb250ZW50U3BlYy5DT05URU5UU1BFQ05PREVfWkVST19PUl9NT1JFCi0gICAgICAgICAgICB8fCBub2RlQ3VyLnR5cGUoKSA9PSBYTUxDb250ZW50U3BlYy5DT05URU5UU1BFQ05PREVfT05FX09SX01PUkUpCi0gICAgICAgIHsKLSAgICAgICAgICAgIC8vIFJlY3Vyc2UgZmlyc3QKLSAgICAgICAgICAgIGNhbGNGb2xsb3dMaXN0KCgoQ01VbmlPcClub2RlQ3VyKS5nZXRDaGlsZCgpKTsKLQotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIC8vICBOb3cgaGFuZGxlIG91ciBsZXZlbC4gV2UgdXNlIG91ciBvd24gZmlyc3QgYW5kIGxhc3QgcG9zaXRpb24KLSAgICAgICAgICAgIC8vICBzZXRzLCBzbyBnZXQgdGhlbSB1cCBmcm9udC4KLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICBmaW5hbCBDTVN0YXRlU2V0IGZpcnN0ID0gbm9kZUN1ci5maXJzdFBvcygpOwotICAgICAgICAgICAgZmluYWwgQ01TdGF0ZVNldCBsYXN0ICA9IG5vZGVDdXIubGFzdFBvcygpOwotCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgLy8gIEZvciBldmVyeSBwb3NpdGlvbiB3aGljaCBpcyBpbiBvdXIgbGFzdCBwb3NpdGlvbiBzZXQsIGFkZCBhbGwKLSAgICAgICAgICAgIC8vICBvZiBvdXIgZmlyc3QgcG9zaXRpb24gc3RhdGVzIHRvIHRoZSBmb2xsb3cgc2V0IGZvciB0aGF0Ci0gICAgICAgICAgICAvLyAgcG9zaXRpb24uCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgZm9yIChpbnQgaW5kZXggPSAwOyBpbmRleCA8IGZMZWFmQ291bnQ7IGluZGV4KyspCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgaWYgKGxhc3QuZ2V0Qml0KGluZGV4KSkKLSAgICAgICAgICAgICAgICAgICAgZkZvbGxvd0xpc3RbaW5kZXhdLnVuaW9uKGZpcnN0KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGVsc2UgaWYgKG5vZGVDdXIudHlwZSgpID09IFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9aRVJPX09SX09ORSkgewotICAgICAgICAgICAgLy8gUmVjdXJzZSBvbmx5Ci0gICAgICAgICAgICBjYWxjRm9sbG93TGlzdCgoKENNVW5pT3Apbm9kZUN1cikuZ2V0Q2hpbGQoKSk7Ci0gICAgICAgIH0KLSAgICAgICAgIC8qKiovCi0gICAgfQotCi0gICAgLyoqCi0gICAgICogRHVtcHMgdGhlIHRyZWUgb2YgdGhlIGN1cnJlbnQgbm9kZSB0byBzdGFuZGFyZCBvdXRwdXQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbm9kZUN1ciBUaGUgY3VycmVudCBub2RlLgotICAgICAqIEBwYXJhbSBsZXZlbCAgIFRoZSBtYXhpbXVtIGxldmVscyB0byBvdXRwdXQuCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIENNRXhjZXB0aW9uIFRocm93biBvbiBlcnJvci4KLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgZHVtcFRyZWUoQ01Ob2RlIG5vZGVDdXIsIGludCBsZXZlbCkKLSAgICB7Ci0gICAgICAgIGZvciAoaW50IGluZGV4ID0gMDsgaW5kZXggPCBsZXZlbDsgaW5kZXgrKykKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIiAgICIpOwotCi0gICAgICAgIGludCB0eXBlID0gbm9kZUN1ci50eXBlKCk7Ci0gICAgICAgIGlmICgodHlwZSA9PSBYTUxDb250ZW50U3BlYy5DT05URU5UU1BFQ05PREVfQ0hPSUNFKQotICAgICAgICB8fCAgKHR5cGUgPT0gWE1MQ29udGVudFNwZWMuQ09OVEVOVFNQRUNOT0RFX1NFUSkpCi0gICAgICAgIHsKLSAgICAgICAgICAgIGlmICh0eXBlID09IFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9DSE9JQ0UpCi0gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiQ2hvaWNlIE5vZGUgIik7Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiU2VxIE5vZGUgIik7Ci0KLSAgICAgICAgICAgIGlmIChub2RlQ3VyLmlzTnVsbGFibGUoKSkKLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCJOdWxsYWJsZSAiKTsKLQotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiZmlyc3RQb3M9Iik7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KG5vZGVDdXIuZmlyc3RQb3MoKS50b1N0cmluZygpKTsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIiBsYXN0UG9zPSIpOwotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKG5vZGVDdXIubGFzdFBvcygpLnRvU3RyaW5nKCkpOwotCi0gICAgICAgICAgICBkdW1wVHJlZSgoKENNQmluT3Apbm9kZUN1cikuZ2V0TGVmdCgpLCBsZXZlbCsxKTsKLSAgICAgICAgICAgIGR1bXBUcmVlKCgoQ01CaW5PcClub2RlQ3VyKS5nZXRSaWdodCgpLCBsZXZlbCsxKTsKLSAgICAgICAgfQotICAgICAgICAgZWxzZSBpZiAobm9kZUN1ci50eXBlKCkgPT0gWE1MQ29udGVudFNwZWMuQ09OVEVOVFNQRUNOT0RFX1pFUk9fT1JfTU9SRSkKLSAgICAgICAgewotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiUmVwIE5vZGUgIik7Ci0KLSAgICAgICAgICAgIGlmIChub2RlQ3VyLmlzTnVsbGFibGUoKSkKLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCJOdWxsYWJsZSAiKTsKLQotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiZmlyc3RQb3M9Iik7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KG5vZGVDdXIuZmlyc3RQb3MoKS50b1N0cmluZygpKTsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIiBsYXN0UG9zPSIpOwotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKG5vZGVDdXIubGFzdFBvcygpLnRvU3RyaW5nKCkpOwotCi0gICAgICAgICAgICBkdW1wVHJlZSgoKENNVW5pT3Apbm9kZUN1cikuZ2V0Q2hpbGQoKSwgbGV2ZWwrMSk7Ci0gICAgICAgIH0KLSAgICAgICAgIGVsc2UgaWYgKG5vZGVDdXIudHlwZSgpID09IFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9MRUFGKQotICAgICAgICB7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50Ci0gICAgICAgICAgICAoCi0gICAgICAgICAgICAgICAgIkxlYWY6IChwb3M9IgotICAgICAgICAgICAgICAgICsgKChDTUxlYWYpbm9kZUN1cikuZ2V0UG9zaXRpb24oKQotICAgICAgICAgICAgICAgICsgIiksICIKLSAgICAgICAgICAgICAgICArICgoQ01MZWFmKW5vZGVDdXIpLmdldEVsZW1lbnQoKQotICAgICAgICAgICAgICAgICsgIihlbGVtSW5kZXg9IgotICAgICAgICAgICAgICAgICsgKChDTUxlYWYpbm9kZUN1cikuZ2V0RWxlbWVudCgpCi0gICAgICAgICAgICAgICAgKyAiKSAiCi0gICAgICAgICAgICApOwotCi0gICAgICAgICAgICBpZiAobm9kZUN1ci5pc051bGxhYmxlKCkpCi0gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiIE51bGxhYmxlICIpOwotCi0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCJmaXJzdFBvcz0iKTsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQobm9kZUN1ci5maXJzdFBvcygpLnRvU3RyaW5nKCkpOwotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiIGxhc3RQb3M9Iik7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4obm9kZUN1ci5sYXN0UG9zKCkudG9TdHJpbmcoKSk7Ci0gICAgICAgIH0KLSAgICAgICAgIGVsc2UKLSAgICAgICAgewotICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIkltcGxlbWVudGF0aW9uTWVzc2FnZXMuVkFMX05JSUNNIik7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIC0xIGlzIHVzZWQgdG8gcmVwcmVzZW50IGJhZCB0cmFuc2l0aW9ucyBpbiB0aGUgdHJhbnNpdGlvbiB0YWJsZQotICAgICAqIGVudHJ5IGZvciBlYWNoIHN0YXRlLiBTbyBlYWNoIGVudHJ5IGlzIGluaXRpYWxpemVkIHRvIGFuIGFsbCAtMQotICAgICAqIGFycmF5LiBUaGlzIG1ldGhvZCBjcmVhdGVzIGEgbmV3IGVudHJ5IGFuZCBpbml0aWFsaXplcyBpdC4KLSAgICAgKi8KLSAgICBwcml2YXRlIGludFtdIG1ha2VEZWZTdGF0ZUxpc3QoKQotICAgIHsKLSAgICAgICAgaW50W10gcmV0QXJyYXkgPSBuZXcgaW50W2ZFbGVtTWFwU2l6ZV07Ci0gICAgICAgIGZvciAoaW50IGluZGV4ID0gMDsgaW5kZXggPCBmRWxlbU1hcFNpemU7IGluZGV4KyspCi0gICAgICAgICAgICByZXRBcnJheVtpbmRleF0gPSAtMTsKLSAgICAgICAgcmV0dXJuIHJldEFycmF5OwotICAgIH0KLQotICAgIC8qKiBQb3N0IHRyZWUgYnVpbGQgaW5pdGlhbGl6YXRpb24uICovCi0gICAgcHJpdmF0ZSBpbnQgcG9zdFRyZWVCdWlsZEluaXQoQ01Ob2RlIG5vZGVDdXIsIGludCBjdXJJbmRleCkKLSAgICB7Ci0gICAgICAgIC8vIFNldCB0aGUgbWF4aW11bSBzdGF0ZXMgb24gdGhpcyBub2RlCi0gICAgICAgIG5vZGVDdXIuc2V0TWF4U3RhdGVzKGZMZWFmQ291bnQpOwotCi0gICAgICAgIC8vIFJlY3Vyc2UgYXMgcmVxdWlyZWQKLSAgICAgICAgaWYgKChub2RlQ3VyLnR5cGUoKSAmIDB4MGYpID09IFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9BTlkgfHwKLSAgICAgICAgICAgIChub2RlQ3VyLnR5cGUoKSAmIDB4MGYpID09IFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9BTllfTE9DQUwgfHwKLSAgICAgICAgICAgIChub2RlQ3VyLnR5cGUoKSAmIDB4MGYpID09IFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9BTllfT1RIRVIpIHsKLSAgICAgICAgICAgIC8vIFJFVklTSVQ6IERvbid0IHdhc3RlIHRoZXNlIHN0cnVjdHVyZXMuCi0gICAgICAgICAgICBRTmFtZSBxbmFtZSA9IG5ldyBRTmFtZShudWxsLCBudWxsLCBudWxsLCAoKENNQW55KW5vZGVDdXIpLmdldFVSSSgpKTsKLSAgICAgICAgICAgIGZMZWFmTGlzdFtjdXJJbmRleF0gPSBuZXcgQ01MZWFmKHFuYW1lLCAoKENNQW55KW5vZGVDdXIpLmdldFBvc2l0aW9uKCkpOwotICAgICAgICAgICAgZkxlYWZMaXN0VHlwZVtjdXJJbmRleF0gPSBub2RlQ3VyLnR5cGUoKTsKLSAgICAgICAgICAgIGN1ckluZGV4Kys7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoKG5vZGVDdXIudHlwZSgpID09IFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9DSE9JQ0UpCi0gICAgICAgIHx8ICAobm9kZUN1ci50eXBlKCkgPT0gWE1MQ29udGVudFNwZWMuQ09OVEVOVFNQRUNOT0RFX1NFUSkpCi0gICAgICAgIHsKLSAgICAgICAgICAgIGN1ckluZGV4ID0gcG9zdFRyZWVCdWlsZEluaXQoKChDTUJpbk9wKW5vZGVDdXIpLmdldExlZnQoKSwgY3VySW5kZXgpOwotICAgICAgICAgICAgY3VySW5kZXggPSBwb3N0VHJlZUJ1aWxkSW5pdCgoKENNQmluT3Apbm9kZUN1cikuZ2V0UmlnaHQoKSwgY3VySW5kZXgpOwotICAgICAgICB9Ci0gICAgICAgICBlbHNlIGlmIChub2RlQ3VyLnR5cGUoKSA9PSBYTUxDb250ZW50U3BlYy5DT05URU5UU1BFQ05PREVfWkVST19PUl9NT1JFCi0gICAgICAgICAgICAgfHwgbm9kZUN1ci50eXBlKCkgPT0gWE1MQ29udGVudFNwZWMuQ09OVEVOVFNQRUNOT0RFX09ORV9PUl9NT1JFCi0gICAgICAgICAgICAgfHwgbm9kZUN1ci50eXBlKCkgPT0gWE1MQ29udGVudFNwZWMuQ09OVEVOVFNQRUNOT0RFX1pFUk9fT1JfT05FKQotICAgICAgICB7Ci0gICAgICAgICAgICBjdXJJbmRleCA9IHBvc3RUcmVlQnVpbGRJbml0KCgoQ01VbmlPcClub2RlQ3VyKS5nZXRDaGlsZCgpLCBjdXJJbmRleCk7Ci0gICAgICAgIH0KLSAgICAgICAgIGVsc2UgaWYgKG5vZGVDdXIudHlwZSgpID09IFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9MRUFGKQotICAgICAgICB7Ci0gICAgICAgICAgICAvLwotICAgICAgICAgICAgLy8gIFB1dCB0aGlzIG5vZGUgaW4gdGhlIGxlYWYgbGlzdCBhdCB0aGUgY3VycmVudCBpbmRleCBpZiBpdHMKLSAgICAgICAgICAgIC8vICBhIG5vbi1lcHNpbG9uIGxlYWYuCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgIGZpbmFsIFFOYW1lIG5vZGUgPSAoKENNTGVhZilub2RlQ3VyKS5nZXRFbGVtZW50KCk7Ci0gICAgICAgICAgICBpZiAobm9kZS5sb2NhbHBhcnQgIT0gZkVwc2lsb25TdHJpbmcpIHsKLSAgICAgICAgICAgICAgICBmTGVhZkxpc3RbY3VySW5kZXhdID0gKENNTGVhZilub2RlQ3VyOwotICAgICAgICAgICAgICAgIGZMZWFmTGlzdFR5cGVbY3VySW5kZXhdID0gWE1MQ29udGVudFNwZWMuQ09OVEVOVFNQRUNOT0RFX0xFQUY7Ci0gICAgICAgICAgICAgICAgY3VySW5kZXgrKzsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICAgZWxzZQotICAgICAgICB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiSW1wbGVtZW50YXRpb25NZXNzYWdlcy5WQUxfTklJQ006IHR5cGU9Iitub2RlQ3VyLnR5cGUoKSk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGN1ckluZGV4OwotICAgIH0KLQotfSAvLyBjbGFzcyBERkFDb250ZW50TW9kZWwKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHRkL21vZGVscy9NaXhlZENvbnRlbnRNb2RlbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdGQvbW9kZWxzL01peGVkQ29udGVudE1vZGVsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDhkNGNkYTIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdGQvbW9kZWxzL01peGVkQ29udGVudE1vZGVsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyNTggKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OS0yMDAyIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGVyY2VzIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBJbnRlcm5hdGlvbmFsCi0gKiBCdXNpbmVzcyBNYWNoaW5lcywgSW5jLiwgaHR0cDovL3d3dy5hcGFjaGUub3JnLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR0ZC5tb2RlbHM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5RTmFtZTsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdGQuWE1MQ29udGVudFNwZWM7Ci0KLS8qKgotICogTWl4ZWRDb250ZW50TW9kZWwgaXMgYSBkZXJpdmF0aXZlIG9mIHRoZSBhYnN0cmFjdCBjb250ZW50IG1vZGVsIGJhc2UKLSAqIGNsYXNzIHRoYXQgaGFuZGxlcyB0aGUgc3BlY2lhbCBjYXNlIG9mIG1peGVkIG1vZGVsIGVsZW1lbnRzLiBJZiBhbiBlbGVtZW50Ci0gKiBpcyBtaXhlZCBtb2RlbCwgaXQgaGFzIFBDREFUQSBhcyBpdHMgZmlyc3QgcG9zc2libGUgY29udGVudCwgZm9sbG93ZWQKLSAqIGJ5IGFuIGFsdGVybmF0aW9uIG9mIHRoZSBwb3NzaWJsZSBjaGlsZHJlbi4gVGhlIGNoaWxkcmVuIGNhbm5vdCBoYXZlIGFueQotICogbnVtZXJhdGlvbiBvciBvcmRlciwgc28gaXQgbXVzdCBsb29rIGxpa2UgdGhpczoKLSAqIDxwcmU+Ci0gKiAgICZsdDshRUxFTUVOVCBGb28gKCgjUENEQVRBfGF8YnxjfCkqKSZndDsKLSAqIDwvcHJlPgotICogU28sIGFsbCB3ZSBoYXZlIHRvIGRvIGlzIHRvIGtlZXAgYW4gYXJyYXkgb2YgdGhlIHBvc3NpYmxlIGNoaWxkcmVuIGFuZAotICogdmFsaWRhdGUgYnkganVzdCBsb29raW5nIHVwIGVhY2ggY2hpbGQgYmVpbmcgdmFsaWRhdGVkIGJ5IGxvb2tpbmcgaXQgdXAKLSAqIGluIHRoZSBsaXN0LgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKi8KLXB1YmxpYyBjbGFzcyBNaXhlZENvbnRlbnRNb2RlbAotICAgIGltcGxlbWVudHMgQ29udGVudE1vZGVsVmFsaWRhdG9yIHsKLQotICAgIC8vCi0gICAgLy8gRGF0YQotICAgIC8vCi0KLSAgICAvKiogVGhlIGNvdW50IG9mIHBvc3NpYmxlIGNoaWxkcmVuIHRoYXQgd2UgaGF2ZSB0byBkZWFsIHdpdGguICovCi0gICAgcHJpdmF0ZSBpbnQgZkNvdW50OwotCi0gICAgLyoqIFRoZSBsaXN0IG9mIHBvc3NpYmxlIGNoaWxkcmVuIHRoYXQgd2UgaGF2ZSB0byBhY2NlcHQuICovCi0gICAgcHJpdmF0ZSBRTmFtZSBmQ2hpbGRyZW5bXTsKLQotICAgIC8qKiBUaGUgdHlwZSBvZiB0aGUgY2hpbGRyZW4gdG8gc3VwcG9ydCBBTlkuICovCi0gICAgcHJpdmF0ZSBpbnQgZkNoaWxkcmVuVHlwZVtdOwotCi0gICAgLyogdGhpcyBpcyB0aGUgRXF1aXZDbGFzc0NvbXBhcmF0b3Igb2JqZWN0ICovCi0gICAgLy9wcml2YXRlIEVxdWl2Q2xhc3NDb21wYXJhdG9yIGNvbXBhcmF0b3IgPSBudWxsOwotCi0gICAgLyoqCi0gICAgICogVHJ1ZSBpZiBtaXhlZCBjb250ZW50IG1vZGVsIGlzIG9yZGVyZWQuIERURCBtaXhlZCBjb250ZW50IG1vZGVscwotICAgICAqIGFyZSA8ZW0+YWx3YXlzPC9lbT4gdW5vcmRlcmVkLgotICAgICAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBmT3JkZXJlZDsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHMgYSBtaXhlZCBjb250ZW50IG1vZGVsLgotICAgICAqCi0gICAgICogQHBhcmFtIGNoaWxkcmVuIFRoZSBsaXN0IG9mIGFsbG93ZWQgY2hpbGRyZW4uCi0gICAgICogQHBhcmFtIHR5cGUgVGhlIGxpc3Qgb2YgdGhlIHR5cGVzIG9mIHRoZSBjaGlsZHJlbi4KLSAgICAgKiBAcGFyYW0gb2Zmc2V0IFRoZSBzdGFydCBvZmZzZXQgcG9zaXRpb24gaW4gdGhlIGNoaWxkcmVuLgotICAgICAqIEBwYXJhbSBsZW5ndGggVGhlIGNoaWxkIGNvdW50LgotICAgICAqIEBwYXJhbSBvcmRlcmVkIFRydWUgaWYgY29udGVudCBtdXN0IGJlIG9yZGVyZWQuCi0gICAgICovCi0gICAgcHVibGljIE1peGVkQ29udGVudE1vZGVsKFFOYW1lW10gY2hpbGRyZW4sIGludFtdIHR5cGUsIGludCBvZmZzZXQsIGludCBsZW5ndGggLCBib29sZWFuIG9yZGVyZWQpIHsKLSAgICAgICAgLy8gTWFrZSBvdXIgb3duIGNvcHkgbm93LCB3aGljaCBpcyBleGFjdGx5IHRoZSByaWdodCBzaXplCi0gICAgICAgIGZDb3VudCA9IGxlbmd0aDsKLSAgICAgICAgZkNoaWxkcmVuID0gbmV3IFFOYW1lW2ZDb3VudF07Ci0gICAgICAgIGZDaGlsZHJlblR5cGUgPSBuZXcgaW50W2ZDb3VudF07Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZkNvdW50OyBpKyspIHsKLSAgICAgICAgICAgIGZDaGlsZHJlbltpXSA9IG5ldyBRTmFtZShjaGlsZHJlbltvZmZzZXQgKyBpXSk7Ci0gICAgICAgICAgICBmQ2hpbGRyZW5UeXBlW2ldID0gdHlwZVtvZmZzZXQgKyBpXTsKLSAgICAgICAgfQotICAgICAgICBmT3JkZXJlZCA9IG9yZGVyZWQ7Ci0KLSAgICB9Ci0KLSAgICAvLwotICAgIC8vIENvbnRlbnRNb2RlbFZhbGlkYXRvciBtZXRob2RzCi0gICAgLy8KLQotCi0gICAgLyoqCi0gICAgICogQ2hlY2sgdGhhdCB0aGUgc3BlY2lmaWVkIGNvbnRlbnQgaXMgdmFsaWQgYWNjb3JkaW5nIHRvIHRoaXMKLSAgICAgKiBjb250ZW50IG1vZGVsLiBUaGlzIG1ldGhvZCBjYW4gYWxzbyBiZSBjYWxsZWQgdG8gZG8gJ3doYXQgaWYnCi0gICAgICogdGVzdGluZyBvZiBjb250ZW50IG1vZGVscyBqdXN0IHRvIHNlZSBpZiB0aGV5IHdvdWxkIGJlIHZhbGlkLgotICAgICAqIDxwPgotICAgICAqIEEgdmFsdWUgb2YgLTEgaW4gdGhlIGNoaWxkcmVuIGFycmF5IGluZGljYXRlcyBhIFBDREFUQSBub2RlLiBBbGwgb3RoZXIKLSAgICAgKiBpbmRleGVzIHdpbGwgYmUgcG9zaXRpdmUgYW5kIHJlcHJlc2VudCBjaGlsZCBlbGVtZW50cy4gVGhlIGNvdW50IGNhbiBiZQotICAgICAqIHplcm8sIHNpbmNlIHNvbWUgZWxlbWVudHMgaGF2ZSB0aGUgRU1QVFkgY29udGVudCBtb2RlbCBhbmQgdGhhdCBtdXN0IGJlCi0gICAgICogY29uZmlybWVkLgotICAgICAqCi0gICAgICogQHBhcmFtIGNoaWxkcmVuIFRoZSBjaGlsZHJlbiBvZiB0aGlzIGVsZW1lbnQuICBFYWNoIGludGVnZXIgaXMgYW4gaW5kZXggd2l0aGluCi0gICAgICogICAgICAgICAgICAgICAgIHRoZSA8Y29kZT5TdHJpbmdQb29sPC9jb2RlPiBvZiB0aGUgY2hpbGQgZWxlbWVudCBuYW1lLiAgQW4gaW5kZXgKLSAgICAgKiAgICAgICAgICAgICAgICAgb2YgLTEgaXMgdXNlZCB0byBpbmRpY2F0ZSBhbiBvY2N1cnJlbmNlIG9mIG5vbi13aGl0ZXNwYWNlIGNoYXJhY3RlcgotICAgICAqICAgICAgICAgICAgICAgICBkYXRhLgotICAgICAqIEBwYXJhbSBvZmZzZXQgT2Zmc2V0IGludG8gdGhlIGFycmF5IHdoZXJlIHRoZSBjaGlsZHJlbiBzdGFydHMuCi0gICAgICogQHBhcmFtIGxlbmd0aCBUaGUgbnVtYmVyIG9mIGVudHJpZXMgaW4gdGhlIDxjb2RlPmNoaWxkcmVuPC9jb2RlPiBhcnJheS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIHZhbHVlIC0xIGlmIGZ1bGx5IHZhbGlkLCBlbHNlIHRoZSAwIGJhc2VkIGluZGV4IG9mIHRoZSBjaGlsZAotICAgICAqICAgICAgICAgdGhhdCBmaXJzdCBmYWlsZWQuIElmIHRoZSB2YWx1ZSByZXR1cm5lZCBpcyBlcXVhbCB0byB0aGUgbnVtYmVyCi0gICAgICogICAgICAgICBvZiBjaGlsZHJlbiwgdGhlbiB0aGUgc3BlY2lmaWVkIGNoaWxkcmVuIGFyZSB2YWxpZCBidXQgYWRkaXRpb25hbAotICAgICAqICAgICAgICAgY29udGVudCBpcyByZXF1aXJlZCB0byByZWFjaCBhIHZhbGlkIGVuZGluZyBzdGF0ZS4KLSAgICAgKgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgdmFsaWRhdGUoUU5hbWVbXSBjaGlsZHJlbiwgaW50IG9mZnNldCwgaW50IGxlbmd0aCkgewotCi0gICAgICAgIC8vIG11c3QgbWF0Y2ggb3JkZXIKLSAgICAgICAgaWYgKGZPcmRlcmVkKSB7Ci0gICAgICAgICAgICBpbnQgaW5JbmRleCA9IDA7Ci0gICAgICAgICAgICBmb3IgKGludCBvdXRJbmRleCA9IDA7IG91dEluZGV4IDwgbGVuZ3RoOyBvdXRJbmRleCsrKSB7Ci0KLSAgICAgICAgICAgICAgICAvLyBpZ25vcmUgbWl4ZWQgdGV4dAotICAgICAgICAgICAgICAgIGZpbmFsIFFOYW1lIGN1ckNoaWxkID0gY2hpbGRyZW5bb2Zmc2V0ICsgb3V0SW5kZXhdOwotICAgICAgICAgICAgICAgIGlmIChjdXJDaGlsZC5sb2NhbHBhcnQgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyBlbGVtZW50IG11c3QgbWF0Y2gKLSAgICAgICAgICAgICAgICBpbnQgdHlwZSA9IGZDaGlsZHJlblR5cGVbaW5JbmRleF07Ci0gICAgICAgICAgICAgICAgaWYgKHR5cGUgPT0gWE1MQ29udGVudFNwZWMuQ09OVEVOVFNQRUNOT0RFX0xFQUYpIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGZDaGlsZHJlbltpbkluZGV4XS5yYXduYW1lICE9IGNoaWxkcmVuW29mZnNldCArIG91dEluZGV4XS5yYXduYW1lKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gb3V0SW5kZXg7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSBpZiAodHlwZSA9PSBYTUxDb250ZW50U3BlYy5DT05URU5UU1BFQ05PREVfQU5ZKSB7Ci0gICAgICAgICAgICAgICAgICAgIFN0cmluZyB1cmkgPSBmQ2hpbGRyZW5baW5JbmRleF0udXJpOwotICAgICAgICAgICAgICAgICAgICBpZiAodXJpICE9IG51bGwgJiYgdXJpICE9IGNoaWxkcmVuW291dEluZGV4XS51cmkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBvdXRJbmRleDsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIGlmICh0eXBlID09IFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9BTllfTE9DQUwpIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGNoaWxkcmVuW291dEluZGV4XS51cmkgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG91dEluZGV4OwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGUgPT0gWE1MQ29udGVudFNwZWMuQ09OVEVOVFNQRUNOT0RFX0FOWV9PVEhFUikgewotICAgICAgICAgICAgICAgICAgICBpZiAoZkNoaWxkcmVuW2luSW5kZXhdLnVyaSA9PSBjaGlsZHJlbltvdXRJbmRleF0udXJpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gb3V0SW5kZXg7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyBhZHZhbmNlIGluZGV4Ci0gICAgICAgICAgICAgICAgaW5JbmRleCsrOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gY2FuIGFwcGVhciBpbiBhbnkgb3JkZXIKLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBmb3IgKGludCBvdXRJbmRleCA9IDA7IG91dEluZGV4IDwgbGVuZ3RoOyBvdXRJbmRleCsrKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIC8vIEdldCB0aGUgY3VycmVudCBjaGlsZCBvdXQgb2YgdGhlIHNvdXJjZSBpbmRleAotICAgICAgICAgICAgICAgIGZpbmFsIFFOYW1lIGN1ckNoaWxkID0gY2hpbGRyZW5bb2Zmc2V0ICsgb3V0SW5kZXhdOwotCi0gICAgICAgICAgICAgICAgLy8gSWYgaXRzIFBDREFUQSwgdGhlbiB3ZSBqdXN0IGFjY2VwdCB0aGF0Ci0gICAgICAgICAgICAgICAgaWYgKGN1ckNoaWxkLmxvY2FscGFydCA9PSBudWxsKQotICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKLQotICAgICAgICAgICAgICAgIC8vIEFuZCB0cnkgdG8gZmluZCBpdCBpbiBvdXIgbGlzdAotICAgICAgICAgICAgICAgIGludCBpbkluZGV4ID0gMDsKLSAgICAgICAgICAgICAgICBmb3IgKDsgaW5JbmRleCA8IGZDb3VudDsgaW5JbmRleCsrKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgaW50IHR5cGUgPSBmQ2hpbGRyZW5UeXBlW2luSW5kZXhdOwotICAgICAgICAgICAgICAgICAgICBpZiAodHlwZSA9PSBYTUxDb250ZW50U3BlYy5DT05URU5UU1BFQ05PREVfTEVBRikgewotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGN1ckNoaWxkLnJhd25hbWUgPT0gZkNoaWxkcmVuW2luSW5kZXhdLnJhd25hbWUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICh0eXBlID09IFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9BTlkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyB1cmkgPSBmQ2hpbGRyZW5baW5JbmRleF0udXJpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHVyaSA9PSBudWxsIHx8IHVyaSA9PSBjaGlsZHJlbltvdXRJbmRleF0udXJpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAodHlwZSA9PSBYTUxDb250ZW50U3BlYy5DT05URU5UU1BFQ05PREVfQU5ZX0xPQ0FMKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2hpbGRyZW5bb3V0SW5kZXhdLnVyaSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAodHlwZSA9PSBYTUxDb250ZW50U3BlYy5DT05URU5UU1BFQ05PREVfQU5ZX09USEVSKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZkNoaWxkcmVuW2luSW5kZXhdLnVyaSAhPSBjaGlsZHJlbltvdXRJbmRleF0udXJpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgLy8gUkVWSVNJVDogV2hhdCBhYm91dCBjaGVja2luZyBmb3IgbXVsdGlwbGUgQU5ZIG1hdGNoZXM/Ci0gICAgICAgICAgICAgICAgICAgIC8vICAgICAgICAgIFRoZSBjb250ZW50IG1vZGVsIGFtYmlndWl0eSAqY291bGQqIGJlIGNoZWNrZWQKLSAgICAgICAgICAgICAgICAgICAgLy8gICAgICAgICAgYnkgdGhlIGNhbGxlciBiZWZvcmUgY29uc3RydWN0aW5nIHRoZSBtaXhlZAotICAgICAgICAgICAgICAgICAgICAvLyAgICAgICAgICBjb250ZW50IG1vZGVsLgotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8vIFdlIGRpZCBub3QgZmluZCB0aGlzIG9uZSwgc28gdGhlIHZhbGlkYXRpb24gZmFpbGVkCi0gICAgICAgICAgICAgICAgaWYgKGluSW5kZXggPT0gZkNvdW50KQotICAgICAgICAgICAgICAgICAgICByZXR1cm4gb3V0SW5kZXg7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBFdmVyeXRoaW5nIHNlZW1zIHRvIGJlIGluIG9yZGVyLCBzbyByZXR1cm4gc3VjY2VzcwotICAgICAgICByZXR1cm4gLTE7Ci0gICAgfSAvLyB2YWxpZGF0ZQotCi19IC8vIGNsYXNzIE1peGVkQ29udGVudE1vZGVsCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R0ZC9tb2RlbHMvU2ltcGxlQ29udGVudE1vZGVsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R0ZC9tb2RlbHMvU2ltcGxlQ29udGVudE1vZGVsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDczYWUzN2QuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdGQvbW9kZWxzL1NpbXBsZUNvbnRlbnRNb2RlbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzIwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTktMjAwMiBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhlcmNlcyIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgSW50ZXJuYXRpb25hbAotICogQnVzaW5lc3MgTWFjaGluZXMsIEluYy4sIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdGQubW9kZWxzOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuUU5hbWU7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHRkLlhNTENvbnRlbnRTcGVjOwotCi0vKioKLSAqIFNpbXBsZUNvbnRlbnRNb2RlbCBpcyBhIGRlcml2YXRpdmUgb2YgdGhlIGFic3RyYWN0IGNvbnRlbnQgbW9kZWwgYmFzZQotICogY2xhc3MgdGhhdCBoYW5kbGVzIGEgc21hbGwgc2V0IG9mIHNpbXBsZSBjb250ZW50IG1vZGVscyB0aGF0IGFyZSBqdXN0Ci0gKiB3YXkgb3ZlcmtpbGwgdG8gZ2l2ZSB0aGUgREZBIHRyZWF0bWVudC4KLSAqIDxwPgotICogVGhpcyBjbGFzcyBoYW5kbGVzIHRoZSBmb2xsb3dpbmcgc2NlbmFyaW9zOgotICogPHVsPgotICogPGxpPiBhCi0gKiA8bGk+IGE/Ci0gKiA8bGk+IGEqCi0gKiA8bGk+IGErCi0gKiA8bGk+IGEsYgotICogPGxpPiBhfGIKLSAqIDwvdWw+Ci0gKiA8cD4KLSAqIFRoZXNlIGFsbCBpbnZvbHZlIGEgdW5hcnkgb3BlcmF0aW9uIHdpdGggb25lIGVsZW1lbnQgdHlwZSwgb3IgYSBiaW5hcnkKLSAqIG9wZXJhdGlvbiB3aXRoIHR3byBlbGVtZW50cy4gVGhlc2UgYXJlIHZlcnkgc2ltcGxlIGFuZCBjYW4gYmUgY2hlY2tlZAotICogaW4gYSBzaW1wbGUgd2F5IHdpdGhvdXQgYSBERkEgYW5kIHdpdGhvdXQgdGhlIG92ZXJoZWFkIG9mIHNldHRpbmcgdXAgYQotICogREZBIGZvciBzdWNoIGEgc2ltcGxlIGNoZWNrLgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKi8KLXB1YmxpYyBjbGFzcyBTaW1wbGVDb250ZW50TW9kZWwKLSAgICBpbXBsZW1lbnRzIENvbnRlbnRNb2RlbFZhbGlkYXRvciB7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0YW50cwotICAgIC8vCi0KLSAgICAvKiogQ0hPSUNFICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBDSE9JQ0UgPSAtMTsKLQotICAgIC8qKiBTRVFVRU5DRSAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgU0VRVUVOQ0UgPSAtMTsKLQotICAgIC8vCi0gICAgLy8gRGF0YQotICAgIC8vCi0KLQotICAgIC8qKgotICAgICAqIFRoZSBlbGVtZW50IGRlY2wgcG9vbCBpbmRpY2VzIG9mIHRoZSBmaXJzdCAoYW5kIG9wdGlvbmFsIHNlY29uZCkKLSAgICAgKiBjaGlsZCBub2RlLiBUaGUgb3BlcmF0aW9uIGNvZGUgdGVsbHMgdXMgd2hldGhlciB0aGUgc2Vjb25kIGNoaWxkCi0gICAgICogaXMgdXNlZCBvciBub3QuCi0gICAgICovCi0gICAgcHJpdmF0ZSBRTmFtZSBmRmlyc3RDaGlsZCA9IG5ldyBRTmFtZSgpOwotCi0gICAgLyoqCi0gICAgICogVGhlIGVsZW1lbnQgZGVjbCBwb29sIGluZGljZXMgb2YgdGhlIGZpcnN0IChhbmQgb3B0aW9uYWwgc2Vjb25kKQotICAgICAqIGNoaWxkIG5vZGUuIFRoZSBvcGVyYXRpb24gY29kZSB0ZWxscyB1cyB3aGV0aGVyIHRoZSBzZWNvbmQgY2hpbGQKLSAgICAgKiBpcyB1c2VkIG9yIG5vdC4KLSAgICAgKi8KLSAgICBwcml2YXRlIFFOYW1lIGZTZWNvbmRDaGlsZCA9IG5ldyBRTmFtZSgpOwotCi0gICAgLyoqCi0gICAgICogVGhlIG9wZXJhdGlvbiB0aGF0IHRoaXMgb2JqZWN0IHJlcHJlc2VudHMuIFNpbmNlIHRoaXMgY2xhc3Mgb25seQotICAgICAqIGRvZXMgc2ltcGxlIGNvbnRlbnRzLCB0aGVyZSBpcyBvbmx5IGV2ZXIgYSBzaW5nbGUgb3BlcmF0aW9uCi0gICAgICogaW52b2x2ZWQgKGkuZS4gdGhlIGNoaWxkcmVuIG9mIHRoZSBvcGVyYXRpb24gYXJlIGFsd2F5cyBvbmUgb3IKLSAgICAgKiB0d28gbGVhZnMuKSBUaGlzIGlzIG9uZSBvZiB0aGUgWE1MRFREUGFyYW1zLkNPTlRFTlRTUEVDTk9ERV9YWFggdmFsdWVzLgotICAgICAqLwotICAgIHByaXZhdGUgaW50IGZPcGVyYXRvcjsKLQotICAgIC8qIHRoaXMgaXMgdGhlIEVxdWl2Q2xhc3NDb21wYXJhdG9yIG9iamVjdCAqLwotICAgIC8vcHJpdmF0ZSBFcXVpdkNsYXNzQ29tcGFyYXRvciBjb21wYXJhdG9yID0gbnVsbDsKLQotCi0gICAgLy8KLSAgICAvLyBDb25zdHJ1Y3RvcnMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0cyBhIHNpbXBsZSBjb250ZW50IG1vZGVsLgotICAgICAqCi0gICAgICogQHBhcmFtIG9wZXJhdG9yIFRoZSBjb250ZW50IG1vZGVsIG9wZXJhdG9yLgotICAgICAqIEBwYXJhbSBmaXJzdENoaWxkIHF1YWxpZmllZCBuYW1lIG9mIHRoZSBmaXJzdCBjaGlsZAotICAgICAqIEBwYXJhbSBzZWNvbmRDaGlsZCBxdWFsaWZpZWQgbmFtZSBvZiB0aGUgc2Vjb25kIGNoaWxkCi0gICAgICoKLSAgICAgKi8KLSAgICBwdWJsaWMgU2ltcGxlQ29udGVudE1vZGVsKHNob3J0IG9wZXJhdG9yLCBRTmFtZSBmaXJzdENoaWxkLCBRTmFtZSBzZWNvbmRDaGlsZCkgewotICAgICAgICAvLwotICAgICAgICAvLyAgU3RvcmUgYXdheSB0aGUgY2hpbGRyZW4gYW5kIG9wZXJhdGlvbi4gVGhpcyBpcyBhbGwgd2UgbmVlZCB0bwotICAgICAgICAvLyAgZG8gdGhlIGNvbnRlbnQgbW9kZWwgY2hlY2suCi0gICAgICAgIC8vCi0gICAgICAgIC8vICBUaGUgb3BlcmF0aW9uIGlzIG9uZSBvZiB0aGUgQ29udGVudFNwZWNOb2RlLk5PREVfWFhYIHZhbHVlcyEKLSAgICAgICAgLy8KLSAgICAgICAgZkZpcnN0Q2hpbGQuc2V0VmFsdWVzKGZpcnN0Q2hpbGQpOwotICAgICAgICBpZiAoc2Vjb25kQ2hpbGQgIT0gbnVsbCkgewotICAgICAgICAgICAgZlNlY29uZENoaWxkLnNldFZhbHVlcyhzZWNvbmRDaGlsZCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBmU2Vjb25kQ2hpbGQuY2xlYXIoKTsKLSAgICAgICAgfQotICAgICAgICBmT3BlcmF0b3IgPSBvcGVyYXRvcjsKLSAgICB9Ci0KLSAgICAvLwotICAgIC8vIENvbnRlbnRNb2RlbFZhbGlkYXRvciBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIENoZWNrIHRoYXQgdGhlIHNwZWNpZmllZCBjb250ZW50IGlzIHZhbGlkIGFjY29yZGluZyB0byB0aGlzCi0gICAgICogY29udGVudCBtb2RlbC4gVGhpcyBtZXRob2QgY2FuIGFsc28gYmUgY2FsbGVkIHRvIGRvICd3aGF0IGlmJwotICAgICAqIHRlc3Rpbmcgb2YgY29udGVudCBtb2RlbHMganVzdCB0byBzZWUgaWYgdGhleSB3b3VsZCBiZSB2YWxpZC4KLSAgICAgKiA8cD4KLSAgICAgKiBBIHZhbHVlIG9mIC0xIGluIHRoZSBjaGlsZHJlbiBhcnJheSBpbmRpY2F0ZXMgYSBQQ0RBVEEgbm9kZS4gQWxsIG90aGVyCi0gICAgICogaW5kZXhlcyB3aWxsIGJlIHBvc2l0aXZlIGFuZCByZXByZXNlbnQgY2hpbGQgZWxlbWVudHMuIFRoZSBjb3VudCBjYW4gYmUKLSAgICAgKiB6ZXJvLCBzaW5jZSBzb21lIGVsZW1lbnRzIGhhdmUgdGhlIEVNUFRZIGNvbnRlbnQgbW9kZWwgYW5kIHRoYXQgbXVzdCBiZQotICAgICAqIGNvbmZpcm1lZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjaGlsZHJlbiBUaGUgY2hpbGRyZW4gb2YgdGhpcyBlbGVtZW50LiAgRWFjaCBpbnRlZ2VyIGlzIGFuIGluZGV4IHdpdGhpbgotICAgICAqICAgICAgICAgICAgICAgICB0aGUgPGNvZGU+U3RyaW5nUG9vbDwvY29kZT4gb2YgdGhlIGNoaWxkIGVsZW1lbnQgbmFtZS4gIEFuIGluZGV4Ci0gICAgICogICAgICAgICAgICAgICAgIG9mIC0xIGlzIHVzZWQgdG8gaW5kaWNhdGUgYW4gb2NjdXJyZW5jZSBvZiBub24td2hpdGVzcGFjZSBjaGFyYWN0ZXIKLSAgICAgKiAgICAgICAgICAgICAgICAgZGF0YS4KLSAgICAgKiBAcGFyYW0gb2Zmc2V0IE9mZnNldCBpbnRvIHRoZSBhcnJheSB3aGVyZSB0aGUgY2hpbGRyZW4gc3RhcnRzLgotICAgICAqIEBwYXJhbSBsZW5ndGggVGhlIG51bWJlciBvZiBlbnRyaWVzIGluIHRoZSA8Y29kZT5jaGlsZHJlbjwvY29kZT4gYXJyYXkuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSB2YWx1ZSAtMSBpZiBmdWxseSB2YWxpZCwgZWxzZSB0aGUgMCBiYXNlZCBpbmRleCBvZiB0aGUgY2hpbGQKLSAgICAgKiAgICAgICAgIHRoYXQgZmlyc3QgZmFpbGVkLiBJZiB0aGUgdmFsdWUgcmV0dXJuZWQgaXMgZXF1YWwgdG8gdGhlIG51bWJlcgotICAgICAqICAgICAgICAgb2YgY2hpbGRyZW4sIHRoZW4gdGhlIHNwZWNpZmllZCBjaGlsZHJlbiBhcmUgdmFsaWQgYnV0IGFkZGl0aW9uYWwKLSAgICAgKiAgICAgICAgIGNvbnRlbnQgaXMgcmVxdWlyZWQgdG8gcmVhY2ggYSB2YWxpZCBlbmRpbmcgc3RhdGUuCi0gICAgICoKLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IHZhbGlkYXRlKFFOYW1lW10gY2hpbGRyZW4sIGludCBvZmZzZXQsIGludCBsZW5ndGgpIHsKLQotICAgICAgICAvLwotICAgICAgICAvLyAgQWNjb3JkaW5nIHRvIHRoZSB0eXBlIG9mIG9wZXJhdGlvbiwgd2UgZG8gdGhlIGNvcnJlY3QgdHlwZSBvZgotICAgICAgICAvLyAgY29udGVudCBjaGVjay4KLSAgICAgICAgLy8KLSAgICAgICAgc3dpdGNoKGZPcGVyYXRvcikKLSAgICAgICAgewotICAgICAgICAgICAgY2FzZSBYTUxDb250ZW50U3BlYy5DT05URU5UU1BFQ05PREVfTEVBRiA6Ci0gICAgICAgICAgICAgICAgLy8gSWYgdGhlcmUgaXMgbm90IGEgY2hpbGQsIHRoZW4gcmVwb3J0IGFuIGVycm9yIGF0IGluZGV4IDAKLSAgICAgICAgICAgICAgICBpZiAobGVuZ3RoID09IDApCi0gICAgICAgICAgICAgICAgICAgIHJldHVybiAwOwotCi0gICAgICAgICAgICAgICAgLy8gSWYgdGhlIDB0aCBjaGlsZCBpcyBub3QgdGhlIHJpZ2h0IGtpbmQsIHJlcG9ydCBhbiBlcnJvciBhdCAwCi0gICAgICAgICAgICAgICAgaWYgKGNoaWxkcmVuW29mZnNldF0ucmF3bmFtZSAhPSBmRmlyc3RDaGlsZC5yYXduYW1lKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiAwOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8vIElmIG1vcmUgdGhhbiBvbmUgY2hpbGQsIHJlcG9ydCBhbiBlcnJvciBhdCBpbmRleCAxCi0gICAgICAgICAgICAgICAgaWYgKGxlbmd0aCA+IDEpCi0gICAgICAgICAgICAgICAgICAgIHJldHVybiAxOwotICAgICAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgICAgICBjYXNlIFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9aRVJPX09SX09ORSA6Ci0gICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICAvLyAgSWYgdGhlcmUgaXMgb25lIGNoaWxkLCBtYWtlIHN1cmUgaXRzIHRoZSByaWdodCB0eXBlLiBJZiBub3QsCi0gICAgICAgICAgICAgICAgLy8gIHRoZW4gaXRzIGFuIGVycm9yIGF0IGluZGV4IDAuCi0gICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICBpZiAobGVuZ3RoID09IDEpIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGNoaWxkcmVuW29mZnNldF0ucmF3bmFtZSAhPSBmRmlyc3RDaGlsZC5yYXduYW1lKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gMDsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAgICAgLy8gIElmIHRoZSBjaGlsZCBjb3VudCBpcyBncmVhdGVyIHRoYW4gb25lLCB0aGVuIG9idmlvdXNseQotICAgICAgICAgICAgICAgIC8vICBiYWQsIHNvIHJlcG9ydCBhbiBlcnJvciBhdCBpbmRleCAxLgotICAgICAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAgICAgaWYgKGxlbmd0aCA+IDEpCi0gICAgICAgICAgICAgICAgICAgIHJldHVybiAxOwotICAgICAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgICAgICBjYXNlIFhNTENvbnRlbnRTcGVjLkNPTlRFTlRTUEVDTk9ERV9aRVJPX09SX01PUkUgOgotICAgICAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAgICAgLy8gIElmIHRoZSBjaGlsZCBjb3VudCBpcyB6ZXJvLCB0aGF0J3MgZmluZS4gSWYgaXRzIG1vcmUgdGhhbgotICAgICAgICAgICAgICAgIC8vICB6ZXJvLCB0aGVuIG1ha2Ugc3VyZSB0aGF0IGFsbCBjaGlsZHJlbiBhcmUgb2YgdGhlIGVsZW1lbnQKLSAgICAgICAgICAgICAgICAvLyAgdHlwZSB0aGF0IHdlIHN0b3JlZC4gSWYgbm90LCByZXBvcnQgdGhlIGluZGV4IG9mIHRoZSBmaXJzdAotICAgICAgICAgICAgICAgIC8vICBmYWlsZWQgb25lLgotICAgICAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAgICAgaWYgKGxlbmd0aCA+IDApCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpbmRleCA9IDA7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCsrKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2hpbGRyZW5bb2Zmc2V0ICsgaW5kZXhdLnJhd25hbWUgIT0gZkZpcnN0Q2hpbGQucmF3bmFtZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpbmRleDsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBicmVhazsKLQotICAgICAgICAgICAgY2FzZSBYTUxDb250ZW50U3BlYy5DT05URU5UU1BFQ05PREVfT05FX09SX01PUkUgOgotICAgICAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAgICAgLy8gIElmIHRoZSBjaGlsZCBjb3VudCBpcyB6ZXJvLCB0aGF0J3MgYW4gZXJyb3Igc28gcmVwb3J0Ci0gICAgICAgICAgICAgICAgLy8gIGFuIGVycm9yIGF0IGluZGV4IDAuCi0gICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICBpZiAobGVuZ3RoID09IDApCi0gICAgICAgICAgICAgICAgICAgIHJldHVybiAwOwotCi0gICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICAvLyAgT3RoZXJ3aXNlIHdlIGhhdmUgdG8gY2hlY2sgdGhlbSBhbGwgdG8gbWFrZSBzdXJlIHRoYXQgdGhleQotICAgICAgICAgICAgICAgIC8vICBhcmUgb2YgdGhlIGNvcnJlY3QgY2hpbGQgdHlwZS4gSWYgbm90LCB0aGVuIHJlcG9ydCB0aGUgaW5kZXgKLSAgICAgICAgICAgICAgICAvLyAgb2YgdGhlIGZpcnN0IG9uZSB0aGF0IGlzIG5vdC4KLSAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgIGZvciAoaW50IGluZGV4ID0gMDsgaW5kZXggPCBsZW5ndGg7IGluZGV4KyspIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGNoaWxkcmVuW29mZnNldCArIGluZGV4XS5yYXduYW1lICE9IGZGaXJzdENoaWxkLnJhd25hbWUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpbmRleDsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBicmVhazsKLQotICAgICAgICAgICAgY2FzZSBYTUxDb250ZW50U3BlYy5DT05URU5UU1BFQ05PREVfQ0hPSUNFIDoKLSAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgIC8vICBUaGVyZSBtdXN0IGJlIG9uZSBhbmQgb25seSBvbmUgY2hpbGQsIHNvIGlmIHRoZSBlbGVtZW50IGNvdW50Ci0gICAgICAgICAgICAgICAgLy8gIGlzIHplcm8sIHJldHVybiBhbiBlcnJvciBhdCBpbmRleCAwLgotICAgICAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAgICAgaWYgKGxlbmd0aCA9PSAwKQotICAgICAgICAgICAgICAgICAgICByZXR1cm4gMDsKLQotICAgICAgICAgICAgICAgIC8vIElmIHRoZSB6ZXJvdGggZWxlbWVudCBpc24ndCBvbmUgb2Ygb3VyIGNob2ljZXMsIGVycm9yIGF0IDAKLSAgICAgICAgICAgICAgICBpZiAoKGNoaWxkcmVuW29mZnNldF0ucmF3bmFtZSAhPSBmRmlyc3RDaGlsZC5yYXduYW1lKSAmJgotICAgICAgICAgICAgICAgICAgICAoY2hpbGRyZW5bb2Zmc2V0XS5yYXduYW1lICE9IGZTZWNvbmRDaGlsZC5yYXduYW1lKSkgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gMDsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyBJZiB0aGVyZSBpcyBtb3JlIHRoYW4gb25lIGVsZW1lbnQsIHRoZW4gYW4gZXJyb3IgYXQgMQotICAgICAgICAgICAgICAgIGlmIChsZW5ndGggPiAxKQotICAgICAgICAgICAgICAgICAgICByZXR1cm4gMTsKLSAgICAgICAgICAgICAgICBicmVhazsKLQotICAgICAgICAgICAgY2FzZSBYTUxDb250ZW50U3BlYy5DT05URU5UU1BFQ05PREVfU0VRIDoKLSAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgIC8vICBUaGVyZSBtdXN0IGJlIHR3byBjaGlsZHJlbiBhbmQgdGhleSBtdXN0IGJlIHRoZSB0d28gdmFsdWVzCi0gICAgICAgICAgICAgICAgLy8gIHdlIHN0b3JlZCwgaW4gdGhlIHN0b3JlZCBvcmRlci4KLSAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgIGlmIChsZW5ndGggPT0gMikgewotICAgICAgICAgICAgICAgICAgICBpZiAoY2hpbGRyZW5bb2Zmc2V0XS5yYXduYW1lICE9IGZGaXJzdENoaWxkLnJhd25hbWUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAwOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGlmIChjaGlsZHJlbltvZmZzZXQgKyAxXS5yYXduYW1lICE9IGZTZWNvbmRDaGlsZC5yYXduYW1lKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gMTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGxlbmd0aCA+IDIpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAyOwotICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGxlbmd0aDsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBicmVhazsKLQotICAgICAgICAgICAgZGVmYXVsdCA6Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIkltcGxlbWVudGF0aW9uTWVzc2FnZXMuVkFMX0NTVCIpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gV2Ugc3Vydml2ZWQsIHNvIHJldHVybiBzdWNjZXNzIHN0YXR1cwotICAgICAgICByZXR1cm4gLTE7Ci0gICAgfSAvLyB2YWxpZGF0ZQotCi19IC8vIGNsYXNzIFNpbXBsZUNvbnRlbnRNb2RlbApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi9EVEREVkZhY3RvcnkuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYvRFRERFZGYWN0b3J5LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGNjZmNjYjAuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi9EVEREVkZhY3RvcnkuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEwMSArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDE1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICovCi0vKgotICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCi0gKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKLSAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KLSAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCi0gKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAotICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2OwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LmR0ZC5EVEREVkZhY3RvcnlJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5kdGQuWE1MMTFEVEREVkZhY3RvcnlJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbHMuT2JqZWN0RmFjdG9yeTsKLWltcG9ydCBqYXZhLnV0aWwuTWFwOwotCi0vKioKLSAqIFRoZSBmYWN0b3J5IHRvIGNyZWF0ZSBhbmQgcmV0dXJuIERURCB0eXBlcy4gVGhlIGltcGxlbWVudGF0aW9uIHNob3VsZAotICogc3RvcmUgdGhlIGNyZWF0ZWQgZGF0YXR5cGVzIGluIHN0YXRpYyBkYXRhLCBzbyB0aGF0IHRoZXkgY2FuIGJlIHNoYXJlZCBieQotICogbXVsdGlwbGUgcGFyc2VyIGluc3RhbmNlLCBhbmQgbXVsdGlwbGUgdGhyZWFkcy4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBTYW5keSBHYW8sIElCTQotICoKLSAqIEB2ZXJzaW9uICRJZDogRFRERFZGYWN0b3J5LmphdmEsdiAxLjYgMjAxMC0xMS0wMSAwNDozOTo0MyBqb2VodyBFeHAgJAotICovCi1wdWJsaWMgYWJzdHJhY3QgY2xhc3MgRFRERFZGYWN0b3J5IHsKLQotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBERUZBVUxUX0ZBQ1RPUllfQ0xBU1MgPQotICAgICAgICAgICAgImNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5kdGQuRFRERFZGYWN0b3J5SW1wbCI7Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MMTFfREFUQVRZUEVfVkFMSURBVE9SX0ZBQ1RPUlkgPQotICAgICAgICAiY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LmR0ZC5YTUwxMURURERWRmFjdG9yeUltcGwiOwotCi0gICAgLyoqCi0gICAgICogR2V0IGFuIGluc3RhbmNlIG9mIHRoZSBkZWZhdWx0IERURERWRmFjdG9yeSBpbXBsZW1lbnRhdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gIGFuIGluc3RhbmNlIG9mIERURERWRmFjdG9yeSBpbXBsZW1lbnRhdGlvbgotICAgICAqIEBleGNlcHRpb24gRFZGYWN0b3J5RXhjZXB0aW9uICBjYW5ub3QgY3JlYXRlIGFuIGluc3RhbmNlIG9mIHRoZSBzcGVjaWZpZWQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3MgbmFtZSBvciB0aGUgZGVmYXVsdCBjbGFzcyBuYW1lCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBEVEREVkZhY3RvcnkgZ2V0SW5zdGFuY2UoKSB0aHJvd3MgRFZGYWN0b3J5RXhjZXB0aW9uIHsKLSAgICAgICAgcmV0dXJuIGdldEluc3RhbmNlKERFRkFVTFRfRkFDVE9SWV9DTEFTUyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IGFuIGluc3RhbmNlIG9mIERURERWRmFjdG9yeSBpbXBsZW1lbnRhdGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBmYWN0b3J5Q2xhc3MgIG5hbWUgb2YgdGhlIGltcGxlbWVudGF0aW9uIHRvIGxvYWQuCi0gICAgICogQHJldHVybiAgYW4gaW5zdGFuY2Ugb2YgRFRERFZGYWN0b3J5IGltcGxlbWVudGF0aW9uCi0gICAgICogQGV4Y2VwdGlvbiBEVkZhY3RvcnlFeGNlcHRpb24gIGNhbm5vdCBjcmVhdGUgYW4gaW5zdGFuY2Ugb2YgdGhlIHNwZWNpZmllZAotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcyBuYW1lIG9yIHRoZSBkZWZhdWx0IGNsYXNzIG5hbWUKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIERURERWRmFjdG9yeSBnZXRJbnN0YW5jZShTdHJpbmcgZmFjdG9yeUNsYXNzKSB0aHJvd3MgRFZGYWN0b3J5RXhjZXB0aW9uIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGlmIChERUZBVUxUX0ZBQ1RPUllfQ0xBU1MuZXF1YWxzKGZhY3RvcnlDbGFzcykpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gbmV3IERURERWRmFjdG9yeUltcGwoKTsKLSAgICAgICAgICAgIH0gZWxzZSBpZiAoWE1MMTFfREFUQVRZUEVfVkFMSURBVE9SX0ZBQ1RPUlkuZXF1YWxzKGZhY3RvcnlDbGFzcykpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFhNTDExRFRERFZGYWN0b3J5SW1wbCgpOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAvL2ZhbGwgYmFjayBmb3IgY29tcGF0aWJpbGl0eQotICAgICAgICAgICAgICAgIHJldHVybiAoRFRERFZGYWN0b3J5KQotICAgICAgICAgICAgICAgICAgICAoT2JqZWN0RmFjdG9yeS5uZXdJbnN0YW5jZShmYWN0b3J5Q2xhc3MsIHRydWUpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBEVkZhY3RvcnlFeGNlcHRpb24oIkRURCBmYWN0b3J5IGNsYXNzICIgKyBmYWN0b3J5Q2xhc3MgKyAiIGRvZXMgbm90IGV4dGVuZCBmcm9tIERURERWRmFjdG9yeS4iKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8vIGNhbid0IGNyZWF0ZSBhIG5ldyBvYmplY3Qgb2YgdGhpcyBjbGFzcwotICAgIHByb3RlY3RlZCBEVEREVkZhY3RvcnkoKSB7fQotCi0gICAgLyoqCi0gICAgICogcmV0dXJuIGEgZHRkIHR5cGUgb2YgdGhlIGdpdmVuIG5hbWUKLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lICB0aGUgbmFtZSBvZiB0aGUgZGF0YXR5cGUKLSAgICAgKiBAcmV0dXJuICAgICAgdGhlIGRhdGF0eXBlIHZhbGlkYXRvciBvZiB0aGUgZ2l2ZW4gbmFtZQotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCBEYXRhdHlwZVZhbGlkYXRvciBnZXRCdWlsdEluRFYoU3RyaW5nIG5hbWUpOwotCi0gICAgLyoqCi0gICAgICogZ2V0IGFsbCBidWlsdC1pbiBEVnMsIHdoaWNoIGFyZSBzdG9yZWQgaW4gYSBtYXAga2V5ZWQgYnkgdGhlIG5hbWUKLSAgICAgKgotICAgICAqIEByZXR1cm4gICAgICBhIG1hcCB3aGljaCBjb250YWlucyBhbGwgZGF0YXR5cGVzCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IE1hcDxTdHJpbmcsIERhdGF0eXBlVmFsaWRhdG9yPiBnZXRCdWlsdEluVHlwZXMoKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi9EVkZhY3RvcnlFeGNlcHRpb24uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYvRFZGYWN0b3J5RXhjZXB0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDE0OWQ3MTcuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi9EVkZhY3RvcnlFeGNlcHRpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQyICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEsIDIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2OwotCi0vKioKLSAqIEEgcnVudGltZSBleGNlcHRpb24gdGhhdCdzIHRocm93biBpZiBhbiBlcnJvciBoYXBwZW5zIHdoZW4gdGhlIGFwcGxpY2F0aW9uCi0gKiB0cmllcyB0byBnZXQgYSBEViBmYWN0b3J5IGluc3RhbmNlLgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKi8KLXB1YmxpYyBjbGFzcyBEVkZhY3RvcnlFeGNlcHRpb24gZXh0ZW5kcyBSdW50aW1lRXhjZXB0aW9uIHsKLQotICAgIC8qKiBTZXJpYWxpemF0aW9uIHZlcnNpb24uICovCi0gICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC0zNzM4ODU0Njk3OTI4NjgyNDEyTDsKLQotICAgIHB1YmxpYyBEVkZhY3RvcnlFeGNlcHRpb24oKSB7Ci0gICAgICAgIHN1cGVyKCk7Ci0gICAgfQotCi0gICAgcHVibGljIERWRmFjdG9yeUV4Y2VwdGlvbihTdHJpbmcgbXNnKSB7Ci0gICAgICAgIHN1cGVyKG1zZyk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi9EYXRhdHlwZUV4Y2VwdGlvbi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi9EYXRhdHlwZUV4Y2VwdGlvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmMzhiMWQzLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYvRGF0YXR5cGVFeGNlcHRpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExMCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLCAyMDAyLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbHMuU2VjdXJpdHlTdXBwb3J0OwotaW1wb3J0IGphdmEudXRpbC5SZXNvdXJjZUJ1bmRsZTsKLWltcG9ydCBqYXZhLnV0aWwuUHJvcGVydHlSZXNvdXJjZUJ1bmRsZTsKLWltcG9ydCBqYXZhLnV0aWwuTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uOwotCi0vKioKLSAqIEJhc2UgY2xhc3MgZm9yIGRhdGF0eXBlIGV4Y2VwdGlvbnMuIEZvciBEVEQgdHlwZXMsIHRoZSBleGNlcHRpb24gY2FuIGJlCi0gKiBjcmVhdGVkIGZyb20gYW4gZXJyb3IgbWVzc2FnZS4gRm9yIFNjaGVtYSB0eXBlcywgaXQgbmVlZHMgYW4gZXJyb3IgY29kZQotICogKGFzIGRlZmluZWQgaW4gQXBwZW5kaXggQyBvZiB0aGUgc3RydWN0dXJlIHNwZWMpLCBwbHVzIGFuIGFycmF5IG9mIGFyZ3VlbnRzLAotICogZm9yIGVycm9yIG1lc3NhZ2Ugc3Vic3RpdHV0aW9uLgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIFNhbmR5IEdhbywgSUJNCi0gKgotICogQHZlcnNpb24gJElkOiBEYXRhdHlwZUV4Y2VwdGlvbi5qYXZhLHYgMS42IDIwMTAtMTEtMDEgMDQ6Mzk6NDMgam9laHcgRXhwICQKLSAqLwotcHVibGljIGNsYXNzIERhdGF0eXBlRXhjZXB0aW9uIGV4dGVuZHMgRXhjZXB0aW9uIHsKLQotICAgIC8qKiBTZXJpYWxpemF0aW9uIHZlcnNpb24uICovCi0gICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDE5NDA4MDU4MzI3MzA0NjU1NzhMOwotCi0gICAgLy8gdXNlZCB0byBzdG9yZSBlcnJvciBjb2RlIGFuZCBlcnJvciBzdWJzdGl0dXRpb24gYXJndW1lbnRzCi0gICAgcHJvdGVjdGVkIFN0cmluZyBrZXk7Ci0gICAgcHJvdGVjdGVkIE9iamVjdFtdIGFyZ3M7Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGUgYSBuZXcgZGF0YXR5cGUgZXhjZXB0aW9uIGJ5IHByb3ZpZGluZyBhbiBlcnJvciBjb2RlIGFuZCBhIGxpc3QKLSAgICAgKiBvZiBlcnJvciBtZXNzYWdlIHN1YnN0aXR1dGlvbiBhcmd1bWVudHMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0ga2V5ICBlcnJvciBjb2RlCi0gICAgICogQHBhcmFtIGFyZ3MgZXJyb3IgYXJndW1lbnRzCi0gICAgICovCi0gICAgcHVibGljIERhdGF0eXBlRXhjZXB0aW9uKFN0cmluZyBrZXksIE9iamVjdFtdIGFyZ3MpIHsKLSAgICAgICAgc3VwZXIoa2V5KTsKLSAgICAgICAgdGhpcy5rZXkgPSBrZXk7Ci0gICAgICAgIHRoaXMuYXJncyA9IGFyZ3M7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSBlcnJvciBjb2RlCi0gICAgICoKLSAgICAgKiBAcmV0dXJuICBlcnJvciBjb2RlCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRLZXkoKSB7Ci0gICAgICAgIHJldHVybiBrZXk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSBsaXN0IG9mIGVycm9yIGFyZ3VtZW50cwotICAgICAqCi0gICAgICogQHJldHVybiAgZXJyb3IgYXJndW1lbnRzCi0gICAgICovCi0gICAgcHVibGljIE9iamVjdFtdIGdldEFyZ3MoKSB7Ci0gICAgICAgIHJldHVybiBhcmdzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIE92ZXJyaWRlcyB0aGlzIG1ldGhvZCB0byBnZXQgdGhlIGZvcm1hdHRlZCZsb2NhbGl6ZWQgZXJyb3IgbWVzc2FnZS4KLSAgICAgKgotICAgICAqIFJFVklTSVQ6IHRoZSBzeXN0ZW0gbG9jYWxlIGlzIHVzZWQgdG8gbG9hZCB0aGUgcHJvcGVydHkgZmlsZS4KLSAgICAgKiAgICAgICAgICBkbyB3ZSB3YW50IHRvIGFsbG93IHRoZSBhcHBpbGNhdGlvbiB0byBzcGVjaWZ5IGEKLSAgICAgKiAgICAgICAgICBkaWZmZXJlbnQgbG9jYWxlPwotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TWVzc2FnZSgpIHsKLSAgICAgICAgUmVzb3VyY2VCdW5kbGUgcmVzb3VyY2VCdW5kbGUgPSBudWxsOwotICAgICAgICByZXNvdXJjZUJ1bmRsZSA9IFNlY3VyaXR5U3VwcG9ydC5nZXRSZXNvdXJjZUJ1bmRsZSgiY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLm1zZy5YTUxTY2hlbWFNZXNzYWdlcyIpOwotICAgICAgICBpZiAocmVzb3VyY2VCdW5kbGUgPT0gbnVsbCkKLSAgICAgICAgICAgIHRocm93IG5ldyBNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24oIlByb3BlcnR5IGZpbGUgbm90IGZvdW5kISIsICJjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwubXNnLlhNTFNjaGVtYU1lc3NhZ2VzIiwga2V5KTsKLQotICAgICAgICBTdHJpbmcgbXNnID0gcmVzb3VyY2VCdW5kbGUuZ2V0U3RyaW5nKGtleSk7Ci0gICAgICAgIGlmIChtc2cgPT0gbnVsbCkgewotICAgICAgICAgICAgbXNnID0gcmVzb3VyY2VCdW5kbGUuZ2V0U3RyaW5nKCJCYWRNZXNzYWdlS2V5Iik7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uKG1zZywgImNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5tc2cuWE1MU2NoZW1hTWVzc2FnZXMiLCBrZXkpOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKGFyZ3MgIT0gbnVsbCkgewotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICBtc2cgPSBqYXZhLnRleHQuTWVzc2FnZUZvcm1hdC5mb3JtYXQobXNnLCBhcmdzKTsKLSAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgbXNnID0gcmVzb3VyY2VCdW5kbGUuZ2V0U3RyaW5nKCJGb3JtYXRGYWlsZWQiKTsKLSAgICAgICAgICAgICAgICBtc2cgKz0gIiAiICsgcmVzb3VyY2VCdW5kbGUuZ2V0U3RyaW5nKGtleSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gbXNnOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYvRGF0YXR5cGVWYWxpZGF0b3IuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYvRGF0YXR5cGVWYWxpZGF0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNjhjZDM5Ni4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L0RhdGF0eXBlVmFsaWRhdG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0NSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLCAyMDAyLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5WYWxpZGF0aW9uQ29udGV4dDsKLQotLyoqCi0gKiBUaGUgaW50ZXJmYWNlIHRoYXQgYSBEVEQgZGF0YXR5cGUgbXVzdCBpbXBsZW1lbnQuIFRoZSBpbXBsZW1lbnRhdGlvbiBvZiB0aGlzCi0gKiBpbnRlcmZhY2UgbXVzdCBiZSB0aHJlYWQtc2FmZS4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBTYW5keSBHYW8sIElCTQotICoKLSAqLwotcHVibGljIGludGVyZmFjZSBEYXRhdHlwZVZhbGlkYXRvciB7Ci0KLSAgICAvKioKLSAgICAgKiB2YWxpZGF0ZSBhIGdpdmVuIHN0cmluZyBhZ2FpbnN0IHRoaXMgRFYKLSAgICAgKgotICAgICAqIEBwYXJhbSBjb250ZW50ICAgICAgIHRoZSBzdHJpbmcgdmFsdWUgdGhhdCBuZWVkcyB0byBiZSB2YWxpZGF0ZWQKLSAgICAgKiBAcGFyYW0gY29udGV4dCAgICAgICB0aGUgdmFsaWRhdGlvbiBjb250ZXh0Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgdmFsaWRhdGUoU3RyaW5nIGNvbnRlbnQsIFZhbGlkYXRpb25Db250ZXh0IGNvbnRleHQpCi0gICAgICAgIHRocm93cyBJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbjsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi9JbnZhbGlkRGF0YXR5cGVGYWNldEV4Y2VwdGlvbi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi9JbnZhbGlkRGF0YXR5cGVGYWNldEV4Y2VwdGlvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyMmJlNGI1Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYvSW52YWxpZERhdGF0eXBlRmFjZXRFeGNlcHRpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQ4ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEsIDIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2OwotCi0vKioKLSAqIERhdGF0eXBlIGV4Y2VwdGlvbiBmb3IgaW52YWxpZCBmYWNldC4gVGhpcyBleGNlcHRpb24gaXMgb25seSB1c2VkIGJ5Ci0gKiBzY2hlbWEgZGF0YXR5cGVzLgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIFNhbmR5IEdhbywgSUJNCi0gKgotICovCi1wdWJsaWMgY2xhc3MgSW52YWxpZERhdGF0eXBlRmFjZXRFeGNlcHRpb24gZXh0ZW5kcyBEYXRhdHlwZUV4Y2VwdGlvbiB7Ci0KLSAgICAvKiogU2VyaWFsaXphdGlvbiB2ZXJzaW9uLiAqLwotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNDEwNDA2NjA4NTkwOTk3MDY1NEw7Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGUgYSBuZXcgZGF0YXR5cGUgZXhjZXB0aW9uIGJ5IHByb3ZpZGluZyBhbiBlcnJvciBjb2RlIGFuZCBhIGxpc3QKLSAgICAgKiBvZiBlcnJvciBtZXNzYWdlIHN1YnN0aXR1dGlvbiBhcmd1bWVudHMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0ga2V5ICBlcnJvciBjb2RlCi0gICAgICogQHBhcmFtIGFyZ3MgZXJyb3IgYXJndW1lbnRzCi0gICAgICovCi0gICAgcHVibGljIEludmFsaWREYXRhdHlwZUZhY2V0RXhjZXB0aW9uKFN0cmluZyBrZXksIE9iamVjdFtdIGFyZ3MpIHsKLSAgICAgICAgc3VwZXIoa2V5LCBhcmdzKTsKLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYvSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYvSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNjQ4ZGQxZS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L0ludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4OCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxLCAyMDAyIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGVyY2VzIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBJbnRlcm5hdGlvbmFsCi0gKiBCdXNpbmVzcyBNYWNoaW5lcywgSW5jLiwgaHR0cDovL3d3dy5hcGFjaGUub3JnLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2OwotCi0vKioKLSAqIERhdGF0eXBlIGV4Y2VwdGlvbiBmb3IgaW52YWxpZCB2YWx1ZXMuCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgU2FuZHkgR2FvLCBJQk0KLSAqCi0gKi8KLXB1YmxpYyBjbGFzcyBJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbiBleHRlbmRzIERhdGF0eXBlRXhjZXB0aW9uIHsKLQotICAgIC8qKiBTZXJpYWxpemF0aW9uIHZlcnNpb24uICovCi0gICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC01NTIzNzM5NDI2OTU4MjM2MTI1TDsKLQotICAgIC8qKgotICAgICAqIENyZWF0ZSBhIG5ldyBkYXRhdHlwZSBleGNlcHRpb24gYnkgcHJvdmlkaW5nIGFuIGVycm9yIGNvZGUgYW5kIGEgbGlzdAotICAgICAqIG9mIGVycm9yIG1lc3NhZ2Ugc3Vic3RpdHV0aW9uIGFyZ3VtZW50cy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBrZXkgIGVycm9yIGNvZGUKLSAgICAgKiBAcGFyYW0gYXJncyBlcnJvciBhcmd1bWVudHMKLSAgICAgKi8KLSAgICBwdWJsaWMgSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24oU3RyaW5nIGtleSwgT2JqZWN0W10gYXJncykgewotICAgICAgICBzdXBlcihrZXksIGFyZ3MpOwotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi9TY2hlbWFEVkZhY3RvcnkuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYvU2NoZW1hRFZGYWN0b3J5LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDkwMmQ5ZDMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi9TY2hlbWFEVkZhY3RvcnkuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE0OSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5TeW1ib2xIYXNoOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNPYmplY3RMaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbHMuT2JqZWN0RmFjdG9yeTsKLQotLyoqCi0gKiBEZWZpbmVzIGEgZmFjdG9yeSBBUEkgdGhhdCBlbmFibGVzIGFwcGxpY2F0aW9ucyB0byA8cD4KLSAqIDEuIHRvIGdldCB0aGUgaW5zdGFuY2Ugb2Ygc3BlY2lmaWVkIFNjaGVtYURWRmFjdG9yeSBpbXBsZW1lbnRhdGlvbiA8cD4KLSAqIDIuIHRvIGNyZWF0ZS9yZXR1cm4gYnVpbHQtaW4gc2NoZW1hIHNpbXBsZSB0eXBlcyA8cD4KLSAqIDMuIHRvIGNyZWF0ZSB1c2VyIGRlZmluZWQgc2ltcGxlIHR5cGVzLiA8cD4KLSAqCi0gKiBJbXBsZW1lbnRhdGlvbnMgb2YgdGhpcyBhYnN0cmFjdCBjbGFzcyBjYW4gYmUgdXNlZCB0byBnZXQgYnVpbHQtaW4gc2ltcGxlCi0gKiB0eXBlcyBhbmQgY3JlYXRlIHVzZXItZGVmaW5lZCBzaW1sZSB0eXBlcy4gPHA+Ci0gKgotICogVGhlIGltcGxlbWVudGF0aW9uIHNob3VsZCBzdG9yZSB0aGUgYnVpbHQtaW4gZGF0YXR5cGVzIGluIHN0YXRpYyBkYXRhLCBzbwotICogdGhhdCB0aGV5IGNhbiBiZSBzaGFyZWQgYnkgbXVsdGlwbGUgcGFyc2VyIGluc3RhbmNlLCBhbmQgbXVsdGlwbGUgdGhyZWFkcy4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBTYW5keSBHYW8sIElCTQotICoKLSAqIEB2ZXJzaW9uICRJZDogU2NoZW1hRFZGYWN0b3J5LmphdmEsdiAxLjYgMjAxMC0xMS0wMSAwNDozOTo0MyBqb2VodyBFeHAgJAotICovCi1wdWJsaWMgYWJzdHJhY3QgY2xhc3MgU2NoZW1hRFZGYWN0b3J5IHsKLQotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBERUZBVUxUX0ZBQ1RPUllfQ0xBU1MgPSAiY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LnhzLlNjaGVtYURWRmFjdG9yeUltcGwiOwotCi0gICAgLyoqCi0gICAgICogR2V0IGEgZGVmYXVsdCBpbnN0YW5jZSBvZiBTY2hlbWFEVkZhY3RvcnkgaW1wbGVtZW50YXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuICBhbiBpbnN0YW5jZSBvZiBTY2hlbWFEVkZhY3RvcnkgaW1wbGVtZW50YXRpb24KLSAgICAgKiBAZXhjZXB0aW9uIERWRmFjdG9yeUV4Y2VwdGlvbiAgY2Fubm90IGNyZWF0ZSBhbiBpbnN0YW5jZSBvZiB0aGUgc3BlY2lmaWVkCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzIG5hbWUgb3IgdGhlIGRlZmF1bHQgY2xhc3MgbmFtZQotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgc3luY2hyb25pemVkIGZpbmFsIFNjaGVtYURWRmFjdG9yeSBnZXRJbnN0YW5jZSgpIHRocm93cyBEVkZhY3RvcnlFeGNlcHRpb24gewotICAgICAgICByZXR1cm4gZ2V0SW5zdGFuY2UoREVGQVVMVF9GQUNUT1JZX0NMQVNTKTsKLSAgICB9IC8vZ2V0SW5zdGFuY2UoKTogIFNjaGVtYURWRmFjdG9yeQotCi0KLSAgICAvKioKLSAgICAgKiBHZXQgYW4gaW5zdGFuY2Ugb2YgU2NoZW1hRFZGYWN0b3J5IGltcGxlbWVudGF0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIGZhY3RvcnlDbGFzcyAgIG5hbWUgb2YgdGhlIHNjaGVtYSBmYWN0b3J5IGltcGxlbWVudGF0aW9uIHRvIGluc3RhbnRpYXRlLgotICAgICAqIEByZXR1cm4gIGFuIGluc3RhbmNlIG9mIFNjaGVtYURWRmFjdG9yeSBpbXBsZW1lbnRhdGlvbgotICAgICAqIEBleGNlcHRpb24gRFZGYWN0b3J5RXhjZXB0aW9uICBjYW5ub3QgY3JlYXRlIGFuIGluc3RhbmNlIG9mIHRoZSBzcGVjaWZpZWQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3MgbmFtZSBvciB0aGUgZGVmYXVsdCBjbGFzcyBuYW1lCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBzeW5jaHJvbml6ZWQgZmluYWwgU2NoZW1hRFZGYWN0b3J5IGdldEluc3RhbmNlKFN0cmluZyBmYWN0b3J5Q2xhc3MpIHRocm93cyBEVkZhY3RvcnlFeGNlcHRpb24gewotCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAvLyBpZiB0aGUgY2xhc3MgbmFtZSBpcyBub3Qgc3BlY2lmaWVkLCB1c2UgdGhlIGRlZmF1bHQgb25lCi0gICAgICAgICAgICByZXR1cm4gKFNjaGVtYURWRmFjdG9yeSkoT2JqZWN0RmFjdG9yeS5uZXdJbnN0YW5jZShmYWN0b3J5Q2xhc3MsIHRydWUpKTsKLSAgICAgICAgfSBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGU0KSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgRFZGYWN0b3J5RXhjZXB0aW9uKCJTY2hlbWEgZmFjdG9yeSBjbGFzcyAiICsgZmFjdG9yeUNsYXNzICsgIiBkb2VzIG5vdCBleHRlbmQgZnJvbSBTY2hlbWFEVkZhY3RvcnkuIik7Ci0gICAgICAgIH0KLQotICAgIH0KLQotICAgIC8vIGNhbid0IGNyZWF0ZSBhIG5ldyBvYmplY3Qgb2YgdGhpcyBjbGFzcwotICAgIHByb3RlY3RlZCBTY2hlbWFEVkZhY3RvcnkoKXt9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgYSBidWlsdC1pbiBzaW1wbGUgdHlwZSBvZiB0aGUgZ2l2ZW4gbmFtZQotICAgICAqIFJFVklTSVQ6IGl0cyBzdGlsbCBub3QgZGVjaWRlZCB3aXRoaW4gdGhlIFNjaGVtYSBXRyBob3cgdG8gZGVmaW5lIHRoZQotICAgICAqICAgICAgICAgIHVyLXR5cGVzIGFuZCBpZiBhbGwgc2ltcGxlIHR5cGVzIHNob3VsZCBiZSBkZXJpdmVkIGZyb20gYQotICAgICAqICAgICAgICAgIGNvbXBsZXggdHlwZSwgc28gYXMgb2Ygbm93IHdlIGlnbm9yZSB0aGUgZmFjdCB0aGF0IGFueVNpbXBsZVR5cGUKLSAgICAgKiAgICAgICAgICBpcyBkZXJpdmVkIGZyb20gYW55VHlwZSwgYW5kIHBhc3MgJ251bGwnIGFzIHRoZSBiYXNlIG9mCi0gICAgICogICAgICAgICAgYW55U2ltcGxlVHlwZS4gSXQgbmVlZHMgdG8gYmUgY2hhbmdlZCBhcyBwZXIgdGhlIGRlY2lzaW9uIHRha2VuLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgIHRoZSBuYW1lIG9mIHRoZSBkYXRhdHlwZQotICAgICAqIEByZXR1cm4gICAgICB0aGUgZGF0YXR5cGUgdmFsaWRhdG9yIG9mIHRoZSBnaXZlbiBuYW1lCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IFhTU2ltcGxlVHlwZSBnZXRCdWlsdEluVHlwZShTdHJpbmcgbmFtZSk7Ci0KLSAgICAvKioKLSAgICAgKiBnZXQgYWxsIGJ1aWx0LWluIHNpbXBsZSB0eXBlcywgd2hpY2ggYXJlIHN0b3JlZCBpbiBhIFN5bWJvbEhhc2gga2V5ZWQgYnkKLSAgICAgKiB0aGUgbmFtZQotICAgICAqCi0gICAgICogQHJldHVybiAgICAgIGEgU3ltYm9sSGFzaCB3aGljaCBjb250YWlucyBhbGwgYnVpbHQtaW4gc2ltcGxlIHR5cGVzCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IFN5bWJvbEhhc2ggZ2V0QnVpbHRJblR5cGVzKCk7Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGUgYSBuZXcgc2ltcGxlIHR5cGUgd2hpY2ggaXMgZGVyaXZlZCBieSByZXN0cmljdGlvbiBmcm9tIGFub3RoZXIKLSAgICAgKiBzaW1wbGUgdHlwZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lICAgICAgICAgICAgICBuYW1lIG9mIHRoZSBuZXcgdHlwZSwgY291bGQgYmUgbnVsbAotICAgICAqIEBwYXJhbSB0YXJnZXROYW1lc3BhY2UgICB0YXJnZXQgbmFtZXNwYWNlIG9mIHRoZSBuZXcgdHlwZSwgY291bGQgYmUgbnVsbAotICAgICAqIEBwYXJhbSBmaW5hbFNldCAgICAgICAgICB2YWx1ZSBvZiAiZmluYWwiCi0gICAgICogQHBhcmFtIGJhc2UgICAgICAgICAgICAgIGJhc2UgdHlwZSBvZiB0aGUgbmV3IHR5cGUKLSAgICAgKiBAcGFyYW0gYW5ub3RhdGlvbnMgICAgICAgc2V0IG9mIGFubm90YXRpb25zCi0gICAgICogQHJldHVybiAgICAgICAgICAgICAgICAgIHRoZSBuZXdseSBjcmVhdGVkIHNpbXBsZSB0eXBlCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IFhTU2ltcGxlVHlwZSBjcmVhdGVUeXBlUmVzdHJpY3Rpb24oU3RyaW5nIG5hbWUsIFN0cmluZyB0YXJnZXROYW1lc3BhY2UsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hvcnQgZmluYWxTZXQsIFhTU2ltcGxlVHlwZSBiYXNlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhTT2JqZWN0TGlzdCBhbm5vdGF0aW9ucyk7Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGUgYSBuZXcgc2ltcGxlIHR5cGUgd2hpY2ggaXMgZGVyaXZlZCBieSBsaXN0IGZyb20gYW5vdGhlciBzaW1wbGUKLSAgICAgKiB0eXBlLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgICAgICAgICAgICAgIG5hbWUgb2YgdGhlIG5ldyB0eXBlLCBjb3VsZCBiZSBudWxsCi0gICAgICogQHBhcmFtIHRhcmdldE5hbWVzcGFjZSAgIHRhcmdldCBuYW1lc3BhY2Ugb2YgdGhlIG5ldyB0eXBlLCBjb3VsZCBiZSBudWxsCi0gICAgICogQHBhcmFtIGZpbmFsU2V0ICAgICAgICAgIHZhbHVlIG9mICJmaW5hbCIKLSAgICAgKiBAcGFyYW0gaXRlbVR5cGUgICAgICAgICAgaXRlbSB0eXBlIG9mIHRoZSBsaXN0IHR5cGUKLSAgICAgKiBAcGFyYW0gYW5ub3RhdGlvbnMgICAgICAgc2V0IG9mIGFubm90YXRpb25zCi0gICAgICogQHJldHVybiAgICAgICAgICAgICAgICAgIHRoZSBuZXdseSBjcmVhdGVkIHNpbXBsZSB0eXBlCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IFhTU2ltcGxlVHlwZSBjcmVhdGVUeXBlTGlzdChTdHJpbmcgbmFtZSwgU3RyaW5nIHRhcmdldE5hbWVzcGFjZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNob3J0IGZpbmFsU2V0LCBYU1NpbXBsZVR5cGUgaXRlbVR5cGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYU09iamVjdExpc3QgYW5ub3RhdGlvbnMpOwotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlIGEgbmV3IHNpbXBsZSB0eXBlIHdoaWNoIGlzIGRlcml2ZWQgYnkgdW5pb24gZnJvbSBhIGxpc3Qgb2Ygb3RoZXIKLSAgICAgKiBzaW1wbGUgdHlwZXMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSAgICAgICAgICAgICAgbmFtZSBvZiB0aGUgbmV3IHR5cGUsIGNvdWxkIGJlIG51bGwKLSAgICAgKiBAcGFyYW0gdGFyZ2V0TmFtZXNwYWNlICAgdGFyZ2V0IG5hbWVzcGFjZSBvZiB0aGUgbmV3IHR5cGUsIGNvdWxkIGJlIG51bGwKLSAgICAgKiBAcGFyYW0gZmluYWxTZXQgICAgICAgICAgdmFsdWUgb2YgImZpbmFsIgotICAgICAqIEBwYXJhbSBtZW1iZXJUeXBlcyAgICAgICBtZW1iZXIgdHlwZXMgb2YgdGhlIHVuaW9uIHR5cGUKLSAgICAgKiBAcGFyYW0gYW5ub3RhdGlvbnMgICAgICAgc2V0IG9mIGFubm90YXRpb25zCi0gICAgICogQHJldHVybiAgICAgICAgICAgICAgICAgIHRoZSBuZXdseSBjcmVhdGVkIHNpbXBsZSB0eXBlCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IFhTU2ltcGxlVHlwZSBjcmVhdGVUeXBlVW5pb24oU3RyaW5nIG5hbWUsIFN0cmluZyB0YXJnZXROYW1lc3BhY2UsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hvcnQgZmluYWxTZXQsIFhTU2ltcGxlVHlwZVtdIG1lbWJlclR5cGVzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhTT2JqZWN0TGlzdCBhbm5vdGF0aW9ucyk7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYvVmFsaWRhdGVkSW5mby5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi9WYWxpZGF0ZWRJbmZvLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGU2YjhmMjYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi9WYWxpZGF0ZWRJbmZvLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5OCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLCAyMDAyLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuU2hvcnRMaXN0OwotCi0vKioKLSAqIENsYXNzIHRvIGdldCB0aGUgaW5mb3JtYXRpb24gYmFjayBhZnRlciBjb250ZW50IGlzIHZhbGlkYXRlZC4gVGhpcyBpbmZvCi0gKiB3b3VsZCBiZSBmaWxsZWQgYnkgdmFsaWRhdGUoKS4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBOZWVyYWogQmFqYWosIFN1biBNaWNyb3N5c3RlbXMsIGluYy4KLSAqCi0gKi8KLXB1YmxpYyBjbGFzcyBWYWxpZGF0ZWRJbmZvIHsKLQotICAgIC8qKgotICAgICAqIFRoZSBub3JtYWxpemVkIHZhbHVlIG9mIGEgc3RyaW5nIHZhbHVlCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBub3JtYWxpemVkVmFsdWU7Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgYWN0dWFsIHZhbHVlIGZyb20gYSBzdHJpbmcgdmFsdWUgKFFOYW1lLCBCb29sZWFuLCBldGMuKQotICAgICAqIEFuIGFycmF5IG9mIE9iamVjdHMgaWYgdGhlIHR5cGUgaXMgYSBsaXN0LgotICAgICAqLwotICAgIHB1YmxpYyBPYmplY3QgYWN0dWFsVmFsdWU7Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgdHlwZSBvZiB0aGUgYWN0dWFsIHZhbHVlLiBJdCdzIG9uZSBvZiB0aGUgX0RUIGNvbnN0YW50cwotICAgICAqIGRlZmluZWQgaW4gWFNDb25zdGFudHMuamF2YS4gVGhlIHZhbHVlIGlzIHVzZWQgdG8gaW5kaWNhdGUKLSAgICAgKiB0aGUgbW9zdCBzcGVjaWZpYyBidWlsdC1pbiB0eXBlLgotICAgICAqIChpLmUuIHNob3J0IGluc3RlYWQgb2YgZGVjaW1hbCBvciBpbnRlZ2VyKS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc2hvcnQgYWN0dWFsVmFsdWVUeXBlOwotCi0gICAgLyoqCi0gICAgICogSWYgdGhlIHR5cGUgaXMgYSB1bmlvbiB0eXBlLCB0aGVuIHRoZSBtZW1iZXIgdHlwZSB3aGljaAotICAgICAqIGFjdHVhbGx5IHZhbGlkYXRlZCB0aGUgc3RyaW5nIHZhbHVlLgotICAgICAqLwotICAgIHB1YmxpYyBYU1NpbXBsZVR5cGUgbWVtYmVyVHlwZTsKLQotICAgIC8qKgotICAgICAqIElmCi0gICAgICogMS4gdGhlIHR5cGUgaXMgYSB1bmlvbiB0eXBlIHdoZXJlIG9uZSBvZiB0aGUgbWVtYmVyIHR5cGVzIGlzIGEgbGlzdCwgb3IKLSAgICAgKiAgICBpZiB0aGUgdHlwZSBpcyBhIGxpc3Q7IGFuZAotICAgICAqIDIuIHRoZSBpdGVtIHR5cGUgb2YgdGhlIGxpc3QgaXMgYSB1bmlvbiB0eXBlCi0gICAgICogdGhlbiBhbiBhcnJheSBvZiBtZW1iZXIgdHlwZXMgdXNlZCB0byB2YWxpZGF0ZSB0aGUgdmFsdWVzLgotICAgICAqLwotICAgIHB1YmxpYyBYU1NpbXBsZVR5cGVbXSBtZW1iZXJUeXBlczsKLQotICAgIC8qKgotICAgICAqIEluIHRoZSBjYXNlIHRoZSB2YWx1ZSBpcyBhIGxpc3Qgb3IgYSBsaXN0IG9mIHVuaW9ucywgdGhpcyB2YWx1ZQotICAgICAqIGluZGljYXRlcyB0aGUgdHlwZShzKSBvZiB0aGUgaXRlbXMgaW4gdGhlIGxpc3QuCi0gICAgICogRm9yIGEgbm9ybWFsIGxpc3QsIHRoZSBsZW5ndGggb2YgdGhlIGFycmF5IGlzIDE7IGZvciBsaXN0IG9mIHVuaW9ucywKLSAgICAgKiB0aGUgbGVuZ3RoIG9mIHRoZSBhcnJheSBpcyB0aGUgc2FtZSBhcyB0aGUgbGVuZ3RoIG9mIHRoZSBsaXN0LgotICAgICAqLwotICAgIHB1YmxpYyBTaG9ydExpc3QgaXRlbVZhbHVlVHlwZXM7Ci0KLSAgICAvKioKLSAgICAgKiByZXNldCB0aGUgc3RhdGUgb2YgdGhpcyBvYmplY3QKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCByZXNldCgpIHsKLSAgICAgICAgdGhpcy5ub3JtYWxpemVkVmFsdWUgPSBudWxsOwotICAgICAgICB0aGlzLmFjdHVhbFZhbHVlID0gbnVsbDsKLSAgICAgICAgdGhpcy5tZW1iZXJUeXBlID0gbnVsbDsKLSAgICAgICAgdGhpcy5tZW1iZXJUeXBlcyA9IG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSB2YWx1ZS4gSWYgdGhlcmUgaXMgYW4gYWN0dWFsCi0gICAgICogdmFsdWUsIHVzZSB0b1N0cmluZzsgb3RoZXJ3aXNlLCB1c2UgdGhlIG5vcm1hbGl6ZWQgdmFsdWUuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBzdHJpbmdWYWx1ZSgpIHsKLSAgICAgICAgaWYgKGFjdHVhbFZhbHVlID09IG51bGwpCi0gICAgICAgICAgICByZXR1cm4gbm9ybWFsaXplZFZhbHVlOwotICAgICAgICBlbHNlCi0gICAgICAgICAgICByZXR1cm4gYWN0dWFsVmFsdWUudG9TdHJpbmcoKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L1ZhbGlkYXRpb25Db250ZXh0LmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L1ZhbGlkYXRpb25Db250ZXh0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDZmZjRkNjYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi9WYWxpZGF0aW9uQ29udGV4dC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNjcgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMSwgMjAwMiwyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHY7Ci0KLWltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwotCi0vKioKLSAqIFZhbGlkYXRpb25Db250ZXh0IGhhcyBhbGwgdGhlIGluZm9ybWF0aW9uIHJlcXVpcmVkIGZvciB0aGUKLSAqIHZhbGlkYXRpb24gb2Y6IGlkLCBpZHJlZiwgZW50aXR5LCBub3RhdGlvbiwgcW5hbWUKLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBTYW5keSBHYW8sIElCTQotICogQHZlcnNpb24gJElkOiBWYWxpZGF0aW9uQ29udGV4dC5qYXZhLHYgMS42IDIwMTAvMDcvMjMgMDI6MDk6Mjkgam9laHcgRXhwICQKLSAqLwotcHVibGljIGludGVyZmFjZSBWYWxpZGF0aW9uQ29udGV4dCB7Ci0gICAgLy8gd2hldGhlciB0byB2YWxpZGF0ZSBhZ2FpbnN0IGZhY2V0cwotICAgIHB1YmxpYyBib29sZWFuIG5lZWRGYWNldENoZWNraW5nKCk7Ci0KLSAgICAvLyB3aGV0aGVyIHRvIGRvIGV4dHJhIGlkL2lkcmVmL2VudGl0eSBjaGVja2luZwotICAgIHB1YmxpYyBib29sZWFuIG5lZWRFeHRyYUNoZWNraW5nKCk7Ci0KLSAgICAvLyB3aGV0aGVyIHdlIG5lZWQgdG8gbm9ybWFsaXplIHRoZSB2YWx1ZSB0aGF0IGlzIHBhc3NlZCEKLSAgICBwdWJsaWMgYm9vbGVhbiBuZWVkVG9Ob3JtYWxpemUoKTsKLQotICAgIC8vIGFyZSBuYW1lc3BhY2VzIHJlbGV2YW50IGluIHRoaXMgY29udGV4dD8KLSAgICBwdWJsaWMgYm9vbGVhbiB1c2VOYW1lc3BhY2VzKCk7Ci0KLSAgICAvLyBlbnRpdHkKLSAgICBwdWJsaWMgYm9vbGVhbiBpc0VudGl0eURlY2xhcmVkIChTdHJpbmcgbmFtZSk7Ci0gICAgcHVibGljIGJvb2xlYW4gaXNFbnRpdHlVbnBhcnNlZCAoU3RyaW5nIG5hbWUpOwotCi0gICAgLy8gaWQKLSAgICBwdWJsaWMgYm9vbGVhbiBpc0lkRGVjbGFyZWQgKFN0cmluZyBuYW1lKTsKLSAgICBwdWJsaWMgdm9pZCAgICBhZGRJZChTdHJpbmcgbmFtZSk7Ci0KLSAgICAvLyBpZHJlZgotICAgIHB1YmxpYyB2b2lkIGFkZElkUmVmKFN0cmluZyBuYW1lKTsKLQotICAgIC8vIGdldCBzeW1ib2wgZnJvbSBzeW1ib2wgdGFibGUKLSAgICBwdWJsaWMgU3RyaW5nIGdldFN5bWJvbCAoU3RyaW5nIHN5bWJvbCk7Ci0KLSAgICAvLyBxbmFtZQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VVJJKFN0cmluZyBwcmVmaXgpOwotCi0gICAgLy8gTG9jYWxlCi0gICAgcHVibGljIExvY2FsZSBnZXRMb2NhbGUoKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi9YU0ZhY2V0cy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi9YU0ZhY2V0cy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0YmFlYWYxLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYvWFNGYWNldHMuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEzNiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLCAyMDAyLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdjsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTQW5ub3RhdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTT2JqZWN0TGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMudXRpbC5YU09iamVjdExpc3RJbXBsOwotCi0vKioKLSAqIFRoZSBjbGFzcyB1c2VkIHRvIHBhc3MgYWxsIGZhY2V0cyB0byB7QGxpbmsgWFNTaW1wbGVUeXBlI2FwcGx5RmFjZXRzfS4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBTYW5keSBHYW8sIElCTQotICoKLSAqLwotcHVibGljIGNsYXNzIFhTRmFjZXRzIHsKLQotICAgIC8qKgotICAgICAqIHZhbHVlIG9mIGxlbmd0aCBmYWNldC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGxlbmd0aDsKLQotICAgIC8qKgotICAgICAqIHZhbHVlIG9mIG1pbkxlbmd0aCBmYWNldC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IG1pbkxlbmd0aDsKLQotICAgIC8qKgotICAgICAqIHZhbHVlIG9mIG1heExlbmd0aCBmYWNldC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IG1heExlbmd0aDsKLQotICAgIC8qKgotICAgICAqIHZhbHVlIG9mIHdoaXRlU3BhY2UgZmFjZXQuCi0gICAgICovCi0gICAgcHVibGljIHNob3J0IHdoaXRlU3BhY2U7Ci0KLSAgICAvKioKLSAgICAgKiB2YWx1ZSBvZiB0b3RhbERpZ2l0cyBmYWNldC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IHRvdGFsRGlnaXRzOwotCi0gICAgLyoqCi0gICAgICogdmFsdWUgb2YgZnJhY3Rpb25EaWdpdHMgZmFjZXQuCi0gICAgICovCi0gICAgcHVibGljIGludCBmcmFjdGlvbkRpZ2l0czsKLQotICAgIC8qKgotICAgICAqIHN0cmluZyBjb250YWluaW5nIHZhbHVlIG9mIHBhdHRlcm4gZmFjZXQsIGZvciBtdWx0aXBsZSBwYXR0ZXJucyB2YWx1ZXMKLSAgICAgKiBhcmUgT1JlZCB0b2dldGhlci4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIHBhdHRlcm47Ci0KLSAgICAvKioKLSAgICAgKiBWZWN0b3IgY29udGFpbmluZyB2YWx1ZXMgb2YgRW51bWVyYXRpb24gZmFjZXQsIGFzIFN0cmluZydzLgotICAgICAqLwotICAgIHB1YmxpYyBWZWN0b3IgZW51bWVyYXRpb247Ci0KLSAgICAvKioKLSAgICAgKiBBbiBhcnJheSBwYXJhbGxlbCB0byAiVmVjdG9yIGVudW1lcmF0aW9uIi4gSXQgY29udGFpbnMgbmFtZXNwYWNlIGNvbnRleHQKLSAgICAgKiBvZiBlYWNoIGVudW1lcmF0aW9uIHZhbHVlLiBFbGVtZW50cyBvZiB0aGlzIHZlY3RvciBhcmUgTmFtZXNwYWNlQ29udGV4dAotICAgICAqIG9iamVjdHMuCi0gICAgICovCi0gICAgcHVibGljIFZlY3RvciBlbnVtTlNEZWNsczsKLQotICAgIC8qKgotICAgICAqIHZhbHVlIG9mIG1heEluY2x1c2l2ZSBmYWNldC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIG1heEluY2x1c2l2ZTsKLQotICAgIC8qKgotICAgICAqIHZhbHVlIG9mIG1heEV4Y2x1c2l2ZSBmYWNldC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIG1heEV4Y2x1c2l2ZTsKLQotICAgIC8qKgotICAgICAqIHZhbHVlIG9mIG1pbkluY2x1c2l2ZSBmYWNldC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIG1pbkluY2x1c2l2ZTsKLQotICAgIC8qKgotICAgICAqIHZhbHVlIG9mIG1pbkV4Y2x1c2l2ZSBmYWNldC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIG1pbkV4Y2x1c2l2ZTsKLQotCi0KLSAgICBwdWJsaWMgWFNBbm5vdGF0aW9uIGxlbmd0aEFubm90YXRpb247Ci0gICAgcHVibGljIFhTQW5ub3RhdGlvbiBtaW5MZW5ndGhBbm5vdGF0aW9uOwotICAgIHB1YmxpYyBYU0Fubm90YXRpb24gbWF4TGVuZ3RoQW5ub3RhdGlvbjsKLSAgICBwdWJsaWMgWFNBbm5vdGF0aW9uIHdoaXRlU3BhY2VBbm5vdGF0aW9uOwotICAgIHB1YmxpYyBYU0Fubm90YXRpb24gdG90YWxEaWdpdHNBbm5vdGF0aW9uOwotICAgIHB1YmxpYyBYU0Fubm90YXRpb24gZnJhY3Rpb25EaWdpdHNBbm5vdGF0aW9uOwotICAgIHB1YmxpYyBYU09iamVjdExpc3RJbXBsIHBhdHRlcm5Bbm5vdGF0aW9uczsKLSAgICBwdWJsaWMgWFNPYmplY3RMaXN0IGVudW1Bbm5vdGF0aW9uczsKLSAgICBwdWJsaWMgWFNBbm5vdGF0aW9uIG1heEluY2x1c2l2ZUFubm90YXRpb247Ci0gICAgcHVibGljIFhTQW5ub3RhdGlvbiBtYXhFeGNsdXNpdmVBbm5vdGF0aW9uOwotICAgIHB1YmxpYyBYU0Fubm90YXRpb24gbWluSW5jbHVzaXZlQW5ub3RhdGlvbjsKLSAgICBwdWJsaWMgWFNBbm5vdGF0aW9uIG1pbkV4Y2x1c2l2ZUFubm90YXRpb247Ci0KLSAgICBwdWJsaWMgdm9pZCByZXNldCgpewotICAgICAgICBsZW5ndGhBbm5vdGF0aW9uID0gbnVsbDsKLSAgICAgICAgbWluTGVuZ3RoQW5ub3RhdGlvbiA9IG51bGw7Ci0gICAgICAgIG1heExlbmd0aEFubm90YXRpb24gPSBudWxsOwotICAgICAgICB3aGl0ZVNwYWNlQW5ub3RhdGlvbiA9IG51bGw7Ci0gICAgICAgIHRvdGFsRGlnaXRzQW5ub3RhdGlvbiA9IG51bGw7Ci0gICAgICAgIGZyYWN0aW9uRGlnaXRzQW5ub3RhdGlvbiA9IG51bGw7Ci0gICAgICAgIHBhdHRlcm5Bbm5vdGF0aW9ucyA9IG51bGw7Ci0gICAgICAgIGVudW1Bbm5vdGF0aW9ucyA9IG51bGw7Ci0gICAgICAgIG1heEluY2x1c2l2ZUFubm90YXRpb24gPSBudWxsOwotICAgICAgICBtYXhFeGNsdXNpdmVBbm5vdGF0aW9uID0gbnVsbDsKLSAgICAgICAgbWluSW5jbHVzaXZlQW5ub3RhdGlvbiA9IG51bGw7Ci0gICAgICAgIG1pbkV4Y2x1c2l2ZUFubm90YXRpb24gPSBudWxsOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYvWFNTaW1wbGVUeXBlLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L1hTU2ltcGxlVHlwZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1ZTI0Mjc5Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYvWFNTaW1wbGVUeXBlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMDMgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMSwgMjAwMiwyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHY7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTU2ltcGxlVHlwZURlZmluaXRpb247Ci0KLS8qKgotICogVGhpcyBpbnRlcmZhY2UgPGNvZGU+WFNTaW1wbGVUeXBlPC9jb2RlPiByZXByZXNlbnRzIHRoZSBzaW1wbGUgdHlwZQotICogZGVmaW5pdGlvbiBvZiBzY2hlbWEgY29tcG9uZW50IGFuZCBkZWZpbmVzIG1ldGhvZHMgdG8gcXVlcnkgdGhlIGluZm9ybWF0aW9uCi0gKiBjb250YWluZWQuCi0gKiBBbnkgc2ltcGxlIHR5cGUgKGF0b21pYywgbGlzdCBvciB1bmlvbikgd2lsbCBpbXBsZW1lbnQgdGhpcyBpbnRlcmZhY2UuCi0gKiBJdCBpbmhlcml0cyBmcm9tIDxjb2RlPlhTVHlwZURlY2w8L2NvZGU+LgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIFNhbmR5IEdhbywgSUJNCi0gKgotICovCi1wdWJsaWMgaW50ZXJmYWNlIFhTU2ltcGxlVHlwZSBleHRlbmRzIFhTU2ltcGxlVHlwZURlZmluaXRpb24gewotCi0gICAgLyoqCi0gICAgICogY29uc3RhbnRzIGRlZmluZWQgZm9yIHRoZSB2YWx1ZXMgb2YgJ3doaXRlc3BhY2UnIGZhY2V0LgotICAgICAqIHNlZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi94bWxzY2hlbWEtMi8jZHQtd2hpdGVTcGFjZSc+IFhNTCBTY2hlbWEKLSAgICAgKiBQYXJ0IDI6IERhdGF0eXBlcyA8L2E+Ci0gICAgICovCi0gICAgLyoqIHByZXNlcnZlIHRoZSB3aGl0ZSBzcGFjZXMgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFdTX1BSRVNFUlZFID0gMDsKLSAgICAvKiogcmVwbGFjZSB0aGUgd2hpdGUgc3BhY2VzICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBXU19SRVBMQUNFICA9IDE7Ci0gICAgLyoqIGNvbGxhcHNlIHRoZSB3aGl0ZSBzcGFjZXMgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFdTX0NPTExBUFNFID0gMjsKLQotICAgIC8qKgotICAgICAqIENvbnN0YW50IGRlZmluZWQgZm9yIHRoZSBwcmltaXRpdmUgYnVpbHQtaW4gc2ltcGxlIHRweWVzLgotICAgICAqIHNlZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi94bWxzY2hlbWEtMi8jYnVpbHQtaW4tcHJpbWl0aXZlLWRhdGF0eXBlcyc+Ci0gICAgICogWE1MIFNjaGVtYSBQYXJ0IDI6IERhdGF0eXBlcyA8L2E+Ci0gICAgICovCi0gICAgLyoqICJzdHJpbmciIHR5cGUgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFBSSU1JVElWRV9TVFJJTkcgICAgICAgID0gMTsKLSAgICAvKiogImJvb2xlYW4iIHR5cGUgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFBSSU1JVElWRV9CT09MRUFOICAgICAgID0gMjsKLSAgICAvKiogImRlY2ltYWwiIHR5cGUgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFBSSU1JVElWRV9ERUNJTUFMICAgICAgID0gMzsKLSAgICAvKiogImZsb2F0IiB0eXBlICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBQUklNSVRJVkVfRkxPQVQgICAgICAgICA9IDQ7Ci0gICAgLyoqICJkb3VibGUiIHR5cGUgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFBSSU1JVElWRV9ET1VCTEUgICAgICAgID0gNTsKLSAgICAvKiogImR1cmF0aW9uIiB0eXBlICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBQUklNSVRJVkVfRFVSQVRJT04gICAgICA9IDY7Ci0gICAgLyoqICJkYXRhVGltZSIgdHlwZSAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgUFJJTUlUSVZFX0RBVEVUSU1FICAgICAgPSA3OwotICAgIC8qKiAidGltZSIgdHlwZSAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgUFJJTUlUSVZFX1RJTUUgICAgICAgICAgPSA4OwotICAgIC8qKiAiZGF0ZSIgdHlwZSAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgUFJJTUlUSVZFX0RBVEUgICAgICAgICAgPSA5OwotICAgIC8qKiAiZ1llYXJNb250aCIgdHlwZSAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgUFJJTUlUSVZFX0dZRUFSTU9OVEggICAgPSAxMDsKLSAgICAvKiogImdZZWFyIiB0eXBlICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBQUklNSVRJVkVfR1lFQVIgICAgICAgICA9IDExOwotICAgIC8qKiAiZ01vbnRoRGF5IiB0eXBlICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBQUklNSVRJVkVfR01PTlRIREFZICAgICA9IDEyOwotICAgIC8qKiAiZ0RheSIgdHlwZSAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgUFJJTUlUSVZFX0dEQVkgICAgICAgICAgPSAxMzsKLSAgICAvKiogImdNb250aCIgdHlwZSAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgUFJJTUlUSVZFX0dNT05USCAgICAgICAgPSAxNDsKLSAgICAvKiogImhleEJpbmFyeSIgdHlwZSAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgUFJJTUlUSVZFX0hFWEJJTkFSWSAgICAgPSAxNTsKLSAgICAvKiogImJhc2U2NEJpbmFyeSIgdHlwZSAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgUFJJTUlUSVZFX0JBU0U2NEJJTkFSWSAgPSAxNjsKLSAgICAvKiogImFueVVSSSIgdHlwZSAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgUFJJTUlUSVZFX0FOWVVSSSAgICAgICAgPSAxNzsKLSAgICAvKiogIlFOYW1lIiB0eXBlICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBQUklNSVRJVkVfUU5BTUUgICAgICAgICA9IDE4OwotICAgIC8qKiAicHJlY2lzaW9uRGVjaW1hbCIgdHlwZSAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgUFJJTUlUSVZFX1BSRUNJU0lPTkRFQ0lNQUwgPSAxOTsKLSAgICAvKiogIk5PVEFUSU9OIiB0eXBlICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBQUklNSVRJVkVfTk9UQVRJT04gICAgICA9IDIwOwotCi0gICAgLyoqCi0gICAgICogcmV0dXJuIGFuIElEIHJlcHJlc2VudGluZyB0aGUgYnVpbHQtaW4gcHJpbWl0aXZlIGJhc2UgdHlwZS4KLSAgICAgKiBSRVZJU0lUOiBUaGlzIG1ldGhvZCBpcyAoY3VycmVudGx5KSBmb3IgaW50ZXJuYWwgdXNlIG9ubHkuCi0gICAgICogICAgICAgICAgdGhlIGNvbnN0YW50cyByZXR1cm5lZCBmcm9tIHRoaXMgbWV0aG9kIGFyZSBub3QgZmluYWxpemVkIHlldC4KLSAgICAgKiAgICAgICAgICB0aGUgbmFtZXMgYW5kIHZhbHVlcyBtaWdodCBjaGFuZ2UgaW4gdGhlIGZ1cnRoZXIuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuICAgYW4gSUQgcmVwcmVzZW50aW5nIHRoZSBidWlsdC1pbiBwcmltaXRpdmUgYmFzZSB0eXBlCi0gICAgICovCi0gICAgcHVibGljIHNob3J0IGdldFByaW1pdGl2ZUtpbmQoKTsKLQotICAgIC8qKgotICAgICAqIHZhbGlkYXRlIGEgZ2l2ZW4gc3RyaW5nIGFnYWluc3QgdGhpcyBzaW1wbGUgdHlwZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjb250ZW50ICAgICAgIHRoZSBzdHJpbmcgdmFsdWUgdGhhdCBuZWVkcyB0byBiZSB2YWxpZGF0ZWQKLSAgICAgKiBAcGFyYW0gY29udGV4dCAgICAgICB0aGUgdmFsaWRhdGlvbiBjb250ZXh0Ci0gICAgICogQHBhcmFtIHZhbGlkYXRlZEluZm8gdXNlZCB0byBzdG9yZSB2YWxpZGF0aW9uIHJlc3VsdAotICAgICAqCi0gICAgICogQHJldHVybiAgICAgICAgICAgICAgdGhlIGFjdHVhbCB2YWx1ZSAoUU5hbWUsIEJvb2xlYW4pIG9mIHRoZSBzdHJpbmcgdmFsdWUKLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0IHZhbGlkYXRlKFN0cmluZyBjb250ZW50LCBWYWxpZGF0aW9uQ29udGV4dCBjb250ZXh0LCBWYWxpZGF0ZWRJbmZvIHZhbGlkYXRlZEluZm8pCi0gICAgICAgIHRocm93cyBJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIHZhbGlkYXRlIGEgZ2l2ZW4gc3RyaW5nIHZhbHVlLCByZXByZXNlbnRlZCBieSBjb250ZW50LnRvU3RyaW5nKCkuCi0gICAgICogbm90ZSB0aGF0IGlmIGNvbnRlbnQgaXMgYSBTdHJpbmdCdWZmZXIsIGZvciBwZXJmb3JtYW5jZSByZWFzb25zLAotICAgICAqIGl0J3MgcG9zc2libGUgdGhhdCB0aGUgY29udGVudCBvZiB0aGUgc3RyaW5nIGJ1ZmZlciBpcyBtb2RpZmllZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjb250ZW50ICAgICAgIHRoZSBzdHJpbmcgdmFsdWUgdGhhdCBuZWVkcyB0byBiZSB2YWxpZGF0ZWQKLSAgICAgKiBAcGFyYW0gY29udGV4dCAgICAgICB0aGUgdmFsaWRhdGlvbiBjb250ZXh0Ci0gICAgICogQHBhcmFtIHZhbGlkYXRlZEluZm8gdXNlZCB0byBzdG9yZSB2YWxpZGF0aW9uIHJlc3VsdAotICAgICAqCi0gICAgICogQHJldHVybiAgICAgICAgICAgICAgdGhlIGFjdHVhbCB2YWx1ZSAoUU5hbWUsIEJvb2xlYW4pIG9mIHRoZSBzdHJpbmcgdmFsdWUKLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0IHZhbGlkYXRlKE9iamVjdCBjb250ZW50LCBWYWxpZGF0aW9uQ29udGV4dCBjb250ZXh0LCBWYWxpZGF0ZWRJbmZvIHZhbGlkYXRlZEluZm8pCi0gICAgICAgIHRocm93cyBJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIFZhbGlkYXRlIGFuIGFjdHVhbCB2YWx1ZSBhZ2FpbnN0IHRoaXMgc2ltcGxlIHR5cGUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29udGV4dCAgICAgICB0aGUgdmFsaWRhdGlvbiBjb250ZXh0Ci0gICAgICogQHBhcmFtIHZhbGlkYXRlZEluZm8gdXNlZCB0byBwcm92aWRlIHRoZSBhY3R1YWwgdmFsdWUgYW5kIG1lbWJlciB0eXBlcwotICAgICAqIEBleGNlcHRpb24gSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24gIGV4Y2VwdGlvbiBmb3IgaW52YWxpZCB2YWx1ZXMuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdmFsaWRhdGUoVmFsaWRhdGlvbkNvbnRleHQgY29udGV4dCwgVmFsaWRhdGVkSW5mbyB2YWxpZGF0ZWRJbmZvKQotICAgICAgICB0aHJvd3MgSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBJZiB0aGlzIHR5cGUgaXMgY3JlYXRlZCBmcm9tIHJlc3RyaWN0aW9uLCB0aGVuIHNvbWUgZmFjZXRzIGNhbiBiZSBhcHBsaWVkCi0gICAgICogdG8gdGhlIHNpbXBsZSB0eXBlLiA8Y29kZT5YU0ZhY2V0czwvY29kZT4gaXMgdXNlZCB0byBwYXNzIHRoZSB2YWx1ZSBvZgotICAgICAqIGRpZmZlcmVudCBmYWNldHMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZmFjZXRzICAgICAgICB0aGUgdmFsdWUgb2YgYWxsIHRoZSBmYWNldHMKLSAgICAgKiBAcGFyYW0gcHJlc2VudEZhY2V0ICBiaXQgY29tYmluYXRpb24gdmFsdWUgb2YgdGhlIGNvc3RyYWluaW5nIGZhY2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgY29uc3RhbnRzIHdoaWNoIGFyZSBwcmVzZW50LgotICAgICAqIEBwYXJhbSBmaXhlZEZhY2V0ICAgIGJpdCBjb21iaW5hdGlvbiB2YWx1ZSBvZiB0aGUgY29zdHJhaW5pbmcgZmFjZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBjb25zdGFudHMgd2hpY2ggYXJlIGZpeGVkLgotICAgICAqIEBwYXJhbSBjb250ZXh0ICAgICAgIHRoZSB2YWxpZGF0aW9uIGNvbnRleHQKLSAgICAgKiBAZXhjZXB0aW9uIEludmFsaWREYXRhdHlwZUZhY2V0RXhjZXB0aW9uICBleGNlcHRpb24gZm9yIGludmFsaWQgZmFjZXQgdmFsdWVzLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGFwcGx5RmFjZXRzKFhTRmFjZXRzIGZhY2V0cywgc2hvcnQgcHJlc2VudEZhY2V0LCBzaG9ydCBmaXhlZEZhY2V0LCBWYWxpZGF0aW9uQ29udGV4dCBjb250ZXh0KQotICAgICAgICB0aHJvd3MgSW52YWxpZERhdGF0eXBlRmFjZXRFeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBDaGVjayB3aGV0aGVyIHR3byBhY3R1YWwgdmFsdWVzIGFyZSBlcXVhbC4KLSAgICAgKgotICAgICAqIEBwYXJhbSB2YWx1ZTEgIHRoZSBmaXJzdCB2YWx1ZQotICAgICAqIEBwYXJhbSB2YWx1ZTIgIHRoZSBzZWNvbmQgdmFsdWUKLSAgICAgKiBAcmV0dXJuICAgICAgICB0cnVlIGlmIHRoZSB0d28gdmFsdWUgYXJlIGVxdWFsCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNFcXVhbChPYmplY3QgdmFsdWUxLCBPYmplY3QgdmFsdWUyKTsKLQotICAgIC8qKgotICAgICAqIENoZWNrIHRoZSBvcmRlciBvZiB0aGUgdHdvIGFjdHVhbCB2YWx1ZXMuIChNYXkgbm90IGJlIHN1cHBvcnRlZCBieSBhbGwKLSAgICAgKiBzaW1wbGUgdHlwZXMuCi0gICAgICogUkVWSVNJVDogQW5keSBiZWxpZXZlcyB0aGF0IGEgY29tcGFyZSgpIG1ldGhvZCBpcyBuZWNlc3NhcnkuCi0gICAgICogICAgICAgICAgSSBkb24ndCBzZWUgdGhlIG5lY2Vzc2l0eSBmb3Igc2NoZW1hICh0aGUgb25seSBwbGFjZSB3aGVyZSB3ZQotICAgICAqICAgICAgICAgIG5lZWQgdG8gY29tcGFyZSB0d28gdmFsdWVzIGlzIHRvIGNoZWNrIG1pbi9tYXhJbi9FeGNsdXNpdmUKLSAgICAgKiAgICAgICAgICBmYWNldHMsIGJ1dCB3ZSBvbmx5IG5lZWQgYSBwcml2YXRlIG1ldGhvZCBmb3IgdGhpcyBjYXNlLikKLSAgICAgKiAgICAgICAgICBCdXQgQW5keSB0aGlua3MgWFBBVEggcG90ZW50aWFsbHkgbmVlZHMgdGhpcyBjb21wYXJlKCkgbWV0aG9kLgotICAgICAqCi0gICAgICogQHBhcmFtIHZhbHVlMSAgdGhlIGZpcnN0IHZhbHVlCi0gICAgICogQHByYXJtIHZhbHVlMiAgdGhlIHNlY29uZCB2YWx1ZQotICAgICAqIEByZXR1cm4gICAgICAgID4gMCBpZiB2YWx1ZTEgPiB2YWx1ZTIKLSAgICAgKiAgICAgICAgICAgICAgICA9IDAgaWYgdmFsdWUxID09IHZhbHVlMgotICAgICAqICAgICAgICAgICAgICAgIDwgPSBpZiB2YWx1ZTEgPCB2YWx1ZTIKLSAgICAgKi8KLSAgICAvL3B1YmxpYyBzaG9ydCBjb21wYXJlKE9iamVjdCB2YWx1ZTEsIE9iamVjdCB2YWx1ZTIpOwotCi0gICAgLyoqCi0gICAgICogQ2hlY2sgd2hldGhlciB0aGlzIHR5cGUgaXMgb3IgaXMgZGVyaXZlZCBmcm9tIElELgotICAgICAqIFJFVklTSVQ6IHRoaXMgbWV0aG9kIG1ha2VzIElEIHNwZWNpYWwsIHdoaWNoIGlzIG5vdCBhIGdvb2QgZGVzaWduLgotICAgICAqICAgICAgICAgIGJ1dCBzaW5jZSBJRCBpcyBub3QgYSBwcmltaXRpdmUsIHRoZXJlIGRvZXNuJ3Qgc2VlbSB0byBiZSBhCi0gICAgICogICAgICAgICAgY2xlYW4gd2F5IG9mIGRvaW5nIGl0IGV4Y2VwdCB0byBkZWZpbmUgc3BlY2lhbCBtZXRob2QgbGlrZSB0aGlzLgotICAgICAqCi0gICAgICogQHJldHVybiAgd2hldGhlciB0aGlzIHNpbXBsZSB0eXBlIGlzIG9yIGlzIGRlcml2ZWQgZnJvbSBJRC4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0lEVHlwZSgpOwotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSB3aGl0ZXNwYWNlIGNvcnJlc3BvbmRpbmcgdG8gdGhpcyBkYXRhdHlwZS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdmFsaWQgdmFsdWVzIGFyZSBXU19QUkVTRVJWRSwgV1NfUkVQTEFDRSwgV1NfQ09MTEFQU0UuCi0gICAgICogQGV4Y2VwdGlvbiBEYXRhdHlwZUV4Y2VwdGlvbgotICAgICAqICAgICAgICAgICAgICAgICAgIHVuaW9uIGRhdGF0eXBlcyBkb24ndCBoYXZlIHdoaXRlc3BhY2UgZmFjZXQgYXNzb2NpYXRlZCB3aXRoIHRoZW0KLSAgICAgKi8KLSAgICBwdWJsaWMgc2hvcnQgZ2V0V2hpdGVzcGFjZSgpIHRocm93cyBEYXRhdHlwZUV4Y2VwdGlvbjsKLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYvZHRkL0RURERWRmFjdG9yeUltcGwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYvZHRkL0RURERWRmFjdG9yeUltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDMyMzQxMi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L2R0ZC9EVEREVkZhY3RvcnlJbXBsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4MSArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDE1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICovCi0vKgotICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCi0gKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKLSAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KLSAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCi0gKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAotICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LmR0ZDsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5EVEREVkZhY3Rvcnk7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LkRhdGF0eXBlVmFsaWRhdG9yOwotaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKLWltcG9ydCBqYXZhLnV0aWwuTWFwOwotCi0vKioKLSAqIHRoZSBmYWN0b3J5IHRvIGNyZWF0ZS9yZXR1cm4gYnVpbHQtaW4gc2NoZW1hIERWcyBhbmQgY3JlYXRlIHVzZXItZGVmaW5lZCBEVnMKLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBTYW5keSBHYW8sIElCTQotICoKLSAqLwotcHVibGljIGNsYXNzIERURERWRmFjdG9yeUltcGwgZXh0ZW5kcyBEVEREVkZhY3RvcnkgewotCi0gICAgc3RhdGljIGZpbmFsIE1hcDxTdHJpbmcsIERhdGF0eXBlVmFsaWRhdG9yPiBmQnVpbHRJblR5cGVzOwotICAgIHN0YXRpYyB7Ci0gICAgICAgIE1hcDxTdHJpbmcsIERhdGF0eXBlVmFsaWRhdG9yPiBidWlsdEluVHlwZXMgPSBuZXcgSGFzaE1hcDw+KCk7Ci0gICAgICAgIERhdGF0eXBlVmFsaWRhdG9yIGR2VGVtcDsKLQotICAgICAgICBidWlsdEluVHlwZXMucHV0KCJzdHJpbmciLCBuZXcgU3RyaW5nRGF0YXR5cGVWYWxpZGF0b3IoKSk7Ci0gICAgICAgIGJ1aWx0SW5UeXBlcy5wdXQoIklEIiwgbmV3IElERGF0YXR5cGVWYWxpZGF0b3IoKSk7Ci0gICAgICAgIGR2VGVtcCA9IG5ldyBJRFJFRkRhdGF0eXBlVmFsaWRhdG9yKCk7Ci0gICAgICAgIGJ1aWx0SW5UeXBlcy5wdXQoIklEUkVGIiwgZHZUZW1wKTsKLSAgICAgICAgYnVpbHRJblR5cGVzLnB1dCgiSURSRUZTIiwgbmV3IExpc3REYXRhdHlwZVZhbGlkYXRvcihkdlRlbXApKTsKLSAgICAgICAgZHZUZW1wID0gbmV3IEVOVElUWURhdGF0eXBlVmFsaWRhdG9yKCk7Ci0gICAgICAgIGJ1aWx0SW5UeXBlcy5wdXQoIkVOVElUWSIsIG5ldyBFTlRJVFlEYXRhdHlwZVZhbGlkYXRvcigpKTsKLSAgICAgICAgYnVpbHRJblR5cGVzLnB1dCgiRU5USVRJRVMiLCBuZXcgTGlzdERhdGF0eXBlVmFsaWRhdG9yKGR2VGVtcCkpOwotICAgICAgICBidWlsdEluVHlwZXMucHV0KCJOT1RBVElPTiIsIG5ldyBOT1RBVElPTkRhdGF0eXBlVmFsaWRhdG9yKCkpOwotICAgICAgICBkdlRlbXAgPSBuZXcgTk1UT0tFTkRhdGF0eXBlVmFsaWRhdG9yKCk7Ci0gICAgICAgIGJ1aWx0SW5UeXBlcy5wdXQoIk5NVE9LRU4iLCBkdlRlbXApOwotICAgICAgICBidWlsdEluVHlwZXMucHV0KCJOTVRPS0VOUyIsIG5ldyBMaXN0RGF0YXR5cGVWYWxpZGF0b3IoZHZUZW1wKSk7Ci0KLSAgICAgICAgZkJ1aWx0SW5UeXBlcyA9IENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZU1hcChidWlsdEluVHlwZXMpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIHJldHVybiBhIGR0ZCB0eXBlIG9mIHRoZSBnaXZlbiBuYW1lCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSAgdGhlIG5hbWUgb2YgdGhlIGRhdGF0eXBlCi0gICAgICogQHJldHVybiAgICAgIHRoZSBkYXRhdHlwZSB2YWxpZGF0b3Igb2YgdGhlIGdpdmVuIG5hbWUKLSAgICAgKi8KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgRGF0YXR5cGVWYWxpZGF0b3IgZ2V0QnVpbHRJbkRWKFN0cmluZyBuYW1lKSB7Ci0gICAgICAgIHJldHVybiBmQnVpbHRJblR5cGVzLmdldChuYW1lKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBnZXQgYWxsIGJ1aWx0LWluIERWcywgd2hpY2ggYXJlIHN0b3JlZCBpbiBhIE1hcCBrZXllZCBieSB0aGUgbmFtZQotICAgICAqCi0gICAgICogQHJldHVybiAgICAgIGEgTWFwIHdoaWNoIGNvbnRhaW5zIGFsbCBkYXRhdHlwZXMKLSAgICAgKi8KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgTWFwPFN0cmluZywgRGF0YXR5cGVWYWxpZGF0b3I+IGdldEJ1aWx0SW5UeXBlcygpIHsKLSAgICAgICAgcmV0dXJuIG5ldyBIYXNoTWFwPD4oZkJ1aWx0SW5UeXBlcyk7Ci0gICAgfQotCi19Ly8gRFRERFZGYWN0b3J5SW1wbApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi9kdGQvRU5USVRZRGF0YXR5cGVWYWxpZGF0b3IuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYvZHRkL0VOVElUWURhdGF0eXBlVmFsaWRhdG9yLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDUyZjM5YjAuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi9kdGQvRU5USVRZRGF0YXR5cGVWYWxpZGF0b3IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDY4ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwMiwyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYuZHRkOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2Lio7Ci0KLS8qKgotICogPFA+RU5USVRZRGF0YXR5cGVWYWxpZGF0b3IgaW1wbGVtZW50cyB0aGUKLSAqIERhdGF0dHlwZVZhbGlkYXRvciBpbnRlcmZhY2UuCi0gKiBUaGlzIHZhbGlkYXRvciBlbWJvZGllcyB0aGUgRU5USVRZIGF0dHJpYnV0ZSB0eXBlCi0gKiBmcm9tIFhNTDEuMCByZWNvbW1lbmRhdGlvbi4KLSAqIFRoZSBWYWx1ZSBzcGFjZSBvZiBFTlRJVFkgaXMgdGhlIHNldCBvZiBhbGwgc3RyaW5ncwotICogdGhhdCBtYXRjaCB0aGUgTkNOYW1lIHByb2R1Y3Rpb24gYW5kIGhhdmUgYmVlbgotICogZGVjbGFyZWQgYXMgYW4gdW5wYXJzZWQgZW50aXR5IGluIGEgZG9jdW1lbnQKLSAqIHR5cGUgZGVmaW5pdGlvbi4KLSAqIFRoZSBMZXhpY2FsIHNwYWNlIG9mIEVudGl0eSBpcyB0aGUgc2V0IG9mIGFsbAotICogc3RyaW5ncyB0aGF0IG1hdGNoIHRoZSBOQ05hbWUgcHJvZHVjdGlvbi4KLSAqIFRoZSB2YWx1ZSBzcGFjZSBvZiBFTlRJVFkgaXMgc2NvcGVkIHRvIGEgc3BlY2lmaWMKLSAqIGluc3RhbmNlIGRvY3VtZW50LjwvUD4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBKZWZmcmV5IFJvZHJpZ3VleiwgSUJNCi0gKiBAYXV0aG9yIFNhbmR5IEdhbywgSUJNCi0gKgotICovCi1wdWJsaWMgY2xhc3MgRU5USVRZRGF0YXR5cGVWYWxpZGF0b3IgaW1wbGVtZW50cyBEYXRhdHlwZVZhbGlkYXRvciB7Ci0KLSAgICAvLyBjb25zdHJ1Y3QgYW4gRU5USVRZIGRhdGF0eXBlIHZhbGlkYXRvcgotICAgIHB1YmxpYyBFTlRJVFlEYXRhdHlwZVZhbGlkYXRvcigpIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDaGVja3MgdGhhdCAiY29udGVudCIgc3RyaW5nIGlzIHZhbGlkIElEIHZhbHVlLgotICAgICAqIElmIGludmFsaWQgYSBEYXRhdHlwZSB2YWxpZGF0aW9uIGV4Y2VwdGlvbiBpcyB0aHJvd24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29udGVudCAgICAgICB0aGUgc3RyaW5nIHZhbHVlIHRoYXQgbmVlZHMgdG8gYmUgdmFsaWRhdGVkCi0gICAgICogQHBhcmFtIGNvbnRleHQgICAgICAgdGhlIHZhbGlkYXRpb24gY29udGV4dAotICAgICAqIEB0aHJvd3MgSW52YWxpZERhdGF0eXBlRXhjZXB0aW9uIGlmIHRoZSBjb250ZW50IGlzCi0gICAgICogICAgICAgICBpbnZhbGlkIGFjY29yZGluZyB0byB0aGUgcnVsZXMgZm9yIHRoZSB2YWxpZGF0b3JzCi0gICAgICogQHNlZSBJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHZhbGlkYXRlKFN0cmluZyBjb250ZW50LCBWYWxpZGF0aW9uQ29udGV4dCBjb250ZXh0KSB0aHJvd3MgSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24gewotCi0gICAgICAgIGlmICghY29udGV4dC5pc0VudGl0eVVucGFyc2VkKGNvbnRlbnQpKQotICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uKCJFTlRJVFlOb3RVbnBhcnNlZCIsIG5ldyBPYmplY3RbXXtjb250ZW50fSk7Ci0KLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYvZHRkL0lERGF0YXR5cGVWYWxpZGF0b3IuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYvZHRkL0lERGF0YXR5cGVWYWxpZGF0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNTRmYWMxYS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L2R0ZC9JRERhdGF0eXBlVmFsaWRhdG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4NCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LmR0ZDsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi4qOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5YTUxDaGFyOwotCi0vKioKLSAqIDxQPklERGF0YXR5cGVWYWxpZGF0b3IgLSBJRCByZXByZXNlbnRzIHRoZSBJRCBhdHRyaWJ1dGUKLSAqIHR5cGUgZnJvbSBYTUwgMS4wIFJlY29tbWVuZGF0aW9uLiBUaGUgdmFsdWUgc3BhY2UKLSAqIG9kIElEIGlzIHRoZSBzZXQgb2YgYWxsIHN0cmluZ3MgdGhhdCBtYXRjaCB0aGUKLSAqIE5DTmFtZSBwcm9kdWN0aW9uIGFuZCBoYXZlIGJlZW4gdXNlZCBpbiBhbiBYTUwKLSAqIGRvY3VtZW50LiBUaGUgbGV4aWNhbCBzcGFjZSBvZiBJRCBpcyB0aGUgc2V0IG9mIGFsbAotICogc3RyaW5ncyB0aGF0IG1hdGNoIHRoZSBOQ05hbWUgcHJvZHVjdGlvbi48L1A+Ci0gKiA8UD5UaGUgdmFsdWUgc3BhY2Ugb2YgSUQgaXMgc2NvcGVkIHRvIGEgc3BlY2lmaWMKLSAqIGluc3RhbmNlIGRvY3VtZW50LjwvUD4KLSAqIDxQPlRoZSBmb2xsb3dpbmcgY29uc3RyYWludCBhcHBsaWVzOgotICogQW4gSUQgbXVzdCBub3QgYXBwZWFyIG1vcmUgdGhhbiBvbmNlIGluIGFuIFhNTAotICogZG9jdW1lbnQgYXMgYSB2YWx1ZSBvZiB0aGlzIHR5cGU7IGkuZS4sIElEIHZhbHVlcwotICogbXVzdCB1bmlxdWVseSBpZGVudGlmeSB0aGUgZWxlbWVudHMgd2hpY2ggYmVhcgotICogdGhlbS48L1A+Ci0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgSmVmZnJleSBSb2RyaWd1ZXosIElCTQotICogQGF1dGhvciBTYW5keSBHYW8sIElCTQotICoKLSAqLwotcHVibGljIGNsYXNzIElERGF0YXR5cGVWYWxpZGF0b3IgaW1wbGVtZW50cyBEYXRhdHlwZVZhbGlkYXRvciB7Ci0KLSAgICAvLyBjb25zdHJ1Y3QgYW4gSUQgZGF0YXR5cGUgdmFsaWRhdG9yCi0gICAgcHVibGljIElERGF0YXR5cGVWYWxpZGF0b3IoKSB7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ2hlY2tzIHRoYXQgImNvbnRlbnQiIHN0cmluZyBpcyB2YWxpZCBJRCB2YWx1ZS4KLSAgICAgKiBJZiBpbnZhbGlkIGEgRGF0YXR5cGUgdmFsaWRhdGlvbiBleGNlcHRpb24gaXMgdGhyb3duLgotICAgICAqCi0gICAgICogQHBhcmFtIGNvbnRlbnQgICAgICAgdGhlIHN0cmluZyB2YWx1ZSB0aGF0IG5lZWRzIHRvIGJlIHZhbGlkYXRlZAotICAgICAqIEBwYXJhbSBjb250ZXh0ICAgICAgIHRoZSB2YWxpZGF0aW9uIGNvbnRleHQKLSAgICAgKiBAdGhyb3dzIEludmFsaWREYXRhdHlwZUV4Y2VwdGlvbiBpZiB0aGUgY29udGVudCBpcwotICAgICAqICAgICAgICAgaW52YWxpZCBhY2NvcmRpbmcgdG8gdGhlIHJ1bGVzIGZvciB0aGUgdmFsaWRhdG9ycwotICAgICAqIEBzZWUgSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB2YWxpZGF0ZShTdHJpbmcgY29udGVudCwgVmFsaWRhdGlvbkNvbnRleHQgY29udGV4dCkgdGhyb3dzIEludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uIHsKLQotICAgICAgICAvL0NoZWNrIGlmIGlzIHZhbGlkIGtleS1bODFdIEVuY05hbWUgOjo9IFtBLVphLXpdIChbQS1aYS16MC05Ll9dIHwgJy0nKSoKLSAgICAgICAgaWYoY29udGV4dC51c2VOYW1lc3BhY2VzKCkpIHsKLSAgICAgICAgICAgIGlmICghWE1MQ2hhci5pc1ZhbGlkTkNOYW1lKGNvbnRlbnQpKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uKCJJREludmFsaWRXaXRoTmFtZXNwYWNlcyIsIG5ldyBPYmplY3RbXXtjb250ZW50fSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBpZiAoIVhNTENoYXIuaXNWYWxpZE5hbWUoY29udGVudCkpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24oIklESW52YWxpZCIsIG5ldyBPYmplY3RbXXtjb250ZW50fSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoY29udGV4dC5pc0lkRGVjbGFyZWQoY29udGVudCkpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbigiSUROb3RVbmlxdWUiLCBuZXcgT2JqZWN0W117Y29udGVudH0pOwotICAgICAgICB9Ci0KLSAgICAgICAgY29udGV4dC5hZGRJZChjb250ZW50KTsKLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYvZHRkL0lEUkVGRGF0YXR5cGVWYWxpZGF0b3IuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYvZHRkL0lEUkVGRGF0YXR5cGVWYWxpZGF0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNGZhMmExYy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L2R0ZC9JRFJFRkRhdGF0eXBlVmFsaWRhdG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3OCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LmR0ZDsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi4qOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5YTUxDaGFyOwotCi0vKioKLSAqIDxQPklEUkVGRGF0YXR5cGVWYWxpZGF0b3IgLSByZXByZXNlbnRzIHRoZSBJRFJFRlMKLSAqIGF0dHJpYnV0ZSB0eXBlIGZyb20gWE1MIDEuMCByZWNvbW1lbmRhdGlvbi4gVGhlCi0gKiBWYWx1ZSBTcGFjZSBvZiBJRFJFRiBpcyB0aGUgc2V0IG9mIGFsbCBzdHJpbmdzCi0gKiB0aGF0IG1hdGNoIHRoZSBOQ05hbWUgcHJvZHVjdGlvbiBhbmQgaGF2ZSBiZWVuCi0gKiB1c2VkIGluIGFuIFhNTCBEb2N1bWVudCBhcyB0aGUgdmFsdWUgb2YgYW4gZWxlbWVudAotICogb3IgYXR0cmlidXRlIG9mIFR5cGUgSUQuIFRoZSBMZXhpY2FsIHNwYWNlIG9mCi0gKiBJRFJFRiBpcyB0aGUgc2V0IG9mIHN0cmluZ3MgdGhhdCBtYXRjaCB0aGUgTkNOYW1lCi0gKiBwcm9kdWN0aW9uLjwvUD4KLSAqIDxQPlRoZSBWYWx1ZSBzcGFjZSBvZiBJRFJFRiBpcyBzY29wZWQgdG8gYSBzcGVjaWZpYwotICogaW5zdGFuY2UgZG9jdW1lbnQ8L1A+Ci0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgSmVmZnJleSBSb2RyaWd1ZXosIElCTQotICogQGF1dGhvciBTYW5keSBHYW8sIElCTQotICoKLSAqLwotcHVibGljIGNsYXNzIElEUkVGRGF0YXR5cGVWYWxpZGF0b3IgaW1wbGVtZW50cyBEYXRhdHlwZVZhbGlkYXRvciB7Ci0KLSAgICAvLyBjb25zdHJ1Y3QgYW4gSURSRUYgZGF0YXR5cGUgdmFsaWRhdG9yCi0gICAgcHVibGljIElEUkVGRGF0YXR5cGVWYWxpZGF0b3IoKSB7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ2hlY2tzIHRoYXQgImNvbnRlbnQiIHN0cmluZyBpcyB2YWxpZCBJRFJFRiB2YWx1ZS4KLSAgICAgKiBJZiBpbnZhbGlkIGEgRGF0YXR5cGUgdmFsaWRhdGlvbiBleGNlcHRpb24gaXMgdGhyb3duLgotICAgICAqCi0gICAgICogQHBhcmFtIGNvbnRlbnQgICAgICAgdGhlIHN0cmluZyB2YWx1ZSB0aGF0IG5lZWRzIHRvIGJlIHZhbGlkYXRlZAotICAgICAqIEBwYXJhbSBjb250ZXh0ICAgICAgIHRoZSB2YWxpZGF0aW9uIGNvbnRleHQKLSAgICAgKiBAdGhyb3dzIEludmFsaWREYXRhdHlwZUV4Y2VwdGlvbiBpZiB0aGUgY29udGVudCBpcwotICAgICAqICAgICAgICAgaW52YWxpZCBhY2NvcmRpbmcgdG8gdGhlIHJ1bGVzIGZvciB0aGUgdmFsaWRhdG9ycwotICAgICAqIEBzZWUgSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB2YWxpZGF0ZShTdHJpbmcgY29udGVudCwgVmFsaWRhdGlvbkNvbnRleHQgY29udGV4dCkgdGhyb3dzIEludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uIHsKLQotICAgICAgICAvL0NoZWNrIGlmIGlzIHZhbGlkIGtleS1bODFdIEVuY05hbWUgOjo9IFtBLVphLXpdIChbQS1aYS16MC05Ll9dIHwgJy0nKSoKLSAgICAgICAgaWYoY29udGV4dC51c2VOYW1lc3BhY2VzKCkpIHsKLSAgICAgICAgICAgIGlmICghWE1MQ2hhci5pc1ZhbGlkTkNOYW1lKGNvbnRlbnQpKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uKCJJRFJFRkludmFsaWRXaXRoTmFtZXNwYWNlcyIsIG5ldyBPYmplY3RbXXtjb250ZW50fSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBpZiAoIVhNTENoYXIuaXNWYWxpZE5hbWUoY29udGVudCkpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24oIklEUkVGSW52YWxpZCIsIG5ldyBPYmplY3RbXXtjb250ZW50fSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBjb250ZXh0LmFkZElkUmVmKGNvbnRlbnQpOwotCi0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L2R0ZC9MaXN0RGF0YXR5cGVWYWxpZGF0b3IuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYvZHRkL0xpc3REYXRhdHlwZVZhbGlkYXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyOGEzZmQwLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYvZHRkL0xpc3REYXRhdHlwZVZhbGlkYXRvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNjggKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDAyLDIwMDQsMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LmR0ZDsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi4qOwotaW1wb3J0IGphdmEudXRpbC5TdHJpbmdUb2tlbml6ZXI7Ci0KLS8qKgotICogRm9yIGxpc3QgdHlwZXM6IEVOVElUSUVTLCBJRFJFRlMsIE5NVE9LRU5TLgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIEplZmZyZXkgUm9kcmlndWV6LCBJQk0KLSAqIEBhdXRob3IgU2FuZHkgR2FvLCBJQk0KLSAqCi0gKi8KLXB1YmxpYyBjbGFzcyBMaXN0RGF0YXR5cGVWYWxpZGF0b3IgaW1wbGVtZW50cyBEYXRhdHlwZVZhbGlkYXRvciB7Ci0KLSAgICAvLyB0aGUgdHlwZSBvZiBpdGVtcyBpbiB0aGUgbGlzdAotICAgIERhdGF0eXBlVmFsaWRhdG9yIGZJdGVtVmFsaWRhdG9yOwotCi0gICAgLy8gY29uc3RydWN0IGEgbGlzdCBkYXRhdHlwZSB2YWxpZGF0b3IKLSAgICBwdWJsaWMgTGlzdERhdGF0eXBlVmFsaWRhdG9yKERhdGF0eXBlVmFsaWRhdG9yIGl0ZW1EVikgewotICAgICAgICBmSXRlbVZhbGlkYXRvciA9IGl0ZW1EVjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDaGVja3MgdGhhdCAiY29udGVudCIgc3RyaW5nIGlzIHZhbGlkLgotICAgICAqIElmIGludmFsaWQgYSBEYXRhdHlwZSB2YWxpZGF0aW9uIGV4Y2VwdGlvbiBpcyB0aHJvd24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29udGVudCAgICAgICB0aGUgc3RyaW5nIHZhbHVlIHRoYXQgbmVlZHMgdG8gYmUgdmFsaWRhdGVkCi0gICAgICogQHBhcmFtIGNvbnRleHQgICAgICAgdGhlIHZhbGlkYXRpb24gY29udGV4dAotICAgICAqIEB0aHJvd3MgSW52YWxpZERhdGF0eXBlRXhjZXB0aW9uIGlmIHRoZSBjb250ZW50IGlzCi0gICAgICogICAgICAgICBpbnZhbGlkIGFjY29yZGluZyB0byB0aGUgcnVsZXMgZm9yIHRoZSB2YWxpZGF0b3JzCi0gICAgICogQHNlZSBJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHZhbGlkYXRlKFN0cmluZyBjb250ZW50LCBWYWxpZGF0aW9uQ29udGV4dCBjb250ZXh0KSB0aHJvd3MgSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24gewotCi0gICAgICAgIFN0cmluZ1Rva2VuaXplciBwYXJzZWRMaXN0ID0gbmV3IFN0cmluZ1Rva2VuaXplcihjb250ZW50LCIgIik7Ci0gICAgICAgIGludCBudW1iZXJPZlRva2VucyA9ICBwYXJzZWRMaXN0LmNvdW50VG9rZW5zKCk7Ci0gICAgICAgIGlmIChudW1iZXJPZlRva2VucyA9PSAwKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24oIkVtcHR5TGlzdCIsIG51bGwpOwotICAgICAgICB9Ci0gICAgICAgIC8vQ2hlY2sgZWFjaCB0b2tlbiBpbiBsaXN0IGFnYWluc3QgYmFzZSB0eXBlCi0gICAgICAgIHdoaWxlIChwYXJzZWRMaXN0Lmhhc01vcmVUb2tlbnMoKSkgewotICAgICAgICAgICAgdGhpcy5mSXRlbVZhbGlkYXRvci52YWxpZGF0ZShwYXJzZWRMaXN0Lm5leHRUb2tlbigpLCBjb250ZXh0KTsKLSAgICAgICAgfQotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi9kdGQvTk1UT0tFTkRhdGF0eXBlVmFsaWRhdG9yLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L2R0ZC9OTVRPS0VORGF0YXR5cGVWYWxpZGF0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOTRlYjkwMS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L2R0ZC9OTVRPS0VORGF0YXR5cGVWYWxpZGF0b3IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDU3ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwMiwyMDA0LDIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5kdGQ7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYuKjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuWE1MQ2hhcjsKLQotLyoqCi0gKiBOTVRPS0VOIGRhdGF0eXBlIHZhbGlkYXRvci4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBKZWZmcmV5IFJvZHJpZ3VleiwgSUJNCi0gKiBAYXV0aG9yIFNhbmR5IEdhbywgSUJNCi0gKgotICovCi1wdWJsaWMgY2xhc3MgTk1UT0tFTkRhdGF0eXBlVmFsaWRhdG9yIGltcGxlbWVudHMgRGF0YXR5cGVWYWxpZGF0b3IgewotCi0gICAgLy8gY29uc3RydWN0IGEgTk1UT0tFTiBkYXRhdHlwZSB2YWxpZGF0b3IKLSAgICBwdWJsaWMgTk1UT0tFTkRhdGF0eXBlVmFsaWRhdG9yKCkgewotICAgIH0KLQotICAgIC8qKgotICAgICAqIENoZWNrcyB0aGF0ICJjb250ZW50IiBzdHJpbmcgaXMgdmFsaWQgTk1UT0tFTiB2YWx1ZS4KLSAgICAgKiBJZiBpbnZhbGlkIGEgRGF0YXR5cGUgdmFsaWRhdGlvbiBleGNlcHRpb24gaXMgdGhyb3duLgotICAgICAqCi0gICAgICogQHBhcmFtIGNvbnRlbnQgICAgICAgdGhlIHN0cmluZyB2YWx1ZSB0aGF0IG5lZWRzIHRvIGJlIHZhbGlkYXRlZAotICAgICAqIEBwYXJhbSBjb250ZXh0ICAgICAgIHRoZSB2YWxpZGF0aW9uIGNvbnRleHQKLSAgICAgKiBAdGhyb3dzIEludmFsaWREYXRhdHlwZUV4Y2VwdGlvbiBpZiB0aGUgY29udGVudCBpcwotICAgICAqICAgICAgICAgaW52YWxpZCBhY2NvcmRpbmcgdG8gdGhlIHJ1bGVzIGZvciB0aGUgdmFsaWRhdG9ycwotICAgICAqIEBzZWUgSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB2YWxpZGF0ZShTdHJpbmcgY29udGVudCwgVmFsaWRhdGlvbkNvbnRleHQgY29udGV4dCkgdGhyb3dzIEludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKCFYTUxDaGFyLmlzVmFsaWRObXRva2VuKGNvbnRlbnQpKSB7Ci0gICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbigiTk1UT0tFTkludmFsaWQiLCBuZXcgT2JqZWN0W117Y29udGVudH0pOwotICAgICAgIH0KLSAgIH0KLQotfSAvLyBjbGFzcyBOTVRPS0VORGF0YXR5cGVWYWxpZGF0b3IKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYvZHRkL05PVEFUSU9ORGF0YXR5cGVWYWxpZGF0b3IuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYvZHRkL05PVEFUSU9ORGF0YXR5cGVWYWxpZGF0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggODdkOTVjYy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L2R0ZC9OT1RBVElPTkRhdGF0eXBlVmFsaWRhdG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw1NSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LmR0ZDsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi4qOwotCi0vKioKLSAqIE5PVEFUSU9OVmFsaWRhdG9yIGRlZmluZXMgdGhlIGludGVyZmFjZSB0aGF0IGRhdGEgdHlwZSB2YWxpZGF0b3JzIG11c3Qgb2JleS4KLSAqIFRoZXNlIHZhbGlkYXRvcnMgY2FuIGJlIHN1cHBsaWVkIGJ5IHRoZSBhcHBsaWNhdGlvbiB3cml0ZXIgYW5kIG1heSBiZSB1c2VmdWwgYXMKLSAqIHN0YW5kYWxvbmUgY29kZSBhcyB3ZWxsIGFzIHBsdWdpbnMgdG8gdGhlIHZhbGlkYXRvciBhcmNoaXRlY3R1cmUuCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgSmVmZnJleSBSb2RyaWd1ZXosIElCTQotICogQGF1dGhvciBTYW5keSBHYW8sIElCTQotICoKLSAqLwotIHB1YmxpYyBjbGFzcyBOT1RBVElPTkRhdGF0eXBlVmFsaWRhdG9yIGltcGxlbWVudHMgRGF0YXR5cGVWYWxpZGF0b3IgewotCi0gICAgLy8gY29uc3RydWN0IGEgTk9UQVRJT04gZGF0YXR5cGUgdmFsaWRhdG9yCi0gICAgcHVibGljIE5PVEFUSU9ORGF0YXR5cGVWYWxpZGF0b3IoKSB7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ2hlY2tzIHRoYXQgImNvbnRlbnQiIHN0cmluZyBpcyB2YWxpZCBOT1RBVElPTiB2YWx1ZS4KLSAgICAgKiBJZiBpbnZhbGlkIGEgRGF0YXR5cGUgdmFsaWRhdGlvbiBleGNlcHRpb24gaXMgdGhyb3duLgotICAgICAqCi0gICAgICogQHBhcmFtIGNvbnRlbnQgICAgICAgdGhlIHN0cmluZyB2YWx1ZSB0aGF0IG5lZWRzIHRvIGJlIHZhbGlkYXRlZAotICAgICAqIEBwYXJhbSBjb250ZXh0ICAgICAgIHRoZSB2YWxpZGF0aW9uIGNvbnRleHQKLSAgICAgKiBAdGhyb3dzIEludmFsaWREYXRhdHlwZUV4Y2VwdGlvbiBpZiB0aGUgY29udGVudCBpcwotICAgICAqICAgICAgICAgaW52YWxpZCBhY2NvcmRpbmcgdG8gdGhlIHJ1bGVzIGZvciB0aGUgdmFsaWRhdG9ycwotICAgICAqIEBzZWUgSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB2YWxpZGF0ZShTdHJpbmcgY29udGVudCwgVmFsaWRhdGlvbkNvbnRleHQgY29udGV4dCkgdGhyb3dzIEludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uIHsKLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYvZHRkL1N0cmluZ0RhdGF0eXBlVmFsaWRhdG9yLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L2R0ZC9TdHJpbmdEYXRhdHlwZVZhbGlkYXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlZGM1YzU1Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYvZHRkL1N0cmluZ0RhdGF0eXBlVmFsaWRhdG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw2MCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LmR0ZDsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi4qOwotCi0vKioKLSAqIDxQPlN0cmluZ1ZhbGlkYXRvciB2YWxpZGF0ZXMgdGhhdCBYTUwgY29udGVudCBpcyBhIFczQyBzdHJpbmcgdHlwZS48L1A+Ci0gKiA8UD5UaGUgc3RyaW5nIGRhdGF0eXBlIHJlcHJlc2VudHMgY2hhcmFjdGVyIHN0cmluZ3MgaW4gWE1MLiBUaGUKLSAqIHZhbHVlIHNwYWNlIG9mIHN0cmluZyBpcyB0aGUgc2V0IG9mIGZpbml0ZS1sZW5ndGggc2VxdWVuY2VzCi0gKiBvZiBjaGFyYWN0ZXJzIChhcyBkZWZpbmVkIGluIFtYTUwgMS4wIFJlY29tbWVuZGF0aW9uCi0gKiAoU2Vjb25kIEVkaXRpb24pXSkgdGhhdCBtYXRjaCB0aGUgQ2hhciBwcm9kdWN0aW9uCi0gKiBmcm9tIFtYTUwgMS4wIFJlY29tbWVuZGF0aW9uIChTZWNvbmQgRWRpdGlvbildLgotICogQSBjaGFyYWN0ZXIgaXMgYW4gYXRvbWljIHVuaXQgb2YgY29tbXVuaWNhdGlvbjsgaXQKLSAqIGlzIG5vdCBmdXJ0aGVyIHNwZWNpZmllZCBleGNlcHQgdG8gbm90ZSB0aGF0IGV2ZXJ5Ci0gKiBjaGFyYWN0ZXIgaGFzIGEgY29ycmVzcG9uZGluZyBVbml2ZXJzYWwgQ29kZSBTZXQKLSAqIGNvZGUgcG9pbnQgKFtJU08gMTA2NDZdLFtVbmljb2RlXSBhbmQgW1VuaWNvZGUzXSksCi0gKiB3aGljaCBpcyBhbiBpbnRlZ2VyLjwvUD4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICovCi1wdWJsaWMgY2xhc3MgU3RyaW5nRGF0YXR5cGVWYWxpZGF0b3IgaW1wbGVtZW50cyBEYXRhdHlwZVZhbGlkYXRvciB7Ci0KLSAgICAvLyBjb25zdHJ1Y3QgYSBzdHJpbmcgZGF0YXR5cGUgdmFsaWRhdG9yCi0gICAgcHVibGljIFN0cmluZ0RhdGF0eXBlVmFsaWRhdG9yKCkgewotICAgIH0KLQotICAgIC8qKgotICAgICAqIENoZWNrcyB0aGF0ICJjb250ZW50IiBzdHJpbmcgaXMgdmFsaWQgc3RyaW5nIHZhbHVlLgotICAgICAqIElmIGludmFsaWQgYSBEYXRhdHlwZSB2YWxpZGF0aW9uIGV4Y2VwdGlvbiBpcyB0aHJvd24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29udGVudCAgICAgICB0aGUgc3RyaW5nIHZhbHVlIHRoYXQgbmVlZHMgdG8gYmUgdmFsaWRhdGVkCi0gICAgICogQHBhcmFtIGNvbnRleHQgICAgICAgdGhlIHZhbGlkYXRpb24gY29udGV4dAotICAgICAqIEB0aHJvd3MgSW52YWxpZERhdGF0eXBlRXhjZXB0aW9uIGlmIHRoZSBjb250ZW50IGlzCi0gICAgICogICAgICAgICBpbnZhbGlkIGFjY29yZGluZyB0byB0aGUgcnVsZXMgZm9yIHRoZSB2YWxpZGF0b3JzCi0gICAgICogQHNlZSBJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHZhbGlkYXRlKFN0cmluZyBjb250ZW50LCBWYWxpZGF0aW9uQ29udGV4dCBjb250ZXh0KSB0aHJvd3MgSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24gewotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi9kdGQvWE1MMTFEVEREVkZhY3RvcnlJbXBsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L2R0ZC9YTUwxMURURERWRmFjdG9yeUltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMGMwYjFmMy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L2R0ZC9YTUwxMURURERWRmFjdG9yeUltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDc5ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKi8KLS8qCi0gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKLSAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAotICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgotICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKLSAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCi0gKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYuZHRkOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LkRhdGF0eXBlVmFsaWRhdG9yOwotaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKLWltcG9ydCBqYXZhLnV0aWwuTWFwOwotCi0vKioKLSAqIHRoZSBmYWN0b3J5IHRvIGNyZWF0ZS9yZXR1cm4gYnVpbHQtaW4gWE1MIDEuMSBEVnMgYW5kIGNyZWF0ZSB1c2VyLWRlZmluZWQgRFZzCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgTmVpbCBHcmFoYW0sIElCTQotICoKLSAqLwotcHVibGljIGNsYXNzIFhNTDExRFRERFZGYWN0b3J5SW1wbCBleHRlbmRzIERURERWRmFjdG9yeUltcGwgewotCi0gICAgc3RhdGljIE1hcDxTdHJpbmcsIERhdGF0eXBlVmFsaWRhdG9yPiBYTUwxMUJVSUxUSU5UWVBFUzsKLSAgICBzdGF0aWMgewotICAgICAgICBNYXA8U3RyaW5nLCBEYXRhdHlwZVZhbGlkYXRvcj4geG1sMTFCdWlsdEluVHlwZXMgPSBuZXcgSGFzaE1hcDw+KCk7Ci0gICAgICAgIHhtbDExQnVpbHRJblR5cGVzLnB1dCgiWE1MMTFJRCIsIG5ldyBYTUwxMUlERGF0YXR5cGVWYWxpZGF0b3IoKSk7Ci0gICAgICAgIERhdGF0eXBlVmFsaWRhdG9yIGR2VGVtcCA9IG5ldyBYTUwxMUlEUkVGRGF0YXR5cGVWYWxpZGF0b3IoKTsKLSAgICAgICAgeG1sMTFCdWlsdEluVHlwZXMucHV0KCJYTUwxMUlEUkVGIiwgZHZUZW1wKTsKLSAgICAgICAgeG1sMTFCdWlsdEluVHlwZXMucHV0KCJYTUwxMUlEUkVGUyIsIG5ldyBMaXN0RGF0YXR5cGVWYWxpZGF0b3IoZHZUZW1wKSk7Ci0gICAgICAgIGR2VGVtcCA9IG5ldyBYTUwxMU5NVE9LRU5EYXRhdHlwZVZhbGlkYXRvcigpOwotICAgICAgICB4bWwxMUJ1aWx0SW5UeXBlcy5wdXQoIlhNTDExTk1UT0tFTiIsIGR2VGVtcCk7Ci0gICAgICAgIHhtbDExQnVpbHRJblR5cGVzLnB1dCgiWE1MMTFOTVRPS0VOUyIsIG5ldyBMaXN0RGF0YXR5cGVWYWxpZGF0b3IoZHZUZW1wKSk7Ci0gICAgICAgIFhNTDExQlVJTFRJTlRZUEVTID0gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTWFwKHhtbDExQnVpbHRJblR5cGVzKTsKLSAgICB9IC8vIDxjbGluaXQ+Ci0KLSAgICAvKioKLSAgICAgKiByZXR1cm4gYSBkdGQgdHlwZSBvZiB0aGUgZ2l2ZW4gbmFtZQotICAgICAqIFRoaXMgd2lsbCBjYWxsIHRoZSBzdXBlciBjbGFzcyBpZiBhbmQgb25seSBpZiBpdCBkb2VzIG5vdAotICAgICAqIHJlY29nbml6ZSB0aGUgcGFzc2VkLWluIG5hbWUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSAgdGhlIG5hbWUgb2YgdGhlIGRhdGF0eXBlCi0gICAgICogQHJldHVybiAgICAgIHRoZSBkYXRhdHlwZSB2YWxpZGF0b3Igb2YgdGhlIGdpdmVuIG5hbWUKLSAgICAgKi8KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgRGF0YXR5cGVWYWxpZGF0b3IgZ2V0QnVpbHRJbkRWKFN0cmluZyBuYW1lKSB7Ci0gICAgICAgIGlmKFhNTDExQlVJTFRJTlRZUEVTLmdldChuYW1lKSAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gWE1MMTFCVUlMVElOVFlQRVMuZ2V0KG5hbWUpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmQnVpbHRJblR5cGVzLmdldChuYW1lKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBnZXQgYWxsIGJ1aWx0LWluIERWcywgd2hpY2ggYXJlIHN0b3JlZCBpbiBhIE1hcCBrZXllZCBieSB0aGUgbmFtZQotICAgICAqIE5ldyBYTUwgMS4xIGRhdGF0eXBlcyBhcmUgaW5zZXJ0ZWQuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuICAgICAgYSBNYXAgd2hpY2ggY29udGFpbnMgYWxsIGRhdGF0eXBlcwotICAgICAqLwotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyBNYXA8U3RyaW5nLCBEYXRhdHlwZVZhbGlkYXRvcj4gZ2V0QnVpbHRJblR5cGVzKCkgewotICAgICAgICBmaW5hbCBIYXNoTWFwPFN0cmluZywgRGF0YXR5cGVWYWxpZGF0b3I+IHRvUmV0dXJuID0gbmV3IEhhc2hNYXA8PihmQnVpbHRJblR5cGVzKTsKLSAgICAgICAgdG9SZXR1cm4ucHV0QWxsKFhNTDExQlVJTFRJTlRZUEVTKTsKLSAgICAgICAgcmV0dXJuIHRvUmV0dXJuOwotICAgIH0KLX0vL1hNTDExRFRERFZGYWN0b3J5SW1wbApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi9kdGQvWE1MMTFJRERhdGF0eXBlVmFsaWRhdG9yLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L2R0ZC9YTUwxMUlERGF0YXR5cGVWYWxpZGF0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZTQyOTYyNS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L2R0ZC9YTUwxMUlERGF0YXR5cGVWYWxpZGF0b3IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDg2ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwMiwyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYuZHRkOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2Lio7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlhNTDExQ2hhcjsKLQotLyoqCi0gKiA8UD5JRERhdGF0eXBlVmFsaWRhdG9yIC0gSUQgcmVwcmVzZW50cyB0aGUgSUQgYXR0cmlidXRlCi0gKiB0eXBlIGZyb20gWE1MIDEuMSBSZWNvbW1lbmRhdGlvbi4gVGhlIHZhbHVlIHNwYWNlCi0gKiBvZiBJRCBpcyB0aGUgc2V0IG9mIGFsbCBzdHJpbmdzIHRoYXQgbWF0Y2ggdGhlCi0gKiBOQ05hbWUgcHJvZHVjdGlvbiBhbmQgaGF2ZSBiZWVuIHVzZWQgaW4gYW4gWE1MCi0gKiBkb2N1bWVudC4gVGhlIGxleGljYWwgc3BhY2Ugb2YgSUQgaXMgdGhlIHNldCBvZiBhbGwKLSAqIHN0cmluZ3MgdGhhdCBtYXRjaCB0aGUgTkNOYW1lIHByb2R1Y3Rpb24uPC9QPgotICogPFA+VGhlIHZhbHVlIHNwYWNlIG9mIElEIGlzIHNjb3BlZCB0byBhIHNwZWNpZmljCi0gKiBpbnN0YW5jZSBkb2N1bWVudC48L1A+Ci0gKiA8UD5UaGUgZm9sbG93aW5nIGNvbnN0cmFpbnQgYXBwbGllczoKLSAqIEFuIElEIG11c3Qgbm90IGFwcGVhciBtb3JlIHRoYW4gb25jZSBpbiBhbiBYTUwKLSAqIGRvY3VtZW50IGFzIGEgdmFsdWUgb2YgdGhpcyB0eXBlOyBpLmUuLCBJRCB2YWx1ZXMKLSAqIG11c3QgdW5pcXVlbHkgaWRlbnRpZnkgdGhlIGVsZW1lbnRzIHdoaWNoIGJlYXIKLSAqIHRoZW0uPC9QPgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIEplZmZyZXkgUm9kcmlndWV6LCBJQk0KLSAqIEBhdXRob3IgU2FuZHkgR2FvLCBJQk0KLSAqIEBhdXRob3IgTmVpbCBHcmFoYW0sIElCTQotICoKLSAqLwotcHVibGljIGNsYXNzIFhNTDExSUREYXRhdHlwZVZhbGlkYXRvciBleHRlbmRzIElERGF0YXR5cGVWYWxpZGF0b3IgewotCi0gICAgLy8gY29uc3RydWN0IGFuIElEIGRhdGF0eXBlIHZhbGlkYXRvcgotICAgIHB1YmxpYyBYTUwxMUlERGF0YXR5cGVWYWxpZGF0b3IoKSB7Ci0gICAgICAgIHN1cGVyKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ2hlY2tzIHRoYXQgImNvbnRlbnQiIHN0cmluZyBpcyB2YWxpZCBJRCB2YWx1ZS4KLSAgICAgKiBJZiBpbnZhbGlkIGEgRGF0YXR5cGUgdmFsaWRhdGlvbiBleGNlcHRpb24gaXMgdGhyb3duLgotICAgICAqCi0gICAgICogQHBhcmFtIGNvbnRlbnQgICAgICAgdGhlIHN0cmluZyB2YWx1ZSB0aGF0IG5lZWRzIHRvIGJlIHZhbGlkYXRlZAotICAgICAqIEBwYXJhbSBjb250ZXh0ICAgICAgIHRoZSB2YWxpZGF0aW9uIGNvbnRleHQKLSAgICAgKiBAdGhyb3dzIEludmFsaWREYXRhdHlwZUV4Y2VwdGlvbiBpZiB0aGUgY29udGVudCBpcwotICAgICAqICAgICAgICAgaW52YWxpZCBhY2NvcmRpbmcgdG8gdGhlIHJ1bGVzIGZvciB0aGUgdmFsaWRhdG9ycwotICAgICAqIEBzZWUgSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB2YWxpZGF0ZShTdHJpbmcgY29udGVudCwgVmFsaWRhdGlvbkNvbnRleHQgY29udGV4dCkgdGhyb3dzIEludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uIHsKLQotICAgICAgICAvL0NoZWNrIGlmIGlzIHZhbGlkIGtleS1bODFdIEVuY05hbWUgOjo9IFtBLVphLXpdIChbQS1aYS16MC05Ll9dIHwgJy0nKSoKLSAgICAgICAgaWYoY29udGV4dC51c2VOYW1lc3BhY2VzKCkpIHsKLSAgICAgICAgICAgIGlmICghWE1MMTFDaGFyLmlzWE1MMTFWYWxpZE5DTmFtZShjb250ZW50KSkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbigiSURJbnZhbGlkV2l0aE5hbWVzcGFjZXMiLCBuZXcgT2JqZWN0W117Y29udGVudH0pOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgaWYgKCFYTUwxMUNoYXIuaXNYTUwxMVZhbGlkTmFtZShjb250ZW50KSkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbigiSURJbnZhbGlkIiwgbmV3IE9iamVjdFtde2NvbnRlbnR9KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGlmIChjb250ZXh0LmlzSWREZWNsYXJlZChjb250ZW50KSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uKCJJRE5vdFVuaXF1ZSIsIG5ldyBPYmplY3RbXXtjb250ZW50fSk7Ci0gICAgICAgIH0KLQotICAgICAgICBjb250ZXh0LmFkZElkKGNvbnRlbnQpOwotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi9kdGQvWE1MMTFJRFJFRkRhdGF0eXBlVmFsaWRhdG9yLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L2R0ZC9YTUwxMUlEUkVGRGF0YXR5cGVWYWxpZGF0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMGQ4YmJmNi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L2R0ZC9YTUwxMUlEUkVGRGF0YXR5cGVWYWxpZGF0b3IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDgwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwMiwyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYuZHRkOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2Lio7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlhNTDExQ2hhcjsKLQotLyoqCi0gKiA8UD5JRFJFRkRhdGF0eXBlVmFsaWRhdG9yIC0gcmVwcmVzZW50cyB0aGUgSURSRUZTCi0gKiBhdHRyaWJ1dGUgdHlwZSBmcm9tIFhNTCAxLjEgcmVjb21tZW5kYXRpb24uIFRoZQotICogVmFsdWUgU3BhY2Ugb2YgSURSRUYgaXMgdGhlIHNldCBvZiBhbGwgc3RyaW5ncwotICogdGhhdCBtYXRjaCB0aGUgTkNOYW1lIHByb2R1Y3Rpb24gYW5kIGhhdmUgYmVlbgotICogdXNlZCBpbiBhbiBYTUwgRG9jdW1lbnQgYXMgdGhlIHZhbHVlIG9mIGFuIGVsZW1lbnQKLSAqIG9yIGF0dHJpYnV0ZSBvZiBUeXBlIElELiBUaGUgTGV4aWNhbCBzcGFjZSBvZgotICogSURSRUYgaXMgdGhlIHNldCBvZiBzdHJpbmdzIHRoYXQgbWF0Y2ggdGhlIE5DTmFtZQotICogcHJvZHVjdGlvbi48L1A+Ci0gKiA8UD5UaGUgVmFsdWUgc3BhY2Ugb2YgSURSRUYgaXMgc2NvcGVkIHRvIGEgc3BlY2lmaWMKLSAqIGluc3RhbmNlIGRvY3VtZW50PC9QPgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIEplZmZyZXkgUm9kcmlndWV6LCBJQk0KLSAqIEBhdXRob3IgU2FuZHkgR2FvLCBJQk0KLSAqIEBhdXRob3IgTmVpbCBHcmFoYW0sIElCTQotICoKLSAqLwotcHVibGljIGNsYXNzIFhNTDExSURSRUZEYXRhdHlwZVZhbGlkYXRvciBleHRlbmRzIElEUkVGRGF0YXR5cGVWYWxpZGF0b3IgewotCi0gICAgLy8gY29uc3RydWN0IGFuIElEUkVGIGRhdGF0eXBlIHZhbGlkYXRvcgotICAgIHB1YmxpYyBYTUwxMUlEUkVGRGF0YXR5cGVWYWxpZGF0b3IoKSB7Ci0gICAgICAgIHN1cGVyKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ2hlY2tzIHRoYXQgImNvbnRlbnQiIHN0cmluZyBpcyB2YWxpZCBJRFJFRiB2YWx1ZS4KLSAgICAgKiBJZiBpbnZhbGlkIGEgRGF0YXR5cGUgdmFsaWRhdGlvbiBleGNlcHRpb24gaXMgdGhyb3duLgotICAgICAqCi0gICAgICogQHBhcmFtIGNvbnRlbnQgICAgICAgdGhlIHN0cmluZyB2YWx1ZSB0aGF0IG5lZWRzIHRvIGJlIHZhbGlkYXRlZAotICAgICAqIEBwYXJhbSBjb250ZXh0ICAgICAgIHRoZSB2YWxpZGF0aW9uIGNvbnRleHQKLSAgICAgKiBAdGhyb3dzIEludmFsaWREYXRhdHlwZUV4Y2VwdGlvbiBpZiB0aGUgY29udGVudCBpcwotICAgICAqICAgICAgICAgaW52YWxpZCBhY2NvcmRpbmcgdG8gdGhlIHJ1bGVzIGZvciB0aGUgdmFsaWRhdG9ycwotICAgICAqIEBzZWUgSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB2YWxpZGF0ZShTdHJpbmcgY29udGVudCwgVmFsaWRhdGlvbkNvbnRleHQgY29udGV4dCkgdGhyb3dzIEludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uIHsKLQotICAgICAgICAvL0NoZWNrIGlmIGlzIHZhbGlkIGtleS1bODFdIEVuY05hbWUgOjo9IFtBLVphLXpdIChbQS1aYS16MC05Ll9dIHwgJy0nKSoKLSAgICAgICAgaWYoY29udGV4dC51c2VOYW1lc3BhY2VzKCkpIHsKLSAgICAgICAgICAgIGlmICghWE1MMTFDaGFyLmlzWE1MMTFWYWxpZE5DTmFtZShjb250ZW50KSkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbigiSURSRUZJbnZhbGlkV2l0aE5hbWVzcGFjZXMiLCBuZXcgT2JqZWN0W117Y29udGVudH0pOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgaWYgKCFYTUwxMUNoYXIuaXNYTUwxMVZhbGlkTmFtZShjb250ZW50KSkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbigiSURSRUZJbnZhbGlkIiwgbmV3IE9iamVjdFtde2NvbnRlbnR9KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGNvbnRleHQuYWRkSWRSZWYoY29udGVudCk7Ci0KLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYvZHRkL1hNTDExTk1UT0tFTkRhdGF0eXBlVmFsaWRhdG9yLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L2R0ZC9YTUwxMU5NVE9LRU5EYXRhdHlwZVZhbGlkYXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxYTcyOTZiLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYvZHRkL1hNTDExTk1UT0tFTkRhdGF0eXBlVmFsaWRhdG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw1OSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LmR0ZDsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi4qOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5YTUwxMUNoYXI7Ci0KLS8qKgotICogTk1UT0tFTiBkYXRhdHlwZSB2YWxpZGF0b3IgZm9yIE5NVG9rZW5zIGZyb20gWE1MIDEuMS4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBKZWZmcmV5IFJvZHJpZ3VleiwgSUJNCi0gKiBAYXV0aG9yIFNhbmR5IEdhbywgSUJNCi0gKiBAYXV0aG9yIE5laWwgR3JhaGFtLCBJQk0KLSAqCi0gKi8KLXB1YmxpYyBjbGFzcyBYTUwxMU5NVE9LRU5EYXRhdHlwZVZhbGlkYXRvciBleHRlbmRzIE5NVE9LRU5EYXRhdHlwZVZhbGlkYXRvciB7Ci0KLSAgICAvLyBjb25zdHJ1Y3QgYSBOTVRPS0VOIGRhdGF0eXBlIHZhbGlkYXRvcgotICAgIHB1YmxpYyBYTUwxMU5NVE9LRU5EYXRhdHlwZVZhbGlkYXRvcigpIHsKLSAgICAgICAgc3VwZXIoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDaGVja3MgdGhhdCAiY29udGVudCIgc3RyaW5nIGlzIHZhbGlkIE5NVE9LRU4gdmFsdWUuCi0gICAgICogSWYgaW52YWxpZCBhIERhdGF0eXBlIHZhbGlkYXRpb24gZXhjZXB0aW9uIGlzIHRocm93bi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjb250ZW50ICAgICAgIHRoZSBzdHJpbmcgdmFsdWUgdGhhdCBuZWVkcyB0byBiZSB2YWxpZGF0ZWQKLSAgICAgKiBAcGFyYW0gY29udGV4dCAgICAgICB0aGUgdmFsaWRhdGlvbiBjb250ZXh0Ci0gICAgICogQHRocm93cyBJbnZhbGlkRGF0YXR5cGVFeGNlcHRpb24gaWYgdGhlIGNvbnRlbnQgaXMKLSAgICAgKiAgICAgICAgIGludmFsaWQgYWNjb3JkaW5nIHRvIHRoZSBydWxlcyBmb3IgdGhlIHZhbGlkYXRvcnMKLSAgICAgKiBAc2VlIEludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdmFsaWRhdGUoU3RyaW5nIGNvbnRlbnQsIFZhbGlkYXRpb25Db250ZXh0IGNvbnRleHQpIHRocm93cyBJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmICghWE1MMTFDaGFyLmlzWE1MMTFWYWxpZE5tdG9rZW4oY29udGVudCkpIHsKLSAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uKCJOTVRPS0VOSW52YWxpZCIsIG5ldyBPYmplY3RbXXtjb250ZW50fSk7Ci0gICAgICAgfQotICAgfQotCi19IC8vIGNsYXNzIFhNTDExTk1UT0tFTkRhdGF0eXBlVmFsaWRhdG9yCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L3V0aWwvQmFzZTY0LmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L3V0aWwvQmFzZTY0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDFhYjA3NTIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi91dGlsL0Jhc2U2NC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzA3ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwMiwyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYudXRpbDsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIHByb3ZpZGVzIGVuY29kZS9kZWNvZGUgZm9yIFJGQyAyMDQ1IEJhc2U2NCBhcwotICogZGVmaW5lZCBieSBSRkMgMjA0NSwgTi4gRnJlZWQgYW5kIE4uIEJvcmVuc3RlaW4uCi0gKiBSRkMgMjA0NTogTXVsdGlwdXJwb3NlIEludGVybmV0IE1haWwgRXh0ZW5zaW9ucyAoTUlNRSkKLSAqIFBhcnQgT25lOiBGb3JtYXQgb2YgSW50ZXJuZXQgTWVzc2FnZSBCb2RpZXMuIFJlZmVyZW5jZQotICogMTk5NiBBdmFpbGFibGUgYXQ6IGh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzIwNDUudHh0Ci0gKiBUaGlzIGNsYXNzIGlzIHVzZWQgYnkgWE1MIFNjaGVtYSBiaW5hcnkgZm9ybWF0IHZhbGlkYXRpb24KLSAqCi0gKiBUaGlzIGltcGxlbWVudGF0aW9uIGRvZXMgbm90IGVuY29kZS9kZWNvZGUgc3RyZWFtaW5nCi0gKiBkYXRhLiBZb3UgbmVlZCB0aGUgZGF0YSB0aGF0IHlvdSB3aWxsIGVuY29kZS9kZWNvZGUKLSAqIGFscmVhZHkgb24gYSBieXRlIGFycnJheS4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBKZWZmcmV5IFJvZHJpZ3VlegotICogQGF1dGhvciBTYW5keSBHYW8KLSAqLwotcHVibGljIGZpbmFsIGNsYXNzICBCYXNlNjQgewotCi0gICAgc3RhdGljIHByaXZhdGUgZmluYWwgaW50ICBCQVNFTEVOR1RIICAgICAgICAgPSAxMjg7Ci0gICAgc3RhdGljIHByaXZhdGUgZmluYWwgaW50ICBMT09LVVBMRU5HVEggICAgICAgPSA2NDsKLSAgICBzdGF0aWMgcHJpdmF0ZSBmaW5hbCBpbnQgIFRXRU5UWUZPVVJCSVRHUk9VUCA9IDI0OwotICAgIHN0YXRpYyBwcml2YXRlIGZpbmFsIGludCAgRUlHSFRCSVQgICAgICAgICAgID0gODsKLSAgICBzdGF0aWMgcHJpdmF0ZSBmaW5hbCBpbnQgIFNJWFRFRU5CSVQgICAgICAgICA9IDE2OwotICAgIHN0YXRpYyBwcml2YXRlIGZpbmFsIGludCAgU0lYQklUICAgICAgICAgICAgID0gNjsKLSAgICBzdGF0aWMgcHJpdmF0ZSBmaW5hbCBpbnQgIEZPVVJCWVRFICAgICAgICAgICA9IDQ7Ci0gICAgc3RhdGljIHByaXZhdGUgZmluYWwgaW50ICBTSUdOICAgICAgICAgICAgICAgPSAtMTI4OwotICAgIHN0YXRpYyBwcml2YXRlIGZpbmFsIGNoYXIgUEFEICAgICAgICAgICAgICAgID0gJz0nOwotICAgIHN0YXRpYyBwcml2YXRlIGZpbmFsIGJvb2xlYW4gZkRlYnVnICAgICAgICAgID0gZmFsc2U7Ci0gICAgc3RhdGljIGZpbmFsIHByaXZhdGUgYnl0ZSBbXSBiYXNlNjRBbHBoYWJldCAgICAgICAgPSBuZXcgYnl0ZVtCQVNFTEVOR1RIXTsKLSAgICBzdGF0aWMgZmluYWwgcHJpdmF0ZSBjaGFyIFtdIGxvb2tVcEJhc2U2NEFscGhhYmV0ICA9IG5ldyBjaGFyW0xPT0tVUExFTkdUSF07Ci0KLSAgICBzdGF0aWMgewotCi0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgQkFTRUxFTkdUSDsgKytpKSB7Ci0gICAgICAgICAgICBiYXNlNjRBbHBoYWJldFtpXSA9IC0xOwotICAgICAgICB9Ci0gICAgICAgIGZvciAoaW50IGkgPSAnWic7IGkgPj0gJ0EnOyBpLS0pIHsKLSAgICAgICAgICAgIGJhc2U2NEFscGhhYmV0W2ldID0gKGJ5dGUpIChpLSdBJyk7Ci0gICAgICAgIH0KLSAgICAgICAgZm9yIChpbnQgaSA9ICd6JzsgaT49ICdhJzsgaS0tKSB7Ci0gICAgICAgICAgICBiYXNlNjRBbHBoYWJldFtpXSA9IChieXRlKSAoIGktJ2EnICsgMjYpOwotICAgICAgICB9Ci0KLSAgICAgICAgZm9yIChpbnQgaSA9ICc5JzsgaSA+PSAnMCc7IGktLSkgewotICAgICAgICAgICAgYmFzZTY0QWxwaGFiZXRbaV0gPSAoYnl0ZSkgKGktJzAnICsgNTIpOwotICAgICAgICB9Ci0KLSAgICAgICAgYmFzZTY0QWxwaGFiZXRbJysnXSAgPSA2MjsKLSAgICAgICAgYmFzZTY0QWxwaGFiZXRbJy8nXSAgPSA2MzsKLQotICAgICAgICBmb3IgKGludCBpID0gMDsgaTw9MjU7IGkrKykKLSAgICAgICAgICAgIGxvb2tVcEJhc2U2NEFscGhhYmV0W2ldID0gKGNoYXIpKCdBJytpKTsKLQotICAgICAgICBmb3IgKGludCBpID0gMjYsICBqID0gMDsgaTw9NTE7IGkrKywgaisrKQotICAgICAgICAgICAgbG9va1VwQmFzZTY0QWxwaGFiZXRbaV0gPSAoY2hhcikoJ2EnKyBqKTsKLQotICAgICAgICBmb3IgKGludCBpID0gNTIsICBqID0gMDsgaTw9NjE7IGkrKywgaisrKQotICAgICAgICAgICAgbG9va1VwQmFzZTY0QWxwaGFiZXRbaV0gPSAoY2hhcikoJzAnICsgaik7Ci0gICAgICAgIGxvb2tVcEJhc2U2NEFscGhhYmV0WzYyXSA9IChjaGFyKScrJzsKLSAgICAgICAgbG9va1VwQmFzZTY0QWxwaGFiZXRbNjNdID0gKGNoYXIpJy8nOwotCi0gICAgfQotCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBib29sZWFuIGlzV2hpdGVTcGFjZShjaGFyIG9jdGVjdCkgewotICAgICAgICByZXR1cm4gKG9jdGVjdCA9PSAweDIwIHx8IG9jdGVjdCA9PSAweGQgfHwgb2N0ZWN0ID09IDB4YSB8fCBvY3RlY3QgPT0gMHg5KTsKLSAgICB9Ci0KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGJvb2xlYW4gaXNQYWQoY2hhciBvY3RlY3QpIHsKLSAgICAgICAgcmV0dXJuIChvY3RlY3QgPT0gUEFEKTsKLSAgICB9Ci0KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGJvb2xlYW4gaXNEYXRhKGNoYXIgb2N0ZWN0KSB7Ci0gICAgICAgIHJldHVybiAob2N0ZWN0IDwgQkFTRUxFTkdUSCAmJiBiYXNlNjRBbHBoYWJldFtvY3RlY3RdICE9IC0xKTsKLSAgICB9Ci0KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGJvb2xlYW4gaXNCYXNlNjQoY2hhciBvY3RlY3QpIHsKLSAgICAgICAgcmV0dXJuIChpc1doaXRlU3BhY2Uob2N0ZWN0KSB8fCBpc1BhZChvY3RlY3QpIHx8IGlzRGF0YShvY3RlY3QpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBFbmNvZGVzIGhleCBvY3RlY3RzIGludG8gQmFzZTY0Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gYmluYXJ5RGF0YSBBcnJheSBjb250YWluaW5nIGJpbmFyeURhdGEKLSAgICAgKiBAcmV0dXJuIEVuY29kZWQgQmFzZTY0IGFycmF5Ci0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZW5jb2RlKGJ5dGVbXSBiaW5hcnlEYXRhKSB7Ci0KLSAgICAgICAgaWYgKGJpbmFyeURhdGEgPT0gbnVsbCkKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotCi0gICAgICAgIGludCAgICAgIGxlbmd0aERhdGFCaXRzICAgID0gYmluYXJ5RGF0YS5sZW5ndGgqRUlHSFRCSVQ7Ci0gICAgICAgIGlmIChsZW5ndGhEYXRhQml0cyA9PSAwKSB7Ci0gICAgICAgICAgICByZXR1cm4gIiI7Ci0gICAgICAgIH0KLQotICAgICAgICBpbnQgICAgICBmZXdlclRoYW4yNGJpdHMgICA9IGxlbmd0aERhdGFCaXRzJVRXRU5UWUZPVVJCSVRHUk9VUDsKLSAgICAgICAgaW50ICAgICAgbnVtYmVyVHJpcGxldHMgICAgPSBsZW5ndGhEYXRhQml0cy9UV0VOVFlGT1VSQklUR1JPVVA7Ci0gICAgICAgIGludCAgICAgIG51bWJlclF1YXJ0ZXQgICAgID0gZmV3ZXJUaGFuMjRiaXRzICE9IDAgPyBudW1iZXJUcmlwbGV0cysxIDogbnVtYmVyVHJpcGxldHM7Ci0gICAgICAgIGNoYXIgICAgIGVuY29kZWREYXRhW10gICAgID0gbnVsbDsKLQotICAgICAgICBlbmNvZGVkRGF0YSA9IG5ldyBjaGFyW251bWJlclF1YXJ0ZXQqNF07Ci0KLSAgICAgICAgYnl0ZSBrPTAsIGw9MCwgYjE9MCxiMj0wLGIzPTA7Ci0KLSAgICAgICAgaW50IGVuY29kZWRJbmRleCA9IDA7Ci0gICAgICAgIGludCBkYXRhSW5kZXggICA9IDA7Ci0gICAgICAgIGlmIChmRGVidWcpIHsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigibnVtYmVyIG9mIHRyaXBsZXRzID0gIiArIG51bWJlclRyaXBsZXRzICk7Ci0gICAgICAgIH0KLQotICAgICAgICBmb3IgKGludCBpPTA7IGk8bnVtYmVyVHJpcGxldHM7IGkrKykgewotICAgICAgICAgICAgYjEgPSBiaW5hcnlEYXRhW2RhdGFJbmRleCsrXTsKLSAgICAgICAgICAgIGIyID0gYmluYXJ5RGF0YVtkYXRhSW5kZXgrK107Ci0gICAgICAgICAgICBiMyA9IGJpbmFyeURhdGFbZGF0YUluZGV4KytdOwotCi0gICAgICAgICAgICBpZiAoZkRlYnVnKSB7Ci0gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCAiYjE9ICIgKyBiMSArIiwgYjI9ICIgKyBiMiArICIsIGIzPSAiICsgYjMgKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgbCAgPSAoYnl0ZSkoYjIgJiAweDBmKTsKLSAgICAgICAgICAgIGsgID0gKGJ5dGUpKGIxICYgMHgwMyk7Ci0KLSAgICAgICAgICAgIGJ5dGUgdmFsMSA9ICgoYjEgJiBTSUdOKT09MCk/KGJ5dGUpKGIxPj4yKTooYnl0ZSkoKGIxKT4+Ml4weGMwKTsKLQotICAgICAgICAgICAgYnl0ZSB2YWwyID0gKChiMiAmIFNJR04pPT0wKT8oYnl0ZSkoYjI+PjQpOihieXRlKSgoYjIpPj40XjB4ZjApOwotICAgICAgICAgICAgYnl0ZSB2YWwzID0gKChiMyAmIFNJR04pPT0wKT8oYnl0ZSkoYjM+PjYpOihieXRlKSgoYjMpPj42XjB4ZmMpOwotCi0gICAgICAgICAgICBpZiAoZkRlYnVnKSB7Ci0gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCAidmFsMiA9ICIgKyB2YWwyICk7Ci0gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCAiazQgICA9ICIgKyAoazw8NCkpOwotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbiggInZhayAgPSAiICsgKHZhbDIgfCAoazw8NCkpKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgZW5jb2RlZERhdGFbZW5jb2RlZEluZGV4KytdID0gbG9va1VwQmFzZTY0QWxwaGFiZXRbIHZhbDEgXTsKLSAgICAgICAgICAgIGVuY29kZWREYXRhW2VuY29kZWRJbmRleCsrXSA9IGxvb2tVcEJhc2U2NEFscGhhYmV0WyB2YWwyIHwgKCBrPDw0ICldOwotICAgICAgICAgICAgZW5jb2RlZERhdGFbZW5jb2RlZEluZGV4KytdID0gbG9va1VwQmFzZTY0QWxwaGFiZXRbIChsIDw8MiApIHwgdmFsMyBdOwotICAgICAgICAgICAgZW5jb2RlZERhdGFbZW5jb2RlZEluZGV4KytdID0gbG9va1VwQmFzZTY0QWxwaGFiZXRbIGIzICYgMHgzZiBdOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gZm9ybSBpbnRlZ3JhbCBudW1iZXIgb2YgNi1iaXQgZ3JvdXBzCi0gICAgICAgIGlmIChmZXdlclRoYW4yNGJpdHMgPT0gRUlHSFRCSVQpIHsKLSAgICAgICAgICAgIGIxID0gYmluYXJ5RGF0YVtkYXRhSW5kZXhdOwotICAgICAgICAgICAgayA9IChieXRlKSAoIGIxICYweDAzICk7Ci0gICAgICAgICAgICBpZiAoZkRlYnVnKSB7Ci0gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJiMT0iICsgYjEpOwotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiYjE8PDIgPSAiICsgKGIxPj4yKSApOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgYnl0ZSB2YWwxID0gKChiMSAmIFNJR04pPT0wKT8oYnl0ZSkoYjE+PjIpOihieXRlKSgoYjEpPj4yXjB4YzApOwotICAgICAgICAgICAgZW5jb2RlZERhdGFbZW5jb2RlZEluZGV4KytdID0gbG9va1VwQmFzZTY0QWxwaGFiZXRbIHZhbDEgXTsKLSAgICAgICAgICAgIGVuY29kZWREYXRhW2VuY29kZWRJbmRleCsrXSA9IGxvb2tVcEJhc2U2NEFscGhhYmV0WyBrPDw0IF07Ci0gICAgICAgICAgICBlbmNvZGVkRGF0YVtlbmNvZGVkSW5kZXgrK10gPSBQQUQ7Ci0gICAgICAgICAgICBlbmNvZGVkRGF0YVtlbmNvZGVkSW5kZXgrK10gPSBQQUQ7Ci0gICAgICAgIH0gZWxzZSBpZiAoZmV3ZXJUaGFuMjRiaXRzID09IFNJWFRFRU5CSVQpIHsKLSAgICAgICAgICAgIGIxID0gYmluYXJ5RGF0YVtkYXRhSW5kZXhdOwotICAgICAgICAgICAgYjIgPSBiaW5hcnlEYXRhW2RhdGFJbmRleCArMSBdOwotICAgICAgICAgICAgbCA9ICggYnl0ZSApICggYjIgJjB4MGYgKTsKLSAgICAgICAgICAgIGsgPSAoIGJ5dGUgKSAoIGIxICYweDAzICk7Ci0KLSAgICAgICAgICAgIGJ5dGUgdmFsMSA9ICgoYjEgJiBTSUdOKT09MCk/KGJ5dGUpKGIxPj4yKTooYnl0ZSkoKGIxKT4+Ml4weGMwKTsKLSAgICAgICAgICAgIGJ5dGUgdmFsMiA9ICgoYjIgJiBTSUdOKT09MCk/KGJ5dGUpKGIyPj40KTooYnl0ZSkoKGIyKT4+NF4weGYwKTsKLQotICAgICAgICAgICAgZW5jb2RlZERhdGFbZW5jb2RlZEluZGV4KytdID0gbG9va1VwQmFzZTY0QWxwaGFiZXRbIHZhbDEgXTsKLSAgICAgICAgICAgIGVuY29kZWREYXRhW2VuY29kZWRJbmRleCsrXSA9IGxvb2tVcEJhc2U2NEFscGhhYmV0WyB2YWwyIHwgKCBrPDw0ICldOwotICAgICAgICAgICAgZW5jb2RlZERhdGFbZW5jb2RlZEluZGV4KytdID0gbG9va1VwQmFzZTY0QWxwaGFiZXRbIGw8PDIgXTsKLSAgICAgICAgICAgIGVuY29kZWREYXRhW2VuY29kZWRJbmRleCsrXSA9IFBBRDsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBuZXcgU3RyaW5nKGVuY29kZWREYXRhKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBEZWNvZGVzIEJhc2U2NCBkYXRhIGludG8gb2N0ZWN0cwotICAgICAqCi0gICAgICogQHBhcmFtIGVuY29kZWQgc3RyaW5nIGNvbnRhaW5pbmcgQmFzZTY0IGRhdGEKLSAgICAgKiBAcmV0dXJuIEFycmF5IGNvbnRhaW5pbmQgZGVjb2RlZCBkYXRhLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgYnl0ZVtdIGRlY29kZShTdHJpbmcgZW5jb2RlZCkgewotCi0gICAgICAgIGlmIChlbmNvZGVkID09IG51bGwpCi0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLQotICAgICAgICBjaGFyW10gYmFzZTY0RGF0YSA9IGVuY29kZWQudG9DaGFyQXJyYXkoKTsKLSAgICAgICAgLy8gcmVtb3ZlIHdoaXRlIHNwYWNlcwotICAgICAgICBpbnQgbGVuID0gcmVtb3ZlV2hpdGVTcGFjZShiYXNlNjREYXRhKTsKLQotICAgICAgICBpZiAobGVuJUZPVVJCWVRFICE9IDApIHsKLSAgICAgICAgICAgIHJldHVybiBudWxsOy8vc2hvdWxkIGJlIGRpdmlzaWJsZSBieSBmb3VyCi0gICAgICAgIH0KLQotICAgICAgICBpbnQgICAgICBudW1iZXJRdWFkcnVwbGUgICAgPSAobGVuL0ZPVVJCWVRFICk7Ci0KLSAgICAgICAgaWYgKG51bWJlclF1YWRydXBsZSA9PSAwKQotICAgICAgICAgICAgcmV0dXJuIG5ldyBieXRlWzBdOwotCi0gICAgICAgIGJ5dGUgICAgIGRlY29kZWREYXRhW10gICAgICA9IG51bGw7Ci0gICAgICAgIGJ5dGUgICAgIGIxPTAsYjI9MCxiMz0wLGI0PTA7Ci0gICAgICAgIGNoYXIgICAgIGQxPTAsZDI9MCxkMz0wLGQ0PTA7Ci0KLSAgICAgICAgaW50IGkgPSAwOwotICAgICAgICBpbnQgZW5jb2RlZEluZGV4ID0gMDsKLSAgICAgICAgaW50IGRhdGFJbmRleCAgICA9IDA7Ci0gICAgICAgIGRlY29kZWREYXRhICAgICAgPSBuZXcgYnl0ZVsgKG51bWJlclF1YWRydXBsZSkqM107Ci0KLSAgICAgICAgZm9yICg7IGk8bnVtYmVyUXVhZHJ1cGxlLTE7IGkrKykgewotCi0gICAgICAgICAgICBpZiAoIWlzRGF0YSggKGQxID0gYmFzZTY0RGF0YVtkYXRhSW5kZXgrK10pICl8fAotICAgICAgICAgICAgICAgICFpc0RhdGEoIChkMiA9IGJhc2U2NERhdGFbZGF0YUluZGV4KytdKSApfHwKLSAgICAgICAgICAgICAgICAhaXNEYXRhKCAoZDMgPSBiYXNlNjREYXRhW2RhdGFJbmRleCsrXSkgKXx8Ci0gICAgICAgICAgICAgICAgIWlzRGF0YSggKGQ0ID0gYmFzZTY0RGF0YVtkYXRhSW5kZXgrK10pICkpCi0gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7Ly9pZiBmb3VuZCAibm8gZGF0YSIganVzdCByZXR1cm4gbnVsbAotCi0gICAgICAgICAgICBiMSA9IGJhc2U2NEFscGhhYmV0W2QxXTsKLSAgICAgICAgICAgIGIyID0gYmFzZTY0QWxwaGFiZXRbZDJdOwotICAgICAgICAgICAgYjMgPSBiYXNlNjRBbHBoYWJldFtkM107Ci0gICAgICAgICAgICBiNCA9IGJhc2U2NEFscGhhYmV0W2Q0XTsKLQotICAgICAgICAgICAgZGVjb2RlZERhdGFbZW5jb2RlZEluZGV4KytdID0gKGJ5dGUpKCAgYjEgPDwyIHwgYjI+PjQgKSA7Ci0gICAgICAgICAgICBkZWNvZGVkRGF0YVtlbmNvZGVkSW5kZXgrK10gPSAoYnl0ZSkoKChiMiAmIDB4Zik8PDQgKSB8KCAoYjM+PjIpICYgMHhmKSApOwotICAgICAgICAgICAgZGVjb2RlZERhdGFbZW5jb2RlZEluZGV4KytdID0gKGJ5dGUpKCBiMzw8NiB8IGI0ICk7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoIWlzRGF0YSggKGQxID0gYmFzZTY0RGF0YVtkYXRhSW5kZXgrK10pICkgfHwKLSAgICAgICAgICAgICFpc0RhdGEoIChkMiA9IGJhc2U2NERhdGFbZGF0YUluZGV4KytdKSApKSB7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsvL2lmIGZvdW5kICJubyBkYXRhIiBqdXN0IHJldHVybiBudWxsCi0gICAgICAgIH0KLQotICAgICAgICBiMSA9IGJhc2U2NEFscGhhYmV0W2QxXTsKLSAgICAgICAgYjIgPSBiYXNlNjRBbHBoYWJldFtkMl07Ci0KLSAgICAgICAgZDMgPSBiYXNlNjREYXRhW2RhdGFJbmRleCsrXTsKLSAgICAgICAgZDQgPSBiYXNlNjREYXRhW2RhdGFJbmRleCsrXTsKLSAgICAgICAgaWYgKCFpc0RhdGEoIChkMyApICkgfHwKLSAgICAgICAgICAgICFpc0RhdGEoIChkNCApICkpIHsvL0NoZWNrIGlmIHRoZXkgYXJlIFBBRCBjaGFyYWN0ZXJzCi0gICAgICAgICAgICBpZiAoaXNQYWQoIGQzICkgJiYgaXNQYWQoIGQ0KSkgeyAgICAgICAgICAgICAgIC8vVHdvIFBBRCBlLmcuIDNjW1BhZF1bUGFkXQotICAgICAgICAgICAgICAgIGlmICgoYjIgJiAweGYpICE9IDApLy9sYXN0IDQgYml0cyBzaG91bGQgYmUgemVybwotICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgICAgICAgICBieXRlW10gdG1wID0gbmV3IGJ5dGVbIGkqMyArIDEgXTsKLSAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KCBkZWNvZGVkRGF0YSwgMCwgdG1wLCAwLCBpKjMgKTsKLSAgICAgICAgICAgICAgICB0bXBbZW5jb2RlZEluZGV4XSAgID0gKGJ5dGUpKCAgYjEgPDwyIHwgYjI+PjQgKSA7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHRtcDsKLSAgICAgICAgICAgIH0gZWxzZSBpZiAoIWlzUGFkKCBkMykgJiYgaXNQYWQoZDQpKSB7ICAgICAgICAgICAgICAgLy9PbmUgUEFEICBlLmcuIDNjUVtQYWRdCi0gICAgICAgICAgICAgICAgYjMgPSBiYXNlNjRBbHBoYWJldFsgZDMgXTsKLSAgICAgICAgICAgICAgICBpZiAoKGIzICYgMHgzICkgIT0gMCkvL2xhc3QgMiBiaXRzIHNob3VsZCBiZSB6ZXJvCi0gICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICAgICAgICAgIGJ5dGVbXSB0bXAgPSBuZXcgYnl0ZVsgaSozICsgMiBdOwotICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoIGRlY29kZWREYXRhLCAwLCB0bXAsIDAsIGkqMyApOwotICAgICAgICAgICAgICAgIHRtcFtlbmNvZGVkSW5kZXgrK10gPSAoYnl0ZSkoICBiMSA8PDIgfCBiMj4+NCApOwotICAgICAgICAgICAgICAgIHRtcFtlbmNvZGVkSW5kZXhdICAgPSAoYnl0ZSkoKChiMiAmIDB4Zik8PDQgKSB8KCAoYjM+PjIpICYgMHhmKSApOwotICAgICAgICAgICAgICAgIHJldHVybiB0bXA7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIHJldHVybiBudWxsOy8vYW4gZXJyb3IgIGxpa2UgIjNjW1BhZF1yIiwgIjNjZFgiLCAiM2NYZCIsICIzY1hYIiB3aGVyZSBYIGlzIG5vbiBkYXRhCi0gICAgICAgICAgICB9Ci0gICAgICAgIH0gZWxzZSB7IC8vTm8gUEFEIGUuZyAzY1FsCi0gICAgICAgICAgICBiMyA9IGJhc2U2NEFscGhhYmV0WyBkMyBdOwotICAgICAgICAgICAgYjQgPSBiYXNlNjRBbHBoYWJldFsgZDQgXTsKLSAgICAgICAgICAgIGRlY29kZWREYXRhW2VuY29kZWRJbmRleCsrXSA9IChieXRlKSggIGIxIDw8MiB8IGIyPj40ICkgOwotICAgICAgICAgICAgZGVjb2RlZERhdGFbZW5jb2RlZEluZGV4KytdID0gKGJ5dGUpKCgoYjIgJiAweGYpPDw0ICkgfCggKGIzPj4yKSAmIDB4ZikgKTsKLSAgICAgICAgICAgIGRlY29kZWREYXRhW2VuY29kZWRJbmRleCsrXSA9IChieXRlKSggYjM8PDYgfCBiNCApOwotCi0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gZGVjb2RlZERhdGE7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogcmVtb3ZlIFdoaXRlU3BhY2UgZnJvbSBNSU1FIGNvbnRhaW5pbmcgZW5jb2RlZCBCYXNlNjQgZGF0YS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBkYXRhICB0aGUgYnl0ZSBhcnJheSBvZiBiYXNlNjQgZGF0YSAod2l0aCBXUykKLSAgICAgKiBAcmV0dXJuICAgICAgdGhlIG5ldyBsZW5ndGgKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGludCByZW1vdmVXaGl0ZVNwYWNlKGNoYXJbXSBkYXRhKSB7Ci0gICAgICAgIGlmIChkYXRhID09IG51bGwpCi0gICAgICAgICAgICByZXR1cm4gMDsKLQotICAgICAgICAvLyBjb3VudCBjaGFyYWN0ZXJzIHRoYXQncyBub3Qgd2hpdGVzcGFjZQotICAgICAgICBpbnQgbmV3U2l6ZSA9IDA7Ci0gICAgICAgIGludCBsZW4gPSBkYXRhLmxlbmd0aDsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW47IGkrKykgewotICAgICAgICAgICAgaWYgKCFpc1doaXRlU3BhY2UoZGF0YVtpXSkpCi0gICAgICAgICAgICAgICAgZGF0YVtuZXdTaXplKytdID0gZGF0YVtpXTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbmV3U2l6ZTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L3V0aWwvQnl0ZUxpc3RJbXBsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L3V0aWwvQnl0ZUxpc3RJbXBsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDk4NGZiMmEuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi91dGlsL0J5dGVMaXN0SW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTA2ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYudXRpbDsKLQotaW1wb3J0IGphdmEudXRpbC5BYnN0cmFjdExpc3Q7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuZGF0YXR5cGVzLkJ5dGVMaXN0OwotCi0vKioKLSAqIEltcGxlbWVudGF0aW9uIG9mIDxjb2RlPmNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuZGF0YXR5cGVzLkJ5dGVMaXN0PC9jb2RlPi4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBBbmtpdCBQYXNyaWNoYSwgSUJNCi0gKgotICogQHZlcnNpb24gJElkOiBCeXRlTGlzdEltcGwuamF2YSx2IDEuNyAyMDEwLTExLTAxIDA0OjM5OjQ2IGpvZWh3IEV4cCAkCi0gKi8KLXB1YmxpYyBjbGFzcyBCeXRlTGlzdEltcGwgZXh0ZW5kcyBBYnN0cmFjdExpc3QgaW1wbGVtZW50cyBCeXRlTGlzdCB7Ci0KLSAgICAvLyBhY3R1YWxseSBkYXRhIHN0b3JlZCBpbiBhIGJ5dGUgYXJyYXkKLSAgICBwcm90ZWN0ZWQgZmluYWwgYnl0ZVtdIGRhdGE7Ci0KLSAgICAvLyBjYW5vbmljYWwgcmVwcmVzZW50YXRpb24gb2YgdGhlIGRhdGEKLSAgICBwcm90ZWN0ZWQgU3RyaW5nIGNhbm9uaWNhbDsKLQotICAgIHB1YmxpYyBCeXRlTGlzdEltcGwoYnl0ZVtdIGRhdGEpIHsKLSAgICAgICAgdGhpcy5kYXRhID0gZGF0YTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgbnVtYmVyIG9mIDxjb2RlPmJ5dGU8L2NvZGU+cyBpbiB0aGUgbGlzdC4gVGhlIHJhbmdlIG9mCi0gICAgICogdmFsaWQgY2hpbGQgb2JqZWN0IGluZGljZXMgaXMgMCB0byA8Y29kZT5sZW5ndGgtMTwvY29kZT4gaW5jbHVzaXZlLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0TGVuZ3RoKCkgewotICAgICAgICByZXR1cm4gZGF0YS5sZW5ndGg7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ2hlY2tzIGlmIHRoZSA8Y29kZT5ieXRlPC9jb2RlPiA8Y29kZT5pdGVtPC9jb2RlPiBpcyBhCi0gICAgICogbWVtYmVyIG9mIHRoaXMgbGlzdC4KLSAgICAgKiBAcGFyYW0gaXRlbSAgPGNvZGU+Ynl0ZTwvY29kZT4gd2hvc2UgcHJlc2VuY2UgaW4gdGhpcyBsaXN0Ci0gICAgICogICBpcyB0byBiZSB0ZXN0ZWQuCi0gICAgICogQHJldHVybiAgVHJ1ZSBpZiB0aGlzIGxpc3QgY29udGFpbnMgdGhlIDxjb2RlPmJ5dGU8L2NvZGU+Ci0gICAgICogICA8Y29kZT5pdGVtPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBjb250YWlucyhieXRlIGl0ZW0pIHsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBkYXRhLmxlbmd0aDsgKytpKSB7Ci0gICAgICAgICAgICBpZiAoZGF0YVtpXSA9PSBpdGVtKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIDxjb2RlPmluZGV4PC9jb2RlPnRoIGl0ZW0gaW4gdGhlIGNvbGxlY3Rpb24uIFRoZSBpbmRleAotICAgICAqIHN0YXJ0cyBhdCAwLgotICAgICAqIEBwYXJhbSBpbmRleCAgaW5kZXggaW50byB0aGUgY29sbGVjdGlvbi4KLSAgICAgKiBAcmV0dXJuICBUaGUgPGNvZGU+Ynl0ZTwvY29kZT4gYXQgdGhlIDxjb2RlPmluZGV4PC9jb2RlPnRoCi0gICAgICogICBwb3NpdGlvbiBpbiB0aGUgPGNvZGU+Qnl0ZUxpc3Q8L2NvZGU+LgotICAgICAqIEBleGNlcHRpb24gWFNFeGNlcHRpb24KLSAgICAgKiAgIElOREVYX1NJWkVfRVJSOiBpZiA8Y29kZT5pbmRleDwvY29kZT4gaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHRoZQotICAgICAqICAgbnVtYmVyIG9mIG9iamVjdHMgaW4gdGhlIGxpc3QuCi0gICAgICovCi0gICAgcHVibGljIGJ5dGUgaXRlbShpbnQgaW5kZXgpCi0gICAgICAgIHRocm93cyBYU0V4Y2VwdGlvbiB7Ci0KLSAgICAgICAgaWYoaW5kZXggPCAwIHx8IGluZGV4ID4gZGF0YS5sZW5ndGggLSAxKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWFNFeGNlcHRpb24oWFNFeGNlcHRpb24uSU5ERVhfU0laRV9FUlIsIG51bGwpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBkYXRhW2luZGV4XTsKLSAgICB9Ci0KLSAgICAvKgotICAgICAqIExpc3QgbWV0aG9kcwotICAgICAqLwotCi0gICAgcHVibGljIE9iamVjdCBnZXQoaW50IGluZGV4KSB7Ci0gICAgICAgIGlmIChpbmRleCA+PSAwICYmIGluZGV4IDwgZGF0YS5sZW5ndGgpIHsKLSAgICAgICAgICAgIHJldHVybiBuZXcgQnl0ZShkYXRhW2luZGV4XSk7Ci0gICAgICAgIH0KLSAgICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oIkluZGV4OiAiICsgaW5kZXgpOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKLSAgICAgICAgcmV0dXJuIGdldExlbmd0aCgpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYvdXRpbC9IZXhCaW4uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYvdXRpbC9IZXhCaW4uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZmI0NzdhYy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L3V0aWwvSGV4QmluLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMTUgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDAyLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi51dGlsOwotCi0vKioKLSAqIGZvcm1hdCB2YWxpZGF0aW9uCi0gKgotICogVGhpcyBjbGFzcyBlbmNvZGVzL2RlY29kZXMgaGV4YWRlY2ltYWwgZGF0YQotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIEplZmZyZXkgUm9kcmlndWV6Ci0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyAgSGV4QmluIHsKLSAgICBzdGF0aWMgcHJpdmF0ZSBmaW5hbCBpbnQgIEJBU0VMRU5HVEggICA9IDEyODsKLSAgICBzdGF0aWMgcHJpdmF0ZSBmaW5hbCBpbnQgIExPT0tVUExFTkdUSCA9IDE2OwotICAgIHN0YXRpYyBmaW5hbCBwcml2YXRlIGJ5dGUgW10gaGV4TnVtYmVyVGFibGUgICAgPSBuZXcgYnl0ZVtCQVNFTEVOR1RIXTsKLSAgICBzdGF0aWMgZmluYWwgcHJpdmF0ZSBjaGFyIFtdIGxvb2tVcEhleEFscGhhYmV0ID0gbmV3IGNoYXJbTE9PS1VQTEVOR1RIXTsKLQotCi0gICAgc3RhdGljIHsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBCQVNFTEVOR1RIOyBpKysgKSB7Ci0gICAgICAgICAgICBoZXhOdW1iZXJUYWJsZVtpXSA9IC0xOwotICAgICAgICB9Ci0gICAgICAgIGZvciAoIGludCBpID0gJzknOyBpID49ICcwJzsgaS0tKSB7Ci0gICAgICAgICAgICBoZXhOdW1iZXJUYWJsZVtpXSA9IChieXRlKSAoaS0nMCcpOwotICAgICAgICB9Ci0gICAgICAgIGZvciAoIGludCBpID0gJ0YnOyBpPj0gJ0EnOyBpLS0pIHsKLSAgICAgICAgICAgIGhleE51bWJlclRhYmxlW2ldID0gKGJ5dGUpICggaS0nQScgKyAxMCApOwotICAgICAgICB9Ci0gICAgICAgIGZvciAoIGludCBpID0gJ2YnOyBpPj0gJ2EnOyBpLS0pIHsKLSAgICAgICAgICAgaGV4TnVtYmVyVGFibGVbaV0gPSAoYnl0ZSkgKCBpLSdhJyArIDEwICk7Ci0gICAgICAgIH0KLQotICAgICAgICBmb3IoaW50IGkgPSAwOyBpPDEwOyBpKysgKSB7Ci0gICAgICAgICAgICBsb29rVXBIZXhBbHBoYWJldFtpXSA9IChjaGFyKSgnMCcraSk7Ci0gICAgICAgIH0KLSAgICAgICAgZm9yKGludCBpID0gMTA7IGk8PTE1OyBpKysgKSB7Ci0gICAgICAgICAgICBsb29rVXBIZXhBbHBoYWJldFtpXSA9IChjaGFyKSgnQScraSAtMTApOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRW5jb2RlIGEgYnl0ZSBhcnJheSB0byBoZXggc3RyaW5nCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYmluYXJ5RGF0YSBhcnJheSBvZiBieXRlIHRvIGVuY29kZQotICAgICAqIEByZXR1cm4gcmV0dXJuIGVuY29kZWQgc3RyaW5nCi0gICAgICovCi0gICAgc3RhdGljIHB1YmxpYyBTdHJpbmcgZW5jb2RlKGJ5dGVbXSBiaW5hcnlEYXRhKSB7Ci0gICAgICAgIGlmIChiaW5hcnlEYXRhID09IG51bGwpCi0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgaW50IGxlbmd0aERhdGEgICA9IGJpbmFyeURhdGEubGVuZ3RoOwotICAgICAgICBpbnQgbGVuZ3RoRW5jb2RlID0gbGVuZ3RoRGF0YSAqIDI7Ci0gICAgICAgIGNoYXJbXSBlbmNvZGVkRGF0YSA9IG5ldyBjaGFyW2xlbmd0aEVuY29kZV07Ci0gICAgICAgIGludCB0ZW1wOwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aERhdGE7IGkrKykgewotICAgICAgICAgICAgdGVtcCA9IGJpbmFyeURhdGFbaV07Ci0gICAgICAgICAgICBpZiAodGVtcCA8IDApCi0gICAgICAgICAgICAgICAgdGVtcCArPSAyNTY7Ci0gICAgICAgICAgICBlbmNvZGVkRGF0YVtpKjJdID0gbG9va1VwSGV4QWxwaGFiZXRbdGVtcCA+PiA0XTsKLSAgICAgICAgICAgIGVuY29kZWREYXRhW2kqMisxXSA9IGxvb2tVcEhleEFscGhhYmV0W3RlbXAgJiAweGZdOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBuZXcgU3RyaW5nKGVuY29kZWREYXRhKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBEZWNvZGUgaGV4IHN0cmluZyB0byBhIGJ5dGUgYXJyYXkKLSAgICAgKgotICAgICAqIEBwYXJhbSBlbmNvZGVkIGVuY29kZWQgc3RyaW5nCi0gICAgICogQHJldHVybiByZXR1cm4gYXJyYXkgb2YgYnl0ZSB0byBlbmNvZGUKLSAgICAgKi8KLSAgICBzdGF0aWMgcHVibGljIGJ5dGVbXSBkZWNvZGUoU3RyaW5nIGVuY29kZWQpIHsKLSAgICAgICAgaWYgKGVuY29kZWQgPT0gbnVsbCkKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICBpbnQgbGVuZ3RoRGF0YSA9IGVuY29kZWQubGVuZ3RoKCk7Ci0gICAgICAgIGlmIChsZW5ndGhEYXRhICUgMiAhPSAwKQotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0KLSAgICAgICAgY2hhcltdIGJpbmFyeURhdGEgPSBlbmNvZGVkLnRvQ2hhckFycmF5KCk7Ci0gICAgICAgIGludCBsZW5ndGhEZWNvZGUgPSBsZW5ndGhEYXRhIC8gMjsKLSAgICAgICAgYnl0ZVtdIGRlY29kZWREYXRhID0gbmV3IGJ5dGVbbGVuZ3RoRGVjb2RlXTsKLSAgICAgICAgYnl0ZSB0ZW1wMSwgdGVtcDI7Ci0gICAgICAgIGNoYXIgdGVtcENoYXI7Ci0gICAgICAgIGZvciggaW50IGkgPSAwOyBpPGxlbmd0aERlY29kZTsgaSsrICl7Ci0gICAgICAgICAgICB0ZW1wQ2hhciA9IGJpbmFyeURhdGFbaSoyXTsKLSAgICAgICAgICAgIHRlbXAxID0gKHRlbXBDaGFyIDwgQkFTRUxFTkdUSCkgPyBoZXhOdW1iZXJUYWJsZVt0ZW1wQ2hhcl0gOiAtMTsKLSAgICAgICAgICAgIGlmICh0ZW1wMSA9PSAtMSkKLSAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgICAgIHRlbXBDaGFyID0gYmluYXJ5RGF0YVtpKjIrMV07Ci0gICAgICAgICAgICB0ZW1wMiA9ICh0ZW1wQ2hhciA8IEJBU0VMRU5HVEgpID8gaGV4TnVtYmVyVGFibGVbdGVtcENoYXJdIDogLTE7Ci0gICAgICAgICAgICBpZiAodGVtcDIgPT0gLTEpCi0gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgICAgICBkZWNvZGVkRGF0YVtpXSA9IChieXRlKSgodGVtcDEgPDwgNCkgfCB0ZW1wMik7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGRlY29kZWREYXRhOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYveHMvQWJzdHJhY3REYXRlVGltZURWLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L3hzL0Fic3RyYWN0RGF0ZVRpbWVEVi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkOWQ2NTg3Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYveHMvQWJzdHJhY3REYXRlVGltZURWLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMTc4ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LnhzOwotCi1pbXBvcnQgamF2YS5tYXRoLkJpZ0RlY2ltYWw7Ci0KLWltcG9ydCBqYXZheC54bWwuZGF0YXR5cGUuRGF0YXR5cGVGYWN0b3J5OwotaW1wb3J0IGphdmF4LnhtbC5kYXRhdHlwZS5EdXJhdGlvbjsKLWltcG9ydCBqYXZheC54bWwuZGF0YXR5cGUuWE1MR3JlZ29yaWFuQ2FsZW5kYXI7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuamF4cC5kYXRhdHlwZS5EYXRhdHlwZUZhY3RvcnlJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuZGF0YXR5cGVzLlhTRGF0ZVRpbWU7Ci0KLS8qKgotICogVGhpcyBpcyB0aGUgYmFzZSBjbGFzcyBvZiBhbGwgZGF0ZS90aW1lIGRhdGF0eXBlIHZhbGlkYXRvcnMuCi0gKiBJdCBpbXBsZW1lbnRzIGNvbW1vbiBjb2RlIGZvciBwYXJzaW5nLCB2YWxpZGF0aW5nIGFuZCBjb21wYXJpbmcgZGF0YXR5cGVzLgotICogQ2xhc3NlcyB0aGF0IGV4dGVuZCB0aGlzIGNsYXNzLCBtdXN0IGltcGxlbWVudCBwYXJzZSgpIG1ldGhvZC4KLSAqCi0gKiBSRVZJU0lUOiBUaGVyZSBhcmUgbWFueSBpbnN0YW5jZSB2YXJpYWJsZXMsIHdoaWNoIHdvdWxkIGNhdXNlIHByb2JsZW1zCi0gKiAgICAgICAgICB3aGVuIHdlIHN1cHBvcnQgZ3JhbW1hciBjYWNoaW5nLiBBIGdyYW1tYXIgaXMgcG9zc2libHkgdXNlZCBieQotICogICAgICAgICAgdHdvIHBhcnNlciBpbnN0YW5jZXMgYXQgdGhlIHNhbWUgdGltZSwgdGhlbiB0aGUgc2FtZSBzaW1wbGUgdHlwZQotICogICAgICAgICAgZGVjbCBvYmplY3QgY2FuIGJlIHVzZWQgdG8gdmFsaWRhdGUgdHdvIHN0cmluZ3MgYXQgdGhlIHNhbWUgdGltZS4KLSAqICAgICAgICAgIC1TRwotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIEVsZW5hIExpdGFuaQotICogQGF1dGhvciBMZW4gQmVybWFuCi0gKiBAYXV0aG9yIEdvcGFsIFNoYXJtYSwgU1VOIE1pY3Jvc3lzdGVtcyBJbmMuCi0gKgotICogQHZlcnNpb24gJElkOiBBYnN0cmFjdERhdGVUaW1lRFYuamF2YSx2IDEuNyAyMDEwLTExLTAxIDA0OjM5OjQ2IGpvZWh3IEV4cCAkCi0gKi8KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBBYnN0cmFjdERhdGVUaW1lRFYgZXh0ZW5kcyBUeXBlVmFsaWRhdG9yIHsKLQotICAgIC8vZGVidWdnaW5nCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbiBERUJVRyA9IGZhbHNlOwotICAgIC8vZGVmaW5lIHNoYXJlZCB2YXJpYWJsZXMgZm9yIGRhdGUvdGltZQotICAgIC8vZGVmaW5lIGNvbnN0YW50cyB0byBiZSB1c2VkIGluIGFzc2lnbmluZyBkZWZhdWx0IHZhbHVlcyBmb3IKLSAgICAvL2FsbCBkYXRlL3RpbWUgZXhjbHVkaW5nIGR1cmF0aW9uCi0gICAgcHJvdGVjdGVkIGZpbmFsIHN0YXRpYyBpbnQgWUVBUiA9IDIwMDA7Ci0gICAgcHJvdGVjdGVkIGZpbmFsIHN0YXRpYyBpbnQgTU9OVEggPSAwMTsKLSAgICBwcm90ZWN0ZWQgZmluYWwgc3RhdGljIGludCBEQVkgPSAwMTsKLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIERhdGF0eXBlRmFjdG9yeSBkYXRhdHlwZUZhY3RvcnkgPSBuZXcgRGF0YXR5cGVGYWN0b3J5SW1wbCgpOwotCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIHNob3J0IGdldEFsbG93ZWRGYWNldHMoKSB7Ci0gICAgICAgIHJldHVybiAoWFNTaW1wbGVUeXBlRGVjbC5GQUNFVF9QQVRURVJOIHwgWFNTaW1wbGVUeXBlRGVjbC5GQUNFVF9XSElURVNQQUNFIHwgWFNTaW1wbGVUeXBlRGVjbC5GQUNFVF9FTlVNRVJBVElPTiB8IFhTU2ltcGxlVHlwZURlY2wuRkFDRVRfTUFYSU5DTFVTSVZFIHwgWFNTaW1wbGVUeXBlRGVjbC5GQUNFVF9NSU5JTkNMVVNJVkUgfCBYU1NpbXBsZVR5cGVEZWNsLkZBQ0VUX01BWEVYQ0xVU0lWRSB8IFhTU2ltcGxlVHlwZURlY2wuRkFDRVRfTUlORVhDTFVTSVZFKTsKLSAgICB9Ly9nZXRBbGxvd2VkRmFjZXRzKCkKLQotICAgIC8vIGRpc3Rpbmd1aXNoZXMgYmV0d2VlbiBpZGVudGl0eSBhbmQgZXF1YWxpdHkgZm9yIGRhdGUvdGltZSB2YWx1ZXMKLSAgICAvLyBpZTogdHdvIHZhbHVlcyByZXByZXNlbnRpbmcgdGhlIHNhbWUgIm1vbWVudCBpbiB0aW1lIiBidXQgd2l0aCBkaWZmZXJlbnQKLSAgICAvLyByZW1lbWJlcmVkIHRpbWV6b25lcyBhcmUgbm93IGVxdWFsIGJ1dCBub3QgaWRlbnRpY2FsLgotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyBib29sZWFuIGlzSWRlbnRpY2FsKE9iamVjdCB2YWx1ZTEsIE9iamVjdCB2YWx1ZTIpIHsKLSAgICAgICAgaWYgKCEodmFsdWUxIGluc3RhbmNlb2YgRGF0ZVRpbWVEYXRhKSB8fCAhKHZhbHVlMiBpbnN0YW5jZW9mIERhdGVUaW1lRGF0YSkpIHsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotCi0gICAgICAgIERhdGVUaW1lRGF0YSB2MSA9IChEYXRlVGltZURhdGEpIHZhbHVlMTsKLSAgICAgICAgRGF0ZVRpbWVEYXRhIHYyID0gKERhdGVUaW1lRGF0YSkgdmFsdWUyOwotCi0gICAgICAgIC8vIG9yaWdpbmFsIHRpbWV6b25lcyBtdXN0IGJlIHRoZSBzYW1lIGluIGFkZGl0aW9uIHRvIGRhdGUvdGltZSB2YWx1ZXMKLSAgICAgICAgLy8gYmVpbmcgJ2VxdWFsJwotICAgICAgICBpZiAoKHYxLnRpbWV6b25lSHIgPT0gdjIudGltZXpvbmVIcikgJiYgKHYxLnRpbWV6b25lTWluID09IHYyLnRpbWV6b25lTWluKSkgewotICAgICAgICAgICAgcmV0dXJuIHYxLmVxdWFscyh2Mik7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfS8vaXNJZGVudGljYWwoKQotCi0gICAgLy8gdGhlIHBhcmFtZXRlcnMgYXJlIGluIGNvbXBpbGVkIGZvcm0gKGZyb20gZ2V0QWN0dWFsVmFsdWUpCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIGludCBjb21wYXJlKE9iamVjdCB2YWx1ZTEsIE9iamVjdCB2YWx1ZTIpIHsKLSAgICAgICAgcmV0dXJuIGNvbXBhcmVEYXRlcygoKERhdGVUaW1lRGF0YSkgdmFsdWUxKSwKLSAgICAgICAgICAgICAgICAoKERhdGVUaW1lRGF0YSkgdmFsdWUyKSwgdHJ1ZSk7Ci0gICAgfS8vY29tcGFyZSgpCi0KLSAgICAvKioKLSAgICAgKiBDb21wYXJlIGFsZ29yaXRobSBkZXNjcmliZWQgaW4gZGF0ZURpbWUgKDMuMi43KS4gRHVyYXRpb24gZGF0YXR5cGUKLSAgICAgKiBvdmVyd3JpdGVzIHRoaXMgbWV0aG9kCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZGF0ZTEgbm9ybWFsaXplZCBkYXRlIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBmaXJzdCB2YWx1ZQotICAgICAqIEBwYXJhbSBkYXRlMiBub3JtYWxpemVkIGRhdGUgcmVwcmVzZW50YXRpb24gb2YgdGhlIHNlY29uZCB2YWx1ZQotICAgICAqIEBwYXJhbSBzdHJpY3QKLSAgICAgKiBAcmV0dXJuIGxlc3MsIGdyZWF0ZXIsIGxlc3NfZXF1YWwsIGdyZWF0ZXJfZXF1YWwsIGVxdWFsCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHNob3J0IGNvbXBhcmVEYXRlcyhEYXRlVGltZURhdGEgZGF0ZTEsIERhdGVUaW1lRGF0YSBkYXRlMiwgYm9vbGVhbiBzdHJpY3QpIHsKLSAgICAgICAgaWYgKGRhdGUxLnV0YyA9PSBkYXRlMi51dGMpIHsKLSAgICAgICAgICAgIHJldHVybiBjb21wYXJlT3JkZXIoZGF0ZTEsIGRhdGUyKTsKLSAgICAgICAgfQotICAgICAgICBzaG9ydCBjMSwgYzI7Ci0KLSAgICAgICAgRGF0ZVRpbWVEYXRhIHRlbXBEYXRlID0gbmV3IERhdGVUaW1lRGF0YShudWxsLCB0aGlzKTsKLQotICAgICAgICBpZiAoZGF0ZTEudXRjID09ICdaJykgewotCi0gICAgICAgICAgICAvL2NvbXBhcmUgZGF0ZTE8PWRhdGUxPD0oZGF0ZTIgd2l0aCB0aW1lIHpvbmUgLTE0KQotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIGNsb25lRGF0ZShkYXRlMiwgdGVtcERhdGUpOyAvL2Nsb25lcyBkYXRlMSB2YWx1ZSB0byBnbG9iYWwgdGVtcG9yYXJ5IHN0b3JhZ2U6IGZUZW1wRGF0ZQotICAgICAgICAgICAgdGVtcERhdGUudGltZXpvbmVIciA9IDE0OwotICAgICAgICAgICAgdGVtcERhdGUudGltZXpvbmVNaW4gPSAwOwotICAgICAgICAgICAgdGVtcERhdGUudXRjID0gJysnOwotICAgICAgICAgICAgbm9ybWFsaXplKHRlbXBEYXRlKTsKLSAgICAgICAgICAgIGMxID0gY29tcGFyZU9yZGVyKGRhdGUxLCB0ZW1wRGF0ZSk7Ci0gICAgICAgICAgICBpZiAoYzEgPT0gTEVTU19USEFOKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGMxOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvL2NvbXBhcmUgZGF0ZTE+PShkYXRlMiB3aXRoIHRpbWUgem9uZSArMTQpCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgY2xvbmVEYXRlKGRhdGUyLCB0ZW1wRGF0ZSk7IC8vY2xvbmVzIGRhdGUxIHZhbHVlIHRvIGdsb2JhbCB0ZW1wb3Jhcnkgc3RvcmFnZTogdGVtcERhdGUKLSAgICAgICAgICAgIHRlbXBEYXRlLnRpbWV6b25lSHIgPSAtMTQ7Ci0gICAgICAgICAgICB0ZW1wRGF0ZS50aW1lem9uZU1pbiA9IDA7Ci0gICAgICAgICAgICB0ZW1wRGF0ZS51dGMgPSAnLSc7Ci0gICAgICAgICAgICBub3JtYWxpemUodGVtcERhdGUpOwotICAgICAgICAgICAgYzIgPSBjb21wYXJlT3JkZXIoZGF0ZTEsIHRlbXBEYXRlKTsKLSAgICAgICAgICAgIGlmIChjMiA9PSBHUkVBVEVSX1RIQU4pIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gYzI7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIHJldHVybiBJTkRFVEVSTUlOQVRFOwotICAgICAgICB9IGVsc2UgaWYgKGRhdGUyLnV0YyA9PSAnWicpIHsKLQotICAgICAgICAgICAgLy9jb21wYXJlIChkYXRlMSB3aXRoIHRpbWUgem9uZSAtMTQpPD1kYXRlMgotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIGNsb25lRGF0ZShkYXRlMSwgdGVtcERhdGUpOyAvL2Nsb25lcyBkYXRlMSB2YWx1ZSB0byBnbG9iYWwgdGVtcG9yYXJ5IHN0b3JhZ2U6IHRlbXBEYXRlCi0gICAgICAgICAgICB0ZW1wRGF0ZS50aW1lem9uZUhyID0gLTE0OwotICAgICAgICAgICAgdGVtcERhdGUudGltZXpvbmVNaW4gPSAwOwotICAgICAgICAgICAgdGVtcERhdGUudXRjID0gJy0nOwotICAgICAgICAgICAgaWYgKERFQlVHKSB7Ci0gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJ0ZW1wRGF0ZT0iICsgZGF0ZVRvU3RyaW5nKHRlbXBEYXRlKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBub3JtYWxpemUodGVtcERhdGUpOwotICAgICAgICAgICAgYzEgPSBjb21wYXJlT3JkZXIodGVtcERhdGUsIGRhdGUyKTsKLSAgICAgICAgICAgIGlmIChERUJVRykgewotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiZGF0ZT0iICsgZGF0ZVRvU3RyaW5nKGRhdGUyKSk7Ci0gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJ0ZW1wRGF0ZT0iICsgZGF0ZVRvU3RyaW5nKHRlbXBEYXRlKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoYzEgPT0gTEVTU19USEFOKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGMxOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvL2NvbXBhcmUgKGRhdGUxIHdpdGggdGltZSB6b25lICsxNCk8PWRhdGUyCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgY2xvbmVEYXRlKGRhdGUxLCB0ZW1wRGF0ZSk7IC8vY2xvbmVzIGRhdGUxIHZhbHVlIHRvIGdsb2JhbCB0ZW1wb3Jhcnkgc3RvcmFnZTogdGVtcERhdGUKLSAgICAgICAgICAgIHRlbXBEYXRlLnRpbWV6b25lSHIgPSAxNDsKLSAgICAgICAgICAgIHRlbXBEYXRlLnRpbWV6b25lTWluID0gMDsKLSAgICAgICAgICAgIHRlbXBEYXRlLnV0YyA9ICcrJzsKLSAgICAgICAgICAgIG5vcm1hbGl6ZSh0ZW1wRGF0ZSk7Ci0gICAgICAgICAgICBjMiA9IGNvbXBhcmVPcmRlcih0ZW1wRGF0ZSwgZGF0ZTIpOwotICAgICAgICAgICAgaWYgKERFQlVHKSB7Ci0gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJ0ZW1wRGF0ZT0iICsgZGF0ZVRvU3RyaW5nKHRlbXBEYXRlKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoYzIgPT0gR1JFQVRFUl9USEFOKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGMyOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICByZXR1cm4gSU5ERVRFUk1JTkFURTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gSU5ERVRFUk1JTkFURTsKLQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdpdmVuIG5vcm1hbGl6ZWQgdmFsdWVzLCBkZXRlcm1pbmVzIG9yZGVyLXJlbGF0aW9uIGJldHdlZW4gZ2l2ZSBkYXRlL3RpbWUKLSAgICAgKiBvYmplY3RzLgotICAgICAqCi0gICAgICogQHBhcmFtIGRhdGUxIGRhdGUvdGltZSBvYmplY3QKLSAgICAgKiBAcGFyYW0gZGF0ZTIgZGF0ZS90aW1lIG9iamVjdAotICAgICAqIEByZXR1cm4gMCBpZiBkYXRlMSBhbmQgZGF0ZTIgYXJlIGVxdWFsLCBhIHZhbHVlIGxlc3MgdGhhbiAwIGlmIGRhdGUxIGlzCi0gICAgICogbGVzcyB0aGFuIGRhdGUyLCBhIHZhbHVlIGdyZWF0ZXIgdGhhbiAwIGlmIGRhdGUxIGlzIGdyZWF0ZXIgdGhhbiBkYXRlMgotICAgICAqLwotICAgIHByb3RlY3RlZCBzaG9ydCBjb21wYXJlT3JkZXIoRGF0ZVRpbWVEYXRhIGRhdGUxLCBEYXRlVGltZURhdGEgZGF0ZTIpIHsKLSAgICAgICAgaWYgKGRhdGUxLnBvc2l0aW9uIDwgMSkgewotICAgICAgICAgICAgaWYgKGRhdGUxLnllYXIgPCBkYXRlMi55ZWFyKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIC0xOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKGRhdGUxLnllYXIgPiBkYXRlMi55ZWFyKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIDE7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGRhdGUxLnBvc2l0aW9uIDwgMikgewotICAgICAgICAgICAgaWYgKGRhdGUxLm1vbnRoIDwgZGF0ZTIubW9udGgpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gLTE7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoZGF0ZTEubW9udGggPiBkYXRlMi5tb250aCkgewotICAgICAgICAgICAgICAgIHJldHVybiAxOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGlmIChkYXRlMS5kYXkgPCBkYXRlMi5kYXkpIHsKLSAgICAgICAgICAgIHJldHVybiAtMTsKLSAgICAgICAgfQotICAgICAgICBpZiAoZGF0ZTEuZGF5ID4gZGF0ZTIuZGF5KSB7Ci0gICAgICAgICAgICByZXR1cm4gMTsKLSAgICAgICAgfQotICAgICAgICBpZiAoZGF0ZTEuaG91ciA8IGRhdGUyLmhvdXIpIHsKLSAgICAgICAgICAgIHJldHVybiAtMTsKLSAgICAgICAgfQotICAgICAgICBpZiAoZGF0ZTEuaG91ciA+IGRhdGUyLmhvdXIpIHsKLSAgICAgICAgICAgIHJldHVybiAxOwotICAgICAgICB9Ci0gICAgICAgIGlmIChkYXRlMS5taW51dGUgPCBkYXRlMi5taW51dGUpIHsKLSAgICAgICAgICAgIHJldHVybiAtMTsKLSAgICAgICAgfQotICAgICAgICBpZiAoZGF0ZTEubWludXRlID4gZGF0ZTIubWludXRlKSB7Ci0gICAgICAgICAgICByZXR1cm4gMTsKLSAgICAgICAgfQotICAgICAgICBpZiAoZGF0ZTEuc2Vjb25kIDwgZGF0ZTIuc2Vjb25kKSB7Ci0gICAgICAgICAgICByZXR1cm4gLTE7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGRhdGUxLnNlY29uZCA+IGRhdGUyLnNlY29uZCkgewotICAgICAgICAgICAgcmV0dXJuIDE7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGRhdGUxLnV0YyA8IGRhdGUyLnV0YykgewotICAgICAgICAgICAgcmV0dXJuIC0xOwotICAgICAgICB9Ci0gICAgICAgIGlmIChkYXRlMS51dGMgPiBkYXRlMi51dGMpIHsKLSAgICAgICAgICAgIHJldHVybiAxOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiAwOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFBhcnNlcyB0aW1lIGhoOm1tOnNzLnNzcyBhbmQgdGltZSB6b25lIGlmIGFueQotICAgICAqCi0gICAgICogQHBhcmFtIHN0YXJ0Ci0gICAgICogQHBhcmFtIGVuZAotICAgICAqIEBwYXJhbSBkYXRhCi0gICAgICogQGV4Y2VwdGlvbiBSdW50aW1lRXhjZXB0aW9uCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgZ2V0VGltZShTdHJpbmcgYnVmZmVyLCBpbnQgc3RhcnQsIGludCBlbmQsIERhdGVUaW1lRGF0YSBkYXRhKSB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgaW50IHN0b3AgPSBzdGFydCArIDI7Ci0KLSAgICAgICAgLy9nZXQgaG91cnMgKGhoKQotICAgICAgICBkYXRhLmhvdXIgPSBwYXJzZUludChidWZmZXIsIHN0YXJ0LCBzdG9wKTsKLQotICAgICAgICAvL2dldCBtaW51dGVzIChtbSkKLQotICAgICAgICBpZiAoYnVmZmVyLmNoYXJBdChzdG9wKyspICE9ICc6JykgewotICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIkVycm9yIGluIHBhcnNpbmcgdGltZSB6b25lIik7Ci0gICAgICAgIH0KLSAgICAgICAgc3RhcnQgPSBzdG9wOwotICAgICAgICBzdG9wID0gc3RvcCArIDI7Ci0gICAgICAgIGRhdGEubWludXRlID0gcGFyc2VJbnQoYnVmZmVyLCBzdGFydCwgc3RvcCk7Ci0KLSAgICAgICAgLy9nZXQgc2Vjb25kcyAoc3MpCi0gICAgICAgIGlmIChidWZmZXIuY2hhckF0KHN0b3ArKykgIT0gJzonKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiRXJyb3IgaW4gcGFyc2luZyB0aW1lIHpvbmUiKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vZmluZCBVVEMgc2lnbiBpZiBhbnkKLSAgICAgICAgaW50IHNpZ24gPSBmaW5kVVRDU2lnbihidWZmZXIsIHN0YXJ0LCBlbmQpOwotCi0gICAgICAgIC8vZ2V0IHNlY29uZHMgKG1zKQotICAgICAgICBzdGFydCA9IHN0b3A7Ci0gICAgICAgIHN0b3AgPSBzaWduIDwgMCA/IGVuZCA6IHNpZ247Ci0gICAgICAgIGRhdGEuc2Vjb25kID0gcGFyc2VTZWNvbmQoYnVmZmVyLCBzdGFydCwgc3RvcCk7Ci0KLSAgICAgICAgLy9wYXJzZSBVVEMgdGltZSB6b25lIChoaDptbSkKLSAgICAgICAgaWYgKHNpZ24gPiAwKSB7Ci0gICAgICAgICAgICBnZXRUaW1lWm9uZShidWZmZXIsIGRhdGEsIHNpZ24sIGVuZCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBQYXJzZXMgZGF0ZSBDQ1lZLU1NLURECi0gICAgICoKLSAgICAgKiBAcGFyYW0gYnVmZmVyCi0gICAgICogQHBhcmFtIHN0YXJ0IHN0YXJ0IHBvc2l0aW9uCi0gICAgICogQHBhcmFtIGVuZCBlbmQgcG9zaXRpb24KLSAgICAgKiBAcGFyYW0gZGF0ZQotICAgICAqIEBleGNlcHRpb24gUnVudGltZUV4Y2VwdGlvbgotICAgICAqLwotICAgIHByb3RlY3RlZCBpbnQgZ2V0RGF0ZShTdHJpbmcgYnVmZmVyLCBpbnQgc3RhcnQsIGludCBlbmQsIERhdGVUaW1lRGF0YSBkYXRlKSB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgc3RhcnQgPSBnZXRZZWFyTW9udGgoYnVmZmVyLCBzdGFydCwgZW5kLCBkYXRlKTsKLQotICAgICAgICBpZiAoYnVmZmVyLmNoYXJBdChzdGFydCsrKSAhPSAnLScpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJDQ1lZLU1NIG11c3QgYmUgZm9sbG93ZWQgYnkgJy0nIHNpZ24iKTsKLSAgICAgICAgfQotICAgICAgICBpbnQgc3RvcCA9IHN0YXJ0ICsgMjsKLSAgICAgICAgZGF0ZS5kYXkgPSBwYXJzZUludChidWZmZXIsIHN0YXJ0LCBzdG9wKTsKLSAgICAgICAgcmV0dXJuIHN0b3A7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUGFyc2VzIGRhdGUgQ0NZWS1NTQotICAgICAqCi0gICAgICogQHBhcmFtIGJ1ZmZlcgotICAgICAqIEBwYXJhbSBzdGFydCBzdGFydCBwb3NpdGlvbgotICAgICAqIEBwYXJhbSBlbmQgZW5kIHBvc2l0aW9uCi0gICAgICogQHBhcmFtIGRhdGUKLSAgICAgKiBAZXhjZXB0aW9uIFJ1bnRpbWVFeGNlcHRpb24KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgaW50IGdldFllYXJNb250aChTdHJpbmcgYnVmZmVyLCBpbnQgc3RhcnQsIGludCBlbmQsIERhdGVUaW1lRGF0YSBkYXRlKSB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgaWYgKGJ1ZmZlci5jaGFyQXQoMCkgPT0gJy0nKSB7Ci0gICAgICAgICAgICAvLyBSRVZJU0lUOiBkYXRlIHN0YXJ0cyB3aXRoIHByZWNlZGluZyAnLScgc2lnbgotICAgICAgICAgICAgLy8gICAgICAgICAgZG8gd2UgaGF2ZSB0byBkbyBhbnl0aGluZyB3aXRoIGl0PwotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIHN0YXJ0Kys7Ci0gICAgICAgIH0KLSAgICAgICAgaW50IGkgPSBpbmRleE9mKGJ1ZmZlciwgc3RhcnQsIGVuZCwgJy0nKTsKLSAgICAgICAgaWYgKGkgPT0gLTEpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJZZWFyIHNlcGFyYXRvciBpcyBtaXNzaW5nIG9yIG1pc3BsYWNlZCIpOwotICAgICAgICB9Ci0gICAgICAgIGludCBsZW5ndGggPSBpIC0gc3RhcnQ7Ci0gICAgICAgIGlmIChsZW5ndGggPCA0KSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiWWVhciBtdXN0IGhhdmUgJ0NDWVknIGZvcm1hdCIpOwotICAgICAgICB9IGVsc2UgaWYgKGxlbmd0aCA+IDQgJiYgYnVmZmVyLmNoYXJBdChzdGFydCkgPT0gJzAnKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiTGVhZGluZyB6ZXJvcyBhcmUgcmVxdWlyZWQgaWYgdGhlIHllYXIgdmFsdWUgd291bGQgb3RoZXJ3aXNlIGhhdmUgZmV3ZXIgdGhhbiBmb3VyIGRpZ2l0czsgb3RoZXJ3aXNlIHRoZXkgYXJlIGZvcmJpZGRlbiIpOwotICAgICAgICB9Ci0gICAgICAgIGRhdGUueWVhciA9IHBhcnNlSW50WWVhcihidWZmZXIsIGkpOwotICAgICAgICBpZiAoYnVmZmVyLmNoYXJBdChpKSAhPSAnLScpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJDQ1lZIG11c3QgYmUgZm9sbG93ZWQgYnkgJy0nIHNpZ24iKTsKLSAgICAgICAgfQotICAgICAgICBzdGFydCA9ICsraTsKLSAgICAgICAgaSA9IHN0YXJ0ICsgMjsKLSAgICAgICAgZGF0ZS5tb250aCA9IHBhcnNlSW50KGJ1ZmZlciwgc3RhcnQsIGkpOwotICAgICAgICByZXR1cm4gaTsgLy9mU3RhcnQgcG9pbnRzIHJpZ2h0IGFmdGVyIHRoZSBNT05USAotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNoYXJlZCBjb2RlIGZyb20gRGF0ZSBhbmQgWWVhck1vbnRoIGRhdGF0eXBlcy4gRmluZHMgaWYgdGltZSB6b25lIHNpZ24gaXMKLSAgICAgKiBwcmVzZW50Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gZW5kCi0gICAgICogQHBhcmFtIGRhdGUKLSAgICAgKiBAZXhjZXB0aW9uIFJ1bnRpbWVFeGNlcHRpb24KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCBwYXJzZVRpbWVab25lKFN0cmluZyBidWZmZXIsIGludCBzdGFydCwgaW50IGVuZCwgRGF0ZVRpbWVEYXRhIGRhdGUpIHRocm93cyBSdW50aW1lRXhjZXB0aW9uIHsKLQotICAgICAgICAvL2ZTdGFydCBwb2ludHMgcmlnaHQgYWZ0ZXIgdGhlIGRhdGUKLQotICAgICAgICBpZiAoc3RhcnQgPCBlbmQpIHsKLSAgICAgICAgICAgIGlmICghaXNOZXh0Q2hhclVUQ1NpZ24oYnVmZmVyLCBzdGFydCwgZW5kKSkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJFcnJvciBpbiBtb250aCBwYXJzaW5nIik7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIGdldFRpbWVab25lKGJ1ZmZlciwgZGF0ZSwgc3RhcnQsIGVuZCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBQYXJzZXMgdGltZSB6b25lOiAnWicgb3IgeyssLX0gZm9sbG93ZWQgYnkgaGg6bW0KLSAgICAgKgotICAgICAqIEBwYXJhbSBkYXRhCi0gICAgICogQHBhcmFtIHNpZ24KLSAgICAgKiBAZXhjZXB0aW9uIFJ1bnRpbWVFeGNlcHRpb24KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCBnZXRUaW1lWm9uZShTdHJpbmcgYnVmZmVyLCBEYXRlVGltZURhdGEgZGF0YSwgaW50IHNpZ24sIGludCBlbmQpIHRocm93cyBSdW50aW1lRXhjZXB0aW9uIHsKLSAgICAgICAgZGF0YS51dGMgPSBidWZmZXIuY2hhckF0KHNpZ24pOwotCi0gICAgICAgIGlmIChidWZmZXIuY2hhckF0KHNpZ24pID09ICdaJykgewotICAgICAgICAgICAgaWYgKGVuZCA+ICgrK3NpZ24pKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIkVycm9yIGluIHBhcnNpbmcgdGltZSB6b25lIik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKHNpZ24gPD0gKGVuZCAtIDYpKSB7Ci0KLSAgICAgICAgICAgIGludCBuZWdhdGUgPSBidWZmZXIuY2hhckF0KHNpZ24pID09ICctJyA/IC0xIDogMTsKLSAgICAgICAgICAgIC8vcGFyc2UgaHIKLSAgICAgICAgICAgIGludCBzdG9wID0gKytzaWduICsgMjsKLSAgICAgICAgICAgIGRhdGEudGltZXpvbmVIciA9IG5lZ2F0ZSAqIHBhcnNlSW50KGJ1ZmZlciwgc2lnbiwgc3RvcCk7Ci0gICAgICAgICAgICBpZiAoYnVmZmVyLmNoYXJBdChzdG9wKyspICE9ICc6JykgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJFcnJvciBpbiBwYXJzaW5nIHRpbWUgem9uZSIpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvL3BhcnNlIG1pbgotICAgICAgICAgICAgZGF0YS50aW1lem9uZU1pbiA9IG5lZ2F0ZSAqIHBhcnNlSW50KGJ1ZmZlciwgc3RvcCwgc3RvcCArIDIpOwotCi0gICAgICAgICAgICBpZiAoc3RvcCArIDIgIT0gZW5kKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIkVycm9yIGluIHBhcnNpbmcgdGltZSB6b25lIik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoZGF0YS50aW1lem9uZUhyICE9IDAgfHwgZGF0YS50aW1lem9uZU1pbiAhPSAwKSB7Ci0gICAgICAgICAgICAgICAgZGF0YS5ub3JtYWxpemVkID0gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiRXJyb3IgaW4gcGFyc2luZyB0aW1lIHpvbmUiKTsKLSAgICAgICAgfQotICAgICAgICBpZiAoREVCVUcpIHsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigidGltZVtoaF09IiArIGRhdGEudGltZXpvbmVIciArICIgdGltZVttbV09IiArIGRhdGEudGltZXpvbmVNaW4pOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29tcHV0ZXMgaW5kZXggb2YgZ2l2ZW4gY2hhciB3aXRoaW4gU3RyaW5nQnVmZmVyCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc3RhcnQKLSAgICAgKiBAcGFyYW0gZW5kCi0gICAgICogQHBhcmFtIGNoIGNoYXJhY3RlciB0byBsb29rIGZvciBpbiBTdHJpbmdCdWZmZXIKLSAgICAgKiBAcmV0dXJuIGluZGV4IG9mIGNoIHdpdGhpbiBTdHJpbmdCdWZmZXIKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgaW50IGluZGV4T2YoU3RyaW5nIGJ1ZmZlciwgaW50IHN0YXJ0LCBpbnQgZW5kLCBjaGFyIGNoKSB7Ci0gICAgICAgIGZvciAoaW50IGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7Ci0gICAgICAgICAgICBpZiAoYnVmZmVyLmNoYXJBdChpKSA9PSBjaCkgewotICAgICAgICAgICAgICAgIHJldHVybiBpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiAtMTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBWYWxpZGF0ZXMgZ2l2ZW4gZGF0ZS90aW1lIG9iamVjdCBhY2NvcmluZyB0byBXM0MgUFIgU2NoZW1hIFtELjEgSVNPIDg2MDEKLSAgICAgKiBDb252ZW50aW9uc10KLSAgICAgKgotICAgICAqIEBwYXJhbSBkYXRhCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgdmFsaWRhdGVEYXRlVGltZShEYXRlVGltZURhdGEgZGF0YSkgewotCi0gICAgICAgIC8vUkVWSVNJVDogc2hvdWxkIHdlIHRocm93IGFuIGV4Y2VwdGlvbiBmb3Igbm90IHZhbGlkIGRhdGVzCi0gICAgICAgIC8vICAgICAgICAgIG9yIHJlcG9ydGluZyBhbiBlcnJvciBtZXNzYWdlIHNob3VsZCBiZSBzdWZmaWNpZW50PwotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBYTUwgU2NoZW1hIDEuMSAtIFJRLTEyMzogQWxsb3cgeWVhciAwMDAwIGluIGRhdGUgcmVsYXRlZCB0eXBlcy4KLSAgICAgICAgICovCi0gICAgICAgIGlmICghQ29uc3RhbnRzLlNDSEVNQV8xXzFfU1VQUE9SVCAmJiBkYXRhLnllYXIgPT0gMCkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlRoZSB5ZWFyIFwiMDAwMFwiIGlzIGFuIGlsbGVnYWwgeWVhciB2YWx1ZSIpOwotCi0gICAgICAgIH0KLQotICAgICAgICBpZiAoZGF0YS5tb250aCA8IDEgfHwgZGF0YS5tb250aCA+IDEyKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVGhlIG1vbnRoIG11c3QgaGF2ZSB2YWx1ZXMgMSB0byAxMiIpOwotCi0gICAgICAgIH0KLQotICAgICAgICAvL3ZhbGlkYXRlIGRheXMKLSAgICAgICAgaWYgKGRhdGEuZGF5ID4gbWF4RGF5SW5Nb250aEZvcihkYXRhLnllYXIsIGRhdGEubW9udGgpIHx8IGRhdGEuZGF5IDwgMSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlRoZSBkYXkgbXVzdCBoYXZlIHZhbHVlcyAxIHRvIDMxIik7Ci0gICAgICAgIH0KLQotICAgICAgICAvL3ZhbGlkYXRlIGhvdXJzCi0gICAgICAgIGlmIChkYXRhLmhvdXIgPiAyMyB8fCBkYXRhLmhvdXIgPCAwKSB7Ci0gICAgICAgICAgICBpZiAoZGF0YS5ob3VyID09IDI0ICYmIGRhdGEubWludXRlID09IDAgJiYgZGF0YS5zZWNvbmQgPT0gMCkgewotICAgICAgICAgICAgICAgIGRhdGEuaG91ciA9IDA7Ci0gICAgICAgICAgICAgICAgaWYgKCsrZGF0YS5kYXkgPiBtYXhEYXlJbk1vbnRoRm9yKGRhdGEueWVhciwgZGF0YS5tb250aCkpIHsKLSAgICAgICAgICAgICAgICAgICAgZGF0YS5kYXkgPSAxOwotICAgICAgICAgICAgICAgICAgICBpZiAoKytkYXRhLm1vbnRoID4gMTIpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEubW9udGggPSAxOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKENvbnN0YW50cy5TQ0hFTUFfMV8xX1NVUFBPUlQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICArK2RhdGEueWVhcjsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoKytkYXRhLnllYXIgPT0gMCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEueWVhciA9IDE7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJIb3VyIG11c3QgaGF2ZSB2YWx1ZXMgMC0yMywgdW5sZXNzIDI0OjAwOjAwIik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvL3ZhbGlkYXRlCi0gICAgICAgIGlmIChkYXRhLm1pbnV0ZSA+IDU5IHx8IGRhdGEubWludXRlIDwgMCkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIk1pbnV0ZSBtdXN0IGhhdmUgdmFsdWVzIDAtNTkiKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vdmFsaWRhdGUKLSAgICAgICAgaWYgKGRhdGEuc2Vjb25kID49IDYwIHx8IGRhdGEuc2Vjb25kIDwgMCkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlNlY29uZCBtdXN0IGhhdmUgdmFsdWVzIDAtNTkiKTsKLQotICAgICAgICB9Ci0KLSAgICAgICAgLy92YWxpZGF0ZQotICAgICAgICBpZiAoZGF0YS50aW1lem9uZUhyID4gMTQgfHwgZGF0YS50aW1lem9uZUhyIDwgLTE0KSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVGltZSB6b25lIHNob3VsZCBoYXZlIHJhbmdlIC0xNDowMCB0byArMTQ6MDAiKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIGlmICgoZGF0YS50aW1lem9uZUhyID09IDE0IHx8IGRhdGEudGltZXpvbmVIciA9PSAtMTQpICYmIGRhdGEudGltZXpvbmVNaW4gIT0gMCkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJUaW1lIHpvbmUgc2hvdWxkIGhhdmUgcmFuZ2UgLTE0OjAwIHRvICsxNDowMCIpOwotICAgICAgICAgICAgfSBlbHNlIGlmIChkYXRhLnRpbWV6b25lTWluID4gNTkgfHwgZGF0YS50aW1lem9uZU1pbiA8IC01OSkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJNaW51dGUgbXVzdCBoYXZlIHZhbHVlcyAwLTU5Iik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybiBpbmRleCBvZiBVVEMgY2hhcjogJ1onLCAnKycsICctJwotICAgICAqCi0gICAgICogQHBhcmFtIHN0YXJ0Ci0gICAgICogQHBhcmFtIGVuZAotICAgICAqIEByZXR1cm4gaW5kZXggb2YgdGhlIFVUQyBjaGFyYWN0ZXIgdGhhdCB3YXMgZm91bmQKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgaW50IGZpbmRVVENTaWduKFN0cmluZyBidWZmZXIsIGludCBzdGFydCwgaW50IGVuZCkgewotICAgICAgICBpbnQgYzsKLSAgICAgICAgZm9yIChpbnQgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpKyspIHsKLSAgICAgICAgICAgIGMgPSBidWZmZXIuY2hhckF0KGkpOwotICAgICAgICAgICAgaWYgKGMgPT0gJ1onIHx8IGMgPT0gJysnIHx8IGMgPT0gJy0nKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gLTE7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucwotICAgICAqIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBjaGFyYWN0ZXIgYXQgc3RhcnQgaXMgJ1onLCAnKycgb3IgJy0nLgotICAgICAqLwotICAgIHByb3RlY3RlZCBmaW5hbCBib29sZWFuIGlzTmV4dENoYXJVVENTaWduKFN0cmluZyBidWZmZXIsIGludCBzdGFydCwgaW50IGVuZCkgewotICAgICAgICBpZiAoc3RhcnQgPCBlbmQpIHsKLSAgICAgICAgICAgIGNoYXIgYyA9IGJ1ZmZlci5jaGFyQXQoc3RhcnQpOwotICAgICAgICAgICAgcmV0dXJuIChjID09ICdaJyB8fCBjID09ICcrJyB8fCBjID09ICctJyk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdpdmVuIHN0YXJ0IGFuZCBlbmQgcG9zaXRpb24sIHBhcnNlcyBzdHJpbmcgdmFsdWUKLSAgICAgKgotICAgICAqIEBwYXJhbSBidWZmZXIgc3RyaW5nIHRvIHBhcnNlCi0gICAgICogQHBhcmFtIHN0YXJ0IHN0YXJ0IHBvc2l0aW9uCi0gICAgICogQHBhcmFtIGVuZCBlbmQgcG9zaXRpb24KLSAgICAgKiBAcmV0dXJuIHJldHVybiBpbnRlZ2VyIHJlcHJlc2VudGF0aW9uIG9mIGNoYXJhY3RlcnMKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgaW50IHBhcnNlSW50KFN0cmluZyBidWZmZXIsIGludCBzdGFydCwgaW50IGVuZCkKLSAgICAgICAgICAgIHRocm93cyBOdW1iZXJGb3JtYXRFeGNlcHRpb24gewotICAgICAgICAvL1JFVklTSVQ6IG1vcmUgdGVzdGluZyBvbiB0aGlzIHBhcnNpbmcgbmVlZHMgdG8gYmUgZG9uZS4KLSAgICAgICAgaW50IHJhZGl4ID0gMTA7Ci0gICAgICAgIGludCByZXN1bHQgPSAwOwotICAgICAgICBpbnQgZGlnaXQgPSAwOwotICAgICAgICBpbnQgbGltaXQgPSAtSW50ZWdlci5NQVhfVkFMVUU7Ci0gICAgICAgIGludCBtdWx0bWluID0gbGltaXQgLyByYWRpeDsKLSAgICAgICAgaW50IGkgPSBzdGFydDsKLSAgICAgICAgZG8gewotICAgICAgICAgICAgZGlnaXQgPSBnZXREaWdpdChidWZmZXIuY2hhckF0KGkpKTsKLSAgICAgICAgICAgIGlmIChkaWdpdCA8IDApIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVtYmVyRm9ybWF0RXhjZXB0aW9uKCInIiArIGJ1ZmZlciArICInIGhhcyB3cm9uZyBmb3JtYXQiKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChyZXN1bHQgPCBtdWx0bWluKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bWJlckZvcm1hdEV4Y2VwdGlvbigiJyIgKyBidWZmZXIgKyAiJyBoYXMgd3JvbmcgZm9ybWF0Iik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXN1bHQgKj0gcmFkaXg7Ci0gICAgICAgICAgICBpZiAocmVzdWx0IDwgbGltaXQgKyBkaWdpdCkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBOdW1iZXJGb3JtYXRFeGNlcHRpb24oIiciICsgYnVmZmVyICsgIicgaGFzIHdyb25nIGZvcm1hdCIpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmVzdWx0IC09IGRpZ2l0OwotCi0gICAgICAgIH0gd2hpbGUgKCsraSA8IGVuZCk7Ci0gICAgICAgIHJldHVybiAtcmVzdWx0OwotICAgIH0KLQotICAgIC8vIHBhcnNlIFllYXIgZGlmZmVyZW50bHkgdG8gc3VwcG9ydCBuZWdhdGl2ZSB2YWx1ZS4KLSAgICBwcm90ZWN0ZWQgaW50IHBhcnNlSW50WWVhcihTdHJpbmcgYnVmZmVyLCBpbnQgZW5kKSB7Ci0gICAgICAgIGludCByYWRpeCA9IDEwOwotICAgICAgICBpbnQgcmVzdWx0ID0gMDsKLSAgICAgICAgYm9vbGVhbiBuZWdhdGl2ZSA9IGZhbHNlOwotICAgICAgICBpbnQgaSA9IDA7Ci0gICAgICAgIGludCBsaW1pdDsKLSAgICAgICAgaW50IG11bHRtaW47Ci0gICAgICAgIGludCBkaWdpdCA9IDA7Ci0KLSAgICAgICAgaWYgKGJ1ZmZlci5jaGFyQXQoMCkgPT0gJy0nKSB7Ci0gICAgICAgICAgICBuZWdhdGl2ZSA9IHRydWU7Ci0gICAgICAgICAgICBsaW1pdCA9IEludGVnZXIuTUlOX1ZBTFVFOwotICAgICAgICAgICAgaSsrOwotCi0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBsaW1pdCA9IC1JbnRlZ2VyLk1BWF9WQUxVRTsKLSAgICAgICAgfQotICAgICAgICBtdWx0bWluID0gbGltaXQgLyByYWRpeDsKLSAgICAgICAgd2hpbGUgKGkgPCBlbmQpIHsKLSAgICAgICAgICAgIGRpZ2l0ID0gZ2V0RGlnaXQoYnVmZmVyLmNoYXJBdChpKyspKTsKLSAgICAgICAgICAgIGlmIChkaWdpdCA8IDApIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVtYmVyRm9ybWF0RXhjZXB0aW9uKCInIiArIGJ1ZmZlciArICInIGhhcyB3cm9uZyBmb3JtYXQiKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChyZXN1bHQgPCBtdWx0bWluKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bWJlckZvcm1hdEV4Y2VwdGlvbigiJyIgKyBidWZmZXIgKyAiJyBoYXMgd3JvbmcgZm9ybWF0Iik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXN1bHQgKj0gcmFkaXg7Ci0gICAgICAgICAgICBpZiAocmVzdWx0IDwgbGltaXQgKyBkaWdpdCkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBOdW1iZXJGb3JtYXRFeGNlcHRpb24oIiciICsgYnVmZmVyICsgIicgaGFzIHdyb25nIGZvcm1hdCIpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmVzdWx0IC09IGRpZ2l0OwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKG5lZ2F0aXZlKSB7Ci0gICAgICAgICAgICBpZiAoaSA+IDEpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0OwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVtYmVyRm9ybWF0RXhjZXB0aW9uKCInIiArIGJ1ZmZlciArICInIGhhcyB3cm9uZyBmb3JtYXQiKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gLXJlc3VsdDsKLQotICAgIH0KLQotICAgIC8qKgotICAgICAqIElmIHRpbWV6b25lIHByZXNlbnQgLSBub3JtYWxpemUgZGF0ZVRpbWUgW0UgQWRkaW5nIGR1cmF0aW9ucyB0bwotICAgICAqIGRhdGVUaW1lc10KLSAgICAgKgotICAgICAqIEBwYXJhbSBkYXRlIENDWVktTU0tRERUaGg6bW06c3MrMDMKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCBub3JtYWxpemUoRGF0ZVRpbWVEYXRhIGRhdGUpIHsKLQotICAgICAgICAvLyBSRVZJU0lUOiB3ZSBoYXZlIGNvbW1vbiBjb2RlIGluIGFkZER1cmF0aW9uKCkgZm9yIGR1cmF0aW9ucwotICAgICAgICAvLyAgICAgICAgICBzaG91bGQgY29uc2lkZXIgcmVvcmdhbml6aW5nIGl0LgotICAgICAgICAvLwotCi0gICAgICAgIC8vYWRkIG1pbnV0ZXMgKGZyb20gdGltZSB6b25lKQotICAgICAgICBpbnQgbmVnYXRlID0gLTE7Ci0KLSAgICAgICAgaWYgKERFQlVHKSB7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIj09PmRhdGUubWludXRlIiArIGRhdGUubWludXRlKTsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiPT0+ZGF0ZS50aW1lem9uZU1pbiIgKyBkYXRlLnRpbWV6b25lTWluKTsKLSAgICAgICAgfQotICAgICAgICBpbnQgdGVtcCA9IGRhdGUubWludXRlICsgbmVnYXRlICogZGF0ZS50aW1lem9uZU1pbjsKLSAgICAgICAgaW50IGNhcnJ5ID0gZlF1b3RpZW50KHRlbXAsIDYwKTsKLSAgICAgICAgZGF0ZS5taW51dGUgPSBtb2QodGVtcCwgNjAsIGNhcnJ5KTsKLQotICAgICAgICBpZiAoREVCVUcpIHsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiPT0+Y2Fycnk6ICIgKyBjYXJyeSk7Ci0gICAgICAgIH0KLSAgICAgICAgLy9hZGQgaG91cnMKLSAgICAgICAgdGVtcCA9IGRhdGUuaG91ciArIG5lZ2F0ZSAqIGRhdGUudGltZXpvbmVIciArIGNhcnJ5OwotICAgICAgICBjYXJyeSA9IGZRdW90aWVudCh0ZW1wLCAyNCk7Ci0gICAgICAgIGRhdGUuaG91ciA9IG1vZCh0ZW1wLCAyNCwgY2FycnkpOwotICAgICAgICBpZiAoREVCVUcpIHsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiPT0+ZGF0ZS5ob3VyIiArIGRhdGUuaG91cik7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIj09PmNhcnJ5OiAiICsgY2FycnkpOwotICAgICAgICB9Ci0KLSAgICAgICAgZGF0ZS5kYXkgPSBkYXRlLmRheSArIGNhcnJ5OwotCi0gICAgICAgIHdoaWxlICh0cnVlKSB7Ci0gICAgICAgICAgICB0ZW1wID0gbWF4RGF5SW5Nb250aEZvcihkYXRlLnllYXIsIGRhdGUubW9udGgpOwotICAgICAgICAgICAgaWYgKGRhdGUuZGF5IDwgMSkgewotICAgICAgICAgICAgICAgIGRhdGUuZGF5ID0gZGF0ZS5kYXkgKyBtYXhEYXlJbk1vbnRoRm9yKGRhdGUueWVhciwgZGF0ZS5tb250aCAtIDEpOwotICAgICAgICAgICAgICAgIGNhcnJ5ID0gLTE7Ci0gICAgICAgICAgICB9IGVsc2UgaWYgKGRhdGUuZGF5ID4gdGVtcCkgewotICAgICAgICAgICAgICAgIGRhdGUuZGF5ID0gZGF0ZS5kYXkgLSB0ZW1wOwotICAgICAgICAgICAgICAgIGNhcnJ5ID0gMTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICB0ZW1wID0gZGF0ZS5tb250aCArIGNhcnJ5OwotICAgICAgICAgICAgZGF0ZS5tb250aCA9IG1vZHVsbyh0ZW1wLCAxLCAxMyk7Ci0gICAgICAgICAgICBkYXRlLnllYXIgPSBkYXRlLnllYXIgKyBmUXVvdGllbnQodGVtcCwgMSwgMTMpOwotICAgICAgICAgICAgaWYgKGRhdGUueWVhciA9PSAwICYmICFDb25zdGFudHMuU0NIRU1BXzFfMV9TVVBQT1JUKSB7Ci0gICAgICAgICAgICAgICAgZGF0ZS55ZWFyID0gKGRhdGUudGltZXpvbmVIciA8IDAgfHwgZGF0ZS50aW1lem9uZU1pbiA8IDApID8gMSA6IC0xOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGRhdGUudXRjID0gJ1onOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBwYXJhbSBkYXRlCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgc2F2ZVVubm9ybWFsaXplZChEYXRlVGltZURhdGEgZGF0ZSkgewotICAgICAgICBkYXRlLnVuTm9ybVllYXIgPSBkYXRlLnllYXI7Ci0gICAgICAgIGRhdGUudW5Ob3JtTW9udGggPSBkYXRlLm1vbnRoOwotICAgICAgICBkYXRlLnVuTm9ybURheSA9IGRhdGUuZGF5OwotICAgICAgICBkYXRlLnVuTm9ybUhvdXIgPSBkYXRlLmhvdXI7Ci0gICAgICAgIGRhdGUudW5Ob3JtTWludXRlID0gZGF0ZS5taW51dGU7Ci0gICAgICAgIGRhdGUudW5Ob3JtU2Vjb25kID0gZGF0ZS5zZWNvbmQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmVzZXRzIG9iamVjdCByZXByZXNlbnRhdGlvbiBvZiBkYXRlL3RpbWUKLSAgICAgKgotICAgICAqIEBwYXJhbSBkYXRhIGRhdGUvdGltZSBvYmplY3QKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCByZXNldERhdGVPYmooRGF0ZVRpbWVEYXRhIGRhdGEpIHsKLSAgICAgICAgZGF0YS55ZWFyID0gMDsKLSAgICAgICAgZGF0YS5tb250aCA9IDA7Ci0gICAgICAgIGRhdGEuZGF5ID0gMDsKLSAgICAgICAgZGF0YS5ob3VyID0gMDsKLSAgICAgICAgZGF0YS5taW51dGUgPSAwOwotICAgICAgICBkYXRhLnNlY29uZCA9IDA7Ci0gICAgICAgIGRhdGEudXRjID0gMDsKLSAgICAgICAgZGF0YS50aW1lem9uZUhyID0gMDsKLSAgICAgICAgZGF0YS50aW1lem9uZU1pbiA9IDA7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2l2ZW4ge3llYXIsbW9udGh9IGNvbXB1dGVzIG1heGltdW0gbnVtYmVyIG9mIGRheXMgZm9yIGdpdmVuIG1vbnRoCi0gICAgICoKLSAgICAgKiBAcGFyYW0geWVhcgotICAgICAqIEBwYXJhbSBtb250aAotICAgICAqIEByZXR1cm4gaW50ZWdlciBjb250YWluZyB0aGUgbnVtYmVyIG9mIGRheXMgaW4gYSBnaXZlbiBtb250aAotICAgICAqLwotICAgIHByb3RlY3RlZCBpbnQgbWF4RGF5SW5Nb250aEZvcihpbnQgeWVhciwgaW50IG1vbnRoKSB7Ci0gICAgICAgIC8vdmFsaWRhdGUgZGF5cwotICAgICAgICBpZiAobW9udGggPT0gNCB8fCBtb250aCA9PSA2IHx8IG1vbnRoID09IDkgfHwgbW9udGggPT0gMTEpIHsKLSAgICAgICAgICAgIHJldHVybiAzMDsKLSAgICAgICAgfSBlbHNlIGlmIChtb250aCA9PSAyKSB7Ci0gICAgICAgICAgICBpZiAoaXNMZWFwWWVhcih5ZWFyKSkgewotICAgICAgICAgICAgICAgIHJldHVybiAyOTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIDI4OwotICAgICAgICAgICAgfQotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIDMxOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBib29sZWFuIGlzTGVhcFllYXIoaW50IHllYXIpIHsKLQotICAgICAgICAvL1JFVklTSVQ6IHNob3VsZCB3ZSB0YWtlIGNhcmUgYWJvdXQgSnVsaWFuIGNhbGVuZGFyPwotICAgICAgICByZXR1cm4gKCh5ZWFyICUgNCA9PSAwKSAmJiAoKHllYXIgJSAxMDAgIT0gMCkgfHwgKHllYXIgJSA0MDAgPT0gMCkpKTsKLSAgICB9Ci0KLSAgICAvLwotICAgIC8vIGhlbHAgZnVuY3Rpb24gZGVzY3JpYmVkIGluIFczQyBQUiBTY2hlbWEgW0UgQWRkaW5nIGR1cmF0aW9ucyB0byBkYXRlVGltZXNdCi0gICAgLy8KLSAgICBwcm90ZWN0ZWQgaW50IG1vZChpbnQgYSwgaW50IGIsIGludCBxdW90aWVudCkgewotICAgICAgICAvL21vZHVsbyhhLCBiKSA9IGEgLSBmUXVvdGllbnQoYSxiKSpiCi0gICAgICAgIHJldHVybiAoYSAtIHF1b3RpZW50ICogYik7Ci0gICAgfQotCi0gICAgLy8KLSAgICAvLyBoZWxwIGZ1bmN0aW9uIGRlc2NyaWJlZCBpbiBXM0MgUFIgU2NoZW1hIFtFIEFkZGluZyBkdXJhdGlvbnMgdG8gZGF0ZVRpbWVzXQotICAgIC8vCi0gICAgcHJvdGVjdGVkIGludCBmUXVvdGllbnQoaW50IGEsIGludCBiKSB7Ci0KLSAgICAgICAgLy9mUXVvdGllbnQoYSwgYikgPSB0aGUgZ3JlYXRlc3QgaW50ZWdlciBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gYS9iCi0gICAgICAgIHJldHVybiAoaW50KSBNYXRoLmZsb29yKChmbG9hdCkgYSAvIGIpOwotICAgIH0KLQotICAgIC8vCi0gICAgLy8gaGVscCBmdW5jdGlvbiBkZXNjcmliZWQgaW4gVzNDIFBSIFNjaGVtYSBbRSBBZGRpbmcgZHVyYXRpb25zIHRvIGRhdGVUaW1lc10KLSAgICAvLwotICAgIHByb3RlY3RlZCBpbnQgbW9kdWxvKGludCB0ZW1wLCBpbnQgbG93LCBpbnQgaGlnaCkgewotICAgICAgICAvL21vZHVsbyhhIC0gbG93LCBoaWdoIC0gbG93KSArIGxvdwotICAgICAgICBpbnQgYSA9IHRlbXAgLSBsb3c7Ci0gICAgICAgIGludCBiID0gaGlnaCAtIGxvdzsKLSAgICAgICAgcmV0dXJuIChtb2QoYSwgYiwgZlF1b3RpZW50KGEsIGIpKSArIGxvdyk7Ci0gICAgfQotCi0gICAgLy8KLSAgICAvLyBoZWxwIGZ1bmN0aW9uIGRlc2NyaWJlZCBpbiBXM0MgUFIgU2NoZW1hIFtFIEFkZGluZyBkdXJhdGlvbnMgdG8gZGF0ZVRpbWVzXQotICAgIC8vCi0gICAgcHJvdGVjdGVkIGludCBmUXVvdGllbnQoaW50IHRlbXAsIGludCBsb3csIGludCBoaWdoKSB7Ci0gICAgICAgIC8vZlF1b3RpZW50KGEgLSBsb3csIGhpZ2ggLSBsb3cpCi0KLSAgICAgICAgcmV0dXJuIGZRdW90aWVudCh0ZW1wIC0gbG93LCBoaWdoIC0gbG93KTsKLSAgICB9Ci0KLSAgICBwcm90ZWN0ZWQgU3RyaW5nIGRhdGVUb1N0cmluZyhEYXRlVGltZURhdGEgZGF0ZSkgewotICAgICAgICBTdHJpbmdCdWZmZXIgbWVzc2FnZSA9IG5ldyBTdHJpbmdCdWZmZXIoMjUpOwotICAgICAgICBhcHBlbmQobWVzc2FnZSwgZGF0ZS55ZWFyLCA0KTsKLSAgICAgICAgbWVzc2FnZS5hcHBlbmQoJy0nKTsKLSAgICAgICAgYXBwZW5kKG1lc3NhZ2UsIGRhdGUubW9udGgsIDIpOwotICAgICAgICBtZXNzYWdlLmFwcGVuZCgnLScpOwotICAgICAgICBhcHBlbmQobWVzc2FnZSwgZGF0ZS5kYXksIDIpOwotICAgICAgICBtZXNzYWdlLmFwcGVuZCgnVCcpOwotICAgICAgICBhcHBlbmQobWVzc2FnZSwgZGF0ZS5ob3VyLCAyKTsKLSAgICAgICAgbWVzc2FnZS5hcHBlbmQoJzonKTsKLSAgICAgICAgYXBwZW5kKG1lc3NhZ2UsIGRhdGUubWludXRlLCAyKTsKLSAgICAgICAgbWVzc2FnZS5hcHBlbmQoJzonKTsKLSAgICAgICAgYXBwZW5kKG1lc3NhZ2UsIGRhdGUuc2Vjb25kKTsKLSAgICAgICAgYXBwZW5kKG1lc3NhZ2UsIChjaGFyKSBkYXRlLnV0YywgMCk7Ci0gICAgICAgIHJldHVybiBtZXNzYWdlLnRvU3RyaW5nKCk7Ci0gICAgfQotCi0gICAgcHJvdGVjdGVkIGZpbmFsIHZvaWQgYXBwZW5kKFN0cmluZ0J1ZmZlciBtZXNzYWdlLCBpbnQgdmFsdWUsIGludCBuY2gpIHsKLSAgICAgICAgaWYgKHZhbHVlID09IEludGVnZXIuTUlOX1ZBTFVFKSB7Ci0gICAgICAgICAgICBtZXNzYWdlLmFwcGVuZCh2YWx1ZSk7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKHZhbHVlIDwgMCkgewotICAgICAgICAgICAgbWVzc2FnZS5hcHBlbmQoJy0nKTsKLSAgICAgICAgICAgIHZhbHVlID0gLXZhbHVlOwotICAgICAgICB9Ci0gICAgICAgIGlmIChuY2ggPT0gNCkgewotICAgICAgICAgICAgaWYgKHZhbHVlIDwgMTApIHsKLSAgICAgICAgICAgICAgICBtZXNzYWdlLmFwcGVuZCgiMDAwIik7Ci0gICAgICAgICAgICB9IGVsc2UgaWYgKHZhbHVlIDwgMTAwKSB7Ci0gICAgICAgICAgICAgICAgbWVzc2FnZS5hcHBlbmQoIjAwIik7Ci0gICAgICAgICAgICB9IGVsc2UgaWYgKHZhbHVlIDwgMTAwMCkgewotICAgICAgICAgICAgICAgIG1lc3NhZ2UuYXBwZW5kKCcwJyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBtZXNzYWdlLmFwcGVuZCh2YWx1ZSk7Ci0gICAgICAgIH0gZWxzZSBpZiAobmNoID09IDIpIHsKLSAgICAgICAgICAgIGlmICh2YWx1ZSA8IDEwKSB7Ci0gICAgICAgICAgICAgICAgbWVzc2FnZS5hcHBlbmQoJzAnKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIG1lc3NhZ2UuYXBwZW5kKHZhbHVlKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIGlmICh2YWx1ZSAhPSAwKSB7Ci0gICAgICAgICAgICAgICAgbWVzc2FnZS5hcHBlbmQoKGNoYXIpIHZhbHVlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIHByb3RlY3RlZCBmaW5hbCB2b2lkIGFwcGVuZChTdHJpbmdCdWZmZXIgbWVzc2FnZSwgZG91YmxlIHZhbHVlKSB7Ci0gICAgICAgIGlmICh2YWx1ZSA8IDApIHsKLSAgICAgICAgICAgIG1lc3NhZ2UuYXBwZW5kKCctJyk7Ci0gICAgICAgICAgICB2YWx1ZSA9IC12YWx1ZTsKLSAgICAgICAgfQotICAgICAgICBpZiAodmFsdWUgPCAxMCkgewotICAgICAgICAgICAgbWVzc2FnZS5hcHBlbmQoJzAnKTsKLSAgICAgICAgfQotICAgICAgICBhcHBlbmQyKG1lc3NhZ2UsIHZhbHVlKTsKLSAgICB9Ci0KLSAgICBwcm90ZWN0ZWQgZmluYWwgdm9pZCBhcHBlbmQyKFN0cmluZ0J1ZmZlciBtZXNzYWdlLCBkb3VibGUgdmFsdWUpIHsKLSAgICAgICAgZmluYWwgaW50IGludFZhbHVlID0gKGludCkgdmFsdWU7Ci0gICAgICAgIGlmICh2YWx1ZSA9PSBpbnRWYWx1ZSkgewotICAgICAgICAgICAgbWVzc2FnZS5hcHBlbmQoaW50VmFsdWUpOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgYXBwZW5kMyhtZXNzYWdlLCB2YWx1ZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgYXBwZW5kMyhTdHJpbmdCdWZmZXIgbWVzc2FnZSwgZG91YmxlIHZhbHVlKSB7Ci0gICAgICAgIFN0cmluZyBkID0gU3RyaW5nLnZhbHVlT2YodmFsdWUpOwotICAgICAgICBpbnQgZUluZGV4ID0gZC5pbmRleE9mKCdFJyk7Ci0gICAgICAgIGlmIChlSW5kZXggPT0gLTEpIHsKLSAgICAgICAgICAgIG1lc3NhZ2UuYXBwZW5kKGQpOwotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0gICAgICAgIGludCBleHA7Ci0gICAgICAgIGlmICh2YWx1ZSA8IDEpIHsKLSAgICAgICAgICAgIC8vIE5lZWQgdG8gY29udmVydCBmcm9tIHNjaWVudGlmaWMgbm90YXRpb24gb2YgdGhlIGZvcm0KLSAgICAgICAgICAgIC8vIG4ubm5uLi4uRS1OIChOID49IDQpIHRvIGEgbm9ybWFsIGRlY2ltYWwgdmFsdWUuCi0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIGV4cCA9IHBhcnNlSW50KGQsIGVJbmRleCArIDIsIGQubGVuZ3RoKCkpOwotICAgICAgICAgICAgfSAvLyBUaGlzIHNob3VsZCBuZXZlciBoYXBwZW4uCi0gICAgICAgICAgICAvLyBJdCdzIG9ubHkgcG9zc2libGUgaWYgU3RyaW5nLnZhbHVlT2YoZG91YmxlKSBpcyBicm9rZW4uCi0gICAgICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICBtZXNzYWdlLmFwcGVuZChkKTsKLSAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBtZXNzYWdlLmFwcGVuZCgiMC4iKTsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAxOyBpIDwgZXhwOyArK2kpIHsKLSAgICAgICAgICAgICAgICBtZXNzYWdlLmFwcGVuZCgnMCcpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gUmVtb3ZlIHRyYWlsaW5nIHplcm9zLgotICAgICAgICAgICAgaW50IGVuZCA9IGVJbmRleCAtIDE7Ci0gICAgICAgICAgICB3aGlsZSAoZW5kID4gMCkgewotICAgICAgICAgICAgICAgIGNoYXIgYyA9IGQuY2hhckF0KGVuZCk7Ci0gICAgICAgICAgICAgICAgaWYgKGMgIT0gJzAnKSB7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAtLWVuZDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIE5vdyBhcHBlbmQgdGhlIGRpZ2l0cyB0byB0aGUgZW5kLiBTa2lwIG92ZXIgdGhlIGRlY2ltYWwgcG9pbnQuCi0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8PSBlbmQ7ICsraSkgewotICAgICAgICAgICAgICAgIGNoYXIgYyA9IGQuY2hhckF0KGkpOwotICAgICAgICAgICAgICAgIGlmIChjICE9ICcuJykgewotICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmFwcGVuZChjKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAvLyBOZWVkIHRvIGNvbnZlcnQgZnJvbSBzY2llbnRpZmljIG5vdGF0aW9uIG9mIHRoZSBmb3JtCi0gICAgICAgICAgICAvLyBuLm5ubi4uLkVOIChOID49IDcpIHRvIGEgbm9ybWFsIGRlY2ltYWwgdmFsdWUuCi0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIGV4cCA9IHBhcnNlSW50KGQsIGVJbmRleCArIDEsIGQubGVuZ3RoKCkpOwotICAgICAgICAgICAgfSAvLyBUaGlzIHNob3VsZCBuZXZlciBoYXBwZW4uCi0gICAgICAgICAgICAvLyBJdCdzIG9ubHkgcG9zc2libGUgaWYgU3RyaW5nLnZhbHVlT2YoZG91YmxlKSBpcyBicm9rZW4uCi0gICAgICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICBtZXNzYWdlLmFwcGVuZChkKTsKLSAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmaW5hbCBpbnQgaW50ZWdlckVuZCA9IGV4cCArIDI7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGVJbmRleDsgKytpKSB7Ci0gICAgICAgICAgICAgICAgY2hhciBjID0gZC5jaGFyQXQoaSk7Ci0gICAgICAgICAgICAgICAgaWYgKGMgIT0gJy4nKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChpID09IGludGVnZXJFbmQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuYXBwZW5kKCcuJyk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5hcHBlbmQoYyk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gQXBwZW5kIHRyYWlsaW5nIHplcm9lcyBpZiBuZWNlc3NhcnkuCi0gICAgICAgICAgICBmb3IgKGludCBpID0gaW50ZWdlckVuZCAtIGVJbmRleDsgaSA+IDA7IC0taSkgewotICAgICAgICAgICAgICAgIG1lc3NhZ2UuYXBwZW5kKCcwJyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwcm90ZWN0ZWQgZG91YmxlIHBhcnNlU2Vjb25kKFN0cmluZyBidWZmZXIsIGludCBzdGFydCwgaW50IGVuZCkKLSAgICAgICAgICAgIHRocm93cyBOdW1iZXJGb3JtYXRFeGNlcHRpb24gewotICAgICAgICBpbnQgZG90ID0gLTE7Ci0gICAgICAgIGZvciAoaW50IGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7Ci0gICAgICAgICAgICBjaGFyIGNoID0gYnVmZmVyLmNoYXJBdChpKTsKLSAgICAgICAgICAgIGlmIChjaCA9PSAnLicpIHsKLSAgICAgICAgICAgICAgICBkb3QgPSBpOwotICAgICAgICAgICAgfSBlbHNlIGlmIChjaCA+ICc5JyB8fCBjaCA8ICcwJykgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBOdW1iZXJGb3JtYXRFeGNlcHRpb24oIiciICsgYnVmZmVyICsgIicgaGFzIHdyb25nIGZvcm1hdCIpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGlmIChkb3QgPT0gLTEpIHsKLSAgICAgICAgICAgIGlmIChzdGFydCArIDIgIT0gZW5kKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bWJlckZvcm1hdEV4Y2VwdGlvbigiJyIgKyBidWZmZXIgKyAiJyBoYXMgd3JvbmcgZm9ybWF0Iik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gZWxzZSBpZiAoc3RhcnQgKyAyICE9IGRvdCB8fCBkb3QgKyAxID09IGVuZCkgewotICAgICAgICAgICAgdGhyb3cgbmV3IE51bWJlckZvcm1hdEV4Y2VwdGlvbigiJyIgKyBidWZmZXIgKyAiJyBoYXMgd3JvbmcgZm9ybWF0Iik7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIERvdWJsZS5wYXJzZURvdWJsZShidWZmZXIuc3Vic3RyaW5nKHN0YXJ0LCBlbmQpKTsKLSAgICB9Ci0KLSAgICAvLwotICAgIC8vUHJpdmF0ZSBoZWxwIGZ1bmN0aW9ucwotICAgIC8vCi0gICAgcHJpdmF0ZSB2b2lkIGNsb25lRGF0ZShEYXRlVGltZURhdGEgZmluYWxWYWx1ZSwgRGF0ZVRpbWVEYXRhIHRlbXBEYXRlKSB7Ci0gICAgICAgIHRlbXBEYXRlLnllYXIgPSBmaW5hbFZhbHVlLnllYXI7Ci0gICAgICAgIHRlbXBEYXRlLm1vbnRoID0gZmluYWxWYWx1ZS5tb250aDsKLSAgICAgICAgdGVtcERhdGUuZGF5ID0gZmluYWxWYWx1ZS5kYXk7Ci0gICAgICAgIHRlbXBEYXRlLmhvdXIgPSBmaW5hbFZhbHVlLmhvdXI7Ci0gICAgICAgIHRlbXBEYXRlLm1pbnV0ZSA9IGZpbmFsVmFsdWUubWludXRlOwotICAgICAgICB0ZW1wRGF0ZS5zZWNvbmQgPSBmaW5hbFZhbHVlLnNlY29uZDsKLSAgICAgICAgdGVtcERhdGUudXRjID0gZmluYWxWYWx1ZS51dGM7Ci0gICAgICAgIHRlbXBEYXRlLnRpbWV6b25lSHIgPSBmaW5hbFZhbHVlLnRpbWV6b25lSHI7Ci0gICAgICAgIHRlbXBEYXRlLnRpbWV6b25lTWluID0gZmluYWxWYWx1ZS50aW1lem9uZU1pbjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXByZXNlbnRzIGRhdGUgdGltZSBkYXRhCi0gICAgICovCi0gICAgc3RhdGljIGZpbmFsIGNsYXNzIERhdGVUaW1lRGF0YSBpbXBsZW1lbnRzIFhTRGF0ZVRpbWUgewotCi0gICAgICAgIGludCB5ZWFyLCBtb250aCwgZGF5LCBob3VyLCBtaW51dGUsIHV0YzsKLSAgICAgICAgZG91YmxlIHNlY29uZDsKLSAgICAgICAgaW50IHRpbWV6b25lSHIsIHRpbWV6b25lTWluOwotICAgICAgICBwcml2YXRlIFN0cmluZyBvcmlnaW5hbFZhbHVlOwotICAgICAgICBib29sZWFuIG5vcm1hbGl6ZWQgPSB0cnVlOwotICAgICAgICBpbnQgdW5Ob3JtWWVhcjsKLSAgICAgICAgaW50IHVuTm9ybU1vbnRoOwotICAgICAgICBpbnQgdW5Ob3JtRGF5OwotICAgICAgICBpbnQgdW5Ob3JtSG91cjsKLSAgICAgICAgaW50IHVuTm9ybU1pbnV0ZTsKLSAgICAgICAgZG91YmxlIHVuTm9ybVNlY29uZDsKLSAgICAgICAgLy8gdXNlZCBmb3IgY29tcGFyaXNvbnMgLSB0byBkZWNpZGUgdGhlICdpbnRlcmVzdGluZycgcG9ydGlvbnMgb2YKLSAgICAgICAgLy8gYSBkYXRlL3RpbWUgYmFzZWQgZGF0YSB0eXBlLgotICAgICAgICBpbnQgcG9zaXRpb247Ci0gICAgICAgIC8vIGEgcG9pbnRlciB0byB0aGUgdHlwZSB0aGF0IHdhcyB1c2VkIGdvIGdlbmVyYXRlIHRoaXMgZGF0YQotICAgICAgICAvLyBub3RlIHRoYXQgdGhpcyBpcyBub3QgdGhlIGFjdHVhbCBzaW1wbGUgdHlwZSwgYnV0IG9uZSBvZiB0aGUKLSAgICAgICAgLy8gc3RhdGljYWxseSBjcmVhdGVkIFhYWERWIG9iamVjdHMsIHNvIHRoaXMgd29uJ3QgY2F1c2UgYW55IEdDIHByb2JsZW0uCi0gICAgICAgIGZpbmFsIEFic3RyYWN0RGF0ZVRpbWVEViB0eXBlOwotICAgICAgICBwcml2YXRlIHZvbGF0aWxlIFN0cmluZyBjYW5vbmljYWw7Ci0KLSAgICAgICAgcHVibGljIERhdGVUaW1lRGF0YShTdHJpbmcgb3JpZ2luYWxWYWx1ZSwgQWJzdHJhY3REYXRlVGltZURWIHR5cGUpIHsKLSAgICAgICAgICAgIHRoaXMub3JpZ2luYWxWYWx1ZSA9IG9yaWdpbmFsVmFsdWU7Ci0gICAgICAgICAgICB0aGlzLnR5cGUgPSB0eXBlOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIERhdGVUaW1lRGF0YShpbnQgeWVhciwgaW50IG1vbnRoLCBpbnQgZGF5LCBpbnQgaG91ciwgaW50IG1pbnV0ZSwKLSAgICAgICAgICAgICAgICBkb3VibGUgc2Vjb25kLCBpbnQgdXRjLCBTdHJpbmcgb3JpZ2luYWxWYWx1ZSwgYm9vbGVhbiBub3JtYWxpemVkLCBBYnN0cmFjdERhdGVUaW1lRFYgdHlwZSkgewotICAgICAgICAgICAgdGhpcy55ZWFyID0geWVhcjsKLSAgICAgICAgICAgIHRoaXMubW9udGggPSBtb250aDsKLSAgICAgICAgICAgIHRoaXMuZGF5ID0gZGF5OwotICAgICAgICAgICAgdGhpcy5ob3VyID0gaG91cjsKLSAgICAgICAgICAgIHRoaXMubWludXRlID0gbWludXRlOwotICAgICAgICAgICAgdGhpcy5zZWNvbmQgPSBzZWNvbmQ7Ci0gICAgICAgICAgICB0aGlzLnV0YyA9IHV0YzsKLSAgICAgICAgICAgIHRoaXMudHlwZSA9IHR5cGU7Ci0gICAgICAgICAgICB0aGlzLm9yaWdpbmFsVmFsdWUgPSBvcmlnaW5hbFZhbHVlOwotICAgICAgICB9Ci0KLSAgICAgICAgQE92ZXJyaWRlCi0gICAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqKSB7Ci0gICAgICAgICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBEYXRlVGltZURhdGEpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIHR5cGUuY29tcGFyZURhdGVzKHRoaXMsIChEYXRlVGltZURhdGEpIG9iaiwgdHJ1ZSkgPT0gMDsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIElmIHR3byBEYXRlVGltZURhdGEgYXJlIGVxdWFscyAtIHRoZW4gdGhleSBzaG91bGQgaGF2ZSB0aGUgc2FtZQotICAgICAgICAvLyBoYXNoY29kZS4gVGhpcyBtZWFucyB3ZSBuZWVkIHRvIGNvbnZlcnQgdGhlIGRhdGUgdG8gVVRDIGJlZm9yZQotICAgICAgICAvLyB3ZSByZXR1cm4gaXRzIGhhc2hjb2RlLgotICAgICAgICAvLyBUaGUgRGF0ZVRpbWVEYXRhIGlzIHVuZm9ydHVuYXRlbHkgbXV0YWJsZSAtIHNvIHdlIGNhbm5vdAotICAgICAgICAvLyBjYWNoZSB0aGUgcmVzdWx0IG9mIHRoZSBjb252ZXJzaW9uLi4uCi0gICAgICAgIC8vCi0gICAgICAgIEBPdmVycmlkZQotICAgICAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewotICAgICAgICAgICAgZmluYWwgRGF0ZVRpbWVEYXRhIHRlbXBEYXRlID0gbmV3IERhdGVUaW1lRGF0YShudWxsLCB0eXBlKTsKLSAgICAgICAgICAgIHR5cGUuY2xvbmVEYXRlKHRoaXMsIHRlbXBEYXRlKTsKLSAgICAgICAgICAgIHR5cGUubm9ybWFsaXplKHRlbXBEYXRlKTsKLSAgICAgICAgICAgIHJldHVybiB0eXBlLmRhdGVUb1N0cmluZyh0ZW1wRGF0ZSkuaGFzaENvZGUoKTsKLSAgICAgICAgfQotCi0gICAgICAgIEBPdmVycmlkZQotICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgICAgICAgICAgaWYgKGNhbm9uaWNhbCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgY2Fub25pY2FsID0gdHlwZS5kYXRlVG9TdHJpbmcodGhpcyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gY2Fub25pY2FsOwotICAgICAgICB9Ci0gICAgICAgIC8qIChub24tSmF2YWRvYykKLSAgICAgICAgICogQHNlZSBvcmcuYXBhY2hlLnhlcmNlcy54cy5kYXRhdHlwZXMuWFNEYXRlVGltZSNnZXRZZWFyKCkKLSAgICAgICAgICovCi0KLSAgICAgICAgQE92ZXJyaWRlCi0gICAgICAgIHB1YmxpYyBpbnQgZ2V0WWVhcnMoKSB7Ci0gICAgICAgICAgICBpZiAodHlwZSBpbnN0YW5jZW9mIER1cmF0aW9uRFYpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gMDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiBub3JtYWxpemVkID8geWVhciA6IHVuTm9ybVllYXI7Ci0gICAgICAgIH0KLSAgICAgICAgLyogKG5vbi1KYXZhZG9jKQotICAgICAgICAgKiBAc2VlIG9yZy5hcGFjaGUueGVyY2VzLnhzLmRhdGF0eXBlcy5YU0RhdGVUaW1lI2dldE1vbnRoKCkKLSAgICAgICAgICovCi0KLSAgICAgICAgQE92ZXJyaWRlCi0gICAgICAgIHB1YmxpYyBpbnQgZ2V0TW9udGhzKCkgewotICAgICAgICAgICAgaWYgKHR5cGUgaW5zdGFuY2VvZiBEdXJhdGlvbkRWKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHllYXIgKiAxMiArIG1vbnRoOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIG5vcm1hbGl6ZWQgPyBtb250aCA6IHVuTm9ybU1vbnRoOwotICAgICAgICB9Ci0gICAgICAgIC8qIChub24tSmF2YWRvYykKLSAgICAgICAgICogQHNlZSBvcmcuYXBhY2hlLnhlcmNlcy54cy5kYXRhdHlwZXMuWFNEYXRlVGltZSNnZXREYXkoKQotICAgICAgICAgKi8KLQotICAgICAgICBAT3ZlcnJpZGUKLSAgICAgICAgcHVibGljIGludCBnZXREYXlzKCkgewotICAgICAgICAgICAgaWYgKHR5cGUgaW5zdGFuY2VvZiBEdXJhdGlvbkRWKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIDA7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gbm9ybWFsaXplZCA/IGRheSA6IHVuTm9ybURheTsKLSAgICAgICAgfQotICAgICAgICAvKiAobm9uLUphdmFkb2MpCi0gICAgICAgICAqIEBzZWUgb3JnLmFwYWNoZS54ZXJjZXMueHMuZGF0YXR5cGVzLlhTRGF0ZVRpbWUjZ2V0SG91cigpCi0gICAgICAgICAqLwotCi0gICAgICAgIEBPdmVycmlkZQotICAgICAgICBwdWJsaWMgaW50IGdldEhvdXJzKCkgewotICAgICAgICAgICAgaWYgKHR5cGUgaW5zdGFuY2VvZiBEdXJhdGlvbkRWKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIDA7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gbm9ybWFsaXplZCA/IGhvdXIgOiB1bk5vcm1Ib3VyOwotICAgICAgICB9Ci0gICAgICAgIC8qIChub24tSmF2YWRvYykKLSAgICAgICAgICogQHNlZSBvcmcuYXBhY2hlLnhlcmNlcy54cy5kYXRhdHlwZXMuWFNEYXRlVGltZSNnZXRNaW51dGVzKCkKLSAgICAgICAgICovCi0KLSAgICAgICAgQE92ZXJyaWRlCi0gICAgICAgIHB1YmxpYyBpbnQgZ2V0TWludXRlcygpIHsKLSAgICAgICAgICAgIGlmICh0eXBlIGluc3RhbmNlb2YgRHVyYXRpb25EVikgewotICAgICAgICAgICAgICAgIHJldHVybiAwOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIG5vcm1hbGl6ZWQgPyBtaW51dGUgOiB1bk5vcm1NaW51dGU7Ci0gICAgICAgIH0KLSAgICAgICAgLyogKG5vbi1KYXZhZG9jKQotICAgICAgICAgKiBAc2VlIG9yZy5hcGFjaGUueGVyY2VzLnhzLmRhdGF0eXBlcy5YU0RhdGVUaW1lI2dldFNlY29uZHMoKQotICAgICAgICAgKi8KLQotICAgICAgICBAT3ZlcnJpZGUKLSAgICAgICAgcHVibGljIGRvdWJsZSBnZXRTZWNvbmRzKCkgewotICAgICAgICAgICAgaWYgKHR5cGUgaW5zdGFuY2VvZiBEdXJhdGlvbkRWKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGRheSAqIDI0ICogNjAgKiA2MCArIGhvdXIgKiA2MCAqIDYwICsgbWludXRlICogNjAgKyBzZWNvbmQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gbm9ybWFsaXplZCA/IHNlY29uZCA6IHVuTm9ybVNlY29uZDsKLSAgICAgICAgfQotICAgICAgICAvKiAobm9uLUphdmFkb2MpCi0gICAgICAgICAqIEBzZWUgb3JnLmFwYWNoZS54ZXJjZXMueHMuZGF0YXR5cGVzLlhTRGF0ZVRpbWUjaGFzVGltZVpvbmUoKQotICAgICAgICAgKi8KLQotICAgICAgICBAT3ZlcnJpZGUKLSAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzVGltZVpvbmUoKSB7Ci0gICAgICAgICAgICByZXR1cm4gdXRjICE9IDA7Ci0gICAgICAgIH0KLSAgICAgICAgLyogKG5vbi1KYXZhZG9jKQotICAgICAgICAgKiBAc2VlIG9yZy5hcGFjaGUueGVyY2VzLnhzLmRhdGF0eXBlcy5YU0RhdGVUaW1lI2dldFRpbWVab25lSG91cnMoKQotICAgICAgICAgKi8KLQotICAgICAgICBAT3ZlcnJpZGUKLSAgICAgICAgcHVibGljIGludCBnZXRUaW1lWm9uZUhvdXJzKCkgewotICAgICAgICAgICAgcmV0dXJuIHRpbWV6b25lSHI7Ci0gICAgICAgIH0KLSAgICAgICAgLyogKG5vbi1KYXZhZG9jKQotICAgICAgICAgKiBAc2VlIG9yZy5hcGFjaGUueGVyY2VzLnhzLmRhdGF0eXBlcy5YU0RhdGVUaW1lI2dldFRpbWVab25lTWludXRlcygpCi0gICAgICAgICAqLwotCi0gICAgICAgIEBPdmVycmlkZQotICAgICAgICBwdWJsaWMgaW50IGdldFRpbWVab25lTWludXRlcygpIHsKLSAgICAgICAgICAgIHJldHVybiB0aW1lem9uZU1pbjsKLSAgICAgICAgfQotICAgICAgICAvKiAobm9uLUphdmFkb2MpCi0gICAgICAgICAqIEBzZWUgb3JnLmFwYWNoZS54ZXJjZXMueHMuZGF0YXR5cGVzLlhTRGF0ZVRpbWUjZ2V0TGV4aWNhbFZhbHVlKCkKLSAgICAgICAgICovCi0KLSAgICAgICAgQE92ZXJyaWRlCi0gICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0TGV4aWNhbFZhbHVlKCkgewotICAgICAgICAgICAgcmV0dXJuIG9yaWdpbmFsVmFsdWU7Ci0gICAgICAgIH0KLSAgICAgICAgLyogKG5vbi1KYXZhZG9jKQotICAgICAgICAgKiBAc2VlIG9yZy5hcGFjaGUueGVyY2VzLnhzLmRhdGF0eXBlcy5YU0RhdGVUaW1lI25vcm1hbGl6ZSgpCi0gICAgICAgICAqLwotCi0gICAgICAgIEBPdmVycmlkZQotICAgICAgICBwdWJsaWMgWFNEYXRlVGltZSBub3JtYWxpemUoKSB7Ci0gICAgICAgICAgICBpZiAoIW5vcm1hbGl6ZWQpIHsKLSAgICAgICAgICAgICAgICBEYXRlVGltZURhdGEgZHQgPSAoRGF0ZVRpbWVEYXRhKSB0aGlzLmNsb25lKCk7Ci0gICAgICAgICAgICAgICAgZHQubm9ybWFsaXplZCA9IHRydWU7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGR0OwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIHRoaXM7Ci0gICAgICAgIH0KLSAgICAgICAgLyogKG5vbi1KYXZhZG9jKQotICAgICAgICAgKiBAc2VlIG9yZy5hcGFjaGUueGVyY2VzLnhzLmRhdGF0eXBlcy5YU0RhdGVUaW1lI2lzTm9ybWFsaXplZCgpCi0gICAgICAgICAqLwotCi0gICAgICAgIEBPdmVycmlkZQotICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc05vcm1hbGl6ZWQoKSB7Ci0gICAgICAgICAgICByZXR1cm4gbm9ybWFsaXplZDsKLSAgICAgICAgfQotCi0gICAgICAgIEBPdmVycmlkZQotICAgICAgICBwdWJsaWMgT2JqZWN0IGNsb25lKCkgewotICAgICAgICAgICAgRGF0ZVRpbWVEYXRhIGR0ID0gbmV3IERhdGVUaW1lRGF0YSh0aGlzLnllYXIsIHRoaXMubW9udGgsIHRoaXMuZGF5LCB0aGlzLmhvdXIsCi0gICAgICAgICAgICAgICAgICAgIHRoaXMubWludXRlLCB0aGlzLnNlY29uZCwgdGhpcy51dGMsIHRoaXMub3JpZ2luYWxWYWx1ZSwgdGhpcy5ub3JtYWxpemVkLCB0aGlzLnR5cGUpOwotICAgICAgICAgICAgZHQuY2Fub25pY2FsID0gdGhpcy5jYW5vbmljYWw7Ci0gICAgICAgICAgICBkdC5wb3NpdGlvbiA9IHBvc2l0aW9uOwotICAgICAgICAgICAgZHQudGltZXpvbmVIciA9IHRoaXMudGltZXpvbmVIcjsKLSAgICAgICAgICAgIGR0LnRpbWV6b25lTWluID0gdGhpcy50aW1lem9uZU1pbjsKLSAgICAgICAgICAgIGR0LnVuTm9ybVllYXIgPSB0aGlzLnVuTm9ybVllYXI7Ci0gICAgICAgICAgICBkdC51bk5vcm1Nb250aCA9IHRoaXMudW5Ob3JtTW9udGg7Ci0gICAgICAgICAgICBkdC51bk5vcm1EYXkgPSB0aGlzLnVuTm9ybURheTsKLSAgICAgICAgICAgIGR0LnVuTm9ybUhvdXIgPSB0aGlzLnVuTm9ybUhvdXI7Ci0gICAgICAgICAgICBkdC51bk5vcm1NaW51dGUgPSB0aGlzLnVuTm9ybU1pbnV0ZTsKLSAgICAgICAgICAgIGR0LnVuTm9ybVNlY29uZCA9IHRoaXMudW5Ob3JtU2Vjb25kOwotICAgICAgICAgICAgcmV0dXJuIGR0OwotICAgICAgICB9Ci0KLSAgICAgICAgLyogKG5vbi1KYXZhZG9jKQotICAgICAgICAgKiBAc2VlIG9yZy5hcGFjaGUueGVyY2VzLnhzLmRhdGF0eXBlcy5YU0RhdGVUaW1lI2dldFhNTEdyZWdvcmlhbkNhbGVuZGFyKCkKLSAgICAgICAgICovCi0gICAgICAgIEBPdmVycmlkZQotICAgICAgICBwdWJsaWMgWE1MR3JlZ29yaWFuQ2FsZW5kYXIgZ2V0WE1MR3JlZ29yaWFuQ2FsZW5kYXIoKSB7Ci0gICAgICAgICAgICByZXR1cm4gdHlwZS5nZXRYTUxHcmVnb3JpYW5DYWxlbmRhcih0aGlzKTsKLSAgICAgICAgfQotICAgICAgICAvKiAobm9uLUphdmFkb2MpCi0gICAgICAgICAqIEBzZWUgb3JnLmFwYWNoZS54ZXJjZXMueHMuZGF0YXR5cGVzLlhTRGF0ZVRpbWUjZ2V0RHVyYXRpb24oKQotICAgICAgICAgKi8KLQotICAgICAgICBAT3ZlcnJpZGUKLSAgICAgICAgcHVibGljIER1cmF0aW9uIGdldER1cmF0aW9uKCkgewotICAgICAgICAgICAgcmV0dXJuIHR5cGUuZ2V0RHVyYXRpb24odGhpcyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwcm90ZWN0ZWQgWE1MR3JlZ29yaWFuQ2FsZW5kYXIgZ2V0WE1MR3JlZ29yaWFuQ2FsZW5kYXIoRGF0ZVRpbWVEYXRhIGRhdGEpIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgcHJvdGVjdGVkIER1cmF0aW9uIGdldER1cmF0aW9uKERhdGVUaW1lRGF0YSBkYXRhKSB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIHByb3RlY3RlZCBmaW5hbCBCaWdEZWNpbWFsIGdldEZyYWN0aW9uYWxTZWNvbmRzQXNCaWdEZWNpbWFsKERhdGVUaW1lRGF0YSBkYXRhKSB7Ci0gICAgICAgIGZpbmFsIFN0cmluZ0J1ZmZlciBidWYgPSBuZXcgU3RyaW5nQnVmZmVyKCk7Ci0gICAgICAgIGFwcGVuZDMoYnVmLCBkYXRhLnVuTm9ybVNlY29uZCk7Ci0gICAgICAgIFN0cmluZyB2YWx1ZSA9IGJ1Zi50b1N0cmluZygpOwotICAgICAgICBmaW5hbCBpbnQgaW5kZXggPSB2YWx1ZS5pbmRleE9mKCcuJyk7Ci0gICAgICAgIGlmIChpbmRleCA9PSAtMSkgewotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLSAgICAgICAgdmFsdWUgPSB2YWx1ZS5zdWJzdHJpbmcoaW5kZXgpOwotICAgICAgICBmaW5hbCBCaWdEZWNpbWFsIF92YWwgPSBuZXcgQmlnRGVjaW1hbCh2YWx1ZSk7Ci0gICAgICAgIGlmIChfdmFsLmNvbXBhcmVUbyhCaWdEZWNpbWFsLnZhbHVlT2YoMCkpID09IDApIHsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBfdmFsOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYveHMvQW55QXRvbWljRFYuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYveHMvQW55QXRvbWljRFYuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZTdkYmY5Ni4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L3hzL0FueUF0b21pY0RWLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0NCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYueHM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYuSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LlZhbGlkYXRpb25Db250ZXh0OwotCi0vKioKLSAqIFJlcHJlc2VudCB0aGUgc2NoZW1hIHR5cGUgImFueUF0b21pY1R5cGUiCi0gKgotICogQHhlcmNlcy5leHBlcmltZW50YWwKLSAqCi0gKiBAYXV0aG9yIEFua2l0IFBhc3JpY2hhLCBJQk0KLSAqCi0gKi8KLWNsYXNzIEFueUF0b21pY0RWIGV4dGVuZHMgVHlwZVZhbGlkYXRvciB7Ci0KLSAgICBwdWJsaWMgc2hvcnQgZ2V0QWxsb3dlZEZhY2V0cygpIHsKLSAgICAgICAgcmV0dXJuIDA7Ci0gICAgfQotCi0gICAgcHVibGljIE9iamVjdCBnZXRBY3R1YWxWYWx1ZShTdHJpbmcgY29udGVudCwgVmFsaWRhdGlvbkNvbnRleHQgY29udGV4dCkgdGhyb3dzIEludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uIHsKLSAgICAgICAgcmV0dXJuIGNvbnRlbnQ7Ci0gICAgfQotCi19IC8vIGNsYXNzIEFueUF0b21pY0RWCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L3hzL0FueVNpbXBsZURWLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L3hzL0FueVNpbXBsZURWLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDBhOGJmMDAuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi94cy9BbnlTaW1wbGVEVi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDYgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMSwgMjAwMiwyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYueHM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYuSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LlZhbGlkYXRpb25Db250ZXh0OwotCi0vKioKLSAqIFJlcHJlc2VudCB0aGUgc2NoZW1hIHR5cGUgImFueVNpbXBsZVR5cGUiCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgTmVlcmFqIEJhamFqLCBTdW4gTWljcm9zeXN0ZW1zLCBpbmMuCi0gKiBAYXV0aG9yIFNhbmR5IEdhbywgSUJNCi0gKgotICovCi1wdWJsaWMgY2xhc3MgQW55U2ltcGxlRFYgZXh0ZW5kcyBUeXBlVmFsaWRhdG9yIHsKLQotICAgIHB1YmxpYyBzaG9ydCBnZXRBbGxvd2VkRmFjZXRzKCkgewotICAgICAgICAvLyBhbnlTaW1wbGVUeXBlIGRvZXNuJ3QgYWxsb3cgYW55IGZhY2V0LCBub3QgZXZlbiB3aGl0ZVNwYWNlCi0gICAgICAgIHJldHVybiAwOwotICAgIH0KLQotICAgIHB1YmxpYyBPYmplY3QgZ2V0QWN0dWFsVmFsdWUoU3RyaW5nIGNvbnRlbnQsIFZhbGlkYXRpb25Db250ZXh0IGNvbnRleHQpIHRocm93cyBJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbiB7Ci0gICAgICAgIHJldHVybiBjb250ZW50OwotICAgIH0KLQotfSAvLyBjbGFzcyBBbnlTaW1wbGVEVgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi94cy9BbnlVUklEVi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi94cy9BbnlVUklEVi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzNDU4ZGFjLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYveHMvQW55VVJJRFYuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE3MSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi54czsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5JbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuVVJJOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5WYWxpZGF0aW9uQ29udGV4dDsKLQotLyoqCi0gKiBSZXByZXNlbnQgdGhlIHNjaGVtYSB0eXBlICJhbnlVUkkiCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgTmVlcmFqIEJhamFqLCBTdW4gTWljcm9zeXN0ZW1zLCBpbmMuCi0gKiBAYXV0aG9yIFNhbmR5IEdhbywgSUJNCi0gKgotICovCi1wdWJsaWMgY2xhc3MgQW55VVJJRFYgZXh0ZW5kcyBUeXBlVmFsaWRhdG9yIHsKLQotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFVSSSBCQVNFX1VSSTsKLSAgICBzdGF0aWMgewotICAgICAgICBVUkkgdXJpID0gbnVsbDsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIHVyaSA9IG5ldyBVUkkoImFiYzovL2RlZi5naGkuamtsIik7Ci0gICAgICAgIH0gY2F0Y2ggKFVSSS5NYWxmb3JtZWRVUklFeGNlcHRpb24gZXgpIHsKLSAgICAgICAgfQotICAgICAgICBCQVNFX1VSSSA9IHVyaTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgc2hvcnQgZ2V0QWxsb3dlZEZhY2V0cygpewotICAgICAgICByZXR1cm4gKFhTU2ltcGxlVHlwZURlY2wuRkFDRVRfTEVOR1RIIHwgWFNTaW1wbGVUeXBlRGVjbC5GQUNFVF9NSU5MRU5HVEggfCBYU1NpbXBsZVR5cGVEZWNsLkZBQ0VUX01BWExFTkdUSCB8IFhTU2ltcGxlVHlwZURlY2wuRkFDRVRfUEFUVEVSTiB8IFhTU2ltcGxlVHlwZURlY2wuRkFDRVRfRU5VTUVSQVRJT04gfCBYU1NpbXBsZVR5cGVEZWNsLkZBQ0VUX1dISVRFU1BBQ0UgKTsKLSAgICB9Ci0KLSAgICAvLyBiZWZvcmUgd2UgcmV0dXJuIHN0cmluZyB3ZSBoYXZlIHRvIG1ha2Ugc3VyZSBpdCBpcyBjb3JyZWN0IFVSSSBhcyBwZXIgc3BlYy4KLSAgICAvLyBmb3Igc29tZSB0eXBlcyAoc3RyaW5nIGFuZCBkZXJpdmVkKSwgdGhleSBqdXN0IHJldHVybiB0aGUgc3RyaW5nIGl0c2VsZgotICAgIHB1YmxpYyBPYmplY3QgZ2V0QWN0dWFsVmFsdWUoU3RyaW5nIGNvbnRlbnQsIFZhbGlkYXRpb25Db250ZXh0IGNvbnRleHQpIHRocm93cyBJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbiB7Ci0gICAgICAgIC8vIGNoZWNrIDMuMi4xNy5jMCBtdXN0OiBVUkkgKHJmYyAyMzk2LzI3MjMpCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBpZiggY29udGVudC5sZW5ndGgoKSAhPSAwICkgewotICAgICAgICAgICAgICAgIC8vIGVuY29kZSBzcGVjaWFsIGNoYXJhY3RlcnMgdXNpbmcgWExpbmsgNS40IGFsZ29yaXRobQotICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBlbmNvZGVkID0gZW5jb2RlKGNvbnRlbnQpOwotICAgICAgICAgICAgICAgIC8vIFN1cHBvcnQgZm9yIHJlbGF0aXZlIFVSTHMKLSAgICAgICAgICAgICAgICAvLyBBY2NvcmRpbmcgdG8gSmF2YSAxLjE6IFVSTHMgbWF5IGFsc28gYmUgc3BlY2lmaWVkIHdpdGggYQotICAgICAgICAgICAgICAgIC8vIFN0cmluZyBhbmQgdGhlIFVSTCBvYmplY3QgdGhhdCBpdCBpcyByZWxhdGVkIHRvLgotICAgICAgICAgICAgICAgIG5ldyBVUkkoQkFTRV9VUkksIGVuY29kZWQgKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSBjYXRjaCAoVVJJLk1hbGZvcm1lZFVSSUV4Y2VwdGlvbiBleCkgewotICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uKCJjdmMtZGF0YXR5cGUtdmFsaWQuMS4yLjEiLCBuZXcgT2JqZWN0W117Y29udGVudCwgImFueVVSSSJ9KTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIFJFVklTSVQ6IGRvIHdlIG5lZWQgdG8gcmV0dXJuIHRoZSBuZXcgVVJJIG9iamVjdD8KLSAgICAgICAgcmV0dXJuIGNvbnRlbnQ7Ci0gICAgfQotCi0gICAgLy8gd2hpY2ggQVNDSUkgY2hhcmFjdGVycyBuZWVkIHRvIGJlIGVzY2FwZWQKLSAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGdOZWVkRXNjYXBpbmdbXSA9IG5ldyBib29sZWFuWzEyOF07Ci0gICAgLy8gdGhlIGZpcnN0IGhleCBjaGFyYWN0ZXIgaWYgYSBjaGFyYWN0ZXIgbmVlZHMgdG8gYmUgZXNjYXBlZAotICAgIHByaXZhdGUgc3RhdGljIGNoYXIgZ0FmdGVyRXNjYXBpbmcxW10gPSBuZXcgY2hhclsxMjhdOwotICAgIC8vIHRoZSBzZWNvbmQgaGV4IGNoYXJhY3RlciBpZiBhIGNoYXJhY3RlciBuZWVkcyB0byBiZSBlc2NhcGVkCi0gICAgcHJpdmF0ZSBzdGF0aWMgY2hhciBnQWZ0ZXJFc2NhcGluZzJbXSA9IG5ldyBjaGFyWzEyOF07Ci0gICAgcHJpdmF0ZSBzdGF0aWMgY2hhcltdIGdIZXhDaHMgPSB7JzAnLCAnMScsICcyJywgJzMnLCAnNCcsICc1JywgJzYnLCAnNycsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzgnLCAnOScsICdBJywgJ0InLCAnQycsICdEJywgJ0UnLCAnRid9OwotICAgIC8vIGluaXRpYWxpemUgdGhlIGFib3ZlIDMgYXJyYXlzCi0gICAgc3RhdGljIHsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPD0gMHgxZjsgaSsrKSB7Ci0gICAgICAgICAgICBnTmVlZEVzY2FwaW5nW2ldID0gdHJ1ZTsKLSAgICAgICAgICAgIGdBZnRlckVzY2FwaW5nMVtpXSA9IGdIZXhDaHNbaSA+PiA0XTsKLSAgICAgICAgICAgIGdBZnRlckVzY2FwaW5nMltpXSA9IGdIZXhDaHNbaSAmIDB4Zl07Ci0gICAgICAgIH0KLSAgICAgICAgZ05lZWRFc2NhcGluZ1sweDdmXSA9IHRydWU7Ci0gICAgICAgIGdBZnRlckVzY2FwaW5nMVsweDdmXSA9ICc3JzsKLSAgICAgICAgZ0FmdGVyRXNjYXBpbmcyWzB4N2ZdID0gJ0YnOwotICAgICAgICBjaGFyW10gZXNjQ2hzID0geycgJywgJzwnLCAnPicsICciJywgJ3snLCAnfScsCi0gICAgICAgICAgICAgICAgICAgICAgICAgJ3wnLCAnXFwnLCAnXicsICd+JywgJ2AnfTsKLSAgICAgICAgaW50IGxlbiA9IGVzY0Nocy5sZW5ndGg7Ci0gICAgICAgIGNoYXIgY2g7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKLSAgICAgICAgICAgIGNoID0gZXNjQ2hzW2ldOwotICAgICAgICAgICAgZ05lZWRFc2NhcGluZ1tjaF0gPSB0cnVlOwotICAgICAgICAgICAgZ0FmdGVyRXNjYXBpbmcxW2NoXSA9IGdIZXhDaHNbY2ggPj4gNF07Ci0gICAgICAgICAgICBnQWZ0ZXJFc2NhcGluZzJbY2hdID0gZ0hleENoc1tjaCAmIDB4Zl07Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvLyBUbyBlbmNvZGUgc3BlY2lhbCBjaGFyYWN0ZXJzIGluIGFueVVSSSwgYnkgdXNpbmcgJUhIIHRvIHJlcHJlc2VudAotICAgIC8vIHNwZWNpYWwgQVNDSUkgY2hhcmFjdGVyczogMHgwMH4weDFGLCAweDdGLCAnICcsICc8JywgJz4nLCBldGMuCi0gICAgLy8gYW5kIG5vbi1BU0NJSSBjaGFyYWN0ZXJzICh3aG9zZSB2YWx1ZSA+PSAxMjgpLgotICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBlbmNvZGUoU3RyaW5nIGFueVVSSSl7Ci0gICAgICAgIGludCBsZW4gPSBhbnlVUkkubGVuZ3RoKCksIGNoOwotICAgICAgICBTdHJpbmdCdWZmZXIgYnVmZmVyID0gbmV3IFN0cmluZ0J1ZmZlcihsZW4qMyk7Ci0KLSAgICAgICAgLy8gZm9yIGVhY2ggY2hhcmFjdGVyIGluIHRoZSBhbnlVUkkKLSAgICAgICAgaW50IGkgPSAwOwotICAgICAgICBmb3IgKDsgaSA8IGxlbjsgaSsrKSB7Ci0gICAgICAgICAgICBjaCA9IGFueVVSSS5jaGFyQXQoaSk7Ci0gICAgICAgICAgICAvLyBpZiBpdCdzIG5vdCBhbiBBU0NJSSBjaGFyYWN0ZXIsIGJyZWFrIGhlcmUsIGFuZCB1c2UgVVRGLTggZW5jb2RpbmcKLSAgICAgICAgICAgIGlmIChjaCA+PSAxMjgpCi0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICBpZiAoZ05lZWRFc2NhcGluZ1tjaF0pIHsKLSAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCclJyk7Ci0gICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZChnQWZ0ZXJFc2NhcGluZzFbY2hdKTsKLSAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKGdBZnRlckVzY2FwaW5nMltjaF0pOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgoY2hhciljaCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyB3ZSBzYXcgc29tZSBub24tYXNjaWkgY2hhcmFjdGVyCi0gICAgICAgIGlmIChpIDwgbGVuKSB7Ci0gICAgICAgICAgICAvLyBnZXQgVVRGLTggYnl0ZXMgZm9yIHRoZSByZW1haW5pbmcgc3ViLXN0cmluZwotICAgICAgICAgICAgYnl0ZVtdIGJ5dGVzID0gbnVsbDsKLSAgICAgICAgICAgIGJ5dGUgYjsKLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgYnl0ZXMgPSBhbnlVUkkuc3Vic3RyaW5nKGkpLmdldEJ5dGVzKCJVVEYtOCIpOwotICAgICAgICAgICAgfSBjYXRjaCAoamF2YS5pby5VbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICAvLyBzaG91bGQgbmV2ZXIgaGFwcGVuCi0gICAgICAgICAgICAgICAgcmV0dXJuIGFueVVSSTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGxlbiA9IGJ5dGVzLmxlbmd0aDsKLQotICAgICAgICAgICAgLy8gZm9yIGVhY2ggYnl0ZQotICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgYiA9IGJ5dGVzW2ldOwotICAgICAgICAgICAgICAgIC8vIGZvciBub24tYXNjaWkgY2hhcmFjdGVyOiBtYWtlIGl0IHBvc2l0aXZlLCB0aGVuIGVzY2FwZQotICAgICAgICAgICAgICAgIGlmIChiIDwgMCkgewotICAgICAgICAgICAgICAgICAgICBjaCA9IGIgKyAyNTY7Ci0gICAgICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoJyUnKTsKLSAgICAgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZChnSGV4Q2hzW2NoID4+IDRdKTsKLSAgICAgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZChnSGV4Q2hzW2NoICYgMHhmXSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgaWYgKGdOZWVkRXNjYXBpbmdbYl0pIHsKLSAgICAgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgnJScpOwotICAgICAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKGdBZnRlckVzY2FwaW5nMVtiXSk7Ci0gICAgICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoZ0FmdGVyRXNjYXBpbmcyW2JdKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoKGNoYXIpYik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gSWYgZW5jb2RpbmcgaGFwcGVuZWQsIGNyZWF0ZSBhIG5ldyBzdHJpbmc7Ci0gICAgICAgIC8vIG90aGVyd2lzZSwgcmV0dXJuIHRoZSBvcmdpbmFsIG9uZS4KLSAgICAgICAgaWYgKGJ1ZmZlci5sZW5ndGgoKSAhPSBsZW4pIHsKLSAgICAgICAgICAgIHJldHVybiBidWZmZXIudG9TdHJpbmcoKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiBhbnlVUkk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLX0gLy8gY2xhc3MgQW55VVJJRFYKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYveHMvQmFzZTY0QmluYXJ5RFYuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYveHMvQmFzZTY0QmluYXJ5RFYuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZmNmYTAzOS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L3hzL0Jhc2U2NEJpbmFyeURWLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5NCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLCAyMDAyLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi54czsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5JbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYuVmFsaWRhdGlvbkNvbnRleHQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LnV0aWwuQmFzZTY0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi51dGlsLkJ5dGVMaXN0SW1wbDsKLQotLyoqCi0gKiBSZXByZXNlbnQgdGhlIHNjaGVtYSB0eXBlICJiYXNlNjRCaW5hcnkiCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgTmVlcmFqIEJhamFqLCBTdW4gTWljcm9zeXN0ZW1zLCBpbmMuCi0gKiBAYXV0aG9yIFNhbmR5IEdhbywgSUJNCi0gKgotICogQHZlcnNpb24gJElkOiBCYXNlNjRCaW5hcnlEVi5qYXZhLHYgMS43IDIwMTAtMTEtMDEgMDQ6Mzk6NDYgam9laHcgRXhwICQKLSAqLwotcHVibGljIGNsYXNzIEJhc2U2NEJpbmFyeURWIGV4dGVuZHMgVHlwZVZhbGlkYXRvciB7Ci0KLSAgICBwdWJsaWMgc2hvcnQgZ2V0QWxsb3dlZEZhY2V0cygpewotICAgICAgICByZXR1cm4gKFhTU2ltcGxlVHlwZURlY2wuRkFDRVRfTEVOR1RIIHwgWFNTaW1wbGVUeXBlRGVjbC5GQUNFVF9NSU5MRU5HVEggfCBYU1NpbXBsZVR5cGVEZWNsLkZBQ0VUX01BWExFTkdUSCB8IFhTU2ltcGxlVHlwZURlY2wuRkFDRVRfUEFUVEVSTiB8IFhTU2ltcGxlVHlwZURlY2wuRkFDRVRfRU5VTUVSQVRJT04gfCBYU1NpbXBsZVR5cGVEZWNsLkZBQ0VUX1dISVRFU1BBQ0UgKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgT2JqZWN0IGdldEFjdHVhbFZhbHVlKFN0cmluZyBjb250ZW50LCBWYWxpZGF0aW9uQ29udGV4dCBjb250ZXh0KSB0aHJvd3MgSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24gewotICAgICAgICBieXRlW10gZGVjb2RlZCA9IEJhc2U2NC5kZWNvZGUoY29udGVudCk7Ci0gICAgICAgIGlmIChkZWNvZGVkID09IG51bGwpCi0gICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24oImN2Yy1kYXRhdHlwZS12YWxpZC4xLjIuMSIsIG5ldyBPYmplY3RbXXtjb250ZW50LCAiYmFzZTY0QmluYXJ5In0pOwotCi0gICAgICAgIHJldHVybiBuZXcgWEJhc2U2NChkZWNvZGVkKTsKLSAgICB9Ci0KLSAgICAvLyBsZW5ndGggb2YgYSBiaW5hcnkgdHlwZSBpcyB0aGUgbnVtYmVyIG9mIGJ5dGVzCi0gICAgcHVibGljIGludCBnZXREYXRhTGVuZ3RoKE9iamVjdCB2YWx1ZSkgewotICAgICAgICByZXR1cm4gKChYQmFzZTY0KXZhbHVlKS5nZXRMZW5ndGgoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiByZXByZXNlbnQgYmFzZTY0IGRhdGEKLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBYQmFzZTY0IGV4dGVuZHMgQnl0ZUxpc3RJbXBsIHsKLQotICAgICAgICBwdWJsaWMgWEJhc2U2NChieXRlW10gZGF0YSkgewotICAgICAgICAgICAgc3VwZXIoZGF0YSk7Ci0gICAgICAgIH0KLSAgICAgICAgcHVibGljIHN5bmNocm9uaXplZCBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0gICAgICAgICAgICBpZiAoY2Fub25pY2FsID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBjYW5vbmljYWwgPSBCYXNlNjQuZW5jb2RlKGRhdGEpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIGNhbm9uaWNhbDsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqKSB7Ci0gICAgICAgICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBYQmFzZTY0KSkKLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICBieXRlW10gb2RhdGEgPSAoKFhCYXNlNjQpb2JqKS5kYXRhOwotICAgICAgICAgICAgaW50IGxlbiA9IGRhdGEubGVuZ3RoOwotICAgICAgICAgICAgaWYgKGxlbiAhPSBvZGF0YS5sZW5ndGgpCi0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW47IGkrKykgewotICAgICAgICAgICAgICAgIGlmIChkYXRhW2ldICE9IG9kYXRhW2ldKQotICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7Ci0gICAgICAgICAgICBpbnQgaGFzaCA9IDA7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGRhdGEubGVuZ3RoOyArK2kpIHsKLSAgICAgICAgICAgICAgICBoYXNoID0gaGFzaCAqIDM3ICsgKCgoaW50KSBkYXRhW2ldKSAmIDB4ZmYpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIGhhc2g7Ci0gICAgICAgIH0KLSAgICB9Ci19IC8vIGNsYXNzIEJhc2U2NEJpbmFyeURWCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L3hzL0Jhc2VEVkZhY3RvcnkuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYveHMvQmFzZURWRmFjdG9yeS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxOThmM2FiLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYveHMvQmFzZURWRmFjdG9yeS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjUwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDIsIDIwMDMsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LnhzOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LlNjaGVtYURWRmFjdG9yeTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYuWFNGYWNldHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LlhTU2ltcGxlVHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuU3ltYm9sSGFzaDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNPYmplY3RMaXN0OwotCi0vKioKLSAqIHRoZSBmYWN0b3J5IHRvIGNyZWF0ZS9yZXR1cm4gYnVpbHQtaW4gc2NoZW1hIERWcyBhbmQgY3JlYXRlIHVzZXItZGVmaW5lZCBEVnMKLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBOZWVyYWogQmFqYWosIFN1biBNaWNyb3N5c3RlbXMsIGluYy4KLSAqIEBhdXRob3IgU2FuZHkgR2FvLCBJQk0KLSAqCi0gKiBAdmVyc2lvbiAkSWQ6IEJhc2VEVkZhY3RvcnkuamF2YSx2IDEuNyAyMDEwLTExLTAxIDA0OjM5OjQ2IGpvZWh3IEV4cCAkCi0gKi8KLXB1YmxpYyBjbGFzcyBCYXNlRFZGYWN0b3J5IGV4dGVuZHMgU2NoZW1hRFZGYWN0b3J5IHsKLQotICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgVVJJX1NDSEVNQUZPUlNDSEVNQSA9ICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYSI7Ci0KLSAgICAvLyB0aGVyZSBhcmUgMjcgdHlwZXMuIDUzIGlzIHRoZSBjbG9zZXN0IHByaW1lIG51bWJlciB0byAyNyoyPTU0LgotICAgIHN0YXRpYyBTeW1ib2xIYXNoIGZCYXNlVHlwZXMgPSBuZXcgU3ltYm9sSGFzaCg1Myk7Ci0gICAgc3RhdGljIHsKLSAgICAgICAgY3JlYXRlQnVpbHRJblR5cGVzKGZCYXNlVHlwZXMpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCBhIGJ1aWx0LWluIHNpbXBsZSB0eXBlIG9mIHRoZSBnaXZlbiBuYW1lCi0gICAgICogUkVWSVNJVDogaXRzIHN0aWxsIG5vdCBkZWNpZGVkIHdpdGhpbiB0aGUgU2NoZW1hIFdHIGhvdyB0byBkZWZpbmUgdGhlCi0gICAgICogICAgICAgICAgdXItdHlwZXMgYW5kIGlmIGFsbCBzaW1wbGUgdHlwZXMgc2hvdWxkIGJlIGRlcml2ZWQgZnJvbSBhCi0gICAgICogICAgICAgICAgY29tcGxleCB0eXBlLCBzbyBhcyBvZiBub3cgd2UgaWdub3JlIHRoZSBmYWN0IHRoYXQgYW55U2ltcGxlVHlwZQotICAgICAqICAgICAgICAgIGlzIGRlcml2ZWQgZnJvbSBhbnlUeXBlLCBhbmQgcGFzcyAnbnVsbCcgYXMgdGhlIGJhc2Ugb2YKLSAgICAgKiAgICAgICAgICBhbnlTaW1wbGVUeXBlLiBJdCBuZWVkcyB0byBiZSBjaGFuZ2VkIGFzIHBlciB0aGUgZGVjaXNpb24gdGFrZW4uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSAgdGhlIG5hbWUgb2YgdGhlIGRhdGF0eXBlCi0gICAgICogQHJldHVybiAgICAgIHRoZSBkYXRhdHlwZSB2YWxpZGF0b3Igb2YgdGhlIGdpdmVuIG5hbWUKLSAgICAgKi8KLSAgICBwdWJsaWMgWFNTaW1wbGVUeXBlIGdldEJ1aWx0SW5UeXBlKFN0cmluZyBuYW1lKSB7Ci0gICAgICAgIHJldHVybiAoWFNTaW1wbGVUeXBlKWZCYXNlVHlwZXMuZ2V0KG5hbWUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIGdldCBhbGwgYnVpbHQtaW4gc2ltcGxlIHR5cGVzLCB3aGljaCBhcmUgc3RvcmVkIGluIGEgaGFzaHRhYmxlIGtleWVkIGJ5Ci0gICAgICogdGhlIG5hbWUKLSAgICAgKgotICAgICAqIEByZXR1cm4gICAgICBhIGhhc2h0YWJsZSB3aGljaCBjb250YWlucyBhbGwgYnVpbHQtaW4gc2ltcGxlIHR5cGVzCi0gICAgICovCi0gICAgcHVibGljIFN5bWJvbEhhc2ggZ2V0QnVpbHRJblR5cGVzKCkgewotICAgICAgICByZXR1cm4gKFN5bWJvbEhhc2gpZkJhc2VUeXBlcy5tYWtlQ2xvbmUoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGUgYSBuZXcgc2ltcGxlIHR5cGUgd2hpY2ggaXMgZGVyaXZlZCBieSByZXN0cmljdGlvbiBmcm9tIGFub3RoZXIKLSAgICAgKiBzaW1wbGUgdHlwZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lICAgICAgICAgICAgICBuYW1lIG9mIHRoZSBuZXcgdHlwZSwgY291bGQgYmUgbnVsbAotICAgICAqIEBwYXJhbSB0YXJnZXROYW1lc3BhY2UgICB0YXJnZXQgbmFtZXNwYWNlIG9mIHRoZSBuZXcgdHlwZSwgY291bGQgYmUgbnVsbAotICAgICAqIEBwYXJhbSBmaW5hbFNldCAgICAgICAgICB2YWx1ZSBvZiAiZmluYWwiCi0gICAgICogQHBhcmFtIGJhc2UgICAgICAgICAgICAgIGJhc2UgdHlwZSBvZiB0aGUgbmV3IHR5cGUKLSAgICAgKiBAcGFyYW0gYW5ub3RhdGlvbnMgICAgICAgc2V0IG9mIGFubm90YXRpb25zCi0gICAgICogQHJldHVybiAgICAgICAgICAgICAgICAgIHRoZSBuZXdseSBjcmVhdGVkIHNpbXBsZSB0eXBlCi0gICAgICovCi0gICAgcHVibGljIFhTU2ltcGxlVHlwZSBjcmVhdGVUeXBlUmVzdHJpY3Rpb24oU3RyaW5nIG5hbWUsIFN0cmluZyB0YXJnZXROYW1lc3BhY2UsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hvcnQgZmluYWxTZXQsIFhTU2ltcGxlVHlwZSBiYXNlLCBYU09iamVjdExpc3QgYW5ub3RhdGlvbnMpIHsKLSAgICAgICAgcmV0dXJuIG5ldyBYU1NpbXBsZVR5cGVEZWNsKChYU1NpbXBsZVR5cGVEZWNsKWJhc2UsIG5hbWUsIHRhcmdldE5hbWVzcGFjZSwgZmluYWxTZXQsIGZhbHNlLCBhbm5vdGF0aW9ucyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlIGEgbmV3IHNpbXBsZSB0eXBlIHdoaWNoIGlzIGRlcml2ZWQgYnkgbGlzdCBmcm9tIGFub3RoZXIgc2ltcGxlCi0gICAgICogdHlwZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lICAgICAgICAgICAgICBuYW1lIG9mIHRoZSBuZXcgdHlwZSwgY291bGQgYmUgbnVsbAotICAgICAqIEBwYXJhbSB0YXJnZXROYW1lc3BhY2UgICB0YXJnZXQgbmFtZXNwYWNlIG9mIHRoZSBuZXcgdHlwZSwgY291bGQgYmUgbnVsbAotICAgICAqIEBwYXJhbSBmaW5hbFNldCAgICAgICAgICB2YWx1ZSBvZiAiZmluYWwiCi0gICAgICogQHBhcmFtIGl0ZW1UeXBlICAgICAgICAgIGl0ZW0gdHlwZSBvZiB0aGUgbGlzdCB0eXBlCi0gICAgICogQHBhcmFtIGFubm90YXRpb25zICAgICAgIHNldCBvZiBhbm5vdGF0aW9ucwotICAgICAqIEByZXR1cm4gICAgICAgICAgICAgICAgICB0aGUgbmV3bHkgY3JlYXRlZCBzaW1wbGUgdHlwZQotICAgICAqLwotICAgIHB1YmxpYyBYU1NpbXBsZVR5cGUgY3JlYXRlVHlwZUxpc3QoU3RyaW5nIG5hbWUsIFN0cmluZyB0YXJnZXROYW1lc3BhY2UsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaG9ydCBmaW5hbFNldCwgWFNTaW1wbGVUeXBlIGl0ZW1UeXBlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWFNPYmplY3RMaXN0IGFubm90YXRpb25zKSB7Ci0gICAgICAgIHJldHVybiBuZXcgWFNTaW1wbGVUeXBlRGVjbChuYW1lLCB0YXJnZXROYW1lc3BhY2UsIGZpbmFsU2V0LCAoWFNTaW1wbGVUeXBlRGVjbClpdGVtVHlwZSwgZmFsc2UsIGFubm90YXRpb25zKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGUgYSBuZXcgc2ltcGxlIHR5cGUgd2hpY2ggaXMgZGVyaXZlZCBieSB1bmlvbiBmcm9tIGEgbGlzdCBvZiBvdGhlcgotICAgICAqIHNpbXBsZSB0eXBlcy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lICAgICAgICAgICAgICBuYW1lIG9mIHRoZSBuZXcgdHlwZSwgY291bGQgYmUgbnVsbAotICAgICAqIEBwYXJhbSB0YXJnZXROYW1lc3BhY2UgICB0YXJnZXQgbmFtZXNwYWNlIG9mIHRoZSBuZXcgdHlwZSwgY291bGQgYmUgbnVsbAotICAgICAqIEBwYXJhbSBmaW5hbFNldCAgICAgICAgICB2YWx1ZSBvZiAiZmluYWwiCi0gICAgICogQHBhcmFtIG1lbWJlclR5cGVzICAgICAgIG1lbWJlciB0eXBlcyBvZiB0aGUgdW5pb24gdHlwZQotICAgICAqIEBwYXJhbSBhbm5vdGF0aW9ucyAgICAgICBzZXQgb2YgYW5ub3RhdGlvbnMKLSAgICAgKiBAcmV0dXJuICAgICAgICAgICAgICAgICAgdGhlIG5ld2x5IGNyZWF0ZWQgc2ltcGxlIHR5cGUKLSAgICAgKi8KLSAgICBwdWJsaWMgWFNTaW1wbGVUeXBlIGNyZWF0ZVR5cGVVbmlvbihTdHJpbmcgbmFtZSwgU3RyaW5nIHRhcmdldE5hbWVzcGFjZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaG9ydCBmaW5hbFNldCwgWFNTaW1wbGVUeXBlW10gbWVtYmVyVHlwZXMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWFNPYmplY3RMaXN0IGFubm90YXRpb25zKSB7Ci0gICAgICAgIGludCB0eXBlTnVtID0gbWVtYmVyVHlwZXMubGVuZ3RoOwotICAgICAgICBYU1NpbXBsZVR5cGVEZWNsW10gbXR5cGVzID0gbmV3IFhTU2ltcGxlVHlwZURlY2xbdHlwZU51bV07Ci0gICAgICAgIFN5c3RlbS5hcnJheWNvcHkobWVtYmVyVHlwZXMsIDAsIG10eXBlcywgMCwgdHlwZU51bSk7Ci0KLSAgICAgICAgcmV0dXJuIG5ldyBYU1NpbXBsZVR5cGVEZWNsKG5hbWUsIHRhcmdldE5hbWVzcGFjZSwgZmluYWxTZXQsIG10eXBlcywgYW5ub3RhdGlvbnMpOwotICAgIH0KLQotICAgIC8vIGNyZWF0ZSBhbGwgYnVpbHQtaW4gdHlwZXMKLSAgICBzdGF0aWMgdm9pZCBjcmVhdGVCdWlsdEluVHlwZXMoU3ltYm9sSGFzaCB0eXBlcykgewotICAgICAgICAvLyBiYXNlIHNjaGVtYSBzaW1wbGUgdHlwZSBuYW1lcwotICAgICAgICBmaW5hbCBTdHJpbmcgQU5ZU0lNUExFVFlQRSAgICAgPSAiYW55U2ltcGxlVHlwZSI7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBBTllVUkkgICAgICAgICAgICA9ICJhbnlVUkkiOwotICAgICAgICBmaW5hbCBTdHJpbmcgQkFTRTY0QklOQVJZICAgICAgPSAiYmFzZTY0QmluYXJ5IjsKLSAgICAgICAgZmluYWwgU3RyaW5nIEJPT0xFQU4gICAgICAgICAgID0gImJvb2xlYW4iOwotICAgICAgICBmaW5hbCBTdHJpbmcgQllURSAgICAgICAgICAgICAgPSAiYnl0ZSI7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBEQVRFICAgICAgICAgICAgICA9ICJkYXRlIjsKLSAgICAgICAgZmluYWwgU3RyaW5nIERBVEVUSU1FICAgICAgICAgID0gImRhdGVUaW1lIjsKLSAgICAgICAgZmluYWwgU3RyaW5nIERBWSAgICAgICAgICAgICAgID0gImdEYXkiOwotICAgICAgICBmaW5hbCBTdHJpbmcgREVDSU1BTCAgICAgICAgICAgPSAiZGVjaW1hbCI7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBJTlQgICAgICAgICAgICAgICA9ICJpbnQiOwotICAgICAgICBmaW5hbCBTdHJpbmcgSU5URUdFUiAgICAgICAgICAgPSAiaW50ZWdlciI7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBMT05HICAgICAgICAgICAgICA9ICJsb25nIjsKLSAgICAgICAgZmluYWwgU3RyaW5nIE5FR0FUSVZFSU5URUdFUiAgID0gIm5lZ2F0aXZlSW50ZWdlciI7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBNT05USCAgICAgICAgICAgICA9ICJnTW9udGgiOwotICAgICAgICBmaW5hbCBTdHJpbmcgTU9OVEhEQVkgICAgICAgICAgPSAiZ01vbnRoRGF5IjsKLSAgICAgICAgZmluYWwgU3RyaW5nIE5PTk5FR0FUSVZFSU5URUdFUj0gIm5vbk5lZ2F0aXZlSW50ZWdlciI7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBOT05QT1NJVElWRUlOVEVHRVI9ICJub25Qb3NpdGl2ZUludGVnZXIiOwotICAgICAgICBmaW5hbCBTdHJpbmcgUE9TSVRJVkVJTlRFR0VSICAgPSAicG9zaXRpdmVJbnRlZ2VyIjsKLSAgICAgICAgZmluYWwgU3RyaW5nIFNIT1JUICAgICAgICAgICAgID0gInNob3J0IjsKLSAgICAgICAgZmluYWwgU3RyaW5nIFNUUklORyAgICAgICAgICAgID0gInN0cmluZyI7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBUSU1FICAgICAgICAgICAgICA9ICJ0aW1lIjsKLSAgICAgICAgZmluYWwgU3RyaW5nIFVOU0lHTkVEQllURSAgICAgID0gInVuc2lnbmVkQnl0ZSI7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBVTlNJR05FRElOVCAgICAgICA9ICJ1bnNpZ25lZEludCI7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBVTlNJR05FRExPTkcgICAgICA9ICJ1bnNpZ25lZExvbmciOwotICAgICAgICBmaW5hbCBTdHJpbmcgVU5TSUdORURTSE9SVCAgICAgPSAidW5zaWduZWRTaG9ydCI7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBZRUFSICAgICAgICAgICAgICA9ICJnWWVhciI7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBZRUFSTU9OVEggICAgICAgICA9ICJnWWVhck1vbnRoIjsKLQotICAgICAgICBmaW5hbCBYU0ZhY2V0cyBmYWNldHMgPSBuZXcgWFNGYWNldHMoKTsKLQotICAgICAgICBYU1NpbXBsZVR5cGVEZWNsIGFueVNpbXBsZVR5cGUgPSBYU1NpbXBsZVR5cGVEZWNsLmZBbnlTaW1wbGVUeXBlOwotICAgICAgICB0eXBlcy5wdXQoQU5ZU0lNUExFVFlQRSwgYW55U2ltcGxlVHlwZSk7Ci0gICAgICAgIFhTU2ltcGxlVHlwZURlY2wgc3RyaW5nRFYgPSBuZXcgWFNTaW1wbGVUeXBlRGVjbChhbnlTaW1wbGVUeXBlLCBTVFJJTkcsIFhTU2ltcGxlVHlwZURlY2wuRFZfU1RSSU5HLCBYU1NpbXBsZVR5cGUuT1JERVJFRF9GQUxTRSwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgdHJ1ZSwgWFNDb25zdGFudHMuU1RSSU5HX0RUKTsKLSAgICAgICAgdHlwZXMucHV0KFNUUklORywgc3RyaW5nRFYpOwotICAgICAgICB0eXBlcy5wdXQoQk9PTEVBTiwgbmV3IFhTU2ltcGxlVHlwZURlY2woYW55U2ltcGxlVHlwZSwgQk9PTEVBTiwgWFNTaW1wbGVUeXBlRGVjbC5EVl9CT09MRUFOLCBYU1NpbXBsZVR5cGUuT1JERVJFRF9GQUxTRSwgZmFsc2UsIHRydWUsIGZhbHNlLCB0cnVlLCBYU0NvbnN0YW50cy5CT09MRUFOX0RUKSk7Ci0gICAgICAgIFhTU2ltcGxlVHlwZURlY2wgZGVjaW1hbERWID0gbmV3IFhTU2ltcGxlVHlwZURlY2woYW55U2ltcGxlVHlwZSwgREVDSU1BTCwgWFNTaW1wbGVUeXBlRGVjbC5EVl9ERUNJTUFMLCBYU1NpbXBsZVR5cGUuT1JERVJFRF9UT1RBTCwgZmFsc2UsIGZhbHNlLCB0cnVlLCB0cnVlLCBYU0NvbnN0YW50cy5ERUNJTUFMX0RUKTsKLSAgICAgICAgdHlwZXMucHV0KERFQ0lNQUwsIGRlY2ltYWxEVik7Ci0KLSAgICAgICAgdHlwZXMucHV0KEFOWVVSSSwgbmV3IFhTU2ltcGxlVHlwZURlY2woYW55U2ltcGxlVHlwZSwgQU5ZVVJJLCBYU1NpbXBsZVR5cGVEZWNsLkRWX0FOWVVSSSwgWFNTaW1wbGVUeXBlLk9SREVSRURfRkFMU0UsIGZhbHNlLCBmYWxzZSwgZmFsc2UsIHRydWUsIFhTQ29uc3RhbnRzLkFOWVVSSV9EVCkpOwotICAgICAgICB0eXBlcy5wdXQoQkFTRTY0QklOQVJZLCBuZXcgWFNTaW1wbGVUeXBlRGVjbChhbnlTaW1wbGVUeXBlLCBCQVNFNjRCSU5BUlksIFhTU2ltcGxlVHlwZURlY2wuRFZfQkFTRTY0QklOQVJZLCBYU1NpbXBsZVR5cGUuT1JERVJFRF9GQUxTRSwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgdHJ1ZSwgWFNDb25zdGFudHMuQkFTRTY0QklOQVJZX0RUKSk7Ci0gICAgICAgIHR5cGVzLnB1dChEQVRFVElNRSwgbmV3IFhTU2ltcGxlVHlwZURlY2woYW55U2ltcGxlVHlwZSwgREFURVRJTUUsIFhTU2ltcGxlVHlwZURlY2wuRFZfREFURVRJTUUsIFhTU2ltcGxlVHlwZS5PUkRFUkVEX1BBUlRJQUwsIGZhbHNlLCBmYWxzZSwgZmFsc2UsIHRydWUsIFhTQ29uc3RhbnRzLkRBVEVUSU1FX0RUKSk7Ci0gICAgICAgIHR5cGVzLnB1dChUSU1FLCBuZXcgWFNTaW1wbGVUeXBlRGVjbChhbnlTaW1wbGVUeXBlLCBUSU1FLCBYU1NpbXBsZVR5cGVEZWNsLkRWX1RJTUUsIFhTU2ltcGxlVHlwZS5PUkRFUkVEX1BBUlRJQUwsIGZhbHNlLCBmYWxzZSwgZmFsc2UsIHRydWUsIFhTQ29uc3RhbnRzLlRJTUVfRFQpKTsKLSAgICAgICAgdHlwZXMucHV0KERBVEUsIG5ldyBYU1NpbXBsZVR5cGVEZWNsKGFueVNpbXBsZVR5cGUsIERBVEUsIFhTU2ltcGxlVHlwZURlY2wuRFZfREFURSwgWFNTaW1wbGVUeXBlLk9SREVSRURfUEFSVElBTCwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgdHJ1ZSwgWFNDb25zdGFudHMuREFURV9EVCkpOwotICAgICAgICB0eXBlcy5wdXQoWUVBUk1PTlRILCBuZXcgWFNTaW1wbGVUeXBlRGVjbChhbnlTaW1wbGVUeXBlLCBZRUFSTU9OVEgsIFhTU2ltcGxlVHlwZURlY2wuRFZfR1lFQVJNT05USCwgWFNTaW1wbGVUeXBlLk9SREVSRURfUEFSVElBTCwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgdHJ1ZSwgWFNDb25zdGFudHMuR1lFQVJNT05USF9EVCkpOwotICAgICAgICB0eXBlcy5wdXQoWUVBUiwgbmV3IFhTU2ltcGxlVHlwZURlY2woYW55U2ltcGxlVHlwZSwgWUVBUiwgWFNTaW1wbGVUeXBlRGVjbC5EVl9HWUVBUiwgWFNTaW1wbGVUeXBlLk9SREVSRURfUEFSVElBTCwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgdHJ1ZSwgWFNDb25zdGFudHMuR1lFQVJfRFQpKTsKLSAgICAgICAgdHlwZXMucHV0KE1PTlRIREFZLCBuZXcgWFNTaW1wbGVUeXBlRGVjbChhbnlTaW1wbGVUeXBlLCBNT05USERBWSwgWFNTaW1wbGVUeXBlRGVjbC5EVl9HTU9OVEhEQVksIFhTU2ltcGxlVHlwZS5PUkRFUkVEX1BBUlRJQUwsIGZhbHNlLCBmYWxzZSwgZmFsc2UsIHRydWUsIFhTQ29uc3RhbnRzLkdNT05USERBWV9EVCkpOwotICAgICAgICB0eXBlcy5wdXQoREFZLCBuZXcgWFNTaW1wbGVUeXBlRGVjbChhbnlTaW1wbGVUeXBlLCBEQVksIFhTU2ltcGxlVHlwZURlY2wuRFZfR0RBWSwgWFNTaW1wbGVUeXBlLk9SREVSRURfUEFSVElBTCwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgdHJ1ZSwgWFNDb25zdGFudHMuR0RBWV9EVCkpOwotICAgICAgICB0eXBlcy5wdXQoTU9OVEgsIG5ldyBYU1NpbXBsZVR5cGVEZWNsKGFueVNpbXBsZVR5cGUsIE1PTlRILCBYU1NpbXBsZVR5cGVEZWNsLkRWX0dNT05USCwgWFNTaW1wbGVUeXBlLk9SREVSRURfUEFSVElBTCwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgdHJ1ZSwgWFNDb25zdGFudHMuR01PTlRIX0RUKSk7Ci0KLSAgICAgICAgWFNTaW1wbGVUeXBlRGVjbCBpbnRlZ2VyRFYgPSBuZXcgWFNTaW1wbGVUeXBlRGVjbChkZWNpbWFsRFYsIElOVEVHRVIsIFhTU2ltcGxlVHlwZURlY2wuRFZfSU5URUdFUiwgWFNTaW1wbGVUeXBlLk9SREVSRURfVE9UQUwsIGZhbHNlLCBmYWxzZSwgdHJ1ZSwgdHJ1ZSwgWFNDb25zdGFudHMuSU5URUdFUl9EVCk7Ci0gICAgICAgIHR5cGVzLnB1dChJTlRFR0VSLCBpbnRlZ2VyRFYpOwotCi0gICAgICAgIGZhY2V0cy5tYXhJbmNsdXNpdmUgPSAiMCI7Ci0gICAgICAgIFhTU2ltcGxlVHlwZURlY2wgbm9uUG9zaXRpdmVEViA9IG5ldyBYU1NpbXBsZVR5cGVEZWNsKGludGVnZXJEViwgTk9OUE9TSVRJVkVJTlRFR0VSLCBVUklfU0NIRU1BRk9SU0NIRU1BLCAoc2hvcnQpMCwgZmFsc2UsIG51bGwsIFhTQ29uc3RhbnRzLk5PTlBPU0lUSVZFSU5URUdFUl9EVCk7Ci0gICAgICAgIG5vblBvc2l0aXZlRFYuYXBwbHlGYWNldHMxKGZhY2V0cyAsIFhTU2ltcGxlVHlwZS5GQUNFVF9NQVhJTkNMVVNJVkUsIChzaG9ydCkwKTsKLSAgICAgICAgdHlwZXMucHV0KE5PTlBPU0lUSVZFSU5URUdFUiwgbm9uUG9zaXRpdmVEVik7Ci0KLSAgICAgICAgZmFjZXRzLm1heEluY2x1c2l2ZSA9ICItMSI7Ci0gICAgICAgIFhTU2ltcGxlVHlwZURlY2wgbmVnYXRpdmVEViA9IG5ldyBYU1NpbXBsZVR5cGVEZWNsKG5vblBvc2l0aXZlRFYsIE5FR0FUSVZFSU5URUdFUiwgVVJJX1NDSEVNQUZPUlNDSEVNQSwgKHNob3J0KTAsIGZhbHNlLCBudWxsLCBYU0NvbnN0YW50cy5ORUdBVElWRUlOVEVHRVJfRFQpOwotICAgICAgICBuZWdhdGl2ZURWLmFwcGx5RmFjZXRzMShmYWNldHMgLCBYU1NpbXBsZVR5cGUuRkFDRVRfTUFYSU5DTFVTSVZFLCAoc2hvcnQpMCk7Ci0gICAgICAgIHR5cGVzLnB1dChORUdBVElWRUlOVEVHRVIsIG5lZ2F0aXZlRFYpOwotCi0gICAgICAgIGZhY2V0cy5tYXhJbmNsdXNpdmUgPSAiOTIyMzM3MjAzNjg1NDc3NTgwNyI7Ci0gICAgICAgIGZhY2V0cy5taW5JbmNsdXNpdmUgPSAiLTkyMjMzNzIwMzY4NTQ3NzU4MDgiOwotICAgICAgICBYU1NpbXBsZVR5cGVEZWNsIGxvbmdEViA9IG5ldyBYU1NpbXBsZVR5cGVEZWNsKGludGVnZXJEViwgTE9ORywgVVJJX1NDSEVNQUZPUlNDSEVNQSwgKHNob3J0KTAsIGZhbHNlLCBudWxsLCBYU0NvbnN0YW50cy5MT05HX0RUKTsKLSAgICAgICAgbG9uZ0RWLmFwcGx5RmFjZXRzMShmYWNldHMgLCAoc2hvcnQpKFhTU2ltcGxlVHlwZS5GQUNFVF9NQVhJTkNMVVNJVkUgfCBYU1NpbXBsZVR5cGUuRkFDRVRfTUlOSU5DTFVTSVZFKSwgKHNob3J0KTAgKTsKLSAgICAgICAgdHlwZXMucHV0KExPTkcsIGxvbmdEVik7Ci0KLQotICAgICAgICBmYWNldHMubWF4SW5jbHVzaXZlID0gIjIxNDc0ODM2NDciOwotICAgICAgICBmYWNldHMubWluSW5jbHVzaXZlID0gICItMjE0NzQ4MzY0OCI7Ci0gICAgICAgIFhTU2ltcGxlVHlwZURlY2wgaW50RFYgPSBuZXcgWFNTaW1wbGVUeXBlRGVjbChsb25nRFYsIElOVCwgVVJJX1NDSEVNQUZPUlNDSEVNQSwgKHNob3J0KTAsIGZhbHNlLCBudWxsLCBYU0NvbnN0YW50cy5JTlRfRFQpOwotICAgICAgICBpbnREVi5hcHBseUZhY2V0czEoZmFjZXRzLCAoc2hvcnQpKFhTU2ltcGxlVHlwZS5GQUNFVF9NQVhJTkNMVVNJVkUgfCBYU1NpbXBsZVR5cGUuRkFDRVRfTUlOSU5DTFVTSVZFKSwgKHNob3J0KTAgKTsKLSAgICAgICAgdHlwZXMucHV0KElOVCwgaW50RFYpOwotCi0gICAgICAgIGZhY2V0cy5tYXhJbmNsdXNpdmUgPSAiMzI3NjciOwotICAgICAgICBmYWNldHMubWluSW5jbHVzaXZlID0gIi0zMjc2OCI7Ci0gICAgICAgIFhTU2ltcGxlVHlwZURlY2wgc2hvcnREViA9IG5ldyBYU1NpbXBsZVR5cGVEZWNsKGludERWLCBTSE9SVCAsIFVSSV9TQ0hFTUFGT1JTQ0hFTUEsIChzaG9ydCkwLCBmYWxzZSwgbnVsbCwgWFNDb25zdGFudHMuU0hPUlRfRFQpOwotICAgICAgICBzaG9ydERWLmFwcGx5RmFjZXRzMShmYWNldHMsIChzaG9ydCkoWFNTaW1wbGVUeXBlLkZBQ0VUX01BWElOQ0xVU0lWRSB8IFhTU2ltcGxlVHlwZS5GQUNFVF9NSU5JTkNMVVNJVkUpLCAoc2hvcnQpMCApOwotICAgICAgICB0eXBlcy5wdXQoU0hPUlQsIHNob3J0RFYpOwotCi0gICAgICAgIGZhY2V0cy5tYXhJbmNsdXNpdmUgPSAiMTI3IjsKLSAgICAgICAgZmFjZXRzLm1pbkluY2x1c2l2ZSA9ICItMTI4IjsKLSAgICAgICAgWFNTaW1wbGVUeXBlRGVjbCBieXRlRFYgPSBuZXcgWFNTaW1wbGVUeXBlRGVjbChzaG9ydERWLCBCWVRFICwgVVJJX1NDSEVNQUZPUlNDSEVNQSwgKHNob3J0KTAsIGZhbHNlLCBudWxsLCBYU0NvbnN0YW50cy5CWVRFX0RUKTsKLSAgICAgICAgYnl0ZURWLmFwcGx5RmFjZXRzMShmYWNldHMsIChzaG9ydCkoWFNTaW1wbGVUeXBlLkZBQ0VUX01BWElOQ0xVU0lWRSB8IFhTU2ltcGxlVHlwZS5GQUNFVF9NSU5JTkNMVVNJVkUpLCAoc2hvcnQpMCApOwotICAgICAgICB0eXBlcy5wdXQoQllURSwgYnl0ZURWKTsKLQotICAgICAgICBmYWNldHMubWluSW5jbHVzaXZlID0gICIwIiA7Ci0gICAgICAgIFhTU2ltcGxlVHlwZURlY2wgbm9uTmVnYXRpdmVEViA9IG5ldyBYU1NpbXBsZVR5cGVEZWNsKGludGVnZXJEViwgTk9OTkVHQVRJVkVJTlRFR0VSICwgVVJJX1NDSEVNQUZPUlNDSEVNQSwgKHNob3J0KTAsIGZhbHNlLCBudWxsLCBYU0NvbnN0YW50cy5OT05ORUdBVElWRUlOVEVHRVJfRFQpOwotICAgICAgICBub25OZWdhdGl2ZURWLmFwcGx5RmFjZXRzMShmYWNldHMsIFhTU2ltcGxlVHlwZS5GQUNFVF9NSU5JTkNMVVNJVkUsIChzaG9ydCkwICk7Ci0gICAgICAgIHR5cGVzLnB1dChOT05ORUdBVElWRUlOVEVHRVIsIG5vbk5lZ2F0aXZlRFYpOwotCi0gICAgICAgIGZhY2V0cy5tYXhJbmNsdXNpdmUgPSAiMTg0NDY3NDQwNzM3MDk1NTE2MTUiIDsKLSAgICAgICAgWFNTaW1wbGVUeXBlRGVjbCB1bnNpZ25lZExvbmdEViA9IG5ldyBYU1NpbXBsZVR5cGVEZWNsKG5vbk5lZ2F0aXZlRFYsIFVOU0lHTkVETE9ORyAsIFVSSV9TQ0hFTUFGT1JTQ0hFTUEsIChzaG9ydCkwLCBmYWxzZSwgbnVsbCwgWFNDb25zdGFudHMuVU5TSUdORURMT05HX0RUKTsKLSAgICAgICAgdW5zaWduZWRMb25nRFYuYXBwbHlGYWNldHMxKGZhY2V0cywgWFNTaW1wbGVUeXBlLkZBQ0VUX01BWElOQ0xVU0lWRSwgKHNob3J0KTAgKTsKLSAgICAgICAgdHlwZXMucHV0KFVOU0lHTkVETE9ORywgdW5zaWduZWRMb25nRFYpOwotCi0gICAgICAgIGZhY2V0cy5tYXhJbmNsdXNpdmUgPSAiNDI5NDk2NzI5NSIgOwotICAgICAgICBYU1NpbXBsZVR5cGVEZWNsIHVuc2lnbmVkSW50RFYgPSBuZXcgWFNTaW1wbGVUeXBlRGVjbCh1bnNpZ25lZExvbmdEViwgVU5TSUdORURJTlQgLCBVUklfU0NIRU1BRk9SU0NIRU1BLCAoc2hvcnQpMCwgZmFsc2UsIG51bGwsIFhTQ29uc3RhbnRzLlVOU0lHTkVESU5UX0RUKTsKLSAgICAgICAgdW5zaWduZWRJbnREVi5hcHBseUZhY2V0czEoZmFjZXRzLCBYU1NpbXBsZVR5cGUuRkFDRVRfTUFYSU5DTFVTSVZFLCAoc2hvcnQpMCApOwotICAgICAgICB0eXBlcy5wdXQoVU5TSUdORURJTlQsIHVuc2lnbmVkSW50RFYpOwotCi0gICAgICAgIGZhY2V0cy5tYXhJbmNsdXNpdmUgPSAiNjU1MzUiIDsKLSAgICAgICAgWFNTaW1wbGVUeXBlRGVjbCB1bnNpZ25lZFNob3J0RFYgPSBuZXcgWFNTaW1wbGVUeXBlRGVjbCh1bnNpZ25lZEludERWLCBVTlNJR05FRFNIT1JUICwgVVJJX1NDSEVNQUZPUlNDSEVNQSwgKHNob3J0KTAsIGZhbHNlLCBudWxsLCBYU0NvbnN0YW50cy5VTlNJR05FRFNIT1JUX0RUKTsKLSAgICAgICAgdW5zaWduZWRTaG9ydERWLmFwcGx5RmFjZXRzMShmYWNldHMsIFhTU2ltcGxlVHlwZS5GQUNFVF9NQVhJTkNMVVNJVkUsIChzaG9ydCkwICk7Ci0gICAgICAgIHR5cGVzLnB1dChVTlNJR05FRFNIT1JULCB1bnNpZ25lZFNob3J0RFYpOwotCi0gICAgICAgIGZhY2V0cy5tYXhJbmNsdXNpdmUgPSAiMjU1IiA7Ci0gICAgICAgIFhTU2ltcGxlVHlwZURlY2wgdW5zaWduZWRCeXRlRFYgPSBuZXcgWFNTaW1wbGVUeXBlRGVjbCh1bnNpZ25lZFNob3J0RFYsIFVOU0lHTkVEQllURSAsIFVSSV9TQ0hFTUFGT1JTQ0hFTUEsIChzaG9ydCkwLCBmYWxzZSwgbnVsbCwgWFNDb25zdGFudHMuVU5TSUdORURCWVRFX0RUKTsKLSAgICAgICAgdW5zaWduZWRCeXRlRFYuYXBwbHlGYWNldHMxKGZhY2V0cywgWFNTaW1wbGVUeXBlLkZBQ0VUX01BWElOQ0xVU0lWRSwgKHNob3J0KTAgKTsKLSAgICAgICAgdHlwZXMucHV0KFVOU0lHTkVEQllURSwgdW5zaWduZWRCeXRlRFYpOwotCi0gICAgICAgIGZhY2V0cy5taW5JbmNsdXNpdmUgPSAiMSIgOwotICAgICAgICBYU1NpbXBsZVR5cGVEZWNsIHBvc2l0aXZlSW50ZWdlckRWID0gbmV3IFhTU2ltcGxlVHlwZURlY2wobm9uTmVnYXRpdmVEViwgUE9TSVRJVkVJTlRFR0VSICwgVVJJX1NDSEVNQUZPUlNDSEVNQSwgKHNob3J0KTAsIGZhbHNlLCBudWxsLCBYU0NvbnN0YW50cy5QT1NJVElWRUlOVEVHRVJfRFQpOwotICAgICAgICBwb3NpdGl2ZUludGVnZXJEVi5hcHBseUZhY2V0czEoZmFjZXRzLCBYU1NpbXBsZVR5cGUuRkFDRVRfTUlOSU5DTFVTSVZFLCAoc2hvcnQpMCApOwotICAgICAgICB0eXBlcy5wdXQoUE9TSVRJVkVJTlRFR0VSLCBwb3NpdGl2ZUludGVnZXJEVik7Ci0gICAgfS8vY3JlYXRlQnVpbHRJblR5cGVzKFN5bWJvbEhhc2gpCi0KLX0vL0Jhc2VEVkZhY3RvcnkKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYveHMvQmFzZVNjaGVtYURWRmFjdG9yeS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi94cy9CYXNlU2NoZW1hRFZGYWN0b3J5LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGRhMzBhOGYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi94cy9CYXNlU2NoZW1hRFZGYWN0b3J5LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzMjkgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKLSAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAotICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgotICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKLSAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCi0gKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYueHM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYuU2NoZW1hRFZGYWN0b3J5OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5YU0ZhY2V0czsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYuWFNTaW1wbGVUeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5YU0RlY2xhcmF0aW9uUG9vbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuU3ltYm9sSGFzaDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNPYmplY3RMaXN0OwotCi0vKioKLSAqIHRoZSBiYXNlIGZhY3RvcnkgdG8gY3JlYXRlL3JldHVybiBidWlsdC1pbiBzY2hlbWEgRFZzIGFuZCBjcmVhdGUgdXNlci1kZWZpbmVkIERWcwotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIE5lZXJhaiBCYWphaiwgU3VuIE1pY3Jvc3lzdGVtcywgaW5jLgotICogQGF1dGhvciBTYW5keSBHYW8sIElCTQotICogQGF1dGhvciBLaGFsZWQgTm9hbWFuLCBJQk0KLSAqCi0gKiBAdmVyc2lvbiAkSWQ6IEJhc2VTY2hlbWFEVkZhY3RvcnkuamF2YSx2IDEuMiAyMDEwLTEwLTI2IDIzOjAxOjAzIGpvZWh3IEV4cCAkCi0gKi8KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBCYXNlU2NoZW1hRFZGYWN0b3J5IGV4dGVuZHMgU2NoZW1hRFZGYWN0b3J5IHsKLQotICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgVVJJX1NDSEVNQUZPUlNDSEVNQSA9ICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYSI7Ci0KLSAgICBwcm90ZWN0ZWQgWFNEZWNsYXJhdGlvblBvb2wgZkRlY2xQb29sID0gbnVsbDsKLQotICAgIC8vIGNyZWF0ZSBjb21tb24gYnVpbHQtaW4gdHlwZXMKLSAgICBwcm90ZWN0ZWQgc3RhdGljIHZvaWQgY3JlYXRlQnVpbHRJblR5cGVzKFN5bWJvbEhhc2ggYnVpbHRJblR5cGVzLCBYU1NpbXBsZVR5cGVEZWNsIGJhc2VBdG9taWNUeXBlKSB7Ci0gICAgICAgIC8vIGFsbCBzY2hlbWEgc2ltcGxlIHR5cGUgbmFtZXMKLSAgICAgICAgZmluYWwgU3RyaW5nIEFOWVNJTVBMRVRZUEUgICAgID0gImFueVNpbXBsZVR5cGUiOwotICAgICAgICBmaW5hbCBTdHJpbmcgQU5ZVVJJICAgICAgICAgICAgPSAiYW55VVJJIjsKLSAgICAgICAgZmluYWwgU3RyaW5nIEJBU0U2NEJJTkFSWSAgICAgID0gImJhc2U2NEJpbmFyeSI7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBCT09MRUFOICAgICAgICAgICA9ICJib29sZWFuIjsKLSAgICAgICAgZmluYWwgU3RyaW5nIEJZVEUgICAgICAgICAgICAgID0gImJ5dGUiOwotICAgICAgICBmaW5hbCBTdHJpbmcgREFURSAgICAgICAgICAgICAgPSAiZGF0ZSI7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBEQVRFVElNRSAgICAgICAgICA9ICJkYXRlVGltZSI7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBEQVkgICAgICAgICAgICAgICA9ICJnRGF5IjsKLSAgICAgICAgZmluYWwgU3RyaW5nIERFQ0lNQUwgICAgICAgICAgID0gImRlY2ltYWwiOwotICAgICAgICBmaW5hbCBTdHJpbmcgRE9VQkxFICAgICAgICAgICAgPSAiZG91YmxlIjsKLSAgICAgICAgZmluYWwgU3RyaW5nIERVUkFUSU9OICAgICAgICAgID0gImR1cmF0aW9uIjsKLSAgICAgICAgZmluYWwgU3RyaW5nIEVOVElUWSAgICAgICAgICAgID0gIkVOVElUWSI7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBFTlRJVElFUyAgICAgICAgICA9ICJFTlRJVElFUyI7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBGTE9BVCAgICAgICAgICAgICA9ICJmbG9hdCI7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBIRVhCSU5BUlkgICAgICAgICA9ICJoZXhCaW5hcnkiOwotICAgICAgICBmaW5hbCBTdHJpbmcgSUQgICAgICAgICAgICAgICAgPSAiSUQiOwotICAgICAgICBmaW5hbCBTdHJpbmcgSURSRUYgICAgICAgICAgICAgPSAiSURSRUYiOwotICAgICAgICBmaW5hbCBTdHJpbmcgSURSRUZTICAgICAgICAgICAgPSAiSURSRUZTIjsKLSAgICAgICAgZmluYWwgU3RyaW5nIElOVCAgICAgICAgICAgICAgID0gImludCI7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBJTlRFR0VSICAgICAgICAgICA9ICJpbnRlZ2VyIjsKLSAgICAgICAgZmluYWwgU3RyaW5nIExPTkcgICAgICAgICAgICAgID0gImxvbmciOwotICAgICAgICBmaW5hbCBTdHJpbmcgTkFNRSAgICAgICAgICAgICAgPSAiTmFtZSI7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBORUdBVElWRUlOVEVHRVIgICA9ICJuZWdhdGl2ZUludGVnZXIiOwotICAgICAgICBmaW5hbCBTdHJpbmcgTU9OVEggICAgICAgICAgICAgPSAiZ01vbnRoIjsKLSAgICAgICAgZmluYWwgU3RyaW5nIE1PTlRIREFZICAgICAgICAgID0gImdNb250aERheSI7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBOQ05BTUUgICAgICAgICAgICA9ICJOQ05hbWUiOwotICAgICAgICBmaW5hbCBTdHJpbmcgTk1UT0tFTiAgICAgICAgICAgPSAiTk1UT0tFTiI7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBOTVRPS0VOUyAgICAgICAgICA9ICJOTVRPS0VOUyI7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBMQU5HVUFHRSAgICAgICAgICA9ICJsYW5ndWFnZSI7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBOT05ORUdBVElWRUlOVEVHRVI9ICJub25OZWdhdGl2ZUludGVnZXIiOwotICAgICAgICBmaW5hbCBTdHJpbmcgTk9OUE9TSVRJVkVJTlRFR0VSPSAibm9uUG9zaXRpdmVJbnRlZ2VyIjsKLSAgICAgICAgZmluYWwgU3RyaW5nIE5PUk1BTElaRURTVFJJTkcgID0gIm5vcm1hbGl6ZWRTdHJpbmciOwotICAgICAgICBmaW5hbCBTdHJpbmcgTk9UQVRJT04gICAgICAgICAgPSAiTk9UQVRJT04iOwotICAgICAgICBmaW5hbCBTdHJpbmcgUE9TSVRJVkVJTlRFR0VSICAgPSAicG9zaXRpdmVJbnRlZ2VyIjsKLSAgICAgICAgZmluYWwgU3RyaW5nIFFOQU1FICAgICAgICAgICAgID0gIlFOYW1lIjsKLSAgICAgICAgZmluYWwgU3RyaW5nIFNIT1JUICAgICAgICAgICAgID0gInNob3J0IjsKLSAgICAgICAgZmluYWwgU3RyaW5nIFNUUklORyAgICAgICAgICAgID0gInN0cmluZyI7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBUSU1FICAgICAgICAgICAgICA9ICJ0aW1lIjsKLSAgICAgICAgZmluYWwgU3RyaW5nIFRPS0VOICAgICAgICAgICAgID0gInRva2VuIjsKLSAgICAgICAgZmluYWwgU3RyaW5nIFVOU0lHTkVEQllURSAgICAgID0gInVuc2lnbmVkQnl0ZSI7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBVTlNJR05FRElOVCAgICAgICA9ICJ1bnNpZ25lZEludCI7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBVTlNJR05FRExPTkcgICAgICA9ICJ1bnNpZ25lZExvbmciOwotICAgICAgICBmaW5hbCBTdHJpbmcgVU5TSUdORURTSE9SVCAgICAgPSAidW5zaWduZWRTaG9ydCI7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBZRUFSICAgICAgICAgICAgICA9ICJnWWVhciI7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBZRUFSTU9OVEggICAgICAgICA9ICJnWWVhck1vbnRoIjsKLQotICAgICAgICBmaW5hbCBYU0ZhY2V0cyBmYWNldHMgPSBuZXcgWFNGYWNldHMoKTsKLQotICAgICAgICBidWlsdEluVHlwZXMucHV0KEFOWVNJTVBMRVRZUEUsIFhTU2ltcGxlVHlwZURlY2wuZkFueVNpbXBsZVR5cGUpOwotCi0gICAgICAgIFhTU2ltcGxlVHlwZURlY2wgc3RyaW5nRFYgPSBuZXcgWFNTaW1wbGVUeXBlRGVjbChiYXNlQXRvbWljVHlwZSwgU1RSSU5HLCBYU1NpbXBsZVR5cGVEZWNsLkRWX1NUUklORywgWFNTaW1wbGVUeXBlLk9SREVSRURfRkFMU0UsIGZhbHNlLCBmYWxzZSwgZmFsc2UgLCB0cnVlLCBYU0NvbnN0YW50cy5TVFJJTkdfRFQpOwotICAgICAgICBidWlsdEluVHlwZXMucHV0KFNUUklORywgc3RyaW5nRFYpOwotICAgICAgICBidWlsdEluVHlwZXMucHV0KEJPT0xFQU4sIG5ldyBYU1NpbXBsZVR5cGVEZWNsKGJhc2VBdG9taWNUeXBlLCBCT09MRUFOLCBYU1NpbXBsZVR5cGVEZWNsLkRWX0JPT0xFQU4sIFhTU2ltcGxlVHlwZS5PUkRFUkVEX0ZBTFNFLCBmYWxzZSwgdHJ1ZSwgZmFsc2UsIHRydWUsIFhTQ29uc3RhbnRzLkJPT0xFQU5fRFQpKTsKLSAgICAgICAgWFNTaW1wbGVUeXBlRGVjbCBkZWNpbWFsRFYgPSBuZXcgWFNTaW1wbGVUeXBlRGVjbChiYXNlQXRvbWljVHlwZSwgREVDSU1BTCwgWFNTaW1wbGVUeXBlRGVjbC5EVl9ERUNJTUFMLCBYU1NpbXBsZVR5cGUuT1JERVJFRF9UT1RBTCwgZmFsc2UsIGZhbHNlLCB0cnVlLCB0cnVlLCBYU0NvbnN0YW50cy5ERUNJTUFMX0RUKTsKLSAgICAgICAgYnVpbHRJblR5cGVzLnB1dChERUNJTUFMLCBkZWNpbWFsRFYpOwotCi0gICAgICAgIGJ1aWx0SW5UeXBlcy5wdXQoQU5ZVVJJLCBuZXcgWFNTaW1wbGVUeXBlRGVjbChiYXNlQXRvbWljVHlwZSwgQU5ZVVJJLCBYU1NpbXBsZVR5cGVEZWNsLkRWX0FOWVVSSSwgWFNTaW1wbGVUeXBlLk9SREVSRURfRkFMU0UsIGZhbHNlLCBmYWxzZSwgZmFsc2UsIHRydWUsIFhTQ29uc3RhbnRzLkFOWVVSSV9EVCkpOwotICAgICAgICBidWlsdEluVHlwZXMucHV0KEJBU0U2NEJJTkFSWSwgbmV3IFhTU2ltcGxlVHlwZURlY2woYmFzZUF0b21pY1R5cGUsIEJBU0U2NEJJTkFSWSwgWFNTaW1wbGVUeXBlRGVjbC5EVl9CQVNFNjRCSU5BUlksIFhTU2ltcGxlVHlwZS5PUkRFUkVEX0ZBTFNFLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCB0cnVlLCBYU0NvbnN0YW50cy5CQVNFNjRCSU5BUllfRFQpKTsKLQotICAgICAgICBYU1NpbXBsZVR5cGVEZWNsIGR1cmF0aW9uRFYgPSBuZXcgWFNTaW1wbGVUeXBlRGVjbChiYXNlQXRvbWljVHlwZSwgRFVSQVRJT04sIFhTU2ltcGxlVHlwZURlY2wuRFZfRFVSQVRJT04sIFhTU2ltcGxlVHlwZS5PUkRFUkVEX1BBUlRJQUwsIGZhbHNlLCBmYWxzZSwgZmFsc2UsIHRydWUsIFhTQ29uc3RhbnRzLkRVUkFUSU9OX0RUKTsKLSAgICAgICAgYnVpbHRJblR5cGVzLnB1dChEVVJBVElPTiwgZHVyYXRpb25EVik7Ci0KLSAgICAgICAgYnVpbHRJblR5cGVzLnB1dChEQVRFVElNRSwgbmV3IFhTU2ltcGxlVHlwZURlY2woYmFzZUF0b21pY1R5cGUsIERBVEVUSU1FLCBYU1NpbXBsZVR5cGVEZWNsLkRWX0RBVEVUSU1FLCBYU1NpbXBsZVR5cGUuT1JERVJFRF9QQVJUSUFMLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCB0cnVlLCBYU0NvbnN0YW50cy5EQVRFVElNRV9EVCkpOwotICAgICAgICBidWlsdEluVHlwZXMucHV0KFRJTUUsIG5ldyBYU1NpbXBsZVR5cGVEZWNsKGJhc2VBdG9taWNUeXBlLCBUSU1FLCBYU1NpbXBsZVR5cGVEZWNsLkRWX1RJTUUsIFhTU2ltcGxlVHlwZS5PUkRFUkVEX1BBUlRJQUwsIGZhbHNlLCBmYWxzZSwgZmFsc2UsIHRydWUsIFhTQ29uc3RhbnRzLlRJTUVfRFQpKTsKLSAgICAgICAgYnVpbHRJblR5cGVzLnB1dChEQVRFLCBuZXcgWFNTaW1wbGVUeXBlRGVjbChiYXNlQXRvbWljVHlwZSwgREFURSwgWFNTaW1wbGVUeXBlRGVjbC5EVl9EQVRFLCBYU1NpbXBsZVR5cGUuT1JERVJFRF9QQVJUSUFMLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCB0cnVlLCBYU0NvbnN0YW50cy5EQVRFX0RUKSk7Ci0gICAgICAgIGJ1aWx0SW5UeXBlcy5wdXQoWUVBUk1PTlRILCBuZXcgWFNTaW1wbGVUeXBlRGVjbChiYXNlQXRvbWljVHlwZSwgWUVBUk1PTlRILCBYU1NpbXBsZVR5cGVEZWNsLkRWX0dZRUFSTU9OVEgsIFhTU2ltcGxlVHlwZS5PUkRFUkVEX1BBUlRJQUwsIGZhbHNlLCBmYWxzZSwgZmFsc2UsIHRydWUsIFhTQ29uc3RhbnRzLkdZRUFSTU9OVEhfRFQpKTsKLSAgICAgICAgYnVpbHRJblR5cGVzLnB1dChZRUFSLCBuZXcgWFNTaW1wbGVUeXBlRGVjbChiYXNlQXRvbWljVHlwZSwgWUVBUiwgWFNTaW1wbGVUeXBlRGVjbC5EVl9HWUVBUiwgWFNTaW1wbGVUeXBlLk9SREVSRURfUEFSVElBTCwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgdHJ1ZSwgWFNDb25zdGFudHMuR1lFQVJfRFQpKTsKLSAgICAgICAgYnVpbHRJblR5cGVzLnB1dChNT05USERBWSwgbmV3IFhTU2ltcGxlVHlwZURlY2woYmFzZUF0b21pY1R5cGUsIE1PTlRIREFZLCBYU1NpbXBsZVR5cGVEZWNsLkRWX0dNT05USERBWSwgWFNTaW1wbGVUeXBlLk9SREVSRURfUEFSVElBTCwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgdHJ1ZSwgWFNDb25zdGFudHMuR01PTlRIREFZX0RUKSk7Ci0gICAgICAgIGJ1aWx0SW5UeXBlcy5wdXQoREFZLCBuZXcgWFNTaW1wbGVUeXBlRGVjbChiYXNlQXRvbWljVHlwZSwgREFZLCBYU1NpbXBsZVR5cGVEZWNsLkRWX0dEQVksIFhTU2ltcGxlVHlwZS5PUkRFUkVEX1BBUlRJQUwsIGZhbHNlLCBmYWxzZSwgZmFsc2UsIHRydWUsIFhTQ29uc3RhbnRzLkdEQVlfRFQpKTsKLSAgICAgICAgYnVpbHRJblR5cGVzLnB1dChNT05USCwgbmV3IFhTU2ltcGxlVHlwZURlY2woYmFzZUF0b21pY1R5cGUsIE1PTlRILCBYU1NpbXBsZVR5cGVEZWNsLkRWX0dNT05USCwgWFNTaW1wbGVUeXBlLk9SREVSRURfUEFSVElBTCwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgdHJ1ZSwgWFNDb25zdGFudHMuR01PTlRIX0RUKSk7Ci0KLSAgICAgICAgWFNTaW1wbGVUeXBlRGVjbCBpbnRlZ2VyRFYgPSBuZXcgWFNTaW1wbGVUeXBlRGVjbChkZWNpbWFsRFYsIElOVEVHRVIsIFhTU2ltcGxlVHlwZURlY2wuRFZfSU5URUdFUiwgWFNTaW1wbGVUeXBlLk9SREVSRURfVE9UQUwsIGZhbHNlLCBmYWxzZSwgdHJ1ZSwgdHJ1ZSwgWFNDb25zdGFudHMuSU5URUdFUl9EVCk7Ci0gICAgICAgIGJ1aWx0SW5UeXBlcy5wdXQoSU5URUdFUiwgaW50ZWdlckRWKTsKLQotICAgICAgICBmYWNldHMubWF4SW5jbHVzaXZlID0gIjAiOwotICAgICAgICBYU1NpbXBsZVR5cGVEZWNsIG5vblBvc2l0aXZlRFYgPSBuZXcgWFNTaW1wbGVUeXBlRGVjbChpbnRlZ2VyRFYsIE5PTlBPU0lUSVZFSU5URUdFUiwgVVJJX1NDSEVNQUZPUlNDSEVNQSwgKHNob3J0KTAsIGZhbHNlLCBudWxsLCBYU0NvbnN0YW50cy5OT05QT1NJVElWRUlOVEVHRVJfRFQpOwotICAgICAgICBub25Qb3NpdGl2ZURWLmFwcGx5RmFjZXRzMShmYWNldHMgLCBYU1NpbXBsZVR5cGUuRkFDRVRfTUFYSU5DTFVTSVZFLCAoc2hvcnQpMCk7Ci0gICAgICAgIGJ1aWx0SW5UeXBlcy5wdXQoTk9OUE9TSVRJVkVJTlRFR0VSLCBub25Qb3NpdGl2ZURWKTsKLQotICAgICAgICBmYWNldHMubWF4SW5jbHVzaXZlID0gIi0xIjsKLSAgICAgICAgWFNTaW1wbGVUeXBlRGVjbCBuZWdhdGl2ZURWID0gbmV3IFhTU2ltcGxlVHlwZURlY2wobm9uUG9zaXRpdmVEViwgTkVHQVRJVkVJTlRFR0VSLCBVUklfU0NIRU1BRk9SU0NIRU1BLCAoc2hvcnQpMCwgZmFsc2UsIG51bGwsIFhTQ29uc3RhbnRzLk5FR0FUSVZFSU5URUdFUl9EVCk7Ci0gICAgICAgIG5lZ2F0aXZlRFYuYXBwbHlGYWNldHMxKGZhY2V0cyAsIFhTU2ltcGxlVHlwZS5GQUNFVF9NQVhJTkNMVVNJVkUsIChzaG9ydCkwKTsKLSAgICAgICAgYnVpbHRJblR5cGVzLnB1dChORUdBVElWRUlOVEVHRVIsIG5lZ2F0aXZlRFYpOwotCi0gICAgICAgIGZhY2V0cy5tYXhJbmNsdXNpdmUgPSAiOTIyMzM3MjAzNjg1NDc3NTgwNyI7Ci0gICAgICAgIGZhY2V0cy5taW5JbmNsdXNpdmUgPSAiLTkyMjMzNzIwMzY4NTQ3NzU4MDgiOwotICAgICAgICBYU1NpbXBsZVR5cGVEZWNsIGxvbmdEViA9IG5ldyBYU1NpbXBsZVR5cGVEZWNsKGludGVnZXJEViwgTE9ORywgVVJJX1NDSEVNQUZPUlNDSEVNQSwgKHNob3J0KTAsIGZhbHNlLCBudWxsLCBYU0NvbnN0YW50cy5MT05HX0RUKTsKLSAgICAgICAgbG9uZ0RWLmFwcGx5RmFjZXRzMShmYWNldHMgLCAoc2hvcnQpKFhTU2ltcGxlVHlwZS5GQUNFVF9NQVhJTkNMVVNJVkUgfCBYU1NpbXBsZVR5cGUuRkFDRVRfTUlOSU5DTFVTSVZFKSwgKHNob3J0KTAgKTsKLSAgICAgICAgYnVpbHRJblR5cGVzLnB1dChMT05HLCBsb25nRFYpOwotCi0gICAgICAgIGZhY2V0cy5tYXhJbmNsdXNpdmUgPSAiMjE0NzQ4MzY0NyI7Ci0gICAgICAgIGZhY2V0cy5taW5JbmNsdXNpdmUgPSAgIi0yMTQ3NDgzNjQ4IjsKLSAgICAgICAgWFNTaW1wbGVUeXBlRGVjbCBpbnREViA9IG5ldyBYU1NpbXBsZVR5cGVEZWNsKGxvbmdEViwgSU5ULCBVUklfU0NIRU1BRk9SU0NIRU1BLCAoc2hvcnQpMCwgZmFsc2UsIG51bGwsIFhTQ29uc3RhbnRzLklOVF9EVCk7Ci0gICAgICAgIGludERWLmFwcGx5RmFjZXRzMShmYWNldHMsIChzaG9ydCkoWFNTaW1wbGVUeXBlLkZBQ0VUX01BWElOQ0xVU0lWRSB8IFhTU2ltcGxlVHlwZS5GQUNFVF9NSU5JTkNMVVNJVkUpLCAoc2hvcnQpMCApOwotICAgICAgICBidWlsdEluVHlwZXMucHV0KElOVCwgaW50RFYpOwotCi0gICAgICAgIGZhY2V0cy5tYXhJbmNsdXNpdmUgPSAiMzI3NjciOwotICAgICAgICBmYWNldHMubWluSW5jbHVzaXZlID0gIi0zMjc2OCI7Ci0gICAgICAgIFhTU2ltcGxlVHlwZURlY2wgc2hvcnREViA9IG5ldyBYU1NpbXBsZVR5cGVEZWNsKGludERWLCBTSE9SVCAsIFVSSV9TQ0hFTUFGT1JTQ0hFTUEsIChzaG9ydCkwLCBmYWxzZSwgbnVsbCwgWFNDb25zdGFudHMuU0hPUlRfRFQpOwotICAgICAgICBzaG9ydERWLmFwcGx5RmFjZXRzMShmYWNldHMsIChzaG9ydCkoWFNTaW1wbGVUeXBlLkZBQ0VUX01BWElOQ0xVU0lWRSB8IFhTU2ltcGxlVHlwZS5GQUNFVF9NSU5JTkNMVVNJVkUpLCAoc2hvcnQpMCApOwotICAgICAgICBidWlsdEluVHlwZXMucHV0KFNIT1JULCBzaG9ydERWKTsKLQotICAgICAgICBmYWNldHMubWF4SW5jbHVzaXZlID0gIjEyNyI7Ci0gICAgICAgIGZhY2V0cy5taW5JbmNsdXNpdmUgPSAiLTEyOCI7Ci0gICAgICAgIFhTU2ltcGxlVHlwZURlY2wgYnl0ZURWID0gbmV3IFhTU2ltcGxlVHlwZURlY2woc2hvcnREViwgQllURSAsIFVSSV9TQ0hFTUFGT1JTQ0hFTUEsIChzaG9ydCkwLCBmYWxzZSwgbnVsbCwgWFNDb25zdGFudHMuQllURV9EVCk7Ci0gICAgICAgIGJ5dGVEVi5hcHBseUZhY2V0czEoZmFjZXRzLCAoc2hvcnQpKFhTU2ltcGxlVHlwZS5GQUNFVF9NQVhJTkNMVVNJVkUgfCBYU1NpbXBsZVR5cGUuRkFDRVRfTUlOSU5DTFVTSVZFKSwgKHNob3J0KTAgKTsKLSAgICAgICAgYnVpbHRJblR5cGVzLnB1dChCWVRFLCBieXRlRFYpOwotCi0gICAgICAgIGZhY2V0cy5taW5JbmNsdXNpdmUgPSAgIjAiIDsKLSAgICAgICAgWFNTaW1wbGVUeXBlRGVjbCBub25OZWdhdGl2ZURWID0gbmV3IFhTU2ltcGxlVHlwZURlY2woaW50ZWdlckRWLCBOT05ORUdBVElWRUlOVEVHRVIgLCBVUklfU0NIRU1BRk9SU0NIRU1BLCAoc2hvcnQpMCwgZmFsc2UsIG51bGwsIFhTQ29uc3RhbnRzLk5PTk5FR0FUSVZFSU5URUdFUl9EVCk7Ci0gICAgICAgIG5vbk5lZ2F0aXZlRFYuYXBwbHlGYWNldHMxKGZhY2V0cywgWFNTaW1wbGVUeXBlLkZBQ0VUX01JTklOQ0xVU0lWRSwgKHNob3J0KTAgKTsKLSAgICAgICAgYnVpbHRJblR5cGVzLnB1dChOT05ORUdBVElWRUlOVEVHRVIsIG5vbk5lZ2F0aXZlRFYpOwotCi0gICAgICAgIGZhY2V0cy5tYXhJbmNsdXNpdmUgPSAiMTg0NDY3NDQwNzM3MDk1NTE2MTUiIDsKLSAgICAgICAgWFNTaW1wbGVUeXBlRGVjbCB1bnNpZ25lZExvbmdEViA9IG5ldyBYU1NpbXBsZVR5cGVEZWNsKG5vbk5lZ2F0aXZlRFYsIFVOU0lHTkVETE9ORyAsIFVSSV9TQ0hFTUFGT1JTQ0hFTUEsIChzaG9ydCkwLCBmYWxzZSwgbnVsbCwgWFNDb25zdGFudHMuVU5TSUdORURMT05HX0RUKTsKLSAgICAgICAgdW5zaWduZWRMb25nRFYuYXBwbHlGYWNldHMxKGZhY2V0cywgWFNTaW1wbGVUeXBlLkZBQ0VUX01BWElOQ0xVU0lWRSwgKHNob3J0KTAgKTsKLSAgICAgICAgYnVpbHRJblR5cGVzLnB1dChVTlNJR05FRExPTkcsIHVuc2lnbmVkTG9uZ0RWKTsKLQotICAgICAgICBmYWNldHMubWF4SW5jbHVzaXZlID0gIjQyOTQ5NjcyOTUiIDsKLSAgICAgICAgWFNTaW1wbGVUeXBlRGVjbCB1bnNpZ25lZEludERWID0gbmV3IFhTU2ltcGxlVHlwZURlY2wodW5zaWduZWRMb25nRFYsIFVOU0lHTkVESU5UICwgVVJJX1NDSEVNQUZPUlNDSEVNQSwgKHNob3J0KTAsIGZhbHNlLCBudWxsLCBYU0NvbnN0YW50cy5VTlNJR05FRElOVF9EVCk7Ci0gICAgICAgIHVuc2lnbmVkSW50RFYuYXBwbHlGYWNldHMxKGZhY2V0cywgWFNTaW1wbGVUeXBlLkZBQ0VUX01BWElOQ0xVU0lWRSwgKHNob3J0KTAgKTsKLSAgICAgICAgYnVpbHRJblR5cGVzLnB1dChVTlNJR05FRElOVCwgdW5zaWduZWRJbnREVik7Ci0KLSAgICAgICAgZmFjZXRzLm1heEluY2x1c2l2ZSA9ICI2NTUzNSIgOwotICAgICAgICBYU1NpbXBsZVR5cGVEZWNsIHVuc2lnbmVkU2hvcnREViA9IG5ldyBYU1NpbXBsZVR5cGVEZWNsKHVuc2lnbmVkSW50RFYsIFVOU0lHTkVEU0hPUlQgLCBVUklfU0NIRU1BRk9SU0NIRU1BLCAoc2hvcnQpMCwgZmFsc2UsIG51bGwsIFhTQ29uc3RhbnRzLlVOU0lHTkVEU0hPUlRfRFQpOwotICAgICAgICB1bnNpZ25lZFNob3J0RFYuYXBwbHlGYWNldHMxKGZhY2V0cywgWFNTaW1wbGVUeXBlLkZBQ0VUX01BWElOQ0xVU0lWRSwgKHNob3J0KTAgKTsKLSAgICAgICAgYnVpbHRJblR5cGVzLnB1dChVTlNJR05FRFNIT1JULCB1bnNpZ25lZFNob3J0RFYpOwotCi0gICAgICAgIGZhY2V0cy5tYXhJbmNsdXNpdmUgPSAiMjU1IiA7Ci0gICAgICAgIFhTU2ltcGxlVHlwZURlY2wgdW5zaWduZWRCeXRlRFYgPSBuZXcgWFNTaW1wbGVUeXBlRGVjbCh1bnNpZ25lZFNob3J0RFYsIFVOU0lHTkVEQllURSAsIFVSSV9TQ0hFTUFGT1JTQ0hFTUEsIChzaG9ydCkwLCBmYWxzZSwgbnVsbCwgWFNDb25zdGFudHMuVU5TSUdORURCWVRFX0RUKTsKLSAgICAgICAgdW5zaWduZWRCeXRlRFYuYXBwbHlGYWNldHMxKGZhY2V0cywgWFNTaW1wbGVUeXBlLkZBQ0VUX01BWElOQ0xVU0lWRSwgKHNob3J0KTAgKTsKLSAgICAgICAgYnVpbHRJblR5cGVzLnB1dChVTlNJR05FREJZVEUsIHVuc2lnbmVkQnl0ZURWKTsKLQotICAgICAgICBmYWNldHMubWluSW5jbHVzaXZlID0gIjEiIDsKLSAgICAgICAgWFNTaW1wbGVUeXBlRGVjbCBwb3NpdGl2ZUludGVnZXJEViA9IG5ldyBYU1NpbXBsZVR5cGVEZWNsKG5vbk5lZ2F0aXZlRFYsIFBPU0lUSVZFSU5URUdFUiAsIFVSSV9TQ0hFTUFGT1JTQ0hFTUEsIChzaG9ydCkwLCBmYWxzZSwgbnVsbCwgWFNDb25zdGFudHMuUE9TSVRJVkVJTlRFR0VSX0RUKTsKLSAgICAgICAgcG9zaXRpdmVJbnRlZ2VyRFYuYXBwbHlGYWNldHMxKGZhY2V0cywgWFNTaW1wbGVUeXBlLkZBQ0VUX01JTklOQ0xVU0lWRSwgKHNob3J0KTAgKTsKLSAgICAgICAgYnVpbHRJblR5cGVzLnB1dChQT1NJVElWRUlOVEVHRVIsIHBvc2l0aXZlSW50ZWdlckRWKTsKLQotICAgICAgICBidWlsdEluVHlwZXMucHV0KEZMT0FULCBuZXcgWFNTaW1wbGVUeXBlRGVjbChiYXNlQXRvbWljVHlwZSwgRkxPQVQsIFhTU2ltcGxlVHlwZURlY2wuRFZfRkxPQVQsIFhTU2ltcGxlVHlwZS5PUkRFUkVEX1BBUlRJQUwsIHRydWUsIHRydWUsIHRydWUsIHRydWUsIFhTQ29uc3RhbnRzLkZMT0FUX0RUKSk7Ci0gICAgICAgIGJ1aWx0SW5UeXBlcy5wdXQoRE9VQkxFLCBuZXcgWFNTaW1wbGVUeXBlRGVjbChiYXNlQXRvbWljVHlwZSwgRE9VQkxFLCBYU1NpbXBsZVR5cGVEZWNsLkRWX0RPVUJMRSwgWFNTaW1wbGVUeXBlLk9SREVSRURfUEFSVElBTCwgdHJ1ZSwgdHJ1ZSwgdHJ1ZSwgdHJ1ZSwgWFNDb25zdGFudHMuRE9VQkxFX0RUKSk7Ci0gICAgICAgIGJ1aWx0SW5UeXBlcy5wdXQoSEVYQklOQVJZLCBuZXcgWFNTaW1wbGVUeXBlRGVjbChiYXNlQXRvbWljVHlwZSwgSEVYQklOQVJZLCBYU1NpbXBsZVR5cGVEZWNsLkRWX0hFWEJJTkFSWSwgWFNTaW1wbGVUeXBlLk9SREVSRURfRkFMU0UsIGZhbHNlLCBmYWxzZSwgZmFsc2UsIHRydWUsIFhTQ29uc3RhbnRzLkhFWEJJTkFSWV9EVCkpOwotICAgICAgICBidWlsdEluVHlwZXMucHV0KE5PVEFUSU9OLCBuZXcgWFNTaW1wbGVUeXBlRGVjbChiYXNlQXRvbWljVHlwZSwgTk9UQVRJT04sIFhTU2ltcGxlVHlwZURlY2wuRFZfTk9UQVRJT04sIFhTU2ltcGxlVHlwZS5PUkRFUkVEX0ZBTFNFLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCB0cnVlLCBYU0NvbnN0YW50cy5OT1RBVElPTl9EVCkpOwotCi0gICAgICAgIGZhY2V0cy53aGl0ZVNwYWNlID0gIFhTU2ltcGxlVHlwZS5XU19SRVBMQUNFOwotICAgICAgICBYU1NpbXBsZVR5cGVEZWNsIG5vcm1hbGl6ZWREViA9IG5ldyBYU1NpbXBsZVR5cGVEZWNsKHN0cmluZ0RWLCBOT1JNQUxJWkVEU1RSSU5HICwgVVJJX1NDSEVNQUZPUlNDSEVNQSwgKHNob3J0KTAsIGZhbHNlLCBudWxsLCBYU0NvbnN0YW50cy5OT1JNQUxJWkVEU1RSSU5HX0RUKTsKLSAgICAgICAgbm9ybWFsaXplZERWLmFwcGx5RmFjZXRzMShmYWNldHMsIFhTU2ltcGxlVHlwZS5GQUNFVF9XSElURVNQQUNFLCAoc2hvcnQpMCApOwotICAgICAgICBidWlsdEluVHlwZXMucHV0KE5PUk1BTElaRURTVFJJTkcsIG5vcm1hbGl6ZWREVik7Ci0KLSAgICAgICAgZmFjZXRzLndoaXRlU3BhY2UgPSBYU1NpbXBsZVR5cGUuV1NfQ09MTEFQU0U7Ci0gICAgICAgIFhTU2ltcGxlVHlwZURlY2wgdG9rZW5EViA9IG5ldyBYU1NpbXBsZVR5cGVEZWNsKG5vcm1hbGl6ZWREViwgVE9LRU4gLCBVUklfU0NIRU1BRk9SU0NIRU1BLCAoc2hvcnQpMCwgZmFsc2UsIG51bGwsIFhTQ29uc3RhbnRzLlRPS0VOX0RUKTsKLSAgICAgICAgdG9rZW5EVi5hcHBseUZhY2V0czEoZmFjZXRzLCBYU1NpbXBsZVR5cGUuRkFDRVRfV0hJVEVTUEFDRSwgKHNob3J0KTAgKTsKLSAgICAgICAgYnVpbHRJblR5cGVzLnB1dChUT0tFTiwgdG9rZW5EVik7Ci0KLSAgICAgICAgZmFjZXRzLndoaXRlU3BhY2UgPSBYU1NpbXBsZVR5cGUuV1NfQ09MTEFQU0U7Ci0gICAgICAgIGZhY2V0cy5wYXR0ZXJuICA9ICIoW2EtekEtWl17MSw4fSkoLVthLXpBLVowLTldezEsOH0pKiI7Ci0gICAgICAgIFhTU2ltcGxlVHlwZURlY2wgbGFuZ3VhZ2VEViA9IG5ldyBYU1NpbXBsZVR5cGVEZWNsKHRva2VuRFYsIExBTkdVQUdFICwgVVJJX1NDSEVNQUZPUlNDSEVNQSwgKHNob3J0KTAsIGZhbHNlLCBudWxsLCBYU0NvbnN0YW50cy5MQU5HVUFHRV9EVCk7Ci0gICAgICAgIGxhbmd1YWdlRFYuYXBwbHlGYWNldHMxKGZhY2V0cywgKHNob3J0KShYU1NpbXBsZVR5cGUuRkFDRVRfV0hJVEVTUEFDRSB8IFhTU2ltcGxlVHlwZS5GQUNFVF9QQVRURVJOKSAsKHNob3J0KTApOwotICAgICAgICBidWlsdEluVHlwZXMucHV0KExBTkdVQUdFLCBsYW5ndWFnZURWKTsKLQotICAgICAgICBmYWNldHMud2hpdGVTcGFjZSA9ICBYU1NpbXBsZVR5cGUuV1NfQ09MTEFQU0U7Ci0gICAgICAgIFhTU2ltcGxlVHlwZURlY2wgbmFtZURWID0gbmV3IFhTU2ltcGxlVHlwZURlY2wodG9rZW5EViwgTkFNRSAsIFVSSV9TQ0hFTUFGT1JTQ0hFTUEsIChzaG9ydCkwLCBmYWxzZSwgbnVsbCwgWFNDb25zdGFudHMuTkFNRV9EVCk7Ci0gICAgICAgIG5hbWVEVi5hcHBseUZhY2V0czEoZmFjZXRzLCBYU1NpbXBsZVR5cGUuRkFDRVRfV0hJVEVTUEFDRSwgKHNob3J0KTAsIFhTU2ltcGxlVHlwZURlY2wuU1BFQ0lBTF9QQVRURVJOX05BTUUpOwotICAgICAgICBidWlsdEluVHlwZXMucHV0KE5BTUUsIG5hbWVEVik7Ci0KLSAgICAgICAgZmFjZXRzLndoaXRlU3BhY2UgPSBYU1NpbXBsZVR5cGUuV1NfQ09MTEFQU0U7Ci0gICAgICAgIFhTU2ltcGxlVHlwZURlY2wgbmNuYW1lRFYgPSBuZXcgWFNTaW1wbGVUeXBlRGVjbChuYW1lRFYsIE5DTkFNRSAsIFVSSV9TQ0hFTUFGT1JTQ0hFTUEsIChzaG9ydCkwLCBmYWxzZSwgbnVsbCwgWFNDb25zdGFudHMuTkNOQU1FX0RUKSA7Ci0gICAgICAgIG5jbmFtZURWLmFwcGx5RmFjZXRzMShmYWNldHMsIFhTU2ltcGxlVHlwZS5GQUNFVF9XSElURVNQQUNFLCAoc2hvcnQpMCwgWFNTaW1wbGVUeXBlRGVjbC5TUEVDSUFMX1BBVFRFUk5fTkNOQU1FKTsKLSAgICAgICAgYnVpbHRJblR5cGVzLnB1dChOQ05BTUUsIG5jbmFtZURWKTsKLQotICAgICAgICBidWlsdEluVHlwZXMucHV0KFFOQU1FLCBuZXcgWFNTaW1wbGVUeXBlRGVjbChiYXNlQXRvbWljVHlwZSwgUU5BTUUsIFhTU2ltcGxlVHlwZURlY2wuRFZfUU5BTUUsIFhTU2ltcGxlVHlwZS5PUkRFUkVEX0ZBTFNFLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCB0cnVlLCBYU0NvbnN0YW50cy5RTkFNRV9EVCkpOwotCi0gICAgICAgIGJ1aWx0SW5UeXBlcy5wdXQoSUQsIG5ldyBYU1NpbXBsZVR5cGVEZWNsKG5jbmFtZURWLCAgSUQsIFhTU2ltcGxlVHlwZURlY2wuRFZfSUQsIFhTU2ltcGxlVHlwZS5PUkRFUkVEX0ZBTFNFLCBmYWxzZSwgZmFsc2UsIGZhbHNlICwgdHJ1ZSwgWFNDb25zdGFudHMuSURfRFQpKTsKLSAgICAgICAgWFNTaW1wbGVUeXBlRGVjbCBpZHJlZkRWID0gbmV3IFhTU2ltcGxlVHlwZURlY2wobmNuYW1lRFYsICBJRFJFRiAsIFhTU2ltcGxlVHlwZURlY2wuRFZfSURSRUYsIFhTU2ltcGxlVHlwZS5PUkRFUkVEX0ZBTFNFLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCB0cnVlLCBYU0NvbnN0YW50cy5JRFJFRl9EVCk7Ci0gICAgICAgIGJ1aWx0SW5UeXBlcy5wdXQoSURSRUYsIGlkcmVmRFYpOwotCi0gICAgICAgIGZhY2V0cy5taW5MZW5ndGggPSAxOwotICAgICAgICBYU1NpbXBsZVR5cGVEZWNsIHRlbXBEViA9IG5ldyBYU1NpbXBsZVR5cGVEZWNsKG51bGwsIFVSSV9TQ0hFTUFGT1JTQ0hFTUEsIChzaG9ydCkwLCBpZHJlZkRWLCB0cnVlLCBudWxsKTsKLSAgICAgICAgWFNTaW1wbGVUeXBlRGVjbCBpZHJlZnNEViA9IG5ldyBYU1NpbXBsZVR5cGVEZWNsKHRlbXBEViwgSURSRUZTLCBVUklfU0NIRU1BRk9SU0NIRU1BLCAoc2hvcnQpMCwgZmFsc2UsIG51bGwpOwotICAgICAgICBpZHJlZnNEVi5hcHBseUZhY2V0czEoZmFjZXRzLCBYU1NpbXBsZVR5cGUuRkFDRVRfTUlOTEVOR1RILCAoc2hvcnQpMCk7Ci0gICAgICAgIGJ1aWx0SW5UeXBlcy5wdXQoSURSRUZTLCBpZHJlZnNEVik7Ci0KLSAgICAgICAgWFNTaW1wbGVUeXBlRGVjbCBlbnRpdHlEViA9IG5ldyBYU1NpbXBsZVR5cGVEZWNsKG5jbmFtZURWLCBFTlRJVFkgLCBYU1NpbXBsZVR5cGVEZWNsLkRWX0VOVElUWSwgWFNTaW1wbGVUeXBlLk9SREVSRURfRkFMU0UsIGZhbHNlLCBmYWxzZSwgZmFsc2UsIHRydWUsIFhTQ29uc3RhbnRzLkVOVElUWV9EVCk7Ci0gICAgICAgIGJ1aWx0SW5UeXBlcy5wdXQoRU5USVRZLCBlbnRpdHlEVik7Ci0KLSAgICAgICAgZmFjZXRzLm1pbkxlbmd0aCA9IDE7Ci0gICAgICAgIHRlbXBEViA9IG5ldyBYU1NpbXBsZVR5cGVEZWNsKG51bGwsIFVSSV9TQ0hFTUFGT1JTQ0hFTUEsIChzaG9ydCkwLCBlbnRpdHlEViwgdHJ1ZSwgbnVsbCk7Ci0gICAgICAgIFhTU2ltcGxlVHlwZURlY2wgZW50aXRpZXNEViA9IG5ldyBYU1NpbXBsZVR5cGVEZWNsKHRlbXBEViwgRU5USVRJRVMsIFVSSV9TQ0hFTUFGT1JTQ0hFTUEsIChzaG9ydCkwLCBmYWxzZSwgbnVsbCk7Ci0gICAgICAgIGVudGl0aWVzRFYuYXBwbHlGYWNldHMxKGZhY2V0cywgWFNTaW1wbGVUeXBlLkZBQ0VUX01JTkxFTkdUSCwgKHNob3J0KTApOwotICAgICAgICBidWlsdEluVHlwZXMucHV0KEVOVElUSUVTLCBlbnRpdGllc0RWKTsKLQotICAgICAgICBmYWNldHMud2hpdGVTcGFjZSAgPSBYU1NpbXBsZVR5cGUuV1NfQ09MTEFQU0U7Ci0gICAgICAgIFhTU2ltcGxlVHlwZURlY2wgbm10b2tlbkRWID0gbmV3IFhTU2ltcGxlVHlwZURlY2wodG9rZW5EViwgTk1UT0tFTiwgVVJJX1NDSEVNQUZPUlNDSEVNQSwgKHNob3J0KTAsIGZhbHNlLCBudWxsLCBYU0NvbnN0YW50cy5OTVRPS0VOX0RUKTsKLSAgICAgICAgbm10b2tlbkRWLmFwcGx5RmFjZXRzMShmYWNldHMsIFhTU2ltcGxlVHlwZS5GQUNFVF9XSElURVNQQUNFLCAoc2hvcnQpMCwgWFNTaW1wbGVUeXBlRGVjbC5TUEVDSUFMX1BBVFRFUk5fTk1UT0tFTik7Ci0gICAgICAgIGJ1aWx0SW5UeXBlcy5wdXQoTk1UT0tFTiwgbm10b2tlbkRWKTsKLQotICAgICAgICBmYWNldHMubWluTGVuZ3RoID0gMTsKLSAgICAgICAgdGVtcERWID0gbmV3IFhTU2ltcGxlVHlwZURlY2wobnVsbCwgVVJJX1NDSEVNQUZPUlNDSEVNQSwgKHNob3J0KTAsIG5tdG9rZW5EViwgdHJ1ZSwgbnVsbCk7Ci0gICAgICAgIFhTU2ltcGxlVHlwZURlY2wgbm10b2tlbnNEViA9IG5ldyBYU1NpbXBsZVR5cGVEZWNsKHRlbXBEViwgTk1UT0tFTlMsIFVSSV9TQ0hFTUFGT1JTQ0hFTUEsIChzaG9ydCkwLCBmYWxzZSwgbnVsbCk7Ci0gICAgICAgIG5tdG9rZW5zRFYuYXBwbHlGYWNldHMxKGZhY2V0cywgWFNTaW1wbGVUeXBlLkZBQ0VUX01JTkxFTkdUSCwgKHNob3J0KTApOwotICAgICAgICBidWlsdEluVHlwZXMucHV0KE5NVE9LRU5TLCBubXRva2Vuc0RWKTsKLSAgICB9IC8vY3JlYXRlQnVpbHRJblR5cGVzKCkKLQotICAgIC8qKgotICAgICAqIENyZWF0ZSBhIG5ldyBzaW1wbGUgdHlwZSB3aGljaCBpcyBkZXJpdmVkIGJ5IHJlc3RyaWN0aW9uIGZyb20gYW5vdGhlcgotICAgICAqIHNpbXBsZSB0eXBlLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgICAgICAgICAgICAgIG5hbWUgb2YgdGhlIG5ldyB0eXBlLCBjb3VsZCBiZSBudWxsCi0gICAgICogQHBhcmFtIHRhcmdldE5hbWVzcGFjZSAgIHRhcmdldCBuYW1lc3BhY2Ugb2YgdGhlIG5ldyB0eXBlLCBjb3VsZCBiZSBudWxsCi0gICAgICogQHBhcmFtIGZpbmFsU2V0ICAgICAgICAgIHZhbHVlIG9mICJmaW5hbCIKLSAgICAgKiBAcGFyYW0gYmFzZSAgICAgICAgICAgICAgYmFzZSB0eXBlIG9mIHRoZSBuZXcgdHlwZQotICAgICAqIEBwYXJhbSBhbm5vdGF0aW9ucyAgICAgICBzZXQgb2YgYW5ub3RhdGlvbnMKLSAgICAgKiBAcmV0dXJuICAgICAgICAgICAgICAgICAgdGhlIG5ld2x5IGNyZWF0ZWQgc2ltcGxlIHR5cGUKLSAgICAgKi8KLSAgICBwdWJsaWMgWFNTaW1wbGVUeXBlIGNyZWF0ZVR5cGVSZXN0cmljdGlvbihTdHJpbmcgbmFtZSwgU3RyaW5nIHRhcmdldE5hbWVzcGFjZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaG9ydCBmaW5hbFNldCwgWFNTaW1wbGVUeXBlIGJhc2UsIFhTT2JqZWN0TGlzdCBhbm5vdGF0aW9ucykgewotCi0gICAgICAgIGlmIChmRGVjbFBvb2wgIT0gbnVsbCkgewotICAgICAgICAgICBYU1NpbXBsZVR5cGVEZWNsIHN0PSBmRGVjbFBvb2wuZ2V0U2ltcGxlVHlwZURlY2woKTsKLSAgICAgICAgICAgcmV0dXJuIHN0LnNldFJlc3RyaWN0aW9uVmFsdWVzKChYU1NpbXBsZVR5cGVEZWNsKWJhc2UsIG5hbWUsIHRhcmdldE5hbWVzcGFjZSwgZmluYWxTZXQsIGFubm90YXRpb25zKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbmV3IFhTU2ltcGxlVHlwZURlY2woKFhTU2ltcGxlVHlwZURlY2wpYmFzZSwgbmFtZSwgdGFyZ2V0TmFtZXNwYWNlLCBmaW5hbFNldCwgZmFsc2UsIGFubm90YXRpb25zKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGUgYSBuZXcgc2ltcGxlIHR5cGUgd2hpY2ggaXMgZGVyaXZlZCBieSBsaXN0IGZyb20gYW5vdGhlciBzaW1wbGUKLSAgICAgKiB0eXBlLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgICAgICAgICAgICAgIG5hbWUgb2YgdGhlIG5ldyB0eXBlLCBjb3VsZCBiZSBudWxsCi0gICAgICogQHBhcmFtIHRhcmdldE5hbWVzcGFjZSAgIHRhcmdldCBuYW1lc3BhY2Ugb2YgdGhlIG5ldyB0eXBlLCBjb3VsZCBiZSBudWxsCi0gICAgICogQHBhcmFtIGZpbmFsU2V0ICAgICAgICAgIHZhbHVlIG9mICJmaW5hbCIKLSAgICAgKiBAcGFyYW0gaXRlbVR5cGUgICAgICAgICAgaXRlbSB0eXBlIG9mIHRoZSBsaXN0IHR5cGUKLSAgICAgKiBAcGFyYW0gYW5ub3RhdGlvbnMgICAgICAgc2V0IG9mIGFubm90YXRpb25zCi0gICAgICogQHJldHVybiAgICAgICAgICAgICAgICAgIHRoZSBuZXdseSBjcmVhdGVkIHNpbXBsZSB0eXBlCi0gICAgICovCi0gICAgcHVibGljIFhTU2ltcGxlVHlwZSBjcmVhdGVUeXBlTGlzdChTdHJpbmcgbmFtZSwgU3RyaW5nIHRhcmdldE5hbWVzcGFjZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNob3J0IGZpbmFsU2V0LCBYU1NpbXBsZVR5cGUgaXRlbVR5cGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYU09iamVjdExpc3QgYW5ub3RhdGlvbnMpIHsKLSAgICAgICAgaWYgKGZEZWNsUG9vbCAhPSBudWxsKSB7Ci0gICAgICAgICAgIFhTU2ltcGxlVHlwZURlY2wgc3Q9IGZEZWNsUG9vbC5nZXRTaW1wbGVUeXBlRGVjbCgpOwotICAgICAgICAgICByZXR1cm4gc3Quc2V0TGlzdFZhbHVlcyhuYW1lLCB0YXJnZXROYW1lc3BhY2UsIGZpbmFsU2V0LCAoWFNTaW1wbGVUeXBlRGVjbClpdGVtVHlwZSwgYW5ub3RhdGlvbnMpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBuZXcgWFNTaW1wbGVUeXBlRGVjbChuYW1lLCB0YXJnZXROYW1lc3BhY2UsIGZpbmFsU2V0LCAoWFNTaW1wbGVUeXBlRGVjbClpdGVtVHlwZSwgZmFsc2UsIGFubm90YXRpb25zKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGUgYSBuZXcgc2ltcGxlIHR5cGUgd2hpY2ggaXMgZGVyaXZlZCBieSB1bmlvbiBmcm9tIGEgbGlzdCBvZiBvdGhlcgotICAgICAqIHNpbXBsZSB0eXBlcy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lICAgICAgICAgICAgICBuYW1lIG9mIHRoZSBuZXcgdHlwZSwgY291bGQgYmUgbnVsbAotICAgICAqIEBwYXJhbSB0YXJnZXROYW1lc3BhY2UgICB0YXJnZXQgbmFtZXNwYWNlIG9mIHRoZSBuZXcgdHlwZSwgY291bGQgYmUgbnVsbAotICAgICAqIEBwYXJhbSBmaW5hbFNldCAgICAgICAgICB2YWx1ZSBvZiAiZmluYWwiCi0gICAgICogQHBhcmFtIG1lbWJlclR5cGVzICAgICAgIG1lbWJlciB0eXBlcyBvZiB0aGUgdW5pb24gdHlwZQotICAgICAqIEBwYXJhbSBhbm5vdGF0aW9ucyAgICAgICBzZXQgb2YgYW5ub3RhdGlvbnMKLSAgICAgKiBAcmV0dXJuICAgICAgICAgICAgICAgICAgdGhlIG5ld2x5IGNyZWF0ZWQgc2ltcGxlIHR5cGUKLSAgICAgKi8KLSAgICBwdWJsaWMgWFNTaW1wbGVUeXBlIGNyZWF0ZVR5cGVVbmlvbihTdHJpbmcgbmFtZSwgU3RyaW5nIHRhcmdldE5hbWVzcGFjZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaG9ydCBmaW5hbFNldCwgWFNTaW1wbGVUeXBlW10gbWVtYmVyVHlwZXMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWFNPYmplY3RMaXN0IGFubm90YXRpb25zKSB7Ci0gICAgICAgIGludCB0eXBlTnVtID0gbWVtYmVyVHlwZXMubGVuZ3RoOwotICAgICAgICBYU1NpbXBsZVR5cGVEZWNsW10gbXR5cGVzID0gbmV3IFhTU2ltcGxlVHlwZURlY2xbdHlwZU51bV07Ci0gICAgICAgIFN5c3RlbS5hcnJheWNvcHkobWVtYmVyVHlwZXMsIDAsIG10eXBlcywgMCwgdHlwZU51bSk7Ci0KLSAgICAgICAgaWYgKGZEZWNsUG9vbCAhPSBudWxsKSB7Ci0gICAgICAgICAgIFhTU2ltcGxlVHlwZURlY2wgc3Q9IGZEZWNsUG9vbC5nZXRTaW1wbGVUeXBlRGVjbCgpOwotICAgICAgICAgICByZXR1cm4gc3Quc2V0VW5pb25WYWx1ZXMobmFtZSwgdGFyZ2V0TmFtZXNwYWNlLCBmaW5hbFNldCwgbXR5cGVzLCBhbm5vdGF0aW9ucyk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG5ldyBYU1NpbXBsZVR5cGVEZWNsKG5hbWUsIHRhcmdldE5hbWVzcGFjZSwgZmluYWxTZXQsIG10eXBlcywgYW5ub3RhdGlvbnMpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldERlY2xQb29sIChYU0RlY2xhcmF0aW9uUG9vbCBkZWNsUG9vbCl7Ci0gICAgICAgIGZEZWNsUG9vbCA9IGRlY2xQb29sOwotICAgIH0KLQotICAgIC8qKiBJbXBsZW1lbnRhdGlvbiBpbnRlcm5hbCAqKi8KLSAgICBwdWJsaWMgWFNTaW1wbGVUeXBlRGVjbCBuZXdYU1NpbXBsZVR5cGVEZWNsKCkgewotICAgICAgICByZXR1cm4gbmV3IFhTU2ltcGxlVHlwZURlY2woKTsKLSAgICB9Ci19IC8vQmFzZVNjaGVtYURWRmFjdG9yeQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi94cy9Cb29sZWFuRFYuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYveHMvQm9vbGVhbkRWLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDkwODU3ZWYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi94cy9Cb29sZWFuRFYuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDU1ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEsIDIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LnhzOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LkludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5WYWxpZGF0aW9uQ29udGV4dDsKLQotLyoqCi0gKiBSZXByZXNlbnQgdGhlIHNjaGVtYSB0eXBlICJib29sZWFuIgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIE5lZXJhaiBCYWphaiwgU3VuIE1pY3Jvc3lzdGVtcywgaW5jLgotICogQGF1dGhvciBTYW5keSBHYW8sIElCTQotICoKLSAqLwotcHVibGljIGNsYXNzIEJvb2xlYW5EViBleHRlbmRzIFR5cGVWYWxpZGF0b3J7Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgZlZhbHVlU3BhY2VbXSA9IHsiZmFsc2UiLCAidHJ1ZSIsICIwIiwgIjEifTsKLQotICAgIHB1YmxpYyBzaG9ydCBnZXRBbGxvd2VkRmFjZXRzKCl7Ci0gICAgICAgIHJldHVybiAoWFNTaW1wbGVUeXBlRGVjbC5GQUNFVF9QQVRURVJOIHwgWFNTaW1wbGVUeXBlRGVjbC5GQUNFVF9XSElURVNQQUNFKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgT2JqZWN0IGdldEFjdHVhbFZhbHVlKFN0cmluZyBjb250ZW50LCBWYWxpZGF0aW9uQ29udGV4dCBjb250ZXh0KSB0aHJvd3MgSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24gewotICAgICAgICBCb29sZWFuIHJldCA9IG51bGw7Ci0KLSAgICAgICAgaWYgKGNvbnRlbnQuZXF1YWxzKGZWYWx1ZVNwYWNlWzBdKSB8fCBjb250ZW50LmVxdWFscyhmVmFsdWVTcGFjZVsyXSkpCi0gICAgICAgICAgICByZXQgPSBCb29sZWFuLkZBTFNFOwotICAgICAgICBlbHNlIGlmIChjb250ZW50LmVxdWFscyhmVmFsdWVTcGFjZVsxXSkgfHwgY29udGVudC5lcXVhbHMoZlZhbHVlU3BhY2VbM10pKQotICAgICAgICAgICAgcmV0ID0gQm9vbGVhbi5UUlVFOwotICAgICAgICBlbHNlCi0gICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24oImN2Yy1kYXRhdHlwZS12YWxpZC4xLjIuMSIsIG5ldyBPYmplY3RbXXtjb250ZW50LCAiYm9vbGVhbiJ9KTsKLSAgICAgICAgcmV0dXJuIHJldDsKLSAgICB9Ci0KLX0gLy8gY2xhc3MgQm9vbGVhbkRWCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L3hzL0RhdGVEVi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi94cy9EYXRlRFYuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDFiMGVhYi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L3hzL0RhdGVEVi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTUgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDAyLDIwMDQsMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LnhzOwotCi1pbXBvcnQgamF2YXgueG1sLmRhdGF0eXBlLkRhdGF0eXBlQ29uc3RhbnRzOwotaW1wb3J0IGphdmF4LnhtbC5kYXRhdHlwZS5YTUxHcmVnb3JpYW5DYWxlbmRhcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5JbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYuVmFsaWRhdGlvbkNvbnRleHQ7Ci0KLS8qKgotICogVmFsaWRhdG9yIGZvciA8ZGF0ZT4gZGF0YXR5cGUgKFczQyBTY2hlbWEgZGF0YXR5cGVzKQotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIEVsZW5hIExpdGFuaQotICogQGF1dGhvciBHb3BhbCBTaGFybWEsIFNVTiBNaWNyb3N5c3RlbXMgSW5jLgotICoKLSAqIEB2ZXJzaW9uICRJZDogRGF0ZURWLmphdmEsdiAxLjcgMjAxMC0xMS0wMSAwNDozOTo0NiBqb2VodyBFeHAgJAotICovCi1wdWJsaWMgY2xhc3MgRGF0ZURWIGV4dGVuZHMgRGF0ZVRpbWVEViB7Ci0KLSAgICBwdWJsaWMgT2JqZWN0IGdldEFjdHVhbFZhbHVlKFN0cmluZyBjb250ZW50LCBWYWxpZGF0aW9uQ29udGV4dCBjb250ZXh0KSB0aHJvd3MgSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24gewotICAgICAgICB0cnl7Ci0gICAgICAgICAgICByZXR1cm4gcGFyc2UoY29udGVudCk7Ci0gICAgICAgIH0gY2F0Y2goRXhjZXB0aW9uIGV4KXsKLSAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbigiY3ZjLWRhdGF0eXBlLXZhbGlkLjEuMi4xIiwgbmV3IE9iamVjdFtde2NvbnRlbnQsICJkYXRlIn0pOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUGFyc2VzLCB2YWxpZGF0ZXMgYW5kIGNvbXB1dGVzIG5vcm1hbGl6ZWQgdmVyc2lvbiBvZiBkYXRlVGltZSBvYmplY3QKLSAgICAgKgotICAgICAqIEBwYXJhbSBzdHIgICAgVGhlIGxleGljYWwgcmVwcmVzZW50YXRpb24gb2YgZGF0ZVRpbWUgb2JqZWN0IENDWVktTU0tREQKLSAgICAgKiAgICAgICAgICAgICAgIHdpdGggcG9zc2libGUgdGltZSB6b25lIFogb3IgKC0pLCgrKWhoOm1tCi0gICAgICogQHJldHVybiBub3JtYWxpemVkIGRhdGVUaW1lIHJlcHJlc2VudGF0aW9uCi0gICAgICogQGV4Y2VwdGlvbiBTY2hlbWFEYXRlVGltZUV4Y2VwdGlvbiBJbnZhbGlkIGxleGljYWwgcmVwcmVzZW50YXRpb24KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgRGF0ZVRpbWVEYXRhIHBhcnNlKFN0cmluZyBzdHIpIHRocm93cyBTY2hlbWFEYXRlVGltZUV4Y2VwdGlvbiB7Ci0gICAgICAgIERhdGVUaW1lRGF0YSBkYXRlID0gbmV3IERhdGVUaW1lRGF0YShzdHIsIHRoaXMpOwotICAgICAgICBpbnQgbGVuID0gc3RyLmxlbmd0aCgpOwotCi0gICAgICAgIGludCBlbmQgPSBnZXREYXRlKHN0ciwgMCwgbGVuLCBkYXRlKTsKLSAgICAgICAgcGFyc2VUaW1lWm9uZSAoc3RyLCBlbmQsIGxlbiwgZGF0ZSk7Ci0KLSAgICAgICAgLy92YWxpZGF0ZSBhbmQgbm9ybWFsaXplCi0gICAgICAgIC8vUkVWSVNJVDogZG8gd2UgbmVlZCBTY2hlbWFEYXRlVGltZUV4Y2VwdGlvbj8KLSAgICAgICAgdmFsaWRhdGVEYXRlVGltZShkYXRlKTsKLQotICAgICAgICAvL3NhdmUgdW5ub3JtYWxpemVkIHZhbHVlcwotICAgICAgICBzYXZlVW5ub3JtYWxpemVkKGRhdGUpOwotCi0gICAgICAgIGlmIChkYXRlLnV0YyE9MCAmJiBkYXRlLnV0YyE9J1onKSB7Ci0gICAgICAgICAgICBub3JtYWxpemUoZGF0ZSk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGRhdGU7Ci0gICAgfQotCi0gICAgcHJvdGVjdGVkIFN0cmluZyBkYXRlVG9TdHJpbmcoRGF0ZVRpbWVEYXRhIGRhdGUpIHsKLSAgICAgICAgU3RyaW5nQnVmZmVyIG1lc3NhZ2UgPSBuZXcgU3RyaW5nQnVmZmVyKDI1KTsKLSAgICAgICAgYXBwZW5kKG1lc3NhZ2UsIGRhdGUueWVhciwgNCk7Ci0gICAgICAgIG1lc3NhZ2UuYXBwZW5kKCctJyk7Ci0gICAgICAgIGFwcGVuZChtZXNzYWdlLCBkYXRlLm1vbnRoLCAyKTsKLSAgICAgICAgbWVzc2FnZS5hcHBlbmQoJy0nKTsKLSAgICAgICAgYXBwZW5kKG1lc3NhZ2UsIGRhdGUuZGF5LCAyKTsKLSAgICAgICAgYXBwZW5kKG1lc3NhZ2UsIChjaGFyKWRhdGUudXRjLCAwKTsKLSAgICAgICAgcmV0dXJuIG1lc3NhZ2UudG9TdHJpbmcoKTsKLSAgICB9Ci0KLSAgICBwcm90ZWN0ZWQgWE1MR3JlZ29yaWFuQ2FsZW5kYXIgZ2V0WE1MR3JlZ29yaWFuQ2FsZW5kYXIoRGF0ZVRpbWVEYXRhIGRhdGUpIHsKLSAgICAgICAgcmV0dXJuIGRhdGF0eXBlRmFjdG9yeS5uZXdYTUxHcmVnb3JpYW5DYWxlbmRhcihkYXRlLnVuTm9ybVllYXIsIGRhdGUudW5Ob3JtTW9udGgsCi0gICAgICAgICAgICAgICAgZGF0ZS51bk5vcm1EYXksIERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCwgRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVELAotICAgICAgICAgICAgICAgIERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCwgRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVELAotICAgICAgICAgICAgICAgIGRhdGUuaGFzVGltZVpvbmUoKSA/IChkYXRlLnRpbWV6b25lSHIgKiA2MCArIGRhdGUudGltZXpvbmVNaW4pIDogRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVEKTsKLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYveHMvRGF0ZVRpbWVEVi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi94cy9EYXRlVGltZURWLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDZiMjAxMWQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi94cy9EYXRlVGltZURWLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5NiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDIsMjAwNCwyMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYueHM7Ci0KLWltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKLQotaW1wb3J0IGphdmF4LnhtbC5kYXRhdHlwZS5EYXRhdHlwZUNvbnN0YW50czsKLWltcG9ydCBqYXZheC54bWwuZGF0YXR5cGUuWE1MR3JlZ29yaWFuQ2FsZW5kYXI7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYuSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LlZhbGlkYXRpb25Db250ZXh0OwotCi0vKioKLSAqIFZhbGlkYXRvciBmb3IgJmx0O2RhdGVUaW1lJmd0OyBkYXRhdHlwZSAoVzNDIFNjaGVtYSBEYXRhdHlwZXMpCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgRWxlbmEgTGl0YW5pCi0gKiBAYXV0aG9yIEdvcGFsIFNoYXJtYSwgU1VOIE1pY3Jvc3lzdGVtIEluYy4KLSAqCi0gKiBAdmVyc2lvbiAkSWQ6IERhdGVUaW1lRFYuamF2YSx2IDEuNyAyMDEwLTExLTAxIDA0OjM5OjQ2IGpvZWh3IEV4cCAkCi0gKi8KLXB1YmxpYyBjbGFzcyBEYXRlVGltZURWIGV4dGVuZHMgQWJzdHJhY3REYXRlVGltZURWIHsKLQotICAgIHB1YmxpYyBPYmplY3QgZ2V0QWN0dWFsVmFsdWUoU3RyaW5nIGNvbnRlbnQsIFZhbGlkYXRpb25Db250ZXh0IGNvbnRleHQpIHRocm93cyBJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbiB7Ci0gICAgICAgIHRyeXsKLSAgICAgICAgICAgIHJldHVybiBwYXJzZShjb250ZW50KTsKLSAgICAgICAgfSBjYXRjaChFeGNlcHRpb24gZXgpewotICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uKCJjdmMtZGF0YXR5cGUtdmFsaWQuMS4yLjEiLCBuZXcgT2JqZWN0W117Y29udGVudCwgImRhdGVUaW1lIn0pOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUGFyc2VzLCB2YWxpZGF0ZXMgYW5kIGNvbXB1dGVzIG5vcm1hbGl6ZWQgdmVyc2lvbiBvZiBkYXRlVGltZSBvYmplY3QKLSAgICAgKgotICAgICAqIEBwYXJhbSBzdHIgICAgVGhlIGxleGljYWwgcmVwcmVzZW50YXRpb24gb2YgZGF0ZVRpbWUgb2JqZWN0IENDWVktTU0tRERUaGg6bW06c3Muc3NzCi0gICAgICogICAgICAgICAgICAgICB3aXRoIHBvc3NpYmxlIHRpbWUgem9uZSBaIG9yICgtKSwoKyloaDptbQotICAgICAqIEByZXR1cm4gbm9ybWFsaXplZCBkYXRlVGltZSByZXByZXNlbnRhdGlvbgotICAgICAqIEBleGNlcHRpb24gU2NoZW1hRGF0ZVRpbWVFeGNlcHRpb24gSW52YWxpZCBsZXhpY2FsIHJlcHJlc2VudGF0aW9uCi0gICAgICovCi0gICAgcHJvdGVjdGVkIERhdGVUaW1lRGF0YSBwYXJzZShTdHJpbmcgc3RyKSB0aHJvd3MgU2NoZW1hRGF0ZVRpbWVFeGNlcHRpb24gewotICAgICAgICBEYXRlVGltZURhdGEgZGF0ZSA9IG5ldyBEYXRlVGltZURhdGEoc3RyLCB0aGlzKTsKLSAgICAgICAgaW50IGxlbiA9IHN0ci5sZW5ndGgoKTsKLQotICAgICAgICBpbnQgZW5kID0gaW5kZXhPZiAoc3RyLCAwLCBsZW4sICdUJyk7Ci0KLSAgICAgICAgLy8gYm90aCB0aW1lIGFuZCBkYXRlCi0gICAgICAgIGludCBkYXRlRW5kID0gZ2V0RGF0ZShzdHIsIDAsIGVuZCwgZGF0ZSk7Ci0gICAgICAgIGdldFRpbWUoc3RyLCBlbmQrMSwgbGVuLCBkYXRlKTsKLQotICAgICAgICAvL0NoZWNrIHRoZSBzZXBhcmF0b3IgY2hhcmFjdGVyIGJldHdlZW4gRGF0ZSBhbmQgVGltZQotICAgICAgICBpZiAoZGF0ZUVuZCAhPSBlbmQpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKHN0cgotICAgICAgICAgICAgICAgICAgICArICIgaXMgYW4gaW52YWxpZCBkYXRlVGltZSBkYXRheXBlIHZhbHVlLiAiCi0gICAgICAgICAgICAgICAgICAgICsgIkludmFsaWQgY2hhcmFjdGVyKHMpIHNlcHJhdGluZyBkYXRlIGFuZCB0aW1lIHZhbHVlcy4iKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vdmFsaWRhdGUgYW5kIG5vcm1hbGl6ZQotCi0gICAgICAgIC8vUkVWSVNJVDogZG8gd2UgbmVlZCBTY2hlbWFEYXRlVGltZUV4Y2VwdGlvbj8KLSAgICAgICAgdmFsaWRhdGVEYXRlVGltZShkYXRlKTsKLQotICAgICAgICAvL3NhdmUgdW5ub3JtYWxpemVkIHZhbHVlcwotICAgICAgICBzYXZlVW5ub3JtYWxpemVkKGRhdGUpOwotCi0gICAgICAgIGlmIChkYXRlLnV0YyE9MCAmJiBkYXRlLnV0YyE9J1onKSB7Ci0gICAgICAgICAgICBub3JtYWxpemUoZGF0ZSk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGRhdGU7Ci0gICAgfQotCi0gICAgcHJvdGVjdGVkIFhNTEdyZWdvcmlhbkNhbGVuZGFyIGdldFhNTEdyZWdvcmlhbkNhbGVuZGFyKERhdGVUaW1lRGF0YSBkYXRlKSB7Ci0gICAgICAgIHJldHVybiBkYXRhdHlwZUZhY3RvcnkubmV3WE1MR3JlZ29yaWFuQ2FsZW5kYXIoQmlnSW50ZWdlci52YWx1ZU9mKGRhdGUudW5Ob3JtWWVhciksIGRhdGUudW5Ob3JtTW9udGgsCi0gICAgICAgICAgICAgICAgZGF0ZS51bk5vcm1EYXksIGRhdGUudW5Ob3JtSG91ciwgZGF0ZS51bk5vcm1NaW51dGUsCi0gICAgICAgICAgICAgICAgKGludClkYXRlLnVuTm9ybVNlY29uZCwgZGF0ZS51bk5vcm1TZWNvbmQgIT0gMCA/IGdldEZyYWN0aW9uYWxTZWNvbmRzQXNCaWdEZWNpbWFsKGRhdGUpIDogbnVsbCwKLSAgICAgICAgICAgICAgICBkYXRlLmhhc1RpbWVab25lKCkgPyAoZGF0ZS50aW1lem9uZUhyICogNjAgKyBkYXRlLnRpbWV6b25lTWluKSA6IERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi94cy9EYXlEVi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi94cy9EYXlEVi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxZTUwMWYwLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYveHMvRGF5RFYuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExOSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDIsMjAwNCwyMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYueHM7Ci0KLWltcG9ydCBqYXZheC54bWwuZGF0YXR5cGUuRGF0YXR5cGVDb25zdGFudHM7Ci1pbXBvcnQgamF2YXgueG1sLmRhdGF0eXBlLlhNTEdyZWdvcmlhbkNhbGVuZGFyOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LkludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5WYWxpZGF0aW9uQ29udGV4dDsKLQotLyoqCi0gKiBWYWxpZGF0b3IgZm9yICZsdDtnRGF5Jmd0OyBkYXRhdHlwZSAoVzNDIFNjaGVtYSBkYXRhdHlwZXMpCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgRWxlbmEgTGl0YW5pCi0gKiBAYXV0aG9yIEdvcGFsIFNoYXJtYSwgU1VOIE1pY3Jvc3lzdGVtIEluYy4KLSAqIEB2ZXJzaW9uICRJZDogRGF5RFYuamF2YSx2IDEuNyAyMDEwLTExLTAxIDA0OjM5OjQ2IGpvZWh3IEV4cCAkCi0gKi8KLXB1YmxpYyBjbGFzcyBEYXlEViBleHRlbmRzIEFic3RyYWN0RGF0ZVRpbWVEViB7Ci0KLSAgICAvL3NpemUgd2l0aG91dCB0aW1lIHpvbmU6IC0tLTA5Ci0gICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgaW50IERBWV9TSVpFPTU7Ci0KLSAgICBwdWJsaWMgT2JqZWN0IGdldEFjdHVhbFZhbHVlKFN0cmluZyBjb250ZW50LCBWYWxpZGF0aW9uQ29udGV4dCBjb250ZXh0KSB0aHJvd3MgSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24gewotICAgICAgICB0cnl7Ci0gICAgICAgICAgICByZXR1cm4gcGFyc2UoY29udGVudCk7Ci0gICAgICAgIH0gY2F0Y2goRXhjZXB0aW9uIGV4KXsKLSAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbigiY3ZjLWRhdGF0eXBlLXZhbGlkLjEuMi4xIiwgbmV3IE9iamVjdFtde2NvbnRlbnQsICJnRGF5In0pOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUGFyc2VzLCB2YWxpZGF0ZXMgYW5kIGNvbXB1dGVzIG5vcm1hbGl6ZWQgdmVyc2lvbiBvZiBnRGF5IG9iamVjdAotICAgICAqCi0gICAgICogQHBhcmFtIHN0ciAgICBUaGUgbGV4aWNhbCByZXByZXNlbnRhdGlvbiBvZiBnRGF5IG9iamVjdCAtLS1ERAotICAgICAqICAgICAgICAgICAgICAgd2l0aCBwb3NzaWJsZSB0aW1lIHpvbmUgWiBvciAoLSksKCspaGg6bW0KLSAgICAgKiAgICAgICAgICAgICAgIFBhdHRlcm46IC0tLShcXGRcXGQpKFp8KChbLStdKShcXGRcXGQpKDooXFxkXFxkKSk/Ci0gICAgICogQHJldHVybiBub3JtYWxpemVkIGRhdGUgcmVwcmVzZW50YXRpb24KLSAgICAgKiBAZXhjZXB0aW9uIFNjaGVtYURhdGVUaW1lRXhjZXB0aW9uIEludmFsaWQgbGV4aWNhbCByZXByZXNlbnRhdGlvbgotICAgICAqLwotICAgIHByb3RlY3RlZCBEYXRlVGltZURhdGEgcGFyc2UoU3RyaW5nIHN0cikgdGhyb3dzIFNjaGVtYURhdGVUaW1lRXhjZXB0aW9uIHsKLSAgICAgICAgRGF0ZVRpbWVEYXRhIGRhdGUgPSBuZXcgRGF0ZVRpbWVEYXRhKHN0ciwgdGhpcyk7Ci0gICAgICAgIGludCBsZW4gPSBzdHIubGVuZ3RoKCk7Ci0KLSAgICAgICAgaWYgKHN0ci5jaGFyQXQoMCkhPSctJyB8fCBzdHIuY2hhckF0KDEpIT0nLScgfHwgc3RyLmNoYXJBdCgyKSE9Jy0nKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgU2NoZW1hRGF0ZVRpbWVFeGNlcHRpb24gKCJFcnJvciBpbiBkYXkgcGFyc2luZyIpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy9pbml0aWFsaXplIHZhbHVlcwotICAgICAgICBkYXRlLnllYXI9WUVBUjsKLSAgICAgICAgZGF0ZS5tb250aD1NT05USDsKLQotICAgICAgICBkYXRlLmRheT1wYXJzZUludChzdHIsIDMsNSk7Ci0KLSAgICAgICAgaWYgKCBEQVlfU0laRTxsZW4gKSB7Ci0gICAgICAgICAgICBpZiAoIWlzTmV4dENoYXJVVENTaWduKHN0ciwgREFZX1NJWkUsIGxlbikpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU2NoZW1hRGF0ZVRpbWVFeGNlcHRpb24gKCJFcnJvciBpbiBkYXkgcGFyc2luZyIpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgZ2V0VGltZVpvbmUoc3RyLCBkYXRlLCBEQVlfU0laRSwgbGVuKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgLy92YWxpZGF0ZSBhbmQgbm9ybWFsaXplCi0gICAgICAgIHZhbGlkYXRlRGF0ZVRpbWUoZGF0ZSk7Ci0KLSAgICAgICAgLy9zYXZlIHVubm9ybWFsaXplZCB2YWx1ZXMKLSAgICAgICAgc2F2ZVVubm9ybWFsaXplZChkYXRlKTsKLQotICAgICAgICBpZiAoIGRhdGUudXRjIT0wICYmIGRhdGUudXRjIT0nWicgKSB7Ci0gICAgICAgICAgICBub3JtYWxpemUoZGF0ZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZGF0ZS5wb3NpdGlvbiA9IDI7Ci0gICAgICAgIHJldHVybiBkYXRlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbnZlcnRzIGdEYXkgb2JqZWN0IHJlcHJlc2VudGF0aW9uIHRvIFN0cmluZwotICAgICAqCi0gICAgICogQHBhcmFtIGRhdGUgICBnRGF5IG9iamVjdAotICAgICAqIEByZXR1cm4gbGV4aWNhbCByZXByZXNlbnRhdGlvbiBvZiBnRGF5OiAtLS1ERCB3aXRoIGFuIG9wdGlvbmFsIHRpbWUgem9uZSBzaWduCi0gICAgICovCi0gICAgcHJvdGVjdGVkIFN0cmluZyBkYXRlVG9TdHJpbmcoRGF0ZVRpbWVEYXRhIGRhdGUpIHsKLSAgICAgICAgU3RyaW5nQnVmZmVyIG1lc3NhZ2UgPSBuZXcgU3RyaW5nQnVmZmVyKDYpOwotICAgICAgICBtZXNzYWdlLmFwcGVuZCgnLScpOwotICAgICAgICBtZXNzYWdlLmFwcGVuZCgnLScpOwotICAgICAgICBtZXNzYWdlLmFwcGVuZCgnLScpOwotICAgICAgICBhcHBlbmQobWVzc2FnZSwgZGF0ZS5kYXksIDIpOwotICAgICAgICBhcHBlbmQobWVzc2FnZSwgKGNoYXIpZGF0ZS51dGMsIDApOwotICAgICAgICByZXR1cm4gbWVzc2FnZS50b1N0cmluZygpOwotICAgIH0KLQotICAgIHByb3RlY3RlZCBYTUxHcmVnb3JpYW5DYWxlbmRhciBnZXRYTUxHcmVnb3JpYW5DYWxlbmRhcihEYXRlVGltZURhdGEgZGF0ZSkgewotICAgICAgICByZXR1cm4gZGF0YXR5cGVGYWN0b3J5Lm5ld1hNTEdyZWdvcmlhbkNhbGVuZGFyKERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCwgRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVELAotICAgICAgICAgICAgICAgIGRhdGUudW5Ob3JtRGF5LCBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQsIERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCwKLSAgICAgICAgICAgICAgICBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQsIERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCwKLSAgICAgICAgICAgICAgICBkYXRlLmhhc1RpbWVab25lKCkgPyBkYXRlLnRpbWV6b25lSHIgKiA2MCArIGRhdGUudGltZXpvbmVNaW4gOiBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQpOwotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi94cy9EYXlUaW1lRHVyYXRpb25EVi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi94cy9EYXlUaW1lRHVyYXRpb25EVi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkZDE2ZjE5Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYveHMvRGF5VGltZUR1cmF0aW9uRFYuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDYzICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDQsMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi54czsKLQotaW1wb3J0IGphdmEubWF0aC5CaWdEZWNpbWFsOwotaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOwotCi1pbXBvcnQgamF2YXgueG1sLmRhdGF0eXBlLkRhdGF0eXBlQ29uc3RhbnRzOwotaW1wb3J0IGphdmF4LnhtbC5kYXRhdHlwZS5EdXJhdGlvbjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5JbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYuVmFsaWRhdGlvbkNvbnRleHQ7Ci0KLS8qKgotICogVXNlZCB0byB2YWxpZGF0ZSB0aGUgPGRheVRpbWVEdXJhdGlvbj4gdHlwZQotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIEFua2l0IFBhc3JpY2hhLCBJQk0KLSAqCi0gKiBAdmVyc2lvbiAkSWQ6IERheVRpbWVEdXJhdGlvbkRWLmphdmEsdiAxLjYgMjAxMC0xMS0wMSAwNDozOTo0NiBqb2VodyBFeHAgJAotICovCi1jbGFzcyBEYXlUaW1lRHVyYXRpb25EViBleHRlbmRzIER1cmF0aW9uRFYgewotCi0gICAgcHVibGljIE9iamVjdCBnZXRBY3R1YWxWYWx1ZShTdHJpbmcgY29udGVudCwgVmFsaWRhdGlvbkNvbnRleHQgY29udGV4dCkKLSAgICAgICAgdGhyb3dzIEludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIHJldHVybiBwYXJzZShjb250ZW50LCBEdXJhdGlvbkRWLkRBWVRJTUVEVVJBVElPTl9UWVBFKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24oImN2Yy1kYXRhdHlwZS12YWxpZC4xLjIuMSIsIG5ldyBPYmplY3RbXXtjb250ZW50LCAiZGF5VGltZUR1cmF0aW9uIn0pOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHJvdGVjdGVkIER1cmF0aW9uIGdldER1cmF0aW9uKERhdGVUaW1lRGF0YSBkYXRlKSB7Ci0gICAgICAgIGludCBzaWduID0gMTsKLSAgICAgICAgaWYgKGRhdGUuZGF5PDAgfHwgZGF0ZS5ob3VyPDAgfHwgZGF0ZS5taW51dGU8MCB8fCBkYXRlLnNlY29uZDwwKSB7Ci0gICAgICAgICAgICBzaWduID0gLTE7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGRhdGF0eXBlRmFjdG9yeS5uZXdEdXJhdGlvbihzaWduID09IDEsIG51bGwsIG51bGwsCi0gICAgICAgICAgICAgICAgZGF0ZS5kYXkgIT0gRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVEP0JpZ0ludGVnZXIudmFsdWVPZihzaWduKmRhdGUuZGF5KTpudWxsLAotICAgICAgICAgICAgICAgIGRhdGUuaG91ciAhPSBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQ/QmlnSW50ZWdlci52YWx1ZU9mKHNpZ24qZGF0ZS5ob3VyKTpudWxsLAotICAgICAgICAgICAgICAgIGRhdGUubWludXRlICE9IERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRD9CaWdJbnRlZ2VyLnZhbHVlT2Yoc2lnbipkYXRlLm1pbnV0ZSk6bnVsbCwKLSAgICAgICAgICAgICAgICBkYXRlLnNlY29uZCAhPSBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQ/bmV3IEJpZ0RlY2ltYWwoU3RyaW5nLnZhbHVlT2Yoc2lnbipkYXRlLnNlY29uZCkpOm51bGwpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYveHMvRGVjaW1hbERWLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L3hzL0RlY2ltYWxEVi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2MjIwNDJiLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYveHMvRGVjaW1hbERWLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzOTIgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMSwyMDAyLDIwMDQsMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LnhzOwotCi1pbXBvcnQgamF2YS5tYXRoLkJpZ0RlY2ltYWw7Ci1pbXBvcnQgamF2YS5tYXRoLkJpZ0ludGVnZXI7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYuSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LlZhbGlkYXRpb25Db250ZXh0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuZGF0YXR5cGVzLlhTRGVjaW1hbDsKLWltcG9ydCBqYXZhLnV0aWwuT2JqZWN0czsKLQotLyoqCi0gKiBSZXByZXNlbnQgdGhlIHNjaGVtYSB0eXBlICJkZWNpbWFsIgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIE5lZXJhaiBCYWphaiwgU3VuIE1pY3Jvc3lzdGVtcywgaW5jLgotICogQGF1dGhvciBTYW5keSBHYW8sIElCTQotICoKLSAqLwotcHVibGljIGNsYXNzIERlY2ltYWxEViBleHRlbmRzIFR5cGVWYWxpZGF0b3IgewotCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIGZpbmFsIHNob3J0IGdldEFsbG93ZWRGYWNldHMoKXsKLSAgICAgICAgcmV0dXJuICggWFNTaW1wbGVUeXBlRGVjbC5GQUNFVF9QQVRURVJOIHwgWFNTaW1wbGVUeXBlRGVjbC5GQUNFVF9XSElURVNQQUNFIHwgWFNTaW1wbGVUeXBlRGVjbC5GQUNFVF9FTlVNRVJBVElPTiB8WFNTaW1wbGVUeXBlRGVjbC5GQUNFVF9NQVhJTkNMVVNJVkUgfFhTU2ltcGxlVHlwZURlY2wuRkFDRVRfTUlOSU5DTFVTSVZFIHwgWFNTaW1wbGVUeXBlRGVjbC5GQUNFVF9NQVhFWENMVVNJVkUgIHwgWFNTaW1wbGVUeXBlRGVjbC5GQUNFVF9NSU5FWENMVVNJVkUgfCBYU1NpbXBsZVR5cGVEZWNsLkZBQ0VUX1RPVEFMRElHSVRTIHwgWFNTaW1wbGVUeXBlRGVjbC5GQUNFVF9GUkFDVElPTkRJR0lUUyk7Ci0gICAgfQotCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIE9iamVjdCBnZXRBY3R1YWxWYWx1ZShTdHJpbmcgY29udGVudCwgVmFsaWRhdGlvbkNvbnRleHQgY29udGV4dCkgdGhyb3dzIEludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIHJldHVybiBuZXcgWERlY2ltYWwoY29udGVudCk7Ci0gICAgICAgIH0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBuZmUpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbigiY3ZjLWRhdGF0eXBlLXZhbGlkLjEuMi4xIiwgbmV3IE9iamVjdFtde2NvbnRlbnQsICJkZWNpbWFsIn0pOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIGZpbmFsIGludCBjb21wYXJlKE9iamVjdCB2YWx1ZTEsIE9iamVjdCB2YWx1ZTIpewotICAgICAgICByZXR1cm4gKChYRGVjaW1hbCl2YWx1ZTEpLmNvbXBhcmVUbygoWERlY2ltYWwpdmFsdWUyKTsKLSAgICB9Ci0KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgZmluYWwgaW50IGdldFRvdGFsRGlnaXRzKE9iamVjdCB2YWx1ZSl7Ci0gICAgICAgIHJldHVybiAoKFhEZWNpbWFsKXZhbHVlKS50b3RhbERpZ2l0czsKLSAgICB9Ci0KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgZmluYWwgaW50IGdldEZyYWN0aW9uRGlnaXRzKE9iamVjdCB2YWx1ZSl7Ci0gICAgICAgIHJldHVybiAoKFhEZWNpbWFsKXZhbHVlKS5mcmFjRGlnaXRzOwotICAgIH0KLQotICAgIC8vIEF2b2lkIHVzaW5nIHRoZSBoZWF2eS13ZWlnaHQgamF2YS5tYXRoLkJpZ0RlY2ltYWwKLSAgICBzdGF0aWMgZmluYWwgY2xhc3MgWERlY2ltYWwgaW1wbGVtZW50cyBYU0RlY2ltYWwgewotICAgICAgICAvLyBzaWduOiAwIGZvciB2bGF1ZSAwOyAxIGZvciBwb3NpdGl2ZSB2YWx1ZXM7IC0xIGZvciBuZWdhdGl2ZSB2YWx1ZXMKLSAgICAgICAgaW50IHNpZ24gPSAxOwotICAgICAgICAvLyB0b3RhbCBkaWdpdHMuID49IDEKLSAgICAgICAgaW50IHRvdGFsRGlnaXRzID0gMDsKLSAgICAgICAgLy8gaW50ZWdlciBkaWdpdHMgd2hlbiBzaWduICE9IDAKLSAgICAgICAgaW50IGludERpZ2l0cyA9IDA7Ci0gICAgICAgIC8vIGZyYWN0aW9uIGRpZ2l0cyB3aGVuIHNpZ24gIT0gMAotICAgICAgICBpbnQgZnJhY0RpZ2l0cyA9IDA7Ci0gICAgICAgIC8vIHRoZSBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBpbnRlZ2VyIHBhcnQKLSAgICAgICAgU3RyaW5nIGl2YWx1ZSA9ICIiOwotICAgICAgICAvLyB0aGUgc3RyaW5nIHJlcHJlc2VudGluZyB0aGUgZnJhY3Rpb24gcGFydAotICAgICAgICBTdHJpbmcgZnZhbHVlID0gIiI7Ci0gICAgICAgIC8vIHdoZXRoZXIgdGhlIGNhbm9uaWNhbCBmb3JtIGNvbnRhaW5zIGRlY2ltYWwgcG9pbnQKLSAgICAgICAgYm9vbGVhbiBpbnRlZ2VyID0gZmFsc2U7Ci0KLSAgICAgICAgWERlY2ltYWwoU3RyaW5nIGNvbnRlbnQpIHRocm93cyBOdW1iZXJGb3JtYXRFeGNlcHRpb24gewotICAgICAgICAgICAgaW5pdEQoY29udGVudCk7Ci0gICAgICAgIH0KLSAgICAgICAgWERlY2ltYWwoU3RyaW5nIGNvbnRlbnQsIGJvb2xlYW4gaW50ZWdlcikgdGhyb3dzIE51bWJlckZvcm1hdEV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICBpZiAoaW50ZWdlcikKLSAgICAgICAgICAgICAgICBpbml0SShjb250ZW50KTsKLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICBpbml0RChjb250ZW50KTsKLSAgICAgICAgfQotICAgICAgICB2b2lkIGluaXREKFN0cmluZyBjb250ZW50KSB0aHJvd3MgTnVtYmVyRm9ybWF0RXhjZXB0aW9uIHsKLSAgICAgICAgICAgIGludCBsZW4gPSBjb250ZW50Lmxlbmd0aCgpOwotICAgICAgICAgICAgaWYgKGxlbiA9PSAwKQotICAgICAgICAgICAgICAgIHRocm93IG5ldyBOdW1iZXJGb3JtYXRFeGNlcHRpb24oKTsKLQotICAgICAgICAgICAgLy8gdGhlc2UgNCB2YXJpYWJsZXMgYXJlIHVzZWQgdG8gaW5kaWNhdGUgd2hlcmUgdGhlIGludGVncmUvZnJhY3Rpb24KLSAgICAgICAgICAgIC8vIHBhcnRzIHN0YXJ0L2VuZC4KLSAgICAgICAgICAgIGludCBpbnRTdGFydCA9IDAsIGludEVuZCA9IDAsIGZyYWNTdGFydCA9IDAsIGZyYWNFbmQgPSAwOwotCi0gICAgICAgICAgICAvLyBEZWFsIHdpdGggbGVhZGluZyBzaWduIHN5bWJvbCBpZiBwcmVzZW50Ci0gICAgICAgICAgICBpZiAoY29udGVudC5jaGFyQXQoMCkgPT0gJysnKSB7Ci0gICAgICAgICAgICAgICAgLy8gc2tpcCAnKycsIHNvIGludFN0YXJ0IHNob3VsZCBiZSAxCi0gICAgICAgICAgICAgICAgaW50U3RhcnQgPSAxOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoY29udGVudC5jaGFyQXQoMCkgPT0gJy0nKSB7Ci0gICAgICAgICAgICAgICAgLy8ga2VlcCAnLScsIHNvIGludFN0YXJ0IGlzIHN0aWwgMAotICAgICAgICAgICAgICAgIGludFN0YXJ0ID0gMTsKLSAgICAgICAgICAgICAgICBzaWduID0gLTE7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIHNraXAgbGVhZGluZyB6ZXJvZXMgaW4gaW50ZWdlciBwYXJ0Ci0gICAgICAgICAgICBpbnQgYWN0dWFsSW50U3RhcnQgPSBpbnRTdGFydDsKLSAgICAgICAgICAgIHdoaWxlIChhY3R1YWxJbnRTdGFydCA8IGxlbiAmJiBjb250ZW50LmNoYXJBdChhY3R1YWxJbnRTdGFydCkgPT0gJzAnKSB7Ci0gICAgICAgICAgICAgICAgYWN0dWFsSW50U3RhcnQrKzsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gRmluZCB0aGUgZW5kaW5nIHBvc2l0aW9uIG9mIHRoZSBpbnRlZ2VyIHBhcnQKLSAgICAgICAgICAgIGZvciAoaW50RW5kID0gYWN0dWFsSW50U3RhcnQ7Ci0gICAgICAgICAgICAgICAgIGludEVuZCA8IGxlbiAmJiBUeXBlVmFsaWRhdG9yLmlzRGlnaXQoY29udGVudC5jaGFyQXQoaW50RW5kKSk7Ci0gICAgICAgICAgICAgICAgIGludEVuZCsrKTsKLQotICAgICAgICAgICAgLy8gTm90IHJlYWNoZWQgdGhlIGVuZCB5ZXQKLSAgICAgICAgICAgIGlmIChpbnRFbmQgPCBsZW4pIHsKLSAgICAgICAgICAgICAgICAvLyB0aGUgcmVtYWluaW5nIHBhcnQgaXMgbm90ICIuREREIiwgZXJyb3IKLSAgICAgICAgICAgICAgICBpZiAoY29udGVudC5jaGFyQXQoaW50RW5kKSAhPSAnLicpCi0gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBOdW1iZXJGb3JtYXRFeGNlcHRpb24oKTsKLQotICAgICAgICAgICAgICAgIC8vIGZyYWN0aW9uIHBhcnQgc3RhcnRzIGFmdGVyICcuJywgYW5kIGVuZHMgYXQgdGhlIGVuZCBvZiB0aGUgaW5wdXQKLSAgICAgICAgICAgICAgICBmcmFjU3RhcnQgPSBpbnRFbmQgKyAxOwotICAgICAgICAgICAgICAgIGZyYWNFbmQgPSBsZW47Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIG5vIGludGVnZXIgcGFydCwgbm8gZnJhY3Rpb24gcGFydCwgZXJyb3IuCi0gICAgICAgICAgICBpZiAoaW50U3RhcnQgPT0gaW50RW5kICYmIGZyYWNTdGFydCA9PSBmcmFjRW5kKQotICAgICAgICAgICAgICAgIHRocm93IG5ldyBOdW1iZXJGb3JtYXRFeGNlcHRpb24oKTsKLQotICAgICAgICAgICAgLy8gaWdub3JlIHRyYWlsaW5nIHplcm9lcyBpbiBmcmFjdGlvbiBwYXJ0Ci0gICAgICAgICAgICB3aGlsZSAoZnJhY0VuZCA+IGZyYWNTdGFydCAmJiBjb250ZW50LmNoYXJBdChmcmFjRW5kLTEpID09ICcwJykgewotICAgICAgICAgICAgICAgIGZyYWNFbmQtLTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gY2hlY2sgd2hldGhlciB0aGVyZSBpcyBub24tZGlnaXQgY2hhcmFjdGVycyBpbiB0aGUgZnJhY3Rpb24gcGFydAotICAgICAgICAgICAgZm9yIChpbnQgZnJhY1BvcyA9IGZyYWNTdGFydDsgZnJhY1BvcyA8IGZyYWNFbmQ7IGZyYWNQb3MrKykgewotICAgICAgICAgICAgICAgIGlmICghVHlwZVZhbGlkYXRvci5pc0RpZ2l0KGNvbnRlbnQuY2hhckF0KGZyYWNQb3MpKSkKLSAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bWJlckZvcm1hdEV4Y2VwdGlvbigpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpbnREaWdpdHMgPSBpbnRFbmQgLSBhY3R1YWxJbnRTdGFydDsKLSAgICAgICAgICAgIGZyYWNEaWdpdHMgPSBmcmFjRW5kIC0gZnJhY1N0YXJ0OwotICAgICAgICAgICAgdG90YWxEaWdpdHMgPSBpbnREaWdpdHMgKyBmcmFjRGlnaXRzOwotCi0gICAgICAgICAgICBpZiAoaW50RGlnaXRzID4gMCkgewotICAgICAgICAgICAgICAgIGl2YWx1ZSA9IGNvbnRlbnQuc3Vic3RyaW5nKGFjdHVhbEludFN0YXJ0LCBpbnRFbmQpOwotICAgICAgICAgICAgICAgIGlmIChmcmFjRGlnaXRzID4gMCkKLSAgICAgICAgICAgICAgICAgICAgZnZhbHVlID0gY29udGVudC5zdWJzdHJpbmcoZnJhY1N0YXJ0LCBmcmFjRW5kKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIGlmIChmcmFjRGlnaXRzID4gMCkgewotICAgICAgICAgICAgICAgICAgICBmdmFsdWUgPSBjb250ZW50LnN1YnN0cmluZyhmcmFjU3RhcnQsIGZyYWNFbmQpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gIi4wMCIsIHRyZWF0IGl0IGFzICIwIgotICAgICAgICAgICAgICAgICAgICBzaWduID0gMDsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgdm9pZCBpbml0SShTdHJpbmcgY29udGVudCkgdGhyb3dzIE51bWJlckZvcm1hdEV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICBpbnQgbGVuID0gY29udGVudC5sZW5ndGgoKTsKLSAgICAgICAgICAgIGlmIChsZW4gPT0gMCkKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVtYmVyRm9ybWF0RXhjZXB0aW9uKCk7Ci0KLSAgICAgICAgICAgIC8vIHRoZXNlIDIgdmFyaWFibGVzIGFyZSB1c2VkIHRvIGluZGljYXRlIHdoZXJlIHRoZSBpbnRlZ3JlIHN0YXJ0L2VuZC4KLSAgICAgICAgICAgIGludCBpbnRTdGFydCA9IDAsIGludEVuZCA9IDA7Ci0KLSAgICAgICAgICAgIC8vIERlYWwgd2l0aCBsZWFkaW5nIHNpZ24gc3ltYm9sIGlmIHByZXNlbnQKLSAgICAgICAgICAgIGlmIChjb250ZW50LmNoYXJBdCgwKSA9PSAnKycpIHsKLSAgICAgICAgICAgICAgICAvLyBza2lwICcrJywgc28gaW50U3RhcnQgc2hvdWxkIGJlIDEKLSAgICAgICAgICAgICAgICBpbnRTdGFydCA9IDE7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChjb250ZW50LmNoYXJBdCgwKSA9PSAnLScpIHsKLSAgICAgICAgICAgICAgICAvLyBrZWVwICctJywgc28gaW50U3RhcnQgaXMgc3RpbCAwCi0gICAgICAgICAgICAgICAgaW50U3RhcnQgPSAxOwotICAgICAgICAgICAgICAgIHNpZ24gPSAtMTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gc2tpcCBsZWFkaW5nIHplcm9lcyBpbiBpbnRlZ2VyIHBhcnQKLSAgICAgICAgICAgIGludCBhY3R1YWxJbnRTdGFydCA9IGludFN0YXJ0OwotICAgICAgICAgICAgd2hpbGUgKGFjdHVhbEludFN0YXJ0IDwgbGVuICYmIGNvbnRlbnQuY2hhckF0KGFjdHVhbEludFN0YXJ0KSA9PSAnMCcpIHsKLSAgICAgICAgICAgICAgICBhY3R1YWxJbnRTdGFydCsrOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBGaW5kIHRoZSBlbmRpbmcgcG9zaXRpb24gb2YgdGhlIGludGVnZXIgcGFydAotICAgICAgICAgICAgZm9yIChpbnRFbmQgPSBhY3R1YWxJbnRTdGFydDsKLSAgICAgICAgICAgICAgICAgaW50RW5kIDwgbGVuICYmIFR5cGVWYWxpZGF0b3IuaXNEaWdpdChjb250ZW50LmNoYXJBdChpbnRFbmQpKTsKLSAgICAgICAgICAgICAgICAgaW50RW5kKyspOwotCi0gICAgICAgICAgICAvLyBOb3QgcmVhY2hlZCB0aGUgZW5kIHlldCwgZXJyb3IKLSAgICAgICAgICAgIGlmIChpbnRFbmQgPCBsZW4pCi0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bWJlckZvcm1hdEV4Y2VwdGlvbigpOwotCi0gICAgICAgICAgICAvLyBubyBpbnRlZ2VyIHBhcnQsIGVycm9yLgotICAgICAgICAgICAgaWYgKGludFN0YXJ0ID09IGludEVuZCkKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVtYmVyRm9ybWF0RXhjZXB0aW9uKCk7Ci0KLSAgICAgICAgICAgIGludERpZ2l0cyA9IGludEVuZCAtIGFjdHVhbEludFN0YXJ0OwotICAgICAgICAgICAgZnJhY0RpZ2l0cyA9IDA7Ci0gICAgICAgICAgICB0b3RhbERpZ2l0cyA9IGludERpZ2l0czsKLQotICAgICAgICAgICAgaWYgKGludERpZ2l0cyA+IDApIHsKLSAgICAgICAgICAgICAgICBpdmFsdWUgPSBjb250ZW50LnN1YnN0cmluZyhhY3R1YWxJbnRTdGFydCwgaW50RW5kKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIC8vICIwMCIsIHRyZWF0IGl0IGFzICIwIgotICAgICAgICAgICAgICAgIHNpZ24gPSAwOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpbnRlZ2VyID0gdHJ1ZTsKLSAgICAgICAgfQotCi0gICAgICAgIEBPdmVycmlkZQotICAgICAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IHZhbCkgewotICAgICAgICAgICAgaWYgKHZhbCA9PSB0aGlzKQotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotCi0gICAgICAgICAgICBpZiAoISh2YWwgaW5zdGFuY2VvZiBYRGVjaW1hbCkpCi0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgWERlY2ltYWwgb3ZhbCA9IChYRGVjaW1hbCl2YWw7Ci0KLSAgICAgICAgICAgIGlmIChzaWduICE9IG92YWwuc2lnbikKLSAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIGlmIChzaWduID09IDApCi0gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0KLSAgICAgICAgICAgIHJldHVybiBpbnREaWdpdHMgPT0gb3ZhbC5pbnREaWdpdHMgJiYgZnJhY0RpZ2l0cyA9PSBvdmFsLmZyYWNEaWdpdHMgJiYKLSAgICAgICAgICAgICAgICAgICBpdmFsdWUuZXF1YWxzKG92YWwuaXZhbHVlKSAmJiBmdmFsdWUuZXF1YWxzKG92YWwuZnZhbHVlKTsKLSAgICAgICAgfQotCi0gICAgICAgIEBPdmVycmlkZQotICAgICAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewotICAgICAgICAgICAgaW50IGhhc2ggPSA3OwotICAgICAgICAgICAgaGFzaCA9IDE3ICogaGFzaCArIHRoaXMuc2lnbjsKLSAgICAgICAgICAgIGlmICh0aGlzLnNpZ24gPT0gMCkgcmV0dXJuIGhhc2g7Ci0gICAgICAgICAgICBoYXNoID0gMTcgKiBoYXNoICsgdGhpcy5pbnREaWdpdHM7Ci0gICAgICAgICAgICBoYXNoID0gMTcgKiBoYXNoICsgdGhpcy5mcmFjRGlnaXRzOwotICAgICAgICAgICAgaGFzaCA9IDE3ICogaGFzaCArIE9iamVjdHMuaGFzaENvZGUodGhpcy5pdmFsdWUpOwotICAgICAgICAgICAgaGFzaCA9IDE3ICogaGFzaCArIE9iamVjdHMuaGFzaENvZGUodGhpcy5mdmFsdWUpOwotICAgICAgICAgICAgcmV0dXJuIGhhc2g7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgaW50IGNvbXBhcmVUbyhYRGVjaW1hbCB2YWwpIHsKLSAgICAgICAgICAgIGlmIChzaWduICE9IHZhbC5zaWduKQotICAgICAgICAgICAgICAgIHJldHVybiBzaWduID4gdmFsLnNpZ24gPyAxIDogLTE7Ci0gICAgICAgICAgICBpZiAoc2lnbiA9PSAwKQotICAgICAgICAgICAgICAgIHJldHVybiAwOwotICAgICAgICAgICAgcmV0dXJuIHNpZ24gKiBpbnRDb21wKHZhbCk7Ci0gICAgICAgIH0KLSAgICAgICAgcHJpdmF0ZSBpbnQgaW50Q29tcChYRGVjaW1hbCB2YWwpIHsKLSAgICAgICAgICAgIGlmIChpbnREaWdpdHMgIT0gdmFsLmludERpZ2l0cykKLSAgICAgICAgICAgICAgICByZXR1cm4gaW50RGlnaXRzID4gdmFsLmludERpZ2l0cyA/IDEgOiAtMTsKLSAgICAgICAgICAgIGludCByZXQgPSBpdmFsdWUuY29tcGFyZVRvKHZhbC5pdmFsdWUpOwotICAgICAgICAgICAgaWYgKHJldCAhPSAwKQotICAgICAgICAgICAgICAgIHJldHVybiByZXQgPiAwID8gMSA6IC0xOzsKLSAgICAgICAgICAgIHJldCA9IGZ2YWx1ZS5jb21wYXJlVG8odmFsLmZ2YWx1ZSk7Ci0gICAgICAgICAgICByZXR1cm4gcmV0ID09IDAgPyAwIDogKHJldCA+IDAgPyAxIDogLTEpOwotICAgICAgICB9Ci0KLSAgICAgICAgcHJpdmF0ZSBTdHJpbmcgY2Fub25pY2FsOwotICAgICAgICBAT3ZlcnJpZGUKLSAgICAgICAgcHVibGljIHN5bmNocm9uaXplZCBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0gICAgICAgICAgICBpZiAoY2Fub25pY2FsID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBtYWtlQ2Fub25pY2FsKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gY2Fub25pY2FsOwotICAgICAgICB9Ci0KLSAgICAgICAgcHJpdmF0ZSB2b2lkIG1ha2VDYW5vbmljYWwoKSB7Ci0gICAgICAgICAgICBpZiAoc2lnbiA9PSAwKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGludGVnZXIpCi0gICAgICAgICAgICAgICAgICAgIGNhbm9uaWNhbCA9ICIwIjsKLSAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgIGNhbm9uaWNhbCA9ICIwLjAiOwotICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChpbnRlZ2VyICYmIHNpZ24gPiAwKSB7Ci0gICAgICAgICAgICAgICAgY2Fub25pY2FsID0gaXZhbHVlOwotICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIGZvciAtMC4xLCB0b3RhbCBkaWdpdHMgaXMgMSwgc28gd2UgbmVlZCAzIGV4dHJhIHNwb3RzCi0gICAgICAgICAgICBmaW5hbCBTdHJpbmdCdWlsZGVyIGJ1ZmZlciA9IG5ldyBTdHJpbmdCdWlsZGVyKHRvdGFsRGlnaXRzKzMpOwotICAgICAgICAgICAgaWYgKHNpZ24gPT0gLTEpCi0gICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgnLScpOwotICAgICAgICAgICAgaWYgKGludERpZ2l0cyAhPSAwKQotICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoaXZhbHVlKTsKLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCcwJyk7Ci0gICAgICAgICAgICBpZiAoIWludGVnZXIpIHsKLSAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCcuJyk7Ci0gICAgICAgICAgICAgICAgaWYgKGZyYWNEaWdpdHMgIT0gMCkgewotICAgICAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKGZ2YWx1ZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCcwJyk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2Fub25pY2FsID0gYnVmZmVyLnRvU3RyaW5nKCk7Ci0gICAgICAgIH0KLQotICAgICAgICBAT3ZlcnJpZGUKLSAgICAgICAgcHVibGljIEJpZ0RlY2ltYWwgZ2V0QmlnRGVjaW1hbCgpIHsKLSAgICAgICAgICAgIGlmIChzaWduID09IDApIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEJpZ0RlY2ltYWwoQmlnSW50ZWdlci5aRVJPKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiBuZXcgQmlnRGVjaW1hbCh0b1N0cmluZygpKTsKLSAgICAgICAgfQotCi0gICAgICAgIEBPdmVycmlkZQotICAgICAgICBwdWJsaWMgQmlnSW50ZWdlciBnZXRCaWdJbnRlZ2VyKCkgdGhyb3dzIE51bWJlckZvcm1hdEV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICBpZiAoZnJhY0RpZ2l0cyAhPSAwKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bWJlckZvcm1hdEV4Y2VwdGlvbigpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKHNpZ24gPT0gMCkgewotICAgICAgICAgICAgICAgIHJldHVybiBCaWdJbnRlZ2VyLlpFUk87Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoc2lnbiA9PSAxKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBCaWdJbnRlZ2VyKGl2YWx1ZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gbmV3IEJpZ0ludGVnZXIoIi0iICsgaXZhbHVlKTsKLSAgICAgICAgfQotCi0gICAgICAgIEBPdmVycmlkZQotICAgICAgICBwdWJsaWMgbG9uZyBnZXRMb25nKCkgdGhyb3dzIE51bWJlckZvcm1hdEV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICBpZiAoZnJhY0RpZ2l0cyAhPSAwKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bWJlckZvcm1hdEV4Y2VwdGlvbigpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKHNpZ24gPT0gMCkgewotICAgICAgICAgICAgICAgIHJldHVybiAwTDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChzaWduID09IDEpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gTG9uZy5wYXJzZUxvbmcoaXZhbHVlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiBMb25nLnBhcnNlTG9uZygiLSIgKyBpdmFsdWUpOwotICAgICAgICB9Ci0KLSAgICAgICAgQE92ZXJyaWRlCi0gICAgICAgIHB1YmxpYyBpbnQgZ2V0SW50KCkgdGhyb3dzIE51bWJlckZvcm1hdEV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICBpZiAoZnJhY0RpZ2l0cyAhPSAwKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bWJlckZvcm1hdEV4Y2VwdGlvbigpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKHNpZ24gPT0gMCkgewotICAgICAgICAgICAgICAgIHJldHVybiAwOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKHNpZ24gPT0gMSkgewotICAgICAgICAgICAgICAgIHJldHVybiBJbnRlZ2VyLnBhcnNlSW50KGl2YWx1ZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gSW50ZWdlci5wYXJzZUludCgiLSIgKyBpdmFsdWUpOwotICAgICAgICB9Ci0KLSAgICAgICAgQE92ZXJyaWRlCi0gICAgICAgIHB1YmxpYyBzaG9ydCBnZXRTaG9ydCgpIHRocm93cyBOdW1iZXJGb3JtYXRFeGNlcHRpb24gewotICAgICAgICAgICAgaWYgKGZyYWNEaWdpdHMgIT0gMCkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBOdW1iZXJGb3JtYXRFeGNlcHRpb24oKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChzaWduID09IDApIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gMDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChzaWduID09IDEpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gU2hvcnQucGFyc2VTaG9ydChpdmFsdWUpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIFNob3J0LnBhcnNlU2hvcnQoIi0iICsgaXZhbHVlKTsKLSAgICAgICAgfQotCi0gICAgICAgIEBPdmVycmlkZQotICAgICAgICBwdWJsaWMgYnl0ZSBnZXRCeXRlKCkgdGhyb3dzIE51bWJlckZvcm1hdEV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICBpZiAoZnJhY0RpZ2l0cyAhPSAwKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bWJlckZvcm1hdEV4Y2VwdGlvbigpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKHNpZ24gPT0gMCkgewotICAgICAgICAgICAgICAgIHJldHVybiAwOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKHNpZ24gPT0gMSkgewotICAgICAgICAgICAgICAgIHJldHVybiBCeXRlLnBhcnNlQnl0ZShpdmFsdWUpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIEJ5dGUucGFyc2VCeXRlKCItIiArIGl2YWx1ZSk7Ci0gICAgICAgIH0KLSAgICB9Ci19IC8vIGNsYXNzIERlY2ltYWxEVgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi94cy9Eb3VibGVEVi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi94cy9Eb3VibGVEVi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlODg0ZDBkLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYveHMvRG91YmxlRFYuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI2MCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi54czsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5JbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYuVmFsaWRhdGlvbkNvbnRleHQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5kYXRhdHlwZXMuWFNEb3VibGU7Ci0KLS8qKgotICogUmVwcmVzZW50IHRoZSBzY2hlbWEgdHlwZSAiZG91YmxlIgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIE5lZXJhaiBCYWphaiwgU3VuIE1pY3Jvc3lzdGVtcywgaW5jLgotICogQGF1dGhvciBTYW5keSBHYW8sIElCTQotICoKLSAqIEB2ZXJzaW9uICRJZDogRG91YmxlRFYuamF2YSx2IDEuNyAyMDEwLTExLTAxIDA0OjM5OjQ2IGpvZWh3IEV4cCAkCi0gKi8KLXB1YmxpYyBjbGFzcyBEb3VibGVEViBleHRlbmRzIFR5cGVWYWxpZGF0b3IgewotCi0gICAgcHVibGljIHNob3J0IGdldEFsbG93ZWRGYWNldHMoKXsKLSAgICAgICAgcmV0dXJuICggWFNTaW1wbGVUeXBlRGVjbC5GQUNFVF9QQVRURVJOIHwgWFNTaW1wbGVUeXBlRGVjbC5GQUNFVF9XSElURVNQQUNFIHwgWFNTaW1wbGVUeXBlRGVjbC5GQUNFVF9FTlVNRVJBVElPTiB8WFNTaW1wbGVUeXBlRGVjbC5GQUNFVF9NQVhJTkNMVVNJVkUgfFhTU2ltcGxlVHlwZURlY2wuRkFDRVRfTUlOSU5DTFVTSVZFIHwgWFNTaW1wbGVUeXBlRGVjbC5GQUNFVF9NQVhFWENMVVNJVkUgIHwgWFNTaW1wbGVUeXBlRGVjbC5GQUNFVF9NSU5FWENMVVNJVkUgICk7Ci0gICAgfS8vZ2V0QWxsb3dlZEZhY2V0cygpCi0KLSAgICAvL2NvbnZlcnQgYSBTdHJpbmcgdG8gRG91YmxlIGZvcm0sIHdlIGhhdmUgdG8gdGFrZSBjYXJlIG9mIGNhc2VzIHNwZWNpZmllZCBpbiBzcGVjIGxpa2UgSU5GLCAtSU5GIGFuZCBOYU4KLSAgICBwdWJsaWMgT2JqZWN0IGdldEFjdHVhbFZhbHVlKFN0cmluZyBjb250ZW50LCBWYWxpZGF0aW9uQ29udGV4dCBjb250ZXh0KSB0aHJvd3MgSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24gewotICAgICAgICB0cnl7Ci0gICAgICAgICAgICByZXR1cm4gbmV3IFhEb3VibGUoY29udGVudCk7Ci0gICAgICAgIH0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBleCl7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24oImN2Yy1kYXRhdHlwZS12YWxpZC4xLjIuMSIsIG5ldyBPYmplY3RbXXtjb250ZW50LCAiZG91YmxlIn0pOwotICAgICAgICB9Ci0gICAgfS8vZ2V0QWN0dWFsVmFsdWUoKQotCi0gICAgLy8gQ2FuJ3QgY2FsbCBEb3VibGUjY29tcGFyZVRvIG1ldGhvZCwgYmVjYXVzZSBpdCdzIGludHJvZHVjZWQgaW4gamRrIDEuMgotICAgIHB1YmxpYyBpbnQgY29tcGFyZShPYmplY3QgdmFsdWUxLCBPYmplY3QgdmFsdWUyKSB7Ci0gICAgICAgIHJldHVybiAoKFhEb3VibGUpdmFsdWUxKS5jb21wYXJlVG8oKFhEb3VibGUpdmFsdWUyKTsKLSAgICB9Ly9jb21wYXJlKCkKLQotICAgIC8vZGlzdGluZ3Vpc2hlcyBiZXR3ZWVuIGlkZW50aXR5IGFuZCBlcXVhbGl0eSBmb3IgZG91YmxlIGRhdGF0eXBlCi0gICAgLy8wLjAgaXMgZXF1YWwgYnV0IG5vdCBpZGVudGljYWwgdG8gLTAuMAotICAgIHB1YmxpYyBib29sZWFuIGlzSWRlbnRpY2FsIChPYmplY3QgdmFsdWUxLCBPYmplY3QgdmFsdWUyKSB7Ci0gICAgICAgIGlmICh2YWx1ZTIgaW5zdGFuY2VvZiBYRG91YmxlKSB7Ci0gICAgICAgICAgICByZXR1cm4gKChYRG91YmxlKXZhbHVlMSkuaXNJZGVudGljYWwoKFhEb3VibGUpdmFsdWUyKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfS8vaXNJZGVudGljYWwoKQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIGlmIGl0J3MgcG9zc2libGUgdGhhdCB0aGUgZ2l2ZW4KLSAgICAgKiBzdHJpbmcgcmVwcmVzZW50cyBhIHZhbGlkIGZsb2F0aW5nIHBvaW50IHZhbHVlCi0gICAgICogKGV4Y2x1ZGluZyBOYU4sIElORiBhbmQgLUlORikuCi0gICAgICovCi0gICAgc3RhdGljIGJvb2xlYW4gaXNQb3NzaWJsZUZQKFN0cmluZyB2YWwpIHsKLSAgICAgICAgZmluYWwgaW50IGxlbmd0aCA9IHZhbC5sZW5ndGgoKTsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkgewotICAgICAgICAgICAgY2hhciBjID0gdmFsLmNoYXJBdChpKTsKLSAgICAgICAgICAgIGlmICghKGMgPj0gJzAnICYmIGMgPD0gJzknIHx8IGMgPT0gJy4nIHx8Ci0gICAgICAgICAgICAgICAgYyA9PSAnLScgfHwgYyA9PSAnKycgfHwgYyA9PSAnRScgfHwgYyA9PSAnZScpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIFhEb3VibGUgaW1wbGVtZW50cyBYU0RvdWJsZSB7Ci0gICAgICAgIHByaXZhdGUgZmluYWwgZG91YmxlIHZhbHVlOwotICAgICAgICBwdWJsaWMgWERvdWJsZShTdHJpbmcgcykgdGhyb3dzIE51bWJlckZvcm1hdEV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICBpZiAoaXNQb3NzaWJsZUZQKHMpKSB7Ci0gICAgICAgICAgICAgICAgdmFsdWUgPSBEb3VibGUucGFyc2VEb3VibGUocyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmICggcy5lcXVhbHMoIklORiIpICkgewotICAgICAgICAgICAgICAgIHZhbHVlID0gRG91YmxlLlBPU0lUSVZFX0lORklOSVRZOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoIHMuZXF1YWxzKCItSU5GIikgKSB7Ci0gICAgICAgICAgICAgICAgdmFsdWUgPSBEb3VibGUuTkVHQVRJVkVfSU5GSU5JVFk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmICggcy5lcXVhbHMoIk5hTiIgKSApIHsKLSAgICAgICAgICAgICAgICB2YWx1ZSA9IERvdWJsZS5OYU47Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVtYmVyRm9ybWF0RXhjZXB0aW9uKHMpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCB2YWwpIHsKLSAgICAgICAgICAgIGlmICh2YWwgPT0gdGhpcykKLSAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLQotICAgICAgICAgICAgaWYgKCEodmFsIGluc3RhbmNlb2YgWERvdWJsZSkpCi0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgWERvdWJsZSBvdmFsID0gKFhEb3VibGUpdmFsOwotCi0gICAgICAgICAgICAvLyBOT1RFOiB3ZSBkb24ndCBkaXN0aW5ndWlzaCAwLjAgZnJvbSAtMC4wCi0gICAgICAgICAgICBpZiAodmFsdWUgPT0gb3ZhbC52YWx1ZSkKLSAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLQotICAgICAgICAgICAgaWYgKHZhbHVlICE9IHZhbHVlICYmIG92YWwudmFsdWUgIT0gb3ZhbC52YWx1ZSkKLSAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLQotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKLSAgICAgICAgICAgIC8vIFRoaXMgY2hlY2sgaXMgbmVjZXNzYXJ5IGJlY2F1c2UgZG91YmxlVG9Mb25nQml0cygrMCkgIT0gZG91YmxlVG9Mb25nQml0cygtMCkKLSAgICAgICAgICAgIGlmICh2YWx1ZSA9PSAwZCkgewotICAgICAgICAgICAgICAgIHJldHVybiAwOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgbG9uZyB2ID0gRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHModmFsdWUpOwotICAgICAgICAgICAgcmV0dXJuIChpbnQpICh2IF4gKHYgPj4+IDMyKSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBOT1RFOiAwLjAgaXMgZXF1YWwgYnV0IG5vdCBpZGVudGljYWwgdG8gLTAuMAotICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc0lkZW50aWNhbCAoWERvdWJsZSB2YWwpIHsKLSAgICAgICAgICAgIGlmICh2YWwgPT0gdGhpcykgewotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAodmFsdWUgPT0gdmFsLnZhbHVlKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuICh2YWx1ZSAhPSAwLjBkIHx8Ci0gICAgICAgICAgICAgICAgICAgIChEb3VibGUuZG91YmxlVG9Mb25nQml0cyh2YWx1ZSkgPT0gRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHModmFsLnZhbHVlKSkpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAodmFsdWUgIT0gdmFsdWUgJiYgdmFsLnZhbHVlICE9IHZhbC52YWx1ZSkKLSAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLQotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0KLSAgICAgICAgcHJpdmF0ZSBpbnQgY29tcGFyZVRvKFhEb3VibGUgdmFsKSB7Ci0gICAgICAgICAgICBkb3VibGUgb3ZhbCA9IHZhbC52YWx1ZTsKLQotICAgICAgICAgICAgLy8gdGhpcyA8IG90aGVyCi0gICAgICAgICAgICBpZiAodmFsdWUgPCBvdmFsKQotICAgICAgICAgICAgICAgIHJldHVybiAtMTsKLSAgICAgICAgICAgIC8vIHRoaXMgPiBvdGhlcgotICAgICAgICAgICAgaWYgKHZhbHVlID4gb3ZhbCkKLSAgICAgICAgICAgICAgICByZXR1cm4gMTsKLSAgICAgICAgICAgIC8vIHRoaXMgPT0gb3RoZXIKLSAgICAgICAgICAgIC8vIE5PVEU6IHdlIGRvbid0IGRpc3Rpbmd1aXNoIDAuMCBmcm9tIC0wLjAKLSAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBvdmFsKQotICAgICAgICAgICAgICAgIHJldHVybiAwOwotCi0gICAgICAgICAgICAvLyBvbmUgb2YgdGhlIDIgdmFsdWVzIG9yIGJvdGggaXMvYXJlIE5hTihzKQotCi0gICAgICAgICAgICBpZiAodmFsdWUgIT0gdmFsdWUpIHsKLSAgICAgICAgICAgICAgICAvLyB0aGlzID0gTmFOID0gb3RoZXIKLSAgICAgICAgICAgICAgICBpZiAob3ZhbCAhPSBvdmFsKQotICAgICAgICAgICAgICAgICAgICByZXR1cm4gMDsKLSAgICAgICAgICAgICAgICAvLyB0aGlzIGlzIE5hTiA8PiBvdGhlcgotICAgICAgICAgICAgICAgIHJldHVybiBJTkRFVEVSTUlOQVRFOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBvdGhlciBpcyBOYU4gPD4gdGhpcwotICAgICAgICAgICAgcmV0dXJuIElOREVURVJNSU5BVEU7Ci0gICAgICAgIH0KLQotICAgICAgICBwcml2YXRlIFN0cmluZyBjYW5vbmljYWw7Ci0gICAgICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgICAgICAgICAgaWYgKGNhbm9uaWNhbCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgaWYgKHZhbHVlID09IERvdWJsZS5QT1NJVElWRV9JTkZJTklUWSkKLSAgICAgICAgICAgICAgICAgICAgY2Fub25pY2FsID0gIklORiI7Ci0gICAgICAgICAgICAgICAgZWxzZSBpZiAodmFsdWUgPT0gRG91YmxlLk5FR0FUSVZFX0lORklOSVRZKQotICAgICAgICAgICAgICAgICAgICBjYW5vbmljYWwgPSAiLUlORiI7Ci0gICAgICAgICAgICAgICAgZWxzZSBpZiAodmFsdWUgIT0gdmFsdWUpCi0gICAgICAgICAgICAgICAgICAgIGNhbm9uaWNhbCA9ICJOYU4iOwotICAgICAgICAgICAgICAgIC8vIE5PVEU6IHdlIGRvbid0IGRpc3Rpbmd1aXNoIDAuMCBmcm9tIC0wLjAKLSAgICAgICAgICAgICAgICBlbHNlIGlmICh2YWx1ZSA9PSAwKQotICAgICAgICAgICAgICAgICAgICBjYW5vbmljYWwgPSAiMC4wRTEiOwotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAvLyBSRVZJU0lUOiB1c2UgdGhlIGphdmEgYWxnb3JpdGhtIGZvciBub3csIGJlY2F1c2Ugd2UKLSAgICAgICAgICAgICAgICAgICAgLy8gZG9uJ3Qga25vdyB3aGF0IHRvIG91dHB1dCBmb3IgMS4xZCAod2hpY2ggaXMgbm8KLSAgICAgICAgICAgICAgICAgICAgLy8gYWN0dWFsbHkgMS4xKQotICAgICAgICAgICAgICAgICAgICBjYW5vbmljYWwgPSBEb3VibGUudG9TdHJpbmcodmFsdWUpOwotICAgICAgICAgICAgICAgICAgICAvLyBpZiBpdCBjb250YWlucyAnRScsIHRoZW4gaXQgc2hvdWxkIGJlIGEgdmFsaWQgc2NoZW1hCi0gICAgICAgICAgICAgICAgICAgIC8vIGNhbm9uaWNhbCByZXByZXNlbnRhdGlvbgotICAgICAgICAgICAgICAgICAgICBpZiAoY2Fub25pY2FsLmluZGV4T2YoJ0UnKSA9PSAtMSkgewotICAgICAgICAgICAgICAgICAgICAgICAgaW50IGxlbiA9IGNhbm9uaWNhbC5sZW5ndGgoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGF0IG1vc3QgMyBsb25nZXI6IEUsIC0sIDkKLSAgICAgICAgICAgICAgICAgICAgICAgIGNoYXJbXSBjaGFycyA9IG5ldyBjaGFyW2xlbiszXTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGNhbm9uaWNhbC5nZXRDaGFycygwLCBsZW4sIGNoYXJzLCAwKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGV4cGVjdGVkIGRlY2ltYWwgcG9pbnQgcG9zaXRpb24KLSAgICAgICAgICAgICAgICAgICAgICAgIGludCBlZHAgPSBjaGFyc1swXSA9PSAnLScgPyAyIDogMTsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZvciBub24temVybyBpbnRlZ2VyIHBhcnQKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA+PSAxIHx8IHZhbHVlIDw9IC0xKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZGVjaW1hbCBwb2ludCBwb3NpdGlvbgotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBkcCA9IGNhbm9uaWNhbC5pbmRleE9mKCcuJyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbW92ZSB0aGUgZGlnaXRzOiBkZGQuZCAtLT4gZC5kZGQKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gZHA7IGkgPiBlZHA7IGktLSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFyc1tpXSA9IGNoYXJzW2ktMV07Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYXJzW2VkcF0gPSAnLic7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHJpbSB0cmFpbGluZyB6ZXJvczogZDAwLjAgLS0+IGQuMDAwIC0tPiBkLgotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChjaGFyc1tsZW4tMV0gPT0gJzAnKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZW4tLTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBhZGQgdGhlIGxhc3QgemVybyBpZiBuZWNlc3Nhcnk6IGQuIC0tPiBkLjAKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2hhcnNbbGVuLTFdID09ICcuJykKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVuKys7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYXBwZW5kIEU6IGQuZGQgLS0+IGQuZGRFCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhcnNbbGVuKytdID0gJ0UnOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGhvdyBmYXIgd2Ugc2hpZnRlZCB0aGUgZGVjaW1hbCBwb2ludAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBzaGlmdCA9IGRwIC0gZWRwOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFwcGVuZCB0aGUgZXhwb25lbnQgLS0+IGQuZGRFZAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoZSBleHBvbmVudCBpcyBhdCBtb3N0IDcKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFyc1tsZW4rK10gPSAoY2hhcikoc2hpZnQgKyAnMCcpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbm9uLXplcm8gZGlnaXQgcG9pbnQKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbnpwID0gZWRwICsgMTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBza2lwIHplcm9zOiAwLjAwMwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChjaGFyc1tuenBdID09ICcwJykKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnpwKys7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcHV0IHRoZSBmaXJzdCBub24temVybyBkaWdpdCB0byB0aGUgbGVmdCBvZiAnLicKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFyc1tlZHAtMV0gPSBjaGFyc1tuenBdOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYXJzW2VkcF0gPSAnLic7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbW92ZSBvdGhlciBkaWdpdHMgKG5vbi16ZXJvKSB0byB0aGUgcmlnaHQgb2YgJy4nCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IG56cCsxLCBqID0gZWRwKzE7IGkgPCBsZW47IGkrKywgaisrKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFyc1tqXSA9IGNoYXJzW2ldOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFkanVzdCB0aGUgbGVuZ3RoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVuIC09IG56cCAtIGVkcDsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBhcHBlbmQgMCBpZiBuZXNzYXJ5OiAwLjAzIC0tPiAzLiAtLT4gMy4wCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxlbiA9PSBlZHAgKyAxKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFyc1tsZW4rK10gPSAnMCc7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYXBwZW5kIEUtOiBkLmRkIC0tPiBkLmRkRS0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFyc1tsZW4rK10gPSAnRSc7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhcnNbbGVuKytdID0gJy0nOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGhvdyBmYXIgd2Ugc2hpZnRlZCB0aGUgZGVjaW1hbCBwb2ludAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBzaGlmdCA9IG56cCAtIGVkcDsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBhcHBlbmQgdGhlIGV4cG9uZW50IC0tPiBkLmRkRWQKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGUgZXhwb25lbnQgaXMgYXQgbW9zdCAzCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhcnNbbGVuKytdID0gKGNoYXIpKHNoaWZ0ICsgJzAnKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGNhbm9uaWNhbCA9IG5ldyBTdHJpbmcoY2hhcnMsIDAsIGxlbik7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gY2Fub25pY2FsOwotICAgICAgICB9Ci0gICAgICAgIHB1YmxpYyBkb3VibGUgZ2V0VmFsdWUoKSB7Ci0gICAgICAgICAgICByZXR1cm4gdmFsdWU7Ci0gICAgICAgIH0KLSAgICB9Ci19IC8vIGNsYXNzIERvdWJsZURWCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L3hzL0R1cmF0aW9uRFYuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYveHMvRHVyYXRpb25EVi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxZWM4NmQwLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYveHMvRHVyYXRpb25EVi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzkwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwMiwyMDA0LDIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi54czsKLQotaW1wb3J0IGphdmEubWF0aC5CaWdEZWNpbWFsOwotaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOwotCi1pbXBvcnQgamF2YXgueG1sLmRhdGF0eXBlLkRhdGF0eXBlQ29uc3RhbnRzOwotaW1wb3J0IGphdmF4LnhtbC5kYXRhdHlwZS5EdXJhdGlvbjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5JbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYuVmFsaWRhdGlvbkNvbnRleHQ7Ci0KLS8qKgotICogVmFsaWRhdG9yIGZvciAmbHQ7ZHVyYXRpb24mZ3Q7IGRhdGF0eXBlIChXM0MgU2NoZW1hIERhdGF0eXBlcykKLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBFbGVuYSBMaXRhbmkKLSAqIEBhdXRob3IgR29wYWwgU2hhcm1hLCBTVU4gTWljcm9zeXN0ZW0gSW5jLgotICogQHZlcnNpb24gJElkOiBEdXJhdGlvbkRWLmphdmEsdiAxLjcgMjAxMC0xMS0wMSAwNDozOTo0NyBqb2VodyBFeHAgJAotICovCi1wdWJsaWMgY2xhc3MgRHVyYXRpb25EViBleHRlbmRzIEFic3RyYWN0RGF0ZVRpbWVEViB7Ci0KLSAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRFVSQVRJT05fVFlQRSA9IDA7Ci0gICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFlFQVJNT05USERVUkFUSU9OX1RZUEUgPSAxOwotICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBEQVlUSU1FRFVSQVRJT05fVFlQRSA9IDI7Ci0gICAgLy8gb3JkZXItcmVsYXRpb24gb24gZHVyYXRpb24gaXMgYSBwYXJ0aWFsIG9yZGVyLiBUaGUgZGF0ZXMgYmVsb3cgYXJlIHVzZWQgdG8KLSAgICAvLyBmb3IgY29tcGFyaXNvbiBvZiAyIGR1cmF0aW9ucywgYmFzZWQgb24gdGhlIGZhY3QgdGhhdAotICAgIC8vIGR1cmF0aW9uIHggYW5kIHkgaXMgeDw9eSBpZmYgcyt4PD1zK3kKLSAgICAvLyBzZWUgMy4yLjYgZHVyYXRpb24gVzNDIHNjaGVtYSBkYXRhdHlwZSBzcGVjcwotICAgIC8vCi0gICAgLy8gdGhlIGRhdGVzIGFyZSBpbiBmb3JtYXQ6IHtDQ1lZLE1NLERELCBILCBTLCBNLCBNUywgdGltZXpvbmV9Ci0gICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgRGF0ZVRpbWVEYXRhW10gREFURVRJTUVTPSB7Ci0gICAgICAgIG5ldyBEYXRlVGltZURhdGEoMTY5NiwgOSwgMSwgMCwgMCwgMCwgJ1onLCBudWxsLCB0cnVlLCBudWxsKSwKLSAgICAgICAgbmV3IERhdGVUaW1lRGF0YSgxNjk3LCAyLCAxLCAwLCAwLCAwLCAnWicsIG51bGwsIHRydWUsIG51bGwpLAotICAgICAgICBuZXcgRGF0ZVRpbWVEYXRhKDE5MDMsIDMsIDEsIDAsIDAsIDAsICdaJywgbnVsbCwgdHJ1ZSwgbnVsbCksCi0gICAgICAgIG5ldyBEYXRlVGltZURhdGEoMTkwMywgNywgMSwgMCwgMCwgMCwgJ1onLCBudWxsLCB0cnVlLCBudWxsKX07Ci0KLSAgICBwdWJsaWMgT2JqZWN0IGdldEFjdHVhbFZhbHVlKFN0cmluZyBjb250ZW50LCBWYWxpZGF0aW9uQ29udGV4dCBjb250ZXh0KSB0aHJvd3MgSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb257Ci0gICAgICAgIHRyeXsKLSAgICAgICAgICAgIHJldHVybiBwYXJzZShjb250ZW50LCBEVVJBVElPTl9UWVBFKTsKLSAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24oImN2Yy1kYXRhdHlwZS12YWxpZC4xLjIuMSIsIG5ldyBPYmplY3RbXXtjb250ZW50LCAiZHVyYXRpb24ifSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBQYXJzZXMsIHZhbGlkYXRlcyBhbmQgY29tcHV0ZXMgbm9ybWFsaXplZCB2ZXJzaW9uIG9mIGR1cmF0aW9uIG9iamVjdAotICAgICAqCi0gICAgICogQHBhcmFtIHN0ciAgICBUaGUgbGV4aWNhbCByZXByZXNlbnRhdGlvbiBvZiBkdXJhdGlvbiBvYmplY3QgUG5ZbiBNbkRUbkggbk1uUwotICAgICAqIEBwYXJhbSBkdXJhdGlvblR5cGUKLSAgICAgKiBAcmV0dXJuIG5vcm1hbGl6ZWQgZGF0ZSByZXByZXNlbnRhdGlvbgotICAgICAqIEBleGNlcHRpb24gU2NoZW1hRGF0ZVRpbWVFeGNlcHRpb24gSW52YWxpZCBsZXhpY2FsIHJlcHJlc2VudGF0aW9uCi0gICAgICovCi0gICAgcHJvdGVjdGVkIERhdGVUaW1lRGF0YSBwYXJzZShTdHJpbmcgc3RyLCBpbnQgZHVyYXRpb25UeXBlKSB0aHJvd3MgU2NoZW1hRGF0ZVRpbWVFeGNlcHRpb257Ci0gICAgICAgIGludCBsZW4gPSBzdHIubGVuZ3RoKCk7Ci0gICAgICAgIERhdGVUaW1lRGF0YSBkYXRlPSBuZXcgRGF0ZVRpbWVEYXRhKHN0ciwgdGhpcyk7Ci0KLSAgICAgICAgaW50IHN0YXJ0ID0gMDsKLSAgICAgICAgY2hhciBjPXN0ci5jaGFyQXQoc3RhcnQrKyk7Ci0gICAgICAgIGlmICggYyE9J1AnICYmIGMhPSctJyApIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBTY2hlbWFEYXRlVGltZUV4Y2VwdGlvbigpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgZGF0ZS51dGM9KGM9PSctJyk/Jy0nOjA7Ci0gICAgICAgICAgICBpZiAoIGM9PSctJyAmJiBzdHIuY2hhckF0KHN0YXJ0KyspIT0nUCcgKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFNjaGVtYURhdGVUaW1lRXhjZXB0aW9uKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBpbnQgbmVnYXRlID0gMTsKLSAgICAgICAgLy9uZWdhdGl2ZSBkdXJhdGlvbgotICAgICAgICBpZiAoIGRhdGUudXRjPT0nLScgKSB7Ci0gICAgICAgICAgICBuZWdhdGUgPSAtMTsKLQotICAgICAgICB9Ci0gICAgICAgIC8vYXQgbGVhc3Qgb25lIG51bWJlciBhbmQgZGVzaWduYXRvciBtdXN0IGJlIHNlZW4gYWZ0ZXIgUAotICAgICAgICBib29sZWFuIGRlc2lnbmF0b3IgPSBmYWxzZTsKLQotICAgICAgICBpbnQgZW5kRGF0ZSA9IGluZGV4T2YgKHN0ciwgc3RhcnQsIGxlbiwgJ1QnKTsKLSAgICAgICAgaWYgKCBlbmREYXRlID09IC0xICkgewotICAgICAgICAgICAgZW5kRGF0ZSA9IGxlbjsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChkdXJhdGlvblR5cGUgPT0gWUVBUk1PTlRIRFVSQVRJT05fVFlQRSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFNjaGVtYURhdGVUaW1lRXhjZXB0aW9uKCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvL2ZpbmQgJ1knCi0gICAgICAgIGludCBlbmQgPSBpbmRleE9mIChzdHIsIHN0YXJ0LCBlbmREYXRlLCAnWScpOwotICAgICAgICBpZiAoIGVuZCE9LTEgKSB7Ci0KLSAgICAgICAgICAgIGlmIChkdXJhdGlvblR5cGUgPT0gREFZVElNRURVUkFUSU9OX1RZUEUpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU2NoZW1hRGF0ZVRpbWVFeGNlcHRpb24oKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy9zY2FuIHllYXIKLSAgICAgICAgICAgIGRhdGUueWVhcj1uZWdhdGUgKiBwYXJzZUludChzdHIsc3RhcnQsZW5kKTsKLSAgICAgICAgICAgIHN0YXJ0ID0gZW5kKzE7Ci0gICAgICAgICAgICBkZXNpZ25hdG9yID0gdHJ1ZTsKLSAgICAgICAgfQotCi0gICAgICAgIGVuZCA9IGluZGV4T2YgKHN0ciwgc3RhcnQsIGVuZERhdGUsICdNJyk7Ci0gICAgICAgIGlmICggZW5kIT0tMSApIHsKLQotICAgICAgICAgICAgaWYgKGR1cmF0aW9uVHlwZSA9PSBEQVlUSU1FRFVSQVRJT05fVFlQRSkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBTY2hlbWFEYXRlVGltZUV4Y2VwdGlvbigpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvL3NjYW4gbW9udGgKLSAgICAgICAgICAgIGRhdGUubW9udGg9bmVnYXRlICogcGFyc2VJbnQoc3RyLHN0YXJ0LGVuZCk7Ci0gICAgICAgICAgICBzdGFydCA9IGVuZCsxOwotICAgICAgICAgICAgZGVzaWduYXRvciA9IHRydWU7Ci0gICAgICAgIH0KLQotICAgICAgICBlbmQgPSBpbmRleE9mIChzdHIsIHN0YXJ0LCBlbmREYXRlLCAnRCcpOwotICAgICAgICBpZiAoIGVuZCE9LTEgKSB7Ci0KLSAgICAgICAgICAgIGlmKGR1cmF0aW9uVHlwZSA9PSBZRUFSTU9OVEhEVVJBVElPTl9UWVBFKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFNjaGVtYURhdGVUaW1lRXhjZXB0aW9uKCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vc2NhbiBkYXkKLSAgICAgICAgICAgIGRhdGUuZGF5PW5lZ2F0ZSAqIHBhcnNlSW50KHN0cixzdGFydCxlbmQpOwotICAgICAgICAgICAgc3RhcnQgPSBlbmQrMTsKLSAgICAgICAgICAgIGRlc2lnbmF0b3IgPSB0cnVlOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKCBsZW4gPT0gZW5kRGF0ZSAmJiBzdGFydCE9bGVuICkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFNjaGVtYURhdGVUaW1lRXhjZXB0aW9uKCk7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKCBsZW4gIT1lbmREYXRlICkgewotCi0gICAgICAgICAgICAvL3NjYW4gaG91cnMsIG1pbnV0ZXMsIHNlY29uZHMKLSAgICAgICAgICAgIC8vUkVWSVNJVDogY2FuIGFueSBpdGVtIGluY2x1ZGUgYSBkZWNpbWFsIGZyYWN0aW9uIG9yIG9ubHkgc2Vjb25kcz8KLSAgICAgICAgICAgIC8vCi0KLSAgICAgICAgICAgIGVuZCA9IGluZGV4T2YgKHN0ciwgKytzdGFydCwgbGVuLCAnSCcpOwotICAgICAgICAgICAgaWYgKCBlbmQhPS0xICkgewotICAgICAgICAgICAgICAgIC8vc2NhbiBob3VycwotICAgICAgICAgICAgICAgIGRhdGUuaG91cj1uZWdhdGUgKiBwYXJzZUludChzdHIsc3RhcnQsZW5kKTsKLSAgICAgICAgICAgICAgICBzdGFydD1lbmQrMTsKLSAgICAgICAgICAgICAgICBkZXNpZ25hdG9yID0gdHJ1ZTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgZW5kID0gaW5kZXhPZiAoc3RyLCBzdGFydCwgbGVuLCAnTScpOwotICAgICAgICAgICAgaWYgKCBlbmQhPS0xICkgewotICAgICAgICAgICAgICAgIC8vc2NhbiBtaW4KLSAgICAgICAgICAgICAgICBkYXRlLm1pbnV0ZT1uZWdhdGUgKiBwYXJzZUludChzdHIsc3RhcnQsZW5kKTsKLSAgICAgICAgICAgICAgICBzdGFydD1lbmQrMTsKLSAgICAgICAgICAgICAgICBkZXNpZ25hdG9yID0gdHJ1ZTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgZW5kID0gaW5kZXhPZiAoc3RyLCBzdGFydCwgbGVuLCAnUycpOwotICAgICAgICAgICAgaWYgKCBlbmQhPS0xICkgewotICAgICAgICAgICAgICAgIC8vc2NhbiBzZWNvbmRzCi0gICAgICAgICAgICAgICAgZGF0ZS5zZWNvbmQgPSBuZWdhdGUgKiBwYXJzZVNlY29uZChzdHIsIHN0YXJ0LCBlbmQpOwotICAgICAgICAgICAgICAgIHN0YXJ0PWVuZCsxOwotICAgICAgICAgICAgICAgIGRlc2lnbmF0b3IgPSB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gbm8gYWRkaXRpb25hbCBkYXRhIHNob3VscyBhcHBlYXIgYWZ0ZXIgbGFzdCBpdGVtCi0gICAgICAgICAgICAvLyBQMVkxTTFEVCBpcyBpbGxpZ2FsIHZhbHVlIGFzIHdlbGwKLSAgICAgICAgICAgIGlmICggc3RhcnQgIT0gbGVuIHx8IHN0ci5jaGFyQXQoLS1zdGFydCk9PSdUJyApIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU2NoZW1hRGF0ZVRpbWVFeGNlcHRpb24oKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGlmICggIWRlc2lnbmF0b3IgKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgU2NoZW1hRGF0ZVRpbWVFeGNlcHRpb24oKTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBkYXRlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbXBhcmVzIDIgZ2l2ZW4gZHVyYXRpb25zLiAocmVmZXIgdG8gVzNDIFNjaGVtYSBEYXRhdHlwZXMgIjMuMi42IGR1cmF0aW9uIikKLSAgICAgKgotICAgICAqIEBwYXJhbSBkYXRlMSAgVW5ub3JtYWxpemVkIGR1cmF0aW9uCi0gICAgICogQHBhcmFtIGRhdGUyICBVbm5vcm1hbGl6ZWQgZHVyYXRpb24KLSAgICAgKiBAcGFyYW0gc3RyaWN0IChtaW4vbWF4KUV4Y2x1c2l2ZSBzdHJpY3QgPT0gdHJ1ZSAoIExFU1NfVEhBTiApIG9yICggR1JFQVRFUl9USEFOICkKLSAgICAgKiAgICAgICAgICAgICAgIChtaW4vbWF4KUluY2x1c2l2ZSBzdHJpY3QgPT0gZmFsc2UgKExFU1NfRVFVQUwpIG9yIChHUkVBVEVSX0VRVUFMKQotICAgICAqIEByZXR1cm4gSU5ERVRFUk1JTkFURSBpZiB0aGUgb3JkZXIgcmVsYXRpb25zaGlwIGJldHdlZW4gZGF0ZTEgYW5kIGRhdGUyIGlzIGluZGV0ZXJtaW5hdGUuCi0gICAgICogRVFVQUwgaWYgdGhlIG9yZGVyIHJlbGF0aW9uIGJldHdlZW4gZGF0ZTEgYW5kIGRhdGUyIGlzIEVRVUFMLgotICAgICAqIElmIHRoZSBzdHJpY3QgcGFyYW1ldGVyIGlzIHRydWUsIHJldHVybiBMRVNTX1RIQU4gaWYgZGF0ZTEgaXMgbGVzcyB0aGFuIGRhdGUyIGFuZAotICAgICAqIHJldHVybiBHUkVBVEVSX1RIQU4gaWYgZGF0ZTEgaXMgZ3JlYXRlciB0aGFuIGRhdGUyLgotICAgICAqIElmIHRoZSBzdHJpY3QgcGFyYW1ldGVyIGlzIGZhbHNlLCByZXR1cm4gTEVTU19USEFOIGlmIGRhdGUxIGlzIGxlc3MgdGhhbiBPUiBlcXVhbCB0byBkYXRlMiBhbmQKLSAgICAgKiByZXR1cm4gR1JFQVRFUl9USEFOIGlmIGRhdGUxIGlzIGdyZWF0ZXIgdGhhbiBPUiBlcXVhbCB0byBkYXRlMgotICAgICAqLwotICAgIHByb3RlY3RlZCAgc2hvcnQgY29tcGFyZURhdGVzKERhdGVUaW1lRGF0YSBkYXRlMSwgRGF0ZVRpbWVEYXRhIGRhdGUyLCBib29sZWFuIHN0cmljdCkgewotCi0gICAgICAgIC8vUkVWSVNJVDogdGhpcyBpcyB1bm9wdGltYXplZCB2cyBvZiBjb21wYXJpbmcgMiBkdXJhdGlvbnMKLSAgICAgICAgLy8gICAgICAgICBBbGdvcml0aG0gaXMgZGVzY3JpYmVkIGluIDMuMi42LjIgVzNDIFNjaGVtYSBEYXRhdHlwZSBzcGVjcwotICAgICAgICAvLwotCi0gICAgICAgIC8vYWRkIGNvbnN0QSB0byBib3RoIGR1cmF0aW9ucwotICAgICAgICBzaG9ydCByZXN1bHRBLCByZXN1bHRCPSBJTkRFVEVSTUlOQVRFOwotICAgICAgICAvL3RyeSBhbmQgc2VlIGlmIHRoZSBvYmplY3RzIGFyZSBlcXVhbAotICAgICAgICByZXN1bHRBID0gY29tcGFyZU9yZGVyIChkYXRlMSwgZGF0ZTIpOwotICAgICAgICBpZiAoIHJlc3VsdEEgPT0gMCApIHsKLSAgICAgICAgICAgIHJldHVybiAwOwotICAgICAgICB9Ci0KLSAgICAgICAgRGF0ZVRpbWVEYXRhW10gcmVzdWx0ID0gbmV3IERhdGVUaW1lRGF0YVsyXTsKLSAgICAgICAgcmVzdWx0WzBdID0gbmV3IERhdGVUaW1lRGF0YShudWxsLCB0aGlzKTsKLSAgICAgICAgcmVzdWx0WzFdID0gbmV3IERhdGVUaW1lRGF0YShudWxsLCB0aGlzKTsKLQotICAgICAgICAvL2xvbmcgY29tcGFyaXNvbiBhbGdvcml0aG0gaXMgcmVxdWlyZWQKLSAgICAgICAgRGF0ZVRpbWVEYXRhIHRlbXBBID0gYWRkRHVyYXRpb24gKGRhdGUxLCBEQVRFVElNRVNbMF0sIHJlc3VsdFswXSk7Ci0gICAgICAgIERhdGVUaW1lRGF0YSB0ZW1wQiA9IGFkZER1cmF0aW9uIChkYXRlMiwgREFURVRJTUVTWzBdLCByZXN1bHRbMV0pOwotICAgICAgICByZXN1bHRBID0gIGNvbXBhcmVPcmRlcih0ZW1wQSwgdGVtcEIpOwotICAgICAgICBpZiAoIHJlc3VsdEEgPT0gSU5ERVRFUk1JTkFURSApIHsKLSAgICAgICAgICAgIHJldHVybiBJTkRFVEVSTUlOQVRFOwotICAgICAgICB9Ci0KLSAgICAgICAgdGVtcEEgPSBhZGREdXJhdGlvbihkYXRlMSwgREFURVRJTUVTWzFdLCByZXN1bHRbMF0pOwotICAgICAgICB0ZW1wQiA9IGFkZER1cmF0aW9uKGRhdGUyLCBEQVRFVElNRVNbMV0sIHJlc3VsdFsxXSk7Ci0gICAgICAgIHJlc3VsdEIgPSBjb21wYXJlT3JkZXIodGVtcEEsIHRlbXBCKTsKLSAgICAgICAgcmVzdWx0QSA9IGNvbXBhcmVSZXN1bHRzKHJlc3VsdEEsIHJlc3VsdEIsIHN0cmljdCk7Ci0gICAgICAgIGlmIChyZXN1bHRBID09IElOREVURVJNSU5BVEUpIHsKLSAgICAgICAgICAgIHJldHVybiBJTkRFVEVSTUlOQVRFOwotICAgICAgICB9Ci0KLSAgICAgICAgdGVtcEEgPSBhZGREdXJhdGlvbihkYXRlMSwgREFURVRJTUVTWzJdLCByZXN1bHRbMF0pOwotICAgICAgICB0ZW1wQiA9IGFkZER1cmF0aW9uKGRhdGUyLCBEQVRFVElNRVNbMl0sIHJlc3VsdFsxXSk7Ci0gICAgICAgIHJlc3VsdEIgPSBjb21wYXJlT3JkZXIodGVtcEEsIHRlbXBCKTsKLSAgICAgICAgcmVzdWx0QSA9IGNvbXBhcmVSZXN1bHRzKHJlc3VsdEEsIHJlc3VsdEIsIHN0cmljdCk7Ci0gICAgICAgIGlmIChyZXN1bHRBID09IElOREVURVJNSU5BVEUpIHsKLSAgICAgICAgICAgIHJldHVybiBJTkRFVEVSTUlOQVRFOwotICAgICAgICB9Ci0KLSAgICAgICAgdGVtcEEgPSBhZGREdXJhdGlvbihkYXRlMSwgREFURVRJTUVTWzNdLCByZXN1bHRbMF0pOwotICAgICAgICB0ZW1wQiA9IGFkZER1cmF0aW9uKGRhdGUyLCBEQVRFVElNRVNbM10sIHJlc3VsdFsxXSk7Ci0gICAgICAgIHJlc3VsdEIgPSBjb21wYXJlT3JkZXIodGVtcEEsIHRlbXBCKTsKLSAgICAgICAgcmVzdWx0QSA9IGNvbXBhcmVSZXN1bHRzKHJlc3VsdEEsIHJlc3VsdEIsIHN0cmljdCk7Ci0KLSAgICAgICAgcmV0dXJuIHJlc3VsdEE7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBzaG9ydCBjb21wYXJlUmVzdWx0cyhzaG9ydCByZXN1bHRBLCBzaG9ydCByZXN1bHRCLCBib29sZWFuIHN0cmljdCl7Ci0KLSAgICAgIGlmICggcmVzdWx0QiA9PSBJTkRFVEVSTUlOQVRFICkgewotICAgICAgICAgICAgcmV0dXJuIElOREVURVJNSU5BVEU7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoIHJlc3VsdEEhPXJlc3VsdEIgJiYgc3RyaWN0ICkgewotICAgICAgICAgICAgcmV0dXJuIElOREVURVJNSU5BVEU7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoIHJlc3VsdEEhPXJlc3VsdEIgJiYgIXN0cmljdCApIHsKLSAgICAgICAgICAgIGlmICggcmVzdWx0QSE9MCAmJiByZXN1bHRCIT0wICkgewotICAgICAgICAgICAgICAgIHJldHVybiBJTkRFVEVSTUlOQVRFOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIChyZXN1bHRBIT0wKT9yZXN1bHRBOnJlc3VsdEI7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHJlc3VsdEE7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBEYXRlVGltZURhdGEgYWRkRHVyYXRpb24oRGF0ZVRpbWVEYXRhIGRhdGUsIERhdGVUaW1lRGF0YSBhZGR0bywgRGF0ZVRpbWVEYXRhIGR1cmF0aW9uKSB7Ci0KLSAgICAgICAgLy9SRVZJU0lUOiBzb21lIGNvZGUgY291bGQgYmUgc2hhcmVkIGJldHdlZW4gbm9ybWFsaXplKCkgYW5kIHRoaXMgbWV0aG9kLAotICAgICAgICAvLyAgICAgICAgIGhvd2V2ZXIgaXMgaXQgd29ydGggbW92aW5nIGl0PyBUaGUgc3RydWN0dXJlcyBhcmUgZGlmZmVyZW50Li4uCi0gICAgICAgIC8vCi0KLSAgICAgICAgcmVzZXREYXRlT2JqKGR1cmF0aW9uKTsKLSAgICAgICAgLy9hZGQgbW9udGhzIChtYXkgYmUgbW9kaWZpZWQgYWRkaXRpb25hbHkgYmVsb3cpCi0gICAgICAgIGludCB0ZW1wID0gYWRkdG8ubW9udGggKyBkYXRlLm1vbnRoOwotICAgICAgICBkdXJhdGlvbi5tb250aCA9IG1vZHVsbyAodGVtcCwgMSwgMTMpOwotICAgICAgICBpbnQgY2FycnkgPSBmUXVvdGllbnQgKHRlbXAsIDEsIDEzKTsKLQotICAgICAgICAvL2FkZCB5ZWFycyAobWF5IGJlIG1vZGlmaWVkIGFkZGl0aW9uYWx5IGJlbG93KQotICAgICAgICBkdXJhdGlvbi55ZWFyPWFkZHRvLnllYXIgKyBkYXRlLnllYXIgKyBjYXJyeTsKLQotICAgICAgICAvL2FkZCBzZWNvbmRzCi0gICAgICAgIGRvdWJsZSBkdGVtcCA9IGFkZHRvLnNlY29uZCArIGRhdGUuc2Vjb25kOwotICAgICAgICBjYXJyeSA9IChpbnQpTWF0aC5mbG9vcihkdGVtcC82MCk7Ci0gICAgICAgIGR1cmF0aW9uLnNlY29uZCA9IGR0ZW1wIC0gY2FycnkqNjA7Ci0KLSAgICAgICAgLy9hZGQgbWludXRlcwotICAgICAgICB0ZW1wID0gYWRkdG8ubWludXRlICtkYXRlLm1pbnV0ZSArIGNhcnJ5OwotICAgICAgICBjYXJyeSA9IGZRdW90aWVudCAodGVtcCwgNjApOwotICAgICAgICBkdXJhdGlvbi5taW51dGU9IG1vZCh0ZW1wLCA2MCwgY2FycnkpOwotCi0gICAgICAgIC8vYWRkIGhvdXJzCi0gICAgICAgIHRlbXAgPSBhZGR0by5ob3VyICsgZGF0ZS5ob3VyICsgY2Fycnk7Ci0gICAgICAgIGNhcnJ5ID0gZlF1b3RpZW50KHRlbXAsIDI0KTsKLSAgICAgICAgZHVyYXRpb24uaG91ciA9IG1vZCh0ZW1wLCAyNCwgY2FycnkpOwotCi0KLSAgICAgICAgZHVyYXRpb24uZGF5PWFkZHRvLmRheSArIGRhdGUuZGF5ICsgY2Fycnk7Ci0KLSAgICAgICAgd2hpbGUgKCB0cnVlICkgewotCi0gICAgICAgICAgICB0ZW1wPW1heERheUluTW9udGhGb3IoZHVyYXRpb24ueWVhciwgZHVyYXRpb24ubW9udGgpOwotICAgICAgICAgICAgaWYgKCBkdXJhdGlvbi5kYXkgPCAxICkgeyAvL29yaWdpbmFsIGR1cmF0aW9uIHdhcyBuZWdhdGl2ZQotICAgICAgICAgICAgICAgIGR1cmF0aW9uLmRheSA9IGR1cmF0aW9uLmRheSArIG1heERheUluTW9udGhGb3IoZHVyYXRpb24ueWVhciwgZHVyYXRpb24ubW9udGgtMSk7Ci0gICAgICAgICAgICAgICAgY2Fycnk9LTE7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmICggZHVyYXRpb24uZGF5ID4gdGVtcCApIHsKLSAgICAgICAgICAgICAgICBkdXJhdGlvbi5kYXkgPSBkdXJhdGlvbi5kYXkgLSB0ZW1wOwotICAgICAgICAgICAgICAgIGNhcnJ5PTE7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHRlbXAgPSBkdXJhdGlvbi5tb250aCtjYXJyeTsKLSAgICAgICAgICAgIGR1cmF0aW9uLm1vbnRoID0gbW9kdWxvKHRlbXAsIDEsIDEzKTsKLSAgICAgICAgICAgIGR1cmF0aW9uLnllYXIgPSBkdXJhdGlvbi55ZWFyK2ZRdW90aWVudCh0ZW1wLCAxLCAxMyk7Ci0gICAgICAgIH0KLQotICAgICAgICBkdXJhdGlvbi51dGM9J1onOwotICAgICAgICByZXR1cm4gZHVyYXRpb247Ci0gICAgfQotCi0gICAgcHJvdGVjdGVkIGRvdWJsZSBwYXJzZVNlY29uZChTdHJpbmcgYnVmZmVyLCBpbnQgc3RhcnQsIGludCBlbmQpCi0gICAgICAgIHRocm93cyBOdW1iZXJGb3JtYXRFeGNlcHRpb24gewotICAgICAgICBpbnQgZG90ID0gLTE7Ci0gICAgICAgIGZvciAoaW50IGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7Ci0gICAgICAgICAgICBjaGFyIGNoID0gYnVmZmVyLmNoYXJBdChpKTsKLSAgICAgICAgICAgIGlmIChjaCA9PSAnLicpCi0gICAgICAgICAgICAgICAgZG90ID0gaTsKLSAgICAgICAgICAgIGVsc2UgaWYgKGNoID4gJzknIHx8IGNoIDwgJzAnKQotICAgICAgICAgICAgICAgIHRocm93IG5ldyBOdW1iZXJGb3JtYXRFeGNlcHRpb24oIiciICsgYnVmZmVyICsgIicgaGFzIHdyb25nIGZvcm1hdCIpOwotICAgICAgICB9Ci0gICAgICAgIGlmIChkb3QrMSA9PSBlbmQpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBOdW1iZXJGb3JtYXRFeGNlcHRpb24oIiciICsgYnVmZmVyICsgIicgaGFzIHdyb25nIGZvcm1hdCIpOwotICAgICAgICB9Ci0gICAgICAgIGRvdWJsZSB2YWx1ZSA9IERvdWJsZS5wYXJzZURvdWJsZShidWZmZXIuc3Vic3RyaW5nKHN0YXJ0LCBlbmQpKTsKLSAgICAgICAgaWYgKHZhbHVlID09IERvdWJsZS5QT1NJVElWRV9JTkZJTklUWSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IE51bWJlckZvcm1hdEV4Y2VwdGlvbigiJyIgKyBidWZmZXIgKyAiJyBoYXMgd3JvbmcgZm9ybWF0Iik7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHZhbHVlOwotICAgIH0KLQotICAgIHByb3RlY3RlZCBTdHJpbmcgZGF0ZVRvU3RyaW5nKERhdGVUaW1lRGF0YSBkYXRlKSB7Ci0gICAgICAgIFN0cmluZ0J1ZmZlciBtZXNzYWdlID0gbmV3IFN0cmluZ0J1ZmZlcigzMCk7Ci0gICAgICAgIGlmICggZGF0ZS55ZWFyPDAgfHwgZGF0ZS5tb250aDwwIHx8IGRhdGUuZGF5PDAKLSAgICAgICAgICAgICAgICB8fCBkYXRlLmhvdXI8MCB8fCBkYXRlLm1pbnV0ZTwwIHx8IGRhdGUuc2Vjb25kPDApIHsKLSAgICAgICAgICAgIG1lc3NhZ2UuYXBwZW5kKCctJyk7Ci0gICAgICAgIH0KLSAgICAgICAgbWVzc2FnZS5hcHBlbmQoJ1AnKTsKLSAgICAgICAgbWVzc2FnZS5hcHBlbmQoKGRhdGUueWVhciA8IDA/LTE6MSkgKiBkYXRlLnllYXIpOwotICAgICAgICBtZXNzYWdlLmFwcGVuZCgnWScpOwotICAgICAgICBtZXNzYWdlLmFwcGVuZCgoZGF0ZS5tb250aCA8IDA/LTE6MSkgKiBkYXRlLm1vbnRoKTsKLSAgICAgICAgbWVzc2FnZS5hcHBlbmQoJ00nKTsKLSAgICAgICAgbWVzc2FnZS5hcHBlbmQoKGRhdGUuZGF5IDwgMD8tMToxKSAqIGRhdGUuZGF5KTsKLSAgICAgICAgbWVzc2FnZS5hcHBlbmQoJ0QnKTsKLSAgICAgICAgbWVzc2FnZS5hcHBlbmQoJ1QnKTsKLSAgICAgICAgbWVzc2FnZS5hcHBlbmQoKGRhdGUuaG91ciA8IDA/LTE6MSkgKiBkYXRlLmhvdXIpOwotICAgICAgICBtZXNzYWdlLmFwcGVuZCgnSCcpOwotICAgICAgICBtZXNzYWdlLmFwcGVuZCgoZGF0ZS5taW51dGUgPCAwPy0xOjEpICogZGF0ZS5taW51dGUpOwotICAgICAgICBtZXNzYWdlLmFwcGVuZCgnTScpOwotICAgICAgICBhcHBlbmQyKG1lc3NhZ2UsIChkYXRlLnNlY29uZCA8IDA/LTE6MSkgKiBkYXRlLnNlY29uZCk7Ci0gICAgICAgIG1lc3NhZ2UuYXBwZW5kKCdTJyk7Ci0KLSAgICAgICAgcmV0dXJuIG1lc3NhZ2UudG9TdHJpbmcoKTsKLSAgICB9Ci0KLSAgICBwcm90ZWN0ZWQgRHVyYXRpb24gZ2V0RHVyYXRpb24oRGF0ZVRpbWVEYXRhIGRhdGUpIHsKLSAgICAgICAgaW50IHNpZ24gPSAxOwotICAgICAgICBpZiAoIGRhdGUueWVhcjwwIHx8IGRhdGUubW9udGg8MCB8fCBkYXRlLmRheTwwCi0gICAgICAgICAgICAgICAgfHwgZGF0ZS5ob3VyPDAgfHwgZGF0ZS5taW51dGU8MCB8fCBkYXRlLnNlY29uZDwwKSB7Ci0gICAgICAgICAgICBzaWduID0gLTE7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGRhdGF0eXBlRmFjdG9yeS5uZXdEdXJhdGlvbihzaWduID09IDEsCi0gICAgICAgICAgICAgICAgZGF0ZS55ZWFyICE9IERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRD9CaWdJbnRlZ2VyLnZhbHVlT2Yoc2lnbipkYXRlLnllYXIpOm51bGwsCi0gICAgICAgICAgICAgICAgZGF0ZS5tb250aCAhPSBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQ/QmlnSW50ZWdlci52YWx1ZU9mKHNpZ24qZGF0ZS5tb250aCk6bnVsbCwKLSAgICAgICAgICAgICAgICBkYXRlLmRheSAhPSBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQ/QmlnSW50ZWdlci52YWx1ZU9mKHNpZ24qZGF0ZS5kYXkpOm51bGwsCi0gICAgICAgICAgICAgICAgZGF0ZS5ob3VyICE9IERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRD9CaWdJbnRlZ2VyLnZhbHVlT2Yoc2lnbipkYXRlLmhvdXIpOm51bGwsCi0gICAgICAgICAgICAgICAgZGF0ZS5taW51dGUgIT0gRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVEP0JpZ0ludGVnZXIudmFsdWVPZihzaWduKmRhdGUubWludXRlKTpudWxsLAotICAgICAgICAgICAgICAgIGRhdGUuc2Vjb25kICE9IERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRD9uZXcgQmlnRGVjaW1hbChTdHJpbmcudmFsdWVPZihzaWduKmRhdGUuc2Vjb25kKSk6bnVsbCk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi94cy9FbnRpdHlEVi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi94cy9FbnRpdHlEVi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxYTYyYWM5Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYveHMvRW50aXR5RFYuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDU2ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEsIDIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LnhzOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LkludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5WYWxpZGF0aW9uQ29udGV4dDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuWE1MQ2hhcjsKLQotLyoqCi0gKiBSZXByZXNlbnQgdGhlIHNjaGVtYSB0eXBlICJlbnRpdHkiCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgTmVlcmFqIEJhamFqLCBTdW4gTWljcm9zeXN0ZW1zLCBpbmMuCi0gKiBAYXV0aG9yIFNhbmR5IEdhbywgSUJNCi0gKgotICovCi1wdWJsaWMgY2xhc3MgRW50aXR5RFYgZXh0ZW5kcyBUeXBlVmFsaWRhdG9yIHsKLQotICAgIHB1YmxpYyBzaG9ydCBnZXRBbGxvd2VkRmFjZXRzKCl7Ci0gICAgICAgIHJldHVybiAoWFNTaW1wbGVUeXBlRGVjbC5GQUNFVF9MRU5HVEggfCBYU1NpbXBsZVR5cGVEZWNsLkZBQ0VUX01JTkxFTkdUSCB8IFhTU2ltcGxlVHlwZURlY2wuRkFDRVRfTUFYTEVOR1RIIHwgWFNTaW1wbGVUeXBlRGVjbC5GQUNFVF9QQVRURVJOIHwgWFNTaW1wbGVUeXBlRGVjbC5GQUNFVF9FTlVNRVJBVElPTiB8IFhTU2ltcGxlVHlwZURlY2wuRkFDRVRfV0hJVEVTUEFDRSApOwotICAgIH0KLQotICAgIHB1YmxpYyBPYmplY3QgZ2V0QWN0dWFsVmFsdWUoU3RyaW5nIGNvbnRlbnQsIFZhbGlkYXRpb25Db250ZXh0IGNvbnRleHQpIHRocm93cyBJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmICghWE1MQ2hhci5pc1ZhbGlkTkNOYW1lKGNvbnRlbnQpKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24oImN2Yy1kYXRhdHlwZS12YWxpZC4xLjIuMSIsIG5ldyBPYmplY3RbXXtjb250ZW50LCAiTkNOYW1lIn0pOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIGNvbnRlbnQ7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgY2hlY2tFeHRyYVJ1bGVzKE9iamVjdCB2YWx1ZSwgVmFsaWRhdGlvbkNvbnRleHQgY29udGV4dCkgdGhyb3dzIEludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKCFjb250ZXh0LmlzRW50aXR5VW5wYXJzZWQoKFN0cmluZyl2YWx1ZSkpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbigiVW5kZWNsYXJlZEVudGl0eSIsIG5ldyBPYmplY3RbXXt2YWx1ZX0pOwotICAgICAgICB9Ci0gICAgfQotCi19IC8vIGNsYXNzIEVudGl0eURWCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L3hzL0V4dGVuZGVkU2NoZW1hRFZGYWN0b3J5SW1wbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi94cy9FeHRlbmRlZFNjaGVtYURWRmFjdG9yeUltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZmE3ZTc5ZS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L3hzL0V4dGVuZGVkU2NoZW1hRFZGYWN0b3J5SW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsODYgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKLSAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAotICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgotICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKLSAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCi0gKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYueHM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYuWFNTaW1wbGVUeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5TeW1ib2xIYXNoOwotCi0vKioKLSAqIEEgc3BlY2lhbCBmYWN0b3J5IHRvIGNyZWF0ZS9yZXR1cm4gYnVpbHQtaW4gc2NoZW1hIERWcyBhbmQgY3JlYXRlIHVzZXItZGVmaW5lZCBEVnMKLSAqIHRoYXQgaW5jbHVkZXMgYW55QXRvbWljVHlwZSwgeWVhck1vbnRoRHVyYXRpb24gYW5kIGRheVRpbWVEdXJhdGlvbgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIEtoYWxlZCBOb2FtYW4sIElCTQotICoKLSAqIEB2ZXJzaW9uICRJZDogRXh0ZW5kZWRTY2hlbWFEVkZhY3RvcnlJbXBsLmphdmEsdiAxLjIgMjAxMC0xMC0yNiAyMzowMTowMyBqb2VodyBFeHAgJAotICovCi1wdWJsaWMgY2xhc3MgRXh0ZW5kZWRTY2hlbWFEVkZhY3RvcnlJbXBsIGV4dGVuZHMgQmFzZVNjaGVtYURWRmFjdG9yeSB7Ci0KLSAgICBzdGF0aWMgU3ltYm9sSGFzaCBmQnVpbHRJblR5cGVzID0gbmV3IFN5bWJvbEhhc2goKTsKLSAgICBzdGF0aWMgewotICAgICAgICBjcmVhdGVCdWlsdEluVHlwZXMoKTsKLSAgICB9Ci0KLSAgICAvLyBjcmVhdGUgYWxsIGJ1aWx0LWluIHR5cGVzCi0gICAgc3RhdGljIHZvaWQgY3JlYXRlQnVpbHRJblR5cGVzKCkgewotICAgICAgICBmaW5hbCBTdHJpbmcgQU5ZQVRPTUlDVFlQRSAgICAgPSAiYW55QXRvbWljVHlwZSI7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBEVVJBVElPTiAgICAgICAgICA9ICJkdXJhdGlvbiI7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBZRUFSTU9OVEhEVVJBVElPTiA9ICJ5ZWFyTW9udGhEdXJhdGlvbiI7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBEQVlUSU1FRFVSQVRJT04gICA9ICJkYXlUaW1lRHVyYXRpb24iOwotCi0gICAgICAgIGNyZWF0ZUJ1aWx0SW5UeXBlcyhmQnVpbHRJblR5cGVzLCBYU1NpbXBsZVR5cGVEZWNsLmZBbnlBdG9taWNUeXBlKTsKLQotICAgICAgICAvLyBhZGQgYW55QXRvbWljVHlwZQotICAgICAgICBmQnVpbHRJblR5cGVzLnB1dChBTllBVE9NSUNUWVBFLCBYU1NpbXBsZVR5cGVEZWNsLmZBbnlBdG9taWNUeXBlKTsKLQotICAgICAgICAvLyBhZGQgMiBkdXJhdGlvbiB0eXBlcwotICAgICAgICBYU1NpbXBsZVR5cGVEZWNsIGR1cmF0aW9uRFYgPSAoWFNTaW1wbGVUeXBlRGVjbClmQnVpbHRJblR5cGVzLmdldChEVVJBVElPTik7Ci0gICAgICAgIGZCdWlsdEluVHlwZXMucHV0KFlFQVJNT05USERVUkFUSU9OLCBuZXcgWFNTaW1wbGVUeXBlRGVjbChkdXJhdGlvbkRWLCBZRUFSTU9OVEhEVVJBVElPTiwgWFNTaW1wbGVUeXBlRGVjbC5EVl9ZRUFSTU9OVEhEVVJBVElPTiwgWFNTaW1wbGVUeXBlLk9SREVSRURfUEFSVElBTCwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgdHJ1ZSwgWFNTaW1wbGVUeXBlRGVjbC5ZRUFSTU9OVEhEVVJBVElPTl9EVCkpOwotICAgICAgICBmQnVpbHRJblR5cGVzLnB1dChEQVlUSU1FRFVSQVRJT04sIG5ldyBYU1NpbXBsZVR5cGVEZWNsKGR1cmF0aW9uRFYsIERBWVRJTUVEVVJBVElPTiwgWFNTaW1wbGVUeXBlRGVjbC5EVl9EQVlUSU1FRFVSQVRJT04sIFhTU2ltcGxlVHlwZS5PUkRFUkVEX1BBUlRJQUwsIGZhbHNlLCBmYWxzZSwgZmFsc2UsIHRydWUsIFhTU2ltcGxlVHlwZURlY2wuREFZVElNRURVUkFUSU9OX0RUKSk7Ci0gICAgfSAvL2NyZWF0ZUJ1aWx0SW5UeXBlcygpCi0KLSAgICAvKioKLSAgICAgKiBHZXQgYSBidWlsdC1pbiBzaW1wbGUgdHlwZSBvZiB0aGUgZ2l2ZW4gbmFtZQotICAgICAqIFJFVklTSVQ6IGl0cyBzdGlsbCBub3QgZGVjaWRlZCB3aXRoaW4gdGhlIFNjaGVtYSBXRyBob3cgdG8gZGVmaW5lIHRoZQotICAgICAqICAgICAgICAgIHVyLXR5cGVzIGFuZCBpZiBhbGwgc2ltcGxlIHR5cGVzIHNob3VsZCBiZSBkZXJpdmVkIGZyb20gYQotICAgICAqICAgICAgICAgIGNvbXBsZXggdHlwZSwgc28gYXMgb2Ygbm93IHdlIGlnbm9yZSB0aGUgZmFjdCB0aGF0IGFueVNpbXBsZVR5cGUKLSAgICAgKiAgICAgICAgICBpcyBkZXJpdmVkIGZyb20gYW55VHlwZSwgYW5kIHBhc3MgJ251bGwnIGFzIHRoZSBiYXNlIG9mCi0gICAgICogICAgICAgICAgYW55U2ltcGxlVHlwZS4gSXQgbmVlZHMgdG8gYmUgY2hhbmdlZCBhcyBwZXIgdGhlIGRlY2lzaW9uIHRha2VuLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgIHRoZSBuYW1lIG9mIHRoZSBkYXRhdHlwZQotICAgICAqIEByZXR1cm4gICAgICB0aGUgZGF0YXR5cGUgdmFsaWRhdG9yIG9mIHRoZSBnaXZlbiBuYW1lCi0gICAgICovCi0gICAgcHVibGljIFhTU2ltcGxlVHlwZSBnZXRCdWlsdEluVHlwZShTdHJpbmcgbmFtZSkgewotICAgICAgICByZXR1cm4gKFhTU2ltcGxlVHlwZSlmQnVpbHRJblR5cGVzLmdldChuYW1lKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBnZXQgYWxsIGJ1aWx0LWluIHNpbXBsZSB0eXBlcywgd2hpY2ggYXJlIHN0b3JlZCBpbiBhIGhhc2h0YWJsZSBrZXllZCBieQotICAgICAqIHRoZSBuYW1lCi0gICAgICoKLSAgICAgKiBAcmV0dXJuICAgICAgYSBoYXNodGFibGUgd2hpY2ggY29udGFpbnMgYWxsIGJ1aWx0LWluIHNpbXBsZSB0eXBlcwotICAgICAqLwotICAgIHB1YmxpYyBTeW1ib2xIYXNoIGdldEJ1aWx0SW5UeXBlcygpIHsKLSAgICAgICAgcmV0dXJuIChTeW1ib2xIYXNoKWZCdWlsdEluVHlwZXMubWFrZUNsb25lKCk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi94cy9GbG9hdERWLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L3hzL0Zsb2F0RFYuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOWZmMGVjZi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L3hzL0Zsb2F0RFYuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI0MSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi54czsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5JbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYuVmFsaWRhdGlvbkNvbnRleHQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5kYXRhdHlwZXMuWFNGbG9hdDsKLQotLyoqCi0gKiBSZXByZXNlbnQgdGhlIHNjaGVtYSB0eXBlICJmbG9hdCIKLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBOZWVyYWogQmFqYWosIFN1biBNaWNyb3N5c3RlbXMsIGluYy4KLSAqIEBhdXRob3IgU2FuZHkgR2FvLCBJQk0KLSAqCi0gKiBAdmVyc2lvbiAkSWQ6IEZsb2F0RFYuamF2YSx2IDEuNyAyMDEwLTExLTAxIDA0OjM5OjQ3IGpvZWh3IEV4cCAkCi0gKi8KLXB1YmxpYyBjbGFzcyBGbG9hdERWIGV4dGVuZHMgVHlwZVZhbGlkYXRvciB7Ci0KLSAgICBwdWJsaWMgc2hvcnQgZ2V0QWxsb3dlZEZhY2V0cygpewotICAgICAgICByZXR1cm4gKCBYU1NpbXBsZVR5cGVEZWNsLkZBQ0VUX1BBVFRFUk4gfCBYU1NpbXBsZVR5cGVEZWNsLkZBQ0VUX1dISVRFU1BBQ0UgfCBYU1NpbXBsZVR5cGVEZWNsLkZBQ0VUX0VOVU1FUkFUSU9OIHxYU1NpbXBsZVR5cGVEZWNsLkZBQ0VUX01BWElOQ0xVU0lWRSB8WFNTaW1wbGVUeXBlRGVjbC5GQUNFVF9NSU5JTkNMVVNJVkUgfCBYU1NpbXBsZVR5cGVEZWNsLkZBQ0VUX01BWEVYQ0xVU0lWRSAgfCBYU1NpbXBsZVR5cGVEZWNsLkZBQ0VUX01JTkVYQ0xVU0lWRSAgKTsKLSAgICB9Ly9nZXRBbGxvd2VkRmFjZXRzKCkKLQotICAgIC8vY29udmVydCBhIFN0cmluZyB0byBGbG9hdCBmb3JtLCB3ZSBoYXZlIHRvIHRha2UgY2FyZSBvZiBjYXNlcyBzcGVjaWZpZWQgaW4gc3BlYyBsaWtlIElORiwgLUlORiBhbmQgTmFOCi0gICAgcHVibGljIE9iamVjdCBnZXRBY3R1YWxWYWx1ZShTdHJpbmcgY29udGVudCwgVmFsaWRhdGlvbkNvbnRleHQgY29udGV4dCkgdGhyb3dzIEludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uIHsKLSAgICAgICAgdHJ5ewotICAgICAgICAgICAgcmV0dXJuIG5ldyBYRmxvYXQoY29udGVudCk7Ci0gICAgICAgIH0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBleCl7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24oImN2Yy1kYXRhdHlwZS12YWxpZC4xLjIuMSIsIG5ldyBPYmplY3RbXXtjb250ZW50LCAiZmxvYXQifSk7Ci0gICAgICAgIH0KLSAgICB9Ly9nZXRBY3R1YWxWYWx1ZSgpCi0KLSAgICAvLyBDYW4ndCBjYWxsIEZsb2F0I2NvbXBhcmVUbyBtZXRob2QsIGJlY2F1c2UgaXQncyBpbnRyb2R1Y2VkIGluIGpkayAxLjIKLSAgICBwdWJsaWMgaW50IGNvbXBhcmUoT2JqZWN0IHZhbHVlMSwgT2JqZWN0IHZhbHVlMil7Ci0gICAgICAgIHJldHVybiAoKFhGbG9hdCl2YWx1ZTEpLmNvbXBhcmVUbygoWEZsb2F0KXZhbHVlMik7Ci0gICAgfS8vY29tcGFyZSgpCi0KLSAgICAvL2Rpc3Rpbmd1aXNoZXMgYmV0d2VlbiBpZGVudGl0eSBhbmQgZXF1YWxpdHkgZm9yIGZsb2F0IGRhdGF0eXBlCi0gICAgLy8wLjAgaXMgZXF1YWwgYnV0IG5vdCBpZGVudGljYWwgdG8gLTAuMAotICAgIHB1YmxpYyBib29sZWFuIGlzSWRlbnRpY2FsIChPYmplY3QgdmFsdWUxLCBPYmplY3QgdmFsdWUyKSB7Ci0gICAgICAgIGlmICh2YWx1ZTIgaW5zdGFuY2VvZiBYRmxvYXQpIHsKLSAgICAgICAgICAgIHJldHVybiAoKFhGbG9hdCl2YWx1ZTEpLmlzSWRlbnRpY2FsKChYRmxvYXQpdmFsdWUyKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfS8vaXNJZGVudGljYWwoKQotCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgWEZsb2F0IGltcGxlbWVudHMgWFNGbG9hdCB7Ci0KLSAgICAgICAgcHJpdmF0ZSBmaW5hbCBmbG9hdCB2YWx1ZTsKLSAgICAgICAgcHVibGljIFhGbG9hdChTdHJpbmcgcykgdGhyb3dzIE51bWJlckZvcm1hdEV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICBpZiAoRG91YmxlRFYuaXNQb3NzaWJsZUZQKHMpKSB7Ci0gICAgICAgICAgICAgICAgdmFsdWUgPSBGbG9hdC5wYXJzZUZsb2F0KHMpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoIHMuZXF1YWxzKCJJTkYiKSApIHsKLSAgICAgICAgICAgICAgICB2YWx1ZSA9IEZsb2F0LlBPU0lUSVZFX0lORklOSVRZOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoIHMuZXF1YWxzKCItSU5GIikgKSB7Ci0gICAgICAgICAgICAgICAgdmFsdWUgPSBGbG9hdC5ORUdBVElWRV9JTkZJTklUWTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKCBzLmVxdWFscygiTmFOIikgKSB7Ci0gICAgICAgICAgICAgICAgdmFsdWUgPSBGbG9hdC5OYU47Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVtYmVyRm9ybWF0RXhjZXB0aW9uKHMpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCB2YWwpIHsKLSAgICAgICAgICAgIGlmICh2YWwgPT0gdGhpcykKLSAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLQotICAgICAgICAgICAgaWYgKCEodmFsIGluc3RhbmNlb2YgWEZsb2F0KSkKLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICBYRmxvYXQgb3ZhbCA9IChYRmxvYXQpdmFsOwotCi0gICAgICAgICAgICAvLyBOT1RFOiB3ZSBkb24ndCBkaXN0aW5ndWlzaCAwLjAgZnJvbSAtMC4wCi0gICAgICAgICAgICBpZiAodmFsdWUgPT0gb3ZhbC52YWx1ZSkKLSAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLQotICAgICAgICAgICAgaWYgKHZhbHVlICE9IHZhbHVlICYmIG92YWwudmFsdWUgIT0gb3ZhbC52YWx1ZSkKLSAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLQotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKLSAgICAgICAgICAgIC8vIFRoaXMgY2hlY2sgaXMgbmVjZXNzYXJ5IGJlY2F1c2UgZmxvYXRUb0ludEJpdHMoKzApICE9IGZsb2F0VG9JbnRCaXRzKC0wKQotICAgICAgICAgICAgcmV0dXJuICh2YWx1ZSA9PSAwZikgPyAwIDogRmxvYXQuZmxvYXRUb0ludEJpdHModmFsdWUpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gTk9URTogMC4wIGlzIGVxdWFsIGJ1dCBub3QgaWRlbnRpY2FsIHRvIC0wLjAKLSAgICAgICAgcHVibGljIGJvb2xlYW4gaXNJZGVudGljYWwgKFhGbG9hdCB2YWwpIHsKLSAgICAgICAgICAgIGlmICh2YWwgPT0gdGhpcykgewotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAodmFsdWUgPT0gdmFsLnZhbHVlKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuICh2YWx1ZSAhPSAwLjBmIHx8Ci0gICAgICAgICAgICAgICAgICAgIChGbG9hdC5mbG9hdFRvSW50Qml0cyh2YWx1ZSkgPT0gRmxvYXQuZmxvYXRUb0ludEJpdHModmFsLnZhbHVlKSkpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAodmFsdWUgIT0gdmFsdWUgJiYgdmFsLnZhbHVlICE9IHZhbC52YWx1ZSkKLSAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLQotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0KLSAgICAgICAgcHJpdmF0ZSBpbnQgY29tcGFyZVRvKFhGbG9hdCB2YWwpIHsKLSAgICAgICAgICAgIGZsb2F0IG92YWwgPSB2YWwudmFsdWU7Ci0KLSAgICAgICAgICAgIC8vIHRoaXMgPCBvdGhlcgotICAgICAgICAgICAgaWYgKHZhbHVlIDwgb3ZhbCkKLSAgICAgICAgICAgICAgICByZXR1cm4gLTE7Ci0gICAgICAgICAgICAvLyB0aGlzID4gb3RoZXIKLSAgICAgICAgICAgIGlmICh2YWx1ZSA+IG92YWwpCi0gICAgICAgICAgICAgICAgcmV0dXJuIDE7Ci0gICAgICAgICAgICAvLyB0aGlzID09IG90aGVyCi0gICAgICAgICAgICAvLyBOT1RFOiB3ZSBkb24ndCBkaXN0aW5ndWlzaCAwLjAgZnJvbSAtMC4wCi0gICAgICAgICAgICBpZiAodmFsdWUgPT0gb3ZhbCkKLSAgICAgICAgICAgICAgICByZXR1cm4gMDsKLQotICAgICAgICAgICAgLy8gb25lIG9mIHRoZSAyIHZhbHVlcyBvciBib3RoIGlzL2FyZSBOYU4ocykKLQotICAgICAgICAgICAgaWYgKHZhbHVlICE9IHZhbHVlKSB7Ci0gICAgICAgICAgICAgICAgLy8gdGhpcyA9IE5hTiA9IG90aGVyCi0gICAgICAgICAgICAgICAgaWYgKG92YWwgIT0gb3ZhbCkKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDA7Ci0gICAgICAgICAgICAgICAgLy8gdGhpcyBpcyBOYU4gPD4gb3RoZXIKLSAgICAgICAgICAgICAgICByZXR1cm4gSU5ERVRFUk1JTkFURTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gb3RoZXIgaXMgTmFOIDw+IHRoaXMKLSAgICAgICAgICAgIHJldHVybiBJTkRFVEVSTUlOQVRFOwotICAgICAgICB9Ci0KLSAgICAgICAgcHJpdmF0ZSBTdHJpbmcgY2Fub25pY2FsOwotICAgICAgICBwdWJsaWMgc3luY2hyb25pemVkIFN0cmluZyB0b1N0cmluZygpIHsKLSAgICAgICAgICAgIGlmIChjYW5vbmljYWwgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBGbG9hdC5QT1NJVElWRV9JTkZJTklUWSkKLSAgICAgICAgICAgICAgICAgICAgY2Fub25pY2FsID0gIklORiI7Ci0gICAgICAgICAgICAgICAgZWxzZSBpZiAodmFsdWUgPT0gRmxvYXQuTkVHQVRJVkVfSU5GSU5JVFkpCi0gICAgICAgICAgICAgICAgICAgIGNhbm9uaWNhbCA9ICItSU5GIjsKLSAgICAgICAgICAgICAgICBlbHNlIGlmICh2YWx1ZSAhPSB2YWx1ZSkKLSAgICAgICAgICAgICAgICAgICAgY2Fub25pY2FsID0gIk5hTiI7Ci0gICAgICAgICAgICAgICAgLy8gTk9URTogd2UgZG9uJ3QgZGlzdGluZ3Vpc2ggMC4wIGZyb20gLTAuMAotICAgICAgICAgICAgICAgIGVsc2UgaWYgKHZhbHVlID09IDApCi0gICAgICAgICAgICAgICAgICAgIGNhbm9uaWNhbCA9ICIwLjBFMSI7Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIFJFVklTSVQ6IHVzZSB0aGUgamF2YSBhbGdvcml0aG0gZm9yIG5vdywgYmVjYXVzZSB3ZQotICAgICAgICAgICAgICAgICAgICAvLyBkb24ndCBrbm93IHdoYXQgdG8gb3V0cHV0IGZvciAxLjFmICh3aGljaCBpcyBubwotICAgICAgICAgICAgICAgICAgICAvLyBhY3R1YWxseSAxLjEpCi0gICAgICAgICAgICAgICAgICAgIGNhbm9uaWNhbCA9IEZsb2F0LnRvU3RyaW5nKHZhbHVlKTsKLSAgICAgICAgICAgICAgICAgICAgLy8gaWYgaXQgY29udGFpbnMgJ0UnLCB0aGVuIGl0IHNob3VsZCBiZSBhIHZhbGlkIHNjaGVtYQotICAgICAgICAgICAgICAgICAgICAvLyBjYW5vbmljYWwgcmVwcmVzZW50YXRpb24KLSAgICAgICAgICAgICAgICAgICAgaWYgKGNhbm9uaWNhbC5pbmRleE9mKCdFJykgPT0gLTEpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGludCBsZW4gPSBjYW5vbmljYWwubGVuZ3RoKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBhdCBtb3N0IDMgbG9uZ2VyOiBFLCAtLCA5Ci0gICAgICAgICAgICAgICAgICAgICAgICBjaGFyW10gY2hhcnMgPSBuZXcgY2hhcltsZW4rM107Ci0gICAgICAgICAgICAgICAgICAgICAgICBjYW5vbmljYWwuZ2V0Q2hhcnMoMCwgbGVuLCBjaGFycywgMCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBleHBlY3RlZCBkZWNpbWFsIHBvaW50IHBvc2l0aW9uCi0gICAgICAgICAgICAgICAgICAgICAgICBpbnQgZWRwID0gY2hhcnNbMF0gPT0gJy0nID8gMiA6IDE7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBmb3Igbm9uLXplcm8gaW50ZWdlciBwYXJ0Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWUgPj0gMSB8fCB2YWx1ZSA8PSAtMSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGRlY2ltYWwgcG9pbnQgcG9zaXRpb24KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgZHAgPSBjYW5vbmljYWwuaW5kZXhPZignLicpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG1vdmUgdGhlIGRpZ2l0czogZGRkLmQgLS0+IGQuZGRkCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IGRwOyBpID4gZWRwOyBpLS0pIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhcnNbaV0gPSBjaGFyc1tpLTFdOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFyc1tlZHBdID0gJy4nOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRyaW0gdHJhaWxpbmcgemVyb3M6IGQwMC4wIC0tPiBkLjAwMCAtLT4gZC4KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoY2hhcnNbbGVuLTFdID09ICcwJykKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVuLS07Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYWRkIHRoZSBsYXN0IHplcm8gaWYgbmVjZXNzYXJ5OiBkLiAtLT4gZC4wCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNoYXJzW2xlbi0xXSA9PSAnLicpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlbisrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFwcGVuZCBFOiBkLmRkIC0tPiBkLmRkRQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYXJzW2xlbisrXSA9ICdFJzsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBob3cgZmFyIHdlIHNoaWZ0ZWQgdGhlIGRlY2ltYWwgcG9pbnQKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgc2hpZnQgPSBkcCAtIGVkcDsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBhcHBlbmQgdGhlIGV4cG9uZW50IC0tPiBkLmRkRWQKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGUgZXhwb25lbnQgaXMgYXQgbW9zdCA3Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhcnNbbGVuKytdID0gKGNoYXIpKHNoaWZ0ICsgJzAnKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG5vbi16ZXJvIGRpZ2l0IHBvaW50Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG56cCA9IGVkcCArIDE7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2tpcCB6ZXJvczogMC4wMDMKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoY2hhcnNbbnpwXSA9PSAnMCcpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG56cCsrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHB1dCB0aGUgZmlyc3Qgbm9uLXplcm8gZGlnaXQgdG8gdGhlIGxlZnQgb2YgJy4nCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhcnNbZWRwLTFdID0gY2hhcnNbbnpwXTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFyc1tlZHBdID0gJy4nOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG1vdmUgb3RoZXIgZGlnaXRzIChub24temVybykgdG8gdGhlIHJpZ2h0IG9mICcuJwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSBuenArMSwgaiA9IGVkcCsxOyBpIDwgbGVuOyBpKyssIGorKykKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhcnNbal0gPSBjaGFyc1tpXTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBhZGp1c3QgdGhlIGxlbmd0aAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlbiAtPSBuenAgLSBlZHA7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYXBwZW5kIDAgaWYgbmVzc2FyeTogMC4wMyAtLT4gMy4gLS0+IDMuMAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsZW4gPT0gZWRwICsgMSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhcnNbbGVuKytdID0gJzAnOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFwcGVuZCBFLTogZC5kZCAtLT4gZC5kZEUtCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhcnNbbGVuKytdID0gJ0UnOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYXJzW2xlbisrXSA9ICctJzsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBob3cgZmFyIHdlIHNoaWZ0ZWQgdGhlIGRlY2ltYWwgcG9pbnQKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgc2hpZnQgPSBuenAgLSBlZHA7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYXBwZW5kIHRoZSBleHBvbmVudCAtLT4gZC5kZEVkCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhlIGV4cG9uZW50IGlzIGF0IG1vc3QgMwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYXJzW2xlbisrXSA9IChjaGFyKShzaGlmdCArICcwJyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBjYW5vbmljYWwgPSBuZXcgU3RyaW5nKGNoYXJzLCAwLCBsZW4pOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIGNhbm9uaWNhbDsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyBmbG9hdCBnZXRWYWx1ZSgpIHsKLSAgICAgICAgICAgIHJldHVybiB2YWx1ZTsKLSAgICAgICAgfQotICAgIH0KLX0gLy8gY2xhc3MgRmxvYXREVgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi94cy9GdWxsRFZGYWN0b3J5LmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L3hzL0Z1bGxEVkZhY3RvcnkuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZDAwM2M0OC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L3hzL0Z1bGxEVkZhY3RvcnkuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE2OCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAyLCAyMDAzLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi54czsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5YU1NpbXBsZVR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LlhTRmFjZXRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5TeW1ib2xIYXNoOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNDb25zdGFudHM7Ci0KLS8qKgotICogdGhlIGZhY3RvcnkgdG8gY3JlYXRlL3JldHVybiBidWlsdC1pbiBzY2hlbWEgRFZzIGFuZCBjcmVhdGUgdXNlci1kZWZpbmVkIERWcwotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIE5lZXJhaiBCYWphaiwgU3VuIE1pY3Jvc3lzdGVtcywgaW5jLgotICogQGF1dGhvciBTYW5keSBHYW8sIElCTQotICoKLSAqLwotcHVibGljIGNsYXNzIEZ1bGxEVkZhY3RvcnkgZXh0ZW5kcyBCYXNlRFZGYWN0b3J5IHsKLQotICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgVVJJX1NDSEVNQUZPUlNDSEVNQSA9ICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYSI7Ci0KLSAgICAvLyB0aGVyZSBhcmUgNDUgdHlwZXMuIDg5IGlzIHRoZSBjbG9zZXN0IHByaW1lIG51bWJlciB0byA0NSoyPTkwLgotICAgIHN0YXRpYyBTeW1ib2xIYXNoIGZGdWxsVHlwZXMgPSBuZXcgU3ltYm9sSGFzaCg4OSk7Ci0gICAgc3RhdGljIHsKLSAgICAgICAgY3JlYXRlQnVpbHRJblR5cGVzKGZGdWxsVHlwZXMpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCBhIGJ1aWx0LWluIHNpbXBsZSB0eXBlIG9mIHRoZSBnaXZlbiBuYW1lCi0gICAgICogUkVWSVNJVDogaXRzIHN0aWxsIG5vdCBkZWNpZGVkIHdpdGhpbiB0aGUgU2NoZW1hIFdHIGhvdyB0byBkZWZpbmUgdGhlCi0gICAgICogICAgICAgICAgdXItdHlwZXMgYW5kIGlmIGFsbCBzaW1wbGUgdHlwZXMgc2hvdWxkIGJlIGRlcml2ZWQgZnJvbSBhCi0gICAgICogICAgICAgICAgY29tcGxleCB0eXBlLCBzbyBhcyBvZiBub3cgd2UgaWdub3JlIHRoZSBmYWN0IHRoYXQgYW55U2ltcGxlVHlwZQotICAgICAqICAgICAgICAgIGlzIGRlcml2ZWQgZnJvbSBhbnlUeXBlLCBhbmQgcGFzcyAnbnVsbCcgYXMgdGhlIGJhc2Ugb2YKLSAgICAgKiAgICAgICAgICBhbnlTaW1wbGVUeXBlLiBJdCBuZWVkcyB0byBiZSBjaGFuZ2VkIGFzIHBlciB0aGUgZGVjaXNpb24gdGFrZW4uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSAgdGhlIG5hbWUgb2YgdGhlIGRhdGF0eXBlCi0gICAgICogQHJldHVybiAgICAgIHRoZSBkYXRhdHlwZSB2YWxpZGF0b3Igb2YgdGhlIGdpdmVuIG5hbWUKLSAgICAgKi8KLSAgICBwdWJsaWMgWFNTaW1wbGVUeXBlIGdldEJ1aWx0SW5UeXBlKFN0cmluZyBuYW1lKSB7Ci0gICAgICAgIHJldHVybiAoWFNTaW1wbGVUeXBlKWZGdWxsVHlwZXMuZ2V0KG5hbWUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIGdldCBhbGwgYnVpbHQtaW4gc2ltcGxlIHR5cGVzLCB3aGljaCBhcmUgc3RvcmVkIGluIGEgaGFzaHRhYmxlIGtleWVkIGJ5Ci0gICAgICogdGhlIG5hbWUKLSAgICAgKgotICAgICAqIEByZXR1cm4gICAgICBhIGhhc2h0YWJsZSB3aGljaCBjb250YWlucyBhbGwgYnVpbHQtaW4gc2ltcGxlIHR5cGVzCi0gICAgICovCi0gICAgcHVibGljIFN5bWJvbEhhc2ggZ2V0QnVpbHRJblR5cGVzKCkgewotICAgICAgICByZXR1cm4gKFN5bWJvbEhhc2gpZkZ1bGxUeXBlcy5tYWtlQ2xvbmUoKTsKLSAgICB9Ci0KLSAgICAvLyBjcmVhdGUgYWxsIGJ1aWx0LWluIHR5cGVzCi0gICAgc3RhdGljIHZvaWQgY3JlYXRlQnVpbHRJblR5cGVzKFN5bWJvbEhhc2ggdHlwZXMpIHsKLSAgICAgICAgLy8gY3JlYXRlIGJhc2UgdHlwZXMgZmlyc3QKLSAgICAgICAgQmFzZURWRmFjdG9yeS5jcmVhdGVCdWlsdEluVHlwZXModHlwZXMpOwotCi0gICAgICAgIC8vIGZ1bGwgc2NoZW1hIHNpbXBsZSB0eXBlIG5hbWVzCi0gICAgICAgIGZpbmFsIFN0cmluZyBET1VCTEUgICAgICAgICAgICA9ICJkb3VibGUiOwotICAgICAgICBmaW5hbCBTdHJpbmcgRFVSQVRJT04gICAgICAgICAgPSAiZHVyYXRpb24iOwotICAgICAgICBmaW5hbCBTdHJpbmcgRU5USVRZICAgICAgICAgICAgPSAiRU5USVRZIjsKLSAgICAgICAgZmluYWwgU3RyaW5nIEVOVElUSUVTICAgICAgICAgID0gIkVOVElUSUVTIjsKLSAgICAgICAgZmluYWwgU3RyaW5nIEZMT0FUICAgICAgICAgICAgID0gImZsb2F0IjsKLSAgICAgICAgZmluYWwgU3RyaW5nIEhFWEJJTkFSWSAgICAgICAgID0gImhleEJpbmFyeSI7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBJRCAgICAgICAgICAgICAgICA9ICJJRCI7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBJRFJFRiAgICAgICAgICAgICA9ICJJRFJFRiI7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBJRFJFRlMgICAgICAgICAgICA9ICJJRFJFRlMiOwotICAgICAgICBmaW5hbCBTdHJpbmcgTkFNRSAgICAgICAgICAgICAgPSAiTmFtZSI7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBOQ05BTUUgICAgICAgICAgICA9ICJOQ05hbWUiOwotICAgICAgICBmaW5hbCBTdHJpbmcgTk1UT0tFTiAgICAgICAgICAgPSAiTk1UT0tFTiI7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBOTVRPS0VOUyAgICAgICAgICA9ICJOTVRPS0VOUyI7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBMQU5HVUFHRSAgICAgICAgICA9ICJsYW5ndWFnZSI7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBOT1JNQUxJWkVEU1RSSU5HICA9ICJub3JtYWxpemVkU3RyaW5nIjsKLSAgICAgICAgZmluYWwgU3RyaW5nIE5PVEFUSU9OICAgICAgICAgID0gIk5PVEFUSU9OIjsKLSAgICAgICAgZmluYWwgU3RyaW5nIFFOQU1FICAgICAgICAgICAgID0gIlFOYW1lIjsKLSAgICAgICAgZmluYWwgU3RyaW5nIFNUUklORyAgICAgICAgICAgID0gInN0cmluZyI7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBUT0tFTiAgICAgICAgICAgICA9ICJ0b2tlbiI7Ci0KLSAgICAgICAgZmluYWwgWFNGYWNldHMgZmFjZXRzID0gbmV3IFhTRmFjZXRzKCk7Ci0KLSAgICAgICAgWFNTaW1wbGVUeXBlRGVjbCBhbnlTaW1wbGVUeXBlID0gWFNTaW1wbGVUeXBlRGVjbC5mQW55U2ltcGxlVHlwZTsKLSAgICAgICAgWFNTaW1wbGVUeXBlRGVjbCBzdHJpbmdEViA9IChYU1NpbXBsZVR5cGVEZWNsKXR5cGVzLmdldChTVFJJTkcpOwotCi0gICAgICAgIHR5cGVzLnB1dChGTE9BVCwgbmV3IFhTU2ltcGxlVHlwZURlY2woYW55U2ltcGxlVHlwZSwgRkxPQVQsIFhTU2ltcGxlVHlwZURlY2wuRFZfRkxPQVQsIFhTU2ltcGxlVHlwZS5PUkRFUkVEX1BBUlRJQUwsIHRydWUsIHRydWUsIHRydWUsIHRydWUsIFhTQ29uc3RhbnRzLkZMT0FUX0RUKSk7Ci0gICAgICAgIHR5cGVzLnB1dChET1VCTEUsIG5ldyBYU1NpbXBsZVR5cGVEZWNsKGFueVNpbXBsZVR5cGUsIERPVUJMRSwgWFNTaW1wbGVUeXBlRGVjbC5EVl9ET1VCTEUsIFhTU2ltcGxlVHlwZS5PUkRFUkVEX1BBUlRJQUwsIHRydWUsIHRydWUsIHRydWUsIHRydWUsIFhTQ29uc3RhbnRzLkRPVUJMRV9EVCkpOwotICAgICAgICB0eXBlcy5wdXQoRFVSQVRJT04sIG5ldyBYU1NpbXBsZVR5cGVEZWNsKGFueVNpbXBsZVR5cGUsIERVUkFUSU9OLCBYU1NpbXBsZVR5cGVEZWNsLkRWX0RVUkFUSU9OLCBYU1NpbXBsZVR5cGUuT1JERVJFRF9QQVJUSUFMLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCB0cnVlLCBYU0NvbnN0YW50cy5EVVJBVElPTl9EVCkpOwotICAgICAgICB0eXBlcy5wdXQoSEVYQklOQVJZLCBuZXcgWFNTaW1wbGVUeXBlRGVjbChhbnlTaW1wbGVUeXBlLCBIRVhCSU5BUlksIFhTU2ltcGxlVHlwZURlY2wuRFZfSEVYQklOQVJZLCBYU1NpbXBsZVR5cGUuT1JERVJFRF9GQUxTRSwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgdHJ1ZSwgWFNDb25zdGFudHMuSEVYQklOQVJZX0RUKSk7Ci0gICAgICAgIHR5cGVzLnB1dChRTkFNRSwgbmV3IFhTU2ltcGxlVHlwZURlY2woYW55U2ltcGxlVHlwZSwgUU5BTUUsIFhTU2ltcGxlVHlwZURlY2wuRFZfUU5BTUUsIFhTU2ltcGxlVHlwZS5PUkRFUkVEX0ZBTFNFLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCB0cnVlLCBYU0NvbnN0YW50cy5RTkFNRV9EVCkpOwotICAgICAgICB0eXBlcy5wdXQoTk9UQVRJT04sIG5ldyBYU1NpbXBsZVR5cGVEZWNsKGFueVNpbXBsZVR5cGUsIE5PVEFUSU9OLCBYU1NpbXBsZVR5cGVEZWNsLkRWX05PVEFUSU9OLCBYU1NpbXBsZVR5cGUuT1JERVJFRF9GQUxTRSwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgdHJ1ZSwgWFNDb25zdGFudHMuTk9UQVRJT05fRFQpKTsKLQotICAgICAgICBmYWNldHMud2hpdGVTcGFjZSA9ICBYU1NpbXBsZVR5cGUuV1NfUkVQTEFDRTsKLSAgICAgICAgWFNTaW1wbGVUeXBlRGVjbCBub3JtYWxpemVkRFYgPSBuZXcgWFNTaW1wbGVUeXBlRGVjbChzdHJpbmdEViwgTk9STUFMSVpFRFNUUklORyAsIFVSSV9TQ0hFTUFGT1JTQ0hFTUEsIChzaG9ydCkwLCBmYWxzZSwgbnVsbCwgWFNDb25zdGFudHMuTk9STUFMSVpFRFNUUklOR19EVCk7Ci0gICAgICAgIG5vcm1hbGl6ZWREVi5hcHBseUZhY2V0czEoZmFjZXRzLCBYU1NpbXBsZVR5cGUuRkFDRVRfV0hJVEVTUEFDRSwgKHNob3J0KTAgKTsKLSAgICAgICAgdHlwZXMucHV0KE5PUk1BTElaRURTVFJJTkcsIG5vcm1hbGl6ZWREVik7Ci0KLSAgICAgICAgZmFjZXRzLndoaXRlU3BhY2UgPSBYU1NpbXBsZVR5cGUuV1NfQ09MTEFQU0U7Ci0gICAgICAgIFhTU2ltcGxlVHlwZURlY2wgdG9rZW5EViA9IG5ldyBYU1NpbXBsZVR5cGVEZWNsKG5vcm1hbGl6ZWREViwgVE9LRU4gLCBVUklfU0NIRU1BRk9SU0NIRU1BLCAoc2hvcnQpMCwgZmFsc2UsIG51bGwsIFhTQ29uc3RhbnRzLlRPS0VOX0RUKTsKLSAgICAgICAgdG9rZW5EVi5hcHBseUZhY2V0czEoZmFjZXRzLCBYU1NpbXBsZVR5cGUuRkFDRVRfV0hJVEVTUEFDRSwgKHNob3J0KTAgKTsKLSAgICAgICAgdHlwZXMucHV0KFRPS0VOLCB0b2tlbkRWKTsKLQotICAgICAgICBmYWNldHMud2hpdGVTcGFjZSA9IFhTU2ltcGxlVHlwZS5XU19DT0xMQVBTRTsKLSAgICAgICAgZmFjZXRzLnBhdHRlcm4gID0gIihbYS16QS1aXXsxLDh9KSgtW2EtekEtWjAtOV17MSw4fSkqIjsKLSAgICAgICAgWFNTaW1wbGVUeXBlRGVjbCBsYW5ndWFnZURWID0gbmV3IFhTU2ltcGxlVHlwZURlY2wodG9rZW5EViwgTEFOR1VBR0UgLCBVUklfU0NIRU1BRk9SU0NIRU1BLCAoc2hvcnQpMCwgZmFsc2UsIG51bGwsIFhTQ29uc3RhbnRzLkxBTkdVQUdFX0RUKTsKLSAgICAgICAgbGFuZ3VhZ2VEVi5hcHBseUZhY2V0czEoZmFjZXRzLCAoc2hvcnQpKFhTU2ltcGxlVHlwZS5GQUNFVF9XSElURVNQQUNFIHwgWFNTaW1wbGVUeXBlLkZBQ0VUX1BBVFRFUk4pICwoc2hvcnQpMCk7Ci0gICAgICAgIHR5cGVzLnB1dChMQU5HVUFHRSwgbGFuZ3VhZ2VEVik7Ci0KLSAgICAgICAgZmFjZXRzLndoaXRlU3BhY2UgPSAgWFNTaW1wbGVUeXBlLldTX0NPTExBUFNFOwotICAgICAgICBYU1NpbXBsZVR5cGVEZWNsIG5hbWVEViA9IG5ldyBYU1NpbXBsZVR5cGVEZWNsKHRva2VuRFYsIE5BTUUgLCBVUklfU0NIRU1BRk9SU0NIRU1BLCAoc2hvcnQpMCwgZmFsc2UsIG51bGwsIFhTQ29uc3RhbnRzLk5BTUVfRFQpOwotICAgICAgICBuYW1lRFYuYXBwbHlGYWNldHMxKGZhY2V0cywgWFNTaW1wbGVUeXBlLkZBQ0VUX1dISVRFU1BBQ0UsIChzaG9ydCkwLCBYU1NpbXBsZVR5cGVEZWNsLlNQRUNJQUxfUEFUVEVSTl9OQU1FKTsKLSAgICAgICAgdHlwZXMucHV0KE5BTUUsIG5hbWVEVik7Ci0KLSAgICAgICAgZmFjZXRzLndoaXRlU3BhY2UgPSBYU1NpbXBsZVR5cGUuV1NfQ09MTEFQU0U7Ci0gICAgICAgIFhTU2ltcGxlVHlwZURlY2wgbmNuYW1lRFYgPSBuZXcgWFNTaW1wbGVUeXBlRGVjbChuYW1lRFYsIE5DTkFNRSAsIFVSSV9TQ0hFTUFGT1JTQ0hFTUEsIChzaG9ydCkwLCBmYWxzZSwgbnVsbCwgWFNDb25zdGFudHMuTkNOQU1FX0RUKSA7Ci0gICAgICAgIG5jbmFtZURWLmFwcGx5RmFjZXRzMShmYWNldHMsIFhTU2ltcGxlVHlwZS5GQUNFVF9XSElURVNQQUNFLCAoc2hvcnQpMCwgWFNTaW1wbGVUeXBlRGVjbC5TUEVDSUFMX1BBVFRFUk5fTkNOQU1FKTsKLSAgICAgICAgdHlwZXMucHV0KE5DTkFNRSwgbmNuYW1lRFYpOwotCi0gICAgICAgIHR5cGVzLnB1dChJRCwgbmV3IFhTU2ltcGxlVHlwZURlY2wobmNuYW1lRFYsICBJRCwgWFNTaW1wbGVUeXBlRGVjbC5EVl9JRCwgWFNTaW1wbGVUeXBlLk9SREVSRURfRkFMU0UsIGZhbHNlLCBmYWxzZSwgZmFsc2UgLCB0cnVlLCBYU0NvbnN0YW50cy5JRF9EVCkpOwotICAgICAgICBYU1NpbXBsZVR5cGVEZWNsIGlkcmVmRFYgPSBuZXcgWFNTaW1wbGVUeXBlRGVjbChuY25hbWVEViwgIElEUkVGICwgWFNTaW1wbGVUeXBlRGVjbC5EVl9JRFJFRiwgWFNTaW1wbGVUeXBlLk9SREVSRURfRkFMU0UsIGZhbHNlLCBmYWxzZSwgZmFsc2UsIHRydWUsIFhTQ29uc3RhbnRzLklEUkVGX0RUKTsKLSAgICAgICAgdHlwZXMucHV0KElEUkVGLCBpZHJlZkRWKTsKLQotICAgICAgICBmYWNldHMubWluTGVuZ3RoID0gMTsKLSAgICAgICAgWFNTaW1wbGVUeXBlRGVjbCB0ZW1wRFYgPSBuZXcgWFNTaW1wbGVUeXBlRGVjbChudWxsLCBVUklfU0NIRU1BRk9SU0NIRU1BLCAoc2hvcnQpMCwgaWRyZWZEViwgdHJ1ZSwgbnVsbCk7Ci0gICAgICAgIFhTU2ltcGxlVHlwZURlY2wgaWRyZWZzRFYgPSBuZXcgWFNTaW1wbGVUeXBlRGVjbCh0ZW1wRFYsIElEUkVGUywgVVJJX1NDSEVNQUZPUlNDSEVNQSwgKHNob3J0KTAsIGZhbHNlLCBudWxsKTsKLSAgICAgICAgaWRyZWZzRFYuYXBwbHlGYWNldHMxKGZhY2V0cywgWFNTaW1wbGVUeXBlLkZBQ0VUX01JTkxFTkdUSCwgKHNob3J0KTApOwotICAgICAgICB0eXBlcy5wdXQoSURSRUZTLCBpZHJlZnNEVik7Ci0KLSAgICAgICAgWFNTaW1wbGVUeXBlRGVjbCBlbnRpdHlEViA9IG5ldyBYU1NpbXBsZVR5cGVEZWNsKG5jbmFtZURWLCBFTlRJVFkgLCBYU1NpbXBsZVR5cGVEZWNsLkRWX0VOVElUWSwgWFNTaW1wbGVUeXBlLk9SREVSRURfRkFMU0UsIGZhbHNlLCBmYWxzZSwgZmFsc2UsIHRydWUsIFhTQ29uc3RhbnRzLkVOVElUWV9EVCk7Ci0gICAgICAgIHR5cGVzLnB1dChFTlRJVFksIGVudGl0eURWKTsKLQotICAgICAgICBmYWNldHMubWluTGVuZ3RoID0gMTsKLSAgICAgICAgdGVtcERWID0gbmV3IFhTU2ltcGxlVHlwZURlY2wobnVsbCwgVVJJX1NDSEVNQUZPUlNDSEVNQSwgKHNob3J0KTAsIGVudGl0eURWLCB0cnVlLCBudWxsKTsKLSAgICAgICAgWFNTaW1wbGVUeXBlRGVjbCBlbnRpdGllc0RWID0gbmV3IFhTU2ltcGxlVHlwZURlY2wodGVtcERWLCBFTlRJVElFUywgVVJJX1NDSEVNQUZPUlNDSEVNQSwgKHNob3J0KTAsIGZhbHNlLCBudWxsKTsKLSAgICAgICAgZW50aXRpZXNEVi5hcHBseUZhY2V0czEoZmFjZXRzLCBYU1NpbXBsZVR5cGUuRkFDRVRfTUlOTEVOR1RILCAoc2hvcnQpMCk7Ci0gICAgICAgIHR5cGVzLnB1dChFTlRJVElFUywgZW50aXRpZXNEVik7Ci0KLQotICAgICAgICBmYWNldHMud2hpdGVTcGFjZSAgPSBYU1NpbXBsZVR5cGUuV1NfQ09MTEFQU0U7Ci0gICAgICAgIFhTU2ltcGxlVHlwZURlY2wgbm10b2tlbkRWID0gbmV3IFhTU2ltcGxlVHlwZURlY2wodG9rZW5EViwgTk1UT0tFTiwgVVJJX1NDSEVNQUZPUlNDSEVNQSwgKHNob3J0KTAsIGZhbHNlLCBudWxsLCBYU0NvbnN0YW50cy5OTVRPS0VOX0RUKTsKLSAgICAgICAgbm10b2tlbkRWLmFwcGx5RmFjZXRzMShmYWNldHMsIFhTU2ltcGxlVHlwZS5GQUNFVF9XSElURVNQQUNFLCAoc2hvcnQpMCwgWFNTaW1wbGVUeXBlRGVjbC5TUEVDSUFMX1BBVFRFUk5fTk1UT0tFTik7Ci0gICAgICAgIHR5cGVzLnB1dChOTVRPS0VOLCBubXRva2VuRFYpOwotCi0gICAgICAgIGZhY2V0cy5taW5MZW5ndGggPSAxOwotICAgICAgICB0ZW1wRFYgPSBuZXcgWFNTaW1wbGVUeXBlRGVjbChudWxsLCBVUklfU0NIRU1BRk9SU0NIRU1BLCAoc2hvcnQpMCwgbm10b2tlbkRWLCB0cnVlLCBudWxsKTsKLSAgICAgICAgWFNTaW1wbGVUeXBlRGVjbCBubXRva2Vuc0RWID0gbmV3IFhTU2ltcGxlVHlwZURlY2wodGVtcERWLCBOTVRPS0VOUywgVVJJX1NDSEVNQUZPUlNDSEVNQSwgKHNob3J0KTAsIGZhbHNlLCBudWxsKTsKLSAgICAgICAgbm10b2tlbnNEVi5hcHBseUZhY2V0czEoZmFjZXRzLCBYU1NpbXBsZVR5cGUuRkFDRVRfTUlOTEVOR1RILCAoc2hvcnQpMCk7Ci0gICAgICAgIHR5cGVzLnB1dChOTVRPS0VOUywgbm10b2tlbnNEVik7Ci0gICAgfS8vY3JlYXRlQnVpbHRJblR5cGVzKFN5bWJvbEhhc2gpCi0KLX0vL1hGb3Jtc0RWRmFjdG9yeQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi94cy9IZXhCaW5hcnlEVi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi94cy9IZXhCaW5hcnlEVi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyYjg3MjI2Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYveHMvSGV4QmluYXJ5RFYuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDkxICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEsIDIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LnhzOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LkludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5WYWxpZGF0aW9uQ29udGV4dDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYudXRpbC5CeXRlTGlzdEltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LnV0aWwuSGV4QmluOwotCi0vKioKLSAqIFJlcHJlc2VudCB0aGUgc2NoZW1hIHR5cGUgImhleEJpbmFyeSIKLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBOZWVyYWogQmFqYWosIFN1biBNaWNyb3N5c3RlbXMsIGluYy4KLSAqIEBhdXRob3IgU2FuZHkgR2FvLCBJQk0KLSAqCi0gKiBAdmVyc2lvbiAkSWQ6IEhleEJpbmFyeURWLmphdmEsdiAxLjcgMjAxMC0xMS0wMSAwNDozOTo0NyBqb2VodyBFeHAgJAotICovCi1wdWJsaWMgY2xhc3MgSGV4QmluYXJ5RFYgZXh0ZW5kcyBUeXBlVmFsaWRhdG9yIHsKLQotICAgIHB1YmxpYyBzaG9ydCBnZXRBbGxvd2VkRmFjZXRzKCl7Ci0gICAgICAgIHJldHVybiAoWFNTaW1wbGVUeXBlRGVjbC5GQUNFVF9MRU5HVEggfCBYU1NpbXBsZVR5cGVEZWNsLkZBQ0VUX01JTkxFTkdUSCB8IFhTU2ltcGxlVHlwZURlY2wuRkFDRVRfTUFYTEVOR1RIIHwgWFNTaW1wbGVUeXBlRGVjbC5GQUNFVF9QQVRURVJOIHwgWFNTaW1wbGVUeXBlRGVjbC5GQUNFVF9FTlVNRVJBVElPTiB8IFhTU2ltcGxlVHlwZURlY2wuRkFDRVRfV0hJVEVTUEFDRSApOwotICAgIH0KLQotICAgIHB1YmxpYyBPYmplY3QgZ2V0QWN0dWFsVmFsdWUoU3RyaW5nIGNvbnRlbnQsIFZhbGlkYXRpb25Db250ZXh0IGNvbnRleHQpIHRocm93cyBJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbiB7Ci0gICAgICAgIGJ5dGVbXSBkZWNvZGVkID0gSGV4QmluLmRlY29kZShjb250ZW50KTsKLSAgICAgICAgaWYgKGRlY29kZWQgPT0gbnVsbCkKLSAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbigiY3ZjLWRhdGF0eXBlLXZhbGlkLjEuMi4xIiwgbmV3IE9iamVjdFtde2NvbnRlbnQsICJoZXhCaW5hcnkifSk7Ci0KLSAgICAgICAgcmV0dXJuIG5ldyBYSGV4KGRlY29kZWQpOwotICAgIH0KLQotICAgIC8vIGxlbmd0aCBvZiBhIGJpbmFyeSB0eXBlIGlzIHRoZSBudW1iZXIgb2YgYnl0ZXMKLSAgICBwdWJsaWMgaW50IGdldERhdGFMZW5ndGgoT2JqZWN0IHZhbHVlKSB7Ci0gICAgICAgIHJldHVybiAoKFhIZXgpdmFsdWUpLmdldExlbmd0aCgpOwotICAgIH0KLQotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIFhIZXggZXh0ZW5kcyBCeXRlTGlzdEltcGwgewotCi0gICAgICAgIHB1YmxpYyBYSGV4KGJ5dGVbXSBkYXRhKSB7Ci0gICAgICAgICAgICBzdXBlcihkYXRhKTsKLSAgICAgICAgfQotICAgICAgICBwdWJsaWMgc3luY2hyb25pemVkIFN0cmluZyB0b1N0cmluZygpIHsKLSAgICAgICAgICAgIGlmIChjYW5vbmljYWwgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGNhbm9uaWNhbCA9IEhleEJpbi5lbmNvZGUoZGF0YSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gY2Fub25pY2FsOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmopIHsKLSAgICAgICAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIFhIZXgpKQotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIGJ5dGVbXSBvZGF0YSA9ICgoWEhleClvYmopLmRhdGE7Ci0gICAgICAgICAgICBpbnQgbGVuID0gZGF0YS5sZW5ndGg7Ci0gICAgICAgICAgICBpZiAobGVuICE9IG9kYXRhLmxlbmd0aCkKLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbjsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGRhdGFbaV0gIT0gb2RhdGFbaV0pCi0gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKLSAgICAgICAgICAgIGludCBoYXNoID0gMDsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZGF0YS5sZW5ndGg7ICsraSkgewotICAgICAgICAgICAgICAgIGhhc2ggPSBoYXNoICogMzcgKyAoKChpbnQpIGRhdGFbaV0pICYgMHhmZik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gaGFzaDsKLSAgICAgICAgfQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYveHMvSUREVi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi94cy9JRERWLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDkxNjIxZDQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi94cy9JRERWLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw1NSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLCAyMDAyLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi54czsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5JbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuWE1MQ2hhcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYuVmFsaWRhdGlvbkNvbnRleHQ7Ci0KLS8qKgotICogUmVwcmVzZW50IHRoZSBzY2hlbWEgdHlwZSAiSUQiCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgTmVlcmFqIEJhamFqLCBTdW4gTWljcm9zeXN0ZW1zLCBpbmMuCi0gKiBAYXV0aG9yIFNhbmR5IEdhbywgSUJNCi0gKgotICovCi1wdWJsaWMgY2xhc3MgSUREViBleHRlbmRzIFR5cGVWYWxpZGF0b3J7Ci0KLSAgICBwdWJsaWMgc2hvcnQgZ2V0QWxsb3dlZEZhY2V0cygpewotICAgICAgICByZXR1cm4gKFhTU2ltcGxlVHlwZURlY2wuRkFDRVRfTEVOR1RIIHwgWFNTaW1wbGVUeXBlRGVjbC5GQUNFVF9NSU5MRU5HVEggfCBYU1NpbXBsZVR5cGVEZWNsLkZBQ0VUX01BWExFTkdUSCB8IFhTU2ltcGxlVHlwZURlY2wuRkFDRVRfUEFUVEVSTiB8IFhTU2ltcGxlVHlwZURlY2wuRkFDRVRfRU5VTUVSQVRJT04gfCBYU1NpbXBsZVR5cGVEZWNsLkZBQ0VUX1dISVRFU1BBQ0UgKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgT2JqZWN0IGdldEFjdHVhbFZhbHVlKFN0cmluZyBjb250ZW50LCBWYWxpZGF0aW9uQ29udGV4dCBjb250ZXh0KSB0aHJvd3MgSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24gewotICAgICAgICBpZiAoIVhNTENoYXIuaXNWYWxpZE5DTmFtZShjb250ZW50KSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uKCJjdmMtZGF0YXR5cGUtdmFsaWQuMS4yLjEiLCBuZXcgT2JqZWN0W117Y29udGVudCwgIk5DTmFtZSJ9KTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gY29udGVudDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBjaGVja0V4dHJhUnVsZXMoT2JqZWN0IHZhbHVlLCBWYWxpZGF0aW9uQ29udGV4dCBjb250ZXh0KSB0aHJvd3MgSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24gewotICAgICAgICBTdHJpbmcgY29udGVudCA9IChTdHJpbmcpdmFsdWU7Ci0gICAgICAgIGlmIChjb250ZXh0LmlzSWREZWNsYXJlZChjb250ZW50KSkKLSAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbigiY3ZjLWlkLjIiLCBuZXcgT2JqZWN0W117Y29udGVudH0pOwotICAgICAgICBjb250ZXh0LmFkZElkKGNvbnRlbnQpOwotICAgIH0KLX0gLy8gY2xhc3MgSUREVgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi94cy9JRFJFRkRWLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L3hzL0lEUkVGRFYuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZmYwZmRmZC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L3hzL0lEUkVGRFYuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDUzICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEsIDIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LnhzOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LkludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5WYWxpZGF0aW9uQ29udGV4dDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuWE1MQ2hhcjsKLQotLyoqCi0gKiBSZXByZXNlbnQgdGhlIHNjaGVtYSB0eXBlICJJRFJFRiIKLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBOZWVyYWogQmFqYWosIFN1biBNaWNyb3N5c3RlbXMsIGluYy4KLSAqIEBhdXRob3IgU2FuZHkgR2FvLCBJQk0KLSAqCi0gKi8KLXB1YmxpYyBjbGFzcyBJRFJFRkRWIGV4dGVuZHMgVHlwZVZhbGlkYXRvcnsKLQotICAgIHB1YmxpYyBzaG9ydCBnZXRBbGxvd2VkRmFjZXRzKCl7Ci0gICAgICAgIHJldHVybiAoWFNTaW1wbGVUeXBlRGVjbC5GQUNFVF9MRU5HVEggfCBYU1NpbXBsZVR5cGVEZWNsLkZBQ0VUX01JTkxFTkdUSCB8IFhTU2ltcGxlVHlwZURlY2wuRkFDRVRfTUFYTEVOR1RIIHwgWFNTaW1wbGVUeXBlRGVjbC5GQUNFVF9QQVRURVJOIHwgWFNTaW1wbGVUeXBlRGVjbC5GQUNFVF9FTlVNRVJBVElPTiB8IFhTU2ltcGxlVHlwZURlY2wuRkFDRVRfV0hJVEVTUEFDRSApOwotICAgIH0KLQotICAgIHB1YmxpYyBPYmplY3QgZ2V0QWN0dWFsVmFsdWUoU3RyaW5nIGNvbnRlbnQsIFZhbGlkYXRpb25Db250ZXh0IGNvbnRleHQpIHRocm93cyBJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmICghWE1MQ2hhci5pc1ZhbGlkTkNOYW1lKGNvbnRlbnQpKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24oImN2Yy1kYXRhdHlwZS12YWxpZC4xLjIuMSIsIG5ldyBPYmplY3RbXXtjb250ZW50LCAiTkNOYW1lIn0pOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBjb250ZW50OwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGNoZWNrRXh0cmFSdWxlcyhPYmplY3QgdmFsdWUsIFZhbGlkYXRpb25Db250ZXh0IGNvbnRleHQpIHRocm93cyBJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbiB7Ci0gICAgICAgIGNvbnRleHQuYWRkSWRSZWYoKFN0cmluZyl2YWx1ZSk7Ci0gICAgfQotCi19Ly9JRFJFRiBjbGFzcwpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi94cy9JbnRlZ2VyRFYuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYveHMvSW50ZWdlckRWLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGExYTBjNGIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi94cy9JbnRlZ2VyRFYuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQ0ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LnhzOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LkludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5WYWxpZGF0aW9uQ29udGV4dDsKLQotLyoqCi0gKiBSZXByZXNlbnQgdGhlIHNjaGVtYSB0eXBlICJpbnRlZ2VyIgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIFNhbmR5IEdhbywgSUJNCi0gKgotICovCi1wdWJsaWMgY2xhc3MgSW50ZWdlckRWIGV4dGVuZHMgRGVjaW1hbERWIHsKLQotICAgIHB1YmxpYyBPYmplY3QgZ2V0QWN0dWFsVmFsdWUoU3RyaW5nIGNvbnRlbnQsIFZhbGlkYXRpb25Db250ZXh0IGNvbnRleHQpIHRocm93cyBJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbiB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICByZXR1cm4gbmV3IFhEZWNpbWFsKGNvbnRlbnQsIHRydWUpOwotICAgICAgICB9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gbmZlKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24oImN2Yy1kYXRhdHlwZS12YWxpZC4xLjIuMSIsIG5ldyBPYmplY3RbXXtjb250ZW50LCAiaW50ZWdlciJ9KTsKLSAgICAgICAgfQotICAgIH0KLQotfSAvLyBjbGFzcyBFbnRpdHlEVgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi94cy9MaXN0RFYuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYveHMvTGlzdERWLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGNhMDc0MzIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi94cy9MaXN0RFYuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEzNyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLDIwMDIsMjAwNCwyMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYueHM7Ci0KLWltcG9ydCBqYXZhLnV0aWwuQWJzdHJhY3RMaXN0OwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LkludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5WYWxpZGF0aW9uQ29udGV4dDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLmRhdGF0eXBlcy5PYmplY3RMaXN0OwotCi0vKioKLSAqIFJlcHJlc2VudCB0aGUgc2NoZW1hIGxpc3QgdHlwZXMKLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBOZWVyYWogQmFqYWosIFN1biBNaWNyb3N5c3RlbXMsIGluYy4KLSAqIEBhdXRob3IgU2FuZHkgR2FvLCBJQk0KLSAqCi0gKiBAdmVyc2lvbiAkSWQ6IExpc3REVi5qYXZhLHYgMS43IDIwMTAtMTEtMDEgMDQ6Mzk6NDcgam9laHcgRXhwICQKLSAqLwotcHVibGljIGNsYXNzIExpc3REViBleHRlbmRzIFR5cGVWYWxpZGF0b3J7Ci0KLSAgICBwdWJsaWMgc2hvcnQgZ2V0QWxsb3dlZEZhY2V0cygpewotICAgICAgICAgIHJldHVybiAoWFNTaW1wbGVUeXBlRGVjbC5GQUNFVF9MRU5HVEggfCBYU1NpbXBsZVR5cGVEZWNsLkZBQ0VUX01JTkxFTkdUSCB8IFhTU2ltcGxlVHlwZURlY2wuRkFDRVRfTUFYTEVOR1RIIHwgWFNTaW1wbGVUeXBlRGVjbC5GQUNFVF9QQVRURVJOIHwgWFNTaW1wbGVUeXBlRGVjbC5GQUNFVF9FTlVNRVJBVElPTiB8IFhTU2ltcGxlVHlwZURlY2wuRkFDRVRfV0hJVEVTUEFDRSApOwotICAgIH0KLQotICAgIC8vIHRoaXMgbWV0aG9kIHNob3VsZCBuZXZlciBiZSBjYWxsZWQ6IFhTU2ltcGxlVHlwZURlY2wgaXMgcmVzcG9uc2libGUgZm9yCi0gICAgLy8gY2FsbGluZyB0aGUgaXRlbSB0eXBlIGZvciB0aGUgY29udmVydGlvbgotICAgIHB1YmxpYyBPYmplY3QgZ2V0QWN0dWFsVmFsdWUoU3RyaW5nIGNvbnRlbnQsIFZhbGlkYXRpb25Db250ZXh0IGNvbnRleHQpIHRocm93cyBJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbnsKLSAgICAgICAgcmV0dXJuIGNvbnRlbnQ7Ci0gICAgfQotCi0gICAgLy8gbGVuZ3RoIG9mIGEgbGlzdCB0eXBlIGlzIHRoZSBudW1iZXIgb2YgaXRlbXMgaW4gdGhlIGxpc3QKLSAgICBwdWJsaWMgaW50IGdldERhdGFMZW5ndGgoT2JqZWN0IHZhbHVlKSB7Ci0gICAgICAgIHJldHVybiAoKExpc3REYXRhKXZhbHVlKS5nZXRMZW5ndGgoKTsKLSAgICB9Ci0KLSAgICBmaW5hbCBzdGF0aWMgY2xhc3MgTGlzdERhdGEgZXh0ZW5kcyBBYnN0cmFjdExpc3QgaW1wbGVtZW50cyBPYmplY3RMaXN0IHsKLSAgICAgICAgZmluYWwgT2JqZWN0W10gZGF0YTsKLSAgICAgICAgcHJpdmF0ZSBTdHJpbmcgY2Fub25pY2FsOwotICAgICAgICBwdWJsaWMgTGlzdERhdGEoT2JqZWN0W10gZGF0YSkgewotICAgICAgICAgICAgdGhpcy5kYXRhID0gZGF0YTsKLSAgICAgICAgfQotICAgICAgICBwdWJsaWMgc3luY2hyb25pemVkIFN0cmluZyB0b1N0cmluZygpIHsKLSAgICAgICAgICAgIGlmIChjYW5vbmljYWwgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGludCBsZW4gPSBkYXRhLmxlbmd0aDsKLSAgICAgICAgICAgICAgICBTdHJpbmdCdWZmZXIgYnVmID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotICAgICAgICAgICAgICAgIGlmIChsZW4gPiAwKSB7Ci0gICAgICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoZGF0YVswXS50b1N0cmluZygpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDE7IGkgPCBsZW47IGkrKykgewotICAgICAgICAgICAgICAgICAgICBidWYuYXBwZW5kKCcgJyk7Ci0gICAgICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoZGF0YVtpXS50b1N0cmluZygpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgY2Fub25pY2FsID0gYnVmLnRvU3RyaW5nKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gY2Fub25pY2FsOwotICAgICAgICB9Ci0gICAgICAgIHB1YmxpYyBpbnQgZ2V0TGVuZ3RoKCkgewotICAgICAgICAgICAgcmV0dXJuIGRhdGEubGVuZ3RoOwotICAgICAgICB9Ci0gICAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqKSB7Ci0gICAgICAgICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBMaXN0RGF0YSkpCi0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgT2JqZWN0W10gb2RhdGEgPSAoKExpc3REYXRhKW9iaikuZGF0YTsKLQotICAgICAgICAgICAgaW50IGNvdW50ID0gZGF0YS5sZW5ndGg7Ci0gICAgICAgICAgICBpZiAoY291bnQgIT0gb2RhdGEubGVuZ3RoKQotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLQotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDAgOyBpIDwgY291bnQgOyBpKyspIHsKLSAgICAgICAgICAgICAgICBpZiAoIWRhdGFbaV0uZXF1YWxzKG9kYXRhW2ldKSkKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgfS8vZW5kIG9mIGxvb3AKLQotICAgICAgICAgICAgLy9ldmVyeXRoaW5nIHdlbnQgZmluZS4KLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKLSAgICAgICAgICAgIGludCBoYXNoID0gMDsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZGF0YS5sZW5ndGg7ICsraSkgewotICAgICAgICAgICAgICAgIGhhc2ggXj0gZGF0YVtpXS5oYXNoQ29kZSgpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIGhhc2g7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWlucyhPYmplY3QgaXRlbSkgewotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7aSA8IGRhdGEubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgICAgICBpZiAoaXRlbSA9PSBkYXRhW2ldKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyBPYmplY3QgaXRlbShpbnQgaW5kZXgpIHsKLSAgICAgICAgICAgIGlmIChpbmRleCA8IDAgfHwgaW5kZXggPj0gZGF0YS5sZW5ndGgpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiBkYXRhW2luZGV4XTsKLSAgICAgICAgfQotCi0gICAgICAgIC8qCi0gICAgICAgICAqIExpc3QgbWV0aG9kcwotICAgICAgICAgKi8KLQotICAgICAgICBwdWJsaWMgT2JqZWN0IGdldChpbnQgaW5kZXgpIHsKLSAgICAgICAgICAgIGlmIChpbmRleCA+PSAwICYmIGluZGV4IDwgZGF0YS5sZW5ndGgpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZGF0YVtpbmRleF07Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICB0aHJvdyBuZXcgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigiSW5kZXg6ICIgKyBpbmRleCk7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgaW50IHNpemUoKSB7Ci0gICAgICAgICAgICByZXR1cm4gZ2V0TGVuZ3RoKCk7Ci0gICAgICAgIH0KLSAgICB9Ci19IC8vIGNsYXNzIExpc3REVgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi94cy9Nb250aERWLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L3hzL01vbnRoRFYuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZWE1NzczNi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L3hzL01vbnRoRFYuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE2OCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDIsMjAwNCwyMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYueHM7Ci0KLWltcG9ydCBqYXZheC54bWwuZGF0YXR5cGUuRGF0YXR5cGVDb25zdGFudHM7Ci1pbXBvcnQgamF2YXgueG1sLmRhdGF0eXBlLlhNTEdyZWdvcmlhbkNhbGVuZGFyOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LkludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5WYWxpZGF0aW9uQ29udGV4dDsKLQotLyoqCi0gKiBWYWxpZGF0b3IgZm9yICZsdDtnTW9udGgmZ3Q7IGRhdGF0eXBlIChXM0MgU2NoZW1hIERhdGF0eXBlcykKLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBFbGVuYSBMaXRhbmkKLSAqIEBhdXRob3IgR29wYWwgU2hhcm1hLCBTVU4gTWljcm9zeXN0ZW0gSW5jLgotICoKLSAqIEB2ZXJzaW9uICRJZDogTW9udGhEVi5qYXZhLHYgMS44IDIwMTAtMTEtMDEgMDQ6Mzk6NDcgam9laHcgRXhwICQKLSAqLwotCi1wdWJsaWMgY2xhc3MgTW9udGhEViBleHRlbmRzIEFic3RyYWN0RGF0ZVRpbWVEViB7Ci0KLSAgICAvKioKLSAgICAgKiBDb252ZXJ0IGEgc3RyaW5nIHRvIGEgY29tcGlsZWQgZm9ybQotICAgICAqCi0gICAgICogQHBhcmFtICBjb250ZW50IFRoZSBsZXhpY2FsIHJlcHJlc2VudGF0aW9uIG9mIGdNb250aAotICAgICAqIEByZXR1cm4gYSB2YWxpZCBhbmQgbm9ybWFsaXplZCBnTW9udGggb2JqZWN0Ci0gICAgICovCi0gICAgcHVibGljIE9iamVjdCBnZXRBY3R1YWxWYWx1ZShTdHJpbmcgY29udGVudCwgVmFsaWRhdGlvbkNvbnRleHQgY29udGV4dCkgdGhyb3dzIEludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uewotICAgICAgICB0cnl7Ci0gICAgICAgICAgICByZXR1cm4gcGFyc2UoY29udGVudCk7Ci0gICAgICAgIH0gY2F0Y2goRXhjZXB0aW9uIGV4KXsKLSAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbigiY3ZjLWRhdGF0eXBlLXZhbGlkLjEuMi4xIiwgbmV3IE9iamVjdFtde2NvbnRlbnQsICJnTW9udGgifSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBQYXJzZXMsIHZhbGlkYXRlcyBhbmQgY29tcHV0ZXMgbm9ybWFsaXplZCB2ZXJzaW9uIG9mIGdNb250aCBvYmplY3QKLSAgICAgKgotICAgICAqIEBwYXJhbSBzdHIgICAgVGhlIGxleGljYWwgcmVwcmVzZW50YXRpb24gb2YgZ01vbnRoIG9iamVjdCAtLU1NCi0gICAgICogICAgICAgICAgICAgICB3aXRoIHBvc3NpYmxlIHRpbWUgem9uZSBaIG9yICgtKSwoKyloaDptbQotICAgICAqIEByZXR1cm4gbm9ybWFsaXplZCBkYXRlIHJlcHJlc2VudGF0aW9uCi0gICAgICogQGV4Y2VwdGlvbiBTY2hlbWFEYXRlVGltZUV4Y2VwdGlvbiBJbnZhbGlkIGxleGljYWwgcmVwcmVzZW50YXRpb24KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgRGF0ZVRpbWVEYXRhIHBhcnNlKFN0cmluZyBzdHIpIHRocm93cyBTY2hlbWFEYXRlVGltZUV4Y2VwdGlvbnsKLSAgICAgICAgRGF0ZVRpbWVEYXRhIGRhdGUgPSBuZXcgRGF0ZVRpbWVEYXRhKHN0ciwgdGhpcyk7Ci0gICAgICAgIGludCBsZW4gPSBzdHIubGVuZ3RoKCk7Ci0KLSAgICAgICAgLy9zZXQgY29uc3RhbnRzCi0gICAgICAgIGRhdGUueWVhcj1ZRUFSOwotICAgICAgICBkYXRlLmRheT1EQVk7Ci0gICAgICAgIGlmIChzdHIuY2hhckF0KDApIT0nLScgfHwgc3RyLmNoYXJBdCgxKSE9Jy0nKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgU2NoZW1hRGF0ZVRpbWVFeGNlcHRpb24oIkludmFsaWQgZm9ybWF0IGZvciBnTW9udGg6ICIrc3RyKTsKLSAgICAgICAgfQotICAgICAgICBpbnQgc3RvcCA9IDQ7Ci0gICAgICAgIGRhdGUubW9udGg9cGFyc2VJbnQoc3RyLDIsc3RvcCk7Ci0KLSAgICAgICAgLy8gUkVWSVNJVDogYWxsb3cgYm90aCAtLU1NIGFuZCAtLU1NLS0gbm93LgotICAgICAgICAvLyBuZWVkIHRvIHJlbW92ZSB0aGUgZm9sbG93aW5nIDQgbGluZXMgdG8gZGlzYWxsb3cgLS1NTS0tCi0gICAgICAgIC8vIHdoZW4gdGhlIGVycmF0YSBpcyBvZmZpY2FsbHkgaW4gdGhlIHJlYy4KLSAgICAgICAgaWYgKHN0ci5sZW5ndGgoKSA+PSBzdG9wKzIgJiYKLSAgICAgICAgICAgIHN0ci5jaGFyQXQoc3RvcCkgPT0gJy0nICYmIHN0ci5jaGFyQXQoc3RvcCsxKSA9PSAnLScpIHsKLSAgICAgICAgICAgIHN0b3AgKz0gMjsKLSAgICAgICAgfQotICAgICAgICBpZiAoc3RvcCA8IGxlbikgewotICAgICAgICAgICAgaWYgKCFpc05leHRDaGFyVVRDU2lnbihzdHIsIHN0b3AsIGxlbikpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU2NoZW1hRGF0ZVRpbWVFeGNlcHRpb24gKCJFcnJvciBpbiBtb250aCBwYXJzaW5nOiAiK3N0cik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBnZXRUaW1lWm9uZShzdHIsIGRhdGUsIHN0b3AsIGxlbik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgLy92YWxpZGF0ZSBhbmQgbm9ybWFsaXplCi0gICAgICAgIHZhbGlkYXRlRGF0ZVRpbWUoZGF0ZSk7Ci0KLSAgICAgICAgLy9zYXZlIHVubm9ybWFsaXplZCB2YWx1ZXMKLSAgICAgICAgc2F2ZVVubm9ybWFsaXplZChkYXRlKTsKLQotICAgICAgICBpZiAoIGRhdGUudXRjIT0wICYmIGRhdGUudXRjIT0nWicgKSB7Ci0gICAgICAgICAgICBub3JtYWxpemUoZGF0ZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZGF0ZS5wb3NpdGlvbiA9IDE7Ci0gICAgICAgIHJldHVybiBkYXRlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIE92ZXJ3cml0ZSBjb21wYXJlIGFsZ29yaXRobSB0byBvcHRpbWl6ZSBtb250aCBjb21wYXJpc29uCi0gICAgICoKLSAgICAgKiBSRVZJU0lUOiB0aGlzIG9uZSBpcyBsYWNrIG9mIHRoZSB0aGlyZCBwYXJhbWV0ZXI6IGJvb2xlYW4gc3RyaWN0LCBzbyBpdAotICAgICAqICAgICAgICAgIGRvZXNuJ3Qgb3ZlcnJpZGUgdGhlIG1ldGhvZCBpbiB0aGUgYmFzZS4gQnV0IG1heWJlIHRoaXMgbWV0aG9kCi0gICAgICogICAgICAgICAgaXMgbm90IGNvcnJlY3RseSBpbXBsZW1lbnRlZCwgYW5kIEkgZGlkIGVuY291bnRlciBlcnJvcnMgd2hlbgotICAgICAqICAgICAgICAgIHRyeWluZyB0byBhZGQgdGhlIGV4dHJhIHBhcmFtZXRlci4gSSdtIGxlYXZpbmcgaXQgYXMgaXMuIC1TRwotICAgICAqCi0gICAgICogQHBhcmFtIGRhdGUxCi0gICAgICogQHBhcmFtIGRhdGUyCi0gICAgICogQHJldHVybiBsZXNzLCBncmVhdGVyLCBlcXVhbCwgaW5kZXRlcm1pbmF0ZQotICAgICAqLwotICAgIC8qcHJvdGVjdGVkICBzaG9ydCBjb21wYXJlRGF0ZXMoRGF0ZVRpbWVEYXRhIGRhdGUxLCBEYXRlVGltZURhdGEgZGF0ZTIpIHsKLQotICAgICAgICBpZiAoIGRhdGUxLnV0Yz09ZGF0ZTIudXRjICkgewotICAgICAgICAgICAgcmV0dXJuIChzaG9ydCkoKGRhdGUxLm1vbnRoPj1kYXRlMi5tb250aCk/KGRhdGUxLm1vbnRoPmRhdGUyLm1vbnRoKT8xOjA6LTEpOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKCBkYXRlMS51dGM9PSdaJyB8fCBkYXRlMi51dGM9PSdaJyApIHsKLQotICAgICAgICAgICAgaWYgKCBkYXRlMS5tb250aD09ZGF0ZTIubW9udGggKSB7Ci0gICAgICAgICAgICAgICAgLy8tLTA1LS1aIGFuZCAtLTA1LS0KLSAgICAgICAgICAgICAgICByZXR1cm4gSU5ERVRFUk1JTkFURTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmICggKGRhdGUxLm1vbnRoKzEgPT0gZGF0ZTIubW9udGggfHwgZGF0ZTEubW9udGgtMSA9PSBkYXRlMi5tb250aCkgKSB7Ci0gICAgICAgICAgICAgICAgLy8tLTA1LS1aIGFuZCAoLS0wNC0tIG9yIC0tMDUtLSkKLSAgICAgICAgICAgICAgICAvL1JFVklTSVQ6IHNob3VsZCB0aGlzIGNhc2UgYmUgbGVzcyB0aGFuIG9yIGVxdWFsPwotICAgICAgICAgICAgICAgIC8vICAgICAgICAgbWF4RXhjbHVzaXZlIHNob3VsZCBmYWlsIGJ1dCB3aGF0IGFib3V0IG1heEluY2x1c2l2ZQotICAgICAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAgICAgcmV0dXJuIElOREVURVJNSU5BVEU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoIGRhdGUxLm1vbnRoPGRhdGUyLm1vbnRoICkgewotICAgICAgICAgICAgcmV0dXJuIC0xOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIDE7Ci0gICAgICAgIH0KLQotICAgIH0qLwotCi0gICAgLyoqCi0gICAgICogQ29udmVydHMgbW9udGggb2JqZWN0IHJlcHJlc2VudGF0aW9uIHRvIFN0cmluZwotICAgICAqCi0gICAgICogQHBhcmFtIGRhdGUgICBtb250aCBvYmplY3QKLSAgICAgKiBAcmV0dXJuIGxleGljYWwgcmVwcmVzZW50YXRpb24gb2YgbW9udGg6IC0tTU0gd2l0aCBhbiBvcHRpb25hbCB0aW1lIHpvbmUgc2lnbgotICAgICAqLwotICAgIHByb3RlY3RlZCBTdHJpbmcgZGF0ZVRvU3RyaW5nKERhdGVUaW1lRGF0YSBkYXRlKSB7Ci0gICAgICAgIFN0cmluZ0J1ZmZlciBtZXNzYWdlID0gbmV3IFN0cmluZ0J1ZmZlcig1KTsKLSAgICAgICAgbWVzc2FnZS5hcHBlbmQoJy0nKTsKLSAgICAgICAgbWVzc2FnZS5hcHBlbmQoJy0nKTsKLSAgICAgICAgYXBwZW5kKG1lc3NhZ2UsIGRhdGUubW9udGgsIDIpOwotICAgICAgICBhcHBlbmQobWVzc2FnZSwgKGNoYXIpZGF0ZS51dGMsIDApOwotICAgICAgICByZXR1cm4gbWVzc2FnZS50b1N0cmluZygpOwotICAgIH0KLQotICAgIHByb3RlY3RlZCBYTUxHcmVnb3JpYW5DYWxlbmRhciBnZXRYTUxHcmVnb3JpYW5DYWxlbmRhcihEYXRlVGltZURhdGEgZGF0ZSkgewotICAgICAgICByZXR1cm4gZGF0YXR5cGVGYWN0b3J5Lm5ld1hNTEdyZWdvcmlhbkNhbGVuZGFyKERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCwgZGF0ZS51bk5vcm1Nb250aCwKLSAgICAgICAgICAgICAgICBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQsIERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCwgRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVELAotICAgICAgICAgICAgICAgIERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCwgRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVELAotICAgICAgICAgICAgICAgIGRhdGUuaGFzVGltZVpvbmUoKSA/IGRhdGUudGltZXpvbmVIciAqIDYwICsgZGF0ZS50aW1lem9uZU1pbiA6IERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi94cy9Nb250aERheURWLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L3hzL01vbnRoRGF5RFYuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNGI0ZGMxMS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L3hzL01vbnRoRGF5RFYuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEzMSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDIsMjAwNCwyMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYueHM7Ci0KLWltcG9ydCBqYXZheC54bWwuZGF0YXR5cGUuRGF0YXR5cGVDb25zdGFudHM7Ci1pbXBvcnQgamF2YXgueG1sLmRhdGF0eXBlLlhNTEdyZWdvcmlhbkNhbGVuZGFyOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LkludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5WYWxpZGF0aW9uQ29udGV4dDsKLQotLyoqCi0gKiBWYWxpZGF0b3IgZm9yICZsdDtnTW9udGhEYXkmZ3Q7IGRhdGF0eXBlIChXM0MgU2NoZW1hIERhdGF0eXBlcykKLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBFbGVuYSBMaXRhbmkKLSAqIEBhdXRob3IgR29wYWwgU2hhcm1hLCBTVU4gTWljcm9zeXN0ZW0gSW5jLgotICoKLSAqIEB2ZXJzaW9uICRJZDogTW9udGhEYXlEVi5qYXZhLHYgMS43IDIwMTAtMTEtMDEgMDQ6Mzk6NDcgam9laHcgRXhwICQKLSAqLwotCi1wdWJsaWMgY2xhc3MgTW9udGhEYXlEViBleHRlbmRzIEFic3RyYWN0RGF0ZVRpbWVEViB7Ci0KLSAgICAvL3NpemUgd2l0aG91dCB0aW1lIHpvbmU6IC0tTU0tREQKLSAgICBwcml2YXRlIGZpbmFsIHN0YXRpYyBpbnQgTU9OVEhEQVlfU0laRSA9IDc7Ci0KLSAgICAvKioKLSAgICAgKiBDb252ZXJ0IGEgc3RyaW5nIHRvIGEgY29tcGlsZWQgZm9ybQotICAgICAqCi0gICAgICogQHBhcmFtICBjb250ZW50IFRoZSBsZXhpY2FsIHJlcHJlc2VudGF0aW9uIG9mIGdNb250aERheQotICAgICAqIEByZXR1cm4gYSB2YWxpZCBhbmQgbm9ybWFsaXplZCBnTW9udGhEYXkgb2JqZWN0Ci0gICAgICovCi0gICAgcHVibGljIE9iamVjdCBnZXRBY3R1YWxWYWx1ZShTdHJpbmcgY29udGVudCwgVmFsaWRhdGlvbkNvbnRleHQgY29udGV4dCkgdGhyb3dzIEludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uIHsKLSAgICAgICAgdHJ5ewotICAgICAgICAgICAgcmV0dXJuIHBhcnNlKGNvbnRlbnQpOwotICAgICAgICB9IGNhdGNoKEV4Y2VwdGlvbiBleCl7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24oImN2Yy1kYXRhdHlwZS12YWxpZC4xLjIuMSIsIG5ldyBPYmplY3RbXXtjb250ZW50LCAiZ01vbnRoRGF5In0pOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUGFyc2VzLCB2YWxpZGF0ZXMgYW5kIGNvbXB1dGVzIG5vcm1hbGl6ZWQgdmVyc2lvbiBvZiBnTW9udGhEYXkgb2JqZWN0Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gc3RyICAgIFRoZSBsZXhpY2FsIHJlcHJlc2VudGF0aW9uIG9mIGdNb250aERheSBvYmplY3QgLS1NTS1ERAotICAgICAqICAgICAgICAgICAgICAgd2l0aCBwb3NzaWJsZSB0aW1lIHpvbmUgWiBvciAoLSksKCspaGg6bW0KLSAgICAgKiBAcmV0dXJuIG5vcm1hbGl6ZWQgZGF0ZSByZXByZXNlbnRhdGlvbgotICAgICAqIEBleGNlcHRpb24gU2NoZW1hRGF0ZVRpbWVFeGNlcHRpb24gSW52YWxpZCBsZXhpY2FsIHJlcHJlc2VudGF0aW9uCi0gICAgICovCi0gICAgcHJvdGVjdGVkIERhdGVUaW1lRGF0YSBwYXJzZShTdHJpbmcgc3RyKSB0aHJvd3MgU2NoZW1hRGF0ZVRpbWVFeGNlcHRpb257Ci0gICAgICAgIERhdGVUaW1lRGF0YSBkYXRlID0gbmV3IERhdGVUaW1lRGF0YShzdHIsIHRoaXMpOwotICAgICAgICBpbnQgbGVuID0gc3RyLmxlbmd0aCgpOwotCi0gICAgICAgIC8vaW5pdGlhbGl6ZQotICAgICAgICBkYXRlLnllYXI9WUVBUjsKLQotICAgICAgICBpZiAoc3RyLmNoYXJBdCgwKSE9Jy0nIHx8IHN0ci5jaGFyQXQoMSkhPSctJykgewotICAgICAgICAgICAgdGhyb3cgbmV3IFNjaGVtYURhdGVUaW1lRXhjZXB0aW9uKCJJbnZhbGlkIGZvcm1hdCBmb3IgZ01vbnRoRGF5OiAiK3N0cik7Ci0gICAgICAgIH0KLSAgICAgICAgZGF0ZS5tb250aD1wYXJzZUludChzdHIsIDIsIDQpOwotICAgICAgICBpbnQgc3RhcnQ9NDsKLQotICAgICAgICBpZiAoc3RyLmNoYXJBdChzdGFydCsrKSE9Jy0nKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgU2NoZW1hRGF0ZVRpbWVFeGNlcHRpb24oIkludmFsaWQgZm9ybWF0IGZvciBnTW9udGhEYXk6ICIgKyBzdHIpOwotICAgICAgICB9Ci0KLSAgICAgICAgZGF0ZS5kYXk9cGFyc2VJbnQoc3RyLCBzdGFydCwgc3RhcnQrMik7Ci0KLSAgICAgICAgaWYgKCBNT05USERBWV9TSVpFPGxlbiApIHsKLSAgICAgICAgICAgIGlmICghaXNOZXh0Q2hhclVUQ1NpZ24oc3RyLCBNT05USERBWV9TSVpFLCBsZW4pKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFNjaGVtYURhdGVUaW1lRXhjZXB0aW9uICgiRXJyb3IgaW4gbW9udGggcGFyc2luZzoiICtzdHIpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgZ2V0VGltZVpvbmUoc3RyLCBkYXRlLCBNT05USERBWV9TSVpFLCBsZW4pOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIC8vdmFsaWRhdGUgYW5kIG5vcm1hbGl6ZQotCi0gICAgICAgIHZhbGlkYXRlRGF0ZVRpbWUoZGF0ZSk7Ci0KLSAgICAgICAgLy9zYXZlIHVubm9ybWFsaXplZCB2YWx1ZXMKLSAgICAgICAgc2F2ZVVubm9ybWFsaXplZChkYXRlKTsKLQotICAgICAgICBpZiAoIGRhdGUudXRjIT0wICYmIGRhdGUudXRjIT0nWicgKSB7Ci0gICAgICAgICAgICBub3JtYWxpemUoZGF0ZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZGF0ZS5wb3NpdGlvbiA9IDE7Ci0gICAgICAgIHJldHVybiBkYXRlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbnZlcnRzIGdNb250aERheSBvYmplY3QgcmVwcmVzZW50YXRpb24gdG8gU3RyaW5nCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZGF0ZSAgIGdtb250aERheSBvYmplY3QKLSAgICAgKiBAcmV0dXJuIGxleGljYWwgcmVwcmVzZW50YXRpb24gb2YgbW9udGg6IC0tTU0tREQgd2l0aCBhbiBvcHRpb25hbCB0aW1lIHpvbmUgc2lnbgotICAgICAqLwotICAgIHByb3RlY3RlZCBTdHJpbmcgZGF0ZVRvU3RyaW5nKERhdGVUaW1lRGF0YSBkYXRlKSB7Ci0gICAgICAgIFN0cmluZ0J1ZmZlciBtZXNzYWdlID0gbmV3IFN0cmluZ0J1ZmZlcig4KTsKLSAgICAgICAgbWVzc2FnZS5hcHBlbmQoJy0nKTsKLSAgICAgICAgbWVzc2FnZS5hcHBlbmQoJy0nKTsKLSAgICAgICAgYXBwZW5kKG1lc3NhZ2UsIGRhdGUubW9udGgsIDIpOwotICAgICAgICBtZXNzYWdlLmFwcGVuZCgnLScpOwotICAgICAgICBhcHBlbmQobWVzc2FnZSwgZGF0ZS5kYXksIDIpOwotICAgICAgICBhcHBlbmQobWVzc2FnZSwgKGNoYXIpZGF0ZS51dGMsIDApOwotICAgICAgICByZXR1cm4gbWVzc2FnZS50b1N0cmluZygpOwotICAgIH0KLQotICAgIHByb3RlY3RlZCBYTUxHcmVnb3JpYW5DYWxlbmRhciBnZXRYTUxHcmVnb3JpYW5DYWxlbmRhcihEYXRlVGltZURhdGEgZGF0ZSkgewotICAgICAgICByZXR1cm4gZGF0YXR5cGVGYWN0b3J5Lm5ld1hNTEdyZWdvcmlhbkNhbGVuZGFyKERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCwgZGF0ZS51bk5vcm1Nb250aCwgZGF0ZS51bk5vcm1EYXksCi0gICAgICAgICAgICAgICAgRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVELCBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQsCi0gICAgICAgICAgICAgICAgRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVELCBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQsCi0gICAgICAgICAgICAgICAgZGF0ZS5oYXNUaW1lWm9uZSgpID8gZGF0ZS50aW1lem9uZUhyICogNjAgKyBkYXRlLnRpbWV6b25lTWluIDogRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVEKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L3hzL1ByZWNpc2lvbkRlY2ltYWxEVi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi94cy9QcmVjaXNpb25EZWNpbWFsRFYuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYTc1ZjAzYS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L3hzL1ByZWNpc2lvbkRlY2ltYWxEVi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDQ2ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYueHM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYuSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LlZhbGlkYXRpb25Db250ZXh0OwotCi0vKioKLSAqIFZhbGlkYXRvciBmb3IgPHByZWNpc2lvbkRlY2ltYWw+IGRhdGF0eXBlIChXM0MgU2NoZW1hIDEuMSkKLSAqCi0gKiBAeGVyY2VzLmV4cGVyaW1lbnRhbAotICoKLSAqIEBhdXRob3IgQW5raXQgUGFzcmljaGEsIElCTQotICoKLSAqLwotY2xhc3MgUHJlY2lzaW9uRGVjaW1hbERWIGV4dGVuZHMgVHlwZVZhbGlkYXRvciB7Ci0KLSAgICBzdGF0aWMgZmluYWwgY2xhc3MgWFByZWNpc2lvbkRlY2ltYWwgewotCi0gICAgICAgIC8vIHNpZ246IDAgZm9yIGFic2VudDsgMSBmb3IgcG9zaXRpdmUgdmFsdWVzOyAtMSBmb3IgbmVnYXRpdmUgdmFsdWVzIChleGNlcHQgaW4gY2FzZSBvZiBJTkYsIC1JTkYpCi0gICAgICAgIGludCBzaWduID0gMTsKLSAgICAgICAgLy8gdG90YWwgZGlnaXRzLiA+PSAxCi0gICAgICAgIGludCB0b3RhbERpZ2l0cyA9IDA7Ci0gICAgICAgIC8vIGludGVnZXIgZGlnaXRzIHdoZW4gc2lnbiAhPSAwCi0gICAgICAgIGludCBpbnREaWdpdHMgPSAwOwotICAgICAgICAvLyBmcmFjdGlvbiBkaWdpdHMgd2hlbiBzaWduICE9IDAKLSAgICAgICAgaW50IGZyYWNEaWdpdHMgPSAwOwotICAgICAgICAvL3ByZWNpc2lvbgotICAgICAgICAvL2ludCBwcmVjaXNpb24gPSAwOwotICAgICAgICAvLyB0aGUgc3RyaW5nIHJlcHJlc2VudGluZyB0aGUgaW50ZWdlciBwYXJ0Ci0gICAgICAgIFN0cmluZyBpdmFsdWUgPSAiIjsKLSAgICAgICAgLy8gdGhlIHN0cmluZyByZXByZXNlbnRpbmcgdGhlIGZyYWN0aW9uIHBhcnQKLSAgICAgICAgU3RyaW5nIGZ2YWx1ZSA9ICIiOwotCi0gICAgICAgIGludCBwdmFsdWUgPSAwOwotCi0KLSAgICAgICAgWFByZWNpc2lvbkRlY2ltYWwoU3RyaW5nIGNvbnRlbnQpIHRocm93cyBOdW1iZXJGb3JtYXRFeGNlcHRpb24gewotICAgICAgICAgICAgaWYoY29udGVudC5lcXVhbHMoIk5hTiIpKSB7Ci0gICAgICAgICAgICAgICAgaXZhbHVlID0gY29udGVudDsKLSAgICAgICAgICAgICAgICBzaWduID0gMDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmKGNvbnRlbnQuZXF1YWxzKCIrSU5GIikgfHwgY29udGVudC5lcXVhbHMoIklORiIpIHx8IGNvbnRlbnQuZXF1YWxzKCItSU5GIikpIHsKLSAgICAgICAgICAgICAgICBpdmFsdWUgPSBjb250ZW50LmNoYXJBdCgwKSA9PSAnKycgPyBjb250ZW50LnN1YnN0cmluZygxKSA6IGNvbnRlbnQ7Ci0gICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaW5pdEQoY29udGVudCk7Ci0gICAgICAgIH0KLQotICAgICAgICB2b2lkIGluaXREKFN0cmluZyBjb250ZW50KSB0aHJvd3MgTnVtYmVyRm9ybWF0RXhjZXB0aW9uIHsKLSAgICAgICAgICAgIGludCBsZW4gPSBjb250ZW50Lmxlbmd0aCgpOwotICAgICAgICAgICAgaWYgKGxlbiA9PSAwKQotICAgICAgICAgICAgICAgIHRocm93IG5ldyBOdW1iZXJGb3JtYXRFeGNlcHRpb24oKTsKLQotICAgICAgICAgICAgLy8gdGhlc2UgNCB2YXJpYWJsZXMgYXJlIHVzZWQgdG8gaW5kaWNhdGUgd2hlcmUgdGhlIGludGVncmUvZnJhY3Rpb24KLSAgICAgICAgICAgIC8vIHBhcnRzIHN0YXJ0L2VuZC4KLSAgICAgICAgICAgIGludCBpbnRTdGFydCA9IDAsIGludEVuZCA9IDAsIGZyYWNTdGFydCA9IDAsIGZyYWNFbmQgPSAwOwotCi0gICAgICAgICAgICAvLyBEZWFsIHdpdGggbGVhZGluZyBzaWduIHN5bWJvbCBpZiBwcmVzZW50Ci0gICAgICAgICAgICBpZiAoY29udGVudC5jaGFyQXQoMCkgPT0gJysnKSB7Ci0gICAgICAgICAgICAgICAgLy8gc2tpcCAnKycsIHNvIGludFN0YXJ0IHNob3VsZCBiZSAxCi0gICAgICAgICAgICAgICAgaW50U3RhcnQgPSAxOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoY29udGVudC5jaGFyQXQoMCkgPT0gJy0nKSB7Ci0gICAgICAgICAgICAgICAgaW50U3RhcnQgPSAxOwotICAgICAgICAgICAgICAgIHNpZ24gPSAtMTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gc2tpcCBsZWFkaW5nIHplcm9lcyBpbiBpbnRlZ2VyIHBhcnQKLSAgICAgICAgICAgIGludCBhY3R1YWxJbnRTdGFydCA9IGludFN0YXJ0OwotICAgICAgICAgICAgd2hpbGUgKGFjdHVhbEludFN0YXJ0IDwgbGVuICYmIGNvbnRlbnQuY2hhckF0KGFjdHVhbEludFN0YXJ0KSA9PSAnMCcpIHsKLSAgICAgICAgICAgICAgICBhY3R1YWxJbnRTdGFydCsrOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBGaW5kIHRoZSBlbmRpbmcgcG9zaXRpb24gb2YgdGhlIGludGVnZXIgcGFydAotICAgICAgICAgICAgZm9yIChpbnRFbmQgPSBhY3R1YWxJbnRTdGFydDsgaW50RW5kIDwgbGVuICYmIFR5cGVWYWxpZGF0b3IuaXNEaWdpdChjb250ZW50LmNoYXJBdChpbnRFbmQpKTsgaW50RW5kKyspOwotCi0gICAgICAgICAgICAvLyBOb3QgcmVhY2hlZCB0aGUgZW5kIHlldAotICAgICAgICAgICAgaWYgKGludEVuZCA8IGxlbikgewotICAgICAgICAgICAgICAgIC8vIHRoZSByZW1haW5pbmcgcGFydCBpcyBub3QgIi5EREQiIG9yICJFREREIiBvciAiZURERCIsIGVycm9yCi0gICAgICAgICAgICAgICAgaWYgKGNvbnRlbnQuY2hhckF0KGludEVuZCkgIT0gJy4nICYmIGNvbnRlbnQuY2hhckF0KGludEVuZCkgIT0gJ0UnICYmIGNvbnRlbnQuY2hhckF0KGludEVuZCkgIT0gJ2UnKQotICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVtYmVyRm9ybWF0RXhjZXB0aW9uKCk7Ci0KLSAgICAgICAgICAgICAgICBpZihjb250ZW50LmNoYXJBdChpbnRFbmQpID09ICcuJykgewotICAgICAgICAgICAgICAgICAgICAvLyBmcmFjdGlvbiBwYXJ0IHN0YXJ0cyBhZnRlciAnLicsIGFuZCBlbmRzIGF0IHRoZSBlbmQgb2YgdGhlIGlucHV0Ci0gICAgICAgICAgICAgICAgICAgIGZyYWNTdGFydCA9IGludEVuZCArIDE7Ci0KLSAgICAgICAgICAgICAgICAgICAgLy8gZmluZCBsb2NhdGlvbiBvZiBFIG9yIGUgKGlmIHByZXNlbnQpCi0gICAgICAgICAgICAgICAgICAgIC8vIEZpbmQgdGhlIGVuZGluZyBwb3NpdGlvbiBvZiB0aGUgZnJhY2lvbiBwYXJ0Ci0gICAgICAgICAgICAgICAgICAgIGZvciAoZnJhY0VuZCA9IGZyYWNTdGFydDsKLSAgICAgICAgICAgICAgICAgICAgZnJhY0VuZCA8IGxlbiAmJiBUeXBlVmFsaWRhdG9yLmlzRGlnaXQoY29udGVudC5jaGFyQXQoZnJhY0VuZCkpOwotICAgICAgICAgICAgICAgICAgICBmcmFjRW5kKyspOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgcHZhbHVlID0gSW50ZWdlci5wYXJzZUludChjb250ZW50LnN1YnN0cmluZyhpbnRFbmQgKyAxLCBsZW4pKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIG5vIGludGVnZXIgcGFydCwgbm8gZnJhY3Rpb24gcGFydCwgZXJyb3IuCi0gICAgICAgICAgICBpZiAoaW50U3RhcnQgPT0gaW50RW5kICYmIGZyYWNTdGFydCA9PSBmcmFjRW5kKQotICAgICAgICAgICAgICAgIHRocm93IG5ldyBOdW1iZXJGb3JtYXRFeGNlcHRpb24oKTsKLQotICAgICAgICAgICAgLy8gaWdub3JlIHRyYWlsaW5nIHplcm9lcyBpbiBmcmFjdGlvbiBwYXJ0Ci0gICAgICAgICAgICAvKndoaWxlIChmcmFjRW5kID4gZnJhY1N0YXJ0ICYmIGNvbnRlbnQuY2hhckF0KGZyYWNFbmQtMSkgPT0gJzAnKSB7Ci0gICAgICAgICAgICAgZnJhY0VuZC0tOwotICAgICAgICAgICAgIH0qLwotCi0gICAgICAgICAgICAvLyBjaGVjayB3aGV0aGVyIHRoZXJlIGlzIG5vbi1kaWdpdCBjaGFyYWN0ZXJzIGluIHRoZSBmcmFjdGlvbiBwYXJ0Ci0gICAgICAgICAgICBmb3IgKGludCBmcmFjUG9zID0gZnJhY1N0YXJ0OyBmcmFjUG9zIDwgZnJhY0VuZDsgZnJhY1BvcysrKSB7Ci0gICAgICAgICAgICAgICAgaWYgKCFUeXBlVmFsaWRhdG9yLmlzRGlnaXQoY29udGVudC5jaGFyQXQoZnJhY1BvcykpKQotICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVtYmVyRm9ybWF0RXhjZXB0aW9uKCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGludERpZ2l0cyA9IGludEVuZCAtIGFjdHVhbEludFN0YXJ0OwotICAgICAgICAgICAgZnJhY0RpZ2l0cyA9IGZyYWNFbmQgLSBmcmFjU3RhcnQ7Ci0KLSAgICAgICAgICAgIGlmIChpbnREaWdpdHMgPiAwKSB7Ci0gICAgICAgICAgICAgICAgaXZhbHVlID0gY29udGVudC5zdWJzdHJpbmcoYWN0dWFsSW50U3RhcnQsIGludEVuZCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmIChmcmFjRGlnaXRzID4gMCkgewotICAgICAgICAgICAgICAgIGZ2YWx1ZSA9IGNvbnRlbnQuc3Vic3RyaW5nKGZyYWNTdGFydCwgZnJhY0VuZCk7Ci0gICAgICAgICAgICAgICAgaWYoZnJhY0VuZCA8IGxlbikgewotICAgICAgICAgICAgICAgICAgICBwdmFsdWUgPSBJbnRlZ2VyLnBhcnNlSW50KGNvbnRlbnQuc3Vic3RyaW5nKGZyYWNFbmQgKyAxLCBsZW4pKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICB0b3RhbERpZ2l0cyA9IGludERpZ2l0cyArIGZyYWNEaWdpdHM7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBDb25zdHJ1Y3QgYSBjYW5vbmljYWwgU3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgbnVtYmVyCi0gICAgICAgIC8vIGZvciB0aGUgcHVycG9zZSBvZiBkZXJpdmluZyBhIGhhc2hDb2RlIHZhbHVlIGNvbXBsaWFudCB3aXRoCi0gICAgICAgIC8vIGVxdWFscy4KLSAgICAgICAgLy8gVGhlIHRvU3RyaW5nIHJlcHJlc2VudGF0aW9uIHdpbGwgYmU6Ci0gICAgICAgIC8vIE5hTiBmb3IgTmFOLCBJTkYgZm9yICtpbmZpbml0eSwgLUlORiBmb3IgLWluZmluaXR5LCAwIGZvciB6ZXJvLAotICAgICAgICAvLyBhbmQgWzEtOV0uWzAtOV0qWzEtOV0/KEVbMS05XVswLTldKik/IGZvciBvdGhlciBudW1iZXJzLgotICAgICAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgY2Fub25pY2FsVG9TdHJpbmdGb3JIYXNoQ29kZShTdHJpbmcgaXZhbHVlLCBTdHJpbmcgZnZhbHVlLCBpbnQgc2lnbiwgaW50IHB2YWx1ZSkgewotICAgICAgICAgICAgaWYgKCJOYU4iLmVxdWFscyhpdmFsdWUpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuICJOYU4iOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKCJJTkYiLmVxdWFscyhpdmFsdWUpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHNpZ24gPCAwID8gIi1JTkYiIDogIklORiI7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmaW5hbCBTdHJpbmdCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgU3RyaW5nQnVpbGRlcigpOwotICAgICAgICAgICAgZmluYWwgaW50IGlsZW4gPSBpdmFsdWUubGVuZ3RoKCk7Ci0gICAgICAgICAgICBmaW5hbCBpbnQgZmxlbjAgPSBmdmFsdWUubGVuZ3RoKCk7Ci0gICAgICAgICAgICBpbnQgbGFzdE5vblplcm87Ci0gICAgICAgICAgICBmb3IgKGxhc3ROb25aZXJvID0gZmxlbjA7IGxhc3ROb25aZXJvID4gMCA7IGxhc3ROb25aZXJvLS0pIHsKLSAgICAgICAgICAgICAgICBpZiAoZnZhbHVlLmNoYXJBdChsYXN0Tm9uWmVybyAtMSApICE9ICcwJykgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmaW5hbCBpbnQgZmxlbiA9IGxhc3ROb25aZXJvOwotICAgICAgICAgICAgaW50IGlTdGFydDsKLSAgICAgICAgICAgIGludCBleHBvbmVudCA9IHB2YWx1ZTsKLSAgICAgICAgICAgIGZvciAoaVN0YXJ0ID0gMDsgaVN0YXJ0IDwgaWxlbjsgaVN0YXJ0KyspIHsKLSAgICAgICAgICAgICAgICBpZiAoaXZhbHVlLmNoYXJBdChpU3RhcnQpICE9ICcwJykgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpbnQgZlN0YXJ0ID0gMDsKLSAgICAgICAgICAgIGlmIChpU3RhcnQgPCBpdmFsdWUubGVuZ3RoKCkpIHsKLSAgICAgICAgICAgICAgICBidWlsZGVyLmFwcGVuZChzaWduID09IC0xID8gIi0iIDogIiIpOwotICAgICAgICAgICAgICAgIGJ1aWxkZXIuYXBwZW5kKGl2YWx1ZS5jaGFyQXQoaVN0YXJ0KSk7Ci0gICAgICAgICAgICAgICAgaVN0YXJ0Kys7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIGlmIChmbGVuID4gMCkgewotICAgICAgICAgICAgICAgICAgICBmb3IgKGZTdGFydCA9IDA7IGZTdGFydCA8IGZsZW47IGZTdGFydCsrKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZnZhbHVlLmNoYXJBdChmU3RhcnQpICE9ICcwJykgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgaWYgKGZTdGFydCA8IGZsZW4pIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJ1aWxkZXIuYXBwZW5kKHNpZ24gPT0gLTEgPyAiLSIgOiAiIik7Ci0gICAgICAgICAgICAgICAgICAgICAgICBidWlsZGVyLmFwcGVuZChmdmFsdWUuY2hhckF0KGZTdGFydCkpOwotICAgICAgICAgICAgICAgICAgICAgICAgZXhwb25lbnQgLT0gKytmU3RhcnQ7Ci0gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gIjAiOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuICIwIjsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmIChpU3RhcnQgPCBpbGVuIHx8IGZTdGFydCA8IGZsZW4pIHsKLSAgICAgICAgICAgICAgICBidWlsZGVyLmFwcGVuZCgnLicpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgd2hpbGUgKGlTdGFydCA8IGlsZW4pIHsKLSAgICAgICAgICAgICAgICBidWlsZGVyLmFwcGVuZChpdmFsdWUuY2hhckF0KGlTdGFydCsrKSk7Ci0gICAgICAgICAgICAgICAgZXhwb25lbnQrKzsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHdoaWxlIChmU3RhcnQgPCBmbGVuKSB7Ci0gICAgICAgICAgICAgICAgYnVpbGRlci5hcHBlbmQoZnZhbHVlLmNoYXJBdChmU3RhcnQrKykpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKGV4cG9uZW50ICE9IDApIHsKLSAgICAgICAgICAgICAgICBidWlsZGVyLmFwcGVuZCgiRSIpLmFwcGVuZChleHBvbmVudCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gYnVpbGRlci50b1N0cmluZygpOwotICAgICAgICB9Ci0KLSAgICAgICAgQE92ZXJyaWRlCi0gICAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgdmFsKSB7Ci0gICAgICAgICAgICBpZiAodmFsID09IHRoaXMpCi0gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0KLSAgICAgICAgICAgIGlmICghKHZhbCBpbnN0YW5jZW9mIFhQcmVjaXNpb25EZWNpbWFsKSkKLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICBYUHJlY2lzaW9uRGVjaW1hbCBvdmFsID0gKFhQcmVjaXNpb25EZWNpbWFsKXZhbDsKLQotICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29tcGFyZVRvKG92YWwpID09IEVRVUFMOwotICAgICAgICB9Ci0KLSAgICAgICAgQE92ZXJyaWRlCi0gICAgICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7Ci0gICAgICAgICAgICAvLyBUaGVyZSdzIG5vdGhpbmcgZWxzZSB3ZSBjYW4gdXNlIGVhc2lseSwgYmVjYXVzZSBlcXVhbHMgY291bGQKLSAgICAgICAgICAgIC8vIHJldHVybiB0cnVlIGZvciB3aWRlbHkgZGlmZmVyZW50IHJlcHJlc2VudGF0aW9uIG9mIHRoZQotICAgICAgICAgICAgLy8gc2FtZSBudW1iZXIgLSBhbmQgd2UgZG9uJ3QgaGF2ZSBhbnkgY2Fub25pY2FsIHJlcHJlc2VudGF0aW9uLgotICAgICAgICAgICAgLy8gVGhlIHByb2JsZW0gaGVyZSBpcyB0aGF0IHdlIG11c3QgZW5zdXJlIHRoYXQgaWYgdHdvIG51bWJlcnMKLSAgICAgICAgICAgIC8vIGFyZSBlcXVhbHMgdGhlbiB0aGVpciBoYXNoIGNvZGUgbXVzdCBhbHNvIGJlIGVxdWFscy4KLSAgICAgICAgICAgIC8vIGhhc2hDb2RlIGZvciAxLjAxRTEgc2hvdWxkIGJlIHRoZSBzYW1lIGFzIGhhc2hDb2RlIGZvciAwLjEwMUUyCi0gICAgICAgICAgICAvLyBTbyB3ZSBjYWxsIGNhbm5vbmljYWxUb1N0cmluZ0Zvckhhc2hDb2RlIC0gd2hpY2ggaW1wbGVtZW50cyBhbgotICAgICAgICAgICAgLy8gYWxnb3JpdGhtIHRoYXQgaW52ZW50cyBhIG5vcm1hbGl6ZWQgc3RyaW5nIHJlcHJlc2VudGF0aW9uCi0gICAgICAgICAgICAvLyBmb3IgdGhpcyBudW1iZXIsIGFuZCB3ZSByZXR1cm4gYSBoYXNoIGZvciB0aGF0LgotICAgICAgICAgICAgcmV0dXJuIGNhbm9uaWNhbFRvU3RyaW5nRm9ySGFzaENvZGUoaXZhbHVlLCBmdmFsdWUsIHNpZ24sIHB2YWx1ZSkuaGFzaENvZGUoKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBAcmV0dXJuCi0gICAgICAgICAqLwotICAgICAgICBwcml2YXRlIGludCBjb21wYXJlRnJhY3Rpb25hbFBhcnQoWFByZWNpc2lvbkRlY2ltYWwgb3ZhbCkgewotICAgICAgICAgICAgaWYoZnZhbHVlLmVxdWFscyhvdmFsLmZ2YWx1ZSkpCi0gICAgICAgICAgICAgICAgcmV0dXJuIEVRVUFMOwotCi0gICAgICAgICAgICBTdHJpbmdCdWZmZXIgdGVtcDEgPSBuZXcgU3RyaW5nQnVmZmVyKGZ2YWx1ZSk7Ci0gICAgICAgICAgICBTdHJpbmdCdWZmZXIgdGVtcDIgPSBuZXcgU3RyaW5nQnVmZmVyKG92YWwuZnZhbHVlKTsKLQotICAgICAgICAgICAgdHJ1bmNhdGVUcmFpbGluZ1plcm9zKHRlbXAxLCB0ZW1wMik7Ci0gICAgICAgICAgICByZXR1cm4gdGVtcDEudG9TdHJpbmcoKS5jb21wYXJlVG8odGVtcDIudG9TdHJpbmcoKSk7Ci0gICAgICAgIH0KLQotICAgICAgICBwcml2YXRlIHZvaWQgdHJ1bmNhdGVUcmFpbGluZ1plcm9zKFN0cmluZ0J1ZmZlciBmVmFsdWUsIFN0cmluZ0J1ZmZlciBvdGhlckZWYWx1ZSkgewotICAgICAgICAgICAgZm9yKGludCBpID0gZlZhbHVlLmxlbmd0aCgpIC0gMTtpID49IDA7IGktLSkKLSAgICAgICAgICAgICAgICBpZihmVmFsdWUuY2hhckF0KGkpID09ICcwJykKLSAgICAgICAgICAgICAgICAgICAgZlZhbHVlLmRlbGV0ZUNoYXJBdChpKTsKLSAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgICAgICBmb3IoaW50IGkgPSBvdGhlckZWYWx1ZS5sZW5ndGgoKSAtIDE7aSA+PSAwOyBpLS0pCi0gICAgICAgICAgICAgICAgaWYob3RoZXJGVmFsdWUuY2hhckF0KGkpID09ICcwJykKLSAgICAgICAgICAgICAgICAgICAgb3RoZXJGVmFsdWUuZGVsZXRlQ2hhckF0KGkpOwotICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgaW50IGNvbXBhcmVUbyhYUHJlY2lzaW9uRGVjaW1hbCB2YWwpIHsKLQotICAgICAgICAgICAgLy8gc2VlbiBOYU4KLSAgICAgICAgICAgIGlmKHNpZ24gPT0gMCkKLSAgICAgICAgICAgICAgICByZXR1cm4gSU5ERVRFUk1JTkFURTsKLQotICAgICAgICAgICAgLy9JTkYgaXMgZ3JlYXRlciB0aGFuIGV2ZXJ5dGhpbmcgYW5kIGVxdWFsIHRvIGl0c2VsZgotICAgICAgICAgICAgaWYoaXZhbHVlLmVxdWFscygiSU5GIikgfHwgdmFsLml2YWx1ZS5lcXVhbHMoIklORiIpKSB7Ci0gICAgICAgICAgICAgICAgaWYoaXZhbHVlLmVxdWFscyh2YWwuaXZhbHVlKSkKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEVRVUFMOwotICAgICAgICAgICAgICAgIGVsc2UgaWYoaXZhbHVlLmVxdWFscygiSU5GIikpCi0gICAgICAgICAgICAgICAgICAgIHJldHVybiBHUkVBVEVSX1RIQU47Ci0gICAgICAgICAgICAgICAgcmV0dXJuIExFU1NfVEhBTjsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8tSU5GIGlzIHNtYWxsZXIgdGhhbiBldmVyeXRoaW5nIGFuZCBlcXVhbCBpdHNlbGYKLSAgICAgICAgICAgIGlmKGl2YWx1ZS5lcXVhbHMoIi1JTkYiKSB8fCB2YWwuaXZhbHVlLmVxdWFscygiLUlORiIpKSB7Ci0gICAgICAgICAgICAgICAgaWYoaXZhbHVlLmVxdWFscyh2YWwuaXZhbHVlKSkKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEVRVUFMOwotICAgICAgICAgICAgICAgIGVsc2UgaWYoaXZhbHVlLmVxdWFscygiLUlORiIpKQotICAgICAgICAgICAgICAgICAgICByZXR1cm4gTEVTU19USEFOOwotICAgICAgICAgICAgICAgIHJldHVybiBHUkVBVEVSX1RIQU47Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmIChzaWduICE9IHZhbC5zaWduKQotICAgICAgICAgICAgICAgIHJldHVybiBzaWduID4gdmFsLnNpZ24gPyBHUkVBVEVSX1RIQU4gOiBMRVNTX1RIQU47Ci0KLSAgICAgICAgICAgIHJldHVybiBzaWduICogY29tcGFyZSh2YWwpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gVG8gZW5hYmxlIGNvbXBhcmlzb24gLSB0aGUgZXhwb25lbnQgcGFydCBvZiB0aGUgZGVjaW1hbCB3aWxsIGJlIGxpbWl0ZWQKLSAgICAgICAgLy8gdG8gdGhlIG1heCB2YWx1ZSBvZiBpbnQuCi0gICAgICAgIHByaXZhdGUgaW50IGNvbXBhcmUoWFByZWNpc2lvbkRlY2ltYWwgdmFsKSB7Ci0KLSAgICAgICAgICAgIGlmKHB2YWx1ZSAhPSAwIHx8IHZhbC5wdmFsdWUgIT0gMCkgewotICAgICAgICAgICAgICAgIGlmKHB2YWx1ZSA9PSB2YWwucHZhbHVlKQotICAgICAgICAgICAgICAgICAgICByZXR1cm4gaW50Q29tcCh2YWwpOwotICAgICAgICAgICAgICAgIGVsc2UgewotCi0gICAgICAgICAgICAgICAgICAgIGlmKGludERpZ2l0cyArIHB2YWx1ZSAhPSB2YWwuaW50RGlnaXRzICsgdmFsLnB2YWx1ZSkKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpbnREaWdpdHMgKyBwdmFsdWUgPiB2YWwuaW50RGlnaXRzICsgdmFsLnB2YWx1ZSA/IEdSRUFURVJfVEhBTiA6IExFU1NfVEhBTjsKLQotICAgICAgICAgICAgICAgICAgICAvL290aGVyd2lzZSB0aGUgMiBjb21iaW5lZCB2YWx1ZXMgYXJlIHRoZSBzYW1lCi0gICAgICAgICAgICAgICAgICAgIGlmKHB2YWx1ZSA+IHZhbC5wdmFsdWUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGludCBleHBEaWZmID0gcHZhbHVlIC0gdmFsLnB2YWx1ZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ0J1ZmZlciBidWZmZXIgPSBuZXcgU3RyaW5nQnVmZmVyKGl2YWx1ZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmdCdWZmZXIgZmJ1ZmZlciA9IG5ldyBTdHJpbmdCdWZmZXIoZnZhbHVlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZvcihpbnQgaSA9IDA7aSA8IGV4cERpZmY7IGkrKykgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKGkgPCBmcmFjRGlnaXRzKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoZnZhbHVlLmNoYXJBdChpKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZidWZmZXIuZGVsZXRlQ2hhckF0KGkpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoJzAnKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjb21wYXJlRGVjaW1hbChidWZmZXIudG9TdHJpbmcoKSwgdmFsLml2YWx1ZSwgZmJ1ZmZlci50b1N0cmluZygpLCB2YWwuZnZhbHVlKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGludCBleHBEaWZmID0gdmFsLnB2YWx1ZSAtIHB2YWx1ZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ0J1ZmZlciBidWZmZXIgPSBuZXcgU3RyaW5nQnVmZmVyKHZhbC5pdmFsdWUpOwotICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nQnVmZmVyIGZidWZmZXIgPSBuZXcgU3RyaW5nQnVmZmVyKHZhbC5mdmFsdWUpOwotICAgICAgICAgICAgICAgICAgICAgICAgZm9yKGludCBpID0gMDtpIDwgZXhwRGlmZjsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoaSA8IHZhbC5mcmFjRGlnaXRzKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQodmFsLmZ2YWx1ZS5jaGFyQXQoaSkpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYnVmZmVyLmRlbGV0ZUNoYXJBdChpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCcwJyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29tcGFyZURlY2ltYWwoaXZhbHVlLCBidWZmZXIudG9TdHJpbmcoKSwgZnZhbHVlLCBmYnVmZmVyLnRvU3RyaW5nKCkpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGludENvbXAodmFsKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBAcGFyYW0gdmFsCi0gICAgICAgICAqIEByZXR1cm4KLSAgICAgICAgICovCi0gICAgICAgIHByaXZhdGUgaW50IGludENvbXAoWFByZWNpc2lvbkRlY2ltYWwgdmFsKSB7Ci0gICAgICAgICAgICBpZiAoaW50RGlnaXRzICE9IHZhbC5pbnREaWdpdHMpCi0gICAgICAgICAgICAgICAgcmV0dXJuIGludERpZ2l0cyA+IHZhbC5pbnREaWdpdHMgPyBHUkVBVEVSX1RIQU4gOiBMRVNTX1RIQU47Ci0KLSAgICAgICAgICAgIHJldHVybiBjb21wYXJlRGVjaW1hbChpdmFsdWUsIHZhbC5pdmFsdWUsIGZ2YWx1ZSwgdmFsLmZ2YWx1ZSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogQHBhcmFtIHZhbAotICAgICAgICAgKiBAcmV0dXJuCi0gICAgICAgICAqLwotICAgICAgICBwcml2YXRlIGludCBjb21wYXJlRGVjaW1hbChTdHJpbmcgaVZhbHVlLCBTdHJpbmcgZlZhbHVlLCBTdHJpbmcgb3RoZXJJVmFsdWUsIFN0cmluZyBvdGhlckZWYWx1ZSkgewotICAgICAgICAgICAgaW50IHJldCA9IGlWYWx1ZS5jb21wYXJlVG8ob3RoZXJJVmFsdWUpOwotICAgICAgICAgICAgaWYgKHJldCAhPSAwKQotICAgICAgICAgICAgICAgIHJldHVybiByZXQgPiAwID8gR1JFQVRFUl9USEFOIDogTEVTU19USEFOOwotCi0gICAgICAgICAgICBpZihmVmFsdWUuZXF1YWxzKG90aGVyRlZhbHVlKSkKLSAgICAgICAgICAgICAgICByZXR1cm4gRVFVQUw7Ci0KLSAgICAgICAgICAgIFN0cmluZ0J1ZmZlciB0ZW1wMT1uZXcgU3RyaW5nQnVmZmVyKGZWYWx1ZSk7Ci0gICAgICAgICAgICBTdHJpbmdCdWZmZXIgdGVtcDI9bmV3IFN0cmluZ0J1ZmZlcihvdGhlckZWYWx1ZSk7Ci0KLSAgICAgICAgICAgIHRydW5jYXRlVHJhaWxpbmdaZXJvcyh0ZW1wMSwgdGVtcDIpOwotICAgICAgICAgICAgcmV0ID0gdGVtcDEudG9TdHJpbmcoKS5jb21wYXJlVG8odGVtcDIudG9TdHJpbmcoKSk7Ci0gICAgICAgICAgICByZXR1cm4gcmV0ID09IDAgPyBFUVVBTCA6IChyZXQgPiAwID8gR1JFQVRFUl9USEFOIDogTEVTU19USEFOKTsKLSAgICAgICAgfQotCi0gICAgICAgIHByaXZhdGUgU3RyaW5nIGNhbm9uaWNhbDsKLQotICAgICAgICBAT3ZlcnJpZGUKLSAgICAgICAgcHVibGljIHN5bmNocm9uaXplZCBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0gICAgICAgICAgICBpZiAoY2Fub25pY2FsID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBtYWtlQ2Fub25pY2FsKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gY2Fub25pY2FsOwotICAgICAgICB9Ci0KLSAgICAgICAgcHJpdmF0ZSB2b2lkIG1ha2VDYW5vbmljYWwoKSB7Ci0gICAgICAgICAgICAvLyBSRVZJU0lUOiB0byBiZSBkZXRlcm1pbmVkIGJ5IHdvcmtpbmcgZ3JvdXAKLSAgICAgICAgICAgIGNhbm9uaWNhbCA9ICJUQkQgYnkgV29ya2luZyBHcm91cCI7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogQHBhcmFtIGRlY2ltYWwKLSAgICAgICAgICogQHJldHVybgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIGJvb2xlYW4gaXNJZGVudGljYWwoWFByZWNpc2lvbkRlY2ltYWwgZGVjaW1hbCkgewotICAgICAgICAgICAgaWYoaXZhbHVlLmVxdWFscyhkZWNpbWFsLml2YWx1ZSkgJiYgKGl2YWx1ZS5lcXVhbHMoIklORiIpIHx8IGl2YWx1ZS5lcXVhbHMoIi1JTkYiKSB8fCBpdmFsdWUuZXF1YWxzKCJOYU4iKSkpCi0gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0KLSAgICAgICAgICAgIGlmKHNpZ24gPT0gZGVjaW1hbC5zaWduICYmIGludERpZ2l0cyA9PSBkZWNpbWFsLmludERpZ2l0cyAmJiBmcmFjRGlnaXRzID09IGRlY2ltYWwuZnJhY0RpZ2l0cyAmJiBwdmFsdWUgPT0gZGVjaW1hbC5wdmFsdWUKLSAgICAgICAgICAgICAgICAgICAgJiYgaXZhbHVlLmVxdWFscyhkZWNpbWFsLml2YWx1ZSkgJiYgZnZhbHVlLmVxdWFscyhkZWNpbWFsLmZ2YWx1ZSkpCi0gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLQotICAgIH0KLSAgICAvKiAobm9uLUphdmFkb2MpCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYueHMuVHlwZVZhbGlkYXRvciNnZXRBbGxvd2VkRmFjZXRzKCkKLSAgICAgKi8KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgc2hvcnQgZ2V0QWxsb3dlZEZhY2V0cygpIHsKLSAgICAgICAgcmV0dXJuICggWFNTaW1wbGVUeXBlRGVjbC5GQUNFVF9QQVRURVJOIHwgWFNTaW1wbGVUeXBlRGVjbC5GQUNFVF9XSElURVNQQUNFIHwgWFNTaW1wbGVUeXBlRGVjbC5GQUNFVF9FTlVNRVJBVElPTiB8WFNTaW1wbGVUeXBlRGVjbC5GQUNFVF9NQVhJTkNMVVNJVkUgfFhTU2ltcGxlVHlwZURlY2wuRkFDRVRfTUlOSU5DTFVTSVZFIHwgWFNTaW1wbGVUeXBlRGVjbC5GQUNFVF9NQVhFWENMVVNJVkUgIHwgWFNTaW1wbGVUeXBlRGVjbC5GQUNFVF9NSU5FWENMVVNJVkUgfCBYU1NpbXBsZVR5cGVEZWNsLkZBQ0VUX1RPVEFMRElHSVRTIHwgWFNTaW1wbGVUeXBlRGVjbC5GQUNFVF9GUkFDVElPTkRJR0lUUyk7Ci0gICAgfQotCi0gICAgLyogKG5vbi1KYXZhZG9jKQotICAgICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LnhzLlR5cGVWYWxpZGF0b3IjZ2V0QWN0dWFsVmFsdWUoamF2YS5sYW5nLlN0cmluZywgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LlZhbGlkYXRpb25Db250ZXh0KQotICAgICAqLwotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyBPYmplY3QgZ2V0QWN0dWFsVmFsdWUoU3RyaW5nIGNvbnRlbnQsIFZhbGlkYXRpb25Db250ZXh0IGNvbnRleHQpCi0gICAgdGhyb3dzIEludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIHJldHVybiBuZXcgWFByZWNpc2lvbkRlY2ltYWwoY29udGVudCk7Ci0gICAgICAgIH0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBuZmUpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbigiY3ZjLWRhdGF0eXBlLXZhbGlkLjEuMi4xIiwgbmV3IE9iamVjdFtde2NvbnRlbnQsICJwcmVjaXNpb25EZWNpbWFsIn0pOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIGludCBjb21wYXJlKE9iamVjdCB2YWx1ZTEsIE9iamVjdCB2YWx1ZTIpIHsKLSAgICAgICAgcmV0dXJuICgoWFByZWNpc2lvbkRlY2ltYWwpdmFsdWUxKS5jb21wYXJlVG8oKFhQcmVjaXNpb25EZWNpbWFsKXZhbHVlMik7Ci0gICAgfQotCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIGludCBnZXRGcmFjdGlvbkRpZ2l0cyhPYmplY3QgdmFsdWUpIHsKLSAgICAgICAgcmV0dXJuICgoWFByZWNpc2lvbkRlY2ltYWwpdmFsdWUpLmZyYWNEaWdpdHM7Ci0gICAgfQotCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIGludCBnZXRUb3RhbERpZ2l0cyhPYmplY3QgdmFsdWUpIHsKLSAgICAgICAgcmV0dXJuICgoWFByZWNpc2lvbkRlY2ltYWwpdmFsdWUpLnRvdGFsRGlnaXRzOwotICAgIH0KLQotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyBib29sZWFuIGlzSWRlbnRpY2FsKE9iamVjdCB2YWx1ZTEsIE9iamVjdCB2YWx1ZTIpIHsKLSAgICAgICAgaWYoISh2YWx1ZTIgaW5zdGFuY2VvZiBYUHJlY2lzaW9uRGVjaW1hbCkgfHwgISh2YWx1ZTEgaW5zdGFuY2VvZiBYUHJlY2lzaW9uRGVjaW1hbCkpCi0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIHJldHVybiAoKFhQcmVjaXNpb25EZWNpbWFsKXZhbHVlMSkuaXNJZGVudGljYWwoKFhQcmVjaXNpb25EZWNpbWFsKXZhbHVlMik7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi94cy9RTmFtZURWLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L3hzL1FOYW1lRFYuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMzQ3ZTEwNC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L3hzL1FOYW1lRFYuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExMSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi54czsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5JbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYuVmFsaWRhdGlvbkNvbnRleHQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlhNTENoYXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuUU5hbWU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5kYXRhdHlwZXMuWFNRTmFtZTsKLQotLyoqCi0gKiBSZXByZXNlbnQgdGhlIHNjaGVtYSB0eXBlICJRTmFtZSIgYW5kICJOT1RBVElPTiIKLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBOZWVyYWogQmFqYWosIFN1biBNaWNyb3N5c3RlbXMsIGluYy4KLSAqIEBhdXRob3IgU2FuZHkgR2FvLCBJQk0KLSAqCi0gKi8KLXB1YmxpYyBjbGFzcyBRTmFtZURWIGV4dGVuZHMgVHlwZVZhbGlkYXRvciB7Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRU1QVFlfU1RSSU5HID0gIiIuaW50ZXJuKCk7Ci0KLSAgICBwdWJsaWMgc2hvcnQgZ2V0QWxsb3dlZEZhY2V0cygpIHsKLSAgICAgICAgcmV0dXJuIChYU1NpbXBsZVR5cGVEZWNsLkZBQ0VUX0xFTkdUSCB8IFhTU2ltcGxlVHlwZURlY2wuRkFDRVRfTUlOTEVOR1RIIHwgWFNTaW1wbGVUeXBlRGVjbC5GQUNFVF9NQVhMRU5HVEggfCBYU1NpbXBsZVR5cGVEZWNsLkZBQ0VUX1BBVFRFUk4gfCBYU1NpbXBsZVR5cGVEZWNsLkZBQ0VUX0VOVU1FUkFUSU9OIHwgWFNTaW1wbGVUeXBlRGVjbC5GQUNFVF9XSElURVNQQUNFKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgT2JqZWN0IGdldEFjdHVhbFZhbHVlKFN0cmluZyBjb250ZW50LCBWYWxpZGF0aW9uQ29udGV4dCBjb250ZXh0KQotICAgICAgICB0aHJvd3MgSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24gewotCi0gICAgICAgIC8vICJwcmVmaXg6bG9jYWxwYXJ0IiBvciAibG9jYWxwYXJ0IgotICAgICAgICAvLyBnZXQgcHJlZml4IGFuZCBsb2NhbCBwYXJ0IG91dCBvZiBjb250ZW50Ci0gICAgICAgIFN0cmluZyBwcmVmaXgsIGxvY2FscGFydDsKLSAgICAgICAgaW50IGNvbG9ucHRyID0gY29udGVudC5pbmRleE9mKCI6Iik7Ci0gICAgICAgIGlmIChjb2xvbnB0ciA+IDApIHsKLSAgICAgICAgICAgIHByZWZpeCA9IGNvbnRleHQuZ2V0U3ltYm9sKGNvbnRlbnQuc3Vic3RyaW5nKDAsY29sb25wdHIpKTsKLSAgICAgICAgICAgIGxvY2FscGFydCA9IGNvbnRlbnQuc3Vic3RyaW5nKGNvbG9ucHRyKzEpOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgcHJlZml4ID0gRU1QVFlfU1RSSU5HOwotICAgICAgICAgICAgbG9jYWxwYXJ0ID0gY29udGVudDsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIGJvdGggcHJlZml4IChpZiBhbnkpIGEgbmQgbG9jYWxwYXJ0IG11c3QgYmUgdmFsaWQgTkNOYW1lCi0gICAgICAgIGlmIChwcmVmaXgubGVuZ3RoKCkgPiAwICYmICFYTUxDaGFyLmlzVmFsaWROQ05hbWUocHJlZml4KSkKLSAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbigiY3ZjLWRhdGF0eXBlLXZhbGlkLjEuMi4xIiwgbmV3IE9iamVjdFtde2NvbnRlbnQsICJRTmFtZSJ9KTsKLQotICAgICAgICBpZighWE1MQ2hhci5pc1ZhbGlkTkNOYW1lKGxvY2FscGFydCkpCi0gICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24oImN2Yy1kYXRhdHlwZS12YWxpZC4xLjIuMSIsIG5ldyBPYmplY3RbXXtjb250ZW50LCAiUU5hbWUifSk7Ci0KLSAgICAgICAgLy8gcmVzb3ZlIHByZWZpeCB0byBhIHVyaSwgcmVwb3J0IGFuIGVycm9yIGlmIGZhaWxlZAotICAgICAgICBTdHJpbmcgdXJpID0gY29udGV4dC5nZXRVUkkocHJlZml4KTsKLSAgICAgICAgaWYgKHByZWZpeC5sZW5ndGgoKSA+IDAgJiYgdXJpID09IG51bGwpCi0gICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24oIlVuZGVjbGFyZWRQcmVmaXgiLCBuZXcgT2JqZWN0W117Y29udGVudCwgcHJlZml4fSk7Ci0KLSAgICAgICAgcmV0dXJuIG5ldyBYUU5hbWUocHJlZml4LCBjb250ZXh0LmdldFN5bWJvbChsb2NhbHBhcnQpLCBjb250ZXh0LmdldFN5bWJvbChjb250ZW50KSwgdXJpKTsKLQotICAgIH0KLQotICAgIC8vIFJFVklTSVQ6IHFuYW1lIGFuZCBub3RhdGlvbiBzaG91bGRuJ3Qgc3VwcG9ydCBsZW5ndGggZmFjZXRzLgotICAgIC8vICAgICAgICAgIG5vdyB3ZSBqdXN0IHJldHVybiB0aGUgbGVuZ3RoIG9mIHRoZSByYXduYW1lCi0gICAgcHVibGljIGludCBnZXREYXRhTGVuZ3RoKE9iamVjdCB2YWx1ZSkgewotICAgICAgICByZXR1cm4gKChYUU5hbWUpdmFsdWUpLnJhd25hbWUubGVuZ3RoKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogcmVwcmVzZW50IFFOYW1lIGRhdGEKLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBYUU5hbWUgZXh0ZW5kcyBRTmFtZSBpbXBsZW1lbnRzIFhTUU5hbWUgewotICAgICAgICAvKiogQ29uc3RydWN0cyBhIFFOYW1lIHdpdGggdGhlIHNwZWNpZmllZCB2YWx1ZXMuICovCi0gICAgICAgIHB1YmxpYyBYUU5hbWUoU3RyaW5nIHByZWZpeCwgU3RyaW5nIGxvY2FscGFydCwgU3RyaW5nIHJhd25hbWUsIFN0cmluZyB1cmkpIHsKLSAgICAgICAgICAgIHNldFZhbHVlcyhwcmVmaXgsIGxvY2FscGFydCwgcmF3bmFtZSwgdXJpKTsKLSAgICAgICAgfSAvLyA8aW5pdD4oU3RyaW5nLFN0cmluZyxTdHJpbmcsU3RyaW5nKQotCi0gICAgICAgIC8qKiBSZXR1cm5zIHRydWUgaWYgdGhlIHR3byBvYmplY3RzIGFyZSBlcXVhbC4gKi8KLSAgICAgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmplY3QpIHsKLSAgICAgICAgICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiBRTmFtZSkgewotICAgICAgICAgICAgICAgIFFOYW1lIHFuYW1lID0gKFFOYW1lKW9iamVjdDsKLSAgICAgICAgICAgICAgICByZXR1cm4gdXJpID09IHFuYW1lLnVyaSAmJiBsb2NhbHBhcnQgPT0gcW5hbWUubG9jYWxwYXJ0OwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9IC8vIGVxdWFscyhPYmplY3QpOmJvb2xlYW4KLQotICAgICAgICBwdWJsaWMgc3luY2hyb25pemVkIFN0cmluZyB0b1N0cmluZygpIHsKLSAgICAgICAgICAgIHJldHVybiByYXduYW1lOwotICAgICAgICB9Ci0gICAgICAgIHB1YmxpYyBqYXZheC54bWwubmFtZXNwYWNlLlFOYW1lIGdldEpBWFBRTmFtZSgpIHsKLSAgICAgICAgICAgIHJldHVybiBuZXcgamF2YXgueG1sLm5hbWVzcGFjZS5RTmFtZSh1cmksIGxvY2FscGFydCwgcHJlZml4KTsKLSAgICAgICAgfQotICAgICAgICBwdWJsaWMgUU5hbWUgZ2V0WE5JUU5hbWUoKSB7Ci0gICAgICAgICAgICByZXR1cm4gdGhpczsKLSAgICAgICAgfQotICAgIH0KLX0gLy8gY2xhc3MgUU5hbWVEVkRWCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L3hzL1NjaGVtYURWRmFjdG9yeUltcGwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYveHMvU2NoZW1hRFZGYWN0b3J5SW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzZTA1NzBiLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYveHMvU2NoZW1hRFZGYWN0b3J5SW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNzcgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYueHM7Ci0KLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5YU1NpbXBsZVR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlN5bWJvbEhhc2g7Ci0KLS8qKgotICogdGhlIGZhY3RvcnkgdG8gY3JlYXRlL3JldHVybiBidWlsdC1pbiBzY2hlbWEgRFZzIGFuZCBjcmVhdGUgdXNlci1kZWZpbmVkIERWcwotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIE5lZXJhaiBCYWphaiwgU3VuIE1pY3Jvc3lzdGVtcywgaW5jLgotICogQGF1dGhvciBTYW5keSBHYW8sIElCTQotICoKLSAqIEB2ZXJzaW9uICRJZDogU2NoZW1hRFZGYWN0b3J5SW1wbC5qYXZhLHYgMS43IDIwMTAtMTEtMDEgMDQ6Mzk6NDcgam9laHcgRXhwICQKLSAqLwotcHVibGljIGNsYXNzIFNjaGVtYURWRmFjdG9yeUltcGwgZXh0ZW5kcyBCYXNlU2NoZW1hRFZGYWN0b3J5IHsKLQotICAgIHN0YXRpYyBmaW5hbCBTeW1ib2xIYXNoIGZCdWlsdEluVHlwZXMgPSBuZXcgU3ltYm9sSGFzaCgpOwotCi0gICAgc3RhdGljIHsKLSAgICAgICAgY3JlYXRlQnVpbHRJblR5cGVzKCk7Ci0gICAgfQotCi0gICAgLy8gY3JlYXRlIGFsbCBidWlsdC1pbiB0eXBlcwotICAgIHN0YXRpYyB2b2lkIGNyZWF0ZUJ1aWx0SW5UeXBlcygpIHsKLSAgICAgICAgY3JlYXRlQnVpbHRJblR5cGVzKGZCdWlsdEluVHlwZXMsIFhTU2ltcGxlVHlwZURlY2wuZkFueVNpbXBsZVR5cGUpOwotCi0gICAgICAgIC8vIFRPRE86IG1vdmUgc3BlY2lmaWMgMS4wIERWIGltcGxlbWVudGF0aW9uIGZyb20gYmFzZQotICAgIH0gLy9jcmVhdGVCdWlsdEluVHlwZXMoKQotCi0gICAgLyoqCi0gICAgICogR2V0IGEgYnVpbHQtaW4gc2ltcGxlIHR5cGUgb2YgdGhlIGdpdmVuIG5hbWUKLSAgICAgKiBSRVZJU0lUOiBpdHMgc3RpbGwgbm90IGRlY2lkZWQgd2l0aGluIHRoZSBTY2hlbWEgV0cgaG93IHRvIGRlZmluZSB0aGUKLSAgICAgKiAgICAgICAgICB1ci10eXBlcyBhbmQgaWYgYWxsIHNpbXBsZSB0eXBlcyBzaG91bGQgYmUgZGVyaXZlZCBmcm9tIGEKLSAgICAgKiAgICAgICAgICBjb21wbGV4IHR5cGUsIHNvIGFzIG9mIG5vdyB3ZSBpZ25vcmUgdGhlIGZhY3QgdGhhdCBhbnlTaW1wbGVUeXBlCi0gICAgICogICAgICAgICAgaXMgZGVyaXZlZCBmcm9tIGFueVR5cGUsIGFuZCBwYXNzICdudWxsJyBhcyB0aGUgYmFzZSBvZgotICAgICAqICAgICAgICAgIGFueVNpbXBsZVR5cGUuIEl0IG5lZWRzIHRvIGJlIGNoYW5nZWQgYXMgcGVyIHRoZSBkZWNpc2lvbiB0YWtlbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lICB0aGUgbmFtZSBvZiB0aGUgZGF0YXR5cGUKLSAgICAgKiBAcmV0dXJuICAgICAgdGhlIGRhdGF0eXBlIHZhbGlkYXRvciBvZiB0aGUgZ2l2ZW4gbmFtZQotICAgICAqLwotICAgIHB1YmxpYyBYU1NpbXBsZVR5cGUgZ2V0QnVpbHRJblR5cGUoU3RyaW5nIG5hbWUpIHsKLSAgICAgICAgcmV0dXJuIChYU1NpbXBsZVR5cGUpZkJ1aWx0SW5UeXBlcy5nZXQobmFtZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogZ2V0IGFsbCBidWlsdC1pbiBzaW1wbGUgdHlwZXMsIHdoaWNoIGFyZSBzdG9yZWQgaW4gYSBoYXNodGFibGUga2V5ZWQgYnkKLSAgICAgKiB0aGUgbmFtZQotICAgICAqCi0gICAgICogQHJldHVybiAgICAgIGEgaGFzaHRhYmxlIHdoaWNoIGNvbnRhaW5zIGFsbCBidWlsdC1pbiBzaW1wbGUgdHlwZXMKLSAgICAgKi8KLSAgICBwdWJsaWMgU3ltYm9sSGFzaCBnZXRCdWlsdEluVHlwZXMoKSB7Ci0gICAgICAgIHJldHVybiAoU3ltYm9sSGFzaClmQnVpbHRJblR5cGVzLm1ha2VDbG9uZSgpOwotICAgIH0KLQotfS8vU2NoZW1hRFZGYWN0b3J5SW1wbApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi94cy9TY2hlbWFEYXRlVGltZUV4Y2VwdGlvbi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi94cy9TY2hlbWFEYXRlVGltZUV4Y2VwdGlvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA5MTdlYzU5Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYveHMvU2NoZW1hRGF0ZVRpbWVFeGNlcHRpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDM5ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwMiwyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYueHM7Ci0KLS8qKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqLwotcHVibGljIGNsYXNzIFNjaGVtYURhdGVUaW1lRXhjZXB0aW9uIGV4dGVuZHMgUnVudGltZUV4Y2VwdGlvbiB7Ci0KLSAgICAvKiogU2VyaWFsaXphdGlvbiB2ZXJzaW9uLiAqLwotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtODUyMDgzMjIzNTMzNzc2OTA0MEw7Ci0KLSAgICBwdWJsaWMgU2NoZW1hRGF0ZVRpbWVFeGNlcHRpb24gKCkgewotICAgICAgICBzdXBlcigpOwotICAgIH0KLQotICAgIHB1YmxpYyBTY2hlbWFEYXRlVGltZUV4Y2VwdGlvbiAoU3RyaW5nIHMpIHsKLSAgICAgICAgc3VwZXIgKHMpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYveHMvU3RyaW5nRFYuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYveHMvU3RyaW5nRFYuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDEwYmMxYi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L3hzL1N0cmluZ0RWLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0NiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLCAyMDAyLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi54czsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5JbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYuVmFsaWRhdGlvbkNvbnRleHQ7Ci0KLS8qKgotICogUmVwcmVzZW50IHRoZSBzY2hlbWEgdHlwZSAic3RyaW5nIgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIE5lZXJhaiBCYWphaiwgU3VuIE1pY3Jvc3lzdGVtcywgaW5jLgotICogQGF1dGhvciBTYW5keSBHYW8sIElCTQotICoKLSAqLwotcHVibGljIGNsYXNzIFN0cmluZ0RWIGV4dGVuZHMgVHlwZVZhbGlkYXRvciB7Ci0KLSAgICBwdWJsaWMgc2hvcnQgZ2V0QWxsb3dlZEZhY2V0cygpewotICAgICAgICByZXR1cm4gKFhTU2ltcGxlVHlwZURlY2wuRkFDRVRfTEVOR1RIIHwgWFNTaW1wbGVUeXBlRGVjbC5GQUNFVF9NSU5MRU5HVEggfCBYU1NpbXBsZVR5cGVEZWNsLkZBQ0VUX01BWExFTkdUSCB8IFhTU2ltcGxlVHlwZURlY2wuRkFDRVRfUEFUVEVSTiB8IFhTU2ltcGxlVHlwZURlY2wuRkFDRVRfRU5VTUVSQVRJT04gfCBYU1NpbXBsZVR5cGVEZWNsLkZBQ0VUX1dISVRFU1BBQ0UgKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgT2JqZWN0IGdldEFjdHVhbFZhbHVlKFN0cmluZyBjb250ZW50LCBWYWxpZGF0aW9uQ29udGV4dCBjb250ZXh0KQotICAgICAgICB0aHJvd3MgSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24gewotICAgICAgICByZXR1cm4gY29udGVudDsKLSAgICB9Ci0KLX0gLy8gY2xhc3MgU3RyaW5nRFYKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYveHMvVGltZURWLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L3hzL1RpbWVEVi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjOWJiYWUyLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYveHMvVGltZURWLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMTMgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDAyLDIwMDQsMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LnhzOwotCi1pbXBvcnQgamF2YXgueG1sLmRhdGF0eXBlLkRhdGF0eXBlQ29uc3RhbnRzOwotaW1wb3J0IGphdmF4LnhtbC5kYXRhdHlwZS5YTUxHcmVnb3JpYW5DYWxlbmRhcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5JbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYuVmFsaWRhdGlvbkNvbnRleHQ7Ci0KLS8qKgotICogVmFsaWRhdG9yIGZvciAmbHQ7dGltZSZndDsgZGF0YXR5cGUgKFczQyBTY2hlbWEgRGF0YXR5cGVzKQotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIEVsZW5hIExpdGFuaQotICogQGF1dGhvciBHb3BhbCBTaGFybWEsIFNVTiBNaWNyb3N5c3RlbSBJbmMuCi0gKgotICogQHZlcnNpb24gJElkOiBUaW1lRFYuamF2YSx2IDEuNyAyMDEwLTExLTAxIDA0OjM5OjQ3IGpvZWh3IEV4cCAkCi0gKi8KLXB1YmxpYyBjbGFzcyBUaW1lRFYgZXh0ZW5kcyBBYnN0cmFjdERhdGVUaW1lRFYgewotCi0gICAgLyoqCi0gICAgICogQ29udmVydCBhIHN0cmluZyB0byBhIGNvbXBpbGVkIGZvcm0KLSAgICAgKgotICAgICAqIEBwYXJhbSAgY29udGVudCBUaGUgbGV4aWNhbCByZXByZXNlbnRhdGlvbiBvZiB0aW1lCi0gICAgICogQHJldHVybiBhIHZhbGlkIGFuZCBub3JtYWxpemVkIHRpbWUgb2JqZWN0Ci0gICAgICovCi0gICAgcHVibGljIE9iamVjdCBnZXRBY3R1YWxWYWx1ZShTdHJpbmcgY29udGVudCwgVmFsaWRhdGlvbkNvbnRleHQgY29udGV4dCkgdGhyb3dzIEludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uewotICAgICAgICB0cnl7Ci0gICAgICAgICAgICByZXR1cm4gcGFyc2UoY29udGVudCk7Ci0gICAgICAgIH0gY2F0Y2goRXhjZXB0aW9uIGV4KXsKLSAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbigiY3ZjLWRhdGF0eXBlLXZhbGlkLjEuMi4xIiwgbmV3IE9iamVjdFtde2NvbnRlbnQsICJ0aW1lIn0pOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUGFyc2VzLCB2YWxpZGF0ZXMgYW5kIGNvbXB1dGVzIG5vcm1hbGl6ZWQgdmVyc2lvbiBvZiB0aW1lIG9iamVjdAotICAgICAqCi0gICAgICogQHBhcmFtIHN0ciAgICBUaGUgbGV4aWNhbCByZXByZXNlbnRhdGlvbiBvZiB0aW1lIG9iamVjdCBoaDptbTpzcy5zc3MKLSAgICAgKiAgICAgICAgICAgICAgIHdpdGggcG9zc2libGUgdGltZSB6b25lIFogb3IgKC0pLCgrKWhoOm1tCi0gICAgICogICAgICAgICAgICAgICBQYXR0ZXJuOiAiKFxcZFxcZCk6KFxcZFxcZCk6KFxcZFxcZCkoXFwuKFxcZCkqKT8oWnwoKFstK10pKFxcZFxcZCkoOihcXGRcXGQpKT8pKT8iKQotICAgICAqIEByZXR1cm4gbm9ybWFsaXplZCB0aW1lIHJlcHJlc2VudGF0aW9uCi0gICAgICogQGV4Y2VwdGlvbiBTY2hlbWFEYXRlVGltZUV4Y2VwdGlvbiBJbnZhbGlkIGxleGljYWwgcmVwcmVzZW50YXRpb24KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgRGF0ZVRpbWVEYXRhIHBhcnNlKFN0cmluZyBzdHIpIHRocm93cyBTY2hlbWFEYXRlVGltZUV4Y2VwdGlvbnsKLSAgICAgICAgRGF0ZVRpbWVEYXRhIGRhdGUgPSBuZXcgRGF0ZVRpbWVEYXRhKHN0ciwgdGhpcyk7Ci0gICAgICAgIGludCBsZW4gPSBzdHIubGVuZ3RoKCk7Ci0KLSAgICAgICAgLy8gdGltZQotICAgICAgICAvLyBpbml0aWFsaXplIHRvIGRlZmF1bHQgdmFsdWVzCi0gICAgICAgIGRhdGUueWVhcj1ZRUFSOwotICAgICAgICBkYXRlLm1vbnRoPU1PTlRIOwotICAgICAgICBkYXRlLmRheT0xNTsKLSAgICAgICAgZ2V0VGltZShzdHIsIDAsIGxlbiwgZGF0ZSk7Ci0KLSAgICAgICAgLy92YWxpZGF0ZSBhbmQgbm9ybWFsaXplCi0KLSAgICAgICAgdmFsaWRhdGVEYXRlVGltZShkYXRlKTsKLQotICAgICAgICAvL3NhdmUgdW5ub3JtYWxpemVkIHZhbHVlcwotICAgICAgICBzYXZlVW5ub3JtYWxpemVkKGRhdGUpOwotCi0gICAgICAgIGlmICggZGF0ZS51dGMhPTAgJiYgZGF0ZS51dGMgIT0gJ1onKSB7Ci0gICAgICAgICAgICBub3JtYWxpemUoZGF0ZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZGF0ZS5wb3NpdGlvbiA9IDI7Ci0gICAgICAgIHJldHVybiBkYXRlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbnZlcnRzIHRpbWUgb2JqZWN0IHJlcHJlc2VudGF0aW9uIHRvIFN0cmluZwotICAgICAqCi0gICAgICogQHBhcmFtIGRhdGUgICB0aW1lIG9iamVjdAotICAgICAqIEByZXR1cm4gbGV4aWNhbCByZXByZXNlbnRhdGlvbiBvZiB0aW1lOiBoaDptbTpzcy5zc3Mgd2l0aCBhbiBvcHRpb25hbCB0aW1lIHpvbmUgc2lnbgotICAgICAqLwotICAgIHByb3RlY3RlZCBTdHJpbmcgZGF0ZVRvU3RyaW5nKERhdGVUaW1lRGF0YSBkYXRlKSB7Ci0gICAgICAgIFN0cmluZ0J1ZmZlciBtZXNzYWdlID0gbmV3IFN0cmluZ0J1ZmZlcigxNik7Ci0gICAgICAgIGFwcGVuZChtZXNzYWdlLCBkYXRlLmhvdXIsIDIpOwotICAgICAgICBtZXNzYWdlLmFwcGVuZCgnOicpOwotICAgICAgICBhcHBlbmQobWVzc2FnZSwgZGF0ZS5taW51dGUsIDIpOwotICAgICAgICBtZXNzYWdlLmFwcGVuZCgnOicpOwotICAgICAgICBhcHBlbmQobWVzc2FnZSwgZGF0ZS5zZWNvbmQpOwotCi0gICAgICAgIGFwcGVuZChtZXNzYWdlLCAoY2hhcilkYXRlLnV0YywgMCk7Ci0gICAgICAgIHJldHVybiBtZXNzYWdlLnRvU3RyaW5nKCk7Ci0gICAgfQotCi0gICAgcHJvdGVjdGVkIFhNTEdyZWdvcmlhbkNhbGVuZGFyIGdldFhNTEdyZWdvcmlhbkNhbGVuZGFyKERhdGVUaW1lRGF0YSBkYXRlKSB7Ci0gICAgICAgIHJldHVybiBkYXRhdHlwZUZhY3RvcnkubmV3WE1MR3JlZ29yaWFuQ2FsZW5kYXIobnVsbCwgRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVELAotICAgICAgICAgICAgICAgIERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCwgZGF0ZS51bk5vcm1Ib3VyLCBkYXRlLnVuTm9ybU1pbnV0ZSwKLSAgICAgICAgICAgICAgICAoaW50KWRhdGUudW5Ob3JtU2Vjb25kLCBkYXRlLnVuTm9ybVNlY29uZCAhPSAwID8gZ2V0RnJhY3Rpb25hbFNlY29uZHNBc0JpZ0RlY2ltYWwoZGF0ZSkgOiBudWxsLAotICAgICAgICAgICAgICAgIGRhdGUuaGFzVGltZVpvbmUoKSA/IChkYXRlLnRpbWV6b25lSHIgKiA2MCArIGRhdGUudGltZXpvbmVNaW4pIDogRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVEKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L3hzL1R5cGVWYWxpZGF0b3IuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYveHMvVHlwZVZhbGlkYXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA5ODk5MDJkLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYveHMvVHlwZVZhbGlkYXRvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTEwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEsIDIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LnhzOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LkludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5WYWxpZGF0aW9uQ29udGV4dDsKLQotLyoqCi0gKiBBbGwgcHJpbWl0aXZlIHR5cGVzIHBsdXMgSUQvSURSRUYvRU5USVRZL0lOVEVHRVIgYXJlIGRlcml2ZWQgZnJvbSB0aGlzIGFic3RyYWN0Ci0gKiBjbGFzcy4gSXQgcHJvdmlkZXMgZXh0cmEgaW5mb3JtYXRpb24gWFNTaW1wbGVUeXBlRGVjbCByZXF1aXJlcyBmcm9tIGVhY2gKLSAqIHR5cGU6IGFsbG93ZWQgZmFjZXRzLCBjb252ZXJ0aW5nIFN0cmluZyB0byBhY3R1YWwgdmFsdWUsIGNoZWNrIGVxdWFsaXR5LAotICogY29tcGFyaXNvbiwgZXRjLgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIE5lZXJhaiBCYWphaiwgU3VuIE1pY3Jvc3lzdGVtcywgaW5jLgotICogQGF1dGhvciBTYW5keSBHYW8sIElCTQotICoKLSAqLwotcHVibGljIGFic3RyYWN0IGNsYXNzIFR5cGVWYWxpZGF0b3IgewotCi0gICAgLy8gd2hpY2ggZmFjZXRzIGFyZSBhbGxvd2VkIGZvciB0aGlzIHR5cGUKLSAgICBwdWJsaWMgYWJzdHJhY3Qgc2hvcnQgZ2V0QWxsb3dlZEZhY2V0cygpOwotCi0gICAgLy8gY29udmVydCBhIHN0cmluZyB0byBhbiBhY3R1YWwgdmFsdWUuIGZvciBleGFtcGxlLAotICAgIC8vIGZvciBudW1iZXIgdHlwZXMgKGRlY2ltYWwsIGRvdWJsZSwgZmxvYXQsIGFuZCB0eXBlcyBkZXJpdmVkIGZyb20gdGhlbSksCi0gICAgLy8gZ2V0IHRoZSBCaWdEZWNpbWFsLCBEb3VibGUsIEZsb3V0IG9iamVjdC4KLSAgICAvLyBmb3Igc29tZSB0eXBlcyAoc3RyaW5nIGFuZCBkZXJpdmVkKSwgdGhleSBqdXN0IHJldHVybiB0aGUgc3RyaW5nIGl0c2VsZgotICAgIHB1YmxpYyBhYnN0cmFjdCBPYmplY3QgZ2V0QWN0dWFsVmFsdWUoU3RyaW5nIGNvbnRlbnQsIFZhbGlkYXRpb25Db250ZXh0IGNvbnRleHQpCi0gICAgICAgIHRocm93cyBJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbjsKLQotICAgIC8vIGZvciBJRC9JRFJFRi9FTlRJVFkgdHlwZXMsIGRvIHNvbWUgZXh0cmEgY2hlY2tpbmcgYWZ0ZXIgdGhlIHZhbHVlIGlzCi0gICAgLy8gY2hlY2tlZCB0byBiZSB2YWxpZCB3aXRoIHJlc3BlY3QgdG8gYm90aCBsZXhpY2FsIHJlcHJlc2VudGF0aW9uIGFuZAotICAgIC8vIGZhY2V0cwotICAgIHB1YmxpYyB2b2lkIGNoZWNrRXh0cmFSdWxlcyhPYmplY3QgdmFsdWUsIFZhbGlkYXRpb25Db250ZXh0IGNvbnRleHQpIHRocm93cyBJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbiB7Ci0gICAgfQotCi0gICAgLy8gdGhlIGZvbGxvd2luZyBtZXRob2RzIG1pZ2h0IG5vdCBiZSBzdXBwb3J0ZWQgYnkgZXZlcnkgRFYuCi0gICAgLy8gYnV0IFhTU2ltcGxlVHlwZURlY2wgc2hvdWxkIGtub3cgd2hpY2ggdHlwZSBzdXBwb3J0cyB3aGljaCBtZXRob2RzLAotICAgIC8vIGFuZCBpdCdzIGFuICppbnRlcm5hbCogZXJyb3IgaWYgYSBtZXRob2QgaXMgY2FsbGVkIG9uIGEgRFYgdGhhdAotICAgIC8vIGRvZXNuJ3Qgc3VwcG9ydCBpdC4KLQotICAgIC8vb3JkZXIgY29uc3RhbnRzCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBMRVNTX1RIQU4gICAgID0gLTE7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBFUVVBTCAgICAgICAgID0gMDsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IEdSRUFURVJfVEhBTiAgPSAxOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgSU5ERVRFUk1JTkFURSA9IDI7Ci0KLSAgICAvLyB3aGVyZSB0aGVyZSBpcyBkaXN0aW5jdGlvbiBiZXR3ZWVuIGlkZW50aXR5IGFuZCBlcXVhbGl0eSwgdGhpcyBtZXRob2QKLSAgICAvLyB3aWxsIGJlIG92ZXJ3cml0dGVuCi0gICAgLy8gY2hlY2tzIHdoZXRoZXIgdGhlIHR3byB2YWx1ZXMgYXJlIGlkZW50aWNhbDsgZm9yIGV4LCB0aGlzIGRpc3Rpbmd1aXNoZXMKLSAgICAvLyAtMC4wIGZyb20gMC4wCi0gICAgcHVibGljIGJvb2xlYW4gaXNJZGVudGljYWwgKE9iamVjdCB2YWx1ZTEsIE9iamVjdCB2YWx1ZTIpIHsKLSAgICAgICAgcmV0dXJuIHZhbHVlMS5lcXVhbHModmFsdWUyKTsKLSAgICB9Ci0KLSAgICAvLyBjaGVjayB0aGUgb3JkZXIgcmVsYXRpb24gYmV0d2VlbiB0aGUgdHdvIHZhbHVlcwotICAgIC8vIHRoZSBwYXJhbWV0ZXJzIGFyZSBpbiBjb21waWxlZCBmb3JtIChmcm9tIGdldEFjdHVhbFZhbHVlKQotICAgIHB1YmxpYyBpbnQgY29tcGFyZShPYmplY3QgdmFsdWUxLCBPYmplY3QgdmFsdWUyKSB7Ci0gICAgICAgIHJldHVybiAtMTsKLSAgICB9Ci0KLSAgICAvLyBnZXQgdGhlIGxlbmd0aCBvZiB0aGUgdmFsdWUKLSAgICAvLyB0aGUgcGFyYW1ldGVycyBhcmUgaW4gY29tcGlsZWQgZm9ybSAoZnJvbSBnZXRBY3R1YWxWYWx1ZSkKLSAgICBwdWJsaWMgaW50IGdldERhdGFMZW5ndGgoT2JqZWN0IHZhbHVlKSB7Ci0gICAgICAgIHJldHVybiAodmFsdWUgaW5zdGFuY2VvZiBTdHJpbmcpID8gKChTdHJpbmcpdmFsdWUpLmxlbmd0aCgpIDogLTE7Ci0gICAgfQotCi0gICAgLy8gZ2V0IHRoZSBudW1iZXIgb2YgZGlnaXRzIG9mIHRoZSB2YWx1ZQotICAgIC8vIHRoZSBwYXJhbWV0ZXJzIGFyZSBpbiBjb21waWxlZCBmb3JtIChmcm9tIGdldEFjdHVhbFZhbHVlKQotICAgIHB1YmxpYyBpbnQgZ2V0VG90YWxEaWdpdHMoT2JqZWN0IHZhbHVlKSB7Ci0gICAgICAgIHJldHVybiAtMTsKLSAgICB9Ci0KLSAgICAvLyBnZXQgdGhlIG51bWJlciBvZiBmcmFjdGlvbiBkaWdpdHMgb2YgdGhlIHZhbHVlCi0gICAgLy8gdGhlIHBhcmFtZXRlcnMgYXJlIGluIGNvbXBpbGVkIGZvcm0gKGZyb20gZ2V0QWN0dWFsVmFsdWUpCi0gICAgcHVibGljIGludCBnZXRGcmFjdGlvbkRpZ2l0cyhPYmplY3QgdmFsdWUpIHsKLSAgICAgICAgcmV0dXJuIC0xOwotICAgIH0KLQotICAgIC8vIGNoZWNrIHdoZXRoZXIgdGhlIGNoYXJhY3RlciBpcyBpbiB0aGUgcmFuZ2UgMHgzMCB+IDB4MzkKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGJvb2xlYW4gaXNEaWdpdChjaGFyIGNoKSB7Ci0gICAgICAgIHJldHVybiBjaCA+PSAnMCcgJiYgY2ggPD0gJzknOwotICAgIH0KLQotICAgIC8vIGlmIHRoZSBjaGFyYWN0ZXIgaXMgaW4gdGhlIHJhbmdlIDB4MzAgfiAweDM5LCByZXR1cm4gaXRzIGludCB2YWx1ZSAoMH45KSwKLSAgICAvLyBvdGhlcndpc2UsIHJldHVybiAtMQotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGdldERpZ2l0KGNoYXIgY2gpIHsKLSAgICAgICAgcmV0dXJuIGlzRGlnaXQoY2gpID8gY2ggLSAnMCcgOiAtMTsKLSAgICB9Ci0KLX0gLy8gaW50ZXJmYWNlIFR5cGVWYWxpZGF0b3IKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYveHMvVW5pb25EVi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi94cy9VbmlvbkRWLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDBhMjk2MzkuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi94cy9VbmlvbkRWLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0NyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLCAyMDAyLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi54czsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5JbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYuVmFsaWRhdGlvbkNvbnRleHQ7Ci0KLS8qKgotICogUmVwcmVzZW50IHRoZSBzY2hlbWEgdW5pb24gdHlwZXMKLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBOZWVyYWogQmFqYWosIFN1biBNaWNyb3N5c3RlbXMsIGluYy4KLSAqIEBhdXRob3IgU2FuZHkgR2FvLCBJQk0KLSAqCi0gKi8KLXB1YmxpYyBjbGFzcyBVbmlvbkRWIGV4dGVuZHMgVHlwZVZhbGlkYXRvcnsKLQotICAgIHB1YmxpYyBzaG9ydCBnZXRBbGxvd2VkRmFjZXRzKCl7Ci0gICAgICAgICAgcmV0dXJuIChYU1NpbXBsZVR5cGVEZWNsLkZBQ0VUX1BBVFRFUk4gfCBYU1NpbXBsZVR5cGVEZWNsLkZBQ0VUX0VOVU1FUkFUSU9OICk7Ci0gICAgfQotCi0gICAgLy8gdGhpcyBtZXRob2Qgc2hvdWxkIG5ldmVyIGJlIGNhbGxlZDogWFNTaW1wbGVUeXBlRGVjbCBpcyByZXNwb25zaWJsZSBmb3IKLSAgICAvLyBjYWxsaW5nIHRoZSBtZW1iZXIgdHlwZXMgZm9yIHRoZSBjb252ZXJ0aW9uCi0gICAgcHVibGljIE9iamVjdCBnZXRBY3R1YWxWYWx1ZShTdHJpbmcgY29udGVudCwgVmFsaWRhdGlvbkNvbnRleHQgY29udGV4dCkgdGhyb3dzIEludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uewotICAgICAgICByZXR1cm4gY29udGVudDsKLSAgICB9Ci0KLX0gLy8gY2xhc3MgVW5pb25EVgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi94cy9YU1NpbXBsZVR5cGVEZWNsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L3hzL1hTU2ltcGxlVHlwZURlY2wuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYzljOTEzNC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L3hzL1hTU2ltcGxlVHlwZURlY2wuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDMzOTggKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYueHM7Ci0KLWltcG9ydCBqYXZhLnV0aWwuQWJzdHJhY3RMaXN0OwotaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7Ci1pbXBvcnQgamF2YS51dGlsLlN0cmluZ1Rva2VuaXplcjsKLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLkNvbnN0YW50czsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYuRGF0YXR5cGVFeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LkludmFsaWREYXRhdHlwZUZhY2V0RXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5JbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYuVmFsaWRhdGVkSW5mbzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYuVmFsaWRhdGlvbkNvbnRleHQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LlhTRmFjZXRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5YU1NpbXBsZVR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhwYXRoLnJlZ2V4LlJlZ3VsYXJFeHByZXNzaW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cGF0aC5yZWdleC5QYXJzZUV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMuU2NoZW1hU3ltYm9sczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMudXRpbC5TaG9ydExpc3RJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy51dGlsLlN0cmluZ0xpc3RJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy51dGlsLlhTT2JqZWN0TGlzdEltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlhNTENoYXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuTmFtZXNwYWNlQ29udGV4dDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlNob3J0TGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlN0cmluZ0xpc3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU0Fubm90YXRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU0NvbnN0YW50czsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTRmFjZXQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU011bHRpVmFsdWVGYWNldDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTTmFtZXNwYWNlSXRlbTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTT2JqZWN0TGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTU2ltcGxlVHlwZURlZmluaXRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU1R5cGVEZWZpbml0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuZGF0YXR5cGVzLk9iamVjdExpc3Q7Ci1pbXBvcnQgb3JnLnczYy5kb20uVHlwZUluZm87Ci0KLS8qKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgU2FuZHkgR2FvLCBJQk0KLSAqIEBhdXRob3IgTmVlcmFqIEJhamFqLCBTdW4gTWljcm9zeXN0ZW1zLCBpbmMuCi0gKgotICogQHZlcnNpb24gJElkOiBYU1NpbXBsZVR5cGVEZWNsLmphdmEgMzAyOSAyMDExLTA0LTI0IDE3OjUwOjE4WiBqb2VodyAkCi0gKi8KLXB1YmxpYyBjbGFzcyBYU1NpbXBsZVR5cGVEZWNsIGltcGxlbWVudHMgWFNTaW1wbGVUeXBlLCBUeXBlSW5mbyB7Ci0KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIHNob3J0IERWX1NUUklORyAgICAgICAgPSBQUklNSVRJVkVfU1RSSU5HOwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgc2hvcnQgRFZfQk9PTEVBTiAgICAgICA9IFBSSU1JVElWRV9CT09MRUFOOwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgc2hvcnQgRFZfREVDSU1BTCAgICAgICA9IFBSSU1JVElWRV9ERUNJTUFMOwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgc2hvcnQgRFZfRkxPQVQgICAgICAgICA9IFBSSU1JVElWRV9GTE9BVDsKLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIHNob3J0IERWX0RPVUJMRSAgICAgICAgPSBQUklNSVRJVkVfRE9VQkxFOwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgc2hvcnQgRFZfRFVSQVRJT04gICAgICA9IFBSSU1JVElWRV9EVVJBVElPTjsKLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIHNob3J0IERWX0RBVEVUSU1FICAgICAgPSBQUklNSVRJVkVfREFURVRJTUU7Ci0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBzaG9ydCBEVl9USU1FICAgICAgICAgID0gUFJJTUlUSVZFX1RJTUU7Ci0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBzaG9ydCBEVl9EQVRFICAgICAgICAgID0gUFJJTUlUSVZFX0RBVEU7Ci0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBzaG9ydCBEVl9HWUVBUk1PTlRIICAgID0gUFJJTUlUSVZFX0dZRUFSTU9OVEg7Ci0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBzaG9ydCBEVl9HWUVBUiAgICAgICAgID0gUFJJTUlUSVZFX0dZRUFSOwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgc2hvcnQgRFZfR01PTlRIREFZICAgICA9IFBSSU1JVElWRV9HTU9OVEhEQVk7Ci0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBzaG9ydCBEVl9HREFZICAgICAgICAgID0gUFJJTUlUSVZFX0dEQVk7Ci0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBzaG9ydCBEVl9HTU9OVEggICAgICAgID0gUFJJTUlUSVZFX0dNT05USDsKLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIHNob3J0IERWX0hFWEJJTkFSWSAgICAgPSBQUklNSVRJVkVfSEVYQklOQVJZOwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgc2hvcnQgRFZfQkFTRTY0QklOQVJZICA9IFBSSU1JVElWRV9CQVNFNjRCSU5BUlk7Ci0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBzaG9ydCBEVl9BTllVUkkgICAgICAgID0gUFJJTUlUSVZFX0FOWVVSSTsKLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIHNob3J0IERWX1FOQU1FICAgICAgICAgPSBQUklNSVRJVkVfUU5BTUU7Ci0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBzaG9ydCBEVl9QUkVDSVNJT05ERUNJTUFMID0gUFJJTUlUSVZFX1BSRUNJU0lPTkRFQ0lNQUw7Ci0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBzaG9ydCBEVl9OT1RBVElPTiAgICAgID0gUFJJTUlUSVZFX05PVEFUSU9OOwotCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBzaG9ydCBEVl9BTllTSU1QTEVUWVBFID0gMDsKLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIHNob3J0IERWX0lEICAgICAgICAgICAgPSBEVl9OT1RBVElPTiArIDE7Ci0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBzaG9ydCBEVl9JRFJFRiAgICAgICAgID0gRFZfTk9UQVRJT04gKyAyOwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgc2hvcnQgRFZfRU5USVRZICAgICAgICA9IERWX05PVEFUSU9OICsgMzsKLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIHNob3J0IERWX0lOVEVHRVIgICAgICAgPSBEVl9OT1RBVElPTiArIDQ7Ci0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBzaG9ydCBEVl9MSVNUICAgICAgICAgID0gRFZfTk9UQVRJT04gKyA1OwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgc2hvcnQgRFZfVU5JT04gICAgICAgICA9IERWX05PVEFUSU9OICsgNjsKLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIHNob3J0IERWX1lFQVJNT05USERVUkFUSU9OID0gRFZfTk9UQVRJT04gKyA3OwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgc2hvcnQgRFZfREFZVElNRURVUkFUSU9OICAgICA9IERWX05PVEFUSU9OICsgODsKLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIHNob3J0IERWX0FOWUFUT01JQ1RZUEUgPSBEVl9OT1RBVElPTiArIDk7Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBUeXBlVmFsaWRhdG9yW10gZ0RWcyA9IHsKLSAgICAgICAgbmV3IEFueVNpbXBsZURWKCksCi0gICAgICAgIG5ldyBTdHJpbmdEVigpLAotICAgICAgICBuZXcgQm9vbGVhbkRWKCksCi0gICAgICAgIG5ldyBEZWNpbWFsRFYoKSwKLSAgICAgICAgbmV3IEZsb2F0RFYoKSwKLSAgICAgICAgbmV3IERvdWJsZURWKCksCi0gICAgICAgIG5ldyBEdXJhdGlvbkRWKCksCi0gICAgICAgIG5ldyBEYXRlVGltZURWKCksCi0gICAgICAgIG5ldyBUaW1lRFYoKSwKLSAgICAgICAgbmV3IERhdGVEVigpLAotICAgICAgICBuZXcgWWVhck1vbnRoRFYoKSwKLSAgICAgICAgbmV3IFllYXJEVigpLAotICAgICAgICBuZXcgTW9udGhEYXlEVigpLAotICAgICAgICBuZXcgRGF5RFYoKSwKLSAgICAgICAgbmV3IE1vbnRoRFYoKSwKLSAgICAgICAgbmV3IEhleEJpbmFyeURWKCksCi0gICAgICAgIG5ldyBCYXNlNjRCaW5hcnlEVigpLAotICAgICAgICBuZXcgQW55VVJJRFYoKSwKLSAgICAgICAgbmV3IFFOYW1lRFYoKSwKLSAgICAgICAgbmV3IFByZWNpc2lvbkRlY2ltYWxEVigpLCAvLyBYTUwgU2NoZW1hIDEuMSB0eXBlCi0gICAgICAgIG5ldyBRTmFtZURWKCksICAgLy8gbm90YXRpb24gdXNlIHRoZSBzYW1lIG9uZSBhcyBxbmFtZQotICAgICAgICBuZXcgSUREVigpLAotICAgICAgICBuZXcgSURSRUZEVigpLAotICAgICAgICBuZXcgRW50aXR5RFYoKSwKLSAgICAgICAgbmV3IEludGVnZXJEVigpLAotICAgICAgICBuZXcgTGlzdERWKCksCi0gICAgICAgIG5ldyBVbmlvbkRWKCksCi0gICAgICAgIG5ldyBZZWFyTW9udGhEdXJhdGlvbkRWKCksIC8vIFhNTCBTY2hlbWEgMS4xIHR5cGUKLSAgICAgICAgbmV3IERheVRpbWVEdXJhdGlvbkRWKCksIC8vIFhNTCBTY2hlbWEgMS4xIHR5cGUKLSAgICAgICAgbmV3IEFueUF0b21pY0RWKCkgLy8gWE1MIFNjaGVtYSAxLjEgdHlwZQotICAgIH07Ci0KLSAgICBzdGF0aWMgZmluYWwgc2hvcnQgTk9STUFMSVpFX05PTkUgPSAwOwotICAgIHN0YXRpYyBmaW5hbCBzaG9ydCBOT1JNQUxJWkVfVFJJTSA9IDE7Ci0gICAgc3RhdGljIGZpbmFsIHNob3J0IE5PUk1BTElaRV9GVUxMID0gMjsKLSAgICBzdGF0aWMgZmluYWwgc2hvcnRbXSBmRFZOb3JtYWxpemVUeXBlID0gewotICAgICAgICBOT1JNQUxJWkVfTk9ORSwgLy9BbnlTaW1wbGVEVigpLAotICAgICAgICBOT1JNQUxJWkVfRlVMTCwgLy9TdHJpbmdEVigpLAotICAgICAgICBOT1JNQUxJWkVfVFJJTSwgLy9Cb29sZWFuRFYoKSwKLSAgICAgICAgTk9STUFMSVpFX1RSSU0sIC8vRGVjaW1hbERWKCksCi0gICAgICAgIE5PUk1BTElaRV9UUklNLCAvL0Zsb2F0RFYoKSwKLSAgICAgICAgTk9STUFMSVpFX1RSSU0sIC8vRG91YmxlRFYoKSwKLSAgICAgICAgTk9STUFMSVpFX1RSSU0sIC8vRHVyYXRpb25EVigpLAotICAgICAgICBOT1JNQUxJWkVfVFJJTSwgLy9EYXRlVGltZURWKCksCi0gICAgICAgIE5PUk1BTElaRV9UUklNLCAvL1RpbWVEVigpLAotICAgICAgICBOT1JNQUxJWkVfVFJJTSwgLy9EYXRlRFYoKSwKLSAgICAgICAgTk9STUFMSVpFX1RSSU0sIC8vWWVhck1vbnRoRFYoKSwKLSAgICAgICAgTk9STUFMSVpFX1RSSU0sIC8vWWVhckRWKCksCi0gICAgICAgIE5PUk1BTElaRV9UUklNLCAvL01vbnRoRGF5RFYoKSwKLSAgICAgICAgTk9STUFMSVpFX1RSSU0sIC8vRGF5RFYoKSwKLSAgICAgICAgTk9STUFMSVpFX1RSSU0sIC8vTW9udGhEVigpLAotICAgICAgICBOT1JNQUxJWkVfVFJJTSwgLy9IZXhCaW5hcnlEVigpLAotICAgICAgICBOT1JNQUxJWkVfTk9ORSwgLy9CYXNlNjRCaW5hcnlEVigpLCAgLy8gQmFzZTY0IGtub3cgaG93IHRvIGRlYWwgd2l0aCBzcGFjZXMKLSAgICAgICAgTk9STUFMSVpFX1RSSU0sIC8vQW55VVJJRFYoKSwKLSAgICAgICAgTk9STUFMSVpFX1RSSU0sIC8vUU5hbWVEVigpLAotICAgICAgICBOT1JNQUxJWkVfVFJJTSwgLy9QcmVjaXNpb25EZWNpbWFsRFYoKSAoU2NoZW1hIDEuMSkKLSAgICAgICAgTk9STUFMSVpFX1RSSU0sIC8vUU5hbWVEVigpLCAgIC8vIG5vdGF0aW9uCi0gICAgICAgIE5PUk1BTElaRV9UUklNLCAvL0lERFYoKSwKLSAgICAgICAgTk9STUFMSVpFX1RSSU0sIC8vSURSRUZEVigpLAotICAgICAgICBOT1JNQUxJWkVfVFJJTSwgLy9FbnRpdHlEVigpLAotICAgICAgICBOT1JNQUxJWkVfVFJJTSwgLy9JbnRlZ2VyRFYoKSwKLSAgICAgICAgTk9STUFMSVpFX0ZVTEwsIC8vTGlzdERWKCksCi0gICAgICAgIE5PUk1BTElaRV9OT05FLCAvL1VuaW9uRFYoKSwKLSAgICAgICAgTk9STUFMSVpFX1RSSU0sIC8vWWVhck1vbnRoRHVyYXRpb25EVigpIChTY2hlbWEgMS4xKQotICAgICAgICBOT1JNQUxJWkVfVFJJTSwgLy9EYXlUaW1lRHVyYXRpb25EVigpIChTY2hlbWEgMS4xKQotICAgICAgICBOT1JNQUxJWkVfTk9ORSwgLy9BbnlBdG9taWNEVigpIChTY2hlbWEgMS4xKQotICAgIH07Ci0KLSAgICBzdGF0aWMgZmluYWwgc2hvcnQgU1BFQ0lBTF9QQVRURVJOX05PTkUgICAgID0gMDsKLSAgICBzdGF0aWMgZmluYWwgc2hvcnQgU1BFQ0lBTF9QQVRURVJOX05NVE9LRU4gID0gMTsKLSAgICBzdGF0aWMgZmluYWwgc2hvcnQgU1BFQ0lBTF9QQVRURVJOX05BTUUgICAgID0gMjsKLSAgICBzdGF0aWMgZmluYWwgc2hvcnQgU1BFQ0lBTF9QQVRURVJOX05DTkFNRSAgID0gMzsKLQotICAgIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSBTUEVDSUFMX1BBVFRFUk5fU1RSSU5HICAgPSB7Ci0gICAgICAgICJOT05FIiwgIk5NVE9LRU4iLCAiTmFtZSIsICJOQ05hbWUiCi0gICAgfTsKLQotICAgIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSBXU19GQUNFVF9TVFJJTkcgPSB7Ci0gICAgICAgICJwcmVzZXJ2ZSIsICJyZXBsYWNlIiwgImNvbGxhcHNlIgotICAgIH07Ci0KLSAgICBzdGF0aWMgZmluYWwgU3RyaW5nIFVSSV9TQ0hFTUFGT1JTQ0hFTUEgPSAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiOwotICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgQU5ZX1RZUEUgPSAiYW55VHlwZSI7Ci0KLSAgICAvLyBYTUwgU2NoZW1hIDEuMSB0eXBlIGNvbnN0YW50cwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgWUVBUk1PTlRIRFVSQVRJT05fRFQgICAgICA9IDQ2OwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgREFZVElNRURVUkFUSU9OX0RUICAgICAgICA9IDQ3OwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgUFJFQ0lTSU9OREVDSU1BTF9EVCAgICAgICA9IDQ4OwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgQU5ZQVRPTUlDVFlQRV9EVCAgICAgICAgICA9IDQ5OwotCi0gICAgLy8gRE9NIExldmVsIDMgVHlwZUluZm8gRGVyaXZhdGlvbiBNZXRob2QgY29uc3RhbnRzCi0gICAgc3RhdGljIGZpbmFsIGludCBERVJJVkFUSU9OX0FOWSA9IDA7Ci0gICAgc3RhdGljIGZpbmFsIGludCBERVJJVkFUSU9OX1JFU1RSSUNUSU9OID0gMTsKLSAgICBzdGF0aWMgZmluYWwgaW50IERFUklWQVRJT05fRVhURU5TSU9OID0gMjsKLSAgICBzdGF0aWMgZmluYWwgaW50IERFUklWQVRJT05fVU5JT04gPSA0OwotICAgIHN0YXRpYyBmaW5hbCBpbnQgREVSSVZBVElPTl9MSVNUID0gODsKLQotICAgIHN0YXRpYyBmaW5hbCBWYWxpZGF0aW9uQ29udGV4dCBmRW1wdHlDb250ZXh0ID0gbmV3IFZhbGlkYXRpb25Db250ZXh0KCkgewotICAgICAgICBwdWJsaWMgYm9vbGVhbiBuZWVkRmFjZXRDaGVja2luZygpIHsKLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0gICAgICAgIHB1YmxpYyBib29sZWFuIG5lZWRFeHRyYUNoZWNraW5nKCkgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0gICAgICAgIHB1YmxpYyBib29sZWFuIG5lZWRUb05vcm1hbGl6ZSgpIHsKLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0gICAgICAgIHB1YmxpYyBib29sZWFuIHVzZU5hbWVzcGFjZXMgKCkgewotICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgIH0KLSAgICAgICAgcHVibGljIGJvb2xlYW4gaXNFbnRpdHlEZWNsYXJlZCAoU3RyaW5nIG5hbWUpIHsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc0VudGl0eVVucGFyc2VkIChTdHJpbmcgbmFtZSkgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0gICAgICAgIHB1YmxpYyBib29sZWFuIGlzSWREZWNsYXJlZCAoU3RyaW5nIG5hbWUpIHsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotICAgICAgICBwdWJsaWMgdm9pZCBhZGRJZChTdHJpbmcgbmFtZSkgewotICAgICAgICB9Ci0gICAgICAgIHB1YmxpYyB2b2lkIGFkZElkUmVmKFN0cmluZyBuYW1lKSB7Ci0gICAgICAgIH0KLSAgICAgICAgcHVibGljIFN0cmluZyBnZXRTeW1ib2wgKFN0cmluZyBzeW1ib2wpIHsKLSAgICAgICAgICAgIHJldHVybiBzeW1ib2wuaW50ZXJuKCk7Ci0gICAgICAgIH0KLSAgICAgICAgcHVibGljIFN0cmluZyBnZXRVUkkoU3RyaW5nIHByZWZpeCkgewotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLSAgICAgICAgcHVibGljIExvY2FsZSBnZXRMb2NhbGUoKSB7Ci0gICAgICAgICAgICByZXR1cm4gTG9jYWxlLmdldERlZmF1bHQoKTsKLSAgICAgICAgfQotICAgIH07Ci0KLSAgICBwcm90ZWN0ZWQgc3RhdGljIFR5cGVWYWxpZGF0b3JbXSBnZXRHRFZzKCkgewotICAgICAgICByZXR1cm4gKFR5cGVWYWxpZGF0b3JbXSlnRFZzLmNsb25lKCk7Ci0gICAgfQotICAgIHByaXZhdGUgVHlwZVZhbGlkYXRvcltdIGZEVnMgPSBnRFZzOwotICAgIHByb3RlY3RlZCB2b2lkIHNldERWcyhUeXBlVmFsaWRhdG9yW10gZHZzKSB7Ci0gICAgICAgIGZEVnMgPSBkdnM7Ci0gICAgfQotCi0gICAgLy8gdGhpcyB3aWxsIGJlIHRydWUgaWYgdGhpcyBpcyBhIHN0YXRpYyBYU1NpbXBsZVR5cGVEZWNsCi0gICAgLy8gYW5kIGhlbmNlIG11c3QgcmVtYWluIGltbXV0YWJsZSAoaS5lLiwgYXBwbHlGYWNldHMKLSAgICAvLyBtYXkgbm90IGJlIHBlcm1pdHRlZCB0byBoYXZlIGFueSBlZmZlY3QpLgotICAgIHByaXZhdGUgYm9vbGVhbiBmSXNJbW11dGFibGUgPSBmYWxzZTsKLQotICAgIHByaXZhdGUgWFNTaW1wbGVUeXBlRGVjbCBmSXRlbVR5cGU7Ci0gICAgcHJpdmF0ZSBYU1NpbXBsZVR5cGVEZWNsW10gZk1lbWJlclR5cGVzOwotICAgIC8vIFRoZSBtb3N0IHNwZWNpZmljIGJ1aWx0LWluIHR5cGUga2luZC4KLSAgICBwcml2YXRlIHNob3J0IGZCdWlsdEluS2luZDsKLQotICAgIHByaXZhdGUgU3RyaW5nIGZUeXBlTmFtZTsKLSAgICBwcml2YXRlIFN0cmluZyBmVGFyZ2V0TmFtZXNwYWNlOwotICAgIHByaXZhdGUgc2hvcnQgZkZpbmFsU2V0ID0gMDsKLSAgICBwcml2YXRlIFhTU2ltcGxlVHlwZURlY2wgZkJhc2U7Ci0gICAgcHJpdmF0ZSBzaG9ydCBmVmFyaWV0eSA9IC0xOwotICAgIHByaXZhdGUgc2hvcnQgZlZhbGlkYXRpb25EViA9IC0xOwotCi0gICAgcHJpdmF0ZSBzaG9ydCBmRmFjZXRzRGVmaW5lZCA9IDA7Ci0gICAgcHJpdmF0ZSBzaG9ydCBmRml4ZWRGYWNldCA9IDA7Ci0KLSAgICAvL2ZvciBjb25zdHJhaW5pbmcgZmFjZXRzCi0gICAgcHJpdmF0ZSBzaG9ydCBmV2hpdGVTcGFjZSA9IDA7Ci0gICAgcHJpdmF0ZSBpbnQgZkxlbmd0aCA9IC0xOwotICAgIHByaXZhdGUgaW50IGZNaW5MZW5ndGggPSAtMTsKLSAgICBwcml2YXRlIGludCBmTWF4TGVuZ3RoID0gLTE7Ci0gICAgcHJpdmF0ZSBpbnQgZlRvdGFsRGlnaXRzID0gLTE7Ci0gICAgcHJpdmF0ZSBpbnQgZkZyYWN0aW9uRGlnaXRzID0gLTE7Ci0gICAgcHJpdmF0ZSBWZWN0b3IgZlBhdHRlcm47Ci0gICAgcHJpdmF0ZSBWZWN0b3IgZlBhdHRlcm5TdHI7Ci0gICAgcHJpdmF0ZSBWZWN0b3IgZkVudW1lcmF0aW9uOwotICAgIHByaXZhdGUgc2hvcnRbXSBmRW51bWVyYXRpb25UeXBlOwotICAgIHByaXZhdGUgU2hvcnRMaXN0W10gZkVudW1lcmF0aW9uSXRlbVR5cGU7ICAgLy8gdXNlZCBpbiBjYXNlIGZlbnVtZXJhdGlvblR5cGUgdmFsdWUgaXMgTElTVCBvciBMSVNUT0ZVTklPTgotICAgIHByaXZhdGUgU2hvcnRMaXN0IGZFbnVtZXJhdGlvblR5cGVMaXN0OwotICAgIHByaXZhdGUgT2JqZWN0TGlzdCBmRW51bWVyYXRpb25JdGVtVHlwZUxpc3Q7Ci0gICAgcHJpdmF0ZSBTdHJpbmdMaXN0IGZMZXhpY2FsUGF0dGVybjsKLSAgICBwcml2YXRlIFN0cmluZ0xpc3QgZkxleGljYWxFbnVtZXJhdGlvbjsKLSAgICBwcml2YXRlIE9iamVjdExpc3QgZkFjdHVhbEVudW1lcmF0aW9uOwotICAgIHByaXZhdGUgT2JqZWN0IGZNYXhJbmNsdXNpdmU7Ci0gICAgcHJpdmF0ZSBPYmplY3QgZk1heEV4Y2x1c2l2ZTsKLSAgICBwcml2YXRlIE9iamVjdCBmTWluRXhjbHVzaXZlOwotICAgIHByaXZhdGUgT2JqZWN0IGZNaW5JbmNsdXNpdmU7Ci0KLSAgICAvLyBhbm5vdGF0aW9ucyBmb3IgY29uc3RyYWluaW5nIGZhY2V0cwotICAgIHB1YmxpYyBYU0Fubm90YXRpb24gbGVuZ3RoQW5ub3RhdGlvbjsKLSAgICBwdWJsaWMgWFNBbm5vdGF0aW9uIG1pbkxlbmd0aEFubm90YXRpb247Ci0gICAgcHVibGljIFhTQW5ub3RhdGlvbiBtYXhMZW5ndGhBbm5vdGF0aW9uOwotICAgIHB1YmxpYyBYU0Fubm90YXRpb24gd2hpdGVTcGFjZUFubm90YXRpb247Ci0gICAgcHVibGljIFhTQW5ub3RhdGlvbiB0b3RhbERpZ2l0c0Fubm90YXRpb247Ci0gICAgcHVibGljIFhTQW5ub3RhdGlvbiBmcmFjdGlvbkRpZ2l0c0Fubm90YXRpb247Ci0gICAgcHVibGljIFhTT2JqZWN0TGlzdEltcGwgcGF0dGVybkFubm90YXRpb25zOwotICAgIHB1YmxpYyBYU09iamVjdExpc3QgZW51bWVyYXRpb25Bbm5vdGF0aW9uczsKLSAgICBwdWJsaWMgWFNBbm5vdGF0aW9uIG1heEluY2x1c2l2ZUFubm90YXRpb247Ci0gICAgcHVibGljIFhTQW5ub3RhdGlvbiBtYXhFeGNsdXNpdmVBbm5vdGF0aW9uOwotICAgIHB1YmxpYyBYU0Fubm90YXRpb24gbWluSW5jbHVzaXZlQW5ub3RhdGlvbjsKLSAgICBwdWJsaWMgWFNBbm5vdGF0aW9uIG1pbkV4Y2x1c2l2ZUFubm90YXRpb247Ci0KLSAgICAvLyBmYWNldHMgYXMgb2JqZWN0cwotICAgIHByaXZhdGUgWFNPYmplY3RMaXN0SW1wbCBmRmFjZXRzOwotCi0gICAgLy8gZW51bWVyYXRpb24gYW5kIHBhdHRlcm4gZmFjZXRzCi0gICAgcHJpdmF0ZSBYU09iamVjdExpc3RJbXBsIGZNdWx0aVZhbHVlRmFjZXRzOwotCi0gICAgLy8gc2ltcGxlVHlwZSBhbm5vdGF0aW9ucwotICAgIHByaXZhdGUgWFNPYmplY3RMaXN0IGZBbm5vdGF0aW9ucyA9IG51bGw7Ci0KLSAgICBwcml2YXRlIHNob3J0IGZQYXR0ZXJuVHlwZSA9IFNQRUNJQUxfUEFUVEVSTl9OT05FOwotCi0gICAgLy8gZm9yIGZ1bmRhbWVudGFsIGZhY2V0cwotICAgIHByaXZhdGUgc2hvcnQgZk9yZGVyZWQ7Ci0gICAgcHJpdmF0ZSBib29sZWFuIGZGaW5pdGU7Ci0gICAgcHJpdmF0ZSBib29sZWFuIGZCb3VuZGVkOwotICAgIHByaXZhdGUgYm9vbGVhbiBmTnVtZXJpYzsKLQotICAgIC8vIFRoZSBuYW1lc3BhY2Ugc2NoZW1hIGluZm9ybWF0aW9uIGl0ZW0gY29ycmVzcG9uZGluZyB0byB0aGUgdGFyZ2V0IG5hbWVzcGFjZQotICAgIC8vIG9mIHRoZSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uLCBpZiBpdCBpcyBnbG9iYWxseSBkZWNsYXJlZDsgb3IgbnVsbCBvdGhlcndpc2UuCi0gICAgcHJpdmF0ZSBYU05hbWVzcGFjZUl0ZW0gZk5hbWVzcGFjZUl0ZW0gPSBudWxsOwotCi0gICAgLy8gZGVmYXVsdCBjb25zdHJ1Y3RvcgotICAgIHB1YmxpYyBYU1NpbXBsZVR5cGVEZWNsKCl7fQotCi0gICAgLy9DcmVhdGUgYSBuZXcgYnVpbHQtaW4gcHJpbWl0aXZlIHR5cGVzIChhbmQgaWQvaWRyZWYvZW50aXR5L2ludGVnZXIveWVhck1vbnRoRHVyYXRpb24pCi0gICAgcHJvdGVjdGVkIFhTU2ltcGxlVHlwZURlY2woWFNTaW1wbGVUeXBlRGVjbCBiYXNlLCBTdHJpbmcgbmFtZSwgc2hvcnQgdmFsaWRhdGVEViwKLSAgICAgICAgICAgIHNob3J0IG9yZGVyZWQsIGJvb2xlYW4gYm91bmRlZCwgYm9vbGVhbiBmaW5pdGUsCi0gICAgICAgICAgICBib29sZWFuIG51bWVyaWMsIGJvb2xlYW4gaXNJbW11dGFibGUsIHNob3J0IGJ1aWx0SW5LaW5kKSB7Ci0gICAgICAgIGZJc0ltbXV0YWJsZSA9IGlzSW1tdXRhYmxlOwotICAgICAgICBmQmFzZSA9IGJhc2U7Ci0gICAgICAgIGZUeXBlTmFtZSA9IG5hbWU7Ci0gICAgICAgIGZUYXJnZXROYW1lc3BhY2UgPSBVUklfU0NIRU1BRk9SU0NIRU1BOwotICAgICAgICAvLyBUbyBzaW1wbGlmeSB0aGUgY29kZSBmb3IgYW55U2ltcGxlVHlwZSwgd2UgdHJlYXQgaXQgYXMgYW4gYXRvbWljIHR5cGUKLSAgICAgICAgZlZhcmlldHkgPSBWQVJJRVRZX0FUT01JQzsKLSAgICAgICAgZlZhbGlkYXRpb25EViA9IHZhbGlkYXRlRFY7Ci0gICAgICAgIGZGYWNldHNEZWZpbmVkID0gRkFDRVRfV0hJVEVTUEFDRTsKLSAgICAgICAgaWYgKHZhbGlkYXRlRFYgPT0gRFZfQU5ZU0lNUExFVFlQRSB8fAotICAgICAgICAgICAgdmFsaWRhdGVEViA9PSBEVl9BTllBVE9NSUNUWVBFIHx8Ci0gICAgICAgICAgICB2YWxpZGF0ZURWID09IERWX1NUUklORykgewotICAgICAgICAgICAgZldoaXRlU3BhY2UgPSBXU19QUkVTRVJWRTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIGZXaGl0ZVNwYWNlID0gV1NfQ09MTEFQU0U7Ci0gICAgICAgICAgICBmRml4ZWRGYWNldCA9IEZBQ0VUX1dISVRFU1BBQ0U7Ci0gICAgICAgIH0KLSAgICAgICAgdGhpcy5mT3JkZXJlZCA9IG9yZGVyZWQ7Ci0gICAgICAgIHRoaXMuZkJvdW5kZWQgPSBib3VuZGVkOwotICAgICAgICB0aGlzLmZGaW5pdGUgPSBmaW5pdGU7Ci0gICAgICAgIHRoaXMuZk51bWVyaWMgPSBudW1lcmljOwotICAgICAgICBmQW5ub3RhdGlvbnMgPSBudWxsOwotCi0gICAgICAgIC8vIFNwZWNpZnkgdGhlIGJ1aWxkIGluIGtpbmQgZm9yIHRoaXMgcHJpbWl0aXZlIHR5cGUKLSAgICAgICAgZkJ1aWx0SW5LaW5kID0gYnVpbHRJbktpbmQ7Ci0gICAgfQotCi0gICAgLy9DcmVhdGUgYSBuZXcgc2ltcGxlIHR5cGUgZm9yIHJlc3RyaWN0aW9uIGZvciBidWlsdC1pbiB0eXBlcwotICAgIHByb3RlY3RlZCBYU1NpbXBsZVR5cGVEZWNsKFhTU2ltcGxlVHlwZURlY2wgYmFzZSwgU3RyaW5nIG5hbWUsIFN0cmluZyB1cmksIHNob3J0IGZpbmFsU2V0LCBib29sZWFuIGlzSW1tdXRhYmxlLAotICAgICAgICAgICAgWFNPYmplY3RMaXN0IGFubm90YXRpb25zLCBzaG9ydCBidWlsdEluS2luZCkgewotICAgICAgICB0aGlzKGJhc2UsIG5hbWUsIHVyaSwgZmluYWxTZXQsIGlzSW1tdXRhYmxlLCBhbm5vdGF0aW9ucyk7Ci0gICAgICAgIC8vIFNwZWNpZnkgdGhlIGJ1aWxkIGluIGtpbmQgZm9yIHRoaXMgYnVpbHQtaW4gdHlwZQotICAgICAgICBmQnVpbHRJbktpbmQgPSBidWlsdEluS2luZDsKLSAgICB9Ci0KLSAgICAvL0NyZWF0ZSBhIG5ldyBzaW1wbGUgdHlwZSBmb3IgcmVzdHJpY3Rpb24uCi0gICAgcHJvdGVjdGVkIFhTU2ltcGxlVHlwZURlY2woWFNTaW1wbGVUeXBlRGVjbCBiYXNlLCBTdHJpbmcgbmFtZSwgU3RyaW5nIHVyaSwgc2hvcnQgZmluYWxTZXQsIGJvb2xlYW4gaXNJbW11dGFibGUsCi0gICAgICAgICAgICBYU09iamVjdExpc3QgYW5ub3RhdGlvbnMpIHsKLSAgICAgICAgZkJhc2UgPSBiYXNlOwotICAgICAgICBmVHlwZU5hbWUgPSBuYW1lOwotICAgICAgICBmVGFyZ2V0TmFtZXNwYWNlID0gdXJpOwotICAgICAgICBmRmluYWxTZXQgPSBmaW5hbFNldDsKLSAgICAgICAgZkFubm90YXRpb25zID0gYW5ub3RhdGlvbnM7Ci0KLSAgICAgICAgZlZhcmlldHkgPSBmQmFzZS5mVmFyaWV0eTsKLSAgICAgICAgZlZhbGlkYXRpb25EViA9IGZCYXNlLmZWYWxpZGF0aW9uRFY7Ci0gICAgICAgIHN3aXRjaCAoZlZhcmlldHkpIHsKLSAgICAgICAgICAgIGNhc2UgVkFSSUVUWV9BVE9NSUM6Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICBjYXNlIFZBUklFVFlfTElTVDoKLSAgICAgICAgICAgICAgICBmSXRlbVR5cGUgPSBmQmFzZS5mSXRlbVR5cGU7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICBjYXNlIFZBUklFVFlfVU5JT046Ci0gICAgICAgICAgICAgICAgZk1lbWJlclR5cGVzID0gZkJhc2UuZk1lbWJlclR5cGVzOwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gYWx3YXlzIGluaGVyaXQgZmFjZXRzIGZyb20gdGhlIGJhc2UuCi0gICAgICAgIC8vIGluIGNhc2UgYSB0eXBlIGlzIGNyZWF0ZWQsIGJ1dCBhcHBseUZhY2V0cyBpcyBub3QgY2FsbGVkCi0gICAgICAgIGZMZW5ndGggPSBmQmFzZS5mTGVuZ3RoOwotICAgICAgICBmTWluTGVuZ3RoID0gZkJhc2UuZk1pbkxlbmd0aDsKLSAgICAgICAgZk1heExlbmd0aCA9IGZCYXNlLmZNYXhMZW5ndGg7Ci0gICAgICAgIGZQYXR0ZXJuID0gZkJhc2UuZlBhdHRlcm47Ci0gICAgICAgIGZQYXR0ZXJuU3RyID0gZkJhc2UuZlBhdHRlcm5TdHI7Ci0gICAgICAgIGZFbnVtZXJhdGlvbiA9IGZCYXNlLmZFbnVtZXJhdGlvbjsKLSAgICAgICAgZkVudW1lcmF0aW9uVHlwZSA9IGZCYXNlLmZFbnVtZXJhdGlvblR5cGU7Ci0gICAgICAgIGZFbnVtZXJhdGlvbkl0ZW1UeXBlID0gZkJhc2UuZkVudW1lcmF0aW9uSXRlbVR5cGU7Ci0gICAgICAgIGZXaGl0ZVNwYWNlID0gZkJhc2UuZldoaXRlU3BhY2U7Ci0gICAgICAgIGZNYXhFeGNsdXNpdmUgPSBmQmFzZS5mTWF4RXhjbHVzaXZlOwotICAgICAgICBmTWF4SW5jbHVzaXZlID0gZkJhc2UuZk1heEluY2x1c2l2ZTsKLSAgICAgICAgZk1pbkV4Y2x1c2l2ZSA9IGZCYXNlLmZNaW5FeGNsdXNpdmU7Ci0gICAgICAgIGZNaW5JbmNsdXNpdmUgPSBmQmFzZS5mTWluSW5jbHVzaXZlOwotICAgICAgICBmVG90YWxEaWdpdHMgPSBmQmFzZS5mVG90YWxEaWdpdHM7Ci0gICAgICAgIGZGcmFjdGlvbkRpZ2l0cyA9IGZCYXNlLmZGcmFjdGlvbkRpZ2l0czsKLSAgICAgICAgZlBhdHRlcm5UeXBlID0gZkJhc2UuZlBhdHRlcm5UeXBlOwotICAgICAgICBmRml4ZWRGYWNldCA9IGZCYXNlLmZGaXhlZEZhY2V0OwotICAgICAgICBmRmFjZXRzRGVmaW5lZCA9IGZCYXNlLmZGYWNldHNEZWZpbmVkOwotCi0gICAgICAgIC8vIGFsd2F5cyBpbmhlcml0IGZhY2V0IGFubm90YXRpb25zIGluIGNhc2UgYXBwbHlGYWNldHMgaXMgbm90IGNhbGxlZC4KLSAgICAgICAgbGVuZ3RoQW5ub3RhdGlvbiA9IGZCYXNlLmxlbmd0aEFubm90YXRpb247Ci0gICAgICAgIG1pbkxlbmd0aEFubm90YXRpb24gPSBmQmFzZS5taW5MZW5ndGhBbm5vdGF0aW9uOwotICAgICAgICBtYXhMZW5ndGhBbm5vdGF0aW9uID0gZkJhc2UubWF4TGVuZ3RoQW5ub3RhdGlvbjsKLSAgICAgICAgcGF0dGVybkFubm90YXRpb25zID0gZkJhc2UucGF0dGVybkFubm90YXRpb25zOwotICAgICAgICBlbnVtZXJhdGlvbkFubm90YXRpb25zID0gZkJhc2UuZW51bWVyYXRpb25Bbm5vdGF0aW9uczsKLSAgICAgICAgd2hpdGVTcGFjZUFubm90YXRpb24gPSBmQmFzZS53aGl0ZVNwYWNlQW5ub3RhdGlvbjsKLSAgICAgICAgbWF4RXhjbHVzaXZlQW5ub3RhdGlvbiA9IGZCYXNlLm1heEV4Y2x1c2l2ZUFubm90YXRpb247Ci0gICAgICAgIG1heEluY2x1c2l2ZUFubm90YXRpb24gPSBmQmFzZS5tYXhJbmNsdXNpdmVBbm5vdGF0aW9uOwotICAgICAgICBtaW5FeGNsdXNpdmVBbm5vdGF0aW9uID0gZkJhc2UubWluRXhjbHVzaXZlQW5ub3RhdGlvbjsKLSAgICAgICAgbWluSW5jbHVzaXZlQW5ub3RhdGlvbiA9IGZCYXNlLm1pbkluY2x1c2l2ZUFubm90YXRpb247Ci0gICAgICAgIHRvdGFsRGlnaXRzQW5ub3RhdGlvbiA9IGZCYXNlLnRvdGFsRGlnaXRzQW5ub3RhdGlvbjsKLSAgICAgICAgZnJhY3Rpb25EaWdpdHNBbm5vdGF0aW9uID0gZkJhc2UuZnJhY3Rpb25EaWdpdHNBbm5vdGF0aW9uOwotCi0gICAgICAgIC8vd2UgYWxzbyBzZXQgZnVuZGFtZW50YWwgZmFjZXRzIGluZm9ybWF0aW9uIGluIGNhc2UgYXBwbHlGYWNldHMgaXMgbm90IGNhbGxlZC4KLSAgICAgICAgY2FsY0Z1bmRhbWVudGFsRmFjZXRzKCk7Ci0gICAgICAgIGZJc0ltbXV0YWJsZSA9IGlzSW1tdXRhYmxlOwotCi0gICAgICAgIC8vIEluaGVyaXQgZnJvbSB0aGUgYmFzZSB0eXBlCi0gICAgICAgIGZCdWlsdEluS2luZCA9IGJhc2UuZkJ1aWx0SW5LaW5kOwotICAgIH0KLQotICAgIC8vQ3JlYXRlIGEgbmV3IHNpbXBsZSB0eXBlIGZvciBsaXN0LgotICAgIHByb3RlY3RlZCBYU1NpbXBsZVR5cGVEZWNsKFN0cmluZyBuYW1lLCBTdHJpbmcgdXJpLCBzaG9ydCBmaW5hbFNldCwgWFNTaW1wbGVUeXBlRGVjbCBpdGVtVHlwZSwgYm9vbGVhbiBpc0ltbXV0YWJsZSwKLSAgICAgICAgICAgIFhTT2JqZWN0TGlzdCBhbm5vdGF0aW9ucykgewotICAgICAgICBmQmFzZSA9IGZBbnlTaW1wbGVUeXBlOwotICAgICAgICBmVHlwZU5hbWUgPSBuYW1lOwotICAgICAgICBmVGFyZ2V0TmFtZXNwYWNlID0gdXJpOwotICAgICAgICBmRmluYWxTZXQgPSBmaW5hbFNldDsKLSAgICAgICAgZkFubm90YXRpb25zID0gYW5ub3RhdGlvbnM7Ci0KLSAgICAgICAgZlZhcmlldHkgPSBWQVJJRVRZX0xJU1Q7Ci0gICAgICAgIGZJdGVtVHlwZSA9IChYU1NpbXBsZVR5cGVEZWNsKWl0ZW1UeXBlOwotICAgICAgICBmVmFsaWRhdGlvbkRWID0gRFZfTElTVDsKLSAgICAgICAgZkZhY2V0c0RlZmluZWQgPSBGQUNFVF9XSElURVNQQUNFOwotICAgICAgICBmRml4ZWRGYWNldCA9IEZBQ0VUX1dISVRFU1BBQ0U7Ci0gICAgICAgIGZXaGl0ZVNwYWNlID0gV1NfQ09MTEFQU0U7Ci0KLSAgICAgICAgLy9zZXR0aW5nIGZ1bmRhbWVudGFsIGZhY2V0cwotICAgICAgICBjYWxjRnVuZGFtZW50YWxGYWNldHMoKTsKLSAgICAgICAgZklzSW1tdXRhYmxlID0gaXNJbW11dGFibGU7Ci0KLSAgICAgICAgLy8gVmFsdWVzIG9mIHRoaXMgdHlwZSBhcmUgbGlzdHMKLSAgICAgICAgZkJ1aWx0SW5LaW5kID0gWFNDb25zdGFudHMuTElTVF9EVDsKLSAgICB9Ci0KLSAgICAvL0NyZWF0ZSBhIG5ldyBzaW1wbGUgdHlwZSBmb3IgdW5pb24uCi0gICAgcHJvdGVjdGVkIFhTU2ltcGxlVHlwZURlY2woU3RyaW5nIG5hbWUsIFN0cmluZyB1cmksIHNob3J0IGZpbmFsU2V0LCBYU1NpbXBsZVR5cGVEZWNsW10gbWVtYmVyVHlwZXMsCi0gICAgICAgICAgICBYU09iamVjdExpc3QgYW5ub3RhdGlvbnMpIHsKLSAgICAgICAgZkJhc2UgPSBmQW55U2ltcGxlVHlwZTsKLSAgICAgICAgZlR5cGVOYW1lID0gbmFtZTsKLSAgICAgICAgZlRhcmdldE5hbWVzcGFjZSA9IHVyaTsKLSAgICAgICAgZkZpbmFsU2V0ID0gZmluYWxTZXQ7Ci0gICAgICAgIGZBbm5vdGF0aW9ucyA9IGFubm90YXRpb25zOwotCi0gICAgICAgIGZWYXJpZXR5ID0gVkFSSUVUWV9VTklPTjsKLSAgICAgICAgZk1lbWJlclR5cGVzID0gbWVtYmVyVHlwZXM7Ci0gICAgICAgIGZWYWxpZGF0aW9uRFYgPSBEVl9VTklPTjsKLSAgICAgICAgLy8gZXZlbiBmb3IgdW5pb24sIHdlIHNldCB3aGl0ZXNwYWNlIHRvIHNvbWV0aGluZwotICAgICAgICAvLyB0aGlzIHdpbGwgbmV2ZXIgYmUgdXNlZCwgYnV0IHdlIGNhbiB1c2UgZkZhY2V0c0RlZmluZWQgdG8gY2hlY2sKLSAgICAgICAgLy8gd2hldGhlciBhcHBseUZhY2V0cygpIGlzIGFsbHd3ZWQ6IGl0J3Mgbm90IGFsbG93ZWQKLSAgICAgICAgLy8gaWYgZkZhY2V0c0RlZmluZWQgIT0gMAotICAgICAgICBmRmFjZXRzRGVmaW5lZCA9IEZBQ0VUX1dISVRFU1BBQ0U7Ci0gICAgICAgIGZXaGl0ZVNwYWNlID0gV1NfQ09MTEFQU0U7Ci0KLSAgICAgICAgLy9zZXR0aW5nIGZ1bmRhbWVudGFsIGZhY2V0cwotICAgICAgICBjYWxjRnVuZGFtZW50YWxGYWNldHMoKTsKLSAgICAgICAgLy8gbm9uZSBvZiB0aGUgc2NoZW1hLWRlZmluZWQgdHlwZXMgYXJlIHVuaW9ucywgc28ganVzdCBzZXQKLSAgICAgICAgLy8gZklzSW1tdXRhYmxlIHRvIGZhbHNlLgotICAgICAgICBmSXNJbW11dGFibGUgPSBmYWxzZTsKLQotICAgICAgICAvLyBObyB2YWx1ZSBjYW4gYmUgb2YgdGhpcyB0eXBlLCBzbyBpdCdzIHVuYXZhaWxhYmxlLgotICAgICAgICBmQnVpbHRJbktpbmQgPSBYU0NvbnN0YW50cy5VTkFWQUlMQUJMRV9EVDsKLSAgICB9Ci0KLSAgICAvL3NldCB2YWx1ZXMgZm9yIHJlc3RyaWN0aW9uLgotICAgIHByb3RlY3RlZCBYU1NpbXBsZVR5cGVEZWNsIHNldFJlc3RyaWN0aW9uVmFsdWVzKFhTU2ltcGxlVHlwZURlY2wgYmFzZSwgU3RyaW5nIG5hbWUsIFN0cmluZyB1cmksIHNob3J0IGZpbmFsU2V0LAotICAgICAgICAgICAgWFNPYmplY3RMaXN0IGFubm90YXRpb25zKSB7Ci0gICAgICAgIC8vZGVjbGluZSB0byBkbyBhbnl0aGluZyBpZiB0aGUgb2JqZWN0IGlzIGltbXV0YWJsZS4KLSAgICAgICAgaWYoZklzSW1tdXRhYmxlKSByZXR1cm4gbnVsbDsKLSAgICAgICAgZkJhc2UgPSBiYXNlOwotICAgICAgICBmQW5vbnltb3VzID0gZmFsc2U7Ci0gICAgICAgIGZUeXBlTmFtZSA9IG5hbWU7Ci0gICAgICAgIGZUYXJnZXROYW1lc3BhY2UgPSB1cmk7Ci0gICAgICAgIGZGaW5hbFNldCA9IGZpbmFsU2V0OwotICAgICAgICBmQW5ub3RhdGlvbnMgPSBhbm5vdGF0aW9uczsKLQotICAgICAgICBmVmFyaWV0eSA9IGZCYXNlLmZWYXJpZXR5OwotICAgICAgICBmVmFsaWRhdGlvbkRWID0gZkJhc2UuZlZhbGlkYXRpb25EVjsKLSAgICAgICAgc3dpdGNoIChmVmFyaWV0eSkgewotICAgICAgICAgICAgY2FzZSBWQVJJRVRZX0FUT01JQzoKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIGNhc2UgVkFSSUVUWV9MSVNUOgotICAgICAgICAgICAgICAgIGZJdGVtVHlwZSA9IGZCYXNlLmZJdGVtVHlwZTsKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIGNhc2UgVkFSSUVUWV9VTklPTjoKLSAgICAgICAgICAgICAgICBmTWVtYmVyVHlwZXMgPSBmQmFzZS5mTWVtYmVyVHlwZXM7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBhbHdheXMgaW5oZXJpdCBmYWNldHMgZnJvbSB0aGUgYmFzZS4KLSAgICAgICAgLy8gaW4gY2FzZSBhIHR5cGUgaXMgY3JlYXRlZCwgYnV0IGFwcGx5RmFjZXRzIGlzIG5vdCBjYWxsZWQKLSAgICAgICAgZkxlbmd0aCA9IGZCYXNlLmZMZW5ndGg7Ci0gICAgICAgIGZNaW5MZW5ndGggPSBmQmFzZS5mTWluTGVuZ3RoOwotICAgICAgICBmTWF4TGVuZ3RoID0gZkJhc2UuZk1heExlbmd0aDsKLSAgICAgICAgZlBhdHRlcm4gPSBmQmFzZS5mUGF0dGVybjsKLSAgICAgICAgZlBhdHRlcm5TdHIgPSBmQmFzZS5mUGF0dGVyblN0cjsKLSAgICAgICAgZkVudW1lcmF0aW9uID0gZkJhc2UuZkVudW1lcmF0aW9uOwotICAgICAgICBmRW51bWVyYXRpb25UeXBlID0gZkJhc2UuZkVudW1lcmF0aW9uVHlwZTsKLSAgICAgICAgZkVudW1lcmF0aW9uSXRlbVR5cGUgPSBmQmFzZS5mRW51bWVyYXRpb25JdGVtVHlwZTsKLSAgICAgICAgZldoaXRlU3BhY2UgPSBmQmFzZS5mV2hpdGVTcGFjZTsKLSAgICAgICAgZk1heEV4Y2x1c2l2ZSA9IGZCYXNlLmZNYXhFeGNsdXNpdmU7Ci0gICAgICAgIGZNYXhJbmNsdXNpdmUgPSBmQmFzZS5mTWF4SW5jbHVzaXZlOwotICAgICAgICBmTWluRXhjbHVzaXZlID0gZkJhc2UuZk1pbkV4Y2x1c2l2ZTsKLSAgICAgICAgZk1pbkluY2x1c2l2ZSA9IGZCYXNlLmZNaW5JbmNsdXNpdmU7Ci0gICAgICAgIGZUb3RhbERpZ2l0cyA9IGZCYXNlLmZUb3RhbERpZ2l0czsKLSAgICAgICAgZkZyYWN0aW9uRGlnaXRzID0gZkJhc2UuZkZyYWN0aW9uRGlnaXRzOwotICAgICAgICBmUGF0dGVyblR5cGUgPSBmQmFzZS5mUGF0dGVyblR5cGU7Ci0gICAgICAgIGZGaXhlZEZhY2V0ID0gZkJhc2UuZkZpeGVkRmFjZXQ7Ci0gICAgICAgIGZGYWNldHNEZWZpbmVkID0gZkJhc2UuZkZhY2V0c0RlZmluZWQ7Ci0KLSAgICAgICAgLy93ZSBhbHNvIHNldCBmdW5kYW1lbnRhbCBmYWNldHMgaW5mb3JtYXRpb24gaW4gY2FzZSBhcHBseUZhY2V0cyBpcyBub3QgY2FsbGVkLgotICAgICAgICBjYWxjRnVuZGFtZW50YWxGYWNldHMoKTsKLQotICAgICAgICAvLyBJbmhlcml0IGZyb20gdGhlIGJhc2UgdHlwZQotICAgICAgICBmQnVpbHRJbktpbmQgPSBiYXNlLmZCdWlsdEluS2luZDsKLQotICAgICAgICByZXR1cm4gdGhpczsKLSAgICB9Ci0KLSAgICAvL3NldCB2YWx1ZXMgZm9yIGxpc3QuCi0gICAgcHJvdGVjdGVkIFhTU2ltcGxlVHlwZURlY2wgc2V0TGlzdFZhbHVlcyhTdHJpbmcgbmFtZSwgU3RyaW5nIHVyaSwgc2hvcnQgZmluYWxTZXQsIFhTU2ltcGxlVHlwZURlY2wgaXRlbVR5cGUsCi0gICAgICAgICAgICBYU09iamVjdExpc3QgYW5ub3RhdGlvbnMpIHsKLSAgICAgICAgLy9kZWNsaW5lIHRvIGRvIGFueXRoaW5nIGlmIHRoZSBvYmplY3QgaXMgaW1tdXRhYmxlLgotICAgICAgICBpZihmSXNJbW11dGFibGUpIHJldHVybiBudWxsOwotICAgICAgICBmQmFzZSA9IGZBbnlTaW1wbGVUeXBlOwotICAgICAgICBmQW5vbnltb3VzID0gZmFsc2U7Ci0gICAgICAgIGZUeXBlTmFtZSA9IG5hbWU7Ci0gICAgICAgIGZUYXJnZXROYW1lc3BhY2UgPSB1cmk7Ci0gICAgICAgIGZGaW5hbFNldCA9IGZpbmFsU2V0OwotICAgICAgICBmQW5ub3RhdGlvbnMgPSBhbm5vdGF0aW9uczsKLQotICAgICAgICBmVmFyaWV0eSA9IFZBUklFVFlfTElTVDsKLSAgICAgICAgZkl0ZW1UeXBlID0gKFhTU2ltcGxlVHlwZURlY2wpaXRlbVR5cGU7Ci0gICAgICAgIGZWYWxpZGF0aW9uRFYgPSBEVl9MSVNUOwotICAgICAgICBmRmFjZXRzRGVmaW5lZCA9IEZBQ0VUX1dISVRFU1BBQ0U7Ci0gICAgICAgIGZGaXhlZEZhY2V0ID0gRkFDRVRfV0hJVEVTUEFDRTsKLSAgICAgICAgZldoaXRlU3BhY2UgPSBXU19DT0xMQVBTRTsKLQotICAgICAgICAvL3NldHRpbmcgZnVuZGFtZW50YWwgZmFjZXRzCi0gICAgICAgIGNhbGNGdW5kYW1lbnRhbEZhY2V0cygpOwotCi0gICAgICAgIC8vIFZhbHVlcyBvZiB0aGlzIHR5cGUgYXJlIGxpc3RzCi0gICAgICAgIGZCdWlsdEluS2luZCA9IFhTQ29uc3RhbnRzLkxJU1RfRFQ7Ci0KLSAgICAgICAgcmV0dXJuIHRoaXM7Ci0gICAgfQotCi0gICAgLy9zZXQgdmFsdWVzIGZvciB1bmlvbi4KLSAgICBwcm90ZWN0ZWQgWFNTaW1wbGVUeXBlRGVjbCBzZXRVbmlvblZhbHVlcyhTdHJpbmcgbmFtZSwgU3RyaW5nIHVyaSwgc2hvcnQgZmluYWxTZXQsIFhTU2ltcGxlVHlwZURlY2xbXSBtZW1iZXJUeXBlcywKLSAgICAgICAgICAgIFhTT2JqZWN0TGlzdCBhbm5vdGF0aW9ucykgewotICAgICAgICAvL2RlY2xpbmUgdG8gZG8gYW55dGhpbmcgaWYgdGhlIG9iamVjdCBpcyBpbW11dGFibGUuCi0gICAgICAgIGlmKGZJc0ltbXV0YWJsZSkgcmV0dXJuIG51bGw7Ci0gICAgICAgIGZCYXNlID0gZkFueVNpbXBsZVR5cGU7Ci0gICAgICAgIGZBbm9ueW1vdXMgPSBmYWxzZTsKLSAgICAgICAgZlR5cGVOYW1lID0gbmFtZTsKLSAgICAgICAgZlRhcmdldE5hbWVzcGFjZSA9IHVyaTsKLSAgICAgICAgZkZpbmFsU2V0ID0gZmluYWxTZXQ7Ci0gICAgICAgIGZBbm5vdGF0aW9ucyA9IGFubm90YXRpb25zOwotCi0gICAgICAgIGZWYXJpZXR5ID0gVkFSSUVUWV9VTklPTjsKLSAgICAgICAgZk1lbWJlclR5cGVzID0gbWVtYmVyVHlwZXM7Ci0gICAgICAgIGZWYWxpZGF0aW9uRFYgPSBEVl9VTklPTjsKLSAgICAgICAgLy8gZXZlbiBmb3IgdW5pb24sIHdlIHNldCB3aGl0ZXNwYWNlIHRvIHNvbWV0aGluZwotICAgICAgICAvLyB0aGlzIHdpbGwgbmV2ZXIgYmUgdXNlZCwgYnV0IHdlIGNhbiB1c2UgZkZhY2V0c0RlZmluZWQgdG8gY2hlY2sKLSAgICAgICAgLy8gd2hldGhlciBhcHBseUZhY2V0cygpIGlzIGFsbHd3ZWQ6IGl0J3Mgbm90IGFsbG93ZWQKLSAgICAgICAgLy8gaWYgZkZhY2V0c0RlZmluZWQgIT0gMAotICAgICAgICBmRmFjZXRzRGVmaW5lZCA9IEZBQ0VUX1dISVRFU1BBQ0U7Ci0gICAgICAgIGZXaGl0ZVNwYWNlID0gV1NfQ09MTEFQU0U7Ci0KLSAgICAgICAgLy9zZXR0aW5nIGZ1bmRhbWVudGFsIGZhY2V0cwotICAgICAgICBjYWxjRnVuZGFtZW50YWxGYWNldHMoKTsKLQotICAgICAgICAvLyBObyB2YWx1ZSBjYW4gYmUgb2YgdGhpcyB0eXBlLCBzbyBpdCdzIHVuYXZhaWxhYmxlLgotICAgICAgICBmQnVpbHRJbktpbmQgPSBYU0NvbnN0YW50cy5VTkFWQUlMQUJMRV9EVDsKLQotICAgICAgICByZXR1cm4gdGhpczsKLSAgICB9Ci0KLSAgICBwdWJsaWMgc2hvcnQgZ2V0VHlwZSAoKSB7Ci0gICAgICAgIHJldHVybiBYU0NvbnN0YW50cy5UWVBFX0RFRklOSVRJT047Ci0gICAgfQotCi0gICAgcHVibGljIHNob3J0IGdldFR5cGVDYXRlZ29yeSAoKSB7Ci0gICAgICAgIHJldHVybiBTSU1QTEVfVFlQRTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKSB7Ci0gICAgICAgIHJldHVybiBnZXRBbm9ueW1vdXMoKT9udWxsOmZUeXBlTmFtZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldFR5cGVOYW1lKCkgewotICAgICAgICByZXR1cm4gZlR5cGVOYW1lOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZXNwYWNlKCkgewotICAgICAgICByZXR1cm4gZlRhcmdldE5hbWVzcGFjZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgc2hvcnQgZ2V0RmluYWwoKXsKLSAgICAgICAgcmV0dXJuIGZGaW5hbFNldDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0ZpbmFsKHNob3J0IGRlcml2YXRpb24pIHsKLSAgICAgICAgcmV0dXJuIChmRmluYWxTZXQgJiBkZXJpdmF0aW9uKSAhPSAwOwotICAgIH0KLQotICAgIHB1YmxpYyBYU1R5cGVEZWZpbml0aW9uIGdldEJhc2VUeXBlKCl7Ci0gICAgICAgIHJldHVybiBmQmFzZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXRBbm9ueW1vdXMoKSB7Ci0gICAgICAgIHJldHVybiBmQW5vbnltb3VzIHx8IChmVHlwZU5hbWUgPT0gbnVsbCk7Ci0gICAgfQotCi0gICAgcHVibGljIHNob3J0IGdldFZhcmlldHkoKXsKLSAgICAgICAgLy8gZm9yIGFueVNpbXBsZVR5cGUsIHJldHVybiBhYnNlbnQgdmFyaWF0eQotICAgICAgICByZXR1cm4gZlZhbGlkYXRpb25EViA9PSBEVl9BTllTSU1QTEVUWVBFID8gVkFSSUVUWV9BQlNFTlQgOiBmVmFyaWV0eTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0lEVHlwZSgpewotICAgICAgICBzd2l0Y2ggKGZWYXJpZXR5KSB7Ci0gICAgICAgICAgICBjYXNlIFZBUklFVFlfQVRPTUlDOgotICAgICAgICAgICAgICAgIHJldHVybiBmVmFsaWRhdGlvbkRWID09IERWX0lEOwotICAgICAgICAgICAgY2FzZSBWQVJJRVRZX0xJU1Q6Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZJdGVtVHlwZS5pc0lEVHlwZSgpOwotICAgICAgICAgICAgY2FzZSBWQVJJRVRZX1VOSU9OOgotICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZk1lbWJlclR5cGVzLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChmTWVtYmVyVHlwZXNbaV0uaXNJRFR5cGUoKSkKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgcHVibGljIHNob3J0IGdldFdoaXRlc3BhY2UoKSB0aHJvd3MgRGF0YXR5cGVFeGNlcHRpb257Ci0gICAgICAgIGlmIChmVmFyaWV0eSA9PSBWQVJJRVRZX1VOSU9OKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgRGF0YXR5cGVFeGNlcHRpb24oImR0LXdoaXRlc3BhY2UiLCBuZXcgT2JqZWN0W117ZlR5cGVOYW1lfSk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGZXaGl0ZVNwYWNlOwotICAgIH0KLQotICAgIHB1YmxpYyBzaG9ydCBnZXRQcmltaXRpdmVLaW5kKCkgewotICAgICAgICBpZiAoZlZhcmlldHkgPT0gVkFSSUVUWV9BVE9NSUMgJiYgZlZhbGlkYXRpb25EViAhPSBEVl9BTllTSU1QTEVUWVBFKSB7Ci0gICAgICAgICAgICBpZiAoZlZhbGlkYXRpb25EViA9PSBEVl9JRCB8fCBmVmFsaWRhdGlvbkRWID09IERWX0lEUkVGIHx8IGZWYWxpZGF0aW9uRFYgPT0gRFZfRU5USVRZKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIERWX1NUUklORzsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKGZWYWxpZGF0aW9uRFYgPT0gRFZfSU5URUdFUikgewotICAgICAgICAgICAgICAgIHJldHVybiBEVl9ERUNJTUFMOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoQ29uc3RhbnRzLlNDSEVNQV8xXzFfU1VQUE9SVCAmJiAoZlZhbGlkYXRpb25EViA9PSBEVl9ZRUFSTU9OVEhEVVJBVElPTiB8fCBmVmFsaWRhdGlvbkRWID09IERWX0RBWVRJTUVEVVJBVElPTikpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gRFZfRFVSQVRJT047Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZlZhbGlkYXRpb25EVjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIC8vIFJFVklTSVQ6IGVycm9yIHNpdHVhdGlvbi4gcnVudGltZSBleGNlcHRpb24/Ci0gICAgICAgICAgICByZXR1cm4gKHNob3J0KTA7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBjbG9zZXN0IGJ1aWx0LWluIHR5cGUgY2F0ZWdvcnkgdGhpcyB0eXBlIHJlcHJlc2VudHMgb3IKLSAgICAgKiBkZXJpdmVkIGZyb20uIEZvciBleGFtcGxlLCBpZiB0aGlzIHNpbXBsZSB0eXBlIGlzIGEgYnVpbHQtaW4gZGVyaXZlZAotICAgICAqIHR5cGUgaW50ZWdlciB0aGUgPGNvZGU+SU5URUdFUl9EVjwvY29kZT4gaXMgcmV0dXJuZWQuCi0gICAgICovCi0gICAgcHVibGljIHNob3J0IGdldEJ1aWx0SW5LaW5kKCkgewotICAgICAgICByZXR1cm4gdGhpcy5mQnVpbHRJbktpbmQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSWYgdmFyaWV0eSBpcyA8Y29kZT5hdG9taWM8L2NvZGU+IHRoZSBwcmltaXRpdmUgdHlwZSBkZWZpbml0aW9uIChhCi0gICAgICogYnVpbHQtaW4gcHJpbWl0aXZlIGRhdGF0eXBlIGRlZmluaXRpb24gb3IgdGhlIHNpbXBsZSB1ci10eXBlCi0gICAgICogZGVmaW5pdGlvbikgaXMgYXZhaWxhYmxlLCBvdGhlcndpc2UgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIFhTU2ltcGxlVHlwZURlZmluaXRpb24gZ2V0UHJpbWl0aXZlVHlwZSgpIHsKLSAgICAgICAgaWYgKGZWYXJpZXR5ID09IFZBUklFVFlfQVRPTUlDICYmIGZWYWxpZGF0aW9uRFYgIT0gRFZfQU5ZU0lNUExFVFlQRSkgewotICAgICAgICAgICAgWFNTaW1wbGVUeXBlRGVjbCBwcmkgPSB0aGlzOwotICAgICAgICAgICAgLy8gcmVjdXJzaXZlbHkgZ2V0IGJhc2UsIHVudGlsIHdlIHJlYWNoIGFueVNpbXBsZVR5cGUKLSAgICAgICAgICAgIHdoaWxlIChwcmkuZkJhc2UgIT0gZkFueVNpbXBsZVR5cGUpCi0gICAgICAgICAgICAgICAgcHJpID0gcHJpLmZCYXNlOwotICAgICAgICAgICAgcmV0dXJuIHByaTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIC8vIFJFVklTSVQ6IGVycm9yIHNpdHVhdGlvbi4gcnVudGltZSBleGNlcHRpb24/Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIElmIHZhcmlldHkgaXMgPGNvZGU+bGlzdDwvY29kZT4gdGhlIGl0ZW0gdHlwZSBkZWZpbml0aW9uIChhbiBhdG9taWMgb3IKLSAgICAgKiB1bmlvbiBzaW1wbGUgdHlwZSBkZWZpbml0aW9uKSBpcyBhdmFpbGFibGUsIG90aGVyd2lzZQotICAgICAqIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBYU1NpbXBsZVR5cGVEZWZpbml0aW9uIGdldEl0ZW1UeXBlKCkgewotICAgICAgICBpZiAoZlZhcmlldHkgPT0gVkFSSUVUWV9MSVNUKSB7Ci0gICAgICAgICAgICByZXR1cm4gZkl0ZW1UeXBlOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgLy8gUkVWSVNJVDogZXJyb3Igc2l0dWF0aW9uLiBydW50aW1lIGV4Y2VwdGlvbj8KLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSWYgdmFyaWV0eSBpcyA8Y29kZT51bmlvbjwvY29kZT4gdGhlIGxpc3Qgb2YgbWVtYmVyIHR5cGUgZGVmaW5pdGlvbnMgKGEKLSAgICAgKiBub24tZW1wdHkgc2VxdWVuY2Ugb2Ygc2ltcGxlIHR5cGUgZGVmaW5pdGlvbnMpIGlzIGF2YWlsYWJsZSwKLSAgICAgKiBvdGhlcndpc2UgYW4gZW1wdHkgPGNvZGU+WFNPYmplY3RMaXN0PC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFNPYmplY3RMaXN0IGdldE1lbWJlclR5cGVzKCkgewotICAgICAgICBpZiAoZlZhcmlldHkgPT0gVkFSSUVUWV9VTklPTikgewotICAgICAgICAgICAgcmV0dXJuIG5ldyBYU09iamVjdExpc3RJbXBsKGZNZW1iZXJUeXBlcywgZk1lbWJlclR5cGVzLmxlbmd0aCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gWFNPYmplY3RMaXN0SW1wbC5FTVBUWV9MSVNUOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSWYgPHJlc3RyaWN0aW9uPiBpcyBjaG9zZW4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBhcHBseUZhY2V0cyhYU0ZhY2V0cyBmYWNldHMsIHNob3J0IHByZXNlbnRGYWNldCwgc2hvcnQgZml4ZWRGYWNldCwgVmFsaWRhdGlvbkNvbnRleHQgY29udGV4dCkKLSAgICB0aHJvd3MgSW52YWxpZERhdGF0eXBlRmFjZXRFeGNlcHRpb24gewotICAgICAgICBpZiAoY29udGV4dCA9PSBudWxsKSB7Ci0gICAgICAgICAgICBjb250ZXh0ID0gZkVtcHR5Q29udGV4dDsKLSAgICAgICAgfQotICAgICAgICBhcHBseUZhY2V0cyhmYWNldHMsIHByZXNlbnRGYWNldCwgZml4ZWRGYWNldCwgU1BFQ0lBTF9QQVRURVJOX05PTkUsIGNvbnRleHQpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIGJ1aWx0LWluIGRlcml2ZWQgdHlwZXMgYnkgcmVzdHJpY3Rpb24KLSAgICAgKi8KLSAgICB2b2lkIGFwcGx5RmFjZXRzMShYU0ZhY2V0cyBmYWNldHMsIHNob3J0IHByZXNlbnRGYWNldCwgc2hvcnQgZml4ZWRGYWNldCkgewotCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBhcHBseUZhY2V0cyhmYWNldHMsIHByZXNlbnRGYWNldCwgZml4ZWRGYWNldCwgU1BFQ0lBTF9QQVRURVJOX05PTkUsIGZEdW1teUNvbnRleHQpOwotICAgICAgICB9IGNhdGNoIChJbnZhbGlkRGF0YXR5cGVGYWNldEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAvLyBzaG91bGQgbmV2ZXIgZ2V0cyBoZXJlLCBpbnRlcm5lbCBlcnJvcgotICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oImludGVybmFsIGVycm9yIik7Ci0gICAgICAgIH0KLSAgICAgICAgLy8gd2UndmUgbm93IGFwcGxpZWQgZmFjZXRzOyBzbyBsb2NrIHRoaXMgb2JqZWN0OgotICAgICAgICBmSXNJbW11dGFibGUgPSB0cnVlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIGJ1aWx0LWluIGRlcml2ZWQgdHlwZXMgYnkgcmVzdHJpY3Rpb24KLSAgICAgKi8KLSAgICB2b2lkIGFwcGx5RmFjZXRzMShYU0ZhY2V0cyBmYWNldHMsIHNob3J0IHByZXNlbnRGYWNldCwgc2hvcnQgZml4ZWRGYWNldCwgc2hvcnQgcGF0dGVyblR5cGUpIHsKLQotICAgICAgICB0cnkgewotICAgICAgICAgICAgYXBwbHlGYWNldHMoZmFjZXRzLCBwcmVzZW50RmFjZXQsIGZpeGVkRmFjZXQsIHBhdHRlcm5UeXBlLCBmRHVtbXlDb250ZXh0KTsKLSAgICAgICAgfSBjYXRjaCAoSW52YWxpZERhdGF0eXBlRmFjZXRFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgLy8gc2hvdWxkIG5ldmVyIGdldHMgaGVyZSwgaW50ZXJuZWwgZXJyb3IKLSAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJpbnRlcm5hbCBlcnJvciIpOwotICAgICAgICB9Ci0gICAgICAgIC8vIHdlJ3ZlIG5vdyBhcHBsaWVkIGZhY2V0czsgc28gbG9jayB0aGlzIG9iamVjdDoKLSAgICAgICAgZklzSW1tdXRhYmxlID0gdHJ1ZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJZiA8cmVzdHJpY3Rpb24+IGlzIGNob3Nlbiwgb3IgYnVpbHQtaW4gZGVyaXZlZCB0eXBlcyBieSByZXN0cmljdGlvbgotICAgICAqLwotICAgIHZvaWQgYXBwbHlGYWNldHMoWFNGYWNldHMgZmFjZXRzLCBzaG9ydCBwcmVzZW50RmFjZXQsIHNob3J0IGZpeGVkRmFjZXQsIHNob3J0IHBhdHRlcm5UeXBlLCBWYWxpZGF0aW9uQ29udGV4dCBjb250ZXh0KQotICAgIHRocm93cyBJbnZhbGlkRGF0YXR5cGVGYWNldEV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy8gaWYgdGhlIG9iamVjdCBpcyBpbW11dGFibGUsIHNob3VsZCBub3QgYXBwbHkgZmFjZXRzLi4uCi0gICAgICAgIGlmKGZJc0ltbXV0YWJsZSkgcmV0dXJuOwotICAgICAgICBWYWxpZGF0ZWRJbmZvIHRlbXBJbmZvID0gbmV3IFZhbGlkYXRlZEluZm8oKTsKLQotICAgICAgICAvLyBjbGVhciBmYWNldHMuIGJlY2F1c2Ugd2UgYWx3YXlzIGluaGVyaXQgZmFjZXRzIGluIHRoZSBjb25zdHJ1Y3RvcgotICAgICAgICAvLyBSRVZJU0lUOiBpbiBmYWN0LCB3ZSBkb24ndCBuZWVkIHRvIGNsZWFyIHRoZW0uCi0gICAgICAgIC8vIHdlIGNhbiBjb252ZXJ0IDUgc3RyaW5nIHZhbHVlcyAoNCBib3VuZHMgKyAxIGVudW0pIHRvIGFjdHVhbCB2YWx1ZXMsCi0gICAgICAgIC8vIHN0b3JlIHRoZW0gc29tZXdoZXJlLCB0aGVuIGRvIGZhY2V0IGNoZWNraW5nIGF0IG9uY2UsIGluc3RlYWQgb2YKLSAgICAgICAgLy8gZ29pbmcgdGhyb3VnaCB0aGUgZm9sbG93aW5nIHN0ZXBzLiAobG90cyBvZiBjaGVja2luZyBhcmUgcmVkdW5kYW50OgotICAgICAgICAvLyBmb3IgZXhhbXBsZSwgKChwcmVzZW50RmFjZXQgJiBGQUNFVF9YWFgpICE9IDApKQotCi0gICAgICAgIGZGYWNldHNEZWZpbmVkID0gMDsKLSAgICAgICAgZkZpeGVkRmFjZXQgPSAwOwotCi0gICAgICAgIGludCByZXN1bHQgPSAwIDsKLQotICAgICAgICAvLyBzdGVwIDE6IHBhcnNlIHByZXNlbnQgZmFjZXRzCi0gICAgICAgIHNob3J0IGFsbG93ZWRGYWNldCA9IGZEVnNbZlZhbGlkYXRpb25EVl0uZ2V0QWxsb3dlZEZhY2V0cygpOwotCi0gICAgICAgIC8vIGxlbmd0aAotICAgICAgICBpZiAoKHByZXNlbnRGYWNldCAmIEZBQ0VUX0xFTkdUSCkgIT0gMCkgewotICAgICAgICAgICAgaWYgKChhbGxvd2VkRmFjZXQgJiBGQUNFVF9MRU5HVEgpID09IDApIHsKLSAgICAgICAgICAgICAgICByZXBvcnRFcnJvcigiY29zLWFwcGxpY2FibGUtZmFjZXRzIiwgbmV3IE9iamVjdFtdeyJsZW5ndGgiLCBmVHlwZU5hbWV9KTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgZkxlbmd0aCA9IGZhY2V0cy5sZW5ndGg7Ci0gICAgICAgICAgICAgICAgbGVuZ3RoQW5ub3RhdGlvbiA9IGZhY2V0cy5sZW5ndGhBbm5vdGF0aW9uOwotICAgICAgICAgICAgICAgIGZGYWNldHNEZWZpbmVkIHw9IEZBQ0VUX0xFTkdUSDsKLSAgICAgICAgICAgICAgICBpZiAoKGZpeGVkRmFjZXQgJiBGQUNFVF9MRU5HVEgpICE9IDApCi0gICAgICAgICAgICAgICAgICAgIGZGaXhlZEZhY2V0IHw9IEZBQ0VUX0xFTkdUSDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICAvLyBtaW5MZW5ndGgKLSAgICAgICAgaWYgKChwcmVzZW50RmFjZXQgJiBGQUNFVF9NSU5MRU5HVEgpICE9IDApIHsKLSAgICAgICAgICAgIGlmICgoYWxsb3dlZEZhY2V0ICYgRkFDRVRfTUlOTEVOR1RIKSA9PSAwKSB7Ci0gICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoImNvcy1hcHBsaWNhYmxlLWZhY2V0cyIsIG5ldyBPYmplY3RbXXsibWluTGVuZ3RoIiwgZlR5cGVOYW1lfSk7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIGZNaW5MZW5ndGggPSBmYWNldHMubWluTGVuZ3RoOwotICAgICAgICAgICAgICAgIG1pbkxlbmd0aEFubm90YXRpb24gPSBmYWNldHMubWluTGVuZ3RoQW5ub3RhdGlvbjsKLSAgICAgICAgICAgICAgICBmRmFjZXRzRGVmaW5lZCB8PSBGQUNFVF9NSU5MRU5HVEg7Ci0gICAgICAgICAgICAgICAgaWYgKChmaXhlZEZhY2V0ICYgRkFDRVRfTUlOTEVOR1RIKSAhPSAwKQotICAgICAgICAgICAgICAgICAgICBmRml4ZWRGYWNldCB8PSBGQUNFVF9NSU5MRU5HVEg7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgLy8gbWF4TGVuZ3RoCi0gICAgICAgIGlmICgocHJlc2VudEZhY2V0ICYgRkFDRVRfTUFYTEVOR1RIKSAhPSAwKSB7Ci0gICAgICAgICAgICBpZiAoKGFsbG93ZWRGYWNldCAmIEZBQ0VUX01BWExFTkdUSCkgPT0gMCkgewotICAgICAgICAgICAgICAgIHJlcG9ydEVycm9yKCJjb3MtYXBwbGljYWJsZS1mYWNldHMiLCBuZXcgT2JqZWN0W117Im1heExlbmd0aCIsIGZUeXBlTmFtZX0pOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBmTWF4TGVuZ3RoID0gZmFjZXRzLm1heExlbmd0aDsKLSAgICAgICAgICAgICAgICBtYXhMZW5ndGhBbm5vdGF0aW9uID0gZmFjZXRzLm1heExlbmd0aEFubm90YXRpb247Ci0gICAgICAgICAgICAgICAgZkZhY2V0c0RlZmluZWQgfD0gRkFDRVRfTUFYTEVOR1RIOwotICAgICAgICAgICAgICAgIGlmICgoZml4ZWRGYWNldCAmIEZBQ0VUX01BWExFTkdUSCkgIT0gMCkKLSAgICAgICAgICAgICAgICAgICAgZkZpeGVkRmFjZXQgfD0gRkFDRVRfTUFYTEVOR1RIOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIC8vIHBhdHRlcm4KLSAgICAgICAgaWYgKChwcmVzZW50RmFjZXQgJiBGQUNFVF9QQVRURVJOKSAhPSAwKSB7Ci0gICAgICAgICAgICBpZiAoKGFsbG93ZWRGYWNldCAmIEZBQ0VUX1BBVFRFUk4pID09IDApIHsKLSAgICAgICAgICAgICAgICByZXBvcnRFcnJvcigiY29zLWFwcGxpY2FibGUtZmFjZXRzIiwgbmV3IE9iamVjdFtdeyJwYXR0ZXJuIiwgZlR5cGVOYW1lfSk7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIHBhdHRlcm5Bbm5vdGF0aW9ucyA9IGZhY2V0cy5wYXR0ZXJuQW5ub3RhdGlvbnM7Ci0gICAgICAgICAgICAgICAgUmVndWxhckV4cHJlc3Npb24gcmVnZXggPSBudWxsOwotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgIHJlZ2V4ID0gbmV3IFJlZ3VsYXJFeHByZXNzaW9uKGZhY2V0cy5wYXR0ZXJuLCAiWCIsIGNvbnRleHQuZ2V0TG9jYWxlKCkpOwotICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJlcG9ydEVycm9yKCJJbnZhbGlkUmVnZXgiLCBuZXcgT2JqZWN0W117ZmFjZXRzLnBhdHRlcm4sIGUuZ2V0TG9jYWxpemVkTWVzc2FnZSgpfSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGlmIChyZWdleCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZQYXR0ZXJuID0gbmV3IFZlY3RvcigpOwotICAgICAgICAgICAgICAgICAgICBmUGF0dGVybi5hZGRFbGVtZW50KHJlZ2V4KTsKLSAgICAgICAgICAgICAgICAgICAgZlBhdHRlcm5TdHIgPSBuZXcgVmVjdG9yKCk7Ci0gICAgICAgICAgICAgICAgICAgIGZQYXR0ZXJuU3RyLmFkZEVsZW1lbnQoZmFjZXRzLnBhdHRlcm4pOwotICAgICAgICAgICAgICAgICAgICBmRmFjZXRzRGVmaW5lZCB8PSBGQUNFVF9QQVRURVJOOwotICAgICAgICAgICAgICAgICAgICBpZiAoKGZpeGVkRmFjZXQgJiBGQUNFVF9QQVRURVJOKSAhPSAwKQotICAgICAgICAgICAgICAgICAgICAgICAgZkZpeGVkRmFjZXQgfD0gRkFDRVRfUEFUVEVSTjsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyB3aGl0ZVNwYWNlCi0gICAgICAgIGlmICgocHJlc2VudEZhY2V0ICYgRkFDRVRfV0hJVEVTUEFDRSkgIT0gMCkgewotICAgICAgICAgICAgaWYgKChhbGxvd2VkRmFjZXQgJiBGQUNFVF9XSElURVNQQUNFKSA9PSAwKSB7Ci0gICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoImNvcy1hcHBsaWNhYmxlLWZhY2V0cyIsIG5ldyBPYmplY3RbXXsid2hpdGVTcGFjZSIsIGZUeXBlTmFtZX0pOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBmV2hpdGVTcGFjZSA9IGZhY2V0cy53aGl0ZVNwYWNlOwotICAgICAgICAgICAgICAgIHdoaXRlU3BhY2VBbm5vdGF0aW9uID0gZmFjZXRzLndoaXRlU3BhY2VBbm5vdGF0aW9uOwotICAgICAgICAgICAgICAgIGZGYWNldHNEZWZpbmVkIHw9IEZBQ0VUX1dISVRFU1BBQ0U7Ci0gICAgICAgICAgICAgICAgaWYgKChmaXhlZEZhY2V0ICYgRkFDRVRfV0hJVEVTUEFDRSkgIT0gMCkKLSAgICAgICAgICAgICAgICAgICAgZkZpeGVkRmFjZXQgfD0gRkFDRVRfV0hJVEVTUEFDRTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICAvLyBlbnVtZXJhdGlvbgotICAgICAgICBpZiAoKHByZXNlbnRGYWNldCAmIEZBQ0VUX0VOVU1FUkFUSU9OKSAhPSAwKSB7Ci0gICAgICAgICAgICBpZiAoKGFsbG93ZWRGYWNldCAmIEZBQ0VUX0VOVU1FUkFUSU9OKSA9PSAwKSB7Ci0gICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoImNvcy1hcHBsaWNhYmxlLWZhY2V0cyIsIG5ldyBPYmplY3RbXXsiZW51bWVyYXRpb24iLCBmVHlwZU5hbWV9KTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgZkVudW1lcmF0aW9uID0gbmV3IFZlY3RvcigpOwotICAgICAgICAgICAgICAgIFZlY3RvciBlbnVtVmFscyA9IGZhY2V0cy5lbnVtZXJhdGlvbjsKLSAgICAgICAgICAgICAgICBmRW51bWVyYXRpb25UeXBlID0gbmV3IHNob3J0W2VudW1WYWxzLnNpemUoKV07Ci0gICAgICAgICAgICAgICAgZkVudW1lcmF0aW9uSXRlbVR5cGUgPSBuZXcgU2hvcnRMaXN0W2VudW1WYWxzLnNpemUoKV07Ci0gICAgICAgICAgICAgICAgVmVjdG9yIGVudW1OU0RlY2xzID0gZmFjZXRzLmVudW1OU0RlY2xzOwotICAgICAgICAgICAgICAgIFZhbGlkYXRpb25Db250ZXh0SW1wbCBjdHggPSBuZXcgVmFsaWRhdGlvbkNvbnRleHRJbXBsKGNvbnRleHQpOwotICAgICAgICAgICAgICAgIGVudW1lcmF0aW9uQW5ub3RhdGlvbnMgPSBmYWNldHMuZW51bUFubm90YXRpb25zOwotICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZW51bVZhbHMuc2l6ZSgpOyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGVudW1OU0RlY2xzICE9IG51bGwpCi0gICAgICAgICAgICAgICAgICAgICAgICBjdHguc2V0TlNDb250ZXh0KChOYW1lc3BhY2VDb250ZXh0KWVudW1OU0RlY2xzLmVsZW1lbnRBdChpKSk7Ci0gICAgICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBWYWxpZGF0ZWRJbmZvIGluZm8gPSBnZXRBY3R1YWxFbnVtVmFsdWUoKFN0cmluZyllbnVtVmFscy5lbGVtZW50QXQoaSksIGN0eCwgdGVtcEluZm8pOwotICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2hlY2sgNC4zLjUuYzAgbXVzdDogZW51bWVyYXRpb24gdmFsdWVzIGZyb20gdGhlIHZhbHVlIHNwYWNlIG9mIGJhc2UKLSAgICAgICAgICAgICAgICAgICAgICAgIGZFbnVtZXJhdGlvbi5hZGRFbGVtZW50KGluZm8uYWN0dWFsVmFsdWUpOwotICAgICAgICAgICAgICAgICAgICAgICAgZkVudW1lcmF0aW9uVHlwZVtpXSA9IGluZm8uYWN0dWFsVmFsdWVUeXBlOwotICAgICAgICAgICAgICAgICAgICAgICAgZkVudW1lcmF0aW9uSXRlbVR5cGVbaV0gPSBpbmZvLml0ZW1WYWx1ZVR5cGVzOwotICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbiBpZGUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydEVycm9yKCJlbnVtZXJhdGlvbi12YWxpZC1yZXN0cmljdGlvbiIsIG5ldyBPYmplY3RbXXtlbnVtVmFscy5lbGVtZW50QXQoaSksIHRoaXMuZ2V0QmFzZVR5cGUoKS5nZXROYW1lKCl9KTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBmRmFjZXRzRGVmaW5lZCB8PSBGQUNFVF9FTlVNRVJBVElPTjsKLSAgICAgICAgICAgICAgICBpZiAoKGZpeGVkRmFjZXQgJiBGQUNFVF9FTlVNRVJBVElPTikgIT0gMCkKLSAgICAgICAgICAgICAgICAgICAgZkZpeGVkRmFjZXQgfD0gRkFDRVRfRU5VTUVSQVRJT047Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBtYXhJbmNsdXNpdmUKLSAgICAgICAgaWYgKChwcmVzZW50RmFjZXQgJiBGQUNFVF9NQVhJTkNMVVNJVkUpICE9IDApIHsKLSAgICAgICAgICAgIGlmICgoYWxsb3dlZEZhY2V0ICYgRkFDRVRfTUFYSU5DTFVTSVZFKSA9PSAwKSB7Ci0gICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoImNvcy1hcHBsaWNhYmxlLWZhY2V0cyIsIG5ldyBPYmplY3RbXXsibWF4SW5jbHVzaXZlIiwgZlR5cGVOYW1lfSk7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIG1heEluY2x1c2l2ZUFubm90YXRpb24gPSBmYWNldHMubWF4SW5jbHVzaXZlQW5ub3RhdGlvbjsKLSAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICBmTWF4SW5jbHVzaXZlID0gZkJhc2UuZ2V0QWN0dWFsVmFsdWUoZmFjZXRzLm1heEluY2x1c2l2ZSwgY29udGV4dCwgdGVtcEluZm8sIHRydWUpOwotICAgICAgICAgICAgICAgICAgICBmRmFjZXRzRGVmaW5lZCB8PSBGQUNFVF9NQVhJTkNMVVNJVkU7Ci0gICAgICAgICAgICAgICAgICAgIGlmICgoZml4ZWRGYWNldCAmIEZBQ0VUX01BWElOQ0xVU0lWRSkgIT0gMCkKLSAgICAgICAgICAgICAgICAgICAgICAgIGZGaXhlZEZhY2V0IHw9IEZBQ0VUX01BWElOQ0xVU0lWRTsKLSAgICAgICAgICAgICAgICB9IGNhdGNoIChJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbiBpZGUpIHsKLSAgICAgICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoaWRlLmdldEtleSgpLCBpZGUuZ2V0QXJncygpKTsKLSAgICAgICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoIkZhY2V0VmFsdWVGcm9tQmFzZSIsIG5ldyBPYmplY3RbXXtmVHlwZU5hbWUsIGZhY2V0cy5tYXhJbmNsdXNpdmUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIm1heEluY2x1c2l2ZSIsIGZCYXNlLmdldE5hbWUoKX0pOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8vIGNoZWNrIGFnYWluc3QgZml4ZWQgdmFsdWUgaW4gYmFzZQotICAgICAgICAgICAgICAgIGlmICgoKGZCYXNlLmZGYWNldHNEZWZpbmVkICYgRkFDRVRfTUFYSU5DTFVTSVZFKSAhPSAwKSkgewotICAgICAgICAgICAgICAgICAgICBpZiAoKGZCYXNlLmZGaXhlZEZhY2V0ICYgRkFDRVRfTUFYSU5DTFVTSVZFKSAhPSAwKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZkRWc1tmVmFsaWRhdGlvbkRWXS5jb21wYXJlKGZNYXhJbmNsdXNpdmUsIGZCYXNlLmZNYXhJbmNsdXNpdmUpICE9IDApCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoICJGaXhlZEZhY2V0VmFsdWUiLCBuZXcgT2JqZWN0W117Im1heEluY2x1c2l2ZSIsIGZNYXhJbmNsdXNpdmUsIGZCYXNlLmZNYXhJbmNsdXNpdmUsIGZUeXBlTmFtZX0pOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIC8vIG1heEluY2x1c2l2ZSBmcm9tIGJhc2UKLSAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICBmQmFzZS52YWxpZGF0ZShjb250ZXh0LCB0ZW1wSW5mbyk7Ci0gICAgICAgICAgICAgICAgfSBjYXRjaCAoSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24gaWRlKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJlcG9ydEVycm9yKGlkZS5nZXRLZXkoKSwgaWRlLmdldEFyZ3MoKSk7Ci0gICAgICAgICAgICAgICAgICAgIHJlcG9ydEVycm9yKCJGYWNldFZhbHVlRnJvbUJhc2UiLCBuZXcgT2JqZWN0W117ZlR5cGVOYW1lLCBmYWNldHMubWF4SW5jbHVzaXZlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICJtYXhJbmNsdXNpdmUiLCBmQmFzZS5nZXROYW1lKCl9KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBtYXhFeGNsdXNpdmUKLSAgICAgICAgYm9vbGVhbiBuZWVkQ2hlY2tCYXNlID0gdHJ1ZTsKLSAgICAgICAgaWYgKChwcmVzZW50RmFjZXQgJiBGQUNFVF9NQVhFWENMVVNJVkUpICE9IDApIHsKLSAgICAgICAgICAgIGlmICgoYWxsb3dlZEZhY2V0ICYgRkFDRVRfTUFYRVhDTFVTSVZFKSA9PSAwKSB7Ci0gICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoImNvcy1hcHBsaWNhYmxlLWZhY2V0cyIsIG5ldyBPYmplY3RbXXsibWF4RXhjbHVzaXZlIiwgZlR5cGVOYW1lfSk7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIG1heEV4Y2x1c2l2ZUFubm90YXRpb24gPSBmYWNldHMubWF4RXhjbHVzaXZlQW5ub3RhdGlvbjsKLSAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICBmTWF4RXhjbHVzaXZlID0gZkJhc2UuZ2V0QWN0dWFsVmFsdWUoZmFjZXRzLm1heEV4Y2x1c2l2ZSwgY29udGV4dCwgdGVtcEluZm8sIHRydWUpOwotICAgICAgICAgICAgICAgICAgICBmRmFjZXRzRGVmaW5lZCB8PSBGQUNFVF9NQVhFWENMVVNJVkU7Ci0gICAgICAgICAgICAgICAgICAgIGlmICgoZml4ZWRGYWNldCAmIEZBQ0VUX01BWEVYQ0xVU0lWRSkgIT0gMCkKLSAgICAgICAgICAgICAgICAgICAgICAgIGZGaXhlZEZhY2V0IHw9IEZBQ0VUX01BWEVYQ0xVU0lWRTsKLSAgICAgICAgICAgICAgICB9IGNhdGNoIChJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbiBpZGUpIHsKLSAgICAgICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoaWRlLmdldEtleSgpLCBpZGUuZ2V0QXJncygpKTsKLSAgICAgICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoIkZhY2V0VmFsdWVGcm9tQmFzZSIsIG5ldyBPYmplY3RbXXtmVHlwZU5hbWUsIGZhY2V0cy5tYXhFeGNsdXNpdmUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIm1heEV4Y2x1c2l2ZSIsIGZCYXNlLmdldE5hbWUoKX0pOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8vIGNoZWNrIGFnYWluc3QgZml4ZWQgdmFsdWUgaW4gYmFzZQotICAgICAgICAgICAgICAgIGlmICgoKGZCYXNlLmZGYWNldHNEZWZpbmVkICYgRkFDRVRfTUFYRVhDTFVTSVZFKSAhPSAwKSkgewotICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBmRFZzW2ZWYWxpZGF0aW9uRFZdLmNvbXBhcmUoZk1heEV4Y2x1c2l2ZSwgZkJhc2UuZk1heEV4Y2x1c2l2ZSk7Ci0gICAgICAgICAgICAgICAgICAgIGlmICgoZkJhc2UuZkZpeGVkRmFjZXQgJiBGQUNFVF9NQVhFWENMVVNJVkUpICE9IDAgJiYgcmVzdWx0ICE9IDApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydEVycm9yKCAiRml4ZWRGYWNldFZhbHVlIiwgbmV3IE9iamVjdFtdeyJtYXhFeGNsdXNpdmUiLCBmYWNldHMubWF4RXhjbHVzaXZlLCBmQmFzZS5mTWF4RXhjbHVzaXZlLCBmVHlwZU5hbWV9KTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBpZiAocmVzdWx0ID09IDApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIG5lZWRDaGVja0Jhc2UgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvLyBtYXhFeGNsdXNpdmUgZnJvbSBiYXNlCi0gICAgICAgICAgICAgICAgaWYgKG5lZWRDaGVja0Jhc2UpIHsKLSAgICAgICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZCYXNlLnZhbGlkYXRlKGNvbnRleHQsIHRlbXBJbmZvKTsKLSAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24gaWRlKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRFcnJvcihpZGUuZ2V0S2V5KCksIGlkZS5nZXRBcmdzKCkpOwotICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoIkZhY2V0VmFsdWVGcm9tQmFzZSIsIG5ldyBPYmplY3RbXXtmVHlwZU5hbWUsIGZhY2V0cy5tYXhFeGNsdXNpdmUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJtYXhFeGNsdXNpdmUiLCBmQmFzZS5nZXROYW1lKCl9KTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvLyBJZiBtYXhFeGNsdXNpdmUgPT0gYmFzZS5tYXhFeGNsdXNpdmUsIHRoZW4gd2Ugb25seSBuZWVkIHRvIGNoZWNrCi0gICAgICAgICAgICAgICAgLy8gbWF4RXhjbHVzaXZlIDw9IGJhc2UubWF4SW5jbHVzaXZlCi0gICAgICAgICAgICAgICAgZWxzZSBpZiAoKChmQmFzZS5mRmFjZXRzRGVmaW5lZCAmIEZBQ0VUX01BWElOQ0xVU0lWRSkgIT0gMCkpIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGZEVnNbZlZhbGlkYXRpb25EVl0uY29tcGFyZShmTWF4RXhjbHVzaXZlLCBmQmFzZS5mTWF4SW5jbHVzaXZlKSA+IDApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydEVycm9yKCAibWF4RXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjIiLCBuZXcgT2JqZWN0W117ZmFjZXRzLm1heEV4Y2x1c2l2ZSwgZkJhc2UuZk1heEluY2x1c2l2ZX0pOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIC8vIG1pbkV4Y2x1c2l2ZQotICAgICAgICBuZWVkQ2hlY2tCYXNlID0gdHJ1ZTsKLSAgICAgICAgaWYgKChwcmVzZW50RmFjZXQgJiBGQUNFVF9NSU5FWENMVVNJVkUpICE9IDApIHsKLSAgICAgICAgICAgIGlmICgoYWxsb3dlZEZhY2V0ICYgRkFDRVRfTUlORVhDTFVTSVZFKSA9PSAwKSB7Ci0gICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoImNvcy1hcHBsaWNhYmxlLWZhY2V0cyIsIG5ldyBPYmplY3RbXXsibWluRXhjbHVzaXZlIiwgZlR5cGVOYW1lfSk7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIG1pbkV4Y2x1c2l2ZUFubm90YXRpb24gPSBmYWNldHMubWluRXhjbHVzaXZlQW5ub3RhdGlvbjsKLSAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICBmTWluRXhjbHVzaXZlID0gZkJhc2UuZ2V0QWN0dWFsVmFsdWUoZmFjZXRzLm1pbkV4Y2x1c2l2ZSwgY29udGV4dCwgdGVtcEluZm8sIHRydWUpOwotICAgICAgICAgICAgICAgICAgICBmRmFjZXRzRGVmaW5lZCB8PSBGQUNFVF9NSU5FWENMVVNJVkU7Ci0gICAgICAgICAgICAgICAgICAgIGlmICgoZml4ZWRGYWNldCAmIEZBQ0VUX01JTkVYQ0xVU0lWRSkgIT0gMCkKLSAgICAgICAgICAgICAgICAgICAgICAgIGZGaXhlZEZhY2V0IHw9IEZBQ0VUX01JTkVYQ0xVU0lWRTsKLSAgICAgICAgICAgICAgICB9IGNhdGNoIChJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbiBpZGUpIHsKLSAgICAgICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoaWRlLmdldEtleSgpLCBpZGUuZ2V0QXJncygpKTsKLSAgICAgICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoIkZhY2V0VmFsdWVGcm9tQmFzZSIsIG5ldyBPYmplY3RbXXtmVHlwZU5hbWUsIGZhY2V0cy5taW5FeGNsdXNpdmUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIm1pbkV4Y2x1c2l2ZSIsIGZCYXNlLmdldE5hbWUoKX0pOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8vIGNoZWNrIGFnYWluc3QgZml4ZWQgdmFsdWUgaW4gYmFzZQotICAgICAgICAgICAgICAgIGlmICgoKGZCYXNlLmZGYWNldHNEZWZpbmVkICYgRkFDRVRfTUlORVhDTFVTSVZFKSAhPSAwKSkgewotICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBmRFZzW2ZWYWxpZGF0aW9uRFZdLmNvbXBhcmUoZk1pbkV4Y2x1c2l2ZSwgZkJhc2UuZk1pbkV4Y2x1c2l2ZSk7Ci0gICAgICAgICAgICAgICAgICAgIGlmICgoZkJhc2UuZkZpeGVkRmFjZXQgJiBGQUNFVF9NSU5FWENMVVNJVkUpICE9IDAgJiYgcmVzdWx0ICE9IDApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydEVycm9yKCAiRml4ZWRGYWNldFZhbHVlIiwgbmV3IE9iamVjdFtdeyJtaW5FeGNsdXNpdmUiLCBmYWNldHMubWluRXhjbHVzaXZlLCBmQmFzZS5mTWluRXhjbHVzaXZlLCBmVHlwZU5hbWV9KTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBpZiAocmVzdWx0ID09IDApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIG5lZWRDaGVja0Jhc2UgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvLyBtaW5FeGNsdXNpdmUgZnJvbSBiYXNlCi0gICAgICAgICAgICAgICAgaWYgKG5lZWRDaGVja0Jhc2UpIHsKLSAgICAgICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZCYXNlLnZhbGlkYXRlKGNvbnRleHQsIHRlbXBJbmZvKTsKLSAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24gaWRlKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRFcnJvcihpZGUuZ2V0S2V5KCksIGlkZS5nZXRBcmdzKCkpOwotICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoIkZhY2V0VmFsdWVGcm9tQmFzZSIsIG5ldyBPYmplY3RbXXtmVHlwZU5hbWUsIGZhY2V0cy5taW5FeGNsdXNpdmUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJtaW5FeGNsdXNpdmUiLCBmQmFzZS5nZXROYW1lKCl9KTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvLyBJZiBtaW5FeGNsdXNpdmUgPT0gYmFzZS5taW5FeGNsdXNpdmUsIHRoZW4gd2Ugb25seSBuZWVkIHRvIGNoZWNrCi0gICAgICAgICAgICAgICAgLy8gbWluRXhjbHVzaXZlID49IGJhc2UubWluSW5jbHVzaXZlCi0gICAgICAgICAgICAgICAgZWxzZSBpZiAoKChmQmFzZS5mRmFjZXRzRGVmaW5lZCAmIEZBQ0VUX01JTklOQ0xVU0lWRSkgIT0gMCkpIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGZEVnNbZlZhbGlkYXRpb25EVl0uY29tcGFyZShmTWluRXhjbHVzaXZlLCBmQmFzZS5mTWluSW5jbHVzaXZlKSA8IDApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydEVycm9yKCAibWluRXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjMiLCBuZXcgT2JqZWN0W117ZmFjZXRzLm1pbkV4Y2x1c2l2ZSwgZkJhc2UuZk1pbkluY2x1c2l2ZX0pOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIC8vIG1pbkluY2x1c2l2ZQotICAgICAgICBpZiAoKHByZXNlbnRGYWNldCAmIEZBQ0VUX01JTklOQ0xVU0lWRSkgIT0gMCkgewotICAgICAgICAgICAgaWYgKChhbGxvd2VkRmFjZXQgJiBGQUNFVF9NSU5JTkNMVVNJVkUpID09IDApIHsKLSAgICAgICAgICAgICAgICByZXBvcnRFcnJvcigiY29zLWFwcGxpY2FibGUtZmFjZXRzIiwgbmV3IE9iamVjdFtdeyJtaW5JbmNsdXNpdmUiLCBmVHlwZU5hbWV9KTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgbWluSW5jbHVzaXZlQW5ub3RhdGlvbiA9IGZhY2V0cy5taW5JbmNsdXNpdmVBbm5vdGF0aW9uOwotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgIGZNaW5JbmNsdXNpdmUgPSBmQmFzZS5nZXRBY3R1YWxWYWx1ZShmYWNldHMubWluSW5jbHVzaXZlLCBjb250ZXh0LCB0ZW1wSW5mbywgdHJ1ZSk7Ci0gICAgICAgICAgICAgICAgICAgIGZGYWNldHNEZWZpbmVkIHw9IEZBQ0VUX01JTklOQ0xVU0lWRTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKChmaXhlZEZhY2V0ICYgRkFDRVRfTUlOSU5DTFVTSVZFKSAhPSAwKQotICAgICAgICAgICAgICAgICAgICAgICAgZkZpeGVkRmFjZXQgfD0gRkFDRVRfTUlOSU5DTFVTSVZFOwotICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uIGlkZSkgewotICAgICAgICAgICAgICAgICAgICByZXBvcnRFcnJvcihpZGUuZ2V0S2V5KCksIGlkZS5nZXRBcmdzKCkpOwotICAgICAgICAgICAgICAgICAgICByZXBvcnRFcnJvcigiRmFjZXRWYWx1ZUZyb21CYXNlIiwgbmV3IE9iamVjdFtde2ZUeXBlTmFtZSwgZmFjZXRzLm1pbkluY2x1c2l2ZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAibWluSW5jbHVzaXZlIiwgZkJhc2UuZ2V0TmFtZSgpfSk7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgLy8gY2hlY2sgYWdhaW5zdCBmaXhlZCB2YWx1ZSBpbiBiYXNlCi0gICAgICAgICAgICAgICAgaWYgKCgoZkJhc2UuZkZhY2V0c0RlZmluZWQgJiBGQUNFVF9NSU5JTkNMVVNJVkUpICE9IDApKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmICgoZkJhc2UuZkZpeGVkRmFjZXQgJiBGQUNFVF9NSU5JTkNMVVNJVkUpICE9IDApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmRFZzW2ZWYWxpZGF0aW9uRFZdLmNvbXBhcmUoZk1pbkluY2x1c2l2ZSwgZkJhc2UuZk1pbkluY2x1c2l2ZSkgIT0gMCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRFcnJvciggIkZpeGVkRmFjZXRWYWx1ZSIsIG5ldyBPYmplY3RbXXsibWluSW5jbHVzaXZlIiwgZmFjZXRzLm1pbkluY2x1c2l2ZSwgZkJhc2UuZk1pbkluY2x1c2l2ZSwgZlR5cGVOYW1lfSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLy8gbWluSW5jbHVzaXZlIGZyb20gYmFzZQotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgIGZCYXNlLnZhbGlkYXRlKGNvbnRleHQsIHRlbXBJbmZvKTsKLSAgICAgICAgICAgICAgICB9IGNhdGNoIChJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbiBpZGUpIHsKLSAgICAgICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoaWRlLmdldEtleSgpLCBpZGUuZ2V0QXJncygpKTsKLSAgICAgICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoIkZhY2V0VmFsdWVGcm9tQmFzZSIsIG5ldyBPYmplY3RbXXtmVHlwZU5hbWUsIGZhY2V0cy5taW5JbmNsdXNpdmUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIm1pbkluY2x1c2l2ZSIsIGZCYXNlLmdldE5hbWUoKX0pOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIHRvdGFsRGlnaXRzCi0gICAgICAgIGlmICgocHJlc2VudEZhY2V0ICYgRkFDRVRfVE9UQUxESUdJVFMpICE9IDApIHsKLSAgICAgICAgICAgIGlmICgoYWxsb3dlZEZhY2V0ICYgRkFDRVRfVE9UQUxESUdJVFMpID09IDApIHsKLSAgICAgICAgICAgICAgICByZXBvcnRFcnJvcigiY29zLWFwcGxpY2FibGUtZmFjZXRzIiwgbmV3IE9iamVjdFtdeyJ0b3RhbERpZ2l0cyIsIGZUeXBlTmFtZX0pOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICB0b3RhbERpZ2l0c0Fubm90YXRpb24gPSBmYWNldHMudG90YWxEaWdpdHNBbm5vdGF0aW9uOwotICAgICAgICAgICAgICAgIGZUb3RhbERpZ2l0cyA9IGZhY2V0cy50b3RhbERpZ2l0czsKLSAgICAgICAgICAgICAgICBmRmFjZXRzRGVmaW5lZCB8PSBGQUNFVF9UT1RBTERJR0lUUzsKLSAgICAgICAgICAgICAgICBpZiAoKGZpeGVkRmFjZXQgJiBGQUNFVF9UT1RBTERJR0lUUykgIT0gMCkKLSAgICAgICAgICAgICAgICAgICAgZkZpeGVkRmFjZXQgfD0gRkFDRVRfVE9UQUxESUdJVFM7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgLy8gZnJhY3Rpb25EaWdpdHMKLSAgICAgICAgaWYgKChwcmVzZW50RmFjZXQgJiBGQUNFVF9GUkFDVElPTkRJR0lUUykgIT0gMCkgewotICAgICAgICAgICAgaWYgKChhbGxvd2VkRmFjZXQgJiBGQUNFVF9GUkFDVElPTkRJR0lUUykgPT0gMCkgewotICAgICAgICAgICAgICAgIHJlcG9ydEVycm9yKCJjb3MtYXBwbGljYWJsZS1mYWNldHMiLCBuZXcgT2JqZWN0W117ImZyYWN0aW9uRGlnaXRzIiwgZlR5cGVOYW1lfSk7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIGZGcmFjdGlvbkRpZ2l0cyA9IGZhY2V0cy5mcmFjdGlvbkRpZ2l0czsKLSAgICAgICAgICAgICAgICBmcmFjdGlvbkRpZ2l0c0Fubm90YXRpb24gPSBmYWNldHMuZnJhY3Rpb25EaWdpdHNBbm5vdGF0aW9uOwotICAgICAgICAgICAgICAgIGZGYWNldHNEZWZpbmVkIHw9IEZBQ0VUX0ZSQUNUSU9ORElHSVRTOwotICAgICAgICAgICAgICAgIGlmICgoZml4ZWRGYWNldCAmIEZBQ0VUX0ZSQUNUSU9ORElHSVRTKSAhPSAwKQotICAgICAgICAgICAgICAgICAgICBmRml4ZWRGYWNldCB8PSBGQUNFVF9GUkFDVElPTkRJR0lUUzsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIHRva2VuIHR5cGU6IGludGVybmFsIHVzZSwgc28gZG8gbGVzcyBjaGVja2luZwotICAgICAgICBpZiAocGF0dGVyblR5cGUgIT0gU1BFQ0lBTF9QQVRURVJOX05PTkUpIHsKLSAgICAgICAgICAgIGZQYXR0ZXJuVHlwZSA9IHBhdHRlcm5UeXBlOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gc3RlcCAyOiBjaGVjayBmYWNldHMgYWdhaW5zdCBlYWNoIG90aGVyOiBsZW5ndGgsIGJvdW5kcwotICAgICAgICBpZihmRmFjZXRzRGVmaW5lZCAhPSAwKSB7Ci0KLSAgICAgICAgICAgIC8vIGNoZWNrIDQuMy4yLmMxIG11c3Q6IG1pbkxlbmd0aCA8PSBtYXhMZW5ndGgKLSAgICAgICAgICAgIGlmKCgoZkZhY2V0c0RlZmluZWQgJiBGQUNFVF9NSU5MRU5HVEggKSAhPSAwICkgJiYgKChmRmFjZXRzRGVmaW5lZCAmIEZBQ0VUX01BWExFTkdUSCkgIT0gMCkpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgaWYoZk1pbkxlbmd0aCA+IGZNYXhMZW5ndGgpCi0gICAgICAgICAgICAgICAgICAgIHJlcG9ydEVycm9yKCJtaW5MZW5ndGgtbGVzcy10aGFuLWVxdWFsLXRvLW1heExlbmd0aCIsIG5ldyBPYmplY3RbXXtJbnRlZ2VyLnRvU3RyaW5nKGZNaW5MZW5ndGgpLCBJbnRlZ2VyLnRvU3RyaW5nKGZNYXhMZW5ndGgpLCBmVHlwZU5hbWV9KTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gY2hlY2sgNC4zLjguYzEgZXJyb3I6IG1heEluY2x1c2l2ZSArIG1heEV4Y2x1c2l2ZQotICAgICAgICAgICAgaWYgKCgoZkZhY2V0c0RlZmluZWQgJiBGQUNFVF9NQVhFWENMVVNJVkUpICE9IDApICYmICgoZkZhY2V0c0RlZmluZWQgJiBGQUNFVF9NQVhJTkNMVVNJVkUpICE9IDApKSB7Ci0gICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoICJtYXhJbmNsdXNpdmUtbWF4RXhjbHVzaXZlIiwgbmV3IE9iamVjdFtde2ZNYXhJbmNsdXNpdmUsIGZNYXhFeGNsdXNpdmUsIGZUeXBlTmFtZX0pOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBjaGVjayA0LjMuOS5jMSBlcnJvcjogbWluSW5jbHVzaXZlICsgbWluRXhjbHVzaXZlCi0gICAgICAgICAgICBpZiAoKChmRmFjZXRzRGVmaW5lZCAmIEZBQ0VUX01JTkVYQ0xVU0lWRSkgIT0gMCkgJiYgKChmRmFjZXRzRGVmaW5lZCAmIEZBQ0VUX01JTklOQ0xVU0lWRSkgIT0gMCkpIHsKLSAgICAgICAgICAgICAgICByZXBvcnRFcnJvcigibWluSW5jbHVzaXZlLW1pbkV4Y2x1c2l2ZSIsIG5ldyBPYmplY3RbXXtmTWluSW5jbHVzaXZlLCBmTWluRXhjbHVzaXZlLCBmVHlwZU5hbWV9KTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gY2hlY2sgNC4zLjcuYzEgbXVzdDogbWluSW5jbHVzaXZlIDw9IG1heEluY2x1c2l2ZQotICAgICAgICAgICAgaWYgKCgoZkZhY2V0c0RlZmluZWQgJiAgRkFDRVRfTUFYSU5DTFVTSVZFKSAhPSAwKSAmJiAoKGZGYWNldHNEZWZpbmVkICYgRkFDRVRfTUlOSU5DTFVTSVZFKSAhPSAwKSkgewotICAgICAgICAgICAgICAgIHJlc3VsdCA9IGZEVnNbZlZhbGlkYXRpb25EVl0uY29tcGFyZShmTWluSW5jbHVzaXZlLCBmTWF4SW5jbHVzaXZlKTsKLSAgICAgICAgICAgICAgICBpZiAocmVzdWx0ICE9IC0xICYmIHJlc3VsdCAhPSAwKQotICAgICAgICAgICAgICAgICAgICByZXBvcnRFcnJvcigibWluSW5jbHVzaXZlLWxlc3MtdGhhbi1lcXVhbC10by1tYXhJbmNsdXNpdmUiLCBuZXcgT2JqZWN0W117Zk1pbkluY2x1c2l2ZSwgZk1heEluY2x1c2l2ZSwgZlR5cGVOYW1lfSk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIGNoZWNrIDQuMy44LmMyIG11c3Q6IG1pbkV4Y2x1c2l2ZSA8PSBtYXhFeGNsdXNpdmUgPz8/IG1pbkV4Y2x1c2l2ZSA8IG1heEV4Y2x1c2l2ZQotICAgICAgICAgICAgaWYgKCgoZkZhY2V0c0RlZmluZWQgJiBGQUNFVF9NQVhFWENMVVNJVkUpICE9IDApICYmICgoZkZhY2V0c0RlZmluZWQgJiBGQUNFVF9NSU5FWENMVVNJVkUpICE9IDApKSB7Ci0gICAgICAgICAgICAgICAgcmVzdWx0ID0gZkRWc1tmVmFsaWRhdGlvbkRWXS5jb21wYXJlKGZNaW5FeGNsdXNpdmUsIGZNYXhFeGNsdXNpdmUpOwotICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgIT0gLTEgJiYgcmVzdWx0ICE9IDApCi0gICAgICAgICAgICAgICAgICAgIHJlcG9ydEVycm9yKCAibWluRXhjbHVzaXZlLWxlc3MtdGhhbi1lcXVhbC10by1tYXhFeGNsdXNpdmUiLCBuZXcgT2JqZWN0W117Zk1pbkV4Y2x1c2l2ZSwgZk1heEV4Y2x1c2l2ZSwgZlR5cGVOYW1lfSk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIGNoZWNrIDQuMy45LmMyIG11c3Q6IG1pbkV4Y2x1c2l2ZSA8IG1heEluY2x1c2l2ZQotICAgICAgICAgICAgaWYgKCgoZkZhY2V0c0RlZmluZWQgJiBGQUNFVF9NQVhJTkNMVVNJVkUpICE9IDApICYmICgoZkZhY2V0c0RlZmluZWQgJiBGQUNFVF9NSU5FWENMVVNJVkUpICE9IDApKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGZEVnNbZlZhbGlkYXRpb25EVl0uY29tcGFyZShmTWluRXhjbHVzaXZlLCBmTWF4SW5jbHVzaXZlKSAhPSAtMSkKLSAgICAgICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoICJtaW5FeGNsdXNpdmUtbGVzcy10aGFuLW1heEluY2x1c2l2ZSIsIG5ldyBPYmplY3RbXXtmTWluRXhjbHVzaXZlLCBmTWF4SW5jbHVzaXZlLCBmVHlwZU5hbWV9KTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gY2hlY2sgNC4zLjEwLmMxIG11c3Q6IG1pbkluY2x1c2l2ZSA8IG1heEV4Y2x1c2l2ZQotICAgICAgICAgICAgaWYgKCgoZkZhY2V0c0RlZmluZWQgJiBGQUNFVF9NQVhFWENMVVNJVkUpICE9IDApICYmICgoZkZhY2V0c0RlZmluZWQgJiBGQUNFVF9NSU5JTkNMVVNJVkUpICE9IDApKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGZEVnNbZlZhbGlkYXRpb25EVl0uY29tcGFyZShmTWluSW5jbHVzaXZlLCBmTWF4RXhjbHVzaXZlKSAhPSAtMSkKLSAgICAgICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoICJtaW5JbmNsdXNpdmUtbGVzcy10aGFuLW1heEV4Y2x1c2l2ZSIsIG5ldyBPYmplY3RbXXtmTWluSW5jbHVzaXZlLCBmTWF4RXhjbHVzaXZlLCBmVHlwZU5hbWV9KTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gY2hlY2sgNC4zLjEyLmMxIG11c3Q6IGZyYWN0aW9uRGlnaXRzIDw9IHRvdGFsRGlnaXRzCi0gICAgICAgICAgICBpZiAoKChmRmFjZXRzRGVmaW5lZCAmIEZBQ0VUX0ZSQUNUSU9ORElHSVRTKSAhPSAwKSAmJgotICAgICAgICAgICAgICAgICAgICAoKGZGYWNldHNEZWZpbmVkICYgRkFDRVRfVE9UQUxESUdJVFMpICE9IDApKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGZGcmFjdGlvbkRpZ2l0cyA+IGZUb3RhbERpZ2l0cykKLSAgICAgICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoICJmcmFjdGlvbkRpZ2l0cy10b3RhbERpZ2l0cyIsIG5ldyBPYmplY3RbXXtJbnRlZ2VyLnRvU3RyaW5nKGZGcmFjdGlvbkRpZ2l0cyksIEludGVnZXIudG9TdHJpbmcoZlRvdGFsRGlnaXRzKSwgZlR5cGVOYW1lfSk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIHN0ZXAgMzogY2hlY2sgZmFjZXRzIGFnYWluc3QgYmFzZQotICAgICAgICAgICAgLy8gY2hlY2sgNC4zLjEuYzEgZXJyb3I6IGxlbmd0aCAmIChmQmFzZS5tYXhMZW5ndGggfCBmQmFzZS5taW5MZW5ndGgpCi0gICAgICAgICAgICBpZigoZkZhY2V0c0RlZmluZWQgJiBGQUNFVF9MRU5HVEgpICE9IDAgKXsKLSAgICAgICAgICAgICAgICBpZiAoKGZCYXNlLmZGYWNldHNEZWZpbmVkICYgRkFDRVRfTUlOTEVOR1RIKSAhPSAwICYmCi0gICAgICAgICAgICAgICAgICAgICAgICBmTGVuZ3RoIDwgZkJhc2UuZk1pbkxlbmd0aCkgewotICAgICAgICAgICAgICAgICAgICAvLyBsZW5ndGgsIGZCYXNlLm1pbkxlbmd0aCBhbmQgZkJhc2UubWF4TGVuZ3RoIGRlZmluZWQKLSAgICAgICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoImxlbmd0aC1taW5MZW5ndGgtbWF4TGVuZ3RoLjEuMSIsIG5ldyBPYmplY3RbXXtmVHlwZU5hbWUsIEludGVnZXIudG9TdHJpbmcoZkxlbmd0aCksIEludGVnZXIudG9TdHJpbmcoZkJhc2UuZk1pbkxlbmd0aCl9KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaWYgKChmQmFzZS5mRmFjZXRzRGVmaW5lZCAmIEZBQ0VUX01BWExFTkdUSCkgIT0gMCAmJgotICAgICAgICAgICAgICAgICAgICAgICAgZkxlbmd0aCA+IGZCYXNlLmZNYXhMZW5ndGgpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gbGVuZ3RoIGFuZCBmQmFzZS5tYXhMZW5ndGggZGVmaW5lZAotICAgICAgICAgICAgICAgICAgICByZXBvcnRFcnJvcigibGVuZ3RoLW1pbkxlbmd0aC1tYXhMZW5ndGguMi4xIiwgbmV3IE9iamVjdFtde2ZUeXBlTmFtZSwgSW50ZWdlci50b1N0cmluZyhmTGVuZ3RoKSwgSW50ZWdlci50b1N0cmluZyhmQmFzZS5mTWF4TGVuZ3RoKX0pOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpZiAoIChmQmFzZS5mRmFjZXRzRGVmaW5lZCAmIEZBQ0VUX0xFTkdUSCkgIT0gMCApIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gY2hlY2sgNC4zLjEuYzIgZXJyb3I6IGxlbmd0aCAhPSBmQmFzZS5sZW5ndGgKLSAgICAgICAgICAgICAgICAgICAgaWYgKCBmTGVuZ3RoICE9IGZCYXNlLmZMZW5ndGggKQotICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoICJsZW5ndGgtdmFsaWQtcmVzdHJpY3Rpb24iLCBuZXcgT2JqZWN0W117SW50ZWdlci50b1N0cmluZyhmTGVuZ3RoKSwgSW50ZWdlci50b1N0cmluZyhmQmFzZS5mTGVuZ3RoKSwgZlR5cGVOYW1lfSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBjaGVjayA0LjMuMS5jMSBlcnJvcjogZkJhc2UubGVuZ3RoICYgKG1heExlbmd0aCB8IG1pbkxlbmd0aCkKLSAgICAgICAgICAgIGlmKChmQmFzZS5mRmFjZXRzRGVmaW5lZCAmIEZBQ0VUX0xFTkdUSCkgIT0gMCB8fCAoZkZhY2V0c0RlZmluZWQgJiBGQUNFVF9MRU5HVEgpICE9IDApewotICAgICAgICAgICAgICAgIGlmICgoZkZhY2V0c0RlZmluZWQgJiBGQUNFVF9NSU5MRU5HVEgpICE9IDApewotICAgICAgICAgICAgICAgICAgICBpZiAoZkJhc2UuZkxlbmd0aCA8IGZNaW5MZW5ndGgpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZCYXNlLmxlbmd0aCwgbWluTGVuZ3RoIGFuZCBtYXhMZW5ndGggZGVmaW5lZAotICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoImxlbmd0aC1taW5MZW5ndGgtbWF4TGVuZ3RoLjEuMSIsIG5ldyBPYmplY3RbXXtmVHlwZU5hbWUsIEludGVnZXIudG9TdHJpbmcoZkJhc2UuZkxlbmd0aCksIEludGVnZXIudG9TdHJpbmcoZk1pbkxlbmd0aCl9KTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBpZiAoKGZCYXNlLmZGYWNldHNEZWZpbmVkICYgRkFDRVRfTUlOTEVOR1RIKSA9PSAwKXsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydEVycm9yKCJsZW5ndGgtbWluTGVuZ3RoLW1heExlbmd0aC4xLjIuYSIsIG5ldyBPYmplY3RbXXtmVHlwZU5hbWV9KTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBpZiAoZk1pbkxlbmd0aCAhPSBmQmFzZS5mTWluTGVuZ3RoKXsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydEVycm9yKCJsZW5ndGgtbWluTGVuZ3RoLW1heExlbmd0aC4xLjIuYiIsIG5ldyBPYmplY3RbXXtmVHlwZU5hbWUsIEludGVnZXIudG9TdHJpbmcoZk1pbkxlbmd0aCksIEludGVnZXIudG9TdHJpbmcoZkJhc2UuZk1pbkxlbmd0aCl9KTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpZiAoKGZGYWNldHNEZWZpbmVkICYgRkFDRVRfTUFYTEVOR1RIKSAhPSAwKXsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGZCYXNlLmZMZW5ndGggPiBmTWF4TGVuZ3RoKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBmQmFzZS5sZW5ndGgsIG1pbkxlbmd0aCBhbmQgbWF4TGVuZ3RoIGRlZmluZWQKLSAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydEVycm9yKCJsZW5ndGgtbWluTGVuZ3RoLW1heExlbmd0aC4yLjEiLCBuZXcgT2JqZWN0W117ZlR5cGVOYW1lLCBJbnRlZ2VyLnRvU3RyaW5nKGZCYXNlLmZMZW5ndGgpLCBJbnRlZ2VyLnRvU3RyaW5nKGZNYXhMZW5ndGgpfSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgaWYgKChmQmFzZS5mRmFjZXRzRGVmaW5lZCAmIEZBQ0VUX01BWExFTkdUSCkgPT0gMCl7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRFcnJvcigibGVuZ3RoLW1pbkxlbmd0aC1tYXhMZW5ndGguMi4yLmEiLCBuZXcgT2JqZWN0W117ZlR5cGVOYW1lfSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgaWYgKGZNYXhMZW5ndGggIT0gZkJhc2UuZk1heExlbmd0aCl7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRFcnJvcigibGVuZ3RoLW1pbkxlbmd0aC1tYXhMZW5ndGguMi4yLmIiLCBuZXcgT2JqZWN0W117ZlR5cGVOYW1lLCBJbnRlZ2VyLnRvU3RyaW5nKGZNYXhMZW5ndGgpLCBJbnRlZ2VyLnRvU3RyaW5nKGZCYXNlLmZCYXNlLmZNYXhMZW5ndGgpfSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIGNoZWNrIDQuMy4yLmMxIG11c3Q6IG1pbkxlbmd0aCA8PSBmQmFzZS5tYXhMZW5ndGgKLSAgICAgICAgICAgIGlmICggKChmRmFjZXRzRGVmaW5lZCAmIEZBQ0VUX01JTkxFTkdUSCApICE9IDAgKSApIHsKLSAgICAgICAgICAgICAgICBpZiAoIChmQmFzZS5mRmFjZXRzRGVmaW5lZCAmIEZBQ0VUX01BWExFTkdUSCApICE9IDAgKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmICggZk1pbkxlbmd0aCA+IGZCYXNlLmZNYXhMZW5ndGggKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRFcnJvcigibWluTGVuZ3RoLWxlc3MtdGhhbi1lcXVhbC10by1tYXhMZW5ndGgiLCBuZXcgT2JqZWN0W117SW50ZWdlci50b1N0cmluZyhmTWluTGVuZ3RoKSwgSW50ZWdlci50b1N0cmluZyhmQmFzZS5mTWF4TGVuZ3RoKSwgZlR5cGVOYW1lfSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSBpZiAoIChmQmFzZS5mRmFjZXRzRGVmaW5lZCAmIEZBQ0VUX01JTkxFTkdUSCkgIT0gMCApIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKCAoZkJhc2UuZkZpeGVkRmFjZXQgJiBGQUNFVF9NSU5MRU5HVEgpICE9IDAgJiYgZk1pbkxlbmd0aCAhPSBmQmFzZS5mTWluTGVuZ3RoICkgewotICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoICJGaXhlZEZhY2V0VmFsdWUiLCBuZXcgT2JqZWN0W117Im1pbkxlbmd0aCIsIEludGVnZXIudG9TdHJpbmcoZk1pbkxlbmd0aCksIEludGVnZXIudG9TdHJpbmcoZkJhc2UuZk1pbkxlbmd0aCksIGZUeXBlTmFtZX0pOwotICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgLy8gY2hlY2sgNC4zLjIuYzIgZXJyb3I6IG1pbkxlbmd0aCA8IGZCYXNlLm1pbkxlbmd0aAotICAgICAgICAgICAgICAgICAgICBpZiAoIGZNaW5MZW5ndGggPCBmQmFzZS5mTWluTGVuZ3RoICkgewotICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoICJtaW5MZW5ndGgtdmFsaWQtcmVzdHJpY3Rpb24iLCBuZXcgT2JqZWN0W117SW50ZWdlci50b1N0cmluZyhmTWluTGVuZ3RoKSwgSW50ZWdlci50b1N0cmluZyhmQmFzZS5mTWluTGVuZ3RoKSwgZlR5cGVOYW1lfSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLQotICAgICAgICAgICAgLy8gY2hlY2sgNC4zLjIuYzEgbXVzdDogbWF4TGVuZ3RoIDwgZkJhc2UubWluTGVuZ3RoCi0gICAgICAgICAgICBpZiAoICgoZkZhY2V0c0RlZmluZWQgJiBGQUNFVF9NQVhMRU5HVEggKSAhPSAwICkgJiYgKChmQmFzZS5mRmFjZXRzRGVmaW5lZCAmIEZBQ0VUX01JTkxFTkdUSCApICE9IDAgKSkgewotICAgICAgICAgICAgICAgIGlmICggZk1heExlbmd0aCA8IGZCYXNlLmZNaW5MZW5ndGgpIHsKLSAgICAgICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoIm1pbkxlbmd0aC1sZXNzLXRoYW4tZXF1YWwtdG8tbWF4TGVuZ3RoIiwgbmV3IE9iamVjdFtde0ludGVnZXIudG9TdHJpbmcoZkJhc2UuZk1pbkxlbmd0aCksIEludGVnZXIudG9TdHJpbmcoZk1heExlbmd0aCl9KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIGNoZWNrIDQuMy4zLmMxIGVycm9yOiBtYXhMZW5ndGggPiBmQmFzZS5tYXhMZW5ndGgKLSAgICAgICAgICAgIGlmICggKGZGYWNldHNEZWZpbmVkICYgRkFDRVRfTUFYTEVOR1RIKSAhPSAwICkgewotICAgICAgICAgICAgICAgIGlmICggKGZCYXNlLmZGYWNldHNEZWZpbmVkICYgRkFDRVRfTUFYTEVOR1RIKSAhPSAwICl7Ci0gICAgICAgICAgICAgICAgICAgIGlmKCggKGZCYXNlLmZGaXhlZEZhY2V0ICYgRkFDRVRfTUFYTEVOR1RIKSAhPSAwICkmJiBmTWF4TGVuZ3RoICE9IGZCYXNlLmZNYXhMZW5ndGggKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRFcnJvciggIkZpeGVkRmFjZXRWYWx1ZSIsIG5ldyBPYmplY3RbXXsibWF4TGVuZ3RoIiwgSW50ZWdlci50b1N0cmluZyhmTWF4TGVuZ3RoKSwgSW50ZWdlci50b1N0cmluZyhmQmFzZS5mTWF4TGVuZ3RoKSwgZlR5cGVOYW1lfSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgaWYgKCBmTWF4TGVuZ3RoID4gZkJhc2UuZk1heExlbmd0aCApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydEVycm9yKCAibWF4TGVuZ3RoLXZhbGlkLXJlc3RyaWN0aW9uIiwgbmV3IE9iamVjdFtde0ludGVnZXIudG9TdHJpbmcoZk1heExlbmd0aCksIEludGVnZXIudG9TdHJpbmcoZkJhc2UuZk1heExlbmd0aCksIGZUeXBlTmFtZX0pOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvKiAgICAgICAgICAvLyBjaGVjayA0LjMuNy5jMiBlcnJvcjoKLSAgICAgICAgICAgICAgICAgICAgICAgICAvLyBtYXhJbmNsdXNpdmUgPiBmQmFzZS5tYXhJbmNsdXNpdmUKLSAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbWF4SW5jbHVzaXZlID49IGZCYXNlLm1heEV4Y2x1c2l2ZQotICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbWF4SW5jbHVzaXZlIDwgZkJhc2UubWluSW5jbHVzaXZlCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbWF4SW5jbHVzaXZlIDw9IGZCYXNlLm1pbkV4Y2x1c2l2ZQotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoKGZGYWNldHNEZWZpbmVkICYgRkFDRVRfTUFYSU5DTFVTSVZFKSAhPSAwKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoKChmQmFzZS5mRmFjZXRzRGVmaW5lZCAmIEZBQ0VUX01BWElOQ0xVU0lWRSkgIT0gMCkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gZkRWc1tmVmFsaWRhdGlvbkRWXS5jb21wYXJlKGZNYXhJbmNsdXNpdmUsIGZCYXNlLmZNYXhJbmNsdXNpdmUpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoKGZCYXNlLmZGaXhlZEZhY2V0ICYgRkFDRVRfTUFYSU5DTFVTSVZFKSAhPSAwICYmIHJlc3VsdCAhPSAwKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydEVycm9yKCAiRml4ZWRGYWNldFZhbHVlIiwgbmV3IE9iamVjdFtdeyJtYXhJbmNsdXNpdmUiLCBmTWF4SW5jbHVzaXZlLCBmQmFzZS5mTWF4SW5jbHVzaXZlLCBmVHlwZU5hbWV9KTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVzdWx0ICE9IC0xICYmIHJlc3VsdCAhPSAwKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydEVycm9yKCAibWF4SW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjEiLCBuZXcgT2JqZWN0W117Zk1heEluY2x1c2l2ZSwgZkJhc2UuZk1heEluY2x1c2l2ZSwgZlR5cGVOYW1lfSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoKChmQmFzZS5mRmFjZXRzRGVmaW5lZCAmIEZBQ0VUX01BWEVYQ0xVU0lWRSkgIT0gMCkgJiYKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkRWc1tmVmFsaWRhdGlvbkRWXS5jb21wYXJlKGZNYXhJbmNsdXNpdmUsIGZCYXNlLmZNYXhFeGNsdXNpdmUpICE9IC0xKXsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoICJtYXhJbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMSIsIG5ldyBPYmplY3RbXXtmTWF4SW5jbHVzaXZlLCBmQmFzZS5mTWF4RXhjbHVzaXZlLCBmVHlwZU5hbWV9KTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoKCBmQmFzZS5mRmFjZXRzRGVmaW5lZCAmIEZBQ0VUX01JTklOQ0xVU0lWRSkgIT0gMCkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gZkRWc1tmVmFsaWRhdGlvbkRWXS5jb21wYXJlKGZNYXhJbmNsdXNpdmUsIGZCYXNlLmZNaW5JbmNsdXNpdmUpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVzdWx0ICE9IDEgJiYgcmVzdWx0ICE9IDApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoICJtYXhJbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMSIsIG5ldyBPYmplY3RbXXtmTWF4SW5jbHVzaXZlLCBmQmFzZS5mTWluSW5jbHVzaXZlLCBmVHlwZU5hbWV9KTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCgoIGZCYXNlLmZGYWNldHNEZWZpbmVkICYgRkFDRVRfTUlORVhDTFVTSVZFKSAhPSAwKSAmJgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmRFZzW2ZWYWxpZGF0aW9uRFZdLmNvbXBhcmUoZk1heEluY2x1c2l2ZSwgZkJhc2UuZk1pbkV4Y2x1c2l2ZSApICE9IDEpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydEVycm9yKCAibWF4SW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjEiLCBuZXcgT2JqZWN0W117Zk1heEluY2x1c2l2ZSwgZkJhc2UuZk1pbkV4Y2x1c2l2ZSwgZlR5cGVOYW1lfSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjaGVjayA0LjMuOC5jMyBlcnJvcjoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG1heEV4Y2x1c2l2ZSA+IGZCYXNlLm1heEV4Y2x1c2l2ZQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG1heEV4Y2x1c2l2ZSA+IGZCYXNlLm1heEluY2x1c2l2ZQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBtYXhFeGNsdXNpdmUgPD0gZkJhc2UubWluSW5jbHVzaXZlCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBtYXhFeGNsdXNpdmUgPD0gZkJhc2UubWluRXhjbHVzaXZlCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCgoZkZhY2V0c0RlZmluZWQgJiBGQUNFVF9NQVhFWENMVVNJVkUpICE9IDApKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCgoIGZCYXNlLmZGYWNldHNEZWZpbmVkICYgRkFDRVRfTUFYRVhDTFVTSVZFKSAhPSAwKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdD0gZkRWc1tmVmFsaWRhdGlvbkRWXS5jb21wYXJlKGZNYXhFeGNsdXNpdmUsIGZCYXNlLmZNYXhFeGNsdXNpdmUpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoZkJhc2UuZkZpeGVkRmFjZXQgJiBGQUNFVF9NQVhFWENMVVNJVkUpICE9IDAgJiYgIHJlc3VsdCAhPSAwKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoICJGaXhlZEZhY2V0VmFsdWUiLCBuZXcgT2JqZWN0W117Im1heEV4Y2x1c2l2ZSIsIGZNYXhFeGNsdXNpdmUsIGZCYXNlLmZNYXhFeGNsdXNpdmUsIGZUeXBlTmFtZX0pOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVzdWx0ICE9IC0xICYmIHJlc3VsdCAhPSAwKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoICJtYXhFeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMSIsIG5ldyBPYmplY3RbXXtmTWF4RXhjbHVzaXZlLCBmQmFzZS5mTWF4RXhjbHVzaXZlLCBmVHlwZU5hbWV9KTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCgoIGZCYXNlLmZGYWNldHNEZWZpbmVkICYgRkFDRVRfTUFYSU5DTFVTSVZFKSAhPSAwKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdD0gZkRWc1tmVmFsaWRhdGlvbkRWXS5jb21wYXJlKGZNYXhFeGNsdXNpdmUsIGZCYXNlLmZNYXhJbmNsdXNpdmUpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgIT0gLTEgJiYgcmVzdWx0ICE9IDApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRFcnJvciggIm1heEV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4yIiwgbmV3IE9iamVjdFtde2ZNYXhFeGNsdXNpdmUsIGZCYXNlLmZNYXhJbmNsdXNpdmUsIGZUeXBlTmFtZX0pOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoKCggZkJhc2UuZkZhY2V0c0RlZmluZWQgJiBGQUNFVF9NSU5FWENMVVNJVkUpICE9IDApICYmCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkRWc1tmVmFsaWRhdGlvbkRWXS5jb21wYXJlKGZNYXhFeGNsdXNpdmUsIGZCYXNlLmZNaW5FeGNsdXNpdmUgKSAhPSAxKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydEVycm9yKCAibWF4RXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjMiLCBuZXcgT2JqZWN0W117Zk1heEV4Y2x1c2l2ZSwgZkJhc2UuZk1pbkV4Y2x1c2l2ZSwgZlR5cGVOYW1lfSk7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoKCggZkJhc2UuZkZhY2V0c0RlZmluZWQgJiBGQUNFVF9NSU5JTkNMVVNJVkUpICE9IDApICYmCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkRWc1tmVmFsaWRhdGlvbkRWXS5jb21wYXJlKGZNYXhFeGNsdXNpdmUsIGZCYXNlLmZNaW5JbmNsdXNpdmUpICE9IDEpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoICJtYXhFeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uNCIsIG5ldyBPYmplY3RbXXtmTWF4RXhjbHVzaXZlLCBmQmFzZS5mTWluSW5jbHVzaXZlLCBmVHlwZU5hbWV9KTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjaGVjayA0LjMuOS5jMyBlcnJvcjoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbWluRXhjbHVzaXZlIDwgZkJhc2UubWluRXhjbHVzaXZlCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBtaW5FeGNsdXNpdmUgPiBmQmFzZS5tYXhJbmNsdXNpdmUKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBtaW5FeGNsdXNpdmUgPCBmQmFzZS5taW5JbmNsdXNpdmUKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbWluRXhjbHVzaXZlID49IGZCYXNlLm1heEV4Y2x1c2l2ZQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCgoZkZhY2V0c0RlZmluZWQgJiBGQUNFVF9NSU5FWENMVVNJVkUpICE9IDApKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoKCggZkJhc2UuZkZhY2V0c0RlZmluZWQgJiBGQUNFVF9NSU5FWENMVVNJVkUpICE9IDApKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQ9IGZEVnNbZlZhbGlkYXRpb25EVl0uY29tcGFyZShmTWluRXhjbHVzaXZlLCBmQmFzZS5mTWluRXhjbHVzaXZlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoZkJhc2UuZkZpeGVkRmFjZXQgJiBGQUNFVF9NSU5FWENMVVNJVkUpICE9IDAgJiYgcmVzdWx0ICE9IDApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydEVycm9yKCAiRml4ZWRGYWNldFZhbHVlIiwgbmV3IE9iamVjdFtdeyJtaW5FeGNsdXNpdmUiLCBmTWluRXhjbHVzaXZlLCBmQmFzZS5mTWluRXhjbHVzaXZlLCBmVHlwZU5hbWV9KTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgIT0gMSAmJiByZXN1bHQgIT0gMCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoICJtaW5FeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMSIsIG5ldyBPYmplY3RbXXtmTWluRXhjbHVzaXZlLCBmQmFzZS5mTWluRXhjbHVzaXZlLCBmVHlwZU5hbWV9KTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCgoIGZCYXNlLmZGYWNldHNEZWZpbmVkICYgRkFDRVRfTUFYSU5DTFVTSVZFKSAhPSAwKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0PWZEVnNbZlZhbGlkYXRpb25EVl0uY29tcGFyZShmTWluRXhjbHVzaXZlLCBmQmFzZS5mTWF4SW5jbHVzaXZlKTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdCAhPSAtMSAmJiByZXN1bHQgIT0gMCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoICJtaW5FeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMiIsIG5ldyBPYmplY3RbXXtmTWluRXhjbHVzaXZlLCBmQmFzZS5mTWF4SW5jbHVzaXZlLCBmVHlwZU5hbWV9KTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCgoIGZCYXNlLmZGYWNldHNEZWZpbmVkICYgRkFDRVRfTUlOSU5DTFVTSVZFKSAhPSAwKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gZkRWc1tmVmFsaWRhdGlvbkRWXS5jb21wYXJlKGZNaW5FeGNsdXNpdmUsIGZCYXNlLmZNaW5JbmNsdXNpdmUpOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVzdWx0ICE9IDEgJiYgcmVzdWx0ICE9IDApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydEVycm9yKCAibWluRXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjMiLCBuZXcgT2JqZWN0W117Zk1pbkV4Y2x1c2l2ZSwgZkJhc2UuZk1pbkluY2x1c2l2ZSwgZlR5cGVOYW1lfSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoKCBmQmFzZS5mRmFjZXRzRGVmaW5lZCAmIEZBQ0VUX01BWEVYQ0xVU0lWRSkgIT0gMCkgJiYKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZEVnNbZlZhbGlkYXRpb25EVl0uY29tcGFyZShmTWluRXhjbHVzaXZlLCBmQmFzZS5mTWF4RXhjbHVzaXZlKSAhPSAtMSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydEVycm9yKCAibWluRXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjQiLCBuZXcgT2JqZWN0W117Zk1pbkV4Y2x1c2l2ZSwgZkJhc2UuZk1heEV4Y2x1c2l2ZSwgZlR5cGVOYW1lfSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNoZWNrIDQuMy4xMC5jMiBlcnJvcjoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBtaW5JbmNsdXNpdmUgPCBmQmFzZS5taW5JbmNsdXNpdmUKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbWluSW5jbHVzaXZlID4gZkJhc2UubWF4SW5jbHVzaXZlCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBtaW5JbmNsdXNpdmUgPD0gZkJhc2UubWluRXhjbHVzaXZlCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbWluSW5jbHVzaXZlID49IGZCYXNlLm1heEV4Y2x1c2l2ZQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoKChmRmFjZXRzRGVmaW5lZCAmIEZBQ0VUX01JTklOQ0xVU0lWRSkgIT0gMCkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCgoZkJhc2UuZkZhY2V0c0RlZmluZWQgJiBGQUNFVF9NSU5JTkNMVVNJVkUpICE9IDApKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IGZEVnNbZlZhbGlkYXRpb25EVl0uY29tcGFyZShmTWluSW5jbHVzaXZlLCBmQmFzZS5mTWluSW5jbHVzaXZlKTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoKGZCYXNlLmZGaXhlZEZhY2V0ICYgRkFDRVRfTUlOSU5DTFVTSVZFKSAhPSAwICYmIHJlc3VsdCAhPSAwKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydEVycm9yKCAiRml4ZWRGYWNldFZhbHVlIiwgbmV3IE9iamVjdFtdeyJtaW5JbmNsdXNpdmUiLCBmTWluSW5jbHVzaXZlLCBmQmFzZS5mTWluSW5jbHVzaXZlLCBmVHlwZU5hbWV9KTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVzdWx0ICE9IDEgJiYgcmVzdWx0ICE9IDApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoICJtaW5JbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMSIsIG5ldyBPYmplY3RbXXtmTWluSW5jbHVzaXZlLCBmQmFzZS5mTWluSW5jbHVzaXZlLCBmVHlwZU5hbWV9KTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoKCBmQmFzZS5mRmFjZXRzRGVmaW5lZCAmIEZBQ0VUX01BWElOQ0xVU0lWRSkgIT0gMCkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0PWZEVnNbZlZhbGlkYXRpb25EVl0uY29tcGFyZShmTWluSW5jbHVzaXZlLCBmQmFzZS5mTWF4SW5jbHVzaXZlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdCAhPSAtMSAmJiByZXN1bHQgIT0gMCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRFcnJvciggIm1pbkluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4yIiwgbmV3IE9iamVjdFtde2ZNaW5JbmNsdXNpdmUsIGZCYXNlLmZNYXhJbmNsdXNpdmUsIGZUeXBlTmFtZX0pOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCgoIGZCYXNlLmZGYWNldHNEZWZpbmVkICYgRkFDRVRfTUlORVhDTFVTSVZFKSAhPSAwKSAmJgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmRFZzW2ZWYWxpZGF0aW9uRFZdLmNvbXBhcmUoZk1pbkluY2x1c2l2ZSwgZkJhc2UuZk1pbkV4Y2x1c2l2ZSApICE9IDEpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydEVycm9yKCAibWluSW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjMiLCBuZXcgT2JqZWN0W117Zk1pbkluY2x1c2l2ZSwgZkJhc2UuZk1pbkV4Y2x1c2l2ZSwgZlR5cGVOYW1lfSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoKCBmQmFzZS5mRmFjZXRzRGVmaW5lZCAmIEZBQ0VUX01BWEVYQ0xVU0lWRSkgIT0gMCkgJiYKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkRWc1tmVmFsaWRhdGlvbkRWXS5jb21wYXJlKGZNaW5JbmNsdXNpdmUsIGZCYXNlLmZNYXhFeGNsdXNpdmUpICE9IC0xKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRFcnJvciggIm1pbkluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi40IiwgbmV3IE9iamVjdFtde2ZNaW5JbmNsdXNpdmUsIGZCYXNlLmZNYXhFeGNsdXNpdmUsIGZUeXBlTmFtZX0pOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgKi8KLSAgICAgICAgICAgIC8vIGNoZWNrIDQuMy4xMS5jMSBlcnJvcjogdG90YWxEaWdpdHMgPiBmQmFzZS50b3RhbERpZ2l0cwotICAgICAgICAgICAgaWYgKCgoZkZhY2V0c0RlZmluZWQgJiBGQUNFVF9UT1RBTERJR0lUUykgIT0gMCkpIHsKLSAgICAgICAgICAgICAgICBpZiAoKCggZkJhc2UuZkZhY2V0c0RlZmluZWQgJiBGQUNFVF9UT1RBTERJR0lUUykgIT0gMCkpIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKChmQmFzZS5mRml4ZWRGYWNldCAmIEZBQ0VUX1RPVEFMRElHSVRTKSAhPSAwICYmIGZUb3RhbERpZ2l0cyAhPSBmQmFzZS5mVG90YWxEaWdpdHMpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydEVycm9yKCJGaXhlZEZhY2V0VmFsdWUiLCBuZXcgT2JqZWN0W117InRvdGFsRGlnaXRzIiwgSW50ZWdlci50b1N0cmluZyhmVG90YWxEaWdpdHMpLCBJbnRlZ2VyLnRvU3RyaW5nKGZCYXNlLmZUb3RhbERpZ2l0cyksIGZUeXBlTmFtZX0pOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGlmIChmVG90YWxEaWdpdHMgPiBmQmFzZS5mVG90YWxEaWdpdHMpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydEVycm9yKCAidG90YWxEaWdpdHMtdmFsaWQtcmVzdHJpY3Rpb24iLCBuZXcgT2JqZWN0W117SW50ZWdlci50b1N0cmluZyhmVG90YWxEaWdpdHMpLCBJbnRlZ2VyLnRvU3RyaW5nKGZCYXNlLmZUb3RhbERpZ2l0cyksIGZUeXBlTmFtZX0pOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBjaGVjayA0LjMuMTIuYzEgbXVzdDogZnJhY3Rpb25EaWdpdHMgPD0gYmFzZS50b3RhbERpZ2l0cwotICAgICAgICAgICAgaWYgKChmRmFjZXRzRGVmaW5lZCAmIEZBQ0VUX0ZSQUNUSU9ORElHSVRTKSAhPSAwKSB7Ci0gICAgICAgICAgICAgICAgaWYgKChmQmFzZS5mRmFjZXRzRGVmaW5lZCAmIEZBQ0VUX1RPVEFMRElHSVRTKSAhPSAwKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChmRnJhY3Rpb25EaWdpdHMgPiBmQmFzZS5mVG90YWxEaWdpdHMpCi0gICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRFcnJvciggImZyYWN0aW9uRGlnaXRzLXRvdGFsRGlnaXRzIiwgbmV3IE9iamVjdFtde0ludGVnZXIudG9TdHJpbmcoZkZyYWN0aW9uRGlnaXRzKSwgSW50ZWdlci50b1N0cmluZyhmVG90YWxEaWdpdHMpLCBmVHlwZU5hbWV9KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIGNoZWNrIDQuMy4xMi5jMiBlcnJvcjogZnJhY3Rpb25EaWdpdHMgPiBmQmFzZS5mcmFjdGlvbkRpZ2l0cwotICAgICAgICAgICAgLy8gY2hlY2sgZml4ZWQgdmFsdWUgZm9yIGZyYWN0aW9uRGlnaXRzCi0gICAgICAgICAgICBpZiAoKChmRmFjZXRzRGVmaW5lZCAmIEZBQ0VUX0ZSQUNUSU9ORElHSVRTKSAhPSAwKSkgewotICAgICAgICAgICAgICAgIGlmICgoKCBmQmFzZS5mRmFjZXRzRGVmaW5lZCAmIEZBQ0VUX0ZSQUNUSU9ORElHSVRTKSAhPSAwKSkgewotICAgICAgICAgICAgICAgICAgICBpZiAoKChmQmFzZS5mRml4ZWRGYWNldCAmIEZBQ0VUX0ZSQUNUSU9ORElHSVRTKSAhPSAwICYmIGZGcmFjdGlvbkRpZ2l0cyAhPSBmQmFzZS5mRnJhY3Rpb25EaWdpdHMpIHx8Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGZWYWxpZGF0aW9uRFYgPT0gRFZfSU5URUdFUiAmJiBmRnJhY3Rpb25EaWdpdHMgIT0gMCkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydEVycm9yKCJGaXhlZEZhY2V0VmFsdWUiLCBuZXcgT2JqZWN0W117ImZyYWN0aW9uRGlnaXRzIiwgSW50ZWdlci50b1N0cmluZyhmRnJhY3Rpb25EaWdpdHMpLCBJbnRlZ2VyLnRvU3RyaW5nKGZCYXNlLmZGcmFjdGlvbkRpZ2l0cyksIGZUeXBlTmFtZX0pOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGlmIChmRnJhY3Rpb25EaWdpdHMgPiBmQmFzZS5mRnJhY3Rpb25EaWdpdHMpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydEVycm9yKCAiZnJhY3Rpb25EaWdpdHMtdmFsaWQtcmVzdHJpY3Rpb24iLCBuZXcgT2JqZWN0W117SW50ZWdlci50b1N0cmluZyhmRnJhY3Rpb25EaWdpdHMpLCBJbnRlZ2VyLnRvU3RyaW5nKGZCYXNlLmZGcmFjdGlvbkRpZ2l0cyksIGZUeXBlTmFtZX0pOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgaWYgKGZWYWxpZGF0aW9uRFYgPT0gRFZfSU5URUdFUiAmJiBmRnJhY3Rpb25EaWdpdHMgIT0gMCkgewotICAgICAgICAgICAgICAgICAgICByZXBvcnRFcnJvcigiRml4ZWRGYWNldFZhbHVlIiwgbmV3IE9iamVjdFtdeyJmcmFjdGlvbkRpZ2l0cyIsIEludGVnZXIudG9TdHJpbmcoZkZyYWN0aW9uRGlnaXRzKSwgIjAiLCBmVHlwZU5hbWV9KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIGNoZWNrIDQuMy42LmMxIGVycm9yOgotICAgICAgICAgICAgLy8gKHdoaXRlU3BhY2UgPSBwcmVzZXJ2ZSB8fCB3aGl0ZVNwYWNlID0gcmVwbGFjZSkgJiYgZkJhc2Uud2hpdGVTcGFjZSA9IGNvbGxhcGVzZSBvcgotICAgICAgICAgICAgLy8gd2hpdGVTcGFjZSA9IHByZXNlcnZlICYmIGZCYXNlLndoaXRlU3BhY2UgPSByZXBsYWNlCi0KLSAgICAgICAgICAgIGlmICggKGZGYWNldHNEZWZpbmVkICYgRkFDRVRfV0hJVEVTUEFDRSkgIT0gMCAmJiAoZkJhc2UuZkZhY2V0c0RlZmluZWQgJiBGQUNFVF9XSElURVNQQUNFKSAhPSAwICl7Ci0gICAgICAgICAgICAgICAgaWYgKCAoZkJhc2UuZkZpeGVkRmFjZXQgJiBGQUNFVF9XSElURVNQQUNFKSAhPSAwICYmICBmV2hpdGVTcGFjZSAhPSBmQmFzZS5mV2hpdGVTcGFjZSApIHsKLSAgICAgICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoICJGaXhlZEZhY2V0VmFsdWUiLCBuZXcgT2JqZWN0W117IndoaXRlU3BhY2UiLCB3aGl0ZVNwYWNlVmFsdWUoZldoaXRlU3BhY2UpLCB3aGl0ZVNwYWNlVmFsdWUoZkJhc2UuZldoaXRlU3BhY2UpLCBmVHlwZU5hbWV9KTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBpZiAoIGZXaGl0ZVNwYWNlID09IFdTX1BSRVNFUlZFICYmICBmQmFzZS5mV2hpdGVTcGFjZSA9PSBXU19DT0xMQVBTRSApewotICAgICAgICAgICAgICAgICAgICByZXBvcnRFcnJvciggIndoaXRlU3BhY2UtdmFsaWQtcmVzdHJpY3Rpb24uMSIsIG5ldyBPYmplY3RbXXtmVHlwZU5hbWUsICJwcmVzZXJ2ZSJ9KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaWYgKCBmV2hpdGVTcGFjZSA9PSBXU19SRVBMQUNFICYmICBmQmFzZS5mV2hpdGVTcGFjZSA9PSBXU19DT0xMQVBTRSApewotICAgICAgICAgICAgICAgICAgICByZXBvcnRFcnJvciggIndoaXRlU3BhY2UtdmFsaWQtcmVzdHJpY3Rpb24uMSIsIG5ldyBPYmplY3RbXXtmVHlwZU5hbWUsICJyZXBsYWNlIn0pOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpZiAoIGZXaGl0ZVNwYWNlID09IFdTX1BSRVNFUlZFICYmICBmQmFzZS5mV2hpdGVTcGFjZSA9PSBXU19SRVBMQUNFICl7Ci0gICAgICAgICAgICAgICAgICAgIHJlcG9ydEVycm9yKCAid2hpdGVTcGFjZS12YWxpZC1yZXN0cmljdGlvbi4yIiwgbmV3IE9iamVjdFtde2ZUeXBlTmFtZX0pOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfS8vZkZhY2V0c0RlZmluZWQgIT0gbnVsbAotCi0gICAgICAgIC8vIHN0ZXAgNDogaW5oZXJpdCBvdGhlciBmYWNldHMgZnJvbSBiYXNlIChpbmNsdWRpbmcgZlRva2V5VHlwZSkKLQotICAgICAgICAvLyBpbmhlcml0IGxlbmd0aAotICAgICAgICBpZiAoIChmRmFjZXRzRGVmaW5lZCAmIEZBQ0VUX0xFTkdUSCkgPT0gMCAgJiYgKGZCYXNlLmZGYWNldHNEZWZpbmVkICYgRkFDRVRfTEVOR1RIKSAhPSAwICkgewotICAgICAgICAgICAgZkZhY2V0c0RlZmluZWQgfD0gRkFDRVRfTEVOR1RIOwotICAgICAgICAgICAgZkxlbmd0aCA9IGZCYXNlLmZMZW5ndGg7Ci0gICAgICAgICAgICBsZW5ndGhBbm5vdGF0aW9uID0gZkJhc2UubGVuZ3RoQW5ub3RhdGlvbjsKLSAgICAgICAgfQotICAgICAgICAvLyBpbmhlcml0IG1pbkxlbmd0aAotICAgICAgICBpZiAoIChmRmFjZXRzRGVmaW5lZCAmIEZBQ0VUX01JTkxFTkdUSCkgPT0gMCAmJiAoZkJhc2UuZkZhY2V0c0RlZmluZWQgJiBGQUNFVF9NSU5MRU5HVEgpICE9IDAgKSB7Ci0gICAgICAgICAgICBmRmFjZXRzRGVmaW5lZCB8PSBGQUNFVF9NSU5MRU5HVEg7Ci0gICAgICAgICAgICBmTWluTGVuZ3RoID0gZkJhc2UuZk1pbkxlbmd0aDsKLSAgICAgICAgICAgIG1pbkxlbmd0aEFubm90YXRpb24gPSBmQmFzZS5taW5MZW5ndGhBbm5vdGF0aW9uOwotICAgICAgICB9Ci0gICAgICAgIC8vIGluaGVyaXQgbWF4TGVuZ3RoCi0gICAgICAgIGlmICgoZkZhY2V0c0RlZmluZWQgJiBGQUNFVF9NQVhMRU5HVEgpID09IDAgJiYgIChmQmFzZS5mRmFjZXRzRGVmaW5lZCAmIEZBQ0VUX01BWExFTkdUSCkgIT0gMCApIHsKLSAgICAgICAgICAgIGZGYWNldHNEZWZpbmVkIHw9IEZBQ0VUX01BWExFTkdUSDsKLSAgICAgICAgICAgIGZNYXhMZW5ndGggPSBmQmFzZS5mTWF4TGVuZ3RoOwotICAgICAgICAgICAgbWF4TGVuZ3RoQW5ub3RhdGlvbiA9IGZCYXNlLm1heExlbmd0aEFubm90YXRpb247Ci0gICAgICAgIH0KLSAgICAgICAgLy8gaW5oZXJpdCBwYXR0ZXJuCi0gICAgICAgIGlmICggKGZCYXNlLmZGYWNldHNEZWZpbmVkICYgRkFDRVRfUEFUVEVSTikgIT0gMCApIHsKLSAgICAgICAgICAgIGlmICgoZkZhY2V0c0RlZmluZWQgJiBGQUNFVF9QQVRURVJOKSA9PSAwKSB7Ci0gICAgICAgICAgICAgICAgZkZhY2V0c0RlZmluZWQgfD0gRkFDRVRfUEFUVEVSTjsKLSAgICAgICAgICAgICAgICBmUGF0dGVybiA9IGZCYXNlLmZQYXR0ZXJuOwotICAgICAgICAgICAgICAgIGZQYXR0ZXJuU3RyID0gZkJhc2UuZlBhdHRlcm5TdHI7Ci0gICAgICAgICAgICAgICAgcGF0dGVybkFubm90YXRpb25zID0gZkJhc2UucGF0dGVybkFubm90YXRpb25zOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IGZCYXNlLmZQYXR0ZXJuLnNpemUoKS0xOyBpID49IDA7IC0taSkgewotICAgICAgICAgICAgICAgICAgICBmUGF0dGVybi5hZGRFbGVtZW50KGZCYXNlLmZQYXR0ZXJuLmVsZW1lbnRBdChpKSk7Ci0gICAgICAgICAgICAgICAgICAgIGZQYXR0ZXJuU3RyLmFkZEVsZW1lbnQoZkJhc2UuZlBhdHRlcm5TdHIuZWxlbWVudEF0KGkpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaWYgKGZCYXNlLnBhdHRlcm5Bbm5vdGF0aW9ucyAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChwYXR0ZXJuQW5ub3RhdGlvbnMgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IGZCYXNlLnBhdHRlcm5Bbm5vdGF0aW9ucy5nZXRMZW5ndGgoKS0xOyBpID49IDA7IC0taSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhdHRlcm5Bbm5vdGF0aW9ucy5hZGRYU09iamVjdChmQmFzZS5wYXR0ZXJuQW5ub3RhdGlvbnMuaXRlbShpKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBwYXR0ZXJuQW5ub3RhdGlvbnMgPSBmQmFzZS5wYXR0ZXJuQW5ub3RhdGlvbnM7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgLy8gaW5oZXJpdCB3aGl0ZVNwYWNlCi0gICAgICAgIGlmICggKGZGYWNldHNEZWZpbmVkICYgRkFDRVRfV0hJVEVTUEFDRSkgPT0gMCAmJiAgKGZCYXNlLmZGYWNldHNEZWZpbmVkICYgRkFDRVRfV0hJVEVTUEFDRSkgIT0gMCApIHsKLSAgICAgICAgICAgIGZGYWNldHNEZWZpbmVkIHw9IEZBQ0VUX1dISVRFU1BBQ0U7Ci0gICAgICAgICAgICBmV2hpdGVTcGFjZSA9IGZCYXNlLmZXaGl0ZVNwYWNlOwotICAgICAgICAgICAgd2hpdGVTcGFjZUFubm90YXRpb24gPSBmQmFzZS53aGl0ZVNwYWNlQW5ub3RhdGlvbjsKLSAgICAgICAgfQotICAgICAgICAvLyBpbmhlcml0IGVudW1lcmF0aW9uCi0gICAgICAgIGlmICgoZkZhY2V0c0RlZmluZWQgJiBGQUNFVF9FTlVNRVJBVElPTikgPT0gMCAmJiAoZkJhc2UuZkZhY2V0c0RlZmluZWQgJiBGQUNFVF9FTlVNRVJBVElPTikgIT0gMCkgewotICAgICAgICAgICAgZkZhY2V0c0RlZmluZWQgfD0gRkFDRVRfRU5VTUVSQVRJT047Ci0gICAgICAgICAgICBmRW51bWVyYXRpb24gPSBmQmFzZS5mRW51bWVyYXRpb247Ci0gICAgICAgICAgICBlbnVtZXJhdGlvbkFubm90YXRpb25zID0gZkJhc2UuZW51bWVyYXRpb25Bbm5vdGF0aW9uczsKLSAgICAgICAgfQotICAgICAgICAvLyBpbmhlcml0IG1heEV4Y2x1c2l2ZQotICAgICAgICBpZiAoKCggZkJhc2UuZkZhY2V0c0RlZmluZWQgJiBGQUNFVF9NQVhFWENMVVNJVkUpICE9IDApICYmCi0gICAgICAgICAgICAgICAgISgoZkZhY2V0c0RlZmluZWQgJiBGQUNFVF9NQVhFWENMVVNJVkUpICE9IDApICYmICEoKGZGYWNldHNEZWZpbmVkICYgRkFDRVRfTUFYSU5DTFVTSVZFKSAhPSAwKSkgewotICAgICAgICAgICAgZkZhY2V0c0RlZmluZWQgfD0gRkFDRVRfTUFYRVhDTFVTSVZFOwotICAgICAgICAgICAgZk1heEV4Y2x1c2l2ZSA9IGZCYXNlLmZNYXhFeGNsdXNpdmU7Ci0gICAgICAgICAgICBtYXhFeGNsdXNpdmVBbm5vdGF0aW9uID0gZkJhc2UubWF4RXhjbHVzaXZlQW5ub3RhdGlvbjsKLSAgICAgICAgfQotICAgICAgICAvLyBpbmhlcml0IG1heEluY2x1c2l2ZQotICAgICAgICBpZiAoKCggZkJhc2UuZkZhY2V0c0RlZmluZWQgJiBGQUNFVF9NQVhJTkNMVVNJVkUpICE9IDApICYmCi0gICAgICAgICAgICAgICAgISgoZkZhY2V0c0RlZmluZWQgJiBGQUNFVF9NQVhFWENMVVNJVkUpICE9IDApICYmICEoKGZGYWNldHNEZWZpbmVkICYgRkFDRVRfTUFYSU5DTFVTSVZFKSAhPSAwKSkgewotICAgICAgICAgICAgZkZhY2V0c0RlZmluZWQgfD0gRkFDRVRfTUFYSU5DTFVTSVZFOwotICAgICAgICAgICAgZk1heEluY2x1c2l2ZSA9IGZCYXNlLmZNYXhJbmNsdXNpdmU7Ci0gICAgICAgICAgICBtYXhJbmNsdXNpdmVBbm5vdGF0aW9uID0gZkJhc2UubWF4SW5jbHVzaXZlQW5ub3RhdGlvbjsKLSAgICAgICAgfQotICAgICAgICAvLyBpbmhlcml0IG1pbkV4Y2x1c2l2ZQotICAgICAgICBpZiAoKCggZkJhc2UuZkZhY2V0c0RlZmluZWQgJiBGQUNFVF9NSU5FWENMVVNJVkUpICE9IDApICYmCi0gICAgICAgICAgICAgICAgISgoZkZhY2V0c0RlZmluZWQgJiBGQUNFVF9NSU5FWENMVVNJVkUpICE9IDApICYmICEoKGZGYWNldHNEZWZpbmVkICYgRkFDRVRfTUlOSU5DTFVTSVZFKSAhPSAwKSkgewotICAgICAgICAgICAgZkZhY2V0c0RlZmluZWQgfD0gRkFDRVRfTUlORVhDTFVTSVZFOwotICAgICAgICAgICAgZk1pbkV4Y2x1c2l2ZSA9IGZCYXNlLmZNaW5FeGNsdXNpdmU7Ci0gICAgICAgICAgICBtaW5FeGNsdXNpdmVBbm5vdGF0aW9uID0gZkJhc2UubWluRXhjbHVzaXZlQW5ub3RhdGlvbjsKLSAgICAgICAgfQotICAgICAgICAvLyBpbmhlcml0IG1pbkV4Y2x1c2l2ZQotICAgICAgICBpZiAoKCggZkJhc2UuZkZhY2V0c0RlZmluZWQgJiBGQUNFVF9NSU5JTkNMVVNJVkUpICE9IDApICYmCi0gICAgICAgICAgICAgICAgISgoZkZhY2V0c0RlZmluZWQgJiBGQUNFVF9NSU5FWENMVVNJVkUpICE9IDApICYmICEoKGZGYWNldHNEZWZpbmVkICYgRkFDRVRfTUlOSU5DTFVTSVZFKSAhPSAwKSkgewotICAgICAgICAgICAgZkZhY2V0c0RlZmluZWQgfD0gRkFDRVRfTUlOSU5DTFVTSVZFOwotICAgICAgICAgICAgZk1pbkluY2x1c2l2ZSA9IGZCYXNlLmZNaW5JbmNsdXNpdmU7Ci0gICAgICAgICAgICBtaW5JbmNsdXNpdmVBbm5vdGF0aW9uID0gZkJhc2UubWluSW5jbHVzaXZlQW5ub3RhdGlvbjsKLSAgICAgICAgfQotICAgICAgICAvLyBpbmhlcml0IHRvdGFsRGlnaXRzCi0gICAgICAgIGlmICgoKCBmQmFzZS5mRmFjZXRzRGVmaW5lZCAmIEZBQ0VUX1RPVEFMRElHSVRTKSAhPSAwKSAmJgotICAgICAgICAgICAgICAgICEoKGZGYWNldHNEZWZpbmVkICYgRkFDRVRfVE9UQUxESUdJVFMpICE9IDApKSB7Ci0gICAgICAgICAgICBmRmFjZXRzRGVmaW5lZCB8PSBGQUNFVF9UT1RBTERJR0lUUzsKLSAgICAgICAgICAgIGZUb3RhbERpZ2l0cyA9IGZCYXNlLmZUb3RhbERpZ2l0czsKLSAgICAgICAgICAgIHRvdGFsRGlnaXRzQW5ub3RhdGlvbiA9IGZCYXNlLnRvdGFsRGlnaXRzQW5ub3RhdGlvbjsKLSAgICAgICAgfQotICAgICAgICAvLyBpbmhlcml0IGZyYWN0aW9uRGlnaXRzCi0gICAgICAgIGlmICgoKCBmQmFzZS5mRmFjZXRzRGVmaW5lZCAmIEZBQ0VUX0ZSQUNUSU9ORElHSVRTKSAhPSAwKQotICAgICAgICAgICAgICAgICYmICEoKGZGYWNldHNEZWZpbmVkICYgRkFDRVRfRlJBQ1RJT05ESUdJVFMpICE9IDApKSB7Ci0gICAgICAgICAgICBmRmFjZXRzRGVmaW5lZCB8PSBGQUNFVF9GUkFDVElPTkRJR0lUUzsKLSAgICAgICAgICAgIGZGcmFjdGlvbkRpZ2l0cyA9IGZCYXNlLmZGcmFjdGlvbkRpZ2l0czsKLSAgICAgICAgICAgIGZyYWN0aW9uRGlnaXRzQW5ub3RhdGlvbiA9IGZCYXNlLmZyYWN0aW9uRGlnaXRzQW5ub3RhdGlvbjsKLSAgICAgICAgfQotICAgICAgICAvL2luaGVyaXQgdG9rZXl0eXBlCi0gICAgICAgIGlmICgoZlBhdHRlcm5UeXBlID09IFNQRUNJQUxfUEFUVEVSTl9OT05FICkgJiYgKGZCYXNlLmZQYXR0ZXJuVHlwZSAhPSBTUEVDSUFMX1BBVFRFUk5fTk9ORSkpIHsKLSAgICAgICAgICAgIGZQYXR0ZXJuVHlwZSA9IGZCYXNlLmZQYXR0ZXJuVHlwZSA7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBzdGVwIDU6IG1hcmsgZml4ZWQgdmFsdWVzCi0gICAgICAgIGZGaXhlZEZhY2V0IHw9IGZCYXNlLmZGaXhlZEZhY2V0OwotCi0gICAgICAgIC8vc3RlcCA2OiBzZXR0aW5nIGZ1bmRhbWVudGFsIGZhY2V0cwotICAgICAgICBjYWxjRnVuZGFtZW50YWxGYWNldHMoKTsKLQotICAgIH0gLy9hcHBseUZhY2V0cygpCi0KLSAgICAvKioKLSAgICAgKiB2YWxpZGF0ZSBhIHZhbHVlLCBhbmQgcmV0dXJuIHRoZSBjb21waWxlZCBmb3JtCi0gICAgICovCi0gICAgcHVibGljIE9iamVjdCB2YWxpZGF0ZShTdHJpbmcgY29udGVudCwgVmFsaWRhdGlvbkNvbnRleHQgY29udGV4dCwgVmFsaWRhdGVkSW5mbyB2YWxpZGF0ZWRJbmZvKSB0aHJvd3MgSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24gewotCi0gICAgICAgIGlmIChjb250ZXh0ID09IG51bGwpCi0gICAgICAgICAgICBjb250ZXh0ID0gZkVtcHR5Q29udGV4dDsKLQotICAgICAgICBpZiAodmFsaWRhdGVkSW5mbyA9PSBudWxsKQotICAgICAgICAgICAgdmFsaWRhdGVkSW5mbyA9IG5ldyBWYWxpZGF0ZWRJbmZvKCk7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICAgIHZhbGlkYXRlZEluZm8ubWVtYmVyVHlwZSA9IG51bGw7Ci0KLSAgICAgICAgLy8gZmlyc3Qgbm9ybWFsaXplIHN0cmluZyB2YWx1ZSwgYW5kIGNvbnZlcnQgaXQgdG8gYWN0dWFsIHZhbHVlCi0gICAgICAgIGJvb2xlYW4gbmVlZE5vcm1hbGl6ZSA9IGNvbnRleHQ9PW51bGx8fGNvbnRleHQubmVlZFRvTm9ybWFsaXplKCk7Ci0gICAgICAgIE9iamVjdCBvYiA9IGdldEFjdHVhbFZhbHVlKGNvbnRlbnQsIGNvbnRleHQsIHZhbGlkYXRlZEluZm8sIG5lZWROb3JtYWxpemUpOwotCi0gICAgICAgIHZhbGlkYXRlKGNvbnRleHQsIHZhbGlkYXRlZEluZm8pOwotCi0gICAgICAgIHJldHVybiBvYjsKLQotICAgIH0KLQotICAgIHByb3RlY3RlZCBWYWxpZGF0ZWRJbmZvIGdldEFjdHVhbEVudW1WYWx1ZShTdHJpbmcgbGV4aWNhbCwgVmFsaWRhdGlvbkNvbnRleHQgY3R4LCBWYWxpZGF0ZWRJbmZvIGluZm8pCi0gICAgdGhyb3dzIEludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uIHsKLSAgICAgICAgcmV0dXJuIGZCYXNlLnZhbGlkYXRlV2l0aEluZm8obGV4aWNhbCwgY3R4LCBpbmZvKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiB2YWxpZGF0ZSBhIHZhbHVlLCBhbmQgcmV0dXJuIHRoZSBjb21waWxlZCBmb3JtCi0gICAgICovCi0gICAgcHVibGljIFZhbGlkYXRlZEluZm8gdmFsaWRhdGVXaXRoSW5mbyhTdHJpbmcgY29udGVudCwgVmFsaWRhdGlvbkNvbnRleHQgY29udGV4dCwgVmFsaWRhdGVkSW5mbyB2YWxpZGF0ZWRJbmZvKSB0aHJvd3MgSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24gewotCi0gICAgICAgIGlmIChjb250ZXh0ID09IG51bGwpCi0gICAgICAgICAgICBjb250ZXh0ID0gZkVtcHR5Q29udGV4dDsKLQotICAgICAgICBpZiAodmFsaWRhdGVkSW5mbyA9PSBudWxsKQotICAgICAgICAgICAgdmFsaWRhdGVkSW5mbyA9IG5ldyBWYWxpZGF0ZWRJbmZvKCk7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICAgIHZhbGlkYXRlZEluZm8ubWVtYmVyVHlwZSA9IG51bGw7Ci0KLSAgICAgICAgLy8gZmlyc3Qgbm9ybWFsaXplIHN0cmluZyB2YWx1ZSwgYW5kIGNvbnZlcnQgaXQgdG8gYWN0dWFsIHZhbHVlCi0gICAgICAgIGJvb2xlYW4gbmVlZE5vcm1hbGl6ZSA9IGNvbnRleHQ9PW51bGx8fGNvbnRleHQubmVlZFRvTm9ybWFsaXplKCk7Ci0gICAgICAgIGdldEFjdHVhbFZhbHVlKGNvbnRlbnQsIGNvbnRleHQsIHZhbGlkYXRlZEluZm8sIG5lZWROb3JtYWxpemUpOwotCi0gICAgICAgIHZhbGlkYXRlKGNvbnRleHQsIHZhbGlkYXRlZEluZm8pOwotCi0gICAgICAgIHJldHVybiB2YWxpZGF0ZWRJbmZvOwotCi0gICAgfQotCi0gICAgLyoqCi0gICAgICogdmFsaWRhdGUgYSB2YWx1ZSwgYW5kIHJldHVybiB0aGUgY29tcGlsZWQgZm9ybQotICAgICAqLwotICAgIHB1YmxpYyBPYmplY3QgdmFsaWRhdGUoT2JqZWN0IGNvbnRlbnQsIFZhbGlkYXRpb25Db250ZXh0IGNvbnRleHQsIFZhbGlkYXRlZEluZm8gdmFsaWRhdGVkSW5mbykgdGhyb3dzIEludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uIHsKLQotICAgICAgICBpZiAoY29udGV4dCA9PSBudWxsKQotICAgICAgICAgICAgY29udGV4dCA9IGZFbXB0eUNvbnRleHQ7Ci0KLSAgICAgICAgaWYgKHZhbGlkYXRlZEluZm8gPT0gbnVsbCkKLSAgICAgICAgICAgIHZhbGlkYXRlZEluZm8gPSBuZXcgVmFsaWRhdGVkSW5mbygpOwotICAgICAgICBlbHNlCi0gICAgICAgICAgICB2YWxpZGF0ZWRJbmZvLm1lbWJlclR5cGUgPSBudWxsOwotCi0gICAgICAgIC8vIGZpcnN0IG5vcm1hbGl6ZSBzdHJpbmcgdmFsdWUsIGFuZCBjb252ZXJ0IGl0IHRvIGFjdHVhbCB2YWx1ZQotICAgICAgICBib29sZWFuIG5lZWROb3JtYWxpemUgPSBjb250ZXh0PT1udWxsfHxjb250ZXh0Lm5lZWRUb05vcm1hbGl6ZSgpOwotICAgICAgICBPYmplY3Qgb2IgPSBnZXRBY3R1YWxWYWx1ZShjb250ZW50LCBjb250ZXh0LCB2YWxpZGF0ZWRJbmZvLCBuZWVkTm9ybWFsaXplKTsKLQotICAgICAgICB2YWxpZGF0ZShjb250ZXh0LCB2YWxpZGF0ZWRJbmZvKTsKLQotICAgICAgICByZXR1cm4gb2I7Ci0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiB2YWxpZGF0ZSBhbiBhY3R1YWwgdmFsdWUgYWdhaW5zdCB0aGlzIERWCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29udGV4dCAgICAgICB0aGUgdmFsaWRhdGlvbiBjb250ZXh0Ci0gICAgICogQHBhcmFtIHZhbGlkYXRlZEluZm8gdXNlZCB0byBwcm92aWRlIHRoZSBhY3R1YWwgdmFsdWUgYW5kIG1lbWJlciB0eXBlcwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHZhbGlkYXRlKFZhbGlkYXRpb25Db250ZXh0IGNvbnRleHQsIFZhbGlkYXRlZEluZm8gdmFsaWRhdGVkSW5mbykKLSAgICAgICAgdGhyb3dzIEludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uIHsKLQotICAgICAgICBpZiAoY29udGV4dCA9PSBudWxsKQotICAgICAgICAgICAgY29udGV4dCA9IGZFbXB0eUNvbnRleHQ7Ci0KLSAgICAgICAgLy8gdGhlbiB2YWxpZGF0ZSB0aGUgYWN0dWFsIHZhbHVlIGFnYWluc3QgdGhlIGZhY2V0cwotICAgICAgICBpZiAoY29udGV4dC5uZWVkRmFjZXRDaGVja2luZygpICYmCi0gICAgICAgICAgICAgICAgKGZGYWNldHNEZWZpbmVkICE9IDAgJiYgZkZhY2V0c0RlZmluZWQgIT0gRkFDRVRfV0hJVEVTUEFDRSkpIHsKLSAgICAgICAgICAgIGNoZWNrRmFjZXRzKHZhbGlkYXRlZEluZm8pOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gbm93IGNoZWNrIGV4dHJhIHJ1bGVzOiBmb3IgSUQvSURSRUYvRU5USVRZCi0gICAgICAgIGlmIChjb250ZXh0Lm5lZWRFeHRyYUNoZWNraW5nKCkpIHsKLSAgICAgICAgICAgIGNoZWNrRXh0cmFSdWxlcyhjb250ZXh0LCB2YWxpZGF0ZWRJbmZvKTsKLSAgICAgICAgfQotCi0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIGNoZWNrRmFjZXRzKFZhbGlkYXRlZEluZm8gdmFsaWRhdGVkSW5mbykgdGhyb3dzIEludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uIHsKLQotICAgICAgICBPYmplY3Qgb2IgPSB2YWxpZGF0ZWRJbmZvLmFjdHVhbFZhbHVlOwotICAgICAgICBTdHJpbmcgY29udGVudCA9IHZhbGlkYXRlZEluZm8ubm9ybWFsaXplZFZhbHVlOwotICAgICAgICBzaG9ydCB0eXBlID0gdmFsaWRhdGVkSW5mby5hY3R1YWxWYWx1ZVR5cGU7Ci0gICAgICAgIFNob3J0TGlzdCBpdGVtVHlwZSA9IHZhbGlkYXRlZEluZm8uaXRlbVZhbHVlVHlwZXM7Ci0KLSAgICAgICAgLy8gRm9yIFFOYW1lIGFuZCBOT1RBVElPTiB0eXBlcywgd2UgZG9uJ3QgY2hlY2sgbGVuZ3RoIGZhY2V0cwotICAgICAgICBpZiAoZlZhbGlkYXRpb25EViAhPSBEVl9RTkFNRSAmJiBmVmFsaWRhdGlvbkRWICE9IERWX05PVEFUSU9OKSB7Ci0gICAgICAgICAgICBpbnQgbGVuZ3RoID0gZkRWc1tmVmFsaWRhdGlvbkRWXS5nZXREYXRhTGVuZ3RoKG9iKTsKLQotICAgICAgICAgICAgLy8gbWF4TGVuZ3RoCi0gICAgICAgICAgICBpZiAoIChmRmFjZXRzRGVmaW5lZCAmIEZBQ0VUX01BWExFTkdUSCkgIT0gMCApIHsKLSAgICAgICAgICAgICAgICBpZiAoIGxlbmd0aCA+IGZNYXhMZW5ndGggKSB7Ci0gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbigiY3ZjLW1heExlbmd0aC12YWxpZCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde2NvbnRlbnQsIEludGVnZXIudG9TdHJpbmcobGVuZ3RoKSwgSW50ZWdlci50b1N0cmluZyhmTWF4TGVuZ3RoKSwgZlR5cGVOYW1lfSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvL21pbkxlbmd0aAotICAgICAgICAgICAgaWYgKCAoZkZhY2V0c0RlZmluZWQgJiBGQUNFVF9NSU5MRU5HVEgpICE9IDAgKSB7Ci0gICAgICAgICAgICAgICAgaWYgKCBsZW5ndGggPCBmTWluTGVuZ3RoICkgewotICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24oImN2Yy1taW5MZW5ndGgtdmFsaWQiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXtjb250ZW50LCBJbnRlZ2VyLnRvU3RyaW5nKGxlbmd0aCksIEludGVnZXIudG9TdHJpbmcoZk1pbkxlbmd0aCksIGZUeXBlTmFtZX0pOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy9sZW5ndGgKLSAgICAgICAgICAgIGlmICggKGZGYWNldHNEZWZpbmVkICYgRkFDRVRfTEVOR1RIKSAhPSAwICkgewotICAgICAgICAgICAgICAgIGlmICggbGVuZ3RoICE9IGZMZW5ndGggKSB7Ci0gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbigiY3ZjLWxlbmd0aC12YWxpZCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde2NvbnRlbnQsIEludGVnZXIudG9TdHJpbmcobGVuZ3RoKSwgSW50ZWdlci50b1N0cmluZyhmTGVuZ3RoKSwgZlR5cGVOYW1lfSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy9lbnVtZXJhdGlvbgotICAgICAgICBpZiAoICgoZkZhY2V0c0RlZmluZWQgJiBGQUNFVF9FTlVNRVJBVElPTikgIT0gMCApICkgewotICAgICAgICAgICAgYm9vbGVhbiBwcmVzZW50ID0gZmFsc2U7Ci0gICAgICAgICAgICBmaW5hbCBpbnQgZW51bVNpemUgPSBmRW51bWVyYXRpb24uc2l6ZSgpOwotICAgICAgICAgICAgZmluYWwgc2hvcnQgcHJpbWl0aXZlVHlwZTEgPSBjb252ZXJ0VG9QcmltaXRpdmVLaW5kKHR5cGUpOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBlbnVtU2l6ZTsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgZmluYWwgc2hvcnQgcHJpbWl0aXZlVHlwZTIgPSBjb252ZXJ0VG9QcmltaXRpdmVLaW5kKGZFbnVtZXJhdGlvblR5cGVbaV0pOwotICAgICAgICAgICAgICAgIGlmICgocHJpbWl0aXZlVHlwZTEgPT0gcHJpbWl0aXZlVHlwZTIgfHwKLSAgICAgICAgICAgICAgICAgICAgICAgIHByaW1pdGl2ZVR5cGUxID09IFhTQ29uc3RhbnRzLkFOWVNJTVBMRVRZUEVfRFQgJiYgcHJpbWl0aXZlVHlwZTIgPT0gWFNDb25zdGFudHMuU1RSSU5HX0RUIHx8Ci0gICAgICAgICAgICAgICAgICAgICAgICBwcmltaXRpdmVUeXBlMSA9PSBYU0NvbnN0YW50cy5TVFJJTkdfRFQgJiYgcHJpbWl0aXZlVHlwZTIgPT0gWFNDb25zdGFudHMuQU5ZU0lNUExFVFlQRV9EVCkKLSAgICAgICAgICAgICAgICAgICAgICAgICYmIGZFbnVtZXJhdGlvbi5lbGVtZW50QXQoaSkuZXF1YWxzKG9iKSkgewotICAgICAgICAgICAgICAgICAgICBpZiAocHJpbWl0aXZlVHlwZTEgPT0gWFNDb25zdGFudHMuTElTVF9EVCB8fCBwcmltaXRpdmVUeXBlMSA9PSBYU0NvbnN0YW50cy5MSVNUT0ZVTklPTl9EVCkgewotICAgICAgICAgICAgICAgICAgICAgICAgU2hvcnRMaXN0IGVudW1JdGVtVHlwZSA9IGZFbnVtZXJhdGlvbkl0ZW1UeXBlW2ldOwotICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IHR5cGVMaXN0MUxlbmd0aCA9IGl0ZW1UeXBlICE9IG51bGwgPyBpdGVtVHlwZS5nZXRMZW5ndGgoKSA6IDA7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgdHlwZUxpc3QyTGVuZ3RoID0gZW51bUl0ZW1UeXBlICE9IG51bGwgPyBlbnVtSXRlbVR5cGUuZ2V0TGVuZ3RoKCkgOiAwOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVMaXN0MUxlbmd0aCA9PSB0eXBlTGlzdDJMZW5ndGgpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgajsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGogPSAwOyBqIDwgdHlwZUxpc3QxTGVuZ3RoOyArK2opIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgc2hvcnQgcHJpbWl0aXZlSXRlbTEgPSBjb252ZXJ0VG9QcmltaXRpdmVLaW5kKGl0ZW1UeXBlLml0ZW0oaikpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBzaG9ydCBwcmltaXRpdmVJdGVtMiA9IGNvbnZlcnRUb1ByaW1pdGl2ZUtpbmQoZW51bUl0ZW1UeXBlLml0ZW0oaikpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocHJpbWl0aXZlSXRlbTEgIT0gcHJpbWl0aXZlSXRlbTIpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwcmltaXRpdmVJdGVtMSA9PSBYU0NvbnN0YW50cy5BTllTSU1QTEVUWVBFX0RUICYmIHByaW1pdGl2ZUl0ZW0yID09IFhTQ29uc3RhbnRzLlNUUklOR19EVCB8fAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmltaXRpdmVJdGVtMSA9PSBYU0NvbnN0YW50cy5TVFJJTkdfRFQgJiYgcHJpbWl0aXZlSXRlbTIgPT0gWFNDb25zdGFudHMuQU5ZU0lNUExFVFlQRV9EVCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGogPT0gdHlwZUxpc3QxTGVuZ3RoKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZXNlbnQgPSB0cnVlOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBwcmVzZW50ID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYoIXByZXNlbnQpewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbigiY3ZjLWVudW1lcmF0aW9uLXZhbGlkIiwKLSAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3QgW10ge2NvbnRlbnQsIGZFbnVtZXJhdGlvbi50b1N0cmluZygpfSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvL2ZyYWN0aW9uRGlnaXRzCi0gICAgICAgIGlmICgoZkZhY2V0c0RlZmluZWQgJiBGQUNFVF9GUkFDVElPTkRJR0lUUykgIT0gMCkgewotICAgICAgICAgICAgaW50IHNjYWxlID0gZkRWc1tmVmFsaWRhdGlvbkRWXS5nZXRGcmFjdGlvbkRpZ2l0cyhvYik7Ci0gICAgICAgICAgICBpZiAoc2NhbGUgPiBmRnJhY3Rpb25EaWdpdHMpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24oImN2Yy1mcmFjdGlvbkRpZ2l0cy12YWxpZCIsCi0gICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10ge2NvbnRlbnQsIEludGVnZXIudG9TdHJpbmcoc2NhbGUpLCBJbnRlZ2VyLnRvU3RyaW5nKGZGcmFjdGlvbkRpZ2l0cyl9KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vdG90YWxEaWdpdHMKLSAgICAgICAgaWYgKChmRmFjZXRzRGVmaW5lZCAmIEZBQ0VUX1RPVEFMRElHSVRTKSE9MCkgewotICAgICAgICAgICAgaW50IHRvdGFsRGlnaXRzID0gZkRWc1tmVmFsaWRhdGlvbkRWXS5nZXRUb3RhbERpZ2l0cyhvYik7Ci0gICAgICAgICAgICBpZiAodG90YWxEaWdpdHMgPiBmVG90YWxEaWdpdHMpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24oImN2Yy10b3RhbERpZ2l0cy12YWxpZCIsCi0gICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10ge2NvbnRlbnQsIEludGVnZXIudG9TdHJpbmcodG90YWxEaWdpdHMpLCBJbnRlZ2VyLnRvU3RyaW5nKGZUb3RhbERpZ2l0cyl9KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGludCBjb21wYXJlOwotCi0gICAgICAgIC8vbWF4aW5jbHVzaXZlCi0gICAgICAgIGlmICggKGZGYWNldHNEZWZpbmVkICYgRkFDRVRfTUFYSU5DTFVTSVZFKSAhPSAwICkgewotICAgICAgICAgICAgY29tcGFyZSA9IGZEVnNbZlZhbGlkYXRpb25EVl0uY29tcGFyZShvYiwgZk1heEluY2x1c2l2ZSk7Ci0gICAgICAgICAgICBpZiAoY29tcGFyZSAhPSAtMSAmJiBjb21wYXJlICE9IDApIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24oImN2Yy1tYXhJbmNsdXNpdmUtdmFsaWQiLAotICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHtjb250ZW50LCBmTWF4SW5jbHVzaXZlLCBmVHlwZU5hbWV9KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vbWF4RXhjbHVzaXZlCi0gICAgICAgIGlmICggKGZGYWNldHNEZWZpbmVkICYgRkFDRVRfTUFYRVhDTFVTSVZFKSAhPSAwICkgewotICAgICAgICAgICAgY29tcGFyZSA9IGZEVnNbZlZhbGlkYXRpb25EVl0uY29tcGFyZShvYiwgZk1heEV4Y2x1c2l2ZSApOwotICAgICAgICAgICAgaWYgKGNvbXBhcmUgIT0gLTEpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24oImN2Yy1tYXhFeGNsdXNpdmUtdmFsaWQiLAotICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHtjb250ZW50LCBmTWF4RXhjbHVzaXZlLCBmVHlwZU5hbWV9KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vbWluSW5jbHVzaXZlCi0gICAgICAgIGlmICggKGZGYWNldHNEZWZpbmVkICYgRkFDRVRfTUlOSU5DTFVTSVZFKSAhPSAwICkgewotICAgICAgICAgICAgY29tcGFyZSA9IGZEVnNbZlZhbGlkYXRpb25EVl0uY29tcGFyZShvYiwgZk1pbkluY2x1c2l2ZSk7Ci0gICAgICAgICAgICBpZiAoY29tcGFyZSAhPSAxICYmIGNvbXBhcmUgIT0gMCkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbigiY3ZjLW1pbkluY2x1c2l2ZS12YWxpZCIsCi0gICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10ge2NvbnRlbnQsIGZNaW5JbmNsdXNpdmUsIGZUeXBlTmFtZX0pOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy9taW5FeGNsdXNpdmUKLSAgICAgICAgaWYgKCAoZkZhY2V0c0RlZmluZWQgJiBGQUNFVF9NSU5FWENMVVNJVkUpICE9IDAgKSB7Ci0gICAgICAgICAgICBjb21wYXJlID0gZkRWc1tmVmFsaWRhdGlvbkRWXS5jb21wYXJlKG9iLCBmTWluRXhjbHVzaXZlKTsKLSAgICAgICAgICAgIGlmIChjb21wYXJlICE9IDEpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24oImN2Yy1taW5FeGNsdXNpdmUtdmFsaWQiLAotICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHtjb250ZW50LCBmTWluRXhjbHVzaXZlLCBmVHlwZU5hbWV9KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIGNoZWNrRXh0cmFSdWxlcyhWYWxpZGF0aW9uQ29udGV4dCBjb250ZXh0LCBWYWxpZGF0ZWRJbmZvIHZhbGlkYXRlZEluZm8pIHRocm93cyBJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgT2JqZWN0IG9iID0gdmFsaWRhdGVkSW5mby5hY3R1YWxWYWx1ZTsKLQotICAgICAgICBpZiAoZlZhcmlldHkgPT0gVkFSSUVUWV9BVE9NSUMpIHsKLQotICAgICAgICAgICAgZkRWc1tmVmFsaWRhdGlvbkRWXS5jaGVja0V4dHJhUnVsZXMob2IsIGNvbnRleHQpOwotCi0gICAgICAgIH0gZWxzZSBpZiAoZlZhcmlldHkgPT0gVkFSSUVUWV9MSVNUKSB7Ci0KLSAgICAgICAgICAgIExpc3REVi5MaXN0RGF0YSB2YWx1ZXMgPSAoTGlzdERWLkxpc3REYXRhKW9iOwotICAgICAgICAgICAgWFNTaW1wbGVUeXBlIG1lbWJlclR5cGUgPSB2YWxpZGF0ZWRJbmZvLm1lbWJlclR5cGU7Ci0gICAgICAgICAgICBpbnQgbGVuID0gdmFsdWVzLmdldExlbmd0aCgpOwotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICBpZiAoZkl0ZW1UeXBlLmZWYXJpZXR5ID09IFZBUklFVFlfVU5JT04pIHsKLSAgICAgICAgICAgICAgICAgICAgWFNTaW1wbGVUeXBlRGVjbFtdIG1lbWJlclR5cGVzID0gKFhTU2ltcGxlVHlwZURlY2xbXSl2YWxpZGF0ZWRJbmZvLm1lbWJlclR5cGVzOwotICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gbGVuLTE7IGkgPj0gMDsgaS0tKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICB2YWxpZGF0ZWRJbmZvLmFjdHVhbFZhbHVlID0gdmFsdWVzLml0ZW0oaSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB2YWxpZGF0ZWRJbmZvLm1lbWJlclR5cGUgPSBtZW1iZXJUeXBlc1tpXTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZJdGVtVHlwZS5jaGVja0V4dHJhUnVsZXMoY29udGV4dCwgdmFsaWRhdGVkSW5mbyk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9IGVsc2UgeyAvLyAoZlZhcmlldHkgPT0gVkFSSUVUWV9BVE9NSUMpCi0gICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSBsZW4tMTsgaSA+PSAwOyBpLS0pIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHZhbGlkYXRlZEluZm8uYWN0dWFsVmFsdWUgPSB2YWx1ZXMuaXRlbShpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZJdGVtVHlwZS5jaGVja0V4dHJhUnVsZXMoY29udGV4dCwgdmFsaWRhdGVkSW5mbyk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmaW5hbGx5IHsKLSAgICAgICAgICAgICAgICB2YWxpZGF0ZWRJbmZvLmFjdHVhbFZhbHVlID0gdmFsdWVzOwotICAgICAgICAgICAgICAgIHZhbGlkYXRlZEluZm8ubWVtYmVyVHlwZSA9IG1lbWJlclR5cGU7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgfSBlbHNlIHsgLy8gKGZWYXJpZXR5ID09IFZBUklFVFlfVU5JT04pCi0KLSAgICAgICAgICAgICgoWFNTaW1wbGVUeXBlRGVjbCl2YWxpZGF0ZWRJbmZvLm1lbWJlclR5cGUpLmNoZWNrRXh0cmFSdWxlcyhjb250ZXh0LCB2YWxpZGF0ZWRJbmZvKTsKLQotICAgICAgICB9Ci0KLSAgICB9Ly8gY2hlY2tFeHRyYVJ1bGVzKCkKLQotICAgIC8vd2UgY2FuIHN0aWxsIHJldHVybiBvYmplY3QgZm9yIGludGVybmFsIHVzZS4KLSAgICBwcml2YXRlIE9iamVjdCBnZXRBY3R1YWxWYWx1ZShPYmplY3QgY29udGVudCwgVmFsaWRhdGlvbkNvbnRleHQgY29udGV4dCwKLSAgICAgICAgICAgIFZhbGlkYXRlZEluZm8gdmFsaWRhdGVkSW5mbywgYm9vbGVhbiBuZWVkTm9ybWFsaXplKQotICAgIHRocm93cyBJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbnsKLQotICAgICAgICBTdHJpbmcgbnZhbHVlOwotICAgICAgICBpZiAobmVlZE5vcm1hbGl6ZSkgewotICAgICAgICAgICAgbnZhbHVlID0gbm9ybWFsaXplKGNvbnRlbnQsIGZXaGl0ZVNwYWNlKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIG52YWx1ZSA9IGNvbnRlbnQudG9TdHJpbmcoKTsKLSAgICAgICAgfQotICAgICAgICBpZiAoIChmRmFjZXRzRGVmaW5lZCAmIEZBQ0VUX1BBVFRFUk4gKSAhPSAwICkgewotICAgICAgICAgICAgaWYgKGZQYXR0ZXJuLnNpemUoKT09MCAmJiBudmFsdWUubGVuZ3RoKCk+MCkgewotICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uKCJjdmMtcGF0dGVybi12YWxpZCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXtjb250ZW50LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKGVtcHR5IHN0cmluZykiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmVHlwZU5hbWV9KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIFJlZ3VsYXJFeHByZXNzaW9uIHJlZ2V4OwotICAgICAgICAgICAgZm9yIChpbnQgaWR4ID0gZlBhdHRlcm4uc2l6ZSgpLTE7IGlkeCA+PSAwOyBpZHgtLSkgewotICAgICAgICAgICAgICAgIHJlZ2V4ID0gKFJlZ3VsYXJFeHByZXNzaW9uKWZQYXR0ZXJuLmVsZW1lbnRBdChpZHgpOwotICAgICAgICAgICAgICAgIGlmICghcmVnZXgubWF0Y2hlcyhudmFsdWUpKXsKLSAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uKCJjdmMtcGF0dGVybi12YWxpZCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde2NvbnRlbnQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZlBhdHRlcm5TdHIuZWxlbWVudEF0KGlkeCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZlR5cGVOYW1lfSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKGZWYXJpZXR5ID09IFZBUklFVFlfQVRPTUlDKSB7Ci0KLSAgICAgICAgICAgIC8vIHZhbGlkYXRlIHNwZWNpYWwga2luZHMgb2YgdG9rZW4sIGluIHBsYWNlIG9mIG9sZCBwYXR0ZXJuIG1hdGNoaW5nCi0gICAgICAgICAgICBpZiAoZlBhdHRlcm5UeXBlICE9IFNQRUNJQUxfUEFUVEVSTl9OT05FKSB7Ci0KLSAgICAgICAgICAgICAgICBib29sZWFuIHNlZW5FcnIgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICBpZiAoZlBhdHRlcm5UeXBlID09IFNQRUNJQUxfUEFUVEVSTl9OTVRPS0VOKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIFBBVFRFUk4gIlxcYysiCi0gICAgICAgICAgICAgICAgICAgIHNlZW5FcnIgPSAhWE1MQ2hhci5pc1ZhbGlkTm10b2tlbihudmFsdWUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIGlmIChmUGF0dGVyblR5cGUgPT0gU1BFQ0lBTF9QQVRURVJOX05BTUUpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gUEFUVEVSTiAiXFxpXFxjKiIKLSAgICAgICAgICAgICAgICAgICAgc2VlbkVyciA9ICFYTUxDaGFyLmlzVmFsaWROYW1lKG52YWx1ZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgaWYgKGZQYXR0ZXJuVHlwZSA9PSBTUEVDSUFMX1BBVFRFUk5fTkNOQU1FKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIFBBVFRFUk4gIltcXGktWzpdXVtcXGMtWzpdXSoiCi0gICAgICAgICAgICAgICAgICAgIHNlZW5FcnIgPSAhWE1MQ2hhci5pc1ZhbGlkTkNOYW1lKG52YWx1ZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGlmIChzZWVuRXJyKSB7Ci0gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbigiY3ZjLWRhdGF0eXBlLXZhbGlkLjEuMi4xIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117bnZhbHVlLCBTUEVDSUFMX1BBVFRFUk5fU1RSSU5HW2ZQYXR0ZXJuVHlwZV19KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIHZhbGlkYXRlZEluZm8ubm9ybWFsaXplZFZhbHVlID0gbnZhbHVlOwotICAgICAgICAgICAgT2JqZWN0IGF2YWx1ZSA9IGZEVnNbZlZhbGlkYXRpb25EVl0uZ2V0QWN0dWFsVmFsdWUobnZhbHVlLCBjb250ZXh0KTsKLSAgICAgICAgICAgIHZhbGlkYXRlZEluZm8uYWN0dWFsVmFsdWUgPSBhdmFsdWU7Ci0gICAgICAgICAgICB2YWxpZGF0ZWRJbmZvLmFjdHVhbFZhbHVlVHlwZSA9IGZCdWlsdEluS2luZDsKLQotICAgICAgICAgICAgcmV0dXJuIGF2YWx1ZTsKLQotICAgICAgICB9IGVsc2UgaWYgKGZWYXJpZXR5ID09IFZBUklFVFlfTElTVCkgewotCi0gICAgICAgICAgICBTdHJpbmdUb2tlbml6ZXIgcGFyc2VkTGlzdCA9IG5ldyBTdHJpbmdUb2tlbml6ZXIobnZhbHVlLCAiICIpOwotICAgICAgICAgICAgaW50IGNvdW50T2ZUb2tlbnMgPSBwYXJzZWRMaXN0LmNvdW50VG9rZW5zKCkgOwotICAgICAgICAgICAgT2JqZWN0W10gYXZhbHVlID0gbmV3IE9iamVjdFtjb3VudE9mVG9rZW5zXTsKLSAgICAgICAgICAgIGJvb2xlYW4gaXNVbmlvbiA9IGZJdGVtVHlwZS5nZXRWYXJpZXR5KCkgPT0gVkFSSUVUWV9VTklPTjsKLSAgICAgICAgICAgIHNob3J0W10gaXRlbVR5cGVzID0gbmV3IHNob3J0W2lzVW5pb24gPyBjb3VudE9mVG9rZW5zIDogMV07Ci0gICAgICAgICAgICBpZiAoIWlzVW5pb24pCi0gICAgICAgICAgICAgICAgaXRlbVR5cGVzWzBdID0gZkl0ZW1UeXBlLmZCdWlsdEluS2luZDsKLSAgICAgICAgICAgIFhTU2ltcGxlVHlwZURlY2xbXSBtZW1iZXJUeXBlcyA9IG5ldyBYU1NpbXBsZVR5cGVEZWNsW2NvdW50T2ZUb2tlbnNdOwotICAgICAgICAgICAgZm9yKGludCBpID0gMCA7IGkgPCBjb3VudE9mVG9rZW5zIDsgaSArKyl7Ci0gICAgICAgICAgICAgICAgLy8gd2UgY2FuJ3QgY2FsbCBmSXRlbVR5cGUudmFsaWRhdGUoKSwgb3RoZXJ3aXNlIGNoZWNrRXh0cmFSdWxlcygpCi0gICAgICAgICAgICAgICAgLy8gd2lsbCBiZSBjYWxsZWQgdHdpY2U6IG9uY2UgaW4gZkl0ZW1UeXBlLnZhbGlkYXRlLCBvbmNlIGluCi0gICAgICAgICAgICAgICAgLy8gdmFsaWRhdGUgbWV0aG9kIG9mIHRoaXMgdHlwZS4KLSAgICAgICAgICAgICAgICAvLyBzbyB3ZSB0YWtlIHR3byBzdGVwcyB0byBnZXQgdGhlIGFjdHVhbCB2YWx1ZToKLSAgICAgICAgICAgICAgICAvLyAxLiBmSXRlbVR5cGUuZ2V0QWN0dWFsVmFsdWUoKQotICAgICAgICAgICAgICAgIC8vIDIuIGZJdGVtVHlwZS5jaGVrY0ZhY2V0cygpCi0gICAgICAgICAgICAgICAgYXZhbHVlW2ldID0gZkl0ZW1UeXBlLmdldEFjdHVhbFZhbHVlKHBhcnNlZExpc3QubmV4dFRva2VuKCksIGNvbnRleHQsIHZhbGlkYXRlZEluZm8sIGZhbHNlKTsKLSAgICAgICAgICAgICAgICBpZiAoY29udGV4dC5uZWVkRmFjZXRDaGVja2luZygpICYmCi0gICAgICAgICAgICAgICAgICAgICAgICAoZkl0ZW1UeXBlLmZGYWNldHNEZWZpbmVkICE9IDAgJiYgZkl0ZW1UeXBlLmZGYWNldHNEZWZpbmVkICE9IEZBQ0VUX1dISVRFU1BBQ0UpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZJdGVtVHlwZS5jaGVja0ZhY2V0cyh2YWxpZGF0ZWRJbmZvKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgbWVtYmVyVHlwZXNbaV0gPSAoWFNTaW1wbGVUeXBlRGVjbCl2YWxpZGF0ZWRJbmZvLm1lbWJlclR5cGU7Ci0gICAgICAgICAgICAgICAgaWYgKGlzVW5pb24pCi0gICAgICAgICAgICAgICAgICAgIGl0ZW1UeXBlc1tpXSA9IG1lbWJlclR5cGVzW2ldLmZCdWlsdEluS2luZDsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgTGlzdERWLkxpc3REYXRhIHYgPSBuZXcgTGlzdERWLkxpc3REYXRhKGF2YWx1ZSk7Ci0gICAgICAgICAgICB2YWxpZGF0ZWRJbmZvLmFjdHVhbFZhbHVlID0gdjsKLSAgICAgICAgICAgIHZhbGlkYXRlZEluZm8uYWN0dWFsVmFsdWVUeXBlID0gaXNVbmlvbiA/IFhTQ29uc3RhbnRzLkxJU1RPRlVOSU9OX0RUIDogWFNDb25zdGFudHMuTElTVF9EVDsKLSAgICAgICAgICAgIHZhbGlkYXRlZEluZm8ubWVtYmVyVHlwZSA9IG51bGw7Ci0gICAgICAgICAgICB2YWxpZGF0ZWRJbmZvLm1lbWJlclR5cGVzID0gbWVtYmVyVHlwZXM7Ci0gICAgICAgICAgICB2YWxpZGF0ZWRJbmZvLml0ZW1WYWx1ZVR5cGVzID0gbmV3IFNob3J0TGlzdEltcGwoaXRlbVR5cGVzLCBpdGVtVHlwZXMubGVuZ3RoKTsKLSAgICAgICAgICAgIHZhbGlkYXRlZEluZm8ubm9ybWFsaXplZFZhbHVlID0gbnZhbHVlOwotCi0gICAgICAgICAgICByZXR1cm4gdjsKLQotICAgICAgICB9IGVsc2UgeyAvLyAoZlZhcmlldHkgPT0gVkFSSUVUWV9VTklPTikKLSAgICAgICAgICAgIGZpbmFsIE9iamVjdCBfY29udGVudCA9IChmTWVtYmVyVHlwZXMubGVuZ3RoID4gMSAmJiBjb250ZW50ICE9IG51bGwpID8gY29udGVudC50b1N0cmluZygpIDogY29udGVudDsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZk1lbWJlclR5cGVzLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgLy8gd2UgY2FuJ3QgY2FsbCBmTWVtYmVyVHlwZVtpXS52YWxpZGF0ZSgpLCBvdGhlcndpc2UgY2hlY2tFeHRyYVJ1bGVzKCkKLSAgICAgICAgICAgICAgICAgICAgLy8gd2lsbCBiZSBjYWxsZWQgdHdpY2U6IG9uY2UgaW4gZk1lbWJlclR5cGVbaV0udmFsaWRhdGUsIG9uY2UgaW4KLSAgICAgICAgICAgICAgICAgICAgLy8gdmFsaWRhdGUgbWV0aG9kIG9mIHRoaXMgdHlwZS4KLSAgICAgICAgICAgICAgICAgICAgLy8gc28gd2UgdGFrZSB0d28gc3RlcHMgdG8gZ2V0IHRoZSBhY3R1YWwgdmFsdWU6Ci0gICAgICAgICAgICAgICAgICAgIC8vIDEuIGZNZW1iZXJUeXBlW2ldLmdldEFjdHVhbFZhbHVlKCkKLSAgICAgICAgICAgICAgICAgICAgLy8gMi4gZk1lbWJlclR5cGVbaV0uY2hla2NGYWNldHMoKQotICAgICAgICAgICAgICAgICAgICBPYmplY3QgYVZhbHVlID0gZk1lbWJlclR5cGVzW2ldLmdldEFjdHVhbFZhbHVlKF9jb250ZW50LCBjb250ZXh0LCB2YWxpZGF0ZWRJbmZvLCB0cnVlKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGNvbnRleHQubmVlZEZhY2V0Q2hlY2tpbmcoKSAmJgotICAgICAgICAgICAgICAgICAgICAgICAgICAgIChmTWVtYmVyVHlwZXNbaV0uZkZhY2V0c0RlZmluZWQgIT0gMCAmJiBmTWVtYmVyVHlwZXNbaV0uZkZhY2V0c0RlZmluZWQgIT0gRkFDRVRfV0hJVEVTUEFDRSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZNZW1iZXJUeXBlc1tpXS5jaGVja0ZhY2V0cyh2YWxpZGF0ZWRJbmZvKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB2YWxpZGF0ZWRJbmZvLm1lbWJlclR5cGUgPSBmTWVtYmVyVHlwZXNbaV07Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBhVmFsdWU7Ci0gICAgICAgICAgICAgICAgfSBjYXRjaChJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbiBpbnZhbGlkVmFsdWUpIHsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBTdHJpbmdCdWZmZXIgdHlwZXNCdWZmZXIgPSBuZXcgU3RyaW5nQnVmZmVyKCk7Ci0gICAgICAgICAgICBYU1NpbXBsZVR5cGVEZWNsIGRlY2w7Ci0gICAgICAgICAgICBmb3IoaW50IGkgPSAwO2kgPCBmTWVtYmVyVHlwZXMubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgICAgICBpZihpICE9IDApCi0gICAgICAgICAgICAgICAgICAgIHR5cGVzQnVmZmVyLmFwcGVuZCgiIHwgIik7Ci0gICAgICAgICAgICAgICAgZGVjbCA9IGZNZW1iZXJUeXBlc1tpXTsKLSAgICAgICAgICAgICAgICBpZihkZWNsLmZUYXJnZXROYW1lc3BhY2UgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICB0eXBlc0J1ZmZlci5hcHBlbmQoJ3snKTsKLSAgICAgICAgICAgICAgICAgICAgdHlwZXNCdWZmZXIuYXBwZW5kKGRlY2wuZlRhcmdldE5hbWVzcGFjZSk7Ci0gICAgICAgICAgICAgICAgICAgIHR5cGVzQnVmZmVyLmFwcGVuZCgnfScpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB0eXBlc0J1ZmZlci5hcHBlbmQoZGVjbC5mVHlwZU5hbWUpOwotICAgICAgICAgICAgICAgIGlmKGRlY2wuZkVudW1lcmF0aW9uICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgVmVjdG9yIHYgPSBkZWNsLmZFbnVtZXJhdGlvbjsKLSAgICAgICAgICAgICAgICAgICAgdHlwZXNCdWZmZXIuYXBwZW5kKCIgOiBbIik7Ci0gICAgICAgICAgICAgICAgICAgIGZvcihpbnQgaiA9IDA7aiA8IHYuc2l6ZSgpOyBqKyspIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmKGogIT0gMCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlc0J1ZmZlci5hcHBlbmQoJywnKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVzQnVmZmVyLmFwcGVuZCh2LmVsZW1lbnRBdChqKSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgdHlwZXNCdWZmZXIuYXBwZW5kKCddJyk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uKCJjdmMtZGF0YXR5cGUtdmFsaWQuMS4yLjMiLAotICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117Y29udGVudCwgZlR5cGVOYW1lLCB0eXBlc0J1ZmZlci50b1N0cmluZygpfSk7Ci0gICAgICAgIH0KLQotICAgIH0vL2dldEFjdHVhbFZhbHVlKCkKLQotICAgIHB1YmxpYyBib29sZWFuIGlzRXF1YWwoT2JqZWN0IHZhbHVlMSwgT2JqZWN0IHZhbHVlMikgewotICAgICAgICBpZiAodmFsdWUxID09IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gdmFsdWUxLmVxdWFscyh2YWx1ZTIpOwotICAgIH0vL2lzRXF1YWwoKQotCi0gICAgLy8gZGV0ZXJtaW5lIHdoZXRoZXIgdGhlIHR3byB2YWx1ZXMgYXJlIGlkZW50aWNhbAotICAgIHB1YmxpYyBib29sZWFuIGlzSWRlbnRpY2FsIChPYmplY3QgdmFsdWUxLCBPYmplY3QgdmFsdWUyKSB7Ci0gICAgICAgIGlmICh2YWx1ZTEgPT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmRFZzW2ZWYWxpZGF0aW9uRFZdLmlzSWRlbnRpY2FsKHZhbHVlMSwgdmFsdWUyKTsKLSAgICB9Ly9pc0lkZW50aWNhbCgpCi0KLSAgICAvLyBub3JtYWxpemUgdGhlIHN0cmluZyBhY2NvcmRpbmcgdG8gdGhlIHdoaXRlU3BhY2UgZmFjZXQKLSAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBub3JtYWxpemUoU3RyaW5nIGNvbnRlbnQsIHNob3J0IHdzKSB7Ci0gICAgICAgIGludCBsZW4gPSBjb250ZW50ID09IG51bGwgPyAwIDogY29udGVudC5sZW5ndGgoKTsKLSAgICAgICAgaWYgKGxlbiA9PSAwIHx8IHdzID09IFdTX1BSRVNFUlZFKQotICAgICAgICAgICAgcmV0dXJuIGNvbnRlbnQ7Ci0KLSAgICAgICAgU3RyaW5nQnVmZmVyIHNiID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotICAgICAgICBpZiAod3MgPT0gV1NfUkVQTEFDRSkgewotICAgICAgICAgICAgY2hhciBjaDsKLSAgICAgICAgICAgIC8vIHdoZW4gaXQncyByZXBsYWNlLCBqdXN0IHJlcGxhY2UgI3g5LCAjeGEsICN4ZCBieSAjeDIwCi0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbjsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgY2ggPSBjb250ZW50LmNoYXJBdChpKTsKLSAgICAgICAgICAgICAgICBpZiAoY2ggIT0gMHg5ICYmIGNoICE9IDB4YSAmJiBjaCAhPSAweGQpCi0gICAgICAgICAgICAgICAgICAgIHNiLmFwcGVuZChjaCk7Ci0gICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICBzYi5hcHBlbmQoKGNoYXIpMHgyMCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBjaGFyIGNoOwotICAgICAgICAgICAgaW50IGk7Ci0gICAgICAgICAgICBib29sZWFuIGlzTGVhZGluZyA9IHRydWU7Ci0gICAgICAgICAgICAvLyB3aGVuIGl0J3MgY29sbGFwc2UKLSAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKykgewotICAgICAgICAgICAgICAgIGNoID0gY29udGVudC5jaGFyQXQoaSk7Ci0gICAgICAgICAgICAgICAgLy8gYXBwZW5kIHJlYWwgY2hhcmFjdGVycywgc28gd2UgcGFzc2VkIGxlYWRpbmcgd3MKLSAgICAgICAgICAgICAgICBpZiAoY2ggIT0gMHg5ICYmIGNoICE9IDB4YSAmJiBjaCAhPSAweGQgJiYgY2ggIT0gMHgyMCkgewotICAgICAgICAgICAgICAgICAgICBzYi5hcHBlbmQoY2gpOwotICAgICAgICAgICAgICAgICAgICBpc0xlYWRpbmcgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIGZvciB3aGl0ZXNwYWNlcywgd2Ugc2tpcCBhbGwgZm9sbG93aW5nIHdzCi0gICAgICAgICAgICAgICAgICAgIGZvciAoOyBpIDwgbGVuLTE7IGkrKykgewotICAgICAgICAgICAgICAgICAgICAgICAgY2ggPSBjb250ZW50LmNoYXJBdChpKzEpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNoICE9IDB4OSAmJiBjaCAhPSAweGEgJiYgY2ggIT0gMHhkICYmIGNoICE9IDB4MjApCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgLy8gaWYgaXQncyBub3QgYSBsZWFkaW5nIG9yIHRhaWxpbmcgd3MsIHRoZW4gYXBwZW5kIGEgc3BhY2UKLSAgICAgICAgICAgICAgICAgICAgaWYgKGkgPCBsZW4gLSAxICYmICFpc0xlYWRpbmcpCi0gICAgICAgICAgICAgICAgICAgICAgICBzYi5hcHBlbmQoKGNoYXIpMHgyMCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7Ci0gICAgfQotCi0gICAgLy8gbm9ybWFsaXplIHRoZSBzdHJpbmcgYWNjb3JkaW5nIHRvIHRoZSB3aGl0ZVNwYWNlIGZhY2V0Ci0gICAgcHJvdGVjdGVkIFN0cmluZyBub3JtYWxpemUoT2JqZWN0IGNvbnRlbnQsIHNob3J0IHdzKSB7Ci0gICAgICAgIGlmIChjb250ZW50ID09IG51bGwpCi0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLQotICAgICAgICAvLyBJZiBwYXR0ZXJuIGlzIG5vdCBkZWZpbmVkLCB3ZSBjYW4gc2tpcCBzb21lIG9mIHRoZSBub3JtYWxpemF0aW9uLgotICAgICAgICAvLyBPdGhlcndpc2Ugd2UgaGF2ZSB0byBub3JtYWxpemUgdGhlIGRhdGEgZm9yIGNvcnJlY3QgcmVzdWx0IG9mCi0gICAgICAgIC8vIHBhdHRlcm4gdmFsaWRhdGlvbi4KLSAgICAgICAgaWYgKCAoZkZhY2V0c0RlZmluZWQgJiBGQUNFVF9QQVRURVJOICkgPT0gMCApIHsKLSAgICAgICAgICAgIHNob3J0IG5vcm1fdHlwZSA9IGZEVk5vcm1hbGl6ZVR5cGVbZlZhbGlkYXRpb25EVl07Ci0gICAgICAgICAgICBpZiAobm9ybV90eXBlID09IE5PUk1BTElaRV9OT05FKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGNvbnRlbnQudG9TdHJpbmcoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKG5vcm1fdHlwZSA9PSBOT1JNQUxJWkVfVFJJTSkgewotICAgICAgICAgICAgICAgIHJldHVybiBYTUxDaGFyLnRyaW0oY29udGVudC50b1N0cmluZygpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGlmICghKGNvbnRlbnQgaW5zdGFuY2VvZiBTdHJpbmdCdWZmZXIpKSB7Ci0gICAgICAgICAgICBTdHJpbmcgc3RyQ29udGVudCA9IGNvbnRlbnQudG9TdHJpbmcoKTsKLSAgICAgICAgICAgIHJldHVybiBub3JtYWxpemUoc3RyQ29udGVudCwgd3MpOwotICAgICAgICB9Ci0KLSAgICAgICAgU3RyaW5nQnVmZmVyIHNiID0gKFN0cmluZ0J1ZmZlciljb250ZW50OwotICAgICAgICBpbnQgbGVuID0gc2IubGVuZ3RoKCk7Ci0gICAgICAgIGlmIChsZW4gPT0gMCkKLSAgICAgICAgICAgIHJldHVybiAiIjsKLSAgICAgICAgaWYgKHdzID09IFdTX1BSRVNFUlZFKQotICAgICAgICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7Ci0KLSAgICAgICAgaWYgKHdzID09IFdTX1JFUExBQ0UpIHsKLSAgICAgICAgICAgIGNoYXIgY2g7Ci0gICAgICAgICAgICAvLyB3aGVuIGl0J3MgcmVwbGFjZSwganVzdCByZXBsYWNlICN4OSwgI3hhLCAjeGQgYnkgI3gyMAotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW47IGkrKykgewotICAgICAgICAgICAgICAgIGNoID0gc2IuY2hhckF0KGkpOwotICAgICAgICAgICAgICAgIGlmIChjaCA9PSAweDkgfHwgY2ggPT0gMHhhIHx8IGNoID09IDB4ZCkKLSAgICAgICAgICAgICAgICAgICAgc2Iuc2V0Q2hhckF0KGksIChjaGFyKTB4MjApOwotICAgICAgICAgICAgfQotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgY2hhciBjaDsKLSAgICAgICAgICAgIGludCBpLCBqID0gMDsKLSAgICAgICAgICAgIGJvb2xlYW4gaXNMZWFkaW5nID0gdHJ1ZTsKLSAgICAgICAgICAgIC8vIHdoZW4gaXQncyBjb2xsYXBzZQotICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgY2ggPSBzYi5jaGFyQXQoaSk7Ci0gICAgICAgICAgICAgICAgLy8gYXBwZW5kIHJlYWwgY2hhcmFjdGVycywgc28gd2UgcGFzc2VkIGxlYWRpbmcgd3MKLSAgICAgICAgICAgICAgICBpZiAoY2ggIT0gMHg5ICYmIGNoICE9IDB4YSAmJiBjaCAhPSAweGQgJiYgY2ggIT0gMHgyMCkgewotICAgICAgICAgICAgICAgICAgICBzYi5zZXRDaGFyQXQoaisrLCBjaCk7Ci0gICAgICAgICAgICAgICAgICAgIGlzTGVhZGluZyA9IGZhbHNlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gZm9yIHdoaXRlc3BhY2VzLCB3ZSBza2lwIGFsbCBmb2xsb3dpbmcgd3MKLSAgICAgICAgICAgICAgICAgICAgZm9yICg7IGkgPCBsZW4tMTsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBjaCA9IHNiLmNoYXJBdChpKzEpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNoICE9IDB4OSAmJiBjaCAhPSAweGEgJiYgY2ggIT0gMHhkICYmIGNoICE9IDB4MjApCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgLy8gaWYgaXQncyBub3QgYSBsZWFkaW5nIG9yIHRhaWxpbmcgd3MsIHRoZW4gYXBwZW5kIGEgc3BhY2UKLSAgICAgICAgICAgICAgICAgICAgaWYgKGkgPCBsZW4gLSAxICYmICFpc0xlYWRpbmcpCi0gICAgICAgICAgICAgICAgICAgICAgICBzYi5zZXRDaGFyQXQoaisrLCAoY2hhcikweDIwKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBzYi5zZXRMZW5ndGgoaik7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKLSAgICB9Ci0KLSAgICB2b2lkIHJlcG9ydEVycm9yKFN0cmluZyBrZXksIE9iamVjdFtdIGFyZ3MpIHRocm93cyBJbnZhbGlkRGF0YXR5cGVGYWNldEV4Y2VwdGlvbiB7Ci0gICAgICAgIHRocm93IG5ldyBJbnZhbGlkRGF0YXR5cGVGYWNldEV4Y2VwdGlvbihrZXksIGFyZ3MpOwotICAgIH0KLQotCi0gICAgcHJpdmF0ZSBTdHJpbmcgd2hpdGVTcGFjZVZhbHVlKHNob3J0IHdzKXsKLSAgICAgICAgcmV0dXJuIFdTX0ZBQ0VUX1NUUklOR1t3c107Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogIEZ1bmRhbWVudGFsIEZhY2V0OiBvcmRlcmVkLgotICAgICAqLwotICAgIHB1YmxpYyBzaG9ydCBnZXRPcmRlcmVkKCkgewotICAgICAgICByZXR1cm4gZk9yZGVyZWQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRnVuZGFtZW50YWwgRmFjZXQ6IGJvdW5kZWQuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0Qm91bmRlZCgpewotICAgICAgICByZXR1cm4gZkJvdW5kZWQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRnVuZGFtZW50YWwgRmFjZXQ6IGNhcmRpbmFsaXR5LgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGdldEZpbml0ZSgpewotICAgICAgICByZXR1cm4gZkZpbml0ZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBGdW5kYW1lbnRhbCBGYWNldDogbnVtZXJpYy4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXROdW1lcmljKCl7Ci0gICAgICAgIHJldHVybiBmTnVtZXJpYzsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb252ZW5pZW5jZSBtZXRob2QuIFtGYWNldHNdOiBjaGVjayB3aGV0aGVyIGEgZmFjZXQgaXMgZGVmaW5lZCBvbiB0aGlzCi0gICAgICogdHlwZS4KLSAgICAgKiBAcGFyYW0gZmFjZXROYW1lICBUaGUgbmFtZSBvZiB0aGUgZmFjZXQuCi0gICAgICogQHJldHVybiAgVHJ1ZSBpZiB0aGUgZmFjZXQgaXMgZGVmaW5lZCwgZmFsc2Ugb3RoZXJ3aXNlLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzRGVmaW5lZEZhY2V0KHNob3J0IGZhY2V0TmFtZSkgewotICAgICAgICBpZiAoZlZhbGlkYXRpb25EViA9PSBEVl9BTllTSU1QTEVUWVBFIHx8Ci0gICAgICAgICAgICBmVmFsaWRhdGlvbkRWID09IERWX0FOWUFUT01JQ1RZUEUpIHsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotICAgICAgICBpZiAoKGZGYWNldHNEZWZpbmVkICYgZmFjZXROYW1lKSAhPSAwKSB7Ci0gICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgfQotICAgICAgICBpZiAoZlBhdHRlcm5UeXBlICE9IFNQRUNJQUxfUEFUVEVSTl9OT05FKSB7Ci0gICAgICAgICAgICByZXR1cm4gZmFjZXROYW1lID09IEZBQ0VUX1BBVFRFUk47Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGZWYWxpZGF0aW9uRFYgPT0gRFZfSU5URUdFUikgewotICAgICAgICAgICAgcmV0dXJuIGZhY2V0TmFtZSA9PSBGQUNFVF9QQVRURVJOIHx8IGZhY2V0TmFtZSA9PSBGQUNFVF9GUkFDVElPTkRJR0lUUzsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogW2ZhY2V0c106IGFsbCBmYWNldHMgZGVmaW5lZCBvbiB0aGlzIHR5cGUuIFRoZSB2YWx1ZSBpcyBhIGJpdAotICAgICAqIGNvbWJpbmF0aW9uIG9mIEZBQ0VUX1hYWCBjb25zdGFudHMgb2YgYWxsIGRlZmluZWQgZmFjZXRzLgotICAgICAqLwotICAgIHB1YmxpYyBzaG9ydCBnZXREZWZpbmVkRmFjZXRzKCkgewotICAgICAgICBpZiAoZlZhbGlkYXRpb25EViA9PSBEVl9BTllTSU1QTEVUWVBFIHx8Ci0gICAgICAgICAgICBmVmFsaWRhdGlvbkRWID09IERWX0FOWUFUT01JQ1RZUEUpIHsKLSAgICAgICAgICAgIHJldHVybiBGQUNFVF9OT05FOwotICAgICAgICB9Ci0gICAgICAgIGlmIChmUGF0dGVyblR5cGUgIT0gU1BFQ0lBTF9QQVRURVJOX05PTkUpIHsKLSAgICAgICAgICAgIHJldHVybiAoc2hvcnQpKGZGYWNldHNEZWZpbmVkIHwgRkFDRVRfUEFUVEVSTik7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGZWYWxpZGF0aW9uRFYgPT0gRFZfSU5URUdFUikgewotICAgICAgICAgICAgcmV0dXJuIChzaG9ydCkoZkZhY2V0c0RlZmluZWQgfCBGQUNFVF9QQVRURVJOIHwgRkFDRVRfRlJBQ1RJT05ESUdJVFMpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmRmFjZXRzRGVmaW5lZDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb252ZW5pZW5jZSBtZXRob2QuIFtGYWNldHNdOiBjaGVjayB3aGV0aGVyIGEgZmFjZXQgaXMgZGVmaW5lZCBhbmQKLSAgICAgKiBmaXhlZCBvbiB0aGlzIHR5cGUuCi0gICAgICogQHBhcmFtIGZhY2V0TmFtZSAgVGhlIG5hbWUgb2YgdGhlIGZhY2V0LgotICAgICAqIEByZXR1cm4gIFRydWUgaWYgdGhlIGZhY2V0IGlzIGZpeGVkLCBmYWxzZSBvdGhlcndpc2UuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNGaXhlZEZhY2V0KHNob3J0IGZhY2V0TmFtZSkgewotICAgICAgICBpZiAoKGZGaXhlZEZhY2V0ICYgZmFjZXROYW1lKSAhPSAwKQotICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgIGlmIChmVmFsaWRhdGlvbkRWID09IERWX0lOVEVHRVIpCi0gICAgICAgICAgICByZXR1cm4gZmFjZXROYW1lID09IEZBQ0VUX0ZSQUNUSU9ORElHSVRTOwotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogW2ZhY2V0c106IGFsbCBkZWZpbmVkIGZhY2V0cyBmb3IgdGhpcyB0eXBlIHdoaWNoIGFyZSBmaXhlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgc2hvcnQgZ2V0Rml4ZWRGYWNldHMoKSB7Ci0gICAgICAgIGlmIChmVmFsaWRhdGlvbkRWID09IERWX0lOVEVHRVIpCi0gICAgICAgICAgICByZXR1cm4gKHNob3J0KShmRml4ZWRGYWNldCB8IEZBQ0VUX0ZSQUNUSU9ORElHSVRTKTsKLSAgICAgICAgcmV0dXJuIGZGaXhlZEZhY2V0OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbnZlbmllbmNlIG1ldGhvZC4gUmV0dXJucyBhIHZhbHVlIG9mIGEgc2luZ2xlIGNvbnN0cmFpbmluZyBmYWNldCBmb3IKLSAgICAgKiB0aGlzIHNpbXBsZSB0eXBlIGRlZmluaXRpb24uIFRoaXMgbWV0aG9kIG11c3Qgbm90IGJlIHVzZWQgdG8gcmV0cmlldmUKLSAgICAgKiB2YWx1ZXMgZm9yIDxjb2RlPmVudW1lcmF0aW9uPC9jb2RlPiBhbmQgPGNvZGU+cGF0dGVybjwvY29kZT4gZmFjZXRzLgotICAgICAqIEBwYXJhbSBmYWNldE5hbWUgVGhlIG5hbWUgb2YgdGhlIGZhY2V0LCBpLmUuCi0gICAgICogICA8Y29kZT5GQUNFVF9MRU5HVEgsIEZBQ0VUX1RPVEFMRElHSVRTIDwvY29kZT4gKHNlZQotICAgICAqICAgPGNvZGU+WFNDb25zdGFudHM8L2NvZGU+KS4gVG8gcmV0cmlldmUgdGhlIHZhbHVlIGZvciBhIHBhdHRlcm4gb3IKLSAgICAgKiAgIGFuIGVudW1lcmF0aW9uLCBzZWUgPGNvZGU+ZW51bWVyYXRpb248L2NvZGU+IGFuZAotICAgICAqICAgPGNvZGU+cGF0dGVybjwvY29kZT4uCi0gICAgICogQHJldHVybiBBIHZhbHVlIG9mIHRoZSBmYWNldCBzcGVjaWZpZWQgaW4gPGNvZGU+ZmFjZXROYW1lPC9jb2RlPiBmb3IKLSAgICAgKiAgIHRoaXMgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiBvciA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldExleGljYWxGYWNldFZhbHVlKHNob3J0IGZhY2V0TmFtZSkgewotICAgICAgICBzd2l0Y2ggKGZhY2V0TmFtZSkgewotICAgICAgICAgICAgY2FzZSBGQUNFVF9MRU5HVEg6Ci0gICAgICAgICAgICAgICAgcmV0dXJuIChmTGVuZ3RoID09IC0xKT9udWxsOkludGVnZXIudG9TdHJpbmcoZkxlbmd0aCk7Ci0gICAgICAgICAgICBjYXNlIEZBQ0VUX01JTkxFTkdUSDoKLSAgICAgICAgICAgICAgICByZXR1cm4gKGZNaW5MZW5ndGggPT0gLTEpP251bGw6SW50ZWdlci50b1N0cmluZyhmTWluTGVuZ3RoKTsKLSAgICAgICAgICAgIGNhc2UgRkFDRVRfTUFYTEVOR1RIOgotICAgICAgICAgICAgICAgIHJldHVybiAoZk1heExlbmd0aCA9PSAtMSk/bnVsbDpJbnRlZ2VyLnRvU3RyaW5nKGZNYXhMZW5ndGgpOwotICAgICAgICAgICAgY2FzZSBGQUNFVF9XSElURVNQQUNFOgotICAgICAgICAgICAgICAgIGlmIChmVmFsaWRhdGlvbkRWID09IERWX0FOWVNJTVBMRVRZUEUgfHwKLSAgICAgICAgICAgICAgICAgICAgZlZhbGlkYXRpb25EViA9PSBEVl9BTllBVE9NSUNUWVBFKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICByZXR1cm4gV1NfRkFDRVRfU1RSSU5HW2ZXaGl0ZVNwYWNlXTsKLSAgICAgICAgICAgIGNhc2UgRkFDRVRfTUFYSU5DTFVTSVZFOgotICAgICAgICAgICAgICAgIHJldHVybiAoZk1heEluY2x1c2l2ZSA9PSBudWxsKT9udWxsOmZNYXhJbmNsdXNpdmUudG9TdHJpbmcoKTsKLSAgICAgICAgICAgIGNhc2UgRkFDRVRfTUFYRVhDTFVTSVZFOgotICAgICAgICAgICAgICAgIHJldHVybiAoZk1heEV4Y2x1c2l2ZSA9PSBudWxsKT9udWxsOmZNYXhFeGNsdXNpdmUudG9TdHJpbmcoKTsKLSAgICAgICAgICAgIGNhc2UgRkFDRVRfTUlORVhDTFVTSVZFOgotICAgICAgICAgICAgICAgIHJldHVybiAoZk1pbkV4Y2x1c2l2ZSA9PSBudWxsKT9udWxsOmZNaW5FeGNsdXNpdmUudG9TdHJpbmcoKTsKLSAgICAgICAgICAgIGNhc2UgRkFDRVRfTUlOSU5DTFVTSVZFOgotICAgICAgICAgICAgICAgIHJldHVybiAoZk1pbkluY2x1c2l2ZSA9PSBudWxsKT9udWxsOmZNaW5JbmNsdXNpdmUudG9TdHJpbmcoKTsKLSAgICAgICAgICAgIGNhc2UgRkFDRVRfVE9UQUxESUdJVFM6Ci0gICAgICAgICAgICAgICAgcmV0dXJuIChmVG90YWxEaWdpdHMgPT0gLTEpP251bGw6SW50ZWdlci50b1N0cmluZyhmVG90YWxEaWdpdHMpOwotICAgICAgICAgICAgY2FzZSBGQUNFVF9GUkFDVElPTkRJR0lUUzoKLSAgICAgICAgICAgICAgICBpZiAoZlZhbGlkYXRpb25EViA9PSBEVl9JTlRFR0VSKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiAiMCI7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHJldHVybiAoZkZyYWN0aW9uRGlnaXRzID09IC0xKT9udWxsOkludGVnZXIudG9TdHJpbmcoZkZyYWN0aW9uRGlnaXRzKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBIGxpc3Qgb2YgZW51bWVyYXRpb24gdmFsdWVzIGlmIGl0IGV4aXN0cywgb3RoZXJ3aXNlIGFuIGVtcHR5Ci0gICAgICogPGNvZGU+U3RyaW5nTGlzdDwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZ0xpc3QgZ2V0TGV4aWNhbEVudW1lcmF0aW9uKCkgewotICAgICAgICBpZiAoZkxleGljYWxFbnVtZXJhdGlvbiA9PSBudWxsKXsKLSAgICAgICAgICAgIGlmIChmRW51bWVyYXRpb24gPT0gbnVsbCkKLSAgICAgICAgICAgICAgICByZXR1cm4gU3RyaW5nTGlzdEltcGwuRU1QVFlfTElTVDsKLSAgICAgICAgICAgIGludCBzaXplID0gZkVudW1lcmF0aW9uLnNpemUoKTsKLSAgICAgICAgICAgIFN0cmluZ1tdIHN0cnMgPSBuZXcgU3RyaW5nW3NpemVdOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspCi0gICAgICAgICAgICAgICAgc3Ryc1tpXSA9IGZFbnVtZXJhdGlvbi5lbGVtZW50QXQoaSkudG9TdHJpbmcoKTsKLSAgICAgICAgICAgIGZMZXhpY2FsRW51bWVyYXRpb24gPSBuZXcgU3RyaW5nTGlzdEltcGwoc3Rycywgc2l6ZSk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGZMZXhpY2FsRW51bWVyYXRpb247Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQSBsaXN0IG9mIGFjdHVhbCBlbnVtZXJhdGlvbiB2YWx1ZXMgaWYgaXQgZXhpc3RzLCBvdGhlcndpc2UgYW4gZW1wdHkKLSAgICAgKiA8Y29kZT5PYmplY3RMaXN0PC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0TGlzdCBnZXRBY3R1YWxFbnVtZXJhdGlvbigpIHsKLSAgICAgICAgaWYgKGZBY3R1YWxFbnVtZXJhdGlvbiA9PSBudWxsKSB7Ci0gICAgICAgICAgICBmQWN0dWFsRW51bWVyYXRpb24gPSBuZXcgQWJzdHJhY3RPYmplY3RMaXN0KCkgewotICAgICAgICAgICAgICAgIHB1YmxpYyBpbnQgZ2V0TGVuZ3RoKCkgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gKGZFbnVtZXJhdGlvbiAhPSBudWxsKSA/IGZFbnVtZXJhdGlvbi5zaXplKCkgOiAwOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWlucyhPYmplY3QgaXRlbSkgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gKGZFbnVtZXJhdGlvbiAhPSBudWxsICYmIGZFbnVtZXJhdGlvbi5jb250YWlucyhpdGVtKSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHB1YmxpYyBPYmplY3QgaXRlbShpbnQgaW5kZXgpIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGluZGV4IDwgMCB8fCBpbmRleCA+PSBnZXRMZW5ndGgoKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZFbnVtZXJhdGlvbi5lbGVtZW50QXQoaW5kZXgpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH07Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGZBY3R1YWxFbnVtZXJhdGlvbjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBIGxpc3Qgb2YgZW51bWVyYXRpb24gdHlwZSB2YWx1ZXMgKGFzIGEgbGlzdCBvZiBTaG9ydExpc3Qgb2JqZWN0cykgaWYgaXQgZXhpc3RzLCBvdGhlcndpc2UgcmV0dXJucwotICAgICAqIG51bGwKLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0TGlzdCBnZXRFbnVtZXJhdGlvbkl0ZW1UeXBlTGlzdCgpIHsKLSAgICAgICAgaWYgKGZFbnVtZXJhdGlvbkl0ZW1UeXBlTGlzdCA9PSBudWxsKSB7Ci0gICAgICAgICAgICBpZihmRW51bWVyYXRpb25JdGVtVHlwZSA9PSBudWxsKQotICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICAgICAgZkVudW1lcmF0aW9uSXRlbVR5cGVMaXN0ID0gbmV3IEFic3RyYWN0T2JqZWN0TGlzdCgpIHsKLSAgICAgICAgICAgICAgICBwdWJsaWMgaW50IGdldExlbmd0aCgpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChmRW51bWVyYXRpb25JdGVtVHlwZSAhPSBudWxsKSA/IGZFbnVtZXJhdGlvbkl0ZW1UeXBlLmxlbmd0aCA6IDA7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKE9iamVjdCBpdGVtKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmKGZFbnVtZXJhdGlvbkl0ZW1UeXBlID09IG51bGwgfHwgIShpdGVtIGluc3RhbmNlb2YgU2hvcnRMaXN0KSkKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgICAgICAgICAgZm9yKGludCBpID0gMDtpIDwgZkVudW1lcmF0aW9uSXRlbVR5cGUubGVuZ3RoOyBpKyspCi0gICAgICAgICAgICAgICAgICAgICAgICBpZihmRW51bWVyYXRpb25JdGVtVHlwZVtpXSA9PSBpdGVtKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHB1YmxpYyBPYmplY3QgaXRlbShpbnQgaW5kZXgpIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGluZGV4IDwgMCB8fCBpbmRleCA+PSBnZXRMZW5ndGgoKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZFbnVtZXJhdGlvbkl0ZW1UeXBlW2luZGV4XTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9OwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmRW51bWVyYXRpb25JdGVtVHlwZUxpc3Q7Ci0gICAgfQotCi0gICAgcHVibGljIFNob3J0TGlzdCBnZXRFbnVtZXJhdGlvblR5cGVMaXN0KCkgewotICAgICAgICBpZiAoZkVudW1lcmF0aW9uVHlwZUxpc3QgPT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKGZFbnVtZXJhdGlvblR5cGUgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJldHVybiBTaG9ydExpc3RJbXBsLkVNUFRZX0xJU1Q7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmRW51bWVyYXRpb25UeXBlTGlzdCA9IG5ldyBTaG9ydExpc3RJbXBsIChmRW51bWVyYXRpb25UeXBlLCBmRW51bWVyYXRpb25UeXBlLmxlbmd0aCk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGZFbnVtZXJhdGlvblR5cGVMaXN0OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEEgbGlzdCBvZiBwYXR0ZXJuIHZhbHVlcyBpZiBpdCBleGlzdHMsIG90aGVyd2lzZSBhbiBlbXB0eQotICAgICAqIDxjb2RlPlN0cmluZ0xpc3Q8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmdMaXN0IGdldExleGljYWxQYXR0ZXJuKCkgewotICAgICAgICBpZiAoZlBhdHRlcm5UeXBlID09IFNQRUNJQUxfUEFUVEVSTl9OT05FICYmIGZWYWxpZGF0aW9uRFYgIT0gRFZfSU5URUdFUiAmJiBmUGF0dGVyblN0ciA9PSBudWxsKQotICAgICAgICAgICAgcmV0dXJuIFN0cmluZ0xpc3RJbXBsLkVNUFRZX0xJU1Q7Ci0gICAgICAgIGlmIChmTGV4aWNhbFBhdHRlcm4gPT0gbnVsbCl7Ci0gICAgICAgICAgICBpbnQgc2l6ZSA9IGZQYXR0ZXJuU3RyID09IG51bGwgPyAwIDogZlBhdHRlcm5TdHIuc2l6ZSgpOwotICAgICAgICAgICAgU3RyaW5nW10gc3RyczsKLSAgICAgICAgICAgIGlmIChmUGF0dGVyblR5cGUgPT0gU1BFQ0lBTF9QQVRURVJOX05NVE9LRU4pIHsKLSAgICAgICAgICAgICAgICBzdHJzID0gbmV3IFN0cmluZ1tzaXplKzFdOwotICAgICAgICAgICAgICAgIHN0cnNbc2l6ZV0gPSAiXFxjKyI7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChmUGF0dGVyblR5cGUgPT0gU1BFQ0lBTF9QQVRURVJOX05BTUUpIHsKLSAgICAgICAgICAgICAgICBzdHJzID0gbmV3IFN0cmluZ1tzaXplKzFdOwotICAgICAgICAgICAgICAgIHN0cnNbc2l6ZV0gPSAiXFxpXFxjKiI7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChmUGF0dGVyblR5cGUgPT0gU1BFQ0lBTF9QQVRURVJOX05DTkFNRSkgewotICAgICAgICAgICAgICAgIHN0cnMgPSBuZXcgU3RyaW5nW3NpemUrMl07Ci0gICAgICAgICAgICAgICAgc3Ryc1tzaXplXSA9ICJcXGlcXGMqIjsKLSAgICAgICAgICAgICAgICBzdHJzW3NpemUrMV0gPSAiW1xcaS1bOl1dW1xcYy1bOl1dKiI7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChmVmFsaWRhdGlvbkRWID09IERWX0lOVEVHRVIpIHsKLSAgICAgICAgICAgICAgICBzdHJzID0gbmV3IFN0cmluZ1tzaXplKzFdOwotICAgICAgICAgICAgICAgIHN0cnNbc2l6ZV0gPSAiW1xcLStdP1swLTldKyI7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBzdHJzID0gbmV3IFN0cmluZ1tzaXplXTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKQotICAgICAgICAgICAgICAgIHN0cnNbaV0gPSAoU3RyaW5nKWZQYXR0ZXJuU3RyLmVsZW1lbnRBdChpKTsKLSAgICAgICAgICAgIGZMZXhpY2FsUGF0dGVybiA9IG5ldyBTdHJpbmdMaXN0SW1wbChzdHJzLCBzdHJzLmxlbmd0aCk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGZMZXhpY2FsUGF0dGVybjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBbYW5ub3RhdGlvbnNdOiBhIHNldCBvZiBhbm5vdGF0aW9ucyBmb3IgdGhpcyBzaW1wbGUgdHlwZSBjb21wb25lbnQgaWYKLSAgICAgKiBpdCBleGlzdHMsIG90aGVyd2lzZSBhbiBlbXB0eSA8Y29kZT5YU09iamVjdExpc3Q8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBYU09iamVjdExpc3QgZ2V0QW5ub3RhdGlvbnMoKSB7Ci0gICAgICAgIHJldHVybiAoZkFubm90YXRpb25zICE9IG51bGwpID8gZkFubm90YXRpb25zIDogWFNPYmplY3RMaXN0SW1wbC5FTVBUWV9MSVNUOwotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBjYWxjRnVuZGFtZW50YWxGYWNldHMoKSB7Ci0gICAgICAgIHNldE9yZGVyZWQoKTsKLSAgICAgICAgc2V0TnVtZXJpYygpOwotICAgICAgICBzZXRCb3VuZGVkKCk7Ci0gICAgICAgIHNldENhcmRpbmFsaXR5KCk7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIHNldE9yZGVyZWQoKXsKLQotICAgICAgICAvLyBXaGVuIHt2YXJpZXR5fSBpcyBhdG9taWMsIHt2YWx1ZX0gaXMgaW5oZXJpdGVkIGZyb20ge3ZhbHVlfSBvZiB7YmFzZSB0eXBlIGRlZmluaXRpb259LiBGb3IgYWxsICJwcmltaXRpdmUiIHR5cGVzIHt2YWx1ZX0gaXMgYXMgc3BlY2lmaWVkIGluIHRoZSB0YWJsZSBpbiBGdW5kYW1lbnRhbCBGYWNldHMgKEMuMSkuCi0gICAgICAgIGlmKGZWYXJpZXR5ID09IFZBUklFVFlfQVRPTUlDKXsKLSAgICAgICAgICAgIHRoaXMuZk9yZGVyZWQgPSBmQmFzZS5mT3JkZXJlZDsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIFdoZW4ge3ZhcmlldHl9IGlzIGxpc3QsIHt2YWx1ZX0gaXMgZmFsc2UuCi0gICAgICAgIGVsc2UgaWYoZlZhcmlldHkgPT0gVkFSSUVUWV9MSVNUKXsKLSAgICAgICAgICAgIHRoaXMuZk9yZGVyZWQgPSBPUkRFUkVEX0ZBTFNFOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gV2hlbiB7dmFyaWV0eX0gaXMgdW5pb24sIHRoZSB7dmFsdWV9IGlzIHBhcnRpYWwgdW5sZXNzIG9uZSBvZiB0aGUgZm9sbG93aW5nOgotICAgICAgICAvLyAxLiBJZiBldmVyeSBtZW1iZXIgb2Yge21lbWJlciB0eXBlIGRlZmluaXRpb25zfSBpcyBkZXJpdmVkIGZyb20gYSBjb21tb24gYW5jZXN0b3Igb3RoZXIgdGhhbiB0aGUgc2ltcGxlIHVyLXR5cGUsIHRoZW4ge3ZhbHVlfSBpcyB0aGUgc2FtZSBhcyB0aGF0IGFuY2VzdG9yJ3Mgb3JkZXJlZCBmYWNldC4KLSAgICAgICAgLy8gMi4gSWYgZXZlcnkgbWVtYmVyIG9mIHttZW1iZXIgdHlwZSBkZWZpbml0aW9uc30gaGFzIGEge3ZhbHVlfSBvZiBmYWxzZSBmb3IgdGhlIG9yZGVyZWQgZmFjZXQsIHRoZW4ge3ZhbHVlfSBpcyBmYWxzZS4KLSAgICAgICAgZWxzZSBpZihmVmFyaWV0eSA9PSBWQVJJRVRZX1VOSU9OKXsKLSAgICAgICAgICAgIGludCBsZW5ndGggPSBmTWVtYmVyVHlwZXMubGVuZ3RoOwotICAgICAgICAgICAgLy8gUkVWSVNJVDogaXMgdGhlIGxlbmd0aCBwb3NzaWJsZSB0byBiZSAwPwotICAgICAgICAgICAgaWYgKGxlbmd0aCA9PSAwKSB7Ci0gICAgICAgICAgICAgICAgdGhpcy5mT3JkZXJlZCA9IE9SREVSRURfUEFSVElBTDsKLSAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyB3ZSBuZWVkIHRvIHByb2Nlc3MgdGhlIGZpcnN0IG1lbWJlciB0eXBlIGJlZm9yZSBlbnRlcmluZyB0aGUgbG9vcAotICAgICAgICAgICAgc2hvcnQgYW5jZXN0b3JJZCA9IGdldFByaW1pdGl2ZURWKGZNZW1iZXJUeXBlc1swXS5mVmFsaWRhdGlvbkRWKTsKLSAgICAgICAgICAgIGJvb2xlYW4gY29tbW9uQW5jID0gYW5jZXN0b3JJZCAhPSBEVl9BTllTSU1QTEVUWVBFOwotICAgICAgICAgICAgYm9vbGVhbiBhbGxGYWxzZSA9IGZNZW1iZXJUeXBlc1swXS5mT3JkZXJlZCA9PSBPUkRFUkVEX0ZBTFNFOwotICAgICAgICAgICAgLy8gZm9yIHRoZSBvdGhlciBtZW1iZXIgdHlwZXMsIGNoZWNrIHdoZXRoZXIgdGhlIHZhbHVlIGlzIGZhbHNlCi0gICAgICAgICAgICAvLyBhbmQgd2hldGhlciB0aGV5IGhhdmUgdGhlIHNhbWUgYW5jZXN0b3IgYXMgdGhlIGZpcnN0IG9uZQotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDE7IGkgPCBmTWVtYmVyVHlwZXMubGVuZ3RoICYmIChjb21tb25BbmMgfHwgYWxsRmFsc2UpOyBpKyspIHsKLSAgICAgICAgICAgICAgICBpZiAoY29tbW9uQW5jKQotICAgICAgICAgICAgICAgICAgICBjb21tb25BbmMgPSBhbmNlc3RvcklkID09IGdldFByaW1pdGl2ZURWKGZNZW1iZXJUeXBlc1tpXS5mVmFsaWRhdGlvbkRWKTsKLSAgICAgICAgICAgICAgICBpZiAoYWxsRmFsc2UpCi0gICAgICAgICAgICAgICAgICAgIGFsbEZhbHNlID0gZk1lbWJlclR5cGVzW2ldLmZPcmRlcmVkID09IE9SREVSRURfRkFMU0U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoY29tbW9uQW5jKSB7Ci0gICAgICAgICAgICAgICAgLy8gUkVWSVNJVDogYWxsIG1lbWJlciB0eXBlcyBzaG91bGQgaGF2ZSB0aGUgc2FtZSBvcmRlcmVkIHZhbHVlCi0gICAgICAgICAgICAgICAgLy8gICAgICAgICAganVzdCB1c2UgdGhlIGZpcnN0IG9uZS4gQ2FuIHdlIGFzc3VtZSB0aGlzPwotICAgICAgICAgICAgICAgIHRoaXMuZk9yZGVyZWQgPSBmTWVtYmVyVHlwZXNbMF0uZk9yZGVyZWQ7Ci0gICAgICAgICAgICB9IGVsc2UgaWYgKGFsbEZhbHNlKSB7Ci0gICAgICAgICAgICAgICAgdGhpcy5mT3JkZXJlZCA9IE9SREVSRURfRkFMU0U7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIHRoaXMuZk9yZGVyZWQgPSBPUkRFUkVEX1BBUlRJQUw7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgIH0vL3NldE9yZGVyZWQKLQotICAgIHByaXZhdGUgdm9pZCBzZXROdW1lcmljKCl7Ci0gICAgICAgIGlmKGZWYXJpZXR5ID09IFZBUklFVFlfQVRPTUlDKXsKLSAgICAgICAgICAgIHRoaXMuZk51bWVyaWMgPSBmQmFzZS5mTnVtZXJpYzsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmKGZWYXJpZXR5ID09IFZBUklFVFlfTElTVCl7Ci0gICAgICAgICAgICB0aGlzLmZOdW1lcmljID0gZmFsc2U7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZihmVmFyaWV0eSA9PSBWQVJJRVRZX1VOSU9OKXsKLSAgICAgICAgICAgIFhTU2ltcGxlVHlwZVtdIG1lbWJlclR5cGVzID0gZk1lbWJlclR5cGVzOwotICAgICAgICAgICAgZm9yKGludCBpID0gMCA7IGkgPCBtZW1iZXJUeXBlcy5sZW5ndGggOyBpKyspewotICAgICAgICAgICAgICAgIGlmKCFtZW1iZXJUeXBlc1tpXS5nZXROdW1lcmljKCkgKXsKLSAgICAgICAgICAgICAgICAgICAgdGhpcy5mTnVtZXJpYyA9IGZhbHNlOwotICAgICAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgdGhpcy5mTnVtZXJpYyA9IHRydWU7Ci0gICAgICAgIH0KLQotICAgIH0vL3NldE51bWVyaWMKLQotICAgIHByaXZhdGUgdm9pZCBzZXRCb3VuZGVkKCl7Ci0gICAgICAgIGlmKGZWYXJpZXR5ID09IFZBUklFVFlfQVRPTUlDKXsKLSAgICAgICAgICAgIGlmKCAoKCh0aGlzLmZGYWNldHNEZWZpbmVkICYgRkFDRVRfTUlOSU5DTFVTSVZFKSAhPSAwKSAgfHwgKCh0aGlzLmZGYWNldHNEZWZpbmVkICYgRkFDRVRfTUlORVhDTFVTSVZFKSAhPSAwKSkKLSAgICAgICAgICAgICAgICAgICAgJiYgICgoKHRoaXMuZkZhY2V0c0RlZmluZWQgJiBGQUNFVF9NQVhJTkNMVVNJVkUpICE9IDApICB8fCAoKHRoaXMuZkZhY2V0c0RlZmluZWQgJiBGQUNFVF9NQVhFWENMVVNJVkUpICE9IDApKSApewotICAgICAgICAgICAgICAgIHRoaXMuZkJvdW5kZWQgPSB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZXsKLSAgICAgICAgICAgICAgICB0aGlzLmZCb3VuZGVkID0gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZihmVmFyaWV0eSA9PSBWQVJJRVRZX0xJU1QpewotICAgICAgICAgICAgaWYoICgodGhpcy5mRmFjZXRzRGVmaW5lZCAmIEZBQ0VUX0xFTkdUSCkgIT0gMCApIHx8ICggKCh0aGlzLmZGYWNldHNEZWZpbmVkICYgRkFDRVRfTUlOTEVOR1RIKSAhPSAwICkKLSAgICAgICAgICAgICAgICAgICAgJiYgICgodGhpcy5mRmFjZXRzRGVmaW5lZCAmIEZBQ0VUX01BWExFTkdUSCkgIT0gMCApKSApewotICAgICAgICAgICAgICAgIHRoaXMuZkJvdW5kZWQgPSB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZXsKLSAgICAgICAgICAgICAgICB0aGlzLmZCb3VuZGVkID0gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmKGZWYXJpZXR5ID09IFZBUklFVFlfVU5JT04pewotCi0gICAgICAgICAgICBYU1NpbXBsZVR5cGVEZWNsIFtdIG1lbWJlclR5cGVzID0gdGhpcy5mTWVtYmVyVHlwZXM7Ci0gICAgICAgICAgICBzaG9ydCBhbmNlc3RvcklkID0gMCA7Ci0KLSAgICAgICAgICAgIGlmKG1lbWJlclR5cGVzLmxlbmd0aCA+IDApewotICAgICAgICAgICAgICAgIGFuY2VzdG9ySWQgPSBnZXRQcmltaXRpdmVEVihtZW1iZXJUeXBlc1swXS5mVmFsaWRhdGlvbkRWKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgZm9yKGludCBpID0gMCA7IGkgPCBtZW1iZXJUeXBlcy5sZW5ndGggOyBpKyspewotICAgICAgICAgICAgICAgIGlmKCFtZW1iZXJUeXBlc1tpXS5nZXRCb3VuZGVkKCkgfHwgKGFuY2VzdG9ySWQgIT0gZ2V0UHJpbWl0aXZlRFYobWVtYmVyVHlwZXNbaV0uZlZhbGlkYXRpb25EVikpICl7Ci0gICAgICAgICAgICAgICAgICAgIHRoaXMuZkJvdW5kZWQgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHRoaXMuZkJvdW5kZWQgPSB0cnVlOwotICAgICAgICB9Ci0KLSAgICB9Ly9zZXRCb3VuZGVkCi0KLSAgICBwcml2YXRlIGJvb2xlYW4gc3BlY2lhbENhcmRpbmFsaXR5Q2hlY2soKXsKLSAgICAgICAgaWYoIChmQmFzZS5mVmFsaWRhdGlvbkRWID09IFhTU2ltcGxlVHlwZURlY2wuRFZfREFURSkgfHwgKGZCYXNlLmZWYWxpZGF0aW9uRFYgPT0gWFNTaW1wbGVUeXBlRGVjbC5EVl9HWUVBUk1PTlRIKQotICAgICAgICAgICAgICAgIHx8IChmQmFzZS5mVmFsaWRhdGlvbkRWID09IFhTU2ltcGxlVHlwZURlY2wuRFZfR1lFQVIpIHx8IChmQmFzZS5mVmFsaWRhdGlvbkRWID09IFhTU2ltcGxlVHlwZURlY2wuRFZfR01PTlRIREFZKQotICAgICAgICAgICAgICAgIHx8IChmQmFzZS5mVmFsaWRhdGlvbkRWID09IFhTU2ltcGxlVHlwZURlY2wuRFZfR0RBWSkgfHwgKGZCYXNlLmZWYWxpZGF0aW9uRFYgPT0gWFNTaW1wbGVUeXBlRGVjbC5EVl9HTU9OVEgpICl7Ci0gICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZmFsc2U7Ci0KLSAgICB9IC8vc3BlY2lhbENhcmRpbmFsaXR5Q2hlY2soKQotCi0gICAgcHJpdmF0ZSB2b2lkIHNldENhcmRpbmFsaXR5KCl7Ci0gICAgICAgIGlmKGZWYXJpZXR5ID09IFZBUklFVFlfQVRPTUlDKXsKLSAgICAgICAgICAgIGlmKGZCYXNlLmZGaW5pdGUpewotICAgICAgICAgICAgICAgIHRoaXMuZkZpbml0ZSA9IHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsvLyAoIWZCYXNlLmZGaW5pdGUpCi0gICAgICAgICAgICAgICAgaWYgKCAoKHRoaXMuZkZhY2V0c0RlZmluZWQgJiBGQUNFVF9MRU5HVEgpICE9IDAgKSB8fCAoKHRoaXMuZkZhY2V0c0RlZmluZWQgJiBGQUNFVF9NQVhMRU5HVEgpICE9IDAgKQotICAgICAgICAgICAgICAgICAgICAgICAgfHwgKCh0aGlzLmZGYWNldHNEZWZpbmVkICYgRkFDRVRfVE9UQUxESUdJVFMpICE9IDAgKSApewotICAgICAgICAgICAgICAgICAgICB0aGlzLmZGaW5pdGUgPSB0cnVlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIGlmKCAoKCh0aGlzLmZGYWNldHNEZWZpbmVkICYgRkFDRVRfTUlOSU5DTFVTSVZFKSAhPSAwICkgfHwgKCh0aGlzLmZGYWNldHNEZWZpbmVkICYgRkFDRVRfTUlORVhDTFVTSVZFKSAhPSAwICkpCi0gICAgICAgICAgICAgICAgICAgICAgICAmJiAoKCh0aGlzLmZGYWNldHNEZWZpbmVkICYgRkFDRVRfTUFYSU5DTFVTSVZFKSAhPSAwICkgfHwgKCh0aGlzLmZGYWNldHNEZWZpbmVkICYgRkFDRVRfTUFYRVhDTFVTSVZFKSAhPSAwICkpICl7Ci0gICAgICAgICAgICAgICAgICAgIGlmKCAoKHRoaXMuZkZhY2V0c0RlZmluZWQgJiBGQUNFVF9GUkFDVElPTkRJR0lUUykgIT0gMCApIHx8IHNwZWNpYWxDYXJkaW5hbGl0eUNoZWNrKCkpewotICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5mRmluaXRlID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlewotICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5mRmluaXRlID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZXsKLSAgICAgICAgICAgICAgICAgICAgdGhpcy5mRmluaXRlID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYoZlZhcmlldHkgPT0gVkFSSUVUWV9MSVNUKXsKLSAgICAgICAgICAgIGlmKCAoKHRoaXMuZkZhY2V0c0RlZmluZWQgJiBGQUNFVF9MRU5HVEgpICE9IDAgKSB8fCAoICgodGhpcy5mRmFjZXRzRGVmaW5lZCAmIEZBQ0VUX01JTkxFTkdUSCkgIT0gMCApCi0gICAgICAgICAgICAgICAgICAgICYmICgodGhpcy5mRmFjZXRzRGVmaW5lZCAmIEZBQ0VUX01BWExFTkdUSCkgIT0gMCApKSApewotICAgICAgICAgICAgICAgIHRoaXMuZkZpbml0ZSA9IHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlewotICAgICAgICAgICAgICAgIHRoaXMuZkZpbml0ZSA9IGZhbHNlOwotICAgICAgICAgICAgfQotCi0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZihmVmFyaWV0eSA9PSBWQVJJRVRZX1VOSU9OKXsKLSAgICAgICAgICAgIFhTU2ltcGxlVHlwZSBbXSBtZW1iZXJUeXBlcyA9IGZNZW1iZXJUeXBlczsKLSAgICAgICAgICAgIGZvcihpbnQgaSA9IDAgOyBpIDwgbWVtYmVyVHlwZXMubGVuZ3RoIDsgaSsrKXsKLSAgICAgICAgICAgICAgICBpZighKG1lbWJlclR5cGVzW2ldLmdldEZpbml0ZSgpKSApewotICAgICAgICAgICAgICAgICAgICB0aGlzLmZGaW5pdGUgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHRoaXMuZkZpbml0ZSA9IHRydWU7Ci0gICAgICAgIH0KLQotICAgIH0vL3NldENhcmRpbmFsaXR5Ci0KLSAgICBwcml2YXRlIHNob3J0IGdldFByaW1pdGl2ZURWKHNob3J0IHZhbGlkYXRpb25EVil7Ci0KLSAgICAgICAgaWYgKHZhbGlkYXRpb25EViA9PSBEVl9JRCB8fCB2YWxpZGF0aW9uRFYgPT0gRFZfSURSRUYgfHwgdmFsaWRhdGlvbkRWID09IERWX0VOVElUWSl7Ci0gICAgICAgICAgICByZXR1cm4gRFZfU1RSSU5HOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKHZhbGlkYXRpb25EViA9PSBEVl9JTlRFR0VSKSB7Ci0gICAgICAgICAgICByZXR1cm4gRFZfREVDSU1BTDsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChDb25zdGFudHMuU0NIRU1BXzFfMV9TVVBQT1JUICYmICh2YWxpZGF0aW9uRFYgPT0gRFZfWUVBUk1PTlRIRFVSQVRJT04gfHwgdmFsaWRhdGlvbkRWID09IERWX0RBWVRJTUVEVVJBVElPTikpIHsKLSAgICAgICAgICAgIHJldHVybiBEVl9EVVJBVElPTjsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiB2YWxpZGF0aW9uRFY7Ci0gICAgICAgIH0KLQotICAgIH0vL2dldFByaW1pdGl2ZURWKCkKLQotICAgIHB1YmxpYyBib29sZWFuIGRlcml2ZWRGcm9tVHlwZShYU1R5cGVEZWZpbml0aW9uIGFuY2VzdG9yLCBzaG9ydCBkZXJpdmF0aW9uKSB7Ci0gICAgICAgIC8vIFJFVklTSVQ6IGltcGxlbWVudCBhY2NvcmRpbmcgdG8gZGVyaXZhdGlvbgotCi0gICAgICAgIC8vIGFuY2VzdG9yIGlzIG51bGwsIHJldHVybiBmYWxzZQotICAgICAgICBpZiAoYW5jZXN0b3IgPT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0gICAgICAgIC8vIGV4dHJhY3QgdGhlIGFjdHVhbCBYU1R5cGVEZWZpbml0aW9uIGlmIHRoZSBnaXZlbiBhbmNlc3RvciBpcyBhIGRlbGVnYXRlLgotICAgICAgICB3aGlsZSAoYW5jZXN0b3IgaW5zdGFuY2VvZiBYU1NpbXBsZVR5cGVEZWxlZ2F0ZSkgewotICAgICAgICAgICAgYW5jZXN0b3IgPSAoKFhTU2ltcGxlVHlwZURlbGVnYXRlKSBhbmNlc3RvcikudHlwZTsKLSAgICAgICAgfQotICAgICAgICAvLyBhbmNlc3RvciBpcyBhbnlUeXBlLCByZXR1cm4gdHJ1ZQotICAgICAgICAvLyBhbnlUeXBlIGlzIHRoZSBvbmx5IHR5cGUgd2hvc2UgYmFzZSB0eXBlIGlzIGl0c2VsZgotICAgICAgICBpZiAoYW5jZXN0b3IuZ2V0QmFzZVR5cGUoKSA9PSBhbmNlc3RvcikgewotICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgIH0KLSAgICAgICAgLy8gcmVjdXJzaXZlbHkgZ2V0IGJhc2UsIGFuZCBjb21wYXJlIGl0IHdpdGggYW5jZXN0b3IKLSAgICAgICAgWFNUeXBlRGVmaW5pdGlvbiB0eXBlID0gdGhpczsKLSAgICAgICAgd2hpbGUgKHR5cGUgIT0gYW5jZXN0b3IgJiYgICAgICAgICAgICAgICAgICAgICAgLy8gY29tcGFyZSB3aXRoIGFuY2VzdG9yCi0gICAgICAgICAgICAgICAgdHlwZSAhPSBmQW55U2ltcGxlVHlwZSkgeyAgLy8gcmVhY2hlZCBhbnlTaW1wbGVUeXBlCi0gICAgICAgICAgICB0eXBlID0gdHlwZS5nZXRCYXNlVHlwZSgpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiB0eXBlID09IGFuY2VzdG9yOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGRlcml2ZWRGcm9tKFN0cmluZyBhbmNlc3Rvck5TLCBTdHJpbmcgYW5jZXN0b3JOYW1lLCBzaG9ydCBkZXJpdmF0aW9uKSB7Ci0gICAgICAgIC8vIFJFVklTSVQ6IGltcGxlbWVudCBhY2NvcmRpbmcgdG8gZGVyaXZhdGlvbgotCi0gICAgICAgIC8vIGFuY2VzdG9yIGlzIG51bGwsIHJldHVyIGZhbHNlCi0gICAgICAgIGlmIChhbmNlc3Rvck5hbWUgPT0gbnVsbCkKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgLy8gYW5jZXN0b3IgaXMgYW55VHlwZSwgcmV0dXJuIHRydWUKLSAgICAgICAgaWYgKFVSSV9TQ0hFTUFGT1JTQ0hFTUEuZXF1YWxzKGFuY2VzdG9yTlMpICYmCi0gICAgICAgICAgICAgICAgQU5ZX1RZUEUuZXF1YWxzKGFuY2VzdG9yTmFtZSkpIHsKLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gcmVjdXJzaXZlbHkgZ2V0IGJhc2UsIGFuZCBjb21wYXJlIGl0IHdpdGggYW5jZXN0b3IKLSAgICAgICAgWFNUeXBlRGVmaW5pdGlvbiB0eXBlID0gdGhpczsKLSAgICAgICAgd2hpbGUgKCEoYW5jZXN0b3JOYW1lLmVxdWFscyh0eXBlLmdldE5hbWUoKSkgJiYKLSAgICAgICAgICAgICAgICAoKGFuY2VzdG9yTlMgPT0gbnVsbCAmJiB0eXBlLmdldE5hbWVzcGFjZSgpID09IG51bGwpIHx8Ci0gICAgICAgICAgICAgICAgICAgICAgICAoYW5jZXN0b3JOUyAhPSBudWxsICYmIGFuY2VzdG9yTlMuZXF1YWxzKHR5cGUuZ2V0TmFtZXNwYWNlKCkpKSkpICYmICAgLy8gY29tcGFyZSB3aXRoIGFuY2VzdG9yCi0gICAgICAgICAgICAgICAgICAgICAgICB0eXBlICE9IGZBbnlTaW1wbGVUeXBlKSB7ICAvLyByZWFjaGVkIGFueVNpbXBsZVR5cGUKLSAgICAgICAgICAgIHR5cGUgPSAoWFNUeXBlRGVmaW5pdGlvbil0eXBlLmdldEJhc2VUeXBlKCk7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gdHlwZSAhPSBmQW55U2ltcGxlVHlwZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDaGVja3MgaWYgYSB0eXBlIGlzIGRlcml2ZWQgZnJvbSBhbm90aGVyIGJ5IHJlc3RyaWN0aW9uLCBnaXZlbiB0aGUgbmFtZQotICAgICAqIGFuZCBuYW1lc3BhY2UuIFNlZToKLSAgICAgKiBodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy1ET00tTGV2ZWwtMy1Db3JlLTIwMDQwNDA3L2NvcmUuaHRtbCNUeXBlSW5mby1pc0Rlcml2ZWRGcm9tCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYW5jZXN0b3JOUwotICAgICAqICAgICAgICAgICAgVGhlIG5hbXNwYWNlIG9mIHRoZSBhbmNlc3RvciB0eXBlIGRlY2xhcmF0aW9uCi0gICAgICogQHBhcmFtIGFuY2VzdG9yTmFtZQotICAgICAqICAgICAgICAgICAgVGhlIG5hbWUgb2YgdGhlIGFuY2VzdG9yIHR5cGUgZGVjbGFyYXRpb24KLSAgICAgKiBAcGFyYW0gZGVyaXZhdGlvbk1ldGhvZAotICAgICAqICAgICAgICAgICAgVGhlIGRlcml2YXRpb24gbWV0aG9kCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIGJvb2xlYW4gVHJ1ZSBpZiB0aGUgYW5jZXN0b3IgdHlwZSBpcyBkZXJpdmVkIGZyb20gdGhlIHJlZmVyZW5jZSB0eXBlIGJ5IHRoZSBzcGVjaWZpaWVkIGRlcml2YXRpb24gbWV0aG9kLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzRE9NRGVyaXZlZEZyb20oU3RyaW5nIGFuY2VzdG9yTlMsIFN0cmluZyBhbmNlc3Rvck5hbWUsIGludCBkZXJpdmF0aW9uTWV0aG9kKSB7Ci0KLSAgICAgICAgLy8gYW5jZXN0b3IgaXMgbnVsbCwgcmV0dXJuIGZhbHNlCi0gICAgICAgIGlmIChhbmNlc3Rvck5hbWUgPT0gbnVsbCkKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLQotICAgICAgICAvLyBhbmNlc3RvciBpcyBhbnlUeXBlLCByZXR1cm4gdHJ1ZQotICAgICAgICBpZiAoU2NoZW1hU3ltYm9scy5VUklfU0NIRU1BRk9SU0NIRU1BLmVxdWFscyhhbmNlc3Rvck5TKQotICAgICAgICAgICAgICAgICYmIFNjaGVtYVN5bWJvbHMuQVRUVkFMX0FOWVRZUEUuZXF1YWxzKGFuY2VzdG9yTmFtZSkKLSAgICAgICAgICAgICAgICAmJiAoKChkZXJpdmF0aW9uTWV0aG9kICAmIERFUklWQVRJT05fUkVTVFJJQ1RJT04pICE9IDApCi0gICAgICAgICAgICAgICAgICAgICAgICB8fCAoZGVyaXZhdGlvbk1ldGhvZCAgPT0gREVSSVZBVElPTl9BTlkpKSkgewotICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyByZXN0cmljdGlvbgotICAgICAgICBpZiAoKGRlcml2YXRpb25NZXRob2QgJiBERVJJVkFUSU9OX1JFU1RSSUNUSU9OKSAhPSAwKSB7Ci0gICAgICAgICAgICBpZiAoaXNEZXJpdmVkQnlSZXN0cmljdGlvbihhbmNlc3Rvck5TLCBhbmNlc3Rvck5hbWUsIHRoaXMpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBsaXN0Ci0gICAgICAgIGlmICgoZGVyaXZhdGlvbk1ldGhvZCAmIERFUklWQVRJT05fTElTVCkgIT0gMCkgewotICAgICAgICAgICAgaWYgKGlzRGVyaXZlZEJ5TGlzdChhbmNlc3Rvck5TLCBhbmNlc3Rvck5hbWUsIHRoaXMpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyB1bmlvbgotICAgICAgICBpZiAoKGRlcml2YXRpb25NZXRob2QgJiBERVJJVkFUSU9OX1VOSU9OKSAhPSAwKSB7Ci0gICAgICAgICAgICBpZiAoaXNEZXJpdmVkQnlVbmlvbihhbmNlc3Rvck5TLCBhbmNlc3Rvck5hbWUsIHRoaXMpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBleHRlbnNpb24KLSAgICAgICAgaWYgKCgoZGVyaXZhdGlvbk1ldGhvZCAmIERFUklWQVRJT05fRVhURU5TSU9OKSAhPSAwKQotICAgICAgICAgICAgICAgICYmICgoKGRlcml2YXRpb25NZXRob2QgJiBERVJJVkFUSU9OX1JFU1RSSUNUSU9OKSA9PSAwKQotICAgICAgICAgICAgICAgICAgICAgICAgJiYgKChkZXJpdmF0aW9uTWV0aG9kICYgREVSSVZBVElPTl9MSVNUKSA9PSAwKQotICAgICAgICAgICAgICAgICAgICAgICAgJiYgKChkZXJpdmF0aW9uTWV0aG9kICYgREVSSVZBVElPTl9VTklPTikgPT0gMCkpKSB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBJZiB0aGUgdmFsdWUgb2YgdGhlIHBhcmFtZXRlciBpcyAwIGkuZS4gbm8gYml0IChjb3JyZXNwb25kaW5nIHRvCi0gICAgICAgIC8vIHJlc3RyaWN0aW9uLCBsaXN0LCBleHRlbnNpb24gb3IgdW5pb24pIGlzIHNldCB0byAxIGZvciB0aGUKLSAgICAgICAgLy8gZGVyaXZhdGlvbk1ldGhvZCBwYXJhbWV0ZXIuCi0gICAgICAgIGlmICgoKGRlcml2YXRpb25NZXRob2QgJiBERVJJVkFUSU9OX0VYVEVOU0lPTikgPT0gMCkKLSAgICAgICAgICAgICAgICAmJiAoKChkZXJpdmF0aW9uTWV0aG9kICYgREVSSVZBVElPTl9SRVNUUklDVElPTikgPT0gMCkKLSAgICAgICAgICAgICAgICAgICAgICAgICYmICgoZGVyaXZhdGlvbk1ldGhvZCAmIERFUklWQVRJT05fTElTVCkgPT0gMCkKLSAgICAgICAgICAgICAgICAgICAgICAgICYmICgoZGVyaXZhdGlvbk1ldGhvZCAmIERFUklWQVRJT05fVU5JT04pID09IDApKSkgewotICAgICAgICAgICAgcmV0dXJuIGlzRGVyaXZlZEJ5QW55KGFuY2VzdG9yTlMsIGFuY2VzdG9yTmFtZSwgdGhpcyk7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBDaGVja3MgaWYgYSB0eXBlIGlzIGRlcml2ZWQgZnJvbSBhbm90aGVyIGJ5IGFueSBjb21iaW5hdGlvbiBvZiByZXN0cmljdGlvbiwgbGlzdCBpciB1bmlvbi4gU2VlOgotICAgICAqIGh0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLURPTS1MZXZlbC0zLUNvcmUtMjAwNDA0MDcvY29yZS5odG1sI1R5cGVJbmZvLWlzRGVyaXZlZEZyb20KLSAgICAgKgotICAgICAqIEBwYXJhbSBhbmNlc3Rvck5TCi0gICAgICogICAgICAgICAgICBUaGUgbmFtc3BhY2Ugb2YgdGhlIGFuY2VzdG9yIHR5cGUgZGVjbGFyYXRpb24KLSAgICAgKiBAcGFyYW0gYW5jZXN0b3JOYW1lCi0gICAgICogICAgICAgICAgICBUaGUgbmFtZSBvZiB0aGUgYW5jZXN0b3IgdHlwZSBkZWNsYXJhdGlvbgotICAgICAqIEBwYXJhbSB0eXBlCi0gICAgICogICAgICAgICAgICBUaGUgcmVmZXJlbmNlIHR5cGUgZGVmaW5pdGlvbgotICAgICAqCi0gICAgICogQHJldHVybiBib29sZWFuIFRydWUgaWYgdGhlIHR5cGUgaXMgZGVyaXZlZCBieSByZXN0cmljaXRvbiBmb3IgdGhlIHJlZmVyZW5jZSB0eXBlCi0gICAgICovCi0gICAgcHJpdmF0ZSBib29sZWFuIGlzRGVyaXZlZEJ5QW55KFN0cmluZyBhbmNlc3Rvck5TLCBTdHJpbmcgYW5jZXN0b3JOYW1lLAotICAgICAgICAgICAgWFNUeXBlRGVmaW5pdGlvbiB0eXBlKSB7Ci0KLSAgICAgICAgYm9vbGVhbiBkZXJpdmVkRnJvbSA9IGZhbHNlOwotICAgICAgICBYU1R5cGVEZWZpbml0aW9uIG9sZFR5cGUgPSBudWxsOwotICAgICAgICAvLyBmb3IgZWFjaCBiYXNlLCBpdGVtIG9yIG1lbWJlciB0eXBlCi0gICAgICAgIHdoaWxlICh0eXBlICE9IG51bGwgJiYgdHlwZSAhPSBvbGRUeXBlKSAgewotCi0gICAgICAgICAgICAvLyBJZiB0aGUgYW5jZXN0b3IgdHlwZSBpcyByZWFjaGVkIG9yIGlzIHRoZSBzYW1lIGFzIHRoaXMgdHlwZS4KLSAgICAgICAgICAgIGlmICgoYW5jZXN0b3JOYW1lLmVxdWFscyh0eXBlLmdldE5hbWUoKSkpCi0gICAgICAgICAgICAgICAgICAgICYmICgoYW5jZXN0b3JOUyA9PSBudWxsICYmIHR5cGUuZ2V0TmFtZXNwYWNlKCkgPT0gbnVsbCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCAoYW5jZXN0b3JOUyAhPSBudWxsICYmIGFuY2VzdG9yTlMuZXF1YWxzKHR5cGUuZ2V0TmFtZXNwYWNlKCkpKSkpIHsKLSAgICAgICAgICAgICAgICBkZXJpdmVkRnJvbSA9IHRydWU7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIGNoZWNrIGlmIGRlcml2ZWQgYnkgcmVzdHJpY3Rpb24gb3IgbGlzdCBvciB1bmlvbgotICAgICAgICAgICAgaWYgKGlzRGVyaXZlZEJ5UmVzdHJpY3Rpb24oYW5jZXN0b3JOUywgYW5jZXN0b3JOYW1lLCB0eXBlKSkgewotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgfSBlbHNlIGlmIChpc0Rlcml2ZWRCeUxpc3QoYW5jZXN0b3JOUywgYW5jZXN0b3JOYW1lLCB0eXBlKSkgewotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgfSBlbHNlICBpZiAoaXNEZXJpdmVkQnlVbmlvbihhbmNlc3Rvck5TLCBhbmNlc3Rvck5hbWUsIHR5cGUpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBvbGRUeXBlID0gdHlwZTsKLSAgICAgICAgICAgIC8vIGdldCB0aGUgYmFzZSwgaXRlbSBvciBtZW1iZXIgdHlwZSBkZXBlbmRpbmcgb24gdGhlIHZhcmlldHkKLSAgICAgICAgICAgIGlmICgoKFhTU2ltcGxlVHlwZURlY2wpIHR5cGUpLmdldFZhcmlldHkoKSA9PSBWQVJJRVRZX0FCU0VOVAotICAgICAgICAgICAgICAgICAgICB8fCAoKFhTU2ltcGxlVHlwZURlY2wpIHR5cGUpLmdldFZhcmlldHkoKSA9PSBWQVJJRVRZX0FUT01JQykgewotICAgICAgICAgICAgICAgIHR5cGUgPSB0eXBlLmdldEJhc2VUeXBlKCk7Ci0gICAgICAgICAgICB9IGVsc2UgaWYgKCgoWFNTaW1wbGVUeXBlRGVjbCkgdHlwZSkuZ2V0VmFyaWV0eSgpID09IFZBUklFVFlfVU5JT04pIHsKLSAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8ICgoWFNTaW1wbGVUeXBlRGVjbCkgdHlwZSkuZ2V0TWVtYmVyVHlwZXMoKS5nZXRMZW5ndGgoKTsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBpc0Rlcml2ZWRCeUFueShhbmNlc3Rvck5TLCBhbmNlc3Rvck5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgKFhTVHlwZURlZmluaXRpb24pICgoWFNTaW1wbGVUeXBlRGVjbCkgdHlwZSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0TWVtYmVyVHlwZXMoKS5pdGVtKGkpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9IGVsc2UgaWYgKCgoWFNTaW1wbGVUeXBlRGVjbCkgdHlwZSkuZ2V0VmFyaWV0eSgpID09IFZBUklFVFlfTElTVCkgewotICAgICAgICAgICAgICAgIHR5cGUgPSAoKFhTU2ltcGxlVHlwZURlY2wpIHR5cGUpLmdldEl0ZW1UeXBlKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gZGVyaXZlZEZyb207Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRE9NIExldmVsIDMKLSAgICAgKiBDaGVja3MgaWYgYSB0eXBlIGlzIGRlcml2ZWQgZnJvbSBhbm90aGVyIGJ5IHJlc3RyaWN0aW9uLiBTZWU6Ci0gICAgICogaHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMtRE9NLUxldmVsLTMtQ29yZS0yMDA0MDQwNy9jb3JlLmh0bWwjVHlwZUluZm8taXNEZXJpdmVkRnJvbQotICAgICAqCi0gICAgICogQHBhcmFtIGFuY2VzdG9yTlMKLSAgICAgKiAgICAgICAgICAgIFRoZSBuYW1zcGFjZSBvZiB0aGUgYW5jZXN0b3IgdHlwZSBkZWNsYXJhdGlvbgotICAgICAqIEBwYXJhbSBhbmNlc3Rvck5hbWUKLSAgICAgKiAgICAgICAgICAgIFRoZSBuYW1lIG9mIHRoZSBhbmNlc3RvciB0eXBlIGRlY2xhcmF0aW9uCi0gICAgICogQHBhcmFtIHR5cGUKLSAgICAgKiAgICAgICAgICAgIFRoZSByZWZlcmVuY2UgdHlwZSBkZWZpbml0aW9uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIGJvb2xlYW4gVHJ1ZSBpZiB0aGUgdHlwZSBpcyBkZXJpdmVkIGJ5IHJlc3RyaWNpdG9uIGZvciB0aGUKLSAgICAgKiAgICAgICAgIHJlZmVyZW5jZSB0eXBlCi0gICAgICovCi0gICAgcHJpdmF0ZSBib29sZWFuIGlzRGVyaXZlZEJ5UmVzdHJpY3Rpb24gKFN0cmluZyBhbmNlc3Rvck5TLCBTdHJpbmcgYW5jZXN0b3JOYW1lLCBYU1R5cGVEZWZpbml0aW9uIHR5cGUpIHsKLSAgICAgICAgWFNUeXBlRGVmaW5pdGlvbiBvbGRUeXBlID0gbnVsbDsKLSAgICAgICAgd2hpbGUgKHR5cGUgIT0gbnVsbCAmJiB0eXBlICE9IG9sZFR5cGUpIHsKLSAgICAgICAgICAgIGlmICgoYW5jZXN0b3JOYW1lLmVxdWFscyh0eXBlLmdldE5hbWUoKSkpCi0gICAgICAgICAgICAgICAgICAgICYmICgoYW5jZXN0b3JOUyAhPSBudWxsICYmIGFuY2VzdG9yTlMuZXF1YWxzKHR5cGUuZ2V0TmFtZXNwYWNlKCkpKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8ICh0eXBlLmdldE5hbWVzcGFjZSgpID09IG51bGwgJiYgYW5jZXN0b3JOUyA9PSBudWxsKSkpIHsKLQotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgb2xkVHlwZSA9IHR5cGU7Ci0gICAgICAgICAgICB0eXBlID0gdHlwZS5nZXRCYXNlVHlwZSgpOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENoZWNrcyBpZiBhIHR5cGUgaXMgZGVyaXZlZCBmcm9tIGFub3RoZXIgYnkgbGlzdC4gU2VlOgotICAgICAqIGh0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLURPTS1MZXZlbC0zLUNvcmUtMjAwNDA0MDcvY29yZS5odG1sI1R5cGVJbmZvLWlzRGVyaXZlZEZyb20KLSAgICAgKgotICAgICAqIEBwYXJhbSBhbmNlc3Rvck5TCi0gICAgICogICAgICAgICAgICBUaGUgbmFtc3BhY2Ugb2YgdGhlIGFuY2VzdG9yIHR5cGUgZGVjbGFyYXRpb24KLSAgICAgKiBAcGFyYW0gYW5jZXN0b3JOYW1lCi0gICAgICogICAgICAgICAgICBUaGUgbmFtZSBvZiB0aGUgYW5jZXN0b3IgdHlwZSBkZWNsYXJhdGlvbgotICAgICAqIEBwYXJhbSB0eXBlCi0gICAgICogICAgICAgICAgICBUaGUgcmVmZXJlbmNlIHR5cGUgZGVmaW5pdGlvbgotICAgICAqCi0gICAgICogQHJldHVybiBib29sZWFuIFRydWUgaWYgdGhlIHR5cGUgaXMgZGVyaXZlZCBieSBsaXN0IGZvciB0aGUgcmVmZXJlbmNlIHR5cGUKLSAgICAgKi8KLSAgICBwcml2YXRlIGJvb2xlYW4gaXNEZXJpdmVkQnlMaXN0IChTdHJpbmcgYW5jZXN0b3JOUywgU3RyaW5nIGFuY2VzdG9yTmFtZSwgWFNUeXBlRGVmaW5pdGlvbiB0eXBlKSB7Ci0gICAgICAgIC8vIElmIHRoZSB2YXJpZXR5IGlzIHVuaW9uCi0gICAgICAgIGlmICh0eXBlICE9bnVsbCAmJiAoKFhTU2ltcGxlVHlwZURlZmluaXRpb24pdHlwZSkuZ2V0VmFyaWV0eSgpID09IFZBUklFVFlfTElTVCkgewotCi0gICAgICAgICAgICAvLyBnZXQgdGhlIHtpdGVtIHR5cGV9Ci0gICAgICAgICAgICBYU1R5cGVEZWZpbml0aW9uIGl0ZW1UeXBlID0gKChYU1NpbXBsZVR5cGVEZWZpbml0aW9uKXR5cGUpLmdldEl0ZW1UeXBlKCk7Ci0KLSAgICAgICAgICAgIC8vIFQyIGlzIHRoZSB7aXRlbSB0eXBlIGRlZmluaXRpb259Ci0gICAgICAgICAgICBpZiAoaXRlbVR5cGUgIT0gbnVsbCkgewotCi0gICAgICAgICAgICAgICAgLy8gVDIgaXMgZGVyaXZlZCBmcm9tIHRoZSBvdGhlciB0eXBlIGRlZmluaXRpb24gYnkgREVSSVZBVElPTl9SRVNUUklDVElPTgotICAgICAgICAgICAgICAgIGlmIChpc0Rlcml2ZWRCeVJlc3RyaWN0aW9uKGFuY2VzdG9yTlMsIGFuY2VzdG9yTmFtZSwgaXRlbVR5cGUpKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ2hlY2tzIGlmIGEgdHlwZSBpcyBkZXJpdmVkIGZyb20gYW5vdGhlciBieSB1bmlvbi4gIFNlZToKLSAgICAgKiBodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy1ET00tTGV2ZWwtMy1Db3JlLTIwMDQwNDA3L2NvcmUuaHRtbCNUeXBlSW5mby1pc0Rlcml2ZWRGcm9tCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYW5jZXN0b3JOUwotICAgICAqICAgICAgICAgICAgVGhlIG5hbXNwYWNlIG9mIHRoZSBhbmNlc3RvciB0eXBlIGRlY2xhcmF0aW9uCi0gICAgICogQHBhcmFtIGFuY2VzdG9yTmFtZQotICAgICAqICAgICAgICAgICAgVGhlIG5hbWUgb2YgdGhlIGFuY2VzdG9yIHR5cGUgZGVjbGFyYXRpb24KLSAgICAgKiBAcGFyYW0gdHlwZQotICAgICAqICAgICAgICAgICAgVGhlIHJlZmVyZW5jZSB0eXBlIGRlZmluaXRpb24KLSAgICAgKgotICAgICAqIEByZXR1cm4gYm9vbGVhbiBUcnVlIGlmIHRoZSB0eXBlIGlzIGRlcml2ZWQgYnkgdW5pb24gZm9yIHRoZSByZWZlcmVuY2UgdHlwZQotICAgICAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBpc0Rlcml2ZWRCeVVuaW9uIChTdHJpbmcgYW5jZXN0b3JOUywgU3RyaW5nIGFuY2VzdG9yTmFtZSwgWFNUeXBlRGVmaW5pdGlvbiB0eXBlKSB7Ci0KLSAgICAgICAgLy8gSWYgdGhlIHZhcmlldHkgaXMgdW5pb24KLSAgICAgICAgaWYgKHR5cGUgIT1udWxsICYmICgoWFNTaW1wbGVUeXBlRGVmaW5pdGlvbil0eXBlKS5nZXRWYXJpZXR5KCkgPT0gVkFSSUVUWV9VTklPTikgewotCi0gICAgICAgICAgICAvLyBnZXQgbWVtYmVyIHR5cGVzCi0gICAgICAgICAgICBYU09iamVjdExpc3QgbWVtYmVyVHlwZXMgPSAoKFhTU2ltcGxlVHlwZURlZmluaXRpb24pdHlwZSkuZ2V0TWVtYmVyVHlwZXMoKTsKLQotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtZW1iZXJUeXBlcy5nZXRMZW5ndGgoKTsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgLy8gT25lIG9mIHRoZSB7bWVtYmVyIHR5cGUgZGVmaW5pdGlvbnN9IGlzIFQyLgotICAgICAgICAgICAgICAgIGlmIChtZW1iZXJUeXBlcy5pdGVtKGkpICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gVDIgaXMgZGVyaXZlZCBmcm9tIHRoZSBvdGhlciB0eXBlIGRlZmluaXRpb24gYnkgREVSSVZBVElPTl9SRVNUUklDVElPTgotICAgICAgICAgICAgICAgICAgICBpZiAoaXNEZXJpdmVkQnlSZXN0cmljdGlvbihhbmNlc3Rvck5TLCBhbmNlc3Rvck5hbWUsKFhTU2ltcGxlVHlwZURlZmluaXRpb24pbWVtYmVyVHlwZXMuaXRlbShpKSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLQotICAgIHN0YXRpYyBmaW5hbCBYU1NpbXBsZVR5cGVEZWNsIGZBbnlTaW1wbGVUeXBlID0gbmV3IFhTU2ltcGxlVHlwZURlY2wobnVsbCwgImFueVNpbXBsZVR5cGUiLCBEVl9BTllTSU1QTEVUWVBFLCBPUkRFUkVEX0ZBTFNFLCBmYWxzZSwgdHJ1ZSwgZmFsc2UsIHRydWUsIFhTQ29uc3RhbnRzLkFOWVNJTVBMRVRZUEVfRFQpOwotCi0gICAgc3RhdGljIGZpbmFsIFhTU2ltcGxlVHlwZURlY2wgZkFueUF0b21pY1R5cGUgPSBuZXcgWFNTaW1wbGVUeXBlRGVjbChmQW55U2ltcGxlVHlwZSwgImFueUF0b21pY1R5cGUiLCBEVl9BTllBVE9NSUNUWVBFLCBPUkRFUkVEX0ZBTFNFLCBmYWxzZSwgdHJ1ZSwgZmFsc2UsIHRydWUsIFhTU2ltcGxlVHlwZURlY2wuQU5ZQVRPTUlDVFlQRV9EVCk7Ci0KLSAgICAvKioKLSAgICAgKiBWYWxpZGF0aW9uIGNvbnRleHQgdXNlZCB0byB2YWxpZGF0ZSBmYWNldCB2YWx1ZXMuCi0gICAgICovCi0gICAgc3RhdGljIGZpbmFsIFZhbGlkYXRpb25Db250ZXh0IGZEdW1teUNvbnRleHQgPSBuZXcgVmFsaWRhdGlvbkNvbnRleHQoKSB7Ci0gICAgICAgIHB1YmxpYyBib29sZWFuIG5lZWRGYWNldENoZWNraW5nKCkgewotICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgYm9vbGVhbiBuZWVkRXh0cmFDaGVja2luZygpIHsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotICAgICAgICBwdWJsaWMgYm9vbGVhbiBuZWVkVG9Ob3JtYWxpemUoKSB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLSAgICAgICAgcHVibGljIGJvb2xlYW4gdXNlTmFtZXNwYWNlcygpIHsKLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIGJvb2xlYW4gaXNFbnRpdHlEZWNsYXJlZChTdHJpbmcgbmFtZSkgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIGJvb2xlYW4gaXNFbnRpdHlVbnBhcnNlZChTdHJpbmcgbmFtZSkgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIGJvb2xlYW4gaXNJZERlY2xhcmVkKFN0cmluZyBuYW1lKSB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCBhZGRJZChTdHJpbmcgbmFtZSkgewotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIHZvaWQgYWRkSWRSZWYoU3RyaW5nIG5hbWUpIHsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3ltYm9sIChTdHJpbmcgc3ltYm9sKSB7Ci0gICAgICAgICAgICByZXR1cm4gc3ltYm9sLmludGVybigpOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIFN0cmluZyBnZXRVUkkoU3RyaW5nIHByZWZpeCkgewotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgTG9jYWxlIGdldExvY2FsZSgpIHsKLSAgICAgICAgICAgIHJldHVybiBMb2NhbGUuZ2V0RGVmYXVsdCgpOwotICAgICAgICB9Ci0gICAgfTsKLQotICAgIHByaXZhdGUgYm9vbGVhbiBmQW5vbnltb3VzID0gZmFsc2U7Ci0KLSAgICAvKioKLSAgICAgKiBBIHdyYXBwZXIgb2YgVmFsaWRhdGlvbkNvbnRleHQsIHRvIHByb3ZpZGUgYSB3YXkgb2Ygc3dpdGNoaW5nIHRvIGEKLSAgICAgKiBkaWZmZXJlbnQgTmFtZXNwYWNlIGRlY2xhcmF0aW9uIGNvbnRleHQuCi0gICAgICovCi0gICAgc3RhdGljIGZpbmFsIGNsYXNzIFZhbGlkYXRpb25Db250ZXh0SW1wbCBpbXBsZW1lbnRzIFZhbGlkYXRpb25Db250ZXh0IHsKLQotICAgICAgICBmaW5hbCBWYWxpZGF0aW9uQ29udGV4dCBmRXh0ZXJuYWw7Ci0KLSAgICAgICAgVmFsaWRhdGlvbkNvbnRleHRJbXBsKFZhbGlkYXRpb25Db250ZXh0IGV4dGVybmFsKSB7Ci0gICAgICAgICAgICBmRXh0ZXJuYWwgPSBleHRlcm5hbDsKLSAgICAgICAgfQotCi0gICAgICAgIE5hbWVzcGFjZUNvbnRleHQgZk5TQ29udGV4dDsKLSAgICAgICAgdm9pZCBzZXROU0NvbnRleHQoTmFtZXNwYWNlQ29udGV4dCBuc0NvbnRleHQpIHsKLSAgICAgICAgICAgIGZOU0NvbnRleHQgPSBuc0NvbnRleHQ7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgYm9vbGVhbiBuZWVkRmFjZXRDaGVja2luZygpIHsKLSAgICAgICAgICAgIHJldHVybiBmRXh0ZXJuYWwubmVlZEZhY2V0Q2hlY2tpbmcoKTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyBib29sZWFuIG5lZWRFeHRyYUNoZWNraW5nKCkgewotICAgICAgICAgICAgcmV0dXJuIGZFeHRlcm5hbC5uZWVkRXh0cmFDaGVja2luZygpOwotICAgICAgICB9Ci0gICAgICAgIHB1YmxpYyBib29sZWFuIG5lZWRUb05vcm1hbGl6ZSgpIHsKLSAgICAgICAgICAgIHJldHVybiBmRXh0ZXJuYWwubmVlZFRvTm9ybWFsaXplKCk7Ci0gICAgICAgIH0KLSAgICAgICAgLy8gc2NoZW1hIHZhbGlkYXRpb24gaXMgcHJlZGljYXRlZCB1cG9uIG5hbWVzcGFjZXMKLSAgICAgICAgcHVibGljIGJvb2xlYW4gdXNlTmFtZXNwYWNlcygpIHsKLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIGJvb2xlYW4gaXNFbnRpdHlEZWNsYXJlZCAoU3RyaW5nIG5hbWUpIHsKLSAgICAgICAgICAgIHJldHVybiBmRXh0ZXJuYWwuaXNFbnRpdHlEZWNsYXJlZChuYW1lKTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyBib29sZWFuIGlzRW50aXR5VW5wYXJzZWQgKFN0cmluZyBuYW1lKSB7Ci0gICAgICAgICAgICByZXR1cm4gZkV4dGVybmFsLmlzRW50aXR5VW5wYXJzZWQobmFtZSk7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc0lkRGVjbGFyZWQgKFN0cmluZyBuYW1lKSB7Ci0gICAgICAgICAgICByZXR1cm4gZkV4dGVybmFsLmlzSWREZWNsYXJlZChuYW1lKTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyB2b2lkIGFkZElkKFN0cmluZyBuYW1lKSB7Ci0gICAgICAgICAgICBmRXh0ZXJuYWwuYWRkSWQobmFtZSk7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCBhZGRJZFJlZihTdHJpbmcgbmFtZSkgewotICAgICAgICAgICAgZkV4dGVybmFsLmFkZElkUmVmKG5hbWUpOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIFN0cmluZyBnZXRTeW1ib2wgKFN0cmluZyBzeW1ib2wpIHsKLSAgICAgICAgICAgIHJldHVybiBmRXh0ZXJuYWwuZ2V0U3ltYm9sKHN5bWJvbCk7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFVSSShTdHJpbmcgcHJlZml4KSB7Ci0gICAgICAgICAgICBpZiAoZk5TQ29udGV4dCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZFeHRlcm5hbC5nZXRVUkkocHJlZml4KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIHJldHVybiBmTlNDb250ZXh0LmdldFVSSShwcmVmaXgpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIExvY2FsZSBnZXRMb2NhbGUoKSB7Ci0gICAgICAgICAgICByZXR1cm4gZkV4dGVybmFsLmdldExvY2FsZSgpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgcmVzZXQoKXsKLQotICAgICAgICAvLyBpZiBpdCdzIGltbXV0YWJsZSwgY2FuJ3QgYmUgcmVzZXQ6Ci0gICAgICAgIGlmIChmSXNJbW11dGFibGUpIHJldHVybjsKLSAgICAgICAgZkl0ZW1UeXBlID0gbnVsbDsKLSAgICAgICAgZk1lbWJlclR5cGVzID0gbnVsbDsKLQotICAgICAgICBmVHlwZU5hbWUgPSBudWxsOwotICAgICAgICBmVGFyZ2V0TmFtZXNwYWNlID0gbnVsbDsKLSAgICAgICAgZkZpbmFsU2V0ID0gMDsKLSAgICAgICAgZkJhc2UgPSBudWxsOwotICAgICAgICBmVmFyaWV0eSA9IC0xOwotICAgICAgICBmVmFsaWRhdGlvbkRWID0gLTE7Ci0KLSAgICAgICAgZkZhY2V0c0RlZmluZWQgPSAwOwotICAgICAgICBmRml4ZWRGYWNldCA9IDA7Ci0KLSAgICAgICAgLy9mb3IgY29uc3RyYWluaW5nIGZhY2V0cwotICAgICAgICBmV2hpdGVTcGFjZSA9IDA7Ci0gICAgICAgIGZMZW5ndGggPSAtMTsKLSAgICAgICAgZk1pbkxlbmd0aCA9IC0xOwotICAgICAgICBmTWF4TGVuZ3RoID0gLTE7Ci0gICAgICAgIGZUb3RhbERpZ2l0cyA9IC0xOwotICAgICAgICBmRnJhY3Rpb25EaWdpdHMgPSAtMTsKLSAgICAgICAgZlBhdHRlcm4gPSBudWxsOwotICAgICAgICBmUGF0dGVyblN0ciA9IG51bGw7Ci0gICAgICAgIGZFbnVtZXJhdGlvbiA9IG51bGw7Ci0gICAgICAgIGZFbnVtZXJhdGlvblR5cGUgPSBudWxsOwotICAgICAgICBmRW51bWVyYXRpb25JdGVtVHlwZSA9IG51bGw7Ci0gICAgICAgIGZMZXhpY2FsUGF0dGVybiA9IG51bGw7Ci0gICAgICAgIGZMZXhpY2FsRW51bWVyYXRpb24gPSBudWxsOwotICAgICAgICBmTWF4SW5jbHVzaXZlID0gbnVsbDsKLSAgICAgICAgZk1heEV4Y2x1c2l2ZSA9IG51bGw7Ci0gICAgICAgIGZNaW5FeGNsdXNpdmUgPSBudWxsOwotICAgICAgICBmTWluSW5jbHVzaXZlID0gbnVsbDsKLSAgICAgICAgbGVuZ3RoQW5ub3RhdGlvbiA9IG51bGw7Ci0gICAgICAgIG1pbkxlbmd0aEFubm90YXRpb24gPSBudWxsOwotICAgICAgICBtYXhMZW5ndGhBbm5vdGF0aW9uID0gbnVsbDsKLSAgICAgICAgd2hpdGVTcGFjZUFubm90YXRpb24gPSBudWxsOwotICAgICAgICB0b3RhbERpZ2l0c0Fubm90YXRpb24gPSBudWxsOwotICAgICAgICBmcmFjdGlvbkRpZ2l0c0Fubm90YXRpb24gPSBudWxsOwotICAgICAgICBwYXR0ZXJuQW5ub3RhdGlvbnMgPSBudWxsOwotICAgICAgICBlbnVtZXJhdGlvbkFubm90YXRpb25zID0gbnVsbDsKLSAgICAgICAgbWF4SW5jbHVzaXZlQW5ub3RhdGlvbiA9IG51bGw7Ci0gICAgICAgIG1heEV4Y2x1c2l2ZUFubm90YXRpb24gPSBudWxsOwotICAgICAgICBtaW5JbmNsdXNpdmVBbm5vdGF0aW9uID0gbnVsbDsKLSAgICAgICAgbWluRXhjbHVzaXZlQW5ub3RhdGlvbiA9IG51bGw7Ci0KLSAgICAgICAgZlBhdHRlcm5UeXBlID0gU1BFQ0lBTF9QQVRURVJOX05PTkU7Ci0gICAgICAgIGZBbm5vdGF0aW9ucyA9IG51bGw7Ci0gICAgICAgIGZGYWNldHMgPSBudWxsOwotCi0gICAgICAgIC8vIFJFVklTSVQ6IHJlc2V0IGZvciBmdW5kYW1lbnRhbCBmYWNldHMKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNPYmplY3QjZ2V0TmFtZXNwYWNlSXRlbSgpCi0gICAgICovCi0gICAgcHVibGljIFhTTmFtZXNwYWNlSXRlbSBnZXROYW1lc3BhY2VJdGVtKCkgewotICAgICAgICByZXR1cm4gZk5hbWVzcGFjZUl0ZW07Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0TmFtZXNwYWNlSXRlbShYU05hbWVzcGFjZUl0ZW0gbmFtZXNwYWNlSXRlbSkgewotICAgICAgICBmTmFtZXNwYWNlSXRlbSA9IG5hbWVzcGFjZUl0ZW07Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBqYXZhLmxhbmcuT2JqZWN0I3RvU3RyaW5nKCkKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgICAgICByZXR1cm4gdGhpcy5mVGFyZ2V0TmFtZXNwYWNlKyIsIiArdGhpcy5mVHlwZU5hbWU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogIEEgbGlzdCBvZiBjb25zdHJhaW5pbmcgZmFjZXRzIGlmIGl0IGV4aXN0cywgb3RoZXJ3aXNlIGFuIGVtcHR5Ci0gICAgICogPGNvZGU+WFNPYmplY3RMaXN0PC9jb2RlPi4gTm90ZTogVGhpcyBtZXRob2QgbXVzdCBub3QgYmUgdXNlZCB0bwotICAgICAqIHJldHJpZXZlIHZhbHVlcyBmb3IgPGNvZGU+ZW51bWVyYXRpb248L2NvZGU+IGFuZCA8Y29kZT5wYXR0ZXJuPC9jb2RlPgotICAgICAqIGZhY2V0cy4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFNPYmplY3RMaXN0IGdldEZhY2V0cygpIHsKLSAgICAgICAgaWYgKGZGYWNldHMgPT0gbnVsbCAmJgotICAgICAgICAgICAgICAgIChmRmFjZXRzRGVmaW5lZCAhPSAwIHx8IGZWYWxpZGF0aW9uRFYgPT0gRFZfSU5URUdFUikpIHsKLQotICAgICAgICAgICAgWFNGYWNldEltcGxbXSBmYWNldHMgPSBuZXcgWFNGYWNldEltcGxbMTBdOwotICAgICAgICAgICAgaW50IGNvdW50ID0gMDsKLSAgICAgICAgICAgIGlmICgoZkZhY2V0c0RlZmluZWQgJiBGQUNFVF9XSElURVNQQUNFKSAhPSAwICYmCi0gICAgICAgICAgICAgICAgZlZhbGlkYXRpb25EViAhPSBEVl9BTllTSU1QTEVUWVBFICYmCi0gICAgICAgICAgICAgICAgZlZhbGlkYXRpb25EViAhPSBEVl9BTllBVE9NSUNUWVBFKSB7Ci0gICAgICAgICAgICAgICAgZmFjZXRzW2NvdW50XSA9Ci0gICAgICAgICAgICAgICAgICAgIG5ldyBYU0ZhY2V0SW1wbCgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBGQUNFVF9XSElURVNQQUNFLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdTX0ZBQ0VUX1NUUklOR1tmV2hpdGVTcGFjZV0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGZGaXhlZEZhY2V0ICYgRkFDRVRfV0hJVEVTUEFDRSkgIT0gMCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGl0ZVNwYWNlQW5ub3RhdGlvbik7Ci0gICAgICAgICAgICAgICAgY291bnQrKzsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChmTGVuZ3RoICE9IC0xKSB7Ci0gICAgICAgICAgICAgICAgZmFjZXRzW2NvdW50XSA9Ci0gICAgICAgICAgICAgICAgICAgIG5ldyBYU0ZhY2V0SW1wbCgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBGQUNFVF9MRU5HVEgsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgSW50ZWdlci50b1N0cmluZyhmTGVuZ3RoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZkZpeGVkRmFjZXQgJiBGQUNFVF9MRU5HVEgpICE9IDAsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVuZ3RoQW5ub3RhdGlvbik7Ci0gICAgICAgICAgICAgICAgY291bnQrKzsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChmTWluTGVuZ3RoICE9IC0xKSB7Ci0gICAgICAgICAgICAgICAgZmFjZXRzW2NvdW50XSA9Ci0gICAgICAgICAgICAgICAgICAgIG5ldyBYU0ZhY2V0SW1wbCgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBGQUNFVF9NSU5MRU5HVEgsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgSW50ZWdlci50b1N0cmluZyhmTWluTGVuZ3RoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZkZpeGVkRmFjZXQgJiBGQUNFVF9NSU5MRU5HVEgpICE9IDAsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluTGVuZ3RoQW5ub3RhdGlvbik7Ci0gICAgICAgICAgICAgICAgY291bnQrKzsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChmTWF4TGVuZ3RoICE9IC0xKSB7Ci0gICAgICAgICAgICAgICAgZmFjZXRzW2NvdW50XSA9Ci0gICAgICAgICAgICAgICAgICAgIG5ldyBYU0ZhY2V0SW1wbCgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBGQUNFVF9NQVhMRU5HVEgsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgSW50ZWdlci50b1N0cmluZyhmTWF4TGVuZ3RoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZkZpeGVkRmFjZXQgJiBGQUNFVF9NQVhMRU5HVEgpICE9IDAsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF4TGVuZ3RoQW5ub3RhdGlvbik7Ci0gICAgICAgICAgICAgICAgY291bnQrKzsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChmVG90YWxEaWdpdHMgIT0gLTEpIHsKLSAgICAgICAgICAgICAgICBmYWNldHNbY291bnRdID0KLSAgICAgICAgICAgICAgICAgICAgbmV3IFhTRmFjZXRJbXBsKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZBQ0VUX1RPVEFMRElHSVRTLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIEludGVnZXIudG9TdHJpbmcoZlRvdGFsRGlnaXRzKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZkZpeGVkRmFjZXQgJiBGQUNFVF9UT1RBTERJR0lUUykgIT0gMCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbERpZ2l0c0Fubm90YXRpb24pOwotICAgICAgICAgICAgICAgIGNvdW50Kys7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoZlZhbGlkYXRpb25EViA9PSBEVl9JTlRFR0VSKSB7Ci0gICAgICAgICAgICAgICAgZmFjZXRzW2NvdW50XSA9Ci0gICAgICAgICAgICAgICAgICAgIG5ldyBYU0ZhY2V0SW1wbCgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBGQUNFVF9GUkFDVElPTkRJR0lUUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAiMCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ1ZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcmFjdGlvbkRpZ2l0c0Fubm90YXRpb24pOwotICAgICAgICAgICAgICAgIGNvdW50Kys7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChmRnJhY3Rpb25EaWdpdHMgIT0gLTEpIHsKLSAgICAgICAgICAgICAgICBmYWNldHNbY291bnRdID0KLSAgICAgICAgICAgICAgICAgICAgbmV3IFhTRmFjZXRJbXBsKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZBQ0VUX0ZSQUNUSU9ORElHSVRTLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIEludGVnZXIudG9TdHJpbmcoZkZyYWN0aW9uRGlnaXRzKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZkZpeGVkRmFjZXQgJiBGQUNFVF9GUkFDVElPTkRJR0lUUykgIT0gMCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcmFjdGlvbkRpZ2l0c0Fubm90YXRpb24pOwotICAgICAgICAgICAgICAgIGNvdW50Kys7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoZk1heEluY2x1c2l2ZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZmFjZXRzW2NvdW50XSA9Ci0gICAgICAgICAgICAgICAgICAgIG5ldyBYU0ZhY2V0SW1wbCgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBGQUNFVF9NQVhJTkNMVVNJVkUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZk1heEluY2x1c2l2ZS50b1N0cmluZygpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIChmRml4ZWRGYWNldCAmIEZBQ0VUX01BWElOQ0xVU0lWRSkgIT0gMCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXhJbmNsdXNpdmVBbm5vdGF0aW9uKTsKLSAgICAgICAgICAgICAgICBjb3VudCsrOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKGZNYXhFeGNsdXNpdmUgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZhY2V0c1tjb3VudF0gPQotICAgICAgICAgICAgICAgICAgICBuZXcgWFNGYWNldEltcGwoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgRkFDRVRfTUFYRVhDTFVTSVZFLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZNYXhFeGNsdXNpdmUudG9TdHJpbmcoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZkZpeGVkRmFjZXQgJiBGQUNFVF9NQVhFWENMVVNJVkUpICE9IDAsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF4RXhjbHVzaXZlQW5ub3RhdGlvbik7Ci0gICAgICAgICAgICAgICAgY291bnQrKzsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChmTWluRXhjbHVzaXZlICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmYWNldHNbY291bnRdID0KLSAgICAgICAgICAgICAgICAgICAgbmV3IFhTRmFjZXRJbXBsKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZBQ0VUX01JTkVYQ0xVU0lWRSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmTWluRXhjbHVzaXZlLnRvU3RyaW5nKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGZGaXhlZEZhY2V0ICYgRkFDRVRfTUlORVhDTFVTSVZFKSAhPSAwLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbkV4Y2x1c2l2ZUFubm90YXRpb24pOwotICAgICAgICAgICAgICAgIGNvdW50Kys7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoZk1pbkluY2x1c2l2ZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZmFjZXRzW2NvdW50XSA9Ci0gICAgICAgICAgICAgICAgICAgIG5ldyBYU0ZhY2V0SW1wbCgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBGQUNFVF9NSU5JTkNMVVNJVkUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZk1pbkluY2x1c2l2ZS50b1N0cmluZygpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIChmRml4ZWRGYWNldCAmIEZBQ0VUX01JTklOQ0xVU0lWRSkgIT0gMCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW5JbmNsdXNpdmVBbm5vdGF0aW9uKTsKLSAgICAgICAgICAgICAgICBjb3VudCsrOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZkZhY2V0cyA9IChjb3VudCA+IDApID8gbmV3IFhTT2JqZWN0TGlzdEltcGwoZmFjZXRzLCBjb3VudCkgOiBYU09iamVjdExpc3RJbXBsLkVNUFRZX0xJU1Q7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIChmRmFjZXRzICE9IG51bGwpID8gZkZhY2V0cyA6IFhTT2JqZWN0TGlzdEltcGwuRU1QVFlfTElTVDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiAgQSBsaXN0IG9mIGVudW1lcmF0aW9uIGFuZCBwYXR0ZXJuIGNvbnN0cmFpbmluZyBmYWNldHMgaWYgaXQgZXhpc3RzLAotICAgICAqIG90aGVyd2lzZSBhbiBlbXB0eSA8Y29kZT5YU09iamVjdExpc3Q8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBYU09iamVjdExpc3QgZ2V0TXVsdGlWYWx1ZUZhY2V0cygpIHsKLSAgICAgICAgaWYgKGZNdWx0aVZhbHVlRmFjZXRzID09IG51bGwgJiYKLSAgICAgICAgICAgICAgICAoKGZGYWNldHNEZWZpbmVkICYgRkFDRVRfRU5VTUVSQVRJT04pICE9IDAgfHwKLSAgICAgICAgICAgICAgICAgICAgICAgIChmRmFjZXRzRGVmaW5lZCAmIEZBQ0VUX1BBVFRFUk4pICE9IDAgfHwKLSAgICAgICAgICAgICAgICAgICAgICAgIGZQYXR0ZXJuVHlwZSAhPSBTUEVDSUFMX1BBVFRFUk5fTk9ORSB8fAotICAgICAgICAgICAgICAgICAgICAgICAgZlZhbGlkYXRpb25EViA9PSBEVl9JTlRFR0VSKSkgewotCi0gICAgICAgICAgICBYU01WRmFjZXRJbXBsW10gZmFjZXRzID0gbmV3IFhTTVZGYWNldEltcGxbMl07Ci0gICAgICAgICAgICBpbnQgY291bnQgPSAwOwotICAgICAgICAgICAgaWYgKChmRmFjZXRzRGVmaW5lZCAmIEZBQ0VUX1BBVFRFUk4pICE9IDAgfHwKLSAgICAgICAgICAgICAgICAgICAgZlBhdHRlcm5UeXBlICE9IFNQRUNJQUxfUEFUVEVSTl9OT05FIHx8Ci0gICAgICAgICAgICAgICAgICAgIGZWYWxpZGF0aW9uRFYgPT0gRFZfSU5URUdFUikgewotICAgICAgICAgICAgICAgIGZhY2V0c1tjb3VudF0gPQotICAgICAgICAgICAgICAgICAgICBuZXcgWFNNVkZhY2V0SW1wbCgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBGQUNFVF9QQVRURVJOLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZ2V0TGV4aWNhbFBhdHRlcm4oKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXR0ZXJuQW5ub3RhdGlvbnMpOwotICAgICAgICAgICAgICAgIGNvdW50Kys7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoZkVudW1lcmF0aW9uICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmYWNldHNbY291bnRdID0KLSAgICAgICAgICAgICAgICAgICAgbmV3IFhTTVZGYWNldEltcGwoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgRkFDRVRfRU5VTUVSQVRJT04sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5nZXRMZXhpY2FsRW51bWVyYXRpb24oKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbnVtZXJhdGlvbkFubm90YXRpb25zKTsKLSAgICAgICAgICAgICAgICBjb3VudCsrOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZk11bHRpVmFsdWVGYWNldHMgPSBuZXcgWFNPYmplY3RMaXN0SW1wbChmYWNldHMsIGNvdW50KTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gKGZNdWx0aVZhbHVlRmFjZXRzICE9IG51bGwpID8KLSAgICAgICAgICAgICAgICBmTXVsdGlWYWx1ZUZhY2V0cyA6IFhTT2JqZWN0TGlzdEltcGwuRU1QVFlfTElTVDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgT2JqZWN0IGdldE1pbkluY2x1c2l2ZVZhbHVlKCkgewotICAgICAgICByZXR1cm4gZk1pbkluY2x1c2l2ZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgT2JqZWN0IGdldE1pbkV4Y2x1c2l2ZVZhbHVlKCkgewotICAgICAgICByZXR1cm4gZk1pbkV4Y2x1c2l2ZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgT2JqZWN0IGdldE1heEluY2x1c2l2ZVZhbHVlKCkgewotICAgICAgICByZXR1cm4gZk1heEluY2x1c2l2ZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgT2JqZWN0IGdldE1heEV4Y2x1c2l2ZVZhbHVlKCkgewotICAgICAgICByZXR1cm4gZk1heEV4Y2x1c2l2ZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRBbm9ueW1vdXMoYm9vbGVhbiBhbm9uKSB7Ci0gICAgICAgIGZBbm9ueW1vdXMgPSBhbm9uOwotICAgIH0KLQotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIFhTRmFjZXRJbXBsIGltcGxlbWVudHMgWFNGYWNldCB7Ci0gICAgICAgIGZpbmFsIHNob3J0IGtpbmQ7Ci0gICAgICAgIGZpbmFsIFN0cmluZyB2YWx1ZTsKLSAgICAgICAgZmluYWwgYm9vbGVhbiBmaXhlZDsKLSAgICAgICAgZmluYWwgWFNPYmplY3RMaXN0IGFubm90YXRpb25zOwotCi0gICAgICAgIHB1YmxpYyBYU0ZhY2V0SW1wbChzaG9ydCBraW5kLCBTdHJpbmcgdmFsdWUsIGJvb2xlYW4gZml4ZWQsIFhTQW5ub3RhdGlvbiBhbm5vdGF0aW9uKSB7Ci0gICAgICAgICAgICB0aGlzLmtpbmQgPSBraW5kOwotICAgICAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOwotICAgICAgICAgICAgdGhpcy5maXhlZCA9IGZpeGVkOwotCi0gICAgICAgICAgICBpZiAoYW5ub3RhdGlvbiAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgdGhpcy5hbm5vdGF0aW9ucyA9IG5ldyBYU09iamVjdExpc3RJbXBsKCk7Ci0gICAgICAgICAgICAgICAgKChYU09iamVjdExpc3RJbXBsKXRoaXMuYW5ub3RhdGlvbnMpLmFkZFhTT2JqZWN0KGFubm90YXRpb24pOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgdGhpcy5hbm5vdGF0aW9ucyA9ICBYU09iamVjdExpc3RJbXBsLkVNUFRZX0xJU1Q7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvKgotICAgICAgICAgKiAobm9uLUphdmFkb2MpCi0gICAgICAgICAqCi0gICAgICAgICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU0ZhY2V0I2dldEFubm90YXRpb24oKQotICAgICAgICAgKi8KLSAgICAgICAgLyoqCi0gICAgICAgICAqIE9wdGlvbmFsLiBBbm5vdGF0aW9uLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIFhTQW5ub3RhdGlvbiBnZXRBbm5vdGF0aW9uKCkgewotICAgICAgICAgICAgcmV0dXJuIChYU0Fubm90YXRpb24pIGFubm90YXRpb25zLml0ZW0oMCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvKgotICAgICAgICAgKiAobm9uLUphdmFkb2MpCi0gICAgICAgICAqCi0gICAgICAgICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU0ZhY2V0I2dldEFubm90YXRpb25zKCkKLSAgICAgICAgICovCi0gICAgICAgIC8qKgotICAgICAgICAgKiBPcHRpb25hbC4gQW5ub3RhdGlvbnMuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgWFNPYmplY3RMaXN0IGdldEFubm90YXRpb25zKCkgewotICAgICAgICAgICAgcmV0dXJuIGFubm90YXRpb25zOwotICAgICAgICB9Ci0KLSAgICAgICAgLyogKG5vbi1KYXZhZG9jKQotICAgICAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNGYWNldCNnZXRGYWNldEtpbmQoKQotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIHNob3J0IGdldEZhY2V0S2luZCgpIHsKLSAgICAgICAgICAgIHJldHVybiBraW5kOwotICAgICAgICB9Ci0KLSAgICAgICAgLyogKG5vbi1KYXZhZG9jKQotICAgICAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNGYWNldCNnZXRMZXhpY2FsRmFjZXRWYWx1ZSgpCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgU3RyaW5nIGdldExleGljYWxGYWNldFZhbHVlKCkgewotICAgICAgICAgICAgcmV0dXJuIHZhbHVlOwotICAgICAgICB9Ci0KLSAgICAgICAgLyogKG5vbi1KYXZhZG9jKQotICAgICAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNGYWNldCNpc0ZpeGVkKCkKLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBib29sZWFuIGdldEZpeGVkKCkgewotICAgICAgICAgICAgcmV0dXJuIGZpeGVkOwotICAgICAgICB9Ci0KLSAgICAgICAgLyogKG5vbi1KYXZhZG9jKQotICAgICAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNPYmplY3QjZ2V0TmFtZSgpCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKSB7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotCi0gICAgICAgIC8qIChub24tSmF2YWRvYykKLSAgICAgICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTT2JqZWN0I2dldE5hbWVzcGFjZSgpCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWVzcGFjZSgpIHsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0KLSAgICAgICAgLyogKG5vbi1KYXZhZG9jKQotICAgICAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNPYmplY3QjZ2V0TmFtZXNwYWNlSXRlbSgpCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgWFNOYW1lc3BhY2VJdGVtIGdldE5hbWVzcGFjZUl0ZW0oKSB7Ci0gICAgICAgICAgICAvLyBSRVZJU0lUOiBpbXBsZW1lbnQKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0KLSAgICAgICAgLyogKG5vbi1KYXZhZG9jKQotICAgICAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNPYmplY3QjZ2V0VHlwZSgpCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgc2hvcnQgZ2V0VHlwZSgpIHsKLSAgICAgICAgICAgIHJldHVybiBYU0NvbnN0YW50cy5GQUNFVDsKLSAgICAgICAgfQotCi0gICAgfQotCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgWFNNVkZhY2V0SW1wbCBpbXBsZW1lbnRzIFhTTXVsdGlWYWx1ZUZhY2V0IHsKLSAgICAgICAgZmluYWwgc2hvcnQga2luZDsKLSAgICAgICAgZmluYWwgWFNPYmplY3RMaXN0IGFubm90YXRpb25zOwotICAgICAgICBmaW5hbCBTdHJpbmdMaXN0IHZhbHVlczsKLQotICAgICAgICBwdWJsaWMgWFNNVkZhY2V0SW1wbChzaG9ydCBraW5kLCBTdHJpbmdMaXN0IHZhbHVlcywgWFNPYmplY3RMaXN0IGFubm90YXRpb25zKSB7Ci0gICAgICAgICAgICB0aGlzLmtpbmQgPSBraW5kOwotICAgICAgICAgICAgdGhpcy52YWx1ZXMgPSB2YWx1ZXM7Ci0gICAgICAgICAgICB0aGlzLmFubm90YXRpb25zID0gKGFubm90YXRpb25zICE9IG51bGwpID8gYW5ub3RhdGlvbnMgOiBYU09iamVjdExpc3RJbXBsLkVNUFRZX0xJU1Q7Ci0gICAgICAgIH0KLQotICAgICAgICAvKiAobm9uLUphdmFkb2MpCi0gICAgICAgICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU0ZhY2V0I2dldEZhY2V0S2luZCgpCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgc2hvcnQgZ2V0RmFjZXRLaW5kKCkgewotICAgICAgICAgICAgcmV0dXJuIGtpbmQ7Ci0gICAgICAgIH0KLQotICAgICAgICAvKiAobm9uLUphdmFkb2MpCi0gICAgICAgICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU011bHRpVmFsdWVGYWNldCNnZXRBbm5vdGF0aW9ucygpCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgWFNPYmplY3RMaXN0IGdldEFubm90YXRpb25zKCkgewotICAgICAgICAgICAgcmV0dXJuIGFubm90YXRpb25zOwotICAgICAgICB9Ci0KLSAgICAgICAgLyogKG5vbi1KYXZhZG9jKQotICAgICAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNNdWx0aVZhbHVlRmFjZXQjZ2V0TGV4aWNhbEZhY2V0VmFsdWVzKCkKLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBTdHJpbmdMaXN0IGdldExleGljYWxGYWNldFZhbHVlcygpIHsKLSAgICAgICAgICAgIHJldHVybiB2YWx1ZXM7Ci0gICAgICAgIH0KLQotICAgICAgICAvKiAobm9uLUphdmFkb2MpCi0gICAgICAgICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU09iamVjdCNnZXROYW1lKCkKLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpIHsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0KLSAgICAgICAgLyogKG5vbi1KYXZhZG9jKQotICAgICAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNPYmplY3QjZ2V0TmFtZXNwYWNlKCkKLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZXNwYWNlKCkgewotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLQotICAgICAgICAvKiAobm9uLUphdmFkb2MpCi0gICAgICAgICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU09iamVjdCNnZXROYW1lc3BhY2VJdGVtKCkKLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBYU05hbWVzcGFjZUl0ZW0gZ2V0TmFtZXNwYWNlSXRlbSgpIHsKLSAgICAgICAgICAgIC8vIFJFVklTSVQ6IGltcGxlbWVudAotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLQotICAgICAgICAvKiAobm9uLUphdmFkb2MpCi0gICAgICAgICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU09iamVjdCNnZXRUeXBlKCkKLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBzaG9ydCBnZXRUeXBlKCkgewotICAgICAgICAgICAgcmV0dXJuIFhTQ29uc3RhbnRzLk1VTFRJVkFMVUVfRkFDRVQ7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBhYnN0cmFjdCBjbGFzcyBBYnN0cmFjdE9iamVjdExpc3QgZXh0ZW5kcyBBYnN0cmFjdExpc3QgaW1wbGVtZW50cyBPYmplY3RMaXN0IHsKLSAgICAgICAgcHVibGljIE9iamVjdCBnZXQoaW50IGluZGV4KSB7Ci0gICAgICAgICAgICBpZiAoaW5kZXggPj0gMCAmJiBpbmRleCA8IGdldExlbmd0aCgpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGl0ZW0oaW5kZXgpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oIkluZGV4OiAiICsgaW5kZXgpOwotICAgICAgICB9Ci0gICAgICAgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKLSAgICAgICAgICAgIHJldHVybiBnZXRMZW5ndGgoKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VHlwZU5hbWVzcGFjZSgpIHsKLSAgICAgICAgcmV0dXJuIGdldE5hbWVzcGFjZSgpOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGlzRGVyaXZlZEZyb20oU3RyaW5nIHR5cGVOYW1lc3BhY2VBcmcsIFN0cmluZyB0eXBlTmFtZUFyZywgaW50IGRlcml2YXRpb25NZXRob2QpIHsKLSAgICAgICAgcmV0dXJuIGlzRE9NRGVyaXZlZEZyb20odHlwZU5hbWVzcGFjZUFyZywgdHlwZU5hbWVBcmcsIGRlcml2YXRpb25NZXRob2QpOwotICAgIH0KLQotICAgIHByaXZhdGUgc2hvcnQgY29udmVydFRvUHJpbWl0aXZlS2luZChzaG9ydCB2YWx1ZVR5cGUpIHsKLSAgICAgICAgLyoqIFByaW1pdGl2ZSBkYXRhdHlwZXMuICovCi0gICAgICAgIGlmICh2YWx1ZVR5cGUgPD0gWFNDb25zdGFudHMuTk9UQVRJT05fRFQpIHsKLSAgICAgICAgICAgIHJldHVybiB2YWx1ZVR5cGU7Ci0gICAgICAgIH0KLSAgICAgICAgLyoqIFR5cGVzIGRlcml2ZWQgZnJvbSBzdHJpbmcuICovCi0gICAgICAgIGlmICh2YWx1ZVR5cGUgPD0gWFNDb25zdGFudHMuRU5USVRZX0RUKSB7Ci0gICAgICAgICAgICByZXR1cm4gWFNDb25zdGFudHMuU1RSSU5HX0RUOwotICAgICAgICB9Ci0gICAgICAgIC8qKiBUeXBlcyBkZXJpdmVkIGZyb20gZGVjaW1hbC4gKi8KLSAgICAgICAgaWYgKHZhbHVlVHlwZSA8PSBYU0NvbnN0YW50cy5QT1NJVElWRUlOVEVHRVJfRFQpIHsKLSAgICAgICAgICAgIHJldHVybiBYU0NvbnN0YW50cy5ERUNJTUFMX0RUOwotICAgICAgICB9Ci0gICAgICAgIC8qKiBPdGhlciB0eXBlcy4gKi8KLSAgICAgICAgcmV0dXJuIHZhbHVlVHlwZTsKLSAgICB9Ci0KLX0gLy8gY2xhc3MgWFNTaW1wbGVUeXBlRGVjbApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi94cy9YU1NpbXBsZVR5cGVEZWxlZ2F0ZS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi94cy9YU1NpbXBsZVR5cGVEZWxlZ2F0ZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxYjY4M2RiLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYveHMvWFNTaW1wbGVUeXBlRGVsZWdhdGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIxOSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQotICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCi0gKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCi0gKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAotICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKLSAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi54czsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5EYXRhdHlwZUV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYuSW52YWxpZERhdGF0eXBlRmFjZXRFeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LkludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5WYWxpZGF0ZWRJbmZvOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5WYWxpZGF0aW9uQ29udGV4dDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYuWFNGYWNldHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LlhTU2ltcGxlVHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlN0cmluZ0xpc3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU05hbWVzcGFjZUl0ZW07Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU09iamVjdExpc3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU1NpbXBsZVR5cGVEZWZpbml0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNUeXBlRGVmaW5pdGlvbjsKLQotLyoqCi0gKiBCYXNlIGNsYXNzIGZvciBYU1NpbXBsZVR5cGUgd3JhcHBlciBpbXBsZW1lbnRhdGlvbnMuCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEB2ZXJzaW9uICRJZDogWFNTaW1wbGVUeXBlRGVsZWdhdGUuamF2YSx2IDEuMyAyMDEwLTExLTAxIDA0OjM5OjQ3IGpvZWh3IEV4cCAkCi0gKi8KLXB1YmxpYyBjbGFzcyBYU1NpbXBsZVR5cGVEZWxlZ2F0ZQotICAgIGltcGxlbWVudHMgWFNTaW1wbGVUeXBlIHsKLQotICAgIHByb3RlY3RlZCBmaW5hbCBYU1NpbXBsZVR5cGUgdHlwZTsKLQotICAgIHB1YmxpYyBYU1NpbXBsZVR5cGVEZWxlZ2F0ZShYU1NpbXBsZVR5cGUgdHlwZSkgewotICAgICAgICBpZiAodHlwZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKLSAgICAgICAgfQotICAgICAgICB0aGlzLnR5cGUgPSB0eXBlOwotICAgIH0KLQotICAgIHB1YmxpYyBYU1NpbXBsZVR5cGUgZ2V0V3JhcHBlZFhTU2ltcGxlVHlwZSgpIHsKLSAgICAgICAgcmV0dXJuIHR5cGU7Ci0gICAgfQotCi0gICAgcHVibGljIFhTT2JqZWN0TGlzdCBnZXRBbm5vdGF0aW9ucygpIHsKLSAgICAgICAgcmV0dXJuIHR5cGUuZ2V0QW5ub3RhdGlvbnMoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXRCb3VuZGVkKCkgewotICAgICAgICByZXR1cm4gdHlwZS5nZXRCb3VuZGVkKCk7Ci0gICAgfQotCi0gICAgcHVibGljIHNob3J0IGdldEJ1aWx0SW5LaW5kKCkgewotICAgICAgICByZXR1cm4gdHlwZS5nZXRCdWlsdEluS2luZCgpOwotICAgIH0KLQotICAgIHB1YmxpYyBzaG9ydCBnZXREZWZpbmVkRmFjZXRzKCkgewotICAgICAgICByZXR1cm4gdHlwZS5nZXREZWZpbmVkRmFjZXRzKCk7Ci0gICAgfQotCi0gICAgcHVibGljIFhTT2JqZWN0TGlzdCBnZXRGYWNldHMoKSB7Ci0gICAgICAgIHJldHVybiB0eXBlLmdldEZhY2V0cygpOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGdldEZpbml0ZSgpIHsKLSAgICAgICAgcmV0dXJuIHR5cGUuZ2V0RmluaXRlKCk7Ci0gICAgfQotCi0gICAgcHVibGljIHNob3J0IGdldEZpeGVkRmFjZXRzKCkgewotICAgICAgICByZXR1cm4gdHlwZS5nZXRGaXhlZEZhY2V0cygpOwotICAgIH0KLQotICAgIHB1YmxpYyBYU1NpbXBsZVR5cGVEZWZpbml0aW9uIGdldEl0ZW1UeXBlKCkgewotICAgICAgICByZXR1cm4gdHlwZS5nZXRJdGVtVHlwZSgpOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmdMaXN0IGdldExleGljYWxFbnVtZXJhdGlvbigpIHsKLSAgICAgICAgcmV0dXJuIHR5cGUuZ2V0TGV4aWNhbEVudW1lcmF0aW9uKCk7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRMZXhpY2FsRmFjZXRWYWx1ZShzaG9ydCBmYWNldE5hbWUpIHsKLSAgICAgICAgcmV0dXJuIHR5cGUuZ2V0TGV4aWNhbEZhY2V0VmFsdWUoZmFjZXROYW1lKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nTGlzdCBnZXRMZXhpY2FsUGF0dGVybigpIHsKLSAgICAgICAgcmV0dXJuIHR5cGUuZ2V0TGV4aWNhbFBhdHRlcm4oKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgWFNPYmplY3RMaXN0IGdldE1lbWJlclR5cGVzKCkgewotICAgICAgICByZXR1cm4gdHlwZS5nZXRNZW1iZXJUeXBlcygpOwotICAgIH0KLQotICAgIHB1YmxpYyBYU09iamVjdExpc3QgZ2V0TXVsdGlWYWx1ZUZhY2V0cygpIHsKLSAgICAgICAgcmV0dXJuIHR5cGUuZ2V0TXVsdGlWYWx1ZUZhY2V0cygpOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGdldE51bWVyaWMoKSB7Ci0gICAgICAgIHJldHVybiB0eXBlLmdldE51bWVyaWMoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgc2hvcnQgZ2V0T3JkZXJlZCgpIHsKLSAgICAgICAgcmV0dXJuIHR5cGUuZ2V0T3JkZXJlZCgpOwotICAgIH0KLQotICAgIHB1YmxpYyBYU1NpbXBsZVR5cGVEZWZpbml0aW9uIGdldFByaW1pdGl2ZVR5cGUoKSB7Ci0gICAgICAgIHJldHVybiB0eXBlLmdldFByaW1pdGl2ZVR5cGUoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgc2hvcnQgZ2V0VmFyaWV0eSgpIHsKLSAgICAgICAgcmV0dXJuIHR5cGUuZ2V0VmFyaWV0eSgpOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGlzRGVmaW5lZEZhY2V0KHNob3J0IGZhY2V0TmFtZSkgewotICAgICAgICByZXR1cm4gdHlwZS5pc0RlZmluZWRGYWNldChmYWNldE5hbWUpOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGlzRml4ZWRGYWNldChzaG9ydCBmYWNldE5hbWUpIHsKLSAgICAgICAgcmV0dXJuIHR5cGUuaXNGaXhlZEZhY2V0KGZhY2V0TmFtZSk7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gZGVyaXZlZEZyb20oU3RyaW5nIG5hbWVzcGFjZSwgU3RyaW5nIG5hbWUsIHNob3J0IGRlcml2YXRpb25NZXRob2QpIHsKLSAgICAgICAgcmV0dXJuIHR5cGUuZGVyaXZlZEZyb20obmFtZXNwYWNlLCBuYW1lLCBkZXJpdmF0aW9uTWV0aG9kKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBkZXJpdmVkRnJvbVR5cGUoWFNUeXBlRGVmaW5pdGlvbiBhbmNlc3RvclR5cGUsIHNob3J0IGRlcml2YXRpb25NZXRob2QpIHsKLSAgICAgICAgcmV0dXJuIHR5cGUuZGVyaXZlZEZyb21UeXBlKGFuY2VzdG9yVHlwZSwgZGVyaXZhdGlvbk1ldGhvZCk7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0QW5vbnltb3VzKCkgewotICAgICAgICByZXR1cm4gdHlwZS5nZXRBbm9ueW1vdXMoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgWFNUeXBlRGVmaW5pdGlvbiBnZXRCYXNlVHlwZSgpIHsKLSAgICAgICAgcmV0dXJuIHR5cGUuZ2V0QmFzZVR5cGUoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgc2hvcnQgZ2V0RmluYWwoKSB7Ci0gICAgICAgIHJldHVybiB0eXBlLmdldEZpbmFsKCk7Ci0gICAgfQotCi0gICAgcHVibGljIHNob3J0IGdldFR5cGVDYXRlZ29yeSgpIHsKLSAgICAgICAgcmV0dXJuIHR5cGUuZ2V0VHlwZUNhdGVnb3J5KCk7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gaXNGaW5hbChzaG9ydCByZXN0cmljdGlvbikgewotICAgICAgICByZXR1cm4gdHlwZS5pc0ZpbmFsKHJlc3RyaWN0aW9uKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKSB7Ci0gICAgICAgIHJldHVybiB0eXBlLmdldE5hbWUoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWVzcGFjZSgpIHsKLSAgICAgICAgcmV0dXJuIHR5cGUuZ2V0TmFtZXNwYWNlKCk7Ci0gICAgfQotCi0gICAgcHVibGljIFhTTmFtZXNwYWNlSXRlbSBnZXROYW1lc3BhY2VJdGVtKCkgewotICAgICAgICByZXR1cm4gdHlwZS5nZXROYW1lc3BhY2VJdGVtKCk7Ci0gICAgfQotCi0gICAgcHVibGljIHNob3J0IGdldFR5cGUoKSB7Ci0gICAgICAgIHJldHVybiB0eXBlLmdldFR5cGUoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBhcHBseUZhY2V0cyhYU0ZhY2V0cyBmYWNldHMsIHNob3J0IHByZXNlbnRGYWNldCwgc2hvcnQgZml4ZWRGYWNldCwgVmFsaWRhdGlvbkNvbnRleHQgY29udGV4dCkKLSAgICAgICAgdGhyb3dzIEludmFsaWREYXRhdHlwZUZhY2V0RXhjZXB0aW9uIHsKLSAgICAgICAgdHlwZS5hcHBseUZhY2V0cyhmYWNldHMsIHByZXNlbnRGYWNldCwgZml4ZWRGYWNldCwgY29udGV4dCk7Ci0gICAgfQotCi0gICAgcHVibGljIHNob3J0IGdldFByaW1pdGl2ZUtpbmQoKSB7Ci0gICAgICAgIHJldHVybiB0eXBlLmdldFByaW1pdGl2ZUtpbmQoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgc2hvcnQgZ2V0V2hpdGVzcGFjZSgpIHRocm93cyBEYXRhdHlwZUV4Y2VwdGlvbiB7Ci0gICAgICAgIHJldHVybiB0eXBlLmdldFdoaXRlc3BhY2UoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0VxdWFsKE9iamVjdCB2YWx1ZTEsIE9iamVjdCB2YWx1ZTIpIHsKLSAgICAgICAgcmV0dXJuIHR5cGUuaXNFcXVhbCh2YWx1ZTEsIHZhbHVlMik7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gaXNJRFR5cGUoKSB7Ci0gICAgICAgIHJldHVybiB0eXBlLmlzSURUeXBlKCk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgdmFsaWRhdGUoVmFsaWRhdGlvbkNvbnRleHQgY29udGV4dCwgVmFsaWRhdGVkSW5mbyB2YWxpZGF0ZWRJbmZvKQotICAgICAgICB0aHJvd3MgSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24gewotICAgICAgICB0eXBlLnZhbGlkYXRlKGNvbnRleHQsIHZhbGlkYXRlZEluZm8pOwotICAgIH0KLQotICAgIHB1YmxpYyBPYmplY3QgdmFsaWRhdGUoU3RyaW5nIGNvbnRlbnQsIFZhbGlkYXRpb25Db250ZXh0IGNvbnRleHQsIFZhbGlkYXRlZEluZm8gdmFsaWRhdGVkSW5mbykKLSAgICAgICAgdGhyb3dzIEludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uIHsKLSAgICAgICAgcmV0dXJuIHR5cGUudmFsaWRhdGUoY29udGVudCwgY29udGV4dCwgdmFsaWRhdGVkSW5mbyk7Ci0gICAgfQotCi0gICAgcHVibGljIE9iamVjdCB2YWxpZGF0ZShPYmplY3QgY29udGVudCwgVmFsaWRhdGlvbkNvbnRleHQgY29udGV4dCwgVmFsaWRhdGVkSW5mbyB2YWxpZGF0ZWRJbmZvKQotICAgICAgICB0aHJvd3MgSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24gewotICAgICAgICByZXR1cm4gdHlwZS52YWxpZGF0ZShjb250ZW50LCBjb250ZXh0LCB2YWxpZGF0ZWRJbmZvKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgICAgICByZXR1cm4gdHlwZS50b1N0cmluZygpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYveHMvWWVhckRWLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L3hzL1llYXJEVi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkMDY5YzQwLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYveHMvWWVhckRWLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMjcgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDAyLDIwMDQsMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LnhzOwotCi1pbXBvcnQgamF2YXgueG1sLmRhdGF0eXBlLkRhdGF0eXBlQ29uc3RhbnRzOwotaW1wb3J0IGphdmF4LnhtbC5kYXRhdHlwZS5YTUxHcmVnb3JpYW5DYWxlbmRhcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5JbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYuVmFsaWRhdGlvbkNvbnRleHQ7Ci0KLS8qKgotICogVmFsaWRhdG9yIGZvciAmbHQ7Z1llYXImZ3Q7IGRhdGF0eXBlIChXM0MgU2NoZW1hIERhdGF0eXBlcykKLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBFbGVuYSBMaXRhbmkKLSAqIEBhdXRob3IgR29wYWwgU2hhcm1hLCBTVU4gTWljcm9zeXN0ZW0gSW5jLgotICoKLSAqIEB2ZXJzaW9uICRJZDogWWVhckRWLmphdmEsdiAxLjcgMjAxMC0xMS0wMSAwNDozOTo0NyBqb2VodyBFeHAgJAotICovCi0KLXB1YmxpYyBjbGFzcyBZZWFyRFYgZXh0ZW5kcyBBYnN0cmFjdERhdGVUaW1lRFYgewotCi0gICAgLyoqCi0gICAgICogQ29udmVydCBhIHN0cmluZyB0byBhIGNvbXBpbGVkIGZvcm0KLSAgICAgKgotICAgICAqIEBwYXJhbSAgY29udGVudCBUaGUgbGV4aWNhbCByZXByZXNlbnRhdGlvbiBvZiB0aW1lCi0gICAgICogQHJldHVybiBhIHZhbGlkIGFuZCBub3JtYWxpemVkIHRpbWUgb2JqZWN0Ci0gICAgICovCi0gICAgcHVibGljIE9iamVjdCBnZXRBY3R1YWxWYWx1ZShTdHJpbmcgY29udGVudCwgVmFsaWRhdGlvbkNvbnRleHQgY29udGV4dCkgdGhyb3dzIEludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uewotICAgICAgICB0cnl7Ci0gICAgICAgICAgICByZXR1cm4gcGFyc2UoY29udGVudCk7Ci0gICAgICAgIH0gY2F0Y2goRXhjZXB0aW9uIGV4KXsKLSAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbigiY3ZjLWRhdGF0eXBlLXZhbGlkLjEuMi4xIiwgbmV3IE9iamVjdFtde2NvbnRlbnQsICJnWWVhciJ9KTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFBhcnNlcywgdmFsaWRhdGVzIGFuZCBjb21wdXRlcyBub3JtYWxpemVkIHZlcnNpb24gb2YgZ1llYXIgb2JqZWN0Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gc3RyICAgIFRoZSBsZXhpY2FsIHJlcHJlc2VudGF0aW9uIG9mIHllYXIgb2JqZWN0IENDWVkKLSAgICAgKiAgICAgICAgICAgICAgIHdpdGggcG9zc2libGUgdGltZSB6b25lIFogb3IgKC0pLCgrKWhoOm1tCi0gICAgICogQHJldHVybiBub3JtYWxpemVkIGRhdGUgcmVwcmVzZW50YXRpb24KLSAgICAgKiBAZXhjZXB0aW9uIFNjaGVtYURhdGVUaW1lRXhjZXB0aW9uIEludmFsaWQgbGV4aWNhbCByZXByZXNlbnRhdGlvbgotICAgICAqLwotICAgIHByb3RlY3RlZCBEYXRlVGltZURhdGEgcGFyc2UoU3RyaW5nIHN0cikgdGhyb3dzIFNjaGVtYURhdGVUaW1lRXhjZXB0aW9uewotICAgICAgICBEYXRlVGltZURhdGEgZGF0ZSA9IG5ldyBEYXRlVGltZURhdGEoc3RyLCB0aGlzKTsKLSAgICAgICAgaW50IGxlbiA9IHN0ci5sZW5ndGgoKTsKLQotICAgICAgICAvLyBjaGVjayBmb3IgcHJlY2VkaW5nICctJyBzaWduCi0gICAgICAgIGludCBzdGFydCA9IDA7Ci0gICAgICAgIGlmIChzdHIuY2hhckF0KDApPT0nLScpIHsKLSAgICAgICAgICAgIHN0YXJ0ID0gMTsKLSAgICAgICAgfQotICAgICAgICBpbnQgc2lnbiA9IGZpbmRVVENTaWduKHN0ciwgc3RhcnQsIGxlbik7Ci0KLSAgICAgICAgZmluYWwgaW50IGxlbmd0aCA9ICgoc2lnbiA9PSAtMSkgPyBsZW4gOiBzaWduKSAtIHN0YXJ0OwotICAgICAgICBpZiAobGVuZ3RoIDwgNCkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlllYXIgbXVzdCBoYXZlICdDQ1lZJyBmb3JtYXQiKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChsZW5ndGggPiA0ICYmIHN0ci5jaGFyQXQoc3RhcnQpID09ICcwJykgewotICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIkxlYWRpbmcgemVyb3MgYXJlIHJlcXVpcmVkIGlmIHRoZSB5ZWFyIHZhbHVlIHdvdWxkIG90aGVyd2lzZSBoYXZlIGZld2VyIHRoYW4gZm91ciBkaWdpdHM7IG90aGVyd2lzZSB0aGV5IGFyZSBmb3JiaWRkZW4iKTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChzaWduID09IC0xKSB7Ci0gICAgICAgICAgICBkYXRlLnllYXI9cGFyc2VJbnRZZWFyKHN0ciwgbGVuKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIGRhdGUueWVhcj1wYXJzZUludFllYXIoc3RyLCBzaWduKTsKLSAgICAgICAgICAgIGdldFRpbWVab25lIChzdHIsIGRhdGUsIHNpZ24sIGxlbik7Ci0gICAgICAgIH0KLQotICAgICAgICAvL2luaXRpYWxpemUgdmFsdWVzCi0gICAgICAgIGRhdGUubW9udGg9TU9OVEg7Ci0gICAgICAgIGRhdGUuZGF5PTE7Ci0KLSAgICAgICAgLy92YWxpZGF0ZSBhbmQgbm9ybWFsaXplCi0gICAgICAgIHZhbGlkYXRlRGF0ZVRpbWUoZGF0ZSk7Ci0KLSAgICAgICAgLy9zYXZlIHVubm9ybWFsaXplZCB2YWx1ZXMKLSAgICAgICAgc2F2ZVVubm9ybWFsaXplZChkYXRlKTsKLQotICAgICAgICBpZiAoIGRhdGUudXRjIT0wICYmIGRhdGUudXRjIT0nWicgKSB7Ci0gICAgICAgICAgICBub3JtYWxpemUoZGF0ZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZGF0ZS5wb3NpdGlvbiA9IDA7Ci0gICAgICAgIHJldHVybiBkYXRlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbnZlcnRzIHllYXIgb2JqZWN0IHJlcHJlc2VudGF0aW9uIHRvIFN0cmluZwotICAgICAqCi0gICAgICogQHBhcmFtIGRhdGUgICB5ZWFyIG9iamVjdAotICAgICAqIEByZXR1cm4gbGV4aWNhbCByZXByZXNlbnRhdGlvbiBvZiBtb250aDogQ0NZWSB3aXRoIG9wdGlvbmFsIHRpbWUgem9uZSBzaWduCi0gICAgICovCi0gICAgcHJvdGVjdGVkIFN0cmluZyBkYXRlVG9TdHJpbmcoRGF0ZVRpbWVEYXRhIGRhdGUpIHsKLSAgICAgICAgU3RyaW5nQnVmZmVyIG1lc3NhZ2UgPSBuZXcgU3RyaW5nQnVmZmVyKDUpOwotICAgICAgICBhcHBlbmQobWVzc2FnZSwgZGF0ZS55ZWFyLCA0KTsKLSAgICAgICAgYXBwZW5kKG1lc3NhZ2UsIChjaGFyKWRhdGUudXRjLCAwKTsKLSAgICAgICAgcmV0dXJuIG1lc3NhZ2UudG9TdHJpbmcoKTsKLSAgICB9Ci0KLSAgICBwcm90ZWN0ZWQgWE1MR3JlZ29yaWFuQ2FsZW5kYXIgZ2V0WE1MR3JlZ29yaWFuQ2FsZW5kYXIoRGF0ZVRpbWVEYXRhIGRhdGUpIHsKLSAgICAgICAgcmV0dXJuIGRhdGF0eXBlRmFjdG9yeS5uZXdYTUxHcmVnb3JpYW5DYWxlbmRhcihkYXRlLnVuTm9ybVllYXIsIERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCwKLSAgICAgICAgICAgICAgICBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQsIERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCwgRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVELAotICAgICAgICAgICAgICAgIERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCwgRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVELAotICAgICAgICAgICAgICAgIGRhdGUuaGFzVGltZVpvbmUoKSA/IGRhdGUudGltZXpvbmVIciAqIDYwICsgZGF0ZS50aW1lem9uZU1pbiA6IERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi94cy9ZZWFyTW9udGhEVi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9kdi94cy9ZZWFyTW9udGhEVi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2Yjk2ZGViLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYveHMvWWVhck1vbnRoRFYuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEwMSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDIsMjAwNCwyMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYueHM7Ci0KLWltcG9ydCBqYXZheC54bWwuZGF0YXR5cGUuRGF0YXR5cGVDb25zdGFudHM7Ci1pbXBvcnQgamF2YXgueG1sLmRhdGF0eXBlLlhNTEdyZWdvcmlhbkNhbGVuZGFyOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LkludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5WYWxpZGF0aW9uQ29udGV4dDsKLQotLyoqCi0gKiBWYWxpZGF0b3IgZm9yICZsdDtnWWVhck1vbnRoJmd0OyBkYXRhdHlwZSAoVzNDIFNjaGVtYSBEYXRhdHlwZXMpCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgRWxlbmEgTGl0YW5pCi0gKiBAYXV0aG9yIEdvcGFsIFNoYXJtYSwgU1VOIE1pY3Jvc3lzdGVtIEluYy4KLSAqCi0gKiBAdmVyc2lvbiAkSWQ6IFllYXJNb250aERWLmphdmEsdiAxLjcgMjAxMC0xMS0wMSAwNDozOTo0NyBqb2VodyBFeHAgJAotICovCi1wdWJsaWMgY2xhc3MgWWVhck1vbnRoRFYgZXh0ZW5kcyBBYnN0cmFjdERhdGVUaW1lRFZ7Ci0KLSAgICAvKioKLSAgICAgKiBDb252ZXJ0IGEgc3RyaW5nIHRvIGEgY29tcGlsZWQgZm9ybQotICAgICAqCi0gICAgICogQHBhcmFtICBjb250ZW50IFRoZSBsZXhpY2FsIHJlcHJlc2VudGF0aW9uIG9mIGdZZWFyTW9udGgKLSAgICAgKiBAcmV0dXJuIGEgdmFsaWQgYW5kIG5vcm1hbGl6ZWQgZ1llYXJNb250aCBvYmplY3QKLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0IGdldEFjdHVhbFZhbHVlKFN0cmluZyBjb250ZW50LCBWYWxpZGF0aW9uQ29udGV4dCBjb250ZXh0KSB0aHJvd3MgSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb257Ci0gICAgICAgIHRyeXsKLSAgICAgICAgICAgIHJldHVybiBwYXJzZShjb250ZW50KTsKLSAgICAgICAgfSBjYXRjaChFeGNlcHRpb24gZXgpewotICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uKCJjdmMtZGF0YXR5cGUtdmFsaWQuMS4yLjEiLCBuZXcgT2JqZWN0W117Y29udGVudCwgImdZZWFyTW9udGgifSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBQYXJzZXMsIHZhbGlkYXRlcyBhbmQgY29tcHV0ZXMgbm9ybWFsaXplZCB2ZXJzaW9uIG9mIGdZZWFyTW9udGggb2JqZWN0Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gc3RyICAgIFRoZSBsZXhpY2FsIHJlcHJlc2VudGF0aW9uIG9mIGdZZWFyTW9udGggb2JqZWN0IENDWVktTU0KLSAgICAgKiAgICAgICAgICAgICAgIHdpdGggcG9zc2libGUgdGltZSB6b25lIFogb3IgKC0pLCgrKWhoOm1tCi0gICAgICogQHJldHVybiBub3JtYWxpemVkIGRhdGUgcmVwcmVzZW50YXRpb24KLSAgICAgKiBAZXhjZXB0aW9uIFNjaGVtYURhdGVUaW1lRXhjZXB0aW9uIEludmFsaWQgbGV4aWNhbCByZXByZXNlbnRhdGlvbgotICAgICAqLwotICAgIHByb3RlY3RlZCBEYXRlVGltZURhdGEgcGFyc2UoU3RyaW5nIHN0cikgdGhyb3dzIFNjaGVtYURhdGVUaW1lRXhjZXB0aW9uewotICAgICAgICBEYXRlVGltZURhdGEgZGF0ZSA9IG5ldyBEYXRlVGltZURhdGEoc3RyLCB0aGlzKTsKLSAgICAgICAgaW50IGxlbiA9IHN0ci5sZW5ndGgoKTsKLQotICAgICAgICAvLyBnZXQgZGF0ZQotICAgICAgICBpbnQgZW5kID0gZ2V0WWVhck1vbnRoKHN0ciwgMCwgbGVuLCBkYXRlKTsKLSAgICAgICAgZGF0ZS5kYXkgPSBEQVk7Ci0gICAgICAgIHBhcnNlVGltZVpvbmUgKHN0ciwgZW5kLCBsZW4sIGRhdGUpOwotCi0gICAgICAgIC8vdmFsaWRhdGUgYW5kIG5vcm1hbGl6ZQotCi0gICAgICAgIHZhbGlkYXRlRGF0ZVRpbWUoZGF0ZSk7Ci0KLSAgICAgICAgLy9zYXZlIHVubm9ybWFsaXplZCB2YWx1ZXMKLSAgICAgICAgc2F2ZVVubm9ybWFsaXplZChkYXRlKTsKLQotICAgICAgICBpZiAoIGRhdGUudXRjIT0wICYmIGRhdGUudXRjIT0nWicgKSB7Ci0gICAgICAgICAgICBub3JtYWxpemUoZGF0ZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZGF0ZS5wb3NpdGlvbiA9IDA7Ci0gICAgICAgIHJldHVybiBkYXRlOwotICAgIH0KLQotICAgIHByb3RlY3RlZCBTdHJpbmcgZGF0ZVRvU3RyaW5nKERhdGVUaW1lRGF0YSBkYXRlKSB7Ci0gICAgICAgIFN0cmluZ0J1ZmZlciBtZXNzYWdlID0gbmV3IFN0cmluZ0J1ZmZlcigyNSk7Ci0gICAgICAgIGFwcGVuZChtZXNzYWdlLCBkYXRlLnllYXIsIDQpOwotICAgICAgICBtZXNzYWdlLmFwcGVuZCgnLScpOwotICAgICAgICBhcHBlbmQobWVzc2FnZSwgZGF0ZS5tb250aCwgMik7Ci0gICAgICAgIGFwcGVuZChtZXNzYWdlLCAoY2hhcilkYXRlLnV0YywgMCk7Ci0gICAgICAgIHJldHVybiBtZXNzYWdlLnRvU3RyaW5nKCk7Ci0gICAgfQotCi0gICAgcHJvdGVjdGVkIFhNTEdyZWdvcmlhbkNhbGVuZGFyIGdldFhNTEdyZWdvcmlhbkNhbGVuZGFyKERhdGVUaW1lRGF0YSBkYXRlKSB7Ci0gICAgICAgIHJldHVybiBkYXRhdHlwZUZhY3RvcnkubmV3WE1MR3JlZ29yaWFuQ2FsZW5kYXIoZGF0ZS51bk5vcm1ZZWFyLCBkYXRlLnVuTm9ybU1vbnRoLCBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQsCi0gICAgICAgICAgICAgICAgRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVELCBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQsCi0gICAgICAgICAgICAgICAgRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVELCBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQsCi0gICAgICAgICAgICAgICAgZGF0ZS5oYXNUaW1lWm9uZSgpID8gZGF0ZS50aW1lem9uZUhyICogNjAgKyBkYXRlLnRpbWV6b25lTWluIDogRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVEKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2R2L3hzL1llYXJNb250aER1cmF0aW9uRFYuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYveHMvWWVhck1vbnRoRHVyYXRpb25EVi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0NzIzYTY1Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvZHYveHMvWWVhck1vbnRoRHVyYXRpb25EVi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNjQgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwNCwyMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LnhzOwotCi1pbXBvcnQgamF2YS5tYXRoLkJpZ0ludGVnZXI7Ci0KLWltcG9ydCBqYXZheC54bWwuZGF0YXR5cGUuRGF0YXR5cGVDb25zdGFudHM7Ci1pbXBvcnQgamF2YXgueG1sLmRhdGF0eXBlLkR1cmF0aW9uOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LkludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5WYWxpZGF0aW9uQ29udGV4dDsKLQotLyoqCi0gKiBVc2VkIHRvIHZhbGlkYXRlIHRoZSA8eWVhck1vbnRoRHVyYXRpb24+IHR5cGUKLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBBbmtpdCBQYXNyaWNoYSwgSUJNCi0gKgotICogQHZlcnNpb24gJElkOiBZZWFyTW9udGhEdXJhdGlvbkRWLmphdmEsdiAxLjYgMjAxMC0xMS0wMSAwNDozOTo0NyBqb2VodyBFeHAgJAotICovCi1jbGFzcyBZZWFyTW9udGhEdXJhdGlvbkRWIGV4dGVuZHMgRHVyYXRpb25EViB7Ci0KLSAgICBwdWJsaWMgT2JqZWN0IGdldEFjdHVhbFZhbHVlKFN0cmluZyBjb250ZW50LCBWYWxpZGF0aW9uQ29udGV4dCBjb250ZXh0KQotICAgICAgICB0aHJvd3MgSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24gewotICAgICAgICB0cnkgewotICAgICAgICAgICAgcmV0dXJuIHBhcnNlKGNvbnRlbnQsIER1cmF0aW9uRFYuWUVBUk1PTlRIRFVSQVRJT05fVFlQRSk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkgewotICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uKCJjdmMtZGF0YXR5cGUtdmFsaWQuMS4yLjEiLCBuZXcgT2JqZWN0W117Y29udGVudCwgInllYXJNb250aER1cmF0aW9uIn0pOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHJvdGVjdGVkIER1cmF0aW9uIGdldER1cmF0aW9uKERhdGVUaW1lRGF0YSBkYXRlKSB7Ci0gICAgICAgIGludCBzaWduID0gMTsKLSAgICAgICAgaWYgKCBkYXRlLnllYXI8MCB8fCBkYXRlLm1vbnRoPDApIHsKLSAgICAgICAgICAgIHNpZ24gPSAtMTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZGF0YXR5cGVGYWN0b3J5Lm5ld0R1cmF0aW9uKHNpZ24gPT0gMSwKLSAgICAgICAgICAgICAgICBkYXRlLnllYXIgIT0gRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVEP0JpZ0ludGVnZXIudmFsdWVPZihzaWduKmRhdGUueWVhcik6bnVsbCwKLSAgICAgICAgICAgICAgICBkYXRlLm1vbnRoICE9IERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRD9CaWdJbnRlZ2VyLnZhbHVlT2Yoc2lnbipkYXRlLm1vbnRoKTpudWxsLAotICAgICAgICAgICAgICAgIG51bGwsCi0gICAgICAgICAgICAgICAgbnVsbCwKLSAgICAgICAgICAgICAgICBudWxsLAotICAgICAgICAgICAgICAgIG51bGwpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvaW8vQVNDSUlSZWFkZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvaW8vQVNDSUlSZWFkZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDY5OGM1OC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2lvL0FTQ0lJUmVhZGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyNDcgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMC0yMDAyLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5pbzsKLQotaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLlJlYWRlcjsKLWltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5NZXNzYWdlRm9ybWF0dGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5tc2cuWE1MTWVzc2FnZUZvcm1hdHRlcjsKLQotaW1wb3J0IGNvbS5zdW4ueG1sLmludGVybmFsLnN0cmVhbS51dGlsLkJ1ZmZlckFsbG9jYXRvcjsKLWltcG9ydCBjb20uc3VuLnhtbC5pbnRlcm5hbC5zdHJlYW0udXRpbC5UaHJlYWRMb2NhbEJ1ZmZlckFsbG9jYXRvcjsKLQotLyoqCi0gKiBBIHNpbXBsZSBBU0NJSSBieXRlIHJlYWRlci4gVGhpcyBpcyBhbiBvcHRpbWl6ZWQgcmVhZGVyIGZvciByZWFkaW5nCi0gKiBieXRlIHN0cmVhbXMgdGhhdCBvbmx5IGNvbnRhaW4gNy1iaXQgQVNDSUkgY2hhcmFjdGVycy4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBBbmR5IENsYXJrLCBJQk0KLSAqCi0gKi8KLXB1YmxpYyBjbGFzcyBBU0NJSVJlYWRlcgotICAgIGV4dGVuZHMgUmVhZGVyIHsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RhbnRzCi0gICAgLy8KLQotICAgIC8qKiBEZWZhdWx0IGJ5dGUgYnVmZmVyIHNpemUgKDIwNDgpLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFRkFVTFRfQlVGRkVSX1NJWkUgPSAyMDQ4OwotCi0gICAgLy8KLSAgICAvLyBEYXRhCi0gICAgLy8KLQotICAgIC8qKiBJbnB1dCBzdHJlYW0uICovCi0gICAgcHJvdGVjdGVkIElucHV0U3RyZWFtIGZJbnB1dFN0cmVhbTsKLQotICAgIC8qKiBCeXRlIGJ1ZmZlci4gKi8KLSAgICBwcm90ZWN0ZWQgYnl0ZVtdIGZCdWZmZXI7Ci0KLSAgICAvLyBtZXNzYWdlIGZvcm1hdHRlcjsgdXNlZCB0byBwcm9kdWNlIGxvY2FsaXplZAotICAgIC8vIGV4Y2VwdGlvbiBtZXNzYWdlcwotICAgIHByaXZhdGUgTWVzc2FnZUZvcm1hdHRlciBmRm9ybWF0dGVyID0gbnVsbDsKLQotICAgIC8vTG9jYWxlIHRvIHVzZSBmb3IgbWVzc2FnZXMKLSAgICBwcml2YXRlIExvY2FsZSBmTG9jYWxlID0gbnVsbDsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHMgYW4gQVNDSUkgcmVhZGVyIGZyb20gdGhlIHNwZWNpZmllZCBpbnB1dCBzdHJlYW0KLSAgICAgKiB1c2luZyB0aGUgZGVmYXVsdCBidWZmZXIgc2l6ZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBpbnB1dFN0cmVhbSBUaGUgaW5wdXQgc3RyZWFtLgotICAgICAqIEBwYXJhbSBtZXNzYWdlRm9ybWF0dGVyICB0aGUgTWVzc2FnZUZvcm1hdHRlciB0byB1c2UgdG8gbWVzc2FnZSByZXBvcnRpbmcuCi0gICAgICogQHBhcmFtIGxvY2FsZSAgICB0aGUgTG9jYWxlIGZvciB3aGljaCBtZXNzYWdlcyBhcmUgdG8gYmUgcmVwb3J0ZWQKLSAgICAgKi8KLSAgICBwdWJsaWMgQVNDSUlSZWFkZXIoSW5wdXRTdHJlYW0gaW5wdXRTdHJlYW0sIE1lc3NhZ2VGb3JtYXR0ZXIgbWVzc2FnZUZvcm1hdHRlciwKLSAgICAgICAgICAgIExvY2FsZSBsb2NhbGUpIHsKLSAgICAgICAgdGhpcyhpbnB1dFN0cmVhbSwgREVGQVVMVF9CVUZGRVJfU0laRSwgbWVzc2FnZUZvcm1hdHRlciwgbG9jYWxlKTsKLSAgICB9IC8vIDxpbml0PihJbnB1dFN0cmVhbSwgTWVzc2FnZUZvcm1hdHRlciwgTG9jYWxlKQotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0cyBhbiBBU0NJSSByZWFkZXIgZnJvbSB0aGUgc3BlY2lmaWVkIGlucHV0IHN0cmVhbQotICAgICAqIGFuZCBidWZmZXIgc2l6ZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBpbnB1dFN0cmVhbSBUaGUgaW5wdXQgc3RyZWFtLgotICAgICAqIEBwYXJhbSBzaXplICAgICAgICBUaGUgaW5pdGlhbCBidWZmZXIgc2l6ZS4KLSAgICAgKiBAcGFyYW0gbWVzc2FnZUZvcm1hdHRlciAgdGhlIE1lc3NhZ2VGb3JtYXR0ZXIgdG8gdXNlIHRvIG1lc3NhZ2UgcmVwb3J0aW5nLgotICAgICAqIEBwYXJhbSBsb2NhbGUgICAgdGhlIExvY2FsZSBmb3Igd2hpY2ggbWVzc2FnZXMgYXJlIHRvIGJlIHJlcG9ydGVkCi0gICAgICovCi0gICAgcHVibGljIEFTQ0lJUmVhZGVyKElucHV0U3RyZWFtIGlucHV0U3RyZWFtLCBpbnQgc2l6ZSwKLSAgICAgICAgICAgIE1lc3NhZ2VGb3JtYXR0ZXIgbWVzc2FnZUZvcm1hdHRlciwgTG9jYWxlIGxvY2FsZSkgewotICAgICAgICBmSW5wdXRTdHJlYW0gPSBpbnB1dFN0cmVhbTsKLSAgICAgICAgQnVmZmVyQWxsb2NhdG9yIGJhID0gVGhyZWFkTG9jYWxCdWZmZXJBbGxvY2F0b3IuZ2V0QnVmZmVyQWxsb2NhdG9yKCk7Ci0gICAgICAgIGZCdWZmZXIgPSBiYS5nZXRCeXRlQnVmZmVyKHNpemUpOwotICAgICAgICBpZiAoZkJ1ZmZlciA9PSBudWxsKSB7Ci0gICAgICAgICAgICBmQnVmZmVyID0gbmV3IGJ5dGVbc2l6ZV07Ci0gICAgICAgIH0KLSAgICAgICAgZkZvcm1hdHRlciA9IG1lc3NhZ2VGb3JtYXR0ZXI7Ci0gICAgICAgIGZMb2NhbGUgPSBsb2NhbGU7Ci0gICAgfSAvLyA8aW5pdD4oSW5wdXRTdHJlYW0saW50LCBNZXNzYWdlRm9ybWF0dGVyLCBMb2NhbGUpCi0KLSAgICAvLwotICAgIC8vIFJlYWRlciBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFJlYWQgYSBzaW5nbGUgY2hhcmFjdGVyLiAgVGhpcyBtZXRob2Qgd2lsbCBibG9jayB1bnRpbCBhIGNoYXJhY3RlciBpcwotICAgICAqIGF2YWlsYWJsZSwgYW4gSS9PIGVycm9yIG9jY3Vycywgb3IgdGhlIGVuZCBvZiB0aGUgc3RyZWFtIGlzIHJlYWNoZWQuCi0gICAgICoKLSAgICAgKiA8cD4gU3ViY2xhc3NlcyB0aGF0IGludGVuZCB0byBzdXBwb3J0IGVmZmljaWVudCBzaW5nbGUtY2hhcmFjdGVyIGlucHV0Ci0gICAgICogc2hvdWxkIG92ZXJyaWRlIHRoaXMgbWV0aG9kLgotICAgICAqCi0gICAgICogQHJldHVybiAgICAgVGhlIGNoYXJhY3RlciByZWFkLCBhcyBhbiBpbnRlZ2VyIGluIHRoZSByYW5nZSAwIHRvIDEyNwotICAgICAqICAgICAgICAgICAgICg8dHQ+MHgwMC0weDdmPC90dD4pLCBvciAtMSBpZiB0aGUgZW5kIG9mIHRoZSBzdHJlYW0gaGFzCi0gICAgICogICAgICAgICAgICAgYmVlbiByZWFjaGVkCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uICBJT0V4Y2VwdGlvbiAgSWYgYW4gSS9PIGVycm9yIG9jY3VycwotICAgICAqLwotICAgIHB1YmxpYyBpbnQgcmVhZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgIGludCBiMCA9IGZJbnB1dFN0cmVhbS5yZWFkKCk7Ci0gICAgICAgIGlmIChiMCA+PSAweDgwKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkQnl0ZVNlcXVlbmNlRXhjZXB0aW9uKGZGb3JtYXR0ZXIsCi0gICAgICAgICAgICAgICAgZkxvY2FsZSwgWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLAotICAgICAgICAgICAgICAgICJJbnZhbGlkQVNDSUkiLCBuZXcgT2JqZWN0IFtdIHtJbnRlZ2VyLnRvU3RyaW5nKGIwKX0pOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBiMDsKLSAgICB9IC8vIHJlYWQoKTppbnQKLQotICAgIC8qKgotICAgICAqIFJlYWQgY2hhcmFjdGVycyBpbnRvIGEgcG9ydGlvbiBvZiBhbiBhcnJheS4gIFRoaXMgbWV0aG9kIHdpbGwgYmxvY2sKLSAgICAgKiB1bnRpbCBzb21lIGlucHV0IGlzIGF2YWlsYWJsZSwgYW4gSS9PIGVycm9yIG9jY3Vycywgb3IgdGhlIGVuZCBvZiB0aGUKLSAgICAgKiBzdHJlYW0gaXMgcmVhY2hlZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSAgICAgIGNoICAgICBEZXN0aW5hdGlvbiBidWZmZXIKLSAgICAgKiBAcGFyYW0gICAgICBvZmZzZXQgT2Zmc2V0IGF0IHdoaWNoIHRvIHN0YXJ0IHN0b3JpbmcgY2hhcmFjdGVycwotICAgICAqIEBwYXJhbSAgICAgIGxlbmd0aCBNYXhpbXVtIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHJlYWQKLSAgICAgKgotICAgICAqIEByZXR1cm4gICAgIFRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyByZWFkLCBvciAtMSBpZiB0aGUgZW5kIG9mIHRoZQotICAgICAqICAgICAgICAgICAgIHN0cmVhbSBoYXMgYmVlbiByZWFjaGVkCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uICBJT0V4Y2VwdGlvbiAgSWYgYW4gSS9PIGVycm9yIG9jY3VycwotICAgICAqLwotICAgIHB1YmxpYyBpbnQgcmVhZChjaGFyIGNoW10sIGludCBvZmZzZXQsIGludCBsZW5ndGgpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChsZW5ndGggPiBmQnVmZmVyLmxlbmd0aCkgewotICAgICAgICAgICAgbGVuZ3RoID0gZkJ1ZmZlci5sZW5ndGg7Ci0gICAgICAgIH0KLSAgICAgICAgaW50IGNvdW50ID0gZklucHV0U3RyZWFtLnJlYWQoZkJ1ZmZlciwgMCwgbGVuZ3RoKTsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7Ci0gICAgICAgICAgICBpbnQgYjAgPSBmQnVmZmVyW2ldOwotICAgICAgICAgICAgaWYgKGIwIDwgMCkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRCeXRlU2VxdWVuY2VFeGNlcHRpb24oZkZvcm1hdHRlciwKLSAgICAgICAgICAgICAgICAgICAgZkxvY2FsZSwgWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAiSW52YWxpZEFTQ0lJIiwgbmV3IE9iamVjdCBbXSB7SW50ZWdlci50b1N0cmluZyhiMCAmIDB4MEZGKX0pOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2hbb2Zmc2V0ICsgaV0gPSAoY2hhciliMDsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gY291bnQ7Ci0gICAgfSAvLyByZWFkKGNoYXJbXSxpbnQsaW50KQotCi0gICAgLyoqCi0gICAgICogU2tpcCBjaGFyYWN0ZXJzLiAgVGhpcyBtZXRob2Qgd2lsbCBibG9jayB1bnRpbCBzb21lIGNoYXJhY3RlcnMgYXJlCi0gICAgICogYXZhaWxhYmxlLCBhbiBJL08gZXJyb3Igb2NjdXJzLCBvciB0aGUgZW5kIG9mIHRoZSBzdHJlYW0gaXMgcmVhY2hlZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSAgbiAgVGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHNraXAKLSAgICAgKgotICAgICAqIEByZXR1cm4gICAgVGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIGFjdHVhbGx5IHNraXBwZWQKLSAgICAgKgotICAgICAqIEBleGNlcHRpb24gIElPRXhjZXB0aW9uICBJZiBhbiBJL08gZXJyb3Igb2NjdXJzCi0gICAgICovCi0gICAgcHVibGljIGxvbmcgc2tpcChsb25nIG4pIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgIHJldHVybiBmSW5wdXRTdHJlYW0uc2tpcChuKTsKLSAgICB9IC8vIHNraXAobG9uZyk6bG9uZwotCi0gICAgLyoqCi0gICAgICogVGVsbCB3aGV0aGVyIHRoaXMgc3RyZWFtIGlzIHJlYWR5IHRvIGJlIHJlYWQuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRydWUgaWYgdGhlIG5leHQgcmVhZCgpIGlzIGd1YXJhbnRlZWQgbm90IHRvIGJsb2NrIGZvciBpbnB1dCwKLSAgICAgKiBmYWxzZSBvdGhlcndpc2UuICBOb3RlIHRoYXQgcmV0dXJuaW5nIGZhbHNlIGRvZXMgbm90IGd1YXJhbnRlZSB0aGF0IHRoZQotICAgICAqIG5leHQgcmVhZCB3aWxsIGJsb2NrLgotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiAgSU9FeGNlcHRpb24gIElmIGFuIEkvTyBlcnJvciBvY2N1cnMKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiByZWFkeSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfSAvLyByZWFkeSgpCi0KLSAgICAvKioKLSAgICAgKiBUZWxsIHdoZXRoZXIgdGhpcyBzdHJlYW0gc3VwcG9ydHMgdGhlIG1hcmsoKSBvcGVyYXRpb24uCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gbWFya1N1cHBvcnRlZCgpIHsKLSAgICAgICAgICAgIHJldHVybiBmSW5wdXRTdHJlYW0ubWFya1N1cHBvcnRlZCgpOwotICAgIH0gLy8gbWFya1N1cHBvcnRlZCgpCi0KLSAgICAvKioKLSAgICAgKiBNYXJrIHRoZSBwcmVzZW50IHBvc2l0aW9uIGluIHRoZSBzdHJlYW0uICBTdWJzZXF1ZW50IGNhbGxzIHRvIHJlc2V0KCkKLSAgICAgKiB3aWxsIGF0dGVtcHQgdG8gcmVwb3NpdGlvbiB0aGUgc3RyZWFtIHRvIHRoaXMgcG9pbnQuICBOb3QgYWxsCi0gICAgICogY2hhcmFjdGVyLWlucHV0IHN0cmVhbXMgc3VwcG9ydCB0aGUgbWFyaygpIG9wZXJhdGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSAgcmVhZEFoZWFkTGltaXQgIExpbWl0IG9uIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyB0aGF0IG1heSBiZQotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIHJlYWQgd2hpbGUgc3RpbGwgcHJlc2VydmluZyB0aGUgbWFyay4gIEFmdGVyCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgcmVhZGluZyB0aGlzIG1hbnkgY2hhcmFjdGVycywgYXR0ZW1wdGluZyB0bwotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIHJlc2V0IHRoZSBzdHJlYW0gbWF5IGZhaWwuCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uICBJT0V4Y2VwdGlvbiAgSWYgdGhlIHN0cmVhbSBkb2VzIG5vdCBzdXBwb3J0IG1hcmsoKSwKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgb3IgaWYgc29tZSBvdGhlciBJL08gZXJyb3Igb2NjdXJzCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgbWFyayhpbnQgcmVhZEFoZWFkTGltaXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgICAgICBmSW5wdXRTdHJlYW0ubWFyayhyZWFkQWhlYWRMaW1pdCk7Ci0gICAgfSAvLyBtYXJrKGludCkKLQotICAgIC8qKgotICAgICAqIFJlc2V0IHRoZSBzdHJlYW0uICBJZiB0aGUgc3RyZWFtIGhhcyBiZWVuIG1hcmtlZCwgdGhlbiBhdHRlbXB0IHRvCi0gICAgICogcmVwb3NpdGlvbiBpdCBhdCB0aGUgbWFyay4gIElmIHRoZSBzdHJlYW0gaGFzIG5vdCBiZWVuIG1hcmtlZCwgdGhlbgotICAgICAqIGF0dGVtcHQgdG8gcmVzZXQgaXQgaW4gc29tZSB3YXkgYXBwcm9wcmlhdGUgdG8gdGhlIHBhcnRpY3VsYXIgc3RyZWFtLAotICAgICAqIGZvciBleGFtcGxlIGJ5IHJlcG9zaXRpb25pbmcgaXQgdG8gaXRzIHN0YXJ0aW5nIHBvaW50LiAgTm90IGFsbAotICAgICAqIGNoYXJhY3Rlci1pbnB1dCBzdHJlYW1zIHN1cHBvcnQgdGhlIHJlc2V0KCkgb3BlcmF0aW9uLCBhbmQgc29tZSBzdXBwb3J0Ci0gICAgICogcmVzZXQoKSB3aXRob3V0IHN1cHBvcnRpbmcgbWFyaygpLgotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiAgSU9FeGNlcHRpb24gIElmIHRoZSBzdHJlYW0gaGFzIG5vdCBiZWVuIG1hcmtlZCwKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgb3IgaWYgdGhlIG1hcmsgaGFzIGJlZW4gaW52YWxpZGF0ZWQsCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgIG9yIGlmIHRoZSBzdHJlYW0gZG9lcyBub3Qgc3VwcG9ydCByZXNldCgpLAotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICBvciBpZiBzb21lIG90aGVyIEkvTyBlcnJvciBvY2N1cnMKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCByZXNldCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgIGZJbnB1dFN0cmVhbS5yZXNldCgpOwotICAgIH0gLy8gcmVzZXQoKQotCi0gICAgLyoqCi0gICAgICogQ2xvc2UgdGhlIHN0cmVhbS4gIE9uY2UgYSBzdHJlYW0gaGFzIGJlZW4gY2xvc2VkLCBmdXJ0aGVyIHJlYWQoKSwKLSAgICAgKiByZWFkeSgpLCBtYXJrKCksIG9yIHJlc2V0KCkgaW52b2NhdGlvbnMgd2lsbCB0aHJvdyBhbiBJT0V4Y2VwdGlvbi4KLSAgICAgKiBDbG9zaW5nIGEgcHJldmlvdXNseS1jbG9zZWQgc3RyZWFtLCBob3dldmVyLCBoYXMgbm8gZWZmZWN0LgotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiAgSU9FeGNlcHRpb24gIElmIGFuIEkvTyBlcnJvciBvY2N1cnMKLSAgICAgKi8KLSAgICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgICAgICAgQnVmZmVyQWxsb2NhdG9yIGJhID0gVGhyZWFkTG9jYWxCdWZmZXJBbGxvY2F0b3IuZ2V0QnVmZmVyQWxsb2NhdG9yKCk7Ci0gICAgICAgICBiYS5yZXR1cm5CeXRlQnVmZmVyKGZCdWZmZXIpOwotICAgICAgICAgZkJ1ZmZlciA9IG51bGw7Ci0gICAgICAgICBmSW5wdXRTdHJlYW0uY2xvc2UoKTsKLSAgICAgfSAvLyBjbG9zZSgpCi0KLX0gLy8gY2xhc3MgQVNDSUlSZWFkZXIKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvaW8vTWFsZm9ybWVkQnl0ZVNlcXVlbmNlRXhjZXB0aW9uLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2lvL01hbGZvcm1lZEJ5dGVTZXF1ZW5jZUV4Y2VwdGlvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkNjg1MTc3Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvaW8vTWFsZm9ybWVkQnl0ZVNlcXVlbmNlRXhjZXB0aW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMzkgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmlvOwotCi1pbXBvcnQgamF2YS5pby5DaGFyQ29udmVyc2lvbkV4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5NZXNzYWdlRm9ybWF0dGVyOwotCi0vKioKLSAqIDxwPlNpZ25hbHMgdGhhdCBhIG1hbGZvcm1lZCBieXRlIHNlcXVlbmNlIHdhcyBkZXRlY3RlZAotICogYnkgYSA8Y29kZT5qYXZhLmlvLlJlYWRlcjwvY29kZT4gdGhhdCBkZWNvZGVzIGJ5dGVzCi0gKiBvZiBhIGdpdmVuIGVuY29kaW5nIGludG8gY2hhcmFjdGVycy48L3A+Ci0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgTWljaGFlbCBHbGF2YXNzZXZpY2gsIElCTQotICoKLSAqLwotcHVibGljIGNsYXNzIE1hbGZvcm1lZEJ5dGVTZXF1ZW5jZUV4Y2VwdGlvbiBleHRlbmRzIENoYXJDb252ZXJzaW9uRXhjZXB0aW9uIHsKLQotICAgIC8qKiBTZXJpYWxpemF0aW9uIHZlcnNpb24uICovCi0gICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDg0MzYzODIyNDUwNDgzMjg3MzlMOwotCi0gICAgLy8KLSAgICAvLyBEYXRhCi0gICAgLy8KLQotICAgIC8qKiBtZXNzYWdlIGZvcm1hdHRlciAqKi8KLSAgICBwcml2YXRlIE1lc3NhZ2VGb3JtYXR0ZXIgZkZvcm1hdHRlcjsKLQotICAgIC8qKiBsb2NhbGUgZm9yIGVycm9yIG1lc3NhZ2UgKiovCi0gICAgcHJpdmF0ZSBMb2NhbGUgZkxvY2FsZTsKLQotICAgIC8qKiBlcnJvciBkb21haW4gKiovCi0gICAgcHJpdmF0ZSBTdHJpbmcgZkRvbWFpbjsKLQotICAgIC8qKiBrZXkgZm9yIHRoZSBlcnJvciBtZXNzYWdlICoqLwotICAgIHByaXZhdGUgU3RyaW5nIGZLZXk7Ci0KLSAgICAvKiogcmVwbGFjZW1lbnQgYXJndWVtZW50cyBmb3IgdGhlIGVycm9yIG1lc3NhZ2UgKiovCi0gICAgcHJpdmF0ZSBPYmplY3RbXSBmQXJndW1lbnRzOwotCi0gICAgLyoqIG1lc3NhZ2UgdGV4dCBmb3IgdGhpcyBtZXNzYWdlLCBpbml0aWFsbHkgbnVsbCAqKi8KLSAgICBwcml2YXRlIFN0cmluZyBmTWVzc2FnZTsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHMgYSBNYWxmb3JtZWRCeXRlU2VxdWVuY2VFeGNlcHRpb24gd2l0aCB0aGUgZ2l2ZW4KLSAgICAgKiBwYXJhbWV0ZXJzIHdoaWNoIG1heSBiZSBwYXNzZWQgdG8gYW4gZXJyb3IgcmVwb3J0ZXIgdG8KLSAgICAgKiBnZW5lcmF0ZSBhIGxvY2FsaXplZCBzdHJpbmcgZm9yIHRoaXMgZXhjZXB0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIGZvcm1hdHRlciBUaGUgTWVzc2FnZUZvcm1hdHRlciB1c2VkIGZvciBidWlsZGluZyB0aGUKLSAgICAgKiAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgdGV4dCBmb3IgdGhpcyBleGNlcHRpb24uCi0gICAgICogQHBhcmFtIGxvY2FsZSAgICBUaGUgTG9jYWxlIGZvciB3aGljaCBtZXNzYWdlcyBhcmUgdG8gYmUgcmVwb3J0ZWQuCi0gICAgICogQHBhcmFtIGRvbWFpbiAgICBUaGUgZXJyb3IgZG9tYWluLgotICAgICAqIEBwYXJhbSBrZXkgICAgICAgVGhlIGtleSBvZiB0aGUgZXJyb3IgbWVzc2FnZS4KLSAgICAgKiBAcGFyYW0gYXJndW1lbnRzIFRoZSByZXBsYWNlbWVudCBhcmd1bWVudHMgZm9yIHRoZSBlcnJvciBtZXNzYWdlLAotICAgICAqICAgICAgICAgICAgICAgICAgaWYgbmVlZGVkLgotICAgICAqLwotICAgIHB1YmxpYyBNYWxmb3JtZWRCeXRlU2VxdWVuY2VFeGNlcHRpb24oTWVzc2FnZUZvcm1hdHRlciBmb3JtYXR0ZXIsCi0gICAgICAgIExvY2FsZSBsb2NhbGUsIFN0cmluZyBkb21haW4sIFN0cmluZyBrZXksIE9iamVjdFtdIGFyZ3VtZW50cykgewotICAgICAgICBmRm9ybWF0dGVyID0gZm9ybWF0dGVyOwotICAgICAgICBmTG9jYWxlID0gbG9jYWxlOwotICAgICAgICBmRG9tYWluID0gZG9tYWluOwotICAgICAgICBmS2V5ID0ga2V5OwotICAgICAgICBmQXJndW1lbnRzID0gYXJndW1lbnRzOwotICAgIH0gLy8gPGluaXQ+KE1lc3NhZ2VGb3JtYXR0ZXIsIExvY2FsZSwgU3RyaW5nLCBTdHJpbmcsIE9iamVjdFtdKQotCi0gICAgLy8KLSAgICAvLyBQdWJsaWMgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiA8cD5SZXR1cm5zIHRoZSBlcnJvciBkb21haW4gb2YgdGhlIGVycm9yIG1lc3NhZ2UuPC9wPgotICAgICAqCi0gICAgICogQHJldHVybiB0aGUgZXJyb3IgZG9tYWluCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXREb21haW4gKCkgewotICAgICAgICByZXR1cm4gZkRvbWFpbjsKLSAgICB9IC8vIGdldERvbWFpbgotCi0gICAgLyoqCi0gICAgICogPHA+UmV0dXJucyB0aGUga2V5IG9mIHRoZSBlcnJvciBtZXNzYWdlLjwvcD4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdGhlIGVycm9yIGtleSBvZiB0aGUgZXJyb3IgbWVzc2FnZQotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0S2V5ICgpIHsKLSAgICAgICAgcmV0dXJuIGZLZXk7Ci0gICAgfSAvLyBnZXRLZXkoKQotCi0gICAgLyoqCi0gICAgICogPHA+UmV0dXJucyB0aGUgcmVwbGFjZW1lbnQgYXJndW1lbnRzIGZvciB0aGUgZXJyb3IKLSAgICAgKiBtZXNzYWdlIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIG5vbmUgZXhpc3QuPC9wPgotICAgICAqCi0gICAgICogQHJldHVybiB0aGUgcmVwbGFjZW1lbnQgYXJndW1lbnRzIGZvciB0aGUgZXJyb3IgbWVzc2FnZQotICAgICAqIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIG5vbmUgZXhpc3QKLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0W10gZ2V0QXJndW1lbnRzICgpIHsKLSAgICAgICAgcmV0dXJuIGZBcmd1bWVudHM7Ci0gICAgfSAvLyBnZXRBcmd1bWVudHMoKTsKLQotICAgIC8qKgotICAgICAqIDxwPlJldHVybnMgdGhlIGxvY2FsaXplZCBtZXNzYWdlIGZvciB0aGlzIGV4Y2VwdGlvbi48L3A+Ci0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRoZSBsb2NhbGl6ZWQgbWVzc2FnZSBmb3IgdGhpcyBleGNlcHRpb24uCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRNZXNzYWdlKCkgewotICAgICAgICBpZiAoZk1lc3NhZ2UgPT0gbnVsbCkgewotICAgICAgICAgICAgZk1lc3NhZ2UgPSBmRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoZkxvY2FsZSwgZktleSwgZkFyZ3VtZW50cyk7Ci0gICAgICAgICAgICAvLyBUaGUgcmVmZXJlbmNlcyB0byB0aGUgbWVzc2FnZSBmb3JtYXR0ZXIgYW5kIGxvY2FsZQotICAgICAgICAgICAgLy8gYXJlbid0IG5lZWRlZCBhbnltb3JlIHNvIG51bGwgdGhlbS4KLSAgICAgICAgICAgIGZGb3JtYXR0ZXIgPSBudWxsOwotICAgICAgICAgICAgZkxvY2FsZSA9IG51bGw7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGZNZXNzYWdlOwotICAgICB9IC8vIGdldE1lc3NhZ2UoKQotCi19IC8vIE1hbGZvcm1lZEJ5dGVTZXF1ZW5jZUV4Y2VwdGlvbgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9pby9VQ1NSZWFkZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvaW8vVUNTUmVhZGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDc0ZGI1ZjYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9pby9VQ1NSZWFkZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDMxMSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAwLTIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmlvOwotCi1pbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotaW1wb3J0IGphdmEuaW8uUmVhZGVyOwotCi1pbXBvcnQgY29tLnN1bi54bWwuaW50ZXJuYWwuc3RyZWFtLnV0aWwuQnVmZmVyQWxsb2NhdG9yOwotaW1wb3J0IGNvbS5zdW4ueG1sLmludGVybmFsLnN0cmVhbS51dGlsLlRocmVhZExvY2FsQnVmZmVyQWxsb2NhdG9yOwotCi0vKioKLSAqIFJlYWRlciBmb3IgVUNTLTIgYW5kIFVDUy00IGVuY29kaW5ncy4KLSAqIChpLmUuLCBlbmNvZGluZ3MgZnJvbSBJU08tMTA2NDYtVUNTLSgyfDQpKS4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBOZWlsIEdyYWhhbSwgSUJNCi0gKgotICovCi1wdWJsaWMgY2xhc3MgVUNTUmVhZGVyIGV4dGVuZHMgUmVhZGVyIHsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RhbnRzCi0gICAgLy8KLQotICAgIC8qKiBEZWZhdWx0IGJ5dGUgYnVmZmVyIHNpemUgKDgxOTIsIGxhcmdlciB0aGFuIHRoYXQgb2YgQVNDSUlSZWFkZXIKLSAgICAgKiBzaW5jZSBpdCdzIHJlYXNvbmFibGUgdG8gc3VybWlzZSB0aGF0IHRoZSBhdmVyYWdlIFVDUy00LWVuY29kZWQKLSAgICAgKiBmaWxlIHNob3VsZCBiZSA0IHRpbWVzIGFzIGxhcmdlIGFzIHRoZSBhdmVyYWdlIEFTQ0lJLWVuY29kZWQgZmlsZSkuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgREVGQVVMVF9CVUZGRVJfU0laRSA9IDgxOTI7Ci0KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFVDUzJMRSA9IDE7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBVQ1MyQkUgPSAyOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgVUNTNExFID0gNDsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFVDUzRCRSA9IDg7Ci0KLSAgICAvLwotICAgIC8vIERhdGEKLSAgICAvLwotCi0gICAgLyoqIElucHV0IHN0cmVhbS4gKi8KLSAgICBwcm90ZWN0ZWQgSW5wdXRTdHJlYW0gZklucHV0U3RyZWFtOwotCi0gICAgLyoqIEJ5dGUgYnVmZmVyLiAqLwotICAgIHByb3RlY3RlZCBieXRlW10gZkJ1ZmZlcjsKLQotICAgIC8vIHdoYXQga2luZCBvZiBkYXRhIHdlJ3JlIGRlYWxpbmcgd2l0aAotICAgIHByb3RlY3RlZCBzaG9ydCBmRW5jb2Rpbmc7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0cnVjdG9ycwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RzIGFuIEFTQ0lJIHJlYWRlciBmcm9tIHRoZSBzcGVjaWZpZWQgaW5wdXQgc3RyZWFtCi0gICAgICogdXNpbmcgdGhlIGRlZmF1bHQgYnVmZmVyIHNpemUuICBUaGUgRW5kaWFuLW5lc3MgYW5kIHdoZXRoZXIgdGhpcyBpcwotICAgICAqIFVDUy0yIG9yIFVDUy00IG5lZWRzIGFsc28gdG8gYmUga25vd24gaW4gYWR2YW5jZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBpbnB1dFN0cmVhbSBUaGUgaW5wdXQgc3RyZWFtLgotICAgICAqIEBwYXJhbSBlbmNvZGluZyBPbmUgb2YgVUNTMkxFLCBVQ1MyQkUsIFVDUzRMRSBvciBVQ1M0QkUuCi0gICAgICovCi0gICAgcHVibGljIFVDU1JlYWRlcihJbnB1dFN0cmVhbSBpbnB1dFN0cmVhbSwgc2hvcnQgZW5jb2RpbmcpIHsKLSAgICAgICAgdGhpcyhpbnB1dFN0cmVhbSwgREVGQVVMVF9CVUZGRVJfU0laRSwgZW5jb2RpbmcpOwotICAgIH0gLy8gPGluaXQ+KElucHV0U3RyZWFtLCBzaG9ydCkKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHMgYW4gQVNDSUkgcmVhZGVyIGZyb20gdGhlIHNwZWNpZmllZCBpbnB1dCBzdHJlYW0KLSAgICAgKiBhbmQgYnVmZmVyIHNpemUuICBUaGUgRW5kaWFuLW5lc3MgYW5kIHdoZXRoZXIgdGhpcyBpcwotICAgICAqIFVDUy0yIG9yIFVDUy00IG5lZWRzIGFsc28gdG8gYmUga25vd24gaW4gYWR2YW5jZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBpbnB1dFN0cmVhbSBUaGUgaW5wdXQgc3RyZWFtLgotICAgICAqIEBwYXJhbSBzaXplICAgICAgICBUaGUgaW5pdGlhbCBidWZmZXIgc2l6ZS4KLSAgICAgKiBAcGFyYW0gZW5jb2RpbmcgT25lIG9mIFVDUzJMRSwgVUNTMkJFLCBVQ1M0TEUgb3IgVUNTNEJFLgotICAgICAqLwotICAgIHB1YmxpYyBVQ1NSZWFkZXIoSW5wdXRTdHJlYW0gaW5wdXRTdHJlYW0sIGludCBzaXplLCBzaG9ydCBlbmNvZGluZykgewotICAgICAgICBmSW5wdXRTdHJlYW0gPSBpbnB1dFN0cmVhbTsKLSAgICAgICAgQnVmZmVyQWxsb2NhdG9yIGJhID0gVGhyZWFkTG9jYWxCdWZmZXJBbGxvY2F0b3IuZ2V0QnVmZmVyQWxsb2NhdG9yKCk7Ci0gICAgICAgIGZCdWZmZXIgPSBiYS5nZXRCeXRlQnVmZmVyKHNpemUpOwotICAgICAgICBpZiAoZkJ1ZmZlciA9PSBudWxsKSB7Ci0gICAgICAgICAgICBmQnVmZmVyID0gbmV3IGJ5dGVbc2l6ZV07Ci0gICAgICAgIH0KLSAgICAgICAgZkVuY29kaW5nID0gZW5jb2Rpbmc7Ci0gICAgfSAvLyA8aW5pdD4oSW5wdXRTdHJlYW0saW50LHNob3J0KQotCi0gICAgLy8KLSAgICAvLyBSZWFkZXIgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBSZWFkIGEgc2luZ2xlIGNoYXJhY3Rlci4gIFRoaXMgbWV0aG9kIHdpbGwgYmxvY2sgdW50aWwgYSBjaGFyYWN0ZXIgaXMKLSAgICAgKiBhdmFpbGFibGUsIGFuIEkvTyBlcnJvciBvY2N1cnMsIG9yIHRoZSBlbmQgb2YgdGhlIHN0cmVhbSBpcyByZWFjaGVkLgotICAgICAqCi0gICAgICogPHA+IFN1YmNsYXNzZXMgdGhhdCBpbnRlbmQgdG8gc3VwcG9ydCBlZmZpY2llbnQgc2luZ2xlLWNoYXJhY3RlciBpbnB1dAotICAgICAqIHNob3VsZCBvdmVycmlkZSB0aGlzIG1ldGhvZC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gICAgIFRoZSBjaGFyYWN0ZXIgcmVhZCwgYXMgYW4gaW50ZWdlciBpbiB0aGUgcmFuZ2UgMCB0byAxMjcKLSAgICAgKiAgICAgICAgICAgICAoPHR0PjB4MDAtMHg3ZjwvdHQ+KSwgb3IgLTEgaWYgdGhlIGVuZCBvZiB0aGUgc3RyZWFtIGhhcwotICAgICAqICAgICAgICAgICAgIGJlZW4gcmVhY2hlZAotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiAgSU9FeGNlcHRpb24gIElmIGFuIEkvTyBlcnJvciBvY2N1cnMKLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IHJlYWQoKSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgICAgICBpbnQgYjAgPSBmSW5wdXRTdHJlYW0ucmVhZCgpICYgMHhmZjsKLSAgICAgICAgaWYgKGIwID09IDB4ZmYpCi0gICAgICAgICAgICByZXR1cm4gLTE7Ci0gICAgICAgIGludCBiMSA9IGZJbnB1dFN0cmVhbS5yZWFkKCkgJiAweGZmOwotICAgICAgICBpZiAoYjEgPT0gMHhmZikKLSAgICAgICAgICAgIHJldHVybiAtMTsKLSAgICAgICAgaWYoZkVuY29kaW5nID49NCkgewotICAgICAgICAgICAgaW50IGIyID0gZklucHV0U3RyZWFtLnJlYWQoKSAmIDB4ZmY7Ci0gICAgICAgICAgICBpZiAoYjIgPT0gMHhmZikKLSAgICAgICAgICAgICAgICByZXR1cm4gLTE7Ci0gICAgICAgICAgICBpbnQgYjMgPSBmSW5wdXRTdHJlYW0ucmVhZCgpICYgMHhmZjsKLSAgICAgICAgICAgIGlmIChiMyA9PSAweGZmKQotICAgICAgICAgICAgICAgIHJldHVybiAtMTsKLSAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiYjAgaXMgIiArIChiMCAmIDB4ZmYpICsgIiBiMSAiICsgKGIxICYgMHhmZikgKyAiIGIyICIgKyAoYjIgJiAweGZmKSArICIgYjMgIiArIChiMyAmIDB4ZmYpKTsKLSAgICAgICAgICAgIGlmIChmRW5jb2RpbmcgPT0gVUNTNEJFKQotICAgICAgICAgICAgICAgIHJldHVybiAoYjA8PDI0KSsoYjE8PDE2KSsoYjI8PDgpK2IzOwotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIHJldHVybiAoYjM8PDI0KSsoYjI8PDE2KSsoYjE8PDgpK2IwOwotICAgICAgICB9IGVsc2UgeyAvLyBVQ1MtMgotICAgICAgICAgICAgaWYgKGZFbmNvZGluZyA9PSBVQ1MyQkUpCi0gICAgICAgICAgICAgICAgcmV0dXJuIChiMDw8OCkrYjE7Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgcmV0dXJuIChiMTw8OCkrYjA7Ci0gICAgICAgIH0KLSAgICB9IC8vIHJlYWQoKTppbnQKLQotICAgIC8qKgotICAgICAqIFJlYWQgY2hhcmFjdGVycyBpbnRvIGEgcG9ydGlvbiBvZiBhbiBhcnJheS4gIFRoaXMgbWV0aG9kIHdpbGwgYmxvY2sKLSAgICAgKiB1bnRpbCBzb21lIGlucHV0IGlzIGF2YWlsYWJsZSwgYW4gSS9PIGVycm9yIG9jY3Vycywgb3IgdGhlIGVuZCBvZiB0aGUKLSAgICAgKiBzdHJlYW0gaXMgcmVhY2hlZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSAgICAgIGNoICAgICBEZXN0aW5hdGlvbiBidWZmZXIKLSAgICAgKiBAcGFyYW0gICAgICBvZmZzZXQgT2Zmc2V0IGF0IHdoaWNoIHRvIHN0YXJ0IHN0b3JpbmcgY2hhcmFjdGVycwotICAgICAqIEBwYXJhbSAgICAgIGxlbmd0aCBNYXhpbXVtIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHJlYWQKLSAgICAgKgotICAgICAqIEByZXR1cm4gICAgIFRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyByZWFkLCBvciAtMSBpZiB0aGUgZW5kIG9mIHRoZQotICAgICAqICAgICAgICAgICAgIHN0cmVhbSBoYXMgYmVlbiByZWFjaGVkCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uICBJT0V4Y2VwdGlvbiAgSWYgYW4gSS9PIGVycm9yIG9jY3VycwotICAgICAqLwotICAgIHB1YmxpYyBpbnQgcmVhZChjaGFyIGNoW10sIGludCBvZmZzZXQsIGludCBsZW5ndGgpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgIGludCBieXRlTGVuZ3RoID0gbGVuZ3RoIDw8ICgoZkVuY29kaW5nID49IDQpPzI6MSk7Ci0gICAgICAgIGlmIChieXRlTGVuZ3RoID4gZkJ1ZmZlci5sZW5ndGgpIHsKLSAgICAgICAgICAgIGJ5dGVMZW5ndGggPSBmQnVmZmVyLmxlbmd0aDsKLSAgICAgICAgfQotICAgICAgICBpbnQgY291bnQgPSBmSW5wdXRTdHJlYW0ucmVhZChmQnVmZmVyLCAwLCBieXRlTGVuZ3RoKTsKLSAgICAgICAgaWYoY291bnQgPT0gLTEpIHJldHVybiAtMTsKLSAgICAgICAgLy8gdHJ5IGFuZCBtYWtlIGNvdW50IGJlIGEgbXVsdGlwbGUgb2YgdGhlIG51bWJlciBvZiBieXRlcyB3ZSdyZSBsb29raW5nIGZvcgotICAgICAgICBpZihmRW5jb2RpbmcgPj0gNCkgeyAvLyBCaWdFbmRpYW4KLSAgICAgICAgICAgIC8vIHRoaXMgbG9va3MgdWdseSwgYnV0IGl0IGF2b2lkcyBhbiBpZiBhdCBhbnkgcmF0ZS4uLgotICAgICAgICAgICAgaW50IG51bVRvUmVhZCA9ICg0IC0gKGNvdW50ICYgMykgJiAzKTsKLSAgICAgICAgICAgIGZvcihpbnQgaT0wOyBpPG51bVRvUmVhZDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgaW50IGNoYXJSZWFkID0gZklucHV0U3RyZWFtLnJlYWQoKTsKLSAgICAgICAgICAgICAgICBpZihjaGFyUmVhZCA9PSAtMSkgeyAvLyBlbmQgb2YgaW5wdXQ7IHNvbWV0aGluZyBsaWtlbHkgd2VudCB3cm9uZyFBICBQYWQgYnVmZmVyIHdpdGggbnVsbHMuCi0gICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGogPSBpO2o8bnVtVG9SZWFkOyBqKyspCi0gICAgICAgICAgICAgICAgICAgICAgICBmQnVmZmVyW2NvdW50K2pdID0gMDsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgZkJ1ZmZlcltjb3VudCtpXSA9IChieXRlKWNoYXJSZWFkOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNvdW50ICs9IG51bVRvUmVhZDsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIGludCBudW1Ub1JlYWQgPSBjb3VudCAmIDE7Ci0gICAgICAgICAgICBpZihudW1Ub1JlYWQgIT0gMCkgewotICAgICAgICAgICAgICAgIGNvdW50Kys7Ci0gICAgICAgICAgICAgICAgaW50IGNoYXJSZWFkID0gZklucHV0U3RyZWFtLnJlYWQoKTsKLSAgICAgICAgICAgICAgICBpZihjaGFyUmVhZCA9PSAtMSkgeyAvLyBlbmQgb2YgaW5wdXQ7IHNvbWV0aGluZyBsaWtlbHkgd2VudCB3cm9uZyFBICBQYWQgYnVmZmVyIHdpdGggbnVsbHMuCi0gICAgICAgICAgICAgICAgICAgIGZCdWZmZXJbY291bnRdID0gMDsKLSAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICBmQnVmZmVyW2NvdW50XSA9IChieXRlKWNoYXJSZWFkOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIG5vdyBjb3VudCBpcyBhIG11bHRpcGxlIG9mIHRoZSByaWdodCBudW1iZXIgb2YgYnl0ZXMKLSAgICAgICAgaW50IG51bUNoYXJzID0gY291bnQgPj4gKChmRW5jb2RpbmcgPj0gNCk/MjoxKTsKLSAgICAgICAgaW50IGN1clBvcyA9IDA7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtQ2hhcnM7IGkrKykgewotICAgICAgICAgICAgaW50IGIwID0gZkJ1ZmZlcltjdXJQb3MrK10gJiAweGZmOwotICAgICAgICAgICAgaW50IGIxID0gZkJ1ZmZlcltjdXJQb3MrK10gJiAweGZmOwotICAgICAgICAgICAgaWYoZkVuY29kaW5nID49NCkgewotICAgICAgICAgICAgICAgIGludCBiMiA9IGZCdWZmZXJbY3VyUG9zKytdICYgMHhmZjsKLSAgICAgICAgICAgICAgICBpbnQgYjMgPSBmQnVmZmVyW2N1clBvcysrXSAmIDB4ZmY7Ci0gICAgICAgICAgICAgICAgaWYgKGZFbmNvZGluZyA9PSBVQ1M0QkUpCi0gICAgICAgICAgICAgICAgICAgIGNoW29mZnNldCtpXSA9IChjaGFyKSgoYjA8PDI0KSsoYjE8PDE2KSsoYjI8PDgpK2IzKTsKLSAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgIGNoW29mZnNldCtpXSA9IChjaGFyKSgoYjM8PDI0KSsoYjI8PDE2KSsoYjE8PDgpK2IwKTsKLSAgICAgICAgICAgIH0gZWxzZSB7IC8vIFVDUy0yCi0gICAgICAgICAgICAgICAgaWYgKGZFbmNvZGluZyA9PSBVQ1MyQkUpCi0gICAgICAgICAgICAgICAgICAgIGNoW29mZnNldCtpXSA9IChjaGFyKSgoYjA8PDgpK2IxKTsKLSAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgIGNoW29mZnNldCtpXSA9IChjaGFyKSgoYjE8PDgpK2IwKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbnVtQ2hhcnM7Ci0gICAgfSAvLyByZWFkKGNoYXJbXSxpbnQsaW50KQotCi0gICAgLyoqCi0gICAgICogU2tpcCBjaGFyYWN0ZXJzLiAgVGhpcyBtZXRob2Qgd2lsbCBibG9jayB1bnRpbCBzb21lIGNoYXJhY3RlcnMgYXJlCi0gICAgICogYXZhaWxhYmxlLCBhbiBJL08gZXJyb3Igb2NjdXJzLCBvciB0aGUgZW5kIG9mIHRoZSBzdHJlYW0gaXMgcmVhY2hlZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSAgbiAgVGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHNraXAKLSAgICAgKgotICAgICAqIEByZXR1cm4gICAgVGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIGFjdHVhbGx5IHNraXBwZWQKLSAgICAgKgotICAgICAqIEBleGNlcHRpb24gIElPRXhjZXB0aW9uICBJZiBhbiBJL08gZXJyb3Igb2NjdXJzCi0gICAgICovCi0gICAgcHVibGljIGxvbmcgc2tpcChsb25nIG4pIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgIC8vIGNoYXJXaWR0aCB3aWxsIHJlcHJlc2VudCB0aGUgbnVtYmVyIG9mIGJpdHMgdG8gbW92ZQotICAgICAgICAvLyBuIGxlZnR3YXJkIHRvIGdldCBudW0gb2YgYnl0ZXMgdG8gc2tpcCwgYW5kIHRoZW4gbW92ZSB0aGUgcmVzdWx0IHJpZ2h0d2FyZAotICAgICAgICAvLyB0byBnZXQgbnVtIG9mIGNoYXJzIGVmZmVjdGl2ZWx5IHNraXBwZWQuCi0gICAgICAgIC8vIFRoZSB0cmljayB3aXRoICYnaW5nLCBhcyB3aXRoIGVsc2V3aGVyZSBpbiB0aGlzIGRjb2RlLCBpcwotICAgICAgICAvLyBpbnRlbmRlZCB0byBhdm9pZCBhbiBleHBlbnNpdmUgdXNlIG9mIC8gdGhhdCBtaWdodCBub3QgYmUgb3B0aW1pemVkCi0gICAgICAgIC8vIGF3YXkuCi0gICAgICAgIGludCBjaGFyV2lkdGggPSAoZkVuY29kaW5nID49NCk/MjoxOwotICAgICAgICBsb25nIGJ5dGVzU2tpcHBlZCA9IGZJbnB1dFN0cmVhbS5za2lwKG48PGNoYXJXaWR0aCk7Ci0gICAgICAgIGlmKChieXRlc1NraXBwZWQgJiAoY2hhcldpZHRoIHwgMSkpID09IDApIHJldHVybiBieXRlc1NraXBwZWQgPj4gY2hhcldpZHRoOwotICAgICAgICByZXR1cm4gKGJ5dGVzU2tpcHBlZCA+PiBjaGFyV2lkdGgpICsgMTsKLSAgICB9IC8vIHNraXAobG9uZyk6bG9uZwotCi0gICAgLyoqCi0gICAgICogVGVsbCB3aGV0aGVyIHRoaXMgc3RyZWFtIGlzIHJlYWR5IHRvIGJlIHJlYWQuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRydWUgaWYgdGhlIG5leHQgcmVhZCgpIGlzIGd1YXJhbnRlZWQgbm90IHRvIGJsb2NrIGZvciBpbnB1dCwKLSAgICAgKiBmYWxzZSBvdGhlcndpc2UuICBOb3RlIHRoYXQgcmV0dXJuaW5nIGZhbHNlIGRvZXMgbm90IGd1YXJhbnRlZSB0aGF0IHRoZQotICAgICAqIG5leHQgcmVhZCB3aWxsIGJsb2NrLgotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiAgSU9FeGNlcHRpb24gIElmIGFuIEkvTyBlcnJvciBvY2N1cnMKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiByZWFkeSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfSAvLyByZWFkeSgpCi0KLSAgICAvKioKLSAgICAgKiBUZWxsIHdoZXRoZXIgdGhpcyBzdHJlYW0gc3VwcG9ydHMgdGhlIG1hcmsoKSBvcGVyYXRpb24uCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gbWFya1N1cHBvcnRlZCgpIHsKLSAgICAgICAgICAgIHJldHVybiBmSW5wdXRTdHJlYW0ubWFya1N1cHBvcnRlZCgpOwotICAgIH0gLy8gbWFya1N1cHBvcnRlZCgpCi0KLSAgICAvKioKLSAgICAgKiBNYXJrIHRoZSBwcmVzZW50IHBvc2l0aW9uIGluIHRoZSBzdHJlYW0uICBTdWJzZXF1ZW50IGNhbGxzIHRvIHJlc2V0KCkKLSAgICAgKiB3aWxsIGF0dGVtcHQgdG8gcmVwb3NpdGlvbiB0aGUgc3RyZWFtIHRvIHRoaXMgcG9pbnQuICBOb3QgYWxsCi0gICAgICogY2hhcmFjdGVyLWlucHV0IHN0cmVhbXMgc3VwcG9ydCB0aGUgbWFyaygpIG9wZXJhdGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSAgcmVhZEFoZWFkTGltaXQgIExpbWl0IG9uIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyB0aGF0IG1heSBiZQotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIHJlYWQgd2hpbGUgc3RpbGwgcHJlc2VydmluZyB0aGUgbWFyay4gIEFmdGVyCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgcmVhZGluZyB0aGlzIG1hbnkgY2hhcmFjdGVycywgYXR0ZW1wdGluZyB0bwotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIHJlc2V0IHRoZSBzdHJlYW0gbWF5IGZhaWwuCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uICBJT0V4Y2VwdGlvbiAgSWYgdGhlIHN0cmVhbSBkb2VzIG5vdCBzdXBwb3J0IG1hcmsoKSwKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgb3IgaWYgc29tZSBvdGhlciBJL08gZXJyb3Igb2NjdXJzCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgbWFyayhpbnQgcmVhZEFoZWFkTGltaXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgICAgICBmSW5wdXRTdHJlYW0ubWFyayhyZWFkQWhlYWRMaW1pdCk7Ci0gICAgfSAvLyBtYXJrKGludCkKLQotICAgIC8qKgotICAgICAqIFJlc2V0IHRoZSBzdHJlYW0uICBJZiB0aGUgc3RyZWFtIGhhcyBiZWVuIG1hcmtlZCwgdGhlbiBhdHRlbXB0IHRvCi0gICAgICogcmVwb3NpdGlvbiBpdCBhdCB0aGUgbWFyay4gIElmIHRoZSBzdHJlYW0gaGFzIG5vdCBiZWVuIG1hcmtlZCwgdGhlbgotICAgICAqIGF0dGVtcHQgdG8gcmVzZXQgaXQgaW4gc29tZSB3YXkgYXBwcm9wcmlhdGUgdG8gdGhlIHBhcnRpY3VsYXIgc3RyZWFtLAotICAgICAqIGZvciBleGFtcGxlIGJ5IHJlcG9zaXRpb25pbmcgaXQgdG8gaXRzIHN0YXJ0aW5nIHBvaW50LiAgTm90IGFsbAotICAgICAqIGNoYXJhY3Rlci1pbnB1dCBzdHJlYW1zIHN1cHBvcnQgdGhlIHJlc2V0KCkgb3BlcmF0aW9uLCBhbmQgc29tZSBzdXBwb3J0Ci0gICAgICogcmVzZXQoKSB3aXRob3V0IHN1cHBvcnRpbmcgbWFyaygpLgotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiAgSU9FeGNlcHRpb24gIElmIHRoZSBzdHJlYW0gaGFzIG5vdCBiZWVuIG1hcmtlZCwKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgb3IgaWYgdGhlIG1hcmsgaGFzIGJlZW4gaW52YWxpZGF0ZWQsCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgIG9yIGlmIHRoZSBzdHJlYW0gZG9lcyBub3Qgc3VwcG9ydCByZXNldCgpLAotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICBvciBpZiBzb21lIG90aGVyIEkvTyBlcnJvciBvY2N1cnMKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCByZXNldCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgIGZJbnB1dFN0cmVhbS5yZXNldCgpOwotICAgIH0gLy8gcmVzZXQoKQotCi0gICAgLyoqCi0gICAgICogQ2xvc2UgdGhlIHN0cmVhbS4gIE9uY2UgYSBzdHJlYW0gaGFzIGJlZW4gY2xvc2VkLCBmdXJ0aGVyIHJlYWQoKSwKLSAgICAgKiByZWFkeSgpLCBtYXJrKCksIG9yIHJlc2V0KCkgaW52b2NhdGlvbnMgd2lsbCB0aHJvdyBhbiBJT0V4Y2VwdGlvbi4KLSAgICAgKiBDbG9zaW5nIGEgcHJldmlvdXNseS1jbG9zZWQgc3RyZWFtLCBob3dldmVyLCBoYXMgbm8gZWZmZWN0LgotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiAgSU9FeGNlcHRpb24gIElmIGFuIEkvTyBlcnJvciBvY2N1cnMKLSAgICAgKi8KLSAgICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgICAgICAgQnVmZmVyQWxsb2NhdG9yIGJhID0gVGhyZWFkTG9jYWxCdWZmZXJBbGxvY2F0b3IuZ2V0QnVmZmVyQWxsb2NhdG9yKCk7Ci0gICAgICAgICBiYS5yZXR1cm5CeXRlQnVmZmVyKGZCdWZmZXIpOwotICAgICAgICAgZkJ1ZmZlciA9IG51bGw7Ci0gICAgICAgICBmSW5wdXRTdHJlYW0uY2xvc2UoKTsKLSAgICAgfSAvLyBjbG9zZSgpCi0KLX0gLy8gY2xhc3MgVUNTUmVhZGVyCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL2lvL1VURjhSZWFkZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvaW8vVVRGOFJlYWRlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0NjI0MjA1Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvaW8vVVRGOFJlYWRlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNzE2ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDAtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmlvOwotCi1pbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotaW1wb3J0IGphdmEuaW8uUmVhZGVyOwotCi1pbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuTWVzc2FnZUZvcm1hdHRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwubXNnLlhNTE1lc3NhZ2VGb3JtYXR0ZXI7Ci0KLWltcG9ydCBjb20uc3VuLnhtbC5pbnRlcm5hbC5zdHJlYW0udXRpbC5CdWZmZXJBbGxvY2F0b3I7Ci1pbXBvcnQgY29tLnN1bi54bWwuaW50ZXJuYWwuc3RyZWFtLnV0aWwuVGhyZWFkTG9jYWxCdWZmZXJBbGxvY2F0b3I7Ci0KLS8qKgotICogPHA+QSBVVEYtOCByZWFkZXIuPC9wPgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIEFuZHkgQ2xhcmssIElCTQotICoKLSAqLwotcHVibGljIGNsYXNzIFVURjhSZWFkZXIKLSAgICBleHRlbmRzIFJlYWRlciB7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0YW50cwotICAgIC8vCi0KLSAgICAvKiogRGVmYXVsdCBieXRlIGJ1ZmZlciBzaXplICgyMDQ4KS4gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBERUZBVUxUX0JVRkZFUl9TSVpFID0gMjA0ODsKLQotICAgIC8vIGRlYnVnZ2luZwotCi0gICAgLyoqIERlYnVnIHJlYWQuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbiBERUJVR19SRUFEID0gZmFsc2U7Ci0KLSAgICAvLwotICAgIC8vIERhdGEKLSAgICAvLwotCi0gICAgLyoqIElucHV0IHN0cmVhbS4gKi8KLSAgICBwcm90ZWN0ZWQgSW5wdXRTdHJlYW0gZklucHV0U3RyZWFtOwotCi0gICAgLyoqIEJ5dGUgYnVmZmVyLiAqLwotICAgIHByb3RlY3RlZCBieXRlW10gZkJ1ZmZlcjsKLQotICAgIC8qKiBPZmZzZXQgaW50byBidWZmZXIuICovCi0gICAgcHJvdGVjdGVkIGludCBmT2Zmc2V0OwotCi0gICAgLyoqIFN1cnJvZ2F0ZSBjaGFyYWN0ZXIuICovCi0gICAgcHJpdmF0ZSBpbnQgZlN1cnJvZ2F0ZSA9IC0xOwotCi0gICAgLy8gbWVzc2FnZSBmb3JtYXR0ZXI7IHVzZWQgdG8gcHJvZHVjZSBsb2NhbGl6ZWQKLSAgICAvLyBleGNlcHRpb24gbWVzc2FnZXMKLSAgICBwcml2YXRlIE1lc3NhZ2VGb3JtYXR0ZXIgZkZvcm1hdHRlciA9IG51bGw7Ci0KLSAgICAvL0xvY2FsZSB0byB1c2UgZm9yIG1lc3NhZ2VzCi0gICAgcHJpdmF0ZSBMb2NhbGUgZkxvY2FsZSA9IG51bGw7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0cnVjdG9ycwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RzIGEgVVRGLTggcmVhZGVyIGZyb20gdGhlIHNwZWNpZmllZCBpbnB1dCBzdHJlYW0KLSAgICAgKiB1c2luZyB0aGUgZGVmYXVsdCBidWZmZXIgc2l6ZS4gIFByaW1hcmlseSBmb3IgdGVzdGluZy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBpbnB1dFN0cmVhbSBUaGUgaW5wdXQgc3RyZWFtLgotICAgICAqLwotICAgIHB1YmxpYyBVVEY4UmVhZGVyKElucHV0U3RyZWFtIGlucHV0U3RyZWFtKSB7Ci0gICAgICAgIHRoaXMoaW5wdXRTdHJlYW0sIERFRkFVTFRfQlVGRkVSX1NJWkUsIG5ldyBYTUxNZXNzYWdlRm9ybWF0dGVyKCksIExvY2FsZS5nZXREZWZhdWx0KCkpOwotICAgIH0gLy8gPGluaXQ+KElucHV0U3RyZWFtLCBNZXNzYWdlRm9ybWF0dGVyKQotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0cyBhIFVURi04IHJlYWRlciBmcm9tIHRoZSBzcGVjaWZpZWQgaW5wdXQgc3RyZWFtCi0gICAgICogdXNpbmcgdGhlIGRlZmF1bHQgYnVmZmVyIHNpemUgYW5kIHRoZSBnaXZlbiBNZXNzYWdlRm9ybWF0dGVyLgotICAgICAqCi0gICAgICogQHBhcmFtIGlucHV0U3RyZWFtIFRoZSBpbnB1dCBzdHJlYW0uCi0gICAgICogQHBhcmFtIG1lc3NhZ2VGb3JtYXR0ZXIgIGdpdmVuIE1lc3NhZ2VGb3JtYXR0ZXIKLSAgICAgKiBAcGFyYW0gbG9jYWxlICAgIExvY2FsZSB0byB1c2UgZm9yIG1lc3NhZ2VzCi0gICAgICovCi0gICAgcHVibGljIFVURjhSZWFkZXIoSW5wdXRTdHJlYW0gaW5wdXRTdHJlYW0sIE1lc3NhZ2VGb3JtYXR0ZXIgbWVzc2FnZUZvcm1hdHRlciwKLSAgICAgICAgICAgIExvY2FsZSBsb2NhbGUpIHsKLSAgICAgICAgdGhpcyhpbnB1dFN0cmVhbSwgREVGQVVMVF9CVUZGRVJfU0laRSwgbWVzc2FnZUZvcm1hdHRlciwgbG9jYWxlKTsKLSAgICB9IC8vIDxpbml0PihJbnB1dFN0cmVhbSwgTWVzc2FnZUZvcm1hdHRlciwgTG9jYWxlKQotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0cyBhIFVURi04IHJlYWRlciBmcm9tIHRoZSBzcGVjaWZpZWQgaW5wdXQgc3RyZWFtLAotICAgICAqIGJ1ZmZlciBzaXplIGFuZCBNZXNzYWdlRm9ybWF0dGVyLgotICAgICAqCi0gICAgICogQHBhcmFtIGlucHV0U3RyZWFtIFRoZSBpbnB1dCBzdHJlYW0uCi0gICAgICogQHBhcmFtIHNpemUgICAgICAgIFRoZSBpbml0aWFsIGJ1ZmZlciBzaXplLgotICAgICAqIEBwYXJhbSBtZXNzYWdlRm9ybWF0dGVyICB0aGUgZm9ybWF0dGVyIGZvciBsb2NhbGl6aW5nL2Zvcm1hdHRpbmcgZXJyb3JzLgotICAgICAqIEBwYXJhbSBsb2NhbGUgICAgdGhlIExvY2FsZSB0byB1c2UgZm9yIG1lc3NhZ2VzCi0gICAgICovCi0gICAgcHVibGljIFVURjhSZWFkZXIoSW5wdXRTdHJlYW0gaW5wdXRTdHJlYW0sIGludCBzaXplLAotICAgICAgICAgICAgTWVzc2FnZUZvcm1hdHRlciBtZXNzYWdlRm9ybWF0dGVyLCBMb2NhbGUgbG9jYWxlKSB7Ci0gICAgICAgIGZJbnB1dFN0cmVhbSA9IGlucHV0U3RyZWFtOwotICAgICAgICBCdWZmZXJBbGxvY2F0b3IgYmEgPSBUaHJlYWRMb2NhbEJ1ZmZlckFsbG9jYXRvci5nZXRCdWZmZXJBbGxvY2F0b3IoKTsKLSAgICAgICAgZkJ1ZmZlciA9IGJhLmdldEJ5dGVCdWZmZXIoc2l6ZSk7Ci0gICAgICAgIGlmIChmQnVmZmVyID09IG51bGwpIHsKLSAgICAgICAgICAgIGZCdWZmZXIgPSBuZXcgYnl0ZVtzaXplXTsKLSAgICAgICAgfQotICAgICAgICBmRm9ybWF0dGVyID0gbWVzc2FnZUZvcm1hdHRlcjsKLSAgICAgICAgZkxvY2FsZSA9IGxvY2FsZTsKLSAgICB9IC8vIDxpbml0PihJbnB1dFN0cmVhbSwgaW50LCBNZXNzYWdlRm9ybWF0dGVyLCBMb2NhbGUpCi0KLSAgICAvLwotICAgIC8vIFJlYWRlciBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFJlYWQgYSBzaW5nbGUgY2hhcmFjdGVyLiAgVGhpcyBtZXRob2Qgd2lsbCBibG9jayB1bnRpbCBhIGNoYXJhY3RlciBpcwotICAgICAqIGF2YWlsYWJsZSwgYW4gSS9PIGVycm9yIG9jY3Vycywgb3IgdGhlIGVuZCBvZiB0aGUgc3RyZWFtIGlzIHJlYWNoZWQuCi0gICAgICoKLSAgICAgKiA8cD4gU3ViY2xhc3NlcyB0aGF0IGludGVuZCB0byBzdXBwb3J0IGVmZmljaWVudCBzaW5nbGUtY2hhcmFjdGVyIGlucHV0Ci0gICAgICogc2hvdWxkIG92ZXJyaWRlIHRoaXMgbWV0aG9kLgotICAgICAqCi0gICAgICogQHJldHVybiAgICAgVGhlIGNoYXJhY3RlciByZWFkLCBhcyBhbiBpbnRlZ2VyIGluIHRoZSByYW5nZSAwIHRvIDE2MzgzCi0gICAgICogICAgICAgICAgICAgKDx0dD4weDAwLTB4ZmZmZjwvdHQ+KSwgb3IgLTEgaWYgdGhlIGVuZCBvZiB0aGUgc3RyZWFtIGhhcwotICAgICAqICAgICAgICAgICAgIGJlZW4gcmVhY2hlZAotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiAgSU9FeGNlcHRpb24gIElmIGFuIEkvTyBlcnJvciBvY2N1cnMKLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IHJlYWQoKSB0aHJvd3MgSU9FeGNlcHRpb24gewotCi0gICAgICAgIC8vIGRlY29kZSBjaGFyYWN0ZXIKLSAgICAgICAgaW50IGMgPSBmU3Vycm9nYXRlOwotICAgICAgICBpZiAoZlN1cnJvZ2F0ZSA9PSAtMSkgewotICAgICAgICAgICAgLy8gTk9URTogV2UgdXNlIHRoZSBpbmRleCBpbnRvIHRoZSBidWZmZXIgaWYgdGhlcmUgYXJlIHJlbWFpbmluZwotICAgICAgICAgICAgLy8gICAgICAgYnl0ZXMgZnJvbSB0aGUgbGFzdCBibG9jayByZWFkLiAtQWMKLSAgICAgICAgICAgIGludCBpbmRleCA9IDA7Ci0KLSAgICAgICAgICAgIC8vIGdldCBmaXJzdCBieXRlCi0gICAgICAgICAgICBpbnQgYjAgPSBpbmRleCA9PSBmT2Zmc2V0Ci0gICAgICAgICAgICAgICAgICAgPyBmSW5wdXRTdHJlYW0ucmVhZCgpIDogZkJ1ZmZlcltpbmRleCsrXSAmIDB4MDBGRjsKLSAgICAgICAgICAgIGlmIChiMCA9PSAtMSkgewotICAgICAgICAgICAgICAgIHJldHVybiAtMTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gVVRGLTg6ICAgWzB4eHggeHh4eF0KLSAgICAgICAgICAgIC8vIFVuaWNvZGU6IFswMDAwIDAwMDBdIFsweHh4IHh4eHhdCi0gICAgICAgICAgICBpZiAoYjAgPCAweDgwKSB7Ci0gICAgICAgICAgICAgICAgYyA9IChjaGFyKWIwOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBVVEYtODogICBbMTEweSB5eXl5XSBbMTB4eCB4eHh4XQotICAgICAgICAgICAgLy8gVW5pY29kZTogWzAwMDAgMHl5eV0gW3l5eHggeHh4eF0KLSAgICAgICAgICAgIGVsc2UgaWYgKChiMCAmIDB4RTApID09IDB4QzAgJiYgKGIwICYgMHgxRSkgIT0gMCkgewotICAgICAgICAgICAgICAgIGludCBiMSA9IGluZGV4ID09IGZPZmZzZXQKLSAgICAgICAgICAgICAgICAgICAgICAgPyBmSW5wdXRTdHJlYW0ucmVhZCgpIDogZkJ1ZmZlcltpbmRleCsrXSAmIDB4MDBGRjsKLSAgICAgICAgICAgICAgICBpZiAoYjEgPT0gLTEpIHsKLSAgICAgICAgICAgICAgICAgICAgZXhwZWN0ZWRCeXRlKDIsIDIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpZiAoKGIxICYgMHhDMCkgIT0gMHg4MCkgewotICAgICAgICAgICAgICAgICAgICBpbnZhbGlkQnl0ZSgyLCAyLCBiMSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGMgPSAoKGIwIDw8IDYpICYgMHgwN0MwKSB8IChiMSAmIDB4MDAzRik7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIFVURi04OiAgIFsxMTEwIHp6enpdIFsxMHl5IHl5eXldIFsxMHh4IHh4eHhdCi0gICAgICAgICAgICAvLyBVbmljb2RlOiBbenp6eiB5eXl5XSBbeXl4eCB4eHh4XQotICAgICAgICAgICAgZWxzZSBpZiAoKGIwICYgMHhGMCkgPT0gMHhFMCkgewotICAgICAgICAgICAgICAgIGludCBiMSA9IGluZGV4ID09IGZPZmZzZXQKLSAgICAgICAgICAgICAgICAgICAgICAgPyBmSW5wdXRTdHJlYW0ucmVhZCgpIDogZkJ1ZmZlcltpbmRleCsrXSAmIDB4MDBGRjsKLSAgICAgICAgICAgICAgICBpZiAoYjEgPT0gLTEpIHsKLSAgICAgICAgICAgICAgICAgICAgZXhwZWN0ZWRCeXRlKDIsIDMpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpZiAoKGIxICYgMHhDMCkgIT0gMHg4MAotICAgICAgICAgICAgICAgICAgICB8fCAoYjAgPT0gMHhFRCAmJiBiMSA+PSAweEEwKQotICAgICAgICAgICAgICAgICAgICB8fCAoKGIwICYgMHgwRikgPT0gMCAmJiAoYjEgJiAweDIwKSA9PSAwKSkgewotICAgICAgICAgICAgICAgICAgICBpbnZhbGlkQnl0ZSgyLCAzLCBiMSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGludCBiMiA9IGluZGV4ID09IGZPZmZzZXQKLSAgICAgICAgICAgICAgICAgICAgICAgPyBmSW5wdXRTdHJlYW0ucmVhZCgpIDogZkJ1ZmZlcltpbmRleCsrXSAmIDB4MDBGRjsKLSAgICAgICAgICAgICAgICBpZiAoYjIgPT0gLTEpIHsKLSAgICAgICAgICAgICAgICAgICAgZXhwZWN0ZWRCeXRlKDMsIDMpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpZiAoKGIyICYgMHhDMCkgIT0gMHg4MCkgewotICAgICAgICAgICAgICAgICAgICBpbnZhbGlkQnl0ZSgzLCAzLCBiMik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGMgPSAoKGIwIDw8IDEyKSAmIDB4RjAwMCkgfCAoKGIxIDw8IDYpICYgMHgwRkMwKSB8Ci0gICAgICAgICAgICAgICAgICAgIChiMiAmIDB4MDAzRik7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIFVURi04OiAgIFsxMTExIDB1dXVdIFsxMHV1IHp6enpdIFsxMHl5IHl5eXldIFsxMHh4IHh4eHhdKgotICAgICAgICAgICAgLy8gVW5pY29kZTogWzExMDEgMTB3d10gW3d3enogenp5eV0gKGhpZ2ggc3Vycm9nYXRlKQotICAgICAgICAgICAgLy8gICAgICAgICAgWzExMDEgMTF5eV0gW3l5eHggeHh4eF0gKGxvdyBzdXJyb2dhdGUpCi0gICAgICAgICAgICAvLyAgICAgICAgICAqIHV1dXV1ID0gd3d3dyArIDEKLSAgICAgICAgICAgIGVsc2UgaWYgKChiMCAmIDB4RjgpID09IDB4RjApIHsKLSAgICAgICAgICAgICAgICBpbnQgYjEgPSBpbmRleCA9PSBmT2Zmc2V0Ci0gICAgICAgICAgICAgICAgICAgICAgID8gZklucHV0U3RyZWFtLnJlYWQoKSA6IGZCdWZmZXJbaW5kZXgrK10gJiAweDAwRkY7Ci0gICAgICAgICAgICAgICAgaWYgKGIxID09IC0xKSB7Ci0gICAgICAgICAgICAgICAgICAgIGV4cGVjdGVkQnl0ZSgyLCA0KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaWYgKChiMSAmIDB4QzApICE9IDB4ODAKLSAgICAgICAgICAgICAgICAgICAgfHwgKChiMSAmIDB4MzApID09IDAgJiYgKGIwICYgMHgwNykgPT0gMCkpIHsKLSAgICAgICAgICAgICAgICAgICAgaW52YWxpZEJ5dGUoMiwgMywgYjEpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpbnQgYjIgPSBpbmRleCA9PSBmT2Zmc2V0Ci0gICAgICAgICAgICAgICAgICAgICAgID8gZklucHV0U3RyZWFtLnJlYWQoKSA6IGZCdWZmZXJbaW5kZXgrK10gJiAweDAwRkY7Ci0gICAgICAgICAgICAgICAgaWYgKGIyID09IC0xKSB7Ci0gICAgICAgICAgICAgICAgICAgIGV4cGVjdGVkQnl0ZSgzLCA0KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaWYgKChiMiAmIDB4QzApICE9IDB4ODApIHsKLSAgICAgICAgICAgICAgICAgICAgaW52YWxpZEJ5dGUoMywgMywgYjIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpbnQgYjMgPSBpbmRleCA9PSBmT2Zmc2V0Ci0gICAgICAgICAgICAgICAgICAgICAgID8gZklucHV0U3RyZWFtLnJlYWQoKSA6IGZCdWZmZXJbaW5kZXgrK10gJiAweDAwRkY7Ci0gICAgICAgICAgICAgICAgaWYgKGIzID09IC0xKSB7Ci0gICAgICAgICAgICAgICAgICAgIGV4cGVjdGVkQnl0ZSg0LCA0KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaWYgKChiMyAmIDB4QzApICE9IDB4ODApIHsKLSAgICAgICAgICAgICAgICAgICAgaW52YWxpZEJ5dGUoNCwgNCwgYjMpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpbnQgdXV1dXUgPSAoKGIwIDw8IDIpICYgMHgwMDFDKSB8ICgoYjEgPj4gNCkgJiAweDAwMDMpOwotICAgICAgICAgICAgICAgIGlmICh1dXV1dSA+IDB4MTApIHsKLSAgICAgICAgICAgICAgICAgICAgaW52YWxpZFN1cnJvZ2F0ZSh1dXV1dSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGludCB3d3d3ID0gdXV1dXUgLSAxOwotICAgICAgICAgICAgICAgIGludCBocyA9IDB4RDgwMCB8Ci0gICAgICAgICAgICAgICAgICAgICAgICAgKCh3d3d3IDw8IDYpICYgMHgwM0MwKSB8ICgoYjEgPDwgMikgJiAweDAwM0MpIHwKLSAgICAgICAgICAgICAgICAgICAgICAgICAoKGIyID4+IDQpICYgMHgwMDAzKTsKLSAgICAgICAgICAgICAgICBpbnQgbHMgPSAweERDMDAgfCAoKGIyIDw8IDYpICYgMHgwM0MwKSB8IChiMyAmIDB4MDAzRik7Ci0gICAgICAgICAgICAgICAgYyA9IGhzOwotICAgICAgICAgICAgICAgIGZTdXJyb2dhdGUgPSBsczsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gZXJyb3IKLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIGludmFsaWRCeXRlKDEsIDEsIGIwKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIHVzZSBzdXJyb2dhdGUKLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBmU3Vycm9nYXRlID0gLTE7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyByZXR1cm4gY2hhcmFjdGVyCi0gICAgICAgIGlmIChERUJVR19SRUFEKSB7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oInJlYWQoKTogMHgiK0ludGVnZXIudG9IZXhTdHJpbmcoYykpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBjOwotCi0gICAgfSAvLyByZWFkKCk6aW50Ci0KLSAgICAvKioKLSAgICAgKiBSZWFkIGNoYXJhY3RlcnMgaW50byBhIHBvcnRpb24gb2YgYW4gYXJyYXkuICBUaGlzIG1ldGhvZCB3aWxsIGJsb2NrCi0gICAgICogdW50aWwgc29tZSBpbnB1dCBpcyBhdmFpbGFibGUsIGFuIEkvTyBlcnJvciBvY2N1cnMsIG9yIHRoZSBlbmQgb2YgdGhlCi0gICAgICogc3RyZWFtIGlzIHJlYWNoZWQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gICAgICBjaCAgICAgRGVzdGluYXRpb24gYnVmZmVyCi0gICAgICogQHBhcmFtICAgICAgb2Zmc2V0IE9mZnNldCBhdCB3aGljaCB0byBzdGFydCBzdG9yaW5nIGNoYXJhY3RlcnMKLSAgICAgKiBAcGFyYW0gICAgICBsZW5ndGggTWF4aW11bSBudW1iZXIgb2YgY2hhcmFjdGVycyB0byByZWFkCi0gICAgICoKLSAgICAgKiBAcmV0dXJuICAgICBUaGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgcmVhZCwgb3IgLTEgaWYgdGhlIGVuZCBvZiB0aGUKLSAgICAgKiAgICAgICAgICAgICBzdHJlYW0gaGFzIGJlZW4gcmVhY2hlZAotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiAgSU9FeGNlcHRpb24gIElmIGFuIEkvTyBlcnJvciBvY2N1cnMKLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IHJlYWQoY2hhciBjaFtdLCBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoKSB0aHJvd3MgSU9FeGNlcHRpb24gewotCi0gICAgICAgIC8vIGhhbmRsZSBzdXJyb2dhdGUKLSAgICAgICAgaW50IG91dCA9IG9mZnNldDsKLSAgICAgICAgaWYgKGZTdXJyb2dhdGUgIT0gLTEpIHsKLSAgICAgICAgICAgIGNoW29mZnNldCArIDFdID0gKGNoYXIpZlN1cnJvZ2F0ZTsKLSAgICAgICAgICAgIGZTdXJyb2dhdGUgPSAtMTsKLSAgICAgICAgICAgIGxlbmd0aC0tOwotICAgICAgICAgICAgb3V0Kys7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyByZWFkIGJ5dGVzCi0gICAgICAgIGludCBjb3VudCA9IDA7Ci0gICAgICAgIGlmIChmT2Zmc2V0ID09IDApIHsKLSAgICAgICAgICAgIC8vIGFkanVzdCBsZW5ndGggdG8gcmVhZAotICAgICAgICAgICAgaWYgKGxlbmd0aCA+IGZCdWZmZXIubGVuZ3RoKSB7Ci0gICAgICAgICAgICAgICAgbGVuZ3RoID0gZkJ1ZmZlci5sZW5ndGg7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIHBlcmZvcm0gcmVhZCBvcGVyYXRpb24KLSAgICAgICAgICAgIGNvdW50ID0gZklucHV0U3RyZWFtLnJlYWQoZkJ1ZmZlciwgMCwgbGVuZ3RoKTsKLSAgICAgICAgICAgIGlmIChjb3VudCA9PSAtMSkgewotICAgICAgICAgICAgICAgIHJldHVybiAtMTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNvdW50ICs9IG91dCAtIG9mZnNldDsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIHNraXAgcmVhZDsgbGFzdCBjaGFyYWN0ZXIgd2FzIGluIGVycm9yCi0gICAgICAgIC8vIE5PVEU6IEhhdmluZyBhbiBvZmZzZXQgdmFsdWUgb3RoZXIgdGhhbiB6ZXJvIG1lYW5zIHRoYXQgdGhlcmUgd2FzCi0gICAgICAgIC8vICAgICAgIGFuIGVycm9yIGluIHRoZSBsYXN0IGNoYXJhY3RlciByZWFkLiBJbiB0aGlzIGNhc2UsIHdlIGhhdmUKLSAgICAgICAgLy8gICAgICAgc2tpcHBlZCB0aGUgcmVhZCBzbyB3ZSBkb24ndCBjb25zdW1lIGFueSBieXRlcyBwYXN0IHRoZQotICAgICAgICAvLyAgICAgICBlcnJvci4gQnkgc2lnbmFsbGluZyB0aGUgZXJyb3Igb24gdGhlIG5leHQgYmxvY2sgcmVhZCB3ZQotICAgICAgICAvLyAgICAgICBhbGxvdyB0aGUgbWV0aG9kIHRvIHJldHVybiB0aGUgbW9zdCB2YWxpZCBjaGFyYWN0ZXJzIHRoYXQKLSAgICAgICAgLy8gICAgICAgaXQgY2FuIG9uIHRoZSBwcmV2aW91cyBibG9jayByZWFkLiAtQWMKLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBjb3VudCA9IGZPZmZzZXQ7Ci0gICAgICAgICAgICBmT2Zmc2V0ID0gMDsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIGNvbnZlcnQgYnl0ZXMgdG8gY2hhcmFjdGVycwotICAgICAgICBmaW5hbCBpbnQgdG90YWwgPSBjb3VudDsKLSAgICAgICAgaW50IGluOwotICAgICAgICBieXRlIGJ5dGUxOwotICAgICAgICBmaW5hbCBieXRlIGJ5dGUwID0gMDsKLSAgICAgICAgZm9yIChpbiA9IDA7IGluIDwgdG90YWw7IGluKyspIHsKLSAgICAgICAgICAgIGJ5dGUxID0gZkJ1ZmZlcltpbl07Ci0gICAgICAgICAgICBpZiAoYnl0ZTEgPj0gYnl0ZTApIHsKLSAgICAgICAgICAgICAgICBjaFtvdXQrK10gPSAoY2hhcilieXRlMTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgICB7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZm9yICggOyBpbiA8IHRvdGFsOyBpbisrKSB7Ci0gICAgICAgICAgICBieXRlMSA9IGZCdWZmZXJbaW5dOwotCi0gICAgICAgICAgICAvLyBVVEYtODogICBbMHh4eCB4eHh4XQotICAgICAgICAgICAgLy8gVW5pY29kZTogWzAwMDAgMDAwMF0gWzB4eHggeHh4eF0KLSAgICAgICAgICAgIGlmIChieXRlMSA+PSBieXRlMCkgewotICAgICAgICAgICAgICAgIGNoW291dCsrXSA9IChjaGFyKWJ5dGUxOwotICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBVVEYtODogICBbMTEweSB5eXl5XSBbMTB4eCB4eHh4XQotICAgICAgICAgICAgLy8gVW5pY29kZTogWzAwMDAgMHl5eV0gW3l5eHggeHh4eF0KLSAgICAgICAgICAgIGludCBiMCA9IGJ5dGUxICYgMHgwRkY7Ci0gICAgICAgICAgICBpZiAoKGIwICYgMHhFMCkgPT0gMHhDMCAmJiAoYjAgJiAweDFFKSAhPSAwKSB7Ci0gICAgICAgICAgICAgICAgaW50IGIxID0gLTE7Ci0gICAgICAgICAgICAgICAgaWYgKCsraW4gPCB0b3RhbCkgewotICAgICAgICAgICAgICAgICAgICBiMSA9IGZCdWZmZXJbaW5dICYgMHgwMEZGOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgYjEgPSBmSW5wdXRTdHJlYW0ucmVhZCgpOwotICAgICAgICAgICAgICAgICAgICBpZiAoYjEgPT0gLTEpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvdXQgPiBvZmZzZXQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmQnVmZmVyWzBdID0gKGJ5dGUpYjA7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZk9mZnNldCA9IDE7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG91dCAtIG9mZnNldDsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGV4cGVjdGVkQnl0ZSgyLCAyKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBjb3VudCsrOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpZiAoKGIxICYgMHhDMCkgIT0gMHg4MCkgewotICAgICAgICAgICAgICAgICAgICBpZiAob3V0ID4gb2Zmc2V0KSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmQnVmZmVyWzBdID0gKGJ5dGUpYjA7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmQnVmZmVyWzFdID0gKGJ5dGUpYjE7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmT2Zmc2V0ID0gMjsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBvdXQgLSBvZmZzZXQ7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgaW52YWxpZEJ5dGUoMiwgMiwgYjEpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpbnQgYyA9ICgoYjAgPDwgNikgJiAweDA3QzApIHwgKGIxICYgMHgwMDNGKTsKLSAgICAgICAgICAgICAgICBjaFtvdXQrK10gPSAoY2hhciljOwotICAgICAgICAgICAgICAgIGNvdW50IC09IDE7Ci0gICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIFVURi04OiAgIFsxMTEwIHp6enpdIFsxMHl5IHl5eXldIFsxMHh4IHh4eHhdCi0gICAgICAgICAgICAvLyBVbmljb2RlOiBbenp6eiB5eXl5XSBbeXl4eCB4eHh4XQotICAgICAgICAgICAgaWYgKChiMCAmIDB4RjApID09IDB4RTApIHsKLSAgICAgICAgICAgICAgICBpbnQgYjEgPSAtMTsKLSAgICAgICAgICAgICAgICBpZiAoKytpbiA8IHRvdGFsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGIxID0gZkJ1ZmZlcltpbl0gJiAweDAwRkY7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICBiMSA9IGZJbnB1dFN0cmVhbS5yZWFkKCk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChiMSA9PSAtMSkgewotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG91dCA+IG9mZnNldCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZCdWZmZXJbMF0gPSAoYnl0ZSliMDsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmT2Zmc2V0ID0gMTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gb3V0IC0gb2Zmc2V0OwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgZXhwZWN0ZWRCeXRlKDIsIDMpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGNvdW50Kys7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGlmICgoYjEgJiAweEMwKSAhPSAweDgwCi0gICAgICAgICAgICAgICAgICAgIHx8IChiMCA9PSAweEVEICYmIGIxID49IDB4QTApCi0gICAgICAgICAgICAgICAgICAgIHx8ICgoYjAgJiAweDBGKSA9PSAwICYmIChiMSAmIDB4MjApID09IDApKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChvdXQgPiBvZmZzZXQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZCdWZmZXJbMF0gPSAoYnl0ZSliMDsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZCdWZmZXJbMV0gPSAoYnl0ZSliMTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZPZmZzZXQgPSAyOwotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG91dCAtIG9mZnNldDsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBpbnZhbGlkQnl0ZSgyLCAzLCBiMSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGludCBiMiA9IC0xOwotICAgICAgICAgICAgICAgIGlmICgrK2luIDwgdG90YWwpIHsKLSAgICAgICAgICAgICAgICAgICAgYjIgPSBmQnVmZmVyW2luXSAmIDB4MDBGRjsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIGIyID0gZklucHV0U3RyZWFtLnJlYWQoKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGIyID09IC0xKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAob3V0ID4gb2Zmc2V0KSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZkJ1ZmZlclswXSA9IChieXRlKWIwOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZCdWZmZXJbMV0gPSAoYnl0ZSliMTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmT2Zmc2V0ID0gMjsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gb3V0IC0gb2Zmc2V0OwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgZXhwZWN0ZWRCeXRlKDMsIDMpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGNvdW50Kys7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGlmICgoYjIgJiAweEMwKSAhPSAweDgwKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChvdXQgPiBvZmZzZXQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZCdWZmZXJbMF0gPSAoYnl0ZSliMDsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZCdWZmZXJbMV0gPSAoYnl0ZSliMTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZCdWZmZXJbMl0gPSAoYnl0ZSliMjsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZPZmZzZXQgPSAzOwotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG91dCAtIG9mZnNldDsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBpbnZhbGlkQnl0ZSgzLCAzLCBiMik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGludCBjID0gKChiMCA8PCAxMikgJiAweEYwMDApIHwgKChiMSA8PCA2KSAmIDB4MEZDMCkgfAotICAgICAgICAgICAgICAgICAgICAgICAgKGIyICYgMHgwMDNGKTsKLSAgICAgICAgICAgICAgICBjaFtvdXQrK10gPSAoY2hhciljOwotICAgICAgICAgICAgICAgIGNvdW50IC09IDI7Ci0gICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIFVURi04OiAgIFsxMTExIDB1dXVdIFsxMHV1IHp6enpdIFsxMHl5IHl5eXldIFsxMHh4IHh4eHhdKgotICAgICAgICAgICAgLy8gVW5pY29kZTogWzExMDEgMTB3d10gW3d3enogenp5eV0gKGhpZ2ggc3Vycm9nYXRlKQotICAgICAgICAgICAgLy8gICAgICAgICAgWzExMDEgMTF5eV0gW3l5eHggeHh4eF0gKGxvdyBzdXJyb2dhdGUpCi0gICAgICAgICAgICAvLyAgICAgICAgICAqIHV1dXV1ID0gd3d3dyArIDEKLSAgICAgICAgICAgIGlmICgoYjAgJiAweEY4KSA9PSAweEYwKSB7Ci0gICAgICAgICAgICAgICAgaW50IGIxID0gLTE7Ci0gICAgICAgICAgICAgICAgaWYgKCsraW4gPCB0b3RhbCkgewotICAgICAgICAgICAgICAgICAgICBiMSA9IGZCdWZmZXJbaW5dICYgMHgwMEZGOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgYjEgPSBmSW5wdXRTdHJlYW0ucmVhZCgpOwotICAgICAgICAgICAgICAgICAgICBpZiAoYjEgPT0gLTEpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvdXQgPiBvZmZzZXQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmQnVmZmVyWzBdID0gKGJ5dGUpYjA7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZk9mZnNldCA9IDE7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG91dCAtIG9mZnNldDsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGV4cGVjdGVkQnl0ZSgyLCA0KTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBjb3VudCsrOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpZiAoKGIxICYgMHhDMCkgIT0gMHg4MAotICAgICAgICAgICAgICAgICAgICB8fCAoKGIxICYgMHgzMCkgPT0gMCAmJiAoYjAgJiAweDA3KSA9PSAwKSkgewotICAgICAgICAgICAgICAgICAgICBpZiAob3V0ID4gb2Zmc2V0KSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmQnVmZmVyWzBdID0gKGJ5dGUpYjA7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmQnVmZmVyWzFdID0gKGJ5dGUpYjE7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmT2Zmc2V0ID0gMjsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBvdXQgLSBvZmZzZXQ7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgaW52YWxpZEJ5dGUoMiwgNCwgYjEpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpbnQgYjIgPSAtMTsKLSAgICAgICAgICAgICAgICBpZiAoKytpbiA8IHRvdGFsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGIyID0gZkJ1ZmZlcltpbl0gJiAweDAwRkY7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICBiMiA9IGZJbnB1dFN0cmVhbS5yZWFkKCk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChiMiA9PSAtMSkgewotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG91dCA+IG9mZnNldCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZCdWZmZXJbMF0gPSAoYnl0ZSliMDsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmQnVmZmVyWzFdID0gKGJ5dGUpYjE7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZk9mZnNldCA9IDI7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG91dCAtIG9mZnNldDsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGV4cGVjdGVkQnl0ZSgzLCA0KTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBjb3VudCsrOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpZiAoKGIyICYgMHhDMCkgIT0gMHg4MCkgewotICAgICAgICAgICAgICAgICAgICBpZiAob3V0ID4gb2Zmc2V0KSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmQnVmZmVyWzBdID0gKGJ5dGUpYjA7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmQnVmZmVyWzFdID0gKGJ5dGUpYjE7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmQnVmZmVyWzJdID0gKGJ5dGUpYjI7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmT2Zmc2V0ID0gMzsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBvdXQgLSBvZmZzZXQ7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgaW52YWxpZEJ5dGUoMywgNCwgYjIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpbnQgYjMgPSAtMTsKLSAgICAgICAgICAgICAgICBpZiAoKytpbiA8IHRvdGFsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGIzID0gZkJ1ZmZlcltpbl0gJiAweDAwRkY7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICBiMyA9IGZJbnB1dFN0cmVhbS5yZWFkKCk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChiMyA9PSAtMSkgewotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG91dCA+IG9mZnNldCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZCdWZmZXJbMF0gPSAoYnl0ZSliMDsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmQnVmZmVyWzFdID0gKGJ5dGUpYjE7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZkJ1ZmZlclsyXSA9IChieXRlKWIyOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZPZmZzZXQgPSAzOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBvdXQgLSBvZmZzZXQ7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBleHBlY3RlZEJ5dGUoNCwgNCk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgY291bnQrKzsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaWYgKChiMyAmIDB4QzApICE9IDB4ODApIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKG91dCA+IG9mZnNldCkgewotICAgICAgICAgICAgICAgICAgICAgICAgZkJ1ZmZlclswXSA9IChieXRlKWIwOwotICAgICAgICAgICAgICAgICAgICAgICAgZkJ1ZmZlclsxXSA9IChieXRlKWIxOwotICAgICAgICAgICAgICAgICAgICAgICAgZkJ1ZmZlclsyXSA9IChieXRlKWIyOwotICAgICAgICAgICAgICAgICAgICAgICAgZkJ1ZmZlclszXSA9IChieXRlKWIzOwotICAgICAgICAgICAgICAgICAgICAgICAgZk9mZnNldCA9IDQ7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gb3V0IC0gb2Zmc2V0OwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGludmFsaWRCeXRlKDQsIDQsIGIyKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyBjaGVjayBpZiBvdXRwdXQgYnVmZmVyIGlzIGxhcmdlIGVub3VnaCB0byBob2xkIDIgc3Vycm9nYXRlIGNoYXJzCi0gICAgICAgICAgICAgICAgaWYgKG91dCArIDEgPj0gY2gubGVuZ3RoKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZCdWZmZXJbMF0gPSAoYnl0ZSliMDsKLSAgICAgICAgICAgICAgICAgICAgZkJ1ZmZlclsxXSA9IChieXRlKWIxOwotICAgICAgICAgICAgICAgICAgICBmQnVmZmVyWzJdID0gKGJ5dGUpYjI7Ci0gICAgICAgICAgICAgICAgICAgIGZCdWZmZXJbM10gPSAoYnl0ZSliMzsKLSAgICAgICAgICAgICAgICAgICAgZk9mZnNldCA9IDQ7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBvdXQgLSBvZmZzZXQ7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgLy8gZGVjb2RlIGJ5dGVzIGludG8gc3Vycm9nYXRlIGNoYXJhY3RlcnMKLSAgICAgICAgICAgICAgICBpbnQgdXV1dXUgPSAoKGIwIDw8IDIpICYgMHgwMDFDKSB8ICgoYjEgPj4gNCkgJiAweDAwMDMpOwotICAgICAgICAgICAgICAgIGlmICh1dXV1dSA+IDB4MTApIHsKLSAgICAgICAgICAgICAgICAgICAgaW52YWxpZFN1cnJvZ2F0ZSh1dXV1dSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGludCB3d3d3ID0gdXV1dXUgLSAxOwotICAgICAgICAgICAgICAgIGludCB6enp6ID0gYjEgJiAweDAwMEY7Ci0gICAgICAgICAgICAgICAgaW50IHl5eXl5eSA9IGIyICYgMHgwMDNGOwotICAgICAgICAgICAgICAgIGludCB4eHh4eHggPSBiMyAmIDB4MDAzRjsKLSAgICAgICAgICAgICAgICBpbnQgaHMgPSAweEQ4MDAgfCAoKHd3d3cgPDwgNikgJiAweDAzQzApIHwgKHp6enogPDwgMikgfCAoeXl5eXl5ID4+IDQpOwotICAgICAgICAgICAgICAgIGludCBscyA9IDB4REMwMCB8ICgoeXl5eXl5IDw8IDYpICYgMHgwM0MwKSB8IHh4eHh4eDsKLQotICAgICAgICAgICAgICAgIC8vIHNldCBjaGFyYWN0ZXJzCi0gICAgICAgICAgICAgICAgY2hbb3V0KytdID0gKGNoYXIpaHM7Ci0gICAgICAgICAgICAgICAgY2hbb3V0KytdID0gKGNoYXIpbHM7Ci0gICAgICAgICAgICAgICAgY291bnQgLT0gMjsKLSAgICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gZXJyb3IKLSAgICAgICAgICAgIGlmIChvdXQgPiBvZmZzZXQpIHsKLSAgICAgICAgICAgICAgICBmQnVmZmVyWzBdID0gKGJ5dGUpYjA7Ci0gICAgICAgICAgICAgICAgZk9mZnNldCA9IDE7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIG91dCAtIG9mZnNldDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGludmFsaWRCeXRlKDEsIDEsIGIwKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIHJldHVybiBudW1iZXIgb2YgY2hhcmFjdGVycyBjb252ZXJ0ZWQKLSAgICAgICAgaWYgKERFQlVHX1JFQUQpIHsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigicmVhZChjaGFyW10sIitvZmZzZXQrJywnK2xlbmd0aCsiKTogY291bnQ9Iitjb3VudCk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGNvdW50OwotCi0gICAgfSAvLyByZWFkKGNoYXJbXSxpbnQsaW50KQotCi0gICAgLyoqCi0gICAgICogU2tpcCBjaGFyYWN0ZXJzLiAgVGhpcyBtZXRob2Qgd2lsbCBibG9jayB1bnRpbCBzb21lIGNoYXJhY3RlcnMgYXJlCi0gICAgICogYXZhaWxhYmxlLCBhbiBJL08gZXJyb3Igb2NjdXJzLCBvciB0aGUgZW5kIG9mIHRoZSBzdHJlYW0gaXMgcmVhY2hlZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSAgbiAgVGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHNraXAKLSAgICAgKgotICAgICAqIEByZXR1cm4gICAgVGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIGFjdHVhbGx5IHNraXBwZWQKLSAgICAgKgotICAgICAqIEBleGNlcHRpb24gIElPRXhjZXB0aW9uICBJZiBhbiBJL08gZXJyb3Igb2NjdXJzCi0gICAgICovCi0gICAgcHVibGljIGxvbmcgc2tpcChsb25nIG4pIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0KLSAgICAgICAgbG9uZyByZW1haW5pbmcgPSBuOwotICAgICAgICBmaW5hbCBjaGFyW10gY2ggPSBuZXcgY2hhcltmQnVmZmVyLmxlbmd0aF07Ci0gICAgICAgIGRvIHsKLSAgICAgICAgICAgIGludCBsZW5ndGggPSBjaC5sZW5ndGggPCByZW1haW5pbmcgPyBjaC5sZW5ndGggOiAoaW50KXJlbWFpbmluZzsKLSAgICAgICAgICAgIGludCBjb3VudCA9IHJlYWQoY2gsIDAsIGxlbmd0aCk7Ci0gICAgICAgICAgICBpZiAoY291bnQgPiAwKSB7Ci0gICAgICAgICAgICAgICAgcmVtYWluaW5nIC09IGNvdW50OwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gd2hpbGUgKHJlbWFpbmluZyA+IDApOwotCi0gICAgICAgIGxvbmcgc2tpcHBlZCA9IG4gLSByZW1haW5pbmc7Ci0gICAgICAgIHJldHVybiBza2lwcGVkOwotCi0gICAgfSAvLyBza2lwKGxvbmcpOmxvbmcKLQotICAgIC8qKgotICAgICAqIFRlbGwgd2hldGhlciB0aGlzIHN0cmVhbSBpcyByZWFkeSB0byBiZSByZWFkLgotICAgICAqCi0gICAgICogQHJldHVybiBUcnVlIGlmIHRoZSBuZXh0IHJlYWQoKSBpcyBndWFyYW50ZWVkIG5vdCB0byBibG9jayBmb3IgaW5wdXQsCi0gICAgICogZmFsc2Ugb3RoZXJ3aXNlLiAgTm90ZSB0aGF0IHJldHVybmluZyBmYWxzZSBkb2VzIG5vdCBndWFyYW50ZWUgdGhhdCB0aGUKLSAgICAgKiBuZXh0IHJlYWQgd2lsbCBibG9jay4KLSAgICAgKgotICAgICAqIEBleGNlcHRpb24gIElPRXhjZXB0aW9uICBJZiBhbiBJL08gZXJyb3Igb2NjdXJzCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gcmVhZHkoKSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfSAvLyByZWFkeSgpCi0KLSAgICAvKioKLSAgICAgKiBUZWxsIHdoZXRoZXIgdGhpcyBzdHJlYW0gc3VwcG9ydHMgdGhlIG1hcmsoKSBvcGVyYXRpb24uCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gbWFya1N1cHBvcnRlZCgpIHsKLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0gLy8gbWFya1N1cHBvcnRlZCgpCi0KLSAgICAvKioKLSAgICAgKiBNYXJrIHRoZSBwcmVzZW50IHBvc2l0aW9uIGluIHRoZSBzdHJlYW0uICBTdWJzZXF1ZW50IGNhbGxzIHRvIHJlc2V0KCkKLSAgICAgKiB3aWxsIGF0dGVtcHQgdG8gcmVwb3NpdGlvbiB0aGUgc3RyZWFtIHRvIHRoaXMgcG9pbnQuICBOb3QgYWxsCi0gICAgICogY2hhcmFjdGVyLWlucHV0IHN0cmVhbXMgc3VwcG9ydCB0aGUgbWFyaygpIG9wZXJhdGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSAgcmVhZEFoZWFkTGltaXQgIExpbWl0IG9uIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyB0aGF0IG1heSBiZQotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIHJlYWQgd2hpbGUgc3RpbGwgcHJlc2VydmluZyB0aGUgbWFyay4gIEFmdGVyCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgcmVhZGluZyB0aGlzIG1hbnkgY2hhcmFjdGVycywgYXR0ZW1wdGluZyB0bwotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIHJlc2V0IHRoZSBzdHJlYW0gbWF5IGZhaWwuCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uICBJT0V4Y2VwdGlvbiAgSWYgdGhlIHN0cmVhbSBkb2VzIG5vdCBzdXBwb3J0IG1hcmsoKSwKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgb3IgaWYgc29tZSBvdGhlciBJL08gZXJyb3Igb2NjdXJzCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgbWFyayhpbnQgcmVhZEFoZWFkTGltaXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbihmRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoZkxvY2FsZSwgIk9wZXJhdGlvbk5vdFN1cHBvcnRlZCIsIG5ldyBPYmplY3RbXXsibWFyaygpIiwgIlVURi04In0pKTsKLSAgICB9IC8vIG1hcmsoaW50KQotCi0gICAgLyoqCi0gICAgICogUmVzZXQgdGhlIHN0cmVhbS4gIElmIHRoZSBzdHJlYW0gaGFzIGJlZW4gbWFya2VkLCB0aGVuIGF0dGVtcHQgdG8KLSAgICAgKiByZXBvc2l0aW9uIGl0IGF0IHRoZSBtYXJrLiAgSWYgdGhlIHN0cmVhbSBoYXMgbm90IGJlZW4gbWFya2VkLCB0aGVuCi0gICAgICogYXR0ZW1wdCB0byByZXNldCBpdCBpbiBzb21lIHdheSBhcHByb3ByaWF0ZSB0byB0aGUgcGFydGljdWxhciBzdHJlYW0sCi0gICAgICogZm9yIGV4YW1wbGUgYnkgcmVwb3NpdGlvbmluZyBpdCB0byBpdHMgc3RhcnRpbmcgcG9pbnQuICBOb3QgYWxsCi0gICAgICogY2hhcmFjdGVyLWlucHV0IHN0cmVhbXMgc3VwcG9ydCB0aGUgcmVzZXQoKSBvcGVyYXRpb24sIGFuZCBzb21lIHN1cHBvcnQKLSAgICAgKiByZXNldCgpIHdpdGhvdXQgc3VwcG9ydGluZyBtYXJrKCkuCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uICBJT0V4Y2VwdGlvbiAgSWYgdGhlIHN0cmVhbSBoYXMgbm90IGJlZW4gbWFya2VkLAotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICBvciBpZiB0aGUgbWFyayBoYXMgYmVlbiBpbnZhbGlkYXRlZCwKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgb3IgaWYgdGhlIHN0cmVhbSBkb2VzIG5vdCBzdXBwb3J0IHJlc2V0KCksCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgIG9yIGlmIHNvbWUgb3RoZXIgSS9PIGVycm9yIG9jY3VycwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHJlc2V0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLSAgICAgICAgZk9mZnNldCA9IDA7Ci0gICAgICAgIGZTdXJyb2dhdGUgPSAtMTsKLSAgICB9IC8vIHJlc2V0KCkKLQotICAgIC8qKgotICAgICAqIENsb3NlIHRoZSBzdHJlYW0uICBPbmNlIGEgc3RyZWFtIGhhcyBiZWVuIGNsb3NlZCwgZnVydGhlciByZWFkKCksCi0gICAgICogcmVhZHkoKSwgbWFyaygpLCBvciByZXNldCgpIGludm9jYXRpb25zIHdpbGwgdGhyb3cgYW4gSU9FeGNlcHRpb24uCi0gICAgICogQ2xvc2luZyBhIHByZXZpb3VzbHktY2xvc2VkIHN0cmVhbSwgaG93ZXZlciwgaGFzIG5vIGVmZmVjdC4KLSAgICAgKgotICAgICAqIEBleGNlcHRpb24gIElPRXhjZXB0aW9uICBJZiBhbiBJL08gZXJyb3Igb2NjdXJzCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgICAgICBCdWZmZXJBbGxvY2F0b3IgYmEgPSBUaHJlYWRMb2NhbEJ1ZmZlckFsbG9jYXRvci5nZXRCdWZmZXJBbGxvY2F0b3IoKTsKLSAgICAgICAgYmEucmV0dXJuQnl0ZUJ1ZmZlcihmQnVmZmVyKTsKLSAgICAgICAgZkJ1ZmZlciA9IG51bGw7Ci0gICAgICAgIGZJbnB1dFN0cmVhbS5jbG9zZSgpOwotICAgIH0gLy8gY2xvc2UoKQotCi0gICAgLy8KLSAgICAvLyBQcml2YXRlIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqIFRocm93cyBhbiBleGNlcHRpb24gZm9yIGV4cGVjdGVkIGJ5dGUuICovCi0gICAgcHJpdmF0ZSB2b2lkIGV4cGVjdGVkQnl0ZShpbnQgcG9zaXRpb24sIGludCBjb3VudCkKLSAgICAgICAgdGhyb3dzIE1hbGZvcm1lZEJ5dGVTZXF1ZW5jZUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZEJ5dGVTZXF1ZW5jZUV4Y2VwdGlvbihmRm9ybWF0dGVyLAotICAgICAgICAgICAgZkxvY2FsZSwKLSAgICAgICAgICAgIFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwKLSAgICAgICAgICAgICJFeHBlY3RlZEJ5dGUiLAotICAgICAgICAgICAgbmV3IE9iamVjdFtdIHtJbnRlZ2VyLnRvU3RyaW5nKHBvc2l0aW9uKSwgSW50ZWdlci50b1N0cmluZyhjb3VudCl9KTsKLQotICAgIH0gLy8gZXhwZWN0ZWRCeXRlKGludCxpbnQpCi0KLSAgICAvKiogVGhyb3dzIGFuIGV4Y2VwdGlvbiBmb3IgaW52YWxpZCBieXRlLiAqLwotICAgIHByaXZhdGUgdm9pZCBpbnZhbGlkQnl0ZShpbnQgcG9zaXRpb24sIGludCBjb3VudCwgaW50IGMpCi0gICAgICAgIHRocm93cyBNYWxmb3JtZWRCeXRlU2VxdWVuY2VFeGNlcHRpb24gewotCi0gICAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRCeXRlU2VxdWVuY2VFeGNlcHRpb24oZkZvcm1hdHRlciwKLSAgICAgICAgICAgIGZMb2NhbGUsCi0gICAgICAgICAgICBYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sCi0gICAgICAgICAgICAiSW52YWxpZEJ5dGUiLAotICAgICAgICAgICAgbmV3IE9iamVjdCBbXSB7SW50ZWdlci50b1N0cmluZyhwb3NpdGlvbiksIEludGVnZXIudG9TdHJpbmcoY291bnQpfSk7Ci0KLSAgICB9IC8vIGludmFsaWRCeXRlKGludCxpbnQsaW50KQotCi0gICAgLyoqIFRocm93cyBhbiBleGNlcHRpb24gZm9yIGludmFsaWQgc3Vycm9nYXRlIGJpdHMuICovCi0gICAgcHJpdmF0ZSB2b2lkIGludmFsaWRTdXJyb2dhdGUoaW50IHV1dXV1KSB0aHJvd3MgTWFsZm9ybWVkQnl0ZVNlcXVlbmNlRXhjZXB0aW9uIHsKLQotICAgICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkQnl0ZVNlcXVlbmNlRXhjZXB0aW9uKGZGb3JtYXR0ZXIsCi0gICAgICAgICAgICBmTG9jYWxlLAotICAgICAgICAgICAgWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLAotICAgICAgICAgICAgIkludmFsaWRIaWdoU3Vycm9nYXRlIiwKLSAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7SW50ZWdlci50b0hleFN0cmluZyh1dXV1dSl9KTsKLQotICAgIH0gLy8gaW52YWxpZFN1cnJvZ2F0ZShpbnQpCi0KLX0gLy8gY2xhc3MgVVRGOFJlYWRlcgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvRE9NTWVzc2FnZXMucHJvcGVydGllcyBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL0RPTU1lc3NhZ2VzLnByb3BlcnRpZXMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDhmOTFlZTkuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvRE9NTWVzc2FnZXMucHJvcGVydGllcworKysgL2Rldi9udWxsCkBAIC0xLDY5ICswLDAgQEAKLSMgVGhpcyBmaWxlIHN0b3JlcyBsb2NhbGl6ZWQgbWVzc2FnZXMgZm9yIHRoZSBYZXJjZXMKLSMgRE9NIGltcGxlbWVudGF0aW9uLgotIwotIyBUaGUgbWVzc2FnZXMgYXJlIGFycmFuZ2VkIGluIGtleSBhbmQgdmFsdWUgdHVwbGVzIGluIGEgTGlzdFJlc291cmNlQnVuZGxlLgotIwotCi1CYWRNZXNzYWdlS2V5ID0gVGhlIGVycm9yIG1lc3NhZ2UgY29ycmVzcG9uZGluZyB0byB0aGUgbWVzc2FnZSBrZXkgY2FuIG5vdCBiZSBmb3VuZC4KLUZvcm1hdEZhaWxlZCA9IEFuIGludGVybmFsIGVycm9yIG9jY3VycmVkIHdoaWxlIGZvcm1hdHRpbmcgdGhlIGZvbGxvd2luZyBtZXNzYWdlOlxuICAKLQotIyBET00gQ29yZQotCi0jIGV4Y2VwdGlvbiBjb2RlcwotRE9NU1RSSU5HX1NJWkVfRVJSID0gVGhlIHNwZWNpZmllZCByYW5nZSBvZiB0ZXh0IGRvZXMgbm90IGZpdCBpbnRvIGEgRE9NU3RyaW5nLiAKLUhJRVJBUkNIWV9SRVFVRVNUX0VSUiAgPSBBbiBhdHRlbXB0IHdhcyBtYWRlIHRvIGluc2VydCBhIG5vZGUgd2hlcmUgaXQgaXMgbm90IHBlcm1pdHRlZC4gCi1JTkRFWF9TSVpFX0VSUiA9IFRoZSBpbmRleCBvciBzaXplIGlzIG5lZ2F0aXZlLCBvciBncmVhdGVyIHRoYW4gdGhlIGFsbG93ZWQgdmFsdWUuCi1JTlVTRV9BVFRSSUJVVEVfRVJSID0gQW4gYXR0ZW1wdCBpcyBtYWRlIHRvIGFkZCBhbiBhdHRyaWJ1dGUgdGhhdCBpcyBhbHJlYWR5IGluIHVzZSBlbHNld2hlcmUuCi1JTlZBTElEX0FDQ0VTU19FUlIgID0gQSBwYXJhbWV0ZXIgb3IgYW4gb3BlcmF0aW9uIGlzIG5vdCBzdXBwb3J0ZWQgYnkgdGhlIHVuZGVybHlpbmcgb2JqZWN0LiAKLUlOVkFMSURfQ0hBUkFDVEVSX0VSUiA9IEFuIGludmFsaWQgb3IgaWxsZWdhbCBYTUwgY2hhcmFjdGVyIGlzIHNwZWNpZmllZC4gCi1JTlZBTElEX01PRElGSUNBVElPTl9FUlIgPSAgQW4gYXR0ZW1wdCBpcyBtYWRlIHRvIG1vZGlmeSB0aGUgdHlwZSBvZiB0aGUgdW5kZXJseWluZyBvYmplY3QuIAotSU5WQUxJRF9TVEFURV9FUlIgPSBBbiBhdHRlbXB0IGlzIG1hZGUgdG8gdXNlIGFuIG9iamVjdCB0aGF0IGlzIG5vdCwgb3IgaXMgbm8gbG9uZ2VyLCB1c2FibGUuIAotTkFNRVNQQUNFX0VSUiA9IEFuIGF0dGVtcHQgaXMgbWFkZSB0byBjcmVhdGUgb3IgY2hhbmdlIGFuIG9iamVjdCBpbiBhIHdheSB3aGljaCBpcyBpbmNvcnJlY3Qgd2l0aCByZWdhcmQgdG8gbmFtZXNwYWNlcy4KLU5PVF9GT1VORF9FUlIgPSBBbiBhdHRlbXB0IGlzIG1hZGUgdG8gcmVmZXJlbmNlIGEgbm9kZSBpbiBhIGNvbnRleHQgd2hlcmUgaXQgZG9lcyBub3QgZXhpc3QuCi1OT1RfU1VQUE9SVEVEX0VSUiA9IFRoZSBpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdCBzdXBwb3J0IHRoZSByZXF1ZXN0ZWQgdHlwZSBvZiBvYmplY3Qgb3Igb3BlcmF0aW9uLiAKLU5PX0RBVEFfQUxMT1dFRF9FUlIgPSBEYXRhIGlzIHNwZWNpZmllZCBmb3IgYSBub2RlIHdoaWNoIGRvZXMgbm90IHN1cHBvcnQgZGF0YS4KLU5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiA9IEFuIGF0dGVtcHQgaXMgbWFkZSB0byBtb2RpZnkgYW4gb2JqZWN0IHdoZXJlIG1vZGlmaWNhdGlvbnMgYXJlIG5vdCBhbGxvd2VkLgotU1lOVEFYX0VSUiA9IEFuIGludmFsaWQgb3IgaWxsZWdhbCBzdHJpbmcgaXMgc3BlY2lmaWVkLiAKLVZBTElEQVRJT05fRVJSID0gQSBjYWxsIHRvIGEgbWV0aG9kIHN1Y2ggYXMgaW5zZXJ0QmVmb3JlIG9yIHJlbW92ZUNoaWxkIHdvdWxkIG1ha2UgdGhlIE5vZGUgaW52YWxpZCB3aXRoIHJlc3BlY3QgdG8gZG9jdW1lbnQgZ3JhbW1hci4KLVdST05HX0RPQ1VNRU5UX0VSUiA9IEEgbm9kZSBpcyB1c2VkIGluIGEgZGlmZmVyZW50IGRvY3VtZW50IHRoYW4gdGhlIG9uZSB0aGF0IGNyZWF0ZWQgaXQuCi1UWVBFX01JU01BVENIX0VSUiA9IFRoZSB2YWx1ZSB0eXBlIGZvciB0aGlzIHBhcmFtZXRlciBuYW1lIGlzIGluY29tcGF0aWJsZSB3aXRoIHRoZSBleHBlY3RlZCB2YWx1ZSB0eXBlLiAKLSAKLSNlcnJvciBtZXNzYWdlcyBvciBleGNlcHRpb25zCi1GRUFUVVJFX05PVF9TVVBQT1JURUQgPSBUaGUgcGFyYW1ldGVyIHswfSBpcyByZWNvZ25pemVkIGJ1dCB0aGUgcmVxdWVzdGVkIHZhbHVlIGNhbm5vdCBiZSBzZXQuCi1GRUFUVVJFX05PVF9GT1VORCA9IFRoZSBwYXJhbWV0ZXIgezB9IGlzIG5vdCByZWNvZ25pemVkLgotU1RSSU5HX1RPT19MT05HICAgPSBUaGUgcmVzdWx0aW5nIHN0cmluZyBpcyB0b28gbG9uZyB0byBmaXQgaW4gYSBET01TdHJpbmc6ICcnezB9JycuCi0KLSNET00gTGV2ZWwgMyBET01FcnJvciBjb2Rlcwotd2YtaW52YWxpZC1jaGFyYWN0ZXIgPSAgVGhlIHRleHQgezB9IG9mIHRoZSB7MX0gbm9kZSBjb250YWlucyBpbnZhbGlkIFhNTCBjaGFyYWN0ZXJzLgotd2YtaW52YWxpZC1jaGFyYWN0ZXItaW4tbm9kZS1uYW1lID0gVGhlIHswfSBub2RlIG5hbWVkIHsxfSBjb250YWlucyBpbnZhbGlkIFhNTCBjaGFyYWN0ZXJzLgotY2RhdGEtc2VjdGlvbnMtc3BsaXR0ZWQgPSAgQ0RBVEEgc2VjdGlvbnMgY29udGFpbmluZyB0aGUgQ0RBVEEgc2VjdGlvbiB0ZXJtaW5hdGlvbiBtYXJrZXIgJyddXT4nJwotZG9jdHlwZS1ub3QtYWxsb3dlZCA9IERPQ1RZUEUgZGVjbGFyYXRpb24gaXMgbm90IGFsbG93ZWQuCi11bnN1cHBvcnRlZC1lbmNvZGluZyA9IFRoZSBlbmNvZGluZyB7MH0gaXMgbm90IHN1cHBvcnRlZC4KLQotI0Vycm9yIGNvZGVzIHVzZWQgaW4gRE9NIE5vcm1hbGl6ZXIKLUludmFsaWRYTUxDaGFySW5ET00gPSBBbiBpbnZhbGlkIFhNTCBjaGFyYWN0ZXIgKFVuaWNvZGU6IDB4ezB9KSB3YXMgZm91bmQgaW4gdGhlIERPTSBkdXJpbmcgbm9ybWFsaXphdGlvbi4KLVVuZGVjbGFyZWRFbnRSZWZJbkF0dHJWYWx1ZSA9IFRoZSBhdHRyaWJ1dGUgXCJ7MH1cIiB2YWx1ZSBcInsxfVwiIHJlZmVyZW5jZWQgYW4gZW50aXR5IHRoYXQgd2FzIG5vdCBkZWNsYXJlZC4KLU51bGxMb2NhbEVsZW1lbnROYW1lID0gQSBudWxsIGxvY2FsIG5hbWUgd2FzIGVuY291bnRlcmVkIGR1cmluZyBuYW1lc3BhY2Ugbm9ybWFsaXphdGlvbiBvZiBlbGVtZW50IHswfS4KLU51bGxMb2NhbEF0dHJOYW1lID0gQSBudWxsIGxvY2FsIG5hbWUgd2FzIGVuY291bnRlcmVkIGR1cmluZyBuYW1lc3BhY2Ugbm9ybWFsaXphdGlvbiBvZiBhdHRyaWJ1dGUgezB9LgotCi0jRXJyb3IgY29kZXMgdXNlZCBpbiBET01QYXJzZXIKLUludmFsaWREb2N1bWVudENsYXNzTmFtZSA9IFRoZSBjbGFzcyBuYW1lIG9mIHRoZSBkb2N1bWVudCBmYWN0b3J5IFwiezB9XCIgdXNlZCB0byBjb25zdHJ1Y3QgdGhlIERPTSB0cmVlIGlzIG5vdCBvZiB0eXBlIG9yZy53M2MuZG9tLkRvY3VtZW50LgotTWlzc2luZ0RvY3VtZW50Q2xhc3NOYW1lID0gVGhlIGNsYXNzIG5hbWUgb2YgdGhlIGRvY3VtZW50IGZhY3RvcnkgXCJ7MH1cIiB1c2VkIHRvIGNvbnN0cnVjdCB0aGUgRE9NIHRyZWUgY291bGQgbm90IGJlIGZvdW5kLgotQ2Fubm90Q3JlYXRlRG9jdW1lbnRDbGFzcyA9IFRoZSBjbGFzcyBuYW1lZCBcInswfVwiIGNvdWxkIG5vdCBiZSBjb25zdHJ1Y3RlZCBhcyBhIG9yZy53M2MuZG9tLkRvY3VtZW50LgotCi0jIEVycm9yIGNvZGVzIHVzZWQgYnkgSkFYUCBEb2N1bWVudEJ1aWxkZXIKLWpheHAtb3JkZXItbm90LXN1cHBvcnRlZCA9IFByb3BlcnR5ICcnezB9JycgbXVzdCBiZSBzZXQgYmVmb3JlIHNldHRpbmcgcHJvcGVydHkgJyd7MX0nJy4KLWpheHAtbnVsbC1pbnB1dC1zb3VyY2UgPSBUaGUgc291cmNlIHNwZWNpZmllZCBjYW5ub3QgYmUgbnVsbC4KLQotI1JhbmdlcwotQkFEX0JPVU5EQVJZUE9JTlRTX0VSUiA9IFRoZSBib3VuZGFyeS1wb2ludHMgb2YgYSBSYW5nZSBkbyBub3QgbWVldCBzcGVjaWZpYyByZXF1aXJlbWVudHMuCi1JTlZBTElEX05PREVfVFlQRV9FUlIgPSBUaGUgY29udGFpbmVyIG9mIGEgYm91bmRhcnktcG9pbnQgb2YgYSBSYW5nZSBpcyBiZWluZyBzZXQgdG8gZWl0aGVyIGEgbm9kZSBvZiBhbiBpbnZhbGlkIHR5cGUgb3IgYSBub2RlIHdpdGggYW4gYW5jZXN0b3Igb2YgYW4gaW52YWxpZCB0eXBlLgotCi0KLSNFdmVudHMKLVVOU1BFQ0lGSUVEX0VWRU5UX1RZUEVfRVJSID0gVGhlIEV2ZW50J3MgdHlwZSB3YXMgbm90IHNwZWNpZmllZCBieSBpbml0aWFsaXppbmcgdGhlIGV2ZW50IGJlZm9yZSB0aGUgbWV0aG9kIHdhcyBjYWxsZWQuIAotCi0KLWpheHAtc2NoZW1hLXN1cHBvcnQ9Qm90aCB0aGUgc2V0U2NoZW1hIG1ldGhvZCBhbmQgdGhlIHNjaGVtYUxhbmd1YWdlIHByb3BlcnR5IGlzIHVzZWQKLQotamF4cF9mZWF0dXJlX25vdF9zdXBwb3J0ZWQ9RmVhdHVyZSAiezB9IiBpcyBub3Qgc3VwcG9ydGVkLgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvRE9NTWVzc2FnZXNfZGUucHJvcGVydGllcyBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL0RPTU1lc3NhZ2VzX2RlLnByb3BlcnRpZXMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDgxMjU1MzcuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvRE9NTWVzc2FnZXNfZGUucHJvcGVydGllcworKysgL2Rldi9udWxsCkBAIC0xLDY5ICswLDAgQEAKLSMgVGhpcyBmaWxlIHN0b3JlcyBsb2NhbGl6ZWQgbWVzc2FnZXMgZm9yIHRoZSBYZXJjZXMKLSMgRE9NIGltcGxlbWVudGF0aW9uLgotIwotIyBUaGUgbWVzc2FnZXMgYXJlIGFycmFuZ2VkIGluIGtleSBhbmQgdmFsdWUgdHVwbGVzIGluIGEgTGlzdFJlc291cmNlQnVuZGxlLgotIwotCi1CYWRNZXNzYWdlS2V5ID0gRGllIHp1bSBNZWxkdW5nc3NjaGxcdTAwRkNzc2VsIGdlaFx1MDBGNnJpZ2UgRmVobGVybWVsZHVuZyBrYW5uIG5pY2h0IGdlZnVuZGVuIHdlcmRlbi4KLUZvcm1hdEZhaWxlZCA9IEJlaW0gRm9ybWF0aWVyZW4gZGVyIGZvbGdlbmRlbiBNZWxkdW5nIGlzdCBlaW4gaW50ZXJuZXIgRmVobGVyIGF1ZmdldHJldGVuOlxuICAKLQotIyBET00gQ29yZQotCi0jIGV4Y2VwdGlvbiBjb2RlcwotRE9NU1RSSU5HX1NJWkVfRVJSID0gRGVyIGFuZ2VnZWJlbmUgVGV4dGJlcmVpY2ggcGFzc3QgbmljaHQgaW4gZWluZSBET01TdHJpbmcuIAotSElFUkFSQ0hZX1JFUVVFU1RfRVJSICA9IEVzIHd1cmRlIHZlcnN1Y2h0LCBlaW5lbiBLbm90ZW4gYW4gZWluZXIgU3RlbGxlIGVpbnp1Zlx1MDBGQ2dlbiwgYW4gZGVyIGRpZXMgbmljaHQgenVsXHUwMEU0c3NpZyBpc3QuIAotSU5ERVhfU0laRV9FUlIgPSBJbmRleCBvZGVyIEdyXHUwMEY2XHUwMERGZSBpc3QgbmVnYXRpdiBvZGVyIGdyXHUwMEY2XHUwMERGZXIgYWxzIGRlciB6dWxcdTAwRTRzc2lnZSBXZXJ0LgotSU5VU0VfQVRUUklCVVRFX0VSUiA9IEVzIHd1cmRlIHZlcnN1Y2h0LCBlaW4gQXR0cmlidXQgaGluenV6dWZcdTAwRkNnZW4sIGRhcyBiZXJlaXRzIGFuIGVpbmVyIGFuZGVyZW4gU3RlbGxlIHZlcndlbmRldCB3aXJkLgotSU5WQUxJRF9BQ0NFU1NfRVJSICA9IEVpbiBQYXJhbWV0ZXIgb2RlciBWb3JnYW5nIHdpcmQgbmljaHQgdm9tIHp1Z3J1bmRlIGxpZWdlbmRlbiBPYmpla3QgdW50ZXJzdFx1MDBGQ3R6dC4gCi1JTlZBTElEX0NIQVJBQ1RFUl9FUlIgPSBVbmdcdTAwRkNsdGlnZXMgWE1MLVplaWNoZW4gYW5nZWdlYmVuLiAKLUlOVkFMSURfTU9ESUZJQ0FUSU9OX0VSUiA9ICBFcyB3dXJkZSB2ZXJzdWNodCwgZGVuIFR5cCBkZXMgenVncnVuZGUgbGllZ2VuZGVuIE9iamVrdHMgenUgXHUwMEU0bmRlcm4uIAotSU5WQUxJRF9TVEFURV9FUlIgPSBFcyB3dXJkZSB2ZXJzdWNodCwgZWluIE9iamVrdCB6dSBcdTAwRTRuZGVybiwgZGFzIG5pY2h0IHZlcndlbmRldCB3ZXJkZW4ga2Fubi4gCi1OQU1FU1BBQ0VfRVJSID0gRXMgd3VyZGUgdmVyc3VjaHQsIGVpbiBPYmpla3QgYXVmIGVpbmUgV2Vpc2UgenUgZXJzdGVsbGVuIG9kZXIgenUgXHUwMEU0bmRlcm4sIGRpZSBmYWxzY2ggaW4gQmV6dWcgYXVmIE5hbWVzcGFjZXMgaXN0LgotTk9UX0ZPVU5EX0VSUiA9IEVzIHd1cmRlIHZlcnN1Y2h0LCBlaW5lbiBLbm90ZW4gaW4gZWluZW0gS29udGV4dCB6dSByZWZlcmVuemllcmVuLCBpbiBkZW0gZXIgbmljaHQgdm9yaGFuZGVuIGlzdC4KLU5PVF9TVVBQT1JURURfRVJSID0gRGVyIGFuZ2Vmb3JkZXJ0ZSBUeXAgZGVzIE9iamVrdHMgb2RlciBWb3JnYW5ncyB3aXJkIG5pY2h0IHZvbiBkZXIgSW1wbGVtZW50aWVydW5nIHVudGVyc3RcdTAwRkN0enQuIAotTk9fREFUQV9BTExPV0VEX0VSUiA9IERhdGVuIHd1cmRlbiBmXHUwMEZDciBlaW5lbiBLbm90ZW4gYW5nZWdlYmVuLCBkZXIga2VpbmUgRGF0ZW4gdW50ZXJzdFx1MDBGQ3R6dC4KLU5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiA9IEVzIHd1cmRlIHZlcnN1Y2h0LCBlaW4gT2JqZWt0IHp1IFx1MDBFNG5kZXJuLCBiZWkgZGVtIFx1MDBDNG5kZXJ1bmdlbiBuaWNodCB6dWxcdTAwRTRzc2lnIHNpbmQuCi1TWU5UQVhfRVJSID0gVW5nXHUwMEZDbHRpZ2UgWmVpY2hlbmZvbGdlIGFuZ2VnZWJlbi4gCi1WQUxJREFUSU9OX0VSUiA9IEF1ZnJ1ZiBlaW5lciBNZXRob2RlIHdpZSBpbnNlcnRCZWZvcmUgb2RlciByZW1vdmVDaGlsZCB3XHUwMEZDcmRlIGRpZSBEb2t1bWVudGdyYW1tYXRpayBkZXMgS25vdGVucyB1bmdcdTAwRkNsdGlnIG1hY2hlbi4KLVdST05HX0RPQ1VNRU5UX0VSUiA9IEVpbiBLbm90ZW4gd2lyZCBpbiBlaW5lbSBhbmRlcmVuIERva3VtZW50IHZlcndlbmRldCBhbHMgZGVtLCB2b24gZGVtIGVyIGVyc3RlbGx0IHd1cmRlLgotVFlQRV9NSVNNQVRDSF9FUlIgPSBEZXIgV2VydHR5cCBmXHUwMEZDciBkaWVzZW4gUGFyYW1ldGVybmFtZW4gaXN0IG5pY2h0IG1pdCBkZW0gZXJ3YXJ0ZXRlbiBXZXJ0dHlwIGtvbXBhdGliZWwuIAotIAotI2Vycm9yIG1lc3NhZ2VzIG9yIGV4Y2VwdGlvbnMKLUZFQVRVUkVfTk9UX1NVUFBPUlRFRCA9IFBhcmFtZXRlciB7MH0gd2lyZCBlcmthbm50LCBhYmVyIGRlciBhbmdlZm9yZGVydGUgV2VydCBrYW5uIG5pY2h0IGZlc3RnZWxlZ3Qgd2VyZGVuLgotRkVBVFVSRV9OT1RfRk9VTkQgPSBQYXJhbWV0ZXIgezB9IGlzdCB1bmJla2FubnQuCi1TVFJJTkdfVE9PX0xPTkcgICA9IERpZSByZXN1bHRpZXJlbmRlIFplaWNoZW5mb2xnZSBpc3QgenUgbGFuZywgdW0gaW4gZWluZSBET01TdHJpbmcgenVwYXNzZW46ICJ7MH0iLgotCi0jRE9NIExldmVsIDMgRE9NRXJyb3IgY29kZXMKLXdmLWludmFsaWQtY2hhcmFjdGVyID0gIFRleHQgezB9IGRlcyB7MX0tS25vdGVucyBlbnRoXHUwMEU0bHQgdW5nXHUwMEZDbHRpZ2UgWE1MLVplaWNoZW4uCi13Zi1pbnZhbGlkLWNoYXJhY3Rlci1pbi1ub2RlLW5hbWUgPSB7MH0tS25vdGVuIG1pdCBkZW0gTmFtZW4gezF9IGVudGhcdTAwRTRsdCB1bmdcdTAwRkNsdGlnZSBYTUwtWmVpY2hlbi4KLWNkYXRhLXNlY3Rpb25zLXNwbGl0dGVkID0gIENEQVRBLUFic2Nobml0dCBtaXQgZGVtIENEQVRBLUFic2Nobml0dHNhYnNjaGx1c3N6ZWljaGVuICJdXT4iCi1kb2N0eXBlLW5vdC1hbGxvd2VkID0gRE9DVFlQRS1EZWtsYXJhdGlvbiBpc3QgbmljaHQgenVsXHUwMEU0c3NpZy4KLXVuc3VwcG9ydGVkLWVuY29kaW5nID0gQ29kaWVydW5nIHswfSB3aXJkIG5pY2h0IHVudGVyc3RcdTAwRkN0enQuCi0KLSNFcnJvciBjb2RlcyB1c2VkIGluIERPTSBOb3JtYWxpemVyCi1JbnZhbGlkWE1MQ2hhckluRE9NID0gVW5nXHUwMEZDbHRpZ2VzIFhNTC1aZWljaGVuIChVbmljb2RlOiAweHswfSkgd3VyZGUgYmVpIGRlciBOb3JtYWxpc2llcnVuZyBpbSBET00gZ2VmdW5kZW4uCi1VbmRlY2xhcmVkRW50UmVmSW5BdHRyVmFsdWUgPSBBdHRyaWJ1dCAiezB9IiBXZXJ0ICJ7MX0iIHJlZmVyZW56aWVydGUgZWluZSBuaWNodCBkZWtsYXJpZXJ0ZSBFbnRpdHkuCi1OdWxsTG9jYWxFbGVtZW50TmFtZSA9IExva2FsZXIgTnVsbG5hbWUgd3VyZGUgYmVpIGRlciBOYW1lc3BhY2UtTm9ybWFsaXNpZXJ1bmcgdm9uIEVsZW1lbnQgezB9IGdlZnVuZGVuLgotTnVsbExvY2FsQXR0ck5hbWUgPSBMb2thbGVyIE51bGxuYW1lIHd1cmRlIGJlaSBkZXIgTmFtZXNwYWNlLU5vcm1hbGlzaWVydW5nIHZvbiBBdHRyaWJ1dCB7MH0gZ2VmdW5kZW4uCi0KLSNFcnJvciBjb2RlcyB1c2VkIGluIERPTVBhcnNlcgotSW52YWxpZERvY3VtZW50Q2xhc3NOYW1lID0gRGVyIEtsYXNzZW5uYW1lIGRlciBEb2t1bWVudC1GYWN0b3J5ICJ7MH0iLCBtaXQgZGVtIGRlciBET00tQmF1bSBlcnN0ZWxsdCB3dXJkZSwgaGF0IG5pY2h0IGRlbiBUeXAgb3JnLnczYy5kb20uRG9jdW1lbnQuCi1NaXNzaW5nRG9jdW1lbnRDbGFzc05hbWUgPSBEZXIgS2xhc3Nlbm5hbWUgZGVyIERva3VtZW50LUZhY3RvcnkgInswfSIsIG1pdCBkZW0gZGVyIERPTS1CYXVtIGVyc3RlbGx0IHd1cmRlLCBrb25udGUgbmljaHQgZ2VmdW5kZW4gd2VyZGVuLgotQ2Fubm90Q3JlYXRlRG9jdW1lbnRDbGFzcyA9IERpZSBLbGFzc2UgbWl0IGRlbSBOYW1lbiAiezB9IiBrb25udGUgbmljaHQgYWxzIG9yZy53M2MuZG9tLkRvY3VtZW50IGVyc3RlbGx0IHdlcmRlbi4KLQotIyBFcnJvciBjb2RlcyB1c2VkIGJ5IEpBWFAgRG9jdW1lbnRCdWlsZGVyCi1qYXhwLW9yZGVyLW5vdC1zdXBwb3J0ZWQgPSBFaWdlbnNjaGFmdCAiezB9IiBtdXNzIHZvciBkZXIgRWlnZW5zY2hhZnQgInsxfSIgZmVzdGdlbGVndCB3ZXJkZW4uCi1qYXhwLW51bGwtaW5wdXQtc291cmNlID0gQW5nZWdlYmVuZSBRdWVsbGUgZGFyZiBuaWNodCBudWxsIHNlaW4uCi0KLSNSYW5nZXMKLUJBRF9CT1VOREFSWVBPSU5UU19FUlIgPSBHcmVuendlcnRlIGVpbmVzIEJlcmVpY2hzIGVudHNwcmVjaGVuIG5pY2h0IGRlbiBzcGV6aWVsbGVuIEFuZm9yZGVydW5nZW4uCi1JTlZBTElEX05PREVfVFlQRV9FUlIgPSBDb250YWluZXIgZWluZXMgR3Jlbnp3ZXJ0ZXMgZWluZXMgQmVyZWljaHMgd2lyZCBlbnR3ZWRlciBhdWYgZWluZW4gS25vdGVuIG1pdCBlaW5lbSB1bmdcdTAwRkNsdGlnZW4gVHlwIG9kZXIgYXVmIGVpbmVuIEtub3RlbiBtaXQgZWluZW0gVm9yZ1x1MDBFNG5nZSBlaW5lcyB1bmdcdTAwRkNsdGlnZW4gVHlwcyBnZXNldHp0LgotCi0KLSNFdmVudHMKLVVOU1BFQ0lGSUVEX0VWRU5UX1RZUEVfRVJSID0gRGVyIEVyZWlnbmlzdHlwIHd1cmRlIG5pY2h0IGR1cmNoIEluaXRpYWxpc2llcmVuIGRlcyBFcmVpZ25pc3NlcyB2b3IgZGVtIEF1ZnJ1ZiBkZXIgTWV0aG9kZSBhbmdlZ2ViZW4uIAotCi0KLWpheHAtc2NoZW1hLXN1cHBvcnQ9c2V0U2NoZW1hLU1ldGhvZGUgdW5kIHNjaGVtYUxhbmd1YWdlLUVpZ2Vuc2NoYWZ0IHdlcmRlbiB2ZXJ3ZW5kZXQKLQotamF4cF9mZWF0dXJlX25vdF9zdXBwb3J0ZWQ9RmVhdHVyZSAiezB9IiB3aXJkIG5pY2h0IHVudGVyc3RcdTAwRkN0enQuCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9ET01NZXNzYWdlc19lcy5wcm9wZXJ0aWVzIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvRE9NTWVzc2FnZXNfZXMucHJvcGVydGllcwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDk0MDIxZS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9ET01NZXNzYWdlc19lcy5wcm9wZXJ0aWVzCisrKyAvZGV2L251bGwKQEAgLTEsNjkgKzAsMCBAQAotIyBUaGlzIGZpbGUgc3RvcmVzIGxvY2FsaXplZCBtZXNzYWdlcyBmb3IgdGhlIFhlcmNlcwotIyBET00gaW1wbGVtZW50YXRpb24uCi0jCi0jIFRoZSBtZXNzYWdlcyBhcmUgYXJyYW5nZWQgaW4ga2V5IGFuZCB2YWx1ZSB0dXBsZXMgaW4gYSBMaXN0UmVzb3VyY2VCdW5kbGUuCi0jCi0KLUJhZE1lc3NhZ2VLZXkgPSBObyBzZSBoYSBlbmNvbnRyYWRvIGVsIG1lbnNhamUgZGUgZXJyb3IgY29ycmVzcG9uZGllbnRlIGEgbGEgY2xhdmUgZGUgbWVuc2FqZS4KLUZvcm1hdEZhaWxlZCA9IFNlIGhhIHByb2R1Y2lkbyB1biBlcnJvciBpbnRlcm5vIGFsIGZvcm1hdGVhciBlbCBzaWd1aWVudGUgbWVuc2FqZTpcbiAgCi0KLSMgRE9NIENvcmUKLQotIyBleGNlcHRpb24gY29kZXMKLURPTVNUUklOR19TSVpFX0VSUiA9IEVsIHJhbmdvIGVzcGVjaWZpY2FkbyBkZSB0ZXh0byBubyBjYWJlIGVuIHVuYSBjYWRlbmEgRE9NLiAKLUhJRVJBUkNIWV9SRVFVRVNUX0VSUiAgPSBTZSBoYSByZWFsaXphZG8gdW4gaW50ZW50byBkZSBpbnNlcnRhciB1biBub2RvIGRvbmRlIG5vIGVzdFx1MDBFMSBwZXJtaXRpZG8uIAotSU5ERVhfU0laRV9FUlIgPSBFbCBcdTAwRURuZGljZSBvIHRhbWFcdTAwRjFvIGVzIG5lZ2F0aXZvIG8gc3VwZXJpb3IgYWwgdmFsb3IgcGVybWl0aWRvLgotSU5VU0VfQVRUUklCVVRFX0VSUiA9IFNlIGhhIHJlYWxpemFkbyB1biBpbnRlbnRvIGRlIGFncmVnYXIgdW4gYXRyaWJ1dG8gcXVlIHlhIHNlIGVzdFx1MDBFMSB1dGlsaXphbmRvIGVuIG90cm8gbHVnYXIuCi1JTlZBTElEX0FDQ0VTU19FUlIgID0gRWwgb2JqZXRvIHN1YnlhY2VudGUgbm8gc29wb3J0YSB1biBwYXJcdTAwRTFtZXRybyBvIHVuYSBvcGVyYWNpXHUwMEYzbi4gCi1JTlZBTElEX0NIQVJBQ1RFUl9FUlIgPSBTZSBoYSBlc3BlY2lmaWNhZG8gdW4gY2FyXHUwMEUxY3RlciBYTUwgbm8gdlx1MDBFMWxpZG8gbyBubyBwZXJtaXRpZG8uIAotSU5WQUxJRF9NT0RJRklDQVRJT05fRVJSID0gIFNlIGhhIHJlYWxpemFkbyB1biBpbnRlbnRvIGRlIG1vZGlmaWNhciBlbCB0aXBvIGRlIG9iamV0byBzdWJ5YWNlbnRlLiAKLUlOVkFMSURfU1RBVEVfRVJSID0gU2UgaGEgcmVhbGl6YWRvIHVuIGludGVudG8gZGUgdXRpbGl6YXIgdW4gb2JqZXRvIHF1ZSB5YSBubyBzZSBwdWVkZSB1dGlsaXphci4gCi1OQU1FU1BBQ0VfRVJSID0gU2UgaGEgcmVhbGl6YWRvIHVuIGludGVudG8gZGUgY3JlYXIgbyBjYW1iaWFyIHVuIG9iamV0byBkZSB1biBtb2RvIGluY29ycmVjdG8gY29uIHJlc3BlY3RvIGEgbG9zIGVzcGFjaW9zIGRlIG5vbWJyZXMuCi1OT1RfRk9VTkRfRVJSID0gU2UgaGEgcmVhbGl6YWRvIHVuIGludGVudG8gZGUgaGFjZXIgcmVmZXJlbmNpYSBhIHVuIG5vZG8gZW4gdW4gY29udGV4dG8gZW4gZWwgcXVlIG5vIGV4aXN0ZS4KLU5PVF9TVVBQT1JURURfRVJSID0gTGEgaW1wbGFudGFjaVx1MDBGM24gbm8gc29wb3J0YSBlbCB0aXBvIHNvbGljaXRhZG8gZGUgb2JqZXRvIHUgb3BlcmFjaVx1MDBGM24uIAotTk9fREFUQV9BTExPV0VEX0VSUiA9IFNlIGhhbiBlc3BlY2lmaWNhZG8gZGF0b3MgcGFyYSB1biBub2RvIHF1ZSBubyBzb3BvcnRhIGRhdG9zLgotTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSID0gU2UgaGEgcmVhbGl6YWRvIHVuIGludGVudG8gZGUgbW9kaWZpY2FyIHVuIG9iamV0byBlbiBlbCBxdWUgbm8gZXN0XHUwMEUxbiBwZXJtaXRpZGFzIGxhcyBtb2RpZmljYWNpb25lcy4KLVNZTlRBWF9FUlIgPSBTZSBoYSBlc3BlY2lmaWNhZG8gdW5hIGNhZGVuYSBubyB2XHUwMEUxbGlkYSBvIG5vIHBlcm1pdGlkYS4gCi1WQUxJREFUSU9OX0VSUiA9IFVuYSBsbGFtYWRhIGEgdW4gbVx1MDBFOXRvZG8gY29tbyBpbnNlcnRCZWZvcmUgbyByZW1vdmVDaGlsZCBpbnZhbGlkYXJcdTAwRURhIGVsIG5vZG8gY29uIHJlc3BlY3RvIGEgbGEgZ3JhbVx1MDBFMXRpY2EgZGVsIGRvY3VtZW50by4KLVdST05HX0RPQ1VNRU5UX0VSUiA9IFNlIGhhIHV0aWxpemFkbyB1biBub2RvIGVuIHVuIGRvY3VtZW50byBkaXN0aW50byBhbCBxdWUgbG8gY3JlXHUwMEYzLgotVFlQRV9NSVNNQVRDSF9FUlIgPSBFbCB0aXBvIGRlIHZhbG9yIHBhcmEgZXN0ZSBub21icmUgZGUgcGFyXHUwMEUxbWV0cm8gbm8gZXMgY29tcGF0aWJsZSBjb24gZWwgdGlwbyBkZSB2YWxvciBlc3BlcmFkby4gCi0gCi0jZXJyb3IgbWVzc2FnZXMgb3IgZXhjZXB0aW9ucwotRkVBVFVSRV9OT1RfU1VQUE9SVEVEID0gU2UgcmVjb25vY2UgZWwgcGFyXHUwMEUxbWV0cm8gezB9IHBlcm8gbm8gc2UgcHVlZGUgZGVmaW5pciBlbCB2YWxvciBzb2xpY2l0YWRvLgotRkVBVFVSRV9OT1RfRk9VTkQgPSBObyBzZSByZWNvbm9jZSBlbCBwYXJcdTAwRTFtZXRybyB7MH0uCi1TVFJJTkdfVE9PX0xPTkcgICA9IExhIGNhZGVuYSByZXN1bHRhbnRlIGVzIGRlbWFzaWFkbyBsYXJnYSBwYXJhIHF1ZSBxdWVwYSBlbiB1bmEgY2FkZW5hIERPTTogJyd7MH0nJy4KLQotI0RPTSBMZXZlbCAzIERPTUVycm9yIGNvZGVzCi13Zi1pbnZhbGlkLWNoYXJhY3RlciA9ICBFbCB0ZXh0byB7MH0gZGVsIG5vZG8gezF9IGNvbnRpZW5lIGNhcmFjdGVyZXMgWE1MIG5vIHZcdTAwRTFsaWRvcy4KLXdmLWludmFsaWQtY2hhcmFjdGVyLWluLW5vZGUtbmFtZSA9IEVsIG5vZG8gezB9IGNvbiBlbCBub21icmUgezF9IGNvbnRpZW5lIGNhcmFjdGVyZXMgWE1MIG5vIHZcdTAwRTFsaWRvcy4KLWNkYXRhLXNlY3Rpb25zLXNwbGl0dGVkID0gIExhcyBzZWNjaW9uZXMgQ0RBVEEgY29udGllbmVuIGVsIG1hcmNhZG9yIGRlIHRlcm1pbmFjaVx1MDBGM24gZGUgc2VjY2lcdTAwRjNuIENEQVRBICcnXV0+JycKLWRvY3R5cGUtbm90LWFsbG93ZWQgPSBMYSBkZWNsYXJhY2lcdTAwRjNuIERPQ1RZUEUgbm8gZXN0XHUwMEUxIHBlcm1pdGlkYS4KLXVuc3VwcG9ydGVkLWVuY29kaW5nID0gTGEgY29kaWZpY2FjaVx1MDBGM24gezB9IG5vIGVzdFx1MDBFMSBzb3BvcnRhZGEuCi0KLSNFcnJvciBjb2RlcyB1c2VkIGluIERPTSBOb3JtYWxpemVyCi1JbnZhbGlkWE1MQ2hhckluRE9NID0gU2UgaGEgZW5jb250cmFkbyB1biBjYXJcdTAwRTFjdGVyIFhNTCAoVW5pY29kZTogMHh7MH0pIG5vIHZcdTAwRTFsaWRvIGVuIERPTSBkdXJhbnRlIGxhIG5vcm1hbGl6YWNpXHUwMEYzbi4KLVVuZGVjbGFyZWRFbnRSZWZJbkF0dHJWYWx1ZSA9IEVsIGF0cmlidXRvICJ7MH0iIGNvbiB2YWxvciAiezF9IiBoYSBoZWNobyByZWZlcmVuY2lhIGEgdW5hIGVudGlkYWQgcXVlIG5vIHNlIGRlY2xhclx1MDBGMy4KLU51bGxMb2NhbEVsZW1lbnROYW1lID0gU2UgaGEgZW5jb250cmFkbyB1biBub21icmUgbG9jYWwgbnVsbyBkdXJhbnRlIGxhIG5vcm1hbGl6YWNpXHUwMEYzbiBkZWwgZXNwYWNpbyBkZSBub21icmVzIGRlbCBlbGVtZW50byB7MH0uCi1OdWxsTG9jYWxBdHRyTmFtZSA9IFNlIGhhIGVuY29udHJhZG8gdW4gbm9tYnJlIGxvY2FsIG51bG8gZHVyYW50ZSBsYSBub3JtYWxpemFjaVx1MDBGM24gZGVsIGVzcGFjaW8gZGUgbm9tYnJlcyBkZWwgYXRyaWJ1dG8gezB9LgotCi0jRXJyb3IgY29kZXMgdXNlZCBpbiBET01QYXJzZXIKLUludmFsaWREb2N1bWVudENsYXNzTmFtZSA9IEVsIG5vbWJyZSBkZSBjbGFzZSBkZSBsYSBmXHUwMEUxYnJpY2EgZGUgZG9jdW1lbnRvcyAiezB9IiB1dGlsaXphZG8gcGFyYSBjb25zdHJ1aXIgZWwgXHUwMEUxcmJvbCBET00gbm8gZXMgZGVsIHRpcG8gb3JnLnczYy5kb20uRG9jdW1lbnQuCi1NaXNzaW5nRG9jdW1lbnRDbGFzc05hbWUgPSBObyBzZSBoYSBlbmNvbnRyYWRvIGVsIG5vbWJyZSBkZSBjbGFzZSBkZSBsYSBmXHUwMEUxYnJpY2EgZGUgZG9jdW1lbnRvcyAiezB9IiB1dGlsaXphZG8gcGFyYSBjb25zdHJ1aXIgZWwgXHUwMEUxcmJvbCBET00uCi1DYW5ub3RDcmVhdGVEb2N1bWVudENsYXNzID0gTm8gc2UgaGEgcG9kaWRvIGNvbnN0cnVpciBsYSBjbGFzZSBjb24gZWwgbm9tYnJlICJ7MH0iIGNvbW8gdW4gb3JnLnczYy5kb20uRG9jdW1lbnQuCi0KLSMgRXJyb3IgY29kZXMgdXNlZCBieSBKQVhQIERvY3VtZW50QnVpbGRlcgotamF4cC1vcmRlci1ub3Qtc3VwcG9ydGVkID0gTGEgcHJvcGllZGFkICcnezB9JycgZGViZSBkZWZpbmlyc2UgYW50ZXMgZGUgZGVmaW5pciBsYSBwcm9waWVkYWQgJyd7MX0nJy4KLWpheHAtbnVsbC1pbnB1dC1zb3VyY2UgPSBFbCBvcmlnZW4gZXNwZWNpZmljYWRvIG5vIHB1ZWRlIHNlciBudWxvLgotCi0jUmFuZ2VzCi1CQURfQk9VTkRBUllQT0lOVFNfRVJSID0gTG9zIHB1bnRvcyBkZSBsXHUwMEVEbWl0ZSBkZSB1biByYW5nbyBubyBjdW1wbGVuIGxvcyByZXF1aXNpdG9zIGVzcGVjXHUwMEVEZmljb3MuCi1JTlZBTElEX05PREVfVFlQRV9FUlIgPSBFbCBjb250ZW5lZG9yIGRlIHVuIHB1bnRvIGRlIGxcdTAwRURtaXRlIGRlIHVuIHJhbmdvIHNlIGVzdFx1MDBFMSBkZWZpbmllbmRvIGVuIHVuIG5vZG8gZGUgdW4gdGlwbyBubyB2XHUwMEUxbGlkbyBvIHVuIG5vZG8gY29uIHVuIGFzY2VuZGllbnRlIGRlIHVuIHRpcG8gbm8gdlx1MDBFMWxpZG8uCi0KLQotI0V2ZW50cwotVU5TUEVDSUZJRURfRVZFTlRfVFlQRV9FUlIgPSBObyBzZSBoYSBlc3BlY2lmaWNhZG8gZWwgdGlwbyBkZSBldmVudG8gbWVkaWFudGUgbGEgaW5pY2lhbGl6YWNpXHUwMEYzbiBkZWwgZXZlbnRvIGFudGVzIGRlIHF1ZSBzZSBsbGFtZSBhbCBtXHUwMEU5dG9kby4gCi0KLQotamF4cC1zY2hlbWEtc3VwcG9ydD1TZSB1dGlsaXphIHRhbnRvIGVsIG1cdTAwRTl0b2RvIHNldFNjaGVtYSBjb21vIGxhIHByb3BpZWRhZCBzY2hlbWFMYW5ndWFnZQotCi1qYXhwX2ZlYXR1cmVfbm90X3N1cHBvcnRlZD1MYSBmdW5jaVx1MDBGM24gInswfSIgbm8gZXN0XHUwMEUxIHNvcG9ydGFkYS4KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL0RPTU1lc3NhZ2VzX2ZyLnByb3BlcnRpZXMgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9ET01NZXNzYWdlc19mci5wcm9wZXJ0aWVzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA5MjQxZmQ5Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL0RPTU1lc3NhZ2VzX2ZyLnByb3BlcnRpZXMKKysrIC9kZXYvbnVsbApAQCAtMSw2OSArMCwwIEBACi0jIFRoaXMgZmlsZSBzdG9yZXMgbG9jYWxpemVkIG1lc3NhZ2VzIGZvciB0aGUgWGVyY2VzCi0jIERPTSBpbXBsZW1lbnRhdGlvbi4KLSMKLSMgVGhlIG1lc3NhZ2VzIGFyZSBhcnJhbmdlZCBpbiBrZXkgYW5kIHZhbHVlIHR1cGxlcyBpbiBhIExpc3RSZXNvdXJjZUJ1bmRsZS4KLSMKLQotQmFkTWVzc2FnZUtleSA9IExlIG1lc3NhZ2UgZCdlcnJldXIgY29ycmVzcG9uZGFudCBcdTAwRTAgbGEgY2xcdTAwRTkgZGUgbWVzc2FnZSBlc3QgaW50cm91dmFibGUuCi1Gb3JtYXRGYWlsZWQgPSBVbmUgZXJyZXVyIGludGVybmUgZXN0IHN1cnZlbnVlIGxvcnMgZHUgZm9ybWF0YWdlIGR1IG1lc3NhZ2Ugc3VpdmFudCA6XG4gIAotCi0jIERPTSBDb3JlCi0KLSMgZXhjZXB0aW9uIGNvZGVzCi1ET01TVFJJTkdfU0laRV9FUlIgPSBMYSBwbGFnZSBkZSB0ZXh0ZSBpbmRpcXVcdTAwRTllIG5lIHRpZW50IHBhcyBkYW5zIHVuIFx1MDBFOWxcdTAwRTltZW50IERPTVN0cmluZy4gCi1ISUVSQVJDSFlfUkVRVUVTVF9FUlIgID0gVGVudGF0aXZlIGQnaW5zZXJ0aW9uIGQndW4gbm9ldWQgXHUwMEUwIHVuIGVtcGxhY2VtZW50IG5vbiBhdXRvcmlzXHUwMEU5LiAKLUlOREVYX1NJWkVfRVJSID0gTCdpbmRleCBvdSBsYSB0YWlsbGUgZXN0IG5cdTAwRTlnYXRpZiBvdSBkXHUwMEU5cGFzc2UgbGEgdmFsZXVyIGF1dG9yaXNcdTAwRTllLgotSU5VU0VfQVRUUklCVVRFX0VSUiA9IFRlbnRhdGl2ZSBkJ2Fqb3V0IGQndW4gYXR0cmlidXQgZFx1MDBFOWpcdTAwRTAgdXRpbGlzXHUwMEU5IGFpbGxldXJzLgotSU5WQUxJRF9BQ0NFU1NfRVJSICA9IFVuIHBhcmFtXHUwMEU4dHJlIG91IHVuZSBvcFx1MDBFOXJhdGlvbiBuJ2VzdCBwYXMgcHJpcyBlbiBjaGFyZ2UgcGFyIGwnb2JqZXQgc291cy1qYWNlbnQuIAotSU5WQUxJRF9DSEFSQUNURVJfRVJSID0gVW4gY2FyYWN0XHUwMEU4cmUgWE1MIG5vbiB2YWxpZGUgb3Ugbm9uIGFkbWlzIGVzdCBpbmRpcXVcdTAwRTkuIAotSU5WQUxJRF9NT0RJRklDQVRJT05fRVJSID0gIFRlbnRhdGl2ZSBkZSBtb2RpZmljYXRpb24gZHUgdHlwZSBkZSBsJ29iamV0IHNvdXMtamFjZW50LiAKLUlOVkFMSURfU1RBVEVfRVJSID0gVGVudGF0aXZlIGQndXRpbGlzYXRpb24gZCd1biBvYmpldCBxdWkgbidlc3QgcGFzIG91IHBsdXMgdXRpbGlzYWJsZS4gCi1OQU1FU1BBQ0VfRVJSID0gVGVudGF0aXZlIGRlIGNyXHUwMEU5YXRpb24gb3UgZGUgbW9kaWZpY2F0aW9uIGQndW4gb2JqZXQgaW5jb3JyZWN0ZSBwYXIgcmFwcG9ydCBhdXggZXNwYWNlcyBkZSBub21zLgotTk9UX0ZPVU5EX0VSUiA9IFRlbnRhdGl2ZSBkZSByXHUwMEU5Zlx1MDBFOXJlbmNlbWVudCBkJ3VuIG5vZXVkIGRhbnMgdW4gY29udGV4dGUgb1x1MDBGOSBpbCBuJ2V4aXN0ZSBwYXMuCi1OT1RfU1VQUE9SVEVEX0VSUiA9IEwnaW1wbFx1MDBFOW1lbnRhdGlvbiBuZSBwcmVuZCBwYXMgZW4gY2hhcmdlIGxlIHR5cGUgZCdvYmpldCBvdSBkJ29wXHUwMEU5cmF0aW9uIGRlbWFuZFx1MDBFOS4gCi1OT19EQVRBX0FMTE9XRURfRVJSID0gRGVzIGRvbm5cdTAwRTllcyBvbnQgXHUwMEU5dFx1MDBFOSBpbmRpcXVcdTAwRTllcyBwb3VyIHVuIG5vZXVkIG5lIHByZW5hbnQgcGFzIGVuIGNoYXJnZSBsZXMgZG9ublx1MDBFOWVzLgotTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSID0gVGVudGF0aXZlIGRlIG1vZGlmaWNhdGlvbiBkJ3VuIG9iamV0IHBvdXIgbGVxdWVsIGxlcyBtb2RpZmljYXRpb25zIG5lIHNvbnQgcGFzIGF1dG9yaXNcdTAwRTllcy4KLVNZTlRBWF9FUlIgPSBVbmUgY2hhXHUwMEVFbmUgbm9uIHZhbGlkZSBvdSBub24gYWRtaXNlIGVzdCBpbmRpcXVcdTAwRTllLiAKLVZBTElEQVRJT05fRVJSID0gTCdhcHBlbCBkJ3VuZSBtXHUwMEU5dGhvZGUgY29tbWUgaW5zZXJ0QmVmb3JlIG91IHJlbW92ZUNoaWxkIHJpc3F1ZSBkZSByZW5kcmUgbGUgbm9ldWQgbm9uIHZhbGlkZSBwYXIgcmFwcG9ydCBcdTAwRTAgbGEgZ3JhbW1haXJlIGRlIGRvY3VtZW50LgotV1JPTkdfRE9DVU1FTlRfRVJSID0gVW4gbm9ldWQgZXN0IHV0aWxpc1x1MDBFOSBkYW5zIHVuIGRvY3VtZW50IGRpZmZcdTAwRTlyZW50IGRlIGNlbHVpIGwnYXlhbnQgY3JcdTAwRTlcdTAwRTkuCi1UWVBFX01JU01BVENIX0VSUiA9IExlIHR5cGUgZGUgdmFsZXVyIHBvdXIgY2Ugbm9tIGRlIHBhcmFtXHUwMEU4dHJlIG4nZXN0IHBhcyBjb21wYXRpYmxlIGF2ZWMgbGUgdHlwZSBkZSB2YWxldXIgYXR0ZW5kdS4gCi0gCi0jZXJyb3IgbWVzc2FnZXMgb3IgZXhjZXB0aW9ucwotRkVBVFVSRV9OT1RfU1VQUE9SVEVEID0gTGUgcGFyYW1cdTAwRTh0cmUgezB9IGVzdCByZWNvbm51IG1haXMgbGEgdmFsZXVyIGRlbWFuZFx1MDBFOWUgbmUgcGV1dCBwYXMgXHUwMEVBdHJlIGRcdTAwRTlmaW5pZS4KLUZFQVRVUkVfTk9UX0ZPVU5EID0gTGUgcGFyYW1cdTAwRTh0cmUgezB9IG4nJ2VzdCBwYXMgcmVjb25udS4KLVNUUklOR19UT09fTE9ORyAgID0gTGEgY2hhXHUwMEVFbmUgb2J0ZW51ZSBlc3QgdHJvcCBsb25ndWUgcG91ciB0ZW5pciBkYW5zIHVuIFx1MDBFOWxcdTAwRTltZW50IERPTVN0cmluZyA6ICcnezB9JycuCi0KLSNET00gTGV2ZWwgMyBET01FcnJvciBjb2Rlcwotd2YtaW52YWxpZC1jaGFyYWN0ZXIgPSAgTGUgdGV4dGUgezB9IGR1IG5vZXVkIHsxfSBjb250aWVudCBkZXMgY2FyYWN0XHUwMEU4cmVzIFhNTCBub24gdmFsaWRlcy4KLXdmLWludmFsaWQtY2hhcmFjdGVyLWluLW5vZGUtbmFtZSA9IExlIG5vZXVkIHswfSBub21tXHUwMEU5IHsxfSBjb250aWVudCBkZXMgY2FyYWN0XHUwMEU4cmVzIFhNTCBub24gdmFsaWRlcy4KLWNkYXRhLXNlY3Rpb25zLXNwbGl0dGVkID0gIFNlY3Rpb25zIENEQVRBIGNvbnRlbmFudCBsZSBtYXJxdWV1ciBkZSBmaW4gZGUgc2VjdGlvbiBDREFUQSAnJ11dPicnCi1kb2N0eXBlLW5vdC1hbGxvd2VkID0gTGEgZFx1MDBFOWNsYXJhdGlvbiBET0NUWVBFIG4nZXN0IHBhcyBhdXRvcmlzXHUwMEU5ZS4KLXVuc3VwcG9ydGVkLWVuY29kaW5nID0gTCcnZW5jb2RhZ2UgezB9IG4nJ2VzdCBwYXMgcHJpcyBlbiBjaGFyZ2UuCi0KLSNFcnJvciBjb2RlcyB1c2VkIGluIERPTSBOb3JtYWxpemVyCi1JbnZhbGlkWE1MQ2hhckluRE9NID0gVW4gY2FyYWN0XHUwMEU4cmUgWE1MIG5vbiB2YWxpZGUgKFVuaWNvZGUgOiAweHswfSkgYSBcdTAwRTl0XHUwMEU5IHRyb3V2XHUwMEU5IGRhbnMgbGUgRE9NIGF1IGNvdXJzIGRlIGxhIG5vcm1hbGlzYXRpb24uCi1VbmRlY2xhcmVkRW50UmVmSW5BdHRyVmFsdWUgPSBMYSB2YWxldXIgZGUgbCcnYXR0cmlidXQgInswfSIsICJ7MX0iLCByXHUwMEU5Zlx1MDBFOXJlblx1MDBFN2FpdCB1bmUgZW50aXRcdTAwRTkgbm9uIGRcdTAwRTljbGFyXHUwMEU5ZS4KLU51bGxMb2NhbEVsZW1lbnROYW1lID0gVW4gbm9tIGxvY2FsIE5VTEwgYSBcdTAwRTl0XHUwMEU5IGRcdTAwRTl0ZWN0XHUwMEU5IGF1IGNvdXJzIGRlIGxhIG5vcm1hbGlzYXRpb24gZGUgbCcnZXNwYWNlIGRlIG5vbXMgZGUgbCcnXHUwMEU5bFx1MDBFOW1lbnQgezB9LgotTnVsbExvY2FsQXR0ck5hbWUgPSBVbiBub20gbG9jYWwgTlVMTCBhIFx1MDBFOXRcdTAwRTkgZFx1MDBFOXRlY3RcdTAwRTkgYXUgY291cnMgZGUgbGEgbm9ybWFsaXNhdGlvbiBkZSBsJydlc3BhY2UgZGUgbm9tcyBkZSBsJydhdHRyaWJ1dCB7MH0uCi0KLSNFcnJvciBjb2RlcyB1c2VkIGluIERPTVBhcnNlcgotSW52YWxpZERvY3VtZW50Q2xhc3NOYW1lID0gTGUgbm9tIGRlIGNsYXNzZSBkZSBsYSBmYWJyaXF1ZSBkZSBkb2N1bWVudHMgInswfSIgdXRpbGlzXHUwMEU5ZSBwb3VyIGNvbnN0cnVpcmUgbCcnYXJib3Jlc2NlbmNlIERPTSBuJydlc3QgcGFzIGRlIHR5cGUgb3JnLnczYy5kb20uRG9jdW1lbnQuCi1NaXNzaW5nRG9jdW1lbnRDbGFzc05hbWUgPSBMZSBub20gZGUgY2xhc3NlIGRlIGxhIGZhYnJpcXVlIGRlIGRvY3VtZW50cyAiezB9IiB1dGlsaXNcdTAwRTllIHBvdXIgY29uc3RydWlyZSBsJydhcmJvcmVzY2VuY2UgRE9NIGVzdCBpbnRyb3V2YWJsZS4KLUNhbm5vdENyZWF0ZURvY3VtZW50Q2xhc3MgPSBMYSBjbGFzc2Ugbm9tbVx1MDBFOWUgInswfSIgbicnYSBwYXMgcHUgXHUwMEVBdHJlIGNvbnN0cnVpdGUgZW4gdGFudCBxdWUgb3JnLnczYy5kb20uRG9jdW1lbnQuCi0KLSMgRXJyb3IgY29kZXMgdXNlZCBieSBKQVhQIERvY3VtZW50QnVpbGRlcgotamF4cC1vcmRlci1ub3Qtc3VwcG9ydGVkID0gTGEgcHJvcHJpXHUwMEU5dFx1MDBFOSAnJ3swfScnIGRvaXQgXHUwMEVBdHJlIGRcdTAwRTlmaW5pZSBhdmFudCBsYSBwcm9wcmlcdTAwRTl0XHUwMEU5ICcnezF9JycuCi1qYXhwLW51bGwtaW5wdXQtc291cmNlID0gTGEgc291cmNlIGluZGlxdVx1MDBFOWUgbmUgcGV1dCBwYXMgXHUwMEVBdHJlIE5VTEwuCi0KLSNSYW5nZXMKLUJBRF9CT1VOREFSWVBPSU5UU19FUlIgPSBMZXMgcG9pbnRzIGRlIGxpbWl0ZSBkJ3VuZSBwbGFnZSBuZSByXHUwMEU5cG9uZGVudCBwYXMgYXV4IGV4aWdlbmNlcyBzcFx1MDBFOWNpZmlxdWVzLgotSU5WQUxJRF9OT0RFX1RZUEVfRVJSID0gTGUgY29udGVuZXVyIGQndW4gcG9pbnQgZGUgbGltaXRlIGQndW5lIHBsYWdlIGVzdCBkXHUwMEU5ZmluaSBzdXIgdW4gbm9ldWQgZGUgdHlwZSBub24gdmFsaWRlIG91IHN1ciB1biBub2V1ZCBheWFudCB1biBhbmNcdTAwRUF0cmUgZGUgdHlwZSBub24gdmFsaWRlLgotCi0KLSNFdmVudHMKLVVOU1BFQ0lGSUVEX0VWRU5UX1RZUEVfRVJSID0gTGUgdHlwZSBkJ1x1MDBFOXZcdTAwRTluZW1lbnQgbidhIHBhcyBcdTAwRTl0XHUwMEU5IGluZGlxdVx1MDBFOSBlbiBpbml0aWFsaXNhbnQgbCdcdTAwRTl2XHUwMEU5bmVtZW50IGF2YW50IGwnYXBwZWwgZGUgbGEgbVx1MDBFOXRob2RlLiAKLQotCi1qYXhwLXNjaGVtYS1zdXBwb3J0PUxhIG1cdTAwRTl0aG9kZSBzZXRTY2hlbWEgZXQgbGEgcHJvcHJpXHUwMEU5dFx1MDBFOSBzY2hlbWFMYW5ndWFnZSBzb250IHV0aWxpc1x1MDBFOWVzCi0KLWpheHBfZmVhdHVyZV9ub3Rfc3VwcG9ydGVkPUxhIGZvbmN0aW9ubmFsaXRcdTAwRTkgJyd7MH0nJyBuJydlc3QgcGFzIHByaXNlIGVuIGNoYXJnZS4KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL0RPTU1lc3NhZ2VzX2l0LnByb3BlcnRpZXMgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9ET01NZXNzYWdlc19pdC5wcm9wZXJ0aWVzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0ZjRmYWJiLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL0RPTU1lc3NhZ2VzX2l0LnByb3BlcnRpZXMKKysrIC9kZXYvbnVsbApAQCAtMSw2OSArMCwwIEBACi0jIFRoaXMgZmlsZSBzdG9yZXMgbG9jYWxpemVkIG1lc3NhZ2VzIGZvciB0aGUgWGVyY2VzCi0jIERPTSBpbXBsZW1lbnRhdGlvbi4KLSMKLSMgVGhlIG1lc3NhZ2VzIGFyZSBhcnJhbmdlZCBpbiBrZXkgYW5kIHZhbHVlIHR1cGxlcyBpbiBhIExpc3RSZXNvdXJjZUJ1bmRsZS4KLSMKLQotQmFkTWVzc2FnZUtleSA9IEltcG9zc2liaWxlIHRyb3ZhcmUgaWwgbWVzc2FnZ2lvIGRpIGVycm9yZSBjb3JyaXNwb25kZW50ZSBhbGxhIGNoaWF2ZSBkaSBtZXNzYWdnaW8uCi1Gb3JtYXRGYWlsZWQgPSBTaSBcdTAwRTggdmVyaWZpY2F0byB1biBlcnJvcmUgaW50ZXJubyBkdXJhbnRlIGxhIGZvcm1hdHRhemlvbmUgZGVsIHNlZ3VlbnRlIG1lc3NhZ2dpbzpcbiAgCi0KLSMgRE9NIENvcmUKLQotIyBleGNlcHRpb24gY29kZXMKLURPTVNUUklOR19TSVpFX0VSUiA9IEwnaW50ZXJ2YWxsbyBkaSB0ZXN0byBzcGVjaWZpY2F0byBub24gc2kgYWRhdHRhIGluIERPTVN0cmluZy4gCi1ISUVSQVJDSFlfUkVRVUVTVF9FUlIgID0gU2kgXHUwMEU4IHRlbnRhdG8gZGkgaW5zZXJpcmUgdW4gbm9kbyBpbiB1biBwdW50byBpbiBjdWkgbm9uIFx1MDBFOCBjb25zZW50aXRvLiAKLUlOREVYX1NJWkVfRVJSID0gTCdpbmRpY2UgbyBsYSBkaW1lbnNpb25lIFx1MDBFOCBuZWdhdGl2YSBvIG1hZ2dpb3JlIGRlbCB2YWxvcmUgY29uc2VudGl0by4KLUlOVVNFX0FUVFJJQlVURV9FUlIgPSBTaSBcdTAwRTggdGVudGF0byBkaSBhZ2dpdW5nZXJlIHVuIGF0dHJpYnV0byBnaVx1MDBFMCBpbiB1c28gYWx0cm92ZS4KLUlOVkFMSURfQUNDRVNTX0VSUiAgPSBVbiBwYXJhbWV0cm8gbyB1bidvcGVyYXppb25lIG5vbiBcdTAwRTggc3VwcG9ydGF0YSBkYWxsJ29nZ2V0dG8gZGkgYmFzZS4gCi1JTlZBTElEX0NIQVJBQ1RFUl9FUlIgPSBcdTAwQzggc3RhdG8gc3BlY2lmaWNhdG8gdW4gY2FyYXR0ZXJlIFhNTCBub24gdmFsaWRvLiAKLUlOVkFMSURfTU9ESUZJQ0FUSU9OX0VSUiA9ICBTaSBcdTAwRTggdGVudGF0byBkaSBtb2RpZmljYXJlIGlsIHRpcG8gZGVsbCdvZ2dldHRvIGRpIGJhc2UuIAotSU5WQUxJRF9TVEFURV9FUlIgPSBTaSBcdTAwRTggdGVudGF0byBkaSB1dGlsaXp6YXJlIHVuIG9nZ2V0dG8gY2hlIG5vbiBcdTAwRTggbyBub24gXHUwMEU4IHBpXHUwMEY5IHV0aWxpenphYmlsZS4gCi1OQU1FU1BBQ0VfRVJSID0gU2kgXHUwMEU4IHRlbnRhdG8gZGkgY3JlYXJlIG8gbW9kaWZpY2FyZSB1biBvZ2dldHRvIGluIG1vZG8gZXJyYXRvIHBlciBxdWVsIGNoZSByaWd1YXJkYSBnbGkgc3BhemkgZGkgbm9taS4KLU5PVF9GT1VORF9FUlIgPSBTaSBcdTAwRTggdGVudGF0byBkaSBmYXJlIHJpZmVyaW1lbnRvIGEgdW4gbm9kbyBpbiB1biBjb250ZXN0byBpbiBjdWkgbm9uIGVzaXN0ZS4KLU5PVF9TVVBQT1JURURfRVJSID0gTCdpbXBsZW1lbnRhemlvbmUgbm9uIHN1cHBvcnRhIGlsIHRpcG8gcmljaGllc3RvIGRpIG9nZ2V0dG8gbyBvcGVyYXppb25lLiAKLU5PX0RBVEFfQUxMT1dFRF9FUlIgPSBTb25vIHN0YXRpIHNwZWNpZmljYXRpIGRhdGkgcGVyIHVuIG5vZG8gY2hlIG5vbiBzdXBwb3J0YSBkYXRpLgotTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSID0gU2kgXHUwMEU4IHRlbnRhdG8gZGkgbW9kaWZpY2FyZSB1biBvZ2dldHRvIG5vbiBtb2RpZmljYWJpbGUuCi1TWU5UQVhfRVJSID0gXHUwMEM4IHN0YXRhIHNwZWNpZmljYXRhIHVuYSBzdHJpbmdhIG5vbiB2YWxpZGEuIAotVkFMSURBVElPTl9FUlIgPSBTZSBzaSByaWNoaWFtYSB1biBtZXRvZG8gY29tZSBpbnNlcnRCZWZvcmUgbyByZW1vdmVDaGlsZCwgaWwgbm9kbyBub24gc2FyXHUwMEUwIHZhbGlkbyBwZXIgcXVlbCBjaGUgcmlndWFyZGEgbGEgZ3JhbW1hdGljYSBkZWwgZG9jdW1lbnRvLgotV1JPTkdfRE9DVU1FTlRfRVJSID0gVW4gbm9kbyBcdTAwRTggdXRpbGl6emF0byBpbiB1biBkb2N1bWVudG8gZGl2ZXJzbyBkYSBxdWVsbG8gY2hlIGxvIGhhIGNyZWF0by4KLVRZUEVfTUlTTUFUQ0hfRVJSID0gSWwgdGlwbyBkaSB2YWxvcmUgcGVyIHF1ZXN0byBub21lIHBhcmFtZXRybyBub24gXHUwMEU4IGNvbXBhdGliaWxlIGNvbiBpbCB0aXBvIGRpIHZhbG9yZSBwcmV2aXN0by4gCi0gCi0jZXJyb3IgbWVzc2FnZXMgb3IgZXhjZXB0aW9ucwotRkVBVFVSRV9OT1RfU1VQUE9SVEVEID0gSWwgcGFyYW1ldHJvIHswfSBcdTAwRTggc3RhdG8gcmljb25vc2NpdXRvLCBtYSBub24gXHUwMEU4IHBvc3NpYmlsZSBpbXBvc3RhcmUgaWwgdmFsb3JlIHJpY2hpZXN0by4KLUZFQVRVUkVfTk9UX0ZPVU5EID0gSWwgcGFyYW1ldHJvIHswfSBub24gXHUwMEU4IHJpY29ub3NjaXV0by4KLVNUUklOR19UT09fTE9ORyAgID0gTGEgc3RyaW5nYSByaXN1bHRhbnRlIFx1MDBFOCB0cm9wcG8gbHVuZ2EgcGVyIGFkYXR0YXJzaSBpbiBET01TdHJpbmc6ICcnezB9JycuCi0KLSNET00gTGV2ZWwgMyBET01FcnJvciBjb2Rlcwotd2YtaW52YWxpZC1jaGFyYWN0ZXIgPSAgSWwgdGVzdG8gezB9IGRlbCBub2RvIHsxfSBjb250aWVuZSBjYXJhdHRlcmkgWE1MIG5vbiB2YWxpZGkuCi13Zi1pbnZhbGlkLWNoYXJhY3Rlci1pbi1ub2RlLW5hbWUgPSBJbCBub2RvIHswfSBkZW5vbWluYXRvIHsxfSBjb250aWVuZSBjYXJhdHRlcmkgWE1MIG5vbiB2YWxpZGkuCi1jZGF0YS1zZWN0aW9ucy1zcGxpdHRlZCA9ICBTZXppb25pIENEQVRBIGNoZSBjb250ZW5nb25vIGwnaW5kaWNhdG9yZSBkaSBmaW5lIGRlbGxhIHNlemlvbmUgQ0RBVEEgJyddXT4nJwotZG9jdHlwZS1ub3QtYWxsb3dlZCA9IERpY2hpYXJhemlvbmUgRE9DVFlQRSBub24gY29uc2VudGl0YS4KLXVuc3VwcG9ydGVkLWVuY29kaW5nID0gTGEgY29kaWZpY2EgezB9IG5vbiBcdTAwRTggc3VwcG9ydGF0YS4KLQotI0Vycm9yIGNvZGVzIHVzZWQgaW4gRE9NIE5vcm1hbGl6ZXIKLUludmFsaWRYTUxDaGFySW5ET00gPSBcdTAwQzggc3RhdG8gdHJvdmF0byB1biBjYXJhdHRlcmUgWE1MIG5vbiB2YWxpZG8gKFVuaWNvZGU6IDB4ezB9KSBpbiBET00gZHVyYW50ZSBsYSBub3JtYWxpenphemlvbmUuCi1VbmRlY2xhcmVkRW50UmVmSW5BdHRyVmFsdWUgPSBMJydhdHRyaWJ1dG8gInswfSIgY29uIHZhbG9yZSAiezF9IiBmYSByaWZlcmltZW50byBhIHVuJydlbnRpdFx1MDBFMCBub24gZGljaGlhcmF0YS4KLU51bGxMb2NhbEVsZW1lbnROYW1lID0gXHUwMEM4IHN0YXRvIHJpbGV2YXRvIHVuIG5vbWUgbG9jYWxlIG51bGxvIGR1cmFudGUgbGEgbm9ybWFsaXp6YXppb25lIGRlbGxvIHNwYXppbyBkaSBub21pIGRlbGwnJ2VsZW1lbnRvIHswfS4KLU51bGxMb2NhbEF0dHJOYW1lID0gXHUwMEM4IHN0YXRvIHJpbGV2YXRvIHVuIG5vbWUgbG9jYWxlIG51bGxvIGR1cmFudGUgbGEgbm9ybWFsaXp6YXppb25lIGRlbGxvIHNwYXppbyBkaSBub21pIGRlbGwnJ2F0dHJpYnV0byB7MH0uCi0KLSNFcnJvciBjb2RlcyB1c2VkIGluIERPTVBhcnNlcgotSW52YWxpZERvY3VtZW50Q2xhc3NOYW1lID0gSWwgbm9tZSBjbGFzc2UgZGVsIGRvY3VtZW50IGZhY3RvcnkgInswfSIgdXRpbGl6emF0byBwZXIgY3JlYXJlIGxhIHN0cnV0dHVyYSBET00gbm9uIFx1MDBFOCBkaSB0aXBvIG9yZy53M2MuZG9tLkRvY3VtZW50LgotTWlzc2luZ0RvY3VtZW50Q2xhc3NOYW1lID0gSW1wb3NzaWJpbGUgdHJvdmFyZSBpbCBub21lIGNsYXNzZSBkZWwgZG9jdW1lbnQgZmFjdG9yeSAiezB9IiB1dGlsaXp6YXRvIHBlciBjcmVhcmUgbGEgc3RydXR0dXJhIERPTS4KLUNhbm5vdENyZWF0ZURvY3VtZW50Q2xhc3MgPSBJbXBvc3NpYmlsZSBjcmVhcmUgbGEgY2xhc3NlIGRlbm9taW5hdGEgInswfSIgY29tZSBvcmcudzNjLmRvbS5Eb2N1bWVudC4KLQotIyBFcnJvciBjb2RlcyB1c2VkIGJ5IEpBWFAgRG9jdW1lbnRCdWlsZGVyCi1qYXhwLW9yZGVyLW5vdC1zdXBwb3J0ZWQgPSBJbXBvc3RhcmUgbGEgcHJvcHJpZXRcdTAwRTAgJyd7MH0nJyBwcmltYSBkaSBpbXBvc3RhcmUgbGEgcHJvcHJpZXRcdTAwRTAgJyd7MX0nJy4KLWpheHAtbnVsbC1pbnB1dC1zb3VyY2UgPSBMJ29yaWdpbmUgc3BlY2lmaWNhdGEgbm9uIHB1XHUwMEYyIGVzc2VyZSBudWxsYS4KLQotI1JhbmdlcwotQkFEX0JPVU5EQVJZUE9JTlRTX0VSUiA9IEkgcHVudGkgbGltaXRlIGRpIHVuIGludGVydmFsbG8gbm9uIHJpc3BldHRhbm8gaSByZXF1aXNpdGkgc3BlY2lmaWNpLgotSU5WQUxJRF9OT0RFX1RZUEVfRVJSID0gSWwgY29udGVuaXRvcmUgZGkgdW4gcHVudG8gbGltaXRlIGRpIHVuIGludGVydmFsbG8gXHUwMEU4IHN0YXRvIGltcG9zdGF0byBzdSB1biBub2RvIGRpIHRpcG8gbm9uIHZhbGlkbyBvIHN1IHVuIG5vZG8gY29uIHVuIHByZWRlY2Vzc29yZSBkaSB0aXBvIG5vbiB2YWxpZG8uCi0KLQotI0V2ZW50cwotVU5TUEVDSUZJRURfRVZFTlRfVFlQRV9FUlIgPSBJbCB0aXBvIGRpIGV2ZW50byBub24gXHUwMEU4IHN0YXRvIHNwZWNpZmljYXRvIGluaXppYWxpenphbmRvIGwnZXZlbnRvIHByaW1hIGNoZSBmb3NzZSByaWNoaWFtYXRvIGlsIG1ldG9kby4gCi0KLQotamF4cC1zY2hlbWEtc3VwcG9ydD1Tb25vIHN0YXRpIHV0aWxpenphdGkgc2lhIGlsIG1ldG9kbyBzZXRTY2hlbWEgY2hlIGxhIHByb3ByaWV0XHUwMEUwIHNjaGVtYUxhbmd1YWdlCi0KLWpheHBfZmVhdHVyZV9ub3Rfc3VwcG9ydGVkPUxhIGZ1bnppb25lICJ7MH0iIG5vbiBcdTAwRTggc3VwcG9ydGF0YS4KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL0RPTU1lc3NhZ2VzX2phLnByb3BlcnRpZXMgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9ET01NZXNzYWdlc19qYS5wcm9wZXJ0aWVzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjM2IzZGQ5Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL0RPTU1lc3NhZ2VzX2phLnByb3BlcnRpZXMKKysrIC9kZXYvbnVsbApAQCAtMSw2OSArMCwwIEBACi0jIFRoaXMgZmlsZSBzdG9yZXMgbG9jYWxpemVkIG1lc3NhZ2VzIGZvciB0aGUgWGVyY2VzCi0jIERPTSBpbXBsZW1lbnRhdGlvbi4KLSMKLSMgVGhlIG1lc3NhZ2VzIGFyZSBhcnJhbmdlZCBpbiBrZXkgYW5kIHZhbHVlIHR1cGxlcyBpbiBhIExpc3RSZXNvdXJjZUJ1bmRsZS4KLSMKLQotQmFkTWVzc2FnZUtleSA9IFx1MzBFMVx1MzBDM1x1MzBCQlx1MzBGQ1x1MzBCOFx1MzBGQlx1MzBBRFx1MzBGQ1x1MzA2Qlx1NUJGRVx1NUZEQ1x1MzA1OVx1MzA4Qlx1MzBBOFx1MzBFOVx1MzBGQ1x1MzBGQlx1MzBFMVx1MzBDM1x1MzBCQlx1MzBGQ1x1MzBCOFx1MzA0Q1x1ODk4Qlx1MzA2NFx1MzA0Qlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotRm9ybWF0RmFpbGVkID0gXHU2QjIxXHUzMDZFXHUzMEUxXHUzMEMzXHUzMEJCXHUzMEZDXHUzMEI4XHUzMDZFXHU2NkY4XHU1RjBGXHU4QTJEXHU1QjlBXHU0RTJEXHUzMDZCXHU1MTg1XHU5MEU4XHUzMEE4XHUzMEU5XHUzMEZDXHUzMDRDXHU3NjdBXHU3NTFGXHUzMDU3XHUzMDdFXHUzMDU3XHUzMDVGOlxuICAKLQotIyBET00gQ29yZQotCi0jIGV4Y2VwdGlvbiBjb2RlcwotRE9NU1RSSU5HX1NJWkVfRVJSID0gXHU2MzA3XHU1QjlBXHUzMDU3XHUzMDVGXHUzMEM2XHUzMEFEXHUzMEI5XHUzMEM4XHU3QkM0XHU1NkYyXHUzMDZGRE9NU3RyaW5nXHUzMDZCXHU1M0NFXHUzMDdFXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyIAotSElFUkFSQ0hZX1JFUVVFU1RfRVJSICA9IFx1OEEzMVx1NTNFRlx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA2QVx1MzA0NFx1NTgzNFx1NjI0MFx1MzA2N1x1MzBDRVx1MzBGQ1x1MzBDOVx1MzA5Mlx1NjMzRlx1NTE2NVx1MzA1N1x1MzA4OFx1MzA0Nlx1MzA2OFx1MzA1N1x1MzA3RVx1MzA1N1x1MzA1Rlx1MzAwMiAKLUlOREVYX1NJWkVfRVJSID0gXHU3RDIyXHU1RjE1XHUzMDdFXHUzMDVGXHUzMDZGXHUzMEI1XHUzMEE0XHUzMEJBXHUzMDRDXHU4Q0EwXHUzMDRCXHUzMDAxXHU4QTMxXHU1QkI5XHU1MDI0XHUzMDg4XHUzMDhBXHU1OTI3XHUzMDREXHUzMDRGXHUzMDZBXHUzMDYzXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5XHUzMDAyCi1JTlVTRV9BVFRSSUJVVEVfRVJSID0gXHU0RUQ2XHUzMDZFXHU1ODM0XHU2MjQwXHUzMDY3XHUzMDU5XHUzMDY3XHUzMDZCXHU0RjdGXHU3NTI4XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDhCXHU1QzVFXHU2MDI3XHUzMDkyXHU4RkZEXHU1MkEwXHUzMDU3XHUzMDg4XHUzMDQ2XHUzMDY4XHUzMDU3XHUzMDdFXHUzMDU3XHUzMDVGXHUzMDAyCi1JTlZBTElEX0FDQ0VTU19FUlIgID0gXHU1N0ZBXHU3OTBFXHUzMDY4XHUzMDZBXHUzMDhCXHUzMEFBXHUzMEQ2XHUzMEI4XHUzMEE3XHUzMEFGXHUzMEM4XHUzMDY3XHUzMEQxXHUzMEU5XHUzMEUxXHUzMEZDXHUzMEJGXHUzMDdFXHUzMDVGXHUzMDZGXHU2NENEXHU0RjVDXHUzMDRDXHUzMEI1XHUzMEREXHUzMEZDXHUzMEM4XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyIAotSU5WQUxJRF9DSEFSQUNURVJfRVJSID0gXHU3MTIxXHU1MkI5XHUzMDdFXHUzMDVGXHUzMDZGXHU0RTBEXHU2QjYzXHUzMDZBWE1MXHU2NTg3XHU1QjU3XHUzMDRDXHU2MzA3XHU1QjlBXHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5XHUzMDAyIAotSU5WQUxJRF9NT0RJRklDQVRJT05fRVJSID0gIFx1NTdGQVx1NzkwRVx1MzA2OFx1MzA2QVx1MzA4Qlx1MzBBQVx1MzBENlx1MzBCOFx1MzBBN1x1MzBBRlx1MzBDOFx1MzA2RVx1MzBCRlx1MzBBNFx1MzBEN1x1MzA5Mlx1NTkwOVx1NjZGNFx1MzA1N1x1MzA4OFx1MzA0Nlx1MzA2OFx1MzA1N1x1MzA3RVx1MzA1N1x1MzA1Rlx1MzAwMiAKLUlOVkFMSURfU1RBVEVfRVJSID0gXHU0RjdGXHU3NTI4XHUzMDY3XHUzMDREXHUzMDZBXHUzMDQ0XHUzMDRCXHUzMDAxXHU0RUNBXHU1RjhDXHU0RjdGXHU3NTI4XHUzMDY3XHUzMDREXHUzMDZBXHUzMDRGXHUzMDZBXHUzMDhCXHUzMEFBXHUzMEQ2XHUzMEI4XHUzMEE3XHUzMEFGXHUzMEM4XHUzMDkyXHU0RjdGXHU3NTI4XHUzMDU3XHUzMDg4XHUzMDQ2XHUzMDY4XHUzMDU3XHUzMDdFXHUzMDU3XHUzMDVGXHUzMDAyIAotTkFNRVNQQUNFX0VSUiA9IFx1MzBDRFx1MzBGQ1x1MzBFMFx1MzBCOVx1MzBEQVx1MzBGQ1x1MzBCOVx1MzA2Qlx1OTVBMlx1MzA1N1x1MzA2Nlx1NEUwRFx1OTA2OVx1NTIwN1x1MzA2QVx1NjVCOVx1NkNENVx1MzA2N1x1MzBBQVx1MzBENlx1MzBCOFx1MzBBN1x1MzBBRlx1MzBDOFx1MzA5Mlx1NEY1Q1x1NjIxMFx1MzA3RVx1MzA1Rlx1MzA2Rlx1NTkwOVx1NjZGNFx1MzA1N1x1MzA4OFx1MzA0Nlx1MzA2OFx1MzA1N1x1MzA3RVx1MzA1N1x1MzA1Rlx1MzAwMgotTk9UX0ZPVU5EX0VSUiA9IFx1MzBCM1x1MzBGM1x1MzBDNlx1MzBBRFx1MzBCOVx1MzBDOFx1MzA2Qlx1NUI1OFx1NTcyOFx1MzA1N1x1MzA2QVx1MzA0NFx1MzBDRVx1MzBGQ1x1MzBDOVx1MzA5Mlx1NTNDMlx1NzE2N1x1MzA1N1x1MzA4OFx1MzA0Nlx1MzA2OFx1MzA1N1x1MzA3RVx1MzA1N1x1MzA1Rlx1MzAwMgotTk9UX1NVUFBPUlRFRF9FUlIgPSBcdTMwRUFcdTMwQUZcdTMwQThcdTMwQjlcdTMwQzhcdTMwNTdcdTMwNUZcdTMwQkZcdTMwQTRcdTMwRDdcdTMwNkVcdTMwQUFcdTMwRDZcdTMwQjhcdTMwQTdcdTMwQUZcdTMwQzhcdTMwN0VcdTMwNUZcdTMwNkZcdTY0Q0RcdTRGNUNcdTMwNkZcdTVCOUZcdTg4QzVcdTMwNjdcdTMwQjVcdTMwRERcdTMwRkNcdTMwQzhcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIgCi1OT19EQVRBX0FMTE9XRURfRVJSID0gXHUzMEM3XHUzMEZDXHUzMEJGXHUzMDkyXHUzMEI1XHUzMEREXHUzMEZDXHUzMEM4XHUzMDU3XHUzMDY2XHUzMDQ0XHUzMDZBXHUzMDQ0XHUzMENFXHUzMEZDXHUzMEM5XHUzMDZCXHU1QkZFXHUzMDU3XHUzMDY2XHUzMEM3XHUzMEZDXHUzMEJGXHUzMDRDXHU2MzA3XHU1QjlBXHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5XHUzMDAyCi1OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIgPSBcdTU5MDlcdTY2RjRcdTMwNENcdThBMzFcdTUzRUZcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwNkFcdTMwNDRcdTMwQUFcdTMwRDZcdTMwQjhcdTMwQTdcdTMwQUZcdTMwQzhcdTMwOTJcdTU5MDlcdTY2RjRcdTMwNTdcdTMwODhcdTMwNDZcdTMwNjhcdTMwNTdcdTMwN0VcdTMwNTdcdTMwNUZcdTMwMDIKLVNZTlRBWF9FUlIgPSBcdTcxMjFcdTUyQjlcdTMwN0VcdTMwNUZcdTMwNkZcdTRFMERcdTZCNjNcdTMwNkFcdTY1ODdcdTVCNTdcdTUyMTdcdTMwNENcdTYzMDdcdTVCOUFcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTlcdTMwMDIgCi1WQUxJREFUSU9OX0VSUiA9IGluc2VydEJlZm9yZVx1MzAwMXJlbW92ZUNoaWxkXHUzMDZBXHUzMDY5XHUzMDZFXHUzMEUxXHUzMEJEXHUzMEMzXHUzMEM5XHUzMDkyXHU1NDdDXHUzMDczXHU1MUZBXHUzMDU5XHUzMDY4XHUzMDAxXHUzMEM5XHUzMEFEXHUzMEU1XHUzMEUxXHUzMEYzXHUzMEM4XHUzMDZFXHU2OUNCXHU2NTg3XHUzMDZCXHU5NUEyXHUzMDU3XHUzMDY2XHUzMENFXHUzMEZDXHUzMEM5XHUzMDRDXHU3MTIxXHU1MkI5XHUzMDZCXHUzMDZBXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCi1XUk9OR19ET0NVTUVOVF9FUlIgPSBcdTMwQ0VcdTMwRkNcdTMwQzlcdTMwNENcdTMwMDFcdTMwNURcdTMwNkVcdTMwQ0VcdTMwRkNcdTMwQzlcdTMwOTJcdTRGNUNcdTYyMTBcdTMwNTdcdTMwNUZcdTMwODJcdTMwNkVcdTMwNjhcdTMwNkZcdTc1NzBcdTMwNkFcdTMwOEJcdTMwQzlcdTMwQURcdTMwRTVcdTMwRTFcdTMwRjNcdTMwQzhcdTMwNjdcdTRGN0ZcdTc1MjhcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTlcdTMwMDIKLVRZUEVfTUlTTUFUQ0hfRVJSID0gXHUzMDUzXHUzMDZFXHUzMEQxXHUzMEU5XHUzMEUxXHUzMEZDXHUzMEJGXHU1NDBEXHUzMDZFXHU1MDI0XHUzMEJGXHUzMEE0XHUzMEQ3XHUzMDZGXHUzMDAxXHU0RTg4XHU2MEYzXHUzMDU3XHUzMDVGXHU1MDI0XHUzMEJGXHUzMEE0XHUzMEQ3XHUzMDY4XHU0RTkyXHU2M0RCXHU2MDI3XHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyIAotIAotI2Vycm9yIG1lc3NhZ2VzIG9yIGV4Y2VwdGlvbnMKLUZFQVRVUkVfTk9UX1NVUFBPUlRFRCA9IFx1MzBEMVx1MzBFOVx1MzBFMVx1MzBGQ1x1MzBCRnswfVx1MzA2Rlx1OEE4RFx1OEI1OFx1MzA1NVx1MzA4Q1x1MzA3RVx1MzA1OVx1MzA0Q1x1MzAwMVx1MzBFQVx1MzBBRlx1MzBBOFx1MzBCOVx1MzBDOFx1MzA1N1x1MzA1Rlx1NTAyNFx1MzA2Rlx1OEEyRFx1NUI5QVx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotRkVBVFVSRV9OT1RfRk9VTkQgPSBcdTMwRDFcdTMwRTlcdTMwRTFcdTMwRkNcdTMwQkZ7MH1cdTMwNkZcdThBOERcdThCNThcdTMwNTVcdTMwOENcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLVNUUklOR19UT09fTE9ORyAgID0gXHU3RDUwXHU2NzlDXHUzMDZFXHU2NTg3XHU1QjU3XHU1MjE3XHUzMDZGXHU5NTc3XHUzMDU5XHUzMDRFXHUzMDhCXHUzMDVGXHUzMDgxXHUzMDAxRE9NU3RyaW5nXHUzMDZCXHU1M0NFXHUzMDdFXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzOiAnJ3swfScnXHUzMDAyCi0KLSNET00gTGV2ZWwgMyBET01FcnJvciBjb2Rlcwotd2YtaW52YWxpZC1jaGFyYWN0ZXIgPSAgezF9XHUzMENFXHUzMEZDXHUzMEM5XHUzMDZFXHUzMEM2XHUzMEFEXHUzMEI5XHUzMEM4ezB9XHUzMDZCXHU3MTIxXHU1MkI5XHUzMDZBWE1MXHU2NTg3XHU1QjU3XHUzMDRDXHU1NDJCXHUzMDdFXHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5XHUzMDAyCi13Zi1pbnZhbGlkLWNoYXJhY3Rlci1pbi1ub2RlLW5hbWUgPSB7MX1cdTMwNjhcdTMwNDRcdTMwNDZcdTU0MERcdTUyNERcdTMwNkV7MH1cdTMwQ0VcdTMwRkNcdTMwQzlcdTMwNkJcdTcxMjFcdTUyQjlcdTMwNkFYTUxcdTY1ODdcdTVCNTdcdTMwNENcdTU0MkJcdTMwN0VcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTlcdTMwMDIKLWNkYXRhLXNlY3Rpb25zLXNwbGl0dGVkID0gIENEQVRBXHUzMEJCXHUzMEFGXHUzMEI3XHUzMEU3XHUzMEYzXHUzMDZCQ0RBVEFcdTMwQkJcdTMwQUZcdTMwQjdcdTMwRTdcdTMwRjNcdTdENDJcdTRFODZcdTMwREVcdTMwRkNcdTMwQUJcdTMwRkMnJ11dPicnXHUzMDRDXHU1NDJCXHUzMDdFXHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5Ci1kb2N0eXBlLW5vdC1hbGxvd2VkID0gRE9DVFlQRVx1NUJBM1x1OEEwMFx1MzA2Rlx1OEEzMVx1NTNFRlx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotdW5zdXBwb3J0ZWQtZW5jb2RpbmcgPSBcdTMwQThcdTMwRjNcdTMwQjNcdTMwRkNcdTMwQzdcdTMwQTNcdTMwRjNcdTMwQjB7MH1cdTMwNkZcdTMwQjVcdTMwRERcdTMwRkNcdTMwQzhcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLQotI0Vycm9yIGNvZGVzIHVzZWQgaW4gRE9NIE5vcm1hbGl6ZXIKLUludmFsaWRYTUxDaGFySW5ET00gPSBcdTZCNjNcdTg5OEZcdTUzMTZcdTRFMkRcdTMwNkJET01cdTUxODVcdTMwNkJcdTcxMjFcdTUyQjlcdTMwNkFYTUxcdTY1ODdcdTVCNTcoVW5pY29kZTogMHh7MH0pXHUzMDRDXHU4OThCXHUzMDY0XHUzMDRCXHUzMDhBXHUzMDdFXHUzMDU3XHUzMDVGXHUzMDAyCi1VbmRlY2xhcmVkRW50UmVmSW5BdHRyVmFsdWUgPSBcdTVDNUVcdTYwMjciezB9Ilx1MzA2RVx1NTAyNCJ7MX0iXHUzMDY3XHU1M0MyXHU3MTY3XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDhCXHUzMEE4XHUzMEYzXHUzMEM2XHUzMEEzXHUzMEM2XHUzMEEzXHUzMDRDXHU1QkEzXHU4QTAwXHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi1OdWxsTG9jYWxFbGVtZW50TmFtZSA9IFx1ODk4MVx1N0QyMHswfVx1MzA2RVx1MzBDRFx1MzBGQ1x1MzBFMFx1MzBCOVx1MzBEQVx1MzBGQ1x1MzBCOVx1MzA2RVx1NkI2M1x1ODk4Rlx1NTMxNlx1NEUyRFx1MzA2Qm51bGxcdTMwNkVcdTMwRURcdTMwRkNcdTMwQUJcdTMwRUJcdTU0MERcdTMwNENcdTg5OEJcdTMwNjRcdTMwNEJcdTMwOEFcdTMwN0VcdTMwNTdcdTMwNUZcdTMwMDIKLU51bGxMb2NhbEF0dHJOYW1lID0gXHU1QzVFXHU2MDI3ezB9XHUzMDZFXHUzMENEXHUzMEZDXHUzMEUwXHUzMEI5XHUzMERBXHUzMEZDXHUzMEI5XHUzMDZFXHU2QjYzXHU4OThGXHU1MzE2XHU0RTJEXHUzMDZCbnVsbFx1MzA2RVx1MzBFRFx1MzBGQ1x1MzBBQlx1MzBFQlx1NTQwRFx1MzA0Q1x1ODk4Qlx1MzA2NFx1MzA0Qlx1MzA4QVx1MzA3RVx1MzA1N1x1MzA1Rlx1MzAwMgotCi0jRXJyb3IgY29kZXMgdXNlZCBpbiBET01QYXJzZXIKLUludmFsaWREb2N1bWVudENsYXNzTmFtZSA9IERPTVx1MzBDNFx1MzBFQVx1MzBGQ1x1MzA2RVx1NjlDQlx1N0JDOVx1MzA2Qlx1NEY3Rlx1NzUyOFx1MzA1NVx1MzA4Q1x1MzA4Qlx1MzBDOVx1MzBBRFx1MzBFNVx1MzBFMVx1MzBGM1x1MzBDOFx1MzBGQlx1MzBENVx1MzBBMVx1MzBBRlx1MzBDOFx1MzBFQSJ7MH0iXHUzMDZFXHUzMEFGXHUzMEU5XHUzMEI5XHU1NDBEXHUzMDRDXHUzMEJGXHUzMEE0XHUzMEQ3b3JnLnczYy5kb20uRG9jdW1lbnRcdTMwNjdcdTMwNkZcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLU1pc3NpbmdEb2N1bWVudENsYXNzTmFtZSA9IERPTVx1MzBDNFx1MzBFQVx1MzBGQ1x1MzA2RVx1NjlDQlx1N0JDOVx1MzA2Qlx1NEY3Rlx1NzUyOFx1MzA1NVx1MzA4Q1x1MzA4Qlx1MzBDOVx1MzBBRFx1MzBFNVx1MzBFMVx1MzBGM1x1MzBDOFx1MzBGQlx1MzBENVx1MzBBMVx1MzBBRlx1MzBDOFx1MzBFQSJ7MH0iXHUzMDZFXHUzMEFGXHUzMEU5XHUzMEI5XHU1NDBEXHUzMDRDXHU4OThCXHUzMDY0XHUzMDRCXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDY3XHUzMDU3XHUzMDVGXHUzMDAyCi1DYW5ub3RDcmVhdGVEb2N1bWVudENsYXNzID0gInswfSJcdTMwNjhcdTMwNDRcdTMwNDZcdTU0MERcdTUyNERcdTMwNkVcdTMwQUZcdTMwRTlcdTMwQjlcdTMwOTJvcmcudzNjLmRvbS5Eb2N1bWVudFx1MzA2OFx1MzA1N1x1MzA2Nlx1NjlDQlx1N0JDOVx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzA2N1x1MzA1N1x1MzA1Rlx1MzAwMgotCi0jIEVycm9yIGNvZGVzIHVzZWQgYnkgSkFYUCBEb2N1bWVudEJ1aWxkZXIKLWpheHAtb3JkZXItbm90LXN1cHBvcnRlZCA9IFx1MzBEN1x1MzBFRFx1MzBEMVx1MzBDNlx1MzBBMycnezF9JydcdTMwOTJcdThBMkRcdTVCOUFcdTMwNTlcdTMwOEJcdTUyNERcdTMwNkJcdTMwRDdcdTMwRURcdTMwRDFcdTMwQzZcdTMwQTMnJ3swfScnXHUzMDkyXHU4QTJEXHU1QjlBXHUzMDU5XHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCi1qYXhwLW51bGwtaW5wdXQtc291cmNlID0gXHU2MzA3XHU1QjlBXHUzMDU3XHUzMDVGXHUzMEJEXHUzMEZDXHUzMEI5XHUzMDZGbnVsbFx1MzA2Qlx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotCi0jUmFuZ2VzCi1CQURfQk9VTkRBUllQT0lOVFNfRVJSID0gUmFuZ2VcdTMwNkVcdTU4ODNcdTc1NENcdTcwQjlcdTMwNENcdTcyNzlcdTVCOUFcdTMwNkVcdTg5ODFcdTRFRjZcdTMwOTJcdTZFODBcdTMwNUZcdTMwNTdcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLUlOVkFMSURfTk9ERV9UWVBFX0VSUiA9IFJhbmdlXHUzMDZFXHU1ODgzXHU3NTRDXHU3MEI5XHUzMDZFXHUzMEIzXHUzMEYzXHUzMEM2XHUzMENBXHUzMDRDXHUzMDAxXHU3MTIxXHU1MkI5XHUzMDZBXHUzMEJGXHUzMEE0XHUzMEQ3XHUzMDZFXHUzMENFXHUzMEZDXHUzMEM5XHUzMDdFXHUzMDVGXHUzMDZGXHU3MTIxXHU1MkI5XHUzMDZBXHUzMEJGXHUzMEE0XHUzMEQ3XHUzMDZFXHU3OTU2XHU1MTQ4XHUzMDkyXHU2MzAxXHUzMDY0XHUzMENFXHUzMEZDXHUzMEM5XHUzMDZCXHU4QTJEXHU1QjlBXHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5XHUzMDAyCi0KLQotI0V2ZW50cwotVU5TUEVDSUZJRURfRVZFTlRfVFlQRV9FUlIgPSBcdTMwRTFcdTMwQkRcdTMwQzNcdTMwQzlcdTMwOTJcdTU0N0NcdTMwNzNcdTUxRkFcdTMwNTlcdTUyNERcdTMwNkVcdTMwQTRcdTMwRDlcdTMwRjNcdTMwQzhcdTMwNkVcdTUyMURcdTY3MUZcdTUzMTZcdTMwNjdcdTMwMDFcdTMwQTRcdTMwRDlcdTMwRjNcdTMwQzhcdTMwNkVcdTMwQkZcdTMwQTRcdTMwRDdcdTMwNENcdTYzMDdcdTVCOUFcdTMwNTVcdTMwOENcdTMwN0VcdTMwNUJcdTMwOTNcdTMwNjdcdTMwNTdcdTMwNUZcdTMwMDIgCi0KLQotamF4cC1zY2hlbWEtc3VwcG9ydD1zZXRTY2hlbWFcdTMwRTFcdTMwQkRcdTMwQzNcdTMwQzlcdTMwNEFcdTMwODhcdTMwNzNzY2hlbWFMYW5ndWFnZVx1MzBEN1x1MzBFRFx1MzBEMVx1MzBDNlx1MzBBM1x1MzA2RVx1NEUyMVx1NjVCOVx1MzA0Q1x1NEY3Rlx1NzUyOFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OQotCi1qYXhwX2ZlYXR1cmVfbm90X3N1cHBvcnRlZD1cdTZBNUZcdTgwRkQiezB9Ilx1MzA2Rlx1MzBCNVx1MzBERFx1MzBGQ1x1MzBDOFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvRE9NTWVzc2FnZXNfa28ucHJvcGVydGllcyBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL0RPTU1lc3NhZ2VzX2tvLnByb3BlcnRpZXMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDU5Y2I4ZjQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvRE9NTWVzc2FnZXNfa28ucHJvcGVydGllcworKysgL2Rldi9udWxsCkBAIC0xLDY5ICswLDAgQEAKLSMgVGhpcyBmaWxlIHN0b3JlcyBsb2NhbGl6ZWQgbWVzc2FnZXMgZm9yIHRoZSBYZXJjZXMKLSMgRE9NIGltcGxlbWVudGF0aW9uLgotIwotIyBUaGUgbWVzc2FnZXMgYXJlIGFycmFuZ2VkIGluIGtleSBhbmQgdmFsdWUgdHVwbGVzIGluIGEgTGlzdFJlc291cmNlQnVuZGxlLgotIwotCi1CYWRNZXNzYWdlS2V5ID0gXHVCQTU0XHVDMkRDXHVDOUMwIFx1RDBBNFx1QzVEMCBcdUQ1NzRcdUIyRjlcdUQ1NThcdUIyOTQgXHVDNjI0XHVCOTU4IFx1QkE1NFx1QzJEQ1x1QzlDMFx1Qjk3QyBcdUNDM0VcdUM3NDQgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4KLUZvcm1hdEZhaWxlZCA9IFx1QjJFNFx1Qzc0QyBcdUJBNTRcdUMyRENcdUM5QzBcdUM3NTggXHVENjE1XHVDMkREXHVDNzQ0IFx1QzlDMFx1QzgxNVx1RDU1OFx1QjI5NCBcdUM5MTEgXHVCMEI0XHVCRDgwIFx1QzYyNFx1Qjk1OFx1QUMwMCBcdUJDMUNcdUMwRERcdUQ1ODhcdUMyQjVcdUIyQzhcdUIyRTQuXG4gIAotCi0jIERPTSBDb3JlCi0KLSMgZXhjZXB0aW9uIGNvZGVzCi1ET01TVFJJTkdfU0laRV9FUlIgPSBcdUQxNERcdUMyQTRcdUQyQjhcdUM3NTggXHVDOUMwXHVDODE1XHVCNDFDIFx1QkM5NFx1QzcwNFx1QUMwMCBET01TdHJpbmdcdUM1RDAgXHVCOURFXHVDOUMwIFx1QzU0QVx1QzJCNVx1QjJDOFx1QjJFNC4gCi1ISUVSQVJDSFlfUkVRVUVTVF9FUlIgID0gXHVDMEJEXHVDNzg1XHVDNzc0IFx1RDVDOFx1QzZBOVx1QjQxOFx1QzlDMCBcdUM1NEFcdUIyOTQgXHVCMTc4XHVCNERDXHVCOTdDIFx1QzBCRFx1Qzc4NVx1RDU1OFx1QjgyNFx1QUNFMCBcdUMyRENcdUIzQzRcdUQ1ODhcdUMyQjVcdUIyQzhcdUIyRTQuIAotSU5ERVhfU0laRV9FUlIgPSBcdUM3NzhcdUIzNzFcdUMyQTQgXHVCNjEwXHVCMjk0IFx1RDA2Q1x1QUUzMFx1QUMwMCBcdUM3NENcdUMyMThcdUM3NzRcdUFDNzBcdUIwOTggXHVENUM4XHVDNkE5XHVCNDE4XHVCMjk0IFx1QUMxMlx1QkNGNFx1QjJFNCBcdUQwN0RcdUIyQzhcdUIyRTQuCi1JTlVTRV9BVFRSSUJVVEVfRVJSID0gXHVCMkU0XHVCOTc4IFx1QzcwNFx1Q0U1OFx1QzVEMFx1QzExQyBcdUM3NzRcdUJCRjggXHVDMEFDXHVDNkE5IFx1QzkxMVx1Qzc3OCBcdUMxOERcdUMxMzFcdUM3NDQgXHVDRDk0XHVBQzAwXHVENTU4XHVCODI0XHVBQ0UwIFx1QzJEQ1x1QjNDNFx1RDU4OFx1QzJCNVx1QjJDOFx1QjJFNC4KLUlOVkFMSURfQUNDRVNTX0VSUiAgPSBcdUFFMzBcdUJDRjggXHVBQzFEXHVDQ0I0XHVDNUQwXHVDMTFDIFx1QjlFNFx1QUMxQ1x1QkNDMFx1QzIxOCBcdUI2MTBcdUIyOTQgXHVDNzkxXHVDNUM1XHVDNzQ0IFx1QzlDMFx1QzZEMFx1RDU1OFx1QzlDMCBcdUM1NEFcdUMyQjVcdUIyQzhcdUIyRTQuIAotSU5WQUxJRF9DSEFSQUNURVJfRVJSID0gXHVCRDgwXHVDODAxXHVENTY5XHVENTU4XHVBQzcwXHVCMDk4IFx1Qzc5OFx1QkFCQlx1QjQxQyBYTUwgXHVCQjM4XHVDNzkwXHVBQzAwIFx1QzlDMFx1QzgxNVx1QjQxOFx1QzVDOFx1QzJCNVx1QjJDOFx1QjJFNC4gCi1JTlZBTElEX01PRElGSUNBVElPTl9FUlIgPSAgXHVBRTMwXHVCQ0Y4IFx1QUMxRFx1Q0NCNFx1Qzc1OCBcdUM3MjBcdUQ2MTVcdUM3NDQgXHVDMjE4XHVDODE1XHVENTU4XHVCODI0XHVBQ0UwIFx1QzJEQ1x1QjNDNFx1RDU4OFx1QzJCNVx1QjJDOFx1QjJFNC4gCi1JTlZBTElEX1NUQVRFX0VSUiA9IFx1QzBBQ1x1QzZBOVx1RDU2MCBcdUMyMTggXHVDNUM2XHVBQzcwXHVCMDk4IFx1QjM1NCBcdUM3NzRcdUMwQzEgXHVDMEFDXHVDNkE5XHVDNzc0IFx1RDVDOFx1QUMwMFx1QjQxOFx1QzlDMCBcdUM1NEFcdUM3NDAgXHVBQzFEXHVDQ0I0XHVCOTdDIFx1QzBBQ1x1QzZBOVx1RDU1OFx1QjgyNFx1QUNFMCBcdUMyRENcdUIzQzRcdUQ1ODhcdUMyQjVcdUIyQzhcdUIyRTQuIAotTkFNRVNQQUNFX0VSUiA9IFx1QjEyNFx1Qzc4NFx1QzJBNFx1RDM5OFx1Qzc3NFx1QzJBNFx1QzVEMCBcdUIzMDBcdUQ1NzQgXHVDNjJDXHVCQzE0XHVCOTc0XHVDOUMwIFx1QzU0QVx1Qzc0MCBcdUJDMjlcdUMyRERcdUM3M0NcdUI4NUMgXHVBQzFEXHVDQ0I0XHVCOTdDIFx1QzBERFx1QzEzMVx1RDU1OFx1QUM3MFx1QjA5OCBcdUJDQzBcdUFDQkRcdUQ1NThcdUI4MjRcdUFDRTAgXHVDMkRDXHVCM0M0XHVENTg4XHVDMkI1XHVCMkM4XHVCMkU0LgotTk9UX0ZPVU5EX0VSUiA9IFx1Qzg3NFx1QzdBQ1x1RDU1OFx1QzlDMCBcdUM1NEFcdUIyOTQgXHVDRUU4XHVEMTREXHVDMkE0XHVEMkI4XHVDNzU4IFx1QjE3OFx1QjREQ1x1Qjk3QyBcdUNDMzhcdUM4NzBcdUQ1NThcdUI4MjRcdUFDRTAgXHVDMkRDXHVCM0M0XHVENTg4XHVDMkI1XHVCMkM4XHVCMkU0LgotTk9UX1NVUFBPUlRFRF9FUlIgPSBcdUFENkNcdUQ2MDRcdUM1RDBcdUMxMUMgXHVDNjk0XHVDQ0FEXHVCNDFDIFx1QzcyMFx1RDYxNVx1Qzc1OCBcdUFDMURcdUNDQjQgXHVCNjEwXHVCMjk0IFx1Qzc5MVx1QzVDNVx1Qzc0NCBcdUM5QzBcdUM2RDBcdUQ1NThcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0LiAKLU5PX0RBVEFfQUxMT1dFRF9FUlIgPSBcdUIzNzBcdUM3NzRcdUQxMzBcdUI5N0MgXHVDOUMwXHVDNkQwXHVENTU4XHVDOUMwIFx1QzU0QVx1QjI5NCBcdUIxNzhcdUI0RENcdUM1RDAgXHVCMzAwXHVENTc0IFx1QjM3MFx1Qzc3NFx1RDEzMFx1QUMwMCBcdUM5QzBcdUM4MTVcdUI0MThcdUM1QzhcdUMyQjVcdUIyQzhcdUIyRTQuCi1OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIgPSBcdUMyMThcdUM4MTVcdUM3NzQgXHVENUM4XHVDNkE5XHVCNDE4XHVDOUMwIFx1QzU0QVx1QjI5NCBcdUFDMURcdUNDQjRcdUI5N0MgXHVDMjE4XHVDODE1XHVENTU4XHVCODI0XHVBQ0UwIFx1QzJEQ1x1QjNDNFx1RDU4OFx1QzJCNVx1QjJDOFx1QjJFNC4KLVNZTlRBWF9FUlIgPSBcdUJEODBcdUM4MDFcdUQ1NjlcdUQ1NThcdUFDNzBcdUIwOTggXHVDNzk4XHVCQUJCXHVCNDFDIFx1QkIzOFx1Qzc5MFx1QzVGNFx1Qzc3NCBcdUM5QzBcdUM4MTVcdUI0MThcdUM1QzhcdUMyQjVcdUIyQzhcdUIyRTQuIAotVkFMSURBVElPTl9FUlIgPSBpbnNlcnRCZWZvcmUgXHVCNjEwXHVCMjk0IHJlbW92ZUNoaWxkXHVDNjQwIFx1QUMxOVx1Qzc0MCBcdUJBNTRcdUMxOENcdUI0RENcdUI5N0MgXHVENjM4XHVDRDlDXHVENTU4XHVCQTc0IFx1QjE3OFx1QjREQ1x1QUMwMCBcdUJCMzhcdUMxMUMgXHVCQjM4XHVCQzk1XHVDNUQwIFx1QjMwMFx1RDU3NCBcdUJEODBcdUM4MDFcdUQ1NjlcdUQ1NzRcdUM5RDFcdUIyQzhcdUIyRTQuCi1XUk9OR19ET0NVTUVOVF9FUlIgPSBcdUIxNzhcdUI0RENcdUFDMDAgXHVDMEREXHVDMTMxXHVCNDFDIFx1QkIzOFx1QzExQ1x1QUMwMCBcdUM1NDRcdUIyQ0MgXHVCMkU0XHVCOTc4IFx1QkIzOFx1QzExQ1x1QzVEMFx1QzExQyBcdUMwQUNcdUM2QTlcdUI0MThcdUM1QzhcdUMyQjVcdUIyQzhcdUIyRTQuCi1UWVBFX01JU01BVENIX0VSUiA9IFx1Qzc3NCBcdUI5RTRcdUFDMUNcdUJDQzBcdUMyMTggXHVDNzc0XHVCOTg0XHVDNUQwIFx1QjMwMFx1RDU1QyBcdUFDMTIgXHVDNzIwXHVENjE1XHVDNzc0IFx1RDU0NFx1QzY5NFx1RDU1QyBcdUFDMTIgXHVDNzIwXHVENjE1XHVBQ0ZDIFx1RDYzOFx1RDY1OFx1QjQxOFx1QzlDMCBcdUM1NEFcdUMyQjVcdUIyQzhcdUIyRTQuIAotIAotI2Vycm9yIG1lc3NhZ2VzIG9yIGV4Y2VwdGlvbnMKLUZFQVRVUkVfTk9UX1NVUFBPUlRFRCA9IHswfSBcdUI5RTRcdUFDMUNcdUJDQzBcdUMyMThcdUFDMDAgXHVDNzc4XHVDMkREXHVCNDE4XHVDNUM4XHVDOUMwXHVCOUNDIFx1QzY5NFx1Q0NBRFx1QjQxQyBcdUFDMTJcdUM3NDQgXHVDMTI0XHVDODE1XHVENTYwIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuCi1GRUFUVVJFX05PVF9GT1VORCA9IHswfSBcdUI5RTRcdUFDMUNcdUJDQzBcdUMyMThcdUI5N0MgXHVDNzc4XHVDMkREXHVENTYwIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuCi1TVFJJTkdfVE9PX0xPTkcgICA9IFx1QUNCMFx1QUNGQyBcdUJCMzhcdUM3OTBcdUM1RjRcdUM3NzQgXHVCMTA4XHVCQjM0IFx1Q0VFNFx1QzExQyBET01TdHJpbmdcdUM1RDAgXHVCOURFXHVDOUMwIFx1QzU0QVx1Qzc0QzogJyd7MH0nJy4KLQotI0RPTSBMZXZlbCAzIERPTUVycm9yIGNvZGVzCi13Zi1pbnZhbGlkLWNoYXJhY3RlciA9ICB7MX0gXHVCMTc4XHVCNERDXHVDNzU4IHswfSBcdUQxNERcdUMyQTRcdUQyQjhcdUM1RDAgXHVCRDgwXHVDODAxXHVENTY5XHVENTVDIFhNTCBcdUJCMzhcdUM3OTBcdUFDMDAgXHVEM0VDXHVENTY4XHVCNDE4XHVDNUI0IFx1Qzc4OFx1QzJCNVx1QjJDOFx1QjJFNC4KLXdmLWludmFsaWQtY2hhcmFjdGVyLWluLW5vZGUtbmFtZSA9IFx1Qzc3NFx1Qjk4NFx1Qzc3NCB7MX1cdUM3NzggezB9IFx1QjE3OFx1QjREQ1x1QzVEMCBcdUJEODBcdUM4MDFcdUQ1NjlcdUQ1NUMgWE1MIFx1QkIzOFx1Qzc5MFx1QUMwMCBcdUQzRUNcdUQ1NjhcdUI0MThcdUM1QjQgXHVDNzg4XHVDMkI1XHVCMkM4XHVCMkU0LgotY2RhdGEtc2VjdGlvbnMtc3BsaXR0ZWQgPSAgQ0RBVEEgXHVDMTM5XHVDMTU4IFx1Qzg4NVx1QjhDQyBcdUQ0NUNcdUMyRENcdUM3OTAgJyddXT4nJ1x1Qjk3QyBcdUQzRUNcdUQ1NjhcdUQ1NThcdUIyOTQgQ0RBVEEgXHVDMTM5XHVDMTU4Ci1kb2N0eXBlLW5vdC1hbGxvd2VkID0gRE9DVFlQRSBcdUMxMjBcdUM1QjhcdUM3NDAgXHVENUM4XHVDNkE5XHVCNDE4XHVDOUMwIFx1QzU0QVx1QzJCNVx1QjJDOFx1QjJFNC4KLXVuc3VwcG9ydGVkLWVuY29kaW5nID0gezB9IFx1Qzc3OFx1Q0Y1NFx1QjUyOVx1Qzc0MCBcdUM5QzBcdUM2RDBcdUI0MThcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0LgotCi0jRXJyb3IgY29kZXMgdXNlZCBpbiBET00gTm9ybWFsaXplcgotSW52YWxpZFhNTENoYXJJbkRPTSA9IFx1QzgxNVx1QUREQ1x1RDY1NCBcdUM5MTEgRE9NXHVDNUQwXHVDMTFDIFx1QkQ4MFx1QzgwMVx1RDU2OVx1RDU1QyBYTUwgXHVCQjM4XHVDNzkwKFx1QzcyMFx1QjJDOFx1Q0Y1NFx1QjREQzogMHh7MH0pXHVBQzAwIFx1QkMxQ1x1QUNBQ1x1QjQxOFx1QzVDOFx1QzJCNVx1QjJDOFx1QjJFNC4KLVVuZGVjbGFyZWRFbnRSZWZJbkF0dHJWYWx1ZSA9IFx1QzE4RFx1QzEzMSAiezB9IiBcdUFDMTIgInsxfSJcdUM3NzQoXHVBQzAwKSBcdUMxMjBcdUM1QjhcdUI0MThcdUM5QzAgXHVDNTRBXHVDNzQwIFx1QzVENFx1RDJGMFx1RDJGMFx1Qjk3QyBcdUNDMzhcdUM4NzBcdUQ1ODhcdUMyQjVcdUIyQzhcdUIyRTQuCi1OdWxsTG9jYWxFbGVtZW50TmFtZSA9IHswfSBcdUM2OTRcdUMxOENcdUM3NTggXHVCMTI0XHVDNzg0XHVDMkE0XHVEMzk4XHVDNzc0XHVDMkE0IFx1QzgxNVx1QUREQ1x1RDY1NCBcdUM5MTEgXHVCMTEwIFx1Qjg1Q1x1Q0VFQyBcdUM3NzRcdUI5ODRcdUM3NzQgXHVCQzFDXHVBQ0FDXHVCNDE4XHVDNUM4XHVDMkI1XHVCMkM4XHVCMkU0LgotTnVsbExvY2FsQXR0ck5hbWUgPSB7MH0gXHVDMThEXHVDMTMxXHVDNzU4IFx1QjEyNFx1Qzc4NFx1QzJBNFx1RDM5OFx1Qzc3NFx1QzJBNCBcdUM4MTVcdUFERENcdUQ2NTQgXHVDOTExIFx1QjExMCBcdUI4NUNcdUNFRUMgXHVDNzc0XHVCOTg0XHVDNzc0IFx1QkMxQ1x1QUNBQ1x1QjQxOFx1QzVDOFx1QzJCNVx1QjJDOFx1QjJFNC4KLQotI0Vycm9yIGNvZGVzIHVzZWQgaW4gRE9NUGFyc2VyCi1JbnZhbGlkRG9jdW1lbnRDbGFzc05hbWUgPSBET00gXHVEMkI4XHVCOUFDIFx1QzBERFx1QzEzMVx1QzVEMCBcdUMwQUNcdUM2QTlcdUI0MUMgXHVCQjM4XHVDMTFDIFx1RDMyOVx1RDFBMFx1QjlBQyAiezB9Ilx1Qzc1OCBcdUQwNzRcdUI3OThcdUMyQTQgXHVDNzc0XHVCOTg0XHVDNzQwIG9yZy53M2MuZG9tLkRvY3VtZW50IFx1QzcyMFx1RDYxNVx1Qzc3NCBcdUM1NDRcdUIyRDlcdUIyQzhcdUIyRTQuCi1NaXNzaW5nRG9jdW1lbnRDbGFzc05hbWUgPSBET00gXHVEMkI4XHVCOUFDIFx1QzBERFx1QzEzMVx1QzVEMCBcdUMwQUNcdUM2QTlcdUI0MUMgXHVCQjM4XHVDMTFDIFx1RDMyOVx1RDFBMFx1QjlBQyAiezB9Ilx1Qzc1OCBcdUQwNzRcdUI3OThcdUMyQTQgXHVDNzc0XHVCOTg0XHVDNzQ0IFx1Q0MzRVx1Qzc0NCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LgotQ2Fubm90Q3JlYXRlRG9jdW1lbnRDbGFzcyA9IFx1Qzc3NFx1Qjk4NFx1Qzc3NCAiezB9Ilx1Qzc3OCBcdUQwNzRcdUI3OThcdUMyQTRcdUI5N0Mgb3JnLnczYy5kb20uRG9jdW1lbnRcdUI4NUMgXHVDMEREXHVDMTMxXHVENTYwIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuCi0KLSMgRXJyb3IgY29kZXMgdXNlZCBieSBKQVhQIERvY3VtZW50QnVpbGRlcgotamF4cC1vcmRlci1ub3Qtc3VwcG9ydGVkID0gJyd7MX0nJyBcdUMxOERcdUMxMzFcdUM3NDQgXHVDMTI0XHVDODE1XHVENTU4XHVBRTMwIFx1QzgwNFx1QzVEMCAnJ3swfScnIFx1QzE4RFx1QzEzMVx1Qzc0NCBcdUMxMjRcdUM4MTVcdUQ1NzRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotamF4cC1udWxsLWlucHV0LXNvdXJjZSA9IFx1QzlDMFx1QzgxNVx1QjQxQyBcdUMxOENcdUMyQTRcdUIyOTQgXHVCMTEwXHVDNzdDIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuCi0KLSNSYW5nZXMKLUJBRF9CT1VOREFSWVBPSU5UU19FUlIgPSBcdUJDOTRcdUM3MDRcdUM3NTggXHVBQ0JEXHVBQ0M0IFx1QzlDMFx1QzgxMFx1Qzc3NCBcdUQyQjlcdUM4MTUgXHVDNjk0XHVBRDZDIFx1QzBBQ1x1RDU2RFx1Qzc0NCBcdUNEQTlcdUM4NzFcdUQ1NThcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0LgotSU5WQUxJRF9OT0RFX1RZUEVfRVJSID0gXHVCQzk0XHVDNzA0XHVDNzU4IFx1QUNCRFx1QUNDNCBcdUM5QzBcdUM4MTAgXHVDRUU4XHVEMTRDXHVDNzc0XHVCMTA4XHVBQzAwIFx1QkQ4MFx1QzgwMVx1RDU2OVx1RDU1QyBcdUM3MjBcdUQ2MTVcdUM3NTggXHVCMTc4XHVCNERDIFx1QjYxMFx1QjI5NCBcdUJEODBcdUM4MDFcdUQ1NjlcdUQ1NUMgXHVDNzIwXHVENjE1XHVDNzU4IFx1Qzg3MFx1QzBDMVx1Qzc0NCBcdUFDMDBcdUM5QzQgXHVCMTc4XHVCNERDXHVCODVDIFx1QzEyNFx1QzgxNVx1QjQxOFx1QUNFMCBcdUM3ODhcdUMyQjVcdUIyQzhcdUIyRTQuCi0KLQotI0V2ZW50cwotVU5TUEVDSUZJRURfRVZFTlRfVFlQRV9FUlIgPSBcdUJBNTRcdUMxOENcdUI0RENcdUFDMDAgXHVENjM4XHVDRDlDXHVCNDE4XHVBRTMwIFx1QzgwNFx1QzVEMCBcdUM3NzRcdUJDQTRcdUQyQjhcdUI5N0MgXHVDRDA4XHVBRTMwXHVENjU0XHVENTU4XHVDNUVDIFx1Qzc3NFx1QkNBNFx1RDJCOCBcdUM3MjBcdUQ2MTVcdUM3NzQgXHVDOUMwXHVDODE1XHVCNDE4XHVDOUMwIFx1QzU0QVx1QzU1OFx1QzJCNVx1QjJDOFx1QjJFNC4gCi0KLQotamF4cC1zY2hlbWEtc3VwcG9ydD1zZXRTY2hlbWEgXHVCQTU0XHVDMThDXHVCNERDXHVDNjQwIHNjaGVtYUxhbmd1YWdlIFx1QzE4RFx1QzEzMVx1Qzc3NCBcdUJBQThcdUI0NTAgXHVDMEFDXHVDNkE5XHVCNDE4XHVDNUM4XHVDMkI1XHVCMkM4XHVCMkU0LgotCi1qYXhwX2ZlYXR1cmVfbm90X3N1cHBvcnRlZD0iezB9IiBcdUFFMzBcdUIyQTVcdUM3NDAgXHVDOUMwXHVDNkQwXHVCNDE4XHVDOUMwIFx1QzU0QVx1QzJCNVx1QjJDOFx1QjJFNC4KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL0RPTU1lc3NhZ2VzX3B0X0JSLnByb3BlcnRpZXMgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9ET01NZXNzYWdlc19wdF9CUi5wcm9wZXJ0aWVzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1ZmNjNTY2Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL0RPTU1lc3NhZ2VzX3B0X0JSLnByb3BlcnRpZXMKKysrIC9kZXYvbnVsbApAQCAtMSw2OSArMCwwIEBACi0jIFRoaXMgZmlsZSBzdG9yZXMgbG9jYWxpemVkIG1lc3NhZ2VzIGZvciB0aGUgWGVyY2VzCi0jIERPTSBpbXBsZW1lbnRhdGlvbi4KLSMKLSMgVGhlIG1lc3NhZ2VzIGFyZSBhcnJhbmdlZCBpbiBrZXkgYW5kIHZhbHVlIHR1cGxlcyBpbiBhIExpc3RSZXNvdXJjZUJ1bmRsZS4KLSMKLQotQmFkTWVzc2FnZUtleSA9IE5cdTAwRTNvIGZvaSBwb3NzXHUwMEVEdmVsIGVuY29udHJhciBhIG1lbnNhZ2VtIGRlIGVycm8gY29ycmVzcG9uZGVudGUgXHUwMEUwIGNoYXZlIGRhIG1lbnNhZ2VtLgotRm9ybWF0RmFpbGVkID0gT2NvcnJldSB1bSBlcnJvIGludGVybm8gYW8gZm9ybWF0YXIgYSBtZW5zYWdlbSBhIHNlZ3VpcjpcbiAgCi0KLSMgRE9NIENvcmUKLQotIyBleGNlcHRpb24gY29kZXMKLURPTVNUUklOR19TSVpFX0VSUiA9IEEgZmFpeGEgZGUgdGV4dG8gZXNwZWNpZmljYWRhIG5cdTAwRTNvIHNlIGFqdXN0YSBhIERPTVN0cmluZy4gCi1ISUVSQVJDSFlfUkVRVUVTVF9FUlIgID0gSG91dmUgdW1hIHRlbnRhdGl2YSBkZSBpbnNlcmlyIHVtIG5cdTAwRjMgb25kZSBuXHUwMEUzbyBlcmEgcGVybWl0aWRvLiAKLUlOREVYX1NJWkVfRVJSID0gTyBcdTAwRURuZGljZSBvdSBvIHRhbWFuaG8gXHUwMEU5IG5lZ2F0aXZvIG91IG1haW9yIHF1ZSBvIHZhbG9yIHBlcm1pdGlkby4KLUlOVVNFX0FUVFJJQlVURV9FUlIgPSBIb3V2ZSB1bWEgdGVudGF0aXZhIGRlIGFkaWNpb25hciB1bSBhdHJpYnV0byBxdWUgalx1MDBFMSBlc3RcdTAwRTEgc2VuZG8gdXNhZG8gZW0gb3V0cm8gbHVnYXIuCi1JTlZBTElEX0FDQ0VTU19FUlIgID0gVW0gcGFyXHUwMEUybWV0cm8gb3UgdW1hIG9wZXJhXHUwMEU3XHUwMEUzbyBuXHUwMEUzbyBzdXBvcnRhZG8gcGVsbyBvYmpldG8gc3ViamFjZW50ZS4gCi1JTlZBTElEX0NIQVJBQ1RFUl9FUlIgPSBVbSBjYXJhY3RlcmUgWE1MIGludlx1MDBFMWxpZG8gb3UgaWxlZ2FsIGZvaSBlc3BlY2lmaWNhZG8uIAotSU5WQUxJRF9NT0RJRklDQVRJT05fRVJSID0gIEhvdXZlIHVtYSB0ZW50YXRpdmEgZGUgbW9kaWZpY2FyIG8gdGlwbyBkZSBvYmpldG8gc3ViamFjZW50ZS4gCi1JTlZBTElEX1NUQVRFX0VSUiA9IEhvdXZlIHVtYSB0ZW50YXRpdmEgZGUgdXNhciB1bSBvYmpldG8gcXVlIG5cdTAwRTNvIFx1MDBFOSBtYWlzIHV0aWxpelx1MDBFMXZlbC4gCi1OQU1FU1BBQ0VfRVJSID0gSG91dmUgdW1hIHRlbnRhdGl2YSBkZSBjcmlhciBvdSBhbHRlcmFyIHVtIG9iamV0byBkZSB1bWEgZm9ybWEgaW5jb3JyZXRhIGVtIHJlbGFcdTAwRTdcdTAwRTNvIGFvcyBuYW1lc3BhY2VzLgotTk9UX0ZPVU5EX0VSUiA9IEhvdXZlIHVtYSB0ZW50YXRpdmEgZGUgZmF6ZXIgcmVmZXJcdTAwRUFuY2lhIGEgdW0gblx1MDBGMyBlbSB1bSBjb250ZXh0byBubyBxdWFsIGVsZSBuXHUwMEUzbyBleGlzdGUuCi1OT1RfU1VQUE9SVEVEX0VSUiA9IEEgaW1wbGVtZW50YVx1MDBFN1x1MDBFM28gblx1MDBFM28gc3Vwb3J0YSBvIHRpcG8gc29saWNpdGFkbyBkZSBvYmpldG8gb3Ugb3BlcmFcdTAwRTdcdTAwRTNvLiAKLU5PX0RBVEFfQUxMT1dFRF9FUlIgPSBPcyBkYWRvcyBmb3JhbSBlc3BlY2lmaWNhZG9zIHBhcmEgdW0gblx1MDBGMyBxdWUgblx1MDBFM28gc3Vwb3J0YSBkYWRvcy4KLU5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiA9IEZvaSBmZWl0YSB1bWEgdGVudGF0aXZhIGRlIG1vZGlmaWNhciB1bSBvYmpldG8gbm8gcXVhbCBuXHUwMEUzbyBzXHUwMEUzbyBwZXJtaXRpZGFzIG1vZGlmaWNhXHUwMEU3XHUwMEY1ZXMuCi1TWU5UQVhfRVJSID0gVW1hIHN0cmluZyBpbnZcdTAwRTFsaWRhIG91IGlsZWdhbCBmb2kgZXNwZWNpZmljYWRhLiAKLVZBTElEQVRJT05fRVJSID0gVW1hIGNoYW1hZGEgcGFyYSB1bSBtXHUwMEU5dG9kbyBjb21vIGluc2VydEJlZm9yZSBvdSByZW1vdmVDaGlsZCB0b3JuYXJpYSBvIE5cdTAwRjMgaW52XHUwMEUxbGlkbyBlbSByZWxhXHUwMEU3XHUwMEUzbyBcdTAwRTAgZ3JhbVx1MDBFMXRpY2EgZG8gZG9jdW1lbnRvLgotV1JPTkdfRE9DVU1FTlRfRVJSID0gVW0gblx1MDBGMyBcdTAwRTkgdXNhZG8gZW0gdW0gZG9jdW1lbnRvIGRpZmVyZW50ZSBkYXF1ZWxlIHF1ZSBmb2kgY3JpYWRvLgotVFlQRV9NSVNNQVRDSF9FUlIgPSBPIHRpcG8gZGUgdmFsb3IgZG8gbm9tZSBkZXN0ZSBwYXJcdTAwRTJtZXRybyBcdTAwRTkgaW5jb21wYXRcdTAwRUR2ZWwgY29tIG8gdGlwbyBkZSB2YWxvciBlc3BlcmFkby4gCi0gCi0jZXJyb3IgbWVzc2FnZXMgb3IgZXhjZXB0aW9ucwotRkVBVFVSRV9OT1RfU1VQUE9SVEVEID0gTyBwYXJcdTAwRTJtZXRybyB7MH0gXHUwMEU5IHJlY29uaGVjaWRvLCBtYXMgbyB2YWxvciBzb2xpY2l0YWRvIG5cdTAwRTNvIHBvZGUgc2VyIGRlZmluaWRvLgotRkVBVFVSRV9OT1RfRk9VTkQgPSBPIHBhclx1MDBFMm1ldHJvIHswfSBuXHUwMEUzbyBcdTAwRTkgcmVjb25oZWNpZG8uCi1TVFJJTkdfVE9PX0xPTkcgICA9IEEgc3RyaW5nIHJlc3VsdGFudGUgXHUwMEU5IG11aXRvIGxvbmdhIHBhcmEgc2UgYWp1c3RhciBhIHVtYSBET01TdHJpbmc6ICcnezB9JycuCi0KLSNET00gTGV2ZWwgMyBET01FcnJvciBjb2Rlcwotd2YtaW52YWxpZC1jaGFyYWN0ZXIgPSAgTyB0ZXh0byB7MH0gZG8gblx1MDBGMyB7MX0gY29udFx1MDBFOW0gY2FyYWN0ZXJlcyBYTUwgaW52XHUwMEUxbGlkb3MuCi13Zi1pbnZhbGlkLWNoYXJhY3Rlci1pbi1ub2RlLW5hbWUgPSBPIG5cdTAwRjMgezB9IGNvbSBvIG5vbWUgezF9IGNvbnRcdTAwRTltIGNhcmFjdGVyZXMgWE1MIGludlx1MDBFMWxpZG9zLgotY2RhdGEtc2VjdGlvbnMtc3BsaXR0ZWQgPSAgU2VcdTAwRTdcdTAwRjVlcyBDREFUQSBxdWUgY29udFx1MDBFQW0gbyBtYXJjYWRvciAnJ11dPicnIGRlIHRlcm1pbmFcdTAwRTdcdTAwRTNvIGRlIHNlXHUwMEU3XHUwMEUzbyBDREFUQQotZG9jdHlwZS1ub3QtYWxsb3dlZCA9IEEgZGVjbGFyYVx1MDBFN1x1MDBFM28gRE9DVFlQRSBuXHUwMEUzbyBcdTAwRTkgcGVybWl0aWRhLgotdW5zdXBwb3J0ZWQtZW5jb2RpbmcgPSBBIGNvZGlmaWNhXHUwMEU3XHUwMEUzbyB7MH0gblx1MDBFM28gXHUwMEU5IHN1cG9ydGFkYS4KLQotI0Vycm9yIGNvZGVzIHVzZWQgaW4gRE9NIE5vcm1hbGl6ZXIKLUludmFsaWRYTUxDaGFySW5ET00gPSBVbSBjYXJhY3RlcmUgWE1MIGludlx1MDBFMWxpZG8gKFVuaWNvZGU6IDB4IHswfSkgZm9pIGVuY29udHJhZG8gbm8gRE9NIGR1cmFudGUgYSBub3JtYWxpemFcdTAwRTdcdTAwRTNvLgotVW5kZWNsYXJlZEVudFJlZkluQXR0clZhbHVlID0gTyBhdHJpYnV0byAiezB9IiB2YWxvciAiezF9IiBtZW5jaW9ub3UgdW1hIGVudGlkYWRlIHF1ZSBuXHUwMEUzbyBmb2kgZGVjbGFyYWRhLgotTnVsbExvY2FsRWxlbWVudE5hbWUgPSBVbSBub21lIGRlIGxvY2FsIG51bG8gZm9pIGVuY29udHJhZG8gZHVyYW50ZSBhIG5vcm1hbGl6YVx1MDBFN1x1MDBFM28gZG8gbmFtZXNwYWNlIGRvIGVsZW1lbnRvIHswfS4KLU51bGxMb2NhbEF0dHJOYW1lID0gVW0gbm9tZSBkZSBsb2NhbCBudWxvIGZvaSBlbmNvbnRyYWRvIGR1cmFudGUgYSBub3JtYWxpemFcdTAwRTdcdTAwRTNvIGRvIG5hbWVzcGFjZSBkbyBhdHJpYnV0byB7MH0uCi0KLSNFcnJvciBjb2RlcyB1c2VkIGluIERPTVBhcnNlcgotSW52YWxpZERvY3VtZW50Q2xhc3NOYW1lID0gTyBub21lIGRhIGNsYXNzZSBkbyBmYWN0b3J5IGRvIGRvY3VtZW50byAiezB9IiB1c2FkbyBwYXJhIGNvbnN0cnVpciBhIFx1MDBFMXJ2b3JlIERPTSBuXHUwMEUzbyBcdTAwRTkgZG8gdGlwbyBvcmcudzNjLmRvbS5Eb2N1bWVudC4KLU1pc3NpbmdEb2N1bWVudENsYXNzTmFtZSA9IE5cdTAwRTNvIGZvaSBwb3NzXHUwMEVEdmVsIGVuY29udHJhciBvIG5vbWUgZGEgY2xhc3NlIGRvIGZhY3RvcnkgZG8gZG9jdW1lbnRvICJ7MH0iIHVzYWRvIHBhcmEgY29uc3RydWlyIGEgXHUwMEUxcnZvcmUgRE9NLgotQ2Fubm90Q3JlYXRlRG9jdW1lbnRDbGFzcyA9IE5cdTAwRTNvIGZvaSBwb3NzXHUwMEVEdmVsIGNvbnN0cnVpciBhIGNsYXNzZSBjb20gbyBub21lICJ7MH0iIGNvbW8gdW0gb3JnLnczYy5kb20uRG9jdW1lbnQuCi0KLSMgRXJyb3IgY29kZXMgdXNlZCBieSBKQVhQIERvY3VtZW50QnVpbGRlcgotamF4cC1vcmRlci1ub3Qtc3VwcG9ydGVkID0gQSBwcm9wcmllZGFkZSAnJ3swfScnIGRldmUgc2VyIGVzdGFiZWxlY2lkYSBhbnRlcyBkYSBkZWZpbmlcdTAwRTdcdTAwRTNvIGRhIHByb3ByaWVkYWRlICcnezF9JycuCi1qYXhwLW51bGwtaW5wdXQtc291cmNlID0gQSBvcmlnZW0gZXNwZWNpZmljYWRhIG5cdTAwRTNvIHBvZGUgc2VyIG51bGEuCi0KLSNSYW5nZXMKLUJBRF9CT1VOREFSWVBPSU5UU19FUlIgPSBPcyBwb250b3MtbGltaXRlIGRlIHVtYSBGYWl4YSBuXHUwMEUzbyBhdGVuZGVtIGFvcyByZXF1aXNpdG9zIGVzcGVjXHUwMEVEZmljb3MuCi1JTlZBTElEX05PREVfVFlQRV9FUlIgPSBPIGNvbnRhaW5lciBkZSB1bSBwb250by1saW1pdGUgZGUgdW1hIEZhaXhhIGVzdFx1MDBFMSBzZW5kbyBkZWZpbmlkbyBwYXJhIHVtIG5cdTAwRjMgZGUgdW0gdGlwbyBpbnZcdTAwRTFsaWRvIG91IHVtIG5cdTAwRjMgY29tIHVtIGFuY2VzdHJhbCBkZSB1bSB0aXBvIGludlx1MDBFMWxpZG8uCi0KLQotI0V2ZW50cwotVU5TUEVDSUZJRURfRVZFTlRfVFlQRV9FUlIgPSBPIHRpcG8gZGUgRXZlbnRvIG5cdTAwRTNvIGZvaSBlc3BlY2lmaWNhZG8gcG9yIG1laW8gZGEgaW5pY2lhbGl6YVx1MDBFN1x1MDBFM28gZG8gZXZlbnRvIGFudGVzIGRvIG1cdTAwRTl0b2RvIHNlciBjaGFtYWRvLiAKLQotCi1qYXhwLXNjaGVtYS1zdXBwb3J0PU8gbVx1MDBFOXRvZG8gc2V0U2NoZW1hIGUgYSBwcm9wcmllZGFkZSBzY2hlbWFMYW5ndWFnZSBmb3JhbSB1c2Fkb3MKLQotamF4cF9mZWF0dXJlX25vdF9zdXBwb3J0ZWQ9TyByZWN1cnNvICJ7MH0iIG5cdTAwRTNvIFx1MDBFOSBzdXBvcnRhZG8uCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9ET01NZXNzYWdlc19zdi5wcm9wZXJ0aWVzIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvRE9NTWVzc2FnZXNfc3YucHJvcGVydGllcwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYzNlYzc3OS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9ET01NZXNzYWdlc19zdi5wcm9wZXJ0aWVzCisrKyAvZGV2L251bGwKQEAgLTEsNjkgKzAsMCBAQAotIyBUaGlzIGZpbGUgc3RvcmVzIGxvY2FsaXplZCBtZXNzYWdlcyBmb3IgdGhlIFhlcmNlcwotIyBET00gaW1wbGVtZW50YXRpb24uCi0jCi0jIFRoZSBtZXNzYWdlcyBhcmUgYXJyYW5nZWQgaW4ga2V5IGFuZCB2YWx1ZSB0dXBsZXMgaW4gYSBMaXN0UmVzb3VyY2VCdW5kbGUuCi0jCi0KLUJhZE1lc3NhZ2VLZXkgPSBIaXR0YXIgaW50ZSBmZWxtZWRkZWxhbmRldCBzb20gbW90c3ZhcmFyIG1lZGRlbGFuZGVueWNrZWxuLgotRm9ybWF0RmFpbGVkID0gRXR0IGludGVybnQgZmVsIGludHJcdTAwRTRmZmFkZSB2aWQgZm9ybWF0ZXJpbmcgYXYgZlx1MDBGNmxqYW5kZSBtZWRkZWxhbmRlOlxuICAKLQotIyBET00gQ29yZQotCi0jIGV4Y2VwdGlvbiBjb2RlcwotRE9NU1RSSU5HX1NJWkVfRVJSID0gQW5naXZldCB0ZXh0aW50ZXJ2YWxsIHJ5bXMgaW50ZSBpIERPTVN0cmluZy4gCi1ISUVSQVJDSFlfUkVRVUVTVF9FUlIgID0gRXR0IGZcdTAwRjZyc1x1MDBGNmsgZ2pvcmRlcyBhdHQgaW5mb2dhIG5vZCBkXHUwMEU0ciBkZXQgaW50ZSBcdTAwRTRyIHRpbGxcdTAwRTV0ZXQuIAotSU5ERVhfU0laRV9FUlIgPSBJbmRleCBlbGxlciBzdG9ybGVrIFx1MDBFNHIgbmVnYXRpdnQgdGFsIGVsbGVyIHN0XHUwMEY2cnJlIFx1MDBFNG4gdGlsbFx1MDBFNXRldCB2XHUwMEU0cmRlLgotSU5VU0VfQVRUUklCVVRFX0VSUiA9IEV0dCBmXHUwMEY2cnNcdTAwRjZrIGdcdTAwRjZycyBhdHQgbFx1MDBFNGdnYSB0aWxsIGV0dCBhdHRyaWJ1dCBzb20gcmVkYW4gYW52XHUwMEU0bmRzIHBcdTAwRTUgYW5uYW4gcGxhdHMuCi1JTlZBTElEX0FDQ0VTU19FUlIgID0gRW4gcGFyYW1ldGVyIGVsbGVyIGVuIFx1MDBFNXRnXHUwMEU0cmQgc3RcdTAwRjZkcyBpbnRlIGF2IHVuZGVybGlnZ2FuZGUgb2JqZWt0LiAKLUlOVkFMSURfQ0hBUkFDVEVSX0VSUiA9IEV0dCBvZ2lsdGlndCBlbGxlciBvdGlsbFx1MDBFNXRldCBYTUwtdGVja2VuIGhhciBhbmdldHRzLiAKLUlOVkFMSURfTU9ESUZJQ0FUSU9OX0VSUiA9ICBFdHQgZlx1MDBGNnJzXHUwMEY2ayBnXHUwMEY2cnMgYXR0IFx1MDBFNG5kcmEgdHlwIGF2IHVuZGVybGlnZ2FuZGUgb2JqZWt0LiAKLUlOVkFMSURfU1RBVEVfRVJSID0gRXR0IGZcdTAwRjZyc1x1MDBGNmsgZ1x1MDBGNnJzIGF0dCBhbnZcdTAwRTRuZGEgZXR0IG9iamVrdCBzb20gaW50ZSAobFx1MDBFNG5ncmUpIFx1MDBFNHIgYW52XHUwMEU0bmRiYXIuIAotTkFNRVNQQUNFX0VSUiA9IEV0dCBmXHUwMEY2cnNcdTAwRjZrIGdcdTAwRjZycyBhdHQgc2thcGEgZWxsZXIgXHUwMEU0bmRyYSBldHQgb2JqZWt0IHBcdTAwRTUgZXR0IGZlbGFrdGlndCBzXHUwMEU0dHQgYXZzZWVuZGUgbmFtbnJ5bWRlci4KLU5PVF9GT1VORF9FUlIgPSBFdHQgZlx1MDBGNnJzXHUwMEY2ayBnXHUwMEY2cnMgYXR0IHNrYXBhIHJlZmVyZW5zIHRpbGwgZW4gbm9kIGkgZXR0IHNhbW1hbmhhbmcgZFx1MDBFNHIgZGVuIGludGUgZmlubnMuCi1OT1RfU1VQUE9SVEVEX0VSUiA9IEltcGxlbWVudGVyaW5nZW4gc2FrbmFyIHN0XHUwMEY2ZCBmXHUwMEY2ciBiZWdcdTAwRTRyZCB0eXAgYXYgb2JqZWt0IGVsbGVyIFx1MDBFNXRnXHUwMEU0cmQuIAotTk9fREFUQV9BTExPV0VEX0VSUiA9IERhdGEgYW5nZXMgZlx1MDBGNnIgZW4gbm9kIHNvbSBpbnRlIHN0XHUwMEY2ZGVyIGRhdGEuCi1OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIgPSBGXHUwMEY2cnNcdTAwRjZrZXIgXHUwMEU0bmRyYSBldHQgb2JqZWt0IGRcdTAwRTRyIFx1MDBFNG5kcmluZ2FyIGludGUgXHUwMEU0ciB0aWxsXHUwMEU1dG5hLgotU1lOVEFYX0VSUiA9IEVuIG9naWx0aWcgZWxsZXIgb3RpbGxcdTAwRTV0ZW4gc3RyXHUwMEU0bmcgYW5nZXMuIAotVkFMSURBVElPTl9FUlIgPSBFdHQgYW5yb3AgdGlsbCBlbiBtZXRvZCBzb20gaW5zZXJ0QmVmb3JlIGVsbGVyIHJlbW92ZUNoaWxkIHNrdWxsZSBnXHUwMEY2cmEgbm9kZW4gb2dpbHRpZyBtZWQgYWt0dWVsbCBkb2t1bWVudGdyYW1tYXRpay4KLVdST05HX0RPQ1VNRU5UX0VSUiA9IEVuIG5vZCBhbnZcdTAwRTRuZHMgaSBldHQgYW5uYXQgZG9rdW1lbnQgXHUwMEU0biBkZXQgc29tIHNrYXBhZGUgbm9kZW4uCi1UWVBFX01JU01BVENIX0VSUiA9IFZcdTAwRTRyZGV0eXBlbiBmXHUwMEY2ciBkZXR0YSBwYXJhbWV0ZXJuYW1uIFx1MDBFNHIgaW5rb21wYXRpYmVsdCBtZWQgZlx1MDBGNnJ2XHUwMEU0bnRhZCB2XHUwMEU0cmRldHlwLiAKLSAKLSNlcnJvciBtZXNzYWdlcyBvciBleGNlcHRpb25zCi1GRUFUVVJFX05PVF9TVVBQT1JURUQgPSBQYXJhbWV0ZXJuIHswfSBrYW4gaWRlbnRpZmllcmFzLCBtZW4gZGV0IGJlZ1x1MDBFNHJkYSB2XHUwMEU0cmRldCBrYW4gaW50ZSBhbmdlcy4KLUZFQVRVUkVfTk9UX0ZPVU5EID0gUGFyYW1ldGVybiB7MH0ga2FuIGludGUgaWRlbnRpZmllcmFzLgotU1RSSU5HX1RPT19MT05HICAgPSBSZXN1bHRhdHN0clx1MDBFNG5nZW4gXHUwMEU0ciBmXHUwMEY2ciBsXHUwMEU1bmcgb2NoIHJ5bXMgaW50ZSBpIERPTVN0cmluZzogJyd7MH0nJy4KLQotI0RPTSBMZXZlbCAzIERPTUVycm9yIGNvZGVzCi13Zi1pbnZhbGlkLWNoYXJhY3RlciA9ICBUZXh0ZW4gezB9IGkgbm9kZW4gezF9IGlubmVoXHUwMEU1bGxlciBvZ2lsdGlnYSBYTUwtdGVja2VuLgotd2YtaW52YWxpZC1jaGFyYWN0ZXItaW4tbm9kZS1uYW1lID0gTm9kZW4gezB9IG1lZCBuYW1uZXQgezF9IGlubmVoXHUwMEU1bGxlciBvZ2lsdGlnYSBYTUwtdGVja2VuLgotY2RhdGEtc2VjdGlvbnMtc3BsaXR0ZWQgPSAgQ0RBVEEtc2VrdGlvbmVyIGlubmVoXHUwMEU1bGxlciBhdnNsdXRuaW5nc21hcmtcdTAwRjZyZW4gJyddXT4nJwotZG9jdHlwZS1ub3QtYWxsb3dlZCA9IERPQ1RZUEUtZGVrbGFyYXRpb24gXHUwMEU0ciBpbnRlIHRpbGxcdTAwRTV0ZXQuCi11bnN1cHBvcnRlZC1lbmNvZGluZyA9IEtvZG5pbmdlbiB7MH0gc3RcdTAwRjZkcyBpbnRlLgotCi0jRXJyb3IgY29kZXMgdXNlZCBpbiBET00gTm9ybWFsaXplcgotSW52YWxpZFhNTENoYXJJbkRPTSA9IEV0dCBvZ2lsdGlndCBYTUwtdGVja2VuIChVbmljb2RlOiAweHswfSkgaGl0dGFkZXMgaSBET00gdmlkIG5vcm1hbGlzZXJpbmcuCi1VbmRlY2xhcmVkRW50UmVmSW5BdHRyVmFsdWUgPSBBdHRyaWJ1dGV0ICJ7MH0iIG1lZCB2XHUwMEU0cmRldCAiezF9IiByZWZlcmVyYWRlIGVuIGVuaGV0IHNvbSBpbnRlIGhhciBkZWtsYXJlcmF0cy4KLU51bGxMb2NhbEVsZW1lbnROYW1lID0gRXR0IGxva2FsdCBuYW1uIG1lZCBudWxsLXZcdTAwRTRyZGUgcFx1MDBFNXRyXHUwMEU0ZmZhZGVzIHZpZCBuYW1ucnltZHNub3JtYWxpc2VyaW5nIGF2IGVsZW1lbnRldCB7MH0uCi1OdWxsTG9jYWxBdHRyTmFtZSA9IEV0dCBsb2thbHQgbmFtbiBtZWQgbnVsbC12XHUwMEU0cmRlIHBcdTAwRTV0clx1MDBFNGZmYWRlcyB2aWQgbmFtbnJ5bWRzbm9ybWFsaXNlcmluZyBhdiBhdHRyaWJ1dGV0IHswfS4KLQotI0Vycm9yIGNvZGVzIHVzZWQgaW4gRE9NUGFyc2VyCi1JbnZhbGlkRG9jdW1lbnRDbGFzc05hbWUgPSBLbGFzc25hbW5ldCBwXHUwMEU1IGRva3VtZW50ZmFicmlrICJ7MH0iIHNvbSBhbnZcdTAwRTRuZHMgdmlkIGtvbnN0cnVrdGlvbiBhdiBET00tdHJcdTAwRTRkZXQgXHUwMEU0ciBpbnRlIHR5cCBvcmcudzNjLmRvbS5Eb2N1bWVudC4KLU1pc3NpbmdEb2N1bWVudENsYXNzTmFtZSA9IEhpdHRhZGUgaW50ZSBrbGFzc25hbW5ldCBwXHUwMEU1IGRva3VtZW50ZmFicmlrICJ7MH0iIHNvbSBhbnZcdTAwRTRuZHMgdmlkIGtvbnN0cnVrdGlvbiBhdiBET00tdHJcdTAwRTRkZXQuCi1DYW5ub3RDcmVhdGVEb2N1bWVudENsYXNzID0gS2xhc3NlbiAiezB9IiBrdW5kZSBpbnRlIGtvbnN0cnVlcmFzIHNvbSBvcmcudzNjLmRvbS5Eb2N1bWVudC4KLQotIyBFcnJvciBjb2RlcyB1c2VkIGJ5IEpBWFAgRG9jdW1lbnRCdWlsZGVyCi1qYXhwLW9yZGVyLW5vdC1zdXBwb3J0ZWQgPSBFZ2Vuc2thcGVuICcnezB9JycgbVx1MDBFNXN0ZSBhbmdlcyBmXHUwMEY2cmUgaW5zdFx1MDBFNGxsbmluZyBhdiBlZ2Vuc2thcGVuICcnezF9JycuCi1qYXhwLW51bGwtaW5wdXQtc291cmNlID0gQW5naXZlbiBrXHUwMEU0bGxhIGZcdTAwRTVyIGludGUgdmFyYSBudWxsLgotCi0jUmFuZ2VzCi1CQURfQk9VTkRBUllQT0lOVFNfRVJSID0gR3JcdTAwRTRuc3B1bmt0ZXJuYSBpIGV0dCBpbnRlcnZhbGwgdXBwZnlsbGVyIGludGUgZGUgc3BlY2lmaWthIGtyYXZlbi4KLUlOVkFMSURfTk9ERV9UWVBFX0VSUiA9IEVuIGNvbnRhaW5lciBtZWQgZ3JcdTAwRTRuc3B1bmt0c2ludGVydmFsbCBhbmdlcyB0aWxsIG5vZCBhdiBvZ2lsdGlnIHR5cCBlbGxlciBub2QgbWVkIFx1MDBGNnZlcm9yZG5hZCBhdiBvZ2lsdGlnIHR5cC4KLQotCi0jRXZlbnRzCi1VTlNQRUNJRklFRF9FVkVOVF9UWVBFX0VSUiA9IEhcdTAwRTRuZGVsc2V0eXAgc3BlY2lmaWNlcmFkZXMgaW50ZSBuXHUwMEU0ciBoXHUwMEU0bmRlbHNlbiBpbml0aWVyYWRlcyBmXHUwMEY2cmUgbWV0b2RhbnJvcC4gCi0KLQotamF4cC1zY2hlbWEtc3VwcG9ydD1CXHUwMEU1ZGUgc2V0U2NoZW1hLW1ldG9kZW4gb2NoIHNjaGVtYUxhbmd1YWdlLWVnZW5za2FwZW4gYW52XHUwMEU0bmRzCi0KLWpheHBfZmVhdHVyZV9ub3Rfc3VwcG9ydGVkPUZ1bmt0aW9uZW4gInswfSIgc3RcdTAwRjZkcyBpbnRlLgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvRE9NTWVzc2FnZXNfemhfQ04ucHJvcGVydGllcyBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL0RPTU1lc3NhZ2VzX3poX0NOLnByb3BlcnRpZXMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDIyNGM3YTYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvRE9NTWVzc2FnZXNfemhfQ04ucHJvcGVydGllcworKysgL2Rldi9udWxsCkBAIC0xLDY5ICswLDAgQEAKLSMgVGhpcyBmaWxlIHN0b3JlcyBsb2NhbGl6ZWQgbWVzc2FnZXMgZm9yIHRoZSBYZXJjZXMKLSMgRE9NIGltcGxlbWVudGF0aW9uLgotIwotIyBUaGUgbWVzc2FnZXMgYXJlIGFycmFuZ2VkIGluIGtleSBhbmQgdmFsdWUgdHVwbGVzIGluIGEgTGlzdFJlc291cmNlQnVuZGxlLgotIwotCi1CYWRNZXNzYWdlS2V5ID0gXHU2MjdFXHU0RTBEXHU1MjMwXHU0RTBFXHU2RDg4XHU2MDZGXHU1MTczXHU5NTJFXHU1QjU3XHU1QkY5XHU1RTk0XHU3Njg0XHU5NTE5XHU4QkVGXHU2RDg4XHU2MDZGXHUzMDAyCi1Gb3JtYXRGYWlsZWQgPSBcdThCQkVcdTdGNkVcdTRFRTVcdTRFMEJcdTZEODhcdTYwNkZcdTc2ODRcdTY4M0NcdTVGMEZcdTY1RjZcdTUxRkFcdTczQjBcdTUxODVcdTkwRThcdTk1MTlcdThCRUY6XG4gIAotCi0jIERPTSBDb3JlCi0KLSMgZXhjZXB0aW9uIGNvZGVzCi1ET01TVFJJTkdfU0laRV9FUlIgPSBcdTYzMDdcdTVCOUFcdTc2ODRcdTY1ODdcdTY3MkNcdTgzMDNcdTU2RjRcdTRFMERcdTkwMDJcdTU0MDggRE9NU3RyaW5nXHUzMDAyCi1ISUVSQVJDSFlfUkVRVUVTVF9FUlIgID0gXHU1QzFEXHU4QkQ1XHU1NzI4XHU0RTBEXHU1MTQxXHU4QkI4XHU3Njg0XHU0RjREXHU3RjZFXHU2M0QyXHU1MTY1XHU4MjgyXHU3MEI5XHUzMDAyCi1JTkRFWF9TSVpFX0VSUiA9IFx1N0QyMlx1NUYxNVx1NjIxNlx1NTkyN1x1NUMwRlx1NEUzQVx1OEQxRlx1NTAzQywgXHU2MjE2XHU4MDA1XHU1OTI3XHU0RThFXHU1MTQxXHU4QkI4XHU3Njg0XHU1MDNDXHUzMDAyCi1JTlVTRV9BVFRSSUJVVEVfRVJSID0gXHU1QzFEXHU4QkQ1XHU2REZCXHU1MkEwXHU1REYyXHU1NzI4XHU1MTc2XHU0RUQ2XHU0RjREXHU3RjZFXHU0RjdGXHU3NTI4XHU3Njg0XHU1QzVFXHU2MDI3XHUzMDAyCi1JTlZBTElEX0FDQ0VTU19FUlIgID0gXHU1N0ZBXHU3ODQwXHU1QkY5XHU4QzYxXHU0RTBEXHU2NTJGXHU2MzAxXHU1M0MyXHU2NTcwXHU2MjE2XHU2NENEXHU0RjVDXHUzMDAyCi1JTlZBTElEX0NIQVJBQ1RFUl9FUlIgPSBcdTYzMDdcdTVCOUFcdTc2ODQgWE1MIFx1NUI1N1x1N0IyNlx1NjVFMFx1NjU0OFx1NjIxNlx1OTc1RVx1NkNENVx1MzAwMgotSU5WQUxJRF9NT0RJRklDQVRJT05fRVJSID0gIFx1NUMxRFx1OEJENVx1NEZFRVx1NjUzOVx1NTdGQVx1Nzg0MFx1NUJGOVx1OEM2MVx1NzY4NFx1N0M3Qlx1NTc4Qlx1MzAwMgotSU5WQUxJRF9TVEFURV9FUlIgPSBcdTVDMURcdThCRDVcdTRGN0ZcdTc1MjhcdTY1RTBcdTZDRDVcdTRGN0ZcdTc1MjhcdTYyMTZcdTRFMERcdTUxOERcdTUzRUZcdTc1MjhcdTc2ODRcdTVCRjlcdThDNjFcdTMwMDIKLU5BTUVTUEFDRV9FUlIgPSBcdTVDMURcdThCRDVcdTRFRTVcdTk1MTlcdThCRUZcdTc2ODRcdTU0MERcdTc5RjBcdTdBN0FcdTk1RjRcdTUyMUJcdTVFRkFcdTYyMTZcdTY2RjRcdTY1MzlcdTY1QjlcdTVGMEZcdTY3NjVcdTUyMUJcdTVFRkFcdTYyMTZcdTY2RjRcdTY1MzlcdTVCRjlcdThDNjFcdTMwMDIKLU5PVF9GT1VORF9FUlIgPSBcdTVDMURcdThCRDVcdTU3MjhcdTRFMEFcdTRFMEJcdTY1ODdcdTRFMkRcdTVGMTVcdTc1MjhcdTRFMERcdTVCNThcdTU3MjhcdTc2ODRcdTgyODJcdTcwQjlcdTMwMDIKLU5PVF9TVVBQT1JURURfRVJSID0gXHU1QjlFXHU3M0IwXHU0RTBEXHU2NTJGXHU2MzAxXHU4QkY3XHU2QzQyXHU3Njg0XHU1QkY5XHU4QzYxXHU2MjE2XHU2NENEXHU0RjVDXHU3QzdCXHU1NzhCXHUzMDAyCi1OT19EQVRBX0FMTE9XRURfRVJSID0gXHU1REYyXHU0RTNBXHU0RTBEXHU2NTJGXHU2MzAxXHU2NTcwXHU2MzZFXHU3Njg0XHU4MjgyXHU3MEI5XHU2MzA3XHU1QjlBXHU2NTcwXHU2MzZFXHUzMDAyCi1OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIgPSBcdTVDMURcdThCRDVcdTRGRUVcdTY1MzlcdTRFMERcdTUxNDFcdThCQjhcdTRGRUVcdTY1MzlcdTc2ODRcdTVCRjlcdThDNjFcdTMwMDIKLVNZTlRBWF9FUlIgPSBcdTYzMDdcdTVCOUFcdTc2ODRcdTVCNTdcdTdCMjZcdTRFMzJcdTY1RTBcdTY1NDhcdTYyMTZcdTk3NUVcdTZDRDVcdTMwMDIKLVZBTElEQVRJT05fRVJSID0gXHU1QzMxXHU2NTg3XHU2ODYzXHU4QkVEXHU2Q0Q1XHU2NUI5XHU5NzYyXHU4MDBDXHU4QTAwLCBcdThDMDNcdTc1MjggaW5zZXJ0QmVmb3JlIFx1NjIxNiByZW1vdmVDaGlsZCBcdTdCNDlcdTY1QjlcdTZDRDVcdTVDMDZcdTVCRkNcdTgxRjQgTm9kZSBcdTY1RTBcdTY1NDhcdTMwMDIKLVdST05HX0RPQ1VNRU5UX0VSUiA9IFx1NEY3Rlx1NzUyOFx1ODI4Mlx1NzBCOVx1NzY4NFx1NjU4N1x1Njg2M1x1NEUwRVx1NTIxQlx1NUVGQVx1ODI4Mlx1NzBCOVx1NzY4NFx1NjU4N1x1Njg2M1x1NEUwRFx1NzZGOFx1NTQwQ1x1MzAwMgotVFlQRV9NSVNNQVRDSF9FUlIgPSBcdTZCNjRcdTUzQzJcdTY1NzBcdTU0MERcdTc5RjBcdTc2ODRcdTUwM0NcdTdDN0JcdTU3OEJcdTRFMEVcdTk4ODRcdTY3MUZcdTc2ODRcdTUwM0NcdTdDN0JcdTU3OEJcdTRFMERcdTUxN0NcdTVCQjlcdTMwMDIKLSAKLSNlcnJvciBtZXNzYWdlcyBvciBleGNlcHRpb25zCi1GRUFUVVJFX05PVF9TVVBQT1JURUQgPSBcdTVERjJcdThCQzZcdTUyMkJcdTUzQzJcdTY1NzB7MH0sIFx1NEY0Nlx1NjVFMFx1NkNENVx1OEJCRVx1N0Y2RVx1OEJGN1x1NkM0Mlx1NzY4NFx1NTAzQ1x1MzAwMgotRkVBVFVSRV9OT1RfRk9VTkQgPSBcdTY1RTBcdTZDRDVcdThCQzZcdTUyMkJcdTUzQzJcdTY1NzB7MH1cdTMwMDIKLVNUUklOR19UT09fTE9ORyAgID0gXHU3NTFGXHU2MjEwXHU3Njg0XHU1QjU3XHU3QjI2XHU0RTMyXHU1OTJBXHU5NTdGLCBcdTRFMERcdTkwMDJcdTU0MDggRE9NU3RyaW5nOiAnJ3swfScnXHUzMDAyCi0KLSNET00gTGV2ZWwgMyBET01FcnJvciBjb2Rlcwotd2YtaW52YWxpZC1jaGFyYWN0ZXIgPSAgezF9XHU4MjgyXHU3MEI5XHU3Njg0XHU2NTg3XHU2NzJDezB9XHU1MzA1XHU1NDJCXHU2NUUwXHU2NTQ4IFhNTCBcdTVCNTdcdTdCMjZcdTMwMDIKLXdmLWludmFsaWQtY2hhcmFjdGVyLWluLW5vZGUtbmFtZSA9IFx1NTQwRFx1NEUzQXsxfVx1NzY4NHswfVx1ODI4Mlx1NzBCOVx1NTMwNVx1NTQyQlx1NjVFMFx1NjU0OCBYTUwgXHU1QjU3XHU3QjI2XHUzMDAyCi1jZGF0YS1zZWN0aW9ucy1zcGxpdHRlZCA9ICBcdTUzMDVcdTU0MkIgQ0RBVEEgXHU4MjgyXHU3RUM4XHU2QjYyXHU2ODA3XHU4QkIwICcnXV0+JycgXHU3Njg0IENEQVRBIFx1ODI4MgotZG9jdHlwZS1ub3QtYWxsb3dlZCA9IFx1NEUwRFx1NTE0MVx1OEJCOCBET0NUWVBFIFx1NThGMFx1NjYwRVx1MzAwMgotdW5zdXBwb3J0ZWQtZW5jb2RpbmcgPSBcdTRFMERcdTY1MkZcdTYzMDFcdTdGMTZcdTc4MDF7MH1cdTMwMDIKLQotI0Vycm9yIGNvZGVzIHVzZWQgaW4gRE9NIE5vcm1hbGl6ZXIKLUludmFsaWRYTUxDaGFySW5ET00gPSBcdThGREJcdTg4NENcdTg5QzRcdTgzMDNcdTUzMTZcdTY1RjYsIFx1NTcyOCBET00gXHU0RTJEXHU2MjdFXHU1MjMwXHU3Njg0IFhNTCBcdTVCNTdcdTdCMjYgKFVuaWNvZGU6IDB4ezB9KSBcdTY1RTBcdTY1NDhcdTMwMDIKLVVuZGVjbGFyZWRFbnRSZWZJbkF0dHJWYWx1ZSA9IFx1NUM1RVx1NjAyNyAiezB9IiBcdTUwM0MgInsxfSIgXHU1RjE1XHU3NTI4XHU0RTg2XHU2NzJBXHU1OEYwXHU2NjBFXHU3Njg0XHU1QjlFXHU0RjUzXHUzMDAyCi1OdWxsTG9jYWxFbGVtZW50TmFtZSA9IFx1NUJGOVx1NTE0M1x1N0QyMHswfVx1OEZEQlx1ODg0Q1x1NTQwRFx1NzlGMFx1N0E3QVx1OTVGNFx1ODlDNFx1ODMwM1x1NTMxNlx1NjVGNlx1OTA0N1x1NTIzMFx1NEU4Nlx1N0E3QVx1NjcyQ1x1NTczMFx1NTQwRFx1NzlGMFx1MzAwMgotTnVsbExvY2FsQXR0ck5hbWUgPSBcdTVCRjlcdTVDNUVcdTYwMjd7MH1cdThGREJcdTg4NENcdTU0MERcdTc5RjBcdTdBN0FcdTk1RjRcdTg5QzRcdTgzMDNcdTUzMTZcdTY1RjZcdTkwNDdcdTUyMzBcdTRFODZcdTdBN0FcdTY3MkNcdTU3MzBcdTU0MERcdTc5RjBcdTMwMDIKLQotI0Vycm9yIGNvZGVzIHVzZWQgaW4gRE9NUGFyc2VyCi1JbnZhbGlkRG9jdW1lbnRDbGFzc05hbWUgPSBcdTc1MjhcdTRFOEVcdTY3ODRcdTkwMjAgRE9NIFx1NjgxMVx1NzY4NFx1NjU4N1x1Njg2M1x1NURFNVx1NTM4MiAiezB9IiBcdTc2ODRcdTdDN0JcdTU0MERcdTRFMERcdTY2MkYgb3JnLnczYy5kb20uRG9jdW1lbnQgXHU3QzdCXHU1NzhCXHUzMDAyCi1NaXNzaW5nRG9jdW1lbnRDbGFzc05hbWUgPSBcdTYyN0VcdTRFMERcdTUyMzBcdTc1MjhcdTRFOEVcdTY3ODRcdTkwMjAgRE9NIFx1NjgxMVx1NzY4NFx1NjU4N1x1Njg2M1x1NURFNVx1NTM4MiAiezB9IiBcdTc2ODRcdTdDN0JcdTU0MERcdTMwMDIKLUNhbm5vdENyZWF0ZURvY3VtZW50Q2xhc3MgPSBcdTU0MERcdTRFM0EgInswfSIgXHU3Njg0XHU3QzdCXHU2NUUwXHU2Q0Q1XHU2Nzg0XHU5MDIwXHU0RTNBIG9yZy53M2MuZG9tLkRvY3VtZW50XHUzMDAyCi0KLSMgRXJyb3IgY29kZXMgdXNlZCBieSBKQVhQIERvY3VtZW50QnVpbGRlcgotamF4cC1vcmRlci1ub3Qtc3VwcG9ydGVkID0gXHU1RkM1XHU5ODdCXHU1NzI4XHU4QkJFXHU3RjZFXHU1QzVFXHU2MDI3ICcnezF9JycgXHU0RTRCXHU1MjREXHU4QkJFXHU3RjZFXHU1QzVFXHU2MDI3ICcnezB9JydcdTMwMDIKLWpheHAtbnVsbC1pbnB1dC1zb3VyY2UgPSBcdTYzMDdcdTVCOUFcdTc2ODRcdTZFOTBcdTRFMERcdTgwRkRcdTRFM0FcdTdBN0FcdTUwM0NcdTMwMDIKLQotI1JhbmdlcwotQkFEX0JPVU5EQVJZUE9JTlRTX0VSUiA9IFJhbmdlIFx1NzY4NFx1OEZCOVx1NzU0Q1x1NzBCOVx1NEUwRFx1N0IyNlx1NTQwOFx1NzI3OVx1NUI5QVx1ODk4MVx1NkM0Mlx1MzAwMgotSU5WQUxJRF9OT0RFX1RZUEVfRVJSID0gUmFuZ2UgXHU3Njg0XHU4RkI5XHU3NTRDXHU3MEI5XHU3Njg0XHU1QkI5XHU1NjY4XHU4QkJFXHU3RjZFXHU0RTNBXHU2NUUwXHU2NTQ4XHU3QzdCXHU1NzhCXHU3Njg0XHU4MjgyXHU3MEI5XHU2MjE2XHU1MTc3XHU2NzA5XHU2NUUwXHU2NTQ4XHU3QzdCXHU1NzhCXHU3Njg0XHU1MzlGXHU3RUE3XHU3Njg0XHU4MjgyXHU3MEI5XHUzMDAyCi0KLQotI0V2ZW50cwotVU5TUEVDSUZJRURfRVZFTlRfVFlQRV9FUlIgPSBFdmVudCBcdTdDN0JcdTU3OEJcdTRFMERcdTY2MkZcdTkwMUFcdThGQzdcdTU3MjhcdThDMDNcdTc1MjhcdTY1QjlcdTZDRDVcdTUyNERcdTUyMURcdTU5Q0JcdTUzMTZcdTZCNjRcdTRFOEJcdTRFRjZcdTYzMDdcdTVCOUFcdTc2ODRcdTMwMDIKLQotCi1qYXhwLXNjaGVtYS1zdXBwb3J0PVx1NTQwQ1x1NjVGNlx1NEY3Rlx1NzUyOFx1NEU4NiBzZXRTY2hlbWEgXHU2NUI5XHU2Q0Q1XHU1NDhDIHNjaGVtYUxhbmd1YWdlIFx1NUM1RVx1NjAyNwotCi1qYXhwX2ZlYXR1cmVfbm90X3N1cHBvcnRlZD1cdTRFMERcdTY1MkZcdTYzMDFcdTUyOUZcdTgwRkQgInswfSJcdTMwMDIKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL0RPTU1lc3NhZ2VzX3poX1RXLnByb3BlcnRpZXMgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9ET01NZXNzYWdlc196aF9UVy5wcm9wZXJ0aWVzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjYWU0M2E1Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL0RPTU1lc3NhZ2VzX3poX1RXLnByb3BlcnRpZXMKKysrIC9kZXYvbnVsbApAQCAtMSw2OSArMCwwIEBACi0jIFRoaXMgZmlsZSBzdG9yZXMgbG9jYWxpemVkIG1lc3NhZ2VzIGZvciB0aGUgWGVyY2VzCi0jIERPTSBpbXBsZW1lbnRhdGlvbi4KLSMKLSMgVGhlIG1lc3NhZ2VzIGFyZSBhcnJhbmdlZCBpbiBrZXkgYW5kIHZhbHVlIHR1cGxlcyBpbiBhIExpc3RSZXNvdXJjZUJ1bmRsZS4KLSMKLQotQmFkTWVzc2FnZUtleSA9IFx1NjI3RVx1NEUwRFx1NTIzMFx1NUMwRFx1NjFDOVx1OEEwQVx1NjA2Rlx1N0QyMlx1NUYxNVx1OTM3NVx1NzY4NFx1OTMyRlx1OEFBNFx1OEEwQVx1NjA2Rlx1MzAwMgotRm9ybWF0RmFpbGVkID0gXHU2ODNDXHU1RjBGXHU1MzE2XHU0RTBCXHU1MjE3XHU4QTBBXHU2MDZGXHU2NjQyXHU3NjdDXHU3NTFGXHU1MTY3XHU5MEU4XHU5MzJGXHU4QUE0OlxuCi0KLSMgRE9NIENvcmUKLQotIyBleGNlcHRpb24gY29kZXMKLURPTVNUUklOR19TSVpFX0VSUiA9IFx1NjMwN1x1NUI5QVx1NzY4NFx1NjU4N1x1NUI1N1x1N0JDNFx1NTcwRFx1NzEyMVx1NkNENVx1N0QwRFx1NTE2NSBET01TdHJpbmdcdTMwMDIKLUhJRVJBUkNIWV9SRVFVRVNUX0VSUiAgPSBcdTU2MTdcdThBNjZcdTU3MjhcdTRFMERcdTUxNDFcdThBMzFcdTc2ODRcdTRGNERcdTdGNkVcdTYzRDJcdTUxNjVcdTdCQzBcdTlFREVcdTMwMDIKLUlOREVYX1NJWkVfRVJSID0gXHU3RDIyXHU1RjE1XHU2MjE2XHU1OTI3XHU1QzBGXHU3MEJBXHU4Q0EwXHU1MDNDXHVGRjBDXHU2MjE2XHU2NjJGXHU1OTI3XHU2NUJDXHU1MTQxXHU4QTMxXHU3Njg0XHU1MDNDXHUzMDAyCi1JTlVTRV9BVFRSSUJVVEVfRVJSID0gXHU1NjE3XHU4QTY2XHU2NUIwXHU1ODlFXHU1REYyXHU3RDkzXHU1NzI4XHU0RUQ2XHU4NjU1XHU0RjdGXHU3NTI4XHU3Njg0XHU1QzZDXHU2MDI3XHUzMDAyCi1JTlZBTElEX0FDQ0VTU19FUlIgID0gXHU1RTk1XHU1QzY0XHU3MjY5XHU0RUY2XHU0RTBEXHU2NTJGXHU2M0Y0XHU3Njg0XHU1M0MzXHU2NTc4XHU2MjE2XHU0RjVDXHU2OTZEXHUzMDAyCi1JTlZBTElEX0NIQVJBQ1RFUl9FUlIgPSBcdTYzMDdcdTVCOUFcdTRFODZcdTcxMjFcdTY1NDhcdTc2ODQgWE1MIFx1NUI1N1x1NTE0M1x1MzAwMgotSU5WQUxJRF9NT0RJRklDQVRJT05fRVJSID0gIFx1NTYxN1x1OEE2Nlx1NEZFRVx1NjUzOVx1NUU5NVx1NUM2NFx1NzI2OVx1NEVGNlx1NzY4NFx1OTg1RVx1NTc4Qlx1MzAwMgotSU5WQUxJRF9TVEFURV9FUlIgPSBcdTU2MTdcdThBNjZcdTRGN0ZcdTc1MjhcdTRFMERcdTUzRUZcdTc1MjhcdTYyMTZcdTcxMjFcdTZDRDVcdTUxOERcdTRGN0ZcdTc1MjhcdTc2ODRcdTcyNjlcdTRFRjZcdTMwMDIKLU5BTUVTUEFDRV9FUlIgPSBcdTVDMERcdTY1QkNcdTU0N0RcdTU0MERcdTdBN0FcdTk1OTNcdTgwMENcdThBMDBcdUZGMENcdTU2MTdcdThBNjZcdTRGN0ZcdTc1MjhcdTRFMERcdTZCNjNcdTc4QkFcdTc2ODRcdTY1QjlcdTVGMEZcdTRGODZcdTVFRkFcdTdBQ0JcdTYyMTZcdThCOEFcdTY2RjRcdTcyNjlcdTRFRjZcdTMwMDIKLU5PVF9GT1VORF9FUlIgPSBcdTU2MTdcdThBNjZcdTU3MjhcdTc2RjhcdTk1RENcdThDQzdcdThBMEFcdTc0QjBcdTU4ODNcdTRFMkRcdTUzQzNcdTcxNjdcdTRFMERcdTVCNThcdTU3MjhcdTc2ODRcdTdCQzBcdTlFREVcdTMwMDIKLU5PVF9TVVBQT1JURURfRVJSID0gXHU1QkU2XHU4ODRDXHU0RTBEXHU2NTJGXHU2M0Y0XHU4OTgxXHU2QzQyXHU3Njg0XHU3MjY5XHU0RUY2XHU2MjE2XHU0RjVDXHU2OTZEXHU5ODVFXHU1NzhCXHUzMDAyCi1OT19EQVRBX0FMTE9XRURfRVJSID0gXHU3MEJBXHU0RTBEXHU2NTJGXHU2M0Y0XHU4Q0M3XHU2NTk5XHU3Njg0XHU3QkMwXHU5RURFXHU2MzA3XHU1QjlBXHU0RTg2XHU4Q0M3XHU2NTk5XHUzMDAyCi1OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIgPSBcdTU2MTdcdThBNjZcdTRGRUVcdTY1MzlcdTRFMERcdTUxNDFcdThBMzFcdTRGRUVcdTY1MzlcdTc2ODRcdTcyNjlcdTRFRjZcdTMwMDIKLVNZTlRBWF9FUlIgPSBcdTYzMDdcdTVCOUFcdTRFODZcdTcxMjFcdTY1NDhcdTc2ODRcdTVCNTdcdTRFMzJcdTMwMDIKLVZBTElEQVRJT05fRVJSID0gXHU1QzBEXHU2NUJDXHU2NTg3XHU0RUY2XHU2NTg3XHU2Q0Q1XHU4MDBDXHU4QTAwXHVGRjBDXHU1NDdDXHU1M0VCIGluc2VydEJlZm9yZSBcdTYyMTYgcmVtb3ZlQ2hpbGQgXHU0RTRCXHU5ODVFXHU3Njg0XHU2NUI5XHU2Q0Q1XHVGRjBDXHU2NzAzXHU0RjdGXHU1Rjk3XHU3QkMwXHU5RURFXHU3MTIxXHU2NTQ4XHUzMDAyCi1XUk9OR19ET0NVTUVOVF9FUlIgPSBcdTdCQzBcdTlFREVcdTc1MjhcdTU3MjhcdTY3MDlcdTUyMjVcdTY1QkNcdTVFRkFcdTdBQ0JcdThBNzJcdTdCQzBcdTlFREVcdTY1ODdcdTRFRjZcdTc2ODRcdTRFMERcdTU0MENcdTY1ODdcdTRFRjZcdTMwMDIKLVRZUEVfTUlTTUFUQ0hfRVJSID0gXHU2QjY0XHU1M0MzXHU2NTc4XHU1NDBEXHU3QTMxXHU3Njg0XHU1MDNDXHU5ODVFXHU1NzhCXHU4MjA3XHU5ODEwXHU2NzFGXHU3Njg0XHU1MDNDXHU5ODVFXHU1NzhCXHU0RTBEXHU3NkY4XHU1QkI5XHUzMDAyCi0gCi0jZXJyb3IgbWVzc2FnZXMgb3IgZXhjZXB0aW9ucwotRkVBVFVSRV9OT1RfU1VQUE9SVEVEID0gXHU1M0VGXHU4RkE4XHU4QjU4XHU1M0MzXHU2NTc4IHswfVx1RkYwQ1x1NEY0Nlx1NzEyMVx1NkNENVx1OEEyRFx1NUI5QVx1ODk4MVx1NkM0Mlx1NzY4NFx1NTAzQ1x1MzAwMgotRkVBVFVSRV9OT1RfRk9VTkQgPSBcdTcxMjFcdTZDRDVcdThGQThcdThCNThcdTUzQzNcdTY1NzggezB9XHUzMDAyCi1TVFJJTkdfVE9PX0xPTkcgICA9IFx1N0Q1MFx1Njc5Q1x1NUI1N1x1NEUzMlx1NTkyQVx1OTU3N1x1RkYwQ1x1NzEyMVx1NkNENVx1N0QwRFx1NTE2NSBET01TdHJpbmc6ICcnezB9JydcdTMwMDIKLQotI0RPTSBMZXZlbCAzIERPTUVycm9yIGNvZGVzCi13Zi1pbnZhbGlkLWNoYXJhY3RlciA9ICB7MX0gXHU3QkMwXHU5RURFXHU3Njg0XHU2NTg3XHU1QjU3IHswfSBcdTUzMDVcdTU0MkJcdTcxMjFcdTY1NDhcdTc2ODQgWE1MIFx1NUI1N1x1NTE0M1x1MzAwMgotd2YtaW52YWxpZC1jaGFyYWN0ZXItaW4tbm9kZS1uYW1lID0gXHU1NDBEXHU3QTMxXHU3MEJBIHsxfSBcdTc2ODQgezB9IFx1N0JDMFx1OUVERVx1NTMwNVx1NTQyQlx1NzEyMVx1NjU0OFx1NzY4NCBYTUwgXHU1QjU3XHU1MTQzXHUzMDAyCi1jZGF0YS1zZWN0aW9ucy1zcGxpdHRlZCA9ICBcdTUzMDVcdTU0MkIgQ0RBVEEgXHU2QkI1XHU4NDNEXHU3RDQyXHU2QjYyXHU2QTE5XHU4QTE4ICcnXV0+JycgXHU3Njg0IENEQVRBIFx1NkJCNVx1ODQzRAotZG9jdHlwZS1ub3QtYWxsb3dlZCA9IFx1NEUwRFx1NTE0MVx1OEEzMSBET0NUWVBFIFx1NUJBM1x1NTQ0QVx1MzAwMgotdW5zdXBwb3J0ZWQtZW5jb2RpbmcgPSBcdTRFMERcdTY1MkZcdTYzRjRcdTdERThcdTc4QkMgezB9XHUzMDAyCi0KLSNFcnJvciBjb2RlcyB1c2VkIGluIERPTSBOb3JtYWxpemVyCi1JbnZhbGlkWE1MQ2hhckluRE9NID0gXHU2QjYzXHU4OThGXHU1MzE2XHU2NzFGXHU5NTkzXHU1NzI4IERPTSBcdTRFMkRcdTYyN0VcdTUyMzBcdTcxMjFcdTY1NDhcdTc2ODQgWE1MIFx1NUI1N1x1NTE0MyAoVW5pY29kZTogMHh7MH0pXHUzMDAyCi1VbmRlY2xhcmVkRW50UmVmSW5BdHRyVmFsdWUgPSBcdTVDNkNcdTYwMjcgInswfSIgXHU1MDNDICJ7MX0iIFx1NTNDM1x1NzE2N1x1NjcyQVx1NUJBM1x1NTQ0QVx1NzY4NFx1NUJFNlx1OUFENFx1MzAwMgotTnVsbExvY2FsRWxlbWVudE5hbWUgPSBcdTUxNDNcdTdEMjAgezB9IFx1NTQ3RFx1NTQwRFx1N0E3QVx1OTU5M1x1NkI2M1x1ODk4Rlx1NTMxNlx1NjcxRlx1OTU5M1x1RkYwQ1x1NTFGQVx1NzNGRVx1N0E3QVx1NTAzQ1x1NTM0MFx1NTdERlx1NTQwRFx1N0EzMVx1MzAwMgotTnVsbExvY2FsQXR0ck5hbWUgPSBcdTVDNkNcdTYwMjcgezB9IFx1NTQ3RFx1NTQwRFx1N0E3QVx1OTU5M1x1NkI2M1x1ODk4Rlx1NTMxNlx1NjcxRlx1OTU5M1x1RkYwQ1x1NTFGQVx1NzNGRVx1N0E3QVx1NTAzQ1x1NTM0MFx1NTdERlx1NTQwRFx1N0EzMVx1MzAwMgotCi0jRXJyb3IgY29kZXMgdXNlZCBpbiBET01QYXJzZXIKLUludmFsaWREb2N1bWVudENsYXNzTmFtZSA9IFx1NzUyOFx1NjVCQ1x1NUVGQVx1NjlDQiBET00gXHU2QTM5XHU3MkMwXHU3RDUwXHU2OUNCXHU3Njg0XHU2NTg3XHU0RUY2XHU4NjU1XHU3NDA2XHU3QUQ5ICJ7MH0iIFx1OTg1RVx1NTIyNVx1NTQwRFx1N0EzMVx1NEUyNlx1OTc1RVx1OTg1RVx1NTc4QiBvcmcudzNjLmRvbS5Eb2N1bWVudFx1MzAwMgotTWlzc2luZ0RvY3VtZW50Q2xhc3NOYW1lID0gXHU2MjdFXHU0RTBEXHU1MjMwXHU3NTI4XHU2NUJDXHU1RUZBXHU2OUNCIERPTSBcdTZBMzlcdTcyQzBcdTdENTBcdTY5Q0JcdTc2ODRcdTY1ODdcdTRFRjZcdTg2NTVcdTc0MDZcdTdBRDkgInswfSIgXHU5ODVFXHU1MjI1XHU1NDBEXHU3QTMxXHUzMDAyCi1DYW5ub3RDcmVhdGVEb2N1bWVudENsYXNzID0gXHU1NDBEXHU3QTMxXHU3MEJBICJ7MH0iIFx1NzY4NFx1OTg1RVx1NTIyNVx1NzEyMVx1NkNENVx1NUVGQVx1NjlDQlx1NzBCQSBvcmcudzNjLmRvbS5Eb2N1bWVudFx1MzAwMgotCi0jIEVycm9yIGNvZGVzIHVzZWQgYnkgSkFYUCBEb2N1bWVudEJ1aWxkZXIKLWpheHAtb3JkZXItbm90LXN1cHBvcnRlZCA9IFx1OEEyRFx1NUI5QVx1NUM2Q1x1NjAyNyAnJ3sxfScnIFx1NEU0Qlx1NTI0RFx1RkYwQ1x1NUZDNVx1OTgwOFx1OEEyRFx1NUI5QVx1NUM2Q1x1NjAyNyAnJ3swfScnXHUzMDAyCi1qYXhwLW51bGwtaW5wdXQtc291cmNlID0gXHU2MzA3XHU1QjlBXHU3Njg0XHU0Rjg2XHU2RTkwXHU0RTBEXHU1M0VGXHU3MEJBXHU3QTdBXHU1MDNDXHUzMDAyCi0KLSNSYW5nZXMKLUJBRF9CT1VOREFSWVBPSU5UU19FUlIgPSBcdTdCQzRcdTU3MERcdTc2ODRcdTc1NENcdTk2NTBcdTlFREVcdTRFMERcdTdCMjZcdTU0MDhcdTcyNzlcdTVCOUFcdTc2ODRcdTk3MDBcdTZDNDJcdTMwMDIKLUlOVkFMSURfTk9ERV9UWVBFX0VSUiA9IFx1N0JDNFx1NTcwRFx1NzY4NFx1NzU0Q1x1OTY1MFx1OUVERVx1NUJCOVx1NTY2OFx1ODhBQlx1OEEyRFx1NzBCQVx1NzEyMVx1NjU0OFx1OTg1RVx1NTc4Qlx1NzY4NFx1N0JDMFx1OUVERVx1RkYwQ1x1NjIxNlx1NjYyRlx1Nzk1Nlx1N0NGQlx1NzBCQVx1NzEyMVx1NjU0OFx1OTg1RVx1NTc4Qlx1NzY4NFx1N0JDMFx1OUVERVx1MzAwMgotCi0KLSNFdmVudHMKLVVOU1BFQ0lGSUVEX0VWRU5UX1RZUEVfRVJSID0gXHU1NDdDXHU1M0VCXHU2NUI5XHU2Q0Q1XHU0RTRCXHU1MjREXHU4RDc3XHU1OUNCXHU0RThCXHU0RUY2XHVGRjBDXHU0RTBEXHU2NzAzXHU2MzA3XHU1QjlBXHU0RThCXHU0RUY2XHU3Njg0XHU5ODVFXHU1NzhCXHUzMDAyCi0KLQotamF4cC1zY2hlbWEtc3VwcG9ydD1cdTU0MENcdTY2NDJcdTRGN0ZcdTc1Mjggc2V0U2NoZW1hIFx1NjVCOVx1NkNENVx1ODIwNyBzY2hlbWFMYW5ndWFnZSBcdTVDNkNcdTYwMjcKLQotamF4cF9mZWF0dXJlX25vdF9zdXBwb3J0ZWQ9XHU0RTBEXHU2NTJGXHU2M0Y0XHU1MjlGXHU4MEZEICJ7MH0iXHUzMDAyCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9EYXRhdHlwZU1lc3NhZ2VzLnByb3BlcnRpZXMgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9EYXRhdHlwZU1lc3NhZ2VzLnByb3BlcnRpZXMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGRhMWVlZWMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvRGF0YXR5cGVNZXNzYWdlcy5wcm9wZXJ0aWVzCisrKyAvZGV2L251bGwKQEAgLTEsMjkgKzAsMCBAQAotIyBUaGlzIGZpbGUgc3RvcmVzIGxvY2FsaXplZCBtZXNzYWdlcyBmb3IgdGhlIFhlcmNlcyBKQVhQIERhdGF0eXBlIEFQSSBpbXBsZW1lbnRhdGlvbi4KLSMKLSMgVGhlIG1lc3NhZ2VzIGFyZSBhcnJhbmdlZCBpbiBrZXkgYW5kIHZhbHVlIHR1cGxlcyBpbiBhIExpc3RSZXNvdXJjZUJ1bmRsZS4KLSMKLQotQmFkTWVzc2FnZUtleSA9IFRoZSBlcnJvciBtZXNzYWdlIGNvcnJlc3BvbmRpbmcgdG8gdGhlIG1lc3NhZ2Uga2V5IGNhbiBub3QgYmUgZm91bmQuCi1Gb3JtYXRGYWlsZWQgPSBBbiBpbnRlcm5hbCBlcnJvciBvY2N1cnJlZCB3aGlsZSBmb3JtYXR0aW5nIHRoZSBmb2xsb3dpbmcgbWVzc2FnZTpcbgotCi1GaWVsZENhbm5vdEJlTnVsbD17MH0gY2Fubm90IGJlIGNhbGxlZCB3aXRoICdudWxsJyBwYXJhbWV0ZXIuCi1Vbmtub3duRmllbGQ9ezB9IGNhbGxlZCB3aXRoIGFuIHVua25vd24gZmllbGRcOnsxfQotI1RoZXJlIGFyZSB0d28gc2ltaWxhciBrZXlzICdJbnZhbGlkWE1MR3Jlb2dvcmlhbkNhbGVuZGFyVmFsdWUnIC4gU3VmZml4ICh5ZWFyLCBtb250aCkgaGFzIGJlZW4gYWRkZWQgYW5kIGFyZSB1c2VkIGFzIHBlciB0aGUgY29udGV4dC4KLUludmFsaWRYR0NWYWx1ZS1taWxsaT1ZZWFyIFw9IHswfSwgTW9udGggXD0gezF9LCBEYXkgXD0gezJ9LCBIb3VyIFw9IHszfSwgTWludXRlIFw9IHs0fSwgU2Vjb25kIFw9IHs1fSwgZnJhY3Rpb25hbFNlY29uZCBcPSB7Nn0sIFRpbWV6b25lIFw9IHs3fSAsIGlzIG5vdCBhIHZhbGlkIHJlcHJlc2VudGF0aW9uIG9mIGFuIFhNTCBHcmVnb3JpYW4gQ2FsZW5kYXIgdmFsdWUuCi0jVGhlcmUgYXJlIHR3byBzaW1pbGFyIGtleXMgJ0ludmFsaWRYTUxHcmVvZ29yaWFuQ2FsZW5kYXJWYWx1ZScgLiBTdWZmaXggKHllYXIsIG1vbnRoKSBoYXMgYmVlbiBhZGRlZCBhbmQgYXJlIHVzZWQgYXMgcGVyIHRoZSBjb250ZXh0LgotSW52YWxpZFhHQ1ZhbHVlLWZyYWN0aW9uYWw9WWVhciBcPSB7MH0sIE1vbnRoIFw9IHsxfSwgRGF5IFw9IHsyfSwgSG91ciBcPSB7M30sIE1pbnV0ZSBcPSB7NH0sIFNlY29uZCBcPSB7NX0sIGZyYWN0aW9uYWxTZWNvbmQgXD0gezZ9LCBUaW1lem9uZSBcPSB7N30gLCBpcyBub3QgYSB2YWxpZCByZXByZXNlbnRhdGlvbiBvZiBhbiBYTUwgR3JlZ29yaWFuIENhbGVuZGFyIHZhbHVlLgotCi1JbnZhbGlkWEdDRmllbGRzPUludmFsaWQgc2V0IG9mIGZpZWxkcyBzZXQgZm9yIFhNTEdyZWdvcmlhbkNhbGVuZGFyCi0KLUludmFsaWRGcmFjdGlvbmFsPUludmFsaWQgdmFsdWUgezB9IGZvciBmcmFjdGlvbmFsIHNlY29uZC4KLQotI1hHQyBzdGFuZHMgZm9yIFhNTCBHcmVnb3JpYW4gQ2FsZW5kYXIKLUludmFsaWRYR0NSZXByZXNlbnRhdGlvbj0iezB9IiBpcyBub3QgYSB2YWxpZCByZXByZXNlbnRhdGlvbiBvZiBhbiBYTUwgR3JlZ29yaWFuIENhbGVuZGFyIHZhbHVlLgotCi1JbnZhbGlkRmllbGRWYWx1ZT1JbnZhbGlkIHZhbHVlIHswfSBmb3IgezF9IGZpZWxkLgotCi1OZWdhdGl2ZUZpZWxkPSB7MH0gZmllbGQgaXMgbmVnYXRpdmUKLQotQWxsRmllbGRzTnVsbD1BbGwgdGhlIGZpZWxkcyAoamF2YXgueG1sLmRhdGF0eXBlLkRhdGF0eXBlQ29uc3RhbnRzLkZpZWxkKSBhcmUgbnVsbC4KLQotVG9vTGFyZ2U9ezB9IHZhbHVlICJ7MX0iIHRvbyBsYXJnZSB0byBiZSBzdXBwb3J0ZWQgYnkgdGhpcyBpbXBsZW1lbnRhdGlvbgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvRGF0YXR5cGVNZXNzYWdlc19kZS5wcm9wZXJ0aWVzIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvRGF0YXR5cGVNZXNzYWdlc19kZS5wcm9wZXJ0aWVzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxODE5Y2QyLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL0RhdGF0eXBlTWVzc2FnZXNfZGUucHJvcGVydGllcworKysgL2Rldi9udWxsCkBAIC0xLDI5ICswLDAgQEAKLSMgVGhpcyBmaWxlIHN0b3JlcyBsb2NhbGl6ZWQgbWVzc2FnZXMgZm9yIHRoZSBYZXJjZXMgSkFYUCBEYXRhdHlwZSBBUEkgaW1wbGVtZW50YXRpb24uCi0jCi0jIFRoZSBtZXNzYWdlcyBhcmUgYXJyYW5nZWQgaW4ga2V5IGFuZCB2YWx1ZSB0dXBsZXMgaW4gYSBMaXN0UmVzb3VyY2VCdW5kbGUuCi0jCi0KLUJhZE1lc3NhZ2VLZXkgPSBEaWUgenVtIE1lbGR1bmdzc2NobFx1MDBGQ3NzZWwgZ2VoXHUwMEY2cmlnZSBGZWhsZXJtZWxkdW5nIGthbm4gbmljaHQgZ2VmdW5kZW4gd2VyZGVuLgotRm9ybWF0RmFpbGVkID0gQmVpbSBGb3JtYXRpZXJlbiBkZXIgZm9sZ2VuZGVuIE1lbGR1bmcgaXN0IGVpbiBpbnRlcm5lciBGZWhsZXIgYXVmZ2V0cmV0ZW46XG4KLQotRmllbGRDYW5ub3RCZU51bGw9ezB9IGthbm4gbmljaHQgbWl0ICJOdWxsIi1QYXJhbWV0ZXIgYXVmZ2VydWZlbiB3ZXJkZW4uCi1Vbmtub3duRmllbGQ9ezB9IG1pdCB1bmJla2FubnRlbSBGZWxkIGF1ZmdlcnVmZW46ezF9Ci0jVGhlcmUgYXJlIHR3byBzaW1pbGFyIGtleXMgJ0ludmFsaWRYTUxHcmVvZ29yaWFuQ2FsZW5kYXJWYWx1ZScgLiBTdWZmaXggKHllYXIsIG1vbnRoKSBoYXMgYmVlbiBhZGRlZCBhbmQgYXJlIHVzZWQgYXMgcGVyIHRoZSBjb250ZXh0LgotSW52YWxpZFhHQ1ZhbHVlLW1pbGxpPUphaHIgPSB7MH0sIE1vbmF0ID0gezF9LCBUYWcgPSB7Mn0sIFN0dW5kZT0gezN9LCBNaW51dGUgPSB7NH0sIFNla3VuZGUgPSB7NX0sIGZyYWN0aW9uYWxTZWNvbmQgPSB7Nn0sIFplaXR6b25lID0gezd9IGlzdCBrZWluZSBnXHUwMEZDbHRpZ2UgRGFyc3RlbGx1bmcgZWluZXMgWE1MLVdlcnRlcyBmXHUwMEZDciBlaW5lbiBncmVnb3JpYW5pc2NoZW4gS2FsZW5kZXIuCi0jVGhlcmUgYXJlIHR3byBzaW1pbGFyIGtleXMgJ0ludmFsaWRYTUxHcmVvZ29yaWFuQ2FsZW5kYXJWYWx1ZScgLiBTdWZmaXggKHllYXIsIG1vbnRoKSBoYXMgYmVlbiBhZGRlZCBhbmQgYXJlIHVzZWQgYXMgcGVyIHRoZSBjb250ZXh0LgotSW52YWxpZFhHQ1ZhbHVlLWZyYWN0aW9uYWw9SmFociA9IHswfSwgTW9uYXQgPSB7MX0sIFRhZyA9IHsyfSwgU3R1bmRlPSB7M30sIE1pbnV0ZSA9IHs0fSwgU2VrdW5kZSA9IHs1fSwgZnJhY3Rpb25hbFNlY29uZCA9IHs2fSwgWmVpdHpvbmUgPSB7N30gaXN0IGtlaW5lIGdcdTAwRkNsdGlnZSBEYXJzdGVsbHVuZyBlaW5lcyBYTUwtV2VydGVzIGZcdTAwRkNyIGVpbmVuIGdyZWdvcmlhbmlzY2hlbiBLYWxlbmRlci4KLQotSW52YWxpZFhHQ0ZpZWxkcz1VbmdcdTAwRkNsdGlnZSBHcnVwcGUgdm9uIEZlbGRlcm4gZlx1MDBGQ3IgWE1MR3JlZ29yaWFuQ2FsZW5kYXIgZmVzdGdlbGVndAotCi1JbnZhbGlkRnJhY3Rpb25hbD1VbmdcdTAwRkNsdGlnZXIgV2VydCB7MH0gZlx1MDBGQ3IgU2VrdW5kZW5icnVjaHRlaWwuCi0KLSNYR0Mgc3RhbmRzIGZvciBYTUwgR3JlZ29yaWFuIENhbGVuZGFyCi1JbnZhbGlkWEdDUmVwcmVzZW50YXRpb249InswfSIgaXN0IGtlaW5lIGdcdTAwRkNsdGlnZSBEYXJzdGVsbHVuZyBlaW5lcyBYTUwtV2VydGVzIGZcdTAwRkNyIGVpbmVuIGdyZWdvcmlhbmlzY2hlbiBLYWxlbmRlci4KLQotSW52YWxpZEZpZWxkVmFsdWU9VW5nXHUwMEZDbHRpZ2VyIFdlcnQgezB9IGZcdTAwRkNyIEZlbGQgezF9LgotCi1OZWdhdGl2ZUZpZWxkPSBGZWxkIHswfSBpc3QgbmVnYXRpdgotCi1BbGxGaWVsZHNOdWxsPUFsbGUgRmVsZGVyIChqYXZheC54bWwuZGF0YXR5cGUuRGF0YXR5cGVDb25zdGFudHMuRmllbGQpIHNpbmQgbnVsbC4KLQotVG9vTGFyZ2U9ezB9LVdlcnQgInsxfSIgenUgZ3JvXHUwMERGLCB1bSB2b24gZGllc2VyIEltcGxlbWVudGllcnVuZyB1bnRlcnN0XHUwMEZDdHp0IHp1IHdlcmRlbgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvRGF0YXR5cGVNZXNzYWdlc19lcy5wcm9wZXJ0aWVzIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvRGF0YXR5cGVNZXNzYWdlc19lcy5wcm9wZXJ0aWVzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhN2E4NzllLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL0RhdGF0eXBlTWVzc2FnZXNfZXMucHJvcGVydGllcworKysgL2Rldi9udWxsCkBAIC0xLDI5ICswLDAgQEAKLSMgVGhpcyBmaWxlIHN0b3JlcyBsb2NhbGl6ZWQgbWVzc2FnZXMgZm9yIHRoZSBYZXJjZXMgSkFYUCBEYXRhdHlwZSBBUEkgaW1wbGVtZW50YXRpb24uCi0jCi0jIFRoZSBtZXNzYWdlcyBhcmUgYXJyYW5nZWQgaW4ga2V5IGFuZCB2YWx1ZSB0dXBsZXMgaW4gYSBMaXN0UmVzb3VyY2VCdW5kbGUuCi0jCi0KLUJhZE1lc3NhZ2VLZXkgPSBObyBzZSBoYSBlbmNvbnRyYWRvIGVsIG1lbnNhamUgZGUgZXJyb3IgY29ycmVzcG9uZGllbnRlIGEgbGEgY2xhdmUgZGUgbWVuc2FqZS4KLUZvcm1hdEZhaWxlZCA9IFNlIGhhIHByb2R1Y2lkbyB1biBlcnJvciBpbnRlcm5vIGFsIGZvcm1hdGVhciBlbCBzaWd1aWVudGUgbWVuc2FqZTpcbgotCi1GaWVsZENhbm5vdEJlTnVsbD1ubyBzZSBwdWVkZSBsbGFtYXIgYSB7MH0gY29uIHVuIHBhclx1MDBFMW1ldHJvICcnbnVsbycnLgotVW5rbm93bkZpZWxkPXNlIGhhIGxsYW1hZG8gYSB7MH0gY29uIHVuIGNhbXBvIGRlc2Nvbm9jaWRvOnsxfQotI1RoZXJlIGFyZSB0d28gc2ltaWxhciBrZXlzICdJbnZhbGlkWE1MR3Jlb2dvcmlhbkNhbGVuZGFyVmFsdWUnIC4gU3VmZml4ICh5ZWFyLCBtb250aCkgaGFzIGJlZW4gYWRkZWQgYW5kIGFyZSB1c2VkIGFzIHBlciB0aGUgY29udGV4dC4KLUludmFsaWRYR0NWYWx1ZS1taWxsaT1BXHUwMEYxbyA9IHswfSwgTWVzID0gezF9LCBEXHUwMEVEYSA9IHsyfSwgSG9yYSA9IHszfSwgTWludXRvID0gezR9LCBTZWd1bmRvID0gezV9LCBTZWd1bmRvIEZyYWNjaW9uYXJpbyA9IHs2fSwgWm9uYSBIb3JhcmlhID0gezd9ICwgbm8gZXMgdW5hIHJlcHJlc2VudGFjaVx1MDBGM24gdlx1MDBFMWxpZGEgZGUgdW4gdmFsb3IgZGVsIGNhbGVuZGFyaW8gZ3JlZ29yaWFubyBYTUwuCi0jVGhlcmUgYXJlIHR3byBzaW1pbGFyIGtleXMgJ0ludmFsaWRYTUxHcmVvZ29yaWFuQ2FsZW5kYXJWYWx1ZScgLiBTdWZmaXggKHllYXIsIG1vbnRoKSBoYXMgYmVlbiBhZGRlZCBhbmQgYXJlIHVzZWQgYXMgcGVyIHRoZSBjb250ZXh0LgotSW52YWxpZFhHQ1ZhbHVlLWZyYWN0aW9uYWw9QVx1MDBGMW8gPSB7MH0sIE1lcyA9IHsxfSwgRFx1MDBFRGEgPSB7Mn0sIEhvcmEgPSB7M30sIE1pbnV0byA9IHs0fSwgU2VndW5kbyA9IHs1fSwgU2VndW5kbyBGcmFjY2lvbmFyaW8gPSB7Nn0sIFpvbmEgSG9yYXJpYSA9IHs3fSAsIG5vIGVzIHVuYSByZXByZXNlbnRhY2lcdTAwRjNuIHZcdTAwRTFsaWRhIGRlIHVuIHZhbG9yIGRlbCBjYWxlbmRhcmlvIGdyZWdvcmlhbm8gWE1MLgotCi1JbnZhbGlkWEdDRmllbGRzPUp1ZWdvIGRlIGNhbXBvcyBubyB2XHUwMEUxbGlkbyBkZWZpbmlkbyBwYXJhIGVsIGNhbGVuZGFyaW8gZ3JlZ29yaWFubyBYTUwKLQotSW52YWxpZEZyYWN0aW9uYWw9VmFsb3Igbm8gdlx1MDBFMWxpZG8gezB9IHBhcmEgZWwgc2VndW5kbyBmcmFjY2lvbmFyaW8uCi0KLSNYR0Mgc3RhbmRzIGZvciBYTUwgR3JlZ29yaWFuIENhbGVuZGFyCi1JbnZhbGlkWEdDUmVwcmVzZW50YXRpb249InswfSIgbm8gZXMgdW5hIHJlcHJlc2VudGFjaVx1MDBGM24gdlx1MDBFMWxpZGEgZGUgdW4gdmFsb3IgZGVsIGNhbGVuZGFyaW8gZ3JlZ29yaWFubyBYTUwuCi0KLUludmFsaWRGaWVsZFZhbHVlPVZhbG9yIG5vIHZcdTAwRTFsaWRvIHswfSBwYXJhIGVsIGNhbXBvIHsxfS4KLQotTmVnYXRpdmVGaWVsZD0gRWwgY2FtcG8gezB9IGVzIG5lZ2F0aXZvCi0KLUFsbEZpZWxkc051bGw9VG9kb3MgbG9zIGNhbXBvcyAoamF2YXgueG1sLmRhdGF0eXBlLkRhdGF0eXBlQ29uc3RhbnRzLkZpZWxkKSBzb24gbnVsb3MuCi0KLVRvb0xhcmdlPUVsIHZhbG9yICJ7MX0iIGRlIHswfSBlcyBkZW1hc2lhZG8gbGFyZ28gcGFyYSBxdWUgZXN0YSBpbXBsYW50YWNpXHUwMEYzbiBwdWVkYSBzb3BvcnRhcmxvCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9EYXRhdHlwZU1lc3NhZ2VzX2ZyLnByb3BlcnRpZXMgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9EYXRhdHlwZU1lc3NhZ2VzX2ZyLnByb3BlcnRpZXMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDI3MWZmZTcuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvRGF0YXR5cGVNZXNzYWdlc19mci5wcm9wZXJ0aWVzCisrKyAvZGV2L251bGwKQEAgLTEsMjkgKzAsMCBAQAotIyBUaGlzIGZpbGUgc3RvcmVzIGxvY2FsaXplZCBtZXNzYWdlcyBmb3IgdGhlIFhlcmNlcyBKQVhQIERhdGF0eXBlIEFQSSBpbXBsZW1lbnRhdGlvbi4KLSMKLSMgVGhlIG1lc3NhZ2VzIGFyZSBhcnJhbmdlZCBpbiBrZXkgYW5kIHZhbHVlIHR1cGxlcyBpbiBhIExpc3RSZXNvdXJjZUJ1bmRsZS4KLSMKLQotQmFkTWVzc2FnZUtleSA9IExlIG1lc3NhZ2UgZCdlcnJldXIgY29ycmVzcG9uZGFudCBcdTAwRTAgbGEgY2xcdTAwRTkgZGUgbWVzc2FnZSBlc3QgaW50cm91dmFibGUuCi1Gb3JtYXRGYWlsZWQgPSBVbmUgZXJyZXVyIGludGVybmUgZXN0IHN1cnZlbnVlIGxvcnMgZHUgZm9ybWF0YWdlIGR1IG1lc3NhZ2Ugc3VpdmFudCA6XG4KLQotRmllbGRDYW5ub3RCZU51bGw9SW1wb3NzaWJsZSBkJydhcHBlbGVyIHswfSBhdmVjIGxlIHBhcmFtXHUwMEU4dHJlICcnbnVsbCcnLgotVW5rbm93bkZpZWxkPXswfSBhIFx1MDBFOXRcdTAwRTkgYXBwZWxcdTAwRTkgYXZlYyB1biBjaGFtcCBpbmNvbm51IDogezF9Ci0jVGhlcmUgYXJlIHR3byBzaW1pbGFyIGtleXMgJ0ludmFsaWRYTUxHcmVvZ29yaWFuQ2FsZW5kYXJWYWx1ZScgLiBTdWZmaXggKHllYXIsIG1vbnRoKSBoYXMgYmVlbiBhZGRlZCBhbmQgYXJlIHVzZWQgYXMgcGVyIHRoZSBjb250ZXh0LgotSW52YWxpZFhHQ1ZhbHVlLW1pbGxpPUFublx1MDBFOWUgPSB7MH0sIE1vaXMgPSB7MX0sIEpvdXIgPSB7Mn0sIEhldXJlID0gezN9LCBNaW51dGUgPSB7NH0sIFNlY29uZGUgPSB7NX0sIEZyYWN0aW9uIGRlIHNlY29uZGUgPSB7Nn0sIEZ1c2VhdSBob3JhaXJlID0gezd9IG5lIHJlcHJcdTAwRTlzZW50ZW50IHBhcyBkZXMgdmFsZXVycyBkZSBjYWxlbmRyaWVyIGdyXHUwMEU5Z29yaWVuIFhNTCB2YWxpZGVzLgotI1RoZXJlIGFyZSB0d28gc2ltaWxhciBrZXlzICdJbnZhbGlkWE1MR3Jlb2dvcmlhbkNhbGVuZGFyVmFsdWUnIC4gU3VmZml4ICh5ZWFyLCBtb250aCkgaGFzIGJlZW4gYWRkZWQgYW5kIGFyZSB1c2VkIGFzIHBlciB0aGUgY29udGV4dC4KLUludmFsaWRYR0NWYWx1ZS1mcmFjdGlvbmFsPUFublx1MDBFOWUgPSB7MH0sIE1vaXMgPSB7MX0sIEpvdXIgPSB7Mn0sIEhldXJlID0gezN9LCBNaW51dGUgPSB7NH0sIFNlY29uZGUgPSB7NX0sIEZyYWN0aW9uIGRlIHNlY29uZGUgPSB7Nn0sIEZ1c2VhdSBob3JhaXJlID0gezd9IG5lIHJlcHJcdTAwRTlzZW50ZW50IHBhcyBkZXMgdmFsZXVycyBkZSBjYWxlbmRyaWVyIGdyXHUwMEU5Z29yaWVuIFhNTCB2YWxpZGVzLgotCi1JbnZhbGlkWEdDRmllbGRzPUVuc2VtYmxlIGRlIGNoYW1wcyBub24gdmFsaWRlIHBvdXIgWE1MR3JlZ29yaWFuQ2FsZW5kYXIKLQotSW52YWxpZEZyYWN0aW9uYWw9VmFsZXVyIG5vbiB2YWxpZGUgezB9IHBvdXIgbGEgZnJhY3Rpb24gZGUgc2Vjb25kZS4KLQotI1hHQyBzdGFuZHMgZm9yIFhNTCBHcmVnb3JpYW4gQ2FsZW5kYXIKLUludmFsaWRYR0NSZXByZXNlbnRhdGlvbj0iezB9IiBuZSByZXByXHUwMEU5c2VudGUgcGFzIHVuZSB2YWxldXIgZGUgY2FsZW5kcmllciBnclx1MDBFOWdvcmllbiBYTUwgdmFsaWRlLgotCi1JbnZhbGlkRmllbGRWYWx1ZT1WYWxldXIgezB9IG5vbiB2YWxpZGUgcG91ciBsZSBjaGFtcCB7MX0uCi0KLU5lZ2F0aXZlRmllbGQ9IExlIGNoYW1wIHswfSBlc3Qgblx1MDBFOWdhdGlmCi0KLUFsbEZpZWxkc051bGw9VG91cyBsZXMgY2hhbXBzIChqYXZheC54bWwuZGF0YXR5cGUuRGF0YXR5cGVDb25zdGFudHMuRmllbGQpIHNvbnQgTlVMTC4KLQotVG9vTGFyZ2U9TGEgdmFsZXVyIHswfSAiezF9IiBlc3QgdHJvcCBcdTAwRTlsZXZcdTAwRTllIHBvdXIgXHUwMEVBdHJlIHByaXNlIGVuIGNoYXJnZSBwYXIgY2V0dGUgaW1wbFx1MDBFOW1lbnRhdGlvbgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvRGF0YXR5cGVNZXNzYWdlc19pdC5wcm9wZXJ0aWVzIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvRGF0YXR5cGVNZXNzYWdlc19pdC5wcm9wZXJ0aWVzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2N2FhOWMzLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL0RhdGF0eXBlTWVzc2FnZXNfaXQucHJvcGVydGllcworKysgL2Rldi9udWxsCkBAIC0xLDI5ICswLDAgQEAKLSMgVGhpcyBmaWxlIHN0b3JlcyBsb2NhbGl6ZWQgbWVzc2FnZXMgZm9yIHRoZSBYZXJjZXMgSkFYUCBEYXRhdHlwZSBBUEkgaW1wbGVtZW50YXRpb24uCi0jCi0jIFRoZSBtZXNzYWdlcyBhcmUgYXJyYW5nZWQgaW4ga2V5IGFuZCB2YWx1ZSB0dXBsZXMgaW4gYSBMaXN0UmVzb3VyY2VCdW5kbGUuCi0jCi0KLUJhZE1lc3NhZ2VLZXkgPSBJbXBvc3NpYmlsZSB0cm92YXJlIGlsIG1lc3NhZ2dpbyBkaSBlcnJvcmUgY29ycmlzcG9uZGVudGUgYWxsYSBjaGlhdmUgZGkgbWVzc2FnZ2lvLgotRm9ybWF0RmFpbGVkID0gU2kgXHUwMEU4IHZlcmlmaWNhdG8gdW4gZXJyb3JlIGludGVybm8gZHVyYW50ZSBsYSBmb3JtYXR0YXppb25lIGRlbCBzZWd1ZW50ZSBtZXNzYWdnaW86XG4KLQotRmllbGRDYW5ub3RCZU51bGw9SW1wb3NzaWJpbGUgcmljaGlhbWFyZSB7MH0gY29uIHVuIHBhcmFtZXRybyAnJ251bGwnJy4KLVVua25vd25GaWVsZD17MH0gcmljaGlhbWF0byBjb24gdW4gY2FtcG8gc2Nvbm9zY2l1dG86ezF9Ci0jVGhlcmUgYXJlIHR3byBzaW1pbGFyIGtleXMgJ0ludmFsaWRYTUxHcmVvZ29yaWFuQ2FsZW5kYXJWYWx1ZScgLiBTdWZmaXggKHllYXIsIG1vbnRoKSBoYXMgYmVlbiBhZGRlZCBhbmQgYXJlIHVzZWQgYXMgcGVyIHRoZSBjb250ZXh0LgotSW52YWxpZFhHQ1ZhbHVlLW1pbGxpPUFubm8gPSB7MH0sIG1lc2UgPSB7MX0sIGdpb3JubyA9IHsyfSwgb3JhID0gezN9LCBtaW51dG8gPSB7NH0sIHNlY29uZG8gPSB7NX0sIGZyYXppb25lIGRpIHNlY29uZG8gPSB7Nn0sIGZ1c28gb3JhcmlvID0gezd9IG5vbiBcdTAwRTggdW5hIHJhcHByZXNlbnRhemlvbmUgdmFsaWRhIGRpIHVuIHZhbG9yZSBkaSBjYWxlbmRhcmlvIGdyZWdvcmlhbm8gWE1MLgotI1RoZXJlIGFyZSB0d28gc2ltaWxhciBrZXlzICdJbnZhbGlkWE1MR3Jlb2dvcmlhbkNhbGVuZGFyVmFsdWUnIC4gU3VmZml4ICh5ZWFyLCBtb250aCkgaGFzIGJlZW4gYWRkZWQgYW5kIGFyZSB1c2VkIGFzIHBlciB0aGUgY29udGV4dC4KLUludmFsaWRYR0NWYWx1ZS1mcmFjdGlvbmFsPUFubm8gPSB7MH0sIG1lc2UgPSB7MX0sIGdpb3JubyA9IHsyfSwgb3JhID0gezN9LCBtaW51dG8gPSB7NH0sIHNlY29uZG8gPSB7NX0sIGZyYXppb25lIGRpIHNlY29uZG8gPSB7Nn0sIGZ1c28gb3JhcmlvID0gezd9IG5vbiBcdTAwRTggdW5hIHJhcHByZXNlbnRhemlvbmUgdmFsaWRhIGRpIHVuIHZhbG9yZSBkaSBjYWxlbmRhcmlvIGdyZWdvcmlhbm8gWE1MLgotCi1JbnZhbGlkWEdDRmllbGRzPUltcG9zdGF0byBzZXQgZGkgY2FtcGkgbm9uIHZhbGlkbyBwZXIgWE1MR3JlZ29yaWFuQ2FsZW5kYXIKLQotSW52YWxpZEZyYWN0aW9uYWw9VmFsb3JlIHswfSBub24gdmFsaWRvIHBlciBsYSBmcmF6aW9uZSBkaSBzZWNvbmRvLgotCi0jWEdDIHN0YW5kcyBmb3IgWE1MIEdyZWdvcmlhbiBDYWxlbmRhcgotSW52YWxpZFhHQ1JlcHJlc2VudGF0aW9uPSJ7MH0iIG5vbiBcdTAwRTggdW5hIHJhcHByZXNlbnRhemlvbmUgdmFsaWRhIGRpIHVuIHZhbG9yZSBkaSBjYWxlbmRhcmlvIGdyZWdvcmlhbm8gWE1MLgotCi1JbnZhbGlkRmllbGRWYWx1ZT1WYWxvcmUgezB9IG5vbiB2YWxpZG8gcGVyIGlsIGNhbXBvIHsxfS4KLQotTmVnYXRpdmVGaWVsZD0gSWwgY2FtcG8gezB9IFx1MDBFOCBuZWdhdGl2bwotCi1BbGxGaWVsZHNOdWxsPVR1dHRpIGkgY2FtcGkgKGphdmF4LnhtbC5kYXRhdHlwZS5EYXRhdHlwZUNvbnN0YW50cy5GaWVsZCkgc29ubyBudWxsaS4KLQotVG9vTGFyZ2U9SWwgdmFsb3JlIHswfSAiezF9IiBcdTAwRTggdHJvcHBvIGdyYW5kZSBwZXIgZXNzZXJlIHN1cHBvcnRhdG8gZGEgcXVlc3RhIGltcGxlbWVudGF6aW9uZQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvRGF0YXR5cGVNZXNzYWdlc19qYS5wcm9wZXJ0aWVzIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvRGF0YXR5cGVNZXNzYWdlc19qYS5wcm9wZXJ0aWVzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4OWUwYzAyLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL0RhdGF0eXBlTWVzc2FnZXNfamEucHJvcGVydGllcworKysgL2Rldi9udWxsCkBAIC0xLDI5ICswLDAgQEAKLSMgVGhpcyBmaWxlIHN0b3JlcyBsb2NhbGl6ZWQgbWVzc2FnZXMgZm9yIHRoZSBYZXJjZXMgSkFYUCBEYXRhdHlwZSBBUEkgaW1wbGVtZW50YXRpb24uCi0jCi0jIFRoZSBtZXNzYWdlcyBhcmUgYXJyYW5nZWQgaW4ga2V5IGFuZCB2YWx1ZSB0dXBsZXMgaW4gYSBMaXN0UmVzb3VyY2VCdW5kbGUuCi0jCi0KLUJhZE1lc3NhZ2VLZXkgPSBcdTMwRTFcdTMwQzNcdTMwQkJcdTMwRkNcdTMwQjhcdTMwRkJcdTMwQURcdTMwRkNcdTMwNkJcdTVCRkVcdTVGRENcdTMwNTlcdTMwOEJcdTMwQThcdTMwRTlcdTMwRkNcdTMwRkJcdTMwRTFcdTMwQzNcdTMwQkJcdTMwRkNcdTMwQjhcdTMwNENcdTg5OEJcdTMwNjRcdTMwNEJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLUZvcm1hdEZhaWxlZCA9IFx1NkIyMVx1MzA2RVx1MzBFMVx1MzBDM1x1MzBCQlx1MzBGQ1x1MzBCOFx1MzA2RVx1NjZGOFx1NUYwRlx1OEEyRFx1NUI5QVx1NEUyRFx1MzA2Qlx1NTE4NVx1OTBFOFx1MzBBOFx1MzBFOVx1MzBGQ1x1MzA0Q1x1NzY3QVx1NzUxRlx1MzA1N1x1MzA3RVx1MzA1N1x1MzA1RjpcbgotCi1GaWVsZENhbm5vdEJlTnVsbD17MH1cdTMwNkYnJ251bGwnJ1x1MzBEMVx1MzBFOVx1MzBFMVx1MzBGQ1x1MzBCRlx1MzA2N1x1MzA2Rlx1NTQ3Q1x1MzA3M1x1NTFGQVx1MzA1Qlx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotVW5rbm93bkZpZWxkPXswfVx1MzA2Rlx1NEUwRFx1NjYwRVx1MzA2QVx1MzBENVx1MzBBM1x1MzBGQ1x1MzBFQlx1MzBDOVx1MzA2N1x1NTQ3Q1x1MzA3M1x1NTFGQVx1MzA1NVx1MzA4Q1x1MzA3RVx1MzA1N1x1MzA1RjogezF9Ci0jVGhlcmUgYXJlIHR3byBzaW1pbGFyIGtleXMgJ0ludmFsaWRYTUxHcmVvZ29yaWFuQ2FsZW5kYXJWYWx1ZScgLiBTdWZmaXggKHllYXIsIG1vbnRoKSBoYXMgYmVlbiBhZGRlZCBhbmQgYXJlIHVzZWQgYXMgcGVyIHRoZSBjb250ZXh0LgotSW52YWxpZFhHQ1ZhbHVlLW1pbGxpPVx1NUU3ND17MH1cdTMwMDFcdTY3MDg9ezF9XHUzMDAxXHU2NUU1PXsyfVx1MzAwMVx1NjY0Mj17M31cdTMwMDFcdTUyMDY9ezR9XHUzMDAxXHU3OUQyPXs1fVx1MzAwMVx1NUMwRlx1NjU3MFx1NzlEMj17Nn1cdTMwMDFcdTMwQkZcdTMwQTRcdTMwRTBcdTMwQkVcdTMwRkNcdTMwRjM9ezd9XHUzMDZGXHUzMDAxWE1MXHUzMEIwXHUzMEVDXHUzMEI0XHUzMEVBXHUzMEFBXHU2NkE2XHUzMDZFXHU1MDI0XHUzMDZFXHU2NzA5XHU1MkI5XHUzMDZBXHU4ODY4XHU3M0ZFXHUzMDY3XHUzMDZGXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0jVGhlcmUgYXJlIHR3byBzaW1pbGFyIGtleXMgJ0ludmFsaWRYTUxHcmVvZ29yaWFuQ2FsZW5kYXJWYWx1ZScgLiBTdWZmaXggKHllYXIsIG1vbnRoKSBoYXMgYmVlbiBhZGRlZCBhbmQgYXJlIHVzZWQgYXMgcGVyIHRoZSBjb250ZXh0LgotSW52YWxpZFhHQ1ZhbHVlLWZyYWN0aW9uYWw9XHU1RTc0PXswfVx1MzAwMVx1NjcwOD17MX1cdTMwMDFcdTY1RTU9ezJ9XHUzMDAxXHU2NjQyPXszfVx1MzAwMVx1NTIwNj17NH1cdTMwMDFcdTc5RDI9ezV9XHUzMDAxXHU1QzBGXHU2NTcwXHU3OUQyPXs2fVx1MzAwMVx1MzBCRlx1MzBBNFx1MzBFMFx1MzBCRVx1MzBGQ1x1MzBGMz17N31cdTMwNkZcdTMwMDFYTUxcdTMwQjBcdTMwRUNcdTMwQjRcdTMwRUFcdTMwQUFcdTY2QTZcdTMwNkVcdTUwMjRcdTMwNkVcdTY3MDlcdTUyQjlcdTMwNkFcdTg4NjhcdTczRkVcdTMwNjdcdTMwNkZcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLQotSW52YWxpZFhHQ0ZpZWxkcz1YTUxHcmVnb3JpYW5DYWxlbmRhclx1MzA2RVx1MzBENVx1MzBBM1x1MzBGQ1x1MzBFQlx1MzBDOVx1MzBGQlx1MzBCQlx1MzBDM1x1MzBDOFx1MzA0Q1x1NzEyMVx1NTJCOVx1MzA2N1x1MzA1OQotCi1JbnZhbGlkRnJhY3Rpb25hbD1cdTVDMEZcdTY1NzBcdTc5RDJcdTMwNkVcdTUwMjR7MH1cdTMwNENcdTcxMjFcdTUyQjlcdTMwNjdcdTMwNTlcdTMwMDIKLQotI1hHQyBzdGFuZHMgZm9yIFhNTCBHcmVnb3JpYW4gQ2FsZW5kYXIKLUludmFsaWRYR0NSZXByZXNlbnRhdGlvbj0iezB9Ilx1MzA2Rlx1MzAwMVhNTFx1MzBCMFx1MzBFQ1x1MzBCNFx1MzBFQVx1MzBBQVx1NjZBNlx1MzA2RVx1NTAyNFx1MzA2RVx1NjcwOVx1NTJCOVx1MzA2QVx1ODg2OFx1NzNGRVx1MzA2N1x1MzA2Rlx1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotCi1JbnZhbGlkRmllbGRWYWx1ZT17MX1cdTMwRDVcdTMwQTNcdTMwRkNcdTMwRUJcdTMwQzlcdTMwNkVcdTUwMjR7MH1cdTMwNENcdTcxMjFcdTUyQjlcdTMwNjdcdTMwNTlcdTMwMDIKLQotTmVnYXRpdmVGaWVsZD0gezB9XHUzMEQ1XHUzMEEzXHUzMEZDXHUzMEVCXHUzMEM5XHUzMDRDXHU4Q0EwXHUzMDY3XHUzMDU5Ci0KLUFsbEZpZWxkc051bGw9XHUzMDU5XHUzMDc5XHUzMDY2XHUzMDZFXHUzMEQ1XHUzMEEzXHUzMEZDXHUzMEVCXHUzMEM5KGphdmF4LnhtbC5kYXRhdHlwZS5EYXRhdHlwZUNvbnN0YW50cy5GaWVsZClcdTMwNENudWxsXHUzMDY3XHUzMDU5XHUzMDAyCi0KLVRvb0xhcmdlPXswfVx1MzA2RVx1NTAyNCJ7MX0iXHUzMDRDXHU1OTI3XHUzMDREXHUzMDU5XHUzMDRFXHUzMDhCXHUzMDVGXHUzMDgxXHUzMDAxXHUzMDUzXHUzMDZFXHU1QjlGXHU4OEM1XHUzMDY3XHUzMDZGXHUzMEI1XHUzMEREXHUzMEZDXHUzMEM4XHUzMDU1XHUzMDhDXHUzMDdFXHUzMDVCXHUzMDkzCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9EYXRhdHlwZU1lc3NhZ2VzX2tvLnByb3BlcnRpZXMgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9EYXRhdHlwZU1lc3NhZ2VzX2tvLnByb3BlcnRpZXMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDdkZmMxYTAuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvRGF0YXR5cGVNZXNzYWdlc19rby5wcm9wZXJ0aWVzCisrKyAvZGV2L251bGwKQEAgLTEsMjkgKzAsMCBAQAotIyBUaGlzIGZpbGUgc3RvcmVzIGxvY2FsaXplZCBtZXNzYWdlcyBmb3IgdGhlIFhlcmNlcyBKQVhQIERhdGF0eXBlIEFQSSBpbXBsZW1lbnRhdGlvbi4KLSMKLSMgVGhlIG1lc3NhZ2VzIGFyZSBhcnJhbmdlZCBpbiBrZXkgYW5kIHZhbHVlIHR1cGxlcyBpbiBhIExpc3RSZXNvdXJjZUJ1bmRsZS4KLSMKLQotQmFkTWVzc2FnZUtleSA9IFx1QkE1NFx1QzJEQ1x1QzlDMCBcdUQwQTRcdUM1RDAgXHVENTc0XHVCMkY5XHVENTU4XHVCMjk0IFx1QzYyNFx1Qjk1OCBcdUJBNTRcdUMyRENcdUM5QzBcdUI5N0MgXHVDQzNFXHVDNzQ0IFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuCi1Gb3JtYXRGYWlsZWQgPSBcdUIyRTRcdUM3NEMgXHVCQTU0XHVDMkRDXHVDOUMwXHVDNzU4IFx1RDYxNVx1QzJERFx1Qzc0NCBcdUM5QzBcdUM4MTVcdUQ1NThcdUIyOTQgXHVDOTExIFx1QjBCNFx1QkQ4MCBcdUM2MjRcdUI5NThcdUFDMDAgXHVCQzFDXHVDMEREXHVENTg4XHVDMkI1XHVCMkM4XHVCMkU0LlxuCi0KLUZpZWxkQ2Fubm90QmVOdWxsPXswfVx1Qzc0MChcdUIyOTQpICcnbnVsbCcnIFx1QjlFNFx1QUMxQ1x1QkNDMFx1QzIxOFx1Qjg1QyBcdUQ2MzhcdUNEOUNcdUQ1NjAgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4KLVVua25vd25GaWVsZD17MH1cdUM3NzQoXHVBQzAwKSBcdUM1NEMgXHVDMjE4IFx1QzVDNlx1QjI5NCBcdUQ1NDRcdUI0RENcdUI4NUMgXHVENjM4XHVDRDlDXHVCNDI4OnsxfQotI1RoZXJlIGFyZSB0d28gc2ltaWxhciBrZXlzICdJbnZhbGlkWE1MR3Jlb2dvcmlhbkNhbGVuZGFyVmFsdWUnIC4gU3VmZml4ICh5ZWFyLCBtb250aCkgaGFzIGJlZW4gYWRkZWQgYW5kIGFyZSB1c2VkIGFzIHBlciB0aGUgY29udGV4dC4KLUludmFsaWRYR0NWYWx1ZS1taWxsaT1cdUM1RjBcdUIzQzQgPSB7MH0sIFx1QzZENCA9IHsxfSwgXHVCMEEwXHVDOURDID0gezJ9LCBcdUMyRENcdUFDMDQgPSB7M30sIFx1QkQ4NCA9IHs0fSwgXHVDRDA4ID0gezV9LCBcdUMxOENcdUMyMThcdUM4MTAgXHVDNzc0XHVENTU4IFx1Q0QwOCA9IHs2fSwgXHVDMkRDXHVBQzA0XHVCMzAwID0gezd9XHVDNzQwKFx1QjI5NCkgWE1MIFx1QzU5MVx1QjgyNSBcdUFDMTJcdUM1RDAgXHVCRDgwXHVDODAxXHVENTY5XHVENTVDIFx1RDYxNVx1QzJERFx1Qzc4NVx1QjJDOFx1QjJFNC4KLSNUaGVyZSBhcmUgdHdvIHNpbWlsYXIga2V5cyAnSW52YWxpZFhNTEdyZW9nb3JpYW5DYWxlbmRhclZhbHVlJyAuIFN1ZmZpeCAoeWVhciwgbW9udGgpIGhhcyBiZWVuIGFkZGVkIGFuZCBhcmUgdXNlZCBhcyBwZXIgdGhlIGNvbnRleHQuCi1JbnZhbGlkWEdDVmFsdWUtZnJhY3Rpb25hbD1cdUM1RjBcdUIzQzQgPSB7MH0sIFx1QzZENCA9IHsxfSwgXHVCMEEwXHVDOURDID0gezJ9LCBcdUMyRENcdUFDMDQgPSB7M30sIFx1QkQ4NCA9IHs0fSwgXHVDRDA4ID0gezV9LCBcdUMxOENcdUMyMThcdUM4MTAgXHVDNzc0XHVENTU4IFx1Q0QwOCA9IHs2fSwgXHVDMkRDXHVBQzA0XHVCMzAwID0gezd9XHVDNzQwKFx1QjI5NCkgWE1MIFx1QzU5MVx1QjgyNSBcdUFDMTJcdUM1RDAgXHVCRDgwXHVDODAxXHVENTY5XHVENTVDIFx1RDYxNVx1QzJERFx1Qzc4NVx1QjJDOFx1QjJFNC4KLQotSW52YWxpZFhHQ0ZpZWxkcz1YTUxHcmVnb3JpYW5DYWxlbmRhclx1QzVEMCBcdUIzMDBcdUQ1NzQgXHVCRDgwXHVDODAxXHVENTY5XHVENTVDIFx1RDU0NFx1QjREQyBcdUM5RDFcdUQ1NjlcdUM3NzQgXHVDMTI0XHVDODE1XHVCNDE4XHVDNUM4XHVDMkI1XHVCMkM4XHVCMkU0LgotCi1JbnZhbGlkRnJhY3Rpb25hbD17MH1cdUM3NDAoXHVCMjk0KSBcdUMxOENcdUMyMThcdUM4MTAgXHVDNzc0XHVENTU4IFx1Q0QwOFx1QzVEMCBcdUIzMDBcdUQ1NzQgXHVCRDgwXHVDODAxXHVENTY5XHVENTVDIFx1QUMxMlx1Qzc4NVx1QjJDOFx1QjJFNC4KLQotI1hHQyBzdGFuZHMgZm9yIFhNTCBHcmVnb3JpYW4gQ2FsZW5kYXIKLUludmFsaWRYR0NSZXByZXNlbnRhdGlvbj0iezB9Ilx1Qzc0MChcdUIyOTQpIFhNTCBcdUM1OTFcdUI4MjUgXHVBQzEyXHVDNUQwIFx1QkQ4MFx1QzgwMVx1RDU2OVx1RDU1QyBcdUQ2MTVcdUMyRERcdUM3ODVcdUIyQzhcdUIyRTQuCi0KLUludmFsaWRGaWVsZFZhbHVlPXswfVx1Qzc0MChcdUIyOTQpIHsxfSBcdUQ1NDRcdUI0RENcdUM1RDAgXHVCMzAwXHVENTc0IFx1QkQ4MFx1QzgwMVx1RDU2OVx1RDU1QyBcdUFDMTJcdUM3ODVcdUIyQzhcdUIyRTQuCi0KLU5lZ2F0aXZlRmllbGQ9IHswfSBcdUQ1NDRcdUI0RENcdUFDMDAgXHVDNzRDXHVDMjE4XHVDNzg1XHVCMkM4XHVCMkU0LgotCi1BbGxGaWVsZHNOdWxsPVx1QkFBOFx1QjRFMCBcdUQ1NDRcdUI0REMoamF2YXgueG1sLmRhdGF0eXBlLkRhdGF0eXBlQ29uc3RhbnRzLkZpZWxkKVx1QUMwMCBcdUIxMTBcdUM3ODVcdUIyQzhcdUIyRTQuCi0KLVRvb0xhcmdlPXswfSBcdUFDMTIgInsxfSJcdUM3NzQoXHVBQzAwKSBcdUM3NzQgXHVBRDZDXHVENjA0XHVDNUQwXHVDMTFDIFx1QzlDMFx1QzZEMFx1QjQxOFx1QjI5NCBcdUFDMTJcdUM1RDAgXHVCRTQ0XHVENTc0IFx1QjEwOFx1QkIzNCBcdUQwN0RcdUIyQzhcdUIyRTQuCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9EYXRhdHlwZU1lc3NhZ2VzX3B0X0JSLnByb3BlcnRpZXMgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9EYXRhdHlwZU1lc3NhZ2VzX3B0X0JSLnByb3BlcnRpZXMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGFkOGQzYjcuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvRGF0YXR5cGVNZXNzYWdlc19wdF9CUi5wcm9wZXJ0aWVzCisrKyAvZGV2L251bGwKQEAgLTEsMjkgKzAsMCBAQAotIyBUaGlzIGZpbGUgc3RvcmVzIGxvY2FsaXplZCBtZXNzYWdlcyBmb3IgdGhlIFhlcmNlcyBKQVhQIERhdGF0eXBlIEFQSSBpbXBsZW1lbnRhdGlvbi4KLSMKLSMgVGhlIG1lc3NhZ2VzIGFyZSBhcnJhbmdlZCBpbiBrZXkgYW5kIHZhbHVlIHR1cGxlcyBpbiBhIExpc3RSZXNvdXJjZUJ1bmRsZS4KLSMKLQotQmFkTWVzc2FnZUtleSA9IE5cdTAwRTNvIGZvaSBwb3NzXHUwMEVEdmVsIGVuY29udHJhciBhIG1lbnNhZ2VtIGRlIGVycm8gY29ycmVzcG9uZGVudGUgXHUwMEUwIGNoYXZlIGRhIG1lbnNhZ2VtLgotRm9ybWF0RmFpbGVkID0gT2NvcnJldSB1bSBlcnJvIGludGVybm8gYW8gZm9ybWF0YXIgYSBtZW5zYWdlbSBhIHNlZ3VpcjpcbgotCi1GaWVsZENhbm5vdEJlTnVsbD17MH0gblx1MDBFM28gcG9kZSBzZXIgY2hhbWFkbyBjb20gbyBwYXJcdTAwRTJtZXRybyAnJ251bGwnJy4KLVVua25vd25GaWVsZD17MH0gY2hhbWFkbyBjb20gdW0gY2FtcG8gZGVzY29uaGVjaWRvOnsxfQotI1RoZXJlIGFyZSB0d28gc2ltaWxhciBrZXlzICdJbnZhbGlkWE1MR3Jlb2dvcmlhbkNhbGVuZGFyVmFsdWUnIC4gU3VmZml4ICh5ZWFyLCBtb250aCkgaGFzIGJlZW4gYWRkZWQgYW5kIGFyZSB1c2VkIGFzIHBlciB0aGUgY29udGV4dC4KLUludmFsaWRYR0NWYWx1ZS1taWxsaT1Bbm8gPSB7MH0sIE1cdTAwRUFzID0gezF9LCBEaWEgPSB7Mn0sIEhvcmEgPSB7M30sIE1pbnV0byA9IHs0fSwgU2VndW5kbyA9IHs1fSwgZnJhY3Rpb25hbFNlY29uZCA9IHs2fSwgRnVzbyBob3JcdTAwRTFyaW8gPSB7N30gLCBuXHUwMEUzbyBcdTAwRTkgdW1hIHJlcHJlc2VudGFcdTAwRTdcdTAwRTNvIHZcdTAwRTFsaWRhIGRlIHVtIHZhbG9yIGRvIENhbGVuZFx1MDBFMXJpbyBHcmVnb3JpYW5vIFhNTC4KLSNUaGVyZSBhcmUgdHdvIHNpbWlsYXIga2V5cyAnSW52YWxpZFhNTEdyZW9nb3JpYW5DYWxlbmRhclZhbHVlJyAuIFN1ZmZpeCAoeWVhciwgbW9udGgpIGhhcyBiZWVuIGFkZGVkIGFuZCBhcmUgdXNlZCBhcyBwZXIgdGhlIGNvbnRleHQuCi1JbnZhbGlkWEdDVmFsdWUtZnJhY3Rpb25hbD1Bbm8gPSB7MH0sIE1cdTAwRUFzID0gezF9LCBEaWEgPSB7Mn0sIEhvcmEgPSB7M30sIE1pbnV0byA9IHs0fSwgU2VndW5kbyA9IHs1fSwgZnJhY3Rpb25hbFNlY29uZCA9IHs2fSwgRnVzbyBob3JcdTAwRTFyaW8gPSB7N30gLCBuXHUwMEUzbyBcdTAwRTkgdW1hIHJlcHJlc2VudGFcdTAwRTdcdTAwRTNvIHZcdTAwRTFsaWRhIGRlIHVtIHZhbG9yIGRvIENhbGVuZFx1MDBFMXJpbyBHcmVnb3JpYW5vIFhNTC4KLQotSW52YWxpZFhHQ0ZpZWxkcz1Db25qdW50byBpbnZcdTAwRTFsaWRvIGRlIGNvbmp1bnRvIGRlIGNhbXBvcyBwYXJhIFhNTEdyZWdvcmlhbkNhbGVuZGFyCi0KLUludmFsaWRGcmFjdGlvbmFsPVZhbG9yIGludlx1MDBFMWxpZG8gezB9IHBhcmEgc2VndW5kbyBmcmFjaW9uYWwuCi0KLSNYR0Mgc3RhbmRzIGZvciBYTUwgR3JlZ29yaWFuIENhbGVuZGFyCi1JbnZhbGlkWEdDUmVwcmVzZW50YXRpb249InswfSIgblx1MDBFM28gXHUwMEU5IHVtYSByZXByZXNlbnRhXHUwMEU3XHUwMEUzbyB2XHUwMEUxbGlkYSBkZSB1bSB2YWxvciBkbyBDYWxlbmRcdTAwRTFyaW8gR3JlZ29yaWFubyBYTUwuCi0KLUludmFsaWRGaWVsZFZhbHVlPVZhbG9yIGludlx1MDBFMWxpZG8gezB9IHBhcmEgbyBjYW1wbyB7MX0uCi0KLU5lZ2F0aXZlRmllbGQ9IG8gY2FtcG8gezB9IFx1MDBFOSBuZWdhdGl2bwotCi1BbGxGaWVsZHNOdWxsPVRvZG9zIG9zIGNhbXBvcyAoamF2YXgueG1sLmRhdGF0eXBlLkRhdGF0eXBlQ29uc3RhbnRzLkZpZWxkKSBzXHUwMEUzbyBudWxvcy4KLQotVG9vTGFyZ2U9dmFsb3IgezB9ICJ7MX0iIG11aXRvIGdyYW5kZSBwYXJhIHNlciBzdXBvcnRhZG8gcG9yIGVzdGEgaW1wbGVtZW50YVx1MDBFN1x1MDBFM28KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL0RhdGF0eXBlTWVzc2FnZXNfc3YucHJvcGVydGllcyBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL0RhdGF0eXBlTWVzc2FnZXNfc3YucHJvcGVydGllcwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZGM3YTE1Ni4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9EYXRhdHlwZU1lc3NhZ2VzX3N2LnByb3BlcnRpZXMKKysrIC9kZXYvbnVsbApAQCAtMSwyOSArMCwwIEBACi0jIFRoaXMgZmlsZSBzdG9yZXMgbG9jYWxpemVkIG1lc3NhZ2VzIGZvciB0aGUgWGVyY2VzIEpBWFAgRGF0YXR5cGUgQVBJIGltcGxlbWVudGF0aW9uLgotIwotIyBUaGUgbWVzc2FnZXMgYXJlIGFycmFuZ2VkIGluIGtleSBhbmQgdmFsdWUgdHVwbGVzIGluIGEgTGlzdFJlc291cmNlQnVuZGxlLgotIwotCi1CYWRNZXNzYWdlS2V5ID0gSGl0dGFyIGludGUgZmVsbWVkZGVsYW5kZXQgc29tIG1vdHN2YXJhciBtZWRkZWxhbmRlbnlja2Vsbi4KLUZvcm1hdEZhaWxlZCA9IEV0dCBpbnRlcm50IGZlbCBpbnRyXHUwMEU0ZmZhZGUgdmlkIGZvcm1hdGVyaW5nIGF2IGZcdTAwRjZsamFuZGUgbWVkZGVsYW5kZTpcbgotCi1GaWVsZENhbm5vdEJlTnVsbD17MH0ga2FuIGludGUgYW5yb3BhcyBtZWQgbnVsbC1wYXJhbWV0ZXIuCi1Vbmtub3duRmllbGQ9ezB9IGFucm9wYWRlcyBtZWQgb2tcdTAwRTRudCBmXHUwMEU0bHQ6ezF9Ci0jVGhlcmUgYXJlIHR3byBzaW1pbGFyIGtleXMgJ0ludmFsaWRYTUxHcmVvZ29yaWFuQ2FsZW5kYXJWYWx1ZScgLiBTdWZmaXggKHllYXIsIG1vbnRoKSBoYXMgYmVlbiBhZGRlZCBhbmQgYXJlIHVzZWQgYXMgcGVyIHRoZSBjb250ZXh0LgotSW52YWxpZFhHQ1ZhbHVlLW1pbGxpPVx1MDBDNXIgPSB7MH0sIG1cdTAwRTVuYWQgPSB7MX0sIGRhZyA9IHsyfSwgdGltbWUgPSB7M30sIG1pbnV0ID0gezR9LCBzZWt1bmQgPSB7NX0sIGJyXHUwMEU1a2RlbHNzZWt1bmQgPSB7Nn0sIHRpZHN6b24gPSB7N30gXHUwMEU0ciBvZ2lsdGlndCB2XHUwMEU0cmRlIGZcdTAwRjZyIGdyZWdvcmlhbnNrIGthbGVuZGVyIGkgWE1MLgotI1RoZXJlIGFyZSB0d28gc2ltaWxhciBrZXlzICdJbnZhbGlkWE1MR3Jlb2dvcmlhbkNhbGVuZGFyVmFsdWUnIC4gU3VmZml4ICh5ZWFyLCBtb250aCkgaGFzIGJlZW4gYWRkZWQgYW5kIGFyZSB1c2VkIGFzIHBlciB0aGUgY29udGV4dC4KLUludmFsaWRYR0NWYWx1ZS1mcmFjdGlvbmFsPVx1MDBDNXIgPSB7MH0sIG1cdTAwRTVuYWQgPSB7MX0sIGRhZyA9IHsyfSwgdGltbWUgPSB7M30sIG1pbnV0ID0gezR9LCBzZWt1bmQgPSB7NX0sIGJyXHUwMEU1a2RlbHNzZWt1bmQgPSB7Nn0sIHRpZHN6b24gPSB7N30gXHUwMEU0ciBvZ2lsdGlndCB2XHUwMEU0cmRlIGZcdTAwRjZyIGdyZWdvcmlhbnNrIGthbGVuZGVyIGkgWE1MLgotCi1JbnZhbGlkWEdDRmllbGRzPU9naWx0aWcgdXBwc1x1MDBFNHR0bmluZyBtZWQgZlx1MDBFNGx0IGFuZ2l2ZXQgaSBYTUxHcmVnb3JpYW5DYWxlbmRhcgotCi1JbnZhbGlkRnJhY3Rpb25hbD1PZ2lsdGlndCB2XHUwMEU0cmRlIHswfSBhbmdpdmV0IGZcdTAwRjZyIGJyXHUwMEU1a2RlbHNzZWt1bmQuCi0KLSNYR0Mgc3RhbmRzIGZvciBYTUwgR3JlZ29yaWFuIENhbGVuZGFyCi1JbnZhbGlkWEdDUmVwcmVzZW50YXRpb249InswfSIgXHUwMEU0ciBvZ2lsdGlndCB2XHUwMEU0cmRlIGZcdTAwRjZyIGdyZWdvcmlhbnNrIGthbGVuZGVyIGkgWE1MLgotCi1JbnZhbGlkRmllbGRWYWx1ZT17MH0gXHUwMEU0ciBldHQgb2dpbHRpZ3Qgdlx1MDBFNHJkZSBpIGZcdTAwRTRsdGV0IHsxfS4KLQotTmVnYXRpdmVGaWVsZD0gRlx1MDBFNGx0ZXQgezB9IFx1MDBFNHIgbmVnYXRpdnQKLQotQWxsRmllbGRzTnVsbD1BbGxhIGZcdTAwRTRsdCAoamF2YXgueG1sLmRhdGF0eXBlLkRhdGF0eXBlQ29uc3RhbnRzLkZpZWxkKSBcdTAwRTRyIG51bGwuCi0KLVRvb0xhcmdlPXswfS12XHUwMEU0cmRldCAiezF9IiBcdTAwRTRyIGZcdTAwRjZyIHN0b3J0IG9jaCBrYW4gaW50ZSBhbnZcdTAwRTRuZGFzIGkgZGVubmEgaW1wbGVtZW50ZXJpbmcKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL0RhdGF0eXBlTWVzc2FnZXNfemhfQ04ucHJvcGVydGllcyBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL0RhdGF0eXBlTWVzc2FnZXNfemhfQ04ucHJvcGVydGllcwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZTVjOGMwYi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9EYXRhdHlwZU1lc3NhZ2VzX3poX0NOLnByb3BlcnRpZXMKKysrIC9kZXYvbnVsbApAQCAtMSwyOSArMCwwIEBACi0jIFRoaXMgZmlsZSBzdG9yZXMgbG9jYWxpemVkIG1lc3NhZ2VzIGZvciB0aGUgWGVyY2VzIEpBWFAgRGF0YXR5cGUgQVBJIGltcGxlbWVudGF0aW9uLgotIwotIyBUaGUgbWVzc2FnZXMgYXJlIGFycmFuZ2VkIGluIGtleSBhbmQgdmFsdWUgdHVwbGVzIGluIGEgTGlzdFJlc291cmNlQnVuZGxlLgotIwotCi1CYWRNZXNzYWdlS2V5ID0gXHU2MjdFXHU0RTBEXHU1MjMwXHU0RTBFXHU2RDg4XHU2MDZGXHU1MTczXHU5NTJFXHU1QjU3XHU1QkY5XHU1RTk0XHU3Njg0XHU5NTE5XHU4QkVGXHU2RDg4XHU2MDZGXHUzMDAyCi1Gb3JtYXRGYWlsZWQgPSBcdThCQkVcdTdGNkVcdTRFRTVcdTRFMEJcdTZEODhcdTYwNkZcdTc2ODRcdTY4M0NcdTVGMEZcdTY1RjZcdTUxRkFcdTczQjBcdTUxODVcdTkwRThcdTk1MTlcdThCRUY6XG4KLQotRmllbGRDYW5ub3RCZU51bGw9XHU2NUUwXHU2Q0Q1XHU0RjdGXHU3NTI4ICcnbnVsbCcnIFx1NTNDMlx1NjU3MFx1OEMwM1x1NzUyOHswfVx1MzAwMgotVW5rbm93bkZpZWxkPVx1NEY3Rlx1NzUyOFx1NjcyQVx1NzdFNVx1NUI1N1x1NkJCNVx1OEMwM1x1NzUyOFx1NEU4NnswfTogezF9Ci0jVGhlcmUgYXJlIHR3byBzaW1pbGFyIGtleXMgJ0ludmFsaWRYTUxHcmVvZ29yaWFuQ2FsZW5kYXJWYWx1ZScgLiBTdWZmaXggKHllYXIsIG1vbnRoKSBoYXMgYmVlbiBhZGRlZCBhbmQgYXJlIHVzZWQgYXMgcGVyIHRoZSBjb250ZXh0LgotSW52YWxpZFhHQ1ZhbHVlLW1pbGxpPVx1NUU3NCA9IHswfSwgXHU2NzA4ID0gezF9LCBcdTY1RTUgPSB7Mn0sIFx1NUMwRlx1NjVGNiA9IHszfSwgXHU1MjA2ID0gezR9LCBcdTc5RDIgPSB7NX0sIFx1NUMwRlx1NjU3MFx1NzlEMiA9IHs2fSwgXHU2NUY2XHU1MzNBID0gezd9IFx1NEUwRFx1NjYyRiBYTUwgXHU2ODNDXHU5MUNDXHU1Mzg2XHU1MDNDXHU3Njg0XHU2NzA5XHU2NTQ4XHU4ODY4XHU3OTNBXHUzMDAyCi0jVGhlcmUgYXJlIHR3byBzaW1pbGFyIGtleXMgJ0ludmFsaWRYTUxHcmVvZ29yaWFuQ2FsZW5kYXJWYWx1ZScgLiBTdWZmaXggKHllYXIsIG1vbnRoKSBoYXMgYmVlbiBhZGRlZCBhbmQgYXJlIHVzZWQgYXMgcGVyIHRoZSBjb250ZXh0LgotSW52YWxpZFhHQ1ZhbHVlLWZyYWN0aW9uYWw9XHU1RTc0ID0gezB9LCBcdTY3MDggPSB7MX0sIFx1NjVFNSA9IHsyfSwgXHU1QzBGXHU2NUY2ID0gezN9LCBcdTUyMDYgPSB7NH0sIFx1NzlEMiA9IHs1fSwgXHU1QzBGXHU2NTcwXHU3OUQyID0gezZ9LCBcdTY1RjZcdTUzM0EgPSB7N30gXHU0RTBEXHU2NjJGIFhNTCBcdTY4M0NcdTkxQ0NcdTUzODZcdTUwM0NcdTc2ODRcdTY3MDlcdTY1NDhcdTg4NjhcdTc5M0FcdTMwMDIKLQotSW52YWxpZFhHQ0ZpZWxkcz1cdTRFM0EgWE1MR3JlZ29yaWFuQ2FsZW5kYXIgXHU4QkJFXHU3RjZFXHU3Njg0XHU1QjU3XHU2QkI1XHU5NkM2XHU2NUUwXHU2NTQ4Ci0KLUludmFsaWRGcmFjdGlvbmFsPVx1NUMwRlx1NjU3MFx1NzlEMlx1NzY4NFx1NTAzQyB7MH0gXHU2NUUwXHU2NTQ4XHUzMDAyCi0KLSNYR0Mgc3RhbmRzIGZvciBYTUwgR3JlZ29yaWFuIENhbGVuZGFyCi1JbnZhbGlkWEdDUmVwcmVzZW50YXRpb249InswfSIgXHU0RTBEXHU2NjJGIFhNTCBcdTY4M0NcdTkxQ0NcdTUzODZcdTUwM0NcdTc2ODRcdTY3MDlcdTY1NDhcdTg4NjhcdTc5M0FcdTMwMDIKLQotSW52YWxpZEZpZWxkVmFsdWU9ezF9XHU1QjU3XHU2QkI1XHU3Njg0XHU1MDNDezB9XHU2NUUwXHU2NTQ4XHUzMDAyCi0KLU5lZ2F0aXZlRmllbGQ9IHswfVx1NUI1N1x1NkJCNVx1NEUzQVx1OEQxRlx1NTAzQwotCi1BbGxGaWVsZHNOdWxsPVx1NjI0MFx1NjcwOVx1NUI1N1x1NkJCNSAoamF2YXgueG1sLmRhdGF0eXBlLkRhdGF0eXBlQ29uc3RhbnRzLkZpZWxkKSBcdTU3NDdcdTRFM0FcdTdBN0FcdTUwM0NcdTMwMDIKLQotVG9vTGFyZ2U9ezB9XHU1MDNDICJ7MX0iIFx1NTkyQVx1NTkyNywgXHU2NUUwXHU2Q0Q1XHU3NTMxXHU2QjY0XHU1QjlFXHU3M0IwXHU2NTJGXHU2MzAxCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9EYXRhdHlwZU1lc3NhZ2VzX3poX1RXLnByb3BlcnRpZXMgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9EYXRhdHlwZU1lc3NhZ2VzX3poX1RXLnByb3BlcnRpZXMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDJjYjdmZmUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvRGF0YXR5cGVNZXNzYWdlc196aF9UVy5wcm9wZXJ0aWVzCisrKyAvZGV2L251bGwKQEAgLTEsMjkgKzAsMCBAQAotIyBUaGlzIGZpbGUgc3RvcmVzIGxvY2FsaXplZCBtZXNzYWdlcyBmb3IgdGhlIFhlcmNlcyBKQVhQIERhdGF0eXBlIEFQSSBpbXBsZW1lbnRhdGlvbi4KLSMKLSMgVGhlIG1lc3NhZ2VzIGFyZSBhcnJhbmdlZCBpbiBrZXkgYW5kIHZhbHVlIHR1cGxlcyBpbiBhIExpc3RSZXNvdXJjZUJ1bmRsZS4KLSMKLQotQmFkTWVzc2FnZUtleSA9IFx1NjI3RVx1NEUwRFx1NTIzMFx1NUMwRFx1NjFDOVx1OEEwQVx1NjA2Rlx1N0QyMlx1NUYxNVx1OTM3NVx1NzY4NFx1OTMyRlx1OEFBNFx1OEEwQVx1NjA2Rlx1MzAwMgotRm9ybWF0RmFpbGVkID0gXHU2ODNDXHU1RjBGXHU1MzE2XHU0RTBCXHU1MjE3XHU4QTBBXHU2MDZGXHU2NjQyXHU3NjdDXHU3NTFGXHU1MTY3XHU5MEU4XHU5MzJGXHU4QUE0OlxuCi0KLUZpZWxkQ2Fubm90QmVOdWxsPVx1NzEyMVx1NkNENVx1NEY3Rlx1NzUyOCAnJ251bGwnJyBcdTUzQzNcdTY1NzhcdTU0N0NcdTUzRUIgezB9Ci1Vbmtub3duRmllbGQ9XHU0RjdGXHU3NTI4XHU0RTBEXHU2NjBFXHU3Njg0XHU2QjA0XHU0RjREXHU1NDdDXHU1M0VCIHswfTp7MX0KLSNUaGVyZSBhcmUgdHdvIHNpbWlsYXIga2V5cyAnSW52YWxpZFhNTEdyZW9nb3JpYW5DYWxlbmRhclZhbHVlJyAuIFN1ZmZpeCAoeWVhciwgbW9udGgpIGhhcyBiZWVuIGFkZGVkIGFuZCBhcmUgdXNlZCBhcyBwZXIgdGhlIGNvbnRleHQuCi1JbnZhbGlkWEdDVmFsdWUtbWlsbGk9XHU1RTc0ID0gezB9XHUzMDAxXHU2NzA4ID0gezF9XHUzMDAxXHU2NUU1ID0gezJ9XHUzMDAxXHU1QzBGXHU2NjQyID0gezN9XHUzMDAxXHU1MjA2XHU5NDE4ID0gezR9XHUzMDAxXHU3OUQyID0gezV9XHUzMDAxXHU1QzBGXHU2NTc4XHU3OUQyID0gezZ9XHUzMDAxXHU2NjQyXHU1MzQwID0gezd9XHVGRjBDXHU0RTBEXHU2NjJGIFhNTCBcdTUxNkNcdTY2QzZcdTUwM0NcdTc2ODRcdTY3MDlcdTY1NDhcdTg4NjhcdTc5M0FcdTZDRDVcdTMwMDIKLSNUaGVyZSBhcmUgdHdvIHNpbWlsYXIga2V5cyAnSW52YWxpZFhNTEdyZW9nb3JpYW5DYWxlbmRhclZhbHVlJyAuIFN1ZmZpeCAoeWVhciwgbW9udGgpIGhhcyBiZWVuIGFkZGVkIGFuZCBhcmUgdXNlZCBhcyBwZXIgdGhlIGNvbnRleHQuCi1JbnZhbGlkWEdDVmFsdWUtZnJhY3Rpb25hbD1cdTVFNzQgPSB7MH1cdTMwMDFcdTY3MDggPSB7MX1cdTMwMDFcdTY1RTUgPSB7Mn1cdTMwMDFcdTVDMEZcdTY2NDIgPSB7M31cdTMwMDFcdTUyMDZcdTk0MTggPSB7NH1cdTMwMDFcdTc5RDIgPSB7NX1cdTMwMDFcdTVDMEZcdTY1NzhcdTc5RDIgPSB7Nn1cdTMwMDFcdTY2NDJcdTUzNDAgPSB7N31cdUZGMENcdTRFMERcdTY2MkYgWE1MIFx1NTE2Q1x1NjZDNlx1NTAzQ1x1NzY4NFx1NjcwOVx1NjU0OFx1ODg2OFx1NzkzQVx1NkNENVx1MzAwMgotCi1JbnZhbGlkWEdDRmllbGRzPVhNTEdyZWdvcmlhbkNhbGVuZGFyIFx1OEEyRFx1NUI5QVx1NEU4Nlx1NzEyMVx1NjU0OFx1NzY4NFx1NkIwNFx1NEY0RFx1OTZDNgotCi1JbnZhbGlkRnJhY3Rpb25hbD1cdTVDMEZcdTY1NzhcdTc5RDJcdTc2ODRcdTUwM0MgezB9IFx1NzEyMVx1NjU0OFx1MzAwMgotCi0jWEdDIHN0YW5kcyBmb3IgWE1MIEdyZWdvcmlhbiBDYWxlbmRhcgotSW52YWxpZFhHQ1JlcHJlc2VudGF0aW9uPSJ7MH0iIFx1NEUwRFx1NjYyRiBYTUwgXHU1MTZDXHU2NkM2XHU1MDNDXHU3Njg0XHU2NzA5XHU2NTQ4XHU4ODY4XHU3OTNBXHU2Q0Q1XHUzMDAyCi0KLUludmFsaWRGaWVsZFZhbHVlPXsxfSBcdTZCMDRcdTRGNERcdTc2ODRcdTUwM0MgezB9IFx1NzEyMVx1NjU0OFx1MzAwMgotCi1OZWdhdGl2ZUZpZWxkPSB7MH0gXHU2QjA0XHU0RjREXHU3MEJBXHU4Q0EwXHU1MDNDCi0KLUFsbEZpZWxkc051bGw9XHU2MjQwXHU2NzA5XHU2QjA0XHU0RjREIChqYXZheC54bWwuZGF0YXR5cGUuRGF0YXR5cGVDb25zdGFudHMuRmllbGQpIFx1NzY4Nlx1NzBCQVx1N0E3QVx1NTAzQ1x1MzAwMgotCi1Ub29MYXJnZT17MH0gXHU1MDNDICJ7MX0iIFx1NTkyQVx1NTkyN1x1RkYwQ1x1NkI2NFx1NUJFNlx1ODg0Q1x1NEUwRFx1NjUyRlx1NjNGNApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvSkFYUFZhbGlkYXRpb25NZXNzYWdlcy5wcm9wZXJ0aWVzIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvSkFYUFZhbGlkYXRpb25NZXNzYWdlcy5wcm9wZXJ0aWVzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4MTJkMTBiLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL0pBWFBWYWxpZGF0aW9uTWVzc2FnZXMucHJvcGVydGllcworKysgL2Rldi9udWxsCkBAIC0xLDI5ICswLDAgQEAKLSMgVGhpcyBmaWxlIHN0b3JlcyBsb2NhbGl6ZWQgbWVzc2FnZXMgZm9yIHRoZSBYZXJjZXMgSkFYUCBWYWxpZGF0aW9uIEFQSSBpbXBsZW1lbnRhdGlvbi4KLSMKLSMgVGhlIG1lc3NhZ2VzIGFyZSBhcnJhbmdlZCBpbiBrZXkgYW5kIHZhbHVlIHR1cGxlcyBpbiBhIExpc3RSZXNvdXJjZUJ1bmRsZS4KLSMKLQotIyBNZXNzYWdlcyBmb3IgbWVzc2FnZSByZXBvcnRpbmcKLUJhZE1lc3NhZ2VLZXkgPSBUaGUgZXJyb3IgbWVzc2FnZSBjb3JyZXNwb25kaW5nIHRvIHRoZSBtZXNzYWdlIGtleSBjYW4gbm90IGJlIGZvdW5kLgotRm9ybWF0RmFpbGVkID0gQW4gaW50ZXJuYWwgZXJyb3Igb2NjdXJyZWQgd2hpbGUgZm9ybWF0dGluZyB0aGUgZm9sbG93aW5nIG1lc3NhZ2U6XG4KLQotIyBTY2hlbWFGYWN0b3J5IGVycm9yIG1lc3NhZ2VzCi1TY2hlbWFMYW5ndWFnZU51bGwgPSBUaGUgc2NoZW1hIGxhbmd1YWdlIHNwZWNpZmllZCBjYW5ub3QgYmUgbnVsbC4KLVNjaGVtYUxhbmd1YWdlTGVuZ3RoWmVybyA9IFRoZSBzY2hlbWEgbGFuZ3VhZ2Ugc3BlY2lmaWVkIGNhbm5vdCBoYXZlIGEgbGVuZ3RoIG9mIHplcm8gY2hhcmFjdGVycy4KLVNjaGVtYVNvdXJjZUFycmF5TnVsbCA9IFRoZSBTb3VyY2UgYXJyYXkgcGFyYW1ldGVyIGNhbm5vdCBiZSBudWxsLgotU2NoZW1hU291cmNlQXJyYXlNZW1iZXJOdWxsID0gVGhlIFNvdXJjZSBhcnJheSBwYXJhbWV0ZXIgY2Fubm90IGNvbnRhaW4gYW55IGl0ZW1zIHRoYXQgYXJlIG51bGwuCi1TY2hlbWFGYWN0b3J5U291cmNlVW5yZWNvZ25pemVkID0gU291cmNlIHBhcmFtZXRlciBvZiB0eXBlICcnezB9JycgaXMgbm90IHJlY29nbml6ZWQgdGhpcyBTY2hlbWFGYWN0b3J5LgotCi0jIFZhbGlkYXRvciBlcnJvciBtZXNzYWdlcwotU291cmNlUGFyYW1ldGVyTnVsbCA9IFNvdXJjZSBwYXJhbWV0ZXIgY2Fubm90IGJlIG51bGwuCi1Tb3VyY2VOb3RBY2NlcHRlZCA9IFNvdXJjZSBwYXJhbWV0ZXIgb2YgdHlwZSAnJ3swfScnIGlzIG5vdCBhY2NlcHRlZCBieSB0aGlzIHZhbGlkYXRvci4KLVNvdXJjZVJlc3VsdE1pc21hdGNoID0gU291cmNlIHBhcmFtZXRlciBvZiB0eXBlICcnezB9JycgaXMgbm90IGNvbXBhdGlibGUgd2l0aCByZXN1bHQgcGFyYW1ldGVyIG9mIHR5cGUgJyd7MX0nJy4KLQotIyBUeXBlSW5mb1Byb3ZpZGVyIGVycm9yIG1lc3NhZ2VzCi1UeXBlSW5mb1Byb3ZpZGVySWxsZWdhbFN0YXRlID0gQSBUeXBlSW5mb1Byb3ZpZGVyIGNhbm5vdCBiZSBxdWVyaWVkIG91dHNpZGUgb2YgYSBzdGFydEVsZW1lbnQgY2FsbGJhY2suCi0KLSMgR2VuZXJhbCBlcnJvciBtZXNzYWdlcwotRmVhdHVyZU5hbWVOdWxsID0gVGhlIGZlYXR1cmUgbmFtZSBjYW5ub3QgYmUgbnVsbC4KLVByb3BlcnlOYW1lTnVsbCA9IFRoZSBwcm9wZXJ0eSBuYW1lIGNhbm5vdCBiZSBudWxsLgotU0FYU291cmNlTnVsbElucHV0U291cmNlID0gVGhlIFNBWFNvdXJjZSBzcGVjaWZpZWQgY29udGFpbnMgbm8gSW5wdXRTb3VyY2UuCi0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL0pBWFBWYWxpZGF0aW9uTWVzc2FnZXNfZGUucHJvcGVydGllcyBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL0pBWFBWYWxpZGF0aW9uTWVzc2FnZXNfZGUucHJvcGVydGllcwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggY2MyMjc0OC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9KQVhQVmFsaWRhdGlvbk1lc3NhZ2VzX2RlLnByb3BlcnRpZXMKKysrIC9kZXYvbnVsbApAQCAtMSwyOSArMCwwIEBACi0jIFRoaXMgZmlsZSBzdG9yZXMgbG9jYWxpemVkIG1lc3NhZ2VzIGZvciB0aGUgWGVyY2VzIEpBWFAgVmFsaWRhdGlvbiBBUEkgaW1wbGVtZW50YXRpb24uCi0jCi0jIFRoZSBtZXNzYWdlcyBhcmUgYXJyYW5nZWQgaW4ga2V5IGFuZCB2YWx1ZSB0dXBsZXMgaW4gYSBMaXN0UmVzb3VyY2VCdW5kbGUuCi0jCi0KLSMgTWVzc2FnZXMgZm9yIG1lc3NhZ2UgcmVwb3J0aW5nCi1CYWRNZXNzYWdlS2V5ID0gRGllIHp1bSBNZWxkdW5nc3NjaGxcdTAwRkNzc2VsIGdlaFx1MDBGNnJpZ2UgRmVobGVybWVsZHVuZyBrYW5uIG5pY2h0IGdlZnVuZGVuIHdlcmRlbi4KLUZvcm1hdEZhaWxlZCA9IEJlaW0gRm9ybWF0aWVyZW4gZGVyIGZvbGdlbmRlbiBNZWxkdW5nIGlzdCBlaW4gaW50ZXJuZXIgRmVobGVyIGF1ZmdldHJldGVuOlxuCi0KLSMgU2NoZW1hRmFjdG9yeSBlcnJvciBtZXNzYWdlcwotU2NoZW1hTGFuZ3VhZ2VOdWxsID0gQW5nZWdlYmVuZSBTY2hlbWFzcHJhY2hlIGRhcmYgbmljaHQgbnVsbCBzZWluLgotU2NoZW1hTGFuZ3VhZ2VMZW5ndGhaZXJvID0gQW5nZWdlYmVuZSBTY2hlbWFzcHJhY2hlIGRhcmYgbmljaHQgbnVsbCBaZWljaGVuIGxhbmcgc2Vpbi4KLVNjaGVtYVNvdXJjZUFycmF5TnVsbCA9IFF1ZWxsYXJyYXlwYXJhbWV0ZXIgZGFyZiBuaWNodCBudWxsIHNlaW4uCi1TY2hlbWFTb3VyY2VBcnJheU1lbWJlck51bGwgPSBRdWVsbGFycmF5cGFyYW1ldGVyIGRhcmYga2VpbmUgTnVsbGVsZW1lbnRlIGVudGhhbHRlbi4KLVNjaGVtYUZhY3RvcnlTb3VyY2VVbnJlY29nbml6ZWQgPSBRdWVsbHBhcmFtZXRlciBkZXMgVHlwcyAiezB9IiBpc3QgaW4gZGllc2VyIFNjaGVtYUZhY3RvcnkgdW5iZWthbm50LgotCi0jIFZhbGlkYXRvciBlcnJvciBtZXNzYWdlcwotU291cmNlUGFyYW1ldGVyTnVsbCA9IFF1ZWxscGFyYW1ldGVyIGRhcmYgbmljaHQgbnVsbCBzZWluLgotU291cmNlTm90QWNjZXB0ZWQgPSBRdWVsbHBhcmFtZXRlciBkZXMgVHlwcyAiezB9IiB3aXJkIHZvbiBkaWVzZW0gVmFsaWRhdG9yIG5pY2h0IGFremVwdGllcnQuCi1Tb3VyY2VSZXN1bHRNaXNtYXRjaCA9IFF1ZWxscGFyYW1ldGVyIGRlcyBUeXBzICJ7MH0iIGlzdCBuaWNodCBtaXQgZGVtIEVyZ2VibmlzcGFyYW1ldGVyIGRlcyBUeXBzICJ7MX0iIGtvbXBhdGliZWwuCi0KLSMgVHlwZUluZm9Qcm92aWRlciBlcnJvciBtZXNzYWdlcwotVHlwZUluZm9Qcm92aWRlcklsbGVnYWxTdGF0ZSA9IFR5cGVJbmZvUHJvdmlkZXIga2FubiBuaWNodCBhdVx1MDBERmVyaGFsYiBlaW5lcyBzdGFydEVsZW1lbnQtUlx1MDBGQ2NrcnVmcyBhYmdlZnJhZ3Qgd2VyZGVuLgotCi0jIEdlbmVyYWwgZXJyb3IgbWVzc2FnZXMKLUZlYXR1cmVOYW1lTnVsbCA9IEZlYXR1cmVuYW1lIGRhcmYgbmljaHQgbnVsbCBzZWluLgotUHJvcGVyeU5hbWVOdWxsID0gRWlnZW5zY2hhZnRzbmFtZSBkYXJmIG5pY2h0IG51bGwgc2Vpbi4KLVNBWFNvdXJjZU51bGxJbnB1dFNvdXJjZSA9IEFuZ2VnZWJlbmUgU0FYU291cmNlIGVudGhcdTAwRTRsdCBrZWluZSBJbnB1dFNvdXJjZS4KLQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvSkFYUFZhbGlkYXRpb25NZXNzYWdlc19lcy5wcm9wZXJ0aWVzIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvSkFYUFZhbGlkYXRpb25NZXNzYWdlc19lcy5wcm9wZXJ0aWVzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzNzk4YTIyLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL0pBWFBWYWxpZGF0aW9uTWVzc2FnZXNfZXMucHJvcGVydGllcworKysgL2Rldi9udWxsCkBAIC0xLDI5ICswLDAgQEAKLSMgVGhpcyBmaWxlIHN0b3JlcyBsb2NhbGl6ZWQgbWVzc2FnZXMgZm9yIHRoZSBYZXJjZXMgSkFYUCBWYWxpZGF0aW9uIEFQSSBpbXBsZW1lbnRhdGlvbi4KLSMKLSMgVGhlIG1lc3NhZ2VzIGFyZSBhcnJhbmdlZCBpbiBrZXkgYW5kIHZhbHVlIHR1cGxlcyBpbiBhIExpc3RSZXNvdXJjZUJ1bmRsZS4KLSMKLQotIyBNZXNzYWdlcyBmb3IgbWVzc2FnZSByZXBvcnRpbmcKLUJhZE1lc3NhZ2VLZXkgPSBObyBzZSBoYSBlbmNvbnRyYWRvIGVsIG1lbnNhamUgZGUgZXJyb3IgY29ycmVzcG9uZGllbnRlIGEgbGEgY2xhdmUgZGUgbWVuc2FqZS4KLUZvcm1hdEZhaWxlZCA9IFNlIGhhIHByb2R1Y2lkbyB1biBlcnJvciBpbnRlcm5vIGFsIGZvcm1hdGVhciBlbCBzaWd1aWVudGUgbWVuc2FqZTpcbgotCi0jIFNjaGVtYUZhY3RvcnkgZXJyb3IgbWVzc2FnZXMKLVNjaGVtYUxhbmd1YWdlTnVsbCA9IEVsIGlkaW9tYSBkZWwgZXNxdWVtYSBlc3BlY2lmaWNhZG8gbm8gcHVlZGUgc2VyIG51bG8uCi1TY2hlbWFMYW5ndWFnZUxlbmd0aFplcm8gPSBFbCBpZGlvbWEgZGVsIGVzcXVlbWEgZXNwZWNpZmljYWRvIG5vIHB1ZWRlIHRlbmVyIHVuYSBsb25naXR1ZCBkZSBjZXJvIGNhcmFjdGVyZXMuCi1TY2hlbWFTb3VyY2VBcnJheU51bGwgPSBFbCBwYXJcdTAwRTFtZXRybyBkZSBtYXRyaXogZGUgb3JpZ2VuIG5vIHB1ZWRlIHNlciBudWxvLgotU2NoZW1hU291cmNlQXJyYXlNZW1iZXJOdWxsID0gRWwgcGFyXHUwMEUxbWV0cm8gZGUgbWF0cml6IGRlIG9yaWdlbiBubyBwdWVkZSBjb250ZW5lciBuaW5nXHUwMEZBbiBlbGVtZW50byBxdWUgc2VhIG51bG8uCi1TY2hlbWFGYWN0b3J5U291cmNlVW5yZWNvZ25pemVkID0gRXN0ZSBTY2hlbWFGYWN0b3J5IG5vIHJlY29ub2NlIGVsIHBhclx1MDBFMW1ldHJvIGRlIG9yaWdlbiBkZWwgdGlwbyAnJ3swfScnLgotCi0jIFZhbGlkYXRvciBlcnJvciBtZXNzYWdlcwotU291cmNlUGFyYW1ldGVyTnVsbCA9IEVsIHBhclx1MDBFMW1ldHJvIGRlIG9yaWdlbiBubyBwdWVkZSBzZXIgbnVsby4KLVNvdXJjZU5vdEFjY2VwdGVkID0gRXN0ZSB2YWxpZGFkb3Igbm8gYWNlcHRhIGVsIHBhclx1MDBFMW1ldHJvIGRlIG9yaWdlbiBkZWwgdGlwbyAnJ3swfScnLgotU291cmNlUmVzdWx0TWlzbWF0Y2ggPSBFbCBwYXJcdTAwRTFtZXRybyBkZSBvcmlnZW4gZGVsIHRpcG8gJyd7MH0nJyBubyBlcyBjb21wYXRpYmxlIGNvbiBlbCBwYXJcdTAwRTFtZXRybyBkZSByZXN1bHRhZG8gZGVsIHRpcG8gJyd7MX0nJy4KLQotIyBUeXBlSW5mb1Byb3ZpZGVyIGVycm9yIG1lc3NhZ2VzCi1UeXBlSW5mb1Byb3ZpZGVySWxsZWdhbFN0YXRlID0gVW4gVHlwZUluZm9Qcm92aWRlciBubyBwdWVkZSBjb25zdWx0YXJzZSBmdWVyYSBkZSB1bmEgZGV2b2x1Y2lcdTAwRjNuIGRlIGxsYW1hZGEgZGUgc3RhcnRFbGVtZW50LgotCi0jIEdlbmVyYWwgZXJyb3IgbWVzc2FnZXMKLUZlYXR1cmVOYW1lTnVsbCA9IEVsIG5vbWJyZSBkZSBsYSBmdW5jaVx1MDBGM24gbm8gcHVlZGUgc2VyIG51bG8uCi1Qcm9wZXJ5TmFtZU51bGwgPSBFbCBub21icmUgZGUgbGEgcHJvcGllZGFkIG5vIHB1ZWRlIHNlciBudWxvLgotU0FYU291cmNlTnVsbElucHV0U291cmNlID0gRWwgU0FYU291cmNlIGVzcGVjaWZpY2FkbyBubyBjb250aWVuZSBuaW5nXHUwMEZBbiB2YWxvciBkZSBJbnB1dFNvdXJjZS4KLQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvSkFYUFZhbGlkYXRpb25NZXNzYWdlc19mci5wcm9wZXJ0aWVzIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvSkFYUFZhbGlkYXRpb25NZXNzYWdlc19mci5wcm9wZXJ0aWVzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmYWUyZmNlLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL0pBWFBWYWxpZGF0aW9uTWVzc2FnZXNfZnIucHJvcGVydGllcworKysgL2Rldi9udWxsCkBAIC0xLDI5ICswLDAgQEAKLSMgVGhpcyBmaWxlIHN0b3JlcyBsb2NhbGl6ZWQgbWVzc2FnZXMgZm9yIHRoZSBYZXJjZXMgSkFYUCBWYWxpZGF0aW9uIEFQSSBpbXBsZW1lbnRhdGlvbi4KLSMKLSMgVGhlIG1lc3NhZ2VzIGFyZSBhcnJhbmdlZCBpbiBrZXkgYW5kIHZhbHVlIHR1cGxlcyBpbiBhIExpc3RSZXNvdXJjZUJ1bmRsZS4KLSMKLQotIyBNZXNzYWdlcyBmb3IgbWVzc2FnZSByZXBvcnRpbmcKLUJhZE1lc3NhZ2VLZXkgPSBMZSBtZXNzYWdlIGQnZXJyZXVyIGNvcnJlc3BvbmRhbnQgXHUwMEUwIGxhIGNsXHUwMEU5IGRlIG1lc3NhZ2UgZXN0IGludHJvdXZhYmxlLgotRm9ybWF0RmFpbGVkID0gVW5lIGVycmV1ciBpbnRlcm5lIGVzdCBzdXJ2ZW51ZSBsb3JzIGR1IGZvcm1hdGFnZSBkdSBtZXNzYWdlIHN1aXZhbnQgOlxuCi0KLSMgU2NoZW1hRmFjdG9yeSBlcnJvciBtZXNzYWdlcwotU2NoZW1hTGFuZ3VhZ2VOdWxsID0gTGEgbGFuZ3VlIGRlIHNjaFx1MDBFOW1hIGluZGlxdVx1MDBFOWUgbmUgcGV1dCBwYXMgXHUwMEVBdHJlIE5VTEwuCi1TY2hlbWFMYW5ndWFnZUxlbmd0aFplcm8gPSBMYSBsb25ndWV1ciBkZSBsYSBsYW5ndWUgZGUgc2NoXHUwMEU5bWEgaW5kaXF1XHUwMEU5ZSBuZSBwZXV0IFx1MDBFQXRyZSBkZSB6XHUwMEU5cm8gY2FyYWN0XHUwMEU4cmUuCi1TY2hlbWFTb3VyY2VBcnJheU51bGwgPSBMZSBwYXJhbVx1MDBFOHRyZSBkZSB0YWJsZWF1IHNvdXJjZSBuZSBwZXV0IHBhcyBcdTAwRUF0cmUgTlVMTC4KLVNjaGVtYVNvdXJjZUFycmF5TWVtYmVyTnVsbCA9IExlIHBhcmFtXHUwMEU4dHJlIGRlIHRhYmxlYXUgc291cmNlIG5lIHBldXQgcGFzIGNvbnRlbmlyIGQnXHUwMEU5bFx1MDBFOW1lbnQgTlVMTC4KLVNjaGVtYUZhY3RvcnlTb3VyY2VVbnJlY29nbml6ZWQgPSBMZSBwYXJhbVx1MDBFOHRyZSBzb3VyY2UgZGUgdHlwZSAnJ3swfScnIG4nJ2VzdCBwYXMgcmVjb25udSBwYXIgY2V0IFx1MDBFOWxcdTAwRTltZW50IFNjaGVtYUZhY3RvcnkuCi0KLSMgVmFsaWRhdG9yIGVycm9yIG1lc3NhZ2VzCi1Tb3VyY2VQYXJhbWV0ZXJOdWxsID0gTGUgcGFyYW1cdTAwRTh0cmUgc291cmNlIG5lIHBldXQgcGFzIFx1MDBFQXRyZSBOVUxMLgotU291cmNlTm90QWNjZXB0ZWQgPSBMZSBwYXJhbVx1MDBFOHRyZSBzb3VyY2UgZGUgdHlwZSAnJ3swfScnIG4nJ2VzdCBwYXMgYWNjZXB0XHUwMEU5IHBhciBjZSB2YWxpZGV1ci4KLVNvdXJjZVJlc3VsdE1pc21hdGNoID0gTGUgcGFyYW1cdTAwRTh0cmUgc291cmNlIGRlIHR5cGUgJyd7MH0nJyBuJydlc3QgcGFzIGNvbXBhdGlibGUgYXZlYyBsZSBwYXJhbVx1MDBFOHRyZSBkZSByXHUwMEU5c3VsdGF0IGRlIHR5cGUgJyd7MX0nJy4KLQotIyBUeXBlSW5mb1Byb3ZpZGVyIGVycm9yIG1lc3NhZ2VzCi1UeXBlSW5mb1Byb3ZpZGVySWxsZWdhbFN0YXRlID0gVW4gXHUwMEU5bFx1MDBFOW1lbnQgVHlwZUluZm9Qcm92aWRlciBuZSBwZXV0IHBhcyBcdTAwRUF0cmUgaW50ZXJyb2dcdTAwRTkgZW4gZGVob3JzIGQndW4gY2FsbGJhY2sgc3RhcnRFbGVtZW50LgotCi0jIEdlbmVyYWwgZXJyb3IgbWVzc2FnZXMKLUZlYXR1cmVOYW1lTnVsbCA9IExlIG5vbSBkZSBmb25jdGlvbm5hbGl0XHUwMEU5IG5lIHBldXQgcGFzIFx1MDBFQXRyZSBOVUxMLgotUHJvcGVyeU5hbWVOdWxsID0gTGUgbm9tIGRlIHByb3ByaVx1MDBFOXRcdTAwRTkgbmUgcGV1dCBwYXMgXHUwMEVBdHJlIE5VTEwuCi1TQVhTb3VyY2VOdWxsSW5wdXRTb3VyY2UgPSBMJ1x1MDBFOWxcdTAwRTltZW50IFNBWFNvdXJjZSBpbmRpcXVcdTAwRTkgbmUgY29udGllbnQgYXVjdW4gXHUwMEU5bFx1MDBFOW1lbnQgSW5wdXRTb3VyY2UuCi0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL0pBWFBWYWxpZGF0aW9uTWVzc2FnZXNfaXQucHJvcGVydGllcyBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL0pBWFBWYWxpZGF0aW9uTWVzc2FnZXNfaXQucHJvcGVydGllcwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYzc2NDViOC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9KQVhQVmFsaWRhdGlvbk1lc3NhZ2VzX2l0LnByb3BlcnRpZXMKKysrIC9kZXYvbnVsbApAQCAtMSwyOSArMCwwIEBACi0jIFRoaXMgZmlsZSBzdG9yZXMgbG9jYWxpemVkIG1lc3NhZ2VzIGZvciB0aGUgWGVyY2VzIEpBWFAgVmFsaWRhdGlvbiBBUEkgaW1wbGVtZW50YXRpb24uCi0jCi0jIFRoZSBtZXNzYWdlcyBhcmUgYXJyYW5nZWQgaW4ga2V5IGFuZCB2YWx1ZSB0dXBsZXMgaW4gYSBMaXN0UmVzb3VyY2VCdW5kbGUuCi0jCi0KLSMgTWVzc2FnZXMgZm9yIG1lc3NhZ2UgcmVwb3J0aW5nCi1CYWRNZXNzYWdlS2V5ID0gSW1wb3NzaWJpbGUgdHJvdmFyZSBpbCBtZXNzYWdnaW8gZGkgZXJyb3JlIGNvcnJpc3BvbmRlbnRlIGFsbGEgY2hpYXZlIGRpIG1lc3NhZ2dpby4KLUZvcm1hdEZhaWxlZCA9IFNpIFx1MDBFOCB2ZXJpZmljYXRvIHVuIGVycm9yZSBpbnRlcm5vIGR1cmFudGUgbGEgZm9ybWF0dGF6aW9uZSBkZWwgc2VndWVudGUgbWVzc2FnZ2lvOlxuCi0KLSMgU2NoZW1hRmFjdG9yeSBlcnJvciBtZXNzYWdlcwotU2NoZW1hTGFuZ3VhZ2VOdWxsID0gTGEgbGluZ3VhIGRlbGxvIHNjaGVtYSBzcGVjaWZpY2F0YSBub24gcHVcdTAwRjIgZXNzZXJlIG51bGxhLgotU2NoZW1hTGFuZ3VhZ2VMZW5ndGhaZXJvID0gTGEgbGluZ3VhIGRlbGxvIHNjaGVtYSBzcGVjaWZpY2F0YSBub24gcHVcdTAwRjIgYXZlcmUgdW5hIGx1bmdoZXp6YSBkaSB6ZXJvIGNhcmF0dGVyaS4KLVNjaGVtYVNvdXJjZUFycmF5TnVsbCA9IElsIHBhcmFtZXRybyBkaSBhcnJheSBkaSBvcmlnaW5lIG5vbiBwdVx1MDBGMiBlc3NlcmUgbnVsbG8uCi1TY2hlbWFTb3VyY2VBcnJheU1lbWJlck51bGwgPSBJbCBwYXJhbWV0cm8gZGkgYXJyYXkgZGkgb3JpZ2luZSBub24gcHVcdTAwRjIgY29udGVuZXJlIGVsZW1lbnRpIG51bGxpLgotU2NoZW1hRmFjdG9yeVNvdXJjZVVucmVjb2duaXplZCA9IElsIHBhcmFtZXRybyBkaSBvcmlnaW5lIGRpIHRpcG8gJyd7MH0nJyBub24gXHUwMEU4IHJpY29ub3NjaXV0byBpbiBxdWVzdG8gU2NoZW1hRmFjdG9yeS4KLQotIyBWYWxpZGF0b3IgZXJyb3IgbWVzc2FnZXMKLVNvdXJjZVBhcmFtZXRlck51bGwgPSBJbCBwYXJhbWV0cm8gZGkgb3JpZ2luZSBub24gcHVcdTAwRjIgZXNzZXJlIG51bGxvLgotU291cmNlTm90QWNjZXB0ZWQgPSBJbCBwYXJhbWV0cm8gZGkgb3JpZ2luZSBkaSB0aXBvICcnezB9Jycgbm9uIFx1MDBFOCBhY2NldHRhdG8gZGEgcXVlc3RvIHZhbGlkYXRvci4KLVNvdXJjZVJlc3VsdE1pc21hdGNoID0gSWwgcGFyYW1ldHJvIGRpIG9yaWdpbmUgZGkgdGlwbyAnJ3swfScnIG5vbiBcdTAwRTggY29tcGF0aWJpbGUgY29uIGlsIHBhcmFtZXRybyBkZWkgcmlzdWx0YXRpIGRpIHRpcG8gJyd7MX0nJy4KLQotIyBUeXBlSW5mb1Byb3ZpZGVyIGVycm9yIG1lc3NhZ2VzCi1UeXBlSW5mb1Byb3ZpZGVySWxsZWdhbFN0YXRlID0gSW1wb3NzaWJpbGUgZXNlZ3VpcmUgdW5hIHF1ZXJ5IHN1IFR5cGVJbmZvUHJvdmlkZXIgYWwgZGkgZnVvcmkgZGkgdW4gY2FsbGJhY2sgc3RhcnRFbGVtZW50LgotCi0jIEdlbmVyYWwgZXJyb3IgbWVzc2FnZXMKLUZlYXR1cmVOYW1lTnVsbCA9IElsIG5vbWUgZnVuemlvbmUgbm9uIHB1XHUwMEYyIGVzc2VyZSBudWxsby4KLVByb3BlcnlOYW1lTnVsbCA9IElsIG5vbWUgcHJvcHJpZXRcdTAwRTAgbm9uIHB1XHUwMEYyIGVzc2VyZSBudWxsby4KLVNBWFNvdXJjZU51bGxJbnB1dFNvdXJjZSA9IElsIHZhbG9yZSBzcGVjaWZpY2F0byBwZXIgU0FYU291cmNlIG5vbiBjb250aWVuZSBJbnB1dFNvdXJjZS4KLQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvSkFYUFZhbGlkYXRpb25NZXNzYWdlc19qYS5wcm9wZXJ0aWVzIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvSkFYUFZhbGlkYXRpb25NZXNzYWdlc19qYS5wcm9wZXJ0aWVzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxODk0NjA2Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL0pBWFBWYWxpZGF0aW9uTWVzc2FnZXNfamEucHJvcGVydGllcworKysgL2Rldi9udWxsCkBAIC0xLDI5ICswLDAgQEAKLSMgVGhpcyBmaWxlIHN0b3JlcyBsb2NhbGl6ZWQgbWVzc2FnZXMgZm9yIHRoZSBYZXJjZXMgSkFYUCBWYWxpZGF0aW9uIEFQSSBpbXBsZW1lbnRhdGlvbi4KLSMKLSMgVGhlIG1lc3NhZ2VzIGFyZSBhcnJhbmdlZCBpbiBrZXkgYW5kIHZhbHVlIHR1cGxlcyBpbiBhIExpc3RSZXNvdXJjZUJ1bmRsZS4KLSMKLQotIyBNZXNzYWdlcyBmb3IgbWVzc2FnZSByZXBvcnRpbmcKLUJhZE1lc3NhZ2VLZXkgPSBcdTMwRTFcdTMwQzNcdTMwQkJcdTMwRkNcdTMwQjhcdTMwRkJcdTMwQURcdTMwRkNcdTMwNkJcdTVCRkVcdTVGRENcdTMwNTlcdTMwOEJcdTMwQThcdTMwRTlcdTMwRkNcdTMwRkJcdTMwRTFcdTMwQzNcdTMwQkJcdTMwRkNcdTMwQjhcdTMwNENcdTg5OEJcdTMwNjRcdTMwNEJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLUZvcm1hdEZhaWxlZCA9IFx1NkIyMVx1MzA2RVx1MzBFMVx1MzBDM1x1MzBCQlx1MzBGQ1x1MzBCOFx1MzA2RVx1NjZGOFx1NUYwRlx1OEEyRFx1NUI5QVx1NEUyRFx1MzA2Qlx1NTE4NVx1OTBFOFx1MzBBOFx1MzBFOVx1MzBGQ1x1MzA0Q1x1NzY3QVx1NzUxRlx1MzA1N1x1MzA3RVx1MzA1N1x1MzA1RjpcbgotCi0jIFNjaGVtYUZhY3RvcnkgZXJyb3IgbWVzc2FnZXMKLVNjaGVtYUxhbmd1YWdlTnVsbCA9IFx1NjMwN1x1NUI5QVx1MzA1N1x1MzA1Rlx1MzBCOVx1MzBBRFx1MzBGQ1x1MzBERVx1OEEwMFx1OEE5RVx1MzA2Rm51bGxcdTMwNkJcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLVNjaGVtYUxhbmd1YWdlTGVuZ3RoWmVybyA9IFx1NjMwN1x1NUI5QVx1MzA1N1x1MzA1Rlx1MzBCOVx1MzBBRFx1MzBGQ1x1MzBERVx1OEEwMFx1OEE5RVx1MzA2RVx1OTU3N1x1MzA1NVx1MzA2Rlx1MzBCQ1x1MzBFRFx1NjU4N1x1NUI1N1x1MzA2Qlx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotU2NoZW1hU291cmNlQXJyYXlOdWxsID0gU291cmNlXHU5MTREXHU1MjE3XHUzMEQxXHUzMEU5XHUzMEUxXHUzMEZDXHUzMEJGXHUzMDZGbnVsbFx1MzA2Qlx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotU2NoZW1hU291cmNlQXJyYXlNZW1iZXJOdWxsID0gU291cmNlXHU5MTREXHU1MjE3XHUzMEQxXHUzMEU5XHUzMEUxXHUzMEZDXHUzMEJGXHUzMDZCXHUzMDZGXHUzMDAxbnVsbFx1MzA2RVx1MzBBMlx1MzBBNFx1MzBDNlx1MzBFMFx1MzA5Mlx1NTQyQlx1MzA4MVx1MzA4Qlx1MzA1M1x1MzA2OFx1MzA2Rlx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotU2NoZW1hRmFjdG9yeVNvdXJjZVVucmVjb2duaXplZCA9IFx1MzBCRlx1MzBBNFx1MzBENycnezB9JydcdTMwNkVTb3VyY2VcdTMwRDFcdTMwRTlcdTMwRTFcdTMwRkNcdTMwQkZcdTMwNkZcdTMwMDFcdTMwNTNcdTMwNkVTY2hlbWFGYWN0b3J5XHUzMDY3XHUzMDZGXHU4QThEXHU4QjU4XHUzMDU1XHUzMDhDXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0KLSMgVmFsaWRhdG9yIGVycm9yIG1lc3NhZ2VzCi1Tb3VyY2VQYXJhbWV0ZXJOdWxsID0gU291cmNlXHUzMEQxXHUzMEU5XHUzMEUxXHUzMEZDXHUzMEJGXHUzMDZGbnVsbFx1MzA2Qlx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotU291cmNlTm90QWNjZXB0ZWQgPSBcdTMwQkZcdTMwQTRcdTMwRDcnJ3swfScnXHUzMDZFU291cmNlXHUzMEQxXHUzMEU5XHUzMEUxXHUzMEZDXHUzMEJGXHUzMDZGXHUzMDAxXHUzMDUzXHUzMDZFXHUzMEQwXHUzMEVBXHUzMEM3XHUzMEZDXHUzMEJGXHUzMDY3XHUzMDZGXHU0RjdGXHU3NTI4XHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi1Tb3VyY2VSZXN1bHRNaXNtYXRjaCA9IFx1MzBCRlx1MzBBNFx1MzBENycnezB9JydcdTMwNkVTb3VyY2VcdTMwRDFcdTMwRTlcdTMwRTFcdTMwRkNcdTMwQkZcdTMwNkZcdTMwMDFcdTMwQkZcdTMwQTRcdTMwRDcnJ3sxfScnXHUzMDZFXHU3RDUwXHU2NzlDXHUzMEQxXHUzMEU5XHUzMEUxXHUzMEZDXHUzMEJGXHUzMDY4XHU0RTkyXHU2M0RCXHU2MDI3XHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0KLSMgVHlwZUluZm9Qcm92aWRlciBlcnJvciBtZXNzYWdlcwotVHlwZUluZm9Qcm92aWRlcklsbGVnYWxTdGF0ZSA9IFR5cGVJbmZvUHJvdmlkZXJcdTMwNkZcdTMwMDFzdGFydEVsZW1lbnRcdTMwQjNcdTMwRkNcdTMwRUJcdTMwRDBcdTMwQzNcdTMwQUZcdTMwNkVcdTU5MTZcdTMwNjdcdTU1NEZcdTMwNDRcdTU0MDhcdTMwNUJcdTMwOEJcdTMwNTNcdTMwNjhcdTMwNkZcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLQotIyBHZW5lcmFsIGVycm9yIG1lc3NhZ2VzCi1GZWF0dXJlTmFtZU51bGwgPSBcdTZBNUZcdTgwRkRcdTU0MERcdTMwNkZudWxsXHUzMDZCXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi1Qcm9wZXJ5TmFtZU51bGwgPSBcdTMwRDdcdTMwRURcdTMwRDFcdTMwQzZcdTMwQTNcdTU0MERcdTMwNkZudWxsXHUzMDZCXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi1TQVhTb3VyY2VOdWxsSW5wdXRTb3VyY2UgPSBcdTYzMDdcdTVCOUFcdTMwNTdcdTMwNUZTQVhTb3VyY2VcdTMwNkJcdTMwNkZcdTMwMDFJbnB1dFNvdXJjZVx1MzA2Rlx1NTQyQlx1MzA3RVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9KQVhQVmFsaWRhdGlvbk1lc3NhZ2VzX2tvLnByb3BlcnRpZXMgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9KQVhQVmFsaWRhdGlvbk1lc3NhZ2VzX2tvLnByb3BlcnRpZXMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAxNTk4YmYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvSkFYUFZhbGlkYXRpb25NZXNzYWdlc19rby5wcm9wZXJ0aWVzCisrKyAvZGV2L251bGwKQEAgLTEsMjkgKzAsMCBAQAotIyBUaGlzIGZpbGUgc3RvcmVzIGxvY2FsaXplZCBtZXNzYWdlcyBmb3IgdGhlIFhlcmNlcyBKQVhQIFZhbGlkYXRpb24gQVBJIGltcGxlbWVudGF0aW9uLgotIwotIyBUaGUgbWVzc2FnZXMgYXJlIGFycmFuZ2VkIGluIGtleSBhbmQgdmFsdWUgdHVwbGVzIGluIGEgTGlzdFJlc291cmNlQnVuZGxlLgotIwotCi0jIE1lc3NhZ2VzIGZvciBtZXNzYWdlIHJlcG9ydGluZwotQmFkTWVzc2FnZUtleSA9IFx1QkE1NFx1QzJEQ1x1QzlDMCBcdUQwQTRcdUM1RDAgXHVENTc0XHVCMkY5XHVENTU4XHVCMjk0IFx1QzYyNFx1Qjk1OCBcdUJBNTRcdUMyRENcdUM5QzBcdUI5N0MgXHVDQzNFXHVDNzQ0IFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuCi1Gb3JtYXRGYWlsZWQgPSBcdUIyRTRcdUM3NEMgXHVCQTU0XHVDMkRDXHVDOUMwXHVDNzU4IFx1RDYxNVx1QzJERFx1Qzc0NCBcdUM5QzBcdUM4MTVcdUQ1NThcdUIyOTQgXHVDOTExIFx1QjBCNFx1QkQ4MCBcdUM2MjRcdUI5NThcdUFDMDAgXHVCQzFDXHVDMEREXHVENTg4XHVDMkI1XHVCMkM4XHVCMkU0LlxuCi0KLSMgU2NoZW1hRmFjdG9yeSBlcnJvciBtZXNzYWdlcwotU2NoZW1hTGFuZ3VhZ2VOdWxsID0gXHVDOUMwXHVDODE1XHVCNDFDIFx1QzJBNFx1RDBBNFx1QjlDOCBcdUM1QjhcdUM1QjRcdUIyOTQgXHVCMTEwXHVDNzdDIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuCi1TY2hlbWFMYW5ndWFnZUxlbmd0aFplcm8gPSBcdUM5QzBcdUM4MTVcdUI0MUMgXHVDMkE0XHVEMEE0XHVCOUM4IFx1QzVCOFx1QzVCNFx1Qzc1OCBcdUFFMzhcdUM3NzRcdUIyOTQgMFx1Qzc5MFx1Qzc3QyBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LgotU2NoZW1hU291cmNlQXJyYXlOdWxsID0gXHVDMThDXHVDMkE0IFx1QkMzMFx1QzVGNCBcdUI5RTRcdUFDMUNcdUJDQzBcdUMyMThcdUIyOTQgXHVCMTEwXHVDNzdDIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuCi1TY2hlbWFTb3VyY2VBcnJheU1lbWJlck51bGwgPSBcdUMxOENcdUMyQTQgXHVCQzMwXHVDNUY0IFx1QjlFNFx1QUMxQ1x1QkNDMFx1QzIxOFx1QzVEMFx1QjI5NCBcdUIxMTBcdUM3NzggXHVENTZEXHVCQUE5XHVDNzc0IFx1RDNFQ1x1RDU2OFx1QjQyMCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LgotU2NoZW1hRmFjdG9yeVNvdXJjZVVucmVjb2duaXplZCA9IFx1Qzc3NCBTY2hlbWFGYWN0b3J5XHVBQzAwICcnezB9JycgXHVDNzIwXHVENjE1XHVDNzU4IFx1QzE4Q1x1QzJBNCBcdUI5RTRcdUFDMUNcdUJDQzBcdUMyMThcdUI5N0MgXHVDNzc4XHVDMkREXHVENTYwIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuCi0KLSMgVmFsaWRhdG9yIGVycm9yIG1lc3NhZ2VzCi1Tb3VyY2VQYXJhbWV0ZXJOdWxsID0gXHVDMThDXHVDMkE0IFx1QjlFNFx1QUMxQ1x1QkNDMFx1QzIxOFx1QjI5NCBcdUIxMTBcdUM3N0MgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4KLVNvdXJjZU5vdEFjY2VwdGVkID0gXHVDNzc0IFx1QUM4MFx1Qzk5RFx1QUUzMFx1QjI5NCAnJ3swfScnIFx1QzcyMFx1RDYxNVx1Qzc1OCBcdUMxOENcdUMyQTQgXHVCOUU0XHVBQzFDXHVCQ0MwXHVDMjE4XHVCOTdDIFx1QzBBQ1x1QzZBOVx1RDU2MCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LgotU291cmNlUmVzdWx0TWlzbWF0Y2ggPSAnJ3swfScnIFx1QzcyMFx1RDYxNVx1Qzc1OCBcdUMxOENcdUMyQTQgXHVCOUU0XHVBQzFDXHVCQ0MwXHVDMjE4XHVBQzAwICcnezF9JycgXHVDNzIwXHVENjE1XHVDNzU4IFx1QUNCMFx1QUNGQyBcdUI5RTRcdUFDMUNcdUJDQzBcdUMyMThcdUM2NDAgXHVENjM4XHVENjU4XHVCNDE4XHVDOUMwIFx1QzU0QVx1QzJCNVx1QjJDOFx1QjJFNC4KLQotIyBUeXBlSW5mb1Byb3ZpZGVyIGVycm9yIG1lc3NhZ2VzCi1UeXBlSW5mb1Byb3ZpZGVySWxsZWdhbFN0YXRlID0gVHlwZUluZm9Qcm92aWRlclx1QjI5NCBzdGFydEVsZW1lbnQgXHVDRjVDXHVCQzMxIFx1QzY3OFx1QkQ4MFx1QzVEMFx1QzExQyBcdUM5QzhcdUM3NThcdUQ1NjAgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4KLQotIyBHZW5lcmFsIGVycm9yIG1lc3NhZ2VzCi1GZWF0dXJlTmFtZU51bGwgPSBcdUFFMzBcdUIyQTUgXHVDNzc0XHVCOTg0XHVDNzQwIFx1QjExMFx1Qzc3QyBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LgotUHJvcGVyeU5hbWVOdWxsID0gXHVDMThEXHVDMTMxIFx1Qzc3NFx1Qjk4NFx1Qzc0MCBcdUIxMTBcdUM3N0MgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4KLVNBWFNvdXJjZU51bGxJbnB1dFNvdXJjZSA9IFx1QzlDMFx1QzgxNVx1QjQxQyBTQVhTb3VyY2VcdUM1RDAgSW5wdXRTb3VyY2VcdUFDMDAgXHVEM0VDXHVENTY4XHVCNDE4XHVDNUI0IFx1Qzc4OFx1QzlDMCBcdUM1NEFcdUMyQjVcdUIyQzhcdUIyRTQuCi0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL0pBWFBWYWxpZGF0aW9uTWVzc2FnZXNfcHRfQlIucHJvcGVydGllcyBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL0pBWFBWYWxpZGF0aW9uTWVzc2FnZXNfcHRfQlIucHJvcGVydGllcwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZDE5YmJlMi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9KQVhQVmFsaWRhdGlvbk1lc3NhZ2VzX3B0X0JSLnByb3BlcnRpZXMKKysrIC9kZXYvbnVsbApAQCAtMSwyOSArMCwwIEBACi0jIFRoaXMgZmlsZSBzdG9yZXMgbG9jYWxpemVkIG1lc3NhZ2VzIGZvciB0aGUgWGVyY2VzIEpBWFAgVmFsaWRhdGlvbiBBUEkgaW1wbGVtZW50YXRpb24uCi0jCi0jIFRoZSBtZXNzYWdlcyBhcmUgYXJyYW5nZWQgaW4ga2V5IGFuZCB2YWx1ZSB0dXBsZXMgaW4gYSBMaXN0UmVzb3VyY2VCdW5kbGUuCi0jCi0KLSMgTWVzc2FnZXMgZm9yIG1lc3NhZ2UgcmVwb3J0aW5nCi1CYWRNZXNzYWdlS2V5ID0gTlx1MDBFM28gZm9pIHBvc3NcdTAwRUR2ZWwgZW5jb250cmFyIGEgbWVuc2FnZW0gZGUgZXJybyBjb3JyZXNwb25kZW50ZSBcdTAwRTAgY2hhdmUgZGEgbWVuc2FnZW0uCi1Gb3JtYXRGYWlsZWQgPSBPY29ycmV1IHVtIGVycm8gaW50ZXJubyBhbyBmb3JtYXRhciBhIG1lbnNhZ2VtIGEgc2VndWlyOlxuCi0KLSMgU2NoZW1hRmFjdG9yeSBlcnJvciBtZXNzYWdlcwotU2NoZW1hTGFuZ3VhZ2VOdWxsID0gTyBpZGlvbWEgZG8gZXNxdWVtYSBlc3BlY2lmaWNhZG8gblx1MDBFM28gcG9kZSBzZXIgbnVsby4KLVNjaGVtYUxhbmd1YWdlTGVuZ3RoWmVybyA9IE8gaWRpb21hIGRvIGVzcXVlbWEgZXNwZWNpZmljYWRvIG5cdTAwRTNvIHBvZGUgdGVyIHVtIHRhbWFuaG8gZGUgemVybyBjYXJhY3RlcmVzLgotU2NoZW1hU291cmNlQXJyYXlOdWxsID0gTyBwYXJcdTAwRTJtZXRybyBkbyBhcnJheSBkZSBPcmlnZW0gblx1MDBFM28gcG9kZSBzZXIgbnVsby4KLVNjaGVtYVNvdXJjZUFycmF5TWVtYmVyTnVsbCA9IE8gcGFyXHUwMEUybWV0cm8gZG8gYXJyYXkgZGUgT3JpZ2VtIG5cdTAwRTNvIHBvZGUgY29udGVyIG5lbmh1bSBpdGVtIHF1ZSBzZWphIG51bG8uCi1TY2hlbWFGYWN0b3J5U291cmNlVW5yZWNvZ25pemVkID0gTyBwYXJcdTAwRTJtZXRybyBkZSBvcmlnZW0gZG8gdGlwbyAnJ3swfScnIG5cdTAwRTNvIHJlY29uaGVjZXUgZXN0ZSBTY2hlbWFGYWN0b3J5LgotCi0jIFZhbGlkYXRvciBlcnJvciBtZXNzYWdlcwotU291cmNlUGFyYW1ldGVyTnVsbCA9IE8gcGFyXHUwMEUybWV0cm8gZGUgb3JpZ2VtIG5cdTAwRTNvIHBvZGUgc2VyIG51bG8uCi1Tb3VyY2VOb3RBY2NlcHRlZCA9IE8gcGFyXHUwMEUybWV0cm8gZGUgb3JpZ2VtIGRvIHRpcG8gJyd7MH0nJyBuXHUwMEUzbyBcdTAwRTkgYWNlaXRvIHBvciBlc3RlIHZhbGlkYWRvci4KLVNvdXJjZVJlc3VsdE1pc21hdGNoID0gTyBwYXJcdTAwRTJtZXRybyBkbyBvcmlnZW0gZG8gdGlwbyAnJ3swfScnIG5cdTAwRTNvIFx1MDBFOSBjb21wYXRcdTAwRUR2ZWwgY29tIG8gcGFyXHUwMEUybWV0cm8gZGUgcmVzdWx0YWRvIGRvIHRpcG8gJyd7MX0nJy4KLQotIyBUeXBlSW5mb1Byb3ZpZGVyIGVycm9yIG1lc3NhZ2VzCi1UeXBlSW5mb1Byb3ZpZGVySWxsZWdhbFN0YXRlID0gVW0gVHlwZUluZm9Qcm92aWRlciBuXHUwMEUzbyBwb2RlIHNlciBjb25zdWx0YWRvIGZvcmEgZGUgdW0gY2FsbGJhY2sgc3RhcnRFbGVtZW50LgotCi0jIEdlbmVyYWwgZXJyb3IgbWVzc2FnZXMKLUZlYXR1cmVOYW1lTnVsbCA9IE8gbm9tZSBkbyByZWN1cnNvIG5cdTAwRTNvIHBvZGUgc2VyIG51bG8uCi1Qcm9wZXJ5TmFtZU51bGwgPSBPIG5vbWUgZGEgcHJvcHJpZWRhZGUgblx1MDBFM28gcG9kZSBzZXIgbnVsby4KLVNBWFNvdXJjZU51bGxJbnB1dFNvdXJjZSA9IE8gU0FYU291cmNlIGVzcGVjaWZpY2FkbyBuXHUwMEUzbyBjb250XHUwMEU5bSBJbnB1dFNvdXJjZS4KLQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvSkFYUFZhbGlkYXRpb25NZXNzYWdlc19zdi5wcm9wZXJ0aWVzIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvSkFYUFZhbGlkYXRpb25NZXNzYWdlc19zdi5wcm9wZXJ0aWVzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3NGMzM2EwLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL0pBWFBWYWxpZGF0aW9uTWVzc2FnZXNfc3YucHJvcGVydGllcworKysgL2Rldi9udWxsCkBAIC0xLDI5ICswLDAgQEAKLSMgVGhpcyBmaWxlIHN0b3JlcyBsb2NhbGl6ZWQgbWVzc2FnZXMgZm9yIHRoZSBYZXJjZXMgSkFYUCBWYWxpZGF0aW9uIEFQSSBpbXBsZW1lbnRhdGlvbi4KLSMKLSMgVGhlIG1lc3NhZ2VzIGFyZSBhcnJhbmdlZCBpbiBrZXkgYW5kIHZhbHVlIHR1cGxlcyBpbiBhIExpc3RSZXNvdXJjZUJ1bmRsZS4KLSMKLQotIyBNZXNzYWdlcyBmb3IgbWVzc2FnZSByZXBvcnRpbmcKLUJhZE1lc3NhZ2VLZXkgPSBIaXR0YXIgaW50ZSBmZWxtZWRkZWxhbmRldCBzb20gbW90c3ZhcmFyIG1lZGRlbGFuZGVueWNrZWxuLgotRm9ybWF0RmFpbGVkID0gRXR0IGludGVybnQgZmVsIGludHJcdTAwRTRmZmFkZSB2aWQgZm9ybWF0ZXJpbmcgYXYgZlx1MDBGNmxqYW5kZSBtZWRkZWxhbmRlOlxuCi0KLSMgU2NoZW1hRmFjdG9yeSBlcnJvciBtZXNzYWdlcwotU2NoZW1hTGFuZ3VhZ2VOdWxsID0gQW5naXZldCBzY2hlbWFzcHJcdTAwRTVrIGZcdTAwRTVyIGludGUgdmFyYSBudWxsLgotU2NoZW1hTGFuZ3VhZ2VMZW5ndGhaZXJvID0gQW5naXZldCBzY2hlbWFzcHJcdTAwRTVrIGZcdTAwRTVyIGludGUgaGEgZW4gbFx1MDBFNG5nZCBzb20gXHUwMEU0ciBub2xsIHRlY2tlbi4KLVNjaGVtYVNvdXJjZUFycmF5TnVsbCA9IFBhcmFtZXRlcm4gZlx1MDBGNnIgU291cmNlLXVwcHN0XHUwMEU0bGxuaW5nIGZcdTAwRTVyIGludGUgdmFyYSBudWxsLgotU2NoZW1hU291cmNlQXJyYXlNZW1iZXJOdWxsID0gUGFyYW1ldGVybiBmXHUwMEY2ciBTb3VyY2UtdXBwc3RcdTAwRTRsbG5pbmcgZlx1MDBFNXIgaW50ZSBpbm5laFx1MDBFNWxsYSBuXHUwMEU1Z3JhIG9iamVrdCBzb20gXHUwMEU0ciBudWxsLgotU2NoZW1hRmFjdG9yeVNvdXJjZVVucmVjb2duaXplZCA9IFNvdXJjZS1wYXJhbWV0cmFyIGF2IHR5cCAnJ3swfScnIGlkZW50aWZpZXJhcyBpbnRlIGF2IFNjaGVtYUZhY3RvcnkuCi0KLSMgVmFsaWRhdG9yIGVycm9yIG1lc3NhZ2VzCi1Tb3VyY2VQYXJhbWV0ZXJOdWxsID0gU291cmNlLXBhcmFtZXRlciBmXHUwMEU1ciBpbnRlIHZhcmEgbnVsbC4KLVNvdXJjZU5vdEFjY2VwdGVkID0gU291cmNlLXBhcmFtZXRyYXIgYXYgdHlwICcnezB9JycgYWNjZXB0ZXJhcyBpbnRlIGF2IHZhbGlkZXJhcmVuLgotU291cmNlUmVzdWx0TWlzbWF0Y2ggPSBTb3VyY2UtcGFyYW1ldHJhciBhdiB0eXAgJyd7MH0nJyBcdTAwRTRyIGludGUga29tcGF0aWJsYSBtZWQgcmVzdWx0YXRwYXJhbWV0cmFyIGF2IHR5cCAnJ3sxfScnLgotCi0jIFR5cGVJbmZvUHJvdmlkZXIgZXJyb3IgbWVzc2FnZXMKLVR5cGVJbmZvUHJvdmlkZXJJbGxlZ2FsU3RhdGUgPSBUeXBlSW5mb1Byb3ZpZGVyIGZcdTAwRTVyIGludGUgdGEgZW1vdCBmclx1MDBFNWdvciB1dGFuZlx1MDBGNnIgcmVzcG9ucyBmclx1MDBFNW4gc3RhcnRFbGVtZW50LgotCi0jIEdlbmVyYWwgZXJyb3IgbWVzc2FnZXMKLUZlYXR1cmVOYW1lTnVsbCA9IEZ1bmt0aW9uc25hbW4gZlx1MDBFNXIgaW50ZSB2YXJhIG51bGwuCi1Qcm9wZXJ5TmFtZU51bGwgPSBFZ2Vuc2thcHNuYW1uIGZcdTAwRTVyIGludGUgdmFyYSBudWxsLgotU0FYU291cmNlTnVsbElucHV0U291cmNlID0gQW5naXZlbiBTQVhTb3VyY2UgaW5uZWhcdTAwRTVsbGVyIGluZ2VuIElucHV0U291cmNlLgotCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9KQVhQVmFsaWRhdGlvbk1lc3NhZ2VzX3poX0NOLnByb3BlcnRpZXMgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9KQVhQVmFsaWRhdGlvbk1lc3NhZ2VzX3poX0NOLnByb3BlcnRpZXMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGQ0NWFjNzEuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvSkFYUFZhbGlkYXRpb25NZXNzYWdlc196aF9DTi5wcm9wZXJ0aWVzCisrKyAvZGV2L251bGwKQEAgLTEsMjkgKzAsMCBAQAotIyBUaGlzIGZpbGUgc3RvcmVzIGxvY2FsaXplZCBtZXNzYWdlcyBmb3IgdGhlIFhlcmNlcyBKQVhQIFZhbGlkYXRpb24gQVBJIGltcGxlbWVudGF0aW9uLgotIwotIyBUaGUgbWVzc2FnZXMgYXJlIGFycmFuZ2VkIGluIGtleSBhbmQgdmFsdWUgdHVwbGVzIGluIGEgTGlzdFJlc291cmNlQnVuZGxlLgotIwotCi0jIE1lc3NhZ2VzIGZvciBtZXNzYWdlIHJlcG9ydGluZwotQmFkTWVzc2FnZUtleSA9IFx1NjI3RVx1NEUwRFx1NTIzMFx1NEUwRVx1NkQ4OFx1NjA2Rlx1NTE3M1x1OTUyRVx1NUI1N1x1NUJGOVx1NUU5NFx1NzY4NFx1OTUxOVx1OEJFRlx1NkQ4OFx1NjA2Rlx1MzAwMgotRm9ybWF0RmFpbGVkID0gXHU4QkJFXHU3RjZFXHU0RUU1XHU0RTBCXHU2RDg4XHU2MDZGXHU3Njg0XHU2ODNDXHU1RjBGXHU2NUY2XHU1MUZBXHU3M0IwXHU1MTg1XHU5MEU4XHU5NTE5XHU4QkVGOlxuCi0KLSMgU2NoZW1hRmFjdG9yeSBlcnJvciBtZXNzYWdlcwotU2NoZW1hTGFuZ3VhZ2VOdWxsID0gXHU2MzA3XHU1QjlBXHU3Njg0XHU2NUI5XHU2ODQ4XHU4QkVEXHU4QTAwXHU0RTBEXHU4MEZEXHU0RTNBXHU3QTdBXHU1MDNDXHUzMDAyCi1TY2hlbWFMYW5ndWFnZUxlbmd0aFplcm8gPSBcdTYzMDdcdTVCOUFcdTc2ODRcdTY1QjlcdTY4NDhcdThCRURcdThBMDBcdTc2ODRcdTk1N0ZcdTVFQTZcdTRFMERcdTgwRkRcdTRFM0FcdTk2RjZcdTRFMkFcdTVCNTdcdTdCMjZcdTMwMDIKLVNjaGVtYVNvdXJjZUFycmF5TnVsbCA9IFNvdXJjZSBcdTY1NzBcdTdFQzRcdTUzQzJcdTY1NzBcdTRFMERcdTgwRkRcdTRFM0FcdTdBN0FcdTUwM0NcdTMwMDIKLVNjaGVtYVNvdXJjZUFycmF5TWVtYmVyTnVsbCA9IFNvdXJjZSBcdTY1NzBcdTdFQzRcdTUzQzJcdTY1NzBcdTRFMERcdTgwRkRcdTUzMDVcdTU0MkJcdTRFRkJcdTRGNTVcdTRFM0FcdTdBN0FcdTUwM0NcdTc2ODRcdTk4NzlcdTMwMDIKLVNjaGVtYUZhY3RvcnlTb3VyY2VVbnJlY29nbml6ZWQgPSBcdTZCNjQgU2NoZW1hRmFjdG9yeSBcdTY1RTBcdTZDRDVcdThCQzZcdTUyMkJcdTdDN0JcdTU3OEJcdTRFM0EgJyd7MH0nJyBcdTc2ODQgU291cmNlIFx1NTNDMlx1NjU3MFx1MzAwMgotCi0jIFZhbGlkYXRvciBlcnJvciBtZXNzYWdlcwotU291cmNlUGFyYW1ldGVyTnVsbCA9IFNvdXJjZSBcdTUzQzJcdTY1NzBcdTRFMERcdTgwRkRcdTRFM0FcdTdBN0FcdTUwM0NcdTMwMDIKLVNvdXJjZU5vdEFjY2VwdGVkID0gXHU2QjY0XHU5QThDXHU4QkMxXHU3QTBCXHU1RThGXHU0RTBEXHU2M0E1XHU1M0Q3XHU3QzdCXHU1NzhCXHU0RTNBICcnezB9JycgXHU3Njg0IFNvdXJjZSBcdTUzQzJcdTY1NzBcdTMwMDIKLVNvdXJjZVJlc3VsdE1pc21hdGNoID0gXHU3QzdCXHU1NzhCXHU0RTNBICcnezB9JycgXHU3Njg0IFNvdXJjZSBcdTUzQzJcdTY1NzBcdTRFMEVcdTdDN0JcdTU3OEJcdTRFM0EgJyd7MX0nJyBcdTc2ODRcdTdFRDNcdTY3OUNcdTUzQzJcdTY1NzBcdTRFMERcdTUxN0NcdTVCQjlcdTMwMDIKLQotIyBUeXBlSW5mb1Byb3ZpZGVyIGVycm9yIG1lc3NhZ2VzCi1UeXBlSW5mb1Byb3ZpZGVySWxsZWdhbFN0YXRlID0gXHU2NUUwXHU2Q0Q1XHU1NzI4IHN0YXJ0RWxlbWVudCBcdTU2REVcdThDMDNcdTU5MTZcdTkwRThcdTY3RTVcdThCRTIgVHlwZUluZm9Qcm92aWRlclx1MzAwMgotCi0jIEdlbmVyYWwgZXJyb3IgbWVzc2FnZXMKLUZlYXR1cmVOYW1lTnVsbCA9IFx1NTI5Rlx1ODBGRFx1NTQwRFx1NzlGMFx1NEUwRFx1ODBGRFx1NEUzQVx1N0E3QVx1NTAzQ1x1MzAwMgotUHJvcGVyeU5hbWVOdWxsID0gXHU1QzVFXHU2MDI3XHU1NDBEXHU3OUYwXHU0RTBEXHU4MEZEXHU0RTNBXHU3QTdBXHU1MDNDXHUzMDAyCi1TQVhTb3VyY2VOdWxsSW5wdXRTb3VyY2UgPSBcdTYzMDdcdTVCOUFcdTc2ODQgU0FYU291cmNlIFx1NEUwRFx1NTMwNVx1NTQyQiBJbnB1dFNvdXJjZVx1MzAwMgotCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9KQVhQVmFsaWRhdGlvbk1lc3NhZ2VzX3poX1RXLnByb3BlcnRpZXMgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9KQVhQVmFsaWRhdGlvbk1lc3NhZ2VzX3poX1RXLnByb3BlcnRpZXMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDBkYjg2YjYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvSkFYUFZhbGlkYXRpb25NZXNzYWdlc196aF9UVy5wcm9wZXJ0aWVzCisrKyAvZGV2L251bGwKQEAgLTEsMjkgKzAsMCBAQAotIyBUaGlzIGZpbGUgc3RvcmVzIGxvY2FsaXplZCBtZXNzYWdlcyBmb3IgdGhlIFhlcmNlcyBKQVhQIFZhbGlkYXRpb24gQVBJIGltcGxlbWVudGF0aW9uLgotIwotIyBUaGUgbWVzc2FnZXMgYXJlIGFycmFuZ2VkIGluIGtleSBhbmQgdmFsdWUgdHVwbGVzIGluIGEgTGlzdFJlc291cmNlQnVuZGxlLgotIwotCi0jIE1lc3NhZ2VzIGZvciBtZXNzYWdlIHJlcG9ydGluZwotQmFkTWVzc2FnZUtleSA9IFx1NjI3RVx1NEUwRFx1NTIzMFx1NUMwRFx1NjFDOVx1OEEwQVx1NjA2Rlx1N0QyMlx1NUYxNVx1OTM3NVx1NzY4NFx1OTMyRlx1OEFBNFx1OEEwQVx1NjA2Rlx1MzAwMgotRm9ybWF0RmFpbGVkID0gXHU2ODNDXHU1RjBGXHU1MzE2XHU0RTBCXHU1MjE3XHU4QTBBXHU2MDZGXHU2NjQyXHU3NjdDXHU3NTFGXHU1MTY3XHU5MEU4XHU5MzJGXHU4QUE0OlxuCi0KLSMgU2NoZW1hRmFjdG9yeSBlcnJvciBtZXNzYWdlcwotU2NoZW1hTGFuZ3VhZ2VOdWxsID0gXHU2MzA3XHU1QjlBXHU3Njg0XHU3REIxXHU4OTgxXHU4QTlFXHU4QTAwXHU0RTBEXHU1M0VGXHU3MEJBXHU3QTdBXHU1MDNDXHUzMDAyCi1TY2hlbWFMYW5ndWFnZUxlbmd0aFplcm8gPSBcdTYzMDdcdTVCOUFcdTc2ODRcdTdEQjFcdTg5ODFcdThBOUVcdThBMDBcdTRFMERcdTUzRUZcdTcwQkFcdTk2RjZcdTVCNTdcdTUxNDNcdTk1NzdcdTVFQTZcdTMwMDIKLVNjaGVtYVNvdXJjZUFycmF5TnVsbCA9IFx1NEY4Nlx1NkU5MFx1OTY2M1x1NTIxN1x1NTNDM1x1NjU3OFx1NEUwRFx1NTNFRlx1NzBCQVx1N0E3QVx1NTAzQ1x1MzAwMgotU2NoZW1hU291cmNlQXJyYXlNZW1iZXJOdWxsID0gXHU0Rjg2XHU2RTkwXHU5NjYzXHU1MjE3XHU1M0MzXHU2NTc4XHU0RTBEXHU1M0VGXHU1MzA1XHU1NDJCXHU0RUZCXHU0RjU1XHU3QTdBXHU1MDNDXHU5ODA1XHU3NkVFXHUzMDAyCi1TY2hlbWFGYWN0b3J5U291cmNlVW5yZWNvZ25pemVkID0gXHU5ODVFXHU1NzhCICcnezB9JycgXHU3Njg0XHU0Rjg2XHU2RTkwXHU1M0MzXHU2NTc4XHU3MTIxXHU2Q0Q1XHU4RkE4XHU4QjU4XHU2QjY0IFNjaGVtYUZhY3RvcnlcdTMwMDIKLQotIyBWYWxpZGF0b3IgZXJyb3IgbWVzc2FnZXMKLVNvdXJjZVBhcmFtZXRlck51bGwgPSBcdTRGODZcdTZFOTBcdTUzQzNcdTY1NzhcdTRFMERcdTUzRUZcdTcwQkFcdTdBN0FcdTUwM0NcdTMwMDIKLVNvdXJjZU5vdEFjY2VwdGVkID0gXHU2QjY0XHU5QTU3XHU4QjQ5XHU3QTBCXHU1RjBGXHU0RTBEXHU2M0E1XHU1M0Q3XHU5ODVFXHU1NzhCICcnezB9JycgXHU3Njg0XHU0Rjg2XHU2RTkwXHU1M0MzXHU2NTc4XHUzMDAyCi1Tb3VyY2VSZXN1bHRNaXNtYXRjaCA9IFx1OTg1RVx1NTc4QiAnJ3swfScnIFx1NzY4NFx1NEY4Nlx1NkU5MFx1NTNDM1x1NjU3OFx1ODIwN1x1OTg1RVx1NTc4QiAnJ3sxfScnIFx1NzY4NFx1N0Q1MFx1Njc5Q1x1NTNDM1x1NjU3OFx1NEUwRFx1NzZGOFx1NUJCOVx1MzAwMgotCi0jIFR5cGVJbmZvUHJvdmlkZXIgZXJyb3IgbWVzc2FnZXMKLVR5cGVJbmZvUHJvdmlkZXJJbGxlZ2FsU3RhdGUgPSBcdTRFMERcdTUzRUZcdTU3Mjggc3RhcnRFbGVtZW50IFx1NTZERVx1NTQ3Q1x1NEU0Qlx1NTkxNlx1NjdFNVx1OEE2MiBUeXBlSW5mb1Byb3ZpZGVyXHUzMDAyCi0KLSMgR2VuZXJhbCBlcnJvciBtZXNzYWdlcwotRmVhdHVyZU5hbWVOdWxsID0gXHU1MjlGXHU4MEZEXHU1NDBEXHU3QTMxXHU0RTBEXHU1M0VGXHU3MEJBXHU3QTdBXHU1MDNDXHUzMDAyCi1Qcm9wZXJ5TmFtZU51bGwgPSBcdTVDNkNcdTYwMjdcdTU0MERcdTdBMzFcdTRFMERcdTUzRUZcdTcwQkFcdTdBN0FcdTUwM0NcdTMwMDIKLVNBWFNvdXJjZU51bGxJbnB1dFNvdXJjZSA9IFx1NjMwN1x1NUI5QVx1NzY4NCBTQVhTb3VyY2UgXHU2NzJBXHU1MzA1XHU1NDJCIElucHV0U291cmNlXHUzMDAyCi0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1NBWE1lc3NhZ2VzLnByb3BlcnRpZXMgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9TQVhNZXNzYWdlcy5wcm9wZXJ0aWVzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1ZTdiYThiLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1NBWE1lc3NhZ2VzLnByb3BlcnRpZXMKKysrIC9kZXYvbnVsbApAQCAtMSwzNSArMCwwIEBACi0jIFRoaXMgZmlsZSBzdG9yZXMgbG9jYWxpemVkIG1lc3NhZ2VzIGZvciB0aGUgWGVyY2VzCi0jIFNBWCBpbXBsZW1lbnRhdGlvbi4KLSMKLSMgVGhlIG1lc3NhZ2VzIGFyZSBhcnJhbmdlZCBpbiBrZXkgYW5kIHZhbHVlIHR1cGxlcyBpbiBhIExpc3RSZXNvdXJjZUJ1bmRsZS4KLSMKLQotCi1CYWRNZXNzYWdlS2V5ID0gVGhlIGVycm9yIG1lc3NhZ2UgY29ycmVzcG9uZGluZyB0byB0aGUgbWVzc2FnZSBrZXkgY2FuIG5vdCBiZSBmb3VuZC4KLUZvcm1hdEZhaWxlZCA9IEFuIGludGVybmFsIGVycm9yIG9jY3VycmVkIHdoaWxlIGZvcm1hdHRpbmcgdGhlIGZvbGxvd2luZyBtZXNzYWdlOlxuCi0KLSMgSkFYUCBtZXNzYWdlcwotc2NoZW1hLW5vdC1zdXBwb3J0ZWQgPSBUaGUgc3BlY2lmaWVkIHNjaGVtYSBsYW5ndWFnZSBpcyBub3Qgc3VwcG9ydGVkLgotamF4cC1vcmRlci1ub3Qtc3VwcG9ydGVkID0gUHJvcGVydHkgJyd7MH0nJyBtdXN0IGJlIHNldCBiZWZvcmUgc2V0dGluZyBwcm9wZXJ0eSAnJ3sxfScnLiAKLXNjaGVtYS1hbHJlYWR5LXNwZWNpZmllZCA9IFByb3BlcnR5ICcnezB9JycgY2Fubm90IGJlIHNldCB3aGVuIGEgbm9uLW51bGwgU2NoZW1hIG9iamVjdCBoYXMgYWxyZWFkeSBiZWVuIHNwZWNpZmllZC4KLQotIyBmZWF0dXJlIG1lc3NhZ2VzCi1mZWF0dXJlLW5vdC1zdXBwb3J0ZWQgPSBGZWF0dXJlICcnezB9JycgaXMgbm90IHN1cHBvcnRlZC4KLWZlYXR1cmUtbm90LXJlY29nbml6ZWQgPSBGZWF0dXJlICcnezB9JycgaXMgbm90IHJlY29nbml6ZWQuCi10cnVlLW5vdC1zdXBwb3J0ZWQgPSBUcnVlIHN0YXRlIGZvciBmZWF0dXJlICcnezB9JycgaXMgbm90IHN1cHBvcnRlZC4KLWZhbHNlLW5vdC1zdXBwb3J0ZWQgPSBGYWxzZSBzdGF0ZSBmb3IgZmVhdHVyZSAnJ3swfScnIGlzIG5vdCBzdXBwb3J0ZWQuCi1mZWF0dXJlLXJlYWQtb25seSA9IEZlYXR1cmUgJyd7MH0nJyBpcyByZWFkIG9ubHkuCi1qYXhwLXNlY3VyZXByb2Nlc3NpbmctZmVhdHVyZSA9IEZFQVRVUkVfU0VDVVJFX1BST0NFU1NJTkc6IENhbm5vdCBzZXQgdGhlIGZlYXR1cmUgdG8gZmFsc2Ugd2hlbiBzZWN1cml0eSBtYW5hZ2VyIGlzIHByZXNlbnQuCi0KLSMgcHJvcGVydHkgbWVzc2FnZXMKLXByb3BlcnR5LW5vdC1zdXBwb3J0ZWQgPSBQcm9wZXJ0eSAnJ3swfScnIGlzIG5vdCBzdXBwb3J0ZWQuCi1wcm9wZXJ0eS1ub3QtcmVjb2duaXplZCA9IFByb3BlcnR5ICcnezB9JycgaXMgbm90IHJlY29nbml6ZWQuCi1wcm9wZXJ0eS1yZWFkLW9ubHkgPSBQcm9wZXJ0eSAnJ3swfScnIGlzIHJlYWQgb25seS4KLXByb3BlcnR5LW5vdC1wYXJzaW5nLXN1cHBvcnRlZCA9IFByb3BlcnR5ICcnezB9JycgaXMgbm90IHN1cHBvcnRlZCB3aGlsZSBwYXJzaW5nLgotZG9tLW5vZGUtcmVhZC1ub3Qtc3VwcG9ydGVkID0gQ2Fubm90IHJlYWQgRE9NIG5vZGUgcHJvcGVydHkuIE5vIERPTSB0cmVlIGV4aXN0cy4KLWluY29tcGF0aWJsZS1jbGFzcyA9IFRoZSB2YWx1ZSBzcGVjaWZpZWQgZm9yIHByb3BlcnR5ICcnezB9JycgY2Fubm90IGJlIGNhc3RlZCB0byB7MX0uCi0KLXN0YXJ0LWRvY3VtZW50LW5vdC1jYWxsZWQ9UHJvcGVydHkgInswfSIgc2hvdWxkIGJlIGNhbGxlZCBhZnRlciBzdGFydERvY3VtZW50IGV2ZW50IGlzIHRocm93bgotbnVsbHBhcmFtZXRlcj10aGUgbmFtZSBwYXJhbWV0ZXIgZm9yICJ7MH0iIGlzIG51bGwKLWVycm9ySGFuZGxlck5vdFNldD1XYXJuaW5nXDogdmFsaWRhdGlvbiB3YXMgdHVybmVkIG9uIGJ1dCBhbiBvcmcueG1sLnNheC5FcnJvckhhbmRsZXIgd2FzIG5vdCBzZXQsIHdoaWNoIGlzIHByb2JhYmx5IG5vdCB3aGF0IGlzIGRlc2lyZWQuICBQYXJzZXIgd2lsbCB1c2UgYSBkZWZhdWx0IEVycm9ySGFuZGxlciB0byBwcmludCB0aGUgZmlyc3QgezB9ICBlcnJvcnMuICBQbGVhc2UgY2FsbCB0aGUgJ3NldEVycm9ySGFuZGxlcicgbWV0aG9kIHRvIGZpeCB0aGlzLgotZXJyb3JIYW5kbGVyRGVidWdNc2c9RXJyb3JcOiBVUkkgXD0gInswfSIsIExpbmUgXD0gInsxfSIsIFw6IHsyfSAKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1NBWE1lc3NhZ2VzX2RlLnByb3BlcnRpZXMgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9TQVhNZXNzYWdlc19kZS5wcm9wZXJ0aWVzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxMGFhODEzLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1NBWE1lc3NhZ2VzX2RlLnByb3BlcnRpZXMKKysrIC9kZXYvbnVsbApAQCAtMSwzNSArMCwwIEBACi0jIFRoaXMgZmlsZSBzdG9yZXMgbG9jYWxpemVkIG1lc3NhZ2VzIGZvciB0aGUgWGVyY2VzCi0jIFNBWCBpbXBsZW1lbnRhdGlvbi4KLSMKLSMgVGhlIG1lc3NhZ2VzIGFyZSBhcnJhbmdlZCBpbiBrZXkgYW5kIHZhbHVlIHR1cGxlcyBpbiBhIExpc3RSZXNvdXJjZUJ1bmRsZS4KLSMKLQotCi1CYWRNZXNzYWdlS2V5ID0gRGllIHp1bSBNZWxkdW5nc3NjaGxcdTAwRkNzc2VsIGdlaFx1MDBGNnJpZ2UgRmVobGVybWVsZHVuZyBrYW5uIG5pY2h0IGdlZnVuZGVuIHdlcmRlbi4KLUZvcm1hdEZhaWxlZCA9IEJlaW0gRm9ybWF0aWVyZW4gZGVyIGZvbGdlbmRlbiBNZWxkdW5nIGlzdCBlaW4gaW50ZXJuZXIgRmVobGVyIGF1ZmdldHJldGVuOlxuCi0KLSMgSkFYUCBtZXNzYWdlcwotc2NoZW1hLW5vdC1zdXBwb3J0ZWQgPSBEaWUgYW5nZWdlYmVuZSBTY2hlbWFzcHJhY2hlIHdpcmQgbmljaHQgdW50ZXJzdFx1MDBGQ3R6dC4KLWpheHAtb3JkZXItbm90LXN1cHBvcnRlZCA9IEVpZ2Vuc2NoYWZ0ICJ7MH0iIG11c3Mgdm9yIGRlciBFaWdlbnNjaGFmdCAiezF9IiBmZXN0Z2VsZWd0IHdlcmRlbi4gCi1zY2hlbWEtYWxyZWFkeS1zcGVjaWZpZWQgPSBFaWdlbnNjaGFmdCAiezB9IiBrYW5uIG5pY2h0IGZlc3RnZWxlZ3Qgd2VyZGVuLCB3ZW5uIGJlcmVpdHMgZWluIFNjaGVtYW9iamVrdCB1bmdsZWljaCBudWxsIGFuZ2VnZWJlbiB3dXJkZS4KLQotIyBmZWF0dXJlIG1lc3NhZ2VzCi1mZWF0dXJlLW5vdC1zdXBwb3J0ZWQgPSBGZWF0dXJlICJ7MH0iIHdpcmQgbmljaHQgdW50ZXJzdFx1MDBGQ3R6dC4KLWZlYXR1cmUtbm90LXJlY29nbml6ZWQgPSBGZWF0dXJlICJ7MH0iIGlzdCB1bmJla2FubnQuCi10cnVlLW5vdC1zdXBwb3J0ZWQgPSBTdGF0dXMgIlRydWUiIGZcdTAwRkNyIEZlYXR1cmUgInswfSIgd2lyZCBuaWNodCB1bnRlcnN0XHUwMEZDdHp0LgotZmFsc2Utbm90LXN1cHBvcnRlZCA9IFN0YXR1cyAiRmFsc2UiIGZcdTAwRkNyIEZlYXR1cmUgInswfSIgd2lyZCBuaWNodCB1bnRlcnN0XHUwMEZDdHp0LgotZmVhdHVyZS1yZWFkLW9ubHkgPSBGZWF0dXJlICJ7MH0iIGlzdCBzY2hyZWliZ2VzY2hcdTAwRkN0enQuCi1qYXhwLXNlY3VyZXByb2Nlc3NpbmctZmVhdHVyZSA9IEZFQVRVUkVfU0VDVVJFX1BST0NFU1NJTkc6IEZlYXR1cmUga2FubiBuaWNodCBhdWYgImZhbHNlIiBnZXNldHp0IHdlcmRlbiwgd2VubiBTZWN1cml0eSBNYW5hZ2VyIHZvcmhhbmRlbiBpc3QuCi0KLSMgcHJvcGVydHkgbWVzc2FnZXMKLXByb3BlcnR5LW5vdC1zdXBwb3J0ZWQgPSBFaWdlbnNjaGFmdCAiezB9IiB3aXJkIG5pY2h0IHVudGVyc3RcdTAwRkN0enQuCi1wcm9wZXJ0eS1ub3QtcmVjb2duaXplZCA9IEVpZ2Vuc2NoYWZ0ICJ7MH0iIGlzdCB1bmJla2FubnQuCi1wcm9wZXJ0eS1yZWFkLW9ubHkgPSBFaWdlbnNjaGFmdCAiezB9IiBpc3Qgc2NocmVpYmdlc2NoXHUwMEZDdHp0LgotcHJvcGVydHktbm90LXBhcnNpbmctc3VwcG9ydGVkID0gRWlnZW5zY2hhZnQgInswfSIgd2lyZCBiZWltIFBhcnNlbiBuaWNodCB1bnRlcnN0XHUwMEZDdHp0LgotZG9tLW5vZGUtcmVhZC1ub3Qtc3VwcG9ydGVkID0gRE9NLUtub3RlbmVpZ2Vuc2NoYWZ0IGthbm4gbmljaHQgZ2VsZXNlbiB3ZXJkZW4uIEtlaW4gRE9NLUJhdW0gdm9yaGFuZGVuLgotaW5jb21wYXRpYmxlLWNsYXNzID0gRGVyIGZcdTAwRkNyIEVpZ2Vuc2NoYWZ0ICJ7MH0iIGFuZ2VnZWJlbmUgV2VydCBrYW5uIG5pY2h0IGluIHsxfSBrb252ZXJ0aWVydCB3ZXJkZW4uCi0KLXN0YXJ0LWRvY3VtZW50LW5vdC1jYWxsZWQ9RWlnZW5zY2hhZnQgInswfSIgc29sbHRlIGF1ZmdlcnVmZW4gd2VyZGVuLCBuYWNoZGVtIGRhcyBzdGFydERvY3VtZW50LUVyZWlnbmlzIGF1c2dlbFx1MDBGNnN0IHd1cmRlCi1udWxscGFyYW1ldGVyPU5hbWVuc3BhcmFtZXRlciBmXHUwMEZDciAiezB9IiBpc3QgbnVsbAotZXJyb3JIYW5kbGVyTm90U2V0PVdhcm51bmc6IFZhbGlkaWVydW5nIHd1cmRlIGVpbmdlc2NoYWx0ZXQsIGFiZXIgZXMgd3VyZGUga2VpbiBvcmcueG1sLnNheC5FcnJvckhhbmRsZXIgZmVzdGdlbGVndC4gRGllcyBpc3Qgd2FocnNjaGVpbmxpY2ggbmljaHQgYmVhYnNpY2h0aWd0LiBQYXJzZXIgZHJ1Y2t0IGRpZSBlcnN0ZW4gezB9IEZlaGxlciBtaXQgZWluZW0gU3RhbmRhcmQtRXJyb3JIYW5kbGVyLiBSdWZlbiBTaWUgZGllIE1ldGhvZGUgInNldEVycm9ySGFuZGxlciIgYXVmLCB1bSBkaWVzIHp1IGJlaGViZW4uCi1lcnJvckhhbmRsZXJEZWJ1Z01zZz1GZWhsZXI6IFVSSSA9ICJ7MH0iLCBaZWlsZSA9ICJ7MX0iLCA6IHsyfSAKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1NBWE1lc3NhZ2VzX2VzLnByb3BlcnRpZXMgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9TQVhNZXNzYWdlc19lcy5wcm9wZXJ0aWVzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlY2RjZGI5Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1NBWE1lc3NhZ2VzX2VzLnByb3BlcnRpZXMKKysrIC9kZXYvbnVsbApAQCAtMSwzNSArMCwwIEBACi0jIFRoaXMgZmlsZSBzdG9yZXMgbG9jYWxpemVkIG1lc3NhZ2VzIGZvciB0aGUgWGVyY2VzCi0jIFNBWCBpbXBsZW1lbnRhdGlvbi4KLSMKLSMgVGhlIG1lc3NhZ2VzIGFyZSBhcnJhbmdlZCBpbiBrZXkgYW5kIHZhbHVlIHR1cGxlcyBpbiBhIExpc3RSZXNvdXJjZUJ1bmRsZS4KLSMKLQotCi1CYWRNZXNzYWdlS2V5ID0gTm8gc2UgaGEgZW5jb250cmFkbyBlbCBtZW5zYWplIGRlIGVycm9yIGNvcnJlc3BvbmRpZW50ZSBhIGxhIGNsYXZlIGRlIG1lbnNhamUuCi1Gb3JtYXRGYWlsZWQgPSBTZSBoYSBwcm9kdWNpZG8gdW4gZXJyb3IgaW50ZXJubyBhbCBmb3JtYXRlYXIgZWwgc2lndWllbnRlIG1lbnNhamU6XG4KLQotIyBKQVhQIG1lc3NhZ2VzCi1zY2hlbWEtbm90LXN1cHBvcnRlZCA9IEVsIGlkaW9tYSBkZWwgZXNxdWVtYSBlc3BlY2lmaWNhZG8gbm8gZXN0XHUwMEUxIHNvcG9ydGFkby4KLWpheHAtb3JkZXItbm90LXN1cHBvcnRlZCA9IExhIHByb3BpZWRhZCAnJ3swfScnIGRlYmUgZGVmaW5pcnNlIGFudGVzIGRlIGRlZmluaXIgbGEgcHJvcGllZGFkICcnezF9JycuIAotc2NoZW1hLWFscmVhZHktc3BlY2lmaWVkID0gTGEgcHJvcGllZGFkICcnezB9Jycgbm8gcHVlZGUgZGVmaW5pcnNlIGN1YW5kbyB1biBvYmpldG8gZGUgZXNxdWVtYSBubyBudWxvIHlhIHNlIGhheWEgZXNwZWNpZmljYWRvLgotCi0jIGZlYXR1cmUgbWVzc2FnZXMKLWZlYXR1cmUtbm90LXN1cHBvcnRlZCA9IExhIGZ1bmNpXHUwMEYzbiAiezB9IiBubyBlc3RcdTAwRTEgc29wb3J0YWRhLgotZmVhdHVyZS1ub3QtcmVjb2duaXplZCA9IExhIGZ1bmNpXHUwMEYzbiAiezB9IiBubyBzZSBoYSByZWNvbm9jaWRvLgotdHJ1ZS1ub3Qtc3VwcG9ydGVkID0gRWwgZXN0YWRvIHRydWUgcGFyYSBsYSBmdW5jaVx1MDBGM24gJyd7MH0nJyBubyBlc3RcdTAwRTEgc29wb3J0YWRvLgotZmFsc2Utbm90LXN1cHBvcnRlZCA9IEVsIGVzdGFkbyBmYWxzZSBwYXJhIGxhIGZ1bmNpXHUwMEYzbiAnJ3swfScnIG5vIGVzdFx1MDBFMSBzb3BvcnRhZG8uCi1mZWF0dXJlLXJlYWQtb25seSA9IExhIGZ1bmNpXHUwMEYzbiAiezB9IiBlcyBkZSBzXHUwMEYzbG8gbGVjdHVyYS4KLWpheHAtc2VjdXJlcHJvY2Vzc2luZy1mZWF0dXJlID0gRkVBVFVSRV9TRUNVUkVfUFJPQ0VTU0lORzogbm8gc2UgcHVlZGUgZGVmaW5pciBsYSBmdW5jaVx1MDBGM24gZW4gZmFsc2UgY3VhbmRvIGVzdFx1MDBFMSBwcmVzZW50ZSBlbCBnZXN0b3IgZGUgc2VndXJpZGFkLgotCi0jIHByb3BlcnR5IG1lc3NhZ2VzCi1wcm9wZXJ0eS1ub3Qtc3VwcG9ydGVkID0gTGEgcHJvcGllZGFkICJ7MH0iIG5vIGVzdFx1MDBFMSBzb3BvcnRhZGEuCi1wcm9wZXJ0eS1ub3QtcmVjb2duaXplZCA9IExhIHByb3BpZWRhZCAiezB9IiBubyBzZSBoYSByZWNvbm9jaWRvLgotcHJvcGVydHktcmVhZC1vbmx5ID0gTGEgcHJvcGllZGFkICJ7MH0iIGVzIGRlIHNcdTAwRjNsbyBsZWN0dXJhLgotcHJvcGVydHktbm90LXBhcnNpbmctc3VwcG9ydGVkID0gTGEgcHJvcGllZGFkICJ7MH0iIG5vIGVzdFx1MDBFMSBzb3BvcnRhZGEgZHVyYW50ZSBlbCBhblx1MDBFMWxpc2lzLgotZG9tLW5vZGUtcmVhZC1ub3Qtc3VwcG9ydGVkID0gTm8gc2UgcHVlZGUgbGVlciBsYSBwcm9waWVkYWQgZGVsIG5vZG8gRE9NLiBObyBleGlzdGUgZWwgXHUwMEUxcmJvbCBET00uCi1pbmNvbXBhdGlibGUtY2xhc3MgPSBFbCB2YWxvciBlc3BlY2lmaWNhZG8gcGFyYSBsYSBwcm9waWVkYWQgJyd7MH0nJyBubyBzZSBwdWVkZSBjb252ZXJ0aXIgZW4gezF9LgotCi1zdGFydC1kb2N1bWVudC1ub3QtY2FsbGVkPUxhIHByb3BpZWRhZCAiezB9IiBkZWJlIGxsYW1hcnNlIGRlc3B1XHUwMEU5cyBkZSBxdWUgc2UgaGF5YSBkZXZ1ZWx0byBlbCBldmVudG8gc3RhcnREb2N1bWVudAotbnVsbHBhcmFtZXRlcj1lbCBwYXJcdTAwRTFtZXRybyBkZSBub21icmUgcGFyYSAiezB9IiBlcyBudWxvCi1lcnJvckhhbmRsZXJOb3RTZXQ9QWR2ZXJ0ZW5jaWE6IHNlIGFjdGl2XHUwMEYzIGxhIHZhbGlkYWNpXHUwMEYzbiBwZXJvIG5vIHNlIGRlZmluaVx1MDBGMyB1biBvcmcueG1sLnNheC5FcnJvckhhbmRsZXIsIGxvIGN1YWwgcHJvYmFibGVtZW50ZSBzZWEgdW4gcmVzdWx0YWRvIG5vIGRlc2VhZG8uIEVsIGFuYWxpemFkb3IgdXRpbGl6YXJcdTAwRTEgdW4gRXJyb3JIYW5kbGVyIHBvciBkZWZlY3RvIHBhcmEgaW1wcmltaXIgbG9zIHByaW1lcm9zIHswfSBlcnJvcmVzLiBMbGFtZSBhbCBtXHUwMEU5dG9kbyAnJ3NldEVycm9ySGFuZGxlcicnIHBhcmEgc29sdWNpb25hcmxvLgotZXJyb3JIYW5kbGVyRGVidWdNc2c9RXJyb3I6IFVSSSA9ICJ7MH0iLCBMXHUwMEVEbmVhID0gInsxfSIsIDogezJ9IApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvU0FYTWVzc2FnZXNfZnIucHJvcGVydGllcyBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1NBWE1lc3NhZ2VzX2ZyLnByb3BlcnRpZXMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDE0NTdiNjYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvU0FYTWVzc2FnZXNfZnIucHJvcGVydGllcworKysgL2Rldi9udWxsCkBAIC0xLDM1ICswLDAgQEAKLSMgVGhpcyBmaWxlIHN0b3JlcyBsb2NhbGl6ZWQgbWVzc2FnZXMgZm9yIHRoZSBYZXJjZXMKLSMgU0FYIGltcGxlbWVudGF0aW9uLgotIwotIyBUaGUgbWVzc2FnZXMgYXJlIGFycmFuZ2VkIGluIGtleSBhbmQgdmFsdWUgdHVwbGVzIGluIGEgTGlzdFJlc291cmNlQnVuZGxlLgotIwotCi0KLUJhZE1lc3NhZ2VLZXkgPSBMZSBtZXNzYWdlIGQnZXJyZXVyIGNvcnJlc3BvbmRhbnQgXHUwMEUwIGxhIGNsXHUwMEU5IGRlIG1lc3NhZ2UgZXN0IGludHJvdXZhYmxlLgotRm9ybWF0RmFpbGVkID0gVW5lIGVycmV1ciBpbnRlcm5lIGVzdCBzdXJ2ZW51ZSBsb3JzIGR1IGZvcm1hdGFnZSBkdSBtZXNzYWdlIHN1aXZhbnQgOlxuCi0KLSMgSkFYUCBtZXNzYWdlcwotc2NoZW1hLW5vdC1zdXBwb3J0ZWQgPSBMYSBsYW5ndWUgZGUgc2NoXHUwMEU5bWEgaW5kaXF1XHUwMEU5ZSBuJ2VzdCBwYXMgcHJpc2UgZW4gY2hhcmdlLgotamF4cC1vcmRlci1ub3Qtc3VwcG9ydGVkID0gTGEgcHJvcHJpXHUwMEU5dFx1MDBFOSAnJ3swfScnIGRvaXQgXHUwMEVBdHJlIGRcdTAwRTlmaW5pZSBhdmFudCBsYSBwcm9wcmlcdTAwRTl0XHUwMEU5ICcnezF9JycuIAotc2NoZW1hLWFscmVhZHktc3BlY2lmaWVkID0gTGEgcHJvcHJpXHUwMEU5dFx1MDBFOSAnJ3swfScnIG5lIHBldXQgcGFzIFx1MDBFQXRyZSBkXHUwMEU5ZmluaWUgbG9yc3F1Jyd1biBvYmpldCBkZSBzY2hcdTAwRTltYSBub24gTlVMTCBhIGRcdTAwRTlqXHUwMEUwIFx1MDBFOXRcdTAwRTkgaW5kaXF1XHUwMEU5LgotCi0jIGZlYXR1cmUgbWVzc2FnZXMKLWZlYXR1cmUtbm90LXN1cHBvcnRlZCA9IExhIGZvbmN0aW9ubmFsaXRcdTAwRTkgJyd7MH0nJyBuJydlc3QgcGFzIHByaXNlIGVuIGNoYXJnZS4KLWZlYXR1cmUtbm90LXJlY29nbml6ZWQgPSBMYSBmb25jdGlvbm5hbGl0XHUwMEU5ICcnezB9JycgbicnZXN0IHBhcyByZWNvbm51ZS4KLXRydWUtbm90LXN1cHBvcnRlZCA9IEwnJ1x1MDBFOXRhdCBUcnVlIGRlIGxhIGZvbmN0aW9ubmFsaXRcdTAwRTkgJyd7MH0nJyBuJydlc3QgcGFzIHByaXMgZW4gY2hhcmdlLgotZmFsc2Utbm90LXN1cHBvcnRlZCA9IEwnJ1x1MDBFOXRhdCBGYWxzZSBkZSBsYSBmb25jdGlvbm5hbGl0XHUwMEU5ICcnezB9JycgbicnZXN0IHBhcyBwcmlzIGVuIGNoYXJnZS4KLWZlYXR1cmUtcmVhZC1vbmx5ID0gTGEgZm9uY3Rpb25uYWxpdFx1MDBFOSAnJ3swfScnZXN0IGFjY2Vzc2libGUgZW4gbGVjdHVyZSBzZXVsZS4KLWpheHAtc2VjdXJlcHJvY2Vzc2luZy1mZWF0dXJlID0gRkVBVFVSRV9TRUNVUkVfUFJPQ0VTU0lORyA6IGltcG9zc2libGUgZGUgZFx1MDBFOWZpbmlyIGxhIGZvbmN0aW9ubmFsaXRcdTAwRTkgc3VyIEZhbHNlIGVuIHByXHUwMEU5c2VuY2UgZHUgZ2VzdGlvbm5haXJlIGRlIHNcdTAwRTljdXJpdFx1MDBFOS4KLQotIyBwcm9wZXJ0eSBtZXNzYWdlcwotcHJvcGVydHktbm90LXN1cHBvcnRlZCA9IExhIHByb3ByaVx1MDBFOXRcdTAwRTkgJyd7MH0nJyBuJydlc3QgcGFzIHByaXNlIGVuIGNoYXJnZS4KLXByb3BlcnR5LW5vdC1yZWNvZ25pemVkID0gTGEgcHJvcHJpXHUwMEU5dFx1MDBFOSAnJ3swfScnIG4nJ2VzdCBwYXMgcmVjb25udWUuCi1wcm9wZXJ0eS1yZWFkLW9ubHkgPSBMYSBwcm9wcmlcdTAwRTl0XHUwMEU5ICcnezB9JycgZXN0IGFjY2Vzc2libGUgZW4gbGVjdHVyZSBzZXVsZS4KLXByb3BlcnR5LW5vdC1wYXJzaW5nLXN1cHBvcnRlZCA9IExhIHByb3ByaVx1MDBFOXRcdTAwRTkgJyd7MH0nJyBuJydlc3QgcGFzIHByaXNlIGVuIGNoYXJnZSBhdSBjb3VycyBkZSBsJydhbmFseXNlLgotZG9tLW5vZGUtcmVhZC1ub3Qtc3VwcG9ydGVkID0gSW1wb3NzaWJsZSBkZSBsaXJlIGxhIHByb3ByaVx1MDBFOXRcdTAwRTkgZGUgbm9ldWQgRE9NLiBBdWN1bmUgYXJib3Jlc2NlbmNlIERPTSBuJ2V4aXN0ZS4KLWluY29tcGF0aWJsZS1jbGFzcyA9IExhIHZhbGV1ciBpbmRpcXVcdTAwRTllIHBvdXIgbGEgcHJvcHJpXHUwMEU5dFx1MDBFOSAnJ3swfScnIG5lIHBldXQgcGFzIFx1MDBFQXRyZSBjb252ZXJ0aWUgZW4gezF9LgotCi1zdGFydC1kb2N1bWVudC1ub3QtY2FsbGVkPUxhIHByb3ByaVx1MDBFOXRcdTAwRTkgInswfSIgZG9pdCBcdTAwRUF0cmUgYXBwZWxcdTAwRTllIGFwclx1MDBFOHMgcXUnJ3VuIFx1MDBFOXZcdTAwRTluZW1lbnQgc3RhcnREb2N1bWVudCBlc3QgZ1x1MDBFOW5cdTAwRTlyXHUwMEU5Ci1udWxscGFyYW1ldGVyPWxlIHBhcmFtXHUwMEU4dHJlIGRlIG5vbSBwb3VyICJ7MH0iIGVzdCBOVUxMCi1lcnJvckhhbmRsZXJOb3RTZXQ9QXZlcnRpc3NlbWVudCA6IGxhIHZhbGlkYXRpb24gYSBcdTAwRTl0XHUwMEU5IGFjdGl2XHUwMEU5ZSBtYWlzIGF1Y3VuIFx1MDBFOWxcdTAwRTltZW50IG9yZy54bWwuc2F4LkVycm9ySGFuZGxlciBuJydhIFx1MDBFOXRcdTAwRTkgZFx1MDBFOWZpbmksIGNlIHF1aSBkZXZyYWl0IHByb2JhYmxlbWVudCBcdTAwRUF0cmUgbGUgY2FzLiBMJydhbmFseXNldXIgdXRpbGlzZXJhIHVuIGdlc3Rpb25uYWlyZSBkJydlcnJldXJzIHBhciBkXHUwMEU5ZmF1dCBwb3VyIGltcHJpbWVyIGxlcyB7MH0gcHJlbWlcdTAwRThyZXMgZXJyZXVycy4gQXBwZWxleiBsYSBtXHUwMEU5dGhvZGUgJydzZXRFcnJvckhhbmRsZXInJyBwb3VyIHJcdTAwRTlzb3VkcmUgY2UgcHJvYmxcdTAwRThtZS4KLWVycm9ySGFuZGxlckRlYnVnTXNnPUVycmV1ciA6IFVSSSA9ICJ7MH0iLCBsaWduZSA9ICJ7MX0iLCA6IHsyfSAKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1NBWE1lc3NhZ2VzX2l0LnByb3BlcnRpZXMgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9TQVhNZXNzYWdlc19pdC5wcm9wZXJ0aWVzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmODJmYWY0Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1NBWE1lc3NhZ2VzX2l0LnByb3BlcnRpZXMKKysrIC9kZXYvbnVsbApAQCAtMSwzNSArMCwwIEBACi0jIFRoaXMgZmlsZSBzdG9yZXMgbG9jYWxpemVkIG1lc3NhZ2VzIGZvciB0aGUgWGVyY2VzCi0jIFNBWCBpbXBsZW1lbnRhdGlvbi4KLSMKLSMgVGhlIG1lc3NhZ2VzIGFyZSBhcnJhbmdlZCBpbiBrZXkgYW5kIHZhbHVlIHR1cGxlcyBpbiBhIExpc3RSZXNvdXJjZUJ1bmRsZS4KLSMKLQotCi1CYWRNZXNzYWdlS2V5ID0gSW1wb3NzaWJpbGUgdHJvdmFyZSBpbCBtZXNzYWdnaW8gZGkgZXJyb3JlIGNvcnJpc3BvbmRlbnRlIGFsbGEgY2hpYXZlIGRpIG1lc3NhZ2dpby4KLUZvcm1hdEZhaWxlZCA9IFNpIFx1MDBFOCB2ZXJpZmljYXRvIHVuIGVycm9yZSBpbnRlcm5vIGR1cmFudGUgbGEgZm9ybWF0dGF6aW9uZSBkZWwgc2VndWVudGUgbWVzc2FnZ2lvOlxuCi0KLSMgSkFYUCBtZXNzYWdlcwotc2NoZW1hLW5vdC1zdXBwb3J0ZWQgPSBMYSBsaW5ndWEgZGVsbG8gc2NoZW1hIHNwZWNpZmljYXRhIG5vbiBcdTAwRTggc3VwcG9ydGF0YS4KLWpheHAtb3JkZXItbm90LXN1cHBvcnRlZCA9IEltcG9zdGFyZSBsYSBwcm9wcmlldFx1MDBFMCAnJ3swfScnIHByaW1hIGRpIGltcG9zdGFyZSBsYSBwcm9wcmlldFx1MDBFMCAnJ3sxfScnLiAKLXNjaGVtYS1hbHJlYWR5LXNwZWNpZmllZCA9IEltcG9zc2liaWxlIGltcG9zdGFyZSBsYSBwcm9wcmlldFx1MDBFMCAnJ3swfScnIHNlIFx1MDBFOCBnaVx1MDBFMCBzdGF0byBzcGVjaWZpY2F0byB1biBvZ2dldHRvIGRpIHNjaGVtYSBub24gbnVsbG8uCi0KLSMgZmVhdHVyZSBtZXNzYWdlcwotZmVhdHVyZS1ub3Qtc3VwcG9ydGVkID0gTGEgZnVuemlvbmUgInswfSIgbm9uIFx1MDBFOCBzdXBwb3J0YXRhLgotZmVhdHVyZS1ub3QtcmVjb2duaXplZCA9IExhIGZ1bnppb25lICJ7MH0iIG5vbiBcdTAwRTggcmljb25vc2NpdXRhLgotdHJ1ZS1ub3Qtc3VwcG9ydGVkID0gTG8gc3RhdG8gdHJ1ZSBwZXIgbGEgZnVuemlvbmUgInswfSIgbm9uIFx1MDBFOCBzdXBwb3J0YXRvLgotZmFsc2Utbm90LXN1cHBvcnRlZCA9IExvIHN0YXRvIGZhbHNlIHBlciBsYSBmdW56aW9uZSAiezB9IiBub24gXHUwMEU4IHN1cHBvcnRhdG8uCi1mZWF0dXJlLXJlYWQtb25seSA9IExhIGZ1bnppb25lICJ7MH0iIFx1MDBFOCBkaSBzb2xhIGxldHR1cmEuCi1qYXhwLXNlY3VyZXByb2Nlc3NpbmctZmVhdHVyZSA9IEZFQVRVUkVfU0VDVVJFX1BST0NFU1NJTkc6IGltcG9zc2liaWxlIGltcG9zdGFyZSBsYSBmdW56aW9uZSBzdSBmYWxzZSBzZSBcdTAwRTggcHJlc2VudGUgU2VjdXJpdHkgTWFuYWdlci4KLQotIyBwcm9wZXJ0eSBtZXNzYWdlcwotcHJvcGVydHktbm90LXN1cHBvcnRlZCA9IExhIHByb3ByaWV0XHUwMEUwICJ7MH0iIG5vbiBcdTAwRTggc3VwcG9ydGF0YS4KLXByb3BlcnR5LW5vdC1yZWNvZ25pemVkID0gTGEgcHJvcHJpZXRcdTAwRTAgInswfSIgbm9uIFx1MDBFOCByaWNvbm9zY2l1dGEuCi1wcm9wZXJ0eS1yZWFkLW9ubHkgPSBMYSBwcm9wcmlldFx1MDBFMCAiezB9IiBcdTAwRTggZGkgc29sYSBsZXR0dXJhLgotcHJvcGVydHktbm90LXBhcnNpbmctc3VwcG9ydGVkID0gTGEgcHJvcHJpZXRcdTAwRTAgInswfSIgbm9uIFx1MDBFOCBzdXBwb3J0YXRhIGR1cmFudGUgbCcnYW5hbGlzaS4KLWRvbS1ub2RlLXJlYWQtbm90LXN1cHBvcnRlZCA9IEltcG9zc2liaWxlIGxlZ2dlcmUgbGEgcHJvcHJpZXRcdTAwRTAgZGkgbm9kbyBET00uIE5vbiBlc2lzdGUgYWxjdW5hIHN0cnV0dHVyYSBET00uCi1pbmNvbXBhdGlibGUtY2xhc3MgPSBJbXBvc3NpYmlsZSBlc2VndWlyZSBsYSBjb252ZXJzaW9uZSBjYXN0IGRlbCB2YWxvcmUgc3BlY2lmaWNhdG8gcGVyIGxhIHByb3ByaWV0XHUwMEUwICcnezB9JycgaW4gezF9LgotCi1zdGFydC1kb2N1bWVudC1ub3QtY2FsbGVkPVJpY2hpYW1hcmUgbGEgcHJvcHJpZXRcdTAwRTAgInswfSIgZG9wbyBsJydlc2VjdXppb25lIGRlbGwnJ2V2ZW50byBzdGFydERvY3VtZW50Ci1udWxscGFyYW1ldGVyPWlsIHBhcmFtZXRybyBkZWwgbm9tZSBwZXIgInswfSIgXHUwMEU4IG51bGxvCi1lcnJvckhhbmRsZXJOb3RTZXQ9QXZ2ZXJ0ZW56YTogbGEgY29udmFsaWRhIFx1MDBFOCBzdGF0YSBhdHRpdmF0YSwgbWEgb3JnLnhtbC5zYXguRXJyb3JIYW5kbGVyIG5vbiBcdTAwRTggc3RhdG8gaW1wb3N0YXRvLCBpbCBjaGUgcG90cmViYmUgZXNzZXJlIHVuIGVycm9yZS4gSWwgcGFyc2VyIHV0aWxpenplclx1MDBFMCB1biBFcnJvckhhbmRsZXIgcHJlZGVmaW5pdG8gcGVyIHZpc3VhbGl6emFyZSBpIHByaW1pIHswfSBlcnJvcmkuIFJpY2hpYW1hcmUgaWwgbWV0b2RvICcnc2V0RXJyb3JIYW5kbGVyJycgcGVyIGNvcnJlZ2dlcmUgcXVlc3RvIHByb2JsZW1hLgotZXJyb3JIYW5kbGVyRGVidWdNc2c9RXJyb3JlOiBVUkkgPSAiezB9IiwgcmlnYSA9ICJ7MX0iLCA6IHsyfSAKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1NBWE1lc3NhZ2VzX2phLnByb3BlcnRpZXMgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9TQVhNZXNzYWdlc19qYS5wcm9wZXJ0aWVzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiYjcwZjM5Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1NBWE1lc3NhZ2VzX2phLnByb3BlcnRpZXMKKysrIC9kZXYvbnVsbApAQCAtMSwzNSArMCwwIEBACi0jIFRoaXMgZmlsZSBzdG9yZXMgbG9jYWxpemVkIG1lc3NhZ2VzIGZvciB0aGUgWGVyY2VzCi0jIFNBWCBpbXBsZW1lbnRhdGlvbi4KLSMKLSMgVGhlIG1lc3NhZ2VzIGFyZSBhcnJhbmdlZCBpbiBrZXkgYW5kIHZhbHVlIHR1cGxlcyBpbiBhIExpc3RSZXNvdXJjZUJ1bmRsZS4KLSMKLQotCi1CYWRNZXNzYWdlS2V5ID0gXHUzMEUxXHUzMEMzXHUzMEJCXHUzMEZDXHUzMEI4XHUzMEZCXHUzMEFEXHUzMEZDXHUzMDZCXHU1QkZFXHU1RkRDXHUzMDU5XHUzMDhCXHUzMEE4XHUzMEU5XHUzMEZDXHUzMEZCXHUzMEUxXHUzMEMzXHUzMEJCXHUzMEZDXHUzMEI4XHUzMDRDXHU4OThCXHUzMDY0XHUzMDRCXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi1Gb3JtYXRGYWlsZWQgPSBcdTZCMjFcdTMwNkVcdTMwRTFcdTMwQzNcdTMwQkJcdTMwRkNcdTMwQjhcdTMwNkVcdTY2RjhcdTVGMEZcdThBMkRcdTVCOUFcdTRFMkRcdTMwNkJcdTUxODVcdTkwRThcdTMwQThcdTMwRTlcdTMwRkNcdTMwNENcdTc2N0FcdTc1MUZcdTMwNTdcdTMwN0VcdTMwNTdcdTMwNUY6XG4KLQotIyBKQVhQIG1lc3NhZ2VzCi1zY2hlbWEtbm90LXN1cHBvcnRlZCA9IFx1NjMwN1x1NUI5QVx1MzA1N1x1MzA1Rlx1MzBCOVx1MzBBRFx1MzBGQ1x1MzBERVx1OEEwMFx1OEE5RVx1MzA2Rlx1MzBCNVx1MzBERFx1MzBGQ1x1MzBDOFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotamF4cC1vcmRlci1ub3Qtc3VwcG9ydGVkID0gXHUzMEQ3XHUzMEVEXHUzMEQxXHUzMEM2XHUzMEEzJyd7MX0nJ1x1MzA5Mlx1OEEyRFx1NUI5QVx1MzA1OVx1MzA4Qlx1NTI0RFx1MzA2Qlx1MzBEN1x1MzBFRFx1MzBEMVx1MzBDNlx1MzBBMycnezB9JydcdTMwOTJcdThBMkRcdTVCOUFcdTMwNTlcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIgCi1zY2hlbWEtYWxyZWFkeS1zcGVjaWZpZWQgPSBudWxsXHU0RUU1XHU1OTE2XHUzMDZFXHUzMEI5XHUzMEFEXHUzMEZDXHUzMERFXHUzMEZCXHUzMEFBXHUzMEQ2XHUzMEI4XHUzMEE3XHUzMEFGXHUzMEM4XHUzMDRDXHUzMDU5XHUzMDY3XHUzMDZCXHU2MzA3XHU1QjlBXHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDhCXHU1ODM0XHU1NDA4XHUzMDAxXHUzMEQ3XHUzMEVEXHUzMEQxXHUzMEM2XHUzMEEzJyd7MH0nJ1x1MzA2Rlx1OEEyRFx1NUI5QVx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotCi0jIGZlYXR1cmUgbWVzc2FnZXMKLWZlYXR1cmUtbm90LXN1cHBvcnRlZCA9IFx1NkE1Rlx1ODBGRCcnezB9JydcdTMwNkZcdTMwQjVcdTMwRERcdTMwRkNcdTMwQzhcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLWZlYXR1cmUtbm90LXJlY29nbml6ZWQgPSBcdTZBNUZcdTgwRkQnJ3swfScnXHUzMDZGXHU4QThEXHU4QjU4XHUzMDU1XHUzMDhDXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi10cnVlLW5vdC1zdXBwb3J0ZWQgPSBcdTZBNUZcdTgwRkQnJ3swfScnXHUzMDZFdHJ1ZVx1MzA2RVx1NzJCNlx1NjE0Qlx1MzA2Rlx1MzBCNVx1MzBERFx1MzBGQ1x1MzBDOFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotZmFsc2Utbm90LXN1cHBvcnRlZCA9IFx1NkE1Rlx1ODBGRCcnezB9JydcdTMwNkVmYWxzZVx1MzA2RVx1NzJCNlx1NjE0Qlx1MzA2Rlx1MzBCNVx1MzBERFx1MzBGQ1x1MzBDOFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotZmVhdHVyZS1yZWFkLW9ubHkgPSBcdTZBNUZcdTgwRkQnJ3swfScnXHUzMDZGXHU4QUFEXHU1M0Q2XHUzMDhBXHU1QzAyXHU3NTI4XHUzMDY3XHUzMDU5XHUzMDAyCi1qYXhwLXNlY3VyZXByb2Nlc3NpbmctZmVhdHVyZSA9IEZFQVRVUkVfU0VDVVJFX1BST0NFU1NJTkc6IFx1MzBCQlx1MzBBRFx1MzBFNVx1MzBFQVx1MzBDNlx1MzBBM1x1MzBGQlx1MzBERVx1MzBDRFx1MzBGQ1x1MzBCOFx1MzBFM1x1MzA0Q1x1NUI1OFx1NTcyOFx1MzA1OVx1MzA4Qlx1MzA2OFx1MzA0RFx1MzAwMVx1NkE1Rlx1ODBGRFx1MzA5MmZhbHNlXHUzMDZCXHU4QTJEXHU1QjlBXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0KLSMgcHJvcGVydHkgbWVzc2FnZXMKLXByb3BlcnR5LW5vdC1zdXBwb3J0ZWQgPSBcdTMwRDdcdTMwRURcdTMwRDFcdTMwQzZcdTMwQTMnJ3swfScnXHUzMDZGXHUzMEI1XHUzMEREXHUzMEZDXHUzMEM4XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi1wcm9wZXJ0eS1ub3QtcmVjb2duaXplZCA9IFx1MzBEN1x1MzBFRFx1MzBEMVx1MzBDNlx1MzBBMycnezB9JydcdTMwNkZcdThBOERcdThCNThcdTMwNTVcdTMwOENcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLXByb3BlcnR5LXJlYWQtb25seSA9IFx1MzBEN1x1MzBFRFx1MzBEMVx1MzBDNlx1MzBBMycnezB9JydcdTMwNkZcdThBQURcdTUzRDZcdTMwOEFcdTVDMDJcdTc1MjhcdTMwNjdcdTMwNTlcdTMwMDIKLXByb3BlcnR5LW5vdC1wYXJzaW5nLXN1cHBvcnRlZCA9IFx1ODlFM1x1Njc5MFx1NEUyRFx1MzA2Qlx1MzA2Rlx1MzBEN1x1MzBFRFx1MzBEMVx1MzBDNlx1MzBBMycnezB9JydcdTMwNkZcdTMwQjVcdTMwRERcdTMwRkNcdTMwQzhcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLWRvbS1ub2RlLXJlYWQtbm90LXN1cHBvcnRlZCA9IERPTVx1MzBDRVx1MzBGQ1x1MzBDOVx1MzBGQlx1MzBEN1x1MzBFRFx1MzBEMVx1MzBDNlx1MzBBM1x1MzA5Mlx1OEFBRFx1MzA3Rlx1NTNENlx1MzA4Q1x1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMkRPTVx1MzBDNFx1MzBFQVx1MzBGQ1x1MzA0Q1x1NUI1OFx1NTcyOFx1MzA1N1x1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotaW5jb21wYXRpYmxlLWNsYXNzID0gXHUzMEQ3XHUzMEVEXHUzMEQxXHUzMEM2XHUzMEEzJyd7MH0nJ1x1MzA2Qlx1NjMwN1x1NUI5QVx1MzA1N1x1MzA1Rlx1NTAyNFx1MzA2RnsxfVx1MzA2Qlx1MzBBRFx1MzBFM1x1MzBCOVx1MzBDOFx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotCi1zdGFydC1kb2N1bWVudC1ub3QtY2FsbGVkPXN0YXJ0RG9jdW1lbnRcdTMwQTRcdTMwRDlcdTMwRjNcdTMwQzhcdTMwNENcdTMwQjlcdTMwRURcdTMwRkNcdTMwNTVcdTMwOENcdTMwNUZcdTVGOENcdTMwMDFcdTMwRDdcdTMwRURcdTMwRDFcdTMwQzZcdTMwQTMiezB9Ilx1MzA5Mlx1NTQ3Q1x1MzA3M1x1NTFGQVx1MzA1OVx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OQotbnVsbHBhcmFtZXRlcj0iezB9Ilx1MzA2RVx1NTQwRFx1NTI0RFx1MzBEMVx1MzBFOVx1MzBFMVx1MzBGQ1x1MzBCRlx1MzA0Q251bGxcdTMwNjdcdTMwNTkKLWVycm9ySGFuZGxlck5vdFNldD1cdThCNjZcdTU0NEE6IFx1NjkxQ1x1OEEzQ1x1MzA2Rlx1MzBBQVx1MzBGM1x1MzA2Qlx1MzA2QVx1MzA2M1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OVx1MzA0Q1x1MzAwMW9yZy54bWwuc2F4LkVycm9ySGFuZGxlclx1MzA0Q1x1OEEyRFx1NUI5QVx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMlx1NUZDNVx1ODk4MVx1MzA2OFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA4Qlx1MzBDRlx1MzBGM1x1MzBDOVx1MzBFOVx1MzA2Rlx1MzA1M1x1MzA2RVx1MzBDRlx1MzBGM1x1MzBDOVx1MzBFOVx1MzA2N1x1MzA2Rlx1MzA2QVx1MzA0NFx1NTNFRlx1ODBGRFx1NjAyN1x1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMlx1MzBEMVx1MzBGQ1x1MzBCNVx1MzBGQ1x1MzA2N1x1MzA2Rlx1MzAwMVx1MzBDN1x1MzBENVx1MzBBOVx1MzBFQlx1MzBDOFx1MzA2RUVycm9ySGFuZGxlclx1MzA5Mlx1NEY3Rlx1NzUyOFx1MzA1N1x1MzA2Nlx1NjcwMFx1NTIxRFx1MzA2RXswfVx1MzBBOFx1MzBFOVx1MzBGQ1x1MzA0Q1x1NTFGQVx1NTI5Qlx1MzA1NVx1MzA4Q1x1MzA3RVx1MzA1OVx1MzAwMlx1MzA1M1x1MzA2RVx1NTU0Rlx1OTg0Q1x1MzA5Mlx1NEZFRVx1NkI2M1x1MzA1OVx1MzA4Qlx1MzA2Qlx1MzA2Rlx1MzAwMScnc2V0RXJyb3JIYW5kbGVyJydcdTMwRTFcdTMwQkRcdTMwQzNcdTMwQzlcdTMwOTJcdTU0N0NcdTMwNzNcdTUxRkFcdTMwNTdcdTMwNjZcdTMwNEZcdTMwNjBcdTMwNTVcdTMwNDRcdTMwMDIKLWVycm9ySGFuZGxlckRlYnVnTXNnPVx1MzBBOFx1MzBFOVx1MzBGQzogVVJJID0gInswfSJcdTMwMDFcdTg4NEMgPSAiezF9Ilx1MzAwMTogezJ9IApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvU0FYTWVzc2FnZXNfa28ucHJvcGVydGllcyBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1NBWE1lc3NhZ2VzX2tvLnByb3BlcnRpZXMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDZjYTQzMWEuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvU0FYTWVzc2FnZXNfa28ucHJvcGVydGllcworKysgL2Rldi9udWxsCkBAIC0xLDM1ICswLDAgQEAKLSMgVGhpcyBmaWxlIHN0b3JlcyBsb2NhbGl6ZWQgbWVzc2FnZXMgZm9yIHRoZSBYZXJjZXMKLSMgU0FYIGltcGxlbWVudGF0aW9uLgotIwotIyBUaGUgbWVzc2FnZXMgYXJlIGFycmFuZ2VkIGluIGtleSBhbmQgdmFsdWUgdHVwbGVzIGluIGEgTGlzdFJlc291cmNlQnVuZGxlLgotIwotCi0KLUJhZE1lc3NhZ2VLZXkgPSBcdUJBNTRcdUMyRENcdUM5QzAgXHVEMEE0XHVDNUQwIFx1RDU3NFx1QjJGOVx1RDU1OFx1QjI5NCBcdUM2MjRcdUI5NTggXHVCQTU0XHVDMkRDXHVDOUMwXHVCOTdDIFx1Q0MzRVx1Qzc0NCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LgotRm9ybWF0RmFpbGVkID0gXHVCMkU0XHVDNzRDIFx1QkE1NFx1QzJEQ1x1QzlDMFx1Qzc1OCBcdUQ2MTVcdUMyRERcdUM3NDQgXHVDOUMwXHVDODE1XHVENTU4XHVCMjk0IFx1QzkxMSBcdUIwQjRcdUJEODAgXHVDNjI0XHVCOTU4XHVBQzAwIFx1QkMxQ1x1QzBERFx1RDU4OFx1QzJCNVx1QjJDOFx1QjJFNC5cbgotCi0jIEpBWFAgbWVzc2FnZXMKLXNjaGVtYS1ub3Qtc3VwcG9ydGVkID0gXHVDOUMwXHVDODE1XHVCNDFDIFx1QzJBNFx1RDBBNFx1QjlDOCBcdUM1QjhcdUM1QjRcdUIyOTQgXHVDOUMwXHVDNkQwXHVCNDE4XHVDOUMwIFx1QzU0QVx1QzJCNVx1QjJDOFx1QjJFNC4KLWpheHAtb3JkZXItbm90LXN1cHBvcnRlZCA9ICcnezF9JycgXHVDMThEXHVDMTMxXHVDNzQ0IFx1QzEyNFx1QzgxNVx1RDU1OFx1QUUzMCBcdUM4MDRcdUM1RDAgJyd7MH0nJyBcdUMxOERcdUMxMzFcdUM3NDQgXHVDMTI0XHVDODE1XHVENTc0XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4gCi1zY2hlbWEtYWxyZWFkeS1zcGVjaWZpZWQgPSBcdUIxMTBcdUM3NzQgXHVDNTQ0XHVCMkNDIFx1QzJBNFx1RDBBNFx1QjlDOCBcdUFDMURcdUNDQjRcdUFDMDAgXHVDNzc0XHVCQkY4IFx1QzlDMFx1QzgxNVx1QjQxQyBcdUFDQkRcdUM2QjAgJyd7MH0nJyBcdUMxOERcdUMxMzFcdUM3NDQgXHVDMTI0XHVDODE1XHVENTYwIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuCi0KLSMgZmVhdHVyZSBtZXNzYWdlcwotZmVhdHVyZS1ub3Qtc3VwcG9ydGVkID0gJyd7MH0nJyBcdUFFMzBcdUIyQTVcdUM3NDAgXHVDOUMwXHVDNkQwXHVCNDE4XHVDOUMwIFx1QzU0QVx1QzJCNVx1QjJDOFx1QjJFNC4KLWZlYXR1cmUtbm90LXJlY29nbml6ZWQgPSAnJ3swfScnIFx1QUUzMFx1QjJBNVx1Qzc0NCBcdUM3NzhcdUMyRERcdUQ1NjAgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4KLXRydWUtbm90LXN1cHBvcnRlZCA9ICcnezB9JycgXHVBRTMwXHVCMkE1XHVDNzU4IFRydWUgXHVDMEMxXHVEMERDXHVCMjk0IFx1QzlDMFx1QzZEMFx1QjQxOFx1QzlDMCBcdUM1NEFcdUMyQjVcdUIyQzhcdUIyRTQuCi1mYWxzZS1ub3Qtc3VwcG9ydGVkID0gJyd7MH0nJyBcdUFFMzBcdUIyQTVcdUM3NTggRmFsc2UgXHVDMEMxXHVEMERDXHVCMjk0IFx1QzlDMFx1QzZEMFx1QjQxOFx1QzlDMCBcdUM1NEFcdUMyQjVcdUIyQzhcdUIyRTQuCi1mZWF0dXJlLXJlYWQtb25seSA9ICcnezB9JycgXHVBRTMwXHVCMkE1XHVDNzQwIFx1Qzc3RFx1QUUzMCBcdUM4MDRcdUM2QTlcdUM3ODVcdUIyQzhcdUIyRTQuCi1qYXhwLXNlY3VyZXByb2Nlc3NpbmctZmVhdHVyZSA9IEZFQVRVUkVfU0VDVVJFX1BST0NFU1NJTkc6IFx1QkNGNFx1QzU0OCBcdUFEMDBcdUI5QUNcdUM3OTBcdUFDMDAgXHVDNzg4XHVDNzQ0IFx1QUNCRFx1QzZCMCBcdUFFMzBcdUIyQTVcdUM3NDQgZmFsc2VcdUI4NUMgXHVDMTI0XHVDODE1XHVENTYwIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuCi0KLSMgcHJvcGVydHkgbWVzc2FnZXMKLXByb3BlcnR5LW5vdC1zdXBwb3J0ZWQgPSAnJ3swfScnIFx1QzE4RFx1QzEzMVx1Qzc0MCBcdUM5QzBcdUM2RDBcdUI0MThcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0LgotcHJvcGVydHktbm90LXJlY29nbml6ZWQgPSAnJ3swfScnIFx1QzE4RFx1QzEzMVx1Qzc0NCBcdUM3NzhcdUMyRERcdUQ1NjAgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4KLXByb3BlcnR5LXJlYWQtb25seSA9ICcnezB9JycgXHVDMThEXHVDMTMxXHVDNzQwIFx1Qzc3RFx1QUUzMCBcdUM4MDRcdUM2QTlcdUM3ODVcdUIyQzhcdUIyRTQuCi1wcm9wZXJ0eS1ub3QtcGFyc2luZy1zdXBwb3J0ZWQgPSBcdUFENkNcdUJCMzggXHVCRDg0XHVDMTFEIFx1QzkxMSAnJ3swfScnIFx1QzE4RFx1QzEzMVx1Qzc0MCBcdUM5QzBcdUM2RDBcdUI0MThcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0LgotZG9tLW5vZGUtcmVhZC1ub3Qtc3VwcG9ydGVkID0gRE9NIFx1QjE3OFx1QjREQyBcdUMxOERcdUMxMzFcdUM3NDQgXHVDNzdEXHVDNzQ0IFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuIERPTSBcdUQyQjhcdUI5QUNcdUFDMDAgXHVDODc0XHVDN0FDXHVENTU4XHVDOUMwIFx1QzU0QVx1QzJCNVx1QjJDOFx1QjJFNC4KLWluY29tcGF0aWJsZS1jbGFzcyA9ICcnezB9JycgXHVDMThEXHVDMTMxXHVDNUQwIFx1QjMwMFx1RDU3NCBcdUM5QzBcdUM4MTVcdUI0MUMgXHVBQzEyXHVDNzU4IFx1QjM3MFx1Qzc3NFx1RDEzMFx1RDYxNVx1Qzc0NCB7MX0oXHVDNzNDKVx1Qjg1QyBcdUJDQzBcdUQ2NThcdUQ1NjAgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4KLQotc3RhcnQtZG9jdW1lbnQtbm90LWNhbGxlZD0iezB9IiBcdUMxOERcdUMxMzFcdUM3NDAgc3RhcnREb2N1bWVudCBcdUM3NzRcdUJDQTRcdUQyQjhcdUFDMDAgXHVCQzFDXHVDMEREXHVCNDFDIFx1RDZDNCBcdUQ2MzhcdUNEOUNcdUQ1NzRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotbnVsbHBhcmFtZXRlcj0iezB9Ilx1QzVEMCBcdUIzMDBcdUQ1NUMgXHVDNzc0XHVCOTg0IFx1QjlFNFx1QUMxQ1x1QkNDMFx1QzIxOFx1QUMwMCBcdUIxMTBcdUM3ODVcdUIyQzhcdUIyRTQuCi1lcnJvckhhbmRsZXJOb3RTZXQ9XHVBQ0JEXHVBQ0UwOiBcdUFDODBcdUM5OURcdUM3NzQgXHVDMTI0XHVDODE1XHVCNDE4XHVDNUM4XHVDOUMwXHVCOUNDIG9yZy54bWwuc2F4LkVycm9ySGFuZGxlclx1QUMwMCBcdUM4MDFcdUM4MDhcdUQ3ODggXHVDMTI0XHVDODE1XHVCNDE4XHVDOUMwIFx1QzU0QVx1QzU1OFx1QzJCNVx1QjJDOFx1QjJFNC4gXHVBRDZDXHVCQjM4IFx1QkQ4NFx1QzExRFx1QUUzMFx1QUMwMCBcdUFFMzBcdUJDRjggRXJyb3JIYW5kbGVyXHVCOTdDIFx1QzBBQ1x1QzZBOVx1RDU1OFx1QzVFQyBcdUNDOThcdUM3NEMgezB9XHVBQzFDXHVDNzU4IFx1QzYyNFx1Qjk1OFx1Qjk3QyBcdUM3NzhcdUMxQzRcdUQ1NjlcdUIyQzhcdUIyRTQuIFx1Qzc3NCBcdUM2MjRcdUI5NThcdUI5N0MgXHVDMjE4XHVDODE1XHVENTU4XHVCODI0XHVCQTc0ICcnc2V0RXJyb3JIYW5kbGVyJycgXHVCQTU0XHVDMThDXHVCNERDXHVCOTdDIFx1RDYzOFx1Q0Q5Q1x1RDU1OFx1QzJFRFx1QzJEQ1x1QzYyNC4KLWVycm9ySGFuZGxlckRlYnVnTXNnPVx1QzYyNFx1Qjk1ODogVVJJID0gInswfSIsIFx1RDU4OSA9ICJ7MX0iLCA6IHsyfSAKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1NBWE1lc3NhZ2VzX3B0X0JSLnByb3BlcnRpZXMgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9TQVhNZXNzYWdlc19wdF9CUi5wcm9wZXJ0aWVzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhZjE4ZDYxLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1NBWE1lc3NhZ2VzX3B0X0JSLnByb3BlcnRpZXMKKysrIC9kZXYvbnVsbApAQCAtMSwzNSArMCwwIEBACi0jIFRoaXMgZmlsZSBzdG9yZXMgbG9jYWxpemVkIG1lc3NhZ2VzIGZvciB0aGUgWGVyY2VzCi0jIFNBWCBpbXBsZW1lbnRhdGlvbi4KLSMKLSMgVGhlIG1lc3NhZ2VzIGFyZSBhcnJhbmdlZCBpbiBrZXkgYW5kIHZhbHVlIHR1cGxlcyBpbiBhIExpc3RSZXNvdXJjZUJ1bmRsZS4KLSMKLQotCi1CYWRNZXNzYWdlS2V5ID0gTlx1MDBFM28gZm9pIHBvc3NcdTAwRUR2ZWwgZW5jb250cmFyIGEgbWVuc2FnZW0gZGUgZXJybyBjb3JyZXNwb25kZW50ZSBcdTAwRTAgY2hhdmUgZGEgbWVuc2FnZW0uCi1Gb3JtYXRGYWlsZWQgPSBPY29ycmV1IHVtIGVycm8gaW50ZXJubyBhbyBmb3JtYXRhciBhIG1lbnNhZ2VtIGEgc2VndWlyOlxuCi0KLSMgSkFYUCBtZXNzYWdlcwotc2NoZW1hLW5vdC1zdXBwb3J0ZWQgPSBPIGlkaW9tYSBkbyBlc3F1ZW1hIGVzcGVjaWZpY2FkbyBuXHUwMEUzbyBcdTAwRTkgc3Vwb3J0YWRvLgotamF4cC1vcmRlci1ub3Qtc3VwcG9ydGVkID0gQSBwcm9wcmllZGFkZSAnJ3swfScnIGRldmUgc2VyIGRlZmluaWRhIGFudGVzIGRhIGRlZmluaVx1MDBFN1x1MDBFM28gZGEgcHJvcHJpZWRhZGUgJyd7MX0nJy4gCi1zY2hlbWEtYWxyZWFkeS1zcGVjaWZpZWQgPSBBIHByb3ByaWVkYWRlICcnezB9Jycgblx1MDBFM28gcG9kZSBzZXIgZGVmaW5pZGEgcXVhbmRvIHVtIG9iamV0byBkbyBFc3F1ZW1hIG5cdTAwRTNvIG51bG8galx1MDBFMSB0aXZlciBzaWRvIGVzcGVjaWZpY2Fkby4KLQotIyBmZWF0dXJlIG1lc3NhZ2VzCi1mZWF0dXJlLW5vdC1zdXBwb3J0ZWQgPSBPIHJlY3Vyc28gJyd7MH0nJyBuXHUwMEUzbyBcdTAwRTkgc3Vwb3J0YWRvLgotZmVhdHVyZS1ub3QtcmVjb2duaXplZCA9IE8gcmVjdXJzbyAnJ3swfScnIG5cdTAwRTNvIFx1MDBFOSByZWNvbmhlY2lkby4KLXRydWUtbm90LXN1cHBvcnRlZCA9IEVzdGFkbyB2ZXJkYWRlaXJvIGRvIHJlY3Vyc28gJyd7MH0nJyBuXHUwMEUzbyBzdXBvcnRhZG8uCi1mYWxzZS1ub3Qtc3VwcG9ydGVkID0gRXN0YWRvIGZhbHNvIGRvIHJlY3Vyc28gJyd7MH0nJyBuXHUwMEUzbyBzdXBvcnRhZG8uCi1mZWF0dXJlLXJlYWQtb25seSA9IE8gcmVjdXJzbyAnJ3swfScnIFx1MDBFOSBzb21lbnRlIHBhcmEgbGVpdHVyYS4KLWpheHAtc2VjdXJlcHJvY2Vzc2luZy1mZWF0dXJlID0gRkVBVFVSRV9TRUNVUkVfUFJPQ0VTU0lORzogTlx1MDBFM28gXHUwMEU5IHBvc3NcdTAwRUR2ZWwgZGVmaW5pciBvIHJlY3Vyc28gY29tbyBmYWxzbyBxdWFuZG8gbyBnZXJlbmNpYWRvciBkZSBzZWd1cmFuXHUwMEU3YSBlc3RcdTAwRTEgcHJlc2VudGUuCi0KLSMgcHJvcGVydHkgbWVzc2FnZXMKLXByb3BlcnR5LW5vdC1zdXBwb3J0ZWQgPSBBIHByb3ByaWVkYWRlICcnezB9Jycgblx1MDBFM28gXHUwMEU5IHN1cG9ydGFkYS4KLXByb3BlcnR5LW5vdC1yZWNvZ25pemVkID0gQSBwcm9wcmllZGFkZSAnJ3swfScnIG5cdTAwRTNvIFx1MDBFOSByZWNvbmhlY2lkYS4KLXByb3BlcnR5LXJlYWQtb25seSA9IEEgcHJvcHJpZWRhZGUgJyd7MH0nJyBcdTAwRTkgc29tZW50ZSBwYXJhIGxlaXR1cmEuCi1wcm9wZXJ0eS1ub3QtcGFyc2luZy1zdXBwb3J0ZWQgPSBBIHByb3ByaWVkYWRlICcnezB9Jycgblx1MDBFM28gXHUwMEU5IHN1cG9ydGFkYSBkdXJhbnRlIG8gcGFyc2luZy4KLWRvbS1ub2RlLXJlYWQtbm90LXN1cHBvcnRlZCA9IE5cdTAwRTNvIFx1MDBFOSBwb3NzXHUwMEVEdmVsIGxlciBhIHByb3ByaWVkYWRlIGRvIG5cdTAwRjMgZGUgRE9NLiBOXHUwMEUzbyBleGlzdGUgdW1hIFx1MDBFMXJ2b3JlIGRlIERPTS4KLWluY29tcGF0aWJsZS1jbGFzcyA9IE8gdmFsb3IgZXNwZWNpZmljYWRvIHBhcmEgYSBwcm9wcmllZGFkZSAnJ3swfScnIG5cdTAwRTNvIHBvZGUgc2VyIHRyYW5zbWl0aWRvIHBhcmEgJyd7MX0nJy4KLQotc3RhcnQtZG9jdW1lbnQtbm90LWNhbGxlZD1BIHByb3ByaWVkYWRlICJ7MH0iIGRldmUgc2VyIGNoYW1hZGEgYXBcdTAwRjNzIG8gZXZlbnRvIHN0YXJ0RG9jdW1lbnQgc2VyIGxhblx1MDBFN2FkbwotbnVsbHBhcmFtZXRlcj1vIHBhclx1MDBFMm1ldHJvIGRlIG5vbWUgZGUgInswfSIgXHUwMEU5IG51bG8KLWVycm9ySGFuZGxlck5vdFNldD1BZHZlcnRcdTAwRUFuY2lhOiBBIHZhbGlkYVx1MDBFN1x1MDBFM28gZm9pIGF0aXZhZGEsIG1hcyB1bSBvcmcueG1sLnNheC5FcnJvckhhbmRsZXIgblx1MDBFM28gZm9pIGRlZmluaWRvLCBwcm92YXZlbG1lbnRlIHBvcnF1ZSBuXHUwMEUzbyBlcmEgbmVjZXNzXHUwMEUxcmlvLiBPIHBhcnNlciB1c2FyXHUwMEUxIHVtIEVycm9ySGFuZGxlciBwYWRyXHUwMEUzbyBwYXJhIGltcHJpbWlyIG9zIHByaW1laXJvcyB7MH0gZXJyb3MuIENoYW1lIG8gbVx1MDBFOXRvZG8gJydzZXRFcnJvckhhbmRsZXInJyBwYXJhIGNvcnJpZ2lyIG8gcHJvYmxlbWEuCi1lcnJvckhhbmRsZXJEZWJ1Z01zZz1FcnJvOiBVUkkgPSAiezB9IiwgTGluaGEgPSAiezF9IiwgOiB7Mn0gCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9TQVhNZXNzYWdlc19zdi5wcm9wZXJ0aWVzIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvU0FYTWVzc2FnZXNfc3YucHJvcGVydGllcwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZjc2MzRmMi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9TQVhNZXNzYWdlc19zdi5wcm9wZXJ0aWVzCisrKyAvZGV2L251bGwKQEAgLTEsMzUgKzAsMCBAQAotIyBUaGlzIGZpbGUgc3RvcmVzIGxvY2FsaXplZCBtZXNzYWdlcyBmb3IgdGhlIFhlcmNlcwotIyBTQVggaW1wbGVtZW50YXRpb24uCi0jCi0jIFRoZSBtZXNzYWdlcyBhcmUgYXJyYW5nZWQgaW4ga2V5IGFuZCB2YWx1ZSB0dXBsZXMgaW4gYSBMaXN0UmVzb3VyY2VCdW5kbGUuCi0jCi0KLQotQmFkTWVzc2FnZUtleSA9IEhpdHRhciBpbnRlIGZlbG1lZGRlbGFuZGV0IHNvbSBtb3RzdmFyYXIgbWVkZGVsYW5kZW55Y2tlbG4uCi1Gb3JtYXRGYWlsZWQgPSBFdHQgaW50ZXJudCBmZWwgaW50clx1MDBFNGZmYWRlIHZpZCBmb3JtYXRlcmluZyBhdiBmXHUwMEY2bGphbmRlIG1lZGRlbGFuZGU6XG4KLQotIyBKQVhQIG1lc3NhZ2VzCi1zY2hlbWEtbm90LXN1cHBvcnRlZCA9IEFuZ2l2ZXQgc2NoZW1hc3ByXHUwMEU1ayBzdFx1MDBGNmRzIGludGUuCi1qYXhwLW9yZGVyLW5vdC1zdXBwb3J0ZWQgPSBFZ2Vuc2thcGVuICcnezB9JycgbVx1MDBFNXN0ZSBhbmdlcyBmXHUwMEY2cmUgaW5zdFx1MDBFNGxsbmluZyBhdiBlZ2Vuc2thcGVuICcnezF9JycuIAotc2NoZW1hLWFscmVhZHktc3BlY2lmaWVkID0gRWdlbnNrYXBlbiAnJ3swfScnIGthbiBpbnRlIGFuZ2VzIG9tIGV0dCBTY2hlbWEtb2JqZWt0IHNvbSBcdTAwRTRyIGlja2UtbnVsbCByZWRhbiBoYXIgYW5nZXR0cy4KLQotIyBmZWF0dXJlIG1lc3NhZ2VzCi1mZWF0dXJlLW5vdC1zdXBwb3J0ZWQgPSBGdW5rdGlvbmVuICcnezB9Jycgc3RcdTAwRjZkcyBpbnRlLgotZmVhdHVyZS1ub3QtcmVjb2duaXplZCA9IEZ1bmt0aW9uZW4gJyd7MH0nJyBcdTAwRTRyIG9rXHUwMEU0bmQuCi10cnVlLW5vdC1zdXBwb3J0ZWQgPSBUcnVlLXRpbGxzdFx1MDBFNW5kIGZcdTAwRjZyIGZ1bmt0aW9uZW4gJyd7MH0nJyBzdFx1MDBGNmRzIGludGUuCi1mYWxzZS1ub3Qtc3VwcG9ydGVkID0gRmFsc2UtdGlsbHN0XHUwMEU1bmQgZlx1MDBGNnIgZnVua3Rpb25lbiAnJ3swfScnIHN0XHUwMEY2ZHMgaW50ZS4KLWZlYXR1cmUtcmVhZC1vbmx5ID0gRnVua3Rpb25lbiAnJ3swfScnIFx1MDBFNHIgc2tyaXZza3lkZGFkLgotamF4cC1zZWN1cmVwcm9jZXNzaW5nLWZlYXR1cmUgPSBGRUFUVVJFX1NFQ1VSRV9QUk9DRVNTSU5HOiBGdW5rdGlvbmVuIGthbiBpbnRlIGFuZ2VzIHRpbGwgZmFsc2Ugb20gc1x1MDBFNGtlcmhldHNoYW50ZXJhcmVuIGFudlx1MDBFNG5kcy4KLQotIyBwcm9wZXJ0eSBtZXNzYWdlcwotcHJvcGVydHktbm90LXN1cHBvcnRlZCA9IEVnZW5za2FwZW4gJyd7MH0nJyBzdFx1MDBGNmRzIGludGUuCi1wcm9wZXJ0eS1ub3QtcmVjb2duaXplZCA9IEVnZW5za2FwZW4gJyd7MH0nJyBcdTAwRTRyIG9rXHUwMEU0bmQuCi1wcm9wZXJ0eS1yZWFkLW9ubHkgPSBFZ2Vuc2thcGVuICcnezB9JycgXHUwMEU0ciBza3JpdnNreWRkYWQuCi1wcm9wZXJ0eS1ub3QtcGFyc2luZy1zdXBwb3J0ZWQgPSBFZ2Vuc2thcGVuICcnezB9Jycgc3RcdTAwRjZkcyBpbnRlIHZpZCB0b2xrbmluZy4KLWRvbS1ub2RlLXJlYWQtbm90LXN1cHBvcnRlZCA9IEthbiBpbnRlIGxcdTAwRTRzYSBlZ2Vuc2thcCBmXHUwMEY2ciBET00tbm9kLiBEZXQgZmlubnMgaW5nZXQgRE9NLXRyXHUwMEU0ZC4KLWluY29tcGF0aWJsZS1jbGFzcyA9IFZcdTAwRTRyZGV0IGFuZ2l2ZXQgZlx1MDBGNnIgZWdlbnNrYXBlbiAnJ3swfScnIGthbiBpbnRlIG9tdmFuZGxhcyB0aWxsIHsxfS4KLQotc3RhcnQtZG9jdW1lbnQtbm90LWNhbGxlZD1FZ2Vuc2thcGVuICJ7MH0iIGJcdTAwRjZyIGFucm9wYXMgZWZ0ZXIgc3RhcnREb2N1bWVudC1oXHUwMEU0bmRlbHNlbiB1dGxcdTAwRjZzZXMKLW51bGxwYXJhbWV0ZXI9bmFtbnBhcmFtZXRlcm4gZlx1MDBGNnIgInswfSIgXHUwMEU0ciBudWxsCi1lcnJvckhhbmRsZXJOb3RTZXQ9VmFybmluZzogdmFsaWRlcmluZ2VuIHN0YXJ0YWRlcywgbWVuIGRldCBmYW5ucyBpbmdlbiBhbmdpdmVuIG9yZy54bWwuc2F4LkVycm9ySGFuZGxlci4gUGFyc2VyIGFudlx1MDBFNG5kZXIgRXJyb3JIYW5kbGVyIGF2IHN0YW5kYXJkdHlwIHZpZCB1dHNrcmlmdCBhdiBkZSBmXHUwMEY2cnN0YSB7MH0gZmVsZW4uIEtvcnJpZ2VyYSBmZWxldCBnZW5vbSBhbnJvcCBhdiBzZXRFcnJvckhhbmRsZXItbWV0b2Rlbi4KLWVycm9ySGFuZGxlckRlYnVnTXNnPUZlbDogVVJJID0gInswfSIsIFJhZCA9ICJ7MX0iLCA6IHsyfSAKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1NBWE1lc3NhZ2VzX3poX0NOLnByb3BlcnRpZXMgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9TQVhNZXNzYWdlc196aF9DTi5wcm9wZXJ0aWVzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzYjVhNWJjLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1NBWE1lc3NhZ2VzX3poX0NOLnByb3BlcnRpZXMKKysrIC9kZXYvbnVsbApAQCAtMSwzNSArMCwwIEBACi0jIFRoaXMgZmlsZSBzdG9yZXMgbG9jYWxpemVkIG1lc3NhZ2VzIGZvciB0aGUgWGVyY2VzCi0jIFNBWCBpbXBsZW1lbnRhdGlvbi4KLSMKLSMgVGhlIG1lc3NhZ2VzIGFyZSBhcnJhbmdlZCBpbiBrZXkgYW5kIHZhbHVlIHR1cGxlcyBpbiBhIExpc3RSZXNvdXJjZUJ1bmRsZS4KLSMKLQotCi1CYWRNZXNzYWdlS2V5ID0gXHU2MjdFXHU0RTBEXHU1MjMwXHU0RTBFXHU2RDg4XHU2MDZGXHU1MTczXHU5NTJFXHU1QjU3XHU1QkY5XHU1RTk0XHU3Njg0XHU5NTE5XHU4QkVGXHU2RDg4XHU2MDZGXHUzMDAyCi1Gb3JtYXRGYWlsZWQgPSBcdThCQkVcdTdGNkVcdTRFRTVcdTRFMEJcdTZEODhcdTYwNkZcdTc2ODRcdTY4M0NcdTVGMEZcdTY1RjZcdTUxRkFcdTczQjBcdTUxODVcdTkwRThcdTk1MTlcdThCRUY6XG4KLQotIyBKQVhQIG1lc3NhZ2VzCi1zY2hlbWEtbm90LXN1cHBvcnRlZCA9IFx1NEUwRFx1NjUyRlx1NjMwMVx1NjMwN1x1NUI5QVx1NzY4NFx1NjVCOVx1Njg0OFx1OEJFRFx1OEEwMFx1MzAwMgotamF4cC1vcmRlci1ub3Qtc3VwcG9ydGVkID0gXHU1RkM1XHU5ODdCXHU1NzI4XHU4QkJFXHU3RjZFXHU1QzVFXHU2MDI3ICcnezF9JycgXHU0RTRCXHU1MjREXHU4QkJFXHU3RjZFXHU1QzVFXHU2MDI3ICcnezB9JydcdTMwMDIKLXNjaGVtYS1hbHJlYWR5LXNwZWNpZmllZCA9IFx1NjVFMFx1NkNENVx1NTcyOFx1NjMwN1x1NUI5QVx1NEU4Nlx1OTc1RVx1N0E3QSBTY2hlbWEgXHU1QkY5XHU4QzYxXHU3Njg0XHU2MEM1XHU1MUI1XHU0RTBCXHU4QkJFXHU3RjZFXHU1QzVFXHU2MDI3ICcnezB9JydcdTMwMDIKLQotIyBmZWF0dXJlIG1lc3NhZ2VzCi1mZWF0dXJlLW5vdC1zdXBwb3J0ZWQgPSBcdTRFMERcdTY1MkZcdTYzMDFcdTUyOUZcdTgwRkQgJyd7MH0nJ1x1MzAwMgotZmVhdHVyZS1ub3QtcmVjb2duaXplZCA9IFx1NjVFMFx1NkNENVx1OEJDNlx1NTIyQlx1NTI5Rlx1ODBGRCAnJ3swfScnXHUzMDAyCi10cnVlLW5vdC1zdXBwb3J0ZWQgPSBcdTRFMERcdTY1MkZcdTYzMDFcdTUyOUZcdTgwRkQgJyd7MH0nJyBcdTc2ODRcdTIwMUNcdTc3MUZcdTIwMURcdTcyQjZcdTYwMDFcdTMwMDIKLWZhbHNlLW5vdC1zdXBwb3J0ZWQgPSBcdTRFMERcdTY1MkZcdTYzMDFcdTUyOUZcdTgwRkQgJyd7MH0nJyBcdTc2ODRcdTIwMUNcdTUwNDdcdTIwMURcdTcyQjZcdTYwMDFcdTMwMDIKLWZlYXR1cmUtcmVhZC1vbmx5ID0gXHU1MjlGXHU4MEZEICcnezB9JycgXHU0RTNBXHU1M0VBXHU4QkZCXHUzMDAyCi1qYXhwLXNlY3VyZXByb2Nlc3NpbmctZmVhdHVyZSA9IEZFQVRVUkVfU0VDVVJFX1BST0NFU1NJTkc6IFx1NUI1OFx1NTcyOCBTZWN1cml0eSBNYW5hZ2VyIFx1NjVGNiwgXHU2NUUwXHU2Q0Q1XHU1QzA2XHU2QjY0XHU1MjlGXHU4MEZEXHU4QkJFXHU3RjZFXHU0RTNBXHUyMDFDXHU1MDQ3XHUyMDFEXHUzMDAyCi0KLSMgcHJvcGVydHkgbWVzc2FnZXMKLXByb3BlcnR5LW5vdC1zdXBwb3J0ZWQgPSBcdTRFMERcdTY1MkZcdTYzMDFcdTVDNUVcdTYwMjcgJyd7MH0nJ1x1MzAwMgotcHJvcGVydHktbm90LXJlY29nbml6ZWQgPSBcdTY1RTBcdTZDRDVcdThCQzZcdTUyMkJcdTVDNUVcdTYwMjcgJyd7MH0nJ1x1MzAwMgotcHJvcGVydHktcmVhZC1vbmx5ID0gXHU1QzVFXHU2MDI3ICcnezB9JycgXHU0RTNBXHU1M0VBXHU4QkZCXHUzMDAyCi1wcm9wZXJ0eS1ub3QtcGFyc2luZy1zdXBwb3J0ZWQgPSBcdTg5RTNcdTY3OTBcdTY1RjZcdTRFMERcdTY1MkZcdTYzMDFcdTVDNUVcdTYwMjcgJyd7MH0nJ1x1MzAwMgotZG9tLW5vZGUtcmVhZC1ub3Qtc3VwcG9ydGVkID0gXHU2NUUwXHU2Q0Q1XHU4QkZCXHU1M0Q2IERPTSBcdTgyODJcdTcwQjlcdTVDNUVcdTYwMjdcdTMwMDJcdTRFMERcdTVCNThcdTU3MjggRE9NIFx1NjgxMVx1MzAwMgotaW5jb21wYXRpYmxlLWNsYXNzID0gXHU0RTNBXHU1QzVFXHU2MDI3ICcnezB9JycgXHU2MzA3XHU1QjlBXHU3Njg0XHU1MDNDXHU0RTBEXHU4MEZEXHU4RjZDXHU2MzYyXHU0RTNBezF9XHUzMDAyCi0KLXN0YXJ0LWRvY3VtZW50LW5vdC1jYWxsZWQ9XHU1RTk0XHU1NzI4XHU2MjlCXHU1MUZBIHN0YXJ0RG9jdW1lbnQgXHU0RThCXHU0RUY2XHU1NDBFXHU4QzAzXHU3NTI4XHU1QzVFXHU2MDI3ICJ7MH0iCi1udWxscGFyYW1ldGVyPSJ7MH0iIFx1NzY4NFx1NTQwRFx1NzlGMFx1NTNDMlx1NjU3MFx1NEUzQVx1N0E3QVx1NTAzQwotZXJyb3JIYW5kbGVyTm90U2V0PVx1OEI2Nlx1NTQ0QTogXHU1REYyXHU1NDJGXHU3NTI4XHU5QThDXHU4QkMxLCBcdTRGNDZcdTY3MkFcdThCQkVcdTdGNkUgb3JnLnhtbC5zYXguRXJyb3JIYW5kbGVyLCBcdThGRDlcdTUzRUZcdTgwRkRcdTRFMERcdTY2MkZcdTk4ODRcdTY3MUZcdTdFRDNcdTY3OUNcdTMwMDJcdTg5RTNcdTY3OTBcdTU2NjhcdTVDMDZcdTRGN0ZcdTc1MjhcdTlFRDhcdThCQTQgRXJyb3JIYW5kbGVyIFx1Njc2NVx1OEY5M1x1NTFGQVx1NTI0RCB7MH0gXHU0RTJBXHU5NTE5XHU4QkVGXHUzMDAyXHU4QkY3XHU4QzAzXHU3NTI4ICcnc2V0RXJyb3JIYW5kbGVyJycgXHU2NUI5XHU2Q0Q1XHU0RUU1XHU4OUUzXHU1MUIzXHU2QjY0XHU5NUVFXHU5ODk4XHUzMDAyCi1lcnJvckhhbmRsZXJEZWJ1Z01zZz1cdTk1MTlcdThCRUY6IFVSSSA9ICJ7MH0iLCBcdTg4NEMgPSAiezF9IiwgOiB7Mn0gCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9TQVhNZXNzYWdlc196aF9UVy5wcm9wZXJ0aWVzIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvU0FYTWVzc2FnZXNfemhfVFcucHJvcGVydGllcwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMGI3NWQ2NS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9TQVhNZXNzYWdlc196aF9UVy5wcm9wZXJ0aWVzCisrKyAvZGV2L251bGwKQEAgLTEsMzUgKzAsMCBAQAotIyBUaGlzIGZpbGUgc3RvcmVzIGxvY2FsaXplZCBtZXNzYWdlcyBmb3IgdGhlIFhlcmNlcwotIyBTQVggaW1wbGVtZW50YXRpb24uCi0jCi0jIFRoZSBtZXNzYWdlcyBhcmUgYXJyYW5nZWQgaW4ga2V5IGFuZCB2YWx1ZSB0dXBsZXMgaW4gYSBMaXN0UmVzb3VyY2VCdW5kbGUuCi0jCi0KLQotQmFkTWVzc2FnZUtleSA9IFx1NjI3RVx1NEUwRFx1NTIzMFx1NUMwRFx1NjFDOVx1OEEwQVx1NjA2Rlx1N0QyMlx1NUYxNVx1OTM3NVx1NzY4NFx1OTMyRlx1OEFBNFx1OEEwQVx1NjA2Rlx1MzAwMgotRm9ybWF0RmFpbGVkID0gXHU2ODNDXHU1RjBGXHU1MzE2XHU0RTBCXHU1MjE3XHU4QTBBXHU2MDZGXHU2NjQyXHU3NjdDXHU3NTFGXHU1MTY3XHU5MEU4XHU5MzJGXHU4QUE0OlxuCi0KLSMgSkFYUCBtZXNzYWdlcwotc2NoZW1hLW5vdC1zdXBwb3J0ZWQgPSBcdTRFMERcdTY1MkZcdTYzRjRcdTYzMDdcdTVCOUFcdTc2ODRcdTdEQjFcdTg5ODFcdThBOUVcdThBMDBcdTMwMDIKLWpheHAtb3JkZXItbm90LXN1cHBvcnRlZCA9IFx1OEEyRFx1NUI5QVx1NUM2Q1x1NjAyNyAnJ3sxfScnIFx1NEU0Qlx1NTI0RFx1RkYwQ1x1NUZDNVx1OTgwOFx1OEEyRFx1NUI5QVx1NUM2Q1x1NjAyNyAnJ3swfScnXHUzMDAyCi1zY2hlbWEtYWxyZWFkeS1zcGVjaWZpZWQgPSBcdTVERjJcdTdEOTNcdTYzMDdcdTVCOUFcdTk3NUVcdTdBN0FcdTUwM0NcdTdEQjFcdTg5ODFcdTcyNjlcdTRFRjZcdTY2NDJcdUZGMENcdTcxMjFcdTZDRDVcdThBMkRcdTVCOUFcdTVDNkNcdTYwMjcgJyd7MH0nJ1x1MzAwMgotCi0jIGZlYXR1cmUgbWVzc2FnZXMKLWZlYXR1cmUtbm90LXN1cHBvcnRlZCA9IFx1NEUwRFx1NjUyRlx1NjNGNFx1NTI5Rlx1ODBGRCAnJ3swfScnXHUzMDAyCi1mZWF0dXJlLW5vdC1yZWNvZ25pemVkID0gXHU3MTIxXHU2Q0Q1XHU4RkE4XHU4QjU4XHU1MjlGXHU4MEZEICcnezB9JydcdTMwMDIKLXRydWUtbm90LXN1cHBvcnRlZCA9IFx1NEUwRFx1NjUyRlx1NjNGNFx1NTI5Rlx1ODBGRCAnJ3swfScnIFx1NzY4NFx1NzcxRlx1NzJDMFx1NjE0Qlx1MzAwMgotZmFsc2Utbm90LXN1cHBvcnRlZCA9IFx1NEUwRFx1NjUyRlx1NjNGNFx1NTI5Rlx1ODBGRCAnJ3swfScnIFx1NzY4NFx1NTA3RFx1NzJDMFx1NjE0Qlx1MzAwMgotZmVhdHVyZS1yZWFkLW9ubHkgPSBcdTUyOUZcdTgwRkQgJyd7MH0nJyBcdTcwQkFcdTU1MkZcdThCODBcdTMwMDIKLWpheHAtc2VjdXJlcHJvY2Vzc2luZy1mZWF0dXJlID0gRkVBVFVSRV9TRUNVUkVfUFJPQ0VTU0lORzogXHU1Qjg5XHU1MTY4XHU3QkExXHU3NDA2XHU3QTBCXHU1RjBGXHU1QjU4XHU1NzI4XHU2NjQyXHVGRjBDXHU3MTIxXHU2Q0Q1XHU1QzA3XHU1MjlGXHU4MEZEXHU4QTJEXHU3MEJBXHU1MDdEXHUzMDAyCi0KLSMgcHJvcGVydHkgbWVzc2FnZXMKLXByb3BlcnR5LW5vdC1zdXBwb3J0ZWQgPSBcdTRFMERcdTY1MkZcdTYzRjRcdTVDNkNcdTYwMjcgJyd7MH0nJ1x1MzAwMgotcHJvcGVydHktbm90LXJlY29nbml6ZWQgPSBcdTcxMjFcdTZDRDVcdThGQThcdThCNThcdTVDNkNcdTYwMjcgJyd7MH0nJ1x1MzAwMgotcHJvcGVydHktcmVhZC1vbmx5ID0gXHU1QzZDXHU2MDI3ICcnezB9JycgXHU3MEJBXHU1NTJGXHU4QjgwXHUzMDAyCi1wcm9wZXJ0eS1ub3QtcGFyc2luZy1zdXBwb3J0ZWQgPSBcdTUyNTZcdTY3OTBcdTY2NDJcdTRFMERcdTY1MkZcdTYzRjRcdTVDNkNcdTYwMjcgJyd7MH0nJ1x1MzAwMgotZG9tLW5vZGUtcmVhZC1ub3Qtc3VwcG9ydGVkID0gXHU3MTIxXHU2Q0Q1XHU4QjgwXHU1M0Q2IERPTSBcdTdCQzBcdTlFREVcdTVDNkNcdTYwMjdcdTMwMDJET00gXHU2QTM5XHU3MkMwXHU3RDUwXHU2OUNCXHU0RTBEXHU1QjU4XHU1NzI4XHUzMDAyCi1pbmNvbXBhdGlibGUtY2xhc3MgPSBcdTcwQkFcdTVDNkNcdTYwMjcgJyd7MH0nJyBcdTYzMDdcdTVCOUFcdTc2ODRcdTUwM0NcdTRFMERcdTUzRUZcdThGNDlcdTYzREJcdTcwQkEgezF9XHUzMDAyCi0KLXN0YXJ0LWRvY3VtZW50LW5vdC1jYWxsZWQ9XHU3NjdDXHU3NTFGIHN0YXJ0RG9jdW1lbnQgXHU0RThCXHU0RUY2XHU0RTRCXHU1RjhDXHVGRjBDXHU2MUM5XHU1NDdDXHU1M0VCXHU1QzZDXHU2MDI3ICJ7MH0iXHUzMDAyCi1udWxscGFyYW1ldGVyPSJ7MH0iIFx1NzY4NFx1NTQwRFx1N0EzMVx1NTNDM1x1NjU3OFx1NzBCQVx1N0E3QVx1NTAzQwotZXJyb3JIYW5kbGVyTm90U2V0PVx1OEI2Nlx1NTQ0QTogXHU1REYyXHU5NThCXHU1NTVGXHU5QTU3XHU4QjQ5XHVGRjBDXHU0RjQ2XHU2NjJGXHU2NzJBXHU4QTJEXHU1QjlBIG9yZy54bWwuc2F4LkVycm9ySGFuZGxlclx1RkYwQ1x1OTAxOVx1NTNFRlx1ODBGRFx1NEUwRFx1NjYyRlx1NjI0MFx1ODk4MVx1NzY4NFx1NzJDMFx1NjE0Qlx1MzAwMlx1NTI1Nlx1Njc5MFx1NTY2OFx1NUMwN1x1NEY3Rlx1NzUyOFx1OTgxMFx1OEEyRFx1NzY4NCBFcnJvckhhbmRsZXIgXHU0Rjg2XHU1MjE3XHU1MzcwXHU3QjJDXHU0RTAwXHU1MDBCIHswfSBcdTkzMkZcdThBQTRcdTMwMDJcdThBQ0JcdTU0N0NcdTUzRUIgJydzZXRFcnJvckhhbmRsZXInJyBcdTY1QjlcdTZDRDVcdTRGODZcdTRGRUVcdTZCNjNcdTZCNjRcdTU1NEZcdTk4NENcdTMwMDIKLWVycm9ySGFuZGxlckRlYnVnTXNnPVx1OTMyRlx1OEFBNDogVVJJID0gInswfSJcdUZGMENcdTg4NEMgPSAiezF9Ilx1RkYwQzogezJ9IApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWEluY2x1ZGVNZXNzYWdlcy5wcm9wZXJ0aWVzIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWEluY2x1ZGVNZXNzYWdlcy5wcm9wZXJ0aWVzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlYTM1YzllLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hJbmNsdWRlTWVzc2FnZXMucHJvcGVydGllcworKysgL2Rldi9udWxsCkBAIC0xLDM2ICswLDAgQEAKLSMgTWVzc2FnZXMgZm9yIG1lc3NhZ2UgcmVwb3J0aW5nCi1CYWRNZXNzYWdlS2V5ID0gVGhlIGVycm9yIG1lc3NhZ2UgY29ycmVzcG9uZGluZyB0byB0aGUgbWVzc2FnZSBrZXkgY2FuIG5vdCBiZSBmb3VuZC4KLUZvcm1hdEZhaWxlZCA9IEFuIGludGVybmFsIGVycm9yIG9jY3VycmVkIHdoaWxlIGZvcm1hdHRpbmcgdGhlIGZvbGxvd2luZyBtZXNzYWdlOlxuICAKLQotIyBNZXNzYWdlcyBmb3IgZXJyb25lb3VzIGlucHV0Ci1Ob0ZhbGxiYWNrID0gQW4gJ2luY2x1ZGUnIHdpdGggaHJlZiAnJ3swfScnZmFpbGVkLCBhbmQgbm8gJ2ZhbGxiYWNrJyBlbGVtZW50IHdhcyBmb3VuZC4KLU11bHRpcGxlRmFsbGJhY2tzID0gVGhlIFtjaGlsZHJlbl0gb2YgYW4gJ2luY2x1ZGUnIGVsZW1lbnQgY2Fubm90IGNvbnRhaW4gbW9yZSB0aGFuIG9uZSAnZmFsbGJhY2snIGVsZW1lbnQuCi1GYWxsYmFja1BhcmVudCA9IEEgJ2ZhbGxiYWNrJyBlbGVtZW50IHdhcyBmb3VuZCB0aGF0IGRpZCBub3QgaGF2ZSAnaW5jbHVkZScgYXMgdGhlIHBhcmVudC4KLUluY2x1ZGVDaGlsZCA9IEVsZW1lbnRzIGZyb20gbmFtZXNwYWNlICcnaHR0cDovL3d3dy53My5vcmcvMjAwMS9YSW5jbHVkZScnLCBvdGhlciB0aGFuICcnZmFsbGJhY2snJywgYXJlIG5vdCBhbGxvd2VkIHRvIGJlIGNoaWxkcmVuIG9mICcnaW5jbHVkZScnIGVsZW1lbnRzLiAgSG93ZXZlciwgJyd7MH0nJyB3YXMgZm91bmQuCi1GYWxsYmFja0NoaWxkID0gRWxlbWVudHMgZnJvbSBuYW1lc3BhY2UgJydodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hJbmNsdWRlJycsIG90aGVyIHRoYW4gJydpbmNsdWRlJycsIGFyZSBub3QgYWxsb3dlZCB0byBiZSBjaGlsZHJlbiBvZiAnJ2ZhbGxiYWNrJycgZWxlbWVudHMuICBIb3dldmVyLCAnJ3swfScnIHdhcyBmb3VuZC4KLUhyZWZNaXNzaW5nID0gVGhlICdocmVmJyBhdHRyaWJ1dGUgb2YgYW4gJ2luY2x1ZGUnIGVsZW1lbnQgaXMgbWlzc2luZy4KLVJlY3Vyc2l2ZUluY2x1ZGUgPSBSZWN1cnNpdmUgaW5jbHVkZSBkZXRlY3RlZC4gIERvY3VtZW50ICcnezB9Jycgd2FzIGFscmVhZHkgcHJvY2Vzc2VkLgotSW52YWxpZFBhcnNlVmFsdWUgPSBJbnZhbGlkIHZhbHVlIGZvciAnJ3BhcnNlJycgYXR0cmlidXRlIG9uICcnaW5jbHVkZScnIGVsZW1lbnQ6ICcnezB9JycuCi1YTUxQYXJzZUVycm9yID0gRXJyb3IgYXR0ZW1wdGluZyB0byBwYXJzZSBYTUwgZmlsZSAoaHJlZj0nJ3swfScnKS4gUmVhc29uOiB7MX0KLVhNTFJlc291cmNlRXJyb3IgPSBJbmNsdWRlIG9wZXJhdGlvbiBmYWlsZWQsIHJldmVydGluZyB0byBmYWxsYmFjay4gUmVzb3VyY2UgZXJyb3IgcmVhZGluZyBmaWxlIGFzIFhNTCAoaHJlZj0nJ3swfScnKS4gUmVhc29uOiB7MX0KLVRleHRSZXNvdXJjZUVycm9yID0gSW5jbHVkZSBvcGVyYXRpb24gZmFpbGVkLCByZXZlcnRpbmcgdG8gZmFsbGJhY2suIFJlc291cmNlIGVycm9yIHJlYWRpbmcgZmlsZSBhcyB0ZXh0IChocmVmPScnezB9JycpLiBSZWFzb246IHsxfQotTk9fWFBvaW50ZXJTY2hlbWEgPSBTY2hlbWEgZm9yIFwiezB9XCIgaXMgbm90IHN1cHBvcnRlZCBieSBkZWZhdWx0LiBEZWZpbmUgeW91ciBvd24gc2NoZW1hIGZvciB7MH0uU2VlIGh0dHA6Ly9hcGFjaGUub3JnL3htbC9wcm9wZXJ0aWVzL3hwb2ludGVyLXNjaGVtYQotTk9fU3ViUmVzb3VyY2VJZGVudGlmaWVkID0gTm8gU3VicmVzb3VyY2UgaXMgaWRlbnRpZmllZCBieSB0aGUgWFBvaW50ZXIgUHJvY2Vzc29yIGZvciBQb2ludGVyIHswfS4KLU5vbkR1cGxpY2F0ZU5vdGF0aW9uID0gTXVsdGlwbGUgbm90YXRpb25zIHdlcmUgdXNlZCB3aGljaCBoYWQgdGhlIG5hbWUgJyd7MH0nJywgYnV0IHdoaWNoIHdlcmUgbm90IGRldGVybWluZWQgdG8gYmUgZHVwbGljYXRlcy4KLU5vbkR1cGxpY2F0ZVVucGFyc2VkRW50aXR5ID0gTXVsdGlwbGUgdW5wYXJzZWQgZW50aXRpZXMgd2VyZSB1c2VkIHdoaWNoIGhhZCB0aGUgbmFtZSAnJ3swfScnLCBidXQgd2hpY2ggd2VyZSBub3QgZGV0ZXJtaW5lZCB0byBiZSBkdXBsaWNhdGVzLgotWHBvaW50ZXJNaXNzaW5nID0geHBvaW50ZXIgYXR0cmlidXRlIG11c3QgYmUgcHJlc2VudCB3aGVuIGhyZWYgYXR0cmlidXRlIGlzIGFic2VudC4KLUFjY2VwdE1hbGZvcm1lZCA9IENoYXJhY3RlcnMgb3V0c2lkZSB0aGUgcmFuZ2UgI3gyMCB0aHJvdWdoICN4N0UgYXJlIG5vdCBhbGxvd2VkIGluIHRoZSB2YWx1ZSBvZiB0aGUgJ2FjY2VwdCcgYXR0cmlidXRlIG9mIGFuICdpbmNsdWRlJyBlbGVtZW50LgotQWNjZXB0TGFuZ3VhZ2VNYWxmb3JtZWQgPSBDaGFyYWN0ZXJzIG91dHNpZGUgdGhlIHJhbmdlICN4MjAgdGhyb3VnaCAjeDdFIGFyZSBub3QgYWxsb3dlZCBpbiB0aGUgdmFsdWUgb2YgdGhlICdhY2NlcHQtbGFuZ3VhZ2UnIGF0dHJpYnV0ZSBvZiBhbiAnaW5jbHVkZScgZWxlbWVudC4KLVJvb3RFbGVtZW50UmVxdWlyZWQgPSBBIHdlbGwtZm9ybWVkIGRvY3VtZW50IHJlcXVpcmVzIGEgcm9vdCBlbGVtZW50LgotTXVsdGlwbGVSb290RWxlbWVudHMgPSBBIHdlbGwtZm9ybWVkIGRvY3VtZW50IG11c3Qgbm90IGNvbnRhaW4gbXVsdGlwbGUgcm9vdCBlbGVtZW50cy4KLUNvbnRlbnRJbGxlZ2FsQXRUb3BMZXZlbCA9IFRoZSByZXBsYWNlbWVudCBvZiBhbiAnaW5jbHVkZScgZWxlbWVudCBhcHBlYXJpbmcgYXMgdGhlIGRvY3VtZW50IGVsZW1lbnQgaW4gdGhlIHRvcC1sZXZlbCBzb3VyY2UgaW5mb3NldCBjYW5ub3QgY29udGFpbiBjaGFyYWN0ZXJzLgotVW5leHBhbmRlZEVudGl0eVJlZmVyZW5jZUlsbGVnYWwgPSBUaGUgcmVwbGFjZW1lbnQgb2YgYW4gJ2luY2x1ZGUnIGVsZW1lbnQgYXBwZWFyaW5nIGFzIHRoZSBkb2N1bWVudCBlbGVtZW50IGluIHRoZSB0b3AtbGV2ZWwgc291cmNlIGluZm9zZXQgY2Fubm90IGNvbnRhaW4gdW5leHBhbmRlZCBlbnRpdHkgcmVmZXJlbmNlcy4KLUhyZWZGcmFnbWVudElkZW50aWZpZXJJbGxlZ2FsID0gRnJhZ21lbnQgaWRlbnRpZmllcnMgbXVzdCBub3QgYmUgdXNlZC4gVGhlICcnaHJlZicnIGF0dHJpYnV0ZSB2YWx1ZSAnJ3swfScnIGlzIG5vdCBwZXJtaXR0ZWQuCi1IcmVmU3ludGFjdGljYWxseUludmFsaWQgPSAnJ2hyZWYnJyBhdHRyaWJ1dGUgdmFsdWUgJyd7MH0nJyBpcyBzeW50YWN0aWNhbGx5IGludmFsaWQuIEFmdGVyIGFwcGx5aW5nIGVzY2FwaW5nIHJ1bGVzIHRoZSB2YWx1ZSBpcyBuZWl0aGVyIGEgc3ludGFjdGljYWxseSBjb3JyZWN0IFVSSSBvciBJUkkuCi1YUG9pbnRlclN0cmVhbWFiaWxpdHkgPSBBbiB4cG9pbnRlciB3YXMgc3BlY2lmaWVkIHRoYXQgcG9pbnRzIHRvIGEgbG9jYXRpb24gaW4gdGhlIHNvdXJjZSBpbmZvc2V0LiBUaGlzIGxvY2F0aW9uIGNhbm5vdCBiZSBhY2Nlc3NlZCBkdWUgdG8gdGhlIHN0cmVhbWluZyBuYXR1cmUgb2YgdGhlIHByb2Nlc3Nvci4KLQotWFBvaW50ZXJSZXNvbHV0aW9uVW5zdWNjZXNzZnVsID0gWFBvaW50ZXIgcmVzb2x1dGlvbiB1bnN1Y2Nlc3NmdWwuCi0KLSMgTWVzc2FnZXMgZnJvbSBlcnJvbmVvdXMgc2V0LXVwCi1JbmNvbXBhdGlibGVOYW1lc3BhY2VDb250ZXh0ID0gVGhlIHR5cGUgb2YgdGhlIE5hbWVzcGFjZUNvbnRleHQgaXMgaW5jb21wYXRpYmxlIHdpdGggdXNpbmcgWEluY2x1ZGU7IGl0IG11c3QgYmUgYW4gaW5zdGFuY2Ugb2YgWEluY2x1ZGVOYW1lc3BhY2VTdXBwb3J0Ci1FeHBhbmRlZFN5c3RlbUlkID0gQ291bGQgbm90IGV4cGFuZCBzeXN0ZW0gaWQgb2YgaW5jbHVkZWQgcmVzb3VyY2UKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hJbmNsdWRlTWVzc2FnZXNfZGUucHJvcGVydGllcyBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hJbmNsdWRlTWVzc2FnZXNfZGUucHJvcGVydGllcwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYTRhZGE3Zi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9YSW5jbHVkZU1lc3NhZ2VzX2RlLnByb3BlcnRpZXMKKysrIC9kZXYvbnVsbApAQCAtMSwzNiArMCwwIEBACi0jIE1lc3NhZ2VzIGZvciBtZXNzYWdlIHJlcG9ydGluZwotQmFkTWVzc2FnZUtleSA9IERpZSB6dW0gTWVsZHVuZ3NzY2hsXHUwMEZDc3NlbCBnZWhcdTAwRjZyaWdlIEZlaGxlcm1lbGR1bmcga2FubiBuaWNodCBnZWZ1bmRlbiB3ZXJkZW4uCi1Gb3JtYXRGYWlsZWQgPSBCZWltIEZvcm1hdGllcmVuIGRlciBmb2xnZW5kZW4gTWVsZHVuZyBpc3QgZWluIGludGVybmVyIEZlaGxlciBhdWZnZXRyZXRlbjpcbiAgCi0KLSMgTWVzc2FnZXMgZm9yIGVycm9uZW91cyBpbnB1dAotTm9GYWxsYmFjayA9ICJpbmNsdWRlIiBtaXQgaHJlZiAiezB9IiBuaWNodCBlcmZvbGdyZWljaCwgdW5kIGVzIHd1cmRlIGtlaW4gImZhbGxiYWNrIi1FbGVtZW50IGdlZnVuZGVuLgotTXVsdGlwbGVGYWxsYmFja3MgPSBEaWUgW3VudGVyZ2VvcmRuZXRlbiBFbGVtZW50ZV0gZWluZXMgImluY2x1ZGUiLUVsZW1lbnRzIGtcdTAwRjZubmVuIG5pY2h0IG1laHJlcmUgImZhbGxiYWNrIi1FbGVtZW50ZSBlbnRoYWx0ZW4uCi1GYWxsYmFja1BhcmVudCA9IEVpbiAiZmFsbGJhY2siLUVsZW1lbnQgd3VyZGUgZ2VmdW5kZW4sIGZcdTAwRkNyIGRhcyAiaW5jbHVkZSIgbmljaHQgZGFzIFx1MDBGQ2Jlcmdlb3JkbmV0ZSBFbGVtZW50IHdhci4KLUluY2x1ZGVDaGlsZCA9IEFuZGVyZSBFbGVtZW50ZSBhdXMgTmFtZXNwYWNlICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hJbmNsdWRlIiBhbHMgImZhbGxiYWNrIiBkXHUwMEZDcmZlbiBrZWluZSB1bnRlcmdlb3JkbmV0ZW4gRWxlbWVudGUgdm9uICJpbmNsdWRlIi1FbGVtZW50ZW4gc2Vpbi4gRXMgd3VyZGUgYWJlciAiezB9IiBnZWZ1bmRlbi4KLUZhbGxiYWNrQ2hpbGQgPSBBbmRlcmUgRWxlbWVudGUgYXVzIE5hbWVzcGFjZSAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9YSW5jbHVkZSIgYWxzICJpbmNsdWRlIiBkXHUwMEZDcmZlbiBrZWluZSB1bnRlcmdlb3JkbmV0ZW4gRWxlbWVudGUgdm9uICJmYWxsYmFjayItRWxlbWVudGVuIHNlaW4uIEVzIHd1cmRlIGFiZXIgInswfSIgZ2VmdW5kZW4uCi1IcmVmTWlzc2luZyA9ICJocmVmIi1BdHRyaWJ1dCBlaW5lcyAiaW5jbHVkZSItRWxlbWVudHMgZmVobHQuCi1SZWN1cnNpdmVJbmNsdWRlID0gUmVrdXJzaXZlcyAiaW5jbHVkZSIgZXJtaXR0ZWx0LiBEb2t1bWVudCAiezB9IiB3dXJkZSBiZXJlaXRzIHZlcmFyYmVpdGV0LgotSW52YWxpZFBhcnNlVmFsdWUgPSBVbmdcdTAwRkNsdGlnZXIgV2VydCBmXHUwMEZDciAicGFyc2UiLUF0dHJpYnV0IGJlaSAiaW5jbHVkZSItRWxlbWVudDogInswfSIuCi1YTUxQYXJzZUVycm9yID0gRmVobGVyIGJlaW0gVmVyc3VjaCwgWE1MLURhdGVpIHp1IHBhcnNlbiAoaHJlZj0nJ3swfScnKS4gVXJzYWNoZTogezF9Ci1YTUxSZXNvdXJjZUVycm9yID0gSW5jbHVkZS1Wb3JnYW5nIG5pY2h0IGVyZm9sZ3JlaWNoLiBadXJcdTAwRkNjayB6dSBGYWxsYmFjay4gUmVzc291cmNlbmZlaGxlciBiZWltIExlc2VuIGRlciBEYXRlaSBhbHMgWE1MIChocmVmPSJ7MH0iKS4gR3J1bmQ6IHsxfQotVGV4dFJlc291cmNlRXJyb3IgPSBJbmNsdWRlLVZvcmdhbmcgbmljaHQgZXJmb2xncmVpY2guIFp1clx1MDBGQ2NrIHp1IEZhbGxiYWNrLiBSZXNzb3VyY2VuZmVobGVyIGJlaW0gTGVzZW4gZGVyIERhdGVpIGFscyBUZXh0IChocmVmPSJ7MH0iKS4gR3J1bmQ6IHsxfQotTk9fWFBvaW50ZXJTY2hlbWEgPSBTY2hlbWEgZlx1MDBGQ3IgInswfSIgd2lyZCBzdGFuZGFyZG1cdTAwRTRcdTAwREZpZyBuaWNodCB1bnRlcnN0XHUwMEZDdHp0LiBEZWZpbmllcmVuIFNpZSBJaHIgZWlnZW5lcyBTY2hlbWEgZlx1MDBGQ3IgezB9LiBTaWVoZSBodHRwOi8vYXBhY2hlLm9yZy94bWwvcHJvcGVydGllcy94cG9pbnRlci1zY2hlbWEKLU5PX1N1YlJlc291cmNlSWRlbnRpZmllZCA9IEtlaW5lIFN1YnJlc3NvdXJjZSB2b24gWFBvaW50ZXItUHJvemVzc29yIGZcdTAwRkNyIFplaWdlciB7MH0gaWRlbnRpZml6aWVydC4KLU5vbkR1cGxpY2F0ZU5vdGF0aW9uID0gTWVocmVyZSBOb3RhdGlvbmVuIG1pdCBkZW0gTmFtZW4gInswfSIgd3VyZGVuIHZlcndlbmRldCwgZGllIGFiZXIgbmljaHQgYWxzIER1cGxpa2F0ZSBlcm1pdHRlbHQgd3VyZGVuLgotTm9uRHVwbGljYXRlVW5wYXJzZWRFbnRpdHkgPSBNZWhyZXJlIG5pY2h0IGdlcGFyc3RlIEVudGl0eXMgbWl0IGRlbSBOYW1lbiAiezB9IiB3dXJkZW4gdmVyd2VuZGV0LCBkaWUgYWJlciBuaWNodCBhbHMgRHVwbGlrYXRlIGVybWl0dGVsdCB3dXJkZW4uCi1YcG9pbnRlck1pc3NpbmcgPSB4cG9pbnRlci1BdHRyaWJ1dCBtdXNzIHZvcmhhbmRlbiBzZWluLCB3ZW5uIGhyZWYtQXR0cmlidXQgZmVobHQuCi1BY2NlcHRNYWxmb3JtZWQgPSBaZWljaGVuIGF1XHUwMERGZXJoYWxiIGRlcyBCZXJlaWNocyAjeDIwIGJpcyAjeDdFIHNpbmQgaW0gV2VydCBkZXMgImFjY2VwdCItQXR0cmlidXRzIGVpbmVzICJpbmNsdWRlIi1FbGVtZW50cyBuaWNodCB6dWxcdTAwRTRzc2lnLgotQWNjZXB0TGFuZ3VhZ2VNYWxmb3JtZWQgPSBaZWljaGVuIGF1XHUwMERGZXJoYWxiIGRlcyBCZXJlaWNocyAjeDIwIGJpcyAjeDdFIHNpbmQgaW0gV2VydCBkZXMgImFjY2VwdC1sYW5ndWFnZSItQXR0cmlidXRzIGVpbmVzICJpbmNsdWRlIi1FbGVtZW50cyBuaWNodCB6dWxcdTAwRTRzc2lnLgotUm9vdEVsZW1lbnRSZXF1aXJlZCA9IEZcdTAwRkNyIGVpbiBvcmRudW5nc2dlbVx1MDBFNFx1MDBERiBmb3JtYXRpZXJ0ZXMgRG9rdW1lbnQgaXN0IGVpbiBSb290LUVsZW1lbnQgZXJmb3JkZXJsaWNoLgotTXVsdGlwbGVSb290RWxlbWVudHMgPSBFaW4gb3JkbnVuZ3NnZW1cdTAwRTRcdTAwREYgZm9ybWF0aWVydGVzIERva3VtZW50IGRhcmYgbmljaHQgbWVocmVyZSBSb290LUVsZW1lbnRlIGVudGhhbHRlbi4KLUNvbnRlbnRJbGxlZ2FsQXRUb3BMZXZlbCA9IERlciBFcnNhdHogZWluZXMgImluY2x1ZGUiLUVsZW1lbnRzLCBkYXMgYWxzIERva3VtZW50ZWxlbWVudCBpbSBRdWVsbC1JbmZvc2V0IGRlciBvYmVyc3RlbiBFYmVuZSBhbmdlemVpZ3Qgd2lyZCwgZGFyZiBrZWluZSBaZWljaGVuIGVudGhhbHRlbi4KLVVuZXhwYW5kZWRFbnRpdHlSZWZlcmVuY2VJbGxlZ2FsID0gRGVyIEVyc2F0eiBlaW5lcyAiaW5jbHVkZSItRWxlbWVudHMsIGRhcyBhbHMgRG9rdW1lbnRlbGVtZW50IGltIFF1ZWxsLUluZm9zZXQgZGVyIG9iZXJzdGVuIEViZW5lIGFuZ2V6ZWlndCB3aXJkLCBkYXJmIGtlaW5lIG5pY2h0IGVyd2VpdGVydGVuIEVudGl0eXJlZmVyZW56ZW4gZW50aGFsdGVuLgotSHJlZkZyYWdtZW50SWRlbnRpZmllcklsbGVnYWwgPSBGcmFnbWVudC1JRHMgZFx1MDBGQ3JmZW4gbmljaHQgdmVyd2VuZGV0IHdlcmRlbi4gRGVyICJocmVmIi1BdHRyaWJ1dHdlcnQgInswfSIgaXN0IG5pY2h0IHp1bFx1MDBFNHNzaWcuCi1IcmVmU3ludGFjdGljYWxseUludmFsaWQgPSAiaHJlZiItQXR0cmlidXR3ZXJ0ICJ7MH0iIGhhdCBlaW5lIHVuZ1x1MDBGQ2x0aWdlIFN5bnRheC4gTmFjaCBBbndlbmRlbiBkZXIgRXNjYXBlLVJlZ2VsbiBpc3QgZGVyIFdlcnQga2VpbiBzeW50YWt0aXNjaCBrb3JyZWt0ZXIgVVJJIG9kZXIgSVJJLgotWFBvaW50ZXJTdHJlYW1hYmlsaXR5ID0gRXMgd3VyZGUgZWluIHhwb2ludGVyIGFuZ2VnZWJlbiwgZGVyIGF1ZiBlaW5lIFN0ZWxsZSBpbSBRdWVsbC1JbmZvc2V0IHZlcndlaXN0LiBBdWYgZGllc2UgU3RlbGxlIGthbm4gYXVmZ3J1bmQgZGVzIFN0cmVhbWluZ2NoYXJha3RlcnMgZGVzIFByb3plc3NvcnMgbmljaHQgenVnZWdyaWZmZW4gd2VyZGVuLgotCi1YUG9pbnRlclJlc29sdXRpb25VbnN1Y2Nlc3NmdWwgPSBYUG9pbnRlci1BdWZsXHUwMEY2c3VuZyBuaWNodCBlcmZvbGdyZWljaC4KLQotIyBNZXNzYWdlcyBmcm9tIGVycm9uZW91cyBzZXQtdXAKLUluY29tcGF0aWJsZU5hbWVzcGFjZUNvbnRleHQgPSBUeXAgZGVzIE5hbWVzcGFjZUNvbnRleHQgaXN0IG5pY2h0IG1pdCBkZXIgVmVyd2VuZHVuZyB2b24gWEluY2x1ZGUga29tcGF0aWJlbC4gTXVzcyBlaW5lIEluc3Rhbnogdm9uIFhJbmNsdWRlTmFtZXNwYWNlU3VwcG9ydCBzZWluCi1FeHBhbmRlZFN5c3RlbUlkID0gU3lzdGVtLUlEIGRlciBhdWZnZW5vbW1lbmVuIFJlc3NvdXJjZSBrb25udGUgbmljaHQgZXJ3ZWl0ZXJ0IHdlcmRlbgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWEluY2x1ZGVNZXNzYWdlc19lcy5wcm9wZXJ0aWVzIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWEluY2x1ZGVNZXNzYWdlc19lcy5wcm9wZXJ0aWVzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0MzMyYzE1Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hJbmNsdWRlTWVzc2FnZXNfZXMucHJvcGVydGllcworKysgL2Rldi9udWxsCkBAIC0xLDM2ICswLDAgQEAKLSMgTWVzc2FnZXMgZm9yIG1lc3NhZ2UgcmVwb3J0aW5nCi1CYWRNZXNzYWdlS2V5ID0gTm8gc2UgaGEgZW5jb250cmFkbyBlbCBtZW5zYWplIGRlIGVycm9yIGNvcnJlc3BvbmRpZW50ZSBhIGxhIGNsYXZlIGRlIG1lbnNhamUuCi1Gb3JtYXRGYWlsZWQgPSBTZSBoYSBwcm9kdWNpZG8gdW4gZXJyb3IgaW50ZXJubyBhbCBmb3JtYXRlYXIgZWwgc2lndWllbnRlIG1lbnNhamU6XG4gIAotCi0jIE1lc3NhZ2VzIGZvciBlcnJvbmVvdXMgaW5wdXQKLU5vRmFsbGJhY2sgPSBIYSBmYWxsYWRvIHVuIGVsZW1lbnRvICcnaW5jbHVkZScnIGNvbiBocmVmICcnezB9JycgeSBubyBzZSBoYSBlbmNvbnRyYWRvIG5pbmdcdTAwRkFuIGVsZW1lbnRvICcnZmFsbGJhY2snJy4KLU11bHRpcGxlRmFsbGJhY2tzID0gTG9zIFtzZWN1bmRhcmlvc10gZGUgdW4gZWxlbWVudG8gJ2luY2x1ZGUnIG5vIHB1ZWRlbiBjb250ZW5lciBtXHUwMEUxcyBkZSB1biBlbGVtZW50byAnZmFsbGJhY2snLgotRmFsbGJhY2tQYXJlbnQgPSBTZSBoYSBlbmNvbnRyYWRvIHVuIGVsZW1lbnRvICdmYWxsYmFjaycgcXVlIG5vIHRlblx1MDBFRGEgdW4gZWxlbWVudG8gJ2luY2x1ZGUnIGNvbW8gcHJpbmNpcGFsLgotSW5jbHVkZUNoaWxkID0gTm8gc2UgcGVybWl0ZSBxdWUgbG9zIGVsZW1lbnRvcyBkZWwgZXNwYWNpbyBkZSBub21icmVzICcnaHR0cDovL3d3dy53My5vcmcvMjAwMS9YSW5jbHVkZScnLCBkaXN0aW50b3MgZGUgbG9zIGVsZW1lbnRvcyAnJ2ZhbGxiYWNrJycgc2VhbiBzZWN1bmRhcmlvcyBkZSBsb3MgZWxlbWVudG9zICcnaW5jbHVkZScnLiBTaW4gZW1iYXJnbywgc2UgaGEgZW5jb250cmFkbyAnJ3swfScnLgotRmFsbGJhY2tDaGlsZCA9IE5vIHNlIHBlcm1pdGUgcXVlIGxvcyBlbGVtZW50b3MgZGVsIGVzcGFjaW8gZGUgbm9tYnJlcyAnJ2h0dHA6Ly93d3cudzMub3JnLzIwMDEvWEluY2x1ZGUnJywgZGlzdGludG9zIGRlIGxvcyBlbGVtZW50b3MgJydpbmNsdWRlJycgc2VhbiBzZWN1bmRhcmlvcyBkZSBsb3MgZWxlbWVudG9zICcnZmFsbGJhY2snJy4gU2luIGVtYmFyZ28sIHNlIGhhIGVuY29udHJhZG8gJyd7MH0nJy4KLUhyZWZNaXNzaW5nID0gRmFsdGEgZWwgYXRyaWJ1dG8gJ2hyZWYnIGRlIHVuIGVsZW1lbnRvICdpbmNsdWRlJy4KLVJlY3Vyc2l2ZUluY2x1ZGUgPSBTZSBoYSBkZXRlY3RhZG8gdW4gZWxlbWVudG8gaW5jbHVkZSByZWN1cnNpdm8uIEVsIGRvY3VtZW50byAnJ3swfScnIHlhIHNlIGhhIHByb2Nlc2Fkby4KLUludmFsaWRQYXJzZVZhbHVlID0gVmFsb3Igbm8gdlx1MDBFMWxpZG8gcGFyYSBlbCBhdHJpYnV0byAnJ3BhcnNlJycgZW4gZWwgZWxlbWVudG8gJydpbmNsdWRlJyc6ICcnezB9JycuCi1YTUxQYXJzZUVycm9yID0gRXJyb3IgYWwgaW50ZW50YXIgYW5hbGl6YXIgZWwgYXJjaGl2byBYTUwgKGhyZWY9Jyd7MH0nJykuIE1vdGl2bzogezF9Ci1YTUxSZXNvdXJjZUVycm9yID0gRmFsbG8gZGUgbGEgb3BlcmFjaVx1MDBGM24gaW5jbHVkZSwgY29udmVyc2lcdTAwRjNuIGEgZmFsbGJhY2suIEVycm9yIGRlbCByZWN1cnNvIGFsIGxlZXIgZWwgYXJjaGl2byBjb21vIFhNTCAoaHJlZj0nJ3swfScnKS4gTW90aXZvOiB7MX0KLVRleHRSZXNvdXJjZUVycm9yID0gRmFsbG8gZGUgbGEgb3BlcmFjaVx1MDBGM24gaW5jbHVkZSwgY29udmVyc2lcdTAwRjNuIGEgZmFsbGJhY2suIEVycm9yIGRlbCByZWN1cnNvIGFsIGxlZXIgZWwgYXJjaGl2byBjb21vIHRleHRvIChocmVmPScnezB9JycpLiBNb3Rpdm86IHsxfQotTk9fWFBvaW50ZXJTY2hlbWEgPSBFbCBlc3F1ZW1hIHBhcmEgInswfSIgbm8gZXN0XHUwMEUxIHNvcG9ydGFkbyBwb3IgZGVmZWN0by4gRGVmaW5hIHN1IHByb3BpbyBlc3F1ZW1hIHBhcmEgezB9LiBDb25zdWx0ZSBodHRwOi8vYXBhY2hlLm9yZy94bWwvcHJvcGVydGllcy94cG9pbnRlci1zY2hlbWEKLU5PX1N1YlJlc291cmNlSWRlbnRpZmllZCA9IEVsIHByb2Nlc2Fkb3IgWFBvaW50ZXIgbm8gaGEgaWRlbnRpZmljYWRvIGVsIHN1YnJlY3Vyc28gcGFyYSBlbCBwdW50ZXJvIHswfS4KLU5vbkR1cGxpY2F0ZU5vdGF0aW9uID0gU2UgaGFuIHV0aWxpemFkbyB2YXJpYXMgbm90YWNpb25lcyBjb24gZWwgbm9tYnJlJyd7MH0nJywgcGVybyBubyBzZSBoYSBkZXRlcm1pbmFkbyBxdWUgc2VhbiBkdXBsaWNhZG9zLgotTm9uRHVwbGljYXRlVW5wYXJzZWRFbnRpdHkgPSBTZSBoYW4gdXRpbGl6YWRvIHZhcmlhcyBlbnRpZGFkZXMgbm8gYW5hbGl6YWRhcyBjb24gZWwgbm9tYnJlJyd7MH0nJywgcGVybyBubyBzZSBoYSBkZXRlcm1pbmFkbyBxdWUgc2VhbiBkdXBsaWNhZG9zLgotWHBvaW50ZXJNaXNzaW5nID0gZWwgYXRyaWJ1dG8geHBvaW50ZXIgZGViZSBlc3RhciBwcmVzZW50ZSBjdWFuZG8gZWwgYXRyaWJ1dG8gaHJlZiBlc3RcdTAwRTkgYXVzZW50ZS4KLUFjY2VwdE1hbGZvcm1lZCA9IExvcyBjYXJhY3RlcmVzIGZ1ZXJhIGRlbCByYW5nbyBkZSAjeDIwIGEgI3g3RSBubyBlc3RcdTAwRTFuIHBlcm1pdGlkb3MgZW4gZWwgdmFsb3IgZGVsIGF0cmlidXRvICdhY2NlcHQnIGRlIHVuIGVsZW1lbnRvICdpbmNsdWRlJy4KLUFjY2VwdExhbmd1YWdlTWFsZm9ybWVkID0gTG9zIGNhcmFjdGVyZXMgZnVlcmEgZGVsIHJhbmdvICN4MjAgdGhyb3VnaCAjeDdFIG5vIGVzdFx1MDBFMW4gcGVybWl0aWRvcyBlbiBlbCB2YWxvciBkZWwgYXRyaWJ1dG8gJ2FjY2VwdC1sYW5ndWFnZScgZGUgdW4gZWxlbWVudG8gJ2luY2x1ZGUnLgotUm9vdEVsZW1lbnRSZXF1aXJlZCA9IFVuIGRvY3VtZW50byBjb24gZm9ybWF0byBjb3JyZWN0byBuZWNlc2l0YSB1biBlbGVtZW50byByYVx1MDBFRHouCi1NdWx0aXBsZVJvb3RFbGVtZW50cyA9IFVuIGRvY3VtZW50byBjb24gZm9ybWF0byBjb3JyZWN0byBubyBkZWJlIGNvbnRlbmVyIHZhcmlvcyBlbGVtZW50b3MgcmFcdTAwRUR6LgotQ29udGVudElsbGVnYWxBdFRvcExldmVsID0gTGEgc3VzdGl0dWNpXHUwMEYzbiBkZSB1biBlbGVtZW50byAnaW5jbHVkZScgcXVlIGFwYXJlY2UgY29tbyBlbCBlbGVtZW50byBkZSBkb2N1bWVudG8gZW4gZWwganVlZ28gZGUgaW5mb3JtYWNpXHUwMEYzbiBkZSBvcmlnZW4gZGUgbml2ZWwgc3VwZXJpb3Igbm8gcHVlZGUgY29udGVuZXIgY2FyYWN0ZXJlcy4KLVVuZXhwYW5kZWRFbnRpdHlSZWZlcmVuY2VJbGxlZ2FsID0gTGEgc3VzdGl0dWNpXHUwMEYzbiBkZSB1biBlbGVtZW50byAnaW5jbHVkZScgcXVlIGFwYXJlY2UgY29tbyBlbCBlbGVtZW50byBkZSBkb2N1bWVudG8gZW4gZWwganVlZ28gZGUgaW5mb3JtYWNpXHUwMEYzbiBkZSBvcmlnZW4gZGUgbml2ZWwgc3VwZXJpb3Igbm8gcHVlZGUgY29udGVuZXIgcmVmZXJlbmNpYXMgZGUgZW50aWRhZCBubyBhbXBsaWFkYXMuCi1IcmVmRnJhZ21lbnRJZGVudGlmaWVySWxsZWdhbCA9IExvcyBpZGVudGlmaWNhZG9yZXMgZGUgZnJhZ21lbnRvIG5vIGRlYmVuIHV0aWxpemFyc2UuIEVsIHZhbG9yIGRlbCBhdHJpYnV0byAnJ2hyZWYnJyAnJ3swfScnIG5vIGVzdFx1MDBFMSBwZXJtaXRpZG8uCi1IcmVmU3ludGFjdGljYWxseUludmFsaWQgPSBFbCB2YWxvciBkZWwgYXRyaWJ1dG8gJydocmVmJycgJyd7MH0nJyBubyBlcyB2XHUwMEUxbGlkbyBzaW50XHUwMEUxY3RpY2FtZW50ZS4gRGVzcHVcdTAwRTlzIGRlIGFwbGljYXIgbGFzIHJlZ2xhcyBkZSBlc2NhcGUsIGVsIHZhbG9yIG5vIGVzIHVuIFVSSSBuaSB1biBJUkkgc2ludFx1MDBFMWN0aWNhbWVudGUgY29ycmVjdG9zLgotWFBvaW50ZXJTdHJlYW1hYmlsaXR5ID0gU2UgaGEgZXNwZWNpZmljYWRvIHVuIHhwb2ludGVyIHF1ZSBhcHVudGEgYSB1bmEgdWJpY2FjaVx1MDBGM24gZW4gZWwganVlZ28gZGUgaW5mb3JtYWNpXHUwMEYzbiBkZSBvcmlnZW4uIE5vIHNlIHB1ZWRlIGFjY2VkZXIgYSBlc3RhIHViaWNhY2lcdTAwRjNuIGRlYmlkbyBhIGxhIG5hdHVyYWxlemEgZGUgZmx1am8gZGVsIHByb2Nlc2Fkb3IuCi0KLVhQb2ludGVyUmVzb2x1dGlvblVuc3VjY2Vzc2Z1bCA9IFJlc29sdWNpXHUwMEYzbiBkZSBYUG9pbnRlciBpbmNvcnJlY3RhLgotCi0jIE1lc3NhZ2VzIGZyb20gZXJyb25lb3VzIHNldC11cAotSW5jb21wYXRpYmxlTmFtZXNwYWNlQ29udGV4dCA9IEVsIHRpcG8gZGUgTmFtZXNwYWNlQ29udGV4dCBlcyBpbmNvbXBhdGlibGUgY29uIGVsIHVzbyBkZSBYSW5jbHVkZTsgZGViZSBzZXIgdW5hIGluc3RhbmNpYSBkZSBYSW5jbHVkZU5hbWVzcGFjZVN1cHBvcnQKLUV4cGFuZGVkU3lzdGVtSWQgPSBObyBzZSBoYSBwb2RpZG8gYW1wbGlhciBlbCBpZGVudGlmaWNhZG9yIGRlbCBzaXN0ZW1hIGRlbCByZWN1cnNvIGluY2x1aWRvCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9YSW5jbHVkZU1lc3NhZ2VzX2ZyLnByb3BlcnRpZXMgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9YSW5jbHVkZU1lc3NhZ2VzX2ZyLnByb3BlcnRpZXMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDk2ZWY5MTIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWEluY2x1ZGVNZXNzYWdlc19mci5wcm9wZXJ0aWVzCisrKyAvZGV2L251bGwKQEAgLTEsMzYgKzAsMCBAQAotIyBNZXNzYWdlcyBmb3IgbWVzc2FnZSByZXBvcnRpbmcKLUJhZE1lc3NhZ2VLZXkgPSBMZSBtZXNzYWdlIGQnZXJyZXVyIGNvcnJlc3BvbmRhbnQgXHUwMEUwIGxhIGNsXHUwMEU5IGRlIG1lc3NhZ2UgZXN0IGludHJvdXZhYmxlLgotRm9ybWF0RmFpbGVkID0gVW5lIGVycmV1ciBpbnRlcm5lIGVzdCBzdXJ2ZW51ZSBsb3JzIGR1IGZvcm1hdGFnZSBkdSBtZXNzYWdlIHN1aXZhbnQgOlxuICAKLQotIyBNZXNzYWdlcyBmb3IgZXJyb25lb3VzIGlucHV0Ci1Ob0ZhbGxiYWNrID0gRWNoZWMgZCcndW4gXHUwMEU5bFx1MDBFOW1lbnQgJydpbmNsdWRlJycgYXZlYyBsJydhdHRyaWJ1dCBocmVmICcnezB9JycgOyBhdWN1biBcdTAwRTlsXHUwMEU5bWVudCAnJ2ZhbGxiYWNrJycgbicnYSBcdTAwRTl0XHUwMEU5IHRyb3V2XHUwMEU5LgotTXVsdGlwbGVGYWxsYmFja3MgPSBMZXMgW2VuZmFudHNdIGQndW4gXHUwMEU5bFx1MDBFOW1lbnQgJ2luY2x1ZGUnIG5lIGRvaXZlbnQgcGFzIGNvbnRlbmlyIHBsdXNpZXVycyBcdTAwRTlsXHUwMEU5bWVudHMgJ2ZhbGxiYWNrJy4KLUZhbGxiYWNrUGFyZW50ID0gVW4gXHUwMEU5bFx1MDBFOW1lbnQgJ2ZhbGxiYWNrJyBuJ2F5YW50IHBhcyBsJ1x1MDBFOWxcdTAwRTltZW50ICdpbmNsdWRlJyBjb21tZSBwYXJlbnQgXHUwMEU5dFx1MDBFOSB0cm91dlx1MDBFOS4KLUluY2x1ZGVDaGlsZCA9IExlcyBcdTAwRTlsXHUwMEU5bWVudHMgZGUgbCcnZXNwYWNlIGRlIG5vbXMgJydodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hJbmNsdWRlJycsIGF1dHJlcyBxdWUgJydmYWxsYmFjaycnLCBuZSBwZXV2ZW50IHBhcyBcdTAwRUF0cmUgZGVzIGVuZmFudHMgZGVzIFx1MDBFOWxcdTAwRTltZW50cyAnJ2luY2x1ZGUnJy4gQ2VwZW5kYW50LCAnJ3swfScnIGEgXHUwMEU5dFx1MDBFOSB0cm91dlx1MDBFOS4KLUZhbGxiYWNrQ2hpbGQgPSBMZXMgXHUwMEU5bFx1MDBFOW1lbnRzIGRlIGwnJ2VzcGFjZSBkZSBub21zICcnaHR0cDovL3d3dy53My5vcmcvMjAwMS9YSW5jbHVkZScnLCBhdXRyZXMgcXVlICcnaW5jbHVkZScnLCBuZSBwZXV2ZW50IHBhcyBcdTAwRUF0cmUgZGVzIGVuZmFudHMgZGVzIFx1MDBFOWxcdTAwRTltZW50cyAnJ2ZhbGxiYWNrJycuIENlcGVuZGFudCwgJyd7MH0nJyBhIFx1MDBFOXRcdTAwRTkgdHJvdXZcdTAwRTkuCi1IcmVmTWlzc2luZyA9IEwnYXR0cmlidXQgJ2hyZWYnIGQndW4gXHUwMEU5bFx1MDBFOW1lbnQgJ2luY2x1ZGUnIGVzdCBtYW5xdWFudC4KLVJlY3Vyc2l2ZUluY2x1ZGUgPSBFbFx1MDBFOW1lbnQgImluY2x1ZGUiIHJcdTAwRTljdXJzaWYgZFx1MDBFOXRlY3RcdTAwRTkuIExlIGRvY3VtZW50ICcnezB9JycgYSBkXHUwMEU5alx1MDBFMCBcdTAwRTl0XHUwMEU5IHRyYWl0XHUwMEU5LgotSW52YWxpZFBhcnNlVmFsdWUgPSBWYWxldXIgbm9uIHZhbGlkZSBwb3VyIGwnJ2F0dHJpYnV0ICcncGFyc2UnJyBzdXIgbCcnXHUwMEU5bFx1MDBFOW1lbnQgJydpbmNsdWRlJycgOiAnJ3swfScnLgotWE1MUGFyc2VFcnJvciA9IEVycmV1ciBsb3JzIGRlIGxhIHRlbnRhdGl2ZSBkJydhbmFseXNlIGR1IGZpY2hpZXIgWE1MIChocmVmPScnezB9JycpLiBSYWlzb24gOiB7MX0KLVhNTFJlc291cmNlRXJyb3IgPSBFY2hlYyBkZSBsJydvcFx1MDBFOXJhdGlvbiBJbmNsdWRlLCByXHUwMEU5dGFibGlzc2VtZW50IGRlIGwnJ1x1MDBFOWxcdTAwRTltZW50IGZhbGxiYWNrLiBFcnJldXIgZGUgcmVzc291cmNlIGxvcnMgZGUgbGEgbGVjdHVyZSBkdSBmaWNoaWVyIGVuIHRhbnQgcXVlIFhNTCAoaHJlZj0nJ3swfScnKS4gUmFpc29uIDogezF9Ci1UZXh0UmVzb3VyY2VFcnJvciA9IEVjaGVjIGRlIGwnJ29wXHUwMEU5cmF0aW9uIEluY2x1ZGUsIHJcdTAwRTl0YWJsaXNzZW1lbnQgZGUgbCcnXHUwMEU5bFx1MDBFOW1lbnQgZmFsbGJhY2suIEVycmV1ciBkZSByZXNzb3VyY2UgbG9ycyBkZSBsYSBsZWN0dXJlIGR1IGZpY2hpZXIgZW4gdGFudCBxdWUgdGV4dGUgKGhyZWY9Jyd7MH0nJykuIFJhaXNvbiA6IHsxfQotTk9fWFBvaW50ZXJTY2hlbWEgPSBQYXIgZFx1MDBFOWZhdXQsIGxlIHNjaFx1MDBFOW1hIHBvdXIgInswfSIgbicnZXN0IHBhcyBwcmlzIGVuIGNoYXJnZS4gRFx1MDBFOWZpbmlzc2V6IHZvdHJlIHByb3ByZSBzY2hcdTAwRTltYSBwb3VyIHswfS4gUmVwb3J0ZXotdm91cyBcdTAwRTAgbCcnYWRyZXNzZSBodHRwOi8vYXBhY2hlLm9yZy94bWwvcHJvcGVydGllcy94cG9pbnRlci1zY2hlbWEKLU5PX1N1YlJlc291cmNlSWRlbnRpZmllZCA9IEF1Y3VuZSBzb3VzLXJlc3NvdXJjZSBuJydlc3QgaWRlbnRpZmlcdTAwRTllIHBhciBsZSBwcm9jZXNzZXVyIFhQb2ludGVyIHBvdXIgbGUgcG9pbnRldXIgezB9LgotTm9uRHVwbGljYXRlTm90YXRpb24gPSBQbHVzaWV1cnMgbm90YXRpb25zIHBvcnRhbnQgbGUgbm9tICcnezB9Jycgb250IFx1MDBFOXRcdTAwRTkgdXRpbGlzXHUwMEU5ZXMsIG1haXMgZWxsZXMgbicnb250IHBhcyBcdTAwRTl0XHUwMEU5IGNvbnNpZFx1MDBFOXJcdTAwRTllcyBjb21tZSBkZXMgZG91YmxvbnMuCi1Ob25EdXBsaWNhdGVVbnBhcnNlZEVudGl0eSA9IFBsdXNpZXVycyBlbnRpdFx1MDBFOXMgbm9uIGFuYWx5c1x1MDBFOWVzIHBvcnRhbnQgbGUgbm9tICcnezB9Jycgb250IFx1MDBFOXRcdTAwRTkgdXRpbGlzXHUwMEU5ZXMsIG1haXMgZWxsZXMgbicnb250IHBhcyBcdTAwRTl0XHUwMEU5IGNvbnNpZFx1MDBFOXJcdTAwRTllcyBjb21tZSBkZXMgZG91YmxvbnMuCi1YcG9pbnRlck1pc3NpbmcgPSBsJ2F0dHJpYnV0IHhwb2ludGVyIGRvaXQgXHUwMEVBdHJlIHByXHUwMEU5c2VudCBsb3JzcXVlIGwnYXR0cmlidXQgaHJlZiBlc3QgYWJzZW50LgotQWNjZXB0TWFsZm9ybWVkID0gTGVzIGNhcmFjdFx1MDBFOHJlcyBub24gY29tcHJpcyBlbnRyZSAjeDIwIGV0ICN4N0UgbmUgc29udCBwYXMgYXV0b3Jpc1x1MDBFOXMgY29tbWUgdmFsZXVyIGRlIGwnYXR0cmlidXQgJ2FjY2VwdCcgZCd1biBcdTAwRTlsXHUwMEU5bWVudCAnaW5jbHVkZScuCi1BY2NlcHRMYW5ndWFnZU1hbGZvcm1lZCA9IExlcyBjYXJhY3RcdTAwRThyZXMgbm9uIGNvbXByaXMgZW50cmUgI3gyMCBldCAjeDdFIG5lIHNvbnQgcGFzIGF1dG9yaXNcdTAwRTlzIGNvbW1lIHZhbGV1ciBkZSBsJ2F0dHJpYnV0ICdhY2NlcHQtbGFuZ3VhZ2UnIGQndW4gXHUwMEU5bFx1MDBFOW1lbnQgJ2luY2x1ZGUnLgotUm9vdEVsZW1lbnRSZXF1aXJlZCA9IFVuIGRvY3VtZW50IGRvbnQgbGUgZm9ybWF0IGVzdCBjb3JyZWN0IHJlcXVpZXJ0IHVuIFx1MDBFOWxcdTAwRTltZW50IHJhY2luZS4KLU11bHRpcGxlUm9vdEVsZW1lbnRzID0gVW4gZG9jdW1lbnQgZG9udCBsZSBmb3JtYXQgZXN0IGNvcnJlY3QgbmUgZG9pdCBwYXMgY29udGVuaXIgcGx1c2lldXJzIFx1MDBFOWxcdTAwRTltZW50cyByYWNpbmUuCi1Db250ZW50SWxsZWdhbEF0VG9wTGV2ZWwgPSBMZSByZW1wbGFjZW1lbnQgZCd1biBcdTAwRTlsXHUwMEU5bWVudCAnaW5jbHVkZScgYWZmaWNoXHUwMEU5IGVuIHRhbnQgcXUnXHUwMEU5bFx1MDBFOW1lbnQgZGUgZG9jdW1lbnQgZGFucyBsJ2Vuc2VtYmxlIGQnaW5mb3JtYXRpb24gc291cmNlIGRlIG5pdmVhdSBzdXBcdTAwRTlyaWV1ciBuZSBkb2l0IHBhcyBjb250ZW5pciBkZSBjYXJhY3RcdTAwRThyZXMuCi1VbmV4cGFuZGVkRW50aXR5UmVmZXJlbmNlSWxsZWdhbCA9IExlIHJlbXBsYWNlbWVudCBkJ3VuIFx1MDBFOWxcdTAwRTltZW50ICdpbmNsdWRlJyBhZmZpY2hcdTAwRTkgZW4gdGFudCBxdSdcdTAwRTlsXHUwMEU5bWVudCBkZSBkb2N1bWVudCBkYW5zIGwnZW5zZW1ibGUgZCdpbmZvcm1hdGlvbiBzb3VyY2UgZGUgbml2ZWF1IHN1cFx1MDBFOXJpZXVyIG5lIGRvaXQgcGFzIGNvbnRlbmlyIGRlIHJcdTAwRTlmXHUwMEU5cmVuY2VzIGQnZW50aXRcdTAwRTkgbm9uIGRcdTAwRTl2ZWxvcHBcdTAwRTllcy4KLUhyZWZGcmFnbWVudElkZW50aWZpZXJJbGxlZ2FsID0gTGVzIGlkZW50aWZpY2F0ZXVycyBkZSBmcmFnbWVudCBuZSBkb2l2ZW50IHBhcyBcdTAwRUF0cmUgdXRpbGlzXHUwMEU5cy4gTGEgdmFsZXVyIGQnJ2F0dHJpYnV0ICcnaHJlZicnICcnezB9JycgbicnZXN0IHBhcyBhdXRvcmlzXHUwMEU5ZS4KLUhyZWZTeW50YWN0aWNhbGx5SW52YWxpZCA9IExhIHN5bnRheGUgZGUgbGEgdmFsZXVyIGQnJ2F0dHJpYnV0ICcnaHJlZicnICcnezB9JycgZXN0IGluY29ycmVjdGUuIEFwclx1MDBFOHMgbCcnYXBwbGljYXRpb24gZGVzIHJcdTAwRThnbGVzIGQnJ1x1MDBFOWNoYXBwZW1lbnQsIGxhIHZhbGV1ciBuJydlc3QgcGFzIHVuIFVSSSBvdSB1biBJUkkgZXhwcmltXHUwMEU5IGRhbnMgdW5lIHN5bnRheGUgY29ycmVjdGUuCi1YUG9pbnRlclN0cmVhbWFiaWxpdHkgPSBVbiBYUG9pbnRlciBwb2ludGFudCBzdXIgdW4gZW1wbGFjZW1lbnQgZGUgbCdlbnNlbWJsZSBkJ2luZm9ybWF0aW9uIHNvdXJjZSBhIFx1MDBFOXRcdTAwRTkgaW5kaXF1XHUwMEU5LiBDZXQgZW1wbGFjZW1lbnQgZXN0IGluYWNjZXNzaWJsZSBlbiByYWlzb24gZGVzIGNhcmFjdFx1MDBFOXJpc3RpcXVlcyBkZSB0cmFuc21pc3Npb24gZW4gY29udGludSBkdSBwcm9jZXNzZXVyLgotCi1YUG9pbnRlclJlc29sdXRpb25VbnN1Y2Nlc3NmdWwgPSBFY2hlYyBkZSBsYSByXHUwMEU5c29sdXRpb24gZGUgWFBvaW50ZXIuCi0KLSMgTWVzc2FnZXMgZnJvbSBlcnJvbmVvdXMgc2V0LXVwCi1JbmNvbXBhdGlibGVOYW1lc3BhY2VDb250ZXh0ID0gTGUgdHlwZSBkZSBsJ1x1MDBFOWxcdTAwRTltZW50IE5hbWVzcGFjZUNvbnRleHQgbidlc3QgcGFzIGNvbXBhdGlibGUgYXZlYyBsJ3V0aWxpc2F0aW9uIGRlIGwnXHUwMEU5bFx1MDBFOW1lbnQgWEluY2x1ZGUgOyBpbCBkb2l0IHMnYWdpciBkJ3VuZSBpbnN0YW5jZSBkZSBYSW5jbHVkZU5hbWVzcGFjZVN1cHBvcnQKLUV4cGFuZGVkU3lzdGVtSWQgPSBJbXBvc3NpYmxlIGRlIGRcdTAwRTl2ZWxvcHBlciBsJ0lEIHN5c3RcdTAwRThtZSBkZSBsYSByZXNzb3VyY2UgaW5jbHVzZQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWEluY2x1ZGVNZXNzYWdlc19pdC5wcm9wZXJ0aWVzIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWEluY2x1ZGVNZXNzYWdlc19pdC5wcm9wZXJ0aWVzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxOThmZTViLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hJbmNsdWRlTWVzc2FnZXNfaXQucHJvcGVydGllcworKysgL2Rldi9udWxsCkBAIC0xLDM2ICswLDAgQEAKLSMgTWVzc2FnZXMgZm9yIG1lc3NhZ2UgcmVwb3J0aW5nCi1CYWRNZXNzYWdlS2V5ID0gSW1wb3NzaWJpbGUgdHJvdmFyZSBpbCBtZXNzYWdnaW8gZGkgZXJyb3JlIGNvcnJpc3BvbmRlbnRlIGFsbGEgY2hpYXZlIGRpIG1lc3NhZ2dpby4KLUZvcm1hdEZhaWxlZCA9IFNpIFx1MDBFOCB2ZXJpZmljYXRvIHVuIGVycm9yZSBpbnRlcm5vIGR1cmFudGUgbGEgZm9ybWF0dGF6aW9uZSBkZWwgc2VndWVudGUgbWVzc2FnZ2lvOlxuICAKLQotIyBNZXNzYWdlcyBmb3IgZXJyb25lb3VzIGlucHV0Ci1Ob0ZhbGxiYWNrID0gRXJyb3JlIGRlbGwnJ2VsZW1lbnRvICcnaW5jbHVkZScnIGNvbiBocmVmICcnezB9JycuIE5vbiBcdTAwRTggc3RhdG8gdHJvdmF0byBhbGN1bmUgZWxlbWVudG8gJydmYWxsYmFjaycnLgotTXVsdGlwbGVGYWxsYmFja3MgPSBbY2hpbGRyZW5dIGRpIHVuIGVsZW1lbnRvICdpbmNsdWRlJyBub24gcG9zc29ubyBjb250ZW5lcmUgcGlcdTAwRjkgZWxlbWVudGkgJ2ZhbGxiYWNrJy4KLUZhbGxiYWNrUGFyZW50ID0gXHUwMEM4IHN0YXRvIHRyb3ZhdG8gdW4gZWxlbWVudG8gJ2ZhbGxiYWNrJyBjaGUgbm9uIGhhIHVuIGVsZW1lbnRvICdpbmNsdWRlJyBjb21lIHBhZHJlLgotSW5jbHVkZUNoaWxkID0gR2xpIGVsZW1lbnRpIGRlbGxvIHNwYXppbyBkaSBub21pICcnaHR0cDovL3d3dy53My5vcmcvMjAwMS9YSW5jbHVkZScnIGRpdmVyc2kgZGEgJydmYWxsYmFjaycnIG5vbiBwb3Nzb25vIGF2ZXJlIGVsZW1lbnRpIGZpZ2xpbyBkaSBlbGVtZW50aSAnJ2luY2x1ZGUnJy4gIFR1dHRhdmlhLCBcdTAwRTggc3RhdG8gdHJvdmF0byAnJ3swfScnLgotRmFsbGJhY2tDaGlsZCA9IEdsaSBlbGVtZW50aSBkZWxsbyBzcGF6aW8gZGkgbm9taSAnJ2h0dHA6Ly93d3cudzMub3JnLzIwMDEvWEluY2x1ZGUnJyBkaXZlcnNpIGRhICcnaW5jbHVkZScnIG5vbiBwb3Nzb25vIGF2ZXJlIGVsZW1lbnRpIGZpZ2xpbyBkaSBlbGVtZW50aSAnJ2ZhbGxiYWNrJycuICBUdXR0YXZpYSwgXHUwMEU4IHN0YXRvIHRyb3ZhdG8gJyd7MH0nJy4KLUhyZWZNaXNzaW5nID0gTWFuY2EgbCdhdHRyaWJ1dG8gJ2hyZWYnIGRpIHVuIGVsZW1lbnRvICdpbmNsdWRlJy4KLVJlY3Vyc2l2ZUluY2x1ZGUgPSBJbmNsdXNpb25lIHJpY29yc2l2YSByaWxldmF0YS4gSWwgZG9jdW1lbnRvICcnezB9JycgXHUwMEU4IGdpXHUwMEUwIHN0YXRvIGVsYWJvcmF0by4KLUludmFsaWRQYXJzZVZhbHVlID0gVmFsb3JlIG5vbiB2YWxpZG8gcGVyIGwnJ2F0dHJpYnV0byAnJ3BhcnNlJycgbmVsbCcnZWxlbWVudG8gJydpbmNsdWRlJyc6ICcnezB9JycuCi1YTUxQYXJzZUVycm9yID0gRXJyb3JlIGR1cmFudGUgaWwgdGVudGF0aXZvIGRpIGFuYWxpenphcmUgaWwgZmlsZSBYTUwgKGhyZWY9Jyd7MH0nJykuIENhdXNhOiB7MX0KLVhNTFJlc291cmNlRXJyb3IgPSBPcGVyYXppb25lIGRpIGluY2x1c2lvbmUgbm9uIHJpdXNjaXRhLiBWZXJyXHUwMEUwIHJpcHJpc3RpbmF0byBpbCBmYWxsYmFjay4gRXJyb3JlIGRpIHJpc29yc2EgZHVyYW50ZSBsYSBsZXR0dXJhIGRlbCBmaWxlIGNvbWUgWE1MIChocmVmPScnezB9JycpLiBNb3Rpdm86IHsxfQotVGV4dFJlc291cmNlRXJyb3IgPSBPcGVyYXppb25lIGRpIGluY2x1c2lvbmUgbm9uIHJpdXNjaXRhLiBWZXJyXHUwMEUwIHJpcHJpc3RpbmF0byBpbCBmYWxsYmFjay4gRXJyb3JlIGRpIHJpc29yc2EgZHVyYW50ZSBsYSBsZXR0dXJhIGRlbCBmaWxlIGNvbWUgdGVzdG8gKGhyZWY9Jyd7MH0nJykuIE1vdGl2bzogezF9Ci1OT19YUG9pbnRlclNjaGVtYSA9IExvIHNjaGVtYSBwZXIgInswfSIgbm9uIFx1MDBFOCBzdXBwb3J0YXRvIHBlciBpbXBvc3RhemlvbmUgcHJlZGVmaW5pdGEuIERlZmluaXJlIGlsIHByb3ByaW8gc2NoZW1hIHBlciB7MH0uIFZlZGVyZSBodHRwOi8vYXBhY2hlLm9yZy94bWwvcHJvcGVydGllcy94cG9pbnRlci1zY2hlbWEuCi1OT19TdWJSZXNvdXJjZUlkZW50aWZpZWQgPSBOZXNzdW5hIHJpc29yc2Egc2Vjb25kYXJpYSBpZGVudGlmaWNhdGEgZGFsIHByb2Nlc3NvcmUgWFBvaW50ZXIgcGVyIGlsIHB1bnRhdG9yZSB7MH0uCi1Ob25EdXBsaWNhdGVOb3RhdGlvbiA9IFNvbm8gc3RhdGUgdXRpbGl6emF0ZSBwaVx1MDBGOSBub3RhemlvbmkgY29uIGlsIG5vbWUgJyd7MH0nJywgbWEgXHUwMEU4IHN0YXRvIGRldGVybWluYXRvIGNoZSBub24gc29ubyBkdXBsaWNhdGkuCi1Ob25EdXBsaWNhdGVVbnBhcnNlZEVudGl0eSA9IFNvbm8gc3RhdGUgdXRpbGl6emF0ZSBwaVx1MDBGOSBlbnRpdFx1MDBFMCBub24gYW5hbGl6emF0ZSBjb24gaWwgbm9tZSAnJ3swfScnLCBtYSBcdTAwRTggc3RhdG8gZGV0ZXJtaW5hdG8gY2hlIG5vbiBzb25vIGR1cGxpY2F0aS4KLVhwb2ludGVyTWlzc2luZyA9IEwnYXR0cmlidXRvIHhwb2ludGVyIGRldmUgZXNzZXJlIHByZXNlbnRlIHNlIFx1MDBFOCBhc3NlbnRlIGwnYXR0cmlidXRvIGhyZWYuCi1BY2NlcHRNYWxmb3JtZWQgPSBJIGNhcmF0dGVyaSBjaGUgbm9uIHJpZW50cmFubyB0cmEgI3gyMCBlICN4N0Ugbm9uIHNvbm8gY29uc2VudGl0aSBuZWwgdmFsb3JlIGRlbGwnYXR0cmlidXRvICdhY2NlcHQnIGRpIHVuIGVsZW1lbnRvICdpbmNsdWRlJy4KLUFjY2VwdExhbmd1YWdlTWFsZm9ybWVkID0gSSBjYXJhdHRlcmkgY2hlIG5vbiByaWVudHJhbm8gdHJhICN4MjAgZSAjeDdFIG5vbiBzb25vIGNvbnNlbnRpdGkgbmVsIHZhbG9yZSBkZWxsJ2F0dHJpYnV0byAnYWNjZXB0LWxhbmd1YWdlJyBkaSB1biBlbGVtZW50byAnaW5jbHVkZScuCi1Sb290RWxlbWVudFJlcXVpcmVkID0gVW4gZG9jdW1lbnRvIGNvbiBmb3JtYXRvIGNvcnJldHRvIHJpY2hpZWRlIHVuIGVsZW1lbnRvIHJhZGljZS4KLU11bHRpcGxlUm9vdEVsZW1lbnRzID0gVW4gZG9jdW1lbnRvIGNvbiBmb3JtYXRvIGNvcnJldHRvIG5vbiBkZXZlIGNvbnRlbmVyZSBwaVx1MDBGOSBlbGVtZW50aSByYWRpY2UuCi1Db250ZW50SWxsZWdhbEF0VG9wTGV2ZWwgPSBMYSBzb3N0aXR1emlvbmUgZGkgdW4gZWxlbWVudG8gJ2luY2x1ZGUnIGluZGljYXRvIGNvbWUgZWxlbWVudG8gZGkgZG9jdW1lbnRvIG5lbCBzZXQgZGkgaW5mb3JtYXppb25pIGRpIG9yaWdpbmUgbmVsIGxpdmVsbG8gc3VwZXJpb3JlIG5vbiBwdVx1MDBGMiBjb250ZW5lcmUgY2FyYXR0ZXJpLgotVW5leHBhbmRlZEVudGl0eVJlZmVyZW5jZUlsbGVnYWwgPSBMYSBzb3N0aXR1emlvbmUgZGkgdW4gZWxlbWVudG8gJ2luY2x1ZGUnIGluZGljYXRvIGNvbWUgZWxlbWVudG8gZGkgZG9jdW1lbnRvIG5lbCBzZXQgZGkgaW5mb3JtYXppb25pIGRpIG9yaWdpbmUgbmVsIGxpdmVsbG8gc3VwZXJpb3JlIG5vbiBwdVx1MDBGMiBjb250ZW5lcmUgcmlmZXJpbWVudGkgZGkgZW50aXRcdTAwRTAgbm9uIGVzcGFuc2kuCi1IcmVmRnJhZ21lbnRJZGVudGlmaWVySWxsZWdhbCA9IE5vbiB1dGlsaXp6YXJlIGdsaSBpZGVudGlmaWNhdGl2aSBkaSBmcmFtbWVudG8uIElsIHZhbG9yZSAnJ3swfScnIGRlbGwnJ2F0dHJpYnV0byAnJ2hyZWYnJyBub24gXHUwMEU4IGNvbnNlbnRpdG8uCi1IcmVmU3ludGFjdGljYWxseUludmFsaWQgPSBJbCB2YWxvcmUgJyd7MH0nJyBkZWxsJydhdHRyaWJ1dG8gJydocmVmJycgbm9uIFx1MDBFOCB2YWxpZG8gYSBsaXZlbGxvIGRpIHNpbnRhc3NpLiBEb3BvIGF2ZXIgYXBwbGljYXRvIGxlIHJlZ29sZSBkaSBlc2NhcGUsIGlsIHZhbG9yZSBub24gXHUwMEU4IHVuIFVSSSBvIHVuIElSSSBjb24gc2ludGFzc2kgY29ycmV0dGEuCi1YUG9pbnRlclN0cmVhbWFiaWxpdHkgPSBcdTAwQzggc3RhdG8gc3BlY2lmaWNhdG8gdW4geHBvaW50ZXIgY2hlIHB1bnRhIGEgdW5hIHBvc2l6aW9uZSBuZWwgc2V0IGRpIGluZm9ybWF6aW9uaSBkaSBvcmlnaW5lLiBOb24gXHUwMEU4IHBvc3NpYmlsZSBhY2NlZGVyZSBhIHF1ZXN0YSBwb3NpemlvbmUgcG9pY2hcdTAwRTkgaWwgcHJvY2Vzc29yZSBcdTAwRTggZGkgdGlwbyBzdHJlYW1pbmcuCi0KLVhQb2ludGVyUmVzb2x1dGlvblVuc3VjY2Vzc2Z1bCA9IFJpc29sdXppb25lIGRpIFhQb2ludGVyIG5vbiByaXVzY2l0YS4KLQotIyBNZXNzYWdlcyBmcm9tIGVycm9uZW91cyBzZXQtdXAKLUluY29tcGF0aWJsZU5hbWVzcGFjZUNvbnRleHQgPSBJbCB0aXBvIGRpIE5hbWVzcGFjZUNvbnRleHQgbm9uIFx1MDBFOCBjb21wYXRpYmlsZSBjb24gbCd1c28gZGkgWEluY2x1ZGU7IGRldmUgZXNzZXJlIHVuJ2lzdGFuemEgZGkgWEluY2x1ZGVOYW1lc3BhY2VTdXBwb3J0LgotRXhwYW5kZWRTeXN0ZW1JZCA9IEltcG9zc2liaWxlIGVzcGFuZGVyZSBsJ0lEIGRpIHNpc3RlbWEgZGVsbGEgcmlzb3JzYSBpbmNsdXNhCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9YSW5jbHVkZU1lc3NhZ2VzX2phLnByb3BlcnRpZXMgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9YSW5jbHVkZU1lc3NhZ2VzX2phLnByb3BlcnRpZXMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDU1YWJmZGEuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWEluY2x1ZGVNZXNzYWdlc19qYS5wcm9wZXJ0aWVzCisrKyAvZGV2L251bGwKQEAgLTEsMzYgKzAsMCBAQAotIyBNZXNzYWdlcyBmb3IgbWVzc2FnZSByZXBvcnRpbmcKLUJhZE1lc3NhZ2VLZXkgPSBcdTMwRTFcdTMwQzNcdTMwQkJcdTMwRkNcdTMwQjhcdTMwRkJcdTMwQURcdTMwRkNcdTMwNkJcdTVCRkVcdTVGRENcdTMwNTlcdTMwOEJcdTMwQThcdTMwRTlcdTMwRkNcdTMwRkJcdTMwRTFcdTMwQzNcdTMwQkJcdTMwRkNcdTMwQjhcdTMwNENcdTg5OEJcdTMwNjRcdTMwNEJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLUZvcm1hdEZhaWxlZCA9IFx1NkIyMVx1MzA2RVx1MzBFMVx1MzBDM1x1MzBCQlx1MzBGQ1x1MzBCOFx1MzA2RVx1NjZGOFx1NUYwRlx1OEEyRFx1NUI5QVx1NEUyRFx1MzA2Qlx1NTE4NVx1OTBFOFx1MzBBOFx1MzBFOVx1MzBGQ1x1MzA0Q1x1NzY3QVx1NzUxRlx1MzA1N1x1MzA3RVx1MzA1N1x1MzA1RjpcbiAgCi0KLSMgTWVzc2FnZXMgZm9yIGVycm9uZW91cyBpbnB1dAotTm9GYWxsYmFjayA9IGhyZWYgJyd7MH0nJ1x1MzA5Mlx1NTQyQlx1MzA4MCcnaW5jbHVkZScnXHUzMDRDXHU1OTMxXHU2NTU3XHUzMDU3XHUzMDAxJydmYWxsYmFjaycnXHU4OTgxXHU3RDIwXHUzMDRDXHU4OThCXHUzMDY0XHUzMDRCXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDY3XHUzMDU3XHUzMDVGXHUzMDAyCi1NdWx0aXBsZUZhbGxiYWNrcyA9ICdpbmNsdWRlJ1x1ODk4MVx1N0QyMFx1MzA2RVtjaGlsZHJlbl1cdTMwNkJcdTMwNkZcdTMwMDFcdTg5MDdcdTY1NzBcdTMwNkUnZmFsbGJhY2snXHU4OTgxXHU3RDIwXHUzMDkyXHU1NDJCXHUzMDgxXHUzMDhCXHUzMDUzXHUzMDY4XHUzMDZGXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi1GYWxsYmFja1BhcmVudCA9IFx1ODlBQVx1MzA2OFx1MzA1N1x1MzA2NidpbmNsdWRlJ1x1MzA5Mlx1NjMwMVx1MzA1Rlx1MzA2QVx1MzA0NCdmYWxsYmFjaydcdTg5ODFcdTdEMjBcdTMwNENcdTg5OEJcdTMwNjRcdTMwNEJcdTMwOEFcdTMwN0VcdTMwNTdcdTMwNUZcdTMwMDIKLUluY2x1ZGVDaGlsZCA9IFx1MzBDRFx1MzBGQ1x1MzBFMFx1MzBCOVx1MzBEQVx1MzBGQ1x1MzBCOScnaHR0cDovL3d3dy53My5vcmcvMjAwMS9YSW5jbHVkZScnXHUzMDRCXHUzMDg5XHUzMDZFXHU4OTgxXHU3RDIwXHUzMDZGXHUzMDAxJydmYWxsYmFjaycnXHUzMDkyXHU5NjY0XHUzMDQ0XHUzMDY2XHUzMDAxJydpbmNsdWRlJydcdTg5ODFcdTdEMjBcdTMwNkVcdTVCNTBcdTMwNkJcdTMwNTlcdTMwOEJcdTMwNTNcdTMwNjhcdTMwNkZcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDJcdTMwNURcdTMwOENcdTMwNkJcdTMwODJcdTMwNEJcdTMwNEJcdTMwOEZcdTMwODlcdTMwNUFcdTMwMDEnJ3swfScnXHUzMDRDXHU4OThCXHUzMDY0XHUzMDRCXHUzMDhBXHUzMDdFXHUzMDU3XHUzMDVGXHUzMDAyCi1GYWxsYmFja0NoaWxkID0gXHUzMENEXHUzMEZDXHUzMEUwXHUzMEI5XHUzMERBXHUzMEZDXHUzMEI5JydodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hJbmNsdWRlJydcdTMwNEJcdTMwODlcdTMwNkVcdTg5ODFcdTdEMjBcdTMwNkZcdTMwMDEnJ2luY2x1ZGUnJ1x1MzA5Mlx1OTY2NFx1MzA0NFx1MzA2Nlx1MzAwMScnZmFsbGJhY2snJ1x1ODk4MVx1N0QyMFx1MzA2RVx1NUI1MFx1MzA2Qlx1MzA1OVx1MzA4Qlx1MzA1M1x1MzA2OFx1MzA2Rlx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMlx1MzA1RFx1MzA4Q1x1MzA2Qlx1MzA4Mlx1MzA0Qlx1MzA0Qlx1MzA4Rlx1MzA4OVx1MzA1QVx1MzAwMScnezB9JydcdTMwNENcdTg5OEJcdTMwNjRcdTMwNEJcdTMwOEFcdTMwN0VcdTMwNTdcdTMwNUZcdTMwMDIKLUhyZWZNaXNzaW5nID0gJ2luY2x1ZGUnXHU4OTgxXHU3RDIwXHUzMDZFJ2hyZWYnXHU1QzVFXHU2MDI3XHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi1SZWN1cnNpdmVJbmNsdWRlID0gXHU1MThEXHU1RTMwXHU3Njg0XHUzMDZBaW5jbHVkZVx1MzA0Q1x1NjkxQ1x1NTFGQVx1MzA1NVx1MzA4Q1x1MzA3RVx1MzA1N1x1MzA1Rlx1MzAwMlx1MzBDOVx1MzBBRFx1MzBFNVx1MzBFMVx1MzBGM1x1MzBDOCcnezB9JydcdTMwNkZcdTMwNTlcdTMwNjdcdTMwNkJcdTUxRTZcdTc0MDZcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTlcdTMwMDIKLUludmFsaWRQYXJzZVZhbHVlID0gJydpbmNsdWRlJydcdTg5ODFcdTdEMjBcdTMwNkUnJ3BhcnNlJydcdTVDNUVcdTYwMjdcdTMwNkVcdTUwMjRcdTMwNENcdTcxMjFcdTUyQjlcdTMwNjdcdTMwNTk6ICcnezB9JydcdTMwMDIKLVhNTFBhcnNlRXJyb3IgPSBYTUxcdTMwRDVcdTMwQTFcdTMwQTRcdTMwRUJcdTMwNkVcdTg5RTNcdTY3OTBcdThBNjZcdTg4NENcdTRFMkRcdTMwNkJcdTMwQThcdTMwRTlcdTMwRkNcdTMwNENcdTc2N0FcdTc1MUZcdTMwNTdcdTMwN0VcdTMwNTdcdTMwNUYoaHJlZj0nJ3swfScnKVx1MzAwMlx1NzQwNlx1NzUzMTogezF9Ci1YTUxSZXNvdXJjZUVycm9yID0gXHUzMEE0XHUzMEYzXHUzMEFGXHUzMEVCXHUzMEZDXHUzMEM5XHU2NENEXHU0RjVDXHUzMDRDXHU1OTMxXHU2NTU3XHUzMDU3XHUzMDAxXHUzMEQ1XHUzMEE5XHUzMEZDXHUzMEVCXHUzMEQwXHUzMEMzXHUzMEFGXHUzMDZCXHU2MjNCXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyXHUzMEQ1XHUzMEExXHUzMEE0XHUzMEVCXHUzMDkyWE1MXHUzMDY4XHUzMDU3XHUzMDY2XHU4QUFEXHU1M0Q2XHUzMDhBXHU0RTJEXHUzMDZCXHUzMEVBXHUzMEJEXHUzMEZDXHUzMEI5XHUzMEZCXHUzMEE4XHUzMEU5XHUzMEZDXHUzMDRDXHU3NjdBXHU3NTFGXHUzMDU3XHUzMDdFXHUzMDU3XHUzMDVGKGhyZWY9Jyd7MH0nJylcdTMwMDJcdTc0MDZcdTc1MzE6IHsxfQotVGV4dFJlc291cmNlRXJyb3IgPSBcdTMwQTRcdTMwRjNcdTMwQUZcdTMwRUJcdTMwRkNcdTMwQzlcdTY0Q0RcdTRGNUNcdTMwNENcdTU5MzFcdTY1NTdcdTMwNTdcdTMwMDFcdTMwRDVcdTMwQTlcdTMwRkNcdTMwRUJcdTMwRDBcdTMwQzNcdTMwQUZcdTMwNkJcdTYyM0JcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDJcdTMwRDVcdTMwQTFcdTMwQTRcdTMwRUJcdTMwOTJcdTMwQzZcdTMwQURcdTMwQjlcdTMwQzhcdTMwNjhcdTMwNTdcdTMwNjZcdThBQURcdTUzRDZcdTMwOEFcdTRFMkRcdTMwNkJcdTMwRUFcdTMwQkRcdTMwRkNcdTMwQjlcdTMwRkJcdTMwQThcdTMwRTlcdTMwRkNcdTMwNENcdTc2N0FcdTc1MUZcdTMwNTdcdTMwN0VcdTMwNTdcdTMwNUYoaHJlZj0nJ3swfScnKVx1MzAwMlx1NzQwNlx1NzUzMTogezF9Ci1OT19YUG9pbnRlclNjaGVtYSA9IFx1MzBDN1x1MzBENVx1MzBBOVx1MzBFQlx1MzBDOFx1MzA2N1x1MzA2Rlx1MzAwMSJ7MH0iXHUzMDZFXHUzMEI5XHUzMEFEXHUzMEZDXHUzMERFXHUzMDZGXHUzMEI1XHUzMEREXHUzMEZDXHUzMEM4XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyezB9XHUzMDZCXHU1QkZFXHUzMDU3XHUzMDY2XHU3MkVDXHU4MUVBXHUzMDZFXHUzMEI5XHUzMEFEXHUzMEZDXHUzMERFXHUzMDkyXHU1QjlBXHU3RkE5XHUzMDU3XHUzMDY2XHUzMDRGXHUzMDYwXHUzMDU1XHUzMDQ0XHUzMDAyaHR0cDovL2FwYWNoZS5vcmcveG1sL3Byb3BlcnRpZXMveHBvaW50ZXItc2NoZW1hXHUzMDkyXHU1M0MyXHU3MTY3XHUzMDU3XHUzMDY2XHUzMDRGXHUzMDYwXHUzMDU1XHUzMDQ0Ci1OT19TdWJSZXNvdXJjZUlkZW50aWZpZWQgPSBcdTMwRERcdTMwQTRcdTMwRjNcdTMwQkZ7MH1cdTMwNkVYUG9pbnRlclx1MzBEN1x1MzBFRFx1MzBCQlx1MzBDM1x1MzBCNVx1MzA2N1x1MzA2Rlx1MzBCNVx1MzBENlx1MzBFQVx1MzBCRFx1MzBGQ1x1MzBCOVx1MzA2Rlx1OEI1OFx1NTIyNVx1MzA1NVx1MzA4Q1x1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotTm9uRHVwbGljYXRlTm90YXRpb24gPSBcdTU0MERcdTUyNERcdTMwNEMnJ3swfScnXHUzMDZFXHU4OTA3XHU2NTcwXHUzMDZFXHU4ODY4XHU4QTE4XHU2Q0Q1XHUzMDRDXHU0RjdGXHU3NTI4XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5XHUzMDRDXHUzMDAxXHUzMDUzXHUzMDhDXHUzMDg5XHUzMDZFXHU4ODY4XHU4QTE4XHU2Q0Q1XHUzMDZGXHU5MUNEXHU4OTA3XHUzMDY4XHUzMDdGXHUzMDZBXHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi1Ob25EdXBsaWNhdGVVbnBhcnNlZEVudGl0eSA9IFx1NTQwRFx1NTI0RFx1MzA0QycnezB9JydcdTMwNkVcdTg5MDdcdTY1NzBcdTMwNkVcdTY3MkFcdTg5RTNcdTY3OTBcdTMwQThcdTMwRjNcdTMwQzZcdTMwQTNcdTMwQzZcdTMwQTNcdTMwNENcdTRGN0ZcdTc1MjhcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTlcdTMwNENcdTMwMDFcdTMwNTNcdTMwOENcdTMwODlcdTMwNkVcdTMwQThcdTMwRjNcdTMwQzZcdTMwQTNcdTMwQzZcdTMwQTNcdTMwNkZcdTkxQ0RcdTg5MDdcdTMwNjhcdTMwN0ZcdTMwNkFcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLVhwb2ludGVyTWlzc2luZyA9IGhyZWZcdTVDNUVcdTYwMjdcdTMwNENcdTVCNThcdTU3MjhcdTMwNTdcdTMwNkFcdTMwNDRcdTU4MzRcdTU0MDhcdTMwNkZcdTMwMDF4cG9pbnRlclx1NUM1RVx1NjAyN1x1MzA0Q1x1NUZDNVx1ODk4MVx1MzA2N1x1MzA1OVx1MzAwMgotQWNjZXB0TWFsZm9ybWVkID0gI3gyMFx1MzA0Qlx1MzA4OSN4N0VcdTMwNkVcdTdCQzRcdTU2RjJcdTMwNkJcdTU0MkJcdTMwN0VcdTMwOENcdTMwNkFcdTMwNDRcdTY1ODdcdTVCNTdcdTMwNkZcdTMwMDEnaW5jbHVkZSdcdTg5ODFcdTdEMjBcdTMwNkUnYWNjZXB0J1x1NUM1RVx1NjAyN1x1MzA2RVx1NTAyNFx1MzA2Qlx1MzA2Rlx1NEY3Rlx1NzUyOFx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotQWNjZXB0TGFuZ3VhZ2VNYWxmb3JtZWQgPSAjeDIwXHUzMDRCXHUzMDg5I3g3RVx1MzA2RVx1N0JDNFx1NTZGMlx1MzA2Qlx1NTQyQlx1MzA3RVx1MzA4Q1x1MzA2QVx1MzA0NFx1NjU4N1x1NUI1N1x1MzA2Rlx1MzAwMSdpbmNsdWRlJ1x1ODk4MVx1N0QyMFx1MzA2RSdhY2NlcHQtbGFuZ3VhZ2UnXHU1QzVFXHU2MDI3XHUzMDZFXHU1MDI0XHUzMDZCXHUzMDZGXHU0RjdGXHU3NTI4XHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi1Sb290RWxlbWVudFJlcXVpcmVkID0gXHU2NTc0XHU1RjYyXHU1RjBGXHUzMEM5XHUzMEFEXHUzMEU1XHUzMEUxXHUzMEYzXHUzMEM4XHUzMDZCXHUzMDZGXHUzMEVCXHUzMEZDXHUzMEM4XHU4OTgxXHU3RDIwXHUzMDRDXHU1RkM1XHU4OTgxXHUzMDY3XHUzMDU5XHUzMDAyCi1NdWx0aXBsZVJvb3RFbGVtZW50cyA9IFx1NjU3NFx1NUY2Mlx1NUYwRlx1MzBDOVx1MzBBRFx1MzBFNVx1MzBFMVx1MzBGM1x1MzBDOFx1MzA2Qlx1MzA2Rlx1MzAwMVx1ODkwN1x1NjU3MFx1MzA2RVx1MzBFQlx1MzBGQ1x1MzBDOFx1ODk4MVx1N0QyMFx1MzA5Mlx1NTQyQlx1MzA4MVx1MzA4Qlx1MzA1M1x1MzA2OFx1MzA2Rlx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotQ29udGVudElsbGVnYWxBdFRvcExldmVsID0gXHUzMEM4XHUzMEMzXHUzMEQ3XHUzMEVDXHUzMEQ5XHUzMEVCXHUzMDZFXHUzMEJEXHUzMEZDXHUzMEI5XHU2MEM1XHU1ODMxXHUzMEJCXHUzMEMzXHUzMEM4XHUzMDZCXHUzMEM5XHUzMEFEXHUzMEU1XHUzMEUxXHUzMEYzXHUzMEM4XHU4OTgxXHU3RDIwXHUzMDY4XHUzMDU3XHUzMDY2XHU1MUZBXHU3M0ZFXHUzMDU5XHUzMDhCJ2luY2x1ZGUnXHU4OTgxXHU3RDIwXHUzMDZFXHU3RjZFXHU2M0RCXHUzMDZCXHUzMDZGXHUzMDAxXHU2NTg3XHU1QjU3XHUzMDkyXHU1NDJCXHUzMDgxXHUzMDhCXHUzMDUzXHUzMDY4XHUzMDZGXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi1VbmV4cGFuZGVkRW50aXR5UmVmZXJlbmNlSWxsZWdhbCA9IFx1MzBDOFx1MzBDM1x1MzBEN1x1MzBFQ1x1MzBEOVx1MzBFQlx1MzA2RVx1MzBCRFx1MzBGQ1x1MzBCOVx1NjBDNVx1NTgzMVx1MzBCQlx1MzBDM1x1MzBDOFx1MzA2Qlx1MzBDOVx1MzBBRFx1MzBFNVx1MzBFMVx1MzBGM1x1MzBDOFx1ODk4MVx1N0QyMFx1MzA2OFx1MzA1N1x1MzA2Nlx1NTFGQVx1NzNGRVx1MzA1OVx1MzA4QidpbmNsdWRlJ1x1ODk4MVx1N0QyMFx1MzA2RVx1N0Y2RVx1NjNEQlx1MzA2Qlx1MzA2Rlx1MzAwMVx1NUM1NVx1OTU4Qlx1MzA1N1x1MzA2Nlx1MzA0NFx1MzA2QVx1MzA0NFx1MzBBOFx1MzBGM1x1MzBDNlx1MzBBM1x1MzBDNlx1MzBBM1x1NTNDMlx1NzE2N1x1MzA5Mlx1NTQyQlx1MzA4MVx1MzA4Qlx1MzA1M1x1MzA2OFx1MzA2Rlx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotSHJlZkZyYWdtZW50SWRlbnRpZmllcklsbGVnYWwgPSBcdTMwRDVcdTMwRTlcdTMwQjBcdTMwRTFcdTMwRjNcdTMwQzhcdThCNThcdTUyMjVcdTVCNTBcdTMwNkZcdTRGN0ZcdTc1MjhcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDInJ2hyZWYnJ1x1NUM1RVx1NjAyN1x1MzA2RVx1NTAyNCcnezB9JydcdTMwNkZcdThBMzFcdTUzRUZcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLUhyZWZTeW50YWN0aWNhbGx5SW52YWxpZCA9ICcnaHJlZicnXHU1QzVFXHU2MDI3XHUzMDZFXHU1MDI0Jyd7MH0nJ1x1MzA2RVx1NjlDQlx1NjU4N1x1MzA0Q1x1NzEyMVx1NTJCOVx1MzA2N1x1MzA1OVx1MzAwMlx1MzBBOFx1MzBCOVx1MzBCMVx1MzBGQ1x1MzBEN1x1MzBGQlx1MzBFQlx1MzBGQ1x1MzBFQlx1MzA5Mlx1OTA2OVx1NzUyOFx1MzA1OVx1MzA4Qlx1MzA2OFx1MzAwMVx1NTAyNFx1MzA2Rlx1NkI2M1x1MzA1N1x1MzA0NFx1NjlDQlx1NjU4N1x1MzA2RVVSSVx1MzA3RVx1MzA1Rlx1MzA2RklSSVx1MzA2Qlx1MzA2QVx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotWFBvaW50ZXJTdHJlYW1hYmlsaXR5ID0gXHUzMEJEXHUzMEZDXHUzMEI5XHU2MEM1XHU1ODMxXHUzMEJCXHUzMEMzXHUzMEM4XHU1MTg1XHUzMDZFXHU1ODM0XHU2MjQwXHUzMDkyXHU2MzA3XHUzMDU5eHBvaW50ZXJcdTMwNENcdTYzMDdcdTVCOUFcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTlcdTMwMDJcdTMwRDdcdTMwRURcdTMwQkJcdTMwQzNcdTMwQjVcdTMwNkVcdTMwQjlcdTMwQzhcdTMwRUFcdTMwRkNcdTMwREZcdTMwRjNcdTMwQjBcdTMwNkVcdTYwMjdcdThDRUFcdTRFMEFcdTMwMDFcdTMwNTNcdTMwNkVcdTU4MzRcdTYyNDBcdTMwNkJcdTMwNkZcdTMwQTJcdTMwQUZcdTMwQkJcdTMwQjlcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLQotWFBvaW50ZXJSZXNvbHV0aW9uVW5zdWNjZXNzZnVsID0gWFBvaW50ZXJcdTMwNkVcdTg5RTNcdTZDN0FcdTMwNkJcdTU5MzFcdTY1NTdcdTMwNTdcdTMwN0VcdTMwNTdcdTMwNUZcdTMwMDIKLQotIyBNZXNzYWdlcyBmcm9tIGVycm9uZW91cyBzZXQtdXAKLUluY29tcGF0aWJsZU5hbWVzcGFjZUNvbnRleHQgPSBOYW1lc3BhY2VDb250ZXh0XHUzMDZFXHUzMEJGXHUzMEE0XHUzMEQ3XHUzMDZGXHUzMDAxWEluY2x1ZGVcdTMwNkVcdTRGN0ZcdTc1MjhcdTMwNjhcdTRFOTJcdTYzREJcdTYwMjdcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDJYSW5jbHVkZU5hbWVzcGFjZVN1cHBvcnRcdTMwNkVcdTMwQTRcdTMwRjNcdTMwQjlcdTMwQkZcdTMwRjNcdTMwQjlcdTMwNjdcdTMwNDJcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTkKLUV4cGFuZGVkU3lzdGVtSWQgPSBcdTMwQTRcdTMwRjNcdTMwQUZcdTMwRUJcdTMwRkNcdTMwQzlcdTMwNTVcdTMwOENcdTMwNUZcdTMwRUFcdTMwQkRcdTMwRkNcdTMwQjlcdTMwNkVcdTMwQjdcdTMwQjlcdTMwQzZcdTMwRTBJRFx1MzA5Mlx1NjJFMVx1NUYzNVx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzA2N1x1MzA1N1x1MzA1RgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWEluY2x1ZGVNZXNzYWdlc19rby5wcm9wZXJ0aWVzIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWEluY2x1ZGVNZXNzYWdlc19rby5wcm9wZXJ0aWVzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3MTYzNjkwLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hJbmNsdWRlTWVzc2FnZXNfa28ucHJvcGVydGllcworKysgL2Rldi9udWxsCkBAIC0xLDM2ICswLDAgQEAKLSMgTWVzc2FnZXMgZm9yIG1lc3NhZ2UgcmVwb3J0aW5nCi1CYWRNZXNzYWdlS2V5ID0gXHVCQTU0XHVDMkRDXHVDOUMwIFx1RDBBNFx1QzVEMCBcdUQ1NzRcdUIyRjlcdUQ1NThcdUIyOTQgXHVDNjI0XHVCOTU4IFx1QkE1NFx1QzJEQ1x1QzlDMFx1Qjk3QyBcdUNDM0VcdUM3NDQgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4KLUZvcm1hdEZhaWxlZCA9IFx1QjJFNFx1Qzc0QyBcdUJBNTRcdUMyRENcdUM5QzBcdUM3NTggXHVENjE1XHVDMkREXHVDNzQ0IFx1QzlDMFx1QzgxNVx1RDU1OFx1QjI5NCBcdUM5MTEgXHVCMEI0XHVCRDgwIFx1QzYyNFx1Qjk1OFx1QUMwMCBcdUJDMUNcdUMwRERcdUQ1ODhcdUMyQjVcdUIyQzhcdUIyRTQuXG4gIAotCi0jIE1lc3NhZ2VzIGZvciBlcnJvbmVvdXMgaW5wdXQKLU5vRmFsbGJhY2sgPSBocmVmICcnezB9JydcdUM3NDQoXHVCOTdDKSBcdUMwQUNcdUM2QTlcdUQ1NUMgJydpbmNsdWRlJydcdUI5N0MgXHVDMkU0XHVEMzI4XHVENTg4XHVDNzNDXHVCQTcwICcnZmFsbGJhY2snJyBcdUM2OTRcdUMxOENcdUI5N0MgXHVDQzNFXHVDNzQ0IFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuCi1NdWx0aXBsZUZhbGxiYWNrcyA9ICdpbmNsdWRlJyBcdUM2OTRcdUMxOENcdUM3NTggW2NoaWxkcmVuXVx1QzVEMFx1QjI5NCBcdUI0NTAgXHVBQzFDIFx1Qzc3NFx1QzBDMVx1Qzc1OCAnZmFsbGJhY2snIFx1QzY5NFx1QzE4Q1x1QUMwMCBcdUQzRUNcdUQ1NjhcdUI0MjAgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4KLUZhbGxiYWNrUGFyZW50ID0gXHVDMEMxXHVDNzA0XHVCODVDICdpbmNsdWRlJ1x1Qjk3QyBcdUQzRUNcdUQ1NjhcdUQ1NThcdUM5QzAgXHVDNTRBXHVDNzQwICdmYWxsYmFjaycgXHVDNjk0XHVDMThDXHVBQzAwIFx1QkMxQ1x1QUNBQ1x1QjQxOFx1QzVDOFx1QzJCNVx1QjJDOFx1QjJFNC4KLUluY2x1ZGVDaGlsZCA9ICcnZmFsbGJhY2snJyBcdUM2NzhcdUM1RDAgXHVCMkU0XHVCOTc4ICcnaHR0cDovL3d3dy53My5vcmcvMjAwMS9YSW5jbHVkZScnIFx1QjEyNFx1Qzc4NFx1QzJBNFx1RDM5OFx1Qzc3NFx1QzJBNFx1Qzc1OCBcdUM2OTRcdUMxOENcdUIyOTQgJydpbmNsdWRlJycgXHVDNjk0XHVDMThDXHVDNzU4IFx1RDU1OFx1QzcwNCBcdUQ1NkRcdUJBQTlcdUM3N0MgXHVDMjE4IFx1QzVDNlx1QzlDMFx1QjlDQywgJyd7MH0nJ1x1Qzc3NChcdUFDMDApIFx1QkMxQ1x1QUNBQ1x1QjQxOFx1QzVDOFx1QzJCNVx1QjJDOFx1QjJFNC4KLUZhbGxiYWNrQ2hpbGQgPSAnJ2luY2x1ZGUnJyBcdUM2NzhcdUM1RDAgXHVCMkU0XHVCOTc4ICcnaHR0cDovL3d3dy53My5vcmcvMjAwMS9YSW5jbHVkZScnIFx1QjEyNFx1Qzc4NFx1QzJBNFx1RDM5OFx1Qzc3NFx1QzJBNFx1Qzc1OCBcdUM2OTRcdUMxOENcdUIyOTQgJydmYWxsYmFjaycnIFx1QzY5NFx1QzE4Q1x1Qzc1OCBcdUQ1NThcdUM3MDQgXHVENTZEXHVCQUE5XHVDNzdDIFx1QzIxOCBcdUM1QzZcdUM5QzBcdUI5Q0MsICcnezB9JydcdUM3NzQoXHVBQzAwKSBcdUJDMUNcdUFDQUNcdUI0MThcdUM1QzhcdUMyQjVcdUIyQzhcdUIyRTQuCi1IcmVmTWlzc2luZyA9ICdpbmNsdWRlJyBcdUM2OTRcdUMxOENcdUM3NTggJ2hyZWYnIFx1QzE4RFx1QzEzMVx1Qzc3NCBcdUIyMDRcdUI3N0RcdUI0MThcdUM1QzhcdUMyQjVcdUIyQzhcdUIyRTQuCi1SZWN1cnNpdmVJbmNsdWRlID0gXHVDMjFDXHVENjU4IGluY2x1ZGVcdUFDMDAgXHVBQzEwXHVDOUMwXHVCNDE4XHVDNUM4XHVDMkI1XHVCMkM4XHVCMkU0LiAnJ3swfScnIFx1QkIzOFx1QzExQ1x1QUMwMCBcdUM3NzRcdUJCRjggXHVDQzk4XHVCOUFDXHVCNDE4XHVDNUM4XHVDMkI1XHVCMkM4XHVCMkU0LgotSW52YWxpZFBhcnNlVmFsdWUgPSAnJ2luY2x1ZGUnJyBcdUM2OTRcdUMxOENcdUM1RDAgJydwYXJzZScnIFx1QzE4RFx1QzEzMVx1QzVEMCBcdUIzMDBcdUQ1NzQgXHVCRDgwXHVDODAxXHVENTY5XHVENTVDIFx1QUMxMlx1Qzc3NCBcdUM3ODhcdUM3NEM6ICcnezB9JycuCi1YTUxQYXJzZUVycm9yID0gWE1MIFx1RDMwQ1x1Qzc3QyhocmVmPScnezB9JycpXHVDNzU4IFx1QUQ2Q1x1QkIzOFx1Qzc0NCBcdUJEODRcdUMxMURcdUQ1NThcdUI4MjRcdUFDRTAgXHVDMkRDXHVCM0M0XHVENTU4XHVCMjk0IFx1QzkxMSBcdUM2MjRcdUI5NThcdUFDMDAgXHVCQzFDXHVDMEREXHVENTg4XHVDMkI1XHVCMkM4XHVCMkU0LiBcdUM2RDBcdUM3Nzg6IHsxfQotWE1MUmVzb3VyY2VFcnJvciA9IEluY2x1ZGUgXHVDNzkxXHVDNUM1XHVDNzQ0IFx1QzJFNFx1RDMyOFx1RDU1OFx1QzVFQyBmYWxsYmFja1x1QzczQ1x1Qjg1QyBcdUJDRjVcdUM2RDBcdUQ1NThcdUIyOTQgXHVDOTExXHVDNzg1XHVCMkM4XHVCMkU0LiBcdUQzMENcdUM3N0NcdUM3NDQgWE1MKGhyZWY9Jyd7MH0nJylcdUI4NUMgXHVDNzdEXHVCMjk0IFx1QzkxMSBcdUI5QUNcdUMxOENcdUMyQTQgXHVDNjI0XHVCOTU4XHVBQzAwIFx1QkMxQ1x1QzBERFx1RDU4OFx1QzJCNVx1QjJDOFx1QjJFNC4gXHVDNkQwXHVDNzc4OiB7MX0KLVRleHRSZXNvdXJjZUVycm9yID0gSW5jbHVkZSBcdUM3OTFcdUM1QzVcdUM3NDQgXHVDMkU0XHVEMzI4XHVENTU4XHVDNUVDIGZhbGxiYWNrXHVDNzNDXHVCODVDIFx1QkNGNVx1QzZEMFx1RDU1OFx1QjI5NCBcdUM5MTFcdUM3ODVcdUIyQzhcdUIyRTQuIFx1RDMwQ1x1Qzc3Q1x1Qzc0NCBcdUQxNERcdUMyQTRcdUQyQjgoaHJlZj0nJ3swfScnKVx1Qjg1QyBcdUM3N0RcdUIyOTQgXHVDOTExIFx1QjlBQ1x1QzE4Q1x1QzJBNCBcdUM2MjRcdUI5NThcdUFDMDAgXHVCQzFDXHVDMEREXHVENTg4XHVDMkI1XHVCMkM4XHVCMkU0LiBcdUM2RDBcdUM3Nzg6IHsxfQotTk9fWFBvaW50ZXJTY2hlbWEgPSBcdUFFMzBcdUJDRjhcdUM4MDFcdUM3M0NcdUI4NUMgInswfSJcdUM1RDAgXHVCMzAwXHVENTVDIFx1QzJBNFx1RDBBNFx1QjlDOFx1QjI5NCBcdUM5QzBcdUM2RDBcdUI0MThcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0LiB7MH1cdUM1RDAgXHVCMzAwXHVENTc0IFx1QUNFMFx1QzcyMFx1RDU1QyBcdUMyQTRcdUQwQTRcdUI5QzhcdUI5N0MgXHVDODE1XHVDNzU4XHVENTU4XHVDMkVEXHVDMkRDXHVDNjI0LiBodHRwOi8vYXBhY2hlLm9yZy94bWwvcHJvcGVydGllcy94cG9pbnRlci1zY2hlbWFcdUI5N0MgXHVDQzM4XHVDODcwXHVENTU4XHVDMkVEXHVDMkRDXHVDNjI0LgotTk9fU3ViUmVzb3VyY2VJZGVudGlmaWVkID0gezB9IFx1RDNFQ1x1Qzc3OFx1RDEzMFx1QzVEMCBcdUIzMDBcdUQ1NUMgWFBvaW50ZXIgXHVENTA0XHVCODVDXHVDMTM4XHVDMTFDXHVBQzAwIFx1QzJERFx1QkNDNFx1RDU1QyBcdUQ1NThcdUM3MDQgXHVCOUFDXHVDMThDXHVDMkE0XHVBQzAwIFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4KLU5vbkR1cGxpY2F0ZU5vdGF0aW9uID0gXHVDNzc0XHVCOTg0XHVDNzc0ICcnezB9JydcdUM3NzRcdUM5QzBcdUI5Q0MgXHVDOTExXHVCQ0Y1XHVCNDFDIFx1QUM4M1x1QzczQ1x1Qjg1QyBcdUQ2NTVcdUM3NzhcdUI0MThcdUM5QzAgXHVDNTRBXHVDNzQwIFx1RDQ1Q1x1QUUzMFx1QkM5NVx1Qzc3NCBcdUM1RUNcdUI3RUMgXHVBQzFDIFx1QzBBQ1x1QzZBOVx1QjQxOFx1QzVDOFx1QzJCNVx1QjJDOFx1QjJFNC4KLU5vbkR1cGxpY2F0ZVVucGFyc2VkRW50aXR5ID0gXHVDNzc0XHVCOTg0XHVDNzc0ICcnezB9JydcdUM3NzRcdUM5QzBcdUI5Q0MgXHVDOTExXHVCQ0Y1XHVCNDFDIFx1QUM4M1x1QzczQ1x1Qjg1QyBcdUQ2NTVcdUM3NzhcdUI0MThcdUM5QzAgXHVDNTRBXHVDNTU4XHVDNzNDXHVCQTcwIFx1QUQ2Q1x1QkIzOFx1Qzc3NCBcdUJEODRcdUMxMURcdUI0MThcdUM5QzAgXHVDNTRBXHVDNzQwIFx1QzVENFx1RDJGMFx1RDJGMFx1QUMwMCBcdUM1RUNcdUI3RUMgXHVBQzFDIFx1QzBBQ1x1QzZBOVx1QjQxOFx1QzVDOFx1QzJCNVx1QjJDOFx1QjJFNC4KLVhwb2ludGVyTWlzc2luZyA9IGhyZWYgXHVDMThEXHVDMTMxXHVDNzc0IFx1QzVDNlx1Qzc0NCBcdUFDQkRcdUM2QjAgeHBvaW50ZXIgXHVDMThEXHVDMTMxXHVDNzc0IFx1Qzc4OFx1QzVCNFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi1BY2NlcHRNYWxmb3JtZWQgPSAnaW5jbHVkZScgXHVDNjk0XHVDMThDXHVDNzU4ICdhY2NlcHQnIFx1QzE4RFx1QzEzMVx1QUMxMlx1QzVEMFx1QzExQ1x1QjI5NCAjeDIwIC0gI3g3RSBcdUJDOTRcdUM3MDRcdUM1RDAgXHVDMThEXHVENTU4XHVDOUMwIFx1QzU0QVx1QjI5NCBcdUJCMzhcdUM3OTBcdUFDMDAgXHVENUM4XHVDNkE5XHVCNDE4XHVDOUMwIFx1QzU0QVx1QzJCNVx1QjJDOFx1QjJFNC4KLUFjY2VwdExhbmd1YWdlTWFsZm9ybWVkID0gJ2luY2x1ZGUnIFx1QzY5NFx1QzE4Q1x1Qzc1OCAnYWNjZXB0LWxhbmd1YWdlJyBcdUMxOERcdUMxMzFcdUFDMTJcdUM1RDBcdUMxMUNcdUIyOTQgI3gyMCAtICN4N0UgXHVCQzk0XHVDNzA0XHVDNUQwIFx1QzE4RFx1RDU1OFx1QzlDMCBcdUM1NEFcdUIyOTQgXHVCQjM4XHVDNzkwXHVBQzAwIFx1RDVDOFx1QzZBOVx1QjQxOFx1QzlDMCBcdUM1NEFcdUMyQjVcdUIyQzhcdUIyRTQuCi1Sb290RWxlbWVudFJlcXVpcmVkID0gXHVDNjJDXHVCQzE0XHVCOTc4IFx1RDYxNVx1QzJERFx1Qzc1OCBcdUJCMzhcdUMxMUNcdUM1RDBcdUIyOTQgXHVCOEU4XHVEMkI4IFx1QzY5NFx1QzE4Q1x1QUMwMCBcdUQ1NDRcdUM2OTRcdUQ1NjlcdUIyQzhcdUIyRTQuCi1NdWx0aXBsZVJvb3RFbGVtZW50cyA9IFx1QzYyQ1x1QkMxNFx1Qjk3OCBcdUQ2MTVcdUMyRERcdUM3NTggXHVCQjM4XHVDMTFDXHVDNUQwXHVCMjk0IFx1QjhFOFx1RDJCOCBcdUM2OTRcdUMxOENcdUFDMDAgXHVDNUVDXHVCN0VDIFx1QUMxQyBcdUQzRUNcdUQ1NjhcdUI0MThcdUM5QzAgXHVDNTRBXHVDNTQ0XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4KLUNvbnRlbnRJbGxlZ2FsQXRUb3BMZXZlbCA9IFx1Q0Q1Q1x1QzBDMVx1QzcwNCBcdUI4MDhcdUJDQTggXHVDMThDXHVDMkE0IGluZm9zZXRcdUM1RDBcdUMxMUMgXHVCQjM4XHVDMTFDIFx1QzY5NFx1QzE4Q1x1Qjg1QyBcdUIwOThcdUQwQzBcdUIwOThcdUIyOTQgJ2luY2x1ZGUnIFx1QzY5NFx1QzE4Q1x1Qzc1OCBcdUIzMDBcdUNDQjRcdUM1RDBcdUIyOTQgXHVCQjM4XHVDNzkwXHVBQzAwIFx1RDNFQ1x1RDU2OFx1QjQyMCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LgotVW5leHBhbmRlZEVudGl0eVJlZmVyZW5jZUlsbGVnYWwgPSBcdUNENUNcdUMwQzFcdUM3MDQgXHVCODA4XHVCQ0E4IFx1QzE4Q1x1QzJBNCBpbmZvc2V0XHVDNUQwXHVDMTFDIFx1QkIzOFx1QzExQyBcdUM2OTRcdUMxOENcdUI4NUMgXHVCMDk4XHVEMEMwXHVCMDk4XHVCMjk0ICdpbmNsdWRlJyBcdUM2OTRcdUMxOENcdUM3NTggXHVCMzAwXHVDQ0I0XHVDNUQwXHVCMjk0IFx1RDY1NVx1QzdBNVx1QjQxOFx1QzlDMCBcdUM1NEFcdUM3NDAgXHVDNUQ0XHVEMkYwXHVEMkYwIFx1Q0MzOFx1Qzg3MFx1QUMwMCBcdUQzRUNcdUQ1NjhcdUI0MjAgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4KLUhyZWZGcmFnbWVudElkZW50aWZpZXJJbGxlZ2FsID0gXHVCRDgwXHVCRDg0IFx1QzJERFx1QkNDNFx1Qzc5MFx1QjI5NCBcdUMwQUNcdUM2QTlcdUQ1NThcdUM5QzAgXHVDNTRBXHVDNTQ0XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4gJydocmVmJycgXHVDMThEXHVDMTMxXHVBQzEyICcnezB9JydcdUM3NDAoXHVCMjk0KSBcdUQ1QzhcdUM2QTlcdUI0MThcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0LgotSHJlZlN5bnRhY3RpY2FsbHlJbnZhbGlkID0gJydocmVmJycgXHVDMThEXHVDMTMxXHVBQzEyICcnezB9JydcdUM3NzQoXHVBQzAwKSBcdUFENkNcdUJCMzhcdUM4MDFcdUM3M0NcdUI4NUMgXHVCRDgwXHVDODAxXHVENTY5XHVENTY5XHVCMkM4XHVCMkU0LiBcdUM3NzRcdUMyQTRcdUNGMDBcdUM3NzRcdUQ1MDQgXHVBRERDXHVDRTU5XHVDNzQ0IFx1QzgwMVx1QzZBOVx1RDU1QyBcdUQ2QzQgXHVBQzEyXHVDNzc0IFx1QUQ2Q1x1QkIzOFx1QzgwMVx1QzczQ1x1Qjg1QyBcdUM2MkNcdUJDMTRcdUI5NzggVVJJIFx1QjYxMFx1QjI5NCBJUklcdUFDMDAgXHVDNTQ0XHVCMkNDIFx1QUM4M1x1QzczQ1x1Qjg1QyBcdUQ2NTVcdUM3NzhcdUI0MThcdUM1QzhcdUMyQjVcdUIyQzhcdUIyRTQuCi1YUG9pbnRlclN0cmVhbWFiaWxpdHkgPSBcdUMxOENcdUMyQTQgaW5mb3NldFx1Qzc1OCBcdUM3MDRcdUNFNThcdUI5N0MgXHVBQzAwXHVCOUFDXHVEMEE0XHVCMjk0IHhwb2ludGVyXHVBQzAwIFx1QzlDMFx1QzgxNVx1QjQxOFx1QzVDOFx1QzJCNVx1QjJDOFx1QjJFNC4gXHVENTA0XHVCODVDXHVDMTM4XHVDMTFDXHVDNzU4IFx1QzJBNFx1RDJCOFx1QjlBQ1x1QkMwRCBcdUQyQjlcdUMxMzFcdUM3M0NcdUI4NUMgXHVDNzc4XHVENTc0IFx1Qzc3NCBcdUM3MDRcdUNFNThcdUM1RDAgXHVDNTYxXHVDMTM4XHVDMkE0XHVENTYwIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuCi0KLVhQb2ludGVyUmVzb2x1dGlvblVuc3VjY2Vzc2Z1bCA9IFhQb2ludGVyIFx1QkQ4NFx1QzExRFx1Qzc0NCBcdUMyRTRcdUQzMjhcdUQ1ODhcdUMyQjVcdUIyQzhcdUIyRTQuCi0KLSMgTWVzc2FnZXMgZnJvbSBlcnJvbmVvdXMgc2V0LXVwCi1JbmNvbXBhdGlibGVOYW1lc3BhY2VDb250ZXh0ID0gTmFtZXNwYWNlQ29udGV4dFx1Qzc1OCBcdUM3MjBcdUQ2MTVcdUM3NzQgXHVDMEFDXHVDNkE5IFx1QzkxMVx1Qzc3OCBYSW5jbHVkZVx1QzY0MCBcdUQ2MzhcdUQ2NThcdUI0MThcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0LiBYSW5jbHVkZU5hbWVzcGFjZVN1cHBvcnRcdUM3NTggXHVDNzc4XHVDMkE0XHVEMTM0XHVDMkE0XHVDNUVDXHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4KLUV4cGFuZGVkU3lzdGVtSWQgPSBcdUQzRUNcdUQ1NjhcdUI0MUMgXHVCOUFDXHVDMThDXHVDMkE0XHVDNzU4IFx1QzJEQ1x1QzJBNFx1RDE1QyBJRFx1Qjk3QyBcdUQ2NTVcdUM3QTVcdUQ1NjAgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hJbmNsdWRlTWVzc2FnZXNfcHRfQlIucHJvcGVydGllcyBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hJbmNsdWRlTWVzc2FnZXNfcHRfQlIucHJvcGVydGllcwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNTMxZTkxOS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9YSW5jbHVkZU1lc3NhZ2VzX3B0X0JSLnByb3BlcnRpZXMKKysrIC9kZXYvbnVsbApAQCAtMSwzNiArMCwwIEBACi0jIE1lc3NhZ2VzIGZvciBtZXNzYWdlIHJlcG9ydGluZwotQmFkTWVzc2FnZUtleSA9IE5cdTAwRTNvIGZvaSBwb3NzXHUwMEVEdmVsIGVuY29udHJhciBhIG1lbnNhZ2VtIGRlIGVycm8gY29ycmVzcG9uZGVudGUgXHUwMEUwIGNoYXZlIGRhIG1lbnNhZ2VtLgotRm9ybWF0RmFpbGVkID0gT2NvcnJldSB1bSBlcnJvIGludGVybm8gYW8gZm9ybWF0YXIgYSBtZW5zYWdlbSBhIHNlZ3VpcjpcbiAgCi0KLSMgTWVzc2FnZXMgZm9yIGVycm9uZW91cyBpbnB1dAotTm9GYWxsYmFjayA9IEZhbGhhIGVtIHVtICcnaW5jbHVkZScnIGNvbSBocmVmICcnezB9JycgZSBuXHUwMEUzbyBmb2kgZW5jb250cmFkbyBlbGVtZW50byAnJ2ZhbGxiYWNrJycuCi1NdWx0aXBsZUZhbGxiYWNrcyA9IE8gW2NoaWxkcmVuXSBkZSB1bSBlbGVtZW50byAnaW5jbHVkZScgblx1MDBFM28gcG9kZSBjb250ZXIgbWFpcyBkZSB1bSBlbGVtZW50byAnZmFsbGJhY2snLgotRmFsbGJhY2tQYXJlbnQgPSBVbSBlbGVtZW50byAnZmFsbGJhY2snIHF1ZSBmb2kgZW5jb250cmFkbyBuXHUwMEUzbyB0aW5oYSAnaW5jbHVkZScgY29tbyBwYWkuCi1JbmNsdWRlQ2hpbGQgPSBFbGVtZW50b3MgZG8gbmFtZXNwYWNlICcnaHR0cDovL3d3dy53My5vcmcvMjAwMS9YSW5jbHVkZScnLCBkaWZlcmVudGVzIGRlICcnZmFsbGJhY2snJywgblx1MDBFM28gcG9kZW0gc2VyIGZpbGhvcyBkb3MgZWxlbWVudG9zICcnaW5jbHVkZScnLiBObyBlbnRhbnRvLCAnJ3swfScnIGZvaSBlbmNvbnRyYWRvLgotRmFsbGJhY2tDaGlsZCA9IEVsZW1lbnRvcyBkbyBuYW1lc3BhY2UgJydodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hJbmNsdWRlJycsIGRpZmVyZW50ZXMgZGUgJydpbmNsdWRlJycsIG5cdTAwRTNvIHBvZGVtIHNlciBmaWxob3MgZG9zIGVsZW1lbnRvcyAnJ2ZhbGxiYWNrJycuIE5vIGVudGFudG8sICcnezB9JycgZm9pIGVuY29udHJhZG8uCi1IcmVmTWlzc2luZyA9IE8gYXRyaWJ1dG8gJ2hyZWYnIGRlIHVtIGVsZW1lbnRvICdpbmNsdWRlJyBuXHUwMEUzbyBmb2kgZW5jb250cmFkby4KLVJlY3Vyc2l2ZUluY2x1ZGUgPSBJbmNsdXNcdTAwRTNvIHJlY3Vyc2l2YSBkZXRlY3RhZGEuIE8gZG9jdW1lbnRvICcnezB9Jycgalx1MDBFMSBmb2kgcHJvY2Vzc2Fkby4KLUludmFsaWRQYXJzZVZhbHVlID0gVmFsb3IgaW52XHUwMEUxbGlkbyBwYXJhIG8gYXRyaWJ1dG8gJydwYXJzZScnIG5vIGVsZW1lbnRvICcnaW5jbHVkZScnOiAnJ3swfScnLgotWE1MUGFyc2VFcnJvciA9IEVycm8gYW8gdGVudGFyIGZhemVyIHBhcnNlIGRvIGFycXVpdm8gWE1MIChocmVmPScnezB9JycpLiBNb3Rpdm86IHsxfQotWE1MUmVzb3VyY2VFcnJvciA9IEZhbGhhIG5hIG9wZXJhXHUwMEU3XHUwMEUzbyBkZSBpbmNsdXNcdTAwRTNvOyByZXZlcnRlbmRvIHBhcmEgZmFsbGJhY2suIEVycm8gZG8gcmVjdXJzbyBhbyBsZXIgbyBhcnF1aXZvIGNvbW8gWE1MIChocmVmPScnezB9JycpLiBNb3Rpdm86IHsxfQotVGV4dFJlc291cmNlRXJyb3IgPSBGYWxoYSBuYSBvcGVyYVx1MDBFN1x1MDBFM28gZGUgaW5jbHVzXHUwMEUzbzsgcmV2ZXJ0ZW5kbyBwYXJhIGZhbGxiYWNrLiBFcnJvIGRvIHJlY3Vyc28gYW8gbGVyIG8gYXJxdWl2byBjb21vIHRleHRvIChocmVmPScnezB9JycpLiBNb3Rpdm86IHsxfQotTk9fWFBvaW50ZXJTY2hlbWEgPSBQb3IgcGFkclx1MDBFM28sIG8gZXNxdWVtYSBwYXJhICJ7MH0iIG5cdTAwRTNvIFx1MDBFOSBzdXBvcnRhZG8uIERlZmluYSBzZXUgcHJcdTAwRjNwcmlvIGVzcXVlbWEgcGFyYSB7MH0uIENvbnN1bHRlIGh0dHA6Ly9hcGFjaGUub3JnL3htbC9wcm9wZXJ0aWVzL3hwb2ludGVyLXNjaGVtYQotTk9fU3ViUmVzb3VyY2VJZGVudGlmaWVkID0gTmVuaHVtIFN1Yi1yZWN1cnNvIGZvaSBpZGVudGlmaWNhZG8gcGVsbyBQcm9jZXNzYWRvciBYUG9pbnRlciBkbyBQb250ZWlybyB7MH0uCi1Ob25EdXBsaWNhdGVOb3RhdGlvbiA9IEZvcmFtIHVzYWRhcyB2XHUwMEUxcmlhcyBub3RhXHUwMEU3XHUwMEY1ZXMgcXVlIHRpbmhhbSBvIG5vbWUgJyd7MH0nJywgbWFzIG5cdTAwRTNvIGZvcmFtIGRldGVybWluYWRhcyBjb21vIGR1cGxpY2FcdTAwRTdcdTAwRjVlcy4KLU5vbkR1cGxpY2F0ZVVucGFyc2VkRW50aXR5ID0gRm9yYW0gdXNhZGFzIHZcdTAwRTFyaWFzIGVudGlkYWRlcyBxdWUgdGluaGFtIG8gbm9tZSAnJ3swfScnLCBtYXMgblx1MDBFM28gZm9yYW0gZGV0ZXJtaW5hZGFzIGNvbW8gZHVwbGljYVx1MDBFN1x1MDBGNWVzLgotWHBvaW50ZXJNaXNzaW5nID0gbyBhdHJpYnV0byB4cG9pbnRlciBkZXZlclx1MDBFMSBlc3RhciBwcmVzZW50ZSBxdWFuZG8gbyBhdHJpYnV0byBocmVmIGVzdGl2ZXIgYXVzZW50ZS4KLUFjY2VwdE1hbGZvcm1lZCA9IE5cdTAwRTNvIHNcdTAwRTNvIHBlcm1pdGlkb3MgY2FyYWN0ZXJlcyBmb3JhIGRhIGZhaXhhICN4MjAgYXRcdTAwRTkgI3g3RSBubyB2YWxvciBkbyBhdHJpYnV0byAnYWNjZXB0JyBkZSB1bSBlbGVtZW50byAnaW5jbHVkZScuCi1BY2NlcHRMYW5ndWFnZU1hbGZvcm1lZCA9IE5cdTAwRTNvIHNcdTAwRTNvIHBlcm1pdGlkb3MgY2FyYWN0ZXJlcyBmb3JhIGRhIGZhaXhhICN4MjAgYXRcdTAwRTkgI3g3RSBubyB2YWxvciBkbyBhdHJpYnV0byAnYWNjZXB0LWxhbmd1YWdlJyBkZSB1bSBlbGVtZW50byAnaW5jbHVkZScuCi1Sb290RWxlbWVudFJlcXVpcmVkID0gVW0gZG9jdW1lbnRvIGNvcnJldG8gcmVxdWVyIHVtIGVsZW1lbnRvLXJhaXouCi1NdWx0aXBsZVJvb3RFbGVtZW50cyA9IFVtIGRvY3VtZW50byBjb3JyZXRvIG5cdTAwRTNvIGRldmUgY29udGVyIHZcdTAwRTFyaW9zIGVsZW1lbnRvcy1yYWl6LgotQ29udGVudElsbGVnYWxBdFRvcExldmVsID0gQSBzdWJzdGl0dWlcdTAwRTdcdTAwRTNvIGRlIHVtIGVsZW1lbnRvICdpbmNsdWRlJyBxdWUgYXBhcmVjZSBjb21vIG8gZWxlbWVudG8gZG8gZG9jdW1lbnRvIG5vIGNvbmp1bnRvIGRlIGluZm9ybWFcdTAwRTdcdTAwRjVlcyBkZSBvcmlnZW0gZGUgblx1MDBFRHZlbCBzdXBlcmlvciBuXHUwMEUzbyBwb2RlIGNvbnRlciBjYXJhY3RlcmVzLgotVW5leHBhbmRlZEVudGl0eVJlZmVyZW5jZUlsbGVnYWwgPSBBIHN1YnN0aXR1aVx1MDBFN1x1MDBFM28gZGUgdW0gZWxlbWVudG8gJ2luY2x1ZGUnIHF1ZSBhcGFyZWNlIGNvbW8gbyBlbGVtZW50byBkbyBkb2N1bWVudG8gbm8gY29uanVudG8gZGUgaW5mb3JtYVx1MDBFN1x1MDBGNWVzIGRlIG9yaWdlbSBkZSBuXHUwMEVEdmVsIHN1cGVyaW9yIG5cdTAwRTNvIHBvZGUgY29udGVyIHJlZmVyXHUwMEVBbmNpYXMgZGEgZW50aWRhZGUgblx1MDBFM28gZXhwYW5kaWRhcy4KLUhyZWZGcmFnbWVudElkZW50aWZpZXJJbGxlZ2FsID0gT3MgaWRlbnRpZmljYWRvcmVzIGRlIGZyYWdtZW50byBuXHUwMEUzbyBkZXZlbSBzZXIgdXNhZG9zLiBPIHZhbG9yIGRvIGF0cmlidXRvICcnaHJlZicnICJ7MH0nJyBuXHUwMEUzbyBcdTAwRTkgcGVybWl0aWRvLgotSHJlZlN5bnRhY3RpY2FsbHlJbnZhbGlkID0gbyB2YWxvciBkbyBhdHJpYnV0byAnJ2hyZWYnJyAnJ3swfScnIFx1MDBFOSBpbnZcdTAwRTFsaWRvIHNpbnRhdGljYW1lbnRlLiBBcFx1MDBGM3MgYXBsaWNhciBhcyByZWdyYXMgZGUgZXNjYXBlLCBvIHZhbG9yIG5cdTAwRTNvIFx1MDBFOSB1bSBVUkkgb3UgSVJJIGNvcnJldG8uCi1YUG9pbnRlclN0cmVhbWFiaWxpdHkgPSBGb2kgZXNwZWNpZmljYWRvIHVtIHhwb2ludGVyIHF1ZSBhcG9udGEgcGFyYSB1bWEgbG9jYWxpemFcdTAwRTdcdTAwRTNvIG5vIGNvbmp1bnRvIGRlIGluZm9ybWFcdTAwRTdcdTAwRjVlcyBkZSBvcmlnZW0uIEVzdGEgbG9jYWxpemFcdTAwRTdcdTAwRTNvIG5cdTAwRTNvIHBvZGUgc2VyIGFjZXNzYWRhIGVtIGRlY29yclx1MDBFQW5jaWEgZGEgbmF0dXJlemEgZG8gZmx1eG8gZG8gcHJvY2Vzc2Fkb3IuCi0KLVhQb2ludGVyUmVzb2x1dGlvblVuc3VjY2Vzc2Z1bCA9IFJlc29sdVx1MDBFN1x1MDBFM28gZGUgWFBvaW50ZXIgbWFsc3VjZWRpZGEuCi0KLSMgTWVzc2FnZXMgZnJvbSBlcnJvbmVvdXMgc2V0LXVwCi1JbmNvbXBhdGlibGVOYW1lc3BhY2VDb250ZXh0ID0gTyB0aXBvIGRlIE5hbWVzcGFjZUNvbnRleHQgXHUwMEU5IGluY29tcGF0XHUwMEVEdmVsIGFvIHVzYXIgWEluY2x1ZGUuIERldmUgc2VyIHVtYSBpbnN0XHUwMEUybmNpYSBkZSBYSW5jbHVkZU5hbWVzcGFjZVN1cHBvcnQKLUV4cGFuZGVkU3lzdGVtSWQgPSBOXHUwMEUzbyBmb2kgcG9zc1x1MDBFRHZlbCBleHBhbmRpciBvIGlkIGRvIHNpc3RlbWEgZG8gcmVjdXJzbyBpbmNsdVx1MDBFRGRvCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9YSW5jbHVkZU1lc3NhZ2VzX3N2LnByb3BlcnRpZXMgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9YSW5jbHVkZU1lc3NhZ2VzX3N2LnByb3BlcnRpZXMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGQ3OWViYmQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWEluY2x1ZGVNZXNzYWdlc19zdi5wcm9wZXJ0aWVzCisrKyAvZGV2L251bGwKQEAgLTEsMzYgKzAsMCBAQAotIyBNZXNzYWdlcyBmb3IgbWVzc2FnZSByZXBvcnRpbmcKLUJhZE1lc3NhZ2VLZXkgPSBIaXR0YXIgaW50ZSBmZWxtZWRkZWxhbmRldCBzb20gbW90c3ZhcmFyIG1lZGRlbGFuZGVueWNrZWxuLgotRm9ybWF0RmFpbGVkID0gRXR0IGludGVybnQgZmVsIGludHJcdTAwRTRmZmFkZSB2aWQgZm9ybWF0ZXJpbmcgYXYgZlx1MDBGNmxqYW5kZSBtZWRkZWxhbmRlOlxuICAKLQotIyBNZXNzYWdlcyBmb3IgZXJyb25lb3VzIGlucHV0Ci1Ob0ZhbGxiYWNrID0gRXR0ICcnaW5jbHVkZScnIG1lZCBocmVmICcnezB9JycgdXRmXHUwMEY2cmRlcyBpbnRlLCBoaXR0YWRlIGluZ2V0IFx1MDBFNXRlcnNrYXBuaW5nc2VsZW1lbnQgKCcnZmFsbGJhY2snJykuCi1NdWx0aXBsZUZhbGxiYWNrcyA9IFt1bmRlcm9yZG5hZGVdIGkgZXR0ICdpbmNsdWRlJy1lbGVtZW50IGZcdTAwRTVyIGludGUgaW5uZWhcdTAwRTVsbGEgZmxlciBcdTAwRTRuIGV0dCAnZmFsbGJhY2snLWVsZW1lbnQuCi1GYWxsYmFja1BhcmVudCA9IEV0dCAnZmFsbGJhY2snLWVsZW1lbnQgaGl0dGFkZXMgdXRhbiBuXHUwMEU1Z290ICdpbmNsdWRlJyBzb20gXHUwMEY2dmVyb3JkbmF0IGVsZW1lbnQuCi1JbmNsdWRlQ2hpbGQgPSBFbGVtZW50IGZyXHUwMEU1biBuYW1ucnltZCAnJ2h0dHA6Ly93d3cudzMub3JnLzIwMDEvWEluY2x1ZGUnJywgdXRcdTAwRjZ2ZXIgJydmYWxsYmFjaycnLCBcdTAwRTRyIGludGUgdGlsbFx1MDBFNXRuYSBzb20gdW5kZXJvcmRuYWRlIGkgJydpbmNsdWRlJyctZWxlbWVudC4gSGl0dGFkZSBkXHUwMEU0cmVtb3QgJyd7MH0nJy4KLUZhbGxiYWNrQ2hpbGQgPSBFbGVtZW50IGZyXHUwMEU1biBuYW1ucnltZCAnJ2h0dHA6Ly93d3cudzMub3JnLzIwMDEvWEluY2x1ZGUnJywgdXRcdTAwRjZ2ZXIgJydpbmNsdWRlJycsIFx1MDBFNHIgaW50ZSB0aWxsXHUwMEU1dG5hIHNvbSB1bmRlcm9yZG5hZGUgaSAnJ2ZhbGxiYWNrJyctZWxlbWVudC4gSGl0dGFkZSBkXHUwMEU0cmVtb3QgJyd7MH0nJy4KLUhyZWZNaXNzaW5nID0gRXR0ICdocmVmJy1hdHRyaWJ1dCBpIGV0dCAnaW5jbHVkZSctZWxlbWVudCBzYWtuYXMuCi1SZWN1cnNpdmVJbmNsdWRlID0gUmVrdXJzaXYgaW5rbHVkZXJpbmcgdXBwdFx1MDBFNGNrdGVzLiBEb2t1bWVudGV0ICcnezB9JycgaGFyIHJlZGFuIGJlYXJiZXRhdHMuCi1JbnZhbGlkUGFyc2VWYWx1ZSA9IE9naWx0aWd0IHZcdTAwRTRyZGUgZlx1MDBGNnIgJydwYXJzZScnLWF0dHJpYnV0IGkgJydpbmNsdWRlJyctZWxlbWVudDogJyd7MH0nJy4KLVhNTFBhcnNlRXJyb3IgPSBGZWwgdmlkIGZcdTAwRjZyc1x1MDBGNmsgYXR0IHRvbGthIFhNTC1maWwgKGhyZWY9Jyd7MH0nJykuIE9yc2FrOiB7MX0KLVhNTFJlc291cmNlRXJyb3IgPSBJbmtsdWRlcmluZ3NcdTAwRTV0Z1x1MDBFNHJkZW4gdXRmXHUwMEY2cmRlcyBpbnRlLCBcdTAwRTV0ZXJzdFx1MDBFNGxsZXIgZ2Vub20gYXR0IFx1MDBFNXRlcnNrYXBhLiBSZXN1cnNmZWwgdmlkIGxcdTAwRTRzbmluZyBhdiBmaWwgc29tIFhNTCAoaHJlZj0nJ3swfScnKS4gT3JzYWs6IHsxfQotVGV4dFJlc291cmNlRXJyb3IgPSBJbmtsdWRlcmluZ3NcdTAwRTV0Z1x1MDBFNHJkZW4gdXRmXHUwMEY2cmRlcyBpbnRlLCBcdTAwRTV0ZXJzdFx1MDBFNGxsZXIgZ2Vub20gYXR0IFx1MDBFNXRlcnNrYXBhLiBSZXN1cnNmZWwgdmlkIGxcdTAwRTRzbmluZyBhdiBmaWwgc29tIHRleHQgKGhyZWY9Jyd7MH0nJykuIE9yc2FrOiB7MX0KLU5PX1hQb2ludGVyU2NoZW1hID0gU2NoZW1hIGZcdTAwRjZyICJ7MH0iIHN0XHUwMEY2ZHMgaW50ZSBzb20gc3RhbmRhcmQuIERlZmluaWVyYSBldHQgZWdldCBzY2hlbWEgZlx1MDBGNnIgezB9LlNlIGh0dHA6Ly9hcGFjaGUub3JnL3htbC9wcm9wZXJ0aWVzL3hwb2ludGVyLXNjaGVtYQotTk9fU3ViUmVzb3VyY2VJZGVudGlmaWVkID0gSW5nZW4gU3VicmVzb3VyY2UgaGFyIGlkZW50aWZpZXJhdHMgYXYgWFBvaW50ZXItcHJvY2Vzc29ybiBmXHUwMEY2ciBwZWthcmUgezB9LgotTm9uRHVwbGljYXRlTm90YXRpb24gPSBGbGVyYSBub3RlcmluZ2FyIGFudlx1MDBFNG5kcyBtZWQgbmFtbmV0ICcnezB9JycsIG1lbiBzb20gaW50ZSBmYXN0c3RcdTAwRTRsbHMgc29tIGR1YmJsZXR0ZXIuCi1Ob25EdXBsaWNhdGVVbnBhcnNlZEVudGl0eSA9IEZsZXJhIG90b2xrYWRlIGVuaGV0ZXIgYW52XHUwMEU0bmRzIG1lZCBuYW1uZXQgJyd7MH0nJywgbWVuIHNvbSBpbnRlIGZhc3RzdFx1MDBFNGxscyBzb20gZHViYmxldHRlci4KLVhwb2ludGVyTWlzc2luZyA9IE9tIGhyZWYtYXR0cmlidXQgc2FrbmFzIG1cdTAwRTVzdGUgZGV0IGZpbm5hcyBldHQgeHBvaW50ZXItYXR0cmlidXQuCi1BY2NlcHRNYWxmb3JtZWQgPSBUZWNrZW4gdXRhbmZcdTAwRjZyIGludGVydmFsbGV0ICN4MjAgdGlsbCAjeDdFIHRpbGxcdTAwRTV0cyBpbnRlIGkgdlx1MDBFNHJkZXQgZlx1MDBGNnIgJ2FjY2VwdCctYXR0cmlidXRldCBpICdpbmNsdWRlJy1lbGVtZW50LgotQWNjZXB0TGFuZ3VhZ2VNYWxmb3JtZWQgPSBUZWNrZW4gdXRhbmZcdTAwRjZyIGludGVydmFsbGV0ICN4MjAgdGlsbCAjeDdFIHRpbGxcdTAwRTV0cyBpbnRlIGkgdlx1MDBFNHJkZXQgZlx1MDBGNnIgJ2FjY2VwdC1sYW5ndWFnZSctYXR0cmlidXRldCBpICdpbmNsdWRlJy1lbGVtZW50LgotUm9vdEVsZW1lbnRSZXF1aXJlZCA9IEV0dCB2XHUwMEU0bGZvcm11bGVyYXQgZG9rdW1lbnQga3JcdTAwRTR2ZXIgZXR0IHJvdGVsZW1lbnQuCi1NdWx0aXBsZVJvb3RFbGVtZW50cyA9IEV0dCB2XHUwMEU0bGZvcm11bGVyYXQgZG9rdW1lbnQgZlx1MDBFNXIgaW50ZSBpbm5laFx1MDBFNWxsYSBmbGVyYSByb3RlbGVtZW50LgotQ29udGVudElsbGVnYWxBdFRvcExldmVsID0gRXJzXHUwMEU0dHRuaW5nZW4gYXYgZXR0ICdpbmNsdWRlJy1lbGVtZW50IHNvbSBmXHUwMEY2cmVrb21tZXIgc29tIGRva3VtZW50ZWxlbWVudCBpIGtcdTAwRTRsbGFucyBpbmZvcm1hdGlvbnN1cHBzXHUwMEU0dHRuaW5nIHBcdTAwRTUgXHUwMEY2dmVyc3RhIG5pdlx1MDBFNW4gZlx1MDBFNXIgaW50ZSBpbm5laFx1MDBFNWxsYSB0ZWNrZW4uCi1VbmV4cGFuZGVkRW50aXR5UmVmZXJlbmNlSWxsZWdhbCA9IEVyc1x1MDBFNHR0bmluZ2VuIGF2IGV0dCAnaW5jbHVkZSctZWxlbWVudCBzb20gZlx1MDBGNnJla29tbWVyIHNvbSBkb2t1bWVudGVsZW1lbnQgaSBrXHUwMEU0bGxhbnMgaW5mb3JtYXRpb25zdXBwc1x1MDBFNHR0bmluZyBwXHUwMEU1IFx1MDBGNnZlcnN0YSBuaXZcdTAwRTVuIGZcdTAwRTVyIGludGUgaW5uZWhcdTAwRTVsbGEgdXRcdTAwRjZrYWRlIGVuaGV0c3JlZmVyZW5zZXIuCi1IcmVmRnJhZ21lbnRJZGVudGlmaWVySWxsZWdhbCA9IEZyYWdtZW50aWRlbnRpZmllcmFyZSBmXHUwMEU1ciBpbnRlIGFudlx1MDBFNG5kYXMuICcnaHJlZicnLWF0dHJpYnV0dlx1MDBFNHJkZXQgJyd7MH0nJyBcdTAwRTRyIGludGUgdGlsbFx1MDBFNXRldC4KLUhyZWZTeW50YWN0aWNhbGx5SW52YWxpZCA9ICcnaHJlZicnLWF0dHJpYnV0dlx1MDBFNHJkZXQgJyd7MH0nJyBcdTAwRTRyIHN5bnRha3Rpc2t0IG9naWx0aWd0LiBFZnRlciB0aWxsXHUwMEU0bXBuaW5nIGF2IGF2YnJvdHRzcmVnbGVyIGhhciB2XHUwMEU0cmRldCB2YXJrZW4gc3ludGFrdGlza3Qga29ycmVrdCBVUkkgZWxsZXIgSVJJLgotWFBvaW50ZXJTdHJlYW1hYmlsaXR5ID0gRW4geHBvaW50ZXIgaGFyIGFuZ2V0dHMgc29tIHBla2FyIHRpbGwgZW4gcGxhdHMgaSBrXHUwMEU0bGxhbnMgaW5mb3JtYXRpb25zdXBwc1x1MDBFNHR0bmluZy4gRGV0IGZpbm5zIGluZ2VuIFx1MDBFNXRrb21zdCB0aWxsIGRlbm5hIHBsYXRzIHBcdTAwRTUgZ3J1bmQgYXYgcHJvY2Vzc29ybnMgc3RyXHUwMEY2bW5pbmdzbWV0b2QuCi0KLVhQb2ludGVyUmVzb2x1dGlvblVuc3VjY2Vzc2Z1bCA9IFhQb2ludGVyLW1hdGNobmluZ2VuIHV0Zlx1MDBGNnJkZXMgaW50ZS4KLQotIyBNZXNzYWdlcyBmcm9tIGVycm9uZW91cyBzZXQtdXAKLUluY29tcGF0aWJsZU5hbWVzcGFjZUNvbnRleHQgPSBUeXAgYXYgTmFtZXNwYWNlQ29udGV4dCBcdTAwRTRyIGlua29tcGF0aWJlbCBtZWQgWEluY2x1ZGU7IGRldCBrclx1MDBFNHZzIGVuIGluc3RhbnMgYXYgWEluY2x1ZGVOYW1lc3BhY2VTdXBwb3J0Ci1FeHBhbmRlZFN5c3RlbUlkID0gS3VuZGUgaW50ZSB1dFx1MDBGNmthIHN5c3RlbS1JRDp0IGZcdTAwRjZyIGlua2x1ZGVyYWQgcmVzdXJzCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9YSW5jbHVkZU1lc3NhZ2VzX3poX0NOLnByb3BlcnRpZXMgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9YSW5jbHVkZU1lc3NhZ2VzX3poX0NOLnByb3BlcnRpZXMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDhlMzJhNzMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWEluY2x1ZGVNZXNzYWdlc196aF9DTi5wcm9wZXJ0aWVzCisrKyAvZGV2L251bGwKQEAgLTEsMzYgKzAsMCBAQAotIyBNZXNzYWdlcyBmb3IgbWVzc2FnZSByZXBvcnRpbmcKLUJhZE1lc3NhZ2VLZXkgPSBcdTYyN0VcdTRFMERcdTUyMzBcdTRFMEVcdTZEODhcdTYwNkZcdTUxNzNcdTk1MkVcdTVCNTdcdTVCRjlcdTVFOTRcdTc2ODRcdTk1MTlcdThCRUZcdTZEODhcdTYwNkZcdTMwMDIKLUZvcm1hdEZhaWxlZCA9IFx1OEJCRVx1N0Y2RVx1NEVFNVx1NEUwQlx1NkQ4OFx1NjA2Rlx1NzY4NFx1NjgzQ1x1NUYwRlx1NjVGNlx1NTFGQVx1NzNCMFx1NTE4NVx1OTBFOFx1OTUxOVx1OEJFRjpcbiAgCi0KLSMgTWVzc2FnZXMgZm9yIGVycm9uZW91cyBpbnB1dAotTm9GYWxsYmFjayA9IFx1NUUyNlx1NjcwOSBocmVmICcnezB9JycgXHU3Njg0ICcnaW5jbHVkZScnIFx1NTkzMVx1OEQyNSwgXHU1RTc2XHU0RTE0XHU2MjdFXHU0RTBEXHU1MjMwICcnZmFsbGJhY2snJyBcdTUxNDNcdTdEMjBcdTMwMDIKLU11bHRpcGxlRmFsbGJhY2tzID0gJ2luY2x1ZGUnIFx1NTE0M1x1N0QyMFx1NzY4NCBbY2hpbGRyZW5dIFx1NEUwRFx1ODBGRFx1NTMwNVx1NTQyQlx1NTkxQVx1NEUyQSAnZmFsbGJhY2snIFx1NTE0M1x1N0QyMFx1MzAwMgotRmFsbGJhY2tQYXJlbnQgPSBcdTYyN0VcdTUyMzBcdTY3MkFcdTVDMDYgJ2luY2x1ZGUnIFx1NEY1Q1x1NEUzQVx1NzIzNlx1N0VBN1x1NzY4NCAnZmFsbGJhY2snIFx1NTE0M1x1N0QyMFx1MzAwMgotSW5jbHVkZUNoaWxkID0gXHU0RTBEXHU1MTQxXHU4QkI4XHU1QzA2XHU1NDBEXHU3OUYwXHU3QTdBXHU5NUY0ICcnaHR0cDovL3d3dy53My5vcmcvMjAwMS9YSW5jbHVkZScnIChcdTgwMENcdTk3NUUgJydmYWxsYmFjaycnKSBcdTRFMkRcdTc2ODRcdTUxNDNcdTdEMjBcdTRGNUNcdTRFM0EgJydpbmNsdWRlJycgXHU1MTQzXHU3RDIwXHU3Njg0XHU1QjUwXHU3RUE3XHUzMDAyXHU0RjQ2XHU2NjJGLCBcdTYyN0VcdTUyMzAgJyd7MH0nJ1x1MzAwMgotRmFsbGJhY2tDaGlsZCA9IFx1NEUwRFx1NTE0MVx1OEJCOFx1NUMwNlx1NTQwRFx1NzlGMFx1N0E3QVx1OTVGNCAnJ2h0dHA6Ly93d3cudzMub3JnLzIwMDEvWEluY2x1ZGUnJyAoXHU4MDBDXHU5NzVFICcnaW5jbHVkZScnKSBcdTRFMkRcdTc2ODRcdTUxNDNcdTdEMjBcdTRGNUNcdTRFM0EgJydmYWxsYmFjaycnIFx1NTE0M1x1N0QyMFx1NzY4NFx1NUI1MFx1N0VBN1x1MzAwMlx1NEY0Nlx1NjYyRiwgXHU2MjdFXHU1MjMwICcnezB9JydcdTMwMDIKLUhyZWZNaXNzaW5nID0gXHU3RjNBXHU1QzExICdpbmNsdWRlJyBcdTUxNDNcdTdEMjBcdTc2ODQgJ2hyZWYnIFx1NUM1RVx1NjAyN1x1MzAwMgotUmVjdXJzaXZlSW5jbHVkZSA9IFx1NjhDMFx1NkQ0Qlx1NTIzMFx1OTAxMlx1NUY1MiBpbmNsdWRlXHUzMDAyXHU1REYyXHU1OTA0XHU3NDA2XHU2NTg3XHU2ODYzICcnezB9JydcdTMwMDIKLUludmFsaWRQYXJzZVZhbHVlID0gJydpbmNsdWRlJycgXHU1MTQzXHU3RDIwXHU3Njg0ICcncGFyc2UnJyBcdTVDNUVcdTYwMjdcdTc2ODRcdTUwM0NcdTY1RTBcdTY1NDg6ICcnezB9JydcdTMwMDIKLVhNTFBhcnNlRXJyb3IgPSBcdTVDMURcdThCRDVcdTg5RTNcdTY3OTAgWE1MIFx1NjU4N1x1NEVGNiAoaHJlZj0nJ3swfScnKSBcdTY1RjZcdTUxRkFcdTk1MTlcdTMwMDJcdTUzOUZcdTU2RTA6IHsxfQotWE1MUmVzb3VyY2VFcnJvciA9IEluY2x1ZGUgXHU2NENEXHU0RjVDXHU1OTMxXHU4RDI1LCBcdTVFNzZcdThGRDhcdTUzOUZcdTRFM0EgZmFsbGJhY2tcdTMwMDJcdTRFRTUgWE1MIChocmVmPScnezB9JycpIFx1NjgzQ1x1NUYwRlx1OEJGQlx1NTNENlx1NjU4N1x1NEVGNlx1NjVGNlx1NTFGQVx1NzNCMFx1OEQ0NFx1NkU5MFx1OTUxOVx1OEJFRlx1MzAwMlx1NTM5Rlx1NTZFMDogezF9Ci1UZXh0UmVzb3VyY2VFcnJvciA9IEluY2x1ZGUgXHU2NENEXHU0RjVDXHU1OTMxXHU4RDI1LCBcdTVFNzZcdThGRDhcdTUzOUZcdTRFM0EgZmFsbGJhY2tcdTMwMDJcdTRFRTVcdTY1ODdcdTY3MkMgKGhyZWY9Jyd7MH0nJykgXHU2ODNDXHU1RjBGXHU4QkZCXHU1M0Q2XHU2NTg3XHU0RUY2XHU2NUY2XHU1MUZBXHU3M0IwXHU4RDQ0XHU2RTkwXHU5NTE5XHU4QkVGXHUzMDAyXHU1MzlGXHU1NkUwOiB7MX0KLU5PX1hQb2ludGVyU2NoZW1hID0gXHU5RUQ4XHU4QkE0XHU2MEM1XHU1MUI1XHU0RTBCLCBcdTRFMERcdTY1MkZcdTYzMDEgInswfSIgXHU3Njg0XHU2NUI5XHU2ODQ4XHUzMDAyXHU4QkY3XHU0RTNBezB9XHU1QjlBXHU0RTQ5XHU2MEE4XHU4MUVBXHU1REYxXHU3Njg0XHU2NUI5XHU2ODQ4XHUzMDAyXHU4QkY3XHU4QkJGXHU5NUVFIGh0dHA6Ly9hcGFjaGUub3JnL3htbC9wcm9wZXJ0aWVzL3hwb2ludGVyLXNjaGVtYQotTk9fU3ViUmVzb3VyY2VJZGVudGlmaWVkID0gXHU2NUUwXHU2Q0Q1XHU5MDFBXHU4RkM3IFhQb2ludGVyIFByb2Nlc3NvciBmb3IgUG9pbnRlciB7MH0gXHU4QkM2XHU1MjJCIFN1YnJlc291cmNlXHUzMDAyCi1Ob25EdXBsaWNhdGVOb3RhdGlvbiA9IFx1NEY3Rlx1NzUyOFx1NEU4Nlx1NTkxQVx1NEUyQVx1NTQwRFx1NEUzQSAnJ3swfScnIFx1NzY4NFx1OEJCMFx1NTNGNywgXHU0RjQ2XHU2NzJBXHU1QzA2XHU4RkQ5XHU0RTlCXHU4QkIwXHU1M0Y3XHU3ODZFXHU1QjlBXHU0RTNBXHU5MUNEXHU1OTBEXHU5ODc5XHUzMDAyCi1Ob25EdXBsaWNhdGVVbnBhcnNlZEVudGl0eSA9IFx1NEY3Rlx1NzUyOFx1NEU4Nlx1NTkxQVx1NEUyQVx1NTQwRFx1NEUzQSAnJ3swfScnIFx1NzY4NFx1NjcyQVx1ODlFM1x1Njc5MFx1NUI5RVx1NEY1MywgXHU0RjQ2XHU2NzJBXHU1QzA2XHU4RkQ5XHU0RTlCXHU1QjlFXHU0RjUzXHU3ODZFXHU1QjlBXHU0RTNBXHU5MUNEXHU1OTBEXHU5ODc5XHUzMDAyCi1YcG9pbnRlck1pc3NpbmcgPSBcdTdGM0FcdTVDMTEgaHJlZiBcdTVDNUVcdTYwMjdcdTY1RjYsIFx1NUZDNVx1OTg3Qlx1NUI1OFx1NTcyOCB4cG9pbnRlciBcdTVDNUVcdTYwMjdcdTMwMDIKLUFjY2VwdE1hbGZvcm1lZCA9ICdpbmNsdWRlJyBcdTUxNDNcdTdEMjBcdTc2ODQgJ2FjY2VwdCcgXHU1QzVFXHU2MDI3XHU3Njg0XHU1MDNDXHU0RTJEXHU0RTBEXHU1MTQxXHU4QkI4XHU0RjdGXHU3NTI4XHU4MzAzXHU1NkY0ICN4MjAgXHU4MUYzICN4N0UgXHU0RUU1XHU1OTE2XHU3Njg0XHU1QjU3XHU3QjI2XHUzMDAyCi1BY2NlcHRMYW5ndWFnZU1hbGZvcm1lZCA9ICdpbmNsdWRlJyBcdTUxNDNcdTdEMjBcdTc2ODQgJ2FjY2VwdC1sYW5ndWFnZScgXHU1QzVFXHU2MDI3XHU3Njg0XHU1MDNDXHU0RTJEXHU0RTBEXHU1MTQxXHU4QkI4XHU0RjdGXHU3NTI4XHU4MzAzXHU1NkY0ICN4MjAgXHU4MUYzICN4N0UgXHU0RUU1XHU1OTE2XHU3Njg0XHU1QjU3XHU3QjI2XHUzMDAyCi1Sb290RWxlbWVudFJlcXVpcmVkID0gXHU2ODNDXHU1RjBGXHU2QjYzXHU3ODZFXHU3Njg0XHU2NTg3XHU2ODYzXHU5NzAwXHU4OTgxXHU0RTAwXHU0RTJBXHU2ODM5XHU1MTQzXHU3RDIwXHUzMDAyCi1NdWx0aXBsZVJvb3RFbGVtZW50cyA9IFx1NjgzQ1x1NUYwRlx1NkI2M1x1Nzg2RVx1NzY4NFx1NjU4N1x1Njg2M1x1NEUwRFx1ODBGRFx1NTMwNVx1NTQyQlx1NTkxQVx1NEUyQVx1NjgzOVx1NTE0M1x1N0QyMFx1MzAwMgotQ29udGVudElsbGVnYWxBdFRvcExldmVsID0gXHU1NzI4XHU5ODc2XHU3RUE3XHU2RTkwXHU0RkUxXHU2MDZGXHU5NkM2XHU0RTJEXHU2NjNFXHU3OTNBXHU0RTNBXHU2NTg3XHU2ODYzXHU1MTQzXHU3RDIwXHU3Njg0ICdpbmNsdWRlJyBcdTUxNDNcdTdEMjBcdTc2ODRcdTY2RkZcdTRFRTNcdTk4NzlcdTRFMERcdTgwRkRcdTUzMDVcdTU0MkJcdTVCNTdcdTdCMjZcdTMwMDIKLVVuZXhwYW5kZWRFbnRpdHlSZWZlcmVuY2VJbGxlZ2FsID0gXHU1NzI4XHU5ODc2XHU3RUE3XHU2RTkwXHU0RkUxXHU2MDZGXHU5NkM2XHU0RTJEXHU2NjNFXHU3OTNBXHU0RTNBXHU2NTg3XHU2ODYzXHU1MTQzXHU3RDIwXHU3Njg0ICdpbmNsdWRlJyBcdTUxNDNcdTdEMjBcdTc2ODRcdTY2RkZcdTRFRTNcdTk4NzlcdTRFMERcdTgwRkRcdTUzMDVcdTU0MkJcdTY3MkFcdTVDNTVcdTVGMDBcdTc2ODRcdTVCOUVcdTRGNTNcdTVGMTVcdTc1MjhcdTMwMDIKLUhyZWZGcmFnbWVudElkZW50aWZpZXJJbGxlZ2FsID0gXHU0RTBEXHU4MEZEXHU0RjdGXHU3NTI4XHU3MjQ3XHU2QkI1XHU2ODA3XHU4QkM2XHU3QjI2XHUzMDAyXHU0RTBEXHU1MTQxXHU4QkI4XHU0RjdGXHU3NTI4ICcnaHJlZicnIFx1NUM1RVx1NjAyN1x1NTAzQyAnJ3swfScnXHUzMDAyCi1IcmVmU3ludGFjdGljYWxseUludmFsaWQgPSAnJ2hyZWYnJyBcdTVDNUVcdTYwMjdcdTUwM0MgJyd7MH0nJyBcdTc2ODRcdThCRURcdTZDRDVcdTY1RTBcdTY1NDhcdTMwMDJcdTVFOTRcdTc1MjhcdThGNkNcdTRFNDlcdTg5QzRcdTUyMTlcdTU0MEUsIFx1OEJFNVx1NTAzQ1x1NEUwRFx1NjYyRlx1OEJFRFx1NkNENVx1NkI2M1x1Nzg2RVx1NzY4NCBVUkkgXHU2MjE2IElSSVx1MzAwMgotWFBvaW50ZXJTdHJlYW1hYmlsaXR5ID0gXHU1REYyXHU2MzA3XHU1QjlBXHU2MzA3XHU1NDExXHU2RTkwXHU0RkUxXHU2MDZGXHU5NkM2XHU0RTJEXHU3Njg0XHU0RjREXHU3RjZFXHU3Njg0IHhwb2ludGVyXHUzMDAyXHU3NTMxXHU0RThFXHU1OTA0XHU3NDA2XHU3QTBCXHU1RThGXHU3Njg0XHU2RDQxXHU1RjBGXHU2MDI3XHU4RDI4LCBcdTY1RTBcdTZDRDVcdThCQkZcdTk1RUVcdTZCNjRcdTRGNERcdTdGNkVcdTMwMDIKLQotWFBvaW50ZXJSZXNvbHV0aW9uVW5zdWNjZXNzZnVsID0gWFBvaW50ZXIgXHU4OUUzXHU2NzkwXHU2NzJBXHU2MjEwXHU1MjlGXHUzMDAyCi0KLSMgTWVzc2FnZXMgZnJvbSBlcnJvbmVvdXMgc2V0LXVwCi1JbmNvbXBhdGlibGVOYW1lc3BhY2VDb250ZXh0ID0gTmFtZXNwYWNlQ29udGV4dCBcdTc2ODRcdTdDN0JcdTU3OEJcdTRFMEVcdTRGN0ZcdTc1MjggWEluY2x1ZGUgXHU0RTBEXHU1MTdDXHU1QkI5OyBcdTVCODNcdTVGQzVcdTk4N0JcdTY2MkYgWEluY2x1ZGVOYW1lc3BhY2VTdXBwb3J0IFx1NzY4NFx1NUI5RVx1NEY4QgotRXhwYW5kZWRTeXN0ZW1JZCA9IFx1NjVFMFx1NkNENVx1NjI2OVx1NUM1NVx1NTMwNVx1NTQyQlx1OEQ0NFx1NkU5MFx1NzY4NFx1N0NGQlx1N0VERiBJRApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWEluY2x1ZGVNZXNzYWdlc196aF9UVy5wcm9wZXJ0aWVzIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWEluY2x1ZGVNZXNzYWdlc196aF9UVy5wcm9wZXJ0aWVzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2OWNkMDM0Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hJbmNsdWRlTWVzc2FnZXNfemhfVFcucHJvcGVydGllcworKysgL2Rldi9udWxsCkBAIC0xLDM2ICswLDAgQEAKLSMgTWVzc2FnZXMgZm9yIG1lc3NhZ2UgcmVwb3J0aW5nCi1CYWRNZXNzYWdlS2V5ID0gXHU2MjdFXHU0RTBEXHU1MjMwXHU1QzBEXHU2MUM5XHU4QTBBXHU2MDZGXHU3RDIyXHU1RjE1XHU5Mzc1XHU3Njg0XHU5MzJGXHU4QUE0XHU4QTBBXHU2MDZGXHUzMDAyCi1Gb3JtYXRGYWlsZWQgPSBcdTY4M0NcdTVGMEZcdTUzMTZcdTRFMEJcdTUyMTdcdThBMEFcdTYwNkZcdTY2NDJcdTc2N0NcdTc1MUZcdTUxNjdcdTkwRThcdTkzMkZcdThBQTQ6XG4KLQotIyBNZXNzYWdlcyBmb3IgZXJyb25lb3VzIGlucHV0Ci1Ob0ZhbGxiYWNrID0gXHU1NDJCXHU2NzA5IGhyZWYgJyd7MH0nJyBcdTc2ODQgJydpbmNsdWRlJycgXHU1OTMxXHU2NTU3XHVGRjBDXHU2MjdFXHU0RTBEXHU1MjMwICcnZmFsbGJhY2snJyBcdTUxNDNcdTdEMjBcdTMwMDIKLU11bHRpcGxlRmFsbGJhY2tzID0gJ2luY2x1ZGUnIFx1NTE0M1x1N0QyMFx1NzY4NCBbY2hpbGRyZW5dIFx1NEUwRFx1NTNFRlx1NTMwNVx1NTQyQlx1OEQ4NVx1OTA0RVx1NEUwMFx1NTAwQlx1NEVFNVx1NEUwQVx1NzY4NCAnZmFsbGJhY2snIFx1NTE0M1x1N0QyMFx1MzAwMgotRmFsbGJhY2tQYXJlbnQgPSBcdTYyN0VcdTUyMzBcdTRFMDBcdTUwMEJcdTRFMERcdTUxNzdcdTY3MDkgJ2luY2x1ZGUnIFx1NEY1Q1x1NzBCQVx1NzIzNlx1OTgwNVx1NzY4NCAnZmFsbGJhY2snIFx1NTE0M1x1N0QyMFx1MzAwMgotSW5jbHVkZUNoaWxkID0gXHU0Rjg2XHU4MUVBXHU1NDdEXHU1NDBEXHU3QTdBXHU5NTkzICcnaHR0cDovL3d3dy53My5vcmcvMjAwMS9YSW5jbHVkZScnIFx1NEUxNFx1NEUwRFx1NjYyRiAnJ2ZhbGxiYWNrJycgXHU3Njg0XHU1MTQzXHU3RDIwXHVGRjBDXHU0RTBEXHU1MTQxXHU4QTMxXHU2MjEwXHU3MEJBICcnaW5jbHVkZScnIFx1NTE0M1x1N0QyMFx1NzY4NFx1NUI1MFx1OTgwNVx1MzAwMlx1NEUwRFx1OTA0RVx1RkYwQ1x1NTM3Qlx1NjI3RVx1NTIzMCAnJ3swfScnXHUzMDAyCi1GYWxsYmFja0NoaWxkID0gXHU0Rjg2XHU4MUVBXHU1NDdEXHU1NDBEXHU3QTdBXHU5NTkzICcnaHR0cDovL3d3dy53My5vcmcvMjAwMS9YSW5jbHVkZScnIFx1NEUxNFx1NEUwRFx1NjYyRiAnJ2luY2x1ZGUnJyBcdTc2ODRcdTUxNDNcdTdEMjBcdUZGMENcdTRFMERcdTUxNDFcdThBMzFcdTYyMTBcdTcwQkEgJydmYWxsYmFjaycnIFx1NTE0M1x1N0QyMFx1NzY4NFx1NUI1MFx1OTgwNVx1MzAwMlx1NEUwRFx1OTA0RVx1RkYwQ1x1NTM3Qlx1NjI3RVx1NTIzMCAnJ3swfScnXHUzMDAyCi1IcmVmTWlzc2luZyA9IFx1OTA3QVx1NkYwRiAnaW5jbHVkZScgXHU1MTQzXHU3RDIwXHU3Njg0ICdocmVmJyBcdTVDNkNcdTYwMjdcdTMwMDIKLVJlY3Vyc2l2ZUluY2x1ZGUgPSBcdTUwNzVcdTZFMkNcdTUyMzBcdTkwNUVcdThGRjRcdTUzMDVcdTU0MkJcdTMwMDJcdTVERjJcdTdEOTNcdTg2NTVcdTc0MDZcdTY1ODdcdTRFRjYgJyd7MH0nJ1x1MzAwMgotSW52YWxpZFBhcnNlVmFsdWUgPSAnJ2luY2x1ZGUnJyBcdTUxNDNcdTdEMjBcdTRFMEEgJydwYXJzZScnIFx1NUM2Q1x1NjAyN1x1NzY4NFx1NzEyMVx1NjU0OFx1NTAzQzogJyd7MH0nJ1x1MzAwMgotWE1MUGFyc2VFcnJvciA9IFx1NTYxN1x1OEE2Nlx1NTI1Nlx1Njc5MCBYTUwgXHU2QTk0XHU2ODQ4IChocmVmPScnezB9JycpIFx1NjY0Mlx1NzY3Q1x1NzUxRlx1OTMyRlx1OEFBNFx1MzAwMlx1NTM5Rlx1NTZFMDogezF9Ci1YTUxSZXNvdXJjZUVycm9yID0gXHU1MzA1XHU1NDJCXHU0RjVDXHU2OTZEXHU1OTMxXHU2NTU3XHVGRjBDXHU1NkRFXHU1RkE5XHU4MUYzXHU1RjhDXHU2M0Y0XHUzMDAyXHU0RUU1IFhNTCAoaHJlZj0nJ3swfScnKSBcdTY1QjlcdTVGMEZcdThCODBcdTUzRDZcdTZBOTRcdTY4NDhcdTY2NDJcdTc2N0NcdTc1MUZcdThDQzdcdTZFOTBcdTkzMkZcdThBQTRcdTMwMDJcdTUzOUZcdTU2RTA6IHsxfQotVGV4dFJlc291cmNlRXJyb3IgPSBcdTUzMDVcdTU0MkJcdTRGNUNcdTY5NkRcdTU5MzFcdTY1NTdcdUZGMENcdTU2REVcdTVGQTlcdTgxRjNcdTVGOENcdTYzRjRcdTMwMDJcdTRFRTVcdTY1ODdcdTVCNTcgKGhyZWY9Jyd7MH0nJykgXHU2NUI5XHU1RjBGXHU4QjgwXHU1M0Q2XHU2QTk0XHU2ODQ4XHU2NjQyXHU3NjdDXHU3NTFGXHU4Q0M3XHU2RTkwXHU5MzJGXHU4QUE0XHUzMDAyXHU1MzlGXHU1NkUwOiB7MX0KLU5PX1hQb2ludGVyU2NoZW1hID0gXHU5ODEwXHU4QTJEXHU0RTBEXHU2NTJGXHU2M0Y0ICJ7MH0iIFx1NzY4NFx1N0RCMVx1ODk4MVx1MzAwMlx1OEFDQlx1NzBCQSB7MH0gXHU1QjlBXHU3RkE5XHU2MEE4XHU4MUVBXHU1REYxXHU3Njg0XHU3REIxXHU4OTgxXHUzMDAyXHU4QUNCXHU1M0MzXHU5NUIxIGh0dHA6Ly9hcGFjaGUub3JnL3htbC9wcm9wZXJ0aWVzL3hwb2ludGVyLXNjaGVtYQotTk9fU3ViUmVzb3VyY2VJZGVudGlmaWVkID0gWFBvaW50ZXIgXHU4NjU1XHU3NDA2XHU1NjY4XHU2NzJBXHU4MEZEXHU3MEJBXHU2MzA3XHU2QTE5IHswfSBcdThCNThcdTUyMjVcdTRFRkJcdTRGNTVcdTVCNTBcdThDQzdcdTZFOTBcdTMwMDIKLU5vbkR1cGxpY2F0ZU5vdGF0aW9uID0gXHU0RjdGXHU3NTI4XHU1NDBEXHU3QTMxXHU3MEJBICcnezB9JycgXHU3Njg0XHU1OTFBXHU1MDBCXHU4ODY4XHU3OTNBXHU2Q0Q1XHVGRjBDXHU0RjQ2XHU2NjJGXHU2NzJBXHU4MEZEXHU1MjI0XHU2NUI3XHU5MDE5XHU0RTlCXHU4ODY4XHU3OTNBXHU2Q0Q1XHU5MUNEXHU4OTA3XHUzMDAyCi1Ob25EdXBsaWNhdGVVbnBhcnNlZEVudGl0eSA9IFx1NEY3Rlx1NzUyOFx1NTQwRFx1N0EzMVx1NzBCQSAnJ3swfScnIFx1NzY4NFx1NTkxQVx1NTAwQlx1NjcyQVx1NTI1Nlx1Njc5MFx1NUJFNlx1OUFENFx1RkYwQ1x1NEY0Nlx1NjYyRlx1NjcyQVx1ODBGRFx1NTIyNFx1NjVCN1x1OTAxOVx1NEU5Qlx1NUJFNlx1OUFENFx1OTFDRFx1ODkwN1x1MzAwMgotWHBvaW50ZXJNaXNzaW5nID0gXHU2QzkyXHU2NzA5IGhyZWYgXHU1QzZDXHU2MDI3XHU2NjQyXHVGRjBDXHU1RkM1XHU5ODA4XHU2NzA5IHhwb2ludGVyIFx1NUM2Q1x1NjAyN1x1MzAwMgotQWNjZXB0TWFsZm9ybWVkID0gJ2luY2x1ZGUnIFx1NTE0M1x1N0QyMFx1NzY4NCAnYWNjZXB0JyBcdTVDNkNcdTYwMjdcdTUwM0NcdTRFMkRcdUZGMENcdTRFMERcdTUxNDFcdThBMzFcdTdCQzRcdTU3MEQgI3gyMCBcdTgxRjMgI3g3RSBcdTRFNEJcdTU5MTZcdTc2ODRcdTVCNTdcdTUxNDNcdTMwMDIKLUFjY2VwdExhbmd1YWdlTWFsZm9ybWVkID0gJ2luY2x1ZGUnIFx1NTE0M1x1N0QyMFx1NzY4NCAnYWNjZXB0LWxhbmd1YWdlJyBcdTVDNkNcdTYwMjdcdTUwM0NcdTRFMkRcdUZGMENcdTRFMERcdTUxNDFcdThBMzFcdTdCQzRcdTU3MEQgI3gyMCBcdTgxRjMgI3g3RSBcdTRFNEJcdTU5MTZcdTc2ODRcdTVCNTdcdTUxNDNcdTMwMDIKLVJvb3RFbGVtZW50UmVxdWlyZWQgPSBcdTY4M0NcdTVGMEZcdTZCNjNcdTc4QkFcdTc2ODRcdTY1ODdcdTRFRjZcdTk3MDBcdTg5ODFcdTY4MzlcdTUxNDNcdTdEMjBcdTMwMDIKLU11bHRpcGxlUm9vdEVsZW1lbnRzID0gXHU2ODNDXHU1RjBGXHU2QjYzXHU3OEJBXHU3Njg0XHU2NTg3XHU0RUY2XHU0RTBEXHU1M0VGXHU1MzA1XHU1NDJCXHU1OTFBXHU1MDBCXHU2ODM5XHU1MTQzXHU3RDIwXHUzMDAyCi1Db250ZW50SWxsZWdhbEF0VG9wTGV2ZWwgPSBcdTUzRDZcdTRFRTMgJ2luY2x1ZGUnIFx1NTE0M1x1N0QyMFx1NEY1Q1x1NzBCQVx1NjcwMFx1NEUwQVx1NUM2NFx1NEY4Nlx1NkU5MCBpbmZvc2V0IFx1NzY4NFx1NjU4N1x1NEVGNlx1NTE0M1x1N0QyMFx1NEUwRFx1ODBGRFx1NTMwNVx1NTQyQlx1NUI1N1x1NTE0M1x1MzAwMgotVW5leHBhbmRlZEVudGl0eVJlZmVyZW5jZUlsbGVnYWwgPSBcdTUzRDZcdTRFRTMgJ2luY2x1ZGUnIFx1NTE0M1x1N0QyMFx1NEY1Q1x1NzBCQVx1NjcwMFx1NEUwQVx1NUM2NFx1NEY4Nlx1NkU5MCBpbmZvc2V0IFx1NzY4NFx1NjU4N1x1NEVGNlx1NTE0M1x1N0QyMFx1NEUwRFx1ODBGRFx1NTMwNVx1NTQyQlx1NjcyQVx1NUM1NVx1OTU4Qlx1NzY4NFx1NUJFNlx1OUFENFx1NTNDM1x1NzE2N1x1MzAwMgotSHJlZkZyYWdtZW50SWRlbnRpZmllcklsbGVnYWwgPSBcdTRFMERcdTUzRUZcdTRGN0ZcdTc1MjhcdTcyNDdcdTZCQjUgSURcdTMwMDJcdTRFMERcdTUxNDFcdThBMzEgJydocmVmJycgXHU1QzZDXHU2MDI3XHU1MDNDICcnezB9JydcdTMwMDIKLUhyZWZTeW50YWN0aWNhbGx5SW52YWxpZCA9ICcnaHJlZicnIFx1NUM2Q1x1NjAyN1x1NTAzQyAnJ3swfScnIFx1NTNFNVx1NkNENVx1NzEyMVx1NjU0OFx1MzAwMlx1NTk1N1x1NzUyOFx1OTA0MVx1OTZFMlx1ODk4Rlx1NTI0N1x1NEU0Qlx1NUY4Q1x1RkYwQ1x1NTAzQ1x1NzBCQVx1NTNFNVx1NkNENVx1NkI2M1x1NzhCQVx1NzY4NCBVUkkgXHU2MjE2IElSSVx1MzAwMgotWFBvaW50ZXJTdHJlYW1hYmlsaXR5ID0gXHU2MzA3XHU1QjlBIHhwb2ludGVyIFx1NjMwN1x1NTQxMVx1NEY4Nlx1NkU5MCBpbmZvc2V0IFx1NEUyRFx1NzY4NFx1NEY0RFx1N0Y2RVx1MzAwMlx1NzUzMVx1NjVCQ1x1ODY1NVx1NzQwNlx1NTY2OFx1NEUzMlx1NkQ0MVx1NzI3OVx1NjAyN1x1RkYwQ1x1NTZFMFx1NkI2NFx1NzEyMVx1NkNENVx1NUI1OFx1NTNENlx1NkI2NFx1NEY0RFx1N0Y2RVx1MzAwMgotCi1YUG9pbnRlclJlc29sdXRpb25VbnN1Y2Nlc3NmdWwgPSBYUG9pbnRlciBcdTg5RTNcdTY3OTBcdTU5MzFcdTY1NTdcdTMwMDIKLQotIyBNZXNzYWdlcyBmcm9tIGVycm9uZW91cyBzZXQtdXAKLUluY29tcGF0aWJsZU5hbWVzcGFjZUNvbnRleHQgPSBOYW1lc3BhY2VDb250ZXh0IFx1OTg1RVx1NTc4Qlx1ODIwN1x1NEY3Rlx1NzUyOCBYSW5jbHVkZSBcdTRFMERcdTc2RjhcdTVCQjk7IFx1NUI4M1x1NUZDNVx1OTgwOFx1NjYyRiBYSW5jbHVkZU5hbWVzcGFjZVN1cHBvcnQgXHU3Njg0XHU1N0Y3XHU4ODRDXHU4NjU1XHU3NDA2Ci1FeHBhbmRlZFN5c3RlbUlkID0gXHU3MTIxXHU2Q0Q1XHU1QzU1XHU5NThCXHU1MzA1XHU1NDJCXHU4Q0M3XHU2RTkwXHU3Njg0XHU3Q0ZCXHU3RDcxIElECmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9YTUxNZXNzYWdlRm9ybWF0dGVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9YTUxNZXNzYWdlRm9ybWF0dGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGFkYjhjNDQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MTWVzc2FnZUZvcm1hdHRlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTIxICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLm1zZzsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5NZXNzYWdlRm9ybWF0dGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbHMuU2VjdXJpdHlTdXBwb3J0OwotaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7Ci1pbXBvcnQgamF2YS51dGlsLk1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuUmVzb3VyY2VCdW5kbGU7Ci0KLS8qKgotICogWE1MTWVzc2FnZUZvcm1hdHRlciBwcm92aWRlcyBlcnJvciBtZXNzYWdlcyBmb3IgdGhlIFhNTCAxLjAgUmVjb21tZW5kYXRpb24gYW5kIGZvcgotICogdGhlIE5hbWVzcGFjZXMgUmVjb21tZW5kYXRpb24KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBFcmljIFllLCBJQk0KLSAqIEB2ZXJzaW9uICRJZDogWE1MTWVzc2FnZUZvcm1hdHRlci5qYXZhIDMwOTQgMjAxMi0wMy0yMSAwNTo1MDowMVogam9laHcgJAotICoKLSAqLwotcHVibGljIGNsYXNzIFhNTE1lc3NhZ2VGb3JtYXR0ZXIgaW1wbGVtZW50cyBNZXNzYWdlRm9ybWF0dGVyIHsKLSAgICAvKioKLSAgICAgKiBUaGUgZG9tYWluIG9mIG1lc3NhZ2VzIGNvbmNlcm5pbmcgdGhlIFhNTCAxLjAgc3BlY2lmaWNhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxfRE9NQUlOID0gImh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLXhtbC0xOTk4MDIxMCI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MTlNfRE9NQUlOID0gImh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTkvUkVDLXhtbC1uYW1lcy0xOTk5MDExNCI7Ci0KLSAgICAvLyBwcml2YXRlIG9iamVjdHMgdG8gY2FjaGUgdGhlIGxvY2FsZSBhbmQgcmVzb3VyY2UgYnVuZGxlCi0gICAgcHJpdmF0ZSBMb2NhbGUgZkxvY2FsZSA9IG51bGw7Ci0gICAgcHJpdmF0ZSBSZXNvdXJjZUJ1bmRsZSBmUmVzb3VyY2VCdW5kbGUgPSBudWxsOwotCi0gICAgLy8KLSAgICAvLyBNZXNzYWdlRm9ybWF0dGVyIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogRm9ybWF0cyBhIG1lc3NhZ2Ugd2l0aCB0aGUgc3BlY2lmaWVkIGFyZ3VtZW50cyB1c2luZyB0aGUgZ2l2ZW4KLSAgICAgKiBsb2NhbGUgaW5mb3JtYXRpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbG9jYWxlICAgIFRoZSBsb2NhbGUgb2YgdGhlIG1lc3NhZ2UuCi0gICAgICogQHBhcmFtIGtleSAgICAgICBUaGUgbWVzc2FnZSBrZXkuCi0gICAgICogQHBhcmFtIGFyZ3VtZW50cyBUaGUgbWVzc2FnZSByZXBsYWNlbWVudCB0ZXh0IGFyZ3VtZW50cy4gVGhlIG9yZGVyCi0gICAgICogICAgICAgICAgICAgICAgICBvZiB0aGUgYXJndW1lbnRzIG11c3QgbWF0Y2ggdGhhdCBvZiB0aGUgcGxhY2Vob2xkZXJzCi0gICAgICogICAgICAgICAgICAgICAgICBpbiB0aGUgYWN0dWFsIG1lc3NhZ2UuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFJldHVybnMgdGhlIGZvcm1hdHRlZCBtZXNzYWdlLgotICAgICAqCi0gICAgICogQHRocm93cyBNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24gVGhyb3duIGlmIHRoZSBtZXNzYWdlIHdpdGggdGhlCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BlY2lmaWVkIGtleSBjYW5ub3QgYmUgZm91bmQuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBmb3JtYXRNZXNzYWdlKExvY2FsZSBsb2NhbGUsIFN0cmluZyBrZXksIE9iamVjdFtdIGFyZ3VtZW50cykKLSAgICAgICAgdGhyb3dzIE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgaWYgKGZSZXNvdXJjZUJ1bmRsZSA9PSBudWxsIHx8IGxvY2FsZSAhPSBmTG9jYWxlKSB7Ci0gICAgICAgICAgICBpZiAobG9jYWxlICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmUmVzb3VyY2VCdW5kbGUgPSBTZWN1cml0eVN1cHBvcnQuZ2V0UmVzb3VyY2VCdW5kbGUoImNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5tc2cuWE1MTWVzc2FnZXMiLCBsb2NhbGUpOwotICAgICAgICAgICAgICAgIC8vIG1lbW9yaXplIHRoZSBtb3N0LXJlY2VudCBsb2NhbGUKLSAgICAgICAgICAgICAgICBmTG9jYWxlID0gbG9jYWxlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKGZSZXNvdXJjZUJ1bmRsZSA9PSBudWxsKQotICAgICAgICAgICAgICAgIGZSZXNvdXJjZUJ1bmRsZSA9IFNlY3VyaXR5U3VwcG9ydC5nZXRSZXNvdXJjZUJ1bmRsZSgiY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLm1zZy5YTUxNZXNzYWdlcyIpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gZm9ybWF0IG1lc3NhZ2UKLSAgICAgICAgU3RyaW5nIG1zZzsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIG1zZyA9IGZSZXNvdXJjZUJ1bmRsZS5nZXRTdHJpbmcoa2V5KTsKLSAgICAgICAgICAgIGlmIChhcmd1bWVudHMgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgIG1zZyA9IGphdmEudGV4dC5NZXNzYWdlRm9ybWF0LmZvcm1hdChtc2csIGFyZ3VtZW50cyk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgICAgICBtc2cgPSBmUmVzb3VyY2VCdW5kbGUuZ2V0U3RyaW5nKCJGb3JtYXRGYWlsZWQiKTsKLSAgICAgICAgICAgICAgICAgICAgbXNnICs9ICIgIiArIGZSZXNvdXJjZUJ1bmRsZS5nZXRTdHJpbmcoa2V5KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBlcnJvcgotICAgICAgICBjYXRjaCAoTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIG1zZyA9IGZSZXNvdXJjZUJ1bmRsZS5nZXRTdHJpbmcoIkJhZE1lc3NhZ2VLZXkiKTsKLSAgICAgICAgICAgIHRocm93IG5ldyBNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24oa2V5LCBtc2csIGtleSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBubyBtZXNzYWdlCi0gICAgICAgIGlmIChtc2cgPT0gbnVsbCkgewotICAgICAgICAgICAgbXNnID0ga2V5OwotICAgICAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAwKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nQnVmZmVyIHN0ciA9IG5ldyBTdHJpbmdCdWZmZXIobXNnKTsKLSAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKCc/Jyk7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGkgPiAwKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKCcmJyk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgc3RyLmFwcGVuZChTdHJpbmcudmFsdWVPZihhcmd1bWVudHNbaV0pKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gbXNnOwotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MTWVzc2FnZUZvcm1hdHRlcl9kZS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MTWVzc2FnZUZvcm1hdHRlcl9kZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxZjlkMjgxLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hNTE1lc3NhZ2VGb3JtYXR0ZXJfZGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEyMyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5tc2c7Ci0KLWltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwotaW1wb3J0IGphdmEudXRpbC5NaXNzaW5nUmVzb3VyY2VFeGNlcHRpb247Ci1pbXBvcnQgamF2YS51dGlsLlJlc291cmNlQnVuZGxlOwotaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0eVJlc291cmNlQnVuZGxlOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLk1lc3NhZ2VGb3JtYXR0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlscy5TZWN1cml0eVN1cHBvcnQ7Ci0KLS8qKgotICogWE1MTWVzc2FnZUZvcm1hdHRlciBwcm92aWRlcyBlcnJvciBtZXNzYWdlcyBmb3IgdGhlIFhNTCAxLjAgUmVjb21tZW5kYXRpb24gYW5kIGZvcgotICogdGhlIE5hbWVzcGFjZXMgUmVjb21tZW5kYXRpb24KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBFcmljIFllLCBJQk0KLSAqIEB2ZXJzaW9uICRJZDogWE1MTWVzc2FnZUZvcm1hdHRlcl9kZS5qYXZhIDMwOTQgMjAxMi0wMy0yMSAwNTo1MDowMVogam9laHcgJAotICoKLSAqLwotcHVibGljIGNsYXNzIFhNTE1lc3NhZ2VGb3JtYXR0ZXJfZGUgaW1wbGVtZW50cyBNZXNzYWdlRm9ybWF0dGVyIHsKLSAgICAvKioKLSAgICAgKiBUaGUgZG9tYWluIG9mIG1lc3NhZ2VzIGNvbmNlcm5pbmcgdGhlIFhNTCAxLjAgc3BlY2lmaWNhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxfRE9NQUlOID0gImh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLXhtbC0xOTk4MDIxMCI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MTlNfRE9NQUlOID0gImh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTkvUkVDLXhtbC1uYW1lcy0xOTk5MDExNCI7Ci0KLSAgICAvLyBwcml2YXRlIG9iamVjdHMgdG8gY2FjaGUgdGhlIGxvY2FsZSBhbmQgcmVzb3VyY2UgYnVuZGxlCi0gICAgcHJpdmF0ZSBMb2NhbGUgZkxvY2FsZSA9IG51bGw7Ci0gICAgcHJpdmF0ZSBSZXNvdXJjZUJ1bmRsZSBmUmVzb3VyY2VCdW5kbGUgPSBudWxsOwotCi0gICAgLy8KLSAgICAvLyBNZXNzYWdlRm9ybWF0dGVyIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogRm9ybWF0cyBhIG1lc3NhZ2Ugd2l0aCB0aGUgc3BlY2lmaWVkIGFyZ3VtZW50cyB1c2luZyB0aGUgZ2l2ZW4KLSAgICAgKiBsb2NhbGUgaW5mb3JtYXRpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbG9jYWxlICAgIFRoZSBsb2NhbGUgb2YgdGhlIG1lc3NhZ2UuCi0gICAgICogQHBhcmFtIGtleSAgICAgICBUaGUgbWVzc2FnZSBrZXkuCi0gICAgICogQHBhcmFtIGFyZ3VtZW50cyBUaGUgbWVzc2FnZSByZXBsYWNlbWVudCB0ZXh0IGFyZ3VtZW50cy4gVGhlIG9yZGVyCi0gICAgICogICAgICAgICAgICAgICAgICBvZiB0aGUgYXJndW1lbnRzIG11c3QgbWF0Y2ggdGhhdCBvZiB0aGUgcGxhY2Vob2xkZXJzCi0gICAgICogICAgICAgICAgICAgICAgICBpbiB0aGUgYWN0dWFsIG1lc3NhZ2UuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFJldHVybnMgdGhlIGZvcm1hdHRlZCBtZXNzYWdlLgotICAgICAqCi0gICAgICogQHRocm93cyBNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24gVGhyb3duIGlmIHRoZSBtZXNzYWdlIHdpdGggdGhlCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BlY2lmaWVkIGtleSBjYW5ub3QgYmUgZm91bmQuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBmb3JtYXRNZXNzYWdlKExvY2FsZSBsb2NhbGUsIFN0cmluZyBrZXksIE9iamVjdFtdIGFyZ3VtZW50cykKLSAgICAgICAgdGhyb3dzIE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgaWYgKGZSZXNvdXJjZUJ1bmRsZSA9PSBudWxsIHx8IGxvY2FsZSAhPSBmTG9jYWxlKSB7Ci0gICAgICAgICAgICBpZiAobG9jYWxlICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmUmVzb3VyY2VCdW5kbGUgPSBTZWN1cml0eVN1cHBvcnQuZ2V0UmVzb3VyY2VCdW5kbGUoImNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5tc2cuWE1MTWVzc2FnZXMiLCBsb2NhbGUpOwotICAgICAgICAgICAgICAgIC8vIG1lbW9yaXplIHRoZSBtb3N0LXJlY2VudCBsb2NhbGUKLSAgICAgICAgICAgICAgICBmTG9jYWxlID0gbG9jYWxlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKGZSZXNvdXJjZUJ1bmRsZSA9PSBudWxsKQotICAgICAgICAgICAgICAgIGZSZXNvdXJjZUJ1bmRsZSA9IFNlY3VyaXR5U3VwcG9ydC5nZXRSZXNvdXJjZUJ1bmRsZSgiY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLm1zZy5YTUxNZXNzYWdlcyIpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gZm9ybWF0IG1lc3NhZ2UKLSAgICAgICAgU3RyaW5nIG1zZzsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIG1zZyA9IGZSZXNvdXJjZUJ1bmRsZS5nZXRTdHJpbmcoa2V5KTsKLSAgICAgICAgICAgIGlmIChhcmd1bWVudHMgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgIG1zZyA9IGphdmEudGV4dC5NZXNzYWdlRm9ybWF0LmZvcm1hdChtc2csIGFyZ3VtZW50cyk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgICAgICBtc2cgPSBmUmVzb3VyY2VCdW5kbGUuZ2V0U3RyaW5nKCJGb3JtYXRGYWlsZWQiKTsKLSAgICAgICAgICAgICAgICAgICAgbXNnICs9ICIgIiArIGZSZXNvdXJjZUJ1bmRsZS5nZXRTdHJpbmcoa2V5KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBlcnJvcgotICAgICAgICBjYXRjaCAoTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIG1zZyA9IGZSZXNvdXJjZUJ1bmRsZS5nZXRTdHJpbmcoIkJhZE1lc3NhZ2VLZXkiKTsKLSAgICAgICAgICAgIHRocm93IG5ldyBNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24oa2V5LCBtc2csIGtleSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBubyBtZXNzYWdlCi0gICAgICAgIGlmIChtc2cgPT0gbnVsbCkgewotICAgICAgICAgICAgbXNnID0ga2V5OwotICAgICAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAwKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nQnVmZmVyIHN0ciA9IG5ldyBTdHJpbmdCdWZmZXIobXNnKTsKLSAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKCc/Jyk7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGkgPiAwKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKCcmJyk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgc3RyLmFwcGVuZChTdHJpbmcudmFsdWVPZihhcmd1bWVudHNbaV0pKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gbXNnOwotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MTWVzc2FnZUZvcm1hdHRlcl9lcy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MTWVzc2FnZUZvcm1hdHRlcl9lcy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxNjRhMjUxLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hNTE1lc3NhZ2VGb3JtYXR0ZXJfZXMuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEyMyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5tc2c7Ci0KLWltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwotaW1wb3J0IGphdmEudXRpbC5NaXNzaW5nUmVzb3VyY2VFeGNlcHRpb247Ci1pbXBvcnQgamF2YS51dGlsLlJlc291cmNlQnVuZGxlOwotaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0eVJlc291cmNlQnVuZGxlOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLk1lc3NhZ2VGb3JtYXR0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlscy5TZWN1cml0eVN1cHBvcnQ7Ci0KLS8qKgotICogWE1MTWVzc2FnZUZvcm1hdHRlciBwcm92aWRlcyBlcnJvciBtZXNzYWdlcyBmb3IgdGhlIFhNTCAxLjAgUmVjb21tZW5kYXRpb24gYW5kIGZvcgotICogdGhlIE5hbWVzcGFjZXMgUmVjb21tZW5kYXRpb24KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBFcmljIFllLCBJQk0KLSAqIEB2ZXJzaW9uICRJZDogWE1MTWVzc2FnZUZvcm1hdHRlcl9lcy5qYXZhIDMwOTQgMjAxMi0wMy0yMSAwNTo1MDowMVogam9laHcgJAotICoKLSAqLwotcHVibGljIGNsYXNzIFhNTE1lc3NhZ2VGb3JtYXR0ZXJfZXMgaW1wbGVtZW50cyBNZXNzYWdlRm9ybWF0dGVyIHsKLSAgICAvKioKLSAgICAgKiBUaGUgZG9tYWluIG9mIG1lc3NhZ2VzIGNvbmNlcm5pbmcgdGhlIFhNTCAxLjAgc3BlY2lmaWNhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxfRE9NQUlOID0gImh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLXhtbC0xOTk4MDIxMCI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MTlNfRE9NQUlOID0gImh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTkvUkVDLXhtbC1uYW1lcy0xOTk5MDExNCI7Ci0KLSAgICAvLyBwcml2YXRlIG9iamVjdHMgdG8gY2FjaGUgdGhlIGxvY2FsZSBhbmQgcmVzb3VyY2UgYnVuZGxlCi0gICAgcHJpdmF0ZSBMb2NhbGUgZkxvY2FsZSA9IG51bGw7Ci0gICAgcHJpdmF0ZSBSZXNvdXJjZUJ1bmRsZSBmUmVzb3VyY2VCdW5kbGUgPSBudWxsOwotCi0gICAgLy8KLSAgICAvLyBNZXNzYWdlRm9ybWF0dGVyIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogRm9ybWF0cyBhIG1lc3NhZ2Ugd2l0aCB0aGUgc3BlY2lmaWVkIGFyZ3VtZW50cyB1c2luZyB0aGUgZ2l2ZW4KLSAgICAgKiBsb2NhbGUgaW5mb3JtYXRpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbG9jYWxlICAgIFRoZSBsb2NhbGUgb2YgdGhlIG1lc3NhZ2UuCi0gICAgICogQHBhcmFtIGtleSAgICAgICBUaGUgbWVzc2FnZSBrZXkuCi0gICAgICogQHBhcmFtIGFyZ3VtZW50cyBUaGUgbWVzc2FnZSByZXBsYWNlbWVudCB0ZXh0IGFyZ3VtZW50cy4gVGhlIG9yZGVyCi0gICAgICogICAgICAgICAgICAgICAgICBvZiB0aGUgYXJndW1lbnRzIG11c3QgbWF0Y2ggdGhhdCBvZiB0aGUgcGxhY2Vob2xkZXJzCi0gICAgICogICAgICAgICAgICAgICAgICBpbiB0aGUgYWN0dWFsIG1lc3NhZ2UuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFJldHVybnMgdGhlIGZvcm1hdHRlZCBtZXNzYWdlLgotICAgICAqCi0gICAgICogQHRocm93cyBNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24gVGhyb3duIGlmIHRoZSBtZXNzYWdlIHdpdGggdGhlCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BlY2lmaWVkIGtleSBjYW5ub3QgYmUgZm91bmQuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBmb3JtYXRNZXNzYWdlKExvY2FsZSBsb2NhbGUsIFN0cmluZyBrZXksIE9iamVjdFtdIGFyZ3VtZW50cykKLSAgICAgICAgdGhyb3dzIE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgaWYgKGZSZXNvdXJjZUJ1bmRsZSA9PSBudWxsIHx8IGxvY2FsZSAhPSBmTG9jYWxlKSB7Ci0gICAgICAgICAgICBpZiAobG9jYWxlICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmUmVzb3VyY2VCdW5kbGUgPSBTZWN1cml0eVN1cHBvcnQuZ2V0UmVzb3VyY2VCdW5kbGUoImNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5tc2cuWE1MTWVzc2FnZXMiLCBsb2NhbGUpOwotICAgICAgICAgICAgICAgIC8vIG1lbW9yaXplIHRoZSBtb3N0LXJlY2VudCBsb2NhbGUKLSAgICAgICAgICAgICAgICBmTG9jYWxlID0gbG9jYWxlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKGZSZXNvdXJjZUJ1bmRsZSA9PSBudWxsKQotICAgICAgICAgICAgICAgIGZSZXNvdXJjZUJ1bmRsZSA9IFNlY3VyaXR5U3VwcG9ydC5nZXRSZXNvdXJjZUJ1bmRsZSgiY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLm1zZy5YTUxNZXNzYWdlcyIpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gZm9ybWF0IG1lc3NhZ2UKLSAgICAgICAgU3RyaW5nIG1zZzsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIG1zZyA9IGZSZXNvdXJjZUJ1bmRsZS5nZXRTdHJpbmcoa2V5KTsKLSAgICAgICAgICAgIGlmIChhcmd1bWVudHMgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgIG1zZyA9IGphdmEudGV4dC5NZXNzYWdlRm9ybWF0LmZvcm1hdChtc2csIGFyZ3VtZW50cyk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgICAgICBtc2cgPSBmUmVzb3VyY2VCdW5kbGUuZ2V0U3RyaW5nKCJGb3JtYXRGYWlsZWQiKTsKLSAgICAgICAgICAgICAgICAgICAgbXNnICs9ICIgIiArIGZSZXNvdXJjZUJ1bmRsZS5nZXRTdHJpbmcoa2V5KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBlcnJvcgotICAgICAgICBjYXRjaCAoTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIG1zZyA9IGZSZXNvdXJjZUJ1bmRsZS5nZXRTdHJpbmcoIkJhZE1lc3NhZ2VLZXkiKTsKLSAgICAgICAgICAgIHRocm93IG5ldyBNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24oa2V5LCBtc2csIGtleSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBubyBtZXNzYWdlCi0gICAgICAgIGlmIChtc2cgPT0gbnVsbCkgewotICAgICAgICAgICAgbXNnID0ga2V5OwotICAgICAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAwKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nQnVmZmVyIHN0ciA9IG5ldyBTdHJpbmdCdWZmZXIobXNnKTsKLSAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKCc/Jyk7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGkgPiAwKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKCcmJyk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgc3RyLmFwcGVuZChTdHJpbmcudmFsdWVPZihhcmd1bWVudHNbaV0pKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gbXNnOwotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MTWVzc2FnZUZvcm1hdHRlcl9mci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MTWVzc2FnZUZvcm1hdHRlcl9mci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlNGU0MTI5Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hNTE1lc3NhZ2VGb3JtYXR0ZXJfZnIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEyMyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5tc2c7Ci0KLWltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwotaW1wb3J0IGphdmEudXRpbC5NaXNzaW5nUmVzb3VyY2VFeGNlcHRpb247Ci1pbXBvcnQgamF2YS51dGlsLlJlc291cmNlQnVuZGxlOwotaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0eVJlc291cmNlQnVuZGxlOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLk1lc3NhZ2VGb3JtYXR0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlscy5TZWN1cml0eVN1cHBvcnQ7Ci0KLS8qKgotICogWE1MTWVzc2FnZUZvcm1hdHRlciBwcm92aWRlcyBlcnJvciBtZXNzYWdlcyBmb3IgdGhlIFhNTCAxLjAgUmVjb21tZW5kYXRpb24gYW5kIGZvcgotICogdGhlIE5hbWVzcGFjZXMgUmVjb21tZW5kYXRpb24KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBFcmljIFllLCBJQk0KLSAqIEB2ZXJzaW9uICRJZDogWE1MTWVzc2FnZUZvcm1hdHRlcl9mci5qYXZhIDMwOTQgMjAxMi0wMy0yMSAwNTo1MDowMVogam9laHcgJAotICoKLSAqLwotcHVibGljIGNsYXNzIFhNTE1lc3NhZ2VGb3JtYXR0ZXJfZnIgaW1wbGVtZW50cyBNZXNzYWdlRm9ybWF0dGVyIHsKLSAgICAvKioKLSAgICAgKiBUaGUgZG9tYWluIG9mIG1lc3NhZ2VzIGNvbmNlcm5pbmcgdGhlIFhNTCAxLjAgc3BlY2lmaWNhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxfRE9NQUlOID0gImh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLXhtbC0xOTk4MDIxMCI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MTlNfRE9NQUlOID0gImh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTkvUkVDLXhtbC1uYW1lcy0xOTk5MDExNCI7Ci0KLSAgICAvLyBwcml2YXRlIG9iamVjdHMgdG8gY2FjaGUgdGhlIGxvY2FsZSBhbmQgcmVzb3VyY2UgYnVuZGxlCi0gICAgcHJpdmF0ZSBMb2NhbGUgZkxvY2FsZSA9IG51bGw7Ci0gICAgcHJpdmF0ZSBSZXNvdXJjZUJ1bmRsZSBmUmVzb3VyY2VCdW5kbGUgPSBudWxsOwotCi0gICAgLy8KLSAgICAvLyBNZXNzYWdlRm9ybWF0dGVyIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogRm9ybWF0cyBhIG1lc3NhZ2Ugd2l0aCB0aGUgc3BlY2lmaWVkIGFyZ3VtZW50cyB1c2luZyB0aGUgZ2l2ZW4KLSAgICAgKiBsb2NhbGUgaW5mb3JtYXRpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbG9jYWxlICAgIFRoZSBsb2NhbGUgb2YgdGhlIG1lc3NhZ2UuCi0gICAgICogQHBhcmFtIGtleSAgICAgICBUaGUgbWVzc2FnZSBrZXkuCi0gICAgICogQHBhcmFtIGFyZ3VtZW50cyBUaGUgbWVzc2FnZSByZXBsYWNlbWVudCB0ZXh0IGFyZ3VtZW50cy4gVGhlIG9yZGVyCi0gICAgICogICAgICAgICAgICAgICAgICBvZiB0aGUgYXJndW1lbnRzIG11c3QgbWF0Y2ggdGhhdCBvZiB0aGUgcGxhY2Vob2xkZXJzCi0gICAgICogICAgICAgICAgICAgICAgICBpbiB0aGUgYWN0dWFsIG1lc3NhZ2UuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFJldHVybnMgdGhlIGZvcm1hdHRlZCBtZXNzYWdlLgotICAgICAqCi0gICAgICogQHRocm93cyBNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24gVGhyb3duIGlmIHRoZSBtZXNzYWdlIHdpdGggdGhlCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BlY2lmaWVkIGtleSBjYW5ub3QgYmUgZm91bmQuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBmb3JtYXRNZXNzYWdlKExvY2FsZSBsb2NhbGUsIFN0cmluZyBrZXksIE9iamVjdFtdIGFyZ3VtZW50cykKLSAgICAgICAgdGhyb3dzIE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgaWYgKGZSZXNvdXJjZUJ1bmRsZSA9PSBudWxsIHx8IGxvY2FsZSAhPSBmTG9jYWxlKSB7Ci0gICAgICAgICAgICBpZiAobG9jYWxlICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmUmVzb3VyY2VCdW5kbGUgPSBTZWN1cml0eVN1cHBvcnQuZ2V0UmVzb3VyY2VCdW5kbGUoImNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5tc2cuWE1MTWVzc2FnZXMiLCBsb2NhbGUpOwotICAgICAgICAgICAgICAgIC8vIG1lbW9yaXplIHRoZSBtb3N0LXJlY2VudCBsb2NhbGUKLSAgICAgICAgICAgICAgICBmTG9jYWxlID0gbG9jYWxlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKGZSZXNvdXJjZUJ1bmRsZSA9PSBudWxsKQotICAgICAgICAgICAgICAgIGZSZXNvdXJjZUJ1bmRsZSA9IFNlY3VyaXR5U3VwcG9ydC5nZXRSZXNvdXJjZUJ1bmRsZSgiY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLm1zZy5YTUxNZXNzYWdlcyIpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gZm9ybWF0IG1lc3NhZ2UKLSAgICAgICAgU3RyaW5nIG1zZzsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIG1zZyA9IGZSZXNvdXJjZUJ1bmRsZS5nZXRTdHJpbmcoa2V5KTsKLSAgICAgICAgICAgIGlmIChhcmd1bWVudHMgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgIG1zZyA9IGphdmEudGV4dC5NZXNzYWdlRm9ybWF0LmZvcm1hdChtc2csIGFyZ3VtZW50cyk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgICAgICBtc2cgPSBmUmVzb3VyY2VCdW5kbGUuZ2V0U3RyaW5nKCJGb3JtYXRGYWlsZWQiKTsKLSAgICAgICAgICAgICAgICAgICAgbXNnICs9ICIgIiArIGZSZXNvdXJjZUJ1bmRsZS5nZXRTdHJpbmcoa2V5KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBlcnJvcgotICAgICAgICBjYXRjaCAoTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIG1zZyA9IGZSZXNvdXJjZUJ1bmRsZS5nZXRTdHJpbmcoIkJhZE1lc3NhZ2VLZXkiKTsKLSAgICAgICAgICAgIHRocm93IG5ldyBNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24oa2V5LCBtc2csIGtleSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBubyBtZXNzYWdlCi0gICAgICAgIGlmIChtc2cgPT0gbnVsbCkgewotICAgICAgICAgICAgbXNnID0ga2V5OwotICAgICAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAwKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nQnVmZmVyIHN0ciA9IG5ldyBTdHJpbmdCdWZmZXIobXNnKTsKLSAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKCc/Jyk7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGkgPiAwKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKCcmJyk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgc3RyLmFwcGVuZChTdHJpbmcudmFsdWVPZihhcmd1bWVudHNbaV0pKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gbXNnOwotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MTWVzc2FnZUZvcm1hdHRlcl9pdC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MTWVzc2FnZUZvcm1hdHRlcl9pdC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlMmRkNTEzLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hNTE1lc3NhZ2VGb3JtYXR0ZXJfaXQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEyMyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5tc2c7Ci0KLWltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwotaW1wb3J0IGphdmEudXRpbC5NaXNzaW5nUmVzb3VyY2VFeGNlcHRpb247Ci1pbXBvcnQgamF2YS51dGlsLlJlc291cmNlQnVuZGxlOwotaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0eVJlc291cmNlQnVuZGxlOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLk1lc3NhZ2VGb3JtYXR0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlscy5TZWN1cml0eVN1cHBvcnQ7Ci0KLS8qKgotICogWE1MTWVzc2FnZUZvcm1hdHRlciBwcm92aWRlcyBlcnJvciBtZXNzYWdlcyBmb3IgdGhlIFhNTCAxLjAgUmVjb21tZW5kYXRpb24gYW5kIGZvcgotICogdGhlIE5hbWVzcGFjZXMgUmVjb21tZW5kYXRpb24KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBFcmljIFllLCBJQk0KLSAqIEB2ZXJzaW9uICRJZDogWE1MTWVzc2FnZUZvcm1hdHRlcl9pdC5qYXZhIDMwOTQgMjAxMi0wMy0yMSAwNTo1MDowMVogam9laHcgJAotICoKLSAqLwotcHVibGljIGNsYXNzIFhNTE1lc3NhZ2VGb3JtYXR0ZXJfaXQgaW1wbGVtZW50cyBNZXNzYWdlRm9ybWF0dGVyIHsKLSAgICAvKioKLSAgICAgKiBUaGUgZG9tYWluIG9mIG1lc3NhZ2VzIGNvbmNlcm5pbmcgdGhlIFhNTCAxLjAgc3BlY2lmaWNhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxfRE9NQUlOID0gImh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLXhtbC0xOTk4MDIxMCI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MTlNfRE9NQUlOID0gImh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTkvUkVDLXhtbC1uYW1lcy0xOTk5MDExNCI7Ci0KLSAgICAvLyBwcml2YXRlIG9iamVjdHMgdG8gY2FjaGUgdGhlIGxvY2FsZSBhbmQgcmVzb3VyY2UgYnVuZGxlCi0gICAgcHJpdmF0ZSBMb2NhbGUgZkxvY2FsZSA9IG51bGw7Ci0gICAgcHJpdmF0ZSBSZXNvdXJjZUJ1bmRsZSBmUmVzb3VyY2VCdW5kbGUgPSBudWxsOwotCi0gICAgLy8KLSAgICAvLyBNZXNzYWdlRm9ybWF0dGVyIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogRm9ybWF0cyBhIG1lc3NhZ2Ugd2l0aCB0aGUgc3BlY2lmaWVkIGFyZ3VtZW50cyB1c2luZyB0aGUgZ2l2ZW4KLSAgICAgKiBsb2NhbGUgaW5mb3JtYXRpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbG9jYWxlICAgIFRoZSBsb2NhbGUgb2YgdGhlIG1lc3NhZ2UuCi0gICAgICogQHBhcmFtIGtleSAgICAgICBUaGUgbWVzc2FnZSBrZXkuCi0gICAgICogQHBhcmFtIGFyZ3VtZW50cyBUaGUgbWVzc2FnZSByZXBsYWNlbWVudCB0ZXh0IGFyZ3VtZW50cy4gVGhlIG9yZGVyCi0gICAgICogICAgICAgICAgICAgICAgICBvZiB0aGUgYXJndW1lbnRzIG11c3QgbWF0Y2ggdGhhdCBvZiB0aGUgcGxhY2Vob2xkZXJzCi0gICAgICogICAgICAgICAgICAgICAgICBpbiB0aGUgYWN0dWFsIG1lc3NhZ2UuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFJldHVybnMgdGhlIGZvcm1hdHRlZCBtZXNzYWdlLgotICAgICAqCi0gICAgICogQHRocm93cyBNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24gVGhyb3duIGlmIHRoZSBtZXNzYWdlIHdpdGggdGhlCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BlY2lmaWVkIGtleSBjYW5ub3QgYmUgZm91bmQuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBmb3JtYXRNZXNzYWdlKExvY2FsZSBsb2NhbGUsIFN0cmluZyBrZXksIE9iamVjdFtdIGFyZ3VtZW50cykKLSAgICAgICAgdGhyb3dzIE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgaWYgKGZSZXNvdXJjZUJ1bmRsZSA9PSBudWxsIHx8IGxvY2FsZSAhPSBmTG9jYWxlKSB7Ci0gICAgICAgICAgICBpZiAobG9jYWxlICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmUmVzb3VyY2VCdW5kbGUgPSBTZWN1cml0eVN1cHBvcnQuZ2V0UmVzb3VyY2VCdW5kbGUoImNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5tc2cuWE1MTWVzc2FnZXMiLCBsb2NhbGUpOwotICAgICAgICAgICAgICAgIC8vIG1lbW9yaXplIHRoZSBtb3N0LXJlY2VudCBsb2NhbGUKLSAgICAgICAgICAgICAgICBmTG9jYWxlID0gbG9jYWxlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKGZSZXNvdXJjZUJ1bmRsZSA9PSBudWxsKQotICAgICAgICAgICAgICAgIGZSZXNvdXJjZUJ1bmRsZSA9IFNlY3VyaXR5U3VwcG9ydC5nZXRSZXNvdXJjZUJ1bmRsZSgiY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLm1zZy5YTUxNZXNzYWdlcyIpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gZm9ybWF0IG1lc3NhZ2UKLSAgICAgICAgU3RyaW5nIG1zZzsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIG1zZyA9IGZSZXNvdXJjZUJ1bmRsZS5nZXRTdHJpbmcoa2V5KTsKLSAgICAgICAgICAgIGlmIChhcmd1bWVudHMgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgIG1zZyA9IGphdmEudGV4dC5NZXNzYWdlRm9ybWF0LmZvcm1hdChtc2csIGFyZ3VtZW50cyk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgICAgICBtc2cgPSBmUmVzb3VyY2VCdW5kbGUuZ2V0U3RyaW5nKCJGb3JtYXRGYWlsZWQiKTsKLSAgICAgICAgICAgICAgICAgICAgbXNnICs9ICIgIiArIGZSZXNvdXJjZUJ1bmRsZS5nZXRTdHJpbmcoa2V5KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBlcnJvcgotICAgICAgICBjYXRjaCAoTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIG1zZyA9IGZSZXNvdXJjZUJ1bmRsZS5nZXRTdHJpbmcoIkJhZE1lc3NhZ2VLZXkiKTsKLSAgICAgICAgICAgIHRocm93IG5ldyBNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24oa2V5LCBtc2csIGtleSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBubyBtZXNzYWdlCi0gICAgICAgIGlmIChtc2cgPT0gbnVsbCkgewotICAgICAgICAgICAgbXNnID0ga2V5OwotICAgICAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAwKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nQnVmZmVyIHN0ciA9IG5ldyBTdHJpbmdCdWZmZXIobXNnKTsKLSAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKCc/Jyk7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGkgPiAwKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKCcmJyk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgc3RyLmFwcGVuZChTdHJpbmcudmFsdWVPZihhcmd1bWVudHNbaV0pKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gbXNnOwotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MTWVzc2FnZUZvcm1hdHRlcl9qYS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MTWVzc2FnZUZvcm1hdHRlcl9qYS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiM2ZiODU2Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hNTE1lc3NhZ2VGb3JtYXR0ZXJfamEuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEyMyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5tc2c7Ci0KLWltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwotaW1wb3J0IGphdmEudXRpbC5NaXNzaW5nUmVzb3VyY2VFeGNlcHRpb247Ci1pbXBvcnQgamF2YS51dGlsLlJlc291cmNlQnVuZGxlOwotaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0eVJlc291cmNlQnVuZGxlOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLk1lc3NhZ2VGb3JtYXR0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlscy5TZWN1cml0eVN1cHBvcnQ7Ci0KLS8qKgotICogWE1MTWVzc2FnZUZvcm1hdHRlciBwcm92aWRlcyBlcnJvciBtZXNzYWdlcyBmb3IgdGhlIFhNTCAxLjAgUmVjb21tZW5kYXRpb24gYW5kIGZvcgotICogdGhlIE5hbWVzcGFjZXMgUmVjb21tZW5kYXRpb24KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBFcmljIFllLCBJQk0KLSAqIEB2ZXJzaW9uICRJZDogWE1MTWVzc2FnZUZvcm1hdHRlcl9qYS5qYXZhIDMwOTQgMjAxMi0wMy0yMSAwNTo1MDowMVogam9laHcgJAotICoKLSAqLwotcHVibGljIGNsYXNzIFhNTE1lc3NhZ2VGb3JtYXR0ZXJfamEgaW1wbGVtZW50cyBNZXNzYWdlRm9ybWF0dGVyIHsKLSAgICAvKioKLSAgICAgKiBUaGUgZG9tYWluIG9mIG1lc3NhZ2VzIGNvbmNlcm5pbmcgdGhlIFhNTCAxLjAgc3BlY2lmaWNhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxfRE9NQUlOID0gImh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLXhtbC0xOTk4MDIxMCI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MTlNfRE9NQUlOID0gImh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTkvUkVDLXhtbC1uYW1lcy0xOTk5MDExNCI7Ci0KLSAgICAvLyBwcml2YXRlIG9iamVjdHMgdG8gY2FjaGUgdGhlIGxvY2FsZSBhbmQgcmVzb3VyY2UgYnVuZGxlCi0gICAgcHJpdmF0ZSBMb2NhbGUgZkxvY2FsZSA9IG51bGw7Ci0gICAgcHJpdmF0ZSBSZXNvdXJjZUJ1bmRsZSBmUmVzb3VyY2VCdW5kbGUgPSBudWxsOwotCi0gICAgLy8KLSAgICAvLyBNZXNzYWdlRm9ybWF0dGVyIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogRm9ybWF0cyBhIG1lc3NhZ2Ugd2l0aCB0aGUgc3BlY2lmaWVkIGFyZ3VtZW50cyB1c2luZyB0aGUgZ2l2ZW4KLSAgICAgKiBsb2NhbGUgaW5mb3JtYXRpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbG9jYWxlICAgIFRoZSBsb2NhbGUgb2YgdGhlIG1lc3NhZ2UuCi0gICAgICogQHBhcmFtIGtleSAgICAgICBUaGUgbWVzc2FnZSBrZXkuCi0gICAgICogQHBhcmFtIGFyZ3VtZW50cyBUaGUgbWVzc2FnZSByZXBsYWNlbWVudCB0ZXh0IGFyZ3VtZW50cy4gVGhlIG9yZGVyCi0gICAgICogICAgICAgICAgICAgICAgICBvZiB0aGUgYXJndW1lbnRzIG11c3QgbWF0Y2ggdGhhdCBvZiB0aGUgcGxhY2Vob2xkZXJzCi0gICAgICogICAgICAgICAgICAgICAgICBpbiB0aGUgYWN0dWFsIG1lc3NhZ2UuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFJldHVybnMgdGhlIGZvcm1hdHRlZCBtZXNzYWdlLgotICAgICAqCi0gICAgICogQHRocm93cyBNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24gVGhyb3duIGlmIHRoZSBtZXNzYWdlIHdpdGggdGhlCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BlY2lmaWVkIGtleSBjYW5ub3QgYmUgZm91bmQuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBmb3JtYXRNZXNzYWdlKExvY2FsZSBsb2NhbGUsIFN0cmluZyBrZXksIE9iamVjdFtdIGFyZ3VtZW50cykKLSAgICAgICAgdGhyb3dzIE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgaWYgKGZSZXNvdXJjZUJ1bmRsZSA9PSBudWxsIHx8IGxvY2FsZSAhPSBmTG9jYWxlKSB7Ci0gICAgICAgICAgICBpZiAobG9jYWxlICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmUmVzb3VyY2VCdW5kbGUgPSBTZWN1cml0eVN1cHBvcnQuZ2V0UmVzb3VyY2VCdW5kbGUoImNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5tc2cuWE1MTWVzc2FnZXMiLCBsb2NhbGUpOwotICAgICAgICAgICAgICAgIC8vIG1lbW9yaXplIHRoZSBtb3N0LXJlY2VudCBsb2NhbGUKLSAgICAgICAgICAgICAgICBmTG9jYWxlID0gbG9jYWxlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKGZSZXNvdXJjZUJ1bmRsZSA9PSBudWxsKQotICAgICAgICAgICAgICAgIGZSZXNvdXJjZUJ1bmRsZSA9IFNlY3VyaXR5U3VwcG9ydC5nZXRSZXNvdXJjZUJ1bmRsZSgiY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLm1zZy5YTUxNZXNzYWdlcyIpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gZm9ybWF0IG1lc3NhZ2UKLSAgICAgICAgU3RyaW5nIG1zZzsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIG1zZyA9IGZSZXNvdXJjZUJ1bmRsZS5nZXRTdHJpbmcoa2V5KTsKLSAgICAgICAgICAgIGlmIChhcmd1bWVudHMgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgIG1zZyA9IGphdmEudGV4dC5NZXNzYWdlRm9ybWF0LmZvcm1hdChtc2csIGFyZ3VtZW50cyk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgICAgICBtc2cgPSBmUmVzb3VyY2VCdW5kbGUuZ2V0U3RyaW5nKCJGb3JtYXRGYWlsZWQiKTsKLSAgICAgICAgICAgICAgICAgICAgbXNnICs9ICIgIiArIGZSZXNvdXJjZUJ1bmRsZS5nZXRTdHJpbmcoa2V5KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBlcnJvcgotICAgICAgICBjYXRjaCAoTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIG1zZyA9IGZSZXNvdXJjZUJ1bmRsZS5nZXRTdHJpbmcoIkJhZE1lc3NhZ2VLZXkiKTsKLSAgICAgICAgICAgIHRocm93IG5ldyBNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24oa2V5LCBtc2csIGtleSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBubyBtZXNzYWdlCi0gICAgICAgIGlmIChtc2cgPT0gbnVsbCkgewotICAgICAgICAgICAgbXNnID0ga2V5OwotICAgICAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAwKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nQnVmZmVyIHN0ciA9IG5ldyBTdHJpbmdCdWZmZXIobXNnKTsKLSAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKCc/Jyk7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGkgPiAwKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKCcmJyk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgc3RyLmFwcGVuZChTdHJpbmcudmFsdWVPZihhcmd1bWVudHNbaV0pKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gbXNnOwotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MTWVzc2FnZUZvcm1hdHRlcl9rby5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MTWVzc2FnZUZvcm1hdHRlcl9rby5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzZGU3NzU3Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hNTE1lc3NhZ2VGb3JtYXR0ZXJfa28uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEyMyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5tc2c7Ci0KLWltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwotaW1wb3J0IGphdmEudXRpbC5NaXNzaW5nUmVzb3VyY2VFeGNlcHRpb247Ci1pbXBvcnQgamF2YS51dGlsLlJlc291cmNlQnVuZGxlOwotaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0eVJlc291cmNlQnVuZGxlOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLk1lc3NhZ2VGb3JtYXR0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlscy5TZWN1cml0eVN1cHBvcnQ7Ci0KLS8qKgotICogWE1MTWVzc2FnZUZvcm1hdHRlciBwcm92aWRlcyBlcnJvciBtZXNzYWdlcyBmb3IgdGhlIFhNTCAxLjAgUmVjb21tZW5kYXRpb24gYW5kIGZvcgotICogdGhlIE5hbWVzcGFjZXMgUmVjb21tZW5kYXRpb24KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBFcmljIFllLCBJQk0KLSAqIEB2ZXJzaW9uICRJZDogWE1MTWVzc2FnZUZvcm1hdHRlcl9rby5qYXZhIDMwOTQgMjAxMi0wMy0yMSAwNTo1MDowMVogam9laHcgJAotICoKLSAqLwotcHVibGljIGNsYXNzIFhNTE1lc3NhZ2VGb3JtYXR0ZXJfa28gaW1wbGVtZW50cyBNZXNzYWdlRm9ybWF0dGVyIHsKLSAgICAvKioKLSAgICAgKiBUaGUgZG9tYWluIG9mIG1lc3NhZ2VzIGNvbmNlcm5pbmcgdGhlIFhNTCAxLjAgc3BlY2lmaWNhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxfRE9NQUlOID0gImh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLXhtbC0xOTk4MDIxMCI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MTlNfRE9NQUlOID0gImh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTkvUkVDLXhtbC1uYW1lcy0xOTk5MDExNCI7Ci0KLSAgICAvLyBwcml2YXRlIG9iamVjdHMgdG8gY2FjaGUgdGhlIGxvY2FsZSBhbmQgcmVzb3VyY2UgYnVuZGxlCi0gICAgcHJpdmF0ZSBMb2NhbGUgZkxvY2FsZSA9IG51bGw7Ci0gICAgcHJpdmF0ZSBSZXNvdXJjZUJ1bmRsZSBmUmVzb3VyY2VCdW5kbGUgPSBudWxsOwotCi0gICAgLy8KLSAgICAvLyBNZXNzYWdlRm9ybWF0dGVyIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogRm9ybWF0cyBhIG1lc3NhZ2Ugd2l0aCB0aGUgc3BlY2lmaWVkIGFyZ3VtZW50cyB1c2luZyB0aGUgZ2l2ZW4KLSAgICAgKiBsb2NhbGUgaW5mb3JtYXRpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbG9jYWxlICAgIFRoZSBsb2NhbGUgb2YgdGhlIG1lc3NhZ2UuCi0gICAgICogQHBhcmFtIGtleSAgICAgICBUaGUgbWVzc2FnZSBrZXkuCi0gICAgICogQHBhcmFtIGFyZ3VtZW50cyBUaGUgbWVzc2FnZSByZXBsYWNlbWVudCB0ZXh0IGFyZ3VtZW50cy4gVGhlIG9yZGVyCi0gICAgICogICAgICAgICAgICAgICAgICBvZiB0aGUgYXJndW1lbnRzIG11c3QgbWF0Y2ggdGhhdCBvZiB0aGUgcGxhY2Vob2xkZXJzCi0gICAgICogICAgICAgICAgICAgICAgICBpbiB0aGUgYWN0dWFsIG1lc3NhZ2UuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFJldHVybnMgdGhlIGZvcm1hdHRlZCBtZXNzYWdlLgotICAgICAqCi0gICAgICogQHRocm93cyBNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24gVGhyb3duIGlmIHRoZSBtZXNzYWdlIHdpdGggdGhlCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BlY2lmaWVkIGtleSBjYW5ub3QgYmUgZm91bmQuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBmb3JtYXRNZXNzYWdlKExvY2FsZSBsb2NhbGUsIFN0cmluZyBrZXksIE9iamVjdFtdIGFyZ3VtZW50cykKLSAgICAgICAgdGhyb3dzIE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgaWYgKGZSZXNvdXJjZUJ1bmRsZSA9PSBudWxsIHx8IGxvY2FsZSAhPSBmTG9jYWxlKSB7Ci0gICAgICAgICAgICBpZiAobG9jYWxlICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmUmVzb3VyY2VCdW5kbGUgPSBTZWN1cml0eVN1cHBvcnQuZ2V0UmVzb3VyY2VCdW5kbGUoImNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5tc2cuWE1MTWVzc2FnZXMiLCBsb2NhbGUpOwotICAgICAgICAgICAgICAgIC8vIG1lbW9yaXplIHRoZSBtb3N0LXJlY2VudCBsb2NhbGUKLSAgICAgICAgICAgICAgICBmTG9jYWxlID0gbG9jYWxlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKGZSZXNvdXJjZUJ1bmRsZSA9PSBudWxsKQotICAgICAgICAgICAgICAgIGZSZXNvdXJjZUJ1bmRsZSA9IFNlY3VyaXR5U3VwcG9ydC5nZXRSZXNvdXJjZUJ1bmRsZSgiY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLm1zZy5YTUxNZXNzYWdlcyIpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gZm9ybWF0IG1lc3NhZ2UKLSAgICAgICAgU3RyaW5nIG1zZzsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIG1zZyA9IGZSZXNvdXJjZUJ1bmRsZS5nZXRTdHJpbmcoa2V5KTsKLSAgICAgICAgICAgIGlmIChhcmd1bWVudHMgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgIG1zZyA9IGphdmEudGV4dC5NZXNzYWdlRm9ybWF0LmZvcm1hdChtc2csIGFyZ3VtZW50cyk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgICAgICBtc2cgPSBmUmVzb3VyY2VCdW5kbGUuZ2V0U3RyaW5nKCJGb3JtYXRGYWlsZWQiKTsKLSAgICAgICAgICAgICAgICAgICAgbXNnICs9ICIgIiArIGZSZXNvdXJjZUJ1bmRsZS5nZXRTdHJpbmcoa2V5KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBlcnJvcgotICAgICAgICBjYXRjaCAoTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIG1zZyA9IGZSZXNvdXJjZUJ1bmRsZS5nZXRTdHJpbmcoIkJhZE1lc3NhZ2VLZXkiKTsKLSAgICAgICAgICAgIHRocm93IG5ldyBNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24oa2V5LCBtc2csIGtleSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBubyBtZXNzYWdlCi0gICAgICAgIGlmIChtc2cgPT0gbnVsbCkgewotICAgICAgICAgICAgbXNnID0ga2V5OwotICAgICAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAwKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nQnVmZmVyIHN0ciA9IG5ldyBTdHJpbmdCdWZmZXIobXNnKTsKLSAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKCc/Jyk7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGkgPiAwKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKCcmJyk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgc3RyLmFwcGVuZChTdHJpbmcudmFsdWVPZihhcmd1bWVudHNbaV0pKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gbXNnOwotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MTWVzc2FnZUZvcm1hdHRlcl9wdF9CUi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MTWVzc2FnZUZvcm1hdHRlcl9wdF9CUi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1OWIzZDFkLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hNTE1lc3NhZ2VGb3JtYXR0ZXJfcHRfQlIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEyMyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5tc2c7Ci0KLWltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwotaW1wb3J0IGphdmEudXRpbC5NaXNzaW5nUmVzb3VyY2VFeGNlcHRpb247Ci1pbXBvcnQgamF2YS51dGlsLlJlc291cmNlQnVuZGxlOwotaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0eVJlc291cmNlQnVuZGxlOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLk1lc3NhZ2VGb3JtYXR0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlscy5TZWN1cml0eVN1cHBvcnQ7Ci0KLS8qKgotICogWE1MTWVzc2FnZUZvcm1hdHRlciBwcm92aWRlcyBlcnJvciBtZXNzYWdlcyBmb3IgdGhlIFhNTCAxLjAgUmVjb21tZW5kYXRpb24gYW5kIGZvcgotICogdGhlIE5hbWVzcGFjZXMgUmVjb21tZW5kYXRpb24KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBFcmljIFllLCBJQk0KLSAqIEB2ZXJzaW9uICRJZDogWE1MTWVzc2FnZUZvcm1hdHRlcl9wdF9CUi5qYXZhIDMwOTQgMjAxMi0wMy0yMSAwNTo1MDowMVogam9laHcgJAotICoKLSAqLwotcHVibGljIGNsYXNzIFhNTE1lc3NhZ2VGb3JtYXR0ZXJfcHRfQlIgaW1wbGVtZW50cyBNZXNzYWdlRm9ybWF0dGVyIHsKLSAgICAvKioKLSAgICAgKiBUaGUgZG9tYWluIG9mIG1lc3NhZ2VzIGNvbmNlcm5pbmcgdGhlIFhNTCAxLjAgc3BlY2lmaWNhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxfRE9NQUlOID0gImh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLXhtbC0xOTk4MDIxMCI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MTlNfRE9NQUlOID0gImh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTkvUkVDLXhtbC1uYW1lcy0xOTk5MDExNCI7Ci0KLSAgICAvLyBwcml2YXRlIG9iamVjdHMgdG8gY2FjaGUgdGhlIGxvY2FsZSBhbmQgcmVzb3VyY2UgYnVuZGxlCi0gICAgcHJpdmF0ZSBMb2NhbGUgZkxvY2FsZSA9IG51bGw7Ci0gICAgcHJpdmF0ZSBSZXNvdXJjZUJ1bmRsZSBmUmVzb3VyY2VCdW5kbGUgPSBudWxsOwotCi0gICAgLy8KLSAgICAvLyBNZXNzYWdlRm9ybWF0dGVyIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogRm9ybWF0cyBhIG1lc3NhZ2Ugd2l0aCB0aGUgc3BlY2lmaWVkIGFyZ3VtZW50cyB1c2luZyB0aGUgZ2l2ZW4KLSAgICAgKiBsb2NhbGUgaW5mb3JtYXRpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbG9jYWxlICAgIFRoZSBsb2NhbGUgb2YgdGhlIG1lc3NhZ2UuCi0gICAgICogQHBhcmFtIGtleSAgICAgICBUaGUgbWVzc2FnZSBrZXkuCi0gICAgICogQHBhcmFtIGFyZ3VtZW50cyBUaGUgbWVzc2FnZSByZXBsYWNlbWVudCB0ZXh0IGFyZ3VtZW50cy4gVGhlIG9yZGVyCi0gICAgICogICAgICAgICAgICAgICAgICBvZiB0aGUgYXJndW1lbnRzIG11c3QgbWF0Y2ggdGhhdCBvZiB0aGUgcGxhY2Vob2xkZXJzCi0gICAgICogICAgICAgICAgICAgICAgICBpbiB0aGUgYWN0dWFsIG1lc3NhZ2UuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFJldHVybnMgdGhlIGZvcm1hdHRlZCBtZXNzYWdlLgotICAgICAqCi0gICAgICogQHRocm93cyBNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24gVGhyb3duIGlmIHRoZSBtZXNzYWdlIHdpdGggdGhlCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BlY2lmaWVkIGtleSBjYW5ub3QgYmUgZm91bmQuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBmb3JtYXRNZXNzYWdlKExvY2FsZSBsb2NhbGUsIFN0cmluZyBrZXksIE9iamVjdFtdIGFyZ3VtZW50cykKLSAgICAgICAgdGhyb3dzIE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgaWYgKGZSZXNvdXJjZUJ1bmRsZSA9PSBudWxsIHx8IGxvY2FsZSAhPSBmTG9jYWxlKSB7Ci0gICAgICAgICAgICBpZiAobG9jYWxlICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmUmVzb3VyY2VCdW5kbGUgPSBTZWN1cml0eVN1cHBvcnQuZ2V0UmVzb3VyY2VCdW5kbGUoImNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5tc2cuWE1MTWVzc2FnZXMiLCBsb2NhbGUpOwotICAgICAgICAgICAgICAgIC8vIG1lbW9yaXplIHRoZSBtb3N0LXJlY2VudCBsb2NhbGUKLSAgICAgICAgICAgICAgICBmTG9jYWxlID0gbG9jYWxlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKGZSZXNvdXJjZUJ1bmRsZSA9PSBudWxsKQotICAgICAgICAgICAgICAgIGZSZXNvdXJjZUJ1bmRsZSA9IFNlY3VyaXR5U3VwcG9ydC5nZXRSZXNvdXJjZUJ1bmRsZSgiY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLm1zZy5YTUxNZXNzYWdlcyIpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gZm9ybWF0IG1lc3NhZ2UKLSAgICAgICAgU3RyaW5nIG1zZzsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIG1zZyA9IGZSZXNvdXJjZUJ1bmRsZS5nZXRTdHJpbmcoa2V5KTsKLSAgICAgICAgICAgIGlmIChhcmd1bWVudHMgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgIG1zZyA9IGphdmEudGV4dC5NZXNzYWdlRm9ybWF0LmZvcm1hdChtc2csIGFyZ3VtZW50cyk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgICAgICBtc2cgPSBmUmVzb3VyY2VCdW5kbGUuZ2V0U3RyaW5nKCJGb3JtYXRGYWlsZWQiKTsKLSAgICAgICAgICAgICAgICAgICAgbXNnICs9ICIgIiArIGZSZXNvdXJjZUJ1bmRsZS5nZXRTdHJpbmcoa2V5KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBlcnJvcgotICAgICAgICBjYXRjaCAoTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIG1zZyA9IGZSZXNvdXJjZUJ1bmRsZS5nZXRTdHJpbmcoIkJhZE1lc3NhZ2VLZXkiKTsKLSAgICAgICAgICAgIHRocm93IG5ldyBNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24oa2V5LCBtc2csIGtleSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBubyBtZXNzYWdlCi0gICAgICAgIGlmIChtc2cgPT0gbnVsbCkgewotICAgICAgICAgICAgbXNnID0ga2V5OwotICAgICAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAwKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nQnVmZmVyIHN0ciA9IG5ldyBTdHJpbmdCdWZmZXIobXNnKTsKLSAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKCc/Jyk7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGkgPiAwKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKCcmJyk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgc3RyLmFwcGVuZChTdHJpbmcudmFsdWVPZihhcmd1bWVudHNbaV0pKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gbXNnOwotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MTWVzc2FnZUZvcm1hdHRlcl9zdi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MTWVzc2FnZUZvcm1hdHRlcl9zdi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDIxN2FlLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hNTE1lc3NhZ2VGb3JtYXR0ZXJfc3YuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEyMyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5tc2c7Ci0KLWltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwotaW1wb3J0IGphdmEudXRpbC5NaXNzaW5nUmVzb3VyY2VFeGNlcHRpb247Ci1pbXBvcnQgamF2YS51dGlsLlJlc291cmNlQnVuZGxlOwotaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0eVJlc291cmNlQnVuZGxlOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLk1lc3NhZ2VGb3JtYXR0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlscy5TZWN1cml0eVN1cHBvcnQ7Ci0KLS8qKgotICogWE1MTWVzc2FnZUZvcm1hdHRlciBwcm92aWRlcyBlcnJvciBtZXNzYWdlcyBmb3IgdGhlIFhNTCAxLjAgUmVjb21tZW5kYXRpb24gYW5kIGZvcgotICogdGhlIE5hbWVzcGFjZXMgUmVjb21tZW5kYXRpb24KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBFcmljIFllLCBJQk0KLSAqIEB2ZXJzaW9uICRJZDogWE1MTWVzc2FnZUZvcm1hdHRlcl9zdi5qYXZhIDMwOTQgMjAxMi0wMy0yMSAwNTo1MDowMVogam9laHcgJAotICoKLSAqLwotcHVibGljIGNsYXNzIFhNTE1lc3NhZ2VGb3JtYXR0ZXJfc3YgaW1wbGVtZW50cyBNZXNzYWdlRm9ybWF0dGVyIHsKLSAgICAvKioKLSAgICAgKiBUaGUgZG9tYWluIG9mIG1lc3NhZ2VzIGNvbmNlcm5pbmcgdGhlIFhNTCAxLjAgc3BlY2lmaWNhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxfRE9NQUlOID0gImh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLXhtbC0xOTk4MDIxMCI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MTlNfRE9NQUlOID0gImh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTkvUkVDLXhtbC1uYW1lcy0xOTk5MDExNCI7Ci0KLSAgICAvLyBwcml2YXRlIG9iamVjdHMgdG8gY2FjaGUgdGhlIGxvY2FsZSBhbmQgcmVzb3VyY2UgYnVuZGxlCi0gICAgcHJpdmF0ZSBMb2NhbGUgZkxvY2FsZSA9IG51bGw7Ci0gICAgcHJpdmF0ZSBSZXNvdXJjZUJ1bmRsZSBmUmVzb3VyY2VCdW5kbGUgPSBudWxsOwotCi0gICAgLy8KLSAgICAvLyBNZXNzYWdlRm9ybWF0dGVyIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogRm9ybWF0cyBhIG1lc3NhZ2Ugd2l0aCB0aGUgc3BlY2lmaWVkIGFyZ3VtZW50cyB1c2luZyB0aGUgZ2l2ZW4KLSAgICAgKiBsb2NhbGUgaW5mb3JtYXRpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbG9jYWxlICAgIFRoZSBsb2NhbGUgb2YgdGhlIG1lc3NhZ2UuCi0gICAgICogQHBhcmFtIGtleSAgICAgICBUaGUgbWVzc2FnZSBrZXkuCi0gICAgICogQHBhcmFtIGFyZ3VtZW50cyBUaGUgbWVzc2FnZSByZXBsYWNlbWVudCB0ZXh0IGFyZ3VtZW50cy4gVGhlIG9yZGVyCi0gICAgICogICAgICAgICAgICAgICAgICBvZiB0aGUgYXJndW1lbnRzIG11c3QgbWF0Y2ggdGhhdCBvZiB0aGUgcGxhY2Vob2xkZXJzCi0gICAgICogICAgICAgICAgICAgICAgICBpbiB0aGUgYWN0dWFsIG1lc3NhZ2UuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFJldHVybnMgdGhlIGZvcm1hdHRlZCBtZXNzYWdlLgotICAgICAqCi0gICAgICogQHRocm93cyBNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24gVGhyb3duIGlmIHRoZSBtZXNzYWdlIHdpdGggdGhlCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BlY2lmaWVkIGtleSBjYW5ub3QgYmUgZm91bmQuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBmb3JtYXRNZXNzYWdlKExvY2FsZSBsb2NhbGUsIFN0cmluZyBrZXksIE9iamVjdFtdIGFyZ3VtZW50cykKLSAgICAgICAgdGhyb3dzIE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgaWYgKGZSZXNvdXJjZUJ1bmRsZSA9PSBudWxsIHx8IGxvY2FsZSAhPSBmTG9jYWxlKSB7Ci0gICAgICAgICAgICBpZiAobG9jYWxlICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmUmVzb3VyY2VCdW5kbGUgPSBTZWN1cml0eVN1cHBvcnQuZ2V0UmVzb3VyY2VCdW5kbGUoImNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5tc2cuWE1MTWVzc2FnZXMiLCBsb2NhbGUpOwotICAgICAgICAgICAgICAgIC8vIG1lbW9yaXplIHRoZSBtb3N0LXJlY2VudCBsb2NhbGUKLSAgICAgICAgICAgICAgICBmTG9jYWxlID0gbG9jYWxlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKGZSZXNvdXJjZUJ1bmRsZSA9PSBudWxsKQotICAgICAgICAgICAgICAgIGZSZXNvdXJjZUJ1bmRsZSA9IFNlY3VyaXR5U3VwcG9ydC5nZXRSZXNvdXJjZUJ1bmRsZSgiY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLm1zZy5YTUxNZXNzYWdlcyIpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gZm9ybWF0IG1lc3NhZ2UKLSAgICAgICAgU3RyaW5nIG1zZzsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIG1zZyA9IGZSZXNvdXJjZUJ1bmRsZS5nZXRTdHJpbmcoa2V5KTsKLSAgICAgICAgICAgIGlmIChhcmd1bWVudHMgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgIG1zZyA9IGphdmEudGV4dC5NZXNzYWdlRm9ybWF0LmZvcm1hdChtc2csIGFyZ3VtZW50cyk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgICAgICBtc2cgPSBmUmVzb3VyY2VCdW5kbGUuZ2V0U3RyaW5nKCJGb3JtYXRGYWlsZWQiKTsKLSAgICAgICAgICAgICAgICAgICAgbXNnICs9ICIgIiArIGZSZXNvdXJjZUJ1bmRsZS5nZXRTdHJpbmcoa2V5KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBlcnJvcgotICAgICAgICBjYXRjaCAoTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIG1zZyA9IGZSZXNvdXJjZUJ1bmRsZS5nZXRTdHJpbmcoIkJhZE1lc3NhZ2VLZXkiKTsKLSAgICAgICAgICAgIHRocm93IG5ldyBNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24oa2V5LCBtc2csIGtleSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBubyBtZXNzYWdlCi0gICAgICAgIGlmIChtc2cgPT0gbnVsbCkgewotICAgICAgICAgICAgbXNnID0ga2V5OwotICAgICAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAwKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nQnVmZmVyIHN0ciA9IG5ldyBTdHJpbmdCdWZmZXIobXNnKTsKLSAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKCc/Jyk7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGkgPiAwKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKCcmJyk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgc3RyLmFwcGVuZChTdHJpbmcudmFsdWVPZihhcmd1bWVudHNbaV0pKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gbXNnOwotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MTWVzc2FnZUZvcm1hdHRlcl96aF9DTi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MTWVzc2FnZUZvcm1hdHRlcl96aF9DTi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0Y2ZhOTY4Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hNTE1lc3NhZ2VGb3JtYXR0ZXJfemhfQ04uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEyMyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5tc2c7Ci0KLWltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwotaW1wb3J0IGphdmEudXRpbC5NaXNzaW5nUmVzb3VyY2VFeGNlcHRpb247Ci1pbXBvcnQgamF2YS51dGlsLlJlc291cmNlQnVuZGxlOwotaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0eVJlc291cmNlQnVuZGxlOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLk1lc3NhZ2VGb3JtYXR0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlscy5TZWN1cml0eVN1cHBvcnQ7Ci0KLS8qKgotICogWE1MTWVzc2FnZUZvcm1hdHRlciBwcm92aWRlcyBlcnJvciBtZXNzYWdlcyBmb3IgdGhlIFhNTCAxLjAgUmVjb21tZW5kYXRpb24gYW5kIGZvcgotICogdGhlIE5hbWVzcGFjZXMgUmVjb21tZW5kYXRpb24KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBFcmljIFllLCBJQk0KLSAqIEB2ZXJzaW9uICRJZDogWE1MTWVzc2FnZUZvcm1hdHRlcl96aF9DTi5qYXZhIDMwOTQgMjAxMi0wMy0yMSAwNTo1MDowMVogam9laHcgJAotICoKLSAqLwotcHVibGljIGNsYXNzIFhNTE1lc3NhZ2VGb3JtYXR0ZXJfemhfQ04gaW1wbGVtZW50cyBNZXNzYWdlRm9ybWF0dGVyIHsKLSAgICAvKioKLSAgICAgKiBUaGUgZG9tYWluIG9mIG1lc3NhZ2VzIGNvbmNlcm5pbmcgdGhlIFhNTCAxLjAgc3BlY2lmaWNhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxfRE9NQUlOID0gImh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLXhtbC0xOTk4MDIxMCI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MTlNfRE9NQUlOID0gImh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTkvUkVDLXhtbC1uYW1lcy0xOTk5MDExNCI7Ci0KLSAgICAvLyBwcml2YXRlIG9iamVjdHMgdG8gY2FjaGUgdGhlIGxvY2FsZSBhbmQgcmVzb3VyY2UgYnVuZGxlCi0gICAgcHJpdmF0ZSBMb2NhbGUgZkxvY2FsZSA9IG51bGw7Ci0gICAgcHJpdmF0ZSBSZXNvdXJjZUJ1bmRsZSBmUmVzb3VyY2VCdW5kbGUgPSBudWxsOwotCi0gICAgLy8KLSAgICAvLyBNZXNzYWdlRm9ybWF0dGVyIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogRm9ybWF0cyBhIG1lc3NhZ2Ugd2l0aCB0aGUgc3BlY2lmaWVkIGFyZ3VtZW50cyB1c2luZyB0aGUgZ2l2ZW4KLSAgICAgKiBsb2NhbGUgaW5mb3JtYXRpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbG9jYWxlICAgIFRoZSBsb2NhbGUgb2YgdGhlIG1lc3NhZ2UuCi0gICAgICogQHBhcmFtIGtleSAgICAgICBUaGUgbWVzc2FnZSBrZXkuCi0gICAgICogQHBhcmFtIGFyZ3VtZW50cyBUaGUgbWVzc2FnZSByZXBsYWNlbWVudCB0ZXh0IGFyZ3VtZW50cy4gVGhlIG9yZGVyCi0gICAgICogICAgICAgICAgICAgICAgICBvZiB0aGUgYXJndW1lbnRzIG11c3QgbWF0Y2ggdGhhdCBvZiB0aGUgcGxhY2Vob2xkZXJzCi0gICAgICogICAgICAgICAgICAgICAgICBpbiB0aGUgYWN0dWFsIG1lc3NhZ2UuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFJldHVybnMgdGhlIGZvcm1hdHRlZCBtZXNzYWdlLgotICAgICAqCi0gICAgICogQHRocm93cyBNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24gVGhyb3duIGlmIHRoZSBtZXNzYWdlIHdpdGggdGhlCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BlY2lmaWVkIGtleSBjYW5ub3QgYmUgZm91bmQuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBmb3JtYXRNZXNzYWdlKExvY2FsZSBsb2NhbGUsIFN0cmluZyBrZXksIE9iamVjdFtdIGFyZ3VtZW50cykKLSAgICAgICAgdGhyb3dzIE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgaWYgKGZSZXNvdXJjZUJ1bmRsZSA9PSBudWxsIHx8IGxvY2FsZSAhPSBmTG9jYWxlKSB7Ci0gICAgICAgICAgICBpZiAobG9jYWxlICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmUmVzb3VyY2VCdW5kbGUgPSBTZWN1cml0eVN1cHBvcnQuZ2V0UmVzb3VyY2VCdW5kbGUoImNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5tc2cuWE1MTWVzc2FnZXMiLCBsb2NhbGUpOwotICAgICAgICAgICAgICAgIC8vIG1lbW9yaXplIHRoZSBtb3N0LXJlY2VudCBsb2NhbGUKLSAgICAgICAgICAgICAgICBmTG9jYWxlID0gbG9jYWxlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKGZSZXNvdXJjZUJ1bmRsZSA9PSBudWxsKQotICAgICAgICAgICAgICAgIGZSZXNvdXJjZUJ1bmRsZSA9IFNlY3VyaXR5U3VwcG9ydC5nZXRSZXNvdXJjZUJ1bmRsZSgiY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLm1zZy5YTUxNZXNzYWdlcyIpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gZm9ybWF0IG1lc3NhZ2UKLSAgICAgICAgU3RyaW5nIG1zZzsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIG1zZyA9IGZSZXNvdXJjZUJ1bmRsZS5nZXRTdHJpbmcoa2V5KTsKLSAgICAgICAgICAgIGlmIChhcmd1bWVudHMgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgIG1zZyA9IGphdmEudGV4dC5NZXNzYWdlRm9ybWF0LmZvcm1hdChtc2csIGFyZ3VtZW50cyk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgICAgICBtc2cgPSBmUmVzb3VyY2VCdW5kbGUuZ2V0U3RyaW5nKCJGb3JtYXRGYWlsZWQiKTsKLSAgICAgICAgICAgICAgICAgICAgbXNnICs9ICIgIiArIGZSZXNvdXJjZUJ1bmRsZS5nZXRTdHJpbmcoa2V5KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBlcnJvcgotICAgICAgICBjYXRjaCAoTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIG1zZyA9IGZSZXNvdXJjZUJ1bmRsZS5nZXRTdHJpbmcoIkJhZE1lc3NhZ2VLZXkiKTsKLSAgICAgICAgICAgIHRocm93IG5ldyBNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24oa2V5LCBtc2csIGtleSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBubyBtZXNzYWdlCi0gICAgICAgIGlmIChtc2cgPT0gbnVsbCkgewotICAgICAgICAgICAgbXNnID0ga2V5OwotICAgICAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAwKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nQnVmZmVyIHN0ciA9IG5ldyBTdHJpbmdCdWZmZXIobXNnKTsKLSAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKCc/Jyk7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGkgPiAwKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKCcmJyk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgc3RyLmFwcGVuZChTdHJpbmcudmFsdWVPZihhcmd1bWVudHNbaV0pKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gbXNnOwotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MTWVzc2FnZUZvcm1hdHRlcl96aF9UVy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MTWVzc2FnZUZvcm1hdHRlcl96aF9UVy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0ZjM0ZmEyLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hNTE1lc3NhZ2VGb3JtYXR0ZXJfemhfVFcuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEyMyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5tc2c7Ci0KLWltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwotaW1wb3J0IGphdmEudXRpbC5NaXNzaW5nUmVzb3VyY2VFeGNlcHRpb247Ci1pbXBvcnQgamF2YS51dGlsLlJlc291cmNlQnVuZGxlOwotaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0eVJlc291cmNlQnVuZGxlOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLk1lc3NhZ2VGb3JtYXR0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlscy5TZWN1cml0eVN1cHBvcnQ7Ci0KLS8qKgotICogWE1MTWVzc2FnZUZvcm1hdHRlciBwcm92aWRlcyBlcnJvciBtZXNzYWdlcyBmb3IgdGhlIFhNTCAxLjAgUmVjb21tZW5kYXRpb24gYW5kIGZvcgotICogdGhlIE5hbWVzcGFjZXMgUmVjb21tZW5kYXRpb24KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBFcmljIFllLCBJQk0KLSAqIEB2ZXJzaW9uICRJZDogWE1MTWVzc2FnZUZvcm1hdHRlcl96aF9UVy5qYXZhIDMwOTQgMjAxMi0wMy0yMSAwNTo1MDowMVogam9laHcgJAotICoKLSAqLwotcHVibGljIGNsYXNzIFhNTE1lc3NhZ2VGb3JtYXR0ZXJfemhfVFcgaW1wbGVtZW50cyBNZXNzYWdlRm9ybWF0dGVyIHsKLSAgICAvKioKLSAgICAgKiBUaGUgZG9tYWluIG9mIG1lc3NhZ2VzIGNvbmNlcm5pbmcgdGhlIFhNTCAxLjAgc3BlY2lmaWNhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxfRE9NQUlOID0gImh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLXhtbC0xOTk4MDIxMCI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MTlNfRE9NQUlOID0gImh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTkvUkVDLXhtbC1uYW1lcy0xOTk5MDExNCI7Ci0KLSAgICAvLyBwcml2YXRlIG9iamVjdHMgdG8gY2FjaGUgdGhlIGxvY2FsZSBhbmQgcmVzb3VyY2UgYnVuZGxlCi0gICAgcHJpdmF0ZSBMb2NhbGUgZkxvY2FsZSA9IG51bGw7Ci0gICAgcHJpdmF0ZSBSZXNvdXJjZUJ1bmRsZSBmUmVzb3VyY2VCdW5kbGUgPSBudWxsOwotCi0gICAgLy8KLSAgICAvLyBNZXNzYWdlRm9ybWF0dGVyIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogRm9ybWF0cyBhIG1lc3NhZ2Ugd2l0aCB0aGUgc3BlY2lmaWVkIGFyZ3VtZW50cyB1c2luZyB0aGUgZ2l2ZW4KLSAgICAgKiBsb2NhbGUgaW5mb3JtYXRpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbG9jYWxlICAgIFRoZSBsb2NhbGUgb2YgdGhlIG1lc3NhZ2UuCi0gICAgICogQHBhcmFtIGtleSAgICAgICBUaGUgbWVzc2FnZSBrZXkuCi0gICAgICogQHBhcmFtIGFyZ3VtZW50cyBUaGUgbWVzc2FnZSByZXBsYWNlbWVudCB0ZXh0IGFyZ3VtZW50cy4gVGhlIG9yZGVyCi0gICAgICogICAgICAgICAgICAgICAgICBvZiB0aGUgYXJndW1lbnRzIG11c3QgbWF0Y2ggdGhhdCBvZiB0aGUgcGxhY2Vob2xkZXJzCi0gICAgICogICAgICAgICAgICAgICAgICBpbiB0aGUgYWN0dWFsIG1lc3NhZ2UuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFJldHVybnMgdGhlIGZvcm1hdHRlZCBtZXNzYWdlLgotICAgICAqCi0gICAgICogQHRocm93cyBNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24gVGhyb3duIGlmIHRoZSBtZXNzYWdlIHdpdGggdGhlCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BlY2lmaWVkIGtleSBjYW5ub3QgYmUgZm91bmQuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBmb3JtYXRNZXNzYWdlKExvY2FsZSBsb2NhbGUsIFN0cmluZyBrZXksIE9iamVjdFtdIGFyZ3VtZW50cykKLSAgICAgICAgdGhyb3dzIE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgaWYgKGZSZXNvdXJjZUJ1bmRsZSA9PSBudWxsIHx8IGxvY2FsZSAhPSBmTG9jYWxlKSB7Ci0gICAgICAgICAgICBpZiAobG9jYWxlICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmUmVzb3VyY2VCdW5kbGUgPSBTZWN1cml0eVN1cHBvcnQuZ2V0UmVzb3VyY2VCdW5kbGUoImNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5tc2cuWE1MTWVzc2FnZXMiLCBsb2NhbGUpOwotICAgICAgICAgICAgICAgIC8vIG1lbW9yaXplIHRoZSBtb3N0LXJlY2VudCBsb2NhbGUKLSAgICAgICAgICAgICAgICBmTG9jYWxlID0gbG9jYWxlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKGZSZXNvdXJjZUJ1bmRsZSA9PSBudWxsKQotICAgICAgICAgICAgICAgIGZSZXNvdXJjZUJ1bmRsZSA9IFNlY3VyaXR5U3VwcG9ydC5nZXRSZXNvdXJjZUJ1bmRsZSgiY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLm1zZy5YTUxNZXNzYWdlcyIpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gZm9ybWF0IG1lc3NhZ2UKLSAgICAgICAgU3RyaW5nIG1zZzsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIG1zZyA9IGZSZXNvdXJjZUJ1bmRsZS5nZXRTdHJpbmcoa2V5KTsKLSAgICAgICAgICAgIGlmIChhcmd1bWVudHMgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgIG1zZyA9IGphdmEudGV4dC5NZXNzYWdlRm9ybWF0LmZvcm1hdChtc2csIGFyZ3VtZW50cyk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgICAgICBtc2cgPSBmUmVzb3VyY2VCdW5kbGUuZ2V0U3RyaW5nKCJGb3JtYXRGYWlsZWQiKTsKLSAgICAgICAgICAgICAgICAgICAgbXNnICs9ICIgIiArIGZSZXNvdXJjZUJ1bmRsZS5nZXRTdHJpbmcoa2V5KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBlcnJvcgotICAgICAgICBjYXRjaCAoTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIG1zZyA9IGZSZXNvdXJjZUJ1bmRsZS5nZXRTdHJpbmcoIkJhZE1lc3NhZ2VLZXkiKTsKLSAgICAgICAgICAgIHRocm93IG5ldyBNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24oa2V5LCBtc2csIGtleSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBubyBtZXNzYWdlCi0gICAgICAgIGlmIChtc2cgPT0gbnVsbCkgewotICAgICAgICAgICAgbXNnID0ga2V5OwotICAgICAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAwKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nQnVmZmVyIHN0ciA9IG5ldyBTdHJpbmdCdWZmZXIobXNnKTsKLSAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKCc/Jyk7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGkgPiAwKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKCcmJyk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgc3RyLmFwcGVuZChTdHJpbmcudmFsdWVPZihhcmd1bWVudHNbaV0pKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gbXNnOwotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MTWVzc2FnZXMucHJvcGVydGllcyBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hNTE1lc3NhZ2VzLnByb3BlcnRpZXMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAxNTMxZjcuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MTWVzc2FnZXMucHJvcGVydGllcworKysgL2Rldi9udWxsCkBAIC0xLDMwNSArMCwwIEBACi0jIFRoaXMgZmlsZSBjb250YWlucyBlcnJvciBhbmQgd2FybmluZyBtZXNzYWdlcyByZWxhdGVkIHRvIFhNTAotIyBUaGUgbWVzc2FnZXMgYXJlIGFycmFuZ2VkIGluIGtleSBhbmQgdmFsdWUgdHVwbGVzIGluIGEgTGlzdFJlc291cmNlQnVuZGxlLgotIwotIyBAdmVyc2lvbgotCi0gICAgICAgIEJhZE1lc3NhZ2VLZXkgPSBUaGUgZXJyb3IgbWVzc2FnZSBjb3JyZXNwb25kaW5nIHRvIHRoZSBtZXNzYWdlIGtleSBjYW4gbm90IGJlIGZvdW5kLgotICAgICAgICBGb3JtYXRGYWlsZWQgPSBBbiBpbnRlcm5hbCBlcnJvciBvY2N1cnJlZCB3aGlsZSBmb3JtYXR0aW5nIHRoZSBmb2xsb3dpbmcgbWVzc2FnZTpcbiAgCi0gICAgICAgIAotIyBEb2N1bWVudCBtZXNzYWdlcwotICAgICAgICBQcmVtYXR1cmVFT0Y9UHJlbWF0dXJlIGVuZCBvZiBmaWxlLgotIyAyLjEgV2VsbC1Gb3JtZWQgWE1MIERvY3VtZW50cwotICAgICAgICBSb290RWxlbWVudFJlcXVpcmVkID0gVGhlIHJvb3QgZWxlbWVudCBpcyByZXF1aXJlZCBpbiBhIHdlbGwtZm9ybWVkIGRvY3VtZW50LgotIyAyLjIgQ2hhcmFjdGVycwotCi0gICAgICAgIEludmFsaWRDaGFySW5DRFNlY3QgPSBBbiBpbnZhbGlkIFhNTCBjaGFyYWN0ZXIgKFVuaWNvZGU6IDB4ezB9KSB3YXMgZm91bmQgaW4gdGhlIENEQVRBIHNlY3Rpb24uCi0gICAgICAgIEludmFsaWRDaGFySW5Db250ZW50ID0gQW4gaW52YWxpZCBYTUwgY2hhcmFjdGVyIChVbmljb2RlOiAweHswfSkgd2FzIGZvdW5kIGluIHRoZSBlbGVtZW50IGNvbnRlbnQgb2YgdGhlIGRvY3VtZW50LgotICAgICAgICBUd29Db2xvbnNJblFOYW1lID0gQW4gaW52YWxpZCBzZWNvbmQgJzonIHdhcyBmb3VuZCBpbiB0aGUgZWxlbWVudCB0eXBlIG9yIGF0dHJpYnV0ZSBuYW1lLgotICAgICAgICBDb2xvbk5vdExlZ2FsV2l0aE5TID0gQSBjb2xvbiBpcyBub3QgYWxsb3dlZCBpbiB0aGUgbmFtZSAnJ3swfScnIHdoZW4gbmFtZXNwYWNlcyBhcmUgZW5hYmxlZC4KLSAgICAgICAgSW52YWxpZENoYXJJbk1pc2MgPSBBbiBpbnZhbGlkIFhNTCBjaGFyYWN0ZXIgKFVuaWNvZGU6IDB4ezB9KSB3YXMgZm91bmQgaW4gbWFya3VwIGFmdGVyIHRoZSBlbmQgb2YgdGhlIGVsZW1lbnQgY29udGVudC4KLSAgICAgICAgSW52YWxpZENoYXJJblByb2xvZyA9IEFuIGludmFsaWQgWE1MIGNoYXJhY3RlciAoVW5pY29kZTogMHh7MH0pIHdhcyBmb3VuZCBpbiB0aGUgcHJvbG9nIG9mIHRoZSBkb2N1bWVudC4KLSAgICAgICAgSW52YWxpZENoYXJJblhNTERlY2wgPSBBbiBpbnZhbGlkIFhNTCBjaGFyYWN0ZXIgKFVuaWNvZGU6IDB4ezB9KSB3YXMgZm91bmQgaW4gdGhlIFhNTCBkZWNsYXJhdGlvbi4KLSMgMi40IENoYXJhY3RlciBEYXRhIGFuZCBNYXJrdXAKLSAgICAgICAgQ0RFbmRJbkNvbnRlbnQgPSBUaGUgY2hhcmFjdGVyIHNlcXVlbmNlIFwiXV0+XCIgbXVzdCBub3QgYXBwZWFyIGluIGNvbnRlbnQgdW5sZXNzIHVzZWQgdG8gbWFyayB0aGUgZW5kIG9mIGEgQ0RBVEEgc2VjdGlvbi4KLSMgMi43IENEQVRBIFNlY3Rpb25zCi0gICAgICAgIENEU2VjdFVudGVybWluYXRlZCA9IFRoZSBDREFUQSBzZWN0aW9uIG11c3QgZW5kIHdpdGggXCJdXT5cIi4KLSMgMi44IFByb2xvZyBhbmQgRG9jdW1lbnQgVHlwZSBEZWNsYXJhdGlvbgotICAgICAgICBYTUxEZWNsTXVzdEJlRmlyc3QgPSBUaGUgWE1MIGRlY2xhcmF0aW9uIG1heSBvbmx5IGFwcGVhciBhdCB0aGUgdmVyeSBiZWdpbm5pbmcgb2YgdGhlIGRvY3VtZW50LgotICAgICAgICBFcVJlcXVpcmVkSW5YTUxEZWNsID0gVGhlICcnID0gJycgY2hhcmFjdGVyIG11c3QgZm9sbG93IFwiezB9XCIgaW4gdGhlIFhNTCBkZWNsYXJhdGlvbi4KLSAgICAgICAgUXVvdGVSZXF1aXJlZEluWE1MRGVjbCA9IFRoZSB2YWx1ZSBmb2xsb3dpbmcgXCJ7MH1cIiBpbiB0aGUgWE1MIGRlY2xhcmF0aW9uIG11c3QgYmUgYSBxdW90ZWQgc3RyaW5nLgotICAgICAgICBYTUxEZWNsVW50ZXJtaW5hdGVkID0gVGhlIFhNTCBkZWNsYXJhdGlvbiBtdXN0IGVuZCB3aXRoIFwiPz5cIi4KLSAgICAgICAgVmVyc2lvbkluZm9SZXF1aXJlZCA9IFRoZSB2ZXJzaW9uIGlzIHJlcXVpcmVkIGluIHRoZSBYTUwgZGVjbGFyYXRpb24uCi0gICAgICAgIFNwYWNlUmVxdWlyZWRCZWZvcmVWZXJzaW9uSW5YTUxEZWNsID0gV2hpdGUgc3BhY2UgaXMgcmVxdWlyZWQgYmVmb3JlIHRoZSB2ZXJzaW9uIHBzZXVkbyBhdHRyaWJ1dGUgaW4gdGhlIFhNTCBkZWNsYXJhdGlvbi4KLSAgICAgICAgU3BhY2VSZXF1aXJlZEJlZm9yZUVuY29kaW5nSW5YTUxEZWNsID0gV2hpdGUgc3BhY2UgaXMgcmVxdWlyZWQgYmVmb3JlIHRoZSBlbmNvZGluZyBwc2V1ZG8gYXR0cmlidXRlIGluIHRoZSBYTUwgZGVjbGFyYXRpb24uCi0gICAgICAgIFNwYWNlUmVxdWlyZWRCZWZvcmVTdGFuZGFsb25lID0gV2hpdGUgc3BhY2UgaXMgcmVxdWlyZWQgYmVmb3JlIHRoZSBlbmNvZGluZyBwc2V1ZG8gYXR0cmlidXRlIGluIHRoZSBYTUwgZGVjbGFyYXRpb24uCi0gICAgICAgIE1hcmt1cE5vdFJlY29nbml6ZWRJblByb2xvZyA9IFRoZSBtYXJrdXAgaW4gdGhlIGRvY3VtZW50IHByZWNlZGluZyB0aGUgcm9vdCBlbGVtZW50IG11c3QgYmUgd2VsbC1mb3JtZWQuCi0gICAgICAgIE1hcmt1cE5vdFJlY29nbml6ZWRJbk1pc2MgPSBUaGUgbWFya3VwIGluIHRoZSBkb2N1bWVudCBmb2xsb3dpbmcgdGhlIHJvb3QgZWxlbWVudCBtdXN0IGJlIHdlbGwtZm9ybWVkLgotICAgICAgICBBbHJlYWR5U2VlbkRvY3R5cGUgPSBBbHJlYWR5IHNlZW4gZG9jdHlwZS4KLSAgICAgICAgRG9jdHlwZU5vdEFsbG93ZWQgPSBET0NUWVBFIGlzIGRpc2FsbG93ZWQgd2hlbiB0aGUgZmVhdHVyZSAiaHR0cDovL2FwYWNoZS5vcmcveG1sL2ZlYXR1cmVzL2Rpc2FsbG93LWRvY3R5cGUtZGVjbCIgc2V0IHRvIHRydWUuCi0gICAgICAgIENvbnRlbnRJbGxlZ2FsSW5Qcm9sb2cgPSBDb250ZW50IGlzIG5vdCBhbGxvd2VkIGluIHByb2xvZy4KLSAgICAgICAgUmVmZXJlbmNlSWxsZWdhbEluUHJvbG9nID0gUmVmZXJlbmNlIGlzIG5vdCBhbGxvd2VkIGluIHByb2xvZy4KLSMgVHJhaWxpbmcgTWlzYwotICAgICAgICBDb250ZW50SWxsZWdhbEluVHJhaWxpbmdNaXNjPUNvbnRlbnQgaXMgbm90IGFsbG93ZWQgaW4gdHJhaWxpbmcgc2VjdGlvbi4KLSAgICAgICAgUmVmZXJlbmNlSWxsZWdhbEluVHJhaWxpbmdNaXNjPVJlZmVyZW5jZSBpcyBub3QgYWxsb3dlZCBpbiB0cmFpbGluZyBzZWN0aW9uLgotICAgICAgICAKLSMgMi45IFN0YW5kYWxvbmUgRG9jdW1lbnQgRGVjbGFyYXRpb24KLSAgICAgICAgU0REZWNsSW52YWxpZCA9IFRoZSBzdGFuZGFsb25lIGRvY3VtZW50IGRlY2xhcmF0aW9uIHZhbHVlIG11c3QgYmUgXCJ5ZXNcIiBvciBcIm5vXCIsIG5vdCBcInswfVwiLgotICAgICAgICBTRERlY2xOYW1lSW52YWxpZCA9IFRoZSBzdGFuZGFsb25lIG5hbWUgaW4gWE1MIGRlY2xhcmF0aW9uIG1heSBiZSBtaXNzcGVsbGVkLgotIyAyLjEyIExhbmd1YWdlIElkZW50aWZpY2F0aW9uCi0gICAgICAgIFhNTExhbmdJbnZhbGlkID0gVGhlIHhtbDpsYW5nIGF0dHJpYnV0ZSB2YWx1ZSBcInswfVwiIGlzIGFuIGludmFsaWQgbGFuZ3VhZ2UgaWRlbnRpZmllci4KLSMgMy4gTG9naWNhbCBTdHJ1Y3R1cmVzCi0gICAgICAgIEVUYWdSZXF1aXJlZCA9IFRoZSBlbGVtZW50IHR5cGUgXCJ7MH1cIiBtdXN0IGJlIHRlcm1pbmF0ZWQgYnkgdGhlIG1hdGNoaW5nIGVuZC10YWcgXCI8L3swfT5cIi4KLSMgMy4xIFN0YXJ0LVRhZ3MsIEVuZC1UYWdzLCBhbmQgRW1wdHktRWxlbWVudCBUYWdzCi0gICAgICAgIEVsZW1lbnRVbnRlcm1pbmF0ZWQgPSBFbGVtZW50IHR5cGUgXCJ7MH1cIiBtdXN0IGJlIGZvbGxvd2VkIGJ5IGVpdGhlciBhdHRyaWJ1dGUgc3BlY2lmaWNhdGlvbnMsIFwiPlwiIG9yIFwiLz5cIi4KLSAgICAgICAgRXFSZXF1aXJlZEluQXR0cmlidXRlID0gQXR0cmlidXRlIG5hbWUgXCJ7MX1cIiBhc3NvY2lhdGVkIHdpdGggYW4gZWxlbWVudCB0eXBlIFwiezB9XCIgbXVzdCBiZSBmb2xsb3dlZCBieSB0aGUgJycgPSAnJyBjaGFyYWN0ZXIuCi0gICAgICAgIE9wZW5RdW90ZUV4cGVjdGVkID0gT3BlbiBxdW90ZSBpcyBleHBlY3RlZCBmb3IgYXR0cmlidXRlIFwiezF9XCIgYXNzb2NpYXRlZCB3aXRoIGFuICBlbGVtZW50IHR5cGUgIFwiezB9XCIuCi0gICAgICAgIENsb3NlUXVvdGVFeHBlY3RlZCA9IENsb3NlIHF1b3RlIGlzIGV4cGVjdGVkIGZvciBhdHRyaWJ1dGUgXCJ7MX1cIiBhc3NvY2lhdGVkIHdpdGggYW4gZWxlbWVudCB0eXBlIFwiezB9XCIuCi0gICAgICAgIEF0dHJpYnV0ZU5vdFVuaXF1ZSA9IEF0dHJpYnV0ZSBcInsxfVwiIHdhcyBhbHJlYWR5IHNwZWNpZmllZCBmb3IgZWxlbWVudCBcInswfVwiLgotICAgICAgICBBdHRyaWJ1dGVOU05vdFVuaXF1ZSA9IEF0dHJpYnV0ZSBcInsxfVwiIGJvdW5kIHRvIG5hbWVzcGFjZSBcInsyfVwiIHdhcyBhbHJlYWR5IHNwZWNpZmllZCBmb3IgZWxlbWVudCBcInswfVwiLgotICAgICAgICBFVGFnVW50ZXJtaW5hdGVkID0gVGhlIGVuZC10YWcgZm9yIGVsZW1lbnQgdHlwZSBcInswfVwiIG11c3QgZW5kIHdpdGggYSAnJz4nJyBkZWxpbWl0ZXIuCi0gICAgICAgIE1hcmt1cE5vdFJlY29nbml6ZWRJbkNvbnRlbnQgPSBUaGUgY29udGVudCBvZiBlbGVtZW50cyBtdXN0IGNvbnNpc3Qgb2Ygd2VsbC1mb3JtZWQgY2hhcmFjdGVyIGRhdGEgb3IgbWFya3VwLgotICAgICAgICBEb2N0eXBlSWxsZWdhbEluQ29udGVudCA9IEEgRE9DVFlQRSBpcyBub3QgYWxsb3dlZCBpbiBjb250ZW50LgotIyA0LjEgQ2hhcmFjdGVyIGFuZCBFbnRpdHkgUmVmZXJlbmNlcwotICAgICAgICBSZWZlcmVuY2VVbnRlcm1pbmF0ZWQgPSBUaGUgcmVmZXJlbmNlIG11c3QgYmUgdGVybWluYXRlZCBieSBhICc7JyBkZWxpbWl0ZXIuCi0jIDQuMy4yIFdlbGwtRm9ybWVkIFBhcnNlZCBFbnRpdGllcwotICAgICAgICBSZWZlcmVuY2VOb3RJbk9uZUVudGl0eSA9IFRoZSByZWZlcmVuY2UgbXVzdCBiZSBlbnRpcmVseSBjb250YWluZWQgd2l0aGluIHRoZSBzYW1lIHBhcnNlZCBlbnRpdHkuCi0gICAgICAgIEVsZW1lbnRFbnRpdHlNaXNtYXRjaCA9IFRoZSBlbGVtZW50IFwiezB9XCIgbXVzdCBzdGFydCBhbmQgZW5kIHdpdGhpbiB0aGUgc2FtZSBlbnRpdHkuCi0gICAgICAgIE1hcmt1cEVudGl0eU1pc21hdGNoPVhNTCBkb2N1bWVudCBzdHJ1Y3R1cmVzIG11c3Qgc3RhcnQgYW5kIGVuZCB3aXRoaW4gdGhlIHNhbWUgZW50aXR5LgotICAgICAgICAKLSMgTWVzc2FnZXMgY29tbW9uIHRvIERvY3VtZW50IGFuZCBEVEQKLSMgMi4yIENoYXJhY3RlcnMKLSAgICAgICAgSW52YWxpZENoYXJJbkF0dFZhbHVlID0gQW4gaW52YWxpZCBYTUwgY2hhcmFjdGVyIChVbmljb2RlOiAweHsyfSkgd2FzIGZvdW5kIGluIHRoZSB2YWx1ZSBvZiBhdHRyaWJ1dGUgXCJ7MX1cIiBhbmQgZWxlbWVudCBpcyBcInswfVwiLgotICAgICAgICBJbnZhbGlkQ2hhckluQ29tbWVudCA9IEFuIGludmFsaWQgWE1MIGNoYXJhY3RlciAoVW5pY29kZTogMHh7MH0pIHdhcyBmb3VuZCBpbiB0aGUgY29tbWVudC4KLSAgICAgICAgSW52YWxpZENoYXJJblBJID0gQW4gaW52YWxpZCBYTUwgY2hhcmFjdGVyIChVbmljb2RlOiAweHswfSkgd2FzIGZvdW5kIGluIHRoZSBwcm9jZXNzaW5nIGluc3RydWN0aW9uLgotICAgICAgICBJbnZhbGlkQ2hhckluSW50ZXJuYWxTdWJzZXQgPSBBbiBpbnZhbGlkIFhNTCBjaGFyYWN0ZXIgKFVuaWNvZGU6IDB4ezB9KSB3YXMgZm91bmQgaW4gdGhlIGludGVybmFsIHN1YnNldCBvZiB0aGUgRFRELgotICAgICAgICBJbnZhbGlkQ2hhckluVGV4dERlY2wgPSBBbiBpbnZhbGlkIFhNTCBjaGFyYWN0ZXIgKFVuaWNvZGU6IDB4ezB9KSB3YXMgZm91bmQgaW4gdGhlIHRleHQgZGVjbGFyYXRpb24uCi0jIDIuMyBDb21tb24gU3ludGFjdGljIENvbnN0cnVjdHMKLSAgICAgICAgUXVvdGVSZXF1aXJlZEluQXR0VmFsdWUgPSBUaGUgdmFsdWUgb2YgYXR0cmlidXRlIFwiezF9XCIgbXVzdCBiZWdpbiB3aXRoIGVpdGhlciBhIHNpbmdsZSBvciBkb3VibGUgcXVvdGUgY2hhcmFjdGVyLgotICAgICAgICBMZXNzdGhhbkluQXR0VmFsdWUgPSBUaGUgdmFsdWUgb2YgYXR0cmlidXRlIFwiezF9XCIgYXNzb2NpYXRlZCB3aXRoIGFuIGVsZW1lbnQgdHlwZSBcInswfVwiIG11c3Qgbm90IGNvbnRhaW4gdGhlICcnPCcnIGNoYXJhY3Rlci4KLSAgICAgICAgQXR0cmlidXRlVmFsdWVVbnRlcm1pbmF0ZWQgPSBUaGUgdmFsdWUgZm9yIGF0dHJpYnV0ZSBcInsxfVwiIG11c3QgZW5kIHdpdGggdGhlIG1hdGNoaW5nIHF1b3RlIGNoYXJhY3Rlci4KLSMgMi41IENvbW1lbnRzCi0gICAgICAgIEludmFsaWRDb21tZW50U3RhcnQgPSBDb21tZW50IG11c3Qgc3RhcnQgd2l0aCBcIjwhLS1cIi4KLSAgICAgICAgRGFzaERhc2hJbkNvbW1lbnQgPSBUaGUgc3RyaW5nIFwiLS1cIiBpcyBub3QgcGVybWl0dGVkIHdpdGhpbiBjb21tZW50cy4KLSAgICAgICAgQ29tbWVudFVudGVybWluYXRlZCA9IFRoZSBjb21tZW50IG11c3QgZW5kIHdpdGggXCItLT5cIi4KLSAgICAgICAgQ09NTUVOVF9OT1RfSU5fT05FX0VOVElUWSA9IFRoZSBjb21tZW50IGlzIG5vdCBlbmNsb3NlZCB4aW4gdGhlIHNhbWUgZW50aXR5LgotIyAyLjYgUHJvY2Vzc2luZyBJbnN0cnVjdGlvbnMKLSAgICAgICAgUElUYXJnZXRSZXF1aXJlZCA9IFRoZSBwcm9jZXNzaW5nIGluc3RydWN0aW9uIG11c3QgYmVnaW4gd2l0aCB0aGUgbmFtZSBvZiB0aGUgdGFyZ2V0LgotICAgICAgICBTcGFjZVJlcXVpcmVkSW5QSSA9IFdoaXRlIHNwYWNlIGlzIHJlcXVpcmVkIGJldHdlZW4gdGhlIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gdGFyZ2V0IGFuZCBkYXRhLgotICAgICAgICBQSVVudGVybWluYXRlZCA9IFRoZSBwcm9jZXNzaW5nIGluc3RydWN0aW9uIG11c3QgZW5kIHdpdGggXCI/PlwiLgotICAgICAgICBSZXNlcnZlZFBJVGFyZ2V0ID0gVGhlIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gdGFyZ2V0IG1hdGNoaW5nIFwiW3hYXVttTV1bbExdXCIgaXMgbm90IGFsbG93ZWQuCi0gICAgICAgIFBJX05PVF9JTl9PTkVfRU5USVRZID0gVGhlIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gaXMgbm90IGVuY2xvc2VkIGluIHRoZSBzYW1lIGVudGl0eS4KLSMgMi44IFByb2xvZyBhbmQgRG9jdW1lbnQgVHlwZSBEZWNsYXJhdGlvbgotICAgICAgICBWZXJzaW9uSW5mb0ludmFsaWQgPSBJbnZhbGlkIHZlcnNpb24gXCJ7MH1cIi4KLSAgICAgICAgVmVyc2lvbk5vdFN1cHBvcnRlZCA9IFhNTCB2ZXJzaW9uIFwiezB9XCIgaXMgbm90IHN1cHBvcnRlZCwgb25seSBYTUwgMS4wIGlzIHN1cHBvcnRlZC4KLSAgICAgICAgVmVyc2lvbk5vdFN1cHBvcnRlZDExID0gWE1MIHZlcnNpb24gXCJ7MH1cIiBpcyBub3Qgc3VwcG9ydGVkLCBvbmx5IFhNTCAxLjAgYW5kIFhNTCAxLjEgYXJlIHN1cHBvcnRlZC4KLSAgICAgICAgVmVyc2lvbk1pc21hdGNoPSBBbiBlbnRpdHkgY2Fubm90IGluY2x1ZGUgYW5vdGhlciBlbnRpdHkgb2YgYSBsYXRlciB2ZXJzaW9uLgotIyA0LjEgQ2hhcmFjdGVyIGFuZCBFbnRpdHkgUmVmZXJlbmNlcwotICAgICAgICBEaWdpdFJlcXVpcmVkSW5DaGFyUmVmID0gQSBkZWNpbWFsIHJlcHJlc2VudGF0aW9uIG11c3QgaW1tZWRpYXRlbHkgZm9sbG93IHRoZSBcIiYjXCIgaW4gYSBjaGFyYWN0ZXIgcmVmZXJlbmNlLgotICAgICAgICBIZXhkaWdpdFJlcXVpcmVkSW5DaGFyUmVmID0gQSBoZXhhZGVjaW1hbCByZXByZXNlbnRhdGlvbiBtdXN0IGltbWVkaWF0ZWx5IGZvbGxvdyB0aGUgXCImI3hcIiBpbiBhIGNoYXJhY3RlciByZWZlcmVuY2UuCi0gICAgICAgIFNlbWljb2xvblJlcXVpcmVkSW5DaGFyUmVmID0gVGhlIGNoYXJhY3RlciByZWZlcmVuY2UgbXVzdCBlbmQgd2l0aCB0aGUgJzsnIGRlbGltaXRlci4KLSAgICAgICAgSW52YWxpZENoYXJSZWYgPSBDaGFyYWN0ZXIgcmVmZXJlbmNlIFwiJiN7MH1cIiBpcyBhbiBpbnZhbGlkIFhNTCBjaGFyYWN0ZXIuCi0gICAgICAgIE5hbWVSZXF1aXJlZEluUmVmZXJlbmNlID0gVGhlIGVudGl0eSBuYW1lIG11c3QgaW1tZWRpYXRlbHkgZm9sbG93IHRoZSAnJicgaW4gdGhlIGVudGl0eSByZWZlcmVuY2UuCi0gICAgICAgIFNlbWljb2xvblJlcXVpcmVkSW5SZWZlcmVuY2UgPSBUaGUgcmVmZXJlbmNlIHRvIGVudGl0eSBcInswfVwiIG11c3QgZW5kIHdpdGggdGhlICcnOycnIGRlbGltaXRlci4KLSMgNC4zLjEgVGhlIFRleHQgRGVjbGFyYXRpb24KLSAgICAgICAgVGV4dERlY2xNdXN0QmVGaXJzdCA9IFRoZSB0ZXh0IGRlY2xhcmF0aW9uIG1heSBvbmx5IGFwcGVhciBhdCB0aGUgdmVyeSBiZWdpbm5pbmcgb2YgdGhlIGV4dGVybmFsIHBhcnNlZCBlbnRpdHkuCi0gICAgICAgIEVxUmVxdWlyZWRJblRleHREZWNsID0gVGhlICcnID0gJycgY2hhcmFjdGVyIG11c3QgZm9sbG93IFwiezB9XCIgaW4gdGhlIHRleHQgZGVjbGFyYXRpb24uCi0gICAgICAgIFF1b3RlUmVxdWlyZWRJblRleHREZWNsID0gVGhlIHZhbHVlIGZvbGxvd2luZyBcInswfVwiIGluIHRoZSB0ZXh0IGRlY2xhcmF0aW9uIG11c3QgYmUgYSBxdW90ZWQgc3RyaW5nLgotICAgICAgICBDbG9zZVF1b3RlTWlzc2luZ0luVGV4dERlY2wgPSBjbG9zaW5nIHF1b3RlIGluIHRoZSB2YWx1ZSBmb2xsb3dpbmcgXCJ7MH1cIiBpbiB0aGUgdGV4dCBkZWNsYXJhdGlvbiBpcyBtaXNzaW5nLgotICAgICAgICBTcGFjZVJlcXVpcmVkQmVmb3JlVmVyc2lvbkluVGV4dERlY2wgPSBXaGl0ZSBzcGFjZSBpcyByZXF1aXJlZCBiZWZvcmUgdGhlIHZlcnNpb24gcHNldWRvIGF0dHJpYnV0ZSBpbiB0aGUgdGV4dCBkZWNsYXJhdGlvbi4KLSAgICAgICAgU3BhY2VSZXF1aXJlZEJlZm9yZUVuY29kaW5nSW5UZXh0RGVjbCA9IFdoaXRlIHNwYWNlIGlzIHJlcXVpcmVkIGJlZm9yZSB0aGUgZW5jb2RpbmcgcHNldWRvIGF0dHJpYnV0ZSBpbiB0aGUgdGV4dCBkZWNsYXJhdGlvbi4KLSAgICAgICAgVGV4dERlY2xVbnRlcm1pbmF0ZWQgPSBUaGUgdGV4dCBkZWNsYXJhdGlvbiBtdXN0IGVuZCB3aXRoIFwiPz5cIi4KLSAgICAgICAgRW5jb2RpbmdEZWNsUmVxdWlyZWQgPSBUaGUgZW5jb2RpbmcgZGVjbGFyYXRpb24gaXMgcmVxdWlyZWQgaW4gdGhlIHRleHQgZGVjbGFyYXRpb24uCi0gICAgICAgIE5vTW9yZVBzZXVkb0F0dHJpYnV0ZXMgPSBObyBtb3JlIHBzZXVkbyBhdHRyaWJ1dGVzIGFyZSBhbGxvd2VkLgotICAgICAgICBNb3JlUHNldWRvQXR0cmlidXRlcyA9IE1vcmUgcHNldWRvIGF0dHJpYnV0ZXMgYXJlIGV4cGVjdGVkLgotICAgICAgICBQc2V1ZG9BdHRyTmFtZUV4cGVjdGVkID0gQSBwc2V1ZG8gYXR0cmlidXRlIG5hbWUgaXMgZXhwZWN0ZWQuIAotIyA0LjMuMiBXZWxsLUZvcm1lZCBQYXJzZWQgRW50aXRpZXMKLSAgICAgICAgQ29tbWVudE5vdEluT25lRW50aXR5ID0gVGhlIGNvbW1lbnQgbXVzdCBiZSBlbnRpcmVseSBjb250YWluZWQgd2l0aGluIHRoZSBzYW1lIHBhcnNlZCBlbnRpdHkuCi0gICAgICAgIFBJTm90SW5PbmVFbnRpdHkgPSBUaGUgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiBtdXN0IGJlIGVudGlyZWx5IGNvbnRhaW5lZCB3aXRoaW4gdGhlIHNhbWUgcGFyc2VkIGVudGl0eS4KLSMgNC4zLjMgQ2hhcmFjdGVyIEVuY29kaW5nIGluIEVudGl0aWVzCi0gICAgICAgIEVuY29kaW5nRGVjbEludmFsaWQgPSBJbnZhbGlkIGVuY29kaW5nIG5hbWUgXCJ7MH1cIi4KLSAgICAgICAgRW5jb2RpbmdCeXRlT3JkZXJVbnN1cHBvcnRlZCA9IEdpdmVuIGJ5dGUgb3JkZXIgZm9yIGVuY29kaW5nIFwiezB9XCIgaXMgbm90IHN1cHBvcnRlZC4KLSAgICAgICAgSW52YWxpZEJ5dGUgPSBJbnZhbGlkIGJ5dGUgezB9IG9mIHsxfS1ieXRlIFVURi04IHNlcXVlbmNlLgotICAgICAgICBFeHBlY3RlZEJ5dGUgPSBFeHBlY3RlZCBieXRlIHswfSBvZiB7MX0tYnl0ZSBVVEYtOCBzZXF1ZW5jZS4gIAotICAgICAgICBJbnZhbGlkSGlnaFN1cnJvZ2F0ZSA9IEhpZ2ggc3Vycm9nYXRlIGJpdHMgaW4gVVRGLTggc2VxdWVuY2UgbXVzdCBub3QgZXhjZWVkIDB4MTAgYnV0IGZvdW5kIDB4ezB9LgotICAgICAgICBPcGVyYXRpb25Ob3RTdXBwb3J0ZWQgPSBPcGVyYXRpb24gXCJ7MH1cIiBub3Qgc3VwcG9ydGVkIGJ5IHsxfSByZWFkZXIuCi0gICAgICAgIEludmFsaWRBU0NJSSA9IEJ5dGUgXCJ7MH1cIiBpcyBub3QgYSBtZW1iZXIgb2YgdGhlICg3LWJpdCkgQVNDSUkgY2hhcmFjdGVyIHNldC4KLSAgICAgICAgQ2hhckNvbnZlcnNpb25GYWlsdXJlID0gQW4gZW50aXR5IGRldGVybWluZWQgdG8gYmUgaW4gYSBjZXJ0YWluIGVuY29kaW5nIG11c3Qgbm90IGNvbnRhaW4gc2VxdWVuY2VzIGlsbGVnYWwgaW4gdGhhdCBlbmNvZGluZy4KLSAgICAgICAgCi0jIERURCBNZXNzYWdlcwotIyAyLjIgQ2hhcmFjdGVycwotICAgICAgICBJbnZhbGlkQ2hhckluRW50aXR5VmFsdWUgPSBBbiBpbnZhbGlkIFhNTCBjaGFyYWN0ZXIgKFVuaWNvZGU6IDB4ezB9KSB3YXMgZm91bmQgaW4gdGhlIGxpdGVyYWwgZW50aXR5IHZhbHVlLgotICAgICAgICBJbnZhbGlkQ2hhckluRXh0ZXJuYWxTdWJzZXQgPSBBbiBpbnZhbGlkIFhNTCBjaGFyYWN0ZXIgKFVuaWNvZGU6IDB4ezB9KSB3YXMgZm91bmQgaW4gdGhlIGV4dGVybmFsIHN1YnNldCBvZiB0aGUgRFRELgotICAgICAgICBJbnZhbGlkQ2hhckluSWdub3JlU2VjdCA9IEFuIGludmFsaWQgWE1MIGNoYXJhY3RlciAoVW5pY29kZTogMHh7MH0pIHdhcyBmb3VuZCBpbiB0aGUgZXhjbHVkZWQgY29uZGl0aW9uYWwgc2VjdGlvbi4KLSAgICAgICAgSW52YWxpZENoYXJJblB1YmxpY0lEID0gQW4gaW52YWxpZCBYTUwgY2hhcmFjdGVyIChVbmljb2RlOiAweHswfSkgd2FzIGZvdW5kIGluIHRoZSBwdWJsaWMgaWRlbnRpZmllci4KLSAgICAgICAgSW52YWxpZENoYXJJblN5c3RlbUlEID0gQW4gaW52YWxpZCBYTUwgY2hhcmFjdGVyIChVbmljb2RlOiAweHswfSkgd2FzIGZvdW5kIGluIHRoZSBzeXN0ZW0gaWRlbnRpZmllci4KLSMgMi4zIENvbW1vbiBTeW50YWN0aWMgQ29uc3RydWN0cwotICAgICAgICBTcGFjZVJlcXVpcmVkQWZ0ZXJTWVNURU0gPSBXaGl0ZSBzcGFjZSBpcyByZXF1aXJlZCBhZnRlciBrZXl3b3JkIFNZU1RFTSBpbiBET0NUWVBFIGRlY2wuCi0gICAgICAgIFF1b3RlUmVxdWlyZWRJblN5c3RlbUlEID0gVGhlIHN5c3RlbSBpZGVudGlmaWVyIG11c3QgYmVnaW4gd2l0aCBlaXRoZXIgYSBzaW5nbGUgb3IgZG91YmxlIHF1b3RlIGNoYXJhY3Rlci4KLSAgICAgICAgU3lzdGVtSURVbnRlcm1pbmF0ZWQgPSBUaGUgc3lzdGVtIGlkZW50aWZpZXIgbXVzdCBlbmQgd2l0aCB0aGUgbWF0Y2hpbmcgcXVvdGUgY2hhcmFjdGVyLgotICAgICAgICBTcGFjZVJlcXVpcmVkQWZ0ZXJQVUJMSUMgPSBXaGl0ZSBzcGFjZXMgYXJlIHJlcXVpcmVkIGFmdGVyIGtleXdvcmQgUFVCTElDIGluIERPQ1RZUEUgZGVjbC4KLSAgICAgICAgUXVvdGVSZXF1aXJlZEluUHVibGljSUQgPSBUaGUgcHVibGljIGlkZW50aWZpZXIgbXVzdCBiZWdpbiB3aXRoIGVpdGhlciBhIHNpbmdsZSBvciBkb3VibGUgcXVvdGUgY2hhcmFjdGVyLgotICAgICAgICBQdWJsaWNJRFVudGVybWluYXRlZCA9IFRoZSBwdWJsaWMgaWRlbnRpZmllciBtdXN0IGVuZCB3aXRoIHRoZSBtYXRjaGluZyBxdW90ZSBjaGFyYWN0ZXIuCi0gICAgICAgIFB1YmlkQ2hhcklsbGVnYWwgPSBUaGUgY2hhcmFjdGVyIChVbmljb2RlOiAweHswfSkgaXMgbm90IHBlcm1pdHRlZCBpbiB0aGUgcHVibGljIGlkZW50aWZpZXIuCi0gICAgICAgIFNwYWNlUmVxdWlyZWRCZXR3ZWVuUHVibGljQW5kU3lzdGVtID0gV2hpdGUgc3BhY2VzIGFyZSByZXF1aXJlZCBiZXR3ZWVuIHB1YmxpY0lkIGFuZCBzeXN0ZW1JZC4KLSMgMi44IFByb2xvZyBhbmQgRG9jdW1lbnQgVHlwZSBEZWNsYXJhdGlvbgotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX1JPT1RfRUxFTUVOVF9UWVBFX0lOX0RPQ1RZUEVERUNMID0gV2hpdGUgc3BhY2UgaXMgcmVxdWlyZWQgYWZ0ZXIgXCI8IURPQ1RZUEVcIiBpbiB0aGUgZG9jdW1lbnQgdHlwZSBkZWNsYXJhdGlvbi4KLSAgICAgICAgTVNHX1JPT1RfRUxFTUVOVF9UWVBFX1JFUVVJUkVEID0gVGhlIHJvb3QgZWxlbWVudCB0eXBlIG11c3QgYXBwZWFyIGFmdGVyIFwiPCFET0NUWVBFXCIgaW4gdGhlIGRvY3VtZW50IHR5cGUgZGVjbGFyYXRpb24uCi0gICAgICAgIERvY3R5cGVkZWNsVW50ZXJtaW5hdGVkID0gVGhlIGRvY3VtZW50IHR5cGUgZGVjbGFyYXRpb24gZm9yIHJvb3QgZWxlbWVudCB0eXBlIFwiezB9XCIgbXVzdCBlbmQgd2l0aCAnJz4nJy4KLSAgICAgICAgRG9jdHlwZWRlY2xOb3RDbG9zZWQgPSBUaGUgZG9jdW1lbnQgdHlwZSBkZWNsYXJhdGlvbiBmb3Igcm9vdCBlbGVtZW50IHR5cGUgXCJ7MH1cIiBtdXN0IGJlIGNsb3NlZCB3aXRoICcnXScnLgotICAgICAgICBQRVJlZmVyZW5jZVdpdGhpbk1hcmt1cCA9IFRoZSBwYXJhbWV0ZXIgZW50aXR5IHJlZmVyZW5jZSBcIiV7MH07XCIgY2Fubm90IG9jY3VyIHdpdGhpbiBtYXJrdXAgaW4gdGhlIGludGVybmFsIHN1YnNldCBvZiB0aGUgRFRELgotICAgICAgICBNU0dfTUFSS1VQX05PVF9SRUNPR05JWkVEX0lOX0RURCA9IFRoZSBtYXJrdXAgZGVjbGFyYXRpb25zIGNvbnRhaW5lZCBvciBwb2ludGVkIHRvIGJ5IHRoZSBkb2N1bWVudCB0eXBlIGRlY2xhcmF0aW9uIG11c3QgYmUgd2VsbC1mb3JtZWQuCi0jIDIuMTAgV2hpdGUgU3BhY2UgSGFuZGxpbmcKLSAgICAgICAgTVNHX1hNTF9TUEFDRV9ERUNMQVJBVElPTl9JTExFR0FMID0gVGhlIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbiBmb3IgXCJ4bWw6c3BhY2VcIiBtdXN0IGJlIGdpdmVuIGFzIGFuIGVudW1lcmF0ZWQgdHlwZSB3aG9zZSBvbmx5IHBvc3NpYmxlIHZhbHVlcyBhcmUgXCJkZWZhdWx0XCIgYW5kIFwicHJlc2VydmVcIi4KLSMgMy4yIEVsZW1lbnQgVHlwZSBEZWNsYXJhdGlvbnMKLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9FTEVNRU5UX1RZUEVfSU5fRUxFTUVOVERFQ0wgPSBXaGl0ZSBzcGFjZSBpcyByZXF1aXJlZCBhZnRlciBcIjwhRUxFTUVOVFwiIGluIHRoZSBlbGVtZW50IHR5cGUgZGVjbGFyYXRpb24uCi0gICAgICAgIE1TR19FTEVNRU5UX1RZUEVfUkVRVUlSRURfSU5fRUxFTUVOVERFQ0wgPSBUaGUgZWxlbWVudCB0eXBlIGlzIHJlcXVpcmVkIGluIHRoZSBlbGVtZW50IHR5cGUgZGVjbGFyYXRpb24uCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfQ09OVEVOVFNQRUNfSU5fRUxFTUVOVERFQ0wgPSBXaGl0ZSBzcGFjZSBpcyByZXF1aXJlZCBhZnRlciB0aGUgZWxlbWVudCB0eXBlIFwiezB9XCIgaW4gdGhlIGVsZW1lbnQgdHlwZSBkZWNsYXJhdGlvbi4KLSAgICAgICAgTVNHX0NPTlRFTlRTUEVDX1JFUVVJUkVEX0lOX0VMRU1FTlRERUNMID0gVGhlIGNvbnN0cmFpbnQgaXMgcmVxdWlyZWQgYWZ0ZXIgdGhlIGVsZW1lbnQgdHlwZSBcInswfVwiIGluIHRoZSBlbGVtZW50IHR5cGUgZGVjbGFyYXRpb24uCi0gICAgICAgIEVsZW1lbnREZWNsVW50ZXJtaW5hdGVkID0gVGhlIGRlY2xhcmF0aW9uIGZvciBlbGVtZW50IHR5cGUgXCJ7MH1cIiBtdXN0IGVuZCB3aXRoICcnPicnLgotIyAzLjIuMSBFbGVtZW50IENvbnRlbnQKLSAgICAgICAgTVNHX09QRU5fUEFSRU5fT1JfRUxFTUVOVF9UWVBFX1JFUVVJUkVEX0lOX0NISUxEUkVOID0gQSAnJygnJyBjaGFyYWN0ZXIgb3IgYW4gZWxlbWVudCB0eXBlIGlzIHJlcXVpcmVkIGluIHRoZSBkZWNsYXJhdGlvbiBvZiBlbGVtZW50IHR5cGUgXCJ7MH1cIi4KLSAgICAgICAgTVNHX0NMT1NFX1BBUkVOX1JFUVVJUkVEX0lOX0NISUxEUkVOID0gQSAnJyknJyBpcyByZXF1aXJlZCBpbiB0aGUgZGVjbGFyYXRpb24gb2YgZWxlbWVudCB0eXBlIFwiezB9XCIuCi0jIDMuMi4yIE1peGVkIENvbnRlbnQKLSAgICAgICAgTVNHX0VMRU1FTlRfVFlQRV9SRVFVSVJFRF9JTl9NSVhFRF9DT05URU5UID0gQW4gZWxlbWVudCB0eXBlIGlzIHJlcXVpcmVkIGluIHRoZSBkZWNsYXJhdGlvbiBvZiBlbGVtZW50IHR5cGUgXCJ7MH1cIi4KLSAgICAgICAgTVNHX0NMT1NFX1BBUkVOX1JFUVVJUkVEX0lOX01JWEVEID0gQSAnJyknJyBpcyByZXF1aXJlZCBpbiB0aGUgZGVjbGFyYXRpb24gb2YgZWxlbWVudCB0eXBlIFwiezB9XCIuCi0gICAgICAgIE1peGVkQ29udGVudFVudGVybWluYXRlZCA9IFRoZSBtaXhlZCBjb250ZW50IG1vZGVsIFwiezB9XCIgbXVzdCBlbmQgd2l0aCBcIikqXCIgd2hlbiB0aGUgdHlwZXMgb2YgY2hpbGQgZWxlbWVudHMgYXJlIGNvbnN0cmFpbmVkLgotIyAzLjMgQXR0cmlidXRlLUxpc3QgRGVjbGFyYXRpb25zCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfRUxFTUVOVF9UWVBFX0lOX0FUVExJU1RERUNMID0gV2hpdGUgc3BhY2UgaXMgcmVxdWlyZWQgYWZ0ZXIgXCI8IUFUVExJU1RcIiBpbiB0aGUgYXR0cmlidXRlLWxpc3QgZGVjbGFyYXRpb24uCi0gICAgICAgIE1TR19FTEVNRU5UX1RZUEVfUkVRVUlSRURfSU5fQVRUTElTVERFQ0wgPSBUaGUgZWxlbWVudCB0eXBlIGlzIHJlcXVpcmVkIGluIHRoZSBhdHRyaWJ1dGUtbGlzdCBkZWNsYXJhdGlvbi4KLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9BVFRSSUJVVEVfTkFNRV9JTl9BVFRERUYgPSBXaGl0ZSBzcGFjZSBpcyByZXF1aXJlZCBiZWZvcmUgdGhlIGF0dHJpYnV0ZSBuYW1lIGluIHRoZSBhdHRyaWJ1dGUtbGlzdCBkZWNsYXJhdGlvbiBmb3IgZWxlbWVudCBcInswfVwiLgotICAgICAgICBBdHROYW1lUmVxdWlyZWRJbkF0dERlZiA9IFRoZSBhdHRyaWJ1dGUgbmFtZSBtdXN0IGJlIHNwZWNpZmllZCBpbiB0aGUgYXR0cmlidXRlLWxpc3QgZGVjbGFyYXRpb24gZm9yIGVsZW1lbnQgXCJ7MH1cIi4KLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9BVFRUWVBFX0lOX0FUVERFRiA9IFdoaXRlIHNwYWNlIGlzIHJlcXVpcmVkIGJlZm9yZSB0aGUgYXR0cmlidXRlIHR5cGUgaW4gdGhlIGRlY2xhcmF0aW9uIG9mIGF0dHJpYnV0ZSBcInsxfVwiIGZvciBlbGVtZW50IFwiezB9XCIuCi0gICAgICAgIEF0dFR5cGVSZXF1aXJlZEluQXR0RGVmID0gVGhlIGF0dHJpYnV0ZSB0eXBlIGlzIHJlcXVpcmVkIGluIHRoZSBkZWNsYXJhdGlvbiBvZiBhdHRyaWJ1dGUgXCJ7MX1cIiBmb3IgZWxlbWVudCBcInswfVwiLgotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX0RFRkFVTFRERUNMX0lOX0FUVERFRiA9IFdoaXRlIHNwYWNlIGlzIHJlcXVpcmVkIGJlZm9yZSB0aGUgYXR0cmlidXRlIGRlZmF1bHQgaW4gdGhlIGRlY2xhcmF0aW9uIG9mIGF0dHJpYnV0ZSBcInsxfVwiIGZvciBlbGVtZW50IFwiezB9XCIuCi0gICAgICAgIE1TR19EVVBMSUNBVEVfQVRUUklCVVRFX0RFRklOSVRJT04gPSBNb3JlIHRoYW4gb25lIGF0dHJpYnV0ZSBkZWZpbml0aW9uIGlzIHByb3ZpZGVkIGZvciB0aGUgc2FtZSBhdHRyaWJ1dGUgXCJ7MX1cIiBvZiBhIGdpdmVuIGVsZW1lbnQgXCJ7MH1cIi4KLSMgMy4zLjEgQXR0cmlidXRlIFR5cGVzCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9BRlRFUl9OT1RBVElPTl9JTl9OT1RBVElPTlRZUEUgPSBXaGl0ZSBzcGFjZSBtdXN0IGFwcGVhciBhZnRlciBcIk5PVEFUSU9OXCIgaW4gdGhlIFwiezF9XCIgYXR0cmlidXRlIGRlY2xhcmF0aW9uLgotICAgICAgICBNU0dfT1BFTl9QQVJFTl9SRVFVSVJFRF9JTl9OT1RBVElPTlRZUEUgPSBUaGUgJycoJycgY2hhcmFjdGVyIG11c3QgZm9sbG93IFwiTk9UQVRJT05cIiBpbiB0aGUgXCJ7MX1cIiBhdHRyaWJ1dGUgZGVjbGFyYXRpb24uCi0gICAgICAgIE1TR19OQU1FX1JFUVVJUkVEX0lOX05PVEFUSU9OVFlQRSA9IFRoZSBub3RhdGlvbiBuYW1lIGlzIHJlcXVpcmVkIGluIHRoZSBub3RhdGlvbiB0eXBlIGxpc3QgZm9yIHRoZSBcInsxfVwiIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbi4KLSAgICAgICAgTm90YXRpb25UeXBlVW50ZXJtaW5hdGVkID0gVGhlIG5vdGF0aW9uIHR5cGUgbGlzdCBtdXN0IGVuZCB3aXRoICcnKScnIGluIHRoZSBcInsxfVwiIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbi4KLSAgICAgICAgTVNHX05NVE9LRU5fUkVRVUlSRURfSU5fRU5VTUVSQVRJT04gPSBUaGUgbmFtZSB0b2tlbiBpcyByZXF1aXJlZCBpbiB0aGUgZW51bWVyYXRlZCB0eXBlIGxpc3QgZm9yIHRoZSBcInsxfVwiIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbi4KLSAgICAgICAgRW51bWVyYXRpb25VbnRlcm1pbmF0ZWQgPSBUaGUgZW51bWVyYXRlZCB0eXBlIGxpc3QgbXVzdCBlbmQgd2l0aCAnJyknJyBpbiB0aGUgXCJ7MX1cIiBhdHRyaWJ1dGUgZGVjbGFyYXRpb24uCi0gICAgICAgIE1TR19ESVNUSU5DVF9UT0tFTlNfSU5fRU5VTUVSQVRJT04gPSBUaGUgZW51bWVyYXRpb24gdmFsdWUgXCJ7MX1cIiB3YXMgc3BlY2lmaWVkIG1vcmUgdGhhbiBvbmNlIGluIHRoZSBkZWNsYXJhdGlvbiBvZiBhdHRyaWJ1dGUgXCJ7Mn1cIiBmb3IgZWxlbWVudCBcInswfVwiLiBUaGUgTk1UT0tFTlMgaW4gYSBzaW5nbGUgRW51bWVyYXRpb24gYXR0cmlidXRlIGRlY2xhcmF0aW9uIG11c3QgYWxsIGJlIGRpc3RpbmN0LgotICAgICAgICBNU0dfRElTVElOQ1RfTk9UQVRJT05fSU5fRU5VTUVSQVRJT04gPSBUaGUgZW51bWVyYXRpb24gdmFsdWUgXCJ7MX1cIiB3YXMgc3BlY2lmaWVkIG1vcmUgdGhhbiBvbmNlIGluIHRoZSBkZWNsYXJhdGlvbiBvZiBhdHRyaWJ1dGUgXCJ7Mn1cIiBmb3IgZWxlbWVudCBcInswfVwiLiBUaGUgTk9UQVRJT04gbmFtZXMgaW4gYSBzaW5nbGUgTm90YXRpb25UeXBlIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbiBtdXN0IGFsbCBiZSBkaXN0aW5jdC4KLSMgMy4zLjIgQXR0cmlidXRlIERlZmF1bHRzCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9BRlRFUl9GSVhFRF9JTl9ERUZBVUxUREVDTCA9IFdoaXRlIHNwYWNlIG11c3QgYXBwZWFyIGFmdGVyIFwiRklYRURcIiBpbiB0aGUgXCJ7MX1cIiBhdHRyaWJ1dGUgZGVjbGFyYXRpb24uCi0jIDMuNCBDb25kaXRpb25hbCBTZWN0aW9ucwotICAgICAgICBJbmNsdWRlU2VjdFVudGVybWluYXRlZCA9IFRoZSBpbmNsdWRlZCBjb25kaXRpb25hbCBzZWN0aW9uIG11c3QgZW5kIHdpdGggXCJdXT5cIi4KLSAgICAgICAgSWdub3JlU2VjdFVudGVybWluYXRlZCA9IFRoZSBleGNsdWRlZCBjb25kaXRpb25hbCBzZWN0aW9uIG11c3QgZW5kIHdpdGggXCJdXT5cIi4KLSMgNC4xIENoYXJhY3RlciBhbmQgRW50aXR5IFJlZmVyZW5jZXMKLSAgICAgICAgTmFtZVJlcXVpcmVkSW5QRVJlZmVyZW5jZSA9IFRoZSBlbnRpdHkgbmFtZSBtdXN0IGltbWVkaWF0ZWx5IGZvbGxvdyB0aGUgJyUnIGluIHRoZSBwYXJhbWV0ZXIgZW50aXR5IHJlZmVyZW5jZS4KLSAgICAgICAgU2VtaWNvbG9uUmVxdWlyZWRJblBFUmVmZXJlbmNlID0gVGhlIHBhcmFtZXRlciBlbnRpdHkgcmVmZXJlbmNlIFwiJXswfTtcIiBtdXN0IGVuZCB3aXRoIHRoZSAnJzsnJyBkZWxpbWl0ZXIuCi0jIDQuMiBFbnRpdHkgRGVjbGFyYXRpb25zCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfRU5USVRZX05BTUVfSU5fRU5USVRZREVDTCA9IFdoaXRlIHNwYWNlIGlzIHJlcXVpcmVkIGFmdGVyIFwiPCFFTlRJVFlcIiBpbiB0aGUgZW50aXR5IGRlY2xhcmF0aW9uLgotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX1BFUkNFTlRfSU5fUEVERUNMID0gV2hpdGUgc3BhY2UgaXMgcmVxdWlyZWQgYmV0d2VlbiBcIjwhRU5USVRZXCIgYW5kIHRoZSAnJScgY2hhcmFjdGVyIGluIHRoZSBwYXJhbWV0ZXIgZW50aXR5IGRlY2xhcmF0aW9uLgotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX0VOVElUWV9OQU1FX0lOX1BFREVDTCA9IFdoaXRlIHNwYWNlIGlzIHJlcXVpcmVkIGJldHdlZW4gdGhlICclJyBhbmQgdGhlIGVudGl0eSBuYW1lIGluIHRoZSBwYXJhbWV0ZXIgZW50aXR5IGRlY2xhcmF0aW9uLgotICAgICAgICBNU0dfRU5USVRZX05BTUVfUkVRVUlSRURfSU5fRU5USVRZREVDTCA9IFRoZSBuYW1lIG9mIHRoZSBlbnRpdHkgaXMgcmVxdWlyZWQgaW4gdGhlIGVudGl0eSBkZWNsYXJhdGlvbi4KLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0FGVEVSX0VOVElUWV9OQU1FX0lOX0VOVElUWURFQ0wgPSBXaGl0ZSBzcGFjZSBpcyByZXF1aXJlZCBiZXR3ZWVuIHRoZSBlbnRpdHkgbmFtZSBcInswfVwiIGFuZCB0aGUgZGVmaW5pdGlvbiBpbiB0aGUgZW50aXR5IGRlY2xhcmF0aW9uLgotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX05PVEFUSU9OX05BTUVfSU5fVU5QQVJTRURfRU5USVRZREVDTCA9IFdoaXRlIHNwYWNlIGlzIHJlcXVpcmVkIGJldHdlZW4gXCJOREFUQVwiIGFuZCB0aGUgbm90YXRpb24gbmFtZSBpbiB0aGUgZGVjbGFyYXRpb24gZm9yIHRoZSBlbnRpdHkgXCJ7MH1cIi4KLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9OREFUQV9JTl9VTlBBUlNFRF9FTlRJVFlERUNMID0gV2hpdGUgc3BhY2UgaXMgcmVxdWlyZWQgYmVmb3JlIFwiTkRBVEFcIiBpbiB0aGUgZGVjbGFyYXRpb24gZm9yIHRoZSBlbnRpdHkgXCJ7MH1cIi4KLSAgICAgICAgTVNHX05PVEFUSU9OX05BTUVfUkVRVUlSRURfRk9SX1VOUEFSU0VEX0VOVElUWURFQ0wgPSBUaGUgbm90YXRpb24gbmFtZSBpcyByZXF1aXJlZCBhZnRlciBcIk5EQVRBXCIgaW4gdGhlIGRlY2xhcmF0aW9uIGZvciB0aGUgZW50aXR5IFwiezB9XCIuCi0gICAgICAgIEVudGl0eURlY2xVbnRlcm1pbmF0ZWQgPSBUaGUgZGVjbGFyYXRpb24gZm9yIHRoZSBlbnRpdHkgXCJ7MH1cIiBtdXN0IGVuZCB3aXRoICcnPicnLgotCU1TR19EVVBMSUNBVEVfRU5USVRZX0RFRklOSVRJT04gPSBFbnRpdHkgXCJ7MH1cIiBpcyBkZWNsYXJlZCBtb3JlIHRoYW4gb25jZS4gICAgICAgIAotIyA0LjIuMiBFeHRlcm5hbCBFbnRpdGllcwotICAgICAgICBFeHRlcm5hbElEUmVxdWlyZWQgPSBUaGUgZXh0ZXJuYWwgZW50aXR5IGRlY2xhcmF0aW9uIG11c3QgYmVnaW4gd2l0aCBlaXRoZXIgXCJTWVNURU1cIiBvciBcIlBVQkxJQ1wiLgotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX1BVQklETElURVJBTF9JTl9FWFRFUk5BTElEID0gV2hpdGUgc3BhY2UgaXMgcmVxdWlyZWQgYmV0d2VlbiBcIlBVQkxJQ1wiIGFuZCB0aGUgcHVibGljIGlkZW50aWZpZXIuCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9BRlRFUl9QVUJJRExJVEVSQUxfSU5fRVhURVJOQUxJRCA9IFdoaXRlIHNwYWNlIGlzIHJlcXVpcmVkIGJldHdlZW4gdGhlIHB1YmxpYyBpZGVudGlmaWVyIGFuZCB0aGUgc3lzdGVtIGlkZW50aWZpZXIuCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfU1lTVEVNTElURVJBTF9JTl9FWFRFUk5BTElEID0gV2hpdGUgc3BhY2UgaXMgcmVxdWlyZWQgYmV0d2VlbiBcIlNZU1RFTVwiIGFuZCB0aGUgc3lzdGVtIGlkZW50aWZpZXIuCi0gICAgICAgIE1TR19VUklfRlJBR01FTlRfSU5fU1lTVEVNSUQgPSBUaGUgZnJhZ21lbnQgaWRlbnRpZmllciBzaG91bGQgbm90IGJlIHNwZWNpZmllZCBhcyBwYXJ0IG9mIHRoZSBzeXN0ZW0gaWRlbnRpZmllciBcInswfVwiLgotIyA0LjcgTm90YXRpb24gRGVjbGFyYXRpb25zCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfTk9UQVRJT05fTkFNRV9JTl9OT1RBVElPTkRFQ0wgPSBXaGl0ZSBzcGFjZSBpcyByZXF1aXJlZCBhZnRlciBcIjwhTk9UQVRJT05cIiBpbiB0aGUgbm90YXRpb24gZGVjbGFyYXRpb24uCi0gICAgICAgIE1TR19OT1RBVElPTl9OQU1FX1JFUVVJUkVEX0lOX05PVEFUSU9OREVDTCA9IFRoZSBuYW1lIG9mIHRoZSBub3RhdGlvbiBpcyByZXF1aXJlZCBpbiB0aGUgbm90YXRpb24gZGVjbGFyYXRpb24uCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9BRlRFUl9OT1RBVElPTl9OQU1FX0lOX05PVEFUSU9OREVDTCA9IFdoaXRlIHNwYWNlIGlzIHJlcXVpcmVkIGFmdGVyIHRoZSBub3RhdGlvbiBuYW1lIFwiezB9XCIgaW4gdGhlIG5vdGF0aW9uIGRlY2xhcmF0aW9uLgotICAgICAgICBFeHRlcm5hbElEb3JQdWJsaWNJRFJlcXVpcmVkID0gVGhlIGRlY2xhcmF0aW9uIGZvciB0aGUgbm90YXRpb24gXCJ7MH1cIiBtdXN0IGluY2x1ZGUgYSBzeXN0ZW0gb3IgcHVibGljIGlkZW50aWZpZXIuCi0gICAgICAgIE5vdGF0aW9uRGVjbFVudGVybWluYXRlZCA9IFRoZSBkZWNsYXJhdGlvbiBmb3IgdGhlIG5vdGF0aW9uIFwiezB9XCIgbXVzdCBlbmQgd2l0aCAnJz4nJy4KLSAgICAgICAgCi0jIFZhbGlkYXRpb24gbWVzc2FnZXMKLSAgICAgICAgRHVwbGljYXRlVHlwZUluTWl4ZWRDb250ZW50ID0gVGhlIGVsZW1lbnQgdHlwZSBcInsxfVwiIHdhcyBhbHJlYWR5IHNwZWNpZmllZCBpbiB0aGUgY29udGVudCBtb2RlbCBvZiB0aGUgZWxlbWVudCBkZWNsIFwiezB9XCIuCi0gICAgICAgIEVOVElUSUVTSW52YWxpZCA9IEF0dHJpYnV0ZSB2YWx1ZSBcInsxfVwiIG9mIHR5cGUgRU5USVRJRVMgbXVzdCBiZSB0aGUgbmFtZXMgb2Ygb25lIG9yIG1vcmUgdW5wYXJzZWQgZW50aXRpZXMuCi0gICAgICAgIEVOVElUWUludmFsaWQgPSBBdHRyaWJ1dGUgdmFsdWUgXCJ7MX1cIiBvZiB0eXBlIEVOVElUWSBtdXN0IGJlIHRoZSBuYW1lIG9mIGFuIHVucGFyc2VkIGVudGl0eS4KLSAgICAgICAgSUREZWZhdWx0VHlwZUludmFsaWQgPSBUaGUgSUQgYXR0cmlidXRlIFwiezB9XCIgbXVzdCBoYXZlIGEgZGVjbGFyZWQgZGVmYXVsdCBvZiBcIiNJTVBMSUVEXCIgb3IgXCIjUkVRVUlSRURcIi4KLSAgICAgICAgSURJbnZhbGlkID0gQXR0cmlidXRlIHZhbHVlIFwiezB9XCIgb2YgdHlwZSBJRCBtdXN0IGJlIGEgbmFtZS4KLSAgICAgICAgSURJbnZhbGlkV2l0aE5hbWVzcGFjZXMgPSBBdHRyaWJ1dGUgdmFsdWUgXCJ7MH1cIiBvZiB0eXBlIElEIG11c3QgYmUgYW4gTkNOYW1lIHdoZW4gbmFtZXNwYWNlcyBhcmUgZW5hYmxlZC4KLSAgICAgICAgSUROb3RVbmlxdWUgPSBBdHRyaWJ1dGUgdmFsdWUgXCJ7MH1cIiBvZiB0eXBlIElEIG11c3QgYmUgdW5pcXVlIHdpdGhpbiB0aGUgZG9jdW1lbnQuCi0gICAgICAgIElEUkVGSW52YWxpZCA9IEF0dHJpYnV0ZSB2YWx1ZSBcInswfVwiIG9mIHR5cGUgSURSRUYgbXVzdCBiZSBhIG5hbWUuCi0gICAgICAgIElEUkVGSW52YWxpZFdpdGhOYW1lc3BhY2VzID0gQXR0cmlidXRlIHZhbHVlIFwiezB9XCIgb2YgdHlwZSBJRFJFRiBtdXN0IGJlIGFuIE5DTmFtZSB3aGVuIG5hbWVzcGFjZXMgYXJlIGVuYWJsZWQuCi0gICAgICAgIElEUkVGU0ludmFsaWQgPSBBdHRyaWJ1dGUgdmFsdWUgXCJ7MH1cIiBvZiB0eXBlIElEUkVGUyBtdXN0IGJlIG9uZSBvciBtb3JlIG5hbWVzLgotICAgICAgICBJTExfRk9STUVEX1BBUkFNRVRFUl9FTlRJVFlfV0hFTl9VU0VEX0lOX0RFQ0wgPSBUaGUgcmVwbGFjZW1lbnQgdGV4dCBvZiBwYXJhbWV0ZXIgZW50aXR5IFwiezB9XCIgbXVzdCBpbmNsdWRlIHByb3Blcmx5IG5lc3RlZCBkZWNsYXJhdGlvbnMgd2hlbiB0aGUgZW50aXR5IHJlZmVyZW5jZSBpcyB1c2VkIGFzIGEgY29tcGxldGUgZGVjbGFyYXRpb24uCi0gICAgICAgIEltcHJvcGVyRGVjbGFyYXRpb25OZXN0aW5nID0gVGhlIHJlcGxhY2VtZW50IHRleHQgb2YgcGFyYW1ldGVyIGVudGl0eSBcInswfVwiIG11c3QgaW5jbHVkZSBwcm9wZXJseSBuZXN0ZWQgZGVjbGFyYXRpb25zLgotICAgICAgICBJbXByb3Blckdyb3VwTmVzdGluZyA9IFRoZSByZXBsYWNlbWVudCB0ZXh0IG9mIHBhcmFtZXRlciBlbnRpdHkgXCJ7MH1cIiBtdXN0IGluY2x1ZGUgcHJvcGVybHkgbmVzdGVkIHBhaXJzIG9mIHBhcmVudGhlc2VzLgotICAgICAgICBJTlZBTElEX1BFX0lOX0NPTkRJVElPTkFMID0gVGhlIHJlcGxhY2VtZW50IHRleHQgb2YgcGFyYW1ldGVyIGVudGl0eSBcInswfVwiIG11c3QgaW5jbHVkZSB0aGUgZW50aXJlIGNvbmRpdGlvbmFsIHNlY3Rpb24gb3IganVzdCBJTkNMVURFIG9yIElHTk9SRS4KLSAgICAgICAgTVNHX0FUVFJJQlVURV9OT1RfREVDTEFSRUQgPSBBdHRyaWJ1dGUgXCJ7MX1cIiBtdXN0IGJlIGRlY2xhcmVkIGZvciBlbGVtZW50IHR5cGUgXCJ7MH1cIi4KLSAgICAgICAgTVNHX0FUVFJJQlVURV9WQUxVRV9OT1RfSU5fTElTVCA9IEF0dHJpYnV0ZSBcInswfVwiIHdpdGggdmFsdWUgXCJ7MX1cIiBtdXN0IGhhdmUgYSB2YWx1ZSBmcm9tIHRoZSBsaXN0IFwiezJ9XCIuCi0gICAgICAgIE1TR19BVFRWQUxVRV9DSEFOR0VEX0RVUklOR19OT1JNQUxJWkFUSU9OX1dIRU5fU1RBTkRBTE9ORSA9IFRoZSB2YWx1ZSBcInsxfVwiIG9mIGF0dHJpYnV0ZSBcInswfVwiIG11c3Qgbm90IGJlIGNoYW5nZWQgYnkgbm9ybWFsaXphdGlvbiAodG8gXCJ7Mn1cIikgaW4gYSBzdGFuZGFsb25lIGRvY3VtZW50LgotICAgICAgICBNU0dfQ09OVEVOVF9JTkNPTVBMRVRFID0gVGhlIGNvbnRlbnQgb2YgZWxlbWVudCB0eXBlIFwiezB9XCIgaXMgaW5jb21wbGV0ZSwgaXQgbXVzdCBtYXRjaCBcInsxfVwiLgotICAgICAgICBNU0dfQ09OVEVOVF9JTlZBTElEID0gVGhlIGNvbnRlbnQgb2YgZWxlbWVudCB0eXBlIFwiezB9XCIgbXVzdCBtYXRjaCBcInsxfVwiLgotICAgICAgICBNU0dfQ09OVEVOVF9JTlZBTElEX1NQRUNJRklFRCA9IFRoZSBjb250ZW50IG9mIGVsZW1lbnQgdHlwZSBcInswfVwiIG11c3QgbWF0Y2ggXCJ7MX1cIi4gIENoaWxkcmVuIG9mIHR5cGUgXCJ7Mn1cIiBhcmUgbm90IGFsbG93ZWQuCi0gICAgICAgIE1TR19ERUZBVUxURURfQVRUUklCVVRFX05PVF9TUEVDSUZJRUQgPSBBdHRyaWJ1dGUgXCJ7MX1cIiBmb3IgZWxlbWVudCB0eXBlIFwiezB9XCIgaGFzIGEgZGVmYXVsdCB2YWx1ZSBhbmQgbXVzdCBiZSBzcGVjaWZpZWQgaW4gYSBzdGFuZGFsb25lIGRvY3VtZW50LgotICAgICAgICBNU0dfRFVQTElDQVRFX0FUVERFRiA9IEF0dHJpYnV0ZSBcInsxfVwiIGlzIGFscmVhZHkgZGVjbGFyZWQgZm9yIGVsZW1lbnQgdHlwZSBcInswfVwiLgotICAgICAgICBNU0dfRUxFTUVOVF9BTFJFQURZX0RFQ0xBUkVEID0gRWxlbWVudCB0eXBlIFwiezB9XCIgbXVzdCBub3QgYmUgZGVjbGFyZWQgbW9yZSB0aGFuIG9uY2UuCi0gICAgICAgIE1TR19FTEVNRU5UX05PVF9ERUNMQVJFRCA9IEVsZW1lbnQgdHlwZSBcInswfVwiIG11c3QgYmUgZGVjbGFyZWQuCi0gICAgICAgIE1TR19HUkFNTUFSX05PVF9GT1VORCA9IERvY3VtZW50IGlzIGludmFsaWQ6IG5vIGdyYW1tYXIgZm91bmQuCi0gICAgICAgIE1TR19FTEVNRU5UX1dJVEhfSURfUkVRVUlSRUQgPSBBbiBlbGVtZW50IHdpdGggdGhlIGlkZW50aWZpZXIgXCJ7MH1cIiBtdXN0IGFwcGVhciBpbiB0aGUgZG9jdW1lbnQuCi0gICAgICAgIE1TR19FWFRFUk5BTF9FTlRJVFlfTk9UX1BFUk1JVFRFRCA9IFRoZSByZWZlcmVuY2UgdG8gZXh0ZXJuYWwgZW50aXR5IFwiezB9XCIgaXMgbm90IHBlcm1pdHRlZCBpbiBhIHN0YW5kYWxvbmUgZG9jdW1lbnQuCi0gICAgICAgIE1TR19GSVhFRF9BVFRWQUxVRV9JTlZBTElEID0gQXR0cmlidXRlIFwiezF9XCIgd2l0aCB2YWx1ZSBcInsyfVwiIG11c3QgaGF2ZSBhIHZhbHVlIG9mIFwiezN9XCIuCi0gICAgICAgIE1TR19NT1JFX1RIQU5fT05FX0lEX0FUVFJJQlVURSA9IEVsZW1lbnQgdHlwZSBcInswfVwiIGFscmVhZHkgaGFzIGF0dHJpYnV0ZSBcInsxfVwiIG9mIHR5cGUgSUQsIGEgc2Vjb25kIGF0dHJpYnV0ZSBcInsyfVwiIG9mIHR5cGUgSUQgaXMgbm90IHBlcm1pdHRlZC4KLSAgICAgICAgTVNHX01PUkVfVEhBTl9PTkVfTk9UQVRJT05fQVRUUklCVVRFID0gRWxlbWVudCB0eXBlIFwiezB9XCIgYWxyZWFkeSBoYXMgYXR0cmlidXRlIFwiezF9XCIgb2YgdHlwZSBOT1RBVElPTiwgYSBzZWNvbmQgYXR0cmlidXRlIFwiezJ9XCIgb2YgdHlwZSBOT1RBVElPTiBpcyBub3QgcGVybWl0dGVkLgotICAgICAgICBNU0dfTk9UQVRJT05fTk9UX0RFQ0xBUkVEX0ZPUl9OT1RBVElPTlRZUEVfQVRUUklCVVRFID0gVGhlIG5vdGF0aW9uIFwiezF9XCIgbXVzdCBiZSBkZWNsYXJlZCB3aGVuIHJlZmVyZW5jZWQgaW4gdGhlIG5vdGF0aW9uIHR5cGUgbGlzdCBmb3IgYXR0cmlidXRlIFwiezB9XCIuCi0gICAgICAgIE1TR19OT1RBVElPTl9OT1RfREVDTEFSRURfRk9SX1VOUEFSU0VEX0VOVElUWURFQ0wgPSBUaGUgbm90YXRpb24gXCJ7MX1cIiBtdXN0IGJlIGRlY2xhcmVkIHdoZW4gcmVmZXJlbmNlZCBpbiB0aGUgdW5wYXJzZWQgZW50aXR5IGRlY2xhcmF0aW9uIGZvciBcInswfVwiLgotICAgICAgICBNU0dfUkVGRVJFTkNFX1RPX0VYVEVSTkFMTFlfREVDTEFSRURfRU5USVRZX1dIRU5fU1RBTkRBTE9ORSA9IFRoZSByZWZlcmVuY2UgdG8gZW50aXR5IFwiezB9XCIgZGVjbGFyZWQgaW4gYW4gZXh0ZXJuYWwgcGFyc2VkIGVudGl0eSBpcyBub3QgcGVybWl0dGVkIGluIGEgc3RhbmRhbG9uZSBkb2N1bWVudC4KLSAgICAgICAgTVNHX1JFUVVJUkVEX0FUVFJJQlVURV9OT1RfU1BFQ0lGSUVEID0gQXR0cmlidXRlIFwiezF9XCIgaXMgcmVxdWlyZWQgYW5kIG11c3QgYmUgc3BlY2lmaWVkIGZvciBlbGVtZW50IHR5cGUgXCJ7MH1cIi4KLSAgICAgICAgTVNHX1dISVRFX1NQQUNFX0lOX0VMRU1FTlRfQ09OVEVOVF9XSEVOX1NUQU5EQUxPTkUgPSBXaGl0ZSBzcGFjZSBtdXN0IG5vdCBvY2N1ciBiZXR3ZWVuIGVsZW1lbnRzIGRlY2xhcmVkIGluIGFuIGV4dGVybmFsIHBhcnNlZCBlbnRpdHkgd2l0aCBlbGVtZW50IGNvbnRlbnQgaW4gYSBzdGFuZGFsb25lIGRvY3VtZW50LgotICAgICAgICBOTVRPS0VOSW52YWxpZCA9IEF0dHJpYnV0ZSB2YWx1ZSBcInswfVwiIG9mIHR5cGUgTk1UT0tFTiBtdXN0IGJlIGEgbmFtZSB0b2tlbi4KLSAgICAgICAgTk1UT0tFTlNJbnZhbGlkID0gQXR0cmlidXRlIHZhbHVlIFwiezB9XCIgb2YgdHlwZSBOTVRPS0VOUyBtdXN0IGJlIG9uZSBvciBtb3JlIG5hbWUgdG9rZW5zLgotICAgICAgICBOb05vdGF0aW9uT25FbXB0eUVsZW1lbnQgPSBFbGVtZW50IHR5cGUgXCJ7MH1cIiB3aGljaCB3YXMgZGVjbGFyZWQgRU1QVFkgY2Fubm90IGRlY2xhcmUgYXR0cmlidXRlIFwiezF9XCIgb2YgdHlwZSBOT1RBVElPTi4KLSAgICAgICAgUm9vdEVsZW1lbnRUeXBlTXVzdE1hdGNoRG9jdHlwZWRlY2wgPSBEb2N1bWVudCByb290IGVsZW1lbnQgXCJ7MX1cIiwgbXVzdCBtYXRjaCBET0NUWVBFIHJvb3QgXCJ7MH1cIi4KLSAgICAgICAgVW5kZWNsYXJlZEVsZW1lbnRJbkNvbnRlbnRTcGVjID0gVGhlIGNvbnRlbnQgbW9kZWwgb2YgZWxlbWVudCBcInswfVwiIHJlZmVycyB0byB0aGUgdW5kZWNsYXJlZCBlbGVtZW50IFwiezF9XCIuCi0gICAgICAgIFVuaXF1ZU5vdGF0aW9uTmFtZSA9IFRoZSBkZWNsYXJhdGlvbiBmb3IgdGhlIG5vdGF0aW9uIFwiezB9XCIgaXMgbm90IHVuaXF1ZS4gQSBnaXZlbiBOYW1lIG11c3Qgbm90IGJlIGRlY2xhcmVkIGluIG1vcmUgdGhhbiBvbmUgbm90YXRpb24gZGVjbGFyYXRpb24uCi0gICAgICAgIEVOVElUWUZhaWxlZEluaXRpYWxpemVHcmFtbWFyID0gIEVOVElUWURhdGF0eXBlIFZhbGlkYXRvcjogRmFpbGVkIE5lZWQgdG8gY2FsbCBpbml0aWFsaXplIG1ldGhvZCB3aXRoIGEgdmFsaWQgR3JhbW1hciByZWZlcmVuY2UuIAkKLSAgICAgICAgRU5USVRZTm90VW5wYXJzZWQgPSBFTlRJVFkgXCJ7MH1cIiBpcyBub3QgdW5wYXJzZWQuCi0gICAgICAgIEVOVElUWU5vdFZhbGlkID0gRU5USVRZIFwiezB9XCIgaXMgbm90IHZhbGlkLgotICAgICAgICBFbXB0eUxpc3QgPSBWYWx1ZSBvZiB0eXBlIEVOVElUSUVTLCBJRFJFRlMsIGFuZCBOTVRPS0VOUyBjYW5ub3QgYmUgZW1wdHkgbGlzdC4KLQotIyBFbnRpdHkgcmVsYXRlZCBtZXNzYWdlcwotIyAzLjEgU3RhcnQtVGFncywgRW5kLVRhZ3MsIGFuZCBFbXB0eS1FbGVtZW50IFRhZ3MKLSAgICAgICAgUmVmZXJlbmNlVG9FeHRlcm5hbEVudGl0eSA9IFRoZSBleHRlcm5hbCBlbnRpdHkgcmVmZXJlbmNlIFwiJnswfTtcIiBpcyBub3QgcGVybWl0dGVkIGluIGFuIGF0dHJpYnV0ZSB2YWx1ZS4KLSAgICAgICAgQWNjZXNzRXh0ZXJuYWxEVEQgPSBFeHRlcm5hbCBEVEQ6IEZhaWxlZCB0byByZWFkIGV4dGVybmFsIERURCAnJ3swfScnLCBiZWNhdXNlICcnezF9JycgYWNjZXNzIGlzIG5vdCBhbGxvd2VkIGR1ZSB0byByZXN0cmljdGlvbiBzZXQgYnkgdGhlIGFjY2Vzc0V4dGVybmFsRFREIHByb3BlcnR5LgotICAgICAgICBBY2Nlc3NFeHRlcm5hbEVudGl0eSA9IEV4dGVybmFsIEVudGl0eTogRmFpbGVkIHRvIHJlYWQgZXh0ZXJuYWwgZG9jdW1lbnQgJyd7MH0nJywgYmVjYXVzZSAnJ3sxfScnIGFjY2VzcyBpcyBub3QgYWxsb3dlZCBkdWUgdG8gcmVzdHJpY3Rpb24gc2V0IGJ5IHRoZSBhY2Nlc3NFeHRlcm5hbERURCBwcm9wZXJ0eS4KLQotIyA0LjEgQ2hhcmFjdGVyIGFuZCBFbnRpdHkgUmVmZXJlbmNlcwotICAgICAgICBFbnRpdHlOb3REZWNsYXJlZCA9IFRoZSBlbnRpdHkgXCJ7MH1cIiB3YXMgcmVmZXJlbmNlZCwgYnV0IG5vdCBkZWNsYXJlZC4KLSAgICAgICAgUmVmZXJlbmNlVG9VbnBhcnNlZEVudGl0eSA9IFRoZSB1bnBhcnNlZCBlbnRpdHkgcmVmZXJlbmNlIFwiJnswfTtcIiBpcyBub3QgcGVybWl0dGVkLgotICAgICAgICBSZWN1cnNpdmVSZWZlcmVuY2UgPSBSZWN1cnNpdmUgZW50aXR5IHJlZmVyZW5jZSBcInswfVwiLiAoUmVmZXJlbmNlIHBhdGg6IHsxfSksCi0gICAgICAgIFJlY3Vyc2l2ZUdlbmVyYWxSZWZlcmVuY2UgPSBSZWN1cnNpdmUgZ2VuZXJhbCBlbnRpdHkgcmVmZXJlbmNlIFwiJnswfTtcIi4gKFJlZmVyZW5jZSBwYXRoOiB7MX0pLAotICAgICAgICBSZWN1cnNpdmVQRVJlZmVyZW5jZSA9IFJlY3Vyc2l2ZSBwYXJhbWV0ZXIgZW50aXR5IHJlZmVyZW5jZSBcIiV7MH07XCIuIChSZWZlcmVuY2UgcGF0aDogezF9KSwKLSMgNC4zLjMgQ2hhcmFjdGVyIEVuY29kaW5nIGluIEVudGl0aWVzCi0gICAgICAgIEVuY29kaW5nTm90U3VwcG9ydGVkID0gVGhlIGVuY29kaW5nIFwiezB9XCIgaXMgbm90IHN1cHBvcnRlZC4KLSAgICAgICAgRW5jb2RpbmdSZXF1aXJlZCA9IEEgcGFyc2VkIGVudGl0eSBub3QgZW5jb2RlZCBpbiBlaXRoZXIgVVRGLTggb3IgVVRGLTE2IG11c3QgY29udGFpbiBhbiBlbmNvZGluZyBkZWNsYXJhdGlvbi4KLSAgICAgICAgCi0jIE5hbWVzcGFjZXMgc3VwcG9ydAotIyA0LiBVc2luZyBRdWFsaWZpZWQgTmFtZXMKLSAgICAgICAgSWxsZWdhbFFOYW1lID0gRWxlbWVudCBvciBhdHRyaWJ1dGUgZG8gbm90IG1hdGNoIFFOYW1lIHByb2R1Y3Rpb246IFFOYW1lOjo9KE5DTmFtZSc6Jyk/TkNOYW1lLiAKLSAgICAgICAgRWxlbWVudFhNTE5TUHJlZml4ID0gRWxlbWVudCBcInswfVwiIGNhbm5vdCBoYXZlIFwieG1sbnNcIiBhcyBpdHMgcHJlZml4LgotICAgICAgICBFbGVtZW50UHJlZml4VW5ib3VuZCA9IFRoZSBwcmVmaXggXCJ7MH1cIiBmb3IgZWxlbWVudCBcInsxfVwiIGlzIG5vdCBib3VuZC4KLSAgICAgICAgQXR0cmlidXRlUHJlZml4VW5ib3VuZCA9IFRoZSBwcmVmaXggXCJ7Mn1cIiBmb3IgYXR0cmlidXRlIFwiezF9XCIgYXNzb2NpYXRlZCB3aXRoIGFuIGVsZW1lbnQgdHlwZSBcInswfVwiIGlzIG5vdCBib3VuZC4KLSAgICAgICAgRW1wdHlQcmVmaXhlZEF0dE5hbWUgPSBUaGUgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZSBcInswfVwiIGlzIGludmFsaWQuIFByZWZpeGVkIG5hbWVzcGFjZSBiaW5kaW5ncyBtYXkgbm90IGJlIGVtcHR5LgotICAgICAgICBQcmVmaXhEZWNsYXJlZCA9IFRoZSBuYW1lc3BhY2UgcHJlZml4IFwiezB9XCIgd2FzIG5vdCBkZWNsYXJlZC4KLSAgICAgICAgQ2FudEJpbmRYTUxOUyA9IFRoZSBwcmVmaXggInhtbG5zIiBjYW5ub3QgYmUgYm91bmQgdG8gYW55IG5hbWVzcGFjZSBleHBsaWNpdGx5OyBuZWl0aGVyIGNhbiB0aGUgbmFtZXNwYWNlIGZvciAieG1sbnMiIGJlIGJvdW5kIHRvIGFueSBwcmVmaXggZXhwbGljaXRseS4KLSAgICAgICAgQ2FudEJpbmRYTUwgPSBUaGUgcHJlZml4ICJ4bWwiIGNhbm5vdCBiZSBib3VuZCB0byBhbnkgbmFtZXNwYWNlIG90aGVyIHRoYW4gaXRzIHVzdWFsIG5hbWVzcGFjZTsgbmVpdGhlciBjYW4gdGhlIG5hbWVzcGFjZSBmb3IgInhtbCIgYmUgYm91bmQgdG8gYW55IHByZWZpeCBvdGhlciB0aGFuICJ4bWwiLgotICAgICAgICBNU0dfQVRUX0RFRkFVTFRfSU5WQUxJRCA9IFRoZSBkZWZhdWx0VmFsdWUgXCJ7MX1cIiBvZiBhdHRyaWJ1dGUgXCJ7MH1cIiBpcyBub3QgbGVnYWwgYXMgZm9yIHRoZSBsZXhpY2FsIGNvbnN0cmFpbnRzIG9mIHRoaXMgYXR0cmlidXRlIHR5cGUuCi0KLSMgUkVWSVNJVDogVGhlc2UgbmVlZCBtZXNzYWdlcwotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQUZURVJfU1lTVEVNTElURVJBTF9JTl9FWFRFUk5BTElEPU1TR19TUEFDRV9SRVFVSVJFRF9BRlRFUl9TWVNURU1MSVRFUkFMX0lOX0VYVEVSTkFMSUQKLSAgICAgICAgT3BlblF1b3RlTWlzc2luZ0luRGVjbD1PcGVuUXVvdGVNaXNzaW5nSW5EZWNsCi0gICAgICAgIEludmFsaWRDaGFySW5MaXRlcmFsPUludmFsaWRDaGFySW5MaXRlcmFsCi0KLQotIyBJbXBsZW1lbnRhdGlvbiBsaW1pdHMKLSAgICAgICAgRW50aXR5RXhwYW5zaW9uTGltaXQ9SkFYUDAwMDEwMDAxOiBUaGUgcGFyc2VyIGhhcyBlbmNvdW50ZXJlZCBtb3JlIHRoYW4gXCJ7MH1cIiBlbnRpdHkgZXhwYW5zaW9ucyBpbiB0aGlzIGRvY3VtZW50OyB0aGlzIGlzIHRoZSBsaW1pdCBpbXBvc2VkIGJ5IHRoZSBKREsuCi0gICAgICAgIEVsZW1lbnRBdHRyaWJ1dGVMaW1pdD1KQVhQMDAwMTAwMDI6ICBFbGVtZW50IFwiezB9XCIgaGFzIG1vcmUgdGhhbiBcInsxfVwiIGF0dHJpYnV0ZXMsIFwiezF9XCIgaXMgdGhlIGxpbWl0IGltcG9zZWQgYnkgdGhlIEpESy4KLSAgICAgICAgTWF4RW50aXR5U2l6ZUxpbWl0PUpBWFAwMDAxMDAwMzogVGhlIGxlbmd0aCBvZiBlbnRpdHkgXCJ7MH1cIiBpcyBcInsxfVwiIHRoYXQgZXhjZWVkcyB0aGUgXCJ7Mn1cIiBsaW1pdCBzZXQgYnkgXCJ7M31cIi4KLSAgICAgICAgVG90YWxFbnRpdHlTaXplTGltaXQ9SkFYUDAwMDEwMDA0OiBUaGUgYWNjdW11bGF0ZWQgc2l6ZSBvZiBlbnRpdGllcyBpcyBcInswfVwiIHRoYXQgZXhjZWVkZWQgdGhlIFwiezF9XCIgbGltaXQgc2V0IGJ5IFwiezJ9XCIuCi0gICAgICAgIE1heFhNTE5hbWVMaW1pdD1KQVhQMDAwMTAwMDU6IFRoZSBsZW5ndGggb2YgZW50aXR5IFwiezB9XCIgaXMgXCJ7MX1cIiB0aGF0IGV4Y2VlZHMgdGhlIFwiezJ9XCIgbGltaXQgc2V0IGJ5IFwiezN9XCIuCi0gICAgICAgIE1heEVsZW1lbnREZXB0aExpbWl0PUpBWFAwMDAxMDAwNjogVGhlIGVsZW1lbnQgXCJ7MH1cIiBoYXMgYSBkZXB0aCBvZiBcInsxfVwiIHRoYXQgZXhjZWVkcyB0aGUgbGltaXQgXCJ7Mn1cIiBzZXQgYnkgXCJ7M31cIi4KLSAgICAgICAgRW50aXR5UmVwbGFjZW1lbnRMaW1pdD1KQVhQMDAwMTAwMDc6IFRoZSB0b3RhbCBudW1iZXIgb2Ygbm9kZXMgaW4gZW50aXR5IHJlZmVyZW5jZXMgaXMgXCJ7MH1cIiB0aGF0IGlzIG92ZXIgdGhlIGxpbWl0IFwiezF9XCIgc2V0IGJ5IFwiezJ9XCIuCi0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hNTE1lc3NhZ2VzX2RlLnByb3BlcnRpZXMgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9YTUxNZXNzYWdlc19kZS5wcm9wZXJ0aWVzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwODQ4MjcwLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hNTE1lc3NhZ2VzX2RlLnByb3BlcnRpZXMKKysrIC9kZXYvbnVsbApAQCAtMSwzMDUgKzAsMCBAQAotIyBUaGlzIGZpbGUgY29udGFpbnMgZXJyb3IgYW5kIHdhcm5pbmcgbWVzc2FnZXMgcmVsYXRlZCB0byBYTUwKLSMgVGhlIG1lc3NhZ2VzIGFyZSBhcnJhbmdlZCBpbiBrZXkgYW5kIHZhbHVlIHR1cGxlcyBpbiBhIExpc3RSZXNvdXJjZUJ1bmRsZS4KLSMKLSMgQHZlcnNpb24KLQotICAgICAgICBCYWRNZXNzYWdlS2V5ID0gRGllIHp1bSBNZWxkdW5nc3NjaGxcdTAwRkNzc2VsIGdlaFx1MDBGNnJpZ2UgRmVobGVybWVsZHVuZyBrYW5uIG5pY2h0IGdlZnVuZGVuIHdlcmRlbi4KLSAgICAgICAgRm9ybWF0RmFpbGVkID0gQmVpbSBGb3JtYXRpZXJlbiBkZXIgZm9sZ2VuZGVuIE1lbGR1bmcgaXN0IGVpbiBpbnRlcm5lciBGZWhsZXIgYXVmZ2V0cmV0ZW46XG4gIAotICAgICAgICAKLSMgRG9jdW1lbnQgbWVzc2FnZXMKLSAgICAgICAgUHJlbWF0dXJlRU9GPVZvcnplaXRpZ2VzIERhdGVpZW5kZS4KLSMgMi4xIFdlbGwtRm9ybWVkIFhNTCBEb2N1bWVudHMKLSAgICAgICAgUm9vdEVsZW1lbnRSZXF1aXJlZCA9IFJvb3QtRWxlbWVudCBpc3QgaW4gZWluZW0gb3JkbnVuZ3NnZW1cdTAwRTRcdTAwREYgZm9ybWF0aWVydGVuIERva3VtZW50IGVyZm9yZGVybGljaC4KLSMgMi4yIENoYXJhY3RlcnMKLQotICAgICAgICBJbnZhbGlkQ2hhckluQ0RTZWN0ID0gVW5nXHUwMEZDbHRpZ2VzIFhNTC1aZWljaGVuIChVbmljb2RlOiAweHswfSkgd3VyZGUgaW0gQ0RBVEEtQWJzY2huaXR0IGdlZnVuZGVuLgotICAgICAgICBJbnZhbGlkQ2hhckluQ29udGVudCA9IFVuZ1x1MDBGQ2x0aWdlcyBYTUwtWmVpY2hlbiAoVW5pY29kZTogMHh7MH0pIHd1cmRlIGltIEVsZW1lbnRjb250ZW50IGRlcyBEb2t1bWVudHMgZ2VmdW5kZW4uCi0gICAgICAgIFR3b0NvbG9uc0luUU5hbWUgPSBVbmdcdTAwRkNsdGlnZXIgendlaXRlciAiOiIgd3VyZGUgaW0gRWxlbWVudHR5cCBvZGVyIEF0dHJpYnV0bmFtZW4gZ2VmdW5kZW4uCi0gICAgICAgIENvbG9uTm90TGVnYWxXaXRoTlMgPSBEb3BwZWxwdW5rdCBuaWNodCB6dWxcdTAwRTRzc2lnIGltIE5hbWVuICJ7MH0iLCB3ZW5uIE5hbWVzcGFjZXMgYWt0aXZpZXJ0IHNpbmQuCi0gICAgICAgIEludmFsaWRDaGFySW5NaXNjID0gVW5nXHUwMEZDbHRpZ2VzIFhNTC1aZWljaGVuIChVbmljb2RlOiAweHswfSkgd3VyZGUgaW0gTWFya3VwIG5hY2ggRW5kZSBkZXMgRWxlbWVudGNvbnRlbnRzIGdlZnVuZGVuLgotICAgICAgICBJbnZhbGlkQ2hhckluUHJvbG9nID0gVW5nXHUwMEZDbHRpZ2VzIFhNTC1aZWljaGVuIChVbmljb2RlOiAweHswfSkgd3VyZGUgaW0gUHJvbG9nIGRlcyBEb2t1bWVudHMgZ2VmdW5kZW4uCi0gICAgICAgIEludmFsaWRDaGFySW5YTUxEZWNsID0gVW5nXHUwMEZDbHRpZ2VzIFhNTC1aZWljaGVuIChVbmljb2RlOiAweHswfSkgd3VyZGUgaW4gZGVyIFhNTC1EZWtsYXJhdGlvbiBnZWZ1bmRlbi4KLSMgMi40IENoYXJhY3RlciBEYXRhIGFuZCBNYXJrdXAKLSAgICAgICAgQ0RFbmRJbkNvbnRlbnQgPSBaZWljaGVuZm9sZ2UiIl1dPiIgZGFyZiBudXIgaW0gQ29udGVudCBlbnRoYWx0ZW4gc2Vpbiwgd2VubiBzaWUgZGFzIEVuZGUgZWluZXMgQ0RBVEEtQWJzY2huaXR0cyBtYXJraWVydC4KLSMgMi43IENEQVRBIFNlY3Rpb25zCi0gICAgICAgIENEU2VjdFVudGVybWluYXRlZCA9IENEQVRBLUFic2Nobml0dCBtdXNzIG1pdCAiXV0+IiBlbmRlbi4KLSMgMi44IFByb2xvZyBhbmQgRG9jdW1lbnQgVHlwZSBEZWNsYXJhdGlvbgotICAgICAgICBYTUxEZWNsTXVzdEJlRmlyc3QgPSBYTUwtRGVrbGFyYXRpb24gZGFyZiBudXIgZ2FueiBhbSBBbmZhbmcgZGVzIERva3VtZW50cyBlbnRoYWx0ZW4gc2Vpbi4KLSAgICAgICAgRXFSZXF1aXJlZEluWE1MRGVjbCA9IFplaWNoZW4gIiA9ICIgbXVzcyBhdWYgInswfSIgaW4gZGVyIFhNTC1EZWtsYXJhdGlvbiBmb2xnZW4uCi0gICAgICAgIFF1b3RlUmVxdWlyZWRJblhNTERlY2wgPSBEZXIgV2VydCBuYWNoICJ7MH0iIGluIGRlciBYTUwtRGVrbGFyYXRpb24gbXVzcyBlaW5lIFplaWNoZW5mb2xnZSBpbiBBbmZcdTAwRkNocnVuZ3N6ZWljaGVuIHNlaW4uCi0gICAgICAgIFhNTERlY2xVbnRlcm1pbmF0ZWQgPSBYTUwtRGVrbGFyYXRpb24gbXVzcyBtaXQgIj8+IiBlbmRlbi4KLSAgICAgICAgVmVyc2lvbkluZm9SZXF1aXJlZCA9IFZlcnNpb24gaXN0IGluIGRlciBYTUwtRGVrbGFyYXRpb24gZXJmb3JkZXJsaWNoLgotICAgICAgICBTcGFjZVJlcXVpcmVkQmVmb3JlVmVyc2lvbkluWE1MRGVjbCA9IExlZXJzdGVsbGUgdm9yIGRlbSBWZXJzaW9uc3BzZXVkb2F0dHJpYnV0IGluIGRlciBYTUwtRGVrbGFyYXRpb24gZXJmb3JkZXJsaWNoLgotICAgICAgICBTcGFjZVJlcXVpcmVkQmVmb3JlRW5jb2RpbmdJblhNTERlY2wgPSBMZWVyc3RlbGxlIHZvciBkZW0gQ29kaWVydW5nc3BzZXVkb2F0dHJpYnV0IGluIGRlciBYTUwtRGVrbGFyYXRpb24gZXJmb3JkZXJsaWNoLgotICAgICAgICBTcGFjZVJlcXVpcmVkQmVmb3JlU3RhbmRhbG9uZSA9IExlZXJzdGVsbGUgdm9yIGRlbSBDb2RpZXJ1bmdzcHNldWRvYXR0cmlidXQgaW4gZGVyIFhNTC1EZWtsYXJhdGlvbiBlcmZvcmRlcmxpY2guCi0gICAgICAgIE1hcmt1cE5vdFJlY29nbml6ZWRJblByb2xvZyA9IE1hcmt1cCBpbSBEb2t1bWVudCB2b3IgZGVtIFJvb3QtRWxlbWVudCBtdXNzIG9yZG51bmdzZ2VtXHUwMEU0XHUwMERGIGZvcm1hdGllcnQgc2Vpbi4KLSAgICAgICAgTWFya3VwTm90UmVjb2duaXplZEluTWlzYyA9IE1hcmt1cCBpbSBEb2t1bWVudCBuYWNoIGRlbSBSb290LUVsZW1lbnQgbXVzcyBvcmRudW5nc2dlbVx1MDBFNFx1MDBERiBmb3JtYXRpZXJ0IHNlaW4uCi0gICAgICAgIEFscmVhZHlTZWVuRG9jdHlwZSA9IGRvY3R5cGUgYmVyZWl0cyBnZXNlaGVuLgotICAgICAgICBEb2N0eXBlTm90QWxsb3dlZCA9IERPQ1RZUEUgaXN0IG5pY2h0IHp1bFx1MDBFNHNzaWcsIHdlbm4gZGFzIEZlYXR1cmUgImh0dHA6Ly9hcGFjaGUub3JnL3htbC9mZWF0dXJlcy9kaXNhbGxvdy1kb2N0eXBlLWRlY2wiIGF1ZiAidHJ1ZSIgZ2VzZXR6dCBpc3QuCi0gICAgICAgIENvbnRlbnRJbGxlZ2FsSW5Qcm9sb2cgPSBDb250ZW50IGlzdCBuaWNodCB6dWxcdTAwRTRzc2lnIGluIFByb2xvZy4KLSAgICAgICAgUmVmZXJlbmNlSWxsZWdhbEluUHJvbG9nID0gUmVmZXJlbnogaXN0IG5pY2h0IHp1bFx1MDBFNHNzaWcgaW4gUHJvbG9nLgotIyBUcmFpbGluZyBNaXNjCi0gICAgICAgIENvbnRlbnRJbGxlZ2FsSW5UcmFpbGluZ01pc2M9Q29udGVudCBpc3QgbmljaHQgenVsXHUwMEU0c3NpZyBpbiBhbmdlaFx1MDBFNG5ndGVtIEFic2Nobml0dC4KLSAgICAgICAgUmVmZXJlbmNlSWxsZWdhbEluVHJhaWxpbmdNaXNjPVJlZmVyZW56IGlzdCBuaWNodCB6dWxcdTAwRTRzc2lnIGluIGFuZ2VoXHUwMEU0bmd0ZW0gQWJzY2huaXR0LgotICAgICAgICAKLSMgMi45IFN0YW5kYWxvbmUgRG9jdW1lbnQgRGVjbGFyYXRpb24KLSAgICAgICAgU0REZWNsSW52YWxpZCA9IFN0YW5kYWxvbmUtRG9rdW1lbnRkZWtsYXJhdGlvbnN3ZXJ0IG11c3MgIkphIiBvZGVyICJOZWluIiB1bmQgbmljaHQgInswfSIgc2Vpbi4KLSAgICAgICAgU0REZWNsTmFtZUludmFsaWQgPSBEZXIgU3RhbmRhbG9uZS1OYW1lIGluIGRlciBYTUwtRGVrbGFyYXRpb24gaXN0IG1cdTAwRjZnbGljaGVyd2Vpc2UgZmFsc2NoIGdlc2NocmllYmVuLgotIyAyLjEyIExhbmd1YWdlIElkZW50aWZpY2F0aW9uCi0gICAgICAgIFhNTExhbmdJbnZhbGlkID0geG1sOmxhbmctQXR0cmlidXR3ZXJ0ICJ7MH0iIGlzdCBlaW5lIHVuZ1x1MDBGQ2x0aWdlIFNwcmFjaC1JRC4KLSMgMy4gTG9naWNhbCBTdHJ1Y3R1cmVzCi0gICAgICAgIEVUYWdSZXF1aXJlZCA9IEVsZW1lbnR0eXAgInswfSIgbXVzcyBtaXQgZGVtIGVudHNwcmVjaGVuZGVuIEVuZHRhZyAiPC97MH0+IiBiZWVuZGV0IHdlcmRlbi4KLSMgMy4xIFN0YXJ0LVRhZ3MsIEVuZC1UYWdzLCBhbmQgRW1wdHktRWxlbWVudCBUYWdzCi0gICAgICAgIEVsZW1lbnRVbnRlcm1pbmF0ZWQgPSBBdWYgRWxlbWVudHR5cCAiezB9IiBtXHUwMEZDc3NlbiBlbnR3ZWRlciBBdHRyaWJ1dHNwZXppZmlrYXRpb25lbiwgIj4iIG9kZXIgIi8+IiBmb2xnZW4uCi0gICAgICAgIEVxUmVxdWlyZWRJbkF0dHJpYnV0ZSA9IE1pdCBFbGVtZW50dHlwICJ7MH0iIHZlcmtuXHUwMEZDcGZ0ZXIgQXR0cmlidXRuYW1lICJ7MX0iIG11c3Mgdm9tIFplaWNoZW4gIiA9ICIgZ2Vmb2xndCB3ZXJkZW4uCi0gICAgICAgIE9wZW5RdW90ZUV4cGVjdGVkID0gXHUwMEQ2ZmZuZW5kZXMgQW5mXHUwMEZDaHJ1bmdzemVpY2hlbiB3aXJkIGZcdTAwRkNyIEF0dHJpYnV0ICJ7MX0iIGVyd2FydGV0LCBkYXMgbWl0IEVsZW1lbnR0eXAgInswfSIgdmVya25cdTAwRkNwZnQgaXN0LgotICAgICAgICBDbG9zZVF1b3RlRXhwZWN0ZWQgPSBTY2hsaWVcdTAwREZlbmRlcyBBbmZcdTAwRkNocnVuZ3N6ZWljaGVuIHdpcmQgZlx1MDBGQ3IgQXR0cmlidXQgInsxfSIgZXJ3YXJ0ZXQsIGRhcyBtaXQgRWxlbWVudHR5cCAiezB9IiB2ZXJrblx1MDBGQ3BmdCBpc3QuCi0gICAgICAgIEF0dHJpYnV0ZU5vdFVuaXF1ZSA9IEF0dHJpYnV0ICJ7MX0iIHd1cmRlIGJlcmVpdHMgZlx1MDBGQ3IgRWxlbWVudCAiezB9IiBhbmdlZ2ViZW4uCi0gICAgICAgIEF0dHJpYnV0ZU5TTm90VW5pcXVlID0gQW4gTmFtZXNwYWNlICJ7Mn0iIGdlYnVuZGVuZXMgQXR0cmlidXQgInsxfSIgd3VyZGUgYmVyZWl0cyBmXHUwMEZDciBFbGVtZW50ICJ7MH0iIGFuZ2VnZWJlbi4KLSAgICAgICAgRVRhZ1VudGVybWluYXRlZCA9IEVuZHRhZyBmXHUwMEZDciBFbGVtZW50dHlwICJ7MH0iIG11c3MgbWl0IGVpbmVtICI+Ii1CZWdyZW56dW5nc3plaWNoZW4gZW5kZW4uCi0gICAgICAgIE1hcmt1cE5vdFJlY29nbml6ZWRJbkNvbnRlbnQgPSBEZXIgQ29udGVudCB2b24gRWxlbWVudGVuIG11c3MgYXVzIG9yZG51bmdzZ2VtXHUwMEU0XHUwMERGIGZvcm1hdGllcnRlbiBaZWljaGVuZGF0ZW4gb2RlciBNYXJrdXBzIGJlc3RlaGVuLgotICAgICAgICBEb2N0eXBlSWxsZWdhbEluQ29udGVudCA9IERPQ1RZUEUgaXN0IG5pY2h0IHp1bFx1MDBFNHNzaWcgaW4gQ29udGVudC4KLSMgNC4xIENoYXJhY3RlciBhbmQgRW50aXR5IFJlZmVyZW5jZXMKLSAgICAgICAgUmVmZXJlbmNlVW50ZXJtaW5hdGVkID0gUmVmZXJlbnogbXVzcyBtaXQgZWluZW0gIjsiLUJlZ3Jlbnp1bmdzemVpY2hlbiBiZWVuZGV0IHdlcmRlbi4KLSMgNC4zLjIgV2VsbC1Gb3JtZWQgUGFyc2VkIEVudGl0aWVzCi0gICAgICAgIFJlZmVyZW5jZU5vdEluT25lRW50aXR5ID0gUmVmZXJlbnogbXVzcyB2b2xsc3RcdTAwRTRuZGlnIGluIGRlcnNlbGJlbiBnZXBhcnN0ZW4gRW50aXR5IGVudGhhbHRlbiBzZWluLgotICAgICAgICBFbGVtZW50RW50aXR5TWlzbWF0Y2ggPSBFbGVtZW50ICJ7MH0iIG11c3MgaW5uZXJoYWxiIGRlcnNlbGJlbiBFbnRpdHkgYmVnaW5uZW4gdW5kIGVuZGVuLgotICAgICAgICBNYXJrdXBFbnRpdHlNaXNtYXRjaD1YTUwtRG9rdW1lbnRzdHJ1a3R1cmVuIG1cdTAwRkNzc2VuIGlubmVyaGFsYiBkZXJzZWxiZW4gRW50aXR5IGJlZ2lubmVuIHVuZCBlbmRlbi4KLSAgICAgICAgCi0jIE1lc3NhZ2VzIGNvbW1vbiB0byBEb2N1bWVudCBhbmQgRFRECi0jIDIuMiBDaGFyYWN0ZXJzCi0gICAgICAgIEludmFsaWRDaGFySW5BdHRWYWx1ZSA9IFVuZ1x1MDBGQ2x0aWdlcyBYTUwtWmVpY2hlbiAoVW5pY29kZTogMHh7Mn0pIHd1cmRlIGltIFdlcnQgZGVzIEF0dHJpYnV0cyAiezF9IiBnZWZ1bmRlbi4gRWxlbWVudCBpc3QgInswfSIuCi0gICAgICAgIEludmFsaWRDaGFySW5Db21tZW50ID0gVW5nXHUwMEZDbHRpZ2VzIFhNTC1aZWljaGVuIChVbmljb2RlOiAweHswfSkgd3VyZGUgaW0gS29tbWVudGFyIGdlZnVuZGVuLgotICAgICAgICBJbnZhbGlkQ2hhckluUEkgPSBVbmdcdTAwRkNsdGlnZXMgWE1MLVplaWNoZW4gKFVuaWNvZGU6IDB4ezB9KSB3dXJkZSBpbiBkZXIgVmVyYXJiZWl0dW5nc2Fud2Vpc3VuZyBnZWZ1bmRlbi4KLSAgICAgICAgSW52YWxpZENoYXJJbkludGVybmFsU3Vic2V0ID0gVW5nXHUwMEZDbHRpZ2VzIFhNTC1aZWljaGVuIChVbmljb2RlOiAweHswfSkgd3VyZGUgaW4gZGVyIGludGVybmVuIFRlaWxtZW5nZSBkZXIgRFREIGdlZnVuZGVuLgotICAgICAgICBJbnZhbGlkQ2hhckluVGV4dERlY2wgPSBVbmdcdTAwRkNsdGlnZXMgWE1MLVplaWNoZW4gKFVuaWNvZGU6IDB4ezB9KSB3dXJkZSBpbiBkZXIgVGV4dGRla2xhcmF0aW9uIGdlZnVuZGVuLgotIyAyLjMgQ29tbW9uIFN5bnRhY3RpYyBDb25zdHJ1Y3RzCi0gICAgICAgIFF1b3RlUmVxdWlyZWRJbkF0dFZhbHVlID0gV2VydCBkZXMgQXR0cmlidXRzICJ7MX0iIG11c3MgbWl0IGVpbmVtIGVpbnplbG5lbiBvZGVyIGRvcHBlbHRlbiBBbmZcdTAwRkNocnVuZ3N6ZWljaGVuIGJlZ2lubmVuLgotICAgICAgICBMZXNzdGhhbkluQXR0VmFsdWUgPSBXZXJ0IGRlcyBBdHRyaWJ1dHMgInsxfSIsIGRhcyBtaXQgRWxlbWVudHR5cCAiezB9IiB2ZXJrblx1MDBGQ3BmdCBpc3QsIGRhcmYgbmljaHQgZGFzIFplaWNoZW4gIjwiIGVudGhhbHRlbi4KLSAgICAgICAgQXR0cmlidXRlVmFsdWVVbnRlcm1pbmF0ZWQgPSBXZXJ0IGZcdTAwRkNyIEF0dHJpYnV0ICJ7MX0iIG11c3MgbWl0IGRlbSBlbnRzcHJlY2hlbmRlbiBBbmZcdTAwRkNocnVuZ3N6ZWljaGVuIGVuZGVuLgotIyAyLjUgQ29tbWVudHMKLSAgICAgICAgSW52YWxpZENvbW1lbnRTdGFydCA9IEtvbW1lbnRhciBtdXNzIG1pdCAiPCEtLSIgYmVnaW5uZW4uCi0gICAgICAgIERhc2hEYXNoSW5Db21tZW50ID0gWmVpY2hlbmZvbGdlICItLSIgaXN0IGluIEtvbW1lbnRhcmVuIG5pY2h0IHp1bFx1MDBFNHNzaWcuCi0gICAgICAgIENvbW1lbnRVbnRlcm1pbmF0ZWQgPSBLb21tZW50YXIgbXVzcyBtaXQgIi0tPiIgZW5kZW4uCi0gICAgICAgIENPTU1FTlRfTk9UX0lOX09ORV9FTlRJVFkgPSBLb21tZW50YXIgaXN0IG5pY2h0IGluIGRlcnNlbGJlbiBFbnRpdHkgZW50aGFsdGVuLgotIyAyLjYgUHJvY2Vzc2luZyBJbnN0cnVjdGlvbnMKLSAgICAgICAgUElUYXJnZXRSZXF1aXJlZCA9IFZlcmFyYmVpdHVuZ3NhbndlaXN1bmcgbXVzcyBtaXQgZGVtIE5hbWVuIGRlcyBaaWVscyBiZWdpbm5lbi4KLSAgICAgICAgU3BhY2VSZXF1aXJlZEluUEkgPSBMZWVyc3RlbGxlIGlzdCB6d2lzY2hlbiBkZW0gWmllbCBkZXIgVmVyYXJiZWl0dW5nc2Fud2Vpc3VuZyB1bmQgZGVuIERhdGVuIGVyZm9yZGVybGljaC4KLSAgICAgICAgUElVbnRlcm1pbmF0ZWQgPSBWZXJhcmJlaXR1bmdzYW53ZWlzdW5nIG11c3MgbWl0ICI/PiIgZW5kZW4uCi0gICAgICAgIFJlc2VydmVkUElUYXJnZXQgPSBWZXJhcmJlaXR1bmdzYW53ZWlzdW5nc3ppZWwsIGRhcyAiW3hYXVttTV1bbExdIiBlbnRzcHJpY2h0LCBpc3QgbmljaHQgenVsXHUwMEU0c3NpZy4KLSAgICAgICAgUElfTk9UX0lOX09ORV9FTlRJVFkgPSBWZXJhcmJlaXR1bmdzYW53ZWlzdW5nIGlzdCBuaWNodCBpbiBkZXJzZWxiZW4gRW50aXR5IGVudGhhbHRlbi4KLSMgMi44IFByb2xvZyBhbmQgRG9jdW1lbnQgVHlwZSBEZWNsYXJhdGlvbgotICAgICAgICBWZXJzaW9uSW5mb0ludmFsaWQgPSBVbmdcdTAwRkNsdGlnZSBWZXJzaW9uICJ7MH0iLgotICAgICAgICBWZXJzaW9uTm90U3VwcG9ydGVkID0gWE1MLVZlcnNpb24gInswfSIgd2lyZCBuaWNodCB1bnRlcnN0XHUwMEZDdHp0LiBOdXIgWE1MIDEuMCB3aXJkIHVudGVyc3RcdTAwRkN0enQuCi0gICAgICAgIFZlcnNpb25Ob3RTdXBwb3J0ZWQxMSA9IFhNTC1WZXJzaW9uICJ7MH0iIHdpcmQgbmljaHQgdW50ZXJzdFx1MDBGQ3R6dC4gTnVyIFhNTCAxLjAgdW5kIFhNTCAxLjEgd2VyZGVuIHVudGVyc3RcdTAwRkN0enQuCi0gICAgICAgIFZlcnNpb25NaXNtYXRjaD0gRWluZSBFbnRpdHkga2FubiBrZWluZSBhbmRlcmUgRW50aXR5IGVpbmVyIHNwXHUwMEU0dGVyZW4gVmVyc2lvbiBlbnRoYWx0ZW4uCi0jIDQuMSBDaGFyYWN0ZXIgYW5kIEVudGl0eSBSZWZlcmVuY2VzCi0gICAgICAgIERpZ2l0UmVxdWlyZWRJbkNoYXJSZWYgPSBBdWYgIiYjIiBpbiBlaW5lciBaZWljaGVucmVmZXJlbnogbXVzcyB1bWdlaGVuZCBlaW5lIERlemltYWxkYXJzdGVsbHVuZyBmb2xnZW4uCi0gICAgICAgIEhleGRpZ2l0UmVxdWlyZWRJbkNoYXJSZWYgPSBBdWYgIiYjeCIgaW4gZWluZXIgWmVpY2hlbnJlZmVyZW56IG11c3MgdW1nZWhlbmQgZWluZSBoZXhhZGV6aW1hbGUgRGFyc3RlbGx1bmcgZm9sZ2VuLgotICAgICAgICBTZW1pY29sb25SZXF1aXJlZEluQ2hhclJlZiA9IFplaWNoZW5yZWZlcmVueiBtdXNzIG1pdCBkZW0gQmVncmVuenVuZ3N6ZWljaGVuICI7IiBlbmRlbi4KLSAgICAgICAgSW52YWxpZENoYXJSZWYgPSBaZWljaGVucmVmZXJlbnogIiYjezB9IiBpc3QgZWluIHVuZ1x1MDBGQ2x0aWdlcyBYTUwtWmVpY2hlbi4KLSAgICAgICAgTmFtZVJlcXVpcmVkSW5SZWZlcmVuY2UgPSBBdWYgIiYiIGluIGRlciBFbnRpdHlyZWZlcmVueiBtdXNzIHVtZ2VoZW5kIGRlciBFbnRpdHluYW1lIGZvbGdlbi4KLSAgICAgICAgU2VtaWNvbG9uUmVxdWlyZWRJblJlZmVyZW5jZSA9IFJlZmVyZW56IHp1IEVudGl0eSAiezB9IiBtdXNzIG1pdCBkZW0gQmVncmVuenVuZ3N6ZWljaGVuICI7IiBlbmRlbi4KLSMgNC4zLjEgVGhlIFRleHQgRGVjbGFyYXRpb24KLSAgICAgICAgVGV4dERlY2xNdXN0QmVGaXJzdCA9IFRleHRkZWtsYXJhdGlvbiBkYXJmIG51ciBnYW56IGFtIEFuZmFuZyBkZXIgZXh0ZXJuZW4gZ2VwYXJzdGVuIEVudGl0eSBlbnRoYWx0ZW4gc2Vpbi4KLSAgICAgICAgRXFSZXF1aXJlZEluVGV4dERlY2wgPSBaZWljaGVuICIgPSAiIG11c3MgYXVmICJ7MH0iIGluIGRlciBUZXh0ZGVrbGFyYXRpb24gZm9sZ2VuLgotICAgICAgICBRdW90ZVJlcXVpcmVkSW5UZXh0RGVjbCA9IERlciBXZXJ0IG5hY2ggInswfSIgaW4gZGVyIFRleHRkZWtsYXJhdGlvbiBtdXNzIGVpbmUgWmVpY2hlbmZvbGdlIGluIEFuZlx1MDBGQ2hydW5nc3plaWNoZW4gc2Vpbi4KLSAgICAgICAgQ2xvc2VRdW90ZU1pc3NpbmdJblRleHREZWNsID0gU2NobGllXHUwMERGZW5kZXMgQW5mXHUwMEZDaHJ1bmdzemVpY2hlbiBpbSBXZXJ0IG5hY2ggInswfSIgaW4gZGVyIFRleHRkZWtsYXJhdGlvbiBmZWhsdC4KLSAgICAgICAgU3BhY2VSZXF1aXJlZEJlZm9yZVZlcnNpb25JblRleHREZWNsID0gTGVlcnN0ZWxsZSB2b3IgZGVtIFZlcnNpb25zcHNldWRvYXR0cmlidXQgaW4gZGVyIFRleHRkZWtsYXJhdGlvbiBlcmZvcmRlcmxpY2guCi0gICAgICAgIFNwYWNlUmVxdWlyZWRCZWZvcmVFbmNvZGluZ0luVGV4dERlY2wgPSBMZWVyc3RlbGxlIHZvciBkZW0gQ29kaWVydW5nc3BzZXVkb2F0dHJpYnV0IGluIGRlciBUZXh0ZGVrbGFyYXRpb24gZXJmb3JkZXJsaWNoLgotICAgICAgICBUZXh0RGVjbFVudGVybWluYXRlZCA9IFRleHRkZWtsYXJhdGlvbiBtdXNzIG1pdCAiPz4iIGVuZGVuLgotICAgICAgICBFbmNvZGluZ0RlY2xSZXF1aXJlZCA9IENvZGllcnVuZ3NkZWtsYXJhdGlvbiBpc3QgaW4gZGVyIFRleHRkZWtsYXJhdGlvbiBlcmZvcmRlcmxpY2guCi0gICAgICAgIE5vTW9yZVBzZXVkb0F0dHJpYnV0ZXMgPSBFcyBzaW5kIGtlaW5lIHdlaXRlcmVuIFBzZXVkb2F0dHJpYnV0ZSB6dWxcdTAwRTRzc2lnLgotICAgICAgICBNb3JlUHNldWRvQXR0cmlidXRlcyA9IEVzIHdlcmRlbiB3ZWl0ZXJlIFBzZXVkb2F0dHJpYnV0ZSBlcndhcnRldC4KLSAgICAgICAgUHNldWRvQXR0ck5hbWVFeHBlY3RlZCA9IFBzZXVkb2F0dHJpYnV0bmFtZSB3aXJkIGVyd2FydGV0LiAKLSMgNC4zLjIgV2VsbC1Gb3JtZWQgUGFyc2VkIEVudGl0aWVzCi0gICAgICAgIENvbW1lbnROb3RJbk9uZUVudGl0eSA9IEtvbW1lbnRhciBtdXNzIHZvbGxzdFx1MDBFNG5kaWcgaW4gZGVyc2VsYmVuIGdlcGFyc3RlbiBFbnRpdHkgZW50aGFsdGVuIHNlaW4uCi0gICAgICAgIFBJTm90SW5PbmVFbnRpdHkgPSBWZXJhcmJlaXR1bmdzYW53ZWlzdW5nIG11c3Mgdm9sbHN0XHUwMEU0bmRpZyBpbiBkZXJzZWxiZW4gZ2VwYXJzdGVuIEVudGl0eSBlbnRoYWx0ZW4gc2Vpbi4KLSMgNC4zLjMgQ2hhcmFjdGVyIEVuY29kaW5nIGluIEVudGl0aWVzCi0gICAgICAgIEVuY29kaW5nRGVjbEludmFsaWQgPSBVbmdcdTAwRkNsdGlnZXIgQ29kaWVydW5nc25hbWUgInswfSIuCi0gICAgICAgIEVuY29kaW5nQnl0ZU9yZGVyVW5zdXBwb3J0ZWQgPSBBbmdlZ2ViZW5lIEJ5dGVyZWloZW5mb2xnZSBmXHUwMEZDciBkaWUgQ29kaWVydW5nIHZvbiAiezB9IiB3aXJkIG5pY2h0IHVudGVyc3RcdTAwRkN0enQuCi0gICAgICAgIEludmFsaWRCeXRlID0gVW5nXHUwMEZDbHRpZ2VzIEJ5dGUgezB9IHZvbiB7MX0tQnl0ZS1VVEYtOC1TZXF1ZW56LgotICAgICAgICBFeHBlY3RlZEJ5dGUgPSBCeXRlIHswfSB2b24gezF9LUJ5dGUtVVRGLTgtU2VxdWVueiBlcndhcnRldC4gIAotICAgICAgICBJbnZhbGlkSGlnaFN1cnJvZ2F0ZSA9IEhpZ2gtU3Vycm9nYXRlLUJpdHMgaW4gVVRGLTgtU2VxdWVueiBkXHUwMEZDcmZlbiAweDEwIG5pY2h0IFx1MDBGQ2JlcnNjaHJlaXRlbiwgZ2VmdW5kZW4gd3VyZGUgYWJlciAweHswfS4KLSAgICAgICAgT3BlcmF0aW9uTm90U3VwcG9ydGVkID0gVm9yZ2FuZyAiezB9IiBuaWNodCB1bnRlcnN0XHUwMEZDdHp0IHZvbiB7MX0tUmVhZGVyLgotICAgICAgICBJbnZhbGlkQVNDSUkgPSBCeXRlICJ7MH0iIGdlaFx1MDBGNnJ0IG5pY2h0IHp1bSAoNy1CaXQpIEFTQ0lJLVplaWNoZW5zYXR6LgotICAgICAgICBDaGFyQ29udmVyc2lvbkZhaWx1cmUgPSBFaW5lIEVudGl0eSwgZlx1MDBGQ3IgZGllIGVpbmUgYmVzdGltbXRlIENvZGllcnVuZyBlcm1pdHRlbHQgd3VyZGUsIGRhcmYga2VpbmUgU2VxdWVuemVuIGVudGhhbHRlbiwgZGllIGluIGRpZXNlciBDb2RpZXJ1bmcgdW5nXHUwMEZDbHRpZyBzaW5kLgotICAgICAgICAKLSMgRFREIE1lc3NhZ2VzCi0jIDIuMiBDaGFyYWN0ZXJzCi0gICAgICAgIEludmFsaWRDaGFySW5FbnRpdHlWYWx1ZSA9IFVuZ1x1MDBGQ2x0aWdlcyBYTUwtWmVpY2hlbiAoVW5pY29kZTogMHh7MH0pIHd1cmRlIGltIGxpdGVyYWxlbiBFbnRpdHl3ZXJ0IGdlZnVuZGVuLgotICAgICAgICBJbnZhbGlkQ2hhckluRXh0ZXJuYWxTdWJzZXQgPSBVbmdcdTAwRkNsdGlnZXMgWE1MLVplaWNoZW4gKFVuaWNvZGU6IDB4ezB9KSB3dXJkZSBpbiBkZXIgZXh0ZXJuZW4gVGVpbG1lbmdlIGRlciBEVEQgZ2VmdW5kZW4uCi0gICAgICAgIEludmFsaWRDaGFySW5JZ25vcmVTZWN0ID0gVW5nXHUwMEZDbHRpZ2VzIFhNTC1aZWljaGVuIChVbmljb2RlOiAweHswfSkgd3VyZGUgaW0gYXVzZ2VzY2hsb3NzZW5lbiBCZWRpbmd1bmdzYWJzY2huaXR0IGdlZnVuZGVuLgotICAgICAgICBJbnZhbGlkQ2hhckluUHVibGljSUQgPSBVbmdcdTAwRkNsdGlnZXMgWE1MLVplaWNoZW4gKFVuaWNvZGU6IDB4ezB9KSB3dXJkZSBpbiBkZXIgXHUwMEY2ZmZlbnRsaWNoZW4gSUQgZ2VmdW5kZW4uCi0gICAgICAgIEludmFsaWRDaGFySW5TeXN0ZW1JRCA9IFVuZ1x1MDBGQ2x0aWdlcyBYTUwtWmVpY2hlbiAoVW5pY29kZTogMHh7MH0pIHd1cmRlIGluIGRlciBTeXN0ZW0tSUQgZ2VmdW5kZW4uCi0jIDIuMyBDb21tb24gU3ludGFjdGljIENvbnN0cnVjdHMKLSAgICAgICAgU3BhY2VSZXF1aXJlZEFmdGVyU1lTVEVNID0gTGVlcnN0ZWxsZSBuYWNoIFNjaGxcdTAwRkNzc2Vsd29ydCBTWVNURU0gaW4gRE9DVFlQRS1EZWtsYXJhdGlvbiBlcmZvcmRlcmxpY2guCi0gICAgICAgIFF1b3RlUmVxdWlyZWRJblN5c3RlbUlEID0gU3lzdGVtLUlEIG11c3MgbWl0IGVpbmVtIGVpbnplbG5lbiBvZGVyIGRvcHBlbHRlbiBBbmZcdTAwRkNocnVuZ3N6ZWljaGVuIGJlZ2lubmVuLgotICAgICAgICBTeXN0ZW1JRFVudGVybWluYXRlZCA9IFN5c3RlbS1JRCBtdXNzIG1pdCBkZW0gZW50c3ByZWNoZW5kZW4gQW5mXHUwMEZDaHJ1bmdzemVpY2hlbiBlbmRlbi4KLSAgICAgICAgU3BhY2VSZXF1aXJlZEFmdGVyUFVCTElDID0gTGVlcnN0ZWxsZW4gbmFjaCBTY2hsXHUwMEZDc3NlbHdvcnQgUFVCTElDIGluIERPQ1RZUEUtRGVrbGFyYXRpb24gZXJmb3JkZXJsaWNoLgotICAgICAgICBRdW90ZVJlcXVpcmVkSW5QdWJsaWNJRCA9IFx1MDBENmZmZW50bGljaGUgSUQgbXVzcyBtaXQgZWluZW0gZWluemVsbmVuIG9kZXIgZG9wcGVsdGVuIEFuZlx1MDBGQ2hydW5nc3plaWNoZW4gYmVnaW5uZW4uCi0gICAgICAgIFB1YmxpY0lEVW50ZXJtaW5hdGVkID0gXHUwMEQ2ZmZlbnRsaWNoZSBJRCBtdXNzIG1pdCBkZW0gZW50c3ByZWNoZW5kZW4gQW5mXHUwMEZDaHJ1bmdzemVpY2hlbiBlbmRlbi4KLSAgICAgICAgUHViaWRDaGFySWxsZWdhbCA9IFplaWNoZW4gKFVuaWNvZGU6IDB4ezB9KSBpc3QgbmljaHQgenVsXHUwMEU0c3NpZyBpbiBkZXIgXHUwMEY2ZmZlbnRsaWNoZW4gSUQuCi0gICAgICAgIFNwYWNlUmVxdWlyZWRCZXR3ZWVuUHVibGljQW5kU3lzdGVtID0gTGVlcnN0ZWxsZW4gZXJmb3JkZXJsaWNoIHp3aXNjaGVuIHB1YmxpY0lkIHVuZCBzeXN0ZW1JZC4KLSMgMi44IFByb2xvZyBhbmQgRG9jdW1lbnQgVHlwZSBEZWNsYXJhdGlvbgotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX1JPT1RfRUxFTUVOVF9UWVBFX0lOX0RPQ1RZUEVERUNMID0gTGVlcnN0ZWxsZSBuYWNoICI8IURPQ1RZUEUiIGluIGRlciBEb2t1bWVudHR5cGRla2xhcmF0aW9uIGVyZm9yZGVybGljaC4KLSAgICAgICAgTVNHX1JPT1RfRUxFTUVOVF9UWVBFX1JFUVVJUkVEID0gUm9vdC1FbGVtZW50dHlwIG11c3MgbmFjaCAiPCFET0NUWVBFIiBpbiBkZXIgRG9rdW1lbnR0eXBkZWtsYXJhdGlvbiBlbnRoYWx0ZW4gc2Vpbi4KLSAgICAgICAgRG9jdHlwZWRlY2xVbnRlcm1pbmF0ZWQgPSBEb2t1bWVudHR5cGRla2xhcmF0aW9uIGZcdTAwRkNyIFJvb3QtRWxlbWVudHR5cCAiezB9IiBtdXNzIG1pdCAiPiIgZW5kZW4uCi0gICAgICAgIERvY3R5cGVkZWNsTm90Q2xvc2VkID0gRG9rdW1lbnR0eXBkZWtsYXJhdGlvbiBmXHUwMEZDciBSb290LUVsZW1lbnR0eXAgInswfSIgbXVzcyBtaXQgJyddJycgZW5kZW4uCi0gICAgICAgIFBFUmVmZXJlbmNlV2l0aGluTWFya3VwID0gUGFyYW1ldGVyZW50aXR5cmVmZXJlbnogIiV7MH07IiBkYXJmIG5pY2h0IGluIE1hcmt1cCBpbiBkZXIgaW50ZXJuZW4gVGVpbG1lbmdlIGRlciBEVEQgdm9ya29tbWVuLgotICAgICAgICBNU0dfTUFSS1VQX05PVF9SRUNPR05JWkVEX0lOX0RURCA9IERpZSBNYXJrdXAtRGVrbGFyYXRpb25lbiwgZGllIGluIGRlciBEb2t1bWVudHR5cGRla2xhcmF0aW9uIGVudGhhbHRlbiBzaW5kIGJ6dy4gYXVmIGRpZSB2b24gZGVyIERva3VtZW50dHlwZGVrbGFyYXRpb24gdmVyd2llc2VuIHdpcmQsIG1cdTAwRkNzc2VuIG9yZG51bmdzZ2VtXHUwMEU0XHUwMERGIGZvcm1hdGllcnQgc2Vpbi4KLSMgMi4xMCBXaGl0ZSBTcGFjZSBIYW5kbGluZwotICAgICAgICBNU0dfWE1MX1NQQUNFX0RFQ0xBUkFUSU9OX0lMTEVHQUwgPSBBdHRyaWJ1dGRla2xhcmF0aW9uIGZcdTAwRkNyICJ4bWw6c3BhY2UiIG11c3MgYWxzIGF1Zmdlelx1MDBFNGhsdGVyIFR5cCBhbmdlZ2ViZW4gd2VyZGVuLCBkZXNzZW4gZWluemlnZW4gbVx1MDBGNmdsaWNoZW4gV2VydGUgImRlZmF1bHQiIHVuZCAicHJlc2VydmUiIHNpbmQuCi0jIDMuMiBFbGVtZW50IFR5cGUgRGVjbGFyYXRpb25zCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfRUxFTUVOVF9UWVBFX0lOX0VMRU1FTlRERUNMID0gTGVlcnN0ZWxsZSBuYWNoICI8IUVMRU1FTlQiIGluIGRlciBFbGVtZW50dHlwZGVrbGFyYXRpb24gZXJmb3JkZXJsaWNoLgotICAgICAgICBNU0dfRUxFTUVOVF9UWVBFX1JFUVVJUkVEX0lOX0VMRU1FTlRERUNMID0gRWxlbWVudHR5cCBpc3QgaW4gZGVyIEVsZW1lbnR0eXBkZWtsYXJhdGlvbiBlcmZvcmRlcmxpY2guCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfQ09OVEVOVFNQRUNfSU5fRUxFTUVOVERFQ0wgPSBMZWVyc3RlbGxlIG5hY2ggRWxlbWVudHR5cCAiezB9IiBpbiBkZXIgRWxlbWVudHR5cGRla2xhcmF0aW9uIGVyZm9yZGVybGljaC4KLSAgICAgICAgTVNHX0NPTlRFTlRTUEVDX1JFUVVJUkVEX0lOX0VMRU1FTlRERUNMID0gQ29uc3RyYWludCBpc3QgbmFjaCBkZW0gRWxlbWVudHR5cCAiezB9IiBpbiBkZXIgRWxlbWVudHR5cGRla2xhcmF0aW9uIGVyZm9yZGVybGljaC4KLSAgICAgICAgRWxlbWVudERlY2xVbnRlcm1pbmF0ZWQgPSBEZWtsYXJhdGlvbiBmXHUwMEZDciBFbGVtZW50dHlwICJ7MH0iIG11c3MgbWl0ICI+IiBlbmRlbi4KLSMgMy4yLjEgRWxlbWVudCBDb250ZW50Ci0gICAgICAgIE1TR19PUEVOX1BBUkVOX09SX0VMRU1FTlRfVFlQRV9SRVFVSVJFRF9JTl9DSElMRFJFTiA9IERhcyBaZWljaGVuICIoIiBvZGVyIGVpbiBFbGVtZW50dHlwIGlzdCBpbiBkZXIgRGVrbGFyYXRpb24gZGVzIEVsZW1lbnR0eXBzICJ7MH0iIGVyZm9yZGVybGljaC4KLSAgICAgICAgTVNHX0NMT1NFX1BBUkVOX1JFUVVJUkVEX0lOX0NISUxEUkVOID0gRGFzIFplaWNoZW4gIikiIGlzdCBpbiBkZXIgRGVrbGFyYXRpb24gZGVzIEVsZW1lbnR0eXBzICJ7MH0iIGVyZm9yZGVybGljaC4KLSMgMy4yLjIgTWl4ZWQgQ29udGVudAotICAgICAgICBNU0dfRUxFTUVOVF9UWVBFX1JFUVVJUkVEX0lOX01JWEVEX0NPTlRFTlQgPSBFaW4gRWxlbWVudHR5cCBpc3QgaW4gZGVyIERla2xhcmF0aW9uIGRlcyBFbGVtZW50dHlwcyAiezB9IiBlcmZvcmRlcmxpY2guCi0gICAgICAgIE1TR19DTE9TRV9QQVJFTl9SRVFVSVJFRF9JTl9NSVhFRCA9IERhcyBaZWljaGVuICIpIiBpc3QgaW4gZGVyIERla2xhcmF0aW9uIGRlcyBFbGVtZW50dHlwcyAiezB9IiBlcmZvcmRlcmxpY2guCi0gICAgICAgIE1peGVkQ29udGVudFVudGVybWluYXRlZCA9IERhcyBNaXNjaGNvbnRlbnRtb2RlbGwgInswfSIgbXVzcyBtaXQgIikqIiBlbmRlbiwgd2VubiBkaWUgVHlwZW4gZGVyIHVudGVyZ2VvcmRuZXRlbiBFbGVtZW50ZSBlaW5nZXNjaHJcdTAwRTRua3Qgc2luZC4KLSMgMy4zIEF0dHJpYnV0ZS1MaXN0IERlY2xhcmF0aW9ucwotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX0VMRU1FTlRfVFlQRV9JTl9BVFRMSVNUREVDTCA9IExlZXJzdGVsbGUgbmFjaCAiPCFBVFRMSVNUIiBpbiBkZXIgQXR0cmlidXRsaXN0ZW5kZWtsYXJhdGlvbiBlcmZvcmRlcmxpY2guCi0gICAgICAgIE1TR19FTEVNRU5UX1RZUEVfUkVRVUlSRURfSU5fQVRUTElTVERFQ0wgPSBFbGVtZW50dHlwIGlzdCBpbiBkZXIgQXR0cmlidXRsaXN0ZW5kZWtsYXJhdGlvbiBlcmZvcmRlcmxpY2guCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfQVRUUklCVVRFX05BTUVfSU5fQVRUREVGID0gTGVlcnN0ZWxsZSB2b3IgZGVtIEF0dHJpYnV0bmFtZW4gaW4gZGVyIEF0dHJpYnV0bGlzdGVuZGVrbGFyYXRpb24gZlx1MDBGQ3IgRWxlbWVudCAiezB9IiBlcmZvcmRlcmxpY2guCi0gICAgICAgIEF0dE5hbWVSZXF1aXJlZEluQXR0RGVmID0gQXR0cmlidXRuYW1lIG11c3MgaW4gZGVyIEF0dHJpYnV0bGlzdGVuZGVrbGFyYXRpb24gZlx1MDBGQ3IgRWxlbWVudCAiezB9IiBhbmdlZ2ViZW4gd2VyZGVuLgotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX0FUVFRZUEVfSU5fQVRUREVGID0gTGVlcnN0ZWxsZSB2b3IgZGVtIEF0dHJpYnV0dHlwIGluIGRlciBEZWtsYXJhdGlvbiBkZXMgQXR0cmlidXRzICJ7MX0iIGZcdTAwRkNyIEVsZW1lbnQgInswfSIgZXJmb3JkZXJsaWNoLgotICAgICAgICBBdHRUeXBlUmVxdWlyZWRJbkF0dERlZiA9IEF0dHJpYnV0dHlwIGlzdCBpbiBkZXIgRGVrbGFyYXRpb24gZGVzIEF0dHJpYnV0cyAiezF9IiBmXHUwMEZDciBFbGVtZW50ICJ7MH0iIGVyZm9yZGVybGljaC4KLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9ERUZBVUxUREVDTF9JTl9BVFRERUYgPSBMZWVyc3RlbGxlIHZvciBkZW0gQXR0cmlidXRzdGFuZGFyZCBpbiBkZXIgRGVrbGFyYXRpb24gZGVzIEF0dHJpYnV0cyAiezF9IiBmXHUwMEZDciBFbGVtZW50ICJ7MH0iIGVyZm9yZGVybGljaC4KLSAgICAgICAgTVNHX0RVUExJQ0FURV9BVFRSSUJVVEVfREVGSU5JVElPTiA9IE1laHJlcmUgQXR0cmlidXRkZWZpbml0aW9uZW4gZlx1MDBGQ3IgZGFzc2VsYmUgQXR0cmlidXQgInsxfSIgZWluZXMgRWxlbWVudHMgInswfSIgYW5nZWdlYmVuLgotIyAzLjMuMSBBdHRyaWJ1dGUgVHlwZXMKLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0FGVEVSX05PVEFUSU9OX0lOX05PVEFUSU9OVFlQRSA9IExlZXJzdGVsbGUgbmFjaCAiTk9UQVRJT04iIGluIGRlciAiezF9Ii1BdHRyaWJ1dGRla2xhcmF0aW9uIGVyZm9yZGVybGljaC4KLSAgICAgICAgTVNHX09QRU5fUEFSRU5fUkVRVUlSRURfSU5fTk9UQVRJT05UWVBFID0gRGFzIFplaWNoZW4gIigiIG11c3MgYXVmICJOT1RBVElPTiIgaW4gZGVyICJ7MX0iLUF0dHJpYnV0ZGVrbGFyYXRpb24gZm9sZ2VuLgotICAgICAgICBNU0dfTkFNRV9SRVFVSVJFRF9JTl9OT1RBVElPTlRZUEUgPSBOb3RhdGlvbnNuYW1lIGlzdCBpbiBkZXIgTm90YXRpb25zdHlwbGlzdGUgZlx1MDBGQ3IgZGllICJ7MX0iLUF0dHJpYnV0ZGVrbGFyYXRpb24gZXJmb3JkZXJsaWNoLgotICAgICAgICBOb3RhdGlvblR5cGVVbnRlcm1pbmF0ZWQgPSBOb3RhdGlvbnN0eXBsaXN0ZSBtdXNzIG1pdCAiKSIgaW4gZGVyInsxfSItQXR0cmlidXRkZWtsYXJhdGlvbiBlbmRlbi4KLSAgICAgICAgTVNHX05NVE9LRU5fUkVRVUlSRURfSU5fRU5VTUVSQVRJT04gPSBOYW1lbnN0b2tlbiBpc3QgaW4gZGVyIGF1Zmdlelx1MDBFNGhsdGVuIFR5cGxpc3RlIGZcdTAwRkNyIGRpZSAiezF9Ii1BdHRyaWJ1dGRla2xhcmF0aW9uIGVyZm9yZGVybGljaC4KLSAgICAgICAgRW51bWVyYXRpb25VbnRlcm1pbmF0ZWQgPSBBdWZnZXpcdTAwRTRobHRlIFR5cGxpc3RlIG11c3MgbWl0ICIpIiBpbiBkZXIiezF9Ii1BdHRyaWJ1dGRla2xhcmF0aW9uIGVuZGVuLgotICAgICAgICBNU0dfRElTVElOQ1RfVE9LRU5TX0lOX0VOVU1FUkFUSU9OID0gRW51bWVyYXRpb25zd2VydCAiezF9IiB3dXJkZSBtZWhybWFscyBpbiBkZXIgRGVrbGFyYXRpb24gZGVzIEF0dHJpYnV0cyAiezJ9IiBmXHUwMEZDciBFbGVtZW50ICJ7MH0iIGFuZ2VnZWJlbi4gRGllIE5NVE9LRU5TIGluIGVpbmVyIGVpbnplbG5lbiAiRW51bWVyYXRpb24iLUF0dHJpYnV0ZGVrbGFyYXRpb24gbVx1MDBGQ3NzZW4gYWxsZSBlaW5kZXV0aWcgc2Vpbi4KLSAgICAgICAgTVNHX0RJU1RJTkNUX05PVEFUSU9OX0lOX0VOVU1FUkFUSU9OID0gRW51bWVyYXRpb25zd2VydCAiezF9IiB3dXJkZSBtZWhybWFscyBpbiBkZXIgRGVrbGFyYXRpb24gZGVzIEF0dHJpYnV0cyAiezJ9IiBmXHUwMEZDciBFbGVtZW50ICJ7MH0iIGFuZ2VnZWJlbi4gRGllIE5PVEFUSU9OLU5hbWVuIGluIGVpbmVyIGVpbnplbG5lbiBOb3RhdGlvblR5cGUtQXR0cmlidXRkZWtsYXJhdGlvbiBtXHUwMEZDc3NlbiBhbGxlIGVpbmRldXRpZyBzZWluLgotIyAzLjMuMiBBdHRyaWJ1dGUgRGVmYXVsdHMKLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0FGVEVSX0ZJWEVEX0lOX0RFRkFVTFRERUNMID0gTGVlcnN0ZWxsZSBuYWNoICJGSVhFRCIgaW4gZGVyICJ7MX0iLUF0dHJpYnV0ZGVrbGFyYXRpb24gZXJmb3JkZXJsaWNoLgotIyAzLjQgQ29uZGl0aW9uYWwgU2VjdGlvbnMKLSAgICAgICAgSW5jbHVkZVNlY3RVbnRlcm1pbmF0ZWQgPSBEZXIgZWluZ2VzY2hsb3NzZW5lIEJlZGluZ3VuZ3NhYnNjaG5pdHQgbXVzcyBtaXQgIl1dPiIgZW5kZW4uCi0gICAgICAgIElnbm9yZVNlY3RVbnRlcm1pbmF0ZWQgPSBEZXIgYXVzZ2VzY2hsb3NzZW5lIEJlZGluZ3VuZ3NhYnNjaG5pdHQgbXVzcyBtaXQgIl1dPiIgZW5kZW4uCi0jIDQuMSBDaGFyYWN0ZXIgYW5kIEVudGl0eSBSZWZlcmVuY2VzCi0gICAgICAgIE5hbWVSZXF1aXJlZEluUEVSZWZlcmVuY2UgPSBBdWYgIiUiIGluIGRlciBQYXJhbWV0ZXJlbnRpdHlyZWZlcmVueiBtdXNzIHVtZ2VoZW5kIGRlciBFbnRpdHluYW1lIGZvbGdlbi4KLSAgICAgICAgU2VtaWNvbG9uUmVxdWlyZWRJblBFUmVmZXJlbmNlID0gUGFyYW1ldGVyZW50aXR5cmVmZXJlbnogIiV7MH07IiBtdXNzIG1pdCBkZW0gQmVncmVuenVuZ3N6ZWljaGVuICI7IiBlbmRlbi4KLSMgNC4yIEVudGl0eSBEZWNsYXJhdGlvbnMKLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9FTlRJVFlfTkFNRV9JTl9FTlRJVFlERUNMID0gTGVlcnN0ZWxsZSBuYWNoICI8IUVOVElUWSIgaW4gZGVyIEVudGl0eWRla2xhcmF0aW9uIGVyZm9yZGVybGljaC4KLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9QRVJDRU5UX0lOX1BFREVDTCA9IExlZXJzdGVsbGUgendpc2NoZW4gIjwhRU5USVRZIiB1bmQgZGVtIFplaWNoZW4gIiUiIGluIGRlciBQYXJhbWV0ZXJlbnRpdHlkZWtsYXJhdGlvbiBlcmZvcmRlcmxpY2guCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfRU5USVRZX05BTUVfSU5fUEVERUNMID0gTGVlcnN0ZWxsZSB6d2lzY2hlbiAiJSIgdW5kIGRlbSBFbnRpdHluYW1lbiBpbiBkZXIgUGFyYW1ldGVyZW50aXR5ZGVrbGFyYXRpb24gZXJmb3JkZXJsaWNoLgotICAgICAgICBNU0dfRU5USVRZX05BTUVfUkVRVUlSRURfSU5fRU5USVRZREVDTCA9IE5hbWUgZGVyIEVudGl0eSBpc3QgaW4gZGVyIEVudGl0eWRla2xhcmF0aW9uIGVyZm9yZGVybGljaC4KLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0FGVEVSX0VOVElUWV9OQU1FX0lOX0VOVElUWURFQ0wgPSBMZWVyc3RlbGxlIHp3aXNjaGVuIGRlbSBFbnRpdHluYW1lbiAiezB9IiB1bmQgZGVyIERlZmluaXRpb24gaW4gZGVyIEVudGl0eWRla2xhcmF0aW9uIGVyZm9yZGVybGljaC4KLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9OT1RBVElPTl9OQU1FX0lOX1VOUEFSU0VEX0VOVElUWURFQ0wgPSBMZWVyc3RlbGxlIHp3aXNjaGVuICJOREFUQSIgdW5kIGRlbSBOb3RhdGlvbnNuYW1lbiBpbiBkZXIgRGVrbGFyYXRpb24gZlx1MDBGQ3IgZGllIEVudGl0eSAiezB9IGVyZm9yZGVybGljaC4KLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9OREFUQV9JTl9VTlBBUlNFRF9FTlRJVFlERUNMID0gTGVlcnN0ZWxsZSB2b3IgIk5EQVRBIiBpbiBkZXIgRGVrbGFyYXRpb24gZlx1MDBGQ3IgZGllIEVudGl0eSAiezB9IGVyZm9yZGVybGljaC4KLSAgICAgICAgTVNHX05PVEFUSU9OX05BTUVfUkVRVUlSRURfRk9SX1VOUEFSU0VEX0VOVElUWURFQ0wgPSBOb3RhdGlvbnNuYW1lIGlzdCBuYWNoICJOREFUQSIgaW4gZGVyIERla2xhcmF0aW9uIGZcdTAwRkNyIGRpZSBFbnRpdHkgInswfSBlcmZvcmRlcmxpY2guCi0gICAgICAgIEVudGl0eURlY2xVbnRlcm1pbmF0ZWQgPSBEZWtsYXJhdGlvbiBmXHUwMEZDciBFbnRpdHkgInswfSIgbXVzcyBtaXQgIj4iIGVuZGVuLgotCU1TR19EVVBMSUNBVEVfRU5USVRZX0RFRklOSVRJT04gPSBFbnRpdHkgInswfSIgd3VyZGUgbWVocm1hbHMgZGVrbGFyaWVydC4gICAgICAgIAotIyA0LjIuMiBFeHRlcm5hbCBFbnRpdGllcwotICAgICAgICBFeHRlcm5hbElEUmVxdWlyZWQgPSBFeHRlcm5lIEVudGl0eWRla2xhcmF0aW9uIG11c3MgbWl0ICJTWVNURU0iIG9kZXIgIlBVQkxJQyIgYmVnaW5uZW4uCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfUFVCSURMSVRFUkFMX0lOX0VYVEVSTkFMSUQgPSBMZWVyc3RlbGxlIHp3aXNjaGVuICJQVUJMSUMiIHVuZCBkZXIgXHUwMEY2ZmZlbnRsaWNoZW4gSUQgZXJmb3JkZXJsaWNoLgotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQUZURVJfUFVCSURMSVRFUkFMX0lOX0VYVEVSTkFMSUQgPSBMZWVyc3RlbGxlIHp3aXNjaGVuIGRlciBcdTAwRjZmZmVudGxpY2hlbiBJRCB1bmQgZGVyIFN5c3RlbS1JRCBlcmZvcmRlcmxpY2guCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfU1lTVEVNTElURVJBTF9JTl9FWFRFUk5BTElEID0gTGVlcnN0ZWxsZSB6d2lzY2hlbiAiU1lTVEVNIiB1bmQgZGVyIFN5c3RlbS1JRCBlcmZvcmRlcmxpY2guCi0gICAgICAgIE1TR19VUklfRlJBR01FTlRfSU5fU1lTVEVNSUQgPSBGcmFnbWVudC1JRCBkYXJmIG5pY2h0IGFscyBUZWlsIGRlciBTeXN0ZW0tSUQgInswfSIgYW5nZWdlYmVuIHdlcmRlbi4KLSMgNC43IE5vdGF0aW9uIERlY2xhcmF0aW9ucwotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX05PVEFUSU9OX05BTUVfSU5fTk9UQVRJT05ERUNMID0gTGVlcnN0ZWxsZSBuYWNoICI8IU5PVEFUSU9OIiBpbiBkZXIgTm90YXRpb25zZGVrbGFyYXRpb24gZXJmb3JkZXJsaWNoLgotICAgICAgICBNU0dfTk9UQVRJT05fTkFNRV9SRVFVSVJFRF9JTl9OT1RBVElPTkRFQ0wgPSBOYW1lIGRlciBOb3RhdGlvbiBpc3QgaW4gZGVyIE5vdGF0aW9uc2Rla2xhcmF0aW9uIGVyZm9yZGVybGljaC4KLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0FGVEVSX05PVEFUSU9OX05BTUVfSU5fTk9UQVRJT05ERUNMID0gTGVlcnN0ZWxsZSBuYWNoIGRlbSBOb3RhdGlvbnNuYW1lbiAiezB9IiBpbiBkZXIgTm90YXRpb25zZGVrbGFyYXRpb24gZXJmb3JkZXJsaWNoLgotICAgICAgICBFeHRlcm5hbElEb3JQdWJsaWNJRFJlcXVpcmVkID0gRGVrbGFyYXRpb24gZlx1MDBGQ3IgZGllIE5vdGF0aW9uICJ7MH0iIG11c3MgZWluZSBTeXN0ZW0tIG9kZXIgZWluZSBcdTAwRjZmZmVudGxpY2hlIElEIGVudGhhbHRlbi4KLSAgICAgICAgTm90YXRpb25EZWNsVW50ZXJtaW5hdGVkID0gRGVrbGFyYXRpb24gZlx1MDBGQ3IgZGllIE5vdGF0aW9uICJ7MH0iIG11c3MgbWl0ICI+IiBlbmRlbi4KLSAgICAgICAgCi0jIFZhbGlkYXRpb24gbWVzc2FnZXMKLSAgICAgICAgRHVwbGljYXRlVHlwZUluTWl4ZWRDb250ZW50ID0gRWxlbWVudHR5cCAiezF9IiB3dXJkZSBiZXJlaXRzIGltIENvbnRlbnRtb2RlbGwgZGVyIEVsZW1lbnRkZWtsYXJhdGlvbiJ7MH0iIGFuZ2VnZWJlbi4KLSAgICAgICAgRU5USVRJRVNJbnZhbGlkID0gQXR0cmlidXR3ZXJ0ICJ7MX0iIG1pdCBkZW0gVHlwIEVOVElUSUVTIG11c3MgYXVzIGRlbiBOYW1lbiB2b24gbWluZGVzdGVucyBlaW5lciBnZXBhcnN0ZW4gRW50aXR5IGJlc3RlaGVuLgotICAgICAgICBFTlRJVFlJbnZhbGlkID0gQXR0cmlidXR3ZXJ0ICJ7MX0iIG1pdCBkZW0gVHlwIEVOVElUWSBtdXNzIGF1cyBkZW0gTmFtZW4gZWluZXIgZ2VwYXJzdGVuIEVudGl0eSBiZXN0ZWhlbi4KLSAgICAgICAgSUREZWZhdWx0VHlwZUludmFsaWQgPSBJRC1BdHRyaWJ1dCAiezB9IiBtdXNzIGRlbiBkZWtsYXJpZXJ0ZW4gU3RhbmRhcmR3ZXJ0ICIjSU1QTElFRCIgb2RlciAiI1JFUVVJUkVEIiBoYWJlbi4KLSAgICAgICAgSURJbnZhbGlkID0gQXR0cmlidXR3ZXJ0ICJ7MH0iIG1pdCBkZW0gVHlwIElEIG11c3MgZWluIE5hbWUgc2Vpbi4KLSAgICAgICAgSURJbnZhbGlkV2l0aE5hbWVzcGFjZXMgPSBBdHRyaWJ1dHdlcnQgInswfSIgbWl0IGRlbSBUeXAgSUQgbXVzcyBlaW4gTkNOYW1lIHNlaW4sIHdlbm4gTmFtZXNwYWNlcyBha3RpdmllcnQgc2luZC4KLSAgICAgICAgSUROb3RVbmlxdWUgPSBBdHRyaWJ1dHdlcnQgInswfSIgbWl0IGRlbSBUeXAgSUQgbXVzcyBlaW5kZXV0aWcgaW0gRG9rdW1lbnQgc2Vpbi4KLSAgICAgICAgSURSRUZJbnZhbGlkID0gQXR0cmlidXR3ZXJ0ICJ7MH0iIG1pdCBkZW0gVHlwIElEUkVGIG11c3MgZWluIE5hbWUgc2Vpbi4KLSAgICAgICAgSURSRUZJbnZhbGlkV2l0aE5hbWVzcGFjZXMgPSBBdHRyaWJ1dHdlcnQgInswfSIgbWl0IGRlbSBUeXAgSURSRUYgbXVzcyBlaW4gTkNOYW1lIHNlaW4sIHdlbm4gTmFtZXNwYWNlcyBha3RpdmllcnQgc2luZC4KLSAgICAgICAgSURSRUZTSW52YWxpZCA9IEF0dHJpYnV0d2VydCAiezB9IiBtaXQgZGVtIFR5cCBJRFJFRlMgbXVzcyBtaW5kZXN0ZW5zIGVpbiBOYW1lIHNlaW4uCi0gICAgICAgIElMTF9GT1JNRURfUEFSQU1FVEVSX0VOVElUWV9XSEVOX1VTRURfSU5fREVDTCA9IEVyc2F0enRleHQgZGVyIFBhcmFtZXRlcmVudGl0eSAiezB9IiBtdXNzIG9yZG51bmdzZ2VtXHUwMEU0XHUwMERGIHZlcnNjaGFjaHRlbHRlIERla2xhcmF0aW9uZW4gZW50aGFsdGVuLCB3ZW5uIGRpZSBFbnRpdHlyZWZlcmVueiBhbHMgdm9sbHN0XHUwMEU0bmRpZ2UgRGVrbGFyYXRpb24gdmVyd2VuZGV0IHdpcmQuCi0gICAgICAgIEltcHJvcGVyRGVjbGFyYXRpb25OZXN0aW5nID0gRXJzYXR6dGV4dCBkZXIgUGFyYW1ldGVyZW50aXR5ICJ7MH0iIG11c3Mgb3JkbnVuZ3NnZW1cdTAwRTRcdTAwREYgdmVyc2NoYWNodGVsdGUgRGVrbGFyYXRpb25lbiBlbnRoYWx0ZW4uCi0gICAgICAgIEltcHJvcGVyR3JvdXBOZXN0aW5nID0gRXJzYXR6dGV4dCBkZXIgUGFyYW1ldGVyZW50aXR5ICJ7MH0iIG11c3Mgb3JkbnVuZ3NnZW1cdTAwRTRcdTAwREYgdmVyc2NoYWNodGVsdGUgS2xhbW1lcm5wYWFyZSBlbnRoYWx0ZW4uCi0gICAgICAgIElOVkFMSURfUEVfSU5fQ09ORElUSU9OQUwgPSBFcnNhdHp0ZXh0IGRlciBQYXJhbWV0ZXJlbnRpdHkgInswfSIgbXVzcyBkZW4gZ2VzYW10ZW4gQmVkaW5ndW5nc2Fic2Nobml0dCBvZGVyIG51ciBJTkNMVURFIG9kZXIgSUdOT1JFIGVudGhhbHRlbi4KLSAgICAgICAgTVNHX0FUVFJJQlVURV9OT1RfREVDTEFSRUQgPSBBdHRyaWJ1dCAiezF9IiBtdXNzIGZcdTAwRkNyIEVsZW1lbnR0eXAgInswfSIgZGVrbGFyaWVydCB3ZXJkZW4uCi0gICAgICAgIE1TR19BVFRSSUJVVEVfVkFMVUVfTk9UX0lOX0xJU1QgPSBBdHRyaWJ1dCAiezB9IiBtaXQgV2VydCAiezF9IiBtdXNzIGVpbmVuIFdlcnQgYXVzIGRlciBMaXN0ZSAiezJ9IiBoYWJlbi4KLSAgICAgICAgTVNHX0FUVFZBTFVFX0NIQU5HRURfRFVSSU5HX05PUk1BTElaQVRJT05fV0hFTl9TVEFOREFMT05FID0gRGVyIFdlcnQgInsxfSIgZGVzIEF0dHJpYnV0cyAiezB9IiBkYXJmIG5pY2h0IHZvbiBkZXIgTm9ybWFsaXNpZXJ1bmcgKHp1ICJ7Mn0iKSBpbiBlaW5lbSBTdGFuZGFsb25lLURva3VtZW50IGdlXHUwMEU0bmRlcnQgd2VyZGVuLgotICAgICAgICBNU0dfQ09OVEVOVF9JTkNPTVBMRVRFID0gQ29udGVudCBkZXMgRWxlbWVudHR5cHMgInswfSIgaXN0IHVudm9sbHN0XHUwMEU0bmRpZy4gTXVzcyAiezF9IiBlbnRzcHJlY2hlbi4KLSAgICAgICAgTVNHX0NPTlRFTlRfSU5WQUxJRCA9IENvbnRlbnQgZGVzIEVsZW1lbnR0eXBzICJ7MH0iIG11c3MgInsxfSIgZW50c3ByZWNoZW4uCi0gICAgICAgIE1TR19DT05URU5UX0lOVkFMSURfU1BFQ0lGSUVEID0gQ29udGVudCBkZXMgRWxlbWVudHR5cHMgInswfSIgbXVzcyAiezF9IiBlbnRzcHJlY2hlbi4gVW50ZXJnZW9yZG5ldGUgRWxlbWVudGUgbWl0IGRlbSBUeXAgInsyfSIgc2luZCBuaWNodCB6dWxcdTAwRTRzc2lnLgotICAgICAgICBNU0dfREVGQVVMVEVEX0FUVFJJQlVURV9OT1RfU1BFQ0lGSUVEID0gQXR0cmlidXQgInsxfSIgZlx1MDBGQ3IgRWxlbWVudHR5cCAiezB9IiBoYXQgZWluZW4gU3RhbmRhcmR3ZXJ0IHVuZCBtdXNzIGluIGVpbmVtIFN0YW5kYWxvbmUtRG9rdW1lbnQgYW5nZWdlYmVuIHdlcmRlbi4KLSAgICAgICAgTVNHX0RVUExJQ0FURV9BVFRERUYgPSBBdHRyaWJ1dCAiezF9IiBpc3QgYmVyZWl0cyBkZWtsYXJpZXJ0IGZcdTAwRkNyIEVsZW1lbnR0eXAgInswfSIuCi0gICAgICAgIE1TR19FTEVNRU5UX0FMUkVBRFlfREVDTEFSRUQgPSBFbGVtZW50dHlwICJ7MH0iIGRhcmYgbmljaHQgbWVocm1hbHMgZGVrbGFyaWVydCB3ZXJkZW4uCi0gICAgICAgIE1TR19FTEVNRU5UX05PVF9ERUNMQVJFRCA9IEVsZW1lbnR0eXAgInswfSIgbXVzcyBkZWtsYXJpZXJ0IHdlcmRlbi4KLSAgICAgICAgTVNHX0dSQU1NQVJfTk9UX0ZPVU5EID0gRG9rdW1lbnQgaXN0IHVuZ1x1MDBGQ2x0aWcuIEtlaW5lIEdyYW1tYXRpayBnZWZ1bmRlbi4KLSAgICAgICAgTVNHX0VMRU1FTlRfV0lUSF9JRF9SRVFVSVJFRCA9IEVsZW1lbnQgbWl0ICJ7MH0iIGlzdCBpbSBEb2t1bWVudCBlcmZvcmRlcmxpY2guCi0gICAgICAgIE1TR19FWFRFUk5BTF9FTlRJVFlfTk9UX1BFUk1JVFRFRCA9IFJlZmVyZW56IHp1ciBleHRlcm5lbiBFbnRpdHkgInswfSIgaXN0IGluIGVpbmVtIFN0YW5kYWxvbmUtRG9rdW1lbnQgbmljaHQgenVsXHUwMEU0c3NpZy4KLSAgICAgICAgTVNHX0ZJWEVEX0FUVFZBTFVFX0lOVkFMSUQgPSBBdHRyaWJ1dCAiezF9IiBtaXQgV2VydCAiezJ9IiBtdXNzIGRlbiBXZXJ0InszfSIgaGFiZW4uCi0gICAgICAgIE1TR19NT1JFX1RIQU5fT05FX0lEX0FUVFJJQlVURSA9IEVsZW1lbnR0eXAgInswfSIgaGF0IGJlcmVpdHMgZWluIEF0dHJpYnV0ICJ7MX0iIG1pdCBkZW0gVHlwIElELiBFaW4gendlaXRlcyBBdHRyaWJ1dCAiezJ9IiBtaXQgZGVtIFR5cCBJRCBpc3QgbmljaHQgenVsXHUwMEU0c3NpZy4KLSAgICAgICAgTVNHX01PUkVfVEhBTl9PTkVfTk9UQVRJT05fQVRUUklCVVRFID0gRWxlbWVudHR5cCAiezB9IiBoYXQgYmVyZWl0cyBlaW4gQXR0cmlidXQgInsxfSIgbWl0IGRlbSBUeXAgTk9UQVRJT04uIEVpbiB6d2VpdGVzIEF0dHJpYnV0ICJ7Mn0iIG1pdCBkZW0gVHlwIE5PVEFUSU9OIGlzdCBuaWNodCB6dWxcdTAwRTRzc2lnLgotICAgICAgICBNU0dfTk9UQVRJT05fTk9UX0RFQ0xBUkVEX0ZPUl9OT1RBVElPTlRZUEVfQVRUUklCVVRFID0gTm90YXRpb24gInsxfSIgbXVzcyBkZWtsYXJpZXJ0IHdlcmRlbiwgd2VubiBzaWUgaW4gZGVyIE5vdGF0aW9uc3R5cGxpc3RlIGZcdTAwRkNyIEF0dHJpYnV0ICJ7MH0iIHJlZmVyZW56aWVydCB3aXJkLgotICAgICAgICBNU0dfTk9UQVRJT05fTk9UX0RFQ0xBUkVEX0ZPUl9VTlBBUlNFRF9FTlRJVFlERUNMID0gTm90YXRpb24gInsxfSIgbXVzcyBkZWtsYXJpZXJ0IHdlcmRlbiwgd2VubiBzaWUgaW4gZGVyIERla2xhcmF0aW9uIGRlciBuaWNodCBnZXBhcnN0ZW4gRW50aXR5IGZcdTAwRkNyICJ7MH0iIHJlZmVyZW56aWVydCB3aXJkLgotICAgICAgICBNU0dfUkVGRVJFTkNFX1RPX0VYVEVSTkFMTFlfREVDTEFSRURfRU5USVRZX1dIRU5fU1RBTkRBTE9ORSA9IFJlZmVyZW56IHp1ciBFbnRpdHkgInswfSIsIGRpZSBpbiBlaW5lciBleHRlcm5lbiBnZXBhcnN0ZW4gRW50aXR5IGRla2xhcmllcnQgd2lyZCwgaXN0IGluIGVpbmVtIFN0YW5kYWxvbmUtRG9rdW1lbnQgbmljaHQgenVsXHUwMEU0c3NpZy4KLSAgICAgICAgTVNHX1JFUVVJUkVEX0FUVFJJQlVURV9OT1RfU1BFQ0lGSUVEID0gQXR0cmlidXQgInsxfSIgaXN0IGVyZm9yZGVybGljaCB1bmQgbXVzcyBmXHUwMEZDciBFbGVtZW50dHlwICJ7MH0iIGFuZ2VnZWJlbiB3ZXJkZW4uCi0gICAgICAgIE1TR19XSElURV9TUEFDRV9JTl9FTEVNRU5UX0NPTlRFTlRfV0hFTl9TVEFOREFMT05FID0gRXMgZFx1MDBGQ3JmZW4ga2VpbmUgTGVlcnN0ZWxsZW4gendpc2NoZW4gRWxlbWVudGVuIGluIGVpbmVtIFN0YW5kYWxvbmUtRG9rdW1lbnQgdm9ya29tbWVuLCBkaWUgaW4gZWluZXIgZXh0ZXJuZW4gZ2VwYXJzdGVuIEVudGl0eSBtaXQgRWxlbWVudGNvbnRlbnQgZGVrbGFyaWVydCBzaW5kLgotICAgICAgICBOTVRPS0VOSW52YWxpZCA9IEF0dHJpYnV0d2VydCAiezB9IiBtaXQgZGVtIFR5cCBOTVRPS0VOIG11c3MgZWluIE5hbWVuc3Rva2VuIHNlaW4uCi0gICAgICAgIE5NVE9LRU5TSW52YWxpZCA9IEF0dHJpYnV0d2VydCAiezB9IiBtaXQgZGVtIFR5cCBOTVRPS0VOUyBtdXNzIG1pbmRlc3RlbnMgZWluIE5hbWVuc3Rva2VuIHNlaW4uCi0gICAgICAgIE5vTm90YXRpb25PbkVtcHR5RWxlbWVudCA9IEVsZW1lbnR0eXAgInswfSIsIGRlciBhbHMgRU1QVFkgZGVrbGFyaWVydCB3dXJkZSwga2FubiBuaWNodCBkYXMgQXR0cmlidXQgInsxfSIgbWl0IGRlbSBUeXAgTk9UQVRJT04gZGVrbGFyaWVyZW4uCi0gICAgICAgIFJvb3RFbGVtZW50VHlwZU11c3RNYXRjaERvY3R5cGVkZWNsID0gRG9jdW1lbnQgUm9vdC1FbGVtZW50ICJ7MX0ibXVzcyBtaXQgRE9DVFlQRS1Sb290ICJ7MH0iIFx1MDBGQ2JlcmVpbnN0aW1tZW4uCi0gICAgICAgIFVuZGVjbGFyZWRFbGVtZW50SW5Db250ZW50U3BlYyA9IENvbnRlbnRtb2RlbGwgZGVzIEVsZW1lbnRzICJ7MH0iIHZlcndlaXN0IGF1ZiBkYXMgbmljaHQgZGVrbGFyaWVydGUgRWxlbWVudCAiezF9Ii4KLSAgICAgICAgVW5pcXVlTm90YXRpb25OYW1lID0gRGVrbGFyYXRpb24gZlx1MDBGQ3IgZGllIE5vdGF0aW9uICJ7MH0iIGlzdCBuaWNodCBlaW5kZXV0aWcuIEVpbiBqZXdlaWxpZ2VyIE5hbWUgZGFyZiBuaWNodCBpbiBtZWhyZXJlbiBOb3RhdGlvbnNkZWtsYXJhdGlvbmVuIGRla2xhcmllcnQgd2VyZGVuLgotICAgICAgICBFTlRJVFlGYWlsZWRJbml0aWFsaXplR3JhbW1hciA9ICBFTlRJVFlEYXRhdHlwZS1WYWxpZGF0b3I6IE5pY2h0IGVyZm9sZ3JlaWNoLiBJbml0aWFsaXNpZXJ1bmdzbWV0aG9kZSBtdXNzIG1pdCBlaW5lciBnXHUwMEZDbHRpZ2VuIEdyYW1tYXRpa3JlZmVyZW56IGF1ZmdlcnVmZW4gd2VyZGVuLiBcdAotICAgICAgICBFTlRJVFlOb3RVbnBhcnNlZCA9IEVOVElUWSAiezB9IiBpc3QgZ2VwYXJzdC4KLSAgICAgICAgRU5USVRZTm90VmFsaWQgPSBFTlRJVFkgInswfSIgaXN0IG5pY2h0IGdcdTAwRkNsdGlnLgotICAgICAgICBFbXB0eUxpc3QgPSBXZXJ0ZSBkZXIgVHlwZW4gRU5USVRJRVMsIElEUkVGUyB1bmQgTk1UT0tFTlMgZFx1MDBGQ3JmZW4ga2VpbmUgbGVlcmVuIExpc3RlbiBzZWluLgotCi0jIEVudGl0eSByZWxhdGVkIG1lc3NhZ2VzCi0jIDMuMSBTdGFydC1UYWdzLCBFbmQtVGFncywgYW5kIEVtcHR5LUVsZW1lbnQgVGFncwotICAgICAgICBSZWZlcmVuY2VUb0V4dGVybmFsRW50aXR5ID0gRXh0ZXJuZSBFbnRpdHlyZWZlcmVueiAiJnswfTsiIGlzdCBpbiBlaW5lbSBBdHRyaWJ1dHdlcnQgbmljaHQgenVsXHUwMEU0c3NpZy4KLSAgICAgICAgQWNjZXNzRXh0ZXJuYWxEVEQgPSBFeHRlcm5lIERURDogTGVzZW4gdm9uIGV4dGVybmVyIERURCAiezB9IiBuaWNodCBlcmZvbGdyZWljaCwgZGEgInsxfSItWnVncmlmZiB3ZWdlbiBkZXIgdm9uIGRlciBFaWdlbnNjaGFmdCAiYWNjZXNzRXh0ZXJuYWxEVEQiIGZlc3RnZWxlZ3RlbiBFaW5zY2hyXHUwMEU0bmt1bmcgbmljaHQgenVsXHUwMEU0c3NpZyBpc3QuCi0gICAgICAgIEFjY2Vzc0V4dGVybmFsRW50aXR5ID0gRXh0ZXJuZSBFbnRpdHk6IExlc2VuIGRlcyBleHRlcm5lbiBEb2t1bWVudHMgInswfSIgbmljaHQgZXJmb2xncmVpY2gsIGRhICJ7MX0iLVp1Z3JpZmYgd2VnZW4gZGVyIHZvbiBkZXIgRWlnZW5zY2hhZnQgImFjY2Vzc0V4dGVybmFsRFREIiBmZXN0Z2VsZWd0ZW4gRWluc2Noclx1MDBFNG5rdW5nIG5pY2h0IHp1bFx1MDBFNHNzaWcgaXN0LgotCi0jIDQuMSBDaGFyYWN0ZXIgYW5kIEVudGl0eSBSZWZlcmVuY2VzCi0gICAgICAgIEVudGl0eU5vdERlY2xhcmVkID0gRW50aXR5ICJ7MH0iIHd1cmRlIHJlZmVyZW56aWVydCBhYmVyIG5pY2h0IGRla2xhcmllcnQuCi0gICAgICAgIFJlZmVyZW5jZVRvVW5wYXJzZWRFbnRpdHkgPSBOaWNodCBnZXBhcnN0ZSBFbnRpdHlyZWZlcmVueiAiJnswfTsiIGlzdCBuaWNodCB6dWxcdTAwRTRzc2lnLgotICAgICAgICBSZWN1cnNpdmVSZWZlcmVuY2UgPSBSZWt1cnNpdmUgRW50aXR5cmVmZXJlbnogInswfSIuIChSZWZlcmVuenBmYWQ6IHsxfSksCi0gICAgICAgIFJlY3Vyc2l2ZUdlbmVyYWxSZWZlcmVuY2UgPSBSZWt1cnNpdmUgYWxsZ2VtZWluZSBFbnRpdHlyZWZlcmVueiAiJnswfTsiLiAoUmVmZXJlbnpwZmFkOiB7MX0pLAotICAgICAgICBSZWN1cnNpdmVQRVJlZmVyZW5jZSA9IFJla3Vyc2l2ZSBQYXJhbWV0ZXJlbnRpdHlyZWZlcmVueiAiJXswfTsiLiAoUmVmZXJlbnpwZmFkOiB7MX0pLAotIyA0LjMuMyBDaGFyYWN0ZXIgRW5jb2RpbmcgaW4gRW50aXRpZXMKLSAgICAgICAgRW5jb2RpbmdOb3RTdXBwb3J0ZWQgPSBDb2RpZXJ1bmcgInswfSIgd2lyZCBuaWNodCB1bnRlcnN0XHUwMEZDdHp0LgotICAgICAgICBFbmNvZGluZ1JlcXVpcmVkID0gRWluZSBuaWNodCBpbiBVVEYtOCBvZGVyIFVURi0xNiBjb2RpZXJ0ZSBnZXBhcnN0ZSBFbnRpdHkgbXVzcyBlaW5lIENvZGllcnVuZ3NkZWtsYXJhdGlvbiBlbnRoYWx0ZW4uCi0gICAgICAgIAotIyBOYW1lc3BhY2VzIHN1cHBvcnQKLSMgNC4gVXNpbmcgUXVhbGlmaWVkIE5hbWVzCi0gICAgICAgIElsbGVnYWxRTmFtZSA9IEVsZW1lbnQgb2RlciBBdHRyaWJ1dCBzdGltbXQgbmljaHQgbWl0IFFOYW1lLVByb2R1Y3Rpb24gXHUwMEZDYmVyZWluOiBRTmFtZTo6PShOQ05hbWUnOicpP05DTmFtZS4gCi0gICAgICAgIEVsZW1lbnRYTUxOU1ByZWZpeCA9IEVsZW1lbnQgInswfSIgZGFyZiBuaWNodCAieG1sbnMiIGFscyBQclx1MDBFNGZpeCBlbnRoYWx0ZW4uCi0gICAgICAgIEVsZW1lbnRQcmVmaXhVbmJvdW5kID0gUHJcdTAwRTRmaXggInswfSIgZlx1MDBGQ3IgRWxlbWVudCAiezF9IiBpc3QgbmljaHQgZ2VidW5kZW4uCi0gICAgICAgIEF0dHJpYnV0ZVByZWZpeFVuYm91bmQgPSBQclx1MDBFNGZpeCAiezJ9IiBmXHUwMEZDciBBdHRyaWJ1dCAiezF9IiwgZGFzIG1pdCBFbGVtZW50dHlwICJ7MH0iIHZlcmtuXHUwMEZDcGZ0IGlzdCwgaXN0IG5pY2h0IGdlYnVuZGVuLgotICAgICAgICBFbXB0eVByZWZpeGVkQXR0TmFtZSA9IFdlcnQgZGVzIEF0dHJpYnV0cyAiezB9IiBpc3QgdW5nXHUwMEZDbHRpZy4gTmFtZXNwYWNlIEJpbmRpbmdzIG1pdCBQclx1MDBFNGZpeCBkXHUwMEZDcmZlbiBuaWNodCBsZWVyIHNlaW4uCi0gICAgICAgIFByZWZpeERlY2xhcmVkID0gTmFtZXNwYWNlLVByXHUwMEU0Zml4ICJ7MH0iIHd1cmRlIG5pY2h0IGRla2xhcmllcnQuCi0gICAgICAgIENhbnRCaW5kWE1MTlMgPSBQclx1MDBFNGZpeCAieG1sbnMiIGthbm4gbmljaHQgZXhwbGl6aXQgYW4gZWluZW4gTmFtZXNwYWNlIGdlYnVuZGVuIHdlcmRlbi4gVW1nZWtlaHJ0IGthbm4gYXVjaCBkZXIgTmFtZXNwYWNlIGZcdTAwRkNyICJ4bWxucyIgbmljaHQgZXhwbGl6aXQgYW4gZWluIFByXHUwMEU0Zml4IGdlYnVuZGVuIHdlcmRlbi4KLSAgICAgICAgQ2FudEJpbmRYTUwgPSBQclx1MDBFNGZpeCAieG1sIiBrYW5uIG5pY2h0IGFuIGVpbmVuIGFuZGVyZW4gTmFtZXNwYWNlIGFscyBkZW4gZ2V3XHUwMEY2aG5saWNoZW4gZ2VidW5kZW4gd2VyZGVuLiBVbWdla2VocnQga2FubiBhdWNoIGRlciBOYW1lc3BhY2UgZlx1MDBGQ3IgInhtbCIgbmljaHQgYW4gZWluIGFuZGVyZXMgUHJcdTAwRTRmaXggYWxzICJ4bWwiIGdlYnVuZGVuIHdlcmRlbi4KLSAgICAgICAgTVNHX0FUVF9ERUZBVUxUX0lOVkFMSUQgPSBkZWZhdWx0VmFsdWUgInsxfSIgdm9uIEF0dHJpYnV0ICJ7MH0iIGlzdCBhdWZncnVuZCBkZXIgbGV4aWthbGlzY2hlbiBDb25zdHJhaW50cyBkaWVzZXMgQXR0cmlidXR0eXBzIG5pY2h0IGdcdTAwRkNsdGlnLgotCi0jIFJFVklTSVQ6IFRoZXNlIG5lZWQgbWVzc2FnZXMKLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0FGVEVSX1NZU1RFTUxJVEVSQUxfSU5fRVhURVJOQUxJRD1NU0dfU1BBQ0VfUkVRVUlSRURfQUZURVJfU1lTVEVNTElURVJBTF9JTl9FWFRFUk5BTElECi0gICAgICAgIE9wZW5RdW90ZU1pc3NpbmdJbkRlY2w9T3BlblF1b3RlTWlzc2luZ0luRGVjbAotICAgICAgICBJbnZhbGlkQ2hhckluTGl0ZXJhbD1JbnZhbGlkQ2hhckluTGl0ZXJhbAotCi0KLSMgSW1wbGVtZW50YXRpb24gbGltaXRzCi0gICAgICAgIEVudGl0eUV4cGFuc2lvbkxpbWl0PUpBWFAwMDAxMDAwMTogRGVyIFBhcnNlciBoYXQgbWVociBhbHMgezB9IEVudGl0eWVyd2VpdGVydW5nZW4gaW4gZGllc2VtIERva3VtZW50IGdlZnVuZGVuLiBEaWVzIGlzdCBkZXIgdm9uIEpESyB2b3JnZXNjaHJpZWJlbmUgR3Jlbnp3ZXJ0LgotICAgICAgICBFbGVtZW50QXR0cmlidXRlTGltaXQ9SkFYUDAwMDEwMDAyOiBFbGVtZW50ICJ7MH0iIGhhdCBtZWhyIGFscyB7MX0gQXR0cmlidXRlLiAiezF9IiBpc3QgZGVyIHZvbiBKREsgdm9yZ2VzY2hyaWViZW5lIEdyZW56d2VydC4KLSAgICAgICAgTWF4RW50aXR5U2l6ZUxpbWl0PUpBWFAwMDAxMDAwMzogRGllIExcdTAwRTRuZ2Ugdm9uIEVudGl0eSAiezB9IiBpc3QgInsxfSIgdW5kIFx1MDBGQ2JlcnNjaHJlaXRldCBkZW4gR3Jlbnp3ZXJ0ICJ7Mn0iLCBkZXIgdm9uICJ7M30iIGZlc3RnZWxlZ3Qgd3VyZGUuCi0gICAgICAgIFRvdGFsRW50aXR5U2l6ZUxpbWl0PUpBWFAwMDAxMDAwNDogRGllIGFra3VtdWxpZXJ0ZSBHclx1MDBGNlx1MDBERmUgdm9uIEVudGl0eXMgaXN0ICJ7MH0iIHVuZCBcdTAwRkNiZXJzY2hyZWl0ZXQgZGVuIEdyZW56d2VydCAiezF9IiwgZGVyIHZvbiAiezJ9IiBmZXN0Z2VsZWd0IHd1cmRlLgotICAgICAgICBNYXhYTUxOYW1lTGltaXQ9SkFYUDAwMDEwMDA1OiBEaWUgTFx1MDBFNG5nZSB2b24gRW50aXR5ICJ7MH0iIGlzdCAiezF9IiB1bmQgXHUwMEZDYmVyc2NocmVpdGV0IGRlbiBHcmVuendlcnQgInsyfSIsIGRlciB2b24gInszfSIgZmVzdGdlbGVndCB3dXJkZS4KLSAgICAgICAgTWF4RWxlbWVudERlcHRoTGltaXQ9SkFYUDAwMDEwMDA2OiBEaWUgVGllZmUgdm9uIEVsZW1lbnQgInswfSIgaXN0ICJ7MX0iIHVuZCBcdTAwRkNiZXJzY2hyZWl0ZXQgZGVuIEdyZW56d2VydCAiezJ9IiwgZGVyIHZvbiAiezN9IiBmZXN0Z2VsZWd0IHd1cmRlLgotICAgICAgICBFbnRpdHlSZXBsYWNlbWVudExpbWl0PUpBWFAwMDAxMDAwNzogRGllIEdlc2FtdGFuemFobCB2b24gS25vdGVuIGluIEVudGl0eXJlZmVyZW56ZW4gYmV0clx1MDBFNGd0ICJ7MH0iLiBEYXMgbGllZ3QgXHUwMEZDYmVyIGRlbSB2b24gInsyfSIgZmVzdGdlbGVndGVuIEdyZW56d2VydCAiezF9Ii4KLQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MTWVzc2FnZXNfZXMucHJvcGVydGllcyBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hNTE1lc3NhZ2VzX2VzLnByb3BlcnRpZXMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDEwOGVlZWIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MTWVzc2FnZXNfZXMucHJvcGVydGllcworKysgL2Rldi9udWxsCkBAIC0xLDMwNSArMCwwIEBACi0jIFRoaXMgZmlsZSBjb250YWlucyBlcnJvciBhbmQgd2FybmluZyBtZXNzYWdlcyByZWxhdGVkIHRvIFhNTAotIyBUaGUgbWVzc2FnZXMgYXJlIGFycmFuZ2VkIGluIGtleSBhbmQgdmFsdWUgdHVwbGVzIGluIGEgTGlzdFJlc291cmNlQnVuZGxlLgotIwotIyBAdmVyc2lvbgotCi0gICAgICAgIEJhZE1lc3NhZ2VLZXkgPSBObyBzZSBoYSBlbmNvbnRyYWRvIGVsIG1lbnNhamUgZGUgZXJyb3IgY29ycmVzcG9uZGllbnRlIGEgbGEgY2xhdmUgZGUgbWVuc2FqZS4KLSAgICAgICAgRm9ybWF0RmFpbGVkID0gU2UgaGEgcHJvZHVjaWRvIHVuIGVycm9yIGludGVybm8gYWwgZm9ybWF0ZWFyIGVsIHNpZ3VpZW50ZSBtZW5zYWplOlxuICAKLSAgICAgICAgCi0jIERvY3VtZW50IG1lc3NhZ2VzCi0gICAgICAgIFByZW1hdHVyZUVPRj1GaW5hbCBkZSBhcmNoaXZvIHByZW1hdHVyby4KLSMgMi4xIFdlbGwtRm9ybWVkIFhNTCBEb2N1bWVudHMKLSAgICAgICAgUm9vdEVsZW1lbnRSZXF1aXJlZCA9IEVsIGVsZW1lbnRvIHJhXHUwMEVEeiBlcyBuZWNlc2FyaW8gZW4gdW4gZG9jdW1lbnRvIGNvbiBmb3JtYXRvIGNvcnJlY3RvLgotIyAyLjIgQ2hhcmFjdGVycwotCi0gICAgICAgIEludmFsaWRDaGFySW5DRFNlY3QgPSBTZSBoYSBlbmNvbnRyYWRvIHVuIGNhclx1MDBFMWN0ZXIgWE1MIChVbmljb2RlOiAweHswfSkgbm8gdlx1MDBFMWxpZG8gZW4gbGEgc2VjY2lcdTAwRjNuIENEQVRBLgotICAgICAgICBJbnZhbGlkQ2hhckluQ29udGVudCA9IFNlIGhhIGVuY29udHJhZG8gdW4gY2FyXHUwMEUxY3RlciBYTUwgKFVuaWNvZGU6IDB4ezB9KSBubyB2XHUwMEUxbGlkbyBlbiBlbCBjb250ZW5pZG8gZGVsIGVsZW1lbnRvIGRlbCBkb2N1bWVudG8uCi0gICAgICAgIFR3b0NvbG9uc0luUU5hbWUgPSBTZSBoYSBlbmNvbnRyYWRvIHVuIHNlZ3VuZG8gJzonIG5vIHZcdTAwRTFsaWRvIGVuIGVsIHRpcG8gZGUgZWxlbWVudG8gbyBlbiBlbCBub21icmUgZGVsIGF0cmlidXRvLgotICAgICAgICBDb2xvbk5vdExlZ2FsV2l0aE5TID0gTm8gc2UgcGVybWl0ZSBpbmNsdWlyIGRvcyBwdW50b3MgZW4gZWwgbm9tYnJlICcnezB9JycgY3VhbmRvIHNlIGFjdGl2YW4gbG9zIGVzcGFjaW9zIGRlIG5vbWJyZXMuCi0gICAgICAgIEludmFsaWRDaGFySW5NaXNjID0gU2UgaGEgZW5jb250cmFkbyB1biBjYXJcdTAwRTFjdGVyIFhNTCAoVW5pY29kZTogMHh7MH0pIG5vIHZcdTAwRTFsaWRvIGVuIGVsIG1hcmNhZG9yIGFsIGZpbmFsaXphciBlbCBjb250ZW5pZG8gZGVsIGVsZW1lbnRvLgotICAgICAgICBJbnZhbGlkQ2hhckluUHJvbG9nID0gU2UgaGEgZW5jb250cmFkbyB1biBjYXJcdTAwRTFjdGVyIFhNTCAoVW5pY29kZTogMHh7MH0pIG5vIHZcdTAwRTFsaWRvIGVuIGVsIHByXHUwMEYzbG9nbyBkZWwgZG9jdW1lbnRvLgotICAgICAgICBJbnZhbGlkQ2hhckluWE1MRGVjbCA9IFNlIGhhIGVuY29udHJhZG8gdW4gY2FyXHUwMEUxY3RlciBYTUwgKFVuaWNvZGU6IDB4ezB9KSBubyB2XHUwMEUxbGlkbyBlbiBsYSBkZWNsYXJhY2lcdTAwRjNuIFhNTC4KLSMgMi40IENoYXJhY3RlciBEYXRhIGFuZCBNYXJrdXAKLSAgICAgICAgQ0RFbmRJbkNvbnRlbnQgPSBMYSBzZWN1ZW5jaWEgZGUgY2FyYWN0ZXJlcyAiXV0+IiBubyBkZWJlIGFwYXJlY2VyIGVuIGVsIGNvbnRlbmlkbywgYSBtZW5vcyBxdWUgc2UgdXRpbGljZSBwYXJhIG1hcmNhciBlbCBmaW5hbCBkZSB1bmEgc2VjY2lcdTAwRjNuIENEQVRBLgotIyAyLjcgQ0RBVEEgU2VjdGlvbnMKLSAgICAgICAgQ0RTZWN0VW50ZXJtaW5hdGVkID0gTGEgc2VjY2lcdTAwRjNuIENEQVRBIGRlYmUgZmluYWxpemFyIGVuICJdXT4iLgotIyAyLjggUHJvbG9nIGFuZCBEb2N1bWVudCBUeXBlIERlY2xhcmF0aW9uCi0gICAgICAgIFhNTERlY2xNdXN0QmVGaXJzdCA9IExhIGRlY2xhcmFjaVx1MDBGM24gWE1MIHNcdTAwRjNsbyBwdWVkZSBhcGFyZWNlciBhbCBwcmluY2lwaW8gZGVsIGRvY3VtZW50by4KLSAgICAgICAgRXFSZXF1aXJlZEluWE1MRGVjbCA9IEVsIGNhclx1MDBFMWN0ZXIgJycgPSAnJyBkZWJlIGFwYXJlY2VyIGRlc3B1XHUwMEU5cyBkZSAiezB9IiBlbiBsYSBkZWNsYXJhY2lcdTAwRjNuIFhNTC4KLSAgICAgICAgUXVvdGVSZXF1aXJlZEluWE1MRGVjbCA9IEVsIHZhbG9yIGRlc3B1XHUwMEU5cyBkZSAiezB9IiBlbiBsYSBkZWNsYXJhY2lcdTAwRjNuIFhNTCBkZWJlIHNlciB1bmEgY2FkZW5hIGNvbiBjb21pbGxhcy4KLSAgICAgICAgWE1MRGVjbFVudGVybWluYXRlZCA9IExhIGRlY2xhcmFjaVx1MDBGM24gWE1MIGRlYmUgZmluYWxpemFyIGVuICI/PiIuCi0gICAgICAgIFZlcnNpb25JbmZvUmVxdWlyZWQgPSBMYSB2ZXJzaVx1MDBGM24gZXMgbmVjZXNhcmlhIGVuIGxhIGRlY2xhcmFjaVx1MDBGM24gWE1MLgotICAgICAgICBTcGFjZVJlcXVpcmVkQmVmb3JlVmVyc2lvbkluWE1MRGVjbCA9IEVzIG5lY2VzYXJpbyB1biBlc3BhY2lvIGVuIGJsYW5jbyBhbnRlcyBkZWwgcHNldWRvIGF0cmlidXRvIHZlcnNpb24gZW4gbGEgZGVjbGFyYWNpXHUwMEYzbiBYTUwuCi0gICAgICAgIFNwYWNlUmVxdWlyZWRCZWZvcmVFbmNvZGluZ0luWE1MRGVjbCA9IEVzIG5lY2VzYXJpbyB1biBlc3BhY2lvIGVuIGJsYW5jbyBhbnRlcyBkZWwgcHNldWRvIGF0cmlidXRvIGVuY29kaW5nIGVuIGxhIGRlY2xhcmFjaVx1MDBGM24gWE1MLgotICAgICAgICBTcGFjZVJlcXVpcmVkQmVmb3JlU3RhbmRhbG9uZSA9IEVzIG5lY2VzYXJpbyB1biBlc3BhY2lvIGVuIGJsYW5jbyBhbnRlcyBkZWwgcHNldWRvIGF0cmlidXRvIGVuY29kaW5nIGVuIGxhIGRlY2xhcmFjaVx1MDBGM24gWE1MLgotICAgICAgICBNYXJrdXBOb3RSZWNvZ25pemVkSW5Qcm9sb2cgPSBFbCBtYXJjYWRvciBlbiBlbCBkb2N1bWVudG8gcXVlIHByZWNlZGUgYWwgZWxlbWVudG8gcmFcdTAwRUR6IGRlYmUgdGVuZXIgZWwgZm9ybWF0byBjb3JyZWN0by4KLSAgICAgICAgTWFya3VwTm90UmVjb2duaXplZEluTWlzYyA9IEVsIG1hcmNhZG9yIGVuIGVsIGRvY3VtZW50byBxdWUgYXBhcmVjZSB0cmFzIGVsIGVsZW1lbnRvIHJhXHUwMEVEeiBkZWJlIHRlbmVyIGVsIGZvcm1hdG8gY29ycmVjdG8uCi0gICAgICAgIEFscmVhZHlTZWVuRG9jdHlwZSA9IFRpcG8gZGUgZG9jdW1lbnRvIHlhIGNvbnN1bHRhZG8uCi0gICAgICAgIERvY3R5cGVOb3RBbGxvd2VkID0gRE9DVFlQRSBubyBlc3RcdTAwRTEgcGVybWl0aWRvIGN1YW5kbyBsYSBmdW5jaVx1MDBGM24gImh0dHA6Ly9hcGFjaGUub3JnL3htbC9mZWF0dXJlcy9kaXNhbGxvdy1kb2N0eXBlLWRlY2wiIHNlIGhhIGRlZmluaWRvIGVuIHRydWUuCi0gICAgICAgIENvbnRlbnRJbGxlZ2FsSW5Qcm9sb2cgPSBFbCBjb250ZW5pZG8gbm8gZXN0XHUwMEUxIHBlcm1pdGlkbyBlbiBlbCBwclx1MDBGM2xvZ28uCi0gICAgICAgIFJlZmVyZW5jZUlsbGVnYWxJblByb2xvZyA9IExhIHJlZmVyZW5jaWEgbm8gZXN0XHUwMEUxIHBlcm1pdGlkYSBlbiBlbCBwclx1MDBGM2xvZ28uCi0jIFRyYWlsaW5nIE1pc2MKLSAgICAgICAgQ29udGVudElsbGVnYWxJblRyYWlsaW5nTWlzYz1FbCBjb250ZW5pZG8gbm8gZXN0XHUwMEUxIHBlcm1pdGlkbyBlbiBsYSBzZWNjaVx1MDBGM24gZmluYWwuCi0gICAgICAgIFJlZmVyZW5jZUlsbGVnYWxJblRyYWlsaW5nTWlzYz1MYSByZWZlcmVuY2lhIG5vIGVzdFx1MDBFMSBwZXJtaXRpZGEgZW4gbGEgc2VjY2lcdTAwRjNuIGZpbmFsLgotICAgICAgICAKLSMgMi45IFN0YW5kYWxvbmUgRG9jdW1lbnQgRGVjbGFyYXRpb24KLSAgICAgICAgU0REZWNsSW52YWxpZCA9IEVsIHZhbG9yIGRlIGRlY2xhcmFjaVx1MDBGM24gZGVsIGRvY3VtZW50byBhdXRcdTAwRjNub21vIGRlYmUgc2VyICJ5ZXMiIG8gIm5vIiwgcGVybyBudW5jYSAiezB9Ii4KLSAgICAgICAgU0REZWNsTmFtZUludmFsaWQgPSBQdWVkZSBxdWUgZWwgbm9tYnJlIGF1dFx1MDBGM25vbW8gZGUgbGEgZGVjbGFyYWNpXHUwMEYzbiBYTUwgZXN0XHUwMEU5IG1hbCBlc2NyaXRvLgotIyAyLjEyIExhbmd1YWdlIElkZW50aWZpY2F0aW9uCi0gICAgICAgIFhNTExhbmdJbnZhbGlkID0gRWwgdmFsb3IgZGVsIGF0cmlidXRvIHhtbDpsYW5nICJ7MH0iIGVzIHVuIGlkZW50aWZpY2Fkb3IgZGUgaWRpb21hIG5vIHZcdTAwRTFsaWRvLgotIyAzLiBMb2dpY2FsIFN0cnVjdHVyZXMKLSAgICAgICAgRVRhZ1JlcXVpcmVkID0gRWwgdGlwbyBkZSBlbGVtZW50byAiezB9IiBkZWJlIGZpbmFsaXphciBwb3IgbGEgZXRpcXVldGEgZmluYWwgY29pbmNpZGVudGUgIjwvezB9PiIuCi0jIDMuMSBTdGFydC1UYWdzLCBFbmQtVGFncywgYW5kIEVtcHR5LUVsZW1lbnQgVGFncwotICAgICAgICBFbGVtZW50VW50ZXJtaW5hdGVkID0gRWwgdGlwbyBkZSBlbGVtZW50byAiezB9IiBkZWJlIGlyIHNlZ3VpZG8gZGUgdW5hIGRlIGVzdGFzIGVzcGVjaWZpY2FjaW9uZXMgZGUgYXRyaWJ1dG86ICI+IiBvICIvPiIuCi0gICAgICAgIEVxUmVxdWlyZWRJbkF0dHJpYnV0ZSA9IEVsIG5vbWJyZSBkZSBhdHJpYnV0byAiezF9IiBhc29jaWFkbyBhIHVuIHRpcG8gZGUgZWxlbWVudG8gInswfSIgZGViZSBpciBzZWd1aWRvIGRlbCBjYXJcdTAwRTFjdGVyICcnID0gJycuCi0gICAgICAgIE9wZW5RdW90ZUV4cGVjdGVkID0gTGFzIGNvbWlsbGFzIGRlIGFwZXJ0dXJhIHNlIGRlYmVuIHV0aWxpemFyIHBhcmEgZWwgYXRyaWJ1dG8gInsxfSIgYXNvY2lhZG8gYSB1biB0aXBvIGRlIGVsZW1lbnRvICJ7MH0iLgotICAgICAgICBDbG9zZVF1b3RlRXhwZWN0ZWQgPSBMYXMgY29taWxsYXMgZGUgY2llcnJlIHNlIGRlYmVuIHV0aWxpemFyIHBhcmEgZWwgYXRyaWJ1dG8gInsxfSIgYXNvY2lhZG8gYSB1biB0aXBvIGRlIGVsZW1lbnRvICJ7MH0iLgotICAgICAgICBBdHRyaWJ1dGVOb3RVbmlxdWUgPSBFbCBhdHJpYnV0byAiezF9IiB5YSBzZSBoYSBlc3BlY2lmaWNhZG8gcGFyYSBlbCBlbGVtZW50byAiezB9Ii4KLSAgICAgICAgQXR0cmlidXRlTlNOb3RVbmlxdWUgPSBFbCBhdHJpYnV0byAiezF9IiBlbmxhemFkbyBhbCBlc3BhY2lvIGRlIG5vbWJyZXMgInsyfSIgeWEgc2UgaGEgZXNwZWNpZmljYWRvIHBhcmEgZWwgZWxlbWVudG8gInswfSIuCi0gICAgICAgIEVUYWdVbnRlcm1pbmF0ZWQgPSBMYSBldGlxdWV0YSBmaW5hbCBwYXJhIGVsIHRpcG8gZGUgZWxlbWVudG8gInswfSIgZGViZSBmaW5hbGl6YXIgZW4gdW4gZGVsaW1pdGFkb3IgJyc+JycuCi0gICAgICAgIE1hcmt1cE5vdFJlY29nbml6ZWRJbkNvbnRlbnQgPSBFbCBjb250ZW5pZG8gZGUgbG9zIGVsZW1lbnRvcyBkZWJlIGNvbnN0YXIgZGUgbWFyY2Fkb3JlcyBvIGRhdG9zIGRlIGNhclx1MDBFMWN0ZXIgY29uIHVuIGZvcm1hdG8gY29ycmVjdG8uCi0gICAgICAgIERvY3R5cGVJbGxlZ2FsSW5Db250ZW50ID0gTm8gc2UgcGVybWl0ZSB1biBET0NUWVBFIGVuIGVsIGNvbnRlbmlkby4KLSMgNC4xIENoYXJhY3RlciBhbmQgRW50aXR5IFJlZmVyZW5jZXMKLSAgICAgICAgUmVmZXJlbmNlVW50ZXJtaW5hdGVkID0gTGEgcmVmZXJlbmNpYSBkZWJlIGZpbmFsaXphciBjb24gdW4gZGVsaW1pdGFkb3IgJzsnLgotIyA0LjMuMiBXZWxsLUZvcm1lZCBQYXJzZWQgRW50aXRpZXMKLSAgICAgICAgUmVmZXJlbmNlTm90SW5PbmVFbnRpdHkgPSBMYSByZWZlcmVuY2lhIGRlYmUgaW5jbHVpcnNlIHRvdGFsbWVudGUgZW4gbGEgbWlzbWEgZW50aWRhZCBhbmFsaXphZGEuCi0gICAgICAgIEVsZW1lbnRFbnRpdHlNaXNtYXRjaCA9IEVsIGVsZW1lbnRvICJ7MH0iIGRlYmUgZW1wZXphciB5IGZpbmFsaXphciBlbiBsYSBtaXNtYSBlbnRpZGFkLgotICAgICAgICBNYXJrdXBFbnRpdHlNaXNtYXRjaD1MYXMgZXN0cnVjdHVyYXMgZGVsIGRvY3VtZW50byBYTUwgZGViZW4gZW1wZXphciB5IGZpbmFsaXphciBlbiBsYSBtaXNtYSBlbnRpZGFkLgotICAgICAgICAKLSMgTWVzc2FnZXMgY29tbW9uIHRvIERvY3VtZW50IGFuZCBEVEQKLSMgMi4yIENoYXJhY3RlcnMKLSAgICAgICAgSW52YWxpZENoYXJJbkF0dFZhbHVlID0gU2UgaGEgZW5jb250cmFkbyB1biBjYXJcdTAwRTFjdGVyIFhNTCAoVW5pY29kZTogMHh7Mn0pIG5vIHZcdTAwRTFsaWRvIGVuIGVsIHZhbG9yIGRlbCBhdHJpYnV0byAiezF9IiB5IGVsIGVsZW1lbnRvIGVzICJ7MH0iLgotICAgICAgICBJbnZhbGlkQ2hhckluQ29tbWVudCA9IFNlIGhhIGVuY29udHJhZG8gdW4gY2FyXHUwMEUxY3RlciBYTUwgKFVuaWNvZGU6IDB4ezB9KSBubyB2XHUwMEUxbGlkbyBlbiBlbCBjb21lbnRhcmlvLgotICAgICAgICBJbnZhbGlkQ2hhckluUEkgPSBTZSBoYSBlbmNvbnRyYWRvIHVuIGNhclx1MDBFMWN0ZXIgWE1MIChVbmljb2RlOiAweHswfSkgbm8gdlx1MDBFMWxpZG8gZW4gbGEgaW5zdHJ1Y2NpXHUwMEYzbiBkZSBwcm9jZXNhbWllbnRvLgotICAgICAgICBJbnZhbGlkQ2hhckluSW50ZXJuYWxTdWJzZXQgPSBTZSBoYSBlbmNvbnRyYWRvIHVuIGNhclx1MDBFMWN0ZXIgWE1MIChVbmljb2RlOiAweHswfSkgbm8gdlx1MDBFMWxpZG8gZW4gZWwgc3ViY29uanVudG8gaW50ZXJubyBkZWwgRFRELgotICAgICAgICBJbnZhbGlkQ2hhckluVGV4dERlY2wgPSBTZSBoYSBlbmNvbnRyYWRvIHVuIGNhclx1MDBFMWN0ZXIgWE1MIChVbmljb2RlOiAweHswfSkgbm8gdlx1MDBFMWxpZG8gZW4gbGEgZGVjbGFyYWNpXHUwMEYzbiBkZSB0ZXh0by4KLSMgMi4zIENvbW1vbiBTeW50YWN0aWMgQ29uc3RydWN0cwotICAgICAgICBRdW90ZVJlcXVpcmVkSW5BdHRWYWx1ZSA9IEVsIHZhbG9yIGRlbCBhdHJpYnV0byAiezF9IiBkZWJlIGVtcGV6YXIgcG9yIHVuIGNhclx1MDBFMWN0ZXIgZGUgY29taWxsYXMgZG9ibGVzIG8gc2ltcGxlcy4KLSAgICAgICAgTGVzc3RoYW5JbkF0dFZhbHVlID0gRWwgdmFsb3IgZGVsIGF0cmlidXRvICJ7MX0iIGFzb2NpYWRvIGEgdW4gdGlwbyBkZSBlbGVtZW50byAiezB9IiBubyBkZWJlIGNvbnRlbmVyIGVsIGNhclx1MDBFMWN0ZXIgJyc8JycuCi0gICAgICAgIEF0dHJpYnV0ZVZhbHVlVW50ZXJtaW5hdGVkID0gRWwgdmFsb3IgcGFyYSBlbCBhdHJpYnV0byAiezF9IiBkZWJlIGZpbmFsaXphciBlbiB1biBjYXJcdTAwRTFjdGVyIGRlIGNvbWlsbGFzIGNvaW5jaWRlbnRlcy4KLSMgMi41IENvbW1lbnRzCi0gICAgICAgIEludmFsaWRDb21tZW50U3RhcnQgPSBFbCBjb21lbnRhcmlvIGRlYmUgZW1wZXphciBwb3IgIjwhLS0iLgotICAgICAgICBEYXNoRGFzaEluQ29tbWVudCA9IExhIGNhZGVuYSAiLS0iIG5vIGVzdFx1MDBFMSBwZXJtaXRpZGEgZW4gbG9zIGNvbWVudGFyaW9zLgotICAgICAgICBDb21tZW50VW50ZXJtaW5hdGVkID0gRWwgY29tZW50YXJpbyBkZWJlIGZpbmFsaXphciBlbiAiLS0+Ii4KLSAgICAgICAgQ09NTUVOVF9OT1RfSU5fT05FX0VOVElUWSA9IEVsIGNvbWVudGFyaW8gbm8gZXN0XHUwMEUxIGluY2x1aWRvIGVuIGxhIG1pc21hIGVudGlkYWQuCi0jIDIuNiBQcm9jZXNzaW5nIEluc3RydWN0aW9ucwotICAgICAgICBQSVRhcmdldFJlcXVpcmVkID0gTGEgaW5zdHJ1Y2NpXHUwMEYzbiBkZSBwcm9jZXNhbWllbnRvIGRlYmUgZW1wZXphciBwb3IgZWwgbm9tYnJlIGRlbCBkZXN0aW5vLgotICAgICAgICBTcGFjZVJlcXVpcmVkSW5QSSA9IEVzIG5lY2VzYXJpbyB1biBlc3BhY2lvIGVuIGJsYW5jbyBlbnRyZSBlbCBkZXN0aW5vIGRlIGxhIGluc3RydWNjaVx1MDBGM24gZGUgcHJvY2VzYW1pZW50byB5IGxvcyBkYXRvcy4KLSAgICAgICAgUElVbnRlcm1pbmF0ZWQgPSBMYSBpbnN0cnVjY2lcdTAwRjNuIGRlIHByb2Nlc2FtaWVudG8gZGViZSBmaW5hbGl6YXIgZW4gIj8+Ii4KLSAgICAgICAgUmVzZXJ2ZWRQSVRhcmdldCA9IEVsIGRlc3Rpbm8gZGUgbGEgaW5zdHJ1Y2NpXHUwMEYzbiBkZSBwcm9jZXNhbWllbnRvIHF1ZSBjb2luY2lkZSBjb24gIlt4WF1bbU1dW2xMXSIgbm8gZXN0XHUwMEUxIHBlcm1pdGlkby4KLSAgICAgICAgUElfTk9UX0lOX09ORV9FTlRJVFkgPSBMYSBpbnN0cnVjY2lcdTAwRjNuIGRlIHByb2Nlc2FtaWVudG8gbm8gZXN0XHUwMEUxIGluY2x1aWRhIGVuIGxhIG1pc21hIGVudGlkYWQuCi0jIDIuOCBQcm9sb2cgYW5kIERvY3VtZW50IFR5cGUgRGVjbGFyYXRpb24KLSAgICAgICAgVmVyc2lvbkluZm9JbnZhbGlkID0gVmVyc2lcdTAwRjNuIG5vIHZcdTAwRTFsaWRhICJ7MH0iLgotICAgICAgICBWZXJzaW9uTm90U3VwcG9ydGVkID0gTGEgdmVyc2lcdTAwRjNuIFhNTCAiezB9IiBubyBlc3RcdTAwRTEgc29wb3J0YWRhLCBzXHUwMEYzbG8gbGEgdmVyc2lcdTAwRjNuIFhNTCAxLjAgZXN0XHUwMEUxIHNvcG9ydGFkYS4KLSAgICAgICAgVmVyc2lvbk5vdFN1cHBvcnRlZDExID0gTGEgdmVyc2lcdTAwRjNuIFhNTCAiezB9IiBubyBlc3RcdTAwRTEgc29wb3J0YWRhLCBzXHUwMEYzbG8gbGFzIHZlcnNpb25lcyBYTUwgMS4wIHkgWE1MIDEuMSBlc3RcdTAwRTFuIHNvcG9ydGFkYXMuCi0gICAgICAgIFZlcnNpb25NaXNtYXRjaD0gVW5hIGVudGlkYWQgbm8gcHVlZGUgaW5jbHVpciBvdHJhIGVudGlkYWQgZGUgdW5hIHZlcnNpXHUwMEYzbiBwb3N0ZXJpb3IuCi0jIDQuMSBDaGFyYWN0ZXIgYW5kIEVudGl0eSBSZWZlcmVuY2VzCi0gICAgICAgIERpZ2l0UmVxdWlyZWRJbkNoYXJSZWYgPSBVbmEgcmVwcmVzZW50YWNpXHUwMEYzbiBkZWNpbWFsIGRlYmUgYXBhcmVjZXIgaW5tZWRpYXRhbWVudGUgZGVzcHVcdTAwRTlzIGRlICImIyIgZW4gdW5hIHJlZmVyZW5jaWEgZGUgY2FyYWN0ZXJlcy4KLSAgICAgICAgSGV4ZGlnaXRSZXF1aXJlZEluQ2hhclJlZiA9IFVuYSByZXByZXNlbnRhY2lcdTAwRjNuIGhleGFkZWNpbWFsIGRlYmUgYXBhcmVjZXIgaW5tZWRpYXRhbWVudGUgZGVzcHVcdTAwRTlzIGRlICImIyIgZW4gdW5hIHJlZmVyZW5jaWEgZGUgY2FyYWN0ZXJlcy4KLSAgICAgICAgU2VtaWNvbG9uUmVxdWlyZWRJbkNoYXJSZWYgPSBMYSByZWZlcmVuY2lhIGRlIGNhcmFjdGVyZXMgZGViZSBmaW5hbGl6YXIgZW4gZWwgZGVsaW1pdGFkb3IgJzsnLgotICAgICAgICBJbnZhbGlkQ2hhclJlZiA9IExhIHJlZmVyZW5jaWEgZGUgY2FyYWN0ZXJlcyAiJiN7MH0iIGVzIHVuIGNhclx1MDBFMWN0ZXIgWE1MIG5vIHZcdTAwRTFsaWRvLgotICAgICAgICBOYW1lUmVxdWlyZWRJblJlZmVyZW5jZSA9IEVsIG5vbWJyZSBkZSBsYSBlbnRpZGFkIGRlYmUgYXBhcmVjZXIgaW5tZWRpYXRhbWVudGUgZGVzcHVcdTAwRTlzIGRlICcmJyBlbiBsYSByZWZlcmVuY2lhIGRlIGVudGlkYWRlcy4KLSAgICAgICAgU2VtaWNvbG9uUmVxdWlyZWRJblJlZmVyZW5jZSA9IExhIHJlZmVyZW5jaWEgYSBsYSBlbnRpZGFkICJ7MH0iIGRlYmUgZmluYWxpemFyIGVuIGVsIGRlbGltaXRhZG9yICcnOycnLgotIyA0LjMuMSBUaGUgVGV4dCBEZWNsYXJhdGlvbgotICAgICAgICBUZXh0RGVjbE11c3RCZUZpcnN0ID0gTGEgZGVjbGFyYWNpXHUwMEYzbiBkZSB0ZXh0byBzXHUwMEYzbG8gcHVlZGUgYXBhcmVjZXIgYWwgcHJpbmNpcGlvIGRlIGxhIGVudGlkYWQgYW5hbGl6YWRhIGV4dGVybmEuCi0gICAgICAgIEVxUmVxdWlyZWRJblRleHREZWNsID0gRWwgY2FyXHUwMEUxY3RlciAnJyA9ICcnIGRlYmUgYXBhcmVjZXIgZGVzcHVcdTAwRTlzIGRlICJ7MH0iIGVuIGxhIGRlY2xhcmFjaVx1MDBGM24gZGUgdGV4dG8uCi0gICAgICAgIFF1b3RlUmVxdWlyZWRJblRleHREZWNsID0gRWwgdmFsb3IgZGVzcHVcdTAwRTlzIGRlICJ7MH0iIGVuIGxhIGRlY2xhcmFjaVx1MDBGM24gZGUgdGV4dG8gZGViZSBzZXIgdW5hIGNhZGVuYSBjb24gY29taWxsYXMuCi0gICAgICAgIENsb3NlUXVvdGVNaXNzaW5nSW5UZXh0RGVjbCA9IEZhbHRhbiBsYXMgY29taWxsYXMgZGUgY2llcnJlIGVuIGVsIHZhbG9yIGRlc3B1XHUwMEU5cyBkZSAiezB9IiBlbiBsYSBkZWNsYXJhY2lcdTAwRjNuIGRlIHRleHRvLgotICAgICAgICBTcGFjZVJlcXVpcmVkQmVmb3JlVmVyc2lvbkluVGV4dERlY2wgPSBFcyBuZWNlc2FyaW8gdW4gZXNwYWNpbyBlbiBibGFuY28gYW50ZXMgZGVsIHBzZXVkbyBhdHJpYnV0byB2ZXJzaW9uIGVuIGxhIGRlY2xhcmFjaVx1MDBGM24gZGUgdGV4dG8uCi0gICAgICAgIFNwYWNlUmVxdWlyZWRCZWZvcmVFbmNvZGluZ0luVGV4dERlY2wgPSBFcyBuZWNlc2FyaW8gdW4gZXNwYWNpbyBlbiBibGFuY28gYW50ZXMgZGVsIHBzZXVkbyBhdHJpYnV0byBlbmNvZGluZyBlbiBsYSBkZWNsYXJhY2lcdTAwRjNuIGRlIHRleHRvLgotICAgICAgICBUZXh0RGVjbFVudGVybWluYXRlZCA9IExhIGRlY2xhcmFjaVx1MDBGM24gZGUgdGV4dG8gZGViZSBmaW5hbGl6YXIgZW4gIj8+Ii4KLSAgICAgICAgRW5jb2RpbmdEZWNsUmVxdWlyZWQgPSBMYSBkZWNsYXJhY2lcdTAwRjNuIGRlIGNvZGlmaWNhY2lcdTAwRjNuIGVzIG5lY2VzYXJpYSBlbiBsYSBkZWNsYXJhY2lcdTAwRjNuIGRlIHRleHRvLgotICAgICAgICBOb01vcmVQc2V1ZG9BdHRyaWJ1dGVzID0gTm8gc2UgcGVybWl0ZW4gbVx1MDBFMXMgcHNldWRvIGF0cmlidXRvcy4KLSAgICAgICAgTW9yZVBzZXVkb0F0dHJpYnV0ZXMgPSBTZSBlc3BlcmFuIG1cdTAwRTFzIHBzZXVkbyBhdHJpYnV0b3MuCi0gICAgICAgIFBzZXVkb0F0dHJOYW1lRXhwZWN0ZWQgPSBTZSBlc3BlcmEgZWwgbm9tYnJlIGRlIHVuIHBzZXVkbyBhdHJpYnV0by4gCi0jIDQuMy4yIFdlbGwtRm9ybWVkIFBhcnNlZCBFbnRpdGllcwotICAgICAgICBDb21tZW50Tm90SW5PbmVFbnRpdHkgPSBFbCBjb21lbnRhcmlvIGRlYmUgaW5jbHVpcnNlIHRvdGFsbWVudGUgZW4gbGEgbWlzbWEgZW50aWRhZCBhbmFsaXphZGEuCi0gICAgICAgIFBJTm90SW5PbmVFbnRpdHkgPSBMYSBpbnN0cnVjY2lcdTAwRjNuIGRlIHByb2Nlc2FtaWVudG8gZGViZSBpbmNsdWlyc2UgdG90YWxtZW50ZSBlbiBsYSBtaXNtYSBlbnRpZGFkIGFuYWxpemFkYS4KLSMgNC4zLjMgQ2hhcmFjdGVyIEVuY29kaW5nIGluIEVudGl0aWVzCi0gICAgICAgIEVuY29kaW5nRGVjbEludmFsaWQgPSBOb21icmUgZGUgY29kaWZpY2FjaVx1MDBGM24gbm8gdlx1MDBFMWxpZG8gInswfSIuCi0gICAgICAgIEVuY29kaW5nQnl0ZU9yZGVyVW5zdXBwb3J0ZWQgPSBFbCBvcmRlbiBkZSBieXRlcyBwcm9wb3JjaW9uYWRvIHBhcmEgbGEgY29kaWZpY2FjaVx1MDBGM24gInswfSIgbm8gZXN0XHUwMEUxIHNvcG9ydGFkby4KLSAgICAgICAgSW52YWxpZEJ5dGUgPSBCeXRlIG5vIHZcdTAwRTFsaWRvIHswfSBkZSBsYSBzZWN1ZW5jaWEgVVRGLTggZGUgezF9IGJ5dGVzCi0gICAgICAgIEV4cGVjdGVkQnl0ZSA9IEJ5dGUgZXNwZXJhZG8gezB9IGRlIGxhIHNlY3VlbmNpYSBVVEYtOCBkZSB7MX0gYnl0ZXMuICAKLSAgICAgICAgSW52YWxpZEhpZ2hTdXJyb2dhdGUgPSBMb3MgYml0cyBkZSBzdXN0aXR1Y2lcdTAwRjNuIHN1cGVyaW9yIGVuIGxhIHNlY3VlbmNpYSBVVEYtOCBubyBkZWJlbiBleGNlZGVyIDB4MTAgcGVybyBzZSBoYW4gZW5jb250cmFkbyAweHswfS4KLSAgICAgICAgT3BlcmF0aW9uTm90U3VwcG9ydGVkID0gTGEgb3BlcmFjaVx1MDBGM24gInswfSIgbm8gZXN0XHUwMEUxIHNvcG9ydGFkYSBwb3IgZWwgbGVjdG9yIHsxfS4KLSAgICAgICAgSW52YWxpZEFTQ0lJID0gRWwgYnl0ZSAiezB9Im5vIGVzIHVuIG1pZW1icm8gZGVsIGp1ZWdvIGRlIGNhcmFjdGVyZXMgQVNDSUkgKDcgYml0cykuCi0gICAgICAgIENoYXJDb252ZXJzaW9uRmFpbHVyZSA9IFVuYSBlbnRpZGFkIGNvbiB1bmEgY29kaWZpY2FjaVx1MDBGM24gZGV0ZXJtaW5hZGEgbm8gZGViZSBjb250ZW5lciBzZWN1ZW5jaWFzIG5vIHBlcm1pdGlkYXMgZW4gZGljaGEgY29kaWZpY2FjaVx1MDBGM24uCi0gICAgICAgIAotIyBEVEQgTWVzc2FnZXMKLSMgMi4yIENoYXJhY3RlcnMKLSAgICAgICAgSW52YWxpZENoYXJJbkVudGl0eVZhbHVlID0gU2UgaGEgZW5jb250cmFkbyB1biBjYXJcdTAwRTFjdGVyIFhNTCAoVW5pY29kZTogMHh7MH0pIG5vIHZcdTAwRTFsaWRvIGVuIGVsIHZhbG9yIGRlIGVudGlkYWQgbGl0ZXJhbC4KLSAgICAgICAgSW52YWxpZENoYXJJbkV4dGVybmFsU3Vic2V0ID0gU2UgaGEgZW5jb250cmFkbyB1biBjYXJcdTAwRTFjdGVyIFhNTCAoVW5pY29kZTogMHh7MH0pIG5vIHZcdTAwRTFsaWRvIGVuIGVsIHN1Ymp1ZWdvIGV4dGVybm8gZGVsIERURC4KLSAgICAgICAgSW52YWxpZENoYXJJbklnbm9yZVNlY3QgPSBTZSBoYSBlbmNvbnRyYWRvIHVuIGNhclx1MDBFMWN0ZXIgWE1MIChVbmljb2RlOiAweHswfSkgbm8gdlx1MDBFMWxpZG8gZW4gbGEgc2VjY2lcdTAwRjNuIGNvbmRpY2lvbmFsIGV4Y2x1aWRhLgotICAgICAgICBJbnZhbGlkQ2hhckluUHVibGljSUQgPSBTZSBoYSBlbmNvbnRyYWRvIHVuIGNhclx1MDBFMWN0ZXIgWE1MIChVbmljb2RlOiAweHswfSkgbm8gdlx1MDBFMWxpZG8gZW4gZWwgaWRlbnRpZmljYWRvciBwXHUwMEZBYmxpY28uCi0gICAgICAgIEludmFsaWRDaGFySW5TeXN0ZW1JRCA9IFNlIGhhIGVuY29udHJhZG8gdW4gY2FyXHUwMEUxY3RlciBYTUwgKFVuaWNvZGU6IDB4ezB9KSBubyB2XHUwMEUxbGlkbyBlbiBlbCBpZGVudGlmaWNhZG9yIGRlbCBzaXN0ZW1hLgotIyAyLjMgQ29tbW9uIFN5bnRhY3RpYyBDb25zdHJ1Y3RzCi0gICAgICAgIFNwYWNlUmVxdWlyZWRBZnRlclNZU1RFTSA9IEVzIG5lY2VzYXJpbyB1biBlc3BhY2lvIGVuIGJsYW5jbyBkZXNwdVx1MDBFOXMgZGUgbGEgcGFsYWJyYSBjbGF2ZSBTWVNURU0gZW4gbGEgZGVjbGFyYWNpXHUwMEYzbiBET0NUWVBFLgotICAgICAgICBRdW90ZVJlcXVpcmVkSW5TeXN0ZW1JRCA9IEVsIGlkZW50aWZpY2Fkb3IgZGVsIHNpc3RlbWEgZGViZSBlbXBlemFyIHBvciB1biBjYXJcdTAwRTFjdGVyIGRlIGNvbWlsbGFzIGRvYmxlcyBvIHNpbXBsZXMuCi0gICAgICAgIFN5c3RlbUlEVW50ZXJtaW5hdGVkID0gRWwgaWRlbnRpZmljYWRvciBkZWwgc2lzdGVtYSBkZWJlIGZpbmFsaXphciBlbiB1biBjYXJcdTAwRTFjdGVyIGRlIGNvbWlsbGFzIGNvaW5jaWRlbnRlLgotICAgICAgICBTcGFjZVJlcXVpcmVkQWZ0ZXJQVUJMSUMgPSBTb24gbmVjZXNhcmlvcyBlc3BhY2lvcyBlbiBibGFuY28gZGVzcHVcdTAwRTlzIGRlIGxhIHBhbGFicmEgY2xhdmUgUFVCTElDIGVuIGxhIGRlY2xhcmFjaVx1MDBGM24gRE9DVFlQRS4KLSAgICAgICAgUXVvdGVSZXF1aXJlZEluUHVibGljSUQgPSBFbCBpZGVudGlmaWNhZG9yIHBcdTAwRkFibGljbyBkZWJlIGVtcGV6YXIgcG9yIHVuIGNhclx1MDBFMWN0ZXIgZGUgY29taWxsYXMgZG9ibGVzIG8gc2ltcGxlcy4KLSAgICAgICAgUHVibGljSURVbnRlcm1pbmF0ZWQgPSBFbCBpZGVudGlmaWNhZG9yIHBcdTAwRkFibGljbyBkZWJlIGZpbmFsaXphciBlbiB1biBjYXJcdTAwRTFjdGVyIGRlIGNvbWlsbGFzIGNvaW5jaWRlbnRlLgotICAgICAgICBQdWJpZENoYXJJbGxlZ2FsID0gRWwgY2FyXHUwMEUxY3RlciAoVW5pY29kZTogMHh7MH0pIG5vIGVzdFx1MDBFMSBwZXJtaXRpZG8gZW4gZWwgaWRlbnRpZmljYWRvciBwXHUwMEZBYmxpY28uCi0gICAgICAgIFNwYWNlUmVxdWlyZWRCZXR3ZWVuUHVibGljQW5kU3lzdGVtID0gU29uIG5lY2VzYXJpb3MgZXNwYWNpb3MgZW4gYmxhbmNvIGVudHJlIHB1YmxpY0lkIHkgc3lzdGVtSWQuCi0jIDIuOCBQcm9sb2cgYW5kIERvY3VtZW50IFR5cGUgRGVjbGFyYXRpb24KLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9ST09UX0VMRU1FTlRfVFlQRV9JTl9ET0NUWVBFREVDTCA9IEVzIG5lY2VzYXJpbyB1biBlc3BhY2lvIGVuIGJsYW5jbyBkZXNwdVx1MDBFOXMgZGUgIjwhRE9DVFlQRSIgZW4gbGEgZGVjbGFyYWNpXHUwMEYzbiBkZSB0aXBvIGRlIGRvY3VtZW50by4KLSAgICAgICAgTVNHX1JPT1RfRUxFTUVOVF9UWVBFX1JFUVVJUkVEID0gRWwgdGlwbyBkZSBlbGVtZW50byByYVx1MDBFRHogZGViZSBhcGFyZWNlciBkZXNwdVx1MDBFOXMgZGUgIjwhRE9DVFlQRSIgZW4gbGEgZGVjbGFyYWNpXHUwMEYzbiBkZSB0aXBvIGRlIGRvY3VtZW50by4KLSAgICAgICAgRG9jdHlwZWRlY2xVbnRlcm1pbmF0ZWQgPSBMYSBkZWNsYXJhY2lcdTAwRjNuIGRlIHRpcG8gZGUgZG9jdW1lbnRvIHBhcmEgZWwgdGlwbyBkZSBlbGVtZW50byByYVx1MDBFRHogInswfSIgZGViZSBmaW5hbGl6YXIgZW4gJyc+JycuCi0gICAgICAgIERvY3R5cGVkZWNsTm90Q2xvc2VkID0gTGEgZGVjbGFyYWNpXHUwMEYzbiBkZSB0aXBvIGRlIGRvY3VtZW50byBwYXJhIGVsIHRpcG8gZGUgZWxlbWVudG8gcmFcdTAwRUR6ICJ7MH0iIGRlYmUgZmluYWxpemFyIGVuICcnXScnLgotICAgICAgICBQRVJlZmVyZW5jZVdpdGhpbk1hcmt1cCA9IExhIHJlZmVyZW5jaWEgZGUgZW50aWRhZCBkZWwgcGFyXHUwMEUxbWV0cm8gIiV7MH07IiBubyBwdWVkZSBwcm9kdWNpcnNlIGVuIGVsIG1hcmNhZG9yIGVuIGVsIHN1YmNvbmp1bnRvIGludGVybm8gZGVsIERURC4KLSAgICAgICAgTVNHX01BUktVUF9OT1RfUkVDT0dOSVpFRF9JTl9EVEQgPSBMYXMgZGVjbGFyYWNpb25lcyBkZSBtYXJjYWRvciBxdWUgc2UgaW5jbHV5ZW4gbyBhIGxhcyBxdWUgYXB1bnRhIGxhIGRlY2xhcmFjaVx1MDBGM24gZGUgdGlwbyBkZSBkb2N1bWVudG8gZGViZW4gdGVuZXIgZWwgZm9ybWF0byBjb3JyZWN0by4KLSMgMi4xMCBXaGl0ZSBTcGFjZSBIYW5kbGluZwotICAgICAgICBNU0dfWE1MX1NQQUNFX0RFQ0xBUkFUSU9OX0lMTEVHQUwgPSBMYSBkZWNsYXJhY2lcdTAwRjNuIGRlIGF0cmlidXRvIHBhcmEgInhtbDpzcGFjZSIgZGViZSBvZnJlY2Vyc2UgY29tbyB1biB0aXBvIGVudW1lcmFkbyBjdXlvcyBcdTAwRkFuaWNvcyB2YWxvcmVzIHBvc2libGVzIHNvbiAiZGVmYXVsdCIgeSAicHJlc2VydmUiLgotIyAzLjIgRWxlbWVudCBUeXBlIERlY2xhcmF0aW9ucwotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX0VMRU1FTlRfVFlQRV9JTl9FTEVNRU5UREVDTCA9IEVzIG5lY2VzYXJpbyB1biBlc3BhY2lvIGVuIGJsYW5jbyBkZXNwdVx1MDBFOXMgZGUgIjwhRUxFTUVOVCIgZW4gbGEgZGVjbGFyYWNpXHUwMEYzbiBkZSB0aXBvIGRlIGVsZW1lbnRvLgotICAgICAgICBNU0dfRUxFTUVOVF9UWVBFX1JFUVVJUkVEX0lOX0VMRU1FTlRERUNMID0gRWwgdGlwbyBkZSBlbGVtZW50byBlcyBuZWNlc2FyaW8gZW4gbGEgZGVjbGFyYWNpXHUwMEYzbiBkZSB0aXBvIGRlIGVsZW1lbnRvLgotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX0NPTlRFTlRTUEVDX0lOX0VMRU1FTlRERUNMID0gRXMgbmVjZXNhcmlvIHVuIGVzcGFjaW8gZW4gYmxhbmNvIGRlc3B1XHUwMEU5cyBkZWwgdGlwbyBkZSBlbGVtZW50byAiezB9IiBlbiBsYSBkZWNsYXJhY2lcdTAwRjNuIGRlIHRpcG8gZGUgZWxlbWVudG8uCi0gICAgICAgIE1TR19DT05URU5UU1BFQ19SRVFVSVJFRF9JTl9FTEVNRU5UREVDTCA9IEVzIG5lY2VzYXJpYSBsYSByZXN0cmljY2lcdTAwRjNuIGRlc3B1XHUwMEU5cyBkZWwgdGlwbyBkZSBlbGVtZW50byAiezB9IiBlbiBsYSBkZWNsYXJhY2lcdTAwRjNuIGRlIHRpcG8gZGUgZWxlbWVudG8uCi0gICAgICAgIEVsZW1lbnREZWNsVW50ZXJtaW5hdGVkID0gTGEgZGVjbGFyYWNpXHUwMEYzbiBwYXJhIGVsIHRpcG8gZGUgZWxlbWVudG8gInswfSIgZGViZSBmaW5hbGl6YXIgZW4gJyc+JycuCi0jIDMuMi4xIEVsZW1lbnQgQ29udGVudAotICAgICAgICBNU0dfT1BFTl9QQVJFTl9PUl9FTEVNRU5UX1RZUEVfUkVRVUlSRURfSU5fQ0hJTERSRU4gPSBVbiBjYXJcdTAwRTFjdGVyICcnKCcnIG8gdW4gdGlwbyBkZSBlbGVtZW50byBlcyBuZWNlc2FyaW8gZW4gbGEgZGVjbGFyYWNpXHUwMEYzbiBkZSB0aXBvIGRlIGVsZW1lbnRvICJ7MH0iLgotICAgICAgICBNU0dfQ0xPU0VfUEFSRU5fUkVRVUlSRURfSU5fQ0hJTERSRU4gPSBVbiBjYXJcdTAwRTFjdGVyICcnKScnIGVzIG5lY2VzYXJpbyBlbiBsYSBkZWNsYXJhY2lcdTAwRjNuIGRlIHRpcG8gZGUgZWxlbWVudG8gInswfSIuCi0jIDMuMi4yIE1peGVkIENvbnRlbnQKLSAgICAgICAgTVNHX0VMRU1FTlRfVFlQRV9SRVFVSVJFRF9JTl9NSVhFRF9DT05URU5UID0gVW4gdGlwbyBkZSBlbGVtZW50byBlcyBuZWNlc2FyaW8gZW4gbGEgZGVjbGFyYWNpXHUwMEYzbiBkZSB0aXBvIGRlIGVsZW1lbnRvICJ7MH0iLgotICAgICAgICBNU0dfQ0xPU0VfUEFSRU5fUkVRVUlSRURfSU5fTUlYRUQgPSBVbiBjYXJcdTAwRTFjdGVyICcnKScnIGVzIG5lY2VzYXJpbyBlbiBsYSBkZWNsYXJhY2lcdTAwRjNuIGRlIHRpcG8gZGUgZWxlbWVudG8gInswfSIuCi0gICAgICAgIE1peGVkQ29udGVudFVudGVybWluYXRlZCA9IEVsIG1vZGVsbyBkZSBjb250ZW5pZG8gbWl4dG8gInswfSIgZGViZSBmaW5hbGl6YXIgZW4gIikqIiBjdWFuZG8gbG9zIHRpcG9zIGRlIGVsZW1lbnRvcyBzZWN1bmRhcmlvcyBlc3RcdTAwRTFuIHJlc3RyaW5naWRvcy4KLSMgMy4zIEF0dHJpYnV0ZS1MaXN0IERlY2xhcmF0aW9ucwotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX0VMRU1FTlRfVFlQRV9JTl9BVFRMSVNUREVDTCA9IEVzIG5lY2VzYXJpbyB1biBlc3BhY2lvIGVuIGJsYW5jbyBkZXNwdVx1MDBFOXMgZGUgIjwhQVRUTElTVCIgZW4gbGEgZGVjbGFyYWNpXHUwMEYzbiBkZSBsYSBsaXN0YSBkZSBhdHJpYnV0b3MuCi0gICAgICAgIE1TR19FTEVNRU5UX1RZUEVfUkVRVUlSRURfSU5fQVRUTElTVERFQ0wgPSBFbCB0aXBvIGRlIGVsZW1lbnRvIGVzIG5lY2VzYXJpbyBlbiBsYSBkZWNsYXJhY2lcdTAwRjNuIGRlIGxhIGxpc3RhIGRlIGF0cmlidXRvcy4KLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9BVFRSSUJVVEVfTkFNRV9JTl9BVFRERUYgPSBFcyBuZWNlc2FyaW8gdW4gZXNwYWNpbyBlbiBibGFuY28gYW50ZXMgZGVsIG5vbWJyZSBkZSBhdHJpYnV0byBlbiBsYSBkZWNsYXJhY2lcdTAwRjNuIGRlIGxhIGxpc3RhIGRlIGF0cmlidXRvcyBwYXJhIGVsIGVsZW1lbnRvICJ7MH0iLgotICAgICAgICBBdHROYW1lUmVxdWlyZWRJbkF0dERlZiA9IFNlIGRlYmUgZXNwZWNpZmljYXIgZWwgbm9tYnJlIGRlbCBhdHJpYnV0byBlbiBsYSBkZWNsYXJhY2lcdTAwRjNuIGRlIGxhIGxpc3RhIGRlIGF0cmlidXRvcyBwYXJhIGVsIGVsZW1lbnRvICJ7MH0iLgotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX0FUVFRZUEVfSU5fQVRUREVGID0gRXMgbmVjZXNhcmlvIHVuIGVzcGFjaW8gZW4gYmxhbmNvIGFudGVzIGRlbCB0aXBvIGRlIGF0cmlidXRvIGVuIGxhIGRlY2xhcmFjaVx1MDBGM24gZGVsIGF0cmlidXRvICJ7MX0iIHBhcmEgZWwgZWxlbWVudG8gInswfSIuCi0gICAgICAgIEF0dFR5cGVSZXF1aXJlZEluQXR0RGVmID0gRXMgbmVjZXNhcmlvIGVsIHRpcG8gZGUgYXRyaWJ1dG8gZW4gbGEgZGVjbGFyYWNpXHUwMEYzbiBkZWwgYXRyaWJ1dG8gInsxfSIgcGFyYSBlbCBlbGVtZW50byAiezB9Ii4KLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9ERUZBVUxUREVDTF9JTl9BVFRERUYgPSBFcyBuZWNlc2FyaW8gdW4gZXNwYWNpbyBlbiBibGFuY28gYW50ZXMgZGVsIGF0cmlidXRvIHBvciBkZWZlY3RvIGVuIGxhIGRlY2xhcmFjaVx1MDBGM24gZGVsIGF0cmlidXRvICJ7MX0iIHBhcmEgZWwgZWxlbWVudG8gInswfSIuCi0gICAgICAgIE1TR19EVVBMSUNBVEVfQVRUUklCVVRFX0RFRklOSVRJT04gPSBTZSBoYSBwcm9wb3JjaW9uYWRvIG1cdTAwRTFzIGRlIHVuYSBkZWZpbmljaVx1MDBGM24gZGUgYXRyaWJ1dG8gcGFyYSBlbCBtaXNtbyBhdHJpYnV0byAiezF9IiBkZSB1biBlbGVtZW50byBkZXRlcm1pbmFkbyAiezB9Ii4KLSMgMy4zLjEgQXR0cmlidXRlIFR5cGVzCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9BRlRFUl9OT1RBVElPTl9JTl9OT1RBVElPTlRZUEUgPSBEZWJlIGFwYXJlY2VyIHVuIGVzcGFjaW8gZW4gYmxhbmNvIGRlc3B1XHUwMEU5cyBkZSAiTk9UQVRJT04iIGVuIGxhIGRlY2xhcmFjaVx1MDBGM24gZGUgYXRyaWJ1dG8gInsxfSIuCi0gICAgICAgIE1TR19PUEVOX1BBUkVOX1JFUVVJUkVEX0lOX05PVEFUSU9OVFlQRSA9IEVsIGNhclx1MDBFMWN0ZXIgJycoJycgZGViZSBhcGFyZWNlciBkZXNwdVx1MDBFOXMgZGUgIk5PVEFUSU9OIiBlbiBsYSBkZWNsYXJhY2lcdTAwRjNuIGRlIGF0cmlidXRvICJ7MX0iLgotICAgICAgICBNU0dfTkFNRV9SRVFVSVJFRF9JTl9OT1RBVElPTlRZUEUgPSBFbCBub21icmUgZGUgbm90YWNpXHUwMEYzbiBlcyBuZWNlc2FyaW8gZW4gbGEgbGlzdGEgZGUgdGlwb3MgZGUgbm90YWNpXHUwMEYzbiBwYXJhIGxhIGRlY2xhcmFjaVx1MDBGM24gZGUgYXRyaWJ1dG8gInsxfSIuCi0gICAgICAgIE5vdGF0aW9uVHlwZVVudGVybWluYXRlZCA9IExhIGxpc3RhIGRlIHRpcG9zIGRlIG5vdGFjaW9uZXMgZGViZSBmaW5hbGl6YXIgZW4gJycpJycgZW4gbGEgZGVjbGFyYWNpXHUwMEYzbiBkZWwgYXRyaWJ1dG8gInsxfSIuCi0gICAgICAgIE1TR19OTVRPS0VOX1JFUVVJUkVEX0lOX0VOVU1FUkFUSU9OID0gRWwgdG9rZW4gZGUgbm9tYnJlIGVzIG5lY2VzYXJpbyBlbiBsYSBsaXN0YSBkZSB0aXBvcyBlbnVtZXJhZG9zIHBhcmEgbGEgZGVjbGFyYWNpXHUwMEYzbiBkZWwgYXRyaWJ1dG8gInsxfSIuCi0gICAgICAgIEVudW1lcmF0aW9uVW50ZXJtaW5hdGVkID0gTGEgbGlzdGEgZGUgdGlwb3MgZW51bWVyYWRvcyBkZWJlIGZpbmFsaXphciBlbiAnJyknJyBlbiBsYSBkZWNsYXJhY2lcdTAwRjNuIGRlbCBhdHJpYnV0byAiezF9Ii4KLSAgICAgICAgTVNHX0RJU1RJTkNUX1RPS0VOU19JTl9FTlVNRVJBVElPTiA9IEVsIHZhbG9yIGRlIGVudW1lcmFjaVx1MDBGM24gInsxfSIgc2UgZXNwZWNpZmljXHUwMEYzIG1cdTAwRTFzIGRlIHVuYSB2ZXogZW4gbGEgZGVjbGFyYWNpXHUwMEYzbiBkZWwgYXRyaWJ1dG8gInsyfSIgcGFyYSBlbCB0b2tlbiAiezB9Ii4gVG9kb3MgbG9zIE5NVE9LRU5TIGVuIHVuYSBkZWNsYXJhY2lcdTAwRjNuIGRlbCBhdHJpYnV0byBFbnVtZXJhdGlvbiBcdTAwRkFuaWNvIGRlYmVuIHNlciBkaXN0aW50b3MuCi0gICAgICAgIE1TR19ESVNUSU5DVF9OT1RBVElPTl9JTl9FTlVNRVJBVElPTiA9IEVsIHZhbG9yIGRlIGVudW1lcmFjaVx1MDBGM24gInsxfSIgc2UgZXNwZWNpZmljXHUwMEYzIG1cdTAwRTFzIGRlIHVuYSB2ZXogZW4gbGEgZGVjbGFyYWNpXHUwMEYzbiBkZWwgYXRyaWJ1dG8gInsyfSIgcGFyYSBlbCBlbGVtZW50byAiezB9Ii4gVG9kb3MgbG9zIG5vbWJyZXMgTk9UQVRJT04gZW4gdW5hIGRlY2xhcmFjaVx1MDBGM24gZGVsIGF0cmlidXRvIE5vdGF0aW9uVHlwZSBcdTAwRkFuaWNvIGRlYmVuIHNlciBkaXN0aW50b3MuCi0jIDMuMy4yIEF0dHJpYnV0ZSBEZWZhdWx0cwotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQUZURVJfRklYRURfSU5fREVGQVVMVERFQ0wgPSBEZWJlIGFwYXJlY2VyIHVuIGVzcGFjaW8gZW4gYmxhbmNvIGRlc3B1XHUwMEU5cyBkZSAiRklYRUQiIGVuIGxhIGRlY2xhcmFjaVx1MDBGM24gZGUgYXRyaWJ1dG8gInsxfSIuCi0jIDMuNCBDb25kaXRpb25hbCBTZWN0aW9ucwotICAgICAgICBJbmNsdWRlU2VjdFVudGVybWluYXRlZCA9IExhIHNlY2NpXHUwMEYzbiBjb25kaWNpb25hbCBpbmNsdWlkYSBkZWJlIGZpbmFsaXphciBlbiAiXV0+Ii4KLSAgICAgICAgSWdub3JlU2VjdFVudGVybWluYXRlZCA9IExhIHNlY2NpXHUwMEYzbiBjb25kaWNpb25hbCBleGNsdWlkYSBkZWJlIGZpbmFsaXphciBlbiAiXV0+Ii4KLSMgNC4xIENoYXJhY3RlciBhbmQgRW50aXR5IFJlZmVyZW5jZXMKLSAgICAgICAgTmFtZVJlcXVpcmVkSW5QRVJlZmVyZW5jZSA9IEVsIG5vbWJyZSBkZSBsYSBlbnRpZGFkIGRlYmUgYXBhcmVjZXIgaW5tZWRpYXRhbWVudGUgZGVzcHVcdTAwRTlzIGRlICclJyBlbiBsYSByZWZlcmVuY2lhIGRlIGVudGlkYWQgZGUgcGFyXHUwMEUxbWV0cm8uCi0gICAgICAgIFNlbWljb2xvblJlcXVpcmVkSW5QRVJlZmVyZW5jZSA9IExhIHJlZmVyZW5jaWEgZGUgZW50aWRhZCBkZSBwYXJcdTAwRTFtZXRybyAiJXswfTsiIGRlYmUgZmluYWxpemFyIGVuIGVsIGRlbGltaXRhZG9yICcnOycnLgotIyA0LjIgRW50aXR5IERlY2xhcmF0aW9ucwotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX0VOVElUWV9OQU1FX0lOX0VOVElUWURFQ0wgPSBFcyBuZWNlc2FyaW8gdW4gZXNwYWNpbyBlbiBibGFuY28gZGVzcHVcdTAwRTlzIGRlICI8IUVOVElUWSIgZW4gbGEgZGVjbGFyYWNpXHUwMEYzbiBkZSBlbnRpZGFkLgotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX1BFUkNFTlRfSU5fUEVERUNMID0gRXMgbmVjZXNhcmlvIHVuIGVzcGFjaW8gZW4gYmxhbmNvIGVudHJlICI8IUVOVElUWSIgeSBlbCBjYXJcdTAwRTFjdGVyICclJyBlbiBsYSBkZWNsYXJhY2lcdTAwRjNuIGRlIGVudGlkYWQgZGUgcGFyXHUwMEUxbWV0cm8uCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfRU5USVRZX05BTUVfSU5fUEVERUNMID0gRXMgbmVjZXNhcmlvIHVuIGVzcGFjaW8gZW4gYmxhbmNvIGVudHJlICclJyB5IGVsIG5vbWJyZSBkZSBlbnRpZGFkIGVuIGxhIGRlY2xhcmFjaVx1MDBGM24gZGUgZW50aWRhZCBkZSBwYXJcdTAwRTFtZXRyby4KLSAgICAgICAgTVNHX0VOVElUWV9OQU1FX1JFUVVJUkVEX0lOX0VOVElUWURFQ0wgPSBFbCBub21icmUgZGUgbGEgZW50aWRhZCBlcyBuZWNlc2FyaW8gZW4gbGEgZGVjbGFyYWNpXHUwMEYzbiBkZSBlbnRpZGFkLgotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQUZURVJfRU5USVRZX05BTUVfSU5fRU5USVRZREVDTCA9IEVzIG5lY2VzYXJpbyB1biBlc3BhY2lvIGVuIGJsYW5jbyBlbnRyZSBlbCBub21icmUgZGUgZW50aWRhZCAiezB9IiB5IGxhIGRlZmluaWNpXHUwMEYzbiBlbiBsYSBkZWNsYXJhY2lcdTAwRjNuIGRlIGVudGlkYWQuCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfTk9UQVRJT05fTkFNRV9JTl9VTlBBUlNFRF9FTlRJVFlERUNMID0gRXMgbmVjZXNhcmlvIHVuIGVzcGFjaW8gZW4gYmxhbmNvIGVudHJlICJOREFUQSIgeSBlbCBub21icmUgZGUgbm90YWNpXHUwMEYzbiBlbiBsYSBkZWNsYXJhY2lcdTAwRjNuIHBhcmEgbGEgZW50aWRhZCAiezB9Ii4KLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9OREFUQV9JTl9VTlBBUlNFRF9FTlRJVFlERUNMID0gRXMgbmVjZXNhcmlvIHVuIGVzcGFjaW8gZW4gYmxhbmNvIGFudGVzIGRlICJOREFUQSIgZW4gbGEgZGVjbGFyYWNpXHUwMEYzbiBwYXJhIGxhIGVudGlkYWQgInswfSIuCi0gICAgICAgIE1TR19OT1RBVElPTl9OQU1FX1JFUVVJUkVEX0ZPUl9VTlBBUlNFRF9FTlRJVFlERUNMID0gRWwgbm9tYnJlIGRlIG5vdGFjaVx1MDBGM24gZXMgbmVjZXNhcmlvIGRlc3B1XHUwMEU5cyBkZSAiTkRBVEEiIGVuIGxhIGRlY2xhcmFjaVx1MDBGM24gcGFyYSBsYSBlbnRpZGFkICJ7MH0iLgotICAgICAgICBFbnRpdHlEZWNsVW50ZXJtaW5hdGVkID0gTGEgZGVjbGFyYWNpXHUwMEYzbiBwYXJhIGxhIGVudGlkYWQgInswfSIgZGViZSBmaW5hbGl6YXIgZW4gJyc+JycuCi0JTVNHX0RVUExJQ0FURV9FTlRJVFlfREVGSU5JVElPTiA9IExhIGVudGlkYWQgInswfSIgc2UgaGEgZGVjbGFyYWRvIG1cdTAwRTFzIGRlIHVuYSB2ZXouICAgICAgICAKLSMgNC4yLjIgRXh0ZXJuYWwgRW50aXRpZXMKLSAgICAgICAgRXh0ZXJuYWxJRFJlcXVpcmVkID0gTGEgZGVjbGFyYWNpXHUwMEYzbiBkZSBlbnRpZGFkIGV4dGVybmEgZGViZSBlbXBlemFyIHBvciAiU1lTVEVNIiBvICJQVUJMSUMiLgotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX1BVQklETElURVJBTF9JTl9FWFRFUk5BTElEID0gRXMgbmVjZXNhcmlvIHVuIGVzcGFjaW8gZW4gYmxhbmNvIGVudHJlICJQVUJMSUMiIHkgZWwgaWRlbnRpZmljYWRvciBwXHUwMEZBYmxpY28uCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9BRlRFUl9QVUJJRExJVEVSQUxfSU5fRVhURVJOQUxJRCA9IEVzIG5lY2VzYXJpbyB1biBlc3BhY2lvIGVuIGJsYW5jbyBlbnRyZSBlbCBpZGVudGlmaWNhZG9yIHBcdTAwRkFibGljbyB5IGVsIGlkZW50aWZpY2Fkb3IgZGVsIHNpc3RlbWEuCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfU1lTVEVNTElURVJBTF9JTl9FWFRFUk5BTElEID0gRXMgbmVjZXNhcmlvIHVuIGVzcGFjaW8gZW4gYmxhbmNvIGVudHJlICJTWVNURU0iIHkgZWwgaWRlbnRpZmljYWRvciBkZWwgc2lzdGVtYS4KLSAgICAgICAgTVNHX1VSSV9GUkFHTUVOVF9JTl9TWVNURU1JRCA9IE5vIHNlIGRlYmUgZXNwZWNpZmljYXIgZWwgaWRlbnRpZmljYWRvciBkZWwgZnJhZ21lbnRvIGNvbW8gcGFydGUgZGVsIGlkZW50aWZpY2Fkb3IgZGVsIHNpc3RlbWEgInswfSIuCi0jIDQuNyBOb3RhdGlvbiBEZWNsYXJhdGlvbnMKLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9OT1RBVElPTl9OQU1FX0lOX05PVEFUSU9OREVDTCA9IEVzIG5lY2VzYXJpbyB1biBlc3BhY2lvIGVuIGJsYW5jbyBkZXNwdVx1MDBFOXMgZGUgIjwhTk9UQVRJT04iIGVuIGxhIGRlY2xhcmFjaVx1MDBGM24gZGUgbm90YWNpXHUwMEYzbi4KLSAgICAgICAgTVNHX05PVEFUSU9OX05BTUVfUkVRVUlSRURfSU5fTk9UQVRJT05ERUNMID0gRWwgbm9tYnJlIGRlIGxhIG5vdGFjaVx1MDBGM24gZXMgbmVjZXNhcmlvIGVuIGxhIGRlY2xhcmFjaVx1MDBGM24gZGUgbm90YWNpXHUwMEYzbi4KLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0FGVEVSX05PVEFUSU9OX05BTUVfSU5fTk9UQVRJT05ERUNMID0gRXMgbmVjZXNhcmlvIHVuIGVzcGFjaW8gZW4gYmxhbmNvIGRlc3B1XHUwMEU5cyBkZWwgbm9tYnJlIGRlIGxhIG5vdGFjaVx1MDBGM24gInswfSIgZW4gbGEgZGVjbGFyYWNpXHUwMEYzbiBkZSBub3RhY2lcdTAwRjNuLgotICAgICAgICBFeHRlcm5hbElEb3JQdWJsaWNJRFJlcXVpcmVkID0gTGEgZGVjbGFyYWNpXHUwMEYzbiBwYXJhIGxhIG5vdGFjaVx1MDBGM24gInswfSIgZGViZSBpbmNsdWlyIHVuIGlkZW50aWZpY2Fkb3IgcFx1MDBGQWJsaWNvIG8gZGVsIHNpc3RlbWEuCi0gICAgICAgIE5vdGF0aW9uRGVjbFVudGVybWluYXRlZCA9IExhIGRlY2xhcmFjaVx1MDBGM24gcGFyYSBsYSBub3RhY2lcdTAwRjNuICJ7MH0iIGRlYmUgZmluYWxpemFyIGVuICcnPicnLgotICAgICAgICAKLSMgVmFsaWRhdGlvbiBtZXNzYWdlcwotICAgICAgICBEdXBsaWNhdGVUeXBlSW5NaXhlZENvbnRlbnQgPSBFbCB0aXBvIGRlIGVsZW1lbnRvICJ7MX0iIHlhIHNlIGVzcGVjaWZpY1x1MDBGMyBlbiBlbCBtb2RlbG8gZGUgY29udGVuaWRvIGRlIGxhIGRlY2xhcmFjaVx1MDBGM24gZGUgZWxlbWVudG9zICJ7MH0iLgotICAgICAgICBFTlRJVElFU0ludmFsaWQgPSBFbCB2YWxvciBkZSBhdHJpYnV0byAiezF9IiBkZWwgdGlwbyBFTlRJVElFUyBkZWJlIHNlciBlbCBub21icmUgZGUgdW5hIG8gbVx1MDBFMXMgZW50aWRhZGVzIG5vIGFuYWxpemFkYXMuCi0gICAgICAgIEVOVElUWUludmFsaWQgPSBFbCB2YWxvciBkZSBhdHJpYnV0byAiezF9IiBkZWwgdGlwbyBFTlRJVFkgZGViZSBzZXIgZWwgbm9tYnJlIGRlIHVuYSBlbnRpZGFkIG5vIGFuYWxpemFkYS4KLSAgICAgICAgSUREZWZhdWx0VHlwZUludmFsaWQgPSBFbCBhdHJpYnV0byBkZSBpZGVudGlmaWNhZG9yICJ7MH0iIGRlYmUgdGVuZXIgdW4gdmFsb3IgcG9yIGRlZmVjdG8gZGVjbGFyYWRvIGRlICIjSU1QTElFRCIgbyAiI1JFUVVJUkVEIi4KLSAgICAgICAgSURJbnZhbGlkID0gRWwgdmFsb3IgZGUgYXRyaWJ1dG8gInswfSIgZGVsIHRpcG8gSUQgZGViZSBzZXIgdW4gbm9tYnJlLgotICAgICAgICBJREludmFsaWRXaXRoTmFtZXNwYWNlcyA9IEVsIHZhbG9yIGRlIGF0cmlidXRvICJ7MH0iIGRlbCB0aXBvIElEIGRlYmUgc2VyIHVuIE5DTmFtZSBjdWFuZG8gbG9zIGVzcGFjaW9zIGRlIG5vbWJyZXMgZXN0XHUwMEU5biBhY3RpdmFkb3MuCi0gICAgICAgIElETm90VW5pcXVlID0gRWwgdmFsb3IgZGUgYXRyaWJ1dG8gInswfSIgZGVsIHRpcG8gSUQgZGViZSBzZXIgXHUwMEZBbmljbyBlbiBlbCBkb2N1bWVudG8uCi0gICAgICAgIElEUkVGSW52YWxpZCA9IEVsIHZhbG9yIGRlIGF0cmlidXRvICJ7MH0iIGRlbCB0aXBvIElEUkVGIGRlYmUgc2VyIHVuIG5vbWJyZS4KLSAgICAgICAgSURSRUZJbnZhbGlkV2l0aE5hbWVzcGFjZXMgPSBFbCB2YWxvciBkZSBhdHJpYnV0byAiezB9IiBkZWwgdGlwbyBJRFJFRiBkZWJlIHNlciB1biBOQ05hbWUgY3VhbmRvIGxvcyBlc3BhY2lvcyBkZSBub21icmVzIGVzdFx1MDBFOW4gYWN0aXZhZG9zLgotICAgICAgICBJRFJFRlNJbnZhbGlkID0gRWwgdmFsb3IgZGUgYXRyaWJ1dG8gInswfSIgZGVsIHRpcG8gSURSRUZTIGRlYmUgc2VyIHVubyBvIG1cdTAwRTFzIG5vbWJyZXMuCi0gICAgICAgIElMTF9GT1JNRURfUEFSQU1FVEVSX0VOVElUWV9XSEVOX1VTRURfSU5fREVDTCA9IEVsIHRleHRvIGRlIHN1c3RpdHVjaVx1MDBGM24gZGUgbGEgZW50aWRhZCBkZWwgcGFyXHUwMEUxbWV0cm8gInswfSIgZGViZSBpbmNsdWlyIGRlY2xhcmFjaW9uZXMgY29ycmVjdGFtZW50ZSBhbmlkYWRhcyBjdWFuZG8gbGEgcmVmZXJlbmNpYSBkZSBlbnRpZGFkIHNlIHV0aWxpemEgY29tbyB1bmEgZGVjbGFyYWNpXHUwMEYzbiBjb21wbGV0YS4KLSAgICAgICAgSW1wcm9wZXJEZWNsYXJhdGlvbk5lc3RpbmcgPSBFbCB0ZXh0byBkZSBzdXN0aXR1Y2lcdTAwRjNuIGRlIGxhIGVudGlkYWQgZGVsIHBhclx1MDBFMW1ldHJvICJ7MH0iIGRlYmUgaW5jbHVpciBkZWNsYXJhY2lvbmVzIGNvcnJlY3RhbWVudGUgYW5pZGFkYXMuCi0gICAgICAgIEltcHJvcGVyR3JvdXBOZXN0aW5nID0gRWwgdGV4dG8gZGUgc3VzdGl0dWNpXHUwMEYzbiBkZSBsYSBlbnRpZGFkIGRlbCBwYXJcdTAwRTFtZXRybyAiezB9IiBkZWJlIGluY2x1aXIgcGFyZXMgZGUgcGFyXHUwMEU5bnRlc2lzIGNvcnJlY3RhbWVudGUgYW5pZGFkb3MuCi0gICAgICAgIElOVkFMSURfUEVfSU5fQ09ORElUSU9OQUwgPSBFbCB0ZXh0byBkZSBzdXN0aXR1Y2lcdTAwRjNuIGRlIGxhIGVudGlkYWQgZGVsIHBhclx1MDBFMW1ldHJvICJ7MH0iIGRlYmUgaW5jbHVpciBsYSBzZWNjaVx1MDBGM24gY29uZGljaW9uYWwgY29tcGxldGEgbyBzXHUwMEYzbG8gSU5DTFVERSBvIElHTk9SRS4KLSAgICAgICAgTVNHX0FUVFJJQlVURV9OT1RfREVDTEFSRUQgPSBFbCBhdHJpYnV0byAiezF9IiBzZSBkZWJlIGhhYmVyIGRlY2xhcmFkbyBwYXJhIGVsIHRpcG8gZGUgZWxlbWVudG8gInswfSIuCi0gICAgICAgIE1TR19BVFRSSUJVVEVfVkFMVUVfTk9UX0lOX0xJU1QgPSBFbCBhdHJpYnV0byAiezB9IiBjb24gZWwgdmFsb3IgInsxfSIgZGViZSB0ZW5lciB1biB2YWxvciBkZSBsYSBsaXN0YSAiezJ9Ii4KLSAgICAgICAgTVNHX0FUVFZBTFVFX0NIQU5HRURfRFVSSU5HX05PUk1BTElaQVRJT05fV0hFTl9TVEFOREFMT05FID0gRWwgdmFsb3IgInsxfSIgZGVsIGF0cmlidXRvICJ7MH0iIG5vIHNlIGRlYmUgY2FtYmlhciBtZWRpYW50ZSBsYSBub3JtYWxpemFjaVx1MDBGM24gKGEgInsyfSIpIGVuIHVuIGRvY3VtZW50byBhdXRcdTAwRjNub21vLgotICAgICAgICBNU0dfQ09OVEVOVF9JTkNPTVBMRVRFID0gRWwgY29udGVuaWRvIGRlbCB0aXBvIGRlIGVsZW1lbnRvICJ7MH0iIGVzIGluY29tcGxldG8sIGRlYmUgY29pbmNpZGlyIGNvbiAiezF9Ii4KLSAgICAgICAgTVNHX0NPTlRFTlRfSU5WQUxJRCA9IEVsIGNvbnRlbmlkbyBkZWwgdGlwbyBkZSBlbGVtZW50byAiezB9IiBkZWJlIGNvaW5jaWRpciBjb24gInsxfSIuCi0gICAgICAgIE1TR19DT05URU5UX0lOVkFMSURfU1BFQ0lGSUVEID0gRWwgY29udGVuaWRvIGRlbCB0aXBvIGRlIGVsZW1lbnRvICJ7MH0iIGRlYmUgY29pbmNpZGlyIGNvbiAiezF9Ii4gTG9zIHNlY3VuZGFyaW9zIGRlbCB0aXBvICJ7Mn0iIG5vIGVzdFx1MDBFMW4gcGVybWl0aWRvcy4KLSAgICAgICAgTVNHX0RFRkFVTFRFRF9BVFRSSUJVVEVfTk9UX1NQRUNJRklFRCA9IEVsIGF0cmlidXRvICJ7MX0iIHBhcmEgZWwgdGlwbyBkZSBlbGVtZW50byAiezB9IiB0aWVuZSB1biB2YWxvciBwb3IgZGVmZWN0byB5IGRlYmUgZXNwZWNpZmljYXJzZSBlbiB1biBkb2N1bWVudG8gYXV0XHUwMEYzbm9tby4KLSAgICAgICAgTVNHX0RVUExJQ0FURV9BVFRERUYgPSBFbCBhdHJpYnV0byAiezF9IiB5YSBzZSBoYSBkZWNsYXJhZG8gcGFyYSBlbCB0aXBvIGRlIGVsZW1lbnRvICJ7MH0iLgotICAgICAgICBNU0dfRUxFTUVOVF9BTFJFQURZX0RFQ0xBUkVEID0gRWwgdGlwbyBkZSBlbGVtZW50byAiezB9IiBubyBkZWJlIGRlY2xhcmFyc2UgbVx1MDBFMXMgZGUgdW5hIHZlei4KLSAgICAgICAgTVNHX0VMRU1FTlRfTk9UX0RFQ0xBUkVEID0gRWwgdGlwbyBkZSBlbGVtZW50byAiezB9IiBkZWJlIGRlY2xhcmFyc2UuCi0gICAgICAgIE1TR19HUkFNTUFSX05PVF9GT1VORCA9IEVsIGRvY3VtZW50byBubyBlcyB2XHUwMEUxbGlkbzogbm8gc2UgaGEgZW5jb250cmFkbyBsYSBncmFtXHUwMEUxdGljYS4KLSAgICAgICAgTVNHX0VMRU1FTlRfV0lUSF9JRF9SRVFVSVJFRCA9IFVuIGVsZW1lbnRvIGNvbiBlbCBpZGVudGlmaWNhZG9yICJ7MH0iIGRlYmUgYXBhcmVjZXIgZW4gZWwgZG9jdW1lbnRvLgotICAgICAgICBNU0dfRVhURVJOQUxfRU5USVRZX05PVF9QRVJNSVRURUQgPSBMYSByZWZlcmVuY2lhIGEgbGEgZW50aWRhZCBleHRlcm5hICJ7MH0iIG5vIGVzdFx1MDBFMSBwZXJtaXRpZGEgZW4gdW4gZG9jdW1lbnRvIGF1dFx1MDBGM25vbW8uCi0gICAgICAgIE1TR19GSVhFRF9BVFRWQUxVRV9JTlZBTElEID0gRWwgYXRyaWJ1dG8gInsxfSIgY29uIGVsIHZhbG9yICJ7Mn0iIGRlYmUgdGVuZXIgdW4gdmFsb3IgZGUgInszfSIuCi0gICAgICAgIE1TR19NT1JFX1RIQU5fT05FX0lEX0FUVFJJQlVURSA9IEVsIHRpcG8gZGUgZWxlbWVudG8gInswfSIgeWEgdGllbmUgdW4gYXRyaWJ1dG8gInsxfSIgZGVsIHRpcG8gSUQsIHVuIHNlZ3VuZG8gYXRyaWJ1dG8gInsyfSIgZGVsIHRpcG8gSUQgbm8gZXN0XHUwMEUxIHBlcm1pdGlkby4KLSAgICAgICAgTVNHX01PUkVfVEhBTl9PTkVfTk9UQVRJT05fQVRUUklCVVRFID0gRWwgdGlwbyBkZSBlbGVtZW50byAiezB9IiB5YSB0aWVuZSB1biBhdHJpYnV0byAiezF9IiBkZWwgdGlwbyBOT1RBVElPTiwgdW4gc2VndW5kbyBhdHJpYnV0byAiezJ9IiBkZWwgdGlwbyBOT1RBVElPTiBubyBlc3RcdTAwRTEgcGVybWl0aWRvLgotICAgICAgICBNU0dfTk9UQVRJT05fTk9UX0RFQ0xBUkVEX0ZPUl9OT1RBVElPTlRZUEVfQVRUUklCVVRFID0gTGEgbm90YWNpXHUwMEYzbiAiezF9IiBkZWJlIGRlY2xhcmFyc2UgY3VhbmRvIHNlIGhhY2UgcmVmZXJlbmNpYSBhIGxhIG1pc21hIGVuIGxhIGxpc3RhIGRlIHRpcG9zIGRlIG5vdGFjaVx1MDBGM24gcGFyYSBlbCBhdHJpYnV0byAiezB9Ii4KLSAgICAgICAgTVNHX05PVEFUSU9OX05PVF9ERUNMQVJFRF9GT1JfVU5QQVJTRURfRU5USVRZREVDTCA9IExhIG5vdGFjaVx1MDBGM24gInsxfSIgZGViZSBkZWNsYXJhcnNlIGN1YW5kbyBzZSBoYWNlIHJlZmVyZW5jaWEgYSBsYSBtaXNtYSBlbiBsYSBkZWNsYXJhY2lcdTAwRjNuIGRlIGVudGlkYWQgbm8gYW5hbGl6YWRhIHBhcmEgInswfSIuCi0gICAgICAgIE1TR19SRUZFUkVOQ0VfVE9fRVhURVJOQUxMWV9ERUNMQVJFRF9FTlRJVFlfV0hFTl9TVEFOREFMT05FID0gTGEgcmVmZXJlbmNpYSBhIGxhIGVudGlkYWQgInswfSIgZGVjbGFyYWRhIGVuIHVuYSBlbnRpZGFkIGFuYWxpemFkYSBleHRlcm5hIG5vIGVzdFx1MDBFMSBwZXJtaXRpZGEgZW4gdW4gZG9jdW1lbnRvIGF1dFx1MDBGM25vbW8uCi0gICAgICAgIE1TR19SRVFVSVJFRF9BVFRSSUJVVEVfTk9UX1NQRUNJRklFRCA9IEVsIGF0cmlidXRvICJ7MX0iIGVzIG5lY2VzYXJpbyB5IGRlYmUgZXNwZWNpZmljYXJzZSBwYXJhIGVsIHRpcG8gZGUgZWxlbWVudG8gInswfSIuCi0gICAgICAgIE1TR19XSElURV9TUEFDRV9JTl9FTEVNRU5UX0NPTlRFTlRfV0hFTl9TVEFOREFMT05FID0gTm8gZGViZSBpbmNsdWlyc2UgdW4gZXNwYWNpbyBlbiBibGFuY28gZW50cmUgbG9zIGVsZW1lbnRvcyBkZWNsYXJhZG9zIGVuIHVuYSBlbnRpZGFkIGFuYWxpemFkYSBleHRlcm5hIGNvbiBlbCBjb250ZW5pZG8gZGVsIGVsZW1lbnRvIGVuIHVuIGRvY3VtZW50byBhdXRcdTAwRjNub21vLgotICAgICAgICBOTVRPS0VOSW52YWxpZCA9IEVsIHZhbG9yIGRlIGF0cmlidXRvICJ7MH0iIGRlbCB0aXBvIE5NVE9LRU4gZGViZSBzZXIgdW4gdG9rZW4gZGUgbm9tYnJlLgotICAgICAgICBOTVRPS0VOU0ludmFsaWQgPSBFbCB2YWxvciBkZSBhdHJpYnV0byAiezB9IiBkZWwgdGlwbyBOTVRPS0VOUyBkZWJlIHNlciB1bm8gbyBtXHUwMEUxcyB0b2tlbnMgZGUgbm9tYnJlLgotICAgICAgICBOb05vdGF0aW9uT25FbXB0eUVsZW1lbnQgPSBFbCB0aXBvIGRlIGVsZW1lbnRvICJ7MH0iIHF1ZSBzZSBkZWNsYXJcdTAwRjMgY29tbyBFTVBUWSBubyBwdWVkZSBkZWNsYXJhciBlbCBhdHJpYnV0byAiezF9IiBkZWwgdGlwbyBOT1RBVElPTi4KLSAgICAgICAgUm9vdEVsZW1lbnRUeXBlTXVzdE1hdGNoRG9jdHlwZWRlY2wgPSBFbCBlbGVtZW50byByYVx1MDBFRHogZGVsIGRvY3VtZW50byAiezF9IiwgZGViZSBjb2luY2lkaXIgY29uIGxhIHJhXHUwMEVEeiBET0NUWVBFICJ7MH0iLgotICAgICAgICBVbmRlY2xhcmVkRWxlbWVudEluQ29udGVudFNwZWMgPSBFbCBtb2RlbG8gZGUgY29udGVuaWRvIGRlbCBlbGVtZW50byAiezB9IiBoYWNlIHJlZmVyZW5jaWEgYWwgZWxlbWVudG8gbm8gZGVjbGFyYWRvICJ7MX0iLgotICAgICAgICBVbmlxdWVOb3RhdGlvbk5hbWUgPSBMYSBkZWNsYXJhY2lcdTAwRjNuIGRlIGxhIG5vdGFjaVx1MDBGM24gInswfSIgbm8gZXMgXHUwMEZBbmljYS4gVW4gbm9tYnJlIGRldGVybWluYWRvIG5vIGRlYmUgZGVjbGFyYXJzZSBlbiBtXHUwMEUxcyBkZSB1bmEgZGVjbGFyYWNpXHUwMEYzbiBkZSBub3RhY2lcdTAwRjNuLgotICAgICAgICBFTlRJVFlGYWlsZWRJbml0aWFsaXplR3JhbW1hciA9ICBGYWxsbyBkZWwgdmFsaWRhZG9yIEVOVElUWURhdGF0eXBlLiBFcyBuZWNlc2FyaW8gbGxhbWFyIGFsIG1cdTAwRTl0b2RvIGRlIGluaWNpYWxpemFjaVx1MDBGM24gY29uIHVuYSByZWZlcmVuY2lhIGRlIGdyYW1cdTAwRTF0aWNhIHZcdTAwRTFsaWRhLiBcdAotICAgICAgICBFTlRJVFlOb3RVbnBhcnNlZCA9IEVOVElUWSAiezB9Im5vIGVzdFx1MDBFMSBzaW4gYW5hbGl6YXIuCi0gICAgICAgIEVOVElUWU5vdFZhbGlkID0gRU5USVRZICJ7MH0iIG5vIGVzIHZcdTAwRTFsaWRhLgotICAgICAgICBFbXB0eUxpc3QgPSBFbCB2YWxvciBkZSB0aXBvIEVOVElUSUVTLCBJRFJFRlMgeSBOTVRPS0VOUyBubyBwdWVkZSBzZXIgdW5hIGxpc3RhIHZhY1x1MDBFRGEuCi0KLSMgRW50aXR5IHJlbGF0ZWQgbWVzc2FnZXMKLSMgMy4xIFN0YXJ0LVRhZ3MsIEVuZC1UYWdzLCBhbmQgRW1wdHktRWxlbWVudCBUYWdzCi0gICAgICAgIFJlZmVyZW5jZVRvRXh0ZXJuYWxFbnRpdHkgPSBMYSByZWZlcmVuY2lhIGRlIGVudGlkYWQgZXh0ZXJuYSAiJnswfTsiIG5vIGVzdFx1MDBFMSBwZXJtaXRpZGEgZW4gdW4gdmFsb3IgZGUgYXRyaWJ1dG8uCi0gICAgICAgIEFjY2Vzc0V4dGVybmFsRFREID0gRFREIGV4dGVybmE6IGZhbGxvIGFsIGxlZXIgRFREIGV4dGVybmEgJyd7MH0nJyBwb3JxdWUgZWwgYWNjZXNvIGEgJyd7MX0nJyBubyBlc3RcdTAwRTEgcGVybWl0aWRvIGRlYmlkbyBhIHVuYSByZXN0cmljY2lcdTAwRjNuIHF1ZSBoYSBkZWZpbmlkbyBsYSBwcm9waWVkYWQgYWNjZXNzRXh0ZXJuYWxEVEQuCi0gICAgICAgIEFjY2Vzc0V4dGVybmFsRW50aXR5ID0gRW50aWRhZCBleHRlcm5hOiBmYWxsbyBhbCBsZWVyIGVsIGRvY3VtZW50byBleHRlcm5vICcnezB9JycgcG9ycXVlIGVsIGFjY2VzbyBhICcnezF9Jycgbm8gZXN0XHUwMEUxIHBlcm1pdGlkbyBkZWJpZG8gYSB1bmEgcmVzdHJpY2NpXHUwMEYzbiBxdWUgaGEgZGVmaW5pZG8gbGEgcHJvcGllZGFkIGFjY2Vzc0V4dGVybmFsRFRELgotCi0jIDQuMSBDaGFyYWN0ZXIgYW5kIEVudGl0eSBSZWZlcmVuY2VzCi0gICAgICAgIEVudGl0eU5vdERlY2xhcmVkID0gU2UgaGl6byByZWZlcmVuY2lhIGEgbGEgZW50aWRhZCAiezB9IiwgcGVybyBubyBzZSBkZWNsYXJcdTAwRjMuCi0gICAgICAgIFJlZmVyZW5jZVRvVW5wYXJzZWRFbnRpdHkgPSBMYSByZWZlcmVuY2lhIGRlIGVudGlkYWQgbm8gYW5hbGl6YWRhICImezB9OyIgbm8gZXN0XHUwMEUxIHBlcm1pdGlkYS4KLSAgICAgICAgUmVjdXJzaXZlUmVmZXJlbmNlID0gUmVmZXJlbmNpYSBkZSBlbnRpZGFkIHJlY3Vyc2l2YSAiezB9Ii4gKFJ1dGEgZGUgYWNjZXNvIGRlIHJlZmVyZW5jaWE6IHsxfSksCi0gICAgICAgIFJlY3Vyc2l2ZUdlbmVyYWxSZWZlcmVuY2UgPSBSZWZlcmVuY2lhIGRlIGVudGlkYWQgZ2VuZXJhbCByZWN1cnNpdmEgIiZ7MH07Ii4gKFJ1dGEgZGUgYWNjZXNvIGRlIHJlZmVyZW5jaWE6IHsxfSksCi0gICAgICAgIFJlY3Vyc2l2ZVBFUmVmZXJlbmNlID0gUmVmZXJlbmNpYSBkZSBlbnRpZGFkIGRlIHBhclx1MDBFMW1ldHJvIHJlY3Vyc2l2YSAiJXswfTsiLiAoUnV0YSBkZSBhY2Nlc28gZGUgcmVmZXJlbmNpYTogezF9KSwKLSMgNC4zLjMgQ2hhcmFjdGVyIEVuY29kaW5nIGluIEVudGl0aWVzCi0gICAgICAgIEVuY29kaW5nTm90U3VwcG9ydGVkID0gTGEgY29kaWZpY2FjaVx1MDBGM24gInswfSIgbm8gZXN0XHUwMEUxIHNvcG9ydGFkYS4KLSAgICAgICAgRW5jb2RpbmdSZXF1aXJlZCA9IFVuYSBlbnRpZGFkIGFuYWxpemFkYSBubyBjb2RpZmljYWRhIGVuIFVURi04IG8gVVRGLTE2IGRlYmUgY29udGVuZXIgdW5hIGRlY2xhcmFjaVx1MDBGM24gZGUgY29kaWZpY2FjaVx1MDBGM24uCi0gICAgICAgIAotIyBOYW1lc3BhY2VzIHN1cHBvcnQKLSMgNC4gVXNpbmcgUXVhbGlmaWVkIE5hbWVzCi0gICAgICAgIElsbGVnYWxRTmFtZSA9IEVsIGVsZW1lbnRvIG8gZWwgYXRyaWJ1dG8gbm8gY29pbmNpZGVuIGNvbiBsYSBwcm9kdWNjaVx1MDBGM24gZGVsIFFOYW1lOiBRTmFtZTo6PShOQ05hbWUnOicpP05DTmFtZS4gCi0gICAgICAgIEVsZW1lbnRYTUxOU1ByZWZpeCA9IEVsIGVsZW1lbnRvICJ7MH0iIG5vIHB1ZWRlIHRlbmVyICJ4bWxucyIgY29tbyBwcmVmaWpvLgotICAgICAgICBFbGVtZW50UHJlZml4VW5ib3VuZCA9IEVsIHByZWZpam8gInswfSIgcGFyYSBlbCBlbGVtZW50byAiezF9IiBubyBlc3RcdTAwRTEgZW5sYXphZG8uCi0gICAgICAgIEF0dHJpYnV0ZVByZWZpeFVuYm91bmQgPSBFbCBwcmVmaWpvICJ7Mn0iIHBhcmEgZWwgYXRyaWJ1dG8gInsxfSIgYXNvY2lhZG8gYSB1biB0aXBvIGRlIGVsZW1lbnRvICJ7MH0iIG5vIGVzdFx1MDBFMSBlbmxhemFkby4KLSAgICAgICAgRW1wdHlQcmVmaXhlZEF0dE5hbWUgPSBFbCB2YWxvciBkZWwgYXRyaWJ1dG8gInswfSIgbm8gZXMgdlx1MDBFMWxpZG8uIExvcyBlbmxhY2VzIGRlIGVzcGFjaW8gZGUgbm9tYnJlcyB1dGlsaXphZG9zIGRlIHByZWZpam8gbm8gcHVlZGVuIGVzdGFyIHZhY1x1MDBFRG9zLgotICAgICAgICBQcmVmaXhEZWNsYXJlZCA9IEVsIHByZWZpam8gZGUgZXNwYWNpbyBkZSBub21icmVzICJ7MH0iIG5vIHNlIGhhIGRlY2xhcmFkby4KLSAgICAgICAgQ2FudEJpbmRYTUxOUyA9IEVsIHByZWZpam8gInhtbG5zIiBubyBwdWVkZSBlbmxhemFyc2UgYSBuaW5nXHUwMEZBbiBlc3BhY2lvIGRlIG5vbWJyZXMgZXhwbFx1MDBFRGNpdGFtZW50ZTsgdGFtcG9jbyBwdWVkZSBlbmxhemFyc2UgZWwgZXNwYWNpbyBkZSBub21icmVzIHBhcmEgInhtbG5zIiBhIGN1YWxxdWllciBwcmVmaWpvIGV4cGxcdTAwRURjaXRhbWVudGUuCi0gICAgICAgIENhbnRCaW5kWE1MID0gRWwgcHJlZmlqbyAieG1sIiBubyBwdWVkZSBlbmxhemFyc2UgYSBuaW5nXHUwMEZBbiBlc3BhY2lvIGRlIG5vbWJyZXMgcXVlIG5vIHNlYSBlbCBoYWJpdHVhbDsgdGFtcG9jbyBwdWVkZSBlbmxhemFyc2UgZWwgZXNwYWNpbyBkZSBub21icmVzIHBhcmEgInhtbCIgYSBjdWFscXVpZXIgcHJlZmlqbyBxdWUgbm8gc2VhICJ4bWwiLgotICAgICAgICBNU0dfQVRUX0RFRkFVTFRfSU5WQUxJRCA9IEVsIHZhbG9yIHBvciBkZWZlY3RvICJ7MX0iIGRlbCBhdHJpYnV0byAiezB9IiBubyBlcyBsZWdhbCBwYXJhIGxhcyByZXN0cmljY2lvbmVzIGxcdTAwRTl4aWNhcyBkZSBlc3RlIHRpcG8gZGUgYXRyaWJ1dG8uCi0KLSMgUkVWSVNJVDogVGhlc2UgbmVlZCBtZXNzYWdlcwotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQUZURVJfU1lTVEVNTElURVJBTF9JTl9FWFRFUk5BTElEPU1TR19TUEFDRV9SRVFVSVJFRF9BRlRFUl9TWVNURU1MSVRFUkFMX0lOX0VYVEVSTkFMSUQKLSAgICAgICAgT3BlblF1b3RlTWlzc2luZ0luRGVjbD1PcGVuUXVvdGVNaXNzaW5nSW5EZWNsCi0gICAgICAgIEludmFsaWRDaGFySW5MaXRlcmFsPUludmFsaWRDaGFySW5MaXRlcmFsCi0KLQotIyBJbXBsZW1lbnRhdGlvbiBsaW1pdHMKLSAgICAgICAgRW50aXR5RXhwYW5zaW9uTGltaXQ9SkFYUDAwMDEwMDAxOiBlbCBhbmFsaXphZG9yIGhhIGVuY29udHJhZG8gbVx1MDBFMXMgZGUgInswfSJhbXBsaWFjaW9uZXMgZGUgZW50aWRhZCBlbiBlc3RlIGRvY3VtZW50bzsgXHUwMEU5c3RlIGVzIGVsIGxcdTAwRURtaXRlIGltcHVlc3RvIHBvciBlbCBKREsuCi0gICAgICAgIEVsZW1lbnRBdHRyaWJ1dGVMaW1pdD1KQVhQMDAwMTAwMDI6IGVsIGVsZW1lbnRvICJ7MH0iIHRpZW5lIG1cdTAwRTFzIGRlICJ7MX0iIGF0cmlidXRvcywgInsxfSIgZXMgZWwgbFx1MDBFRG1pdGUgaW1wdWVzdG8gcG9yIGVsIEpESy4KLSAgICAgICAgTWF4RW50aXR5U2l6ZUxpbWl0PUpBWFAwMDAxMDAwMzogbGEgbG9uZ2l0dWQgZGUgbGEgZW50aWRhZCAiezB9IiBlcyAiezF9IiwgcXVlIGV4Y2VkZSBlbCBsXHUwMEVEbWl0ZSBkZSAiezJ9IiBxdWUgaGEgZGVmaW5pZG8gInszfSIuCi0gICAgICAgIFRvdGFsRW50aXR5U2l6ZUxpbWl0PUpBWFAwMDAxMDAwNDogZWwgdGFtYVx1MDBGMW8gYWN1bXVsYWRvIGRlIGxhcyBlbnRpZGFkZXMgZXMgInswfSIgeSBleGNlZGUgZWwgbFx1MDBFRG1pdGUgZGUgInsxfSIgZGVmaW5pZG8gcG9yICJ7Mn0iLgotICAgICAgICBNYXhYTUxOYW1lTGltaXQ9SkFYUDAwMDEwMDA1OiBsYSBsb25naXR1ZCBkZSBsYSBlbnRpZGFkICJ7MH0iIGVzICJ7MX0iIHkgZXhjZWRlIGVsIGxcdTAwRURtaXRlIGRlICJ7Mn0iIGRlZmluaWRvIHBvciAiezN9Ii4KLSAgICAgICAgTWF4RWxlbWVudERlcHRoTGltaXQ9SkFYUDAwMDEwMDA2OiBFbCBlbGVtZW50byAiezB9IiB0aWVuZSB1bmEgcHJvZnVuZGlkYWQgZGUgInsxfSIgcXVlIGV4Y2VkZSBlbCBsXHUwMEVEbWl0ZSAiezJ9IiBkZWZpbmlkbyBwb3IgInszfSIuCi0gICAgICAgIEVudGl0eVJlcGxhY2VtZW50TGltaXQ9SkFYUDAwMDEwMDA3OiBFbCBuXHUwMEZBbWVybyB0b3RhbCBkZSBub2RvcyBlbiBsYXMgcmVmZXJlbmNpYXMgZGUgZW50aWRhZCBlcyBkZSAiezB9IiBxdWUgc3VwZXJhIGVsIGxcdTAwRURtaXRlIGRlICJ7MX0iIGRlZmluaWRvIHBvciAiezJ9Ii4KLQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MTWVzc2FnZXNfZnIucHJvcGVydGllcyBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hNTE1lc3NhZ2VzX2ZyLnByb3BlcnRpZXMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGM5YzMxYmIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MTWVzc2FnZXNfZnIucHJvcGVydGllcworKysgL2Rldi9udWxsCkBAIC0xLDMwNSArMCwwIEBACi0jIFRoaXMgZmlsZSBjb250YWlucyBlcnJvciBhbmQgd2FybmluZyBtZXNzYWdlcyByZWxhdGVkIHRvIFhNTAotIyBUaGUgbWVzc2FnZXMgYXJlIGFycmFuZ2VkIGluIGtleSBhbmQgdmFsdWUgdHVwbGVzIGluIGEgTGlzdFJlc291cmNlQnVuZGxlLgotIwotIyBAdmVyc2lvbgotCi0gICAgICAgIEJhZE1lc3NhZ2VLZXkgPSBMZSBtZXNzYWdlIGQnZXJyZXVyIGNvcnJlc3BvbmRhbnQgXHUwMEUwIGxhIGNsXHUwMEU5IGRlIG1lc3NhZ2UgZXN0IGludHJvdXZhYmxlLgotICAgICAgICBGb3JtYXRGYWlsZWQgPSBVbmUgZXJyZXVyIGludGVybmUgcydlc3QgcHJvZHVpdGUgcGVuZGFudCBsYSBtaXNlIGVuIGZvcm1lIGR1IG1lc3NhZ2Ugc3VpdmFudCA6XG4gIAotICAgICAgICAKLSMgRG9jdW1lbnQgbWVzc2FnZXMKLSAgICAgICAgUHJlbWF0dXJlRU9GPUZpbiBwclx1MDBFOW1hdHVyXHUwMEU5ZSBkdSBmaWNoaWVyLgotIyAyLjEgV2VsbC1Gb3JtZWQgWE1MIERvY3VtZW50cwotICAgICAgICBSb290RWxlbWVudFJlcXVpcmVkID0gTCdcdTAwRTlsXHUwMEU5bWVudCByYWNpbmUgZXN0IG9ibGlnYXRvaXJlIGRhbnMgdW4gZG9jdW1lbnQgYXUgZm9ybWF0IGNvcnJlY3QuCi0jIDIuMiBDaGFyYWN0ZXJzCi0KLSAgICAgICAgSW52YWxpZENoYXJJbkNEU2VjdCA9IFVuIGNhcmFjdFx1MDBFOHJlIFhNTCBub24gdmFsaWRlIChVbmljb2RlIDogMHh7MH0pIGEgXHUwMEU5dFx1MDBFOSBkXHUwMEU5dGVjdFx1MDBFOSBkYW5zIGxhIHNlY3Rpb24gQ0RBVEEuCi0gICAgICAgIEludmFsaWRDaGFySW5Db250ZW50ID0gVW4gY2FyYWN0XHUwMEU4cmUgWE1MIG5vbiB2YWxpZGUgKFVuaWNvZGUgOiAweHswfSkgYSBcdTAwRTl0XHUwMEU5IGRcdTAwRTl0ZWN0XHUwMEU5IGRhbnMgbGUgY29udGVudSBkJydcdTAwRTlsXHUwMEU5bWVudCBkdSBkb2N1bWVudC4KLSAgICAgICAgVHdvQ29sb25zSW5RTmFtZSA9IFVuIGRldXhpXHUwMEU4bWUgIjoiIG5vbiB2YWxpZGUgYSBcdTAwRTl0XHUwMEU5IGRcdTAwRTl0ZWN0XHUwMEU5IGRhbnMgbGUgdHlwZSBkJ1x1MDBFOWxcdTAwRTltZW50IG91IGxlIG5vbSBkJ2F0dHJpYnV0LgotICAgICAgICBDb2xvbk5vdExlZ2FsV2l0aE5TID0gTGVzIGRldXgtcG9pbnRzIG5lIHNvbnQgcGFzIGF1dG9yaXNcdTAwRTlzIGRhbnMgbGUgbm9tICcnezB9JycgbG9yc3F1ZSBsZXMgZXNwYWNlcyBkZSBub21zIHNvbnQgYWN0aXZcdTAwRTlzLgotICAgICAgICBJbnZhbGlkQ2hhckluTWlzYyA9IFVuIGNhcmFjdFx1MDBFOHJlIFhNTCBub24gdmFsaWRlIChVbmljb2RlIDogMHh7MH0pIGEgXHUwMEU5dFx1MDBFOSBkXHUwMEU5dGVjdFx1MDBFOSBkYW5zIGxlIGJhbGlzYWdlIGFwclx1MDBFOHMgbGEgZmluIGR1IGNvbnRlbnUgZCcnXHUwMEU5bFx1MDBFOW1lbnQuCi0gICAgICAgIEludmFsaWRDaGFySW5Qcm9sb2cgPSBVbiBjYXJhY3RcdTAwRThyZSBYTUwgbm9uIHZhbGlkZSAoVW5pY29kZSA6IDB4ezB9KSBhIFx1MDBFOXRcdTAwRTkgZFx1MDBFOXRlY3RcdTAwRTkgZGFucyBsZSBwcm9sb2d1ZSBkdSBkb2N1bWVudC4KLSAgICAgICAgSW52YWxpZENoYXJJblhNTERlY2wgPSBVbiBjYXJhY3RcdTAwRThyZSBYTUwgbm9uIHZhbGlkZSAoVW5pY29kZSA6IDB4ezB9KSBhIFx1MDBFOXRcdTAwRTkgZFx1MDBFOXRlY3RcdTAwRTkgZGFucyBsYSBkXHUwMEU5Y2xhcmF0aW9uIFhNTC4KLSMgMi40IENoYXJhY3RlciBEYXRhIGFuZCBNYXJrdXAKLSAgICAgICAgQ0RFbmRJbkNvbnRlbnQgPSBMYSBzXHUwMEU5cXVlbmNlIGRlIGNhcmFjdFx1MDBFOHJlcyAiXV0+IiBuZSBkb2l0IHBhcyBmaWd1cmVyIGRhbnMgbGUgY29udGVudSBzYXVmIHNpIGVsbGUgZXN0IHV0aWxpc1x1MDBFOWUgcG91ciBiYWxpc2VyIGxhIGZpbiBkJ3VuZSBzZWN0aW9uIENEQVRBLgotIyAyLjcgQ0RBVEEgU2VjdGlvbnMKLSAgICAgICAgQ0RTZWN0VW50ZXJtaW5hdGVkID0gTGEgc2VjdGlvbiBDREFUQSBkb2l0IHNlIHRlcm1pbmVyIHBhciAiXV0+Ii4KLSMgMi44IFByb2xvZyBhbmQgRG9jdW1lbnQgVHlwZSBEZWNsYXJhdGlvbgotICAgICAgICBYTUxEZWNsTXVzdEJlRmlyc3QgPSBMYSBkXHUwMEU5Y2xhcmF0aW9uIFhNTCBuZSBwZXV0IGZpZ3VyZXIgcXUnYXUgZFx1MDBFOWJ1dCBkdSBkb2N1bWVudC4KLSAgICAgICAgRXFSZXF1aXJlZEluWE1MRGVjbCA9IExlIGNhcmFjdFx1MDBFOHJlICcnPScnIGRvaXQgc3VpdnJlICJ7MH0iIGRhbnMgbGEgZFx1MDBFOWNsYXJhdGlvbiBYTUwuCi0gICAgICAgIFF1b3RlUmVxdWlyZWRJblhNTERlY2wgPSBMYSB2YWxldXIgc3VpdmFudCAiezB9IiBkYW5zIGxhIGRcdTAwRTljbGFyYXRpb24gWE1MIGRvaXQgXHUwMEVBdHJlIHVuZSBjaGFcdTAwRUVuZSBlbnRyZSBndWlsbGVtZXRzLgotICAgICAgICBYTUxEZWNsVW50ZXJtaW5hdGVkID0gTGEgZFx1MDBFOWNsYXJhdGlvbiBYTUwgZG9pdCBzZSB0ZXJtaW5lciBwYXIgIj8+Ii4KLSAgICAgICAgVmVyc2lvbkluZm9SZXF1aXJlZCA9IExhIHZlcnNpb24gZXN0IG9ibGlnYXRvaXJlIGRhbnMgbGEgZFx1MDBFOWNsYXJhdGlvbiBYTUwuCi0gICAgICAgIFNwYWNlUmVxdWlyZWRCZWZvcmVWZXJzaW9uSW5YTUxEZWNsID0gVW4gZXNwYWNlIGVzdCBvYmxpZ2F0b2lyZSBkZXZhbnQgbGUgcHNldWRvLWF0dHJpYnV0IHZlcnNpb24gZGFucyBsYSBkXHUwMEU5Y2xhcmF0aW9uIFhNTC4KLSAgICAgICAgU3BhY2VSZXF1aXJlZEJlZm9yZUVuY29kaW5nSW5YTUxEZWNsID0gVW4gZXNwYWNlIGVzdCBvYmxpZ2F0b2lyZSBkZXZhbnQgbGUgcHNldWRvLWF0dHJpYnV0IGVuY29kaW5nIGRhbnMgbGEgZFx1MDBFOWNsYXJhdGlvbiBYTUwuCi0gICAgICAgIFNwYWNlUmVxdWlyZWRCZWZvcmVTdGFuZGFsb25lID0gVW4gZXNwYWNlIGVzdCBvYmxpZ2F0b2lyZSBkZXZhbnQgbGUgcHNldWRvLWF0dHJpYnV0IGVuY29kaW5nIGRhbnMgbGEgZFx1MDBFOWNsYXJhdGlvbiBYTUwuCi0gICAgICAgIE1hcmt1cE5vdFJlY29nbml6ZWRJblByb2xvZyA9IExlIGJhbGlzYWdlIGR1IGRvY3VtZW50IHByXHUwMEU5Y1x1MDBFOWRhbnQgbCdcdTAwRTlsXHUwMEU5bWVudCByYWNpbmUgZG9pdCBhdm9pciB1biBmb3JtYXQgY29ycmVjdC4KLSAgICAgICAgTWFya3VwTm90UmVjb2duaXplZEluTWlzYyA9IExlIGJhbGlzYWdlIGR1IGRvY3VtZW50IHN1aXZhbnQgbCdcdTAwRTlsXHUwMEU5bWVudCByYWNpbmUgZG9pdCBhdm9pciB1biBmb3JtYXQgY29ycmVjdC4KLSAgICAgICAgQWxyZWFkeVNlZW5Eb2N0eXBlID0gRE9DVFlQRSBkXHUwMEU5alx1MDBFMCB2dS4KLSAgICAgICAgRG9jdHlwZU5vdEFsbG93ZWQgPSBET0NUWVBFIG4nZXN0IHBhcyBhdXRvcmlzXHUwMEU5IGxvcnNxdWUgbGEgZm9uY3Rpb25uYWxpdFx1MDBFOSAiaHR0cDovL2FwYWNoZS5vcmcveG1sL2ZlYXR1cmVzL2Rpc2FsbG93LWRvY3R5cGUtZGVjbCIgZXN0IGRcdTAwRTlmaW5pZSBzdXIgVHJ1ZS4KLSAgICAgICAgQ29udGVudElsbGVnYWxJblByb2xvZyA9IENvbnRlbnUgbm9uIGF1dG9yaXNcdTAwRTkgZGFucyBsZSBwcm9sb2d1ZS4KLSAgICAgICAgUmVmZXJlbmNlSWxsZWdhbEluUHJvbG9nID0gUlx1MDBFOWZcdTAwRTlyZW5jZSBub24gYXV0b3Jpc1x1MDBFOWUgZGFucyBsZSBwcm9sb2d1ZS4KLSMgVHJhaWxpbmcgTWlzYwotICAgICAgICBDb250ZW50SWxsZWdhbEluVHJhaWxpbmdNaXNjPUNvbnRlbnUgbm9uIGF1dG9yaXNcdTAwRTkgZGFucyBsYSBzZWN0aW9uIGRlIGZpbi4KLSAgICAgICAgUmVmZXJlbmNlSWxsZWdhbEluVHJhaWxpbmdNaXNjPVJcdTAwRTlmXHUwMEU5cmVuY2Ugbm9uIGF1dG9yaXNcdTAwRTllIGRhbnMgbGEgc2VjdGlvbiBkZSBmaW4uCi0gICAgICAgIAotIyAyLjkgU3RhbmRhbG9uZSBEb2N1bWVudCBEZWNsYXJhdGlvbgotICAgICAgICBTRERlY2xJbnZhbGlkID0gTGEgdmFsZXVyIGRlIGRcdTAwRTljbGFyYXRpb24gZGUgZG9jdW1lbnQgYXV0b25vbWUgZG9pdCBcdTAwRUF0cmUgIm91aSIgb3UgIm5vbiIsIG1haXMgcGFzICJ7MH0iLgotICAgICAgICBTRERlY2xOYW1lSW52YWxpZCA9IExlIG5vbSBkZSBkb2N1bWVudCBhdXRvbm9tZSBjb250ZW51IGRhbnMgbGEgZFx1MDBFOWNsYXJhdGlvbiBYTUwgZXN0IHBldXQtXHUwMEVBdHJlIG1hbCBvcnRob2dyYXBoaVx1MDBFOS4KLSMgMi4xMiBMYW5ndWFnZSBJZGVudGlmaWNhdGlvbgotICAgICAgICBYTUxMYW5nSW52YWxpZCA9IExhIHZhbGV1ciBkJydhdHRyaWJ1dCB4bWw6bGFuZyAiezB9IiBlc3QgdW4gaWRlbnRpZmljYXRldXIgZGUgbGFuZ3VlIG5vbiB2YWxpZGUuCi0jIDMuIExvZ2ljYWwgU3RydWN0dXJlcwotICAgICAgICBFVGFnUmVxdWlyZWQgPSBMZSB0eXBlIGQnJ1x1MDBFOWxcdTAwRTltZW50ICJ7MH0iIGRvaXQgc2UgdGVybWluZXIgcGFyIGxhIGJhbGlzZSBkZSBmaW4gY29ycmVzcG9uZGFudGUgIjwvezB9PiIuCi0jIDMuMSBTdGFydC1UYWdzLCBFbmQtVGFncywgYW5kIEVtcHR5LUVsZW1lbnQgVGFncwotICAgICAgICBFbGVtZW50VW50ZXJtaW5hdGVkID0gTGUgdHlwZSBkJydcdTAwRTlsXHUwMEU5bWVudCAiezB9IiBkb2l0IFx1MDBFQXRyZSBzdWl2aSBkZXMgc3BcdTAwRTljaWZpY2F0aW9ucyBkJydhdHRyaWJ1dCwgIj4iIG91ICIvPiIuCi0gICAgICAgIEVxUmVxdWlyZWRJbkF0dHJpYnV0ZSA9IExlIG5vbSBkJydhdHRyaWJ1dCAiezF9IiBhc3NvY2lcdTAwRTkgXHUwMEUwIHVuIHR5cGUgZCcnXHUwMEU5bFx1MDBFOW1lbnQgInswfSIgZG9pdCBcdTAwRUF0cmUgc3VpdmkgZHUgY2FyYWN0XHUwMEU4cmUgJyc9JycuCi0gICAgICAgIE9wZW5RdW90ZUV4cGVjdGVkID0gRGVzIGd1aWxsZW1ldHMgb3V2cmFudHMgc29udCBhdHRlbmR1cyBwb3VyIGwnJ2F0dHJpYnV0ICJ7MX0iIGFzc29jaVx1MDBFOSBcdTAwRTAgdW4gdHlwZSBkJydcdTAwRTlsXHUwMEU5bWVudCAiezB9Ii4KLSAgICAgICAgQ2xvc2VRdW90ZUV4cGVjdGVkID0gRGVzIGd1aWxsZW1ldHMgZmVybWFudHMgc29udCBhdHRlbmR1cyBwb3VyIGwnJ2F0dHJpYnV0ICJ7MX0iIGFzc29jaVx1MDBFOSBcdTAwRTAgdW4gdHlwZSBkJydcdTAwRTlsXHUwMEU5bWVudCAiezB9Ii4KLSAgICAgICAgQXR0cmlidXRlTm90VW5pcXVlID0gTCcnYXR0cmlidXQgInsxfSIgYSBkXHUwMEU5alx1MDBFMCBcdTAwRTl0XHUwMEU5IHNwXHUwMEU5Y2lmaVx1MDBFOSBwb3VyIGwnJ1x1MDBFOWxcdTAwRTltZW50ICJ7MH0iLgotICAgICAgICBBdHRyaWJ1dGVOU05vdFVuaXF1ZSA9IEwnJ2F0dHJpYnV0ICJ7MX0iIGxpXHUwMEU5IFx1MDBFMCBsJydlc3BhY2UgZGUgbm9tcyAiezJ9IiBhIGRcdTAwRTlqXHUwMEUwIFx1MDBFOXRcdTAwRTkgc3BcdTAwRTljaWZpXHUwMEU5IHBvdXIgbCcnXHUwMEU5bFx1MDBFOW1lbnQgInswfSIuCi0gICAgICAgIEVUYWdVbnRlcm1pbmF0ZWQgPSBMYSBiYWxpc2UgZGUgZmluIHBvdXIgbGUgdHlwZSBkJydcdTAwRTlsXHUwMEU5bWVudCAiezB9IiBkb2l0IHNlIHRlcm1pbmVyIHBhciB1biBkXHUwMEU5bGltaXRldXIgJyc+JycuCi0gICAgICAgIE1hcmt1cE5vdFJlY29nbml6ZWRJbkNvbnRlbnQgPSBMZSBjb250ZW51IGRlcyBcdTAwRTlsXHUwMEU5bWVudHMgZG9pdCBpbmNsdXJlIHVuIGJhbGlzYWdlIG91IGRlcyBjYXJhY3RcdTAwRThyZXMgYXUgZm9ybWF0IGNvcnJlY3QuCi0gICAgICAgIERvY3R5cGVJbGxlZ2FsSW5Db250ZW50ID0gVW4gRE9DVFlQRSBuJ2VzdCBwYXMgYXV0b3Jpc1x1MDBFOSBkYW5zIGxlIGNvbnRlbnUuCi0jIDQuMSBDaGFyYWN0ZXIgYW5kIEVudGl0eSBSZWZlcmVuY2VzCi0gICAgICAgIFJlZmVyZW5jZVVudGVybWluYXRlZCA9IExhIHJcdTAwRTlmXHUwMEU5cmVuY2UgZG9pdCBzZSB0ZXJtaW5lciBwYXIgdW4gZFx1MDBFOWxpbWl0ZXVyICc7Jy4KLSMgNC4zLjIgV2VsbC1Gb3JtZWQgUGFyc2VkIEVudGl0aWVzCi0gICAgICAgIFJlZmVyZW5jZU5vdEluT25lRW50aXR5ID0gTGEgclx1MDBFOWZcdTAwRTlyZW5jZSBkb2l0IFx1MDBFQXRyZSBlbnRpXHUwMEU4cmVtZW50IGluY2x1c2UgZGFucyBsYSBtXHUwMEVBbWUgZW50aXRcdTAwRTkgYW5hbHlzXHUwMEU5ZS4KLSAgICAgICAgRWxlbWVudEVudGl0eU1pc21hdGNoID0gTCcnXHUwMEU5bFx1MDBFOW1lbnQgInswfSIgZG9pdCBjb21tZW5jZXIgZXQgc2UgdGVybWluZXIgZGFucyBsYSBtXHUwMEVBbWUgZW50aXRcdTAwRTkuCi0gICAgICAgIE1hcmt1cEVudGl0eU1pc21hdGNoPUxlcyBzdHJ1Y3R1cmVzIGRlIGRvY3VtZW50IFhNTCBkb2l2ZW50IGNvbW1lbmNlciBldCBzZSB0ZXJtaW5lciBkYW5zIGxhIG1cdTAwRUFtZSBlbnRpdFx1MDBFOS4KLSAgICAgICAgCi0jIE1lc3NhZ2VzIGNvbW1vbiB0byBEb2N1bWVudCBhbmQgRFRECi0jIDIuMiBDaGFyYWN0ZXJzCi0gICAgICAgIEludmFsaWRDaGFySW5BdHRWYWx1ZSA9IFVuIGNhcmFjdFx1MDBFOHJlIFhNTCBub24gdmFsaWRlIChVbmljb2RlIDogMHh7Mn0pIGEgXHUwMEU5dFx1MDBFOSBkXHUwMEU5dGVjdFx1MDBFOSBkYW5zIGxhIHZhbGV1ciBkZSBsJydhdHRyaWJ1dCAiezF9IiBldCBsJydcdTAwRTlsXHUwMEU5bWVudCBlc3QgInswfSIuCi0gICAgICAgIEludmFsaWRDaGFySW5Db21tZW50ID0gVW4gY2FyYWN0XHUwMEU4cmUgWE1MIG5vbiB2YWxpZGUgKFVuaWNvZGUgOiAweHswfSkgYSBcdTAwRTl0XHUwMEU5IGRcdTAwRTl0ZWN0XHUwMEU5IGRhbnMgbGUgY29tbWVudGFpcmUuCi0gICAgICAgIEludmFsaWRDaGFySW5QSSA9IFVuIGNhcmFjdFx1MDBFOHJlIFhNTCBub24gdmFsaWRlIChVbmljb2RlIDogMHh7MH0pIGEgXHUwMEU5dFx1MDBFOSBkXHUwMEU5dGVjdFx1MDBFOSBkYW5zIGwnJ2luc3RydWN0aW9uIGRlIHRyYWl0ZW1lbnQuCi0gICAgICAgIEludmFsaWRDaGFySW5JbnRlcm5hbFN1YnNldCA9IFVuIGNhcmFjdFx1MDBFOHJlIFhNTCBub24gdmFsaWRlIChVbmljb2RlIDogMHh7MH0pIGEgXHUwMEU5dFx1MDBFOSBkXHUwMEU5dGVjdFx1MDBFOSBkYW5zIGxlIHNvdXMtZW5zZW1ibGUgaW50ZXJuZSBkZSBsYSBEVEQuCi0gICAgICAgIEludmFsaWRDaGFySW5UZXh0RGVjbCA9IFVuIGNhcmFjdFx1MDBFOHJlIFhNTCBub24gdmFsaWRlIChVbmljb2RlIDogMHh7MH0pIGEgXHUwMEU5dFx1MDBFOSBkXHUwMEU5dGVjdFx1MDBFOSBkYW5zIGxhIGRcdTAwRTljbGFyYXRpb24gdGV4dHVlbGxlLgotIyAyLjMgQ29tbW9uIFN5bnRhY3RpYyBDb25zdHJ1Y3RzCi0gICAgICAgIFF1b3RlUmVxdWlyZWRJbkF0dFZhbHVlID0gTGEgdmFsZXVyIGRlIGwnJ2F0dHJpYnV0ICJ7MX0iIGRvaXQgY29tbWVuY2VyIHBhciB1bmUgYXBvc3Ryb3BoZSBvdSBkZXMgZ3VpbGxlbWV0cy4KLSAgICAgICAgTGVzc3RoYW5JbkF0dFZhbHVlID0gTGEgdmFsZXVyIGRlIGwnJ2F0dHJpYnV0ICJ7MX0iIGFzc29jaVx1MDBFOSBcdTAwRTAgdW4gdHlwZSBkJydcdTAwRTlsXHUwMEU5bWVudCAiezB9IiBuZSBkb2l0IHBhcyBjb250ZW5pciBsZSBjYXJhY3RcdTAwRThyZSAnJzwnJy4KLSAgICAgICAgQXR0cmlidXRlVmFsdWVVbnRlcm1pbmF0ZWQgPSBMYSB2YWxldXIgZGUgbCcnYXR0cmlidXQgInsxfSIgZG9pdCBzZSB0ZXJtaW5lciBwYXIgbGVzIGd1aWxsZW1ldHMgY29ycmVzcG9uZGFudHMuCi0jIDIuNSBDb21tZW50cwotICAgICAgICBJbnZhbGlkQ29tbWVudFN0YXJ0ID0gTGUgY29tbWVudGFpcmUgZG9pdCBjb21tZW5jZXIgcGFyICI8IS0tIi4KLSAgICAgICAgRGFzaERhc2hJbkNvbW1lbnQgPSBMYSBjaGFcdTAwRUVuZSAiLS0iIG4nZXN0IHBhcyBhdXRvcmlzXHUwMEU5ZSBkYW5zIGxlcyBjb21tZW50YWlyZXMuCi0gICAgICAgIENvbW1lbnRVbnRlcm1pbmF0ZWQgPSBMZSBjb21tZW50YWlyZSBkb2l0IHNlIHRlcm1pbmVyIHBhciAiLS0+Ii4KLSAgICAgICAgQ09NTUVOVF9OT1RfSU5fT05FX0VOVElUWSA9IExlIGNvbW1lbnRhaXJlIG4nZXN0IHBhcyBjb21wcmlzIGRhbnMgbGEgbVx1MDBFQW1lIGVudGl0XHUwMEU5LgotIyAyLjYgUHJvY2Vzc2luZyBJbnN0cnVjdGlvbnMKLSAgICAgICAgUElUYXJnZXRSZXF1aXJlZCA9IEwnaW5zdHJ1Y3Rpb24gZGUgdHJhaXRlbWVudCBkb2l0IGNvbW1lbmNlciBwYXIgbGUgbm9tIGRlIGxhIGNpYmxlLgotICAgICAgICBTcGFjZVJlcXVpcmVkSW5QSSA9IFVuIGVzcGFjZSBlc3Qgb2JsaWdhdG9pcmUgZW50cmUgbGVzIGRvbm5cdTAwRTllcyBldCBsYSBjaWJsZSBkZSBsJ2luc3RydWN0aW9uIGRlIHRyYWl0ZW1lbnQuCi0gICAgICAgIFBJVW50ZXJtaW5hdGVkID0gTCdpbnN0cnVjdGlvbiBkZSB0cmFpdGVtZW50IGRvaXQgc2UgdGVybWluZXIgcGFyICI/PiIuCi0gICAgICAgIFJlc2VydmVkUElUYXJnZXQgPSBMYSBjaWJsZSBkZSBsJ2luc3RydWN0aW9uIGRlIHRyYWl0ZW1lbnQgY29ycmVzcG9uZGFudCBcdTAwRTAgIlt4WF1bbU1dW2xMXSIgbidlc3QgcGFzIGF1dG9yaXNcdTAwRTllLgotICAgICAgICBQSV9OT1RfSU5fT05FX0VOVElUWSA9IEwnaW5zdHJ1Y3Rpb24gZGUgdHJhaXRlbWVudCBuJ2VzdCBwYXMgY29tcHJpc2UgZGFucyBsYSBtXHUwMEVBbWUgZW50aXRcdTAwRTkuCi0jIDIuOCBQcm9sb2cgYW5kIERvY3VtZW50IFR5cGUgRGVjbGFyYXRpb24KLSAgICAgICAgVmVyc2lvbkluZm9JbnZhbGlkID0gVmVyc2lvbiAiezB9IiBub24gdmFsaWRlLgotICAgICAgICBWZXJzaW9uTm90U3VwcG9ydGVkID0gTGEgdmVyc2lvbiBYTUwgInswfSIgbicnZXN0IHBhcyBwcmlzZSBlbiBjaGFyZ2UuIFNldWxlIGxhIHZlcnNpb24gWE1MIDEuMCBlc3QgcHJpc2UgZW4gY2hhcmdlLgotICAgICAgICBWZXJzaW9uTm90U3VwcG9ydGVkMTEgPSBMYSB2ZXJzaW9uIFhNTCAiezB9IiBuJydlc3QgcGFzIHByaXNlIGVuIGNoYXJnZS4gU2V1bGVzIGxlcyB2ZXJzaW9ucyBYTUwgMS4wIGV0IFhNTCAxLjEgc29udCBwcmlzZXMgZW4gY2hhcmdlLgotICAgICAgICBWZXJzaW9uTWlzbWF0Y2g9IFVuZSBlbnRpdFx1MDBFOSBuZSBwZXV0IHBhcyBpbmNsdXJlIHVuZSBhdXRyZSBlbnRpdFx1MDBFOSBkJ3VuZSB2ZXJzaW9uIHVsdFx1MDBFOXJpZXVyZS4KLSMgNC4xIENoYXJhY3RlciBhbmQgRW50aXR5IFJlZmVyZW5jZXMKLSAgICAgICAgRGlnaXRSZXF1aXJlZEluQ2hhclJlZiA9IFVuZSByZXByXHUwMEU5c2VudGF0aW9uIGRcdTAwRTljaW1hbGUgZG9pdCBpbW1cdTAwRTlkaWF0ZW1lbnQgc3VpdnJlIGxhIGNoYVx1MDBFRW5lICImIyIgZGFucyB1bmUgclx1MDBFOWZcdTAwRTlyZW5jZSBkZSBjYXJhY3RcdTAwRThyZS4KLSAgICAgICAgSGV4ZGlnaXRSZXF1aXJlZEluQ2hhclJlZiA9IFVuZSByZXByXHUwMEU5c2VudGF0aW9uIGhleGFkXHUwMEU5Y2ltYWxlIGRvaXQgaW1tXHUwMEU5ZGlhdGVtZW50IHN1aXZyZSBsYSBjaGFcdTAwRUVuZSAiJiN4IiBkYW5zIHVuZSByXHUwMEU5Zlx1MDBFOXJlbmNlIGRlIGNhcmFjdFx1MDBFOHJlLgotICAgICAgICBTZW1pY29sb25SZXF1aXJlZEluQ2hhclJlZiA9IExhIHJcdTAwRTlmXHUwMEU5cmVuY2UgZGUgY2FyYWN0XHUwMEU4cmUgZG9pdCBzZSB0ZXJtaW5lciBwYXIgbGUgZFx1MDBFOWxpbWl0ZXVyICc7Jy4KLSAgICAgICAgSW52YWxpZENoYXJSZWYgPSBMYSByXHUwMEU5Zlx1MDBFOXJlbmNlIGRlIGNhcmFjdFx1MDBFOHJlICImI3swfSIgZXN0IHVuIGNhcmFjdFx1MDBFOHJlIFhNTCBub24gdmFsaWRlLgotICAgICAgICBOYW1lUmVxdWlyZWRJblJlZmVyZW5jZSA9IExlIG5vbSBkZSBsJ2lkZW50aXRcdTAwRTkgZG9pdCBpbW1cdTAwRTlkaWF0ZW1lbnQgc3VpdnJlIGxlIGNhcmFjdFx1MDBFOHJlICImIiBkYW5zIGxhIHJcdTAwRTlmXHUwMEU5cmVuY2UgZCdlbnRpdFx1MDBFOS4KLSAgICAgICAgU2VtaWNvbG9uUmVxdWlyZWRJblJlZmVyZW5jZSA9IExhIHJcdTAwRTlmXHUwMEU5cmVuY2UgXHUwMEUwIGwnJ2VudGl0XHUwMEU5ICJ7MH0iIGRvaXQgc2UgdGVybWluZXIgcGFyIGxlIGRcdTAwRTlsaW1pdGV1ciAnJzsnJy4KLSMgNC4zLjEgVGhlIFRleHQgRGVjbGFyYXRpb24KLSAgICAgICAgVGV4dERlY2xNdXN0QmVGaXJzdCA9IExhIGRcdTAwRTljbGFyYXRpb24gdGV4dHVlbGxlIG5lIGRvaXQgZmlndXJlciBxdSdhdSBkXHUwMEU5YnV0IGRlIGwnZW50aXRcdTAwRTkgYW5hbHlzXHUwMEU5ZSBleHRlcm5lLgotICAgICAgICBFcVJlcXVpcmVkSW5UZXh0RGVjbCA9IExlIGNhcmFjdFx1MDBFOHJlICcnPScnIGRvaXQgc3VpdnJlICJ7MH0iIGRhbnMgbGEgZFx1MDBFOWNsYXJhdGlvbiB0ZXh0dWVsbGUuCi0gICAgICAgIFF1b3RlUmVxdWlyZWRJblRleHREZWNsID0gTGEgdmFsZXVyIHN1aXZhbnQgInswfSIgZGFucyBsYSBkXHUwMEU5Y2xhcmF0aW9uIHRleHR1ZWxsZSBkb2l0IFx1MDBFQXRyZSB1bmUgY2hhXHUwMEVFbmUgZW50cmUgZ3VpbGxlbWV0cy4KLSAgICAgICAgQ2xvc2VRdW90ZU1pc3NpbmdJblRleHREZWNsID0gRGFucyBsYSB2YWxldXIgc3VpdmFudCAiezB9IiBkYW5zIGxhIGRcdTAwRTljbGFyYXRpb24gdGV4dHVlbGxlLCBpbCBtYW5xdWUgbGVzIGd1aWxsZW1ldHMgZmVybWFudHMuCi0gICAgICAgIFNwYWNlUmVxdWlyZWRCZWZvcmVWZXJzaW9uSW5UZXh0RGVjbCA9IFVuIGVzcGFjZSBlc3Qgb2JsaWdhdG9pcmUgZGV2YW50IGxlIHBzZXVkby1hdHRyaWJ1dCB2ZXJzaW9uIGRhbnMgbGEgZFx1MDBFOWNsYXJhdGlvbiB0ZXh0dWVsbGUuCi0gICAgICAgIFNwYWNlUmVxdWlyZWRCZWZvcmVFbmNvZGluZ0luVGV4dERlY2wgPSBVbiBlc3BhY2UgZXN0IG9ibGlnYXRvaXJlIGRldmFudCBsZSBwc2V1ZG8tYXR0cmlidXQgZW5jb2RpbmcgZGFucyBsYSBkXHUwMEU5Y2xhcmF0aW9uIHRleHR1ZWxsZS4KLSAgICAgICAgVGV4dERlY2xVbnRlcm1pbmF0ZWQgPSBMYSBkXHUwMEU5Y2xhcmF0aW9uIHRleHR1ZWxsZSBkb2l0IHNlIHRlcm1pbmVyIHBhciAiPz4iLgotICAgICAgICBFbmNvZGluZ0RlY2xSZXF1aXJlZCA9IExhIGRcdTAwRTljbGFyYXRpb24gZCdlbmNvZGFnZSBlc3Qgb2JsaWdhdG9pcmUgZGFucyBsYSBkXHUwMEU5Y2xhcmF0aW9uIHRleHR1ZWxsZS4KLSAgICAgICAgTm9Nb3JlUHNldWRvQXR0cmlidXRlcyA9IEF1Y3VuIGF1dHJlIHBzZXVkby1hdHRyaWJ1dCBuJ2VzdCBhdXRvcmlzXHUwMEU5LgotICAgICAgICBNb3JlUHNldWRvQXR0cmlidXRlcyA9IEQnYXV0cmVzIHBzZXVkby1hdHRyaWJ1dHMgc29udCBhdHRlbmR1cy4KLSAgICAgICAgUHNldWRvQXR0ck5hbWVFeHBlY3RlZCA9IFVuIG5vbSBkZSBwc2V1ZG8tYXR0cmlidXQgZXN0IGF0dGVuZHUuIAotIyA0LjMuMiBXZWxsLUZvcm1lZCBQYXJzZWQgRW50aXRpZXMKLSAgICAgICAgQ29tbWVudE5vdEluT25lRW50aXR5ID0gTGUgY29tbWVudGFpcmUgZG9pdCBcdTAwRUF0cmUgZW50aVx1MDBFOHJlbWVudCBpbmNsdXMgZGFucyBsYSBtXHUwMEVBbWUgZW50aXRcdTAwRTkgYW5hbHlzXHUwMEU5ZS4KLSAgICAgICAgUElOb3RJbk9uZUVudGl0eSA9IEwnaW5zdHJ1Y3Rpb24gZGUgdHJhaXRlbWVudCBkb2l0IFx1MDBFQXRyZSBlbnRpXHUwMEU4cmVtZW50IGluY2x1c2UgZGFucyBsYSBtXHUwMEVBbWUgZW50aXRcdTAwRTkgYW5hbHlzXHUwMEU5ZS4KLSMgNC4zLjMgQ2hhcmFjdGVyIEVuY29kaW5nIGluIEVudGl0aWVzCi0gICAgICAgIEVuY29kaW5nRGVjbEludmFsaWQgPSBOb20gZCcnZW5jb2RhZ2UgInswfSIgbm9uIHZhbGlkZS4KLSAgICAgICAgRW5jb2RpbmdCeXRlT3JkZXJVbnN1cHBvcnRlZCA9IEwnJ29yZHJlIGRlcyBvY3RldHMgZG9ublx1MDBFOSBwb3VyIGVuY29kZXIgInswfSIgbicnZXN0IHBhcyBwcmlzIGVuIGNoYXJnZS4KLSAgICAgICAgSW52YWxpZEJ5dGUgPSBPY3RldCB7MH0gZGUgbGEgc1x1MDBFOXF1ZW5jZSBVVEYtOCBcdTAwRTAgezF9IG9jdGV0cyBub24gdmFsaWRlLgotICAgICAgICBFeHBlY3RlZEJ5dGUgPSBPY3RldCB7MH0gZGUgbGEgc1x1MDBFOXF1ZW5jZSBVVEYtOCBcdTAwRTAgezF9IG9jdGV0cyBhdHRlbmR1LiAgCi0gICAgICAgIEludmFsaWRIaWdoU3Vycm9nYXRlID0gTGVzIGJpdHMgZGUgc3Vic3RpdHV0aW9uIHN1cFx1MDBFOXJpZXVycyAoSGlnaCBzdXJyb2dhdGUpIGRhbnMgbGEgc1x1MDBFOXF1ZW5jZSBVVEYtOCBuZSBkb2l2ZW50IHBhcyBkXHUwMEU5cGFzc2VyIDB4MTAgbWFpcyBkZXMgYml0cyAweHswfSBvbnQgXHUwMEU5dFx1MDBFOSBkXHUwMEU5dGVjdFx1MDBFOXMuCi0gICAgICAgIE9wZXJhdGlvbk5vdFN1cHBvcnRlZCA9IE9wXHUwMEU5cmF0aW9uICJ7MH0iIG5vbiBwcmlzZSBlbiBjaGFyZ2UgcGFyIGxlIGxlY3RldXIgezF9LgotICAgICAgICBJbnZhbGlkQVNDSUkgPSBMJydvY3RldCAiezB9IiBuJydhcHBhcnRpZW50IHBhcyBhdSBqZXUgZGUgY2FyYWN0XHUwMEU4cmVzIEFTQ0lJICg3IGJpdHMpLgotICAgICAgICBDaGFyQ29udmVyc2lvbkZhaWx1cmUgPSBVbmUgZW50aXRcdTAwRTkgcmVzcGVjdGFudCB1biBjZXJ0YWluIGVuY29kYWdlIG5lIGRvaXQgcGFzIGNvbnRlbmlyIGRlIHNcdTAwRTlxdWVuY2VzIG5vbiBhZG1pc2VzIGRhbnMgY2V0IGVuY29kYWdlLgotICAgICAgICAKLSMgRFREIE1lc3NhZ2VzCi0jIDIuMiBDaGFyYWN0ZXJzCi0gICAgICAgIEludmFsaWRDaGFySW5FbnRpdHlWYWx1ZSA9IFVuIGNhcmFjdFx1MDBFOHJlIFhNTCBub24gdmFsaWRlIChVbmljb2RlIDogMHh7MH0pIGEgXHUwMEU5dFx1MDBFOSBkXHUwMEU5dGVjdFx1MDBFOSBkYW5zIGxhIHZhbGV1ciBkJydlbnRpdFx1MDBFOSBsaXR0XHUwMEU5cmFsZS4KLSAgICAgICAgSW52YWxpZENoYXJJbkV4dGVybmFsU3Vic2V0ID0gVW4gY2FyYWN0XHUwMEU4cmUgWE1MIG5vbiB2YWxpZGUgKFVuaWNvZGUgOiAweHswfSkgYSBcdTAwRTl0XHUwMEU5IGRcdTAwRTl0ZWN0XHUwMEU5IGRhbnMgbGUgc291cy1lbnNlbWJsZSBleHRlcm5lIGRlIGxhIERURC4KLSAgICAgICAgSW52YWxpZENoYXJJbklnbm9yZVNlY3QgPSBVbiBjYXJhY3RcdTAwRThyZSBYTUwgbm9uIHZhbGlkZSAoVW5pY29kZSA6IDB4ezB9KSBhIFx1MDBFOXRcdTAwRTkgZFx1MDBFOXRlY3RcdTAwRTkgZGFucyBsYSBzZWN0aW9uIGNvbmRpdGlvbm5lbGxlIGV4Y2x1ZS4KLSAgICAgICAgSW52YWxpZENoYXJJblB1YmxpY0lEID0gVW4gY2FyYWN0XHUwMEU4cmUgWE1MIG5vbiB2YWxpZGUgKFVuaWNvZGUgOiAweHswfSkgYSBcdTAwRTl0XHUwMEU5IGRcdTAwRTl0ZWN0XHUwMEU5IGRhbnMgbCcnaWRlbnRpZmljYXRldXIgcHVibGljLgotICAgICAgICBJbnZhbGlkQ2hhckluU3lzdGVtSUQgPSBVbiBjYXJhY3RcdTAwRThyZSBYTUwgbm9uIHZhbGlkZSAoVW5pY29kZSA6IDB4ezB9KSBhIFx1MDBFOXRcdTAwRTkgZFx1MDBFOXRlY3RcdTAwRTkgZGFucyBsJydpZGVudGlmaWNhdGV1ciBzeXN0XHUwMEU4bWUuCi0jIDIuMyBDb21tb24gU3ludGFjdGljIENvbnN0cnVjdHMKLSAgICAgICAgU3BhY2VSZXF1aXJlZEFmdGVyU1lTVEVNID0gVW4gZXNwYWNlIGVzdCBvYmxpZ2F0b2lyZSBhcHJcdTAwRThzIGxlIG1vdC1jbFx1MDBFOSBTWVNURU0gZGFucyBsYSBkXHUwMEU5Y2xhcmF0aW9uIERPQ1RZUEUuCi0gICAgICAgIFF1b3RlUmVxdWlyZWRJblN5c3RlbUlEID0gTCdpZGVudGlmaWNhdGV1ciBzeXN0XHUwMEU4bWUgZG9pdCBjb21tZW5jZXIgcGFyIHVuZSBhcG9zdHJvcGhlIG91IGRlcyBndWlsbGVtZXRzLgotICAgICAgICBTeXN0ZW1JRFVudGVybWluYXRlZCA9IEwnaWRlbnRpZmljYXRldXIgc3lzdFx1MDBFOG1lIGRvaXQgc2UgdGVybWluZXIgcGFyIGxlcyBndWlsbGVtZXRzIGNvcnJlc3BvbmRhbnRzLgotICAgICAgICBTcGFjZVJlcXVpcmVkQWZ0ZXJQVUJMSUMgPSBVbiBlc3BhY2UgZXN0IG9ibGlnYXRvaXJlIGFwclx1MDBFOHMgbGUgbW90LWNsXHUwMEU5IFBVQkxJQyBkYW5zIGxhIGRcdTAwRTljbGFyYXRpb24gRE9DVFlQRS4KLSAgICAgICAgUXVvdGVSZXF1aXJlZEluUHVibGljSUQgPSBMJ2lkZW50aWZpY2F0ZXVyIHB1YmxpYyBkb2l0IGNvbW1lbmNlciBwYXIgdW5lIGFwb3N0cm9waGUgb3UgZGVzIGd1aWxsZW1ldHMuCi0gICAgICAgIFB1YmxpY0lEVW50ZXJtaW5hdGVkID0gTCdpZGVudGlmaWNhdGV1ciBwdWJsaWMgZG9pdCBzZSB0ZXJtaW5lciBwYXIgbGVzIGd1aWxsZW1ldHMgY29ycmVzcG9uZGFudHMuCi0gICAgICAgIFB1YmlkQ2hhcklsbGVnYWwgPSBDZSBjYXJhY3RcdTAwRThyZSAoVW5pY29kZSA6IDB4ezB9KSBuJydlc3QgcGFzIGF1dG9yaXNcdTAwRTkgZGFucyBsJydpZGVudGlmaWNhdGV1ciBwdWJsaWMuCi0gICAgICAgIFNwYWNlUmVxdWlyZWRCZXR3ZWVuUHVibGljQW5kU3lzdGVtID0gRGVzIGVzcGFjZXMgc29udCBvYmxpZ2F0b2lyZXMgZW50cmUgbGVzIElEIHB1YmxpY0lkIGV0IHN5c3RlbUlkLgotIyAyLjggUHJvbG9nIGFuZCBEb2N1bWVudCBUeXBlIERlY2xhcmF0aW9uCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfUk9PVF9FTEVNRU5UX1RZUEVfSU5fRE9DVFlQRURFQ0wgPSBVbiBlc3BhY2UgZXN0IG9ibGlnYXRvaXJlIGFwclx1MDBFOHMgIjwhRE9DVFlQRSIgZGFucyBsYSBkXHUwMEU5Y2xhcmF0aW9uIGRlIHR5cGUgZGUgZG9jdW1lbnQuCi0gICAgICAgIE1TR19ST09UX0VMRU1FTlRfVFlQRV9SRVFVSVJFRCA9IExlIHR5cGUgZCdcdTAwRTlsXHUwMEU5bWVudCByYWNpbmUgZG9pdCBmaWd1cmVyIGFwclx1MDBFOHMgIjwhRE9DVFlQRSIgZGFucyBsYSBkXHUwMEU5Y2xhcmF0aW9uIGRlIHR5cGUgZGUgZG9jdW1lbnQuCi0gICAgICAgIERvY3R5cGVkZWNsVW50ZXJtaW5hdGVkID0gTGEgZFx1MDBFOWNsYXJhdGlvbiBkZSB0eXBlIGRlIGRvY3VtZW50IHBvdXIgbGUgdHlwZSBkJydcdTAwRTlsXHUwMEU5bWVudCByYWNpbmUgInswfSIgZG9pdCBzZSB0ZXJtaW5lciBwYXIgJyc+JycuCi0gICAgICAgIERvY3R5cGVkZWNsTm90Q2xvc2VkID0gTGEgZFx1MDBFOWNsYXJhdGlvbiBkZSB0eXBlIGRlIGRvY3VtZW50IHBvdXIgbGUgdHlwZSBkJydcdTAwRTlsXHUwMEU5bWVudCByYWNpbmUgInswfSIgZG9pdCBzZSB0ZXJtaW5lciBwYXIgJyddJycuCi0gICAgICAgIFBFUmVmZXJlbmNlV2l0aGluTWFya3VwID0gTGEgclx1MDBFOWZcdTAwRTlyZW5jZSBkJydlbnRpdFx1MDBFOSBkZSBwYXJhbVx1MDBFOHRyZSAiJXswfTsiIG5lIHBldXQgcGFzIHN1cnZlbmlyIGRhbnMgbGUgYmFsaXNhZ2UgZHUgc291cy1lbnNlbWJsZSBpbnRlcm5lIGRlIGxhIERURC4KLSAgICAgICAgTVNHX01BUktVUF9OT1RfUkVDT0dOSVpFRF9JTl9EVEQgPSBMZXMgZFx1MDBFOWNsYXJhdGlvbnMgZGUgYmFsaXNhZ2UgY29udGVudWVzIGRhbnMgbGEgZFx1MDBFOWNsYXJhdGlvbiBkZSB0eXBlIGRlIGRvY3VtZW50IG91IHN1ciBsZXNxdWVsbGVzIHBvaW50ZSBjZXR0ZSBkZXJuaVx1MDBFOHJlIGRvaXZlbnQgYXZvaXIgdW4gZm9ybWF0IGNvcnJlY3QuCi0jIDIuMTAgV2hpdGUgU3BhY2UgSGFuZGxpbmcKLSAgICAgICAgTVNHX1hNTF9TUEFDRV9ERUNMQVJBVElPTl9JTExFR0FMID0gTGEgZFx1MDBFOWNsYXJhdGlvbiBkJ2F0dHJpYnV0IHBvdXIgInhtbDpzcGFjZSIgZG9pdCBcdTAwRUF0cmUgcHJcdTAwRTlzZW50XHUwMEU5ZSBjb21tZSB0eXBlIFx1MDBFOW51bVx1MDBFOXJcdTAwRTkgZG9udCBsZXMgc2V1bGVzIHZhbGV1cnMgcG9zc2libGVzIHNvbnQgImRlZmF1bHQiIGV0ICJwcmVzZXJ2ZSIuCi0jIDMuMiBFbGVtZW50IFR5cGUgRGVjbGFyYXRpb25zCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfRUxFTUVOVF9UWVBFX0lOX0VMRU1FTlRERUNMID0gVW4gZXNwYWNlIGVzdCBvYmxpZ2F0b2lyZSBhcHJcdTAwRThzICI8IUVMRU1FTlQiIGRhbnMgbGEgZFx1MDBFOWNsYXJhdGlvbiBkZSB0eXBlIGQnXHUwMEU5bFx1MDBFOW1lbnQuCi0gICAgICAgIE1TR19FTEVNRU5UX1RZUEVfUkVRVUlSRURfSU5fRUxFTUVOVERFQ0wgPSBMZSB0eXBlIGQnXHUwMEU5bFx1MDBFOW1lbnQgZXN0IG9ibGlnYXRvaXJlIGRhbnMgbGEgZFx1MDBFOWNsYXJhdGlvbiBkZSB0eXBlIGQnXHUwMEU5bFx1MDBFOW1lbnQuCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfQ09OVEVOVFNQRUNfSU5fRUxFTUVOVERFQ0wgPSBVbiBlc3BhY2UgZXN0IG9ibGlnYXRvaXJlIGFwclx1MDBFOHMgbGUgdHlwZSBkJydcdTAwRTlsXHUwMEU5bWVudCAiezB9IiBkYW5zIGxhIGRcdTAwRTljbGFyYXRpb24gZGUgdHlwZSBkJydcdTAwRTlsXHUwMEU5bWVudC4KLSAgICAgICAgTVNHX0NPTlRFTlRTUEVDX1JFUVVJUkVEX0lOX0VMRU1FTlRERUNMID0gTGEgY29udHJhaW50ZSBlc3Qgb2JsaWdhdG9pcmUgYXByXHUwMEU4cyBsZSB0eXBlIGQnJ1x1MDBFOWxcdTAwRTltZW50ICJ7MH0iIGRhbnMgbGEgZFx1MDBFOWNsYXJhdGlvbiBkZSB0eXBlIGQnJ1x1MDBFOWxcdTAwRTltZW50LgotICAgICAgICBFbGVtZW50RGVjbFVudGVybWluYXRlZCA9IExhIGRcdTAwRTljbGFyYXRpb24gZHUgdHlwZSBkJydcdTAwRTlsXHUwMEU5bWVudCAiezB9IiBkb2l0IHNlIHRlcm1pbmVyIHBhciAnJz4nJy4KLSMgMy4yLjEgRWxlbWVudCBDb250ZW50Ci0gICAgICAgIE1TR19PUEVOX1BBUkVOX09SX0VMRU1FTlRfVFlQRV9SRVFVSVJFRF9JTl9DSElMRFJFTiA9IFVuIGNhcmFjdFx1MDBFOHJlICcnKCcnIG91IHVuIHR5cGUgZCcnXHUwMEU5bFx1MDBFOW1lbnQgZXN0IG9ibGlnYXRvaXJlIGRhbnMgbGEgZFx1MDBFOWNsYXJhdGlvbiBkdSB0eXBlIGQnJ1x1MDBFOWxcdTAwRTltZW50ICJ7MH0iLgotICAgICAgICBNU0dfQ0xPU0VfUEFSRU5fUkVRVUlSRURfSU5fQ0hJTERSRU4gPSBVbiBjYXJhY3RcdTAwRThyZSAnJyknJyBlc3Qgb2JsaWdhdG9pcmUgZGFucyBsYSBkXHUwMEU5Y2xhcmF0aW9uIGR1IHR5cGUgZCcnXHUwMEU5bFx1MDBFOW1lbnQgInswfSIuCi0jIDMuMi4yIE1peGVkIENvbnRlbnQKLSAgICAgICAgTVNHX0VMRU1FTlRfVFlQRV9SRVFVSVJFRF9JTl9NSVhFRF9DT05URU5UID0gVW4gdHlwZSBkJydcdTAwRTlsXHUwMEU5bWVudCBlc3Qgb2JsaWdhdG9pcmUgZGFucyBsYSBkXHUwMEU5Y2xhcmF0aW9uIGR1IHR5cGUgZCcnXHUwMEU5bFx1MDBFOW1lbnQgInswfSIuCi0gICAgICAgIE1TR19DTE9TRV9QQVJFTl9SRVFVSVJFRF9JTl9NSVhFRCA9IFVuIGNhcmFjdFx1MDBFOHJlICcnKScnIGVzdCBvYmxpZ2F0b2lyZSBkYW5zIGxhIGRcdTAwRTljbGFyYXRpb24gZHUgdHlwZSBkJydcdTAwRTlsXHUwMEU5bWVudCAiezB9Ii4KLSAgICAgICAgTWl4ZWRDb250ZW50VW50ZXJtaW5hdGVkID0gTGUgbW9kXHUwMEU4bGUgZGUgY29udGVudSBtaXh0ZSAiezB9IiBkb2l0IHNlIHRlcm1pbmVyIHBhciAiKSoiIGxvcnNxdWUgbGVzIHR5cGVzIGQnJ1x1MDBFOWxcdTAwRTltZW50IGVuZmFudCBzb250IGNvbnRyYWludHMuCi0jIDMuMyBBdHRyaWJ1dGUtTGlzdCBEZWNsYXJhdGlvbnMKLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9FTEVNRU5UX1RZUEVfSU5fQVRUTElTVERFQ0wgPSBVbiBlc3BhY2UgZXN0IG9ibGlnYXRvaXJlIGFwclx1MDBFOHMgIjwhQVRUTElTVCIgZGFucyBsYSBkXHUwMEU5Y2xhcmF0aW9uIGRlIGxpc3RlIGQnYXR0cmlidXRzLgotICAgICAgICBNU0dfRUxFTUVOVF9UWVBFX1JFUVVJUkVEX0lOX0FUVExJU1RERUNMID0gTGUgdHlwZSBkJ1x1MDBFOWxcdTAwRTltZW50IGVzdCBvYmxpZ2F0b2lyZSBkYW5zIGxhIGRcdTAwRTljbGFyYXRpb24gZGUgbGlzdGUgZCdhdHRyaWJ1dHMuCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfQVRUUklCVVRFX05BTUVfSU5fQVRUREVGID0gVW4gZXNwYWNlIGVzdCBvYmxpZ2F0b2lyZSBhdmFudCBsZSBub20gZCcnYXR0cmlidXQgZGFucyBsYSBkXHUwMEU5Y2xhcmF0aW9uIGRlIGxpc3RlIGQnJ2F0dHJpYnV0cyBkZSBsJydcdTAwRTlsXHUwMEU5bWVudCAiezB9Ii4KLSAgICAgICAgQXR0TmFtZVJlcXVpcmVkSW5BdHREZWYgPSBMZSBub20gZCcnYXR0cmlidXQgZG9pdCBcdTAwRUF0cmUgc3BcdTAwRTljaWZpXHUwMEU5IGRhbnMgbGEgZFx1MDBFOWNsYXJhdGlvbiBkZSBsaXN0ZSBkJydhdHRyaWJ1dHMgZGUgbCcnXHUwMEU5bFx1MDBFOW1lbnQgInswfSIuCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfQVRUVFlQRV9JTl9BVFRERUYgPSBVbiBlc3BhY2UgZXN0IG9ibGlnYXRvaXJlIGF2YW50IGxlIHR5cGUgZCcnYXR0cmlidXQgZGFucyBsYSBkXHUwMEU5Y2xhcmF0aW9uIGRlIGwnJ2F0dHJpYnV0ICJ7MX0iIGRlIGwnJ1x1MDBFOWxcdTAwRTltZW50ICJ7MH0iLgotICAgICAgICBBdHRUeXBlUmVxdWlyZWRJbkF0dERlZiA9IExlIHR5cGUgZCcnYXR0cmlidXQgZXN0IG9ibGlnYXRvaXJlIGRhbnMgbGEgZFx1MDBFOWNsYXJhdGlvbiBkZSBsJydhdHRyaWJ1dCAiezF9IiBkZSBsJydcdTAwRTlsXHUwMEU5bWVudCAiezB9Ii4KLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9ERUZBVUxUREVDTF9JTl9BVFRERUYgPSBVbiBlc3BhY2UgZXN0IG9ibGlnYXRvaXJlIGF2YW50IGxhIHZhbGV1ciBwYXIgZFx1MDBFOWZhdXQgZGUgbCcnYXR0cmlidXQgZGFucyBsYSBkXHUwMEU5Y2xhcmF0aW9uIGRlIGwnJ2F0dHJpYnV0ICJ7MX0iIGRlIGwnJ1x1MDBFOWxcdTAwRTltZW50ICJ7MH0iLgotICAgICAgICBNU0dfRFVQTElDQVRFX0FUVFJJQlVURV9ERUZJTklUSU9OID0gUGx1c2lldXJzIGRcdTAwRTlmaW5pdGlvbnMgZCcnYXR0cmlidXQgc29udCBmb3VybmllcyBwb3VyIGxlIG1cdTAwRUFtZSBhdHRyaWJ1dCAiezF9IiBkJyd1biBcdTAwRTlsXHUwMEU5bWVudCBkb25uXHUwMEU5ICJ7MH0iLgotIyAzLjMuMSBBdHRyaWJ1dGUgVHlwZXMKLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0FGVEVSX05PVEFUSU9OX0lOX05PVEFUSU9OVFlQRSA9IFVuIGVzcGFjZSBkb2l0IGZpZ3VyZXIgYXByXHUwMEU4cyAiTk9UQVRJT04iIGRhbnMgbGEgZFx1MDBFOWNsYXJhdGlvbiBkJydhdHRyaWJ1dCAiezF9Ii4KLSAgICAgICAgTVNHX09QRU5fUEFSRU5fUkVRVUlSRURfSU5fTk9UQVRJT05UWVBFID0gTGUgY2FyYWN0XHUwMEU4cmUgJycoJycgZG9pdCBzdWl2cmUgIk5PVEFUSU9OIiBkYW5zIGxhIGRcdTAwRTljbGFyYXRpb24gZCcnYXR0cmlidXQgInsxfSIuCi0gICAgICAgIE1TR19OQU1FX1JFUVVJUkVEX0lOX05PVEFUSU9OVFlQRSA9IExlIG5vbSBkZSBub3RhdGlvbiBlc3Qgb2JsaWdhdG9pcmUgZGFucyBsYSBsaXN0ZSBkZXMgdHlwZXMgZGUgbm90YXRpb24gZGUgbGEgZFx1MDBFOWNsYXJhdGlvbiBkJydhdHRyaWJ1dCAiezF9Ii4KLSAgICAgICAgTm90YXRpb25UeXBlVW50ZXJtaW5hdGVkID0gTGEgbGlzdGUgZGVzIHR5cGVzIGRlIG5vdGF0aW9uIGRvaXQgc2UgdGVybWluZXIgcGFyICcnKScnIGRhbnMgbGEgZFx1MDBFOWNsYXJhdGlvbiBkJydhdHRyaWJ1dCAiezF9Ii4KLSAgICAgICAgTVNHX05NVE9LRU5fUkVRVUlSRURfSU5fRU5VTUVSQVRJT04gPSBMZSBqZXRvbiBkZSBub20gZXN0IG9ibGlnYXRvaXJlIGRhbnMgbGEgbGlzdGUgZGVzIHR5cGVzIFx1MDBFOW51bVx1MDBFOXJcdTAwRTlzIHBvdXIgbGEgZFx1MDBFOWNsYXJhdGlvbiBkJydhdHRyaWJ1dCAiezF9Ii4KLSAgICAgICAgRW51bWVyYXRpb25VbnRlcm1pbmF0ZWQgPSBMYSBsaXN0ZSBkZXMgdHlwZXMgXHUwMEU5bnVtXHUwMEU5clx1MDBFOXMgZG9pdCBzZSB0ZXJtaW5lciBwYXIgJycpJycgZGFucyBsYSBkXHUwMEU5Y2xhcmF0aW9uIGQnJ2F0dHJpYnV0ICJ7MX0iLgotICAgICAgICBNU0dfRElTVElOQ1RfVE9LRU5TX0lOX0VOVU1FUkFUSU9OID0gTGEgdmFsZXVyIGQnJ1x1MDBFOW51bVx1MDBFOXJhdGlvbiAiezF9IiBhIFx1MDBFOXRcdTAwRTkgaW5kaXF1XHUwMEU5ZSBwbHVzaWV1cnMgZm9pcyBkYW5zIGxhIGRcdTAwRTljbGFyYXRpb24gZGUgbCcnYXR0cmlidXQgInsyfSIgcG91ciBsJydcdTAwRTlsXHUwMEU5bWVudCAiezB9Ii4gTGVzIHZhbGV1cnMgTk1UT0tFTlMgZCcndW5lIGRcdTAwRTljbGFyYXRpb24gZCcnYXR0cmlidXQgRW51bWVyYXRpb24gdW5pcXVlIGRvaXZlbnQgdG91dGVzIFx1MDBFQXRyZSBkaXN0aW5jdGVzLgotICAgICAgICBNU0dfRElTVElOQ1RfTk9UQVRJT05fSU5fRU5VTUVSQVRJT04gPSBMYSB2YWxldXIgZCcnXHUwMEU5bnVtXHUwMEU5cmF0aW9uICJ7MX0iIGEgXHUwMEU5dFx1MDBFOSBpbmRpcXVcdTAwRTllIHBsdXNpZXVycyBmb2lzIGRhbnMgbGEgZFx1MDBFOWNsYXJhdGlvbiBkZSBsJydhdHRyaWJ1dCAiezJ9IiBwb3VyIGwnJ1x1MDBFOWxcdTAwRTltZW50ICJ7MH0iLiBMZXMgbm9tcyBOT1RBVElPTiBkJyd1bmUgZFx1MDBFOWNsYXJhdGlvbiBkJydhdHRyaWJ1dCBOb3RhdGlvblR5cGUgdW5pcXVlIGRvaXZlbnQgdG91cyBcdTAwRUF0cmUgZGlzdGluY3RzLgotIyAzLjMuMiBBdHRyaWJ1dGUgRGVmYXVsdHMKLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0FGVEVSX0ZJWEVEX0lOX0RFRkFVTFRERUNMID0gVW4gZXNwYWNlIGRvaXQgZmlndXJlciBhcHJcdTAwRThzICJGSVhFRCIgZGFucyBsYSBkXHUwMEU5Y2xhcmF0aW9uIGQnJ2F0dHJpYnV0ICJ7MX0iLgotIyAzLjQgQ29uZGl0aW9uYWwgU2VjdGlvbnMKLSAgICAgICAgSW5jbHVkZVNlY3RVbnRlcm1pbmF0ZWQgPSBMYSBzZWN0aW9uIGNvbmRpdGlvbm5lbGxlIGluY2x1c2UgZG9pdCBzZSB0ZXJtaW5lciBwYXIgIl1dPiIuCi0gICAgICAgIElnbm9yZVNlY3RVbnRlcm1pbmF0ZWQgPSBMYSBzZWN0aW9uIGNvbmRpdGlvbm5lbGxlIGV4Y2x1ZSBkb2l0IHNlIHRlcm1pbmVyIHBhciAiXV0+Ii4KLSMgNC4xIENoYXJhY3RlciBhbmQgRW50aXR5IFJlZmVyZW5jZXMKLSAgICAgICAgTmFtZVJlcXVpcmVkSW5QRVJlZmVyZW5jZSA9IExlIG5vbSBkZSBsJ2VudGl0XHUwMEU5IGRvaXQgaW1tXHUwMEU5ZGlhdGVtZW50IHN1aXZyZSBsZSBjYXJhY3RcdTAwRThyZSAiJSIgZGFucyBsYSByXHUwMEU5Zlx1MDBFOXJlbmNlIGQnZW50aXRcdTAwRTkgZGUgcGFyYW1cdTAwRTh0cmUuCi0gICAgICAgIFNlbWljb2xvblJlcXVpcmVkSW5QRVJlZmVyZW5jZSA9IExhIHJcdTAwRTlmXHUwMEU5cmVuY2UgZCcnZW50aXRcdTAwRTkgZGUgcGFyYW1cdTAwRTh0cmUgIiV7MH07IiBkb2l0IHNlIHRlcm1pbmVyIHBhciBsZSBkXHUwMEU5bGltaXRldXIgJyc7JycuCi0jIDQuMiBFbnRpdHkgRGVjbGFyYXRpb25zCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfRU5USVRZX05BTUVfSU5fRU5USVRZREVDTCA9IFVuIGVzcGFjZSBlc3Qgb2JsaWdhdG9pcmUgYXByXHUwMEU4cyAiPCFFTlRJVFkiIGRhbnMgbGEgZFx1MDBFOWNsYXJhdGlvbiBkJ2VudGl0XHUwMEU5LgotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX1BFUkNFTlRfSU5fUEVERUNMID0gVW4gZXNwYWNlIGVzdCBvYmxpZ2F0b2lyZSBlbnRyZSAiPCFFTlRJVFkiIGV0IGxlIGNhcmFjdFx1MDBFOHJlICIlIiBkYW5zIGxhIGRcdTAwRTljbGFyYXRpb24gZCdlbnRpdFx1MDBFOSBkZSBwYXJhbVx1MDBFOHRyZS4KLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9FTlRJVFlfTkFNRV9JTl9QRURFQ0wgPSBVbiBlc3BhY2UgZXN0IG9ibGlnYXRvaXJlIGVudHJlICIlIiBldCBsZSBub20gZGUgbCdlbnRpdFx1MDBFOSBkYW5zIGxhIGRcdTAwRTljbGFyYXRpb24gZCdlbnRpdFx1MDBFOSBkZSBwYXJhbVx1MDBFOHRyZS4KLSAgICAgICAgTVNHX0VOVElUWV9OQU1FX1JFUVVJUkVEX0lOX0VOVElUWURFQ0wgPSBMZSBub20gZGUgbCdlbnRpdFx1MDBFOSBlc3Qgb2JsaWdhdG9pcmUgZGFucyBsYSBkXHUwMEU5Y2xhcmF0aW9uIGQnZW50aXRcdTAwRTkuCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9BRlRFUl9FTlRJVFlfTkFNRV9JTl9FTlRJVFlERUNMID0gVW4gZXNwYWNlIGVzdCBvYmxpZ2F0b2lyZSBlbnRyZSBsZSBub20gZGUgbCcnZW50aXRcdTAwRTkgInswfSIgZXQgbGEgZFx1MDBFOWZpbml0aW9uIGRhbnMgbGEgZFx1MDBFOWNsYXJhdGlvbiBkJydlbnRpdFx1MDBFOS4KLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9OT1RBVElPTl9OQU1FX0lOX1VOUEFSU0VEX0VOVElUWURFQ0wgPSBVbiBlc3BhY2UgZXN0IG9ibGlnYXRvaXJlIGVudHJlICJOREFUQSIgZXQgbGUgbm9tIGRlIG5vdGF0aW9uIGRhbnMgbGEgZFx1MDBFOWNsYXJhdGlvbiBkZSBsJydlbnRpdFx1MDBFOSAiezB9Ii4KLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9OREFUQV9JTl9VTlBBUlNFRF9FTlRJVFlERUNMID0gVW4gZXNwYWNlIGVzdCBvYmxpZ2F0b2lyZSBhdmFudCAiTkRBVEEiIGRhbnMgbGEgZFx1MDBFOWNsYXJhdGlvbiBkZSBsJydlbnRpdFx1MDBFOSAiezB9Ii4KLSAgICAgICAgTVNHX05PVEFUSU9OX05BTUVfUkVRVUlSRURfRk9SX1VOUEFSU0VEX0VOVElUWURFQ0wgPSBMZSBub20gZGUgbm90YXRpb24gZXN0IG9ibGlnYXRvaXJlIGFwclx1MDBFOHMgIk5EQVRBIiBkYW5zIGxhIGRcdTAwRTljbGFyYXRpb24gZGUgbCcnZW50aXRcdTAwRTkgInswfSIuCi0gICAgICAgIEVudGl0eURlY2xVbnRlcm1pbmF0ZWQgPSBMYSBkXHUwMEU5Y2xhcmF0aW9uIGRlIGwnJ2VudGl0XHUwMEU5ICJ7MH0iIGRvaXQgc2UgdGVybWluZXIgcGFyICcnPicnLgotCU1TR19EVVBMSUNBVEVfRU5USVRZX0RFRklOSVRJT04gPSBMJydlbnRpdFx1MDBFOSAiezB9IiBlc3QgZFx1MDBFOWNsYXJcdTAwRTllIHBsdXNpZXVycyBmb2lzLiAgICAgICAgCi0jIDQuMi4yIEV4dGVybmFsIEVudGl0aWVzCi0gICAgICAgIEV4dGVybmFsSURSZXF1aXJlZCA9IExhIGRcdTAwRTljbGFyYXRpb24gZCdlbnRpdFx1MDBFOSBleHRlcm5lIGRvaXQgY29tbWVuY2VyIHBhciAiU1lTVEVNIiBvdSAiUFVCTElDIi4KLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9QVUJJRExJVEVSQUxfSU5fRVhURVJOQUxJRCA9IFVuIGVzcGFjZSBlc3Qgb2JsaWdhdG9pcmUgZW50cmUgIlBVQkxJQyIgZXQgbCdpZGVudGlmaWNhdGV1ciBwdWJsaWMuCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9BRlRFUl9QVUJJRExJVEVSQUxfSU5fRVhURVJOQUxJRCA9IFVuIGVzcGFjZSBlc3Qgb2JsaWdhdG9pcmUgZW50cmUgbCdpZGVudGlmaWNhdGV1ciBwdWJsaWMgZXQgbCdpZGVudGlmaWNhdGV1ciBzeXN0XHUwMEU4bWUuCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfU1lTVEVNTElURVJBTF9JTl9FWFRFUk5BTElEID0gVW4gZXNwYWNlIGVzdCBvYmxpZ2F0b2lyZSBlbnRyZSAiU1lTVEVNIiBldCBsJ2lkZW50aWZpY2F0ZXVyIHN5c3RcdTAwRThtZS4KLSAgICAgICAgTVNHX1VSSV9GUkFHTUVOVF9JTl9TWVNURU1JRCA9IEwnJ2lkZW50aWZpY2F0ZXVyIGR1IGZyYWdtZW50IG5lIGRvaXQgcGFzIFx1MDBFQXRyZSBzcFx1MDBFOWNpZmlcdTAwRTkgY29tbWUgZmFpc2FudCBwYXJ0aWUgZGUgbCcnaWRlbnRpZmljYXRldXIgc3lzdFx1MDBFOG1lICJ7MH0iLgotIyA0LjcgTm90YXRpb24gRGVjbGFyYXRpb25zCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfTk9UQVRJT05fTkFNRV9JTl9OT1RBVElPTkRFQ0wgPSBVbiBlc3BhY2UgZXN0IG9ibGlnYXRvaXJlIGFwclx1MDBFOHMgIjwhTk9UQVRJT04iIGRhbnMgbGEgZFx1MDBFOWNsYXJhdGlvbiBkZSBub3RhdGlvbi4KLSAgICAgICAgTVNHX05PVEFUSU9OX05BTUVfUkVRVUlSRURfSU5fTk9UQVRJT05ERUNMID0gTGUgbm9tIGRlIGxhIG5vdGF0aW9uIGVzdCBvYmxpZ2F0b2lyZSBkYW5zIGxhIGRcdTAwRTljbGFyYXRpb24gZGUgbm90YXRpb24uCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9BRlRFUl9OT1RBVElPTl9OQU1FX0lOX05PVEFUSU9OREVDTCA9IFVuIGVzcGFjZSBlc3Qgb2JsaWdhdG9pcmUgYXByXHUwMEU4cyBsZSBub20gZGUgbm90YXRpb24gInswfSIgZGFucyBsYSBkXHUwMEU5Y2xhcmF0aW9uIGRlIG5vdGF0aW9uLgotICAgICAgICBFeHRlcm5hbElEb3JQdWJsaWNJRFJlcXVpcmVkID0gTGEgZFx1MDBFOWNsYXJhdGlvbiBkZSBsYSBub3RhdGlvbiAiezB9IiBkb2l0IGluY2x1cmUgdW4gaWRlbnRpZmljYXRldXIgc3lzdFx1MDBFOG1lIG91IHB1YmxpYy4KLSAgICAgICAgTm90YXRpb25EZWNsVW50ZXJtaW5hdGVkID0gTGEgZFx1MDBFOWNsYXJhdGlvbiBkZSBsYSBub3RhdGlvbiAiezB9IiBkb2l0IHNlIHRlcm1pbmVyIHBhciAnJz4nJy4KLSAgICAgICAgCi0jIFZhbGlkYXRpb24gbWVzc2FnZXMKLSAgICAgICAgRHVwbGljYXRlVHlwZUluTWl4ZWRDb250ZW50ID0gTGUgdHlwZSBkJydcdTAwRTlsXHUwMEU5bWVudCAiezF9IiBhIGRcdTAwRTlqXHUwMEUwIFx1MDBFOXRcdTAwRTkgc3BcdTAwRTljaWZpXHUwMEU5IGRhbnMgbGUgbW9kXHUwMEU4bGUgZGUgY29udGVudSBkZSBsYSBkXHUwMEU5Y2xhcmF0aW9uIGQnJ1x1MDBFOWxcdTAwRTltZW50ICJ7MH0iLgotICAgICAgICBFTlRJVElFU0ludmFsaWQgPSBMYSB2YWxldXIgZCcnYXR0cmlidXQgInsxfSIgZGUgdHlwZSBFTlRJVElFUyBkb2l0IGNvcnJlc3BvbmRyZSBhdSBub20gZCcnYXUgbW9pbnMgdW5lIGVudGl0XHUwMEU5IG5vbiBhbmFseXNcdTAwRTllLgotICAgICAgICBFTlRJVFlJbnZhbGlkID0gTGEgdmFsZXVyIGQnJ2F0dHJpYnV0ICJ7MX0iIGRlIHR5cGUgRU5USVRZIGRvaXQgY29ycmVzcG9uZHJlIGF1IG5vbSBkJyd1bmUgZW50aXRcdTAwRTkgbm9uIGFuYWx5c1x1MDBFOWUuCi0gICAgICAgIElERGVmYXVsdFR5cGVJbnZhbGlkID0gTCcnYXR0cmlidXQgZCcnSUQgInswfSIgZG9pdCBhdm9pciB1bmUgdmFsZXVyIHBhciBkXHUwMEU5ZmF1dCBkXHUwMEU5Y2xhclx1MDBFOWUgZGUgIiNJTVBMSUVEIiBvdSAiI1JFUVVJUkVEIi4KLSAgICAgICAgSURJbnZhbGlkID0gTGEgdmFsZXVyIGQnJ2F0dHJpYnV0ICJ7MH0iIGRlIHR5cGUgSUQgZG9pdCBcdTAwRUF0cmUgdW4gbm9tLgotICAgICAgICBJREludmFsaWRXaXRoTmFtZXNwYWNlcyA9IExhIHZhbGV1ciBkJydhdHRyaWJ1dCAiezB9IiBkZSB0eXBlIElEIGRvaXQgXHUwMEVBdHJlIHVuIE5DTmFtZSBsb3JzcXVlIGxlcyBlc3BhY2VzIGRlIG5vbXMgc29udCBhY3Rpdlx1MDBFOXMuCi0gICAgICAgIElETm90VW5pcXVlID0gTGEgdmFsZXVyIGQnJ2F0dHJpYnV0ICJ7MH0iIGRlIHR5cGUgSUQgZG9pdCBcdTAwRUF0cmUgdW5pcXVlIGRhbnMgbGUgZG9jdW1lbnQuCi0gICAgICAgIElEUkVGSW52YWxpZCA9IExhIHZhbGV1ciBkJydhdHRyaWJ1dCAiezB9IiBkZSB0eXBlIElEUkVGIGRvaXQgXHUwMEVBdHJlIHVuIG5vbS4KLSAgICAgICAgSURSRUZJbnZhbGlkV2l0aE5hbWVzcGFjZXMgPSBMYSB2YWxldXIgZCcnYXR0cmlidXQgInswfSIgZGUgdHlwZSBJRFJFRiBkb2l0IFx1MDBFQXRyZSB1biBOQ05hbWUgbG9yc3F1ZSBsZXMgZXNwYWNlcyBkZSBub21zIHNvbnQgYWN0aXZcdTAwRTlzLgotICAgICAgICBJRFJFRlNJbnZhbGlkID0gVW5lIHZhbGV1ciBkJydhdHRyaWJ1dCAiezB9IiBkZSB0eXBlIElEUkVGUyBkb2l0IGNvcnJlc3BvbmRyZSBcdTAwRTAgYXUgbW9pbnMgdW4gbm9tLgotICAgICAgICBJTExfRk9STUVEX1BBUkFNRVRFUl9FTlRJVFlfV0hFTl9VU0VEX0lOX0RFQ0wgPSBMZSB0ZXh0ZSBkZSByZW1wbGFjZW1lbnQgZGUgbCcnZW50aXRcdTAwRTkgZGUgcGFyYW1cdTAwRTh0cmUgInswfSIgZG9pdCBpbmNsdXJlIGRlcyBkXHUwMEU5Y2xhcmF0aW9ucyBjb3JyZWN0ZW1lbnQgaW1icmlxdVx1MDBFOWVzIGxvcnNxdWUgbGEgclx1MDBFOWZcdTAwRTlyZW5jZSBkJydlbnRpdFx1MDBFOSBlc3QgdXRpbGlzXHUwMEU5ZSBjb21tZSBkXHUwMEU5Y2xhcmF0aW9uIGNvbXBsXHUwMEU4dGUuCi0gICAgICAgIEltcHJvcGVyRGVjbGFyYXRpb25OZXN0aW5nID0gTGUgdGV4dGUgZGUgcmVtcGxhY2VtZW50IGRlIGwnJ2VudGl0XHUwMEU5IGRlIHBhcmFtXHUwMEU4dHJlICJ7MH0iIGRvaXQgaW5jbHVyZSBkZXMgZFx1MDBFOWNsYXJhdGlvbnMgY29ycmVjdGVtZW50IGltYnJpcXVcdTAwRTllcy4KLSAgICAgICAgSW1wcm9wZXJHcm91cE5lc3RpbmcgPSBMZSB0ZXh0ZSBkZSByZW1wbGFjZW1lbnQgZGUgbCcnZW50aXRcdTAwRTkgZGUgcGFyYW1cdTAwRTh0cmUgInswfSIgZG9pdCBpbmNsdXJlIGRlcyBwYWlyZXMgZGUgcGFyZW50aFx1MDBFOHNlcyBjb3JyZWN0ZW1lbnQgaW1icmlxdVx1MDBFOWVzLgotICAgICAgICBJTlZBTElEX1BFX0lOX0NPTkRJVElPTkFMID0gTGUgdGV4dGUgZGUgcmVtcGxhY2VtZW50IGRlIGwnJ2VudGl0XHUwMEU5IGRlIHBhcmFtXHUwMEU4dHJlICJ7MH0iIGRvaXQgaW5jbHVyZSBsYSBzZWN0aW9uIGNvbmRpdGlvbm5lbGxlIGNvbXBsXHUwMEU4dGUgb3Ugc2V1bGVtZW50IElOQ0xVREUgb3UgSUdOT1JFLgotICAgICAgICBNU0dfQVRUUklCVVRFX05PVF9ERUNMQVJFRCA9IEwnJ2F0dHJpYnV0ICJ7MX0iIGRvaXQgXHUwMEVBdHJlIGRcdTAwRTljbGFyXHUwMEU5IHBvdXIgbGUgdHlwZSBkJydcdTAwRTlsXHUwMEU5bWVudCAiezB9Ii4KLSAgICAgICAgTVNHX0FUVFJJQlVURV9WQUxVRV9OT1RfSU5fTElTVCA9IEwnJ2F0dHJpYnV0ICJ7MH0iIGRlIHZhbGV1ciAiezF9IiBkb2l0IGF2b2lyIHVuZSB2YWxldXIgaXNzdWUgZGUgbGEgbGlzdGUgInsyfSIuCi0gICAgICAgIE1TR19BVFRWQUxVRV9DSEFOR0VEX0RVUklOR19OT1JNQUxJWkFUSU9OX1dIRU5fU1RBTkRBTE9ORSA9IExhIHZhbGV1ciAiezF9IiBkZSBsJydhdHRyaWJ1dCAiezB9IiBuZSBkb2l0IHBhcyBcdTAwRUF0cmUgbW9kaWZpXHUwMEU5ZSBwYXIgbm9ybWFsaXNhdGlvbiAoZXQgZGV2ZW5pciAiezJ9IikgZGFucyB1biBkb2N1bWVudCBhdXRvbm9tZS4KLSAgICAgICAgTVNHX0NPTlRFTlRfSU5DT01QTEVURSA9IExlIGNvbnRlbnUgZHUgdHlwZSBkJydcdTAwRTlsXHUwMEU5bWVudCAiezB9IiBlc3QgaW5jb21wbGV0LiBJbCBkb2l0IGNvcnJlc3BvbmRyZSBcdTAwRTAgInsxfSIuCi0gICAgICAgIE1TR19DT05URU5UX0lOVkFMSUQgPSBMZSBjb250ZW51IGR1IHR5cGUgZCcnXHUwMEU5bFx1MDBFOW1lbnQgInswfSIgZG9pdCBjb3JyZXNwb25kcmUgXHUwMEUwICJ7MX0iLgotICAgICAgICBNU0dfQ09OVEVOVF9JTlZBTElEX1NQRUNJRklFRCA9IExlIGNvbnRlbnUgZHUgdHlwZSBkJydcdTAwRTlsXHUwMEU5bWVudCAiezB9IiBkb2l0IGNvcnJlc3BvbmRyZSBcdTAwRTAgInsxfSIuIExlcyBlbmZhbnRzIGRlIHR5cGUgInsyfSIgbmUgc29udCBwYXMgYXV0b3Jpc1x1MDBFOXMuCi0gICAgICAgIE1TR19ERUZBVUxURURfQVRUUklCVVRFX05PVF9TUEVDSUZJRUQgPSBMJydhdHRyaWJ1dCAiezF9IiBkdSB0eXBlIGQnJ1x1MDBFOWxcdTAwRTltZW50ICJ7MH0iIGEgdW5lIHZhbGV1ciBwYXIgZFx1MDBFOWZhdXQgZXQgZG9pdCBcdTAwRUF0cmUgc3BcdTAwRTljaWZpXHUwMEU5IGRhbnMgdW4gZG9jdW1lbnQgYXV0b25vbWUuCi0gICAgICAgIE1TR19EVVBMSUNBVEVfQVRUREVGID0gTCcnYXR0cmlidXQgInsxfSIgZXN0IGRcdTAwRTlqXHUwMEUwIGRcdTAwRTljbGFyXHUwMEU5IHBvdXIgbGUgdHlwZSBkJydcdTAwRTlsXHUwMEU5bWVudCAiezB9Ii4KLSAgICAgICAgTVNHX0VMRU1FTlRfQUxSRUFEWV9ERUNMQVJFRCA9IExlIHR5cGUgZCcnXHUwMEU5bFx1MDBFOW1lbnQgInswfSIgbmUgZG9pdCBwYXMgXHUwMEVBdHJlIGRcdTAwRTljbGFyXHUwMEU5IHBsdXNpZXVycyBmb2lzLgotICAgICAgICBNU0dfRUxFTUVOVF9OT1RfREVDTEFSRUQgPSBMZSB0eXBlIGQnJ1x1MDBFOWxcdTAwRTltZW50ICJ7MH0iIGRvaXQgXHUwMEVBdHJlIGRcdTAwRTljbGFyXHUwMEU5LgotICAgICAgICBNU0dfR1JBTU1BUl9OT1RfRk9VTkQgPSBMZSBkb2N1bWVudCBuJ2VzdCBwYXMgdmFsaWRlIDogYXVjdW5lIGdyYW1tYWlyZSBkXHUwMEU5dGVjdFx1MDBFOWUuCi0gICAgICAgIE1TR19FTEVNRU5UX1dJVEhfSURfUkVRVUlSRUQgPSBVbiBcdTAwRTlsXHUwMEU5bWVudCBhdmVjIGwnJ2lkZW50aWZpY2F0ZXVyICJ7MH0iIGRvaXQgZmlndXJlciBkYW5zIGxlIGRvY3VtZW50LgotICAgICAgICBNU0dfRVhURVJOQUxfRU5USVRZX05PVF9QRVJNSVRURUQgPSBMYSByXHUwMEU5Zlx1MDBFOXJlbmNlIFx1MDBFMCBsJydlbnRpdFx1MDBFOSBleHRlcm5lICJ7MH0iIG4nJ2VzdCBwYXMgYXV0b3Jpc1x1MDBFOWUgZGFucyBsZSBkb2N1bWVudCBhdXRvbm9tZS4KLSAgICAgICAgTVNHX0ZJWEVEX0FUVFZBTFVFX0lOVkFMSUQgPSBMJydhdHRyaWJ1dCAiezF9IiBkZSB2YWxldXIgInsyfSIgZG9pdCBhdm9pciB1bmUgdmFsZXVyIGRlICJ7M30iLgotICAgICAgICBNU0dfTU9SRV9USEFOX09ORV9JRF9BVFRSSUJVVEUgPSBMZSB0eXBlIGQnJ1x1MDBFOWxcdTAwRTltZW50ICJ7MH0iIGEgZFx1MDBFOWpcdTAwRTAgbCcnYXR0cmlidXQgInsxfSIgZGUgdHlwZSBJRC4gVW4gZGV1eGlcdTAwRThtZSBhdHRyaWJ1dCAiezJ9IiBkZSB0eXBlIElEIG4nJ2VzdCBwYXMgYXV0b3Jpc1x1MDBFOS4KLSAgICAgICAgTVNHX01PUkVfVEhBTl9PTkVfTk9UQVRJT05fQVRUUklCVVRFID0gTGUgdHlwZSBkJydcdTAwRTlsXHUwMEU5bWVudCAiezB9IiBhIGRcdTAwRTlqXHUwMEUwIGwnJ2F0dHJpYnV0ICJ7MX0iIGRlIHR5cGUgTk9UQVRJT04uIFVuIGRldXhpXHUwMEU4bWUgYXR0cmlidXQgInsyfSIgZGUgdHlwZSBOT1RBVElPTiBuJydlc3QgcGFzIGF1dG9yaXNcdTAwRTkuCi0gICAgICAgIE1TR19OT1RBVElPTl9OT1RfREVDTEFSRURfRk9SX05PVEFUSU9OVFlQRV9BVFRSSUJVVEUgPSBMYSBub3RhdGlvbiAiezF9IiBkb2l0IFx1MDBFQXRyZSBkXHUwMEU5Y2xhclx1MDBFOWUgbG9yc3F1JydlbGxlIGVzdCByXHUwMEU5Zlx1MDBFOXJlbmNcdTAwRTllIGRhbnMgbGEgbGlzdGUgZGVzIHR5cGVzIGRlIG5vdGF0aW9uIGRlIGwnJ2F0dHJpYnV0ICJ7MH0iLgotICAgICAgICBNU0dfTk9UQVRJT05fTk9UX0RFQ0xBUkVEX0ZPUl9VTlBBUlNFRF9FTlRJVFlERUNMID0gTGEgbm90YXRpb24gInsxfSIgZG9pdCBcdTAwRUF0cmUgZFx1MDBFOWNsYXJcdTAwRTllIGxvcnNxdScnZWxsZSBlc3Qgclx1MDBFOWZcdTAwRTlyZW5jXHUwMEU5ZSBkYW5zIGxhIGRcdTAwRTljbGFyYXRpb24gZCcnZW50aXRcdTAwRTkgbm9uIGFuYWx5c1x1MDBFOWUgcG91ciAiezB9Ii4KLSAgICAgICAgTVNHX1JFRkVSRU5DRV9UT19FWFRFUk5BTExZX0RFQ0xBUkVEX0VOVElUWV9XSEVOX1NUQU5EQUxPTkUgPSBMYSByXHUwMEU5Zlx1MDBFOXJlbmNlIFx1MDBFMCBsJydlbnRpdFx1MDBFOSAiezB9IiBkXHUwMEU5Y2xhclx1MDBFOWUgZGFucyB1bmUgZW50aXRcdTAwRTkgYW5hbHlzXHUwMEU5ZSBleHRlcm5lIG4nJ2VzdCBwYXMgYXV0b3Jpc1x1MDBFOWUgZGFucyB1biBkb2N1bWVudCBhdXRvbm9tZS4KLSAgICAgICAgTVNHX1JFUVVJUkVEX0FUVFJJQlVURV9OT1RfU1BFQ0lGSUVEID0gTCcnYXR0cmlidXQgInsxfSIgZXN0IG9ibGlnYXRvaXJlIGV0IGRvaXQgXHUwMEVBdHJlIHNwXHUwMEU5Y2lmaVx1MDBFOSBwb3VyIGxlIHR5cGUgZCcnXHUwMEU5bFx1MDBFOW1lbnQgInswfSIuCi0gICAgICAgIE1TR19XSElURV9TUEFDRV9JTl9FTEVNRU5UX0NPTlRFTlRfV0hFTl9TVEFOREFMT05FID0gQXVjdW4gZXNwYWNlIG5lIGRvaXQgZmlndXJlciBlbnRyZSBsZXMgXHUwMEU5bFx1MDBFOW1lbnRzIGRcdTAwRTljbGFyXHUwMEU5cyBkYW5zIHVuZSBlbnRpdFx1MDBFOSBhbmFseXNcdTAwRTllIGV4dGVybmUgYXZlYyBsZSBjb250ZW51IGRlcyBcdTAwRTlsXHUwMEU5bWVudHMgZGFucyB1biBkb2N1bWVudCBhdXRvbm9tZS4KLSAgICAgICAgTk1UT0tFTkludmFsaWQgPSBMYSB2YWxldXIgZCcnYXR0cmlidXQgInswfSIgZGUgdHlwZSBOTVRPS0VOIGRvaXQgY29ycmVzcG9uZHJlIFx1MDBFMCB1biBqZXRvbiBkZSBub20uCi0gICAgICAgIE5NVE9LRU5TSW52YWxpZCA9IExhIHZhbGV1ciBkJydhdHRyaWJ1dCAiezB9IiBkZSB0eXBlIE5NVE9LRU5TIGRvaXQgY29ycmVzcG9uZHJlIFx1MDBFMCBhdSBtb2lucyB1biBqZXRvbiBkZSBub20uCi0gICAgICAgIE5vTm90YXRpb25PbkVtcHR5RWxlbWVudCA9IExlIHR5cGUgZCcnXHUwMEU5bFx1MDBFOW1lbnQgInswfSIgZFx1MDBFOWNsYXJcdTAwRTkgRU1QVFkgbmUgcGV1dCBwYXMgZFx1MDBFOWNsYXJlciB1biBhdHRyaWJ1dCAiezF9IiBkZSB0eXBlIE5PVEFUSU9OLgotICAgICAgICBSb290RWxlbWVudFR5cGVNdXN0TWF0Y2hEb2N0eXBlZGVjbCA9IEwnJ1x1MDBFOWxcdTAwRTltZW50IHJhY2luZSBkZSBkb2N1bWVudCAiezF9IiBkb2l0IGNvcnJlc3BvbmRyZSBcdTAwRTAgbGEgcmFjaW5lIERPQ1RZUEUgInswfSIuCi0gICAgICAgIFVuZGVjbGFyZWRFbGVtZW50SW5Db250ZW50U3BlYyA9IExlIG1vZFx1MDBFOGxlIGRlIGNvbnRlbnUgZGUgbCcnXHUwMEU5bFx1MDBFOW1lbnQgInswfSIgZmFpdCByXHUwMEU5Zlx1MDBFOXJlbmNlIFx1MDBFMCBsJydcdTAwRTlsXHUwMEU5bWVudCBub24gZFx1MDBFOWNsYXJcdTAwRTkgInsxfSIuCi0gICAgICAgIFVuaXF1ZU5vdGF0aW9uTmFtZSA9IExhIGRcdTAwRTljbGFyYXRpb24gZGUgbGEgbm90YXRpb24gInswfSIgbicnZXN0IHBhcyB1bmlxdWUuIFVuZSB2YWxldXIgTmFtZSBkb25uXHUwMEU5ZSBuZSBkb2l0IHBhcyBcdTAwRUF0cmUgZFx1MDBFOWNsYXJcdTAwRTllIGRhbnMgcGx1c2lldXJzIGRcdTAwRTljbGFyYXRpb25zIGRlIG5vdGF0aW9uLgotICAgICAgICBFTlRJVFlGYWlsZWRJbml0aWFsaXplR3JhbW1hciA9ICBWYWxpZGV1ciBFTlRJVFlEYXRhdHlwZSA6IFx1MDBFOWNoZWMuIEJlc29pbiBkJ2FwcGVsZXIgdW5lIG1cdTAwRTl0aG9kZSBkJ2luaXRpYWxpc2F0aW9uIGF2ZWMgdW5lIHJcdTAwRTlmXHUwMEU5cmVuY2UgZGUgZ3JhbW1haXJlIHZhbGlkZS4gXHQKLSAgICAgICAgRU5USVRZTm90VW5wYXJzZWQgPSBMYSB2YWxldXIgRU5USVRZICJ7MH0iIGVzdCBhbmFseXNcdTAwRTllLgotICAgICAgICBFTlRJVFlOb3RWYWxpZCA9IExhIHZhbGV1ciBFTlRJVFkgInswfSIgbicnZXN0IHBhcyB2YWxpZGUuCi0gICAgICAgIEVtcHR5TGlzdCA9IFVuZSB2YWxldXIgZGUgdHlwZSBFTlRJVElFUywgSURSRUZTIGV0IE5NVE9LRU5TIG5lIHBldXQgcGFzIGNvcnJlc3BvbmRyZSBcdTAwRTAgdW5lIGxpc3RlIHZpZGUuCi0KLSMgRW50aXR5IHJlbGF0ZWQgbWVzc2FnZXMKLSMgMy4xIFN0YXJ0LVRhZ3MsIEVuZC1UYWdzLCBhbmQgRW1wdHktRWxlbWVudCBUYWdzCi0gICAgICAgIFJlZmVyZW5jZVRvRXh0ZXJuYWxFbnRpdHkgPSBMYSByXHUwMEU5Zlx1MDBFOXJlbmNlIGQnJ2VudGl0XHUwMEU5IGV4dGVybmUgIiZ7MH07IiBuJydlc3QgcGFzIGF1dG9yaXNcdTAwRTllIGRhbnMgdW5lIHZhbGV1ciBkJydhdHRyaWJ1dC4KLSAgICAgICAgQWNjZXNzRXh0ZXJuYWxEVEQgPSBEVEQgZXh0ZXJuZSA6IFx1MDBFOWNoZWMgZGUgbGEgbGVjdHVyZSBkZSBsYSBEVEQgZXh0ZXJuZSAnJ3swfScnLCBjYXIgbCcnYWNjXHUwMEU4cyAnJ3sxfScnIG4nJ2VzdCBwYXMgYXV0b3Jpc1x1MDBFOSBlbiByYWlzb24gZCcndW5lIHJlc3RyaWN0aW9uIGRcdTAwRTlmaW5pZSBwYXIgbGEgcHJvcHJpXHUwMEU5dFx1MDBFOSBhY2Nlc3NFeHRlcm5hbERURC4KLSAgICAgICAgQWNjZXNzRXh0ZXJuYWxFbnRpdHkgPSBFbnRpdFx1MDBFOSBleHRlcm5lIDogXHUwMEU5Y2hlYyBkZSBsYSBsZWN0dXJlIGR1IGRvY3VtZW50IGV4dGVybmUgJyd7MH0nJywgY2FyIGwnJ2FjY1x1MDBFOHMgJyd7MX0nJyBuJydlc3QgcGFzIGF1dG9yaXNcdTAwRTkgZW4gcmFpc29uIGQnJ3VuZSByZXN0cmljdGlvbiBkXHUwMEU5ZmluaWUgcGFyIGxhIHByb3ByaVx1MDBFOXRcdTAwRTkgYWNjZXNzRXh0ZXJuYWxEVEQuCi0KLSMgNC4xIENoYXJhY3RlciBhbmQgRW50aXR5IFJlZmVyZW5jZXMKLSAgICAgICAgRW50aXR5Tm90RGVjbGFyZWQgPSBMJydlbnRpdFx1MDBFOSAiezB9IiBcdTAwRTl0YWl0IHJcdTAwRTlmXHUwMEU5cmVuY1x1MDBFOWUsIG1haXMgcGFzIGRcdTAwRTljbGFyXHUwMEU5ZS4KLSAgICAgICAgUmVmZXJlbmNlVG9VbnBhcnNlZEVudGl0eSA9IExhIHJcdTAwRTlmXHUwMEU5cmVuY2UgZCcnZW50aXRcdTAwRTkgbm9uIGFuYWx5c1x1MDBFOWUgIiZ7MH07IiBuJydlc3QgcGFzIGF1dG9yaXNcdTAwRTllLgotICAgICAgICBSZWN1cnNpdmVSZWZlcmVuY2UgPSBSXHUwMEU5Zlx1MDBFOXJlbmNlIGQnJ2VudGl0XHUwMEU5IHJcdTAwRTljdXJzaXZlICJ7MH0iLiAoQ2hlbWluIGRlIHJcdTAwRTlmXHUwMEU5cmVuY2UgOiB7MX0pLAotICAgICAgICBSZWN1cnNpdmVHZW5lcmFsUmVmZXJlbmNlID0gUlx1MDBFOWZcdTAwRTlyZW5jZSBkJydlbnRpdFx1MDBFOSBnXHUwMEU5blx1MDBFOXJhbGUgclx1MDBFOWN1cnNpdmUgIiZ7MH07Ii4gKENoZW1pbiBkZSByXHUwMEU5Zlx1MDBFOXJlbmNlIDogezF9KSwKLSAgICAgICAgUmVjdXJzaXZlUEVSZWZlcmVuY2UgPSBSXHUwMEU5Zlx1MDBFOXJlbmNlIGQnJ2VudGl0XHUwMEU5IGRlIHBhcmFtXHUwMEU4dHJlIHJcdTAwRTljdXJzaXZlICIlezB9OyIuIChDaGVtaW4gZGUgclx1MDBFOWZcdTAwRTlyZW5jZSA6IHsxfSksCi0jIDQuMy4zIENoYXJhY3RlciBFbmNvZGluZyBpbiBFbnRpdGllcwotICAgICAgICBFbmNvZGluZ05vdFN1cHBvcnRlZCA9IEwnJ2VuY29kYWdlICJ7MH0iIG4nJ2VzdCBwYXMgcHJpcyBlbiBjaGFyZ2UuCi0gICAgICAgIEVuY29kaW5nUmVxdWlyZWQgPSBVbmUgZW50aXRcdTAwRTkgYW5hbHlzXHUwMEU5ZSBzYW5zIGVuY29kYWdlIFVURi04IG91IFVURi0xNiBkb2l0IGNvbnRlbmlyIHVuZSBkXHUwMEU5Y2xhcmF0aW9uIGQnZW5jb2RhZ2UuCi0gICAgICAgIAotIyBOYW1lc3BhY2VzIHN1cHBvcnQKLSMgNC4gVXNpbmcgUXVhbGlmaWVkIE5hbWVzCi0gICAgICAgIElsbGVnYWxRTmFtZSA9IEwnXHUwMEU5bFx1MDBFOW1lbnQgb3UgbCdhdHRyaWJ1dCBuZSBjb3JyZXNwb25kIHBhcyBcdTAwRTAgbGEgcHJvZHVjdGlvbiBRTmFtZSA6IFFOYW1lOjo9KE5DTmFtZSc6Jyk/TkNOYW1lLiAKLSAgICAgICAgRWxlbWVudFhNTE5TUHJlZml4ID0gTCcnXHUwMEU5bFx1MDBFOW1lbnQgInswfSIgbmUgcGV1dCBwYXMgYXZvaXIgInhtbG5zIiBjb21tZSBwclx1MDBFOWZpeGUuCi0gICAgICAgIEVsZW1lbnRQcmVmaXhVbmJvdW5kID0gTGUgcHJcdTAwRTlmaXhlICJ7MH0iIGRlIGwnJ1x1MDBFOWxcdTAwRTltZW50ICJ7MX0iIG4nJ2VzdCBwYXMgbGlcdTAwRTkuCi0gICAgICAgIEF0dHJpYnV0ZVByZWZpeFVuYm91bmQgPSBMZSBwclx1MDBFOWZpeGUgInsyfSIgZGUgbCcnYXR0cmlidXQgInsxfSIgYXNzb2NpXHUwMEU5IFx1MDBFMCB1biB0eXBlIGQnJ1x1MDBFOWxcdTAwRTltZW50ICJ7MH0iIG4nJ2VzdCBwYXMgbGlcdTAwRTkuCi0gICAgICAgIEVtcHR5UHJlZml4ZWRBdHROYW1lID0gTGEgdmFsZXVyIGRlIGwnJ2F0dHJpYnV0ICJ7MH0iIG4nJ2VzdCBwYXMgdmFsaWRlLiBMZXMgbGlhaXNvbnMgZCcnZXNwYWNlcyBkZSBub21zIHByXHUwMEU5Zml4XHUwMEU5cyBuZSBwZXV2ZW50IHBhcyBcdTAwRUF0cmUgdmlkZXMuCi0gICAgICAgIFByZWZpeERlY2xhcmVkID0gTGUgcHJcdTAwRTlmaXhlIGQnJ2VzcGFjZSBkZSBub21zICJ7MH0iIG4nJ1x1MDBFOXRhaXQgcGFzIGRcdTAwRTljbGFyXHUwMEU5LgotICAgICAgICBDYW50QmluZFhNTE5TID0gTGUgcHJcdTAwRTlmaXhlICJ4bWxucyIgbmUgcGV1dCBwYXMgXHUwMEVBdHJlIGxpXHUwMEU5IFx1MDBFMCB1biBlc3BhY2UgZGUgbm9tcyBkZSBmYVx1MDBFN29uIGV4cGxpY2l0ZSwgcGFzIHBsdXMgcXVlIGwnZXNwYWNlIGRlIG5vbXMgZGUgInhtbG5zIiBcdTAwRTAgdW4gcHJcdTAwRTlmaXhlIHF1ZWxjb25xdWUuCi0gICAgICAgIENhbnRCaW5kWE1MID0gTGUgcHJcdTAwRTlmaXhlICJ4bWwiIG5lIHBldXQgcGFzIFx1MDBFQXRyZSBsaVx1MDBFOSBcdTAwRTAgdW4gYXV0cmUgZXNwYWNlIGRlIG5vbXMgcXVlIHNvbiBlc3BhY2UgZGUgbm9tcyBoYWJpdHVlbC4gTCdlc3BhY2UgZGUgbm9tcyBkZSAieG1sIiBuZSBwZXV0IHBhcyBub24gcGx1cyBcdTAwRUF0cmUgbGlcdTAwRTkgXHUwMEUwIHVuIGF1dHJlIHByXHUwMEU5Zml4ZSBxdWUgInhtbCIuCi0gICAgICAgIE1TR19BVFRfREVGQVVMVF9JTlZBTElEID0gTGEgdmFsZXVyIHBhciBkXHUwMEU5ZmF1dCAiezF9IiBkZSBsJydhdHRyaWJ1dCAiezB9IiBuJydlc3QgcGFzIGFkbWlzZSBjb25mb3JtXHUwMEU5bWVudCBhdXggY29udHJhaW50ZXMgbGV4aWNhbGVzIGRlIGNlIHR5cGUgZCcnYXR0cmlidXQuCi0KLSMgUkVWSVNJVDogVGhlc2UgbmVlZCBtZXNzYWdlcwotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQUZURVJfU1lTVEVNTElURVJBTF9JTl9FWFRFUk5BTElEPU1TR19TUEFDRV9SRVFVSVJFRF9BRlRFUl9TWVNURU1MSVRFUkFMX0lOX0VYVEVSTkFMSUQKLSAgICAgICAgT3BlblF1b3RlTWlzc2luZ0luRGVjbD1PcGVuUXVvdGVNaXNzaW5nSW5EZWNsCi0gICAgICAgIEludmFsaWRDaGFySW5MaXRlcmFsPUludmFsaWRDaGFySW5MaXRlcmFsCi0KLQotIyBJbXBsZW1lbnRhdGlvbiBsaW1pdHMKLSAgICAgICAgRW50aXR5RXhwYW5zaW9uTGltaXQ9SkFYUDAwMDEwMDAxIDogTCcnYW5hbHlzZXVyIGEgcmVuY29udHJcdTAwRTkgcGx1cyBkZSAiezB9IiBkXHUwMEU5dmVsb3BwZW1lbnRzIGQnJ2VudGl0XHUwMEU5IGRhbnMgY2UgZG9jdW1lbnQuIElsIHMnJ2FnaXQgZGUgbGEgbGltaXRlIGltcG9zXHUwMEU5ZSBwYXIgbGUgSkRLLgotICAgICAgICBFbGVtZW50QXR0cmlidXRlTGltaXQ9SkFYUDAwMDEwMDAyIDogTCcnXHUwMEU5bFx1MDBFOW1lbnQgInswfSIgYSBwbHVzIGRlICJ7MX0iIGF0dHJpYnV0cy4gInsxfSIgZXN0IGxhIGxpbWl0ZSBpbXBvc1x1MDBFOWUgcGFyIGxlIEpESy4KLSAgICAgICAgTWF4RW50aXR5U2l6ZUxpbWl0PUpBWFAwMDAxMDAwMyA6IExhIGxvbmd1ZXVyIGRlIGwnJ2VudGl0XHUwMEU5ICJ7MH0iIGVzdCBkZSAiezF9Ii4gQ2V0dGUgdmFsZXVyIGRcdTAwRTlwYXNzZSBsYSBsaW1pdGUgZGUgInsyfSIgZFx1MDBFOWZpbmllIHBhciAiezN9Ii4KLSAgICAgICAgVG90YWxFbnRpdHlTaXplTGltaXQ9SkFYUDAwMDEwMDA0IDogTGEgdGFpbGxlIGN1bXVsXHUwMEU5ZSBkZXMgZW50aXRcdTAwRTlzIGVzdCAiezB9IiBldCBkXHUwMEU5cGFzc2UgbGEgbGltaXRlIGRlICJ7MX0iIGRcdTAwRTlmaW5pZSBwYXIgInsyfSIuCi0gICAgICAgIE1heFhNTE5hbWVMaW1pdD1KQVhQMDAwMTAwMDUgOiBMYSBsb25ndWV1ciBkZSBsJydlbnRpdFx1MDBFOSAiezB9IiBlc3QgZGUgInsxfSIuIENldHRlIHZhbGV1ciBkXHUwMEU5cGFzc2UgbGEgbGltaXRlIGRlICJ7Mn0iIGRcdTAwRTlmaW5pZSBwYXIgInszfSIuCi0gICAgICAgIE1heEVsZW1lbnREZXB0aExpbWl0PUpBWFAwMDAxMDAwNiA6IGwnJ1x1MDBFOWxcdTAwRTltZW50ICJ7MH0iIGEgdW5lIHByb2ZvbmRldXIgZGUgInsxfSIgcXVpIGRcdTAwRTlwYXNzZSBsYSBsaW1pdGUgZGUgInsyfSIgZFx1MDBFOWZpbmllIHBhciAiezN9Ii4KLSAgICAgICAgRW50aXR5UmVwbGFjZW1lbnRMaW1pdD1KQVhQMDAwMTAwMDcgOiBMZSBub21icmUgdG90YWwgZGUgbm9ldWRzIGRhbnMgbGVzIHJcdTAwRTlmXHUwMEU5cmVuY2VzIGQnJ2VudGl0XHUwMEU5IGVzdCAiezB9Iiwgc29pdCBwbHVzIHF1ZSBsYSBsaW1pdGUgZGUgInsxfSIgZFx1MDBFOWZpbmllIHBhciAiezJ9Ii4KLQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MTWVzc2FnZXNfaXQucHJvcGVydGllcyBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hNTE1lc3NhZ2VzX2l0LnByb3BlcnRpZXMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDFjY2E2MDQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MTWVzc2FnZXNfaXQucHJvcGVydGllcworKysgL2Rldi9udWxsCkBAIC0xLDMwNSArMCwwIEBACi0jIFRoaXMgZmlsZSBjb250YWlucyBlcnJvciBhbmQgd2FybmluZyBtZXNzYWdlcyByZWxhdGVkIHRvIFhNTAotIyBUaGUgbWVzc2FnZXMgYXJlIGFycmFuZ2VkIGluIGtleSBhbmQgdmFsdWUgdHVwbGVzIGluIGEgTGlzdFJlc291cmNlQnVuZGxlLgotIwotIyBAdmVyc2lvbgotCi0gICAgICAgIEJhZE1lc3NhZ2VLZXkgPSBJbXBvc3NpYmlsZSB0cm92YXJlIGlsIG1lc3NhZ2dpbyBkaSBlcnJvcmUgY29ycmlzcG9uZGVudGUgYWxsYSBjaGlhdmUgZGkgbWVzc2FnZ2lvLgotICAgICAgICBGb3JtYXRGYWlsZWQgPSBTaSBcdTAwRTggdmVyaWZpY2F0byB1biBlcnJvcmUgaW50ZXJubyBkdXJhbnRlIGxhIGZvcm1hdHRhemlvbmUgZGVsIHNlZ3VlbnRlIG1lc3NhZ2dpbzpcbiAgCi0gICAgICAgIAotIyBEb2N1bWVudCBtZXNzYWdlcwotICAgICAgICBQcmVtYXR1cmVFT0Y9RmluZSBkZWwgZmlsZSBhbnRpY2lwYXRhLgotIyAyLjEgV2VsbC1Gb3JtZWQgWE1MIERvY3VtZW50cwotICAgICAgICBSb290RWxlbWVudFJlcXVpcmVkID0gTCdlbGVtZW50byByYWRpY2UgXHUwMEU4IG9iYmxpZ2F0b3JpbyBpbiB1biBkb2N1bWVudG8gY29uIGZvcm1hdG8gY29ycmV0dG8uCi0jIDIuMiBDaGFyYWN0ZXJzCi0KLSAgICAgICAgSW52YWxpZENoYXJJbkNEU2VjdCA9IFx1MDBDOCBzdGF0byB0cm92YXRvIHVuIGNhcmF0dGVyZSBYTUwgbm9uIHZhbGlkbyAoVW5pY29kZTogMHh7MH0pIG5lbGxhIHNlemlvbmUgQ0RBVEEuCi0gICAgICAgIEludmFsaWRDaGFySW5Db250ZW50ID0gXHUwMEM4IHN0YXRvIHRyb3ZhdG8gdW4gY2FyYXR0ZXJlIFhNTCBub24gdmFsaWRvIChVbmljb2RlOiAweHswfSkgbmVsIGNvbnRlbnV0byBkZWxsJydlbGVtZW50byBkZWwgZG9jdW1lbnRvLgotICAgICAgICBUd29Db2xvbnNJblFOYW1lID0gXHUwMEM4IHN0YXRvIHRyb3ZhdG8gdW4gc2Vjb25kbyBjYXJhdHRlcmUgZGVpIGR1ZSBwdW50aSAoJzonKSBub24gdmFsaWRvIG5lbCB0aXBvIGRpIGVsZW1lbnRvIG8gbmVsIG5vbWUgYXR0cmlidXRvLgotICAgICAgICBDb2xvbk5vdExlZ2FsV2l0aE5TID0gTm9uIHNvbm8gY29uc2VudGl0aSBpIGR1ZSBwdW50aSBuZWwgbm9tZSAiezB9IiBzZSBzb25vIGFiaWxpdGF0aSBnbGkgc3BhemkgZGkgbm9taS4KLSAgICAgICAgSW52YWxpZENoYXJJbk1pc2MgPSBcdTAwQzggc3RhdG8gdHJvdmF0byB1biBjYXJhdHRlcmUgWE1MIG5vbiB2YWxpZG8gKFVuaWNvZGU6IDB4ezB9KSBuZWwgbWFya3VwIGRvcG8gbGEgZmluZSBkZWwgY29udGVudXRvIGRlbGwnJ2VsZW1lbnRvLgotICAgICAgICBJbnZhbGlkQ2hhckluUHJvbG9nID0gXHUwMEM4IHN0YXRvIHRyb3ZhdG8gdW4gY2FyYXR0ZXJlIFhNTCBub24gdmFsaWRvIChVbmljb2RlOiAweHswfSkgbmVsIHByb2xvZ28gZGVsIGRvY3VtZW50by4KLSAgICAgICAgSW52YWxpZENoYXJJblhNTERlY2wgPSBcdTAwQzggc3RhdG8gdHJvdmF0byB1biBjYXJhdHRlcmUgWE1MIG5vbiB2YWxpZG8gKFVuaWNvZGU6IDB4ezB9KSBuZWxsYSBkaWNoaWFyYXppb25lIFhNTC4KLSMgMi40IENoYXJhY3RlciBEYXRhIGFuZCBNYXJrdXAKLSAgICAgICAgQ0RFbmRJbkNvbnRlbnQgPSBMYSBzZXF1ZW56YSBkaSBjYXJhdHRlcmkgIl1dPiIgbm9uIGRldmUgZXNzZXJlIHByZXNlbnRlIG5lbCBjb250ZW51dG8gYSBtZW5vIGNoZSBub24gc2lhIHV0aWxpenphdGEgcGVyIGNvbnRyYXNzZWduYXJlIGxhIGZpbmUgZGkgdW5hIHNlemlvbmUgQ0RBVEEuCi0jIDIuNyBDREFUQSBTZWN0aW9ucwotICAgICAgICBDRFNlY3RVbnRlcm1pbmF0ZWQgPSBMYSBzZXppb25lIENEQVRBIGRldmUgdGVybWluYXJlIGNvbiAiXV0+Ii4KLSMgMi44IFByb2xvZyBhbmQgRG9jdW1lbnQgVHlwZSBEZWNsYXJhdGlvbgotICAgICAgICBYTUxEZWNsTXVzdEJlRmlyc3QgPSBMYSBkaWNoaWFyYXppb25lIFhNTCBwdVx1MDBGMiBjb21wYXJpcmUgc29sbyBhbGwnaW5pemlvIGRlbCBkb2N1bWVudG8uCi0gICAgICAgIEVxUmVxdWlyZWRJblhNTERlY2wgPSBJbCBjYXJhdHRlcmUgJycgPSAnJyBkZXZlIHNlZ3VpcmUgInswfSIgbmVsbGEgZGljaGlhcmF6aW9uZSBYTUwuCi0gICAgICAgIFF1b3RlUmVxdWlyZWRJblhNTERlY2wgPSBJbCB2YWxvcmUgY2hlIHNlZ3VlICJ7MH0iIG5lbGxhIGRpY2hpYXJhemlvbmUgWE1MIGRldmUgZXNzZXJlIHVuYSBzdHJpbmdhIGNvbXByZXNhIHRyYSBhcGljaS4KLSAgICAgICAgWE1MRGVjbFVudGVybWluYXRlZCA9IExhIGRpY2hpYXJhemlvbmUgWE1MIGRldmUgdGVybWluYXJlIGNvbiAiPz4iLgotICAgICAgICBWZXJzaW9uSW5mb1JlcXVpcmVkID0gTGEgdmVyc2lvbmUgXHUwMEU4IG9iYmxpZ2F0b3JpYSBuZWxsYSBkaWNoaWFyYXppb25lIFhNTC4KLSAgICAgICAgU3BhY2VSZXF1aXJlZEJlZm9yZVZlcnNpb25JblhNTERlY2wgPSBcdTAwQzggcmljaGllc3RvIHVubyBzcGF6aW8gcHJpbWEgZGVsbCdhdHRyaWJ1dG8gcHNldWRvIGRlbGxhIHZlcnNpb25lIG5lbGxhIGRpY2hpYXJhemlvbmUgWE1MLgotICAgICAgICBTcGFjZVJlcXVpcmVkQmVmb3JlRW5jb2RpbmdJblhNTERlY2wgPSBcdTAwQzggcmljaGllc3RvIHVubyBzcGF6aW8gcHJpbWEgZGVsbCdhdHRyaWJ1dG8gcHNldWRvIGRpIGNvZGlmaWNhIG5lbGxhIGRpY2hpYXJhemlvbmUgWE1MLgotICAgICAgICBTcGFjZVJlcXVpcmVkQmVmb3JlU3RhbmRhbG9uZSA9IFx1MDBDOCByaWNoaWVzdG8gdW5vIHNwYXppbyBwcmltYSBkZWxsJ2F0dHJpYnV0byBwc2V1ZG8gZGkgY29kaWZpY2EgbmVsbGEgZGljaGlhcmF6aW9uZSBYTUwuCi0gICAgICAgIE1hcmt1cE5vdFJlY29nbml6ZWRJblByb2xvZyA9IElsIG1hcmt1cCBuZWwgZG9jdW1lbnRvIGNoZSBwcmVjZWRlIGwnZWxlbWVudG8gcmFkaWNlIGRldmUgYXZlcmUgdW4gZm9ybWF0byBjb3JyZXR0by4KLSAgICAgICAgTWFya3VwTm90UmVjb2duaXplZEluTWlzYyA9IElsIG1hcmt1cCBuZWwgZG9jdW1lbnRvIGNoZSBzZWd1ZSBsJ2VsZW1lbnRvIHJhZGljZSBkZXZlIGF2ZXJlIHVuIGZvcm1hdG8gY29ycmV0dG8uCi0gICAgICAgIEFscmVhZHlTZWVuRG9jdHlwZSA9IERvY3R5cGUgZ2lcdTAwRTAgcHJlc2VudGUuCi0gICAgICAgIERvY3R5cGVOb3RBbGxvd2VkID0gRE9DVFlQRSBub24gXHUwMEU4IGNvbnNlbnRpdG8gc2UgbGEgZnVuemlvbmUgImh0dHA6Ly9hcGFjaGUub3JnL3htbC9mZWF0dXJlcy9kaXNhbGxvdy1kb2N0eXBlLWRlY2wiIFx1MDBFOCBpbXBvc3RhdGEgc3UgdHJ1ZS4KLSAgICAgICAgQ29udGVudElsbGVnYWxJblByb2xvZyA9IElsIGNvbnRlbnV0byBub24gXHUwMEU4IGNvbnNlbnRpdG8gbmVsIHByb2xvZ28uCi0gICAgICAgIFJlZmVyZW5jZUlsbGVnYWxJblByb2xvZyA9IElsIHJpZmVyaW1lbnRvIG5vbiBcdTAwRTggY29uc2VudGl0byBuZWwgcHJvbG9nby4KLSMgVHJhaWxpbmcgTWlzYwotICAgICAgICBDb250ZW50SWxsZWdhbEluVHJhaWxpbmdNaXNjPUlsIGNvbnRlbnV0byBub24gXHUwMEU4IGNvbnNlbnRpdG8gbmVsbGEgc2V6aW9uZSBmaW5hbGUuCi0gICAgICAgIFJlZmVyZW5jZUlsbGVnYWxJblRyYWlsaW5nTWlzYz1JbCByaWZlcmltZW50byBub24gXHUwMEU4IGNvbnNlbnRpdG8gbmVsbGEgc2V6aW9uZSBmaW5hbGUuCi0gICAgICAgIAotIyAyLjkgU3RhbmRhbG9uZSBEb2N1bWVudCBEZWNsYXJhdGlvbgotICAgICAgICBTRERlY2xJbnZhbGlkID0gSWwgdmFsb3JlIGRlbGxhIGRpY2hpYXJhemlvbmUgZGVsIGRvY3VtZW50byBzdGFuZGFsb25lIGRldmUgZXNzZXJlICJ5ZXMiIG8gIm5vIiwgbm9uICJ7MH0iLgotICAgICAgICBTRERlY2xOYW1lSW52YWxpZCA9IElsIG5vbWUgc3RhbmRhbG9uZSBuZWxsYSBkaWNoaWFyYXppb25lIFhNTCBwb3RyZWJiZSBlc3NlcmUgc3RhdG8gZGlnaXRhdG8gaW4gbW9kbyBlcnJhdG8uCi0jIDIuMTIgTGFuZ3VhZ2UgSWRlbnRpZmljYXRpb24KLSAgICAgICAgWE1MTGFuZ0ludmFsaWQgPSBJbCB2YWxvcmUgZGVsbCcnYXR0cmlidXRvIHhtbDpsYW5nICJ7MH0iIFx1MDBFOCB1biBpZGVudGlmaWNhdGl2byBkaSBsaW5ndWEgbm9uIHZhbGlkby4KLSMgMy4gTG9naWNhbCBTdHJ1Y3R1cmVzCi0gICAgICAgIEVUYWdSZXF1aXJlZCA9IElsIHRpcG8gZGkgZWxlbWVudG8gInswfSIgZGV2ZSB0ZXJtaW5hcmUgY29uIGxhIGNvcnJpc3BvbmRlbnRlIHRhZyBmaW5hbGUgIjwvezB9PiIuCi0jIDMuMSBTdGFydC1UYWdzLCBFbmQtVGFncywgYW5kIEVtcHR5LUVsZW1lbnQgVGFncwotICAgICAgICBFbGVtZW50VW50ZXJtaW5hdGVkID0gSWwgdGlwbyBkaSBlbGVtZW50byAiezB9IiBkZXZlIGVzc2VyZSBzZWd1aXRvIGRhbGxlIHNwZWNpZmljaGUgZGkgYXR0cmlidXRvICI+IiBvICIvPiIuCi0gICAgICAgIEVxUmVxdWlyZWRJbkF0dHJpYnV0ZSA9IElsIG5vbWUgYXR0cmlidXRvICJ7MX0iIGFzc29jaWF0byBhIHVuIHRpcG8gZGkgZWxlbWVudG8gInswfSIgZGV2ZSBlc3NlcmUgc2VndWl0byBkYWwgY2FyYXR0ZXJlICcnID0gJycuCi0gICAgICAgIE9wZW5RdW90ZUV4cGVjdGVkID0gXHUwMEM4IHByZXZpc3RvIHVuIGFwaWNlIGRpIGFwZXJ0dXJhIHBlciBsJydhdHRyaWJ1dG8gInsxfSIgYXNzb2NpYXRvIGEgdW4gdGlwbyBkaSBlbGVtZW50byAiezB9Ii4KLSAgICAgICAgQ2xvc2VRdW90ZUV4cGVjdGVkID0gXHUwMEM4IHByZXZpc3RvIHVuIGFwaWNlIGRpIGNoaXVzdXJhIHBlciBsJydhdHRyaWJ1dG8gInsxfSIgYXNzb2NpYXRvIGEgdW4gdGlwbyBkaSBlbGVtZW50byAiezB9Ii4KLSAgICAgICAgQXR0cmlidXRlTm90VW5pcXVlID0gTCcnYXR0cmlidXRvICJ7MX0iIFx1MDBFOCBnaVx1MDBFMCBzdGF0byBzcGVjaWZpY2F0byBwZXIgbCcnZWxlbWVudG8gInswfSIuCi0gICAgICAgIEF0dHJpYnV0ZU5TTm90VW5pcXVlID0gTCcnYXR0cmlidXRvICJ7MX0iIGFzc29jaWF0byBhbGxvIHNwYXppbyBkaSBub21pICJ7Mn0iIFx1MDBFOCBnaVx1MDBFMCBzdGF0byBzcGVjaWZpY2F0byBwZXIgbCcnZWxlbWVudG8gInswfSIuCi0gICAgICAgIEVUYWdVbnRlcm1pbmF0ZWQgPSBMYSB0YWcgZmluYWxlIHBlciBpbCB0aXBvIGRpIGVsZW1lbnRvICJ7MH0iIGRldmUgdGVybWluYXJlIGNvbiB1biBkZWxpbWl0YXRvcmUgJyc+JycuCi0gICAgICAgIE1hcmt1cE5vdFJlY29nbml6ZWRJbkNvbnRlbnQgPSBJbCBjb250ZW51dG8gZGVnbGkgZWxlbWVudGkgZGV2ZSBlc3NlcmUgY29tcG9zdG8gZGEgZGF0aSBvIG1hcmt1cCBkaSBjYXJhdHRlcmkgY29uIGZvcm1hdG8gY29ycmV0dG8uCi0gICAgICAgIERvY3R5cGVJbGxlZ2FsSW5Db250ZW50ID0gRE9DVFlQRSBub24gXHUwMEU4IGNvbnNlbnRpdG8gbmVsIGNvbnRlbnV0by4KLSMgNC4xIENoYXJhY3RlciBhbmQgRW50aXR5IFJlZmVyZW5jZXMKLSAgICAgICAgUmVmZXJlbmNlVW50ZXJtaW5hdGVkID0gSWwgcmlmZXJpbWVudG8gZGV2ZSB0ZXJtaW5hcmUgY29uIHVuIGRlbGltaXRhdG9yZSAnOycuCi0jIDQuMy4yIFdlbGwtRm9ybWVkIFBhcnNlZCBFbnRpdGllcwotICAgICAgICBSZWZlcmVuY2VOb3RJbk9uZUVudGl0eSA9IElsIHJpZmVyaW1lbnRvIGRldmUgZXNzZXJlIGNvbXByZXNvIGNvbXBsZXRhbWVudGUgYWxsJ2ludGVybm8gZGVsbGEgc3Rlc3NhIGVudGl0XHUwMEUwIGFuYWxpenphdGEuCi0gICAgICAgIEVsZW1lbnRFbnRpdHlNaXNtYXRjaCA9IEwnJ2VsZW1lbnRvICJ7MH0iIGRldmUgaW5pemlhcmUgZSBmaW5pcmUgY29uIGxhIHN0ZXNzYSBlbnRpdFx1MDBFMC4KLSAgICAgICAgTWFya3VwRW50aXR5TWlzbWF0Y2g9TGUgc3RydXR0dXJlIGRpIGRvY3VtZW50aSBYTUwgZGV2b25vIGluaXppYXJlIGUgZmluaXJlIGNvbiBsYSBzdGVzc2EgZW50aXRcdTAwRTAuCi0gICAgICAgIAotIyBNZXNzYWdlcyBjb21tb24gdG8gRG9jdW1lbnQgYW5kIERURAotIyAyLjIgQ2hhcmFjdGVycwotICAgICAgICBJbnZhbGlkQ2hhckluQXR0VmFsdWUgPSBcdTAwQzggc3RhdG8gdHJvdmF0byB1biBjYXJhdHRlcmUgWE1MIG5vbiB2YWxpZG8gKFVuaWNvZGU6IDB4ezJ9KSBuZWwgdmFsb3JlIGRlbGwnJ2F0dHJpYnV0byAiezF9Ii4gTCcnZWxlbWVudG8gXHUwMEU4ICJ7MH0iLgotICAgICAgICBJbnZhbGlkQ2hhckluQ29tbWVudCA9IFx1MDBDOCBzdGF0byB0cm92YXRvIHVuIGNhcmF0dGVyZSBYTUwgbm9uIHZhbGlkbyAoVW5pY29kZTogMHh7MH0pIG5lbCBjb21tZW50by4KLSAgICAgICAgSW52YWxpZENoYXJJblBJID0gXHUwMEM4IHN0YXRvIHRyb3ZhdG8gdW4gY2FyYXR0ZXJlIFhNTCBub24gdmFsaWRvIChVbmljb2RlOiAweHswfSkgbmVsbCcnaXN0cnV6aW9uZSBkaSBlbGFib3JhemlvbmUuCi0gICAgICAgIEludmFsaWRDaGFySW5JbnRlcm5hbFN1YnNldCA9IFx1MDBDOCBzdGF0byB0cm92YXRvIHVuIGNhcmF0dGVyZSBYTUwgbm9uIHZhbGlkbyAoVW5pY29kZTogMHh7MH0pIG5lbCBzZXQgc2Vjb25kYXJpbyBpbnRlcm5vIGRlbCBEVEQuCi0gICAgICAgIEludmFsaWRDaGFySW5UZXh0RGVjbCA9IFx1MDBDOCBzdGF0byB0cm92YXRvIHVuIGNhcmF0dGVyZSBYTUwgbm9uIHZhbGlkbyAoVW5pY29kZTogMHh7MH0pIG5lbGxhIGRpY2hpYXJhemlvbmUgdGVzdHVhbGUuCi0jIDIuMyBDb21tb24gU3ludGFjdGljIENvbnN0cnVjdHMKLSAgICAgICAgUXVvdGVSZXF1aXJlZEluQXR0VmFsdWUgPSBJbCB2YWxvcmUgZGVsbCcnYXR0cmlidXRvICJ7MX0iIGRldmUgaW5pemlhcmUgY29uIHVuIGFwaWNlIG8gdW5hIHZpcmdvbGV0dGEuCi0gICAgICAgIExlc3N0aGFuSW5BdHRWYWx1ZSA9IElsIHZhbG9yZSBkZWxsJydhdHRyaWJ1dG8gInsxfSIgYXNzb2NpYXRvIGEgdW4gdGlwbyBkaSBlbGVtZW50byAiezB9IiBub24gZGV2ZSBlc3NlcmUgY29udGVuZXJlIGlsIGNhcmF0dGVyZSAnJzwnJy4KLSAgICAgICAgQXR0cmlidXRlVmFsdWVVbnRlcm1pbmF0ZWQgPSBJbCB2YWxvcmUgZGVsbCcnYXR0cmlidXRvICJ7MX0iIGRldmUgdGVybWluYXJlIGNvbiB1biBhcGljZSBjb3JyaXNwb25kZW50ZS4KLSMgMi41IENvbW1lbnRzCi0gICAgICAgIEludmFsaWRDb21tZW50U3RhcnQgPSBJbCBjb21tZW50byBkZXZlIGluaXppYXJlIGNvbiAiPCEtLSIuCi0gICAgICAgIERhc2hEYXNoSW5Db21tZW50ID0gTGEgc3RyaW5nYSAiLS0iIG5vbiBcdTAwRTggY29uc2VudGl0YSBuZWkgY29tbWVudGkuCi0gICAgICAgIENvbW1lbnRVbnRlcm1pbmF0ZWQgPSBJbCBjb21tZW50byBkZXZlIHRlcm1pbmFyZSBjb24gIi0tPiIuCi0gICAgICAgIENPTU1FTlRfTk9UX0lOX09ORV9FTlRJVFkgPSBJbCBjb21tZW50byBub24gXHUwMEU4IGNvbXByZXNvIGFsbCdpbnRlcm5vIGRlbGxhIHN0ZXNzYSBlbnRpdFx1MDBFMC4KLSMgMi42IFByb2Nlc3NpbmcgSW5zdHJ1Y3Rpb25zCi0gICAgICAgIFBJVGFyZ2V0UmVxdWlyZWQgPSBMJ2lzdHJ1emlvbmUgZGkgZWxhYm9yYXppb25lIGRldmUgaW5pemlhcmUgY29uIGlsIG5vbWUgZGVsbGEgZGVzdGluYXppb25lLgotICAgICAgICBTcGFjZVJlcXVpcmVkSW5QSSA9IFx1MDBDOCByaWNoaWVzdG8gdW5vIHNwYXppbyB0cmEgbGEgZGVzdGluYXppb25lIGRlbGxlIGlzdHJ1emlvbmkgZGkgZWxhYm9yYXppb25lIGUgaSBkYXRpLgotICAgICAgICBQSVVudGVybWluYXRlZCA9IEwnaXN0cnV6aW9uZSBkaSBlbGFib3JhemlvbmUgZGV2ZSB0ZXJtaW5hcmUgY29uICI/PiIuCi0gICAgICAgIFJlc2VydmVkUElUYXJnZXQgPSBOb24gXHUwMEU4IGNvbnNlbnRpdGEgdW5hIGRlc3RpbmF6aW9uZSBkaSBpc3RydXppb25lIGRpIGVsYWJvcmF6aW9uZSBjb3JyaXNwb25kZW50ZSBhICJbeFhdW21NXVtsTF0iLgotICAgICAgICBQSV9OT1RfSU5fT05FX0VOVElUWSA9IEwnaXN0cnV6aW9uZSBkaSBlbGFib3JhemlvbmUgbm9uIFx1MDBFOCBjb21wcmVzYSBhbGwnaW50ZXJubyBkZWxsYSBzdGVzc2EgZW50aXRcdTAwRTAuCi0jIDIuOCBQcm9sb2cgYW5kIERvY3VtZW50IFR5cGUgRGVjbGFyYXRpb24KLSAgICAgICAgVmVyc2lvbkluZm9JbnZhbGlkID0gVmVyc2lvbmUgInswfSIgbm9uIHZhbGlkYS4KLSAgICAgICAgVmVyc2lvbk5vdFN1cHBvcnRlZCA9IExhIHZlcnNpb25lIFhNTCAiezB9IiBub24gXHUwMEU4IHN1cHBvcnRhdGEuIFNvbG8gbGEgdmVyc2lvbmUgWE1MIDEuMCBcdTAwRTggc3VwcG9ydGF0YS4KLSAgICAgICAgVmVyc2lvbk5vdFN1cHBvcnRlZDExID0gTGEgdmVyc2lvbmUgWE1MICJ7MH0iIG5vbiBcdTAwRTggc3VwcG9ydGF0YS4gU29sbyBsZSB2ZXJzaW9uaSBYTUwgMS4wIGUgWE1MIDEuMSBzb25vIHN1cHBvcnRhdGUuCi0gICAgICAgIFZlcnNpb25NaXNtYXRjaD0gVW4nZW50aXRcdTAwRTAgbm9uIHB1XHUwMEYyIGluY2x1ZGVybmUgdW4nYWx0cmEgY29uIHVuYSB2ZXJzaW9uZSBzdWNjZXNzaXZhLgotIyA0LjEgQ2hhcmFjdGVyIGFuZCBFbnRpdHkgUmVmZXJlbmNlcwotICAgICAgICBEaWdpdFJlcXVpcmVkSW5DaGFyUmVmID0gVW5hIHJhcHByZXNlbnRhemlvbmUgZGVjaW1hbGUgZGV2ZSBzZWd1aXJlIGltbWVkaWF0YW1lbnRlICImIyIgaW4gdW4gcmlmZXJpbWVudG8gZGkgY2FyYXR0ZXJlLgotICAgICAgICBIZXhkaWdpdFJlcXVpcmVkSW5DaGFyUmVmID0gVW5hIHJhcHByZXNlbnRhemlvbmUgZXNhZGVjaW1hbGUgZGV2ZSBzZWd1aXJlIGltbWVkaWF0YW1lbnRlICImIyIgaW4gdW4gcmlmZXJpbWVudG8gZGkgY2FyYXR0ZXJlLgotICAgICAgICBTZW1pY29sb25SZXF1aXJlZEluQ2hhclJlZiA9IElsIHJpZmVyaW1lbnRvIGRpIGNhcmF0dGVyZSBkZXZlIHRlcm1pbmFyZSBjb24gaWwgZGVsaW1pdGF0b3JlICc7Jy4KLSAgICAgICAgSW52YWxpZENoYXJSZWYgPSBJbCByaWZlcmltZW50byBkaSBjYXJhdHRlcmUgIiYjezB9IiBcdTAwRTggdW4gY2FyYXR0ZXJlIFhNTCBub24gdmFsaWRvLgotICAgICAgICBOYW1lUmVxdWlyZWRJblJlZmVyZW5jZSA9IElsIG5vbWUgZW50aXRcdTAwRTAgZGV2ZSBzZWd1aXJlIGltbWVkaWF0YW1lbnRlICcmJyBuZWwgcmlmZXJpbWVudG8gZGkgZW50aXRcdTAwRTAuCi0gICAgICAgIFNlbWljb2xvblJlcXVpcmVkSW5SZWZlcmVuY2UgPSBJbCByaWZlcmltZW50byBkaSBlbnRpdFx1MDBFMCAiezB9IiBkZXZlIHRlcm1pbmFyZSBjb24gaWwgZGVsaW1pdGF0b3JlICcnOycnLgotIyA0LjMuMSBUaGUgVGV4dCBEZWNsYXJhdGlvbgotICAgICAgICBUZXh0RGVjbE11c3RCZUZpcnN0ID0gTGEgZGljaGlhcmF6aW9uZSBkaSB0ZXN0byBwdVx1MDBGMiBjb21wYXJpcmUgc29sbyBhbGwnaW5pemlvIGRlbGwnZW50aXRcdTAwRTAgZXN0ZXJuYSBhbmFsaXp6YXRhLgotICAgICAgICBFcVJlcXVpcmVkSW5UZXh0RGVjbCA9IElsIGNhcmF0dGVyZSAnJyA9ICcnIGRldmUgc2VndWlyZSAiezB9IiBuZWxsYSBkaWNoaWFyYXppb25lIGRpIHRlc3RvLgotICAgICAgICBRdW90ZVJlcXVpcmVkSW5UZXh0RGVjbCA9IElsIHZhbG9yZSBjaGUgc2VndWUgInswfSIgbmVsbGEgZGljaGlhcmF6aW9uZSBkaSB0ZXN0byBkZXZlIGVzc2VyZSB1bmEgc3RyaW5nYSBjb21wcmVzYSB0cmEgYXBpY2kuCi0gICAgICAgIENsb3NlUXVvdGVNaXNzaW5nSW5UZXh0RGVjbCA9IG1hbmNhIGwnJ2FwaWNlIGRpIGNoaXVzdXJhIG5lbCB2YWxvcmUgY2hlIHNlZ3VlICJ7MH0iIG5lbGxhIGRpY2hpYXJhemlvbmUgZGkgdGVzdG8uCi0gICAgICAgIFNwYWNlUmVxdWlyZWRCZWZvcmVWZXJzaW9uSW5UZXh0RGVjbCA9IFx1MDBDOCByaWNoaWVzdG8gdW5vIHNwYXppbyBwcmltYSBkZWxsJ2F0dHJpYnV0byBwc2V1ZG8gZGVsbGEgdmVyc2lvbmUgbmVsbGEgZGljaGlhcmF6aW9uZSBkZWwgdGVzdG8uCi0gICAgICAgIFNwYWNlUmVxdWlyZWRCZWZvcmVFbmNvZGluZ0luVGV4dERlY2wgPSBcdTAwQzggcmljaGllc3RvIHVubyBzcGF6aW8gcHJpbWEgZGVsbCdhdHRyaWJ1dG8gcHNldWRvIGRpIGNvZGlmaWNhIG5lbGxhIGRpY2hpYXJhemlvbmUgZGVsIHRlc3RvLgotICAgICAgICBUZXh0RGVjbFVudGVybWluYXRlZCA9IExhIGRpY2hpYXJhemlvbmUgZGkgdGVzdG8gZGV2ZSB0ZXJtaW5hcmUgY29uICI/PiIuCi0gICAgICAgIEVuY29kaW5nRGVjbFJlcXVpcmVkID0gTGEgZGljaGlhcmF6aW9uZSBkaSBjb2RpZmljYSBcdTAwRTggb2JibGlnYXRvcmlhIG5lbGxhIGRpY2hpYXJhemlvbmUgZGkgdGVzdG8uCi0gICAgICAgIE5vTW9yZVBzZXVkb0F0dHJpYnV0ZXMgPSBOb24gc29ubyBjb25zZW50aXRpIGFsdHJpIGF0dHJpYnV0aSBwc2V1ZG8uCi0gICAgICAgIE1vcmVQc2V1ZG9BdHRyaWJ1dGVzID0gU29ubyBwcmV2aXN0aSBhbHRyaSBhdHRyaWJ1dGkgcHNldWRvLgotICAgICAgICBQc2V1ZG9BdHRyTmFtZUV4cGVjdGVkID0gXHUwMEM4IHByZXZpc3RvIHVuIG5vbWUgYXR0cmlidXRvIHBzZXVkby4gCi0jIDQuMy4yIFdlbGwtRm9ybWVkIFBhcnNlZCBFbnRpdGllcwotICAgICAgICBDb21tZW50Tm90SW5PbmVFbnRpdHkgPSBJbCBjb21tZW50byBkZXZlIGVzc2VyZSBjb21wcmVzbyBjb21wbGV0YW1lbnRlIGFsbCdpbnRlcm5vIGRlbGxhIHN0ZXNzYSBlbnRpdFx1MDBFMCBhbmFsaXp6YXRhLgotICAgICAgICBQSU5vdEluT25lRW50aXR5ID0gTCdpc3RydXppb25lIGRpIGVsYWJvcmF6aW9uZSBkZXZlIGVzc2VyZSBjb21wcmVzYSBjb21wbGV0YW1lbnRlIGFsbCdpbnRlcm5vIGRlbGxhIHN0ZXNzYSBlbnRpdFx1MDBFMCBhbmFsaXp6YXRhLgotIyA0LjMuMyBDaGFyYWN0ZXIgRW5jb2RpbmcgaW4gRW50aXRpZXMKLSAgICAgICAgRW5jb2RpbmdEZWNsSW52YWxpZCA9IE5vbWUgY29kaWZpY2EgInswfSIgbm9uIHZhbGlkby4KLSAgICAgICAgRW5jb2RpbmdCeXRlT3JkZXJVbnN1cHBvcnRlZCA9IEwnJ29yZGluZSBkaSBieXRlIHNwZWNpZmljYXRvIHBlciBsYSBjb2RpZmljYSAiezB9IiBub24gXHUwMEU4IHN1cHBvcnRhdG8uCi0gICAgICAgIEludmFsaWRCeXRlID0gQnl0ZSBub24gdmFsaWRvIHswfSBkZWxsYSBzZXF1ZW56YSBVVEYtOCBhIHsxfSBieXRlLgotICAgICAgICBFeHBlY3RlZEJ5dGUgPSBcdTAwQzggcHJldmlzdG8gaWwgYnl0ZSB7MH0gZGVsbGEgc2VxdWVuemEgVVRGLTggYSB7MX0gYnl0ZS4gIAotICAgICAgICBJbnZhbGlkSGlnaFN1cnJvZ2F0ZSA9IEkgYml0IHBlciBzdXJyb2dhdG8gYWx0byBuZWxsYSBzZXF1ZW56YSBVVEYtOCBub24gZGV2b25vIHN1cGVyYXJlIDB4MTAsIG1hIFx1MDBFOCBzdGF0byB0cm92YXRvIDB4ezB9LgotICAgICAgICBPcGVyYXRpb25Ob3RTdXBwb3J0ZWQgPSBPcGVyYXppb25lICJ7MH0iIG5vbiBzdXBwb3J0YXRhIGRhbCBwcm9jZXNzbyBkaSBsZXR0dXJhIHsxfS4KLSAgICAgICAgSW52YWxpZEFTQ0lJID0gSWwgYnl0ZSAiezB9IiBub24gZmEgcGFydGUgZGVsIHNldCBkaSBjYXJhdHRlcmkgQVNDSUkgKGEgNyBiaXQpLgotICAgICAgICBDaGFyQ29udmVyc2lvbkZhaWx1cmUgPSBVbidlbnRpdFx1MDBFMCBjaGUgZGV2ZSB0cm92YXJzaSBpbiB1bmEgZGV0ZXJtaW5hdGEgY29kaWZpY2Egbm9uIHB1XHUwMEYyIGNvbnRlbmVyZSBzZXF1ZW56ZSBub24gdmFsaWRlIGluIHF1ZWxsYSBjb2RpZmljYS4KLSAgICAgICAgCi0jIERURCBNZXNzYWdlcwotIyAyLjIgQ2hhcmFjdGVycwotICAgICAgICBJbnZhbGlkQ2hhckluRW50aXR5VmFsdWUgPSBcdTAwQzggc3RhdG8gdHJvdmF0byB1biBjYXJhdHRlcmUgWE1MIG5vbiB2YWxpZG8gKFVuaWNvZGU6IDB4ezB9KSBuZWwgdmFsb3JlIGRlbGwnJ2VudGl0XHUwMEUwLgotICAgICAgICBJbnZhbGlkQ2hhckluRXh0ZXJuYWxTdWJzZXQgPSBcdTAwQzggc3RhdG8gdHJvdmF0byB1biBjYXJhdHRlcmUgWE1MIG5vbiB2YWxpZG8gKFVuaWNvZGU6IDB4ezB9KSBuZWwgc2V0IHNlY29uZGFyaW8gZXN0ZXJubyBkZWwgRFRELgotICAgICAgICBJbnZhbGlkQ2hhckluSWdub3JlU2VjdCA9IFx1MDBDOCBzdGF0byB0cm92YXRvIHVuIGNhcmF0dGVyZSBYTUwgbm9uIHZhbGlkbyAoVW5pY29kZTogMHh7MH0pIG5lbGxhIHNlemlvbmUgY29uZGl6aW9uYWxlIGVzY2x1c2EuCi0gICAgICAgIEludmFsaWRDaGFySW5QdWJsaWNJRCA9IFx1MDBDOCBzdGF0byB0cm92YXRvIHVuIGNhcmF0dGVyZSBYTUwgbm9uIHZhbGlkbyAoVW5pY29kZTogMHh7MH0pIG5lbGwnJ2lkZW50aWZpY2F0aXZvIHB1YmJsaWNvLgotICAgICAgICBJbnZhbGlkQ2hhckluU3lzdGVtSUQgPSBcdTAwQzggc3RhdG8gdHJvdmF0byB1biBjYXJhdHRlcmUgWE1MIG5vbiB2YWxpZG8gKFVuaWNvZGU6IDB4ezB9KSBuZWxsJydpZGVudGlmaWNhdGl2byBkaSBzaXN0ZW1hLgotIyAyLjMgQ29tbW9uIFN5bnRhY3RpYyBDb25zdHJ1Y3RzCi0gICAgICAgIFNwYWNlUmVxdWlyZWRBZnRlclNZU1RFTSA9IFx1MDBDOCByaWNoaWVzdG8gdW5vIHNwYXppbyBkb3BvIGxhIHBhcm9sYSBjaGlhdmUgU1lTVEVNIG5lbGxhIGRpY2hpYXJhemlvbmUgRE9DVFlQRS4KLSAgICAgICAgUXVvdGVSZXF1aXJlZEluU3lzdGVtSUQgPSBMJ2lkZW50aWZpY2F0aXZvIGRpIHNpc3RlbWEgZGV2ZSBpbml6aWFyZSBjb24gdW4gYXBpY2UgbyBjb24gdmlyZ29sZXR0ZS4KLSAgICAgICAgU3lzdGVtSURVbnRlcm1pbmF0ZWQgPSBMJ2lkZW50aWZpY2F0aXZvIGRpIHNpc3RlbWEgZGV2ZSB0ZXJtaW5hcmUgY29uIHVuIGFwaWNlIGNvcnJpc3BvbmRlbnRlLgotICAgICAgICBTcGFjZVJlcXVpcmVkQWZ0ZXJQVUJMSUMgPSBTb25vIHJpY2hpZXN0aSBzcGF6aSBkb3BvIGxhIHBhcm9sYSBjaGlhdmUgUFVCTElDIG5lbGxhIGRpY2hpYXJhemlvbmUgRE9DVFlQRS4KLSAgICAgICAgUXVvdGVSZXF1aXJlZEluUHVibGljSUQgPSBMJ2lkZW50aWZpY2F0aXZvIHB1YmJsaWNvIGRldmUgaW5pemlhcmUgY29uIHVuIGFwaWNlIG8gY29uIGxlIHZpcmdvbGV0dGUuCi0gICAgICAgIFB1YmxpY0lEVW50ZXJtaW5hdGVkID0gTCdpZGVudGlmaWNhdGl2byBwdWJibGljbyBkZXZlIHRlcm1pbmFyZSBjb24gdW4gYXBpY2UgY29ycmlzcG9uZGVudGUuCi0gICAgICAgIFB1YmlkQ2hhcklsbGVnYWwgPSBJbCBjYXJhdHRlcmUgKFVuaWNvZGU6IDB4ezB9KSBub24gXHUwMEU4IGNvbnNlbnRpdG8gbmVsbCcnaWRlbnRpZmljYXRpdm8gcHViYmxpY28uCi0gICAgICAgIFNwYWNlUmVxdWlyZWRCZXR3ZWVuUHVibGljQW5kU3lzdGVtID0gU29ubyByaWNoaWVzdGkgc3BhemkgdHJhIHB1YmxpY0lkIGUgc3lzdGVtSWQuCi0jIDIuOCBQcm9sb2cgYW5kIERvY3VtZW50IFR5cGUgRGVjbGFyYXRpb24KLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9ST09UX0VMRU1FTlRfVFlQRV9JTl9ET0NUWVBFREVDTCA9IFx1MDBDOCByaWNoaWVzdG8gdW5vIHNwYXppbyBkb3BvICI8IURPQ1RZUEUiIG5lbGxhIGRpY2hpYXJhemlvbmUgZGVsIHRpcG8gZGkgZG9jdW1lbnRvLgotICAgICAgICBNU0dfUk9PVF9FTEVNRU5UX1RZUEVfUkVRVUlSRUQgPSBJbCB0aXBvIGRpIGVsZW1lbnRvIHJhZGljZSBkZXZlIGNvbXBhcmlyZSBkb3BvICI8IURPQ1RZUEUiIG5lbGxhIGRpY2hpYXJhemlvbmUgZGVsIHRpcG8gZGkgZG9jdW1lbnRvLgotICAgICAgICBEb2N0eXBlZGVjbFVudGVybWluYXRlZCA9IExhIGRpY2hpYXJhemlvbmUgZGVsIHRpcG8gZGkgZG9jdW1lbnRvIHBlciBpbCB0aXBvIGRpIGVsZW1lbnRvIHJhZGljZSAiezB9IiBkZXZlIHRlcm1pbmFyZSBjb24gJyc+JycuCi0gICAgICAgIERvY3R5cGVkZWNsTm90Q2xvc2VkID0gTGEgZGljaGlhcmF6aW9uZSBkZWwgdGlwbyBkaSBkb2N1bWVudG8gcGVyIGlsIHRpcG8gZGkgZWxlbWVudG8gcmFkaWNlICJ7MH0iIGRldmUgdGVybWluYXJlIGNvbiAnJ10nJy4KLSAgICAgICAgUEVSZWZlcmVuY2VXaXRoaW5NYXJrdXAgPSBJbCByaWZlcmltZW50byBkaSBlbnRpdFx1MDBFMCBkaSBwYXJhbWV0cm8gIiV7MH07IiBub24gcHVcdTAwRjIgZXNzZXJlIHByZXNlbnRlIG5lbCBtYXJrdXAgZGVsIHNldCBzZWNvbmRhcmlvIGludGVybm8gZGVsIERURC4KLSAgICAgICAgTVNHX01BUktVUF9OT1RfUkVDT0dOSVpFRF9JTl9EVEQgPSBMZSBkaWNoaWFyYXppb25pIGRpIG1hcmt1cCBjb250ZW51dGUgbyBpbmRpY2F0ZSBkYWxsYSBkaWNoaWFyYXppb25lIGRlbCB0aXBvIGRpIGRvY3VtZW50byBkZXZvbm8gYXZlcmUgdW4gZm9ybWF0byBjb3JyZXR0by4KLSMgMi4xMCBXaGl0ZSBTcGFjZSBIYW5kbGluZwotICAgICAgICBNU0dfWE1MX1NQQUNFX0RFQ0xBUkFUSU9OX0lMTEVHQUwgPSBMYSBkaWNoaWFyYXppb25lIGRpIGF0dHJpYnV0byAieG1sOnNwYWNlIiBkZXZlIGVzc2VyZSBzcGVjaWZpY2F0YSBjb21lIHRpcG8gZW51bWVyYXRvLCBpIGN1aSB1bmljaSBwb3NzaWJpbGkgdmFsb3JpIHNvbm8gImRlZmF1bHQiIGUgInByZXNlcnZlIi4KLSMgMy4yIEVsZW1lbnQgVHlwZSBEZWNsYXJhdGlvbnMKLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9FTEVNRU5UX1RZUEVfSU5fRUxFTUVOVERFQ0wgPSBcdTAwQzggcmljaGllc3RvIHVubyBzcGF6aW8gZG9wbyAiPCFFTEVNRU5UIiBuZWxsYSBkaWNoaWFyYXppb25lIGRlbCB0aXBvIGRpIGVsZW1lbnRvLgotICAgICAgICBNU0dfRUxFTUVOVF9UWVBFX1JFUVVJUkVEX0lOX0VMRU1FTlRERUNMID0gSWwgdGlwbyBkaSBlbGVtZW50byBcdTAwRTggb2JibGlnYXRvcmlvIG5lbGxhIGRpY2hpYXJhemlvbmUgZGVsIHRpcG8gZGkgZWxlbWVudG8uCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfQ09OVEVOVFNQRUNfSU5fRUxFTUVOVERFQ0wgPSBcdTAwQzggcmljaGllc3RvIHVubyBzcGF6aW8gZG9wbyBpbCB0aXBvIGRpIGVsZW1lbnRvICJ7MH0iIG5lbGxhIGRpY2hpYXJhemlvbmUgZGVsIHRpcG8gZGkgZWxlbWVudG8uCi0gICAgICAgIE1TR19DT05URU5UU1BFQ19SRVFVSVJFRF9JTl9FTEVNRU5UREVDTCA9IFx1MDBDOCByaWNoaWVzdG8gdW5vIHZpbmNvbG8gZG9wbyBpbCB0aXBvIGRpIGVsZW1lbnRvICJ7MH0iIG5lbGxhIGRpY2hpYXJhemlvbmUgZGVsIHRpcG8gZGkgZWxlbWVudG8uCi0gICAgICAgIEVsZW1lbnREZWNsVW50ZXJtaW5hdGVkID0gTGEgZGljaGlhcmF6aW9uZSBwZXIgaWwgdGlwbyBkaSBlbGVtZW50byAiezB9IiBkZXZlIHRlcm1pbmFyZSBjb24gJyc+JycuCi0jIDMuMi4xIEVsZW1lbnQgQ29udGVudAotICAgICAgICBNU0dfT1BFTl9QQVJFTl9PUl9FTEVNRU5UX1RZUEVfUkVRVUlSRURfSU5fQ0hJTERSRU4gPSBVbiBjYXJhdHRlcmUgJycoJycgbyB1biB0aXBvIGRpIGVsZW1lbnRvIFx1MDBFOCBvYmJsaWdhdG9yaW8gbmVsbGEgZGljaGlhcmF6aW9uZSBkZWwgdGlwbyBkaSBlbGVtZW50byAiezB9Ii4KLSAgICAgICAgTVNHX0NMT1NFX1BBUkVOX1JFUVVJUkVEX0lOX0NISUxEUkVOID0gVW4gY2FyYXR0ZXJlICcnKScnIFx1MDBFOCBvYmJsaWdhdG9yaW8gbmVsbGEgZGljaGlhcmF6aW9uZSBkZWwgdGlwbyBkaSBlbGVtZW50byAiezB9Ii4KLSMgMy4yLjIgTWl4ZWQgQ29udGVudAotICAgICAgICBNU0dfRUxFTUVOVF9UWVBFX1JFUVVJUkVEX0lOX01JWEVEX0NPTlRFTlQgPSBVbiB0aXBvIGRpIGVsZW1lbnRvIFx1MDBFOCBvYmJsaWdhdG9yaW8gbmVsbGEgZGljaGlhcmF6aW9uZSBkZWwgdGlwbyBkaSBlbGVtZW50byAiezB9Ii4KLSAgICAgICAgTVNHX0NMT1NFX1BBUkVOX1JFUVVJUkVEX0lOX01JWEVEID0gVW4gY2FyYXR0ZXJlICcnKScnIFx1MDBFOCBvYmJsaWdhdG9yaW8gbmVsbGEgZGljaGlhcmF6aW9uZSBkZWwgdGlwbyBkaSBlbGVtZW50byAiezB9Ii4KLSAgICAgICAgTWl4ZWRDb250ZW50VW50ZXJtaW5hdGVkID0gSWwgbW9kZWxsbyBkaSBjb250ZW51dG8gbWlzdG8gInswfSIgZGV2ZSB0ZXJtaW5hcmUgY29uICIpKiIgc2UgaSB0aXBpIGRpIGVsZW1lbnRpIGZpZ2xpbyBoYW5ubyB2aW5jb2xpLgotIyAzLjMgQXR0cmlidXRlLUxpc3QgRGVjbGFyYXRpb25zCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfRUxFTUVOVF9UWVBFX0lOX0FUVExJU1RERUNMID0gXHUwMEM4IHJpY2hpZXN0byB1bm8gc3BhemlvIGRvcG8gIjwhQVRUTElTVCIgbmVsbGEgZGljaGlhcmF6aW9uZSBkZWxsYSBsaXN0YSBkaSBhdHRyaWJ1dGkuCi0gICAgICAgIE1TR19FTEVNRU5UX1RZUEVfUkVRVUlSRURfSU5fQVRUTElTVERFQ0wgPSBJbCB0aXBvIGRpIGVsZW1lbnRvIFx1MDBFOCBvYmJsaWdhdG9yaW8gbmVsbGEgZGljaGlhcmF6aW9uZSBkZWxsYSBsaXN0YSBkaSBhdHRyaWJ1dGkuCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfQVRUUklCVVRFX05BTUVfSU5fQVRUREVGID0gXHUwMEM4IHJpY2hpZXN0byB1bm8gc3BhemlvIHByaW1hIGRlbCBub21lIGF0dHJpYnV0byBuZWxsYSBkaWNoaWFyYXppb25lIGRlbGxhIGxpc3RhIGRpIGF0dHJpYnV0aSBwZXIgbCcnZWxlbWVudG8gInswfSIuCi0gICAgICAgIEF0dE5hbWVSZXF1aXJlZEluQXR0RGVmID0gU3BlY2lmaWNhcmUgaWwgbm9tZSBhdHRyaWJ1dG8gbmVsbGEgZGljaGlhcmF6aW9uZSBkZWxsYSBsaXN0YSBkaSBhdHRyaWJ1dGkgcGVyIGwnJ2VsZW1lbnRvICJ7MH0iLgotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX0FUVFRZUEVfSU5fQVRUREVGID0gXHUwMEM4IHJpY2hpZXN0byB1bm8gc3BhemlvIHByaW1hIGRlbCB0aXBvIGRpIGF0dHJpYnV0byBuZWxsYSBkaWNoaWFyYXppb25lIGRlbGwnJ2F0dHJpYnV0byAiezF9IiBwZXIgbCcnZWxlbWVudG8gInswfSIuCi0gICAgICAgIEF0dFR5cGVSZXF1aXJlZEluQXR0RGVmID0gSWwgdGlwbyBkaSBhdHRyaWJ1dG8gXHUwMEU4IG9iYmxpZ2F0b3JpbyBuZWxsYSBkaWNoaWFyYXppb25lIGRlbGwnJ2F0dHJpYnV0byAiezF9IiBwZXIgbCcnZWxlbWVudG8gInswfSIuCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfREVGQVVMVERFQ0xfSU5fQVRUREVGID0gXHUwMEM4IHJpY2hpZXN0byB1bm8gc3BhemlvIHByaW1hIGRlbCB2YWxvcmUgcHJlZGVmaW5pdG8gZGkgYXR0cmlidXRvIG5lbGxhIGRpY2hpYXJhemlvbmUgZGVsbCcnYXR0cmlidXRvICJ7MX0iIHBlciBsJydlbGVtZW50byAiezB9Ii4KLSAgICAgICAgTVNHX0RVUExJQ0FURV9BVFRSSUJVVEVfREVGSU5JVElPTiA9IFNvbm8gc3RhdGUgc3BlY2lmaWNhdGUgcGlcdTAwRjkgZGVmaW5pemlvbmkgZGkgYXR0cmlidXRvIHBlciBsbyBzdGVzc28gYXR0cmlidXRvICJ7MX0iIGRlbGwnJ2VsZW1lbnRvICJ7MH0iIHNwZWNpZmljYXRvLgotIyAzLjMuMSBBdHRyaWJ1dGUgVHlwZXMKLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0FGVEVSX05PVEFUSU9OX0lOX05PVEFUSU9OVFlQRSA9IERldmUgZXNzZXJlIHByZXNlbnRlIHVubyBzcGF6aW8gZG9wbyAiTk9UQVRJT04iIG5lbGxhIGRpY2hpYXJhemlvbmUgZGkgYXR0cmlidXRvICJ7MX0iLgotICAgICAgICBNU0dfT1BFTl9QQVJFTl9SRVFVSVJFRF9JTl9OT1RBVElPTlRZUEUgPSBJbCBjYXJhdHRlcmUgJycoJycgZGV2ZSBzZWd1aXJlICJOT1RBVElPTiIgbmVsbGEgZGljaGlhcmF6aW9uZSBkaSBhdHRyaWJ1dG8gInsxfSIuCi0gICAgICAgIE1TR19OQU1FX1JFUVVJUkVEX0lOX05PVEFUSU9OVFlQRSA9IElsIG5vbWUgbm90YXppb25lIFx1MDBFOCBvYmJsaWdhdG9yaW8gbmVsbGEgbGlzdGEgZGkgdGlwaSBkaSBub3RhemlvbmUgcGVyIGxhIGRpY2hpYXJhemlvbmUgZGkgYXR0cmlidXRvICJ7MX0iLgotICAgICAgICBOb3RhdGlvblR5cGVVbnRlcm1pbmF0ZWQgPSBMYSBsaXN0YSBkaSB0aXBpIGRpIG5vdGF6aW9uZSBkZXZlIHRlcm1pbmFyZSBjb24gJycpJycgbmVsbGEgZGljaGlhcmF6aW9uZSBkaSBhdHRyaWJ1dG8gInsxfSIuCi0gICAgICAgIE1TR19OTVRPS0VOX1JFUVVJUkVEX0lOX0VOVU1FUkFUSU9OID0gSWwgbm9tZSB0b2tlbiBcdTAwRTggb2JibGlnYXRvcmlvIG5lbGxhIGxpc3RhIGRpIHRpcGkgZW51bWVyYXRpIHBlciBsYSBkaWNoaWFyYXppb25lIGRpIGF0dHJpYnV0byAiezF9Ii4KLSAgICAgICAgRW51bWVyYXRpb25VbnRlcm1pbmF0ZWQgPSBMYSBsaXN0YSBkaSB0aXBpIGVudW1lcmF0aSBkZXZlIHRlcm1pbmFyZSBjb24gJycpJycgbmVsbGEgZGljaGlhcmF6aW9uZSBkaSBhdHRyaWJ1dG8gInsxfSIuCi0gICAgICAgIE1TR19ESVNUSU5DVF9UT0tFTlNfSU5fRU5VTUVSQVRJT04gPSBJbCB2YWxvcmUgZGkgZW51bWVyYXppb25lICJ7MX0iIFx1MDBFOCBzdGF0byBzcGVjaWZpY2F0byBwaVx1MDBGOSB2b2x0ZSBuZWxsYSBkaWNoaWFyYXppb25lIGRlbGwnJ2F0dHJpYnV0byAiezJ9IiBwZXIgbCcnZWxlbWVudG8gInswfSIuIEkgdmFsb3JpIGRpIE5NVE9LRU5TIGluIHVuYSBkaWNoaWFyYXppb25lIHNpbmdvbGEgZGkgYXR0cmlidXRvIEVudW1lcmF0aW9uIGRldm9ubyBlc3NlcmUgdHV0dGkgZGl2ZXJzaS4KLSAgICAgICAgTVNHX0RJU1RJTkNUX05PVEFUSU9OX0lOX0VOVU1FUkFUSU9OID0gSWwgdmFsb3JlIGRpIGVudW1lcmF6aW9uZSAiezF9IiBcdTAwRTggc3RhdG8gc3BlY2lmaWNhdG8gcGlcdTAwRjkgdm9sdGUgbmVsbGEgZGljaGlhcmF6aW9uZSBkZWxsJydhdHRyaWJ1dG8gInsyfSIgcGVyIGwnJ2VsZW1lbnRvICJ7MH0iLiBJIG5vbWkgTk9UQVRJT04gaW4gdW5hIGRpY2hpYXJhemlvbmUgc2luZ29sYSBkaSBhdHRyaWJ1dG8gTm90YXRpb25UeXBlIGRldm9ubyBlc3NlcmUgdHV0dGkgZGl2ZXJzaS4KLSMgMy4zLjIgQXR0cmlidXRlIERlZmF1bHRzCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9BRlRFUl9GSVhFRF9JTl9ERUZBVUxUREVDTCA9IERldmUgZXNzZXJlIHByZXNlbnRlIHVubyBzcGF6aW8gZG9wbyAiRklYRUQiIG5lbGxhIGRpY2hpYXJhemlvbmUgZGkgYXR0cmlidXRvICJ7MX0iLgotIyAzLjQgQ29uZGl0aW9uYWwgU2VjdGlvbnMKLSAgICAgICAgSW5jbHVkZVNlY3RVbnRlcm1pbmF0ZWQgPSBMYSBzZXppb25lIGNvbmRpemlvbmFsZSBpbmNsdXNhIGRldmUgdGVybWluYXJlIGNvbiAiXV0+Ii4KLSAgICAgICAgSWdub3JlU2VjdFVudGVybWluYXRlZCA9IExhIHNlemlvbmUgY29uZGl6aW9uYWxlIGVzY2x1c2EgZGV2ZSB0ZXJtaW5hcmUgY29uICJdXT4iLgotIyA0LjEgQ2hhcmFjdGVyIGFuZCBFbnRpdHkgUmVmZXJlbmNlcwotICAgICAgICBOYW1lUmVxdWlyZWRJblBFUmVmZXJlbmNlID0gSWwgbm9tZSBlbnRpdFx1MDBFMCBkZXZlIHNlZ3VpcmUgaW1tZWRpYXRhbWVudGUgJyUnIG5lbCByaWZlcmltZW50byBkaSBlbnRpdFx1MDBFMCBkaSBwYXJhbWV0cm8uCi0gICAgICAgIFNlbWljb2xvblJlcXVpcmVkSW5QRVJlZmVyZW5jZSA9IElsIHJpZmVyaW1lbnRvIGRpIGVudGl0XHUwMEUwIGRpIHBhcmFtZXRybyAiJXswfTsiIGRldmUgdGVybWluYXJlIGNvbiBpbCBkZWxpbWl0YXRvcmUgJyc7JycuCi0jIDQuMiBFbnRpdHkgRGVjbGFyYXRpb25zCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfRU5USVRZX05BTUVfSU5fRU5USVRZREVDTCA9IFx1MDBDOCByaWNoaWVzdG8gdW5vIHNwYXppbyBkb3BvICI8IUVOVElUWSIgbmVsbGEgZGljaGlhcmF6aW9uZSBkZWxsJ2VudGl0XHUwMEUwLgotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX1BFUkNFTlRfSU5fUEVERUNMID0gXHUwMEM4IHJpY2hpZXN0byB1bm8gc3BhemlvIHRyYSAiPCFFTlRJVFkiIGUgaWwgY2FyYXR0ZXJlICclJyBuZWxsYSBkaWNoaWFyYXppb25lIGRlbGwnZW50aXRcdTAwRTAgZGkgcGFyYW1ldHJvLgotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX0VOVElUWV9OQU1FX0lOX1BFREVDTCA9IFx1MDBDOCByaWNoaWVzdG8gdW5vIHNwYXppbyB0cmEgJyUnIGUgaWwgbm9tZSBlbnRpdFx1MDBFMCBuZWxsYSBkaWNoaWFyYXppb25lIGRlbGwnZW50aXRcdTAwRTAgZGkgcGFyYW1ldHJvLgotICAgICAgICBNU0dfRU5USVRZX05BTUVfUkVRVUlSRURfSU5fRU5USVRZREVDTCA9IElsIG5vbWUgZGVsbCdlbnRpdFx1MDBFMCBcdTAwRTggb2JibGlnYXRvcmlvIG5lbGxhIGRpY2hpYXJhemlvbmUgZGkgZW50aXRcdTAwRTAuCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9BRlRFUl9FTlRJVFlfTkFNRV9JTl9FTlRJVFlERUNMID0gXHUwMEM4IHJpY2hpZXN0byB1bm8gc3BhemlvIHRyYSBpbCBub21lIGVudGl0XHUwMEUwICJ7MH0iIGUgbGEgZGVmaW5pemlvbmUgbmVsbGEgZGljaGlhcmF6aW9uZSBkZWxsJydlbnRpdFx1MDBFMDoKLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9OT1RBVElPTl9OQU1FX0lOX1VOUEFSU0VEX0VOVElUWURFQ0wgPSBcdTAwQzggcmljaGllc3RvIHVubyBzcGF6aW8gdHJhICJOREFUQSIgZSBpbCBub21lIG5vdGF6aW9uZSBuZWxsYSBkaWNoaWFyYXppb25lIGRlbGwnJ2VudGl0XHUwMEUwICJ7MH0iLgotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX05EQVRBX0lOX1VOUEFSU0VEX0VOVElUWURFQ0wgPSBcdTAwQzggcmljaGllc3RvIHVubyBzcGF6aW8gcHJpbWEgZGkgIk5EQVRBIiBuZWxsYSBkaWNoaWFyYXppb25lIGRlbGwnJ2VudGl0XHUwMEUwICJ7MH0iLgotICAgICAgICBNU0dfTk9UQVRJT05fTkFNRV9SRVFVSVJFRF9GT1JfVU5QQVJTRURfRU5USVRZREVDTCA9IElsIG5vbWUgbm90YXppb25lIFx1MDBFOCBvYmJsaWdhdG9yaW8gZG9wbyAiTkRBVEEiIG5lbGxhIGRpY2hpYXJhemlvbmUgZGVsbCcnZW50aXRcdTAwRTAgInswfSIuCi0gICAgICAgIEVudGl0eURlY2xVbnRlcm1pbmF0ZWQgPSBMYSBkaWNoaWFyYXppb25lIHBlciBsJydlbnRpdFx1MDBFMCAiezB9IiBkZXZlIHRlcm1pbmFyZSBjb24gJyc+JycuCi0JTVNHX0RVUExJQ0FURV9FTlRJVFlfREVGSU5JVElPTiA9IEwnJ2VudGl0XHUwMEUwICJ7MH0iIFx1MDBFOCBzdGF0YSBkaWNoaWFyYXRhIHBpXHUwMEY5IHZvbHRlLiAgICAgICAgCi0jIDQuMi4yIEV4dGVybmFsIEVudGl0aWVzCi0gICAgICAgIEV4dGVybmFsSURSZXF1aXJlZCA9IExhIGRpY2hpYXJhemlvbmUgZGkgZW50aXRcdTAwRTAgZXN0ZXJuYSBkZXZlIGluaXppYXJlIGNvbiAiU1lTVEVNIiBvICJQVUJMSUMiLgotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX1BVQklETElURVJBTF9JTl9FWFRFUk5BTElEID0gXHUwMEM4IHJpY2hpZXN0byB1bm8gc3BhemlvIHRyYSAiUFVCTElDIiBlIGwnaWRlbnRpZmljYXRpdm8gcHViYmxpY28uCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9BRlRFUl9QVUJJRExJVEVSQUxfSU5fRVhURVJOQUxJRCA9IFx1MDBDOCByaWNoaWVzdG8gdW5vIHNwYXppbyB0cmEgbCdpZGVudGlmaWNhdGl2byBwdWJibGljbyBlIHF1ZWxsbyBkaSBzaXN0ZW1hLgotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX1NZU1RFTUxJVEVSQUxfSU5fRVhURVJOQUxJRCA9IFx1MDBDOCByaWNoaWVzdG8gdW5vIHNwYXppbyB0cmEgIlNZU1RFTSIgZSBsJ2lkZW50aWZpY2F0aXZvIGRpIHNpc3RlbWEuCi0gICAgICAgIE1TR19VUklfRlJBR01FTlRfSU5fU1lTVEVNSUQgPSBMJydpZGVudGlmaWNhdGl2byBkaSBmcmFtbWVudG8gbm9uIGRldmUgZXNzZXJlIHNwZWNpZmljYXRvIG5lbGwnJ2lkZW50aWZpY2F0aXZvIGRpIHNpc3RlbWEgInswfSIuCi0jIDQuNyBOb3RhdGlvbiBEZWNsYXJhdGlvbnMKLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9OT1RBVElPTl9OQU1FX0lOX05PVEFUSU9OREVDTCA9IFx1MDBDOCByaWNoaWVzdG8gdW5vIHNwYXppbyBkb3BvICI8IU5PVEFUSU9OIiBuZWxsYSBkaWNoaWFyYXppb25lIGRlbGxhIG5vdGF6aW9uZS4KLSAgICAgICAgTVNHX05PVEFUSU9OX05BTUVfUkVRVUlSRURfSU5fTk9UQVRJT05ERUNMID0gSWwgbm9tZSBkZWxsYSBub3RhemlvbmUgXHUwMEU4IG9iYmxpZ2F0b3JpbyBuZWxsYSBkaWNoaWFyYXppb25lIGRpIG5vdGF6aW9uZS4KLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0FGVEVSX05PVEFUSU9OX05BTUVfSU5fTk9UQVRJT05ERUNMID0gXHUwMEM4IHJpY2hpZXN0byB1bm8gc3BhemlvIGRvcG8gaWwgbm9tZSBub3RhemlvbmUgInswfSIgbmVsbGEgZGljaGlhcmF6aW9uZSBkZWxsYSBub3RhemlvbmUuCi0gICAgICAgIEV4dGVybmFsSURvclB1YmxpY0lEUmVxdWlyZWQgPSBMYSBkaWNoaWFyYXppb25lIHBlciBsYSBub3RhemlvbmUgInswfSIgZGV2ZSBpbmNsdWRlcmUgdW4gaWRlbnRpZmljYXRpdm8gZGkgc2lzdGVtYSBvIHB1YmJsaWNvLgotICAgICAgICBOb3RhdGlvbkRlY2xVbnRlcm1pbmF0ZWQgPSBMYSBkaWNoaWFyYXppb25lIHBlciBsYSBub3RhemlvbmUgInswfSIgZGV2ZSB0ZXJtaW5hcmUgY29uICcnPicnLgotICAgICAgICAKLSMgVmFsaWRhdGlvbiBtZXNzYWdlcwotICAgICAgICBEdXBsaWNhdGVUeXBlSW5NaXhlZENvbnRlbnQgPSBJbCB0aXBvIGRpIGVsZW1lbnRvICJ7MX0iIFx1MDBFOCBnaVx1MDBFMCBzdGF0byBzcGVjaWZpY2F0byBuZWwgbW9kZWxsbyBkaSBjb250ZW51dG8gZGVsbGEgZGljaGlhcmF6aW9uZSBkaSBlbGVtZW50byAiezB9Ii4KLSAgICAgICAgRU5USVRJRVNJbnZhbGlkID0gSWwgdmFsb3JlIGRpIGF0dHJpYnV0byAiezF9IiBkaSB0aXBvIEVOVElUSUVTIGRldmUgY29ycmlzcG9uZGVyZSBhaSBub21pIGRpIHVuYSBvIHBpXHUwMEY5IGVudGl0XHUwMEUwIG5vbiBhbmFsaXp6YXRlLgotICAgICAgICBFTlRJVFlJbnZhbGlkID0gSWwgdmFsb3JlIGRpIGF0dHJpYnV0byAiezF9IiBkaSB0aXBvIEVOVElUWSBkZXZlIGNvcnJpc3BvbmRlcmUgYWwgbm9tZSBkaSB1bicnZW50aXRcdTAwRTAgbm9uIGFuYWxpenphdGEuCi0gICAgICAgIElERGVmYXVsdFR5cGVJbnZhbGlkID0gTmVsbCcnYXR0cmlidXRvIElEICJ7MH0iIGRldmUgZXNzZXJlIGRpY2hpYXJhdG8gdW4gdmFsb3JlIHByZWRlZmluaXRvICIjSU1QTElFRCIgbyAiI1JFUVVJUkVEIi4KLSAgICAgICAgSURJbnZhbGlkID0gSWwgdmFsb3JlIGRpIGF0dHJpYnV0byAiezB9IiBkaSB0aXBvIElEIGRldmUgZXNzZXJlIHVuIG5vbWUuCi0gICAgICAgIElESW52YWxpZFdpdGhOYW1lc3BhY2VzID0gSWwgdmFsb3JlIGRpIGF0dHJpYnV0byAiezB9IiBkaSB0aXBvIElEIGRldmUgZXNzZXJlIHVuIE5DTmFtZSBzZSBzb25vIGFiaWxpdGF0aSBnbGkgc3BhemkgZGkgbm9taS4KLSAgICAgICAgSUROb3RVbmlxdWUgPSBJbCB2YWxvcmUgZGkgYXR0cmlidXRvICJ7MH0iIGRpIHRpcG8gSUQgZGV2ZSBlc3NlcmUgdW5pdm9jbyBhbGwnJ2ludGVybm8gZGVsIGRvY3VtZW50by4KLSAgICAgICAgSURSRUZJbnZhbGlkID0gSWwgdmFsb3JlIGRpIGF0dHJpYnV0byAiezB9IiBkaSB0aXBvIElEUkVGIGRldmUgZXNzZXJlIHVuIG5vbWUuCi0gICAgICAgIElEUkVGSW52YWxpZFdpdGhOYW1lc3BhY2VzID0gSWwgdmFsb3JlIGRpIGF0dHJpYnV0byAiezB9IiBkaSB0aXBvIElEUkVGIGRldmUgZXNzZXJlIHVuIE5DTmFtZSBzZSBzb25vIGFiaWxpdGF0aSBnbGkgc3BhemkgZGkgbm9taS4KLSAgICAgICAgSURSRUZTSW52YWxpZCA9IElsIHZhbG9yZSBkaSBhdHRyaWJ1dG8gInswfSIgZGkgdGlwbyBJRFJFRlMgZGV2ZSBjb3JyaXNwb25kZXJlIGEgdW5vIG8gcGlcdTAwRjkgbm9taS4KLSAgICAgICAgSUxMX0ZPUk1FRF9QQVJBTUVURVJfRU5USVRZX1dIRU5fVVNFRF9JTl9ERUNMID0gSWwgdGVzdG8gZGkgc29zdGl0dXppb25lIGRlbGwnJ2VudGl0XHUwMEUwIGRpIHBhcmFtZXRybyAiezB9IiBkZXZlIGluY2x1ZGVyZSBkaWNoaWFyYXppb25pIG5pZGlmaWNhdGUgY29ycmV0dGFtZW50ZSBzZSBpbCByaWZlcmltZW50byBkZWxsJydlbnRpdFx1MDBFMCBcdTAwRTggdXRpbGl6emF0byBjb21lIGRpY2hpYXJhemlvbmUgY29tcGxldGEuCi0gICAgICAgIEltcHJvcGVyRGVjbGFyYXRpb25OZXN0aW5nID0gSWwgdGVzdG8gZGkgc29zdGl0dXppb25lIGRlbGwnJ2VudGl0XHUwMEUwIGRpIHBhcmFtZXRybyAiezB9IiBkZXZlIGluY2x1ZGVyZSBkaWNoaWFyYXppb25pIG5pZGlmaWNhdGUgY29ycmV0dGFtZW50ZS4KLSAgICAgICAgSW1wcm9wZXJHcm91cE5lc3RpbmcgPSBJbCB0ZXN0byBkaSBzb3N0aXR1emlvbmUgZGVsbCcnZW50aXRcdTAwRTAgZGkgcGFyYW1ldHJvICJ7MH0iIGRldmUgaW5jbHVkZXJlIGNvcHBpZSBkaSBwYXJlbnRlc2kgbmlkaWZpY2F0ZSBjb3JyZXR0YW1lbnRlLgotICAgICAgICBJTlZBTElEX1BFX0lOX0NPTkRJVElPTkFMID0gSWwgdGVzdG8gZGkgc29zdGl0dXppb25lIGRlbGwnJ2VudGl0XHUwMEUwIGRpIHBhcmFtZXRybyAiezB9IiBkZXZlIGluY2x1ZGVyZSB0dXR0YSBsYSBzZXppb25lIGNvbmRpemlvbmFsZSBvcHB1cmUgc29sbyBJTkNMVURFIG8gSUdOT1JFLgotICAgICAgICBNU0dfQVRUUklCVVRFX05PVF9ERUNMQVJFRCA9IERpY2hpYXJhcmUgbCcnYXR0cmlidXRvICJ7MX0iIHBlciBpbCB0aXBvIGRpIGVsZW1lbnRvICJ7MH0iLgotICAgICAgICBNU0dfQVRUUklCVVRFX1ZBTFVFX05PVF9JTl9MSVNUID0gTCcnYXR0cmlidXRvICJ7MH0iIGNvbiB2YWxvcmUgInsxfSIgZGV2ZSBhdmVyZSB1biB2YWxvcmUgZGVsbGEgbGlzdGEgInsyfSIuCi0gICAgICAgIE1TR19BVFRWQUxVRV9DSEFOR0VEX0RVUklOR19OT1JNQUxJWkFUSU9OX1dIRU5fU1RBTkRBTE9ORSA9IElsIHZhbG9yZSAiezF9IiBkZWxsJydhdHRyaWJ1dG8gInswfSIgbm9uIGRldmUgZXNzZXJlIG1vZGlmaWNhdG8gZGFsbGEgbm9ybWFsaXp6YXppb25lIChpbiAiezJ9IikgaW4gdW4gZG9jdW1lbnRvIHN0YW5kYWxvbmUuCi0gICAgICAgIE1TR19DT05URU5UX0lOQ09NUExFVEUgPSBJbCBjb250ZW51dG8gZGVsIHRpcG8gZGkgZWxlbWVudG8gInswfSIgXHUwMEU4IGluY29tcGxldG8uIERldmUgY29ycmlzcG9uZGVyZSBhICJ7MX0iLgotICAgICAgICBNU0dfQ09OVEVOVF9JTlZBTElEID0gSWwgY29udGVudXRvIGRlbCB0aXBvIGRpIGVsZW1lbnRvICJ7MH0iIGRldmUgY29ycmlzcG9uZGVyZSBhICJ7MX0iLgotICAgICAgICBNU0dfQ09OVEVOVF9JTlZBTElEX1NQRUNJRklFRCA9IElsIGNvbnRlbnV0byBkZWwgdGlwbyBkaSBlbGVtZW50byAiezB9IiBkZXZlIGNvcnJpc3BvbmRlcmUgYSAiezF9Ii4gTm9uIHNvbm8gY29uc2VudGl0aSBlbGVtZW50aSBmaWdsaW8gZGkgdGlwbyAiezJ9Ii4KLSAgICAgICAgTVNHX0RFRkFVTFRFRF9BVFRSSUJVVEVfTk9UX1NQRUNJRklFRCA9IEwnJ2F0dHJpYnV0byAiezF9IiBwZXIgaWwgdGlwbyBkaSBlbGVtZW50byAiezB9IiBoYSB1biB2YWxvcmUgcHJlZGVmaW5pdG8gZSBkZXZlIGVzc2VyZSBzcGVjaWZpY2F0byBpbiB1biBkb2N1bWVudG8gc3RhbmRhbG9uZS4KLSAgICAgICAgTVNHX0RVUExJQ0FURV9BVFRERUYgPSBMJydhdHRyaWJ1dG8gInsxfSIgXHUwMEU4IGdpXHUwMEUwIHN0YXRvIGRpY2hpYXJhdG8gcGVyIGlsIHRpcG8gZGkgZWxlbWVudG8gInswfSIuCi0gICAgICAgIE1TR19FTEVNRU5UX0FMUkVBRFlfREVDTEFSRUQgPSBJbCB0aXBvIGRpIGVsZW1lbnRvICJ7MH0iIG5vbiBkZXZlIGVzc2VyZSBkaWNoaWFyYXRvIHBpXHUwMEY5IHZvbHRlLgotICAgICAgICBNU0dfRUxFTUVOVF9OT1RfREVDTEFSRUQgPSBJbCB0aXBvIGRpIGVsZW1lbnRvICJ7MH0iIGRldmUgZXNzZXJlIGRpY2hpYXJhdG8uCi0gICAgICAgIE1TR19HUkFNTUFSX05PVF9GT1VORCA9IERvY3VtZW50byBub24gdmFsaWRvOiBuZXNzdW5hIGdyYW1tYXRpY2EgdHJvdmF0YS4KLSAgICAgICAgTVNHX0VMRU1FTlRfV0lUSF9JRF9SRVFVSVJFRCA9IFVuIGVsZW1lbnRvIGNvbiBpZGVudGlmaWNhdGl2byAiezB9IiBkZXZlIGVzaXN0ZXJlIG5lbCBkb2N1bWVudG8uCi0gICAgICAgIE1TR19FWFRFUk5BTF9FTlRJVFlfTk9UX1BFUk1JVFRFRCA9IElsIHJpZmVyaW1lbnRvIGFsbCcnZW50aXRcdTAwRTAgZXN0ZXJuYSAiezB9IiBub24gXHUwMEU4IGNvbnNlbnRpdG8gaW4gdW4gZG9jdW1lbnRvIHN0YW5kYWxvbmUuCi0gICAgICAgIE1TR19GSVhFRF9BVFRWQUxVRV9JTlZBTElEID0gTCcnYXR0cmlidXRvICJ7MX0iIGNvbiB2YWxvcmUgInsyfSIgZGV2ZSBhdmVyZSB1biB2YWxvcmUgInszfSIuCi0gICAgICAgIE1TR19NT1JFX1RIQU5fT05FX0lEX0FUVFJJQlVURSA9IElsIHRpcG8gZGkgZWxlbWVudG8gInswfSIgaGEgZ2lcdTAwRTAgdW4gYXR0cmlidXRvICJ7MX0iIGRpIHRpcG8gSUQuIE5vbiBcdTAwRTggY29uc2VudGl0byB1biBzZWNvbmRvIGF0dHJpYnV0byAiezJ9IiBkaSB0aXBvIElELgotICAgICAgICBNU0dfTU9SRV9USEFOX09ORV9OT1RBVElPTl9BVFRSSUJVVEUgPSBJbCB0aXBvIGRpIGVsZW1lbnRvICJ7MH0iIGhhIGdpXHUwMEUwIHVuIGF0dHJpYnV0byAiezF9IiBkaSB0aXBvIE5PVEFUSU9OLiBOb24gXHUwMEU4IGNvbnNlbnRpdG8gdW4gc2Vjb25kbyBhdHRyaWJ1dG8gInsyfSIgZGkgdGlwbyBOT1RBVElPTi4KLSAgICAgICAgTVNHX05PVEFUSU9OX05PVF9ERUNMQVJFRF9GT1JfTk9UQVRJT05UWVBFX0FUVFJJQlVURSA9IExhIG5vdGF6aW9uZSAiezF9IiBkZXZlIGVzc2VyZSBkaWNoaWFyYXRhIHNlIHZpIHZpZW5lIGZhdHRvIHJpZmVyaW1lbnRvIG5lbGxhIGxpc3RhIGRlaSB0aXBpIGRpIG5vdGF6aW9uZSBwZXIgbCcnYXR0cmlidXRvICJ7MH0iLgotICAgICAgICBNU0dfTk9UQVRJT05fTk9UX0RFQ0xBUkVEX0ZPUl9VTlBBUlNFRF9FTlRJVFlERUNMID0gTGEgbm90YXppb25lICJ7MX0iIGRldmUgZXNzZXJlIGRpY2hpYXJhdGEgc2UgdmkgdmllbmUgZmF0dG8gcmlmZXJpbWVudG8gZGljaGlhcmF6aW9uZSBkaSBlbnRpdFx1MDBFMCBub24gYW5hbGl6emF0YSBwZXIgInswfSIuCi0gICAgICAgIE1TR19SRUZFUkVOQ0VfVE9fRVhURVJOQUxMWV9ERUNMQVJFRF9FTlRJVFlfV0hFTl9TVEFOREFMT05FID0gSWwgcmlmZXJpbWVudG8gYWxsJydlbnRpdFx1MDBFMCAiezB9IiBkaWNoaWFyYXRhIGluIHVuJydlbnRpdFx1MDBFMCBlc3Rlcm5hIGFuYWxpenphdGEgbm9uIFx1MDBFOCBjb25zZW50aXRvIGluIHVuIGRvY3VtZW50byBzdGFuZGFsb25lLgotICAgICAgICBNU0dfUkVRVUlSRURfQVRUUklCVVRFX05PVF9TUEVDSUZJRUQgPSBMJydhdHRyaWJ1dG8gInsxfSIgXHUwMEU4IG9iYmxpZ2F0b3JpbyBlIGRldmUgZXNzZXJlIHNwZWNpZmljYXRvIHBlciBpbCB0aXBvIGRpIGVsZW1lbnRvICJ7MH0iLgotICAgICAgICBNU0dfV0hJVEVfU1BBQ0VfSU5fRUxFTUVOVF9DT05URU5UX1dIRU5fU1RBTkRBTE9ORSA9IE5vbiBkZXZlIGVzaXN0ZXJlIG5lc3N1bm8gc3BhemlvIHRyYSBnbGkgZWxlbWVudGkgZGljaGlhcmF0aSBpbiB1bidlbnRpdFx1MDBFMCBlc3Rlcm5hIGFuYWxpenphdGEgY29uIGlsIGNvbnRlbnV0byBkZWxsJ2VsZW1lbnRvIGluIHVuIGRvY3VtZW50byBzdGFuZGFsb25lLgotICAgICAgICBOTVRPS0VOSW52YWxpZCA9IElsIHZhbG9yZSBkaSBhdHRyaWJ1dG8gInswfSIgZGkgdGlwbyBOTVRPS0VOIGRldmUgZXNzZXJlIHVuIHRva2VuIGRpIG5vbWUuCi0gICAgICAgIE5NVE9LRU5TSW52YWxpZCA9IElsIHZhbG9yZSBkaSBhdHRyaWJ1dG8gInswfSIgZGkgdGlwbyBOTVRPS0VOUyBkZXZlIGNvcnJpc3BvbmRlcmUgYSB1bm8gbyBwaVx1MDBGOSB0b2tlbiBkaSBub21pLgotICAgICAgICBOb05vdGF0aW9uT25FbXB0eUVsZW1lbnQgPSBJbCB0aXBvIGRpIGVsZW1lbnRvICJ7MH0iIGRpY2hpYXJhdG8gY29tZSBFTVBUWSBub24gcHVcdTAwRjIgZGljaGlhcmFyZSBsJydhdHRyaWJ1dG8gInsxfSIgZGkgdGlwbyBOT1RBVElPTi4KLSAgICAgICAgUm9vdEVsZW1lbnRUeXBlTXVzdE1hdGNoRG9jdHlwZWRlY2wgPSBMJydlbGVtZW50byByYWRpY2UgInsxfSIgZGVsIGRvY3VtZW50byBkZXZlIGNvcnJpc3BvbmRlcmUgYWxsYSByYWRpY2UgRE9DVFlQRSAiezB9Ii4KLSAgICAgICAgVW5kZWNsYXJlZEVsZW1lbnRJbkNvbnRlbnRTcGVjID0gSWwgbW9kZWxsbyBkaSBjb250ZW51dG8gZGVsbCcnZWxlbWVudG8gInswfSIgZmEgcmlmZXJpbWVudG8gYSB1biBlbGVtZW50byAiezF9IiBub24gZGljaGlhcmF0by4KLSAgICAgICAgVW5pcXVlTm90YXRpb25OYW1lID0gTGEgZGljaGlhcmF6aW9uZSBwZXIgbGEgbm90YXppb25lICJ7MH0iIG5vbiBcdTAwRTggdW5pdm9jYS4gVW4gbm9tZSBub24gZGV2ZSBlc3NlcmUgZGljaGlhcmF0byBwaVx1MDBGOSB2b2x0ZSBuZWxsYSBkaWNoaWFyYXppb25lIGRpIHVuYSBub3RhemlvbmUuCi0gICAgICAgIEVOVElUWUZhaWxlZEluaXRpYWxpemVHcmFtbWFyID0gIEVOVElUWURhdGF0eXBlIFZhbGlkYXRvcjogZXJyb3JlLiBcdTAwQzggbmVjZXNzYXJpbyByaWNoaWFtYXJlIGlsIG1ldG9kbyBkaSBpbml6aWFsaXp6YXppb25lIGNvbiB1biByaWZlcmltZW50byBkaSBncmFtbWF0aWNhIHZhbGlkby4gXHQKLSAgICAgICAgRU5USVRZTm90VW5wYXJzZWQgPSBFTlRJVFkgInswfSIgbm9uIGFuYWxpenphdGEuCi0gICAgICAgIEVOVElUWU5vdFZhbGlkID0gRU5USVRZICJ7MH0iIG5vbiB2YWxpZGEuCi0gICAgICAgIEVtcHR5TGlzdCA9IEkgdmFsb3JpIGRpIHRpcG8gRU5USVRJRVMsIElEUkVGUyBlIE5NVE9LRU5TIG5vbiBwb3Nzb25vIGVzc2VyZSB1bmEgbGlzdGEgdnVvdGEuCi0KLSMgRW50aXR5IHJlbGF0ZWQgbWVzc2FnZXMKLSMgMy4xIFN0YXJ0LVRhZ3MsIEVuZC1UYWdzLCBhbmQgRW1wdHktRWxlbWVudCBUYWdzCi0gICAgICAgIFJlZmVyZW5jZVRvRXh0ZXJuYWxFbnRpdHkgPSBJbCByaWZlcmltZW50byBkaSBlbnRpdFx1MDBFMCBlc3Rlcm5hICImezB9OyIgbm9uIFx1MDBFOCBjb25zZW50aXRvIGluIHVuIHZhbG9yZSBkaSBhdHRyaWJ1dG8uCi0gICAgICAgIEFjY2Vzc0V4dGVybmFsRFREID0gRFREIGVzdGVybmE6IGxldHR1cmEgZGVsbGEgRFREIGVzdGVybmEgJyd7MH0nJyBub24gcml1c2NpdGEuIEFjY2Vzc28gJyd7MX0nJyBub24gY29uc2VudGl0byBhIGNhdXNhIGRlbGxhIGxpbWl0YXppb25lIGRlZmluaXRhIGRhbGxhIHByb3ByaWV0XHUwMEUwIGFjY2Vzc0V4dGVybmFsRFRELgotICAgICAgICBBY2Nlc3NFeHRlcm5hbEVudGl0eSA9IEVudGl0XHUwMEUwIGVzdGVybmE6IGxldHR1cmEgZGVsIGRvY3VtZW50byBlc3Rlcm5vICcnezB9Jycgbm9uIHJpdXNjaXRhLiBBY2Nlc3NvICcnezF9Jycgbm9uIGNvbnNlbnRpdG8gYSBjYXVzYSBkZWxsYSBsaW1pdGF6aW9uZSBkZWZpbml0YSBkYWxsYSBwcm9wcmlldFx1MDBFMCBhY2Nlc3NFeHRlcm5hbERURC4KLQotIyA0LjEgQ2hhcmFjdGVyIGFuZCBFbnRpdHkgUmVmZXJlbmNlcwotICAgICAgICBFbnRpdHlOb3REZWNsYXJlZCA9IEwnJ2VudGl0XHUwMEUwICJ7MH0iIFx1MDBFOCBpbmRpY2F0YSBkYSB1biByaWZlcmltZW50bywgbWEgbm9uIFx1MDBFOCBkaWNoaWFyYXRhLgotICAgICAgICBSZWZlcmVuY2VUb1VucGFyc2VkRW50aXR5ID0gSWwgcmlmZXJpbWVudG8gZGkgZW50aXRcdTAwRTAgbm9uIGFuYWxpenphdGEgIiZ7MH07IiBub24gXHUwMEU4IGNvbnNlbnRpdG8uCi0gICAgICAgIFJlY3Vyc2l2ZVJlZmVyZW5jZSA9IFJpZmVyaW1lbnRvIGRpIGVudGl0XHUwMEUwIHJpY29yc2l2byAiezB9IiAocGVyY29yc28gcmlmZXJpbWVudG86IHsxfSkuCi0gICAgICAgIFJlY3Vyc2l2ZUdlbmVyYWxSZWZlcmVuY2UgPSBSaWZlcmltZW50byBkaSBlbnRpdFx1MDBFMCBnZW5lcmFsZSByaWNvcnNpdm8gIiZ7MH07IiAocGVyY29yc28gcmlmZXJpbWVudG86IHsxfSkuCi0gICAgICAgIFJlY3Vyc2l2ZVBFUmVmZXJlbmNlID0gUmlmZXJpbWVudG8gZGkgZW50aXRcdTAwRTAgcGFyYW1ldHJvIHJpY29yc2l2byAiJXswfTsiIChwZXJjb3JzbyByaWZlcmltZW50bzogezF9KS4KLSMgNC4zLjMgQ2hhcmFjdGVyIEVuY29kaW5nIGluIEVudGl0aWVzCi0gICAgICAgIEVuY29kaW5nTm90U3VwcG9ydGVkID0gTGEgY29kaWZpY2EgInswfSIgbm9uIFx1MDBFOCBzdXBwb3J0YXRhLgotICAgICAgICBFbmNvZGluZ1JlcXVpcmVkID0gVW4nZW50aXRcdTAwRTAgYW5hbGl6emF0YSBub24gY29kaWZpY2F0YSBpbiBVVEYtOCBvIFVURi0xNiBkZXZlIGNvbnRlbmVyZSB1bmEgZGljaGlhcmF6aW9uZSBkaSBjb2RpZmljYS4KLSAgICAgICAgCi0jIE5hbWVzcGFjZXMgc3VwcG9ydAotIyA0LiBVc2luZyBRdWFsaWZpZWQgTmFtZXMKLSAgICAgICAgSWxsZWdhbFFOYW1lID0gTCdlbGVtZW50byBvIGwnYXR0cmlidXRvIG5vbiBjb3JyaXNwb25kZSBhbGxhIHByb2R1emlvbmUgZGVsIFFOYW1lOiBRTmFtZTo6PShOQ05hbWUnOicpP05DTmFtZS4gCi0gICAgICAgIEVsZW1lbnRYTUxOU1ByZWZpeCA9IEwnJ2VsZW1lbnRvICJ7MH0iIG5vbiBwdVx1MDBGMiBhdmVyZSAieG1sbnMiIGNvbWUgcHJlZmlzc28uCi0gICAgICAgIEVsZW1lbnRQcmVmaXhVbmJvdW5kID0gSWwgcHJlZmlzc28gInswfSIgcGVyIGwnJ2VsZW1lbnRvICJ7MX0iIG5vbiBcdTAwRTggYXNzb2NpYXRvLgotICAgICAgICBBdHRyaWJ1dGVQcmVmaXhVbmJvdW5kID0gSWwgcHJlZmlzc28gInsyfSIgcGVyIGwnJ2F0dHJpYnV0byAiezF9IiBhc3NvY2lhdG8gYSB1biB0aXBvIGRpIGVsZW1lbnRvICJ7MH0iIG5vbiBcdTAwRTggYXNzb2NpYXRvLgotICAgICAgICBFbXB0eVByZWZpeGVkQXR0TmFtZSA9IElsIHZhbG9yZSBkZWxsJydhdHRyaWJ1dG8gInswfSIgbm9uIFx1MDBFOCB2YWxpZG8uIExlIGFzc29jaWF6aW9uaSBkaSBzcGF6aSBkaSBub21pIGNvbiBwcmVmaXNzbyBub24gcG9zc29ubyBlc3NlcmUgdnVvdGUuCi0gICAgICAgIFByZWZpeERlY2xhcmVkID0gSWwgcHJlZmlzc28gc3BhemlvIGRpIG5vbWkgInswfSIgbm9uIFx1MDBFOCBzdGF0byBkaWNoaWFyYXRvLgotICAgICAgICBDYW50QmluZFhNTE5TID0gSWwgcHJlZmlzc28gInhtbG5zIiBub24gcHVcdTAwRjIgZXNzZXJlIGFzc29jaWF0byBlc3BsaWNpdGFtZW50ZSBhIHVubyBzcGF6aW8gZGkgbm9taSwgblx1MDBFOSBsbyBzcGF6aW8gZGkgbm9taSBwZXIgInhtbG5zIiBwdVx1MDBGMiBlc3NlcmUgYXNzb2NpYXRvIGVzcGxpY2l0YW1lbnRlIGEgdW4gcHJlZmlzc28uCi0gICAgICAgIENhbnRCaW5kWE1MID0gSWwgcHJlZmlzc28gInhtbCIgbm9uIHB1XHUwMEYyIGVzc2VyZSBhc3NvY2lhdG8gYSB1bm8gc3BhemlvIGRpIG5vbWkgZGl2ZXJzbyBkYSBxdWVsbG8gYWwgcXVhbGUgYXBwYXJ0aWVuZSwgblx1MDBFOSBsbyBzcGF6aW8gZGkgbm9taSBwZXIgInhtbCIgcHVcdTAwRjIgZXNzZXJlIGFzc29jaWF0byBhIHVuIHByZWZpc3NvIGRpdmVyc28gZGEgInhtbCIuCi0gICAgICAgIE1TR19BVFRfREVGQVVMVF9JTlZBTElEID0gZGVmYXVsdFZhbHVlICJ7MX0iIGRlbGwnJ2F0dHJpYnV0byAiezB9IiBub24gdmFsaWRvIHBlciBpIHZpbmNvbGkgbGVzc2ljYWxpIGRpIHF1ZXN0byB0aXBvIGRpIGF0dHJpYnV0by4KLQotIyBSRVZJU0lUOiBUaGVzZSBuZWVkIG1lc3NhZ2VzCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9BRlRFUl9TWVNURU1MSVRFUkFMX0lOX0VYVEVSTkFMSUQ9TVNHX1NQQUNFX1JFUVVJUkVEX0FGVEVSX1NZU1RFTUxJVEVSQUxfSU5fRVhURVJOQUxJRAotICAgICAgICBPcGVuUXVvdGVNaXNzaW5nSW5EZWNsPU9wZW5RdW90ZU1pc3NpbmdJbkRlY2wKLSAgICAgICAgSW52YWxpZENoYXJJbkxpdGVyYWw9SW52YWxpZENoYXJJbkxpdGVyYWwKLQotCi0jIEltcGxlbWVudGF0aW9uIGxpbWl0cwotICAgICAgICBFbnRpdHlFeHBhbnNpb25MaW1pdD1KQVhQMDAwMTAwMDE6IGlsIHBhcnNlciBoYSByaWxldmF0byBwaVx1MDBGOSAiezB9IiBlc3BhbnNpb25pIGRpIGVudGl0XHUwMEUwIG5lbCBkb2N1bWVudG8uIFF1ZXN0byBcdTAwRTggaWwgbGltaXRlIGltcG9zdG8gZGFsIGtpdCBKREsuCi0gICAgICAgIEVsZW1lbnRBdHRyaWJ1dGVMaW1pdD1KQVhQMDAwMTAwMDI6IGwnJ2VsZW1lbnRvICJ7MH0iIGNvbnRpZW5lIHBpXHUwMEY5IGRpICJ7MX0iIGF0dHJpYnV0aS4gInsxfSIgXHUwMEU4IGlsIGxpbWl0ZSBpbXBvc3RvIGRhbCBraXQgSkRLLgotICAgICAgICBNYXhFbnRpdHlTaXplTGltaXQ9SkFYUDAwMDEwMDAzOiBsYSBsdW5naGV6emEgZGVsbCcnZW50aXRcdTAwRTAgInswfSIgXHUwMEU4ICJ7MX0iLiBUYWxlIHZhbG9yZSBzdXBlcmEgaWwgbGltaXRlICJ7Mn0iIGRlZmluaXRvIGRhICJ7M30iLgotICAgICAgICBUb3RhbEVudGl0eVNpemVMaW1pdD1KQVhQMDAwMTAwMDQ6IGxlIGRpbWVuc2lvbmkgYWNjdW11bGF0ZSBkZWxsZSBlbnRpdFx1MDBFMCBzb25vIHBhcmkgYSAiezB9Ii4gVGFsZSB2YWxvcmUgc3VwZXJhIGlsIGxpbWl0ZSAiezF9IiBkZWZpbml0byBkYSAiezJ9Ii4KLSAgICAgICAgTWF4WE1MTmFtZUxpbWl0PUpBWFAwMDAxMDAwNTogbGEgbHVuZ2hlenphIGRlbGwnJ2VudGl0XHUwMEUwICJ7MH0iIFx1MDBFOCAiezF9Ii4gVGFsZSB2YWxvcmUgc3VwZXJhIGlsIGxpbWl0ZSAiezJ9IiBkZWZpbml0byBkYSAiezN9Ii4KLSAgICAgICAgTWF4RWxlbWVudERlcHRoTGltaXQ9SkFYUDAwMDEwMDA2OiBsYSBwcm9mb25kaXRcdTAwRTAgZGVsbCcnZWxlbWVudG8gInswfSIgXHUwMEU4ICJ7MX0iLiBUYWxlIHZhbG9yZSBzdXBlcmEgaWwgbGltaXRlICJ7Mn0iIGRlZmluaXRvIGRhICJ7M30iLgotICAgICAgICBFbnRpdHlSZXBsYWNlbWVudExpbWl0PUpBWFAwMDAxMDAwNzogaWwgbnVtZXJvIHRvdGFsZSBkaSBub2RpIG5laSByaWZlcmltZW50aSBlbnRpdFx1MDBFMCBcdTAwRTggInswfSIuIFRhbGUgdmFsb3JlIHN1cGVyYSBpbCBsaW1pdGUgZGkgInsxfSIgaW1wb3N0YXRvIGRhICJ7Mn0iLgotCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9YTUxNZXNzYWdlc19qYS5wcm9wZXJ0aWVzIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MTWVzc2FnZXNfamEucHJvcGVydGllcwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNzRlMDU5NC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9YTUxNZXNzYWdlc19qYS5wcm9wZXJ0aWVzCisrKyAvZGV2L251bGwKQEAgLTEsMzA1ICswLDAgQEAKLSMgVGhpcyBmaWxlIGNvbnRhaW5zIGVycm9yIGFuZCB3YXJuaW5nIG1lc3NhZ2VzIHJlbGF0ZWQgdG8gWE1MCi0jIFRoZSBtZXNzYWdlcyBhcmUgYXJyYW5nZWQgaW4ga2V5IGFuZCB2YWx1ZSB0dXBsZXMgaW4gYSBMaXN0UmVzb3VyY2VCdW5kbGUuCi0jCi0jIEB2ZXJzaW9uCi0KLSAgICAgICAgQmFkTWVzc2FnZUtleSA9IFx1MzBFMVx1MzBDM1x1MzBCQlx1MzBGQ1x1MzBCOFx1MzBGQlx1MzBBRFx1MzBGQ1x1MzA2Qlx1NUJGRVx1NUZEQ1x1MzA1OVx1MzA4Qlx1MzBBOFx1MzBFOVx1MzBGQ1x1MzBGQlx1MzBFMVx1MzBDM1x1MzBCQlx1MzBGQ1x1MzBCOFx1MzA0Q1x1ODk4Qlx1MzA2NFx1MzA0Qlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotICAgICAgICBGb3JtYXRGYWlsZWQgPSBcdTZCMjFcdTMwNkVcdTMwRTFcdTMwQzNcdTMwQkJcdTMwRkNcdTMwQjhcdTMwNkVcdTY2RjhcdTVGMEZcdThBMkRcdTVCOUFcdTRFMkRcdTMwNkJcdTUxODVcdTkwRThcdTMwQThcdTMwRTlcdTMwRkNcdTMwNENcdTc2N0FcdTc1MUZcdTMwNTdcdTMwN0VcdTMwNTdcdTMwNUY6XG4gIAotICAgICAgICAKLSMgRG9jdW1lbnQgbWVzc2FnZXMKLSAgICAgICAgUHJlbWF0dXJlRU9GPVx1OTAxNFx1NEUyRFx1MzA2N1x1MzBENVx1MzBBMVx1MzBBNFx1MzBFQlx1MzA2RVx1NjcyQlx1NUMzRVx1MzA2Qlx1OTA1NFx1MzA1N1x1MzA3RVx1MzA1N1x1MzA1Rlx1MzAwMgotIyAyLjEgV2VsbC1Gb3JtZWQgWE1MIERvY3VtZW50cwotICAgICAgICBSb290RWxlbWVudFJlcXVpcmVkID0gXHU2NTc0XHU1RjYyXHU1RjBGXHUzMEM5XHUzMEFEXHUzMEU1XHUzMEUxXHUzMEYzXHUzMEM4XHUzMDZCXHUzMDZGXHUzMEVCXHUzMEZDXHUzMEM4XHU4OTgxXHU3RDIwXHUzMDRDXHU1RkM1XHU4OTgxXHUzMDY3XHUzMDU5XHUzMDAyCi0jIDIuMiBDaGFyYWN0ZXJzCi0KLSAgICAgICAgSW52YWxpZENoYXJJbkNEU2VjdCA9IENEQVRBXHUzMEJCXHUzMEFGXHUzMEI3XHUzMEU3XHUzMEYzXHUzMDZCXHU3MTIxXHU1MkI5XHUzMDZBWE1MXHU2NTg3XHU1QjU3KFVuaWNvZGU6IDB4ezB9KVx1MzA0Q1x1ODk4Qlx1MzA2NFx1MzA0Qlx1MzA4QVx1MzA3RVx1MzA1N1x1MzA1Rlx1MzAwMgotICAgICAgICBJbnZhbGlkQ2hhckluQ29udGVudCA9IFx1MzBDOVx1MzBBRFx1MzBFNVx1MzBFMVx1MzBGM1x1MzBDOFx1MzA2RVx1ODk4MVx1N0QyMFx1MzBCM1x1MzBGM1x1MzBDNlx1MzBGM1x1MzBDNFx1MzA2Qlx1NzEyMVx1NTJCOVx1MzA2QVhNTFx1NjU4N1x1NUI1NyhVbmljb2RlOiAweHswfSlcdTMwNENcdTg5OEJcdTMwNjRcdTMwNEJcdTMwOEFcdTMwN0VcdTMwNTdcdTMwNUZcdTMwMDIKLSAgICAgICAgVHdvQ29sb25zSW5RTmFtZSA9IFx1ODk4MVx1N0QyMFx1MzBCRlx1MzBBNFx1MzBEN1x1MzA3RVx1MzA1Rlx1MzA2Rlx1NUM1RVx1NjAyN1x1NTQwRFx1MzA2Qlx1NzEyMVx1NTJCOVx1MzA2QSc6J1x1MzA0Q1x1MzA4Mlx1MzA0NjFcdTMwNjRcdTg5OEJcdTMwNjRcdTMwNEJcdTMwOEFcdTMwN0VcdTMwNTdcdTMwNUZcdTMwMDIKLSAgICAgICAgQ29sb25Ob3RMZWdhbFdpdGhOUyA9IFx1MzBDRFx1MzBGQ1x1MzBFMFx1MzBCOVx1MzBEQVx1MzBGQ1x1MzBCOVx1MzA0Q1x1NjcwOVx1NTJCOVx1MzA2Qlx1MzA2QVx1MzA2M1x1MzA2Nlx1MzA0NFx1MzA4Qlx1NTgzNFx1NTQwOFx1MzAwMVx1NTQwRFx1NTI0RCcnezB9JydcdTMwNkJcdTMwQjNcdTMwRURcdTMwRjNcdTMwNkZcdTRGN0ZcdTc1MjhcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLSAgICAgICAgSW52YWxpZENoYXJJbk1pc2MgPSBcdTg5ODFcdTdEMjBcdTMwQjNcdTMwRjNcdTMwQzZcdTMwRjNcdTMwQzRcdTMwNkVcdTdENDJcdTMwOEZcdTMwOEFcdTMwNkVcdTVGOENcdTMwNkVcdTMwREVcdTMwRkNcdTMwQUZcdTMwQTJcdTMwQzNcdTMwRDdcdTMwNkJcdTcxMjFcdTUyQjlcdTMwNkFYTUxcdTY1ODdcdTVCNTcoVW5pY29kZTogMHh7MH0pXHUzMDRDXHU4OThCXHUzMDY0XHUzMDRCXHUzMDhBXHUzMDdFXHUzMDU3XHUzMDVGXHUzMDAyCi0gICAgICAgIEludmFsaWRDaGFySW5Qcm9sb2cgPSBcdTMwQzlcdTMwQURcdTMwRTVcdTMwRTFcdTMwRjNcdTMwQzhcdTMwNkVcdTMwRDdcdTMwRURcdTMwRURcdTMwRkNcdTMwQjBcdTMwNkJcdTcxMjFcdTUyQjlcdTMwNkFYTUxcdTY1ODdcdTVCNTcoVW5pY29kZTogMHh7MH0pXHUzMDRDXHU4OThCXHUzMDY0XHUzMDRCXHUzMDhBXHUzMDdFXHUzMDU3XHUzMDVGXHUzMDAyCi0gICAgICAgIEludmFsaWRDaGFySW5YTUxEZWNsID0gWE1MXHU1QkEzXHU4QTAwXHUzMDZCXHU3MTIxXHU1MkI5XHUzMDZBWE1MXHU2NTg3XHU1QjU3KFVuaWNvZGU6IDB4ezB9KVx1MzA0Q1x1ODk4Qlx1MzA2NFx1MzA0Qlx1MzA4QVx1MzA3RVx1MzA1N1x1MzA1Rlx1MzAwMgotIyAyLjQgQ2hhcmFjdGVyIERhdGEgYW5kIE1hcmt1cAotICAgICAgICBDREVuZEluQ29udGVudCA9IFx1NjU4N1x1NUI1N1x1MzBCN1x1MzBGQ1x1MzBCMVx1MzBGM1x1MzBCOSJdXT4iXHUzMDZGXHUzMDAxQ0RBVEFcdTMwQkJcdTMwQUZcdTMwQjdcdTMwRTdcdTMwRjNcdTMwNkVcdTdENDJcdTMwOEZcdTMwOEFcdTMwOTJcdTc5M0FcdTMwNTlcdTc2RUVcdTc2ODRcdTRFRTVcdTU5MTZcdTMwNjdcdTMwQjNcdTMwRjNcdTMwQzZcdTMwRjNcdTMwQzRcdTMwNkJcdTRGN0ZcdTc1MjhcdTMwNTdcdTMwNkFcdTMwNDRcdTMwNjdcdTMwNEZcdTMwNjBcdTMwNTVcdTMwNDRcdTMwMDIKLSMgMi43IENEQVRBIFNlY3Rpb25zCi0gICAgICAgIENEU2VjdFVudGVybWluYXRlZCA9IENEQVRBXHUzMEJCXHUzMEFGXHUzMEI3XHUzMEU3XHUzMEYzXHUzMDZGIl1dPiJcdTMwNjdcdTdENDJcdTRFODZcdTMwNTlcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIKLSMgMi44IFByb2xvZyBhbmQgRG9jdW1lbnQgVHlwZSBEZWNsYXJhdGlvbgotICAgICAgICBYTUxEZWNsTXVzdEJlRmlyc3QgPSBYTUxcdTVCQTNcdThBMDBcdTMwNkZcdTMwMDFcdTMwQzlcdTMwQURcdTMwRTVcdTMwRTFcdTMwRjNcdTMwQzhcdTMwNkVcdTUxNDhcdTk4MkRcdTMwNjdcdTMwNkVcdTMwN0ZcdTRGN0ZcdTc1MjhcdTMwNjdcdTMwNERcdTMwN0VcdTMwNTlcdTMwMDIKLSAgICAgICAgRXFSZXF1aXJlZEluWE1MRGVjbCA9IFhNTFx1NUJBM1x1OEEwMFx1MzA2N1x1MzA2Rlx1MzAwMSJ7MH0iXHUzMDZFXHU1RjhDXHUzMDZCJycgPSAnJ1x1NjU4N1x1NUI1N1x1MzA0Q1x1NUZDNVx1ODk4MVx1MzA2N1x1MzA1OVx1MzAwMgotICAgICAgICBRdW90ZVJlcXVpcmVkSW5YTUxEZWNsID0gWE1MXHU1QkEzXHU4QTAwXHUzMDZFInswfSJcdTMwNkVcdTVGOENcdTMwNkJcdTdEOUFcdTMwNEZcdTUwMjRcdTMwNkZcdTMwMDFcdTVGMTVcdTc1MjhcdTdCMjZcdTMwNjdcdTU2RjJcdTMwOTNcdTMwNjBcdTY1ODdcdTVCNTdcdTUyMTdcdTMwNkJcdTMwNTlcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIKLSAgICAgICAgWE1MRGVjbFVudGVybWluYXRlZCA9IFhNTFx1NUJBM1x1OEEwMFx1MzA2RiI/PiJcdTMwNjdcdTdENDJcdTRFODZcdTMwNTlcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIKLSAgICAgICAgVmVyc2lvbkluZm9SZXF1aXJlZCA9IFhNTFx1NUJBM1x1OEEwMFx1MzA2Qlx1MzA2Rlx1MzBEMFx1MzBGQ1x1MzBCOFx1MzBFN1x1MzBGM1x1MzA0Q1x1NUZDNVx1ODk4MVx1MzA2N1x1MzA1OVx1MzAwMgotICAgICAgICBTcGFjZVJlcXVpcmVkQmVmb3JlVmVyc2lvbkluWE1MRGVjbCA9IFhNTFx1NUJBM1x1OEEwMFx1MzA2N1x1MzA2Rlx1MzAwMVx1MzBEMFx1MzBGQ1x1MzBCOFx1MzBFN1x1MzBGM1x1NzU5MVx1NEYzQ1x1NUM1RVx1NjAyN1x1MzA2RVx1NTI0RFx1MzA2Qlx1N0E3QVx1NzY3RFx1MzA0Q1x1NUZDNVx1ODk4MVx1MzA2N1x1MzA1OVx1MzAwMgotICAgICAgICBTcGFjZVJlcXVpcmVkQmVmb3JlRW5jb2RpbmdJblhNTERlY2wgPSBYTUxcdTVCQTNcdThBMDBcdTMwNjdcdTMwNkZcdTMwMDFcdTMwQThcdTMwRjNcdTMwQjNcdTMwRkNcdTMwQzdcdTMwQTNcdTMwRjNcdTMwQjBcdTc1OTFcdTRGM0NcdTVDNUVcdTYwMjdcdTMwNkVcdTUyNERcdTMwNkJcdTdBN0FcdTc2N0RcdTMwNENcdTVGQzVcdTg5ODFcdTMwNjdcdTMwNTlcdTMwMDIKLSAgICAgICAgU3BhY2VSZXF1aXJlZEJlZm9yZVN0YW5kYWxvbmUgPSBYTUxcdTVCQTNcdThBMDBcdTMwNjdcdTMwNkZcdTMwMDFcdTMwQThcdTMwRjNcdTMwQjNcdTMwRkNcdTMwQzdcdTMwQTNcdTMwRjNcdTMwQjBcdTc1OTFcdTRGM0NcdTVDNUVcdTYwMjdcdTMwNkVcdTUyNERcdTMwNkJcdTdBN0FcdTc2N0RcdTMwNENcdTVGQzVcdTg5ODFcdTMwNjdcdTMwNTlcdTMwMDIKLSAgICAgICAgTWFya3VwTm90UmVjb2duaXplZEluUHJvbG9nID0gXHUzMEM5XHUzMEFEXHUzMEU1XHUzMEUxXHUzMEYzXHUzMEM4XHU1MTg1XHUzMDZFXHUzMEVCXHUzMEZDXHUzMEM4XHU4OTgxXHU3RDIwXHUzMDg4XHUzMDhBXHU1MjREXHUzMDZFXHUzMERFXHUzMEZDXHUzMEFGXHUzMEEyXHUzMEMzXHUzMEQ3XHUzMDZGXHU2NTc0XHU1RjYyXHU1RjBGXHUzMDY3XHUzMDQyXHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIE1hcmt1cE5vdFJlY29nbml6ZWRJbk1pc2MgPSBcdTMwQzlcdTMwQURcdTMwRTVcdTMwRTFcdTMwRjNcdTMwQzhcdTUxODVcdTMwNkVcdTMwRUJcdTMwRkNcdTMwQzhcdTg5ODFcdTdEMjBcdTMwNkJcdTdEOUFcdTMwNEZcdTMwREVcdTMwRkNcdTMwQUZcdTMwQTJcdTMwQzNcdTMwRDdcdTMwNkZcdTY1NzRcdTVGNjJcdTVGMEZcdTMwNjdcdTMwNDJcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIKLSAgICAgICAgQWxyZWFkeVNlZW5Eb2N0eXBlID0gRE9DVFlQRVx1MzA2Rlx1MzA1OVx1MzA2N1x1MzA2Qlx1NUI1OFx1NTcyOFx1MzA1N1x1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBEb2N0eXBlTm90QWxsb3dlZCA9IFx1NkE1Rlx1ODBGRCJodHRwOi8vYXBhY2hlLm9yZy94bWwvZmVhdHVyZXMvZGlzYWxsb3ctZG9jdHlwZS1kZWNsIlx1MzA0Q3RydWVcdTMwNkJcdThBMkRcdTVCOUFcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwOEJcdTU4MzRcdTU0MDhcdTMwMDFET0NUWVBFXHUzMDZGXHU2MzA3XHU1QjlBXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0gICAgICAgIENvbnRlbnRJbGxlZ2FsSW5Qcm9sb2cgPSBcdTMwRDdcdTMwRURcdTMwRURcdTMwRkNcdTMwQjBcdTMwNkJcdTMwNkZcdTMwQjNcdTMwRjNcdTMwQzZcdTMwRjNcdTMwQzRcdTMwOTJcdTYzMDdcdTVCOUFcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLSAgICAgICAgUmVmZXJlbmNlSWxsZWdhbEluUHJvbG9nID0gXHUzMEQ3XHUzMEVEXHUzMEVEXHUzMEZDXHUzMEIwXHUzMDZCXHUzMDZGXHU1M0MyXHU3MTY3XHUzMDkyXHU2MzA3XHU1QjlBXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0jIFRyYWlsaW5nIE1pc2MKLSAgICAgICAgQ29udGVudElsbGVnYWxJblRyYWlsaW5nTWlzYz1cdTVGOENcdTdEOUFcdTMwQkJcdTMwQUZcdTMwQjdcdTMwRTdcdTMwRjNcdTMwNkJcdTMwNkZcdTMwQjNcdTMwRjNcdTMwQzZcdTMwRjNcdTMwQzRcdTMwOTJcdTYzMDdcdTVCOUFcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLSAgICAgICAgUmVmZXJlbmNlSWxsZWdhbEluVHJhaWxpbmdNaXNjPVx1NUY4Q1x1N0Q5QVx1MzBCQlx1MzBBRlx1MzBCN1x1MzBFN1x1MzBGM1x1MzA2Qlx1MzA2Rlx1NTNDMlx1NzE2N1x1MzA5Mlx1NjMwN1x1NUI5QVx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotICAgICAgICAKLSMgMi45IFN0YW5kYWxvbmUgRG9jdW1lbnQgRGVjbGFyYXRpb24KLSAgICAgICAgU0REZWNsSW52YWxpZCA9IFx1MzBCOVx1MzBCRlx1MzBGM1x1MzBDOVx1MzBBMlx1MzBFRFx1MzBGM1x1MzBGQlx1MzBDOVx1MzBBRFx1MzBFNVx1MzBFMVx1MzBGM1x1MzBDOFx1NUJBM1x1OEEwMFx1MzA2RVx1NTAyNFx1MzA2Rlx1MzAwMSJ7MH0iXHUzMDY3XHUzMDZGXHUzMDZBXHUzMDRGXHUzMDAxInllcyJcdTMwN0VcdTMwNUZcdTMwNkYibm8iXHUzMDZCXHUzMDU5XHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIFNERGVjbE5hbWVJbnZhbGlkID0gWE1MXHU1QkEzXHU4QTAwXHUzMDZFXHUzMEI5XHUzMEJGXHUzMEYzXHUzMEM5XHUzMEEyXHUzMEVEXHUzMEYzXHU1NDBEXHUzMDRDXHU5NTkzXHU5MDU1XHUzMDYzXHUzMDY2XHUzMDQ0XHUzMDhCXHU1M0VGXHU4MEZEXHU2MDI3XHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCi0jIDIuMTIgTGFuZ3VhZ2UgSWRlbnRpZmljYXRpb24KLSAgICAgICAgWE1MTGFuZ0ludmFsaWQgPSB4bWw6bGFuZ1x1NUM1RVx1NjAyN1x1MzA2RVx1NTAyNCJ7MH0iXHUzMDZGXHU3MTIxXHU1MkI5XHUzMDZBXHU4QTAwXHU4QTlFXHU4QjU4XHU1MjI1XHU1QjUwXHUzMDY3XHUzMDU5XHUzMDAyCi0jIDMuIExvZ2ljYWwgU3RydWN0dXJlcwotICAgICAgICBFVGFnUmVxdWlyZWQgPSBcdTg5ODFcdTdEMjBcdTMwQkZcdTMwQTRcdTMwRDciezB9Ilx1MzA2Rlx1MzAwMVx1NUJGRVx1NUZEQ1x1MzA1OVx1MzA4Qlx1N0Q0Mlx1NEU4Nlx1MzBCRlx1MzBCMCI8L3swfT4iXHUzMDY3XHU3RDQyXHU0RTg2XHUzMDU5XHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCi0jIDMuMSBTdGFydC1UYWdzLCBFbmQtVGFncywgYW5kIEVtcHR5LUVsZW1lbnQgVGFncwotICAgICAgICBFbGVtZW50VW50ZXJtaW5hdGVkID0gXHU4OTgxXHU3RDIwXHUzMEJGXHUzMEE0XHUzMEQ3InswfSJcdTMwNkVcdTVGOENcdTMwNkJcdTMwNkZcdTMwMDFcdTVDNUVcdTYwMjdcdTYzMDdcdTVCOUEiPiJcdTMwN0VcdTMwNUZcdTMwNkYiLz4iXHUzMDRDXHU1RkM1XHU4OTgxXHUzMDY3XHUzMDU5XHUzMDAyCi0gICAgICAgIEVxUmVxdWlyZWRJbkF0dHJpYnV0ZSA9IFx1ODk4MVx1N0QyMFx1MzBCRlx1MzBBNFx1MzBENyJ7MH0iXHUzMDZCXHU5NUEyXHU5MDIzXHU0RUQ4XHUzMDUxXHUzMDg5XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDhCXHU1QzVFXHU2MDI3XHU1NDBEInsxfSJcdTMwNkVcdTVGOENcdTMwNkJcdTMwNkZcdTMwMDEnJyA9ICcnXHU2NTg3XHU1QjU3XHUzMDRDXHU1RkM1XHU4OTgxXHUzMDY3XHUzMDU5XHUzMDAyCi0gICAgICAgIE9wZW5RdW90ZUV4cGVjdGVkID0gXHU4OTgxXHU3RDIwXHUzMEJGXHUzMEE0XHUzMEQ3InswfSJcdTMwNkJcdTk1QTJcdTkwMjNcdTRFRDhcdTMwNTFcdTMwODlcdTMwOENcdTMwNjZcdTMwNDRcdTMwOEJcdTVDNUVcdTYwMjciezF9Ilx1MzA2Qlx1MzA2Rlx1MzAwMVx1OTU4Qlx1NTlDQlx1NUYxNVx1NzUyOFx1N0IyNlx1MzA0Q1x1NUZDNVx1ODk4MVx1MzA2N1x1MzA1OVx1MzAwMgotICAgICAgICBDbG9zZVF1b3RlRXhwZWN0ZWQgPSBcdTg5ODFcdTdEMjBcdTMwQkZcdTMwQTRcdTMwRDciezB9Ilx1MzA2Qlx1OTVBMlx1OTAyM1x1NEVEOFx1MzA1MVx1MzA4OVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA4Qlx1NUM1RVx1NjAyNyJ7MX0iXHUzMDZCXHUzMDZGXHUzMDAxXHU3RDQyXHU0RTg2XHU1RjE1XHU3NTI4XHU3QjI2XHUzMDRDXHU1RkM1XHU4OTgxXHUzMDY3XHUzMDU5XHUzMDAyCi0gICAgICAgIEF0dHJpYnV0ZU5vdFVuaXF1ZSA9IFx1NUM1RVx1NjAyNyJ7MX0iXHUzMDZGXHU4OTgxXHU3RDIwInswfSJcdTMwNkJcdTVCRkVcdTMwNTdcdTMwNjZcdTMwNTlcdTMwNjdcdTMwNkJcdTYzMDdcdTVCOUFcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTlcdTMwMDIKLSAgICAgICAgQXR0cmlidXRlTlNOb3RVbmlxdWUgPSBcdTMwQ0RcdTMwRkNcdTMwRTBcdTMwQjlcdTMwREFcdTMwRkNcdTMwQjkiezJ9Ilx1MzA2Qlx1MzBEMFx1MzBBNFx1MzBGM1x1MzBDOVx1MzA1NVx1MzA4Q1x1MzA1Rlx1NUM1RVx1NjAyNyJ7MX0iXHUzMDZGXHU4OTgxXHU3RDIwInswfSJcdTMwNkJcdTVCRkVcdTMwNTdcdTMwNjZcdTMwNTlcdTMwNjdcdTMwNkJcdTYzMDdcdTVCOUFcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTlcdTMwMDIKLSAgICAgICAgRVRhZ1VudGVybWluYXRlZCA9IFx1ODk4MVx1N0QyMFx1MzBCRlx1MzBBNFx1MzBENyJ7MH0iXHUzMDZFXHU3RDQyXHU0RTg2XHUzMEJGXHUzMEIwXHUzMDZGJyc+JydcdTMwQzdcdTMwRUFcdTMwREZcdTMwQkZcdTMwNjdcdTdENDJcdTRFODZcdTMwNTlcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIKLSAgICAgICAgTWFya3VwTm90UmVjb2duaXplZEluQ29udGVudCA9IFx1ODk4MVx1N0QyMFx1MzA2RVx1MzBCM1x1MzBGM1x1MzBDNlx1MzBGM1x1MzBDNFx1MzA2Rlx1MzAwMVx1NjU3NFx1NUY2Mlx1NUYwRlx1MzA2RVx1NjU4N1x1NUI1N1x1MzBDN1x1MzBGQ1x1MzBCRlx1MzA3RVx1MzA1Rlx1MzA2Rlx1MzBERVx1MzBGQ1x1MzBBRlx1MzBBMlx1MzBDM1x1MzBEN1x1MzA2N1x1NjlDQlx1NjIxMFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBEb2N0eXBlSWxsZWdhbEluQ29udGVudCA9IFx1MzBCM1x1MzBGM1x1MzBDNlx1MzBGM1x1MzBDNFx1MzA2Qlx1MzA2RkRPQ1RZUEVcdTMwOTJcdTYzMDdcdTVCOUFcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLSMgNC4xIENoYXJhY3RlciBhbmQgRW50aXR5IFJlZmVyZW5jZXMKLSAgICAgICAgUmVmZXJlbmNlVW50ZXJtaW5hdGVkID0gXHU1M0MyXHU3MTY3XHUzMDZGJzsnXHUzMEM3XHUzMEVBXHUzMERGXHUzMEJGXHUzMDY3XHU3RDQyXHU0RTg2XHUzMDU5XHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCi0jIDQuMy4yIFdlbGwtRm9ybWVkIFBhcnNlZCBFbnRpdGllcwotICAgICAgICBSZWZlcmVuY2VOb3RJbk9uZUVudGl0eSA9IFx1NTNDMlx1NzE2N1x1MzA2Rlx1MzAwMVx1NTQwQ1x1MzA1OFx1ODlFM1x1Njc5MFx1NkUwOFx1MzBBOFx1MzBGM1x1MzBDNlx1MzBBM1x1MzBDNlx1MzBBM1x1NTE4NVx1MzA2Qlx1NUI4Q1x1NTE2OFx1MzA2Qlx1NTQyQlx1MzA3RVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBFbGVtZW50RW50aXR5TWlzbWF0Y2ggPSBcdTg5ODFcdTdEMjAiezB9Ilx1MzA2Rlx1MzAwMVx1NTQwQ1x1MzA1OFx1MzBBOFx1MzBGM1x1MzBDNlx1MzBBM1x1MzBDNlx1MzBBM1x1NTE4NVx1MzA2N1x1OTU4Qlx1NTlDQlx1MzA0QVx1MzA4OFx1MzA3M1x1N0Q0Mlx1NEU4Nlx1MzA1OVx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBNYXJrdXBFbnRpdHlNaXNtYXRjaD1YTUxcdTMwQzlcdTMwQURcdTMwRTVcdTMwRTFcdTMwRjNcdTMwQzhcdTY5Q0JcdTkwMjBcdTMwNkZcdTMwMDFcdTU0MENcdTMwNThcdTMwQThcdTMwRjNcdTMwQzZcdTMwQTNcdTMwQzZcdTMwQTNcdTUxODVcdTMwNjdcdTk1OEJcdTU5Q0JcdTMwNEFcdTMwODhcdTMwNzNcdTdENDJcdTRFODZcdTMwNTlcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIKLSAgICAgICAgCi0jIE1lc3NhZ2VzIGNvbW1vbiB0byBEb2N1bWVudCBhbmQgRFRECi0jIDIuMiBDaGFyYWN0ZXJzCi0gICAgICAgIEludmFsaWRDaGFySW5BdHRWYWx1ZSA9IFx1NUM1RVx1NjAyNyJ7MX0iXHUzMDZFXHU1MDI0XHUzMDZCXHU3MTIxXHU1MkI5XHUzMDZBWE1MXHU2NTg3XHU1QjU3KFVuaWNvZGU6IDB4ezJ9KVx1MzA0Q1x1ODk4Qlx1MzA2NFx1MzA0Qlx1MzA4QVx1MzA3RVx1MzA1N1x1MzA1Rlx1MzAwMlx1ODk4MVx1N0QyMFx1MzA2RiJ7MH0iXHUzMDY3XHUzMDU5XHUzMDAyCi0gICAgICAgIEludmFsaWRDaGFySW5Db21tZW50ID0gXHUzMEIzXHUzMEUxXHUzMEYzXHUzMEM4XHUzMDZCXHU3MTIxXHU1MkI5XHUzMDZBWE1MXHU2NTg3XHU1QjU3KFVuaWNvZGU6IDB4ezB9KVx1MzA0Q1x1ODk4Qlx1MzA2NFx1MzA0Qlx1MzA4QVx1MzA3RVx1MzA1N1x1MzA1Rlx1MzAwMgotICAgICAgICBJbnZhbGlkQ2hhckluUEkgPSBcdTUxRTZcdTc0MDZcdTU0N0RcdTRFRTRcdTMwNkJcdTcxMjFcdTUyQjlcdTMwNkFYTUxcdTY1ODdcdTVCNTcoVW5pY29kZTogMHh7MH0pXHUzMDRDXHU4OThCXHUzMDY0XHUzMDRCXHUzMDhBXHUzMDdFXHUzMDU3XHUzMDVGXHUzMDAyCi0gICAgICAgIEludmFsaWRDaGFySW5JbnRlcm5hbFN1YnNldCA9IERURFx1MzA2RVx1NTE4NVx1OTBFOFx1MzBCNVx1MzBENlx1MzBCQlx1MzBDM1x1MzBDOFx1MzA2Qlx1NzEyMVx1NTJCOVx1MzA2QVhNTFx1NjU4N1x1NUI1NyhVbmljb2RlOiAweHswfSlcdTMwNENcdTg5OEJcdTMwNjRcdTMwNEJcdTMwOEFcdTMwN0VcdTMwNTdcdTMwNUZcdTMwMDIKLSAgICAgICAgSW52YWxpZENoYXJJblRleHREZWNsID0gXHUzMEM2XHUzMEFEXHUzMEI5XHUzMEM4XHU1QkEzXHU4QTAwXHUzMDZCXHU3MTIxXHU1MkI5XHUzMDZBWE1MXHU2NTg3XHU1QjU3KFVuaWNvZGU6IDB4ezB9KVx1MzA0Q1x1ODk4Qlx1MzA2NFx1MzA0Qlx1MzA4QVx1MzA3RVx1MzA1N1x1MzA1Rlx1MzAwMgotIyAyLjMgQ29tbW9uIFN5bnRhY3RpYyBDb25zdHJ1Y3RzCi0gICAgICAgIFF1b3RlUmVxdWlyZWRJbkF0dFZhbHVlID0gXHU1QzVFXHU2MDI3InsxfSJcdTMwNkVcdTUwMjRcdTMwNkVcdTUxNDhcdTk4MkRcdTMwNkJcdTMwNkZcdTMwMDFcdTRFMDBcdTkxQ0RcdTVGMTVcdTc1MjhcdTdCMjZcdTY1ODdcdTVCNTdcdTMwN0VcdTMwNUZcdTMwNkZcdTRFOENcdTkxQ0RcdTVGMTVcdTc1MjhcdTdCMjZcdTY1ODdcdTVCNTdcdTMwNENcdTVGQzVcdTg5ODFcdTMwNjdcdTMwNTlcdTMwMDIKLSAgICAgICAgTGVzc3RoYW5JbkF0dFZhbHVlID0gXHU4OTgxXHU3RDIwXHUzMEJGXHUzMEE0XHUzMEQ3InswfSJcdTMwNkJcdTk1QTJcdTkwMjNcdTRFRDhcdTMwNTFcdTMwODlcdTMwOENcdTMwNjZcdTMwNDRcdTMwOEJcdTVDNUVcdTYwMjciezF9Ilx1MzA2RVx1NTAyNFx1MzA2Qlx1MzA2Rlx1MzAwMScnPCcnXHU2NTg3XHU1QjU3XHUzMDkyXHU1NDJCXHUzMDgxXHUzMDhCXHUzMDUzXHUzMDY4XHUzMDZGXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0gICAgICAgIEF0dHJpYnV0ZVZhbHVlVW50ZXJtaW5hdGVkID0gXHU1QzVFXHU2MDI3InsxfSJcdTMwNkVcdTUwMjRcdTMwNkZcdTMwMDFcdTVCRkVcdTVGRENcdTMwNTlcdTMwOEJcdTVGMTVcdTc1MjhcdTdCMjZcdTY1ODdcdTVCNTdcdTMwNjdcdTdENDJcdTRFODZcdTMwNTlcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIKLSMgMi41IENvbW1lbnRzCi0gICAgICAgIEludmFsaWRDb21tZW50U3RhcnQgPSBcdTMwQjNcdTMwRTFcdTMwRjNcdTMwQzhcdTMwNkVcdTUxNDhcdTk4MkRcdTMwNkJcdTMwNkYiPCEtLSJcdTMwNENcdTVGQzVcdTg5ODFcdTMwNjdcdTMwNTlcdTMwMDIKLSAgICAgICAgRGFzaERhc2hJbkNvbW1lbnQgPSBcdTMwQjNcdTMwRTFcdTMwRjNcdTMwQzhcdTUxODVcdTMwNjdcdTMwNkZcdTY1ODdcdTVCNTdcdTUyMTciLS0iXHUzMDZGXHU0RjdGXHU3NTI4XHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0gICAgICAgIENvbW1lbnRVbnRlcm1pbmF0ZWQgPSBcdTMwQjNcdTMwRTFcdTMwRjNcdTMwQzhcdTMwNkYiLS0+Ilx1MzA2N1x1N0Q0Mlx1NEU4Nlx1MzA1OVx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBDT01NRU5UX05PVF9JTl9PTkVfRU5USVRZID0gXHUzMEIzXHUzMEUxXHUzMEYzXHUzMEM4XHUzMDRDXHU1NDBDXHUzMDU4XHUzMEE4XHUzMEYzXHUzMEM2XHUzMEEzXHUzMEM2XHUzMEEzXHUzMDY3XHU1NkYyXHUzMDdFXHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0jIDIuNiBQcm9jZXNzaW5nIEluc3RydWN0aW9ucwotICAgICAgICBQSVRhcmdldFJlcXVpcmVkID0gXHU1MUU2XHU3NDA2XHU1NDdEXHU0RUU0XHUzMDZFXHU1MTQ4XHU5ODJEXHUzMDZCXHUzMDZGXHUzMEJGXHUzMEZDXHUzMEIyXHUzMEMzXHUzMEM4XHUzMDZFXHU1NDBEXHU1MjREXHUzMDRDXHU1RkM1XHU4OTgxXHUzMDY3XHUzMDU5XHUzMDAyCi0gICAgICAgIFNwYWNlUmVxdWlyZWRJblBJID0gXHU1MUU2XHU3NDA2XHU1NDdEXHU0RUU0XHUzMEJGXHUzMEZDXHUzMEIyXHUzMEMzXHUzMEM4XHUzMDY4XHUzMEM3XHUzMEZDXHUzMEJGXHUzMDZFXHU5NTkzXHUzMDZCXHUzMDZGXHU3QTdBXHU3NjdEXHUzMDRDXHU1RkM1XHU4OTgxXHUzMDY3XHUzMDU5XHUzMDAyCi0gICAgICAgIFBJVW50ZXJtaW5hdGVkID0gXHU1MUU2XHU3NDA2XHU1NDdEXHU0RUU0XHUzMDZGIj8+Ilx1MzA2N1x1N0Q0Mlx1NEU4Nlx1MzA1OVx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBSZXNlcnZlZFBJVGFyZ2V0ID0gIlt4WF1bbU1dW2xMXSJcdTMwNjhcdTRFMDBcdTgxRjRcdTMwNTlcdTMwOEJcdTUxRTZcdTc0MDZcdTU0N0RcdTRFRTRcdTMwQkZcdTMwRkNcdTMwQjJcdTMwQzNcdTMwQzhcdTMwNkZcdThBMzFcdTUzRUZcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLSAgICAgICAgUElfTk9UX0lOX09ORV9FTlRJVFkgPSBcdTUxRTZcdTc0MDZcdTU0N0RcdTRFRTRcdTMwNENcdTU0MENcdTMwNThcdTMwQThcdTMwRjNcdTMwQzZcdTMwQTNcdTMwQzZcdTMwQTNcdTMwNjdcdTU2RjJcdTMwN0VcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLSMgMi44IFByb2xvZyBhbmQgRG9jdW1lbnQgVHlwZSBEZWNsYXJhdGlvbgotICAgICAgICBWZXJzaW9uSW5mb0ludmFsaWQgPSBcdTMwRDBcdTMwRkNcdTMwQjhcdTMwRTdcdTMwRjMiezB9Ilx1MzA2Rlx1NzEyMVx1NTJCOVx1MzA2N1x1MzA1OVx1MzAwMgotICAgICAgICBWZXJzaW9uTm90U3VwcG9ydGVkID0gWE1MXHUzMEQwXHUzMEZDXHUzMEI4XHUzMEU3XHUzMEYzInswfSJcdTMwNkZcdTMwQjVcdTMwRERcdTMwRkNcdTMwQzhcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDJcdTMwQjVcdTMwRERcdTMwRkNcdTMwQzhcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwOEJcdTMwNkVcdTMwNkZYTUwgMS4wXHUzMDZFXHUzMDdGXHUzMDY3XHUzMDU5XHUzMDAyCi0gICAgICAgIFZlcnNpb25Ob3RTdXBwb3J0ZWQxMSA9IFhNTFx1MzBEMFx1MzBGQ1x1MzBCOFx1MzBFN1x1MzBGMyJ7MH0iXHUzMDZGXHUzMEI1XHUzMEREXHUzMEZDXHUzMEM4XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyXHUzMEI1XHUzMEREXHUzMEZDXHUzMEM4XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDhCXHUzMDZFXHUzMDZGWE1MIDEuMFx1MzA0QVx1MzA4OFx1MzA3M1hNTCAxLjFcdTMwNkVcdTMwN0ZcdTMwNjdcdTMwNTlcdTMwMDIKLSAgICAgICAgVmVyc2lvbk1pc21hdGNoPSBcdTMwQThcdTMwRjNcdTMwQzZcdTMwQTNcdTMwQzZcdTMwQTNcdTMwNkJcdTMwNkZcdTMwMDFcdTVGOENcdTdEOUFcdTMwRDBcdTMwRkNcdTMwQjhcdTMwRTdcdTMwRjNcdTMwNkVcdTUyMjVcdTMwNkVcdTMwQThcdTMwRjNcdTMwQzZcdTMwQTNcdTMwQzZcdTMwQTNcdTMwOTJcdTU0MkJcdTMwODFcdTMwOEJcdTMwNTNcdTMwNjhcdTMwNkZcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLSMgNC4xIENoYXJhY3RlciBhbmQgRW50aXR5IFJlZmVyZW5jZXMKLSAgICAgICAgRGlnaXRSZXF1aXJlZEluQ2hhclJlZiA9IFx1NjU4N1x1NUI1N1x1NTNDMlx1NzE2N1x1MzA2N1x1MzA2Rlx1MzAwMTEwXHU5MDMyXHU4ODY4XHU3M0ZFXHUzMDZGIiYjIlx1MzA2RVx1NzZGNFx1NUY4Q1x1MzA2Qlx1NjMwN1x1NUI5QVx1MzA1OVx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBIZXhkaWdpdFJlcXVpcmVkSW5DaGFyUmVmID0gXHU2NTg3XHU1QjU3XHU1M0MyXHU3MTY3XHUzMDY3XHUzMDZGXHUzMDAxMTZcdTkwMzJcdTg4NjhcdTczRkVcdTMwNkYiJiN4Ilx1MzA2RVx1NzZGNFx1NUY4Q1x1MzA2Qlx1NjMwN1x1NUI5QVx1MzA1OVx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBTZW1pY29sb25SZXF1aXJlZEluQ2hhclJlZiA9IFx1NjU4N1x1NUI1N1x1NTNDMlx1NzE2N1x1MzA2Ric7J1x1MzBDN1x1MzBFQVx1MzBERlx1MzBCRlx1MzA2N1x1N0Q0Mlx1NEU4Nlx1MzA1OVx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBJbnZhbGlkQ2hhclJlZiA9IFx1NjU4N1x1NUI1N1x1NTNDMlx1NzE2NyImI3swfSJcdTMwNkZcdTcxMjFcdTUyQjlcdTMwNkFYTUxcdTY1ODdcdTVCNTdcdTMwNjdcdTMwNTlcdTMwMDIKLSAgICAgICAgTmFtZVJlcXVpcmVkSW5SZWZlcmVuY2UgPSBcdTMwQThcdTMwRjNcdTMwQzZcdTMwQTNcdTMwQzZcdTMwQTNcdTUzQzJcdTcxNjdcdTMwNjdcdTMwNkZcdTMwMDFcdTMwQThcdTMwRjNcdTMwQzZcdTMwQTNcdTMwQzZcdTMwQTNcdTU0MERcdTMwNkYnJidcdTMwNkVcdTc2RjRcdTVGOENcdTMwNkJcdTYzMDdcdTVCOUFcdTMwNTlcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIKLSAgICAgICAgU2VtaWNvbG9uUmVxdWlyZWRJblJlZmVyZW5jZSA9IFx1MzBBOFx1MzBGM1x1MzBDNlx1MzBBM1x1MzBDNlx1MzBBMyJ7MH0iXHUzMDc4XHUzMDZFXHU1M0MyXHU3MTY3XHUzMDZGJyc7JydcdTMwQzdcdTMwRUFcdTMwREZcdTMwQkZcdTMwNjdcdTdENDJcdTRFODZcdTMwNTlcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIKLSMgNC4zLjEgVGhlIFRleHQgRGVjbGFyYXRpb24KLSAgICAgICAgVGV4dERlY2xNdXN0QmVGaXJzdCA9IFx1MzBDNlx1MzBBRFx1MzBCOVx1MzBDOFx1NUJBM1x1OEEwMFx1MzA2Rlx1MzAwMVx1NTkxNlx1OTBFOFx1MzA2RVx1ODlFM1x1Njc5MFx1NkUwOFx1MzBBOFx1MzBGM1x1MzBDNlx1MzBBM1x1MzBDNlx1MzBBM1x1MzA2RVx1NTE0OFx1OTgyRFx1MzA2N1x1MzA2RVx1MzA3Rlx1NEY3Rlx1NzUyOFx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBFcVJlcXVpcmVkSW5UZXh0RGVjbCA9IFx1MzBDNlx1MzBBRFx1MzBCOVx1MzBDOFx1NUJBM1x1OEEwMFx1MzA2N1x1MzA2Rlx1MzAwMSJ7MH0iXHUzMDZFXHU1RjhDXHUzMDZCJycgPSAnJ1x1NjU4N1x1NUI1N1x1MzA0Q1x1NUZDNVx1ODk4MVx1MzA2N1x1MzA1OVx1MzAwMgotICAgICAgICBRdW90ZVJlcXVpcmVkSW5UZXh0RGVjbCA9IFx1MzBDNlx1MzBBRFx1MzBCOVx1MzBDOFx1NUJBM1x1OEEwMFx1MzA2RSJ7MH0iXHUzMDZFXHU1RjhDXHUzMDZCXHU3RDlBXHUzMDRGXHU1MDI0XHUzMDZGXHUzMDAxXHU1RjE1XHU3NTI4XHU3QjI2XHUzMDY3XHU1NkYyXHUzMDkzXHUzMDYwXHU2NTg3XHU1QjU3XHU1MjE3XHUzMDZCXHUzMDU5XHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIENsb3NlUXVvdGVNaXNzaW5nSW5UZXh0RGVjbCA9IFx1MzBDNlx1MzBBRFx1MzBCOVx1MzBDOFx1NUJBM1x1OEEwMFx1MzA2RSJ7MH0iXHUzMDZFXHU1RjhDXHUzMDZCXHU3RDlBXHUzMDRGXHU1MDI0XHUzMDZCXHU3RDQyXHU0RTg2XHU1RjE1XHU3NTI4XHU3QjI2XHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0gICAgICAgIFNwYWNlUmVxdWlyZWRCZWZvcmVWZXJzaW9uSW5UZXh0RGVjbCA9IFx1MzBDNlx1MzBBRFx1MzBCOVx1MzBDOFx1NUJBM1x1OEEwMFx1MzA2N1x1MzA2Rlx1MzAwMVx1MzBEMFx1MzBGQ1x1MzBCOFx1MzBFN1x1MzBGM1x1NzU5MVx1NEYzQ1x1NUM1RVx1NjAyN1x1MzA2RVx1NTI0RFx1MzA2Qlx1N0E3QVx1NzY3RFx1MzA0Q1x1NUZDNVx1ODk4MVx1MzA2N1x1MzA1OVx1MzAwMgotICAgICAgICBTcGFjZVJlcXVpcmVkQmVmb3JlRW5jb2RpbmdJblRleHREZWNsID0gXHUzMEM2XHUzMEFEXHUzMEI5XHUzMEM4XHU1QkEzXHU4QTAwXHUzMDY3XHUzMDZGXHUzMDAxXHUzMEE4XHUzMEYzXHUzMEIzXHUzMEZDXHUzMEM3XHUzMEEzXHUzMEYzXHUzMEIwXHU3NTkxXHU0RjNDXHU1QzVFXHU2MDI3XHUzMDZFXHU1MjREXHUzMDZCXHU3QTdBXHU3NjdEXHUzMDRDXHU1RkM1XHU4OTgxXHUzMDY3XHUzMDU5XHUzMDAyCi0gICAgICAgIFRleHREZWNsVW50ZXJtaW5hdGVkID0gXHUzMEM2XHUzMEFEXHUzMEI5XHUzMEM4XHU1QkEzXHU4QTAwXHUzMDZGIj8+Ilx1MzA2N1x1N0Q0Mlx1NEU4Nlx1MzA1OVx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBFbmNvZGluZ0RlY2xSZXF1aXJlZCA9IFx1MzBDNlx1MzBBRFx1MzBCOVx1MzBDOFx1NUJBM1x1OEEwMFx1MzA2Qlx1MzA2Rlx1MzBBOFx1MzBGM1x1MzBCM1x1MzBGQ1x1MzBDN1x1MzBBM1x1MzBGM1x1MzBCMFx1NUJBM1x1OEEwMFx1MzA0Q1x1NUZDNVx1ODk4MVx1MzA2N1x1MzA1OVx1MzAwMgotICAgICAgICBOb01vcmVQc2V1ZG9BdHRyaWJ1dGVzID0gXHUzMDUzXHUzMDhDXHU0RUU1XHU0RTBBXHUzMDZFXHU3NTkxXHU0RjNDXHU1QzVFXHU2MDI3XHUzMDZGXHU2MzA3XHU1QjlBXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0gICAgICAgIE1vcmVQc2V1ZG9BdHRyaWJ1dGVzID0gXHU3NTkxXHU0RjNDXHU1QzVFXHU2MDI3XHUzMDRDXHUzMDU1XHUzMDg5XHUzMDZCXHU1RkM1XHU4OTgxXHUzMDY3XHUzMDU5XHUzMDAyCi0gICAgICAgIFBzZXVkb0F0dHJOYW1lRXhwZWN0ZWQgPSBcdTc1OTFcdTRGM0NcdTVDNUVcdTYwMjdcdTU0MERcdTMwNENcdTVGQzVcdTg5ODFcdTMwNjdcdTMwNTlcdTMwMDIgCi0jIDQuMy4yIFdlbGwtRm9ybWVkIFBhcnNlZCBFbnRpdGllcwotICAgICAgICBDb21tZW50Tm90SW5PbmVFbnRpdHkgPSBcdTMwQjNcdTMwRTFcdTMwRjNcdTMwQzhcdTMwNkZcdTMwMDFcdTU0MENcdTMwNThcdTg5RTNcdTY3OTBcdTZFMDhcdTMwQThcdTMwRjNcdTMwQzZcdTMwQTNcdTMwQzZcdTMwQTNcdTUxODVcdTMwNkJcdTVCOENcdTUxNjhcdTMwNkJcdTU0MkJcdTMwN0VcdTMwOENcdTMwNjZcdTMwNDRcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIKLSAgICAgICAgUElOb3RJbk9uZUVudGl0eSA9IFx1NTFFNlx1NzQwNlx1NTQ3RFx1NEVFNFx1MzA2Rlx1MzAwMVx1NTQwQ1x1MzA1OFx1ODlFM1x1Njc5MFx1NkUwOFx1MzBBOFx1MzBGM1x1MzBDNlx1MzBBM1x1MzBDNlx1MzBBM1x1NTE4NVx1MzA2Qlx1NUI4Q1x1NTE2OFx1MzA2Qlx1NTQyQlx1MzA3RVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgotIyA0LjMuMyBDaGFyYWN0ZXIgRW5jb2RpbmcgaW4gRW50aXRpZXMKLSAgICAgICAgRW5jb2RpbmdEZWNsSW52YWxpZCA9IFx1MzBBOFx1MzBGM1x1MzBCM1x1MzBGQ1x1MzBDN1x1MzBBM1x1MzBGM1x1MzBCMFx1NTQwRCJ7MH0iXHUzMDRDXHU3MTIxXHU1MkI5XHUzMDY3XHUzMDU5XHUzMDAyCi0gICAgICAgIEVuY29kaW5nQnl0ZU9yZGVyVW5zdXBwb3J0ZWQgPSBcdTMwQThcdTMwRjNcdTMwQjNcdTMwRkNcdTMwQzdcdTMwQTNcdTMwRjNcdTMwQjAiezB9Ilx1MzA2Qlx1NjMwN1x1NUI5QVx1MzA1NVx1MzA4Q1x1MzA1Rlx1MzBEMFx1MzBBNFx1MzBDOFx1OTgwNlx1MzA2Rlx1MzBCNVx1MzBERFx1MzBGQ1x1MzBDOFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotICAgICAgICBJbnZhbGlkQnl0ZSA9IHsxfVx1MzBEMFx1MzBBNFx1MzBDOFx1MzA2RVVURi04XHUzMEI3XHUzMEZDXHUzMEIxXHUzMEYzXHUzMEI5XHUzMDZFXHUzMEQwXHUzMEE0XHUzMEM4ezB9XHUzMDRDXHU3MTIxXHU1MkI5XHUzMDY3XHUzMDU5XHUzMDAyCi0gICAgICAgIEV4cGVjdGVkQnl0ZSA9IHsxfVx1MzBEMFx1MzBBNFx1MzBDOFx1MzA2RVVURi04XHUzMEI3XHUzMEZDXHUzMEIxXHUzMEYzXHUzMEI5XHUzMDZFXHUzMEQwXHUzMEE0XHUzMEM4ezB9XHUzMDRDXHU1RkM1XHU4OTgxXHUzMDY3XHUzMDU5XHUzMDAyICAKLSAgICAgICAgSW52YWxpZEhpZ2hTdXJyb2dhdGUgPSBVVEYtOFx1MzBCN1x1MzBGQ1x1MzBCMVx1MzBGM1x1MzBCOVx1MzA2RVx1NEUwQVx1NEY0RFx1MzBCNVx1MzBFRFx1MzBCMlx1MzBGQ1x1MzBDOFx1MzBGQlx1MzBEM1x1MzBDM1x1MzBDOFx1MzA2RVx1NEUwQVx1OTY1MFx1MzA2RjB4MTBcdTMwNjdcdTMwNTlcdTMwNENcdTMwMDEweHswfVx1MzA0Q1x1NjkxQ1x1NTFGQVx1MzA1NVx1MzA4Q1x1MzA3RVx1MzA1N1x1MzA1Rlx1MzAwMgotICAgICAgICBPcGVyYXRpb25Ob3RTdXBwb3J0ZWQgPSBcdTY0Q0RcdTRGNUMiezB9Ilx1MzA2RnsxfVx1MzBFQVx1MzBGQ1x1MzBDMFx1MzBGQ1x1MzA2N1x1MzBCNVx1MzBERFx1MzBGQ1x1MzBDOFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotICAgICAgICBJbnZhbGlkQVNDSUkgPSBcdTMwRDBcdTMwQTRcdTMwQzgiezB9Ilx1MzA2Rlx1MzAwMSg3XHUzMEQzXHUzMEMzXHUzMEM4KSBBU0NJSVx1NjU4N1x1NUI1N1x1MzBCQlx1MzBDM1x1MzBDOFx1MzA2RVx1MzBFMVx1MzBGM1x1MzBEMFx1MzBGQ1x1MzA2N1x1MzA2Rlx1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotICAgICAgICBDaGFyQ29udmVyc2lvbkZhaWx1cmUgPSBcdTcyNzlcdTVCOUFcdTMwNkVcdTMwQThcdTMwRjNcdTMwQjNcdTMwRkNcdTMwQzdcdTMwQTNcdTMwRjNcdTMwQjBcdTMwNjdcdTMwNDJcdTMwOEJcdTMwNjhcdTc4QkFcdTVCOUFcdTMwNTVcdTMwOENcdTMwNUZcdTMwQThcdTMwRjNcdTMwQzZcdTMwQTNcdTMwQzZcdTMwQTNcdTMwNkJcdTMwNkZcdTMwMDFcdTMwNURcdTMwNkVcdTMwQThcdTMwRjNcdTMwQjNcdTMwRkNcdTMwQzdcdTMwQTNcdTMwRjNcdTMwQjBcdTMwNjdcdTRFMERcdTZCNjNcdTMwNkFcdTMwQjdcdTMwRkNcdTMwQjFcdTMwRjNcdTMwQjlcdTMwOTJcdTU0MkJcdTMwODFcdTMwOEJcdTMwNTNcdTMwNjhcdTMwNkZcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLSAgICAgICAgCi0jIERURCBNZXNzYWdlcwotIyAyLjIgQ2hhcmFjdGVycwotICAgICAgICBJbnZhbGlkQ2hhckluRW50aXR5VmFsdWUgPSBcdTMwRUFcdTMwQzZcdTMwRTlcdTMwRUJcdTMwRkJcdTMwQThcdTMwRjNcdTMwQzZcdTMwQTNcdTMwQzZcdTMwQTNcdTUwMjRcdTMwNkJcdTcxMjFcdTUyQjlcdTMwNkFYTUxcdTY1ODdcdTVCNTcoVW5pY29kZTogMHh7MH0pXHUzMDRDXHU4OThCXHUzMDY0XHUzMDRCXHUzMDhBXHUzMDdFXHUzMDU3XHUzMDVGXHUzMDAyCi0gICAgICAgIEludmFsaWRDaGFySW5FeHRlcm5hbFN1YnNldCA9IERURFx1MzA2RVx1NTkxNlx1OTBFOFx1MzBCNVx1MzBENlx1MzBCQlx1MzBDM1x1MzBDOFx1MzA2Qlx1NzEyMVx1NTJCOVx1MzA2QVhNTFx1NjU4N1x1NUI1NyhVbmljb2RlOiAweHswfSlcdTMwNENcdTg5OEJcdTMwNjRcdTMwNEJcdTMwOEFcdTMwN0VcdTMwNTdcdTMwNUZcdTMwMDIKLSAgICAgICAgSW52YWxpZENoYXJJbklnbm9yZVNlY3QgPSBcdTk2NjRcdTU5MTZcdTY3NjFcdTRFRjZcdTRFRDhcdTMwNERcdTMwQkJcdTMwQUZcdTMwQjdcdTMwRTdcdTMwRjNcdTMwNkJcdTcxMjFcdTUyQjlcdTMwNkFYTUxcdTY1ODdcdTVCNTcoVW5pY29kZTogMHh7MH0pXHUzMDRDXHU4OThCXHUzMDY0XHUzMDRCXHUzMDhBXHUzMDdFXHUzMDU3XHUzMDVGXHUzMDAyCi0gICAgICAgIEludmFsaWRDaGFySW5QdWJsaWNJRCA9IFx1NTE2Q1x1OTU4Qlx1OEI1OFx1NTIyNVx1NUI1MFx1MzA2Qlx1NzEyMVx1NTJCOVx1MzA2QVhNTFx1NjU4N1x1NUI1NyhVbmljb2RlOiAweHswfSlcdTMwNENcdTg5OEJcdTMwNjRcdTMwNEJcdTMwOEFcdTMwN0VcdTMwNTdcdTMwNUZcdTMwMDIKLSAgICAgICAgSW52YWxpZENoYXJJblN5c3RlbUlEID0gXHUzMEI3XHUzMEI5XHUzMEM2XHUzMEUwXHU4QjU4XHU1MjI1XHU1QjUwXHUzMDZCXHU3MTIxXHU1MkI5XHUzMDZBWE1MXHU2NTg3XHU1QjU3KFVuaWNvZGU6IDB4ezB9KVx1MzA0Q1x1ODk4Qlx1MzA2NFx1MzA0Qlx1MzA4QVx1MzA3RVx1MzA1N1x1MzA1Rlx1MzAwMgotIyAyLjMgQ29tbW9uIFN5bnRhY3RpYyBDb25zdHJ1Y3RzCi0gICAgICAgIFNwYWNlUmVxdWlyZWRBZnRlclNZU1RFTSA9IERPQ1RZUEVcdTVCQTNcdThBMDBcdTMwNjdcdTMwNkZcdTMwMDFcdTMwQURcdTMwRkNcdTMwRUZcdTMwRkNcdTMwQzlTWVNURU1cdTMwNkVcdTVGOENcdTMwNkJcdTdBN0FcdTc2N0RcdTMwNENcdTVGQzVcdTg5ODFcdTMwNjdcdTMwNTlcdTMwMDIKLSAgICAgICAgUXVvdGVSZXF1aXJlZEluU3lzdGVtSUQgPSBcdTMwQjdcdTMwQjlcdTMwQzZcdTMwRTBcdThCNThcdTUyMjVcdTVCNTBcdTMwNkVcdTUxNDhcdTk4MkRcdTMwNkJcdTMwNkZcdTMwMDFcdTRFMDBcdTkxQ0RcdTVGMTVcdTc1MjhcdTdCMjZcdTY1ODdcdTVCNTdcdTMwN0VcdTMwNUZcdTMwNkZcdTRFOENcdTkxQ0RcdTVGMTVcdTc1MjhcdTdCMjZcdTY1ODdcdTVCNTdcdTMwNENcdTVGQzVcdTg5ODFcdTMwNjdcdTMwNTlcdTMwMDIKLSAgICAgICAgU3lzdGVtSURVbnRlcm1pbmF0ZWQgPSBcdTMwQjdcdTMwQjlcdTMwQzZcdTMwRTBcdThCNThcdTUyMjVcdTVCNTBcdTMwNkZcdTMwMDFcdTVCRkVcdTVGRENcdTMwNTlcdTMwOEJcdTVGMTVcdTc1MjhcdTdCMjZcdTY1ODdcdTVCNTdcdTMwNjdcdTdENDJcdTRFODZcdTMwNTlcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIKLSAgICAgICAgU3BhY2VSZXF1aXJlZEFmdGVyUFVCTElDID0gRE9DVFlQRVx1NUJBM1x1OEEwMFx1MzA2N1x1MzA2Rlx1MzAwMVx1MzBBRFx1MzBGQ1x1MzBFRlx1MzBGQ1x1MzBDOVBVQkxJQ1x1MzA2RVx1NUY4Q1x1MzA2Qlx1N0E3QVx1NzY3RFx1MzA0Q1x1NUZDNVx1ODk4MVx1MzA2N1x1MzA1OVx1MzAwMgotICAgICAgICBRdW90ZVJlcXVpcmVkSW5QdWJsaWNJRCA9IFx1NTE2Q1x1OTU4Qlx1OEI1OFx1NTIyNVx1NUI1MFx1MzA2RVx1NTE0OFx1OTgyRFx1MzA2Qlx1MzA2Rlx1MzAwMVx1NEUwMFx1OTFDRFx1NUYxNVx1NzUyOFx1N0IyNlx1NjU4N1x1NUI1N1x1MzA3RVx1MzA1Rlx1MzA2Rlx1NEU4Q1x1OTFDRFx1NUYxNVx1NzUyOFx1N0IyNlx1NjU4N1x1NUI1N1x1MzA0Q1x1NUZDNVx1ODk4MVx1MzA2N1x1MzA1OVx1MzAwMgotICAgICAgICBQdWJsaWNJRFVudGVybWluYXRlZCA9IFx1NTE2Q1x1OTU4Qlx1OEI1OFx1NTIyNVx1NUI1MFx1MzA2Rlx1MzAwMVx1NUJGRVx1NUZEQ1x1MzA1OVx1MzA4Qlx1NUYxNVx1NzUyOFx1N0IyNlx1NjU4N1x1NUI1N1x1MzA2N1x1N0Q0Mlx1NEU4Nlx1MzA1OVx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBQdWJpZENoYXJJbGxlZ2FsID0gXHU1MTZDXHU5NThCXHU4QjU4XHU1MjI1XHU1QjUwXHUzMDY3XHUzMDZGXHUzMDAxXHU2NTg3XHU1QjU3KFVuaWNvZGU6IDB4ezB9KVx1MzA2Rlx1NEY3Rlx1NzUyOFx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotICAgICAgICBTcGFjZVJlcXVpcmVkQmV0d2VlblB1YmxpY0FuZFN5c3RlbSA9IFx1NTE2Q1x1OTU4Qlx1OEI1OFx1NTIyNVx1NUI1MFx1MzA2OFx1MzBCN1x1MzBCOVx1MzBDNlx1MzBFMFx1OEI1OFx1NTIyNVx1NUI1MFx1MzA2RVx1OTU5M1x1MzA2Qlx1MzA2Rlx1N0E3QVx1NzY3RFx1MzA0Q1x1NUZDNVx1ODk4MVx1MzA2N1x1MzA1OVx1MzAwMgotIyAyLjggUHJvbG9nIGFuZCBEb2N1bWVudCBUeXBlIERlY2xhcmF0aW9uCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfUk9PVF9FTEVNRU5UX1RZUEVfSU5fRE9DVFlQRURFQ0wgPSBcdTMwQzlcdTMwQURcdTMwRTVcdTMwRTFcdTMwRjNcdTMwQzhcdTMwRkJcdTMwQkZcdTMwQTRcdTMwRDdcdTVCQTNcdThBMDBcdTMwNjdcdTMwNkZcdTMwMDEiPCFET0NUWVBFIlx1MzA2RVx1NUY4Q1x1MzA2Qlx1N0E3QVx1NzY3RFx1MzA0Q1x1NUZDNVx1ODk4MVx1MzA2N1x1MzA1OVx1MzAwMgotICAgICAgICBNU0dfUk9PVF9FTEVNRU5UX1RZUEVfUkVRVUlSRUQgPSBcdTMwQzlcdTMwQURcdTMwRTVcdTMwRTFcdTMwRjNcdTMwQzhcdTMwRkJcdTMwQkZcdTMwQTRcdTMwRDdcdTVCQTNcdThBMDBcdTMwNjdcdTMwNkZcdTMwMDEiPCFET0NUWVBFIlx1MzA2RVx1NUY4Q1x1MzA2Qlx1MzBFQlx1MzBGQ1x1MzBDOFx1ODk4MVx1N0QyMFx1MzBCRlx1MzBBNFx1MzBEN1x1MzA0Q1x1NUZDNVx1ODk4MVx1MzA2N1x1MzA1OVx1MzAwMgotICAgICAgICBEb2N0eXBlZGVjbFVudGVybWluYXRlZCA9IFx1MzBFQlx1MzBGQ1x1MzBDOFx1ODk4MVx1N0QyMFx1MzBCRlx1MzBBNFx1MzBENyJ7MH0iXHUzMDZFXHUzMEM5XHUzMEFEXHUzMEU1XHUzMEUxXHUzMEYzXHUzMEM4XHUzMEZCXHUzMEJGXHUzMEE0XHUzMEQ3XHU1QkEzXHU4QTAwXHUzMDZGJyc+JydcdTMwNjdcdTdENDJcdTRFODZcdTMwNTlcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIKLSAgICAgICAgRG9jdHlwZWRlY2xOb3RDbG9zZWQgPSBcdTMwRUJcdTMwRkNcdTMwQzhcdTg5ODFcdTdEMjBcdTMwQkZcdTMwQTRcdTMwRDciezB9Ilx1MzA2RVx1MzBDOVx1MzBBRFx1MzBFNVx1MzBFMVx1MzBGM1x1MzBDOFx1MzBGQlx1MzBCRlx1MzBBNFx1MzBEN1x1NUJBM1x1OEEwMFx1MzA2RicnXScnXHUzMDY3XHU5NTg5XHUzMDU4XHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIFBFUmVmZXJlbmNlV2l0aGluTWFya3VwID0gXHUzMEQxXHUzMEU5XHUzMEUxXHUzMEZDXHUzMEJGXHUzMEZCXHUzMEE4XHUzMEYzXHUzMEM2XHUzMEEzXHUzMEM2XHUzMEEzXHU1M0MyXHU3MTY3IiV7MH07Ilx1MzA2Rlx1MzAwMURURFx1MzA2RVx1NTE4NVx1OTBFOFx1MzBCNVx1MzBENlx1MzBCQlx1MzBDM1x1MzBDOFx1MzA2RVx1MzBERVx1MzBGQ1x1MzBBRlx1MzBBMlx1MzBDM1x1MzBEN1x1NTE4NVx1MzA2Qlx1MzA2Rlx1NjMwN1x1NUI5QVx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotICAgICAgICBNU0dfTUFSS1VQX05PVF9SRUNPR05JWkVEX0lOX0RURCA9IFx1MzBDOVx1MzBBRFx1MzBFNVx1MzBFMVx1MzBGM1x1MzBDOFx1MzBGQlx1MzBCRlx1MzBBNFx1MzBEN1x1NUJBM1x1OEEwMFx1MzA2Qlx1NTQyQlx1MzA3RVx1MzA4Q1x1MzA4Qlx1MzA0Qlx1MzAwMVx1MzBDOVx1MzBBRFx1MzBFNVx1MzBFMVx1MzBGM1x1MzBDOFx1MzBGQlx1MzBCRlx1MzBBNFx1MzBEN1x1NUJBM1x1OEEwMFx1MzA0Q1x1NjMwN1x1MzA1N1x1MzA2Nlx1MzA0NFx1MzA4Qlx1MzBERVx1MzBGQ1x1MzBBRlx1MzBBMlx1MzBDM1x1MzBEN1x1NUJBM1x1OEEwMFx1MzA2Rlx1NjU3NFx1NUY2Mlx1NUYwRlx1MzA2N1x1MzA0Mlx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgotIyAyLjEwIFdoaXRlIFNwYWNlIEhhbmRsaW5nCi0gICAgICAgIE1TR19YTUxfU1BBQ0VfREVDTEFSQVRJT05fSUxMRUdBTCA9ICJ4bWw6c3BhY2UiXHUzMDZFXHU1QzVFXHU2MDI3XHU1QkEzXHU4QTAwXHUzMDZGXHUzMDAxImRlZmF1bHQiXHUzMDRBXHUzMDg4XHUzMDczInByZXNlcnZlIlx1MzA2RVx1MzA3Rlx1MzA5Mlx1NEY3Rlx1NzUyOFx1MzA2N1x1MzA0RFx1MzA4Qlx1NTIxN1x1NjMxOVx1MzBCRlx1MzBBNFx1MzBEN1x1MzA2OFx1MzA1N1x1MzA2Nlx1NjMwN1x1NUI5QVx1MzA1OVx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgotIyAzLjIgRWxlbWVudCBUeXBlIERlY2xhcmF0aW9ucwotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX0VMRU1FTlRfVFlQRV9JTl9FTEVNRU5UREVDTCA9IFx1ODk4MVx1N0QyMFx1MzBCRlx1MzBBNFx1MzBEN1x1NUJBM1x1OEEwMFx1MzA2N1x1MzA2Rlx1MzAwMSI8IUVMRU1FTlQiXHUzMDZFXHU1RjhDXHUzMDZCXHU3QTdBXHU3NjdEXHUzMDRDXHU1RkM1XHU4OTgxXHUzMDY3XHUzMDU5XHUzMDAyCi0gICAgICAgIE1TR19FTEVNRU5UX1RZUEVfUkVRVUlSRURfSU5fRUxFTUVOVERFQ0wgPSBcdTg5ODFcdTdEMjBcdTMwQkZcdTMwQTRcdTMwRDdcdTVCQTNcdThBMDBcdTMwNkJcdTMwNkZcdTg5ODFcdTdEMjBcdTMwQkZcdTMwQTRcdTMwRDdcdTMwNENcdTVGQzVcdTg5ODFcdTMwNjdcdTMwNTlcdTMwMDIKLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9DT05URU5UU1BFQ19JTl9FTEVNRU5UREVDTCA9IFx1ODk4MVx1N0QyMFx1MzBCRlx1MzBBNFx1MzBEN1x1NUJBM1x1OEEwMFx1MzA2N1x1MzA2Rlx1MzAwMVx1ODk4MVx1N0QyMFx1MzBCRlx1MzBBNFx1MzBENyJ7MH0iXHUzMDZFXHU1RjhDXHUzMDZCXHU3QTdBXHU3NjdEXHUzMDRDXHU1RkM1XHU4OTgxXHUzMDY3XHUzMDU5XHUzMDAyCi0gICAgICAgIE1TR19DT05URU5UU1BFQ19SRVFVSVJFRF9JTl9FTEVNRU5UREVDTCA9IFx1ODk4MVx1N0QyMFx1MzBCRlx1MzBBNFx1MzBEN1x1NUJBM1x1OEEwMFx1MzA2N1x1MzA2Rlx1MzAwMVx1ODk4MVx1N0QyMFx1MzBCRlx1MzBBNFx1MzBENyJ7MH0iXHUzMDZFXHU1RjhDXHUzMDZCXHU1MjM2XHU3RDA0XHUzMDRDXHU1RkM1XHU4OTgxXHUzMDY3XHUzMDU5XHUzMDAyCi0gICAgICAgIEVsZW1lbnREZWNsVW50ZXJtaW5hdGVkID0gXHU4OTgxXHU3RDIwXHUzMEJGXHUzMEE0XHUzMEQ3InswfSJcdTMwNkVcdTVCQTNcdThBMDBcdTMwNkYnJz4nJ1x1MzA2N1x1N0Q0Mlx1NEU4Nlx1MzA1OVx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgotIyAzLjIuMSBFbGVtZW50IENvbnRlbnQKLSAgICAgICAgTVNHX09QRU5fUEFSRU5fT1JfRUxFTUVOVF9UWVBFX1JFUVVJUkVEX0lOX0NISUxEUkVOID0gXHU4OTgxXHU3RDIwXHUzMEJGXHUzMEE0XHUzMEQ3InswfSJcdTMwNkVcdTVCQTNcdThBMDBcdTMwNkJcdTMwNkYnJygnJ1x1NjU4N1x1NUI1N1x1MzA3RVx1MzA1Rlx1MzA2Rlx1ODk4MVx1N0QyMFx1MzBCRlx1MzBBNFx1MzBEN1x1MzA0Q1x1NUZDNVx1ODk4MVx1MzA2N1x1MzA1OVx1MzAwMgotICAgICAgICBNU0dfQ0xPU0VfUEFSRU5fUkVRVUlSRURfSU5fQ0hJTERSRU4gPSBcdTg5ODFcdTdEMjBcdTMwQkZcdTMwQTRcdTMwRDciezB9Ilx1MzA2RVx1NUJBM1x1OEEwMFx1MzA2Qlx1MzA2RicnKScnXHUzMDRDXHU1RkM1XHU4OTgxXHUzMDY3XHUzMDU5XHUzMDAyCi0jIDMuMi4yIE1peGVkIENvbnRlbnQKLSAgICAgICAgTVNHX0VMRU1FTlRfVFlQRV9SRVFVSVJFRF9JTl9NSVhFRF9DT05URU5UID0gXHU4OTgxXHU3RDIwXHUzMEJGXHUzMEE0XHUzMEQ3InswfSJcdTMwNkVcdTVCQTNcdThBMDBcdTMwNkJcdTMwNkZcdTg5ODFcdTdEMjBcdTMwQkZcdTMwQTRcdTMwRDdcdTMwNENcdTVGQzVcdTg5ODFcdTMwNjdcdTMwNTlcdTMwMDIKLSAgICAgICAgTVNHX0NMT1NFX1BBUkVOX1JFUVVJUkVEX0lOX01JWEVEID0gXHU4OTgxXHU3RDIwXHUzMEJGXHUzMEE0XHUzMEQ3InswfSJcdTMwNkVcdTVCQTNcdThBMDBcdTMwNkJcdTMwNkYnJyknJ1x1MzA0Q1x1NUZDNVx1ODk4MVx1MzA2N1x1MzA1OVx1MzAwMgotICAgICAgICBNaXhlZENvbnRlbnRVbnRlcm1pbmF0ZWQgPSBcdTVCNTBcdTg5ODFcdTdEMjBcdTMwNkVcdTMwQkZcdTMwQTRcdTMwRDdcdTMwNENcdTUyMzZcdTdEMDRcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwOEJcdTU4MzRcdTU0MDhcdTMwMDFcdTZERjdcdTU0MDhcdTMwQjNcdTMwRjNcdTMwQzZcdTMwRjNcdTMwQzRcdTMwRkJcdTMwRTJcdTMwQzdcdTMwRUIiezB9Ilx1MzA2RiIpKiJcdTMwNjdcdTdENDJcdTRFODZcdTMwNTlcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIKLSMgMy4zIEF0dHJpYnV0ZS1MaXN0IERlY2xhcmF0aW9ucwotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX0VMRU1FTlRfVFlQRV9JTl9BVFRMSVNUREVDTCA9IFx1NUM1RVx1NjAyN1x1MzBFQVx1MzBCOVx1MzBDOFx1NUJBM1x1OEEwMFx1MzA2N1x1MzA2Rlx1MzAwMSI8IUFUVExJU1QiXHUzMDZFXHU1RjhDXHUzMDZCXHU3QTdBXHU3NjdEXHUzMDRDXHU1RkM1XHU4OTgxXHUzMDY3XHUzMDU5XHUzMDAyCi0gICAgICAgIE1TR19FTEVNRU5UX1RZUEVfUkVRVUlSRURfSU5fQVRUTElTVERFQ0wgPSBcdTVDNUVcdTYwMjdcdTMwRUFcdTMwQjlcdTMwQzhcdTVCQTNcdThBMDBcdTMwNkJcdTMwNkZcdTg5ODFcdTdEMjBcdTMwQkZcdTMwQTRcdTMwRDdcdTMwNENcdTVGQzVcdTg5ODFcdTMwNjdcdTMwNTlcdTMwMDIKLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9BVFRSSUJVVEVfTkFNRV9JTl9BVFRERUYgPSBcdTg5ODFcdTdEMjAiezB9Ilx1MzA2RVx1NUM1RVx1NjAyN1x1MzBFQVx1MzBCOVx1MzBDOFx1NUJBM1x1OEEwMFx1MzA2N1x1MzA2Rlx1MzAwMVx1NUM1RVx1NjAyN1x1NTQwRFx1MzA2RVx1NTI0RFx1MzA2Qlx1N0E3QVx1NzY3RFx1MzA0Q1x1NUZDNVx1ODk4MVx1MzA2N1x1MzA1OVx1MzAwMgotICAgICAgICBBdHROYW1lUmVxdWlyZWRJbkF0dERlZiA9IFx1ODk4MVx1N0QyMCJ7MH0iXHUzMDZFXHU1QzVFXHU2MDI3XHUzMEVBXHUzMEI5XHUzMEM4XHU1QkEzXHU4QTAwXHUzMDZCXHUzMDZGXHU1QzVFXHU2MDI3XHU1NDBEXHUzMDkyXHU2MzA3XHU1QjlBXHUzMDU5XHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfQVRUVFlQRV9JTl9BVFRERUYgPSBcdTg5ODFcdTdEMjAiezB9Ilx1MzA2RVx1NUM1RVx1NjAyNyJ7MX0iXHUzMDZFXHU1QkEzXHU4QTAwXHUzMDY3XHUzMDZGXHUzMDAxXHU1QzVFXHU2MDI3XHUzMEJGXHUzMEE0XHUzMEQ3XHUzMDZFXHU1MjREXHUzMDZCXHU3QTdBXHU3NjdEXHUzMDRDXHU1RkM1XHU4OTgxXHUzMDY3XHUzMDU5XHUzMDAyCi0gICAgICAgIEF0dFR5cGVSZXF1aXJlZEluQXR0RGVmID0gXHU4OTgxXHU3RDIwInswfSJcdTMwNkVcdTVDNUVcdTYwMjciezF9Ilx1MzA2RVx1NUJBM1x1OEEwMFx1MzA2Qlx1MzA2Rlx1NUM1RVx1NjAyN1x1MzBCRlx1MzBBNFx1MzBEN1x1MzA0Q1x1NUZDNVx1ODk4MVx1MzA2N1x1MzA1OVx1MzAwMgotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX0RFRkFVTFRERUNMX0lOX0FUVERFRiA9IFx1ODk4MVx1N0QyMCJ7MH0iXHUzMDZFXHU1QzVFXHU2MDI3InsxfSJcdTMwNkVcdTVCQTNcdThBMDBcdTMwNjdcdTMwNkZcdTMwMDFcdTVDNUVcdTYwMjdcdTMwQzdcdTMwRDVcdTMwQTlcdTMwRUJcdTMwQzhcdTMwNkVcdTUyNERcdTMwNkJcdTdBN0FcdTc2N0RcdTMwNENcdTVGQzVcdTg5ODFcdTMwNjdcdTMwNTlcdTMwMDIKLSAgICAgICAgTVNHX0RVUExJQ0FURV9BVFRSSUJVVEVfREVGSU5JVElPTiA9IFx1NzI3OVx1NUI5QVx1MzA2RVx1ODk4MVx1N0QyMCJ7MH0iXHUzMDZFXHU1NDBDXHU0RTAwXHU1QzVFXHU2MDI3InsxfSJcdTMwNkJcdTg5MDdcdTY1NzBcdTMwNkVcdTVDNUVcdTYwMjdcdTVCOUFcdTdGQTlcdTMwNENcdTYzMDdcdTVCOUFcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTlcdTMwMDIKLSMgMy4zLjEgQXR0cmlidXRlIFR5cGVzCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9BRlRFUl9OT1RBVElPTl9JTl9OT1RBVElPTlRZUEUgPSAiezF9Ilx1NUM1RVx1NjAyN1x1NUJBM1x1OEEwMFx1MzA2N1x1MzA2Rlx1MzAwMSJOT1RBVElPTiJcdTMwNkVcdTVGOENcdTMwNkJcdTdBN0FcdTc2N0RcdTMwNENcdTVGQzVcdTg5ODFcdTMwNjdcdTMwNTlcdTMwMDIKLSAgICAgICAgTVNHX09QRU5fUEFSRU5fUkVRVUlSRURfSU5fTk9UQVRJT05UWVBFID0gInsxfSJcdTVDNUVcdTYwMjdcdTVCQTNcdThBMDBcdTMwNjdcdTMwNkZcdTMwMDEiTk9UQVRJT04iXHUzMDZFXHU1RjhDXHUzMDZCJycoJydcdTY1ODdcdTVCNTdcdTMwNENcdTVGQzVcdTg5ODFcdTMwNjdcdTMwNTlcdTMwMDIKLSAgICAgICAgTVNHX05BTUVfUkVRVUlSRURfSU5fTk9UQVRJT05UWVBFID0gInsxfSJcdTVDNUVcdTYwMjdcdTVCQTNcdThBMDBcdTMwNkVcdTg4NjhcdThBMThcdTZDRDVcdTMwQkZcdTMwQTRcdTMwRDdcdTMwRkJcdTMwRUFcdTMwQjlcdTMwQzhcdTMwNkJcdTMwNkZcdTg4NjhcdThBMThcdTU0MERcdTMwNENcdTVGQzVcdTg5ODFcdTMwNjdcdTMwNTlcdTMwMDIKLSAgICAgICAgTm90YXRpb25UeXBlVW50ZXJtaW5hdGVkID0gInsxfSJcdTVDNUVcdTYwMjdcdTVCQTNcdThBMDBcdTMwNkVcdTg4NjhcdThBMThcdTZDRDVcdTMwQkZcdTMwQTRcdTMwRDdcdTMwRkJcdTMwRUFcdTMwQjlcdTMwQzhcdTMwNkYnJyknJ1x1MzA2N1x1N0Q0Mlx1NEU4Nlx1MzA1OVx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBNU0dfTk1UT0tFTl9SRVFVSVJFRF9JTl9FTlVNRVJBVElPTiA9ICJ7MX0iXHU1QzVFXHU2MDI3XHU1QkEzXHU4QTAwXHUzMDZFXHU1MjE3XHU2MzE5XHUzMEJGXHUzMEE0XHUzMEQ3XHUzMEZCXHUzMEVBXHUzMEI5XHUzMEM4XHUzMDZCXHUzMDZGXHU1NDBEXHU1MjREXHUzMEM4XHUzMEZDXHUzMEFGXHUzMEYzXHUzMDRDXHU1RkM1XHU4OTgxXHUzMDY3XHUzMDU5XHUzMDAyCi0gICAgICAgIEVudW1lcmF0aW9uVW50ZXJtaW5hdGVkID0gInsxfSJcdTVDNUVcdTYwMjdcdTVCQTNcdThBMDBcdTMwNkVcdTUyMTdcdTYzMTlcdTMwQkZcdTMwQTRcdTMwRDdcdTMwRkJcdTMwRUFcdTMwQjlcdTMwQzhcdTMwNkYnJyknJ1x1MzA2N1x1N0Q0Mlx1NEU4Nlx1MzA1OVx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBNU0dfRElTVElOQ1RfVE9LRU5TX0lOX0VOVU1FUkFUSU9OID0gXHU4OTgxXHU3RDIwInswfSJcdTMwNkVcdTVDNUVcdTYwMjciezJ9Ilx1MzA2RVx1NUJBM1x1OEEwMFx1MzA2N1x1NTIxN1x1NjMxOVx1NTAyNCJ7MX0iXHUzMDRDXHU4OTA3XHU2NTcwXHU1NkRFXHU2MzA3XHU1QjlBXHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5XHUzMDAyXHU1MzU4XHU0RTAwXHUzMDZFRW51bWVyYXRpb25cdTVDNUVcdTYwMjdcdTVCQTNcdThBMDBcdTMwNkJcdTMwNEFcdTMwNTFcdTMwOEJOTVRPS0VOU1x1MzA2Rlx1MzA1OVx1MzA3OVx1MzA2Nlx1NzU3MFx1MzA2QVx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBNU0dfRElTVElOQ1RfTk9UQVRJT05fSU5fRU5VTUVSQVRJT04gPSBcdTg5ODFcdTdEMjAiezB9Ilx1MzA2RVx1NUM1RVx1NjAyNyJ7Mn0iXHUzMDZFXHU1QkEzXHU4QTAwXHUzMDY3XHU1MjE3XHU2MzE5XHU1MDI0InsxfSJcdTMwNENcdTg5MDdcdTY1NzBcdTU2REVcdTYzMDdcdTVCOUFcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTlcdTMwMDJcdTUzNThcdTRFMDBcdTMwNkVOb3RhdGlvblR5cGVcdTVDNUVcdTYwMjdcdTVCQTNcdThBMDBcdTMwNkJcdTMwNEFcdTMwNTFcdTMwOEJOT1RBVElPTlx1MzA2RVx1NTQwRFx1NTI0RFx1MzA2Rlx1MzA1OVx1MzA3OVx1MzA2Nlx1NzU3MFx1MzA2QVx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgotIyAzLjMuMiBBdHRyaWJ1dGUgRGVmYXVsdHMKLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0FGVEVSX0ZJWEVEX0lOX0RFRkFVTFRERUNMID0gInsxfSJcdTVDNUVcdTYwMjdcdTVCQTNcdThBMDBcdTMwNjdcdTMwNkZcdTMwMDEiRklYRUQiXHUzMDZFXHU1RjhDXHUzMDZCXHU3QTdBXHU3NjdEXHUzMDRDXHU1RkM1XHU4OTgxXHUzMDY3XHUzMDU5XHUzMDAyCi0jIDMuNCBDb25kaXRpb25hbCBTZWN0aW9ucwotICAgICAgICBJbmNsdWRlU2VjdFVudGVybWluYXRlZCA9IFx1NTMwNVx1NTQyQlx1Njc2MVx1NEVGNlx1NEVEOFx1MzA0RFx1MzBCQlx1MzBBRlx1MzBCN1x1MzBFN1x1MzBGM1x1MzA2RiJdXT4iXHUzMDY3XHU3RDQyXHU0RTg2XHUzMDU5XHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIElnbm9yZVNlY3RVbnRlcm1pbmF0ZWQgPSBcdTk2NjRcdTU5MTZcdTY3NjFcdTRFRjZcdTRFRDhcdTMwNERcdTMwQkJcdTMwQUZcdTMwQjdcdTMwRTdcdTMwRjNcdTMwNkVcdTY3MDBcdTVGOENcdTMwNkYiXV0+Ilx1MzA2N1x1N0Q0Mlx1NEU4Nlx1MzA1OVx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgotIyA0LjEgQ2hhcmFjdGVyIGFuZCBFbnRpdHkgUmVmZXJlbmNlcwotICAgICAgICBOYW1lUmVxdWlyZWRJblBFUmVmZXJlbmNlID0gXHUzMEQxXHUzMEU5XHUzMEUxXHUzMEZDXHUzMEJGXHUzMEZCXHUzMEE4XHUzMEYzXHUzMEM2XHUzMEEzXHUzMEM2XHUzMEEzXHU1M0MyXHU3MTY3XHUzMDY3XHUzMDZGXHUzMDAxXHUzMEE4XHUzMEYzXHUzMEM2XHUzMEEzXHUzMEM2XHUzMEEzXHU1NDBEXHUzMDZGJyUnXHUzMDZFXHU3NkY0XHU1RjhDXHUzMDZCXHU2MzA3XHU1QjlBXHUzMDU5XHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIFNlbWljb2xvblJlcXVpcmVkSW5QRVJlZmVyZW5jZSA9IFx1MzBEMVx1MzBFOVx1MzBFMVx1MzBGQ1x1MzBCRlx1MzBGQlx1MzBBOFx1MzBGM1x1MzBDNlx1MzBBM1x1MzBDNlx1MzBBM1x1NTNDMlx1NzE2NyIlezB9OyJcdTMwNkYnJzsnJ1x1MzBDN1x1MzBFQVx1MzBERlx1MzBCRlx1MzA2N1x1N0Q0Mlx1NEU4Nlx1MzA1OVx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgotIyA0LjIgRW50aXR5IERlY2xhcmF0aW9ucwotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX0VOVElUWV9OQU1FX0lOX0VOVElUWURFQ0wgPSBcdTMwQThcdTMwRjNcdTMwQzZcdTMwQTNcdTMwQzZcdTMwQTNcdTVCQTNcdThBMDBcdTMwNjdcdTMwNkZcdTMwMDEiPCFFTlRJVFkiXHUzMDZFXHU1RjhDXHUzMDZCXHU3QTdBXHU3NjdEXHUzMDRDXHU1RkM1XHU4OTgxXHUzMDY3XHUzMDU5XHUzMDAyCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfUEVSQ0VOVF9JTl9QRURFQ0wgPSBcdTMwRDFcdTMwRTlcdTMwRTFcdTMwRkNcdTMwQkZcdTMwRkJcdTMwQThcdTMwRjNcdTMwQzZcdTMwQTNcdTMwQzZcdTMwQTNcdTVCQTNcdThBMDBcdTMwNjdcdTMwNkZcdTMwMDEiPCFFTlRJVFkiXHUzMDY4JyUnXHU2NTg3XHU1QjU3XHUzMDZFXHU5NTkzXHUzMDZCXHU3QTdBXHU3NjdEXHUzMDRDXHU1RkM1XHU4OTgxXHUzMDY3XHUzMDU5XHUzMDAyCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfRU5USVRZX05BTUVfSU5fUEVERUNMID0gXHUzMEQxXHUzMEU5XHUzMEUxXHUzMEZDXHUzMEJGXHUzMEZCXHUzMEE4XHUzMEYzXHUzMEM2XHUzMEEzXHUzMEM2XHUzMEEzXHU1QkEzXHU4QTAwXHUzMDY3XHUzMDZGXHUzMDAxJyUnXHUzMDY4XHUzMEE4XHUzMEYzXHUzMEM2XHUzMEEzXHUzMEM2XHUzMEEzXHU1NDBEXHUzMDZFXHU5NTkzXHUzMDZCXHU3QTdBXHU3NjdEXHUzMDRDXHU1RkM1XHU4OTgxXHUzMDY3XHUzMDU5XHUzMDAyCi0gICAgICAgIE1TR19FTlRJVFlfTkFNRV9SRVFVSVJFRF9JTl9FTlRJVFlERUNMID0gXHUzMEE4XHUzMEYzXHUzMEM2XHUzMEEzXHUzMEM2XHUzMEEzXHU1QkEzXHU4QTAwXHUzMDZCXHUzMDZGXHUzMEE4XHUzMEYzXHUzMEM2XHUzMEEzXHUzMEM2XHUzMEEzXHUzMDZFXHU1NDBEXHU1MjREXHUzMDRDXHU1RkM1XHU4OTgxXHUzMDY3XHUzMDU5XHUzMDAyCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9BRlRFUl9FTlRJVFlfTkFNRV9JTl9FTlRJVFlERUNMID0gXHUzMEE4XHUzMEYzXHUzMEM2XHUzMEEzXHUzMEM2XHUzMEEzXHU1QkEzXHU4QTAwXHUzMDY3XHUzMDZGXHUzMDAxXHUzMEE4XHUzMEYzXHUzMEM2XHUzMEEzXHUzMEM2XHUzMEEzXHU1NDBEInswfSJcdTMwNjhcdTVCOUFcdTdGQTlcdTMwNkVcdTk1OTNcdTMwNkJcdTdBN0FcdTc2N0RcdTMwNENcdTVGQzVcdTg5ODFcdTMwNjdcdTMwNTlcdTMwMDIKLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9OT1RBVElPTl9OQU1FX0lOX1VOUEFSU0VEX0VOVElUWURFQ0wgPSBcdTMwQThcdTMwRjNcdTMwQzZcdTMwQTNcdTMwQzZcdTMwQTMiezB9Ilx1MzA2RVx1NUJBM1x1OEEwMFx1MzA2N1x1MzA2Rlx1MzAwMSJOREFUQSJcdTMwNjhcdTg4NjhcdThBMThcdTU0MERcdTMwNkVcdTk1OTNcdTMwNkJcdTdBN0FcdTc2N0RcdTMwNENcdTVGQzVcdTg5ODFcdTMwNjdcdTMwNTlcdTMwMDIKLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9OREFUQV9JTl9VTlBBUlNFRF9FTlRJVFlERUNMID0gXHUzMEE4XHUzMEYzXHUzMEM2XHUzMEEzXHUzMEM2XHUzMEEzInswfSJcdTMwNkVcdTVCQTNcdThBMDBcdTMwNjdcdTMwNkZcdTMwMDEiTkRBVEEiXHUzMDZFXHU1MjREXHUzMDZCXHU3QTdBXHU3NjdEXHUzMDRDXHU1RkM1XHU4OTgxXHUzMDY3XHUzMDU5XHUzMDAyCi0gICAgICAgIE1TR19OT1RBVElPTl9OQU1FX1JFUVVJUkVEX0ZPUl9VTlBBUlNFRF9FTlRJVFlERUNMID0gXHUzMEE4XHUzMEYzXHUzMEM2XHUzMEEzXHUzMEM2XHUzMEEzInswfSJcdTMwNkVcdTVCQTNcdThBMDBcdTMwNjdcdTMwNkZcdTMwMDEiTkRBVEEiXHUzMDZFXHU1RjhDXHUzMDZCXHU4ODY4XHU4QTE4XHU1NDBEXHUzMDRDXHU1RkM1XHU4OTgxXHUzMDY3XHUzMDU5XHUzMDAyCi0gICAgICAgIEVudGl0eURlY2xVbnRlcm1pbmF0ZWQgPSBcdTMwQThcdTMwRjNcdTMwQzZcdTMwQTNcdTMwQzZcdTMwQTMiezB9Ilx1MzA2RVx1NUJBM1x1OEEwMFx1MzA2RicnPicnXHUzMDY3XHU3RDQyXHU0RTg2XHUzMDU5XHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCi0JTVNHX0RVUExJQ0FURV9FTlRJVFlfREVGSU5JVElPTiA9IFx1MzBBOFx1MzBGM1x1MzBDNlx1MzBBM1x1MzBDNlx1MzBBMyJ7MH0iXHUzMDRDXHU4OTA3XHU2NTcwXHU1NkRFXHU1QkEzXHU4QTAwXHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5XHUzMDAyICAgICAgICAKLSMgNC4yLjIgRXh0ZXJuYWwgRW50aXRpZXMKLSAgICAgICAgRXh0ZXJuYWxJRFJlcXVpcmVkID0gXHU1OTE2XHU5MEU4XHUzMEE4XHUzMEYzXHUzMEM2XHUzMEEzXHUzMEM2XHUzMEEzXHU1QkEzXHU4QTAwXHUzMDZFXHU1MTQ4XHU5ODJEXHUzMDZCXHUzMDZGIlNZU1RFTSJcdTMwN0VcdTMwNUZcdTMwNkYiUFVCTElDIlx1MzA0Q1x1NUZDNVx1ODk4MVx1MzA2N1x1MzA1OVx1MzAwMgotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX1BVQklETElURVJBTF9JTl9FWFRFUk5BTElEID0gIlBVQkxJQyJcdTMwNjhcdTUxNkNcdTk1OEJcdThCNThcdTUyMjVcdTVCNTBcdTMwNkVcdTk1OTNcdTMwNkJcdTMwNkZcdTdBN0FcdTc2N0RcdTMwNENcdTVGQzVcdTg5ODFcdTMwNjdcdTMwNTlcdTMwMDIKLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0FGVEVSX1BVQklETElURVJBTF9JTl9FWFRFUk5BTElEID0gXHU1MTZDXHU5NThCXHU4QjU4XHU1MjI1XHU1QjUwXHUzMDY4XHUzMEI3XHUzMEI5XHUzMEM2XHUzMEUwXHU4QjU4XHU1MjI1XHU1QjUwXHUzMDZFXHU5NTkzXHUzMDZCXHUzMDZGXHU3QTdBXHU3NjdEXHUzMDRDXHU1RkM1XHU4OTgxXHUzMDY3XHUzMDU5XHUzMDAyCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfU1lTVEVNTElURVJBTF9JTl9FWFRFUk5BTElEID0gIlNZU1RFTSJcdTMwNjhcdTMwQjdcdTMwQjlcdTMwQzZcdTMwRTBcdThCNThcdTUyMjVcdTVCNTBcdTMwNkVcdTk1OTNcdTMwNkJcdTMwNkZcdTdBN0FcdTc2N0RcdTMwNENcdTVGQzVcdTg5ODFcdTMwNjdcdTMwNTlcdTMwMDIKLSAgICAgICAgTVNHX1VSSV9GUkFHTUVOVF9JTl9TWVNURU1JRCA9IFx1MzBENVx1MzBFOVx1MzBCMFx1MzBFMVx1MzBGM1x1MzBDOFx1OEI1OFx1NTIyNVx1NUI1MFx1MzA2Rlx1MzAwMVx1MzBCN1x1MzBCOVx1MzBDNlx1MzBFMFx1OEI1OFx1NTIyNVx1NUI1MCJ7MH0iXHUzMDZFXHU0RTAwXHU5MEU4XHUzMDY4XHUzMDU3XHUzMDY2XHU2MzA3XHU1QjlBXHUzMDU3XHUzMDZBXHUzMDQ0XHUzMDY3XHUzMDRGXHUzMDYwXHUzMDU1XHUzMDQ0XHUzMDAyCi0jIDQuNyBOb3RhdGlvbiBEZWNsYXJhdGlvbnMKLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9OT1RBVElPTl9OQU1FX0lOX05PVEFUSU9OREVDTCA9IFx1ODg2OFx1OEExOFx1NkNENVx1NUJBM1x1OEEwMFx1MzA2N1x1MzA2Rlx1MzAwMSI8IU5PVEFUSU9OIlx1MzA2RVx1NUY4Q1x1MzA2Qlx1N0E3QVx1NzY3RFx1MzA0Q1x1NUZDNVx1ODk4MVx1MzA2N1x1MzA1OVx1MzAwMgotICAgICAgICBNU0dfTk9UQVRJT05fTkFNRV9SRVFVSVJFRF9JTl9OT1RBVElPTkRFQ0wgPSBcdTg4NjhcdThBMThcdTZDRDVcdTVCQTNcdThBMDBcdTMwNkJcdTMwNkZcdTg4NjhcdThBMThcdTMwNkVcdTU0MERcdTUyNERcdTMwNENcdTVGQzVcdTg5ODFcdTMwNjdcdTMwNTlcdTMwMDIKLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0FGVEVSX05PVEFUSU9OX05BTUVfSU5fTk9UQVRJT05ERUNMID0gXHU4ODY4XHU4QTE4XHU2Q0Q1XHU1QkEzXHU4QTAwXHUzMDY3XHUzMDZGXHUzMDAxXHU4ODY4XHU4QTE4XHU1NDBEInswfSJcdTMwNkVcdTVGOENcdTMwNkJcdTdBN0FcdTc2N0RcdTMwNENcdTVGQzVcdTg5ODFcdTMwNjdcdTMwNTlcdTMwMDIKLSAgICAgICAgRXh0ZXJuYWxJRG9yUHVibGljSURSZXF1aXJlZCA9IFx1ODg2OFx1OEExOFx1NkNENSJ7MH0iXHUzMDZFXHU1QkEzXHU4QTAwXHUzMDZCXHUzMDZGXHUzMDAxXHUzMEI3XHUzMEI5XHUzMEM2XHUzMEUwXHU4QjU4XHU1MjI1XHU1QjUwXHUzMDdFXHUzMDVGXHUzMDZGXHU1MTZDXHU5NThCXHU4QjU4XHU1MjI1XHU1QjUwXHUzMDkyXHU1NDJCXHUzMDgxXHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIE5vdGF0aW9uRGVjbFVudGVybWluYXRlZCA9IFx1ODg2OFx1OEExOFx1NkNENSJ7MH0iXHUzMDZFXHU1QkEzXHU4QTAwXHUzMDZGJyc+JydcdTMwNjdcdTdENDJcdTRFODZcdTMwNTlcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIKLSAgICAgICAgCi0jIFZhbGlkYXRpb24gbWVzc2FnZXMKLSAgICAgICAgRHVwbGljYXRlVHlwZUluTWl4ZWRDb250ZW50ID0gXHU4OTgxXHU3RDIwXHUzMEJGXHUzMEE0XHUzMEQ3InsxfSJcdTMwNkZcdTMwMDFcdTg5ODFcdTdEMjBcdTVCQTNcdThBMDAiezB9Ilx1MzA2RVx1MzBCM1x1MzBGM1x1MzBDNlx1MzBGM1x1MzBDNFx1MzBGQlx1MzBFMlx1MzBDN1x1MzBFQlx1MzA2N1x1MzA1OVx1MzA2N1x1MzA2Qlx1NjMwN1x1NUI5QVx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBFTlRJVElFU0ludmFsaWQgPSBcdTMwQkZcdTMwQTRcdTMwRDdFTlRJVElFU1x1MzA2RVx1NUM1RVx1NjAyN1x1NTAyNCJ7MX0iXHUzMDZGXHUzMDAxMVx1MzA2NFx1NEVFNVx1NEUwQVx1MzA2RVx1NjcyQVx1ODlFM1x1Njc5MFx1MzBBOFx1MzBGM1x1MzBDNlx1MzBBM1x1MzBDNlx1MzBBM1x1MzA2RVx1NTQwRFx1NTI0RFx1MzA2Qlx1MzA1OVx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBFTlRJVFlJbnZhbGlkID0gXHUzMEJGXHUzMEE0XHUzMEQ3RU5USVRZXHUzMDZFXHU1QzVFXHU2MDI3XHU1MDI0InsxfSJcdTMwNkZcdTMwMDFcdTY3MkFcdTg5RTNcdTY3OTBcdTMwQThcdTMwRjNcdTMwQzZcdTMwQTNcdTMwQzZcdTMwQTNcdTMwNkVcdTU0MERcdTUyNERcdTMwNkJcdTMwNTlcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIKLSAgICAgICAgSUREZWZhdWx0VHlwZUludmFsaWQgPSBJRFx1NUM1RVx1NjAyNyJ7MH0iXHUzMDZCXHUzMDZGXHUzMDAxIiNJTVBMSUVEIlx1MzA3RVx1MzA1Rlx1MzA2RiIjUkVRVUlSRUQiXHUzMDZFXHU1QkEzXHU4QTAwXHU2RTA4XHUzMEM3XHUzMEQ1XHUzMEE5XHUzMEVCXHUzMEM4XHUzMDRDXHU1NDJCXHUzMDdFXHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIElESW52YWxpZCA9IFx1MzBCRlx1MzBBNFx1MzBEN0lEXHUzMDZFXHU1QzVFXHU2MDI3XHU1MDI0InswfSJcdTMwNkZcdTMwMDFcdTU0MERcdTUyNERcdTMwNkJcdTMwNTlcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIKLSAgICAgICAgSURJbnZhbGlkV2l0aE5hbWVzcGFjZXMgPSBcdTMwQ0RcdTMwRkNcdTMwRTBcdTMwQjlcdTMwREFcdTMwRkNcdTMwQjlcdTMwNENcdTY3MDlcdTUyQjlcdTMwNkJcdTMwNkFcdTMwNjNcdTMwNjZcdTMwNDRcdTMwOEJcdTU4MzRcdTU0MDhcdTMwMDFcdTMwQkZcdTMwQTRcdTMwRDdJRFx1MzA2RVx1NUM1RVx1NjAyN1x1NTAyNCJ7MH0iXHUzMDZGTkNOYW1lXHUzMDZCXHUzMDU5XHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIElETm90VW5pcXVlID0gXHUzMEJGXHUzMEE0XHUzMEQ3SURcdTMwNkVcdTVDNUVcdTYwMjdcdTUwMjQiezB9Ilx1MzA2Rlx1MzAwMVx1MzBDOVx1MzBBRFx1MzBFNVx1MzBFMVx1MzBGM1x1MzBDOFx1NTE4NVx1MzA2N1x1NEUwMFx1NjEwRlx1MzA2N1x1MzA0Mlx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBJRFJFRkludmFsaWQgPSBcdTMwQkZcdTMwQTRcdTMwRDdJRFJFRlx1MzA2RVx1NUM1RVx1NjAyN1x1NTAyNCJ7MH0iXHUzMDZGXHUzMDAxXHU1NDBEXHU1MjREXHUzMDZCXHUzMDU5XHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIElEUkVGSW52YWxpZFdpdGhOYW1lc3BhY2VzID0gXHUzMENEXHUzMEZDXHUzMEUwXHUzMEI5XHUzMERBXHUzMEZDXHUzMEI5XHUzMDRDXHU2NzA5XHU1MkI5XHUzMDZCXHUzMDZBXHUzMDYzXHUzMDY2XHUzMDQ0XHUzMDhCXHU1ODM0XHU1NDA4XHUzMDAxXHUzMEJGXHUzMEE0XHUzMEQ3SURSRUZcdTMwNkVcdTVDNUVcdTYwMjdcdTUwMjQiezB9Ilx1MzA2Rk5DTmFtZVx1MzA2Qlx1MzA1OVx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBJRFJFRlNJbnZhbGlkID0gXHUzMEJGXHUzMEE0XHUzMEQ3SURSRUZTXHUzMDZFXHU1QzVFXHU2MDI3XHU1MDI0InswfSJcdTMwNkZcdTMwMDExXHUzMDY0XHU0RUU1XHU0RTBBXHUzMDZFXHU1NDBEXHU1MjREXHUzMDZCXHUzMDU5XHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIElMTF9GT1JNRURfUEFSQU1FVEVSX0VOVElUWV9XSEVOX1VTRURfSU5fREVDTCA9IFx1MzBBOFx1MzBGM1x1MzBDNlx1MzBBM1x1MzBDNlx1MzBBM1x1NTNDMlx1NzE2N1x1MzA0Q1x1NUI4Q1x1NTE2OFx1MzA2QVx1NUJBM1x1OEEwMFx1MzA2OFx1MzA1N1x1MzA2Nlx1NEY3Rlx1NzUyOFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA4Qlx1NTgzNFx1NTQwOFx1MzAwMVx1MzBEMVx1MzBFOVx1MzBFMVx1MzBGQ1x1MzBCRlx1MzBGQlx1MzBBOFx1MzBGM1x1MzBDNlx1MzBBM1x1MzBDNlx1MzBBMyJ7MH0iXHUzMDZFXHU3RjZFXHU2M0RCXHUzMEM2XHUzMEFEXHUzMEI5XHUzMEM4XHUzMDZCXHUzMDZGXHUzMDAxXHU5MDY5XHU1MjA3XHUzMDZCXHUzMENEXHUzMEI5XHUzMEM4XHUzMDU1XHUzMDhDXHUzMDVGXHU1QkEzXHU4QTAwXHUzMDRDXHU1NDJCXHUzMDdFXHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIEltcHJvcGVyRGVjbGFyYXRpb25OZXN0aW5nID0gXHUzMEQxXHUzMEU5XHUzMEUxXHUzMEZDXHUzMEJGXHUzMEZCXHUzMEE4XHUzMEYzXHUzMEM2XHUzMEEzXHUzMEM2XHUzMEEzInswfSJcdTMwNkVcdTdGNkVcdTYzREJcdTMwQzZcdTMwQURcdTMwQjlcdTMwQzhcdTMwNkJcdTMwNkZcdTMwMDFcdTkwNjlcdTUyMDdcdTMwNkJcdTMwQ0RcdTMwQjlcdTMwQzhcdTMwNTVcdTMwOENcdTMwNUZcdTVCQTNcdThBMDBcdTMwNENcdTU0MkJcdTMwN0VcdTMwOENcdTMwNjZcdTMwNDRcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIKLSAgICAgICAgSW1wcm9wZXJHcm91cE5lc3RpbmcgPSBcdTMwRDFcdTMwRTlcdTMwRTFcdTMwRkNcdTMwQkZcdTMwRkJcdTMwQThcdTMwRjNcdTMwQzZcdTMwQTNcdTMwQzZcdTMwQTMiezB9Ilx1MzA2RVx1N0Y2RVx1NjNEQlx1MzBDNlx1MzBBRFx1MzBCOVx1MzBDOFx1MzA2Qlx1MzA2Rlx1MzAwMVx1OTA2OVx1NTIwN1x1MzA2Qlx1MzBDRFx1MzBCOVx1MzBDOFx1MzA1NVx1MzA4Q1x1MzA1Rlx1NEUzOFx1MzBBQlx1MzBDM1x1MzBCM1x1MzA2RVx1MzBEQVx1MzBBMlx1MzA0Q1x1NTQyQlx1MzA3RVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBJTlZBTElEX1BFX0lOX0NPTkRJVElPTkFMID0gXHUzMEQxXHUzMEU5XHUzMEUxXHUzMEZDXHUzMEJGXHUzMEZCXHUzMEE4XHUzMEYzXHUzMEM2XHUzMEEzXHUzMEM2XHUzMEEzInswfSJcdTMwNkVcdTdGNkVcdTYzREJcdTMwQzZcdTMwQURcdTMwQjlcdTMwQzhcdTMwNkJcdTMwNkZcdTMwMDFcdTY3NjFcdTRFRjZcdTRFRDhcdTMwNERcdTMwQkJcdTMwQUZcdTMwQjdcdTMwRTdcdTMwRjNcdTUxNjhcdTRGNTNcdTMwNEJcdTMwMDFJTkNMVURFXHUzMDdFXHUzMDVGXHUzMDZGSUdOT1JFXHUzMDZFXHUzMDdGXHUzMDRDXHU1NDJCXHUzMDdFXHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIE1TR19BVFRSSUJVVEVfTk9UX0RFQ0xBUkVEID0gXHU4OTgxXHU3RDIwXHUzMEJGXHUzMEE0XHUzMEQ3InswfSJcdTMwNkJcdTVCRkVcdTMwNTdcdTMwNjZcdTVDNUVcdTYwMjciezF9Ilx1MzA0Q1x1NUJBM1x1OEEwMFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBNU0dfQVRUUklCVVRFX1ZBTFVFX05PVF9JTl9MSVNUID0gXHU1MDI0InsxfSJcdTMwOTJcdTYzMDFcdTMwNjRcdTVDNUVcdTYwMjciezB9Ilx1MzA2Qlx1MzA2Rlx1MzAwMVx1MzBFQVx1MzBCOVx1MzBDOCJ7Mn0iXHUzMDRCXHUzMDg5XHUzMDZFXHU1MDI0XHUzMDRDXHU1RkM1XHU4OTgxXHUzMDY3XHUzMDU5XHUzMDAyCi0gICAgICAgIE1TR19BVFRWQUxVRV9DSEFOR0VEX0RVUklOR19OT1JNQUxJWkFUSU9OX1dIRU5fU1RBTkRBTE9ORSA9IFx1NUM1RVx1NjAyNyJ7MH0iXHUzMDZFXHU1MDI0InsxfSJcdTMwNkZcdTMwMDFcdTMwQjlcdTMwQkZcdTMwRjNcdTMwQzlcdTMwQTJcdTMwRURcdTMwRjNcdTMwRkJcdTMwQzlcdTMwQURcdTMwRTVcdTMwRTFcdTMwRjNcdTMwQzhcdTMwNjdcdTZCNjNcdTg5OEZcdTUzMTZcdTMwNkJcdTMwODhcdTMwNjNcdTMwNjYoInsyfSJcdTMwNkIpXHU1OTA5XHU2NkY0XHUzMDU1XHUzMDhDXHUzMDZBXHUzMDQ0XHUzMDg4XHUzMDQ2XHUzMDZCXHUzMDU5XHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIE1TR19DT05URU5UX0lOQ09NUExFVEUgPSBcdTg5ODFcdTdEMjBcdTMwQkZcdTMwQTRcdTMwRDciezB9Ilx1MzA2RVx1MzBCM1x1MzBGM1x1MzBDNlx1MzBGM1x1MzBDNFx1MzA0Q1x1NEUwRFx1NUI4Q1x1NTE2OFx1MzA2N1x1MzA1OVx1MzAwMiJ7MX0iXHUzMDY4XHU0RTAwXHU4MUY0XHUzMDU5XHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIE1TR19DT05URU5UX0lOVkFMSUQgPSBcdTg5ODFcdTdEMjBcdTMwQkZcdTMwQTRcdTMwRDciezB9Ilx1MzA2RVx1MzBCM1x1MzBGM1x1MzBDNlx1MzBGM1x1MzBDNFx1MzA2RiJ7MX0iXHUzMDY4XHU0RTAwXHU4MUY0XHUzMDU5XHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIE1TR19DT05URU5UX0lOVkFMSURfU1BFQ0lGSUVEID0gXHU4OTgxXHU3RDIwXHUzMEJGXHUzMEE0XHUzMEQ3InswfSJcdTMwNkVcdTMwQjNcdTMwRjNcdTMwQzZcdTMwRjNcdTMwQzRcdTMwNkYiezF9Ilx1MzA2OFx1NEUwMFx1ODFGNFx1MzA1OVx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMlx1MzBCRlx1MzBBNFx1MzBENyJ7Mn0iXHUzMDZFXHU1QjUwXHUzMDZGXHU4QTMxXHU1M0VGXHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0gICAgICAgIE1TR19ERUZBVUxURURfQVRUUklCVVRFX05PVF9TUEVDSUZJRUQgPSBcdTg5ODFcdTdEMjBcdTMwQkZcdTMwQTRcdTMwRDciezB9Ilx1MzA2RVx1NUM1RVx1NjAyNyJ7MX0iXHUzMDZGXHUzMDAxXHUzMEM3XHUzMEQ1XHUzMEE5XHUzMEVCXHUzMEM4XHU1MDI0XHUzMDkyXHU2MzAxXHUzMDYxXHUzMDAxXHUzMEI5XHUzMEJGXHUzMEYzXHUzMEM5XHUzMEEyXHUzMEVEXHUzMEYzXHUzMEZCXHUzMEM5XHUzMEFEXHUzMEU1XHUzMEUxXHUzMEYzXHUzMEM4XHUzMDY3XHU2MzA3XHU1QjlBXHUzMDU5XHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIE1TR19EVVBMSUNBVEVfQVRUREVGID0gXHU1QzVFXHU2MDI3InsxfSJcdTMwNkZcdTg5ODFcdTdEMjBcdTMwQkZcdTMwQTRcdTMwRDciezB9Ilx1MzA2Qlx1NUJGRVx1MzA1N1x1MzA2Nlx1MzA1OVx1MzA2N1x1MzA2Qlx1NUJBM1x1OEEwMFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBNU0dfRUxFTUVOVF9BTFJFQURZX0RFQ0xBUkVEID0gXHU4OTgxXHU3RDIwXHUzMEJGXHUzMEE0XHUzMEQ3InswfSJcdTMwNkZcdTg5MDdcdTY1NzBcdTU2REVcdTVCQTNcdThBMDBcdTMwNTdcdTMwNkFcdTMwNDRcdTMwNjdcdTMwNEZcdTMwNjBcdTMwNTVcdTMwNDRcdTMwMDIKLSAgICAgICAgTVNHX0VMRU1FTlRfTk9UX0RFQ0xBUkVEID0gXHU4OTgxXHU3RDIwXHUzMEJGXHUzMEE0XHUzMEQ3InswfSJcdTMwOTJcdTVCQTNcdThBMDBcdTMwNTlcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIKLSAgICAgICAgTVNHX0dSQU1NQVJfTk9UX0ZPVU5EID0gXHUzMEM5XHUzMEFEXHUzMEU1XHUzMEUxXHUzMEYzXHUzMEM4XHUzMDRDXHU3MTIxXHU1MkI5XHUzMDY3XHUzMDU5OiBcdTY5Q0JcdTY1ODdcdTMwNENcdTg5OEJcdTMwNjRcdTMwNEJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLSAgICAgICAgTVNHX0VMRU1FTlRfV0lUSF9JRF9SRVFVSVJFRCA9IFx1MzBDOVx1MzBBRFx1MzBFNVx1MzBFMVx1MzBGM1x1MzBDOFx1MzA2Qlx1MzA2Rlx1OEI1OFx1NTIyNVx1NUI1MCJ7MH0iXHUzMDkyXHU2MzAxXHUzMDY0XHU4OTgxXHU3RDIwXHUzMDRDXHU1RkM1XHU4OTgxXHUzMDY3XHUzMDU5XHUzMDAyCi0gICAgICAgIE1TR19FWFRFUk5BTF9FTlRJVFlfTk9UX1BFUk1JVFRFRCA9IFx1NTkxNlx1OTBFOFx1MzBBOFx1MzBGM1x1MzBDNlx1MzBBM1x1MzBDNlx1MzBBMyJ7MH0iXHUzMDc4XHUzMDZFXHU1M0MyXHU3MTY3XHUzMDZGXHUzMDAxXHUzMEI5XHUzMEJGXHUzMEYzXHUzMEM5XHUzMEEyXHUzMEVEXHUzMEYzXHUzMEZCXHUzMEM5XHUzMEFEXHUzMEU1XHUzMEUxXHUzMEYzXHUzMEM4XHUzMDY3XHUzMDZGXHU4QTMxXHU1M0VGXHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0gICAgICAgIE1TR19GSVhFRF9BVFRWQUxVRV9JTlZBTElEID0gXHU1MDI0InsyfSJcdTMwOTJcdTYzMDFcdTMwNjRcdTVDNUVcdTYwMjciezF9Ilx1MzA2Qlx1MzA2Rlx1MzAwMSJ7M30iXHUzMDZFXHU1MDI0XHUzMDRDXHU1RkM1XHU4OTgxXHUzMDY3XHUzMDU5XHUzMDAyCi0gICAgICAgIE1TR19NT1JFX1RIQU5fT05FX0lEX0FUVFJJQlVURSA9IFx1ODk4MVx1N0QyMFx1MzBCRlx1MzBBNFx1MzBENyJ7MH0iXHUzMDZCXHUzMDZGXHUzMDAxXHUzMEJGXHUzMEE0XHUzMEQ3SURcdTMwNkVcdTVDNUVcdTYwMjciezF9Ilx1MzA0Q1x1MzA1OVx1MzA2N1x1MzA2Qlx1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMlx1MzBCRlx1MzBBNFx1MzBEN0lEXHUzMDZFXHU1QzVFXHU2MDI3InsyfSJcdTMwOTJcdTMwODJcdTMwNDYxXHUzMDY0XHU2MzA3XHU1QjlBXHUzMDU5XHUzMDhCXHUzMDUzXHUzMDY4XHUzMDZGXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0gICAgICAgIE1TR19NT1JFX1RIQU5fT05FX05PVEFUSU9OX0FUVFJJQlVURSA9IFx1ODk4MVx1N0QyMFx1MzBCRlx1MzBBNFx1MzBENyJ7MH0iXHUzMDZCXHUzMDZGXHUzMDAxXHUzMEJGXHUzMEE0XHUzMEQ3Tk9UQVRJT05cdTMwNkVcdTVDNUVcdTYwMjciezF9Ilx1MzA0Q1x1MzA1OVx1MzA2N1x1MzA2Qlx1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMlx1MzBCRlx1MzBBNFx1MzBEN05PVEFUSU9OXHUzMDZFXHU1QzVFXHU2MDI3InsyfSJcdTMwOTJcdTMwODJcdTMwNDYxXHUzMDY0XHU2MzA3XHU1QjlBXHUzMDU5XHUzMDhCXHUzMDUzXHUzMDY4XHUzMDZGXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0gICAgICAgIE1TR19OT1RBVElPTl9OT1RfREVDTEFSRURfRk9SX05PVEFUSU9OVFlQRV9BVFRSSUJVVEUgPSBcdTVDNUVcdTYwMjciezB9Ilx1MzA2RVx1ODg2OFx1OEExOFx1NkNENVx1MzBCRlx1MzBBNFx1MzBEN1x1MzBGQlx1MzBFQVx1MzBCOVx1MzBDOFx1MzA2N1x1NTNDMlx1NzE2N1x1MzA1NVx1MzA4Q1x1MzA4Qlx1NTgzNFx1NTQwOFx1MzAwMVx1ODg2OFx1OEExOFx1NkNENSJ7MX0iXHUzMDkyXHU1QkEzXHU4QTAwXHUzMDU5XHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIE1TR19OT1RBVElPTl9OT1RfREVDTEFSRURfRk9SX1VOUEFSU0VEX0VOVElUWURFQ0wgPSAiezB9Ilx1MzA2RVx1NjcyQVx1ODlFM1x1Njc5MFx1MzBBOFx1MzBGM1x1MzBDNlx1MzBBM1x1MzBDNlx1MzBBM1x1NUJBM1x1OEEwMFx1MzA2N1x1NTNDMlx1NzE2N1x1MzA1NVx1MzA4Q1x1MzA4Qlx1NTgzNFx1NTQwOFx1MzAwMVx1ODg2OFx1OEExOFx1NkNENSJ7MX0iXHUzMDkyXHU1QkEzXHU4QTAwXHUzMDU5XHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIE1TR19SRUZFUkVOQ0VfVE9fRVhURVJOQUxMWV9ERUNMQVJFRF9FTlRJVFlfV0hFTl9TVEFOREFMT05FID0gXHU1OTE2XHU5MEU4XHUzMDZFXHU4OUUzXHU2NzkwXHU2RTA4XHUzMEE4XHUzMEYzXHUzMEM2XHUzMEEzXHUzMEM2XHUzMEEzXHUzMDY3XHU1QkEzXHU4QTAwXHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDhCXHUzMEE4XHUzMEYzXHUzMEM2XHUzMEEzXHUzMEM2XHUzMEEzInswfSJcdTMwNzhcdTMwNkVcdTUzQzJcdTcxNjdcdTMwNkZcdTMwMDFcdTMwQjlcdTMwQkZcdTMwRjNcdTMwQzlcdTMwQTJcdTMwRURcdTMwRjNcdTMwRkJcdTMwQzlcdTMwQURcdTMwRTVcdTMwRTFcdTMwRjNcdTMwQzhcdTMwNjdcdTMwNkZcdThBMzFcdTUzRUZcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLSAgICAgICAgTVNHX1JFUVVJUkVEX0FUVFJJQlVURV9OT1RfU1BFQ0lGSUVEID0gXHU1QzVFXHU2MDI3InsxfSJcdTMwNENcdTVGQzVcdTg5ODFcdTMwNjdcdTMwNTlcdTMwMDJcdTMwNTNcdTMwNkVcdTVDNUVcdTYwMjdcdTMwNkZcdTMwMDFcdTg5ODFcdTdEMjBcdTMwQkZcdTMwQTRcdTMwRDciezB9Ilx1MzA2Qlx1NUJGRVx1MzA1N1x1MzA2Nlx1NjMwN1x1NUI5QVx1MzA1OVx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBNU0dfV0hJVEVfU1BBQ0VfSU5fRUxFTUVOVF9DT05URU5UX1dIRU5fU1RBTkRBTE9ORSA9IFx1MzBCOVx1MzBCRlx1MzBGM1x1MzBDOVx1MzBBMlx1MzBFRFx1MzBGM1x1MzBGQlx1MzBDOVx1MzBBRFx1MzBFNVx1MzBFMVx1MzBGM1x1MzBDOFx1MzA2N1x1MzA2Rlx1MzAwMVx1ODk4MVx1N0QyMFx1MzBCM1x1MzBGM1x1MzBDNlx1MzBGM1x1MzBDNFx1MzA5Mlx1NjMwMVx1MzA2NFx1NTkxNlx1OTBFOFx1MzA2RVx1ODlFM1x1Njc5MFx1NkUwOFx1MzBBOFx1MzBGM1x1MzBDNlx1MzBBM1x1MzBDNlx1MzBBM1x1MzA2N1x1NUJBM1x1OEEwMFx1MzA1NVx1MzA4Q1x1MzA4Qlx1ODk4MVx1N0QyMFx1OTU5M1x1MzA2Qlx1N0E3QVx1NzY3RFx1MzA2Rlx1NEUwRFx1ODk4MVx1MzA2N1x1MzA1OVx1MzAwMgotICAgICAgICBOTVRPS0VOSW52YWxpZCA9IFx1MzBCRlx1MzBBNFx1MzBEN05NVE9LRU5cdTMwNkVcdTVDNUVcdTYwMjdcdTUwMjQiezB9Ilx1MzA2Rlx1MzAwMVx1NTQwRFx1NTI0RFx1MzBDOFx1MzBGQ1x1MzBBRlx1MzBGM1x1MzA2Qlx1MzA1OVx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBOTVRPS0VOU0ludmFsaWQgPSBcdTMwQkZcdTMwQTRcdTMwRDdOTVRPS0VOU1x1MzA2RVx1NUM1RVx1NjAyN1x1NTAyNCJ7MH0iXHUzMDZGXHUzMDAxMVx1MzA2NFx1NEVFNVx1NEUwQVx1MzA2RVx1NTQwRFx1NTI0RFx1MzBDOFx1MzBGQ1x1MzBBRlx1MzBGM1x1MzA2Qlx1MzA1OVx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBOb05vdGF0aW9uT25FbXB0eUVsZW1lbnQgPSBFTVBUWVx1MzA2OFx1NUJBM1x1OEEwMFx1MzA1NVx1MzA4Q1x1MzA1Rlx1ODk4MVx1N0QyMFx1MzBCRlx1MzBBNFx1MzBENyJ7MH0iXHUzMDY3XHUzMDZGXHUzMDAxXHUzMEJGXHUzMEE0XHUzMEQ3Tk9UQVRJT05cdTMwNkVcdTVDNUVcdTYwMjciezF9Ilx1MzA5Mlx1NUJBM1x1OEEwMFx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotICAgICAgICBSb290RWxlbWVudFR5cGVNdXN0TWF0Y2hEb2N0eXBlZGVjbCA9IFx1MzBDOVx1MzBBRFx1MzBFNVx1MzBFMVx1MzBGM1x1MzBDOFx1MzBGQlx1MzBFQlx1MzBGQ1x1MzBDOFx1ODk4MVx1N0QyMCJ7MX0iXHUzMDZGRE9DVFlQRVx1MzBFQlx1MzBGQ1x1MzBDOCJ7MH0iXHUzMDY4XHU0RTAwXHU4MUY0XHUzMDU5XHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIFVuZGVjbGFyZWRFbGVtZW50SW5Db250ZW50U3BlYyA9IFx1ODk4MVx1N0QyMCJ7MH0iXHUzMDZFXHUzMEIzXHUzMEYzXHUzMEM2XHUzMEYzXHUzMEM0XHUzMEZCXHUzMEUyXHUzMEM3XHUzMEVCXHUzMDY3XHU2NzJBXHU1QkEzXHU4QTAwXHUzMDZFXHU4OTgxXHU3RDIwInsxfSJcdTMwNENcdTUzQzJcdTcxNjdcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTlcdTMwMDIKLSAgICAgICAgVW5pcXVlTm90YXRpb25OYW1lID0gXHU4ODY4XHU4QTE4XHU2Q0Q1InswfSJcdTMwNkVcdTVCQTNcdThBMDBcdTMwNENcdTRFMDBcdTYxMEZcdTMwNjdcdTMwNkZcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDJcdTU0MENcdTMwNThcdTU0MERcdTUyNERcdTMwOTJcdTg5MDdcdTY1NzBcdTMwNkVcdTg4NjhcdThBMThcdTZDRDVcdTVCQTNcdThBMDBcdTMwNjdcdTVCQTNcdThBMDBcdTMwNTdcdTMwNkFcdTMwNDRcdTMwNjdcdTMwNEZcdTMwNjBcdTMwNTVcdTMwNDRcdTMwMDIKLSAgICAgICAgRU5USVRZRmFpbGVkSW5pdGlhbGl6ZUdyYW1tYXIgPSAgRU5USVRZRGF0YXR5cGVcdTMwRDBcdTMwRUFcdTMwQzdcdTMwRkNcdTMwQkY6IFx1NjcwOVx1NTJCOVx1MzA2QVx1NjlDQlx1NjU4N1x1NTNDMlx1NzE2N1x1MzA2Qlx1MzA4OFx1MzA4Qlx1NTIxRFx1NjcxRlx1NTMxNlx1MzBFMVx1MzBCRFx1MzBDM1x1MzBDOVx1MzA2RVx1NTQ3Q1x1NTFGQVx1MzA1N1x1MzA2Qlx1NTkzMVx1NjU1N1x1MzA1N1x1MzA3RVx1MzA1N1x1MzA1Rlx1MzAwMiBcdAotICAgICAgICBFTlRJVFlOb3RVbnBhcnNlZCA9IEVOVElUWSAiezB9Ilx1MzA2Rlx1NjcyQVx1ODlFM1x1Njc5MFx1MzA2N1x1MzA2Rlx1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotICAgICAgICBFTlRJVFlOb3RWYWxpZCA9IEVOVElUWSAiezB9Ilx1MzA2Rlx1NjcwOVx1NTJCOVx1MzA2N1x1MzA2Rlx1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotICAgICAgICBFbXB0eUxpc3QgPSBcdTMwQkZcdTMwQTRcdTMwRDdFTlRJVElFU1x1MzAwMUlEUkVGU1x1MzA0QVx1MzA4OFx1MzA3M05NVE9LRU5TXHUzMDZFXHU1MDI0XHUzMDZGXHU3QTdBXHUzMDZFXHUzMEVBXHUzMEI5XHUzMEM4XHUzMDZCXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0KLSMgRW50aXR5IHJlbGF0ZWQgbWVzc2FnZXMKLSMgMy4xIFN0YXJ0LVRhZ3MsIEVuZC1UYWdzLCBhbmQgRW1wdHktRWxlbWVudCBUYWdzCi0gICAgICAgIFJlZmVyZW5jZVRvRXh0ZXJuYWxFbnRpdHkgPSBcdTU5MTZcdTkwRThcdTMwQThcdTMwRjNcdTMwQzZcdTMwQTNcdTMwQzZcdTMwQTNcdTUzQzJcdTcxNjciJnswfTsiXHUzMDZGXHUzMDAxXHU1QzVFXHU2MDI3XHU1MDI0XHUzMDY3XHUzMDZGXHU4QTMxXHU1M0VGXHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0gICAgICAgIEFjY2Vzc0V4dGVybmFsRFREID0gXHU1OTE2XHU5MEU4RFREOiBhY2Nlc3NFeHRlcm5hbERURFx1MzBEN1x1MzBFRFx1MzBEMVx1MzBDNlx1MzBBM1x1MzA2N1x1OEEyRFx1NUI5QVx1MzA1NVx1MzA4Q1x1MzA1Rlx1NTIzNlx1OTY1MFx1MzA2Qlx1MzA4OFx1MzA4QScnezF9JydcdTMwQTJcdTMwQUZcdTMwQkJcdTMwQjlcdTMwNENcdThBMzFcdTUzRUZcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwNkFcdTMwNDRcdTMwNUZcdTMwODFcdTMwMDFcdTU5MTZcdTkwRThEVEQgJyd7MH0nJ1x1MzA2RVx1OEFBRFx1NTNENlx1MzA4QVx1MzA2Qlx1NTkzMVx1NjU1N1x1MzA1N1x1MzA3RVx1MzA1N1x1MzA1Rlx1MzAwMgotICAgICAgICBBY2Nlc3NFeHRlcm5hbEVudGl0eSA9IFx1NTkxNlx1OTBFOFx1MzBBOFx1MzBGM1x1MzBDNlx1MzBBM1x1MzBDNlx1MzBBMzogYWNjZXNzRXh0ZXJuYWxEVERcdTMwRDdcdTMwRURcdTMwRDFcdTMwQzZcdTMwQTNcdTMwNjdcdThBMkRcdTVCOUFcdTMwNTVcdTMwOENcdTMwNUZcdTUyMzZcdTk2NTBcdTMwNkJcdTMwODhcdTMwOEEnJ3sxfScnXHUzMEEyXHUzMEFGXHUzMEJCXHUzMEI5XHUzMDRDXHU4QTMxXHU1M0VGXHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDZBXHUzMDQ0XHUzMDVGXHUzMDgxXHUzMDAxXHU1OTE2XHU5MEU4XHUzMEM5XHUzMEFEXHUzMEU1XHUzMEUxXHUzMEYzXHUzMEM4Jyd7MH0nJ1x1MzA2RVx1OEFBRFx1NTNENlx1MzA4QVx1MzA2Qlx1NTkzMVx1NjU1N1x1MzA1N1x1MzA3RVx1MzA1N1x1MzA1Rlx1MzAwMgotCi0jIDQuMSBDaGFyYWN0ZXIgYW5kIEVudGl0eSBSZWZlcmVuY2VzCi0gICAgICAgIEVudGl0eU5vdERlY2xhcmVkID0gXHUzMEE4XHUzMEYzXHUzMEM2XHUzMEEzXHUzMEM2XHUzMEEzInswfSJcdTMwNENcdTUzQzJcdTcxNjdcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTlcdTMwNENcdTMwMDFcdTVCQTNcdThBMDBcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLSAgICAgICAgUmVmZXJlbmNlVG9VbnBhcnNlZEVudGl0eSA9IFx1NjcyQVx1ODlFM1x1Njc5MFx1MzBBOFx1MzBGM1x1MzBDNlx1MzBBM1x1MzBDNlx1MzBBM1x1NTNDMlx1NzE2NyImezB9OyJcdTMwNkZcdThBMzFcdTUzRUZcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLSAgICAgICAgUmVjdXJzaXZlUmVmZXJlbmNlID0gXHU1MThEXHU1RTMwXHU3Njg0XHUzMDZBXHUzMEE4XHUzMEYzXHUzMEM2XHUzMEEzXHUzMEM2XHUzMEEzXHU1M0MyXHU3MTY3InswfSJcdTMwNjdcdTMwNTlcdTMwMDIoXHU1M0MyXHU3MTY3XHUzMEQxXHUzMEI5OiB7MX0pXHUzMDAxCi0gICAgICAgIFJlY3Vyc2l2ZUdlbmVyYWxSZWZlcmVuY2UgPSBcdTUxOERcdTVFMzBcdTc2ODRcdTMwNkFcdTRFMDBcdTgyMkNcdTMwQThcdTMwRjNcdTMwQzZcdTMwQTNcdTMwQzZcdTMwQTNcdTUzQzJcdTcxNjciJnswfTsiXHUzMDY3XHUzMDU5XHUzMDAyKFx1NTNDMlx1NzE2N1x1MzBEMVx1MzBCOTogezF9KVx1MzAwMQotICAgICAgICBSZWN1cnNpdmVQRVJlZmVyZW5jZSA9IFx1NTE4RFx1NUUzMFx1NzY4NFx1MzA2QVx1MzBEMVx1MzBFOVx1MzBFMVx1MzBGQ1x1MzBCRlx1MzBGQlx1MzBBOFx1MzBGM1x1MzBDNlx1MzBBM1x1MzBDNlx1MzBBM1x1NTNDMlx1NzE2NyIlezB9OyJcdTMwNjdcdTMwNTlcdTMwMDIoXHU1M0MyXHU3MTY3XHUzMEQxXHUzMEI5OiB7MX0pXHUzMDAxCi0jIDQuMy4zIENoYXJhY3RlciBFbmNvZGluZyBpbiBFbnRpdGllcwotICAgICAgICBFbmNvZGluZ05vdFN1cHBvcnRlZCA9IFx1MzBBOFx1MzBGM1x1MzBCM1x1MzBGQ1x1MzBDN1x1MzBBM1x1MzBGM1x1MzBCMCJ7MH0iXHUzMDZGXHUzMEI1XHUzMEREXHUzMEZDXHUzMEM4XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0gICAgICAgIEVuY29kaW5nUmVxdWlyZWQgPSBcdTMwQThcdTMwRjNcdTMwQjNcdTMwRkNcdTMwQzlcdTMwNENVVEYtOFx1MzA2OFVURi0xNlx1MzA2RVx1MzA0NFx1MzA1QVx1MzA4Q1x1MzA2N1x1MzA4Mlx1MzA2QVx1MzA0NFx1ODlFM1x1Njc5MFx1NkUwOFx1MzBBOFx1MzBGM1x1MzBDNlx1MzBBM1x1MzBDNlx1MzBBM1x1MzA2Qlx1MzA2Rlx1MzAwMVx1MzBBOFx1MzBGM1x1MzBCM1x1MzBGQ1x1MzBDN1x1MzBBM1x1MzBGM1x1MzBCMFx1NUJBM1x1OEEwMFx1MzA0Q1x1NTQyQlx1MzA3RVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICAKLSMgTmFtZXNwYWNlcyBzdXBwb3J0Ci0jIDQuIFVzaW5nIFF1YWxpZmllZCBOYW1lcwotICAgICAgICBJbGxlZ2FsUU5hbWUgPSBcdTg5ODFcdTdEMjBcdTMwN0VcdTMwNUZcdTMwNkZcdTVDNUVcdTYwMjdcdTMwNENRTmFtZVx1NzUxRlx1NjIxMFx1MzA2OFx1NEUwMFx1ODFGNFx1MzA1N1x1MzA3RVx1MzA1Qlx1MzA5MzogUU5hbWU6Oj0oTkNOYW1lJzonKT9OQ05hbWVcdTMwMDIgCi0gICAgICAgIEVsZW1lbnRYTUxOU1ByZWZpeCA9IFx1ODk4MVx1N0QyMCJ7MH0iXHUzMDZFXHU2M0E1XHU5ODJEXHU4RjlFXHUzMDY4XHUzMDU3XHUzMDY2InhtbG5zIlx1MzA2Rlx1NjMwN1x1NUI5QVx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotICAgICAgICBFbGVtZW50UHJlZml4VW5ib3VuZCA9IFx1ODk4MVx1N0QyMCJ7MX0iXHUzMDZFXHU2M0E1XHU5ODJEXHU4RjlFInswfSJcdTMwNENcdTMwRDBcdTMwQTRcdTMwRjNcdTMwQzlcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLSAgICAgICAgQXR0cmlidXRlUHJlZml4VW5ib3VuZCA9IFx1ODk4MVx1N0QyMFx1MzBCRlx1MzBBNFx1MzBENyJ7MH0iXHUzMDZCXHU5NUEyXHU5MDIzXHU0RUQ4XHUzMDUxXHUzMDg5XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDhCXHU1QzVFXHU2MDI3InsxfSJcdTMwNkVcdTYzQTVcdTk4MkRcdThGOUUiezJ9Ilx1MzA0Q1x1MzBEMFx1MzBBNFx1MzBGM1x1MzBDOVx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotICAgICAgICBFbXB0eVByZWZpeGVkQXR0TmFtZSA9IFx1NUM1RVx1NjAyNyJ7MH0iXHUzMDZFXHU1MDI0XHUzMDRDXHU3MTIxXHU1MkI5XHUzMDY3XHUzMDU5XHUzMDAyXHU2M0E1XHU5ODJEXHU4RjlFXHUzMDZFXHU0RUQ4XHUzMDQ0XHUzMDVGXHUzMENEXHUzMEZDXHUzMEUwXHUzMEI5XHUzMERBXHUzMEZDXHUzMEI5XHUzMEZCXHUzMEQwXHUzMEE0XHUzMEYzXHUzMEM3XHUzMEEzXHUzMEYzXHUzMEIwXHUzMDZGXHU3QTdBXHUzMDZCXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0gICAgICAgIFByZWZpeERlY2xhcmVkID0gXHUzMENEXHUzMEZDXHUzMEUwXHUzMEI5XHUzMERBXHUzMEZDXHUzMEI5XHUzMDZFXHU2M0E1XHU5ODJEXHU4RjlFInswfSJcdTMwNENcdTVCQTNcdThBMDBcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLSAgICAgICAgQ2FudEJpbmRYTUxOUyA9IFx1NjNBNVx1OTgyRFx1OEY5RSJ4bWxucyJcdTMwNkZcdTMwMDFcdTMwQ0RcdTMwRkNcdTMwRTBcdTMwQjlcdTMwREFcdTMwRkNcdTMwQjlcdTMwNkJcdTY2MEVcdTc5M0FcdTc2ODRcdTMwNkJcdTMwRDBcdTMwQTRcdTMwRjNcdTMwQzlcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDJcdTMwN0VcdTMwNUZcdTMwMDEieG1sbnMiXHUzMDZFXHUzMENEXHUzMEZDXHUzMEUwXHUzMEI5XHUzMERBXHUzMEZDXHUzMEI5XHUzMDgyXHUzMDAxXHU2M0E1XHU5ODJEXHU4RjlFXHUzMDZCXHU2NjBFXHU3OTNBXHU3Njg0XHUzMDZCXHUzMEQwXHUzMEE0XHUzMEYzXHUzMEM5XHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0gICAgICAgIENhbnRCaW5kWE1MID0gXHU2M0E1XHU5ODJEXHU4RjlFInhtbCJcdTMwNkZcdTMwMDFcdTkwMUFcdTVFMzhcdTMwNkVcdTMwQ0RcdTMwRkNcdTMwRTBcdTMwQjlcdTMwREFcdTMwRkNcdTMwQjlcdTRFRTVcdTU5MTZcdTMwNkVcdTMwQ0RcdTMwRkNcdTMwRTBcdTMwQjlcdTMwREFcdTMwRkNcdTMwQjlcdTMwNkJcdTMwRDBcdTMwQTRcdTMwRjNcdTMwQzlcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDJcdTMwN0VcdTMwNUZcdTMwMDEieG1sIlx1MzA2RVx1MzBDRFx1MzBGQ1x1MzBFMFx1MzBCOVx1MzBEQVx1MzBGQ1x1MzBCOVx1MzA4Mlx1MzAwMSJ4bWwiXHU0RUU1XHU1OTE2XHUzMDZFXHU2M0E1XHU5ODJEXHU4RjlFXHUzMDZCXHUzMEQwXHUzMEE0XHUzMEYzXHUzMEM5XHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0gICAgICAgIE1TR19BVFRfREVGQVVMVF9JTlZBTElEID0gXHU1QzVFXHU2MDI3InswfSJcdTMwNkVkZWZhdWx0VmFsdWUgInsxfSJcdTMwNkZcdTMwMDFcdTMwNTNcdTMwNkVcdTVDNUVcdTYwMjdcdTMwQkZcdTMwQTRcdTMwRDdcdTMwNkVcdTVCNTdcdTUzRTVcdTUyMzZcdTdEMDRcdTMwNkJcdTk1QTJcdTMwNTdcdTMwNjZcdTY3MDlcdTUyQjlcdTMwNjdcdTMwNkZcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLQotIyBSRVZJU0lUOiBUaGVzZSBuZWVkIG1lc3NhZ2VzCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9BRlRFUl9TWVNURU1MSVRFUkFMX0lOX0VYVEVSTkFMSUQ9TVNHX1NQQUNFX1JFUVVJUkVEX0FGVEVSX1NZU1RFTUxJVEVSQUxfSU5fRVhURVJOQUxJRAotICAgICAgICBPcGVuUXVvdGVNaXNzaW5nSW5EZWNsPU9wZW5RdW90ZU1pc3NpbmdJbkRlY2wKLSAgICAgICAgSW52YWxpZENoYXJJbkxpdGVyYWw9SW52YWxpZENoYXJJbkxpdGVyYWwKLQotCi0jIEltcGxlbWVudGF0aW9uIGxpbWl0cwotICAgICAgICBFbnRpdHlFeHBhbnNpb25MaW1pdD1KQVhQMDAwMTAwMDE6IFx1MzBEMVx1MzBGQ1x1MzBCNVx1MzBGQ1x1MzA2Qlx1MzA4OFx1MzA2M1x1MzA2Nlx1MzAwMVx1MzA1M1x1MzA2RVx1MzBDOVx1MzBBRFx1MzBFNVx1MzBFMVx1MzBGM1x1MzBDOFx1NTE4NVx1MzA2NyJ7MH0iXHUzMDkyXHU4RDg1XHUzMDQ4XHUzMDhCXHUzMEE4XHUzMEYzXHUzMEM2XHUzMEEzXHUzMEM2XHUzMEEzXHU2MkUxXHU1RjM1XHUzMDRDXHU2OTFDXHU1MUZBXHUzMDU1XHUzMDhDXHUzMDdFXHUzMDU3XHUzMDVGXHUzMDAyXHUzMDUzXHUzMDhDXHUzMDZGXHUzMDAxSkRLXHUzMDZCXHUzMDg4XHUzMDhCXHU1MjM2XHU5NjUwXHUzMDY3XHUzMDU5XHUzMDAyCi0gICAgICAgIEVsZW1lbnRBdHRyaWJ1dGVMaW1pdD1KQVhQMDAwMTAwMDI6IFx1ODk4MVx1N0QyMCJ7MH0iXHUzMDZCInsxfSJcdTMwOTJcdThEODVcdTMwNDhcdTMwOEJcdTVDNUVcdTYwMjdcdTMwNENcdTVCNThcdTU3MjhcdTMwNTdcdTMwN0VcdTMwNTlcdTMwMDIiezF9Ilx1MzA2Rlx1MzAwMUpES1x1MzA2Qlx1MzA4OFx1MzA4Qlx1NTIzNlx1OTY1MFx1MzA2N1x1MzA1OVx1MzAwMgotICAgICAgICBNYXhFbnRpdHlTaXplTGltaXQ9SkFYUDAwMDEwMDAzOiBcdTMwQThcdTMwRjNcdTMwQzZcdTMwQTNcdTMwQzZcdTMwQTMiezB9Ilx1MzA2RVx1OTU3N1x1MzA1NVx1MzA2RiJ7MX0iXHUzMDY3XHUzMDAxInszfSJcdTMwNjdcdThBMkRcdTVCOUFcdTMwNTVcdTMwOENcdTMwNUZcdTUyMzZcdTk2NTAiezJ9Ilx1MzA5Mlx1OEQ4NVx1MzA0OFx1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBUb3RhbEVudGl0eVNpemVMaW1pdD1KQVhQMDAwMTAwMDQ6IFx1MzBBOFx1MzBGM1x1MzBDNlx1MzBBM1x1MzBDNlx1MzBBM1x1MzA2RVx1N0QyRlx1N0E0RFx1MzBCNVx1MzBBNFx1MzBCQSJ7MH0iXHUzMDZGXHUzMDAxInsyfSJcdTMwNjdcdThBMkRcdTVCOUFcdTMwNTVcdTMwOENcdTMwNUZcdTUyMzZcdTk2NTAiezF9Ilx1MzA5Mlx1OEQ4NVx1MzA0OFx1MzA3RVx1MzA1N1x1MzA1Rlx1MzAwMgotICAgICAgICBNYXhYTUxOYW1lTGltaXQ9SkFYUDAwMDEwMDA1OiBcdTMwQThcdTMwRjNcdTMwQzZcdTMwQTNcdTMwQzZcdTMwQTMiezB9Ilx1MzA2RVx1OTU3N1x1MzA1NVx1MzA2RiJ7MX0iXHUzMDY3XHUzMDAxInszfSJcdTMwNjdcdThBMkRcdTVCOUFcdTMwNTVcdTMwOENcdTMwNUZcdTUyMzZcdTk2NTAiezJ9Ilx1MzA5Mlx1OEQ4NVx1MzA0OFx1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBNYXhFbGVtZW50RGVwdGhMaW1pdD1KQVhQMDAwMTAwMDY6IFx1ODk4MVx1N0QyMCJ7MH0iXHUzMDZFXHU2REYxXHUzMDU1XHUzMDZGInsxfSJcdTMwNjdcdTMwMDEiezN9Ilx1MzA2N1x1OEEyRFx1NUI5QVx1MzA1NVx1MzA4Q1x1MzA1Rlx1NTIzNlx1OTY1MCJ7Mn0iXHUzMDkyXHU4RDg1XHUzMDQ4XHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIEVudGl0eVJlcGxhY2VtZW50TGltaXQ9SkFYUDAwMDEwMDA3OiBcdTMwQThcdTMwRjNcdTMwQzZcdTMwQTNcdTMwQzZcdTMwQTNcdTUzQzJcdTcxNjdcdTMwNkVcdTU0MDhcdThBMDhcdTMwQ0VcdTMwRkNcdTMwQzlcdTY1NzBcdTMwNkYiezB9Ilx1MzA2N1x1MzAwMSJ7Mn0iXHUzMDY3XHU4QTJEXHU1QjlBXHUzMDU1XHUzMDhDXHUzMDVGXHU1MjM2XHU5NjUwInsxfSJcdTMwOTJcdThEODVcdTMwNDhcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTlcdTMwMDIKLQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MTWVzc2FnZXNfa28ucHJvcGVydGllcyBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hNTE1lc3NhZ2VzX2tvLnByb3BlcnRpZXMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGU5MGJlMzMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MTWVzc2FnZXNfa28ucHJvcGVydGllcworKysgL2Rldi9udWxsCkBAIC0xLDMwNSArMCwwIEBACi0jIFRoaXMgZmlsZSBjb250YWlucyBlcnJvciBhbmQgd2FybmluZyBtZXNzYWdlcyByZWxhdGVkIHRvIFhNTAotIyBUaGUgbWVzc2FnZXMgYXJlIGFycmFuZ2VkIGluIGtleSBhbmQgdmFsdWUgdHVwbGVzIGluIGEgTGlzdFJlc291cmNlQnVuZGxlLgotIwotIyBAdmVyc2lvbgotCi0gICAgICAgIEJhZE1lc3NhZ2VLZXkgPSBcdUJBNTRcdUMyRENcdUM5QzAgXHVEMEE0XHVDNUQwIFx1RDU3NFx1QjJGOVx1RDU1OFx1QjI5NCBcdUM2MjRcdUI5NTggXHVCQTU0XHVDMkRDXHVDOUMwXHVCOTdDIFx1Q0MzRVx1Qzc0NCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LgotICAgICAgICBGb3JtYXRGYWlsZWQgPSBcdUIyRTRcdUM3NEMgXHVCQTU0XHVDMkRDXHVDOUMwXHVDNzU4IFx1RDYxNVx1QzJERFx1Qzc0NCBcdUM5QzBcdUM4MTVcdUQ1NThcdUIyOTQgXHVDOTExIFx1QjBCNFx1QkQ4MCBcdUM2MjRcdUI5NThcdUFDMDAgXHVCQzFDXHVDMEREXHVENTg4XHVDMkI1XHVCMkM4XHVCMkU0LlxuICAKLSAgICAgICAgCi0jIERvY3VtZW50IG1lc3NhZ2VzCi0gICAgICAgIFByZW1hdHVyZUVPRj1cdUM2MDhcdUFFMzBcdUNFNTggXHVDNTRBXHVDNzQwIFx1RDMwQ1x1Qzc3Q1x1Qzc1OCBcdUIwNURcdUM3ODVcdUIyQzhcdUIyRTQuCi0jIDIuMSBXZWxsLUZvcm1lZCBYTUwgRG9jdW1lbnRzCi0gICAgICAgIFJvb3RFbGVtZW50UmVxdWlyZWQgPSBcdUM2MkNcdUJDMTRcdUI5NzggXHVENjE1XHVDMkREXHVDNzU4IFx1QkIzOFx1QzExQ1x1QzVEMFx1QjI5NCBcdUI4RThcdUQyQjggXHVDNjk0XHVDMThDXHVBQzAwIFx1RDU0NFx1QzY5NFx1RDU2OVx1QjJDOFx1QjJFNC4KLSMgMi4yIENoYXJhY3RlcnMKLQotICAgICAgICBJbnZhbGlkQ2hhckluQ0RTZWN0ID0gQ0RBVEEgXHVDMTM5XHVDMTU4XHVDNUQwXHVDMTFDIFx1QkQ4MFx1QzgwMVx1RDU2OVx1RDU1QyBYTUwgXHVCQjM4XHVDNzkwKFx1QzcyMFx1QjJDOFx1Q0Y1NFx1QjREQzogMHh7MH0pXHVBQzAwIFx1QkMxQ1x1QUNBQ1x1QjQxOFx1QzVDOFx1QzJCNVx1QjJDOFx1QjJFNC4KLSAgICAgICAgSW52YWxpZENoYXJJbkNvbnRlbnQgPSBcdUJCMzhcdUMxMUNcdUM3NTggXHVDNjk0XHVDMThDIFx1Q0Y1OFx1RDE1MFx1Q0UyMFx1QzVEMFx1QzExQyBcdUJEODBcdUM4MDFcdUQ1NjlcdUQ1NUMgWE1MIFx1QkIzOFx1Qzc5MChcdUM3MjBcdUIyQzhcdUNGNTRcdUI0REM6IDB4ezB9KVx1QUMwMCBcdUJDMUNcdUFDQUNcdUI0MThcdUM1QzhcdUMyQjVcdUIyQzhcdUIyRTQuCi0gICAgICAgIFR3b0NvbG9uc0luUU5hbWUgPSBcdUM2OTRcdUMxOEMgXHVDNzIwXHVENjE1IFx1QjYxMFx1QjI5NCBcdUMxOERcdUMxMzEgXHVDNzc0XHVCOTg0XHVDNUQwXHVDMTFDIFx1QkQ4MFx1QzgwMVx1RDU2OVx1RDU1QyBcdUI0NTBcdUJDODhcdUM5RjggJzonXHVDNzc0IFx1QkMxQ1x1QUNBQ1x1QjQxOFx1QzVDOFx1QzJCNVx1QjJDOFx1QjJFNC4KLSAgICAgICAgQ29sb25Ob3RMZWdhbFdpdGhOUyA9IFx1QjEyNFx1Qzc4NFx1QzJBNFx1RDM5OFx1Qzc3NFx1QzJBNFx1QUMwMCBcdUMwQUNcdUM2QTlcdUM3M0NcdUI4NUMgXHVDMTI0XHVDODE1XHVCNDFDIFx1QUNCRFx1QzZCMCAnJ3swfScnIFx1Qzc3NFx1Qjk4NFx1QzVEMFx1QzExQ1x1QjI5NCBcdUNGNUNcdUI4NjBcdUM3NzQgXHVENUM4XHVDNkE5XHVCNDE4XHVDOUMwIFx1QzU0QVx1QzJCNVx1QjJDOFx1QjJFNC4KLSAgICAgICAgSW52YWxpZENoYXJJbk1pc2MgPSBcdUM2OTRcdUMxOEMgXHVDRjU4XHVEMTUwXHVDRTIwIFx1QjA1RFx1QUU0Q1x1QzlDMCBcdUM3N0RcdUM3NDAgXHVENkM0IFx1QjlDOFx1RDA2Q1x1QzVDNVx1QzVEMFx1QzExQyBcdUJEODBcdUM4MDFcdUQ1NjlcdUQ1NUMgWE1MIFx1QkIzOFx1Qzc5MChcdUM3MjBcdUIyQzhcdUNGNTRcdUI0REM6IDB4ezB9KVx1QUMwMCBcdUJDMUNcdUFDQUNcdUI0MThcdUM1QzhcdUMyQjVcdUIyQzhcdUIyRTQuCi0gICAgICAgIEludmFsaWRDaGFySW5Qcm9sb2cgPSBcdUJCMzhcdUMxMUNcdUM3NTggXHVENTA0XHVCODY0XHVCODVDXHVBREY4XHVDNUQwXHVDMTFDIFx1QkQ4MFx1QzgwMVx1RDU2OVx1RDU1QyBYTUwgXHVCQjM4XHVDNzkwKFx1QzcyMFx1QjJDOFx1Q0Y1NFx1QjREQzogMHh7MH0pXHVBQzAwIFx1QkMxQ1x1QUNBQ1x1QjQxOFx1QzVDOFx1QzJCNVx1QjJDOFx1QjJFNC4KLSAgICAgICAgSW52YWxpZENoYXJJblhNTERlY2wgPSBYTUwgXHVDMTIwXHVDNUI4XHVDNUQwXHVDMTFDIFx1QkQ4MFx1QzgwMVx1RDU2OVx1RDU1QyBYTUwgXHVCQjM4XHVDNzkwKFx1QzcyMFx1QjJDOFx1Q0Y1NFx1QjREQzogMHh7MH0pXHVBQzAwIFx1QkMxQ1x1QUNBQ1x1QjQxOFx1QzVDOFx1QzJCNVx1QjJDOFx1QjJFNC4KLSMgMi40IENoYXJhY3RlciBEYXRhIGFuZCBNYXJrdXAKLSAgICAgICAgQ0RFbmRJbkNvbnRlbnQgPSBcdUJCMzhcdUM3OTAgXHVDMkRDXHVEMDAwXHVDMkE0ICJdXT4iXHVCMjk0IENEQVRBIFx1QzEzOVx1QzE1OCBcdUIwNURcdUM3NDQgXHVENDVDXHVDMkRDXHVENTU4XHVCMjk0IFx1QjM3MCBcdUMwQUNcdUM2QTlcdUI0MThcdUM5QzAgXHVDNTRBXHVCMjk0IFx1QUNCRFx1QzZCMCBcdUNGNThcdUQxNTBcdUNFMjBcdUM1RDAgXHVCMDk4XHVEMEMwXHVCMDk4XHVDOUMwIFx1QzU0QVx1QzU0NFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0jIDIuNyBDREFUQSBTZWN0aW9ucwotICAgICAgICBDRFNlY3RVbnRlcm1pbmF0ZWQgPSBDREFUQSBcdUMxMzlcdUMxNThcdUM3NDAgIl1dPiJcdUI4NUMgXHVCMDVEXHVCMDk4XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4KLSMgMi44IFByb2xvZyBhbmQgRG9jdW1lbnQgVHlwZSBEZWNsYXJhdGlvbgotICAgICAgICBYTUxEZWNsTXVzdEJlRmlyc3QgPSBYTUwgXHVDMTIwXHVDNUI4XHVDNzQwIFx1QkIzOFx1QzExQyBcdUI5RTggXHVDNTVFXHVDNUQwXHVCOUNDIFx1QjA5OFx1RDBDMFx1QjBBMCBcdUMyMTggXHVDNzg4XHVDMkI1XHVCMkM4XHVCMkU0LgotICAgICAgICBFcVJlcXVpcmVkSW5YTUxEZWNsID0gWE1MIFx1QzEyMFx1QzVCOFx1QzVEMFx1QzExQ1x1QjI5NCAiezB9IiBcdUIyRTRcdUM3NENcdUM1RDAgJycgPSAnJyBcdUJCMzhcdUM3OTBcdUFDMDAgXHVDNjQwXHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgUXVvdGVSZXF1aXJlZEluWE1MRGVjbCA9IFhNTCBcdUMxMjBcdUM1QjhcdUM1RDBcdUMxMUMgInswfSIgXHVCMkU0XHVDNzRDXHVDNUQwIFx1QzYyNFx1QjI5NCBcdUFDMTJcdUM3NDAgXHVCNTMwXHVDNjM0XHVENDVDXHVBQzAwIFx1QkQ5OVx1Qzc0MCBcdUJCMzhcdUM3OTBcdUM1RjRcdUM3NzRcdUM1QjRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBYTUxEZWNsVW50ZXJtaW5hdGVkID0gWE1MIFx1QzEyMFx1QzVCOFx1Qzc0MCAiPz4iXHVCODVDIFx1QjA1RFx1QjA5OFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIFZlcnNpb25JbmZvUmVxdWlyZWQgPSBYTUwgXHVDMTIwXHVDNUI4XHVDNUQwXHVCMjk0IFx1QkM4NFx1QzgwNFx1Qzc3NCBcdUQ1NDRcdUM2OTRcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIFNwYWNlUmVxdWlyZWRCZWZvcmVWZXJzaW9uSW5YTUxEZWNsID0gWE1MIFx1QzEyMFx1QzVCOFx1QzVEMFx1QzExQ1x1QjI5NCBcdUJDODRcdUM4MDQgXHVDNzU4XHVDMEFDIFx1QzE4RFx1QzEzMSBcdUM1NUVcdUM1RDAgXHVBQ0Y1XHVCQzMxXHVDNzc0IFx1RDU0NFx1QzY5NFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgU3BhY2VSZXF1aXJlZEJlZm9yZUVuY29kaW5nSW5YTUxEZWNsID0gWE1MIFx1QzEyMFx1QzVCOFx1QzVEMFx1QzExQ1x1QjI5NCBcdUM3NzhcdUNGNTRcdUI1MjkgXHVDNzU4XHVDMEFDIFx1QzE4RFx1QzEzMSBcdUM1NUVcdUM1RDAgXHVBQ0Y1XHVCQzMxXHVDNzc0IFx1RDU0NFx1QzY5NFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgU3BhY2VSZXF1aXJlZEJlZm9yZVN0YW5kYWxvbmUgPSBYTUwgXHVDMTIwXHVDNUI4XHVDNUQwXHVDMTFDXHVCMjk0IFx1Qzc3OFx1Q0Y1NFx1QjUyOSBcdUM3NThcdUMwQUMgXHVDMThEXHVDMTMxIFx1QzU1RVx1QzVEMCBcdUFDRjVcdUJDMzFcdUM3NzQgXHVENTQ0XHVDNjk0XHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBNYXJrdXBOb3RSZWNvZ25pemVkSW5Qcm9sb2cgPSBcdUJCMzhcdUMxMUNcdUM1RDBcdUMxMUMgXHVCOEU4XHVEMkI4IFx1QzY5NFx1QzE4QyBcdUM1NUVcdUM1RDAgXHVDNjI0XHVCMjk0IFx1QjlDOFx1RDA2Q1x1QzVDNVx1Qzc0MCBcdUM2MkNcdUJDMTRcdUI5NzggXHVENjE1XHVDMkREXHVDNzc0XHVDNUI0XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgTWFya3VwTm90UmVjb2duaXplZEluTWlzYyA9IFx1QkIzOFx1QzExQ1x1QzVEMFx1QzExQyBcdUI4RThcdUQyQjggXHVDNjk0XHVDMThDIFx1QjJFNFx1Qzc0Q1x1QzVEMCBcdUM2MjRcdUIyOTQgXHVCOUM4XHVEMDZDXHVDNUM1XHVDNzQwIFx1QzYyQ1x1QkMxNFx1Qjk3OCBcdUQ2MTVcdUMyRERcdUM3NzRcdUM1QjRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBBbHJlYWR5U2VlbkRvY3R5cGUgPSBkb2N0eXBlXHVDNzc0IFx1Qzc3NFx1QkJGOCBcdUQ0NUNcdUMyRENcdUI0MThcdUM1QzhcdUMyQjVcdUIyQzhcdUIyRTQuCi0gICAgICAgIERvY3R5cGVOb3RBbGxvd2VkID0gRE9DVFlQRVx1Qzc0MCAiaHR0cDovL2FwYWNoZS5vcmcveG1sL2ZlYXR1cmVzL2Rpc2FsbG93LWRvY3R5cGUtZGVjbCIgXHVBRTMwXHVCMkE1XHVDNzc0IHRydWVcdUI4NUMgXHVDMTI0XHVDODE1XHVCNDFDIFx1QUNCRFx1QzZCMCBcdUQ1QzhcdUM2QTlcdUI0MThcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0LgotICAgICAgICBDb250ZW50SWxsZWdhbEluUHJvbG9nID0gXHVENTA0XHVCODY0XHVCODVDXHVBREY4XHVDNUQwXHVDMTFDXHVCMjk0IFx1Q0Y1OFx1RDE1MFx1Q0UyMFx1QUMwMCBcdUQ1QzhcdUM2QTlcdUI0MThcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0LgotICAgICAgICBSZWZlcmVuY2VJbGxlZ2FsSW5Qcm9sb2cgPSBcdUQ1MDRcdUI4NjRcdUI4NUNcdUFERjhcdUM1RDBcdUMxMUNcdUIyOTQgXHVDQzM4XHVDODcwXHVBQzAwIFx1RDVDOFx1QzZBOVx1QjQxOFx1QzlDMCBcdUM1NEFcdUMyQjVcdUIyQzhcdUIyRTQuCi0jIFRyYWlsaW5nIE1pc2MKLSAgICAgICAgQ29udGVudElsbGVnYWxJblRyYWlsaW5nTWlzYz1cdUQ2QzRcdUQ1ODkgXHVDMTM5XHVDMTU4XHVDNUQwXHVDMTFDXHVCMjk0IFx1Q0Y1OFx1RDE1MFx1Q0UyMFx1QUMwMCBcdUQ1QzhcdUM2QTlcdUI0MThcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0LgotICAgICAgICBSZWZlcmVuY2VJbGxlZ2FsSW5UcmFpbGluZ01pc2M9XHVENkM0XHVENTg5IFx1QzEzOVx1QzE1OFx1QzVEMFx1QzExQ1x1QjI5NCBcdUNDMzhcdUM4NzBcdUFDMDAgXHVENUM4XHVDNkE5XHVCNDE4XHVDOUMwIFx1QzU0QVx1QzJCNVx1QjJDOFx1QjJFNC4KLSAgICAgICAgCi0jIDIuOSBTdGFuZGFsb25lIERvY3VtZW50IERlY2xhcmF0aW9uCi0gICAgICAgIFNERGVjbEludmFsaWQgPSBcdUIzQzVcdUI5QkRcdUQ2MTUgXHVCQjM4XHVDMTFDIFx1QzEyMFx1QzVCOCBcdUFDMTJcdUM3NDAgInswfSJcdUM3NzQoXHVBQzAwKSBcdUM1NDRcdUIyQ0MgInllcyIgXHVCNjEwXHVCMjk0ICJubyJcdUM1RUNcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBTRERlY2xOYW1lSW52YWxpZCA9IFhNTCBcdUMxMjBcdUM1QjhcdUM3NTggXHVCM0M1XHVCOUJEXHVENjE1IFx1Qzc3NFx1Qjk4NFx1Qzc1OCBcdUNDQTBcdUM3OTBcdUFDMDAgXHVDNzk4XHVCQUJCXHVCNDE4XHVDNUM4XHVDNzQ0IFx1QzIxOCBcdUM3ODhcdUMyQjVcdUIyQzhcdUIyRTQuCi0jIDIuMTIgTGFuZ3VhZ2UgSWRlbnRpZmljYXRpb24KLSAgICAgICAgWE1MTGFuZ0ludmFsaWQgPSB4bWw6bGFuZyBcdUMxOERcdUMxMzFcdUFDMTIgInswfSJcdUM3NDAoXHVCMjk0KSBcdUJEODBcdUM4MDFcdUQ1NjlcdUQ1NUMgXHVDNUI4XHVDNUI0IFx1QzJERFx1QkNDNFx1Qzc5MFx1Qzc4NVx1QjJDOFx1QjJFNC4KLSMgMy4gTG9naWNhbCBTdHJ1Y3R1cmVzCi0gICAgICAgIEVUYWdSZXF1aXJlZCA9IFx1QzY5NFx1QzE4QyBcdUM3MjBcdUQ2MTUgInswfSJcdUM3NDAoXHVCMjk0KSBcdUM5RERcdUM3NzQgXHVCOURFXHVCMjk0IFx1Qzg4NVx1QjhDQyBcdUQwRENcdUFERjggIjwvezB9PiIoXHVDNzNDKVx1Qjg1QyBcdUM4ODVcdUI4Q0NcdUI0MThcdUM1QjRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotIyAzLjEgU3RhcnQtVGFncywgRW5kLVRhZ3MsIGFuZCBFbXB0eS1FbGVtZW50IFRhZ3MKLSAgICAgICAgRWxlbWVudFVudGVybWluYXRlZCA9IFx1QzY5NFx1QzE4QyBcdUM3MjBcdUQ2MTUgInswfSIgXHVCMkU0XHVDNzRDXHVDNUQwXHVCMjk0IFx1QzE4RFx1QzEzMSBcdUMwQUNcdUM1OTEgIj4iIFx1QjYxMFx1QjI5NCAiLz4iXHVBQzAwIFx1QzY0MFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIEVxUmVxdWlyZWRJbkF0dHJpYnV0ZSA9IFx1QzY5NFx1QzE4QyBcdUM3MjBcdUQ2MTUgInswfSJcdUFDRkMoXHVDNjQwKSBcdUM1RjBcdUFEMDBcdUI0MUMgXHVDMThEXHVDMTMxIFx1Qzc3NFx1Qjk4NCAiezF9IiBcdUIyRTRcdUM3NENcdUM1RDBcdUIyOTQgJycgPSAnJyBcdUJCMzhcdUM3OTBcdUFDMDAgXHVDNjQwXHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgT3BlblF1b3RlRXhwZWN0ZWQgPSBcdUM2OTRcdUMxOEMgXHVDNzIwXHVENjE1ICJ7MH0iXHVBQ0ZDKFx1QzY0MCkgXHVDNUYwXHVBRDAwXHVCNDFDICJ7MX0iIFx1QzE4RFx1QzEzMVx1QzVEMFx1QjI5NCBcdUM1RUNcdUIyOTQgXHVCNTMwXHVDNjM0XHVENDVDXHVBQzAwIFx1RDU0NFx1QzY5NFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgQ2xvc2VRdW90ZUV4cGVjdGVkID0gXHVDNjk0XHVDMThDIFx1QzcyMFx1RDYxNSAiezB9Ilx1QUNGQyhcdUM2NDApIFx1QzVGMFx1QUQwMFx1QjQxQyAiezF9IiBcdUMxOERcdUMxMzFcdUM1RDBcdUIyOTQgXHVCMkVCXHVCMjk0IFx1QjUzMFx1QzYzNFx1RDQ1Q1x1QUMwMCBcdUQ1NDRcdUM2OTRcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIEF0dHJpYnV0ZU5vdFVuaXF1ZSA9ICJ7MX0iIFx1QzE4RFx1QzEzMVx1Qzc3NCAiezB9IiBcdUM2OTRcdUMxOENcdUM1RDAgXHVCMzAwXHVENTc0IFx1Qzc3NFx1QkJGOCBcdUM5QzBcdUM4MTVcdUI0MThcdUM1QzhcdUMyQjVcdUIyQzhcdUIyRTQuCi0gICAgICAgIEF0dHJpYnV0ZU5TTm90VW5pcXVlID0gInsyfSIgXHVCMTI0XHVDNzg0XHVDMkE0XHVEMzk4XHVDNzc0XHVDMkE0XHVDNUQwIFx1QkMxNFx1Qzc3OFx1QjREQ1x1QjQxQyAiezF9IiBcdUMxOERcdUMxMzFcdUM3NzQgInswfSIgXHVDNjk0XHVDMThDXHVDNUQwIFx1QjMwMFx1RDU3NCBcdUM3NzRcdUJCRjggXHVDOUMwXHVDODE1XHVCNDE4XHVDNUM4XHVDMkI1XHVCMkM4XHVCMkU0LgotICAgICAgICBFVGFnVW50ZXJtaW5hdGVkID0gXHVDNjk0XHVDMThDIFx1QzcyMFx1RDYxNSAiezB9Ilx1QzVEMCBcdUIzMDBcdUQ1NUMgXHVDODg1XHVCOENDIFx1RDBEQ1x1QURGOFx1QjI5NCAnJz4nJyBcdUFENkNcdUJEODRcdUM3OTBcdUI4NUMgXHVCMDVEXHVCMDk4XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgTWFya3VwTm90UmVjb2duaXplZEluQ29udGVudCA9IFx1QzY5NFx1QzE4QyBcdUNGNThcdUQxNTBcdUNFMjBcdUIyOTQgXHVDNjJDXHVCQzE0XHVCOTc4IFx1RDYxNVx1QzJERFx1Qzc1OCBcdUJCMzhcdUM3OTAgXHVCMzcwXHVDNzc0XHVEMTMwIFx1QjYxMFx1QjI5NCBcdUI5QzhcdUQwNkNcdUM1QzVcdUM3M0NcdUI4NUMgXHVBRDZDXHVDMTMxXHVCNDE4XHVDNUI0XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgRG9jdHlwZUlsbGVnYWxJbkNvbnRlbnQgPSBcdUNGNThcdUQxNTBcdUNFMjBcdUM1RDBcdUMxMUNcdUIyOTQgRE9DVFlQRVx1Qzc3NCBcdUQ1QzhcdUM2QTlcdUI0MThcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0LgotIyA0LjEgQ2hhcmFjdGVyIGFuZCBFbnRpdHkgUmVmZXJlbmNlcwotICAgICAgICBSZWZlcmVuY2VVbnRlcm1pbmF0ZWQgPSBcdUNDMzhcdUM4NzBcdUIyOTQgJzsnIFx1QUQ2Q1x1QkQ4NFx1Qzc5MFx1Qjg1QyBcdUM4ODVcdUI4Q0NcdUI0MThcdUM1QjRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotIyA0LjMuMiBXZWxsLUZvcm1lZCBQYXJzZWQgRW50aXRpZXMKLSAgICAgICAgUmVmZXJlbmNlTm90SW5PbmVFbnRpdHkgPSBcdUNDMzhcdUM4NzBcdUIyOTQgXHVBRDZDXHVCQjM4XHVDNzc0IFx1QkQ4NFx1QzExRFx1QjQxQyBcdUIzRDlcdUM3N0NcdUQ1NUMgXHVDNUQ0XHVEMkYwXHVEMkYwXHVDNUQwIFx1QzY0NFx1QzgwNFx1RDc4OCBcdUQzRUNcdUQ1NjhcdUI0MThcdUM1QjRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBFbGVtZW50RW50aXR5TWlzbWF0Y2ggPSAiezB9IiBcdUM2OTRcdUMxOENcdUIyOTQgXHVCM0Q5XHVDNzdDXHVENTVDIFx1QzVENFx1RDJGMFx1RDJGMFx1QzVEMFx1QzExQyBcdUMyRENcdUM3OTFcdUI0MThcdUFDRTAgXHVCMDVEXHVCMDk4XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgTWFya3VwRW50aXR5TWlzbWF0Y2g9WE1MIFx1QkIzOFx1QzExQyBcdUFENkNcdUM4NzBcdUIyOTQgXHVCM0Q5XHVDNzdDXHVENTVDIFx1QzVENFx1RDJGMFx1RDJGMFx1QzVEMFx1QzExQyBcdUMyRENcdUM3OTFcdUI0MThcdUFDRTAgXHVCMDVEXHVCMDk4XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgCi0jIE1lc3NhZ2VzIGNvbW1vbiB0byBEb2N1bWVudCBhbmQgRFRECi0jIDIuMiBDaGFyYWN0ZXJzCi0gICAgICAgIEludmFsaWRDaGFySW5BdHRWYWx1ZSA9ICJ7MX0iIFx1QzE4RFx1QzEzMVx1Qzc1OCBcdUFDMTJcdUM1RDBcdUMxMUMgXHVCRDgwXHVDODAxXHVENTY5XHVENTVDIFhNTCBcdUJCMzhcdUM3OTAoXHVDNzIwXHVCMkM4XHVDRjU0XHVCNERDOiAweHsyfSlcdUFDMDAgXHVCQzFDXHVBQ0FDXHVCNDE4XHVDNUM4XHVDNzNDXHVCQTcwIFx1QzY5NFx1QzE4Q1x1QUMwMCAiezB9Ilx1Qzc4NVx1QjJDOFx1QjJFNC4KLSAgICAgICAgSW52YWxpZENoYXJJbkNvbW1lbnQgPSBcdUM4RkNcdUMxMURcdUM1RDBcdUMxMUMgXHVCRDgwXHVDODAxXHVENTY5XHVENTVDIFhNTCBcdUJCMzhcdUM3OTAoXHVDNzIwXHVCMkM4XHVDRjU0XHVCNERDOiAweHswfSlcdUFDMDAgXHVCQzFDXHVBQ0FDXHVCNDE4XHVDNUM4XHVDMkI1XHVCMkM4XHVCMkU0LgotICAgICAgICBJbnZhbGlkQ2hhckluUEkgPSBcdUNDOThcdUI5QUMgXHVCQTg1XHVCODM5XHVDNUQwXHVDMTFDIFx1QkQ4MFx1QzgwMVx1RDU2OVx1RDU1QyBYTUwgXHVCQjM4XHVDNzkwKFx1QzcyMFx1QjJDOFx1Q0Y1NFx1QjREQzogMHh7MH0pXHVBQzAwIFx1QkMxQ1x1QUNBQ1x1QjQxOFx1QzVDOFx1QzJCNVx1QjJDOFx1QjJFNC4KLSAgICAgICAgSW52YWxpZENoYXJJbkludGVybmFsU3Vic2V0ID0gRFREXHVDNzU4IFx1QjBCNFx1QkQ4MCBcdUJEODBcdUJEODQgXHVDOUQxXHVENTY5XHVDNUQwXHVDMTFDIFx1QkQ4MFx1QzgwMVx1RDU2OVx1RDU1QyBYTUwgXHVCQjM4XHVDNzkwKFx1QzcyMFx1QjJDOFx1Q0Y1NFx1QjREQzogMHh7MH0pXHVBQzAwIFx1QkMxQ1x1QUNBQ1x1QjQxOFx1QzVDOFx1QzJCNVx1QjJDOFx1QjJFNC4KLSAgICAgICAgSW52YWxpZENoYXJJblRleHREZWNsID0gXHVEMTREXHVDMkE0XHVEMkI4IFx1QzEyMFx1QzVCOFx1QzVEMFx1QzExQyBcdUJEODBcdUM4MDFcdUQ1NjlcdUQ1NUMgWE1MIFx1QkIzOFx1Qzc5MChcdUM3MjBcdUIyQzhcdUNGNTRcdUI0REM6IDB4ezB9KVx1QUMwMCBcdUJDMUNcdUFDQUNcdUI0MThcdUM1QzhcdUMyQjVcdUIyQzhcdUIyRTQuCi0jIDIuMyBDb21tb24gU3ludGFjdGljIENvbnN0cnVjdHMKLSAgICAgICAgUXVvdGVSZXF1aXJlZEluQXR0VmFsdWUgPSAiezF9IiBcdUMxOERcdUMxMzFcdUM3NTggXHVBQzEyXHVDNzQwIFx1Qzc5MVx1Qzc0MCBcdUI1MzBcdUM2MzRcdUQ0NUMgXHVCNjEwXHVCMjk0IFx1RDA3MCBcdUI1MzBcdUM2MzRcdUQ0NUMgXHVCQjM4XHVDNzkwXHVCODVDIFx1QzJEQ1x1Qzc5MVx1RDU3NFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIExlc3N0aGFuSW5BdHRWYWx1ZSA9IFx1QzY5NFx1QzE4QyBcdUM3MjBcdUQ2MTUgInswfSJcdUFDRkMoXHVDNjQwKSBcdUM1RjBcdUFEMDBcdUI0MUMgInsxfSIgXHVDMThEXHVDMTMxXHVDNzU4IFx1QUMxMlx1QzVEMFx1QjI5NCAnJzwnJyBcdUJCMzhcdUM3OTBcdUFDMDAgXHVEM0VDXHVENTY4XHVCNDE4XHVDOUMwIFx1QzU0QVx1QzU0NFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIEF0dHJpYnV0ZVZhbHVlVW50ZXJtaW5hdGVkID0gInsxfSIgXHVDMThEXHVDMTMxXHVDNzU4IFx1QUMxMlx1Qzc0MCBcdUM5RERcdUM3NzQgXHVCOURFXHVCMjk0IFx1QjUzMFx1QzYzNFx1RDQ1QyBcdUJCMzhcdUM3OTBcdUI4NUMgXHVCMDVEXHVCMDk4XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4KLSMgMi41IENvbW1lbnRzCi0gICAgICAgIEludmFsaWRDb21tZW50U3RhcnQgPSBcdUM4RkNcdUMxMURcdUM3NDAgIjwhLS0iXHVCODVDIFx1QzJEQ1x1Qzc5MVx1RDU3NFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIERhc2hEYXNoSW5Db21tZW50ID0gXHVDOEZDXHVDMTFEXHVDNUQwXHVDMTFDXHVCMjk0ICItLSIgXHVCQjM4XHVDNzkwXHVDNUY0XHVDNzc0IFx1RDVDOFx1QzZBOVx1QjQxOFx1QzlDMCBcdUM1NEFcdUMyQjVcdUIyQzhcdUIyRTQuCi0gICAgICAgIENvbW1lbnRVbnRlcm1pbmF0ZWQgPSBcdUM4RkNcdUMxMURcdUM3NDAgIi0tPiJcdUI4NUMgXHVCMDVEXHVCMDk4XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgQ09NTUVOVF9OT1RfSU5fT05FX0VOVElUWSA9IFx1QzhGQ1x1QzExRFx1Qzc3NCBcdUIzRDlcdUM3N0NcdUQ1NUMgXHVDNUQ0XHVEMkYwXHVEMkYwIFx1QzU0OFx1QzVEMCBcdUM3ODhcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0LgotIyAyLjYgUHJvY2Vzc2luZyBJbnN0cnVjdGlvbnMKLSAgICAgICAgUElUYXJnZXRSZXF1aXJlZCA9IFx1Q0M5OFx1QjlBQyBcdUJBODVcdUI4MzlcdUM3NDAgXHVCMzAwXHVDMEMxIFx1Qzc3NFx1Qjk4NFx1QzczQ1x1Qjg1QyBcdUMyRENcdUM3OTFcdUQ1NzRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBTcGFjZVJlcXVpcmVkSW5QSSA9IFx1Q0M5OFx1QjlBQyBcdUJBODVcdUI4MzkgXHVCMzAwXHVDMEMxXHVBQ0ZDIFx1QjM3MFx1Qzc3NFx1RDEzMCBcdUMwQUNcdUM3NzRcdUM1RDBcdUIyOTQgXHVBQ0Y1XHVCQzMxXHVDNzc0IFx1RDU0NFx1QzY5NFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgUElVbnRlcm1pbmF0ZWQgPSBcdUNDOThcdUI5QUMgXHVCQTg1XHVCODM5XHVDNzQwICI/PiJcdUI4NUMgXHVCMDVEXHVCMDk4XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgUmVzZXJ2ZWRQSVRhcmdldCA9ICJbeFhdW21NXVtsTF0iXHVBQ0ZDIFx1Qzc3Q1x1Q0U1OFx1RDU1OFx1QjI5NCBcdUNDOThcdUI5QUMgXHVCQTg1XHVCODM5IFx1QjMwMFx1QzBDMVx1Qzc0MCBcdUQ1QzhcdUM2QTlcdUI0MThcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0LgotICAgICAgICBQSV9OT1RfSU5fT05FX0VOVElUWSA9IFx1Q0M5OFx1QjlBQyBcdUJBODVcdUI4MzlcdUM3NzQgXHVCM0Q5XHVDNzdDXHVENTVDIFx1QzVENFx1RDJGMFx1RDJGMCBcdUM1NDhcdUM1RDAgXHVDNzg4XHVDOUMwIFx1QzU0QVx1QzJCNVx1QjJDOFx1QjJFNC4KLSMgMi44IFByb2xvZyBhbmQgRG9jdW1lbnQgVHlwZSBEZWNsYXJhdGlvbgotICAgICAgICBWZXJzaW9uSW5mb0ludmFsaWQgPSAiezB9Ilx1Qzc0MChcdUIyOTQpIFx1QkQ4MFx1QzgwMVx1RDU2OVx1RDU1QyBcdUJDODRcdUM4MDRcdUM3ODVcdUIyQzhcdUIyRTQuCi0gICAgICAgIFZlcnNpb25Ob3RTdXBwb3J0ZWQgPSBYTUwgXHVCQzg0XHVDODA0ICJ7MH0iXHVDNzQwKFx1QjI5NCkgXHVDOUMwXHVDNkQwXHVCNDE4XHVDOUMwIFx1QzU0QVx1QzJCNVx1QjJDOFx1QjJFNC4gWE1MIDEuMFx1QjlDQyBcdUM5QzBcdUM2RDBcdUI0MjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIFZlcnNpb25Ob3RTdXBwb3J0ZWQxMSA9IFhNTCBcdUJDODRcdUM4MDQgInswfSJcdUM3NDAoXHVCMjk0KSBcdUM5QzBcdUM2RDBcdUI0MThcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0LiBYTUwgMS4wIFx1QkMwRiBYTUwgMS4xXHVCOUNDIFx1QzlDMFx1QzZEMFx1QjQyOVx1QjJDOFx1QjJFNC4KLSAgICAgICAgVmVyc2lvbk1pc21hdGNoPSBcdUQ1NThcdUIwOThcdUM3NTggXHVDNUQ0XHVEMkYwXHVEMkYwXHVDNUQwXHVCMjk0IFx1Qzc3NFx1RDZDNCBcdUJDODRcdUM4MDRcdUM3NTggXHVCMkU0XHVCOTc4IFx1QzVENFx1RDJGMFx1RDJGMFx1QUMwMCBcdUQzRUNcdUQ1NjhcdUI0MjAgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4KLSMgNC4xIENoYXJhY3RlciBhbmQgRW50aXR5IFJlZmVyZW5jZXMKLSAgICAgICAgRGlnaXRSZXF1aXJlZEluQ2hhclJlZiA9IFx1QkIzOFx1Qzc5MCBcdUNDMzhcdUM4NzBcdUM1RDBcdUMxMUNcdUIyOTQgIiYjIiBcdUJDMTRcdUI4NUMgXHVCMkU0XHVDNzRDXHVDNUQwIFx1QzJFRFx1QzlDNFx1QzIxOCBcdUQ0NUNcdUQ2MDRcdUM3NzQgXHVDNjQwXHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgSGV4ZGlnaXRSZXF1aXJlZEluQ2hhclJlZiA9IFx1QkIzOFx1Qzc5MCBcdUNDMzhcdUM4NzBcdUM1RDBcdUMxMUNcdUIyOTQgIiYjeCIgXHVCQzE0XHVCODVDIFx1QjJFNFx1Qzc0Q1x1QzVEMCAxNlx1QzlDNFx1QzIxOCBcdUQ0NUNcdUQ2MDRcdUM3NzQgXHVDNjQwXHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgU2VtaWNvbG9uUmVxdWlyZWRJbkNoYXJSZWYgPSBcdUJCMzhcdUM3OTAgXHVDQzM4XHVDODcwXHVCMjk0ICc7JyBcdUFENkNcdUJEODRcdUM3OTBcdUI4NUMgXHVCMDVEXHVCMDk4XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgSW52YWxpZENoYXJSZWYgPSBcdUJCMzhcdUM3OTAgXHVDQzM4XHVDODcwICImI3swfSJcdUM3NDAoXHVCMjk0KSBcdUJEODBcdUM4MDFcdUQ1NjlcdUQ1NUMgWE1MIFx1QkIzOFx1Qzc5MFx1Qzc4NVx1QjJDOFx1QjJFNC4KLSAgICAgICAgTmFtZVJlcXVpcmVkSW5SZWZlcmVuY2UgPSBcdUM1RDRcdUQyRjBcdUQyRjAgXHVDQzM4XHVDODcwXHVDNUQwXHVDMTFDXHVCMjk0ICcmJyBcdUJDMTRcdUI4NUMgXHVCMkU0XHVDNzRDXHVDNUQwIFx1QzVENFx1RDJGMFx1RDJGMCBcdUM3NzRcdUI5ODRcdUM3NzQgXHVDNjQwXHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgU2VtaWNvbG9uUmVxdWlyZWRJblJlZmVyZW5jZSA9ICJ7MH0iIFx1QzVENFx1RDJGMFx1RDJGMFx1QzVEMCBcdUIzMDBcdUQ1NUMgXHVDQzM4XHVDODcwXHVCMjk0ICcnOycnIFx1QUQ2Q1x1QkQ4NFx1Qzc5MFx1Qjg1QyBcdUIwNURcdUIwOThcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotIyA0LjMuMSBUaGUgVGV4dCBEZWNsYXJhdGlvbgotICAgICAgICBUZXh0RGVjbE11c3RCZUZpcnN0ID0gXHVEMTREXHVDMkE0XHVEMkI4IFx1QzEyMFx1QzVCOFx1Qzc0MCBcdUFENkNcdUJCMzhcdUM3NzQgXHVCRDg0XHVDMTFEXHVCNDFDIFx1QzY3OFx1QkQ4MCBcdUM1RDRcdUQyRjBcdUQyRjAgXHVCOUU4IFx1QzU1RVx1QzVEMFx1QjlDQyBcdUIwOThcdUQwQzBcdUIwQTAgXHVDMjE4IFx1Qzc4OFx1QzJCNVx1QjJDOFx1QjJFNC4KLSAgICAgICAgRXFSZXF1aXJlZEluVGV4dERlY2wgPSBcdUQxNERcdUMyQTRcdUQyQjggXHVDMTIwXHVDNUI4XHVDNUQwXHVDMTFDXHVCMjk0ICJ7MH0iIFx1QjJFNFx1Qzc0Q1x1QzVEMCAnJyA9ICcnIFx1QkIzOFx1Qzc5MFx1QUMwMCBcdUM2NDBcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBRdW90ZVJlcXVpcmVkSW5UZXh0RGVjbCA9IFx1RDE0RFx1QzJBNFx1RDJCOCBcdUMxMjBcdUM1QjhcdUM1RDBcdUMxMUMgInswfSIgXHVCMkU0XHVDNzRDXHVDNUQwIFx1QzYyNFx1QjI5NCBcdUFDMTJcdUM3NDAgXHVCNTMwXHVDNjM0XHVENDVDXHVBQzAwIFx1QkQ5OVx1Qzc0MCBcdUJCMzhcdUM3OTBcdUM1RjRcdUM3NzRcdUM1QjRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBDbG9zZVF1b3RlTWlzc2luZ0luVGV4dERlY2wgPSBcdUQxNERcdUMyQTRcdUQyQjggXHVDMTIwXHVDNUI4XHVDNUQwXHVDMTFDICJ7MH0iIFx1QjJFNFx1Qzc0Q1x1QzVEMCBcdUM2MjRcdUIyOTQgXHVBQzEyXHVDNzU4IFx1QjJFQlx1QjI5NCBcdUI1MzBcdUM2MzRcdUQ0NUNcdUFDMDAgXHVCMjA0XHVCNzdEXHVCNDE4XHVDNUM4XHVDMkI1XHVCMkM4XHVCMkU0LgotICAgICAgICBTcGFjZVJlcXVpcmVkQmVmb3JlVmVyc2lvbkluVGV4dERlY2wgPSBcdUQxNERcdUMyQTRcdUQyQjggXHVDMTIwXHVDNUI4XHVDNzQwIFx1QkM4NFx1QzgwNCBcdUM3NThcdUMwQUMgXHVDMThEXHVDMTMxIFx1QzU1RVx1QzVEMCBcdUFDRjVcdUJDMzFcdUM3NzQgXHVENTQ0XHVDNjk0XHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBTcGFjZVJlcXVpcmVkQmVmb3JlRW5jb2RpbmdJblRleHREZWNsID0gXHVEMTREXHVDMkE0XHVEMkI4IFx1QzEyMFx1QzVCOFx1Qzc0MCBcdUM3NzhcdUNGNTRcdUI1MjkgXHVDNzU4XHVDMEFDIFx1QzE4RFx1QzEzMSBcdUM1NUVcdUM1RDAgXHVBQ0Y1XHVCQzMxXHVDNzc0IFx1RDU0NFx1QzY5NFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgVGV4dERlY2xVbnRlcm1pbmF0ZWQgPSBcdUQxNERcdUMyQTRcdUQyQjggXHVDMTIwXHVDNUI4XHVDNzQwICI/PiJcdUI4NUMgXHVCMDVEXHVCMDk4XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgRW5jb2RpbmdEZWNsUmVxdWlyZWQgPSBcdUQxNERcdUMyQTRcdUQyQjggXHVDMTIwXHVDNUI4XHVDNUQwXHVCMjk0IFx1Qzc3OFx1Q0Y1NFx1QjUyOSBcdUMxMjBcdUM1QjhcdUM3NzQgXHVENTQ0XHVDNjk0XHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBOb01vcmVQc2V1ZG9BdHRyaWJ1dGVzID0gXHVDNzU4XHVDMEFDIFx1QzE4RFx1QzEzMVx1Qzc0MCBcdUIzNTQgXHVDNzc0XHVDMEMxIFx1RDVDOFx1QzZBOVx1QjQxOFx1QzlDMCBcdUM1NEFcdUMyQjVcdUIyQzhcdUIyRTQuCi0gICAgICAgIE1vcmVQc2V1ZG9BdHRyaWJ1dGVzID0gXHVDNzU4XHVDMEFDIFx1QzE4RFx1QzEzMVx1Qzc3NCBcdUIzNTQgXHVENTQ0XHVDNjk0XHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBQc2V1ZG9BdHRyTmFtZUV4cGVjdGVkID0gXHVDNzU4XHVDMEFDIFx1QzE4RFx1QzEzMSBcdUM3NzRcdUI5ODRcdUM3NzQgXHVENTQ0XHVDNjk0XHVENTY5XHVCMkM4XHVCMkU0LiAKLSMgNC4zLjIgV2VsbC1Gb3JtZWQgUGFyc2VkIEVudGl0aWVzCi0gICAgICAgIENvbW1lbnROb3RJbk9uZUVudGl0eSA9IFx1QzhGQ1x1QzExRFx1Qzc0MCBcdUFENkNcdUJCMzhcdUM3NzQgXHVCRDg0XHVDMTFEXHVCNDFDIFx1QjNEOVx1Qzc3Q1x1RDU1QyBcdUM1RDRcdUQyRjBcdUQyRjBcdUM1RDAgXHVDNjQ0XHVDODA0XHVENzg4IFx1RDNFQ1x1RDU2OFx1QjQxOFx1QzVCNFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIFBJTm90SW5PbmVFbnRpdHkgPSBcdUNDOThcdUI5QUMgXHVCQTg1XHVCODM5XHVDNzQwIFx1QUQ2Q1x1QkIzOFx1Qzc3NCBcdUJEODRcdUMxMURcdUI0MUMgXHVCM0Q5XHVDNzdDXHVENTVDIFx1QzVENFx1RDJGMFx1RDJGMFx1QzVEMCBcdUM2NDRcdUM4MDRcdUQ3ODggXHVEM0VDXHVENTY4XHVCNDE4XHVDNUI0XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4KLSMgNC4zLjMgQ2hhcmFjdGVyIEVuY29kaW5nIGluIEVudGl0aWVzCi0gICAgICAgIEVuY29kaW5nRGVjbEludmFsaWQgPSAiezB9Ilx1Qzc0MChcdUIyOTQpIFx1QkQ4MFx1QzgwMVx1RDU2OVx1RDU1QyBcdUM3NzhcdUNGNTRcdUI1MjkgXHVDNzc0XHVCOTg0XHVDNzg1XHVCMkM4XHVCMkU0LgotICAgICAgICBFbmNvZGluZ0J5dGVPcmRlclVuc3VwcG9ydGVkID0gInswfSIgXHVDNzc4XHVDRjU0XHVCNTI5XHVDNUQwIFx1QjMwMFx1RDU3NCBcdUM4MUNcdUFDRjVcdUI0MUMgXHVCQzE0XHVDNzc0XHVEMkI4IFx1QzIxQ1x1QzExQ1x1QjI5NCBcdUM5QzBcdUM2RDBcdUI0MThcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0LgotICAgICAgICBJbnZhbGlkQnl0ZSA9IHswfVx1Qzc0MChcdUIyOTQpIHsxfVx1QkMxNFx1Qzc3NFx1RDJCOCBVVEYtOCBcdUMyRENcdUQwMDBcdUMyQTRcdUM1RDAgXHVCMzAwXHVENTc0IFx1QkQ4MFx1QzgwMVx1RDU2OVx1RDU1QyBcdUJDMTRcdUM3NzRcdUQyQjhcdUM3ODVcdUIyQzhcdUIyRTQuCi0gICAgICAgIEV4cGVjdGVkQnl0ZSA9IHsxfVx1QkMxNFx1Qzc3NFx1RDJCOCBVVEYtOCBcdUMyRENcdUQwMDBcdUMyQTRcdUM1RDAgXHVENTQ0XHVDNjk0XHVENTVDIFx1QkMxNFx1Qzc3NFx1RDJCOFx1QjI5NCB7MH1cdUM3ODVcdUIyQzhcdUIyRTQuICAKLSAgICAgICAgSW52YWxpZEhpZ2hTdXJyb2dhdGUgPSBVVEYtOCBcdUMyRENcdUQwMDBcdUMyQTRcdUM3NTggXHVCMTkyXHVDNzQwIFx1QjMwMFx1QjlBQyBcdUJFNDRcdUQyQjhcdUIyOTQgMHgxMFx1Qzc0NCBcdUNEMDhcdUFDRkNcdUQ1NThcdUM5QzAgXHVDNTRBXHVDNTQ0XHVDNTdDIFx1RDU1OFx1QzlDMFx1QjlDQyAweHswfVx1Qzc3NChcdUFDMDApIFx1QkMxQ1x1QUNBQ1x1QjQxOFx1QzVDOFx1QzJCNVx1QjJDOFx1QjJFNC4KLSAgICAgICAgT3BlcmF0aW9uTm90U3VwcG9ydGVkID0gezF9IFx1Qzc3RFx1QUUzMCBcdUQ1MDRcdUI4NUNcdUFERjhcdUI3QThcdUM3NDAgInswfSIgXHVDNzkxXHVDNUM1XHVDNzQ0IFx1QzlDMFx1QzZEMFx1RDU1OFx1QzlDMCBcdUM1NEFcdUMyQjVcdUIyQzhcdUIyRTQuCi0gICAgICAgIEludmFsaWRBU0NJSSA9IFx1QkMxNFx1Qzc3NFx1RDJCOCAiezB9Ilx1Qzc0MChcdUIyOTQpICg3XHVCRTQ0XHVEMkI4KSBBU0NJSSBcdUJCMzhcdUM3OTAgXHVDOUQxXHVENTY5XHVDNUQwIFx1QzE4RFx1RDU1OFx1QzlDMCBcdUM1NEFcdUMyQjVcdUIyQzhcdUIyRTQuCi0gICAgICAgIENoYXJDb252ZXJzaW9uRmFpbHVyZSA9IFx1RDJCOVx1QzgxNSBcdUM3NzhcdUNGNTRcdUI1MjkgXHVENjE1XHVDMkREXHVDNzc0XHVDNUI0XHVDNTdDIFx1RDU1OFx1QjI5NCBcdUFDODNcdUM3M0NcdUI4NUMgXHVENjU1XHVDNzc4XHVCNDFDIFx1QzVENFx1RDJGMFx1RDJGMFx1QzVEMFx1QjI5NCBcdUQ1NzRcdUIyRjkgXHVDNzc4XHVDRjU0XHVCNTI5XHVDNUQwIFx1QkQ4MFx1QzgwMVx1RDU2OVx1RDU1QyBcdUMyRENcdUQwMDBcdUMyQTRcdUFDMDAgXHVEM0VDXHVENTY4XHVCNDE4XHVDOUMwIFx1QzU0QVx1QzU0NFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIAotIyBEVEQgTWVzc2FnZXMKLSMgMi4yIENoYXJhY3RlcnMKLSAgICAgICAgSW52YWxpZENoYXJJbkVudGl0eVZhbHVlID0gXHVCOUFDXHVEMTMwXHVCN0Y0IFx1QzVENFx1RDJGMFx1RDJGMCBcdUFDMTJcdUM1RDBcdUMxMUMgXHVCRDgwXHVDODAxXHVENTY5XHVENTVDIFhNTCBcdUJCMzhcdUM3OTAoXHVDNzIwXHVCMkM4XHVDRjU0XHVCNERDOiAweHswfSlcdUFDMDAgXHVCQzFDXHVBQ0FDXHVCNDE4XHVDNUM4XHVDMkI1XHVCMkM4XHVCMkU0LgotICAgICAgICBJbnZhbGlkQ2hhckluRXh0ZXJuYWxTdWJzZXQgPSBEVERcdUM3NTggXHVDNjc4XHVCRDgwIFx1QkQ4MFx1QkQ4NCBcdUM5RDFcdUQ1NjlcdUM1RDBcdUMxMUMgXHVCRDgwXHVDODAxXHVENTY5XHVENTVDIFhNTCBcdUJCMzhcdUM3OTAoXHVDNzIwXHVCMkM4XHVDRjU0XHVCNERDOiAweHswfSlcdUFDMDAgXHVCQzFDXHVBQ0FDXHVCNDE4XHVDNUM4XHVDMkI1XHVCMkM4XHVCMkU0LgotICAgICAgICBJbnZhbGlkQ2hhckluSWdub3JlU2VjdCA9IFx1QzgxQ1x1QzY3OFx1QjQxQyBcdUM4NzBcdUFDNzRcdUJEODAgXHVDMTM5XHVDMTU4XHVDNUQwXHVDMTFDIFx1QkQ4MFx1QzgwMVx1RDU2OVx1RDU1QyBYTUwgXHVCQjM4XHVDNzkwKFx1QzcyMFx1QjJDOFx1Q0Y1NFx1QjREQzogMHh7MH0pXHVBQzAwIFx1QkMxQ1x1QUNBQ1x1QjQxOFx1QzVDOFx1QzJCNVx1QjJDOFx1QjJFNC4KLSAgICAgICAgSW52YWxpZENoYXJJblB1YmxpY0lEID0gXHVBQ0Y1XHVDNkE5IFx1QzJERFx1QkNDNFx1Qzc5MFx1QzVEMCBcdUJEODBcdUM4MDFcdUQ1NjlcdUQ1NUMgWE1MIFx1QkIzOFx1Qzc5MChcdUM3MjBcdUIyQzhcdUNGNTRcdUI0REM6IDB4ezB9KVx1QUMwMCBcdUJDMUNcdUFDQUNcdUI0MThcdUM1QzhcdUMyQjVcdUIyQzhcdUIyRTQuCi0gICAgICAgIEludmFsaWRDaGFySW5TeXN0ZW1JRCA9IFx1QzJEQ1x1QzJBNFx1RDE1QyBcdUMyRERcdUJDQzRcdUM3OTBcdUM1RDAgXHVCRDgwXHVDODAxXHVENTY5XHVENTVDIFhNTCBcdUJCMzhcdUM3OTAoXHVDNzIwXHVCMkM4XHVDRjU0XHVCNERDOiAweHswfSlcdUFDMDAgXHVCQzFDXHVBQ0FDXHVCNDE4XHVDNUM4XHVDMkI1XHVCMkM4XHVCMkU0LgotIyAyLjMgQ29tbW9uIFN5bnRhY3RpYyBDb25zdHJ1Y3RzCi0gICAgICAgIFNwYWNlUmVxdWlyZWRBZnRlclNZU1RFTSA9IERPQ1RZUEUgXHVDMTIwXHVDNUI4XHVDNUQwXHVCMjk0IFNZU1RFTSBcdUQwQTRcdUM2Q0NcdUI0REMgXHVCMkU0XHVDNzRDXHVDNUQwIFx1QUNGNVx1QkMzMVx1Qzc3NCBcdUQ1NDRcdUM2OTRcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIFF1b3RlUmVxdWlyZWRJblN5c3RlbUlEID0gXHVDMkRDXHVDMkE0XHVEMTVDIFx1QzJERFx1QkNDNFx1Qzc5MFx1QjI5NCBcdUM3OTFcdUM3NDAgXHVCNTMwXHVDNjM0XHVENDVDIFx1QjYxMFx1QjI5NCBcdUQwNzAgXHVCNTMwXHVDNjM0XHVENDVDIFx1QkIzOFx1Qzc5MFx1Qjg1QyBcdUMyRENcdUM3OTFcdUQ1NzRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBTeXN0ZW1JRFVudGVybWluYXRlZCA9IFx1QzJEQ1x1QzJBNFx1RDE1QyBcdUMyRERcdUJDQzRcdUM3OTBcdUIyOTQgXHVDOUREXHVDNzc0IFx1QjlERVx1QjI5NCBcdUI1MzBcdUM2MzRcdUQ0NUMgXHVCQjM4XHVDNzkwXHVCODVDIFx1QjA1RFx1QjA5OFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIFNwYWNlUmVxdWlyZWRBZnRlclBVQkxJQyA9IERPQ1RZUEUgXHVDMTIwXHVDNUI4XHVDNUQwXHVCMjk0IFBVQkxJQyBcdUQwQTRcdUM2Q0NcdUI0REMgXHVCMkU0XHVDNzRDXHVDNUQwIFx1QUNGNVx1QkMzMVx1Qzc3NCBcdUQ1NDRcdUM2OTRcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIFF1b3RlUmVxdWlyZWRJblB1YmxpY0lEID0gXHVBQ0Y1XHVDNkE5IFx1QzJERFx1QkNDNFx1Qzc5MFx1QjI5NCBcdUM3OTFcdUM3NDAgXHVCNTMwXHVDNjM0XHVENDVDIFx1QjYxMFx1QjI5NCBcdUQwNzAgXHVCNTMwXHVDNjM0XHVENDVDIFx1QkIzOFx1Qzc5MFx1Qjg1QyBcdUMyRENcdUM3OTFcdUQ1NzRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBQdWJsaWNJRFVudGVybWluYXRlZCA9IFx1QUNGNVx1QzZBOSBcdUMyRERcdUJDQzRcdUM3OTBcdUIyOTQgXHVDOUREXHVDNzc0IFx1QjlERVx1QjI5NCBcdUI1MzBcdUM2MzRcdUQ0NUMgXHVCQjM4XHVDNzkwXHVCODVDIFx1QjA1RFx1QjA5OFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIFB1YmlkQ2hhcklsbGVnYWwgPSBcdUFDRjVcdUM2QTkgXHVDMkREXHVCQ0M0XHVDNzkwXHVDNUQwXHVCMjk0IFx1QkIzOFx1Qzc5MChcdUM3MjBcdUIyQzhcdUNGNTRcdUI0REM6IDB4ezB9KVx1QUMwMCBcdUQ1QzhcdUM2QTlcdUI0MThcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0LgotICAgICAgICBTcGFjZVJlcXVpcmVkQmV0d2VlblB1YmxpY0FuZFN5c3RlbSA9IHB1YmxpY0lkXHVDNjQwIHN5c3RlbUlkIFx1QzBBQ1x1Qzc3NFx1QzVEMFx1QjI5NCBcdUFDRjVcdUJDMzFcdUM3NzQgXHVENTQ0XHVDNjk0XHVENTY5XHVCMkM4XHVCMkU0LgotIyAyLjggUHJvbG9nIGFuZCBEb2N1bWVudCBUeXBlIERlY2xhcmF0aW9uCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfUk9PVF9FTEVNRU5UX1RZUEVfSU5fRE9DVFlQRURFQ0wgPSBcdUJCMzhcdUMxMUMgXHVDNzIwXHVENjE1IFx1QzEyMFx1QzVCOFx1QzVEMFx1QzExQ1x1QjI5NCAiPCFET0NUWVBFIiBcdUIyRTRcdUM3NENcdUM1RDAgXHVBQ0Y1XHVCQzMxXHVDNzc0IFx1RDU0NFx1QzY5NFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgTVNHX1JPT1RfRUxFTUVOVF9UWVBFX1JFUVVJUkVEID0gXHVCQjM4XHVDMTFDIFx1QzcyMFx1RDYxNSBcdUMxMjBcdUM1QjhcdUM1RDBcdUMxMUNcdUIyOTQgIjwhRE9DVFlQRSIgXHVCMkU0XHVDNzRDXHVDNUQwIFx1QjhFOFx1RDJCOCBcdUM2OTRcdUMxOEMgXHVDNzIwXHVENjE1XHVDNzc0IFx1QjA5OFx1RDBDMFx1QjA5OFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIERvY3R5cGVkZWNsVW50ZXJtaW5hdGVkID0gXHVCOEU4XHVEMkI4IFx1QzY5NFx1QzE4QyBcdUM3MjBcdUQ2MTUgInswfSJcdUM1RDAgXHVCMzAwXHVENTVDIFx1QkIzOFx1QzExQyBcdUM3MjBcdUQ2MTUgXHVDMTIwXHVDNUI4XHVDNzQwICcnPicnXHVCODVDIFx1QjA1RFx1QjA5OFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIERvY3R5cGVkZWNsTm90Q2xvc2VkID0gXHVCOEU4XHVEMkI4IFx1QzY5NFx1QzE4QyBcdUM3MjBcdUQ2MTUgInswfSJcdUM1RDAgXHVCMzAwXHVENTVDIFx1QkIzOFx1QzExQyBcdUM3MjBcdUQ2MTUgXHVDMTIwXHVDNUI4XHVDNzQwICcnXScnXHVCODVDIFx1QjA1RFx1QjA5OFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIFBFUmVmZXJlbmNlV2l0aGluTWFya3VwID0gXHVCOUU0XHVBQzFDXHVCQ0MwXHVDMjE4IFx1QzVENFx1RDJGMFx1RDJGMCBcdUNDMzhcdUM4NzAgIiV7MH07Ilx1Qzc0MCBEVERcdUM3NTggXHVCMEI0XHVCRDgwIFx1QkQ4MFx1QkQ4NCBcdUM5RDFcdUQ1NjlcdUM1RDAgXHVDNzg4XHVCMjk0IFx1QjlDOFx1RDA2Q1x1QzVDNSBcdUM1NDhcdUM1RDAgXHVENDVDXHVDMkRDXHVCNDIwIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuCi0gICAgICAgIE1TR19NQVJLVVBfTk9UX1JFQ09HTklaRURfSU5fRFREID0gXHVCQjM4XHVDMTFDIFx1QzcyMFx1RDYxNSBcdUMxMjBcdUM1QjhcdUM3NDQgXHVEM0VDXHVENTY4XHVENTU4XHVBQzcwXHVCMDk4IFx1QkIzOFx1QzExQyBcdUM3MjBcdUQ2MTUgXHVDMTIwXHVDNUI4XHVDNzc0IFx1QUMwMFx1QjlBQ1x1RDBBNFx1QjI5NCBcdUI5QzhcdUQwNkNcdUM1QzUgXHVDMTIwXHVDNUI4XHVDNzQwIFx1QzYyQ1x1QkMxNFx1Qjk3OCBcdUQ2MTVcdUMyRERcdUM3NzRcdUM1QjRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotIyAyLjEwIFdoaXRlIFNwYWNlIEhhbmRsaW5nCi0gICAgICAgIE1TR19YTUxfU1BBQ0VfREVDTEFSQVRJT05fSUxMRUdBTCA9ICJ4bWw6c3BhY2UiXHVDNUQwIFx1QjMwMFx1RDU1QyBcdUMxOERcdUMxMzEgXHVDMTIwXHVDNUI4XHVDNzQwICJkZWZhdWx0IiBcdUJDMEYgInByZXNlcnZlIiBcdUFDMTJcdUI5Q0MgXHVBQzAwXHVCMkE1XHVENTVDIFx1QzVGNFx1QUM3MCBcdUM3MjBcdUQ2MTVcdUM3M0NcdUI4NUMgXHVDOUMwXHVDODE1XHVCNDE4XHVDNUI0XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4KLSMgMy4yIEVsZW1lbnQgVHlwZSBEZWNsYXJhdGlvbnMKLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9FTEVNRU5UX1RZUEVfSU5fRUxFTUVOVERFQ0wgPSBcdUM2OTRcdUMxOEMgXHVDNzIwXHVENjE1IFx1QzEyMFx1QzVCOFx1QzVEMFx1QzExQ1x1QjI5NCAiPCFFTEVNRU5UIiBcdUIyRTRcdUM3NENcdUM1RDAgXHVBQ0Y1XHVCQzMxXHVDNzc0IFx1RDU0NFx1QzY5NFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgTVNHX0VMRU1FTlRfVFlQRV9SRVFVSVJFRF9JTl9FTEVNRU5UREVDTCA9IFx1QzY5NFx1QzE4QyBcdUM3MjBcdUQ2MTUgXHVDMTIwXHVDNUI4XHVDNUQwXHVCMjk0IFx1QzY5NFx1QzE4QyBcdUM3MjBcdUQ2MTVcdUM3NzQgXHVENTQ0XHVDNjk0XHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX0NPTlRFTlRTUEVDX0lOX0VMRU1FTlRERUNMID0gXHVDNjk0XHVDMThDIFx1QzcyMFx1RDYxNSBcdUMxMjBcdUM1QjhcdUM1RDBcdUMxMUNcdUIyOTQgXHVDNjk0XHVDMThDIFx1QzcyMFx1RDYxNSAiezB9IiBcdUIyRTRcdUM3NENcdUM1RDAgXHVBQ0Y1XHVCQzMxXHVDNzc0IFx1RDU0NFx1QzY5NFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgTVNHX0NPTlRFTlRTUEVDX1JFUVVJUkVEX0lOX0VMRU1FTlRERUNMID0gXHVDNjk0XHVDMThDIFx1QzcyMFx1RDYxNSBcdUMxMjBcdUM1QjhcdUM1RDBcdUMxMUNcdUIyOTQgXHVDNjk0XHVDMThDIFx1QzcyMFx1RDYxNSAiezB9IiBcdUIyRTRcdUM3NENcdUM1RDAgXHVDODFDXHVDNTdEIFx1Qzg3MFx1QUM3NFx1Qzc3NCBcdUQ1NDRcdUM2OTRcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIEVsZW1lbnREZWNsVW50ZXJtaW5hdGVkID0gXHVDNjk0XHVDMThDIFx1QzcyMFx1RDYxNSAiezB9Ilx1QzVEMCBcdUIzMDBcdUQ1NUMgXHVDMTIwXHVDNUI4XHVDNzQwICcnPicnXHVCODVDIFx1QjA1RFx1QjA5OFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0jIDMuMi4xIEVsZW1lbnQgQ29udGVudAotICAgICAgICBNU0dfT1BFTl9QQVJFTl9PUl9FTEVNRU5UX1RZUEVfUkVRVUlSRURfSU5fQ0hJTERSRU4gPSBcdUM2OTRcdUMxOEMgXHVDNzIwXHVENjE1ICJ7MH0iXHVDNzU4IFx1QzEyMFx1QzVCOFx1QzVEMFx1QjI5NCAnJygnJyBcdUJCMzhcdUM3OTAgXHVCNjEwXHVCMjk0IFx1QzY5NFx1QzE4QyBcdUM3MjBcdUQ2MTVcdUM3NzQgXHVENTQ0XHVDNjk0XHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBNU0dfQ0xPU0VfUEFSRU5fUkVRVUlSRURfSU5fQ0hJTERSRU4gPSBcdUM2OTRcdUMxOEMgXHVDNzIwXHVENjE1ICJ7MH0iXHVDNzU4IFx1QzEyMFx1QzVCOFx1QzVEMFx1QjI5NCAnJyknJ1x1QUMwMCBcdUQ1NDRcdUM2OTRcdUQ1NjlcdUIyQzhcdUIyRTQuCi0jIDMuMi4yIE1peGVkIENvbnRlbnQKLSAgICAgICAgTVNHX0VMRU1FTlRfVFlQRV9SRVFVSVJFRF9JTl9NSVhFRF9DT05URU5UID0gXHVDNjk0XHVDMThDIFx1QzcyMFx1RDYxNSAiezB9Ilx1Qzc1OCBcdUMxMjBcdUM1QjhcdUM1RDBcdUIyOTQgXHVDNjk0XHVDMThDIFx1QzcyMFx1RDYxNVx1Qzc3NCBcdUQ1NDRcdUM2OTRcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIE1TR19DTE9TRV9QQVJFTl9SRVFVSVJFRF9JTl9NSVhFRCA9IFx1QzY5NFx1QzE4QyBcdUM3MjBcdUQ2MTUgInswfSJcdUM3NTggXHVDMTIwXHVDNUI4XHVDNUQwXHVCMjk0ICcnKScnXHVBQzAwIFx1RDU0NFx1QzY5NFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgTWl4ZWRDb250ZW50VW50ZXJtaW5hdGVkID0gXHVENTU4XHVDNzA0IFx1QzY5NFx1QzE4QyBcdUM3MjBcdUQ2MTVcdUM3NzQgXHVDODFDXHVENTVDXHVCNDE4XHVCMjk0IFx1QUNCRFx1QzZCMCBcdUQ2M0NcdUQ1NjkgXHVDRjU4XHVEMTUwXHVDRTIwIFx1QkFBOFx1QjM3OCAiezB9Ilx1Qzc0MChcdUIyOTQpICIpKiJcdUI4NUMgXHVCMDVEXHVCMDk4XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4KLSMgMy4zIEF0dHJpYnV0ZS1MaXN0IERlY2xhcmF0aW9ucwotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX0VMRU1FTlRfVFlQRV9JTl9BVFRMSVNUREVDTCA9IGF0dHJpYnV0ZS1saXN0IFx1QzEyMFx1QzVCOFx1QzVEMFx1QzExQ1x1QjI5NCAiPCFBVFRMSVNUIiBcdUIyRTRcdUM3NENcdUM1RDAgXHVBQ0Y1XHVCQzMxXHVDNzc0IFx1RDU0NFx1QzY5NFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgTVNHX0VMRU1FTlRfVFlQRV9SRVFVSVJFRF9JTl9BVFRMSVNUREVDTCA9IGF0dHJpYnV0ZS1saXN0IFx1QzEyMFx1QzVCOFx1QzVEMFx1QjI5NCBcdUM2OTRcdUMxOEMgXHVDNzIwXHVENjE1XHVDNzc0IFx1RDU0NFx1QzY5NFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9BVFRSSUJVVEVfTkFNRV9JTl9BVFRERUYgPSAiezB9IiBcdUM2OTRcdUMxOENcdUM1RDAgXHVCMzAwXHVENTVDIGF0dHJpYnV0ZS1saXN0IFx1QzEyMFx1QzVCOFx1QzVEMFx1QzExQ1x1QjI5NCBcdUMxOERcdUMxMzEgXHVDNzc0XHVCOTg0IFx1QzU1RVx1QzVEMCBcdUFDRjVcdUJDMzFcdUM3NzQgXHVENTQ0XHVDNjk0XHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBBdHROYW1lUmVxdWlyZWRJbkF0dERlZiA9ICJ7MH0iIFx1QzY5NFx1QzE4Q1x1QzVEMCBcdUIzMDBcdUQ1NUMgYXR0cmlidXRlLWxpc3QgXHVDMTIwXHVDNUI4XHVDNUQwXHVCMjk0IFx1QzE4RFx1QzEzMSBcdUM3NzRcdUI5ODRcdUM3NzQgXHVDOUMwXHVDODE1XHVCNDE4XHVDNUI0XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9BVFRUWVBFX0lOX0FUVERFRiA9ICJ7MH0iIFx1QzY5NFx1QzE4Q1x1QzVEMCBcdUIzMDBcdUQ1NUMgInsxfSIgXHVDMThEXHVDMTMxXHVDNzU4IFx1QzEyMFx1QzVCOFx1QzVEMFx1QzExQ1x1QjI5NCBcdUMxOERcdUMxMzEgXHVDNzIwXHVENjE1IFx1QzU1RVx1QzVEMCBcdUFDRjVcdUJDMzFcdUM3NzQgXHVENTQ0XHVDNjk0XHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBBdHRUeXBlUmVxdWlyZWRJbkF0dERlZiA9ICJ7MH0iIFx1QzY5NFx1QzE4Q1x1QzVEMCBcdUIzMDBcdUQ1NUMgInsxfSIgXHVDMThEXHVDMTMxXHVDNzU4IFx1QzEyMFx1QzVCOFx1QzVEMFx1QjI5NCBcdUMxOERcdUMxMzEgXHVDNzIwXHVENjE1XHVDNzc0IFx1RDU0NFx1QzY5NFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9ERUZBVUxUREVDTF9JTl9BVFRERUYgPSAiezB9IiBcdUM2OTRcdUMxOENcdUM1RDAgXHVCMzAwXHVENTVDICJ7MX0iIFx1QzE4RFx1QzEzMVx1Qzc1OCBcdUMxMjBcdUM1QjhcdUM1RDBcdUMxMUNcdUIyOTQgXHVDMThEXHVDMTMxIFx1QUUzMFx1QkNGOFx1QUMxMiBcdUM1NUVcdUM1RDAgXHVBQ0Y1XHVCQzMxXHVDNzc0IFx1RDU0NFx1QzY5NFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgTVNHX0RVUExJQ0FURV9BVFRSSUJVVEVfREVGSU5JVElPTiA9IFx1QzgxQ1x1QUNGNVx1QjQxQyBcdUM2OTRcdUMxOEMgInswfSJcdUM3NTggXHVCM0Q5XHVDNzdDXHVENTVDIFx1QzE4RFx1QzEzMSAiezF9Ilx1QzVEMCBcdUIzMDBcdUQ1NzQgXHVDMThEXHVDMTMxIFx1QzgxNVx1Qzc1OFx1QUMwMCBcdUI0NTAgXHVBQzFDIFx1Qzc3NFx1QzBDMSBcdUM4MUNcdUFDRjVcdUI0MThcdUM1QzhcdUMyQjVcdUIyQzhcdUIyRTQuCi0jIDMuMy4xIEF0dHJpYnV0ZSBUeXBlcwotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQUZURVJfTk9UQVRJT05fSU5fTk9UQVRJT05UWVBFID0gInsxfSIgXHVDMThEXHVDMTMxIFx1QzEyMFx1QzVCOFx1QzVEMFx1QzExQ1x1QjI5NCAiTk9UQVRJT04iIFx1QjJFNFx1Qzc0Q1x1QzVEMCBcdUFDRjVcdUJDMzFcdUM3NzQgXHVCMDk4XHVEMEMwXHVCMDk4XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgTVNHX09QRU5fUEFSRU5fUkVRVUlSRURfSU5fTk9UQVRJT05UWVBFID0gInsxfSIgXHVDMThEXHVDMTMxIFx1QzEyMFx1QzVCOFx1QzVEMFx1QzExQ1x1QjI5NCAiTk9UQVRJT04iIFx1QjJFNFx1Qzc0Q1x1QzVEMCAnJygnJyBcdUJCMzhcdUM3OTBcdUFDMDAgXHVDNjQwXHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgTVNHX05BTUVfUkVRVUlSRURfSU5fTk9UQVRJT05UWVBFID0gInsxfSIgXHVDMThEXHVDMTMxIFx1QzEyMFx1QzVCOFx1QzVEMCBcdUIzMDBcdUQ1NUMgXHVENDVDXHVBRTMwXHVCQzk1IFx1QzcyMFx1RDYxNSBcdUJBQTlcdUI4NURcdUM1RDBcdUIyOTQgXHVENDVDXHVBRTMwXHVCQzk1IFx1Qzc3NFx1Qjk4NFx1Qzc3NCBcdUQ1NDRcdUM2OTRcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIE5vdGF0aW9uVHlwZVVudGVybWluYXRlZCA9ICJ7MX0iIFx1QzE4RFx1QzEzMSBcdUMxMjBcdUM1QjhcdUM1RDBcdUMxMUMgXHVENDVDXHVBRTMwXHVCQzk1IFx1QzcyMFx1RDYxNSBcdUJBQTlcdUI4NURcdUM3NDAgJycpJydcdUI4NUMgXHVCMDVEXHVCMDk4XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgTVNHX05NVE9LRU5fUkVRVUlSRURfSU5fRU5VTUVSQVRJT04gPSAiezF9IiBcdUMxOERcdUMxMzEgXHVDMTIwXHVDNUI4XHVDNUQwIFx1QjMwMFx1RDU1QyBcdUM1RjRcdUFDNzAgXHVDNzIwXHVENjE1IFx1QkFBOVx1Qjg1RFx1QzVEMFx1QjI5NCBcdUM3NzRcdUI5ODQgXHVEMUEwXHVEMDcwXHVDNzc0IFx1RDU0NFx1QzY5NFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgRW51bWVyYXRpb25VbnRlcm1pbmF0ZWQgPSAiezF9IiBcdUMxOERcdUMxMzEgXHVDMTIwXHVDNUI4XHVDNUQwXHVDMTFDIFx1QzVGNFx1QUM3MCBcdUM3MjBcdUQ2MTUgXHVCQUE5XHVCODVEXHVDNzQwICcnKScnXHVCODVDIFx1QjA1RFx1QjA5OFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIE1TR19ESVNUSU5DVF9UT0tFTlNfSU5fRU5VTUVSQVRJT04gPSAiezB9IiBcdUM2OTRcdUMxOENcdUM1RDAgXHVCMzAwXHVENTVDICJ7Mn0iIFx1QzE4RFx1QzEzMVx1Qzc1OCBcdUMxMjBcdUM1QjhcdUM1RDBcdUMxMUMgXHVCQUE5XHVCODVEIFx1QUMxMiAiezF9Ilx1Qzc3NChcdUFDMDApIFx1QjQ1MCBcdUJDODggXHVDNzc0XHVDMEMxIFx1QzlDMFx1QzgxNVx1QjQxOFx1QzVDOFx1QzJCNVx1QjJDOFx1QjJFNC4gXHVCMkU4XHVDNzdDIFx1QkFBOVx1Qjg1RCBcdUMxOERcdUMxMzEgXHVDMTIwXHVDNUI4XHVDNUQwXHVDMTFDIE5NVE9LRU5TXHVCMjk0IFx1QkFBOFx1QjQ1MCBcdUFDRTBcdUM3MjBcdUQ1NzRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBNU0dfRElTVElOQ1RfTk9UQVRJT05fSU5fRU5VTUVSQVRJT04gPSAiezB9IiBcdUM2OTRcdUMxOENcdUM1RDAgXHVCMzAwXHVENTVDICJ7Mn0iIFx1QzE4RFx1QzEzMVx1Qzc1OCBcdUMxMjBcdUM1QjhcdUM1RDBcdUMxMUMgXHVCQUE5XHVCODVEIFx1QUMxMiAiezF9Ilx1Qzc3NChcdUFDMDApIFx1QjQ1MCBcdUJDODggXHVDNzc0XHVDMEMxIFx1QzlDMFx1QzgxNVx1QjQxOFx1QzVDOFx1QzJCNVx1QjJDOFx1QjJFNC4gXHVCMkU4XHVDNzdDIE5vdGF0aW9uVHlwZSBcdUMxOERcdUMxMzEgXHVDMTIwXHVDNUI4XHVDNUQwXHVDMTFDIE5PVEFUSU9OIFx1Qzc3NFx1Qjk4NFx1Qzc0MCBcdUJBQThcdUI0NTAgXHVBQ0UwXHVDNzIwXHVENTc0XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4KLSMgMy4zLjIgQXR0cmlidXRlIERlZmF1bHRzCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9BRlRFUl9GSVhFRF9JTl9ERUZBVUxUREVDTCA9ICJ7MX0iIFx1QzE4RFx1QzEzMSBcdUMxMjBcdUM1QjhcdUM1RDBcdUMxMUNcdUIyOTQgIkZJWEVEIiBcdUIyRTRcdUM3NENcdUM1RDAgXHVBQ0Y1XHVCQzMxXHVDNzc0IFx1QjA5OFx1RDBDMFx1QjA5OFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0jIDMuNCBDb25kaXRpb25hbCBTZWN0aW9ucwotICAgICAgICBJbmNsdWRlU2VjdFVudGVybWluYXRlZCA9IFx1RDNFQ1x1RDU2OFx1QjQxQyBcdUM4NzBcdUFDNzRcdUJEODAgXHVDMTM5XHVDMTU4XHVDNzQwICJdXT4iXHVCODVDIFx1QjA1RFx1QjA5OFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIElnbm9yZVNlY3RVbnRlcm1pbmF0ZWQgPSBcdUM4MUNcdUM2NzhcdUI0MUMgXHVDODcwXHVBQzc0XHVCRDgwIFx1QzEzOVx1QzE1OFx1Qzc0MCAiXV0+Ilx1Qjg1QyBcdUIwNURcdUIwOThcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotIyA0LjEgQ2hhcmFjdGVyIGFuZCBFbnRpdHkgUmVmZXJlbmNlcwotICAgICAgICBOYW1lUmVxdWlyZWRJblBFUmVmZXJlbmNlID0gXHVCOUU0XHVBQzFDXHVCQ0MwXHVDMjE4IFx1QzVENFx1RDJGMFx1RDJGMCBcdUNDMzhcdUM4NzBcdUM1RDBcdUMxMUNcdUIyOTQgJyUnIFx1QkMxNFx1Qjg1QyBcdUIyRTRcdUM3NENcdUM1RDAgXHVDNUQ0XHVEMkYwXHVEMkYwIFx1Qzc3NFx1Qjk4NFx1Qzc3NCBcdUM2NDBcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBTZW1pY29sb25SZXF1aXJlZEluUEVSZWZlcmVuY2UgPSBcdUI5RTRcdUFDMUNcdUJDQzBcdUMyMTggXHVDNUQ0XHVEMkYwXHVEMkYwIFx1Q0MzOFx1Qzg3MCAiJXswfTsiXHVDNzQwICcnOycnIFx1QUQ2Q1x1QkQ4NFx1Qzc5MFx1Qjg1QyBcdUIwNURcdUIwOThcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotIyA0LjIgRW50aXR5IERlY2xhcmF0aW9ucwotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX0VOVElUWV9OQU1FX0lOX0VOVElUWURFQ0wgPSBcdUM1RDRcdUQyRjBcdUQyRjAgXHVDMTIwXHVDNUI4XHVDNUQwXHVDMTFDXHVCMjk0ICI8IUVOVElUWSIgXHVCMkU0XHVDNzRDXHVDNUQwIFx1QUNGNVx1QkMzMVx1Qzc3NCBcdUQ1NDRcdUM2OTRcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfUEVSQ0VOVF9JTl9QRURFQ0wgPSBcdUI5RTRcdUFDMUNcdUJDQzBcdUMyMTggXHVDNUQ0XHVEMkYwXHVEMkYwIFx1QzEyMFx1QzVCOFx1QzVEMFx1QzExQ1x1QjI5NCAiPCFFTlRJVFkiXHVDNjQwICclJyBcdUJCMzhcdUM3OTAgXHVDMEFDXHVDNzc0XHVDNUQwIFx1QUNGNVx1QkMzMVx1Qzc3NCBcdUQ1NDRcdUM2OTRcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfRU5USVRZX05BTUVfSU5fUEVERUNMID0gXHVCOUU0XHVBQzFDXHVCQ0MwXHVDMjE4IFx1QzVENFx1RDJGMFx1RDJGMCBcdUMxMjBcdUM1QjhcdUM1RDBcdUMxMUNcdUIyOTQgJyUnXHVDNjQwIFx1QzVENFx1RDJGMFx1RDJGMCBcdUM3NzRcdUI5ODQgXHVDMEFDXHVDNzc0XHVDNUQwIFx1QUNGNVx1QkMzMVx1Qzc3NCBcdUQ1NDRcdUM2OTRcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIE1TR19FTlRJVFlfTkFNRV9SRVFVSVJFRF9JTl9FTlRJVFlERUNMID0gXHVDNUQ0XHVEMkYwXHVEMkYwIFx1QzEyMFx1QzVCOFx1QzVEMFx1QjI5NCBcdUM1RDRcdUQyRjBcdUQyRjAgXHVDNzc0XHVCOTg0XHVDNzc0IFx1RDU0NFx1QzY5NFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0FGVEVSX0VOVElUWV9OQU1FX0lOX0VOVElUWURFQ0wgPSBcdUM1RDRcdUQyRjBcdUQyRjAgXHVDMTIwXHVDNUI4XHVDNUQwXHVDMTFDXHVCMjk0IFx1QzVENFx1RDJGMFx1RDJGMCBcdUM3NzRcdUI5ODQgInswfSJcdUFDRkMoXHVDNjQwKSBcdUM4MTVcdUM3NTggXHVDMEFDXHVDNzc0XHVDNUQwIFx1QUNGNVx1QkMzMVx1Qzc3NCBcdUQ1NDRcdUM2OTRcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfTk9UQVRJT05fTkFNRV9JTl9VTlBBUlNFRF9FTlRJVFlERUNMID0gInswfSIgXHVDNUQ0XHVEMkYwXHVEMkYwXHVDNUQwIFx1QjMwMFx1RDU1QyBcdUMxMjBcdUM1QjhcdUM1RDBcdUMxMUNcdUIyOTQgIk5EQVRBIlx1QzY0MCBcdUQ0NUNcdUFFMzBcdUJDOTUgXHVDNzc0XHVCOTg0IFx1QzBBQ1x1Qzc3NFx1QzVEMCBcdUFDRjVcdUJDMzFcdUM3NzQgXHVENTQ0XHVDNjk0XHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX05EQVRBX0lOX1VOUEFSU0VEX0VOVElUWURFQ0wgPSAiezB9IiBcdUM1RDRcdUQyRjBcdUQyRjBcdUM1RDAgXHVCMzAwXHVENTVDIFx1QzEyMFx1QzVCOFx1QzVEMFx1QzExQ1x1QjI5NCAiTkRBVEEiIFx1QzU1RVx1QzVEMCBcdUFDRjVcdUJDMzFcdUM3NzQgXHVENTQ0XHVDNjk0XHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBNU0dfTk9UQVRJT05fTkFNRV9SRVFVSVJFRF9GT1JfVU5QQVJTRURfRU5USVRZREVDTCA9ICJ7MH0iIFx1QzVENFx1RDJGMFx1RDJGMFx1QzVEMCBcdUIzMDBcdUQ1NUMgXHVDMTIwXHVDNUI4XHVDNUQwXHVDMTFDXHVCMjk0ICJOREFUQSIgXHVCMkU0XHVDNzRDXHVDNUQwIFx1RDQ1Q1x1QUUzMFx1QkM5NSBcdUM3NzRcdUI5ODRcdUM3NzQgXHVENTQ0XHVDNjk0XHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBFbnRpdHlEZWNsVW50ZXJtaW5hdGVkID0gInswfSIgXHVDNUQ0XHVEMkYwXHVEMkYwXHVDNUQwIFx1QjMwMFx1RDU1QyBcdUMxMjBcdUM1QjhcdUM3NDAgJyc+JydcdUI4NUMgXHVCMDVEXHVCMDk4XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4KLQlNU0dfRFVQTElDQVRFX0VOVElUWV9ERUZJTklUSU9OID0gInswfSIgXHVDNUQ0XHVEMkYwXHVEMkYwXHVBQzAwIFx1QjQ1MCBcdUJDODggXHVDNzc0XHVDMEMxIFx1QzEyMFx1QzVCOFx1QjQxOFx1QzVDOFx1QzJCNVx1QjJDOFx1QjJFNC4gICAgICAgIAotIyA0LjIuMiBFeHRlcm5hbCBFbnRpdGllcwotICAgICAgICBFeHRlcm5hbElEUmVxdWlyZWQgPSBcdUM2NzhcdUJEODAgXHVDNUQ0XHVEMkYwXHVEMkYwIFx1QzEyMFx1QzVCOFx1Qzc0MCAiU1lTVEVNIiBcdUI2MTBcdUIyOTQgIlBVQkxJQyJcdUM3M0NcdUI4NUMgXHVDMkRDXHVDNzkxXHVENTc0XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9QVUJJRExJVEVSQUxfSU5fRVhURVJOQUxJRCA9ICJQVUJMSUMiXHVBQ0ZDIFx1QUNGNVx1QzZBOSBcdUMyRERcdUJDQzRcdUM3OTAgXHVDMEFDXHVDNzc0XHVDNUQwXHVCMjk0IFx1QUNGNVx1QkMzMVx1Qzc3NCBcdUQ1NDRcdUM2OTRcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9BRlRFUl9QVUJJRExJVEVSQUxfSU5fRVhURVJOQUxJRCA9IFx1QUNGNVx1QzZBOSBcdUMyRERcdUJDQzRcdUM3OTBcdUM2NDAgXHVDMkRDXHVDMkE0XHVEMTVDIFx1QzJERFx1QkNDNFx1Qzc5MCBcdUMwQUNcdUM3NzRcdUM1RDBcdUIyOTQgXHVBQ0Y1XHVCQzMxXHVDNzc0IFx1RDU0NFx1QzY5NFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9TWVNURU1MSVRFUkFMX0lOX0VYVEVSTkFMSUQgPSAiU1lTVEVNIlx1QUNGQyBcdUMyRENcdUMyQTRcdUQxNUMgXHVDMkREXHVCQ0M0XHVDNzkwIFx1QzBBQ1x1Qzc3NFx1QzVEMFx1QjI5NCBcdUFDRjVcdUJDMzFcdUM3NzQgXHVENTQ0XHVDNjk0XHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBNU0dfVVJJX0ZSQUdNRU5UX0lOX1NZU1RFTUlEID0gXHVCRDgwXHVCRDg0IFx1QzJERFx1QkNDNFx1Qzc5MFx1QjI5NCBcdUMyRENcdUMyQTRcdUQxNUMgXHVDMkREXHVCQ0M0XHVDNzkwICJ7MH0iXHVDNzU4IFx1Qzc3Q1x1QkQ4MFx1Qjg1QyBcdUM5QzBcdUM4MTVcdUI0MThcdUM5QzAgXHVDNTRBXHVDNTQ0XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4KLSMgNC43IE5vdGF0aW9uIERlY2xhcmF0aW9ucwotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX05PVEFUSU9OX05BTUVfSU5fTk9UQVRJT05ERUNMID0gXHVENDVDXHVBRTMwXHVCQzk1IFx1QzEyMFx1QzVCOFx1QzVEMFx1QzExQ1x1QjI5NCAiPCFOT1RBVElPTiIgXHVCMkU0XHVDNzRDXHVDNUQwIFx1QUNGNVx1QkMzMVx1Qzc3NCBcdUQ1NDRcdUM2OTRcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIE1TR19OT1RBVElPTl9OQU1FX1JFUVVJUkVEX0lOX05PVEFUSU9OREVDTCA9IFx1RDQ1Q1x1QUUzMFx1QkM5NSBcdUMxMjBcdUM1QjhcdUM1RDBcdUIyOTQgXHVENDVDXHVBRTMwXHVCQzk1IFx1Qzc3NFx1Qjk4NFx1Qzc3NCBcdUQ1NDRcdUM2OTRcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9BRlRFUl9OT1RBVElPTl9OQU1FX0lOX05PVEFUSU9OREVDTCA9IFx1RDQ1Q1x1QUUzMFx1QkM5NSBcdUMxMjBcdUM1QjhcdUM1RDBcdUMxMUNcdUIyOTQgXHVENDVDXHVBRTMwXHVCQzk1IFx1Qzc3NFx1Qjk4NCAiezB9IiBcdUIyRTRcdUM3NENcdUM1RDAgXHVBQ0Y1XHVCQzMxXHVDNzc0IFx1RDU0NFx1QzY5NFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgRXh0ZXJuYWxJRG9yUHVibGljSURSZXF1aXJlZCA9ICJ7MH0iIFx1RDQ1Q1x1QUUzMFx1QkM5NVx1QzVEMCBcdUIzMDBcdUQ1NUMgXHVDMTIwXHVDNUI4XHVDNUQwXHVCMjk0IFx1QzJEQ1x1QzJBNFx1RDE1QyBcdUI2MTBcdUIyOTQgXHVBQ0Y1XHVDNkE5IFx1QzJERFx1QkNDNFx1Qzc5MFx1QUMwMCBcdUQzRUNcdUQ1NjhcdUI0MThcdUM1QjRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBOb3RhdGlvbkRlY2xVbnRlcm1pbmF0ZWQgPSAiezB9IiBcdUQ0NUNcdUFFMzBcdUJDOTVcdUM1RDAgXHVCMzAwXHVENTVDIFx1QzEyMFx1QzVCOFx1Qzc0MCAnJz4nJ1x1Qjg1QyBcdUIwNURcdUIwOThcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICAKLSMgVmFsaWRhdGlvbiBtZXNzYWdlcwotICAgICAgICBEdXBsaWNhdGVUeXBlSW5NaXhlZENvbnRlbnQgPSBcdUM2OTRcdUMxOEMgXHVDNzIwXHVENjE1ICJ7MX0iXHVDNzc0KFx1QUMwMCkgXHVDNjk0XHVDMThDIFx1QzEyMFx1QzVCOCAiezB9Ilx1Qzc1OCBcdUNGNThcdUQxNTBcdUNFMjAgXHVCQUE4XHVCMzc4XHVDNUQwIFx1Qzc3NFx1QkJGOCBcdUM5QzBcdUM4MTVcdUI0MThcdUM1QzhcdUMyQjVcdUIyQzhcdUIyRTQuCi0gICAgICAgIEVOVElUSUVTSW52YWxpZCA9IEVOVElUSUVTIFx1QzcyMFx1RDYxNVx1Qzc1OCBcdUMxOERcdUMxMzFcdUFDMTIgInsxfSJcdUM3NDAoXHVCMjk0KSBcdUFENkNcdUJCMzhcdUM3NzQgXHVCRDg0XHVDMTFEXHVCNDE4XHVDOUMwIFx1QzU0QVx1Qzc0MCBcdUQ1NThcdUIwOTggXHVDNzc0XHVDMEMxXHVDNzU4IFx1QzVENFx1RDJGMFx1RDJGMFx1QzVEMCBcdUIzMDBcdUQ1NUMgXHVDNzc0XHVCOTg0XHVDNzc0XHVDNUI0XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgRU5USVRZSW52YWxpZCA9IEVOVElUWSBcdUM3MjBcdUQ2MTVcdUM3NTggXHVDMThEXHVDMTMxXHVBQzEyICJ7MX0iXHVDNzQwKFx1QjI5NCkgXHVBRDZDXHVCQjM4XHVDNzc0IFx1QkQ4NFx1QzExRFx1QjQxOFx1QzlDMCBcdUM1NEFcdUM3NDAgXHVDNUQ0XHVEMkYwXHVEMkYwXHVDNUQwIFx1QjMwMFx1RDU1QyBcdUM3NzRcdUI5ODRcdUM3NzRcdUM1QjRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBJRERlZmF1bHRUeXBlSW52YWxpZCA9IElEIFx1QzE4RFx1QzEzMSAiezB9Ilx1Qzc1OCBcdUMxMjBcdUM1QjhcdUI0MUMgXHVBRTMwXHVCQ0Y4XHVBQzEyXHVDNzQwICIjSU1QTElFRCIgXHVCNjEwXHVCMjk0ICIjUkVRVUlSRUQiXHVDNUVDXHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgSURJbnZhbGlkID0gSUQgXHVDNzIwXHVENjE1XHVDNzU4IFx1QzE4RFx1QzEzMVx1QUMxMiAiezB9Ilx1Qzc0MChcdUIyOTQpIFx1Qzc3NFx1Qjk4NFx1Qzc3NFx1QzVCNFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIElESW52YWxpZFdpdGhOYW1lc3BhY2VzID0gXHVCMTI0XHVDNzg0XHVDMkE0XHVEMzk4XHVDNzc0XHVDMkE0XHVBQzAwIFx1QzBBQ1x1QzZBOVx1QzczQ1x1Qjg1QyBcdUMxMjRcdUM4MTVcdUI0MUMgXHVBQ0JEXHVDNkIwIElEIFx1QzcyMFx1RDYxNVx1Qzc1OCBcdUMxOERcdUMxMzFcdUFDMTIgInswfSJcdUM3NDAoXHVCMjk0KSBOQ05hbWVcdUM3NzRcdUM1QjRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBJRE5vdFVuaXF1ZSA9IElEIFx1QzcyMFx1RDYxNVx1Qzc1OCBcdUMxOERcdUMxMzFcdUFDMTIgInswfSJcdUM3NDAoXHVCMjk0KSBcdUJCMzhcdUMxMUMgXHVCMEI0XHVDNUQwXHVDMTFDIFx1QUNFMFx1QzcyMFx1RDU3NFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIElEUkVGSW52YWxpZCA9IElEUkVGIFx1QzcyMFx1RDYxNVx1Qzc1OCBcdUMxOERcdUMxMzFcdUFDMTIgInswfSJcdUM3NDAoXHVCMjk0KSBcdUM3NzRcdUI5ODRcdUM3NzRcdUM1QjRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBJRFJFRkludmFsaWRXaXRoTmFtZXNwYWNlcyA9IFx1QjEyNFx1Qzc4NFx1QzJBNFx1RDM5OFx1Qzc3NFx1QzJBNFx1QUMwMCBcdUMwQUNcdUM2QTlcdUM3M0NcdUI4NUMgXHVDMTI0XHVDODE1XHVCNDFDIFx1QUNCRFx1QzZCMCBJRFJFRiBcdUM3MjBcdUQ2MTVcdUM3NTggXHVDMThEXHVDMTMxXHVBQzEyICJ7MH0iXHVDNzQwKFx1QjI5NCkgTkNOYW1lXHVDNzc0XHVDNUI0XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgSURSRUZTSW52YWxpZCA9IElEUkVGUyBcdUM3MjBcdUQ2MTVcdUM3NTggXHVDMThEXHVDMTMxXHVBQzEyICJ7MH0iXHVDNzQwKFx1QjI5NCkgXHVENTU4XHVCMDk4IFx1Qzc3NFx1QzBDMVx1Qzc1OCBcdUM3NzRcdUI5ODRcdUM3NzRcdUM1QjRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBJTExfRk9STUVEX1BBUkFNRVRFUl9FTlRJVFlfV0hFTl9VU0VEX0lOX0RFQ0wgPSBcdUM1RDRcdUQyRjBcdUQyRjAgXHVDQzM4XHVDODcwXHVBQzAwIFx1QzgwNFx1Q0NCNCBcdUMxMjBcdUM1QjhcdUM3M0NcdUI4NUMgXHVDMEFDXHVDNkE5XHVCNDFDIFx1QUNCRFx1QzZCMCBcdUI5RTRcdUFDMUNcdUJDQzBcdUMyMTggXHVDNUQ0XHVEMkYwXHVEMkYwICJ7MH0iXHVDNzU4IFx1QjMwMFx1Q0NCNCBcdUQxNERcdUMyQTRcdUQyQjhcdUM1RDBcdUIyOTQgXHVDODFDXHVCMzAwXHVCODVDIFx1QzkxMVx1Q0NBOVx1QjQxQyBcdUMxMjBcdUM1QjhcdUM3NzQgXHVEM0VDXHVENTY4XHVCNDE4XHVDNUI0XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgSW1wcm9wZXJEZWNsYXJhdGlvbk5lc3RpbmcgPSBcdUI5RTRcdUFDMUNcdUJDQzBcdUMyMTggXHVDNUQ0XHVEMkYwXHVEMkYwICJ7MH0iXHVDNzU4IFx1QjMwMFx1Q0NCNCBcdUQxNERcdUMyQTRcdUQyQjhcdUM1RDBcdUIyOTQgXHVDODFDXHVCMzAwXHVCODVDIFx1QzkxMVx1Q0NBOVx1QjQxQyBcdUMxMjBcdUM1QjhcdUM3NzQgXHVEM0VDXHVENTY4XHVCNDE4XHVDNUI0XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgSW1wcm9wZXJHcm91cE5lc3RpbmcgPSBcdUI5RTRcdUFDMUNcdUJDQzBcdUMyMTggXHVDNUQ0XHVEMkYwXHVEMkYwICJ7MH0iXHVDNzU4IFx1QjMwMFx1Q0NCNCBcdUQxNERcdUMyQTRcdUQyQjhcdUM1RDBcdUIyOTQgXHVDODFDXHVCMzAwXHVCODVDIFx1QzkxMVx1Q0NBOVx1QjQxQyBcdUFEMDRcdUQ2MzggXHVDMzBEXHVDNzc0IFx1RDNFQ1x1RDU2OFx1QjQxOFx1QzVCNFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIElOVkFMSURfUEVfSU5fQ09ORElUSU9OQUwgPSBcdUI5RTRcdUFDMUNcdUJDQzBcdUMyMTggXHVDNUQ0XHVEMkYwXHVEMkYwICJ7MH0iXHVDNzU4IFx1QjMwMFx1Q0NCNCBcdUQxNERcdUMyQTRcdUQyQjhcdUM1RDBcdUIyOTQgXHVDODA0XHVDQ0I0IFx1Qzg3MFx1QUM3NFx1QkQ4MCBcdUMxMzlcdUMxNThcdUM3NzQgXHVEM0VDXHVENTY4XHVCNDE4XHVBQzcwXHVCMDk4IElOQ0xVREUgXHVCNjEwXHVCMjk0IElHTk9SRVx1QjlDQyBcdUQzRUNcdUQ1NjhcdUI0MThcdUM1QjRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBNU0dfQVRUUklCVVRFX05PVF9ERUNMQVJFRCA9IFx1QzY5NFx1QzE4QyBcdUM3MjBcdUQ2MTUgInswfSJcdUM1RDAgXHVCMzAwXHVENTVDICJ7MX0iIFx1QzE4RFx1QzEzMVx1Qzc0NCBcdUMxMjBcdUM1QjhcdUQ1NzRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBNU0dfQVRUUklCVVRFX1ZBTFVFX05PVF9JTl9MSVNUID0gXHVBQzEyXHVDNzc0ICJ7MX0iXHVDNzc4ICJ7MH0iIFx1QzE4RFx1QzEzMVx1QzVEMFx1QjI5NCAiezJ9IiBcdUJBQTlcdUI4NURcdUM3NTggXHVBQzEyXHVDNzc0IFx1QzBBQ1x1QzZBOVx1QjQxOFx1QzVCNFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIE1TR19BVFRWQUxVRV9DSEFOR0VEX0RVUklOR19OT1JNQUxJWkFUSU9OX1dIRU5fU1RBTkRBTE9ORSA9ICJ7MH0iIFx1QzE4RFx1QzEzMVx1Qzc1OCAiezF9IiBcdUFDMTJcdUM3NDAgXHVCM0M1XHVCOUJEXHVENjE1IFx1QkIzOFx1QzExQ1x1QzVEMFx1QzExQyBcdUM4MTVcdUFERENcdUQ2NTRcdUM1RDAgXHVDNzU4XHVENTc0ICJ7Mn0iKFx1QzczQylcdUI4NUMgXHVCQ0MwXHVBQ0JEXHVCNDE4XHVDOUMwIFx1QzU0QVx1QzU0NFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIE1TR19DT05URU5UX0lOQ09NUExFVEUgPSBcdUM2OTRcdUMxOEMgXHVDNzIwXHVENjE1ICJ7MH0iXHVDNzU4IFx1Q0Y1OFx1RDE1MFx1Q0UyMFx1QUMwMCBcdUJEODhcdUM2NDRcdUM4MDRcdUQ1NjlcdUIyQzhcdUIyRTQuIFx1RDU3NFx1QjJGOSBcdUNGNThcdUQxNTBcdUNFMjBcdUIyOTQgInsxfSJcdUFDRkMoXHVDNjQwKSBcdUM3N0NcdUNFNThcdUQ1NzRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBNU0dfQ09OVEVOVF9JTlZBTElEID0gXHVDNjk0XHVDMThDIFx1QzcyMFx1RDYxNSAiezB9Ilx1Qzc1OCBcdUNGNThcdUQxNTBcdUNFMjBcdUIyOTQgInsxfSJcdUFDRkMoXHVDNjQwKSBcdUM3N0NcdUNFNThcdUQ1NzRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBNU0dfQ09OVEVOVF9JTlZBTElEX1NQRUNJRklFRCA9IFx1QzY5NFx1QzE4QyBcdUM3MjBcdUQ2MTUgInswfSJcdUM3NTggXHVDRjU4XHVEMTUwXHVDRTIwXHVCMjk0ICJ7MX0iXHVBQ0ZDKFx1QzY0MCkgXHVDNzdDXHVDRTU4XHVENTc0XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4gInsyfSIgXHVDNzIwXHVENjE1XHVDNzU4IFx1RDU1OFx1QzcwNCBcdUQ1NkRcdUJBQTlcdUM3NDAgXHVENUM4XHVDNkE5XHVCNDE4XHVDOUMwIFx1QzU0QVx1QzJCNVx1QjJDOFx1QjJFNC4KLSAgICAgICAgTVNHX0RFRkFVTFRFRF9BVFRSSUJVVEVfTk9UX1NQRUNJRklFRCA9IFx1QzY5NFx1QzE4QyBcdUM3MjBcdUQ2MTUgInswfSJcdUM1RDAgXHVCMzAwXHVENTVDICJ7MX0iIFx1QzE4RFx1QzEzMVx1QzVEMCBcdUFFMzBcdUJDRjhcdUFDMTJcdUM3NzQgXHVDNzg4XHVDNzNDXHVCQTcwIFx1QjNDNVx1QjlCRFx1RDYxNSBcdUJCMzhcdUMxMUNcdUM1RDAgXHVDOUMwXHVDODE1XHVCNDE4XHVDNUI0XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgTVNHX0RVUExJQ0FURV9BVFRERUYgPSBcdUM2OTRcdUMxOEMgXHVDNzIwXHVENjE1ICJ7MH0iXHVDNUQwIFx1QjMwMFx1RDU1QyAiezF9IiBcdUMxOERcdUMxMzFcdUM3NzQgXHVDNzc0XHVCQkY4IFx1QzEyMFx1QzVCOFx1QjQxOFx1QzVCNCBcdUM3ODhcdUMyQjVcdUIyQzhcdUIyRTQuCi0gICAgICAgIE1TR19FTEVNRU5UX0FMUkVBRFlfREVDTEFSRUQgPSBcdUM2OTRcdUMxOEMgXHVDNzIwXHVENjE1ICJ7MH0iXHVDNzQwKFx1QjI5NCkgXHVCNDUwIFx1QkM4OCBcdUM3NzRcdUMwQzEgXHVDMTIwXHVDNUI4XHVCNDE4XHVDOUMwIFx1QzU0QVx1QzU0NFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIE1TR19FTEVNRU5UX05PVF9ERUNMQVJFRCA9IFx1QzY5NFx1QzE4QyBcdUM3MjBcdUQ2MTUgInswfSJcdUM3NDQoXHVCOTdDKSBcdUMxMjBcdUM1QjhcdUQ1NzRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBNU0dfR1JBTU1BUl9OT1RfRk9VTkQgPSBcdUJCMzhcdUMxMUNcdUFDMDAgXHVCRDgwXHVDODAxXHVENTY5XHVENTY4OiBcdUJCMzhcdUJDOTVcdUM3NDQgXHVDQzNFXHVDNzQ0IFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuCi0gICAgICAgIE1TR19FTEVNRU5UX1dJVEhfSURfUkVRVUlSRUQgPSBcdUMyRERcdUJDQzRcdUM3OTBcdUFDMDAgInswfSJcdUM3NzggXHVDNjk0XHVDMThDXHVBQzAwIFx1QkIzOFx1QzExQ1x1QzVEMCBcdUIwOThcdUQwQzBcdUIwOThcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBNU0dfRVhURVJOQUxfRU5USVRZX05PVF9QRVJNSVRURUQgPSBcdUIzQzVcdUI5QkRcdUQ2MTUgXHVCQjM4XHVDMTFDXHVDNUQwXHVDMTFDXHVCMjk0IFx1QzY3OFx1QkQ4MCBcdUM1RDRcdUQyRjBcdUQyRjAgInswfSJcdUM1RDAgXHVCMzAwXHVENTVDIFx1Q0MzOFx1Qzg3MFx1QUMwMCBcdUQ1QzhcdUM2QTlcdUI0MThcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0LgotICAgICAgICBNU0dfRklYRURfQVRUVkFMVUVfSU5WQUxJRCA9IFx1QUMxMlx1Qzc3NCAiezJ9Ilx1Qzc3OCAiezF9IiBcdUMxOERcdUMxMzFcdUM3NTggXHVBQzEyXHVDNzQwICJ7M30iXHVDNzc0XHVDNUI0XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgTVNHX01PUkVfVEhBTl9PTkVfSURfQVRUUklCVVRFID0gXHVDNjk0XHVDMThDIFx1QzcyMFx1RDYxNSAiezB9Ilx1QzVEMCBJRCBcdUM3MjBcdUQ2MTVcdUM3NTggInsxfSIgXHVDMThEXHVDMTMxXHVDNzc0IFx1Qzc3NFx1QkJGOCBcdUM3ODhcdUM3M0NcdUJCQzBcdUI4NUMgSUQgXHVDNzIwXHVENjE1XHVDNzU4IFx1QjQ1MFx1QkM4OFx1QzlGOCBcdUMxOERcdUMxMzEgInsyfSJcdUM3NzQoXHVBQzAwKSBcdUQ1QzhcdUM2QTlcdUI0MThcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0LgotICAgICAgICBNU0dfTU9SRV9USEFOX09ORV9OT1RBVElPTl9BVFRSSUJVVEUgPSBcdUM2OTRcdUMxOEMgXHVDNzIwXHVENjE1ICJ7MH0iXHVDNUQwIE5PVEFUSU9OIFx1QzcyMFx1RDYxNVx1Qzc1OCAiezF9IiBcdUMxOERcdUMxMzFcdUM3NzQgXHVDNzc0XHVCQkY4IFx1Qzc4OFx1QzczQ1x1QkJDMFx1Qjg1QyBOT1RBVElPTiBcdUM3MjBcdUQ2MTVcdUM3NTggXHVCNDUwXHVCQzg4XHVDOUY4IFx1QzE4RFx1QzEzMSAiezJ9Ilx1Qzc3NChcdUFDMDApIFx1RDVDOFx1QzZBOVx1QjQxOFx1QzlDMCBcdUM1NEFcdUMyQjVcdUIyQzhcdUIyRTQuCi0gICAgICAgIE1TR19OT1RBVElPTl9OT1RfREVDTEFSRURfRk9SX05PVEFUSU9OVFlQRV9BVFRSSUJVVEUgPSAiezF9IiBcdUQ0NUNcdUFFMzBcdUJDOTVcdUM3NDAgInswfSIgXHVDMThEXHVDMTMxXHVDNUQwIFx1QjMwMFx1RDU1QyBcdUQ0NUNcdUFFMzBcdUJDOTUgXHVDNzIwXHVENjE1IFx1QkFBOVx1Qjg1RFx1QzVEMFx1QzExQyBcdUNDMzhcdUM4NzBcdUI0MThcdUIyOTQgXHVBQ0JEXHVDNkIwIFx1QzEyMFx1QzVCOFx1QjQxOFx1QzVCNFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIE1TR19OT1RBVElPTl9OT1RfREVDTEFSRURfRk9SX1VOUEFSU0VEX0VOVElUWURFQ0wgPSAiezF9IiBcdUQ0NUNcdUFFMzBcdUJDOTVcdUM3NDAgInswfSJcdUM1RDAgXHVCMzAwXHVENTc0IFx1QUQ2Q1x1QkIzOFx1Qzc3NCBcdUJEODRcdUMxMURcdUI0MThcdUM5QzAgXHVDNTRBXHVDNzQwIFx1QzVENFx1RDJGMFx1RDJGMCBcdUMxMjBcdUM1QjhcdUM1RDBcdUMxMUMgXHVDQzM4XHVDODcwXHVCNDE4XHVCMjk0IFx1QUNCRFx1QzZCMCBcdUMxMjBcdUM1QjhcdUI0MThcdUM1QjRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBNU0dfUkVGRVJFTkNFX1RPX0VYVEVSTkFMTFlfREVDTEFSRURfRU5USVRZX1dIRU5fU1RBTkRBTE9ORSA9IFx1QjNDNVx1QjlCRFx1RDYxNSBcdUJCMzhcdUMxMUNcdUM1RDBcdUMxMUNcdUIyOTQgXHVBRDZDXHVCQjM4XHVDNzc0IFx1QkQ4NFx1QzExRFx1QjQxQyBcdUM2NzhcdUJEODAgXHVDNUQ0XHVEMkYwXHVEMkYwXHVDNUQwXHVDMTFDIFx1QzEyMFx1QzVCOFx1QjQxQyAiezB9IiBcdUM1RDRcdUQyRjBcdUQyRjBcdUM1RDAgXHVCMzAwXHVENTVDIFx1Q0MzOFx1Qzg3MFx1QUMwMCBcdUQ1QzhcdUM2QTlcdUI0MThcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0LgotICAgICAgICBNU0dfUkVRVUlSRURfQVRUUklCVVRFX05PVF9TUEVDSUZJRUQgPSAiezF9IiBcdUMxOERcdUMxMzFcdUM3NzQgXHVENTQ0XHVDNjk0XHVENTU4XHVCQTcwIFx1QzY5NFx1QzE4QyBcdUM3MjBcdUQ2MTUgInswfSJcdUM1RDAgXHVCMzAwXHVENTc0IFx1QzlDMFx1QzgxNVx1QjQxOFx1QzVCNFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIE1TR19XSElURV9TUEFDRV9JTl9FTEVNRU5UX0NPTlRFTlRfV0hFTl9TVEFOREFMT05FID0gXHVCM0M1XHVCOUJEXHVENjE1IFx1QkIzOFx1QzExQ1x1QzVEMFx1QzExQ1x1QjI5NCBcdUM2OTRcdUMxOEMgXHVDRjU4XHVEMTUwXHVDRTIwXHVCOTdDIFx1QUMwMFx1QzlDMFx1QkE3MCBcdUFENkNcdUJCMzhcdUM3NzQgXHVCRDg0XHVDMTFEXHVCNDFDIFx1QzY3OFx1QkQ4MCBcdUM1RDRcdUQyRjBcdUQyRjBcdUM1RDBcdUMxMUMgXHVDMTIwXHVDNUI4XHVCNDFDIFx1QzY5NFx1QzE4QyBcdUMwQUNcdUM3NzRcdUM1RDAgXHVBQ0Y1XHVCQzMxXHVDNzc0IFx1QzVDNlx1QzVCNFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIE5NVE9LRU5JbnZhbGlkID0gTk1UT0tFTiBcdUM3MjBcdUQ2MTVcdUM3NTggXHVDMThEXHVDMTMxXHVBQzEyICJ7MH0iXHVDNzQwKFx1QjI5NCkgXHVDNzc0XHVCOTg0IFx1RDFBMFx1RDA3MFx1Qzc3NFx1QzVCNFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIE5NVE9LRU5TSW52YWxpZCA9IE5NVE9LRU5TIFx1QzcyMFx1RDYxNVx1Qzc1OCBcdUMxOERcdUMxMzFcdUFDMTIgInswfSJcdUM3NDAoXHVCMjk0KSBcdUQ1NThcdUIwOTggXHVDNzc0XHVDMEMxXHVDNzU4IFx1Qzc3NFx1Qjk4NCBcdUQxQTBcdUQwNzBcdUM3NzRcdUM1QjRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBOb05vdGF0aW9uT25FbXB0eUVsZW1lbnQgPSBFTVBUWVx1Qjg1QyBcdUMxMjBcdUM1QjhcdUI0MUMgXHVDNjk0XHVDMThDIFx1QzcyMFx1RDYxNSAiezB9Ilx1Qzc0MChcdUIyOTQpIE5PVEFUSU9OIFx1QzcyMFx1RDYxNVx1Qzc1OCAiezF9IiBcdUMxOERcdUMxMzFcdUM3NDQgXHVDMTIwXHVDNUI4XHVENTYwIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuCi0gICAgICAgIFJvb3RFbGVtZW50VHlwZU11c3RNYXRjaERvY3R5cGVkZWNsID0gXHVCQjM4XHVDMTFDIFx1QjhFOFx1RDJCOCBcdUM2OTRcdUMxOEMgInsxfSJcdUM3NDAoXHVCMjk0KSBET0NUWVBFIFx1QjhFOFx1RDJCOCAiezB9Ilx1QUNGQyhcdUM2NDApIFx1Qzc3Q1x1Q0U1OFx1RDU3NFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIFVuZGVjbGFyZWRFbGVtZW50SW5Db250ZW50U3BlYyA9ICJ7MH0iIFx1QzY5NFx1QzE4Q1x1Qzc1OCBcdUNGNThcdUQxNTBcdUNFMjAgXHVCQUE4XHVCMzc4XHVDNzc0IFx1QzEyMFx1QzVCOFx1QjQxOFx1QzlDMCBcdUM1NEFcdUM3NDAgXHVDNjk0XHVDMThDICJ7MX0iXHVDNzQ0KFx1Qjk3QykgXHVDQzM4XHVDODcwXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBVbmlxdWVOb3RhdGlvbk5hbWUgPSAiezB9IiBcdUQ0NUNcdUFFMzBcdUJDOTVcdUM1RDAgXHVCMzAwXHVENTVDIFx1QzEyMFx1QzVCOFx1Qzc3NCBcdUFDRTBcdUM3MjBcdUQ1NThcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0LiBcdUM4MUNcdUFDRjVcdUI0MUMgXHVDNzc0XHVCOTg0XHVDNzQwIFx1QjQ1MCBcdUFDMUMgXHVDNzc0XHVDMEMxXHVDNzU4IFx1RDQ1Q1x1QUUzMFx1QkM5NSBcdUMxMjBcdUM1QjhcdUM1RDBcdUMxMUMgXHVDMTIwXHVDNUI4XHVCNDE4XHVDOUMwIFx1QzU0QVx1QzU0NFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIEVOVElUWUZhaWxlZEluaXRpYWxpemVHcmFtbWFyID0gIEVOVElUWURhdGF0eXBlIFx1QUM4MFx1Qzk5RFx1QUUzMDogXHVDMkU0XHVEMzI4XHVENTg4XHVDMkI1XHVCMkM4XHVCMkU0LiBcdUM4MDFcdUQ1NjlcdUQ1NUMgXHVCQjM4XHVCQzk1IFx1Q0MzOFx1Qzg3MFx1Qjg1QyBcdUNEMDhcdUFFMzBcdUQ2NTQgXHVCQTU0XHVDMThDXHVCNERDXHVCOTdDIFx1RDYzOFx1Q0Q5Q1x1RDU3NFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuIFx0Ci0gICAgICAgIEVOVElUWU5vdFVucGFyc2VkID0gRU5USVRZICJ7MH0iXHVDNzU4IFx1QUQ2Q1x1QkIzOFx1Qzc3NCBcdUJEODRcdUMxMURcdUI0MThcdUM5QzAgXHVDNTRBXHVDNTU4XHVDMkI1XHVCMkM4XHVCMkU0LgotICAgICAgICBFTlRJVFlOb3RWYWxpZCA9IEVOVElUWSAiezB9Ilx1Qzc3NChcdUFDMDApIFx1QkQ4MFx1QzgwMVx1RDU2OVx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgRW1wdHlMaXN0ID0gRU5USVRJRVMsIElEUkVGUyBcdUJDMEYgTk1UT0tFTlMgXHVDNzIwXHVENjE1XHVDNzU4IFx1QUMxMlx1Qzc0MCBcdUJFNDggXHVCQUE5XHVCODVEXHVDNzdDIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuCi0KLSMgRW50aXR5IHJlbGF0ZWQgbWVzc2FnZXMKLSMgMy4xIFN0YXJ0LVRhZ3MsIEVuZC1UYWdzLCBhbmQgRW1wdHktRWxlbWVudCBUYWdzCi0gICAgICAgIFJlZmVyZW5jZVRvRXh0ZXJuYWxFbnRpdHkgPSBcdUMxOERcdUMxMzFcdUFDMTJcdUM1RDBcdUMxMUNcdUIyOTQgXHVDNjc4XHVCRDgwIFx1QzVENFx1RDJGMFx1RDJGMCBcdUNDMzhcdUM4NzAgIiZ7MH07Ilx1Qzc3NCBcdUQ1QzhcdUM2QTlcdUI0MThcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0LgotICAgICAgICBBY2Nlc3NFeHRlcm5hbERURCA9IFx1QzY3OFx1QkQ4MCBEVEQ6IGFjY2Vzc0V4dGVybmFsRFREIFx1QzE4RFx1QzEzMVx1QzczQ1x1Qjg1QyBcdUMxMjRcdUM4MTVcdUI0MUMgXHVDODFDXHVENTVDXHVDNzNDXHVCODVDIFx1Qzc3OFx1RDU3NCAnJ3sxfScnIFx1QzU2MVx1QzEzOFx1QzJBNFx1QUMwMCBcdUQ1QzhcdUM2QTlcdUI0MThcdUM5QzAgXHVDNTRBXHVDNzNDXHVCQkMwXHVCODVDIFx1QzY3OFx1QkQ4MCBEVEQgJyd7MH0nJyBcdUM3N0RcdUFFMzBcdUI5N0MgXHVDMkU0XHVEMzI4XHVENTg4XHVDMkI1XHVCMkM4XHVCMkU0LgotICAgICAgICBBY2Nlc3NFeHRlcm5hbEVudGl0eSA9IFx1QzY3OFx1QkQ4MCBcdUM1RDRcdUQyRjBcdUQyRjA6IGFjY2Vzc0V4dGVybmFsRFREIFx1QzE4RFx1QzEzMVx1QzczQ1x1Qjg1QyBcdUMxMjRcdUM4MTVcdUI0MUMgXHVDODFDXHVENTVDXHVDNzNDXHVCODVDIFx1Qzc3OFx1RDU3NCAnJ3sxfScnIFx1QzU2MVx1QzEzOFx1QzJBNFx1QUMwMCBcdUQ1QzhcdUM2QTlcdUI0MThcdUM5QzAgXHVDNTRBXHVDNzNDXHVCQkMwXHVCODVDIFx1QzY3OFx1QkQ4MCBcdUJCMzhcdUMxMUMgJyd7MH0nJyBcdUM3N0RcdUFFMzBcdUI5N0MgXHVDMkU0XHVEMzI4XHVENTg4XHVDMkI1XHVCMkM4XHVCMkU0LgotCi0jIDQuMSBDaGFyYWN0ZXIgYW5kIEVudGl0eSBSZWZlcmVuY2VzCi0gICAgICAgIEVudGl0eU5vdERlY2xhcmVkID0gInswfSIgXHVDNUQ0XHVEMkYwXHVEMkYwXHVBQzAwIFx1Q0MzOFx1Qzg3MFx1QjQxOFx1QzVDOFx1QzlDMFx1QjlDQyBcdUMxMjBcdUM1QjhcdUI0MThcdUM5QzAgXHVDNTRBXHVDNTU4XHVDMkI1XHVCMkM4XHVCMkU0LgotICAgICAgICBSZWZlcmVuY2VUb1VucGFyc2VkRW50aXR5ID0gXHVBRDZDXHVCQjM4XHVDNzc0IFx1QkQ4NFx1QzExRFx1QjQxOFx1QzlDMCBcdUM1NEFcdUM3NDAgXHVDNUQ0XHVEMkYwXHVEMkYwIFx1Q0MzOFx1Qzg3MCAiJnswfTsiXHVDNzQwKFx1QjI5NCkgXHVENUM4XHVDNkE5XHVCNDE4XHVDOUMwIFx1QzU0QVx1QzJCNVx1QjJDOFx1QjJFNC4KLSAgICAgICAgUmVjdXJzaXZlUmVmZXJlbmNlID0gInswfSJcdUM3NDAoXHVCMjk0KSBcdUMyMUNcdUQ2NTggXHVDNUQ0XHVEMkYwXHVEMkYwIFx1Q0MzOFx1Qzg3MFx1Qzc4NVx1QjJDOFx1QjJFNChcdUNDMzhcdUM4NzAgXHVBQ0JEXHVCODVDOiB7MX0pLgotICAgICAgICBSZWN1cnNpdmVHZW5lcmFsUmVmZXJlbmNlID0gIiZ7MH07Ilx1Qzc0MCBcdUMyMUNcdUQ2NTggXHVDNzdDXHVCQzE4IFx1QzVENFx1RDJGMFx1RDJGMCBcdUNDMzhcdUM4NzBcdUM3ODVcdUIyQzhcdUIyRTQoXHVDQzM4XHVDODcwIFx1QUNCRFx1Qjg1QzogezF9KS4KLSAgICAgICAgUmVjdXJzaXZlUEVSZWZlcmVuY2UgPSAiJXswfTsiXHVDNzQwIFx1QzIxQ1x1RDY1OCBcdUI5RTRcdUFDMUNcdUJDQzBcdUMyMTggXHVDNUQ0XHVEMkYwXHVEMkYwIFx1Q0MzOFx1Qzg3MFx1Qzc4NVx1QjJDOFx1QjJFNChcdUNDMzhcdUM4NzAgXHVBQ0JEXHVCODVDOiB7MX0pLgotIyA0LjMuMyBDaGFyYWN0ZXIgRW5jb2RpbmcgaW4gRW50aXRpZXMKLSAgICAgICAgRW5jb2RpbmdOb3RTdXBwb3J0ZWQgPSAiezB9IiBcdUM3NzhcdUNGNTRcdUI1MjlcdUM3NDAgXHVDOUMwXHVDNkQwXHVCNDE4XHVDOUMwIFx1QzU0QVx1QzJCNVx1QjJDOFx1QjJFNC4KLSAgICAgICAgRW5jb2RpbmdSZXF1aXJlZCA9IFVURi04IFx1QjYxMFx1QjI5NCBVVEYtMTZcdUM3M0NcdUI4NUMgXHVDNzc4XHVDRjU0XHVCNTI5XHVCNDE4XHVDOUMwIFx1QzU0QVx1Qzc0MCBcdUFENkNcdUJCMzhcdUM3NzQgXHVCRDg0XHVDMTFEXHVCNDFDIFx1QzVENFx1RDJGMFx1RDJGMFx1QzVEMFx1QjI5NCBcdUM3NzhcdUNGNTRcdUI1MjkgXHVDMTIwXHVDNUI4XHVDNzc0IFx1RDNFQ1x1RDU2OFx1QjQxOFx1QzVCNFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIAotIyBOYW1lc3BhY2VzIHN1cHBvcnQKLSMgNC4gVXNpbmcgUXVhbGlmaWVkIE5hbWVzCi0gICAgICAgIElsbGVnYWxRTmFtZSA9IFx1QzY5NFx1QzE4QyBcdUI2MTBcdUIyOTQgXHVDMThEXHVDMTMxXHVDNzc0IFFOYW1lIFx1Qzc5MVx1QzEzMVx1QUNGQyBcdUM3N0NcdUNFNThcdUQ1NThcdUM5QzAgXHVDNTRBXHVDNzRDOiBRTmFtZTo6PShOQ05hbWUnOicpP05DTmFtZS4gCi0gICAgICAgIEVsZW1lbnRYTUxOU1ByZWZpeCA9ICJ7MH0iIFx1QzY5NFx1QzE4Q1x1QzVEMFx1QjI5NCAieG1sbnMiXHVBQzAwIFx1QzgxMVx1QjQ1MFx1QzVCNFx1Qjg1QyBcdUMwQUNcdUM2QTlcdUI0MjAgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4KLSAgICAgICAgRWxlbWVudFByZWZpeFVuYm91bmQgPSAiezF9IiBcdUM2OTRcdUMxOENcdUM1RDAgXHVCMzAwXHVENTVDICJ7MH0iIFx1QzgxMVx1QjQ1MFx1QzVCNFx1QUMwMCBcdUJDMTRcdUM3NzhcdUI0RENcdUI0MThcdUM5QzAgXHVDNTRBXHVDNTU4XHVDMkI1XHVCMkM4XHVCMkU0LgotICAgICAgICBBdHRyaWJ1dGVQcmVmaXhVbmJvdW5kID0gXHVDNjk0XHVDMThDIFx1QzcyMFx1RDYxNSAiezB9Ilx1QUNGQyhcdUM2NDApIFx1QzVGMFx1QUQwMFx1QjQxQyAiezF9IiBcdUMxOERcdUMxMzFcdUM3NTggInsyfSIgXHVDODExXHVCNDUwXHVDNUI0XHVBQzAwIFx1QkMxNFx1Qzc3OFx1QjREQ1x1QjQxOFx1QzlDMCBcdUM1NEFcdUM1NThcdUMyQjVcdUIyQzhcdUIyRTQuCi0gICAgICAgIEVtcHR5UHJlZml4ZWRBdHROYW1lID0gInswfSIgXHVDMThEXHVDMTMxXHVDNzU4IFx1QUMxMlx1Qzc3NCBcdUJEODBcdUM4MDFcdUQ1NjlcdUQ1NjlcdUIyQzhcdUIyRTQuIFx1QzgxMVx1QjQ1MFx1QzVCNFx1QUMwMCBcdUM5QzBcdUM4MTVcdUI0MUMgXHVCMTI0XHVDNzg0XHVDMkE0XHVEMzk4XHVDNzc0XHVDMkE0IFx1QkMxNFx1Qzc3OFx1QjUyOVx1Qzc0MCBcdUJFNDRcdUM2Q0MgXHVCNDU4IFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuCi0gICAgICAgIFByZWZpeERlY2xhcmVkID0gXHVCMTI0XHVDNzg0XHVDMkE0XHVEMzk4XHVDNzc0XHVDMkE0IFx1QzgxMVx1QjQ1MFx1QzVCNCAiezB9Ilx1Qzc3NChcdUFDMDApIFx1QzEyMFx1QzVCOFx1QjQxOFx1QzlDMCBcdUM1NEFcdUM1NThcdUMyQjVcdUIyQzhcdUIyRTQuCi0gICAgICAgIENhbnRCaW5kWE1MTlMgPSAieG1sbnMiIFx1QzgxMVx1QjQ1MFx1QzVCNFx1QjI5NCBcdUJBODVcdUMyRENcdUM4MDFcdUM3M0NcdUI4NUMgXHVCMTI0XHVDNzg0XHVDMkE0XHVEMzk4XHVDNzc0XHVDMkE0XHVDNUQwIFx1QkMxNFx1Qzc3OFx1QjREQ1x1QjQyMCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiAieG1sbnMiXHVDNUQwIFx1QjMwMFx1RDU1QyBcdUIxMjRcdUM3ODRcdUMyQTRcdUQzOThcdUM3NzRcdUMyQTRcdUIzQzQgXHVCQTg1XHVDMkRDXHVDODAxXHVDNzNDXHVCODVDIFx1QzgxMVx1QjQ1MFx1QzVCNFx1QzVEMCBcdUJDMTRcdUM3NzhcdUI0RENcdUI0MjAgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4KLSAgICAgICAgQ2FudEJpbmRYTUwgPSAieG1sIiBcdUM4MTFcdUI0NTBcdUM1QjRcdUIyOTQgXHVDNzdDXHVCQzE4IFx1QjEyNFx1Qzc4NFx1QzJBNFx1RDM5OFx1Qzc3NFx1QzJBNFx1QUMwMCBcdUM1NDRcdUIyQ0MgXHVCMkU0XHVCOTc4IFx1QjEyNFx1Qzc4NFx1QzJBNFx1RDM5OFx1Qzc3NFx1QzJBNFx1QzVEMCBcdUJDMTRcdUM3NzhcdUI0RENcdUI0MjAgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4gInhtbCJcdUM1RDAgXHVCMzAwXHVENTVDIFx1QjEyNFx1Qzc4NFx1QzJBNFx1RDM5OFx1Qzc3NFx1QzJBNFx1QjNDNCAieG1sIiBcdUM3NzRcdUM2NzhcdUM3NTggXHVDODExXHVCNDUwXHVDNUI0XHVDNUQwIFx1QkMxNFx1Qzc3OFx1QjREQ1x1QjQyMCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LgotICAgICAgICBNU0dfQVRUX0RFRkFVTFRfSU5WQUxJRCA9ICJ7MH0iIFx1QzE4RFx1QzEzMVx1Qzc1OCBkZWZhdWx0VmFsdWUgInsxfSJcdUM3NDAoXHVCMjk0KSBcdUM3NzQgXHVDMThEXHVDMTMxIFx1QzcyMFx1RDYxNVx1Qzc1OCBcdUI4MDlcdUMyRENcdUNFN0MgXHVDODFDXHVDNTdEIFx1Qzg3MFx1QUM3NFx1QzVEMCBcdUIzMDBcdUQ1NUMgXHVBQzEyXHVDNzNDXHVCODVDIFx1QkQ4MFx1QzgwMVx1RDU2OVx1RDU2OVx1QjJDOFx1QjJFNC4KLQotIyBSRVZJU0lUOiBUaGVzZSBuZWVkIG1lc3NhZ2VzCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9BRlRFUl9TWVNURU1MSVRFUkFMX0lOX0VYVEVSTkFMSUQ9TVNHX1NQQUNFX1JFUVVJUkVEX0FGVEVSX1NZU1RFTUxJVEVSQUxfSU5fRVhURVJOQUxJRAotICAgICAgICBPcGVuUXVvdGVNaXNzaW5nSW5EZWNsPU9wZW5RdW90ZU1pc3NpbmdJbkRlY2wKLSAgICAgICAgSW52YWxpZENoYXJJbkxpdGVyYWw9SW52YWxpZENoYXJJbkxpdGVyYWwKLQotCi0jIEltcGxlbWVudGF0aW9uIGxpbWl0cwotICAgICAgICBFbnRpdHlFeHBhbnNpb25MaW1pdD1KQVhQMDAwMTAwMDE6IFx1QUQ2Q1x1QkIzOCBcdUJEODRcdUMxMURcdUFFMzBcdUFDMDAgXHVDNzc0IFx1QkIzOFx1QzExQ1x1QzVEMFx1QzExQyAiezB9Ilx1QUMxQ1x1Qjk3QyBcdUNEMDhcdUFDRkNcdUQ1NThcdUIyOTQgXHVDNUQ0XHVEMkYwXHVEMkYwIFx1RDY1NVx1QzdBNVx1Qzc0NCBcdUJDMUNcdUFDQUNcdUQ1ODhcdUMyQjVcdUIyQzhcdUIyRTQuIFx1Qzc3NFx1QjI5NCBKREtcdUM1RDBcdUMxMUMgXHVDODAxXHVDNkE5XHVENTU4XHVCMjk0IFx1QzgxQ1x1RDU1Q1x1Qzc4NVx1QjJDOFx1QjJFNC4KLSAgICAgICAgRWxlbWVudEF0dHJpYnV0ZUxpbWl0PUpBWFAwMDAxMDAwMjogICJ7MH0iIFx1QzY5NFx1QzE4Q1x1QzVEMCAiezF9Ilx1QUMxQ1x1Qjk3QyBcdUNEMDhcdUFDRkNcdUQ1NThcdUIyOTQgXHVDMThEXHVDMTMxXHVDNzc0IFx1Qzc4OFx1QzJCNVx1QjJDOFx1QjJFNC4gInsxfSJcdUM3NDAoXHVCMjk0KSBKREtcdUM1RDBcdUMxMUMgXHVDODAxXHVDNkE5XHVENTU4XHVCMjk0IFx1QzgxQ1x1RDU1Q1x1Qzc4NVx1QjJDOFx1QjJFNC4KLSAgICAgICAgTWF4RW50aXR5U2l6ZUxpbWl0PUpBWFAwMDAxMDAwMzogInswfSIgXHVDNUQ0XHVEMkYwXHVEMkYwXHVDNzU4IFx1QUUzOFx1Qzc3NFx1QUMwMCAiezN9Ilx1QzVEMFx1QzExQyBcdUMxMjRcdUM4MTVcdUI0MUMgInsyfSIgXHVDODFDXHVENTVDXHVDNzQ0IFx1Q0QwOFx1QUNGQ1x1RDU1OFx1QjI5NCAiezF9Ilx1Qzc4NVx1QjJDOFx1QjJFNC4KLSAgICAgICAgVG90YWxFbnRpdHlTaXplTGltaXQ9SkFYUDAwMDEwMDA0OiBcdUM1RDRcdUQyRjBcdUQyRjBcdUM3NTggXHVCMjA0XHVDODAxIFx1RDA2Q1x1QUUzMFx1QUMwMCAiezJ9Ilx1QzVEMFx1QzExQyBcdUMxMjRcdUM4MTVcdUQ1NUMgInsxfSIgXHVDODFDXHVENTVDXHVDNzQ0IFx1Q0QwOFx1QUNGQ1x1RDU1OFx1QjI5NCAiezB9Ilx1Qzc4NVx1QjJDOFx1QjJFNC4KLSAgICAgICAgTWF4WE1MTmFtZUxpbWl0PUpBWFAwMDAxMDAwNTogInswfSIgXHVDNUQ0XHVEMkYwXHVEMkYwXHVDNzU4IFx1QUUzOFx1Qzc3NFx1QUMwMCAiezN9Ilx1QzVEMFx1QzExQyBcdUMxMjRcdUM4MTVcdUQ1NUMgInsyfSIgXHVDODFDXHVENTVDXHVDNzQ0IFx1Q0QwOFx1QUNGQ1x1RDU1OFx1QjI5NCAiezF9Ilx1Qzc4NVx1QjJDOFx1QjJFNC4KLSAgICAgICAgTWF4RWxlbWVudERlcHRoTGltaXQ9SkFYUDAwMDEwMDA2OiAiezB9IiBcdUM2OTRcdUMxOENcdUM3NTggXHVBRTRBXHVDNzc0XHVBQzAwICJ7M30iXHVDNUQwXHVDMTFDIFx1QzEyNFx1QzgxNVx1QjQxQyAiezJ9IiBcdUM4MUNcdUQ1NUNcdUM3NDQgXHVDRDA4XHVBQ0ZDXHVENTU4XHVCMjk0ICJ7MX0iXHVDNzg1XHVCMkM4XHVCMkU0LgotICAgICAgICBFbnRpdHlSZXBsYWNlbWVudExpbWl0PUpBWFAwMDAxMDAwNzogXHVDNUQ0XHVEMkYwXHVEMkYwIFx1Q0MzOFx1Qzg3MFx1Qzc1OCBcdUNEMUQgXHVCMTc4XHVCNERDIFx1QzIxOFx1QUMwMCAiezJ9Ilx1QzVEMFx1QzExQyBcdUMxMjRcdUM4MTVcdUQ1NUMgInsxfSIgXHVDODFDXHVENTVDXHVDNzQ0IFx1Q0QwOFx1QUNGQ1x1RDU1OFx1QjI5NCAiezB9Ilx1Qzc4NVx1QjJDOFx1QjJFNC4KLQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MTWVzc2FnZXNfcHRfQlIucHJvcGVydGllcyBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hNTE1lc3NhZ2VzX3B0X0JSLnByb3BlcnRpZXMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDkzYWU0OGUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MTWVzc2FnZXNfcHRfQlIucHJvcGVydGllcworKysgL2Rldi9udWxsCkBAIC0xLDMwNSArMCwwIEBACi0jIFRoaXMgZmlsZSBjb250YWlucyBlcnJvciBhbmQgd2FybmluZyBtZXNzYWdlcyByZWxhdGVkIHRvIFhNTAotIyBUaGUgbWVzc2FnZXMgYXJlIGFycmFuZ2VkIGluIGtleSBhbmQgdmFsdWUgdHVwbGVzIGluIGEgTGlzdFJlc291cmNlQnVuZGxlLgotIwotIyBAdmVyc2lvbgotCi0gICAgICAgIEJhZE1lc3NhZ2VLZXkgPSBOXHUwMEUzbyBmb2kgcG9zc1x1MDBFRHZlbCBlbmNvbnRyYXIgYSBtZW5zYWdlbSBkZSBlcnJvIGNvcnJlc3BvbmRlbnRlIFx1MDBFMCBjaGF2ZSBkYSBtZW5zYWdlbS4KLSAgICAgICAgRm9ybWF0RmFpbGVkID0gT2NvcnJldSB1bSBlcnJvIGludGVybm8gYW8gZm9ybWF0YXIgYSBtZW5zYWdlbSBhIHNlZ3VpcjpcbiAgCi0gICAgICAgIAotIyBEb2N1bWVudCBtZXNzYWdlcwotICAgICAgICBQcmVtYXR1cmVFT0Y9RmltIHByZW1hdHVybyBkbyBhcnF1aXZvLgotIyAyLjEgV2VsbC1Gb3JtZWQgWE1MIERvY3VtZW50cwotICAgICAgICBSb290RWxlbWVudFJlcXVpcmVkID0gTyBlbGVtZW50by1yYWl6IFx1MDBFOSBuZWNlc3NcdTAwRTFyaW8gZW0gdW0gZG9jdW1lbnRvIGNvcnJldG8uCi0jIDIuMiBDaGFyYWN0ZXJzCi0KLSAgICAgICAgSW52YWxpZENoYXJJbkNEU2VjdCA9IFVtIGNhcmFjdGVyZSBYTUwgaW52XHUwMEUxbGlkbyAoVW5pY29kZTogMHh7MH0pIGZvaSBlbmNvbnRyYWRvIG5hIHNlXHUwMEU3XHUwMEUzbyBDREFUQS4KLSAgICAgICAgSW52YWxpZENoYXJJbkNvbnRlbnQgPSBVbSBjYXJhY3RlcmUgWE1MIGludlx1MDBFMWxpZG8gKFVuaWNvZGU6IDB4IHswfSkgZm9pIGVuY29udHJhZG8gbm8gY29udGVcdTAwRkFkbyBkbyBlbGVtZW50byBkbyBkb2N1bWVudG8uCi0gICAgICAgIFR3b0NvbG9uc0luUU5hbWUgPSBVbSBzZWd1bmRvICc6JyBpbnZcdTAwRTFsaWRvIGZvaSBlbmNvbnRyYWRvIG5vIHRpcG8gZGUgZWxlbWVudG8gb3Ugbm8gbm9tZSBkbyBhdHJpYnV0by4KLSAgICAgICAgQ29sb25Ob3RMZWdhbFdpdGhOUyA9IE5cdTAwRTNvIFx1MDBFOSBwZXJtaXRpZG8gdXNhciBkb2lzLXBvbnRvcyBubyBub21lICcnezB9JycgcXVhbmRvIG5hbWVzcGFjZXMgZXN0aXZlcmVtIGF0aXZhZG9zLgotICAgICAgICBJbnZhbGlkQ2hhckluTWlzYyA9IFVtIGNhcmFjdGVyZSBYTUwgaW52XHUwMEUxbGlkbyAoVW5pY29kZTogMHggezB9KSBmb2kgZW5jb250cmFkbyBuYSBtYXJjYVx1MDBFN1x1MDBFM28gYXBcdTAwRjNzIG8gZmltIGRvIGNvbnRlXHUwMEZBZG8gZG8gZWxlbWVudG8uCi0gICAgICAgIEludmFsaWRDaGFySW5Qcm9sb2cgPSBVbSBjYXJhY3RlcmUgWE1MIGludlx1MDBFMWxpZG8gKFVuaWNvZGU6IDB4IHswfSkgZm9pIGVuY29udHJhZG8gbm8gcHJcdTAwRjNsb2dvIGRvIGRvY3VtZW50by4KLSAgICAgICAgSW52YWxpZENoYXJJblhNTERlY2wgPSBVbSBjYXJhY3RlcmUgWE1MIGludlx1MDBFMWxpZG8gKFVuaWNvZGU6IDB4ezB9KSBmb2kgZW5jb250cmFkbyBuYSBkZWNsYXJhXHUwMEU3XHUwMEUzbyBYTUwuCi0jIDIuNCBDaGFyYWN0ZXIgRGF0YSBhbmQgTWFya3VwCi0gICAgICAgIENERW5kSW5Db250ZW50ID0gQSBzZXF1XHUwMEVBbmNpYSBkZSBjYXJhY3RlcmVzICJdXT4iIG5cdTAwRTNvIGRldmUgYXBhcmVjZXIgbm8gY29udGVcdTAwRkFkbywgYSBtZW5vcyBxdWUgc2VqYSB1c2FkYSBwYXJhIG1hcmNhciBvIGZpbSBkZSB1bWEgc2VcdTAwRTdcdTAwRTNvIENEQVRBLgotIyAyLjcgQ0RBVEEgU2VjdGlvbnMKLSAgICAgICAgQ0RTZWN0VW50ZXJtaW5hdGVkID0gQSBzZVx1MDBFN1x1MDBFM28gQ0RBVEEgZGV2ZSB0ZXJtaW5hciBjb20gIl1dPiIuCi0jIDIuOCBQcm9sb2cgYW5kIERvY3VtZW50IFR5cGUgRGVjbGFyYXRpb24KLSAgICAgICAgWE1MRGVjbE11c3RCZUZpcnN0ID0gQSBkZWNsYXJhXHUwMEU3XHUwMEUzbyBYTUwgcG9kZSBhcGFyZWNlciBzb21lbnRlIGJlbSBubyBpblx1MDBFRGNpbyBkbyBkb2N1bWVudG8uCi0gICAgICAgIEVxUmVxdWlyZWRJblhNTERlY2wgPSBPIGNhcmFjdGVyZSAnJyA9ICcnIGRldmUgZXN0YXIgYXBcdTAwRjNzICJ7MH0iIG5hIGRlY2xhcmFcdTAwRTdcdTAwRTNvIFhNTC4KLSAgICAgICAgUXVvdGVSZXF1aXJlZEluWE1MRGVjbCA9IE8gdmFsb3IgYXBcdTAwRjNzICJ7MH0iIG5hIGRlY2xhcmFcdTAwRTdcdTAwRTNvIFhNTCBkZXZlIHNlciB1bWEgc3RyaW5nIGVudHJlIGFzcGFzLgotICAgICAgICBYTUxEZWNsVW50ZXJtaW5hdGVkID0gQSBkZWNsYXJhXHUwMEU3XHUwMEUzbyBYTUwgZGV2ZSB0ZXJtaW5hciBjb20gIj8+Ii4KLSAgICAgICAgVmVyc2lvbkluZm9SZXF1aXJlZCA9IEEgdmVyc1x1MDBFM28gXHUwMEU5IG9icmlnYXRcdTAwRjNyaWEgbmEgZGVjbGFyYVx1MDBFN1x1MDBFM28gWE1MLgotICAgICAgICBTcGFjZVJlcXVpcmVkQmVmb3JlVmVyc2lvbkluWE1MRGVjbCA9IE8gZXNwYVx1MDBFN28gZW0gYnJhbmNvIFx1MDBFOSBuZWNlc3NcdTAwRTFyaW8gYW50ZXMgZG8gcHNldWRvLWF0cmlidXRvIGRhIHZlcnNcdTAwRTNvIG5hIGRlY2xhcmFcdTAwRTdcdTAwRTNvIFhNTC4KLSAgICAgICAgU3BhY2VSZXF1aXJlZEJlZm9yZUVuY29kaW5nSW5YTUxEZWNsID0gTyBlc3BhXHUwMEU3byBlbSBicmFuY28gXHUwMEU5IG5lY2Vzc1x1MDBFMXJpbyBhbnRlcyBkZSBjb2RpZmljYXIgbyBwc2V1ZG8tYXRyaWJ1dG8gbmEgZGVjbGFyYVx1MDBFN1x1MDBFM28gWE1MLgotICAgICAgICBTcGFjZVJlcXVpcmVkQmVmb3JlU3RhbmRhbG9uZSA9IE8gZXNwYVx1MDBFN28gZW0gYnJhbmNvIFx1MDBFOSBuZWNlc3NcdTAwRTFyaW8gYW50ZXMgZGUgY29kaWZpY2FyIG8gcHNldWRvLWF0cmlidXRvIG5hIGRlY2xhcmFcdTAwRTdcdTAwRTNvIFhNTC4KLSAgICAgICAgTWFya3VwTm90UmVjb2duaXplZEluUHJvbG9nID0gQSBtYXJjYVx1MDBFN1x1MDBFM28gbm8gZG9jdW1lbnRvIHF1ZSBwcmVjZWRlIG8gZWxlbWVudG8tcmFpeiBkZXZlIGVzdGFyIGNvcnJldGEuCi0gICAgICAgIE1hcmt1cE5vdFJlY29nbml6ZWRJbk1pc2MgPSBBIG1hcmNhXHUwMEU3XHUwMEUzbyBubyBkb2N1bWVudG8gYXBcdTAwRjNzIG8gZWxlbWVudG8tcmFpeiBkZXZlIGVzdGFyIGNvcnJldGEuCi0gICAgICAgIEFscmVhZHlTZWVuRG9jdHlwZSA9IFRpcG8gZGUgZG9jdW1lbnRvIGpcdTAwRTEgdmlzdG8uCi0gICAgICAgIERvY3R5cGVOb3RBbGxvd2VkID0gRE9DVFlQRSBmaWNhIGRlc2F0aXZhZG8gcXVhbmRvIG8gcmVjdXJzbyAiaHR0cDovL2FwYWNoZS5vcmcveG1sL2ZlYXR1cmVzL2Rpc2FsbG93LWRvY3R5cGUtZGVjbCIgXHUwMEU5IGRlZmluaWRvIGNvbW8gdmVyZGFkZWlyby4KLSAgICAgICAgQ29udGVudElsbGVnYWxJblByb2xvZyA9IE8gY29udGVcdTAwRkFkbyBuXHUwMEUzbyBcdTAwRTkgcGVybWl0aWRvIG5vIHByXHUwMEYzbG9nby4KLSAgICAgICAgUmVmZXJlbmNlSWxsZWdhbEluUHJvbG9nID0gQSByZWZlclx1MDBFQW5jaWEgblx1MDBFM28gXHUwMEU5IHBlcm1pdGlkYSBubyBwclx1MDBGM2xvZ28uCi0jIFRyYWlsaW5nIE1pc2MKLSAgICAgICAgQ29udGVudElsbGVnYWxJblRyYWlsaW5nTWlzYz1PIGNvbnRlXHUwMEZBZG8gblx1MDBFM28gXHUwMEU5IHBlcm1pdGlkbyBuYSBzZVx1MDBFN1x1MDBFM28gXHUwMEUwIGVzcXVlcmRhLgotICAgICAgICBSZWZlcmVuY2VJbGxlZ2FsSW5UcmFpbGluZ01pc2M9QSByZWZlclx1MDBFQW5jaWEgblx1MDBFM28gXHUwMEU5IHBlcm1pdGlkYSBuYSBzZVx1MDBFN1x1MDBFM28gXHUwMEUwIGVzcXVlcmRhLgotICAgICAgICAKLSMgMi45IFN0YW5kYWxvbmUgRG9jdW1lbnQgRGVjbGFyYXRpb24KLSAgICAgICAgU0REZWNsSW52YWxpZCA9IE8gdmFsb3IgZGEgZGVjbGFyYVx1MDBFN1x1MDBFM28gZG8gZG9jdW1lbnRvIHN0YW5kLWFsb25lIGRldmUgc2VyICJzaW0iIG91ICJuXHUwMEUzbyIsIG1hcyBuXHUwMEUzbyBkZXZlIHNlciAiezB9Ii4KLSAgICAgICAgU0REZWNsTmFtZUludmFsaWQgPSBPIG5vbWUgc3RhbmRhbG9uZSBuYSBkZWNsYXJhXHUwMEU3XHUwMEUzbyBYTUwgcG9kZSBlc3RhciBncmFmYWRvIGluY29ycmV0YW1lbnRlLgotIyAyLjEyIExhbmd1YWdlIElkZW50aWZpY2F0aW9uCi0gICAgICAgIFhNTExhbmdJbnZhbGlkID0gTyB2YWxvciBkbyBhdHJpYnV0byB4bWw6bGFuZyAiezB9IiBcdTAwRTkgdW0gaWRlbnRpZmljYWRvciBkZSBpZGlvbWEgaW52XHUwMEUxbGlkby4KLSMgMy4gTG9naWNhbCBTdHJ1Y3R1cmVzCi0gICAgICAgIEVUYWdSZXF1aXJlZCA9IE8gdGlwbyBkZSBlbGVtZW50byB7MH0iIGRldmUgc2VyIGVuY2VycmFkbyBwZWxhIHRhZyBmaW5hbCBjb3JyZXNwb25kZW50ZSAiPC97MH0+Ii4KLSMgMy4xIFN0YXJ0LVRhZ3MsIEVuZC1UYWdzLCBhbmQgRW1wdHktRWxlbWVudCBUYWdzCi0gICAgICAgIEVsZW1lbnRVbnRlcm1pbmF0ZWQgPSBPIHRpcG8gZGUgZWxlbWVudG8gInswfSIgZGV2ZSBzZXIgc2VndWlkbyBwZWxhcyBlc3BlY2lmaWNhXHUwMEU3XHUwMEY1ZXMgZG8gYXRyaWJ1dG8sICI+IiBvdSAiLz4iLgotICAgICAgICBFcVJlcXVpcmVkSW5BdHRyaWJ1dGUgPSBPIG5vbWUgZG8gYXRyaWJ1dG8gInsxfSIgYXNzb2NpYWRvIGEgdW0gdGlwbyBkZSBlbGVtZW50byAiezB9IiBkZXZlIHNlciBzZWd1aWRvIGRvIGNhcmFjdGVyZSAnJyA9ICcnLgotICAgICAgICBPcGVuUXVvdGVFeHBlY3RlZCA9IFNcdTAwRTNvIGVzcGVyYWRhcyBhc3BhcyBkZSBhYmVydHVyYSBwYXJhIG8gYXRyaWJ1dG8gInsxfSIgYXNzb2NpYWRvIGEgdW0gdGlwbyBkZSBlbGVtZW50byAiezB9Ii4KLSAgICAgICAgQ2xvc2VRdW90ZUV4cGVjdGVkID0gU1x1MDBFM28gZXNwZXJhZGFzIGFzcGFzIGRlIGZlY2hhbWVudG8gcGFyYSBvIGF0cmlidXRvICJ7MX0iIGFzc29jaWFkbyBhIHVtIHRpcG8gZGUgZWxlbWVudG8gInswfSIuCi0gICAgICAgIEF0dHJpYnV0ZU5vdFVuaXF1ZSA9IE8gYXRyaWJ1dG8gInsxfSIgalx1MDBFMSBmb2kgZXNwZWNpZmljYWRvIHBhcmEgbyBlbGVtZW50byAiezB9Ii4KLSAgICAgICAgQXR0cmlidXRlTlNOb3RVbmlxdWUgPSBPIGF0cmlidXRvICJ7MX0iIHZpbmN1bGFkbyBhbyBuYW1lc3BhY2UgInsyfSIgalx1MDBFMSBmb2kgZXNwZWNpZmljYWRvIHBhcmEgbyBlbGVtZW50byAiezB9Ii4KLSAgICAgICAgRVRhZ1VudGVybWluYXRlZCA9IEEgdGFnIGZpbmFsIGRvIHRpcG8gZGUgZWxlbWVudG8gInswfSIgZGV2ZSB0ZXJtaW5hciBjb20gdW0gZGVsaW1pdGFkb3IgJyc+Ii4KLSAgICAgICAgTWFya3VwTm90UmVjb2duaXplZEluQ29udGVudCA9IE8gY29udGVcdTAwRkFkbyBkb3MgZWxlbWVudG9zIGRldmUgY29uc2lzdGlyIGVtIGRhZG9zIG91IG1hcmNhXHUwMEU3XHUwMEUzbyBkbyBjYXJhY3RlcmUgY29ycmV0by4KLSAgICAgICAgRG9jdHlwZUlsbGVnYWxJbkNvbnRlbnQgPSBVbSBET0NUWVBFIG5cdTAwRTNvIFx1MDBFOSBwZXJtaXRpZG8gbm8gY29udGVcdTAwRkFkby4KLSMgNC4xIENoYXJhY3RlciBhbmQgRW50aXR5IFJlZmVyZW5jZXMKLSAgICAgICAgUmVmZXJlbmNlVW50ZXJtaW5hdGVkID0gQSByZWZlclx1MDBFQW5jaWEgZGV2ZSBzZXIgZW5jZXJyYWRhIHBvciB1bSBkZWxpbWl0YWRvciAnOycuCi0jIDQuMy4yIFdlbGwtRm9ybWVkIFBhcnNlZCBFbnRpdGllcwotICAgICAgICBSZWZlcmVuY2VOb3RJbk9uZUVudGl0eSA9IEEgcmVmZXJcdTAwRUFuY2lhIGRldmUgZXN0YXIgdG90YWxtZW50ZSBjb250aWRhIG5hIG1lc21hIGVudGlkYWRlIHN1Ym1ldGlkYSBhIHBhcnNpbmcuCi0gICAgICAgIEVsZW1lbnRFbnRpdHlNaXNtYXRjaCA9IE8gZWxlbWVudG8gInswfSIgZGV2ZSBjb21lXHUwMEU3YXIgZSB0ZXJtaW5hciBjb20gYSBtZXNtYSBlbnRpZGFkZS4KLSAgICAgICAgTWFya3VwRW50aXR5TWlzbWF0Y2g9QXMgZXN0cnV0dXJhcyBkbyBkb2N1bWVudG8gWE1MIGRldmVtIGNvbWVcdTAwRTdhciBlIHRlcm1pbmFyIGNvbSBhIG1lc21hIGVudGlkYWRlLgotICAgICAgICAKLSMgTWVzc2FnZXMgY29tbW9uIHRvIERvY3VtZW50IGFuZCBEVEQKLSMgMi4yIENoYXJhY3RlcnMKLSAgICAgICAgSW52YWxpZENoYXJJbkF0dFZhbHVlID0gVW0gY2FyYWN0ZXJlIFhNTCBpbnZcdTAwRTFsaWRvIChVbmljb2RlOiAweCB7Mn0pIGZvaSBlbmNvbnRyYWRvIG5vIHZhbG9yIGRvIGF0cmlidXRvICJ7MX0iIGUgbyBlbGVtZW50byBcdTAwRTkgInswfSIuCi0gICAgICAgIEludmFsaWRDaGFySW5Db21tZW50ID0gVW0gY2FyYWN0ZXJlIFhNTCBpbnZcdTAwRTFsaWRvIChVbmljb2RlOiAweHswfSkgZm9pIGVuY29udHJhZG8gbm8gY29tZW50XHUwMEUxcmlvLgotICAgICAgICBJbnZhbGlkQ2hhckluUEkgPSBVbSBjYXJhY3RlcmUgWE1MIGludlx1MDBFMWxpZG8gKFVuaWNvZGU6IDB4ezB9KSBmb2kgZW5jb250cmFkbyBuYSBpbnN0cnVcdTAwRTdcdTAwRTNvIGRlIHByb2Nlc3NhbWVudG8uCi0gICAgICAgIEludmFsaWRDaGFySW5JbnRlcm5hbFN1YnNldCA9IFVtIGNhcmFjdGVyZSBYTUwgaW52XHUwMEUxbGlkbyAoVW5pY29kZTogMHggezB9KSBmb2kgZW5jb250cmFkbyBubyBzdWJjb25qdW50byBpbnRlcm5vIGRvIERURC4KLSAgICAgICAgSW52YWxpZENoYXJJblRleHREZWNsID0gVW0gY2FyYWN0ZXJlIFhNTCBpbnZcdTAwRTFsaWRvIChVbmljb2RlOiAweHswfSkgZm9pIGVuY29udHJhZG8gbmEgZGVjbGFyYVx1MDBFN1x1MDBFM28gZGUgdGV4dG8uCi0jIDIuMyBDb21tb24gU3ludGFjdGljIENvbnN0cnVjdHMKLSAgICAgICAgUXVvdGVSZXF1aXJlZEluQXR0VmFsdWUgPSBPIHZhbG9yIGRvIGF0cmlidXRvICJ7MX0iIGRldmUgY29tZVx1MDBFN2FyIGNvbSBhc3BhcyBzaW1wbGVzIG91IGR1cGxhcy4KLSAgICAgICAgTGVzc3RoYW5JbkF0dFZhbHVlID0gTyB2YWxvciBkbyBhdHJpYnV0byAiezF9IiBhc3NvY2lhZG8gYSB1bSB0aXBvIGRlIGVsZW1lbnRvICJ7MH0iIG5cdTAwRTNvIGRldmUgY29udGVyIG8gY2FyYWN0ZXJlICcnPCcnLgotICAgICAgICBBdHRyaWJ1dGVWYWx1ZVVudGVybWluYXRlZCA9IE8gdmFsb3IgZG8gYXRyaWJ1dG8gInsxfSIgZGV2ZSB0ZXJtaW5hciBjb20gYXMgYXNwYXMgY29ycmVzcG9uZGVudGVzLgotIyAyLjUgQ29tbWVudHMKLSAgICAgICAgSW52YWxpZENvbW1lbnRTdGFydCA9IE8gY29tZW50XHUwMEUxcmlvIGRldmUgY29tZVx1MDBFN2FyIGNvbSAiPCEtLSIuCi0gICAgICAgIERhc2hEYXNoSW5Db21tZW50ID0gQSBzdHJpbmcgIi0tIiBuXHUwMEUzbyBcdTAwRTkgcGVybWl0aWRhIG5vcyBjb21lbnRcdTAwRTFyaW9zLgotICAgICAgICBDb21tZW50VW50ZXJtaW5hdGVkID0gTyBjb21lbnRcdTAwRTFyaW8gZGV2ZSB0ZXJtaW5hciBjb20gIi0tPiIuCi0gICAgICAgIENPTU1FTlRfTk9UX0lOX09ORV9FTlRJVFkgPSBPIGNvbWVudFx1MDBFMXJpbyBuXHUwMEUzbyBlc3RcdTAwRTEgZW50cmUgY2hhdmVzIG5hIG1lc21hIGVudGlkYWRlLgotIyAyLjYgUHJvY2Vzc2luZyBJbnN0cnVjdGlvbnMKLSAgICAgICAgUElUYXJnZXRSZXF1aXJlZCA9IEEgaW5zdHJ1XHUwMEU3XHUwMEUzbyBkZSBwcm9jZXNzYW1lbnRvIGRldmUgY29tZVx1MDBFN2FyIGNvbSBvIG5vbWUgZG8gZGVzdGluby4KLSAgICAgICAgU3BhY2VSZXF1aXJlZEluUEkgPSBPIGVzcGFcdTAwRTdvIGVtIGJyYW5jbyBcdTAwRTkgb2JyaWdhdFx1MDBGM3JpbyBlbnRyZSBvIGRlc3Rpbm8gZGEgaW5zdHJ1XHUwMEU3XHUwMEUzbyBkZSBwcm9jZXNzYW1lbnRvIGUgb3MgZGFkb3MuCi0gICAgICAgIFBJVW50ZXJtaW5hdGVkID0gQSBpbnN0cnVcdTAwRTdcdTAwRTNvIGRlIHByb2Nlc3NhbWVudG8gZGV2ZSB0ZXJtaW5hciBjb20gIj8+Ii4KLSAgICAgICAgUmVzZXJ2ZWRQSVRhcmdldCA9IE8gZGVzdGlubyBkYSBpbnN0cnVcdTAwRTdcdTAwRTNvIGRlIHByb2Nlc3NhbWVudG8gY29ycmVzcG9uZGVudGUgIlt4WF1bbU1dW2xMXSIgblx1MDBFM28gXHUwMEU5IHBlcm1pdGlkby4KLSAgICAgICAgUElfTk9UX0lOX09ORV9FTlRJVFkgPSBBIGluc3RydVx1MDBFN1x1MDBFM28gZGUgcHJvY2Vzc2FtZW50byBuXHUwMEUzbyBlc3RcdTAwRTEgZW50cmUgY2hhdmVzIG5hIG1lc21hIGVudGlkYWRlLgotIyAyLjggUHJvbG9nIGFuZCBEb2N1bWVudCBUeXBlIERlY2xhcmF0aW9uCi0gICAgICAgIFZlcnNpb25JbmZvSW52YWxpZCA9IFZlcnNcdTAwRTNvIGludlx1MDBFMWxpZGEgInswfSIuCi0gICAgICAgIFZlcnNpb25Ob3RTdXBwb3J0ZWQgPSBWZXJzXHUwMEUzbyBYTUwgInswfSIgblx1MDBFM28gc3Vwb3J0YWRhOyBzb21lbnRlIFhNTCAxLjAgXHUwMEU5IHN1cG9ydGFkYS4KLSAgICAgICAgVmVyc2lvbk5vdFN1cHBvcnRlZDExID0gVmVyc1x1MDBFM28gWE1MICJ7MH0iIG5cdTAwRTNvIHN1cG9ydGFkYSwgc29tZW50ZSBYTUwgMS4wIGUgWE1MIDEuMSBzXHUwMEUzbyBzdXBvcnRhZGFzLgotICAgICAgICBWZXJzaW9uTWlzbWF0Y2g9IFVtYSBlbnRpZGFkZSBuXHUwMEUzbyBwb2RlIGluY2x1aXIgb3V0cmEgZW50aWRhZGUgZGUgdW1hIHZlcnNcdTAwRTNvIHBvc3Rlcmlvci4KLSMgNC4xIENoYXJhY3RlciBhbmQgRW50aXR5IFJlZmVyZW5jZXMKLSAgICAgICAgRGlnaXRSZXF1aXJlZEluQ2hhclJlZiA9IFVtYSByZXByZXNlbnRhXHUwMEU3XHUwMEUzbyBkZWNpbWFsIGRldmUgc2VndWlyIGltZWRpYXRhbWVudGUgbyAiJiMiIGVtIHVtYSByZWZlclx1MDBFQW5jaWEgZGUgY2FyYWN0ZXJlLgotICAgICAgICBIZXhkaWdpdFJlcXVpcmVkSW5DaGFyUmVmID0gVW1hIHJlcHJlc2VudGFcdTAwRTdcdTAwRTNvIGhleGFkZWNpbWFsIGRldmUgc2VndWlyIGltZWRpYXRhbWVudGUgbyAiJiMiIGVtIHVtYSByZWZlclx1MDBFQW5jaWEgZGUgY2FyYWN0ZXJlLgotICAgICAgICBTZW1pY29sb25SZXF1aXJlZEluQ2hhclJlZiA9IEEgcmVmZXJcdTAwRUFuY2lhIGRlIGNhcmFjdGVyZSBkZXZlIHRlcm1pbmFyIGNvbSBvIGRlbGltaXRhZG9yICc7Jy4KLSAgICAgICAgSW52YWxpZENoYXJSZWYgPSBBIHJlZmVyXHUwMEVBbmNpYSBkbyBjYXJhY3RlcmUgIiYjezB9IiBcdTAwRTkgdW0gY2FyYWN0ZXJlIFhNTCBpbnZcdTAwRTFsaWRvLgotICAgICAgICBOYW1lUmVxdWlyZWRJblJlZmVyZW5jZSA9IE8gbm9tZSBkYSBlbnRpZGFkZSBkZXZlIHNlZ3VpciBpbWVkaWF0YW1lbnRlIG8gJyYnIG5hIHJlZmVyXHUwMEVBbmNpYSBkYSBlbnRpZGFkZS4KLSAgICAgICAgU2VtaWNvbG9uUmVxdWlyZWRJblJlZmVyZW5jZSA9IEEgcmVmZXJcdTAwRUFuY2lhIFx1MDBFMCBlbnRpZGFkZSAiezB9IiBkZXZlIHRlcm1pbmFyIGNvbSBvIGRlbGltaXRhZG9yICcnOycnLgotIyA0LjMuMSBUaGUgVGV4dCBEZWNsYXJhdGlvbgotICAgICAgICBUZXh0RGVjbE11c3RCZUZpcnN0ID0gQSBkZWNsYXJhXHUwMEU3XHUwMEUzbyBkZSB0ZXh0byBzb21lbnRlIHBvZGUgYXBhcmVjZXIgYmVtIG5vIGluXHUwMEVEY2lvIGRhIGVudGlkYWRlIGV4dGVybmEgc3VibWV0aWRhIGEgcGFyc2luZy4KLSAgICAgICAgRXFSZXF1aXJlZEluVGV4dERlY2wgPSBPIGNhcmFjdGVyZSAnJyA9ICcnIGRldmUgZXN0YXIgYXBcdTAwRjNzICJ7MH0iIG5hIGRlY2xhcmFcdTAwRTdcdTAwRTNvIGRlIHRleHRvLgotICAgICAgICBRdW90ZVJlcXVpcmVkSW5UZXh0RGVjbCA9IE8gdmFsb3IgYXBcdTAwRjNzICJ7MH0iIG5hIGRlY2xhcmFcdTAwRTdcdTAwRTNvIGRlIHRleHRvIGRldmUgc2VyIHVtYSBzdHJpbmcgZW50cmUgYXNwYXMuCi0gICAgICAgIENsb3NlUXVvdGVNaXNzaW5nSW5UZXh0RGVjbCA9IG5cdTAwRTNvIGZvaSBlbmNvbnRyYWRhIGEgYXNwYSBkZSBmZWNoYW1lbnRvIG5vIHZhbG9yIGFwXHUwMEYzcyAiezB9IiBuYSBkZWNsYXJhXHUwMEU3XHUwMEUzbyBkZSB0ZXh0by4KLSAgICAgICAgU3BhY2VSZXF1aXJlZEJlZm9yZVZlcnNpb25JblRleHREZWNsID0gTyBlc3BhXHUwMEU3byBlbSBicmFuY28gXHUwMEU5IG5lY2Vzc1x1MDBFMXJpbyBhbnRlcyBkbyBwc2V1ZG8tYXRyaWJ1dG8gZGEgdmVyc1x1MDBFM28gbmEgZGVjbGFyYVx1MDBFN1x1MDBFM28gZGUgdGV4dG8uCi0gICAgICAgIFNwYWNlUmVxdWlyZWRCZWZvcmVFbmNvZGluZ0luVGV4dERlY2wgPSBPIGVzcGFcdTAwRTdvIGVtIGJyYW5jbyBcdTAwRTkgbmVjZXNzXHUwMEUxcmlvIGFudGVzIGRlIGNvZGlmaWNhciBvIHBzZXVkby1hdHJpYnV0byBuYSBkZWNsYXJhXHUwMEU3XHUwMEUzbyBkZSB0ZXh0by4KLSAgICAgICAgVGV4dERlY2xVbnRlcm1pbmF0ZWQgPSBBIGRlY2xhcmFcdTAwRTdcdTAwRTNvIGRlIHRleHRvIGRldmUgdGVybWluYXIgY29tICI/PiIuCi0gICAgICAgIEVuY29kaW5nRGVjbFJlcXVpcmVkID0gQSBkZWNsYXJhXHUwMEU3XHUwMEUzbyBkZSBjb2RpZmljYVx1MDBFN1x1MDBFM28gXHUwMEU5IG5lY2Vzc1x1MDBFMXJpYSBuYSBkZWNsYXJhXHUwMEU3XHUwMEUzbyBkZSB0ZXh0by4KLSAgICAgICAgTm9Nb3JlUHNldWRvQXR0cmlidXRlcyA9IE5cdTAwRTNvIHNcdTAwRTNvIG1haXMgcGVybWl0aWRvcyBwc2V1ZG8tYXRyaWJ1dG9zLgotICAgICAgICBNb3JlUHNldWRvQXR0cmlidXRlcyA9IFNcdTAwRTNvIGVzcGVyYWRvcyBtYWlzIHBzZXVkby1hdHJpYnV0b3MuCi0gICAgICAgIFBzZXVkb0F0dHJOYW1lRXhwZWN0ZWQgPSBcdTAwQzkgZXNwZXJhZG8gdW0gbm9tZSBkZSB1bSBwc2V1ZG8tYXRyaWJ1dG8uIAotIyA0LjMuMiBXZWxsLUZvcm1lZCBQYXJzZWQgRW50aXRpZXMKLSAgICAgICAgQ29tbWVudE5vdEluT25lRW50aXR5ID0gTyBjb21lbnRcdTAwRTFyaW8gZGV2ZSBlc3RhciB0b3RhbG1lbnRlIGNvbnRpZG8gbmEgbWVzbWEgZW50aWRhZGUgc3VibWV0aWRhIGEgcGFyc2luZy4KLSAgICAgICAgUElOb3RJbk9uZUVudGl0eSA9IEEgaW5zdHJ1XHUwMEU3XHUwMEUzbyBkZSBwcm9jZXNzYW1lbnRvIGRldmUgZXN0YXIgdG90YWxtZW50ZSBjb250aWRhIG5hIG1lc21hIGVudGlkYWRlIHN1Ym1ldGlkYSBhIHBhcnNpbmcuCi0jIDQuMy4zIENoYXJhY3RlciBFbmNvZGluZyBpbiBFbnRpdGllcwotICAgICAgICBFbmNvZGluZ0RlY2xJbnZhbGlkID0gTm9tZSBkYSBjb2RpZmljYVx1MDBFN1x1MDBFM28gaW52XHUwMEUxbGlkYSAiezB9Ii4KLSAgICAgICAgRW5jb2RpbmdCeXRlT3JkZXJVbnN1cHBvcnRlZCA9IEEgb3JkZW0gZGUgYnl0ZXMgZm9ybmVjaWRhIHBhcmEgY29kaWZpY2FcdTAwRTdcdTAwRTNvICJ7MH0iIG5cdTAwRTNvIFx1MDBFOSBzdXBvcnRhZGEuCi0gICAgICAgIEludmFsaWRCeXRlID0gQnl0ZSBpbnZcdTAwRTFsaWRvIHswfSBkYSBzZXF1XHUwMEVBbmNpYSBVVEYtOCBkbyBieXRlIHsxfS4KLSAgICAgICAgRXhwZWN0ZWRCeXRlID0gRXNwZXJhdmEgezB9IGJ5dGUgZGEgc2VxdVx1MDBFQW5jaWEgVVRGLTggZG8gYnl0ZSB7MX0uICAKLSAgICAgICAgSW52YWxpZEhpZ2hTdXJyb2dhdGUgPSBPcyBiaXRzIHN1YnN0aXR1dG9zIGFsdG9zIG5hIHNlcXVcdTAwRUFuY2lhIGRhIFVURi04IG5cdTAwRTNvIGRldmVtIGV4Y2VkZXIgMHgxMCBtYXMgZm9pIGVuY29udHJhZG8gMHh7MH0uCi0gICAgICAgIE9wZXJhdGlvbk5vdFN1cHBvcnRlZCA9IEEgb3BlcmFcdTAwRTdcdTAwRTNvICJ7MH0iIG5cdTAwRTNvIFx1MDBFOSBzdXBvcnRhZGEgcGVsbyBsZWl0b3IgezF9LgotICAgICAgICBJbnZhbGlkQVNDSUkgPSBPIGJ5dGUgInswfSIgblx1MDBFM28gXHUwMEU5IG1lbWJybyBkbyBjb25qdW50byBkZSBjYXJhY3RlcmVzIEFTQ0lJICg3IGJpdHMpLgotICAgICAgICBDaGFyQ29udmVyc2lvbkZhaWx1cmUgPSBVbWEgZW50aWRhZGUgZGVzdGluYWRhIGEgZXN0YXIgZW0gdW1hIGRldGVybWluYWRhIGNvZGlmaWNhXHUwMEU3XHUwMEUzbyBuXHUwMEUzbyBkZXZlIGNvbnRlciBzZXF1XHUwMEVBbmNpYXMgaW52XHUwMEUxbGlkYXMgbmEgcmVmZXJpZGEgY29kaWZpY2FcdTAwRTdcdTAwRTNvLgotICAgICAgICAKLSMgRFREIE1lc3NhZ2VzCi0jIDIuMiBDaGFyYWN0ZXJzCi0gICAgICAgIEludmFsaWRDaGFySW5FbnRpdHlWYWx1ZSA9IFVtIGNhcmFjdGVyZSBYTUwgaW52XHUwMEUxbGlkbyAoVW5pY29kZTogMHggezB9KSBmb2kgZW5jb250cmFkbyBubyB2YWxvciBkYSBlbnRpZGFkZSBkYSBsaXRlcmFsLgotICAgICAgICBJbnZhbGlkQ2hhckluRXh0ZXJuYWxTdWJzZXQgPSBVbSBjYXJhY3RlcmUgWE1MIGludlx1MDBFMWxpZG8gKFVuaWNvZGU6IDB4IHswfSkgZm9pIGVuY29udHJhZG8gbm8gc3ViY29uanVudG8gZXh0ZXJubyBkbyBEVEQuCi0gICAgICAgIEludmFsaWRDaGFySW5JZ25vcmVTZWN0ID0gVW0gY2FyYWN0ZXJlIFhNTCBpbnZcdTAwRTFsaWRvIChVbmljb2RlOiAweHswfSkgZm9pIGVuY29udHJhZG8gbmEgc2VcdTAwRTdcdTAwRTNvIGNvbmRpY2lvbmFsIGV4Y2x1XHUwMEVEZGEuCi0gICAgICAgIEludmFsaWRDaGFySW5QdWJsaWNJRCA9IFVtIGNhcmFjdGVyZSBYTUwgaW52XHUwMEUxbGlkbyAoVW5pY29kZTogMHh7MH0pIGZvaSBlbmNvbnRyYWRvIG5vIGlkZW50aWZpY2Fkb3IgcFx1MDBGQWJsaWNvLgotICAgICAgICBJbnZhbGlkQ2hhckluU3lzdGVtSUQgPSBVbSBjYXJhY3RlcmUgWE1MIGludlx1MDBFMWxpZG8gKFVuaWNvZGU6IDB4ezB9KSBmb2kgZW5jb250cmFkbyBubyBpZGVudGlmaWNhZG9yIGRvIHNpc3RlbWEuCi0jIDIuMyBDb21tb24gU3ludGFjdGljIENvbnN0cnVjdHMKLSAgICAgICAgU3BhY2VSZXF1aXJlZEFmdGVyU1lTVEVNID0gXHUwMEM5IG5lY2Vzc1x1MDBFMXJpbyB1bSBlc3BhXHUwMEU3byBlbSBicmFuY28gYXBcdTAwRjNzIGEgcGFsYXZyYS1jaGF2ZSBTWVRFTSBuYSBkZWNsYXJhXHUwMEU3XHUwMEUzbyBET0NUWVBFLgotICAgICAgICBRdW90ZVJlcXVpcmVkSW5TeXN0ZW1JRCA9IE8gaWRlbnRpZmljYWRvciBkbyBzaXN0ZW1hIGRldmUgY29tZVx1MDBFN2FyIGNvbSBhc3BhcyBzaW1wbGVzIG91IGR1cGxhcy4KLSAgICAgICAgU3lzdGVtSURVbnRlcm1pbmF0ZWQgPSBPIGlkZW50aWZpY2Fkb3IgZG8gc2lzdGVtYSBkZXZlIHRlcm1pbmFyIGNvbSBhcyBhc3BhcyBjb3JyZXNwb25kZW50ZXMuCi0gICAgICAgIFNwYWNlUmVxdWlyZWRBZnRlclBVQkxJQyA9IFNcdTAwRTNvIG5lY2Vzc1x1MDBFMXJpb3MgZXNwYVx1MDBFN29zIGVtIGJyYW5jbyBhcFx1MDBGM3MgYSBwYWxhdnJhLWNoYXZlIFBVQkxJQyBuYSBkZWNsYXJhXHUwMEU3XHUwMEUzbyBET0NUWVBFLgotICAgICAgICBRdW90ZVJlcXVpcmVkSW5QdWJsaWNJRCA9IE8gaWRlbnRpZmljYWRvciBwXHUwMEZBYmxpY28gZGV2ZSBjb21lXHUwMEU3YXIgY29tIGFzcGFzIHNpbXBsZXMgb3UgZHVwbGFzLgotICAgICAgICBQdWJsaWNJRFVudGVybWluYXRlZCA9IE8gaWRlbnRpZmljYWRvciBwXHUwMEZBYmxpY28gZGV2ZSB0ZXJtaW5hciBjb20gYXMgYXNwYXMgY29ycmVzcG9uZGVudGVzLgotICAgICAgICBQdWJpZENoYXJJbGxlZ2FsID0gTyBjYXJhY3RlcmUgWE1MIChVbmljb2RlOiAweHswfSkgblx1MDBFM28gXHUwMEU5IHBlcm1pdGlkbyBubyBpZGVudGlmaWNhZG9yIHBcdTAwRkFibGljby4KLSAgICAgICAgU3BhY2VSZXF1aXJlZEJldHdlZW5QdWJsaWNBbmRTeXN0ZW0gPSBFc3BhXHUwMEU3b3MgZW0gYnJhbmNvIHNcdTAwRTNvIG5lY2Vzc1x1MDBFMXJpb3MgZW50cmUgcHVibGljSWQgZSBzeXN0ZW1JZC4KLSMgMi44IFByb2xvZyBhbmQgRG9jdW1lbnQgVHlwZSBEZWNsYXJhdGlvbgotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX1JPT1RfRUxFTUVOVF9UWVBFX0lOX0RPQ1RZUEVERUNMID0gTyBlc3BhXHUwMEU3byBlbSBicmFuY28gXHUwMEU5IG5lY2Vzc1x1MDBFMXJpbyBhcFx1MDBGM3MgIjwhRE9DVFlQRSIgbmEgZGVjbGFyYVx1MDBFN1x1MDBFM28gZG8gdGlwbyBkZSBkb2N1bWVudG8uCi0gICAgICAgIE1TR19ST09UX0VMRU1FTlRfVFlQRV9SRVFVSVJFRCA9IE8gdGlwbyBkZSBlbGVtZW50by1yYWl6IGRldmUgYXBhcmVjZXIgYXBcdTAwRjNzICI8IURPQ1RZUEUiIG5hIGRlY2xhcmFcdTAwRTdcdTAwRTNvIGRvIHRpcG8gZGUgZG9jdW1lbnRvLgotICAgICAgICBEb2N0eXBlZGVjbFVudGVybWluYXRlZCA9IEEgZGVjbGFyYVx1MDBFN1x1MDBFM28gZG8gdGlwbyBkZSBkb2N1bWVudG8gZG8gdGlwbyBkZSBlbGVtZW50byAiezB9IiBkZXZlIHRlcm1pbmFyIGNvbSAnJz4nJy4KLSAgICAgICAgRG9jdHlwZWRlY2xOb3RDbG9zZWQgPSBBIGRlY2xhcmFcdTAwRTdcdTAwRTNvIGRvIHRpcG8gZGUgZG9jdW1lbnRvIGRvIHRpcG8gZGUgZWxlbWVudG8gInswfSIgZGV2ZSB0ZXJtaW5hciBjb20gJyddJycuCi0gICAgICAgIFBFUmVmZXJlbmNlV2l0aGluTWFya3VwID0gQSByZWZlclx1MDBFQW5jaWEgZGEgZW50aWRhZGUgZG8gcGFyXHUwMEUybWV0cm8gIiV7MH07IiBuXHUwMEUzbyBwb2RlIG9jb3JyZXIgbmEgbWFyY2FcdTAwRTdcdTAwRTNvIG5vIHN1YmNvbmp1bnRvIGludGVybm8gZG8gRFRELgotICAgICAgICBNU0dfTUFSS1VQX05PVF9SRUNPR05JWkVEX0lOX0RURCA9IEFzIGRlY2xhcmFcdTAwRTdcdTAwRjVlcyBkZSBtYXJjYVx1MDBFN1x1MDBFM28gY29udGlkYXMgb3UgYXBvbnRhZGFzIHBlbGEgZGVjbGFyYVx1MDBFN1x1MDBFM28gZG8gdGlwbyBkZSBkb2N1bWVudG8gZGV2ZW0gZXN0YXIgY29ycmV0YXMuCi0jIDIuMTAgV2hpdGUgU3BhY2UgSGFuZGxpbmcKLSAgICAgICAgTVNHX1hNTF9TUEFDRV9ERUNMQVJBVElPTl9JTExFR0FMID0gRGV2ZSBzZXIgZm9ybmVjaWRhIGEgZGVjbGFyYVx1MDBFN1x1MDBFM28gZG8gYXRyaWJ1dG8gcGFyYSAieG1sOnNwYWNlIiBjb21vIHVtIHRpcG8gZW51bWVyYWRvLCBjdWpvIG9zIFx1MDBGQW5pY29zIHZhbG9yZXMgcG9zc1x1MDBFRHZlaXMgc1x1MDBFM28gInBhZHJcdTAwRTNvIiBlICJwcmVzZXJ2ZSIuCi0jIDMuMiBFbGVtZW50IFR5cGUgRGVjbGFyYXRpb25zCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfRUxFTUVOVF9UWVBFX0lOX0VMRU1FTlRERUNMID0gTyBlc3BhXHUwMEU3byBlbSBicmFuY28gXHUwMEU5IG5lY2Vzc1x1MDBFMXJpbyBhcFx1MDBGM3MgIjwhRUxFTUVOVCIgbmEgZGVjbGFyYVx1MDBFN1x1MDBFM28gZG8gdGlwbyBkZSBlbGVtZW50by4KLSAgICAgICAgTVNHX0VMRU1FTlRfVFlQRV9SRVFVSVJFRF9JTl9FTEVNRU5UREVDTCA9IE8gdGlwbyBkZSBlbGVtZW50byBcdTAwRTkgbmVjZXNzXHUwMEUxcmlvIG5hIGRlY2xhcmFcdTAwRTdcdTAwRTNvIGRvIHRpcG8gZGUgZWxlbWVudG8uCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfQ09OVEVOVFNQRUNfSU5fRUxFTUVOVERFQ0wgPSBPIGVzcGFcdTAwRTdvIGVtIGJyYW5jbyBcdTAwRTkgbmVjZXNzXHUwMEUxcmlvIGFwXHUwMEYzcyBvIHRpcG8gZGUgZWxlbWVudG8gInswfSIgbmEgZGVjbGFyYVx1MDBFN1x1MDBFM28gZG8gdGlwbyBkZSBlbGVtZW50by4KLSAgICAgICAgTVNHX0NPTlRFTlRTUEVDX1JFUVVJUkVEX0lOX0VMRU1FTlRERUNMID0gQSByZXN0cmlcdTAwRTdcdTAwRTNvIFx1MDBFOSBuZWNlc3NcdTAwRTFyaWEgYXBcdTAwRjNzIG8gdGlwbyBkZSBlbGVtZW50byAiezB9IiBuYSBkZWNsYXJhXHUwMEU3XHUwMEUzbyBkbyB0aXBvIGRlIGVsZW1lbnRvLgotICAgICAgICBFbGVtZW50RGVjbFVudGVybWluYXRlZCA9IEEgZGVjbGFyYVx1MDBFN1x1MDBFM28gZG8gdGlwbyBkZSBlbGVtZW50byAiezB9IiBkZXZlIHRlcm1pbmFyIGNvbSAnJz4nJy4KLSMgMy4yLjEgRWxlbWVudCBDb250ZW50Ci0gICAgICAgIE1TR19PUEVOX1BBUkVOX09SX0VMRU1FTlRfVFlQRV9SRVFVSVJFRF9JTl9DSElMRFJFTiA9IFx1MDBDOSBuZWNlc3NcdTAwRTFyaW8gdW0gY2FyYWN0ZXJlICcnKCcnIG91IHVtIHRpcG8gZGUgZWxlbWVudG8gbmEgZGVjbGFyYVx1MDBFN1x1MDBFM28gZG8gdGlwbyBkZSBlbGVtZW50byAiezB9Ii4KLSAgICAgICAgTVNHX0NMT1NFX1BBUkVOX1JFUVVJUkVEX0lOX0NISUxEUkVOID0gXHUwMEM5IG5lY2Vzc1x1MDBFMXJpbyB1bSBjYXJhY3RlcmUgJycpJycgbmEgZGVjbGFyYVx1MDBFN1x1MDBFM28gZG8gdGlwbyBkZSBlbGVtZW50byAiezB9Ii4KLSMgMy4yLjIgTWl4ZWQgQ29udGVudAotICAgICAgICBNU0dfRUxFTUVOVF9UWVBFX1JFUVVJUkVEX0lOX01JWEVEX0NPTlRFTlQgPSBcdTAwQzkgbmVjZXNzXHUwMEUxcmlvIHVtIHRpcG8gZGUgZWxlbWVudG8gbmEgZGVjbGFyYVx1MDBFN1x1MDBFM28gZG8gdGlwbyBkZSBlbGVtZW50byAiezB9Ii4KLSAgICAgICAgTVNHX0NMT1NFX1BBUkVOX1JFUVVJUkVEX0lOX01JWEVEID0gXHUwMEM5IG5lY2Vzc1x1MDBFMXJpbyB1bSBjYXJhY3RlcmUgJycpJycgbmEgZGVjbGFyYVx1MDBFN1x1MDBFM28gZG8gdGlwbyBkZSBlbGVtZW50byAiezB9Ii4KLSAgICAgICAgTWl4ZWRDb250ZW50VW50ZXJtaW5hdGVkID0gTyBtb2RlbG8gZGUgY29udGVcdTAwRkFkbyBtaXN0byAiezB9IiBkZXZlIHRlcm1pbmFyIGNvbSAiKSoiIHF1YW5kbyBvcyB0aXBvcyBkZSBlbGVtZW50b3MgZmlsaG9zIGZvcmVtIHJlc3RyaW5naWRvcy4KLSMgMy4zIEF0dHJpYnV0ZS1MaXN0IERlY2xhcmF0aW9ucwotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX0VMRU1FTlRfVFlQRV9JTl9BVFRMSVNUREVDTCA9IE8gZXNwYVx1MDBFN28gZW0gYnJhbmNvIFx1MDBFOSBuZWNlc3NcdTAwRTFyaW8gYXBcdTAwRjNzICI8IUFUVExJU1QiIG5hIGRlY2xhcmFcdTAwRTdcdTAwRTNvIGRhIGxpc3RhIGRlIGF0cmlidXRvcy4KLSAgICAgICAgTVNHX0VMRU1FTlRfVFlQRV9SRVFVSVJFRF9JTl9BVFRMSVNUREVDTCA9IFx1MDBDOSBuZWNlc3NcdTAwRTFyaW8gbyB0aXBvIGRlIGVsZW1lbnRvIG5hIGRlY2xhcmFcdTAwRTdcdTAwRTNvIGRhIGxpc3RhIGRlIGF0cmlidXRvcy4KLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9BVFRSSUJVVEVfTkFNRV9JTl9BVFRERUYgPSBcdTAwQzkgbmVjZXNzXHUwMEUxcmlvIG8gZXNwYVx1MDBFN28gZW0gYnJhbmNvIGFudGVzIGRvIG5vbWUgZG8gYXRyaWJ1dG8gbmEgZGVjbGFyYVx1MDBFN1x1MDBFM28gZGEgbGlzdGEgZGUgYXRyaWJ1dG9zIGRvIGVsZW1lbnRvICJ7MH0iLgotICAgICAgICBBdHROYW1lUmVxdWlyZWRJbkF0dERlZiA9IE8gbm9tZSBkbyBhdHJpYnV0byBkZXZlIHNlciBlc3BlY2lmaWNhZG8gbmEgZGVjbGFyYVx1MDBFN1x1MDBFM28gZGEgbGlzdGEgZGUgYXRyaWJ1dG9zIGRvIGVsZW1lbnRvICJ7MH0iLgotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX0FUVFRZUEVfSU5fQVRUREVGID0gXHUwMEM5IG5lY2Vzc1x1MDBFMXJpbyBvIGVzcGFcdTAwRTdvIGVtIGJyYW5jbyBhbnRlcyBkbyB0aXBvIGRlIGF0cmlidXRvIG5hIGRlY2xhcmFcdTAwRTdcdTAwRTNvIGRvIGF0cmlidXRvICJ7MX0iIGRvIGVsZW1lbnRvICJ7MH0iLgotICAgICAgICBBdHRUeXBlUmVxdWlyZWRJbkF0dERlZiA9IFx1MDBDOSBuZWNlc3NcdTAwRTFyaW8gbyB0aXBvIGRlIGF0cmlidXRvIG5hIGRlY2xhcmFcdTAwRTdcdTAwRTNvIGRvIGF0cmlidXRvICJ7MX0iIGRvIGVsZW1lbnRvICJ7MH0iLgotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX0RFRkFVTFRERUNMX0lOX0FUVERFRiA9IFx1MDBDOSBuZWNlc3NcdTAwRTFyaW8gbyBlc3BhXHUwMEU3byBlbSBicmFuY28gYW50ZXMgZG8gcGFkclx1MDBFM28gZG8gYXRyaWJ1dG8gbmEgZGVjbGFyYVx1MDBFN1x1MDBFM28gZG8gYXRyaWJ1dG8gInsxfSIgZG8gZWxlbWVudG8gInswfSIuCi0gICAgICAgIE1TR19EVVBMSUNBVEVfQVRUUklCVVRFX0RFRklOSVRJT04gPSBNYWlzIGRlIHVtYSBkZWZpbmlcdTAwRTdcdTAwRTNvIGRlIGF0cmlidXRvIGZvcm5lY2lkYSBwYXJhIG8gbWVzbW8gYXRyaWJ1dG8gInsxfSIgZGUgdW0gZGV0ZXJtaW5hZG8gZWxlbWVudG8gInswfSIuCi0jIDMuMy4xIEF0dHJpYnV0ZSBUeXBlcwotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQUZURVJfTk9UQVRJT05fSU5fTk9UQVRJT05UWVBFID0gTyBlc3BhXHUwMEU3byBlbSBicmFuY28gZGV2ZSBhcGFyZWNlciBhcFx1MDBGM3MgIk5PVEFUSU9OIiBuYSBkZWNsYXJhXHUwMEU3XHUwMEUzbyBkbyBhdHJpYnV0byAiezF9Ii4KLSAgICAgICAgTVNHX09QRU5fUEFSRU5fUkVRVUlSRURfSU5fTk9UQVRJT05UWVBFID0gTyBjYXJhY3RlcmUgJycoJycgZGV2ZSBlc3RhciBhcFx1MDBGM3MgIk5PVEFUSU9OIiBuYSBkZWNsYXJhXHUwMEU3XHUwMEUzbyBkbyBhdHJpYnV0byAiezF9Ii4KLSAgICAgICAgTVNHX05BTUVfUkVRVUlSRURfSU5fTk9UQVRJT05UWVBFID0gXHUwMEM5IG5lY2Vzc1x1MDBFMXJpbyBvIG5vbWUgZGEgbm90YVx1MDBFN1x1MDBFM28gbmEgbGlzdGEgZGUgdGlwb3MgZGUgbm90YVx1MDBFN1x1MDBFM28gcGFyYSBhIGRlY2xhcmFcdTAwRTdcdTAwRTNvIGRvIGF0cmlidXRvICJ7MX0iLgotICAgICAgICBOb3RhdGlvblR5cGVVbnRlcm1pbmF0ZWQgPSBBIGxpc3RhIGRlIHRpcG9zIGRlIG5vdGFcdTAwRTdcdTAwRTNvIGRldmUgdGVybWluYXIgY29tICcnKScnIG5hIGRlY2xhcmFcdTAwRTdcdTAwRTNvIGRvIGF0cmlidXRvICJ7MX0iLgotICAgICAgICBNU0dfTk1UT0tFTl9SRVFVSVJFRF9JTl9FTlVNRVJBVElPTiA9IE8gdG9rZW4gZG8gbm9tZSBcdTAwRTkgb2JyaWdhdFx1MDBGM3JpbyBuYSBsaXN0YSBkZSB0aXBvcyBlbnVtZXJhZGEgcGFyYSBhIGRlY2xhcmFcdTAwRTdcdTAwRTNvIGRvIGF0cmlidXRvICJ7MX0iLgotICAgICAgICBFbnVtZXJhdGlvblVudGVybWluYXRlZCA9IEEgbGlzdGEgZGUgdGlwb3MgZW51bWVyYWRhIGRldmUgdGVybWluYXIgY29tICcnKScnIG5hIGRlY2xhcmFcdTAwRTdcdTAwRTNvIGRvIGF0cmlidXRvICJ7MX0iLgotICAgICAgICBNU0dfRElTVElOQ1RfVE9LRU5TX0lOX0VOVU1FUkFUSU9OID0gTyB2YWxvciBkYSBlbnVtZXJhXHUwMEU3XHUwMEUzbyAiezF9IiBmb2kgZXNwZWNpZmljYWRvIG1haXMgZGUgdW1hIHZleiBuYSBkZWNsYXJhXHUwMEU3XHUwMEUzbyBkbyBhdHJpYnV0byAiezJ9IiBkbyBlbGVtZW50byAiezB9Ii4gT3MgTk1UT0tFTlMgZW0gdW1hIGRlY2xhcmFcdTAwRTdcdTAwRTNvIGRlIGF0cmlidXRvIGRlIEVudW1lcmFcdTAwRTdcdTAwRTNvIFx1MDBGQW5pY2EgZGV2ZW0gc2VyIHRvZG9zIGRpc3RpbnRvcy4KLSAgICAgICAgTVNHX0RJU1RJTkNUX05PVEFUSU9OX0lOX0VOVU1FUkFUSU9OID0gTyB2YWxvciBkYSBlbnVtZXJhXHUwMEU3XHUwMEUzbyAiezF9IiBmb2kgZXNwZWNpZmljYWRvIG1haXMgZGUgdW1hIHZleiBuYSBkZWNsYXJhXHUwMEU3XHUwMEUzbyBkbyBhdHJpYnV0byAiezJ9IiBkbyBlbGVtZW50byAiezB9Ii4gT3Mgbm9tZXMgZGEgTk9UQVRJT04gZW0gdW1hIGRlY2xhcmFcdTAwRTdcdTAwRTNvIGRvIGF0cmlidXRvIE5vdGF0aW9uVHlwZSBcdTAwRkFuaWNhIGRldmVtIHNlciB0b2RvcyBkaXN0aW50b3MuCi0jIDMuMy4yIEF0dHJpYnV0ZSBEZWZhdWx0cwotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQUZURVJfRklYRURfSU5fREVGQVVMVERFQ0wgPSBPIGVzcGFcdTAwRTdvIGVtIGJyYW5jbyBkZXZlIGFwYXJlY2VyIGFwXHUwMEYzcyAiRklYRUQiIG5hIGRlY2xhcmFcdTAwRTdcdTAwRTNvIGRvIGF0cmlidXRvICJ7MX0iLgotIyAzLjQgQ29uZGl0aW9uYWwgU2VjdGlvbnMKLSAgICAgICAgSW5jbHVkZVNlY3RVbnRlcm1pbmF0ZWQgPSBBIHNlXHUwMEU3XHUwMEUzbyBjb25kaWNpb25hbCBpbmNsdVx1MDBFRGRhIGRldmUgdGVybWluYXIgY29tICJdXT4iLgotICAgICAgICBJZ25vcmVTZWN0VW50ZXJtaW5hdGVkID0gQSBzZVx1MDBFN1x1MDBFM28gY29uZGljaW9uYWwgZXhjbHVcdTAwRURkYSBkZXZlIHRlcm1pbmFyIGNvbSAiXV0+Ii4KLSMgNC4xIENoYXJhY3RlciBhbmQgRW50aXR5IFJlZmVyZW5jZXMKLSAgICAgICAgTmFtZVJlcXVpcmVkSW5QRVJlZmVyZW5jZSA9IE8gbm9tZSBkYSBlbnRpZGFkZSBkZXZlIHNlZ3VpciBpbWVkaWF0YW1lbnRlIG8gJyUnIG5hIHJlZmVyXHUwMEVBbmNpYSBkYSBlbnRpZGFkZSBkbyBwYXJcdTAwRTJtZXRyby4KLSAgICAgICAgU2VtaWNvbG9uUmVxdWlyZWRJblBFUmVmZXJlbmNlID0gQSByZWZlclx1MDBFQW5jaWEgZGEgZW50aWRhZGUgZG8gcGFyXHUwMEUybWV0cm8gIiV7MH07IiBkZXZlIHRlcm1pbmFyIGNvbSBvIGRlbGltaXRhZG9yICcnOyIuCi0jIDQuMiBFbnRpdHkgRGVjbGFyYXRpb25zCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfRU5USVRZX05BTUVfSU5fRU5USVRZREVDTCA9IE8gZXNwYVx1MDBFN28gZW0gYnJhbmNvIFx1MDBFOSBuZWNlc3NcdTAwRTFyaW8gYXBcdTAwRjNzICI8IUVOVElUWSIgbmEgZGVjbGFyYVx1MDBFN1x1MDBFM28gZGEgZW50aWRhZGUuCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfUEVSQ0VOVF9JTl9QRURFQ0wgPSBPIGVzcGFcdTAwRTdvIGVtIGJyYW5jbyBcdTAwRTkgbmVjZXNzXHUwMEUxcmlvIGVudHJlICI8IUVOVElUWSIgZSBvIGNhcmFjdGVyZSAnJScgbmEgZGVjbGFyYVx1MDBFN1x1MDBFM28gZGEgZW50aWRhZGUgZG8gcGFyXHUwMEUybWV0cm8uCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfRU5USVRZX05BTUVfSU5fUEVERUNMID0gTyBlc3BhXHUwMEU3byBlbSBicmFuY28gXHUwMEU5IG5lY2Vzc1x1MDBFMXJpbyBlbnRyZSAnJScgZSBvIG5vbWUgZGEgZW50aWRhZGUgbmEgZGVjbGFyYVx1MDBFN1x1MDBFM28gZGEgZW50aWRhZGUgZG8gcGFyXHUwMEUybWV0cm8uCi0gICAgICAgIE1TR19FTlRJVFlfTkFNRV9SRVFVSVJFRF9JTl9FTlRJVFlERUNMID0gTyBub21lIGRhIGVudGlkYWRlIFx1MDBFOSBuZWNlc3NcdTAwRTFyaW8gbmEgZGVjbGFyYVx1MDBFN1x1MDBFM28gZGEgZW50aWRhZGUuCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9BRlRFUl9FTlRJVFlfTkFNRV9JTl9FTlRJVFlERUNMID0gTyBlc3BhXHUwMEU3byBlbSBicmFuY28gXHUwMEU5IG5lY2Vzc1x1MDBFMXJpbyBlbnRyZSBvIG5vbWUgZGEgZW50aWRhZGUgInswfSIgZSBhIGRlZmluaVx1MDBFN1x1MDBFM28gZGEgZGVjbGFyYVx1MDBFN1x1MDBFM28gZGEgZW50aWRhZGUuCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfTk9UQVRJT05fTkFNRV9JTl9VTlBBUlNFRF9FTlRJVFlERUNMID0gXHUwMEM5IG5lY2Vzc1x1MDBFMXJpbyB1bSBlc3BhXHUwMEU3byBlbSBicmFuY28gZW50cmUgIk5EQVRBIiBlIG8gbm9tZSBkYSBub3RhXHUwMEU3XHUwMEUzbyBuYSBkZWNsYXJhXHUwMEU3XHUwMEUzbyBkYSBlbnRpZGFkZSAiezB9Ii4KLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9OREFUQV9JTl9VTlBBUlNFRF9FTlRJVFlERUNMID0gTyBlc3BhXHUwMEU3byBlbSBicmFuY28gXHUwMEU5IG5lY2Vzc1x1MDBFMXJpbyBhbnRlcyBkZSAiTkRBVEEiIG5hIGRlY2xhcmFcdTAwRTdcdTAwRTNvIGRhIGVudGlkYWRlICJ7MH0iLgotICAgICAgICBNU0dfTk9UQVRJT05fTkFNRV9SRVFVSVJFRF9GT1JfVU5QQVJTRURfRU5USVRZREVDTCA9IE8gbm9tZSBkYSBub3RhXHUwMEU3XHUwMEUzbyBcdTAwRTkgbmVjZXNzXHUwMEUxcmlvIGFwXHUwMEYzcyAiTkRBVEEiIG5hIGRlY2xhcmFcdTAwRTdcdTAwRTNvIGRhIGVudGlkYWRlICJ7MH0iLgotICAgICAgICBFbnRpdHlEZWNsVW50ZXJtaW5hdGVkID0gQSBkZWNsYXJhXHUwMEU3XHUwMEUzbyBkYSBlbnRpZGFkZSAiezB9IiBkZXZlIHRlcm1pbmFyIGNvbSAnJz4nJy4KLQlNU0dfRFVQTElDQVRFX0VOVElUWV9ERUZJTklUSU9OID0gQSBlbnRpZGFkZSAiezB9IiBmb2kgZGVjbGFyYWRhIG1haXMgZGUgdW1hIHZlei4gICAgICAgIAotIyA0LjIuMiBFeHRlcm5hbCBFbnRpdGllcwotICAgICAgICBFeHRlcm5hbElEUmVxdWlyZWQgPSBBIGRlY2xhcmFcdTAwRTdcdTAwRTNvIGRhIGVudGlkYWRlIGV4dGVybmEgZGV2ZSBjb21lXHUwMEU3YXIgY29tICJTWVNURU0iIG91ICJQVUJMSUMiLgotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX1BVQklETElURVJBTF9JTl9FWFRFUk5BTElEID0gTyBlc3BhXHUwMEU3byBlbSBicmFuY28gXHUwMEU5IG5lY2Vzc1x1MDBFMXJpbyBlbnRyZSAiUFVCTElDIiBlIG8gaWRlbnRpZmljYWRvciBwXHUwMEZBYmxpY28uCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9BRlRFUl9QVUJJRExJVEVSQUxfSU5fRVhURVJOQUxJRCA9IE8gZXNwYVx1MDBFN28gZW0gYnJhbmNvIFx1MDBFOSBuZWNlc3NcdTAwRTFyaW8gZW50cmUgbyBpZGVudGlmaWNhZG9yIHBcdTAwRkFibGljbyBlIG8gaWRlbnRpZmljYWRvciBkbyBzaXN0ZW1hLgotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX1NZU1RFTUxJVEVSQUxfSU5fRVhURVJOQUxJRCA9IE8gZXNwYVx1MDBFN28gZW0gYnJhbmNvIFx1MDBFOSBuZWNlc3NcdTAwRTFyaW8gZW50cmUgIlNZU1RFTSIgZSBvIGlkZW50aWZpY2Fkb3IgZG8gc2lzdGVtYS4KLSAgICAgICAgTVNHX1VSSV9GUkFHTUVOVF9JTl9TWVNURU1JRCA9IE8gaWRlbnRpZmljYWRvciBkbyBmcmFnbWVudG8gblx1MDBFM28gZGV2ZSBzZXIgZXNwZWNpZmljYWRvIGNvbW8gcGFydGUgZG8gaWRlbnRpZmljYWRvciBkbyBzaXN0ZW1hICJ7MH0iLgotIyA0LjcgTm90YXRpb24gRGVjbGFyYXRpb25zCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfTk9UQVRJT05fTkFNRV9JTl9OT1RBVElPTkRFQ0wgPSBPIGVzcGFcdTAwRTdvIGVtIGJyYW5jbyBcdTAwRTkgbmVjZXNzXHUwMEUxcmlvIGFwXHUwMEYzcyAiPCFOT1RBVElPTiIgbmEgZGVjbGFyYVx1MDBFN1x1MDBFM28gZGEgbm90YVx1MDBFN1x1MDBFM28uCi0gICAgICAgIE1TR19OT1RBVElPTl9OQU1FX1JFUVVJUkVEX0lOX05PVEFUSU9OREVDTCA9IE8gbm9tZSBkYSBub3RhXHUwMEU3XHUwMEUzbyBcdTAwRTkgb2JyaWdhdFx1MDBGM3JpbyBuYSBkZWNsYXJhXHUwMEU3XHUwMEUzbyBkZSBub3RhXHUwMEU3XHUwMEUzby4KLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0FGVEVSX05PVEFUSU9OX05BTUVfSU5fTk9UQVRJT05ERUNMID0gTyBlc3BhXHUwMEU3byBlbSBicmFuY28gXHUwMEU5IG5lY2Vzc1x1MDBFMXJpbyBhcFx1MDBGM3MgbyBub21lIGRhIG5vdGFcdTAwRTdcdTAwRTNvICJ7MH0iIG5hIGRlY2xhcmFcdTAwRTdcdTAwRTNvIGRlIG5vdGFcdTAwRTdcdTAwRTNvLgotICAgICAgICBFeHRlcm5hbElEb3JQdWJsaWNJRFJlcXVpcmVkID0gQSBkZWNsYXJhXHUwMEU3XHUwMEUzbyBkYSBub3RhXHUwMEU3XHUwMEUzbyAiezB9IiBkZXZlIGluY2x1aXIgdW0gaWRlbnRpZmljYWRvciBwXHUwMEZBYmxpY28gb3UgZG8gc2lzdGVtYS4KLSAgICAgICAgTm90YXRpb25EZWNsVW50ZXJtaW5hdGVkID0gQSBkZWNsYXJhXHUwMEU3XHUwMEUzbyBkYSBub3RhXHUwMEU3XHUwMEUzbyAiezB9IiBkZXZlIHRlcm1pbmFyIGNvbSAnJz4nJy4KLSAgICAgICAgCi0jIFZhbGlkYXRpb24gbWVzc2FnZXMKLSAgICAgICAgRHVwbGljYXRlVHlwZUluTWl4ZWRDb250ZW50ID0gTyB0aXBvIGRlIGVsZW1lbnRvICJ7MX0iIGpcdTAwRTEgZm9pIGVzcGVjaWZpY2FkbyBubyBtb2RlbG8gZGUgY29udGVcdTAwRkFkbyBkYSBkZWNsYXJhXHUwMEU3XHUwMEUzbyBkbyBlbGVtZW50byAiezB9Ii4KLSAgICAgICAgRU5USVRJRVNJbnZhbGlkID0gTyB2YWxvciBkbyBhdHJpYnV0byAiezF9IiBkbyB0aXBvIEVOVElUSUVTIGRldmUgc2VyIG8gbm9tZSBkZSB1bWEgb3UgbWFpcyBlbnRpZGFkZXMgblx1MDBFM28gc3VibWV0aWRhcyBhIHBhcnNpbmcuCi0gICAgICAgIEVOVElUWUludmFsaWQgPSBPIHZhbG9yIGRvIGF0cmlidXRvICJ7MX0iIGRvIHRpcG8gRU5USVRZIGRldmUgc2VyIG8gbm9tZSBkZSB1bWEgZW50aWRhZGUgblx1MDBFM28gc3VibWV0aWRhIGEgcGFyc2luZy4KLSAgICAgICAgSUREZWZhdWx0VHlwZUludmFsaWQgPSBPIGF0cmlidXRvIGRvIElEICJ7MH0iIGRldmUgdGVyIHVtIHBhZHJcdTAwRTNvIGRlY2xhcmFkbyAiI0lNUExJRUQiIG91ICIjUkVRVUlSRUQiLgotICAgICAgICBJREludmFsaWQgPSBPIHZhbG9yIGRvIGF0cmlidXRvICJ7MH0iIGRvIElEIGRlIHRpcG8gZGV2ZSBzZXIgdW0gbm9tZS4KLSAgICAgICAgSURJbnZhbGlkV2l0aE5hbWVzcGFjZXMgPSBPIHZhbG9yIGRvIGF0cmlidXRvICJ7MH0iIGRvIElEIGRlIHRpcG8gZGV2ZSBzZXIgdW0gTkNOYW1lIHF1YW5kbyBvcyBuYW1lc3BhY2VzIGVzdGl2ZXJlbSBhdGl2YWRvcy4KLSAgICAgICAgSUROb3RVbmlxdWUgPSBPIHZhbG9yIGRvIGF0cmlidXRvICJ7MH0iIGRvIElEIGRlIHRpcG8gZGV2ZSBzZXIgZXhjbHVzaXZvIG5vIGRvY3VtZW50by4KLSAgICAgICAgSURSRUZJbnZhbGlkID0gTyB2YWxvciBkbyBhdHJpYnV0byAiezB9IiBkbyBJRFJFRiBkZSB0aXBvIGRldmUgc2VyIHVtIG5vbWUuCi0gICAgICAgIElEUkVGSW52YWxpZFdpdGhOYW1lc3BhY2VzID0gTyB2YWxvciBkbyBhdHJpYnV0byAiezB9IiBkbyBJRFJFRiBkZSB0aXBvIGRldmUgc2VyIHVtIE5DTmFtZSBxdWFuZG8gb3MgbmFtZXNwYWNlcyBlc3RpdmVyZW0gYXRpdmFkb3MuCi0gICAgICAgIElEUkVGU0ludmFsaWQgPSBPIHZhbG9yIGRvIGF0cmlidXRvICJ7MH0iIGRlIHRpcG8gSURSRUZTIGRldmUgdGVyIHVtIG91IG1haXMgbm9tZXMuCi0gICAgICAgIElMTF9GT1JNRURfUEFSQU1FVEVSX0VOVElUWV9XSEVOX1VTRURfSU5fREVDTCA9IE8gdGV4dG8gZGUgc3Vic3RpdHVpXHUwMEU3XHUwMEUzbyBkYSBlbnRpZGFkZSBkbyBwYXJcdTAwRTJtZXRybyAiezB9IiBkZXZlIGluY2x1aXIgYXMgZGVjbGFyYVx1MDBFN1x1MDBGNWVzIGFuaW5oYWRhcyBjb3JyZXRhbWVudGUgcXVhbmRvIGEgcmVmZXJcdTAwRUFuY2lhIGRhIGVudGlkYWRlIGZvciB1c2FkYSBjb21vIHVtYSBkZWNsYXJhXHUwMEU3XHUwMEUzbyBjb21wbGV0YS4KLSAgICAgICAgSW1wcm9wZXJEZWNsYXJhdGlvbk5lc3RpbmcgPSBPIHRleHRvIGRlIHN1YnN0aXR1aVx1MDBFN1x1MDBFM28gZGEgZW50aWRhZGUgZG8gcGFyXHUwMEUybWV0cm8gInswfSIgZGV2ZSBpbmNsdWlyIGFzIGRlY2xhcmFcdTAwRTdcdTAwRjVlcyBhbmluaGFkYXMgY29ycmV0YW1lbnRlLgotICAgICAgICBJbXByb3Blckdyb3VwTmVzdGluZyA9IE8gdGV4dG8gZGUgc3Vic3RpdHVpXHUwMEU3XHUwMEUzbyBkYSBlbnRpZGFkZSBkbyBwYXJcdTAwRTJtZXRybyAiezB9IiBkZXZlIGluY2x1aXIgcGFyZXMgZGUgcGFyXHUwMEVBbnRlc2VzIGFuaW5oYWRvcyBjb3JyZXRhbWVudGUuCi0gICAgICAgIElOVkFMSURfUEVfSU5fQ09ORElUSU9OQUwgPSBPIHRleHRvIGRlIHN1YnN0aXR1aVx1MDBFN1x1MDBFM28gZGEgZW50aWRhZGUgZG8gcGFyXHUwMEUybWV0cm8gInswfSIgZGV2ZSBpbmNsdWlyIGEgc2VcdTAwRTdcdTAwRTNvIGNvbmRpY2lvbmFsIGludGVpcmEgb3UgYXBlbmFzIElOQ0xVREUgb3UgSUdOT1JFLgotICAgICAgICBNU0dfQVRUUklCVVRFX05PVF9ERUNMQVJFRCA9IE8gYXRyaWJ1dG8gInsxfSIgZGV2ZSBzZXIgZGVjbGFyYWRvIHBhcmEgbyB0aXBvIGRlIGVsZW1lbnRvICJ7MH0iLgotICAgICAgICBNU0dfQVRUUklCVVRFX1ZBTFVFX05PVF9JTl9MSVNUID0gTyBhdHJpYnV0byAiezB9IiBjb20gbyB2YWxvciAiezF9IiBkZXZlIHRlciB1bSB2YWxvciBkYSBsaXN0YSAiezJ9Ii4KLSAgICAgICAgTVNHX0FUVFZBTFVFX0NIQU5HRURfRFVSSU5HX05PUk1BTElaQVRJT05fV0hFTl9TVEFOREFMT05FID0gTyB2YWxvciAiezF9IiBkbyBhdHJpYnV0byAiezB9IiBuXHUwMEUzbyBkZXZlIHNlciBhbHRlcmFkbyBwb3IgbWVpbyBkYSBub3JtYWxpemFcdTAwRTdcdTAwRTNvIChwYXJhICJ7Mn0iKSBlbSB1bSBkb2N1bWVudG8gc3RhbmQtYWxvbmUuCi0gICAgICAgIE1TR19DT05URU5UX0lOQ09NUExFVEUgPSBPIGNvbnRlXHUwMEZBZG8gZG8gdGlwbyBkZSBlbGVtZW50byAiezB9IiBlc3RcdTAwRTEgaW5jb21wbGV0bzsgZWxlIGRldmUgY29ycmVzcG9uZGVyIGEgInsxfSIuCi0gICAgICAgIE1TR19DT05URU5UX0lOVkFMSUQgPSBPIGNvbnRlXHUwMEZBZG8gZG8gdGlwbyBkZSBlbGVtZW50byAiezB9IiBkZXZlIGNvcnJlc3BvbmRlciBhICJ7MX0iLgotICAgICAgICBNU0dfQ09OVEVOVF9JTlZBTElEX1NQRUNJRklFRCA9IE8gY29udGVcdTAwRkFkbyBkbyB0aXBvIGRlIGVsZW1lbnRvICJ7MH0iIGRldmUgY29ycmVzcG9uZGVyIGEgInsxfSIuIE5cdTAwRTNvIHNcdTAwRTNvIHBlcm1pdGlkb3Mgb3MgZmlsaG9zIGRvIHRpcG8gInsyfSIuCi0gICAgICAgIE1TR19ERUZBVUxURURfQVRUUklCVVRFX05PVF9TUEVDSUZJRUQgPSBPIGF0cmlidXRvICJ7MX0iIGRvIHRpcG8gZGUgZWxlbWVudG8gInswfSIgdGVtIHVtIHZhbG9yIHBhZHJcdTAwRTNvIGUgZGV2ZSBzZXIgZXNwZWNpZmljYWRvIGVtIHVtIGRvY3VtZW50byBzdGFuZC1hbG9uZS4KLSAgICAgICAgTVNHX0RVUExJQ0FURV9BVFRERUYgPSBPIGF0cmlidXRvICJ7MX0iIGpcdTAwRTEgZm9pIGRlY2xhcmFkbyBwYXJhIG8gdGlwbyBkZSBlbGVtZW50byAiezB9Ii4KLSAgICAgICAgTVNHX0VMRU1FTlRfQUxSRUFEWV9ERUNMQVJFRCA9IE8gdGlwbyBkZSBlbGVtZW50byAiezB9IiBuXHUwMEUzbyBkZXZlIHNlciBkZWNsYXJhZG8gbWFpcyBkZSB1bWEgdmV6LgotICAgICAgICBNU0dfRUxFTUVOVF9OT1RfREVDTEFSRUQgPSBPIHRpcG8gZGUgZWxlbWVudG8gInswfSIgZGV2ZSBzZXIgZGVjbGFyYWRvLgotICAgICAgICBNU0dfR1JBTU1BUl9OT1RfRk9VTkQgPSBPIGRvY3VtZW50byBcdTAwRTkgaW52XHUwMEUxbGlkbzogbmVuaHVtYSBncmFtXHUwMEUxdGljYSBlbmNvbnRyYWRhLgotICAgICAgICBNU0dfRUxFTUVOVF9XSVRIX0lEX1JFUVVJUkVEID0gVW0gZWxlbWVudG8gY29tIG8gaWRlbnRpZmljYWRvciAiezB9IiBkZXZlIGFwYXJlY2VyIG5vIGRvY3VtZW50by4KLSAgICAgICAgTVNHX0VYVEVSTkFMX0VOVElUWV9OT1RfUEVSTUlUVEVEID0gQSByZWZlclx1MDBFQW5jaWEgXHUwMEUwIGVudGlkYWRlIGV4dGVybmEgInswfSIgblx1MDBFM28gXHUwMEU5IHBlcm1pdGlkYSBlbSB1bSBkb2N1bWVudG8gc3RhbmQtYWxvbmUuCi0gICAgICAgIE1TR19GSVhFRF9BVFRWQUxVRV9JTlZBTElEID0gTyBhdHJpYnV0byAiezF9IiBjb20gbyB2YWxvciAiezJ9IiBkZXZlIHRlciB1bSB2YWxvciAiezN9Ii4KLSAgICAgICAgTVNHX01PUkVfVEhBTl9PTkVfSURfQVRUUklCVVRFID0gTyB0aXBvIGRlIGVsZW1lbnRvICJ7MH0iIGpcdTAwRTEgdGVtIG8gYXRyaWJ1dG8gInsxfSIgZG8gSUQgZG8gdGlwbzsgdW0gc2VndW5kbyBhdHJpYnV0byAiezJ9IiBkbyBJRCBkZSB0aXBvIG5cdTAwRTNvIFx1MDBFOSBwZXJtaXRpZG8uCi0gICAgICAgIE1TR19NT1JFX1RIQU5fT05FX05PVEFUSU9OX0FUVFJJQlVURSA9IE8gdGlwbyBkZSBlbGVtZW50byAiezB9IiBqXHUwMEUxIHRlbSBvIGF0cmlidXRvICJ7MX0iIGRvIHRpcG8gTk9UQVRJT047IHVtIHNlZ3VuZG8gYXRyaWJ1dG8gInsyfSIgZG8gdGlwbyBOT1RBVElPTiBuXHUwMEUzbyBcdTAwRTkgcGVybWl0aWRvLgotICAgICAgICBNU0dfTk9UQVRJT05fTk9UX0RFQ0xBUkVEX0ZPUl9OT1RBVElPTlRZUEVfQVRUUklCVVRFID0gQSBub3RhXHUwMEU3XHUwMEUzbyAiezF9IiBkZXZlIHNlciBkZWNsYXJhZGEgcXVhbmRvIHJlZmVyZW5jaWFkYSBuYSBsaXN0YSBkZSB0aXBvcyBkZSBub3RhXHUwMEU3XHUwMEUzbyBkbyBhdHJpYnV0byAiezB9Ii4KLSAgICAgICAgTVNHX05PVEFUSU9OX05PVF9ERUNMQVJFRF9GT1JfVU5QQVJTRURfRU5USVRZREVDTCA9IEEgbm90YVx1MDBFN1x1MDBFM28gInsxfSIgZGV2ZSBzZXIgZGVjbGFyYWRhIHF1YW5kbyByZWZlcmVuY2lhZGEgbmEgZGVjbGFyYVx1MDBFN1x1MDBFM28gZGEgZW50aWRhZGUgblx1MDBFM28gc3VibWV0aWRhIGEgcGFyc2luZyBwYXJhICJ7MH0iLgotICAgICAgICBNU0dfUkVGRVJFTkNFX1RPX0VYVEVSTkFMTFlfREVDTEFSRURfRU5USVRZX1dIRU5fU1RBTkRBTE9ORSA9IEEgcmVmZXJcdTAwRUFuY2lhIFx1MDBFMCBlbnRpZGFkZSAiezB9IiBkZWNsYXJhZGEgZW0gdW1hIGVudGlkYWRlIGV4dGVybmEgc3VibWV0aWRhIGEgcGFyc2luZyBuXHUwMEUzbyBcdTAwRTkgcGVybWl0aWRhIGVtIHVtIGRvY3VtZW50byBzdGFuZC1hbG9uZS4KLSAgICAgICAgTVNHX1JFUVVJUkVEX0FUVFJJQlVURV9OT1RfU1BFQ0lGSUVEID0gTyBhdHJpYnV0byAiezF9IiBcdTAwRTkgbmVjZXNzXHUwMEUxcmlvIGUgZGV2ZSBzZXIgZXNwZWNpZmljYWRvIHBhcmEgbyB0aXBvIGRlIGVsZW1lbnRvICJ7MH0iLgotICAgICAgICBNU0dfV0hJVEVfU1BBQ0VfSU5fRUxFTUVOVF9DT05URU5UX1dIRU5fU1RBTkRBTE9ORSA9IE5cdTAwRTNvIGRldmUgaGF2ZXIgZXNwYVx1MDBFN28gZW0gYnJhbmNvIGVudHJlIG9zIGVsZW1lbnRvcyBkZWNsYXJhZG9zIGVtIHVtYSBlbnRpZGFkZSBleHRlcm5hIHN1Ym1ldGlkYSBhIHBhcnNpbmcgY29tIG8gY29udGVcdTAwRkFkbyBkbyBlbGVtZW50byBlbSB1bSBkb2N1bWVudG8gc3RhbmQtYWxvbmUuCi0gICAgICAgIE5NVE9LRU5JbnZhbGlkID0gTyB2YWxvciBkbyBhdHJpYnV0byAiezB9IiBkbyB0aXBvIE5NVE9LRU4gZGV2ZSBzZXIgdW0gdG9rZW4gZGUgbm9tZS4KLSAgICAgICAgTk1UT0tFTlNJbnZhbGlkID0gTyB2YWxvciBkbyBhdHJpYnV0byAiezB9IiBkbyB0aXBvIE5NVE9LRU5TIGRldmUgdGVyIHVtIG91IG1haXMgdG9rZW5zIGRlIG5vbWUuCi0gICAgICAgIE5vTm90YXRpb25PbkVtcHR5RWxlbWVudCA9IE8gdGlwbyBkZSBlbGVtZW50byAiezB9IiBxdWUgZm9pIGRlY2xhcmFkbyBFTVBUWSBuXHUwMEUzbyBwb2RlIGRlY2xhcmFyIG8gYXRyaWJ1dG8gInsxfSIgZG8gdGlwbyBOT1RBVElPTi4KLSAgICAgICAgUm9vdEVsZW1lbnRUeXBlTXVzdE1hdGNoRG9jdHlwZWRlY2wgPSBPIGVsZW1lbnRvLXJhaXogZG8gZG9jdW1lbnRvICJ7MX0iIGRldmUgY29ycmVzcG9uZGVyIFx1MDBFMCByYWl6IGRlIERPQ1RZUEUgInswfSIuCi0gICAgICAgIFVuZGVjbGFyZWRFbGVtZW50SW5Db250ZW50U3BlYyA9IE8gbW9kZWxvIGRvIGNvbnRlXHUwMEZBZG8gZG8gZWxlbWVudG8gInswfSIgcmVmZXJlLXNlIGFvIGVsZW1lbnRvIG5cdTAwRTNvIGRlY2xhcmFkbyAiezF9Ii4KLSAgICAgICAgVW5pcXVlTm90YXRpb25OYW1lID0gQSBkZWNsYXJhXHUwMEU3XHUwMEUzbyBkYSBub3RhXHUwMEU3XHUwMEUzbyAiezB9IiBuXHUwMEUzbyBcdTAwRTkgZXhjbHVzaXZhLiBVbSBOb21lIGZvcm5lY2lkbyBuXHUwMEUzbyBkZXZlIHNlciBkZWNsYXJhZG8gZW0gbWFpcyBkZSB1bWEgZGVjbGFyYVx1MDBFN1x1MDBFM28gZGUgbm90YVx1MDBFN1x1MDBFM28uCi0gICAgICAgIEVOVElUWUZhaWxlZEluaXRpYWxpemVHcmFtbWFyID0gIFZhbGlkYWRvciBkZSBFTlRJVFlEYXRhdHlwZTogRmFsaGEgYW8gY2hhbWFyIG8gbVx1MDBFOXRvZG8gZGUgaW5pY2lhbGl6YVx1MDBFN1x1MDBFM28gY29tIHVtYSByZWZlclx1MDBFQW5jaWEgZGUgR3JhbVx1MDBFMXRpY2Egdlx1MDBFMWxpZGEuIFx0Ci0gICAgICAgIEVOVElUWU5vdFVucGFyc2VkID0gRU5USVRZICJ7MH0iIG5cdTAwRTNvIFx1MDBFOSBzdWJtZXRpZGEgYSBwYXJzaW5nLgotICAgICAgICBFTlRJVFlOb3RWYWxpZCA9IEVOVElUWSAiezB9IiBuXHUwMEUzbyBcdTAwRTkgdlx1MDBFMWxpZGEuCi0gICAgICAgIEVtcHR5TGlzdCA9IE8gdmFsb3IgZG9zIHRpcG9zIEVOVElUSUVTLCBJRFJFRlMgZSBOTVRPS0VOUyBuXHUwMEUzbyBwb2RlIGVzdGFyIG5hIGxpc3RhIHZhemlhLgotCi0jIEVudGl0eSByZWxhdGVkIG1lc3NhZ2VzCi0jIDMuMSBTdGFydC1UYWdzLCBFbmQtVGFncywgYW5kIEVtcHR5LUVsZW1lbnQgVGFncwotICAgICAgICBSZWZlcmVuY2VUb0V4dGVybmFsRW50aXR5ID0gQSByZWZlclx1MDBFQW5jaWEgZGEgZW50aWRhZGUgZXh0ZXJuYSAiJnswfTsiIG5cdTAwRTNvIFx1MDBFOSBwZXJtaXRpZGEgZW0gdW0gdmFsb3IgZG8gYXRyaWJ1dG8uCi0gICAgICAgIEFjY2Vzc0V4dGVybmFsRFREID0gRFREIEV4dGVybm86IGZhbGhhIGFvIGxlciBvIERURCAnJ3swfScnIGV4dGVybm8gcG9ycXVlIG8gYWNlc3NvIGEgJyd7MX0nJyBuXHUwMEUzbyBcdTAwRTkgcGVybWl0aWRvIGVtIGRlY29yclx1MDBFQW5jaWEgZGUgdW1hIHJlc3RyaVx1MDBFN1x1MDBFM28gZGVmaW5pZGEgcGVsYSBwcm9wcmllZGFkZSBhY2Nlc3NFeHRlcm5hbERURC4KLSAgICAgICAgQWNjZXNzRXh0ZXJuYWxFbnRpdHkgPSBFbnRpZGFkZSBFeHRlcm5hOiBmYWxoYSBhbyBsZXIgbyBkb2N1bWVudG8gJyd7MH0nJyBleHRlcm5vIHBvcnF1ZSBvIGFjZXNzbyBhICcnezF9Jycgblx1MDBFM28gXHUwMEU5IHBlcm1pdGlkbyBlbSBkZWNvcnJcdTAwRUFuY2lhIGRlIHVtYSByZXN0cmlcdTAwRTdcdTAwRTNvIGRlZmluaWRhIHBlbGEgcHJvcHJpZWRhZGUgYWNjZXNzRXh0ZXJuYWxEVEQuCi0KLSMgNC4xIENoYXJhY3RlciBhbmQgRW50aXR5IFJlZmVyZW5jZXMKLSAgICAgICAgRW50aXR5Tm90RGVjbGFyZWQgPSBBIGVudGlkYWRlICJ7MH0iIGZvaSByZWZlcmVuY2lhZGEsIG1hcyBuXHUwMEUzbyBkZWNsYXJhZGEuCi0gICAgICAgIFJlZmVyZW5jZVRvVW5wYXJzZWRFbnRpdHkgPSBBIHJlZmVyXHUwMEVBbmNpYSBkYSBlbnRpZGFkZSBuXHUwMEUzbyBzdWJtZXRpZGEgYSBwYXJzaW5nICImezB9OyIgblx1MDBFM28gXHUwMEU5IHBlcm1pdGlkYS4KLSAgICAgICAgUmVjdXJzaXZlUmVmZXJlbmNlID0gUmVmZXJcdTAwRUFuY2lhIGRhIGVudGlkYWRlIHJlY3Vyc2l2YSAiezB9Ii4gKENhbWluaG8gZGUgcmVmZXJcdTAwRUFuY2lhOiB7MX0pLAotICAgICAgICBSZWN1cnNpdmVHZW5lcmFsUmVmZXJlbmNlID0gUmVmZXJcdTAwRUFuY2lhIGdlcmFsIGRhIGVudGlkYWRlIHJlY3Vyc2l2YSAiJnswfTsiLiAoQ2FtaW5obyBkZSByZWZlclx1MDBFQW5jaWE6IHsxfSksCi0gICAgICAgIFJlY3Vyc2l2ZVBFUmVmZXJlbmNlID0gUmVmZXJcdTAwRUFuY2lhIGRhIGVudGlkYWRlIGRvIHBhclx1MDBFMm1ldHJvIHJlY3Vyc2l2byAiJXswfTsiLiAoQ2FtaW5obyBkZSByZWZlclx1MDBFQW5jaWE6IHsxfSksCi0jIDQuMy4zIENoYXJhY3RlciBFbmNvZGluZyBpbiBFbnRpdGllcwotICAgICAgICBFbmNvZGluZ05vdFN1cHBvcnRlZCA9IEEgY29kaWZpY2FcdTAwRTdcdTAwRTNvICJ7MH0iIG5cdTAwRTNvIFx1MDBFOSBzdXBvcnRhZGEuCi0gICAgICAgIEVuY29kaW5nUmVxdWlyZWQgPSBVbWEgZW50aWRhZGUgc3VibWV0aWRhIGEgcGFyc2luZyBuXHUwMEUzbyBjb2RpZmljYWRhIGVtIFVURi04IG5lbSBlbSBVVEYtMTYgZGV2ZSBjb250ZXIgdW1hIGRlY2xhcmFcdTAwRTdcdTAwRTNvIGRlIGNvZGlmaWNhXHUwMEU3XHUwMEUzby4KLSAgICAgICAgCi0jIE5hbWVzcGFjZXMgc3VwcG9ydAotIyA0LiBVc2luZyBRdWFsaWZpZWQgTmFtZXMKLSAgICAgICAgSWxsZWdhbFFOYW1lID0gTyBlbGVtZW50byBvdSBvIGF0cmlidXRvIG5cdTAwRTNvIGNvcnJlc3BvbmRlbSBcdTAwRTAgcHJvZHVcdTAwRTdcdTAwRTNvIFFOYW1lOiBRTmFtZTo6PShOQ05hbWUnOicpP05DTmFtZS4gCi0gICAgICAgIEVsZW1lbnRYTUxOU1ByZWZpeCA9IE8gZWxlbWVudG8gInswfSIgblx1MDBFM28gcG9kZSB0ZXIgInhtbG5zIiBjb21vIHNldSBwcmVmaXhvLgotICAgICAgICBFbGVtZW50UHJlZml4VW5ib3VuZCA9IE8gcHJlZml4byAiezB9IiBkbyBlbGVtZW50byAiezF9IiBuXHUwMEUzbyBlc3RcdTAwRTEgdmluY3VsYWRvLgotICAgICAgICBBdHRyaWJ1dGVQcmVmaXhVbmJvdW5kID0gTyBwcmVmaXhvICJ7Mn0iIGRvIGF0cmlidXRvICJ7MX0iIGFzc29jaWFkbyBhIHVtIHRpcG8gZGUgZWxlbWVudG8gInswfSIgblx1MDBFM28gZXN0XHUwMEUxIHZpbmN1bGFkby4KLSAgICAgICAgRW1wdHlQcmVmaXhlZEF0dE5hbWUgPSBPIHZhbG9yIGRvIGF0cmlidXRvICJ7MH0iIFx1MDBFOSBpbnZcdTAwRTFsaWRvLiBBc3NvY2lhXHUwMEU3XHUwMEY1ZXMgZGUgbmFtZXNwYWNlIHByZWZpeGFkYXMgblx1MDBFM28gcG9kZW0gZmljYXIgdmF6aWFzLgotICAgICAgICBQcmVmaXhEZWNsYXJlZCA9IE8gcHJlZml4byBkbyBuYW1lc3BhY2UgInswfSIgblx1MDBFM28gZm9pIGRlY2xhcmFkby4KLSAgICAgICAgQ2FudEJpbmRYTUxOUyA9IE8gcHJlZml4byAieG1sbnMiIG5cdTAwRTNvIHBvZGUgc2VyIHZpbmN1bGFkbyBhIHVtIG5hbWVzcGFjZSBleHBsaWNpdGFtZW50ZSwgYXNzaW0gY29tbyBvIG5hbWVzcGFjZSBkZSAieG1sbnMiIG5cdTAwRTNvIHBvZGUgc2VyIHZpbmN1bGFkbyBhIHVtIHByZWZpeG8gZXhwbGljaXRhbWVudGUuCi0gICAgICAgIENhbnRCaW5kWE1MID0gTyBwcmVmaXhvICJ4bWwiIG5cdTAwRTNvIHBvZGUgc2VyIHZpbmN1bGFkbyBhIHVtIG5hbWVzcGFjZSBkaWZlcmVudGUgZG8gbmFtZXNwYWNlIGNvbXVtLCBhc3NpbSBjb21vIG8gbmFtZXNwYWNlIGRlICJ4bWwiIG5cdTAwRTNvIHBvZGUgc2VyIHZpbmN1bGFkbyBhIHVtIHByZWZpeG8gZGlmZXJlbnRlIGRlICJ4bWwiLgotICAgICAgICBNU0dfQVRUX0RFRkFVTFRfSU5WQUxJRCA9IE8gZGVmYXVsdFZhbHVlICJ7MX0iIGRvIGF0cmlidXRvICJ7MH0iIG5cdTAwRTNvIFx1MDBFOSB2XHUwMEUxbGlkbyBwYXJhIGFzIHJlc3RyaVx1MDBFN1x1MDBGNWVzIGxcdTAwRTl4aWNhcyBkZXN0ZSB0aXBvIGRlIGF0cmlidXRvLgotCi0jIFJFVklTSVQ6IFRoZXNlIG5lZWQgbWVzc2FnZXMKLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0FGVEVSX1NZU1RFTUxJVEVSQUxfSU5fRVhURVJOQUxJRD1NU0dfU1BBQ0VfUkVRVUlSRURfQUZURVJfU1lTVEVNTElURVJBTF9JTl9FWFRFUk5BTElECi0gICAgICAgIE9wZW5RdW90ZU1pc3NpbmdJbkRlY2w9T3BlblF1b3RlTWlzc2luZ0luRGVjbAotICAgICAgICBJbnZhbGlkQ2hhckluTGl0ZXJhbD1JbnZhbGlkQ2hhckluTGl0ZXJhbAotCi0KLSMgSW1wbGVtZW50YXRpb24gbGltaXRzCi0gICAgICAgIEVudGl0eUV4cGFuc2lvbkxpbWl0PUpBWFAwMDAxMDAwMTogTyBwYXJzZXIgZGV0ZWN0b3UgbWFpcyBkZSAiezB9IiBleHBhbnNcdTAwRjVlcyBkYSBlbnRpZGFkZSBuZXN0ZSBkb2N1bWVudG8uIEVzdGUgXHUwMEU5IG8gbGltaXRlIGltcG9zdG8gcGVsbyBKREsuCi0gICAgICAgIEVsZW1lbnRBdHRyaWJ1dGVMaW1pdD1KQVhQMDAwMTAwMDI6IG8gZWxlbWVudG8gInswfSIgdGVtIG1haXMgZGUgInsxfSIgYXRyaWJ1dG9zLiAiezF9IiBcdTAwRTkgbyBsaW1pdGUgaW1wb3N0byBwZWxvIEpESy4KLSAgICAgICAgTWF4RW50aXR5U2l6ZUxpbWl0PUpBWFAwMDAxMDAwMzogbyB0YW1hbmhvIGRhIGVudGlkYWRlICJ7MH0iIFx1MDBFOSAiezF9IiwgbyBxdWUgZXhjZWRlIG8gbGltaXRlIGRlICJ7Mn0iIGRlZmluaWRvIHBvciAiezN9Ii4KLSAgICAgICAgVG90YWxFbnRpdHlTaXplTGltaXQ9SkFYUDAwMDEwMDA0OiBvIHRhbWFuaG8gYWN1bXVsYWRvIGRlIGVudGlkYWRlcyBcdTAwRTkgInswfSIsIG8gcXVlIGV4Y2VkZXUgbyBsaW1pdGUgZGUgInsxfSIgZGVmaW5pZG8gcG9yICJ7Mn0iLgotICAgICAgICBNYXhYTUxOYW1lTGltaXQ9SkFYUDAwMDEwMDA1OiBvIHRhbWFuaG8gZGEgZW50aWRhZGUgInswfSIgXHUwMEU5ICJ7MX0iLCBvIHF1ZSBleGNlZGUgbyBsaW1pdGUgZGUgInsyfSIgZGVmaW5pZG8gcG9yICJ7M30iLgotICAgICAgICBNYXhFbGVtZW50RGVwdGhMaW1pdD1KQVhQMDAwMTAwMDY6IG8gZWxlbWVudG8gInswfSIgdGVtIHVtYSBwcm9mdW5kaWRhZGUgZGUgInsxfSIgcXVlIGV4Y2VkZSBvIGxpbWl0ZSBkZSAiezJ9IiBkZWZpbmlkbyBwb3IgInszfSIuCi0gICAgICAgIEVudGl0eVJlcGxhY2VtZW50TGltaXQ9SkFYUDAwMDEwMDA3OiBPIG5cdTAwRkFtZXJvIHRvdGFsIGRlIG5cdTAwRjNzIG5hcyByZWZlclx1MDBFQW5jaWFzIGRhIGVudGlkYWRlIFx1MDBFOSBkZSAiezB9IiwgbyBxdWUgZXN0XHUwMEUxIGFjaW1hIGRvIGxpbWl0ZSBkZSAiezF9IiBkZWZpbmlkbyBwb3IgInsyfSIuCi0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hNTE1lc3NhZ2VzX3N2LnByb3BlcnRpZXMgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9YTUxNZXNzYWdlc19zdi5wcm9wZXJ0aWVzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0ZjU0ZTVmLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hNTE1lc3NhZ2VzX3N2LnByb3BlcnRpZXMKKysrIC9kZXYvbnVsbApAQCAtMSwzMDUgKzAsMCBAQAotIyBUaGlzIGZpbGUgY29udGFpbnMgZXJyb3IgYW5kIHdhcm5pbmcgbWVzc2FnZXMgcmVsYXRlZCB0byBYTUwKLSMgVGhlIG1lc3NhZ2VzIGFyZSBhcnJhbmdlZCBpbiBrZXkgYW5kIHZhbHVlIHR1cGxlcyBpbiBhIExpc3RSZXNvdXJjZUJ1bmRsZS4KLSMKLSMgQHZlcnNpb24KLQotICAgICAgICBCYWRNZXNzYWdlS2V5ID0gSGl0dGFyIGludGUgZmVsbWVkZGVsYW5kZXQgc29tIG1vdHN2YXJhciBtZWRkZWxhbmRlbnlja2Vsbi4KLSAgICAgICAgRm9ybWF0RmFpbGVkID0gRXR0IGludGVybnQgZmVsIGludHJcdTAwRTRmZmFkZSB2aWQgZm9ybWF0ZXJpbmcgYXYgZlx1MDBGNmxqYW5kZSBtZWRkZWxhbmRlOlxuICAKLSAgICAgICAgCi0jIERvY3VtZW50IG1lc3NhZ2VzCi0gICAgICAgIFByZW1hdHVyZUVPRj1GaWxlbiBoYXIgYXZzbHV0YXRzIGZcdTAwRjZyIHRpZGlndC4KLSMgMi4xIFdlbGwtRm9ybWVkIFhNTCBEb2N1bWVudHMKLSAgICAgICAgUm9vdEVsZW1lbnRSZXF1aXJlZCA9IFJvdGVsZW1lbnRldCBrclx1MDBFNHZzIGkgZXR0IHZcdTAwRTRsZm9ybXVsZXJhdCBkb2t1bWVudC4KLSMgMi4yIENoYXJhY3RlcnMKLQotICAgICAgICBJbnZhbGlkQ2hhckluQ0RTZWN0ID0gRXR0IG9naWx0aWd0IFhNTC10ZWNrZW4gKFVuaWNvZGU6IDB4ezB9KSBoaXR0YWRlcyBpIENEQVRBLXNla3Rpb25lbi4KLSAgICAgICAgSW52YWxpZENoYXJJbkNvbnRlbnQgPSBFdHQgb2dpbHRpZ3QgWE1MLXRlY2tlbiAoVW5pY29kZTogMHh7MH0pIGhpdHRhZGVzIGkgZG9rdW1lbnRldHMgZWxlbWVudGlubmVoXHUwMEU1bGwuCi0gICAgICAgIFR3b0NvbG9uc0luUU5hbWUgPSBFbiBvZ2lsdGlnIGFuZHJhIGZcdTAwRjZyZWtvbXN0IGF2ICc6JyBoaXR0YWRlcyBpIGVsZW1lbnR0eXAgZWxsZXIgYXR0cmlidXRuYW1uLgotICAgICAgICBDb2xvbk5vdExlZ2FsV2l0aE5TID0gS29sb24gXHUwMEU0ciBpbnRlIHRpbGxcdTAwRTV0ZXQgaSBuYW1uZXQgJyd7MH0nJyBvbSBuYW1ucnltZGVyIFx1MDBFNHIgYWt0aXZlcmFkZS4KLSAgICAgICAgSW52YWxpZENoYXJJbk1pc2MgPSBFdHQgb2dpbHRpZ3QgWE1MLXRlY2tlbiAoVW5pY29kZTogMHh7MH0pIGhpdHRhZGVzIGkga29kdGV4dCBlZnRlciBlbGVtZW50aW5uZWhcdTAwRTVsbGV0LgotICAgICAgICBJbnZhbGlkQ2hhckluUHJvbG9nID0gRXR0IG9naWx0aWd0IFhNTC10ZWNrZW4gKFVuaWNvZGU6IDB4ezB9KSBoaXR0YWRlcyBpIGRva3VtZW50ZXRzIHByb2xvZy4KLSAgICAgICAgSW52YWxpZENoYXJJblhNTERlY2wgPSBFdHQgb2dpbHRpZ3QgWE1MLXRlY2tlbiAoVW5pY29kZTogMHh7MH0pIGhpdHRhZGVzIGkgWE1MLWRla2xhcmF0aW9uZW4uCi0jIDIuNCBDaGFyYWN0ZXIgRGF0YSBhbmQgTWFya3VwCi0gICAgICAgIENERW5kSW5Db250ZW50ID0gVGVja2Vuc2VrdmVuc2VuICJdXT4iIGZcdTAwRTVyIGludGUgZlx1MDBGNnJla29tbWEgaSBpbm5laFx1MDBFNWxsZXQsIHNcdTAwRTV2aWRhIGRldCBpbnRlIGFudlx1MDBFNG5kcyBmXHUwMEY2ciBhdHQgbWFya2VyYSBzbHV0IGF2IENEQVRBLXNla3Rpb24uCi0jIDIuNyBDREFUQSBTZWN0aW9ucwotICAgICAgICBDRFNlY3RVbnRlcm1pbmF0ZWQgPSBDREFUQS1zZWt0aW9uZW4gbVx1MDBFNXN0ZSBzbHV0YSBtZWQgIl1dPiIuCi0jIDIuOCBQcm9sb2cgYW5kIERvY3VtZW50IFR5cGUgRGVjbGFyYXRpb24KLSAgICAgICAgWE1MRGVjbE11c3RCZUZpcnN0ID0gWE1MLWRla2xhcmF0aW9uZW4gZlx1MDBFNXIgZW5kYXN0IGZcdTAwRjZyZWtvbW1hIGFsbHJhIFx1MDBGNnZlcnN0IGkgZG9rdW1lbnRldC4KLSAgICAgICAgRXFSZXF1aXJlZEluWE1MRGVjbCA9IFRlY2tuZXQgJycgPSAnJyBtXHUwMEU1c3RlIGFuZ2VzIGVmdGVyICJ7MH0iIGkgWE1MLWRla2xhcmF0aW9uZW4uCi0gICAgICAgIFF1b3RlUmVxdWlyZWRJblhNTERlY2wgPSBWXHUwMEU0cmRldCBzb20gZlx1MDBGNmxqZXIgInswfSIgaSBYTUwtZGVrbGFyYXRpb25lbiBtXHUwMEU1c3RlIG9tZ2VzIGF2IGNpdGF0dGVja2VuLgotICAgICAgICBYTUxEZWNsVW50ZXJtaW5hdGVkID0gWE1MLWRla2xhcmF0aW9uZW4gbVx1MDBFNXN0ZSBhdnNsdXRhcyBtZWQgIj8+Ii4KLSAgICAgICAgVmVyc2lvbkluZm9SZXF1aXJlZCA9IFZlcnNpb25lbiBrclx1MDBFNHZzIGkgWE1MLWRla2xhcmF0aW9uZW4uCi0gICAgICAgIFNwYWNlUmVxdWlyZWRCZWZvcmVWZXJzaW9uSW5YTUxEZWNsID0gVG9tdCB1dHJ5bW1lIGtyXHUwMEU0dnMgZlx1MDBGNnJlIHZlcnNpb25lbnMgcHNldWRvYXR0cmlidXQgaSBYTUwtZGVrbGFyYXRpb25lbi4KLSAgICAgICAgU3BhY2VSZXF1aXJlZEJlZm9yZUVuY29kaW5nSW5YTUxEZWNsID0gVG9tdCB1dHJ5bW1lIGtyXHUwMEU0dnMgZlx1MDBGNnJlIGtvZG5pbmdlbnMgcHNldWRvYXR0cmlidXQgaSBYTUwtZGVrbGFyYXRpb25lbi4KLSAgICAgICAgU3BhY2VSZXF1aXJlZEJlZm9yZVN0YW5kYWxvbmUgPSBUb210IHV0cnltbWUga3JcdTAwRTR2cyBmXHUwMEY2cmUga29kbmluZ2VucyBwc2V1ZG9hdHRyaWJ1dCBpIFhNTC1kZWtsYXJhdGlvbmVuLgotICAgICAgICBNYXJrdXBOb3RSZWNvZ25pemVkSW5Qcm9sb2cgPSBEb2t1bWVudGV0cyBrb2R0ZXh0IGZcdTAwRjZyZSByb3RlbGVtZW50ZXQgbVx1MDBFNXN0ZSB2YXJhIHZcdTAwRTRsZm9ybXVsZXJhZC4KLSAgICAgICAgTWFya3VwTm90UmVjb2duaXplZEluTWlzYyA9IERva3VtZW50ZXRzIGtvZHRleHQgZWZ0ZXIgcm90ZWxlbWVudGV0IG1cdTAwRTVzdGUgdmFyYSB2XHUwMEU0bGZvcm11bGVyYWQuCi0gICAgICAgIEFscmVhZHlTZWVuRG9jdHlwZSA9IERPQ1RZUEUgaGFyIHJlZGFuIHRhZ2l0cyBlbW90LgotICAgICAgICBEb2N0eXBlTm90QWxsb3dlZCA9IERPQ1RZUEUgXHUwMEU0ciBpbnRlIHRpbGxcdTAwRTV0ZXQgb20gZnVua3Rpb25lbiAiaHR0cDovL2FwYWNoZS5vcmcveG1sL2ZlYXR1cmVzL2Rpc2FsbG93LWRvY3R5cGUtZGVjbCIgYW5nZXMgc29tIHRydWUuCi0gICAgICAgIENvbnRlbnRJbGxlZ2FsSW5Qcm9sb2cgPSBJbm5laFx1MDBFNWxsZXQgXHUwMEU0ciBpbnRlIHRpbGxcdTAwRTV0ZXQgaSBwcm9sb2dlbi4KLSAgICAgICAgUmVmZXJlbmNlSWxsZWdhbEluUHJvbG9nID0gUmVmZXJlbnNlbiBcdTAwRTRyIGludGUgdGlsbFx1MDBFNXRlbiBpIHByb2xvZ2VuLgotIyBUcmFpbGluZyBNaXNjCi0gICAgICAgIENvbnRlbnRJbGxlZ2FsSW5UcmFpbGluZ01pc2M9SW5uZWhcdTAwRTVsbGV0IFx1MDBFNHIgaW50ZSB0aWxsXHUwMEU1dGV0IGkgZWZ0ZXJmXHUwMEY2bGphbmRlIHNla3Rpb24uCi0gICAgICAgIFJlZmVyZW5jZUlsbGVnYWxJblRyYWlsaW5nTWlzYz1SZWZlcmVuc2VuIFx1MDBFNHIgaW50ZSB0aWxsXHUwMEU1dGVuIGkgZWZ0ZXJmXHUwMEY2bGphbmRlIHNla3Rpb24uCi0gICAgICAgIAotIyAyLjkgU3RhbmRhbG9uZSBEb2N1bWVudCBEZWNsYXJhdGlvbgotICAgICAgICBTRERlY2xJbnZhbGlkID0gRGVrbGFyYXRpb25zdlx1MDBFNHJkZXQgZlx1MDBGNnIgZnJpc3RcdTAwRTVlbmRlIGRva3VtZW50IG1cdTAwRTVzdGUgdmFyYSAieWVzIiBlbGxlciAibm8iLCBpbnRlICJ7MH0iLgotICAgICAgICBTRERlY2xOYW1lSW52YWxpZCA9IERldCBmcmlzdFx1MDBFNWVuZGUgbmFtbmV0IGkgWE1MLWRla2xhcmF0aW9uZW4ga2FuIHZhcmEgZmVsc3RhdmF0LgotIyAyLjEyIExhbmd1YWdlIElkZW50aWZpY2F0aW9uCi0gICAgICAgIFhNTExhbmdJbnZhbGlkID0gQXR0cmlidXR2XHUwMEU0cmRldCAiezB9IiBmXHUwMEY2ciB4bWw6bGFuZyBcdTAwRTRyIGVuIG9naWx0aWcgc3ByXHUwMEU1a2lkZW50aWZpZXJhcmUuCi0jIDMuIExvZ2ljYWwgU3RydWN0dXJlcwotICAgICAgICBFVGFnUmVxdWlyZWQgPSBFbGVtZW50dHlwICJ7MH0iIG1cdTAwRTVzdGUgYXZzbHV0YXMgbWVkIG1hdGNoYW5kZSBzbHV0dGFnZyAiPC97MH0+Ii4KLSMgMy4xIFN0YXJ0LVRhZ3MsIEVuZC1UYWdzLCBhbmQgRW1wdHktRWxlbWVudCBUYWdzCi0gICAgICAgIEVsZW1lbnRVbnRlcm1pbmF0ZWQgPSBFbGVtZW50dHlwICJ7MH0iIG1cdTAwRTVzdGUgZlx1MDBGNmxqYXMgYXYgblx1MDBFNWdvbmRlcmEgYXYgYXR0cmlidXRzcGVjaWZpa2F0aW9uZXJuYSAiPiIgZWxsZXIgIi8+Ii4KLSAgICAgICAgRXFSZXF1aXJlZEluQXR0cmlidXRlID0gQXR0cmlidXRuYW1uZXQgInsxfSIgc29tIGFzc29jaWVyYXMgbWVkIGVsZW1lbnR0eXAgInswfSIgbVx1MDBFNXN0ZSBmXHUwMEY2bGphcyBhdiBsaWtoZXRzdGVja25ldCAoJycgPSAnJykuCi0gICAgICAgIE9wZW5RdW90ZUV4cGVjdGVkID0gXHUwMEQ2cHBuaW5nc2NpdGF0dGVja2VuIGZcdTAwRjZydlx1MDBFNG50YXMgZlx1MDBGNnIgYXR0cmlidXRldCAiezF9IiBzb20gYXNzb2NpZXJhcyBtZWQgZWxlbWVudHR5cCAiezB9Ii4KLSAgICAgICAgQ2xvc2VRdW90ZUV4cGVjdGVkID0gU2x1dGNpdGF0dGVja2VuIGZcdTAwRjZydlx1MDBFNG50YXMgZlx1MDBGNnIgYXR0cmlidXRldCAiezF9IiBzb20gYXNzb2NpZXJhcyBtZWQgZWxlbWVudHR5cCAiezB9Ii4KLSAgICAgICAgQXR0cmlidXRlTm90VW5pcXVlID0gQXR0cmlidXRldCAiezF9IiBoYXIgcmVkYW4gYW5nZXR0cyBmXHUwMEY2ciBlbGVtZW50ZXQgInswfSIuCi0gICAgICAgIEF0dHJpYnV0ZU5TTm90VW5pcXVlID0gQXR0cmlidXRldCAiezF9IiBidW5kZXQgdGlsbCBuYW1ucnltZGVuICJ7Mn0iIGhhciByZWRhbiBhbmdldHRzIGZcdTAwRjZyIGVsZW1lbnRldCAiezB9Ii4KLSAgICAgICAgRVRhZ1VudGVybWluYXRlZCA9IFNsdXR0YWdnZW4gZlx1MDBGNnIgZWxlbWVudHR5cCAiezB9IiBtXHUwMEU1c3RlIGF2c2x1dGFzIG1lZCBlbiAnJz4nJy1hdmdyXHUwMEU0bnNhcmUuCi0gICAgICAgIE1hcmt1cE5vdFJlY29nbml6ZWRJbkNvbnRlbnQgPSBFbGVtZW50aW5uZWhcdTAwRTVsbGV0IG1cdTAwRTVzdGUgYmVzdFx1MDBFNSBhdiB2XHUwMEU0bGZvcm11bGVyYWQoZSkgdGVja2VuZGF0YSBlbGxlciBrb2R0ZXh0LgotICAgICAgICBEb2N0eXBlSWxsZWdhbEluQ29udGVudCA9IERPQ1RZUEUgXHUwMEU0ciBpbnRlIHRpbGxcdTAwRTV0ZXQgaSBpbm5laFx1MDBFNWxsZXQuCi0jIDQuMSBDaGFyYWN0ZXIgYW5kIEVudGl0eSBSZWZlcmVuY2VzCi0gICAgICAgIFJlZmVyZW5jZVVudGVybWluYXRlZCA9IFJlZmVyZW5zZW4gbVx1MDBFNXN0ZSBhdnNsdXRhcyBtZWQgZW4gJzsnLWF2Z3JcdTAwRTRuc2FyZS4KLSMgNC4zLjIgV2VsbC1Gb3JtZWQgUGFyc2VkIEVudGl0aWVzCi0gICAgICAgIFJlZmVyZW5jZU5vdEluT25lRW50aXR5ID0gUmVmZXJlbnNlbiBtXHUwMEU1c3RlIGZpbm5hcyBtZWQgaW5vbSBzYW1tYSB0b2xrYWRlIGVuaGV0LgotICAgICAgICBFbGVtZW50RW50aXR5TWlzbWF0Y2ggPSBFbGVtZW50ZXQgInswfSIgbVx1MDBFNXN0ZSBiXHUwMEY2cmphIG9jaCBzbHV0YSBpbm9tIHNhbW1hIGVuaGV0LgotICAgICAgICBNYXJrdXBFbnRpdHlNaXNtYXRjaD1YTUwtZG9rdW1lbnRzdHJ1a3R1cmVyIG1cdTAwRTVzdGUgYlx1MDBGNnJqYSBvY2ggc2x1dGEgaW5vbSBzYW1tYSBlbmhldC4KLSAgICAgICAgCi0jIE1lc3NhZ2VzIGNvbW1vbiB0byBEb2N1bWVudCBhbmQgRFRECi0jIDIuMiBDaGFyYWN0ZXJzCi0gICAgICAgIEludmFsaWRDaGFySW5BdHRWYWx1ZSA9IEV0dCBvZ2lsdGlndCBYTUwtdGVja2VuIChVbmljb2RlOiAweHsyfSkgaGl0dGFkZXMgaSBhdHRyaWJ1dHZcdTAwRTRyZGV0ICJ7MX0iIG9jaCBlbGVtZW50ZXQgXHUwMEU0ciAiezB9Ii4KLSAgICAgICAgSW52YWxpZENoYXJJbkNvbW1lbnQgPSBFdHQgb2dpbHRpZ3QgWE1MLXRlY2tlbiAoVW5pY29kZTogMHh7MH0pIGhpdHRhZGVzIGkga29tbWVudGFyZW4uCi0gICAgICAgIEludmFsaWRDaGFySW5QSSA9IEV0dCBvZ2lsdGlndCBYTUwtdGVja2VuIChVbmljb2RlOiAweHswfSkgaGl0dGFkZXMgaSBiZWFyYmV0bmluZ3NpbnN0cnVrdGlvbmVuLgotICAgICAgICBJbnZhbGlkQ2hhckluSW50ZXJuYWxTdWJzZXQgPSBFdHQgb2dpbHRpZ3QgWE1MLXRlY2tlbiAoVW5pY29kZTogMHh7MH0pIGhpdHRhZGVzIGkgZGVuIGludGVybmEgZGVsbVx1MDBFNG5nZGVuIGkgRFRELgotICAgICAgICBJbnZhbGlkQ2hhckluVGV4dERlY2wgPSBFdHQgb2dpbHRpZ3QgWE1MLXRlY2tlbiAoVW5pY29kZTogMHh7MH0pIGhpdHRhZGVzIGkgdGV4dGRla2xhcmF0aW9uZW4uCi0jIDIuMyBDb21tb24gU3ludGFjdGljIENvbnN0cnVjdHMKLSAgICAgICAgUXVvdGVSZXF1aXJlZEluQXR0VmFsdWUgPSBBdHRyaWJ1dHZcdTAwRTRyZGV0ICJ7MX0iIG1cdTAwRTVzdGUgYlx1MDBGNnJqYSBtZWQgYW50aW5nZW4gZW5rZWx0IGVsbGVyIGR1YmJlbHQgY2l0YXR0ZWNrZW4uCi0gICAgICAgIExlc3N0aGFuSW5BdHRWYWx1ZSA9IEF0dHJpYnV0dlx1MDBFNHJkZXQgInsxfSIgc29tIGFzc29jaWVyYXMgbWVkIGVsZW1lbnR0eXAgInswfSIgZlx1MDBFNXIgaW50ZSBpbm5laFx1MDBFNWxsYSBuXHUwMEU1Z290ICcnPCcnLXRlY2tlbi4KLSAgICAgICAgQXR0cmlidXRlVmFsdWVVbnRlcm1pbmF0ZWQgPSBBdHRyaWJ1dHZcdTAwRTRyZGV0ICJ7MX0iIG1cdTAwRTVzdGUgYXZzbHV0YXMgbWVkIG1hdGNoYW5kZSBjaXRhdHRlY2tlbi4KLSMgMi41IENvbW1lbnRzCi0gICAgICAgIEludmFsaWRDb21tZW50U3RhcnQgPSBLb21tZW50YXJlciBtXHUwMEU1c3RlIGlubGVkYXMgbWVkICI8IS0tIi4KLSAgICAgICAgRGFzaERhc2hJbkNvbW1lbnQgPSBTdHJcdTAwRTRuZ2VuICItLSIgXHUwMEU0ciBpbnRlIHRpbGxcdTAwRTV0ZW4gaW5vbSBrb21tZW50YXJlci4KLSAgICAgICAgQ29tbWVudFVudGVybWluYXRlZCA9IEtvbW1lbnRhcmVuIG1cdTAwRTVzdGUgYXZzbHV0YXMgbWVkICItLT4iLgotICAgICAgICBDT01NRU5UX05PVF9JTl9PTkVfRU5USVRZID0gS29tbWVudGFyZW4gaW5uZXNsdXRzIGludGUgaSBzYW1tYSBlbmhldC4KLSMgMi42IFByb2Nlc3NpbmcgSW5zdHJ1Y3Rpb25zCi0gICAgICAgIFBJVGFyZ2V0UmVxdWlyZWQgPSBCZWFyYmV0bmluZ3NpbnN0cnVrdGlvbmVuIG1cdTAwRTVzdGUgYlx1MDBGNnJqYSBtZWQgbVx1MDBFNWxuYW1uZXQuCi0gICAgICAgIFNwYWNlUmVxdWlyZWRJblBJID0gVG9tdCB1dHJ5bW1lIGtyXHUwMEU0dnMgbWVsbGFuIGJlYXJiZXRuaW5nc2luc3RydWt0aW9uZW5zIG1cdTAwRTVsIG9jaCBkYXRhLgotICAgICAgICBQSVVudGVybWluYXRlZCA9IEJlYXJiZXRuaW5nc2luc3RydWt0aW9uZW4gbVx1MDBFNXN0ZSBhdnNsdXRhcyBtZWQgIj8+Ii4KLSAgICAgICAgUmVzZXJ2ZWRQSVRhcmdldCA9IEJlYXJiZXRuaW5nc2luc3RydWt0aW9uZW5zIG1cdTAwRTVsbWF0Y2huaW5nICJbeFhdW21NXVtsTF0iIFx1MDBFNHIgaW50ZSB0aWxsXHUwMEU1dGVuLgotICAgICAgICBQSV9OT1RfSU5fT05FX0VOVElUWSA9IEJlYXJiZXRuaW5nc2luc3RydWt0aW9uZW4gaW5uZXNsdXRzIGludGUgaSBzYW1tYSBlbmhldC4KLSMgMi44IFByb2xvZyBhbmQgRG9jdW1lbnQgVHlwZSBEZWNsYXJhdGlvbgotICAgICAgICBWZXJzaW9uSW5mb0ludmFsaWQgPSBPZ2lsdGlnIHZlcnNpb24gInswfSIuCi0gICAgICAgIFZlcnNpb25Ob3RTdXBwb3J0ZWQgPSBYTUwtdmVyc2lvbmVuICJ7MH0iIHN0XHUwMEY2ZHMgaW50ZSwgZW5kYXN0IFhNTCAxLjAgc3RcdTAwRjZkcy4KLSAgICAgICAgVmVyc2lvbk5vdFN1cHBvcnRlZDExID0gWE1MLXZlcnNpb25lbiAiezB9IiBzdFx1MDBGNmRzIGludGUsIGVuZGFzdCBYTUwgMS4wIG9jaCBYTUwgMS4xIHN0XHUwMEY2ZHMuCi0gICAgICAgIFZlcnNpb25NaXNtYXRjaD0gRW4gZW5oZXQga2FuIGludGUgaW5rbHVkZXJhIG5cdTAwRTVnb24gYW5uYW4gZW5oZXQgc29tIGhhciBlbiBzZW5hcmUgdmVyc2lvbi4KLSMgNC4xIENoYXJhY3RlciBhbmQgRW50aXR5IFJlZmVyZW5jZXMKLSAgICAgICAgRGlnaXRSZXF1aXJlZEluQ2hhclJlZiA9IEV0dCBkZWNpbWFsdCB1dHRyeWNrIG1cdTAwRTVzdGUgYW5nZXMgZGlyZWt0IGVmdGVyICImIyIgaSBlbiB0ZWNrZW5yZWZlcmVucy4KLSAgICAgICAgSGV4ZGlnaXRSZXF1aXJlZEluQ2hhclJlZiA9IEV0dCBoZXhhZGVjaW1hbHQgdXR0cnljayBtXHUwMEU1c3RlIGFuZ2VzIGRpcmVrdCBlZnRlciAiJiN4IiBpIGVuIHRlY2tlbnJlZmVyZW5zLgotICAgICAgICBTZW1pY29sb25SZXF1aXJlZEluQ2hhclJlZiA9IFRlY2tlbnJlZmVyZW5zZW4gbVx1MDBFNXN0ZSBhdnNsdXRhcyBtZWQgJzsnLWF2Z3JcdTAwRTRuc2FyZS4KLSAgICAgICAgSW52YWxpZENoYXJSZWYgPSBUZWNrZW5yZWZlcmVuc2VuICImI3swfSIgXHUwMEU0ciBldHQgb2dpbHRpZ3QgWE1MLXRlY2tlbi4KLSAgICAgICAgTmFtZVJlcXVpcmVkSW5SZWZlcmVuY2UgPSBFbmhldHNuYW1uZXQgbVx1MDBFNXN0ZSBvbWVkZWxiYXJ0IGZcdTAwRjZsamFzIGF2ICcmJyBpIGVuaGV0c3JlZmVyZW5zZW4uCi0gICAgICAgIFNlbWljb2xvblJlcXVpcmVkSW5SZWZlcmVuY2UgPSBSZWZlcmVuc2VuIHRpbGwgZW5oZXQgInswfSIgbVx1MDBFNXN0ZSBhdnNsdXRhcyBtZWQgJyc7JyctYXZnclx1MDBFNG5zYXJlLgotIyA0LjMuMSBUaGUgVGV4dCBEZWNsYXJhdGlvbgotICAgICAgICBUZXh0RGVjbE11c3RCZUZpcnN0ID0gVGV4dGRla2xhcmF0aW9uZW4gbVx1MDBFNXN0ZSBhbmdlcyBkaXJla3QgaSBiXHUwMEY2cmphbiBhdiBleHRlcm50IHRvbGthZCBlbmhldC4KLSAgICAgICAgRXFSZXF1aXJlZEluVGV4dERlY2wgPSBFdHQgbGlraGV0c3RlY2tlbiAoJycgPSAnJykgbVx1MDBFNXN0ZSBhbmdlcyBlZnRlciAiezB9IiBpIHRleHRkZWtsYXJhdGlvbmVuLgotICAgICAgICBRdW90ZVJlcXVpcmVkSW5UZXh0RGVjbCA9IFZcdTAwRTRyZGV0IHNvbSBmXHUwMEY2bGplciAiezB9IiBpIHRleHRkZWtsYXJhdGlvbmVuIG1cdTAwRTVzdGUgb21nZXMgYXYgY2l0YXR0ZWNrZW4uCi0gICAgICAgIENsb3NlUXVvdGVNaXNzaW5nSW5UZXh0RGVjbCA9IGF2c2x1dGFuZGUgY2l0YXR0ZWNrZW4gc2FrbmFzIGZcdTAwRjZyIHZcdTAwRTRyZGV0IGVmdGVyICJ7MH0iIGkgdGV4dGRla2xhcmF0aW9uZW4uCi0gICAgICAgIFNwYWNlUmVxdWlyZWRCZWZvcmVWZXJzaW9uSW5UZXh0RGVjbCA9IFRvbXQgdXRyeW1tZSBrclx1MDBFNHZzIGZcdTAwRjZyZSB2ZXJzaW9uZW5zIHBzZXVkb2F0dHJpYnV0IGkgdGV4dGRla2xhcmF0aW9uZW4uCi0gICAgICAgIFNwYWNlUmVxdWlyZWRCZWZvcmVFbmNvZGluZ0luVGV4dERlY2wgPSBUb210IHV0cnltbWUga3JcdTAwRTR2cyBmXHUwMEY2cmUga29kbmluZ2VucyBwc2V1ZG9hdHRyaWJ1dCBpIHRleHRkZWtsYXJhdGlvbmVuLgotICAgICAgICBUZXh0RGVjbFVudGVybWluYXRlZCA9IFRleHRkZWtsYXJhdGlvbmVuIG1cdTAwRTVzdGUgYXZzbHV0YXMgbWVkICI/PiIuCi0gICAgICAgIEVuY29kaW5nRGVjbFJlcXVpcmVkID0gS29kZGVrbGFyYXRpb24ga3JcdTAwRTR2cyBpIHRleHRkZWtsYXJhdGlvbmVuLgotICAgICAgICBOb01vcmVQc2V1ZG9BdHRyaWJ1dGVzID0gSW5nYSBmbGVyIHBzZXVkb2F0dHJpYnV0IFx1MDBFNHIgdGlsbFx1MDBFNXRuYS4KLSAgICAgICAgTW9yZVBzZXVkb0F0dHJpYnV0ZXMgPSBZdHRlcmxpZ2FyZSBwc2V1ZG9hdHRyaWJ1dCBmXHUwMEY2cnZcdTAwRTRudGFzLgotICAgICAgICBQc2V1ZG9BdHRyTmFtZUV4cGVjdGVkID0gRXR0IHBzZXVkb2F0dHJpYnV0bmFtbiBmXHUwMEY2cnZcdTAwRTRudGFzLiAKLSMgNC4zLjIgV2VsbC1Gb3JtZWQgUGFyc2VkIEVudGl0aWVzCi0gICAgICAgIENvbW1lbnROb3RJbk9uZUVudGl0eSA9IEtvbW1lbnRhcmVuIG1cdTAwRTVzdGUgZmlubmFzIG1lZCBpbm9tIHNhbW1hIHRvbGthZGUgZW5oZXQuCi0gICAgICAgIFBJTm90SW5PbmVFbnRpdHkgPSBCZWFyYmV0bmluZ3NpbnN0cnVrdGlvbmVuIG1cdTAwRTVzdGUgZmlubmFzIG1lZCBpbm9tIHNhbW1hIHRvbGthZGUgZW5oZXQuCi0jIDQuMy4zIENoYXJhY3RlciBFbmNvZGluZyBpbiBFbnRpdGllcwotICAgICAgICBFbmNvZGluZ0RlY2xJbnZhbGlkID0gT2dpbHRpZ3Qga29kbmFtbiwgInswfSIuCi0gICAgICAgIEVuY29kaW5nQnl0ZU9yZGVyVW5zdXBwb3J0ZWQgPSBBbmdpdmVuIGJ5dGVvcmRuaW5nc2ZcdTAwRjZsamQgaSBrb2RuaW5nICJ7MH0iIHN0XHUwMEY2ZHMgaW50ZS4KLSAgICAgICAgSW52YWxpZEJ5dGUgPSBPZ2lsdGlnIGJ5dGUgezB9IGkgVVRGLTgtc2VrdmVuc2VuIGZcdTAwRjZyIHsxfS1ieXRlLgotICAgICAgICBFeHBlY3RlZEJ5dGUgPSBGXHUwMEY2cnZcdTAwRTRudGFkIGJ5dGUgezB9IGkgVVRGLTgtc2VrdmVuc2VuIGZcdTAwRjZyIHsxfS1ieXRlLiAgCi0gICAgICAgIEludmFsaWRIaWdoU3Vycm9nYXRlID0gSFx1MDBGNmdhIHN1cnJvZ2F0Yml0YXIgaSBVVEYtOC1zZWt2ZW5zIGZcdTAwRTVyIGludGUgXHUwMEY2dmVyc2tyaWRhIDB4MTAsIG1lbiAweHswfSBoaXR0YWRlcy4KLSAgICAgICAgT3BlcmF0aW9uTm90U3VwcG9ydGVkID0gXHUwMEM1dGdcdTAwRTRyZGVuICJ7MH0iIHN0XHUwMEY2ZHMgaW50ZSBpIGxcdTAwRTRzYXJlbiB7MX0uCi0gICAgICAgIEludmFsaWRBU0NJSSA9IEJ5dGUgInswfSIgaW5nXHUwMEU1ciBpbnRlIGkgQVNDSUktdGVja2VudXBwc1x1MDBFNHR0bmluZ2VuICg3IGJpdGFyKS4KLSAgICAgICAgQ2hhckNvbnZlcnNpb25GYWlsdXJlID0gRW4gZW5oZXQgc29tIGZhc3RzdFx1MDBFNGxscyBhbnZcdTAwRTRuZGEgZXR0IHZpc3N0IGtvZGZvcm1hdCBmXHUwMEU1ciBpbnRlIGlubmVoXHUwMEU1bGxhIHNla3ZlbnNlciBzb20gXHUwMEU0ciBvdGlsbFx1MDBFNXRuYSBpIGtvZG5pbmdlbi4KLSAgICAgICAgCi0jIERURCBNZXNzYWdlcwotIyAyLjIgQ2hhcmFjdGVycwotICAgICAgICBJbnZhbGlkQ2hhckluRW50aXR5VmFsdWUgPSBFdHQgb2dpbHRpZ3QgWE1MLXRlY2tlbiAoVW5pY29kZTogMHh7MH0pIGhpdHRhZGVzIGkgZGV0IGxpdHRlcmFsYSBlbmhldHN2XHUwMEU0cmRldC4KLSAgICAgICAgSW52YWxpZENoYXJJbkV4dGVybmFsU3Vic2V0ID0gRXR0IG9naWx0aWd0IFhNTC10ZWNrZW4gKFVuaWNvZGU6IDB4ezB9KSBoaXR0YWRlcyBpIGRlbiBleHRlcm5hIGRlbG1cdTAwRTRuZ2RlbiBpIERURC4KLSAgICAgICAgSW52YWxpZENoYXJJbklnbm9yZVNlY3QgPSBFdHQgb2dpbHRpZ3QgWE1MLXRlY2tlbiAoVW5pY29kZTogMHh7MH0pIGhpdHRhZGVzIGkgc2VrdGlvbmVuIGZcdTAwRjZyIGV4a2x1ZGVyYWRlIHZpbGxrb3IuCi0gICAgICAgIEludmFsaWRDaGFySW5QdWJsaWNJRCA9IEV0dCBvZ2lsdGlndCBYTUwtdGVja2VuIChVbmljb2RlOiAweHswfSkgaGl0dGFkZXMgaSBhbGxtXHUwMEU0biBpZGVudGlmaWVyYXJlLgotICAgICAgICBJbnZhbGlkQ2hhckluU3lzdGVtSUQgPSBFdHQgb2dpbHRpZ3QgWE1MLXRlY2tlbiAoVW5pY29kZTogMHh7MH0pIGhpdHRhZGVzIGkgc3lzdGVtaWRlbnRpZmllcmFyZS4KLSMgMi4zIENvbW1vbiBTeW50YWN0aWMgQ29uc3RydWN0cwotICAgICAgICBTcGFjZVJlcXVpcmVkQWZ0ZXJTWVNURU0gPSBUb210IHV0cnltbWUga3JcdTAwRTR2cyBlZnRlciBueWNrZWxvcmRldCBTWVNURU0gaSBET0NUWVBFLWRla2xhcmF0aW9uZW4uCi0gICAgICAgIFF1b3RlUmVxdWlyZWRJblN5c3RlbUlEID0gU3lzdGVtaWRlbnRpZmllcmFyZW4gbVx1MDBFNXN0ZSBpbmxlZGFzIG1lZCBhbnRpbmdlbiBlbmtlbHQgZWxsZXIgZHViYmVsdCBjaXRhdHRlY2tlbi4KLSAgICAgICAgU3lzdGVtSURVbnRlcm1pbmF0ZWQgPSBTeXN0ZW1pZGVudGlmaWVyYXJlbiBtXHUwMEU1c3RlIGF2c2x1dGFzIG1lZCBtYXRjaGFuZGUgY2l0YXR0ZWNrZW4uCi0gICAgICAgIFNwYWNlUmVxdWlyZWRBZnRlclBVQkxJQyA9IFRvbW1hIHV0cnltbWVuIGtyXHUwMEU0dnMgZWZ0ZXIgbnlja2Vsb3JkZXQgUFVCTElDIGkgRE9DVFlQRS1kZWtsYXJhdGlvbmVuLgotICAgICAgICBRdW90ZVJlcXVpcmVkSW5QdWJsaWNJRCA9IERlbiBhbGxtXHUwMEU0bm5hIGlkZW50aWZpZXJhcmVuIG1cdTAwRTVzdGUgaW5sZWRhcyBtZWQgYW50aW5nZW4gZW5rZWx0IGVsbGVyIGR1YmJlbHQgY2l0YXR0ZWNrZW4uCi0gICAgICAgIFB1YmxpY0lEVW50ZXJtaW5hdGVkID0gRGVuIGFsbG1cdTAwRTRubmEgaWRlbnRpZmllcmFyZW4gbVx1MDBFNXN0ZSBhdnNsdXRhcyBtZWQgbWF0Y2hhbmRlIGNpdGF0dGVja2VuLgotICAgICAgICBQdWJpZENoYXJJbGxlZ2FsID0gVGVja25ldCAoVW5pY29kZTogMHh7MH0pIFx1MDBFNHIgaW50ZSB0aWxsXHUwMEU1dGV0IGkgZGVuIGFsbG1cdTAwRTRubmEgaWRlbnRpZmllcmFyZW4uCi0gICAgICAgIFNwYWNlUmVxdWlyZWRCZXR3ZWVuUHVibGljQW5kU3lzdGVtID0gVG9tbWEgdXRyeW1tZW4ga3JcdTAwRTR2cyBtZWxsYW4gcHVibGljSWQgb2NoIHN5c3RlbUlkLgotIyAyLjggUHJvbG9nIGFuZCBEb2N1bWVudCBUeXBlIERlY2xhcmF0aW9uCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfUk9PVF9FTEVNRU5UX1RZUEVfSU5fRE9DVFlQRURFQ0wgPSBUb210IHV0cnltbWUga3JcdTAwRTR2cyBlZnRlciAiPCFET0NUWVBFIiBpIGRva3VtZW50dHlwZGVrbGFyYXRpb25lbi4KLSAgICAgICAgTVNHX1JPT1RfRUxFTUVOVF9UWVBFX1JFUVVJUkVEID0gUm90ZWxlbWVudHR5cCBtXHUwMEU1c3RlIGFuZ2VzIGVmdGVyICI8IURPQ1RZUEUiIGkgZG9rdW1lbnR0eXBkZWtsYXJhdGlvbmVuLgotICAgICAgICBEb2N0eXBlZGVjbFVudGVybWluYXRlZCA9IERva3VtZW50dHlwZGVrbGFyYXRpb25lbiBmXHUwMEY2ciByb3RlbGVtZW50dHlwICJ7MH0iIG1cdTAwRTVzdGUgYXZzbHV0YXMgbWVkICcnPicnLgotICAgICAgICBEb2N0eXBlZGVjbE5vdENsb3NlZCA9IERva3VtZW50dHlwc2Rla2xhcmF0aW9uZW4gZlx1MDBGNnIgcm90ZWxlbWVudHR5cGVuICJ7MH0iIG1cdTAwRTVzdGUgc3RcdTAwRTRuZ2FzIG1lZCAnJ10nJy4KLSAgICAgICAgUEVSZWZlcmVuY2VXaXRoaW5NYXJrdXAgPSBQYXJhbWV0ZXJyZWZlcmVuc2VuICIlezB9OyIgZlx1MDBFNXIgaW50ZSBmXHUwMEY2cmVrb21tYSBpIGtvZHRleHRlbiBpIGRlbiBpbnRlcm5hIGRlbG1cdTAwRTRuZ2RlbiBpIERURC4KLSAgICAgICAgTVNHX01BUktVUF9OT1RfUkVDT0dOSVpFRF9JTl9EVEQgPSBLb2R0ZXh0ZGVrbGFyYXRpb25lcm5hIHNvbSBmaW5ucyBtZWQgZWxsZXIgcGVrYXMgdGlsbCBmclx1MDBFNW4gZG9rdW1lbnR0eXBkZWtsYXJhdGlvbmVuIG1cdTAwRTVzdGUgdmFyYSB2XHUwMEU0bGZvcm11bGVyYWRlLgotIyAyLjEwIFdoaXRlIFNwYWNlIEhhbmRsaW5nCi0gICAgICAgIE1TR19YTUxfU1BBQ0VfREVDTEFSQVRJT05fSUxMRUdBTCA9IEF0dHJpYnV0ZGVrbGFyYXRpb25lbiBmXHUwMEY2ciAieG1sOnNwYWNlIiBtXHUwMEU1c3RlIGFuZ2VzIHNvbSB1cHByXHUwMEU0a25pbmdzdHlwIHZhcnMgZW5kYSBtXHUwMEY2amxpZ2Egdlx1MDBFNHJkZW4gXHUwMEU0ciAiZGVmYXVsdCIgb2NoICJwcmVzZXJ2ZSIuCi0jIDMuMiBFbGVtZW50IFR5cGUgRGVjbGFyYXRpb25zCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfRUxFTUVOVF9UWVBFX0lOX0VMRU1FTlRERUNMID0gVG9tdCB1dHJ5bW1lIGtyXHUwMEU0dnMgZWZ0ZXIgIjwhRUxFTUVOVCIgaSBlbGVtZW50dHlwZGVrbGFyYXRpb25lbi4KLSAgICAgICAgTVNHX0VMRU1FTlRfVFlQRV9SRVFVSVJFRF9JTl9FTEVNRU5UREVDTCA9IEVsZW1lbnR0eXAgbVx1MDBFNXN0ZSBhbmdlcyBpIGVsZW1lbnR0eXBkZWtsYXJhdGlvbmVuLgotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX0NPTlRFTlRTUEVDX0lOX0VMRU1FTlRERUNMID0gVG9tdCB1dHJ5bW1lIGtyXHUwMEU0dnMgZWZ0ZXIgZWxlbWVudHR5cCAiezB9IiBpIGVsZW1lbnR0eXBkZWtsYXJhdGlvbmVuLgotICAgICAgICBNU0dfQ09OVEVOVFNQRUNfUkVRVUlSRURfSU5fRUxFTUVOVERFQ0wgPSBCZWdyXHUwMEU0bnNuaW5nZW4ga3JcdTAwRTR2cyBlZnRlciBlbGVtZW50dHlwICJ7MH0iIGkgZWxlbWVudHR5cGRla2xhcmF0aW9uZW4uCi0gICAgICAgIEVsZW1lbnREZWNsVW50ZXJtaW5hdGVkID0gRGVrbGFyYXRpb25lbiBmXHUwMEY2ciBlbGVtZW50dHlwICJ7MH0iIG1cdTAwRTVzdGUgYXZzbHV0YXMgbWVkICcnPicnLgotIyAzLjIuMSBFbGVtZW50IENvbnRlbnQKLSAgICAgICAgTVNHX09QRU5fUEFSRU5fT1JfRUxFTUVOVF9UWVBFX1JFUVVJUkVEX0lOX0NISUxEUkVOID0gVGVja25ldCAnJygnJyBlbGxlciBlbiBlbGVtZW50dHlwIG1cdTAwRTVzdGUgYW5nZXMgaSBkZWtsYXJhdGlvbmVuIGF2IGVsZW1lbnR0eXAgInswfSIuCi0gICAgICAgIE1TR19DTE9TRV9QQVJFTl9SRVFVSVJFRF9JTl9DSElMRFJFTiA9IFRlY2tuZXQgJycpJycgbVx1MDBFNXN0ZSBhbmdlcyBpIGRla2xhcmF0aW9uZW4gYXYgZWxlbWVudHR5cCAiezB9Ii4KLSMgMy4yLjIgTWl4ZWQgQ29udGVudAotICAgICAgICBNU0dfRUxFTUVOVF9UWVBFX1JFUVVJUkVEX0lOX01JWEVEX0NPTlRFTlQgPSBFbiBlbGVtZW50dHlwIG1cdTAwRTVzdGUgYW5nZXMgaSBkZWtsYXJhdGlvbmVuIGF2IGVsZW1lbnR0eXAgInswfSIuCi0gICAgICAgIE1TR19DTE9TRV9QQVJFTl9SRVFVSVJFRF9JTl9NSVhFRCA9IFRlY2tuZXQgJycpJycgbVx1MDBFNXN0ZSBhbmdlcyBpIGRla2xhcmF0aW9uZW4gYXYgZWxlbWVudHR5cCAiezB9Ii4KLSAgICAgICAgTWl4ZWRDb250ZW50VW50ZXJtaW5hdGVkID0gTW9kZWxsZW4gbWVkIGJsYW5kYXQgaW5uZWhcdTAwRTVsbCAiezB9IiBtXHUwMEU1c3RlIGF2c2x1dGFzIG1lZCAiKSoiIG9tIHR5cGVyIGF2IHVuZGVyb3JkbmFkZSBlbGVtZW50IFx1MDBFNHIgYmVnclx1MDBFNG5zYWRlLgotIyAzLjMgQXR0cmlidXRlLUxpc3QgRGVjbGFyYXRpb25zCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfRUxFTUVOVF9UWVBFX0lOX0FUVExJU1RERUNMID0gVG9tdCB1dHJ5bW1lIGtyXHUwMEU0dnMgZWZ0ZXIgIjwhQVRUTElTVCIgaSBkZWtsYXJhdGlvbmVuIGZcdTAwRjZyIGF0dHJpYnV0bGlzdGEuCi0gICAgICAgIE1TR19FTEVNRU5UX1RZUEVfUkVRVUlSRURfSU5fQVRUTElTVERFQ0wgPSBFbGVtZW50dHlwIG1cdTAwRTVzdGUgYW5nZXMgaSBkZWtsYXJhdGlvbmVuIGZcdTAwRjZyIGF0dHJpYnV0bGlzdGEuCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfQVRUUklCVVRFX05BTUVfSU5fQVRUREVGID0gVG9tdCB1dHJ5bW1lIGtyXHUwMEU0dnMgZlx1MDBGNnJlIGF0dHJpYnV0bmFtbmV0IGkgZGVrbGFyYXRpb25lbiBmXHUwMEY2ciBhdHRyaWJ1dGxpc3RhIGZcdTAwRjZyIGVsZW1lbnRldCAiezB9Ii4KLSAgICAgICAgQXR0TmFtZVJlcXVpcmVkSW5BdHREZWYgPSBBdHRyaWJ1dG5hbW5ldCBtXHUwMEU1c3RlIGFuZ2VzIGkgZGVrbGFyYXRpb25lbiBmXHUwMEY2ciBhdHRyaWJ1dGxpc3RhIGZcdTAwRjZyIGVsZW1lbnRldCAiezB9Ii4KLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9BVFRUWVBFX0lOX0FUVERFRiA9IFRvbXQgdXRyeW1tZSBrclx1MDBFNHZzIGZcdTAwRjZyZSBhdHRyaWJ1dHR5cCBpIGRla2xhcmF0aW9uZW4gZlx1MDBGNnIgYXR0cmlidXRldCAiezF9IiBmXHUwMEY2ciBlbGVtZW50ZXQgInswfSIuCi0gICAgICAgIEF0dFR5cGVSZXF1aXJlZEluQXR0RGVmID0gQXR0cmlidXR0eXAgbVx1MDBFNXN0ZSBhbmdlcyBpIGRla2xhcmF0aW9uZW4gZlx1MDBGNnIgYXR0cmlidXRldCAiezF9IiBmXHUwMEY2ciBlbGVtZW50ZXQgInswfSIuCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfREVGQVVMVERFQ0xfSU5fQVRUREVGID0gVG9tdCB1dHJ5bW1lIGtyXHUwMEU0dnMgZlx1MDBGNnJlIGF0dHJpYnV0c3RhbmRhcmR2XHUwMEU0cmRlIGkgZGVrbGFyYXRpb25lbiBmXHUwMEY2ciBhdHRyaWJ1dGV0ICJ7MX0iIGZcdTAwRjZyIGVsZW1lbnRldCAiezB9Ii4KLSAgICAgICAgTVNHX0RVUExJQ0FURV9BVFRSSUJVVEVfREVGSU5JVElPTiA9IERldCBmaW5ucyBmbGVyIFx1MDBFNG4gZW4gYXR0cmlidXRkZWZpbml0aW9uIGZcdTAwRjZyIHNhbW1hIGF0dHJpYnV0ICJ7MX0iIGZcdTAwRjZyIGFuZ2l2ZXQgZWxlbWVudCAiezB9Ii4KLSMgMy4zLjEgQXR0cmlidXRlIFR5cGVzCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9BRlRFUl9OT1RBVElPTl9JTl9OT1RBVElPTlRZUEUgPSBUb210IHV0cnltbWUgbVx1MDBFNXN0ZSBhbmdlcyBlZnRlciAiTk9UQVRJT04iIGkgYXR0cmlidXRkZWtsYXJhdGlvbmVuICJ7MX0iLgotICAgICAgICBNU0dfT1BFTl9QQVJFTl9SRVFVSVJFRF9JTl9OT1RBVElPTlRZUEUgPSBUZWNrbmV0ICcnKCcnIG1cdTAwRTVzdGUgYW5nZXMgZWZ0ZXIgIk5PVEFUSU9OIiBpIGF0dHJpYnV0ZGVrbGFyYXRpb25lbiAiezF9Ii4KLSAgICAgICAgTVNHX05BTUVfUkVRVUlSRURfSU5fTk9UQVRJT05UWVBFID0gTm90YXRpb25zbmFtbiBtXHUwMEU1c3RlIGFuZ2VzIGkgbm90YXRpb25zdHlwbGlzdGFuIGZcdTAwRjZyIGF0dHJpYnV0ZGVrbGFyYXRpb25lbiAiezF9Ii4KLSAgICAgICAgTm90YXRpb25UeXBlVW50ZXJtaW5hdGVkID0gTm90YXRpb25zdHlwbGlzdGFuIG1cdTAwRTVzdGUgYXZzbHV0YXMgbWVkICcnKScnIGkgYXR0cmlidXRkZWtsYXJhdGlvbmVuICJ7MX0iLgotICAgICAgICBNU0dfTk1UT0tFTl9SRVFVSVJFRF9JTl9FTlVNRVJBVElPTiA9IE5hbW50ZWNrZW4gbVx1MDBFNXN0ZSBhbmdlcyBpIHVwcHJcdTAwRTRrbmluZ3N0eXBsaXN0YW4gZlx1MDBGNnIgYXR0cmlidXRkZWtsYXJhdGlvbmVuICJ7MX0iLgotICAgICAgICBFbnVtZXJhdGlvblVudGVybWluYXRlZCA9IFVwcHJcdTAwRTRrbmluZ3N0eXBsaXN0YW4gbVx1MDBFNXN0ZSBhdnNsdXRhcyBtZWQgJycpJycgaSBhdHRyaWJ1dGRla2xhcmF0aW9uZW4gInsxfSIuCi0gICAgICAgIE1TR19ESVNUSU5DVF9UT0tFTlNfSU5fRU5VTUVSQVRJT04gPSBVcHByXHUwMEU0a25pbmdzdlx1MDBFNHJkZXQgInsxfSIgaGFyIGFuZ2V0dHMgZmxlciBcdTAwRTRuIGVuIGdcdTAwRTVuZyBpIGF0dHJpYnV0ZGVrbGFyYXRpb25lbiAiezJ9IiBmXHUwMEY2ciBlbGVtZW50ZXQgInswfSIuIEFsbGEgTk1UT0tFTlMgaSBlbiBvY2ggc2FtbWEgYXR0cmlidXRkZWtsYXJhdGlvbiBmXHUwMEY2ciBFbnVtZXJhdGlvbiBtXHUwMEU1c3RlIHZhcmEgdW5pa2EuCi0gICAgICAgIE1TR19ESVNUSU5DVF9OT1RBVElPTl9JTl9FTlVNRVJBVElPTiA9IFVwcHJcdTAwRTRrbmluZ3N2XHUwMEU0cmRldCAiezF9IiBoYXIgYW5nZXR0cyBmbGVyIFx1MDBFNG4gZW4gZ1x1MDBFNW5nIGkgYXR0cmlidXRkZWtsYXJhdGlvbmVuICJ7Mn0iIGZcdTAwRjZyIGVsZW1lbnRldCAiezB9Ii4gQWxsYSBOT1RBVElPTi1uYW1uIGkgZW4gb2NoIHNhbW1hIGF0dHJpYnV0ZGVrbGFyYXRpb24gZlx1MDBGNnIgTm90YXRpb25UeXBlIG1cdTAwRTVzdGUgdmFyYSB1bmlrYS4KLSMgMy4zLjIgQXR0cmlidXRlIERlZmF1bHRzCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9BRlRFUl9GSVhFRF9JTl9ERUZBVUxUREVDTCA9IFRvbXQgdXRyeW1tZSBtXHUwMEU1c3RlIGFuZ2VzIGVmdGVyICJGSVhFRCIgaSBhdHRyaWJ1dGRla2xhcmF0aW9uZW4gInsxfSIuCi0jIDMuNCBDb25kaXRpb25hbCBTZWN0aW9ucwotICAgICAgICBJbmNsdWRlU2VjdFVudGVybWluYXRlZCA9IFNla3Rpb25lbiBmXHUwMEY2ciBpbmtsdWRlcmFkZSB2aWxsa29yIG1cdTAwRTVzdGUgYXZzbHV0YXMgbWVkICJdXT4iLgotICAgICAgICBJZ25vcmVTZWN0VW50ZXJtaW5hdGVkID0gU2VrdGlvbmVuIGZcdTAwRjZyIGV4a2x1ZGVyYWRlIHZpbGxrb3IgbVx1MDBFNXN0ZSBhdnNsdXRhcyBtZWQgIl1dPiIuCi0jIDQuMSBDaGFyYWN0ZXIgYW5kIEVudGl0eSBSZWZlcmVuY2VzCi0gICAgICAgIE5hbWVSZXF1aXJlZEluUEVSZWZlcmVuY2UgPSBFbmhldHNuYW1uZXQgbVx1MDBFNXN0ZSBvbWVkZWxiYXJ0IGZcdTAwRjZsamFzIGF2ICclJyBpIHBhcmFtZXRlcnJlZmVyZW5zZW4uCi0gICAgICAgIFNlbWljb2xvblJlcXVpcmVkSW5QRVJlZmVyZW5jZSA9IFBhcmFtZXRlcnJlZmVyZW5zZW4gIiV7MH07IiBtXHUwMEU1c3RlIGF2c2x1dGFzIG1lZCAnJzsnJy1hdmdyXHUwMEU0bnNhcmUuCi0jIDQuMiBFbnRpdHkgRGVjbGFyYXRpb25zCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfRU5USVRZX05BTUVfSU5fRU5USVRZREVDTCA9IFRvbXQgdXRyeW1tZSBrclx1MDBFNHZzIGVmdGVyICI8IUVOVElUWSIgaSBlbmhldHNkZWtsYXJhdGlvbmVuLgotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX1BFUkNFTlRfSU5fUEVERUNMID0gVG9tdCB1dHJ5bW1lIGtyXHUwMEU0dnMgbWVsbGFuICI8IUVOVElUWSIgb2NoICclJy10ZWNrbmV0IGkgcGFyYW1ldGVyZGVrbGFyYXRpb25lbi4KLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9FTlRJVFlfTkFNRV9JTl9QRURFQ0wgPSBUb210IHV0cnltbWUga3JcdTAwRTR2cyBtZWxsYW4gJyUnIG9jaCBlbmhldHNuYW1uZXQgaSBwYXJhbWV0ZXJkZWtsYXJhdGlvbmVuLgotICAgICAgICBNU0dfRU5USVRZX05BTUVfUkVRVUlSRURfSU5fRU5USVRZREVDTCA9IE5hbW5ldCBwXHUwMEU1IGVuaGV0ZW4gbVx1MDBFNXN0ZSBhbmdlcyBpIGVuaGV0c2Rla2xhcmF0aW9uZW4uCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9BRlRFUl9FTlRJVFlfTkFNRV9JTl9FTlRJVFlERUNMID0gVG9tdCB1dHJ5bW1lIGtyXHUwMEU0dnMgbWVsbGFuIGVuaGV0c25hbW5ldCAiezB9IiBvY2ggZGVmaW5pdGlvbmVuIGkgZW5oZXRzZGVrbGFyYXRpb25lbi4KLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9OT1RBVElPTl9OQU1FX0lOX1VOUEFSU0VEX0VOVElUWURFQ0wgPSBUb210IHV0cnltbWUga3JcdTAwRTR2cyBtZWxsYW4gIk5EQVRBIiBvY2ggbm90YXRpb25zbmFtbmV0IGkgZGVrbGFyYXRpb25lbiBmXHUwMEY2ciBlbmhldGVuICJ7MH0iLgotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX05EQVRBX0lOX1VOUEFSU0VEX0VOVElUWURFQ0wgPSBUb210IHV0cnltbWUga3JcdTAwRTR2cyBmXHUwMEY2cmUgIk5EQVRBIiBpIGRla2xhcmF0aW9uZW4gZlx1MDBGNnIgZW5oZXRlbiAiezB9Ii4KLSAgICAgICAgTVNHX05PVEFUSU9OX05BTUVfUkVRVUlSRURfRk9SX1VOUEFSU0VEX0VOVElUWURFQ0wgPSBOb3RhdGlvbnNuYW1uZXQgbVx1MDBFNXN0ZSBhbmdlcyBlZnRlciAiTkRBVEEiIGkgZGVrbGFyYXRpb25lbiBmXHUwMEY2ciBlbmhldGVuICJ7MH0iLgotICAgICAgICBFbnRpdHlEZWNsVW50ZXJtaW5hdGVkID0gRGVrbGFyYXRpb25lbiBmXHUwMEY2ciBlbmhldGVuICJ7MH0iIG1cdTAwRTVzdGUgYXZzbHV0YXMgbWVkICcnPicnLgotCU1TR19EVVBMSUNBVEVfRU5USVRZX0RFRklOSVRJT04gPSBFbmhldGVuICJ7MH0iIGhhciBkZWtsYXJlcmF0cyBtZXIgXHUwMEU0biBlbiBnXHUwMEU1bmcuICAgICAgICAKLSMgNC4yLjIgRXh0ZXJuYWwgRW50aXRpZXMKLSAgICAgICAgRXh0ZXJuYWxJRFJlcXVpcmVkID0gRGVuIGV4dGVybmEgZW5oZXRzZGVrbGFyYXRpb25lbiBtXHUwMEU1c3RlIGlubGVkYXMgbWVkIGFudGluZ2VuICJTWVNURU0iIGVsbGVyICJQVUJMSUMiLgotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX1BVQklETElURVJBTF9JTl9FWFRFUk5BTElEID0gVG9tdCB1dHJ5bW1lIGtyXHUwMEU0dnMgbWVsbGFuICJQVUJMSUMiIG9jaCBkZW4gYWxsbVx1MDBFNG5uYSBpZGVudGlmaWVyYXJlbi4KLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0FGVEVSX1BVQklETElURVJBTF9JTl9FWFRFUk5BTElEID0gVG9tdCB1dHJ5bW1lIGtyXHUwMEU0dnMgbWVsbGFuIGRlbiBhbGxtXHUwMEU0bm5hIGlkZW50aWZpZXJhcmVuIG9jaCBzeXN0ZW1pZGVudGlmaWVyYXJlbi4KLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9TWVNURU1MSVRFUkFMX0lOX0VYVEVSTkFMSUQgPSBUb210IHV0cnltbWUga3JcdTAwRTR2cyBtZWxsYW4gIlNZU1RFTSIgb2NoIHN5c3RlbWlkZW50aWZpZXJhcmVuLgotICAgICAgICBNU0dfVVJJX0ZSQUdNRU5UX0lOX1NZU1RFTUlEID0gRnJhZ21lbnRpZGVudGlmaWVyYXJlbiBmXHUwMEU1ciBpbnRlIGFuZ2VzIHNvbSBkZWwgYXYgc3lzdGVtaWRlbnRpZmllcmFyZW4gInswfSIuCi0jIDQuNyBOb3RhdGlvbiBEZWNsYXJhdGlvbnMKLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9OT1RBVElPTl9OQU1FX0lOX05PVEFUSU9OREVDTCA9IFRvbXQgdXRyeW1tZSBrclx1MDBFNHZzIGVmdGVyICI8IU5PVEFUSU9OIiBpIG5vdGF0aW9uc2Rla2xhcmF0aW9uZW4uCi0gICAgICAgIE1TR19OT1RBVElPTl9OQU1FX1JFUVVJUkVEX0lOX05PVEFUSU9OREVDTCA9IE5hbW5ldCBwXHUwMEU1IG5vdGF0aW9uZW4gbVx1MDBFNXN0ZSBhbmdlcyBpIG5vdGF0aW9uc2Rla2xhcmF0aW9uZW4uCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9BRlRFUl9OT1RBVElPTl9OQU1FX0lOX05PVEFUSU9OREVDTCA9IFRvbXQgdXRyeW1tZSBrclx1MDBFNHZzIGVmdGVyIG5vdGF0aW9uc25hbW5ldCAiezB9IiBpIG5vdGF0aW9uc2Rla2xhcmF0aW9uZW4uCi0gICAgICAgIEV4dGVybmFsSURvclB1YmxpY0lEUmVxdWlyZWQgPSBEZWtsYXJhdGlvbmVuIGZcdTAwRjZyIG5vdGF0aW9uZW4gInswfSIgbVx1MDBFNXN0ZSBpbmtsdWRlcmEgc3lzdGVtaWRlbnRpZmllcmFyZSBlbGxlciBhbGxtXHUwMEU0biBpZGVudGlmaWVyYXJlLgotICAgICAgICBOb3RhdGlvbkRlY2xVbnRlcm1pbmF0ZWQgPSBEZWtsYXJhdGlvbmVuIGZcdTAwRjZyIG5vdGF0aW9uZW4gInswfSIgbVx1MDBFNXN0ZSBhdnNsdXRhcyBtZWQgJyc+JycuCi0gICAgICAgIAotIyBWYWxpZGF0aW9uIG1lc3NhZ2VzCi0gICAgICAgIER1cGxpY2F0ZVR5cGVJbk1peGVkQ29udGVudCA9IEVsZW1lbnR0eXAgInsxfSIgaGFyIHJlZGFuIGFuZ2V0dHMgaSBtb2RlbGxlbiBtZWQgaW5uZWhcdTAwRTVsbCBmXHUwMEY2ciBlbGVtZW50ZGVrbGFyYXRpb25lbiAiezB9Ii4KLSAgICAgICAgRU5USVRJRVNJbnZhbGlkID0gQXR0cmlidXR2XHUwMEU0cmRldCAiezF9IiBhdiB0eXBlbiBFTlRJVElFUyBtXHUwMEU1c3RlIG1vdHN2YXJhIG5hbW5lbiBwXHUwMEU1IGVuIGVsbGVyIGZsZXJhIG90b2xrYWRlIGVuaGV0ZXIuCi0gICAgICAgIEVOVElUWUludmFsaWQgPSBBdHRyaWJ1dHZcdTAwRTRyZGV0ICJ7MX0iIGF2IHR5cGVuIEVOVElUWSBtXHUwMEU1c3RlIG1vdHN2YXJhIG5hbW5ldCBwXHUwMEU1IGVuIG90b2xrYWQgZW5oZXQuCi0gICAgICAgIElERGVmYXVsdFR5cGVJbnZhbGlkID0gSWQtYXR0cmlidXRldCAiezB9IiBtXHUwMEU1c3RlIGlubmVoXHUwMEU1bGxhIGRla2xhcmVyYXQgc3RhbmRhcmR2XHUwMEU0cmRlICIjSU1QTElFRCIgZWxsZXIgIiNSRVFVSVJFRCIuCi0gICAgICAgIElESW52YWxpZCA9IEF0dHJpYnV0dlx1MDBFNHJkZXQgInswfSIgYXYgdHlwZW4gSUQgbVx1MDBFNXN0ZSB2YXJhIGV0dCBuYW1uLgotICAgICAgICBJREludmFsaWRXaXRoTmFtZXNwYWNlcyA9IEF0dHJpYnV0dlx1MDBFNHJkZXQgInswfSIgYXYgdHlwZW4gSUQgbVx1MDBFNXN0ZSB2YXJhIE5DTmFtZSBvbSBuYW1ucnltZGVyIGFudlx1MDBFNG5kcy4KLSAgICAgICAgSUROb3RVbmlxdWUgPSBBdHRyaWJ1dHZcdTAwRTRyZGV0ICJ7MH0iIGF2IHR5cGVuIElEIG1cdTAwRTVzdGUgdmFyYSB1bmlrdCBpbm9tIGRva3VtZW50ZXQuCi0gICAgICAgIElEUkVGSW52YWxpZCA9IEF0dHJpYnV0dlx1MDBFNHJkZXQgInswfSIgYXYgdHlwZW4gSURSRUYgbVx1MDBFNXN0ZSB2YXJhIGV0dCBuYW1uLgotICAgICAgICBJRFJFRkludmFsaWRXaXRoTmFtZXNwYWNlcyA9IEF0dHJpYnV0dlx1MDBFNHJkZXQgInswfSIgYXYgdHlwZW4gSURSRUYgbVx1MDBFNXN0ZSB2YXJhIE5DTmFtZSBvbSBuYW1ucnltZGVyIGFudlx1MDBFNG5kcy4KLSAgICAgICAgSURSRUZTSW52YWxpZCA9IEF0dHJpYnV0dlx1MDBFNHJkZXQgInswfSIgYXYgdHlwZW4gSURSRUZTIG1cdTAwRTVzdGUgdmFyYSBldHQgZWxsZXIgZmxlcmEgbmFtbi4KLSAgICAgICAgSUxMX0ZPUk1FRF9QQVJBTUVURVJfRU5USVRZX1dIRU5fVVNFRF9JTl9ERUNMID0gRXJzXHUwMEU0dHRuaW5nc3RleHRlbiBmXHUwMEY2ciBwYXJhbWV0ZXJlbmhldGVuICJ7MH0iIG1cdTAwRTVzdGUgaW5rbHVkZXJhIGtvcnJla3Qga2Fwc2xhZGUgZGVrbGFyYXRpb25lciBvbSBlbmhldHNyZWZlcmVuc2VuIGFudlx1MDBFNG5kcyBzb20gZnVsbHN0XHUwMEU0bmRpZyBkZWtsYXJhdGlvbi4KLSAgICAgICAgSW1wcm9wZXJEZWNsYXJhdGlvbk5lc3RpbmcgPSBFcnNcdTAwRTR0dG5pbmdzdGV4dGVuIGZcdTAwRjZyIHBhcmFtZXRlcmVuaGV0ZW4gInswfSIgbVx1MDBFNXN0ZSBpbmtsdWRlcmEgZGVrbGFyYXRpb25lciBzb20gXHUwMEU0ciBrb3JyZWt0IGthcHNsYWRlLgotICAgICAgICBJbXByb3Blckdyb3VwTmVzdGluZyA9IEVyc1x1MDBFNHR0bmluZ3N0ZXh0ZW4gZlx1MDBGNnIgcGFyYW1ldGVyZW5oZXRlbiAiezB9IiBtXHUwMEU1c3RlIGlua2x1ZGVyYSBwYXJlbnRlc3BhciBzb20gXHUwMEU0ciBrb3JyZWt0IGthcHNsYWRlLgotICAgICAgICBJTlZBTElEX1BFX0lOX0NPTkRJVElPTkFMID0gRXJzXHUwMEU0dHRuaW5nc3RleHRlbiBmXHUwMEY2ciBwYXJhbWV0ZXJlbmhldGVuICJ7MH0iIG1cdTAwRTVzdCBpbmtsdWRlcmEgaGVsYSB2aWxsa29yc3Nla3Rpb25lbiBlbGxlciBlbmRhc3QgSU5DTFVERSBlbGxlciBJR05PUkUuCi0gICAgICAgIE1TR19BVFRSSUJVVEVfTk9UX0RFQ0xBUkVEID0gQXR0cmlidXRldCAiezF9IiBtXHUwMEU1c3RlIGRla2xhcmVyYXMgZlx1MDBGNnIgZWxlbWVudHR5cCAiezB9Ii4KLSAgICAgICAgTVNHX0FUVFJJQlVURV9WQUxVRV9OT1RfSU5fTElTVCA9IEF0dHJpYnV0ZXQgInswfSIgbWVkIHZcdTAwRTRyZGV0ICJ7MX0iIG1cdTAwRTVzdGUgaGEgZXR0IHZcdTAwRTRyZGUgZnJcdTAwRTVuIGxpc3RhbiAiezJ9Ii4KLSAgICAgICAgTVNHX0FUVFZBTFVFX0NIQU5HRURfRFVSSU5HX05PUk1BTElaQVRJT05fV0hFTl9TVEFOREFMT05FID0gVlx1MDBFNHJkZXQgInsxfSIgZlx1MDBGNnIgYXR0cmlidXRldCAiezB9IiBmXHUwMEU1ciBpbnRlIFx1MDBFNG5kcmFzIHZpZCBub3JtYWxpc2VyaW5nICh0aWxsICJ7Mn0iKSBpIGV0dCBmcmlzdFx1MDBFNWVuZGUgZG9rdW1lbnQuCi0gICAgICAgIE1TR19DT05URU5UX0lOQ09NUExFVEUgPSBJbm5laFx1MDBFNWxsZXQgaSBlbGVtZW50dHlwICJ7MH0iIFx1MDBFNHIgb2Z1bGxzdFx1MDBFNG5kaWd0LCBkZXQgbVx1MDBFNXN0ZSBtYXRjaGEgInsxfSIuCi0gICAgICAgIE1TR19DT05URU5UX0lOVkFMSUQgPSBJbm5laFx1MDBFNWxsZXQgaSBlbGVtZW50dHlwICJ7MH0iIG1cdTAwRTVzdGUgbWF0Y2hhICJ7MX0iLgotICAgICAgICBNU0dfQ09OVEVOVF9JTlZBTElEX1NQRUNJRklFRCA9IElubmVoXHUwMEU1bGxldCBpIGVsZW1lbnR0eXAgInswfSIgbVx1MDBFNXN0ZSBtYXRjaGEgInsxfSIuIFVuZGVyb3JkbmFkZSB0aWxsIHR5cCAiezJ9IiBcdTAwRTRyIGludGUgdGlsbFx1MDBFNXRuYS4KLSAgICAgICAgTVNHX0RFRkFVTFRFRF9BVFRSSUJVVEVfTk9UX1NQRUNJRklFRCA9IEF0dHJpYnV0ZXQgInsxfSIgZlx1MDBGNnIgZWxlbWVudHR5cCAiezB9IiBoYXIgZXR0IHN0YW5kYXJkdlx1MDBFNHJkZSBvY2ggbVx1MDBFNXN0ZSBhbmdlcyBpIGV0dCBmcmlzdFx1MDBFNWVuZGUgZG9rdW1lbnQuCi0gICAgICAgIE1TR19EVVBMSUNBVEVfQVRUREVGID0gQXR0cmlidXRldCAiezF9IiBoYXIgcmVkYW4gZGVrbGFyZXJhdHMgZlx1MDBGNnIgZWxlbWVudHR5cCAiezB9Ii4KLSAgICAgICAgTVNHX0VMRU1FTlRfQUxSRUFEWV9ERUNMQVJFRCA9IEVsZW1lbnR0eXAgInswfSIgZlx1MDBFNXIgZGVrbGFyZXJhcyBlbmRhc3QgZW4gZ1x1MDBFNW5nLgotICAgICAgICBNU0dfRUxFTUVOVF9OT1RfREVDTEFSRUQgPSBFbGVtZW50dHlwICJ7MH0iIG1cdTAwRTVzdGUgZGVrbGFyZXJhcy4KLSAgICAgICAgTVNHX0dSQU1NQVJfTk9UX0ZPVU5EID0gRG9rdW1lbnRldCBcdTAwRTRyIG9naWx0aWd0OiBoaXR0YWRlIGluZ2VuIGdyYW1tYXRpay4KLSAgICAgICAgTVNHX0VMRU1FTlRfV0lUSF9JRF9SRVFVSVJFRCA9IEV0dCBlbGVtZW50IG1lZCBpZGVudGlmaWVyYXJlbiAiezB9IiBtXHUwMEU1c3RlIGZpbm5hcyBtZWQgaSBkb2t1bWVudGV0LgotICAgICAgICBNU0dfRVhURVJOQUxfRU5USVRZX05PVF9QRVJNSVRURUQgPSBSZWZlcmVucyB0aWxsIGRlbiBleHRlcm5hIGVuaGV0ZW4gInswfSIgXHUwMEU0ciBpbnRlIHRpbGxcdTAwRTV0ZXQgaSBmcmlzdFx1MDBFNWVuZGUgZG9rdW1lbnQuCi0gICAgICAgIE1TR19GSVhFRF9BVFRWQUxVRV9JTlZBTElEID0gQXR0cmlidXRldCAiezF9IiBtZWQgdlx1MDBFNHJkZXQgInsyfSIgbVx1MDBFNXN0ZSBoYSB2XHUwMEU0cmRldCAiezN9Ii4KLSAgICAgICAgTVNHX01PUkVfVEhBTl9PTkVfSURfQVRUUklCVVRFID0gRWxlbWVudHR5cCAiezB9IiBoYXIgcmVkYW4gYXR0cmlidXRldCAiezF9IiBhdiBpZC10eXAsIGV0dCBhbmRyYSBhdHRyaWJ1dCAiezJ9IiBhdiBzYW1tYSB0eXAgXHUwMEU0ciBpbnRlIHRpbGxcdTAwRTV0ZXQuCi0gICAgICAgIE1TR19NT1JFX1RIQU5fT05FX05PVEFUSU9OX0FUVFJJQlVURSA9IEVsZW1lbnR0eXAgInswfSIgaGFyIHJlZGFuIGF0dHJpYnV0ZXQgInsxfSIgYXYgTk9UQVRJT04tdHlwLCBldHQgYW5kcmEgYXR0cmlidXQgInsyfSIgYXYgc2FtbWEgdHlwIFx1MDBFNHIgaW50ZSB0aWxsXHUwMEU1dGV0LgotICAgICAgICBNU0dfTk9UQVRJT05fTk9UX0RFQ0xBUkVEX0ZPUl9OT1RBVElPTlRZUEVfQVRUUklCVVRFID0gTm90YXRpb25lbiAiezF9IiBtXHUwMEU1c3RlIGRla2xhcmVyYXMgdmlkIHJlZmVyZW5zIGkgbm90YXRpb25zdHlwbGlzdGFuIGZcdTAwRjZyIGF0dHJpYnV0ZXQgInswfSIuCi0gICAgICAgIE1TR19OT1RBVElPTl9OT1RfREVDTEFSRURfRk9SX1VOUEFSU0VEX0VOVElUWURFQ0wgPSBOb3RhdGlvbmVuICJ7MX0iIG1cdTAwRTVzdGUgZGVrbGFyZXJhcyB2aWQgcmVmZXJlbnMgaSBvdG9sa2FkIGVuaGV0c2Rla2xhcmF0aW9uIGZcdTAwRjZyICJ7MH0iLgotICAgICAgICBNU0dfUkVGRVJFTkNFX1RPX0VYVEVSTkFMTFlfREVDTEFSRURfRU5USVRZX1dIRU5fU1RBTkRBTE9ORSA9IFJlZmVyZW5zZW4gdGlsbCBlbmhldGVuICJ7MH0iIHNvbSBoYXIgZGVrbGFyZXJhdHMgaSBlbiBleHRlcm50IHRvbGthZCBlbmhldCBcdTAwRTRyIGludGUgdGlsbFx1MDBFNXRldCBpIGZyaXN0XHUwMEU1ZW5kZSBkb2t1bWVudC4KLSAgICAgICAgTVNHX1JFUVVJUkVEX0FUVFJJQlVURV9OT1RfU1BFQ0lGSUVEID0gQXR0cmlidXRldCAiezF9IiBtXHUwMEU1c3RlIGFuZ2VzIGZcdTAwRjZyIGVsZW1lbnR0eXAgInswfSIuCi0gICAgICAgIE1TR19XSElURV9TUEFDRV9JTl9FTEVNRU5UX0NPTlRFTlRfV0hFTl9TVEFOREFMT05FID0gVG9tdCB1dHJ5bW1lIGZcdTAwRTVyIGludGUgZlx1MDBGNnJla29tbWEgbWVsbGFuIGVsZW1lbnQgc29tIGhhciBkZWtsYXJlcmF0cyBpIGVuIGV4dGVybnQgdG9sa2FkIGVuaGV0IG1lZCBlbGVtZW50aW5uZWhcdTAwRTVsbCBpIGZyaXN0XHUwMEU1ZW5kZSBkb2t1bWVudC4KLSAgICAgICAgTk1UT0tFTkludmFsaWQgPSBBdHRyaWJ1dHZcdTAwRTRyZGV0ICJ7MH0iIGF2IHR5cGVuIE5NVE9LRU4gbVx1MDBFNXN0ZSB2YXJhIGV0dCBuYW1udGVja2VuLgotICAgICAgICBOTVRPS0VOU0ludmFsaWQgPSBBdHRyaWJ1dHZcdTAwRTRyZGV0ICJ7MH0iIGF2IHR5cGVuIE5NVE9LRU5TIG1cdTAwRTVzdGUgdmFyYSBldHQgZWxsZXIgZmxlcmEgbmFtbnRlY2tlbi4KLSAgICAgICAgTm9Ob3RhdGlvbk9uRW1wdHlFbGVtZW50ID0gRWxlbWVudHR5cCAiezB9IiBtZWQgZGVrbGFyYXRpb25lbiBFTVBUWSBrYW4gaW50ZSBkZWtsYXJlcmFzIG1lZCBhdHRyaWJ1dGV0ICJ7MX0iIGF2IHR5cGVuIE5PVEFUSU9OLgotICAgICAgICBSb290RWxlbWVudFR5cGVNdXN0TWF0Y2hEb2N0eXBlZGVjbCA9IERva3VtZW50cm90ZWxlbWVudGV0ICJ7MX0iIG1cdTAwRTVzdGUgbWF0Y2hhIERPQ1RZUEUtcm90ZW4gInswfSIuCi0gICAgICAgIFVuZGVjbGFyZWRFbGVtZW50SW5Db250ZW50U3BlYyA9IE1vZGVsbGVuIG1lZCBpbm5laFx1MDBFNWxsIGZcdTAwRjZyIGVsZW1lbnRldCAiezB9IiByZWZlcmVyYXIgdGlsbCBlbGVtZW50ZXQgInsxfSIgc29tIGludGUgaGFyIGRla2xhcmVyYXRzLgotICAgICAgICBVbmlxdWVOb3RhdGlvbk5hbWUgPSBEZWtsYXJhdGlvbmVuIGZcdTAwRjZyIG5vdGF0aW9uZW4gInswfSIgXHUwMEU0ciBpbnRlIHVuaWsuIEV0dCBuYW1uIGZcdTAwRTVyIGludGUgZGVrbGFyZXJhcyBpIGZsZXIgXHUwMEU0biBlbiBub3RhdGlvbnNkZWtsYXJhdGlvbi4KLSAgICAgICAgRU5USVRZRmFpbGVkSW5pdGlhbGl6ZUdyYW1tYXIgPSAgRU5USVRZRGF0YXR5cGUtdmFsaWRlcmFyZTogQmVob3YgYXR0IGFucm9wYSBpbml0aWVyaW5nc21ldG9kIG1lZCBnaWx0aWcgZ3JhbW1hdGlrcmVmZXJlbnMgdXRmXHUwMEY2cmRlcyBpbnRlLiBcdAotICAgICAgICBFTlRJVFlOb3RVbnBhcnNlZCA9IEVOVElUWSAiezB9IiBcdTAwRTRyIG90b2xrYXQuCi0gICAgICAgIEVOVElUWU5vdFZhbGlkID0gRU5USVRZICJ7MH0iIFx1MDBFNHIgaW50ZSBnaWx0aWd0LgotICAgICAgICBFbXB0eUxpc3QgPSBWXHUwMEU0cmRldCBmXHUwMEY2ciB0eXAgRU5USVRJRVMsIElEUkVGUyBvY2ggTk1UT0tFTlMgZlx1MDBFNXIgaW50ZSB2YXJhIGVuIHRvbSBsaXN0YS4KLQotIyBFbnRpdHkgcmVsYXRlZCBtZXNzYWdlcwotIyAzLjEgU3RhcnQtVGFncywgRW5kLVRhZ3MsIGFuZCBFbXB0eS1FbGVtZW50IFRhZ3MKLSAgICAgICAgUmVmZXJlbmNlVG9FeHRlcm5hbEVudGl0eSA9IERlbiBleHRlcm5hIGVuaGV0c3JlZmVyZW5zZW4gIiZ7MH07IiB0aWxsXHUwMEU1dHMgaW50ZSBpIGV0dCBhdHRyaWJ1dHZcdTAwRTRyZGUuCi0gICAgICAgIEFjY2Vzc0V4dGVybmFsRFREID0gRXh0ZXJuIERURDogS3VuZGUgaW50ZSBsXHUwMEU0c2EgZXh0ZXJuIERURCAnJ3swfScnLCBlZnRlcnNvbSAnJ3sxfScnIFx1MDBFNXRrb21zdCBpbnRlIHRpbGxcdTAwRTV0cyBwXHUwMEU1IGdydW5kIGF2IGJlZ3JcdTAwRTRuc25pbmcgc29tIGFuZ2VzIGF2IGFjY2Vzc0V4dGVybmFsRFRELWVnZW5za2FwZW4uCi0gICAgICAgIEFjY2Vzc0V4dGVybmFsRW50aXR5ID0gRXh0ZXJuIGVuaGV0OiBLdW5kZSBpbnRlIGxcdTAwRTRzYSBleHRlcm50IGRva3VtZW50ICcnezB9JycsIGVmdGVyc29tICcnezF9JycgXHUwMEU1dGtvbXN0IGludGUgdGlsbFx1MDBFNXRzIHBcdTAwRTUgZ3J1bmQgYXYgYmVnclx1MDBFNG5zbmluZyBzb20gYW5nZXMgYXYgYWNjZXNzRXh0ZXJuYWxEVEQtZWdlbnNrYXBlbi4KLQotIyA0LjEgQ2hhcmFjdGVyIGFuZCBFbnRpdHkgUmVmZXJlbmNlcwotICAgICAgICBFbnRpdHlOb3REZWNsYXJlZCA9IEVuaGV0ZW4gInswfSIgaGFyIHJlZmVyZXJhdHMsIG1lbiBcdTAwRTRyIGludGUgZGVrbGFyZXJhZC4KLSAgICAgICAgUmVmZXJlbmNlVG9VbnBhcnNlZEVudGl0eSA9IERlbiBvdG9sa2FkZSBlbmhldHNyZWZlcmVuc2VuICImezB9OyIgXHUwMEU0ciBpbnRlIHRpbGxcdTAwRTV0ZW4uCi0gICAgICAgIFJlY3Vyc2l2ZVJlZmVyZW5jZSA9IFJla3Vyc2l2IGVuaGV0c3JlZmVyZW5zICJ7MH0iLiAoUmVmZXJlbnNzXHUwMEY2a3ZcdTAwRTRnOiB7MX0pLAotICAgICAgICBSZWN1cnNpdmVHZW5lcmFsUmVmZXJlbmNlID0gUmVrdXJzaXYgYWxsbVx1MDBFNG4gZW5oZXRzcmVmZXJlbnMgIiZ7MH07Ii4gKFJlZmVyZW5zc1x1MDBGNmt2XHUwMEU0ZzogezF9KSwKLSAgICAgICAgUmVjdXJzaXZlUEVSZWZlcmVuY2UgPSBSZWt1cnNpdiBwYXJhbWV0ZXJyZWZlcmVucyAiJXswfTsiLiAoUmVmZXJlbnNzXHUwMEY2a3ZcdTAwRTRnOiB7MX0pLAotIyA0LjMuMyBDaGFyYWN0ZXIgRW5jb2RpbmcgaW4gRW50aXRpZXMKLSAgICAgICAgRW5jb2RpbmdOb3RTdXBwb3J0ZWQgPSBLb2RuaW5nZW4gInswfSIgc3RcdTAwRjZkcyBpbnRlLgotICAgICAgICBFbmNvZGluZ1JlcXVpcmVkID0gRW4gdG9sa2FkIGVuaGV0IHNvbSBpbnRlIFx1MDBFNHIga29kYWQgaSB2YXJrZW4gVVRGLTggZWxsZXIgVVRGLTE2IG1cdTAwRTVzdGUgaGEgZW4ga29kbmluZ3NkZWtsYXJhdGlvbi4KLSAgICAgICAgCi0jIE5hbWVzcGFjZXMgc3VwcG9ydAotIyA0LiBVc2luZyBRdWFsaWZpZWQgTmFtZXMKLSAgICAgICAgSWxsZWdhbFFOYW1lID0gRWxlbWVudCBlbGxlciBhdHRyaWJ1dCBtYXRjaGFyIGludGUgUU5hbWUtcHJvZHVrdGlvbjogUU5hbWU6Oj0oTkNOYW1lJzonKT9OQ05hbWUuIAotICAgICAgICBFbGVtZW50WE1MTlNQcmVmaXggPSBFbGVtZW50ZXQgInswfSIga2FuIGludGUgYW52XHUwMEU0bmRhcyBtZWQgInhtbG5zIiBzb20gcHJlZml4LgotICAgICAgICBFbGVtZW50UHJlZml4VW5ib3VuZCA9IFByZWZpeGV0ICJ7MH0iIGZcdTAwRjZyIGVsZW1lbnRldCAiezF9IiBcdTAwRTRyIGludGUgYnVuZGV0LgotICAgICAgICBBdHRyaWJ1dGVQcmVmaXhVbmJvdW5kID0gUHJlZml4ZXQgInsyfSIgZlx1MDBGNnIgYXR0cmlidXRldCAiezF9IiBzb20gYXNzb2NpZXJhcyBtZWQgZWxlbWVudHR5cCAiezB9IiBcdTAwRTRyIGludGUgYnVuZGV0LgotICAgICAgICBFbXB0eVByZWZpeGVkQXR0TmFtZSA9IE9naWx0aWd0IHZcdTAwRTRyZGUgZlx1MDBGNnIgYXR0cmlidXRldCAiezB9Ii4gTmFtbnJ5bWRzYmluZG5pbmdhciBzb20gcHJlZml4IGthbnNrZSBpbnRlIFx1MDBFNHIgdG9tbWEuCi0gICAgICAgIFByZWZpeERlY2xhcmVkID0gTmFtbnJ5bWRzcHJlZml4ZXQgInswfSIgaGFyIGludGUgZGVrbGFyZXJhdHMuCi0gICAgICAgIENhbnRCaW5kWE1MTlMgPSBQcmVmaXhldCAieG1sbnMiIGthbiBpbnRlIGJpbmRhcyB0aWxsIGVuIHNwZWNpZmlrIG5hbW5yeW1kIG9jaCBuYW1ucnltZGVuIGZcdTAwRjZyICJ4bWxucyIga2FuIGludGUgaGVsbGVyIGJpbmRhcyB0aWxsIGV0dCBzcGVjaWZpa3QgcHJlZml4LgotICAgICAgICBDYW50QmluZFhNTCA9IFByZWZpeGV0ICJ4bWwiIGthbiBpbnRlIGJpbmRhcyB0aWxsIGVuIG5hbW5yeW1kIHV0XHUwMEY2dmVyIGRlbiB2YW5saWdhIG9jaCBuYW1ucnltZGVuIGZcdTAwRjZyICJ4bWwiIGthbiBpbnRlIGhlbGxlciBiaW5kYXMgdGlsbCBuXHUwMEU1Z290IGFubmF0IHByZWZpeCBcdTAwRTRuICJ4bWwiLgotICAgICAgICBNU0dfQVRUX0RFRkFVTFRfSU5WQUxJRCA9IGRlZmF1bHRWYWx1ZSAiezF9IiBmXHUwMEY2ciBhdHRyaWJ1dGV0ICJ7MH0iIFx1MDBFNHIgaW50ZSB0aWxsXHUwMEU1dGV0IHZhZCBnXHUwMEU0bGxlciBkZSBsZXhpa2FsYSBiZWdyXHUwMEU0bnNuaW5nYXJuYSBmXHUwMEY2ciBkZW5uYSBhdHRyaWJ1dHR5cC4KLQotIyBSRVZJU0lUOiBUaGVzZSBuZWVkIG1lc3NhZ2VzCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9BRlRFUl9TWVNURU1MSVRFUkFMX0lOX0VYVEVSTkFMSUQ9TVNHX1NQQUNFX1JFUVVJUkVEX0FGVEVSX1NZU1RFTUxJVEVSQUxfSU5fRVhURVJOQUxJRAotICAgICAgICBPcGVuUXVvdGVNaXNzaW5nSW5EZWNsPU9wZW5RdW90ZU1pc3NpbmdJbkRlY2wKLSAgICAgICAgSW52YWxpZENoYXJJbkxpdGVyYWw9SW52YWxpZENoYXJJbkxpdGVyYWwKLQotCi0jIEltcGxlbWVudGF0aW9uIGxpbWl0cwotICAgICAgICBFbnRpdHlFeHBhbnNpb25MaW1pdD1KQVhQMDAwMTAwMDE6IFBhcnNlcm4gaGFyIHBcdTAwRTV0clx1MDBFNGZmYXQgZmxlciBcdTAwRTRuICJ7MH0iIGVuaGV0c3RpbGxcdTAwRTRnZyBpIGRva3VtZW50ZXQgLSBnclx1MDBFNG5zdlx1MDBFNHJkZXQgZlx1MDBGNnIgSkRLIGhhciB1cHBuXHUwMEU1dHRzLgotICAgICAgICBFbGVtZW50QXR0cmlidXRlTGltaXQ9SkFYUDAwMDEwMDAyOiAgRWxlbWVudGV0ICJ7MH0iIGhhciBmbGVyIFx1MDBFNG4gInsxfSIgYXR0cmlidXQsICJ7MX0iIFx1MDBFNHIgZ3JcdTAwRTRuc3ZcdTAwRTRyZGV0IGZcdTAwRjZyIEpESy4KLSAgICAgICAgTWF4RW50aXR5U2l6ZUxpbWl0PUpBWFAwMDAxMDAwMzogTFx1MDBFNG5nZGVuIHBcdTAwRTUgZW5oZXRlbiAiezB9IiBcdTAwRTRyICJ7MX0iIHNvbSBcdTAwRjZ2ZXJza3JpdmVyIGdyXHUwMEU0bnN2XHUwMEU0cmRldCBwXHUwMEU1ICJ7Mn0iIHNvbSBhbmdlcyBhdiAiezN9Ii4KLSAgICAgICAgVG90YWxFbnRpdHlTaXplTGltaXQ9SkFYUDAwMDEwMDA0OiBEZW4gYWNrdW11bGVyYWRlIHN0b3JsZWtlbiBmXHUwMEY2ciBlbmhldGVyIFx1MDBFNHIgInswfSIsIHZpbGtldCBcdTAwRjZ2ZXJza3JpZGVyIGdyXHUwMEU0bnN2XHUwMEU0cmRldCAiezF9IiBzb20gYW5nZXMgYXYgInsyfSIuCi0gICAgICAgIE1heFhNTE5hbWVMaW1pdD1KQVhQMDAwMTAwMDU6IExcdTAwRTRuZ2RlbiBwXHUwMEU1IGVuaGV0ZW4gInswfSIgXHUwMEU0ciAiezF9Iiwgdmlsa2V0IFx1MDBGNnZlcnNrcmlkZXIgZ3JcdTAwRTRuc3ZcdTAwRTRyZGV0ICJ7Mn0iIHNvbSBhbmdlcyBhdiAiezN9Ii4KLSAgICAgICAgTWF4RWxlbWVudERlcHRoTGltaXQ9SkFYUDAwMDEwMDA2OiBFbGVtZW50ZXQgInswfSIgaGFyIGRqdXBldCAiezF9IiB2aWxrZXQgXHUwMEU0ciBzdFx1MDBGNnJyZSBcdTAwRTRuIGdyXHUwMEU0bnNlbiAiezJ9IiBzb20gYW5nZXMgYXYgInszfSIuCi0gICAgICAgIEVudGl0eVJlcGxhY2VtZW50TGltaXQ9SkFYUDAwMDEwMDA3OiBEZXQgdG90YWxhIGFudGFsZXQgbm9kZXIgaSBlbmhldHNyZWZlcmVuc2VyIFx1MDBFNHIgInswfSIsIHZpbGtldCBcdTAwRTRyIFx1MDBGNnZlciBnclx1MDBFNG5zZW4gInsxfSIgc29tIGhhciBhbmdldHRzIGF2ICJ7Mn0iLgotCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9YTUxNZXNzYWdlc196aF9DTi5wcm9wZXJ0aWVzIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MTWVzc2FnZXNfemhfQ04ucHJvcGVydGllcwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZGMyZTFkMC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9YTUxNZXNzYWdlc196aF9DTi5wcm9wZXJ0aWVzCisrKyAvZGV2L251bGwKQEAgLTEsMzA1ICswLDAgQEAKLSMgVGhpcyBmaWxlIGNvbnRhaW5zIGVycm9yIGFuZCB3YXJuaW5nIG1lc3NhZ2VzIHJlbGF0ZWQgdG8gWE1MCi0jIFRoZSBtZXNzYWdlcyBhcmUgYXJyYW5nZWQgaW4ga2V5IGFuZCB2YWx1ZSB0dXBsZXMgaW4gYSBMaXN0UmVzb3VyY2VCdW5kbGUuCi0jCi0jIEB2ZXJzaW9uCi0KLSAgICAgICAgQmFkTWVzc2FnZUtleSA9IFx1NjI3RVx1NEUwRFx1NTIzMFx1NEUwRVx1NkQ4OFx1NjA2Rlx1NTE3M1x1OTUyRVx1NUI1N1x1NUJGOVx1NUU5NFx1NzY4NFx1OTUxOVx1OEJFRlx1NkQ4OFx1NjA2Rlx1MzAwMgotICAgICAgICBGb3JtYXRGYWlsZWQgPSBcdThCQkVcdTdGNkVcdTRFRTVcdTRFMEJcdTZEODhcdTYwNkZcdTc2ODRcdTY4M0NcdTVGMEZcdTY1RjZcdTUxRkFcdTczQjBcdTUxODVcdTkwRThcdTk1MTlcdThCRUY6XG4gIAotICAgICAgICAKLSMgRG9jdW1lbnQgbWVzc2FnZXMKLSAgICAgICAgUHJlbWF0dXJlRU9GPVx1NjU4N1x1NEVGNlx1NjNEMFx1NTI0RFx1N0VEM1x1Njc1Rlx1MzAwMgotIyAyLjEgV2VsbC1Gb3JtZWQgWE1MIERvY3VtZW50cwotICAgICAgICBSb290RWxlbWVudFJlcXVpcmVkID0gXHU2ODM5XHU1MTQzXHU3RDIwXHU1RTk0XHU4QkU1XHU0RjREXHU0RThFXHU2ODNDXHU1RjBGXHU2QjYzXHU3ODZFXHU3Njg0XHU2NTg3XHU2ODYzXHU0RTJEXHUzMDAyCi0jIDIuMiBDaGFyYWN0ZXJzCi0KLSAgICAgICAgSW52YWxpZENoYXJJbkNEU2VjdCA9IFx1NTcyOCBDREFUQSBcdTgyODJcdTRFMkRcdTYyN0VcdTUyMzBcdTY1RTBcdTY1NDhcdTc2ODQgWE1MIFx1NUI1N1x1N0IyNiAoVW5pY29kZTogMHh7MH0pXHUzMDAyCi0gICAgICAgIEludmFsaWRDaGFySW5Db250ZW50ID0gXHU1NzI4XHU2NTg3XHU2ODYzXHU3Njg0XHU1MTQzXHU3RDIwXHU1MTg1XHU1QkI5XHU0RTJEXHU2MjdFXHU1MjMwXHU2NUUwXHU2NTQ4XHU3Njg0IFhNTCBcdTVCNTdcdTdCMjYgKFVuaWNvZGU6IDB4ezB9KVx1MzAwMgotICAgICAgICBUd29Db2xvbnNJblFOYW1lID0gXHU1NzI4XHU1MTQzXHU3RDIwXHU1MTg1XHU1QkI5XHU2MjE2XHU1QzVFXHU2MDI3XHU1NDBEXHU0RTJEXHU2MjdFXHU1MjMwXHU2NUUwXHU2NTQ4XHU3Njg0XHU3QjJDXHU0RThDXHU0RTJBICc6J1x1MzAwMgotICAgICAgICBDb2xvbk5vdExlZ2FsV2l0aE5TID0gXHU1RjUzXHU1NDJGXHU3NTI4XHU1NDBEXHU3OUYwXHU3QTdBXHU5NUY0XHU2NUY2LCBcdTRFMERcdTUxNDFcdThCQjhcdTU3MjhcdTU0MERcdTc5RjAgJyd7MH0nJyBcdTRFMkRcdTRGN0ZcdTc1MjhcdTUxOTJcdTUzRjdcdTMwMDIKLSAgICAgICAgSW52YWxpZENoYXJJbk1pc2MgPSBcdTU3MjhcdTUxNDNcdTdEMjBcdTUxODVcdTVCQjlcdTdFRDNcdTVDM0VcdTU0MEVcdTc2ODRcdTY4MDdcdThCQjBcdTRFMkRcdTYyN0VcdTUyMzBcdTY1RTBcdTY1NDhcdTc2ODQgWE1MIFx1NUI1N1x1N0IyNiAoVW5pY29kZTogMHh7MH0pXHUzMDAyCi0gICAgICAgIEludmFsaWRDaGFySW5Qcm9sb2cgPSBcdTU3MjhcdTY1ODdcdTY4NjNcdTUyNERcdThBMDBcdTRFMkRcdTYyN0VcdTUyMzBcdTY1RTBcdTY1NDhcdTc2ODQgWE1MIFx1NUI1N1x1N0IyNiAoVW5pY29kZTogMHh7MH0pXHUzMDAyCi0gICAgICAgIEludmFsaWRDaGFySW5YTUxEZWNsID0gXHU1NzI4IFhNTCBcdTU4RjBcdTY2MEVcdTRFMkRcdTYyN0VcdTUyMzBcdTY1RTBcdTY1NDhcdTc2ODQgWE1MIFx1NUI1N1x1N0IyNiAoVW5pY29kZTogMHh7MH0pXHUzMDAyCi0jIDIuNCBDaGFyYWN0ZXIgRGF0YSBhbmQgTWFya3VwCi0gICAgICAgIENERW5kSW5Db250ZW50ID0gXHU5NjY0XHU5NzVFXHU0RjdGXHU3NTI4XHU1QjU3XHU3QjI2XHU1RThGXHU1MjE3ICJdXT4iIFx1Njc2NVx1NjgwN1x1OEJCMCBDREFUQSBcdTgyODJcdTc2ODRcdTdFRDNcdTVDM0UsIFx1NTQyNlx1NTIxOVx1OEJFNVx1NUI1N1x1N0IyNlx1NUU4Rlx1NTIxN1x1NEUwRFx1ODBGRFx1NTFGQVx1NzNCMFx1NTcyOFx1NTE4NVx1NUJCOVx1NEUyRFx1MzAwMgotIyAyLjcgQ0RBVEEgU2VjdGlvbnMKLSAgICAgICAgQ0RTZWN0VW50ZXJtaW5hdGVkID0gQ0RBVEEgXHU4MjgyXHU1RkM1XHU5ODdCXHU0RUU1ICJdXT4iIFx1N0VEM1x1NUMzRVx1MzAwMgotIyAyLjggUHJvbG9nIGFuZCBEb2N1bWVudCBUeXBlIERlY2xhcmF0aW9uCi0gICAgICAgIFhNTERlY2xNdXN0QmVGaXJzdCA9IFhNTCBcdTU4RjBcdTY2MEVcdTUzRUFcdTgwRkRcdTUxRkFcdTczQjBcdTU3MjhcdTY1ODdcdTY4NjNcdTc2ODRcdTY3MDBcdTVGMDBcdTU5MzRcdTU5MDRcdTMwMDIKLSAgICAgICAgRXFSZXF1aXJlZEluWE1MRGVjbCA9IFx1NTcyOCBYTUwgXHU1OEYwXHU2NjBFXHU0RTJELCAiezB9IiBcdTU0MEVcdTk3NjJcdTVGQzVcdTk4N0JcdThEREZcdTY3MDkgJycgPSAnJyBcdTVCNTdcdTdCMjZcdTMwMDIKLSAgICAgICAgUXVvdGVSZXF1aXJlZEluWE1MRGVjbCA9IFhNTCBcdTU4RjBcdTY2MEVcdTRFMkQgInswfSIgXHU1NDBFXHU5NzYyXHU4RERGXHU5NjhGXHU3Njg0XHU1MDNDXHU1RkM1XHU5ODdCXHU2NjJGXHU3NTI4XHU1RjE1XHU1M0Y3XHU2MkVDXHU4RDc3XHU2NzY1XHU3Njg0XHU1QjU3XHU3QjI2XHU0RTMyXHUzMDAyCi0gICAgICAgIFhNTERlY2xVbnRlcm1pbmF0ZWQgPSBYTUwgXHU1OEYwXHU2NjBFXHU1RkM1XHU5ODdCXHU0RUU1ICI/PiIgXHU3RUQzXHU1QzNFXHUzMDAyCi0gICAgICAgIFZlcnNpb25JbmZvUmVxdWlyZWQgPSBYTUwgXHU1OEYwXHU2NjBFXHU0RTJEXHU5NzAwXHU4OTgxXHU2QjY0XHU3MjQ4XHU2NzJDXHUzMDAyCi0gICAgICAgIFNwYWNlUmVxdWlyZWRCZWZvcmVWZXJzaW9uSW5YTUxEZWNsID0gXHU1NzI4IFhNTCBcdTU4RjBcdTY2MEVcdTRFMkRcdTc2ODRcdTcyNDhcdTY3MkNcdTRGMkFcdTVDNUVcdTYwMjdcdTUyNERcdTk3NjJcdTVGQzVcdTk4N0JcdTY3MDlcdTdBN0FcdTY4M0NcdTMwMDIKLSAgICAgICAgU3BhY2VSZXF1aXJlZEJlZm9yZUVuY29kaW5nSW5YTUxEZWNsID0gXHU1NzI4IFhNTCBcdTU4RjBcdTY2MEVcdTRFMkRcdTc2ODRcdTdGMTZcdTc4MDFcdTRGMkFcdTVDNUVcdTYwMjdcdTUyNERcdTk3NjJcdTVGQzVcdTk4N0JcdTY3MDlcdTdBN0FcdTY4M0NcdTMwMDIKLSAgICAgICAgU3BhY2VSZXF1aXJlZEJlZm9yZVN0YW5kYWxvbmUgPSBcdTU3MjggWE1MIFx1NThGMFx1NjYwRVx1NEUyRFx1NzY4NFx1N0YxNlx1NzgwMVx1NEYyQVx1NUM1RVx1NjAyN1x1NTI0RFx1OTc2Mlx1NUZDNVx1OTg3Qlx1NjcwOVx1N0E3QVx1NjgzQ1x1MzAwMgotICAgICAgICBNYXJrdXBOb3RSZWNvZ25pemVkSW5Qcm9sb2cgPSBcdTY1ODdcdTY4NjNcdTRFMkRcdTY4MzlcdTUxNDNcdTdEMjBcdTUyNERcdTk3NjJcdTc2ODRcdTY4MDdcdThCQjBcdTVGQzVcdTk4N0JcdTY4M0NcdTVGMEZcdTZCNjNcdTc4NkVcdTMwMDIKLSAgICAgICAgTWFya3VwTm90UmVjb2duaXplZEluTWlzYyA9IFx1NjU4N1x1Njg2M1x1NEUyRFx1NjgzOVx1NTE0M1x1N0QyMFx1NTQwRVx1OTc2Mlx1NzY4NFx1NjgwN1x1OEJCMFx1NUZDNVx1OTg3Qlx1NjgzQ1x1NUYwRlx1NkI2M1x1Nzg2RVx1MzAwMgotICAgICAgICBBbHJlYWR5U2VlbkRvY3R5cGUgPSBcdTVERjJcdTdFQ0ZcdTc3MEJcdTUyMzAgZG9jdHlwZVx1MzAwMgotICAgICAgICBEb2N0eXBlTm90QWxsb3dlZCA9IFx1NUMwNlx1NTI5Rlx1ODBGRCAiaHR0cDovL2FwYWNoZS5vcmcveG1sL2ZlYXR1cmVzL2Rpc2FsbG93LWRvY3R5cGUtZGVjbCIgXHU4QkJFXHU3RjZFXHU0RTNBXHUyMDFDXHU3NzFGXHUyMDFEXHU2NUY2LCBcdTRFMERcdTUxNDFcdThCQjhcdTRGN0ZcdTc1MjggRE9DVFlQRVx1MzAwMgotICAgICAgICBDb250ZW50SWxsZWdhbEluUHJvbG9nID0gXHU1MjREXHU4QTAwXHU0RTJEXHU0RTBEXHU1MTQxXHU4QkI4XHU2NzA5XHU1MTg1XHU1QkI5XHUzMDAyCi0gICAgICAgIFJlZmVyZW5jZUlsbGVnYWxJblByb2xvZyA9IFx1NTI0RFx1OEEwMFx1NEUyRFx1NEUwRFx1NTE0MVx1OEJCOFx1NjcwOVx1NUYxNVx1NzUyOFx1MzAwMgotIyBUcmFpbGluZyBNaXNjCi0gICAgICAgIENvbnRlbnRJbGxlZ2FsSW5UcmFpbGluZ01pc2M9XHU1QzNFXHU5NjhGXHU4MjgyXHU0RTJEXHU0RTBEXHU1MTQxXHU4QkI4XHU2NzA5XHU1MTg1XHU1QkI5XHUzMDAyCi0gICAgICAgIFJlZmVyZW5jZUlsbGVnYWxJblRyYWlsaW5nTWlzYz1cdTVDM0VcdTk2OEZcdTgyODJcdTRFMkRcdTRFMERcdTUxNDFcdThCQjhcdTY3MDlcdTVGMTVcdTc1MjhcdTMwMDIKLSAgICAgICAgCi0jIDIuOSBTdGFuZGFsb25lIERvY3VtZW50IERlY2xhcmF0aW9uCi0gICAgICAgIFNERGVjbEludmFsaWQgPSBcdTcyRUNcdTdBQ0JcdTY1ODdcdTY4NjNcdTU4RjBcdTY2MEVcdTUwM0NcdTVGQzVcdTk4N0JcdTRFM0EgIlx1NjYyRiIgXHU2MjE2ICJcdTU0MjYiLCBcdTRFMERcdTgwRkRcdTRFM0EgInswfSJcdTMwMDIKLSAgICAgICAgU0REZWNsTmFtZUludmFsaWQgPSBYTUwgXHU1OEYwXHU2NjBFXHU0RTJEXHU3Njg0XHU3MkVDXHU3QUNCXHU1NDBEXHU3OUYwXHU1M0VGXHU4MEZEXHU2MkZDXHU1MTk5XHU2NzA5XHU4QkVGXHUzMDAyCi0jIDIuMTIgTGFuZ3VhZ2UgSWRlbnRpZmljYXRpb24KLSAgICAgICAgWE1MTGFuZ0ludmFsaWQgPSB4bWw6bGFuZyBcdTVDNUVcdTYwMjdcdTUwM0MgInswfSIgXHU2NjJGXHU2NUUwXHU2NTQ4XHU3Njg0XHU4QkVEXHU4QTAwXHU2ODA3XHU4QkM2XHU3QjI2XHUzMDAyCi0jIDMuIExvZ2ljYWwgU3RydWN0dXJlcwotICAgICAgICBFVGFnUmVxdWlyZWQgPSBcdTUxNDNcdTdEMjBcdTdDN0JcdTU3OEIgInswfSIgXHU1RkM1XHU5ODdCXHU3NTMxXHU1MzM5XHU5MTREXHU3Njg0XHU3RUQzXHU2NzVGXHU2ODA3XHU4QkIwICI8L3swfT4iIFx1N0VDOFx1NkI2Mlx1MzAwMgotIyAzLjEgU3RhcnQtVGFncywgRW5kLVRhZ3MsIGFuZCBFbXB0eS1FbGVtZW50IFRhZ3MKLSAgICAgICAgRWxlbWVudFVudGVybWluYXRlZCA9IFx1NTE0M1x1N0QyMFx1N0M3Qlx1NTc4QiAiezB9IiBcdTVGQzVcdTk4N0JcdTU0MEVcdThEREZcdTVDNUVcdTYwMjdcdTg5QzRcdTgzMDMgIj4iIFx1NjIxNiAiLz4iXHUzMDAyCi0gICAgICAgIEVxUmVxdWlyZWRJbkF0dHJpYnV0ZSA9IFx1NEUwRVx1NTE0M1x1N0QyMFx1N0M3Qlx1NTc4QiAiezB9IiBcdTc2RjhcdTUxNzNcdTgwNTRcdTc2ODRcdTVDNUVcdTYwMjdcdTU0MEQgInsxfSIgXHU1RkM1XHU5ODdCXHU1NDBFXHU4RERGICcnID0gJycgXHU1QjU3XHU3QjI2XHUzMDAyCi0gICAgICAgIE9wZW5RdW90ZUV4cGVjdGVkID0gXHU0RTBFXHU1MTQzXHU3RDIwXHU3QzdCXHU1NzhCICJ7MH0iIFx1NzZGOFx1NTE3M1x1ODA1NFx1NzY4NFx1NUM1RVx1NjAyNyAiezF9IiBcdTVFOTRcdTY3MDlcdTVERTZcdTVGMTVcdTUzRjdcdTMwMDIKLSAgICAgICAgQ2xvc2VRdW90ZUV4cGVjdGVkID0gXHU0RTBFXHU1MTQzXHU3RDIwXHU3QzdCXHU1NzhCICJ7MH0iIFx1NzZGOFx1NTE3M1x1ODA1NFx1NzY4NFx1NUM1RVx1NjAyNyAiezF9IiBcdTVFOTRcdTY3MDlcdTUzRjNcdTVGMTVcdTUzRjdcdTMwMDIKLSAgICAgICAgQXR0cmlidXRlTm90VW5pcXVlID0gXHU1REYyXHU3RUNGXHU0RTNBXHU1MTQzXHU3RDIwICJ7MH0iIFx1NjMwN1x1NUI5QVx1NUM1RVx1NjAyNyAiezF9Ilx1MzAwMgotICAgICAgICBBdHRyaWJ1dGVOU05vdFVuaXF1ZSA9IFx1NURGMlx1N0VDRlx1NEUzQVx1NTE0M1x1N0QyMCAiezB9IiBcdTYzMDdcdTVCOUFcdTdFRDFcdTVCOUFcdTUyMzBcdTU0MERcdTc5RjBcdTdBN0FcdTk1RjQgInsyfSIgXHU3Njg0XHU1QzVFXHU2MDI3ICJ7MX0iXHUzMDAyCi0gICAgICAgIEVUYWdVbnRlcm1pbmF0ZWQgPSBcdTUxNDNcdTdEMjBcdTdDN0JcdTU3OEIgInswfSIgXHU3Njg0XHU3RUQzXHU2NzVGXHU2ODA3XHU4QkIwXHU1RkM1XHU5ODdCXHU0RUU1ICcnPicnIFx1NTIwNlx1OTY5NFx1N0IyNlx1N0VEM1x1Njc1Rlx1MzAwMgotICAgICAgICBNYXJrdXBOb3RSZWNvZ25pemVkSW5Db250ZW50ID0gXHU1MTQzXHU3RDIwXHU1MTg1XHU1QkI5XHU1RkM1XHU5ODdCXHU3NTMxXHU2ODNDXHU1RjBGXHU2QjYzXHU3ODZFXHU3Njg0XHU1QjU3XHU3QjI2XHU2NTcwXHU2MzZFXHU2MjE2XHU2ODA3XHU4QkIwXHU3RUM0XHU2MjEwXHUzMDAyCi0gICAgICAgIERvY3R5cGVJbGxlZ2FsSW5Db250ZW50ID0gXHU1MTg1XHU1QkI5XHU0RTJEXHU0RTBEXHU1MTQxXHU4QkI4XHU2NzA5IERPQ1RZUEVcdTMwMDIKLSMgNC4xIENoYXJhY3RlciBhbmQgRW50aXR5IFJlZmVyZW5jZXMKLSAgICAgICAgUmVmZXJlbmNlVW50ZXJtaW5hdGVkID0gXHU1RjE1XHU3NTI4XHU1RkM1XHU5ODdCXHU0RUU1ICc7JyBcdTUyMDZcdTk2OTRcdTdCMjZcdTdFQzhcdTZCNjJcdTMwMDIKLSMgNC4zLjIgV2VsbC1Gb3JtZWQgUGFyc2VkIEVudGl0aWVzCi0gICAgICAgIFJlZmVyZW5jZU5vdEluT25lRW50aXR5ID0gXHU1RjE1XHU3NTI4XHU1RkM1XHU5ODdCXHU1QjhDXHU1MTY4XHU1MzA1XHU1NDJCXHU1NzI4XHU1NDBDXHU0RTAwXHU0RTJBXHU1REYyXHU4OUUzXHU2NzkwXHU1QjlFXHU0RjUzXHU1MTg1XHUzMDAyCi0gICAgICAgIEVsZW1lbnRFbnRpdHlNaXNtYXRjaCA9IFx1NTE0M1x1N0QyMCAiezB9IiBcdTVGQzVcdTk4N0JcdTRFQ0VcdTU5MzRcdTgxRjNcdTVDM0VcdTUzMDVcdTU0MkJcdTU3MjhcdTU0MENcdTRFMDBcdTRFMkFcdTVCOUVcdTRGNTNcdTUxODVcdTMwMDIKLSAgICAgICAgTWFya3VwRW50aXR5TWlzbWF0Y2g9WE1MIFx1NjU4N1x1Njg2M1x1N0VEM1x1Njc4NFx1NUZDNVx1OTg3Qlx1NEVDRVx1NTkzNFx1ODFGM1x1NUMzRVx1NTMwNVx1NTQyQlx1NTcyOFx1NTQwQ1x1NEUwMFx1NEUyQVx1NUI5RVx1NEY1M1x1NTE4NVx1MzAwMgotICAgICAgICAKLSMgTWVzc2FnZXMgY29tbW9uIHRvIERvY3VtZW50IGFuZCBEVEQKLSMgMi4yIENoYXJhY3RlcnMKLSAgICAgICAgSW52YWxpZENoYXJJbkF0dFZhbHVlID0gXHU1NzI4ICJ7MX0iIFx1NUM1RVx1NjAyN1x1NTAzQ1x1NEUyRFx1NjI3RVx1NTIzMFx1NjVFMFx1NjU0OFx1NzY4NCBYTUwgXHU1QjU3XHU3QjI2IChVbmljb2RlOiAweHsyfSksIFx1NUU3Nlx1NEUxNFx1NTE0M1x1N0QyMFx1NEUzQSAiezB9Ilx1MzAwMgotICAgICAgICBJbnZhbGlkQ2hhckluQ29tbWVudCA9IFx1NTcyOFx1NkNFOFx1OTFDQVx1NEUyRFx1NjI3RVx1NTIzMFx1NjVFMFx1NjU0OFx1NzY4NCBYTUwgXHU1QjU3XHU3QjI2IChVbmljb2RlOiAweHswfSlcdTMwMDIKLSAgICAgICAgSW52YWxpZENoYXJJblBJID0gXHU1NzI4XHU1OTA0XHU3NDA2XHU2MzA3XHU0RUU0XHU0RTJEXHU2MjdFXHU1MjMwXHU2NUUwXHU2NTQ4XHU3Njg0IFhNTCBcdTVCNTdcdTdCMjYgKFVuaWNvZGU6IDB4ezB9KVx1MzAwMgotICAgICAgICBJbnZhbGlkQ2hhckluSW50ZXJuYWxTdWJzZXQgPSBcdTU3MjggRFREIFx1NzY4NFx1NTE4NVx1OTBFOFx1NUI1MFx1OTZDNlx1NEUyRFx1NjI3RVx1NTIzMFx1NjVFMFx1NjU0OFx1NzY4NCBYTUwgXHU1QjU3XHU3QjI2IChVbmljb2RlOiAweHswfSlcdTMwMDIKLSAgICAgICAgSW52YWxpZENoYXJJblRleHREZWNsID0gXHU1NzI4XHU2NTg3XHU2NzJDXHU1OEYwXHU2NjBFXHU0RTJEXHU2MjdFXHU1MjMwXHU2NUUwXHU2NTQ4XHU3Njg0IFhNTCBcdTVCNTdcdTdCMjYgKFVuaWNvZGU6IDB4ezB9KVx1MzAwMgotIyAyLjMgQ29tbW9uIFN5bnRhY3RpYyBDb25zdHJ1Y3RzCi0gICAgICAgIFF1b3RlUmVxdWlyZWRJbkF0dFZhbHVlID0gInsxfSIgXHU1QzVFXHU2MDI3XHU1MDNDXHU1RkM1XHU5ODdCXHU0RUU1XHU1MzU1XHU1RjE1XHU1M0Y3XHU1QjU3XHU3QjI2XHU2MjE2XHU1M0NDXHU1RjE1XHU1M0Y3XHU1QjU3XHU3QjI2XHU1RjAwXHU1OTM0XHUzMDAyCi0gICAgICAgIExlc3N0aGFuSW5BdHRWYWx1ZSA9IFx1NEUwRVx1NTE0M1x1N0QyMFx1N0M3Qlx1NTc4QiAiezB9IiBcdTc2RjhcdTUxNzNcdTgwNTRcdTc2ODQgInsxfSIgXHU1QzVFXHU2MDI3XHU1MDNDXHU0RTBEXHU4MEZEXHU1MzA1XHU1NDJCICcnPCcnIFx1NUI1N1x1N0IyNlx1MzAwMgotICAgICAgICBBdHRyaWJ1dGVWYWx1ZVVudGVybWluYXRlZCA9ICJ7MX0iIFx1NUM1RVx1NjAyN1x1NTAzQ1x1NUZDNVx1OTg3Qlx1NEVFNVx1NTMzOVx1OTE0RFx1NzY4NFx1NUYxNVx1NTNGN1x1NUI1N1x1N0IyNlx1N0VEM1x1NUMzRVx1MzAwMgotIyAyLjUgQ29tbWVudHMKLSAgICAgICAgSW52YWxpZENvbW1lbnRTdGFydCA9IFx1NkNFOFx1OTFDQVx1NUZDNVx1OTg3Qlx1NEVFNSAiPCEtLSIgXHU1RjAwXHU1OTM0XHUzMDAyCi0gICAgICAgIERhc2hEYXNoSW5Db21tZW50ID0gXHU2Q0U4XHU5MUNBXHU0RTJEXHU0RTBEXHU1MTQxXHU4QkI4XHU1MUZBXHU3M0IwXHU1QjU3XHU3QjI2XHU0RTMyICItLSJcdTMwMDIKLSAgICAgICAgQ29tbWVudFVudGVybWluYXRlZCA9IFx1NkNFOFx1OTFDQVx1NUZDNVx1OTg3Qlx1NEVFNSAiLS0+IiBcdTdFRDNcdTVDM0VcdTMwMDIKLSAgICAgICAgQ09NTUVOVF9OT1RfSU5fT05FX0VOVElUWSA9IFx1NkNFOFx1OTFDQVx1NkNBMVx1NjcwOVx1NTMwNVx1NTQyQlx1NTcyOFx1NTQwQ1x1NEUwMFx1NEUyQVx1NUI5RVx1NEY1M1x1NTE4NVx1MzAwMgotIyAyLjYgUHJvY2Vzc2luZyBJbnN0cnVjdGlvbnMKLSAgICAgICAgUElUYXJnZXRSZXF1aXJlZCA9IFx1NTkwNFx1NzQwNlx1NjMwN1x1NEVFNFx1NUZDNVx1OTg3Qlx1NEVFNVx1NzZFRVx1NjgwN1x1NTQwRFx1NzlGMFx1NUYwMFx1NTkzNFx1MzAwMgotICAgICAgICBTcGFjZVJlcXVpcmVkSW5QSSA9IFx1NTcyOFx1NTkwNFx1NzQwNlx1NjMwN1x1NEVFNFx1NzZFRVx1NjgwN1x1NTQ4Q1x1NjU3MFx1NjM2RVx1NEU0Qlx1OTVGNFx1OTcwMFx1ODk4MVx1NjcwOVx1N0E3QVx1NjgzQ1x1MzAwMgotICAgICAgICBQSVVudGVybWluYXRlZCA9IFx1NTkwNFx1NzQwNlx1NjMwN1x1NEVFNFx1NUZDNVx1OTg3Qlx1NEVFNSAiPz4iIFx1N0VEM1x1NUMzRVx1MzAwMgotICAgICAgICBSZXNlcnZlZFBJVGFyZ2V0ID0gXHU0RTBEXHU1MTQxXHU4QkI4XHU2NzA5XHU1MzM5XHU5MTREICJbeFhdW21NXVtsTF0iIFx1NzY4NFx1NTkwNFx1NzQwNlx1NjMwN1x1NEVFNFx1NzZFRVx1NjgwN1x1MzAwMgotICAgICAgICBQSV9OT1RfSU5fT05FX0VOVElUWSA9IFx1NTkwNFx1NzQwNlx1NjMwN1x1NEVFNFx1NkNBMVx1NjcwOVx1NTMwNVx1NTQyQlx1NTcyOFx1NTQwQ1x1NEUwMFx1NEUyQVx1NUI5RVx1NEY1M1x1NTE4NVx1MzAwMgotIyAyLjggUHJvbG9nIGFuZCBEb2N1bWVudCBUeXBlIERlY2xhcmF0aW9uCi0gICAgICAgIFZlcnNpb25JbmZvSW52YWxpZCA9IFx1NzI0OFx1NjcyQyAiezB9IiBcdTY1RTBcdTY1NDhcdTMwMDIKLSAgICAgICAgVmVyc2lvbk5vdFN1cHBvcnRlZCA9IFx1NEUwRFx1NjUyRlx1NjMwMSBYTUwgXHU3MjQ4XHU2NzJDICJ7MH0iLCBcdTUzRUFcdTY1MkZcdTYzMDEgWE1MIDEuMFx1MzAwMgotICAgICAgICBWZXJzaW9uTm90U3VwcG9ydGVkMTEgPSBcdTRFMERcdTY1MkZcdTYzMDEgWE1MIFx1NzI0OFx1NjcyQyAiezB9IiwgXHU1M0VBXHU2NTJGXHU2MzAxIFhNTCAxLjAgXHU1NDhDIFhNTCAxLjFcdTMwMDIKLSAgICAgICAgVmVyc2lvbk1pc21hdGNoPSBcdTVCOUVcdTRGNTNcdTRFMERcdTgwRkRcdTUzMDVcdTU0MkJcdThGODNcdTlBRDhcdTcyNDhcdTY3MkNcdTc2ODRcdTUzRTZcdTRFMDBcdTRFMkFcdTVCOUVcdTRGNTNcdTMwMDIKLSMgNC4xIENoYXJhY3RlciBhbmQgRW50aXR5IFJlZmVyZW5jZXMKLSAgICAgICAgRGlnaXRSZXF1aXJlZEluQ2hhclJlZiA9IFx1NTcyOFx1NUI1N1x1N0IyNlx1NUYxNVx1NzUyOFx1NEUyRCwgXHU1MzQxXHU4RkRCXHU1MjM2XHU4ODY4XHU3OTNBXHU2NUI5XHU2Q0Q1XHU1RkM1XHU5ODdCXHU3RDI3XHU4RERGXHU1NzI4ICImIyIgXHU1NDBFXHU5NzYyXHUzMDAyCi0gICAgICAgIEhleGRpZ2l0UmVxdWlyZWRJbkNoYXJSZWYgPSBcdTU3MjhcdTVCNTdcdTdCMjZcdTVGMTVcdTc1MjhcdTRFMkQsIFx1NTM0MVx1NTE2RFx1OEZEQlx1NTIzNlx1ODg2OFx1NzkzQVx1NjVCOVx1NkNENVx1NUZDNVx1OTg3Qlx1N0QyN1x1OERERlx1NTcyOCAiJiN4IiBcdTU0MEVcdTk3NjJcdTMwMDIKLSAgICAgICAgU2VtaWNvbG9uUmVxdWlyZWRJbkNoYXJSZWYgPSBcdTVCNTdcdTdCMjZcdTVGMTVcdTc1MjhcdTVGQzVcdTk4N0JcdTRFRTUgJzsnIFx1NTIwNlx1OTY5NFx1N0IyNlx1N0VEM1x1NUMzRVx1MzAwMgotICAgICAgICBJbnZhbGlkQ2hhclJlZiA9IFx1NUI1N1x1N0IyNlx1NUYxNVx1NzUyOCAiJiN7MH0iIFx1NjYyRlx1NjVFMFx1NjU0OFx1NzY4NCBYTUwgXHU1QjU3XHU3QjI2XHUzMDAyCi0gICAgICAgIE5hbWVSZXF1aXJlZEluUmVmZXJlbmNlID0gXHU1NzI4XHU1QjlFXHU0RjUzXHU1RjE1XHU3NTI4XHU0RTJELCBcdTVCOUVcdTRGNTNcdTU0MERcdTc5RjBcdTVGQzVcdTk4N0JcdTdEMjdcdThEREZcdTU3MjggJyYnIFx1NTQwRVx1OTc2Mlx1MzAwMgotICAgICAgICBTZW1pY29sb25SZXF1aXJlZEluUmVmZXJlbmNlID0gXHU1QkY5XHU1QjlFXHU0RjUzICJ7MH0iIFx1NzY4NFx1NUYxNVx1NzUyOFx1NUZDNVx1OTg3Qlx1NEVFNSAnJzsnJyBcdTUyMDZcdTk2OTRcdTdCMjZcdTdFRDNcdTVDM0VcdTMwMDIKLSMgNC4zLjEgVGhlIFRleHQgRGVjbGFyYXRpb24KLSAgICAgICAgVGV4dERlY2xNdXN0QmVGaXJzdCA9IFx1NjU4N1x1NjcyQ1x1NThGMFx1NjYwRVx1NTNFQVx1ODBGRFx1NTFGQVx1NzNCMFx1NTcyOFx1NURGMlx1ODlFM1x1Njc5MFx1NzY4NFx1NTkxNlx1OTBFOFx1NUI5RVx1NEY1M1x1NzY4NFx1NjcwMFx1NUYwMFx1NTkzNFx1NTkwNFx1MzAwMgotICAgICAgICBFcVJlcXVpcmVkSW5UZXh0RGVjbCA9IFx1NTcyOFx1NjU4N1x1NjcyQ1x1NThGMFx1NjYwRVx1NEUyRCwgInswfSIgXHU1NDBFXHU5NzYyXHU1RkM1XHU5ODdCXHU4RERGXHU2NzA5ICcnID0gJycgXHU1QjU3XHU3QjI2XHUzMDAyCi0gICAgICAgIFF1b3RlUmVxdWlyZWRJblRleHREZWNsID0gXHU2NTg3XHU2NzJDXHU1OEYwXHU2NjBFXHU0RTJEICJ7MH0iIFx1NTQwRVx1OTc2Mlx1OERERlx1OTY4Rlx1NzY4NFx1NTAzQ1x1NUZDNVx1OTg3Qlx1NjYyRlx1NzUyOFx1NUYxNVx1NTNGN1x1NjJFQ1x1OEQ3N1x1Njc2NVx1NzY4NFx1NUI1N1x1N0IyNlx1NEUzMlx1MzAwMgotICAgICAgICBDbG9zZVF1b3RlTWlzc2luZ0luVGV4dERlY2wgPSBcdTY1ODdcdTY3MkNcdTU4RjBcdTY2MEVcdTRFMkQgInswfSIgXHU1NDBFXHU5NzYyXHU4RERGXHU5NjhGXHU3Njg0XHU1MDNDXHU3RjNBXHU1QzExXHU1M0YzXHU1RjE1XHU1M0Y3XHUzMDAyCi0gICAgICAgIFNwYWNlUmVxdWlyZWRCZWZvcmVWZXJzaW9uSW5UZXh0RGVjbCA9IFx1NTcyOFx1NjU4N1x1NjcyQ1x1NThGMFx1NjYwRVx1NEUyRFx1NzY4NFx1NzI0OFx1NjcyQ1x1NEYyQVx1NUM1RVx1NjAyN1x1NTI0RFx1OTc2Mlx1NUZDNVx1OTg3Qlx1NjcwOVx1N0E3QVx1NjgzQ1x1MzAwMgotICAgICAgICBTcGFjZVJlcXVpcmVkQmVmb3JlRW5jb2RpbmdJblRleHREZWNsID0gXHU1NzI4XHU2NTg3XHU2NzJDXHU1OEYwXHU2NjBFXHU0RTJEXHU3Njg0XHU3RjE2XHU3ODAxXHU0RjJBXHU1QzVFXHU2MDI3XHU1MjREXHU5NzYyXHU1RkM1XHU5ODdCXHU2NzA5XHU3QTdBXHU2ODNDXHUzMDAyCi0gICAgICAgIFRleHREZWNsVW50ZXJtaW5hdGVkID0gXHU2NTg3XHU2NzJDXHU1OEYwXHU2NjBFXHU1RkM1XHU5ODdCXHU0RUU1ICI/PiIgXHU3RUQzXHU1QzNFXHUzMDAyCi0gICAgICAgIEVuY29kaW5nRGVjbFJlcXVpcmVkID0gXHU2NTg3XHU2NzJDXHU1OEYwXHU2NjBFXHU0RTJEXHU5NzAwXHU4OTgxXHU3RjE2XHU3ODAxXHU1OEYwXHU2NjBFXHUzMDAyCi0gICAgICAgIE5vTW9yZVBzZXVkb0F0dHJpYnV0ZXMgPSBcdTRFMERcdTUxNDFcdThCQjhcdTRGN0ZcdTc1MjhcdTY2RjRcdTU5MUFcdTc2ODRcdTRGMkFcdTVDNUVcdTYwMjdcdTMwMDIKLSAgICAgICAgTW9yZVBzZXVkb0F0dHJpYnV0ZXMgPSBcdTVFOTRcdThCRTVcdTY3MDlcdTY2RjRcdTU5MUFcdTc2ODRcdTRGMkFcdTVDNUVcdTYwMjdcdTMwMDIKLSAgICAgICAgUHNldWRvQXR0ck5hbWVFeHBlY3RlZCA9IFx1NUU5NFx1OEJFNVx1NjcwOVx1NEYyQVx1NUM1RVx1NjAyN1x1NTQwRFx1MzAwMgotIyA0LjMuMiBXZWxsLUZvcm1lZCBQYXJzZWQgRW50aXRpZXMKLSAgICAgICAgQ29tbWVudE5vdEluT25lRW50aXR5ID0gXHU2Q0U4XHU5MUNBXHU1RkM1XHU5ODdCXHU1QjhDXHU1MTY4XHU1MzA1XHU1NDJCXHU1NzI4XHU1NDBDXHU0RTAwXHU0RTJBXHU1REYyXHU4OUUzXHU2NzkwXHU1QjlFXHU0RjUzXHU1MTg1XHUzMDAyCi0gICAgICAgIFBJTm90SW5PbmVFbnRpdHkgPSBcdTU5MDRcdTc0MDZcdTYzMDdcdTRFRTRcdTVGQzVcdTk4N0JcdTVCOENcdTUxNjhcdTUzMDVcdTU0MkJcdTU3MjhcdTU0MENcdTRFMDBcdTRFMkFcdTVERjJcdTg5RTNcdTY3OTBcdTVCOUVcdTRGNTNcdTUxODVcdTMwMDIKLSMgNC4zLjMgQ2hhcmFjdGVyIEVuY29kaW5nIGluIEVudGl0aWVzCi0gICAgICAgIEVuY29kaW5nRGVjbEludmFsaWQgPSBcdTdGMTZcdTc4MDFcdTU0MERcdTc5RjAgInswfSIgXHU2NUUwXHU2NTQ4XHUzMDAyCi0gICAgICAgIEVuY29kaW5nQnl0ZU9yZGVyVW5zdXBwb3J0ZWQgPSBcdTRFMERcdTY1MkZcdTYzMDFcdTdGMTZcdTc4MDEgInswfSIgXHU3Njg0XHU3RUQ5XHU1QjlBXHU1QjU3XHU4MjgyXHU5ODdBXHU1RThGXHUzMDAyCi0gICAgICAgIEludmFsaWRCeXRlID0gezF9IFx1NUI1N1x1ODI4Mlx1NzY4NCBVVEYtOCBcdTVFOEZcdTUyMTdcdTc2ODRcdTVCNTdcdTgyODIgezB9IFx1NjVFMFx1NjU0OFx1MzAwMgotICAgICAgICBFeHBlY3RlZEJ5dGUgPSBcdTVFOTRcdTRFM0EgezF9IFx1NUI1N1x1ODI4Mlx1NzY4NCBVVEYtOCBcdTVFOEZcdTUyMTdcdTc2ODRcdTVCNTdcdTgyODIgezB9XHUzMDAyCi0gICAgICAgIEludmFsaWRIaWdoU3Vycm9nYXRlID0gVVRGLTggXHU1RThGXHU1MjE3XHU0RTJEXHU3Njg0XHU5QUQ4XHU0RUUzXHU3NDA2XHU0RjREXHU0RTBEXHU4MEZEXHU4RDg1XHU4RkM3IDB4MTAsIFx1NEY0Nlx1NjI3RVx1NTIzMCAweHswfVx1MzAwMgotICAgICAgICBPcGVyYXRpb25Ob3RTdXBwb3J0ZWQgPSB7MX1cdThCRkJcdThGREJcdTdBMEJcdTRFMERcdTY1MkZcdTYzMDFcdTY0Q0RcdTRGNUMgInswfSJcdTMwMDIKLSAgICAgICAgSW52YWxpZEFTQ0lJID0gXHU1QjU3XHU4MjgyICJ7MH0iIFx1NEUwRFx1NjYyRiAoNyBcdTRGNEQpIEFTQ0lJIFx1NUI1N1x1N0IyNlx1OTZDNlx1NzY4NFx1NjIxMFx1NTQ1OFx1MzAwMgotICAgICAgICBDaGFyQ29udmVyc2lvbkZhaWx1cmUgPSBcdTc4NkVcdTVCOUFcdTVDNUVcdTRFOEVcdTY3RDBcdTRFMkFcdTdGMTZcdTc4MDFcdTc2ODRcdTVCOUVcdTRGNTNcdTRFMERcdTgwRkRcdTUzMDVcdTU0MkJcdTU3MjhcdThCRTVcdTdGMTZcdTc4MDFcdTRFMkRcdTk3NUVcdTZDRDVcdTc2ODRcdTVFOEZcdTUyMTdcdTMwMDIKLSAgICAgICAgCi0jIERURCBNZXNzYWdlcwotIyAyLjIgQ2hhcmFjdGVycwotICAgICAgICBJbnZhbGlkQ2hhckluRW50aXR5VmFsdWUgPSBcdTU3MjhcdTY1ODdcdTVCNTdcdTVCOUVcdTRGNTNcdTUwM0NcdTRFMkRcdTYyN0VcdTUyMzBcdTY1RTBcdTY1NDhcdTc2ODQgWE1MIFx1NUI1N1x1N0IyNiAoVW5pY29kZTogMHh7MH0pXHUzMDAyCi0gICAgICAgIEludmFsaWRDaGFySW5FeHRlcm5hbFN1YnNldCA9IFx1NTcyOCBEVEQgXHU3Njg0XHU1OTE2XHU5MEU4XHU1QjUwXHU5NkM2XHU0RTJEXHU2MjdFXHU1MjMwXHU2NUUwXHU2NTQ4XHU3Njg0IFhNTCBcdTVCNTdcdTdCMjYgKFVuaWNvZGU6IDB4ezB9KVx1MzAwMgotICAgICAgICBJbnZhbGlkQ2hhckluSWdub3JlU2VjdCA9IFx1NTcyOFx1NjM5Mlx1OTY2NFx1NzY4NFx1Njc2MVx1NEVGNlx1ODI4Mlx1NEUyRFx1NjI3RVx1NTIzMFx1NjVFMFx1NjU0OFx1NzY4NCBYTUwgXHU1QjU3XHU3QjI2IChVbmljb2RlOiAweHswfSlcdTMwMDIKLSAgICAgICAgSW52YWxpZENoYXJJblB1YmxpY0lEID0gXHU1NzI4XHU1MTZDXHU1MTcxXHU2ODA3XHU4QkM2XHU3QjI2XHU0RTJEXHU2MjdFXHU1MjMwXHU2NUUwXHU2NTQ4XHU3Njg0IFhNTCBcdTVCNTdcdTdCMjYgKFVuaWNvZGU6IDB4ezB9KVx1MzAwMgotICAgICAgICBJbnZhbGlkQ2hhckluU3lzdGVtSUQgPSBcdTU3MjhcdTdDRkJcdTdFREZcdTY4MDdcdThCQzZcdTdCMjZcdTRFMkRcdTYyN0VcdTUyMzBcdTY1RTBcdTY1NDhcdTc2ODQgWE1MIFx1NUI1N1x1N0IyNiAoVW5pY29kZTogMHh7MH0pXHUzMDAyCi0jIDIuMyBDb21tb24gU3ludGFjdGljIENvbnN0cnVjdHMKLSAgICAgICAgU3BhY2VSZXF1aXJlZEFmdGVyU1lTVEVNID0gXHU1NzI4IERPQ1RZUEUgXHU1OEYwXHU2NjBFXHU0RTJEXHU3Njg0XHU1MTczXHU5NTJFXHU1QjU3IFNZU1RFTSBcdTU0MEVcdTk3NjJcdTk3MDBcdTg5ODFcdTY3MDlcdTdBN0FcdTY4M0NcdTMwMDIKLSAgICAgICAgUXVvdGVSZXF1aXJlZEluU3lzdGVtSUQgPSBcdTdDRkJcdTdFREZcdTY4MDdcdThCQzZcdTdCMjZcdTVGQzVcdTk4N0JcdTRFRTVcdTUzNTVcdTVGMTVcdTUzRjdcdTVCNTdcdTdCMjZcdTYyMTZcdTUzQ0NcdTVGMTVcdTUzRjdcdTVCNTdcdTdCMjZcdTVGMDBcdTU5MzRcdTMwMDIKLSAgICAgICAgU3lzdGVtSURVbnRlcm1pbmF0ZWQgPSBcdTdDRkJcdTdFREZcdTY4MDdcdThCQzZcdTdCMjZcdTVGQzVcdTk4N0JcdTRFRTVcdTUzMzlcdTkxNERcdTc2ODRcdTVGMTVcdTUzRjdcdTVCNTdcdTdCMjZcdTdFRDNcdTVDM0VcdTMwMDIKLSAgICAgICAgU3BhY2VSZXF1aXJlZEFmdGVyUFVCTElDID0gXHU1NzI4IERPQ1RZUEUgXHU1OEYwXHU2NjBFXHU0RTJEXHU3Njg0XHU1MTczXHU5NTJFXHU1QjU3IFBVQkxJQyBcdTU0MEVcdTk3NjJcdTk3MDBcdTg5ODFcdTY3MDlcdTdBN0FcdTY4M0NcdTMwMDIKLSAgICAgICAgUXVvdGVSZXF1aXJlZEluUHVibGljSUQgPSBcdTUxNkNcdTUxNzFcdTY4MDdcdThCQzZcdTdCMjZcdTVGQzVcdTk4N0JcdTRFRTVcdTUzNTVcdTVGMTVcdTUzRjdcdTVCNTdcdTdCMjZcdTYyMTZcdTUzQ0NcdTVGMTVcdTUzRjdcdTVCNTdcdTdCMjZcdTVGMDBcdTU5MzRcdTMwMDIKLSAgICAgICAgUHVibGljSURVbnRlcm1pbmF0ZWQgPSBcdTUxNkNcdTUxNzFcdTY4MDdcdThCQzZcdTdCMjZcdTVGQzVcdTk4N0JcdTRFRTVcdTUzMzlcdTkxNERcdTc2ODRcdTVGMTVcdTUzRjdcdTVCNTdcdTdCMjZcdTdFRDNcdTVDM0VcdTMwMDIKLSAgICAgICAgUHViaWRDaGFySWxsZWdhbCA9IFx1NTE2Q1x1NTE3MVx1NjgwN1x1OEJDNlx1N0IyNlx1NEUyRFx1NEUwRFx1NTE0MVx1OEJCOFx1NEY3Rlx1NzUyOFx1OEJFNVx1NUI1N1x1N0IyNiAoVW5pY29kZTogMHh7MH0pXHUzMDAyCi0gICAgICAgIFNwYWNlUmVxdWlyZWRCZXR3ZWVuUHVibGljQW5kU3lzdGVtID0gXHU1NzI4IHB1YmxpY0lkIFx1NTQ4QyBzeXN0ZW1JZCBcdTRFNEJcdTk1RjRcdTk3MDBcdTg5ODFcdTY3MDlcdTdBN0FcdTY4M0NcdTMwMDIKLSMgMi44IFByb2xvZyBhbmQgRG9jdW1lbnQgVHlwZSBEZWNsYXJhdGlvbgotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX1JPT1RfRUxFTUVOVF9UWVBFX0lOX0RPQ1RZUEVERUNMID0gXHU1NzI4XHU2NTg3XHU2ODYzXHU3QzdCXHU1NzhCXHU1OEYwXHU2NjBFXHU0RTJEXHU3Njg0ICI8IURPQ1RZUEUiIFx1NTQwRVx1OTc2Mlx1OTcwMFx1ODk4MVx1NjcwOVx1N0E3QVx1NjgzQ1x1MzAwMgotICAgICAgICBNU0dfUk9PVF9FTEVNRU5UX1RZUEVfUkVRVUlSRUQgPSBcdTU3MjhcdTY1ODdcdTY4NjNcdTdDN0JcdTU3OEJcdTU4RjBcdTY2MEVcdTRFMkQsIFx1NjgzOVx1NTE0M1x1N0QyMFx1N0M3Qlx1NTc4Qlx1NUZDNVx1OTg3Qlx1NTFGQVx1NzNCMFx1NTcyOCAiPCFET0NUWVBFIiBcdTU0MEVcdTk3NjJcdTMwMDIKLSAgICAgICAgRG9jdHlwZWRlY2xVbnRlcm1pbmF0ZWQgPSBcdTY4MzlcdTUxNDNcdTdEMjBcdTdDN0JcdTU3OEIgInswfSIgXHU3Njg0XHU2NTg3XHU2ODYzXHU3QzdCXHU1NzhCXHU1OEYwXHU2NjBFXHU1RkM1XHU5ODdCXHU0RUU1ICcnPicnIFx1N0VEM1x1NUMzRVx1MzAwMgotICAgICAgICBEb2N0eXBlZGVjbE5vdENsb3NlZCA9IFx1NjgzOVx1NTE0M1x1N0QyMFx1N0M3Qlx1NTc4QiAiezB9IiBcdTc2ODRcdTY1ODdcdTY4NjNcdTdDN0JcdTU3OEJcdTU4RjBcdTY2MEVcdTVGQzVcdTk4N0JcdTRFRTUgJyddJycgXHU3RUQzXHU1QzNFXHUzMDAyCi0gICAgICAgIFBFUmVmZXJlbmNlV2l0aGluTWFya3VwID0gXHU1M0MyXHU2NTcwXHU1QjlFXHU0RjUzXHU1RjE1XHU3NTI4ICIlezB9OyIgXHU0RTBEXHU4MEZEXHU1MUZBXHU3M0IwXHU1NzI4IERURCBcdTc2ODRcdTUxODVcdTkwRThcdTVCNTBcdTk2QzZcdTRFMkRcdTc2ODRcdTY4MDdcdThCQjBcdTUxODVcdTMwMDIKLSAgICAgICAgTVNHX01BUktVUF9OT1RfUkVDT0dOSVpFRF9JTl9EVEQgPSBcdTY1ODdcdTY4NjNcdTdDN0JcdTU3OEJcdTU4RjBcdTY2MEVcdTUzMDVcdTU0MkJcdTYyMTZcdTYzMDdcdTU0MTFcdTc2ODRcdTY4MDdcdThCQjBcdTU4RjBcdTY2MEVcdTVGQzVcdTk4N0JcdTY4M0NcdTVGMEZcdTZCNjNcdTc4NkVcdTMwMDIKLSMgMi4xMCBXaGl0ZSBTcGFjZSBIYW5kbGluZwotICAgICAgICBNU0dfWE1MX1NQQUNFX0RFQ0xBUkFUSU9OX0lMTEVHQUwgPSAieG1sOnNwYWNlIiBcdTc2ODRcdTVDNUVcdTYwMjdcdTU4RjBcdTY2MEVcdTVGQzVcdTk4N0JcdTYzMDdcdTVCOUFcdTRFM0FcdTY3OUFcdTRFM0VcdTdDN0JcdTU3OEIsIFx1NUI4M1x1NzY4NFx1NTNFRlx1ODBGRFx1NTAzQ1x1NTNFQVx1NjcwOSAiZGVmYXVsdCIgXHU1NDhDICJwcmVzZXJ2ZSJcdTMwMDIKLSMgMy4yIEVsZW1lbnQgVHlwZSBEZWNsYXJhdGlvbnMKLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9FTEVNRU5UX1RZUEVfSU5fRUxFTUVOVERFQ0wgPSBcdTU3MjhcdTUxNDNcdTdEMjBcdTdDN0JcdTU3OEJcdTU4RjBcdTY2MEVcdTRFMkRcdTc2ODQgIjwhRUxFTUVOVCIgXHU1NDBFXHU5NzYyXHU5NzAwXHU4OTgxXHU2NzA5XHU3QTdBXHU2ODNDXHUzMDAyCi0gICAgICAgIE1TR19FTEVNRU5UX1RZUEVfUkVRVUlSRURfSU5fRUxFTUVOVERFQ0wgPSBcdTUxNDNcdTdEMjBcdTdDN0JcdTU3OEJcdTU4RjBcdTY2MEVcdTRFMkRcdTk3MDBcdTg5ODFcdTY3MDlcdTUxNDNcdTdEMjBcdTdDN0JcdTU3OEJcdTMwMDIKLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9DT05URU5UU1BFQ19JTl9FTEVNRU5UREVDTCA9IFx1NTcyOFx1NTE0M1x1N0QyMFx1N0M3Qlx1NTc4Qlx1NThGMFx1NjYwRVx1NEUyRFx1NzY4NFx1NTE0M1x1N0QyMFx1N0M3Qlx1NTc4QiAiezB9IiBcdTU0MEVcdTk3NjJcdTk3MDBcdTg5ODFcdTY3MDlcdTdBN0FcdTY4M0NcdTMwMDIKLSAgICAgICAgTVNHX0NPTlRFTlRTUEVDX1JFUVVJUkVEX0lOX0VMRU1FTlRERUNMID0gXHU1NzI4XHU1MTQzXHU3RDIwXHU3QzdCXHU1NzhCXHU1OEYwXHU2NjBFXHU0RTJEXHU3Njg0XHU1MTQzXHU3RDIwXHU3QzdCXHU1NzhCICJ7MH0iIFx1NTQwRVx1OTc2Mlx1OTcwMFx1ODk4MVx1NjcwOVx1N0VBNlx1Njc1Rlx1Njc2MVx1NEVGNlx1MzAwMgotICAgICAgICBFbGVtZW50RGVjbFVudGVybWluYXRlZCA9IFx1NTE0M1x1N0QyMFx1N0M3Qlx1NTc4QiAiezB9IiBcdTc2ODRcdTU4RjBcdTY2MEVcdTVGQzVcdTk4N0JcdTRFRTUgJyc+JycgXHU3RUQzXHU1QzNFXHUzMDAyCi0jIDMuMi4xIEVsZW1lbnQgQ29udGVudAotICAgICAgICBNU0dfT1BFTl9QQVJFTl9PUl9FTEVNRU5UX1RZUEVfUkVRVUlSRURfSU5fQ0hJTERSRU4gPSBcdTU3MjhcdTUxNDNcdTdEMjBcdTdDN0JcdTU3OEIgInswfSIgXHU3Njg0XHU1OEYwXHU2NjBFXHU0RTJEXHU5NzAwXHU4OTgxXHU2NzA5ICcnKCcnIFx1NUI1N1x1N0IyNlx1NjIxNlx1NTE0M1x1N0QyMFx1N0M3Qlx1NTc4Qlx1MzAwMgotICAgICAgICBNU0dfQ0xPU0VfUEFSRU5fUkVRVUlSRURfSU5fQ0hJTERSRU4gPSBcdTU3MjhcdTUxNDNcdTdEMjBcdTdDN0JcdTU3OEIgInswfSIgXHU3Njg0XHU1OEYwXHU2NjBFXHU0RTJEXHU5NzAwXHU4OTgxXHU2NzA5ICcnKScnXHUzMDAyCi0jIDMuMi4yIE1peGVkIENvbnRlbnQKLSAgICAgICAgTVNHX0VMRU1FTlRfVFlQRV9SRVFVSVJFRF9JTl9NSVhFRF9DT05URU5UID0gXHU1NzI4XHU1MTQzXHU3RDIwXHU3QzdCXHU1NzhCICJ7MH0iIFx1NzY4NFx1NThGMFx1NjYwRVx1NEUyRFx1OTcwMFx1ODk4MVx1NjcwOVx1NTE0M1x1N0QyMFx1N0M3Qlx1NTc4Qlx1MzAwMgotICAgICAgICBNU0dfQ0xPU0VfUEFSRU5fUkVRVUlSRURfSU5fTUlYRUQgPSBcdTU3MjhcdTUxNDNcdTdEMjBcdTdDN0JcdTU3OEIgInswfSIgXHU3Njg0XHU1OEYwXHU2NjBFXHU0RTJEXHU5NzAwXHU4OTgxXHU2NzA5ICcnKScnXHUzMDAyCi0gICAgICAgIE1peGVkQ29udGVudFVudGVybWluYXRlZCA9IFx1NUY1M1x1NUI1MFx1NTE0M1x1N0QyMFx1N0M3Qlx1NTc4Qlx1NTNEN1x1N0VBNlx1Njc1Rlx1NjVGNiwgXHU2REY3XHU1NDA4XHU1MTg1XHU1QkI5XHU2QTIxXHU1NzhCICJ7MH0iIFx1NUZDNVx1OTg3Qlx1NEVFNSAiKSoiIFx1N0VEM1x1NUMzRVx1MzAwMgotIyAzLjMgQXR0cmlidXRlLUxpc3QgRGVjbGFyYXRpb25zCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfRUxFTUVOVF9UWVBFX0lOX0FUVExJU1RERUNMID0gXHU1NzI4XHU1QzVFXHU2MDI3XHU1MjE3XHU4ODY4XHU1OEYwXHU2NjBFXHU0RTJEXHU3Njg0ICI8IUFUVExJU1QiIFx1NTQwRVx1OTc2Mlx1OTcwMFx1ODk4MVx1NjcwOVx1N0E3QVx1NjgzQ1x1MzAwMgotICAgICAgICBNU0dfRUxFTUVOVF9UWVBFX1JFUVVJUkVEX0lOX0FUVExJU1RERUNMID0gXHU1QzVFXHU2MDI3XHU1MjE3XHU4ODY4XHU1OEYwXHU2NjBFXHU0RTJEXHU5NzAwXHU4OTgxXHU2NzA5XHU1MTQzXHU3RDIwXHU3QzdCXHU1NzhCXHUzMDAyCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfQVRUUklCVVRFX05BTUVfSU5fQVRUREVGID0gXHU1NzI4XHU1MTQzXHU3RDIwICJ7MH0iIFx1NzY4NFx1NUM1RVx1NjAyN1x1NTIxN1x1ODg2OFx1NThGMFx1NjYwRVx1NEUyRFx1NzY4NFx1NUM1RVx1NjAyN1x1NTQwRFx1NTI0RFx1OTc2Mlx1OTcwMFx1ODk4MVx1NjcwOVx1N0E3QVx1NjgzQ1x1MzAwMgotICAgICAgICBBdHROYW1lUmVxdWlyZWRJbkF0dERlZiA9IFx1NTcyOFx1NTE0M1x1N0QyMCAiezB9IiBcdTc2ODRcdTVDNUVcdTYwMjdcdTUyMTdcdTg4NjhcdTU4RjBcdTY2MEVcdTRFMkRcdTVGQzVcdTk4N0JcdTYzMDdcdTVCOUFcdTVDNUVcdTYwMjdcdTU0MERcdTMwMDIKLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9BVFRUWVBFX0lOX0FUVERFRiA9IFx1NTcyOFx1NTE0M1x1N0QyMCAiezB9IiBcdTc2ODRcdTVDNUVcdTYwMjcgInsxfSIgXHU3Njg0XHU1OEYwXHU2NjBFXHU0RTJELCBcdTU3MjhcdTVDNUVcdTYwMjdcdTdDN0JcdTU3OEJcdTUyNERcdTk3NjJcdTk3MDBcdTg5ODFcdTY3MDlcdTdBN0FcdTY4M0NcdTMwMDIKLSAgICAgICAgQXR0VHlwZVJlcXVpcmVkSW5BdHREZWYgPSBcdTU3MjhcdTUxNDNcdTdEMjAgInswfSIgXHU3Njg0XHU1QzVFXHU2MDI3ICJ7MX0iIFx1NzY4NFx1NThGMFx1NjYwRVx1NEUyRFx1OTcwMFx1ODk4MVx1NjcwOVx1NUM1RVx1NjAyN1x1N0M3Qlx1NTc4Qlx1MzAwMgotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX0RFRkFVTFRERUNMX0lOX0FUVERFRiA9IFx1NTcyOFx1NTE0M1x1N0QyMCAiezB9IiBcdTc2ODRcdTVDNUVcdTYwMjcgInsxfSIgXHU3Njg0XHU1OEYwXHU2NjBFXHU0RTJELCBcdTU3MjhcdTVDNUVcdTYwMjdcdTlFRDhcdThCQTRcdTUwM0NcdTUyNERcdTk3NjJcdTk3MDBcdTg5ODFcdTY3MDlcdTdBN0FcdTY4M0NcdTMwMDIKLSAgICAgICAgTVNHX0RVUExJQ0FURV9BVFRSSUJVVEVfREVGSU5JVElPTiA9IFx1NEUzQVx1NjMwN1x1NUI5QVx1NTE0M1x1N0QyMCAiezB9IiBcdTc2ODRcdTU0MENcdTRFMDBcdTVDNUVcdTYwMjcgInsxfSIgXHU2M0QwXHU0RjlCXHU0RTg2XHU1OTFBXHU0RTJBXHU1QzVFXHU2MDI3XHU1QjlBXHU0RTQ5XHUzMDAyCi0jIDMuMy4xIEF0dHJpYnV0ZSBUeXBlcwotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQUZURVJfTk9UQVRJT05fSU5fTk9UQVRJT05UWVBFID0gXHU1NzI4ICJ7MX0iIFx1NUM1RVx1NjAyN1x1NThGMFx1NjYwRVx1NEUyRCwgXHU3QTdBXHU2ODNDXHU1RkM1XHU5ODdCXHU1MUZBXHU3M0IwXHU1NzI4ICJOT1RBVElPTiIgXHU1NDBFXHU5NzYyXHUzMDAyCi0gICAgICAgIE1TR19PUEVOX1BBUkVOX1JFUVVJUkVEX0lOX05PVEFUSU9OVFlQRSA9IFx1NTcyOCAiezF9IiBcdTVDNUVcdTYwMjdcdTU4RjBcdTY2MEVcdTRFMkQsICJOT1RBVElPTiIgXHU1NDBFXHU5NzYyXHU1RkM1XHU5ODdCXHU4RERGXHU2NzA5ICcnKCcnIFx1NUI1N1x1N0IyNlx1MzAwMgotICAgICAgICBNU0dfTkFNRV9SRVFVSVJFRF9JTl9OT1RBVElPTlRZUEUgPSBcdTU3MjggInsxfSIgXHU1QzVFXHU2MDI3XHU1OEYwXHU2NjBFXHU3Njg0XHU4QkIwXHU1M0Y3XHU3QzdCXHU1NzhCXHU1MjE3XHU4ODY4XHU0RTJEXHU5NzAwXHU4OTgxXHU2NzA5XHU4QkIwXHU1M0Y3XHU1NDBEXHU3OUYwXHUzMDAyCi0gICAgICAgIE5vdGF0aW9uVHlwZVVudGVybWluYXRlZCA9IFx1NTcyOCAiezF9IiBcdTVDNUVcdTYwMjdcdTU4RjBcdTY2MEVcdTRFMkQsIFx1OEJCMFx1NTNGN1x1N0M3Qlx1NTc4Qlx1NTIxN1x1ODg2OFx1NUZDNVx1OTg3Qlx1NEVFNSAnJyknJyBcdTdFRDNcdTVDM0VcdTMwMDIKLSAgICAgICAgTVNHX05NVE9LRU5fUkVRVUlSRURfSU5fRU5VTUVSQVRJT04gPSBcdTU3MjggInsxfSIgXHU1QzVFXHU2MDI3XHU1OEYwXHU2NjBFXHU3Njg0XHU2NzlBXHU0RTNFXHU3QzdCXHU1NzhCXHU1MjE3XHU4ODY4XHU0RTJEXHU5NzAwXHU4OTgxXHU2NzA5XHU1NDBEXHU3OUYwXHU2ODA3XHU4QkIwXHUzMDAyCi0gICAgICAgIEVudW1lcmF0aW9uVW50ZXJtaW5hdGVkID0gXHU1NzI4ICJ7MX0iIFx1NUM1RVx1NjAyN1x1NThGMFx1NjYwRVx1NEUyRCwgXHU2NzlBXHU0RTNFXHU3QzdCXHU1NzhCXHU1MjE3XHU4ODY4XHU1RkM1XHU5ODdCXHU0RUU1ICcnKScnIFx1N0VEM1x1NUMzRVx1MzAwMgotICAgICAgICBNU0dfRElTVElOQ1RfVE9LRU5TX0lOX0VOVU1FUkFUSU9OID0gXHU1NzI4XHU1MTQzXHU3RDIwICJ7MH0iIFx1NzY4NFx1NUM1RVx1NjAyNyAiezJ9IiBcdTc2ODRcdTU4RjBcdTY2MEVcdTRFMkQsIFx1Njc5QVx1NEUzRVx1NTAzQyAiezF9IiBcdTYzMDdcdTVCOUFcdTRFODZcdTU5MUFcdTZCMjFcdTMwMDJcdTUzNTVcdTRFMkFcdTY3OUFcdTRFM0VcdTVDNUVcdTYwMjdcdTU4RjBcdTY2MEVcdTRFMkRcdTc2ODQgTk1UT0tFTlMgXHU1RkM1XHU5ODdCXHU1MTY4XHU5MEU4XHU0RTBEXHU3NkY4XHU1NDBDXHUzMDAyCi0gICAgICAgIE1TR19ESVNUSU5DVF9OT1RBVElPTl9JTl9FTlVNRVJBVElPTiA9IFx1NTcyOFx1NTE0M1x1N0QyMCAiezB9IiBcdTc2ODRcdTVDNUVcdTYwMjcgInsyfSIgXHU3Njg0XHU1OEYwXHU2NjBFXHU0RTJELCBcdTY3OUFcdTRFM0VcdTUwM0MgInsxfSIgXHU2MzA3XHU1QjlBXHU0RTg2XHU1OTFBXHU2QjIxXHUzMDAyXHU1MzU1XHU0RTJBIE5vdGF0aW9uVHlwZSBcdTVDNUVcdTYwMjdcdTU4RjBcdTY2MEVcdTRFMkRcdTc2ODQgTk9UQVRJT04gXHU1NDBEXHU3OUYwXHU1RkM1XHU5ODdCXHU1MTY4XHU5MEU4XHU0RTBEXHU3NkY4XHU1NDBDXHUzMDAyCi0jIDMuMy4yIEF0dHJpYnV0ZSBEZWZhdWx0cwotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQUZURVJfRklYRURfSU5fREVGQVVMVERFQ0wgPSBcdTU3MjggInsxfSIgXHU1QzVFXHU2MDI3XHU1OEYwXHU2NjBFXHU0RTJELCBcdTdBN0FcdTY4M0NcdTVGQzVcdTk4N0JcdTUxRkFcdTczQjBcdTU3MjggIkZJWEVEIiBcdTU0MEVcdTk3NjJcdTMwMDIKLSMgMy40IENvbmRpdGlvbmFsIFNlY3Rpb25zCi0gICAgICAgIEluY2x1ZGVTZWN0VW50ZXJtaW5hdGVkID0gXHU1MzA1XHU1NDJCXHU3Njg0XHU2NzYxXHU0RUY2XHU4MjgyXHU1RkM1XHU5ODdCXHU0RUU1ICJdXT4iIFx1N0VEM1x1NUMzRVx1MzAwMgotICAgICAgICBJZ25vcmVTZWN0VW50ZXJtaW5hdGVkID0gXHU2MzkyXHU5NjY0XHU3Njg0XHU2NzYxXHU0RUY2XHU4MjgyXHU1RkM1XHU5ODdCXHU0RUU1ICJdXT4iIFx1N0VEM1x1NUMzRVx1MzAwMgotIyA0LjEgQ2hhcmFjdGVyIGFuZCBFbnRpdHkgUmVmZXJlbmNlcwotICAgICAgICBOYW1lUmVxdWlyZWRJblBFUmVmZXJlbmNlID0gXHU1NzI4XHU1M0MyXHU2NTcwXHU1QjlFXHU0RjUzXHU1RjE1XHU3NTI4XHU0RTJELCBcdTVCOUVcdTRGNTNcdTU0MERcdTc5RjBcdTVGQzVcdTk4N0JcdTdEMjdcdThEREZcdTU3MjggJyUnIFx1NTQwRVx1OTc2Mlx1MzAwMgotICAgICAgICBTZW1pY29sb25SZXF1aXJlZEluUEVSZWZlcmVuY2UgPSBcdTUzQzJcdTY1NzBcdTVCOUVcdTRGNTNcdTVGMTVcdTc1MjggIiV7MH07IiBcdTVGQzVcdTk4N0JcdTRFRTUgJyc7JycgXHU1MjA2XHU5Njk0XHU3QjI2XHU3RUQzXHU1QzNFXHUzMDAyCi0jIDQuMiBFbnRpdHkgRGVjbGFyYXRpb25zCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfRU5USVRZX05BTUVfSU5fRU5USVRZREVDTCA9IFx1NTcyOFx1NUI5RVx1NEY1M1x1NThGMFx1NjYwRVx1NEUyRFx1NzY4NCAiPCFFTlRJVFkiIFx1NTQwRVx1OTc2Mlx1OTcwMFx1ODk4MVx1NjcwOVx1N0E3QVx1NjgzQ1x1MzAwMgotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX1BFUkNFTlRfSU5fUEVERUNMID0gXHU1NzI4XHU1M0MyXHU2NTcwXHU1QjlFXHU0RjUzXHU1OEYwXHU2NjBFXHU0RTJEXHU3Njg0ICI8IUVOVElUWSIgXHU1NDhDICclJyBcdTVCNTdcdTdCMjZcdTRFNEJcdTk1RjRcdTk3MDBcdTg5ODFcdTY3MDlcdTdBN0FcdTY4M0NcdTMwMDIKLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9FTlRJVFlfTkFNRV9JTl9QRURFQ0wgPSBcdTU3MjhcdTUzQzJcdTY1NzBcdTVCOUVcdTRGNTNcdTU4RjBcdTY2MEVcdTRFMkRcdTc2ODQgJyUnIFx1NTQ4Q1x1NUI5RVx1NEY1M1x1NTQwRFx1NzlGMFx1NEU0Qlx1OTVGNFx1OTcwMFx1ODk4MVx1NjcwOVx1N0E3QVx1NjgzQ1x1MzAwMgotICAgICAgICBNU0dfRU5USVRZX05BTUVfUkVRVUlSRURfSU5fRU5USVRZREVDTCA9IFx1NUI5RVx1NEY1M1x1NThGMFx1NjYwRVx1NEUyRFx1OTcwMFx1ODk4MVx1NjcwOVx1NUI5RVx1NEY1M1x1NTQwRFx1NzlGMFx1MzAwMgotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQUZURVJfRU5USVRZX05BTUVfSU5fRU5USVRZREVDTCA9IFx1NTcyOFx1NUI5RVx1NEY1M1x1NThGMFx1NjYwRVx1NEUyRFx1NzY4NFx1NUI5RVx1NEY1M1x1NTQwRFx1NzlGMCAiezB9IiBcdTU0OENcdTVCOUFcdTRFNDlcdTRFNEJcdTk1RjRcdTk3MDBcdTg5ODFcdTY3MDlcdTdBN0FcdTY4M0NcdTMwMDIKLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9OT1RBVElPTl9OQU1FX0lOX1VOUEFSU0VEX0VOVElUWURFQ0wgPSBcdTU3MjhcdTVCOUVcdTRGNTMgInswfSIgXHU3Njg0XHU1OEYwXHU2NjBFXHU0RTJEXHU3Njg0ICJOREFUQSIgXHU1NDhDXHU4QkIwXHU1M0Y3XHU1NDBEXHU3OUYwXHU0RTRCXHU5NUY0XHU5NzAwXHU4OTgxXHU2NzA5XHU3QTdBXHU2ODNDXHUzMDAyCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfTkRBVEFfSU5fVU5QQVJTRURfRU5USVRZREVDTCA9IFx1NTcyOFx1NUI5RVx1NEY1MyAiezB9IiBcdTc2ODRcdTU4RjBcdTY2MEVcdTRFMkRcdTc2ODQgIk5EQVRBIiBcdTUyNERcdTk3NjJcdTk3MDBcdTg5ODFcdTY3MDlcdTdBN0FcdTY4M0NcdTMwMDIKLSAgICAgICAgTVNHX05PVEFUSU9OX05BTUVfUkVRVUlSRURfRk9SX1VOUEFSU0VEX0VOVElUWURFQ0wgPSBcdTU3MjhcdTVCOUVcdTRGNTMgInswfSIgXHU3Njg0XHU1OEYwXHU2NjBFXHU0RTJEXHU3Njg0ICJOREFUQSIgXHU1NDBFXHU5NzYyXHU5NzAwXHU4OTgxXHU2NzA5XHU4QkIwXHU1M0Y3XHU1NDBEXHU3OUYwXHUzMDAyCi0gICAgICAgIEVudGl0eURlY2xVbnRlcm1pbmF0ZWQgPSBcdTVCOUVcdTRGNTMgInswfSIgXHU3Njg0XHU1OEYwXHU2NjBFXHU1RkM1XHU5ODdCXHU0RUU1ICcnPicnIFx1N0VEM1x1NUMzRVx1MzAwMgotCU1TR19EVVBMSUNBVEVfRU5USVRZX0RFRklOSVRJT04gPSBcdTVCOUVcdTRGNTMgInswfSIgXHU1OEYwXHU2NjBFXHU0RTg2XHU1OTFBXHU2QjIxXHUzMDAyICAgICAgICAKLSMgNC4yLjIgRXh0ZXJuYWwgRW50aXRpZXMKLSAgICAgICAgRXh0ZXJuYWxJRFJlcXVpcmVkID0gXHU1OTE2XHU5MEU4XHU1QjlFXHU0RjUzXHU1OEYwXHU2NjBFXHU1RkM1XHU5ODdCXHU0RUU1ICJTWVNURU0iIFx1NjIxNiAiUFVCTElDIiBcdTVGMDBcdTU5MzRcdTMwMDIKLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9QVUJJRExJVEVSQUxfSU5fRVhURVJOQUxJRCA9IFx1NTcyOCAiUFVCTElDIiBcdTU0OENcdTUxNkNcdTUxNzFcdTY4MDdcdThCQzZcdTdCMjZcdTRFNEJcdTk1RjRcdTk3MDBcdTg5ODFcdTY3MDlcdTdBN0FcdTY4M0NcdTMwMDIKLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0FGVEVSX1BVQklETElURVJBTF9JTl9FWFRFUk5BTElEID0gXHU1NzI4XHU1MTZDXHU1MTcxXHU2ODA3XHU4QkM2XHU3QjI2XHU1NDhDXHU3Q0ZCXHU3RURGXHU2ODA3XHU4QkM2XHU3QjI2XHU0RTRCXHU5NUY0XHU5NzAwXHU4OTgxXHU2NzA5XHU3QTdBXHU2ODNDXHUzMDAyCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfU1lTVEVNTElURVJBTF9JTl9FWFRFUk5BTElEID0gXHU1NzI4ICJTWVNURU0iIFx1NTQ4Q1x1N0NGQlx1N0VERlx1NjgwN1x1OEJDNlx1N0IyNlx1NEU0Qlx1OTVGNFx1OTcwMFx1ODk4MVx1NjcwOVx1N0E3QVx1NjgzQ1x1MzAwMgotICAgICAgICBNU0dfVVJJX0ZSQUdNRU5UX0lOX1NZU1RFTUlEID0gXHU3MjQ3XHU2QkI1XHU2ODA3XHU4QkM2XHU3QjI2XHU0RTBEXHU4MEZEXHU2MzA3XHU1QjlBXHU0RTNBXHU3Q0ZCXHU3RURGXHU2ODA3XHU4QkM2XHU3QjI2ICJ7MH0iIFx1NzY4NFx1NEUwMFx1OTBFOFx1NTIwNlx1MzAwMgotIyA0LjcgTm90YXRpb24gRGVjbGFyYXRpb25zCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfTk9UQVRJT05fTkFNRV9JTl9OT1RBVElPTkRFQ0wgPSBcdTU3MjhcdThCQjBcdTUzRjdcdTU4RjBcdTY2MEVcdTRFMkRcdTc2ODQgIjwhTk9UQVRJT04iIFx1NTQwRVx1OTc2Mlx1OTcwMFx1ODk4MVx1NjcwOVx1N0E3QVx1NjgzQ1x1MzAwMgotICAgICAgICBNU0dfTk9UQVRJT05fTkFNRV9SRVFVSVJFRF9JTl9OT1RBVElPTkRFQ0wgPSBcdThCQjBcdTUzRjdcdTU4RjBcdTY2MEVcdTRFMkRcdTk3MDBcdTg5ODFcdTY3MDlcdThCQjBcdTUzRjdcdTU0MERcdTc5RjBcdTMwMDIKLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0FGVEVSX05PVEFUSU9OX05BTUVfSU5fTk9UQVRJT05ERUNMID0gXHU1NzI4XHU4QkIwXHU1M0Y3XHU1OEYwXHU2NjBFXHU0RTJEXHU3Njg0XHU4QkIwXHU1M0Y3XHU1NDBEXHU3OUYwICJ7MH0iIFx1NTQwRVx1OTc2Mlx1OTcwMFx1ODk4MVx1NjcwOVx1N0E3QVx1NjgzQ1x1MzAwMgotICAgICAgICBFeHRlcm5hbElEb3JQdWJsaWNJRFJlcXVpcmVkID0gXHU4QkIwXHU1M0Y3ICJ7MH0iIFx1NzY4NFx1NThGMFx1NjYwRVx1NUZDNVx1OTg3Qlx1NTMwNVx1NTQyQlx1N0NGQlx1N0VERlx1NjgwN1x1OEJDNlx1N0IyNlx1NjIxNlx1NTE2Q1x1NTE3MVx1NjgwN1x1OEJDNlx1N0IyNlx1MzAwMgotICAgICAgICBOb3RhdGlvbkRlY2xVbnRlcm1pbmF0ZWQgPSBcdThCQjBcdTUzRjcgInswfSIgXHU3Njg0XHU1OEYwXHU2NjBFXHU1RkM1XHU5ODdCXHU0RUU1ICcnPicnIFx1N0VEM1x1NUMzRVx1MzAwMgotICAgICAgICAKLSMgVmFsaWRhdGlvbiBtZXNzYWdlcwotICAgICAgICBEdXBsaWNhdGVUeXBlSW5NaXhlZENvbnRlbnQgPSBcdTU3MjhcdTUxNDNcdTdEMjBcdTU4RjBcdTY2MEUgInswfSIgXHU3Njg0XHU1MTg1XHU1QkI5XHU2QTIxXHU1NzhCXHU0RTJEXHU1REYyXHU3RUNGXHU2MzA3XHU1QjlBXHU0RTg2XHU1MTQzXHU3RDIwXHU3QzdCXHU1NzhCICJ7MX0iXHUzMDAyCi0gICAgICAgIEVOVElUSUVTSW52YWxpZCA9IFx1N0M3Qlx1NTc4Qlx1NEUzQSBFTlRJVElFUyBcdTc2ODRcdTVDNUVcdTYwMjdcdTUwM0MgInsxfSIgXHU1RkM1XHU5ODdCXHU2NjJGXHU0RTAwXHU0RTJBXHU2MjE2XHU1OTFBXHU0RTJBXHU2NzJBXHU4OUUzXHU2NzkwXHU1QjlFXHU0RjUzXHU3Njg0XHU1NDBEXHU3OUYwXHUzMDAyCi0gICAgICAgIEVOVElUWUludmFsaWQgPSBcdTdDN0JcdTU3OEJcdTRFM0EgRU5USVRZIFx1NzY4NFx1NUM1RVx1NjAyN1x1NTAzQyAiezF9IiBcdTVGQzVcdTk4N0JcdTY2MkZcdTY3MkFcdTg5RTNcdTY3OTBcdTVCOUVcdTRGNTNcdTc2ODRcdTU0MERcdTc5RjBcdTMwMDIKLSAgICAgICAgSUREZWZhdWx0VHlwZUludmFsaWQgPSBJRCBcdTVDNUVcdTYwMjcgInswfSIgXHU1RkM1XHU5ODdCXHU1MTc3XHU2NzA5XHU1REYyXHU1OEYwXHU2NjBFXHU3Njg0XHU5RUQ4XHU4QkE0XHU1MDNDICIjSU1QTElFRCIgXHU2MjE2ICIjUkVRVUlSRUQiXHUzMDAyCi0gICAgICAgIElESW52YWxpZCA9IFx1N0M3Qlx1NTc4Qlx1NEUzQSBJRCBcdTc2ODRcdTVDNUVcdTYwMjdcdTUwM0MgInswfSIgXHU1RkM1XHU5ODdCXHU2NjJGXHU1NDBEXHU3OUYwXHUzMDAyCi0gICAgICAgIElESW52YWxpZFdpdGhOYW1lc3BhY2VzID0gXHU1NDJGXHU3NTI4XHU1NDBEXHU3OUYwXHU3QTdBXHU5NUY0XHU2NUY2LCBcdTdDN0JcdTU3OEJcdTRFM0EgSUQgXHU3Njg0XHU1QzVFXHU2MDI3XHU1MDNDICJ7MH0iIFx1NUZDNVx1OTg3Qlx1NjYyRiBOQ05hbWVcdTMwMDIKLSAgICAgICAgSUROb3RVbmlxdWUgPSBcdTdDN0JcdTU3OEJcdTRFM0EgSUQgXHU3Njg0XHU1QzVFXHU2MDI3XHU1MDNDICJ7MH0iIFx1NTcyOFx1NjU4N1x1Njg2M1x1NTE4NVx1NUZDNVx1OTg3Qlx1NjYyRlx1NTUyRlx1NEUwMFx1NzY4NFx1MzAwMgotICAgICAgICBJRFJFRkludmFsaWQgPSBcdTdDN0JcdTU3OEJcdTRFM0EgSURSRUYgXHU3Njg0XHU1QzVFXHU2MDI3XHU1MDNDICJ7MH0iIFx1NUZDNVx1OTg3Qlx1NjYyRlx1NTQwRFx1NzlGMFx1MzAwMgotICAgICAgICBJRFJFRkludmFsaWRXaXRoTmFtZXNwYWNlcyA9IFx1NTQyRlx1NzUyOFx1NTQwRFx1NzlGMFx1N0E3QVx1OTVGNFx1NjVGNiwgXHU3QzdCXHU1NzhCXHU0RTNBIElEUkVGIFx1NzY4NFx1NUM1RVx1NjAyN1x1NTAzQyAiezB9IiBcdTVGQzVcdTk4N0JcdTY2MkYgTkNOYW1lXHUzMDAyCi0gICAgICAgIElEUkVGU0ludmFsaWQgPSBcdTdDN0JcdTU3OEJcdTRFM0EgSURSRUZTIFx1NzY4NFx1NUM1RVx1NjAyN1x1NTAzQyAiezB9IiBcdTVGQzVcdTk4N0JcdTY2MkZcdTRFMDBcdTRFMkFcdTYyMTZcdTU5MUFcdTRFMkFcdTU0MERcdTc5RjBcdTMwMDIKLSAgICAgICAgSUxMX0ZPUk1FRF9QQVJBTUVURVJfRU5USVRZX1dIRU5fVVNFRF9JTl9ERUNMID0gXHU1RjUzXHU1QjlFXHU0RjUzXHU1RjE1XHU3NTI4XHU3NTI4XHU0RjVDXHU1QjhDXHU2NTc0XHU1OEYwXHU2NjBFXHU2NUY2LCBcdTUzQzJcdTY1NzBcdTVCOUVcdTRGNTMgInswfSIgXHU3Njg0XHU2NkZGXHU2MzYyXHU2NTg3XHU2NzJDXHU1RkM1XHU5ODdCXHU1MzA1XHU1NDJCXHU2QjYzXHU3ODZFXHU1RDRDXHU1OTU3XHU3Njg0XHU1OEYwXHU2NjBFXHUzMDAyCi0gICAgICAgIEltcHJvcGVyRGVjbGFyYXRpb25OZXN0aW5nID0gXHU1M0MyXHU2NTcwXHU1QjlFXHU0RjUzICJ7MH0iIFx1NzY4NFx1NjZGRlx1NjM2Mlx1NjU4N1x1NjcyQ1x1NUZDNVx1OTg3Qlx1NTMwNVx1NTQyQlx1NkI2M1x1Nzg2RVx1NUQ0Q1x1NTk1N1x1NzY4NFx1NThGMFx1NjYwRVx1MzAwMgotICAgICAgICBJbXByb3Blckdyb3VwTmVzdGluZyA9IFx1NTNDMlx1NjU3MFx1NUI5RVx1NEY1MyAiezB9IiBcdTc2ODRcdTY2RkZcdTYzNjJcdTY1ODdcdTY3MkNcdTVGQzVcdTk4N0JcdTUzMDVcdTU0MkJcdTZCNjNcdTc4NkVcdTVENENcdTU5NTdcdTc2ODRcdTYyRUNcdTUzRjdcdTVCRjlcdTMwMDIKLSAgICAgICAgSU5WQUxJRF9QRV9JTl9DT05ESVRJT05BTCA9IFx1NTNDMlx1NjU3MFx1NUI5RVx1NEY1MyAiezB9IiBcdTc2ODRcdTY2RkZcdTYzNjJcdTY1ODdcdTY3MkNcdTVGQzVcdTk4N0JcdTUzMDVcdTU0MkJcdTY1NzRcdTRFMkFcdTY3NjFcdTRFRjZcdTgyODIsIFx1NjIxNlx1ODAwNVx1NEVDNVx1NTMwNVx1NTQyQiBJTkNMVURFIFx1NjIxNiBJR05PUkVcdTMwMDIKLSAgICAgICAgTVNHX0FUVFJJQlVURV9OT1RfREVDTEFSRUQgPSBcdTVGQzVcdTk4N0JcdTRFM0FcdTUxNDNcdTdEMjBcdTdDN0JcdTU3OEIgInswfSIgXHU1OEYwXHU2NjBFXHU1QzVFXHU2MDI3ICJ7MX0iXHUzMDAyCi0gICAgICAgIE1TR19BVFRSSUJVVEVfVkFMVUVfTk9UX0lOX0xJU1QgPSBcdTUwM0NcdTRFM0EgInsxfSIgXHU3Njg0XHU1QzVFXHU2MDI3ICJ7MH0iIFx1NUZDNVx1OTg3Qlx1NTE3N1x1NjcwOVx1NTIxN1x1ODg2OCAiezJ9IiBcdTRFMkRcdTc2ODRcdTUwM0NcdTMwMDIKLSAgICAgICAgTVNHX0FUVFZBTFVFX0NIQU5HRURfRFVSSU5HX05PUk1BTElaQVRJT05fV0hFTl9TVEFOREFMT05FID0gXHU1NzI4XHU3MkVDXHU3QUNCXHU2NTg3XHU2ODYzXHU0RTJELCBcdTVDNUVcdTYwMjcgInswfSIgXHU3Njg0XHU1MDNDICJ7MX0iIFx1NEUwRFx1ODBGRFx1OTAxQVx1OEZDN1x1ODlDNFx1ODMwM1x1NTMxNlx1OEZEQlx1ODg0Q1x1NjZGNFx1NjUzOSAoXHU2NkY0XHU2NTM5XHU0RTNBICJ7Mn0iKVx1MzAwMgotICAgICAgICBNU0dfQ09OVEVOVF9JTkNPTVBMRVRFID0gXHU1MTQzXHU3RDIwXHU3QzdCXHU1NzhCXHU0RTNBICJ7MH0iIFx1NzY4NFx1NTE4NVx1NUJCOVx1NEUwRFx1NUI4Q1x1NjU3NCwgXHU1QjgzXHU1RkM1XHU5ODdCXHU1MzM5XHU5MTREICJ7MX0iXHUzMDAyCi0gICAgICAgIE1TR19DT05URU5UX0lOVkFMSUQgPSBcdTUxNDNcdTdEMjBcdTdDN0JcdTU3OEJcdTRFM0EgInswfSIgXHU3Njg0XHU1MTg1XHU1QkI5XHU1RkM1XHU5ODdCXHU1MzM5XHU5MTREICJ7MX0iXHUzMDAyCi0gICAgICAgIE1TR19DT05URU5UX0lOVkFMSURfU1BFQ0lGSUVEID0gXHU1MTQzXHU3RDIwXHU3QzdCXHU1NzhCXHU0RTNBICJ7MH0iIFx1NzY4NFx1NTE4NVx1NUJCOVx1NUZDNVx1OTg3Qlx1NTMzOVx1OTE0RCAiezF9Ilx1MzAwMlx1NEUwRFx1NTE0MVx1OEJCOFx1NEY3Rlx1NzUyOFx1N0M3Qlx1NTc4Qlx1NEUzQSAiezJ9IiBcdTc2ODRcdTVCNTBcdTdFQTdcdTMwMDIKLSAgICAgICAgTVNHX0RFRkFVTFRFRF9BVFRSSUJVVEVfTk9UX1NQRUNJRklFRCA9IFx1NTE0M1x1N0QyMFx1N0M3Qlx1NTc4Qlx1NEUzQSAiezB9IiBcdTc2ODRcdTVDNUVcdTYwMjcgInsxfSIgXHU1MTc3XHU2NzA5XHU5RUQ4XHU4QkE0XHU1MDNDLCBcdTVFNzZcdTRFMTRcdTVGQzVcdTk4N0JcdTU3MjhcdTcyRUNcdTdBQ0JcdTY1ODdcdTY4NjNcdTRFMkRcdTYzMDdcdTVCOUFcdTMwMDIKLSAgICAgICAgTVNHX0RVUExJQ0FURV9BVFRERUYgPSBcdTVERjJcdTdFQ0ZcdTRFM0FcdTUxNDNcdTdEMjBcdTdDN0JcdTU3OEIgInswfSIgXHU1OEYwXHU2NjBFXHU1QzVFXHU2MDI3ICJ7MX0iXHUzMDAyCi0gICAgICAgIE1TR19FTEVNRU5UX0FMUkVBRFlfREVDTEFSRUQgPSBcdTUxNDNcdTdEMjBcdTdDN0JcdTU3OEIgInswfSIgXHU0RTBEXHU4MEZEXHU1OEYwXHU2NjBFXHU1OTFBXHU2QjIxXHUzMDAyCi0gICAgICAgIE1TR19FTEVNRU5UX05PVF9ERUNMQVJFRCA9IFx1NUZDNVx1OTg3Qlx1NThGMFx1NjYwRVx1NTE0M1x1N0QyMFx1N0M3Qlx1NTc4QiAiezB9Ilx1MzAwMgotICAgICAgICBNU0dfR1JBTU1BUl9OT1RfRk9VTkQgPSBcdTY1ODdcdTY4NjNcdTY1RTBcdTY1NDg6IFx1NjI3RVx1NEUwRFx1NTIzMFx1OEJFRFx1NkNENVx1MzAwMgotICAgICAgICBNU0dfRUxFTUVOVF9XSVRIX0lEX1JFUVVJUkVEID0gXHU2NTg3XHU2ODYzXHU0RTJEXHU1RkM1XHU5ODdCXHU1MzA1XHU1NDJCXHU2ODA3XHU4QkM2XHU3QjI2XHU0RTNBICJ7MH0iIFx1NzY4NFx1NTE0M1x1N0QyMFx1MzAwMgotICAgICAgICBNU0dfRVhURVJOQUxfRU5USVRZX05PVF9QRVJNSVRURUQgPSBcdTU3MjhcdTcyRUNcdTdBQ0JcdTY1ODdcdTY4NjNcdTRFMkRcdTRFMERcdTUxNDFcdThCQjhcdTVGMTVcdTc1MjhcdTU5MTZcdTkwRThcdTVCOUVcdTRGNTMgInswfSJcdTMwMDIKLSAgICAgICAgTVNHX0ZJWEVEX0FUVFZBTFVFX0lOVkFMSUQgPSBcdTUwM0NcdTRFM0EgInsyfSIgXHU3Njg0XHU1QzVFXHU2MDI3ICJ7MX0iIFx1NUZDNVx1OTg3Qlx1NTE3N1x1NjcwOSAiezN9IiBcdTc2ODRcdTUwM0NcdTMwMDIKLSAgICAgICAgTVNHX01PUkVfVEhBTl9PTkVfSURfQVRUUklCVVRFID0gXHU1MTQzXHU3RDIwXHU3QzdCXHU1NzhCICJ7MH0iIFx1NURGMlx1N0VDRlx1NTE3N1x1NjcwOVx1N0M3Qlx1NTc4Qlx1NEUzQSBJRCBcdTc2ODRcdTVDNUVcdTYwMjcgInsxfSIsIFx1NEUwRFx1NTE0MVx1OEJCOFx1NEY3Rlx1NzUyOFx1N0M3Qlx1NTc4Qlx1NEUzQSBJRCBcdTc2ODRcdTUzRTZcdTRFMDBcdTRFMkFcdTVDNUVcdTYwMjcgInsyfSJcdTMwMDIKLSAgICAgICAgTVNHX01PUkVfVEhBTl9PTkVfTk9UQVRJT05fQVRUUklCVVRFID0gXHU1MTQzXHU3RDIwXHU3QzdCXHU1NzhCICJ7MH0iIFx1NURGMlx1N0VDRlx1NTE3N1x1NjcwOVx1N0M3Qlx1NTc4Qlx1NEUzQSBOT1RBVElPTiBcdTc2ODRcdTVDNUVcdTYwMjcgInsxfSIsIFx1NEUwRFx1NTE0MVx1OEJCOFx1NEY3Rlx1NzUyOFx1N0M3Qlx1NTc4Qlx1NEUzQSBOT1RBVElPTiBcdTc2ODRcdTUzRTZcdTRFMDBcdTRFMkFcdTVDNUVcdTYwMjcgInsyfSJcdTMwMDIKLSAgICAgICAgTVNHX05PVEFUSU9OX05PVF9ERUNMQVJFRF9GT1JfTk9UQVRJT05UWVBFX0FUVFJJQlVURSA9IFx1NTcyOFx1NUM1RVx1NjAyNyAiezB9IiBcdTc2ODRcdThCQjBcdTUzRjdcdTdDN0JcdTU3OEJcdTUyMTdcdTg4NjhcdTRFMkRcdTVGMTVcdTc1MjhcdThCQjBcdTUzRjcgInsxfSIgXHU2NUY2LCBcdTVGQzVcdTk4N0JcdTU4RjBcdTY2MEVcdThCRTVcdThCQjBcdTUzRjdcdTMwMDIKLSAgICAgICAgTVNHX05PVEFUSU9OX05PVF9ERUNMQVJFRF9GT1JfVU5QQVJTRURfRU5USVRZREVDTCA9IFx1NTcyOCAiezB9IiBcdTc2ODRcdTY3MkFcdTg5RTNcdTY3OTBcdTVCOUVcdTRGNTNcdTU4RjBcdTY2MEVcdTRFMkRcdTVGMTVcdTc1MjhcdThCQjBcdTUzRjcgInsxfSIgXHU2NUY2LCBcdTVGQzVcdTk4N0JcdTU4RjBcdTY2MEVcdThCRTVcdThCQjBcdTUzRjdcdTMwMDIKLSAgICAgICAgTVNHX1JFRkVSRU5DRV9UT19FWFRFUk5BTExZX0RFQ0xBUkVEX0VOVElUWV9XSEVOX1NUQU5EQUxPTkUgPSBcdTU3MjhcdTcyRUNcdTdBQ0JcdTY1ODdcdTY4NjNcdTRFMkRcdTRFMERcdTUxNDFcdThCQjhcdTVGMTVcdTc1MjhcdTVERjJcdTg5RTNcdTY3OTBcdTc2ODRcdTU5MTZcdTkwRThcdTVCOUVcdTRGNTNcdTRFMkRcdTU4RjBcdTY2MEVcdTc2ODRcdTVCOUVcdTRGNTMgInswfSJcdTMwMDIKLSAgICAgICAgTVNHX1JFUVVJUkVEX0FUVFJJQlVURV9OT1RfU1BFQ0lGSUVEID0gXHU5NzAwXHU4OTgxXHU1QzVFXHU2MDI3ICJ7MX0iLCBcdTVFNzZcdTRFMTRcdTVGQzVcdTk4N0JcdTRFM0FcdTUxNDNcdTdEMjBcdTdDN0JcdTU3OEIgInswfSIgXHU2MzA3XHU1QjlBXHU4QkU1XHU1QzVFXHU2MDI3XHUzMDAyCi0gICAgICAgIE1TR19XSElURV9TUEFDRV9JTl9FTEVNRU5UX0NPTlRFTlRfV0hFTl9TVEFOREFMT05FID0gXHU1QkY5XHU0RThFXHU1NzI4XHU3MkVDXHU3QUNCXHU2NTg3XHU2ODYzXHU0RTJEXHU1MTc3XHU2NzA5XHU1MTQzXHU3RDIwXHU1MTg1XHU1QkI5XHU3Njg0XHU1REYyXHU4OUUzXHU2NzkwXHU3Njg0XHU1OTE2XHU5MEU4XHU1QjlFXHU0RjUzLCBcdTU3MjhcdThCRTVcdTVCOUVcdTRGNTNcdTRFMkRcdTU4RjBcdTY2MEVcdTc2ODRcdTUxNDNcdTdEMjBcdTRFNEJcdTk1RjRcdTRFMERcdTgwRkRcdTUxRkFcdTczQjBcdTdBN0FcdTY4M0NcdTMwMDIKLSAgICAgICAgTk1UT0tFTkludmFsaWQgPSBcdTdDN0JcdTU3OEJcdTRFM0EgTk1UT0tFTiBcdTc2ODRcdTVDNUVcdTYwMjdcdTUwM0MgInswfSIgXHU1RkM1XHU5ODdCXHU2NjJGXHU1NDBEXHU3OUYwXHU2ODA3XHU4QkIwXHUzMDAyCi0gICAgICAgIE5NVE9LRU5TSW52YWxpZCA9IFx1N0M3Qlx1NTc4Qlx1NEUzQSBOTVRPS0VOUyBcdTc2ODRcdTVDNUVcdTYwMjdcdTUwM0MgInswfSIgXHU1RkM1XHU5ODdCXHU2NjJGXHU0RTAwXHU0RTJBXHU2MjE2XHU1OTFBXHU0RTJBXHU1NDBEXHU3OUYwXHU2ODA3XHU4QkIwXHUzMDAyCi0gICAgICAgIE5vTm90YXRpb25PbkVtcHR5RWxlbWVudCA9IFx1NURGMlx1NThGMFx1NjYwRVx1NEUzQSBFTVBUWSBcdTc2ODRcdTUxNDNcdTdEMjBcdTdDN0JcdTU3OEIgInswfSIgXHU0RTBEXHU4MEZEXHU1OEYwXHU2NjBFXHU3QzdCXHU1NzhCXHU0RTNBIE5PVEFUSU9OIFx1NzY4NFx1NUM1RVx1NjAyNyAiezF9Ilx1MzAwMgotICAgICAgICBSb290RWxlbWVudFR5cGVNdXN0TWF0Y2hEb2N0eXBlZGVjbCA9IFx1NjU4N1x1Njg2M1x1NjgzOVx1NTE0M1x1N0QyMCAiezF9IiBcdTVGQzVcdTk4N0JcdTUzMzlcdTkxNEQgRE9DVFlQRSBcdTY4MzkgInswfSJcdTMwMDIKLSAgICAgICAgVW5kZWNsYXJlZEVsZW1lbnRJbkNvbnRlbnRTcGVjID0gXHU1MTQzXHU3RDIwICJ7MH0iIFx1NzY4NFx1NTE4NVx1NUJCOVx1NkEyMVx1NTc4Qlx1NUYxNVx1NzUyOFx1NjcyQVx1NThGMFx1NjYwRVx1NzY4NFx1NTE0M1x1N0QyMCAiezF9Ilx1MzAwMgotICAgICAgICBVbmlxdWVOb3RhdGlvbk5hbWUgPSBcdThCQjBcdTUzRjcgInswfSIgXHU3Njg0XHU1OEYwXHU2NjBFXHU0RTBEXHU2NjJGXHU1NTJGXHU0RTAwXHU3Njg0XHUzMDAyXHU0RTBEXHU4MEZEXHU1NzI4XHU1OTFBXHU0RTJBXHU4QkIwXHU1M0Y3XHU1OEYwXHU2NjBFXHU0RTJEXHU1OEYwXHU2NjBFXHU2MzA3XHU1QjlBXHU3Njg0XHU1NDBEXHU3OUYwXHUzMDAyCi0gICAgICAgIEVOVElUWUZhaWxlZEluaXRpYWxpemVHcmFtbWFyID0gIEVOVElUWURhdGF0eXBlIFx1OUE4Q1x1OEJDMVx1N0EwQlx1NUU4RjogXHU2NzJBXHU4MEZEXHU0RjdGXHU3NTI4XHU2NzA5XHU2NTQ4XHU3Njg0XHU4QkVEXHU2Q0Q1XHU1RjE1XHU3NTI4XHU4QzAzXHU3NTI4XHU1MjFEXHU1OUNCXHU1MzE2XHU2NUI5XHU2Q0Q1XHUzMDAyXHQKLSAgICAgICAgRU5USVRZTm90VW5wYXJzZWQgPSBFTlRJVFkgInswfSIgXHU0RTBEXHU2NjJGXHU2NzJBXHU4OUUzXHU2NzkwXHU3Njg0XHUzMDAyCi0gICAgICAgIEVOVElUWU5vdFZhbGlkID0gRU5USVRZICJ7MH0iIFx1NjVFMFx1NjU0OFx1MzAwMgotICAgICAgICBFbXB0eUxpc3QgPSBcdTdDN0JcdTU3OEJcdTRFM0EgRU5USVRJRVMsIElEUkVGUyBcdTU0OEMgTk1UT0tFTlMgXHU3Njg0XHU1MDNDXHU0RTBEXHU4MEZEXHU2NjJGXHU3QTdBXHU1MjE3XHU4ODY4XHUzMDAyCi0KLSMgRW50aXR5IHJlbGF0ZWQgbWVzc2FnZXMKLSMgMy4xIFN0YXJ0LVRhZ3MsIEVuZC1UYWdzLCBhbmQgRW1wdHktRWxlbWVudCBUYWdzCi0gICAgICAgIFJlZmVyZW5jZVRvRXh0ZXJuYWxFbnRpdHkgPSBcdTVDNUVcdTYwMjdcdTUwM0NcdTRFMkRcdTRFMERcdTUxNDFcdThCQjhcdTkxQzdcdTc1MjhcdTU5MTZcdTkwRThcdTVCOUVcdTRGNTNcdTVGMTVcdTc1MjggIiZ7MH07Ilx1MzAwMgotICAgICAgICBBY2Nlc3NFeHRlcm5hbERURCA9IFx1NTkxNlx1OTBFOCBEVEQ6IFx1NjVFMFx1NkNENVx1OEJGQlx1NTNENlx1NTkxNlx1OTBFOCBEVEQgJyd7MH0nJywgXHU1NkUwXHU0RTNBIGFjY2Vzc0V4dGVybmFsRFREIFx1NUM1RVx1NjAyN1x1OEJCRVx1N0Y2RVx1NzY4NFx1OTY1MFx1NTIzNlx1NUJGQ1x1ODFGNFx1NEUwRFx1NTE0MVx1OEJCOCAnJ3sxfScnIFx1OEJCRlx1OTVFRVx1MzAwMgotICAgICAgICBBY2Nlc3NFeHRlcm5hbEVudGl0eSA9IFx1NTkxNlx1OTBFOFx1NUI5RVx1NEY1MzogXHU2NUUwXHU2Q0Q1XHU4QkZCXHU1M0Q2XHU1OTE2XHU5MEU4XHU2NTg3XHU2ODYzICcnezB9JycsIFx1NTZFMFx1NEUzQSBhY2Nlc3NFeHRlcm5hbERURCBcdTVDNUVcdTYwMjdcdThCQkVcdTdGNkVcdTc2ODRcdTk2NTBcdTUyMzZcdTVCRkNcdTgxRjRcdTRFMERcdTUxNDFcdThCQjggJyd7MX0nJyBcdThCQkZcdTk1RUVcdTMwMDIKLQotIyA0LjEgQ2hhcmFjdGVyIGFuZCBFbnRpdHkgUmVmZXJlbmNlcwotICAgICAgICBFbnRpdHlOb3REZWNsYXJlZCA9IFx1NUYxNVx1NzUyOFx1NEU4Nlx1NUI5RVx1NEY1MyAiezB9IiwgXHU0RjQ2XHU2NzJBXHU1OEYwXHU2NjBFXHU1QjgzXHUzMDAyCi0gICAgICAgIFJlZmVyZW5jZVRvVW5wYXJzZWRFbnRpdHkgPSBcdTRFMERcdTUxNDFcdThCQjhcdTRGN0ZcdTc1MjhcdTY3MkFcdTg5RTNcdTY3OTBcdTc2ODRcdTVCOUVcdTRGNTNcdTVGMTVcdTc1MjggIiZ7MH07Ilx1MzAwMgotICAgICAgICBSZWN1cnNpdmVSZWZlcmVuY2UgPSBcdTkwMTJcdTVGNTJcdTVCOUVcdTRGNTNcdTVGMTVcdTc1MjggInswfSJcdTMwMDIoXHU1RjE1XHU3NTI4XHU4REVGXHU1Rjg0OiB7MX0pLAotICAgICAgICBSZWN1cnNpdmVHZW5lcmFsUmVmZXJlbmNlID0gXHU5MDEyXHU1RjUyXHU0RTAwXHU4MjJDXHU1QjlFXHU0RjUzXHU1RjE1XHU3NTI4ICImezB9OyJcdTMwMDIoXHU1RjE1XHU3NTI4XHU4REVGXHU1Rjg0OiB7MX0pLAotICAgICAgICBSZWN1cnNpdmVQRVJlZmVyZW5jZSA9IFx1OTAxMlx1NUY1Mlx1NTNDMlx1NjU3MFx1NUI5RVx1NEY1M1x1NUYxNVx1NzUyOCAiJXswfTsiXHUzMDAyKFx1NUYxNVx1NzUyOFx1OERFRlx1NUY4NDogezF9KSwKLSMgNC4zLjMgQ2hhcmFjdGVyIEVuY29kaW5nIGluIEVudGl0aWVzCi0gICAgICAgIEVuY29kaW5nTm90U3VwcG9ydGVkID0gXHU0RTBEXHU2NTJGXHU2MzAxXHU3RjE2XHU3ODAxICJ7MH0iXHUzMDAyCi0gICAgICAgIEVuY29kaW5nUmVxdWlyZWQgPSBcdTU5ODJcdTY3OUNcdTVERjJcdTg5RTNcdTY3OTBcdTc2ODRcdTVCOUVcdTRGNTNcdTY3MkFcdTRGN0ZcdTc1MjggVVRGLTggXHU2MjE2IFVURi0xNiBcdThGREJcdTg4NENcdTdGMTZcdTc4MDEsIFx1NTIxOVx1OEJFNVx1NUI5RVx1NEY1M1x1NUZDNVx1OTg3Qlx1NTMwNVx1NTQyQlx1N0YxNlx1NzgwMVx1NThGMFx1NjYwRVx1MzAwMgotICAgICAgICAKLSMgTmFtZXNwYWNlcyBzdXBwb3J0Ci0jIDQuIFVzaW5nIFF1YWxpZmllZCBOYW1lcwotICAgICAgICBJbGxlZ2FsUU5hbWUgPSBcdTUxNDNcdTdEMjBcdTYyMTZcdTVDNUVcdTYwMjdcdTRFMERcdTUzMzlcdTkxNEQgUU5hbWUgXHU3NTFGXHU0RUE3OiBRTmFtZTo6PShOQ05hbWUnOicpP05DTmFtZVx1MzAwMgotICAgICAgICBFbGVtZW50WE1MTlNQcmVmaXggPSBcdTUxNDNcdTdEMjAgInswfSIgXHU0RTBEXHU4MEZEXHU0RjdGXHU3NTI4ICJ4bWxucyIgXHU0RjVDXHU0RTNBXHU1MjREXHU3RjAwXHUzMDAyCi0gICAgICAgIEVsZW1lbnRQcmVmaXhVbmJvdW5kID0gXHU1MTQzXHU3RDIwICJ7MX0iIFx1NzY4NFx1NTI0RFx1N0YwMCAiezB9IiBcdTY3MkFcdTdFRDFcdTVCOUFcdTMwMDIKLSAgICAgICAgQXR0cmlidXRlUHJlZml4VW5ib3VuZCA9IFx1NEUwRVx1NTE0M1x1N0QyMFx1N0M3Qlx1NTc4QiAiezB9IiBcdTc2RjhcdTUxNzNcdTgwNTRcdTc2ODRcdTVDNUVcdTYwMjcgInsxfSIgXHU3Njg0XHU1MjREXHU3RjAwICJ7Mn0iIFx1NjcyQVx1N0VEMVx1NUI5QVx1MzAwMgotICAgICAgICBFbXB0eVByZWZpeGVkQXR0TmFtZSA9IFx1NUM1RVx1NjAyNyAiezB9IiBcdTc2ODRcdTUwM0NcdTY1RTBcdTY1NDhcdTMwMDJcdTVFMjZcdTUyNERcdTdGMDBcdTc2ODRcdTU0MERcdTc5RjBcdTdBN0FcdTk1RjRcdTdFRDFcdTVCOUFcdTRFMERcdTgwRkRcdTRFM0FcdTdBN0FcdTMwMDIKLSAgICAgICAgUHJlZml4RGVjbGFyZWQgPSBcdTY3MkFcdTU4RjBcdTY2MEVcdTU0MERcdTc5RjBcdTdBN0FcdTk1RjRcdTUyNERcdTdGMDAgInswfSJcdTMwMDIKLSAgICAgICAgQ2FudEJpbmRYTUxOUyA9IFx1NTI0RFx1N0YwMCAieG1sbnMiIFx1NEUwRFx1ODBGRFx1NjYzRVx1NUYwRlx1N0VEMVx1NUI5QVx1NTIzMFx1NEVGQlx1NEY1NVx1NTQwRFx1NzlGMFx1N0E3QVx1OTVGNDsgInhtbG5zIiBcdTc2ODRcdTU0MERcdTc5RjBcdTdBN0FcdTk1RjRcdTRFNUZcdTRFMERcdTgwRkRcdTY2M0VcdTVGMEZcdTdFRDFcdTVCOUFcdTUyMzBcdTRFRkJcdTRGNTVcdTUyNERcdTdGMDBcdTMwMDIKLSAgICAgICAgQ2FudEJpbmRYTUwgPSBcdTUyNERcdTdGMDAgInhtbCIgXHU0RTBEXHU4MEZEXHU3RUQxXHU1QjlBXHU1MjMwXHU5NjY0XHU1QjgzXHU3Njg0XHU1RTM4XHU3NTI4XHU1NDBEXHU3OUYwXHU3QTdBXHU5NUY0XHU1OTE2XHU3Njg0XHU0RUZCXHU0RjU1XHU1NDBEXHU3OUYwXHU3QTdBXHU5NUY0OyAieG1sIiBcdTc2ODRcdTU0MERcdTc5RjBcdTdBN0FcdTk1RjRcdTRFNUZcdTRFMERcdTgwRkRcdTdFRDFcdTVCOUFcdTUyMzBcdTk2NjQgInhtbCIgXHU1OTE2XHU3Njg0XHU0RUZCXHU0RjU1XHU1MjREXHU3RjAwXHUzMDAyCi0gICAgICAgIE1TR19BVFRfREVGQVVMVF9JTlZBTElEID0gXHU1QzVFXHU2MDI3ICJ7MH0iIFx1NzY4NCBkZWZhdWx0VmFsdWUgInsxfSIgXHU5NzVFXHU2Q0Q1LCBcdTU2RTBcdTRFM0FcdTZCNjRcdTVDNUVcdTYwMjdcdTdDN0JcdTU3OEJcdTUxNzdcdTY3MDlcdThCQ0RcdTZDNDdcdTdFQTZcdTY3NUZcdTY3NjFcdTRFRjZcdTMwMDIKLQotIyBSRVZJU0lUOiBUaGVzZSBuZWVkIG1lc3NhZ2VzCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9BRlRFUl9TWVNURU1MSVRFUkFMX0lOX0VYVEVSTkFMSUQ9TVNHX1NQQUNFX1JFUVVJUkVEX0FGVEVSX1NZU1RFTUxJVEVSQUxfSU5fRVhURVJOQUxJRAotICAgICAgICBPcGVuUXVvdGVNaXNzaW5nSW5EZWNsPU9wZW5RdW90ZU1pc3NpbmdJbkRlY2wKLSAgICAgICAgSW52YWxpZENoYXJJbkxpdGVyYWw9SW52YWxpZENoYXJJbkxpdGVyYWwKLQotCi0jIEltcGxlbWVudGF0aW9uIGxpbWl0cwotICAgICAgICBFbnRpdHlFeHBhbnNpb25MaW1pdD1KQVhQMDAwMTAwMDE6IFx1ODlFM1x1Njc5MFx1NTY2OFx1NTcyOFx1NkI2NFx1NjU4N1x1Njg2M1x1NEUyRFx1OTA0N1x1NTIzMFx1NTkxQVx1NEUyQSAiezB9IiBcdTVCOUVcdTRGNTNcdTYyNjlcdTVDNTU7IFx1OEZEOVx1NjYyRiBKREsgXHU2NUJEXHU1MkEwXHU3Njg0XHU5NjUwXHU1MjM2XHUzMDAyCi0gICAgICAgIEVsZW1lbnRBdHRyaWJ1dGVMaW1pdD1KQVhQMDAwMTAwMDI6IFx1NTE0M1x1N0QyMCAiezB9IiBcdTUxNzdcdTY3MDlcdTU5MUFcdTRFMkEgInsxfSIgXHU1QzVFXHU2MDI3LCAiezF9IiBcdTY2MkYgSkRLIFx1NjVCRFx1NTJBMFx1NzY4NFx1OTY1MFx1NTIzNlx1MzAwMgotICAgICAgICBNYXhFbnRpdHlTaXplTGltaXQ9SkFYUDAwMDEwMDAzOiBcdTVCOUVcdTRGNTMgInswfSIgXHU3Njg0XHU5NTdGXHU1RUE2XHU0RTNBICJ7MX0iLCBcdThEODVcdThGQzdcdTRFODYgInszfSIgXHU4QkJFXHU3RjZFXHU3Njg0ICJ7Mn0iIFx1OTY1MFx1NTIzNlx1MzAwMgotICAgICAgICBUb3RhbEVudGl0eVNpemVMaW1pdD1KQVhQMDAwMTAwMDQ6IFx1NUI5RVx1NEY1M1x1NzY4NFx1N0QyRlx1OEJBMVx1NTkyN1x1NUMwRlx1NEUzQSAiezB9IiwgXHU4RDg1XHU4RkM3XHU0RTg2ICJ7Mn0iIFx1OEJCRVx1N0Y2RVx1NzY4NCAiezF9IiBcdTk2NTBcdTUyMzZcdTMwMDIKLSAgICAgICAgTWF4WE1MTmFtZUxpbWl0PUpBWFAwMDAxMDAwNTogXHU1QjlFXHU0RjUzICJ7MH0iIFx1NzY4NFx1OTU3Rlx1NUVBNlx1NEUzQSAiezF9IiwgXHU4RDg1XHU4RkM3XHU0RTg2ICJ7M30iIFx1OEJCRVx1N0Y2RVx1NzY4NCAiezJ9IiBcdTk2NTBcdTUyMzZcdTMwMDIKLSAgICAgICAgTWF4RWxlbWVudERlcHRoTGltaXQ9SkFYUDAwMDEwMDA2OiBcdTUxNDNcdTdEMjAgInswfSIgXHU3Njg0XHU2REYxXHU1RUE2ICJ7MX0iIFx1OEQ4NVx1OEZDN1x1NEU4NiAiezN9IiBcdThCQkVcdTdGNkVcdTc2ODRcdTk2NTBcdTUyMzYgInsyfSJcdTMwMDIKLSAgICAgICAgRW50aXR5UmVwbGFjZW1lbnRMaW1pdD1KQVhQMDAwMTAwMDc6IFx1NUI5RVx1NEY1M1x1NUYxNVx1NzUyOFx1NEUyRFx1NzY4NFx1ODI4Mlx1NzBCOVx1NjAzQlx1NjU3MFx1NEUzQSAiezB9IiwgXHU4RDg1XHU4RkM3XHU0RTg2ICJ7Mn0iIFx1OEJCRVx1N0Y2RVx1NzY4NFx1OTY1MFx1NTIzNiAiezF9Ilx1MzAwMgotCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9YTUxNZXNzYWdlc196aF9UVy5wcm9wZXJ0aWVzIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MTWVzc2FnZXNfemhfVFcucHJvcGVydGllcwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggODBlMDFmMi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9YTUxNZXNzYWdlc196aF9UVy5wcm9wZXJ0aWVzCisrKyAvZGV2L251bGwKQEAgLTEsMzA1ICswLDAgQEAKLSMgVGhpcyBmaWxlIGNvbnRhaW5zIGVycm9yIGFuZCB3YXJuaW5nIG1lc3NhZ2VzIHJlbGF0ZWQgdG8gWE1MCi0jIFRoZSBtZXNzYWdlcyBhcmUgYXJyYW5nZWQgaW4ga2V5IGFuZCB2YWx1ZSB0dXBsZXMgaW4gYSBMaXN0UmVzb3VyY2VCdW5kbGUuCi0jCi0jIEB2ZXJzaW9uCi0KLSAgICAgICAgQmFkTWVzc2FnZUtleSA9IFx1NjI3RVx1NEUwRFx1NTIzMFx1NUMwRFx1NjFDOVx1OEEwQVx1NjA2Rlx1N0QyMlx1NUYxNVx1OTM3NVx1NzY4NFx1OTMyRlx1OEFBNFx1OEEwQVx1NjA2Rlx1MzAwMgotICAgICAgICBGb3JtYXRGYWlsZWQgPSBcdTY4M0NcdTVGMEZcdTUzMTZcdTRFMEJcdTUyMTdcdThBMEFcdTYwNkZcdTY2NDJcdTc2N0NcdTc1MUZcdTUxNjdcdTkwRThcdTkzMkZcdThBQTQ6XG4KLSAgICAgICAgCi0jIERvY3VtZW50IG1lc3NhZ2VzCi0gICAgICAgIFByZW1hdHVyZUVPRj1cdTZBOTRcdTY4NDhcdTYzRDBcdTY1RTlcdTdENTBcdTY3NUZcdTMwMDIKLSMgMi4xIFdlbGwtRm9ybWVkIFhNTCBEb2N1bWVudHMKLSAgICAgICAgUm9vdEVsZW1lbnRSZXF1aXJlZCA9IFx1NjgzQ1x1NUYwRlx1NkI2M1x1NzhCQVx1NzY4NFx1NjU4N1x1NEVGNlx1OTcwMFx1ODk4MVx1NjgzOVx1NTE0M1x1N0QyMFx1MzAwMgotIyAyLjIgQ2hhcmFjdGVycwotCi0gICAgICAgIEludmFsaWRDaGFySW5DRFNlY3QgPSBcdTU3MjggQ0RBVEEgXHU2QkI1XHU4NDNEXHU0RTJEXHU2MjdFXHU1MjMwXHU3MTIxXHU2NTQ4XHU3Njg0IFhNTCBcdTVCNTdcdTUxNDMgKFVuaWNvZGU6IDB4ezB9KVx1MzAwMgotICAgICAgICBJbnZhbGlkQ2hhckluQ29udGVudCA9IFx1NTcyOFx1NjU4N1x1NEVGNlx1NTE0M1x1N0QyMFx1NTE2N1x1NUJCOVx1NEUyRFx1NjI3RVx1NTIzMFx1NzEyMVx1NjU0OFx1NzY4NCBYTUwgXHU1QjU3XHU1MTQzIChVbmljb2RlOiAweHswfSlcdTMwMDIKLSAgICAgICAgVHdvQ29sb25zSW5RTmFtZSA9IFx1NTcyOFx1NTE0M1x1N0QyMFx1OTg1RVx1NTc4Qlx1NjIxNlx1NUM2Q1x1NjAyN1x1NTQwRFx1N0EzMVx1NEUyRFx1NjI3RVx1NTIzMFx1NzEyMVx1NjU0OFx1NzY4NFx1N0IyQ1x1NEU4Q1x1NTAwQiAnOidcdTMwMDIKLSAgICAgICAgQ29sb25Ob3RMZWdhbFdpdGhOUyA9IFx1NTU1Rlx1NzUyOFx1NTQ3RFx1NTQwRFx1N0E3QVx1OTU5M1x1NjY0Mlx1RkYwQ1x1NTQwRFx1N0EzMSAnJ3swfScnIFx1NEUyRFx1NEUwRFx1NTE0MVx1OEEzMVx1NTE5Mlx1ODY1Rlx1MzAwMgotICAgICAgICBJbnZhbGlkQ2hhckluTWlzYyA9IFx1NTcyOFx1NTE0M1x1N0QyMFx1NTE2N1x1NUJCOVx1N0Q1MFx1Njc1Rlx1NUY4Q1x1NzY4NFx1NkExOVx1OEExOFx1NEUyRFx1NjI3RVx1NTIzMFx1NzEyMVx1NjU0OFx1NzY4NCBYTUwgXHU1QjU3XHU1MTQzIChVbmljb2RlOiAweHswfSlcdTMwMDIKLSAgICAgICAgSW52YWxpZENoYXJJblByb2xvZyA9IFx1NTcyOFx1NjU4N1x1NEVGNlx1NUJBM1x1NTQ0QVx1OTZDNlx1NEUyRFx1NjI3RVx1NTIzMFx1NzEyMVx1NjU0OFx1NzY4NCBYTUwgXHU1QjU3XHU1MTQzIChVbmljb2RlOiAweHswfSlcdTMwMDIKLSAgICAgICAgSW52YWxpZENoYXJJblhNTERlY2wgPSBcdTU3MjggWE1MIFx1NUJBM1x1NTQ0QVx1NEUyRFx1NjI3RVx1NTIzMFx1NzEyMVx1NjU0OFx1NzY4NCBYTUwgXHU1QjU3XHU1MTQzIChVbmljb2RlOiAweHswfSlcdTMwMDIKLSMgMi40IENoYXJhY3RlciBEYXRhIGFuZCBNYXJrdXAKLSAgICAgICAgQ0RFbmRJbkNvbnRlbnQgPSBcdTVCNTdcdTUxNDNcdTk4MDZcdTVFOEYgIl1dPiIgXHU0RTBEXHU1M0VGXHU1MUZBXHU3M0ZFXHU1NzI4XHU1MTY3XHU1QkI5XHU0RTJEXHVGRjBDXHU5NjY0XHU5NzVFXHU3NTI4XHU2NUJDXHU2QTE5XHU3OTNBIENEQVRBIFx1NkJCNVx1ODQzRFx1NzY4NFx1N0Q1MFx1NUMzRVx1MzAwMgotIyAyLjcgQ0RBVEEgU2VjdGlvbnMKLSAgICAgICAgQ0RTZWN0VW50ZXJtaW5hdGVkID0gQ0RBVEEgXHU2QkI1XHU4NDNEXHU3RDUwXHU1QzNFXHU1RkM1XHU5ODA4XHU2NjJGICJdXT4iXHUzMDAyCi0jIDIuOCBQcm9sb2cgYW5kIERvY3VtZW50IFR5cGUgRGVjbGFyYXRpb24KLSAgICAgICAgWE1MRGVjbE11c3RCZUZpcnN0ID0gWE1MIFx1NUJBM1x1NTQ0QVx1NTBDNVx1ODBGRFx1NTFGQVx1NzNGRVx1NTcyOFx1NjU4N1x1NEVGNlx1NzY4NFx1OTU4Qlx1OTgyRFx1MzAwMgotICAgICAgICBFcVJlcXVpcmVkSW5YTUxEZWNsID0gXHU1NzI4IFhNTCBcdTVCQTNcdTU0NEFcdTRFMkRcdUZGMEMnJyA9ICcnIFx1NUI1N1x1NTE0M1x1NUZDNVx1OTgwOFx1N0RDQVx1NjNBNVx1NTcyOCAiezB9IiBcdTRFNEJcdTVGOENcdTMwMDIKLSAgICAgICAgUXVvdGVSZXF1aXJlZEluWE1MRGVjbCA9IFx1NTcyOCBYTUwgXHU1QkEzXHU1NDRBXHU0RTJEXHVGRjBDInswfSIgXHU0RTRCXHU1RjhDXHU3Njg0XHU1MDNDXHU1RkM1XHU5ODA4XHU2NjJGXHU0RUU1XHU1RjE1XHU4NjVGXHU2MkVDXHU0RjRGXHU3Njg0XHU1QjU3XHU0RTMyXHUzMDAyCi0gICAgICAgIFhNTERlY2xVbnRlcm1pbmF0ZWQgPSBYTUwgXHU1QkEzXHU1NDRBXHU3RDUwXHU1QzNFXHU1RkM1XHU5ODA4XHU2NjJGICI/PiJcdTMwMDIKLSAgICAgICAgVmVyc2lvbkluZm9SZXF1aXJlZCA9IFhNTCBcdTVCQTNcdTU0NEFcdTRFMkRcdTk3MDBcdTg5ODFcdTcyNDhcdTY3MkNcdTMwMDIKLSAgICAgICAgU3BhY2VSZXF1aXJlZEJlZm9yZVZlcnNpb25JblhNTERlY2wgPSBcdTU3MjggWE1MIFx1NUJBM1x1NTQ0QVx1NEUyRFx1RkYwQ1x1NzI0OFx1NjcyQ1x1ODY1Qlx1NjRFQ1x1NUM2Q1x1NjAyN1x1NEU0Qlx1NTI0RFx1OTcwMFx1ODk4MVx1NjcwOVx1N0E3QVx1NjgzQ1x1MzAwMgotICAgICAgICBTcGFjZVJlcXVpcmVkQmVmb3JlRW5jb2RpbmdJblhNTERlY2wgPSBcdTU3MjggWE1MIFx1NUJBM1x1NTQ0QVx1NEUyRFx1RkYwQ1x1N0RFOFx1NzhCQ1x1ODY1Qlx1NjRFQ1x1NUM2Q1x1NjAyN1x1NEU0Qlx1NTI0RFx1OTcwMFx1ODk4MVx1NjcwOVx1N0E3QVx1NjgzQ1x1MzAwMgotICAgICAgICBTcGFjZVJlcXVpcmVkQmVmb3JlU3RhbmRhbG9uZSA9IFx1NTcyOCBYTUwgXHU1QkEzXHU1NDRBXHU0RTJEXHVGRjBDXHU3REU4XHU3OEJDXHU4NjVCXHU2NEVDXHU1QzZDXHU2MDI3XHU0RTRCXHU1MjREXHU5NzAwXHU4OTgxXHU2NzA5XHU3QTdBXHU2ODNDXHUzMDAyCi0gICAgICAgIE1hcmt1cE5vdFJlY29nbml6ZWRJblByb2xvZyA9IFx1NjU4N1x1NEVGNlx1NEUyRFx1NjgzOVx1NTE0M1x1N0QyMFx1NTI0RFx1NzY4NFx1NkExOVx1OEExOFx1NUZDNVx1OTgwOFx1NjgzQ1x1NUYwRlx1NkI2M1x1NzhCQVx1MzAwMgotICAgICAgICBNYXJrdXBOb3RSZWNvZ25pemVkSW5NaXNjID0gXHU2NTg3XHU0RUY2XHU0RTJEXHU2ODM5XHU1MTQzXHU3RDIwXHU1RjhDXHU3Njg0XHU2QTE5XHU4QTE4XHU1RkM1XHU5ODA4XHU2ODNDXHU1RjBGXHU2QjYzXHU3OEJBXHUzMDAyCi0gICAgICAgIEFscmVhZHlTZWVuRG9jdHlwZSA9IGRvY3R5cGUgXHU1REYyXHU3RDkzXHU1MUZBXHU3M0ZFXHU5MDRFXHUzMDAyCi0gICAgICAgIERvY3R5cGVOb3RBbGxvd2VkID0gXHU3NTc2XHU1MjlGXHU4MEZEICJodHRwOi8vYXBhY2hlLm9yZy94bWwvZmVhdHVyZXMvZGlzYWxsb3ctZG9jdHlwZS1kZWNsIiBcdThBMkRcdTcwQkFcdTc3MUZcdTY2NDJcdUZGMENcdTRFMERcdTUxNDFcdThBMzEgRE9DVFlQRVx1MzAwMgotICAgICAgICBDb250ZW50SWxsZWdhbEluUHJvbG9nID0gXHU1QkEzXHU1NDRBXHU5NkM2XHU0RTJEXHU0RTBEXHU1MTQxXHU4QTMxXHU1MTY3XHU1QkI5XHUzMDAyCi0gICAgICAgIFJlZmVyZW5jZUlsbGVnYWxJblByb2xvZyA9IFx1NUJBM1x1NTQ0QVx1OTZDNlx1NEUyRFx1NEUwRFx1NTE0MVx1OEEzMVx1NTNDM1x1NzE2N1x1MzAwMgotIyBUcmFpbGluZyBNaXNjCi0gICAgICAgIENvbnRlbnRJbGxlZ2FsSW5UcmFpbGluZ01pc2M9XHU1QzNFXHU3QUVGXHU2QkI1XHU4NDNEXHU0RTJEXHU0RTBEXHU1MTQxXHU4QTMxXHU1MTY3XHU1QkI5XHUzMDAyCi0gICAgICAgIFJlZmVyZW5jZUlsbGVnYWxJblRyYWlsaW5nTWlzYz1cdTVDM0VcdTdBRUZcdTZCQjVcdTg0M0RcdTRFMkRcdTRFMERcdTUxNDFcdThBMzFcdTUzQzNcdTcxNjdcdTMwMDIKLSAgICAgICAgCi0jIDIuOSBTdGFuZGFsb25lIERvY3VtZW50IERlY2xhcmF0aW9uCi0gICAgICAgIFNERGVjbEludmFsaWQgPSBcdTczNjhcdTdBQ0JcdTY1ODdcdTRFRjZcdTVCQTNcdTU0NEFcdTUwM0NcdTVGQzVcdTk4MDhcdTY2MkYgInllcyIgXHU2MjE2ICJubyJcdUZGMENcdTgwMENcdTk3NUUgInswfSJcdTMwMDIKLSAgICAgICAgU0REZWNsTmFtZUludmFsaWQgPSBYTUwgXHU1QkEzXHU1NDRBXHU0RTJEXHU3Njg0XHU3MzY4XHU3QUNCXHU1NDBEXHU3QTMxXHU1M0VGXHU4MEZEXHU2MkZDXHU5MzJGXHU0RTg2XHUzMDAyCi0jIDIuMTIgTGFuZ3VhZ2UgSWRlbnRpZmljYXRpb24KLSAgICAgICAgWE1MTGFuZ0ludmFsaWQgPSB4bWw6bGFuZyBcdTVDNkNcdTYwMjdcdTUwM0MgInswfSIgXHU3MEJBXHU3MTIxXHU2NTQ4XHU3Njg0XHU4QTlFXHU4QTAwIElEXHUzMDAyCi0jIDMuIExvZ2ljYWwgU3RydWN0dXJlcwotICAgICAgICBFVGFnUmVxdWlyZWQgPSBcdTUxNDNcdTdEMjBcdTk4NUVcdTU3OEIgInswfSIgXHU1RkM1XHU5ODA4XHU3NTMxXHU5MTREXHU1QzBEXHU3Njg0XHU3RDUwXHU2NzVGXHU2QTE5XHU4QTE4ICI8L3swfT4iIFx1N0Q0Mlx1NkI2Mlx1MzAwMgotIyAzLjEgU3RhcnQtVGFncywgRW5kLVRhZ3MsIGFuZCBFbXB0eS1FbGVtZW50IFRhZ3MKLSAgICAgICAgRWxlbWVudFVudGVybWluYXRlZCA9IFx1NTE0M1x1N0QyMFx1OTg1RVx1NTc4QiAiezB9IiBcdTRFNEJcdTVGOENcdTVGQzVcdTk4MDhcdTdEQ0FcdTYzQTVcdTVDNkNcdTYwMjdcdThBMkRcdTVCOUEgIj4iIFx1NjIxNiAiLz4iXHUzMDAyCi0gICAgICAgIEVxUmVxdWlyZWRJbkF0dHJpYnV0ZSA9IFx1OTVEQ1x1ODA2Rlx1NTE0M1x1N0QyMFx1OTg1RVx1NTc4QiAiezB9IiBcdTc2ODRcdTVDNkNcdTYwMjdcdTU0MERcdTdBMzEgInsxfSIgXHU0RTRCXHU1RjhDXHU1RkM1XHU5ODA4XHU3RENBXHU2M0E1ICcnID0gJycgXHU1QjU3XHU1MTQzXHUzMDAyCi0gICAgICAgIE9wZW5RdW90ZUV4cGVjdGVkID0gXHU5NURDXHU4MDZGXHU1MTQzXHU3RDIwXHU5ODVFXHU1NzhCICJ7MH0iIFx1NzY4NFx1NUM2Q1x1NjAyNyAiezF9IiBcdTk4MTBcdTY3MUZcdTY3MDlcdTk1OEJcdTk4MkRcdTVGMTVcdTg2NUZcdTMwMDIKLSAgICAgICAgQ2xvc2VRdW90ZUV4cGVjdGVkID0gXHU5NURDXHU4MDZGXHU1MTQzXHU3RDIwXHU5ODVFXHU1NzhCICJ7MH0iIFx1NzY4NFx1NUM2Q1x1NjAyNyAiezF9IiBcdTk4MTBcdTY3MUZcdTY3MDlcdTdENTBcdTY3NUZcdTVGMTVcdTg2NUZcdTMwMDIKLSAgICAgICAgQXR0cmlidXRlTm90VW5pcXVlID0gXHU1REYyXHU3RDkzXHU3MEJBXHU1MTQzXHU3RDIwICJ7MH0iIFx1NjMwN1x1NUI5QVx1NUM2Q1x1NjAyNyAiezF9Ilx1MzAwMgotICAgICAgICBBdHRyaWJ1dGVOU05vdFVuaXF1ZSA9IFx1NURGMlx1N0Q5M1x1NzBCQVx1NTE0M1x1N0QyMCAiezB9IiBcdTYzMDdcdTVCOUFcdTkwMjNcdTdENTBcdTU0N0RcdTU0MERcdTdBN0FcdTk1OTMgInsyfSIgXHU3Njg0XHU1QzZDXHU2MDI3ICJ7MX0iXHUzMDAyCi0gICAgICAgIEVUYWdVbnRlcm1pbmF0ZWQgPSBcdTUxNDNcdTdEMjBcdTk4NUVcdTU3OEIgInswfSIgXHU3Njg0XHU3RDUwXHU2NzVGXHU2QTE5XHU4QTE4XHU3RDUwXHU1QzNFXHU1RkM1XHU5ODA4XHU2NjJGICcnPicnIFx1NTIwNlx1NzU0Q1x1NUI1N1x1NTE0M1x1MzAwMgotICAgICAgICBNYXJrdXBOb3RSZWNvZ25pemVkSW5Db250ZW50ID0gXHU1MTQzXHU3RDIwXHU3Njg0XHU1MTY3XHU1QkI5XHU1RkM1XHU5ODA4XHU3NTMxXHU2ODNDXHU1RjBGXHU2QjYzXHU3OEJBXHU3Njg0XHU0RjREXHU2M0NGXHU4RkYwXHU4Q0M3XHU2NTk5XHU2MjE2XHU2QTE5XHU4QTE4XHU2MjQwXHU3RDQ0XHU2MjEwXHUzMDAyCi0gICAgICAgIERvY3R5cGVJbGxlZ2FsSW5Db250ZW50ID0gXHU1MTY3XHU1QkI5XHU0RTBEXHU1MTQxXHU4QTMxIERPQ1RZUEVcdTMwMDIKLSMgNC4xIENoYXJhY3RlciBhbmQgRW50aXR5IFJlZmVyZW5jZXMKLSAgICAgICAgUmVmZXJlbmNlVW50ZXJtaW5hdGVkID0gXHU1M0MzXHU3MTY3XHU1RkM1XHU5ODA4XHU3NTMxICc7JyBcdTUyMDZcdTc1NENcdTVCNTdcdTUxNDNcdTdENDJcdTZCNjJcdTMwMDIKLSMgNC4zLjIgV2VsbC1Gb3JtZWQgUGFyc2VkIEVudGl0aWVzCi0gICAgICAgIFJlZmVyZW5jZU5vdEluT25lRW50aXR5ID0gXHU1M0MzXHU3MTY3XHU1RkM1XHU5ODA4XHU2NTc0XHU1MDBCXHU1MzA1XHU1NDJCXHU1NzI4XHU3NkY4XHU1NDBDXHU3Njg0XHU1MjU2XHU2NzkwXHU1QkU2XHU5QUQ0XHU1MTY3XHUzMDAyCi0gICAgICAgIEVsZW1lbnRFbnRpdHlNaXNtYXRjaCA9IFx1NTE0M1x1N0QyMCAiezB9IiBcdTc2ODRcdTk1OEJcdTk4MkRcdTgyMDdcdTdENTBcdTVDM0VcdTVGQzVcdTk4MDhcdTU3MjhcdTc2RjhcdTU0MENcdTVCRTZcdTlBRDRcdTUxNjdcdTMwMDIKLSAgICAgICAgTWFya3VwRW50aXR5TWlzbWF0Y2g9WE1MIFx1NjU4N1x1NEVGNlx1N0Q1MFx1NjlDQlx1NzY4NFx1OTU4Qlx1OTgyRFx1ODIwN1x1N0Q1MFx1NUMzRVx1NUZDNVx1OTgwOFx1NTcyOFx1NzZGOFx1NTQwQ1x1NUJFNlx1OUFENFx1NTE2N1x1MzAwMgotICAgICAgICAKLSMgTWVzc2FnZXMgY29tbW9uIHRvIERvY3VtZW50IGFuZCBEVEQKLSMgMi4yIENoYXJhY3RlcnMKLSAgICAgICAgSW52YWxpZENoYXJJbkF0dFZhbHVlID0gXHU1NzI4XHU1QzZDXHU2MDI3ICJ7MX0iIFx1NzY4NFx1NTAzQ1x1NEUyRFx1NjI3RVx1NTIzMFx1NzEyMVx1NjU0OFx1NzY4NCBYTUwgXHU1QjU3XHU1MTQzIChVbmljb2RlOiAweHsyfSkgXHU0RTE0XHU1MTQzXHU3RDIwXHU3MEJBICJ7MH0iXHUzMDAyCi0gICAgICAgIEludmFsaWRDaGFySW5Db21tZW50ID0gXHU1NzI4XHU4QTNCXHU4OUUzXHU0RTJEXHU2MjdFXHU1MjMwXHU3MTIxXHU2NTQ4XHU3Njg0IFhNTCBcdTVCNTdcdTUxNDMgKFVuaWNvZGU6IDB4ezB9KVx1MzAwMgotICAgICAgICBJbnZhbGlkQ2hhckluUEkgPSBcdTU3MjhcdTg2NTVcdTc0MDZcdTYzMDdcdTc5M0FcdTRFMkRcdTYyN0VcdTUyMzBcdTcxMjFcdTY1NDhcdTc2ODQgWE1MIFx1NUI1N1x1NTE0MyAoVW5pY29kZTogMHh7MH0pXHUzMDAyCi0gICAgICAgIEludmFsaWRDaGFySW5JbnRlcm5hbFN1YnNldCA9IFx1NTcyOCBEVEQgXHU1MTY3XHU5MEU4XHU1QjUwXHU5NkM2XHU0RTJEXHU2MjdFXHU1MjMwXHU3MTIxXHU2NTQ4XHU3Njg0IFhNTCBcdTVCNTdcdTUxNDMgKFVuaWNvZGU6IDB4ezB9KVx1MzAwMgotICAgICAgICBJbnZhbGlkQ2hhckluVGV4dERlY2wgPSBcdTU3MjhcdTY1ODdcdTVCNTdcdTVCQTNcdTU0NEFcdTRFMkRcdTYyN0VcdTUyMzBcdTcxMjFcdTY1NDhcdTc2ODQgWE1MIFx1NUI1N1x1NTE0MyAoVW5pY29kZTogMHh7MH0pXHUzMDAyCi0jIDIuMyBDb21tb24gU3ludGFjdGljIENvbnN0cnVjdHMKLSAgICAgICAgUXVvdGVSZXF1aXJlZEluQXR0VmFsdWUgPSBcdTVDNkNcdTYwMjcgInsxfSIgXHU3Njg0XHU1MDNDXHU5NThCXHU5ODJEXHU1RkM1XHU5ODA4XHU3MEJBXHU1NUFFXHU1RjE1XHU4NjVGXHU2MjE2XHU5NkQ5XHU1RjE1XHU4NjVGXHU1QjU3XHU1MTQzXHUzMDAyCi0gICAgICAgIExlc3N0aGFuSW5BdHRWYWx1ZSA9IFx1OTVEQ1x1ODA2Rlx1NTE0M1x1N0QyMFx1OTg1RVx1NTc4QiAiezB9IiBcdTRFNEJcdTVDNkNcdTYwMjcgInsxfSIgXHU3Njg0XHU1MDNDXHU0RTBEXHU1M0VGXHU1MzA1XHU1NDJCICcnPCcnIFx1NUI1N1x1NTE0M1x1MzAwMgotICAgICAgICBBdHRyaWJ1dGVWYWx1ZVVudGVybWluYXRlZCA9IFx1NUM2Q1x1NjAyNyAiezF9IiBcdTc2ODRcdTUwM0NcdTdENTBcdTVDM0VcdTVGQzVcdTk4MDhcdTY2MkZcdTkxNERcdTVDMERcdTc2ODRcdTVGMTVcdTg2NUZcdTVCNTdcdTUxNDNcdTMwMDIKLSMgMi41IENvbW1lbnRzCi0gICAgICAgIEludmFsaWRDb21tZW50U3RhcnQgPSBcdThBM0JcdTg5RTNcdTk1OEJcdTk4MkRcdTVGQzVcdTk4MDhcdTcwQkEgIjwhLS0iXHUzMDAyCi0gICAgICAgIERhc2hEYXNoSW5Db21tZW50ID0gXHU4QTNCXHU4OUUzXHU0RTBEXHU1MTQxXHU4QTMxXHU1QjU3XHU0RTMyICItLSJcdTMwMDIKLSAgICAgICAgQ29tbWVudFVudGVybWluYXRlZCA9IFx1OEEzQlx1ODlFM1x1N0Q1MFx1NUMzRVx1NUZDNVx1OTgwOFx1NzBCQSAiLS0+Ilx1MzAwMgotICAgICAgICBDT01NRU5UX05PVF9JTl9PTkVfRU5USVRZID0gXHU4QTNCXHU4OUUzXHU2NzJBXHU1MzA1XHU1NDJCXHU1NzI4XHU3NkY4XHU1NDBDXHU1QkU2XHU5QUQ0XHU1MTY3XHUzMDAyCi0jIDIuNiBQcm9jZXNzaW5nIEluc3RydWN0aW9ucwotICAgICAgICBQSVRhcmdldFJlcXVpcmVkID0gXHU4NjU1XHU3NDA2XHU2MzA3XHU3OTNBXHU3Njg0XHU5NThCXHU5ODJEXHU1RkM1XHU5ODA4XHU2NjJGXHU3NkVFXHU2QTE5XHU3Njg0XHU1NDBEXHU3QTMxXHUzMDAyCi0gICAgICAgIFNwYWNlUmVxdWlyZWRJblBJID0gXHU4NjU1XHU3NDA2XHU2MzA3XHU3OTNBXHU3NkVFXHU2QTE5XHU4MjA3XHU4Q0M3XHU2NTk5XHU0RTRCXHU5NTkzXHU5NzAwXHU4OTgxXHU3QTdBXHU2ODNDXHUzMDAyCi0gICAgICAgIFBJVW50ZXJtaW5hdGVkID0gXHU4NjU1XHU3NDA2XHU2MzA3XHU3OTNBXHU3RDUwXHU1QzNFXHU1RkM1XHU5ODA4XHU2NjJGICI/PiJcdTMwMDIKLSAgICAgICAgUmVzZXJ2ZWRQSVRhcmdldCA9IFx1NEUwRFx1NTE0MVx1OEEzMVx1N0IyNlx1NTQwOCAiW3hYXVttTV1bbExdIiBcdTc2ODRcdTg2NTVcdTc0MDZcdTYzMDdcdTc5M0FcdTc2RUVcdTZBMTlcdTMwMDIKLSAgICAgICAgUElfTk9UX0lOX09ORV9FTlRJVFkgPSBcdTg2NTVcdTc0MDZcdTYzMDdcdTc5M0FcdTY3MkFcdTUzMDVcdTU0MkJcdTU3MjhcdTc2RjhcdTU0MENcdTVCRTZcdTlBRDRcdTUxNjdcdTMwMDIKLSMgMi44IFByb2xvZyBhbmQgRG9jdW1lbnQgVHlwZSBEZWNsYXJhdGlvbgotICAgICAgICBWZXJzaW9uSW5mb0ludmFsaWQgPSBcdTcxMjFcdTY1NDhcdTc2ODRcdTcyNDhcdTY3MkMgInswfSJcdTMwMDIKLSAgICAgICAgVmVyc2lvbk5vdFN1cHBvcnRlZCA9IFx1NEUwRFx1NjUyRlx1NjNGNCBYTUwgXHU3MjQ4XHU2NzJDICJ7MH0iXHVGRjBDXHU1MEM1XHU2NTJGXHU2M0Y0IFhNTCAxLjBcdTMwMDIKLSAgICAgICAgVmVyc2lvbk5vdFN1cHBvcnRlZDExID0gXHU0RTBEXHU2NTJGXHU2M0Y0IFhNTCBcdTcyNDhcdTY3MkMgInswfSJcdUZGMENcdTUwQzVcdTY1MkZcdTYzRjQgWE1MIDEuMCBcdTgyMDcgWE1MIDEuMVx1MzAwMgotICAgICAgICBWZXJzaW9uTWlzbWF0Y2g9IFx1NUJFNlx1OUFENFx1NEUwRFx1NTNFRlx1NTMwNVx1NTQyQlx1OEYwM1x1NjVCMFx1NzI0OFx1NjcyQ1x1NzY4NFx1NTE3Nlx1NEVENlx1NUJFNlx1OUFENFx1MzAwMgotIyA0LjEgQ2hhcmFjdGVyIGFuZCBFbnRpdHkgUmVmZXJlbmNlcwotICAgICAgICBEaWdpdFJlcXVpcmVkSW5DaGFyUmVmID0gXHU1NzI4XHU1QjU3XHU1MTQzXHU1M0MzXHU3MTY3XHU0RTJEXHVGRjBDXHU1MzQxXHU5MDMyXHU0RjREXHU4ODY4XHU3OTNBXHU2Q0Q1XHU1RkM1XHU5ODA4XHU3RENBXHU2M0E1XHU1NzI4ICImIyIgXHU0RTRCXHU1RjhDXHUzMDAyCi0gICAgICAgIEhleGRpZ2l0UmVxdWlyZWRJbkNoYXJSZWYgPSBcdTU3MjhcdTVCNTdcdTUxNDNcdTUzQzNcdTcxNjdcdTRFMkRcdUZGMENcdTUzNDFcdTUxNkRcdTkwMzJcdTRGNERcdTg4NjhcdTc5M0FcdTZDRDVcdTVGQzVcdTk4MDhcdTdEQ0FcdTYzQTVcdTU3MjggIiYjeCIgXHU0RTRCXHU1RjhDXHUzMDAyCi0gICAgICAgIFNlbWljb2xvblJlcXVpcmVkSW5DaGFyUmVmID0gXHU1QjU3XHU1MTQzXHU1M0MzXHU3MTY3XHU3Njg0XHU3RDUwXHU1QzNFXHU1RkM1XHU5ODA4XHU2NjJGICc7JyBcdTUyMDZcdTc1NENcdTVCNTdcdTUxNDNcdTMwMDIKLSAgICAgICAgSW52YWxpZENoYXJSZWYgPSBcdTVCNTdcdTUxNDNcdTUzQzNcdTcxNjcgIiYjezB9IiBcdTcwQkFcdTcxMjFcdTY1NDhcdTc2ODQgWE1MIFx1NUI1N1x1NTE0M1x1MzAwMgotICAgICAgICBOYW1lUmVxdWlyZWRJblJlZmVyZW5jZSA9IFx1NTcyOFx1NUJFNlx1OUFENFx1NTNDM1x1NzE2N1x1NEUyRFx1RkYwQ1x1NUJFNlx1OUFENFx1NTQwRFx1N0EzMVx1NUZDNVx1OTgwOFx1N0RDQVx1NjNBNVx1NTcyOCAnJicgXHU0RTRCXHU1RjhDXHUzMDAyCi0gICAgICAgIFNlbWljb2xvblJlcXVpcmVkSW5SZWZlcmVuY2UgPSBcdTVCRTZcdTlBRDQgInswfSIgXHU3Njg0XHU1M0MzXHU3MTY3XHU3RDUwXHU1QzNFXHU1RkM1XHU5ODA4XHU3MEJBICcnOycnIFx1NTIwNlx1NzU0Q1x1NUI1N1x1NTE0M1x1MzAwMgotIyA0LjMuMSBUaGUgVGV4dCBEZWNsYXJhdGlvbgotICAgICAgICBUZXh0RGVjbE11c3RCZUZpcnN0ID0gXHU2NTg3XHU1QjU3XHU1QkEzXHU1NDRBXHU1MEM1XHU4MEZEXHU1MUZBXHU3M0ZFXHU1NzI4XHU1OTE2XHU5MEU4XHU1MjU2XHU2NzkwXHU1QkU2XHU5QUQ0XHU3Njg0XHU5NThCXHU5ODJEXHUzMDAyCi0gICAgICAgIEVxUmVxdWlyZWRJblRleHREZWNsID0gXHU1NzI4XHU2NTg3XHU1QjU3XHU1QkEzXHU1NDRBXHU0RTJEXHVGRjBDJycgPSAnJyBcdTVCNTdcdTUxNDNcdTVGQzVcdTk4MDhcdTdEQ0FcdTYzQTVcdTU3MjggInswfSIgXHU0RTRCXHU1RjhDXHUzMDAyCi0gICAgICAgIFF1b3RlUmVxdWlyZWRJblRleHREZWNsID0gXHU2NTg3XHU1QjU3XHU1QkEzXHU1NDRBXHU0RTJEICJ7MH0iIFx1NEU0Qlx1NUY4Q1x1NzY4NFx1NTAzQ1x1NUZDNVx1OTgwOFx1NjYyRlx1NEVFNVx1NUYxNVx1ODY1Rlx1NjJFQ1x1NEY0Rlx1NzY4NFx1NUI1N1x1NEUzMlx1MzAwMgotICAgICAgICBDbG9zZVF1b3RlTWlzc2luZ0luVGV4dERlY2wgPSBcdTY1ODdcdTVCNTdcdTVCQTNcdTU0NEFcdTRFMkRcdUZGMENcdTkwN0FcdTZGMEYgInswfSIgXHU0RTRCXHU1RjhDXHU3Njg0XHU1MDNDXHU3Njg0XHU3RDUwXHU2NzVGXHU1RjE1XHU4NjVGXHUzMDAyCi0gICAgICAgIFNwYWNlUmVxdWlyZWRCZWZvcmVWZXJzaW9uSW5UZXh0RGVjbCA9IFx1NTcyOFx1NjU4N1x1NUI1N1x1NUJBM1x1NTQ0QVx1NEUyRFx1RkYwQ1x1NzI0OFx1NjcyQ1x1ODY1Qlx1NjRFQ1x1NUM2Q1x1NjAyN1x1NEU0Qlx1NTI0RFx1OTcwMFx1ODk4MVx1NjcwOVx1N0E3QVx1NjgzQ1x1MzAwMgotICAgICAgICBTcGFjZVJlcXVpcmVkQmVmb3JlRW5jb2RpbmdJblRleHREZWNsID0gXHU1NzI4XHU2NTg3XHU1QjU3XHU1QkEzXHU1NDRBXHU0RTJEXHVGRjBDXHU3REU4XHU3OEJDXHU4NjVCXHU2NEVDXHU1QzZDXHU2MDI3XHU0RTRCXHU1MjREXHU5NzAwXHU4OTgxXHU2NzA5XHU3QTdBXHU2ODNDXHUzMDAyCi0gICAgICAgIFRleHREZWNsVW50ZXJtaW5hdGVkID0gXHU2NTg3XHU1QjU3XHU1QkEzXHU1NDRBXHU3RDUwXHU1QzNFXHU1RkM1XHU5ODA4XHU2NjJGICI/PiJcdTMwMDIKLSAgICAgICAgRW5jb2RpbmdEZWNsUmVxdWlyZWQgPSBcdTY1ODdcdTVCNTdcdTVCQTNcdTU0NEFcdTRFMkRcdTk3MDBcdTg5ODFcdTdERThcdTc4QkNcdTVCQTNcdTU0NEFcdTMwMDIKLSAgICAgICAgTm9Nb3JlUHNldWRvQXR0cmlidXRlcyA9IFx1NEUwRFx1NTE0MVx1OEEzMVx1NjZGNFx1NTkxQVx1NzY4NFx1ODY1Qlx1NjRFQ1x1NUM2Q1x1NjAyN1x1MzAwMgotICAgICAgICBNb3JlUHNldWRvQXR0cmlidXRlcyA9IFx1OTgxMFx1NjcxRlx1NjZGNFx1NTkxQVx1NzY4NFx1ODY1Qlx1NjRFQ1x1NUM2Q1x1NjAyN1x1MzAwMgotICAgICAgICBQc2V1ZG9BdHRyTmFtZUV4cGVjdGVkID0gXHU5ODEwXHU2NzFGXHU0RTAwXHU1MDBCXHU4NjVCXHU2NEVDXHU1QzZDXHU2MDI3XHU1NDBEXHU3QTMxXHUzMDAyCi0jIDQuMy4yIFdlbGwtRm9ybWVkIFBhcnNlZCBFbnRpdGllcwotICAgICAgICBDb21tZW50Tm90SW5PbmVFbnRpdHkgPSBcdThBM0JcdTg5RTNcdTVGQzVcdTk4MDhcdTY1NzRcdTUwMEJcdTUzMDVcdTU0MkJcdTU3MjhcdTc2RjhcdTU0MENcdTc2ODRcdTUyNTZcdTY3OTBcdTVCRTZcdTlBRDRcdTUxNjdcdTMwMDIKLSAgICAgICAgUElOb3RJbk9uZUVudGl0eSA9IFx1ODY1NVx1NzQwNlx1NjMwN1x1NzkzQVx1NUZDNVx1OTgwOFx1NjU3NFx1NTAwQlx1NTMwNVx1NTQyQlx1NTcyOFx1NzZGOFx1NTQwQ1x1NzY4NFx1NTI1Nlx1Njc5MFx1NUJFNlx1OUFENFx1NTE2N1x1MzAwMgotIyA0LjMuMyBDaGFyYWN0ZXIgRW5jb2RpbmcgaW4gRW50aXRpZXMKLSAgICAgICAgRW5jb2RpbmdEZWNsSW52YWxpZCA9IFx1NzEyMVx1NjU0OFx1NzY4NFx1N0RFOFx1NzhCQ1x1NTQwRFx1N0EzMSAiezB9Ilx1MzAwMgotICAgICAgICBFbmNvZGluZ0J5dGVPcmRlclVuc3VwcG9ydGVkID0gXHU0RTBEXHU2NTJGXHU2M0Y0XHU3REU4XHU3OEJDICJ7MH0iIFx1NzY4NFx1NjMwN1x1NUI5QVx1NEY0RFx1NTE0M1x1N0Q0NFx1OTgwNlx1NUU4Rlx1MzAwMgotICAgICAgICBJbnZhbGlkQnl0ZSA9IHsxfS1ieXRlIFVURi04IFx1NUU4Rlx1NTIxN1x1NzY4NFx1NzEyMVx1NjU0OFx1NEY0RFx1NTE0M1x1N0Q0NCB7MH1cdTMwMDIKLSAgICAgICAgRXhwZWN0ZWRCeXRlID0gezF9LWJ5dGUgVVRGLTggXHU1RThGXHU1MjE3XHU5ODEwXHU2NzFGXHU3Njg0XHU0RjREXHU1MTQzXHU3RDQ0IHswfVx1MzAwMgotICAgICAgICBJbnZhbGlkSGlnaFN1cnJvZ2F0ZSA9IFVURi04IFx1NUU4Rlx1NTIxN1x1NEUyRFx1OUFEOFx1NjZGRlx1NEVFM1x1NEY0RFx1NTE0M1x1NEUwRFx1NTNFRlx1OEQ4NVx1OTA0RSAweDEwXHVGRjBDXHU0RjQ2XHU2MjdFXHU1MjMwIDB4ezB9XHUzMDAyCi0gICAgICAgIE9wZXJhdGlvbk5vdFN1cHBvcnRlZCA9IHsxfSBcdThCODBcdTUzRDZcdTU2NjhcdTRFMERcdTY1MkZcdTYzRjRcdTRGNUNcdTY5NkQgInswfSJcdTMwMDIKLSAgICAgICAgSW52YWxpZEFTQ0lJID0gXHU3RDQ0XHU1MTQzXHU3RDQ0ICJ7MH0iIFx1NEUwRFx1NjYyRiAoNyBcdTRGNERcdTUxNDMpIEFTQ0lJIFx1NUI1N1x1NTE0M1x1OTZDNlx1NzY4NFx1NjIxMFx1NTRFMVx1MzAwMgotICAgICAgICBDaGFyQ29udmVyc2lvbkZhaWx1cmUgPSBcdTZDN0FcdTVCOUFcdTRGN0ZcdTc1MjhcdTcyNzlcdTVCOUFcdTdERThcdTc4QkNcdTc2ODRcdTVCRTZcdTlBRDRcdUZGMENcdTU3MjhcdThBNzJcdTdERThcdTc4QkNcdTRFMkRcdTRFMERcdTUzRUZcdTUzMDVcdTU0MkJcdTcxMjFcdTY1NDhcdTc2ODRcdTVFOEZcdTUyMTdcdTMwMDIKLSAgICAgICAgCi0jIERURCBNZXNzYWdlcwotIyAyLjIgQ2hhcmFjdGVycwotICAgICAgICBJbnZhbGlkQ2hhckluRW50aXR5VmFsdWUgPSBcdTU3MjhcdTY1ODdcdTVCNTdcdTVCRTZcdTlBRDRcdTUwM0NcdTRFMkRcdTYyN0VcdTUyMzBcdTcxMjFcdTY1NDhcdTc2ODQgWE1MIFx1NUI1N1x1NTE0MyAoVW5pY29kZTogMHh7MH0pXHUzMDAyCi0gICAgICAgIEludmFsaWRDaGFySW5FeHRlcm5hbFN1YnNldCA9IFx1NTcyOCBEVEQgXHU1OTE2XHU5MEU4XHU1QjUwXHU5NkM2XHU0RTJEXHU2MjdFXHU1MjMwXHU3MTIxXHU2NTQ4XHU3Njg0IFhNTCBcdTVCNTdcdTUxNDMgKFVuaWNvZGU6IDB4ezB9KVx1MzAwMgotICAgICAgICBJbnZhbGlkQ2hhckluSWdub3JlU2VjdCA9IFx1NTcyOFx1NjM5Mlx1OTY2NFx1NzY4NFx1Njg5RFx1NEVGNlx1NjAyN1x1NkJCNVx1ODQzRFx1NEUyRFx1NjI3RVx1NTIzMFx1NzEyMVx1NjU0OFx1NzY4NCBYTUwgXHU1QjU3XHU1MTQzIChVbmljb2RlOiAweHswfSlcdTMwMDIKLSAgICAgICAgSW52YWxpZENoYXJJblB1YmxpY0lEID0gXHU1NzI4XHU1MTZDXHU3NTI4IElEIFx1NEUyRFx1NjI3RVx1NTIzMFx1NzEyMVx1NjU0OFx1NzY4NCBYTUwgXHU1QjU3XHU1MTQzIChVbmljb2RlOiAweHswfSlcdTMwMDIKLSAgICAgICAgSW52YWxpZENoYXJJblN5c3RlbUlEID0gXHU1NzI4XHU3Q0ZCXHU3RDcxIElEIFx1NEUyRFx1NjI3RVx1NTIzMFx1NzEyMVx1NjU0OFx1NzY4NCBYTUwgXHU1QjU3XHU1MTQzIChVbmljb2RlOiAweHswfSlcdTMwMDIKLSMgMi4zIENvbW1vbiBTeW50YWN0aWMgQ29uc3RydWN0cwotICAgICAgICBTcGFjZVJlcXVpcmVkQWZ0ZXJTWVNURU0gPSBcdTU3MjggRE9DVFlQRSBcdTVCQTNcdTU0NEFcdTRFMkRcdTk1RENcdTkzNzVcdTVCNTcgU1lTVEVNIFx1NEU0Qlx1NUY4Q1x1OTcwMFx1ODk4MVx1N0E3QVx1NjgzQ1x1MzAwMgotICAgICAgICBRdW90ZVJlcXVpcmVkSW5TeXN0ZW1JRCA9IFx1N0NGQlx1N0Q3MSBJRCBcdTc2ODRcdTk1OEJcdTk4MkRcdTVGQzVcdTk4MDhcdTcwQkFcdTU1QUVcdTVGMTVcdTg2NUZcdTYyMTZcdTk2RDlcdTVGMTVcdTg2NUZcdTVCNTdcdTUxNDNcdTMwMDIKLSAgICAgICAgU3lzdGVtSURVbnRlcm1pbmF0ZWQgPSBcdTdDRkJcdTdENzEgSUQgXHU3Njg0XHU3RDUwXHU1QzNFXHU1RkM1XHU5ODA4XHU2NjJGXHU5MTREXHU1QzBEXHU3Njg0XHU1RjE1XHU4NjVGXHU1QjU3XHU1MTQzXHUzMDAyCi0gICAgICAgIFNwYWNlUmVxdWlyZWRBZnRlclBVQkxJQyA9IFx1NTcyOCBET0NUWVBFIFx1NUJBM1x1NTQ0QVx1NEUyRFx1OTVEQ1x1OTM3NVx1NUI1NyBQVUJMSUMgXHU0RTRCXHU1RjhDXHU5NzAwXHU4OTgxXHU3QTdBXHU2ODNDXHUzMDAyCi0gICAgICAgIFF1b3RlUmVxdWlyZWRJblB1YmxpY0lEID0gXHU1MTZDXHU3NTI4IElEIFx1NzY4NFx1OTU4Qlx1OTgyRFx1NUZDNVx1OTgwOFx1NzBCQVx1NTVBRVx1NUYxNVx1ODY1Rlx1NjIxNlx1OTZEOVx1NUYxNVx1ODY1Rlx1NUI1N1x1NTE0M1x1MzAwMgotICAgICAgICBQdWJsaWNJRFVudGVybWluYXRlZCA9IFx1NTE2Q1x1NzUyOCBJRCBcdTc2ODRcdTdENTBcdTVDM0VcdTVGQzVcdTk4MDhcdTY2MkZcdTkxNERcdTVDMERcdTc2ODRcdTVGMTVcdTg2NUZcdTVCNTdcdTUxNDNcdTMwMDIKLSAgICAgICAgUHViaWRDaGFySWxsZWdhbCA9IFx1NTE2Q1x1NzUyOCBJRCBcdTRFMkRcdTRFMERcdTUxNDFcdThBMzFcdTVCNTdcdTUxNDMgKFVuaWNvZGU6IDB4ezB9KVx1MzAwMgotICAgICAgICBTcGFjZVJlcXVpcmVkQmV0d2VlblB1YmxpY0FuZFN5c3RlbSA9IHB1YmxpY0lkIFx1ODIwNyBzeXN0ZW1JZCBcdTRFNEJcdTk1OTNcdTk3MDBcdTg5ODFcdTdBN0FcdTY4M0NcdTMwMDIKLSMgMi44IFByb2xvZyBhbmQgRG9jdW1lbnQgVHlwZSBEZWNsYXJhdGlvbgotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX1JPT1RfRUxFTUVOVF9UWVBFX0lOX0RPQ1RZUEVERUNMID0gXHU1NzI4XHU2NTg3XHU0RUY2XHU5ODVFXHU1NzhCXHU1QkEzXHU1NDRBXHU0RTJEICI8IURPQ1RZUEUiIFx1NEU0Qlx1NUY4Q1x1OTcwMFx1ODk4MVx1N0E3QVx1NjgzQ1x1MzAwMgotICAgICAgICBNU0dfUk9PVF9FTEVNRU5UX1RZUEVfUkVRVUlSRUQgPSBcdTU3MjhcdTY1ODdcdTRFRjZcdTk4NUVcdTU3OEJcdTVCQTNcdTU0NEFcdTRFMkRcdUZGMENcdTY4MzlcdTUxNDNcdTdEMjBcdTk4NUVcdTU3OEJcdTVGQzVcdTk4MDhcdTUxRkFcdTczRkVcdTU3MjggIjwhRE9DVFlQRSIgXHU0RTRCXHU1RjhDXHUzMDAyCi0gICAgICAgIERvY3R5cGVkZWNsVW50ZXJtaW5hdGVkID0gXHU2ODM5XHU1MTQzXHU3RDIwXHU5ODVFXHU1NzhCICJ7MH0iIFx1NzY4NFx1NjU4N1x1NEVGNlx1OTg1RVx1NTc4Qlx1NUJBM1x1NTQ0QVx1N0Q1MFx1NUMzRVx1NUZDNVx1OTgwOFx1NzBCQSAnJz4nJ1x1MzAwMgotICAgICAgICBEb2N0eXBlZGVjbE5vdENsb3NlZCA9IFx1NjgzOVx1NTE0M1x1N0QyMFx1OTg1RVx1NTc4QiAiezB9IiBcdTc2ODRcdTY1ODdcdTRFRjZcdTk4NUVcdTU3OEJcdTVCQTNcdTU0NEFcdTdENTBcdTVDM0VcdTVGQzVcdTk4MDhcdTcwQkEgJyddJydcdTMwMDIKLSAgICAgICAgUEVSZWZlcmVuY2VXaXRoaW5NYXJrdXAgPSBEVEQgXHU1MTY3XHU5MEU4XHU1QjU3XHU5NkM2XHU3Njg0XHU2QTE5XHU4QTE4XHU1MTY3XHU0RTBEXHU4MEZEXHU1MUZBXHU3M0ZFXHU1M0MzXHU2NTc4XHU1QkU2XHU5QUQ0XHU1M0MzXHU3MTY3ICIlezB9OyJcdTMwMDIKLSAgICAgICAgTVNHX01BUktVUF9OT1RfUkVDT0dOSVpFRF9JTl9EVEQgPSBcdTY1ODdcdTRFRjZcdTk4NUVcdTU3OEJcdTVCQTNcdTU0NEFcdTUzMDVcdTU0MkJcdTYyMTZcdTYzMDdcdTU0MTFcdTc2ODRcdTZBMTlcdThBMThcdTVCQTNcdTU0NEFcdTVGQzVcdTk4MDhcdTY4M0NcdTVGMEZcdTZCNjNcdTc4QkFcdTMwMDIKLSMgMi4xMCBXaGl0ZSBTcGFjZSBIYW5kbGluZwotICAgICAgICBNU0dfWE1MX1NQQUNFX0RFQ0xBUkFUSU9OX0lMTEVHQUwgPSAieG1sOnNwYWNlIiBcdTc2ODRcdTVDNkNcdTYwMjdcdTVCQTNcdTU0NEFcdTVGQzVcdTk4MDhcdTYzMDdcdTVCOUFcdTcwQkFcdTUyMTdcdTgyMDlcdTk4NUVcdTU3OEJcdUZGMENcdTUxNzZcdTUzRUZcdTgwRkRcdTc2ODRcdTUwM0NcdTcwQkEgImRlZmF1bHQiIFx1ODIwNyAicHJlc2VydmUiXHUzMDAyCi0jIDMuMiBFbGVtZW50IFR5cGUgRGVjbGFyYXRpb25zCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfRUxFTUVOVF9UWVBFX0lOX0VMRU1FTlRERUNMID0gXHU1NzI4XHU1MTQzXHU3RDIwXHU5ODVFXHU1NzhCXHU1QkEzXHU1NDRBXHU0RTJEICI8IUVMRU1FTlQiIFx1NEU0Qlx1NUY4Q1x1OTcwMFx1ODk4MVx1N0E3QVx1NjgzQ1x1MzAwMgotICAgICAgICBNU0dfRUxFTUVOVF9UWVBFX1JFUVVJUkVEX0lOX0VMRU1FTlRERUNMID0gXHU1MTQzXHU3RDIwXHU5ODVFXHU1NzhCXHU1QkEzXHU1NDRBXHU0RTJEXHU5NzAwXHU4OTgxXHU1MTQzXHU3RDIwXHU5ODVFXHU1NzhCXHUzMDAyCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfQ09OVEVOVFNQRUNfSU5fRUxFTUVOVERFQ0wgPSBcdTU3MjhcdTUxNDNcdTdEMjBcdTk4NUVcdTU3OEJcdTVCQTNcdTU0NEFcdTRFMkRcdTUxNDNcdTdEMjBcdTk4NUVcdTU3OEIgInswfSIgXHU0RTRCXHU1RjhDXHU5NzAwXHU4OTgxXHU3QTdBXHU2ODNDXHUzMDAyCi0gICAgICAgIE1TR19DT05URU5UU1BFQ19SRVFVSVJFRF9JTl9FTEVNRU5UREVDTCA9IFx1NTcyOFx1NTE0M1x1N0QyMFx1OTg1RVx1NTc4Qlx1NUJBM1x1NTQ0QVx1NEUyRFx1NTE0M1x1N0QyMFx1OTg1RVx1NTc4QiAiezB9IiBcdTRFNEJcdTVGOENcdTk3MDBcdTg5ODFcdTk2NTBcdTUyMzZcdTY4OURcdTRFRjZcdTMwMDIKLSAgICAgICAgRWxlbWVudERlY2xVbnRlcm1pbmF0ZWQgPSBcdTUxNDNcdTdEMjBcdTk4NUVcdTU3OEIgInswfSIgXHU3Njg0XHU1QkEzXHU1NDRBXHU3RDUwXHU1QzNFXHU1RkM1XHU5ODA4XHU3MEJBICcnPicnXHUzMDAyCi0jIDMuMi4xIEVsZW1lbnQgQ29udGVudAotICAgICAgICBNU0dfT1BFTl9QQVJFTl9PUl9FTEVNRU5UX1RZUEVfUkVRVUlSRURfSU5fQ0hJTERSRU4gPSBcdTUxNDNcdTdEMjBcdTk4NUVcdTU3OEIgInswfSIgXHU3Njg0XHU1QkEzXHU1NDRBXHU0RTJEXHU5NzAwXHU4OTgxXHU0RTAwXHU1MDBCICcnKCcnIFx1NUI1N1x1NTE0M1x1NjIxNlx1NTE0M1x1N0QyMFx1OTg1RVx1NTc4Qlx1MzAwMgotICAgICAgICBNU0dfQ0xPU0VfUEFSRU5fUkVRVUlSRURfSU5fQ0hJTERSRU4gPSBcdTUxNDNcdTdEMjBcdTk4NUVcdTU3OEIgInswfSIgXHU3Njg0XHU1QkEzXHU1NDRBXHU0RTJEXHU5NzAwXHU4OTgxXHU0RTAwXHU1MDBCICcnKScnXHUzMDAyCi0jIDMuMi4yIE1peGVkIENvbnRlbnQKLSAgICAgICAgTVNHX0VMRU1FTlRfVFlQRV9SRVFVSVJFRF9JTl9NSVhFRF9DT05URU5UID0gXHU1MTQzXHU3RDIwXHU5ODVFXHU1NzhCICJ7MH0iIFx1NzY4NFx1NUJBM1x1NTQ0QVx1NEUyRFx1OTcwMFx1ODk4MVx1NEUwMFx1NTAwQlx1NTE0M1x1N0QyMFx1OTg1RVx1NTc4Qlx1MzAwMgotICAgICAgICBNU0dfQ0xPU0VfUEFSRU5fUkVRVUlSRURfSU5fTUlYRUQgPSBcdTUxNDNcdTdEMjBcdTk4NUVcdTU3OEIgInswfSIgXHU3Njg0XHU1QkEzXHU1NDRBXHU0RTJEXHU5NzAwXHU4OTgxXHU0RTAwXHU1MDBCICcnKScnXHUzMDAyCi0gICAgICAgIE1peGVkQ29udGVudFVudGVybWluYXRlZCA9IFx1NUI1MFx1OTgwNVx1NTE0M1x1N0QyMFx1NzY4NFx1OTg1RVx1NTc4Qlx1NTNEN1x1NTIzMFx1OTY1MFx1NTIzNlx1NjY0Mlx1RkYwQ1x1NkRGN1x1NTQwOFx1NTE2N1x1NUJCOVx1NkEyMVx1NTc4QiAiezB9IiBcdTc2ODRcdTdENTBcdTVDM0VcdTVGQzVcdTk4MDhcdTcwQkEgIikqIlx1MzAwMgotIyAzLjMgQXR0cmlidXRlLUxpc3QgRGVjbGFyYXRpb25zCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfRUxFTUVOVF9UWVBFX0lOX0FUVExJU1RERUNMID0gXHU1NzI4IGF0dHJpYnV0ZS1saXN0IFx1NUJBM1x1NTQ0QVx1NEUyRCAiPCFBVFRMSVNUIiBcdTRFNEJcdTVGOENcdTk3MDBcdTg5ODFcdTdBN0FcdTY4M0NcdTMwMDIKLSAgICAgICAgTVNHX0VMRU1FTlRfVFlQRV9SRVFVSVJFRF9JTl9BVFRMSVNUREVDTCA9IGF0dHJpYnV0ZS1saXN0IFx1NUJBM1x1NTQ0QVx1NEUyRFx1OTcwMFx1ODk4MVx1NTE0M1x1N0QyMFx1OTg1RVx1NTc4Qlx1MzAwMgotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX0FUVFJJQlVURV9OQU1FX0lOX0FUVERFRiA9IFx1NTE0M1x1N0QyMCAiezB9IiBcdTc2ODQgYXR0cmlidXRlLWxpc3QgXHU1QkEzXHU1NDRBXHU0RTJEXHVGRjBDXHU1QzZDXHU2MDI3XHU1NDBEXHU3QTMxXHU0RTRCXHU1MjREXHU5NzAwXHU4OTgxXHU3QTdBXHU2ODNDXHUzMDAyCi0gICAgICAgIEF0dE5hbWVSZXF1aXJlZEluQXR0RGVmID0gXHU1MTQzXHU3RDIwICJ7MH0iIFx1NzY4NCBhdHRyaWJ1dGUtbGlzdCBcdTVCQTNcdTU0NEFcdTVGQzVcdTk4MDhcdTYzMDdcdTVCOUFcdTVDNkNcdTYwMjdcdTU0MERcdTdBMzFcdTMwMDIKLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9BVFRUWVBFX0lOX0FUVERFRiA9IFx1NTE0M1x1N0QyMCAiezB9IiBcdTVDNkNcdTYwMjcgInsxfSIgXHU3Njg0XHU1QkEzXHU1NDRBXHU0RTJEXHVGRjBDXHU1QzZDXHU2MDI3XHU5ODVFXHU1NzhCXHU0RTRCXHU1MjREXHU5NzAwXHU4OTgxXHU3QTdBXHU2ODNDXHUzMDAyCi0gICAgICAgIEF0dFR5cGVSZXF1aXJlZEluQXR0RGVmID0gXHU1MTQzXHU3RDIwICJ7MH0iIFx1NUM2Q1x1NjAyNyAiezF9IiBcdTc2ODRcdTVCQTNcdTU0NEFcdTRFMkRcdTk3MDBcdTg5ODFcdTVDNkNcdTYwMjdcdTk4NUVcdTU3OEJcdTMwMDIKLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9ERUZBVUxUREVDTF9JTl9BVFRERUYgPSBcdTUxNDNcdTdEMjAgInswfSIgXHU1QzZDXHU2MDI3ICJ7MX0iIFx1NzY4NFx1NUJBM1x1NTQ0QVx1NEUyRFx1RkYwQ1x1NUM2Q1x1NjAyN1x1OTgxMFx1OEEyRFx1NEU0Qlx1NTI0RFx1OTcwMFx1ODk4MVx1N0E3QVx1NjgzQ1x1MzAwMgotICAgICAgICBNU0dfRFVQTElDQVRFX0FUVFJJQlVURV9ERUZJTklUSU9OID0gXHU3MEJBXHU2MzA3XHU1QjlBXHU1MTQzXHU3RDIwICJ7MH0iIFx1NzY4NFx1NzZGOFx1NTQwQ1x1NUM2Q1x1NjAyNyAiezF9IiBcdTYzRDBcdTRGOUJcdTRFODZcdThEODVcdTkwNEVcdTRFMDBcdTUwMEJcdTRFRTVcdTRFMEFcdTc2ODRcdTVDNkNcdTYwMjdcdTVCOUFcdTdGQTlcdTMwMDIKLSMgMy4zLjEgQXR0cmlidXRlIFR5cGVzCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9BRlRFUl9OT1RBVElPTl9JTl9OT1RBVElPTlRZUEUgPSAiezF9IiBcdTVDNkNcdTYwMjdcdTVCQTNcdTU0NEFcdTRFMkQgIk5PVEFUSU9OIiBcdTRFNEJcdTVGOENcdTVGQzVcdTk4MDhcdTY3MDlcdTdBN0FcdTY4M0NcdTMwMDIKLSAgICAgICAgTVNHX09QRU5fUEFSRU5fUkVRVUlSRURfSU5fTk9UQVRJT05UWVBFID0gXHU1NzI4ICJ7MX0iIFx1NUM2Q1x1NjAyN1x1NUJBM1x1NTQ0QVx1NEUyRFx1RkYwQycnKCcnIFx1NUI1N1x1NTE0M1x1NUZDNVx1OTgwOFx1N0RDQVx1NjNBNVx1NTcyOCAiTk9UQVRJT04iIFx1NEU0Qlx1NUY4Q1x1MzAwMgotICAgICAgICBNU0dfTkFNRV9SRVFVSVJFRF9JTl9OT1RBVElPTlRZUEUgPSAiezF9IiBcdTVDNkNcdTYwMjdcdTVCQTNcdTU0NEFcdTc2ODRcdTg4NjhcdTc5M0FcdTZDRDVcdTk4NUVcdTU3OEJcdTZFMDVcdTU1QUVcdTRFMkRcdUZGMENcdTk3MDBcdTg5ODFcdTg4NjhcdTc5M0FcdTZDRDVcdTU0MERcdTdBMzFcdTMwMDIKLSAgICAgICAgTm90YXRpb25UeXBlVW50ZXJtaW5hdGVkID0gXHU1NzI4ICJ7MX0iIFx1NUM2Q1x1NjAyN1x1NUJBM1x1NTQ0QVx1NEUyRFx1RkYwQ1x1ODg2OFx1NzkzQVx1NkNENVx1OTg1RVx1NTc4Qlx1NkUwNVx1NTVBRVx1NzY4NFx1N0Q1MFx1NUMzRVx1NUZDNVx1OTgwOFx1NzBCQSAnJyknJ1x1MzAwMgotICAgICAgICBNU0dfTk1UT0tFTl9SRVFVSVJFRF9JTl9FTlVNRVJBVElPTiA9ICJ7MX0iIFx1NUM2Q1x1NjAyN1x1NUJBM1x1NTQ0QVx1NzY4NFx1NTIxN1x1ODIwOVx1OTg1RVx1NTc4Qlx1NkUwNVx1NTVBRVx1NEUyRFx1RkYwQ1x1OTcwMFx1ODk4MVx1NTQwRFx1N0EzMVx1OEExOFx1ODY1Rlx1MzAwMgotICAgICAgICBFbnVtZXJhdGlvblVudGVybWluYXRlZCA9IFx1NTcyOCAiezF9IiBcdTVDNkNcdTYwMjdcdTVCQTNcdTU0NEFcdTRFMkRcdUZGMENcdTUyMTdcdTgyMDlcdTk4NUVcdTU3OEJcdTZFMDVcdTU1QUVcdTc2ODRcdTdENTBcdTVDM0VcdTVGQzVcdTk4MDhcdTcwQkEgJycpJydcdTMwMDIKLSAgICAgICAgTVNHX0RJU1RJTkNUX1RPS0VOU19JTl9FTlVNRVJBVElPTiA9IFx1NTE0M1x1N0QyMCAiezB9IiBcdTc2ODRcdTVDNkNcdTYwMjcgInsyfSIgXHU1QkEzXHU1NDRBXHU0RTJEXHVGRjBDXHU2MzA3XHU1QjlBXHU4RDg1XHU5MDRFXHU0RTAwXHU2QjIxXHU0RUU1XHU0RTBBXHU3Njg0XHU1MjE3XHU4MjA5XHU1MDNDICJ7MX0iXHUzMDAyXHU1NUFFXHU0RTAwIEVudW1lcmF0aW9uIFx1NUM2Q1x1NjAyN1x1NUJBM1x1NTQ0QVx1NEUyRFx1NzY4NCBOTVRPS0VOUyBcdTVGQzVcdTk4MDhcdTUxNjhcdTkwRThcdTkwRkRcdTRFMERcdTc2RjhcdTU0MENcdTMwMDIKLSAgICAgICAgTVNHX0RJU1RJTkNUX05PVEFUSU9OX0lOX0VOVU1FUkFUSU9OID0gXHU1MTQzXHU3RDIwICJ7MH0iIFx1NUM2Q1x1NjAyNyAiezJ9IiBcdTc2ODRcdTVCQTNcdTU0NEFcdTRFMkRcdUZGMENcdTYzMDdcdTVCOUFcdThEODVcdTkwNEVcdTRFMDBcdTZCMjFcdTRFRTVcdTRFMEFcdTc2ODRcdTUyMTdcdTgyMDlcdTUwM0MgInsxfSJcdTMwMDJcdTU1QUVcdTRFMDAgTm90YXRpb25UeXBlIFx1NUM2Q1x1NjAyN1x1NUJBM1x1NTQ0QVx1NEUyRFx1NzY4NCBOT1RBVElPTiBcdTU0MERcdTdBMzFcdTVGQzVcdTk4MDhcdTUxNjhcdTkwRThcdTkwRkRcdTRFMERcdTc2RjhcdTU0MENcdTMwMDIKLSMgMy4zLjIgQXR0cmlidXRlIERlZmF1bHRzCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9BRlRFUl9GSVhFRF9JTl9ERUZBVUxUREVDTCA9ICJ7MX0iIFx1NUM2Q1x1NjAyN1x1NUJBM1x1NTQ0QVx1NEUyRCAiRklYRUQiIFx1NEU0Qlx1NUY4Q1x1NUZDNVx1OTgwOFx1NjcwOVx1N0E3QVx1NjgzQ1x1MzAwMgotIyAzLjQgQ29uZGl0aW9uYWwgU2VjdGlvbnMKLSAgICAgICAgSW5jbHVkZVNlY3RVbnRlcm1pbmF0ZWQgPSBcdTUzMDVcdTU0MkJcdTY4OURcdTRFRjZcdTYwMjdcdTZCQjVcdTg0M0RcdTdENTBcdTVDM0VcdTVGQzVcdTk4MDhcdTY2MkYgIl1dPiJcdTMwMDIKLSAgICAgICAgSWdub3JlU2VjdFVudGVybWluYXRlZCA9IFx1NjM5Mlx1OTY2NFx1Njg5RFx1NEVGNlx1NjAyN1x1NkJCNVx1ODQzRFx1N0Q1MFx1NUMzRVx1NUZDNVx1OTgwOFx1NjYyRiAiXV0+Ilx1MzAwMgotIyA0LjEgQ2hhcmFjdGVyIGFuZCBFbnRpdHkgUmVmZXJlbmNlcwotICAgICAgICBOYW1lUmVxdWlyZWRJblBFUmVmZXJlbmNlID0gXHU1NzI4XHU1M0MzXHU2NTc4XHU1QkU2XHU5QUQ0XHU1M0MzXHU3MTY3XHU0RTJEXHVGRjBDXHU1QkU2XHU5QUQ0XHU1NDBEXHU3QTMxXHU1RkM1XHU5ODA4XHU3RENBXHU2M0E1XHU1NzI4ICclJyBcdTRFNEJcdTVGOENcdTMwMDIKLSAgICAgICAgU2VtaWNvbG9uUmVxdWlyZWRJblBFUmVmZXJlbmNlID0gXHU1M0MzXHU2NTc4XHU1QkU2XHU5QUQ0XHU1M0MzXHU3MTY3ICIlezB9OyIgXHU3Njg0XHU3RDUwXHU1QzNFXHU1RkM1XHU5ODA4XHU3MEJBICcnOycnIFx1NTIwNlx1NzU0Q1x1NUI1N1x1NTE0M1x1MzAwMgotIyA0LjIgRW50aXR5IERlY2xhcmF0aW9ucwotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX0VOVElUWV9OQU1FX0lOX0VOVElUWURFQ0wgPSBcdTU3MjhcdTVCRTZcdTlBRDRcdTVCQTNcdTU0NEFcdTRFMkQgIjwhRU5USVRZIiBcdTRFNEJcdTVGOENcdTk3MDBcdTg5ODFcdTdBN0FcdTY4M0NcdTMwMDIKLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9QRVJDRU5UX0lOX1BFREVDTCA9IFx1NTcyOFx1NTNDM1x1NjU3OFx1NUJFNlx1OUFENFx1NUJBM1x1NTQ0QVx1NEUyRFx1RkYwQyI8IUVOVElUWSIgXHU4MjA3ICclJyBcdTVCNTdcdTUxNDNcdTRFNEJcdTk1OTNcdTk3MDBcdTg5ODFcdTdBN0FcdTY4M0NcdTMwMDIKLSAgICAgICAgTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9FTlRJVFlfTkFNRV9JTl9QRURFQ0wgPSBcdTU3MjhcdTUzQzNcdTY1NzhcdTVCRTZcdTlBRDRcdTVCQTNcdTU0NEFcdTRFMkRcdUZGMEMnJScgXHU4MjA3XHU1QkU2XHU5QUQ0XHU1NDBEXHU3QTMxXHU0RTRCXHU5NTkzXHU5NzAwXHU4OTgxXHU3QTdBXHU2ODNDXHUzMDAyCi0gICAgICAgIE1TR19FTlRJVFlfTkFNRV9SRVFVSVJFRF9JTl9FTlRJVFlERUNMID0gXHU1QkU2XHU5QUQ0XHU1QkEzXHU1NDRBXHU0RTJEXHU5NzAwXHU4OTgxXHU1QkU2XHU5QUQ0XHU3Njg0XHU1NDBEXHU3QTMxXHUzMDAyCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9BRlRFUl9FTlRJVFlfTkFNRV9JTl9FTlRJVFlERUNMID0gXHU1NzI4XHU1QkU2XHU5QUQ0XHU1QkEzXHU1NDRBXHU0RTJEXHVGRjBDXHU1QkU2XHU5QUQ0XHU1NDBEXHU3QTMxICJ7MH0iIFx1ODIwN1x1NUI5QVx1N0ZBOVx1NEU0Qlx1OTU5M1x1OTcwMFx1ODk4MVx1N0E3QVx1NjgzQ1x1MzAwMgotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX05PVEFUSU9OX05BTUVfSU5fVU5QQVJTRURfRU5USVRZREVDTCA9IFx1NTcyOFx1NUJFNlx1OUFENCAiezB9IiBcdTc2ODRcdTVCQTNcdTU0NEFcdTRFMkRcdUZGMEMiTkRBVEEiIFx1ODIwN1x1ODg2OFx1NzkzQVx1NkNENVx1NTQwRFx1N0EzMVx1NEU0Qlx1OTU5M1x1OTcwMFx1ODk4MVx1N0E3QVx1NjgzQ1x1MzAwMgotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX05EQVRBX0lOX1VOUEFSU0VEX0VOVElUWURFQ0wgPSBcdTU3MjhcdTVCRTZcdTlBRDQgInswfSIgXHU3Njg0XHU1QkEzXHU1NDRBXHU0RTJEXHVGRjBDIk5EQVRBIiBcdTRFNEJcdTUyNERcdTk3MDBcdTg5ODFcdTdBN0FcdTY4M0NcdTMwMDIKLSAgICAgICAgTVNHX05PVEFUSU9OX05BTUVfUkVRVUlSRURfRk9SX1VOUEFSU0VEX0VOVElUWURFQ0wgPSBcdTU3MjhcdTVCRTZcdTlBRDQgInswfSIgXHU3Njg0XHU1QkEzXHU1NDRBXHU0RTJEXHVGRjBDIk5EQVRBIiBcdTRFNEJcdTVGOENcdTk3MDBcdTg5ODFcdTg4NjhcdTc5M0FcdTZDRDVcdTU0MERcdTdBMzFcdTMwMDIKLSAgICAgICAgRW50aXR5RGVjbFVudGVybWluYXRlZCA9IFx1NUJFNlx1OUFENCAiezB9IiBcdTc2ODRcdTVCQTNcdTU0NEFcdTdENTBcdTVDM0VcdTVGQzVcdTk4MDhcdTcwQkEgJyc+JydcdTMwMDIKLQlNU0dfRFVQTElDQVRFX0VOVElUWV9ERUZJTklUSU9OID0gXHU1QkU2XHU5QUQ0ICJ7MH0iIFx1NUJBM1x1NTQ0QVx1OEQ4NVx1OTA0RVx1NEUwMFx1NkIyMVx1NEVFNVx1NEUwQVx1MzAwMgotIyA0LjIuMiBFeHRlcm5hbCBFbnRpdGllcwotICAgICAgICBFeHRlcm5hbElEUmVxdWlyZWQgPSBcdTU5MTZcdTkwRThcdTVCRTZcdTlBRDRcdTVCQTNcdTU0NEFcdTc2ODRcdTk1OEJcdTk4MkRcdTVGQzVcdTk4MDhcdTcwQkEgIlNZU1RFTSIgXHU2MjE2ICJQVUJMSUMiXHUzMDAyCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfUFVCSURMSVRFUkFMX0lOX0VYVEVSTkFMSUQgPSAiUFVCTElDIiBcdTgyMDdcdTUxNkNcdTc1MjggSUQgXHU0RTRCXHU5NTkzXHU5NzAwXHU4OTgxXHU3QTdBXHU2ODNDXHUzMDAyCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9BRlRFUl9QVUJJRExJVEVSQUxfSU5fRVhURVJOQUxJRCA9IFx1NTE2Q1x1NzUyOCBJRCBcdTgyMDdcdTdDRkJcdTdENzEgSUQgXHU0RTRCXHU5NTkzXHU5NzAwXHU4OTgxXHU3QTdBXHU2ODNDXHUzMDAyCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfU1lTVEVNTElURVJBTF9JTl9FWFRFUk5BTElEID0gIlNZU1RFTSIgXHU4MjA3XHU3Q0ZCXHU3RDcxIElEIFx1NEU0Qlx1OTU5M1x1OTcwMFx1ODk4MVx1N0E3QVx1NjgzQ1x1MzAwMgotICAgICAgICBNU0dfVVJJX0ZSQUdNRU5UX0lOX1NZU1RFTUlEID0gXHU3MjQ3XHU2QkI1IElEIFx1NEUwRFx1NjFDOVx1NjMwN1x1NUI5QVx1NzBCQVx1N0NGQlx1N0Q3MSBJRCAiezB9IiBcdTc2ODRcdTRFMDBcdTkwRThcdTUyMDZcdTMwMDIKLSMgNC43IE5vdGF0aW9uIERlY2xhcmF0aW9ucwotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX05PVEFUSU9OX05BTUVfSU5fTk9UQVRJT05ERUNMID0gXHU1NzI4XHU4ODY4XHU3OTNBXHU2Q0Q1XHU1QkEzXHU1NDRBXHU0RTJEICI8IU5PVEFUSU9OIiBcdTRFNEJcdTVGOENcdTk3MDBcdTg5ODFcdTdBN0FcdTY4M0NcdTMwMDIKLSAgICAgICAgTVNHX05PVEFUSU9OX05BTUVfUkVRVUlSRURfSU5fTk9UQVRJT05ERUNMID0gXHU4ODY4XHU3OTNBXHU2Q0Q1XHU1QkEzXHU1NDRBXHU0RTJEXHU5NzAwXHU4OTgxXHU4ODY4XHU3OTNBXHU2Q0Q1XHU3Njg0XHU1NDBEXHU3QTMxXHUzMDAyCi0gICAgICAgIE1TR19TUEFDRV9SRVFVSVJFRF9BRlRFUl9OT1RBVElPTl9OQU1FX0lOX05PVEFUSU9OREVDTCA9IFx1NTcyOFx1ODg2OFx1NzkzQVx1NkNENVx1NUJBM1x1NTQ0QVx1NEUyRFx1ODg2OFx1NzkzQVx1NkNENVx1NTQwRFx1N0EzMSAiezB9IiBcdTRFNEJcdTVGOENcdTk3MDBcdTg5ODFcdTdBN0FcdTY4M0NcdTMwMDIKLSAgICAgICAgRXh0ZXJuYWxJRG9yUHVibGljSURSZXF1aXJlZCA9IFx1ODg2OFx1NzkzQVx1NkNENSAiezB9IiBcdTc2ODRcdTVCQTNcdTU0NEFcdTVGQzVcdTk4MDhcdTUzMDVcdTU0MkJcdTdDRkJcdTdENzFcdTYyMTZcdTUxNkNcdTc1MjggSURcdTMwMDIKLSAgICAgICAgTm90YXRpb25EZWNsVW50ZXJtaW5hdGVkID0gXHU4ODY4XHU3OTNBXHU2Q0Q1ICJ7MH0iIFx1NzY4NFx1NUJBM1x1NTQ0QVx1N0Q1MFx1NUMzRVx1NUZDNVx1OTgwOFx1NzBCQSAnJz4nJ1x1MzAwMgotICAgICAgICAKLSMgVmFsaWRhdGlvbiBtZXNzYWdlcwotICAgICAgICBEdXBsaWNhdGVUeXBlSW5NaXhlZENvbnRlbnQgPSBcdTUxNDNcdTdEMjBcdTVCQTNcdTU0NEEgInswfSIgXHU3Njg0XHU1MTY3XHU1QkI5XHU2QTIxXHU1NzhCXHU0RTJEXHU1REYyXHU3RDkzXHU2MzA3XHU1QjlBXHU1MTQzXHU3RDIwXHU5ODVFXHU1NzhCICJ7MX0iXHUzMDAyCi0gICAgICAgIEVOVElUSUVTSW52YWxpZCA9IFx1OTg1RVx1NTc4QiBFTlRJVElFUyBcdTc2ODRcdTVDNkNcdTYwMjdcdTUwM0MgInsxfSIgXHU1RkM1XHU5ODA4XHU2NjJGXHU0RTAwXHU2MjE2XHU1OTFBXHU1MDBCXHU2NzJBXHU1MjU2XHU2NzkwXHU1QkU2XHU5QUQ0XHU3Njg0XHU1NDBEXHU3QTMxXHUzMDAyCi0gICAgICAgIEVOVElUWUludmFsaWQgPSBcdTk4NUVcdTU3OEIgRU5USVRZIFx1NzY4NFx1NUM2Q1x1NjAyN1x1NTAzQyAiezF9IiBcdTVGQzVcdTk4MDhcdTY2MkZcdTRFMDBcdTUwMEJcdTY3MkFcdTUyNTZcdTY3OTBcdTVCRTZcdTlBRDRcdTc2ODRcdTU0MERcdTdBMzFcdTMwMDIKLSAgICAgICAgSUREZWZhdWx0VHlwZUludmFsaWQgPSBJRCBcdTVDNkNcdTYwMjcgInswfSIgXHU1RkM1XHU5ODA4XHU1MTc3XHU2NzA5ICIjSU1QTElFRCIgXHU2MjE2ICIjUkVRVUlSRUQiIFx1NzY4NFx1NUJBM1x1NTQ0QVx1OTgxMFx1OEEyRFx1MzAwMgotICAgICAgICBJREludmFsaWQgPSBcdTk4NUVcdTU3OEIgSUQgXHU3Njg0XHU1QzZDXHU2MDI3XHU1MDNDICJ7MH0iIFx1NUZDNVx1OTgwOFx1NjYyRlx1NTQwRFx1N0EzMVx1MzAwMgotICAgICAgICBJREludmFsaWRXaXRoTmFtZXNwYWNlcyA9IFx1NTU1Rlx1NzUyOFx1NTQ3RFx1NTQwRFx1N0E3QVx1OTU5M1x1NjY0Mlx1RkYwQ1x1OTg1RVx1NTc4QiBJRCBcdTc2ODRcdTVDNkNcdTYwMjdcdTUwM0MgInswfSIgXHU1RkM1XHU5ODA4XHU2NjJGIE5DTmFtZVx1MzAwMgotICAgICAgICBJRE5vdFVuaXF1ZSA9IFx1OTg1RVx1NTc4QiBJRCBcdTc2ODRcdTVDNkNcdTYwMjdcdTUwM0MgInswfSIgXHU1RkM1XHU5ODA4XHU2NjJGXHU2NTg3XHU0RUY2XHU1MTY3XHU3Njg0XHU1NTJGXHU0RTAwXHU1MDNDXHUzMDAyCi0gICAgICAgIElEUkVGSW52YWxpZCA9IFx1OTg1RVx1NTc4QiBJRFJFRiBcdTc2ODRcdTVDNkNcdTYwMjdcdTUwM0MgInswfSIgXHU1RkM1XHU5ODA4XHU2NjJGXHU1NDBEXHU3QTMxXHUzMDAyCi0gICAgICAgIElEUkVGSW52YWxpZFdpdGhOYW1lc3BhY2VzID0gXHU1NTVGXHU3NTI4XHU1NDdEXHU1NDBEXHU3QTdBXHU5NTkzXHU2NjQyXHVGRjBDXHU5ODVFXHU1NzhCIElEUkVGIFx1NzY4NFx1NUM2Q1x1NjAyN1x1NTAzQyAiezB9IiBcdTVGQzVcdTk4MDhcdTY2MkYgTkNOYW1lXHUzMDAyCi0gICAgICAgIElEUkVGU0ludmFsaWQgPSBcdTk4NUVcdTU3OEIgSURSRUZTIFx1NzY4NFx1NUM2Q1x1NjAyN1x1NTAzQyAiezB9IiBcdTVGQzVcdTk4MDhcdTY2MkZcdTRFMDBcdTYyMTZcdTU5MUFcdTUwMEJcdTU0MERcdTdBMzFcdTMwMDIKLSAgICAgICAgSUxMX0ZPUk1FRF9QQVJBTUVURVJfRU5USVRZX1dIRU5fVVNFRF9JTl9ERUNMID0gXHU3NTc2XHU1QkU2XHU5QUQ0XHU1M0MzXHU3MTY3XHU3NTc2XHU0RjVDXHU1QjhDXHU2NTc0XHU1QkEzXHU1NDRBXHU2NjQyXHVGRjBDXHU1M0MzXHU2NTc4XHU1QkU2XHU5QUQ0ICJ7MH0iIFx1NzY4NFx1NTNENlx1NEVFM1x1NjU4N1x1NUI1N1x1NUZDNVx1OTgwOFx1NTMwNVx1NTQyQlx1NkI2M1x1NzhCQVx1NURFMlx1NzJDMFx1N0Q1MFx1NjlDQlx1NzY4NFx1NUJBM1x1NTQ0QVx1MzAwMgotICAgICAgICBJbXByb3BlckRlY2xhcmF0aW9uTmVzdGluZyA9IFx1NTNDM1x1NjU3OFx1NUJFNlx1OUFENCAiezB9IiBcdTc2ODRcdTUzRDZcdTRFRTNcdTY1ODdcdTVCNTdcdTVGQzVcdTk4MDhcdTUzMDVcdTU0MkJcdTZCNjNcdTc4QkFcdTVERTJcdTcyQzBcdTdENTBcdTY5Q0JcdTc2ODRcdTVCQTNcdTU0NEFcdTMwMDIKLSAgICAgICAgSW1wcm9wZXJHcm91cE5lc3RpbmcgPSBcdTUzQzNcdTY1NzhcdTVCRTZcdTlBRDQgInswfSIgXHU3Njg0XHU1M0Q2XHU0RUUzXHU2NTg3XHU1QjU3XHU1RkM1XHU5ODA4XHU1MzA1XHU1NDJCXHU2QjYzXHU3OEJBXHU1REUyXHU3MkMwXHU3RDUwXHU2OUNCXHU3Njg0XHU2MjEwXHU1QzBEXHU2MkVDXHU4NjVGXHUzMDAyCi0gICAgICAgIElOVkFMSURfUEVfSU5fQ09ORElUSU9OQUwgPSBcdTUzQzNcdTY1NzhcdTVCRTZcdTlBRDQgInswfSIgXHU3Njg0XHU1M0Q2XHU0RUUzXHU2NTg3XHU1QjU3XHU1RkM1XHU5ODA4XHU1MzA1XHU1NDJCXHU2NTc0XHU1MDBCXHU2ODlEXHU0RUY2XHU2MDI3XHU2QkI1XHU4NDNEXHU2MjE2XHU1MEM1XHU1MzA1XHU1NDJCIElOQ0xVREUgXHU2MjE2IElHTk9SRVx1MzAwMgotICAgICAgICBNU0dfQVRUUklCVVRFX05PVF9ERUNMQVJFRCA9IFx1NTE0M1x1N0QyMFx1OTg1RVx1NTc4QiAiezB9IiBcdTVGQzVcdTk4MDhcdTVCQTNcdTU0NEFcdTVDNkNcdTYwMjcgInsxfSJcdTMwMDIKLSAgICAgICAgTVNHX0FUVFJJQlVURV9WQUxVRV9OT1RfSU5fTElTVCA9IFx1NTE3N1x1NjcwOVx1NTAzQyAiezF9IiBcdTc2ODRcdTVDNkNcdTYwMjcgInswfSIgXHU1RkM1XHU5ODA4XHU1MTc3XHU2NzA5XHU0Rjg2XHU4MUVBXHU2RTA1XHU1NUFFICJ7Mn0iIFx1NzY4NFx1NTAzQ1x1MzAwMgotICAgICAgICBNU0dfQVRUVkFMVUVfQ0hBTkdFRF9EVVJJTkdfTk9STUFMSVpBVElPTl9XSEVOX1NUQU5EQUxPTkUgPSBcdTU3MjhcdTczNjhcdTdBQ0JcdTY1ODdcdTRFRjZcdTRFMkRcdUZGMENcdTVDNkNcdTYwMjcgInswfSIgXHU3Njg0XHU1MDNDICJ7MX0iIFx1NEUwRFx1NTNFRlx1OTAwRlx1OTA0RVx1NkI2M1x1ODk4Rlx1NTMxNlx1OTAzMlx1ODg0Q1x1OEI4QVx1NjZGNCAoXHU2MjEwXHU3MEJBICJ7Mn0iKVx1MzAwMgotICAgICAgICBNU0dfQ09OVEVOVF9JTkNPTVBMRVRFID0gXHU1MTQzXHU3RDIwXHU5ODVFXHU1NzhCICJ7MH0iIFx1NzY4NFx1NTE2N1x1NUJCOVx1NEUwRFx1NUI4Q1x1NjU3NFx1RkYwQ1x1NUI4M1x1NUZDNVx1OTgwOFx1OTE0RFx1NUMwRCAiezF9Ilx1MzAwMgotICAgICAgICBNU0dfQ09OVEVOVF9JTlZBTElEID0gXHU1MTQzXHU3RDIwXHU5ODVFXHU1NzhCICJ7MH0iIFx1NzY4NFx1NTE2N1x1NUJCOVx1NUZDNVx1OTgwOFx1OTE0RFx1NUMwRCAiezF9Ilx1MzAwMgotICAgICAgICBNU0dfQ09OVEVOVF9JTlZBTElEX1NQRUNJRklFRCA9IFx1NTE0M1x1N0QyMFx1OTg1RVx1NTc4QiAiezB9IiBcdTc2ODRcdTUxNjdcdTVCQjlcdTVGQzVcdTk4MDhcdTkxNERcdTVDMEQgInsxfSJcdTMwMDJcdTRFMERcdTUxNDFcdThBMzFcdTk4NUVcdTU3OEIgInsyfSIgXHU3Njg0XHU1QjUwXHU5ODA1XHUzMDAyCi0gICAgICAgIE1TR19ERUZBVUxURURfQVRUUklCVVRFX05PVF9TUEVDSUZJRUQgPSBcdTUxNDNcdTdEMjBcdTk4NUVcdTU3OEIgInswfSIgXHU3Njg0XHU1QzZDXHU2MDI3ICJ7MX0iIFx1NTE3N1x1NjcwOVx1OTgxMFx1OEEyRFx1NTAzQ1x1RkYwQ1x1NEUxNFx1NUZDNVx1OTgwOFx1NTcyOFx1NzM2OFx1N0FDQlx1NjU4N1x1NEVGNlx1NEUyRFx1NjMwN1x1NUI5QVx1MzAwMgotICAgICAgICBNU0dfRFVQTElDQVRFX0FUVERFRiA9IFx1NTE0M1x1N0QyMFx1OTg1RVx1NTc4QiAiezB9IiBcdTVERjJcdTdEOTNcdTVCQTNcdTU0NEFcdTVDNkNcdTYwMjcgInsxfSJcdTMwMDIKLSAgICAgICAgTVNHX0VMRU1FTlRfQUxSRUFEWV9ERUNMQVJFRCA9IFx1NTE0M1x1N0QyMFx1OTg1RVx1NTc4QiAiezB9IiBcdTRFMERcdTUzRUZcdTVCQTNcdTU0NEFcdThEODVcdTkwNEVcdTRFMDBcdTZCMjFcdTRFRTVcdTRFMEFcdTMwMDIKLSAgICAgICAgTVNHX0VMRU1FTlRfTk9UX0RFQ0xBUkVEID0gXHU1RkM1XHU5ODA4XHU1QkEzXHU1NDRBXHU1MTQzXHU3RDIwXHU5ODVFXHU1NzhCICJ7MH0iXHUzMDAyCi0gICAgICAgIE1TR19HUkFNTUFSX05PVF9GT1VORCA9IFx1NjU4N1x1NEVGNlx1NzEyMVx1NjU0ODogXHU2MjdFXHU0RTBEXHU1MjMwXHU2NTg3XHU2Q0Q1XHUzMDAyCi0gICAgICAgIE1TR19FTEVNRU5UX1dJVEhfSURfUkVRVUlSRUQgPSBJRCBcdTcwQkEgInswfSIgXHU3Njg0XHU1MTQzXHU3RDIwXHU1RkM1XHU5ODA4XHU1MUZBXHU3M0ZFXHU1NzI4XHU2NTg3XHU0RUY2XHU0RTJEXHUzMDAyCi0gICAgICAgIE1TR19FWFRFUk5BTF9FTlRJVFlfTk9UX1BFUk1JVFRFRCA9IFx1NzM2OFx1N0FDQlx1NjU4N1x1NEVGNlx1NEUyRFx1NEUwRFx1NTE0MVx1OEEzMVx1NTNDM1x1NzE2N1x1NTkxNlx1OTBFOFx1NUJFNlx1OUFENCAiezB9Ilx1MzAwMgotICAgICAgICBNU0dfRklYRURfQVRUVkFMVUVfSU5WQUxJRCA9IFx1NTE3N1x1NjcwOVx1NTAzQyAiezJ9IiBcdTc2ODRcdTVDNkNcdTYwMjcgInsxfSIgXHU1RkM1XHU5ODA4XHU1MTc3XHU2NzA5ICJ7M30iIFx1NzY4NFx1NTAzQ1x1MzAwMgotICAgICAgICBNU0dfTU9SRV9USEFOX09ORV9JRF9BVFRSSUJVVEUgPSBcdTUxNDNcdTdEMjBcdTk4NUVcdTU3OEIgInswfSIgXHU1REYyXHU3RDkzXHU1MTc3XHU2NzA5XHU5ODVFXHU1NzhCIElEIFx1NzY4NFx1NUM2Q1x1NjAyNyAiezF9Ilx1RkYwQ1x1NEUwRFx1NTE0MVx1OEEzMVx1OEE3Mlx1OTg1RVx1NTc4QiBJRCBcdTc2ODRcdTdCMkNcdTRFOENcdTUwMEJcdTVDNkNcdTYwMjcgInsyfSJcdTMwMDIKLSAgICAgICAgTVNHX01PUkVfVEhBTl9PTkVfTk9UQVRJT05fQVRUUklCVVRFID0gXHU1MTQzXHU3RDIwXHU5ODVFXHU1NzhCICJ7MH0iIFx1NURGMlx1N0Q5M1x1NTE3N1x1NjcwOVx1OTg1RVx1NTc4QiBOT1RBVElPTiBcdTc2ODRcdTVDNkNcdTYwMjcgInsxfSJcdUZGMENcdTRFMERcdTUxNDFcdThBMzFcdThBNzJcdTk4NUVcdTU3OEIgTk9UQVRJT04gXHU3Njg0XHU3QjJDXHU0RThDXHU1MDBCXHU1QzZDXHU2MDI3ICJ7Mn0iXHUzMDAyCi0gICAgICAgIE1TR19OT1RBVElPTl9OT1RfREVDTEFSRURfRk9SX05PVEFUSU9OVFlQRV9BVFRSSUJVVEUgPSBcdTgyRTVcdTg5ODFcdTU3MjhcdTVDNkNcdTYwMjcgInswfSIgXHU3Njg0XHU4ODY4XHU3OTNBXHU2Q0Q1XHU5ODVFXHU1NzhCXHU2RTA1XHU1NUFFXHU0RTJEXHU1M0MzXHU3MTY3XHU4ODY4XHU3OTNBXHU2Q0Q1ICJ7MX0iXHVGRjBDXHU1RkM1XHU5ODA4XHU0RTg4XHU0RUU1XHU1QkEzXHU1NDRBXHUzMDAyCi0gICAgICAgIE1TR19OT1RBVElPTl9OT1RfREVDTEFSRURfRk9SX1VOUEFSU0VEX0VOVElUWURFQ0wgPSBcdTgyRTVcdTg5ODFcdTU3MjggInswfSIgXHU3Njg0XHU2NzJBXHU1MjU2XHU2NzkwXHU1QkU2XHU5QUQ0XHU1QkEzXHU1NDRBXHU0RTJEXHU1M0MzXHU3MTY3XHU4ODY4XHU3OTNBXHU2Q0Q1ICJ7MX0iXHVGRjBDXHU1RkM1XHU5ODA4XHU0RTg4XHU0RUU1XHU1QkEzXHU1NDRBXHUzMDAyCi0gICAgICAgIE1TR19SRUZFUkVOQ0VfVE9fRVhURVJOQUxMWV9ERUNMQVJFRF9FTlRJVFlfV0hFTl9TVEFOREFMT05FID0gXHU1NzI4XHU3MzY4XHU3QUNCXHU2NTg3XHU0RUY2XHU0RTJEXHVGRjBDXHU0RTBEXHU1MTQxXHU4QTMxXHU1M0MzXHU3MTY3XHU1OTE2XHU5MEU4XHU1MjU2XHU2NzkwXHU1QkU2XHU5QUQ0XHU0RTJEXHU1QkEzXHU1NDRBXHU3Njg0XHU1QkU2XHU5QUQ0ICJ7MH0iXHUzMDAyCi0gICAgICAgIE1TR19SRVFVSVJFRF9BVFRSSUJVVEVfTk9UX1NQRUNJRklFRCA9IFx1NTE0M1x1N0QyMFx1OTg1RVx1NTc4QiAiezB9IiBcdTk3MDBcdTg5ODFcdTVDNkNcdTYwMjcgInsxfSIgXHU0RTE0XHU1RkM1XHU5ODA4XHU0RTg4XHU0RUU1XHU2MzA3XHU1QjlBXHUzMDAyCi0gICAgICAgIE1TR19XSElURV9TUEFDRV9JTl9FTEVNRU5UX0NPTlRFTlRfV0hFTl9TVEFOREFMT05FID0gXHU1NzI4XHU3MzY4XHU3QUNCXHU2NTg3XHU0RUY2XHU0RTJEXHVGRjBDXHU1MTc3XHU2NzA5XHU1MTQzXHU3RDIwXHU1MTY3XHU1QkI5XHU3Njg0XHU1OTE2XHU5MEU4XHU1MjU2XHU2NzkwXHU1QkU2XHU5QUQ0XHU0RTJEXHU1QkEzXHU1NDRBXHU3Njg0XHU1MTQzXHU3RDIwXHU0RTRCXHU5NTkzXHVGRjBDXHU0RTBEXHU1M0VGXHU2NzA5XHU3QTdBXHU2ODNDXHUzMDAyCi0gICAgICAgIE5NVE9LRU5JbnZhbGlkID0gXHU5ODVFXHU1NzhCIE5NVE9LRU4gXHU3Njg0XHU1QzZDXHU2MDI3XHU1MDNDICJ7MH0iIFx1NUZDNVx1OTgwOFx1NjYyRlx1NTQwRFx1N0EzMVx1OEExOFx1ODY1Rlx1MzAwMgotICAgICAgICBOTVRPS0VOU0ludmFsaWQgPSBcdTk4NUVcdTU3OEIgTk1UT0tFTlMgXHU3Njg0XHU1QzZDXHU2MDI3XHU1MDNDICJ7MH0iIFx1NUZDNVx1OTgwOFx1NjYyRlx1NEUwMFx1NjIxNlx1NTkxQVx1NTAwQlx1NTQwRFx1N0EzMVx1OEExOFx1ODY1Rlx1MzAwMgotICAgICAgICBOb05vdGF0aW9uT25FbXB0eUVsZW1lbnQgPSBcdTVCQTNcdTU0NEEgRU1QVFkgXHU3Njg0XHU1MTQzXHU3RDIwXHU5ODVFXHU1NzhCICJ7MH0iIFx1NEUwRFx1NTNFRlx1NUJBM1x1NTQ0QVx1OTg1RVx1NTc4QiBOT1RBVElPTiBcdTc2ODRcdTVDNkNcdTYwMjcgInsxfSJcdTMwMDIKLSAgICAgICAgUm9vdEVsZW1lbnRUeXBlTXVzdE1hdGNoRG9jdHlwZWRlY2wgPSBcdTY1ODdcdTRFRjZcdTY4MzlcdTUxNDNcdTdEMjAgInsxfSIgXHU1RkM1XHU5ODA4XHU5MTREXHU1QzBEIERPQ1RZUEUgXHU2ODM5ICJ7MH0iXHUzMDAyCi0gICAgICAgIFVuZGVjbGFyZWRFbGVtZW50SW5Db250ZW50U3BlYyA9IFx1NTE0M1x1N0QyMCAiezB9IiBcdTc2ODRcdTUxNjdcdTVCQjlcdTZBMjFcdTU3OEJcdTUzQzNcdTcxNjdcdTY3MkFcdTVCQTNcdTU0NEFcdTc2ODRcdTUxNDNcdTdEMjAgInsxfSJcdTMwMDIKLSAgICAgICAgVW5pcXVlTm90YXRpb25OYW1lID0gXHU4ODY4XHU3OTNBXHU2Q0Q1ICJ7MH0iIFx1NzY4NFx1NUJBM1x1NTQ0QVx1NEUyNlx1OTc1RVx1NTUyRlx1NEUwMFx1MzAwMlx1NjMwN1x1NUI5QVx1NzY4NCBOYW1lIFx1NEUwRFx1ODBGRFx1NTcyOFx1NEUwMFx1NTAwQlx1NEVFNVx1NEUwQVx1NzY4NFx1ODg2OFx1NzkzQVx1NkNENVx1NUJBM1x1NTQ0QVx1NEUyRFx1NUJBM1x1NTQ0QVx1MzAwMgotICAgICAgICBFTlRJVFlGYWlsZWRJbml0aWFsaXplR3JhbW1hciA9ICBFTlRJVFlEYXRhdHlwZSBcdTlBNTdcdThCNDlcdTdBMEJcdTVGMEY6IFx1NTkzMVx1NjU1N1x1MzAwMlx1OTcwMFx1ODk4MVx1NEY3Rlx1NzUyOFx1NjcwOVx1NjU0OFx1NzY4NFx1NjU4N1x1NkNENVx1NTNDM1x1NzE2N1x1NEY4Nlx1NTQ3Q1x1NTNFQlx1OEQ3N1x1NTlDQlx1NjVCOVx1NkNENVx1MzAwMlx0Ci0gICAgICAgIEVOVElUWU5vdFVucGFyc2VkID0gRU5USVRZICJ7MH0iIFx1NEUyNlx1OTc1RVx1NjcyQVx1N0Q5M1x1NTI1Nlx1Njc5MFx1MzAwMgotICAgICAgICBFTlRJVFlOb3RWYWxpZCA9IEVOVElUWSAiezB9IiBcdTcxMjFcdTY1NDhcdTMwMDIKLSAgICAgICAgRW1wdHlMaXN0ID0gXHU5ODVFXHU1NzhCIEVOVElUSUVTXHUzMDAxSURSRUZTIFx1ODIwNyBOTVRPS0VOUyBcdTc2ODRcdTUwM0NcdTRFMERcdTUzRUZcdTcwQkFcdTdBN0FcdTc2N0RcdTZFMDVcdTU1QUVcdTMwMDIKLQotIyBFbnRpdHkgcmVsYXRlZCBtZXNzYWdlcwotIyAzLjEgU3RhcnQtVGFncywgRW5kLVRhZ3MsIGFuZCBFbXB0eS1FbGVtZW50IFRhZ3MKLSAgICAgICAgUmVmZXJlbmNlVG9FeHRlcm5hbEVudGl0eSA9IFx1NUM2Q1x1NjAyN1x1NTAzQ1x1NEUwRFx1NTE0MVx1OEEzMVx1NTNDM1x1NzE2N1x1NTkxNlx1OTBFOFx1NUJFNlx1OUFENCAiJnswfTsiXHUzMDAyCi0gICAgICAgIEFjY2Vzc0V4dGVybmFsRFREID0gXHU1OTE2XHU5MEU4IERURDogXHU3MTIxXHU2Q0Q1XHU4QjgwXHU1M0Q2XHU1OTE2XHU5MEU4IERURCAnJ3swfScnXHVGRjBDXHU1NkUwXHU3MEJBIGFjY2Vzc0V4dGVybmFsRFREIFx1NUM2Q1x1NjAyN1x1OEEyRFx1NUI5QVx1NzY4NFx1OTY1MFx1NTIzNlx1RkYwQ1x1NjI0MFx1NEVFNVx1NEUwRFx1NTE0MVx1OEEzMSAnJ3sxfScnIFx1NUI1OFx1NTNENlx1MzAwMgotICAgICAgICBBY2Nlc3NFeHRlcm5hbEVudGl0eSA9IFx1NTkxNlx1OTBFOFx1NUJFNlx1OUFENDogXHU3MTIxXHU2Q0Q1XHU4QjgwXHU1M0Q2XHU1OTE2XHU5MEU4XHU2NTg3XHU0RUY2ICcnezB9JydcdUZGMENcdTU2RTBcdTcwQkEgYWNjZXNzRXh0ZXJuYWxEVEQgXHU1QzZDXHU2MDI3XHU4QTJEXHU1QjlBXHU3Njg0XHU5NjUwXHU1MjM2XHVGRjBDXHU2MjQwXHU0RUU1XHU0RTBEXHU1MTQxXHU4QTMxICcnezF9JycgXHU1QjU4XHU1M0Q2XHUzMDAyCi0KLSMgNC4xIENoYXJhY3RlciBhbmQgRW50aXR5IFJlZmVyZW5jZXMKLSAgICAgICAgRW50aXR5Tm90RGVjbGFyZWQgPSBcdTUzQzNcdTcxNjdcdTRFODZcdTVCRTZcdTlBRDQgInswfSJcdUZGMENcdTRGNDZcdTY2MkZcdTY3MkFcdTVCQTNcdTU0NEFcdTMwMDIKLSAgICAgICAgUmVmZXJlbmNlVG9VbnBhcnNlZEVudGl0eSA9IFx1NEUwRFx1NTE0MVx1OEEzMVx1NjcyQVx1NTI1Nlx1Njc5MFx1NzY4NFx1NUJFNlx1OUFENFx1NTNDM1x1NzE2NyAiJnswfTsiXHUzMDAyCi0gICAgICAgIFJlY3Vyc2l2ZVJlZmVyZW5jZSA9IFx1OTA1RVx1OEZGNFx1NUJFNlx1OUFENFx1NTNDM1x1NzE2NyAiezB9Ilx1MzAwMihcdTUzQzNcdTcxNjdcdThERUZcdTVGOTE6IHsxfSlcdUZGMEMKLSAgICAgICAgUmVjdXJzaXZlR2VuZXJhbFJlZmVyZW5jZSA9IFx1OTA1RVx1OEZGNFx1NEUwMFx1ODIyQ1x1NUJFNlx1OUFENFx1NTNDM1x1NzE2NyAiJnswfTsiXHUzMDAyKFx1NTNDM1x1NzE2N1x1OERFRlx1NUY5MTogezF9KVx1RkYwQwotICAgICAgICBSZWN1cnNpdmVQRVJlZmVyZW5jZSA9IFx1OTA1RVx1OEZGNFx1NTNDM1x1NjU3OFx1NUJFNlx1OUFENFx1NTNDM1x1NzE2NyAiJXswfTsiXHUzMDAyKFx1NTNDM1x1NzE2N1x1OERFRlx1NUY5MTogezF9KVx1RkYwQwotIyA0LjMuMyBDaGFyYWN0ZXIgRW5jb2RpbmcgaW4gRW50aXRpZXMKLSAgICAgICAgRW5jb2RpbmdOb3RTdXBwb3J0ZWQgPSBcdTRFMERcdTY1MkZcdTYzRjRcdTdERThcdTc4QkMgInswfSJcdTMwMDIKLSAgICAgICAgRW5jb2RpbmdSZXF1aXJlZCA9IFx1NjcyQVx1NEY3Rlx1NzUyOCBVVEYtOCBcdTYyMTYgVVRGLTE2IFx1N0RFOFx1NzhCQ1x1NzY4NFx1NTI1Nlx1Njc5MFx1NUJFNlx1OUFENFx1RkYwQ1x1NUZDNVx1OTgwOFx1NTMwNVx1NTQyQlx1N0RFOFx1NzhCQ1x1NUJBM1x1NTQ0QVx1MzAwMgotICAgICAgICAKLSMgTmFtZXNwYWNlcyBzdXBwb3J0Ci0jIDQuIFVzaW5nIFF1YWxpZmllZCBOYW1lcwotICAgICAgICBJbGxlZ2FsUU5hbWUgPSBcdTUxNDNcdTdEMjBcdTYyMTZcdTVDNkNcdTYwMjdcdTRFMERcdTdCMjZcdTU0MDggUU5hbWUgXHU3NTIyXHU3NTFGOiBRTmFtZTo6PShOQ05hbWUnOicpP05DTmFtZVx1MzAwMgotICAgICAgICBFbGVtZW50WE1MTlNQcmVmaXggPSBcdTUxNDNcdTdEMjAgInswfSIgXHU0RTBEXHU4MEZEXHU0RjdGXHU3NTI4ICJ4bWxucyIgXHU0RjVDXHU3MEJBXHU1MjREXHU3RjZFXHU3OEJDXHUzMDAyCi0gICAgICAgIEVsZW1lbnRQcmVmaXhVbmJvdW5kID0gXHU1MTQzXHU3RDIwICJ7MX0iIFx1NzY4NFx1NTI0RFx1N0Y2RVx1NzhCQyAiezB9IiBcdTY3MkFcdTkwMjNcdTdENTBcdTMwMDIKLSAgICAgICAgQXR0cmlidXRlUHJlZml4VW5ib3VuZCA9IFx1OTVEQ1x1ODA2Rlx1NTE0M1x1N0QyMFx1OTg1RVx1NTc4QiAiezB9IiBcdTRFNEJcdTVDNkNcdTYwMjcgInsxfSIgXHU3Njg0XHU1MjREXHU3RjZFXHU3OEJDICJ7Mn0iIFx1NjcyQVx1OTAyM1x1N0Q1MFx1MzAwMgotICAgICAgICBFbXB0eVByZWZpeGVkQXR0TmFtZSA9IFx1NUM2Q1x1NjAyNyAiezB9IiBcdTc2ODRcdTUwM0NcdTcxMjFcdTY1NDhcdTMwMDJcdTUyNERcdTdGNkVcdTc2ODRcdTU0N0RcdTU0MERcdTdBN0FcdTk1OTNcdTkwMjNcdTdENTBcdTRFMERcdTUzRUZcdTcwQkFcdTdBN0FcdTc2N0RcdTMwMDIKLSAgICAgICAgUHJlZml4RGVjbGFyZWQgPSBcdTY3MkFcdTVCQTNcdTU0NEFcdTU0N0RcdTU0MERcdTdBN0FcdTk1OTNcdTUyNERcdTdGNkVcdTc4QkMgInswfSJcdTMwMDIKLSAgICAgICAgQ2FudEJpbmRYTUxOUyA9IFx1NTI0RFx1N0Y2RVx1NzhCQyAieG1sbnMiIFx1NzEyMVx1NkNENVx1NjYwRVx1NzhCQVx1OTAyM1x1N0Q1MFx1NEVGQlx1NEY1NVx1NTQ3RFx1NTQwRFx1N0E3QVx1OTU5MzsgInhtbG5zIiBcdTc2ODRcdTU0N0RcdTU0MERcdTdBN0FcdTk1OTNcdTRFNUZcdTcxMjFcdTZDRDVcdTY2MEVcdTc4QkFcdTkwMjNcdTdENTBcdTRFRkJcdTRGNTVcdTUyNERcdTdGNkVcdTc4QkNcdTMwMDIKLSAgICAgICAgQ2FudEJpbmRYTUwgPSBcdTUyNERcdTdGNkVcdTc4QkMgInhtbCIgXHU3MTIxXHU2Q0Q1XHU5MDIzXHU3RDUwXHU0RTAwXHU4MjJDXHU1NDdEXHU1NDBEXHU3QTdBXHU5NTkzXHU0RTRCXHU1OTE2XHU3Njg0XHU0RUZCXHU0RjU1XHU1NDdEXHU1NDBEXHU3QTdBXHU5NTkzOyAieG1sIiBcdTc2ODRcdTU0N0RcdTU0MERcdTdBN0FcdTk1OTNcdTRFNUZcdTcxMjFcdTZDRDVcdTkwMjNcdTdENTAgInhtbCIgXHU0RTRCXHU1OTE2XHU3Njg0XHU0RUZCXHU0RjU1XHU1NDdEXHU1NDBEXHU3QTdBXHU5NTkzXHUzMDAyCi0gICAgICAgIE1TR19BVFRfREVGQVVMVF9JTlZBTElEID0gXHU3NTMxXHU2NUJDXHU2QjY0XHU1QzZDXHU2MDI3XHU5ODVFXHU1NzhCXHU3Njg0XHU4QTlFXHU1RjU5XHU5NjUwXHU1MjM2XHU2ODlEXHU0RUY2XHVGRjBDXHU1QzZDXHU2MDI3ICJ7MH0iIFx1NzY4NCBkZWZhdWx0VmFsdWUgInsxfSIgXHU3MTIxXHU2NTQ4XHUzMDAyCi0KLSMgUkVWSVNJVDogVGhlc2UgbmVlZCBtZXNzYWdlcwotICAgICAgICBNU0dfU1BBQ0VfUkVRVUlSRURfQUZURVJfU1lTVEVNTElURVJBTF9JTl9FWFRFUk5BTElEPU1TR19TUEFDRV9SRVFVSVJFRF9BRlRFUl9TWVNURU1MSVRFUkFMX0lOX0VYVEVSTkFMSUQKLSAgICAgICAgT3BlblF1b3RlTWlzc2luZ0luRGVjbD1PcGVuUXVvdGVNaXNzaW5nSW5EZWNsCi0gICAgICAgIEludmFsaWRDaGFySW5MaXRlcmFsPUludmFsaWRDaGFySW5MaXRlcmFsCi0KLQotIyBJbXBsZW1lbnRhdGlvbiBsaW1pdHMKLSAgICAgICAgRW50aXR5RXhwYW5zaW9uTGltaXQ9SkFYUDAwMDEwMDAxOiBcdTUyNTZcdTY3OTBcdTU2NjhcdTU3MjhcdTZCNjRcdTY1ODdcdTRFRjZcdTRFMkRcdTkwNDdcdTUyMzAgInswfSIgXHU1MDBCXHU0RUU1XHU0RTBBXHU3Njg0XHU1QkU2XHU5QUQ0XHU2NEY0XHU1MTQ1OyBcdTkwMTlcdTY2MkYgSkRLIFx1NjI0MFx1ODk4Rlx1NUI5QVx1NzY4NFx1OTY1MFx1NTIzNlx1MzAwMgotICAgICAgICBFbGVtZW50QXR0cmlidXRlTGltaXQ9SkFYUDAwMDEwMDAyOiBcdTUxNDNcdTdEMjAgInswfSIgXHU1MTc3XHU2NzA5XHU4RDg1XHU5MDRFICJ7MX0iIFx1NTAwQlx1NEVFNVx1NEUwQVx1NzY4NFx1NUM2Q1x1NjAyN1x1RkYwQyJ7MX0iIFx1NjYyRiBKREsgXHU2MjQwXHU4OThGXHU1QjlBXHU3Njg0XHU5NjUwXHU1MjM2XHUzMDAyCi0gICAgICAgIE1heEVudGl0eVNpemVMaW1pdD1KQVhQMDAwMTAwMDM6IFx1NUJFNlx1OUFENCAiezB9IiBcdTc2ODRcdTk1NzdcdTVFQTZcdTcwQkEgInsxfSJcdUZGMENcdThEODVcdTkwNEUgInszfSIgXHU2MjQwXHU4QTJEXHU1QjlBXHU3Njg0ICJ7Mn0iIFx1OTY1MFx1NTIzNlx1MzAwMgotICAgICAgICBUb3RhbEVudGl0eVNpemVMaW1pdD1KQVhQMDAwMTAwMDQ6IFx1NUJFNlx1OUFENFx1NzY4NFx1N0QyRlx1N0E0RFx1NTkyN1x1NUMwRlx1NzBCQSAiezB9Ilx1RkYwQ1x1OEQ4NVx1OTA0RSAiezJ9IiBcdTYyNDBcdThBMkRcdTVCOUFcdTc2ODQgInsxfSIgXHU5NjUwXHU1MjM2XHUzMDAyCi0gICAgICAgIE1heFhNTE5hbWVMaW1pdD1KQVhQMDAwMTAwMDU6IFx1NUJFNlx1OUFENCAiezB9IiBcdTc2ODRcdTk1NzdcdTVFQTZcdTcwQkEgInsxfSJcdUZGMENcdThEODVcdTkwNEUgInszfSIgXHU2MjQwXHU4QTJEXHU1QjlBXHU3Njg0ICJ7Mn0iIFx1OTY1MFx1NTIzNlx1MzAwMgotICAgICAgICBNYXhFbGVtZW50RGVwdGhMaW1pdD1KQVhQMDAwMTAwMDY6IFx1NTE0M1x1N0QyMCAiezB9IiBcdTc2ODRcdTZERjFcdTVFQTZcdTcwQkEgInsxfSJcdUZGMENcdThEODVcdTkwNEUgInszfSIgXHU2MjQwXHU4QTJEXHU1QjlBXHU3Njg0ICJ7Mn0iIFx1OTY1MFx1NTIzNlx1MzAwMgotICAgICAgICBFbnRpdHlSZXBsYWNlbWVudExpbWl0PUpBWFAwMDAxMDAwNzogXHU1QkU2XHU5QUQ0XHU1M0MzXHU3MTY3XHU0RTJEXHU3Njg0XHU3QkMwXHU5RURFXHU3RTNEXHU2NTc4XHU3MEJBICJ7MH0iXHVGRjBDXHU4RDg1XHU5MDRFICJ7Mn0iIFx1NjI0MFx1OEEyRFx1NUI5QVx1NzY4NCAiezF9IiBcdTk2NTBcdTUyMzZcdTMwMDIKLQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MU2NoZW1hTWVzc2FnZXMucHJvcGVydGllcyBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hNTFNjaGVtYU1lc3NhZ2VzLnByb3BlcnRpZXMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDQ2OGViMWIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MU2NoZW1hTWVzc2FnZXMucHJvcGVydGllcworKysgL2Rldi9udWxsCkBAIC0xLDI5MSArMCwwIEBACi0jIFRoaXMgZmlsZSBjb250YWlucyBlcnJvciBhbmQgd2FybmluZyBtZXNzYWdlcyByZWxhdGVkIHRvIFhNTCBTY2hlbWEKLSMgVGhlIG1lc3NhZ2VzIGFyZSBhcnJhbmdlZCBpbiBrZXkgYW5kIHZhbHVlIHR1cGxlcyBpbiBhIExpc3RSZXNvdXJjZUJ1bmRsZS4KLSMKLQotICAgICAgICBCYWRNZXNzYWdlS2V5ID0gVGhlIGVycm9yIG1lc3NhZ2UgY29ycmVzcG9uZGluZyB0byB0aGUgbWVzc2FnZSBrZXkgY2FuIG5vdCBiZSBmb3VuZC4KLSAgICAgICAgRm9ybWF0RmFpbGVkID0gQW4gaW50ZXJuYWwgZXJyb3Igb2NjdXJyZWQgd2hpbGUgZm9ybWF0dGluZyB0aGUgZm9sbG93aW5nIG1lc3NhZ2U6XG4KLQotIyBGb3IgaW50ZXJuYWwgdXNlCi0KLSAgICAgICAgSW50ZXJuYWwtRXJyb3IgPSBJbnRlcm5hbCBlcnJvcjogezB9LgotICAgICAgICBkdC13aGl0ZXNwYWNlID0gV2hpdGVzcGFjZSBmYWNldCB2YWx1ZSBpcyBub3QgYXZhaWxhYmxlIGZvciB0aGUgdW5pb24gc2ltcGxlVHlwZSAnJ3swfScnCi0gICAgICAgIEdyYW1tYXJDb25mbGljdCA9IE9uZSBvZiB0aGUgZ3JhbW1hcihzKSByZXR1cm5lZCBmcm9tIHRoZSB1c2VyJ3MgZ3JhbW1hciBwb29sIGlzIGluIGNvbmZsaWN0IHdpdGggYW5vdGhlciBncmFtbWFyLgotCi0jIElkZW50aXR5IGNvbnN0cmFpbnRzCi0KLSAgICAgICAgQWJzZW50S2V5VmFsdWUgPSBJZGVudGl0eSBDb25zdHJhaW50IGVycm9yIChjdmMtaWRlbnRpdHktY29uc3RyYWludC40LjIuMSk6ICBlbGVtZW50IFwiezB9XCIgaGFzIGEga2V5IHdpdGggbm8gdmFsdWUuCi0gICAgICAgIER1cGxpY2F0ZUZpZWxkID0gRHVwbGljYXRlIG1hdGNoIGluIHNjb3BlIGZvciBmaWVsZCBcInswfVwiLgotICAgICAgICBEdXBsaWNhdGVLZXkgPSBEdXBsaWNhdGUga2V5IHZhbHVlIFt7MH1dIGRlY2xhcmVkIGZvciBpZGVudGl0eSBjb25zdHJhaW50IG9mIGVsZW1lbnQgXCJ7MX1cIi4KLSAgICAgICAgRHVwbGljYXRlVW5pcXVlID0gRHVwbGljYXRlIHVuaXF1ZSB2YWx1ZSBbezB9XSBkZWNsYXJlZCBmb3IgaWRlbnRpdHkgY29uc3RyYWludCBvZiBlbGVtZW50IFwiezF9XCIuCi0gICAgICAgIEZpZWxkTXVsdGlwbGVNYXRjaCA9IElkZW50aXR5IGNvbnN0cmFpbnQgZXJyb3I6ICBmaWVsZCBcInswfVwiIG1hdGNoZXMgbW9yZSB0aGFuIG9uZSB2YWx1ZSB3aXRoaW4gdGhlIHNjb3BlIG9mIGl0cyBzZWxlY3RvcjsgZmllbGRzIG11c3QgbWF0Y2ggdW5pcXVlIHZhbHVlcy4KLSAgICAgICAgRml4ZWREaWZmZXJzRnJvbUFjdHVhbCA9IFRoZSBjb250ZW50IG9mIHRoaXMgZWxlbWVudCBpcyBub3QgZXF1aXZhbGVudCB0byB0aGUgdmFsdWUgb2YgdGhlIFwiZml4ZWRcIiBhdHRyaWJ1dGUgaW4gdGhlIGVsZW1lbnQncyBkZWNsYXJhdGlvbiBpbiB0aGUgc2NoZW1hLgotICAgICAgICBLZXlNYXRjaGVzTmlsbGFibGUgPSBJZGVudGl0eSBDb25zdHJhaW50IGVycm9yIChjdmMtaWRlbnRpdHktY29uc3RyYWludC40LjIuMyk6ICBlbGVtZW50IFwiezB9XCIgaGFzIGEga2V5IHdoaWNoIG1hdGNoZXMgYW4gZWxlbWVudCB3aGljaCBoYXMgbmlsbGFibGUgc2V0IHRvIHRydWUuCi0gICAgICAgIEtleU5vdEVub3VnaFZhbHVlcyA9IE5vdCBlbm91Z2ggdmFsdWVzIHNwZWNpZmllZCBmb3IgPGtleSBuYW1lPVwiezF9XCI+IGlkZW50aXR5IGNvbnN0cmFpbnQgc3BlY2lmaWVkIGZvciBlbGVtZW50IFwiezB9XCIuCi0gICAgICAgIEtleU5vdEZvdW5kID0gS2V5ICcnezB9Jycgd2l0aCB2YWx1ZSAnJ3sxfScnIG5vdCBmb3VuZCBmb3IgaWRlbnRpdHkgY29uc3RyYWludCBvZiBlbGVtZW50ICcnezJ9JycuCi0gICAgICAgIEtleVJlZk5vdEVub3VnaFZhbHVlcyA9IE5vdCBlbm91Z2ggdmFsdWVzIHNwZWNpZmllZCBmb3IgPGtleXJlZiBuYW1lPVwiezF9XCI+IGlkZW50aXR5IGNvbnN0cmFpbnQgc3BlY2lmaWVkIGZvciBlbGVtZW50IFwiezB9XCIuCi0gICAgICAgIEtleVJlZk91dE9mU2NvcGUgPSBJZGVudGl0eSBDb25zdHJhaW50IGVycm9yOiAgaWRlbnRpdHkgY29uc3RyYWludCBcInswfVwiIGhhcyBhIGtleXJlZiB3aGljaCByZWZlcnMgdG8gYSBrZXkgb3IgdW5pcXVlIHRoYXQgaXMgb3V0IG9mIHNjb3BlLgotICAgICAgICBLZXlSZWZSZWZlck5vdEZvdW5kID0gS2V5IHJlZmVyZW5jZSBkZWNsYXJhdGlvbiBcInswfVwiIHJlZmVycyB0byB1bmtub3duIGtleSB3aXRoIG5hbWUgXCJ7MX1cIi4KLSAgICAgICAgVW5pcXVlTm90RW5vdWdoVmFsdWVzID0gTm90IGVub3VnaCB2YWx1ZXMgc3BlY2lmaWVkIGZvciA8dW5pcXVlPiBpZGVudGl0eSBjb25zdHJhaW50IHNwZWNpZmllZCBmb3IgZWxlbWVudCBcInswfVwiLgotICAgICAgICBVbmtub3duRmllbGQgPSBJbnRlcm5hbCBpZGVudGl0eSBjb25zdHJhaW50IGVycm9yOyB1bmtub3duIGZpZWxkIFwiezB9XCIuCi0KLSMgSWRlYWxseSwgd2Ugc2hvdWxkIG9ubHkgdXNlIHRoZSBmb2xsb3dpbmcgZXJyb3Iga2V5cywgbm90IHRoZSBvbmVzIHVuZGVyCi0jICJJZGVudGl0eSBjb25zdHJhaW50cyIuIEFuZCB3ZSBzaG91bGQgY292ZXIgYWxsIG9mIHRoZSBmb2xsb3dpbmcgZXJyb3JzLgotCi0jdmFsaWRhdGlvbiAoMy5YLjQpCi0KLSAgICAgICAgY3ZjLWF0dHJpYnV0ZS4zID0gY3ZjLWF0dHJpYnV0ZS4zOiBUaGUgdmFsdWUgJyd7Mn0nJyBvZiBhdHRyaWJ1dGUgJyd7MX0nJyBvbiBlbGVtZW50ICcnezB9JycgaXMgbm90IHZhbGlkIHdpdGggcmVzcGVjdCB0byBpdHMgdHlwZSwgJyd7M30nJy4KLSAgICAgICAgY3ZjLWF0dHJpYnV0ZS40ID0gY3ZjLWF0dHJpYnV0ZS40OiBUaGUgdmFsdWUgJyd7Mn0nJyBvZiBhdHRyaWJ1dGUgJyd7MX0nJyBvbiBlbGVtZW50ICcnezB9JycgaXMgbm90IHZhbGlkIHdpdGggcmVzcGVjdCB0byBpdHMgZml4ZWQgJ3sndmFsdWUgY29uc3RyYWludCd9Jy4gVGhlIGF0dHJpYnV0ZSBtdXN0IGhhdmUgYSB2YWx1ZSBvZiAnJ3szfScnLgotICAgICAgICBjdmMtY29tcGxleC10eXBlLjIuMSA9IGN2Yy1jb21wbGV4LXR5cGUuMi4xOiBFbGVtZW50ICcnezB9JycgbXVzdCBoYXZlIG5vIGNoYXJhY3RlciBvciBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0gW2NoaWxkcmVuXSwgYmVjYXVzZSB0aGUgdHlwZScncyBjb250ZW50IHR5cGUgaXMgZW1wdHkuCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuMi4yID0gY3ZjLWNvbXBsZXgtdHlwZS4yLjI6IEVsZW1lbnQgJyd7MH0nJyBtdXN0IGhhdmUgbm8gZWxlbWVudCBbY2hpbGRyZW5dLCBhbmQgdGhlIHZhbHVlIG11c3QgYmUgdmFsaWQuCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuMi4zID0gY3ZjLWNvbXBsZXgtdHlwZS4yLjM6IEVsZW1lbnQgJyd7MH0nJyBjYW5ub3QgaGF2ZSBjaGFyYWN0ZXIgW2NoaWxkcmVuXSwgYmVjYXVzZSB0aGUgdHlwZScncyBjb250ZW50IHR5cGUgaXMgZWxlbWVudC1vbmx5LgotICAgICAgICBjdmMtY29tcGxleC10eXBlLjIuNC5hID0gY3ZjLWNvbXBsZXgtdHlwZS4yLjQuYTogSW52YWxpZCBjb250ZW50IHdhcyBmb3VuZCBzdGFydGluZyB3aXRoIGVsZW1lbnQgJyd7MH0nJy4gT25lIG9mICcnezF9JycgaXMgZXhwZWN0ZWQuCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuMi40LmIgPSBjdmMtY29tcGxleC10eXBlLjIuNC5iOiBUaGUgY29udGVudCBvZiBlbGVtZW50ICcnezB9JycgaXMgbm90IGNvbXBsZXRlLiBPbmUgb2YgJyd7MX0nJyBpcyBleHBlY3RlZC4KLSAgICAgICAgY3ZjLWNvbXBsZXgtdHlwZS4yLjQuYyA9IGN2Yy1jb21wbGV4LXR5cGUuMi40LmM6IFRoZSBtYXRjaGluZyB3aWxkY2FyZCBpcyBzdHJpY3QsIGJ1dCBubyBkZWNsYXJhdGlvbiBjYW4gYmUgZm91bmQgZm9yIGVsZW1lbnQgJyd7MH0nJy4KLSAgICAgICAgY3ZjLWNvbXBsZXgtdHlwZS4yLjQuZCA9IGN2Yy1jb21wbGV4LXR5cGUuMi40LmQ6IEludmFsaWQgY29udGVudCB3YXMgZm91bmQgc3RhcnRpbmcgd2l0aCBlbGVtZW50ICcnezB9JycuIE5vIGNoaWxkIGVsZW1lbnQgaXMgZXhwZWN0ZWQgYXQgdGhpcyBwb2ludC4KLSAgICAgICAgY3ZjLWNvbXBsZXgtdHlwZS4yLjQuZSA9IGN2Yy1jb21wbGV4LXR5cGUuMi40LmQ6IEludmFsaWQgY29udGVudCB3YXMgZm91bmQgc3RhcnRpbmcgd2l0aCBlbGVtZW50ICcnezB9JycuIE5vIGNoaWxkIGVsZW1lbnQgJyd7MX0nJyBpcyBleHBlY3RlZCBhdCB0aGlzIHBvaW50LgotICAgICAgICBjdmMtY29tcGxleC10eXBlLjMuMSA9IGN2Yy1jb21wbGV4LXR5cGUuMy4xOiBWYWx1ZSAnJ3syfScnIG9mIGF0dHJpYnV0ZSAnJ3sxfScnIG9mIGVsZW1lbnQgJyd7MH0nJyBpcyBub3QgdmFsaWQgd2l0aCByZXNwZWN0IHRvIHRoZSBjb3JyZXNwb25kaW5nIGF0dHJpYnV0ZSB1c2UuIEF0dHJpYnV0ZSAnJ3sxfScnIGhhcyBhIGZpeGVkIHZhbHVlIG9mICcnezN9JycuCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuMy4yLjEgPSBjdmMtY29tcGxleC10eXBlLjMuMi4xOiBFbGVtZW50ICcnezB9JycgZG9lcyBub3QgaGF2ZSBhbiBhdHRyaWJ1dGUgd2lsZGNhcmQgZm9yIGF0dHJpYnV0ZSAnJ3sxfScnLgotICAgICAgICBjdmMtY29tcGxleC10eXBlLjMuMi4yID0gY3ZjLWNvbXBsZXgtdHlwZS4zLjIuMjogQXR0cmlidXRlICcnezF9JycgaXMgbm90IGFsbG93ZWQgdG8gYXBwZWFyIGluIGVsZW1lbnQgJyd7MH0nJy4KLSAgICAgICAgY3ZjLWNvbXBsZXgtdHlwZS40ID0gY3ZjLWNvbXBsZXgtdHlwZS40OiBBdHRyaWJ1dGUgJyd7MX0nJyBtdXN0IGFwcGVhciBvbiBlbGVtZW50ICcnezB9JycuCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuNS4xID0gY3ZjLWNvbXBsZXgtdHlwZS41LjE6IEluIGVsZW1lbnQgJyd7MH0nJywgYXR0cmlidXRlICcnezF9JycgaXMgYSBXaWxkIElELiBCdXQgdGhlcmUgaXMgYWxyZWFkeSBhIFdpbGQgSUQgJyd7Mn0nJy4gVGhlcmUgY2FuIGJlIG9ubHkgb25lLgotICAgICAgICBjdmMtY29tcGxleC10eXBlLjUuMiA9IGN2Yy1jb21wbGV4LXR5cGUuNS4yOiBJbiBlbGVtZW50ICcnezB9JycsIGF0dHJpYnV0ZSAnJ3sxfScnIGlzIGEgV2lsZCBJRC4gQnV0IHRoZXJlIGlzIGFscmVhZHkgYW4gYXR0cmlidXRlICcnezJ9JycgZGVyaXZlZCBmcm9tIElEIGFtb25nIHRoZSAneydhdHRyaWJ1dGUgdXNlcyd9Jy4KLSAgICAgICAgY3ZjLWRhdGF0eXBlLXZhbGlkLjEuMi4xID0gY3ZjLWRhdGF0eXBlLXZhbGlkLjEuMi4xOiAnJ3swfScnIGlzIG5vdCBhIHZhbGlkIHZhbHVlIGZvciAnJ3sxfScnLgotICAgICAgICBjdmMtZGF0YXR5cGUtdmFsaWQuMS4yLjIgPSBjdmMtZGF0YXR5cGUtdmFsaWQuMS4yLjI6ICcnezB9JycgaXMgbm90IGEgdmFsaWQgdmFsdWUgb2YgbGlzdCB0eXBlICcnezF9JycuCi0gICAgICAgIGN2Yy1kYXRhdHlwZS12YWxpZC4xLjIuMyA9IGN2Yy1kYXRhdHlwZS12YWxpZC4xLjIuMzogJyd7MH0nJyBpcyBub3QgYSB2YWxpZCB2YWx1ZSBvZiB1bmlvbiB0eXBlICcnezF9JycuCi0gICAgICAgIGN2Yy1lbHQuMSA9IGN2Yy1lbHQuMTogQ2Fubm90IGZpbmQgdGhlIGRlY2xhcmF0aW9uIG9mIGVsZW1lbnQgJyd7MH0nJy4KLSAgICAgICAgY3ZjLWVsdC4yID0gY3ZjLWVsdC4yOiBUaGUgdmFsdWUgb2YgJ3snYWJzdHJhY3QnfScgaW4gdGhlIGVsZW1lbnQgZGVjbGFyYXRpb24gZm9yICcnezB9JycgbXVzdCBiZSBmYWxzZS4KLSAgICAgICAgY3ZjLWVsdC4zLjEgPSBjdmMtZWx0LjMuMTogQXR0cmlidXRlICcnezF9JycgbXVzdCBub3QgYXBwZWFyIG9uIGVsZW1lbnQgJyd7MH0nJywgYmVjYXVzZSB0aGUgJ3snbmlsbGFibGUnfScgcHJvcGVydHkgb2YgJyd7MH0nJyBpcyBmYWxzZS4KLSAgICAgICAgY3ZjLWVsdC4zLjIuMSA9IGN2Yy1lbHQuMy4yLjE6IEVsZW1lbnQgJyd7MH0nJyBjYW5ub3QgaGF2ZSBjaGFyYWN0ZXIgb3IgZWxlbWVudCBpbmZvcm1hdGlvbiBbY2hpbGRyZW5dLCBiZWNhdXNlICcnezF9JycgaXMgc3BlY2lmaWVkLgotICAgICAgICBjdmMtZWx0LjMuMi4yID0gY3ZjLWVsdC4zLjIuMjogVGhlcmUgbXVzdCBiZSBubyBmaXhlZCAneyd2YWx1ZSBjb25zdHJhaW50J30nIGZvciBlbGVtZW50ICcnezB9JycsIGJlY2F1c2UgJyd7MX0nJyBpcyBzcGVjaWZpZWQuCi0gICAgICAgIGN2Yy1lbHQuNC4xID0gY3ZjLWVsdC40LjE6IFRoZSB2YWx1ZSAnJ3syfScnIG9mIGF0dHJpYnV0ZSAnJ3sxfScnIG9mIGVsZW1lbnQgJyd7MH0nJyBpcyBub3QgYSB2YWxpZCBRTmFtZS4KLSAgICAgICAgY3ZjLWVsdC40LjIgPSBjdmMtZWx0LjQuMjogQ2Fubm90IHJlc29sdmUgJyd7MX0nJyB0byBhIHR5cGUgZGVmaW5pdGlvbiBmb3IgZWxlbWVudCAnJ3swfScnLgotICAgICAgICBjdmMtZWx0LjQuMyA9IGN2Yy1lbHQuNC4zOiBUeXBlICcnezF9JycgaXMgbm90IHZhbGlkbHkgZGVyaXZlZCBmcm9tIHRoZSB0eXBlIGRlZmluaXRpb24sICcnezJ9JycsIG9mIGVsZW1lbnQgJyd7MH0nJy4KLSAgICAgICAgY3ZjLWVsdC41LjEuMSA9IGN2Yy1lbHQuNS4xLjE6ICd7J3ZhbHVlIGNvbnN0cmFpbnQnfScgJyd7Mn0nJyBvZiBlbGVtZW50ICcnezB9JycgaXMgbm90IGEgdmFsaWQgZGVmYXVsdCB2YWx1ZSBmb3IgdHlwZSAnJ3sxfScnLgotICAgICAgICBjdmMtZWx0LjUuMi4yLjEgPSBjdmMtZWx0LjUuMi4yLjE6IEVsZW1lbnQgJyd7MH0nJyBtdXN0IGhhdmUgbm8gZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIFtjaGlsZHJlbl0uCi0gICAgICAgIGN2Yy1lbHQuNS4yLjIuMi4xID0gY3ZjLWVsdC41LjIuMi4yLjE6IFRoZSB2YWx1ZSAnJ3sxfScnIG9mIGVsZW1lbnQgJyd7MH0nJyBkb2VzIG5vdCBtYXRjaCB0aGUgZml4ZWQgJ3sndmFsdWUgY29uc3RyYWludCd9JyB2YWx1ZSAnJ3syfScnLgotICAgICAgICBjdmMtZWx0LjUuMi4yLjIuMiA9IGN2Yy1lbHQuNS4yLjIuMi4yOiBUaGUgdmFsdWUgJyd7MX0nJyBvZiBlbGVtZW50ICcnezB9JycgZG9lcyBub3QgbWF0Y2ggdGhlICd7J3ZhbHVlIGNvbnN0cmFpbnQnfScgdmFsdWUgJyd7Mn0nJy4KLSAgICAgICAgY3ZjLWVudW1lcmF0aW9uLXZhbGlkID0gY3ZjLWVudW1lcmF0aW9uLXZhbGlkOiBWYWx1ZSAnJ3swfScnIGlzIG5vdCBmYWNldC12YWxpZCB3aXRoIHJlc3BlY3QgdG8gZW51bWVyYXRpb24gJyd7MX0nJy4gSXQgbXVzdCBiZSBhIHZhbHVlIGZyb20gdGhlIGVudW1lcmF0aW9uLgotICAgICAgICBjdmMtZnJhY3Rpb25EaWdpdHMtdmFsaWQgPSBjdmMtZnJhY3Rpb25EaWdpdHMtdmFsaWQ6IFZhbHVlICcnezB9JycgaGFzIHsxfSBmcmFjdGlvbiBkaWdpdHMsIGJ1dCB0aGUgbnVtYmVyIG9mIGZyYWN0aW9uIGRpZ2l0cyBoYXMgYmVlbiBsaW1pdGVkIHRvIHsyfS4KLSAgICAgICAgY3ZjLWlkLjEgPSBjdmMtaWQuMTogVGhlcmUgaXMgbm8gSUQvSURSRUYgYmluZGluZyBmb3IgSURSRUYgJyd7MH0nJy4KLSAgICAgICAgY3ZjLWlkLjIgPSBjdmMtaWQuMjogVGhlcmUgYXJlIG11bHRpcGxlIG9jY3VycmVuY2VzIG9mIElEIHZhbHVlICcnezB9JycuCi0gICAgICAgIGN2Yy1pZC4zID0gY3ZjLWlkLjM6IEEgZmllbGQgb2YgaWRlbnRpdHkgY29uc3RyYWludCAnJ3swfScnIG1hdGNoZWQgZWxlbWVudCAnJ3sxfScnLCBidXQgdGhpcyBlbGVtZW50IGRvZXMgbm90IGhhdmUgYSBzaW1wbGUgdHlwZS4KLSAgICAgICAgY3ZjLWxlbmd0aC12YWxpZCA9IGN2Yy1sZW5ndGgtdmFsaWQ6IFZhbHVlICcnezB9Jycgd2l0aCBsZW5ndGggPSAnJ3sxfScnIGlzIG5vdCBmYWNldC12YWxpZCB3aXRoIHJlc3BlY3QgdG8gbGVuZ3RoICcnezJ9JycgZm9yIHR5cGUgJyd7M30nJy4KLSAgICAgICAgY3ZjLW1heEV4Y2x1c2l2ZS12YWxpZCA9IGN2Yy1tYXhFeGNsdXNpdmUtdmFsaWQ6IFZhbHVlICcnezB9JycgaXMgbm90IGZhY2V0LXZhbGlkIHdpdGggcmVzcGVjdCB0byBtYXhFeGNsdXNpdmUgJyd7MX0nJyBmb3IgdHlwZSAnJ3syfScnLgotICAgICAgICBjdmMtbWF4SW5jbHVzaXZlLXZhbGlkID0gY3ZjLW1heEluY2x1c2l2ZS12YWxpZDogVmFsdWUgJyd7MH0nJyBpcyBub3QgZmFjZXQtdmFsaWQgd2l0aCByZXNwZWN0IHRvIG1heEluY2x1c2l2ZSAnJ3sxfScnIGZvciB0eXBlICcnezJ9JycuCi0gICAgICAgIGN2Yy1tYXhMZW5ndGgtdmFsaWQgPSBjdmMtbWF4TGVuZ3RoLXZhbGlkOiBWYWx1ZSAnJ3swfScnIHdpdGggbGVuZ3RoID0gJyd7MX0nJyBpcyBub3QgZmFjZXQtdmFsaWQgd2l0aCByZXNwZWN0IHRvIG1heExlbmd0aCAnJ3syfScnIGZvciB0eXBlICcnezN9JycuCi0gICAgICAgIGN2Yy1taW5FeGNsdXNpdmUtdmFsaWQgPSBjdmMtbWluRXhjbHVzaXZlLXZhbGlkOiBWYWx1ZSAnJ3swfScnIGlzIG5vdCBmYWNldC12YWxpZCB3aXRoIHJlc3BlY3QgdG8gbWluRXhjbHVzaXZlICcnezF9JycgZm9yIHR5cGUgJyd7Mn0nJy4KLSAgICAgICAgY3ZjLW1pbkluY2x1c2l2ZS12YWxpZCA9IGN2Yy1taW5JbmNsdXNpdmUtdmFsaWQ6IFZhbHVlICcnezB9JycgaXMgbm90IGZhY2V0LXZhbGlkIHdpdGggcmVzcGVjdCB0byBtaW5JbmNsdXNpdmUgJyd7MX0nJyBmb3IgdHlwZSAnJ3syfScnLgotICAgICAgICBjdmMtbWluTGVuZ3RoLXZhbGlkID0gY3ZjLW1pbkxlbmd0aC12YWxpZDogVmFsdWUgJyd7MH0nJyB3aXRoIGxlbmd0aCA9ICcnezF9JycgaXMgbm90IGZhY2V0LXZhbGlkIHdpdGggcmVzcGVjdCB0byBtaW5MZW5ndGggJyd7Mn0nJyBmb3IgdHlwZSAnJ3szfScnLgotICAgICAgICBjdmMtcGF0dGVybi12YWxpZCA9IGN2Yy1wYXR0ZXJuLXZhbGlkOiBWYWx1ZSAnJ3swfScnIGlzIG5vdCBmYWNldC12YWxpZCB3aXRoIHJlc3BlY3QgdG8gcGF0dGVybiAnJ3sxfScnIGZvciB0eXBlICcnezJ9JycuCi0gICAgICAgIGN2Yy10b3RhbERpZ2l0cy12YWxpZCA9IGN2Yy10b3RhbERpZ2l0cy12YWxpZDogVmFsdWUgJyd7MH0nJyBoYXMgezF9IHRvdGFsIGRpZ2l0cywgYnV0IHRoZSBudW1iZXIgb2YgdG90YWwgZGlnaXRzIGhhcyBiZWVuIGxpbWl0ZWQgdG8gezJ9LgotICAgICAgICBjdmMtdHlwZS4yID0gY3ZjLXR5cGUuMjogVGhlIHR5cGUgZGVmaW5pdGlvbiBjYW5ub3QgYmUgYWJzdHJhY3QgZm9yIGVsZW1lbnQgezB9LgotICAgICAgICBjdmMtdHlwZS4zLjEuMSA9IGN2Yy10eXBlLjMuMS4xOiBFbGVtZW50ICcnezB9JycgaXMgYSBzaW1wbGUgdHlwZSwgc28gaXQgY2Fubm90IGhhdmUgYXR0cmlidXRlcywgZXhjZXB0aW5nIHRob3NlIHdob3NlIG5hbWVzcGFjZSBuYW1lIGlzIGlkZW50aWNhbCB0byAnJ2h0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlJycgYW5kIHdob3NlIFtsb2NhbCBuYW1lXSBpcyBvbmUgb2YgJyd0eXBlJycsICcnbmlsJycsICcnc2NoZW1hTG9jYXRpb24nJyBvciAnJ25vTmFtZXNwYWNlU2NoZW1hTG9jYXRpb24nJy4gSG93ZXZlciwgdGhlIGF0dHJpYnV0ZSwgJyd7MX0nJyB3YXMgZm91bmQuCi0gICAgICAgIGN2Yy10eXBlLjMuMS4yID0gY3ZjLXR5cGUuMy4xLjI6IEVsZW1lbnQgJyd7MH0nJyBpcyBhIHNpbXBsZSB0eXBlLCBzbyBpdCBtdXN0IGhhdmUgbm8gZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIFtjaGlsZHJlbl0uCi0gICAgICAgIGN2Yy10eXBlLjMuMS4zID0gY3ZjLXR5cGUuMy4xLjM6IFRoZSB2YWx1ZSAnJ3sxfScnIG9mIGVsZW1lbnQgJyd7MH0nJyBpcyBub3QgdmFsaWQuCi0KLSNzY2hlbWEgdmFsaWQgKDMuWC4zKQotCi0gICAgICAgIHNjaGVtYV9yZWZlcmVuY2UuYWNjZXNzID0gc2NoZW1hX3JlZmVyZW5jZTogRmFpbGVkIHRvIHJlYWQgc2NoZW1hIGRvY3VtZW50ICcnezB9JycsIGJlY2F1c2UgJyd7MX0nJyBhY2Nlc3MgaXMgbm90IGFsbG93ZWQgZHVlIHRvIHJlc3RyaWN0aW9uIHNldCBieSB0aGUgYWNjZXNzRXh0ZXJuYWxTY2hlbWEgcHJvcGVydHkuIAotICAgICAgICBzY2hlbWFfcmVmZXJlbmNlLjQgPSBzY2hlbWFfcmVmZXJlbmNlLjQ6IEZhaWxlZCB0byByZWFkIHNjaGVtYSBkb2N1bWVudCAnJ3swfScnLCBiZWNhdXNlIDEpIGNvdWxkIG5vdCBmaW5kIHRoZSBkb2N1bWVudDsgMikgdGhlIGRvY3VtZW50IGNvdWxkIG5vdCBiZSByZWFkOyAzKSB0aGUgcm9vdCBlbGVtZW50IG9mIHRoZSBkb2N1bWVudCBpcyBub3QgPHhzZDpzY2hlbWE+LgotICAgICAgICBzcmMtYW5ub3RhdGlvbiA9IHNyYy1hbm5vdGF0aW9uOiA8YW5ub3RhdGlvbj4gZWxlbWVudHMgY2FuIG9ubHkgY29udGFpbiA8YXBwaW5mbz4gYW5kIDxkb2N1bWVudGF0aW9uPiBlbGVtZW50cywgYnV0ICcnezB9Jycgd2FzIGZvdW5kLgotICAgICAgICBzcmMtYXR0cmlidXRlLjEgPSBzcmMtYXR0cmlidXRlLjE6IFRoZSBwcm9wZXJ0aWVzICcnZGVmYXVsdCcnIGFuZCAnJ2ZpeGVkJycgY2Fubm90IGJvdGggYmUgcHJlc2VudCBpbiBhdHRyaWJ1dGUgZGVjbGFyYXRpb24gJyd7MH0nJy4gVXNlIG9ubHkgb25lIG9mIHRoZW0uCi0gICAgICAgIHNyYy1hdHRyaWJ1dGUuMiA9IHNyYy1hdHRyaWJ1dGUuMjogOiBUaGUgcHJvcGVydHkgJydkZWZhdWx0JycgaXMgcHJlc2VudCBpbiBhdHRyaWJ1dGUgJyd7MH0nJywgc28gdGhlIHZhbHVlIG9mICcndXNlJycgbXVzdCBiZSAnJ29wdGlvbmFsJycuCi0gICAgICAgIHNyYy1hdHRyaWJ1dGUuMy4xID0gc3JjLWF0dHJpYnV0ZS4zLjE6IE9uZSBvZiAncmVmJyBvciAnbmFtZScgbXVzdCBiZSBwcmVzZW50IGluIGEgbG9jYWwgYXR0cmlidXRlIGRlY2xhcmF0aW9uLgotICAgICAgICBzcmMtYXR0cmlidXRlLjMuMiA9IHNyYy1hdHRyaWJ1dGUuMy4yOiBUaGUgY29udGVudCBtdXN0IG1hdGNoIChhbm5vdGF0aW9uPykgZm9yIHRoZSBhdHRyaWJ1dGUgcmVmZXJlbmNlICcnezB9JycuCi0gICAgICAgIHNyYy1hdHRyaWJ1dGUuNCA9IHNyYy1hdHRyaWJ1dGUuNDogQXR0cmlidXRlICcnezB9JycgaGFzIGJvdGggYSAnJ3R5cGUnJyBhdHRyaWJ1dGUgYW5kIGFuIGFub255bW91cyAnJ3NpbXBsZVR5cGUnJyBjaGlsZC4gT25seSBvbmUgb2YgdGhlc2UgaXMgYWxsb3dlZCBmb3IgYW4gYXR0cmlidXRlLgotICAgICAgICBzcmMtYXR0cmlidXRlX2dyb3VwLjIgPSBzcmMtYXR0cmlidXRlX2dyb3VwLjI6IFRoZSBpbnRlcnNlY3Rpb24gb2Ygd2lsZGNhcmRzIGlzIG5vdCBleHByZXNzaWJsZSBmb3IgYXR0cmlidXRlIGdyb3VwICcnezB9JycuCi0gICAgICAgIHNyYy1hdHRyaWJ1dGVfZ3JvdXAuMyA9IHNyYy1hdHRyaWJ1dGVfZ3JvdXAuMzogQ2lyY3VsYXIgZGVmaW5pdGlvbnMgZGV0ZWN0ZWQgZm9yIGF0dHJpYnV0ZSBncm91cCAnJ3swfScnLiBSZWN1cnNpdmVseSBmb2xsb3dpbmcgYXR0cmlidXRlIGdyb3VwIHJlZmVyZW5jZXMgZXZlbnR1YWxseSBsZWFkcyBiYWNrIHRvIGl0c2VsZi4KLSAgICAgICAgc3JjLWN0LjEgPSBzcmMtY3QuMTogQ29tcGxleCBUeXBlIERlZmluaXRpb24gUmVwcmVzZW50YXRpb24gRXJyb3IgZm9yIHR5cGUgJyd7MH0nJy4gIFdoZW4gPGNvbXBsZXhDb250ZW50PiBpcyB1c2VkLCB0aGUgYmFzZSB0eXBlIG11c3QgYmUgYSBjb21wbGV4VHlwZS4gJyd7MX0nJyBpcyBhIHNpbXBsZVR5cGUuCi0gICAgICAgIHNyYy1jdC4yLjEgPSBzcmMtY3QuMi4xOiBDb21wbGV4IFR5cGUgRGVmaW5pdGlvbiBSZXByZXNlbnRhdGlvbiBFcnJvciBmb3IgdHlwZSAnJ3swfScnLiAgV2hlbiA8c2ltcGxlQ29udGVudD4gaXMgdXNlZCwgdGhlIGJhc2UgdHlwZSBtdXN0IGJlIGEgY29tcGxleFR5cGUgd2hvc2UgY29udGVudCB0eXBlIGlzIHNpbXBsZSwgb3IsIG9ubHkgaWYgcmVzdHJpY3Rpb24gaXMgc3BlY2lmaWVkLCBhIGNvbXBsZXggdHlwZSB3aXRoIG1peGVkIGNvbnRlbnQgYW5kIGVtcHRpYWJsZSBwYXJ0aWNsZSwgb3IsIG9ubHkgaWYgZXh0ZW5zaW9uIGlzIHNwZWNpZmllZCwgYSBzaW1wbGUgdHlwZS4gJyd7MX0nJyBzYXRpc2ZpZXMgbm9uZSBvZiB0aGVzZSBjb25kaXRpb25zLgotICAgICAgICBzcmMtY3QuMi4yID0gc3JjLWN0LjIuMjogQ29tcGxleCBUeXBlIERlZmluaXRpb24gUmVwcmVzZW50YXRpb24gRXJyb3IgZm9yIHR5cGUgJyd7MH0nJy4gIFdoZW4gYSBjb21wbGV4VHlwZSB3aXRoIHNpbXBsZUNvbnRlbnQgcmVzdHJpY3RzIGEgY29tcGxleFR5cGUgd2l0aCBtaXhlZCBjb250ZW50IGFuZCBlbXB0aWFibGUgcGFydGljbGUsIHRoZW4gdGhlcmUgbXVzdCBiZSBhIDxzaW1wbGVUeXBlPiBhbW9uZyB0aGUgY2hpbGRyZW4gb2YgPHJlc3RyaWN0aW9uPi4KLSAgICAgICAgc3JjLWN0LjQgPSBzcmMtY3QuNDogQ29tcGxleCBUeXBlIERlZmluaXRpb24gUmVwcmVzZW50YXRpb24gRXJyb3IgZm9yIHR5cGUgJyd7MH0nJy4gIFRoZSBpbnRlcnNlY3Rpb24gb2Ygd2lsZGNhcmRzIGlzIG5vdCBleHByZXNzaWJsZS4KLSAgICAgICAgc3JjLWN0LjUgPSBzcmMtY3QuNTogQ29tcGxleCBUeXBlIERlZmluaXRpb24gUmVwcmVzZW50YXRpb24gRXJyb3IgZm9yIHR5cGUgJyd7MH0nJy4gVGhlIHVuaW9uIG9mIHdpbGRjYXJkcyBpcyBub3QgZXhwcmVzc2libGUuCi0gICAgICAgIHNyYy1lbGVtZW50LjEgPSBzcmMtZWxlbWVudC4xOiBUaGUgcHJvcGVydGllcyAnJ2RlZmF1bHQnJyBhbmQgJydmaXhlZCcnIGNhbm5vdCBib3RoIGJlIHByZXNlbnQgaW4gZWxlbWVudCBkZWNsYXJhdGlvbiAnJ3swfScnLiBVc2Ugb25seSBvbmUgb2YgdGhlbS4KLSAgICAgICAgc3JjLWVsZW1lbnQuMi4xID0gc3JjLWVsZW1lbnQuMi4xOiA6IE9uZSBvZiAncmVmJyBvciAnbmFtZScgbXVzdCBiZSBwcmVzZW50IGluIGEgbG9jYWwgZWxlbWVudCBkZWNsYXJhdGlvbi4KLSAgICAgICAgc3JjLWVsZW1lbnQuMi4yID0gc3JjLWVsZW1lbnQuMi4yOiBTaW5jZSAnJ3swfScnIGNvbnRhaW5zIHRoZSAnJ3JlZicnIGF0dHJpYnV0ZSwgaXRzIGNvbnRlbnQgbXVzdCBtYXRjaCAoYW5ub3RhdGlvbj8pLiBIb3dldmVyLCAnJ3sxfScnIHdhcyBmb3VuZC4KLSAgICAgICAgc3JjLWVsZW1lbnQuMyA9IHNyYy1lbGVtZW50LjM6IEVsZW1lbnQgJyd7MH0nJyBoYXMgYm90aCBhICcndHlwZScnIGF0dHJpYnV0ZSBhbmQgYSAnJ2Fub255bW91cyB0eXBlJycgY2hpbGQuIE9ubHkgb25lIG9mIHRoZXNlIGlzIGFsbG93ZWQgZm9yIGFuIGVsZW1lbnQuCi0gICAgICAgIHNyYy1pbXBvcnQuMS4xID0gc3JjLWltcG9ydC4xLjE6IFRoZSBuYW1lc3BhY2UgYXR0cmlidXRlICcnezB9Jycgb2YgYW4gPGltcG9ydD4gZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIG11c3Qgbm90IGJlIHRoZSBzYW1lIGFzIHRoZSB0YXJnZXROYW1lc3BhY2Ugb2YgdGhlIHNjaGVtYSBpdCBleGlzdHMgaW4uCi0gICAgICAgIHNyYy1pbXBvcnQuMS4yID0gc3JjLWltcG9ydC4xLjI6IElmIHRoZSBuYW1lc3BhY2UgYXR0cmlidXRlIGlzIG5vdCBwcmVzZW50IG9uIGFuIDxpbXBvcnQ+IGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSB0aGVuIHRoZSBlbmNsb3Npbmcgc2NoZW1hIG11c3QgaGF2ZSBhIHRhcmdldE5hbWVzcGFjZS4KLSAgICAgICAgc3JjLWltcG9ydC4yID0gc3JjLWltcG9ydC4yOiBUaGUgcm9vdCBlbGVtZW50IG9mIGRvY3VtZW50ICcnezB9JycgaGFzIHRvIGhhdmUgdGhlIG5hbWVzcGFjZSBuYW1lICcnaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEnJyBhbmQgdGhlIGxvY2FsIG5hbWUgJydzY2hlbWEnJy4KLSAgICAgICAgc3JjLWltcG9ydC4zLjEgPSBzcmMtaW1wb3J0LjMuMTogVGhlIG5hbWVzcGFjZSBhdHRyaWJ1dGUsICcnezB9JycsIG9mIGFuIDxpbXBvcnQ+IGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSBtdXN0IGJlIGlkZW50aWNhbCB0byB0aGUgdGFyZ2V0TmFtZXNwYWNlIGF0dHJpYnV0ZSwgJyd7MX0nJywgb2YgdGhlIGltcG9ydGVkIGRvY3VtZW50LgotICAgICAgICBzcmMtaW1wb3J0LjMuMiA9IHNyYy1pbXBvcnQuMy4yOiBBbiA8aW1wb3J0PiBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0gdGhhdCBoYWQgbm8gbmFtZXNwYWNlIGF0dHJpYnV0ZSB3YXMgZm91bmQsIHNvIHRoZSBpbXBvcnRlZCBkb2N1bWVudCBjYW5ub3QgaGF2ZSBhIHRhcmdldE5hbWVzcGFjZSBhdHRyaWJ1dGUuIEhvd2V2ZXIsIHRoZSB0YXJnZXROYW1lc3BhY2UgJyd7MX0nJyB3YXMgZm91bmQgaW4gdGhlIGltcG9ydGVkIGRvY3VtZW50LgotICAgICAgICBzcmMtaW5jbHVkZS4xID0gc3JjLWluY2x1ZGUuMTogVGhlIHJvb3QgZWxlbWVudCBvZiBkb2N1bWVudCAnJ3swfScnIGhhcyB0byBoYXZlIHRoZSBuYW1lc3BhY2UgbmFtZSAnJ2h0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hJycgYW5kIHRoZSBsb2NhbCBuYW1lICcnc2NoZW1hJycuCi0gICAgICAgIHNyYy1pbmNsdWRlLjIuMSA9IHNyYy1pbmNsdWRlLjIuMTogVGhlIHRhcmdldE5hbWVzcGFjZSBvZiB0aGUgcmVmZXJlbmNlZCBzY2hlbWEsIGN1cnJlbnRseSAnJ3sxfScnLCBtdXN0IGJlIGlkZW50aWNhbCB0byB0aGF0IG9mIHRoZSBpbmNsdWRpbmcgc2NoZW1hLCBjdXJyZW50bHkgJyd7MH0nJy4KLSAgICAgICAgc3JjLXJlZGVmaW5lLjIgPSBzcmMtcmVkZWZpbmUuMjogVGhlIHJvb3QgZWxlbWVudCBvZiBkb2N1bWVudCAnJ3swfScnIGhhcyB0byBoYXZlIHRoZSBuYW1lc3BhY2UgbmFtZSAnJ2h0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hJycgYW5kIHRoZSBsb2NhbCBuYW1lICcnc2NoZW1hJycuCi0gICAgICAgIHNyYy1yZWRlZmluZS4zLjEgPSBzcmMtcmVkZWZpbmUuMy4xOiBUaGUgdGFyZ2V0TmFtZXNwYWNlIG9mIHRoZSByZWZlcmVuY2VkIHNjaGVtYSwgY3VycmVudGx5ICcnezF9JycsIG11c3QgYmUgaWRlbnRpY2FsIHRvIHRoYXQgb2YgdGhlIHJlZGVmaW5pbmcgc2NoZW1hLCBjdXJyZW50bHkgJyd7MH0nJy4KLSAgICAgICAgc3JjLXJlZGVmaW5lLjUuYS5hID0gc3JjLXJlZGVmaW5lLjUuYS5hOiBObyBub24tYW5ub3RhdGlvbiBjaGlsZHJlbiBvZiA8c2ltcGxlVHlwZT4gd2VyZSBmb3VuZC4gPHNpbXBsZVR5cGU+IGNoaWxkcmVuIG9mIDxyZWRlZmluZT4gZWxlbWVudHMgbXVzdCBoYXZlIDxyZXN0cmljdGlvbj4gZGVzY2VuZGFudHMsIHdpdGggJ2Jhc2UnIGF0dHJpYnV0ZXMgdGhhdCByZWZlciB0byB0aGVtc2VsdmVzLgotICAgICAgICBzcmMtcmVkZWZpbmUuNS5hLmIgPSBzcmMtcmVkZWZpbmUuNS5hLmI6ICcnezB9JycgaXMgbm90IGEgdmFsaWQgY2hpbGQgZWxlbWVudC4gPHNpbXBsZVR5cGU+IGNoaWxkcmVuIG9mIDxyZWRlZmluZT4gZWxlbWVudHMgbXVzdCBoYXZlIDxyZXN0cmljdGlvbj4gZGVzY2VuZGFudHMsIHdpdGggJydiYXNlJycgYXR0cmlidXRlcyB0aGF0IHJlZmVyIHRvIHRoZW1zZWx2ZXMuCi0gICAgICAgIHNyYy1yZWRlZmluZS41LmEuYyA9IHNyYy1yZWRlZmluZS41LmEuYzogJyd7MH0nJyBkb2VzIG5vdCBoYXZlIGEgJydiYXNlJycgYXR0cmlidXRlIHRoYXQgcmVmZXJzIHRvIHRoZSByZWRlZmluZWQgZWxlbWVudCwgJyd7MX0nJy4gPHNpbXBsZVR5cGU+IGNoaWxkcmVuIG9mIDxyZWRlZmluZT4gZWxlbWVudHMgbXVzdCBoYXZlIDxyZXN0cmljdGlvbj4gZGVzY2VuZGFudHMsIHdpdGggJydiYXNlJycgYXR0cmlidXRlcyB0aGF0IHJlZmVyIHRvIHRoZW1zZWx2ZXMuCi0gICAgICAgIHNyYy1yZWRlZmluZS41LmIuYSA9IHNyYy1yZWRlZmluZS41LmIuYTogTm8gbm9uLWFubm90YXRpb24gY2hpbGRyZW4gb2YgPGNvbXBsZXhUeXBlPiB3ZXJlIGZvdW5kLiA8Y29tcGxleFR5cGU+IGNoaWxkcmVuIG9mIDxyZWRlZmluZT4gZWxlbWVudHMgbXVzdCBoYXZlIDxleHRlbnNpb24+IG9yIDxyZXN0cmljdGlvbj4gZGVzY2VuZGFudHMsIHdpdGggJ2Jhc2UnIGF0dHJpYnV0ZXMgdGhhdCByZWZlciB0byB0aGVtc2VsdmVzLgotICAgICAgICBzcmMtcmVkZWZpbmUuNS5iLmIgPSBzcmMtcmVkZWZpbmUuNS5iLmI6IE5vIG5vbi1hbm5vdGF0aW9uIGdyYW5kY2hpbGRyZW4gb2YgPGNvbXBsZXhUeXBlPiB3ZXJlIGZvdW5kLiA8Y29tcGxleFR5cGU+IGNoaWxkcmVuIG9mIDxyZWRlZmluZT4gZWxlbWVudHMgbXVzdCBoYXZlIDxleHRlbnNpb24+IG9yIDxyZXN0cmljdGlvbj4gZGVzY2VuZGFudHMsIHdpdGggJ2Jhc2UnIGF0dHJpYnV0ZXMgdGhhdCByZWZlciB0byB0aGVtc2VsdmVzLgotICAgICAgICBzcmMtcmVkZWZpbmUuNS5iLmMgPSBzcmMtcmVkZWZpbmUuNS5iLmM6ICcnezB9JycgaXMgbm90IGEgdmFsaWQgZ3JhbmRjaGlsZCBlbGVtZW50LiA8Y29tcGxleFR5cGU+IGNoaWxkcmVuIG9mIDxyZWRlZmluZT4gZWxlbWVudHMgbXVzdCBoYXZlIDxleHRlbnNpb24+IG9yIDxyZXN0cmljdGlvbj4gZGVzY2VuZGFudHMsIHdpdGggJydiYXNlJycgYXR0cmlidXRlcyB0aGF0IHJlZmVyIHRvIHRoZW1zZWx2ZXMuCi0gICAgICAgIHNyYy1yZWRlZmluZS41LmIuZCA9IHNyYy1yZWRlZmluZS41LmIuZDogJyd7MH0nJyBkb2VzIG5vdCBoYXZlIGEgJydiYXNlJycgYXR0cmlidXRlIHRoYXQgcmVmZXJzIHRvIHRoZSByZWRlZmluZWQgZWxlbWVudCwgJyd7MX0nJy4gPGNvbXBsZXhUeXBlPiBjaGlsZHJlbiBvZiA8cmVkZWZpbmU+IGVsZW1lbnRzIG11c3QgaGF2ZSA8ZXh0ZW5zaW9uPiBvciA8cmVzdHJpY3Rpb24+IGRlc2NlbmRhbnRzLCB3aXRoICcnYmFzZScnIGF0dHJpYnV0ZXMgdGhhdCByZWZlciB0byB0aGVtc2VsdmVzLgotICAgICAgICBzcmMtcmVkZWZpbmUuNi4xLjEgPSBzcmMtcmVkZWZpbmUuNi4xLjE6ICBJZiBhIGdyb3VwIGNoaWxkIG9mIGEgPHJlZGVmaW5lPiBlbGVtZW50IGNvbnRhaW5zIGEgZ3JvdXAgcmVmZXJyaW5nIGl0c2VsZiwgaXQgbXVzdCBoYXZlIGV4YWN0bHkgMTsgdGhpcyBvbmUgaGFzICcnezB9JycuCi0gICAgICAgIHNyYy1yZWRlZmluZS42LjEuMiA9IHNyYy1yZWRlZmluZS42LjEuMjogIFRoZSBncm91cCAnJ3swfScnLCB3aGljaCBjb250YWlucyBhIHJlZmVyZW5jZSB0byBhIGdyb3VwIGJlaW5nIHJlZGVmaW5lZCwgbXVzdCBoYXZlICcnbWluT2NjdXJzJycgPSAnJ21heE9jY3VycycnID0gMS4KLSAgICAgICAgc3JjLXJlZGVmaW5lLjYuMi4xID0gc3JjLXJlZGVmaW5lLjYuMi4xOiBObyBncm91cCBpbiB0aGUgcmVkZWZpbmVkIHNjaGVtYSBoYXMgYSBuYW1lIG1hdGNoaW5nICcnezB9JycuCi0gICAgICAgIHNyYy1yZWRlZmluZS42LjIuMiA9IHNyYy1yZWRlZmluZS42LjIuMjogR3JvdXAgJyd7MH0nJyBkb2VzIG5vdCBwcm9wZXJseSByZXN0cmljdCB0aGUgZ3JvdXAgaXQgcmVkZWZpbmVzOyBjb25zdHJhaW50IHZpb2xhdGVkOiAgJyd7MX0nJy4KLSAgICAgICAgc3JjLXJlZGVmaW5lLjcuMSA9IHNyYy1yZWRlZmluZS43LjE6ICBJZiBhbiBhdHRyaWJ1dGVHcm91cCBjaGlsZCBvZiBhIDxyZWRlZmluZT4gZWxlbWVudCBjb250YWlucyBhbiBhdHRyaWJ1dGVHcm91cCByZWZlcnJpbmcgaXRzZWxmLCBpdCBtdXN0IGhhdmUgZXhhY3RseSAxOyB0aGlzIG9uZSBoYXMgezB9LgotICAgICAgICBzcmMtcmVkZWZpbmUuNy4yLjEgPSBzcmMtcmVkZWZpbmUuNy4yLjE6IE5vIGF0dHJpYnV0ZUdyb3VwIGluIHRoZSByZWRlZmluZWQgc2NoZW1hIGhhcyBhIG5hbWUgbWF0Y2hpbmcgJyd7MH0nJy4KLSAgICAgICAgc3JjLXJlZGVmaW5lLjcuMi4yID0gc3JjLXJlZGVmaW5lLjcuMi4yOiBBdHRyaWJ1dGVHcm91cCAnJ3swfScnIGRvZXMgbm90IHByb3Blcmx5IHJlc3RyaWN0IHRoZSBhdHRyaWJ1dGVHcm91cCBpdCByZWRlZmluZXM7IGNvbnN0cmFpbnQgdmlvbGF0ZWQ6ICAnJ3sxfScnLgotICAgICAgICBzcmMtcmVzb2x2ZSA9IHNyYy1yZXNvbHZlOiBDYW5ub3QgcmVzb2x2ZSB0aGUgbmFtZSAnJ3swfScnIHRvIGEobikgJyd7MX0nJyBjb21wb25lbnQuCi0gICAgICAgIHNyYy1yZXNvbHZlLjQuMSA9IHNyYy1yZXNvbHZlLjQuMTogRXJyb3IgcmVzb2x2aW5nIGNvbXBvbmVudCAnJ3syfScnLiBJdCB3YXMgZGV0ZWN0ZWQgdGhhdCAnJ3syfScnIGhhcyBubyBuYW1lc3BhY2UsIGJ1dCBjb21wb25lbnRzIHdpdGggbm8gdGFyZ2V0IG5hbWVzcGFjZSBhcmUgbm90IHJlZmVyZW5jZWFibGUgZnJvbSBzY2hlbWEgZG9jdW1lbnQgJyd7MH0nJy4gSWYgJyd7Mn0nJyBpcyBpbnRlbmRlZCB0byBoYXZlIGEgbmFtZXNwYWNlLCBwZXJoYXBzIGEgcHJlZml4IG5lZWRzIHRvIGJlIHByb3ZpZGVkLiBJZiBpdCBpcyBpbnRlbmRlZCB0aGF0ICcnezJ9JycgaGFzIG5vIG5hbWVzcGFjZSwgdGhlbiBhbiAnJ2ltcG9ydCcnIHdpdGhvdXQgYSAibmFtZXNwYWNlIiBhdHRyaWJ1dGUgc2hvdWxkIGJlIGFkZGVkIHRvICcnezB9JycuCi0gICAgICAgIHNyYy1yZXNvbHZlLjQuMiA9IHNyYy1yZXNvbHZlLjQuMjogRXJyb3IgcmVzb2x2aW5nIGNvbXBvbmVudCAnJ3syfScnLiBJdCB3YXMgZGV0ZWN0ZWQgdGhhdCAnJ3syfScnIGlzIGluIG5hbWVzcGFjZSAnJ3sxfScnLCBidXQgY29tcG9uZW50cyBmcm9tIHRoaXMgbmFtZXNwYWNlIGFyZSBub3QgcmVmZXJlbmNlYWJsZSBmcm9tIHNjaGVtYSBkb2N1bWVudCAnJ3swfScnLiBJZiB0aGlzIGlzIHRoZSBpbmNvcnJlY3QgbmFtZXNwYWNlLCBwZXJoYXBzIHRoZSBwcmVmaXggb2YgJyd7Mn0nJyBuZWVkcyB0byBiZSBjaGFuZ2VkLiBJZiB0aGlzIGlzIHRoZSBjb3JyZWN0IG5hbWVzcGFjZSwgdGhlbiBhbiBhcHByb3ByaWF0ZSAnJ2ltcG9ydCcnIHRhZyBzaG91bGQgYmUgYWRkZWQgdG8gJyd7MH0nJy4KLSAgICAgICAgc3JjLXNpbXBsZS10eXBlLjIuYSA9IHNyYy1zaW1wbGUtdHlwZS4yLmE6IEEgPHJlc3RyaWN0aW9uPiBlbGVtZW50IHdhcyBmb3VuZCB0aGF0IGhhcyBib3RoIGEgYmFzZSBbYXR0cmlidXRlXSBhbmQgYSA8c2ltcGxlVHlwZT4gZWxlbWVudCBhbW9uZyBpdHMgW2NoaWxkcmVuXS4gT25seSBvbmUgaXMgYWxsb3dlZC4KLSAgICAgICAgc3JjLXNpbXBsZS10eXBlLjIuYiA9IHNyYy1zaW1wbGUtdHlwZS4yLmI6IEEgPHJlc3RyaWN0aW9uPiBlbGVtZW50IHdhcyBmb3VuZCB0aGF0IGhhcyBuZWl0aGVyIGEgYmFzZSBbYXR0cmlidXRlXSBub3IgYSA8c2ltcGxlVHlwZT4gZWxlbWVudCBhbW9uZyBpdHMgW2NoaWxkcmVuXS4gT25lIGlzIHJlcXVpcmVkLgotICAgICAgICBzcmMtc2ltcGxlLXR5cGUuMy5hID0gc3JjLXNpbXBsZS10eXBlLjMuYTogQSA8bGlzdD4gZWxlbWVudCB3YXMgZm91bmQgdGhhdCBoYXMgYm90aCBhbiBpdGVtVHlwZSBbYXR0cmlidXRlXSBhbmQgYSA8c2ltcGxlVHlwZT4gZWxlbWVudCBhbW9uZyBpdHMgW2NoaWxkcmVuXS4gT25seSBvbmUgaXMgYWxsb3dlZC4KLSAgICAgICAgc3JjLXNpbXBsZS10eXBlLjMuYiA9IHNyYy1zaW1wbGUtdHlwZS4zLmI6IEEgPGxpc3Q+IGVsZW1lbnQgd2FzIGZvdW5kIHRoYXQgaGFzIG5laXRoZXIgYW4gaXRlbVR5cGUgW2F0dHJpYnV0ZV0gbm9yIGEgPHNpbXBsZVR5cGU+IGVsZW1lbnQgYW1vbmcgaXRzIFtjaGlsZHJlbl0uIE9uZSBpcyByZXF1aXJlZC4KLSAgICAgICAgc3JjLXNpbmdsZS1mYWNldC12YWx1ZSA9IHNyYy1zaW5nbGUtZmFjZXQtdmFsdWU6IFRoZSBmYWNldCAnJ3swfScnIGlzIGRlZmluZWQgbW9yZSB0aGFuIG9uY2UuCi0gICAgICAgIHNyYy11bmlvbi1tZW1iZXJUeXBlcy1vci1zaW1wbGVUeXBlcyA9IHNyYy11bmlvbi1tZW1iZXJUeXBlcy1vci1zaW1wbGVUeXBlczogQSA8dW5pb24+IGVsZW1lbnQgbXVzdCBoYXZlIGVpdGhlciBhIG5vbi1lbXB0eSBtZW1iZXJUeXBlcyBbYXR0cmlidXRlXSBvciBhdCBsZWFzdCBvbmUgPHNpbXBsZVR5cGU+IGVsZW1lbnQgYW1vbmcgaXRzIFtjaGlsZHJlbl0uCi0KLSNjb25zdHJhaW50IHZhbGlkICgzLlguNikKLQotICAgICAgICBhZy1wcm9wcy1jb3JyZWN0LjIgPSBhZy1wcm9wcy1jb3JyZWN0LjI6IEVycm9yIGZvciBhdHRyaWJ1dGUgZ3JvdXAgJyd7MH0nJy4gIER1cGxpY2F0ZSBhdHRyaWJ1dGUgdXNlcyB3aXRoIHRoZSBzYW1lIG5hbWUgYW5kIHRhcmdldCBuYW1lc3BhY2UgYXJlIHNwZWNpZmllZC4gIE5hbWUgb2YgZHVwbGljYXRlIGF0dHJpYnV0ZSB1c2UgaXMgJyd7MX0nJy4KLSAgICAgICAgYWctcHJvcHMtY29ycmVjdC4zID0gYWctcHJvcHMtY29ycmVjdC4zOiBFcnJvciBmb3IgYXR0cmlidXRlIGdyb3VwICcnezB9JycuICBUd28gYXR0cmlidXRlIGRlY2xhcmF0aW9ucywgJyd7MX0nJyBhbmQgJyd7Mn0nJyBoYXZlIHR5cGVzIHdoaWNoIGFyZSBkZXJpdmVkIGZyb20gSUQuCi0gICAgICAgIGEtcHJvcHMtY29ycmVjdC4yID0gYS1wcm9wcy1jb3JyZWN0LjI6IEludmFsaWQgdmFsdWUgY29uc3RyYWludCB2YWx1ZSAnJ3sxfScnIGluIGF0dHJpYnV0ZSAnJ3swfScnLgotICAgICAgICBhLXByb3BzLWNvcnJlY3QuMyA9IGEtcHJvcHMtY29ycmVjdC4zOiBBdHRyaWJ1dGUgJyd7MH0nJyBjYW5ub3QgdXNlICcnZml4ZWQnJyBvciAnJ2RlZmF1bHQnJywgYmVjYXVzZSB0aGUgYXR0cmlidXRlJydzICd7J3R5cGUgZGVmaW5pdGlvbid9JyBpcyBJRCwgb3IgaXMgZGVyaXZlZCBmcm9tIElELgotICAgICAgICBhdS1wcm9wcy1jb3JyZWN0LjIgPSBhdS1wcm9wcy1jb3JyZWN0LjI6IEluIHRoZSBhdHRyaWJ1dGUgZGVjbGFyYXRpb24gb2YgJyd7MH0nJywgYSBmaXhlZCB2YWx1ZSBvZiAnJ3sxfScnIHdhcyBzcGVjaWZpZWQuIFNvIGlmIHRoZSBhdHRyaWJ1dGUgdXNlIHJlZmVycmluZyB0byAnJ3swfScnIGFsc28gaGFzIGEgJ3sndmFsdWUgY29uc3RyYWludCd9JywgaXQgbXVzdCBiZSBmaXhlZCBhbmQgaXRzIHZhbHVlIG11c3QgYmUgJyd7MX0nJy4KLSAgICAgICAgY29zLWFsbC1saW1pdGVkLjEuMiA9IGNvcy1hbGwtbGltaXRlZC4xLjI6IEFuICdhbGwnIG1vZGVsIGdyb3VwIG11c3QgYXBwZWFyIGluIGEgcGFydGljbGUgd2l0aCAneydtaW4gb2NjdXJzJ30nID0gJ3snbWF4IG9jY3Vycyd9JyA9IDEsIGFuZCB0aGF0IHBhcnRpY2xlIG11c3QgYmUgcGFydCBvZiBhIHBhaXIgd2hpY2ggY29uc3RpdHV0ZXMgdGhlICd7J2NvbnRlbnQgdHlwZSd9JyBvZiBhIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uLgotICAgICAgICBjb3MtYWxsLWxpbWl0ZWQuMiA9IGNvcy1hbGwtbGltaXRlZC4yOiBUaGUgJ3snbWF4IG9jY3Vycyd9JyBvZiBhbiBlbGVtZW50IGluIGFuICcnYWxsJycgbW9kZWwgZ3JvdXAgbXVzdCBiZSAwIG9yIDEuIFRoZSB2YWx1ZSAnJ3swfScnIGZvciBlbGVtZW50ICcnezF9JycgaXMgaW52YWxpZC4KLSAgICAgICAgY29zLWFwcGxpY2FibGUtZmFjZXRzID0gY29zLWFwcGxpY2FibGUtZmFjZXRzOiBGYWNldCAnJ3swfScnIGlzIG5vdCBhbGxvd2VkIGJ5IHR5cGUgezF9LgotICAgICAgICBjb3MtY3QtZXh0ZW5kcy4xLjEgPSBjb3MtY3QtZXh0ZW5kcy4xLjE6IFR5cGUgJyd7MH0nJyB3YXMgZGVyaXZlZCBieSBleHRlbnNpb24gZnJvbSB0eXBlICcnezF9JycuICBIb3dldmVyLCB0aGUgJydmaW5hbCcnIGF0dHJpYnV0ZSBvZiAnJ3sxfScnIGZvcmJpZHMgZGVyaXZhdGlvbiBieSBleHRlbnNpb24uCi0gICAgICAgIGNvcy1jdC1leHRlbmRzLjEuNC4zLjIuMi4xLmEgPSBjb3MtY3QtZXh0ZW5kcy4xLjQuMy4yLjIuMS5hOiBUaGUgY29udGVudCB0eXBlIG9mIGEgZGVyaXZlZCB0eXBlIGFuZCB0aGF0IG9mIGl0cyBiYXNlIG11c3QgYm90aCBiZSBtaXhlZCBvciBib3RoIGJlIGVsZW1lbnQtb25seS4gVHlwZSAnJ3swfScnIGlzIGVsZW1lbnQgb25seSwgYnV0IGl0cyBiYXNlIHR5cGUgaXMgbm90LgotICAgICAgICBjb3MtY3QtZXh0ZW5kcy4xLjQuMy4yLjIuMS5iID0gY29zLWN0LWV4dGVuZHMuMS40LjMuMi4yLjEuYjogVGhlIGNvbnRlbnQgdHlwZSBvZiBhIGRlcml2ZWQgdHlwZSBhbmQgdGhhdCBvZiBpdHMgYmFzZSBtdXN0IGJvdGggYmUgbWl4ZWQgb3IgYm90aCBiZSBlbGVtZW50LW9ubHkuIFR5cGUgJyd7MH0nJyBpcyBtaXhlZCwgYnV0IGl0cyBiYXNlIHR5cGUgaXMgbm90LgotICAgICAgICBjb3MtZWxlbWVudC1jb25zaXN0ZW50ID0gY29zLWVsZW1lbnQtY29uc2lzdGVudDogRXJyb3IgZm9yIHR5cGUgJyd7MH0nJy4gTXVsdGlwbGUgZWxlbWVudHMgd2l0aCBuYW1lICcnezF9JycsIHdpdGggZGlmZmVyZW50IHR5cGVzLCBhcHBlYXIgaW4gdGhlIG1vZGVsIGdyb3VwLgotICAgICAgICBjb3MtbGlzdC1vZi1hdG9taWMgPSBjb3MtbGlzdC1vZi1hdG9taWM6IEluIHRoZSBkZWZpbml0aW9uIG9mIGxpc3QgdHlwZSAnJ3swfScnLCB0eXBlICcnezF9JycgaXMgYW4gaW52YWxpZCBsaXN0IGVsZW1lbnQgdHlwZSBiZWNhdXNlIGl0IGlzIG5vdCBhdG9taWMgKCcnezF9JycgaXMgZWl0aGVyIGEgbGlzdCB0eXBlLCBvciBhIHVuaW9uIHR5cGUgd2hpY2ggY29udGFpbnMgYSBsaXN0KS4KLSAgICAgICAgY29zLW5vbmFtYmlnID0gY29zLW5vbmFtYmlnOiB7MH0gYW5kIHsxfSAob3IgZWxlbWVudHMgZnJvbSB0aGVpciBzdWJzdGl0dXRpb24gZ3JvdXApIHZpb2xhdGUgXCJVbmlxdWUgUGFydGljbGUgQXR0cmlidXRpb25cIi4gRHVyaW5nIHZhbGlkYXRpb24gYWdhaW5zdCB0aGlzIHNjaGVtYSwgYW1iaWd1aXR5IHdvdWxkIGJlIGNyZWF0ZWQgZm9yIHRob3NlIHR3byBwYXJ0aWNsZXMuCi0gICAgICAgIGNvcy1wYXJ0aWNsZS1yZXN0cmljdC5hID0gY29zLXBhcnRpY2xlLXJlc3RyaWN0LmE6IERlcml2ZWQgcGFydGljbGUgaXMgZW1wdHksIGFuZCBiYXNlIGlzIG5vdCBlbXB0aWFibGUuCi0gICAgICAgIGNvcy1wYXJ0aWNsZS1yZXN0cmljdC5iID0gY29zLXBhcnRpY2xlLXJlc3RyaWN0LmI6IEJhc2UgcGFydGljbGUgaXMgZW1wdHksIGJ1dCBkZXJpdmVkIHBhcnRpY2xlIGlzIG5vdC4KLSAgICAgICAgY29zLXBhcnRpY2xlLXJlc3RyaWN0LjIgPSBjb3MtcGFydGljbGUtcmVzdHJpY3QuMjogRm9yYmlkZGVuIHBhcnRpY2xlIHJlc3RyaWN0aW9uOiAnJ3swfScnLgotICAgICAgICBjb3Mtc3QtcmVzdHJpY3RzLjEuMSA9IGNvcy1zdC1yZXN0cmljdHMuMS4xOiBUaGUgdHlwZSAnJ3sxfScnIGlzIGF0b21pYywgc28gaXRzICd7J2Jhc2UgdHlwZSBkZWZpbml0aW9uJ30nLCAnJ3swfScnLCBtdXN0IGJlIGFuIGF0b21pYyBzaW1wbGUgdHlwZSBkZWZpbml0aW9uIG9yIGEgYnVpbHQtaW4gcHJpbWl0aXZlIGRhdGF0eXBlLgotICAgICAgICBjb3Mtc3QtcmVzdHJpY3RzLjIuMSA9IGNvcy1zdC1yZXN0cmljdHMuMi4xOiBJbiB0aGUgZGVmaW5pdGlvbiBvZiBsaXN0IHR5cGUgJyd7MH0nJywgdHlwZSAnJ3sxfScnIGlzIGFuIGludmFsaWQgaXRlbSB0eXBlIGJlY2F1c2UgaXQgaXMgZWl0aGVyIGEgbGlzdCB0eXBlLCBvciBhIHVuaW9uIHR5cGUgdGhhdCBjb250YWlucyBhIGxpc3QuCi0gICAgICAgIGNvcy1zdC1yZXN0cmljdHMuMi4zLjEuMSA9IGNvcy1zdC1yZXN0cmljdHMuMi4zLjEuMTogVGhlICd7J2ZpbmFsJ30nIGNvbXBvbmVudCBvZiB0aGUgJ3snaXRlbSB0eXBlIGRlZmluaXRpb24nfScsICcnezB9JycsIGNvbnRhaW5zICcnbGlzdCcnLiBUaGlzIG1lYW5zIHRoYXQgJyd7MH0nJyBjYW5ub3QgYmUgdXNlZCBhcyBhbiBpdGVtIHR5cGUgZm9yIGxpc3QgdHlwZSAnJ3sxfScnLgotICAgICAgICBjb3Mtc3QtcmVzdHJpY3RzLjMuMy4xLjEgPSBjb3Mtc3QtcmVzdHJpY3RzLjMuMy4xLjE6IFRoZSAneydmaW5hbCd9JyBjb21wb25lbnQgb2YgdGhlICd7J21lbWJlciB0eXBlIGRlZmluaXRpb25zJ30nLCAnJ3swfScnLCBjb250YWlucyAnJ3VuaW9uJycuIFRoaXMgbWVhbnMgdGhhdCAnJ3swfScnIGNhbm5vdCBiZSB1c2VkIGFzIGFuIG1lbWJlciB0eXBlIGZvciB1bmlvbiB0eXBlICcnezF9JycuCi0gICAgICAgIGNvcy12YWxpZC1kZWZhdWx0LjIuMSA9IGNvcy12YWxpZC1kZWZhdWx0LjIuMTogRWxlbWVudCAnJ3swfScnIGhhcyBhIHZhbHVlIGNvbnN0cmFpbnQgYW5kIG11c3QgaGF2ZSBhIG1peGVkIG9yIHNpbXBsZSBjb250ZW50IG1vZGVsLgotICAgICAgICBjb3MtdmFsaWQtZGVmYXVsdC4yLjIuMiA9IGNvcy12YWxpZC1kZWZhdWx0LjIuMi4yOiBTaW5jZSBlbGVtZW50ICcnezB9JycgaGFzIGEgJ3sndmFsdWUgY29uc3RyYWludCd9JyBhbmQgaXRzIHR5cGUgZGVmaW5pdGlvbiBoYXMgbWl4ZWQgJ3snY29udGVudCB0eXBlJ30nLCB0aGVuIHRoZSBwYXJ0aWNsZSBvZiB0aGUgJ3snY29udGVudCB0eXBlJ30nIG11c3QgYmUgZW1wdGlhYmxlLgotICAgICAgICBjLXByb3BzLWNvcnJlY3QuMiA9IGMtcHJvcHMtY29ycmVjdC4yOiBDYXJkaW5hbGl0eSBvZiBGaWVsZHMgZm9yIGtleXJlZiAnJ3swfScnIGFuZCBrZXkgJyd7MX0nJyBtdXN0IG1hdGNoIGVhY2ggb3RoZXIuCi0gICAgICAgIGN0LXByb3BzLWNvcnJlY3QuMyA9IGN0LXByb3BzLWNvcnJlY3QuMzogQ2lyY3VsYXIgZGVmaW5pdGlvbnMgZGV0ZWN0ZWQgZm9yIGNvbXBsZXggdHlwZSAnJ3swfScnLiBUaGlzIG1lYW5zIHRoYXQgJyd7MH0nJyBpcyBjb250YWluZWQgaW4gaXRzIG93biB0eXBlIGhpZXJhcmNoeSwgd2hpY2ggaXMgYW4gZXJyb3IuCi0gICAgICAgIGN0LXByb3BzLWNvcnJlY3QuNCA9IGN0LXByb3BzLWNvcnJlY3QuNDogRXJyb3IgZm9yIHR5cGUgJyd7MH0nJy4gRHVwbGljYXRlIGF0dHJpYnV0ZSB1c2VzIHdpdGggdGhlIHNhbWUgbmFtZSBhbmQgdGFyZ2V0IG5hbWVzcGFjZSBhcmUgc3BlY2lmaWVkLiAgTmFtZSBvZiBkdXBsaWNhdGUgYXR0cmlidXRlIHVzZSBpcyAnJ3sxfScnLgotICAgICAgICBjdC1wcm9wcy1jb3JyZWN0LjUgPSBjdC1wcm9wcy1jb3JyZWN0LjU6IEVycm9yIGZvciB0eXBlICcnezB9JycuIFR3byBhdHRyaWJ1dGUgZGVjbGFyYXRpb25zLCAnJ3sxfScnIGFuZCAnJ3syfScnIGhhdmUgdHlwZXMgd2hpY2ggYXJlIGRlcml2ZWQgZnJvbSBJRC4KLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4xID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4xOiBUeXBlICcnezB9Jycgd2FzIGRlcml2ZWQgYnkgcmVzdHJpY3Rpb24gZnJvbSB0eXBlICcnezF9JycuICBIb3dldmVyLCAnJ3sxfScnIGhhcyBhICd7J2ZpbmFsJ30nIHByb3BlcnR5IHRoYXQgZm9yYmlkcyBkZXJpdmF0aW9uIGJ5IHJlc3RyaWN0aW9uLgotICAgICAgICBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjIuMS4xID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4yLjEuMTogRXJyb3IgZm9yIHR5cGUgJyd7MH0nJy4gIFRoZSBhdHRyaWJ1dGUgdXNlICcnezF9JycgaW4gdGhpcyB0eXBlIGhhcyBhICcndXNlJycgdmFsdWUgb2YgJyd7Mn0nJywgd2hpY2ggaXMgaW5jb25zaXN0ZW50IHdpdGggdGhlIHZhbHVlIG9mICcncmVxdWlyZWQnJyBpbiBhIG1hdGNoaW5nIGF0dHJpYnV0ZSB1c2UgaW4gdGhlIGJhc2UgdHlwZS4KLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4yLjEuMiA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMi4xLjI6IEVycm9yIGZvciB0eXBlICcnezB9JycuICBUaGUgYXR0cmlidXRlIHVzZSAnJ3sxfScnIGluIHRoaXMgdHlwZSBoYXMgdHlwZSAnJ3syfScnLCB3aGljaCBpcyBub3QgdmFsaWRseSBkZXJpdmVkIGZyb20gJyd7M30nJywgdGhlIHR5cGUgb2YgdGhlIG1hdGNoaW5nIGF0dHJpYnV0ZSB1c2UgaW4gdGhlIGJhc2UgdHlwZS4KLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4yLjEuMy5hID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4yLjEuMy5hOiBFcnJvciBmb3IgdHlwZSAnJ3swfScnLiAgVGhlIGF0dHJpYnV0ZSB1c2UgJyd7MX0nJyBpbiB0aGlzIHR5cGUgaGFzIGFuIGVmZmVjdGl2ZSB2YWx1ZSBjb25zdHJhaW50IHdoaWNoIGlzIG5vdCBmaXhlZCwgYW5kIHRoZSBlZmZlY3RpdmUgdmFsdWUgY29uc3RyYWludCBvZiB0aGUgbWF0Y2hpbmcgYXR0cmlidXRlIHVzZSBpbiB0aGUgYmFzZSB0eXBlIGlzIGZpeGVkLgotICAgICAgICBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjIuMS4zLmIgPSBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjIuMS4zLmI6IEVycm9yIGZvciB0eXBlICcnezB9JycuICBUaGUgYXR0cmlidXRlIHVzZSAnJ3sxfScnIGluIHRoaXMgdHlwZSBoYXMgYW4gZWZmZWN0aXZlIHZhbHVlIGNvbnN0cmFpbnQgZml4ZWQgd2l0aCBhIHZhbHVlIG9mICcnezJ9JycsIHdoaWNoIGlzIG5vdCBjb25zaXN0ZW50IHdpdGggdGhlIHZhbHVlIG9mICcnezN9JycgZm9yIHRoZSBmaXhlZCBlZmZlY3RpdmUgdmFsdWUgY29uc3RyYWludCBvZiB0aGUgbWF0Y2hpbmcgYXR0cmlidXRlIHVzZSBpbiB0aGUgYmFzZSB0eXBlLgotICAgICAgICBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjIuMi5hID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4yLjIuYTogRXJyb3IgZm9yIHR5cGUgJyd7MH0nJy4gIFRoZSBhdHRyaWJ1dGUgdXNlICcnezF9JycgaW4gdGhpcyB0eXBlIGRvZXMgbm90IGhhdmUgYSBtYXRjaGluZyBhdHRyaWJ1dGUgdXNlIGluIHRoZSBiYXNlLCBhbmQgdGhlIGJhc2UgdHlwZSBkb2VzIG5vdCBoYXZlIGEgd2lsZGNhcmQgYXR0cmlidXRlLgotICAgICAgICBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjIuMi5iID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4yLjIuYjogRXJyb3IgZm9yIHR5cGUgJyd7MH0nJy4gIFRoZSBhdHRyaWJ1dGUgdXNlICcnezF9JycgaW4gdGhpcyB0eXBlIGRvZXMgbm90IGhhdmUgYSBtYXRjaGluZyBhdHRyaWJ1dGUgdXNlIGluIHRoZSBiYXNlLCBhbmQgdGhlIHdpbGRjYXJkIGluIHRoZSBiYXNlIHR5cGUgZG9lcyBub3QgYWxsb3cgdGhlIG5hbWVzcGFjZSAnJ3syfScnIG9mIHRoaXMgYXR0cmlidXRlIHVzZS4KLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4zID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4zOiBFcnJvciBmb3IgdHlwZSAnJ3swfScnLiAgVGhlIGF0dHJpYnV0ZSB1c2UgJyd7MX0nJyBpbiB0aGUgYmFzZSB0eXBlIGhhcyBSRVFVSVJFRCBhcyB0cnVlLCBidXQgdGhlcmUgaXMgbm8gbWF0Y2hpbmcgYXR0cmlidXRlIHVzZSBpbiB0aGUgZGVyaXZlZCB0eXBlLgotICAgICAgICBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjQuMSA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uNC4xOiBFcnJvciBmb3IgdHlwZSAnJ3swfScnLiAgVGhlIGRlcml2YXRpb24gaGFzIGFuIGF0dHJpYnV0ZSB3aWxkY2FyZCwgYnV0IHRoZSBiYXNlIGRvZXMgbm90IGhhdmUgb25lLgotICAgICAgICBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjQuMiA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uNC4yOiBFcnJvciBmb3IgdHlwZSAnJ3swfScnLiAgVGhlIHdpbGRjYXJkIGluIHRoZSBkZXJpdmF0aW9uIGlzIG5vdCBhIHZhbGlkIHdpbGRjYXJkIHN1YnNldCBvZiB0aGUgb25lIGluIHRoZSBiYXNlLgotICAgICAgICBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjQuMyA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uNC4zOiBFcnJvciBmb3IgdHlwZSAnJ3swfScnLiAgVGhlIHByb2Nlc3MgY29udGVudHMgb2YgdGhlIHdpbGRjYXJkIGluIHRoZSBkZXJpdmF0aW9uICh7MX0pIGlzIHdlYWtlciB0aGFuIHRoYXQgaW4gdGhlIGJhc2UgKHsyfSkuCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uNS4yLjIuMSA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uNS4yLjIuMTogRXJyb3IgZm9yIHR5cGUgJyd7MH0nJy4gIFRoZSBzaW1wbGUgY29udGVudCB0eXBlIG9mIHRoaXMgdHlwZSwgJyd7MX0nJywgaXMgbm90IGEgdmFsaWQgcmVzdHJpY3Rpb24gb2YgdGhlIHNpbXBsZSBjb250ZW50IHR5cGUgb2YgdGhlIGJhc2UsICcnezJ9JycuCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uNS4zLjIgPSBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjUuMy4yOiBFcnJvciBmb3IgdHlwZSAnJ3swfScnLiAgVGhlIGNvbnRlbnQgdHlwZSBvZiB0aGlzIHR5cGUgaXMgZW1wdHksIGJ1dCB0aGUgY29udGVudCB0eXBlIG9mIHRoZSBiYXNlLCAnJ3sxfScnLCBpcyBub3QgZW1wdHkgb3IgZW1wdGlhYmxlLgotICAgICAgICBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjUuNC4xLjIgPSBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjUuNC4xLjI6IEVycm9yIGZvciB0eXBlICcnezB9JycuICBUaGUgY29udGVudCB0eXBlIG9mIHRoaXMgdHlwZSBpcyBtaXhlZCwgYnV0IHRoZSBjb250ZW50IHR5cGUgb2YgdGhlIGJhc2UsICcnezF9JycsIGlzIG5vdC4KLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi41LjQuMiA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uNS40LjI6IEVycm9yIGZvciB0eXBlICcnezB9JycuICBUaGUgcGFydGljbGUgb2YgdGhlIHR5cGUgaXMgbm90IGEgdmFsaWQgcmVzdHJpY3Rpb24gb2YgdGhlIHBhcnRpY2xlIG9mIHRoZSBiYXNlLgotICAgICAgICBlbnVtZXJhdGlvbi1yZXF1aXJlZC1ub3RhdGlvbiA9IGVudW1lcmF0aW9uLXJlcXVpcmVkLW5vdGF0aW9uOiBUaGUgTk9UQVRJT04gdHlwZSwgJyd7MH0nJyB1c2VkIGJ5IHsyfSAnJ3sxfScnLCBtdXN0IGhhdmUgYW4gZW51bWVyYXRpb24gZmFjZXQgdmFsdWUgd2hpY2ggc3BlY2lmaWVzIHRoZSBub3RhdGlvbiBlbGVtZW50cyB1c2VkIGJ5IHRoaXMgdHlwZS4KLSAgICAgICAgZW51bWVyYXRpb24tdmFsaWQtcmVzdHJpY3Rpb24gPSBlbnVtZXJhdGlvbi12YWxpZC1yZXN0cmljdGlvbjogRW51bWVyYXRpb24gdmFsdWUgJyd7MH0nJyBpcyBub3QgaW4gdGhlIHZhbHVlIHNwYWNlIG9mIHRoZSBiYXNlIHR5cGUsIHsxfS4KLSAgICAgICAgZS1wcm9wcy1jb3JyZWN0LjIgPSBlLXByb3BzLWNvcnJlY3QuMjogSW52YWxpZCB2YWx1ZSBjb25zdHJhaW50IHZhbHVlICcnezF9JycgaW4gZWxlbWVudCAnJ3swfScnLgotICAgICAgICBlLXByb3BzLWNvcnJlY3QuNCA9IGUtcHJvcHMtY29ycmVjdC40OiBUaGUgJ3sndHlwZSBkZWZpbml0aW9uJ30nIG9mIGVsZW1lbnQgJyd7MH0nJyBpcyBub3QgdmFsaWRseSBkZXJpdmVkIGZyb20gdGhlICd7J3R5cGUgZGVmaW5pdGlvbid9JyBvZiB0aGUgc3Vic3RpdHV0aW9uSGVhZCAnJ3sxfScnLCBvciB0aGUgJ3snc3Vic3RpdHV0aW9uIGdyb3VwIGV4Y2x1c2lvbnMnfScgcHJvcGVydHkgb2YgJyd7MX0nJyBkb2VzIG5vdCBhbGxvdyB0aGlzIGRlcml2YXRpb24uCi0gICAgICAgIGUtcHJvcHMtY29ycmVjdC41ID0gZS1wcm9wcy1jb3JyZWN0LjU6IEEgJ3sndmFsdWUgY29uc3RyYWludCd9JyBtdXN0IG5vdCBiZSBwcmVzZW50IG9uIGVsZW1lbnQgJyd7MH0nJywgYmVjYXVzZSB0aGUgZWxlbWVudCcncyAneyd0eXBlIGRlZmluaXRpb24nfScgb3IgJ3sndHlwZSBkZWZpbml0aW9uJ30nJydzICd7J2NvbnRlbnQgdHlwZSd9JyBpcyBJRCwgb3IgaXMgZGVyaXZlZCBmcm9tIElELgotICAgICAgICBlLXByb3BzLWNvcnJlY3QuNiA9IGUtcHJvcHMtY29ycmVjdC42OiBDaXJjdWxhciBzdWJzdGl0dXRpb24gZ3JvdXAgZGV0ZWN0ZWQgZm9yIGVsZW1lbnQgJyd7MH0nJy4KLSAgICAgICAgZnJhY3Rpb25EaWdpdHMtdmFsaWQtcmVzdHJpY3Rpb24gPSBmcmFjdGlvbkRpZ2l0cy12YWxpZC1yZXN0cmljdGlvbjogSW4gdGhlIGRlZmluaXRpb24gb2YgezJ9LCB0aGUgdmFsdWUgJyd7MH0nJyBmb3IgdGhlIGZhY2V0ICcnZnJhY3Rpb25EaWdpdHMnJyBpcyBpbnZhbGlkLCBiZWNhdXNlIGl0IG11c3QgYmUgPD0gdGhlIHZhbHVlIGZvciAnJ2ZyYWN0aW9uRGlnaXRzJycgd2hpY2ggd2FzIHNldCB0byAnJ3sxfScnIGluIG9uZSBvZiB0aGUgYW5jZXN0b3IgdHlwZXMuCi0gICAgICAgIGZyYWN0aW9uRGlnaXRzLXRvdGFsRGlnaXRzID0gZnJhY3Rpb25EaWdpdHMtdG90YWxEaWdpdHM6IEluIHRoZSBkZWZpbml0aW9uIG9mIHsyfSwgdGhlIHZhbHVlICcnezB9JycgZm9yIHRoZSBmYWNldCAnJ2ZyYWN0aW9uRGlnaXRzJycgaXMgaW52YWxpZCwgYmVjYXVzZSB0aGUgdmFsdWUgbXVzdCBiZSA8PSB0aGUgdmFsdWUgZm9yICcndG90YWxEaWdpdHMnJyB3aGljaCBpcyAnJ3sxfScnLgotICAgICAgICBsZW5ndGgtbWluTGVuZ3RoLW1heExlbmd0aC4xLjEgPSBsZW5ndGgtbWluTGVuZ3RoLW1heExlbmd0aC4xLjE6IEZvciB0eXBlIHswfSwgaXQgaXMgYW4gZXJyb3IgZm9yIHRoZSB2YWx1ZSBvZiBsZW5ndGggJyd7MX0nJyB0byBiZSBsZXNzIHRoYW4gdGhlIHZhbHVlIG9mIG1pbkxlbmd0aCAnJ3syfScnLgotICAgICAgICBsZW5ndGgtbWluTGVuZ3RoLW1heExlbmd0aC4xLjIuYSA9IGxlbmd0aC1taW5MZW5ndGgtbWF4TGVuZ3RoLjEuMi5hOiBGb3IgdHlwZSB7MH0sIGl0IGlzIGFuIGVycm9yIGZvciB0aGUgYmFzZSB0byBub3QgaGF2ZSBhIG1pbkxlbmd0aCBmYWNldCBpZiB0aGUgY3VycmVudCByZXN0cmljdGlvbiBoYXMgdGhlIG1pbkxlbmd0aCBmYWNldCBhbmQgdGhlIGN1cnJlbnQgcmVzdHJpY3Rpb24gb3IgYmFzZSBoYXMgdGhlIGxlbmd0aCBmYWNldC4KLSAgICAgICAgbGVuZ3RoLW1pbkxlbmd0aC1tYXhMZW5ndGguMS4yLmIgPSBsZW5ndGgtbWluTGVuZ3RoLW1heExlbmd0aC4xLjIuYjogRm9yIHR5cGUgezB9LCBpdCBpcyBhbiBlcnJvciBmb3IgdGhlIGN1cnJlbnQgbWluTGVuZ3RoICcnezF9JycgdG8gbm90IGVxdWFsIHRoZSBiYXNlIG1pbkxlbmd0aCAnJ3syfScnLgotICAgICAgICBsZW5ndGgtbWluTGVuZ3RoLW1heExlbmd0aC4yLjEgPSBsZW5ndGgtbWluTGVuZ3RoLW1heExlbmd0aC4yLjE6IEZvciB0eXBlIHswfSwgaXQgaXMgYW4gZXJyb3IgZm9yIHRoZSB2YWx1ZSBvZiBsZW5ndGggJyd7MX0nJyB0byBiZSBncmVhdGVyIHRoYW4gdGhlIHZhbHVlIG9mIG1heExlbmd0aCAnJ3syfScnLgotICAgICAgICBsZW5ndGgtbWluTGVuZ3RoLW1heExlbmd0aC4yLjIuYSA9IGxlbmd0aC1taW5MZW5ndGgtbWF4TGVuZ3RoLjIuMi5hOiBGb3IgdHlwZSB7MH0sIGl0IGlzIGFuIGVycm9yIGZvciB0aGUgYmFzZSB0byBub3QgaGF2ZSBhIG1heExlbmd0aCBmYWNldCBpZiB0aGUgY3VycmVudCByZXN0cmljdGlvbiBoYXMgdGhlIG1heExlbmd0aCBmYWNldCBhbmQgdGhlIGN1cnJlbnQgcmVzdHJpY3Rpb24gb3IgYmFzZSBoYXMgdGhlIGxlbmd0aCBmYWNldC4KLSAgICAgICAgbGVuZ3RoLW1pbkxlbmd0aC1tYXhMZW5ndGguMi4yLmIgPSBsZW5ndGgtbWluTGVuZ3RoLW1heExlbmd0aC4yLjIuYjogRm9yIHR5cGUgezB9LCBpdCBpcyBhbiBlcnJvciBmb3IgdGhlIGN1cnJlbnQgbWF4TGVuZ3RoICcnezF9JycgdG8gbm90IGVxdWFsIHRoZSBiYXNlIG1heExlbmd0aCAnJ3syfScnLgotICAgICAgICBsZW5ndGgtdmFsaWQtcmVzdHJpY3Rpb24gPSBsZW5ndGgtdmFsaWQtcmVzdHJpY3Rpb246IEVycm9yIGZvciB0eXBlICcnezJ9JycuIFRoZSB2YWx1ZSBvZiBsZW5ndGggPSAnJ3swfScnIG11c3QgYmUgPSB0aGUgdmFsdWUgb2YgdGhhdCBvZiB0aGUgYmFzZSB0eXBlICcnezF9JycuCi0gICAgICAgIG1heEV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4xID0gbWF4RXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjE6IEVycm9yIGZvciB0eXBlICcnezJ9JycuIFRoZSBtYXhFeGNsdXNpdmUgdmFsdWUgPScnezB9JycgbXVzdCBiZSA8PSBtYXhFeGNsdXNpdmUgb2YgdGhlIGJhc2UgdHlwZSAnJ3sxfScnLgotICAgICAgICBtYXhFeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMiA9IG1heEV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4yOiBFcnJvciBmb3IgdHlwZSAnJ3syfScnLiBUaGUgbWF4RXhjbHVzaXZlIHZhbHVlID0nJ3swfScnIG11c3QgYmUgPD0gbWF4SW5jbHVzaXZlIG9mIHRoZSBiYXNlIHR5cGUgJyd7MX0nJy4KLSAgICAgICAgbWF4RXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjMgPSBtYXhFeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMzogRXJyb3IgZm9yIHR5cGUgJyd7Mn0nJy4gVGhlIG1heEV4Y2x1c2l2ZSB2YWx1ZSA9Jyd7MH0nJyBtdXN0IGJlID4gbWluSW5jbHVzaXZlIG9mIHRoZSBiYXNlIHR5cGUgJyd7MX0nJy4KLSAgICAgICAgbWF4RXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjQgPSBtYXhFeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uNDogRXJyb3IgZm9yIHR5cGUgJyd7Mn0nJy4gVGhlIG1heEV4Y2x1c2l2ZSB2YWx1ZSA9Jyd7MH0nJyBtdXN0IGJlID4gbWluRXhjbHVzaXZlIG9mIHRoZSBiYXNlIHR5cGUgJyd7MX0nJy4KLSAgICAgICAgbWF4SW5jbHVzaXZlLW1heEV4Y2x1c2l2ZSA9IG1heEluY2x1c2l2ZS1tYXhFeGNsdXNpdmU6IEl0IGlzIGFuIGVycm9yIGZvciBib3RoIG1heEluY2x1c2l2ZSBhbmQgbWF4RXhjbHVzaXZlIHRvIGJlIHNwZWNpZmllZCBmb3IgdGhlIHNhbWUgZGF0YXR5cGUuIEluIHsyfSwgbWF4SW5jbHVzaXZlID0gJyd7MH0nJyBhbmQgbWF4RXhjbHVzaXZlID0gJyd7MX0nJy4KLSAgICAgICAgbWF4SW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjEgPSBtYXhJbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMTogRXJyb3IgZm9yIHR5cGUgJyd7Mn0nJy4gVGhlIG1heEluY2x1c2l2ZSB2YWx1ZSA9Jyd7MH0nJyBtdXN0IGJlIDw9IG1heEluY2x1c2l2ZSBvZiB0aGUgYmFzZSB0eXBlICcnezF9JycuCi0gICAgICAgIG1heEluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4yID0gbWF4SW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjI6IEVycm9yIGZvciB0eXBlICcnezJ9JycuIFRoZSBtYXhJbmNsdXNpdmUgdmFsdWUgPScnezB9JycgbXVzdCBiZSA8IG1heEV4Y2x1c2l2ZSBvZiB0aGUgYmFzZSB0eXBlICcnezF9JycuCi0gICAgICAgIG1heEluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4zID0gbWF4SW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjM6IEVycm9yIGZvciB0eXBlICcnezJ9JycuIFRoZSBtYXhJbmNsdXNpdmUgdmFsdWUgPScnezB9JycgbXVzdCBiZSA+PSBtaW5JbmNsdXNpdmUgb2YgdGhlIGJhc2UgdHlwZSAnJ3sxfScnLgotICAgICAgICBtYXhJbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uNCA9IG1heEluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi40OiBFcnJvciBmb3IgdHlwZSAnJ3syfScnLiBUaGUgbWF4SW5jbHVzaXZlIHZhbHVlID0nJ3swfScnIG11c3QgYmUgPiBtaW5FeGNsdXNpdmUgb2YgdGhlIGJhc2UgdHlwZSAnJ3sxfScnLgotICAgICAgICBtYXhMZW5ndGgtdmFsaWQtcmVzdHJpY3Rpb24gPSBtYXhMZW5ndGgtdmFsaWQtcmVzdHJpY3Rpb246IEluIHRoZSBkZWZpbml0aW9uIG9mIHsyfSwgbWF4TGVuZ3RoIHZhbHVlID0gJyd7MH0nJyBtdXN0IGJlIDw9IHRoYXQgb2YgdGhlIGJhc2UgdHlwZSAnJ3sxfScnLgotICAgICAgICBtZy1wcm9wcy1jb3JyZWN0LjIgPSBtZy1wcm9wcy1jb3JyZWN0LjI6IENpcmN1bGFyIGRlZmluaXRpb25zIGRldGVjdGVkIGZvciBncm91cCAnJ3swfScnLiBSZWN1cnNpdmVseSBmb2xsb3dpbmcgdGhlICd7J3Rlcm0nfScgdmFsdWVzIG9mIHRoZSBwYXJ0aWNsZXMgbGVhZHMgdG8gYSBwYXJ0aWNsZSB3aG9zZSAneyd0ZXJtJ30nIGlzIHRoZSBncm91cCBpdHNlbGYuCi0gICAgICAgIG1pbkV4Y2x1c2l2ZS1sZXNzLXRoYW4tZXF1YWwtdG8tbWF4RXhjbHVzaXZlID0gbWluRXhjbHVzaXZlLWxlc3MtdGhhbi1lcXVhbC10by1tYXhFeGNsdXNpdmU6IEluIHRoZSBkZWZpbml0aW9uIG9mIHsyfSwgbWluRXhjbHVzaXZlIHZhbHVlID0gJyd7MH0nJyBtdXN0IGJlIDw9IG1heEV4Y2x1c2l2ZSB2YWx1ZSA9ICcnezF9JycuCi0gICAgICAgIG1pbkV4Y2x1c2l2ZS1sZXNzLXRoYW4tbWF4SW5jbHVzaXZlID0gbWluRXhjbHVzaXZlLWxlc3MtdGhhbi1tYXhJbmNsdXNpdmU6IEluIHRoZSBkZWZpbml0aW9uIG9mIHsyfSwgbWluRXhjbHVzaXZlIHZhbHVlID0gJyd7MH0nJyBtdXN0IGJlIDwgbWF4SW5jbHVzaXZlIHZhbHVlID0gJyd7MX0nJy4KLSAgICAgICAgbWluRXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjEgPSBtaW5FeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMTogRXJyb3IgZm9yIHR5cGUgJyd7Mn0nJy4gVGhlIG1pbkV4Y2x1c2l2ZSB2YWx1ZSA9Jyd7MH0nJyBtdXN0IGJlID49IG1pbkV4Y2x1c2l2ZSBvZiB0aGUgYmFzZSB0eXBlICcnezF9JycuCi0gICAgICAgIG1pbkV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4yID0gbWluRXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjI6IEVycm9yIGZvciB0eXBlICcnezJ9JycuIFRoZSBtaW5FeGNsdXNpdmUgdmFsdWUgPScnezB9JycgbXVzdCBiZSA8PSBtYXhJbmNsdXNpdmUgb2YgdGhlIGJhc2UgdHlwZSAnJ3sxfScnLgotICAgICAgICBtaW5FeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMyA9IG1pbkV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4zOiBFcnJvciBmb3IgdHlwZSAnJ3syfScnLiBUaGUgbWluRXhjbHVzaXZlIHZhbHVlID0nJ3swfScnIG11c3QgYmUgPj0gbWluSW5jbHVzaXZlIG9mIHRoZSBiYXNlIHR5cGUgJyd7MX0nJy4KLSAgICAgICAgbWluRXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjQgPSBtaW5FeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uNDogRXJyb3IgZm9yIHR5cGUgJyd7Mn0nJy4gVGhlIG1pbkV4Y2x1c2l2ZSB2YWx1ZSA9Jyd7MH0nJyBtdXN0IGJlIDwgbWF4RXhjbHVzaXZlIG9mIHRoZSBiYXNlIHR5cGUgJyd7MX0nJy4KLSAgICAgICAgbWluSW5jbHVzaXZlLWxlc3MtdGhhbi1lcXVhbC10by1tYXhJbmNsdXNpdmUgPSBtaW5JbmNsdXNpdmUtbGVzcy10aGFuLWVxdWFsLXRvLW1heEluY2x1c2l2ZTogSW4gdGhlIGRlZmluaXRpb24gb2YgezJ9LCBtaW5JbmNsdXNpdmUgdmFsdWUgPSAnJ3swfScnIG11c3QgYmUgPD0gbWF4SW5jbHVzaXZlIHZhbHVlID0gJyd7MX0nJy4KLSAgICAgICAgbWluSW5jbHVzaXZlLWxlc3MtdGhhbi1tYXhFeGNsdXNpdmUgPSBtaW5JbmNsdXNpdmUtbGVzcy10aGFuLW1heEV4Y2x1c2l2ZTogSW4gdGhlIGRlZmluaXRpb24gb2YgezJ9LCBtaW5JbmNsdXNpdmUgdmFsdWUgPSAnJ3swfScnIG11c3QgYmUgPCBtYXhFeGNsdXNpdmUgdmFsdWUgPSAnJ3sxfScnLgotICAgICAgICBtaW5JbmNsdXNpdmUtbWluRXhjbHVzaXZlID0gbWluSW5jbHVzaXZlLW1pbkV4Y2x1c2l2ZTogSXQgaXMgYW4gZXJyb3IgZm9yIGJvdGggbWluSW5jbHVzaXZlIGFuZCBtaW5FeGNsdXNpdmUgdG8gYmUgc3BlY2lmaWVkIGZvciB0aGUgc2FtZSBkYXRhdHlwZS4gSW4gezJ9LCBtaW5JbmNsdXNpdmUgPSAnJ3swfScnIGFuZCBtaW5FeGNsdXNpdmUgPSAnJ3sxfScnLgotICAgICAgICBtaW5JbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMSA9IG1pbkluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4xOiBFcnJvciBmb3IgdHlwZSAnJ3syfScnLiBUaGUgbWluSW5jbHVzaXZlIHZhbHVlID0nJ3swfScnIG11c3QgYmUgPj0gbWluSW5jbHVzaXZlIG9mIHRoZSBiYXNlIHR5cGUgJyd7MX0nJy4KLSAgICAgICAgbWluSW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjIgPSBtaW5JbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMjogRXJyb3IgZm9yIHR5cGUgJyd7Mn0nJy4gVGhlIG1pbkluY2x1c2l2ZSB2YWx1ZSA9Jyd7MH0nJyBtdXN0IGJlIDw9IG1heEluY2x1c2l2ZSBvZiB0aGUgYmFzZSB0eXBlICcnezF9JycuCi0gICAgICAgIG1pbkluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4zID0gbWluSW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjM6IEVycm9yIGZvciB0eXBlICcnezJ9JycuIFRoZSBtaW5JbmNsdXNpdmUgdmFsdWUgPScnezB9JycgbXVzdCBiZSA+IG1pbkV4Y2x1c2l2ZSBvZiB0aGUgYmFzZSB0eXBlICcnezF9JycuCi0gICAgICAgIG1pbkluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi40ID0gbWluSW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjQ6IEVycm9yIGZvciB0eXBlICcnezJ9JycuIFRoZSBtaW5JbmNsdXNpdmUgdmFsdWUgPScnezB9JycgbXVzdCBiZSA8IG1heEV4Y2x1c2l2ZSBvZiB0aGUgYmFzZSB0eXBlICcnezF9JycuCi0gICAgICAgIG1pbkxlbmd0aC1sZXNzLXRoYW4tZXF1YWwtdG8tbWF4TGVuZ3RoID0gbWluTGVuZ3RoLWxlc3MtdGhhbi1lcXVhbC10by1tYXhMZW5ndGg6IEluIHRoZSBkZWZpbml0aW9uIG9mIHsyfSwgdmFsdWUgb2YgbWluTGVuZ3RoID0gJyd7MH0nJyBtdXN0IGJlIDwgdmFsdWUgb2YgbWF4TGVuZ3RoID0gJyd7MX0nJy4KLSAgICAgICAgbWluTGVuZ3RoLXZhbGlkLXJlc3RyaWN0aW9uID0gbWluTGVuZ3RoLXZhbGlkLXJlc3RyaWN0aW9uOiBJbiB0aGUgZGVmaW5pdGlvbiBvZiB7Mn0sIG1pbkxlbmd0aCA9ICcnezB9JycgbXVzdCBiZSA+PSB0aGFuIHRoYXQgb2YgdGhlIGJhc2UgdHlwZSwgJyd7MX0nJy4KLSAgICAgICAgbm8teG1sbnMgPSBuby14bWxuczogVGhlIHtuYW1lfSBvZiBhbiBhdHRyaWJ1dGUgZGVjbGFyYXRpb24gbXVzdCBub3QgbWF0Y2ggJ3htbG5zJy4KLSAgICAgICAgbm8teHNpID0gbm8teHNpOiBUaGUgJ3sndGFyZ2V0IG5hbWVzcGFjZSd9JyBvZiBhbiBhdHRyaWJ1dGUgZGVjbGFyYXRpb24gbXVzdCBub3QgbWF0Y2ggJyd7MH0nJy4KLSAgICAgICAgcC1wcm9wcy1jb3JyZWN0LjIuMSA9IHAtcHJvcHMtY29ycmVjdC4yLjE6IEluIHRoZSBkZWNsYXJhdGlvbiBvZiAnJ3swfScnLCB0aGUgdmFsdWUgb2YgJydtaW5PY2N1cnMnJyBpcyAnJ3sxfScnLCBidXQgaXQgbXVzdCBub3QgYmUgZ3JlYXRlciB0aGFuIHRoZSB2YWx1ZSBvZiAnJ21heE9jY3VycycnLCB3aGljaCBpcyAnJ3syfScnLgotICAgICAgICByY2FzZS1NYXBBbmRTdW0uMSA9IHJjYXNlLU1hcEFuZFN1bS4xOiBUaGVyZSBpcyBub3QgYSBjb21wbGV0ZSBmdW5jdGlvbmFsIG1hcHBpbmcgYmV0d2VlbiB0aGUgcGFydGljbGVzLgotICAgICAgICByY2FzZS1NYXBBbmRTdW0uMiA9IHJjYXNlLU1hcEFuZFN1bS4yOiBHcm91cCcncyBvY2N1cnJlbmNlIHJhbmdlLCAoezB9LHsxfSksIGlzIG5vdCBhIHZhbGlkIHJlc3RyaWN0aW9uIG9mIGJhc2UgZ3JvdXAnJ3Mgb2NjdXJyZW5jZSByYW5nZSwgKHsyfSx7M30pLgotICAgICAgICByY2FzZS1OYW1lQW5kVHlwZU9LLjEgPSByY2FzZS1OYW1lQW5kVHlwZU9LLjE6IEVsZW1lbnRzIGhhdmUgbmFtZXMgYW5kIHRhcmdldCBuYW1lc3BhY2VzIHdoaWNoIGFyZSBub3QgdGhlIHNhbWU6ICBFbGVtZW50ICcnezB9JycgaW4gbmFtZXNwYWNlICcnezF9JycgYW5kIGVsZW1lbnQgJyd7Mn0nJyBpbiBuYW1lc3BhY2UgJyd7M30nJy4KLSAgICAgICAgcmNhc2UtTmFtZUFuZFR5cGVPSy4yID0gcmNhc2UtTmFtZUFuZFR5cGVPSy4yOiBFcnJvciBmb3IgdGhlIHBhcnRpY2xlIHdob3NlICd7J3Rlcm0nfScgaXMgdGhlIGVsZW1lbnQgZGVjbGFyYXRpb24gJyd7MH0nJy4gVGhlIGVsZW1lbnQgZGVjbGFyYXRpb24nJ3MgJ3snbmlsbGFibGUnfScgaXMgdHJ1ZSwgYnV0IHRoZSBjb3JyZXNwb25kaW5nIHBhcnRpY2xlIGluIHRoZSBiYXNlIHR5cGUgaGFzIGFuIGVsZW1lbnQgZGVjbGFyYXRpb24gd2hvc2UgJ3snbmlsbGFibGUnfScgaXMgZmFsc2UuCi0gICAgICAgIHJjYXNlLU5hbWVBbmRUeXBlT0suMyA9IHJjYXNlLU5hbWVBbmRUeXBlT0suMzogRXJyb3IgZm9yIHRoZSBwYXJ0aWNsZSB3aG9zZSAneyd0ZXJtJ30nIGlzIHRoZSBlbGVtZW50IGRlY2xhcmF0aW9uICcnezB9JycuIEl0cyBvY2N1cnJlbmNlIHJhbmdlLCAoezF9LHsyfSksIGlzIG5vdCBhIHZhbGlkIHJlc3RyaWN0aW9uIG9mIHRoZSByYW5nZSwgKHszfSx7NH0sIG9mIHRoZSBjb3JyZXNwb25kaW5nIHBhcnRpY2xlIGluIHRoZSBiYXNlIHR5cGUuCi0gICAgICAgIHJjYXNlLU5hbWVBbmRUeXBlT0suNC5hID0gcmNhc2UtTmFtZUFuZFR5cGVPSy40LmE6IEVsZW1lbnQgJyd7MH0nJyBpcyBub3QgZml4ZWQsIGJ1dCB0aGUgY29ycmVzcG9uZGluZyBlbGVtZW50IGluIHRoZSBiYXNlIHR5cGUgaXMgZml4ZWQgd2l0aCB2YWx1ZSAnJ3sxfScnLgotICAgICAgICByY2FzZS1OYW1lQW5kVHlwZU9LLjQuYiA9IHJjYXNlLU5hbWVBbmRUeXBlT0suNC5iOiBFbGVtZW50ICcnezB9JycgaXMgZml4ZWQgd2l0aCB2YWx1ZSAnJ3sxfScnLCBidXQgdGhlIGNvcnJlc3BvbmRpbmcgZWxlbWVudCBpbiB0aGUgYmFzZSB0eXBlIGlzIGZpeGVkIHdpdGggdmFsdWUgJyd7Mn0nJy4KLSAgICAgICAgcmNhc2UtTmFtZUFuZFR5cGVPSy41ID0gcmNhc2UtTmFtZUFuZFR5cGVPSy41OiBJZGVudGl0eSBjb25zdHJhaW50cyBmb3IgZWxlbWVudCAnJ3swfScnIGFyZSBub3QgYSBzdWJzZXQgb2YgdGhvc2UgaW4gYmFzZS4KLSAgICAgICAgcmNhc2UtTmFtZUFuZFR5cGVPSy42ID0gcmNhc2UtTmFtZUFuZFR5cGVPSy42OiBUaGUgZGlzYWxsb3dlZCBzdWJzdGl0dXRpb25zIGZvciBlbGVtZW50ICcnezB9JycgYXJlIG5vdCBhIHN1cGVyc2V0IG9mIHRob3NlIGluIHRoZSBiYXNlLgotICAgICAgICByY2FzZS1OYW1lQW5kVHlwZU9LLjcgPSByY2FzZS1OYW1lQW5kVHlwZU9LLjc6IFRoZSB0eXBlIG9mIGVsZW1lbnQgJyd7MH0nJywgJyd7MX0nJywgaXMgbm90IGRlcml2ZWQgZnJvbSB0aGUgdHlwZSBvZiB0aGUgYmFzZSBlbGVtZW50LCAnJ3syfScnLgotICAgICAgICByY2FzZS1OU0NvbXBhdC4xID0gcmNhc2UtTlNDb21wYXQuMTogRWxlbWVudCAnJ3swfScnIGhhcyBhIG5hbWVzcGFjZSAnJ3sxfScnIHdoaWNoIGlzIG5vdCBhbGxvd2VkIGJ5IHRoZSB3aWxkY2FyZCBpbiB0aGUgYmFzZS4KLSAgICAgICAgcmNhc2UtTlNDb21wYXQuMiA9IHJjYXNlLU5TQ29tcGF0LjI6IEVycm9yIGZvciB0aGUgcGFydGljbGUgd2hvc2UgJ3sndGVybSd9JyBpcyB0aGUgZWxlbWVudCBkZWNsYXJhdGlvbiAnJ3swfScnLiBJdHMgb2NjdXJyZW5jZSByYW5nZSwgKHsxfSx7Mn0pLCBpcyBub3QgYSB2YWxpZCByZXN0cmljdGlvbiBvZiB0aGUgcmFuZ2UsICh7M30sezR9LCBvZiB0aGUgY29ycmVzcG9uZGluZyBwYXJ0aWNsZSBpbiB0aGUgYmFzZSB0eXBlLgotICAgICAgICByY2FzZS1OU1JlY3Vyc2VDaGVja0NhcmRpbmFsaXR5LjEgPSByY2FzZS1OU1JlY3Vyc2VDaGVja0NhcmRpbmFsaXR5LjE6IFRoZXJlIGlzIG5vdCBhIGNvbXBsZXRlIGZ1bmN0aW9uYWwgbWFwcGluZyBiZXR3ZWVuIHRoZSBwYXJ0aWNsZXMuCi0gICAgICAgIHJjYXNlLU5TUmVjdXJzZUNoZWNrQ2FyZGluYWxpdHkuMiA9IHJjYXNlLU5TUmVjdXJzZUNoZWNrQ2FyZGluYWxpdHkuMjogR3JvdXAnJ3Mgb2NjdXJyZW5jZSByYW5nZSwgKHswfSx7MX0pLCBpcyBub3QgYSB2YWxpZCByZXN0cmljdGlvbiBvZiBiYXNlIHdpbGRjYXJkJydzIHJhbmdlLCAoezJ9LHszfSkuCi0gICAgICAgIHJjYXNlLU5TU3Vic2V0LjEgPSByY2FzZS1OU1N1YnNldC4xOiBXaWxkY2FyZCBpcyBub3QgYSBzdWJzZXQgb2YgY29ycmVzcG9uZGluZyB3aWxkY2FyZCBpbiBiYXNlLgotICAgICAgICByY2FzZS1OU1N1YnNldC4yID0gcmNhc2UtTlNTdWJzZXQuMjogV2lsZGNhcmQnJ3Mgb2NjdXJyZW5jZSByYW5nZSwgKHswfSx7MX0pLCBpcyBub3QgYSB2YWxpZCByZXN0cmljdGlvbiBvZiB0aGF0IGluIHRoZSBiYXNlLCAoezJ9LHszfSksLgotICAgICAgICByY2FzZS1OU1N1YnNldC4zID0gcmNhc2UtTlNTdWJzZXQuMzogV2lsZGNhcmQnJ3MgcHJvY2VzcyBjb250ZW50cywgJyd7MH0nJywgaXMgd2Vha2VyIHRoYW4gdGhhdCBpbiB0aGUgYmFzZSwgJyd7MX0nJy4KLSAgICAgICAgcmNhc2UtUmVjdXJzZS4xID0gcmNhc2UtUmVjdXJzZS4xOiBHcm91cCcncyBvY2N1cnJlbmNlIHJhbmdlLCAoezB9LHsxfSksIGlzIG5vdCBhIHZhbGlkIHJlc3RyaWN0aW9uIG9mIGJhc2UgZ3JvdXAnJ3Mgb2NjdXJyZW5jZSByYW5nZSwgKHsyfSx7M30pLgotICAgICAgICByY2FzZS1SZWN1cnNlLjIgPSByY2FzZS1SZWN1cnNlLjI6IFRoZXJlIGlzIG5vdCBhIGNvbXBsZXRlIGZ1bmN0aW9uYWwgbWFwcGluZyBiZXR3ZWVuIHRoZSBwYXJ0aWNsZXMuCi0gICAgICAgIHJjYXNlLVJlY3Vyc2VMYXguMSA9IHJjYXNlLVJlY3Vyc2VMYXguMTogR3JvdXAnJ3Mgb2NjdXJyZW5jZSByYW5nZSwgKHswfSx7MX0pLCBpcyBub3QgYSB2YWxpZCByZXN0cmljdGlvbiBvZiBiYXNlIGdyb3VwJydzIG9jY3VycmVuY2UgcmFuZ2UsICh7Mn0sezN9KS4KLSAgICAgICAgcmNhc2UtUmVjdXJzZUxheC4yID0gcmNhc2UtUmVjdXJzZUxheC4yOiBUaGVyZSBpcyBub3QgYSBjb21wbGV0ZSBmdW5jdGlvbmFsIG1hcHBpbmcgYmV0d2VlbiB0aGUgcGFydGljbGVzLgotICAgICAgICByY2FzZS1SZWN1cnNlVW5vcmRlcmVkLjEgPSByY2FzZS1SZWN1cnNlVW5vcmRlcmVkLjE6IEdyb3VwJydzIG9jY3VycmVuY2UgcmFuZ2UsICh7MH0sezF9KSwgaXMgbm90IGEgdmFsaWQgcmVzdHJpY3Rpb24gb2YgYmFzZSBncm91cCcncyBvY2N1cnJlbmNlIHJhbmdlLCAoezJ9LHszfSkuCi0gICAgICAgIHJjYXNlLVJlY3Vyc2VVbm9yZGVyZWQuMiA9IHJjYXNlLVJlY3Vyc2VVbm9yZGVyZWQuMjogVGhlcmUgaXMgbm90IGEgY29tcGxldGUgZnVuY3Rpb25hbCBtYXBwaW5nIGJldHdlZW4gdGhlIHBhcnRpY2xlcy4KLSMgICAgICAgIFdlJ3JlIHVzaW5nIHNjaC1wcm9wcy1jb3JyZWN0LjIgaW5zdGVhZCBvZiB0aGUgb2xkIHNyYy1yZWRlZmluZS4xCi0jICAgICAgICBzcmMtcmVkZWZpbmUuMSA9IHNyYy1yZWRlZmluZS4xOiBUaGUgY29tcG9uZW50ICcnezB9JycgaXMgYmVnaW4gcmVkZWZpbmVkLCBidXQgaXRzIGNvcnJlc3BvbmRpbmcgY29tcG9uZW50IGlzbid0IGluIHRoZSBzY2hlbWEgZG9jdW1lbnQgYmVpbmcgcmVkZWZpbmVkICh3aXRoIG5hbWVzcGFjZSAnJ3syfScnKSwgYnV0IGluIGEgZGlmZmVyZW50IGRvY3VtZW50LCB3aXRoIG5hbWVzcGFjZSAnJ3sxfScnLgotICAgICAgICBzY2gtcHJvcHMtY29ycmVjdC4yID0gc2NoLXByb3BzLWNvcnJlY3QuMjogQSBzY2hlbWEgY2Fubm90IGNvbnRhaW4gdHdvIGdsb2JhbCBjb21wb25lbnRzIHdpdGggdGhlIHNhbWUgbmFtZTsgdGhpcyBzY2hlbWEgY29udGFpbnMgdHdvIG9jY3VycmVuY2VzIG9mICcnezB9JycuCi0gICAgICAgIHN0LXByb3BzLWNvcnJlY3QuMiA9IHN0LXByb3BzLWNvcnJlY3QuMjogQ2lyY3VsYXIgZGVmaW5pdGlvbnMgaGF2ZSBiZWVuIGRldGVjdGVkIGZvciBzaW1wbGUgdHlwZSAnJ3swfScnLiBUaGlzIG1lYW5zIHRoYXQgJyd7MH0nJyBpcyBjb250YWluZWQgaW4gaXRzIG93biB0eXBlIGhpZXJhcmNoeSwgd2hpY2ggaXMgYW4gZXJyb3IuCi0gICAgICAgIHN0LXByb3BzLWNvcnJlY3QuMyA9IHN0LXByb3BzLWNvcnJlY3QuMzogRXJyb3IgZm9yIHR5cGUgJyd7MH0nJy4gVGhlIHZhbHVlIG9mICd7J2ZpbmFsJ30nIG9mIHRoZSAneydiYXNlIHR5cGUgZGVmaW5pdGlvbid9JywgJyd7MX0nJywgZm9yYmlkcyBkZXJpdmF0aW9uIGJ5IHJlc3RyaWN0aW9uLgotICAgICAgICB0b3RhbERpZ2l0cy12YWxpZC1yZXN0cmljdGlvbiA9IHRvdGFsRGlnaXRzLXZhbGlkLXJlc3RyaWN0aW9uOiBJbiB0aGUgZGVmaW5pdGlvbiBvZiB7Mn0sIHRoZSB2YWx1ZSAnJ3swfScnIGZvciB0aGUgZmFjZXQgJyd0b3RhbERpZ2l0cycnIGlzIGludmFsaWQsIGJlY2F1c2UgaXQgbXVzdCBiZSA8PSB0aGUgdmFsdWUgZm9yICcndG90YWxEaWdpdHMnJyB3aGljaCB3YXMgc2V0IHRvICcnezF9JycgaW4gb25lIG9mIHRoZSBhbmNlc3RvciB0eXBlcy4KLSAgICAgICAgd2hpdGVTcGFjZS12YWxpZC1yZXN0cmljdGlvbi4xID0gd2hpdGVTcGFjZS12YWxpZC1yZXN0cmljdGlvbi4xOiBJbiB0aGUgZGVmaW5pdGlvbiBvZiB7MH0sIHRoZSB2YWx1ZSAnJ3sxfScnIGZvciB0aGUgZmFjZXQgJyd3aGl0ZXNwYWNlJycgaXMgaW52YWxpZCwgYmVjYXVzZSB0aGUgdmFsdWUgZm9yICcnd2hpdGVzcGFjZScnIGhhcyBiZWVuIHNldCB0byAnJ2NvbGxhcHNlJycgaW4gb25lIG9mIHRoZSBhbmNlc3RvciB0eXBlcy4KLSAgICAgICAgd2hpdGVTcGFjZS12YWxpZC1yZXN0cmljdGlvbi4yID0gd2hpdGVTcGFjZS12YWxpZC1yZXN0cmljdGlvbi4yOiBJbiB0aGUgZGVmaW5pdGlvbiBvZiB7MH0sIHRoZSB2YWx1ZSAnJ3ByZXNlcnZlJycgZm9yIHRoZSBmYWNldCAnJ3doaXRlc3BhY2UnJyBpcyBpbnZhbGlkLCBiZWNhdXNlIHRoZSB2YWx1ZSBmb3IgJyd3aGl0ZXNwYWNlJycgaGFzIGJlZW4gc2V0IHRvICcncmVwbGFjZScnIGluIG9uZSBvZiB0aGUgYW5jZXN0b3IgdHlwZXMuCi0KLSNzY2hlbWEgZm9yIFNjaGVtYXMKLQotICAgICAgICBzNHMtYXR0LWludmFsaWQtdmFsdWUgPSBzNHMtYXR0LWludmFsaWQtdmFsdWU6IEludmFsaWQgYXR0cmlidXRlIHZhbHVlIGZvciAnJ3sxfScnIGluIGVsZW1lbnQgJyd7MH0nJy4gUmVjb3JkZWQgcmVhc29uOiB7Mn0KLSAgICAgICAgczRzLWF0dC1tdXN0LWFwcGVhciA9IHM0cy1hdHQtbXVzdC1hcHBlYXI6IEF0dHJpYnV0ZSAnJ3sxfScnIG11c3QgYXBwZWFyIGluIGVsZW1lbnQgJyd7MH0nJy4KLSAgICAgICAgczRzLWF0dC1ub3QtYWxsb3dlZCA9IHM0cy1hdHQtbm90LWFsbG93ZWQ6IEF0dHJpYnV0ZSAnJ3sxfScnIGNhbm5vdCBhcHBlYXIgaW4gZWxlbWVudCAnJ3swfScnLgotICAgICAgICBzNHMtZWx0LWludmFsaWQgPSBzNHMtZWx0LWludmFsaWQ6IEVsZW1lbnQgJyd7MH0nJyBpcyBub3QgYSB2YWxpZCBlbGVtZW50IGluIGEgc2NoZW1hIGRvY3VtZW50LgotICAgICAgICBzNHMtZWx0LW11c3QtbWF0Y2guMSA9IHM0cy1lbHQtbXVzdC1tYXRjaC4xOiBUaGUgY29udGVudCBvZiAnJ3swfScnIG11c3QgbWF0Y2ggezF9LiBBIHByb2JsZW0gd2FzIGZvdW5kIHN0YXJ0aW5nIGF0OiB7Mn0uCi0gICAgICAgIHM0cy1lbHQtbXVzdC1tYXRjaC4yID0gczRzLWVsdC1tdXN0LW1hdGNoLjI6IFRoZSBjb250ZW50IG9mICcnezB9JycgbXVzdCBtYXRjaCB7MX0uIE5vdCBlbm91Z2ggZWxlbWVudHMgd2VyZSBmb3VuZC4KLSAgICAgICAgIyB0aGUgImludmFsaWQtY29udGVudCIgbWVzc2FnZXMgcHJvdmlkZSBsZXNzIGluZm9ybWF0aW9uIHRoYW4gdGhlICJtdXN0LW1hdGNoIiBjb3VudGVycGFydHMgYWJvdmUuIFRoZXkncmUgdXNlZCBmb3IgY29tcGxleCB0eXBlcyB3aGVuIHByb3ZpZGluZyBhICJtYXRjaCIgd291bGQgYmUgYW4gaW5mb3JtYXRpb24gZHVtcAotICAgICAgICBzNHMtZWx0LWludmFsaWQtY29udGVudC4xID0gczRzLWVsdC1pbnZhbGlkLWNvbnRlbnQuMTogVGhlIGNvbnRlbnQgb2YgJyd7MH0nJyBpcyBpbnZhbGlkLiAgRWxlbWVudCAnJ3sxfScnIGlzIGludmFsaWQsIG1pc3BsYWNlZCwgb3Igb2NjdXJzIHRvbyBvZnRlbi4KLSAgICAgICAgczRzLWVsdC1pbnZhbGlkLWNvbnRlbnQuMiA9IHM0cy1lbHQtaW52YWxpZC1jb250ZW50LjI6IFRoZSBjb250ZW50IG9mICcnezB9JycgaXMgaW52YWxpZC4gIEVsZW1lbnQgJyd7MX0nJyBjYW5ub3QgYmUgZW1wdHkuCi0gICAgICAgIHM0cy1lbHQtaW52YWxpZC1jb250ZW50LjMgPSBzNHMtZWx0LWludmFsaWQtY29udGVudC4zOiBFbGVtZW50cyBvZiB0eXBlICcnezB9JycgY2Fubm90IGFwcGVhciBhZnRlciBkZWNsYXJhdGlvbnMgYXMgY2hpbGRyZW4gb2YgYSA8c2NoZW1hPiBlbGVtZW50LgotICAgICAgICBzNHMtZWx0LXNjaGVtYS1ucyA9IHM0cy1lbHQtc2NoZW1hLW5zOiBUaGUgbmFtZXNwYWNlIG9mIGVsZW1lbnQgJyd7MH0nJyBtdXN0IGJlIGZyb20gdGhlIHNjaGVtYSBuYW1lc3BhY2UsICcnaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEnJy4KLSAgICAgICAgczRzLWVsdC1jaGFyYWN0ZXIgPSBzNHMtZWx0LWNoYXJhY3RlcjogTm9uLXdoaXRlc3BhY2UgY2hhcmFjdGVycyBhcmUgbm90IGFsbG93ZWQgaW4gc2NoZW1hIGVsZW1lbnRzIG90aGVyIHRoYW4gJyd4czphcHBpbmZvJycgYW5kICcneHM6ZG9jdW1lbnRhdGlvbicnLiBTYXcgJyd7MH0nJy4KLQotIyBjb2RlcyBub3QgZGVmaW5lZCBieSB0aGUgc3BlYwotCi0gICAgICAgIGMtZmllbGRzLXhwYXRocyA9IGMtZmllbGRzLXhwYXRoczogVGhlIGZpZWxkIHZhbHVlID0gJyd7MH0nJyBpcyBub3QgdmFsaWQuCi0gICAgICAgIGMtZ2VuZXJhbC14cGF0aCA9IGMtZ2VuZXJhbC14cGF0aDogVGhlIGV4cHJlc3Npb24gJyd7MH0nJyBpcyBub3QgdmFsaWQgd2l0aCByZXNwZWN0IHRvIHRoZSBYUGF0aCBzdWJzZXQgc3VwcG9ydGVkIGJ5IFhNTCBTY2hlbWEuCi0gICAgICAgIGMtZ2VuZXJhbC14cGF0aC1ucyA9IGMtZ2VuZXJhbC14cGF0aC1uczogQSBuYW1lc3BhY2UgcHJlZml4IGluIFhQYXRoIGV4cHJlc3Npb24gJyd7MH0nJyB3YXMgbm90IGJvdW5kIHRvIGEgbmFtZXNwYWNlLgotICAgICAgICBjLXNlbGVjdG9yLXhwYXRoID0gYy1zZWxlY3Rvci14cGF0aDogVGhlIHNlbGVjdG9yIHZhbHVlID0gJyd7MH0nJyBpcyBub3QgdmFsaWQ7IHNlbGVjdG9yIHhwYXRocyBjYW5ub3QgY29udGFpbiBhdHRyaWJ1dGVzLgotICAgICAgICBFbXB0eVRhcmdldE5hbWVzcGFjZSA9IEVtcHR5VGFyZ2V0TmFtZXNwYWNlOiBJbiBzY2hlbWEgZG9jdW1lbnQgJyd7MH0nJywgdGhlIHZhbHVlIG9mIHRoZSAnJ3RhcmdldE5hbWVzcGFjZScnIGF0dHJpYnV0ZSBjYW5ub3QgYmUgYW4gZW1wdHkgc3RyaW5nLgotICAgICAgICBGYWNldFZhbHVlRnJvbUJhc2UgPSBGYWNldFZhbHVlRnJvbUJhc2U6IEluIHRoZSBkZWNsYXJhdGlvbiBvZiB0eXBlICcnezB9JycsIHZhbHVlICcnezF9Jycgb2YgZmFjZXQgJyd7Mn0nJyBtdXN0IGJlIGZyb20gdGhlIHZhbHVlIHNwYWNlIG9mIHRoZSBiYXNlIHR5cGUsICcnezN9JycuCi0gICAgICAgIEZpeGVkRmFjZXRWYWx1ZSA9IEZpeGVkRmFjZXRWYWx1ZTogSW4gdGhlIGRlZmluaXRpb24gb2YgezN9LCB0aGUgdmFsdWUgJyd7MX0nJyBmb3IgdGhlIGZhY2V0ICcnezB9JycgaXMgaW52YWxpZCwgYmVjYXVzZSB0aGUgdmFsdWUgZm9yICcnezB9JycgaGFzIGJlZW4gc2V0IHRvICcnezJ9JycgaW4gb25lIG9mIHRoZSBhbmNlc3RvciB0eXBlcywgYW5kICd7J2ZpeGVkJ30nID0gdHJ1ZS4KLSAgICAgICAgSW52YWxpZFJlZ2V4ID0gSW52YWxpZFJlZ2V4OiBQYXR0ZXJuIHZhbHVlICcnezB9JycgaXMgbm90IGEgdmFsaWQgcmVndWxhciBleHByZXNzaW9uLiBUaGUgcmVwb3J0ZWQgZXJyb3Igd2FzOiAnJ3sxfScnIGF0IGNvbHVtbiAnJ3syfScnLgotICAgICAgICBNYXhPY2N1ckxpbWl0ID0gQ3VycmVudCBjb25maWd1cmF0aW9uIG9mIHRoZSBwYXJzZXIgZG9lc24nJ3QgYWxsb3cgYSBtYXhPY2N1cnMgYXR0cmlidXRlIHZhbHVlIHRvIGJlIHNldCBncmVhdGVyIHRoYW4gdGhlIHZhbHVlIHswfS4KLSAgICAgICAgUHVibGljU3lzdGVtT25Ob3RhdGlvbiA9IFB1YmxpY1N5c3RlbU9uTm90YXRpb246IEF0IGxlYXN0IG9uZSBvZiAnJ3B1YmxpYycnIGFuZCAnJ3N5c3RlbScnIG11c3QgYXBwZWFyIGluIGVsZW1lbnQgJydub3RhdGlvbicnLgotICAgICAgICBTY2hlbWFMb2NhdGlvbiA9IFNjaGVtYUxvY2F0aW9uOiBzY2hlbWFMb2NhdGlvbiB2YWx1ZSA9ICcnezB9JycgbXVzdCBoYXZlIGV2ZW4gbnVtYmVyIG9mIFVSSScncy4KLSAgICAgICAgVGFyZ2V0TmFtZXNwYWNlLjEgPSBUYXJnZXROYW1lc3BhY2UuMTogRXhwZWN0aW5nIG5hbWVzcGFjZSAnJ3swfScnLCBidXQgdGhlIHRhcmdldCBuYW1lc3BhY2Ugb2YgdGhlIHNjaGVtYSBkb2N1bWVudCBpcyAnJ3sxfScnLgotICAgICAgICBUYXJnZXROYW1lc3BhY2UuMiA9IFRhcmdldE5hbWVzcGFjZS4yOiBFeHBlY3Rpbmcgbm8gbmFtZXNwYWNlLCBidXQgdGhlIHNjaGVtYSBkb2N1bWVudCBoYXMgYSB0YXJnZXQgbmFtZXNwYWNlIG9mICcnezF9JycuCi0gICAgICAgIFVuZGVjbGFyZWRFbnRpdHkgPSBVbmRlY2xhcmVkRW50aXR5OiBFbnRpdHkgJyd7MH0nJyBpcyBub3QgZGVjbGFyZWQuCi0gICAgICAgIFVuZGVjbGFyZWRQcmVmaXggPSBVbmRlY2xhcmVkUHJlZml4OiBDYW5ub3QgcmVzb2x2ZSAnJ3swfScnIGFzIGEgUU5hbWU6IHRoZSBwcmVmaXggJyd7MX0nJyBpcyBub3QgZGVjbGFyZWQuCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9YTUxTY2hlbWFNZXNzYWdlc19kZS5wcm9wZXJ0aWVzIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MU2NoZW1hTWVzc2FnZXNfZGUucHJvcGVydGllcwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYTBkMmM2ZC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9YTUxTY2hlbWFNZXNzYWdlc19kZS5wcm9wZXJ0aWVzCisrKyAvZGV2L251bGwKQEAgLTEsMjkxICswLDAgQEAKLSMgVGhpcyBmaWxlIGNvbnRhaW5zIGVycm9yIGFuZCB3YXJuaW5nIG1lc3NhZ2VzIHJlbGF0ZWQgdG8gWE1MIFNjaGVtYQotIyBUaGUgbWVzc2FnZXMgYXJlIGFycmFuZ2VkIGluIGtleSBhbmQgdmFsdWUgdHVwbGVzIGluIGEgTGlzdFJlc291cmNlQnVuZGxlLgotIwotCi0gICAgICAgIEJhZE1lc3NhZ2VLZXkgPSBEaWUgenVtIE1lbGR1bmdzc2NobFx1MDBGQ3NzZWwgZ2VoXHUwMEY2cmlnZSBGZWhsZXJtZWxkdW5nIGthbm4gbmljaHQgZ2VmdW5kZW4gd2VyZGVuLgotICAgICAgICBGb3JtYXRGYWlsZWQgPSBCZWltIEZvcm1hdGllcmVuIGRlciBmb2xnZW5kZW4gTWVsZHVuZyBpc3QgZWluIGludGVybmVyIEZlaGxlciBhdWZnZXRyZXRlbjpcbgotCi0jIEZvciBpbnRlcm5hbCB1c2UKLQotICAgICAgICBJbnRlcm5hbC1FcnJvciA9IEludGVybmVyIEZlaGxlcjogezB9LgotICAgICAgICBkdC13aGl0ZXNwYWNlID0gTGVlcnN0ZWxsZW4tRmFjZXQtV2VydCBpc3QgbmljaHQgZlx1MDBGQ3IgVmVyZWluaWd1bmdzbWVuZ2Ugc2ltcGxlVHlwZSAnJ3swfScnIHZlcmZcdTAwRkNnYmFyCi0gICAgICAgIEdyYW1tYXJDb25mbGljdCA9IEVpbmUgdm9tIEdyYW1tYXRpa3Bvb2wgZGVzIEJlbnV0emVycyB6dXJcdTAwRkNja2dlZ2ViZW5lIEdyYW1tYXRpayBzdGVodCBpbSBLb25mbGlrdCBtaXQgZWluZXIgYW5kZXJlbiBHcmFtbWF0aWsuCi0KLSMgSWRlbnRpdHkgY29uc3RyYWludHMKLQotICAgICAgICBBYnNlbnRLZXlWYWx1ZSA9IElkZW50aXR5IENvbnN0cmFpbnQtRmVobGVyIChjdmMtaWRlbnRpdHktY29uc3RyYWludC40LjIuMSk6IEVsZW1lbnQgJyd7MH0nJyBoYXQgZWluZW4gU2NobFx1MDBGQ3NzZWwgb2huZSBXZXJ0LgotICAgICAgICBEdXBsaWNhdGVGaWVsZCA9IERvcHBlbHRlIFx1MDBEQ2JlcmVpbnN0aW1tdW5nIGluIEdlbHR1bmdzYmVyZWljaCBmXHUwMEZDciBGZWxkICcnezB9JycuCi0gICAgICAgIER1cGxpY2F0ZUtleSA9IERvcHBlbHRlciBTY2hsXHUwMEZDc3NlbHdlcnQgW3swfV0gZlx1MDBGQ3IgSWRlbnRpdHkgQ29uc3RyYWludCBkZXMgRWxlbWVudHMgJyd7MX0nJ2Rla2xhcmllcnQuCi0gICAgICAgIER1cGxpY2F0ZVVuaXF1ZSA9IERvcHBlbHRlciBlaW5kZXV0aWdlciBXZXJ0IFt7MH1dIGZcdTAwRkNyIElkZW50aXR5IENvbnN0cmFpbnQgZGVzIEVsZW1lbnRzICcnezF9JycgZGVrbGFyaWVydC4KLSAgICAgICAgRmllbGRNdWx0aXBsZU1hdGNoID0gSWRlbnRpdHkgQ29uc3RyYWludC1GZWhsZXI6IEZlbGQgJyd7MH0nJyBlbnRzcHJpY2h0IG1laHJlcmVuIFdlcnRlbiBpbSBHZWx0dW5nc2JlcmVpY2ggc2VpbmVzIFNlbGVrdG9ycy4gRmVsZGVyIG1cdTAwRkNzc2VuIGVpbmRldXRpZ2VuIFdlcnRlbiBlbnRzcHJlY2hlbi4KLSAgICAgICAgRml4ZWREaWZmZXJzRnJvbUFjdHVhbCA9IENvbnRlbnQgZGllc2VzIEVsZW1lbnRzIGVudHNwcmljaHQgbmljaHQgZGVtIFdlcnQgZGVzICdmaXhlZCctQXR0cmlidXRzIGluIGRlciBFbGVtZW50ZGVrbGFyYXRpb24gaW0gU2NoZW1hLgotICAgICAgICBLZXlNYXRjaGVzTmlsbGFibGUgPSBJZGVudGl0eSBDb25zdHJhaW50LUZlaGxlciAoY3ZjLWlkZW50aXR5LWNvbnN0cmFpbnQuNC4yLjMpOiBFbGVtZW50ICcnezB9JycgaGF0IGVpbmVuIFNjaGxcdTAwRkNzc2VsLCBkZXIgZWluZW0gRWxlbWVudCBlbnRzcHJpY2h0LCBiZWkgZGVtICcnbmlsbGFibGUnJyBhdWYgJyd0cnVlJycgZ2VzZXR6dCB3dXJkZS4KLSAgICAgICAgS2V5Tm90RW5vdWdoVmFsdWVzID0gTmljaHQgZ2VuXHUwMEZDZ2VuZCBXZXJ0ZSBhbmdlZ2ViZW4gZlx1MDBGQ3IgPGtleSBuYW1lPScnezF9Jyc+IElkZW50aXR5IENvbnN0cmFpbnQgZlx1MDBGQ3IgRWxlbWVudCAnJ3swfScnLgotICAgICAgICBLZXlOb3RGb3VuZCA9IFNjaGxcdTAwRkNzc2VsICcnezB9JycgbWl0IFdlcnQgJyd7MX0nJyBuaWNodCBnZWZ1bmRlbiBmXHUwMEZDciBJZGVudGl0eSBDb25zdHJhaW50IGRlcyBFbGVtZW50cyAnJ3syfScnLgotICAgICAgICBLZXlSZWZOb3RFbm91Z2hWYWx1ZXMgPSBOaWNodCBnZW5cdTAwRkNnZW5kIFdlcnRlIGFuZ2VnZWJlbiBmXHUwMEZDciA8a2V5cmVmIG5hbWU9Jyd7MX0nJz4gSWRlbnRpdHkgQ29uc3RyYWludCBmXHUwMEZDciBFbGVtZW50ICcnezB9JycuCi0gICAgICAgIEtleVJlZk91dE9mU2NvcGUgPSBJZGVudGl0eSBDb25zdHJhaW50LUZlaGxlcjogSWRlbnRpdHkgQ29uc3RyYWludCAnJ3swfScnIGhhdCBlaW5lIGtleXJlZiwgZGllIHp1IGVpbmVtIEtleS0gb2RlciBVbmlxdWUtQ29uc3RyYWludCBhdVx1MDBERmVyaGFsYiBkZXMgR2VsdHVuZ3NiZXJlaWNocyB2ZXJ3ZWlzdC4KLSAgICAgICAgS2V5UmVmUmVmZXJOb3RGb3VuZCA9IFNjaGxcdTAwRkNzc2VscmVmZXJlbnpkZWtsYXJhdGlvbiAnJ3swfScnIHZlcndlaXN0IGF1ZiBlaW5lbiB1bmJla2FubnRlbiBTY2hsXHUwMEZDc3NlbCBtaXQgZGVtIE5hbWVuICcnezF9JycuCi0gICAgICAgIFVuaXF1ZU5vdEVub3VnaFZhbHVlcyA9IE5pY2h0IGdlblx1MDBGQ2dlbmQgV2VydGUgYW5nZWdlYmVuIGZcdTAwRkNyIDx1bmlxdWU+IElkZW50aXR5IENvbnN0cmFpbnQgZlx1MDBGQ3IgRWxlbWVudCAnJ3swfScnLgotICAgICAgICBVbmtub3duRmllbGQgPSBJbnRlcm5lciBJZGVudGl0eSBDb25zdHJhaW50LUZlaGxlci4gVW5iZWthbm50ZXMgRmVsZCAnJ3swfScnLgotCi0jIElkZWFsbHksIHdlIHNob3VsZCBvbmx5IHVzZSB0aGUgZm9sbG93aW5nIGVycm9yIGtleXMsIG5vdCB0aGUgb25lcyB1bmRlcgotIyAiSWRlbnRpdHkgY29uc3RyYWludHMiLiBBbmQgd2Ugc2hvdWxkIGNvdmVyIGFsbCBvZiB0aGUgZm9sbG93aW5nIGVycm9ycy4KLQotI3ZhbGlkYXRpb24gKDMuWC40KQotCi0gICAgICAgIGN2Yy1hdHRyaWJ1dGUuMyA9IGN2Yy1hdHRyaWJ1dGUuMzogV2VydCAnJ3syfScnIGRlcyBBdHRyaWJ1dHMgJyd7MX0nJyBiZWkgRWxlbWVudCAnJ3swfScnIGhhdCBrZWluZW4gZ1x1MDBGQ2x0aWdlbiBUeXAgJyd7M30nJy4KLSAgICAgICAgY3ZjLWF0dHJpYnV0ZS40ID0gY3ZjLWF0dHJpYnV0ZS40OiBXZXJ0ICcnezJ9JycgZGVzIEF0dHJpYnV0cyAnJ3sxfScnIGJlaSBFbGVtZW50ICcnezB9JycgaGF0IGtlaW5lbiBnXHUwMEZDbHRpZ2VuIGZlc3RlbiAneyd2YWx1ZSBjb25zdHJhaW50J30nLiBBdHRyaWJ1dGUgbXVzcyBkZW4gV2VydCAnJ3szfScnIGhhYmVuLgotICAgICAgICBjdmMtY29tcGxleC10eXBlLjIuMSA9IGN2Yy1jb21wbGV4LXR5cGUuMi4xOiBFbGVtZW50ICcnezB9JycgZGFyZiBrZWluIFplaWNoZW4tIG9kZXIgRWxlbWVudGluZm9ybWF0aW9uc2VsZW1lbnQgW3VudGVyZ2VvcmRuZXRlIEVsZW1lbnRlXSBoYWJlbiwgZGEgZGVyIENvbnRlbnR0eXAgZGVzIFR5cHMgbGVlciBpc3QuCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuMi4yID0gY3ZjLWNvbXBsZXgtdHlwZS4yLjI6IEVsZW1lbnQgJyd7MH0nJyBkYXJmIGtlaW4gRWxlbWVudCBbdW50ZXJnZW9yZG5ldGUgRWxlbWVudGVdIGhhYmVuLCB1bmQgZGVyIFdlcnQgbXVzcyBnXHUwMEZDbHRpZyBzZWluLgotICAgICAgICBjdmMtY29tcGxleC10eXBlLjIuMyA9IGN2Yy1jb21wbGV4LXR5cGUuMi4zOiBFbGVtZW50ICcnezB9JycgZGFyZiBrZWluZSBaZWljaGVuIFt1bnRlcmdlb3JkbmV0ZSBFbGVtZW50ZV0gaGFiZW4sIGRhIGRlciBDb250ZW50dHlwIGRlcyBUeXBzICcnZWxlbWVudC1vbmx5JycgaXN0LgotICAgICAgICBjdmMtY29tcGxleC10eXBlLjIuNC5hID0gY3ZjLWNvbXBsZXgtdHlwZS4yLjQuYTogVW5nXHUwMEZDbHRpZ2VyIENvbnRlbnQgd3VyZGUgYmVnaW5uZW5kIG1pdCBFbGVtZW50ICcnezB9JycgZ2VmdW5kZW4uICcnezF9Jycgd2lyZCBlcndhcnRldC4KLSAgICAgICAgY3ZjLWNvbXBsZXgtdHlwZS4yLjQuYiA9IGN2Yy1jb21wbGV4LXR5cGUuMi40LmI6IENvbnRlbnQgZGVzIEVsZW1lbnRzICcnezB9JycgaXN0IG5pY2h0IHZvbGxzdFx1MDBFNG5kaWcuICcnezF9Jycgd2lyZCBlcndhcnRldC4KLSAgICAgICAgY3ZjLWNvbXBsZXgtdHlwZS4yLjQuYyA9IGN2Yy1jb21wbGV4LXR5cGUuMi40LmM6IFx1MDBEQ2JlcmVpbnN0aW1tdW5nc3BsYXR6aGFsdGVyIGlzdCBzdHJlbmcsIGFiZXIgZXMga2FubiBrZWluZSBEZWtsYXJhdGlvbiBmXHUwMEZDciBFbGVtZW50ICcnezB9JycgZ2VmdW5kZW4gd2VyZGVuLgotICAgICAgICBjdmMtY29tcGxleC10eXBlLjIuNC5kID0gY3ZjLWNvbXBsZXgtdHlwZS4yLjQuZDogVW5nXHUwMEZDbHRpZ2VyIENvbnRlbnQgd3VyZGUgYmVnaW5uZW5kIG1pdCBFbGVtZW50ICcnezB9JycgZ2VmdW5kZW4uIEFuIGRpZXNlciBTdGVsbGUgd2lyZCBrZWluIHVudGVyZ2VvcmRuZXRlcyBFbGVtZW50IGVyd2FydGV0LgotICAgICAgICBjdmMtY29tcGxleC10eXBlLjIuNC5lID0gY3ZjLWNvbXBsZXgtdHlwZS4yLjQuZDogVW5nXHUwMEZDbHRpZ2VyIENvbnRlbnQgd3VyZGUgYmVnaW5uZW5kIG1pdCBFbGVtZW50ICcnezB9JycgZ2VmdW5kZW4uIEFuIGRpZXNlciBTdGVsbGUgd2lyZCBrZWluIHVudGVyZ2VvcmRuZXRlcyBFbGVtZW50ICcnezF9JycgZXJ3YXJ0ZXQuCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuMy4xID0gY3ZjLWNvbXBsZXgtdHlwZS4zLjE6IFdlcnQgJyd7Mn0nJyBkZXMgQXR0cmlidXRzICcnezF9JycgZGVzIEVsZW1lbnRzICcnezB9JycgaXN0IHVuZ1x1MDBGQ2x0aWcgaW4gQmV6dWcgYXVmIGRpZSBlbnRzcHJlY2hlbmRlIEF0dHJpYnV0dmVyd2VuZHVuZy4gQXR0cmlidXQgJyd7MX0nJyBoYXQgZGVuIGZlc3RlbiBXZXJ0ICcnezN9JycuCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuMy4yLjEgPSBjdmMtY29tcGxleC10eXBlLjMuMi4xOiBFbGVtZW50ICcnezB9JycgaGF0IGtlaW5lbiBBdHRyaWJ1dHBsYXR6aGFsdGVyIGZcdTAwRkNyIEF0dHJpYnV0ICcnezF9JycuCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuMy4yLjIgPSBjdmMtY29tcGxleC10eXBlLjMuMi4yOiBBdHRyaWJ1dCAnJ3sxfScnIGRhcmYgbmljaHQgaW4gRWxlbWVudCAnJ3swfScnIHZvcmtvbW1lbi4KLSAgICAgICAgY3ZjLWNvbXBsZXgtdHlwZS40ID0gY3ZjLWNvbXBsZXgtdHlwZS40OiBBdHRyaWJ1dCAnJ3sxfScnIG11c3MgaW4gRWxlbWVudCAnJ3swfScnIHZvcmtvbW1lbi4KLSAgICAgICAgY3ZjLWNvbXBsZXgtdHlwZS41LjEgPSBjdmMtY29tcGxleC10eXBlLjUuMTogSW4gRWxlbWVudCAnJ3swfScnIGlzdCBBdHRyaWJ1dCAnJ3sxfScnIGVpbiBQbGF0emhhbHRlci4gRXMgaXN0IGFiZXIgYmVyZWl0cyBlaW4gUGxhdHpoYWx0ZXIgJyd7Mn0nJyB2b3JoYW5kZW4uIE51ciBlaW4gUGxhdHpoYWx0ZXIgaXN0IHp1bFx1MDBFNHNzaWcuCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuNS4yID0gY3ZjLWNvbXBsZXgtdHlwZS41LjI6IEluIEVsZW1lbnQgJyd7MH0nJyBpc3QgQXR0cmlidXQgJyd7MX0nJyBlaW4gUGxhdHpoYWx0ZXIuIEVzIGlzdCBhYmVyIGJlcmVpdHMgZWluIEF0dHJpYnV0ICcnezJ9Jycgdm9yaGFuZGVuLCBkYXMgdm9uIGVpbmVyIElEIHVudGVyIGRlbiAneydhdHRyaWJ1dGUgdXNlcyd9JyBhYmdlbGVpdGV0IHd1cmRlLgotICAgICAgICBjdmMtZGF0YXR5cGUtdmFsaWQuMS4yLjEgPSBjdmMtZGF0YXR5cGUtdmFsaWQuMS4yLjE6ICcnezB9JycgaXN0IGtlaW4gZ1x1MDBGQ2x0aWdlciBXZXJ0IGZcdTAwRkNyICcnezF9JycuCi0gICAgICAgIGN2Yy1kYXRhdHlwZS12YWxpZC4xLjIuMiA9IGN2Yy1kYXRhdHlwZS12YWxpZC4xLjIuMjogJyd7MH0nJyBpc3Qga2VpbiBnXHUwMEZDbHRpZ2VyIFdlcnQgZGVzIExpc3RlbnR5cHMgJyd7MX0nJy4KLSAgICAgICAgY3ZjLWRhdGF0eXBlLXZhbGlkLjEuMi4zID0gY3ZjLWRhdGF0eXBlLXZhbGlkLjEuMi4zOiAnJ3swfScnIGlzdCBrZWluIGdcdTAwRkNsdGlnZXIgV2VydCBkZXMgVmVyZWluaWd1bmdzbWVuZ2VudHlwcyAnJ3sxfScnLgotICAgICAgICBjdmMtZWx0LjEgPSBjdmMtZWx0LjE6IERla2xhcmF0aW9uIGRlcyBFbGVtZW50cyAnJ3swfScnIGthbm4gbmljaHQgZ2VmdW5kZW4gd2VyZGVuLgotICAgICAgICBjdmMtZWx0LjIgPSBjdmMtZWx0LjI6IFdlcnQgdm9uICd7J2Fic3RyYWN0J30nIGluIGRlciBFbGVtZW50ZGVrbGFyYXRpb24gZlx1MDBGQ3IgJyd7MH0nJyBtdXNzICcnZmFsc2UnJyBzZWluLgotICAgICAgICBjdmMtZWx0LjMuMSA9IGN2Yy1lbHQuMy4xOiBBdHRyaWJ1dCAnJ3sxfScnIGRhcmYgbmljaHQgaW4gRWxlbWVudCAnJ3swfScnIHZvcmtvbW1lbiwgZGEgZGllIGRpZSBFaWdlbnNjaGFmdCAneyduaWxsYWJsZSd9JyB2b24gJyd7MH0nJyAnJ2ZhbHNlJycgaXN0LgotICAgICAgICBjdmMtZWx0LjMuMi4xID0gY3ZjLWVsdC4zLjIuMTogRWxlbWVudCAnJ3swfScnIGRhcmYga2VpbmUgWmVpY2hlbi0gb2RlciBFbGVtZW50aW5mb3JtYXRpb25lbiBbdW50ZXJnZW9yZG5ldGUgRWxlbWVudGVdIGhhYmVuLCBkYSAnJ3sxfScnIGFuZ2VnZWJlbiB3dXJkZS4KLSAgICAgICAgY3ZjLWVsdC4zLjIuMiA9IGN2Yy1lbHQuMy4yLjI6IEVzIGRhcmYga2VpbiBmZXN0ZXIgJ3sndmFsdWUgY29uc3RyYWludCd9JyBmXHUwMEZDciBFbGVtZW50ICcnezB9Jycgdm9yaGFuZGVuIHNlaW4sIGRhICcnezF9JycgYW5nZWdlYmVuIHd1cmRlLgotICAgICAgICBjdmMtZWx0LjQuMSA9IGN2Yy1lbHQuNC4xOiBXZXJ0ICcnezJ9JycgZGVzIEF0dHJpYnV0cyAnJ3sxfScnIHZvbiBFbGVtZW50ICcnezB9JycgaXN0IGtlaW4gZ1x1MDBGQ2x0aWdlciBRTmFtZS4KLSAgICAgICAgY3ZjLWVsdC40LjIgPSBjdmMtZWx0LjQuMjogJyd7MX0nJyBrYW5uIG5pY2h0IGFscyBUeXBkZWZpbml0aW9uIGZcdTAwRkNyIEVsZW1lbnQgJyd7MH0nJyBhdWZnZWxcdTAwRjZzdCB3ZXJkZW4uCi0gICAgICAgIGN2Yy1lbHQuNC4zID0gY3ZjLWVsdC40LjM6IFR5cCAnJ3sxfScnIHd1cmRlIG5pY2h0IGF1ZiBnXHUwMEZDbHRpZ2UgV2Vpc2Ugdm9uIGRlciBUeXBkZWZpbml0aW9uICcnezJ9JycgZGVzIEVsZW1lbnRzICcnezB9JycgYWJnZWxlaXRldC4KLSAgICAgICAgY3ZjLWVsdC41LjEuMSA9IGN2Yy1lbHQuNS4xLjE6ICd7J3ZhbHVlIGNvbnN0cmFpbnQnfScgJyd7Mn0nJyBkZXMgRWxlbWVudHMgJyd7MH0nJyBpc3Qga2VpbiBnXHUwMEZDbHRpZ2VyIFN0YW5kYXJkd2VydCBmXHUwMEZDciBUeXAgJyd7MX0nJy4KLSAgICAgICAgY3ZjLWVsdC41LjIuMi4xID0gY3ZjLWVsdC41LjIuMi4xOiBFbGVtZW50ICcnezB9JycgZGFyZiBrZWluZSBFbGVtZW50aW5mb3JtYXRpb25zZWxlbWVudGUgW3VudGVyZ2VvcmRuZXRlIEVsZW1lbnRlXSBoYWJlbi4KLSAgICAgICAgY3ZjLWVsdC41LjIuMi4yLjEgPSBjdmMtZWx0LjUuMi4yLjIuMTogV2VydCAnJ3sxfScnIGRlcyBFbGVtZW50cyAnJ3swfScnIHN0aW1tdCBuaWNodCBtaXQgZGVtIGZlc3RlbiAneyd2YWx1ZSBjb25zdHJhaW50J30nLVdlcnQgJyd7Mn0nJyBcdTAwRkNiZXJlaW4uCi0gICAgICAgIGN2Yy1lbHQuNS4yLjIuMi4yID0gY3ZjLWVsdC41LjIuMi4yLjI6IFdlcnQgJyd7MX0nJyBkZXMgRWxlbWVudHMgJyd7MH0nJyBzdGltbXQgbmljaHQgbWl0IGRlbSAneyd2YWx1ZSBjb25zdHJhaW50J30nLVdlcnQgJyd7Mn0nJyBcdTAwRkNiZXJlaW4uCi0gICAgICAgIGN2Yy1lbnVtZXJhdGlvbi12YWxpZCA9IGN2Yy1lbnVtZXJhdGlvbi12YWxpZDogV2VydCAnJ3swfScnIGlzdCBuaWNodCBGYWNldC1nXHUwMEZDbHRpZyBpbiBCZXp1ZyBhdWYgRW51bWVyYXRpb24gJyd7MX0nJy4gRXIgbXVzcyBlaW4gV2VydCBhdXMgZGVyIEVudW1lcmF0aW9uIHNlaW4uCi0gICAgICAgIGN2Yy1mcmFjdGlvbkRpZ2l0cy12YWxpZCA9IGN2Yy1mcmFjdGlvbkRpZ2l0cy12YWxpZDogV2VydCAnJ3swfScnIGVudGhcdTAwRTRsdCB7MX0gQnJ1Y2h6aWZmZXJuLCBkaWUgQW56YWhsIGFuIEJydWNoemlmZmVybiB3dXJkZSBhYmVyIGF1ZiB7Mn0gYmVzY2hyXHUwMEU0bmt0LgotICAgICAgICBjdmMtaWQuMSA9IGN2Yy1pZC4xOiBLZWluIElEL0lEUkVGLUJpbmRpbmcgZlx1MDBGQ3IgSURSRUYgJyd7MH0nJyB2b3JoYW5kZW4uCi0gICAgICAgIGN2Yy1pZC4yID0gY3ZjLWlkLjI6IElELVdlcnQgJyd7MH0nJyBrb21tdCBtZWhybWFscyB2b3IuCi0gICAgICAgIGN2Yy1pZC4zID0gY3ZjLWlkLjM6IEVpbiBGZWxkIHZvbiBJZGVudGl0eSBDb25zdHJhaW50ICcnezB9JycgZW50c3ByYWNoIEVsZW1lbnQgJyd7MX0nJy4gRGllc2VzIEVsZW1lbnQgaGF0IGFiZXIga2VpbmVuIFNpbXBsZSBUeXBlLgotICAgICAgICBjdmMtbGVuZ3RoLXZhbGlkID0gY3ZjLWxlbmd0aC12YWxpZDogV2VydCAnJ3swfScnIG1pdCBMXHUwMEU0bmdlID0gJyd7MX0nJyBpc3QgbmljaHQgRmFjZXQtZ1x1MDBGQ2x0aWcgaW4gQmV6dWcgYXVmIGRpZSBMXHUwMEU0bmdlICcnezJ9JycgZlx1MDBGQ3IgVHlwICcnezN9JycuCi0gICAgICAgIGN2Yy1tYXhFeGNsdXNpdmUtdmFsaWQgPSBjdmMtbWF4RXhjbHVzaXZlLXZhbGlkOiBXZXJ0ICcnezB9JycgaXN0IG5pY2h0IEZhY2V0LWdcdTAwRkNsdGlnIGluIEJlenVnIGF1ZiBtYXhFeGNsdXNpdmUgJyd7MX0nJyBmXHUwMEZDciBUeXAgJyd7Mn0nJy4KLSAgICAgICAgY3ZjLW1heEluY2x1c2l2ZS12YWxpZCA9IGN2Yy1tYXhJbmNsdXNpdmUtdmFsaWQ6IFdlcnQgJyd7MH0nJyBpc3QgbmljaHQgRmFjZXQtZ1x1MDBGQ2x0aWcgaW4gQmV6dWcgYXVmIG1heEluY2x1c2l2ZSAnJ3sxfScnIGZcdTAwRkNyIFR5cCAnJ3syfScnLgotICAgICAgICBjdmMtbWF4TGVuZ3RoLXZhbGlkID0gY3ZjLW1heExlbmd0aC12YWxpZDogV2VydCAnJ3swfScnIG1pdCBMXHUwMEU0bmdlID0gJyd7MX0nJyBpc3QgbmljaHQgRmFjZXQtZ1x1MDBGQ2x0aWcgaW4gQmV6dWcgYXVmIG1heExlbmd0aCAnJ3syfScnIGZcdTAwRkNyIFR5cCAnJ3szfScnLgotICAgICAgICBjdmMtbWluRXhjbHVzaXZlLXZhbGlkID0gY3ZjLW1pbkV4Y2x1c2l2ZS12YWxpZDogV2VydCAnJ3swfScnIGlzdCBuaWNodCBGYWNldC1nXHUwMEZDbHRpZyBpbiBCZXp1ZyBhdWYgbWluRXhjbHVzaXZlICcnezF9JycgZlx1MDBGQ3IgVHlwICcnezJ9JycuCi0gICAgICAgIGN2Yy1taW5JbmNsdXNpdmUtdmFsaWQgPSBjdmMtbWluSW5jbHVzaXZlLXZhbGlkOiBXZXJ0ICcnezB9JycgaXN0IG5pY2h0IEZhY2V0LWdcdTAwRkNsdGlnIGluIEJlenVnIGF1ZiBtaW5JbmNsdXNpdmUgJyd7MX0nJyBmXHUwMEZDciBUeXAgJyd7Mn0nJy4KLSAgICAgICAgY3ZjLW1pbkxlbmd0aC12YWxpZCA9IGN2Yy1taW5MZW5ndGgtdmFsaWQ6IFdlcnQgJyd7MH0nJyBtaXQgTFx1MDBFNG5nZSA9ICcnezF9JycgaXN0IG5pY2h0IEZhY2V0LWdcdTAwRkNsdGlnIGluIEJlenVnIGF1ZiBtaW5MZW5ndGggJyd7Mn0nJyBmXHUwMEZDciBUeXAgJyd7M30nJy4KLSAgICAgICAgY3ZjLXBhdHRlcm4tdmFsaWQgPSBjdmMtcGF0dGVybi12YWxpZDogV2VydCAnJ3swfScnIGlzdCBuaWNodCBGYWNldC1nXHUwMEZDbHRpZyBpbiBCZXp1ZyBhdWYgTXVzdGVyICcnezF9JycgZlx1MDBGQ3IgVHlwICcnezJ9JycuCi0gICAgICAgIGN2Yy10b3RhbERpZ2l0cy12YWxpZCA9IGN2Yy10b3RhbERpZ2l0cy12YWxpZDogV2VydCAnJ3swfScnIGVudGhcdTAwRTRsdCB7MX0gR2VzYW10emlmZmVybiwgZGllIEFuemFobCBhbiBHZXNhbXR6aWZmZXJuIHd1cmRlIGFiZXIgYXVmIHsyfSBiZXNjaHJcdTAwRTRua3QuCi0gICAgICAgIGN2Yy10eXBlLjIgPSBjdmMtdHlwZS4yOiBUeXBkZWZpbml0aW9uIGthbm4gbmljaHQgYWJzdHJha3QgZlx1MDBGQ3IgRWxlbWVudCB7MH0gc2Vpbi4KLSAgICAgICAgY3ZjLXR5cGUuMy4xLjEgPSBjdmMtdHlwZS4zLjEuMTogRWxlbWVudCAnJ3swfScnIGlzdCBTaW1wbGUgVHlwZSB1bmQga2FubiBkYWhlciBrZWluZSBBdHRyaWJ1dGUgaGFiZW4sIG1pdCBBdXNuYWhtZSBkZXIgQXR0cmlidXRlLCBkZXJlbiBOYW1lc3BhY2UtTmFtZSBtaXQgJydodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZScnIGlkZW50aXNjaCBpc3QgdW5kIGRlcmVuIFtsb2thbGVyIE5hbWVdICcndHlwZScnLCAnJ25pbCcnLCAnJ3NjaGVtYUxvY2F0aW9uJycgb2RlciAnJ25vTmFtZXNwYWNlU2NoZW1hTG9jYXRpb24nJyBsYXV0ZXQuIEVzIHd1cmRlIGFsbGVyZGluZ3MgZGFzIEF0dHJpYnV0ICcnezF9JycgZ2VmdW5kZW4uCi0gICAgICAgIGN2Yy10eXBlLjMuMS4yID0gY3ZjLXR5cGUuMy4xLjI6IEVsZW1lbnQgJyd7MH0nJyBpc3QgU2ltcGxlIFR5cGUgdW5kIGRhcmYgZGFoZXIga2VpbmUgRWxlbWVudGluZm9ybWF0aW9uc2VsZW1lbnRlIFt1bnRlcmdlb3JkbmV0ZSBFbGVtZW50ZV0gaGFiZW4uCi0gICAgICAgIGN2Yy10eXBlLjMuMS4zID0gY3ZjLXR5cGUuMy4xLjM6IFdlcnQgJyd7MX0nJyBkZXMgRWxlbWVudHMgJyd7MH0nJyBpc3QgdW5nXHUwMEZDbHRpZy4KLQotI3NjaGVtYSB2YWxpZCAoMy5YLjMpCi0KLSAgICAgICAgc2NoZW1hX3JlZmVyZW5jZS5hY2Nlc3MgPSBzY2hlbWFfcmVmZXJlbmNlOiBTY2hlbWFkb2t1bWVudCAnJ3swfScnIGtvbm50ZSBuaWNodCBnZWxlc2VuIHdlcmRlbiwgd2VpbCBkZXIgJyd7MX0nJy1adWdyaWZmIHdlZ2VuIGRlciB2b24gZGVyIEVpZ2Vuc2NoYWZ0IGFjY2Vzc0V4dGVybmFsU2NoZW1hIGZlc3RnZWxlZ3RlbiBFaW5zY2hyXHUwMEU0bmt1bmcgbmljaHQgenVsXHUwMEU0c3NpZyBpc3QuIAotICAgICAgICBzY2hlbWFfcmVmZXJlbmNlLjQgPSBzY2hlbWFfcmVmZXJlbmNlLjQ6IFNjaGVtYWRva3VtZW50ICcnezB9Jycga29ubnRlIG5pY2h0IGdlbGVzZW4gd2VyZGVuLCBkYSAxKSBkYXMgRG9rdW1lbnQgbmljaHQgZ2VmdW5kZW4gd2VyZGVuIGtvbm50ZTsgMikgZGFzIERva3VtZW50IG5pY2h0IGdlbGVzZW4gd2VyZGVuIGtvbm50ZTsgMykgZGFzIFJvb3QtRWxlbWVudCBkZXMgRG9rdW1lbnRzIG5pY2h0IDx4c2Q6c2NoZW1hPiBpc3QuCi0gICAgICAgIHNyYy1hbm5vdGF0aW9uID0gc3JjLWFubm90YXRpb246IDxhbm5vdGF0aW9uPi1FbGVtZW50ZSBrXHUwMEY2bm5lbiBudXIgPGFwcGluZm8+LSB1bmQgPGRvY3VtZW50YXRpb24+LUVsZW1lbnRlIGVudGhhbHRlbiwgYWJlciBlcyB3dXJkZSAnJ3swfScnIGdlZnVuZGVuLgotICAgICAgICBzcmMtYXR0cmlidXRlLjEgPSBzcmMtYXR0cmlidXRlLjE6IERpZSBFaWdlbnNjaGFmdGVuICcnZGVmYXVsdCcnIHVuZCAnJ2ZpeGVkJycga1x1MDBGNm5uZW4gbmljaHQgYmVpZGUgaW4gZGVyIEF0dHJpYnV0ZGVrbGFyYXRpb24gJyd7MH0nJyB2b3JoYW5kZW4gc2Vpbi4gVmVyd2VuZGVuIFNpZSBudXIgZWluZSBkaWVzZXIgRWlnZW5zY2hhZnRlbi4KLSAgICAgICAgc3JjLWF0dHJpYnV0ZS4yID0gc3JjLWF0dHJpYnV0ZS4yOiA6IEVpZ2Vuc2NoYWZ0ICcnZGVmYXVsdCcnIGlzdCBpbSBBdHRyaWJ1dCAnJ3swfScnIHZvcmhhbmRlbi4gRGFoZXIgbXVzcyBkZXIgV2VydCB2b24gJyd1c2UnJyAnJ29wdGlvbmFsJycgbGF1dGVuLgotICAgICAgICBzcmMtYXR0cmlidXRlLjMuMSA9IHNyYy1hdHRyaWJ1dGUuMy4xOiAncmVmJyBvZGVyICduYW1lJyBtdXNzIGluIGVpbmVyIGxva2FsZW4gQXR0cmlidXRkZWtsYXJhdGlvbiB2b3JoYW5kZW4gc2Vpbi4KLSAgICAgICAgc3JjLWF0dHJpYnV0ZS4zLjIgPSBzcmMtYXR0cmlidXRlLjMuMjogQ29udGVudCBtdXNzIG1pdCAoYW5ub3RhdGlvbj8pIGZcdTAwRkNyIGRpZSBBdHRyaWJ1dHJlZmVyZW56ICcnezB9JycgXHUwMEZDYmVyZWluc3RpbW1lbi4KLSAgICAgICAgc3JjLWF0dHJpYnV0ZS40ID0gc3JjLWF0dHJpYnV0ZS40OiBBdHRyaWJ1dCAnJ3swfScnIGhhdCBzb3dvaGwgZGFzIEF0dHJpYnV0ICcndHlwZScnIGFscyBhdWNoIGVpbiBhbm9ueW1lcyB1bnRlcmdlb3JkbmV0ZXMgRWxlbWVudCAnJ3NpbXBsZVR5cGUnJy4gTnVyIGVpbnMgZGF2b24gaXN0IGZcdTAwRkNyIEF0dHJpYnV0ZSB6dWxcdTAwRTRzc2lnLgotICAgICAgICBzcmMtYXR0cmlidXRlX2dyb3VwLjIgPSBzcmMtYXR0cmlidXRlX2dyb3VwLjI6IFNjaG5pdHRtZW5nZSB2b24gUGxhdHpoYWx0ZXJuIGthbm4gbmljaHQgZlx1MDBGQ3IgQXR0cmlidXRncnVwcGUgJyd7MH0nJyBhdXNnZWRyXHUwMEZDY2t0IHdlcmRlbi4KLSAgICAgICAgc3JjLWF0dHJpYnV0ZV9ncm91cC4zID0gc3JjLWF0dHJpYnV0ZV9ncm91cC4zOiBaeWtsaXNjaGUgRGVmaW5pdGlvbmVuIGZcdTAwRkNyIEF0dHJpYnV0Z3J1cHBlICcnezB9JycgZXJtaXR0ZWx0LiBEYXMgcmVrdXJzaXZlIEZvbGdlbiB2b24gQXR0cmlidXRncnVwcGVucmVmZXJlbnplbiBmXHUwMEZDaHJ0IHNjaGxpZVx1MDBERmxpY2ggenUgc2ljaCBzZWxic3QgenVyXHUwMEZDY2suCi0gICAgICAgIHNyYy1jdC4xID0gc3JjLWN0LjE6IERhcnN0ZWxsdW5nc2ZlaGxlciBiZWkgQ29tcGxleCBUeXBlLURlZmluaXRpb24gZlx1MDBGQ3IgVHlwICcnezB9JycuIFdlbm4gPGNvbXBsZXhDb250ZW50PiB2ZXJ3ZW5kZXQgd2lyZCwgbXVzcyBkZXIgQmFzaXN0eXAgZWluIGNvbXBsZXhUeXBlIHNlaW4uICcnezF9JycgaXN0IGVpbiBzaW1wbGVUeXBlLgotICAgICAgICBzcmMtY3QuMi4xID0gc3JjLWN0LjIuMTogRGFyc3RlbGx1bmdzZmVobGVyIGJlaSBDb21wbGV4IFR5cGUtRGVmaW5pdGlvbiBmXHUwMEZDciBUeXAgJyd7MH0nJy4gV2VubiA8c2ltcGxlQ29udGVudD4gdmVyd2VuZGV0IHdpcmQsIG11c3MgZGVyIEJhc2lzdHlwIGVpbiBjb21wbGV4VHlwZSBzZWluLCBkZXNzZW4gQ29udGVudHR5cCAnJ3NpbXBsZScnIGlzdCwgb2Rlciwgd2VubiBlaW5lIEVpbnNjaHJcdTAwRTRua3VuZyBhbmdlZ2ViZW4gd3VyZGUsIGVpbiAnJ2NvbXBsZXgnJy1UeXAgbWl0IGdlbWlzY2h0ZW0gQ29udGVudCB1bmQgZWluZW0gUGFydGlrZWwsIGRhcyBnZWxlZXJ0IHdlcmRlbiBrYW5uLCBvZGVyLCB3ZW5uIGVpbmUgRXJ3ZWl0ZXJ1bmcgYW5nZWdlYmVuIHd1cmRlLCBlaW4gJydzaW1wbGUnJy1UeXAuICcnezF9JycgZXJmXHUwMEZDbGx0IGtlaW5lIGRpZXNlciBCZWRpbmd1bmdlbi4KLSAgICAgICAgc3JjLWN0LjIuMiA9IHNyYy1jdC4yLjI6IERhcnN0ZWxsdW5nc2ZlaGxlciBiZWkgQ29tcGxleCBUeXBlLURlZmluaXRpb24gZlx1MDBGQ3IgVHlwICcnezB9JycuIFdlbm4gZWluIGNvbXBsZXhUeXBlIG1pdCBzaW1wbGVDb250ZW50IGVpbmVuIGNvbXBsZXhUeXBlIG1pdCBnZW1pc2NodGVtIENvbnRlbnQgdW5kIGVpbmVtIFBhcnRpa2VsLCBkYXMgZ2VsZWVydCB3ZXJkZW4ga2FubiwgZWluc2Noclx1MDBFNG5rdCwgbXVzcyBlaW4gPHNpbXBsZVR5cGU+IGluIGRlbiB1bnRlcmdlb3JkbmV0ZW4gRWxlbWVudGVuIHZvbiA8cmVzdHJpY3Rpb24+IGVudGhhbHRlbiBzZWluLgotICAgICAgICBzcmMtY3QuNCA9IHNyYy1jdC40OiBEYXJzdGVsbHVuZ3NmZWhsZXIgYmVpIENvbXBsZXggVHlwZS1EZWZpbml0aW9uIGZcdTAwRkNyIFR5cCAnJ3swfScnLiBEaWUgU2Nobml0dG1lbmdlIGRlciBQbGF0emhhbHRlciBrYW5uIG5pY2h0IGF1c2dlZHJcdTAwRkNja3Qgd2VyZGVuLgotICAgICAgICBzcmMtY3QuNSA9IHNyYy1jdC41OiBEYXJzdGVsbHVuZ3NmZWhsZXIgYmVpIENvbXBsZXggVHlwZS1EZWZpbml0aW9uIGZcdTAwRkNyIFR5cCAnJ3swfScnLiBEaWUgVmVyZWluaWd1bmdzbWVuZ2UgZGVyIFBsYXR6aGFsdGVyIGthbm4gbmljaHQgYXVzZ2Vkclx1MDBGQ2NrdCB3ZXJkZW4uCi0gICAgICAgIHNyYy1lbGVtZW50LjEgPSBzcmMtZWxlbWVudC4xOiBEaWUgRWlnZW5zY2hhZnRlbiAnJ2RlZmF1bHQnJyB1bmQgJydmaXhlZCcnIGtcdTAwRjZubmVuIG5pY2h0IGJlaWRlIGluIGRlciBFbGVtZW50ZGVrbGFyYXRpb24gJyd7MH0nJyB2b3JoYW5kZW4gc2Vpbi4gVmVyd2VuZGVuIFNpZSBudXIgZWluZSBkaWVzZXIgRWlnZW5zY2hhZnRlbi4KLSAgICAgICAgc3JjLWVsZW1lbnQuMi4xID0gc3JjLWVsZW1lbnQuMi4xOiA6ICdyZWYnIG9kZXIgJ25hbWUnIG11c3MgaW4gZWluZXIgbG9rYWxlbiBFbGVtZW50ZGVrbGFyYXRpb24gdm9yaGFuZGVuIHNlaW4uCi0gICAgICAgIHNyYy1lbGVtZW50LjIuMiA9IHNyYy1lbGVtZW50LjIuMjogRGEgJyd7MH0nJyBkYXMgQXR0cmlidXQgJydyZWYnJyBlbnRoXHUwMEU0bHQsIG11c3MgZGVyIENvbnRlbnQgKGFubm90YXRpb24/KSBlbnRzcHJlY2hlbi4gRXMgd3VyZGUgYWxsZXJkaW5ncyAnJ3sxfScnIGdlZnVuZGVuLgotICAgICAgICBzcmMtZWxlbWVudC4zID0gc3JjLWVsZW1lbnQuMzogRWxlbWVudCAnJ3swfScnIGhhdCBzb3dvaGwgZGFzIEF0dHJpYnV0ICcndHlwZScnIGFscyBhdWNoIGVpbiB1bnRlcmdlb3JkbmV0ZXMgRWxlbWVudCAnJ2Fub255bW91cyB0eXBlJycuIE51ciBlaW5zIGRhdm9uIGlzdCBmXHUwMEZDciBFbGVtZW50ZSB6dWxcdTAwRTRzc2lnLgotICAgICAgICBzcmMtaW1wb3J0LjEuMSA9IHNyYy1pbXBvcnQuMS4xOiBOYW1lc3BhY2UtQXR0cmlidXQgJyd7MH0nJyBlaW5lcyA8aW1wb3J0Pi1FbGVtZW50aW5mb3JtYXRpb25zZWxlbWVudHMgZGFyZiBuaWNodCBtaXQgZGVtIHRhcmdldE5hbWVzcGFjZSBkZXMgU2NoZW1hcyBpZGVudGlzY2ggc2VpbiwgaW4gZGVtIGVzIHZvcmhhbmRlbiBpc3QuCi0gICAgICAgIHNyYy1pbXBvcnQuMS4yID0gc3JjLWltcG9ydC4xLjI6IFdlbm4gZGFzIE5hbWVzcGFjZS1BdHRyaWJ1dCBuaWNodCBiZWkgZWluZW0gPGltcG9ydD4tRWxlbWVudGluZm9ybWF0aW9uc2VsZW1lbnQgdm9yaGFuZGVuIGlzdCwgbXVzcyBkYXMgZWluc2NobGllXHUwMERGZW5kZSBTY2hlbWEgZWluZW4gdGFyZ2V0TmFtZXNwYWNlIGhhYmVuLgotICAgICAgICBzcmMtaW1wb3J0LjIgPSBzcmMtaW1wb3J0LjI6IERhcyBSb290LUVsZW1lbnQgZGVzIERva3VtZW50cyAnJ3swfScnIG11c3MgZGVuIE5hbWVzcGFjZS1OYW1lbiAnJ2h0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hJycgdW5kIGRlbiBsb2thbGVuIE5hbWVuICcnc2NoZW1hJycgaGFiZW4uCi0gICAgICAgIHNyYy1pbXBvcnQuMy4xID0gc3JjLWltcG9ydC4zLjE6IE5hbWVzcGFjZS1BdHRyaWJ1dCAnJ3swfScnIGVpbmVzIDxpbXBvcnQ+LUVsZW1lbnRpbmZvcm1hdGlvbnNlbGVtZW50cyBtdXNzIG1pdCBkZW0gdGFyZ2V0TmFtZXNwYWNlLUF0dHJpYnV0ICcnezF9JycgZGVzIGltcG9ydGllcnRlbiBEb2t1bWVudHMgaWRlbnRpc2NoIHNlaW4uCi0gICAgICAgIHNyYy1pbXBvcnQuMy4yID0gc3JjLWltcG9ydC4zLjI6IEVzIHd1cmRlIGVpbiA8aW1wb3J0Pi1FbGVtZW50aW5mb3JtYXRpb25zZWxlbWVudCBvaG5lIE5hbWVzcGFjZS1BdHRyaWJ1dCBnZWZ1bmRlbi4gRGFoZXIga2FubiBkYXMgaW1wb3J0aWVydGUgRG9rdW1lbnQga2VpbiB0YXJnZXROYW1lc3BhY2UtQXR0cmlidXQgaGFiZW4uIHRhcmdldE5hbWVzcGFjZSAnJ3sxfScnIHd1cmRlIGFiZXIgaW0gaW1wb3J0aWVydGVuIERva3VtZW50IGdlZnVuZGVuLgotICAgICAgICBzcmMtaW5jbHVkZS4xID0gc3JjLWluY2x1ZGUuMTogRGFzIFJvb3QtRWxlbWVudCBkZXMgRG9rdW1lbnRzICcnezB9JycgbXVzcyBkZW4gTmFtZXNwYWNlLU5hbWVuICcnaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEnJyB1bmQgZGVuIGxva2FsZW4gTmFtZW4gJydzY2hlbWEnJyBoYWJlbi4KLSAgICAgICAgc3JjLWluY2x1ZGUuMi4xID0gc3JjLWluY2x1ZGUuMi4xOiB0YXJnZXROYW1lc3BhY2UgZGVzIHJlZmVyZW56aWVydGVuIFNjaGVtYXMsIGRlcnplaXQgJyd7MX0nJywgbXVzcyBtaXQgZGVtIGltIHVtZmFzc2VuZGVuIFNjaGVtYSwgZGVyemVpdCAnJ3swfScnLCBpZGVudGlzY2ggc2Vpbi4KLSAgICAgICAgc3JjLXJlZGVmaW5lLjIgPSBzcmMtcmVkZWZpbmUuMjogRGFzIFJvb3QtRWxlbWVudCBkZXMgRG9rdW1lbnRzICcnezB9JycgbXVzcyBkZW4gTmFtZXNwYWNlLU5hbWVuICcnaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEnJyB1bmQgZGVuIGxva2FsZW4gTmFtZW4gJydzY2hlbWEnJyBoYWJlbi4KLSAgICAgICAgc3JjLXJlZGVmaW5lLjMuMSA9IHNyYy1yZWRlZmluZS4zLjE6IHRhcmdldE5hbWVzcGFjZSBkZXMgcmVmZXJlbnppZXJ0ZW4gU2NoZW1hcywgZGVyemVpdCAnJ3sxfScnLCBtdXNzIG1pdCBkZW0gaW0gbmV1IGRlZmluaWVyZW5kZW4gU2NoZW1hLCBkZXJ6ZWl0ICcnezB9JycsIGlkZW50aXNjaCBzZWluLgotICAgICAgICBzcmMtcmVkZWZpbmUuNS5hLmEgPSBzcmMtcmVkZWZpbmUuNS5hLmE6IEtlaW5lIHVudGVyZ2VvcmRuZXRlbiBOaWNodC1Bbm5vdGF0aW9uc2VsZW1lbnRlIHZvbiA8c2ltcGxlVHlwZT4gZ2VmdW5kZW4uIFVudGVyZ2VvcmRuZXRlIDxzaW1wbGVUeXBlPi1FbGVtZW50ZSB2b24gPHJlZGVmaW5lPi1FbGVtZW50ZW4gbVx1MDBGQ3NzZW4gPHJlc3RyaWN0aW9uPi1OYWNoa29tbWVuIG1pdCAnYmFzZSctQXR0cmlidXRlbiBoYWJlbiwgZGllIGF1ZiBzaWNoIHNlbGJzdCB2ZXJ3ZWlzZW4uCi0gICAgICAgIHNyYy1yZWRlZmluZS41LmEuYiA9IHNyYy1yZWRlZmluZS41LmEuYjogJyd7MH0nJyBpc3Qga2VpbiBnXHUwMEZDbHRpZ2VzIHVudGVyZ2VvcmRuZXRlcyBFbGVtZW50LiBVbnRlcmdlb3JkbmV0ZSA8c2ltcGxlVHlwZT4tRWxlbWVudGUgdm9uIDxyZWRlZmluZT4tRWxlbWVudGVuIG1cdTAwRkNzc2VuIDxyZXN0cmljdGlvbj4tTmFjaGtvbW1lbiBtaXQgJydiYXNlJyctQXR0cmlidXRlbiBoYWJlbiwgZGllIGF1ZiBzaWNoIHNlbGJzdCB2ZXJ3ZWlzZW4uCi0gICAgICAgIHNyYy1yZWRlZmluZS41LmEuYyA9IHNyYy1yZWRlZmluZS41LmEuYzogJyd7MH0nJyBoYXQga2VpbiAnJ2Jhc2UnJy1BdHRyaWJ1dCwgZGFzIGF1ZiBkYXMgbmV1IGRlZmluaWVydGUgRWxlbWVudCAnJ3sxfScnIHZlcndlaXN0LiBVbnRlcmdlb3JkbmV0ZSA8c2ltcGxlVHlwZT4tRWxlbWVudGUgdm9uIDxyZWRlZmluZT4tRWxlbWVudGVuIG1cdTAwRkNzc2VuIDxyZXN0cmljdGlvbj4tTmFjaGtvbW1lbiBtaXQgJydiYXNlJyctQXR0cmlidXRlbiBoYWJlbiwgZGllIGF1ZiBzaWNoIHNlbGJzdCB2ZXJ3ZWlzZW4uCi0gICAgICAgIHNyYy1yZWRlZmluZS41LmIuYSA9IHNyYy1yZWRlZmluZS41LmIuYTogS2VpbmUgdW50ZXJnZW9yZG5ldGVuIE5pY2h0LUFubm90YXRpb25zZWxlbWVudGUgdm9uIDxjb21wbGV4VHlwZT4gZ2VmdW5kZW4uIFVudGVyZ2VvcmRuZXRlIDxjb21wbGV4VHlwZT4tRWxlbWVudGUgdm9uIDxyZWRlZmluZT4tRWxlbWVudGVuIG1cdTAwRkNzc2VuIDxleHRlbnNpb24+LSBvZGVyIDxyZXN0cmljdGlvbj4tTmFjaGtvbW1lbiBtaXQgJ2Jhc2UnLUF0dHJpYnV0ZW4gaGFiZW4sIGRpZSBhdWYgc2ljaCBzZWxic3QgdmVyd2Vpc2VuLgotICAgICAgICBzcmMtcmVkZWZpbmUuNS5iLmIgPSBzcmMtcmVkZWZpbmUuNS5iLmI6IEtlaW5lIHVudGVyZ2VvcmRuZXRlbiBOaWNodC1Bbm5vdGF0aW9uc2VsZW1lbnRlIGRlciB6d2VpdGVuIEdlbmVyYXRpb24gdm9uIDxjb21wbGV4VHlwZT4gZ2VmdW5kZW4uIFVudGVyZ2VvcmRuZXRlIDxjb21wbGV4VHlwZT4tRWxlbWVudGUgdm9uIDxyZWRlZmluZT4tRWxlbWVudGVuIG1cdTAwRkNzc2VuIDxleHRlbnNpb24+LSBvZGVyIDxyZXN0cmljdGlvbj4tTmFjaGtvbW1lbiBtaXQgJ2Jhc2UnLUF0dHJpYnV0ZW4gaGFiZW4sIGRpZSBhdWYgc2ljaCBzZWxic3QgdmVyd2Vpc2VuLgotICAgICAgICBzcmMtcmVkZWZpbmUuNS5iLmMgPSBzcmMtcmVkZWZpbmUuNS5iLmM6ICcnezB9JycgaXN0IGtlaW4gZ1x1MDBGQ2x0aWdlcyB1bnRlcmdlb3JkbmV0ZXMgRWxlbWVudCBkZXIgendlaXRlbiBHZW5lcmF0aW9uLiBVbnRlcmdlb3JkbmV0ZSA8Y29tcGxleFR5cGU+LUVsZW1lbnRlIHZvbiA8cmVkZWZpbmU+LUVsZW1lbnRlbiBtXHUwMEZDc3NlbiA8ZXh0ZW5zaW9uPi0gb2RlciA8cmVzdHJpY3Rpb24+LU5hY2hrb21tZW4gbWl0ICcnYmFzZScnLUF0dHJpYnV0ZW4gaGFiZW4sIGRpZSBhdWYgc2ljaCBzZWxic3QgdmVyd2Vpc2VuLgotICAgICAgICBzcmMtcmVkZWZpbmUuNS5iLmQgPSBzcmMtcmVkZWZpbmUuNS5iLmQ6ICcnezB9JycgaGF0IGtlaW4gJydiYXNlJyctQXR0cmlidXQsIGRhcyBhdWYgZGFzIG5ldSBkZWZpbmllcnRlIEVsZW1lbnQgJyd7MX0nJyB2ZXJ3ZWlzdC4gVW50ZXJnZW9yZG5ldGUgPGNvbXBsZXhUeXBlPi1FbGVtZW50ZSB2b24gPHJlZGVmaW5lPi1FbGVtZW50ZW4gbVx1MDBGQ3NzZW4gPGV4dGVuc2lvbj4tIG9kZXIgPHJlc3RyaWN0aW9uPi1OYWNoa29tbWVuIG1pdCAnJ2Jhc2UnJy1BdHRyaWJ1dGVuIGhhYmVuLCBkaWUgYXVmIHNpY2ggc2VsYnN0IHZlcndlaXNlbi4KLSAgICAgICAgc3JjLXJlZGVmaW5lLjYuMS4xID0gc3JjLXJlZGVmaW5lLjYuMS4xOiBXZW5uIGVpbiB1bnRlcmdlb3JkbmV0ZXMgR3J1cHBlbmVsZW1lbnQgZWluZXMgPHJlZGVmaW5lPi1FbGVtZW50cyBlaW5lIEdydXBwZSBlbnRoXHUwMEU0bHQsIGRpZSBhdWYgc2ljaCBzZWxic3QgdmVyd2Vpc3QsIG11c3MgZ2VuYXUgMSB2b3JoYW5kZW4gc2Vpbi4gSGllciBzaW5kICcnezB9Jycgdm9yaGFuZGVuLgotICAgICAgICBzcmMtcmVkZWZpbmUuNi4xLjIgPSBzcmMtcmVkZWZpbmUuNi4xLjI6IEJlaSBHcnVwcGUgJyd7MH0nJywgZGllIGVpbmUgUmVmZXJlbnogenUgZWluZXIgR3J1cHBlIGVudGhcdTAwRTRsdCwgZGllIG5ldSBkZWZpbmllcnQgd2lyZCwgbXVzcyAnJ21pbk9jY3VycycnID0gJydtYXhPY2N1cnMnJyA9IDEgZ2VsdGVuLgotICAgICAgICBzcmMtcmVkZWZpbmUuNi4yLjEgPSBzcmMtcmVkZWZpbmUuNi4yLjE6IEtlaW5lIEdydXBwZSBpbSBuZXUgZGVmaW5pZXJ0ZW4gU2NoZW1hIGhhdCBlaW5lbiBOYW1lbiwgZGVyICcnezB9JycgZW50c3ByaWNodC4KLSAgICAgICAgc3JjLXJlZGVmaW5lLjYuMi4yID0gc3JjLXJlZGVmaW5lLjYuMi4yOiBHcnVwcGUgJyd7MH0nJyBzY2hyXHUwMEU0bmt0IGRpZSBHcnVwcGUsIGRpZSBuZXUgZGVmaW5pZXJ0IHdpcmQsIG5pY2h0IG9yZG51bmdzZ2VtXHUwMEU0XHUwMERGIGVpbi4gVmVybGV0enRlciBDb25zdHJhaW50OiAnJ3sxfScnLgotICAgICAgICBzcmMtcmVkZWZpbmUuNy4xID0gc3JjLXJlZGVmaW5lLjcuMTogV2VubiBlaW4gdW50ZXJnZW9yZG5ldGVzIGF0dHJpYnV0ZUdyb3VwLUVsZW1lbnQgZWluZXMgPHJlZGVmaW5lPi1FbGVtZW50cyBlaW5lIGF0dHJpYnV0ZUdyb3VwIGVudGhcdTAwRTRsdCwgZGllIGF1ZiBzaWNoIHNlbGJzdCB2ZXJ3ZWlzdCwgbXVzcyBnZW5hdSAxIHZvcmhhbmRlbiBzZWluLiBIaWVyIHNpbmQgezB9IHZvcmhhbmRlbi4KLSAgICAgICAgc3JjLXJlZGVmaW5lLjcuMi4xID0gc3JjLXJlZGVmaW5lLjcuMi4xOiBLZWluZSBhdHRyaWJ1dGVHcm91cCBpbSBuZXUgZGVmaW5pZXJ0ZW4gU2NoZW1hIGhhdCBlaW5lbiBOYW1lbiwgZGVyICcnezB9JycgZW50c3ByaWNodC4KLSAgICAgICAgc3JjLXJlZGVmaW5lLjcuMi4yID0gc3JjLXJlZGVmaW5lLjcuMi4yOiBhdHRyaWJ1dGVHcm91cCAnJ3swfScnIHNjaHJcdTAwRTRua3QgZGllIGF0dHJpYnV0ZUdyb3VwLCBkaWUgbmV1IGRlZmluaWVydCB3aXJkLCBuaWNodCBvcmRudW5nc2dlbVx1MDBFNFx1MDBERiBlaW4uIFZlcmxldHp0ZXIgQ29uc3RyYWludDogJyd7MX0nJy4KLSAgICAgICAgc3JjLXJlc29sdmUgPSBzcmMtcmVzb2x2ZTogTmFtZSAnJ3swfScnIGthbm4gbmljaHQgYWxzICcnezF9JyctS29tcG9uZW50ZSBhdWZnZWxcdTAwRjZzdCB3ZXJkZW4uCi0gICAgICAgIHNyYy1yZXNvbHZlLjQuMSA9IHNyYy1yZXNvbHZlLjQuMTogRmVobGVyIGJlaW0gQXVmbFx1MDBGNnNlbiB2b24gS29tcG9uZW50ZSAnJ3syfScnLiBFcyB3dXJkZSBlcm1pdHRlbHQsIGRhc3MgJyd7Mn0nJyBrZWluZW4gTmFtZXNwYWNlIGhhdCwgYWJlciBLb21wb25lbnRlbiBvaG5lIFppZWwtTmFtZXNwYWNlIGtcdTAwRjZubmVuIG5pY2h0IGF1cyBTY2hlbWFkb2t1bWVudCAnJ3swfScnIHJlZmVyZW56aWVydCB3ZXJkZW4uIFdlbm4gJyd7Mn0nJyBlaW5lbiBOYW1lc3BhY2UgaGFiZW4gc29sbCwgbXVzcyBtXHUwMEY2Z2xpY2hlcndlaXNlIGVpbiBQclx1MDBFNGZpeCBhbmdlZ2ViZW4gd2VyZGVuLiBXZW5uICcnezJ9Jycga2VpbmVuIE5hbWVzcGFjZSBoYWJlbiBzb2xsLCBtdXNzIGVpbiAnJ2ltcG9ydCcnIG9obmUgJyduYW1lc3BhY2UnJy1BdHRyaWJ1dCB6dSAnJ3swfScnIGhpbnp1Z2VmXHUwMEZDZ3Qgd2VyZGVuLgotICAgICAgICBzcmMtcmVzb2x2ZS40LjIgPSBzcmMtcmVzb2x2ZS40LjI6IEZlaGxlciBiZWltIEF1ZmxcdTAwRjZzZW4gdm9uIEtvbXBvbmVudGUgJyd7Mn0nJy4gRXMgd3VyZGUgZXJtaXR0ZWx0LCBkYXNzICcnezJ9JycgaW4gTmFtZXNwYWNlICcnezF9Jycgdm9yaGFuZGVuIGlzdCwgYWJlciBLb21wb25lbnRlbiBhdXMgZGllc2VtIE5hbWVzcGFjZSBrXHUwMEY2bm5lbiBuaWNodCBhdXMgU2NoZW1hZG9rdW1lbnQgJyd7MH0nJyByZWZlcmVuemllcnQgd2VyZGVuLiBXZW5uIGRpZXMgZGVyIGZhbHNjaGUgTmFtZXNwYWNlIGlzdCwgbXVzcyBtXHUwMEY2Z2xpY2hlcndlaXNlIGRhcyBQclx1MDBFNGZpeCB2b24gJyd7Mn0nJyBnZVx1MDBFNG5kZXJ0IHdlcmRlbi4gV2VubiBkaWVzIGRlciByaWNodGlnZSBOYW1lc3BhY2UgaXN0LCBtdXNzIGVpbiBlbnRzcHJlY2hlbmRlcyAnJ2ltcG9ydCcnLVRhZyB6dSAnJ3swfScnIGhpbnp1Z2VmXHUwMEZDZ3Qgd2VyZGVuLgotICAgICAgICBzcmMtc2ltcGxlLXR5cGUuMi5hID0gc3JjLXNpbXBsZS10eXBlLjIuYTogRXMgd3VyZGUgZWluIDxyZXN0cmljdGlvbj4tRWxlbWVudCBnZWZ1bmRlbiwgZGFzIHNvd29obCBlaW4gJ2Jhc2UnLVtBdHRyaWJ1dF0gYWxzIGF1Y2ggZWluIDxzaW1wbGVUeXBlPi1FbGVtZW50IGluIHNlaW5lbiBbdW50ZXJnZW9yZG5ldGVuIEVsZW1lbnRlbl0gZW50aFx1MDBFNGx0LiBOdXIgZWluZXMgZGF2b24gaXN0IHp1bFx1MDBFNHNzaWcuCi0gICAgICAgIHNyYy1zaW1wbGUtdHlwZS4yLmIgPSBzcmMtc2ltcGxlLXR5cGUuMi5iOiBFcyB3dXJkZSBlaW4gPHJlc3RyaWN0aW9uPi1FbGVtZW50IGdlZnVuZGVuLCBkYXMgd2VkZXIgZWluICdiYXNlJy1bQXR0cmlidXRdIG5vY2ggZWluIDxzaW1wbGVUeXBlPi1FbGVtZW50IGluIHNlaW5lbiBbdW50ZXJnZW9yZG5ldGVuIEVsZW1lbnRlbl0gZW50aFx1MDBFNGx0LiBFaW5lcyBkYXZvbiBpc3QgZXJmb3JkZXJsaWNoLgotICAgICAgICBzcmMtc2ltcGxlLXR5cGUuMy5hID0gc3JjLXNpbXBsZS10eXBlLjMuYTogRXMgd3VyZGUgZWluIDxsaXN0Pi1FbGVtZW50IGdlZnVuZGVuLCBkYXMgc293b2hsIGVpbiAnaXRlbVR5cGUnLVtBdHRyaWJ1dF0gYWxzIGF1Y2ggZWluIDxzaW1wbGVUeXBlPi1FbGVtZW50IGluIHNlaW5lbiBbdW50ZXJnZW9yZG5ldGVuIEVsZW1lbnRlbl0gZW50aFx1MDBFNGx0LiBOdXIgZWluZXMgZGF2b24gaXN0IHp1bFx1MDBFNHNzaWcuCi0gICAgICAgIHNyYy1zaW1wbGUtdHlwZS4zLmIgPSBzcmMtc2ltcGxlLXR5cGUuMy5iOiBFcyB3dXJkZSBlaW4gPGxpc3Q+LUVsZW1lbnQgZ2VmdW5kZW4sIGRhcyB3ZWRlciBlaW4gJ2l0ZW1UeXBlJy1bQXR0cmlidXRdIG5vY2ggZWluIDxzaW1wbGVUeXBlPi1FbGVtZW50IGluIHNlaW5lbiBbdW50ZXJnZW9yZG5ldGVuIEVsZW1lbnRlbl0gZW50aFx1MDBFNGx0LiBFaW5lcyBkYXZvbiBpc3QgZXJmb3JkZXJsaWNoLgotICAgICAgICBzcmMtc2luZ2xlLWZhY2V0LXZhbHVlID0gc3JjLXNpbmdsZS1mYWNldC12YWx1ZTogRmFjZXQgJyd7MH0nJyBpc3QgbWVocm1hbHMgZGVmaW5pZXJ0LgotICAgICAgICBzcmMtdW5pb24tbWVtYmVyVHlwZXMtb3Itc2ltcGxlVHlwZXMgPSBzcmMtdW5pb24tbWVtYmVyVHlwZXMtb3Itc2ltcGxlVHlwZXM6IEVpbiA8dW5pb24+LUVsZW1lbnQgbXVzcyBlbnR3ZWRlciBlaW4gbmljaHQgbGVlcmVzIG1lbWJlclR5cGVzLVtBdHRyaWJ1dF0gb2RlciBtaW5kZXN0ZW5zIGVpbiA8c2ltcGxlVHlwZT4tRWxlbWVudCBpbiBzZWluZW4gW3VudGVyZ2VvcmRuZXRlbiBFbGVtZW50ZW5dIGVudGhhbHRlbi4KLQotI2NvbnN0cmFpbnQgdmFsaWQgKDMuWC42KQotCi0gICAgICAgIGFnLXByb3BzLWNvcnJlY3QuMiA9IGFnLXByb3BzLWNvcnJlY3QuMjogRmVobGVyIGJlaSBBdHRyaWJ1dGdydXBwZSAnJ3swfScnLiBFcyB3dXJkZW4gZG9wcGVsdGUgQXR0cmlidXR2ZXJ3ZW5kdW5nZW4gbWl0IGRlbXNlbGJlbiBOYW1lbiB1bmQgWmllbC1OYW1lc3BhY2UgYW5nZWdlYmVuLiBOYW1lIGRlciBkb3BwZWx0ZW4gQXR0cmlidXR2ZXJ3ZW5kdW5nIGxhdXRldCAnJ3sxfScnLgotICAgICAgICBhZy1wcm9wcy1jb3JyZWN0LjMgPSBhZy1wcm9wcy1jb3JyZWN0LjM6IEZlaGxlciBiZWkgQXR0cmlidXRncnVwcGUgJyd7MH0nJy4gWndlaSBBdHRyaWJ1dGRla2xhcmF0aW9uZW4gKCcnezF9JycgdW5kICcnezJ9JycpIGhhYmVuIFR5cGVuLCBkaWUgYXVzIElEIGFiZ2VsZWl0ZXQgd3VyZGVuLgotICAgICAgICBhLXByb3BzLWNvcnJlY3QuMiA9IGEtcHJvcHMtY29ycmVjdC4yOiBVbmdcdTAwRkNsdGlnZXIgV2VydGUtQ29uc3RyYWludC1XZXJ0ICcnezF9JycgaW4gQXR0cmlidXQgJyd7MH0nJy4KLSAgICAgICAgYS1wcm9wcy1jb3JyZWN0LjMgPSBhLXByb3BzLWNvcnJlY3QuMzogQmVpIEF0dHJpYnV0ICcnezB9Jycga2FubiAnJ2ZpeGVkJycgb2RlciAnJ2RlZmF1bHQnJyBuaWNodCB2ZXJ3ZW5kZXQgd2VyZGVuLCBkYSBkaWUgJ3sndHlwZSBkZWZpbml0aW9uJ30nIGRlcyBBdHRyaWJ1dHMgJydJRCcnIGlzdCBvZGVyIGF1cyBJRCBhYmdlbGVpdGV0IHd1cmRlLgotICAgICAgICBhdS1wcm9wcy1jb3JyZWN0LjIgPSBhdS1wcm9wcy1jb3JyZWN0LjI6IEluIGRlciBBdHRyaWJ1dGRla2xhcmF0aW9uIHZvbiAnJ3swfScnIHd1cmRlIGRlciBmZXN0ZSBXZXJ0ICcnezF9JycgYW5nZWdlYmVuLiBXZW5uIGFsc28gZGllIEF0dHJpYnV0dmVyd2VuZHVuZywgZGllIGF1ZiAnJ3swfScnIHZlcndlaXN0LCBhdWNoIGVpbmVuICd7J3ZhbHVlIGNvbnN0cmFpbnQnfScgaGF0LCBtdXNzIHNpZSBmZXN0IHNlaW4sIHVuZCBkZXIgV2VydCBtdXNzICcnezF9JycgbGF1dGVuLgotICAgICAgICBjb3MtYWxsLWxpbWl0ZWQuMS4yID0gY29zLWFsbC1saW1pdGVkLjEuMjogRWluZSAnYWxsJy1Nb2RlbGxncnVwcGUgbXVzcyBpbiBlaW5lbSBQYXJ0aWtlbCBtaXQgJ3snbWluIG9jY3Vycyd9JyA9ICd7J21heCBvY2N1cnMnfScgPSAxIHZvcmtvbW1lbiwgdW5kIGRpZXNlcyBQYXJ0aWtlbCBtdXNzIHp1IGVpbmVtIFBhYXIgZ2VoXHUwMEY2cmVuLCBkYXMgZGVuICd7J2NvbnRlbnQgdHlwZSd9JyBlaW5lciBDb21wbGV4IFR5cGUtRGVmaW5pdGlvbiBkYXJzdGVsbHQuCi0gICAgICAgIGNvcy1hbGwtbGltaXRlZC4yID0gY29zLWFsbC1saW1pdGVkLjI6ICd7J21heCBvY2N1cnMnfScgZWluZXMgRWxlbWVudHMgaW4gZWluZXIgJydhbGwnJy1Nb2RlbGxncnVwcGUgbXVzcyAwIG9kZXIgMSBzZWluLiBEZXIgV2VydCAnJ3swfScnIGZcdTAwRkNyIEVsZW1lbnQgJyd7MX0nJyBpc3QgdW5nXHUwMEZDbHRpZy4KLSAgICAgICAgY29zLWFwcGxpY2FibGUtZmFjZXRzID0gY29zLWFwcGxpY2FibGUtZmFjZXRzOiBGYWNldCAnJ3swfScnIGlzdCBuaWNodCB6dWxcdTAwRTRzc2lnIGZcdTAwRkNyIFR5cCB7MX0uCi0gICAgICAgIGNvcy1jdC1leHRlbmRzLjEuMSA9IGNvcy1jdC1leHRlbmRzLjEuMTogVHlwICcnezB9Jycgd3VyZGUgZHVyY2ggZGllIEVyd2VpdGVydW5nIHZvbiBUeXAgJyd7MX0nJyBhYmdlbGVpdGV0LiBEYXMgQXR0cmlidXQgJydmaW5hbCcnIHZvbiAnJ3sxfScnIGxcdTAwRTRzc3QgZGllIEFibGVpdHVuZyBkdXJjaCBFcndlaXRlcnVuZyBhYmVyIG5pY2h0IHp1LgotICAgICAgICBjb3MtY3QtZXh0ZW5kcy4xLjQuMy4yLjIuMS5hID0gY29zLWN0LWV4dGVuZHMuMS40LjMuMi4yLjEuYTogRGVyIENvbnRlbnR0eXAgZWluZXMgYWJnZWxlaXRldGVuIFR5cHMgdW5kIGRlciBzZWluZXIgQmFzaXMgbVx1MDBGQ3NzZW4gYmVpZGUgJydtaXhlZCcnIG9kZXIgJydlbGVtZW50LW9ubHknJyBzZWluLiBUeXAgJyd7MH0nJyBpc3QgJydlbGVtZW50IG9ubHknJywgYWJlciBzZWluIEJhc2lzdHlwIG5pY2h0LgotICAgICAgICBjb3MtY3QtZXh0ZW5kcy4xLjQuMy4yLjIuMS5iID0gY29zLWN0LWV4dGVuZHMuMS40LjMuMi4yLjEuYjogRGVyIENvbnRlbnR0eXAgZWluZXMgYWJnZWxlaXRldGVuIFR5cHMgdW5kIGRlciBzZWluZXIgQmFzaXMgbVx1MDBGQ3NzZW4gYmVpZGUgJydtaXhlZCcnIG9kZXIgJydlbGVtZW50LW9ubHknJyBzZWluLiBUeXAgJyd7MH0nJyBpc3QgJydtaXhlZCcnLCBhYmVyIHNlaW4gQmFzaXN0eXAgbmljaHQuCi0gICAgICAgIGNvcy1lbGVtZW50LWNvbnNpc3RlbnQgPSBjb3MtZWxlbWVudC1jb25zaXN0ZW50OiBGZWhsZXIgYmVpIFR5cCAnJ3swfScnLiBNZWhyZXJlIEVsZW1lbnRlIG1pdCBOYW1lbiAnJ3sxfScnIHVuZCB1bnRlcnNjaGllZGxpY2hlbiBUeXBlbiBrb21tZW4gaW4gZGVyIE1vZGVsbGdydXBwZSB2b3IuCi0gICAgICAgIGNvcy1saXN0LW9mLWF0b21pYyA9IGNvcy1saXN0LW9mLWF0b21pYzogSW4gZGVyIERlZmluaXRpb24gdm9uIExpc3RlbnR5cCAnJ3swfScnIGlzdCBUeXAgJyd7MX0nJyBlaW4gdW5nXHUwMEZDbHRpZ2VyIExpc3RlbmVsZW1lbnR0eXAsIGRhIGVyIG5pY2h0IGF0b21hciBpc3QgKCcnezF9JycgaXN0IGVudHdlZGVyIGVpbiBMaXN0ZW50eXAgb2RlciBlaW4gVmVyZWluaWd1bmdzbWVuZ2VudHlwLCBkZXIgZWluZSBMaXN0ZSBlbnRoXHUwMEU0bHQpLgotICAgICAgICBjb3Mtbm9uYW1iaWcgPSBjb3Mtbm9uYW1iaWc6IHswfSB1bmQgezF9IChvZGVyIEVsZW1lbnRlIGF1cyBpaHJlciBTdWJzdGl0dXRpb25zZ3J1cHBlKSB2ZXJsZXR6ZW4gJydVbmlxdWUgUGFydGljbGUgQXR0cmlidXRpb24nJy4gQmVpIGRlciBWYWxpZGllcnVuZyBmXHUwMEZDciBkaWVzZXMgU2NoZW1hIHdcdTAwRkNyZGUgZWluZSBNZWhyZGV1dGlna2VpdCBmXHUwMEZDciBkaWVzZSBiZWlkZW4gUGFydGlrZWwgZXJzdGVsbHQuCi0gICAgICAgIGNvcy1wYXJ0aWNsZS1yZXN0cmljdC5hID0gY29zLXBhcnRpY2xlLXJlc3RyaWN0LmE6IEFiZ2VsZWl0ZXRlcyBQYXJ0aWtlbCBpc3QgbGVlciwgdW5kIGRpZSBCYXNpcyBrYW5uIG5pY2h0IGdlbGVlcnQgd2VyZGVuLgotICAgICAgICBjb3MtcGFydGljbGUtcmVzdHJpY3QuYiA9IGNvcy1wYXJ0aWNsZS1yZXN0cmljdC5iOiBCYXNpc3BhcnRpa2VsIGlzdCBsZWVyLCBhYmVyIGRhcyBhYmdlbGVpdGV0ZSBQYXJ0aWtlbCBpc3QgbmljaHQgbGVlci4KLSAgICAgICAgY29zLXBhcnRpY2xlLXJlc3RyaWN0LjIgPSBjb3MtcGFydGljbGUtcmVzdHJpY3QuMjogVW56dWxcdTAwRTRzc2lnZSBQYXJ0aWtlbGVpbnNjaHJcdTAwRTRua3VuZzogJyd7MH0nJy4KLSAgICAgICAgY29zLXN0LXJlc3RyaWN0cy4xLjEgPSBjb3Mtc3QtcmVzdHJpY3RzLjEuMTogVHlwICcnezF9JycgaXN0IGF0b21hci4gRGFoZXIgbXVzcyBkaWUgenVnZWhcdTAwRjZyaWdlICd7J2Jhc2UgdHlwZSBkZWZpbml0aW9uJ30nICcnezB9JycgZWluZSBhdG9tYXJlIFNpbXBsZSBUeXBlLURlZmluaXRpb24gb2RlciBlaW4gaW50ZWdyaWVydGVyIHByaW1pdGl2ZXIgRGF0ZW50eXAgc2Vpbi4KLSAgICAgICAgY29zLXN0LXJlc3RyaWN0cy4yLjEgPSBjb3Mtc3QtcmVzdHJpY3RzLjIuMTogSW4gZGVyIERlZmluaXRpb24gdm9uIExpc3RlbnR5cCAnJ3swfScnIGlzdCBUeXAgJyd7MX0nJyBlaW4gdW5nXHUwMEZDbHRpZ2VyIEVsZW1lbnR0eXAsIGRhIGVyIGVudHdlZGVyIGVpbiBMaXN0ZW50eXAgb2RlciBlaW4gVmVyZWluaWd1bmdzbWVuZ2VudHlwIGlzdCwgZGVyIGVpbmUgTGlzdGUgZW50aFx1MDBFNGx0LgotICAgICAgICBjb3Mtc3QtcmVzdHJpY3RzLjIuMy4xLjEgPSBjb3Mtc3QtcmVzdHJpY3RzLjIuMy4xLjE6IEtvbXBvbmVudGUgJ3snZmluYWwnfScgZGVyICd7J2l0ZW0gdHlwZSBkZWZpbml0aW9uJ30nICcnezB9JycgZW50aFx1MDBFNGx0ICcnbGlzdCcnLiBEaWVzIGJlZGV1dGV0LCBkYXNzICcnezB9JycgbmljaHQgYWxzIEVsZW1lbnR0eXAgZlx1MDBGQ3IgTGlzdGVudHlwICcnezF9JycgdmVyd2VuZGV0IHdlcmRlbiBrYW5uLgotICAgICAgICBjb3Mtc3QtcmVzdHJpY3RzLjMuMy4xLjEgPSBjb3Mtc3QtcmVzdHJpY3RzLjMuMy4xLjE6IEtvbXBvbmVudGUgJ3snZmluYWwnfScgZGVyICd7J21lbWJlciB0eXBlIGRlZmluaXRpb25zJ30nICcnezB9JycgZW50aFx1MDBFNGx0ICcndW5pb24nJy4gRGllcyBiZWRldXRldCwgZGFzcyAnJ3swfScnIG5pY2h0IGFscyBNaXRnbGllZHN0eXAgZlx1MDBGQ3IgVmVyZWluaWd1bmdzbWVuZ2VudHlwICcnezF9JycgdmVyd2VuZGV0IHdlcmRlbiBrYW5uLgotICAgICAgICBjb3MtdmFsaWQtZGVmYXVsdC4yLjEgPSBjb3MtdmFsaWQtZGVmYXVsdC4yLjE6IEVsZW1lbnQgJyd7MH0nJyBoYXQgZWluZW4gV2VydGUtQ29uc3RyYWludCB1bmQgbXVzcyBlaW4gTWlzY2gtIG9kZXIgZWluIGVpbmZhY2hlcyBDb250ZW50bW9kZWxsIGhhYmVuLgotICAgICAgICBjb3MtdmFsaWQtZGVmYXVsdC4yLjIuMiA9IGNvcy12YWxpZC1kZWZhdWx0LjIuMi4yOiBEYSBFbGVtZW50ICcnezB9JycgZWluZW4gJ3sndmFsdWUgY29uc3RyYWludCd9JyBoYXQgdW5kIHNlaW5lIFR5cGRlZmluaXRpb24gZWluZW4gZ2VtaXNjaHRlbiAneydjb250ZW50IHR5cGUnfScgaGF0LCBtdXNzIGRhcyBQYXJ0aWtlbCBkZXMgJ3snY29udGVudCB0eXBlJ30nIGdlbGVlcnQgd2VyZGVuIGtcdTAwRjZubmVuLgotICAgICAgICBjLXByb3BzLWNvcnJlY3QuMiA9IGMtcHJvcHMtY29ycmVjdC4yOiBLYXJkaW5hbGl0XHUwMEU0dCB2b24gRmVsZGVybiBmXHUwMEZDciBrZXlyZWYgJyd7MH0nJyB1bmQgU2NobFx1MDBGQ3NzZWwgJyd7MX0nJyBtdXNzIHNpY2ggZ2VnZW5zZWl0aWcgZW50c3ByZWNoZW4uCi0gICAgICAgIGN0LXByb3BzLWNvcnJlY3QuMyA9IGN0LXByb3BzLWNvcnJlY3QuMzogWnlrbGlzY2hlIERlZmluaXRpb25lbiBmXHUwMEZDciBDb21wbGV4IFR5cGUgJyd7MH0nJyBlcm1pdHRlbHQuIERpZXMgYmVkZXV0ZXQsIGRhc3MgJyd7MH0nJyBpbiBkZXIgZWlnZW5lbiBUeXBoaWVyYXJjaGllIGVudGhhbHRlbiBpc3QuIERpZXMgaXN0IGVpbiBGZWhsZXIuCi0gICAgICAgIGN0LXByb3BzLWNvcnJlY3QuNCA9IGN0LXByb3BzLWNvcnJlY3QuNDogRmVobGVyIGJlaSBUeXAgJyd7MH0nJy4gRXMgd3VyZGVuIGRvcHBlbHRlIEF0dHJpYnV0dmVyd2VuZHVuZ2VuIG1pdCBkZW1zZWxiZW4gTmFtZW4gdW5kIFppZWwtTmFtZXNwYWNlIGFuZ2VnZWJlbi4gTmFtZSBkZXIgZG9wcGVsdGVuIEF0dHJpYnV0dmVyd2VuZHVuZyBsYXV0ZXQgJyd7MX0nJy4KLSAgICAgICAgY3QtcHJvcHMtY29ycmVjdC41ID0gY3QtcHJvcHMtY29ycmVjdC41OiBGZWhsZXIgYmVpIFR5cCAnJ3swfScnLiBad2VpIEF0dHJpYnV0ZGVrbGFyYXRpb25lbiAoJyd7MX0nJyB1bmQgJyd7Mn0nJykgaGFiZW4gVHlwZW4sIGRpZSBhdXMgSUQgYWJnZWxlaXRldCB3dXJkZW4uCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMSA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMTogVHlwICcnezB9Jycgd3VyZGUgZHVyY2ggZGllIEVpbnNjaHJcdTAwRTRua3VuZyB2b24gVHlwICcnezF9JycgYWJnZWxlaXRldC4gJyd7MX0nJyBoYXQgYWJlciBlaW5lICd7J2ZpbmFsJ30nLUVpZ2Vuc2NoYWZ0LCBkaWUgZGllIEFibGVpdHVuZyBkdXJjaCBFaW5zY2hyXHUwMEU0bmt1bmcgbmljaHQgenVsXHUwMEU0c3N0LgotICAgICAgICBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjIuMS4xID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4yLjEuMTogRmVobGVyIGJlaSBUeXAgJyd7MH0nJy4gQXR0cmlidXR2ZXJ3ZW5kdW5nICcnezF9JycgaW4gZGllc2VtIFR5cCBoYXQgZGVuICcndXNlJyctV2VydCAnJ3syfScnLCBkZXIgbmljaHQgbWl0IGRlbSBXZXJ0IHZvbiAnJ3JlcXVpcmVkJycgaW4gZWluZXIgXHUwMEZDYmVyZWluc3RpbW1lbmRlbiBBdHRyaWJ1dHZlcndlbmR1bmcgaW0gQmFzaXN0eXAga29uc2lzdGVudCBpc3QuCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMi4xLjIgPSBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjIuMS4yOiBGZWhsZXIgYmVpIFR5cCAnJ3swfScnLiBBdHRyaWJ1dHZlcndlbmR1bmcgJyd7MX0nJyBpbiBkaWVzZW0gVHlwIGhhdCBkZW4gVHlwICcnezJ9JycsIGRlciBuaWNodCBhdWYgZ1x1MDBGQ2x0aWdlIFdlaXNlIHZvbiAnJ3szfScnIGFiZ2VsZWl0ZXQgd3VyZGUsIGRlbSBUeXAgZGVyIFx1MDBGQ2JlcmVpbnN0aW1tZW5kZW4gQXR0cmlidXR2ZXJ3ZW5kdW5nIGltIEJhc2lzdHlwLgotICAgICAgICBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjIuMS4zLmEgPSBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjIuMS4zLmE6IEZlaGxlciBiZWkgVHlwICcnezB9JycuIEF0dHJpYnV0dmVyd2VuZHVuZyAnJ3sxfScnIGluIGRpZXNlbSBUeXAgaGF0IGVpbmVuIGVmZmVrdGl2ZW4gV2VydGUtQ29uc3RyYWludCwgZGVyIG5pY2h0IGZlc3QgaXN0LCB1bmQgZGVyIGVmZmVrdGl2ZSBXZXJ0ZS1Db25zdHJhaW50IGRlciBcdTAwRkNiZXJlaW5zdGltbWVuZGVuIEF0dHJpYnV0dmVyd2VuZHVuZyBpbSBCYXNpc3R5cCBpc3QgZmVzdC4KLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4yLjEuMy5iID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4yLjEuMy5iOiBGZWhsZXIgYmVpIFR5cCAnJ3swfScnLiBBdHRyaWJ1dHZlcndlbmR1bmcgJyd7MX0nJyBpbiBkaWVzZW0gVHlwIGhhdCBlaW5lbiBlZmZla3RpdmVuIGZlc3RlbiBXZXJ0ZS1Db25zdHJhaW50IG1pdCBkZW0gV2VydCAnJ3syfScnLiBEaWVzIGlzdCBuaWNodCBtaXQgZGVtIFdlcnQgJyd7M30nJyBmXHUwMEZDciBkZW4gZmVzdGVuIGVmZmVrdGl2ZW4gV2VydGUtQ29uc3RyYWludCBkZXIgXHUwMEZDYmVyZWluc3RpbW1lbmRlbiBBdHRyaWJ1dHZlcndlbmR1bmcgaW0gQmFzaXN0eXAga29uc2lzdGVudC4KLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4yLjIuYSA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMi4yLmE6IEZlaGxlciBiZWkgVHlwICcnezB9JycuIEF0dHJpYnV0dmVyd2VuZHVuZyAnJ3sxfScnIGluIGRpZXNlbSBUeXAgaGF0IGtlaW5lIFx1MDBGQ2JlcmVpbnN0aW1tZW5kZSBBdHRyaWJ1dHZlcndlbmR1bmcgaW4gZGVyIEJhc2lzLCB1bmQgZGVyIEJhc2lzdHlwIGhhdCBrZWluIFBsYXR6aGFsdGVyYXR0cmlidXQuCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMi4yLmIgPSBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjIuMi5iOiBGZWhsZXIgYmVpIFR5cCAnJ3swfScnLiBBdHRyaWJ1dHZlcndlbmR1bmcgJyd7MX0nJyBpbiBkaWVzZW0gVHlwIGhhdCBrZWluZSBcdTAwRkNiZXJlaW5zdGltbWVuZGUgQXR0cmlidXR2ZXJ3ZW5kdW5nIGluIGRlciBCYXNpcywgdW5kIGRlciBQbGF0emhhbHRlciBpbSBCYXNpc3R5cCBsXHUwMEU0c3N0IGRlbiBOYW1lc3BhY2UgJyd7Mn0nJyBkaWVzZXIgQXR0cmlidXR2ZXJ3ZW5kdW5nIG5pY2h0IHp1LgotICAgICAgICBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjMgPSBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjM6IEZlaGxlciBiZWkgVHlwICcnezB9JycuIEJlaSBBdHRyaWJ1dHZlcndlbmR1bmcgJyd7MX0nJyBpbSBCYXNpc3R5cCBpc3QgUkVRVUlSRUQgJyd0cnVlJycsIGFiZXIgZXMgaXN0IGtlaW5lIFx1MDBGQ2JlcmVpbnN0aW1tZW5kZSBBdHRyaWJ1dHZlcndlbmR1bmcgaW0gYWJnZWxlaXRldGVuIFR5cCB2b3JoYW5kZW4uCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uNC4xID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi40LjE6IEZlaGxlciBiZWkgVHlwICcnezB9JycuIEFibGVpdHVuZyBoYXQgZWluZW4gQXR0cmlidXRwbGF0emhhbHRlciwgYWJlciBkaWUgQmFzaXMgaGF0IGtlaW5lbi4KLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi40LjIgPSBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjQuMjogRmVobGVyIGJlaSBUeXAgJyd7MH0nJy4gUGxhdHpoYWx0ZXIgaW4gZGVyIEFibGVpdHVuZyBpc3Qga2VpbmUgZ1x1MDBGQ2x0aWdlIFBsYXR6aGFsdGVyLVRlaWxtZW5nZSBkZXMgUGxhdHpoYWx0ZXJzIGluIGRlciBCYXNpcy4KLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi40LjMgPSBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjQuMzogRmVobGVyIGJlaSBUeXAgJyd7MH0nJy4gUHJvemVzc2NvbnRlbnQgZGVzIFBsYXR6aGFsdGVycyBpbiBkZXIgQWJsZWl0dW5nICh7MX0pIGlzdCBzY2h3XHUwMEU0Y2hlciBhbHMgZGVyIENvbnRlbnQgaW4gZGVyIEJhc2lzICh7Mn0pLgotICAgICAgICBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjUuMi4yLjEgPSBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjUuMi4yLjE6IEZlaGxlciBiZWkgVHlwICcnezB9JycuIEVpbmZhY2hlciBDb250ZW50dHlwIGRpZXNlcyBUeXBzICcnezF9JycgaXN0IGtlaW5lIGdcdTAwRkNsdGlnZSBFaW5zY2hyXHUwMEU0bmt1bmcgZGVzIGVpbmZhY2hlbiBDb250ZW50dHlwcyBkZXIgQmFzaXMgJyd7Mn0nJy4KLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi41LjMuMiA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uNS4zLjI6IEZlaGxlciBiZWkgVHlwICcnezB9JycuIENvbnRlbnR0eXAgZGllc2VzIFR5cHMgaXN0IGxlZXIsIGFiZXIgZGVyIENvbnRlbnR0eXBzIGRlciBCYXNpcyAnJ3sxfScnIGlzdCBuaWNodCBsZWVyIG9kZXIga2FubiBuaWNodCBnZWxlZXJ0IHdlcmRlbi4KLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi41LjQuMS4yID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi41LjQuMS4yOiBGZWhsZXIgYmVpIFR5cCAnJ3swfScnLiBDb250ZW50dHlwIGRpZXNlcyBUeXBzIGlzdCAnJ21peGVkJycsIGFiZXIgZGVyIENvbnRlbnR0eXBzIGRlciBCYXNpcyAnJ3sxfScnIG5pY2h0LgotICAgICAgICBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjUuNC4yID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi41LjQuMjogRmVobGVyIGJlaSBUeXAgJyd7MH0nJy4gUGFydGlrZWwgZGVzIFR5cHMgaXN0IGtlaW5lIGdcdTAwRkNsdGlnZSBFaW5zY2hyXHUwMEU0bmt1bmcgZGVzIFBhcnRpa2VscyBkZXIgQmFzaXMuCi0gICAgICAgIGVudW1lcmF0aW9uLXJlcXVpcmVkLW5vdGF0aW9uID0gZW51bWVyYXRpb24tcmVxdWlyZWQtbm90YXRpb246IE5PVEFUSU9OLVR5cCAnJ3swfScnLCBkZXIgdm9uIHsyfSAnJ3sxfScnIHZlcndlbmRldCB3aXJkLCBtdXNzIGVpbmVuIEVudW1lcmF0aW9ucy1GYWNldC1XZXJ0IGhhYmVuLCBkZXIgZGllIHZvbiBkaWVzZW0gVHlwIHZlcndlbmRldGVuIE5vdGF0aW9uc2VsZW1lbnRlIGFuZ2lidC4KLSAgICAgICAgZW51bWVyYXRpb24tdmFsaWQtcmVzdHJpY3Rpb24gPSBlbnVtZXJhdGlvbi12YWxpZC1yZXN0cmljdGlvbjogRW51bWVyYXRpb25zd2VydCAnJ3swfScnIGlzdCBuaWNodCBpbSBXZXJ0ZWJlcmVpY2ggZGVzIEJhc2lzdHlwcyB7MX0gdm9yaGFuZGVuLgotICAgICAgICBlLXByb3BzLWNvcnJlY3QuMiA9IGUtcHJvcHMtY29ycmVjdC4yOiBVbmdcdTAwRkNsdGlnZXIgV2VydGUtQ29uc3RyYWludC1XZXJ0ICcnezF9JycgaW4gRWxlbWVudCAnJ3swfScnLgotICAgICAgICBlLXByb3BzLWNvcnJlY3QuNCA9IGUtcHJvcHMtY29ycmVjdC40OiAneyd0eXBlIGRlZmluaXRpb24nfScgdm9uIEVsZW1lbnQgJyd7MH0nJyB3dXJkZSBuaWNodCBhdWYgZ1x1MDBGQ2x0aWdlIFdlaXNlIHZvbiBkZXIgJ3sndHlwZSBkZWZpbml0aW9uJ30nIHZvbiBzdWJzdGl0dXRpb25IZWFkICcnezF9JycgYWJnZWxlaXRldCwgb2RlciBkaWUgJ3snc3Vic3RpdHV0aW9uIGdyb3VwIGV4Y2x1c2lvbnMnfSctRWlnZW5zY2hhZnQgdm9uICcnezF9JycgbFx1MDBFNHNzdCBkaWVzZSBBYmxlaXR1bmcgbmljaHQgenUuCi0gICAgICAgIGUtcHJvcHMtY29ycmVjdC41ID0gZS1wcm9wcy1jb3JyZWN0LjU6ICd7J3ZhbHVlIGNvbnN0cmFpbnQnfScgZGFyZiBuaWNodCBiZWkgRWxlbWVudCAnJ3swfScnIHZvcmhhbmRlbiBzZWluLCBkYSBkaWUgJ3sndHlwZSBkZWZpbml0aW9uJ30nIGRlcyBFbGVtZW50cyBvZGVyIGRlciAneydjb250ZW50IHR5cGUnfScgZGVyICd7J3R5cGUgZGVmaW5pdGlvbid9JyBJRCBpc3Qgb2RlciB2b24gSUQgYWJnZWxlaXRldCB3dXJkZS4KLSAgICAgICAgZS1wcm9wcy1jb3JyZWN0LjYgPSBlLXByb3BzLWNvcnJlY3QuNjogWnlrbGlzY2hlIFN1YnN0aXR1dGlvbnNncnVwcGUgZlx1MDBGQ3IgRWxlbWVudCAnJ3swfScnIGVybWl0dGVsdC4KLSAgICAgICAgZnJhY3Rpb25EaWdpdHMtdmFsaWQtcmVzdHJpY3Rpb24gPSBmcmFjdGlvbkRpZ2l0cy12YWxpZC1yZXN0cmljdGlvbjogSW4gZGVyIERlZmluaXRpb24gdm9uIHsyfSBpc3QgZGVyIFdlcnQgJyd7MH0nJyBmXHUwMEZDciBGYWNldCAnJ2ZyYWN0aW9uRGlnaXRzJycgdW5nXHUwMEZDbHRpZywgZGEgZXIgPD0gZGVtIFdlcnQgZlx1MDBGQ3IgJydmcmFjdGlvbkRpZ2l0cycnIHNlaW4gbXVzcywgZGVyIGluIGVpbmVtIGRlciBWb3JnXHUwMEU0bmdlcnR5cGVuIGF1ZiAnJ3sxfScnIGdlc2V0enQgd3VyZGUuCi0gICAgICAgIGZyYWN0aW9uRGlnaXRzLXRvdGFsRGlnaXRzID0gZnJhY3Rpb25EaWdpdHMtdG90YWxEaWdpdHM6IEluIGRlciBEZWZpbml0aW9uIHZvbiB7Mn0gaXN0IGRlciBXZXJ0ICcnezB9JycgZlx1MDBGQ3IgRmFjZXQgJydmcmFjdGlvbkRpZ2l0cycnIHVuZ1x1MDBGQ2x0aWcsIGRhIGRlciBXZXJ0IDw9IGRlbSBXZXJ0IGZcdTAwRkNyICcndG90YWxEaWdpdHMnJyBzZWluIG11c3MsIGRlciAnJ3sxfScnIGlzdC4KLSAgICAgICAgbGVuZ3RoLW1pbkxlbmd0aC1tYXhMZW5ndGguMS4xID0gbGVuZ3RoLW1pbkxlbmd0aC1tYXhMZW5ndGguMS4xOiBCZWkgVHlwIHswfSBnaWx0IGVzIGFscyBGZWhsZXIsIHdlbm4gZGVyIFdlcnQgdm9uIGxlbmd0aCAnJ3sxfScnIGtsZWluZXIgYWxzIGRlciBXZXJ0IHZvbiBtaW5MZW5ndGggJyd7Mn0nJyBpc3QuCi0gICAgICAgIGxlbmd0aC1taW5MZW5ndGgtbWF4TGVuZ3RoLjEuMi5hID0gbGVuZ3RoLW1pbkxlbmd0aC1tYXhMZW5ndGguMS4yLmE6IEJlaSBUeXAgezB9IGdpbHQgZXMgYWxzIEZlaGxlciwgd2VubiBkaWUgQmFzaXMga2VpbiBtaW5MZW5ndGgtRmFjZXQgaGF0LCB3ZW5uIGRpZSBha3R1ZWxsZSBFaW5zY2hyXHUwMEU0bmt1bmcgZGFzIG1pbkxlbmd0aC1GYWNldCB1bmQgZGllIGFrdHVlbGxlIEVpbnNjaHJcdTAwRTRua3VuZyBvZGVyIEJhc2lzIGRhcyBsZW5ndGgtRmFjZXQgaGF0LgotICAgICAgICBsZW5ndGgtbWluTGVuZ3RoLW1heExlbmd0aC4xLjIuYiA9IGxlbmd0aC1taW5MZW5ndGgtbWF4TGVuZ3RoLjEuMi5iOiBCZWkgVHlwIHswfSBnaWx0IGVzIGFscyBGZWhsZXIsIHdlbm4gZGllIGFrdHVlbGxlIG1pbkxlbmd0aCAnJ3sxfScnIG5pY2h0IG1pdCBkZXIgQmFzaXMtbWluTGVuZ3RoICcnezJ9JycgaWRlbnRpc2NoIGlzdC4KLSAgICAgICAgbGVuZ3RoLW1pbkxlbmd0aC1tYXhMZW5ndGguMi4xID0gbGVuZ3RoLW1pbkxlbmd0aC1tYXhMZW5ndGguMi4xOiBCZWkgVHlwIHswfSBnaWx0IGVzIGFscyBGZWhsZXIsIHdlbm4gZGVyIFdlcnQgdm9uIGxlbmd0aCAnJ3sxfScnIGdyXHUwMEY2XHUwMERGZXIgYWxzIGRlciBXZXJ0IHZvbiBtYXhMZW5ndGggJyd7Mn0nJyBpc3QuCi0gICAgICAgIGxlbmd0aC1taW5MZW5ndGgtbWF4TGVuZ3RoLjIuMi5hID0gbGVuZ3RoLW1pbkxlbmd0aC1tYXhMZW5ndGguMi4yLmE6IEJlaSBUeXAgezB9IGdpbHQgZXMgYWxzIEZlaGxlciwgd2VubiBkaWUgQmFzaXMga2VpbiBtYXhMZW5ndGgtRmFjZXQgaGF0LCB3ZW5uIGRpZSBha3R1ZWxsZSBFaW5zY2hyXHUwMEU0bmt1bmcgZGFzIG1heExlbmd0aC1GYWNldCB1bmQgZGllIGFrdHVlbGxlIEVpbnNjaHJcdTAwRTRua3VuZyBvZGVyIEJhc2lzIGRhcyBsZW5ndGgtRmFjZXQgaGF0LgotICAgICAgICBsZW5ndGgtbWluTGVuZ3RoLW1heExlbmd0aC4yLjIuYiA9IGxlbmd0aC1taW5MZW5ndGgtbWF4TGVuZ3RoLjIuMi5iOiBCZWkgVHlwIHswfSBnaWx0IGVzIGFscyBGZWhsZXIsIHdlbm4gZGllIGFrdHVlbGxlIG1heExlbmd0aCAnJ3sxfScnIG5pY2h0IG1pdCBkZXIgQmFzaXMtbWF4TGVuZ3RoICcnezJ9JycgaWRlbnRpc2NoIGlzdC4KLSAgICAgICAgbGVuZ3RoLXZhbGlkLXJlc3RyaWN0aW9uID0gbGVuZ3RoLXZhbGlkLXJlc3RyaWN0aW9uOiBGZWhsZXIgYmVpIFR5cCAnJ3syfScnLiBEZXIgV2VydCB2b24gbGVuZ3RoID0gJyd7MH0nJyBtdXNzIG1pdCBkZW0gV2VydCBkZXMgQmFzaXN0eXBzICcnezF9JycgaWRlbnRpc2NoIHNlaW4uCi0gICAgICAgIG1heEV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4xID0gbWF4RXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjE6IEZlaGxlciBiZWkgVHlwICcnezJ9JycuIG1heEV4Y2x1c2l2ZS1XZXJ0ID0nJ3swfScnIG11c3MgPD0gbWF4RXhjbHVzaXZlIGRlcyBCYXNpc3R5cHMgJyd7MX0nJyBzZWluLgotICAgICAgICBtYXhFeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMiA9IG1heEV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4yOiBGZWhsZXIgYmVpIFR5cCAnJ3syfScnLiBtYXhFeGNsdXNpdmUtV2VydCA9Jyd7MH0nJyBtdXNzIDw9IG1heEluY2x1c2l2ZSBkZXMgQmFzaXN0eXBzICcnezF9Jycgc2Vpbi4KLSAgICAgICAgbWF4RXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjMgPSBtYXhFeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMzogRmVobGVyIGJlaSBUeXAgJyd7Mn0nJy4gbWF4RXhjbHVzaXZlLVdlcnQgPScnezB9JycgbXVzcyA+IG1pbkluY2x1c2l2ZSBkZXMgQmFzaXN0eXBzICcnezF9Jycgc2Vpbi4KLSAgICAgICAgbWF4RXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjQgPSBtYXhFeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uNDogRmVobGVyIGJlaSBUeXAgJyd7Mn0nJy4gbWF4RXhjbHVzaXZlLVdlcnQgPScnezB9JycgbXVzcyA+IG1pbkV4Y2x1c2l2ZSBkZXMgQmFzaXN0eXBzICcnezF9Jycgc2Vpbi4KLSAgICAgICAgbWF4SW5jbHVzaXZlLW1heEV4Y2x1c2l2ZSA9IG1heEluY2x1c2l2ZS1tYXhFeGNsdXNpdmU6IEVzIGdpbHQgYWxzIEZlaGxlciwgd2VubiBzb3dvaGwgbWF4SW5jbHVzaXZlIGFscyBhdWNoIG1heEV4Y2x1c2l2ZSBmXHUwMEZDciBkZW5zZWxiZW4gRGF0ZW50eXAgYW5nZWdlYmVuIHdlcmRlbi4gSW4gezJ9IGdpbHQ6IG1heEluY2x1c2l2ZSA9ICcnezB9JycgdW5kIG1heEV4Y2x1c2l2ZSA9ICcnezF9JycuCi0gICAgICAgIG1heEluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4xID0gbWF4SW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjE6IEZlaGxlciBiZWkgVHlwICcnezJ9JycuIG1heEluY2x1c2l2ZS1XZXJ0ID0nJ3swfScnIG11c3MgPD0gbWF4SW5jbHVzaXZlIGRlcyBCYXNpc3R5cHMgJyd7MX0nJyBzZWluLgotICAgICAgICBtYXhJbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMiA9IG1heEluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4yOiBGZWhsZXIgYmVpIFR5cCAnJ3syfScnLiBtYXhJbmNsdXNpdmUtV2VydCA9Jyd7MH0nJyBtdXNzIDwgbWF4RXhjbHVzaXZlIGRlcyBCYXNpc3R5cHMgJyd7MX0nJyBzZWluLgotICAgICAgICBtYXhJbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMyA9IG1heEluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4zOiBGZWhsZXIgYmVpIFR5cCAnJ3syfScnLiBtYXhJbmNsdXNpdmUtV2VydCA9Jyd7MH0nJyBtdXNzID49IG1heEluY2x1c2l2ZSBkZXMgQmFzaXN0eXBzICcnezF9Jycgc2Vpbi4KLSAgICAgICAgbWF4SW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjQgPSBtYXhJbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uNDogRmVobGVyIGJlaSBUeXAgJyd7Mn0nJy4gbWF4SW5jbHVzaXZlLVdlcnQgPScnezB9JycgbXVzcyA+IG1pbkV4Y2x1c2l2ZSBkZXMgQmFzaXN0eXBzICcnezF9Jycgc2Vpbi4KLSAgICAgICAgbWF4TGVuZ3RoLXZhbGlkLXJlc3RyaWN0aW9uID0gbWF4TGVuZ3RoLXZhbGlkLXJlc3RyaWN0aW9uOiBJbiBkZXIgRGVmaW5pdGlvbiB2b24gezJ9IG11c3MgbWF4TGVuZ3RoLVdlcnQgPSAnJ3swfScnIDw9IGRlbSBXZXJ0IGRlcyBCYXNpc3R5cHMgJyd7MX0nJyBzZWluLgotICAgICAgICBtZy1wcm9wcy1jb3JyZWN0LjIgPSBtZy1wcm9wcy1jb3JyZWN0LjI6IFp5a2xpc2NoZSBEZWZpbml0aW9uZW4gZlx1MDBGQ3IgR3J1cHBlICcnezB9JycgZXJtaXR0ZWx0LiBSZWt1cnNpdmVzIEZvbGdlbiBkZXIgJ3sndGVybSd9Jy1XZXJ0ZSBkZXIgUGFydGlrZWwgZlx1MDBGQ2hydCB6dSBlaW5lbSBQYXJ0aWtlbCwgZGVzc2VuICd7J3Rlcm0nfScgZGllIEdydXBwZSBzZWxic3QgaXN0LgotICAgICAgICBtaW5FeGNsdXNpdmUtbGVzcy10aGFuLWVxdWFsLXRvLW1heEV4Y2x1c2l2ZSA9IG1pbkV4Y2x1c2l2ZS1sZXNzLXRoYW4tZXF1YWwtdG8tbWF4RXhjbHVzaXZlOiBJbiBkZXIgRGVmaW5pdGlvbiB2b24gezJ9IG11c3MgbWluRXhjbHVzaXZlLVdlcnQgPSAnJ3swfScnIDw9IG1heEV4Y2x1c2l2ZS1XZXJ0ID0gJyd7MX0nJyBzZWluLgotICAgICAgICBtaW5FeGNsdXNpdmUtbGVzcy10aGFuLW1heEluY2x1c2l2ZSA9IG1pbkV4Y2x1c2l2ZS1sZXNzLXRoYW4tbWF4SW5jbHVzaXZlOiBJbiBkZXIgRGVmaW5pdGlvbiB2b24gezJ9IG11c3MgbWluRXhjbHVzaXZlLVdlcnQgPSAnJ3swfScnIDwgbWF4SW5jbHVzaXZlLVdlcnQgPSAnJ3sxfScnIHNlaW4uCi0gICAgICAgIG1pbkV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4xID0gbWluRXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjE6IEZlaGxlciBiZWkgVHlwICcnezJ9JycuIG1pbkV4Y2x1c2l2ZS1XZXJ0ID0nJ3swfScnIG11c3MgPj0gbWluRXhjbHVzaXZlIGRlcyBCYXNpc3R5cHMgJyd7MX0nJyBzZWluLgotICAgICAgICBtaW5FeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMiA9IG1pbkV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4yOiBGZWhsZXIgYmVpIFR5cCAnJ3syfScnLiBtaW5FeGNsdXNpdmUtV2VydCA9Jyd7MH0nJyBtdXNzIDw9IG1heEluY2x1c2l2ZSBkZXMgQmFzaXN0eXBzICcnezF9Jycgc2Vpbi4KLSAgICAgICAgbWluRXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjMgPSBtaW5FeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMzogRmVobGVyIGJlaSBUeXAgJyd7Mn0nJy4gbWluRXhjbHVzaXZlLVdlcnQgPScnezB9JycgbXVzcyA+PSBtaW5JbmNsdXNpdmUgZGVzIEJhc2lzdHlwcyAnJ3sxfScnIHNlaW4uCi0gICAgICAgIG1pbkV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi40ID0gbWluRXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjQ6IEZlaGxlciBiZWkgVHlwICcnezJ9JycuIG1pbkV4Y2x1c2l2ZS1XZXJ0ID0nJ3swfScnIG11c3MgPCBtYXhFeGNsdXNpdmUgZGVzIEJhc2lzdHlwcyAnJ3sxfScnIHNlaW4uCi0gICAgICAgIG1pbkluY2x1c2l2ZS1sZXNzLXRoYW4tZXF1YWwtdG8tbWF4SW5jbHVzaXZlID0gbWluSW5jbHVzaXZlLWxlc3MtdGhhbi1lcXVhbC10by1tYXhJbmNsdXNpdmU6IEluIGRlciBEZWZpbml0aW9uIHZvbiB7Mn0gbXVzcyBtaW5JbmNsdXNpdmUtV2VydCA9ICcnezB9JycgPD0gbWF4SW5jbHVzaXZlLVdlcnQgPSAnJ3sxfScnIHNlaW4uCi0gICAgICAgIG1pbkluY2x1c2l2ZS1sZXNzLXRoYW4tbWF4RXhjbHVzaXZlID0gbWluSW5jbHVzaXZlLWxlc3MtdGhhbi1tYXhFeGNsdXNpdmU6IEluIGRlciBEZWZpbml0aW9uIHZvbiB7Mn0gbXVzcyBtaW5JbmNsdXNpdmUtV2VydCA9ICcnezB9JycgPCBtYXhFeGNsdXNpdmUtV2VydCA9ICcnezF9Jycgc2Vpbi4KLSAgICAgICAgbWluSW5jbHVzaXZlLW1pbkV4Y2x1c2l2ZSA9IG1pbkluY2x1c2l2ZS1taW5FeGNsdXNpdmU6IEVzIGdpbHQgYWxzIEZlaGxlciwgd2VubiBzb3dvaGwgbWluSW5jbHVzaXZlIGFscyBhdWNoIG1pbkV4Y2x1c2l2ZSBmXHUwMEZDciBkZW5zZWxiZW4gRGF0ZW50eXAgYW5nZWdlYmVuIHdlcmRlbi4gSW4gezJ9IGdpbHQ6IG1pbkluY2x1c2l2ZSA9ICcnezB9JycgdW5kIG1pbkV4Y2x1c2l2ZSA9ICcnezF9JycuCi0gICAgICAgIG1pbkluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4xID0gbWluSW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjE6IEZlaGxlciBiZWkgVHlwICcnezJ9JycuIG1pbkluY2x1c2l2ZS1XZXJ0ID0nJ3swfScnIG11c3MgPj0gbWluSW5jbHVzaXZlIGRlcyBCYXNpc3R5cHMgJyd7MX0nJyBzZWluLgotICAgICAgICBtaW5JbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMiA9IG1pbkluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4yOiBGZWhsZXIgYmVpIFR5cCAnJ3syfScnLiBtaW5JbmNsdXNpdmUtV2VydCA9Jyd7MH0nJyBtdXNzIDw9IG1heEluY2x1c2l2ZSBkZXMgQmFzaXN0eXBzICcnezF9Jycgc2Vpbi4KLSAgICAgICAgbWluSW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjMgPSBtaW5JbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMzogRmVobGVyIGJlaSBUeXAgJyd7Mn0nJy4gbWluSW5jbHVzaXZlLVdlcnQgPScnezB9JycgbXVzcyA+IG1pbkV4Y2x1c2l2ZSBkZXMgQmFzaXN0eXBzICcnezF9Jycgc2Vpbi4KLSAgICAgICAgbWluSW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjQgPSBtaW5JbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uNDogRmVobGVyIGJlaSBUeXAgJyd7Mn0nJy4gbWluSW5jbHVzaXZlLVdlcnQgPScnezB9JycgbXVzcyA8IG1heEV4Y2x1c2l2ZSBkZXMgQmFzaXN0eXBzICcnezF9Jycgc2Vpbi4KLSAgICAgICAgbWluTGVuZ3RoLWxlc3MtdGhhbi1lcXVhbC10by1tYXhMZW5ndGggPSBtaW5MZW5ndGgtbGVzcy10aGFuLWVxdWFsLXRvLW1heExlbmd0aDogSW4gZGVyIERlZmluaXRpb24gdm9uIHsyfSBtdXNzIGRlciBXZXJ0IHZvbiBtaW5MZW5ndGggPSAnJ3swfScnIDwgZGVtIFdlcnQgdm9uIG1heExlbmd0aCA9ICcnezF9Jycgc2Vpbi4KLSAgICAgICAgbWluTGVuZ3RoLXZhbGlkLXJlc3RyaWN0aW9uID0gbWluTGVuZ3RoLXZhbGlkLXJlc3RyaWN0aW9uOiBJbiBkZXIgRGVmaW5pdGlvbiB2b24gezJ9IG11c3MgbWluTGVuZ3RoID0gJyd7MH0nJyA+PSBkZW0gV2VydCBkZXMgQmFzaXN0eXBzICcnezF9Jycgc2Vpbi4KLSAgICAgICAgbm8teG1sbnMgPSBuby14bWxuczoge25hbWV9IGVpbmVyIEF0dHJpYnV0ZGVrbGFyYXRpb24gZGFyZiBuaWNodCBtaXQgJ3htbG5zJyBcdTAwRkNiZXJlaW5zdGltbWVuLgotICAgICAgICBuby14c2kgPSBuby14c2k6ICd7J3RhcmdldCBuYW1lc3BhY2UnfScgZWluZXIgQXR0cmlidXRkZWtsYXJhdGlvbiBkYXJmIG5pY2h0IG1pdCAnJ3swfScnIFx1MDBGQ2JlcmVpbnN0aW1tZW4uCi0gICAgICAgIHAtcHJvcHMtY29ycmVjdC4yLjEgPSBwLXByb3BzLWNvcnJlY3QuMi4xOiBJbiBkZXIgRGVrbGFyYXRpb24gdm9uICcnezB9JycgaXN0IGRlciBXZXJ0IHZvbiAnJ21pbk9jY3VycycnICcnezF9JycsIGVyIGRhcmYgYWJlciBuaWNodCBnclx1MDBGNlx1MDBERmVyIGFscyBkZXIgV2VydCB2b24gJydtYXhPY2N1cnMnJyBzZWluLCBkZXIgJyd7Mn0nJyBsYXV0ZXQuCi0gICAgICAgIHJjYXNlLU1hcEFuZFN1bS4xID0gcmNhc2UtTWFwQW5kU3VtLjE6IEVzIGlzdCBrZWluZSB2b2xsc3RcdTAwRTRuZGlnZSBGdW5rdGlvbnN6dW9yZG51bmcgendpc2NoZW4gZGVuIFBhcnRpa2VsbiB2b3JoYW5kZW4uCi0gICAgICAgIHJjYXNlLU1hcEFuZFN1bS4yID0gcmNhc2UtTWFwQW5kU3VtLjI6IFZvcmtvbW1lbnNiZXJlaWNoIGRlciBHcnVwcGUgKHswfSx7MX0pIGlzdCBrZWluZSBnXHUwMEZDbHRpZ2UgRWluc2Noclx1MDBFNG5rdW5nIGRlcyBWb3Jrb21tZW5zYmVyZWljaHMgZGVyIEJhc2lzZ3J1cHBlICh7Mn0sezN9KS4KLSAgICAgICAgcmNhc2UtTmFtZUFuZFR5cGVPSy4xID0gcmNhc2UtTmFtZUFuZFR5cGVPSy4xOiBFbGVtZW50ZSBoYWJlbiBOYW1lbiB1bmQgWmllbC1OYW1lc3BhY2VzLCBkaWUgbmljaHQgaWRlbnRpc2NoIHNpbmQ6IEVsZW1lbnQgJyd7MH0nJyBpbiBOYW1lc3BhY2UgJyd7MX0nJyB1bmQgRWxlbWVudCAnJ3syfScnIGluIE5hbWVzcGFjZSAnJ3szfScnLgotICAgICAgICByY2FzZS1OYW1lQW5kVHlwZU9LLjIgPSByY2FzZS1OYW1lQW5kVHlwZU9LLjI6IEZlaGxlciBiZWltIFBhcnRpa2VsLCBkZXNzZW4gJ3sndGVybSd9JyBkaWUgRWxlbWVudGRla2xhcmF0aW9uICcnezB9JycgaXN0LiAneyduaWxsYWJsZSd9JyBpc3QgYmVpIGRlciBFbGVtZW50ZGVrbGFyYXRpb24gJyd0cnVlJycsIGFiZXIgZGFzIGVudHNwcmVjaGVuZGUgUGFydGlrZWwgaW0gQmFzaXN0eXAgaGF0IGVpbmUgRWxlbWVudGRla2xhcmF0aW9uLCBiZWkgZGVyICd7J25pbGxhYmxlJ30nICcnZmFsc2UnJyBpc3QuCi0gICAgICAgIHJjYXNlLU5hbWVBbmRUeXBlT0suMyA9IHJjYXNlLU5hbWVBbmRUeXBlT0suMzogRmVobGVyIGJlaW0gUGFydGlrZWwsIGRlc3NlbiAneyd0ZXJtJ30nIGRpZSBFbGVtZW50ZGVrbGFyYXRpb24gJyd7MH0nJyBpc3QuIERlciBWb3Jrb21tZW5zYmVyZWljaCAoezF9LHsyfSkgaXN0IGtlaW5lIGdcdTAwRkNsdGlnZSBFaW5zY2hyXHUwMEU0bmt1bmcgZGVzIEJlcmVpY2hzICh7M30sezR9KSBkZXMgZW50c3ByZWNoZW5kZW4gUGFydGlrZWxzIGltIEJhc2lzdHlwLgotICAgICAgICByY2FzZS1OYW1lQW5kVHlwZU9LLjQuYSA9IHJjYXNlLU5hbWVBbmRUeXBlT0suNC5hOiBFbGVtZW50ICcnezB9JycgaXN0IG5pY2h0IGZlc3QsIGFiZXIgZGFzIGVudHNwcmVjaGVuZGUgRWxlbWVudCBpbSBCYXNpc3R5cCBpc3QgZmVzdCBtaXQgV2VydCAnJ3sxfScnLgotICAgICAgICByY2FzZS1OYW1lQW5kVHlwZU9LLjQuYiA9IHJjYXNlLU5hbWVBbmRUeXBlT0suNC5iOiBFbGVtZW50ICcnezB9JycgaXN0IGZlc3QgbWl0IGRlbSBXZXJ0ICcnezF9JycsIGFiZXIgZGFzIGVudHNwcmVjaGVuZGUgRWxlbWVudCBpbSBCYXNpc3R5cCBpc3QgZmVzdCBtaXQgV2VydCAnJ3syfScnLgotICAgICAgICByY2FzZS1OYW1lQW5kVHlwZU9LLjUgPSByY2FzZS1OYW1lQW5kVHlwZU9LLjU6IElkZW50aXR5IENvbnN0cmFpbnRzIGZcdTAwRkNyIEVsZW1lbnQgJyd7MH0nJyBzaW5kIGtlaW5lIFRlaWxtZW5nZSBkZXIgQ29uc3RyYWludHMgaW4gZGVyIEJhc2lzLgotICAgICAgICByY2FzZS1OYW1lQW5kVHlwZU9LLjYgPSByY2FzZS1OYW1lQW5kVHlwZU9LLjY6IERpZSB1bnp1bFx1MDBFNHNzaWdlbiBTdWJzdGl0dXRpb25lbiBmXHUwMEZDciBFbGVtZW50ICcnezB9Jycgc2luZCBrZWluZSBPYmVybWVuZ2UgZGVyIFN1YnN0aXR1dGlvbmVuIGluIGRlciBCYXNpcy4KLSAgICAgICAgcmNhc2UtTmFtZUFuZFR5cGVPSy43ID0gcmNhc2UtTmFtZUFuZFR5cGVPSy43OiBUeXAgZGVzIEVsZW1lbnRzICcnezB9JycgJyd7MX0nJyB3dXJkZSBuaWNodCB2b20gVHlwIGRlcyBCYXNpc2VsZW1lbnRzICcnezJ9JycgYWJnZWxlaXRldC4KLSAgICAgICAgcmNhc2UtTlNDb21wYXQuMSA9IHJjYXNlLU5TQ29tcGF0LjE6IEVsZW1lbnQgJyd7MH0nJyBoYXQgZGVuIE5hbWVzcGFjZSAnJ3sxfScnLiBEaWVzIHdpcmQgdm9tIFBsYXR6aGFsdGVyIGluIGRlciBCYXNpcyBuaWNodCB6dWdlbGFzc2VuLgotICAgICAgICByY2FzZS1OU0NvbXBhdC4yID0gcmNhc2UtTlNDb21wYXQuMjogRmVobGVyIGJlaW0gUGFydGlrZWwsIGRlc3NlbiAneyd0ZXJtJ30nIGRpZSBFbGVtZW50ZGVrbGFyYXRpb24gJyd7MH0nJyBpc3QuIERlciBWb3Jrb21tZW5zYmVyZWljaCAoezF9LHsyfSkgaXN0IGtlaW5lIGdcdTAwRkNsdGlnZSBFaW5zY2hyXHUwMEU0bmt1bmcgZGVzIEJlcmVpY2hzICh7M30sezR9KSBkZXMgZW50c3ByZWNoZW5kZW4gUGFydGlrZWxzIGltIEJhc2lzdHlwLgotICAgICAgICByY2FzZS1OU1JlY3Vyc2VDaGVja0NhcmRpbmFsaXR5LjEgPSByY2FzZS1OU1JlY3Vyc2VDaGVja0NhcmRpbmFsaXR5LjE6IEVzIGlzdCBrZWluZSB2b2xsc3RcdTAwRTRuZGlnZSBGdW5rdGlvbnN6dW9yZG51bmcgendpc2NoZW4gZGVuIFBhcnRpa2VsbiB2b3JoYW5kZW4uCi0gICAgICAgIHJjYXNlLU5TUmVjdXJzZUNoZWNrQ2FyZGluYWxpdHkuMiA9IHJjYXNlLU5TUmVjdXJzZUNoZWNrQ2FyZGluYWxpdHkuMjogVm9ya29tbWVuc2JlcmVpY2ggZGVyIEdydXBwZSAoezB9LHsxfSkgaXN0IGtlaW5lIGdcdTAwRkNsdGlnZSBFaW5zY2hyXHUwMEU0bmt1bmcgZGVzIEJlcmVpY2hzIGRlcyBCYXNpc3BsYXR6aGFsdGVycyAoezJ9LHszfSkuCi0gICAgICAgIHJjYXNlLU5TU3Vic2V0LjEgPSByY2FzZS1OU1N1YnNldC4xOiBQbGF0emhhbHRlciBpc3Qga2VpbmUgVGVpbG1lbmdlIGRlcyBlbnRzcHJlY2hlbmRlbiBQbGF0emhhbHRlcnMgaW4gZGVyIEJhc2lzLgotICAgICAgICByY2FzZS1OU1N1YnNldC4yID0gcmNhc2UtTlNTdWJzZXQuMjogVm9ya29tbWVuc2JlcmVpY2ggZGVzIFBsYXR6aGFsdGVycyAoezB9LHsxfSkgaXN0IGtlaW5lIGdcdTAwRkNsdGlnZSBFaW5zY2hyXHUwMEU0bmt1bmcgZGVzIEJlcmVpY2hzIGluIGRlciBCYXNpcyAoezJ9LHszfSkuCi0gICAgICAgIHJjYXNlLU5TU3Vic2V0LjMgPSByY2FzZS1OU1N1YnNldC4zOiBQcm96ZXNzY29udGVudCBkZXMgUGxhdHpoYWx0ZXJzICgnJ3swfScnKSBpc3Qgc2Nod1x1MDBFNGNoZXIgYWxzIGRlciBpbiBkZXIgQmFzaXMgJyd7MX0nJy4KLSAgICAgICAgcmNhc2UtUmVjdXJzZS4xID0gcmNhc2UtUmVjdXJzZS4xOiBWb3Jrb21tZW5zYmVyZWljaCBkZXIgR3J1cHBlICh7MH0sezF9KSBpc3Qga2VpbmUgZ1x1MDBGQ2x0aWdlIEVpbnNjaHJcdTAwRTRua3VuZyBkZXMgVm9ya29tbWVuc2JlcmVpY2hzIGRlciBCYXNpc2dydXBwZSAoezJ9LHszfSkuCi0gICAgICAgIHJjYXNlLVJlY3Vyc2UuMiA9IHJjYXNlLVJlY3Vyc2UuMjogRXMgaXN0IGtlaW5lIHZvbGxzdFx1MDBFNG5kaWdlIEZ1bmt0aW9uc3p1b3JkbnVuZyB6d2lzY2hlbiBkZW4gUGFydGlrZWxuIHZvcmhhbmRlbi4KLSAgICAgICAgcmNhc2UtUmVjdXJzZUxheC4xID0gcmNhc2UtUmVjdXJzZUxheC4xOiBWb3Jrb21tZW5zYmVyZWljaCBkZXIgR3J1cHBlICh7MH0sezF9KSBpc3Qga2VpbmUgZ1x1MDBGQ2x0aWdlIEVpbnNjaHJcdTAwRTRua3VuZyBkZXMgVm9ya29tbWVuc2JlcmVpY2hzIGRlciBCYXNpc2dydXBwZSAoezJ9LHszfSkuCi0gICAgICAgIHJjYXNlLVJlY3Vyc2VMYXguMiA9IHJjYXNlLVJlY3Vyc2VMYXguMjogRXMgaXN0IGtlaW5lIHZvbGxzdFx1MDBFNG5kaWdlIEZ1bmt0aW9uc3p1b3JkbnVuZyB6d2lzY2hlbiBkZW4gUGFydGlrZWxuIHZvcmhhbmRlbi4KLSAgICAgICAgcmNhc2UtUmVjdXJzZVVub3JkZXJlZC4xID0gcmNhc2UtUmVjdXJzZVVub3JkZXJlZC4xOiBWb3Jrb21tZW5zYmVyZWljaCBkZXIgR3J1cHBlICh7MH0sezF9KSBpc3Qga2VpbmUgZ1x1MDBGQ2x0aWdlIEVpbnNjaHJcdTAwRTRua3VuZyBkZXMgVm9ya29tbWVuc2JlcmVpY2hzIGRlciBCYXNpc2dydXBwZSAoezJ9LHszfSkuCi0gICAgICAgIHJjYXNlLVJlY3Vyc2VVbm9yZGVyZWQuMiA9IHJjYXNlLVJlY3Vyc2VVbm9yZGVyZWQuMjogRXMgaXN0IGtlaW5lIHZvbGxzdFx1MDBFNG5kaWdlIEZ1bmt0aW9uc3p1b3JkbnVuZyB6d2lzY2hlbiBkZW4gUGFydGlrZWxuIHZvcmhhbmRlbi4KLSMgICAgICAgIFdlJ3JlIHVzaW5nIHNjaC1wcm9wcy1jb3JyZWN0LjIgaW5zdGVhZCBvZiB0aGUgb2xkIHNyYy1yZWRlZmluZS4xCi0jICAgICAgICBzcmMtcmVkZWZpbmUuMSA9IHNyYy1yZWRlZmluZS4xOiBUaGUgY29tcG9uZW50ICcnezB9JycgaXMgYmVnaW4gcmVkZWZpbmVkLCBidXQgaXRzIGNvcnJlc3BvbmRpbmcgY29tcG9uZW50IGlzbid0IGluIHRoZSBzY2hlbWEgZG9jdW1lbnQgYmVpbmcgcmVkZWZpbmVkICh3aXRoIG5hbWVzcGFjZSAnJ3syfScnKSwgYnV0IGluIGEgZGlmZmVyZW50IGRvY3VtZW50LCB3aXRoIG5hbWVzcGFjZSAnJ3sxfScnLgotICAgICAgICBzY2gtcHJvcHMtY29ycmVjdC4yID0gc2NoLXByb3BzLWNvcnJlY3QuMjogRWluIFNjaGVtYSBrYW5uIG5pY2h0IHp3ZWkgZ2xvYmFsZSBLb21wb25lbnRlbiBtaXQgZGVtc2VsYmVuIE5hbWVuIGVudGhhbHRlbi4gRGllc2VzIFNjaGVtYSBlbnRoXHUwMEU0bHQgendlaSBWb3Jrb21tZW4gdm9uICcnezB9JycuCi0gICAgICAgIHN0LXByb3BzLWNvcnJlY3QuMiA9IHN0LXByb3BzLWNvcnJlY3QuMjogWnlrbGlzY2hlIERlZmluaXRpb25lbiB3dXJkZW4gZlx1MDBGQ3IgU2ltcGxlIFR5cGUgJyd7MH0nJyBlcm1pdHRlbHQuIERpZXMgYmVkZXV0ZXQsIGRhc3MgJyd7MH0nJyBpbiBkZXIgZWlnZW5lbiBUeXBoaWVyYXJjaGllIGVudGhhbHRlbiBpc3QuIERpZXMgaXN0IGVpbiBGZWhsZXIuCi0gICAgICAgIHN0LXByb3BzLWNvcnJlY3QuMyA9IHN0LXByb3BzLWNvcnJlY3QuMzogRmVobGVyIGJlaSBUeXAgJyd7MH0nJy4gRGVyIFdlcnQgdm9uICd7J2ZpbmFsJ30nIGRlciAneydiYXNlIHR5cGUgZGVmaW5pdGlvbid9JyAnJ3sxfScnIGxcdTAwRTRzc3Qga2VpbmUgQWJsZWl0dW5nIGR1cmNoIEVpbnNjaHJcdTAwRTRua3VuZyB6dS4KLSAgICAgICAgdG90YWxEaWdpdHMtdmFsaWQtcmVzdHJpY3Rpb24gPSB0b3RhbERpZ2l0cy12YWxpZC1yZXN0cmljdGlvbjogSW4gZGVyIERlZmluaXRpb24gdm9uIHsyfSBpc3QgZGVyIFdlcnQgJyd7MH0nJyBmXHUwMEZDciBGYWNldCAnJ3RvdGFsRGlnaXRzJycgdW5nXHUwMEZDbHRpZywgZGEgZXIgPD0gZGVtIFdlcnQgZlx1MDBGQ3IgJyd0b3RhbERpZ2l0cycnIHNlaW4gbXVzcywgZGVyIGluIGVpbmVtIGRlciBWb3JnXHUwMEU0bmdlcnR5cGVuIGF1ZiAnJ3sxfScnIGdlc2V0enQgd3VyZGUuCi0gICAgICAgIHdoaXRlU3BhY2UtdmFsaWQtcmVzdHJpY3Rpb24uMSA9IHdoaXRlU3BhY2UtdmFsaWQtcmVzdHJpY3Rpb24uMTogSW4gZGVyIERlZmluaXRpb24gdm9uIHswfSBpc3QgZGVyIFdlcnQgJyd7MX0nJyBmXHUwMEZDciBGYWNldCAnJ3doaXRlc3BhY2UnJyB1bmdcdTAwRkNsdGlnLCBkYSBkZXIgV2VydCBmXHUwMEZDciAnJ3doaXRlc3BhY2UnJyBpbiBlaW5lbSBkZXIgVm9yZ1x1MDBFNG5nZXJ0eXBlbiBhdWYgJydjb2xsYXBzZScnIGdlc2V0enQgd3VyZGUuCi0gICAgICAgIHdoaXRlU3BhY2UtdmFsaWQtcmVzdHJpY3Rpb24uMiA9IHdoaXRlU3BhY2UtdmFsaWQtcmVzdHJpY3Rpb24uMjogSW4gZGVyIERlZmluaXRpb24gdm9uIHswfSBpc3QgZGVyIFdlcnQgJydwcmVzZXJ2ZScnIGZcdTAwRkNyIEZhY2V0ICcnd2hpdGVzcGFjZScnIHVuZ1x1MDBGQ2x0aWcsIGRhIGRlciBXZXJ0IGZcdTAwRkNyICcnd2hpdGVzcGFjZScnIGluIGVpbmVtIGRlciBWb3JnXHUwMEU0bmdlcnR5cGVuIGF1ZiAnJ3JlcGxhY2UnJyBnZXNldHp0IHd1cmRlLgotCi0jc2NoZW1hIGZvciBTY2hlbWFzCi0KLSAgICAgICAgczRzLWF0dC1pbnZhbGlkLXZhbHVlID0gczRzLWF0dC1pbnZhbGlkLXZhbHVlOiBVbmdcdTAwRkNsdGlnZXIgQXR0cmlidXR3ZXJ0IGZcdTAwRkNyICcnezF9JycgaW4gRWxlbWVudCAnJ3swfScnLiBBdWZnZXplaWNobmV0ZXIgR3J1bmQ6IHsyfQotICAgICAgICBzNHMtYXR0LW11c3QtYXBwZWFyID0gczRzLWF0dC1tdXN0LWFwcGVhcjogQXR0cmlidXQgJyd7MX0nJyBtdXNzIGluIEVsZW1lbnQgJyd7MH0nJyB2b3Jrb21tZW4uCi0gICAgICAgIHM0cy1hdHQtbm90LWFsbG93ZWQgPSBzNHMtYXR0LW5vdC1hbGxvd2VkOiBBdHRyaWJ1dCAnJ3sxfScnIGRhcmYgbmljaHQgaW4gRWxlbWVudCAnJ3swfScnIHZvcmtvbW1lbi4KLSAgICAgICAgczRzLWVsdC1pbnZhbGlkID0gczRzLWVsdC1pbnZhbGlkOiBFbGVtZW50ICcnezB9JycgaXN0IGtlaW4gZ1x1MDBGQ2x0aWdlcyBFbGVtZW50IGluIGVpbmVtIFNjaGVtYWRva3VtZW50LgotICAgICAgICBzNHMtZWx0LW11c3QtbWF0Y2guMSA9IHM0cy1lbHQtbXVzdC1tYXRjaC4xOiBDb250ZW50IHZvbiAnJ3swfScnIG11c3MgezF9IGVudHNwcmVjaGVuLiBCZWltIFN0YXJ0IGJlaSB7Mn0gaXN0IGVpbiBQcm9ibGVtIGF1ZmdldHJldGVuLgotICAgICAgICBzNHMtZWx0LW11c3QtbWF0Y2guMiA9IHM0cy1lbHQtbXVzdC1tYXRjaC4yOiBDb250ZW50IHZvbiAnJ3swfScnIG11c3MgezF9IGVudHNwcmVjaGVuLiBOaWNodCBnZW5cdTAwRkNnZW5kIEVsZW1lbnRlIGdlZnVuZGVuLgotICAgICAgICAjIHRoZSAiaW52YWxpZC1jb250ZW50IiBtZXNzYWdlcyBwcm92aWRlIGxlc3MgaW5mb3JtYXRpb24gdGhhbiB0aGUgIm11c3QtbWF0Y2giIGNvdW50ZXJwYXJ0cyBhYm92ZS4gVGhleSdyZSB1c2VkIGZvciBjb21wbGV4IHR5cGVzIHdoZW4gcHJvdmlkaW5nIGEgIm1hdGNoIiB3b3VsZCBiZSBhbiBpbmZvcm1hdGlvbiBkdW1wCi0gICAgICAgIHM0cy1lbHQtaW52YWxpZC1jb250ZW50LjEgPSBzNHMtZWx0LWludmFsaWQtY29udGVudC4xOiBDb250ZW50IHZvbiAnJ3swfScnIGlzdCB1bmdcdTAwRkNsdGlnLiBFbGVtZW50ICcnezF9JycgaXN0IHVuZ1x1MDBGQ2x0aWcsIG5pY2h0IGFuIGRlciBlcndhcnRldGVuIFN0ZWxsZSBvZGVyIGtvbW10IHp1IG9mdCB2b3IuCi0gICAgICAgIHM0cy1lbHQtaW52YWxpZC1jb250ZW50LjIgPSBzNHMtZWx0LWludmFsaWQtY29udGVudC4yOiBDb250ZW50IHZvbiAnJ3swfScnIGlzdCB1bmdcdTAwRkNsdGlnLiBFbGVtZW50ICcnezF9JycgZGFyZiBuaWNodCBsZWVyIHNlaW4uCi0gICAgICAgIHM0cy1lbHQtaW52YWxpZC1jb250ZW50LjMgPSBzNHMtZWx0LWludmFsaWQtY29udGVudC4zOiBFbGVtZW50ZSBtaXQgZGVtIFR5cCAnJ3swfScnIGtcdTAwRjZubmVuIG5pY2h0IG5hY2ggRGVrbGFyYXRpb25lbiBhbHMgdW50ZXJnZW9yZG5ldGUgRWxlbWVudGUgZWluZXMgPHNjaGVtYT4tRWxlbWVudHMgdm9ya29tbWVuLgotICAgICAgICBzNHMtZWx0LXNjaGVtYS1ucyA9IHM0cy1lbHQtc2NoZW1hLW5zOiBOYW1lc3BhY2UgZGVzIEVsZW1lbnRzICcnezB9JycgbXVzcyBhdXMgZGVtIFNjaGVtYS1OYW1lc3BhY2UgJydodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYScnIHN0YW1tZW4uCi0gICAgICAgIHM0cy1lbHQtY2hhcmFjdGVyID0gczRzLWVsdC1jaGFyYWN0ZXI6IEluIGFuZGVyZW4gU2NoZW1hZWxlbWVudGVuIGFscyAnJ3hzOmFwcGluZm8nJyB1bmQgJyd4czpkb2N1bWVudGF0aW9uJycgc2luZCBudXIgTGVlcnN0ZWxsZW4genVsXHUwMEU0c3NpZy4gJyd7MH0nJyBnZWZ1bmRlbi4KLQotIyBjb2RlcyBub3QgZGVmaW5lZCBieSB0aGUgc3BlYwotCi0gICAgICAgIGMtZmllbGRzLXhwYXRocyA9IGMtZmllbGRzLXhwYXRoczogRmVsZHdlcnQgPSAnJ3swfScnIGlzdCB1bmdcdTAwRkNsdGlnLgotICAgICAgICBjLWdlbmVyYWwteHBhdGggPSBjLWdlbmVyYWwteHBhdGg6IEF1c2RydWNrICcnezB9JycgaXN0IHVuZ1x1MDBGQ2x0aWcgaW4gQmV6dWcgYXVmIGRpZSB2b20gWE1MLVNjaGVtYSB1bnRlcnN0XHUwMEZDdHp0ZSBYUGF0aC1UZWlsbWVuZ2UuCi0gICAgICAgIGMtZ2VuZXJhbC14cGF0aC1ucyA9IGMtZ2VuZXJhbC14cGF0aC1uczogTmFtZXNwYWNlLVByXHUwMEU0Zml4IGluIFhQYXRoLUF1c2RydWNrICcnezB9Jycgd2FyIGFuIGVpbmVuIE5hbWVzcGFjZSBnZWJ1bmRlbi4KLSAgICAgICAgYy1zZWxlY3Rvci14cGF0aCA9IGMtc2VsZWN0b3IteHBhdGg6IFNlbGVrdG9yLVdlcnQgPSAnJ3swfScnIGlzdCB1bmdcdTAwRkNsdGlnLiBTZWxla3Rvci1YUGF0aHMga1x1MDBGNm5uZW4ga2VpbmUgQXR0cmlidXRlIGVudGhhbHRlbi4KLSAgICAgICAgRW1wdHlUYXJnZXROYW1lc3BhY2UgPSBFbXB0eVRhcmdldE5hbWVzcGFjZTogSW4gU2NoZW1hZG9rdW1lbnQgJyd7MH0nJyBrYW5uIGRlciBXZXJ0IGRlcyAnJ3RhcmdldE5hbWVzcGFjZScnLUF0dHJpYnV0cyBrZWluZSBsZWVyZSBaZWljaGVuZm9sZ2Ugc2Vpbi4KLSAgICAgICAgRmFjZXRWYWx1ZUZyb21CYXNlID0gRmFjZXRWYWx1ZUZyb21CYXNlOiBJbiBkZXIgRGVrbGFyYXRpb24gdm9uIFR5cCAnJ3swfScnIG11c3MgZGVyIFdlcnQgJyd7MX0nJyB2b24gRmFjZXQgJyd7Mn0nJyBhdXMgZGVtIFdlcnRlYmVyZWljaCBkZXMgQmFzaXN0eXBzICcnezN9Jycgc3RhbW1lbi4KLSAgICAgICAgRml4ZWRGYWNldFZhbHVlID0gRml4ZWRGYWNldFZhbHVlOiBJbiBkZXIgRGVmaW5pdGlvbiB2b24gezN9IGlzdCBkZXIgV2VydCAnJ3sxfScnIGZcdTAwRkNyIEZhY2V0ICcnezB9JycgdW5nXHUwMEZDbHRpZywgZGEgZGVyIFdlcnQgZlx1MDBGQ3IgJyd7MH0nJyBpbiBlaW5lbSBkZXIgVm9yZ1x1MDBFNG5nZXJ0eXBlbiBhdWYgJyd7Mn0nJyBnZXNldHp0IHd1cmRlIHVuZCAnJ3snJ2ZpeGVkJ30nJycgPSB0cnVlIGlzdC4KLSAgICAgICAgSW52YWxpZFJlZ2V4ID0gSW52YWxpZFJlZ2V4OiBNdXN0ZXJ3ZXJ0ICcnezB9JycgaXN0IGtlaW4gZ1x1MDBGQ2x0aWdlciByZWd1bFx1MDBFNHJlciBBdXNkcnVjay4gRGVyIGdlbWVsZGV0ZSBGZWhsZXIgd2FyOiAnJ3sxfScnIGJlaSBTcGFsdGUgJyd7Mn0nJy4KLSAgICAgICAgTWF4T2NjdXJMaW1pdCA9IEFrdHVlbGxlIEtvbmZpZ3VyYXRpb24gZGVzIFBhcnNlcnMgbFx1MDBFNHNzdCBuaWNodCB6dSwgZGFzcyBlaW4gbWF4T2NjdXJzLUF0dHJpYnV0d2VydCBhdWYgZWluZW4gaFx1MDBGNmhlcmVuIFdlcnQgYWxzIHswfSBnZXNldHp0IHdpcmQuCi0gICAgICAgIFB1YmxpY1N5c3RlbU9uTm90YXRpb24gPSBQdWJsaWNTeXN0ZW1Pbk5vdGF0aW9uOiBNaW5kZXN0ZW5zIGVpbmVzIGRlciBFbGVtZW50ZSAncHVibGljJyB1bmQgJ3N5c3RlbScgbXVzcyBpbSBFbGVtZW50ICdub3RhdGlvbicgdm9ya29tbWVuLgotICAgICAgICBTY2hlbWFMb2NhdGlvbiA9IFNjaGVtYUxvY2F0aW9uOiBzY2hlbWFMb2NhdGlvbi1XZXJ0ID0gJyd7MH0nJyBtdXNzIGVpbmUgZ2VyYWRlIEFuemFobCBhbiBVUklzIGhhYmVuLgotICAgICAgICBUYXJnZXROYW1lc3BhY2UuMSA9IFRhcmdldE5hbWVzcGFjZS4xOiBOYW1lc3BhY2UgJyd7MH0nJyB3aXJkIGVyd2FydGV0LCBhYmVyIGRlciBaaWVsLU5hbWVzcGFjZSBkZXMgU2NoZW1hZG9rdW1lbnRzIGlzdCAnJ3sxfScnLgotICAgICAgICBUYXJnZXROYW1lc3BhY2UuMiA9IFRhcmdldE5hbWVzcGFjZS4yOiBLZWluIE5hbWVzcGFjZSB3aXJkIGVyd2FydGV0LCBhYmVyIGRhcyBTY2hlbWFkb2t1bWVudCBoYXQgZGVuIFppZWwtTmFtZXNwYWNlICcnezF9JycuCi0gICAgICAgIFVuZGVjbGFyZWRFbnRpdHkgPSBVbmRlY2xhcmVkRW50aXR5OiBFbnRpdHkgJyd7MH0nJyBpc3QgbmljaHQgZGVrbGFyaWVydC4KLSAgICAgICAgVW5kZWNsYXJlZFByZWZpeCA9IFVuZGVjbGFyZWRQcmVmaXg6ICcnezB9Jycga2FubiBuaWNodCBhbHMgUU5hbWUgYXVmZ2VsXHUwMEY2c3Qgd2VyZGVuOiBQclx1MDBFNGZpeCAnJ3sxfScnIGlzdCBuaWNodCBkZWtsYXJpZXJ0LgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MU2NoZW1hTWVzc2FnZXNfZXMucHJvcGVydGllcyBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hNTFNjaGVtYU1lc3NhZ2VzX2VzLnByb3BlcnRpZXMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDJlMjJjZWQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MU2NoZW1hTWVzc2FnZXNfZXMucHJvcGVydGllcworKysgL2Rldi9udWxsCkBAIC0xLDI5MSArMCwwIEBACi0jIFRoaXMgZmlsZSBjb250YWlucyBlcnJvciBhbmQgd2FybmluZyBtZXNzYWdlcyByZWxhdGVkIHRvIFhNTCBTY2hlbWEKLSMgVGhlIG1lc3NhZ2VzIGFyZSBhcnJhbmdlZCBpbiBrZXkgYW5kIHZhbHVlIHR1cGxlcyBpbiBhIExpc3RSZXNvdXJjZUJ1bmRsZS4KLSMKLQotICAgICAgICBCYWRNZXNzYWdlS2V5ID0gTm8gc2UgaGEgZW5jb250cmFkbyBlbCBtZW5zYWplIGRlIGVycm9yIGNvcnJlc3BvbmRpZW50ZSBhIGxhIGNsYXZlIGRlIG1lbnNhamUuCi0gICAgICAgIEZvcm1hdEZhaWxlZCA9IFNlIGhhIHByb2R1Y2lkbyB1biBlcnJvciBpbnRlcm5vIGFsIGZvcm1hdGVhciBlbCBzaWd1aWVudGUgbWVuc2FqZTpcbgotCi0jIEZvciBpbnRlcm5hbCB1c2UKLQotICAgICAgICBJbnRlcm5hbC1FcnJvciA9IEVycm9yIGludGVybm86IHswfS4KLSAgICAgICAgZHQtd2hpdGVzcGFjZSA9IEVsIHZhbG9yIGRlIGZhY2V0YSBkZSBlc3BhY2lvIGVuIGJsYW5jbyBubyBlc3RcdTAwRTEgZGlzcG9uaWJsZSBwYXJhIHNpbXBsZVR5cGUgZGUgdW5pXHUwMEYzbiAnJ3swfScnCi0gICAgICAgIEdyYW1tYXJDb25mbGljdCA9IFVuYSBkZSBsYXMgZ3JhbVx1MDBFMXRpY2FzIGRldnVlbHRhcyBkZWwgcG9vbCBkZSBncmFtXHUwMEUxdGljYSBkZWwgdXN1YXJpbyBlbnRyYSBlbiBjb25mbGljdG8gY29uIG90cmEgZ3JhbVx1MDBFMXRpY2EuCi0KLSMgSWRlbnRpdHkgY29uc3RyYWludHMKLQotICAgICAgICBBYnNlbnRLZXlWYWx1ZSA9IEVycm9yIGRlIHJlc3RyaWNjaVx1MDBGM24gZGUgaWRlbnRpZGFkIChjdmMtaWRlbnRpdHktY29uc3RyYWludC40LjIuMSk6IGVsIGVsZW1lbnRvICJ7MH0iIHRpZW5lIHVuYSBjbGF2ZSBzaW4gdmFsb3IuCi0gICAgICAgIER1cGxpY2F0ZUZpZWxkID0gQ29pbmNpZGVuY2lhIGR1cGxpY2FkYSBlbiBcdTAwRTFtYml0byBkZWwgY2FtcG8gInswfSIuCi0gICAgICAgIER1cGxpY2F0ZUtleSA9IFZhbG9yIGRlIGNsYXZlIGR1cGxpY2FkbyBbezB9XSBkZWNsYXJhZG8gcGFyYSBsYSByZXN0cmljY2lcdTAwRjNuIGRlIGlkZW50aWRhZCBkZWwgZWxlbWVudG8gInsxfSIuCi0gICAgICAgIER1cGxpY2F0ZVVuaXF1ZSA9IFZhbG9yIFx1MDBGQW5pY28gZHVwbGljYWRvIFt7MH1dIGRlY2xhcmFkbyBwYXJhIGxhIHJlc3RyaWNjaVx1MDBGM24gZGUgaWRlbnRpZGFkIGRlbCBlbGVtZW50byAiezF9Ii4KLSAgICAgICAgRmllbGRNdWx0aXBsZU1hdGNoID0gRXJyb3IgZGUgcmVzdHJpY2NpXHUwMEYzbiBkZSBpZGVudGlkYWQ6IGVsIGNhbXBvICJ7MH0iIGNvaW5jaWRlIGNvbiBtXHUwMEUxcyBkZSB1biB2YWxvciBlbiBlbCBcdTAwRTFtYml0byBkZSBzdSBzZWxlY3RvcjsgbG9zIGNhbXBvcyBkZWJlbiBjb2luY2lkaXIgY29uIHZhbG9yZXMgXHUwMEZBbmljb3MuCi0gICAgICAgIEZpeGVkRGlmZmVyc0Zyb21BY3R1YWwgPSBFbCBjb250ZW5pZG8gZGUgZXN0ZSBlbGVtZW50byBubyBlcyBlcXVpdmFsZW50ZSBhbCB2YWxvciBkZWwgYXRyaWJ1dG8gImZpeGVkIiBlbiBsYSBkZWNsYXJhY2lcdTAwRjNuIGRlbCBlbGVtZW50byBkZWwgZXNxdWVtYS4KLSAgICAgICAgS2V5TWF0Y2hlc05pbGxhYmxlID0gRXJyb3IgZGUgcmVzdHJpY2NpXHUwMEYzbiBkZSBpZGVudGlkYWQgKGN2Yy1pZGVudGl0eS1jb25zdHJhaW50LjQuMi4zKTogZWwgZWxlbWVudG8gInswfSIgdGllbmUgdW5hIGNsYXZlIHF1ZSBjb2luY2lkZSBjb24gdW4gZWxlbWVudG8gY3V5byB2YWxvciBkZSBQZXJtaXRlIE5pbGwgZXN0XHUwMEUxIGRlZmluaWRvIGVuIHRydWUuCi0gICAgICAgIEtleU5vdEVub3VnaFZhbHVlcyA9IE5vIHNlIGhhbiBlc3BlY2lmaWNhZG8gc3VmaWNpZW50ZXMgdmFsb3JlcyBwYXJhIGxhIHJlc3RyaWNjaVx1MDBGM24gZGUgaWRlbnRpZGFkIDxrZXkgbmFtZT0iezF9Ij4gZXNwZWNpZmljYWRhIHBhcmEgZWwgZWxlbWVudG8gInswfSIuCi0gICAgICAgIEtleU5vdEZvdW5kID0gTm8gc2UgaGEgZW5jb250cmFkbyBsYSBjbGF2ZSAnJ3swfScnIGNvbiBlbCB2YWxvciAnJ3sxfScnIHBhcmEgbGEgcmVzdHJpY2NpXHUwMEYzbiBkZSBpZGVudGlkYWQgZGVsIGVsZW1lbnRvICcnezJ9JycuCi0gICAgICAgIEtleVJlZk5vdEVub3VnaFZhbHVlcyA9IE5vIHNlIGhhbiBlc3BlY2lmaWNhZG8gc3VmaWNpZW50ZXMgdmFsb3JlcyBwYXJhIGxhIHJlc3RyaWNjaVx1MDBGM24gZGUgaWRlbnRpZGFkIDxrZXlyZWYgbmFtZT0iezF9Ij4gZXNwZWNpZmljYWRhIHBhcmEgZWwgZWxlbWVudG8gInswfSIuCi0gICAgICAgIEtleVJlZk91dE9mU2NvcGUgPSBFcnJvciBkZSByZXN0cmljY2lcdTAwRjNuIGRlIGlkZW50aWRhZDogbGEgcmVzdHJpY2NpXHUwMEYzbiBkZSBpZGVudGlkYWQgInswfSIgdGllbmUgdW5hIHJlZmVyZW5jaWEgZGUgY2xhdmUgcXVlIGhhY2UgcmVmZXJlbmNpYSBhIHVuYSBjbGF2ZSBvIGVsZW1lbnRvIFx1MDBGQW5pY28gcXVlIHNlIGVuY3VlbnRyYSBmdWVyYSBkZSBcdTAwRTFtYml0by4KLSAgICAgICAgS2V5UmVmUmVmZXJOb3RGb3VuZCA9IExhIGRlY2xhcmFjaVx1MDBGM24gZGUgcmVmZXJlbmNpYSBkZSBjbGF2ZSAiezB9IiBoYWNlIHJlZmVyZW5jaWEgYSB1bmEgY2xhdmUgZGVzY29ub2NpZGEgY29uIGVsIG5vbWJyZSAiezF9Ii4KLSAgICAgICAgVW5pcXVlTm90RW5vdWdoVmFsdWVzID0gTm8gc2UgaGFuIGVzcGVjaWZpY2FkbyBzdWZpY2llbnRlcyB2YWxvcmVzIHBhcmEgbGEgcmVzdHJpY2NpXHUwMEYzbiBkZSBpZGVudGlkYWQgPHVuaXF1ZT4gZXNwZWNpZmljYWRhIHBhcmEgZWwgZWxlbWVudG8gInswfSIuCi0gICAgICAgIFVua25vd25GaWVsZCA9IEVycm9yIGRlIHJlc3RyaWNjaVx1MDBGM24gZGUgaWRlbnRpZGFkIGludGVybm87IGNhbXBvIGRlc2Nvbm9jaWRvICJ7MH0iLgotCi0jIElkZWFsbHksIHdlIHNob3VsZCBvbmx5IHVzZSB0aGUgZm9sbG93aW5nIGVycm9yIGtleXMsIG5vdCB0aGUgb25lcyB1bmRlcgotIyAiSWRlbnRpdHkgY29uc3RyYWludHMiLiBBbmQgd2Ugc2hvdWxkIGNvdmVyIGFsbCBvZiB0aGUgZm9sbG93aW5nIGVycm9ycy4KLQotI3ZhbGlkYXRpb24gKDMuWC40KQotCi0gICAgICAgIGN2Yy1hdHRyaWJ1dGUuMyA9IGN2Yy1hdHRyaWJ1dGUuMzogRWwgdmFsb3IgJyd7Mn0nJyBkZWwgYXRyaWJ1dG8gJyd7MX0nJyBkZWwgZWxlbWVudG8gJyd7MH0nJyBubyBlcyB2XHUwMEUxbGlkbyBjb24gcmVzcGVjdG8gYSBzdSB0aXBvLCAnJ3szfScnLgotICAgICAgICBjdmMtYXR0cmlidXRlLjQgPSBjdmMtYXR0cmlidXRlLjQ6IEVsIHZhbG9yICcnezJ9JycgZGVsIGF0cmlidXRvICcnezF9JycgZGVsIGVsZW1lbnRvICcnezB9Jycgbm8gZXMgdlx1MDBFMWxpZG8gY29uIHJlc3BlY3RvIGEgc3UgJ3sndmFsdWUgY29uc3RyYWludCd9JyBmaWphLiBFbCBhdHJpYnV0byBkZWJlIHRlbmVyIHVuIHZhbG9yIGRlICcnezN9JycuCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuMi4xID0gY3ZjLWNvbXBsZXgtdHlwZS4yLjE6IEVsIGVsZW1lbnRvICcnezB9Jycgbm8gZGViZSB0ZW5lciBuaW5nXHUwMEZBbiBjYXJcdTAwRTFjdGVyIG5pIG5pbmdcdTAwRkFuIGVsZW1lbnRvIGRlIGluZm9ybWFjaVx1MDBGM24gZGUgZWxlbWVudG8gW3NlY3VuZGFyaW9zXSwgcG9ycXVlIGVsIHRpcG8gZGUgY29udGVuaWRvIGRlIHRpcG8gZXN0XHUwMEUxIHZhY1x1MDBFRG8uCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuMi4yID0gY3ZjLWNvbXBsZXgtdHlwZS4yLjI6IEVsIGVsZW1lbnRvICcnezB9Jycgbm8gZGViZSB0ZW5lciBuaW5nXHUwMEZBbiBlbGVtZW50byBbc2VjdW5kYXJpb3NdIHkgZWwgdmFsb3IgZGViZSBzZXIgdlx1MDBFMWxpZG8uCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuMi4zID0gY3ZjLWNvbXBsZXgtdHlwZS4yLjM6IEVsIGVsZW1lbnRvICcnezB9Jycgbm8gZGViZSB0ZW5lciBuaW5nXHUwMEZBbiBjYXJcdTAwRTFjdGVyIFtzZWN1bmRhcmlvc10sIHBvcnF1ZSBlbCB0aXBvIGRlIGNvbnRlbmlkbyBkZWwgdGlwbyBlcyBzXHUwMEYzbG8gZGUgZWxlbWVudG8uCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuMi40LmEgPSBjdmMtY29tcGxleC10eXBlLjIuNC5hOiBTZSBoYSBlbmNvbnRyYWRvIGNvbnRlbmlkbyBubyB2XHUwMEUxbGlkbyBhIHBhcnRpciBkZWwgZWxlbWVudG8gJyd7MH0nJy4gU2UgZXNwZXJhYmEgdW5vIGRlICcnezF9JycuCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuMi40LmIgPSBjdmMtY29tcGxleC10eXBlLjIuNC5iOiBFbCBjb250ZW5pZG8gZGVsIGVsZW1lbnRvICcnezB9Jycgbm8gZXN0XHUwMEUxIGNvbXBsZXRvLiBTZSBlc3BlcmFiYSB1bm8gZGUgJyd7MX0nJy4KLSAgICAgICAgY3ZjLWNvbXBsZXgtdHlwZS4yLjQuYyA9IGN2Yy1jb21wbGV4LXR5cGUuMi40LmM6IEVsIGNvbW9kXHUwMEVEbiBjb2luY2lkZW50ZSBlcyBlc3RyaWN0bywgcGVybyBubyBzZSBoYSBlbmNvbnRyYWRvIG5pbmd1bmEgZGVjbGFyYWNpXHUwMEYzbiBwYXJhIGVsIGVsZW1lbnRvICcnezB9JycuCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuMi40LmQgPSBjdmMtY29tcGxleC10eXBlLjIuNC5kOiBTZSBoYSBlbmNvbnRyYWRvIGNvbnRlbmlkbyBubyB2XHUwMEUxbGlkbyBhIHBhcnRpciBkZWwgZWxlbWVudG8gJyd7MH0nJy4gTm8gc2UgZXNwZXJhIG5pbmdcdTAwRkFuIGVsZW1lbnRvIHNlY3VuZGFyaW8gZW4gZXN0ZSBwdW50by4KLSAgICAgICAgY3ZjLWNvbXBsZXgtdHlwZS4yLjQuZSA9IGN2Yy1jb21wbGV4LXR5cGUuMi40LmQ6IFNlIGhhIGVuY29udHJhZG8gY29udGVuaWRvIG5vIHZcdTAwRTFsaWRvIGEgcGFydGlyIGRlbCBlbGVtZW50byAnJ3swfScnLiBObyBzZSBlc3BlcmEgbmluZ1x1MDBGQW4gZWxlbWVudG8gc2VjdW5kYXJpbyAnJ3sxfScnIGVuIGVzdGUgcHVudG8uCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuMy4xID0gY3ZjLWNvbXBsZXgtdHlwZS4zLjE6IEVsIHZhbG9yICcnezJ9JycgZGVsIGF0cmlidXRvICcnezF9JycgZGVsIGVsZW1lbnRvICcnezB9Jycgbm8gZXMgdlx1MDBFMWxpZG8gY29uIHJlc3BlY3RvIGFsIHVzbyBkZSBhdHJpYnV0byBjb3JyZXNwb25kaWVudGUuIEVsIGF0cmlidXRvICcnezF9JycgdGllbmUgdW4gdmFsb3IgZmlqbyBkZSAnJ3szfScnLgotICAgICAgICBjdmMtY29tcGxleC10eXBlLjMuMi4xID0gY3ZjLWNvbXBsZXgtdHlwZS4zLjIuMTogRWwgZWxlbWVudG8gJyd7MH0nJyBubyB0aWVuZSB1biBjb21vZFx1MDBFRG4gZGUgYXRyaWJ1dG8gcGFyYSBlbCBhdHJpYnV0byAnJ3sxfScnLgotICAgICAgICBjdmMtY29tcGxleC10eXBlLjMuMi4yID0gY3ZjLWNvbXBsZXgtdHlwZS4zLjIuMjogTm8gZXN0XHUwMEUxIHBlcm1pdGlkbyBxdWUgZWwgYXRyaWJ1dG8gJyd7MX0nJyBhcGFyZXpjYSBlbiBlbCBlbGVtZW50byAnJ3swfScnLgotICAgICAgICBjdmMtY29tcGxleC10eXBlLjQgPSBjdmMtY29tcGxleC10eXBlLjQ6IEVsIGF0cmlidXRvICcnezF9JycgZGViZSBhcGFyZWNlciBlbiBlbCBlbGVtZW50byAnJ3swfScnLgotICAgICAgICBjdmMtY29tcGxleC10eXBlLjUuMSA9IGN2Yy1jb21wbGV4LXR5cGUuNS4xOiBFbiBlbCBlbGVtZW50byAnJ3swfScnLCBlbCBhdHJpYnV0byAnJ3sxfScnIGVzIHVuIGlkZW50aWZpY2Fkb3IgZGUgY29tb2RcdTAwRURuLCBwZXJvIHlhIGV4aXN0ZSB1biBpZGVudGlmaWNhZG9yIGRlIGNvbW9kXHUwMEVEbiAnJ3syfScnLiBTXHUwMEYzbG8gcHVlZGUgZXhpc3RpciB1bm8uCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuNS4yID0gY3ZjLWNvbXBsZXgtdHlwZS41LjI6IEVuIGVsIGVsZW1lbnRvICcnezB9JycsIGVsIGF0cmlidXRvICcnezF9JycgZXMgdW4gaWRlbnRpZmljYWRvciBkZSBjb21vZFx1MDBFRG4sIHBlcm8geWEgZXhpc3RlIHVuIGF0cmlidXRvICcnezJ9JycgZGVyaXZhZG8gZGVsIGlkZW50aWZpY2Fkb3IgZW50cmUgbG9zICd7J2F0dHJpYnV0ZSB1c2VzJ30nLgotICAgICAgICBjdmMtZGF0YXR5cGUtdmFsaWQuMS4yLjEgPSBjdmMtZGF0YXR5cGUtdmFsaWQuMS4yLjE6ICcnezB9Jycgbm8gZXMgdW4gdmFsb3Igdlx1MDBFMWxpZG8gcGFyYSAnJ3sxfScnLgotICAgICAgICBjdmMtZGF0YXR5cGUtdmFsaWQuMS4yLjIgPSBjdmMtZGF0YXR5cGUtdmFsaWQuMS4yLjI6ICcnezB9Jycgbm8gZXMgdW4gdmFsb3Igdlx1MDBFMWxpZG8gZGUgdGlwbyBkZSBsaXN0YSAnJ3sxfScnLgotICAgICAgICBjdmMtZGF0YXR5cGUtdmFsaWQuMS4yLjMgPSBjdmMtZGF0YXR5cGUtdmFsaWQuMS4yLjM6ICcnezB9Jycgbm8gZXMgdW4gdmFsb3Igdlx1MDBFMWxpZG8gZGUgdGlwbyBkZSB1bmlcdTAwRjNuICcnezF9JycuCi0gICAgICAgIGN2Yy1lbHQuMSA9IGN2Yy1lbHQuMTogTm8gc2UgaGEgZW5jb250cmFkbyBsYSBkZWNsYXJhY2lcdTAwRjNuIGRlbCBlbGVtZW50byAnJ3swfScnLgotICAgICAgICBjdmMtZWx0LjIgPSBjdmMtZWx0LjI6IEVsIHZhbG9yIGRlICd7J2Fic3RyYWN0J30nIGVuIGxhIGRlY2xhcmFjaVx1MDBGM24gZGUgZWxlbWVudG8gcGFyYSAnJ3swfScnIGRlYmUgc2VyIGZhbHNlLgotICAgICAgICBjdmMtZWx0LjMuMSA9IGN2Yy1lbHQuMy4xOiBFbCBhdHJpYnV0byAnJ3sxfScnIG5vIGRlYmUgYXBhcmVjZXIgZW4gZWwgZWxlbWVudG8gJyd7MH0nJywgcG9ycXVlIGxhIHByb3BpZWRhZCAneyduaWxsYWJsZSd9JyBkZSAnJ3swfScnIHRpZW5lIGVsIHZhbG9yIGZhbHNlLgotICAgICAgICBjdmMtZWx0LjMuMi4xID0gY3ZjLWVsdC4zLjIuMTogRWwgZWxlbWVudG8gJyd7MH0nJyBubyBkZWJlIHRlbmVyIG5pbmdcdTAwRkFuIGNhclx1MDBFMWN0ZXIgbmkgaW5mb3JtYWNpXHUwMEYzbiBkZSBlbGVtZW50byBbc2VjdW5kYXJpb3NdLCBwb3JxdWUgc2UgaGEgZXNwZWNpZmljYWRvICcnezF9JycuCi0gICAgICAgIGN2Yy1lbHQuMy4yLjIgPSBjdmMtZWx0LjMuMi4yOiBObyBkZWJlIGhhYmVyIG5pbmdcdTAwRkFuIHZhbG9yIGZpam8gZGUgJ3sndmFsdWUgY29uc3RyYWludCd9JyBwYXJhIGVsIGVsZW1lbnRvICcnezB9JycsIHBvcnF1ZSBzZSBoYSBlc3BlY2lmaWNhZG8gJyd7MX0nJy4KLSAgICAgICAgY3ZjLWVsdC40LjEgPSBjdmMtZWx0LjQuMTogRWwgdmFsb3IgJyd7Mn0nJyBkZWwgYXRyaWJ1dG8gJyd7MX0nJyBkZWwgZWxlbWVudG8gJyd7MH0nJyBubyBlcyB1biBRTmFtZSB2XHUwMEUxbGlkby4KLSAgICAgICAgY3ZjLWVsdC40LjIgPSBjdmMtZWx0LjQuMjogTm8gc2UgcHVlZGUgcmVzb2x2ZXIgJyd7MX0nJyBlbiB1bmEgZGVmaW5pY2lcdTAwRjNuIGRlIHRpcG8gcGFyYSBlbCBlbGVtZW50byAnJ3swfScnLgotICAgICAgICBjdmMtZWx0LjQuMyA9IGN2Yy1lbHQuNC4zOiBFbCB0aXBvICcnezF9Jycgbm8gc2UgaGEgZGVyaXZhZG8gZGUgZm9ybWEgdlx1MDBFMWxpZGEgZGUgbGEgZGVmaW5pY2lcdTAwRjNuIGRlIHRpcG8gJyd7Mn0nJyBkZWwgZWxlbWVudG8gJyd7MH0nJy4KLSAgICAgICAgY3ZjLWVsdC41LjEuMSA9IGN2Yy1lbHQuNS4xLjE6ICd7J3ZhbHVlIGNvbnN0cmFpbnQnfScgJyd7Mn0nJyBkZWwgZWxlbWVudG8gJyd7MH0nJyBubyBlcyB1biB2YWxvciBwb3IgZGVmZWN0byB2XHUwMEUxbGlkbyBwYXJhIGVsIHRpcG8gJyd7MX0nJy4KLSAgICAgICAgY3ZjLWVsdC41LjIuMi4xID0gY3ZjLWVsdC41LjIuMi4xOiBFbCBlbGVtZW50byAnJ3swfScnIG5vIGRlYmUgdGVuZXIgbmluZ1x1MDBGQW4gZWxlbWVudG8gZGUgaW5mb3JtYWNpXHUwMEYzbiBkZSBlbGVtZW50byBbc2VjdW5kYXJpb3NdLgotICAgICAgICBjdmMtZWx0LjUuMi4yLjIuMSA9IGN2Yy1lbHQuNS4yLjIuMi4xOiBFbCB2YWxvciAnJ3sxfScnIGRlbCBlbGVtZW50byAnJ3swfScnIG5vIGNvaW5jaWRlIGNvbiBlbCB2YWxvciBkZSAneyd2YWx1ZSBjb25zdHJhaW50J30nIGZpam8gJyd7Mn0nJy4KLSAgICAgICAgY3ZjLWVsdC41LjIuMi4yLjIgPSBjdmMtZWx0LjUuMi4yLjIuMjogRWwgdmFsb3IgJyd7MX0nJyBkZWwgZWxlbWVudG8gJyd7MH0nJyBubyBjb2luY2lkZSBjb24gZWwgdmFsb3IgZGUgJ3sndmFsdWUgY29uc3RyYWludCd9JyAnJ3syfScnLgotICAgICAgICBjdmMtZW51bWVyYXRpb24tdmFsaWQgPSBjdmMtZW51bWVyYXRpb24tdmFsaWQ6IEVsIHZhbG9yICcnezB9Jycgbm8gZXMgZGUgZmFjZXRhIHZcdTAwRTFsaWRhIGNvbiByZXNwZWN0byBhIGxhIGVudW1lcmFjaVx1MDBGM24gJyd7MX0nJy4gRGViZSBzZXIgdW4gdmFsb3IgZGUgbGEgZW51bWVyYWNpXHUwMEYzbi4KLSAgICAgICAgY3ZjLWZyYWN0aW9uRGlnaXRzLXZhbGlkID0gY3ZjLWZyYWN0aW9uRGlnaXRzLXZhbGlkOiBFbCB2YWxvciAnJ3swfScnIHRpZW5lIHsxfSBkXHUwMEVEZ2l0b3MgZnJhY2Npb25hcmlvcywgcGVybyBlbCBuXHUwMEZBbWVybyBkZSBkXHUwMEVEZ2l0b3MgZnJhY2Npb25hcmlvcyBzZSBoYSBsaW1pdGFkbyBhIHsyfS4KLSAgICAgICAgY3ZjLWlkLjEgPSBjdmMtaWQuMTogTm8gaGF5IG5pbmdcdTAwRkFuIGVubGFjZSBkZSBpZGVudGlmaWNhZG9yL0lEUkVGIHBhcmEgSURSRUYgJyd7MH0nJy4KLSAgICAgICAgY3ZjLWlkLjIgPSBjdmMtaWQuMjogSGF5IHZhcmlhcyBpbmNpZGVuY2lhcyBkZWwgdmFsb3IgZGUgaWRlbnRpZmljYWRvciAnJ3swfScnLgotICAgICAgICBjdmMtaWQuMyA9IGN2Yy1pZC4zOiBVbiBjYW1wbyBkZSByZXN0cmljY2lcdTAwRjNuIGRlIGlkZW50aWRhZCAnJ3swfScnIGNvaW5jaWRlIGNvbiBlbCBlbGVtZW50byAnJ3sxfScnLCBwZXJvIGVsIGVsZW1lbnRvIG5vIGVzIGRlIHRpcG8gc2ltcGxlLgotICAgICAgICBjdmMtbGVuZ3RoLXZhbGlkID0gY3ZjLWxlbmd0aC12YWxpZDogRWwgdmFsb3IgJyd7MH0nJyBjb24gbGEgbG9uZ2l0dWQgPSAnJ3sxfScnIG5vIGVzIGRlIGZhY2V0YSB2XHUwMEUxbGlkYSBjb24gcmVzcGVjdG8gYSBsYSBsb25naXR1ZCAnJ3syfScnIHBhcmEgZWwgdGlwbyAnJ3szfScnLgotICAgICAgICBjdmMtbWF4RXhjbHVzaXZlLXZhbGlkID0gY3ZjLW1heEV4Y2x1c2l2ZS12YWxpZDogRWwgdmFsb3IgJyd7MH0nJyBubyBlcyBkZSBmYWNldGEgdlx1MDBFMWxpZGEgY29uIHJlc3BlY3RvIGEgbWF4RXhjbHVzaXZlICcnezF9JycgcGFyYSBlbCB0aXBvICcnezJ9JycuCi0gICAgICAgIGN2Yy1tYXhJbmNsdXNpdmUtdmFsaWQgPSBjdmMtbWF4SW5jbHVzaXZlLXZhbGlkOiBFbCB2YWxvciAnJ3swfScnIG5vIGVzIGRlIGZhY2V0YSB2XHUwMEUxbGlkYSBjb24gcmVzcGVjdG8gYSBtYXhJbmNsdXNpdmUgJyd7MX0nJyBwYXJhIGVsIHRpcG8gJyd7Mn0nJy4KLSAgICAgICAgY3ZjLW1heExlbmd0aC12YWxpZCA9IGN2Yy1tYXhMZW5ndGgtdmFsaWQ6IEVsIHZhbG9yICcnezB9JycgY29uIGxhIGxvbmdpdHVkID0gJyd7MX0nJyBubyBlcyBkZSBmYWNldGEgdlx1MDBFMWxpZGEgY29uIHJlc3BlY3RvIGEgbWF4TGVuZ3RoICcnezJ9JycgcGFyYSBlbCB0aXBvICcnezN9JycuCi0gICAgICAgIGN2Yy1taW5FeGNsdXNpdmUtdmFsaWQgPSBjdmMtbWluRXhjbHVzaXZlLXZhbGlkOiBFbCB2YWxvciAnJ3swfScnIG5vIGVzIGRlIGZhY2V0YSB2XHUwMEUxbGlkYSBjb24gcmVzcGVjdG8gYSBtaW5FeGNsdXNpdmUgJyd7MX0nJ3BhcmEgZWwgdGlwbyAnJ3syfScnLgotICAgICAgICBjdmMtbWluSW5jbHVzaXZlLXZhbGlkID0gY3ZjLW1pbkluY2x1c2l2ZS12YWxpZDogRWwgdmFsb3IgJyd7MH0nJyBubyBlcyBkZSBmYWNldGEgdlx1MDBFMWxpZGEgY29uIHJlc3BlY3RvIGEgbWluSW5jbHVzaXZlICcnezF9JycgcGFyYSBlbCB0aXBvICcnezJ9JycuCi0gICAgICAgIGN2Yy1taW5MZW5ndGgtdmFsaWQgPSBjdmMtbWluTGVuZ3RoLXZhbGlkOiBFbCB2YWxvciAnJ3swfScnIGNvbiBsYSBsb25naXR1ZCA9ICcnezF9Jycgbm8gZXMgZGUgZmFjZXRhIHZcdTAwRTFsaWRhIGNvbiByZXNwZWN0byBhIG1pbkxlbmd0aCAnJ3syfScnIHBhcmEgZWwgdGlwbyAnJ3szfScnLgotICAgICAgICBjdmMtcGF0dGVybi12YWxpZCA9IGN2Yy1wYXR0ZXJuLXZhbGlkOiBFbCB2YWxvciAnJ3swfScnIG5vIGVzIGRlIGZhY2V0YSB2XHUwMEUxbGlkYSBjb24gcmVzcGVjdG8gYWwgcGF0clx1MDBGM24gJyd7MX0nJyBwYXJhIGVsIHRpcG8gJyd7Mn0nJy4KLSAgICAgICAgY3ZjLXRvdGFsRGlnaXRzLXZhbGlkID0gY3ZjLXRvdGFsRGlnaXRzLXZhbGlkOiBFbCB2YWxvcicnezB9JycgdGllbmUgezF9IGRcdTAwRURnaXRvcyB0b3RhbGVzLCBwZXJvIGVsIG5cdTAwRkFtZXJvIGRlIGRcdTAwRURnaXRvcyB0b3RhbGVzIHNlIGhhIGxpbWl0YWRvIGEgezJ9LgotICAgICAgICBjdmMtdHlwZS4yID0gY3ZjLXR5cGUuMjogTGEgZGVmaW5pY2lcdTAwRjNuIGRlIHRpcG8gbm8gcHVlZGUgc2VyIGFic3RyYWN0YSBwYXJhIGVsIGVsZW1lbnRvIHswfS4KLSAgICAgICAgY3ZjLXR5cGUuMy4xLjEgPSBjdmMtdHlwZS4zLjEuMTogRWwgZWxlbWVudG8gJyd7MH0nJyBlcyB1biB0aXBvIHNpbXBsZSwgcG9yIGxvIHF1ZSBubyBwdWVkZSB0ZW5lciBhdHJpYnV0b3MsIGV4Y2VwdG8gYXF1ZWxsb3MgY3V5byBlc3BhY2lvIGRlIG5vbWJyZXMgc2VhICcnaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UnJyB5IGN1eW8gW25vbWJyZSBsb2NhbF0gc2VhIGRlIHRpcG8gJyd0eXBlJycsICcnbmlsJycsICcnc2NoZW1hTG9jYXRpb24nJyBvICcnbm9OYW1lc3BhY2VTY2hlbWFMb2NhdGlvbicnLiBTaW4gZW1iYXJnbywgc2UgaGEgZW5jb250cmFkbyBlbCBhdHJpYnV0byAnJ3sxfScnLgotICAgICAgICBjdmMtdHlwZS4zLjEuMiA9IGN2Yy10eXBlLjMuMS4yOiBFbCBlbGVtZW50bycnezB9JycgZXMgdW4gdGlwbyBzaW1wbGUsIHBvciBsbyBxdWUgbm8gZGViZSB0ZW5lciBuaW5nXHUwMEZBbiBlbGVtZW50byBkZSBpbmZvcm1hY2lcdTAwRjNuIGRlIGVsZW1lbnRvIFtzZWN1bmRhcmlvc10uCi0gICAgICAgIGN2Yy10eXBlLjMuMS4zID0gY3ZjLXR5cGUuMy4xLjM6IEVsIHZhbG9yICcnezF9JycgZGVsIGVsZW1lbnRvICcnezB9Jycgbm8gZXMgdlx1MDBFMWxpZG8uCi0KLSNzY2hlbWEgdmFsaWQgKDMuWC4zKQotCi0gICAgICAgIHNjaGVtYV9yZWZlcmVuY2UuYWNjZXNzID0gc2NoZW1hX3JlZmVyZW5jZTogZmFsbG8gYWwgbGVlciBlbCBkb2N1bWVudG8gZGUgZXNxdWVtYSAnJ3swfScnIHBvcnF1ZSBubyBzZSBwZXJtaXRlIGVsIGFjY2VzbyAnJ3sxfScnIGRlYmlkbyBhIHVuYSByZXN0cmljY2lcdTAwRjNuIGRlZmluaWRhIHBvciBsYSBwcm9waWVkYWQgYWNjZXNzRXh0ZXJuYWxTY2hlbWEuIAotICAgICAgICBzY2hlbWFfcmVmZXJlbmNlLjQgPSBzY2hlbWFfcmVmZXJlbmNlLjQ6IEZhbGxvIGFsIGxlZXIgZWwgZG9jdW1lbnRvIGRlIGVzcXVlbWEgJyd7MH0nJywgcG9ycXVlIDEpIG5vIHNlIGhhIGVuY29udHJhZG8gZWwgZG9jdW1lbnRvOyAyKSBubyBzZSBoYSBwb2RpZG8gbGVlciBlbCBkb2N1bWVudG87IDMpIGVsIGVsZW1lbnRvIHJhXHUwMEVEeiBkZWwgZG9jdW1lbnRvIG5vIGVzIDx4c2Q6c2NoZW1hPi4KLSAgICAgICAgc3JjLWFubm90YXRpb24gPSBzcmMtYW5ub3RhdGlvbjogTG9zIGVsZW1lbnRvcyBkZSA8YW5ub3RhdGlvbj4gc1x1MDBGM2xvIHB1ZWRlbiBjb250ZW5lciBlbGVtZW50b3MgZGUgPGFwcGluZm8+IHkgPGRvY3VtZW50YXRpb24+LCBwZXJvIHNlIGhhIGVuY29udHJhZG8gJyd7MH0nJy4KLSAgICAgICAgc3JjLWF0dHJpYnV0ZS4xID0gc3JjLWF0dHJpYnV0ZS4xOiBMYXMgcHJvcGllZGFkZXMgJydkZWZhdWx0JycgeSAnJ2ZpeGVkJycgbm8gcHVlZGVuIGVzdGFyIHByZXNlbnRlcyBkZSBmb3JtYSBzaW11bHRcdTAwRTFuZWEgZW4gbGEgZGVjbGFyYWNpXHUwMEYzbiBkZSBhdHJpYnV0byAnJ3swfScnLiBVdGlsaWNlIHNcdTAwRjNsbyB1bmEgZGUgZWxsYXMuCi0gICAgICAgIHNyYy1hdHRyaWJ1dGUuMiA9IHNyYy1hdHRyaWJ1dGUuMjogOiBMYSBwcm9waWVkYWQgJydkZWZhdWx0JycgZXN0XHUwMEUxIHByZXNlbnRlIGVuIGVsIGF0cmlidXRvICcnezB9JycsIHBvciBsbyBxdWUgZWwgdmFsb3IgZGUgJyd1c2UnJyBkZWJlIHNlciAnJ29wdGlvbmFsJycuCi0gICAgICAgIHNyYy1hdHRyaWJ1dGUuMy4xID0gc3JjLWF0dHJpYnV0ZS4zLjE6ICdyZWYnIG8gJ25hbWUnIGRlYmVuIGVzdGFyIHByZXNlbnRlcyBlbiB1bmEgZGVjbGFyYWNpXHUwMEYzbiBkZSBhdHJpYnV0byBsb2NhbC4KLSAgICAgICAgc3JjLWF0dHJpYnV0ZS4zLjIgPSBzcmMtYXR0cmlidXRlLjMuMjogRWwgY29udGVuaWRvIGRlYmUgY29pbmNpZGlyIGNvbiAoYW5ub3RhdGlvbj8pIHBhcmEgbGEgcmVmZXJlbmNpYSBkZSBhdHJpYnV0byAnJ3swfScnLgotICAgICAgICBzcmMtYXR0cmlidXRlLjQgPSBzcmMtYXR0cmlidXRlLjQ6IEVsIGF0cmlidXRvICcnezB9JycgdGllbmUgdW4gYXRyaWJ1dG8gJyd0eXBlJycgeSB1biBzZWN1bmRhcmlvIGFuXHUwMEYzbmltbyAnJ3NpbXBsZVR5cGUnJy4gU1x1MDBGM2xvIHNlIHBlcm1pdGUgdW5vIGRlIGVzdG9zIGNvbW8gYXRyaWJ1dG8uCi0gICAgICAgIHNyYy1hdHRyaWJ1dGVfZ3JvdXAuMiA9IHNyYy1hdHRyaWJ1dGVfZ3JvdXAuMjogTGEgaW50ZXJzZWNjaVx1MDBGM24gZGUgY29tb2RpbmVzIG5vIHNlIHB1ZWRlIGV4cHJlc2FyIHBhcmEgZWwgZ3J1cG8gZGUgYXRyaWJ1dG9zICcnezB9JycuCi0gICAgICAgIHNyYy1hdHRyaWJ1dGVfZ3JvdXAuMyA9IHNyYy1hdHRyaWJ1dGVfZ3JvdXAuMzogU2UgaGFuIGRldGVjdGFkbyBkZWZpbmljaW9uZXMgY2lyY3VsYXJlcyBwYXJhIGVsIGdydXBvIGRlIGF0cmlidXRvcyAnJ3swfScnLiBFbCBzZWd1aW1pZW50byBkZSBmb3JtYSByZWN1cnJlbnRlIGRlIGxhcyByZWZlcmVuY2lhcyBkZSBncnVwbyBkZSBhdHJpYnV0b3MgdnVlbHZlIGRlIGZvcm1hIGV2ZW50dWFsIGEgc1x1MDBFRCBtaXNtby4KLSAgICAgICAgc3JjLWN0LjEgPSBzcmMtY3QuMTogRXJyb3IgZGUgcmVwcmVzZW50YWNpXHUwMEYzbiBkZSBkZWZpbmljaVx1MDBGM24gZGUgdGlwbyBjb21wbGVqbyBwYXJhIGVsIHRpcG8gJyd7MH0nJy4gU2kgc2UgdXRpbGl6YSA8Y29tcGxleENvbnRlbnQ+LCBlbCB0aXBvIGRlIGJhc2UgZGViZSBzZXIgY29tcGxleFR5cGUuICcnezF9JycgZXMgc2ltcGxlVHlwZS4KLSAgICAgICAgc3JjLWN0LjIuMSA9IHNyYy1jdC4yLjE6IEVycm9yIGRlIHJlcHJlc2VudGFjaVx1MDBGM24gZGUgZGVmaW5pY2lcdTAwRjNuIGRlIHRpcG8gY29tcGxlam8gcGFyYSBlbCB0aXBvICcnezB9JycuIFNpIHNlIHV0aWxpemEgPHNpbXBsZUNvbnRlbnQ+LCBlbCB0aXBvIGRlIGJhc2UgZGViZSBzZXIgY29tcGxleFR5cGUgY3V5byB0aXBvIGRlIGNvbnRlbmlkbyBzZWEgc2ltcGxlIG8sIHNcdTAwRjNsbyBlbiBjYXNvIGRlIHF1ZSBzZSBlc3BlY2lmaXF1ZSB1bmEgcmVzdHJpY2NpXHUwMEYzbiwgdW4gdGlwbyBjb21wbGVqbyBjb24gY29udGVuaWRvIG1peHRvIHkgcGFydFx1MDBFRGN1bGEgcXVlIHNlIHB1ZWRhIHZhY2lhciBvLCBzXHUwMEYzbG8gc2kgc2UgZXNwZWNpZmljYSBsYSBleHRlbnNpXHUwMEYzbiwgdW4gdGlwbyBzaW1wbGUuICcnezF9Jycgbm8gY3VtcGxlIG5pbmd1bmEgZGUgZXN0YXMgY29uZGljaW9uZXMuCi0gICAgICAgIHNyYy1jdC4yLjIgPSBzcmMtY3QuMi4yOiBFcnJvciBkZSByZXByZXNlbnRhY2lcdTAwRjNuIGRlIGRlZmluaWNpXHUwMEYzbiBkZSB0aXBvIGNvbXBsZWpvIHBhcmEgZWwgdGlwbyAnJ3swfScnLiBDdWFuZG8gY29tcGxleFR5cGUgY29uIHNpbXBsZUNvbnRlbnQgcmVzdHJpbmdlIHVuIHZhbG9yIGRlIGNvbXBsZXhUeXBlIGNvbiBjb250ZW5pZG8gbWl4dG8geSBwYXJ0XHUwMEVEY3VsYSBxdWUgc2UgcHVlZGEgdmFjaWFyLCBkZWJlIGhhYmVyIHVuIHZhbG9yIDxzaW1wbGVUeXBlPiBlbnRyZSBsb3Mgc2VjdW5kYXJpb3MgZGUgPHJlc3RyaWN0aW9uPi4KLSAgICAgICAgc3JjLWN0LjQgPSBzcmMtY3QuNDogRXJyb3IgZGUgcmVwcmVzZW50YWNpXHUwMEYzbiBkZSBkZWZpbmljaVx1MDBGM24gZGUgdGlwbyBjb21wbGVqbyBwYXJhIGVsIHRpcG8gJyd7MH0nJy4gTGEgaW50ZXJzZWNjaVx1MDBGM24gZGUgbG9zIGNvbW9kaW5lcyBubyBzZSBwdWVkZSBleHByZXNhci4KLSAgICAgICAgc3JjLWN0LjUgPSBzcmMtY3QuNTogRXJyb3IgZGUgcmVwcmVzZW50YWNpXHUwMEYzbiBkZSBkZWZpbmljaVx1MDBGM24gZGUgdGlwbyBjb21wbGVqbyBwYXJhIGVsIHRpcG8gJyd7MH0nJy4gTGEgdW5pXHUwMEYzbiBkZSBsb3MgY29tb2RpbmVzIG5vIHNlIHB1ZWRlIGV4cHJlc2FyLgotICAgICAgICBzcmMtZWxlbWVudC4xID0gc3JjLWVsZW1lbnQuMTogTGFzIHByb3BpZWRhZGVzICcnZGVmYXVsdCcnIHkgJydmaXhlZCcnIG5vIHB1ZWRlbiBlc3RhciBwcmVzZW50ZXMgZGUgZm9ybWEgc2ltdWx0XHUwMEUxbmVhIGVuIGxhIGRlY2xhcmFjaVx1MDBGM24gZGUgZWxlbWVudG8gJyd7MH0nJy4gVXRpbGljZSBzXHUwMEYzbG8gdW5hIGRlIGVsbGFzLgotICAgICAgICBzcmMtZWxlbWVudC4yLjEgPSBzcmMtZWxlbWVudC4yLjE6IDogJ3JlZicgbyAnbmFtZScgZGViZW4gZXN0YXIgcHJlc2VudGVzIGVuIHVuYSBkZWNsYXJhY2lcdTAwRjNuIGRlIGVsZW1lbnRvIGxvY2FsLgotICAgICAgICBzcmMtZWxlbWVudC4yLjIgPSBzcmMtZWxlbWVudC4yLjI6IENvbW8gJyd7MH0nJyBjb250aWVuZSBlbCBhdHJpYnV0byAnJ3JlZicnLCBzdSBjb250ZW5pZG8gZGViZSBjb2luY2lkaXIgY29uIChhbm5vdGF0aW9uPykuIFNpbiBlbWJhcmdvLCBzZSBoYSBlbmNvbnRyYWRvICcnezF9JycuCi0gICAgICAgIHNyYy1lbGVtZW50LjMgPSBzcmMtZWxlbWVudC4zOiBFbCBlbGVtZW50byAnJ3swfScnIHRpZW5lIHVuIGF0cmlidXRvICcndHlwZScnIHkgdW4gc2VjdW5kYXJpbyAnJ2Fub255bW91cyB0eXBlJycuIFNvbG8gc2UgcGVybWl0ZSB1bm8gZGUgZXN0b3MgcGFyYSB1biBlbGVtZW50by4KLSAgICAgICAgc3JjLWltcG9ydC4xLjEgPSBzcmMtaW1wb3J0LjEuMTogRWwgYXRyaWJ1dG8gZGUgZXNwYWNpbyBkZSBub21icmVzICcnezB9JycgZGUgdW4gZWxlbWVudG8gZGUgaW5mb3JtYWNpXHUwMEYzbiBkZSBlbGVtZW50byA8aW1wb3J0PiBubyBkZWJlIHNlciBpZ3VhbCBxdWUgZWwgdmFsb3IgZGUgdGFyZ2V0TmFtZXNwYWNlIGRlbCBlc3F1ZW1hIGVuIGVsIHF1ZSBleGlzdGUuCi0gICAgICAgIHNyYy1pbXBvcnQuMS4yID0gc3JjLWltcG9ydC4xLjI6IFNpIGVsIGF0cmlidXRvIGRlIGVzcGFjaW8gZGUgbm9tYnJlcyBubyBlc3RcdTAwRTEgcHJlc2VudGUgZW4gdW4gZWxlbWVudG8gZGUgaW5mb3JtYWNpXHUwMEYzbiBkZSBlbGVtZW50byA8aW1wb3J0PiwgZWwgZXNxdWVtYSBkZWxpbWl0YWRvciBkZWJlIHRlbmVyIHVuIHRhcmdldE5hbWVzcGFjZS4KLSAgICAgICAgc3JjLWltcG9ydC4yID0gc3JjLWltcG9ydC4yOiBFbCBlc3BhY2lvIGRlIG5vbWJyZXMgZGVsIGVsZW1lbnRvIHJhXHUwMEVEeiBkZWwgZG9jdW1lbnRvICcnezB9JycgZGViZSBsbGFtYXJzZSAnJ2h0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hJycgeSBlbCBub21icmUgbG9jYWwgJydzY2hlbWEnJy4KLSAgICAgICAgc3JjLWltcG9ydC4zLjEgPSBzcmMtaW1wb3J0LjMuMTogRWwgYXRyaWJ1dG8gZGUgZXNwYWNpbyBkZSBub21icmVzLCAnJ3swfScnLCBkZSB1biBlbGVtZW50byBkZSBpbmZvcm1hY2lcdTAwRjNuIGRlIGVsZW1lbnRvIDxpbXBvcnQ+IGRlYmUgc2VyIGlkXHUwMEU5bnRpY28gYWwgYXRyaWJ1dG8gdGFyZ2V0TmFtZXNwYWNlLCAnJ3sxfScnLCBkZWwgZG9jdW1lbnRvIGltcG9ydGFkby4KLSAgICAgICAgc3JjLWltcG9ydC4zLjIgPSBzcmMtaW1wb3J0LjMuMjogU2UgaGEgZW5jb250cmFkbyB1biBlbGVtZW50byBkZSBpbmZvcm1hY2lcdTAwRjNuIGRlIGVsZW1lbnRvIDxpbXBvcnQ+IHF1ZSBubyB0ZW5cdTAwRURhIG5pbmdcdTAwRkFuIGF0cmlidXRvIGRlIGVzcGFjaW8gZGUgbm9tYnJlcywgcG9yIGxvIHF1ZSBlbCBkb2N1bWVudG8gaW1wb3J0YWRvIG5vIHB1ZWRlIHRlbmVyIHVuIGF0cmlidXRvIHRhcmdldE5hbWVzcGFjZS4gU2luIGVtYmFyZ28sIHNlIGhhIGVuY29udHJhZG8gZWwgdmFsb3IgZGUgdGFyZ2V0TmFtZXNwYWNlICcnezF9JycgZW4gZWwgZG9jdW1lbnRvIGltcG9ydGFkby4KLSAgICAgICAgc3JjLWluY2x1ZGUuMSA9IHNyYy1pbmNsdWRlLjE6IEVsIGVzcGFjaW8gZGUgbm9tYnJlcyBkZWwgZWxlbWVudG8gcmFcdTAwRUR6IGRlbCBkb2N1bWVudG8gJyd7MH0nJyBkZWJlIGxsYW1hcnNlICcnaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEnJyB5IGVsIG5vbWJyZSBsb2NhbCAnJ3NjaGVtYScnLgotICAgICAgICBzcmMtaW5jbHVkZS4yLjEgPSBzcmMtaW5jbHVkZS4yLjE6IEVsIHZhbG9yIGRlIHRhcmdldE5hbWVzcGFjZSBkZWwgZXNxdWVtYSBkZSByZWZlcmVuY2lhLCBhY3R1YWxtZW50ZSAnJ3sxfScnLCBkZWJlIHNlciBpZ3VhbCBhbCBkZWwgZXNxdWVtYSBpbmNsdWlkbywgcXVlIGFjdHVhbG1lbnRlIGVzICcnezB9JycuCi0gICAgICAgIHNyYy1yZWRlZmluZS4yID0gc3JjLXJlZGVmaW5lLjI6IEVsIGVzcGFjaW8gZGUgbm9tYnJlcyBkZWwgZWxlbWVudG8gcmFcdTAwRUR6IGRlbCBkb2N1bWVudG8gJyd7MH0nJyBkZWJlIGxsYW1hcnNlICcnaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEnJyB5IGVsIG5vbWJyZSBsb2NhbCAnJ3NjaGVtYScnLgotICAgICAgICBzcmMtcmVkZWZpbmUuMy4xID0gc3JjLXJlZGVmaW5lLjMuMTogRWwgdmFsb3IgZGUgdGFyZ2V0TmFtZXNwYWNlIGRlbCBlc3F1ZW1hIGRlIHJlZmVyZW5jaWEsIHF1ZSBhY3R1YWxtZW50ZSBlcyAnJ3sxfScnLCBkZWJlIHNlciBpZ3VhbCBhbCBkZWwgZXNxdWVtYSByZWRlZmluaWRvLCBxdWUgYWN0dWFsbWVudGUgZXMgJyd7MH0nJy4KLSAgICAgICAgc3JjLXJlZGVmaW5lLjUuYS5hID0gc3JjLXJlZGVmaW5lLjUuYS5hOiBObyBzZSBoYSBlbmNvbnRyYWRvIG5pbmdcdTAwRkFuIHNlY3VuZGFyaW8gc2luIGFub3RhY2lcdTAwRjNuIGRlIDxzaW1wbGVUeXBlPi4gTG9zIHNlY3VuZGFyaW9zIGRlIDxzaW1wbGVUeXBlPiBkZSBsb3MgZWxlbWVudG9zIDxyZWRlZmluZT4gZGViZW4gdGVuZXIgZGVzY2VuZGllbnRlcyBkZSA8cmVzdHJpY3Rpb24+LCBjb24gYXRyaWJ1dG9zIGRlICdiYXNlJyBxdWUgaGFnYW4gcmVmZXJlbmNpYSBhIHNcdTAwRUQgbWlzbW9zLgotICAgICAgICBzcmMtcmVkZWZpbmUuNS5hLmIgPSBzcmMtcmVkZWZpbmUuNS5hLmI6ICcnezB9Jycgbm8gZXMgdW4gZWxlbWVudG8gc2VjdW5kYXJpbyB2XHUwMEUxbGlkby4gTG9zIHNlY3VuZGFyaW9zIGRlIDxzaW1wbGVUeXBlPiBkZSBsb3MgZWxlbWVudG9zIDxyZWRlZmluZT4gZGViZW4gdGVuZXIgZGVzY2VuZGllbnRlcyBkZSA8cmVzdHJpY3Rpb24+LCBjb24gYXRyaWJ1dG9zIGRlICcnYmFzZScnIHF1ZSBoYWdhbiByZWZlcmVuY2lhIGEgc1x1MDBFRCBtaXNtb3MuCi0gICAgICAgIHNyYy1yZWRlZmluZS41LmEuYyA9IHNyYy1yZWRlZmluZS41LmEuYzogJyd7MH0nJyBubyB0aWVuZSB1biBhdHJpYnV0byBkZSAnJ2Jhc2UnJyBxdWUgaGFjZSByZWZlcmVuY2lhIGFsIGVsZW1lbnRvIHJlZGVmaW5pZG8sICcnezF9JycuIExvcyBzZWN1bmRhcmlvcyBkZSA8c2ltcGxlVHlwZT4gZGUgbG9zIGVsZW1lbnRvcyA8cmVkZWZpbmU+IGRlYmVuIHRlbmVyIGRlc2NlbmRpZW50ZXMgZGUgPHJlc3RyaWN0aW9uPiwgY29uIGF0cmlidXRvcyBkZSAnJ2Jhc2UnJyBxdWUgaGFnYW4gcmVmZXJlbmNpYSBhIHNcdTAwRUQgbWlzbW9zLgotICAgICAgICBzcmMtcmVkZWZpbmUuNS5iLmEgPSBzcmMtcmVkZWZpbmUuNS5iLmE6IE5vIHNlIGhhIGVuY29udHJhZG8gbmluZ1x1MDBGQW4gc2VjdW5kYXJpbyBzaW4gYW5vdGFjaVx1MDBGM24gZGUgPGNvbXBsZXhUeXBlPi4gTG9zIHNlY3VuZGFyaW9zIGRlIDxjb21wbGV4VHlwZT4gZGUgbG9zIGVsZW1lbnRvcyA8cmVkZWZpbmU+IGRlYmVuIHRlbmVyIGRlc2NlbmRpZW50ZXMgZGUgPGV4dGVuc2lvbj4gbyA8cmVzdHJpY3Rpb24+LCBjb24gYXRyaWJ1dG9zIGRlICdiYXNlJyBxdWUgaGFnYW4gcmVmZXJlbmNpYSBhIHNcdTAwRUQgbWlzbW9zLgotICAgICAgICBzcmMtcmVkZWZpbmUuNS5iLmIgPSBzcmMtcmVkZWZpbmUuNS5iLmI6Tm8gc2UgaGEgZW5jb250cmFkbyBuaW5nXHUwMEZBbiB0ZXJjaWFyaW8gc2luIGFub3RhY2lcdTAwRjNuIGRlIDxjb21wbGV4VHlwZT4uIExvcyBzZWN1bmRhcmlvcyBkZSA8Y29tcGxleFR5cGU+IGRlIGxvcyBlbGVtZW50b3MgPHJlZGVmaW5lPiBkZWJlbiB0ZW5lciBkZXNjZW5kaWVudGVzIGRlIDxleHRlbnNpb24+IG8gPHJlc3RyaWN0aW9uPiwgY29uIGF0cmlidXRvcyBkZSAnYmFzZScgcXVlIGhhZ2FuIHJlZmVyZW5jaWEgYSBzXHUwMEVEIG1pc21vcy4KLSAgICAgICAgc3JjLXJlZGVmaW5lLjUuYi5jID0gc3JjLXJlZGVmaW5lLjUuYi5jOiAnJ3swfScnIG5vIGVzIHVuIGVsZW1lbnRvIHRlcmNpYXJpbyB2XHUwMEUxbGlkby4gTG9zIHNlY3VuZGFyaW9zIGRlIDxjb21wbGV4VHlwZT4gZGUgbG9zIGVsZW1lbnRvcyA8cmVkZWZpbmU+IGRlYmVuIHRlbmVyIGRlc2NlbmRpZW50ZXMgZGUgPGV4dGVuc2lvbj4gbyA8cmVzdHJpY3Rpb24+LCBjb24gYXRyaWJ1dG9zIGRlICcnYmFzZScnIHF1ZSBoYWdhbiByZWZlcmVuY2lhIGEgc1x1MDBFRCBtaXNtb3MuCi0gICAgICAgIHNyYy1yZWRlZmluZS41LmIuZCA9IHNyYy1yZWRlZmluZS41LmIuZDogJyd7MH0nJyBubyB0aWVuZSB1biBhdHJpYnV0byBkZSAnJ2Jhc2UnJyBxdWUgaGFjZSByZWZlcmVuY2lhIGFsIGVsZW1lbnRvIHJlZGVmaW5pZG8sICcnezF9JycuIExvcyBzZWN1bmRhcmlvcyBkZSA8Y29tcGxleFR5cGU+IGRlIGxvcyBlbGVtZW50b3MgPHJlZGVmaW5lPiBkZWJlbiB0ZW5lciBkZXNjZW5kaWVudGVzIGRlIDxleHRlbnNpb24+IG8gPHJlc3RyaWN0aW9uPiwgY29uIGF0cmlidXRvcyBkZSAnJ2Jhc2UnJyBxdWUgaGFnYW4gcmVmZXJlbmNpYSBhIHNcdTAwRUQgbWlzbW9zLgotICAgICAgICBzcmMtcmVkZWZpbmUuNi4xLjEgPSBzcmMtcmVkZWZpbmUuNi4xLjE6IFNpIHVuIHNlY3VuZGFyaW8gZGUgZ3J1cG8gZGUgdW4gZWxlbWVudG8gPHJlZGVmaW5lPiBjb250aWVuZSB1biBncnVwbyBxdWUgaGFjZSByZWZlcmVuY2lhIGEgc1x1MDBFRCBtaXNtbywgZGViZSB0ZW5lciBleGFjdGFtZW50ZSAxOyBcdTAwRTlzdGUgdGllbmUgJyd7MH0nJy4KLSAgICAgICAgc3JjLXJlZGVmaW5lLjYuMS4yID0gc3JjLXJlZGVmaW5lLjYuMS4yOiBFbCBncnVwbyAnJ3swfScnLCBxdWUgY29udGllbmUgdW5hIHJlZmVyZW5jaWEgYSB1biBncnVwbyBxdWUgc2UgZXN0XHUwMEUxIHJlZGVmaW5pZW5kbyBkZWJlIHRlbmVyIHVuIHZhbG9yIGRlICcnbWluT2NjdXJzJycgPSAnJ21heE9jY3VycycnID0gMS4KLSAgICAgICAgc3JjLXJlZGVmaW5lLjYuMi4xID0gc3JjLXJlZGVmaW5lLjYuMi4xOiBObyBoYXkgbmluZ1x1MDBGQW4gZ3J1cG8gZW4gZWwgZXNxdWVtYSByZWRlZmluaWRvIGNvbiB1biBub21icmUgcXVlIGNvaW5jaWRhIGNvbiAnJ3swfScnLgotICAgICAgICBzcmMtcmVkZWZpbmUuNi4yLjIgPSBzcmMtcmVkZWZpbmUuNi4yLjI6IEVsIGdydXBvICcnezB9Jycgbm8gcmVzdHJpbmdlIGNvcnJlY3RhbWVudGUgYWwgZ3J1cG8gcXVlIHJlZGVmaW5lOyBzZSBoYSB2aW9sYWRvIGxhIHJlc3RyaWNjaVx1MDBGM246ICcnezF9JycuCi0gICAgICAgIHNyYy1yZWRlZmluZS43LjEgPSBzcmMtcmVkZWZpbmUuNy4xOiBTaSB1biBzZWN1bmRhcmlvIGRlIGF0dHJpYnV0ZUdyb3VwIGRlIHVuIGVsZW1lbnRvIDxyZWRlZmluZT4gY29udGllbmUgdW4gdmFsb3IgZGUgYXR0cmlidXRlR3JvdXAgcXVlIGhhY2UgcmVmZXJlbmNpYSBhIHNcdTAwRUQgbWlzbW8sIGRlYmUgdGVuZXIgZXhhY3RhbWVudGUgMTsgXHUwMEU5c3RlIHRpZW5lIHswfS4KLSAgICAgICAgc3JjLXJlZGVmaW5lLjcuMi4xID0gc3JjLXJlZGVmaW5lLjcuMi4xOiBObyBoYXkgbmluZ1x1MDBGQW4gdmFsb3IgZGUgYXR0cmlidXRlR3JvdXAgZW4gZWwgZXNxdWVtYSByZWRlZmluaWRvIGNvbiB1biBub21icmUgcXVlIGNvaW5jaWRhIGNvbiAnJ3swfScnLgotICAgICAgICBzcmMtcmVkZWZpbmUuNy4yLjIgPSBzcmMtcmVkZWZpbmUuNy4yLjI6IGVsIHZhbG9yIGRlIGF0dHJpYnV0ZUdyb3VwICcnezB9Jycgbm8gcmVzdHJpbmdlIGNvcnJlY3RhbWVudGUgZWwgdmFsb3IgZGUgYXR0cmlidXRlR3JvdXAgcXVlIHJlZGVmaW5lOyBzZSBoYSB2aW9sYWRvIGxhIHJlc3RyaWNjaVx1MDBGM246ICcnezF9JycuCi0gICAgICAgIHNyYy1yZXNvbHZlID0gc3JjLXJlc29sdmU6IE5vIHNlIHB1ZWRlIHJlc29sdmVyIGVsIG5vbWJyZSAnJ3swfScnIHBhcmEgdW4gY29tcG9uZW50ZSAnJ3sxfScnLgotICAgICAgICBzcmMtcmVzb2x2ZS40LjEgPSBzcmMtcmVzb2x2ZS40LjE6IEVycm9yIGFsIHJlc29sdmVyIGVsIGNvbXBvbmVudGUgJyd7Mn0nJy4gU2UgaGEgZGV0ZWN0YWRvIHF1ZSAnJ3syfScnIG5vIHRpZW5lIGVzcGFjaW8gZGUgbm9tYnJlcywgcGVybyBubyBzZSBwdWVkZSBoYWNlciByZWZlcmVuY2lhIGEgbG9zIGNvbXBvbmVudGVzIHNpbiBlc3BhY2lvIGRlIG5vbWJyZXMgZGUgZGVzdGlubyBkZXNkZSBlbCBkb2N1bWVudG8gZGUgZXNxdWVtYSAnJ3swfScnLiBTaSBzZSBwcmV0ZW5kZSBxdWUnJ3syfScnIHRlbmdhIHVuIGVzcGFjaW8gZGUgbm9tYnJlcywgcHVlZGUgcXVlIHNlYSBuZWNlc2FyaW8gcHJvcG9yY2lvbmFyIHVuIHByZWZpam8uIFNpIHNlIHByZXRlbmRlIHF1ZSAnJ3syfScnIG5vIHRlbmdhIG5pbmdcdTAwRkFuIGVzcGFjaW8gZGUgbm9tYnJlcywgZXMgbmVjZXNhcmlvIGFncmVnYXIgdW4gYXRyaWJ1dG8gJydpbXBvcnQnJyBzaW4gdW4gYXRyaWJ1dG8gIm5hbWVzcGFjZSIgYSAnJ3swfScnLgotICAgICAgICBzcmMtcmVzb2x2ZS40LjIgPSBzcmMtcmVzb2x2ZS40LjI6IEVycm9yIGFsIHJlc29sdmVyIGVsIGNvbXBvbmVudGUgJyd7Mn0nJy4gU2UgaGEgZGV0ZWN0YWRvIHF1ZSAnJ3syfScnIGVzdFx1MDBFMSBlbiBlbCBlc3BhY2lvIGRlIG5vbWJyZXMgJyd7MX0nJywgcGVybyBubyBzZSBwdWVkZSBoYWNlciByZWZlcmVuY2lhIGEgbG9zIGNvbXBvbmVudGVzIGRlIGVzdGUgZXNwYWNpbyBkZSBub21icmVzIGRlc2RlIGVsIGRvY3VtZW50byBkZSBlc3F1ZW1hICcnezB9JycuIFNpIGVzIGVsIGVzcGFjaW8gZGUgbm9tYnJlcyBpbmNvcnJlY3RvLCBwdWVkZSBxdWUgc2VhIG5lY2VzYXJpbyBjYW1iaWFyIGVsIHByZWZpam8gJyd7Mn0nJy4gU2kgZXMgZWwgZXNwYWNpbyBkZSBub21icmVzIGNvcnJlY3RvLCBlcyBuZWNlc2FyaW8gYWdyZWdhciBsYSBldGlxdWV0YSAnJ2ltcG9ydCcnIGNvcnJlc3BvbmRpZW50ZSBhICcnezB9JycuCi0gICAgICAgIHNyYy1zaW1wbGUtdHlwZS4yLmEgPSBzcmMtc2ltcGxlLXR5cGUuMi5hOiBTZSBoYSBlbmNvbnRyYWRvIHVuIGVsZW1lbnRvIDxyZXN0cmljdGlvbj4gcXVlIHRpZW5lIHVuIFthdHJpYnV0b10gYmFzZSB5IHVuIGVsZW1lbnRvIDxzaW1wbGVUeXBlPiBlbnRyZSBzdXMgW3NlY3VuZGFyaW9zXS4gU1x1MDBGM2xvIHNlIHBlcm1pdGUgdW5vLgotICAgICAgICBzcmMtc2ltcGxlLXR5cGUuMi5iID0gc3JjLXNpbXBsZS10eXBlLjIuYjogU2UgaGEgZW5jb250cmFkbyB1biBlbGVtZW50byA8cmVzdHJpY3Rpb24+IHF1ZSBubyB0aWVuZSBuaSB1biBbYXRyaWJ1dG9dIGJhc2UgbmkgdW4gZWxlbWVudG8gPHNpbXBsZVR5cGU+IGVudHJlIHN1cyBbc2VjdW5kYXJpb3NdLiBTZSByZXF1aWVyZSB1bm8uCi0gICAgICAgIHNyYy1zaW1wbGUtdHlwZS4zLmEgPSBzcmMtc2ltcGxlLXR5cGUuMy5hOiBTZSBoYSBlbmNvbnRyYWRvIHVuIGVsZW1lbnRvIDxsaXN0PiBxdWUgdGllbmUgdW4gW2F0cmlidXRvXSBpdGVtVHlwZSB5IHVuIGVsZW1lbnRvIDxzaW1wbGVUeXBlPiBlbnRyZSBzdXMgW3NlY3VuZGFyaW9zXS4gU1x1MDBGM2xvIHNlIHBlcm1pdGUgdW5vLgotICAgICAgICBzcmMtc2ltcGxlLXR5cGUuMy5iID0gc3JjLXNpbXBsZS10eXBlLjMuYjogU2UgaGEgZW5jb250cmFkbyB1biBlbGVtZW50byA8bGlzdD4gcXVlIG5vIHRpZW5lIG5pIHVuIFthdHJpYnV0b10gaXRlbVR5cGUgbmkgdW4gZWxlbWVudG8gPHNpbXBsZVR5cGU+IGVudHJlIHN1cyBbc2VjdW5kYXJpb3NdLiBTZSByZXF1aWVyZSB1bm8uCi0gICAgICAgIHNyYy1zaW5nbGUtZmFjZXQtdmFsdWUgPSBzcmMtc2luZ2xlLWZhY2V0LXZhbHVlOiBMYSBmYWNldGEgJyd7MH0nJyBlc3RcdTAwRTEgZGVmaW5pZGEgbVx1MDBFMXMgZGUgdW5hIHZlei4KLSAgICAgICAgc3JjLXVuaW9uLW1lbWJlclR5cGVzLW9yLXNpbXBsZVR5cGVzID0gc3JjLXVuaW9uLW1lbWJlclR5cGVzLW9yLXNpbXBsZVR5cGVzOiBVbiBlbGVtZW50byA8dW5pb24+IGRlYmUgdGVuZXIgdW4gW2F0cmlidXRvXSBtZW1iZXJUeXBlcyBubyB2YWNcdTAwRURvIG8gYWwgbWVub3MgdW4gZWxlbWVudG8gPHNpbXBsZVR5cGU+IGVudHJlIHN1cyBbc2VjdW5kYXJpb3NdLgotCi0jY29uc3RyYWludCB2YWxpZCAoMy5YLjYpCi0KLSAgICAgICAgYWctcHJvcHMtY29ycmVjdC4yID0gYWctcHJvcHMtY29ycmVjdC4yOiBFcnJvciBlbiBlbCBncnVwbyBkZSBhdHJpYnV0b3MgJyd7MH0nJy4gU2UgaGFuIGVzcGVjaWZpY2FkbyB1c29zIGRlIGF0cmlidXRvIGR1cGxpY2Fkb3MgY29uIGVsIG1pc21vIG5vbWJyZSB5IGVzcGFjaW8gZGUgbm9tYnJlcyBkZSBkZXN0aW5vLiBFbCBub21icmUgZGVsIHVzbyBkZSBhdHJpYnV0byBkdXBsaWNhZG8gZXMgJyd7MX0nJy4KLSAgICAgICAgYWctcHJvcHMtY29ycmVjdC4zID0gYWctcHJvcHMtY29ycmVjdC4zOiBFcnJvciBlbiBlbCBncnVwbyBkZSBhdHJpYnV0b3MgJyd7MH0nJy4gRG9zIGRlY2xhcmFjaW9uZXMgZGUgYXRyaWJ1dG8sICcnezF9JycgeSAnJ3syfScnLCB0aWVuZW4gdGlwb3MgcXVlIHNlIGRlcml2YW4gZGVsIGlkZW50aWZpY2Fkb3IuCi0gICAgICAgIGEtcHJvcHMtY29ycmVjdC4yID0gYS1wcm9wcy1jb3JyZWN0LjI6IFZhbG9yIGRlIHJlc3RyaWNjaVx1MDBGM24gZGUgdmFsb3IgJyd7MX0nJyBubyB2XHUwMEUxbGlkbyBlbiBlbCBhdHJpYnV0byAnJ3swfScnLgotICAgICAgICBhLXByb3BzLWNvcnJlY3QuMyA9IGEtcHJvcHMtY29ycmVjdC4zOiBFbCBhdHJpYnV0byAnJ3swfScnIG5vIHB1ZWRlIHV0aWxpemFyICcnZml4ZWQnJyBuaSAnJ2RlZmF1bHQnJywgcG9ycXVlIGVsIHZhbG9yIGRlICd7J3R5cGUgZGVmaW5pdGlvbid9JyBkZWwgYXRyaWJ1dG8gZXMgZWwgaWRlbnRpZmljYWRvciBvIHNlIGRlcml2YSBkZWwgaWRlbnRpZmljYWRvci4KLSAgICAgICAgYXUtcHJvcHMtY29ycmVjdC4yID0gYXUtcHJvcHMtY29ycmVjdC4yOiBFbiBsYSBkZWNsYXJhY2lcdTAwRjNuIGRlIGF0cmlidXRvIGRlICcnezB9JycsIHNlIGhhIGVzcGVjaWZpY2FkbyB1biB2YWxvciBmaWpvIGRlICcnezF9JycuIFBvciBsbyB0YW50bywgc2kgZWwgdXNvIGRlbCBhdHJpYnV0byBxdWUgaGFjZSByZWZlcmVuY2lhIGEgJyd7MH0nJyB0YW1iaVx1MDBFOW4gdGllbmUgdW4gdmFsb3IgZGUgJ3sndmFsdWUgY29uc3RyYWludCd9JywgZGViZSBmaWphcnNlIHkgZWwgdmFsb3IgZGViZSBzZXIgJyd7MX0nJy4KLSAgICAgICAgY29zLWFsbC1saW1pdGVkLjEuMiA9IGNvcy1hbGwtbGltaXRlZC4xLjI6RGViZSBhcGFyZWNlciB1biBncnVwbyBkZSBtb2RlbG9zICdhbGwnIGVuIHVuYSBwYXJ0XHUwMEVEY3VsYSBjb24gJ3snbWluIG9jY3Vycyd9JyA9ICd7J21heCBvY2N1cnMnfScgPSAxIHkgZGljaGEgcGFydFx1MDBFRGN1bGEgZGViZSBmb3JtYXIgcGFydGUgZGUgdW4gcGFyIHF1ZSBjb25zdGl0dXlhIGVsIHZhbG9yIGRlICd7J2NvbnRlbnQgdHlwZSd9JyBkZSB1bmEgZGVmaW5pY2lcdTAwRjNuIGRlIHRpcG8gY29tcGxlam8uCi0gICAgICAgIGNvcy1hbGwtbGltaXRlZC4yID0gY29zLWFsbC1saW1pdGVkLjI6IEVsIHZhbG9yIGRlICd7J21heCBvY2N1cnMnfScgZGUgdW4gZWxlbWVudG8gZGUgdW4gZ3J1cG8gZGUgbW9kZWxvcyAnJ2FsbCcnIGRlYmUgc2VyIDAgbyAxLiBFbCB2YWxvciAnJ3swfScnIGRlbCBlbGVtZW50byAnJ3sxfScnIG5vIGVzIHZcdTAwRTFsaWRvLgotICAgICAgICBjb3MtYXBwbGljYWJsZS1mYWNldHMgPSBjb3MtYXBwbGljYWJsZS1mYWNldHM6IEVsIHRpcG8gezF9IG5vIHBlcm1pdGUgbGEgZmFjZXRhICcnezB9JycuCi0gICAgICAgIGNvcy1jdC1leHRlbmRzLjEuMSA9IGNvcy1jdC1leHRlbmRzLjEuMTogRWwgdGlwbyAnJ3swfScnIHNlIGhhIGRlcml2YWRvIHBvciBleHRlbnNpXHUwMEYzbiBkZWwgdGlwbyAnJ3sxfScnLiBTaW4gZW1iYXJnbywgZWwgYXRyaWJ1dG8gJydmaW5hbCcnIGRlICcnezF9JycgcHJvaFx1MDBFRGJlIGxhIGRlcml2YWNpXHUwMEYzbiBwb3IgZXh0ZW5zaVx1MDBGM24uCi0gICAgICAgIGNvcy1jdC1leHRlbmRzLjEuNC4zLjIuMi4xLmEgPSBjb3MtY3QtZXh0ZW5kcy4xLjQuMy4yLjIuMS5hOiBFbCB0aXBvIGRlIGNvbnRlbmlkbyBkZSB1biB0aXBvIGRlcml2YWRvIHkgZWwgZGUgc3UgYmFzZSBkZWJlbiBzZXIgbWl4dG9zIG8gc2VyIGFtYm9zIHNcdTAwRjNsbyBkZSBlbGVtZW50by4gRWwgdGlwbyAnJ3swfScnIGVzIGRlIHNcdTAwRjNsbyBlbGVtZW50bywgcGVybyBzdSB0aXBvIGJhc2Ugbm8gbG8gZXMuCi0gICAgICAgIGNvcy1jdC1leHRlbmRzLjEuNC4zLjIuMi4xLmIgPSBjb3MtY3QtZXh0ZW5kcy4xLjQuMy4yLjIuMS5iOiBFbCB0aXBvIGRlIGNvbnRlbmlkbyBkZSB1biB0aXBvIGRlcml2YWRvIHkgZWwgZGUgc3UgYmFzZSBkZWJlbiBzZXIgbWl4dG9zIG8gc2VyIGFtYm9zIHNcdTAwRjNsbyBkZSBlbGVtZW50by4gRWwgdGlwbyAnJ3swfScnIGVzIG1peHRvLCBwZXJvIHN1IHRpcG8gYmFzZSBubyBsbyBlcy4KLSAgICAgICAgY29zLWVsZW1lbnQtY29uc2lzdGVudCA9IGNvcy1lbGVtZW50LWNvbnNpc3RlbnQ6IEVycm9yIHBhcmEgZWwgdGlwbyAnJ3swfScnLiBBcGFyZWNlbiBlbiBlbCBncnVwbyBkZSBtb2RlbG9zIHZhcmlvcyBlbGVtZW50b3MgY29uIGVsIG5vbWJyZSAnJ3sxfScnIHkgY29uIHRpcG9zIGRpZmVyZW50ZXMuCi0gICAgICAgIGNvcy1saXN0LW9mLWF0b21pYyA9IGNvcy1saXN0LW9mLWF0b21pYzogRW4gbGEgZGVmaW5pY2lcdTAwRjNuIGRlIHRpcG8gZGUgbGlzdGEgJyd7MH0nJywgZWwgdGlwbyAnJ3sxfScnIGVzIHVuIHRpcG8gZGUgZWxlbWVudG8gZGUgbGlzdGEgbm8gdlx1MDBFMWxpZG8gcG9ycXVlIG5vIGVzIGF0XHUwMEYzbWljbyAoJyd7MX0nJyBlcyB1biB0aXBvIGRlIGxpc3RhIG8gdW4gdGlwbyBkZSB1bmlcdTAwRjNuIHF1ZSBjb250aWVuZSB1bmEgbGlzdGEpLgotICAgICAgICBjb3Mtbm9uYW1iaWcgPSBjb3Mtbm9uYW1iaWc6IHswfSB5IHsxfSAobyBsb3MgZWxlbWVudG9zIGRlIHN1IGdydXBvIGRlIHN1c3RpdHVjaVx1MDBGM24pIHZpb2xhbiBsYSAiYXRyaWJ1Y2lcdTAwRjNuIGRlIHBhcnRcdTAwRURjdWxhIFx1MDBGQW5pY2EiLiBEdXJhbnRlIGxhIHZhbGlkYWNpXHUwMEYzbiBhIHBhcnRpciBkZSBlc3RlIGVzcXVlbWEsIHNlIGNyZWFyXHUwMEUxIGFtYmlnXHUwMEZDZWRhZCBwYXJhIGVzdGFzIGRvcyBwYXJ0XHUwMEVEY3VsYXMuCi0gICAgICAgIGNvcy1wYXJ0aWNsZS1yZXN0cmljdC5hID0gY29zLXBhcnRpY2xlLXJlc3RyaWN0LmE6IExhIHBhcnRcdTAwRURjdWxhIGRlcml2YWRhIGVzdFx1MDBFMSB2YWNcdTAwRURhIHkgbGEgYmFzZSBubyBzZSBwdWVkZSB2YWNpYXIuCi0gICAgICAgIGNvcy1wYXJ0aWNsZS1yZXN0cmljdC5iID0gY29zLXBhcnRpY2xlLXJlc3RyaWN0LmI6IExhIHBhcnRcdTAwRURjdWxhIGJhc2UgZXN0XHUwMEUxIHZhY1x1MDBFRGEsIHBlcm8gbGEgcGFydFx1MDBFRGN1bGEgZGVyaXZhZGEgbm8uCi0gICAgICAgIGNvcy1wYXJ0aWNsZS1yZXN0cmljdC4yID0gY29zLXBhcnRpY2xlLXJlc3RyaWN0LjI6IFJlc3RyaWNjaVx1MDBGM24gZGUgcGFydFx1MDBFRGN1bGEgcHJvaGliaWRhOiAnJ3swfScnLgotICAgICAgICBjb3Mtc3QtcmVzdHJpY3RzLjEuMSA9IGNvcy1zdC1yZXN0cmljdHMuMS4xOiBFbCB0aXBvICcnezF9JycgZXMgYXRcdTAwRjNtaWNvLCBwb3IgbG8gcXVlIHN1ICd7J2Jhc2UgdHlwZSBkZWZpbml0aW9uJ30nLCAnJ3swfScnLCBkZWJlIHNlciB1bmEgZGVmaW5pY2lcdTAwRjNuIGRlIHRpcG8gc2ltcGxlIGF0XHUwMEYzbWljbyBvIHVuIHRpcG8gZGUgZGF0byBwcmltaXRpdm8gaW5jb3Jwb3JhZG8uCi0gICAgICAgIGNvcy1zdC1yZXN0cmljdHMuMi4xID0gY29zLXN0LXJlc3RyaWN0cy4yLjE6IEVuIGxhIGRlZmluaWNpXHUwMEYzbiBkZSB0aXBvIGRlIGxpc3RhICcnezB9JycsIGVsIHRpcG8gJyd7MX0nJyBlcyB1biB0aXBvIGRlIGVsZW1lbnRvIG5vIHZcdTAwRTFsaWRvIHBvcnF1ZSBlcyB1biB0aXBvIGRlIGxpc3RhIG8gdW4gdGlwbyBkZSB1bmlcdTAwRjNuIHF1ZSBjb250aWVuZSB1bmEgbGlzdGEuCi0gICAgICAgIGNvcy1zdC1yZXN0cmljdHMuMi4zLjEuMSA9IGNvcy1zdC1yZXN0cmljdHMuMi4zLjEuMTogRWwgY29tcG9uZW50ZSAneydmaW5hbCd9JyBkZSAneydpdGVtIHR5cGUgZGVmaW5pdGlvbid9JywgJyd7MH0nJywgY29udGllbmUgJydsaXN0JycuIFNpZ25pZmljYSBxdWUgJyd7MH0nJyBubyBzZSBwdWVkZSB1dGlsaXphciBjb21vIHVuIHRpcG8gZGUgZWxlbWVudG8gcGFyYSBlbCB0aXBvIGRlIGxpc3RhICcnezF9JycuCi0gICAgICAgIGNvcy1zdC1yZXN0cmljdHMuMy4zLjEuMSA9IGNvcy1zdC1yZXN0cmljdHMuMy4zLjEuMTogRWwgY29tcG9uZW50ZSAneydmaW5hbCd9JyBkZSAneydtZW1iZXIgdHlwZSBkZWZpbml0aW9ucyd9JywgJyd7MH0nJywgY29udGllbmUgJyd1bmlvbicnLiBTaWduaWZpY2EgcXVlICcnezB9Jycgbm8gc2UgcHVlZGUgdXRpbGl6YXIgY29tbyB1biB0aXBvIGRlIG1pZW1icm8gcGFyYSBlbCB0aXBvIGRlIHVuaVx1MDBGM24gJyd7MX0nJy4KLSAgICAgICAgY29zLXZhbGlkLWRlZmF1bHQuMi4xID0gY29zLXZhbGlkLWRlZmF1bHQuMi4xOiBFbCBlbGVtZW50byAnJ3swfScnIGNvbnRpZW5lIHVuYSByZXN0cmljY2lcdTAwRjNuIGRlIHZhbG9yIHkgZGViZSB0ZW5lciB1biBtb2RlbG8gZGUgY29udGVuaWRvIG1peHRvIG8gc2ltcGxlLgotICAgICAgICBjb3MtdmFsaWQtZGVmYXVsdC4yLjIuMiA9IGNvcy12YWxpZC1kZWZhdWx0LjIuMi4yOiBDb21vIGVsIGVsZW1lbnRvICcnezB9JycgdGllbmUgdW5hICd7J3ZhbHVlIGNvbnN0cmFpbnQnfScgeSBzdSBkZWZpbmljaVx1MDBGM24gZGUgdGlwbyB0aWVuZSB1biAneydjb250ZW50IHR5cGUnfScgbWl4dG8sIGxhIHBhcnRcdTAwRURjdWxhIGRlICd7J2NvbnRlbnQgdHlwZSd9JyBkZWJlIHBvZGVyIHZhY2lhcnNlLgotICAgICAgICBjLXByb3BzLWNvcnJlY3QuMiA9IGMtcHJvcHMtY29ycmVjdC4yOiBMYSBjYXJkaW5hbGlkYWQgZGUgbG9zIGNhbXBvcyBkZSBsYSByZWZlcmVuY2lhIGRlIGNsYXZlICcnezB9JycgeSBsYSBjbGF2ZSAnJ3sxfScnIGRlYmVuIGNvaW5jaWRpci4KLSAgICAgICAgY3QtcHJvcHMtY29ycmVjdC4zID0gY3QtcHJvcHMtY29ycmVjdC4zOiBTZSBoYW4gZGV0ZWN0YWRvIGRlZmluaWNpb25lcyBjaXJjdWxhcmVzIHBhcmEgZWwgdGlwbyBjb21wbGVqbyAnJ3swfScnLiBTaWduaWZpY2EgcXVlICcnezB9JycgZXN0XHUwMEUxIGNvbnRlbmlkbyBlbiBzdSBwcm9waWEgamVyYXJxdVx1MDBFRGEgZGUgdGlwb3MsIGxvIHF1ZSBlcyB1biBlcnJvci4KLSAgICAgICAgY3QtcHJvcHMtY29ycmVjdC40ID0gY3QtcHJvcHMtY29ycmVjdC40OiBFcnJvciBwYXJhIGVsIHRpcG8gJyd7MH0nJy4gU2UgaGFuIGVzcGVjaWZpY2FkbyB1c29zIGRlIGF0cmlidXRvIGR1cGxpY2Fkb3MgY29uIGVsIG1pc21vIG5vbWJyZSB5IGVzcGFjaW8gZGUgbm9tYnJlcyBkZSBkZXN0aW5vLiBFbCBub21icmUgZGVsIHVzbyBkZSBhdHJpYnV0byBkdXBsaWNhZG8gZXMgJyd7MX0nJy4KLSAgICAgICAgY3QtcHJvcHMtY29ycmVjdC41ID0gY3QtcHJvcHMtY29ycmVjdC41OiBFcnJvciBwYXJhIGVsIHRpcG8gJyd7MH0nJy4gRG9zIGRlY2xhcmFjaW9uZXMgZGUgYXRyaWJ1dG8sICcnezF9JycgeSAnJ3syfScnLCcnIHRpZW5lbiB0aXBvcyBxdWUgc2UgZGVyaXZhbiBkZWwgaWRlbnRpZmljYWRvci4KLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4xID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4xOiBFbCB0aXBvICcnezB9Jycgc2UgaGEgZGVyaXZhZG8gcG9yIHJlc3RyaWNjaVx1MDBGM24gZGVsIHRpcG8gJyd7MX0nJy4gU2luIGVtYmFyZ28sICcnezF9JycgdGllbmUgdW5hIHByb3BpZWRhZCAneydmaW5hbCd9JyBxdWUgcHJvaFx1MDBFRGJlIGxhIGRlcml2YWNpXHUwMEYzbiBwb3IgcmVzdHJpY2NpXHUwMEYzbi4KLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4yLjEuMSA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMi4xLjE6IEVycm9yIHBhcmEgZWwgdGlwbyAnJ3swfScnLiBFbCB1c28gZGUgYXRyaWJ1dG8gJyd7MX0nJyBlbiBlc3RlIHRpcG8gdGllbmUgdW4gdmFsb3IgJyd1c2UnJyBkZSAnJ3syfScnLCBxdWUgZXMgaW5jb2hlcmVudGUgY29uIGVsIHZhbG9yIGRlICcncmVxdWlyZWQnJyBlbiB1biB1c28gZGUgYXRyaWJ1dG8gY29pbmNpZGVudGUgZGVsIHRpcG8gYmFzZS4KLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4yLjEuMiA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMi4xLjI6IEVycm9yIHBhcmEgZWwgdGlwbyAnJ3swfScnLiBFbCB1c28gZGUgYXRyaWJ1dG8gJyd7MX0nJyBlbiBlc3RlIHRpcG8gdGllbmUgZWwgdGlwbyAnJ3syfScnLCBxdWUgbm8gc2UgaGEgZGVyaXZhZG8gZGUgZm9ybWEgdlx1MDBFMWxpZGEgZGUgJyd7M30nJywgZWwgdGlwbyBkZSB1c28gZGUgYXRyaWJ1dG8gY29pbmNpZGVudGUgZGVsIHRpcG8gYmFzZS4KLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4yLjEuMy5hID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4yLjEuMy5hOiBFcnJvciBwYXJhIGVsIHRpcG8gJyd7MH0nJy4gRWwgdXNvIGRlIGF0cmlidXRvICcnezF9JycgZW4gZXN0ZSB0aXBvIHRpZW5lIHVuYSByZXN0cmljY2lcdTAwRjNuIGRlIHZhbG9yIGVmZWN0aXZvIHF1ZSBubyBlcyBmaWphIHkgbGEgcmVzdHJpY2NpXHUwMEYzbiBkZSB2YWxvciBlZmVjdGl2byBkZWwgdXNvIGRlIGF0cmlidXRvIGNvaW5jaWRlbnRlIGVuIGVsIHRpcG8gYmFzZSBlcyBmaWphLgotICAgICAgICBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjIuMS4zLmIgPSBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjIuMS4zLmI6IEVycm9yIHBhcmEgZWwgdGlwbyAnJ3swfScnLiBFbCB1c28gZGUgYXRyaWJ1dG8gJyd7MX0nJyBlbiBlc3RlIHRpcG8gdGllbmUgdW5hIHJlc3RyaWNjaVx1MDBGM24gZGUgdmFsb3IgZWZlY3Rpdm8gZmlqYSBjb24gdW4gdmFsb3IgZGUgJyd7Mn0nJywgcXVlIG5vIGVzIGNvaGVyZW50ZSBjb24gZWwgdmFsb3IgZGUgJyd7M30nJyBwYXJhIGxhIHJlc3RyaWNjaVx1MDBGM24gZGUgdmFsb3IgZWZlY3Rpdm8gZmlqYSBkZWwgdXNvIGRlIGF0cmlidXRvIGNvaW5jaWRlbnRlIGVuIGVsIHRpcG8gYmFzZS4KLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4yLjIuYSA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMi4yLmE6IEVycm9yIHBhcmEgZWwgdGlwbyAnJ3swfScnLiBFbCB1c28gZGUgYXRyaWJ1dG8gJyd7MX0nJyBlbiBlc3RlIHRpcG8gbm8gdGllbmUgdW4gdXNvIGRlIGF0cmlidXRvIGNvaW5jaWRlbnRlIGVuIGxhIGJhc2UgeSBlbCB0aXBvIGJhc2Ugbm8gdGllbmUgdW4gYXRyaWJ1dG8gZGUgY29tb2RcdTAwRURuLgotICAgICAgICBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjIuMi5iID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4yLjIuYjogRXJyb3IgcGFyYSBlbCB0aXBvICcnezB9JycuIEVsIHVzbyBkZSBhdHJpYnV0byAnJ3sxfScnIGVuIGVzdGUgdGlwbyBubyB0aWVuZSB1biB1c28gZGUgYXRyaWJ1dG8gY29pbmNpZGVudGUgZW4gbGEgYmFzZSB5IGVsIGNvbW9kXHUwMEVEbiBlbiBlbCB0aXBvIGJhc2Ugbm8gcGVybWl0ZSBlbCBlc3BhY2lvIGRlIG5vbWJyZXMgJyd7Mn0nJyBkZSBlc3RlIHVzbyBkZSBhdHJpYnV0by4KLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4zID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4zOiBFcnJvciBwYXJhIGVsIHRpcG8gJyd7MH0nJy4gRWwgdXNvIGRlIGF0cmlidXRvICcnezF9JycgZW4gZWwgdGlwbyBiYXNlIHRpZW5lIGVsIHZhbG9yIFJFUVVJUkVEIGNvbW8gdHJ1ZSwgcGVybyBubyBoYXkgbmluZ1x1MDBGQW4gdXNvIGRlIGF0cmlidXRvIGNvaW5jaWRlbnRlIGVuIGVsIHRpcG8gZGVyaXZhZG8uCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uNC4xID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi40LjE6IEVycm9yIHBhcmEgZWwgdGlwbyAnJ3swfScnLiBMYSBkZXJpdmFjaVx1MDBGM24gdGllbmUgdW4gY29tb2RcdTAwRURuIGRlIGF0cmlidXRvLCBwZXJvIGxhIGJhc2Ugbm8gdGllbmUgdW5vLgotICAgICAgICBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjQuMiA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uNC4yOiBFcnJvciBwYXJhIGVsIHRpcG8gJyd7MH0nJy4gRWwgY29tb2RcdTAwRURuIGRlIGxhIGRlcml2YWNpXHUwMEYzbiBubyBlcyB1biBzdWJqdWVnbyBkZSBjb21vZGluZXMgdlx1MDBFMWxpZG8gZGVsIGRlIGxhIGJhc2UuCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uNC4zID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi40LjM6IEVycm9yIHBhcmEgZWwgdGlwbyAnJ3swfScnLiBFbCBjb250ZW5pZG8gZGVsIHByb2Nlc28gZGVsIGNvbW9kXHUwMEVEbiBkZSBsYSBkZXJpdmFjaVx1MDBGM24gKHsxfSkgZXMgbVx1MDBFMXMgZFx1MDBFOWJpbCBxdWUgZWwgZGUgbGEgYmFzZSAoezJ9KS4KLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi41LjIuMi4xID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi41LjIuMi4xOiBFcnJvciBwYXJhIGVsIHRpcG8gJyd7MH0nJy4gRWwgdGlwbyBkZSBjb250ZW5pZG8gc2ltcGxlIGRlIGVzdGUgdGlwbywgJyd7MX0nJywgbm8gZXMgdW5hIHJlc3RyaWNjaVx1MDBGM24gdlx1MDBFMWxpZGEgZGVsIHRpcG8gZGUgY29udGVuaWRvIHNpbXBsZSBkZSBsYSBiYXNlLCAnJ3syfScnLgotICAgICAgICBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjUuMy4yID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi41LjMuMjogRXJyb3IgcGFyYSBlbCB0aXBvICcnezB9JycuIEVsIHRpcG8gZGUgY29udGVuaWRvIGRlIGVzdGUgdGlwbyBlc3RcdTAwRTEgdmFjXHUwMEVEbywgcGVybyBlbCB0aXBvIGRlIGNvbnRlbmlkbyBkZSBsYSBiYXNlLCAnJ3sxfScnLCBubyBlc3RcdTAwRTEgdmFjXHUwMEVEbyBvIG5vIHNlIHB1ZWRlIHZhY2lhci4KLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi41LjQuMS4yID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi41LjQuMS4yOiBFcnJvciBwYXJhIGVsIHRpcG8gJyd7MH0nJy4gRWwgdGlwbyBkZSBjb250ZW5pZG8gZGUgZXN0ZSB0aXBvIGVzIG1peHRvLCBwZXJvIGVsIHRpcG8gZGUgY29udGVuaWRvIGRlIGxhIGJhc2UsICcnezF9JycsIG5vIGxvIGVzLgotICAgICAgICBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjUuNC4yID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi41LjQuMjogRXJyb3IgcGFyYSBlbCB0aXBvICcnezB9JycuIExhIHBhcnRcdTAwRURjdWxhIGRlbCB0aXBvIG5vIGVzIHVuYSByZXN0cmljY2lcdTAwRjNuIHZcdTAwRTFsaWRhIGRlIGxhIHBhcnRcdTAwRURjdWxhIGRlIGxhIGJhc2UuCi0gICAgICAgIGVudW1lcmF0aW9uLXJlcXVpcmVkLW5vdGF0aW9uID0gZW51bWVyYXRpb24tcmVxdWlyZWQtbm90YXRpb246IEVsIHRpcG8gTk9UQVRJT04gJyd7MH0nJywgdXRpbGl6YWRvIHBvciB7Mn0gJyd7MX0nJywgZGViZSB0ZW5lciB1biB2YWxvciBkZSBmYWNldGEgZGUgZW51bWVyYWNpXHUwMEYzbiBxdWUgZXNwZWNpZmlxdWUgbG9zIGVsZW1lbnRvcyBkZSBub3RhY2lcdTAwRjNuIHF1ZSB1dGlsaXphIGVzdGUgdGlwby4KLSAgICAgICAgZW51bWVyYXRpb24tdmFsaWQtcmVzdHJpY3Rpb24gPSBlbnVtZXJhdGlvbi12YWxpZC1yZXN0cmljdGlvbjogRWwgdmFsb3IgZGUgZW51bWVyYWNpXHUwMEYzbiAnJ3swfScnIG5vIHNlIGVuY3VlbnRyYSBlbiBlbCBlc3BhY2lvIHJlc2VydmFkbyBwYXJhIGVsIHZhbG9yIGRlbCB0aXBvIGJhc2UsIHsxfS4KLSAgICAgICAgZS1wcm9wcy1jb3JyZWN0LjIgPSBlLXByb3BzLWNvcnJlY3QuMjogVmFsb3IgZGUgcmVzdHJpY2NpXHUwMEYzbiBkZSB2YWxvciAnJ3sxfScnIG5vIHZcdTAwRTFsaWRvIGVuIGVsIGVsZW1lbnRvICcnezB9JycuCi0gICAgICAgIGUtcHJvcHMtY29ycmVjdC40ID0gZS1wcm9wcy1jb3JyZWN0LjQ6IEVsIHZhbG9yIGRlICd7J3R5cGUgZGVmaW5pdGlvbid9JyBkZWwgZWxlbWVudG8gJyd7MH0nJyBubyBzZSBoYSBkZXJpdmFkbyBkZSBmb3JtYSB2XHUwMEUxbGlkYSBkZWwgdmFsb3IgZGUgJ3sndHlwZSBkZWZpbml0aW9uJ30nIGRlIHN1YnN0aXR1dGlvbkhlYWQgJyd7MX0nJyBvIGxhIHByb3BpZWRhZCAneydzdWJzdGl0dXRpb24gZ3JvdXAgZXhjbHVzaW9ucyd9JyBkZSAnJ3sxfScnIG5vIHBlcm1pdGUgZXN0YSBkZXJpdmFjaVx1MDBGM24uCi0gICAgICAgIGUtcHJvcHMtY29ycmVjdC41ID0gZS1wcm9wcy1jb3JyZWN0LjU6IFVuIHZhbG9yIGRlICd7J3ZhbHVlIGNvbnN0cmFpbnQnfScgbm8gZGViZSBlc3RhciBwcmVzZW50ZSBlbiBlbCBlbGVtZW50byAnJ3swfScnLCBwb3JxdWUgbGEgJ3sndHlwZSBkZWZpbml0aW9uJ30nIGRlbCBlbGVtZW50byBvIGVsICd7J2NvbnRlbnQgdHlwZSd9JyBkZSAneyd0eXBlIGRlZmluaXRpb24nfScgZXMgdW4gaWRlbnRpZmljYWRvciBvIHNlIGRlcml2YSBkZWwgaWRlbnRpZmljYWRvci4KLSAgICAgICAgZS1wcm9wcy1jb3JyZWN0LjYgPSBlLXByb3BzLWNvcnJlY3QuNjogU2UgaGEgZGV0ZWN0YWRvIHVuIGdydXBvIGRlIHN1c3RpdHVjaVx1MDBGM24gY2lyY3VsYXIgcGFyYSBlbCBlbGVtZW50byAnJ3swfScnLgotICAgICAgICBmcmFjdGlvbkRpZ2l0cy12YWxpZC1yZXN0cmljdGlvbiA9IGZyYWN0aW9uRGlnaXRzLXZhbGlkLXJlc3RyaWN0aW9uOiBFbiBsYSBkZWZpbmljaVx1MDBGM24gZGUgezJ9LCBlbCB2YWxvciAnJ3swfScnIHBhcmEgbGEgZmFjZXRhICcnZnJhY3Rpb25EaWdpdHMnJyBubyBlcyB2XHUwMEUxbGlkbyBwb3JxdWUgZGViZSBzZXIgbWVub3IgbyBpZ3VhbCBxdWUgZWwgdmFsb3IgZGUgJydmcmFjdGlvbkRpZ2l0cycnIHF1ZSBzZSBoYSBkZWZpbmlkbyBlbiAnJ3sxfScnIGVuIHVubyBkZSBsb3MgdGlwb3MgZGUgYXNjZW5kaWVudGVzLgotICAgICAgICBmcmFjdGlvbkRpZ2l0cy10b3RhbERpZ2l0cyA9IGZyYWN0aW9uRGlnaXRzLXRvdGFsRGlnaXRzOiBFbiBsYSBkZWZpbmljaVx1MDBGM24gZGUgezJ9LCBlbCB2YWxvciAnJ3swfScnIHBhcmEgbGEgZmFjZXRhICcnZnJhY3Rpb25EaWdpdHMnJyBubyBlcyB2XHUwMEUxbGlkbyBwb3JxdWUgZGViZSBzZXIgbWVub3IgbyBpZ3VhbCBxdWUgZWwgdmFsb3IgZGUgJyd0b3RhbERpZ2l0cycnLCBxdWUgZXMgJyd7MX0nJy4KLSAgICAgICAgbGVuZ3RoLW1pbkxlbmd0aC1tYXhMZW5ndGguMS4xID0gbGVuZ3RoLW1pbkxlbmd0aC1tYXhMZW5ndGguMS4xOiBQYXJhIGVsIHRpcG8gezB9LCBlcyB1biBlcnJvciBxdWUgZWwgdmFsb3IgZGUgbGEgbG9uZ2l0dWQgJyd7MX0nJyBzZWEgaW5mZXJpb3IgYWwgdmFsb3IgZGUgbWluTGVuZ3RoICcnezJ9JycuCi0gICAgICAgIGxlbmd0aC1taW5MZW5ndGgtbWF4TGVuZ3RoLjEuMi5hID0gbGVuZ3RoLW1pbkxlbmd0aC1tYXhMZW5ndGguMS4yLmE6IFBhcmEgZWwgdGlwbyB7MH0sIGVzIHVuIGVycm9yIHF1ZSBsYSBiYXNlIG5vIHRlbmVyIHVuYSBmYWNldGEgZGUgbWluTGVuZ3RoIHNpIGxhIHJlc3RyaWNjaVx1MDBGM24gYWN0dWFsIHRpZW5lIGxhIGZhY2V0YSBkZSBtaW5MZW5ndGggeSBsYSByZXN0cmljY2lcdTAwRjNuIG8gYmFzZSBhY3R1YWwgdGllbmUgbGEgZmFjZXRhIGRlIGxvbmdpdHVkLgotICAgICAgICBsZW5ndGgtbWluTGVuZ3RoLW1heExlbmd0aC4xLjIuYiA9IGxlbmd0aC1taW5MZW5ndGgtbWF4TGVuZ3RoLjEuMi5iOiBQYXJhIGVsIHRpcG8gezB9LCBlcyB1biBlcnJvciBxdWUgZWwgdmFsb3IgZGUgbWluTGVuZ3RoIGFjdHVhbCAnJ3sxfScnIG5vIHNlYSBpZ3VhbCBhbCB2YWxvciBkZSBtaW5MZW5ndGggZGUgYmFzZSAnJ3syfScnLgotICAgICAgICBsZW5ndGgtbWluTGVuZ3RoLW1heExlbmd0aC4yLjEgPSBsZW5ndGgtbWluTGVuZ3RoLW1heExlbmd0aC4yLjE6IFBhcmEgZWwgdGlwbyB7MH0sIGVzIHVuIGVycm9yIHF1ZSBlbCB2YWxvciBkZSBsYSBsb25naXR1ZCAnJ3sxfScnIHNlYSBzdXBlcmlvciBhbCB2YWxvciBkZSBtYXhMZW5ndGggJyd7Mn0nJy4KLSAgICAgICAgbGVuZ3RoLW1pbkxlbmd0aC1tYXhMZW5ndGguMi4yLmEgPSBsZW5ndGgtbWluTGVuZ3RoLW1heExlbmd0aC4yLjIuYTogUGFyYSBlbCB0aXBvIHswfSwgZXMgdW4gZXJyb3IgcXVlIGxhIGJhc2Ugbm8gdGVuZXIgdW5hIGZhY2V0YSBkZSBtYXhMZW5ndGggc2kgbGEgcmVzdHJpY2NpXHUwMEYzbiBhY3R1YWwgdGllbmUgbGEgZmFjZXRhIGRlIG1heExlbmd0aCB5IGxhIHJlc3RyaWNjaVx1MDBGM24gbyBiYXNlIGFjdHVhbCB0aWVuZSBsYSBmYWNldGEgZGUgbG9uZ2l0dWQuCi0gICAgICAgIGxlbmd0aC1taW5MZW5ndGgtbWF4TGVuZ3RoLjIuMi5iID0gbGVuZ3RoLW1pbkxlbmd0aC1tYXhMZW5ndGguMi4yLmI6IFBhcmEgZWwgdGlwbyB7MH0sIGVzIHVuIGVycm9yIHF1ZSBlbCB2YWxvciBkZSBtYXhMZW5ndGggYWN0dWFsICcnezF9Jycgbm8gc2VhIGlndWFsIGFsIHZhbG9yIGRlIG1heExlbmd0aCBkZSBiYXNlICcnezJ9JycuCi0gICAgICAgIGxlbmd0aC12YWxpZC1yZXN0cmljdGlvbiA9IGxlbmd0aC12YWxpZC1yZXN0cmljdGlvbjogRXJyb3IgcGFyYSBlbCB0aXBvICcnezJ9JycuIEVsIHZhbG9yIGRlIGxhIGxvbmdpdHVkID0gJyd7MH0nJyBkZWJlIHNlciBpZ3VhbCBxdWUgZWwgdmFsb3IgZGVsIHRpcG8gYmFzZSAnJ3sxfScnLgotICAgICAgICBtYXhFeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMSA9IG1heEV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4xOiBFcnJvciBwYXJhIGVsIHRpcG8gJyd7Mn0nJy4gRWwgdmFsb3IgZGUgbWF4RXhjbHVzaXZlID0nJ3swfScnIGRlYmUgc2VyIG1lbm9yIG8gaWd1YWwgcXVlIGVsIHZhbG9yIGRlIG1heEV4Y2x1c2l2ZSBkZWwgdGlwbyBiYXNlICcnezF9JycuCi0gICAgICAgIG1heEV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4yID0gbWF4RXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjI6IEVycm9yIHBhcmEgZWwgdGlwbyAnJ3syfScnLiBFbCB2YWxvciBkZSBtYXhFeGNsdXNpdmUgPScnezB9JycgZGViZSBzZXIgbWVub3IgbyBpZ3VhbCBxdWUgZWwgdmFsb3IgZGUgbWF4SW5jbHVzaXZlIGRlbCB0aXBvIGJhc2UgJyd7MX0nJy4KLSAgICAgICAgbWF4RXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjMgPSBtYXhFeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMzogRXJyb3IgcGFyYSBlbCB0aXBvICcnezJ9JycuIEVsIHZhbG9yIGRlIG1heEV4Y2x1c2l2ZSA9Jyd7MH0nJ2RlYmUgc2VyIG1heW9yIHF1ZSBlbCB2YWxvciBkZSBtaW5JbmNsdXNpdmUgZGVsIHRpcG8gYmFzZSAnJ3sxfScnLgotICAgICAgICBtYXhFeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uNCA9IG1heEV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi40OiBFcnJvciBwYXJhIGVsIHRpcG8gJyd7Mn0nJy4gRWwgdmFsb3IgZGUgbWF4RXhjbHVzaXZlID0nJ3swfScnIGRlYmUgc2VyIG1heW9yIHF1ZSBlbCB2YWxvciBkZSBtaW5FeGNsdXNpdmUgZGVsIHRpcG8gYmFzZSAnJ3sxfScnLgotICAgICAgICBtYXhJbmNsdXNpdmUtbWF4RXhjbHVzaXZlID0gbWF4SW5jbHVzaXZlLW1heEV4Y2x1c2l2ZTogRXMgdW4gZXJyb3IgZXNwZWNpZmljYXIgbWF4SW5jbHVzaXZlIHkgbWF4RXhjbHVzaXZlIHBhcmEgZWwgbWlzbW8gdGlwbyBkZSBkYXRvLiBFbiB7Mn0sIG1heEluY2x1c2l2ZSA9ICcnezB9JycgeSBtYXhFeGNsdXNpdmUgPSAnJ3sxfScnLgotICAgICAgICBtYXhJbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMSA9IG1heEluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4xOiBFcnJvciBwYXJhIGVsIHRpcG8gJyd7Mn0nJy4gRWwgdmFsb3IgZGUgbWF4SW5jbHVzaXZlID0nJ3swfScnIGRlYmUgc2VyIG1lbm9yIG8gaWd1YWwgcXVlIGVsIHZhbG9yIGRlIG1heEluY2x1c2l2ZSBkZWwgdGlwbyBiYXNlICcnezF9JycuCi0gICAgICAgIG1heEluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4yID0gbWF4SW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjI6IEVycm9yIHBhcmEgZWwgdGlwbyAnJ3syfScnLiBFbCB2YWxvciBkZSBtYXhJbmNsdXNpdmUgPScnezB9JycgZGViZSBzZXIgbWVub3IgcXVlIGVsIHZhbG9yIGRlIG1heEV4Y2x1c2l2ZSBkZWwgdGlwbyBiYXNlICcnezF9JycuCi0gICAgICAgIG1heEluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4zID0gbWF4SW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjM6IEVycm9yIHBhcmEgZWwgdGlwbyAnJ3syfScnLiBFbCB2YWxvciBkZSBtYXhJbmNsdXNpdmUgPScnezB9JycgZGViZSBzZXIgbWF5b3IgbyBpZ3VhbCBxdWUgZWwgdmFsb3IgZGUgbWluSW5jbHVzaXZlIGRlbCB0aXBvIGJhc2UgJyd7MX0nJy4KLSAgICAgICAgbWF4SW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjQgPSBtYXhJbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uNDogRXJyb3IgcGFyYSBlbCB0aXBvICcnezJ9JycuIEVsIHZhbG9yIGRlIG1heEluY2x1c2l2ZSA9Jyd7MH0nJyBkZWJlIHNlciBtYXlvciBxdWUgZWwgdmFsb3IgZGUgbWluRXhjbHVzaXZlIGRlbCB0aXBvIGJhc2UgJyd7MX0nJy4KLSAgICAgICAgbWF4TGVuZ3RoLXZhbGlkLXJlc3RyaWN0aW9uID0gbWF4TGVuZ3RoLXZhbGlkLXJlc3RyaWN0aW9uOiBFbiBsYSBkZWZpbmljaVx1MDBGM24gZGUgezJ9LCBlbCB2YWxvciBkZSBtYXhMZW5ndGggPSAnJ3swfScnIGRlYmUgc2VyIG1lbm9yIG8gaWd1YWwgcXVlIGVsIGRlbCB0aXBvIGJhc2UgJyd7MX0nJy4KLSAgICAgICAgbWctcHJvcHMtY29ycmVjdC4yID0gbWctcHJvcHMtY29ycmVjdC4yOiBTZSBoYW4gZGV0ZWN0YWRvIGRlZmluaWNpb25lcyBjaXJjdWxhcmVzIHBhcmEgZWwgZ3J1cG8gJyd7MH0nJy4gRWwgc2VndWltaWVudG8gcmVjdXJyZW50ZSBkZSBsb3MgdmFsb3JlcyAneyd0ZXJtJ30nIGRlIGxhcyBwYXJ0XHUwMEVEY3VsYXMgcHJvdm9jYSB1bmEgcGFydFx1MDBFRGN1bGEgY3V5byB2YWxvciBkZSAneyd0ZXJtJ30nIGVzIGVsIG1pc21vIGdydXBvLgotICAgICAgICBtaW5FeGNsdXNpdmUtbGVzcy10aGFuLWVxdWFsLXRvLW1heEV4Y2x1c2l2ZSA9IG1pbkV4Y2x1c2l2ZS1sZXNzLXRoYW4tZXF1YWwtdG8tbWF4RXhjbHVzaXZlOiBFbiBsYSBkZWZpbmljaVx1MDBGM24gZGUgezJ9LCBlbCB2YWxvciBkZSBtaW5FeGNsdXNpdmUgPSAnJ3swfScnIGRlYmUgc2VyIG1lbm9yIG8gaWd1YWwgcXVlIGVsIHZhbG9yIGRlIG1heEV4Y2x1c2l2ZSA9ICcnezF9JycuCi0gICAgICAgIG1pbkV4Y2x1c2l2ZS1sZXNzLXRoYW4tbWF4SW5jbHVzaXZlID0gbWluRXhjbHVzaXZlLWxlc3MtdGhhbi1tYXhJbmNsdXNpdmU6IEVuIGxhIGRlZmluaWNpXHUwMEYzbiBkZSB7Mn0sIGVsIHZhbG9yIGRlIG1pbkV4Y2x1c2l2ZSA9ICcnezB9JydkZWJlIHNlciBtZW5vciBxdWUgZWwgdmFsb3IgZGUgbWF4SW5jbHVzaXZlID0gJyd7MX0nJy4KLSAgICAgICAgbWluRXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjEgPSBtaW5FeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMTogRXJyb3IgcGFyYSBlbCB0aXBvICcnezJ9JycuIEVsIHZhbG9yIGRlIG1pbkV4Y2x1c2l2ZSA9Jyd7MH0nJyBkZWJlIHNlciBtYXlvciBvIGlndWFsIHF1ZSBlbCB2YWxvciBkZSBtaW5FeGNsdXNpdmUgZGVsIHRpcG8gYmFzZSAnJ3sxfScnLgotICAgICAgICBtaW5FeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMiA9IG1pbkV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4yOiBFcnJvciBwYXJhIGVsIHRpcG8gJyd7Mn0nJy4gRWwgdmFsb3IgZGUgbWluRXhjbHVzaXZlID0nJ3swfScnIGRlYmUgc2VyIG1lbm9yIG8gaWd1YWwgcXVlIGVsIHZhbG9yIGRlIG1heEluY2x1c2l2ZSBkZWwgdGlwbyBiYXNlICcnezF9JycuCi0gICAgICAgIG1pbkV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4zID0gbWluRXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjM6IEVycm9yIHBhcmEgZWwgdGlwbyAnJ3syfScnLiBFbCB2YWxvciBkZSBtaW5FeGNsdXNpdmUgPScnezB9JycgZGViZSBzZXIgbWF5b3IgbyBpZ3VhbCBxdWUgZWwgdmFsb3IgZGUgbWluSW5jbHVzaXZlIGRlbCB0aXBvIGJhc2UgJyd7MX0nJy4KLSAgICAgICAgbWluRXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjQgPSBtaW5FeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uNDogRXJyb3IgcGFyYSBlbCB0aXBvICcnezJ9JycuIEVsIHZhbG9yIGRlIG1pbkV4Y2x1c2l2ZSA9Jyd7MH0nJyBkZWJlIHNlciBtZW5vciBxdWUgZWwgdmFsb3IgZGUgbWF4RXhjbHVzaXZlIGRlbCB0aXBvIGJhc2UgJyd7MX0nJy4KLSAgICAgICAgbWluSW5jbHVzaXZlLWxlc3MtdGhhbi1lcXVhbC10by1tYXhJbmNsdXNpdmUgPSBtaW5JbmNsdXNpdmUtbGVzcy10aGFuLWVxdWFsLXRvLW1heEluY2x1c2l2ZTogRW4gbGEgZGVmaW5pY2lcdTAwRjNuIGRlIHsyfSwgZWwgdmFsb3IgZGUgbWluSW5jbHVzaXZlID0gJyd7MH0nJyBkZWJlIHNlciBtZW5vciBvIGlndWFsIHF1ZSBlbCB2YWxvciBkZSBtYXhJbmNsdXNpdmUgPSAnJ3sxfScnLgotICAgICAgICBtaW5JbmNsdXNpdmUtbGVzcy10aGFuLW1heEV4Y2x1c2l2ZSA9IG1pbkluY2x1c2l2ZS1sZXNzLXRoYW4tbWF4RXhjbHVzaXZlOiBFbiBsYSBkZWZpbmljaVx1MDBGM24gZGUgezJ9LCBlbCB2YWxvciBkZSBtaW5JbmNsdXNpdmUgPSAnJ3swfScnIGRlYmUgc2VyIG1lbm9yIHF1ZSBlbCB2YWxvciBkZSBtYXhFeGNsdXNpdmUgPSAnJ3sxfScnLgotICAgICAgICBtaW5JbmNsdXNpdmUtbWluRXhjbHVzaXZlID0gbWluSW5jbHVzaXZlLW1pbkV4Y2x1c2l2ZTogRXMgdW4gZXJyb3IgZXNwZWNpZmljYXIgbWluSW5jbHVzaXZlIHkgbWluRXhjbHVzaXZlIHBhcmEgZWwgbWlzbW8gdGlwbyBkZSBkYXRvLiBFbiB7Mn0sIG1pbkluY2x1c2l2ZSA9ICcnezB9JycgeSBtaW5FeGNsdXNpdmUgPSAnJ3sxfScnLgotICAgICAgICBtaW5JbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMSA9IG1pbkluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4xOiBFcnJvciBwYXJhIGVsIHRpcG8gJyd7Mn0nJy4gRWwgdmFsb3IgZGUgbWluSW5jbHVzaXZlID0nJ3swfScnIGRlYmUgc2VyIG1heW9yIG8gaWd1YWwgcXVlIGVsIHZhbG9yIGRlIG1pbkluY2x1c2l2ZSBkZWwgdGlwbyBiYXNlICcnezF9JycuCi0gICAgICAgIG1pbkluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4yID0gbWluSW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjI6IEVycm9yIHBhcmEgZWwgdGlwbyAnJ3syfScnLiBFbCB2YWxvciBkZSBtaW5JbmNsdXNpdmUgPScnezB9JycgZGViZSBzZXIgbWVub3IgbyBpZ3VhbCBxdWUgZWwgdmFsb3IgZGUgbWF4SW5jbHVzaXZlIGRlbCB0aXBvIGJhc2UgJyd7MX0nJy4KLSAgICAgICAgbWluSW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjMgPSBtaW5JbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMzogRXJyb3IgcGFyYSBlbCB0aXBvICcnezJ9JycuIEVsIHZhbG9yIGRlIG1pbkluY2x1c2l2ZSA9Jyd7MH0nJyBkZWJlIHNlciBtYXlvciBxdWUgZWwgdmFsb3IgZGUgbWluRXhjbHVzaXZlIGRlbCB0aXBvIGJhc2UgJyd7MX0nJy4KLSAgICAgICAgbWluSW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjQgPSBtaW5JbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uNDogRXJyb3IgcGFyYSBlbCB0aXBvICcnezJ9JycuIEVsIHZhbG9yIGRlIG1pbkluY2x1c2l2ZSA9Jyd7MH0nJyBkZWJlIHNlciBtZW5vciBxdWUgZWwgdmFsb3IgZGUgbWF4RXhjbHVzaXZlIGRlbCB0aXBvIGJhc2UgJyd7MX0nJy4KLSAgICAgICAgbWluTGVuZ3RoLWxlc3MtdGhhbi1lcXVhbC10by1tYXhMZW5ndGggPSBtaW5MZW5ndGgtbGVzcy10aGFuLWVxdWFsLXRvLW1heExlbmd0aDogRW4gbGEgZGVmaW5pY2lcdTAwRjNuIGRlIHsyfSwgZWwgdmFsb3IgZGUgbWluTGVuZ3RoID0gJyd7MH0nJyBkZWJlIHNlciBtZW5vciBxdWUgZWwgdmFsb3IgZGUgbWF4TGVuZ3RoID0gJyd7MX0nJy4KLSAgICAgICAgbWluTGVuZ3RoLXZhbGlkLXJlc3RyaWN0aW9uID0gbWluTGVuZ3RoLXZhbGlkLXJlc3RyaWN0aW9uOiBFbiBsYSBkZWZpbmljaVx1MDBGM24gZGUgezJ9LCBlbCB2YWxvciBkZSBtaW5MZW5ndGggPSAnJ3swfScnIGRlYmUgc2VyIG1heW9yIG8gaWd1YWwgcXVlIGVsIGRlbCB0aXBvIGJhc2UsICcnezF9JycuCi0gICAgICAgIG5vLXhtbG5zID0gbm8teG1sbnM6IEVsIHZhbG9yIGRlIHtuYW1lfSBkZSB1bmEgZGVjbGFyYWNpXHUwMEYzbiBkZSBhdHJpYnV0byBubyBkZWJlIGNvaW5jaWRpciBjb24gJ3htbG5zJy4KLSAgICAgICAgbm8teHNpID0gbm8teHNpOiBFbCB2YWxvciBkZSAneyd0YXJnZXQgbmFtZXNwYWNlJ30nIGRlIHVuYSBkZWNsYXJhY2lcdTAwRjNuIGRlIGF0cmlidXRvIG5vIGRlYmUgY29pbmNpZGlyIGNvbiAnJ3swfScnLgotICAgICAgICBwLXByb3BzLWNvcnJlY3QuMi4xID0gcC1wcm9wcy1jb3JyZWN0LjIuMTogRW4gbGEgZGVjbGFyYWNpXHUwMEYzbiBkZSAnJ3swfScnLCBlbCB2YWxvciBkZSAnJ21pbk9jY3VycycnIGVzICcnezF9JycsIHBlcm8gbm8gZGViZSBzZXIgc3VwZXJpb3IgYWwgdmFsb3IgZGUgJydtYXhPY2N1cnMnJywgcXVlIGVzICcnezJ9JycuCi0gICAgICAgIHJjYXNlLU1hcEFuZFN1bS4xID0gcmNhc2UtTWFwQW5kU3VtLjE6IE5vIGV4aXN0ZSBuaW5ndW5hIGFzaWduYWNpXHUwMEYzbiBmdW5jaW9uYWwgY29tcGxldGEgZW50cmUgbGFzIHBhcnRcdTAwRURjdWxhcy4KLSAgICAgICAgcmNhc2UtTWFwQW5kU3VtLjIgPSByY2FzZS1NYXBBbmRTdW0uMjogRWwgcmFuZ28gZGUgaW5jaWRlbmNpYSBkZWwgZ3J1cG8sICh7MH0sezF9KSwgbm8gZXMgdW5hIHJlc3RyaWNjaVx1MDBGM24gdlx1MDBFMWxpZGEgZGVsIHJhbmdvIGRlIGluY2lkZW5jaWEgZGVsIGdydXBvIGJhc2UsICh7Mn0sezN9KS4KLSAgICAgICAgcmNhc2UtTmFtZUFuZFR5cGVPSy4xID0gcmNhc2UtTmFtZUFuZFR5cGVPSy4xOiBMb3MgZWxlbWVudG9zIHRpZW5lbiBub21icmVzIHkgZXNwYWNpb3MgZGUgbm9tYnJlcyBkZSBkZXN0aW5vIGRpc3RpbnRvczogRWwgZWxlbWVudG8nJ3swfScnIGVuIGVsIGVzcGFjaW8gZGUgbm9tYnJlcyAnJ3sxfScnIHkgZWwgZWxlbWVudG8gJyd7Mn0nJyBlbiBlbCBlc3BhY2lvIGRlIG5vbWJyZXMgJyd7M30nJy4KLSAgICAgICAgcmNhc2UtTmFtZUFuZFR5cGVPSy4yID0gcmNhc2UtTmFtZUFuZFR5cGVPSy4yOiBFcnJvciBwYXJhIGxhIHBhcnRcdTAwRURjdWxhIGN1eW8gdmFsb3IgZGUgJ3sndGVybSd9JyBlcyBsYSBkZWNsYXJhY2lcdTAwRjNuIGRlIGVsZW1lbnRvICcnezB9JycuIEVsIHZhbG9yIGRlICd7J25pbGxhYmxlJ30nIGRlIGxhIGRlY2xhcmFjaVx1MDBGM24gZGUgZWxlbWVudG8gZXMgdHJ1ZSwgcGVybyBsYSBwYXJ0XHUwMEVEY3VsYSBjb3JyZXNwb25kaWVudGUgZW4gZWwgdGlwbyBiYXNlIHRpZW5lIHVuYSBkZWNsYXJhY2lcdTAwRjNuIGRlIGVsZW1lbnRvIGN1eW8gdmFsb3IgZGUgJ3snbmlsbGFibGUnfScgZXMgZmFsc2UuCi0gICAgICAgIHJjYXNlLU5hbWVBbmRUeXBlT0suMyA9IHJjYXNlLU5hbWVBbmRUeXBlT0suMzogRXJyb3IgcGFyYSBsYSBwYXJ0XHUwMEVEY3VsYSBjdXlvIHZhbG9yIGRlICd7J3Rlcm0nfScgZXMgbGEgZGVjbGFyYWNpXHUwMEYzbiBkZSBlbGVtZW50byAnJ3swfScnLiBTdSByYW5nbyBkZSBpbmNpZGVuY2lhLCAoezF9LHsyfSksIG5vIGVzIHVuYSByZXN0cmljY2lcdTAwRjNuIHZcdTAwRTFsaWRhIGRlbCByYW5nbywgKHszfSx7NH0sIGRlIGxhIHBhcnRcdTAwRURjdWxhIGNvcnJlc3BvbmRpZW50ZSBlbiBlbCB0aXBvIGJhc2UuCi0gICAgICAgIHJjYXNlLU5hbWVBbmRUeXBlT0suNC5hID0gcmNhc2UtTmFtZUFuZFR5cGVPSy40LmE6IEVsIGVsZW1lbnRvICcnezB9Jycgbm8gZXMgZmlqbywgcGVybyBlbCBlbGVtZW50byBjb3JyZXNwb25kaWVudGUgZW4gZWwgdGlwbyBiYXNlIGVzIGZpam8gY29uIGVsIHZhbG9yICcnezF9JycuCi0gICAgICAgIHJjYXNlLU5hbWVBbmRUeXBlT0suNC5iID0gcmNhc2UtTmFtZUFuZFR5cGVPSy40LmI6IEVsIGVsZW1lbnRvICcnezB9JycgZXMgZmlqbyBjb24gZWwgdmFsb3IgJyd7MX0nJywgcGVybyBlbCBlbGVtZW50byBjb3JyZXNwb25kaWVudGUgZW4gZWwgdGlwbyBiYXNlIGVzIGZpam8gY29uIGVsIHZhbG9yICcnezJ9JycuCi0gICAgICAgIHJjYXNlLU5hbWVBbmRUeXBlT0suNSA9IHJjYXNlLU5hbWVBbmRUeXBlT0suNTogTGFzIHJlc3RyaWNjaW9uZXMgZGUgaWRlbnRpZGFkIGRlbCBlbGVtZW50byAnJ3swfScnIG5vIHNvbiB1biBzdWJqdWVnbyBkZSBsYXMgZGUgbGEgYmFzZS4KLSAgICAgICAgcmNhc2UtTmFtZUFuZFR5cGVPSy42ID0gcmNhc2UtTmFtZUFuZFR5cGVPSy42OiBMYXMgc3VzdGl0dWNpb25lcyBubyBwZXJtaXRpZGFzIGRlbCBlbGVtZW50byAnJ3swfScnIG5vIHNvbiB1biBzdWJqdWVnbyBkZSBsYXMgZGUgbGEgYmFzZS4KLSAgICAgICAgcmNhc2UtTmFtZUFuZFR5cGVPSy43ID0gcmNhc2UtTmFtZUFuZFR5cGVPSy43OiBFbCB0aXBvIGRlIGVsZW1lbnRvICcnezB9JycsICcnezF9JycsIG5vIGVzdFx1MDBFMSBkZXJpdmFkbyBkZWwgdGlwbyBkZWwgZWxlbWVudG8gYmFzZSwgJyd7Mn0nJy4KLSAgICAgICAgcmNhc2UtTlNDb21wYXQuMSA9IHJjYXNlLU5TQ29tcGF0LjE6IEVsIGVsZW1lbnRvICcnezB9JycgdGllbmUgdW4gZXNwYWNpbyBkZSBub21icmVzICcnezF9JycgcXVlIG5vIGVzdFx1MDBFMSBwZXJtaXRpZG8gcG9yIGVsIGNvbW9kXHUwMEVEbiBkZSBsYSBiYXNlLgotICAgICAgICByY2FzZS1OU0NvbXBhdC4yID0gcmNhc2UtTlNDb21wYXQuMjogRXJyb3IgcGFyYSBsYSBwYXJ0XHUwMEVEY3VsYSBjdXlvIHZhbG9yIGRlICd7J3Rlcm0nfScgZXMgbGEgZGVjbGFyYWNpXHUwMEYzbiBkZSBlbGVtZW50byAnJ3swfScnLiBTdSByYW5nbyBkZSBpbmNpZGVuY2lhLCAoezF9LHsyfSksIG5vIGVzIHVuYSByZXN0cmljY2lcdTAwRjNuIHZcdTAwRTFsaWRhIGRlbCByYW5nbywgKHszfSx7NH0sIGRlIGxhIHBhcnRcdTAwRURjdWxhIGNvcnJlc3BvbmRpZW50ZSBlbiBlbCB0aXBvIGJhc2UuCi0gICAgICAgIHJjYXNlLU5TUmVjdXJzZUNoZWNrQ2FyZGluYWxpdHkuMSA9IHJjYXNlLU5TUmVjdXJzZUNoZWNrQ2FyZGluYWxpdHkuMTogTm8gZXhpc3RlIG5pbmd1bmEgYXNpZ25hY2lcdTAwRjNuIGZ1bmNpb25hbCBjb21wbGV0YSBlbnRyZSBsYXMgcGFydFx1MDBFRGN1bGFzLgotICAgICAgICByY2FzZS1OU1JlY3Vyc2VDaGVja0NhcmRpbmFsaXR5LjIgPSByY2FzZS1OU1JlY3Vyc2VDaGVja0NhcmRpbmFsaXR5LjI6IEVsIHJhbmdvIGRlIGluY2lkZW5jaWEgZGVsIGdydXBvLCAoezB9LHsxfSksIG5vIGVzIHVuYSByZXN0cmljY2lcdTAwRjNuIHZcdTAwRTFsaWRhIGRlbCByYW5nbyBkZSBjb21vZFx1MDBFRG4gZGUgbGEgYmFzZSwgKHsyfSx7M30pLgotICAgICAgICByY2FzZS1OU1N1YnNldC4xID0gcmNhc2UtTlNTdWJzZXQuMTogRWwgY29tb2RcdTAwRURuIG5vIGVzIHVuIHN1Ymp1ZWdvIGRlbCBjb21vZFx1MDBFRG4gY29ycmVzcG9uZGllbnRlIGRlIGxhIGJhc2UuCi0gICAgICAgIHJjYXNlLU5TU3Vic2V0LjIgPSByY2FzZS1OU1N1YnNldC4yOiBFbCByYW5nbyBkZSBpbmNpZGVuY2lhIGRlbCBjb21vZFx1MDBFRG4sICh7MH0sezF9KSwgbm8gZXMgdW5hIHJlc3RyaWNjaVx1MDBGM24gdlx1MDBFMWxpZGEgZGVsIGRlIGxhIGJhc2UsICh7Mn0sezN9KS4KLSAgICAgICAgcmNhc2UtTlNTdWJzZXQuMyA9IHJjYXNlLU5TU3Vic2V0LjM6IEVsIGNvbnRlbmlkbyBkZWwgcHJvY2VzbyBkZWwgY29tb2RcdTAwRURuLCAnJ3swfScnLCBlcyBtXHUwMEUxcyBkXHUwMEU5YmlsIHF1ZSBlbCBkZSBsYSBiYXNlLCAnJ3sxfScnLgotICAgICAgICByY2FzZS1SZWN1cnNlLjEgPSByY2FzZS1SZWN1cnNlLjE6IEVsIHJhbmdvIGRlIGluY2lkZW5jaWEgZGVsIGdydXBvLCAoezB9LHsxfSksIG5vIGVzIHVuYSByZXN0cmljY2lcdTAwRjNuIHZcdTAwRTFsaWRhIGRlbCByYW5nbyBkZSBpbmNpZGVuY2lhIGRlbCBncnVwbyBiYXNlLCAoezJ9LHszfSkuCi0gICAgICAgIHJjYXNlLVJlY3Vyc2UuMiA9IHJjYXNlLVJlY3Vyc2UuMjogTm8gZXhpc3RlIG5pbmd1bmEgYXNpZ25hY2lcdTAwRjNuIGZ1bmNpb25hbCBjb21wbGV0YSBlbnRyZSBsYXMgcGFydFx1MDBFRGN1bGFzLgotICAgICAgICByY2FzZS1SZWN1cnNlTGF4LjEgPSByY2FzZS1SZWN1cnNlTGF4LjE6IEVsIHJhbmdvIGRlIGluY2lkZW5jaWEgZGVsIGdydXBvLCAoezB9LHsxfSksIG5vIGVzIHVuYSByZXN0cmljY2lcdTAwRjNuIHZcdTAwRTFsaWRhIGRlbCByYW5nbyBkZSBpbmNpZGVuY2lhIGRlbCBncnVwbyBiYXNlLCAoezJ9LHszfSkuCi0gICAgICAgIHJjYXNlLVJlY3Vyc2VMYXguMiA9IHJjYXNlLVJlY3Vyc2VMYXguMjogTm8gZXhpc3RlIG5pbmd1bmEgYXNpZ25hY2lcdTAwRjNuIGZ1bmNpb25hbCBjb21wbGV0YSBlbnRyZSBsYXMgcGFydFx1MDBFRGN1bGFzLgotICAgICAgICByY2FzZS1SZWN1cnNlVW5vcmRlcmVkLjEgPSByY2FzZS1SZWN1cnNlVW5vcmRlcmVkLjE6IEVsIHJhbmdvIGRlIGluY2lkZW5jaWEgZGVsIGdydXBvLCAoezB9LHsxfSksIG5vIGVzIHVuYSByZXN0cmljY2lcdTAwRjNuIHZcdTAwRTFsaWRhIGRlbCByYW5nbyBkZSBpbmNpZGVuY2lhIGRlbCBncnVwbyBiYXNlLCAoezJ9LHszfSkuCi0gICAgICAgIHJjYXNlLVJlY3Vyc2VVbm9yZGVyZWQuMiA9IHJjYXNlLVJlY3Vyc2VVbm9yZGVyZWQuMjogTm8gZXhpc3RlIG5pbmd1bmEgYXNpZ25hY2lcdTAwRjNuIGZ1bmNpb25hbCBjb21wbGV0YSBlbnRyZSBsYXMgcGFydFx1MDBFRGN1bGFzLgotIyAgICAgICAgV2UncmUgdXNpbmcgc2NoLXByb3BzLWNvcnJlY3QuMiBpbnN0ZWFkIG9mIHRoZSBvbGQgc3JjLXJlZGVmaW5lLjEKLSMgICAgICAgIHNyYy1yZWRlZmluZS4xID0gc3JjLXJlZGVmaW5lLjE6IFRoZSBjb21wb25lbnQgJyd7MH0nJyBpcyBiZWdpbiByZWRlZmluZWQsIGJ1dCBpdHMgY29ycmVzcG9uZGluZyBjb21wb25lbnQgaXNuJ3QgaW4gdGhlIHNjaGVtYSBkb2N1bWVudCBiZWluZyByZWRlZmluZWQgKHdpdGggbmFtZXNwYWNlICcnezJ9JycpLCBidXQgaW4gYSBkaWZmZXJlbnQgZG9jdW1lbnQsIHdpdGggbmFtZXNwYWNlICcnezF9JycuCi0gICAgICAgIHNjaC1wcm9wcy1jb3JyZWN0LjIgPSBzY2gtcHJvcHMtY29ycmVjdC4yOiBVbiBlc3F1ZW1hIG5vIHB1ZWRlIGNvbnRlbmVyIGRvcyBjb21wb25lbnRlcyBnbG9iYWxlcyBjb24gZWwgbWlzbW8gbm9tYnJlOyBcdTAwRTlzdGUgY29udGllbmUgZG9zIGluY2lkZW5jaWFzIGRlICcnezB9JycuCi0gICAgICAgIHN0LXByb3BzLWNvcnJlY3QuMiA9IHN0LXByb3BzLWNvcnJlY3QuMjogU2UgaGFuIGRldGVjdGFkbyBkZWZpbmljaW9uZXMgY2lyY3VsYXJlcyBwYXJhIGVsIHRpcG8gc2ltcGxlICcnezB9JycuIFNpZ25pZmljYSBxdWUgJyd7MH0nJyBlc3RcdTAwRTEgY29udGVuaWRvIGVuIHN1IHByb3BpYSBqZXJhcnF1XHUwMEVEYSBkZSB0aXBvcywgbG8gcXVlIGVzIHVuIGVycm9yLgotICAgICAgICBzdC1wcm9wcy1jb3JyZWN0LjMgPSBzdC1wcm9wcy1jb3JyZWN0LjM6IEVycm9yIHBhcmEgZWwgdGlwbyAnJ3swfScnLiBFbCB2YWxvciBkZSAneydmaW5hbCd9JyBkZSAneydiYXNlIHR5cGUgZGVmaW5pdGlvbid9JywgJyd7MX0nJywgcHJvaFx1MDBFRGJlIGxhIGRlcml2YWNpXHUwMEYzbiBwb3IgcmVzdHJpY2NpXHUwMEYzbi4KLSAgICAgICAgdG90YWxEaWdpdHMtdmFsaWQtcmVzdHJpY3Rpb24gPSB0b3RhbERpZ2l0cy12YWxpZC1yZXN0cmljdGlvbjogRW4gbGEgZGVmaW5pY2lcdTAwRjNuIGRlIHsyfSwgZWwgdmFsb3IgJyd7MH0nJyBwYXJhIGxhIGZhY2V0YSAnJ3RvdGFsRGlnaXRzJycgbm8gZXMgdlx1MDBFMWxpZG8gcG9ycXVlIGRlYmUgc2VyIG1lbm9yIG8gaWd1YWwgcXVlIGVsIHZhbG9yIGRlICcndG90YWxEaWdpdHMnJyBxdWUgc2UgaGEgZGVmaW5pZG8gZW4gJyd7MX0nJyBlbiB1bm8gZGUgbG9zIHRpcG9zIGRlIGFzY2VuZGllbnRlcy4KLSAgICAgICAgd2hpdGVTcGFjZS12YWxpZC1yZXN0cmljdGlvbi4xID0gd2hpdGVTcGFjZS12YWxpZC1yZXN0cmljdGlvbi4xOiBFbiBsYSBkZWZpbmljaVx1MDBGM24gZGUgezB9LCBlbCB2YWxvciAnJ3sxfScnIHBhcmEgbGEgZmFjZXRhICcnd2hpdGVzcGFjZScnIG5vIGVzIHZcdTAwRTFsaWRvIHBvcnF1ZSBlbCB2YWxvciBkZSAnJ3doaXRlc3BhY2UnJyBzZSBoYSBkZWZpbmlkbyBlbiAnJ2NvbGxhcHNlJycgZW4gdW5vIGRlIGxvcyB0aXBvcyBkZSBhc2NlbmRpZW50ZXMuCi0gICAgICAgIHdoaXRlU3BhY2UtdmFsaWQtcmVzdHJpY3Rpb24uMiA9IHdoaXRlU3BhY2UtdmFsaWQtcmVzdHJpY3Rpb24uMjogRW4gbGEgZGVmaW5pY2lcdTAwRjNuIGRlIHswfSwgZWwgdmFsb3IgJydwcmVzZXJ2ZScnIHBhcmEgbGEgZmFjZXRhICcnd2hpdGVzcGFjZScnIG5vIGVzIHZcdTAwRTFsaWRvIHBvcnF1ZSBlbCB2YWxvciBkZSAnJ3doaXRlc3BhY2UnJyBzZSBoYSBkZWZpbmlkbyBlbiAnJ3JlcGxhY2UnJyBlbiB1bm8gZGUgbG9zIHRpcG9zIGRlIGFzY2VuZGllbnRlcy4KLQotI3NjaGVtYSBmb3IgU2NoZW1hcwotCi0gICAgICAgIHM0cy1hdHQtaW52YWxpZC12YWx1ZSA9IHM0cy1hdHQtaW52YWxpZC12YWx1ZTogVmFsb3IgZGUgYXRyaWJ1dG8gbm8gdlx1MDBFMWxpZG8gcGFyYSAnJ3sxfScnIGVuIGVsIGVsZW1lbnRvICcnezB9JycuIE1vdGl2byByZWdpc3RyYWRvOiB7Mn0KLSAgICAgICAgczRzLWF0dC1tdXN0LWFwcGVhciA9IHM0cy1hdHQtbXVzdC1hcHBlYXI6IEVsIGF0cmlidXRvICcnezF9JycgZGViZSBhcGFyZWNlciBlbiBlbCBlbGVtZW50byAnJ3swfScnLgotICAgICAgICBzNHMtYXR0LW5vdC1hbGxvd2VkID0gczRzLWF0dC1ub3QtYWxsb3dlZDogRWwgYXRyaWJ1dG8gJyd7MX0nJyBubyBwdWVkZSBhcGFyZWNlciBlbiBlbCBlbGVtZW50byAnJ3swfScnLgotICAgICAgICBzNHMtZWx0LWludmFsaWQgPSBzNHMtZWx0LWludmFsaWQ6IEVsIGVsZW1lbnRvICcnezB9Jycgbm8gZXMgdW4gZWxlbWVudG8gdlx1MDBFMWxpZG8gZW4gdW4gZG9jdW1lbnRvIGRlIGVzcXVlbWEuCi0gICAgICAgIHM0cy1lbHQtbXVzdC1tYXRjaC4xID0gczRzLWVsdC1tdXN0LW1hdGNoLjE6IEVsIGNvbnRlbmlkbyBkZSAnJ3swfScnIGRlYmUgY29pbmNpZGlyIGNvbiB7MX0uIFNlIGhhIGVuY29udHJhZG8gdW4gcHJvYmxlbWEgcXVlIGNvbWllbnphIGVuOiB7Mn0uCi0gICAgICAgIHM0cy1lbHQtbXVzdC1tYXRjaC4yID0gczRzLWVsdC1tdXN0LW1hdGNoLjI6IEVsIGNvbnRlbmlkbyBkZSAnJ3swfScnIGRlYmUgY29pbmNpZGlyIGNvbiB7MX0uIE5vIHNlIGhhbiBlbmNvbnRyYWRvIHN1ZmljaWVudGVzIGVsZW1lbnRvcy4KLSAgICAgICAgIyB0aGUgImludmFsaWQtY29udGVudCIgbWVzc2FnZXMgcHJvdmlkZSBsZXNzIGluZm9ybWF0aW9uIHRoYW4gdGhlICJtdXN0LW1hdGNoIiBjb3VudGVycGFydHMgYWJvdmUuIFRoZXkncmUgdXNlZCBmb3IgY29tcGxleCB0eXBlcyB3aGVuIHByb3ZpZGluZyBhICJtYXRjaCIgd291bGQgYmUgYW4gaW5mb3JtYXRpb24gZHVtcAotICAgICAgICBzNHMtZWx0LWludmFsaWQtY29udGVudC4xID0gczRzLWVsdC1pbnZhbGlkLWNvbnRlbnQuMTogRWwgY29udGVuaWRvIGRlICcnezB9Jycgbm8gZXMgdlx1MDBFMWxpZG8uIEVsIGVsZW1lbnRvICcnezF9Jycgbm8gZXMgdlx1MDBFMWxpZG8sIGVzdFx1MDBFMSBtYWwgc2l0dWFkbyBvIGFwYXJlY2UgY29uIGRlbWFzaWFkYSBmcmVjdWVuY2lhLgotICAgICAgICBzNHMtZWx0LWludmFsaWQtY29udGVudC4yID0gczRzLWVsdC1pbnZhbGlkLWNvbnRlbnQuMjogRWwgY29udGVuaWRvIGRlICcnezB9Jycgbm8gZXMgdlx1MDBFMWxpZG8uIEVsIGVsZW1lbnRvICcnezF9Jycgbm8gcHVlZGUgZXN0YXIgdmFjXHUwMEVEby4KLSAgICAgICAgczRzLWVsdC1pbnZhbGlkLWNvbnRlbnQuMyA9IHM0cy1lbHQtaW52YWxpZC1jb250ZW50LjM6IExvcyBlbGVtZW50b3MgZGUgdGlwbycnezB9Jycgbm8gcHVlZGVuIGFwYXJlY2VyIGRlc3B1XHUwMEU5cyBkZSBsYXMgZGVjbGFyYWNpb25lcyBjb21vIHNlY3VuZGFyaW9zIGRlIHVuIGVsZW1lbnRvIGRlIDxzY2hlbWE+LgotICAgICAgICBzNHMtZWx0LXNjaGVtYS1ucyA9IHM0cy1lbHQtc2NoZW1hLW5zOiBFbCBlc3BhY2lvIGRlIG5vbWJyZXMgZGVsIGVsZW1lbnRvICcnezB9JycgZGViZSBzZXIgZGVsIGVzcGFjaW8gZGUgbm9tYnJlcyBkZWwgZXNxdWVtYSwgJydodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYScnLgotICAgICAgICBzNHMtZWx0LWNoYXJhY3RlciA9IHM0cy1lbHQtY2hhcmFjdGVyOiBMb3MgY2FyYWN0ZXJlcyBkaXN0aW50b3MgZGUgbG9zIGVzcGFjaW9zIGVuIGJsYW5jbyBubyBlc3RcdTAwRTFuIHBlcm1pdGlkb3MgZW4gZWxlbWVudG9zIGRlIGVzcXVlbWEgcXVlIG5vIHNlYW4gJyd4czphcHBpbmZvJycgeSAnJ3hzOmRvY3VtZW50YXRpb24nJy4gU2UgaGEgb2J0ZW5pZG8gJyd7MH0nJy4KLQotIyBjb2RlcyBub3QgZGVmaW5lZCBieSB0aGUgc3BlYwotCi0gICAgICAgIGMtZmllbGRzLXhwYXRocyA9IGMtZmllbGRzLXhwYXRoczogRWwgdmFsb3IgZGUgY2FtcG8gPSAnJ3swfScnIG5vIGVzIHZcdTAwRTFsaWRvLgotICAgICAgICBjLWdlbmVyYWwteHBhdGggPSBjLWdlbmVyYWwteHBhdGg6IExhIGV4cHJlc2lcdTAwRjNuICcnezB9Jycgbm8gZXMgdlx1MDBFMWxpZGEgY29uIHJlc3BlY3RvIGFsIHN1Ymp1ZWdvIGRlIFhQYXRoIHNvcG9ydGFkbyBwb3IgZWwgZXNxdWVtYSBYTUwuCi0gICAgICAgIGMtZ2VuZXJhbC14cGF0aC1ucyA9IGMtZ2VuZXJhbC14cGF0aC1uczogVW4gcHJlZmlqbyBkZSBlc3BhY2lvIGRlIG5vbWJyZXMgZW4gbGEgZXhwcmVzaVx1MDBGM24gWFBhdGgnJ3swfScnIG5vIGVzdGFiYSBlbmxhemFkbyBhIG5pbmdcdTAwRkFuIGVzcGFjaW8gZGUgbm9tYnJlcy4KLSAgICAgICAgYy1zZWxlY3Rvci14cGF0aCA9IGMtc2VsZWN0b3IteHBhdGg6IEVsIHZhbG9yIGRlIHNlbGVjdG9yID0gJyd7MH0nJyBubyBlcyB2XHUwMEUxbGlkbzsgbG9zIHZhbG9yZXMgZGUgWHBhdGggZW4gZWwgc2VsZWN0b3Igbm8gcHVlZGVuIGNvbnRlbmVyIGF0cmlidXRvcy4KLSAgICAgICAgRW1wdHlUYXJnZXROYW1lc3BhY2UgPSBFbXB0eVRhcmdldE5hbWVzcGFjZTogRW4gZWwgZG9jdW1lbnRvIGRlIGVzcXVlbWEgJyd7MH0nJywgZWwgdmFsb3IgZGVsIGF0cmlidXRvICcndGFyZ2V0TmFtZXNwYWNlJycgbm8gcHVlZGUgc2VyIHVuYSBjYWRlbmEgdmFjXHUwMEVEYS4KLSAgICAgICAgRmFjZXRWYWx1ZUZyb21CYXNlID0gRmFjZXRWYWx1ZUZyb21CYXNlOiBFbiBsYSBkZWNsYXJhY2lcdTAwRjNuIGRlIHRpcG8gJyd7MH0nJywgZWwgdmFsb3IgJyd7MX0nJyBkZSBsYSBmYWNldGEgJyd7Mn0nJyBkZWJlIHByb2NlZGVyIGRlbCBlc3BhY2lvIHJlc2VydmFkbyBwYXJhIGVsIHZhbG9yIGRlbCB0aXBvIGJhc2UsICcnezN9JycuCi0gICAgICAgIEZpeGVkRmFjZXRWYWx1ZSA9IEZpeGVkRmFjZXRWYWx1ZTogRW4gbGEgZGVmaW5pY2lcdTAwRjNuIGRlIHszfSwgZWwgdmFsb3IgJyd7MX0nJyBwYXJhIGxhIGZhY2V0YSAnJ3swfScnIG5vIGVzIHZcdTAwRTFsaWRvIHBvcnF1ZSBlbCB2YWxvciBkZSAnJ3swfScnIHNlIGhhIGRlZmluaWRvIGVuICcnezJ9JycgZW4gdW5vIGRlIGxvcyB0aXBvcyBkZSBhc2NlbmRpZW50ZXMgeSAneydmaXhlZCd9JyA9IHRydWUuCi0gICAgICAgIEludmFsaWRSZWdleCA9IEludmFsaWRSZWdleDogRWwgdmFsb3IgZGVsIHBhdHJcdTAwRjNuICcnezB9Jycgbm8gZXMgdW5hIGV4cHJlc2lcdTAwRjNuIHJlZ3VsYXIgdlx1MDBFMWxpZGEuIEVsIGVycm9yIHJlZ2lzdHJhZG8gaGEgc2lkbzogJyd7MX0nJyBlbiBsYSBjb2x1bW5hICcnezJ9JycuCi0gICAgICAgIE1heE9jY3VyTGltaXQgPSBMYSBjb25maWd1cmFjaVx1MDBGM24gYWN0dWFsIGRlbCBhbmFsaXphZG9yIG5vIHBlcm1pdGUgcXVlIGxhIGRlZmluaWNpXHUwMEYzbiBkZWwgdmFsb3IgZGVsIGF0cmlidXRvIG1heE9jY3VycyBzZWEgbWF5b3IgcXVlIHswfS4KLSAgICAgICAgUHVibGljU3lzdGVtT25Ob3RhdGlvbiA9IFB1YmxpY1N5c3RlbU9uTm90YXRpb246IEFsIG1lbm9zIHVuIHZhbG9yIGRlICcncHVibGljJycgeSAnJ3N5c3RlbScnIGRlYmUgYXBhcmVjZXIgZW4gZWwgZWxlbWVudG8gJydub3RhdGlvbicnLgotICAgICAgICBTY2hlbWFMb2NhdGlvbiA9IFNjaGVtYUxvY2F0aW9uOiBFbCB2YWxvciBkZSBzY2hlbWFMb2NhdGlvbiA9ICcnezB9JycgZGViZSB0ZW5lciB1biBuXHUwMEZBbWVybyBwYXIgZGUgVVJJLgotICAgICAgICBUYXJnZXROYW1lc3BhY2UuMSA9IFRhcmdldE5hbWVzcGFjZS4xOiBTZSBlc3BlcmFiYSBlbCBlc3BhY2lvIGRlIG5vbWJyZXMgJyd7MH0nJywgcGVybyBlbCBlc3BhY2lvIGRlIG5vbWJyZXMgZGUgZGVzdGlubyBkZWwgZG9jdW1lbnRvIGRlIGVzcXVlbWEgZXMgJyd7MX0nJy4KLSAgICAgICAgVGFyZ2V0TmFtZXNwYWNlLjIgPSBUYXJnZXROYW1lc3BhY2UuMjogTm8gc2UgZXNwZXJhYmEgbmluZ1x1MDBGQW4gZXNwYWNpbyBkZSBub21icmVzLCBwZXJvIGVsIGRvY3VtZW50byBkZSBlc3F1ZW1hIHRpZW5lIHVuIGVzcGFjaW8gZGUgbm9tYnJlcyBkZSBkZXN0aW5vICcnezF9JycuCi0gICAgICAgIFVuZGVjbGFyZWRFbnRpdHkgPSBVbmRlY2xhcmVkRW50aXR5OiBMYSBlbnRpZGFkICcnezB9Jycgbm8gZXN0XHUwMEUxIGRlY2xhcmFkYS4KLSAgICAgICAgVW5kZWNsYXJlZFByZWZpeCA9IFVuZGVjbGFyZWRQcmVmaXg6IE5vIHNlIHB1ZWRlIHJlc29sdmVyICcnezB9JycgY29tbyBRTmFtZTogbm8gc2UgaGEgZGVjbGFyYWRvIGVsIHByZWZpam8gJyd7MX0nJy4KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hNTFNjaGVtYU1lc3NhZ2VzX2ZyLnByb3BlcnRpZXMgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9YTUxTY2hlbWFNZXNzYWdlc19mci5wcm9wZXJ0aWVzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3NGFlMzJjLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hNTFNjaGVtYU1lc3NhZ2VzX2ZyLnByb3BlcnRpZXMKKysrIC9kZXYvbnVsbApAQCAtMSwyOTEgKzAsMCBAQAotIyBUaGlzIGZpbGUgY29udGFpbnMgZXJyb3IgYW5kIHdhcm5pbmcgbWVzc2FnZXMgcmVsYXRlZCB0byBYTUwgU2NoZW1hCi0jIFRoZSBtZXNzYWdlcyBhcmUgYXJyYW5nZWQgaW4ga2V5IGFuZCB2YWx1ZSB0dXBsZXMgaW4gYSBMaXN0UmVzb3VyY2VCdW5kbGUuCi0jCi0KLSAgICAgICAgQmFkTWVzc2FnZUtleSA9IExlIG1lc3NhZ2UgZCdlcnJldXIgY29ycmVzcG9uZGFudCBcdTAwRTAgbGEgY2xcdTAwRTkgZGUgbWVzc2FnZSBlc3QgaW50cm91dmFibGUuCi0gICAgICAgIEZvcm1hdEZhaWxlZCA9IFVuZSBlcnJldXIgaW50ZXJuZSBlc3Qgc3VydmVudWUgbG9ycyBkdSBmb3JtYXRhZ2UgZHUgbWVzc2FnZSBzdWl2YW50IDpcbgotCi0jIEZvciBpbnRlcm5hbCB1c2UKLQotICAgICAgICBJbnRlcm5hbC1FcnJvciA9IEVycmV1ciBpbnRlcm5lIDogezB9LgotICAgICAgICBkdC13aGl0ZXNwYWNlID0gTGEgdmFsZXVyIGRlIGZhY2V0IGRlIGNhcmFjdFx1MDBFOHJlIG5vbiBpbXByaW1hYmxlIG4nJ2VzdCBwYXMgZGlzcG9uaWJsZSBwb3VyIGxlIHNpbXBsZVR5cGUgZCcndW5pb24gJyd7MH0nJwotICAgICAgICBHcmFtbWFyQ29uZmxpY3QgPSBMJ3VuZSBkZXMgZ3JhbW1haXJlcyByZW52b3lcdTAwRTllcyBcdTAwRTAgcGFydGlyIGR1IHBvb2wgZGUgZ3JhbW1haXJlcyBkZSBsJ3V0aWxpc2F0ZXVyIGVzdCBlbiBjb25mbGl0IGF2ZWMgdW5lIGF1dHJlIGdyYW1tYWlyZS4KLQotIyBJZGVudGl0eSBjb25zdHJhaW50cwotCi0gICAgICAgIEFic2VudEtleVZhbHVlID0gRXJyZXVyIGRlIGNvbnRyYWludGUgZCcnaWRlbnRpdFx1MDBFOSAoY3ZjLWlkZW50aXR5LWNvbnN0cmFpbnQuNC4yLjEpIDogbCcnXHUwMEU5bFx1MDBFOW1lbnQgInswfSIgYSB1bmUgY2xcdTAwRTkgc2FucyB2YWxldXIuCi0gICAgICAgIER1cGxpY2F0ZUZpZWxkID0gQ29ycmVzcG9uZGFuY2UgZW4gZG91YmxlIGRhbnMgbGEgcG9ydFx1MDBFOWUgZHUgY2hhbXAgInswfSIuCi0gICAgICAgIER1cGxpY2F0ZUtleSA9IFZhbGV1ciBkZSBjbFx1MDBFOSBlbiBkb3VibGUgW3swfV0gZFx1MDBFOWNsYXJcdTAwRTllIHBvdXIgbGEgY29udHJhaW50ZSBkJydpZGVudGl0XHUwMEU5IGRlIGwnJ1x1MDBFOWxcdTAwRTltZW50ICJ7MX0iLgotICAgICAgICBEdXBsaWNhdGVVbmlxdWUgPSBWYWxldXIgdW5pcXVlIGVuIGRvdWJsZSBbezB9XSBkXHUwMEU5Y2xhclx1MDBFOWUgcG91ciBsYSBjb250cmFpbnRlIGQnJ2lkZW50aXRcdTAwRTkgZGUgbCcnXHUwMEU5bFx1MDBFOW1lbnQgInsxfSIuCi0gICAgICAgIEZpZWxkTXVsdGlwbGVNYXRjaCA9IEVycmV1ciBkZSBjb250cmFpbnRlIGQnJ2lkZW50aXRcdTAwRTkgOiBsZSBjaGFtcCAiezB9IiBjb25jb3JkZSBhdmVjIHBsdXNpZXVycyB2YWxldXJzIGRhbnMgbGEgcG9ydFx1MDBFOWUgZGUgc29uIHNcdTAwRTlsZWN0ZXVyIDsgbGVzIGNoYW1wcyBkb2l2ZW50IGNvbmNvcmRlciBhdmVjIGRlcyB2YWxldXJzIHVuaXF1ZXMuCi0gICAgICAgIEZpeGVkRGlmZmVyc0Zyb21BY3R1YWwgPSBMZSBjb250ZW51IGRlIGwnXHUwMEU5bFx1MDBFOW1lbnQgbidcdTAwRTlxdWl2YXV0IHBhcyBcdTAwRTAgbGEgdmFsZXVyIGRlIGwnYXR0cmlidXQgImZpeGVkIiBkYW5zIGxhIGRcdTAwRTljbGFyYXRpb24gZGUgbCdcdTAwRTlsXHUwMEU5bWVudCBkdSBzY2hcdTAwRTltYS4KLSAgICAgICAgS2V5TWF0Y2hlc05pbGxhYmxlID0gRXJyZXVyIGRlIGNvbnRyYWludGUgZCcnaWRlbnRpdFx1MDBFOSAoY3ZjLWlkZW50aXR5LWNvbnN0cmFpbnQuNC4yLjMpIDogbCcnXHUwMEU5bFx1MDBFOW1lbnQgInswfSIgYSB1bmUgY2xcdTAwRTkgcXVpIGNvbmNvcmRlIGF2ZWMgdW4gXHUwMEU5bFx1MDBFOW1lbnQgZG9udCBsJydhdHRyaWJ1dCBuaWxsYWJsZSBhIGxhIHZhbGV1ciBUcnVlLgotICAgICAgICBLZXlOb3RFbm91Z2hWYWx1ZXMgPSBMZSBub21icmUgZGUgdmFsZXVycyBpbmRpcXVcdTAwRTllcyBwb3VyIGxhIGNvbnRyYWludGUgZCcnaWRlbnRpdFx1MDBFOSA8a2V5IG5hbWU9InsxfSI+IGRlIGwnJ1x1MDBFOWxcdTAwRTltZW50ICJ7MH0iIGVzdCBpbnN1ZmZpc2FudC4KLSAgICAgICAgS2V5Tm90Rm91bmQgPSBMYSBjbFx1MDBFOSAnJ3swfScnIGF5YW50IGxhIHZhbGV1ciAnJ3sxfScnIGVzdCBpbnRyb3V2YWJsZSBwb3VyIGxhIGNvbnRyYWludGUgZCcnaWRlbnRpdFx1MDBFOSBkZSBsJydcdTAwRTlsXHUwMEU5bWVudCAnJ3syfScnLgotICAgICAgICBLZXlSZWZOb3RFbm91Z2hWYWx1ZXMgPSBMZSBub21icmUgZGUgdmFsZXVycyBpbmRpcXVcdTAwRTllcyBwb3VyIGxhIGNvbnRyYWludGUgZCcnaWRlbnRpdFx1MDBFOSA8a2V5cmVmIG5hbWU9InsxfSI+IGRlIGwnJ1x1MDBFOWxcdTAwRTltZW50ICJ7MH0iIGVzdCBpbnN1ZmZpc2FudC4KLSAgICAgICAgS2V5UmVmT3V0T2ZTY29wZSA9IEVycmV1ciBkZSBjb250cmFpbnRlIGQnJ2lkZW50aXRcdTAwRTkgOiBsYSBjb250cmFpbnRlIGQnJ2lkZW50aXRcdTAwRTkgInswfSIgY29tcG9ydGUgdW5lIHJcdTAwRTlmXHUwMEU5cmVuY2Uga2V5cmVmIHNlIHJhcHBvcnRhbnQgXHUwMEUwIHVuZSBjbFx1MDBFOSBvdSBcdTAwRTAgdW5lIHZhbGV1ciB1bmlxdWUgaG9ycyBwb3J0XHUwMEU5ZS4KLSAgICAgICAgS2V5UmVmUmVmZXJOb3RGb3VuZCA9IExhIGRcdTAwRTljbGFyYXRpb24gZGUgclx1MDBFOWZcdTAwRTlyZW5jZSBkZSBjbFx1MDBFOSAiezB9IiBzZSByYXBwb3J0ZSBcdTAwRTAgdW5lIGNsXHUwMEU5IGluY29ubnVlIHBvcnRhbnQgbGUgbm9tICJ7MX0iLgotICAgICAgICBVbmlxdWVOb3RFbm91Z2hWYWx1ZXMgPSBMZSBub21icmUgZGUgdmFsZXVycyBpbmRpcXVcdTAwRTllcyBwb3VyIGxhIGNvbnRyYWludGUgZCcnaWRlbnRpdFx1MDBFOSA8dW5pcXVlPiBkZSBsJydcdTAwRTlsXHUwMEU5bWVudCAiezB9IiBlc3QgaW5zdWZmaXNhbnQuCi0gICAgICAgIFVua25vd25GaWVsZCA9IEVycmV1ciBkZSBjb250cmFpbnRlIGQnJ2lkZW50aXRcdTAwRTkgaW50ZXJuZSA7IGNoYW1wIGluY29ubnUgInswfSIuCi0KLSMgSWRlYWxseSwgd2Ugc2hvdWxkIG9ubHkgdXNlIHRoZSBmb2xsb3dpbmcgZXJyb3Iga2V5cywgbm90IHRoZSBvbmVzIHVuZGVyCi0jICJJZGVudGl0eSBjb25zdHJhaW50cyIuIEFuZCB3ZSBzaG91bGQgY292ZXIgYWxsIG9mIHRoZSBmb2xsb3dpbmcgZXJyb3JzLgotCi0jdmFsaWRhdGlvbiAoMy5YLjQpCi0KLSAgICAgICAgY3ZjLWF0dHJpYnV0ZS4zID0gY3ZjLWF0dHJpYnV0ZS4zIDogTGEgdmFsZXVyICcnezJ9JycgZGUgbCcnYXR0cmlidXQgJyd7MX0nJyBkZSBsJydcdTAwRTlsXHUwMEU5bWVudCAnJ3swfScnIG4nJ2VzdCBwYXMgdmFsaWRlIHBhciByYXBwb3J0IFx1MDBFMCBzb24gdHlwZSwgJyd7M30nJy4KLSAgICAgICAgY3ZjLWF0dHJpYnV0ZS40ID0gY3ZjLWF0dHJpYnV0ZS40IDogTGEgdmFsZXVyICcnezJ9JycgZGUgbCcnYXR0cmlidXQgJyd7MX0nJyBkZSBsJydcdTAwRTlsXHUwMEU5bWVudCAnJ3swfScnIG4nJ2VzdCBwYXMgdmFsaWRlIHBhciByYXBwb3J0IFx1MDBFMCBzb24gYXR0cmlidXQgJ3sndmFsdWUgY29uc3RyYWludCd9JyBmaXhlLiBMJydhdHRyaWJ1dCBkb2l0IGF2b2lyIHVuZSB2YWxldXIgZGUgJyd7M30nJy4KLSAgICAgICAgY3ZjLWNvbXBsZXgtdHlwZS4yLjEgPSBjdmMtY29tcGxleC10eXBlLjIuMSA6IEwnJ1x1MDBFOWxcdTAwRTltZW50ICcnezB9JycgbmUgZG9pdCBjb21wb3J0ZXIgYXVjdW4gZW5mYW50IChbY2hpbGRyZW5dKSBkZSB0eXBlIGNhcmFjdFx1MDBFOHJlIG91IFx1MDBFOWxcdTAwRTltZW50IGQnJ2luZm9ybWF0aW9uLCBjYXIgbGUgdHlwZSBkZSBjb250ZW51IGR1IHR5cGUgZXN0IHZpZGUuCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuMi4yID0gY3ZjLWNvbXBsZXgtdHlwZS4yLjIgOiBMJydcdTAwRTlsXHUwMEU5bWVudCAnJ3swfScnIG5lIGRvaXQgY29tcG9ydGVyIGF1Y3VuIGVuZmFudCAoW2NoaWxkcmVuXSkgZGUgdHlwZSBcdTAwRTlsXHUwMEU5bWVudCBldCBsYSB2YWxldXIgZG9pdCBcdTAwRUF0cmUgdmFsaWRlLgotICAgICAgICBjdmMtY29tcGxleC10eXBlLjIuMyA9IGN2Yy1jb21wbGV4LXR5cGUuMi4zIDogTCcnXHUwMEU5bFx1MDBFOW1lbnQgJyd7MH0nJyBuZSBkb2l0IGNvbXBvcnRlciBhdWN1biBlbmZhbnQgKFtjaGlsZHJlbl0pIGRlIHR5cGUgY2FyYWN0XHUwMEU4cmUsIGNhciBsZSB0eXBlIHBvcnRlIGxlIHR5cGUgZGUgY29udGVudSAiZWxlbWVudC1vbmx5Ii4KLSAgICAgICAgY3ZjLWNvbXBsZXgtdHlwZS4yLjQuYSA9IGN2Yy1jb21wbGV4LXR5cGUuMi40LmEgOiBDb250ZW51IG5vbiB2YWxpZGUgdHJvdXZcdTAwRTkgXHUwMEUwIHBhcnRpciBkZSBsJydcdTAwRTlsXHUwMEU5bWVudCAnJ3swfScnLiBMJyd1bmUgZGVzIHZhbGV1cnMgJyd7MX0nJyBlc3QgYXR0ZW5kdWUuCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuMi40LmIgPSBjdmMtY29tcGxleC10eXBlLjIuNC5iIDogTGUgY29udGVudSBkZSBsJydcdTAwRTlsXHUwMEU5bWVudCAnJ3swfScnIG4nJ2VzdCBwYXMgY29tcGxldC4gTCcndW4gZGVzIFx1MDBFOWxcdTAwRTltZW50cyAnJ3sxfScnIGVzdCBhdHRlbmR1LgotICAgICAgICBjdmMtY29tcGxleC10eXBlLjIuNC5jID0gY3ZjLWNvbXBsZXgtdHlwZS4yLjQuYyA6IExlIGNhcmFjdFx1MDBFOHJlIGdcdTAwRTluXHUwMEU5cmlxdWUgY29uY29yZGFudCBlc3Qgc3RyaWN0LCBtYWlzIGF1Y3VuZSBkXHUwMEU5Y2xhcmF0aW9uIG5lIHBldXQgXHUwMEVBdHJlIHRyb3V2XHUwMEU5ZSBwb3VyIGwnJ1x1MDBFOWxcdTAwRTltZW50ICcnezB9JycuCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuMi40LmQgPSBjdmMtY29tcGxleC10eXBlLjIuNC5kIDogQ29udGVudSBub24gdmFsaWRlIHRyb3V2XHUwMEU5IFx1MDBFMCBwYXJ0aXIgZGUgbCcnXHUwMEU5bFx1MDBFOW1lbnQgJyd7MH0nJy4gQXVjdW4gXHUwMEU5bFx1MDBFOW1lbnQgZW5mYW50IG4nJ2VzdCBhdHRlbmR1IFx1MDBFMCBjZXQgZW5kcm9pdC4KLSAgICAgICAgY3ZjLWNvbXBsZXgtdHlwZS4yLjQuZSA9IGN2Yy1jb21wbGV4LXR5cGUuMi40LmQgOiBDb250ZW51IG5vbiB2YWxpZGUgdHJvdXZcdTAwRTkgXHUwMEUwIHBhcnRpciBkZSBsJydcdTAwRTlsXHUwMEU5bWVudCAnJ3swfScnLiBBdWN1biBcdTAwRTlsXHUwMEU5bWVudCBlbmZhbnQgJyd7MX0nJyBuJydlc3QgYXR0ZW5kdSBcdTAwRTAgY2V0IGVuZHJvaXQuCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuMy4xID0gY3ZjLWNvbXBsZXgtdHlwZS4zLjEgOiBMYSB2YWxldXIgJyd7Mn0nJyBkZSBsJydhdHRyaWJ1dCAnJ3sxfScnIGRlIGwnJ1x1MDBFOWxcdTAwRTltZW50ICcnezB9JycgbicnZXN0IHBhcyB2YWxpZGUgcGFyIHJhcHBvcnQgXHUwMEUwIGxhIHN5bnRheGUgZCcnYXR0cmlidXQgY29ycmVzcG9uZGFudGUuIEwnJ2F0dHJpYnV0ICcnezF9JycgYSB1bmUgdmFsZXVyIGZpeGUgZGUgJyd7M30nJy4KLSAgICAgICAgY3ZjLWNvbXBsZXgtdHlwZS4zLjIuMSA9IGN2Yy1jb21wbGV4LXR5cGUuMy4yLjEgOiBMJydcdTAwRTlsXHUwMEU5bWVudCAnJ3swfScnIG5lIGRpc3Bvc2UgZCcnYXVjdW4gY2FyYWN0XHUwMEU4cmUgZ1x1MDBFOW5cdTAwRTlyaXF1ZSBkJydhdHRyaWJ1dCBwb3VyIGwnJ2F0dHJpYnV0ICcnezF9JycuCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuMy4yLjIgPSBjdmMtY29tcGxleC10eXBlLjMuMi4yIDogTCcnYXR0cmlidXQgJyd7MX0nJyBuJydlc3QgcGFzIGF1dG9yaXNcdTAwRTkgZGFucyBsJydcdTAwRTlsXHUwMEU5bWVudCAnJ3swfScnLgotICAgICAgICBjdmMtY29tcGxleC10eXBlLjQgPSBjdmMtY29tcGxleC10eXBlLjQgOiBMJydhdHRyaWJ1dCAnJ3sxfScnIGRvaXQgZmlndXJlciBkYW5zIGwnJ1x1MDBFOWxcdTAwRTltZW50ICcnezB9JycuCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuNS4xID0gY3ZjLWNvbXBsZXgtdHlwZS41LjEgOiBEYW5zIGwnJ1x1MDBFOWxcdTAwRTltZW50ICcnezB9JycsIGwnJ2F0dHJpYnV0ICcnezF9JycgZXN0IHVuIElEIGdcdTAwRTluXHUwMEU5cmlxdWUuIE9yLCBpbCBleGlzdGUgZFx1MDBFOWpcdTAwRTAgdW4gSUQgZ1x1MDBFOW5cdTAwRTlyaXF1ZSAnJ3syfScnLiBJbCBuZSBwZXV0IGVuIGV4aXN0ZXIgcXUnJ3VuIHNldWwuCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuNS4yID0gY3ZjLWNvbXBsZXgtdHlwZS41LjIgOiBEYW5zIGwnJ1x1MDBFOWxcdTAwRTltZW50ICcnezB9JycsIGwnJ2F0dHJpYnV0ICcnezF9JycgZXN0IHVuIElEIGdcdTAwRTluXHUwMEU5cmlxdWUuIE9yLCBpbCBleGlzdGUgZFx1MDBFOWpcdTAwRTAgdW4gYXR0cmlidXQgJyd7Mn0nJyBkXHUwMEU5cml2XHUwMEU5IGRlIGwnJ0lEIGRhbnMgJ3snYXR0cmlidXRlIHVzZXMnfScuCi0gICAgICAgIGN2Yy1kYXRhdHlwZS12YWxpZC4xLjIuMSA9IGN2Yy1kYXRhdHlwZS12YWxpZC4xLjIuMSA6ICcnezB9JycgbicnZXN0IHBhcyB1bmUgdmFsZXVyIHZhbGlkZSBwb3VyICcnezF9JycuCi0gICAgICAgIGN2Yy1kYXRhdHlwZS12YWxpZC4xLjIuMiA9IGN2Yy1kYXRhdHlwZS12YWxpZC4xLjIuMiA6ICcnezB9JycgbicnZXN0IHBhcyB1bmUgdmFsZXVyIHZhbGlkZSBkdSB0eXBlIGRlIGxpc3RlICcnezF9JycuCi0gICAgICAgIGN2Yy1kYXRhdHlwZS12YWxpZC4xLjIuMyA9IGN2Yy1kYXRhdHlwZS12YWxpZC4xLjIuMyA6ICcnezB9JycgbicnZXN0IHBhcyB1bmUgdmFsZXVyIHZhbGlkZSBkdSB0eXBlIGQnJ3VuaW9uICcnezF9JycuCi0gICAgICAgIGN2Yy1lbHQuMSA9IGN2Yy1lbHQuMSA6IERcdTAwRTljbGFyYXRpb24gZGUgbCcnXHUwMEU5bFx1MDBFOW1lbnQgJyd7MH0nJyBpbnRyb3V2YWJsZS4KLSAgICAgICAgY3ZjLWVsdC4yID0gY3ZjLWVsdC4yIDogTGEgdmFsZXVyIGRlIGwnJ2F0dHJpYnV0ICd7J2Fic3RyYWN0J30nIGRhbnMgbGEgZFx1MDBFOWNsYXJhdGlvbiBkZSBsJydcdTAwRTlsXHUwMEU5bWVudCBwb3VyICcnezB9JycgZG9pdCBcdTAwRUF0cmUgRmFsc2UuCi0gICAgICAgIGN2Yy1lbHQuMy4xID0gY3ZjLWVsdC4zLjEgOiBMJydhdHRyaWJ1dCAnJ3sxfScnIG5lIGRvaXQgcGFzIGZpZ3VyZXIgZGFucyBsJydcdTAwRTlsXHUwMEU5bWVudCAnJ3swfScnLCBjYXIgbGEgcHJvcHJpXHUwMEU5dFx1MDBFOSAneyduaWxsYWJsZSd9JyBkZSAnJ3swfScnIGVzdCBGYWxzZS4KLSAgICAgICAgY3ZjLWVsdC4zLjIuMSA9IGN2Yy1lbHQuMy4yLjEgOiBMJydcdTAwRTlsXHUwMEU5bWVudCAnJ3swfScnIG5lIGRvaXQgY29tcG9ydGVyIGF1Y3VuIGVuZmFudCAoW2NoaWxkcmVuXSkgZGUgdHlwZSBjYXJhY3RcdTAwRThyZSBvdSBcdTAwRTlsXHUwMEU5bWVudCBkJydpbmZvcm1hdGlvbiwgY2FyICcnezF9JycgZXN0IGluZGlxdVx1MDBFOS4KLSAgICAgICAgY3ZjLWVsdC4zLjIuMiA9IGN2Yy1lbHQuMy4yLjIgOiBJbCBuZSBkb2l0IHkgYXZvaXIgYXVjdW4gYXR0cmlidXQgJ3sndmFsdWUgY29uc3RyYWludCd9JyBmaXhlIHBvdXIgbCcnXHUwMEU5bFx1MDBFOW1lbnQgJyd7MH0nJywgY2FyICcnezF9JycgZXN0IGluZGlxdVx1MDBFOS4KLSAgICAgICAgY3ZjLWVsdC40LjEgPSBjdmMtZWx0LjQuMSA6IExhIHZhbGV1ciAnJ3syfScnIGRlIGwnJ2F0dHJpYnV0ICcnezF9JycgZGUgbCcnXHUwMEU5bFx1MDBFOW1lbnQgJyd7MH0nJyBuJydlc3QgcGFzIHVuIFFOYW1lIHZhbGlkZS4KLSAgICAgICAgY3ZjLWVsdC40LjIgPSBjdmMtZWx0LjQuMiA6IEltcG9zc2libGUgZGUgclx1MDBFOXNvdWRyZSAnJ3sxfScnIGVuIHVuZSBkXHUwMEU5ZmluaXRpb24gZGUgdHlwZSBwb3VyIGwnJ1x1MDBFOWxcdTAwRTltZW50ICcnezB9JycuCi0gICAgICAgIGN2Yy1lbHQuNC4zID0gY3ZjLWVsdC40LjMgOiBMYSBkXHUwMEU5cml2YXRpb24gZHUgdHlwZSAnJ3sxfScnIFx1MDBFMCBwYXJ0aXIgZGUgbGEgZFx1MDBFOWZpbml0aW9uIGRlIHR5cGUgJyd7Mn0nJyBkZSBsJydcdTAwRTlsXHUwMEU5bWVudCAiezB9IiBuJydlc3QgcGFzIHZhbGlkZS4KLSAgICAgICAgY3ZjLWVsdC41LjEuMSA9IGN2Yy1lbHQuNS4xLjEgOiBMJydhdHRyaWJ1dCAneyd2YWx1ZSBjb25zdHJhaW50J30nICcnezJ9JycgZGUgbCcnXHUwMEU5bFx1MDBFOW1lbnQgJyd7MH0nJyBuJydlc3QgcGFzIHVuZSB2YWxldXIgcGFyIGRcdTAwRTlmYXV0IHZhbGlkZSBwb3VyIGxlIHR5cGUgJyd7MX0nJy4KLSAgICAgICAgY3ZjLWVsdC41LjIuMi4xID0gY3ZjLWVsdC41LjIuMi4xIDogTCcnXHUwMEU5bFx1MDBFOW1lbnQgJyd7MH0nJyBuZSBkb2l0IGNvbXBvcnRlciBhdWN1biBlbmZhbnQgKFtjaGlsZHJlbl0pIGRlIHR5cGUgXHUwMEU5bFx1MDBFOW1lbnQgZCcnaW5mb3JtYXRpb24uCi0gICAgICAgIGN2Yy1lbHQuNS4yLjIuMi4xID0gY3ZjLWVsdC41LjIuMi4yLjEgOiBMYSB2YWxldXIgJyd7MX0nJyBkZSBsJydcdTAwRTlsXHUwMEU5bWVudCAnJ3swfScnIG5lIGNvbmNvcmRlIHBhcyBhdmVjIGxhIHZhbGV1ciBkZSBsJydhdHRyaWJ1dCAneyd2YWx1ZSBjb25zdHJhaW50J30nIGZpeGUgJyd7Mn0nJy4KLSAgICAgICAgY3ZjLWVsdC41LjIuMi4yLjIgPSBjdmMtZWx0LjUuMi4yLjIuMiA6IExhIHZhbGV1ciAnJ3sxfScnIGRlIGwnJ1x1MDBFOWxcdTAwRTltZW50ICcnezB9JycgbmUgY29uY29yZGUgcGFzIGF2ZWMgbGEgdmFsZXVyIGRlIGwnJ2F0dHJpYnV0ICd7J3ZhbHVlIGNvbnN0cmFpbnQnfScgJyd7Mn0nJy4KLSAgICAgICAgY3ZjLWVudW1lcmF0aW9uLXZhbGlkID0gY3ZjLWVudW1lcmF0aW9uLXZhbGlkIDogTGEgdmFsZXVyICcnezB9JycgbicnZXN0IHBhcyB1biBmYWNldCB2YWxpZGUgcGFyIHJhcHBvcnQgXHUwMEUwIGwnJ1x1MDBFOW51bVx1MDBFOXJhdGlvbiAnJ3sxfScnLiBJbCBkb2l0IHMnJ2FnaXIgZCcndW5lIHZhbGV1ciBwcm92ZW5hbnQgZGUgbCcnXHUwMEU5bnVtXHUwMEU5cmF0aW9uLgotICAgICAgICBjdmMtZnJhY3Rpb25EaWdpdHMtdmFsaWQgPSBjdmMtZnJhY3Rpb25EaWdpdHMtdmFsaWQgOiBMYSB2YWxldXIgJyd7MH0nJyBwb3NzXHUwMEU4ZGUgezF9IGNoaWZmcmVzIGFwclx1MDBFOHMgbGEgdmlyZ3VsZSwgbWFpcyBsZSBub21icmUgZGUgY2hpZmZyZXMgYXByXHUwMEU4cyBsYSB2aXJndWxlIG5lIGRvaXQgcGFzIGRcdTAwRTlwYXNzZXIgezJ9LgotICAgICAgICBjdmMtaWQuMSA9IGN2Yy1pZC4xIDogQXVjdW5lIGxpYWlzb24gSUQvSURSRUYgcG91ciBsJydJRFJFRiAnJ3swfScnLgotICAgICAgICBjdmMtaWQuMiA9IGN2Yy1pZC4yIDogT2NjdXJyZW5jZXMgbXVsdGlwbGVzIGRlIGxhIHZhbGV1ciBkJydJRCAnJ3swfScnLgotICAgICAgICBjdmMtaWQuMyA9IGN2Yy1pZC4zIDogVW4gY2hhbXAgZGUgY29udHJhaW50ZSBkJydpZGVudGl0XHUwMEU5ICJ7MH0iIGEgXHUwMEU5dFx1MDBFOSBtaXMgZW4gY29ycmVzcG9uZGFuY2UgYXZlYyBsJydcdTAwRTlsXHUwMEU5bWVudCAiezF9IiwgbWFpcyBjZXQgXHUwMEU5bFx1MDBFOW1lbnQgbmUgY29tcG9ydGUgcGFzIGRlIHR5cGUgc2ltcGxlLgotICAgICAgICBjdmMtbGVuZ3RoLXZhbGlkID0gY3ZjLWxlbmd0aC12YWxpZCA6IExhIHZhbGV1ciAnJ3swfScnLCBheWFudCBwb3VyIGxvbmd1ZXVyICcnezF9JycsIG4nJ2VzdCBwYXMgdW4gZmFjZXQgdmFsaWRlIHBhciByYXBwb3J0IFx1MDBFMCBsYSBsb25ndWV1ciAnJ3syfScnIHBvdXIgbGUgdHlwZSAnJ3szfScnLgotICAgICAgICBjdmMtbWF4RXhjbHVzaXZlLXZhbGlkID0gY3ZjLW1heEV4Y2x1c2l2ZS12YWxpZCA6IExhIHZhbGV1ciAnJ3swfScnIG4nJ2VzdCBwYXMgdW4gZmFjZXQgdmFsaWRlIHBhciByYXBwb3J0IFx1MDBFMCBtYXhFeGNsdXNpdmUgJyd7MX0nJyBwb3VyIGxlIHR5cGUgJyd7Mn0nJy4KLSAgICAgICAgY3ZjLW1heEluY2x1c2l2ZS12YWxpZCA9IGN2Yy1tYXhJbmNsdXNpdmUtdmFsaWQgOiBMYSB2YWxldXIgJyd7MH0nJyBuJydlc3QgcGFzIHVuIGZhY2V0IHZhbGlkZSBwYXIgcmFwcG9ydCBcdTAwRTAgbWF4SW5jbHVzaXZlICcnezF9JycgcG91ciBsZSB0eXBlICcnezJ9JycuCi0gICAgICAgIGN2Yy1tYXhMZW5ndGgtdmFsaWQgPSBjdmMtbWF4TGVuZ3RoLXZhbGlkIDogTGEgdmFsZXVyICcnezB9JycsIGF5YW50IHBvdXIgbG9uZ3VldXIgJyd7MX0nJywgbicnZXN0IHBhcyB1biBmYWNldCB2YWxpZGUgcGFyIHJhcHBvcnQgXHUwMEUwIG1heExlbmd0aCAnJ3syfScnIHBvdXIgbGUgdHlwZSAnJ3szfScnLgotICAgICAgICBjdmMtbWluRXhjbHVzaXZlLXZhbGlkID0gY3ZjLW1pbkV4Y2x1c2l2ZS12YWxpZCA6IExhIHZhbGV1ciAnJ3swfScnIG4nJ2VzdCBwYXMgdW4gZmFjZXQgdmFsaWRlIHBhciByYXBwb3J0IFx1MDBFMCBtaW5FeGNsdXNpdmUgJyd7MX0nJyBwb3VyIGxlIHR5cGUgJyd7Mn0nJy4KLSAgICAgICAgY3ZjLW1pbkluY2x1c2l2ZS12YWxpZCA9IGN2Yy1taW5JbmNsdXNpdmUtdmFsaWQgOiBMYSB2YWxldXIgJyd7MH0nJyBuJydlc3QgcGFzIHVuIGZhY2V0IHZhbGlkZSBwYXIgcmFwcG9ydCBcdTAwRTAgbWluSW5jbHVzaXZlICcnezF9JycgcG91ciBsZSB0eXBlICcnezJ9JycuCi0gICAgICAgIGN2Yy1taW5MZW5ndGgtdmFsaWQgPSBjdmMtbWluTGVuZ3RoLXZhbGlkIDogTGEgdmFsZXVyICcnezB9JycsIGF5YW50IHBvdXIgbG9uZ3VldXIgJyd7MX0nJywgbicnZXN0IHBhcyB1biBmYWNldCB2YWxpZGUgcGFyIHJhcHBvcnQgXHUwMEUwIG1pbkxlbmd0aCAnJ3syfScnIHBvdXIgbGUgdHlwZSAnJ3szfScnLgotICAgICAgICBjdmMtcGF0dGVybi12YWxpZCA9IGN2Yy1wYXR0ZXJuLXZhbGlkIDogTGEgdmFsZXVyICcnezB9JycgbicnZXN0IHBhcyB1biBmYWNldCB2YWxpZGUgcGFyIHJhcHBvcnQgYXUgbW9kXHUwMEU4bGUgJyd7MX0nJyBwb3VyIGxlIHR5cGUgJyd7Mn0nJy4KLSAgICAgICAgY3ZjLXRvdGFsRGlnaXRzLXZhbGlkID0gY3ZjLXRvdGFsRGlnaXRzLXZhbGlkIDogTGEgdmFsZXVyICcnezB9JycgcG9zc1x1MDBFOGRlIHVuIHRvdGFsIGRlIHsxfSBjaGlmZnJlcywgbWFpcyBsZSBub21icmUgdG90YWwgZGUgY2hpZmZyZXMgbmUgZG9pdCBwYXMgZFx1MDBFOXBhc3NlciB7Mn0uCi0gICAgICAgIGN2Yy10eXBlLjIgPSBjdmMtdHlwZS4yIDogTGEgZFx1MDBFOWZpbml0aW9uIGRlIHR5cGUgbmUgZG9pdCBwYXMgXHUwMEVBdHJlIGFic3RyYWN0IHBvdXIgbCcnXHUwMEU5bFx1MDBFOW1lbnQgezB9LgotICAgICAgICBjdmMtdHlwZS4zLjEuMSA9IGN2Yy10eXBlLjMuMS4xIDogTCcnXHUwMEU5bFx1MDBFOW1lbnQgJyd7MH0nJyBlc3QgZGUgdHlwZSBzaW1wbGUgZXQgbmUgcGV1dCBkb25jIHBhcyBhdm9pciBkJydhdHRyaWJ1dHMsIFx1MDBFMCBsJydleGNlcHRpb24gZGUgY2V1eCBvXHUwMEY5IGxlIG5vbSBkJydlc3BhY2UgZGUgbm9tcyBlc3QgaWRlbnRpcXVlIFx1MDBFMCAnJ2h0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlJycgZXQgb1x1MDBGOSBbbG9jYWwgbmFtZV0gZXN0ICcndHlwZScnLCAnJ25pbCcnLCAnJ3NjaGVtYUxvY2F0aW9uJycgb3UgJydub05hbWVzcGFjZVNjaGVtYUxvY2F0aW9uJycuIENlcGVuZGFudCwgbCcnYXR0cmlidXQgJyd7MX0nJyBhIFx1MDBFOXRcdTAwRTkgdHJvdXZcdTAwRTkuCi0gICAgICAgIGN2Yy10eXBlLjMuMS4yID0gY3ZjLXR5cGUuMy4xLjIgOiBMJydcdTAwRTlsXHUwMEU5bWVudCAnJ3swfScnIGVzdCBkZSB0eXBlIHNpbXBsZSBldCBuZSBkb2l0IGNvbXBvcnRlciBhdWN1biBlbmZhbnQgKFtjaGlsZHJlbl0pIGRlIHR5cGUgXHUwMEU5bFx1MDBFOW1lbnQgZCcnaW5mb3JtYXRpb24uCi0gICAgICAgIGN2Yy10eXBlLjMuMS4zID0gY3ZjLXR5cGUuMy4xLjMgOiBMYSB2YWxldXIgJyd7MX0nJyBkZSBsJydcdTAwRTlsXHUwMEU5bWVudCAnJ3swfScnIG4nJ2VzdCBwYXMgdmFsaWRlLgotCi0jc2NoZW1hIHZhbGlkICgzLlguMykKLQotICAgICAgICBzY2hlbWFfcmVmZXJlbmNlLmFjY2VzcyA9IHNjaGVtYV9yZWZlcmVuY2UgOiBcdTAwRTljaGVjIGRlIGxhIGxlY3R1cmUgZHUgZG9jdW1lbnQgZGUgc2NoXHUwMEU5bWEgJyd7MH0nJywgY2FyIGwnJ2FjY1x1MDBFOHMgJyd7MX0nJyBuJydlc3QgcGFzIGF1dG9yaXNcdTAwRTkgZW4gcmFpc29uIGQnJ3VuZSByZXN0cmljdGlvbiBkXHUwMEU5ZmluaWUgcGFyIGxhIHByb3ByaVx1MDBFOXRcdTAwRTkgYWNjZXNzRXh0ZXJuYWxTY2hlbWEuIAotICAgICAgICBzY2hlbWFfcmVmZXJlbmNlLjQgPSBzY2hlbWFfcmVmZXJlbmNlLjQgOiBFY2hlYyBkZSBsYSBsZWN0dXJlIGR1IGRvY3VtZW50IGRlIHNjaFx1MDBFOW1hICcnezB9JycgcG91ciBsZXMgcmFpc29ucyBzdWl2YW50ZXMgOiAxKSBMZSBkb2N1bWVudCBlc3QgaW50cm91dmFibGUgOyAyKSBMZSBkb2N1bWVudCBuJydhIHBhcyBwdSBcdTAwRUF0cmUgbHUgOyAzKSBMJydcdTAwRTlsXHUwMEU5bWVudCByYWNpbmUgZHUgZG9jdW1lbnQgbicnZXN0IHBhcyA8eHNkOnNjaGVtYT4uCi0gICAgICAgIHNyYy1hbm5vdGF0aW9uID0gc3JjLWFubm90YXRpb24gOiBMZXMgXHUwMEU5bFx1MDBFOW1lbnRzIDxhbm5vdGF0aW9uPiBuZSBwZXV2ZW50IGNvbnRlbmlyIHF1ZSBkZXMgXHUwMEU5bFx1MDBFOW1lbnRzIDxhcHBpbmZvPiBldCA8ZG9jdW1lbnRhdGlvbj4sIG1haXMgJyd7MH0nJyBhIFx1MDBFOXRcdTAwRTkgdHJvdXZcdTAwRTkuCi0gICAgICAgIHNyYy1hdHRyaWJ1dGUuMSA9IHNyYy1hdHRyaWJ1dGUuMSA6IExlcyBwcm9wcmlcdTAwRTl0XHUwMEU5cyAnJ2RlZmF1bHQnJyBldCAnJ2ZpeGVkJycgbmUgcGV1dmVudCBwYXMgZmlndXJlciBzaW11bHRhblx1MDBFOW1lbnQgZGFucyBsYSBkXHUwMEU5Y2xhcmF0aW9uIGQnJ2F0dHJpYnV0ICcnezB9JycuIFV0aWxpc2V6IHVuaXF1ZW1lbnQgbCcndW5lIGQnJ2VudHJlIGVsbGVzLgotICAgICAgICBzcmMtYXR0cmlidXRlLjIgPSBzcmMtYXR0cmlidXRlLjIgOiBMYSBwcm9wcmlcdTAwRTl0XHUwMEU5ICcnZGVmYXVsdCcnIGZpZ3VyZSBkYW5zIGwnJ2F0dHJpYnV0ICcnezB9JycsIGxhIHZhbGV1ciBkZSAnJ3VzZScnIGRvaXQgZG9uYyBcdTAwRUF0cmUgJydvcHRpb25hbCcnLgotICAgICAgICBzcmMtYXR0cmlidXRlLjMuMSA9IHNyYy1hdHRyaWJ1dGUuMy4xIDogJ3JlZicgb3UgJ25hbWUnIGRvaXQgZmlndXJlciBkYW5zIGxlcyBkXHUwMEU5Y2xhcmF0aW9ucyBkJ2F0dHJpYnV0IGxvY2FsLgotICAgICAgICBzcmMtYXR0cmlidXRlLjMuMiA9IHNyYy1hdHRyaWJ1dGUuMy4yIDogTGUgY29udGVudSBkb2l0IGNvbmNvcmRlciBhdmVjIChhbm5vdGF0aW9uPykgcG91ciBsYSByXHUwMEU5Zlx1MDBFOXJlbmNlIGQnJ2F0dHJpYnV0ICcnezB9JycuCi0gICAgICAgIHNyYy1hdHRyaWJ1dGUuNCA9IHNyYy1hdHRyaWJ1dGUuNCA6IEwnJ2F0dHJpYnV0ICcnezB9JycgcHJcdTAwRTlzZW50ZSB1biBhdHRyaWJ1dCAnJ3R5cGUnJyBldCB1biBlbmZhbnQgJydzaW1wbGVUeXBlJycgYW5vbnltZS4gU2V1bCB1biBkJydlbnRyZSBldXggZXN0IGF1dG9yaXNcdTAwRTkgZGFucyB1biBhdHRyaWJ1dC4KLSAgICAgICAgc3JjLWF0dHJpYnV0ZV9ncm91cC4yID0gc3JjLWF0dHJpYnV0ZV9ncm91cC4yIDogTCcnaW50ZXJzZWN0aW9uIGRlIGNhcmFjdFx1MDBFOHJlcyBnXHUwMEU5blx1MDBFOXJpcXVlcyBuZSBwZXV0IHBhcyBcdTAwRUF0cmUgZXhwcmltXHUwMEU5ZSBwb3VyIGxlIGdyb3VwZSBkJydhdHRyaWJ1dCAnJ3swfScnLgotICAgICAgICBzcmMtYXR0cmlidXRlX2dyb3VwLjMgPSBzcmMtYXR0cmlidXRlX2dyb3VwLjMgOiBEXHUwMEU5ZmluaXRpb25zIGNpcmN1bGFpcmVzIGRcdTAwRTl0ZWN0XHUwMEU5ZXMgcG91ciBsZSBncm91cGUgZCcnYXR0cmlidXQgJyd7MH0nJy4gTGUgc3Vpdmkgclx1MDBFOWN1cnNpZiBkZXMgclx1MDBFOWZcdTAwRTlyZW5jZXMgZGUgZ3JvdXBlIGQnJ2F0dHJpYnV0IGNvbmR1aXQgXHUwMEUwIGx1aS1tXHUwMEVBbWUuCi0gICAgICAgIHNyYy1jdC4xID0gc3JjLWN0LjEgOiBFcnJldXIgZGUgcmVwclx1MDBFOXNlbnRhdGlvbiBkZSBsYSBkXHUwMEU5ZmluaXRpb24gZGUgdHlwZSBjb21wbGV4ZSBwb3VyIGxlIHR5cGUgJyd7MH0nJy4gTG9yc3F1ZSA8Y29tcGxleENvbnRlbnQ+IGVzdCB1dGlsaXNcdTAwRTksIGxlIHR5cGUgZGUgYmFzZSBkb2l0IFx1MDBFQXRyZSBjb21wbGV4VHlwZS4gJyd7MX0nJyBlc3Qgc2ltcGxlVHlwZS4KLSAgICAgICAgc3JjLWN0LjIuMSA9IHNyYy1jdC4yLjEgOiBFcnJldXIgZGUgcmVwclx1MDBFOXNlbnRhdGlvbiBkZSBsYSBkXHUwMEU5ZmluaXRpb24gZGUgdHlwZSBjb21wbGV4ZSBwb3VyIGxlIHR5cGUgJyd7MH0nJy4gTG9yc3F1ZSA8c2ltcGxlQ29udGVudD4gZXN0IHV0aWxpc1x1MDBFOSwgbGUgdHlwZSBkZSBiYXNlIGRvaXQgXHUwMEVBdHJlIGNvbXBsZXhUeXBlIGF2ZWMgdW4gdHlwZSBkZSBjb250ZW51IHNpbXBsZS4gU2kgdW5lIHJlc3RyaWN0aW9uIGVzdCBpbmRpcXVcdTAwRTllLCBpbCBwZXV0IHMnJ2FnaXIgZCcndW4gdHlwZSBjb21wbGV4ZSBhdmVjIHVuIGNvbnRlbnUgbWl4dGUgZXQgdW5lIHBhcnRpY3VsZSBwb3V2YW50IFx1MDBFQXRyZSB2aWRlIG91LCBzaSB1bmUgZXh0ZW5zaW9uIGVzdCBpbmRpcXVcdTAwRTllLCBkJyd1biB0eXBlIHNpbXBsZS4gJyd7MX0nJyBuZSByZXNwZWN0ZSBhdWN1bmUgZGUgY2VzIGNvbmRpdGlvbnMuCi0gICAgICAgIHNyYy1jdC4yLjIgPSBzcmMtY3QuMi4yIDogRXJyZXVyIGRlIHJlcHJcdTAwRTlzZW50YXRpb24gZGUgbGEgZFx1MDBFOWZpbml0aW9uIGRlIHR5cGUgY29tcGxleGUgcG91ciBsZSB0eXBlICcnezB9JycuIExvcnNxdScndW4gY29tcGxleFR5cGUgYXZlYyB1biBzaW1wbGVDb250ZW50IHJlc3RyZWludCB1biBjb21wbGV4VHlwZSBjb21wb3J0YW50IHVuIGNvbnRlbnUgbWl4dGUgZXQgdW5lIHBhcnRpY3VsZSBwb3V2YW50IFx1MDBFQXRyZSB2aWRlLCB1biA8c2ltcGxlVHlwZT4gZG9pdCBmaWd1cmVyIHBhcm1pIGxlcyBlbmZhbnRzIGRlIDxyZXN0cmljdGlvbj4uCi0gICAgICAgIHNyYy1jdC40ID0gc3JjLWN0LjQgOiBFcnJldXIgZGUgcmVwclx1MDBFOXNlbnRhdGlvbiBkZSBsYSBkXHUwMEU5ZmluaXRpb24gZGUgdHlwZSBjb21wbGV4ZSBwb3VyIGxlIHR5cGUgJyd7MH0nJy4gTCcnaW50ZXJzZWN0aW9uIGRlIGNhcmFjdFx1MDBFOHJlcyBnXHUwMEU5blx1MDBFOXJpcXVlcyBuZSBwZXV0IHBhcyBcdTAwRUF0cmUgZXhwcmltXHUwMEU5ZS4KLSAgICAgICAgc3JjLWN0LjUgPSBzcmMtY3QuNSA6IEVycmV1ciBkZSByZXByXHUwMEU5c2VudGF0aW9uIGRlIGxhIGRcdTAwRTlmaW5pdGlvbiBkZSB0eXBlIGNvbXBsZXhlIHBvdXIgbGUgdHlwZSAnJ3swfScnLiBMJyd1bmlvbiBkZSBjYXJhY3RcdTAwRThyZXMgZ1x1MDBFOW5cdTAwRTlyaXF1ZXMgbmUgcGV1dCBwYXMgXHUwMEVBdHJlIGV4cHJpbVx1MDBFOWUuCi0gICAgICAgIHNyYy1lbGVtZW50LjEgPSBzcmMtZWxlbWVudC4xIDogTGVzIHByb3ByaVx1MDBFOXRcdTAwRTlzICcnZGVmYXVsdCcnIGV0ICcnZml4ZWQnJyBuZSBwZXV2ZW50IHBhcyBmaWd1cmVyIHNpbXVsdGFuXHUwMEU5bWVudCBkYW5zIGxhIGRcdTAwRTljbGFyYXRpb24gZCcnXHUwMEU5bFx1MDBFOW1lbnQgJyd7MH0nJy4gVXRpbGlzZXogdW5pcXVlbWVudCBsJyd1bmUgZCcnZW50cmUgZWxsZXMuCi0gICAgICAgIHNyYy1lbGVtZW50LjIuMSA9IHNyYy1lbGVtZW50LjIuMSA6ICdyZWYnIG91ICduYW1lJyBkb2l0IGZpZ3VyZXIgZGFucyBsZXMgZFx1MDBFOWNsYXJhdGlvbnMgZCdcdTAwRTlsXHUwMEU5bWVudCBsb2NhbC4KLSAgICAgICAgc3JjLWVsZW1lbnQuMi4yID0gc3JjLWVsZW1lbnQuMi4yIDogUHVpc3F1ZSAnJ3swfScnIGNvbnRpZW50IGwnJ2F0dHJpYnV0ICcncmVmJycsIHNvbiBjb250ZW51IGRvaXQgY29uY29yZGVyIGF2ZWMgKGFubm90YXRpb24/KS4gQ2VwZW5kYW50LCAnJ3sxfScnIGEgXHUwMEU5dFx1MDBFOSB0cm91dlx1MDBFOS4KLSAgICAgICAgc3JjLWVsZW1lbnQuMyA9IHNyYy1lbGVtZW50LjMgOiBMJydcdTAwRTlsXHUwMEU5bWVudCAnJ3swfScnIHByXHUwMEU5c2VudGUgdW4gYXR0cmlidXQgJyd0eXBlJycgZXQgdW4gZW5mYW50ICcnYW5vbnltb3VzIHR5cGUnJy4gU2V1bCB1biBkJydlbnRyZSBldXggZXN0IGF1dG9yaXNcdTAwRTkgZGFucyB1biBcdTAwRTlsXHUwMEU5bWVudC4KLSAgICAgICAgc3JjLWltcG9ydC4xLjEgPSBzcmMtaW1wb3J0LjEuMSA6IEwnJ2F0dHJpYnV0IG5hbWVzcGFjZSAiezB9IiBkJyd1biBcdTAwRTlsXHUwMEU5bWVudCBkJydpbmZvcm1hdGlvbiBkJydcdTAwRTlsXHUwMEU5bWVudCA8aW1wb3J0PiBuZSBkb2l0IHBhcyBcdTAwRUF0cmUgaWRlbnRpcXVlIFx1MDBFMCBsJydhdHRyaWJ1dCB0YXJnZXROYW1lc3BhY2UgZHUgc2NoXHUwMEU5bWEgZGFucyBsZXF1ZWwgaWwgZmlndXJlLgotICAgICAgICBzcmMtaW1wb3J0LjEuMiA9IHNyYy1pbXBvcnQuMS4yIDogU2kgbCdhdHRyaWJ1dCBuYW1lc3BhY2UgbmUgZmlndXJlIHBhcyBkYW5zIHVuIFx1MDBFOWxcdTAwRTltZW50IGQnaW5mb3JtYXRpb24gZCdcdTAwRTlsXHUwMEU5bWVudCA8aW1wb3J0PiwgbGUgc2NoXHUwMEU5bWEgZW5nbG9iYW50IGRvaXQgYXZvaXIgdW4gYXR0cmlidXQgdGFyZ2V0TmFtZXNwYWNlLgotICAgICAgICBzcmMtaW1wb3J0LjIgPSBzcmMtaW1wb3J0LjIgOiBMJydcdTAwRTlsXHUwMEU5bWVudCByYWNpbmUgZHUgZG9jdW1lbnQgJyd7MH0nJyBkb2l0IGF2b2lyIGxlIG5vbSBkJydlc3BhY2UgZGUgbm9tcyAnJ2h0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hJycgZXQgbGUgbm9tIGxvY2FsICcnc2NoZW1hJycuCi0gICAgICAgIHNyYy1pbXBvcnQuMy4xID0gc3JjLWltcG9ydC4zLjEgOiBMJydhdHRyaWJ1dCBuYW1lc3BhY2UgInswfSIgZCcndW4gXHUwMEU5bFx1MDBFOW1lbnQgZCcnaW5mb3JtYXRpb24gZCcnXHUwMEU5bFx1MDBFOW1lbnQgPGltcG9ydD4gZG9pdCBcdTAwRUF0cmUgaWRlbnRpcXVlIFx1MDBFMCBsJydhdHRyaWJ1dCB0YXJnZXROYW1lc3BhY2UgJyd7MX0nJyBkdSBkb2N1bWVudCBpbXBvcnRcdTAwRTkuCi0gICAgICAgIHNyYy1pbXBvcnQuMy4yID0gc3JjLWltcG9ydC4zLjIgOiBVbiBcdTAwRTlsXHUwMEU5bWVudCBkJydpbmZvcm1hdGlvbiBkJydcdTAwRTlsXHUwMEU5bWVudCA8aW1wb3J0PiBzYW5zIGF0dHJpYnV0IG5hbWVzcGFjZSBhIFx1MDBFOXRcdTAwRTkgdHJvdXZcdTAwRTkuIExlIGRvY3VtZW50IGltcG9ydFx1MDBFOSBuZSBwZXV0IGRvbmMgcGFzIGF2b2lyIHVuIGF0dHJpYnV0IHRhcmdldE5hbWVzcGFjZS4gQ2VwZW5kYW50LCBsJydhdHRyaWJ1dCB0YXJnZXROYW1lc3BhY2UgJyd7MX0nJyBhIFx1MDBFOXRcdTAwRTkgdHJvdXZcdTAwRTkgZGFucyBsZSBkb2N1bWVudCBpbXBvcnRcdTAwRTkuCi0gICAgICAgIHNyYy1pbmNsdWRlLjEgPSBzcmMtaW5jbHVkZS4xIDogTCcnXHUwMEU5bFx1MDBFOW1lbnQgcmFjaW5lIGR1IGRvY3VtZW50ICcnezB9JycgZG9pdCBhdm9pciBsZSBub20gZCcnZXNwYWNlIGRlIG5vbXMgJydodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYScnIGV0IGxlIG5vbSBsb2NhbCAnJ3NjaGVtYScnLgotICAgICAgICBzcmMtaW5jbHVkZS4yLjEgPSBzcmMtaW5jbHVkZS4yLjE6IEwnJ2F0dHJpYnV0IHRhcmdldE5hbWVzcGFjZSBkdSBzY2hcdTAwRTltYSByXHUwMEU5Zlx1MDBFOXJlbmNcdTAwRTksIGFjdHVlbGxlbWVudCAnJ3sxfScnLCBkb2l0IFx1MDBFQXRyZSBpZGVudGlxdWUgXHUwMEUwIGNlbHVpIGR1IHNjaFx1MDBFOW1hIGQnJ2luY2x1c2lvbiwgYWN0dWVsbGVtZW50ICcnezB9JycuCi0gICAgICAgIHNyYy1yZWRlZmluZS4yID0gc3JjLXJlZGVmaW5lLjIgOiBMJydcdTAwRTlsXHUwMEU5bWVudCByYWNpbmUgZHUgZG9jdW1lbnQgJyd7MH0nJyBkb2l0IGF2b2lyIGxlIG5vbSBkJydlc3BhY2UgZGUgbm9tcyAnJ2h0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hJycgZXQgbGUgbm9tIGxvY2FsICcnc2NoZW1hJycuCi0gICAgICAgIHNyYy1yZWRlZmluZS4zLjEgPSBzcmMtcmVkZWZpbmUuMy4xIDogTCcnYXR0cmlidXQgdGFyZ2V0TmFtZXNwYWNlIGR1IHNjaFx1MDBFOW1hIHJcdTAwRTlmXHUwMEU5cmVuY1x1MDBFOSwgYWN0dWVsbGVtZW50ICcnezF9JycsIGRvaXQgXHUwMEVBdHJlIGlkZW50aXF1ZSBcdTAwRTAgY2VsdWkgZHUgc2NoXHUwMEU5bWEgZGUgcmVkXHUwMEU5ZmluaXRpb24sIGFjdHVlbGxlbWVudCAnJ3swfScnLgotICAgICAgICBzcmMtcmVkZWZpbmUuNS5hLmEgPSBzcmMtcmVkZWZpbmUuNS5hLmEgOiBBdWN1biBlbmZhbnQgZGUgbm9uLWFubm90YXRpb24gZGUgPHNpbXBsZVR5cGU+IG4nYSBcdTAwRTl0XHUwMEU5IHRyb3V2XHUwMEU5LiBMZXMgZW5mYW50cyA8c2ltcGxlVHlwZT4gZGVzIFx1MDBFOWxcdTAwRTltZW50cyA8cmVkZWZpbmU+IGRvaXZlbnQgY29tcG9ydGVyIGRlcyBkZXNjZW5kYW50cyA8cmVzdHJpY3Rpb24+LCBhdmVjIGRlcyBhdHRyaWJ1dHMgImJhc2UiIGZhaXNhbnQgclx1MDBFOWZcdTAwRTlyZW5jZSBcdTAwRTAgZXV4LW1cdTAwRUFtZXMuCi0gICAgICAgIHNyYy1yZWRlZmluZS41LmEuYiA9IHNyYy1yZWRlZmluZS41LmEuYiA6ICcnezB9JycgbicnZXN0IHBhcyB1biBcdTAwRTlsXHUwMEU5bWVudCBlbmZhbnQgdmFsaWRlLiBMZXMgZW5mYW50cyA8c2ltcGxlVHlwZT4gZGVzIFx1MDBFOWxcdTAwRTltZW50cyA8cmVkZWZpbmU+IGRvaXZlbnQgY29tcG9ydGVyIGRlcyBkZXNjZW5kYW50cyA8cmVzdHJpY3Rpb24+LCBhdmVjIGRlcyBhdHRyaWJ1dHMgJydiYXNlJycgZmFpc2FudCByXHUwMEU5Zlx1MDBFOXJlbmNlIFx1MDBFMCBldXgtbVx1MDBFQW1lcy4KLSAgICAgICAgc3JjLXJlZGVmaW5lLjUuYS5jID0gc3JjLXJlZGVmaW5lLjUuYS5jIDogJyd7MH0nJyBuZSBjb21wb3J0ZSBwYXMgZCcnYXR0cmlidXQgJydiYXNlJycgZmFpc2FudCByXHUwMEU5Zlx1MDBFOXJlbmNlIFx1MDBFMCBsJydcdTAwRTlsXHUwMEU5bWVudCByZWRcdTAwRTlmaW5pLCAnJ3sxfScnLiBMZXMgZW5mYW50cyA8c2ltcGxlVHlwZT4gZGVzIFx1MDBFOWxcdTAwRTltZW50cyA8cmVkZWZpbmU+IGRvaXZlbnQgY29tcG9ydGVyIGRlcyBkZXNjZW5kYW50cyA8cmVzdHJpY3Rpb24+LCBhdmVjIGRlcyBhdHRyaWJ1dHMgJydiYXNlJycgZmFpc2FudCByXHUwMEU5Zlx1MDBFOXJlbmNlIFx1MDBFMCBldXgtbVx1MDBFQW1lcy4KLSAgICAgICAgc3JjLXJlZGVmaW5lLjUuYi5hID0gc3JjLXJlZGVmaW5lLjUuYi5hIDogQXVjdW4gZW5mYW50IGRlIG5vbi1hbm5vdGF0aW9uIGRlIDxjb21wbGV4VHlwZT4gbidhIFx1MDBFOXRcdTAwRTkgdHJvdXZcdTAwRTkuIExlcyBlbmZhbnRzIDxjb21wbGV4VHlwZT4gZGVzIFx1MDBFOWxcdTAwRTltZW50cyA8cmVkZWZpbmU+IGRvaXZlbnQgY29tcG9ydGVyIGRlcyBkZXNjZW5kYW50cyA8ZXh0ZW5zaW9uPiBvdSA8cmVzdHJpY3Rpb24+LCBhdmVjIGRlcyBhdHRyaWJ1dHMgImJhc2UiIGZhaXNhbnQgclx1MDBFOWZcdTAwRTlyZW5jZSBcdTAwRTAgZXV4LW1cdTAwRUFtZXMuCi0gICAgICAgIHNyYy1yZWRlZmluZS41LmIuYiA9IHNyYy1yZWRlZmluZS41LmIuYiA6IEF1Y3VuIHBldGl0LWVuZmFudCBkZSBub24tYW5ub3RhdGlvbiBkZSA8Y29tcGxleFR5cGU+IG4nYSBcdTAwRTl0XHUwMEU5IHRyb3V2XHUwMEU5LiBMZXMgZW5mYW50cyA8Y29tcGxleFR5cGU+IGRlcyBcdTAwRTlsXHUwMEU5bWVudHMgPHJlZGVmaW5lPiBkb2l2ZW50IGNvbXBvcnRlciBkZXMgZGVzY2VuZGFudHMgPGV4dGVuc2lvbj4gb3UgPHJlc3RyaWN0aW9uPiwgYXZlYyBkZXMgYXR0cmlidXRzICJiYXNlIiBmYWlzYW50IHJcdTAwRTlmXHUwMEU5cmVuY2UgXHUwMEUwIGV1eC1tXHUwMEVBbWVzLgotICAgICAgICBzcmMtcmVkZWZpbmUuNS5iLmMgPSBzcmMtcmVkZWZpbmUuNS5iLmMgOiAnJ3swfScnIG4nJ2VzdCBwYXMgdW4gXHUwMEU5bFx1MDBFOW1lbnQgcGV0aXQtZW5mYW50IHZhbGlkZS4gTGVzIGVuZmFudHMgPGNvbXBsZXhUeXBlPiBkZXMgXHUwMEU5bFx1MDBFOW1lbnRzIDxyZWRlZmluZT4gZG9pdmVudCBjb21wb3J0ZXIgZGVzIGRlc2NlbmRhbnRzIDxleHRlbnNpb24+IG91IDxyZXN0cmljdGlvbj4sIGF2ZWMgZGVzIGF0dHJpYnV0cyAnJ2Jhc2UnJyBmYWlzYW50IHJcdTAwRTlmXHUwMEU5cmVuY2UgXHUwMEUwIGV1eC1tXHUwMEVBbWVzLgotICAgICAgICBzcmMtcmVkZWZpbmUuNS5iLmQgPSBzcmMtcmVkZWZpbmUuNS5iLmQgOiAnJ3swfScnIG5lIGNvbXBvcnRlIHBhcyBkJydhdHRyaWJ1dCAnJ2Jhc2UnJyBmYWlzYW50IHJcdTAwRTlmXHUwMEU5cmVuY2UgXHUwMEUwIGwnJ1x1MDBFOWxcdTAwRTltZW50IHJlZFx1MDBFOWZpbmksICcnezF9JycuIExlcyBlbmZhbnRzIDxjb21wbGV4VHlwZT4gZGVzIFx1MDBFOWxcdTAwRTltZW50cyA8cmVkZWZpbmU+IGRvaXZlbnQgY29tcG9ydGVyIGRlcyBkZXNjZW5kYW50cyA8ZXh0ZW5zaW9uPiBvdTxyZXN0cmljdGlvbj4sIGF2ZWMgZGVzIGF0dHJpYnV0cyAnJ2Jhc2UnJyBmYWlzYW50IHJcdTAwRTlmXHUwMEU5cmVuY2UgXHUwMEUwIGV1eC1tXHUwMEVBbWVzLgotICAgICAgICBzcmMtcmVkZWZpbmUuNi4xLjEgPSBzcmMtcmVkZWZpbmUuNi4xLjEgOiBTaSB1biBlbmZhbnQgZGUgZ3JvdXBlIGQnJ3VuIFx1MDBFOWxcdTAwRTltZW50IDxyZWRlZmluZT4gY29udGllbnQgdW4gZ3JvdXBlIGZhaXNhbnQgclx1MDBFOWZcdTAwRTlyZW5jZSBcdTAwRTAgbHVpLW1cdTAwRUFtZSwgaWwgbmUgZG9pdCBlbiBjb21wb3J0ZXIgcXUnJ3VuIHNldWwgOyBjZWx1aS1jaSBlbiBjb21wb3J0ZSAnJ3swfScnLgotICAgICAgICBzcmMtcmVkZWZpbmUuNi4xLjIgPSBzcmMtcmVkZWZpbmUuNi4xLjIgOiBMZSBncm91cGUgJyd7MH0nJyBxdWkgY29udGllbnQgdW5lIHJcdTAwRTlmXHUwMEU5cmVuY2UgXHUwMEUwIHVuIGdyb3VwZSBlbiBjb3VycyBkZSByZWRcdTAwRTlmaW5pdGlvbiBkb2l0IHJlc3BlY3RlciBsYSBjb25kaXRpb24gJydtaW5PY2N1cnMnJyA9ICcnbWF4T2NjdXJzJycgPSAxLgotICAgICAgICBzcmMtcmVkZWZpbmUuNi4yLjEgPSBzcmMtcmVkZWZpbmUuNi4yLjEgOiBBdWN1biBncm91cGUgZGFucyBsZSBzY2hcdTAwRTltYSByZWRcdTAwRTlmaW5pIG5lIGNvbXBvcnRlIHVuIG5vbSBjb25jb3JkYW50IGF2ZWMgJyd7MH0nJy4KLSAgICAgICAgc3JjLXJlZGVmaW5lLjYuMi4yID0gc3JjLXJlZGVmaW5lLjYuMi4yIDogTGUgZ3JvdXBlICcnezB9JycgbmUgcmVzdHJlaW50IHBhcyBjb3JyZWN0ZW1lbnQgbGUgZ3JvdXBlIHF1JydpbCByZWRcdTAwRTlmaW5pdCA7IGNvbnRyYWludGUgdmlvbFx1MDBFOWUgOiAnJ3sxfScnLgotICAgICAgICBzcmMtcmVkZWZpbmUuNy4xID0gc3JjLXJlZGVmaW5lLjcuMSA6IFNpIHVuIGVuZmFudCBhdHRyaWJ1dGVHcm91cCBkJyd1biBcdTAwRTlsXHUwMEU5bWVudCA8cmVkZWZpbmU+IGNvbnRpZW50IHVuIFx1MDBFOWxcdTAwRTltZW50IGF0dHJpYnV0ZUdyb3VwIGZhaXNhbnQgclx1MDBFOWZcdTAwRTlyZW5jZSBcdTAwRTAgbHVpLW1cdTAwRUFtZSwgaWwgbmUgZG9pdCBlbiBjb21wb3J0ZXIgcXUnJ3VuIHNldWwgOyBjZWx1aS1jaSBlbiBjb21wb3J0ZSB7MH0uCi0gICAgICAgIHNyYy1yZWRlZmluZS43LjIuMSA9IHNyYy1yZWRlZmluZS43LjIuMSA6IEF1Y3VuIFx1MDBFOWxcdTAwRTltZW50IGF0dHJpYnV0ZUdyb3VwIGRhbnMgbGUgc2NoXHUwMEU5bWEgcmVkXHUwMEU5ZmluaSBuZSBjb21wb3J0ZSB1biBub20gY29uY29yZGFudCBhdmVjICcnezB9JycuCi0gICAgICAgIHNyYy1yZWRlZmluZS43LjIuMiA9IHNyYy1yZWRlZmluZS43LjIuMiA6IEwnJ1x1MDBFOWxcdTAwRTltZW50IGF0dHJpYnV0ZUdyb3VwICcnezB9JycgbmUgcmVzdHJlaW50IHBhcyBjb3JyZWN0ZW1lbnQgbCcnXHUwMEU5bFx1MDBFOW1lbnQgYXR0cmlidXRlR3JvdXAgcXUnJ2lsIHJlZFx1MDBFOWZpbml0IDsgY29udHJhaW50ZSB2aW9sXHUwMEU5ZSA6ICcnezF9JycuCi0gICAgICAgIHNyYy1yZXNvbHZlID0gc3JjLXJlc29sdmUgOiBJbXBvc3NpYmxlIGRlIHJcdTAwRTlzb3VkcmUgbGUgbm9tICcnezB9JycgZW4gdW4gY29tcG9zYW50ICcnezF9JycuCi0gICAgICAgIHNyYy1yZXNvbHZlLjQuMSA9IHNyYy1yZXNvbHZlLjQuMSA6IEVycmV1ciBsb3JzIGRlIGxhIHJcdTAwRTlzb2x1dGlvbiBkdSBjb21wb3NhbnQgJyd7Mn0nJy4gJyd7Mn0nJyBuZSBjb21wb3J0ZSBwYXMgZCcnZXNwYWNlIGRlIG5vbXMsIG1haXMgbGVzIGNvbXBvc2FudHMgc2FucyBlc3BhY2UgZGUgbm9tcyBuZSBwZXV2ZW50IHBhcyBcdTAwRUF0cmUgclx1MDBFOWZcdTAwRTlyZW5jXHUwMEU5cyBcdTAwRTAgcGFydGlyIGR1IGRvY3VtZW50IGRlIHNjaFx1MDBFOW1hICcnezB9JycuIFNpICcnezJ9JycgZG9pdCBhdm9pciB1biBlc3BhY2UgZGUgbm9tcywgdW4gcHJcdTAwRTlmaXhlIGRvaXQgXHUwMEU5dmVudHVlbGxlbWVudCBcdTAwRUF0cmUgaW5kaXF1XHUwMEU5LiBTaSAnJ3syfScnIG5lIGRvaXQgcGFzIGF2b2lyIGQnJ2VzcGFjZSBkZSBub21zLCB1bmUgYmFsaXNlICcnaW1wb3J0Jycgc2FucyB1biBhdHRyaWJ1dCAibmFtZXNwYWNlIiBkb2l0IFx1MDBFQXRyZSBham91dFx1MDBFOWUgXHUwMEUwICcnezB9JycuCi0gICAgICAgIHNyYy1yZXNvbHZlLjQuMiA9IHNyYy1yZXNvbHZlLjQuMiA6IEVycmV1ciBsb3JzIGRlIGxhIHJcdTAwRTlzb2x1dGlvbiBkdSBjb21wb3NhbnQgJyd7Mn0nJy4gJyd7Mn0nJyBzZSB0cm91dmUgZGFucyBsJydlc3BhY2UgZGUgbm9tcyAnJ3sxfScnLCBtYWlzIGxlcyBjb21wb3NhbnRzIGRlIGNldCBlc3BhY2UgZGUgbm9tcyBuZSBwZXV2ZW50IHBhcyBcdTAwRUF0cmUgclx1MDBFOWZcdTAwRTlyZW5jXHUwMEU5cyBcdTAwRTAgcGFydGlyIGR1IGRvY3VtZW50IGRlIHNjaFx1MDBFOW1hICcnezB9JycuIFMnJ2lsIHMnJ2FnaXQgZCcndW4gZXNwYWNlIGRlIG5vbXMgaW5jb3JyZWN0LCBsZSBwclx1MDBFOWZpeGUgZGUgJyd7Mn0nJyBkb2l0IFx1MDBFOXZlbnR1ZWxsZW1lbnQgXHUwMEVBdHJlIG1vZGlmaVx1MDBFOS4gUycnaWwgZXN0IGNvcnJlY3QsIHVuZSBiYWxpc2UgJydpbXBvcnQnJyBhcHByb3ByaVx1MDBFOWUgZG9pdCBcdTAwRUF0cmUgYWpvdXRcdTAwRTllIFx1MDBFMCAnJ3swfScnLgotICAgICAgICBzcmMtc2ltcGxlLXR5cGUuMi5hID0gc3JjLXNpbXBsZS10eXBlLjIuYSA6IFVuIFx1MDBFOWxcdTAwRTltZW50IDxyZXN0cmljdGlvbj4gYSBcdTAwRTl0XHUwMEU5IHRyb3V2XHUwMEU5IGF2ZWMgdW5lIHZhbGV1ciBbYXR0cmlidXRlXSBkZSBiYXNlIGV0IHVuIFx1MDBFOWxcdTAwRTltZW50IDxzaW1wbGVUeXBlPiBwYXJtaSBzZXMgZW5mYW50cyAoW2NoaWxkcmVuXSkuIFVuIHNldWwgZGUgY2VzIFx1MDBFOWxcdTAwRTltZW50cyBlc3QgYXV0b3Jpc1x1MDBFOS4KLSAgICAgICAgc3JjLXNpbXBsZS10eXBlLjIuYiA9IHNyYy1zaW1wbGUtdHlwZS4yLmIgOiBVbiBcdTAwRTlsXHUwMEU5bWVudCA8cmVzdHJpY3Rpb24+IGEgXHUwMEU5dFx1MDBFOSB0cm91dlx1MDBFOSBzYW5zIHZhbGV1ciBbYXR0cmlidXRlXSBkZSBiYXNlIG5pIFx1MDBFOWxcdTAwRTltZW50IDxzaW1wbGVUeXBlPiBwYXJtaSBzZXMgZW5mYW50cyAoW2NoaWxkcmVuXSkuIFVuIGRlIGNlcyBcdTAwRTlsXHUwMEU5bWVudHMgZXN0IG9ibGlnYXRvaXJlLgotICAgICAgICBzcmMtc2ltcGxlLXR5cGUuMy5hID0gc3JjLXNpbXBsZS10eXBlLjMuYSA6IFVuIFx1MDBFOWxcdTAwRTltZW50IDxsaXN0PiBhIFx1MDBFOXRcdTAwRTkgdHJvdXZcdTAwRTkgYXZlYyB1bmUgdmFsZXVyIFthdHRyaWJ1dGVdIGl0ZW1UeXBlIG91IHVuIFx1MDBFOWxcdTAwRTltZW50IDxzaW1wbGVUeXBlPiBwYXJtaSBzZXMgZW5mYW50cyAoW2NoaWxkcmVuXSkuIFVuIHNldWwgZGUgY2VzIFx1MDBFOWxcdTAwRTltZW50cyBlc3QgYXV0b3Jpc1x1MDBFOS4KLSAgICAgICAgc3JjLXNpbXBsZS10eXBlLjMuYiA9IHNyYy1zaW1wbGUtdHlwZS4zLmIgOiBVbiBcdTAwRTlsXHUwMEU5bWVudCA8bGlzdD4gYSBcdTAwRTl0XHUwMEU5IHRyb3V2XHUwMEU5IHNhbnMgdmFsZXVyIFthdHRyaWJ1dGVdIGl0ZW1UeXBlIG5pIFx1MDBFOWxcdTAwRTltZW50IDxzaW1wbGVUeXBlPiBwYXJtaSBzZXMgZW5mYW50cyAoW2NoaWxkcmVuXSkuIFVuIGRlIGNlcyBcdTAwRTlsXHUwMEU5bWVudHMgZXN0IG9ibGlnYXRvaXJlLgotICAgICAgICBzcmMtc2luZ2xlLWZhY2V0LXZhbHVlID0gc3JjLXNpbmdsZS1mYWNldC12YWx1ZSA6IExlIGZhY2V0ICcnezB9JycgZXN0IGRcdTAwRTlmaW5pIHBsdXNpZXVycyBmb2lzLgotICAgICAgICBzcmMtdW5pb24tbWVtYmVyVHlwZXMtb3Itc2ltcGxlVHlwZXMgPSBzcmMtdW5pb24tbWVtYmVyVHlwZXMtb3Itc2ltcGxlVHlwZXMgOiBVbiBcdTAwRTlsXHUwMEU5bWVudCA8dW5pb24+IGRvaXQgYXZvaXIgdW5lIHZhbGV1ciBbYXR0cmlidXRlXSBtZW1iZXJUeXBlcyBub24gdmlkZSBvdSBhdSBtb2lucyB1biBcdTAwRTlsXHUwMEU5bWVudCA8c2ltcGxlVHlwZT4gcGFybWkgc2VzIGVuZmFudHMgKFtjaGlsZHJlbl0pLgotCi0jY29uc3RyYWludCB2YWxpZCAoMy5YLjYpCi0KLSAgICAgICAgYWctcHJvcHMtY29ycmVjdC4yID0gYWctcHJvcHMtY29ycmVjdC4yIDogRXJyZXVyIGRhbnMgbGUgZ3JvdXBlIGQnJ2F0dHJpYnV0cyAnJ3swfScnLiBEZXMgb2NjdXJyZW5jZXMgZCcnYXR0cmlidXRzIGVuIGRvdWJsZSBhdmVjIHVuIG5vbSBldCB1biBlc3BhY2UgZGUgbm9tcyBjaWJsZSBpZGVudGlxdWVzIHNvbnQgaW5kaXF1XHUwMEU5ZXMuIExlIG5vbSBkZSBsJydvY2N1cnJlbmNlIGQnJ2F0dHJpYnV0IGVuIGRvdWJsZSBlc3QgJyd7MX0nJy4KLSAgICAgICAgYWctcHJvcHMtY29ycmVjdC4zID0gYWctcHJvcHMtY29ycmVjdC4zIDogRXJyZXVyIGRhbnMgbGUgZ3JvdXBlIGQnJ2F0dHJpYnV0cyAnJ3swfScnLiBEZXV4IGRcdTAwRTljbGFyYXRpb25zIGQnJ2F0dHJpYnV0LCAnJ3sxfScnIGV0ICcnezJ9JycsIG9udCBkZXMgdHlwZXMgZFx1MDBFOXJpdlx1MDBFOXMgZGUgbCcnSUQuCi0gICAgICAgIGEtcHJvcHMtY29ycmVjdC4yID0gYS1wcm9wcy1jb3JyZWN0LjIgOiBWYWxldXIgZGUgY29udHJhaW50ZSBkZSB2YWxldXIgJyd7MX0nJyBub24gdmFsaWRlIGRhbnMgbCcnYXR0cmlidXQgJyd7MH0nJy4KLSAgICAgICAgYS1wcm9wcy1jb3JyZWN0LjMgPSBhLXByb3BzLWNvcnJlY3QuMyA6IEwnJ2F0dHJpYnV0ICcnezB9JycgbmUgcGV1dCBwYXMgdXRpbGlzZXIgJydmaXhlZCcnIG91ICcnZGVmYXVsdCcnLCBjYXIgc2EgdmFsZXVyICd7J3R5cGUgZGVmaW5pdGlvbid9JyBlc3QgaWRlbnRpcXVlIFx1MDBFMCBsJydJRCBvdSBlbiBlc3QgZFx1MDBFOXJpdlx1MDBFOWUuCi0gICAgICAgIGF1LXByb3BzLWNvcnJlY3QuMiA9IGF1LXByb3BzLWNvcnJlY3QuMiA6IERhbnMgbGEgZFx1MDBFOWNsYXJhdGlvbiBkJydhdHRyaWJ1dCBkZSAnJ3swfScnLCBsYSB2YWxldXIgZml4ZSAnJ3sxfScnIGEgXHUwMEU5dFx1MDBFOSBpbmRpcXVcdTAwRTllLiBQYXIgY29uc1x1MDBFOXF1ZW50LCBzaSBsJydvY2N1cnJlbmNlIGRlIGwnJ2F0dHJpYnV0IGZhaXNhbnQgclx1MDBFOWZcdTAwRTlyZW5jZSBcdTAwRTAgJyd7MH0nJyBjb21wb3J0ZSBcdTAwRTlnYWxlbWVudCAneyd2YWx1ZSBjb25zdHJhaW50J30nLCBjZWxsZS1jaSBkb2l0IFx1MDBFQXRyZSBmaXhlIGV0IHNhIHZhbGV1ciBkb2l0IFx1MDBFQXRyZSAnJ3sxfScnLgotICAgICAgICBjb3MtYWxsLWxpbWl0ZWQuMS4yID0gY29zLWFsbC1saW1pdGVkLjEuMiA6IFVuIGdyb3VwZSBkZSBtb2RcdTAwRThsZXMgJ2FsbCcgZG9pdCBmaWd1cmVyIGRhbnMgdW5lIHBhcnRpY3VsZSBvXHUwMEY5ICd7J21pbiBvY2N1cnMnfScgPSAneydtYXggb2NjdXJzJ30nID0gMS4gQ2V0dGUgcGFydGljdWxlIGRvaXQgZW4gb3V0cmUgZmFpcmUgcGFydGllIGQndW5lIHBhaXJlIGNvbnN0aXR1YW50IGxhIHZhbGV1ciAneydjb250ZW50IHR5cGUnfScgZCd1bmUgZFx1MDBFOWZpbml0aW9uIGRlIHR5cGUgY29tcGxleGUuCi0gICAgICAgIGNvcy1hbGwtbGltaXRlZC4yID0gY29zLWFsbC1saW1pdGVkLjIgOiBMYSB2YWxldXIgJ3snbWF4IG9jY3Vycyd9JyBkJyd1biBcdTAwRTlsXHUwMEU5bWVudCBkYW5zIHVuIGdyb3VwZSBkZSBtb2RcdTAwRThsZXMgJydhbGwnJyBkb2l0IFx1MDBFQXRyZSAwIG91IDEuIExhIHZhbGV1ciAnJ3swfScnIHBvdXIgbCcnXHUwMEU5bFx1MDBFOW1lbnQgJyd7MX0nJyBuJydlc3QgcGFzIHZhbGlkZS4KLSAgICAgICAgY29zLWFwcGxpY2FibGUtZmFjZXRzID0gY29zLWFwcGxpY2FibGUtZmFjZXRzIDogTGUgZmFjZXQgJyd7MH0nJyBuJydlc3QgcGFzIGF1dG9yaXNcdTAwRTkgcG91ciBsZSB0eXBlIHsxfS4KLSAgICAgICAgY29zLWN0LWV4dGVuZHMuMS4xID0gY29zLWN0LWV4dGVuZHMuMS4xIDogTGUgdHlwZSAnJ3swfScnIGVzdCBkXHUwMEU5cml2XHUwMEU5IHBhciBsJydleHRlbnNpb24gZHUgdHlwZSAnJ3sxfScnLiBUb3V0ZWZvaXMsIGwnJ2F0dHJpYnV0ICcnZmluYWwnJyBkZSAnJ3sxfScnIG4nJ2F1dG9yaXNlIHBhcyBsYSBkXHUwMEU5cml2YXRpb24gcGFyIGV4dGVuc2lvbi4KLSAgICAgICAgY29zLWN0LWV4dGVuZHMuMS40LjMuMi4yLjEuYSA9IGNvcy1jdC1leHRlbmRzLjEuNC4zLjIuMi4xLmEgOiBMZSB0eXBlIGRlIGNvbnRlbnUgZCcndW4gdHlwZSBkXHUwMEU5cml2XHUwMEU5IGV0IGNlbHVpIGRlIHNhIGJhc2UgZG9pdmVudCB0b3VzIGxlcyBkZXV4IFx1MDBFQXRyZSBtaXh0ZXMgKG1peGVkKSBvdSBcdTAwRTlsXHUwMEU5bWVudCB1bmlxdWVtZW50IChlbGVtZW50LW9ubHkpLiBMZSB0eXBlICcnezB9JycgZXN0IFx1MDBFOWxcdTAwRTltZW50IHVuaXF1ZW1lbnQsIG1haXMgbGUgdHlwZSBkZSBzYSBiYXNlIG5lIGwnJ2VzdCBwYXMuCi0gICAgICAgIGNvcy1jdC1leHRlbmRzLjEuNC4zLjIuMi4xLmIgPSBjb3MtY3QtZXh0ZW5kcy4xLjQuMy4yLjIuMS5iIDogTGUgdHlwZSBkZSBjb250ZW51IGQnJ3VuIHR5cGUgZFx1MDBFOXJpdlx1MDBFOSBldCBjZWx1aSBkZSBzYSBiYXNlIGRvaXZlbnQgdG91cyBsZXMgZGV1eCBcdTAwRUF0cmUgbWl4dGVzIChtaXhlZCkgb3UgXHUwMEU5bFx1MDBFOW1lbnQgdW5pcXVlbWVudCAoZWxlbWVudC1vbmx5KS4gTGUgdHlwZSAnJ3swfScnIGVzdCBtaXh0ZSwgbWFpcyBsZSB0eXBlIGRlIHNhIGJhc2UgbmUgbCcnZXN0IHBhcy4KLSAgICAgICAgY29zLWVsZW1lbnQtY29uc2lzdGVudCA9IGNvcy1lbGVtZW50LWNvbnNpc3RlbnQgOiBFcnJldXIgZGFucyBsZSB0eXBlICcnezB9JycuIFBsdXNpZXVycyBcdTAwRTlsXHUwMEU5bWVudHMgcG9ydGFudCBsZSBub20gJyd7MX0nJywgZGUgZGl2ZXJzIHR5cGVzLCBmaWd1cmVudCBkYW5zIGxlIGdyb3VwZSBkZSBtb2RcdTAwRThsZXMuCi0gICAgICAgIGNvcy1saXN0LW9mLWF0b21pYyA9IGNvcy1saXN0LW9mLWF0b21pYyA6IERhbnMgbGEgZFx1MDBFOWZpbml0aW9uIGR1IHR5cGUgZGUgbGlzdGUgJyd7MH0nJywgbGUgdHlwZSAnJ3sxfScnIGVzdCB1biB0eXBlIGQnJ1x1MDBFOWxcdTAwRTltZW50IGRlIGxpc3RlIG5vbiB2YWxpZGUgY2FyIGlsIG4nJ2VzdCBwYXMgYXRvbWlxdWUgKCcnezF9JycgZXN0IHVuIHR5cGUgZGUgbGlzdGUgb3UgdW4gdHlwZSBkJyd1bmlvbiBjb250ZW5hbnQgdW5lIGxpc3RlKS4KLSAgICAgICAgY29zLW5vbmFtYmlnID0gY29zLW5vbmFtYmlnIDogezB9IGV0IHsxfSAob3UgZGVzIFx1MDBFOWxcdTAwRTltZW50cyBkZSBsZXVyIGdyb3VwZSBkZSBzdWJzdGl0dXRpb24pIHZpb2xlbnQgbGEgclx1MDBFOGdsZSBkJydhdHRyaWJ1dGlvbiBkZSBwYXJ0aWN1bGUgdW5pcXVlIChVbmlxdWUgUGFydGljbGUgQXR0cmlidXRpb24pLiBBdSBjb3VycyBkZSBsYSB2YWxpZGF0aW9uIHBhciByYXBwb3J0IFx1MDBFMCBjZSBzY2hcdTAwRTltYSwgY2VzIGRldXggcGFydGljdWxlcyBwZXV2ZW50IGRldmVuaXIgYW1iaWd1XHUwMEVCcy4KLSAgICAgICAgY29zLXBhcnRpY2xlLXJlc3RyaWN0LmEgPSBjb3MtcGFydGljbGUtcmVzdHJpY3QuYSA6IExhIHBhcnRpY3VsZSBkXHUwMEU5cml2XHUwMEU5ZSBlc3QgdmlkZSBldCBsYSBiYXNlIG5lIHBldXQgcGFzIFx1MDBFQXRyZSB2aWRlLgotICAgICAgICBjb3MtcGFydGljbGUtcmVzdHJpY3QuYiA9IGNvcy1wYXJ0aWNsZS1yZXN0cmljdC5iIDogTGEgcGFydGljdWxlIGRlIGJhc2UgZXN0IHZpZGUsIG1haXMgbGEgcGFydGljdWxlIGRcdTAwRTlyaXZcdTAwRTllIG5lIGwnZXN0IHBhcy4KLSAgICAgICAgY29zLXBhcnRpY2xlLXJlc3RyaWN0LjIgPSBjb3MtcGFydGljbGUtcmVzdHJpY3QuMiA6IFJlc3RyaWN0aW9uIGRlIHBhcnRpY3VsZSBpbnRlcmRpdGUgOiAnJ3swfScnLgotICAgICAgICBjb3Mtc3QtcmVzdHJpY3RzLjEuMSA9IGNvcy1zdC1yZXN0cmljdHMuMS4xIDogTGUgdHlwZSAnJ3sxfScnIFx1MDBFOXRhbnQgbm9uIGRcdTAwRTljb21wb3NhYmxlLCBzYSB2YWxldXIgJ3snYmFzZSB0eXBlIGRlZmluaXRpb24nfScsICcnezB9JycsIGRvaXQgXHUwMEVBdHJlIHVuZSBkXHUwMEU5ZmluaXRpb24gZGUgdHlwZSBzaW1wbGUgYXRvbWlxdWUgb3UgdW4gdHlwZSBkZSBkb25uXHUwMEU5ZXMgcHJpbWl0aWYgaW50XHUwMEU5Z3JcdTAwRTkuCi0gICAgICAgIGNvcy1zdC1yZXN0cmljdHMuMi4xID0gY29zLXN0LXJlc3RyaWN0cy4yLjEgOiBEYW5zIGxhIGRcdTAwRTlmaW5pdGlvbiBkdSB0eXBlIGRlIGxpc3RlICcnezB9JycsIGxlIHR5cGUgJyd7MX0nJyBlc3QgdW4gdHlwZSBkJydcdTAwRTlsXHUwMEU5bWVudCBub24gdmFsaWRlIGNhciBpbCBzJydhZ2l0IGQnJ3VuIHR5cGUgZGUgbGlzdGUgb3UgdW4gdHlwZSBkJyd1bmlvbiBjb250ZW5hbnQgdW5lIGxpc3RlLgotICAgICAgICBjb3Mtc3QtcmVzdHJpY3RzLjIuMy4xLjEgPSBjb3Mtc3QtcmVzdHJpY3RzLjIuMy4xLjEgOiBMZSBjb21wb3NhbnQgJ3snZmluYWwnfScgZGUgbGEgdmFsZXVyICd7J2l0ZW0gdHlwZSBkZWZpbml0aW9uJ30nLCAnJ3swfScnLCBjb250aWVudCAnJ2xpc3QnJy4gQ2VsYSBzaWduaWZpZSBxdWUgbGEgdmFsZXVyICcnezB9JycgbmUgcGV1dCBwYXMgXHUwMEVBdHJlIHV0aWxpc1x1MDBFOWUgZW4gdGFudCBxdWUgdHlwZSBkJydcdTAwRTlsXHUwMEU5bWVudCBwb3VyIGxlIHR5cGUgZGUgbGlzdGUgJyd7MX0nJy4KLSAgICAgICAgY29zLXN0LXJlc3RyaWN0cy4zLjMuMS4xID0gY29zLXN0LXJlc3RyaWN0cy4zLjMuMS4xIDogTGUgY29tcG9zYW50ICd7J2ZpbmFsJ30nIGRlIGxhIHZhbGV1ciAneydtZW1iZXIgdHlwZSBkZWZpbml0aW9ucyd9JywgJyd7MH0nJywgY29udGllbnQgJyd1bmlvbicnLiBDZWxhIHNpZ25pZmllIHF1ZSBsYSB2YWxldXIgJyd7MH0nJyBuZSBwZXV0IHBhcyBcdTAwRUF0cmUgdXRpbGlzXHUwMEU5ZSBlbiB0YW50IHF1ZSB0eXBlIGRlIG1lbWJyZSBwb3VyIGxlIHR5cGUgZCcndW5pb24gJyd7MX0nJy4KLSAgICAgICAgY29zLXZhbGlkLWRlZmF1bHQuMi4xID0gY29zLXZhbGlkLWRlZmF1bHQuMi4xIDogTCcnXHUwMEU5bFx1MDBFOW1lbnQgJyd7MH0nJyBjb21wb3J0ZSB1bmUgY29udHJhaW50ZSBkZSB2YWxldXIgZXQgZG9pdCBkaXNwb3NlciBkJyd1biBtb2RcdTAwRThsZSBkZSBjb250ZW51IG1peHRlIG91IHNpbXBsZS4KLSAgICAgICAgY29zLXZhbGlkLWRlZmF1bHQuMi4yLjIgPSBjb3MtdmFsaWQtZGVmYXVsdC4yLjIuMiA6IFB1aXNxdWUgbCcnXHUwMEU5bFx1MDBFOW1lbnQgJyd7MH0nJyBjb21wb3J0ZSB1bmUgdmFsZXVyICd7J3ZhbHVlIGNvbnN0cmFpbnQnfScgZXQgcXVlIHNhIGRcdTAwRTlmaW5pdGlvbiBkZSB0eXBlIGEgbGEgdmFsZXVyICd7J2NvbnRlbnQgdHlwZSd9JyBtaXh0ZSwgbGEgcGFydGljdWxlIGRlICd7J2NvbnRlbnQgdHlwZSd9JyBkb2l0IHBvdXZvaXIgXHUwMEVBdHJlIHZpZGUuCi0gICAgICAgIGMtcHJvcHMtY29ycmVjdC4yID0gYy1wcm9wcy1jb3JyZWN0LjIgOiBMYSBjYXJkaW5hbGl0XHUwMEU5IGRlcyBjaGFtcHMgcG91ciBsZXMgdmFsZXVycyBrZXlyZWYgJyd7MH0nJyBldCBrZXkgJyd7MX0nJyBkb2l0IGNvbmNvcmRlci4KLSAgICAgICAgY3QtcHJvcHMtY29ycmVjdC4zID0gY3QtcHJvcHMtY29ycmVjdC4zIDogRFx1MDBFOWZpbml0aW9ucyBjaXJjdWxhaXJlcyBkXHUwMEU5dGVjdFx1MDBFOWVzIHBvdXIgbGUgdHlwZSBjb21wbGV4ZSAnJ3swfScnLiBDZWxhIHNpZ25pZmllIHF1ZSAnJ3swfScnIGVzdCBjb250ZW51IGRhbnMgc2EgcHJvcHJlIGhpXHUwMEU5cmFyY2hpZSBkZXMgdHlwZXMsIGNlIHF1aSBlc3QgdW5lIGVycmV1ci4KLSAgICAgICAgY3QtcHJvcHMtY29ycmVjdC40ID0gY3QtcHJvcHMtY29ycmVjdC40IDogRXJyZXVyIGRhbnMgbGUgdHlwZSAnJ3swfScnLiBEZXMgb2NjdXJyZW5jZXMgZCcnYXR0cmlidXRzIGVuIGRvdWJsZSBhdmVjIHVuIG5vbSBldCB1biBlc3BhY2UgZGUgbm9tcyBjaWJsZSBpZGVudGlxdWVzIHNvbnQgaW5kaXF1XHUwMEU5ZXMuIExlIG5vbSBkZSBsJydvY2N1cnJlbmNlIGQnJ2F0dHJpYnV0IGVuIGRvdWJsZSBlc3QgJyd7MX0nJy4KLSAgICAgICAgY3QtcHJvcHMtY29ycmVjdC41ID0gY3QtcHJvcHMtY29ycmVjdC41IDogRXJyZXVyIGRhbnMgbGUgdHlwZSAnJ3swfScnLiBEZXV4IGRcdTAwRTljbGFyYXRpb25zIGQnJ2F0dHJpYnV0LCAnJ3sxfScnIGV0ICcnezJ9JycsIG9udCBkZXMgdHlwZXMgZFx1MDBFOXJpdlx1MDBFOXMgZGUgbCcnSUQuCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMSA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMSA6IExlIHR5cGUgJyd7MH0nJyBhIFx1MDBFOXRcdTAwRTkgZFx1MDBFOXJpdlx1MDBFOSBwYXIgcmVzdHJpY3Rpb24gZHUgdHlwZSAnJ3sxfScnLiBDZXBlbmRhbnQsICcnezF9JycgY29tcG9ydGUgdW5lIHByb3ByaVx1MDBFOXRcdTAwRTkgJ3snZmluYWwnfScgaW50ZXJkaXNhbnQgbGEgZFx1MDBFOXJpdmF0aW9uIHBhciByZXN0cmljdGlvbi4KLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4yLjEuMSA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMi4xLjEgOiBFcnJldXIgZGFucyBsZSB0eXBlICcnezB9JycuIEwnJ29jY3VycmVuY2UgZCcnYXR0cmlidXQgJyd7MX0nJyBkYW5zIGNlIHR5cGUgY29tcG9ydGUgdW5lIHZhbGV1ciAnJ3VzZScnIGRlICcnezJ9JycsIGNlIHF1aSBlc3QgaW5jb2hcdTAwRTlyZW50IGF2ZWMgbGEgdmFsZXVyICcncmVxdWlyZWQnJyBkYW5zIHVuZSBvY2N1cnJlbmNlIGQnJ2F0dHJpYnV0IGNvcnJlc3BvbmRhbnRlIGRhbnMgbGUgdHlwZSBkZSBiYXNlLgotICAgICAgICBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjIuMS4yID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4yLjEuMiA6IEVycmV1ciBkYW5zIGxlIHR5cGUgJyd7MH0nJy4gTCcnb2NjdXJyZW5jZSBkJydhdHRyaWJ1dCAnJ3sxfScnIGRhbnMgY2UgdHlwZSBjb21wb3J0ZSBsZSB0eXBlICcnezJ9JycsIGRvbnQgbGEgZFx1MDBFOXJpdmF0aW9uIFx1MDBFMCBwYXJ0aXIgZGUgJyd7M30nJywgbGUgdHlwZSBkZSBsJydvY2N1cnJlbmNlIGQnJ2F0dHJpYnV0IGNvcnJlc3BvbmRhbnRlIGRhbnMgbGUgdHlwZSBkZSBiYXNlLCBuJydlc3QgcGFzIHZhbGlkZS4KLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4yLjEuMy5hID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4yLjEuMy5hIDogRXJyZXVyIGRhbnMgbGUgdHlwZSAnJ3swfScnLiBMJydvY2N1cnJlbmNlIGQnJ2F0dHJpYnV0ICcnezF9JycgZGFucyBjZSB0eXBlIGNvbXBvcnRlIHVuZSBjb250cmFpbnRlIGRlIHZhbGV1ciBlZmZlY3RpdmUgcXVpIG4nJ2VzdCBwYXMgZml4ZSwgZXQgbGEgY29udHJhaW50ZSBkZSB2YWxldXIgZWZmZWN0aXZlIGRlIGwnJ29jY3VycmVuY2UgZCcnYXR0cmlidXQgY29ycmVzcG9uZGFudGUgZGFucyBsZSB0eXBlIGRlIGJhc2UgZXN0IGZpeGUuCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMi4xLjMuYiA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMi4xLjMuYiA6IEVycmV1ciBkYW5zIGxlIHR5cGUgJyd7MH0nJy4gTCcnb2NjdXJyZW5jZSBkJydhdHRyaWJ1dCAnJ3sxfScnIGRhbnMgY2UgdHlwZSBjb21wb3J0ZSB1bmUgY29udHJhaW50ZSBkZSB2YWxldXIgZWZmZWN0aXZlIGZpeGUgYXlhbnQgdW5lIHZhbGV1ciBkZSAnJ3syfScnLCBjZSBxdWkgbicnZXN0IHBhcyBjb2hcdTAwRTlyZW50IGF2ZWMgbGEgdmFsZXVyIGRlICcnezN9JycgcG91ciBsYSBjb250cmFpbnRlIGRlIHZhbGV1ciBlZmZlY3RpdmUgZml4ZSBkZSBsJydvY2N1cnJlbmNlIGQnJ2F0dHJpYnV0IGNvcnJlc3BvbmRhbnRlIGRhbnMgbGUgdHlwZSBkZSBiYXNlLgotICAgICAgICBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjIuMi5hID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4yLjIuYSA6IEVycmV1ciBkYW5zIGxlIHR5cGUgJyd7MH0nJy4gTCcnb2NjdXJyZW5jZSBkJydhdHRyaWJ1dCAnJ3sxfScnIGRhbnMgY2UgdHlwZSBuZSBjb21wb3J0ZSBwYXMgZCcnb2NjdXJyZW5jZSBkJydhdHRyaWJ1dCBjb3JyZXNwb25kYW50ZSBkYW5zIGxhIGJhc2UsIGV0IGxlIHR5cGUgZGUgYmFzZSBuZSBwb3NzXHUwMEU4ZGUgcGFzIGQnJ2F0dHJpYnV0IGRlIGNhcmFjdFx1MDBFOHJlIGdcdTAwRTluXHUwMEU5cmlxdWUuCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMi4yLmIgPSBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjIuMi5iIDogRXJyZXVyIGRhbnMgbGUgdHlwZSAnJ3swfScnLiBMJydvY2N1cnJlbmNlIGQnJ2F0dHJpYnV0ICcnezF9JycgZGFucyBjZSB0eXBlIG5lIGNvbXBvcnRlIHBhcyBkJydvY2N1cnJlbmNlIGQnJ2F0dHJpYnV0IGNvcnJlc3BvbmRhbnRlIGRhbnMgbGEgYmFzZSwgZXQgbGUgY2FyYWN0XHUwMEU4cmUgZ1x1MDBFOW5cdTAwRTlyaXF1ZSBkYW5zIGxlIHR5cGUgZGUgYmFzZSBuJydhY2NlcHRlIHBhcyBsJydlc3BhY2UgZGUgbm9tcyAnJ3syfScnIGRlIGNldHRlIG9jY3VycmVuY2UgZCcnYXR0cmlidXQuCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMyA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMyA6IEVycmV1ciBkYW5zIGxlIHR5cGUgJyd7MH0nJy4gTGUgcGFyYW1cdTAwRTh0cmUgUkVRVUlSRUQgZGUgbCcnb2NjdXJyZW5jZSBkJydhdHRyaWJ1dCAnJ3sxfScnIGR1IHR5cGUgZGUgYmFzZSBhIGxhIHZhbGV1ciBUcnVlLCBtYWlzIGlsIG4nJ2V4aXN0ZSBhdWN1bmUgb2NjdXJyZW5jZSBkJydhdHRyaWJ1dCBjb3JyZXNwb25kYW50ZSBkYW5zIGxlIHR5cGUgZFx1MDBFOXJpdlx1MDBFOS4KLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi40LjEgPSBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjQuMSA6IEVycmV1ciBkYW5zIGxlIHR5cGUgJyd7MH0nJy4gTGEgZFx1MDBFOXJpdmF0aW9uIGNvbXBvcnRlIHVuIGNhcmFjdFx1MDBFOHJlIGdcdTAwRTluXHUwMEU5cmlxdWUgZCcnYXR0cmlidXQgbWFpcyBsZSB0eXBlIGRlIGJhc2UgbicnZW4gYSBwYXMuCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uNC4yID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi40LjIgOiBFcnJldXIgZGFucyBsZSB0eXBlICcnezB9JycuIExlIGNhcmFjdFx1MDBFOHJlIGdcdTAwRTluXHUwMEU5cmlxdWUgZGUgbGEgZFx1MDBFOXJpdmF0aW9uIG4nJ2VzdCBwYXMgdW4gc291cy1lbnNlbWJsZSBkZSBjYXJhY3RcdTAwRThyZXMgZ1x1MDBFOW5cdTAwRTlyaXF1ZXMgdmFsaWRlIGRlIGNlbHVpIGR1IHR5cGUgZGUgYmFzZS4KLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi40LjMgPSBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjQuMyA6IEVycmV1ciBkYW5zIGxlIHR5cGUgJyd7MH0nJy4gTGUgY29udGVudSBkZSBwcm9jZXNzdXMgZHUgY2FyYWN0XHUwMEU4cmUgZ1x1MDBFOW5cdTAwRTlyaXF1ZSBkZSBsYSBkXHUwMEU5cml2YXRpb24gKHsxfSkgZXN0IHBsdXMgZmFpYmxlIHF1ZSBjZWx1aSBkdSB0eXBlIGRlIGJhc2UgKHsyfSkuCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uNS4yLjIuMSA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uNS4yLjIuMSA6IEVycmV1ciBkYW5zIGxlIHR5cGUgJyd7MH0nJy4gTGUgdHlwZSBkZSBjb250ZW51IHNpbXBsZSBkZSBjZSB0eXBlLCAnJ3sxfScnLCBuJydlc3QgcGFzIHVuZSByZXN0cmljdGlvbiB2YWxpZGUgZHUgdHlwZSBkZSBjb250ZW51IHNpbXBsZSBkdSB0eXBlIGRlIGJhc2UsICcnezJ9JycuCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uNS4zLjIgPSBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjUuMy4yIDogRXJyZXVyIGRhbnMgbGUgdHlwZSAnJ3swfScnLiBMZSB0eXBlIGRlIGNvbnRlbnUgZGUgY2UgdHlwZSBlc3QgdmlkZSwgbWFpcyBsZSB0eXBlIGRlIGNvbnRlbnUgZHUgdHlwZSBkZSBiYXNlLCAnJ3sxfScnLCBuJydlc3QgcGFzIHZpZGUgb3UgbmUgcGV1dCBwYXMgXHUwMEVBdHJlIHZpZGUuCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uNS40LjEuMiA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uNS40LjEuMiA6IEVycmV1ciBkYW5zIGxlIHR5cGUgJyd7MH0nJy4gTGUgdHlwZSBkZSBjb250ZW51IGRlIGNlIHR5cGUgZXN0IG1peHRlLCBtYWlzIGxlIHR5cGUgZGUgY29udGVudSBkdSB0eXBlIGRlIGJhc2UsICcnezF9JycsIG5lIGwnJ2VzdCBwYXMuCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uNS40LjIgPSBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjUuNC4yIDogRXJyZXVyIGRhbnMgbGUgdHlwZSAnJ3swfScnLiBMYSBwYXJ0aWN1bGUgZHUgdHlwZSBuJydlc3QgcGFzIHVuZSByZXN0cmljdGlvbiB2YWxpZGUgZGUgbGEgcGFydGljdWxlIGR1IHR5cGUgZGUgYmFzZS4KLSAgICAgICAgZW51bWVyYXRpb24tcmVxdWlyZWQtbm90YXRpb24gPSBlbnVtZXJhdGlvbi1yZXF1aXJlZC1ub3RhdGlvbiA6IExlIHR5cGUgTk9UQVRJT04sICcnezB9JycgdXRpbGlzXHUwMEU5IHBhciB7Mn0gJyd7MX0nJywgZG9pdCBjb21wb3J0ZXIgdW5lIHZhbGV1ciBkZSBmYWNldCBkJydcdTAwRTludW1cdTAwRTlyYXRpb24gaW5kaXF1YW50IGxlcyBcdTAwRTlsXHUwMEU5bWVudHMgZGUgbm90YXRpb24gdXRpbGlzXHUwMEU5cyBwYXIgY2UgdHlwZS4KLSAgICAgICAgZW51bWVyYXRpb24tdmFsaWQtcmVzdHJpY3Rpb24gPSBlbnVtZXJhdGlvbi12YWxpZC1yZXN0cmljdGlvbiA6IExhIHZhbGV1ciBkJydcdTAwRTludW1cdTAwRTlyYXRpb24gJyd7MH0nJyBuJydlc3QgcGFzIGNvbXByaXNlIGwnJ2VzcGFjZSBkZSB2YWxldXJzIGR1IHR5cGUgZGUgYmFzZSwgezF9LgotICAgICAgICBlLXByb3BzLWNvcnJlY3QuMiA9IGUtcHJvcHMtY29ycmVjdC4yIDogVmFsZXVyIGRlIGNvbnRyYWludGUgZGUgdmFsZXVyICcnezF9Jycgbm9uIHZhbGlkZSBkYW5zIGwnJ1x1MDBFOWxcdTAwRTltZW50ICcnezB9JycuCi0gICAgICAgIGUtcHJvcHMtY29ycmVjdC40ID0gZS1wcm9wcy1jb3JyZWN0LjQgOiBMYSB2YWxldXIgJ3sndHlwZSBkZWZpbml0aW9uJ30nIGRlIGwnJ1x1MDBFOWxcdTAwRTltZW50ICcnezB9JycgbicnZXN0IHBhcyBkXHUwMEU5cml2XHUwMEU5ZSBkZSBmYVx1MDBFN29uIHZhbGlkZSBcdTAwRTAgcGFydGlyIGRlIGxhIHZhbGV1ciAneyd0eXBlIGRlZmluaXRpb24nfScgZGUgbCcnXHUwMEU5bFx1MDBFOW1lbnQgc3Vic3RpdHV0aW9uSGVhZCAnJ3sxfScnLCBvdSBsYSBwcm9wcmlcdTAwRTl0XHUwMEU5ICd7J3N1YnN0aXR1dGlvbiBncm91cCBleGNsdXNpb25zJ30nIGRlICcnezF9JycgbicnYWNjZXB0ZSBwYXMgY2V0dGUgZFx1MDBFOXJpdmF0aW9uLgotICAgICAgICBlLXByb3BzLWNvcnJlY3QuNSA9IGUtcHJvcHMtY29ycmVjdC41IDogVW5lIHZhbGV1ciAneyd2YWx1ZSBjb25zdHJhaW50J30nIG5lIGRvaXQgcGFzIGZpZ3VyZXIgZGFucyBsJydcdTAwRTlsXHUwMEU5bWVudCAnJ3swfScnLCBjYXIgc2EgdmFsZXVyICd7J3R5cGUgZGVmaW5pdGlvbid9JyBvdSBsZSAneydjb250ZW50IHR5cGUnfScgZGUgc2EgdmFsZXVyICd7J3R5cGUgZGVmaW5pdGlvbid9JyBlc3QgaWRlbnRpcXVlIFx1MDBFMCBsJydJRCBvdSBlbiBlc3QgZFx1MDBFOXJpdlx1MDBFOS4KLSAgICAgICAgZS1wcm9wcy1jb3JyZWN0LjYgPSBlLXByb3BzLWNvcnJlY3QuNiA6IEdyb3VwZSBkZSBzdWJzdGl0dXRpb24gY2lyY3VsYWlyZSBkXHUwMEU5dGVjdFx1MDBFOSBwb3VyIFx1MDBFOWxcdTAwRTltZW50ICcnezB9JycuCi0gICAgICAgIGZyYWN0aW9uRGlnaXRzLXZhbGlkLXJlc3RyaWN0aW9uID0gZnJhY3Rpb25EaWdpdHMtdmFsaWQtcmVzdHJpY3Rpb24gOiBEYW5zIGxhIGRcdTAwRTlmaW5pdGlvbiBkZSB7Mn0sIGxhIHZhbGV1ciAnJ3swfScnIHBvdXIgbGUgZmFjZXQgJydmcmFjdGlvbkRpZ2l0cycnIG4nJ2VzdCBwYXMgdmFsaWRlIGNhciBlbGxlIGRvaXQgXHUwMEVBdHJlIDw9IFx1MDBFMCBsYSB2YWxldXIgZGUgJydmcmFjdGlvbkRpZ2l0cycnLCBxdWkgYSBcdTAwRTl0XHUwMEU5IGRcdTAwRTlmaW5pZSBzdXIgJyd7MX0nJyBkYW5zIGwnJ3VuIGRlcyB0eXBlcyBkJydhbmNcdTAwRUF0cmUuCi0gICAgICAgIGZyYWN0aW9uRGlnaXRzLXRvdGFsRGlnaXRzID0gZnJhY3Rpb25EaWdpdHMtdG90YWxEaWdpdHMgOiBEYW5zIGxhIGRcdTAwRTlmaW5pdGlvbiBkZSB7Mn0sIGxhIHZhbGV1ciAnJ3swfScnIHBvdXIgbGUgZmFjZXQgJydmcmFjdGlvbkRpZ2l0cycnIG4nJ2VzdCBwYXMgdmFsaWRlIGNhciBlbGxlIGRvaXQgXHUwMEVBdHJlIDw9IFx1MDBFMCBsYSB2YWxldXIgZGUgJyd0b3RhbERpZ2l0cycnLCBkXHUwMEU5ZmluaWUgc3VyICcnezF9JycuCi0gICAgICAgIGxlbmd0aC1taW5MZW5ndGgtbWF4TGVuZ3RoLjEuMSA9IGxlbmd0aC1taW5MZW5ndGgtbWF4TGVuZ3RoLjEuMSA6IFBvdXIgbGUgdHlwZSB7MH0sIHNpIGxhIHZhbGV1ciBkZSBsb25ndWV1ciAnJ3sxfScnIGVzdCBpbmZcdTAwRTlyaWV1cmUgXHUwMEUwIGxhIHZhbGV1ciBkZSBtaW5MZW5ndGggJyd7Mn0nJywgdW5lIGVycmV1ciBlc3QgZ1x1MDBFOW5cdTAwRTlyXHUwMEU5ZS4KLSAgICAgICAgbGVuZ3RoLW1pbkxlbmd0aC1tYXhMZW5ndGguMS4yLmEgPSBsZW5ndGgtbWluTGVuZ3RoLW1heExlbmd0aC4xLjIuYSA6IFBvdXIgbGUgdHlwZSB7MH0sIHVuZSBlcnJldXIgZXN0IGdcdTAwRTluXHUwMEU5clx1MDBFOWUgc2kgbGUgdHlwZSBkZSBiYXNlIG5lIGNvbXBvcnRlIHBhcyB1biBmYWNldCBtaW5MZW5ndGggbG9yc3F1ZSBsYSByZXN0cmljdGlvbiBlbiBjb3VycyBjb21wb3J0ZSBsZSBmYWNldCBtaW5MZW5ndGgsIGV0IHF1ZSBsYSByZXN0cmljdGlvbiBvdSBsZSB0eXBlIGRlIGJhc2UgZW4gY291cnMgY29tcG9ydGUgbGUgZmFjZXQgZGUgbG9uZ3VldXIuCi0gICAgICAgIGxlbmd0aC1taW5MZW5ndGgtbWF4TGVuZ3RoLjEuMi5iID0gbGVuZ3RoLW1pbkxlbmd0aC1tYXhMZW5ndGguMS4yLmIgOiBQb3VyIGxlIHR5cGUgezB9LCBzaSBsYSB2YWxldXIgZGUgbWluTGVuZ3RoIGVuIGNvdXJzICcnezF9JycgbicnZXN0IHBhcyBcdTAwRTlnYWxlIFx1MDBFMCBsYSB2YWxldXIgZGUgbWluTGVuZ3RoIGRlIGJhc2UgJyd7Mn0nJywgdW5lIGVycmV1ciBlc3QgZ1x1MDBFOW5cdTAwRTlyXHUwMEU5ZS4KLSAgICAgICAgbGVuZ3RoLW1pbkxlbmd0aC1tYXhMZW5ndGguMi4xID0gbGVuZ3RoLW1pbkxlbmd0aC1tYXhMZW5ndGguMi4xIDogUG91ciBsZSB0eXBlIHswfSwgc2kgbGEgdmFsZXVyIGRlIGxvbmd1ZXVyICcnezF9JycgZXN0IHN1cFx1MDBFOXJpZXVyZSBcdTAwRTAgbGEgdmFsZXVyIGRlIG1heExlbmd0aCAnJ3syfScnLCB1bmUgZXJyZXVyIGVzdCBnXHUwMEU5blx1MDBFOXJcdTAwRTllLgotICAgICAgICBsZW5ndGgtbWluTGVuZ3RoLW1heExlbmd0aC4yLjIuYSA9IGxlbmd0aC1taW5MZW5ndGgtbWF4TGVuZ3RoLjIuMi5hIDogUG91ciBsZSB0eXBlIHswfSwgdW5lIGVycmV1ciBlc3QgZ1x1MDBFOW5cdTAwRTlyXHUwMEU5ZSBzaSBsZSB0eXBlIGRlIGJhc2UgbmUgY29tcG9ydGUgcGFzIHVuIGZhY2V0IG1heExlbmd0aCBsb3JzcXVlIGxhIHJlc3RyaWN0aW9uIGVuIGNvdXJzIGNvbXBvcnRlIGxlIGZhY2V0IG1heExlbmd0aCwgZXQgcXVlIGxhIHJlc3RyaWN0aW9uIG91IGxlIHR5cGUgZGUgYmFzZSBlbiBjb3VycyBjb21wb3J0ZSBsZSBmYWNldCBkZSBsb25ndWV1ci4KLSAgICAgICAgbGVuZ3RoLW1pbkxlbmd0aC1tYXhMZW5ndGguMi4yLmIgPSBsZW5ndGgtbWluTGVuZ3RoLW1heExlbmd0aC4yLjIuYiA6IFBvdXIgbGUgdHlwZSB7MH0sIHNpIGxhIHZhbGV1ciBtYXhMZW5ndGggZW4gY291cnMgJyd7MX0nJyBuJydlc3QgcGFzIFx1MDBFOWdhbGUgXHUwMEUwIGxhIHZhbGV1ciBtYXhMZW5ndGggZGUgYmFzZSAnJ3syfScnLCB1bmUgZXJyZXVyIGVzdCBnXHUwMEU5blx1MDBFOXJcdTAwRTllLgotICAgICAgICBsZW5ndGgtdmFsaWQtcmVzdHJpY3Rpb24gPSBsZW5ndGgtdmFsaWQtcmVzdHJpY3Rpb24gOiBFcnJldXIgZGFucyBsZSB0eXBlICcnezJ9JycuIExhIHZhbGV1ciBkZSBsb25ndWV1ciAnJ3swfScnIGRvaXQgXHUwMEVBdHJlIFx1MDBFOWdhbGUgXHUwMEUwIGxhIGNlbGxlIGR1IHR5cGUgZGUgYmFzZSAnJ3sxfScnLgotICAgICAgICBtYXhFeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMSA9IG1heEV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4xIDogRXJyZXVyIGRhbnMgbGUgdHlwZSAnJ3syfScnLiBMYSB2YWxldXIgbWF4RXhjbHVzaXZlICcnezB9JycgZG9pdCBcdTAwRUF0cmUgPD0gXHUwMEUwIGxhIHZhbGV1ciBtYXhFeGNsdXNpdmUgZHUgdHlwZSBkZSBiYXNlICcnezF9JycuCi0gICAgICAgIG1heEV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4yID0gbWF4RXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjIgOiBFcnJldXIgZGFucyBsZSB0eXBlICcnezJ9JycuIExhIHZhbGV1ciBtYXhFeGNsdXNpdmUgJyd7MH0nJyBkb2l0IFx1MDBFQXRyZSA8PSBcdTAwRTAgbGEgdmFsZXVyIG1heEluY2x1c2l2ZSBkdSB0eXBlIGRlIGJhc2UgJyd7MX0nJy4KLSAgICAgICAgbWF4RXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjMgPSBtYXhFeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMyA6IEVycmV1ciBkYW5zIGxlIHR5cGUgJyd7Mn0nJy4gTGEgdmFsZXVyIG1heEV4Y2x1c2l2ZSAnJ3swfScnIGRvaXQgXHUwMEVBdHJlID4gXHUwMEUwIGxhIHZhbGV1ciBtaW5JbmNsdXNpdmUgZHUgdHlwZSBkZSBiYXNlICcnezF9JycuCi0gICAgICAgIG1heEV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi40ID0gbWF4RXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjQgOiBFcnJldXIgZGFucyBsZSB0eXBlICcnezJ9JycuIExhIHZhbGV1ciBtYXhFeGNsdXNpdmUgJyd7MH0nJyBkb2l0IFx1MDBFQXRyZSA+IFx1MDBFMCBsYSB2YWxldXIgbWluRXhjbHVzaXZlIGR1IHR5cGUgZGUgYmFzZSAnJ3sxfScnLgotICAgICAgICBtYXhJbmNsdXNpdmUtbWF4RXhjbHVzaXZlID0gbWF4SW5jbHVzaXZlLW1heEV4Y2x1c2l2ZSA6IFZvdXMgbmUgcG91dmV6IHBhcyBpbmRpcXVlciBcdTAwRTAgbGEgZm9pcyBtYXhJbmNsdXNpdmUgZXQgbWF4RXhjbHVzaXZlIHBvdXIgbGUgbVx1MDBFQW1lIHR5cGUgZGUgZG9ublx1MDBFOWVzLiBEYW5zIHsyfSwgbWF4SW5jbHVzaXZlID0gJyd7MH0nJyBldCBtYXhFeGNsdXNpdmUgPSAnJ3sxfScnLgotICAgICAgICBtYXhJbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMSA9IG1heEluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4xIDogRXJyZXVyIGRhbnMgbGUgdHlwZSAnJ3syfScnLiBMYSB2YWxldXIgbWF4SW5jbHVzaXZlICcnezB9JycgZG9pdCBcdTAwRUF0cmUgPD0gXHUwMEUwIGxhIHZhbGV1ciBtYXhJbmNsdXNpdmUgZHUgdHlwZSBkZSBiYXNlICcnezF9JycuCi0gICAgICAgIG1heEluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4yID0gbWF4SW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjIgOiBFcnJldXIgZGFucyBsZSB0eXBlICcnezJ9JycuIExhIHZhbGV1ciBtYXhJbmNsdXNpdmUgJyd7MH0nJyBkb2l0IFx1MDBFQXRyZSA8IFx1MDBFMCBsYSB2YWxldXIgbWF4RXhjbHVzaXZlIGR1IHR5cGUgZGUgYmFzZSAnJ3sxfScnLgotICAgICAgICBtYXhJbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMyA9IG1heEluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4zIDogRXJyZXVyIGRhbnMgbGUgdHlwZSAnJ3syfScnLiBMYSB2YWxldXIgbWF4SW5jbHVzaXZlICcnezB9JycgZG9pdCBcdTAwRUF0cmUgPj0gXHUwMEUwIGxhIHZhbGV1ciBtaW5JbmNsdXNpdmUgZHUgdHlwZSBkZSBiYXNlICcnezF9JycuCi0gICAgICAgIG1heEluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi40ID0gbWF4SW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjQgOiBFcnJldXIgZGFucyBsZSB0eXBlICcnezJ9JycuIExhIHZhbGV1ciBtYXhJbmNsdXNpdmUgJyd7MH0nJyBkb2l0IFx1MDBFQXRyZSA+IFx1MDBFMCBsYSB2YWxldXIgbWluRXhjbHVzaXZlIGR1IHR5cGUgZGUgYmFzZSAnJ3sxfScnLgotICAgICAgICBtYXhMZW5ndGgtdmFsaWQtcmVzdHJpY3Rpb24gPSBtYXhMZW5ndGgtdmFsaWQtcmVzdHJpY3Rpb24gOiBEYW5zIGxhIGRcdTAwRTlmaW5pdGlvbiBkZSB7Mn0sIGxhIHZhbGV1ciBtYXhMZW5ndGggJyd7MH0nJyBkb2l0IFx1MDBFQXRyZSA8PSBcdTAwRTAgY2VsbGUgZHUgdHlwZSBkZSBiYXNlICcnezF9JycuCi0gICAgICAgIG1nLXByb3BzLWNvcnJlY3QuMiA9IG1nLXByb3BzLWNvcnJlY3QuMiA6IERcdTAwRTlmaW5pdGlvbnMgY2lyY3VsYWlyZXMgZFx1MDBFOXRlY3RcdTAwRTllcyBwb3VyIGxlIGdyb3VwZSAnJ3swfScnLiBMZSBzdWl2aSByXHUwMEU5Y3Vyc2lmIGRlcyB2YWxldXJzICd7J3Rlcm0nfScgZGVzIHBhcnRpY3VsZXMgY29uZHVpdCBcdTAwRTAgdW5lIHBhcnRpY3VsZSBvXHUwMEY5ICd7J3Rlcm0nfScgZXN0IGxlIGdyb3VwZSBwcm9wcmVtZW50IGRpdC4KLSAgICAgICAgbWluRXhjbHVzaXZlLWxlc3MtdGhhbi1lcXVhbC10by1tYXhFeGNsdXNpdmUgPSBtaW5FeGNsdXNpdmUtbGVzcy10aGFuLWVxdWFsLXRvLW1heEV4Y2x1c2l2ZSA6IERhbnMgbGEgZFx1MDBFOWZpbml0aW9uIGRlIHsyfSwgbGEgdmFsZXVyIG1pbkV4Y2x1c2l2ZSAnJ3swfScnIGRvaXQgXHUwMEVBdHJlIDw9IFx1MDBFMCBsYSB2YWxldXIgbWF4RXhjbHVzaXZlICcnezF9JycuCi0gICAgICAgIG1pbkV4Y2x1c2l2ZS1sZXNzLXRoYW4tbWF4SW5jbHVzaXZlID0gbWluRXhjbHVzaXZlLWxlc3MtdGhhbi1tYXhJbmNsdXNpdmUgOiBEYW5zIGxhIGRcdTAwRTlmaW5pdGlvbiBkZSB7Mn0sIGxhIHZhbGV1ciBtaW5FeGNsdXNpdmUgJyd7MH0nJyBkb2l0IFx1MDBFQXRyZSA8IFx1MDBFMCBsYSB2YWxldXIgbWF4SW5jbHVzaXZlICcnezF9JycuCi0gICAgICAgIG1pbkV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4xID0gbWluRXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjEgOiBFcnJldXIgZGFucyBsZSB0eXBlICcnezJ9JycuIExhIHZhbGV1ciBtaW5FeGNsdXNpdmUgJyd7MH0nJyBkb2l0IFx1MDBFQXRyZSA+PSBcdTAwRTAgbGEgdmFsZXVyIG1pbkV4Y2x1c2l2ZSBkdSB0eXBlIGRlIGJhc2UgJyd7MX0nJy4KLSAgICAgICAgbWluRXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjIgPSBtaW5FeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMiA6IEVycmV1ciBkYW5zIGxlIHR5cGUgJyd7Mn0nJy4gTGEgdmFsZXVyIG1pbkV4Y2x1c2l2ZSAnJ3swfScnIGRvaXQgXHUwMEVBdHJlIDw9IFx1MDBFMCBsYSB2YWxldXIgbWF4SW5jbHVzaXZlIGR1IHR5cGUgZGUgYmFzZSAnJ3sxfScnLgotICAgICAgICBtaW5FeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMyA9IG1pbkV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4zIDogRXJyZXVyIGRhbnMgbGUgdHlwZSAnJ3syfScnLiBMYSB2YWxldXIgbWluRXhjbHVzaXZlICcnezB9JycgZG9pdCBcdTAwRUF0cmUgPj0gXHUwMEUwIGxhIHZhbGV1ciBtaW5JbmNsdXNpdmUgZHUgdHlwZSBkZSBiYXNlICcnezF9JycuCi0gICAgICAgIG1pbkV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi40ID0gbWluRXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjQgOiBFcnJldXIgZGFucyBsZSB0eXBlICcnezJ9JycuIExhIHZhbGV1ciBtaW5FeGNsdXNpdmUgJyd7MH0nJyBkb2l0IFx1MDBFQXRyZSA8IFx1MDBFMCBsYSB2YWxldXIgbWF4RXhjbHVzaXZlIGR1IHR5cGUgZGUgYmFzZSAnJ3sxfScnLgotICAgICAgICBtaW5JbmNsdXNpdmUtbGVzcy10aGFuLWVxdWFsLXRvLW1heEluY2x1c2l2ZSA9IG1pbkluY2x1c2l2ZS1sZXNzLXRoYW4tZXF1YWwtdG8tbWF4SW5jbHVzaXZlIDogRGFucyBsYSBkXHUwMEU5ZmluaXRpb24gZGUgezJ9LCBsYSB2YWxldXIgbWluSW5jbHVzaXZlICcnezB9JycgZG9pdCBcdTAwRUF0cmUgPD0gXHUwMEUwIGxhIHZhbGV1ciBtYXhJbmNsdXNpdmUgJyd7MX0nJy4KLSAgICAgICAgbWluSW5jbHVzaXZlLWxlc3MtdGhhbi1tYXhFeGNsdXNpdmUgPSBtaW5JbmNsdXNpdmUtbGVzcy10aGFuLW1heEV4Y2x1c2l2ZSA6IERhbnMgbGEgZFx1MDBFOWZpbml0aW9uIGRlIHsyfSwgbGEgdmFsZXVyIG1pbkluY2x1c2l2ZSAnJ3swfScnIGRvaXQgXHUwMEVBdHJlIDwgXHUwMEUwIGxhIHZhbGV1ciBtYXhFeGNsdXNpdmUgJyd7MX0nJy4KLSAgICAgICAgbWluSW5jbHVzaXZlLW1pbkV4Y2x1c2l2ZSA9IG1pbkluY2x1c2l2ZS1taW5FeGNsdXNpdmUgOiBWb3VzIG5lIHBvdXZleiBwYXMgaW5kaXF1ZXIgXHUwMEUwIGxhIGZvaXMgbWluSW5jbHVzaXZlIGV0IG1pbkV4Y2x1c2l2ZSBwb3VyIGxlIG1cdTAwRUFtZSB0eXBlIGRlIGRvbm5cdTAwRTllcy4gRGFucyB7Mn0sIG1pbkluY2x1c2l2ZSA9ICcnezB9JycgZXQgbWluRXhjbHVzaXZlID0gJyd7MX0nJy4KLSAgICAgICAgbWluSW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjEgPSBtaW5JbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMSA6IEVycmV1ciBkYW5zIGxlIHR5cGUgJyd7Mn0nJy4gTGEgdmFsZXVyIG1pbkluY2x1c2l2ZSAnJ3swfScnIGRvaXQgXHUwMEVBdHJlID49IFx1MDBFMCBsYSB2YWxldXIgbWluSW5jbHVzaXZlIGR1IHR5cGUgZGUgYmFzZSAnJ3sxfScnLgotICAgICAgICBtaW5JbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMiA9IG1pbkluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4yIDogRXJyZXVyIGRhbnMgbGUgdHlwZSAnJ3syfScnLiBMYSB2YWxldXIgbWluSW5jbHVzaXZlICcnezB9JycgZG9pdCBcdTAwRUF0cmUgPD0gXHUwMEUwIGxhIHZhbGV1ciBtYXhJbmNsdXNpdmUgZHUgdHlwZSBkZSBiYXNlICcnezF9JycuCi0gICAgICAgIG1pbkluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4zID0gbWluSW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjMgOiBFcnJldXIgZGFucyBsZSB0eXBlICcnezJ9JycuIExhIHZhbGV1ciBtaW5JbmNsdXNpdmUgJyd7MH0nJyBkb2l0IFx1MDBFQXRyZSA+IFx1MDBFMCBsYSB2YWxldXIgbWluRXhjbHVzaXZlIGR1IHR5cGUgZGUgYmFzZSAnJ3sxfScnLgotICAgICAgICBtaW5JbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uNCA9IG1pbkluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi40IDogRXJyZXVyIGRhbnMgbGUgdHlwZSAnJ3syfScnLiBMYSB2YWxldXIgbWluSW5jbHVzaXZlICcnezB9JycgZG9pdCBcdTAwRUF0cmUgPCBcdTAwRTAgbGEgdmFsZXVyIG1heEV4Y2x1c2l2ZSBkdSB0eXBlIGRlIGJhc2UgJyd7MX0nJy4KLSAgICAgICAgbWluTGVuZ3RoLWxlc3MtdGhhbi1lcXVhbC10by1tYXhMZW5ndGggPSBtaW5MZW5ndGgtbGVzcy10aGFuLWVxdWFsLXRvLW1heExlbmd0aDogRGFucyBsYSBkXHUwMEU5ZmluaXRpb24gZGUgezJ9LCBsYSB2YWxldXIgZGUgbWluTGVuZ3RoICcnezB9JycgZG9pdCBcdTAwRUF0cmUgPCBcdTAwRTAgbGEgdmFsZXVyIGRlIG1heExlbmd0aCAnJ3sxfScnLgotICAgICAgICBtaW5MZW5ndGgtdmFsaWQtcmVzdHJpY3Rpb24gPSBtaW5MZW5ndGgtdmFsaWQtcmVzdHJpY3Rpb24gOiBEYW5zIGxhIGRcdTAwRTlmaW5pdGlvbiBkZSB7Mn0sIGxhIHZhbGV1ciBkZSBtaW5MZW5ndGggJyd7MH0nJyBkb2l0IFx1MDBFQXRyZSA+PSBcdTAwRTAgY2VsbGUgZHUgdHlwZSBkZSBiYXNlLCAnJ3sxfScnLgotICAgICAgICBuby14bWxucyA9IG5vLXhtbG5zIDogTGEgdmFsZXVyIHtuYW1lfSBkJ3VuZSBkXHUwMEU5Y2xhcmF0aW9uIGQnYXR0cmlidXQgbmUgZG9pdCBwYXMgXHUwMEVBdHJlIGlkZW50aXF1ZSBcdTAwRTAgJ3htbG5zJy4KLSAgICAgICAgbm8teHNpID0gbm8teHNpIDogTGEgdmFsZXVyICd7J3RhcmdldCBuYW1lc3BhY2UnfScgZCcndW5lIGRcdTAwRTljbGFyYXRpb24gZCcnYXR0cmlidXQgbmUgZG9pdCBwYXMgXHUwMEVBdHJlIGlkZW50aXF1ZSBcdTAwRTAgJyd7MH0nJy4KLSAgICAgICAgcC1wcm9wcy1jb3JyZWN0LjIuMSA9IHAtcHJvcHMtY29ycmVjdC4yLjEgOiBEYW5zIGxhIGRcdTAwRTljbGFyYXRpb24gZGUgJyd7MH0nJywgbGEgdmFsZXVyIGRlICcnbWluT2NjdXJzJycgZXN0ICcnezF9JycsIG1haXMgZWxsZSBuZSBkb2l0IHBhcyBcdTAwRUF0cmUgc3VwXHUwMEU5cmlldXJlIFx1MDBFMCBsYSB2YWxldXIgZGUgJydtYXhPY2N1cnMnJywgcXVpIGVzdCAnJ3syfScnLgotICAgICAgICByY2FzZS1NYXBBbmRTdW0uMSA9IHJjYXNlLU1hcEFuZFN1bS4xIDogQXVjdW5lIG1pc2UgZW4gY29ycmVzcG9uZGFuY2UgZm9uY3Rpb25uZWxsZSBjb21wbFx1MDBFOHRlIGVudHJlIGxlcyBwYXJ0aWN1bGVzLgotICAgICAgICByY2FzZS1NYXBBbmRTdW0uMiA9IHJjYXNlLU1hcEFuZFN1bS4yIDogTGEgcGxhZ2UgZCcnb2NjdXJyZW5jZXMgZHUgZ3JvdXBlLCAoezB9LHsxfSksIG4nJ2VzdCBwYXMgdW5lIHJlc3RyaWN0aW9uIHZhbGlkZSBkZSBsYSBwbGFnZSBkJydvY2N1cnJlbmNlcyBkdSBncm91cGUgZGUgYmFzZSwgKHsyfSx7M30pLgotICAgICAgICByY2FzZS1OYW1lQW5kVHlwZU9LLjEgPSByY2FzZS1OYW1lQW5kVHlwZU9LLjEgOiBMZXMgXHUwMEU5bFx1MDBFOW1lbnRzIG9udCBkZXMgbm9tcyAobmFtZSkgZXQgZGVzIGVzcGFjZXMgZGUgbm9tcyBjaWJsZSAodGFyZ2V0IG5hbWVzcGFjZSkgZGlmZlx1MDBFOXJlbnRzIDogXHUwMEU5bFx1MDBFOW1lbnQgInswfSIgZGFucyBsJydlc3BhY2UgZGUgbm9tcyAiezF9IiBldCBcdTAwRTlsXHUwMEU5bWVudCAnJ3syfScnIGRhbnMgbCcnZXNwYWNlIGRlIG5vbXMgJyd7M30nJy4KLSAgICAgICAgcmNhc2UtTmFtZUFuZFR5cGVPSy4yID0gcmNhc2UtTmFtZUFuZFR5cGVPSy4yIDogRXJyZXVyIGRhbnMgbGEgcGFydGljdWxlIG9cdTAwRjkgbGEgdmFsZXVyICd7J3Rlcm0nfScgZXN0IGxhIGRcdTAwRTljbGFyYXRpb24gZCcnXHUwMEU5bFx1MDBFOW1lbnQgJyd7MH0nJy4gTGEgdmFsZXVyICd7J25pbGxhYmxlJ30nIGRlIGxhIGRcdTAwRTljbGFyYXRpb24gZCcnXHUwMEU5bFx1MDBFOW1lbnQgZXN0IFRydWUsIG1haXMgbGEgcGFydGljdWxlIGNvcnJlc3BvbmRhbnRlIGRhbnMgbGUgdHlwZSBkZSBiYXNlIGNvbXBvcnRlIHVuZSBkXHUwMEU5Y2xhcmF0aW9uIGQnJ1x1MDBFOWxcdTAwRTltZW50IG9cdTAwRjkgbGEgdmFsZXVyICd7J25pbGxhYmxlJ30nIGVzdCBGYWxzZS4KLSAgICAgICAgcmNhc2UtTmFtZUFuZFR5cGVPSy4zID0gcmNhc2UtTmFtZUFuZFR5cGVPSy4zIDogRXJyZXVyIGRhbnMgbGEgcGFydGljdWxlIG9cdTAwRjkgbGEgdmFsZXVyICd7J3Rlcm0nfScgZXN0IGxhIGRcdTAwRTljbGFyYXRpb24gZCcnXHUwMEU5bFx1MDBFOW1lbnQgJyd7MH0nJy4gU2EgcGxhZ2UgZCcnb2NjdXJyZW5jZXMsICh7MX0sezJ9KSwgbicnZXN0IHBhcyB1bmUgcmVzdHJpY3Rpb24gdmFsaWRlIGRlIGxhIHBsYWdlICh7M30sezR9KSBkZSBsYSBwYXJ0aWN1bGUgY29ycmVzcG9uZGFudGUgZGFucyBsZSB0eXBlIGRlIGJhc2UuCi0gICAgICAgIHJjYXNlLU5hbWVBbmRUeXBlT0suNC5hID0gcmNhc2UtTmFtZUFuZFR5cGVPSy40LmEgOiBMJydcdTAwRTlsXHUwMEU5bWVudCAnJ3swfScnIG4nJ2VzdCBwYXMgZml4ZSwgbWFpcyBsJydcdTAwRTlsXHUwMEU5bWVudCBjb3JyZXNwb25kYW50IGRhbnMgbGUgdHlwZSBkZSBiYXNlIGVzdCBmaXhlIGF2ZWMgbGEgdmFsZXVyICcnezF9JycuCi0gICAgICAgIHJjYXNlLU5hbWVBbmRUeXBlT0suNC5iID0gcmNhc2UtTmFtZUFuZFR5cGVPSy40LmIgOiBMJydcdTAwRTlsXHUwMEU5bWVudCAnJ3swfScnIGVzdCBmaXhlIGF2ZWMgbGEgdmFsZXVyICcnezF9JycsIG1haXMgbCcnXHUwMEU5bFx1MDBFOW1lbnQgY29ycmVzcG9uZGFudCBkYW5zIGxlIHR5cGUgZGUgYmFzZSBlc3QgZml4ZSBhdmVjIGxhIHZhbGV1ciAnJ3syfScnLgotICAgICAgICByY2FzZS1OYW1lQW5kVHlwZU9LLjUgPSByY2FzZS1OYW1lQW5kVHlwZU9LLjUgOiBMZXMgY29udHJhaW50ZXMgZCcnaWRlbnRpdFx1MDBFOSBkZSBsJydcdTAwRTlsXHUwMEU5bWVudCAiezB9IiBuZSBzb250IHBhcyB1biBzb3VzLWVuc2VtYmxlIGRlIGNlbGxlcyBkZSBsYSBiYXNlLgotICAgICAgICByY2FzZS1OYW1lQW5kVHlwZU9LLjYgPSByY2FzZS1OYW1lQW5kVHlwZU9LLjYgOiBMZXMgc3Vic3RpdHV0aW9ucyBub24gYXV0b3Jpc1x1MDBFOWVzIHBvdXIgbCcnXHUwMEU5bFx1MDBFOW1lbnQgJyd7MH0nJyBuZSBzb250IHBhcyB1biBzdXItZW5zZW1ibGUgZGUgY2VsbGVzIGRlIGxhIGJhc2UuCi0gICAgICAgIHJjYXNlLU5hbWVBbmRUeXBlT0suNyA9IHJjYXNlLU5hbWVBbmRUeXBlT0suNyA6IExlIHR5cGUgZGUgbCcnXHUwMEU5bFx1MDBFOW1lbnQgJyd7MH0nJywgJyd7MX0nJywgbicnZXN0IHBhcyBkXHUwMEU5cml2XHUwMEU5IGR1IHR5cGUgZGUgbCcnXHUwMEU5bFx1MDBFOW1lbnQgZGUgYmFzZSwgJyd7Mn0nJy4KLSAgICAgICAgcmNhc2UtTlNDb21wYXQuMSA9IHJjYXNlLU5TQ29tcGF0LjEgOiBMJydcdTAwRTlsXHUwMEU5bWVudCAnJ3swfScnIGNvbXBvcnRlIHVuIGVzcGFjZSBkZSBub21zICcnezF9Jycgbm9uIGF1dG9yaXNcdTAwRTkgcGFyIGxlIGNhcmFjdFx1MDBFOHJlIGdcdTAwRTluXHUwMEU5cmlxdWUgZGUgbGEgYmFzZS4KLSAgICAgICAgcmNhc2UtTlNDb21wYXQuMiA9IHJjYXNlLU5TQ29tcGF0LjIgOiBFcnJldXIgZGFucyBsYSBwYXJ0aWN1bGUgb1x1MDBGOSBsYSB2YWxldXIgJ3sndGVybSd9JyBlc3QgbGEgZFx1MDBFOWNsYXJhdGlvbiBkJydcdTAwRTlsXHUwMEU5bWVudCAnJ3swfScnLiBTYSBwbGFnZSBkJydvY2N1cnJlbmNlcywgKHsxfSx7Mn0pLCBuJydlc3QgcGFzIHVuZSByZXN0cmljdGlvbiB2YWxpZGUgZGUgbGEgcGxhZ2UgKHszfSx7NH0pIGRlIGxhIHBhcnRpY3VsZSBjb3JyZXNwb25kYW50ZSBkYW5zIGxlIHR5cGUgZGUgYmFzZS4KLSAgICAgICAgcmNhc2UtTlNSZWN1cnNlQ2hlY2tDYXJkaW5hbGl0eS4xID0gcmNhc2UtTlNSZWN1cnNlQ2hlY2tDYXJkaW5hbGl0eS4xIDogQXVjdW5lIG1pc2UgZW4gY29ycmVzcG9uZGFuY2UgZm9uY3Rpb25uZWxsZSBjb21wbFx1MDBFOHRlIGVudHJlIGxlcyBwYXJ0aWN1bGVzLgotICAgICAgICByY2FzZS1OU1JlY3Vyc2VDaGVja0NhcmRpbmFsaXR5LjIgPSByY2FzZS1OU1JlY3Vyc2VDaGVja0NhcmRpbmFsaXR5LjIgOiBMYSBwbGFnZSBkJydvY2N1cnJlbmNlcyBkdSBncm91cGUsICh7MH0sezF9KSwgbicnZXN0IHBhcyB1bmUgcmVzdHJpY3Rpb24gdmFsaWRlIGRlIGxhIHBsYWdlIFx1MDBFMCBjYXJhY3RcdTAwRThyZSBnXHUwMEU5blx1MDBFOXJpcXVlIGRlIGxhIGJhc2UsICh7Mn0sezN9KS4KLSAgICAgICAgcmNhc2UtTlNTdWJzZXQuMSA9IHJjYXNlLU5TU3Vic2V0LjEgOiBMZSBjYXJhY3RcdTAwRThyZSBnXHUwMEU5blx1MDBFOXJpcXVlIG4nZXN0IHBhcyB1biBzb3VzLWVuc2VtYmxlIGR1IGNhcmFjdFx1MDBFOHJlIGdcdTAwRTluXHUwMEU5cmlxdWUgY29ycmVzcG9uZGFudCBkYW5zIGxhIGJhc2UuCi0gICAgICAgIHJjYXNlLU5TU3Vic2V0LjIgPSByY2FzZS1OU1N1YnNldC4yIDogTGEgcGxhZ2UgZCcnb2NjdXJyZW5jZXMgZHUgY2FyYWN0XHUwMEU4cmUgZ1x1MDBFOW5cdTAwRTlyaXF1ZSwgKHswfSx7MX0pLCBuJydlc3QgcGFzIHVuZSByZXN0cmljdGlvbiB2YWxpZGUgZGUgY2VsbGUgZGUgbGEgYmFzZSwgKHsyfSx7M30pLgotICAgICAgICByY2FzZS1OU1N1YnNldC4zID0gcmNhc2UtTlNTdWJzZXQuMyA6IExlIGNvbnRlbnUgZGUgcHJvY2Vzc3VzIGRlIGNhcmFjdFx1MDBFOHJlIGdcdTAwRTluXHUwMEU5cmlxdWUsICcnezB9JycsIGVzdCBwbHVzIGZhaWJsZSBxdWUgY2VsdWkgZmlndXJhbnQgZGFucyBsYSBiYXNlLCAnJ3sxfScnLgotICAgICAgICByY2FzZS1SZWN1cnNlLjEgPSByY2FzZS1SZWN1cnNlLjEgOiBMYSBwbGFnZSBkJydvY2N1cnJlbmNlcyBkdSBncm91cGUsICh7MH0sezF9KSwgbicnZXN0IHBhcyB1bmUgcmVzdHJpY3Rpb24gdmFsaWRlIGRlIGxhIHBsYWdlIGQnJ29jY3VycmVuY2VzIGR1IGdyb3VwZSBkZSBiYXNlLCAoezJ9LHszfSkuCi0gICAgICAgIHJjYXNlLVJlY3Vyc2UuMiA9IHJjYXNlLVJlY3Vyc2UuMiA6IEF1Y3VuZSBtaXNlIGVuIGNvcnJlc3BvbmRhbmNlIGZvbmN0aW9ubmVsbGUgY29tcGxcdTAwRTh0ZSBlbnRyZSBsZXMgcGFydGljdWxlcy4KLSAgICAgICAgcmNhc2UtUmVjdXJzZUxheC4xID0gcmNhc2UtUmVjdXJzZUxheC4xIDogTGEgcGxhZ2UgZCcnb2NjdXJyZW5jZXMgZHUgZ3JvdXBlLCAoezB9LHsxfSksIG4nJ2VzdCBwYXMgdW5lIHJlc3RyaWN0aW9uIHZhbGlkZSBkZSBsYSBwbGFnZSBkJydvY2N1cnJlbmNlcyBkdSBncm91cGUgZGUgYmFzZSwgKHsyfSx7M30pLgotICAgICAgICByY2FzZS1SZWN1cnNlTGF4LjIgPSByY2FzZS1SZWN1cnNlTGF4LjIgOiBBdWN1bmUgbWlzZSBlbiBjb3JyZXNwb25kYW5jZSBmb25jdGlvbm5lbGxlIGNvbXBsXHUwMEU4dGUgZW50cmUgbGVzIHBhcnRpY3VsZXMuCi0gICAgICAgIHJjYXNlLVJlY3Vyc2VVbm9yZGVyZWQuMSA9IHJjYXNlLVJlY3Vyc2VVbm9yZGVyZWQuMSA6IExhIHBsYWdlIGQnJ29jY3VycmVuY2VzIGR1IGdyb3VwZSwgKHswfSx7MX0pLCBuJydlc3QgcGFzIHVuZSByZXN0cmljdGlvbiB2YWxpZGUgZGUgbGEgcGxhZ2UgZCcnb2NjdXJyZW5jZXMgZHUgZ3JvdXBlIGRlIGJhc2UsICh7Mn0sezN9KS4KLSAgICAgICAgcmNhc2UtUmVjdXJzZVVub3JkZXJlZC4yID0gcmNhc2UtUmVjdXJzZVVub3JkZXJlZC4yIDogQXVjdW5lIG1pc2UgZW4gY29ycmVzcG9uZGFuY2UgZm9uY3Rpb25uZWxsZSBjb21wbFx1MDBFOHRlIGVudHJlIGxlcyBwYXJ0aWN1bGVzLgotIyAgICAgICAgV2UncmUgdXNpbmcgc2NoLXByb3BzLWNvcnJlY3QuMiBpbnN0ZWFkIG9mIHRoZSBvbGQgc3JjLXJlZGVmaW5lLjEKLSMgICAgICAgIHNyYy1yZWRlZmluZS4xID0gc3JjLXJlZGVmaW5lLjE6IFRoZSBjb21wb25lbnQgJyd7MH0nJyBpcyBiZWdpbiByZWRlZmluZWQsIGJ1dCBpdHMgY29ycmVzcG9uZGluZyBjb21wb25lbnQgaXNuJ3QgaW4gdGhlIHNjaGVtYSBkb2N1bWVudCBiZWluZyByZWRlZmluZWQgKHdpdGggbmFtZXNwYWNlICcnezJ9JycpLCBidXQgaW4gYSBkaWZmZXJlbnQgZG9jdW1lbnQsIHdpdGggbmFtZXNwYWNlICcnezF9JycuCi0gICAgICAgIHNjaC1wcm9wcy1jb3JyZWN0LjIgPSBzY2gtcHJvcHMtY29ycmVjdC4yIDogVW4gc2NoXHUwMEU5bWEgbmUgcGV1dCBwYXMgY29udGVuaXIgZGV1eCBjb21wb3NhbnRzIGdsb2JhdXggZGUgbVx1MDBFQW1lIG5vbSA7IGNlbHVpLWNpIGNvbnRpZW50IGRldXggb2NjdXJyZW5jZXMgZGUgJyd7MH0nJy4KLSAgICAgICAgc3QtcHJvcHMtY29ycmVjdC4yID0gc3QtcHJvcHMtY29ycmVjdC4yIDogRFx1MDBFOWZpbml0aW9ucyBjaXJjdWxhaXJlcyBkXHUwMEU5dGVjdFx1MDBFOWVzIHBvdXIgbGUgdHlwZSBzaW1wbGUgJyd7MH0nJy4gQ2VsYSBzaWduaWZpZSBxdWUgJyd7MH0nJyBlc3QgY29udGVudSBkYW5zIHNhIHByb3ByZSBoaVx1MDBFOXJhcmNoaWUgZGVzIHR5cGVzLCBjZSBxdWkgZXN0IHVuZSBlcnJldXIuCi0gICAgICAgIHN0LXByb3BzLWNvcnJlY3QuMyA9IHN0LXByb3BzLWNvcnJlY3QuMyA6IEVycmV1ciBkYW5zIGxlIHR5cGUgJyd7MH0nJy4gTGEgdmFsZXVyICd7J2ZpbmFsJ30nIGRlICd7J2Jhc2UgdHlwZSBkZWZpbml0aW9uJ30nLCAnJ3sxfScnLCBuJydhY2NlcHRlIHBhcyBsYSBkXHUwMEU5cml2YXRpb24gcGFyIHJlc3RyaWN0aW9uLgotICAgICAgICB0b3RhbERpZ2l0cy12YWxpZC1yZXN0cmljdGlvbiA9IHRvdGFsRGlnaXRzLXZhbGlkLXJlc3RyaWN0aW9uIDogRGFucyBsYSBkXHUwMEU5ZmluaXRpb24gZGUgezJ9LCBsYSB2YWxldXIgJyd7MH0nJyBwb3VyIGxlIGZhY2V0ICcndG90YWxEaWdpdHMnJyBuJydlc3QgcGFzIHZhbGlkZSBjYXIgZWxsZSBkb2l0IFx1MDBFQXRyZSA8PSBcdTAwRTAgbGEgdmFsZXVyIGRlICcndG90YWxEaWdpdHMnJywgcXVpIGEgXHUwMEU5dFx1MDBFOSBkXHUwMEU5ZmluaWUgc3VyICcnezF9JycgZGFucyBsJyd1biBkZXMgdHlwZXMgZCcnYW5jXHUwMEVBdHJlLgotICAgICAgICB3aGl0ZVNwYWNlLXZhbGlkLXJlc3RyaWN0aW9uLjEgPSB3aGl0ZVNwYWNlLXZhbGlkLXJlc3RyaWN0aW9uLjEgOiBEYW5zIGxhIGRcdTAwRTlmaW5pdGlvbiBkZSB7MH0sIGxhIHZhbGV1ciAnJ3sxfScnIGR1IGZhY2V0ICcnd2hpdGVzcGFjZScnIG4nJ2VzdCBwYXMgdmFsaWRlIGNhciBlbGxlIGEgXHUwMEU5dFx1MDBFOSBkXHUwMEU5ZmluaWUgc3VyICcnY29sbGFwc2UnJyBkYW5zIGwnJ3VuIGRlcyB0eXBlcyBkJydhbmNcdTAwRUF0cmUuCi0gICAgICAgIHdoaXRlU3BhY2UtdmFsaWQtcmVzdHJpY3Rpb24uMiA9IHdoaXRlU3BhY2UtdmFsaWQtcmVzdHJpY3Rpb24uMiA6IERhbnMgbGEgZFx1MDBFOWZpbml0aW9uIGRlIHswfSwgbGEgdmFsZXVyICcncHJlc2VydmUnJyBkdSBmYWNldCAnJ3doaXRlc3BhY2UnJyBuJydlc3QgcGFzIHZhbGlkZSBjYXIgbGEgdmFsZXVyIGRlICcnd2hpdGVzcGFjZScnIGEgXHUwMEU5dFx1MDBFOSBkXHUwMEU5ZmluaWUgc3VyICcncmVwbGFjZScnIGRhbnMgbCcndW4gZGVzIHR5cGVzIGQnJ2FuY1x1MDBFQXRyZS4KLQotI3NjaGVtYSBmb3IgU2NoZW1hcwotCi0gICAgICAgIHM0cy1hdHQtaW52YWxpZC12YWx1ZSA9IHM0cy1hdHQtaW52YWxpZC12YWx1ZSA6IFZhbGV1ciBkJydhdHRyaWJ1dCBub24gdmFsaWRlIHBvdXIgJyd7MX0nJyBkYW5zIGwnJ1x1MDBFOWxcdTAwRTltZW50ICcnezB9JycuIFJhaXNvbiBlbnJlZ2lzdHJcdTAwRTllIDogezJ9Ci0gICAgICAgIHM0cy1hdHQtbXVzdC1hcHBlYXIgPSBzNHMtYXR0LW11c3QtYXBwZWFyIDogTCcnYXR0cmlidXQgJyd7MX0nJyBkb2l0IGZpZ3VyZXIgZGFucyBsJydcdTAwRTlsXHUwMEU5bWVudCAnJ3swfScnLgotICAgICAgICBzNHMtYXR0LW5vdC1hbGxvd2VkID0gczRzLWF0dC1ub3QtYWxsb3dlZCA6IEwnJ2F0dHJpYnV0ICcnezF9JycgbmUgZG9pdCBwYXMgZmlndXJlciBkYW5zIGwnJ1x1MDBFOWxcdTAwRTltZW50ICcnezB9JycuCi0gICAgICAgIHM0cy1lbHQtaW52YWxpZCA9IHM0cy1lbHQtaW52YWxpZCA6IEwnJ1x1MDBFOWxcdTAwRTltZW50ICcnezB9JycgbicnZXN0IHBhcyB1biBcdTAwRTlsXHUwMEU5bWVudCB2YWxpZGUgZGFucyB1biBkb2N1bWVudCBkZSBzY2hcdTAwRTltYS4KLSAgICAgICAgczRzLWVsdC1tdXN0LW1hdGNoLjEgPSBzNHMtZWx0LW11c3QtbWF0Y2guMSA6IExlIGNvbnRlbnUgZGUgJyd7MH0nJyBkb2l0IGNvbmNvcmRlciBhdmVjIHsxfS4gUHJvYmxcdTAwRThtZSBkXHUwMEU5dGVjdFx1MDBFOSBcdTAwRTAgcGFydGlyIGRlIDogezJ9LgotICAgICAgICBzNHMtZWx0LW11c3QtbWF0Y2guMiA9IHM0cy1lbHQtbXVzdC1tYXRjaC4yIDogTGUgY29udGVudSBkZSAnJ3swfScnIGRvaXQgY29uY29yZGVyIGF2ZWMgezF9LiBOb21icmUgaW5zdWZmaXNhbnQgZCcnXHUwMEU5bFx1MDBFOW1lbnRzIHRyb3V2XHUwMEU5cy4KLSAgICAgICAgIyB0aGUgImludmFsaWQtY29udGVudCIgbWVzc2FnZXMgcHJvdmlkZSBsZXNzIGluZm9ybWF0aW9uIHRoYW4gdGhlICJtdXN0LW1hdGNoIiBjb3VudGVycGFydHMgYWJvdmUuIFRoZXkncmUgdXNlZCBmb3IgY29tcGxleCB0eXBlcyB3aGVuIHByb3ZpZGluZyBhICJtYXRjaCIgd291bGQgYmUgYW4gaW5mb3JtYXRpb24gZHVtcAotICAgICAgICBzNHMtZWx0LWludmFsaWQtY29udGVudC4xID0gczRzLWVsdC1pbnZhbGlkLWNvbnRlbnQuMSA6IExlIGNvbnRlbnUgZGUgJyd7MH0nJyBuJydlc3QgcGFzIHZhbGlkZS4gTCcnXHUwMEU5bFx1MDBFOW1lbnQgJyd7MX0nJyBuJydlc3QgcGFzIHZhbGlkZSwgZXN0IG1hbCBwbGFjXHUwMEU5IG91IGNvbXB0ZSB0cm9wIGQnJ29jY3VycmVuY2VzLgotICAgICAgICBzNHMtZWx0LWludmFsaWQtY29udGVudC4yID0gczRzLWVsdC1pbnZhbGlkLWNvbnRlbnQuMiA6IExlIGNvbnRlbnUgZGUgJyd7MH0nJyBuJydlc3QgcGFzIHZhbGlkZS4gTCcnXHUwMEU5bFx1MDBFOW1lbnQgJyd7MX0nJyBuZSBwZXV0IHBhcyBcdTAwRUF0cmUgdmlkZS4KLSAgICAgICAgczRzLWVsdC1pbnZhbGlkLWNvbnRlbnQuMyA9IHM0cy1lbHQtaW52YWxpZC1jb250ZW50LjMgOiBMZXMgXHUwMEU5bFx1MDBFOW1lbnRzIGRlIHR5cGUgJyd7MH0nJyBuZSBwZXV2ZW50IHBhcyBhcHBhcmFcdTAwRUV0cmUgYXByXHUwMEU4cyBsZXMgZFx1MDBFOWNsYXJhdGlvbnMgZW4gdGFudCBxdScnZW5mYW50cyBkJyd1biBcdTAwRTlsXHUwMEU5bWVudCA8c2NoZW1hPi4KLSAgICAgICAgczRzLWVsdC1zY2hlbWEtbnMgPSBzNHMtZWx0LXNjaGVtYS1ucyA6IEwnJ2VzcGFjZSBkZSBub21zIGRlIGwnJ1x1MDBFOWxcdTAwRTltZW50ICcnezB9JycgZG9pdCBcdTAwRUF0cmUgaXNzdSBkZSBsJydlc3BhY2UgZGUgbm9tcyBkdSBzY2hlbWEsICcnaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEnJy4KLSAgICAgICAgczRzLWVsdC1jaGFyYWN0ZXIgPSBzNHMtZWx0LWNoYXJhY3RlciA6IExlcyBjYXJhY3RcdTAwRThyZXMgaW1wcmltYWJsZXMgbmUgc29udCBwYXMgYXV0b3Jpc1x1MDBFOXMgZGFucyBsZXMgXHUwMEU5bFx1MDBFOW1lbnRzIGRlIHNjaFx1MDBFOW1hIGF1dHJlcyBxdWUgJyd4czphcHBpbmZvJycgZXQgJyd4czpkb2N1bWVudGF0aW9uJycuICcnezB9JycgYSBcdTAwRTl0XHUwMEU5IGRcdTAwRTl0ZWN0XHUwMEU5LgotCi0jIGNvZGVzIG5vdCBkZWZpbmVkIGJ5IHRoZSBzcGVjCi0KLSAgICAgICAgYy1maWVsZHMteHBhdGhzID0gYy1maWVsZHMteHBhdGhzIDogTGEgdmFsZXVyIGRlIGNoYW1wICcnezB9JycgbicnZXN0IHBhcyB2YWxpZGUuCi0gICAgICAgIGMtZ2VuZXJhbC14cGF0aCA9IGMtZ2VuZXJhbC14cGF0aCA6IEwnJ2V4cHJlc3Npb24gJyd7MH0nJyBuJydlc3QgcGFzIHZhbGlkZSBwYXIgcmFwcG9ydCBhdSBzb3VzLWVuc2VtYmxlIFhQYXRoIHByaXMgZW4gY2hhcmdlIHBhciBsZSBzY2hcdTAwRTltYSBYTUwuCi0gICAgICAgIGMtZ2VuZXJhbC14cGF0aC1ucyA9IGMtZ2VuZXJhbC14cGF0aC1ucyA6IFVuIHByXHUwMEU5Zml4ZSBkJydlc3BhY2UgZGUgbm9tcyBkYW5zIGwnJ2V4cHJlc3Npb24gWFBhdGggJyd7MH0nJyBuJydlc3QgbGlcdTAwRTkgXHUwMEUwIGF1Y3VuIGVzcGFjZSBkZSBub21zLgotICAgICAgICBjLXNlbGVjdG9yLXhwYXRoID0gYy1zZWxlY3Rvci14cGF0aCA6IExhIHZhbGV1ciBkZSBzXHUwMEU5bGVjdGV1ciAnJ3swfScnIG4nJ2VzdCBwYXMgdmFsaWRlIDsgbGVzIFhQYXRoIGRlIHNcdTAwRTlsZWN0ZXVyIG5lIHBldXZlbnQgcGFzIGNvbnRlbmlyIGQnJ2F0dHJpYnV0cy4KLSAgICAgICAgRW1wdHlUYXJnZXROYW1lc3BhY2UgPSBFbXB0eVRhcmdldE5hbWVzcGFjZSA6IERhbnMgbGUgZG9jdW1lbnQgZGUgc2NoXHUwMEU5bWEgJyd7MH0nJywgbGEgdmFsZXVyIGRlIGwnJ2F0dHJpYnV0ICcndGFyZ2V0TmFtZXNwYWNlJycgbmUgcGV1dCBwYXMgXHUwMEVBdHJlIHVuZSBjaGFcdTAwRUVuZSB2aWRlLgotICAgICAgICBGYWNldFZhbHVlRnJvbUJhc2UgPSBGYWNldFZhbHVlRnJvbUJhc2UgOiBEYW5zIGxhIGRcdTAwRTljbGFyYXRpb24gZGUgdHlwZSAnJ3swfScnLCBsYSB2YWxldXIgJyd7MX0nJyBkdSBmYWNldCAnJ3syfScnIGRvaXQgXHUwMEVBdHJlIGlzc3VlIGRlIGwnJ2VzcGFjZSBkZSB2YWxldXJzIGR1IHR5cGUgZGUgYmFzZSwgJyd7M30nJy4KLSAgICAgICAgRml4ZWRGYWNldFZhbHVlID0gRml4ZWRGYWNldFZhbHVlIDogRGFucyBsYSBkXHUwMEU5ZmluaXRpb24gZGUgezN9LCBsYSB2YWxldXIgJyd7MX0nJyBkdSBmYWNldCAnJ3swfScnIG4nJ2VzdCBwYXMgdmFsaWRlLCBjYXIgbGEgdmFsZXVyIGRlICcnezB9JycgYSBcdTAwRTl0XHUwMEU5IGRcdTAwRTlmaW5pZSBzdXIgJyd7Mn0nJyBkYW5zIGwnJ3VuIGRlcyB0eXBlcyBkJydhbmNcdTAwRUF0cmUsIGV0ICd7J2ZpeGVkJ30nID0gdHJ1ZS4KLSAgICAgICAgSW52YWxpZFJlZ2V4ID0gSW52YWxpZFJlZ2V4IDogTGEgdmFsZXVyIGRlIG1vZFx1MDBFOGxlICcnezB9JycgbicnZXN0IHBhcyB1bmUgZXhwcmVzc2lvbiByXHUwMEU5Z3VsaVx1MDBFOHJlIHZhbGlkZS4gTCcnZXJyZXVyIHNpZ25hbFx1MDBFOWUgZXN0ICcnezF9JycsIGF1IG5pdmVhdSBkZSBsYSBjb2xvbm5lICcnezJ9JycuCi0gICAgICAgIE1heE9jY3VyTGltaXQgPSBMYSBjb25maWd1cmF0aW9uIGVuIGNvdXJzIGRlIGwnJ2FuYWx5c2V1ciBuZSBwZXJtZXQgcGFzIGRlIGRcdTAwRTlmaW5pciB1bmUgdmFsZXVyIGQnJ2F0dHJpYnV0IG1heE9jY3VycyBzdXIgdW5lIHZhbGV1ciBzdXBcdTAwRTlyaWV1cmUgXHUwMEUwIHswfS4KLSAgICAgICAgUHVibGljU3lzdGVtT25Ob3RhdGlvbiA9IFB1YmxpY1N5c3RlbU9uTm90YXRpb24gOiBBdSBtb2lucyB1bmUgZGVzIHZhbGV1cnMgJydwdWJsaWMnJyBldCAnJ3N5c3RlbScnIGRvaXQgZmlndXJlciBkYW5zIGwnXHUwMEU5bFx1MDBFOW1lbnQgJydub3RhdGlvbicnLgotICAgICAgICBTY2hlbWFMb2NhdGlvbiA9IFNjaGVtYUxvY2F0aW9uIDogTGEgdmFsZXVyIHNjaGVtYUxvY2F0aW9uICcnezB9JycgZG9pdCBjb21wb3J0ZXIgdW4gbm9tYnJlIHBhaXIgZCcnVVJJLgotICAgICAgICBUYXJnZXROYW1lc3BhY2UuMSA9IFRhcmdldE5hbWVzcGFjZS4xIDogRXNwYWNlIGRlIG5vbXMgInswfSIgYXR0ZW5kdSBtYWlzIGwnJ2VzcGFjZSBkZSBub21zIGNpYmxlIGR1IGRvY3VtZW50IGRlIHNjaFx1MDBFOW1hIGVzdCAnJ3sxfScnLgotICAgICAgICBUYXJnZXROYW1lc3BhY2UuMiA9IFRhcmdldE5hbWVzcGFjZS4yIDogQXVjdW4gZXNwYWNlIGRlIG5vbXMgYXR0ZW5kdSBtYWlzIGxlIGRvY3VtZW50IGRlIHNjaFx1MDBFOW1hIGNvbXBvcnRlIHVuIGVzcGFjZSBkZSBub21zIGNpYmxlIGRlICcnezF9JycuCi0gICAgICAgIFVuZGVjbGFyZWRFbnRpdHkgPSBVbmRlY2xhcmVkRW50aXR5IDogTCcnZW50aXRcdTAwRTkgJyd7MH0nJyBuJydlc3QgcGFzIGRcdTAwRTljbGFyXHUwMEU5ZS4KLSAgICAgICAgVW5kZWNsYXJlZFByZWZpeCA9IFVuZGVjbGFyZWRQcmVmaXggOiBJbXBvc3NpYmxlIGRlIHJcdTAwRTlzb3VkcmUgJyd7MH0nJyBlbiB1biBRTmFtZSA6IGxlIHByXHUwMEU5Zml4ZSAnJ3sxfScnIG4nJ2VzdCBwYXMgZFx1MDBFOWNsYXJcdTAwRTkuCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9YTUxTY2hlbWFNZXNzYWdlc19pdC5wcm9wZXJ0aWVzIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MU2NoZW1hTWVzc2FnZXNfaXQucHJvcGVydGllcwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMWE4MGIzZC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9YTUxTY2hlbWFNZXNzYWdlc19pdC5wcm9wZXJ0aWVzCisrKyAvZGV2L251bGwKQEAgLTEsMjkxICswLDAgQEAKLSMgVGhpcyBmaWxlIGNvbnRhaW5zIGVycm9yIGFuZCB3YXJuaW5nIG1lc3NhZ2VzIHJlbGF0ZWQgdG8gWE1MIFNjaGVtYQotIyBUaGUgbWVzc2FnZXMgYXJlIGFycmFuZ2VkIGluIGtleSBhbmQgdmFsdWUgdHVwbGVzIGluIGEgTGlzdFJlc291cmNlQnVuZGxlLgotIwotCi0gICAgICAgIEJhZE1lc3NhZ2VLZXkgPSBJbXBvc3NpYmlsZSB0cm92YXJlIGlsIG1lc3NhZ2dpbyBkaSBlcnJvcmUgY29ycmlzcG9uZGVudGUgYWxsYSBjaGlhdmUgZGkgbWVzc2FnZ2lvLgotICAgICAgICBGb3JtYXRGYWlsZWQgPSBTaSBcdTAwRTggdmVyaWZpY2F0byB1biBlcnJvcmUgaW50ZXJubyBkdXJhbnRlIGxhIGZvcm1hdHRhemlvbmUgZGVsIHNlZ3VlbnRlIG1lc3NhZ2dpbzpcbgotCi0jIEZvciBpbnRlcm5hbCB1c2UKLQotICAgICAgICBJbnRlcm5hbC1FcnJvciA9IEVycm9yZSBpbnRlcm5vOiB7MH0uCi0gICAgICAgIGR0LXdoaXRlc3BhY2UgPSBTcGF6aW8gdnVvdG8gbm9uIGRpc3BvbmliaWxlIGNvbWUgdmFsb3JlIGRpIGZhY2V0IHBlciBpbCBzaW1wbGVUeXBlIGRpIHVuaW9uZSAnJ3swfScnCi0gICAgICAgIEdyYW1tYXJDb25mbGljdCA9IFVuYSBncmFtbWF0aWNhIHJlc3RpdHVpdGEgZGFsIHBvb2wgZGkgZ3JhbW1hdGljaGUgZGVsbCd1dGVudGUgXHUwMEU4IGluIGNvbmZsaXR0byBjb24gdW4nYWx0cmEgZ3JhbW1hdGljYS4KLQotIyBJZGVudGl0eSBjb25zdHJhaW50cwotCi0gICAgICAgIEFic2VudEtleVZhbHVlID0gRXJyb3JlIGRlbCB2aW5jb2xvIGRpIGlkZW50aXRcdTAwRTAgKGN2Yy1pZGVudGl0eS1jb25zdHJhaW50LjQuMi4xKTogbCcnZWxlbWVudG8gInswfSIgaGEgdW5hIGNoaWF2ZSBzZW56YSBhbGN1biB2YWxvcmUuCi0gICAgICAgIER1cGxpY2F0ZUZpZWxkID0gQ29ycmlzcG9uZGVuemEgZHVwbGljYXRhIG5lbGwnJ2FtYml0byBwZXIgaWwgY2FtcG8gInswfSIuCi0gICAgICAgIER1cGxpY2F0ZUtleSA9IFZhbG9yZSBjaGlhdmUgZHVwbGljYXRvIFt7MH1dIGRpY2hpYXJhdG8gcGVyIGlsIHZpbmNvbG8gZGkgaWRlbnRpdFx1MDBFMCBkZWxsJydlbGVtZW50byAiezF9Ii4KLSAgICAgICAgRHVwbGljYXRlVW5pcXVlID0gVmFsb3JlIHVuaXZvY28gZHVwbGljYXRvIFt7MH1dIGRpY2hpYXJhdG8gcGVyIGlsIHZpbmNvbG8gZGkgaWRlbnRpdFx1MDBFMCBkZWxsJydlbGVtZW50byAiezF9Ii4KLSAgICAgICAgRmllbGRNdWx0aXBsZU1hdGNoID0gRXJyb3JlIGRlbCB2aW5jb2xvIGRpIGlkZW50aXRcdTAwRTA6IGlsIGNhbXBvICJ7MH0iIGNvcnJpc3BvbmRlIGEgcGlcdTAwRjkgdmFsb3JpIG5lbGwnJ2FtYml0byBkZWwgcHJvcHJpbyBzZWxldHRvcmU7IGkgY2FtcGkgZGV2b25vIGNvcnJpc3BvbmRlcmUgYSB2YWxvcmkgdW5pdm9jaS4KLSAgICAgICAgRml4ZWREaWZmZXJzRnJvbUFjdHVhbCA9IElsIGNvbnRlbnV0byBkaSBxdWVzdG8gZWxlbWVudG8gbm9uIGVxdWl2YWxlIGFsIHZhbG9yZSBkZWxsJ2F0dHJpYnV0byAiZml4ZWQiIG5lbGxhIGRpY2hpYXJhemlvbmUgZGVsbCdlbGVtZW50byBuZWxsbyBzY2hlbWEuCi0gICAgICAgIEtleU1hdGNoZXNOaWxsYWJsZSA9IEVycm9yZSBkZWwgdmluY29sbyBkaSBpZGVudGl0XHUwMEUwIChjdmMtaWRlbnRpdHktY29uc3RyYWludC40LjIuMyk6IGwnJ2VsZW1lbnRvICJ7MH0iIGhhIHVuYSBjaGlhdmUgY29ycmlzcG9uZGVudGUgYSB1biBlbGVtZW50byBjb24gdW4gdmFsb3JlIGFubnVsbGFiaWxlIGltcG9zdGF0byBzdSB0cnVlLgotICAgICAgICBLZXlOb3RFbm91Z2hWYWx1ZXMgPSBWYWxvcmkgaW5zdWZmaWNpZW50aSBmb3JuaXRpIHBlciBpbCB2aW5jb2xvIGRpIGlkZW50aXRcdTAwRTAgPGtleSBuYW1lPSJ7MX0iPiBzcGVjaWZpY2F0byBwZXIgbCcnZWxlbWVudG8gInswfSIuCi0gICAgICAgIEtleU5vdEZvdW5kID0gQ2hpYXZlICJ7MH0iY29uIHZhbG9yZSAiezF9IiBub24gdHJvdmF0YSBwZXIgaWwgdmluY29sbyBkaSBpZGVudGl0XHUwMEUwIGRlbGwnJ2VsZW1lbnRvICJ7Mn0iLgotICAgICAgICBLZXlSZWZOb3RFbm91Z2hWYWx1ZXMgPSBWYWxvcmkgaW5zdWZmaWNpZW50aSBmb3JuaXRpIHBlciBpbCB2aW5jb2xvIGRpIGlkZW50aXRcdTAwRTAgPGtleXJlZiBuYW1lPSJ7MX0iPiBzcGVjaWZpY2F0byBwZXIgbCcnZWxlbWVudG8gInswfSIuCi0gICAgICAgIEtleVJlZk91dE9mU2NvcGUgPSBFcnJvcmUgZGVsIHZpbmNvbG8gZGkgaWRlbnRpdFx1MDBFMDogaWwgdmluY29sbyBkaSBpZGVudGl0XHUwMEUwICJ7MH0iIGhhIHVuIGtleXJlZiBjaGUgZmEgcmlmZXJpbWVudG8gYSB1bmEgY2hpYXZlIG8gYSB1biB2YWxvcmUgdW5pdm9jbyBmdW9yaSBhbWJpdG8uCi0gICAgICAgIEtleVJlZlJlZmVyTm90Rm91bmQgPSBMYSBkaWNoaWFyYXppb25lICJ7MH0iIGRlbCByaWZlcmltZW50byBjaGlhdmUgZmEgcmlmZXJpbWVudG8gYSB1bmEgY2hpYXZlIHNjb25vc2NpdXRhIGRlbm9taW5hdGEgInsxfSIuCi0gICAgICAgIFVuaXF1ZU5vdEVub3VnaFZhbHVlcyA9IFZhbG9yaSBpbnN1ZmZpY2llbnRpIGZvcm5pdGkgcGVyIGlsIHZpbmNvbG8gZGkgaWRlbnRpdFx1MDBFMCA8dW5pcXVlPiBzcGVjaWZpY2F0byBwZXIgbCcnZWxlbWVudG8gInswfSIuCi0gICAgICAgIFVua25vd25GaWVsZCA9IEVycm9yZSBpbnRlcm5vIGRlbCB2aW5jb2xvIGRpIGlkZW50aXRcdTAwRTA7IGNhbXBvICJ7MH0iIHNjb25vc2NpdXRvCi0KLSMgSWRlYWxseSwgd2Ugc2hvdWxkIG9ubHkgdXNlIHRoZSBmb2xsb3dpbmcgZXJyb3Iga2V5cywgbm90IHRoZSBvbmVzIHVuZGVyCi0jICJJZGVudGl0eSBjb25zdHJhaW50cyIuIEFuZCB3ZSBzaG91bGQgY292ZXIgYWxsIG9mIHRoZSBmb2xsb3dpbmcgZXJyb3JzLgotCi0jdmFsaWRhdGlvbiAoMy5YLjQpCi0KLSAgICAgICAgY3ZjLWF0dHJpYnV0ZS4zID0gY3ZjLWF0dHJpYnV0ZS4zOiBpbCB2YWxvcmUgJyd7Mn0nJyBkZWxsJydhdHRyaWJ1dG8gJyd7MX0nJyBzdWxsJydlbGVtZW50byAnJ3swfScnIG5vbiBcdTAwRTggdmFsaWRvIHJpc3BldHRvIGFsIHN1byB0aXBvICcnezN9JycuCi0gICAgICAgIGN2Yy1hdHRyaWJ1dGUuNCA9IGN2Yy1hdHRyaWJ1dGUuNDogaWwgdmFsb3JlICcnezJ9JycgZGVsbCcnYXR0cmlidXRvICcnezF9Jycgc3VsbCcnZWxlbWVudG8gJyd7MH0nJyBub24gXHUwMEU4IHZhbGlkbyByaXNwZXR0byBhbCBzdW8gJ3sndmFsdWUgY29uc3RyYWludCd9JyBmaXNzby4gTCcnYXR0cmlidXRvIGRldmUgYXZlcmUgdW4gdmFsb3JlIHBhcmkgYSAnJ3szfScnLgotICAgICAgICBjdmMtY29tcGxleC10eXBlLjIuMSA9IGN2Yy1jb21wbGV4LXR5cGUuMi4xOiBsJydlbGVtZW50byAiezB9IiBub24gZGV2ZSBhdmVyZSBbY2hpbGRyZW5dIGRpIHZvY2kgZGkgaW5mb3JtYXppb25pIGRpIGNhcmF0dGVyZSBvIGVsZW1lbnRvIHBlcmNoXHUwMEU5IGlsIHRpcG8gZGkgY29udGVudXRvIFx1MDBFOCB2dW90by4KLSAgICAgICAgY3ZjLWNvbXBsZXgtdHlwZS4yLjIgPSBjdmMtY29tcGxleC10eXBlLjIuMjogbCcnZWxlbWVudG8gInswfSIgbm9uIGRldmUgYXZlcmUgW2NoaWxkcmVuXSBkaSB0aXBvIGVsZW1lbnRvIGUgaWwgdmFsb3JlIGRldmUgZXNzZXJlIHZhbGlkby4KLSAgICAgICAgY3ZjLWNvbXBsZXgtdHlwZS4yLjMgPSBjdmMtY29tcGxleC10eXBlLjIuMzogbCcnZWxlbWVudG8gInswfSIgbm9uIGRldmUgYXZlcmUgW2NoaWxkcmVuXSBkaSB0aXBvIGNhcmF0dGVyZSBwZXJjaFx1MDBFOSBpbCB0aXBvIGRpIGNvbnRlbnV0byBcdTAwRTggZGkgc29saSBlbGVtZW50aS4KLSAgICAgICAgY3ZjLWNvbXBsZXgtdHlwZS4yLjQuYSA9IGN2Yy1jb21wbGV4LXR5cGUuMi40LmE6IGNvbnRlbnV0byBub24gdmFsaWRvIGNoZSBpbml6aWEgY29uIGwnJ2VsZW1lbnRvICJ7MH0iLiBcdTAwQzggcHJldmlzdG8gdW4gZWxlbWVudG8gInsxfSIuCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuMi40LmIgPSBjdmMtY29tcGxleC10eXBlLjIuNC5iOiBpbCBjb250ZW51dG8gZGVsbCcnZWxlbWVudG8gInswfSIgbm9uIFx1MDBFOCBjb21wbGV0by4gXHUwMEM4IHByZXZpc3RvIHVuIGVsZW1lbnRvICJ7MX0iLgotICAgICAgICBjdmMtY29tcGxleC10eXBlLjIuNC5jID0gY3ZjLWNvbXBsZXgtdHlwZS4yLjQuYzogaWwgY2FyYXR0ZXJlIGpvbGx5IGNvcnJpc3BvbmRlbnRlIFx1MDBFOCByaWdvcm9zbyBtYSBub24gXHUwMEU4IHBvc3NpYmlsZSB0cm92YXJlIHVuYSBkaWNoaWFyYXppb25lIHBlciBsJydlbGVtZW50byAiezB9Ii4KLSAgICAgICAgY3ZjLWNvbXBsZXgtdHlwZS4yLjQuZCA9IGN2Yy1jb21wbGV4LXR5cGUuMi40LmQ6IGNvbnRlbnV0byBub24gdmFsaWRvIGNoZSBpbml6aWEgY29uIGwnJ2VsZW1lbnRvICJ7MH0iLiBOb24gc29ubyBwcmV2aXN0aSBlbGVtZW50aSBmaWdsaW8gaW4gcXVlc3RvIHB1bnRvLgotICAgICAgICBjdmMtY29tcGxleC10eXBlLjIuNC5lID0gY3ZjLWNvbXBsZXgtdHlwZS4yLjQuZDogY29udGVudXRvIG5vbiB2YWxpZG8gY2hlIGluaXppYSBjb24gbCcnZWxlbWVudG8gInswfSIuIE5vbiBcdTAwRTggcHJldmlzdG8gdW4gZWxlbWVudG8gZmlnbGlvICcnezF9JycgaW4gcXVlc3RvIHB1bnRvLgotICAgICAgICBjdmMtY29tcGxleC10eXBlLjMuMSA9IGN2Yy1jb21wbGV4LXR5cGUuMy4xOiBpbCB2YWxvcmUgInsyfSIgZGVsbCcnYXR0cmlidXRvICJ7MX0iIGRlbGwnJ2VsZW1lbnRvICJ7MH0iIG5vbiBcdTAwRTggdmFsaWRvIHJpc3BldHRvIGFsIHVzbyBjb3JyaXNwb25kZW50ZSBkZWxsJydhdHRyaWJ1dG8uIEwnJ2F0dHJpYnV0byAnJ3sxfScnIGhhIHVuIHZhbG9yZSBmaXNzbyBwYXJpIGEgJyd7M30nJy4KLSAgICAgICAgY3ZjLWNvbXBsZXgtdHlwZS4zLjIuMSA9IGN2Yy1jb21wbGV4LXR5cGUuMy4yLjE6IGwnJ2VsZW1lbnRvICJ7MH0iIG5vbiBoYSB1biBjYXJhdHRlcmUgam9sbHkgZGkgYXR0cmlidXRvIHBlciBsJydhdHRyaWJ1dG8gInsxfSIuCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuMy4yLjIgPSBjdmMtY29tcGxleC10eXBlLjMuMi4yOiBsJydhdHRyaWJ1dG8gInsxfSIgbm9uIFx1MDBFOCBjb25zZW50aXRvIG5lbGwnJ2VsZW1lbnRvICJ7MH0iLgotICAgICAgICBjdmMtY29tcGxleC10eXBlLjQgPSBjdmMtY29tcGxleC10eXBlLjQ6IGwnJ2F0dHJpYnV0byAnJ3sxfScnIGRldmUgYXBwYXJpcmUgc3VsbCcnZWxlbWVudG8gInswfSIuCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuNS4xID0gY3ZjLWNvbXBsZXgtdHlwZS41LjE6IG5lbGwnJ2VsZW1lbnRvICJ7MH0iLCBsJydhdHRyaWJ1dG8gInsxfSIgXHUwMEU4IHVuIElEIFdpbGQgbWEgZXNpc3RlIGdpXHUwMEUwIHVuIElEIFdpbGQgInsyfSIuIFB1XHUwMEYyIGVzaXN0ZXJuZSBzb2xvIHVuby4KLSAgICAgICAgY3ZjLWNvbXBsZXgtdHlwZS41LjIgPSBjdmMtY29tcGxleC10eXBlLjUuMjogbmVsbCcnZWxlbWVudG8gInswfSIsIGwnJ2F0dHJpYnV0byAiezF9IiBcdTAwRTggdW4gSUQgV2lsZCBtYSBlc2lzdGUgZ2lcdTAwRTAgdW4gYXR0cmlidXRvICJ7Mn0iIGRlcml2YXRvIGRhbGwnJ0lEIHRyYSAneydhdHRyaWJ1dGUgdXNlcyd9Jy4KLSAgICAgICAgY3ZjLWRhdGF0eXBlLXZhbGlkLjEuMi4xID0gY3ZjLWRhdGF0eXBlLXZhbGlkLjEuMi4xOiAiezB9IiBub24gXHUwMEU4IHVuIHZhbG9yZSB2YWxpZG8gcGVyICJ7MX0iLgotICAgICAgICBjdmMtZGF0YXR5cGUtdmFsaWQuMS4yLjIgPSBjdmMtZGF0YXR5cGUtdmFsaWQuMS4yLjI6ICJ7MH0iIG5vbiBcdTAwRTggdW4gdmFsb3JlIHZhbGlkbyBwZXIgaWwgdGlwbyBkaSBsaXN0YSAiezF9Ii4KLSAgICAgICAgY3ZjLWRhdGF0eXBlLXZhbGlkLjEuMi4zID0gY3ZjLWRhdGF0eXBlLXZhbGlkLjEuMi4zOiAiezB9IiBub24gXHUwMEU4IHVuIHZhbG9yZSB2YWxpZG8gcGVyIGlsIHRpcG8gZGkgdW5pb25lICJ7MX0iLgotICAgICAgICBjdmMtZWx0LjEgPSBjdmMtZWx0LjE6IGltcG9zc2liaWxlIHRyb3ZhcmUgbGEgZGljaGlhcmF6aW9uZSBkZWxsJydlbGVtZW50byAiezB9Ii4KLSAgICAgICAgY3ZjLWVsdC4yID0gY3ZjLWVsdC4yOiBpbCB2YWxvcmUgZGkgJ3snYWJzdHJhY3QnfScgbmVsbGEgZGljaGlhcmF6aW9uZSBkaSBlbGVtZW50byBwZXIgInswfSIgZGV2ZSBlc3NlcmUgZmFsc2UuCi0gICAgICAgIGN2Yy1lbHQuMy4xID0gY3ZjLWVsdC4zLjE6IGwnJ2F0dHJpYnV0byAiezF9IiBub24gZGV2ZSBhcHBhcmlyZSBzdWxsJydlbGVtZW50byAiezB9IiBwZXJjaFx1MDBFOSBsYSBwcm9wcmlldFx1MDBFMCAneyduaWxsYWJsZSd9JyBkaSAiezB9IiBcdTAwRTggZmFsc2UuCi0gICAgICAgIGN2Yy1lbHQuMy4yLjEgPSBjdmMtZWx0LjMuMi4xOiBsJydlbGVtZW50byAiezB9IiBub24gZGV2ZSBhdmVyZSBbY2hpbGRyZW5dIGRpIGluZm9ybWF6aW9uaSBkaSB0aXBvIGNhcmF0dGVyZSBvIGVsZW1lbnRvIHBlcmNoXHUwMEU5IFx1MDBFOCBzcGVjaWZpY2F0byAiezF9Ii4KLSAgICAgICAgY3ZjLWVsdC4zLjIuMiA9IGN2Yy1lbHQuMy4yLjI6IG5vbiBkZXZlIGVzaXN0ZXJlIGFsY3VuICd7J3ZhbHVlIGNvbnN0cmFpbnQnfScgZmlzc28gcGVyIGwnJ2VsZW1lbnRvICJ7MH0iIHBlcmNoXHUwMEU5IFx1MDBFOCBzcGVjaWZpY2F0byAiezF9Ii4KLSAgICAgICAgY3ZjLWVsdC40LjEgPSBjdmMtZWx0LjQuMTogaWwgdmFsb3JlICJ7Mn0iIGRlbGwnJ2F0dHJpYnV0byAiezF9IiBwZXIgbCcnZWxlbWVudG8gInswfSIgbm9uIFx1MDBFOCB1biBRTmFtZSB2YWxpZG8uCi0gICAgICAgIGN2Yy1lbHQuNC4yID0gY3ZjLWVsdC40LjI6IGltcG9zc2liaWxlIHJpc29sdmVyZSAiezF9IiBpbiB1bmEgZGVmaW5pemlvbmUgdGlwbyBwZXIgbCcnZWxlbWVudG8gInswfSIuCi0gICAgICAgIGN2Yy1lbHQuNC4zID0gY3ZjLWVsdC40LjM6IHRpcG8gInsxfSIgbm9uIGRlcml2YXRvIGluIG1vZG8gdmFsaWRvIGRhbGxhIGRlZmluaXppb25lIHRpcG8gJyd7Mn0nJyBkZWxsJydlbGVtZW50byAiezB9Ii4KLSAgICAgICAgY3ZjLWVsdC41LjEuMSA9IGN2Yy1lbHQuNS4xLjE6ICd7J3ZhbHVlIGNvbnN0cmFpbnQnfScgInsyfSIgZGVsbCcnZWxlbWVudG8gInswfSIgbm9uIFx1MDBFOCB1biB2YWxvcmUgcHJlZGVmaW5pdG8gdmFsaWRvIHBlciBpbCB0aXBvICJ7MX0iLgotICAgICAgICBjdmMtZWx0LjUuMi4yLjEgPSBjdmMtZWx0LjUuMi4yLjE6IGwnJ2VsZW1lbnRvICJ7MH0iIG5vbiBkZXZlIGF2ZXJlIFtjaGlsZHJlbl0gZGkgdm9jaSBkaSBpbmZvcm1hemlvbmkgZGkgZWxlbWVudG8uCi0gICAgICAgIGN2Yy1lbHQuNS4yLjIuMi4xID0gY3ZjLWVsdC41LjIuMi4yLjE6IGlsIHZhbG9yZSAiezF9IiBkZWxsJydlbGVtZW50byAiezB9IiBub24gY29ycmlzcG9uZGUgYWwgdmFsb3JlIGZpc3NvIGRpICd7J3ZhbHVlIGNvbnN0cmFpbnQnfScgInsyfSIuCi0gICAgICAgIGN2Yy1lbHQuNS4yLjIuMi4yID0gY3ZjLWVsdC41LjIuMi4yLjI6IGlsIHZhbG9yZSAiezF9IiBkZWxsJydlbGVtZW50byAiezB9IiBub24gY29ycmlzcG9uZGUgYWwgdmFsb3JlIGRpICd7J3ZhbHVlIGNvbnN0cmFpbnQnfScgInsyfSIuCi0gICAgICAgIGN2Yy1lbnVtZXJhdGlvbi12YWxpZCA9IGN2Yy1lbnVtZXJhdGlvbi12YWxpZDogaWwgdmFsb3JlICJ7MH0iIG5vbiBcdTAwRTggdmFsaWRvIGNvbWUgZmFjZXQgcmlzcGV0dG8gYWxsJydlbnVtZXJhemlvbmUgInsxfSIuIERldmUgZXNzZXJlIHVuIHZhbG9yZSBkZWxsJydlbnVtZXJhemlvbmUuCi0gICAgICAgIGN2Yy1mcmFjdGlvbkRpZ2l0cy12YWxpZCA9IGN2Yy1mcmFjdGlvbkRpZ2l0cy12YWxpZDogaWwgdmFsb3JlICcnezB9JycgaGEgezF9IGNpZnJlIGRpIGZyYXppb25lLCBtYSBpbCBudW1lcm8gZGkgY2lmcmUgZGkgZnJhemlvbmUgXHUwMEU4IHN0YXRvIGxpbWl0YXRvIGEgezJ9LgotICAgICAgICBjdmMtaWQuMSA9IGN2Yy1pZC4xOiBub24gZXNpc3RlIGFsY3VuYSBhc3NvY2lhemlvbmUgSUQvSURSRUYgcGVyIGwnJ0lEUkVGICJ7MH0iLgotICAgICAgICBjdmMtaWQuMiA9IGN2Yy1pZC4yOiBlc2lzdG9ubyBwaVx1MDBGOSByaWNvcnJlbnplIGRlbCB2YWxvcmUgZGkgSUQgInswfSIuCi0gICAgICAgIGN2Yy1pZC4zID0gY3ZjLWlkLjM6IHVuIGNhbXBvIGRlbCB2aW5jb2xvIGRpIGlkZW50aXRcdTAwRTAgInswfSIgY29ycmlzcG9uZGV2YSBhbGwnJ2VsZW1lbnRvICJ7MX0iIG1hIHF1ZXN0byBlbGVtZW50byBub24gaGEgdW4gdGlwbyBzZW1wbGljZS4KLSAgICAgICAgY3ZjLWxlbmd0aC12YWxpZCA9IGN2Yy1sZW5ndGgtdmFsaWQ6IGlsIHZhbG9yZSAiezB9IiBjb24gbHVuZ2hlenphID0gInsxfSIgbm9uIFx1MDBFOCB2YWxpZG8gY29tZSBmYWNldCByaXNwZXR0byBhbGxhIGx1bmdoZXp6YSAiezJ9IiBwZXIgaWwgdGlwbyAiezN9Ii4KLSAgICAgICAgY3ZjLW1heEV4Y2x1c2l2ZS12YWxpZCA9IGN2Yy1tYXhFeGNsdXNpdmUtdmFsaWQ6IGlsIHZhbG9yZSAiezB9IiBub24gXHUwMEU4IHZhbGlkbyBjb21lIGZhY2V0IHJpc3BldHRvIGEgbWF4RXhjbHVzaXZlICJ7MX0iIHBlciBpbCB0aXBvICcnezJ9JycuCi0gICAgICAgIGN2Yy1tYXhJbmNsdXNpdmUtdmFsaWQgPSBjdmMtbWF4SW5jbHVzaXZlLXZhbGlkOiBpbCB2YWxvcmUgInswfSIgbm9uIFx1MDBFOCB2YWxpZG8gY29tZSBmYWNldCByaXNwZXR0byBhIG1heEluY2x1c2l2ZSAiezF9IiBwZXIgaWwgdGlwbyAnJ3syfScnLgotICAgICAgICBjdmMtbWF4TGVuZ3RoLXZhbGlkID0gY3ZjLW1heExlbmd0aC12YWxpZDogaWwgdmFsb3JlICJ7MH0iIGNvbiBsdW5naGV6emEgPSAiezF9IiBub24gXHUwMEU4IHZhbGlkbyBjb21lIGZhY2V0IHJpc3BldHRvIGEgbWF4TGVuZ3RoICJ7Mn0iIHBlciBpbCB0aXBvICJ7M30iLgotICAgICAgICBjdmMtbWluRXhjbHVzaXZlLXZhbGlkID0gY3ZjLW1pbkV4Y2x1c2l2ZS12YWxpZDogaWwgdmFsb3JlICJ7MH0iIG5vbiBcdTAwRTggdmFsaWRvIGNvbWUgZmFjZXQgcmlzcGV0dG8gYSBtaW5FeGNsdXNpdmUgInsxfSIgcGVyIGlsIHRpcG8gJyd7Mn0nJy4KLSAgICAgICAgY3ZjLW1pbkluY2x1c2l2ZS12YWxpZCA9IGN2Yy1taW5JbmNsdXNpdmUtdmFsaWQ6IGlsIHZhbG9yZSAiezB9IiBub24gXHUwMEU4IHZhbGlkbyBjb21lIGZhY2V0IHJpc3BldHRvIGEgbWluRXhjbHVzaXZlICJ7MX0iIHBlciBpbCB0aXBvICcnezJ9JycuCi0gICAgICAgIGN2Yy1taW5MZW5ndGgtdmFsaWQgPSBjdmMtbWluTGVuZ3RoLXZhbGlkOiBpbCB2YWxvcmUgInswfSIgY29uIGx1bmdoZXp6YSA9ICJ7MX0iIG5vbiBcdTAwRTggdmFsaWRvIGNvbWUgZmFjZXQgcmlzcGV0dG8gYSBtaW5MZW5ndGggInsyfSIgcGVyIGlsIHRpcG8gInszfSIuCi0gICAgICAgIGN2Yy1wYXR0ZXJuLXZhbGlkID0gY3ZjLXBhdHRlcm4tdmFsaWQ6IGlsIHZhbG9yZSAiezB9IiBub24gXHUwMEU4IHZhbGlkbyBjb21lIGZhY2V0IHJpc3BldHRvIGFsIHBhdHRlcm4gInsxfSIgcGVyIGlsIHRpcG8gJyd7Mn0nJy4KLSAgICAgICAgY3ZjLXRvdGFsRGlnaXRzLXZhbGlkID0gY3ZjLXRvdGFsRGlnaXRzLXZhbGlkOiBpbCB2YWxvcmUgJyd7MH0nJyBoYSB7MX0gY2lmcmUgZGkgdG90YWxlLCBtYSBpbCBudW1lcm8gZGkgY2lmcmUgZGkgdG90YWxlIFx1MDBFOCBzdGF0byBsaW1pdGF0byBhIHsyfS4KLSAgICAgICAgY3ZjLXR5cGUuMiA9IGN2Yy10eXBlLjI6IGxhIGRlZmluaXppb25lIHRpcG8gbm9uIHB1XHUwMEYyIGVzc2VyZSBhc3RyYXR0YSBwZXIgbCcnZWxlbWVudG8gezB9LgotICAgICAgICBjdmMtdHlwZS4zLjEuMSA9IGN2Yy10eXBlLjMuMS4xOiBsJydlbGVtZW50byAnJ3swfScnIFx1MDBFOCBkaSB0aXBvIHNlbXBsaWNlLCBxdWluZGkgbm9uIHB1XHUwMEYyIGF2ZXJlIGF0dHJpYnV0aSwgdHJhbm5lIHF1ZWxsaSBpbCBjdWkgc3BhemlvIGRpIG5vbWkgXHUwMEU4IHVndWFsZSAnJ2h0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlJycgZSBpbCBjdWkgW2xvY2FsIG5hbWVdIFx1MDBFOCB1bm8gdHJhICcndHlwZScnLCAnJ25pbCcnLCAnJ3NjaGVtYUxvY2F0aW9uJycgbyAnJ25vTmFtZXNwYWNlU2NoZW1hTG9jYXRpb24nJy4gXHUwMEM4IHN0YXRvIHRyb3ZhdG8gbCcnYXR0cmlidXRvICcnezF9JycuCi0gICAgICAgIGN2Yy10eXBlLjMuMS4yID0gY3ZjLXR5cGUuMy4xLjI6IGwnJ2VsZW1lbnRvICJ7MH0iIFx1MDBFOCBkaSB0aXBvIHNlbXBsaWNlLCBxdWluZGkgbm9uIGRldmUgYXZlcmUgW2NoaWxkcmVuXSBkaSB2b2NpIGRpIGluZm9ybWF6aW9uaSBkaSBlbGVtZW50by4KLSAgICAgICAgY3ZjLXR5cGUuMy4xLjMgPSBjdmMtdHlwZS4zLjEuMzogaWwgdmFsb3JlICJ7MX0iIGRlbGwnJ2VsZW1lbnRvICJ7MH0iIG5vbiBcdTAwRTggdmFsaWRvLgotCi0jc2NoZW1hIHZhbGlkICgzLlguMykKLQotICAgICAgICBzY2hlbWFfcmVmZXJlbmNlLmFjY2VzcyA9IHNjaGVtYV9yZWZlcmVuY2U6IGxldHR1cmEgZGVsIGRvY3VtZW50byBkaSBzY2hlbWEgJyd7MH0nJyBub24gcml1c2NpdGEuIEFjY2Vzc28gJyd7MX0nJyBub24gY29uc2VudGl0byBhIGNhdXNhIGRlbGxhIGxpbWl0YXppb25lIGRlZmluaXRhIGRhbGxhIHByb3ByaWV0XHUwMEUwIGFjY2Vzc0V4dGVybmFsU2NoZW1hLiAKLSAgICAgICAgc2NoZW1hX3JlZmVyZW5jZS40ID0gc2NoZW1hX3JlZmVyZW5jZS40OiBsZXR0dXJhIGRlbCBkb2N1bWVudG8gZGkgc2NoZW1hICJ7MH0iIG5vbiByaXVzY2l0YSBwZXJjaFx1MDBFOSAxKSBub24gXHUwMEU4IHN0YXRvIHBvc3NpYmlsZSB0cm92YXJlIGlsIGRvY3VtZW50bzsgMikgbm9uIFx1MDBFOCBzdGF0byBwb3NzaWJpbGUgbGVnZ2VyZSBpbCBkb2N1bWVudG87IDMpIGwnJ2VsZW1lbnRvIHJhZGljZSBkZWwgZG9jdW1lbnRvIG5vbiBcdTAwRTggPHhzZDpzY2hlbWE+LgotICAgICAgICBzcmMtYW5ub3RhdGlvbiA9IHNyYy1hbm5vdGF0aW9uOiBwb3Nzb25vIGVzc2VyZSBjb250ZW51dGkgc29sdGFudG8gZWxlbWVudGkgPGFwcGluZm8+IGUgPGRvY3VtZW50YXRpb24+LCBtYSBcdTAwRTggc3RhdG8gdHJvdmF0byAnJ3swfScnLgotICAgICAgICBzcmMtYXR0cmlidXRlLjEgPSBzcmMtYXR0cmlidXRlLjE6IGxlIHByb3ByaWV0XHUwMEUwICcnZGVmYXVsdCcnIGUgJydmaXhlZCcnIG5vbiBwb3Nzb25vIGVzc2VyZSBlbnRyYW1iaSBwcmVzZW50aSBuZWxsYSBkaWNoaWFyYXppb25lIGRpIGF0dHJpYnV0byAnJ3swfScnLiBVdGlsaXp6YXJuZSBzb2xvIHVuYS4KLSAgICAgICAgc3JjLWF0dHJpYnV0ZS4yID0gc3JjLWF0dHJpYnV0ZS4yOiBsYSBwcm9wcmlldFx1MDBFMCAnJ2RlZmF1bHQnJyBcdTAwRTggcHJlc2VudGUgbmVsbCcnYXR0cmlidXRvICcnezB9JycsIHF1aW5kaSBpbCB2YWxvcmUgZGkgJyd1c2UnJyBkZXZlIGVzc2VyZSAnJ29wdGlvbmFsJycuCi0gICAgICAgIHNyYy1hdHRyaWJ1dGUuMy4xID0gc3JjLWF0dHJpYnV0ZS4zLjE6IGluIHVuYSBkaWNoaWFyYXppb25lIGRpIGF0dHJpYnV0byBsb2NhbGUgZGV2ZSBlc3NlcmUgcHJlc2VudGUgJ3JlZicgbyAnbmFtZScuCi0gICAgICAgIHNyYy1hdHRyaWJ1dGUuMy4yID0gc3JjLWF0dHJpYnV0ZS4zLjI6IGlsIGNvbnRlbnV0byBkZXZlIGNvcnJpc3BvbmRlcmUgYSAoYW5ub3RhdGlvbj8pIHBlciBpbCByaWZlcmltZW50byBkaSBhdHRyaWJ1dG8gInswfSIuCi0gICAgICAgIHNyYy1hdHRyaWJ1dGUuNCA9IHNyYy1hdHRyaWJ1dGUuNDogbCcnYXR0cmlidXRvICJ7MH0iIGhhIHNpYSB1biBhdHRyaWJ1dG8gJyd0eXBlJycgY2hlIHVuIGVsZW1lbnRvIGZpZ2xpbyAic2ltcGxlVHlwZSIgYW5vbmltby4gXHUwMEM4IGNvbnNlbnRpdG8gdW5vIHNvbG8gZGkgcXVlc3RpIHZhbG9yaSBwZXIgdW4gYXR0cmlidXRvLgotICAgICAgICBzcmMtYXR0cmlidXRlX2dyb3VwLjIgPSBzcmMtYXR0cmlidXRlX2dyb3VwLjI6IG5vbiBcdTAwRTggcG9zc2liaWxlIGVzcHJpbWVyZSBsJydpbnRlcnNlemlvbmUgZGkgY2FyYXR0ZXJpIGpvbGx5IHBlciBpbCBncnVwcG8gZGkgYXR0cmlidXRpICcnezB9JycuCi0gICAgICAgIHNyYy1hdHRyaWJ1dGVfZ3JvdXAuMyA9IHNyYy1hdHRyaWJ1dGVfZ3JvdXAuMzogc29ubyBzdGF0ZSByaWxldmF0ZSBkZWZpbml6aW9uaSBjaXJjb2xhcmkgcGVyIGlsIGdydXBwbyBkaSBhdHRyaWJ1dGkgJyd7MH0nJy4gU2Ugc2kgc2VndW9ubyByaWNvcnNpdmFtZW50ZSBpIHJpZmVyaW1lbnRpIGFpIGdydXBwaSBkaSBhdHRyaWJ1dGksIHNpIHRvcm5hIGluZXZpdGFiaWxtZW50ZSBhbCBwdW50byBkaSBwYXJ0ZW56YS4KLSAgICAgICAgc3JjLWN0LjEgPSBzcmMtY3QuMTogZXJyb3JlIGRpIHJhcHByZXNlbnRhemlvbmUgZGVsbGEgZGVmaW5pemlvbmUgZGkgdGlwbyBjb21wbGVzc28gcGVyIGlsIHRpcG8gJyd7MH0nJy4gU2Ugc2kgdXRpbGl6emEgPGNvbXBsZXhDb250ZW50PiwgaWwgdGlwbyBkaSBiYXNlIGRldmUgZXNzZXJlIHVuIGNvbXBsZXhUeXBlLiAnJ3sxfScnIFx1MDBFOCBzaW1wbGVUeXBlLgotICAgICAgICBzcmMtY3QuMi4xID0gc3JjLWN0LjIuMTogZXJyb3JlIGRpIHJhcHByZXNlbnRhemlvbmUgZGVsbGEgZGVmaW5pemlvbmUgZGkgdGlwbyBjb21wbGVzc28gcGVyIGlsIHRpcG8gJyd7MH0nJy4gU2Ugc2kgdXRpbGl6emEgPGNvbXBsZXhDb250ZW50PiwgaWwgdGlwbyBkaSBiYXNlIGRldmUgZXNzZXJlIHVuIGNvbXBsZXhUeXBlIGNvbiB0aXBvIGRpIGNvbnRlbnV0byBzZW1wbGljZSBvcHB1cmUsIHNlIFx1MDBFOCBzcGVjaWZpY2F0YSBzb2xvIGxhIGxpbWl0YXppb25lLCB1biB0aXBvIGNvbXBsZXNzbyBjb24gY29udGVudXRvIG1pc3RvIGUgcGFydGUgc3Z1b3RhYmlsZSBvcHB1cmUsIHNlIFx1MDBFOCBzcGVjaWZpY2F0byBzb2xvIGwnJ2VzdGVuc2lvbmUsIHVuIHRpcG8gc2VtcGxpY2UuICcnezF9Jycgbm9uIHNvZGRpc2ZhIGFsY3VuYSBkaSBxdWVzdGUgY29uZGl6aW9uaS4KLSAgICAgICAgc3JjLWN0LjIuMiA9IHNyYy1jdC4yLjI6IGVycm9yZSBkaSByYXBwcmVzZW50YXppb25lIGRlbGxhIGRlZmluaXppb25lIGRpIHRpcG8gY29tcGxlc3NvIHBlciBpbCB0aXBvICJ7MH0iLiBRdWFuZG8gdW4gY29tcGxleFR5cGUgY29uIHNpbXBsZUNvbnRlbnQgbGltaXRhIHVuIGNvbXBsZXhUeXBlIGNvbiBjb250ZW51dG8gbWlzdG8gZSBwYXJ0ZSBzdnVvdGFiaWxlLCBkZXZlIGVzaXN0ZXJlIHVuIDxzaW1wbGVUeXBlPiB0cmEgZ2xpIGVsZW1lbnRpIGZpZ2xpbyBkaSA8cmVzdHJpY3Rpb24+LgotICAgICAgICBzcmMtY3QuNCA9IHNyYy1jdC40OiBlcnJvcmUgZGkgcmFwcHJlc2VudGF6aW9uZSBkZWxsYSBkZWZpbml6aW9uZSBkaSB0aXBvIGNvbXBsZXNzbyBwZXIgaWwgdGlwbyAnJ3swfScnLiBOb24gXHUwMEU4IHBvc3NpYmlsZSBlc3ByaW1lcmUgbCcnaW50ZXJzZXppb25lIGRpIGNhcmF0dGVyaSBqb2xseS4KLSAgICAgICAgc3JjLWN0LjUgPSBzcmMtY3QuNTogZXJyb3JlIGRpIHJhcHByZXNlbnRhemlvbmUgZGVsbGEgZGVmaW5pemlvbmUgZGkgdGlwbyBjb21wbGVzc28gcGVyIGlsIHRpcG8gJyd7MH0nJy4gTm9uIFx1MDBFOCBwb3NzaWJpbGUgZXNwcmltZXJlIGwnJ3VuaW9uZSBkaSBjYXJhdHRlcmkgam9sbHkuCi0gICAgICAgIHNyYy1lbGVtZW50LjEgPSBzcmMtZWxlbWVudC4xOiBsZSBwcm9wcmlldFx1MDBFMCAnJ2RlZmF1bHQnJyBlICcnZml4ZWQnJyBub24gcG9zc29ubyBlc3NlcmUgZW50cmFtYmkgcHJlc2VudGkgbmVsbGEgZGljaGlhcmF6aW9uZSBkaSBlbGVtZW50byAnJ3swfScnLiBVdGlsaXp6YXJuZSBzb2xvIHVuYS4KLSAgICAgICAgc3JjLWVsZW1lbnQuMi4xID0gc3JjLWVsZW1lbnQuMi4xOiBpbiB1bmEgZGljaGlhcmF6aW9uZSBkaSBlbGVtZW50byBsb2NhbGUgZGV2ZSBlc3NlcmUgcHJlc2VudGUgJ3JlZicgbyAnbmFtZScuCi0gICAgICAgIHNyYy1lbGVtZW50LjIuMiA9IHNyYy1lbGVtZW50LjIuMjogcG9pY2hcdTAwRTkgJyd7MH0nJyBjb250aWVuZSBsJydhdHRyaWJ1dG8gJydyZWYnJywgaWwgc3VvIGNvbnRlbnV0byBkZXZlIGNvcnJpc3BvbmRlcmUgYSAoYW5ub3RhdGlvbj8pLCBtYSBcdTAwRTggc3RhdG8gdHJvdmF0byAnJ3sxfScnLgotICAgICAgICBzcmMtZWxlbWVudC4zID0gc3JjLWVsZW1lbnQuMzogbCcnZWxlbWVudG8gInswfSIgaGEgc2lhIHVuIGF0dHJpYnV0byAnJ3R5cGUnJyBjaGUgdW4gZWxlbWVudG8gZmlnbGlvICJhbm9ueW1vdXMgdHlwZSIuIFx1MDBDOCBjb25zZW50aXRvIHVubyBzb2xvIGRpIHF1ZXN0aSB2YWxvcmkgcGVyIHVuIGVsZW1lbnRvLgotICAgICAgICBzcmMtaW1wb3J0LjEuMSA9IHNyYy1pbXBvcnQuMS4xOiBsJydhdHRyaWJ1dG8gInswfSIgZGVsbG8gc3BhemlvIGRpIG5vbWkgZGkgdW5hIHZvY2UgZGkgaW5mb3JtYXppb25pIGRpIGVsZW1lbnRvIDxpbXBvcnQ+IG5vbiBkZXZlIGVzc2VyZSB1Z3VhbGUgYWwgdGFyZ2V0TmFtZXNwYWNlIGRlbGxvIHNjaGVtYSBpbiBjdWkgZXNpc3RlLgotICAgICAgICBzcmMtaW1wb3J0LjEuMiA9IHNyYy1pbXBvcnQuMS4yOiBzZSBsJydhdHRyaWJ1dG8gZGVsbG8gc3BhemlvIGRpIG5vbWkgbm9uIFx1MDBFOCBwcmVzZW50ZSBpbiB1bmEgdm9jZSBkaSBpbmZvcm1hemlvbmkgZGkgZWxlbWVudG8gPGltcG9ydD4sIGxvIHNjaGVtYSBjaGUgbG8gY29udGllbmUgZGV2ZSBhdmVyZSB1biB0YXJnZXROYW1lc3BhY2UuCi0gICAgICAgIHNyYy1pbXBvcnQuMiA9IHNyYy1pbXBvcnQuMjogbCcnZWxlbWVudG8gcmFkaWNlIGRlbCBkb2N1bWVudG8gInswfSIgZGV2ZSBhdmVyZSBsbyBzcGF6aW8gZGkgbm9taSBkZW5vbWluYXRvICcnaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEnJyBlIGlsIG5vbWUgbG9jYWxlICcnc2NoZW1hJycuCi0gICAgICAgIHNyYy1pbXBvcnQuMy4xID0gc3JjLWltcG9ydC4zLjE6IGwnJ2F0dHJpYnV0byAiezB9IiBkZWxsbyBzcGF6aW8gZGkgbm9taSBkaSB1bmEgdm9jZSBkaSBpbmZvcm1hemlvbmkgZGkgZWxlbWVudG8gPGltcG9ydD4gZGV2ZSBlc3NlcmUgdWd1YWxlIGFsbCcnYXR0cmlidXRvIHRhcmdldE5hbWVzcGFjZSAnJ3sxfScnIGRlbCBkb2N1bWVudG8gaW1wb3J0YXRvLgotICAgICAgICBzcmMtaW1wb3J0LjMuMiA9IHNyYy1pbXBvcnQuMy4yOiBub24gZXNpc3RlIGFsY3VuIGF0dHJpYnV0byBkZWxsbyBzcGF6aW8gZGkgbm9taSBuZWxsYSB2b2NlIGRpIGluZm9ybWF6aW9uaSBkaSBlbGVtZW50byA8aW1wb3J0PiwgcGVydGFudG8gaWwgZG9jdW1lbnRvIGltcG9ydGF0byBub24gcHVcdTAwRjIgYXZlcmUgYWxjdW4gYXR0cmlidXRvIHRhcmdldE5hbWVzcGFjZS4gdHV0dGF2aWEsIFx1MDBFOCBzdGF0byB0cm92YXRvIHRhcmdldE5hbWVzcGFjZSAnJ3sxfScnIG5lbCBkb2N1bWVudG8gaW1wb3J0YXRvLgotICAgICAgICBzcmMtaW5jbHVkZS4xID0gc3JjLWluY2x1ZGUuMTogbCcnZWxlbWVudG8gcmFkaWNlIGRlbCBkb2N1bWVudG8gInswfSIgZGV2ZSBhdmVyZSBsbyBzcGF6aW8gZGkgbm9taSBkZW5vbWluYXRvICcnaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEnJyBlIGlsIG5vbWUgbG9jYWxlICcnc2NoZW1hJycuCi0gICAgICAgIHNyYy1pbmNsdWRlLjIuMSA9IHNyYy1pbmNsdWRlLjIuMTogdGFyZ2V0TmFtZXNwYWNlIGRlbGxvIHNjaGVtYSBkaSByaWZlcmltZW50byAoYXR0dWFsbWVudGUgInsxfSIpIGRldmUgZXNzZXJlIGlkZW50aWNvIGEgcXVlbGxvIGRlbGxvIHNjaGVtYSBkaSBpbmNsdXNpb25lIChhdHR1YWxtZW50ZSAiezB9IikuCi0gICAgICAgIHNyYy1yZWRlZmluZS4yID0gc3JjLXJlZGVmaW5lLjI6IGwnJ2VsZW1lbnRvIHJhZGljZSBkZWwgZG9jdW1lbnRvICJ7MH0iIGRldmUgYXZlcmUgbG8gc3BhemlvIGRpIG5vbWkgZGVub21pbmF0byAnJ2h0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hJycgZSBpbCBub21lIGxvY2FsZSAnJ3NjaGVtYScnLgotICAgICAgICBzcmMtcmVkZWZpbmUuMy4xID0gc3JjLXJlZGVmaW5lLjMuMTogdGFyZ2V0TmFtZXNwYWNlIGRlbGxvIHNjaGVtYSBkaSByaWZlcmltZW50byAoYXR0dWFsbWVudGUgInsxfSIpIGRldmUgZXNzZXJlIGlkZW50aWNvIGEgcXVlbGxvIGRlbGxvIHNjaGVtYSBkaSByaWRlZmluaXppb25lIChhdHR1YWxtZW50ZSAiezB9IikuCi0gICAgICAgIHNyYy1yZWRlZmluZS41LmEuYSA9IHNyYy1yZWRlZmluZS41LmEuYTogbm9uIFx1MDBFOCBzdGF0byB0cm92YXRvIGFsY3VuIGVsZW1lbnRvIGZpZ2xpbyBkaSBub24gYW5ub3RhemlvbmUgZGkgdGlwbyA8c2ltcGxlVHlwZT4uIEdsaSBlbGVtZW50aSBmaWdsaW8gPHNpbXBsZVR5cGU+IGRpIGVsZW1lbnRpIDxyZWRlZmluZT4gZGV2b25vIGF2ZXJlIGRpc2NlbmRlbnRpIDxyZXN0cmljdGlvbj4sIGNvbiBhdHRyaWJ1dGkgJ2Jhc2UnIGNoZSBmYW5ubyByaWZlcmltZW50byBhIHNcdTAwRTkgc3Rlc3NpLgotICAgICAgICBzcmMtcmVkZWZpbmUuNS5hLmIgPSBzcmMtcmVkZWZpbmUuNS5hLmI6ICcnezB9Jycgbm9uIFx1MDBFOCB1biBlbGVtZW50byBmaWdsaW8gdmFsaWRvLiBHbGkgZWxlbWVudGkgZmlnbGlvIDxzaW1wbGVUeXBlPiBkaSBlbGVtZW50aSA8cmVkZWZpbmU+IGRldm9ubyBhdmVyZSBkaXNjZW5kZW50aSA8cmVzdHJpY3Rpb24+LCBjb24gYXR0cmlidXRpICcnYmFzZScnIGNoZSBmYW5ubyByaWZlcmltZW50byBhIHNcdTAwRTkgc3Rlc3NpLgotICAgICAgICBzcmMtcmVkZWZpbmUuNS5hLmMgPSBzcmMtcmVkZWZpbmUuNS5hLmM6ICcnezB9Jycgbm9uIGRpc3BvbmUgZGkgdW4gYXR0cmlidXRvICJiYXNlIiBjaGUgZmEgcmlmZXJpbWVudG8gYWxsJydlbGVtZW50byByaWRlZmluaXRvICcnezF9JycuIEdsaSBlbGVtZW50aSBmaWdsaW8gPHNpbXBsZVR5cGU+IGRpIGVsZW1lbnRpIDxyZWRlZmluZT4gZGV2b25vIGF2ZXJlIGRpc2NlbmRlbnRpIDxyZXN0cmljdGlvbj4sIGNvbiBhdHRyaWJ1dGkgJydiYXNlJycgY2hlIGZhbm5vIHJpZmVyaW1lbnRvIGEgc1x1MDBFOSBzdGVzc2kuCi0gICAgICAgIHNyYy1yZWRlZmluZS41LmIuYSA9IHNyYy1yZWRlZmluZS41LmIuYTogbm9uIFx1MDBFOCBzdGF0byB0cm92YXRvIGFsY3VuIGVsZW1lbnRvIGZpZ2xpbyBkaSBub24gYW5ub3RhemlvbmUgZGkgdGlwbyA8Y29tcGxleFR5cGU+LiBHbGkgZWxlbWVudGkgZmlnbGlvIDxjb21wbGV4VHlwZT4gZGkgZWxlbWVudGkgPHJlZGVmaW5lPiBkZXZvbm8gYXZlcmUgZGlzY2VuZGVudGkgPGV4dGVuc2lvbj4gbyA8cmVzdHJpY3Rpb24+LCBjb24gYXR0cmlidXRpICdiYXNlJyBjaGUgZmFubm8gcmlmZXJpbWVudG8gYSBzXHUwMEU5IHN0ZXNzaS4KLSAgICAgICAgc3JjLXJlZGVmaW5lLjUuYi5iID0gc3JjLXJlZGVmaW5lLjUuYi5iOiBub24gXHUwMEU4IHN0YXRvIHRyb3ZhdG8gYWxjdW4gZWxlbWVudG8gbmlwb3RlIGRpIG5vbiBhbm5vdGF6aW9uZSBkaSB0aXBvIDxjb21wbGV4VHlwZT4uIEdsaSBlbGVtZW50aSBmaWdsaW8gPGNvbXBsZXhUeXBlPiBkaSBlbGVtZW50aSA8cmVkZWZpbmU+IGRldm9ubyBhdmVyZSBkaXNjZW5kZW50aSA8ZXh0ZW5zaW9uPiBvIDxyZXN0cmljdGlvbj4sIGNvbiBhdHRyaWJ1dGkgJ2Jhc2UnIGNoZSBmYW5ubyByaWZlcmltZW50byBhIHNcdTAwRTkgc3Rlc3NpLgotICAgICAgICBzcmMtcmVkZWZpbmUuNS5iLmMgPSBzcmMtcmVkZWZpbmUuNS5iLmM6ICcnezB9Jycgbm9uIFx1MDBFOCB1biBlbGVtZW50byBuaXBvdGUgdmFsaWRvLiBHbGkgZWxlbWVudGkgZmlnbGlvIDxjb21wbGV4VHlwZT4gZGkgZWxlbWVudGkgPHJlZGVmaW5lPiBkZXZvbm8gYXZlcmUgZGlzY2VuZGVudGkgPGV4dGVuc2lvbj4gbyA8cmVzdHJpY3Rpb24+LCBjb24gYXR0cmlidXRpICcnYmFzZScnIGNoZSBmYW5ubyByaWZlcmltZW50byBhIHNcdTAwRTkgc3Rlc3NpLgotICAgICAgICBzcmMtcmVkZWZpbmUuNS5iLmQgPSBzcmMtcmVkZWZpbmUuNS5iLmQ6ICcnezB9Jycgbm9uIGRpc3BvbmUgZGkgdW4gYXR0cmlidXRvICJiYXNlIiBjaGUgZmEgcmlmZXJpbWVudG8gYWxsJydlbGVtZW50byByaWRlZmluaXRvICcnezF9JycuIEdsaSBlbGVtZW50aSBmaWdsaW8gPGNvbXBsZXhUeXBlPiBkaSBlbGVtZW50aSA8cmVkZWZpbmU+IGRldm9ubyBhdmVyZSBkaXNjZW5kZW50aSA8ZXh0ZW5zaW9uPiBvIDxyZXN0cmljdGlvbj4sIGNvbiBhdHRyaWJ1dGkgJydiYXNlJycgY2hlIGZhbm5vIHJpZmVyaW1lbnRvIGEgc1x1MDBFOSBzdGVzc2kuCi0gICAgICAgIHNyYy1yZWRlZmluZS42LjEuMSA9IHNyYy1yZWRlZmluZS42LjEuMTogc2UgdW4gZWxlbWVudG8gZmlnbGlvIGRlbCBncnVwcG8gZGkgdW4gZWxlbWVudG8gPHJlZGVmaW5lPiBjb250aWVuZSB1biBncnVwcG8gY2hlIGZhIHJpZmVyaW1lbnRvIGEgc1x1MDBFOSBzdGVzc28sIGRldmUgYXZlcm5lIGVzYXR0YW1lbnRlIHVubywgbWVudHJlIHF1ZXN0byBuZSBoYSAiezB9Ii4KLSAgICAgICAgc3JjLXJlZGVmaW5lLjYuMS4yID0gc3JjLXJlZGVmaW5lLjYuMS4yOiBpbCBncnVwcG8gInswfSIgY2hlIGNvbnRpZW5lIHVuIHJpZmVyaW1lbnRvIGEgdW4gZ3J1cHBvIGluIGZhc2UgZGkgcmlkZWZpbml6aW9uZSBkZXZlIGF2ZXJlIG1pbk9jY3VycyA9IG1heE9jY3VycyA9IDEuCi0gICAgICAgIHNyYy1yZWRlZmluZS42LjIuMSA9IHNyYy1yZWRlZmluZS42LjIuMTogbmVzc3VuIGdydXBwbyBuZWxsbyBzY2hlbWEgcmlkZWZpbml0byBjb24gbm9tZSBjb3JyaXNwb25kZW50ZSBhICJ7MH0iLgotICAgICAgICBzcmMtcmVkZWZpbmUuNi4yLjIgPSBzcmMtcmVkZWZpbmUuNi4yLjI6IGlsIGdydXBwbyAiezB9IiBub24gbGltaXRhIGNvcnJldHRhbWVudGUgaWwgZ3J1cHBvIGNoZSByaWRlZmluaXNjZTsgdmluY29sbyB2aW9sYXRvOiAiezF9Ii4KLSAgICAgICAgc3JjLXJlZGVmaW5lLjcuMSA9IHNyYy1yZWRlZmluZS43LjE6IHNlIHVuIGVsZW1lbnRvIGZpZ2xpbyBhdHRyaWJ1dGVHcm91cCBkaSB1biBlbGVtZW50byA8cmVkZWZpbmU+IGNvbnRpZW5lIHVuIGF0dHJpYnV0ZUdyb3VwIGNoZSBmYSByaWZlcmltZW50byBhIHNcdTAwRTkgc3Rlc3NvLCBkZXZlIGF2ZXJuZSBlc2F0dGFtZW50ZSB1bm8sIG1lbnRyZSBxdWVzdG8gbmUgaGEgInswfSIuCi0gICAgICAgIHNyYy1yZWRlZmluZS43LjIuMSA9IHNyYy1yZWRlZmluZS43LjIuMTogbmVzc3VuIGF0dHJpYnV0ZUdyb3VwIG5lbGxvIHNjaGVtYSByaWRlZmluaXRvIGNvbiBub21lIGNvcnJpc3BvbmRlbnRlIGEgInswfSIuCi0gICAgICAgIHNyYy1yZWRlZmluZS43LjIuMiA9IHNyYy1yZWRlZmluZS43LjIuMjogQXR0cmlidXRlR3JvdXAgInswfSIgbm9uIGxpbWl0YSBjb3JyZXR0YW1lbnRlIGwnJ0F0dHJpYnV0ZUdyb3VwIGNoZSByaWRlZmluaXNjZTsgdmluY29sbyB2aW9sYXRvOiAiezF9Ii4KLSAgICAgICAgc3JjLXJlc29sdmUgPSBzcmMtcmVzb2x2ZTogaW1wb3NzaWJpbGUgcmlzb2x2ZXJlIGlsIG5vbWUgInswfSIgaW4gdW4gY29tcG9uZW50ZSB7MX0uCi0gICAgICAgIHNyYy1yZXNvbHZlLjQuMSA9IHNyYy1yZXNvbHZlLjQuMTogZXJyb3JlIGR1cmFudGUgbGEgcmlzb2x1emlvbmUgZGVsIGNvbXBvbmVudGUgJyd7Mn0nJy4gXHUwMEM4IHN0YXRvIHJpbGV2YXRvIGNoZSAnJ3syfScnIG5vbiBkaXNwb25lIGRpIHVubyBzcGF6aW8gZGkgbm9taSwgbWEgYWkgY29tcG9uZW50aSBzZW56YSBzcGF6aSBkaSBub21pIGRpIGRlc3RpbmF6aW9uZSBub24gXHUwMEU4IHBvc3NpYmlsZSBmYXJlIHJpZmVyaW1lbnRvIGRhbCBkb2N1bWVudG8gZGkgc2NoZW1hICcnezB9JycuIFNlIFx1MDBFOCBwcmV2aXN0byBjaGUgJyd7Mn0nJyBhYmJpYSB1bm8gc3BhemlvIGRpIG5vbWksIFx1MDBFOCBwcm9iYWJpbGUgY2hlIHNpYSBuZWNlc3NhcmlvIHNwZWNpZmljYXJlIHVuIHByZWZpc3NvLiBTZSwgaW52ZWNlLCBcdTAwRTggcHJldmlzdG8gY2hlICcnezJ9Jycgbm9uIGFiYmlhIHVubyBzcGF6aW8gZGkgbm9taSwgYWdnaXVuZ2VyZSAnJ2ltcG9ydCcnIHNlbnphIHVuIGF0dHJpYnV0byAibmFtZXNwYWNlIiBhICcnezB9JycuCi0gICAgICAgIHNyYy1yZXNvbHZlLjQuMiA9IHNyYy1yZXNvbHZlLjQuMjogZXJyb3JlIGR1cmFudGUgbGEgcmlzb2x1emlvbmUgZGVsIGNvbXBvbmVudGUgJyd7Mn0nJy4gXHUwMEM4IHN0YXRvIHJpbGV2YXRvIGNoZSAnJ3syfScnIHNpIHRyb3ZhIG5lbGxvIHNwYXppbyBkaSBub21pICcnezF9JycsIG1hIGFpIGNvbXBvbmVudGkgZGkgcXVlc3RvIHNwYXppbyBkaSBub21pIGRpIGRlc3RpbmF6aW9uZSBub24gXHUwMEU4IHBvc3NpYmlsZSBmYXJlIHJpZmVyaW1lbnRvIGRhbCBkb2N1bWVudG8gZGkgc2NoZW1hICcnezB9JycuIFNlIHF1ZXN0byBzcGF6aW8gZGkgbm9taSBcdTAwRTggZXJyYXRvLCBcdTAwRTggcHJvYmFiaWxlIGNoZSBzaWEgbmVjZXNzYXJpbyBtb2RpZmljYXJlIGlsIHByZWZpc3NvICcnezJ9JycuIFNlIGxvIHNwYXppbyBkaSBub21pIFx1MDBFOCBjb3JyZXR0bywgYWdnaXVuZ2VyZSBsYSB0YWcgJydpbXBvcnQnJyBhZGVndWF0YSBhICcnezB9JycuCi0gICAgICAgIHNyYy1zaW1wbGUtdHlwZS4yLmEgPSBzcmMtc2ltcGxlLXR5cGUuMi5hOiBcdTAwRTggc3RhdG8gdHJvdmF0byB1biBlbGVtZW50byA8cmVzdHJpY3Rpb24+IGNoZSBjb250aWVuZSBzaWEgdW4gW2F0dHJpYnV0ZV0gZGkgYmFzZSBjaGUgdW4gZWxlbWVudG8gPHNpbXBsZVR5cGU+IHRyYSBpIHJpc3BldHRpdmkgW2NoaWxkcmVuXS4gXHUwMEM4IGNvbnNlbnRpdG8gc29sbyB1bm8uCi0gICAgICAgIHNyYy1zaW1wbGUtdHlwZS4yLmIgPSBzcmMtc2ltcGxlLXR5cGUuMi5iOiBcdTAwRTggc3RhdG8gdHJvdmF0byB1biBlbGVtZW50byA8cmVzdHJpY3Rpb24+IGNoZSBub24gY29udGllbmUgblx1MDBFOSB1biBbYXR0cmlidXRlXSBkaSBiYXNlIG5cdTAwRTkgdW4gZWxlbWVudG8gPHNpbXBsZVR5cGU+IHRyYSBpIHJpc3BldHRpdmkgW2NoaWxkcmVuXS4gTmUgXHUwMEU4IHJpY2hpZXN0byB1bm8uCi0gICAgICAgIHNyYy1zaW1wbGUtdHlwZS4zLmEgPSBzcmMtc2ltcGxlLXR5cGUuMy5hOiBcdTAwRTggc3RhdG8gdHJvdmF0byB1biBlbGVtZW50byA8bGlzdD4gY2hlIGNvbnRpZW5lIHNpYSB1biBbYXR0cmlidXRlXSBpdGVtVHlwZSBjaGUgdW4gZWxlbWVudG8gPHNpbXBsZVR5cGU+IHRyYSBpIHJpc3BldHRpdmkgW2NoaWxkcmVuXS4gXHUwMEM4IGNvbnNlbnRpdG8gc29sbyB1bm8uCi0gICAgICAgIHNyYy1zaW1wbGUtdHlwZS4zLmIgPSBzcmMtc2ltcGxlLXR5cGUuMy5iOiBcdTAwRTggc3RhdG8gdHJvdmF0byB1biBlbGVtZW50byA8bGlzdD4gY2hlIG5vbiBjb250aWVuZSBuXHUwMEU5IHVuIFthdHRyaWJ1dGVdIGl0ZW1UeXBlIG5cdTAwRTkgdW4gZWxlbWVudG8gPHNpbXBsZVR5cGU+IHRyYSBpIHJpc3BldHRpdmkgW2NoaWxkcmVuXS4gTmUgXHUwMEU4IHJpY2hpZXN0byB1bm8uCi0gICAgICAgIHNyYy1zaW5nbGUtZmFjZXQtdmFsdWUgPSBzcmMtc2luZ2xlLWZhY2V0LXZhbHVlOiBpbCBmYWNldCAnJ3swfScnIFx1MDBFOCBzdGF0byBkZWZpbml0byBwaVx1MDBGOSB2b2x0ZS4KLSAgICAgICAgc3JjLXVuaW9uLW1lbWJlclR5cGVzLW9yLXNpbXBsZVR5cGVzID0gc3JjLXVuaW9uLW1lbWJlclR5cGVzLW9yLXNpbXBsZVR5cGVzOiB1biBlbGVtZW50byA8dW5pb24+IGRldmUgYXZlcmUgdW4gW2F0dHJpYnV0ZV0gbWVtYmVyVHlwZXMgbm9uIHZ1b3RvIG8gYWxtZW5vIHVuIGVsZW1lbnRvIDxzaW1wbGVUeXBlPiB0cmEgaSByaXNwZXR0aXZpIFtjaGlsZHJlbl0uCi0KLSNjb25zdHJhaW50IHZhbGlkICgzLlguNikKLQotICAgICAgICBhZy1wcm9wcy1jb3JyZWN0LjIgPSBhZy1wcm9wcy1jb3JyZWN0LjI6IGVycm9yZSBwZXIgaWwgZ3J1cHBvIGRpIGF0dHJpYnV0aSAiezB9Ii4gU29ubyBzcGVjaWZpY2F0aSB1c2kgZGkgYXR0cmlidXRpIGR1cGxpY2F0aSBjb24gbG8gc3Rlc3NvIG5vbWUgZSBzcGF6aW8gZGkgbm9taSBkaSBkZXN0aW5hemlvbmUuIElsIG5vbWUgZGVsbCcndXNvIGRlbGwnJ2F0dHJpYnV0byBkdXBsaWNhdG8gXHUwMEU4ICJ7MX0iLgotICAgICAgICBhZy1wcm9wcy1jb3JyZWN0LjMgPSBhZy1wcm9wcy1jb3JyZWN0LjM6IGVycm9yZSBwZXIgaWwgZ3J1cHBvIGRpIGF0dHJpYnV0aSAiezB9Ii4gRHVlIGRpY2hpYXJhemlvbmkgZGkgYXR0cmlidXRvLCAiezF9IiBlICJ7Mn0iIGhhbm5vIHRpcGkgZGVyaXZhdGkgZGFsbCcnSUQuCi0gICAgICAgIGEtcHJvcHMtY29ycmVjdC4yID0gYS1wcm9wcy1jb3JyZWN0LjI6IHZhbG9yZSBkaSB2aW5jb2xvIGRpIHZhbG9yZSAiezF9IiBub24gdmFsaWRvIG5lbGwnJ2F0dHJpYnV0byAiezB9Ii4KLSAgICAgICAgYS1wcm9wcy1jb3JyZWN0LjMgPSBhLXByb3BzLWNvcnJlY3QuMzogbCcnYXR0cmlidXRvICcnezB9Jycgbm9uIHB1XHUwMEYyIHV0aWxpenphcmUgaWwgdmFsb3JlICcnZml4ZWQnJyBvICcnZGVmYXVsdCcnIHBvaWNoXHUwMEU5IGxhICd7J3R5cGUgZGVmaW5pdGlvbid9JyBkZWxsJydhdHRyaWJ1dG8gXHUwMEU4IHVuIElEIG8gXHUwMEU4IGRlcml2YXRhIGRhbGwnJ0lELgotICAgICAgICBhdS1wcm9wcy1jb3JyZWN0LjIgPSBhdS1wcm9wcy1jb3JyZWN0LjI6IG5lbGxhIGRpY2hpYXJhemlvbmUgZGkgYXR0cmlidXRvIGRpICcnezB9JycgXHUwMEU4IHN0YXRvIHNwZWNpZmljYXRvIHVuIHZhbG9yZSBmaXNzbyAnJ3sxfScnLiBTZSwgcGVydGFudG8sIGwnJ3VzbyBkZWxsJydhdHRyaWJ1dG8gY2hlIGZhIHJpZmVyaW1lbnRvIGEgJyd7MH0nJyBoYSBhbmNoZSB1biB2YWxvcmUgJ3sndmFsdWUgY29uc3RyYWludCd9JywgZGV2ZSBlc3NlcmUgZmlzc28gZSBpbCBzdW8gdmFsb3JlIGRldmUgZXNzZXJlICcnezF9JycuCi0gICAgICAgIGNvcy1hbGwtbGltaXRlZC4xLjIgPSBjb3MtYWxsLWxpbWl0ZWQuMS4yOiBkZXZlIGFwcGFyaXJlIHVuIGdydXBwbyBkaSBtb2RlbGxpICdhbGwnIGluIHVuYSBwYXJ0ZSBjb24gJ3snbWluIG9jY3Vycyd9JyA9ICd7J21heCBvY2N1cnMnfScgPSAxIGUgbGEgcGFydGUgZGV2ZSBmYXIgcGFydGUgZGkgdW5hIGNvcHBpYSBjaGUgY29zdGl0dWlzY2EgaWwgJ3snY29udGVudCB0eXBlJ30nIGRpIHVuYSBkZWZpbml6aW9uZSBkaSB0aXBvIGNvbXBsZXNzby4KLSAgICAgICAgY29zLWFsbC1saW1pdGVkLjIgPSBjb3MtYWxsLWxpbWl0ZWQuMjogaWwgdmFsb3JlICd7J21heCBvY2N1cnMnfScgZGkgdW4gZWxlbWVudG8gaW4gdW4gZ3J1cHBvIGRpIG1vZGVsbGkgJydhbGwnJyBkZXZlIGVzc2VyZSAwIG8gMS4gSWwgdmFsb3JlICcnezB9JycgcGVyIGwnJ2VsZW1lbnRvICcnezF9Jycgbm9uIFx1MDBFOCB2YWxpZG8uCi0gICAgICAgIGNvcy1hcHBsaWNhYmxlLWZhY2V0cyA9IGNvcy1hcHBsaWNhYmxlLWZhY2V0czogZmFjZXQgJyd7MH0nJyBub24gY29uc2VudGl0byBkYWwgdGlwbyB7MX0uCi0gICAgICAgIGNvcy1jdC1leHRlbmRzLjEuMSA9IGNvcy1jdC1leHRlbmRzLjEuMTogaWwgdGlwbyAnJ3swfScnIFx1MDBFOCBzdGF0byBkZXJpdmF0byBtZWRpYW50ZSBlc3RlbnNpb25lIGRhbCB0aXBvICcnezF9JycsIG1hIGwnJ2F0dHJpYnV0byAiZmluYWwiIGRpICcnezF9JycgaW1wZWRpc2NlIGxhIGRlcml2YXppb25lIG1lZGlhbnRlIGVzdGVuc2lvbmUuCi0gICAgICAgIGNvcy1jdC1leHRlbmRzLjEuNC4zLjIuMi4xLmEgPSBjb3MtY3QtZXh0ZW5kcy4xLjQuMy4yLjIuMS5hOiBJbCB0aXBvIGRpIGNvbnRlbnV0byBkaSB1biB0aXBvIGRlcml2YXRvIGUgcXVlbGxvIGRlbGxhIHJpc3BldHRpdmEgYmFzZSBkZXZvbm8gZXNzZXJlIGVudHJhbWJpIG1pc3RpIG8gZGkgc29saSBlbGVtZW50aS4gSWwgdGlwbyAnJ3swfScnIFx1MDBFOCBkaSBzb2xpIGVsZW1lbnRpLCBtZW50cmUgbGEgcmlzcGV0dGl2YSBiYXNlIG5vbiBsbyBcdTAwRTguCi0gICAgICAgIGNvcy1jdC1leHRlbmRzLjEuNC4zLjIuMi4xLmIgPSBjb3MtY3QtZXh0ZW5kcy4xLjQuMy4yLjIuMS5iOiBJbCB0aXBvIGRpIGNvbnRlbnV0byBkaSB1biB0aXBvIGRlcml2YXRvIGUgcXVlbGxvIGRlbGxhIHJpc3BldHRpdmEgYmFzZSBkZXZvbm8gZXNzZXJlIGVudHJhbWJpIG1pc3RpIG8gZGkgc29saSBlbGVtZW50aS4gSWwgdGlwbyAnJ3swfScnIFx1MDBFOCBtaXN0bywgbWVudHJlIGxhIHJpc3BldHRpdmEgYmFzZSBub24gbG8gXHUwMEU4LgotICAgICAgICBjb3MtZWxlbWVudC1jb25zaXN0ZW50ID0gY29zLWVsZW1lbnQtY29uc2lzdGVudDogZXJyb3JlIHBlciBpbCB0aXBvICJ7MH0iLiBOZWwgZ3J1cHBvIGRpIG1vZGVsbGkgYXBwYWlvbm8gcGlcdTAwRjkgZWxlbWVudGkgY29uIG5vbWUgInsxfSIgZSB0aXBpIGRpdmVyc2kuCi0gICAgICAgIGNvcy1saXN0LW9mLWF0b21pYyA9IGNvcy1saXN0LW9mLWF0b21pYzogbmVsbGEgZGVmaW5pemlvbmUgZGVsIHRpcG8gZGkgbGlzdGEgJyd7MH0nJywgaWwgdGlwbyAnJ3sxfScnIG5vbiBcdTAwRTggdmFsaWRvIHBvaWNoXHUwMEU5IG5vbiBcdTAwRTggaW5kaXZpc2liaWxlICgnJ3sxfScnIFx1MDBFOCB1biB0aXBvIGRpIGxpc3RhIG8gdW4gdGlwbyBkaSB1bmlvbmUgY2hlIGNvbnRpZW5lIHVuYSBsaXN0YSkuCi0gICAgICAgIGNvcy1ub25hbWJpZyA9IGNvcy1ub25hbWJpZzogezB9IGUgezF9IChvIGdsaSBlbGVtZW50aSBkZXJpdmFudGkgZGFsIGdydXBwbyBkaSBzb3N0aXR1emlvbmUpIHZpb2xhbm8gIlVuaXF1ZSBQYXJ0aWNsZSBBdHRyaWJ1dGlvbiIuIER1cmFudGUgbGEgY29udmFsaWRhIHN1IHF1ZXN0byBzY2hlbWEsIHNpIGNyZWVyZWJiZSB1bicnYW1iaWd1aXRcdTAwRTAgcGVyIGxlIGR1ZSBwYXJ0aS4KLSAgICAgICAgY29zLXBhcnRpY2xlLXJlc3RyaWN0LmEgPSBjb3MtcGFydGljbGUtcmVzdHJpY3QuYTogbGEgcGFydGUgZGVyaXZhdGEgXHUwMEU4IHZ1b3RhLCBtZW50ZSBsYSBiYXNlIG5vbiBcdTAwRTggc3Z1b3RhYmlsZS4KLSAgICAgICAgY29zLXBhcnRpY2xlLXJlc3RyaWN0LmIgPSBjb3MtcGFydGljbGUtcmVzdHJpY3QuYjogbGEgcGFydGUgZGVsbGEgYmFzZSBcdTAwRTggdnVvdGEsIG1lbnRlIGxhIHBhcnRlIGRlcml2YXRhIG5vbiBsbyBcdTAwRTguCi0gICAgICAgIGNvcy1wYXJ0aWNsZS1yZXN0cmljdC4yID0gY29zLXBhcnRpY2xlLXJlc3RyaWN0LjI6IGxpbWl0YXppb25lIGRpIHBhcnRlIHZpZXRhdGE6ICcnezB9JycuCi0gICAgICAgIGNvcy1zdC1yZXN0cmljdHMuMS4xID0gY29zLXN0LXJlc3RyaWN0cy4xLjE6IGlsIHRpcG8gJyd7MX0nJyBcdTAwRTggaW5kaXZpc2liaWxlLCBxdWluZGkgbGEgJ3snYmFzZSB0eXBlIGRlZmluaXRpb24nfScgInswfSIgZGV2ZSBlc3NlcmUgdW5hIGRlZmluaXppb25lIGRpIHRpcG8gc2VtcGxpY2UgaW5kaXZpc2liaWxlIG8gdW4gdGlwbyBkaSBkYXRpIHByZWRlZmluaXRvIGluY29ycG9yYXRvLgotICAgICAgICBjb3Mtc3QtcmVzdHJpY3RzLjIuMSA9IGNvcy1zdC1yZXN0cmljdHMuMi4xOiBuZWxsYSBkZWZpbml6aW9uZSBkZWwgdGlwbyBkaSBsaXN0YSAnJ3swfScnLCBpbCB0aXBvICcnezF9Jycgbm9uIFx1MDBFOCB2YWxpZG8gcG9pY2hcdTAwRTkgXHUwMEU4IHVuIHRpcG8gZGkgbGlzdGEgbyB1biB0aXBvIGRpIHVuaW9uZSBjaGUgY29udGllbmUgdW5hIGxpc3RhLgotICAgICAgICBjb3Mtc3QtcmVzdHJpY3RzLjIuMy4xLjEgPSBjb3Mtc3QtcmVzdHJpY3RzLjIuMy4xLjE6IGlsIGNvbXBvbmVudGUgJ3snZmluYWwnfScgZGkgJ3snaXRlbSB0eXBlIGRlZmluaXRpb24nfScgJyd7MH0nJyBjb250aWVuZSAnJ2xpc3QnJywgcGVydGFudG8gJyd7MH0nJyBub24gcHVcdTAwRjIgZXNzZXJlIHV0aWxpenphdG8gY29tZSB0aXBvIGRpIGVsZW1lbnRvIHBlciBpbCB0aXBvIGRpIGxpc3RhICcnezF9JycuCi0gICAgICAgIGNvcy1zdC1yZXN0cmljdHMuMy4zLjEuMSA9IGNvcy1zdC1yZXN0cmljdHMuMy4zLjEuMTogaWwgY29tcG9uZW50ZSAneydmaW5hbCd9JyBkaSAneydtZW1iZXIgdHlwZSBkZWZpbml0aW9ucyd9JyAnJ3swfScnIGNvbnRpZW5lICcndW5pb24nJywgcGVydGFudG8gJyd7MH0nJyBub24gcHVcdTAwRjIgZXNzZXJlIHV0aWxpenphdG8gY29tZSB0aXBvIGRpIG1lbWJybyBwZXIgaWwgdGlwbyBkaSB1bmlvbmUgJyd7MX0nJy4KLSAgICAgICAgY29zLXZhbGlkLWRlZmF1bHQuMi4xID0gY29zLXZhbGlkLWRlZmF1bHQuMi4xOiBsJydlbGVtZW50byAiezB9IiBoYSB1biB2aW5jb2xvIGRpIHZhbG9yZSBlIGRldmUgYXZlcmUgdW4gbW9kZWxsbyBkaSBjb250ZW51dG8gbWlzdG8gbyBzZW1wbGljZS4KLSAgICAgICAgY29zLXZhbGlkLWRlZmF1bHQuMi4yLjIgPSBjb3MtdmFsaWQtZGVmYXVsdC4yLjIuMjogbCcnZWxlbWVudG8gJyd7MH0nJyBoYSB1biAneyd2YWx1ZSBjb25zdHJhaW50J30nIGUgbGEgcmlzcGV0dGl2YSBkZWZpbml6aW9uZSBkZWwgdGlwbyBjb250aWVuZSAneydjb250ZW50IHR5cGUnfScgbWlzdG8sIHF1aW5kaSBsYSBwYXJ0ZSBkaSAneydjb250ZW50IHR5cGUnfScgZGV2ZSBlc3NlcmUgc3Z1b3RhYmlsZS4KLSAgICAgICAgYy1wcm9wcy1jb3JyZWN0LjIgPSBjLXByb3BzLWNvcnJlY3QuMjogbGEgY2FyZGluYWxpdFx1MDBFMCBkZWkgY2FtcGkgcGVyIGlsIGtleXJlZiAiezB9IiBlIHBlciBsYSBjaGlhdmUgInsxfSIgZGV2ZSBjb3JyaXNwb25kZXJlLgotICAgICAgICBjdC1wcm9wcy1jb3JyZWN0LjMgPSBjdC1wcm9wcy1jb3JyZWN0LjM6IHNvbm8gc3RhdGUgcmlsZXZhdGUgZGVmaW5pemlvbmkgY2lyY29sYXJpIHBlciBpbCB0aXBvIGNvbXBsZXNzbyAnJ3swfScnLiBDaVx1MDBGMiBzaWduaWZpY2EgY2hlICcnezB9Jycgc2kgdHJvdmEgYWxsJydpbnRlcm5vIGRlbGxhIHN1YSBzdGVzc2EgZ2VyYXJjaGlhIGRpIHRpcGksIGlsIGNoZSBcdTAwRTggZXJyYXRvLgotICAgICAgICBjdC1wcm9wcy1jb3JyZWN0LjQgPSBjdC1wcm9wcy1jb3JyZWN0LjQ6IGVycm9yZSBwZXIgaWwgdGlwbyAiezB9Ii4gU29ubyBzcGVjaWZpY2F0aSB1c2kgZGkgYXR0cmlidXRpIGR1cGxpY2F0aSBjb24gbG8gc3Rlc3NvIG5vbWUgZSBzcGF6aW8gZGkgbm9taSBkaSBkZXN0aW5hemlvbmUuIElsIG5vbWUgZGVsbCcndXNvIGRlbGwnJ2F0dHJpYnV0byBkdXBsaWNhdG8gXHUwMEU4ICJ7MX0iLgotICAgICAgICBjdC1wcm9wcy1jb3JyZWN0LjUgPSBjdC1wcm9wcy1jb3JyZWN0LjU6IGVycm9yZSBwZXIgaWwgdGlwbyAiezB9Ii4gRHVlIGRpY2hpYXJhemlvbmkgZGkgYXR0cmlidXRvLCAiezF9IiBlICJ7Mn0iIGhhbm5vIHRpcGkgZGVyaXZhdGkgZGFsbCcnSUQuCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMSA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMTogaWwgdGlwbyAnJ3swfScnIFx1MDBFOCBzdGF0byBkZXJpdmF0byBtZWRpYW50ZSBsaW1pdGF6aW9uZSBkYWwgdGlwbyAnJ3sxfScnLCBtYSAnJ3sxfScnIGhhIHVuYSBwcm9wcmlldFx1MDBFMCAneydmaW5hbCd9JyBjaGUgaW1wZWRpc2NlIGxhIGRlcml2YXppb25lIG1lZGlhbnRlIGxpbWl0YXppb25lLgotICAgICAgICBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjIuMS4xID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4yLjEuMTogZXJyb3JlIHBlciBpbCB0aXBvICJ7MH0iLiBVbiB1c28gZGVsbCcnYXR0cmlidXRvICcnezF9JycgaW4gcXVlc3RvIHRpcG8gaGEgdW4gdmFsb3JlICJ1c2UiICcnezJ9JycgY2hlIFx1MDBFOCBpbmNvZXJlbnRlIGNvbiBpbCB2YWxvcmUgZGkgJydyZXF1aXJlZCcnIGluIHVuIHVzbyBjb3JyaXNwb25kZW50ZSBkZWxsJydhdHRyaWJ1dG8gbmVsIHRpcG8gZGkgYmFzZS4KLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4yLjEuMiA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMi4xMjogZXJyb3JlIHBlciBpbCB0aXBvICJ7MH0iLiBVbiB1c28gZGVsbCcnYXR0cmlidXRvICcnezF9JycgaW4gcXVlc3RvIHRpcG8gaGEgdW4gdmFsb3JlIHRpcG8gJyd7Mn0nJyBjaGUgXHUwMEU4IHN0YXRvIGRlcml2YXRvIGluIG1vZG8gdmFsaWRvIGRhICcnezN9JycsIG92dmVybyBkYWwgdGlwbyBkaSB1c28gY29ycmlzcG9uZGVudGUgZGVsbCcnYXR0cmlidXRvIG5lbCB0aXBvIGRpIGJhc2UuCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMi4xLjMuYSA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMi4xLjMuYTogZXJyb3JlIHBlciBpbCB0aXBvICJ7MH0iLiBMJyd1c28gZGVsbCcnYXR0cmlidXRvICcnezF9JycgaW4gcXVlc3RvIHRpcG8gaGEgdW4gdmluY29sbyBkaSB2YWxvcmUgZWZmZXR0aXZvIGNoZSBcdTAwRTggZmlzc28sIG1lbnRyZSBpbCB2aW5jb2xvIGRpIHZhbG9yZSBlZmZldHRpdm8gZGVsbCcndXNvIGRlbGwnJ2F0dHJpYnV0byBjb3JyaXNwb25kZW50ZSBuZWwgdGlwbyBkaSBiYXNlIFx1MDBFOCBmaXNzby4KLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4yLjEuMy5iID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4yLjEuMy5iOiBlcnJvcmUgcGVyIGlsIHRpcG8gInswfSIuIEwnJ3VzbyBkZWxsJydhdHRyaWJ1dG8gJyd7MX0nJyBpbiBxdWVzdG8gdGlwbyBoYSB1biB2aW5jb2xvIGRpIHZhbG9yZSBlZmZldHRpdm8gZmlzc28gY29uIHZhbG9yZSAnJ3syfScnLCBjaGUgXHUwMEU4IGluY29lcmVudGUgY29uIGlsIHZhbG9yZSAnJ3szfScnIHBlciBpbCB2aW5jb2xvIGRpIHZhbG9yZSBlZmZldHRpdm8gZmlzc28gZGVsbCcndXNvIGRlbGwnJ2F0dHJpYnV0byBjb3JyaXNwb25kZW50ZSBuZWwgdGlwbyBkaSBiYXNlLgotICAgICAgICBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjIuMi5hID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4yLjIuYTogZXJyb3JlIHBlciBpbCB0aXBvICJ7MH0iLiBMJyd1c28gZGVsbCcnYXR0cmlidXRvICcnezF9JycgaW4gcXVlc3RvIHRpcG8gbm9uIGhhIHVuIHVzbyBkZWxsJydhdHRyaWJ1dG8gY29ycmlzcG9uZGVudGUgbmVsbGEgYmFzZSBlIGlsIHRpcG8gZGkgYmFzZSBub24gaGEgYWxjdW4gYXR0cmlidXRvIGRpIGNhcmF0dGVyZSBqb2xseS4KLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4yLjIuYiA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMi4yLmI6IGVycm9yZSBwZXIgaWwgdGlwbyAiezB9Ii4gTCcndXNvIGRlbGwnJ2F0dHJpYnV0byAnJ3sxfScnIGluIHF1ZXN0byB0aXBvIG5vbiBoYSB1biB1c28gZGVsbCcnYXR0cmlidXRvIGNvcnJpc3BvbmRlbnRlIG5lbGxhIGJhc2UgZSBpbCBjYXJhdHRlcmUgam9sbHkgbmVsIHRpcG8gZGkgYmFzZSBub24gY29uc2VudGUgbG8gc3BhemlvIGRpIG5vbWkgJyd7Mn0nJyBkaSBxdWVzdG8gdXNvIGRlbGwnJ2F0dHJpYnV0by4KLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4zID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4zOiBlcnJvcmUgcGVyIGlsIHRpcG8gInswfSIuIE5lbGwnJ3VzbyBkZWxsJydhdHRyaWJ1dG8gJyd7MX0nJyBuZWwgdGlwbyBkaSBiYXNlLCBSRVFVSVJFRCBcdTAwRTggaW1wb3N0YXRvIHN1IHRydWUsIG1hIG5vbiBlc2lzdGUgYWxjdW4gdXNvIGRlbGwnJ2F0dHJpYnV0byBjb3JyaXNwb25kZW50ZSBuZWwgdGlwbyBkZXJpdmF0by4KLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi40LjEgPSBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjQuMTogZXJyb3JlIHBlciBpbCB0aXBvICJ7MH0iLiBMYSBkZXJpdmF6aW9uZSBoYSB1biBjYXJhdHRlcmUgam9sbHkgZGVsbCcnYXR0cmlidXRvLCBtYSBsYSBiYXNlIG5vbiBuZSBoYSB1bm8uCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uNC4yID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi40LjI6IGVycm9yZSBwZXIgaWwgdGlwbyAiezB9Ii4gSWwgY2FyYXR0ZXJlIGpvbGx5IG5lbGxhIGRlcml2YXppb25lIG5vbiBcdTAwRTggdW4gc3Vic2V0IGRpIGNhcmF0dGVyaSBqb2xseSB2YWxpZG8gZGkgcXVlbGxvIG5lbGxhIGJhc2UuCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uNC4zID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi40LjM6IGVycm9yZSBwZXIgaWwgdGlwbyAiezB9Ii4gSWwgY29udGVudXRvIGRlbCBwcm9jZXNzbyBkZWwgY2FyYXR0ZXJlIGpvbGx5IG5lbGxhIGRlcml2YXppb25lICh7MX0pIFx1MDBFOCBwaVx1MDBGOSBkZWJvbGUgZGkgcXVlbGxvIG5lbGxhIGJhc2UgKHsyfSkuCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uNS4yLjIuMSA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uNS4yLjIuMTogZXJyb3JlIHBlciBpbCB0aXBvICcnezB9JycuIElsIHRpcG8gZGkgY29udGVudXRvIHNlbXBsaWNlICcnZGVsIHRpcG8gJyd7MX0nJyBub24gXHUwMEU4IHVuYSBsaW1pdGF6aW9uZSB2YWxpZGEgZGVsIHRpcG8gZGkgY29udGVudXRvIHNlbXBsaWNlIGRlbGxhIGJhc2UgJyd7Mn0nJy4KLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi41LjMuMiA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uNS4zLjI6IGVycm9yZSBwZXIgaWwgdGlwbyAnJ3swfScnLiBJbCB0aXBvIGRpIGNvbnRlbnV0byBkaSBxdWVzdG8gdGlwbyBcdTAwRTggdnVvdG8sIG1hIGlsIHRpcG8gZGkgY29udGVudXRvIGRlbGxhIGJhc2UgJyd7MX0nJyBub24gXHUwMEU4IHZ1b3RvIG8gc3Z1b3RhYmlsZS4KLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi41LjQuMS4yID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi41LjQuMS4yOiBlcnJvcmUgcGVyIGlsIHRpcG8gInswfSIuIElsIHRpcG8gZGkgY29udGVudXRvIGRpIHF1ZXN0byB0aXBvIFx1MDBFOCBtaXN0bywgbWEgaWwgdGlwbyBkaSBjb250ZW51dG8gZGVsbGEgYmFzZSAnJ3sxfScnIG5vbiBsbyBcdTAwRTguCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uNS40LjIgPSBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjUuNC4yOiBlcnJvcmUgcGVyIGlsIHRpcG8gInswfSIuIExhIHBhcnRlIGRlbCB0aXBvIG5vbiBcdTAwRTggdW5hIGxpbWl0YXppb25lIHZhbGlkYSBkZWxsYSBwYXJ0ZSBkZWxsYSBiYXNlLgotICAgICAgICBlbnVtZXJhdGlvbi1yZXF1aXJlZC1ub3RhdGlvbiA9IGVudW1lcmF0aW9uLXJlcXVpcmVkLW5vdGF0aW9uOiBpbCB0aXBvIE5PVEFUSU9OICcnezB9JycgdXRpbGl6emF0byBkYSB7Mn0gJyd7MX0nJyBkZXZlIGF2ZXJlIHVuIHZhbG9yZSBkaSBmYWNldCBkaSBlbnVtZXJhemlvbmUgY2hlIHNwZWNpZmljYSBnbGkgZWxlbWVudGkgZGkgbm90YXppb25lIHV0aWxpenphdGkgZGEgcXVlc3RvIHRpcG8uCi0gICAgICAgIGVudW1lcmF0aW9uLXZhbGlkLXJlc3RyaWN0aW9uID0gZW51bWVyYXRpb24tdmFsaWQtcmVzdHJpY3Rpb246IGlsIHZhbG9yZSBkaSBlbnVtZXJhemlvbmUgInswfSIgbm9uIFx1MDBFOCBuZWxsbyBzcGF6aW8gZGVpIHZhbG9yaSBkZWwgdGlwbyBkaSBiYXNlIHsxfS4KLSAgICAgICAgZS1wcm9wcy1jb3JyZWN0LjIgPSBlLXByb3BzLWNvcnJlY3QuMjogdmFsb3JlIGRpIHZpbmNvbG8gZGkgdmFsb3JlICJ7MX0iIG5vbiB2YWxpZG8gbmVsbCcnZWxlbWVudG8gInswfSIuCi0gICAgICAgIGUtcHJvcHMtY29ycmVjdC40ID0gZS1wcm9wcy1jb3JyZWN0LjQ6ICd7J3R5cGUgZGVmaW5pdGlvbid9JyBkZWxsJydlbGVtZW50byAiezB9IiBub24gXHUwMEU4IHN0YXRhIGRlcml2YXRhIGluIG1vZG8gdmFsaWRvIGRhICd7J3R5cGUgZGVmaW5pdGlvbid9JyBkaSBzdWJzdGl0dXRpb25IZWFkICJ7MX0iIG8gbGEgcHJvcHJpZXRcdTAwRTAgJ3snc3Vic3RpdHV0aW9uIGdyb3VwIGV4Y2x1c2lvbnMnfScgZGkgJyd7MX0nJyBub24gY29uc2VudGUgcXVlc3RhIGRlcml2YXppb25lLgotICAgICAgICBlLXByb3BzLWNvcnJlY3QuNSA9IGUtcHJvcHMtY29ycmVjdC41OiBub24gZGV2ZSBlc2lzdGVyZSAneyd2YWx1ZSBjb25zdHJhaW50J30nIHN1bGwnJ2VsZW1lbnRvICJ7MH0iIHBlcmNoXHUwMEU5ICd7J3R5cGUgZGVmaW5pdGlvbid9JyBkZWxsJydlbGVtZW50byBvICd7J2NvbnRlbnQgdHlwZSd9JyBkaSAneyd0eXBlIGRlZmluaXRpb24nfScgXHUwMEU4IHVuIElEIG8gXHUwMEU4IGRlcml2YXRvIGRhIHVuIElELgotICAgICAgICBlLXByb3BzLWNvcnJlY3QuNiA9IGUtcHJvcHMtY29ycmVjdC42OiBncnVwcG8gZGkgc29zdGl0dXppb25lIGNpcmNvbGFyZSByaWxldmF0byBwZXIgbCcnZWxlbWVudG8gInswfSIuCi0gICAgICAgIGZyYWN0aW9uRGlnaXRzLXZhbGlkLXJlc3RyaWN0aW9uID0gZnJhY3Rpb25EaWdpdHMtdmFsaWQtcmVzdHJpY3Rpb246IG5lbGxhIGRlZmluaXppb25lIGRpIHsyfSwgaWwgdmFsb3JlICcnezB9JycgcGVyIGlsIGZhY2V0ICcnZnJhY3Rpb25EaWdpdHMnJyBub24gXHUwMEU4IHZhbGlkby4gRGV2ZSBlc3NlcmUgPD0gcmlzcGV0dG8gYWwgdmFsb3JlIHBlciAnJ2ZyYWN0aW9uRGlnaXRzJycsIGltcG9zdGF0byBzdSAnJ3sxfScnIGluIHVubyBkZWkgdGlwaSBkaSBwcmVkZWNlc3NvcmUuCi0gICAgICAgIGZyYWN0aW9uRGlnaXRzLXRvdGFsRGlnaXRzID0gZnJhY3Rpb25EaWdpdHMtdG90YWxEaWdpdHM6IG5lbGxhIGRlZmluaXppb25lIGRpIHsyfSwgaWwgdmFsb3JlICcnezB9JycgcGVyIGlsIGZhY2V0ICcnZnJhY3Rpb25EaWdpdHMnJyBub24gXHUwMEU4IHZhbGlkby4gSWwgdmFsb3JlIGRldmUgZXNzZXJlIDw9IHJpc3BldHRvIGFsIHZhbG9yZSBwZXIgJyd0b3RhbERpZ2l0cycnLCBpbXBvc3RhdG8gc3UgJyd7MX0nJy4KLSAgICAgICAgbGVuZ3RoLW1pbkxlbmd0aC1tYXhMZW5ndGguMS4xID0gbGVuZ3RoLW1pbkxlbmd0aC1tYXhMZW5ndGguMS4xOiBwZXIgaWwgdGlwbyB7MH0sIGlsIHZhbG9yZSBkaSBsdW5naGV6emEgJyd7MX0nJyBub24gcHVcdTAwRjIgZXNzZXJlIG1pbm9yZSBkZWwgdmFsb3JlIGRpIG1pbkxlbmd0aCAnJ3syfScnLgotICAgICAgICBsZW5ndGgtbWluTGVuZ3RoLW1heExlbmd0aC4xLjIuYSA9IGxlbmd0aC1taW5MZW5ndGgtbWF4TGVuZ3RoLjEuMi5hOiBwZXIgaWwgdGlwbyB7MH0sIGxhIGJhc2Ugbm9uIHB1XHUwMEYyIGF2ZXJlIHVuIGZhY2V0IG1pbkxlbmd0aCBzZSBsYSBsaW1pdGF6aW9uZSBjb3JyZW50ZSBoYSB1biBmYWNldCBtaW5MZW5ndGggZSBsYSBsaW1pdGF6aW9uZSBjb3JyZW50ZSBvIGxhIGJhc2UgaGEgdW4gZmFjZXQgZGkgbHVuZ2hlenphLgotICAgICAgICBsZW5ndGgtbWluTGVuZ3RoLW1heExlbmd0aC4xLjIuYiA9IGxlbmd0aC1taW5MZW5ndGgtbWF4TGVuZ3RoLjEuMi5iOiBwZXIgaWwgdGlwbyB7MH0sIGlsIHZhbG9yZSBjb3JyZW50ZSBkaSBtaW5MZW5ndGggJyd7MX0nJyBkZXZlIGVzc2VyZSB1Z3VhbGUgYSB2YWxvcmUgZGkgbWluTGVuZ3RoICcnezJ9JycgZGVsbGEgYmFzZS4KLSAgICAgICAgbGVuZ3RoLW1pbkxlbmd0aC1tYXhMZW5ndGguMi4xID0gbGVuZ3RoLW1pbkxlbmd0aC1tYXhMZW5ndGguMi4xOiBwZXIgaWwgdGlwbyB7MH0sIGlsIHZhbG9yZSBkaSBsdW5naGV6emEgJyd7MX0nJyBub24gcHVcdTAwRjIgZXNzZXJlIG1hZ2dpb3JlIGRlbCB2YWxvcmUgZGkgbWF4TGVuZ3RoICcnezJ9JycuCi0gICAgICAgIGxlbmd0aC1taW5MZW5ndGgtbWF4TGVuZ3RoLjIuMi5hID0gbGVuZ3RoLW1pbkxlbmd0aC1tYXhMZW5ndGguMi4yLmE6IHBlciBpbCB0aXBvIHswfSwgbGEgYmFzZSBub24gcHVcdTAwRjIgYXZlcmUgdW4gZmFjZXQgbWF4TGVuZ3RoIHNlIGxhIGxpbWl0YXppb25lIGNvcnJlbnRlIGhhIHVuIGZhY2V0IG1heExlbmd0aCBlIGxhIGxpbWl0YXppb25lIGNvcnJlbnRlIG8gbGEgYmFzZSBoYSB1biBmYWNldCBkaSBsdW5naGV6emEuCi0gICAgICAgIGxlbmd0aC1taW5MZW5ndGgtbWF4TGVuZ3RoLjIuMi5iID0gbGVuZ3RoLW1pbkxlbmd0aC1tYXhMZW5ndGguMi4yLmI6IHBlciBpbCB0aXBvIHswfSwgaWwgdmFsb3JlIGNvcnJlbnRlIGRpIG1heExlbmd0aCAnJ3sxfScnIGRldmUgZXNzZXJlIHVndWFsZSBhIHZhbG9yZSBkaSBtYXhMZW5ndGggJyd7Mn0nJyBkZWxsYSBiYXNlLgotICAgICAgICBsZW5ndGgtdmFsaWQtcmVzdHJpY3Rpb24gPSBsZW5ndGgtdmFsaWQtcmVzdHJpY3Rpb246IGVycm9yZSBwZXIgaWwgdGlwbyAnJ3syfScnLiBJbCB2YWxvcmUgZGVsbGEgbHVuZ2hlenphID0gInswfSIgZGV2ZSBlc3NlcmUgPSBhbCB2YWxvcmUgZGkgcXVlbGxhIGRlbCB0aXBvIGRpIGJhc2UgInsxfSIuCi0gICAgICAgIG1heEV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4xID0gbWF4RXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjE6IGVycm9yZSBwZXIgaWwgdGlwbyAnJ3syfScnLiBJbCB2YWxvcmUgbWF4RXhjbHVzaXZlID0iezB9IiBkZXZlIGVzc2VyZSA8PSBtYXhFeGNsdXNpdmUgZGVsIHRpcG8gZGkgYmFzZSAiezF9Ii4KLSAgICAgICAgbWF4RXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjIgPSBtYXhFeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMjogZXJyb3JlIHBlciBpbCB0aXBvICcnezJ9JycuIElsIHZhbG9yZSBtYXhJbmNsdXNpdmUgPSJ7MH0iIGRldmUgZXNzZXJlIDw9IG1heEV4Y2x1c2l2ZSBkZWwgdGlwbyBkaSBiYXNlICJ7MX0iLgotICAgICAgICBtYXhFeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMyA9IG1heEV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4zOiBlcnJvcmUgcGVyIGlsIHRpcG8gJyd7Mn0nJy4gSWwgdmFsb3JlIG1heEV4Y2x1c2l2ZSA9InswfSIgZGV2ZSBlc3NlcmUgPiBtaW5JbmNsdXNpdmUgZGVsIHRpcG8gZGkgYmFzZSAiezF9Ii4KLSAgICAgICAgbWF4RXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjQgPSBtYXhFeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMjogZXJyb3JlIHBlciBpbCB0aXBvICcnezJ9JycuIElsIHZhbG9yZSBtYXhFeGNsdXNpdmUgPSJ7MH0iIGRldmUgZXNzZXJlID4gbWluRXhjbHVzaXZlIGRlbCB0aXBvIGRpIGJhc2UgInsxfSIuCi0gICAgICAgIG1heEluY2x1c2l2ZS1tYXhFeGNsdXNpdmUgPSBtYXhJbmNsdXNpdmUtbWF4RXhjbHVzaXZlOiBub24gXHUwMEU4IHBvc3NpYmlsZSBzcGVjaWZpY2FyZSBzaWEgbWF4SW5jbHVzaXZlIGNoZSBtYXhFeGNsdXNpdmUgcGVyIGxvIHN0ZXNzbyB0aXBvIGRpIGRhdGkuIEluIHsyfSwgbWF4SW5jbHVzaXZlID0gJyd7MH0nJyBlIG1heEV4Y2x1c2l2ZSA9ICcnezF9JycuCi0gICAgICAgIG1heEluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4xID0gbWF4SW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjE6IGVycm9yZSBwZXIgaWwgdGlwbyAnJ3syfScnLiBJbCB2YWxvcmUgbWF4SW5jbHVzaXZlID0iezB9IiBkZXZlIGVzc2VyZSA8PSBtYXhJbmNsdXNpdmUgZGVsIHRpcG8gZGkgYmFzZSAiezF9Ii4KLSAgICAgICAgbWF4SW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjIgPSBtYXhJbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMjogZXJyb3JlIHBlciBpbCB0aXBvICcnezJ9JycuIElsIHZhbG9yZSBtYXhJbmNsdXNpdmUgPSJ7MH0iIGRldmUgZXNzZXJlIDw9IG1heEV4Y2x1c2l2ZSBkZWwgdGlwbyBkaSBiYXNlICJ7MX0iLgotICAgICAgICBtYXhJbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMyA9IG1heEluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4zOiBlcnJvcmUgcGVyIGlsIHRpcG8gJyd7Mn0nJy4gSWwgdmFsb3JlIG1heEluY2x1c2l2ZSA9InswfSIgZGV2ZSBlc3NlcmUgPj0gbWluSW5jbHVzaXZlIGRlbCB0aXBvIGRpIGJhc2UgInsxfSIuCi0gICAgICAgIG1heEluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi40ID0gbWF4SW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjQ6IGVycm9yZSBwZXIgaWwgdGlwbyAnJ3syfScnLiBJbCB2YWxvcmUgbWF4SW5jbHVzaXZlID0iezB9IiBkZXZlIGVzc2VyZSA+IG1pbkV4Y2x1c2l2ZSBkZWwgdGlwbyBkaSBiYXNlICJ7MX0iLgotICAgICAgICBtYXhMZW5ndGgtdmFsaWQtcmVzdHJpY3Rpb24gPSBtYXhMZW5ndGgtdmFsaWQtcmVzdHJpY3Rpb246IG5lbGxhIGRlZmluaXppb25lIGRpIHsyfSwgaWwgdmFsb3JlIG1heExlbmd0aCA9ICJ7MH0iIGRldmUgZXNzZXJlIDw9IHJpc3BldHRvIGEgcXVlbGxvIGRlbCB0aXBvIGRpIGJhc2UgInsxfSIuCi0gICAgICAgIG1nLXByb3BzLWNvcnJlY3QuMiA9IG1nLXByb3BzLWNvcnJlY3QuMjogZGVmaW5pemlvbmkgY2lyY29sYXJpIHJpbGV2YXRlIHBlciBpbCBncnVwcG8gJyd7MH0nJy4gU2Ugc2kgc2VndW9ubyBpbiBtYW5pZXJhIHJpY29yc2l2YSBpIHZhbG9yaSAneyd0ZXJtJ30nIGRlbGxlIHBhcnRpLCBzZSBuZSBhdnJcdTAwRTAgdW5hIGlsIGN1aSAneyd0ZXJtJ30nIFx1MDBFOCBpbCBncnVwcG8gc3Rlc3NvLgotICAgICAgICBtaW5FeGNsdXNpdmUtbGVzcy10aGFuLWVxdWFsLXRvLW1heEV4Y2x1c2l2ZSA9IG1pbkV4Y2x1c2l2ZS1sZXNzLXRoYW4tZXF1YWwtdG8tbWF4RXhjbHVzaXZlOiBuZWxsYSBkZWZpbml6aW9uZSBkaSB7Mn0sIGlsIHZhbG9yZSBtaW5FeGNsdXNpdmUgPSAnJ3swfScnIGRldmUgZXNzZXJlIDw9IHJpc3BldHRvIGFsIHZhbG9yZSBtYXhFeGNsdXNpdmUgPSAnJ3sxfScnLgotICAgICAgICBtaW5FeGNsdXNpdmUtbGVzcy10aGFuLW1heEluY2x1c2l2ZSA9IG1pbkV4Y2x1c2l2ZS1sZXNzLXRoYW4tbWF4SW5jbHVzaXZlOiBuZWxsYSBkZWZpbml6aW9uZSBkaSB7Mn0sIGlsIHZhbG9yZSBtaW5FeGNsdXNpdmUgPSAnJ3swfScnIGRldmUgZXNzZXJlIDw9IHJpc3BldHRvIGFsIHZhbG9yZSBtYXhJbmNsdXNpdmUgPSAnJ3sxfScnLgotICAgICAgICBtaW5FeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMSA9IG1pbkV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4xOiBlcnJvcmUgcGVyIGlsIHRpcG8gJyd7Mn0nJy4gSWwgdmFsb3JlIG1pbkV4Y2x1c2l2ZSA9InswfSIgZGV2ZSBlc3NlcmUgPj0gbWluRXhjbHVzaXZlIGRlbCB0aXBvIGRpIGJhc2UgInsxfSIuCi0gICAgICAgIG1pbkV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4yID0gbWluRXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjI6IGVycm9yZSBwZXIgaWwgdGlwbyAnJ3syfScnLiBJbCB2YWxvcmUgbWluRXhjbHVzaXZlID0iezB9IiBkZXZlIGVzc2VyZSA8PSBtYXhJbmNsdXNpdmUgZGVsIHRpcG8gZGkgYmFzZSAiezF9Ii4KLSAgICAgICAgbWluRXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjMgPSBtaW5FeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uNDogZXJyb3JlIHBlciBpbCB0aXBvICcnezJ9JycuIElsIHZhbG9yZSBtaW5FeGNsdXNpdmUgPSJ7MH0iIGRldmUgZXNzZXJlID49IG1pbkluY2x1c2l2ZSBkZWwgdGlwbyBkaSBiYXNlICJ7MX0iLgotICAgICAgICBtaW5FeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uNCA9IG1pbkV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi40OiBlcnJvcmUgcGVyIGlsIHRpcG8gJyd7Mn0nJy4gSWwgdmFsb3JlIG1pbkV4Y2x1c2l2ZSA9InswfSIgZGV2ZSBlc3NlcmUgPCBtYXhFeGNsdXNpdmUgZGVsIHRpcG8gZGkgYmFzZSAiezF9Ii4KLSAgICAgICAgbWluSW5jbHVzaXZlLWxlc3MtdGhhbi1lcXVhbC10by1tYXhJbmNsdXNpdmUgPSBtaW5JbmNsdXNpdmUtbGVzcy10aGFuLWVxdWFsLXRvLW1heEluY2x1c2l2ZTogbmVsbGEgZGVmaW5pemlvbmUgZGkgezJ9LCBpbCB2YWxvcmUgbWluSW5jbHVzaXZlID0gJyd7MH0nJyBkZXZlIGVzc2VyZSA8PSByaXNwZXR0byBhbCB2YWxvcmUgbWF4SW5jbHVzaXZlID0gJyd7MX0nJy4KLSAgICAgICAgbWluSW5jbHVzaXZlLWxlc3MtdGhhbi1tYXhFeGNsdXNpdmUgPSBtaW5JbmNsdXNpdmUtbGVzcy10aGFuLW1heEV4Y2x1c2l2ZTogbmVsbGEgZGVmaW5pemlvbmUgZGkgezJ9LCBpbCB2YWxvcmUgbWluSW5jbHVzaXZlID0gJyd7MH0nJyBkZXZlIGVzc2VyZSA8IHJpc3BldHRvIGFsIHZhbG9yZSBtYXhFeGNsdXNpdmUgPSAnJ3sxfScnLgotICAgICAgICBtaW5JbmNsdXNpdmUtbWluRXhjbHVzaXZlID0gbWluSW5jbHVzaXZlLW1pbkV4Y2x1c2l2ZTogbm9uIFx1MDBFOCBwb3NzaWJpbGUgc3BlY2lmaWNhcmUgc2lhIG1pbkluY2x1c2l2ZSBjaGUgbWluRXhjbHVzaXZlIHBlciBsbyBzdGVzc28gdGlwbyBkaSBkYXRpLiBJbiB7Mn0sIG1pbkluY2x1c2l2ZSA9ICcnezB9JycgZSBtaW5FeGNsdXNpdmUgPSAnJ3sxfScnLgotICAgICAgICBtaW5JbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMSA9IG1pbkluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4xOiBlcnJvcmUgcGVyIGlsIHRpcG8gJyd7Mn0nJy4gSWwgdmFsb3JlIG1pbkluY2x1c2l2ZSA9InswfSIgZGV2ZSBlc3NlcmUgPj0gbWluSW5jbHVzaXZlIGRlbCB0aXBvIGRpIGJhc2UgInsxfSIuCi0gICAgICAgIG1pbkluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4yID0gbWluSW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjI6IGVycm9yZSBwZXIgaWwgdGlwbyAnJ3syfScnLiBJbCB2YWxvcmUgbWluSW5jbHVzaXZlID0iezB9IiBkZXZlIGVzc2VyZSA8PSBtYXhJbmNsdXNpdmUgZGVsIHRpcG8gZGkgYmFzZSAiezF9Ii4KLSAgICAgICAgbWluSW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjMgPSBtaW5JbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMzogZXJyb3JlIHBlciBpbCB0aXBvICcnezJ9JycuIElsIHZhbG9yZSBtaW5JbmNsdXNpdmUgPSJ7MH0iIGRldmUgZXNzZXJlID4gbWluRXhjbHVzaXZlIGRlbCB0aXBvIGRpIGJhc2UgInsxfSIuCi0gICAgICAgIG1pbkluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi40ID0gbWluSW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjQ6IGVycm9yZSBwZXIgaWwgdGlwbyAnJ3syfScnLiBJbCB2YWxvcmUgbWluSW5jbHVzaXZlID0iezB9IiBkZXZlIGVzc2VyZSA8IG1heEV4Y2x1c2l2ZSBkZWwgdGlwbyBkaSBiYXNlICJ7MX0iLgotICAgICAgICBtaW5MZW5ndGgtbGVzcy10aGFuLWVxdWFsLXRvLW1heExlbmd0aCA9IG1pbkxlbmd0aC1sZXNzLXRoYW4tZXF1YWwtdG8tbWF4TGVuZ3RoOiBuZWxsYSBkZWZpbml6aW9uZSBkaSB7Mn0sIGlsIHZhbG9yZSBtaW5MZW5ndGggPSAnJ3swfScnIGRldmUgZXNzZXJlIDwgcmlzcGV0dG8gYWwgdmFsb3JlIG1heExlbmd0aCA9ICcnezF9JycuCi0gICAgICAgIG1pbkxlbmd0aC12YWxpZC1yZXN0cmljdGlvbiA9IG1pbkxlbmd0aC12YWxpZC1yZXN0cmljdGlvbjogbmVsbGEgZGVmaW5pemlvbmUgZGkgezJ9LCBtaW5MZW5ndGggPSAnJ3swfScnIGRldmUgZXNzZXJlID49IHJpc3BldHRvIGEgcXVlbGxvIGRlbCB0aXBvIGRpIGJhc2UgJyd7MX0nJy4KLSAgICAgICAgbm8teG1sbnMgPSBuby14bWxuczogaWwgeyduYW1lJ30gZGkgdW5hIGRpY2hpYXJhemlvbmUgZGkgYXR0cmlidXRvIG5vbiBkZXZlIGNvcnJpc3BvbmRlcmUgYSAneG1sbnMnLgotICAgICAgICBuby14c2kgPSBuby14c2k6IGlsICd7J3RhcmdldCBuYW1lc3BhY2UnfScgZGkgdW5hIGRpY2hpYXJhemlvbmUgZGkgYXR0cmlidXRvIG5vbiBkZXZlIGNvcnJpc3BvbmRlcmUgYSAiezB9Ii4KLSAgICAgICAgcC1wcm9wcy1jb3JyZWN0LjIuMSA9IHAtcHJvcHMtY29ycmVjdC4yLjE6IG5lbGxhIGRpY2hpYXJhemlvbmUgZGkgJyd7MH0nJywgaWwgdmFsb3JlIGRpICcnbWluT2NjdXJzJycgXHUwMEU4ICcnezF9JycsIG1hIG5vbiBkZXZlIGVzc2VyZSBtYWdnaW9yZSBkZWwgdmFsb3JlIGRpICcnbWF4T2NjdXJzJycsIGNoZSBcdTAwRTggJyd7Mn0nJy4KLSAgICAgICAgcmNhc2UtTWFwQW5kU3VtLjEgPSByY2FzZS1NYXBBbmRTdW0uMTogbm9uIGVzaXN0ZSB1biBtYXBwaW5nIGZ1bnppb25hbGUgY29tcGxldG8gdHJhIGxlIHBhcnRpLgotICAgICAgICByY2FzZS1NYXBBbmRTdW0uMiA9IHJjYXNlLU1hcEFuZFN1bS4yOiBsJydpbnRlcnZhbGxvIGRpIHJpY29ycmVuemEgKHswfSx7MX0pIGRlbCBncnVwcG8gbm9uIFx1MDBFOCB1bmEgbGltaXRhemlvbmUgdmFsaWRhIGRlbGwnJ2ludGVydmFsbG8gZGkgcmljb3JyZW56YSAoezJ9LHszfSkgZGVsIGdydXBwbyBkaSBiYXNlLgotICAgICAgICByY2FzZS1OYW1lQW5kVHlwZU9LLjEgPSByY2FzZS1OYW1lQW5kVHlwZU9LLjE6IGFsY3VuaSBlbGVtZW50aSBoYW5ubyBub21pIGUgc3BhemkgZGkgbm9taSBkaSBkZXN0aW5hemlvbmUgY2hlIG5vbiBzb25vIHVndWFsaTogbCcnZWxlbWVudG8gInswfSIgbmVsbG8gc3BhemlvIGRpIG5vbWkgInsxfSIgZSBsJydlbGVtZW50byAiezJ9IiBuZWxsbyBzcGF6aW8gZGkgbm9taSAiezN9Ii4KLSAgICAgICAgcmNhc2UtTmFtZUFuZFR5cGVPSy4yID0gcmNhc2UtTmFtZUFuZFR5cGVPSy4yOiBlcnJvcmUgcGVyIGxhIHBhcnRlIGlsIGN1aSAneyd0ZXJtJ30nIFx1MDBFOCBsYSBkaWNoaWFyYXppb25lIGRpIGVsZW1lbnRvICcnezB9JycuIElsIHZhbG9yZSAneyduaWxsYWJsZSd9JyBkZWxsYSBkaWNoaWFyYXppb25lIGRpIGVsZW1lbnRvIFx1MDBFOCBpbXBvc3RhdG8gc3UgdHJ1ZSwgbWEgbGEgcGFydGUgY29ycmlzcG9uZGVudGUgbmVsIHRpcG8gZGkgYmFzZSBjb250aWVuZSB1bmEgZGljaGlhcmF6aW9uZSBkaSBlbGVtZW50byBwZXIgbGEgcXVhbGUgJ3snbmlsbGFibGUnfScgXHUwMEU4IGltcG9zdGF0byBzdSBmYWxzZS4KLSAgICAgICAgcmNhc2UtTmFtZUFuZFR5cGVPSy4zID0gcmNhc2UtTmFtZUFuZFR5cGVPSy4zOiBlcnJvcmUgcGVyIGxhIHBhcnRlIGlsIGN1aSAneyd0ZXJtJ30nIFx1MDBFOCBsYSBkaWNoaWFyYXppb25lIGRpIGVsZW1lbnRvICcnezB9JycuIEwnJ2ludGVydmFsbG8gZGkgcmljb3JyZW56YSAoezF9LHsyfSkgbm9uIFx1MDBFOCB1bmEgbGltaXRhemlvbmUgdmFsaWRhIGRlbGwnJ2ludGVydmFsbG8gKHszfSx7NH0pIGRlbGxhIHBhcnRlIGNvcnJpc3BvbmRlbnRlIG5lbCB0aXBvIGRpIGJhc2UuCi0gICAgICAgIHJjYXNlLU5hbWVBbmRUeXBlT0suNC5hID0gcmNhc2UtTmFtZUFuZFR5cGVPSy40LmE6IGwnJ2VsZW1lbnRvICJ7MH0iIG5vbiBcdTAwRTggZmlzc28sIG1hIGwnJ2VsZW1lbnRvIGNvcnJpc3BvbmRlbnRlIG5lbCB0aXBvIGRpIGJhc2UgXHUwMEU4IGZpc3NvIGNvbiBpbCB2YWxvcmUgJyd7MX0nJy4KLSAgICAgICAgcmNhc2UtTmFtZUFuZFR5cGVPSy40LmIgPSByY2FzZS1OYW1lQW5kVHlwZU9LLjQuYjogbCcnZWxlbWVudG8gInswfSIgXHUwMEU4IGZpc3NvIGNvbiBpbCB2YWxvcmUgJyd7MX0nJywgbWEgbCcnZWxlbWVudG8gY29ycmlzcG9uZGVudGUgbmVsIHRpcG8gZGkgYmFzZSBcdTAwRTggZmlzc28gY29uIGlsIHZhbG9yZSAnJ3syfScnLgotICAgICAgICByY2FzZS1OYW1lQW5kVHlwZU9LLjUgPSByY2FzZS1OYW1lQW5kVHlwZU9LLjU6IGkgdmluY29saSBkaSBpZGVudGl0XHUwMEUwIHBlciBsJydlbGVtZW50byAiezB9IiBub24gc29ubyB1biBzdWJzZXQgZGkgcXVlbGxpIG5lbGxhIGJhc2UuCi0gICAgICAgIHJjYXNlLU5hbWVBbmRUeXBlT0suNiA9IHJjYXNlLU5hbWVBbmRUeXBlT0suNjogbGUgc29zdGl0dXppb25pIG5vbiBjb25zZW50aXRlIHBlciBsJydlbGVtZW50byAiezB9IiBub24gc29ubyB1biBzdXBlcnNldCBkaSBxdWVsbGUgbmVsbGEgYmFzZS4KLSAgICAgICAgcmNhc2UtTmFtZUFuZFR5cGVPSy43ID0gcmNhc2UtTmFtZUFuZFR5cGVPSy43OiBpbCB0aXBvICJ7MX0iIGRlbGwnJ2VsZW1lbnRvICJ7MH0iIG5vbiBkZXJpdmEgZGFsIHRpcG8gZGVsbCcnZWxlbWVudG8gZGkgYmFzZSAiezJ9Ii4KLSAgICAgICAgcmNhc2UtTlNDb21wYXQuMSA9IHJjYXNlLU5TQ29tcGF0LjE6IGwnJ2VsZW1lbnRvICJ7MH0iIGhhIHVubyBzcGF6aW8gZGkgbm9taSAiezF9IiBjaGUgbm9uIFx1MDBFOCBjb25zZW50aXRvIGRhbCBjYXJhdHRlcmUgam9sbHkgbmVsbGEgYmFzZS4KLSAgICAgICAgcmNhc2UtTlNDb21wYXQuMiA9IHJjYXNlLU5TQ29tcGF0LjI6IGVycm9yZSBwZXIgbGEgcGFydGUgaWwgY3VpICd7J3Rlcm0nfScgXHUwMEU4IGxhIGRpY2hpYXJhemlvbmUgZGkgZWxlbWVudG8gJyd7MH0nJy4gTCcnaW50ZXJ2YWxsbyBkaSByaWNvcnJlbnphICh7MX0sezJ9KSBub24gXHUwMEU4IHVuYSBsaW1pdGF6aW9uZSB2YWxpZGEgZGVsbCcnaW50ZXJ2YWxsbyAoezN9LHs0fSkgZGVsbGEgcGFydGUgY29ycmlzcG9uZGVudGUgbmVsIHRpcG8gZGkgYmFzZS4KLSAgICAgICAgcmNhc2UtTlNSZWN1cnNlQ2hlY2tDYXJkaW5hbGl0eS4xID0gcmNhc2UtTlNSZWN1cnNlQ2hlY2tDYXJkaW5hbGl0eS4xOiBub24gZXNpc3RlIHVuIG1hcHBpbmcgZnVuemlvbmFsZSBjb21wbGV0byB0cmEgbGUgcGFydGkuCi0gICAgICAgIHJjYXNlLU5TUmVjdXJzZUNoZWNrQ2FyZGluYWxpdHkuMiA9IHJjYXNlLU5TUmVjdXJzZUNoZWNrQ2FyZGluYWxpdHkuMjogbCcnaW50ZXJ2YWxsbyBkaSByaWNvcnJlbnphICh7MH0sezF9KSBkZWwgZ3J1cHBvIG5vbiBcdTAwRTggdW5hIGxpbWl0YXppb25lIHZhbGlkYSBkZWxsJydpbnRlcnZhbGxvICh7Mn0sezN9KSBkZWwgY2FyYXR0ZXJlIGpvbGx5IGRpIGJhc2UuCi0gICAgICAgIHJjYXNlLU5TU3Vic2V0LjEgPSByY2FzZS1OU1N1YnNldC4xOiBpbCBjYXJhdHRlcmUgam9sbHkgbm9uIFx1MDBFOCB1biBzdWJzZXQgZGVsIGNhcmF0dGVyZSBqb2xseSBjb3JyaXNwb25kZW50ZSBuZWxsYSBiYXNlLgotICAgICAgICByY2FzZS1OU1N1YnNldC4yID0gcmNhc2UtTlNTdWJzZXQuMjogbCcnaW50ZXJ2YWxsbyBkaSByaWNvcnJlbnphICh7MH0sezF9KSBkZWwgY2FyYXR0ZXJlIGpvbGx5IG5vbiBcdTAwRTggdW5hIGxpbWl0YXppb25lIHZhbGlkYSBkaSBxdWVsbG8gbmVsbGEgYmFzZSAoezJ9LHszfSkuCi0gICAgICAgIHJjYXNlLU5TU3Vic2V0LjMgPSByY2FzZS1OU1N1YnNldC4zOiBpbCBjb250ZW51dG8gJyd7MH0nJyBkZWwgcHJvY2Vzc28gZGVsIGNhcmF0dGVyZSBqb2xseSBcdTAwRTggcGlcdTAwRjkgZGVib2xlIGRpIHF1ZWxsbyBkZWxsYSBiYXNlICcnezF9JycuCi0gICAgICAgIHJjYXNlLVJlY3Vyc2UuMSA9IHJjYXNlLVJlY3Vyc2UuMTogbCcnaW50ZXJ2YWxsbyBkaSByaWNvcnJlbnphICh7MH0sezF9KSBkZWwgZ3J1cHBvIG5vbiBcdTAwRTggdW5hIGxpbWl0YXppb25lIHZhbGlkYSBkZWxsJydpbnRlcnZhbGxvIGRpIHJpY29ycmVuemEgKHsyfSx7M30pIGRlbCBncnVwcG8gZGkgYmFzZS4KLSAgICAgICAgcmNhc2UtUmVjdXJzZS4yID0gcmNhc2UtUmVjdXJzZS4yOiBub24gZXNpc3RlIHVuIG1hcHBpbmcgZnVuemlvbmFsZSBjb21wbGV0byB0cmEgbGUgcGFydGkuCi0gICAgICAgIHJjYXNlLVJlY3Vyc2VMYXguMSA9IHJjYXNlLVJlY3Vyc2VMYXguMTogbCcnaW50ZXJ2YWxsbyBkaSByaWNvcnJlbnphICh7MH0sezF9KSBkZWwgZ3J1cHBvIG5vbiBcdTAwRTggdW5hIGxpbWl0YXppb25lIHZhbGlkYSBkZWxsJydpbnRlcnZhbGxvIGRpIHJpY29ycmVuemEgKHsyfSx7M30pIGRlbCBncnVwcG8gZGkgYmFzZS4KLSAgICAgICAgcmNhc2UtUmVjdXJzZUxheC4yID0gcmNhc2UtUmVjdXJzZUxheC4yOiBub24gZXNpc3RlIHVuIG1hcHBpbmcgZnVuemlvbmFsZSBjb21wbGV0byB0cmEgbGUgcGFydGkuCi0gICAgICAgIHJjYXNlLVJlY3Vyc2VVbm9yZGVyZWQuMSA9IHJjYXNlLVJlY3Vyc2VVbm9yZGVyZWQuMTogbCcnaW50ZXJ2YWxsbyBkaSByaWNvcnJlbnphICh7MH0sezF9KSBkZWwgZ3J1cHBvIG5vbiBcdTAwRTggdW5hIGxpbWl0YXppb25lIHZhbGlkYSBkZWxsJydpbnRlcnZhbGxvIGRpIHJpY29ycmVuemEgKHsyfSx7M30pIGRlbCBncnVwcG8gZGkgYmFzZS4KLSAgICAgICAgcmNhc2UtUmVjdXJzZVVub3JkZXJlZC4yID0gcmNhc2UtUmVjdXJzZVVub3JkZXJlZC4yOiBub24gZXNpc3RlIHVuIG1hcHBpbmcgZnVuemlvbmFsZSBjb21wbGV0byB0cmEgbGUgcGFydGkuCi0jICAgICAgICBXZSdyZSB1c2luZyBzY2gtcHJvcHMtY29ycmVjdC4yIGluc3RlYWQgb2YgdGhlIG9sZCBzcmMtcmVkZWZpbmUuMQotIyAgICAgICAgc3JjLXJlZGVmaW5lLjEgPSBzcmMtcmVkZWZpbmUuMTogVGhlIGNvbXBvbmVudCAnJ3swfScnIGlzIGJlZ2luIHJlZGVmaW5lZCwgYnV0IGl0cyBjb3JyZXNwb25kaW5nIGNvbXBvbmVudCBpc24ndCBpbiB0aGUgc2NoZW1hIGRvY3VtZW50IGJlaW5nIHJlZGVmaW5lZCAod2l0aCBuYW1lc3BhY2UgJyd7Mn0nJyksIGJ1dCBpbiBhIGRpZmZlcmVudCBkb2N1bWVudCwgd2l0aCBuYW1lc3BhY2UgJyd7MX0nJy4KLSAgICAgICAgc2NoLXByb3BzLWNvcnJlY3QuMiA9IHNjaC1wcm9wcy1jb3JyZWN0LjI6IHVubyBzY2hlbWEgbm9uIHB1XHUwMEYyIGNvbnRlbmVyZSBkdWUgY29tcG9uZW50aSBnbG9iYWxpIGNvbiBsbyBzdGVzc28gbm9tZTsgcXVlc3RvIGNvbnRpZW5lIGR1ZSByaWNvcnJlbnplIGRpICJ7MH0iLgotICAgICAgICBzdC1wcm9wcy1jb3JyZWN0LjIgPSBzdC1wcm9wcy1jb3JyZWN0LjI6IHNvbm8gc3RhdGUgcmlsZXZhdGUgZGVmaW5pemlvbmkgY2lyY29sYXJpIHBlciBpbCB0aXBvIHNlbXBsaWNlICcnezB9JycuIENpXHUwMEYyIHNpZ25pZmljYSBjaGUgJyd7MH0nJyBzaSB0cm92YSBhbGwnJ2ludGVybm8gZGVsbGEgc3VhIHN0ZXNzYSBnZXJhcmNoaWEgZGkgdGlwaSwgaWwgY2hlIFx1MDBFOCBlcnJhdG8uCi0gICAgICAgIHN0LXByb3BzLWNvcnJlY3QuMyA9IHN0LXByb3BzLWNvcnJlY3QuMzogZXJyb3JlIHBlciBpbCB0aXBvICcnezB9JycuIElsIHZhbG9yZSBkaSAneydmaW5hbCd9JyBwZXIgJ3snYmFzZSB0eXBlIGRlZmluaXRpb24nfScsICcnezF9JycsIGltcGVkaXNjZSBsYSBkZXJpdmF6aW9uZSBtZWRpYW50ZSBsaW1pdGF6aW9uZS4KLSAgICAgICAgdG90YWxEaWdpdHMtdmFsaWQtcmVzdHJpY3Rpb24gPSB0b3RhbERpZ2l0cy12YWxpZC1yZXN0cmljdGlvbjogbmVsbGEgZGVmaW5pemlvbmUgZGkgezJ9LCBpbCB2YWxvcmUgJyd7MH0nJyBwZXIgaWwgZmFjZXQgJyd0b3RhbERpZ2l0cycnIG5vbiBcdTAwRTggdmFsaWRvLiBEZXZlIGVzc2VyZSA8PSByaXNwZXR0byBhbCB2YWxvcmUgcGVyICcndG90YWxEaWdpdHMnJywgaW1wb3N0YXRvIHN1ICcnezF9JycgaW4gdW5vIGRlaSB0aXBpIGRpIHByZWRlY2Vzc29yZS4KLSAgICAgICAgd2hpdGVTcGFjZS12YWxpZC1yZXN0cmljdGlvbi4xID0gd2hpdGVTcGFjZS12YWxpZC1yZXN0cmljdGlvbi4xOiBuZWxsYSBkZWZpbml6aW9uZSBkaSB7MH0sIGlsIHZhbG9yZSAnJ3sxfScnIHBlciBpbCBmYWNldCAnJ3doaXRlc3BhY2UnJyBub24gXHUwMEU4IHZhbGlkby4gSWwgdmFsb3JlIHBlciAnJ3doaXRlc3BhY2UnJyBcdTAwRTggc3RhdG8gaW1wb3N0YXRvIHN1ICcnY29sbGFwc2UnJyBpbiB1bm8gZGVpIHRpcGkgZGkgcHJlZGVjZXNzb3JlLgotICAgICAgICB3aGl0ZVNwYWNlLXZhbGlkLXJlc3RyaWN0aW9uLjIgPSB3aGl0ZVNwYWNlLXZhbGlkLXJlc3RyaWN0aW9uLjI6IG5lbGxhIGRlZmluaXppb25lIGRpIHswfSwgaWwgdmFsb3JlICcncHJlc2VydmUnJyBwZXIgaWwgZmFjZXQgJyd3aGl0ZXNwYWNlJycgbm9uIFx1MDBFOCB2YWxpZG8uIElsIHZhbG9yZSBwZXIgJyd3aGl0ZXNwYWNlJycgXHUwMEU4IHN0YXRvIGltcG9zdGF0byBzdSAnJ3JlcGxhY2UnJyBpbiB1bm8gZGVpIHRpcGkgZGkgcHJlZGVjZXNzb3JlLgotCi0jc2NoZW1hIGZvciBTY2hlbWFzCi0KLSAgICAgICAgczRzLWF0dC1pbnZhbGlkLXZhbHVlID0gczRzLWF0dC1pbnZhbGlkLXZhbHVlOiB2YWxvcmUgZGkgYXR0cmlidXRvIG5vbiB2YWxpZG8gcGVyICJ7MX0iIG5lbGwnJ2VsZW1lbnRvICJ7MH0iOiBNb3Rpdm8gcmVnaXN0cmF0bzogezJ9Ci0gICAgICAgIHM0cy1hdHQtbXVzdC1hcHBlYXIgPSBzNHMtYXR0LW11c3QtYXBwZWFyOiBsJydhdHRyaWJ1dG8gJyd7MX0nJyBkZXZlIGFwcGFyaXJlIG5lbGwnJ2VsZW1lbnRvICJ7MH0iLgotICAgICAgICBzNHMtYXR0LW5vdC1hbGxvd2VkID0gczRzLWF0dC1ub3QtYWxsb3dlZDogbCcnYXR0cmlidXRvICcnezF9Jycgbm9uIHB1XHUwMEYyIGFwcGFyaXJlIG5lbGwnJ2VsZW1lbnRvICJ7MH0iLgotICAgICAgICBzNHMtZWx0LWludmFsaWQgPSBzNHMtZWx0LWludmFsaWQ6IGwnJ2VsZW1lbnRvICJ7MH0iIG5vbiBcdTAwRTggdW4gZWxlbWVudG8gdmFsaWRvIG5lbCBkb2N1bWVudG8gZGVsbG8gc2NoZW1hLgotICAgICAgICBzNHMtZWx0LW11c3QtbWF0Y2guMSA9IHM0cy1lbHQtbXVzdC1tYXRjaC4xOiBpbCBjb250ZW51dG8gZGkgInswfSIgZGV2ZSBjb3JyaXNwb25kZXJlIGEgezF9LiBTaSBcdTAwRTggdmVyaWZpY2F0byB1biBwcm9ibGVtYSBjb24gaW5pemlvIGluIHsyfS4KLSAgICAgICAgczRzLWVsdC1tdXN0LW1hdGNoLjIgPSBzNHMtZWx0LW11c3QtbWF0Y2guMjogaWwgY29udGVudXRvIGRpICJ7MH0iIGRldmUgY29ycmlzcG9uZGVyZSBhIHsxfS4gTm9uIHNvbm8gc3RhdGkgdHJvdmF0aSBlbGVtZW50aSBzdWZmaWNpZW50aS4KLSAgICAgICAgIyB0aGUgImludmFsaWQtY29udGVudCIgbWVzc2FnZXMgcHJvdmlkZSBsZXNzIGluZm9ybWF0aW9uIHRoYW4gdGhlICJtdXN0LW1hdGNoIiBjb3VudGVycGFydHMgYWJvdmUuIFRoZXkncmUgdXNlZCBmb3IgY29tcGxleCB0eXBlcyB3aGVuIHByb3ZpZGluZyBhICJtYXRjaCIgd291bGQgYmUgYW4gaW5mb3JtYXRpb24gZHVtcAotICAgICAgICBzNHMtZWx0LWludmFsaWQtY29udGVudC4xID0gczRzLWVsdC1pbnZhbGlkLWNvbnRlbnQuMTogaWwgY29udGVudXRvIGRpICcnezB9Jycgbm9uIFx1MDBFOCB2YWxpZG8uIEwnJ2VsZW1lbnRvICcnezF9Jycgbm9uIFx1MDBFOCB2YWxpZG8sIHNpIHRyb3ZhIGluIHVuYSBwb3NpemlvbmUgZXJyYXRhIG8gXHUwMEU4IHByZXNlbnRlIHRyb3BwZSB2b2x0ZS4KLSAgICAgICAgczRzLWVsdC1pbnZhbGlkLWNvbnRlbnQuMiA9IHM0cy1lbHQtaW52YWxpZC1jb250ZW50LjI6IGlsIGNvbnRlbnV0byBkaSAnJ3swfScnIG5vbiBcdTAwRTggdmFsaWRvLiBMJydlbGVtZW50byAnJ3sxfScnIG5vbiBwdVx1MDBGMiBlc3NlcmUgdnVvdG8uCi0gICAgICAgIHM0cy1lbHQtaW52YWxpZC1jb250ZW50LjMgPSBzNHMtZWx0LWludmFsaWQtY29udGVudC4zOiBnbGkgZWxlbWVudGkgZGkgdGlwbyAnJ3swfScnIG5vbiBwb3Nzb25vIHRyb3ZhcnNpIGRvcG8gZGljaGlhcmF6aW9uaSBjb21lIGVsZW1lbnRpIGZpZ2xpbyBkaSB1biBlbGVtZW50byA8c2NoZW1hPi4KLSAgICAgICAgczRzLWVsdC1zY2hlbWEtbnMgPSBzNHMtZWx0LXNjaGVtYS1uczogbG8gc3BhemlvIGRpIG5vbWkgZGVsbCcnZWxlbWVudG8gJyd7MH0nJyBkZXZlIGRlcml2YXJlIGRhbGxvIHNwYXppbyBkaSBub21pIGRlbGxvIHNjaGVtYSAnJ2h0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hJycuCi0gICAgICAgIHM0cy1lbHQtY2hhcmFjdGVyID0gczRzLWVsdC1jaGFyYWN0ZXI6IG5vbiBzb25vIGNvbnNlbnRpdGkgY2FyYXR0ZXJpIGRpdmVyc2kgZGFsbG8gc3BhemlvIG5lZ2xpIGVsZW1lbnRpIGRpIHNjaGVtYSBkaXZlcnNpIGRhICcneHM6YXBwaW5mbycnIGUgJyd4czpkb2N1bWVudGF0aW9uJycuIFJpbGV2YXRvICJ7MH0iLgotCi0jIGNvZGVzIG5vdCBkZWZpbmVkIGJ5IHRoZSBzcGVjCi0KLSAgICAgICAgYy1maWVsZHMteHBhdGhzID0gYy1maWVsZHMteHBhdGhzOiBpbCB2YWxvcmUgZGkgY2FtcG8gPSAiezB9IiBub24gXHUwMEU4IHZhbGlkby4KLSAgICAgICAgYy1nZW5lcmFsLXhwYXRoID0gYy1nZW5lcmFsLXhwYXRoOiBsJydlc3ByZXNzaW9uZSAiezB9IiBub24gXHUwMEU4IHZhbGlkYSByaXNwZXR0byBhbCBzdWJzZXQgWFBhdGggc3VwcG9ydGF0byBkYWxsbyBzY2hlbWEgWE1MLgotICAgICAgICBjLWdlbmVyYWwteHBhdGgtbnMgPSBjLWdlbmVyYWwteHBhdGgtbnM6IHVuIHByZWZpc3NvIGRlbGxvIHNwYXppbyBkaSBub21pIG5lbGwnJ2VzcHJlc3Npb25lIFhQYXRoICJ7MH0iIG5vbiBcdTAwRTggYXNzb2NpYXRvIGEgdW5vIHNwYXppbyBkaSBub21pLgotICAgICAgICBjLXNlbGVjdG9yLXhwYXRoID0gYy1zZWxlY3Rvci14cGF0aDogaWwgdmFsb3JlIGRlbCBzZWxldHRvcmUgPSAiezB9IiBub24gXHUwMEU4IHZhbGlkbzsgZ2xpIFhQYXRoIGRlbCBzZWxldHRvcmUgbm9uIHBvc3Nvbm8gY29udGVuZXJlIGF0dHJpYnV0aS4KLSAgICAgICAgRW1wdHlUYXJnZXROYW1lc3BhY2UgPSBFbXB0eVRhcmdldE5hbWVzcGFjZTogbmVsIGRvY3VtZW50byBkaSBzY2hlbWEgJyd7MH0nJyBpbCB2YWxvcmUgZGVsbCcnYXR0cmlidXRvICcndGFyZ2V0TmFtZXNwYWNlJycgbm9uIHB1XHUwMEYyIGVzc2VyZSB1bmEgc3RyaW5nYSB2dW90YS4KLSAgICAgICAgRmFjZXRWYWx1ZUZyb21CYXNlID0gRmFjZXRWYWx1ZUZyb21CYXNlOiBuZWxsYSBkaWNoaWFyYXppb25lIGRlbCB0aXBvICcnezB9JycgaWwgdmFsb3JlICcnezF9JycgZGVsIGZhY2V0ICcnezJ9JycgZGV2ZSBwcm92ZW5pcmUgZGFsbG8gc3BhemlvIGRpIHZhbG9yaSBkZWwgdGlwbyBkaSBiYXNlICcnezN9JycuCi0gICAgICAgIEZpeGVkRmFjZXRWYWx1ZSA9IEZpeGVkRmFjZXRWYWx1ZTogbmVsbGEgZGVmaW5pemlvbmUgZGkgezN9LCBpbCB2YWxvcmUgJyd7MX0nJyBwZXIgaWwgZmFjZXQgJyd7MH0nJyBub24gXHUwMEU4IHZhbGlkby4gSWwgdmFsb3JlIHBlciAnJ3swfScnIFx1MDBFOCBzdGF0byBpbXBvc3RhdG8gc3UgJyd7Mn0nJyBpbiB1bm8gZGVpIHRpcGkgZGkgcHJlZGVjZXNzb3JlIGUgJ3snZml4ZWQnfScgPSB0cnVlLgotICAgICAgICBJbnZhbGlkUmVnZXggPSBJbnZhbGlkUmVnZXg6IGlsIHZhbG9yZSBkaSBwYXR0ZXJuICJ7MH0iIG5vbiBcdTAwRTggdW4nJ2VzcHJlc3Npb25lIHJlZ29sYXJlIHZhbGlkYS4gRXJyb3JlIHNlZ25hbGF0byAnJ3sxfScnIG5lbGxhIGNvbG9ubmEgJyd7Mn0nJy4KLSAgICAgICAgTWF4T2NjdXJMaW1pdCA9IExhIGNvbmZpZ3VyYXppb25lIGNvcnJlbnRlIGRlbCBwYXJzZXIgbm9uIGNvbnNlbnRlIGNoZSB1biB2YWxvcmUgZGkgYXR0cmlidXRvIG1heE9jY3VycyBzaWEgaW1wb3N0YXRvIHN1IHVuIHZhbG9yZSBtYWdnaW9yZSBkZWwgdmFsb3JlIHswfS4KLSAgICAgICAgUHVibGljU3lzdGVtT25Ob3RhdGlvbiA9IFB1YmxpY1N5c3RlbU9uTm90YXRpb246IGFsbWVubyB1bm8gdHJhICcncHVibGljJycgZSAnJ3N5c3RlbScnIGRldmUgZXNzZXJlIHByZXNlbnRlIG5lbGwnZWxlbWVudG8gJydub3RhdGlvbicnLgotICAgICAgICBTY2hlbWFMb2NhdGlvbiA9IFNjaGVtYUxvY2F0aW9uOiBpbCB2YWxvcmUgPSAnJ3swfScnIGRpIHNjaGVtYUxvY2F0aW9uIGRldmUgYXZlcmUgdW4gbnVtZXJvIHBhcmkgZGkgVVJJLgotICAgICAgICBUYXJnZXROYW1lc3BhY2UuMSA9IFRhcmdldE5hbWVzcGFjZS4xOiBsbyBzcGF6aW8gZGkgbm9taSBwcmV2aXN0byBcdTAwRTggInswfSIsIG1hIGxvIHNwYXppbyBkaSBub21pIGRpIGRlc3RpbmF6aW9uZSBkZWwgZG9jdW1lbnRvIGRlbGxvIHNjaGVtYSBcdTAwRTggInsxfSIuCi0gICAgICAgIFRhcmdldE5hbWVzcGFjZS4yID0gVGFyZ2V0TmFtZXNwYWNlLjI6IG5vbiBcdTAwRTggcHJldmlzdG8gbmVzc3VubyBzcGF6aW8gZGkgbm9taSwgbWEgaWwgZG9jdW1lbnRvIGRlbGxvIHNjaGVtYSBoYSB1bm8gc3BhemlvIGRpIG5vbWkgZGkgZGVzdGluYXppb25lICcnezF9JycuCi0gICAgICAgIFVuZGVjbGFyZWRFbnRpdHkgPSBVbmRlY2xhcmVkRW50aXR5OiBsJydlbnRpdFx1MDBFMCAnJ3swfScnIG5vbiBcdTAwRTggc3RhdGEgZGljaGlhcmF0YS4KLSAgICAgICAgVW5kZWNsYXJlZFByZWZpeCA9IFVuZGVjbGFyZWRQcmVmaXg6IGltcG9zc2liaWxlIHJpc29sdmVyZSAnJ3swfScnIGNvbWUgUU5hbWUuIElsIHByZWZpc3NvICcnezF9Jycgbm9uIFx1MDBFOCBzdGF0byBkaWNoaWFyYXRvLgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MU2NoZW1hTWVzc2FnZXNfamEucHJvcGVydGllcyBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hNTFNjaGVtYU1lc3NhZ2VzX2phLnByb3BlcnRpZXMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGYwNDg2N2QuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MU2NoZW1hTWVzc2FnZXNfamEucHJvcGVydGllcworKysgL2Rldi9udWxsCkBAIC0xLDI5MSArMCwwIEBACi0jIFRoaXMgZmlsZSBjb250YWlucyBlcnJvciBhbmQgd2FybmluZyBtZXNzYWdlcyByZWxhdGVkIHRvIFhNTCBTY2hlbWEKLSMgVGhlIG1lc3NhZ2VzIGFyZSBhcnJhbmdlZCBpbiBrZXkgYW5kIHZhbHVlIHR1cGxlcyBpbiBhIExpc3RSZXNvdXJjZUJ1bmRsZS4KLSMKLQotICAgICAgICBCYWRNZXNzYWdlS2V5ID0gXHUzMEUxXHUzMEMzXHUzMEJCXHUzMEZDXHUzMEI4XHUzMEZCXHUzMEFEXHUzMEZDXHUzMDZCXHU1QkZFXHU1RkRDXHUzMDU5XHUzMDhCXHUzMEE4XHUzMEU5XHUzMEZDXHUzMEZCXHUzMEUxXHUzMEMzXHUzMEJCXHUzMEZDXHUzMEI4XHUzMDRDXHU4OThCXHUzMDY0XHUzMDRCXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0gICAgICAgIEZvcm1hdEZhaWxlZCA9IFx1NkIyMVx1MzA2RVx1MzBFMVx1MzBDM1x1MzBCQlx1MzBGQ1x1MzBCOFx1MzA2RVx1NjZGOFx1NUYwRlx1OEEyRFx1NUI5QVx1NEUyRFx1MzA2Qlx1NTE4NVx1OTBFOFx1MzBBOFx1MzBFOVx1MzBGQ1x1MzA0Q1x1NzY3QVx1NzUxRlx1MzA1N1x1MzA3RVx1MzA1N1x1MzA1RjpcbgotCi0jIEZvciBpbnRlcm5hbCB1c2UKLQotICAgICAgICBJbnRlcm5hbC1FcnJvciA9IFx1NTE4NVx1OTBFOFx1MzBBOFx1MzBFOVx1MzBGQzogezB9XHUzMDAyCi0gICAgICAgIGR0LXdoaXRlc3BhY2UgPSBcdTUxNzFcdTc1MjhcdTRGNTNcdTMwNkVzaW1wbGVUeXBlICcnezB9JydcdTMwNkJcdTMwNkZcdTdBN0FcdTc2N0RcdTMwNkVcdTMwRDVcdTMwQTFcdTMwQkJcdTMwQzNcdTMwQzhcdTUwMjRcdTMwOTJcdTRGN0ZcdTc1MjhcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTMKLSAgICAgICAgR3JhbW1hckNvbmZsaWN0ID0gXHUzMEU2XHUzMEZDXHUzMEI2XHUzMEZDXHUzMDZFXHU2OUNCXHU2NTg3XHUzMEQ3XHUzMEZDXHUzMEVCXHUzMDRCXHUzMDg5XHU2MjNCXHUzMDU1XHUzMDhDXHUzMDVGXHU2OUNCXHU2NTg3XHUzMDZFXHUzMDQ0XHUzMDVBXHUzMDhDXHUzMDRCXHUzMDRDXHU0RUQ2XHUzMDZFXHU2OUNCXHU2NTg3XHUzMDY4XHU3QUY2XHU1NDA4XHUzMDU3XHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5XHUzMDAyCi0KLSMgSWRlbnRpdHkgY29uc3RyYWludHMKLQotICAgICAgICBBYnNlbnRLZXlWYWx1ZSA9IFx1MzBBMlx1MzBBNFx1MzBDN1x1MzBGM1x1MzBDNlx1MzBBM1x1MzBDNlx1MzBBM1x1NTIzNlx1N0QwNFx1MzBBOFx1MzBFOVx1MzBGQyhjdmMtaWRlbnRpdHktY29uc3RyYWludC40LjIuMSk6IFx1ODk4MVx1N0QyMCJ7MH0iXHUzMDZCXHU1MDI0XHUzMDZFXHUzMDZBXHUzMDQ0XHUzMEFEXHUzMEZDXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIER1cGxpY2F0ZUZpZWxkID0gXHUzMEQ1XHUzMEEzXHUzMEZDXHUzMEVCXHUzMEM5InswfSJcdTMwNkVcdTMwQjlcdTMwQjNcdTMwRkNcdTMwRDdcdTUxODVcdTMwNjdcdTRFMDBcdTgxRjRcdTMwNENcdTkxQ0RcdTg5MDdcdTMwNTdcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTlcdTMwMDIKLSAgICAgICAgRHVwbGljYXRlS2V5ID0gXHU4OTgxXHU3RDIwInsxfSJcdTMwNkVcdTMwQTJcdTMwQTRcdTMwQzdcdTMwRjNcdTMwQzZcdTMwQTNcdTMwQzZcdTMwQTNcdTUyMzZcdTdEMDRcdTMwNjdcdTVCQTNcdThBMDBcdTMwNTVcdTMwOENcdTMwNUZrZXlcdTMwNkVcdTUwMjRbezB9XVx1MzA0Q1x1OTFDRFx1ODkwN1x1MzA1N1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBEdXBsaWNhdGVVbmlxdWUgPSBcdTg5ODFcdTdEMjAiezF9Ilx1MzA2RVx1MzBBMlx1MzBBNFx1MzBDN1x1MzBGM1x1MzBDNlx1MzBBM1x1MzBDNlx1MzBBM1x1NTIzNlx1N0QwNFx1MzA2N1x1NUJBM1x1OEEwMFx1MzA1NVx1MzA4Q1x1MzA1RnVuaXF1ZVx1MzA2RVx1NTAyNFt7MH1dXHUzMDRDXHU5MUNEXHU4OTA3XHUzMDU3XHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIEZpZWxkTXVsdGlwbGVNYXRjaCA9IFx1MzBBMlx1MzBBNFx1MzBDN1x1MzBGM1x1MzBDNlx1MzBBM1x1MzBDNlx1MzBBM1x1NTIzNlx1N0QwNFx1MzBBOFx1MzBFOVx1MzBGQzogXHUzMEQ1XHUzMEEzXHUzMEZDXHUzMEVCXHUzMEM5InswfSJcdTMwNENcdTMwQkJcdTMwRUNcdTMwQUZcdTMwQkZcdTMwNkVcdTMwQjlcdTMwQjNcdTMwRkNcdTMwRDdcdTUxODVcdTMwNkVcdTg5MDdcdTY1NzBcdTMwNkVcdTUwMjRcdTMwNjhcdTRFMDBcdTgxRjRcdTMwNTdcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTlcdTMwMDJcdTMwRDVcdTMwQTNcdTMwRkNcdTMwRUJcdTMwQzlcdTMwNkZ1bmlxdWVcdTMwNkVcdTUwMjRcdTMwNjhcdTRFMDBcdTgxRjRcdTMwNTlcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIKLSAgICAgICAgRml4ZWREaWZmZXJzRnJvbUFjdHVhbCA9IFx1MzA1M1x1MzA2RVx1ODk4MVx1N0QyMFx1MzA2RVx1MzBCM1x1MzBGM1x1MzBDNlx1MzBGM1x1MzBDNFx1MzA2Rlx1MzAwMVx1MzBCOVx1MzBBRFx1MzBGQ1x1MzBERVx1NTE4NVx1MzA2RVx1ODk4MVx1N0QyMFx1NUJBM1x1OEEwMFx1MzA2N1x1MzA2RSJmaXhlZCJcdTVDNUVcdTYwMjdcdTMwNkVcdTUwMjRcdTMwNjhcdTc1NzBcdTMwNkFcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIKLSAgICAgICAgS2V5TWF0Y2hlc05pbGxhYmxlID0gXHUzMEEyXHUzMEE0XHUzMEM3XHUzMEYzXHUzMEM2XHUzMEEzXHUzMEM2XHUzMEEzXHU1MjM2XHU3RDA0XHUzMEE4XHUzMEU5XHUzMEZDKGN2Yy1pZGVudGl0eS1jb25zdHJhaW50LjQuMi4zKTogXHU4OTgxXHU3RDIwInswfSJcdTMwNkJcdTMwNkZcdTMwMDFuaWxsYWJsZVx1MzA0Q3RydWVcdTMwNjdcdTMwNDJcdTMwOEJcdTg5ODFcdTdEMjBcdTMwNjhcdTRFMDBcdTgxRjRcdTMwNTlcdTMwOEJcdTMwQURcdTMwRkNcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIKLSAgICAgICAgS2V5Tm90RW5vdWdoVmFsdWVzID0gXHU4OTgxXHU3RDIwInswfSJcdTMwNkJcdTYzMDdcdTVCOUFcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwOEI8a2V5IG5hbWU9InsxfSI+XHUzMEEyXHUzMEE0XHUzMEM3XHUzMEYzXHUzMEM2XHUzMEEzXHUzMEM2XHUzMEEzXHU1MjM2XHU3RDA0XHUzMDZCXHUzMDAxXHU1MzQxXHU1MjA2XHUzMDZBXHU1MDI0XHUzMDRDXHU2MzA3XHU1QjlBXHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0gICAgICAgIEtleU5vdEZvdW5kID0gXHU4OTgxXHU3RDIwJyd7Mn0nJ1x1MzA2RVx1MzBBMlx1MzBBNFx1MzBDN1x1MzBGM1x1MzBDNlx1MzBBM1x1MzBDNlx1MzBBM1x1NTIzNlx1N0QwNFx1MzA2N1x1MzAwMVx1NTAyNCcnezF9JydcdTMwNkVcdTMwQURcdTMwRkMnJ3swfScnXHUzMDRDXHU4OThCXHUzMDY0XHUzMDRCXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0gICAgICAgIEtleVJlZk5vdEVub3VnaFZhbHVlcyA9IFx1ODk4MVx1N0QyMCJ7MH0iXHUzMDZCXHU2MzA3XHU1QjlBXHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDhCPGtleXJlZiBuYW1lPSJ7MX0iPlx1MzBBMlx1MzBBNFx1MzBDN1x1MzBGM1x1MzBDNlx1MzBBM1x1MzBDNlx1MzBBM1x1NTIzNlx1N0QwNFx1MzA2Qlx1MzAwMVx1NTM0MVx1NTIwNlx1MzA2QVx1NTAyNFx1MzA0Q1x1NjMwN1x1NUI5QVx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotICAgICAgICBLZXlSZWZPdXRPZlNjb3BlID0gXHUzMEEyXHUzMEE0XHUzMEM3XHUzMEYzXHUzMEM2XHUzMEEzXHUzMEM2XHUzMEEzXHU1MjM2XHU3RDA0XHUzMEE4XHUzMEU5XHUzMEZDOiBcdTMwQTJcdTMwQTRcdTMwQzdcdTMwRjNcdTMwQzZcdTMwQTNcdTMwQzZcdTMwQTNcdTUyMzZcdTdEMDQiezB9Ilx1MzA2Qlx1MzAwMVx1MzBCOVx1MzBCM1x1MzBGQ1x1MzBEN1x1NTkxNlx1MzA2RWtleVx1MzA4NHVuaXF1ZVx1MzA5Mlx1NTNDMlx1NzE2N1x1MzA1N1x1MzA2Nlx1MzA0NFx1MzA4QmtleXJlZlx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBLZXlSZWZSZWZlck5vdEZvdW5kID0gXHUzMEFEXHUzMEZDXHU1M0MyXHU3MTY3XHUzMDZFXHU1QkEzXHU4QTAwInswfSJcdTMwNENcdTMwMDEiezF9Ilx1MzA2OFx1MzA0NFx1MzA0Nlx1NTQwRFx1NTI0RFx1MzA2RVx1NEUwRFx1NjYwRVx1MzA2QVx1MzBBRFx1MzBGQ1x1MzA5Mlx1NTNDMlx1NzE2N1x1MzA1N1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBVbmlxdWVOb3RFbm91Z2hWYWx1ZXMgPSBcdTg5ODFcdTdEMjAiezB9Ilx1MzA2Qlx1NjMwN1x1NUI5QVx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA4Qjx1bmlxdWU+XHUzMEEyXHUzMEE0XHUzMEM3XHUzMEYzXHUzMEM2XHUzMEEzXHUzMEM2XHUzMEEzXHU1MjM2XHU3RDA0XHUzMDZCXHUzMDAxXHU1MzQxXHU1MjA2XHUzMDZBXHU1MDI0XHUzMDRDXHU2MzA3XHU1QjlBXHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0gICAgICAgIFVua25vd25GaWVsZCA9IFx1NTE4NVx1OTBFOFx1MzBBMlx1MzBBNFx1MzBDN1x1MzBGM1x1MzBDNlx1MzBBM1x1MzBDNlx1MzBBM1x1NTIzNlx1N0QwNFx1MzBBOFx1MzBFOVx1MzBGQzogXHUzMEQ1XHUzMEEzXHUzMEZDXHUzMEVCXHUzMEM5InswfSJcdTMwNENcdTRFMERcdTY2MEVcdTMwNjdcdTMwNTlcdTMwMDIKLQotIyBJZGVhbGx5LCB3ZSBzaG91bGQgb25seSB1c2UgdGhlIGZvbGxvd2luZyBlcnJvciBrZXlzLCBub3QgdGhlIG9uZXMgdW5kZXIKLSMgIklkZW50aXR5IGNvbnN0cmFpbnRzIi4gQW5kIHdlIHNob3VsZCBjb3ZlciBhbGwgb2YgdGhlIGZvbGxvd2luZyBlcnJvcnMuCi0KLSN2YWxpZGF0aW9uICgzLlguNCkKLQotICAgICAgICBjdmMtYXR0cmlidXRlLjMgPSBjdmMtYXR0cmlidXRlLjM6IFx1ODk4MVx1N0QyMCcnezB9JydcdTMwNkVcdTVDNUVcdTYwMjcnJ3sxfScnXHUzMDZFXHU1MDI0Jyd7Mn0nJ1x1MzA2Rlx1MzAwMVx1MzA1RFx1MzA2RVx1MzBCRlx1MzBBNFx1MzBENycnezN9JydcdTMwNkJcdTVCRkVcdTMwNTdcdTMwNjZcdTcxMjFcdTUyQjlcdTMwNjdcdTMwNTlcdTMwMDIKLSAgICAgICAgY3ZjLWF0dHJpYnV0ZS40ID0gY3ZjLWF0dHJpYnV0ZS40OiBcdTg5ODFcdTdEMjAnJ3swfScnXHUzMDZFXHU1QzVFXHU2MDI3Jyd7MX0nJ1x1MzA2RVx1NTAyNCcnezJ9JydcdTMwNkZcdTMwMDFcdTU2RkFcdTVCOUFcdTMwNkUneyd2YWx1ZSBjb25zdHJhaW50J30nXHUzMDZCXHU1QkZFXHUzMDU3XHUzMDY2XHU3MTIxXHU1MkI5XHUzMDY3XHUzMDU5XHUzMDAyXHU1QzVFXHU2MDI3XHUzMDZFXHU1MDI0XHUzMDZGJyd7M30nJ1x1MzA2N1x1MzA0Mlx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBjdmMtY29tcGxleC10eXBlLjIuMSA9IGN2Yy1jb21wbGV4LXR5cGUuMi4xOiBcdTMwQkZcdTMwQTRcdTMwRDdcdTMwNkVcdTMwQjNcdTMwRjNcdTMwQzZcdTMwRjNcdTMwQzRcdTMwRkJcdTMwQkZcdTMwQTRcdTMwRDdcdTMwNENcdTdBN0FcdTc2N0RcdTMwNjdcdTMwNDJcdTMwOEJcdTMwNUZcdTMwODFcdTMwMDFcdTg5ODFcdTdEMjAnJ3swfScnXHUzMDZCXHUzMDZGXHU2NTg3XHU1QjU3XHUzMDg0XHU4OTgxXHU3RDIwXHU2MEM1XHU1ODMxXHUzMEEyXHUzMEE0XHUzMEM2XHUzMEUwW2NoaWxkcmVuXVx1MzA5Mlx1NEY3Rlx1NzUyOFx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotICAgICAgICBjdmMtY29tcGxleC10eXBlLjIuMiA9IGN2Yy1jb21wbGV4LXR5cGUuMi4yOiBcdTg5ODFcdTdEMjAnJ3swfScnXHUzMDZGXHU4OTgxXHU3RDIwW2NoaWxkcmVuXVx1MzA5Mlx1NTQyQlx1MzA3RVx1MzA1QVx1MzAwMVx1NjcwOVx1NTJCOVx1MzA2QVx1NTAyNFx1MzA2N1x1MzA0Mlx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBjdmMtY29tcGxleC10eXBlLjIuMyA9IGN2Yy1jb21wbGV4LXR5cGUuMi4zOiBcdTMwQkZcdTMwQTRcdTMwRDdcdTMwNkVcdTMwQjNcdTMwRjNcdTMwQzZcdTMwRjNcdTMwQzRcdTMwRkJcdTMwQkZcdTMwQTRcdTMwRDdcdTMwNENcdTg5ODFcdTdEMjBcdTMwNkVcdTMwN0ZcdTMwNjdcdTMwNDJcdTMwOEJcdTMwNUZcdTMwODFcdTMwMDFcdTg5ODFcdTdEMjAnJ3swfScnXHUzMDZCXHUzMDZGXHU2NTg3XHU1QjU3W2NoaWxkcmVuXVx1MzA5Mlx1NEY3Rlx1NzUyOFx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotICAgICAgICBjdmMtY29tcGxleC10eXBlLjIuNC5hID0gY3ZjLWNvbXBsZXgtdHlwZS4yLjQuYTogXHU4OTgxXHU3RDIwJyd7MH0nJ1x1MzA2N1x1NTlDQlx1MzA3RVx1MzA4Qlx1NzEyMVx1NTJCOVx1MzA2QVx1MzBCM1x1MzBGM1x1MzBDNlx1MzBGM1x1MzBDNFx1MzA0Q1x1ODk4Qlx1MzA2NFx1MzA0Qlx1MzA4QVx1MzA3RVx1MzA1N1x1MzA1Rlx1MzAwMicnezF9JydcdTMwNkVcdTMwNDRcdTMwNUFcdTMwOENcdTMwNEJcdTMwNENcdTVGQzVcdTg5ODFcdTMwNjdcdTMwNTlcdTMwMDIKLSAgICAgICAgY3ZjLWNvbXBsZXgtdHlwZS4yLjQuYiA9IGN2Yy1jb21wbGV4LXR5cGUuMi40LmI6IFx1ODk4MVx1N0QyMCcnezB9JydcdTMwNkVcdTMwQjNcdTMwRjNcdTMwQzZcdTMwRjNcdTMwQzRcdTMwNkZcdTRFMERcdTVCOENcdTUxNjhcdTMwNjdcdTMwNTlcdTMwMDInJ3sxfScnXHUzMDZFXHUzMDQ0XHUzMDVBXHUzMDhDXHUzMDRCXHUzMDRDXHU1RkM1XHU4OTgxXHUzMDY3XHUzMDU5XHUzMDAyCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuMi40LmMgPSBjdmMtY29tcGxleC10eXBlLjIuNC5jOiBcdTMwRUZcdTMwQTRcdTMwRUJcdTMwQzlcdTMwQUJcdTMwRkNcdTMwQzlcdTMwNkVcdTRFMDBcdTgxRjRcdTMwNkZcdTUzQjNcdTVCQzZcdTMwNjdcdTMwNTlcdTMwNENcdTMwMDFcdTg5ODFcdTdEMjAnJ3swfScnXHUzMDY3XHU1QkEzXHU4QTAwXHUzMDRDXHU4OThCXHUzMDY0XHUzMDRCXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuMi40LmQgPSBjdmMtY29tcGxleC10eXBlLjIuNC5kOiBcdTg5ODFcdTdEMjAnJ3swfScnXHUzMDY3XHU1OUNCXHUzMDdFXHUzMDhCXHU3MTIxXHU1MkI5XHUzMDZBXHUzMEIzXHUzMEYzXHUzMEM2XHUzMEYzXHUzMEM0XHUzMDRDXHU4OThCXHUzMDY0XHUzMDRCXHUzMDhBXHUzMDdFXHUzMDU3XHUzMDVGXHUzMDAyXHUzMDUzXHUzMDUzXHUzMDY3XHUzMDZGXHU1QjUwXHU4OTgxXHU3RDIwXHUzMDkyXHU0RjdGXHU3NTI4XHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuMi40LmUgPSBjdmMtY29tcGxleC10eXBlLjIuNC5kOiBcdTg5ODFcdTdEMjAnJ3swfScnXHUzMDY3XHU1OUNCXHUzMDdFXHUzMDhCXHU3MTIxXHU1MkI5XHUzMDZBXHUzMEIzXHUzMEYzXHUzMEM2XHUzMEYzXHUzMEM0XHUzMDRDXHU4OThCXHUzMDY0XHUzMDRCXHUzMDhBXHUzMDdFXHUzMDU3XHUzMDVGXHUzMDAyXHUzMDUzXHUzMDUzXHUzMDY3XHUzMDZGXHU1QjUwXHU4OTgxXHU3RDIwJyd7MX0nJ1x1MzA5Mlx1NEY3Rlx1NzUyOFx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotICAgICAgICBjdmMtY29tcGxleC10eXBlLjMuMSA9IGN2Yy1jb21wbGV4LXR5cGUuMy4xOiBcdTg5ODFcdTdEMjAnJ3swfScnXHUzMDZFXHU1QzVFXHU2MDI3Jyd7MX0nJ1x1MzA2RVx1NTAyNCcnezJ9JydcdTMwNkZcdTMwMDFcdTVCRkVcdTVGRENcdTMwNTlcdTMwOEJcdTVDNUVcdTYwMjdcdTRGN0ZcdTc1MjhcdTMwNkJcdTVCRkVcdTMwNTdcdTMwNjZcdTcxMjFcdTUyQjlcdTMwNjdcdTMwNTlcdTMwMDJcdTVDNUVcdTYwMjcnJ3sxfScnXHUzMDZCXHUzMDZGXHU1NkZBXHU1QjlBXHU1MDI0Jyd7M30iXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuMy4yLjEgPSBjdmMtY29tcGxleC10eXBlLjMuMi4xOiBcdTg5ODFcdTdEMjAnJ3swfScnXHUzMDZCXHUzMDAxXHU1QzVFXHU2MDI3Jyd7MX0nJ1x1NzUyOFx1MzA2RVx1NUM1RVx1NjAyN1x1MzBFRlx1MzBBNFx1MzBFQlx1MzBDOVx1MzBBQlx1MzBGQ1x1MzBDOVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotICAgICAgICBjdmMtY29tcGxleC10eXBlLjMuMi4yID0gY3ZjLWNvbXBsZXgtdHlwZS4zLjIuMjogXHU4OTgxXHU3RDIwJyd7MH0nJ1x1MzA2Qlx1NUM1RVx1NjAyNycnezF9JydcdTMwOTJcdTU0MkJcdTMwODFcdTMwOEJcdTMwNTNcdTMwNjhcdTMwNkZcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLSAgICAgICAgY3ZjLWNvbXBsZXgtdHlwZS40ID0gY3ZjLWNvbXBsZXgtdHlwZS40OiBcdTg5ODFcdTdEMjAnJ3swfScnXHUzMDZCXHU1QzVFXHU2MDI3Jyd7MX0nJ1x1MzA0Q1x1NTQyQlx1MzA3RVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBjdmMtY29tcGxleC10eXBlLjUuMSA9IGN2Yy1jb21wbGV4LXR5cGUuNS4xOiBcdTg5ODFcdTdEMjAnJ3swfScnXHUzMDY3XHUzMDZGXHU1QzVFXHU2MDI3Jyd7MX0nJ1x1MzA0Q1dpbGQgSURcdTMwNjdcdTMwNTlcdTMwNENcdTMwMDFcdTMwNTlcdTMwNjdcdTMwNkJXaWxkIElEICcnezJ9JydcdTMwNENcdTVCNThcdTU3MjhcdTMwNTdcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTlcdTMwMDJcdThBMzFcdTUzRUZcdTMwNTVcdTMwOENcdTMwOEJXaWxkIElEXHUzMDZGMVx1MzA2NFx1MzA2RVx1MzA3Rlx1MzA2N1x1MzA1OVx1MzAwMgotICAgICAgICBjdmMtY29tcGxleC10eXBlLjUuMiA9IGN2Yy1jb21wbGV4LXR5cGUuNS4yOiBcdTg5ODFcdTdEMjAnJ3swfScnXHUzMDY3XHUzMDZGXHU1QzVFXHU2MDI3Jyd7MX0nJ1x1MzA0Q1dpbGQgSURcdTMwNjdcdTMwNTlcdTMwNENcdTMwMDFJRFx1MzA0Qlx1MzA4OVx1NUMwRVx1NTFGQVx1MzA1NVx1MzA4Q1x1MzA1Rlx1NUM1RVx1NjAyNycnezJ9JydcdTMwNEMneydhdHRyaWJ1dGUgdXNlcyd9J1x1MzA2Qlx1MzA1OVx1MzA2N1x1MzA2Qlx1NUI1OFx1NTcyOFx1MzA1N1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBjdmMtZGF0YXR5cGUtdmFsaWQuMS4yLjEgPSBjdmMtZGF0YXR5cGUtdmFsaWQuMS4yLjE6ICcnezB9JydcdTMwNkYnJ3sxfScnXHUzMDZFXHU2NzA5XHU1MkI5XHUzMDZBXHU1MDI0XHUzMDY3XHUzMDZGXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0gICAgICAgIGN2Yy1kYXRhdHlwZS12YWxpZC4xLjIuMiA9IGN2Yy1kYXRhdHlwZS12YWxpZC4xLjIuMjogJyd7MH0nJ1x1MzA2Rlx1MzBFQVx1MzBCOVx1MzBDOFx1MzBGQlx1MzBCRlx1MzBBNFx1MzBENycnezF9JydcdTMwNkVcdTY3MDlcdTUyQjlcdTMwNkFcdTUwMjRcdTMwNjdcdTMwNkZcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLSAgICAgICAgY3ZjLWRhdGF0eXBlLXZhbGlkLjEuMi4zID0gY3ZjLWRhdGF0eXBlLXZhbGlkLjEuMi4zOiAnJ3swfScnXHUzMDZGXHU1MTcxXHU3NTI4XHU0RjUzXHUzMEJGXHUzMEE0XHUzMEQ3Jyd7MX0nJ1x1MzA2RVx1NjcwOVx1NTJCOVx1MzA2QVx1NTAyNFx1MzA2N1x1MzA2Rlx1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotICAgICAgICBjdmMtZWx0LjEgPSBjdmMtZWx0LjE6IFx1ODk4MVx1N0QyMCcnezB9JydcdTMwNkVcdTVCQTNcdThBMDBcdTMwNENcdTg5OEJcdTMwNjRcdTMwNEJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLSAgICAgICAgY3ZjLWVsdC4yID0gY3ZjLWVsdC4yOiAnJ3swfScnXHUzMDZCXHU1QkZFXHUzMDU5XHUzMDhCXHU4OTgxXHU3RDIwXHU1QkEzXHU4QTAwXHUzMDZFXHU1MDI0J3snYWJzdHJhY3QnfSdcdTMwNkZcdTMwMDFmYWxzZVx1MzA2N1x1MzA0Mlx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBjdmMtZWx0LjMuMSA9IGN2Yy1lbHQuMy4xOiBcdTVDNUVcdTYwMjcnJ3sxfScnXHUzMDZGXHU4OTgxXHU3RDIwJyd7MH0nJ1x1MzA2Qlx1ODg2OFx1NzkzQVx1MzA1NVx1MzA4Q1x1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMlx1MzA1M1x1MzA4Q1x1MzA2Rlx1MzAwMSd7J25pbGxhYmxlJ30nXHUzMEQ3XHUzMEVEXHUzMEQxXHUzMEM2XHUzMEEzKCcnezB9JycpXHUzMDRDZmFsc2VcdTMwNjdcdTMwNDJcdTMwOEJcdTMwNUZcdTMwODFcdTMwNjdcdTMwNTlcdTMwMDIKLSAgICAgICAgY3ZjLWVsdC4zLjIuMSA9IGN2Yy1lbHQuMy4yLjE6ICcnezF9JydcdTMwNENcdTYzMDdcdTVCOUFcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwOEJcdTMwNUZcdTMwODFcdTMwMDFcdTg5ODFcdTdEMjAnJ3swfScnXHUzMDZCXHUzMDZGXHU2NTg3XHU1QjU3XHUzMDg0XHU4OTgxXHU3RDIwXHU2MEM1XHU1ODMxW2NoaWxkcmVuXVx1MzA5Mlx1NEY3Rlx1NzUyOFx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotICAgICAgICBjdmMtZWx0LjMuMi4yID0gY3ZjLWVsdC4zLjIuMjogXHU1NkZBXHU1QjlBXHUzMDZFJ3sndmFsdWUgY29uc3RyYWludCd9J1x1MzA5Mlx1ODk4MVx1N0QyMCcnezB9JydcdTMwNkJcdTVCRkVcdTMwNTdcdTMwNjZcdTRGN0ZcdTc1MjhcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDInJ3sxfScnXHUzMDRDXHU2MzA3XHU1QjlBXHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIGN2Yy1lbHQuNC4xID0gY3ZjLWVsdC40LjE6IFx1ODk4MVx1N0QyMCcnezB9JydcdTMwNkVcdTVDNUVcdTYwMjcnJ3sxfScnXHUzMDZFXHU1MDI0Jyd7Mn0nJ1x1MzA2Rlx1NjcwOVx1NTJCOVx1MzA2QVFOYW1lXHUzMDY3XHUzMDZGXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0gICAgICAgIGN2Yy1lbHQuNC4yID0gY3ZjLWVsdC40LjI6ICcnezF9JydcdTMwOTJcdTg5ODFcdTdEMjAnJ3swfScnXHUzMDZFXHUzMEJGXHUzMEE0XHUzMEQ3XHU1QjlBXHU3RkE5XHUzMDZCXHU4OUUzXHU2QzdBXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0gICAgICAgIGN2Yy1lbHQuNC4zID0gY3ZjLWVsdC40LjM6IFx1MzBCRlx1MzBBNFx1MzBENycnezF9JydcdTMwNkZcdTMwMDFcdTg5ODFcdTdEMjAnJ3swfScnXHUzMDZFXHUzMEJGXHUzMEE0XHUzMEQ3XHU1QjlBXHU3RkE5Jyd7Mn0nJ1x1MzA0Qlx1MzA4OVx1NkI2M1x1NUUzOFx1MzA2Qlx1NUMwRVx1NTFGQVx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotICAgICAgICBjdmMtZWx0LjUuMS4xID0gY3ZjLWVsdC41LjEuMTogJ3sndmFsdWUgY29uc3RyYWludCd9JyAnJ3syfScnKFx1ODk4MVx1N0QyMCcnezB9JycpXHUzMDZGXHUzMDAxXHUzMEJGXHUzMEE0XHUzMEQ3Jyd7MX0nJ1x1MzA2RVx1NjcwOVx1NTJCOVx1MzA2QVx1MzBDN1x1MzBENVx1MzBBOVx1MzBFQlx1MzBDOFx1NTAyNFx1MzA2N1x1MzA2Rlx1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotICAgICAgICBjdmMtZWx0LjUuMi4yLjEgPSBjdmMtZWx0LjUuMi4yLjE6IFx1ODk4MVx1N0QyMCcnezB9JydcdTMwNkJcdTMwNkZcdTg5ODFcdTdEMjBcdTYwQzVcdTU4MzFcdTMwQTJcdTMwQTRcdTMwQzZcdTMwRTBbY2hpbGRyZW5dXHUzMDkyXHU0RjdGXHU3NTI4XHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0gICAgICAgIGN2Yy1lbHQuNS4yLjIuMi4xID0gY3ZjLWVsdC41LjIuMi4yLjE6IFx1ODk4MVx1N0QyMCcnezB9JydcdTMwNkVcdTUwMjQnJ3sxfScnXHUzMDRDXHUzMDAxXHU1NkZBXHU1QjlBXHUzMDZFJ3sndmFsdWUgY29uc3RyYWludCd9J1x1NTAyNCcnezJ9JydcdTMwNkJcdTRFMDBcdTgxRjRcdTMwNTdcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLSAgICAgICAgY3ZjLWVsdC41LjIuMi4yLjIgPSBjdmMtZWx0LjUuMi4yLjIuMjogXHU4OTgxXHU3RDIwJyd7MH0nJ1x1MzA2RVx1NTAyNCcnezF9JydcdTMwNENcdTMwMDEneyd2YWx1ZSBjb25zdHJhaW50J30nXHU1MDI0Jyd7Mn0nJ1x1MzA2Qlx1NEUwMFx1ODFGNFx1MzA1N1x1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotICAgICAgICBjdmMtZW51bWVyYXRpb24tdmFsaWQgPSBjdmMtZW51bWVyYXRpb24tdmFsaWQ6IFx1NTAyNCcnezB9JydcdTMwNkZcdTMwMDFcdTUyMTdcdTYzMTknJ3sxfScnXHUzMDZCXHU1QkZFXHUzMDU3XHUzMDY2XHUzMEQ1XHUzMEExXHUzMEJCXHUzMEMzXHUzMEM4XHUzMDRDXHU2NzA5XHU1MkI5XHUzMDY3XHUzMDZGXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyXHU1MjE3XHU2MzE5XHUzMDRCXHUzMDg5XHUzMDZFXHU1MDI0XHUzMDY3XHUzMDQyXHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIGN2Yy1mcmFjdGlvbkRpZ2l0cy12YWxpZCA9IGN2Yy1mcmFjdGlvbkRpZ2l0cy12YWxpZDogXHU1MDI0Jyd7MH0nJ1x1MzA2RVx1NUMwRlx1NjU3MFx1MzA2RVx1Njg0MVx1NjU3MFx1MzA2RnsxfVx1MzA2N1x1MzA1OVx1MzA0Q1x1MzAwMVx1NUMwRlx1NjU3MFx1MzA2RVx1Njg0MVx1NjU3MFx1MzA2RnsyfVx1MzA2Qlx1NTIzNlx1OTY1MFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBjdmMtaWQuMSA9IGN2Yy1pZC4xOiBJRFJFRiAnJ3swfScnXHUzMDZFSUQvSURSRUZcdTMwRDBcdTMwQTRcdTMwRjNcdTMwQzdcdTMwQTNcdTMwRjNcdTMwQjBcdTMwNkZcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLSAgICAgICAgY3ZjLWlkLjIgPSBjdmMtaWQuMjogSURcdTUwMjQnJ3swfScnXHUzMDRDXHU4OTA3XHU2NTcwXHU1MUZBXHU3M0ZFXHUzMDU3XHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIGN2Yy1pZC4zID0gY3ZjLWlkLjM6IFx1MzBBMlx1MzBBNFx1MzBDN1x1MzBGM1x1MzBDNlx1MzBBM1x1MzBDNlx1MzBBM1x1NTIzNlx1N0QwNCcnezB9JydcdTMwNkVcdTMwRDVcdTMwQTNcdTMwRkNcdTMwRUJcdTMwQzlcdTMwNENcdTg5ODFcdTdEMjAnJ3sxfScnXHUzMDZCXHU0RTAwXHU4MUY0XHUzMDU3XHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5XHUzMDRDXHUzMDAxXHUzMDUzXHUzMDZFXHU4OTgxXHU3RDIwXHUzMDZCXHUzMDZGXHU1MzU4XHU3RDE0XHU1NzhCXHUzMDRDXHU1NDJCXHUzMDdFXHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0gICAgICAgIGN2Yy1sZW5ndGgtdmFsaWQgPSBjdmMtbGVuZ3RoLXZhbGlkOiBcdTk1NzdcdTMwNTVcdTMwNEMnJ3sxfScnXHUzMDY3XHUzMDQyXHUzMDhCXHU1MDI0Jyd7MH0nJ1x1MzA2Rlx1MzAwMVx1MzBCRlx1MzBBNFx1MzBENycnezN9JydcdTMwNkVcdTk1NzdcdTMwNTUnJ3syfScnXHUzMDZCXHU1QkZFXHUzMDU3XHUzMDY2XHUzMEQ1XHUzMEExXHUzMEJCXHUzMEMzXHUzMEM4XHUzMDRDXHU2NzA5XHU1MkI5XHUzMDY3XHUzMDZGXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0gICAgICAgIGN2Yy1tYXhFeGNsdXNpdmUtdmFsaWQgPSBjdmMtbWF4RXhjbHVzaXZlLXZhbGlkOiBcdTUwMjQnJ3swfScnXHUzMDZGXHUzMDAxXHUzMEJGXHUzMEE0XHUzMEQ3Jyd7Mn0nJ1x1MzA2RW1heEV4Y2x1c2l2ZSAnJ3sxfScnXHUzMDZCXHU1QkZFXHUzMDU3XHUzMDY2XHUzMEQ1XHUzMEExXHUzMEJCXHUzMEMzXHUzMEM4XHUzMDRDXHU2NzA5XHU1MkI5XHUzMDY3XHUzMDZGXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0gICAgICAgIGN2Yy1tYXhJbmNsdXNpdmUtdmFsaWQgPSBjdmMtbWF4SW5jbHVzaXZlLXZhbGlkOiBcdTUwMjQnJ3swfScnXHUzMDZGXHUzMDAxXHUzMEJGXHUzMEE0XHUzMEQ3Jyd7Mn0nJ1x1MzA2RW1heEluY2x1c2l2ZSAnJ3sxfScnXHUzMDZCXHU1QkZFXHUzMDU3XHUzMDY2XHUzMEQ1XHUzMEExXHUzMEJCXHUzMEMzXHUzMEM4XHUzMDRDXHU2NzA5XHU1MkI5XHUzMDY3XHUzMDZGXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0gICAgICAgIGN2Yy1tYXhMZW5ndGgtdmFsaWQgPSBjdmMtbWF4TGVuZ3RoLXZhbGlkOiBcdTk1NzdcdTMwNTVcdTMwNEMnJ3sxfScnXHUzMDY3XHUzMDQyXHUzMDhCXHU1MDI0Jyd7MH0nJ1x1MzA2Rlx1MzAwMVx1MzBCRlx1MzBBNFx1MzBENycnezN9JydcdTMwNkVtYXhMZW5ndGggJyd7Mn0nJ1x1MzA2Qlx1NUJGRVx1MzA1N1x1MzA2Nlx1MzBENVx1MzBBMVx1MzBCQlx1MzBDM1x1MzBDOFx1MzA0Q1x1NjcwOVx1NTJCOVx1MzA2N1x1MzA2Rlx1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotICAgICAgICBjdmMtbWluRXhjbHVzaXZlLXZhbGlkID0gY3ZjLW1pbkV4Y2x1c2l2ZS12YWxpZDogXHU1MDI0Jyd7MH0nJ1x1MzA2Rlx1MzAwMVx1MzBCRlx1MzBBNFx1MzBENycnezJ9JydcdTMwNkVtaW5FeGNsdXNpdmUgJyd7MX0nJ1x1MzA2Qlx1NUJGRVx1MzA1N1x1MzA2Nlx1MzBENVx1MzBBMVx1MzBCQlx1MzBDM1x1MzBDOFx1MzA0Q1x1NjcwOVx1NTJCOVx1MzA2N1x1MzA2Rlx1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotICAgICAgICBjdmMtbWluSW5jbHVzaXZlLXZhbGlkID0gY3ZjLW1pbkluY2x1c2l2ZS12YWxpZDogXHU1MDI0Jyd7MH0nJ1x1MzA2Rlx1MzAwMVx1MzBCRlx1MzBBNFx1MzBENycnezJ9JydcdTMwNkVtaW5JbmNsdXNpdmUgJyd7MX0nJ1x1MzA2Qlx1NUJGRVx1MzA1N1x1MzA2Nlx1MzBENVx1MzBBMVx1MzBCQlx1MzBDM1x1MzBDOFx1MzA0Q1x1NjcwOVx1NTJCOVx1MzA2N1x1MzA2Rlx1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotICAgICAgICBjdmMtbWluTGVuZ3RoLXZhbGlkID0gY3ZjLW1pbkxlbmd0aC12YWxpZDogXHU5NTc3XHUzMDU1XHUzMDRDJyd7MX0nJ1x1MzA2N1x1MzA0Mlx1MzA4Qlx1NTAyNCcnezB9JydcdTMwNkZcdTMwMDFcdTMwQkZcdTMwQTRcdTMwRDcnJ3szfScnXHUzMDZFbWluTGVuZ3RoICcnezJ9JydcdTMwNkJcdTVCRkVcdTMwNTdcdTMwNjZcdTMwRDVcdTMwQTFcdTMwQkJcdTMwQzNcdTMwQzhcdTMwNENcdTY3MDlcdTUyQjlcdTMwNjdcdTMwNkZcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLSAgICAgICAgY3ZjLXBhdHRlcm4tdmFsaWQgPSBjdmMtcGF0dGVybi12YWxpZDogXHU1MDI0Jyd7MH0nJ1x1MzA2Rlx1MzAwMVx1MzBCRlx1MzBBNFx1MzBENycnezJ9JydcdTMwNkVcdTMwRDFcdTMwQkZcdTMwRkNcdTMwRjMnJ3sxfScnXHUzMDZCXHU1QkZFXHUzMDU3XHUzMDY2XHUzMEQ1XHUzMEExXHUzMEJCXHUzMEMzXHUzMEM4XHUzMDRDXHU2NzA5XHU1MkI5XHUzMDY3XHUzMDZGXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0gICAgICAgIGN2Yy10b3RhbERpZ2l0cy12YWxpZCA9IGN2Yy10b3RhbERpZ2l0cy12YWxpZDogXHU1MDI0Jyd7MH0nJ1x1MzA2RVx1N0RDRlx1Njg0MVx1NjU3MFx1MzA2RnsxfVx1MzA2N1x1MzA1OVx1MzA0Q1x1MzAwMVx1N0RDRlx1Njg0MVx1NjU3MFx1MzA2RnsyfVx1MzA2Qlx1NTIzNlx1OTY1MFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBjdmMtdHlwZS4yID0gY3ZjLXR5cGUuMjogXHUzMEJGXHUzMEE0XHUzMEQ3XHUzMDZFXHU1QjlBXHU3RkE5XHUzMDZGXHU4OTgxXHU3RDIwezB9XHUzMDZCXHU1QkZFXHUzMDU3XHUzMDY2XHU2MkJEXHU4QzYxXHU3Njg0XHUzMDZCXHUzMDZGXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0gICAgICAgIGN2Yy10eXBlLjMuMS4xID0gY3ZjLXR5cGUuMy4xLjE6IFx1ODk4MVx1N0QyMCcnezB9JydcdTMwNkZcdTUzNThcdTdEMTRcdTU3OEJcdTMwNjdcdTMwNDJcdTMwOEJcdTMwNUZcdTMwODFcdTMwMDFcdTMwQ0RcdTMwRkNcdTMwRTBcdTMwQjlcdTMwREFcdTMwRkNcdTMwQjlcdTU0MERcdTMwNEMnJ2h0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlJydcdTMwNjhcdTU0MENcdTRFMDBcdTMwNkVcdTVDNUVcdTYwMjdcdTMwNjhbbG9jYWwgbmFtZV1cdTMwNEMnJ3R5cGUnJ1x1MzAwMScnbmlsJydcdTMwMDEnJ3NjaGVtYUxvY2F0aW9uJydcdTMwN0VcdTMwNUZcdTMwNkYnJ25vTmFtZXNwYWNlU2NoZW1hTG9jYXRpb24nJ1x1MzA2RVx1MzA0NFx1MzA1QVx1MzA4Q1x1MzA0Qlx1MzA2N1x1MzA0Mlx1MzA4Qlx1NUM1RVx1NjAyN1x1NEVFNVx1NTkxNlx1MzA2Rlx1MzAwMVx1NUM1RVx1NjAyN1x1MzA5Mlx1NTQyQlx1MzA4MVx1MzA4Qlx1MzA1M1x1MzA2OFx1MzA2Rlx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMlx1MzA1RFx1MzA4Q1x1MzA2Qlx1MzA4Mlx1MzA0Qlx1MzA0Qlx1MzA4Rlx1MzA4OVx1MzA1QVx1NUM1RVx1NjAyNycnezF9JydcdTMwNENcdTg5OEJcdTMwNjRcdTMwNEJcdTMwOEFcdTMwN0VcdTMwNTdcdTMwNUZcdTMwMDIKLSAgICAgICAgY3ZjLXR5cGUuMy4xLjIgPSBjdmMtdHlwZS4zLjEuMjogXHU4OTgxXHU3RDIwJyd7MH0nJ1x1MzA2Rlx1NTM1OFx1N0QxNFx1NTc4Qlx1MzA2N1x1MzA0Mlx1MzA4Qlx1MzA1Rlx1MzA4MVx1MzAwMVx1ODk4MVx1N0QyMFx1NjBDNVx1NTgzMVx1MzBBMlx1MzBBNFx1MzBDNlx1MzBFMFtjaGlsZHJlbl1cdTMwOTJcdTU0MkJcdTMwODFcdTMwOEJcdTMwNTNcdTMwNjhcdTMwNkZcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLSAgICAgICAgY3ZjLXR5cGUuMy4xLjMgPSBjdmMtdHlwZS4zLjEuMzogXHU4OTgxXHU3RDIwJyd7MH0nJ1x1MzA2RVx1NTAyNCcnezF9JydcdTMwNkZcdTcxMjFcdTUyQjlcdTMwNjdcdTMwNTlcdTMwMDIKLQotI3NjaGVtYSB2YWxpZCAoMy5YLjMpCi0KLSAgICAgICAgc2NoZW1hX3JlZmVyZW5jZS5hY2Nlc3MgPSBzY2hlbWFfcmVmZXJlbmNlOiBhY2Nlc3NFeHRlcm5hbFNjaGVtYVx1MzBEN1x1MzBFRFx1MzBEMVx1MzBDNlx1MzBBM1x1MzA2N1x1OEEyRFx1NUI5QVx1MzA1NVx1MzA4Q1x1MzA1Rlx1NTIzNlx1OTY1MFx1MzA2Qlx1MzA4OFx1MzA4QScnezF9JydcdTMwQTJcdTMwQUZcdTMwQkJcdTMwQjlcdTMwNENcdThBMzFcdTUzRUZcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwNkFcdTMwNDRcdTMwNUZcdTMwODFcdTMwMDFcdTMwQjlcdTMwQURcdTMwRkNcdTMwREVcdTMwRkJcdTMwQzlcdTMwQURcdTMwRTVcdTMwRTFcdTMwRjNcdTMwQzgnJ3swfScnXHUzMDZFXHU4QUFEXHU1M0Q2XHUzMDhBXHUzMDZCXHU1OTMxXHU2NTU3XHUzMDU3XHUzMDdFXHUzMDU3XHUzMDVGXHUzMDAyCi0gICAgICAgIHNjaGVtYV9yZWZlcmVuY2UuNCA9IHNjaGVtYV9yZWZlcmVuY2UuNDogMSlcdTMwQzlcdTMwQURcdTMwRTVcdTMwRTFcdTMwRjNcdTMwQzhcdTMwNENcdTg5OEJcdTMwNjRcdTMwNEJcdTMwODlcdTMwNkFcdTMwNEJcdTMwNjNcdTMwNUZcdTMwMDEyKVx1MzBDOVx1MzBBRFx1MzBFNVx1MzBFMVx1MzBGM1x1MzBDOFx1MzA5Mlx1OEFBRFx1MzA3Rlx1NTNENlx1MzA4Q1x1MzA2QVx1MzA0Qlx1MzA2M1x1MzA1Rlx1MzAwMTMpXHUzMEM5XHUzMEFEXHUzMEU1XHUzMEUxXHUzMEYzXHUzMEM4XHUzMDZFXHUzMEVCXHUzMEZDXHUzMEM4XHU4OTgxXHU3RDIwXHUzMDRDPHhzZDpzY2hlbWE+XHUzMDY3XHUzMDZGXHUzMDZBXHUzMDRCXHUzMDYzXHUzMDVGXHUzMDVGXHUzMDgxXHUzMDAxXHUzMEI5XHUzMEFEXHUzMEZDXHUzMERFXHUzMEZCXHUzMEM5XHUzMEFEXHUzMEU1XHUzMEUxXHUzMEYzXHUzMEM4Jyd7MH0nJ1x1MzA2RVx1OEFBRFx1NTNENlx1MzA4QVx1MzA2Qlx1NTkzMVx1NjU1N1x1MzA1N1x1MzA3RVx1MzA1N1x1MzA1Rlx1MzAwMgotICAgICAgICBzcmMtYW5ub3RhdGlvbiA9IHNyYy1hbm5vdGF0aW9uOiA8YW5ub3RhdGlvbj5cdTg5ODFcdTdEMjBcdTMwNkJcdTU0MkJcdTMwODFcdTMwOEJcdTMwNTNcdTMwNjhcdTMwNENcdTMwNjdcdTMwNERcdTMwOEJcdTMwNkVcdTMwNkY8YXBwaW5mbz5cdTg5ODFcdTdEMjBcdTMwNEFcdTMwODhcdTMwNzM8ZG9jdW1lbnRhdGlvbj5cdTg5ODFcdTdEMjBcdTMwNkVcdTMwN0ZcdTMwNjdcdTMwNTlcdTMwNENcdTMwMDEnJ3swfScnXHUzMDRDXHU4OThCXHUzMDY0XHUzMDRCXHUzMDhBXHUzMDdFXHUzMDU3XHUzMDVGXHUzMDAyCi0gICAgICAgIHNyYy1hdHRyaWJ1dGUuMSA9IHNyYy1hdHRyaWJ1dGUuMTogJydkZWZhdWx0JydcdTMwNjgnJ2ZpeGVkJydcdTMwNkVcdTRFMjFcdTY1QjlcdTMwNkVcdTMwRDdcdTMwRURcdTMwRDFcdTMwQzZcdTMwQTNcdTMwOTJcdTVDNUVcdTYwMjdcdTVCQTNcdThBMDAnJ3swfScnXHUzMDZCXHU1NDJCXHUzMDgxXHUzMDhCXHUzMDUzXHUzMDY4XHUzMDZGXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyXHUzMDQ0XHUzMDVBXHUzMDhDXHUzMDRCXHU0RTAwXHU2NUI5XHUzMDZFXHUzMDdGXHUzMDkyXHU0RjdGXHU3NTI4XHUzMDU3XHUzMDY2XHUzMDRGXHUzMDYwXHUzMDU1XHUzMDQ0XHUzMDAyCi0gICAgICAgIHNyYy1hdHRyaWJ1dGUuMiA9IHNyYy1hdHRyaWJ1dGUuMjogOiBcdTVDNUVcdTYwMjcnJ3swfScnXHUzMDZCXHUzMEQ3XHUzMEVEXHUzMEQxXHUzMEM2XHUzMEEzJydkZWZhdWx0JydcdTMwNENcdTRGN0ZcdTc1MjhcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwOEJcdTMwNUZcdTMwODFcdTMwMDEnJ3VzZScnXHUzMDZFXHU1MDI0XHUzMDZGJydvcHRpb25hbCcnXHUzMDZCXHUzMDU5XHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIHNyYy1hdHRyaWJ1dGUuMy4xID0gc3JjLWF0dHJpYnV0ZS4zLjE6ICdyZWYnXHUzMDdFXHUzMDVGXHUzMDZGJ25hbWUnXHUzMDZFXHUzMDQ0XHUzMDVBXHUzMDhDXHUzMDRCXHUzMDRDXHUzMEVEXHUzMEZDXHUzMEFCXHUzMEVCXHU1QzVFXHU2MDI3XHU1QkEzXHU4QTAwXHUzMDZCXHU0RjdGXHU3NTI4XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIHNyYy1hdHRyaWJ1dGUuMy4yID0gc3JjLWF0dHJpYnV0ZS4zLjI6IFx1MzBCM1x1MzBGM1x1MzBDNlx1MzBGM1x1MzBDNFx1MzA2Rlx1NUM1RVx1NjAyN1x1NTNDMlx1NzE2NycnezB9JydcdTMwNkUoYW5ub3RhdGlvbj8pXHUzMDY4XHU0RTAwXHU4MUY0XHUzMDU5XHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIHNyYy1hdHRyaWJ1dGUuNCA9IHNyYy1hdHRyaWJ1dGUuNDogXHU1QzVFXHU2MDI3Jyd7MH0nJ1x1MzA2Qlx1MzAwMScndHlwZScnXHU1QzVFXHU2MDI3XHUzMDY4XHU1MzNGXHU1NDBEXHUzMDZFXHU1QjUwJydzaW1wbGVUeXBlJydcdTMwNkVcdTRFMjFcdTY1QjlcdTMwNENcdTRGN0ZcdTc1MjhcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTlcdTMwMDJcdTVDNUVcdTYwMjdcdTMwNkJcdTMwNkZcdTMwNTNcdTMwOENcdTMwODlcdTMwNkVcdTMwNDZcdTMwNjFcdTMwNDRcdTMwNUFcdTMwOENcdTMwNEJcdTRFMDBcdTY1QjlcdTMwNkVcdTMwN0ZcdTMwOTJcdTRGN0ZcdTc1MjhcdTMwNjdcdTMwNERcdTMwN0VcdTMwNTlcdTMwMDIKLSAgICAgICAgc3JjLWF0dHJpYnV0ZV9ncm91cC4yID0gc3JjLWF0dHJpYnV0ZV9ncm91cC4yOiBcdTVDNUVcdTYwMjdcdTMwQjBcdTMwRUJcdTMwRkNcdTMwRDcnJ3swfScnXHUzMDZCXHU1QkZFXHUzMDU3XHUzMDY2XHUzMEVGXHUzMEE0XHUzMEVCXHUzMEM5XHUzMEFCXHUzMEZDXHUzMEM5XHUzMDZFXHU1MTcxXHU5MDFBXHU5MEU4XHU1MjA2XHUzMDZGXHU4ODY4XHU3M0ZFXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0gICAgICAgIHNyYy1hdHRyaWJ1dGVfZ3JvdXAuMyA9IHNyYy1hdHRyaWJ1dGVfZ3JvdXAuMzogXHU1QzVFXHU2MDI3XHUzMEIwXHUzMEVCXHUzMEZDXHUzMEQ3Jyd7MH0nJ1x1MzA2N1x1NUZBQVx1NzRCMFx1NUI5QVx1N0ZBOVx1MzA0Q1x1NjkxQ1x1NTFGQVx1MzA1NVx1MzA4Q1x1MzA3RVx1MzA1N1x1MzA1Rlx1MzAwMlx1NUM1RVx1NjAyN1x1MzBCMFx1MzBFQlx1MzBGQ1x1MzBEN1x1NTNDMlx1NzE2N1x1MzA5Mlx1NTE4RFx1NUUzMFx1NzY4NFx1MzA2Qlx1MzA1Rlx1MzA2OVx1MzA4Qlx1MzA2OFx1MzAwMVx1NjcwMFx1N0Q0Mlx1NzY4NFx1MzA2Qlx1MzA2Rlx1MzA1RFx1MzA2RVx1NUM1RVx1NjAyN1x1MzBCMFx1MzBFQlx1MzBGQ1x1MzBEN1x1MzA2Qlx1NjIzQlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBzcmMtY3QuMSA9IHNyYy1jdC4xOiBcdTMwQkZcdTMwQTRcdTMwRDcnJ3swfScnXHUzMDZCXHU1QkZFXHUzMDU5XHUzMDhCXHU4OTA3XHU1NDA4XHU1NzhCXHU1QjlBXHU3RkE5XHU4ODY4XHU3M0ZFXHUzMEE4XHUzMEU5XHUzMEZDXHUzMDAyPGNvbXBsZXhDb250ZW50Plx1MzA0Q1x1NEY3Rlx1NzUyOFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA4Qlx1NTgzNFx1NTQwOFx1MzAwMVx1MzBEOVx1MzBGQ1x1MzBCOVx1MzBGQlx1MzBCRlx1MzBBNFx1MzBEN1x1MzA2RmNvbXBsZXhUeXBlXHUzMDY3XHUzMDQyXHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyJyd7MX0nJ1x1MzA2RnNpbXBsZVR5cGVcdTMwNjdcdTMwNTlcdTMwMDIKLSAgICAgICAgc3JjLWN0LjIuMSA9IHNyYy1jdC4yLjE6IFx1MzBCRlx1MzBBNFx1MzBENycnezB9JydcdTMwNkJcdTVCRkVcdTMwNTlcdTMwOEJcdTg5MDdcdTU0MDhcdTU3OEJcdTVCOUFcdTdGQTlcdTg4NjhcdTczRkVcdTMwQThcdTMwRTlcdTMwRkNcdTMwMDI8c2ltcGxlQ29udGVudD5cdTMwNENcdTRGN0ZcdTc1MjhcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwOEJcdTU4MzRcdTU0MDhcdTMwNkVcdTMwRDlcdTMwRkNcdTMwQjlcdTMwRkJcdTMwQkZcdTMwQTRcdTMwRDdcdTMwNkZcdTMwMDFcdTUzNThcdTdEMTRcdTMwNjdcdTMwNDJcdTMwOEJcdTMwNEJcdTMwMDFcdTUyMzZcdTk2NTBcdTMwNENcdTYzMDdcdTVCOUFcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwOEJcdTU4MzRcdTU0MDhcdTMwNkJcdTMwNEJcdTMwNEVcdTMwOEFcdTZERjdcdTU0MDhcdTMwQjNcdTMwRjNcdTMwQzZcdTMwRjNcdTMwQzRcdTMwNjhcdTdBN0FcdTMwNkJcdTMwNjdcdTMwNERcdTMwOEJcdTMwRDFcdTMwRkNcdTMwQzZcdTMwQTNcdTMwQUZcdTMwRUJcdTMwOTJcdTYzMDFcdTMwNjRcdTg5MDdcdTU0MDhcdTU3OEJcdTMwNjdcdTMwNDJcdTMwOEJcdTMwNEJcdTMwMDFcdTMwN0VcdTMwNUZcdTMwNkZcdTYyRTFcdTVGMzVcdTMwNENcdTYzMDdcdTVCOUFcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwOEJcdTU4MzRcdTU0MDhcdTMwNkJcdTMwNEJcdTMwNEVcdTMwOEFcdTUzNThcdTdEMTRcdTU3OEJcdTMwNjdcdTMwNDJcdTMwOEJcdTMwQjNcdTMwRjNcdTMwQzZcdTMwRjNcdTMwQzRcdTMwRkJcdTMwQkZcdTMwQTRcdTMwRDdcdTMwOTJcdTYzMDFcdTMwNjRjb21wbGV4VHlwZVx1MzA2N1x1MzA0Mlx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMicnezF9JydcdTMwNkZcdTMwMDFcdTMwNTNcdTMwOENcdTMwODlcdTMwNkVcdTMwNjlcdTMwNkVcdTY3NjFcdTRFRjZcdTMwODJcdTZFODBcdTMwNUZcdTMwNTdcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLSAgICAgICAgc3JjLWN0LjIuMiA9IHNyYy1jdC4yLjI6IFx1MzBCRlx1MzBBNFx1MzBENycnezB9JydcdTMwNkJcdTVCRkVcdTMwNTlcdTMwOEJcdTg5MDdcdTU0MDhcdTU3OEJcdTVCOUFcdTdGQTlcdTg4NjhcdTczRkVcdTMwQThcdTMwRTlcdTMwRkNcdTMwMDJzaW1wbGVDb250ZW50XHUzMDkyXHU2MzAxXHUzMDY0Y29tcGxleFR5cGVcdTMwNENcdTMwMDFcdTZERjdcdTU0MDhcdTMwQjNcdTMwRjNcdTMwQzZcdTMwRjNcdTMwQzRcdTMwNjhcdTdBN0FcdTMwNkJcdTMwNjdcdTMwNERcdTMwOEJcdTMwRDFcdTMwRkNcdTMwQzZcdTMwQTNcdTMwQUZcdTMwRUJcdTMwOTJcdTYzMDFcdTMwNjRjb21wbGV4VHlwZVx1MzA5Mlx1NTIzNlx1OTY1MFx1MzA1OVx1MzA4Qlx1NTgzNFx1NTQwOFx1MzAwMTxyZXN0cmljdGlvbj5cdTMwNkVcdTVCNTBcdTMwNkVcdTRFMkRcdTMwNkI8c2ltcGxlVHlwZT5cdTMwNENcdTVCNThcdTU3MjhcdTMwNTlcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIKLSAgICAgICAgc3JjLWN0LjQgPSBzcmMtY3QuNDogXHUzMEJGXHUzMEE0XHUzMEQ3Jyd7MH0nJ1x1MzA2Qlx1NUJGRVx1MzA1OVx1MzA4Qlx1ODkwN1x1NTQwOFx1NTc4Qlx1NUI5QVx1N0ZBOVx1ODg2OFx1NzNGRVx1MzBBOFx1MzBFOVx1MzBGQ1x1MzAwMlx1MzBFRlx1MzBBNFx1MzBFQlx1MzBDOVx1MzBBQlx1MzBGQ1x1MzBDOVx1MzA2RVx1NTE3MVx1OTAxQVx1OTBFOFx1NTIwNlx1MzA2Rlx1ODg2OFx1NzNGRVx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotICAgICAgICBzcmMtY3QuNSA9IHNyYy1jdC41OiBcdTMwQkZcdTMwQTRcdTMwRDcnJ3swfScnXHUzMDZCXHU1QkZFXHUzMDU5XHUzMDhCXHU4OTA3XHU1NDA4XHU1NzhCXHU1QjlBXHU3RkE5XHU4ODY4XHU3M0ZFXHUzMEE4XHUzMEU5XHUzMEZDXHUzMDAyXHUzMEVGXHUzMEE0XHUzMEVCXHUzMEM5XHUzMEFCXHUzMEZDXHUzMEM5XHUzMDZFXHU1MTcxXHU3NTI4XHU0RjUzXHUzMDZGXHU4ODY4XHU3M0ZFXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0gICAgICAgIHNyYy1lbGVtZW50LjEgPSBzcmMtZWxlbWVudC4xOiAnJ2RlZmF1bHQnJ1x1MzA2OCcnZml4ZWQnJ1x1MzA2RVx1NEUyMVx1NjVCOVx1MzA2RVx1MzBEN1x1MzBFRFx1MzBEMVx1MzBDNlx1MzBBM1x1MzA5Mlx1ODk4MVx1N0QyMFx1NUJBM1x1OEEwMCcnezB9JydcdTMwNkJcdTU0MkJcdTMwODFcdTMwOEJcdTMwNTNcdTMwNjhcdTMwNkZcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDJcdTMwNDRcdTMwNUFcdTMwOENcdTMwNEJcdTRFMDBcdTY1QjlcdTMwNkVcdTMwN0ZcdTMwOTJcdTRGN0ZcdTc1MjhcdTMwNTdcdTMwNjZcdTMwNEZcdTMwNjBcdTMwNTVcdTMwNDRcdTMwMDIKLSAgICAgICAgc3JjLWVsZW1lbnQuMi4xID0gc3JjLWVsZW1lbnQuMi4xOiA6ICdyZWYnXHUzMDdFXHUzMDVGXHUzMDZGJ25hbWUnXHUzMDZFXHUzMDQ0XHUzMDVBXHUzMDhDXHUzMDRCXHUzMDRDXHUzMEVEXHUzMEZDXHUzMEFCXHUzMEVCXHU4OTgxXHU3RDIwXHU1QkEzXHU4QTAwXHUzMDZCXHU0RjdGXHU3NTI4XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIHNyYy1lbGVtZW50LjIuMiA9IHNyYy1lbGVtZW50LjIuMjogJyd7MH0nJ1x1MzA2QicncmVmJydcdTVDNUVcdTYwMjdcdTMwNENcdTU0MkJcdTMwN0VcdTMwOENcdTMwNjZcdTMwNDRcdTMwOEJcdTMwNUZcdTMwODFcdTMwMDFcdTMwNURcdTMwNkVcdTMwQjNcdTMwRjNcdTMwQzZcdTMwRjNcdTMwQzRcdTMwNkYoYW5ub3RhdGlvbj8pXHUzMDY4XHU0RTAwXHU4MUY0XHUzMDU5XHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyXHUzMDVGXHUzMDYwXHUzMDU3XHUzMDAxJyd7MX0nJ1x1MzA0Q1x1ODk4Qlx1MzA2NFx1MzA0Qlx1MzA4QVx1MzA3RVx1MzA1N1x1MzA1Rlx1MzAwMgotICAgICAgICBzcmMtZWxlbWVudC4zID0gc3JjLWVsZW1lbnQuMzogXHU4OTgxXHU3RDIwJyd7MH0nJ1x1MzA2QicndHlwZScnXHU1QzVFXHU2MDI3XHUzMDY4XHU1QjUwJydhbm9ueW1vdXMgdHlwZScnXHUzMDZFXHU0RTIxXHU2NUI5XHUzMDRDXHU1NDJCXHUzMDdFXHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5XHUzMDAyXHU4OTgxXHU3RDIwXHUzMDZCXHUzMDZGXHUzMDUzXHUzMDhDXHUzMDg5XHUzMDZFXHUzMDQ2XHUzMDYxXHUzMDQ0XHUzMDVBXHUzMDhDXHUzMDRCXHU0RTAwXHU2NUI5XHUzMDZFXHUzMDdGXHUzMDkyXHU0RjdGXHU3NTI4XHUzMDY3XHUzMDREXHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIHNyYy1pbXBvcnQuMS4xID0gc3JjLWltcG9ydC4xLjE6IDxpbXBvcnQ+XHU4OTgxXHU3RDIwXHU2MEM1XHU1ODMxXHUzMEEyXHUzMEE0XHUzMEM2XHUzMEUwXHUzMDZFXHUzMENEXHUzMEZDXHUzMEUwXHUzMEI5XHUzMERBXHUzMEZDXHUzMEI5XHU1QzVFXHU2MDI3Jyd7MH0nJ1x1MzA2Rlx1MzAwMVx1NUM1RVx1NjAyN1x1MzA0Q1x1NUI1OFx1NTcyOFx1MzA1OVx1MzA4Qlx1MzBCOVx1MzBBRFx1MzBGQ1x1MzBERVx1MzA2RXRhcmdldE5hbWVzcGFjZVx1MzA2OFx1NTQwQ1x1MzA1OFx1MzA4Mlx1MzA2RVx1MzA2Qlx1MzA2Rlx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotICAgICAgICBzcmMtaW1wb3J0LjEuMiA9IHNyYy1pbXBvcnQuMS4yOiA8aW1wb3J0Plx1ODk4MVx1N0QyMFx1NjBDNVx1NTgzMVx1MzBBMlx1MzBBNFx1MzBDNlx1MzBFMFx1MzA2Qlx1MzBDRFx1MzBGQ1x1MzBFMFx1MzBCOVx1MzBEQVx1MzBGQ1x1MzBCOVx1NUM1RVx1NjAyN1x1MzA0Q1x1NUI1OFx1NTcyOFx1MzA1N1x1MzA2QVx1MzA0NFx1NTgzNFx1NTQwOFx1MzAwMVx1NTMwNVx1NTQyQlx1MzA1OVx1MzA4Qlx1MzBCOVx1MzBBRFx1MzBGQ1x1MzBERVx1MzA2Qlx1MzA2RnRhcmdldE5hbWVzcGFjZVx1MzA0Q1x1NUZDNVx1ODk4MVx1MzA2N1x1MzA1OVx1MzAwMgotICAgICAgICBzcmMtaW1wb3J0LjIgPSBzcmMtaW1wb3J0LjI6IFx1MzBDOVx1MzBBRFx1MzBFNVx1MzBFMVx1MzBGM1x1MzBDOCcnezB9JydcdTMwNkVcdTMwRUJcdTMwRkNcdTMwQzhcdTg5ODFcdTdEMjBcdTMwNkJcdTMwNkZcdTMwMDFcdTMwQ0RcdTMwRkNcdTMwRTBcdTMwQjlcdTMwREFcdTMwRkNcdTMwQjlcdTU0MEQnJ2h0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hJydcdTMwNEFcdTMwODhcdTMwNzNcdTMwRURcdTMwRkNcdTMwQUJcdTMwRUJcdTU0MEQnJ3NjaGVtYScnXHUzMDRDXHU1RkM1XHU4OTgxXHUzMDY3XHUzMDU5XHUzMDAyCi0gICAgICAgIHNyYy1pbXBvcnQuMy4xID0gc3JjLWltcG9ydC4zLjE6IDxpbXBvcnQ+XHU4OTgxXHU3RDIwXHU2MEM1XHU1ODMxXHUzMEEyXHUzMEE0XHUzMEM2XHUzMEUwXHUzMDZFXHUzMENEXHUzMEZDXHUzMEUwXHUzMEI5XHUzMERBXHUzMEZDXHUzMEI5XHU1QzVFXHU2MDI3Jyd7MH0nJ1x1MzA2Rlx1MzAwMVx1MzBBNFx1MzBGM1x1MzBERFx1MzBGQ1x1MzBDOFx1MzA1N1x1MzA1Rlx1MzBDOVx1MzBBRFx1MzBFNVx1MzBFMVx1MzBGM1x1MzBDOFx1MzA2RXRhcmdldE5hbWVzcGFjZVx1NUM1RVx1NjAyNycnezF9JydcdTMwNjhcdTU0MENcdTMwNThcdTMwNjdcdTMwNDJcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIKLSAgICAgICAgc3JjLWltcG9ydC4zLjIgPSBzcmMtaW1wb3J0LjMuMjogXHUzMENEXHUzMEZDXHUzMEUwXHUzMEI5XHUzMERBXHUzMEZDXHUzMEI5XHU1QzVFXHU2MDI3XHUzMDZFXHUzMDZBXHUzMDQ0PGltcG9ydD5cdTg5ODFcdTdEMjBcdTYwQzVcdTU4MzFcdTMwQTJcdTMwQTRcdTMwQzZcdTMwRTBcdTMwNENcdTg5OEJcdTMwNjRcdTMwNEJcdTMwNjNcdTMwNUZcdTMwNUZcdTMwODFcdTMwMDFcdTMwQTRcdTMwRjNcdTMwRERcdTMwRkNcdTMwQzhcdTMwNTdcdTMwNUZcdTMwQzlcdTMwQURcdTMwRTVcdTMwRTFcdTMwRjNcdTMwQzhcdTMwNkJ0YXJnZXROYW1lc3BhY2VcdTVDNUVcdTYwMjdcdTMwOTJcdTU0MkJcdTMwODFcdTMwOEJcdTMwNTNcdTMwNjhcdTMwNkZcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDJcdTMwNUZcdTMwNjBcdTMwNTdcdTMwMDFcdTMwQTRcdTMwRjNcdTMwRERcdTMwRkNcdTMwQzhcdTMwNTdcdTMwNUZcdTMwQzlcdTMwQURcdTMwRTVcdTMwRTFcdTMwRjNcdTMwQzhcdTMwNkJ0YXJnZXROYW1lc3BhY2UgJyd7MX0nJ1x1MzA0Q1x1ODk4Qlx1MzA2NFx1MzA0Qlx1MzA4QVx1MzA3RVx1MzA1N1x1MzA1Rlx1MzAwMgotICAgICAgICBzcmMtaW5jbHVkZS4xID0gc3JjLWluY2x1ZGUuMTogXHUzMEM5XHUzMEFEXHUzMEU1XHUzMEUxXHUzMEYzXHUzMEM4Jyd7MH0nJ1x1MzA2RVx1MzBFQlx1MzBGQ1x1MzBDOFx1ODk4MVx1N0QyMFx1MzA2Qlx1MzA2Rlx1MzAwMVx1MzBDRFx1MzBGQ1x1MzBFMFx1MzBCOVx1MzBEQVx1MzBGQ1x1MzBCOVx1NTQwRCcnaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEnJ1x1MzA0QVx1MzA4OFx1MzA3M1x1MzBFRFx1MzBGQ1x1MzBBQlx1MzBFQlx1NTQwRCcnc2NoZW1hJydcdTMwNENcdTVGQzVcdTg5ODFcdTMwNjdcdTMwNTlcdTMwMDIKLSAgICAgICAgc3JjLWluY2x1ZGUuMi4xID0gc3JjLWluY2x1ZGUuMi4xOiBcdTczRkVcdTU3MjgnJ3sxfScnXHUzMDY3XHUzMDQyXHUzMDhCXHU1M0MyXHU3MTY3XHUzMEI5XHUzMEFEXHUzMEZDXHUzMERFXHUzMDZFdGFyZ2V0TmFtZXNwYWNlXHUzMDZGXHUzMDAxXHU3M0ZFXHU1NzI4Jyd7MH0nJ1x1MzA2N1x1MzA0Mlx1MzA4Qlx1MzBBNFx1MzBGM1x1MzBBRlx1MzBFQlx1MzBGQ1x1MzBDOVx1MzA1OVx1MzA4Qlx1MzBCOVx1MzBBRFx1MzBGQ1x1MzBERVx1MzA2RVx1MzA4Mlx1MzA2RVx1MzA2OFx1NTQwQ1x1MzA1OFx1MzA2N1x1MzA0Mlx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBzcmMtcmVkZWZpbmUuMiA9IHNyYy1yZWRlZmluZS4yOiBcdTMwQzlcdTMwQURcdTMwRTVcdTMwRTFcdTMwRjNcdTMwQzgnJ3swfScnXHUzMDZFXHUzMEVCXHUzMEZDXHUzMEM4XHU4OTgxXHU3RDIwXHUzMDZCXHUzMDZGXHUzMDAxXHUzMENEXHUzMEZDXHUzMEUwXHUzMEI5XHUzMERBXHUzMEZDXHUzMEI5XHU1NDBEJydodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYScnXHUzMDRBXHUzMDg4XHUzMDczXHUzMEVEXHUzMEZDXHUzMEFCXHUzMEVCXHU1NDBEJydzY2hlbWEnJ1x1MzA0Q1x1NUZDNVx1ODk4MVx1MzA2N1x1MzA1OVx1MzAwMgotICAgICAgICBzcmMtcmVkZWZpbmUuMy4xID0gc3JjLXJlZGVmaW5lLjMuMTogXHU3M0ZFXHU1NzI4Jyd7MX0nJ1x1MzA2N1x1MzA0Mlx1MzA4Qlx1NTNDMlx1NzE2N1x1MzBCOVx1MzBBRFx1MzBGQ1x1MzBERVx1MzA2RXRhcmdldE5hbWVzcGFjZVx1MzA2Rlx1MzAwMVx1NzNGRVx1NTcyOCcnezB9JydcdTMwNjdcdTMwNDJcdTMwOEJcdTUxOERcdTVCOUFcdTdGQTlcdTMwNTlcdTMwOEJcdTMwQjlcdTMwQURcdTMwRkNcdTMwREVcdTMwNkVcdTMwODJcdTMwNkVcdTMwNjhcdTU0MENcdTMwNThcdTMwNjdcdTMwNDJcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIKLSAgICAgICAgc3JjLXJlZGVmaW5lLjUuYS5hID0gc3JjLXJlZGVmaW5lLjUuYS5hOiA8c2ltcGxlVHlwZT5cdTMwNkVcdTZDRThcdTkxQzhcdTRFRTVcdTU5MTZcdTMwNkVcdTVCNTBcdTMwNENcdTg5OEJcdTMwNjRcdTMwNEJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwNjdcdTMwNTdcdTMwNUZcdTMwMDI8cmVkZWZpbmU+XHU4OTgxXHU3RDIwXHUzMDZFPHNpbXBsZVR5cGU+XHUzMDZFXHU1QjUwXHUzMDZCXHUzMDZGXHUzMDAxXHUzMDVEXHUzMDhDXHU4MUVBXHU0RjUzXHUzMDkyXHU1M0MyXHU3MTY3XHUzMDU5XHUzMDhCJ2Jhc2UnXHU1QzVFXHU2MDI3XHUzMDkyXHU2MzAxXHUzMDY0PHJlc3RyaWN0aW9uPlx1MzA2RVx1NUI1MFx1NUI2Qlx1MzA0Q1x1NTQyQlx1MzA3RVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBzcmMtcmVkZWZpbmUuNS5hLmIgPSBzcmMtcmVkZWZpbmUuNS5hLmI6ICcnezB9JydcdTMwNkZcdTY3MDlcdTUyQjlcdTMwNkFcdTVCNTBcdTg5ODFcdTdEMjBcdTMwNjdcdTMwNkZcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDI8cmVkZWZpbmU+XHU4OTgxXHU3RDIwXHUzMDZFPHNpbXBsZVR5cGU+XHUzMDZFXHU1QjUwXHUzMDZCXHUzMDZGXHUzMDAxXHUzMDVEXHUzMDhDXHU4MUVBXHU0RjUzXHUzMDkyXHU1M0MyXHU3MTY3XHUzMDU5XHUzMDhCJydiYXNlJydcdTVDNUVcdTYwMjdcdTMwOTJcdTYzMDFcdTMwNjQ8cmVzdHJpY3Rpb24+XHUzMDZFXHU1QjUwXHU1QjZCXHUzMDRDXHU1NDJCXHUzMDdFXHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIHNyYy1yZWRlZmluZS41LmEuYyA9IHNyYy1yZWRlZmluZS41LmEuYzogJyd7MH0nJ1x1MzA2Qlx1NTE4RFx1NUI5QVx1N0ZBOVx1NkUwOFx1MzA2RVx1ODk4MVx1N0QyMCcnezF9JydcdTMwOTJcdTUzQzJcdTcxNjdcdTMwNTlcdTMwOEInJ2Jhc2UnJ1x1NUM1RVx1NjAyN1x1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMjxyZWRlZmluZT5cdTg5ODFcdTdEMjBcdTMwNkU8c2ltcGxlVHlwZT5cdTMwNkVcdTVCNTBcdTMwNkJcdTMwNkZcdTMwMDFcdTMwNURcdTMwOENcdTgxRUFcdTRGNTNcdTMwOTJcdTUzQzJcdTcxNjdcdTMwNTlcdTMwOEInJ2Jhc2UnJ1x1NUM1RVx1NjAyN1x1MzA5Mlx1NjMwMVx1MzA2NDxyZXN0cmljdGlvbj5cdTMwNkVcdTVCNTBcdTVCNkJcdTMwNENcdTU0MkJcdTMwN0VcdTMwOENcdTMwNjZcdTMwNDRcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIKLSAgICAgICAgc3JjLXJlZGVmaW5lLjUuYi5hID0gc3JjLXJlZGVmaW5lLjUuYi5hOiA8Y29tcGxleFR5cGU+XHUzMDZFXHU2Q0U4XHU5MUM4XHU0RUU1XHU1OTE2XHUzMDZFXHU1QjUwXHUzMDRDXHU4OThCXHUzMDY0XHUzMDRCXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDY3XHUzMDU3XHUzMDVGXHUzMDAyPHJlZGVmaW5lPlx1ODk4MVx1N0QyMFx1MzA2RTxjb21wbGV4VHlwZT5cdTMwNkVcdTVCNTBcdTMwNkJcdTMwNkZcdTMwMDFcdTMwNURcdTMwOENcdTgxRUFcdTRGNTNcdTMwOTJcdTUzQzJcdTcxNjdcdTMwNTlcdTMwOEInYmFzZSdcdTVDNUVcdTYwMjdcdTMwOTJcdTYzMDFcdTMwNjQ8ZXh0ZW5zaW9uPlx1MzA3RVx1MzA1Rlx1MzA2RjxyZXN0cmljdGlvbj5cdTMwNkVcdTVCNTBcdTVCNkJcdTMwNENcdTU0MkJcdTMwN0VcdTMwOENcdTMwNjZcdTMwNDRcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIKLSAgICAgICAgc3JjLXJlZGVmaW5lLjUuYi5iID0gc3JjLXJlZGVmaW5lLjUuYi5iOiA8Y29tcGxleFR5cGU+XHUzMDZFXHU2Q0U4XHU5MUM4XHU0RUU1XHU1OTE2XHUzMDZFXHU1QjZCXHUzMDRDXHU4OThCXHUzMDY0XHUzMDRCXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDY3XHUzMDU3XHUzMDVGXHUzMDAyPHJlZGVmaW5lPlx1ODk4MVx1N0QyMFx1MzA2RTxjb21wbGV4VHlwZT5cdTMwNkVcdTVCNTBcdTMwNkJcdTMwNkZcdTMwMDFcdTMwNURcdTMwOENcdTgxRUFcdTRGNTNcdTMwOTJcdTUzQzJcdTcxNjdcdTMwNTlcdTMwOEInYmFzZSdcdTVDNUVcdTYwMjdcdTMwOTJcdTYzMDFcdTMwNjQ8ZXh0ZW5zaW9uPlx1MzA3RVx1MzA1Rlx1MzA2RjxyZXN0cmljdGlvbj5cdTMwNkVcdTVCNTBcdTVCNkJcdTMwNENcdTU0MkJcdTMwN0VcdTMwOENcdTMwNjZcdTMwNDRcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIKLSAgICAgICAgc3JjLXJlZGVmaW5lLjUuYi5jID0gc3JjLXJlZGVmaW5lLjUuYi5jOiAnJ3swfScnXHUzMDZGXHU2NzA5XHU1MkI5XHUzMDZBXHU1QjZCXHU4OTgxXHU3RDIwXHUzMDY3XHUzMDZGXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyPHJlZGVmaW5lPlx1ODk4MVx1N0QyMFx1MzA2RTxjb21wbGV4VHlwZT5cdTMwNkVcdTVCNTBcdTMwNkJcdTMwNkZcdTMwMDFcdTMwNURcdTMwOENcdTgxRUFcdTRGNTNcdTMwOTJcdTUzQzJcdTcxNjdcdTMwNTlcdTMwOEInJ2Jhc2UnJ1x1NUM1RVx1NjAyN1x1MzA5Mlx1NjMwMVx1MzA2NDxleHRlbnNpb24+XHUzMDdFXHUzMDVGXHUzMDZGPHJlc3RyaWN0aW9uPlx1MzA2RVx1NUI1MFx1NUI2Qlx1MzA0Q1x1NTQyQlx1MzA3RVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBzcmMtcmVkZWZpbmUuNS5iLmQgPSBzcmMtcmVkZWZpbmUuNS5iLmQ6ICcnezB9JydcdTMwNkJcdTUxOERcdTVCOUFcdTdGQTlcdTZFMDhcdTMwNkVcdTg5ODFcdTdEMjAnJ3sxfScnXHUzMDkyXHU1M0MyXHU3MTY3XHUzMDU5XHUzMDhCJydiYXNlJydcdTVDNUVcdTYwMjdcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDI8cmVkZWZpbmU+XHU4OTgxXHU3RDIwXHUzMDZFPGNvbXBsZXhUeXBlPlx1MzA2RVx1NUI1MFx1MzA2Qlx1MzA2Rlx1MzAwMVx1MzA1RFx1MzA4Q1x1ODFFQVx1NEY1M1x1MzA5Mlx1NTNDMlx1NzE2N1x1MzA1OVx1MzA4QicnYmFzZScnXHU1QzVFXHU2MDI3XHUzMDkyXHU2MzAxXHUzMDY0PGV4dGVuc2lvbj5cdTMwN0VcdTMwNUZcdTMwNkY8cmVzdHJpY3Rpb24+XHUzMDZFXHU1QjUwXHU1QjZCXHUzMDRDXHU1NDJCXHUzMDdFXHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIHNyYy1yZWRlZmluZS42LjEuMSA9IHNyYy1yZWRlZmluZS42LjEuMTogPHJlZGVmaW5lPlx1ODk4MVx1N0QyMFx1MzA2RVx1NUI1MFx1MzBCMFx1MzBFQlx1MzBGQ1x1MzBEN1x1MzA2Qlx1MzA1RFx1MzA4Q1x1ODFFQVx1NEY1M1x1MzA5Mlx1NTNDMlx1NzE2N1x1MzA1OVx1MzA4Qlx1MzBCMFx1MzBFQlx1MzBGQ1x1MzBEN1x1MzA0Q1x1NTQyQlx1MzA3RVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA4Qlx1NTgzNFx1NTQwOFx1MzAwMVx1MzA1RFx1MzA4Q1x1MzA2RjFcdTMwNjRcdTMwNjdcdTMwNDJcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDJcdTMwNTNcdTMwOENcdTMwNkJcdTMwNkYnJ3swfScnXHUzMDRDXHU1NDJCXHUzMDdFXHUzMDhDXHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIHNyYy1yZWRlZmluZS42LjEuMiA9IHNyYy1yZWRlZmluZS42LjEuMjogXHU1MThEXHU1QjlBXHU3RkE5XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDhCXHUzMEIwXHUzMEVCXHUzMEZDXHUzMEQ3XHUzMDc4XHUzMDZFXHU1M0MyXHU3MTY3XHUzMDRDXHU1NDJCXHUzMDdFXHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDhCXHUzMEIwXHUzMEVCXHUzMEZDXHUzMEQ3Jyd7MH0nJ1x1MzA2Qlx1MzA2RicnbWluT2NjdXJzJycgPSAnJ21heE9jY3VycycnID0gMVx1MzA5Mlx1NjMwN1x1NUI5QVx1MzA1OVx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBzcmMtcmVkZWZpbmUuNi4yLjEgPSBzcmMtcmVkZWZpbmUuNi4yLjE6IFx1NTE4RFx1NUI5QVx1N0ZBOVx1MzA1NVx1MzA4Q1x1MzA1Rlx1MzBCOVx1MzBBRFx1MzBGQ1x1MzBERVx1MzA2Qlx1MzA2Rlx1MzAwMScnezB9JydcdTMwNjhcdTRFMDBcdTgxRjRcdTMwNTlcdTMwOEJcdTU0MERcdTUyNERcdTMwOTJcdTYzMDFcdTMwNjRcdTMwQjBcdTMwRUJcdTMwRkNcdTMwRDdcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLSAgICAgICAgc3JjLXJlZGVmaW5lLjYuMi4yID0gc3JjLXJlZGVmaW5lLjYuMi4yOiBcdTMwQjBcdTMwRUJcdTMwRkNcdTMwRDcnJ3swfScnXHUzMDY3XHUzMDZGXHU1MThEXHU1QjlBXHU3RkE5XHUzMDU3XHUzMDVGXHUzMEIwXHUzMEVCXHUzMEZDXHUzMEQ3XHUzMDRDXHU5MDY5XHU1MjA3XHUzMDZCXHU1MjM2XHU5NjUwXHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyXHU1MjM2XHU3RDA0XHU5MDU1XHU1M0NEOiAnJ3sxfScnXHUzMDAyCi0gICAgICAgIHNyYy1yZWRlZmluZS43LjEgPSBzcmMtcmVkZWZpbmUuNy4xOiA8cmVkZWZpbmU+XHU4OTgxXHU3RDIwXHUzMDZFYXR0cmlidXRlR3JvdXBcdTMwNkVcdTVCNTBcdTMwNkJcdTMwNURcdTMwOENcdTgxRUFcdTRGNTNcdTMwOTJcdTUzQzJcdTcxNjdcdTMwNTlcdTMwOEJhdHRyaWJ1dGVHcm91cFx1MzA0Q1x1NTQyQlx1MzA3RVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA4Qlx1NTgzNFx1NTQwOFx1MzA2RjFcdTMwNjRcdTMwNjdcdTMwNDJcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwNENcdTMwMDFcdTMwNTNcdTMwOENcdTMwNkJcdTMwNkZ7MH1cdTU0MkJcdTMwN0VcdTMwOENcdTMwN0VcdTMwNTlcdTMwMDIKLSAgICAgICAgc3JjLXJlZGVmaW5lLjcuMi4xID0gc3JjLXJlZGVmaW5lLjcuMi4xOiBcdTUxOERcdTVCOUFcdTdGQTlcdTMwNTVcdTMwOENcdTMwNUZcdTMwQjlcdTMwQURcdTMwRkNcdTMwREVcdTMwNkJcdTMwNkZcdTMwMDEnJ3swfScnXHUzMDY4XHU0RTAwXHU4MUY0XHUzMDU5XHUzMDhCXHU1NDBEXHU1MjREXHUzMDkyXHU2MzAxXHUzMDY0YXR0cmlidXRlR3JvdXBcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLSAgICAgICAgc3JjLXJlZGVmaW5lLjcuMi4yID0gc3JjLXJlZGVmaW5lLjcuMi4yOiBBdHRyaWJ1dGVHcm91cCAnJ3swfScnXHUzMDY3XHUzMDZGXHU1MThEXHU1QjlBXHU3RkE5XHUzMDU3XHUzMDVGYXR0cmlidXRlR3JvdXBcdTMwNENcdTkwNjlcdTUyMDdcdTMwNkJcdTUyMzZcdTk2NTBcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDJcdTUyMzZcdTdEMDRcdTkwNTVcdTUzQ0Q6ICcnezF9JydcdTMwMDIKLSAgICAgICAgc3JjLXJlc29sdmUgPSBzcmMtcmVzb2x2ZTogXHU1NDBEXHU1MjREJyd7MH0nJ1x1MzA5MicnezF9JydcdTMwQjNcdTMwRjNcdTMwRERcdTMwRkNcdTMwQ0RcdTMwRjNcdTMwQzhcdTMwNkJcdTg5RTNcdTZDN0FcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLSAgICAgICAgc3JjLXJlc29sdmUuNC4xID0gc3JjLXJlc29sdmUuNC4xOiBcdTMwQjNcdTMwRjNcdTMwRERcdTMwRkNcdTMwQ0RcdTMwRjNcdTMwQzgnJ3syfScnXHUzMDZFXHU4OUUzXHU2QzdBXHU0RTJEXHUzMDZCXHUzMEE4XHUzMEU5XHUzMEZDXHUzMDRDXHU3NjdBXHU3NTFGXHUzMDU3XHUzMDdFXHUzMDU3XHUzMDVGXHUzMDAyJyd7Mn0nJ1x1MzA2Qlx1MzA2Rlx1MzBDRFx1MzBGQ1x1MzBFMFx1MzBCOVx1MzBEQVx1MzBGQ1x1MzBCOVx1MzA0Q1x1NUI1OFx1NTcyOFx1MzA1N1x1MzA3RVx1MzA1Qlx1MzA5M1x1MzA0Q1x1MzAwMVx1MzBCRlx1MzBGQ1x1MzBCMlx1MzBDM1x1MzBDOFx1MzBGQlx1MzBDRFx1MzBGQ1x1MzBFMFx1MzBCOVx1MzBEQVx1MzBGQ1x1MzBCOVx1MzA2RVx1MzA2QVx1MzA0NFx1MzBCM1x1MzBGM1x1MzBERFx1MzBGQ1x1MzBDRFx1MzBGM1x1MzBDOFx1MzA2Rlx1MzBCOVx1MzBBRFx1MzBGQ1x1MzBERVx1MzBGQlx1MzBDOVx1MzBBRFx1MzBFNVx1MzBFMVx1MzBGM1x1MzBDOCcnezB9JydcdTMwNEJcdTMwODlcdTUzQzJcdTcxNjdcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDInJ3syfScnXHUzMDZCXHUzMENEXHUzMEZDXHUzMEUwXHUzMEI5XHUzMERBXHUzMEZDXHUzMEI5XHUzMDkyXHU2MzA3XHU1QjlBXHUzMDU5XHUzMDhCXHU1ODM0XHU1NDA4XHUzMDZGXHUzMDAxXHU2M0E1XHU5ODJEXHU4RjlFXHUzMDZFXHU4RkZEXHU1MkEwXHUzMDRDXHU1RkM1XHU4OTgxXHUzMDZCXHUzMDZBXHUzMDhCXHUzMDUzXHUzMDY4XHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyJyd7Mn0nJ1x1MzA2Qlx1MzBDRFx1MzBGQ1x1MzBFMFx1MzBCOVx1MzBEQVx1MzBGQ1x1MzBCOVx1MzA5Mlx1NjMwN1x1NUI5QVx1MzA1N1x1MzA2QVx1MzA0NFx1NTgzNFx1NTQwOFx1MzA2Rlx1MzAwMSJuYW1lc3BhY2UiXHU1QzVFXHU2MDI3XHUzMDZFXHUzMDZBXHUzMDQ0JydpbXBvcnQnJ1x1MzA5MicnezB9JydcdTMwNkJcdThGRkRcdTUyQTBcdTMwNTlcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIKLSAgICAgICAgc3JjLXJlc29sdmUuNC4yID0gc3JjLXJlc29sdmUuNC4yOiBcdTMwQjNcdTMwRjNcdTMwRERcdTMwRkNcdTMwQ0RcdTMwRjNcdTMwQzgnJ3syfScnXHUzMDZFXHU4OUUzXHU2QzdBXHU0RTJEXHUzMDZCXHUzMEE4XHUzMEU5XHUzMEZDXHUzMDRDXHU3NjdBXHU3NTFGXHUzMDU3XHUzMDdFXHUzMDU3XHUzMDVGXHUzMDAyJyd7Mn0nJ1x1MzA2Rlx1MzBDRFx1MzBGQ1x1MzBFMFx1MzBCOVx1MzBEQVx1MzBGQ1x1MzBCOScnezF9JydcdTMwNkJcdTU0MkJcdTMwN0VcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTlcdTMwNENcdTMwMDFcdTMwNTNcdTMwNkVcdTMwQ0RcdTMwRkNcdTMwRTBcdTMwQjlcdTMwREFcdTMwRkNcdTMwQjlcdTMwNEJcdTMwODlcdTMwNkVcdTMwQjNcdTMwRjNcdTMwRERcdTMwRkNcdTMwQ0RcdTMwRjNcdTMwQzhcdTMwNkZcdTMwQjlcdTMwQURcdTMwRkNcdTMwREVcdTMwRkJcdTMwQzlcdTMwQURcdTMwRTVcdTMwRTFcdTMwRjNcdTMwQzgnJ3swfScnXHUzMDRCXHUzMDg5XHU1M0MyXHU3MTY3XHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyXHUzMDUzXHUzMDZFXHUzMENEXHUzMEZDXHUzMEUwXHUzMEI5XHUzMERBXHUzMEZDXHUzMEI5XHUzMDRDXHU2QjYzXHUzMDU3XHUzMDRGXHUzMDZBXHUzMDQ0XHU1ODM0XHU1NDA4XHUzMDZGXHUzMDAxJyd7Mn0nJ1x1MzA2RVx1NjNBNVx1OTgyRFx1OEY5RVx1MzA2RVx1NTkwOVx1NjZGNFx1MzA0Q1x1NUZDNVx1ODk4MVx1MzA2Qlx1MzA2QVx1MzA4Qlx1MzA1M1x1MzA2OFx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMlx1MzA1M1x1MzA2RVx1MzBDRFx1MzBGQ1x1MzBFMFx1MzBCOVx1MzBEQVx1MzBGQ1x1MzBCOVx1MzA0Q1x1NkI2M1x1MzA1N1x1MzA0NFx1NTgzNFx1NTQwOFx1MzA2Rlx1MzAwMVx1OTA2OVx1NTIwN1x1MzA2QScnaW1wb3J0JydcdTMwQkZcdTMwQjBcdTMwOTInJ3swfScnXHUzMDZCXHU4RkZEXHU1MkEwXHUzMDU5XHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIHNyYy1zaW1wbGUtdHlwZS4yLmEgPSBzcmMtc2ltcGxlLXR5cGUuMi5hOiBbY2hpbGRyZW5dXHUzMDZCXHUzMEQ5XHUzMEZDXHUzMEI5W2F0dHJpYnV0ZV1cdTMwNjg8c2ltcGxlVHlwZT5cdTg5ODFcdTdEMjBcdTMwNkVcdTRFMjFcdTY1QjlcdTMwOTJcdTU0MkJcdTMwODA8cmVzdHJpY3Rpb24+XHU4OTgxXHU3RDIwXHUzMDRDXHU4OThCXHUzMDY0XHUzMDRCXHUzMDhBXHUzMDdFXHUzMDU3XHUzMDVGXHUzMDAyXHUzMDQ0XHUzMDVBXHUzMDhDXHUzMDRCXHU0RTAwXHU2NUI5XHUzMDZFXHUzMDdGXHUzMDkyXHU0RjdGXHU3NTI4XHUzMDY3XHUzMDREXHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIHNyYy1zaW1wbGUtdHlwZS4yLmIgPSBzcmMtc2ltcGxlLXR5cGUuMi5iOiBbY2hpbGRyZW5dXHUzMDZCXHUzMEQ5XHUzMEZDXHUzMEI5W2F0dHJpYnV0ZV1cdTMwODI8c2ltcGxlVHlwZT5cdTg5ODFcdTdEMjBcdTMwODJcdTMwNkFcdTMwNDQ8cmVzdHJpY3Rpb24+XHU4OTgxXHU3RDIwXHUzMDRDXHU4OThCXHUzMDY0XHUzMDRCXHUzMDhBXHUzMDdFXHUzMDU3XHUzMDVGXHUzMDAyXHUzMDQ0XHUzMDVBXHUzMDhDXHUzMDRCXHU0RTAwXHU2NUI5XHUzMDRDXHU1RkM1XHU4OTgxXHUzMDY3XHUzMDU5XHUzMDAyCi0gICAgICAgIHNyYy1zaW1wbGUtdHlwZS4zLmEgPSBzcmMtc2ltcGxlLXR5cGUuMy5hOiBbY2hpbGRyZW5dXHUzMDZCaXRlbVR5cGUgW2F0dHJpYnV0ZV1cdTMwNjg8c2ltcGxlVHlwZT5cdTg5ODFcdTdEMjBcdTMwNkVcdTRFMjFcdTY1QjlcdTMwOTJcdTU0MkJcdTMwODA8bGlzdD5cdTg5ODFcdTdEMjBcdTMwNENcdTg5OEJcdTMwNjRcdTMwNEJcdTMwOEFcdTMwN0VcdTMwNTdcdTMwNUZcdTMwMDJcdTMwNDRcdTMwNUFcdTMwOENcdTMwNEJcdTRFMDBcdTY1QjlcdTMwNkVcdTMwN0ZcdTMwOTJcdTRGN0ZcdTc1MjhcdTMwNjdcdTMwNERcdTMwN0VcdTMwNTlcdTMwMDIKLSAgICAgICAgc3JjLXNpbXBsZS10eXBlLjMuYiA9IHNyYy1zaW1wbGUtdHlwZS4zLmI6IFtjaGlsZHJlbl1cdTMwNkJpdGVtVHlwZSBbYXR0cmlidXRlXVx1MzA4MjxzaW1wbGVUeXBlPlx1ODk4MVx1N0QyMFx1MzA4Mlx1MzA2QVx1MzA0NDxsaXN0Plx1ODk4MVx1N0QyMFx1MzA0Q1x1ODk4Qlx1MzA2NFx1MzA0Qlx1MzA4QVx1MzA3RVx1MzA1N1x1MzA1Rlx1MzAwMlx1MzA0NFx1MzA1QVx1MzA4Q1x1MzA0Qlx1NEUwMFx1NjVCOVx1MzA0Q1x1NUZDNVx1ODk4MVx1MzA2N1x1MzA1OVx1MzAwMgotICAgICAgICBzcmMtc2luZ2xlLWZhY2V0LXZhbHVlID0gc3JjLXNpbmdsZS1mYWNldC12YWx1ZTogXHUzMEQ1XHUzMEExXHUzMEJCXHUzMEMzXHUzMEM4Jyd7MH0nJ1x1MzA0Q1x1ODkwN1x1NjU3MFx1NTZERVx1NUI5QVx1N0ZBOVx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBzcmMtdW5pb24tbWVtYmVyVHlwZXMtb3Itc2ltcGxlVHlwZXMgPSBzcmMtdW5pb24tbWVtYmVyVHlwZXMtb3Itc2ltcGxlVHlwZXM6IDx1bmlvbj5cdTg5ODFcdTdEMjBcdTMwNkVtZW1iZXJUeXBlcyBbYXR0cmlidXRlXVx1MzA0Q1x1N0E3QVx1MzA2N1x1MzA2QVx1MzA0NFx1MzA0Qlx1MzAwMVtjaGlsZHJlbl1cdTMwNkJcdTVDMTFcdTMwNkFcdTMwNEZcdTMwNjhcdTMwODIxXHUzMDY0XHUzMDZFPHNpbXBsZVR5cGU+XHU4OTgxXHU3RDIwXHUzMDRDXHU1NDJCXHUzMDdFXHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCi0KLSNjb25zdHJhaW50IHZhbGlkICgzLlguNikKLQotICAgICAgICBhZy1wcm9wcy1jb3JyZWN0LjIgPSBhZy1wcm9wcy1jb3JyZWN0LjI6IFx1NUM1RVx1NjAyN1x1MzBCMFx1MzBFQlx1MzBGQ1x1MzBENycnezB9JydcdTMwNkVcdTMwQThcdTMwRTlcdTMwRkNcdTMwMDJcdTU0MENcdTMwNThcdTU0MERcdTUyNERcdTMwNEFcdTMwODhcdTMwNzNcdTMwQkZcdTMwRkNcdTMwQjJcdTMwQzNcdTMwQzhcdTMwRkJcdTMwQ0RcdTMwRkNcdTMwRTBcdTMwQjlcdTMwREFcdTMwRkNcdTMwQjlcdTMwOTJcdTYzMDFcdTMwNjRcdTkxQ0RcdTg5MDdcdTMwNTlcdTMwOEJcdTVDNUVcdTYwMjdcdTRGN0ZcdTc1MjhcdTMwNENcdTYzMDdcdTVCOUFcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTlcdTMwMDJcdTkxQ0RcdTg5MDdcdTMwNTlcdTMwOEJcdTVDNUVcdTYwMjdcdTRGN0ZcdTc1MjhcdTMwNkVcdTU0MERcdTUyNERcdTMwNkYnJ3sxfScnXHUzMDY3XHUzMDU5XHUzMDAyCi0gICAgICAgIGFnLXByb3BzLWNvcnJlY3QuMyA9IGFnLXByb3BzLWNvcnJlY3QuMzogXHU1QzVFXHU2MDI3XHUzMEIwXHUzMEVCXHUzMEZDXHUzMEQ3Jyd7MH0nJ1x1MzA2RVx1MzBBOFx1MzBFOVx1MzBGQ1x1MzAwMjJcdTMwNjRcdTMwNkVcdTVDNUVcdTYwMjdcdTVCQTNcdThBMDAnJ3sxfScnXHUzMDY4Jyd7Mn0nJ1x1MzA2QklEXHUzMDRCXHUzMDg5XHU1QzBFXHU1MUZBXHUzMDU3XHUzMDVGXHUzMEJGXHUzMEE0XHUzMEQ3XHUzMDRDXHU1NDJCXHUzMDdFXHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIGEtcHJvcHMtY29ycmVjdC4yID0gYS1wcm9wcy1jb3JyZWN0LjI6IFx1NUM1RVx1NjAyNycnezB9JydcdTMwNkVcdTUwMjRcdTUyMzZcdTdEMDRcdTMwNkVcdTUwMjQnJ3sxfScnXHUzMDRDXHU3MTIxXHU1MkI5XHUzMDY3XHUzMDU5XHUzMDAyCi0gICAgICAgIGEtcHJvcHMtY29ycmVjdC4zID0gYS1wcm9wcy1jb3JyZWN0LjM6IFx1NUM1RVx1NjAyNycnezB9JydcdTMwNjdcdTMwNkYnJ2ZpeGVkJydcdTMwODInJ2RlZmF1bHQnJ1x1MzA4Mlx1NEY3Rlx1NzUyOFx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMlx1MzA1M1x1MzA4Q1x1MzA2Rlx1MzAwMVx1NUM1RVx1NjAyN1x1MzA2RSd7J3R5cGUgZGVmaW5pdGlvbid9J1x1MzA0Q0lEXHUzMDY3XHUzMDQyXHUzMDhCXHUzMDRCXHUzMDAxSURcdTMwNEJcdTMwODlcdTVDMEVcdTUxRkFcdTMwNTVcdTMwOENcdTMwNUZcdTMwODJcdTMwNkVcdTMwNjdcdTMwNDJcdTMwOEJcdTMwNUZcdTMwODFcdTMwNjdcdTMwNTlcdTMwMDIKLSAgICAgICAgYXUtcHJvcHMtY29ycmVjdC4yID0gYXUtcHJvcHMtY29ycmVjdC4yOiAnJ3swfScnXHUzMDZFXHU1QzVFXHU2MDI3XHU1QkEzXHU4QTAwXHUzMDY3XHUzMDZGXHUzMDAxXHU1NkZBXHU1QjlBXHU1MDI0Jyd7MX0nJ1x1MzA0Q1x1NjMwN1x1NUI5QVx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OVx1MzAwMlx1MzA1RFx1MzA2RVx1MzA1Rlx1MzA4MVx1MzAwMScnezB9JydcdTMwOTJcdTUzQzJcdTcxNjdcdTMwNTlcdTMwOEJcdTVDNUVcdTYwMjdcdTRGN0ZcdTc1MjhcdTMwNkIneyd2YWx1ZSBjb25zdHJhaW50J30nXHUzMDgyXHU1NDJCXHUzMDdFXHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDhCXHU1ODM0XHU1NDA4XHUzMDZGXHUzMDAxXHUzMDVEXHUzMDhDXHUzMDkyXHU1NkZBXHU1QjlBXHUzMDU3XHUzMDAxXHUzMDVEXHUzMDZFXHU1MDI0XHUzMDkyJyd7MX0nJ1x1MzA2Qlx1MzA1OVx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBjb3MtYWxsLWxpbWl0ZWQuMS4yID0gY29zLWFsbC1saW1pdGVkLjEuMjogJ2FsbCdcdTMwNkVcdTMwRTJcdTMwQzdcdTMwRUJcdTMwRkJcdTMwQjBcdTMwRUJcdTMwRkNcdTMwRDdcdTMwNkYneydtaW4gb2NjdXJzJ30nID0gJ3snbWF4IG9jY3Vycyd9JyA9IDFcdTMwNkVcdTMwRDFcdTMwRkNcdTMwQzZcdTMwQTNcdTMwQUZcdTMwRUJcdTMwNkJcdTU0MkJcdTMwN0VcdTMwOENcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwMDFcdTMwRDFcdTMwRkNcdTMwQzZcdTMwQTNcdTMwQUZcdTMwRUJcdTMwNkZcdTg5MDdcdTU0MDhcdTU3OEJcdTVCOUFcdTdGQTlcdTMwNkUneydjb250ZW50IHR5cGUnfSdcdTMwOTJcdTY5Q0JcdTYyMTBcdTMwNTlcdTMwOEIxXHU3RDQ0XHUzMDZFXHU0RTAwXHU5MEU4XHUzMDY3XHUzMDQyXHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIGNvcy1hbGwtbGltaXRlZC4yID0gY29zLWFsbC1saW1pdGVkLjI6ICcnYWxsJydcdTMwNkVcdTMwRTJcdTMwQzdcdTMwRUJcdTMwRkJcdTMwQjBcdTMwRUJcdTMwRkNcdTMwRDdcdTMwNkVcdTg5ODFcdTdEMjBcdTMwNkUneydtYXggb2NjdXJzJ30nXHUzMDZGMFx1MzA0QjFcdTMwNjdcdTMwNDJcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDJcdTg5ODFcdTdEMjAnJ3sxfScnXHUzMDZFXHU1MDI0Jyd7MH0nJ1x1MzA2Rlx1NzEyMVx1NTJCOVx1MzA2N1x1MzA1OVx1MzAwMgotICAgICAgICBjb3MtYXBwbGljYWJsZS1mYWNldHMgPSBjb3MtYXBwbGljYWJsZS1mYWNldHM6IFx1MzBCRlx1MzBBNFx1MzBEN3sxfVx1MzA2Qlx1MzBENVx1MzBBMVx1MzBCQlx1MzBDM1x1MzBDOCcnezB9JydcdTMwNkZcdTRGN0ZcdTc1MjhcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLSAgICAgICAgY29zLWN0LWV4dGVuZHMuMS4xID0gY29zLWN0LWV4dGVuZHMuMS4xOiBcdTMwQkZcdTMwQTRcdTMwRDcnJ3swfScnXHUzMDZGXHUzMEJGXHUzMEE0XHUzMEQ3Jyd7MX0nJ1x1MzA2RVx1NjJFMVx1NUYzNVx1MzA2Qlx1MzA4OFx1MzA2M1x1MzA2Nlx1NUMwRVx1NTFGQVx1MzA1NVx1MzA4Q1x1MzA1Rlx1MzA4Mlx1MzA2RVx1MzA2N1x1MzA1OVx1MzAwMlx1MzA1Rlx1MzA2MFx1MzA1N1x1MzAwMScnezF9JydcdTMwNkUnJ2ZpbmFsJydcdTVDNUVcdTYwMjdcdTMwNkJcdTMwODhcdTMwNjNcdTMwNjZcdTMwMDFcdTYyRTFcdTVGMzVcdTMwNkJcdTMwODhcdTMwOEJcdTVDMEVcdTUxRkFcdTMwNENcdTc5ODFcdTZCNjJcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTlcdTMwMDIKLSAgICAgICAgY29zLWN0LWV4dGVuZHMuMS40LjMuMi4yLjEuYSA9IGNvcy1jdC1leHRlbmRzLjEuNC4zLjIuMi4xLmE6IFx1NUMwRVx1NTFGQVx1MzA1NVx1MzA4Q1x1MzA1Rlx1MzBCRlx1MzBBNFx1MzBEN1x1MzA2RVx1MzBCM1x1MzBGM1x1MzBDNlx1MzBGM1x1MzBDNFx1MzBGQlx1MzBCRlx1MzBBNFx1MzBEN1x1MzA2OFx1MzA1RFx1MzA2RVx1MzBEOVx1MzBGQ1x1MzBCOVx1MzA2RVx1MzBCM1x1MzBGM1x1MzBDNlx1MzBGM1x1MzBDNFx1MzBGQlx1MzBCRlx1MzBBNFx1MzBEN1x1MzA2Rlx1NEUyMVx1NjVCOVx1MzA2OFx1MzA4Mlx1NkRGN1x1NTQwOFx1NTc4Qlx1MzA2Qlx1MzA1OVx1MzA4Qlx1MzA0Qlx1MzAwMVx1ODk4MVx1N0QyMFx1MzA2RVx1MzA3Rlx1MzA2Qlx1MzA1OVx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMlx1MzBCRlx1MzBBNFx1MzBENycnezB9JydcdTMwNkZcdTg5ODFcdTdEMjBcdTMwNkVcdTMwN0ZcdTMwNjdcdTMwNTlcdTMwNENcdTMwMDFcdTMwNURcdTMwNkVcdTMwRDlcdTMwRkNcdTMwQjlcdTMwRkJcdTMwQkZcdTMwQTRcdTMwRDdcdTMwNkZcdTg5ODFcdTdEMjBcdTMwNkVcdTMwN0ZcdTMwNjdcdTMwNkZcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLSAgICAgICAgY29zLWN0LWV4dGVuZHMuMS40LjMuMi4yLjEuYiA9IGNvcy1jdC1leHRlbmRzLjEuNC4zLjIuMi4xLmI6IFx1NUMwRVx1NTFGQVx1MzA1NVx1MzA4Q1x1MzA1Rlx1MzBCRlx1MzBBNFx1MzBEN1x1MzA2RVx1MzBCM1x1MzBGM1x1MzBDNlx1MzBGM1x1MzBDNFx1MzBGQlx1MzBCRlx1MzBBNFx1MzBEN1x1MzA2OFx1MzA1RFx1MzA2RVx1MzBEOVx1MzBGQ1x1MzBCOVx1MzA2RVx1MzBCM1x1MzBGM1x1MzBDNlx1MzBGM1x1MzBDNFx1MzBGQlx1MzBCRlx1MzBBNFx1MzBEN1x1MzA2Rlx1NEUyMVx1NjVCOVx1MzA2OFx1MzA4Mlx1NkRGN1x1NTQwOFx1NTc4Qlx1MzA2Qlx1MzA1OVx1MzA4Qlx1MzA0Qlx1MzAwMVx1ODk4MVx1N0QyMFx1MzA2RVx1MzA3Rlx1MzA2Qlx1MzA1OVx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMlx1MzBCRlx1MzBBNFx1MzBENycnezB9JydcdTMwNkZcdTZERjdcdTU0MDhcdTU3OEJcdTMwNjdcdTMwNTlcdTMwNENcdTMwMDFcdTMwNURcdTMwNkVcdTMwRDlcdTMwRkNcdTMwQjlcdTMwRkJcdTMwQkZcdTMwQTRcdTMwRDdcdTMwNkZcdTZERjdcdTU0MDhcdTU3OEJcdTMwNjdcdTMwNkZcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLSAgICAgICAgY29zLWVsZW1lbnQtY29uc2lzdGVudCA9IGNvcy1lbGVtZW50LWNvbnNpc3RlbnQ6IFx1MzBCRlx1MzBBNFx1MzBENycnezB9JydcdTMwNkVcdTMwQThcdTMwRTlcdTMwRkNcdTMwMDInJ3sxfScnXHUzMDY4XHUzMDQ0XHUzMDQ2XHU1NDBEXHU1MjREXHUzMDZFXHU3NTcwXHUzMDZBXHUzMDhCXHUzMEJGXHUzMEE0XHUzMEQ3XHUzMDZFXHU4OTA3XHU2NTcwXHUzMDZFXHU4OTgxXHU3RDIwXHUzMDRDXHUzMEUyXHUzMEM3XHUzMEVCXHUzMEZCXHUzMEIwXHUzMEVCXHUzMEZDXHUzMEQ3XHUzMDZCXHU1NDJCXHUzMDdFXHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIGNvcy1saXN0LW9mLWF0b21pYyA9IGNvcy1saXN0LW9mLWF0b21pYzogXHUzMEJGXHUzMEE0XHUzMEQ3Jyd7MX0nJ1x1MzA2Rlx1MzBBMlx1MzBDOFx1MzBERlx1MzBDM1x1MzBBRlx1MzA2N1x1MzA2Rlx1MzA2QVx1MzA0NFx1MzA1Rlx1MzA4MSgnJ3sxfScnXHUzMDZGXHUzMEVBXHUzMEI5XHUzMEM4XHUzMEZCXHUzMEJGXHUzMEE0XHUzMEQ3XHUzMDRCXHUzMDAxXHUzMEVBXHUzMEI5XHUzMEM4XHUzMDkyXHU1NDJCXHUzMDgwXHU1MTcxXHU3NTI4XHU0RjUzXHUzMEJGXHUzMEE0XHUzMEQ3XHUzMDY3XHUzMDQyXHUzMDhCXHUzMDVGXHUzMDgxKVx1MzAwMVx1MzBFQVx1MzBCOVx1MzBDOFx1MzBGQlx1MzBCRlx1MzBBNFx1MzBENycnezB9JydcdTMwNkVcdTVCOUFcdTdGQTlcdTMwNjdcdTMwNkZcdTcxMjFcdTUyQjlcdTMwNkFcdTMwRUFcdTMwQjlcdTMwQzhcdTg5ODFcdTdEMjBcdTMwQkZcdTMwQTRcdTMwRDdcdTMwNjdcdTMwNTlcdTMwMDIKLSAgICAgICAgY29zLW5vbmFtYmlnID0gY29zLW5vbmFtYmlnOiB7MH1cdTMwNjh7MX0gKFx1MzA3RVx1MzA1Rlx1MzA2Rlx1N0Y2RVx1NjNEQlx1MzBCMFx1MzBFQlx1MzBGQ1x1MzBEN1x1MzA2RVx1ODk4MVx1N0QyMClcdTMwNEMiVW5pcXVlIFBhcnRpY2xlIEF0dHJpYnV0aW9uIlx1MzA2Qlx1OTA1NVx1NTNDRFx1MzA1N1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OVx1MzAwMlx1MzA1M1x1MzA2RVx1MzBCOVx1MzBBRFx1MzBGQ1x1MzBERVx1MzA2Qlx1NUJGRVx1MzA1OVx1MzA4Qlx1NjkxQ1x1OEEzQ1x1NjY0Mlx1MzA2Qlx1MzAwMVx1MzA1M1x1MzA4Q1x1MzA4OTJcdTMwNjRcdTMwNkVcdTMwRDFcdTMwRkNcdTMwQzZcdTMwQTNcdTMwQUZcdTMwRUJcdTMwNkJcdTMwNDJcdTMwNDRcdTMwN0VcdTMwNDRcdTMwNTVcdTMwNENcdTc1MUZcdTMwNThcdTMwOEJcdTMwNjhcdTgwMDNcdTMwNDhcdTMwODlcdTMwOENcdTMwN0VcdTMwNTlcdTMwMDIKLSAgICAgICAgY29zLXBhcnRpY2xlLXJlc3RyaWN0LmEgPSBjb3MtcGFydGljbGUtcmVzdHJpY3QuYTogXHU1QzBFXHU1MUZBXHUzMDU1XHUzMDhDXHUzMDVGXHUzMEQxXHUzMEZDXHUzMEM2XHUzMEEzXHUzMEFGXHUzMEVCXHUzMDRDXHU3QTdBXHUzMDY3XHUzMDQyXHUzMDhBXHUzMDAxXHUzMEQ5XHUzMEZDXHUzMEI5XHUzMDZGXHU3QTdBXHUzMDZCXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0gICAgICAgIGNvcy1wYXJ0aWNsZS1yZXN0cmljdC5iID0gY29zLXBhcnRpY2xlLXJlc3RyaWN0LmI6IFx1MzBEOVx1MzBGQ1x1MzBCOVx1MzA2RVx1MzBEMVx1MzBGQ1x1MzBDNlx1MzBBM1x1MzBBRlx1MzBFQlx1MzA2Rlx1N0E3QVx1MzA2N1x1MzA1OVx1MzA0Q1x1MzAwMVx1NUMwRVx1NTFGQVx1MzA1NVx1MzA4Q1x1MzA1Rlx1MzBEMVx1MzBGQ1x1MzBDNlx1MzBBM1x1MzBBRlx1MzBFQlx1MzA2Rlx1N0E3QVx1MzA2N1x1MzA2Rlx1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotICAgICAgICBjb3MtcGFydGljbGUtcmVzdHJpY3QuMiA9IGNvcy1wYXJ0aWNsZS1yZXN0cmljdC4yOiBcdTc5ODFcdTZCNjJcdTMwNTVcdTMwOENcdTMwNUZcdTMwRDFcdTMwRkNcdTMwQzZcdTMwQTNcdTMwQUZcdTMwRUJcdTMwNkVcdTUyMzZcdTk2NTA6ICcnezB9JydcdTMwMDIKLSAgICAgICAgY29zLXN0LXJlc3RyaWN0cy4xLjEgPSBjb3Mtc3QtcmVzdHJpY3RzLjEuMTogXHUzMEJGXHUzMEE0XHUzMEQ3Jyd7MX0nJ1x1MzA2Rlx1MzBBMlx1MzBDOFx1MzBERlx1MzBDM1x1MzBBRlx1MzA2N1x1MzA0Mlx1MzA4Qlx1MzA1Rlx1MzA4MVx1MzAwMVx1MzA1RFx1MzA2RSd7J2Jhc2UgdHlwZSBkZWZpbml0aW9uJ30nICcnezB9JydcdTMwNkZcdTMwQTJcdTMwQzhcdTMwREZcdTMwQzNcdTMwQUZcdTMwNkVcdTUzNThcdTdEMTRcdTU3OEJcdTVCOUFcdTdGQTlcdTMwNEJcdTMwRDdcdTMwRUFcdTMwREZcdTMwQzZcdTMwQTNcdTMwRDZcdTMwNkVcdTdENDRcdThGQkNcdTMwN0ZcdTMwQzdcdTMwRkNcdTMwQkZcdTU3OEJcdTMwNjdcdTMwNDJcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIKLSAgICAgICAgY29zLXN0LXJlc3RyaWN0cy4yLjEgPSBjb3Mtc3QtcmVzdHJpY3RzLjIuMTogXHUzMEJGXHUzMEE0XHUzMEQ3Jyd7MX0nJ1x1MzA2Rlx1MzBFQVx1MzBCOVx1MzBDOFx1MzBGQlx1MzBCRlx1MzBBNFx1MzBEN1x1MzA0Qlx1MzAwMVx1MzBFQVx1MzBCOVx1MzBDOFx1MzA5Mlx1NTQyQlx1MzA4MFx1NTE3MVx1NzUyOFx1NEY1M1x1MzBCRlx1MzBBNFx1MzBEN1x1MzA2N1x1MzA0Mlx1MzA4Qlx1MzA1Rlx1MzA4MVx1MzAwMVx1MzBFQVx1MzBCOVx1MzBDOFx1MzBGQlx1MzBCRlx1MzBBNFx1MzBENycnezB9JydcdTMwNkVcdTVCOUFcdTdGQTlcdTMwNjdcdTMwNkZcdTcxMjFcdTUyQjlcdTMwNkFcdTMwQTJcdTMwQTRcdTMwQzZcdTMwRTBcdTMwRkJcdTMwQkZcdTMwQTRcdTMwRDdcdTMwNjdcdTMwNTlcdTMwMDIKLSAgICAgICAgY29zLXN0LXJlc3RyaWN0cy4yLjMuMS4xID0gY29zLXN0LXJlc3RyaWN0cy4yLjMuMS4xOiAneydpdGVtIHR5cGUgZGVmaW5pdGlvbid9JyAnJ3swfScnXHUzMDZFJ3snZmluYWwnfSdcdTMwQjNcdTMwRjNcdTMwRERcdTMwRkNcdTMwQ0RcdTMwRjNcdTMwQzhcdTMwNkJcdTMwNkZcdTMwMDEnJ2xpc3QnJ1x1MzA0Q1x1NTQyQlx1MzA3RVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OVx1MzAwMlx1MzA2NFx1MzA3RVx1MzA4QVx1MzAwMScnezB9JydcdTMwNkZcdTMwRUFcdTMwQjlcdTMwQzhcdTMwRkJcdTMwQkZcdTMwQTRcdTMwRDcnJ3sxfScnXHUzMDZFXHUzMEEyXHUzMEE0XHUzMEM2XHUzMEUwXHUzMEZCXHUzMEJGXHUzMEE0XHUzMEQ3XHUzMDY4XHUzMDU3XHUzMDY2XHUzMDZGXHU0RjdGXHU3NTI4XHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0gICAgICAgIGNvcy1zdC1yZXN0cmljdHMuMy4zLjEuMSA9IGNvcy1zdC1yZXN0cmljdHMuMy4zLjEuMTogJ3snbWVtYmVyIHR5cGUgZGVmaW5pdGlvbnMnfScgJyd7MH0nJ1x1MzA2RSd7J2ZpbmFsJ30nXHUzMEIzXHUzMEYzXHUzMEREXHUzMEZDXHUzMENEXHUzMEYzXHUzMEM4XHUzMDZCXHUzMDZGXHUzMDAxJyd1bmlvbicnXHUzMDRDXHU1NDJCXHUzMDdFXHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5XHUzMDAyXHUzMDY0XHUzMDdFXHUzMDhBXHUzMDAxJyd7MH0nJ1x1MzA2Rlx1NTE3MVx1NzUyOFx1NEY1M1x1MzBCRlx1MzBBNFx1MzBENycnezF9JydcdTMwNkVcdTMwRTFcdTMwRjNcdTMwRDBcdTMwRkNcdTMwRkJcdTMwQkZcdTMwQTRcdTMwRDdcdTMwNjhcdTMwNTdcdTMwNjZcdTMwNkZcdTRGN0ZcdTc1MjhcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLSAgICAgICAgY29zLXZhbGlkLWRlZmF1bHQuMi4xID0gY29zLXZhbGlkLWRlZmF1bHQuMi4xOiBcdTg5ODFcdTdEMjAnJ3swfScnXHUzMDZCXHUzMDZGXHU1MDI0XHU1MjM2XHU3RDA0XHUzMDRDXHU1NDJCXHUzMDdFXHUzMDhDXHUzMDY2XHUzMDRBXHUzMDhBXHUzMDAxXHU2REY3XHU1NDA4XHUzMDdFXHUzMDVGXHUzMDZGXHU1MzU4XHU3RDE0XHUzMEIzXHUzMEYzXHUzMEM2XHUzMEYzXHUzMEM0XHUzMEZCXHUzMEUyXHUzMEM3XHUzMEVCXHUzMDRDXHU1NDJCXHUzMDdFXHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIGNvcy12YWxpZC1kZWZhdWx0LjIuMi4yID0gY29zLXZhbGlkLWRlZmF1bHQuMi4yLjI6IFx1ODk4MVx1N0QyMCcnezB9JydcdTMwNkJcdTMwNkYneyd2YWx1ZSBjb25zdHJhaW50J30nXHUzMDRDXHU1NDJCXHUzMDdFXHUzMDhDXHUzMDY2XHUzMDRBXHUzMDhBXHUzMDAxXHUzMDVEXHUzMDZFXHUzMEJGXHUzMEE0XHUzMEQ3XHU1QjlBXHU3RkE5XHUzMDZCXHUzMDZGXHU2REY3XHU1NDA4J3snY29udGVudCB0eXBlJ30nXHUzMDRDXHU1NDJCXHUzMDdFXHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDhCXHUzMDVGXHUzMDgxXHUzMDAxJ3snY29udGVudCB0eXBlJ30nXHUzMDZFXHUzMEQxXHUzMEZDXHUzMEM2XHUzMEEzXHUzMEFGXHUzMEVCXHUzMDZGXHU3QTdBXHUzMDZCXHUzMDY3XHUzMDREXHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIGMtcHJvcHMtY29ycmVjdC4yID0gYy1wcm9wcy1jb3JyZWN0LjI6IGtleXJlZiAnJ3swfScnXHUzMDY4a2V5ICcnezF9JydcdTMwNkJcdTVCRkVcdTMwNTlcdTMwOEJcdTMwRDVcdTMwQTNcdTMwRkNcdTMwRUJcdTMwQzlcdTMwNkVcdTMwQUJcdTMwRkNcdTMwQzdcdTMwQTNcdTMwQ0FcdTMwRUFcdTMwQzZcdTMwQTNcdTMwNENcdTc2RjhcdTRFOTJcdTMwNkJcdTRFMDBcdTgxRjRcdTMwNTlcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIKLSAgICAgICAgY3QtcHJvcHMtY29ycmVjdC4zID0gY3QtcHJvcHMtY29ycmVjdC4zOiBcdTg5MDdcdTU0MDhcdTU3OEInJ3swfScnXHUzMDY3XHU1RkFBXHU3NEIwXHU1QjlBXHU3RkE5XHUzMDRDXHU2OTFDXHU1MUZBXHUzMDU1XHUzMDhDXHUzMDdFXHUzMDU3XHUzMDVGXHUzMDAyXHUzMDY0XHUzMDdFXHUzMDhBXHUzMDAxJyd7MH0nJ1x1MzA0Q1x1MzA1RFx1MzA4Q1x1ODFFQVx1NEY1M1x1MzA2RVx1MzBCRlx1MzBBNFx1MzBEN1x1OTY4RVx1NUM2NFx1MzA2Qlx1NTQyQlx1MzA3RVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA4Qlx1MzA1Rlx1MzA4MVx1MzBBOFx1MzBFOVx1MzBGQ1x1MzA2Qlx1MzA2QVx1MzA2M1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBjdC1wcm9wcy1jb3JyZWN0LjQgPSBjdC1wcm9wcy1jb3JyZWN0LjQ6IFx1MzBCRlx1MzBBNFx1MzBENycnezB9JydcdTMwNkVcdTMwQThcdTMwRTlcdTMwRkNcdTMwMDJcdTU0MENcdTMwNThcdTU0MERcdTUyNERcdTMwNEFcdTMwODhcdTMwNzNcdTMwQkZcdTMwRkNcdTMwQjJcdTMwQzNcdTMwQzhcdTMwRkJcdTMwQ0RcdTMwRkNcdTMwRTBcdTMwQjlcdTMwREFcdTMwRkNcdTMwQjlcdTMwOTJcdTYzMDFcdTMwNjRcdTkxQ0RcdTg5MDdcdTMwNTlcdTMwOEJcdTVDNUVcdTYwMjdcdTRGN0ZcdTc1MjhcdTMwNENcdTYzMDdcdTVCOUFcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTlcdTMwMDJcdTkxQ0RcdTg5MDdcdTMwNTlcdTMwOEJcdTVDNUVcdTYwMjdcdTRGN0ZcdTc1MjhcdTMwNkVcdTU0MERcdTUyNERcdTMwNkYnJ3sxfScnXHUzMDY3XHUzMDU5XHUzMDAyCi0gICAgICAgIGN0LXByb3BzLWNvcnJlY3QuNSA9IGN0LXByb3BzLWNvcnJlY3QuNTogXHUzMEJGXHUzMEE0XHUzMEQ3Jyd7MH0nJ1x1MzA2RVx1MzBBOFx1MzBFOVx1MzBGQ1x1MzAwMjJcdTMwNjRcdTMwNkVcdTVDNUVcdTYwMjdcdTVCQTNcdThBMDAnJ3sxfScnXHUzMDY4Jyd7Mn0nJ1x1MzA2QklEXHUzMDRCXHUzMDg5XHU1QzBFXHU1MUZBXHUzMDU3XHUzMDVGXHUzMEJGXHUzMEE0XHUzMEQ3XHUzMDRDXHU1NDJCXHUzMDdFXHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMSA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMTogXHUzMEJGXHUzMEE0XHUzMEQ3Jyd7MH0nJ1x1MzA2Rlx1MzBCRlx1MzBBNFx1MzBENycnezF9JydcdTMwNkVcdTUyMzZcdTk2NTBcdTMwNkJcdTMwODhcdTMwNjNcdTMwNjZcdTVDMEVcdTUxRkFcdTMwNTVcdTMwOENcdTMwNUZcdTMwODJcdTMwNkVcdTMwNjdcdTMwNTlcdTMwMDJcdTMwNUZcdTMwNjBcdTMwNTdcdTMwMDEnJ3sxfScnXHUzMDZFJ3snZmluYWwnfSdcdTMwRDdcdTMwRURcdTMwRDFcdTMwQzZcdTMwQTNcdTMwNkJcdTMwODhcdTMwNjNcdTMwNjZcdTMwMDFcdTUyMzZcdTk2NTBcdTMwNkJcdTMwODhcdTMwOEJcdTVDMEVcdTUxRkFcdTMwNENcdTc5ODFcdTZCNjJcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTlcdTMwMDIKLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4yLjEuMSA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMi4xLjE6IFx1MzBCRlx1MzBBNFx1MzBENycnezB9JydcdTMwNkVcdTMwQThcdTMwRTlcdTMwRkNcdTMwMDJcdTMwNTNcdTMwNkVcdTMwQkZcdTMwQTRcdTMwRDdcdTMwNkVcdTVDNUVcdTYwMjdcdTRGN0ZcdTc1MjgnJ3sxfScnXHUzMDZCXHUzMDZGXHUzMDAxXHUzMEQ5XHUzMEZDXHUzMEI5XHUzMEZCXHUzMEJGXHUzMEE0XHUzMEQ3XHUzMDZFXHU1QkZFXHU1RkRDXHUzMDU5XHUzMDhCXHU1QzVFXHU2MDI3XHU0RjdGXHU3NTI4XHUzMDZFXHU1MDI0JydyZXF1aXJlZCcnXHUzMDY4XHU0RTAwXHU4Q0FCXHU2MDI3XHUzMDRDXHUzMDZBXHUzMDQ0Jyd7Mn0nJ1x1MzA2RScndXNlJydcdTUwMjRcdTMwNENcdTU0MkJcdTMwN0VcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTlcdTMwMDIKLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4yLjEuMiA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMi4xLjI6IFx1MzBCRlx1MzBBNFx1MzBENycnezB9JydcdTMwNkVcdTMwQThcdTMwRTlcdTMwRkNcdTMwMDJcdTMwNTNcdTMwNkVcdTMwQkZcdTMwQTRcdTMwRDdcdTMwNkVcdTVDNUVcdTYwMjdcdTRGN0ZcdTc1MjgnJ3sxfScnXHUzMDZCXHUzMDZGXHUzMDAxXHUzMEQ5XHUzMEZDXHUzMEI5XHUzMEZCXHUzMEJGXHUzMEE0XHUzMEQ3XHUzMDZFXHU1QkZFXHU1RkRDXHUzMDU5XHUzMDhCXHU1QzVFXHU2MDI3XHU0RjdGXHU3NTI4XHUzMDZFXHUzMEJGXHUzMEE0XHUzMEQ3Jyd7M30nJ1x1MzA0Qlx1MzA4OVx1NkI2M1x1NUUzOFx1MzA2Qlx1NUMwRVx1NTFGQVx1MzA1NVx1MzA4Q1x1MzA1Rlx1MzA4Mlx1MzA2RVx1MzA2N1x1MzA2Rlx1MzA2QVx1MzA0NFx1MzBCRlx1MzBBNFx1MzBENycnezJ9JydcdTMwNENcdTU0MkJcdTMwN0VcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTlcdTMwMDIKLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4yLjEuMy5hID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4yLjEuMy5hOiBcdTMwQkZcdTMwQTRcdTMwRDcnJ3swfScnXHUzMDZFXHUzMEE4XHUzMEU5XHUzMEZDXHUzMDAyXHUzMDUzXHUzMDZFXHUzMEJGXHUzMEE0XHUzMEQ3XHUzMDZFXHU1QzVFXHU2MDI3XHU0RjdGXHU3NTI4Jyd7MX0nJ1x1MzA2Qlx1MzA2Rlx1MzAwMVx1NTZGQVx1NUI5QVx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA2QVx1MzA0NFx1NjcwOVx1NTJCOVx1MzA2QVx1NTAyNFx1NTIzNlx1N0QwNFx1MzA0Q1x1NTQyQlx1MzA3RVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OVx1MzA0Q1x1MzAwMVx1MzBEOVx1MzBGQ1x1MzBCOVx1MzBGQlx1MzBCRlx1MzBBNFx1MzBEN1x1MzA2RVx1NUJGRVx1NUZEQ1x1MzA1OVx1MzA4Qlx1NUM1RVx1NjAyN1x1NEY3Rlx1NzUyOFx1MzA2RVx1NjcwOVx1NTJCOVx1MzA2QVx1NTAyNFx1NTIzNlx1N0QwNFx1MzA2Rlx1NTZGQVx1NUI5QVx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjIuMS4zLmIgPSBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjIuMS4zLmI6IFx1MzBCRlx1MzBBNFx1MzBENycnezB9JydcdTMwNkVcdTMwQThcdTMwRTlcdTMwRkNcdTMwMDJcdTMwNTNcdTMwNkVcdTMwQkZcdTMwQTRcdTMwRDdcdTMwNkVcdTVDNUVcdTYwMjdcdTRGN0ZcdTc1MjgnJ3sxfScnXHUzMDZCXHUzMDZGXHUzMDAxXHU1MDI0Jyd7Mn0nJ1x1MzA2N1x1NTZGQVx1NUI5QVx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA4Qlx1NjcwOVx1NTJCOVx1MzA2QVx1NTAyNFx1NTIzNlx1N0QwNFx1MzA0Q1x1NTQyQlx1MzA3RVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OVx1MzA0Q1x1MzAwMVx1MzBEOVx1MzBGQ1x1MzBCOVx1MzBGQlx1MzBCRlx1MzBBNFx1MzBEN1x1MzA2RVx1NUJGRVx1NUZEQ1x1MzA1OVx1MzA4Qlx1NUM1RVx1NjAyN1x1NEY3Rlx1NzUyOFx1MzA2RVx1NTZGQVx1NUI5QVx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA4Qlx1NjcwOVx1NTJCOVx1MzA2QVx1NTAyNFx1NTIzNlx1N0QwNFx1MzA2RVx1NTAyNCcnezN9JydcdTMwNjhcdTRFMDBcdThDQUJcdTYwMjdcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4yLjIuYSA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMi4yLmE6IFx1MzBCRlx1MzBBNFx1MzBENycnezB9JydcdTMwNkVcdTMwQThcdTMwRTlcdTMwRkNcdTMwMDJcdTMwNTNcdTMwNkVcdTMwQkZcdTMwQTRcdTMwRDdcdTMwNkVcdTVDNUVcdTYwMjdcdTRGN0ZcdTc1MjgnJ3sxfScnXHUzMDZGXHUzMEQ5XHUzMEZDXHUzMEI5XHUzMDZFXHU1QzVFXHU2MDI3XHU0RjdGXHU3NTI4XHUzMDY4XHU1QkZFXHU1RkRDXHUzMDU3XHUzMDY2XHUzMDRBXHUzMDg5XHUzMDVBXHUzMDAxXHUzMEQ5XHUzMEZDXHUzMEI5XHUzMEZCXHUzMEJGXHUzMEE0XHUzMEQ3XHUzMDZCXHUzMDZGXHUzMEVGXHUzMEE0XHUzMEVCXHUzMEM5XHUzMEFCXHUzMEZDXHUzMEM5XHU1QzVFXHU2MDI3XHUzMDZGXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMi4yLmIgPSBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjIuMi5iOiBcdTMwQkZcdTMwQTRcdTMwRDcnJ3swfScnXHUzMDZFXHUzMEE4XHUzMEU5XHUzMEZDXHUzMDAyXHUzMDUzXHUzMDZFXHUzMEJGXHUzMEE0XHUzMEQ3XHUzMDZFXHU1QzVFXHU2MDI3XHU0RjdGXHU3NTI4Jyd7MX0nJ1x1MzA2Rlx1MzBEOVx1MzBGQ1x1MzBCOVx1MzA2RVx1NUM1RVx1NjAyN1x1NEY3Rlx1NzUyOFx1MzA2OFx1NUJGRVx1NUZEQ1x1MzA1N1x1MzA2Nlx1MzA0QVx1MzA4OVx1MzA1QVx1MzAwMVx1MzBEOVx1MzBGQ1x1MzBCOVx1MzBGQlx1MzBCRlx1MzBBNFx1MzBEN1x1MzA2RVx1MzBFRlx1MzBBNFx1MzBFQlx1MzBDOVx1MzBBQlx1MzBGQ1x1MzBDOVx1MzA2N1x1MzA2Rlx1MzA1M1x1MzA2RVx1NUM1RVx1NjAyN1x1NEY3Rlx1NzUyOFx1MzA2RVx1MzBDRFx1MzBGQ1x1MzBFMFx1MzBCOVx1MzBEQVx1MzBGQ1x1MzBCOScnezJ9JydcdTMwNENcdThBMzFcdTUzRUZcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4zID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4zOiBcdTMwQkZcdTMwQTRcdTMwRDcnJ3swfScnXHUzMDZFXHUzMEE4XHUzMEU5XHUzMEZDXHUzMDAyXHUzMEQ5XHUzMEZDXHUzMEI5XHUzMEZCXHUzMEJGXHUzMEE0XHUzMEQ3XHUzMDZFXHU1QzVFXHU2MDI3XHU0RjdGXHU3NTI4Jyd7MX0nJ1x1MzA2N1x1MzA2RlJFUVVJUkVEXHUzMDRDdHJ1ZVx1MzA2N1x1MzA1OVx1MzA0Q1x1MzAwMVx1NUMwRVx1NTFGQVx1MzA1NVx1MzA4Q1x1MzA1Rlx1MzBCRlx1MzBBNFx1MzBEN1x1MzA2Qlx1MzA2Rlx1MzA1RFx1MzA4Q1x1MzA2OFx1NUJGRVx1NUZEQ1x1MzA1OVx1MzA4Qlx1NUM1RVx1NjAyN1x1NEY3Rlx1NzUyOFx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotICAgICAgICBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjQuMSA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uNC4xOiBcdTMwQkZcdTMwQTRcdTMwRDcnJ3swfScnXHUzMDZFXHUzMEE4XHUzMEU5XHUzMEZDXHUzMDAyXHU1QzBFXHU1MUZBXHUzMDZCXHUzMDZGXHU1QzVFXHU2MDI3XHUzMDZFXHUzMEVGXHUzMEE0XHUzMEVCXHUzMEM5XHUzMEFCXHUzMEZDXHUzMEM5XHUzMDRDXHU1NDJCXHUzMDdFXHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5XHUzMDRDXHUzMDAxXHUzMEQ5XHUzMEZDXHUzMEI5XHUzMDZCXHUzMDZGXHU1NDJCXHUzMDdFXHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uNC4yID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi40LjI6IFx1MzBCRlx1MzBBNFx1MzBENycnezB9JydcdTMwNkVcdTMwQThcdTMwRTlcdTMwRkNcdTMwMDJcdTVDMEVcdTUxRkFcdTMwNkVcdTMwRUZcdTMwQTRcdTMwRUJcdTMwQzlcdTMwQUJcdTMwRkNcdTMwQzlcdTMwNkZcdTMwRDlcdTMwRkNcdTMwQjlcdTMwNkVcdTMwRUZcdTMwQTRcdTMwRUJcdTMwQzlcdTMwQUJcdTMwRkNcdTMwQzlcdTMwNkVcdTY3MDlcdTUyQjlcdTMwNkFcdTMwQjVcdTMwRDZcdTMwQkJcdTMwQzNcdTMwQzhcdTMwNjdcdTMwNkZcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi40LjMgPSBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjQuMzogXHUzMEJGXHUzMEE0XHUzMEQ3Jyd7MH0nJ1x1MzA2RVx1MzBBOFx1MzBFOVx1MzBGQ1x1MzAwMlx1NUMwRVx1NTFGQSh7MX0pXHUzMDZFXHUzMEVGXHUzMEE0XHUzMEVCXHUzMEM5XHUzMEFCXHUzMEZDXHUzMEM5XHUzMDZFXHUzMEQ3XHUzMEVEXHUzMEJCXHUzMEI5XHUzMEZCXHUzMEIzXHUzMEYzXHUzMEM2XHUzMEYzXHUzMEM0XHUzMDRDXHUzMDAxXHUzMEQ5XHUzMEZDXHUzMEI5KHsyfSlcdTMwNkVcdTMwODJcdTMwNkVcdTMwODhcdTMwOEFcdTVGMzFcdTMwNEZcdTMwNkFcdTMwNjNcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTlcdTMwMDIKLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi41LjIuMi4xID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi41LjIuMi4xOiBcdTMwQkZcdTMwQTRcdTMwRDcnJ3swfScnXHUzMDZFXHUzMEE4XHUzMEU5XHUzMEZDXHUzMDAyXHUzMDUzXHUzMDZFXHUzMEJGXHUzMEE0XHUzMEQ3XHUzMDZFXHU1MzU4XHU3RDE0XHUzMEIzXHUzMEYzXHUzMEM2XHUzMEYzXHUzMEM0XHUzMEZCXHUzMEJGXHUzMEE0XHUzMEQ3Jyd7MX0nJ1x1MzA2Rlx1MzAwMVx1MzBEOVx1MzBGQ1x1MzBCOVx1MzA2RVx1NTM1OFx1N0QxNFx1MzBCM1x1MzBGM1x1MzBDNlx1MzBGM1x1MzBDNFx1MzBGQlx1MzBCRlx1MzBBNFx1MzBENycnezJ9JydcdTMwNkVcdTY3MDlcdTUyQjlcdTMwNkFcdTUyMzZcdTk2NTBcdTMwNjdcdTMwNkZcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi41LjMuMiA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uNS4zLjI6IFx1MzBCRlx1MzBBNFx1MzBENycnezB9JydcdTMwNkVcdTMwQThcdTMwRTlcdTMwRkNcdTMwMDJcdTMwNTNcdTMwNkVcdTMwQkZcdTMwQTRcdTMwRDdcdTMwNkVcdTMwQjNcdTMwRjNcdTMwQzZcdTMwRjNcdTMwQzRcdTMwRkJcdTMwQkZcdTMwQTRcdTMwRDdcdTMwNkZcdTdBN0FcdTMwNjdcdTMwNTlcdTMwNENcdTMwMDFcdTMwRDlcdTMwRkNcdTMwQjlcdTMwNkVcdTMwQjNcdTMwRjNcdTMwQzZcdTMwRjNcdTMwQzRcdTMwRkJcdTMwQkZcdTMwQTRcdTMwRDcnJ3sxfScnXHUzMDZGXHU3QTdBXHUzMDY3XHUzMDZGXHUzMDZBXHUzMDQ0XHUzMDRCXHUzMDAxXHU3QTdBXHUzMDZCXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uNS40LjEuMiA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uNS40LjEuMjogXHUzMEJGXHUzMEE0XHUzMEQ3Jyd7MH0nJ1x1MzA2RVx1MzBBOFx1MzBFOVx1MzBGQ1x1MzAwMlx1MzA1M1x1MzA2RVx1MzBCRlx1MzBBNFx1MzBEN1x1MzA2RVx1MzBCM1x1MzBGM1x1MzBDNlx1MzBGM1x1MzBDNFx1MzBGQlx1MzBCRlx1MzBBNFx1MzBEN1x1MzA2Rlx1NkRGN1x1NTQwOFx1NTc4Qlx1MzA2N1x1MzA1OVx1MzA0Q1x1MzAwMVx1MzBEOVx1MzBGQ1x1MzBCOVx1MzA2RVx1MzBCM1x1MzBGM1x1MzBDNlx1MzBGM1x1MzBDNFx1MzBGQlx1MzBCRlx1MzBBNFx1MzBENycnezF9JydcdTMwNkZcdTZERjdcdTU0MDhcdTU3OEJcdTMwNjdcdTMwNkZcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi41LjQuMiA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uNS40LjI6IFx1MzBCRlx1MzBBNFx1MzBENycnezB9JydcdTMwNkVcdTMwQThcdTMwRTlcdTMwRkNcdTMwMDJcdTMwNTNcdTMwNkVcdTMwQkZcdTMwQTRcdTMwRDdcdTMwNkVcdTMwRDFcdTMwRkNcdTMwQzZcdTMwQTNcdTMwQUZcdTMwRUJcdTMwNkZcdTMwRDlcdTMwRkNcdTMwQjlcdTMwNkVcdTMwRDFcdTMwRkNcdTMwQzZcdTMwQTNcdTMwQUZcdTMwRUJcdTMwNkVcdTY3MDlcdTUyQjlcdTMwNkFcdTUyMzZcdTk2NTBcdTMwNjdcdTMwNkZcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLSAgICAgICAgZW51bWVyYXRpb24tcmVxdWlyZWQtbm90YXRpb24gPSBlbnVtZXJhdGlvbi1yZXF1aXJlZC1ub3RhdGlvbjogezJ9ICcnezF9JydcdTMwNjdcdTRGN0ZcdTc1MjhcdTMwNTVcdTMwOENcdTMwOEJOT1RBVElPTlx1MzBCRlx1MzBBNFx1MzBENycnezB9JydcdTMwNkJcdTMwNkZcdTMwMDFcdTMwNTNcdTMwNkVcdTMwQkZcdTMwQTRcdTMwRDdcdTMwNjdcdTRGN0ZcdTc1MjhcdTMwNTVcdTMwOENcdTMwOEJcdTg4NjhcdThBMThcdTZDRDVcdTg5ODFcdTdEMjBcdTMwOTJcdTYzMDdcdTVCOUFcdTMwNTlcdTMwOEJcdTUyMTdcdTYzMTlcdTMwRDVcdTMwQTFcdTMwQkJcdTMwQzNcdTMwQzhcdTUwMjRcdTMwNENcdTU0MkJcdTMwN0VcdTMwOENcdTMwNjZcdTMwNDRcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIKLSAgICAgICAgZW51bWVyYXRpb24tdmFsaWQtcmVzdHJpY3Rpb24gPSBlbnVtZXJhdGlvbi12YWxpZC1yZXN0cmljdGlvbjogXHU1MjE3XHU2MzE5XHU1MDI0Jyd7MH0nJ1x1MzA2Rlx1MzBEOVx1MzBGQ1x1MzBCOVx1MzBGQlx1MzBCRlx1MzBBNFx1MzBEN1x1MzA2RVx1NTAyNFx1N0E3QVx1OTU5M3sxfVx1MzA2Qlx1NUI1OFx1NTcyOFx1MzA1N1x1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotICAgICAgICBlLXByb3BzLWNvcnJlY3QuMiA9IGUtcHJvcHMtY29ycmVjdC4yOiBcdTg5ODFcdTdEMjAnJ3swfScnXHUzMDZFXHU1MDI0XHU1MjM2XHU3RDA0XHUzMDZFXHU1MDI0Jyd7MX0nJ1x1MzA0Q1x1NzEyMVx1NTJCOVx1MzA2N1x1MzA1OVx1MzAwMgotICAgICAgICBlLXByb3BzLWNvcnJlY3QuNCA9IGUtcHJvcHMtY29ycmVjdC40OiBcdTg5ODFcdTdEMjAnJ3swfScnXHUzMDZFJ3sndHlwZSBkZWZpbml0aW9uJ30nXHUzMDRDc3Vic3RpdHV0aW9uSGVhZCAnJ3sxfScnXHUzMDZFJ3sndHlwZSBkZWZpbml0aW9uJ30nXHUzMDRCXHUzMDg5XHU2QjYzXHU1RTM4XHUzMDZCXHU1QzBFXHU1MUZBXHUzMDU1XHUzMDhDXHUzMDVGXHUzMDgyXHUzMDZFXHUzMDY3XHUzMDZBXHUzMDQ0XHUzMDRCXHUzMDAxJyd7MX0nJ1x1MzA2RSd7J3N1YnN0aXR1dGlvbiBncm91cCBleGNsdXNpb25zJ30nXHUzMEQ3XHUzMEVEXHUzMEQxXHUzMEM2XHUzMEEzXHUzMDY3XHUzMDUzXHUzMDZFXHU1QzBFXHU1MUZBXHUzMDRDXHU4QTMxXHU1M0VGXHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0gICAgICAgIGUtcHJvcHMtY29ycmVjdC41ID0gZS1wcm9wcy1jb3JyZWN0LjU6IFx1ODk4MVx1N0QyMFx1MzA2RSd7J3R5cGUgZGVmaW5pdGlvbid9J1x1MzA3RVx1MzA1Rlx1MzA2Rid7J3R5cGUgZGVmaW5pdGlvbid9J1x1MzA2RSd7J2NvbnRlbnQgdHlwZSd9J1x1MzA2RklEXHUzMDY3XHUzMDQyXHUzMDhCXHUzMDRCXHUzMDAxSURcdTMwNEJcdTMwODlcdTVDMEVcdTUxRkFcdTMwNTVcdTMwOENcdTMwNUZcdTMwODJcdTMwNkVcdTMwNjdcdTMwNDJcdTMwOEJcdTMwNUZcdTMwODFcdTMwMDFcdTg5ODFcdTdEMjAnJ3swfScnXHUzMDZCJ3sndmFsdWUgY29uc3RyYWludCd9J1x1MzA5Mlx1NTQyQlx1MzA4MVx1MzA4Qlx1MzA1M1x1MzA2OFx1MzA2Rlx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotICAgICAgICBlLXByb3BzLWNvcnJlY3QuNiA9IGUtcHJvcHMtY29ycmVjdC42OiBcdTg5ODFcdTdEMjAnJ3swfScnXHUzMDY3XHU1RkFBXHU3NEIwXHU3RjZFXHU2M0RCXHUzMEIwXHUzMEVCXHUzMEZDXHUzMEQ3XHUzMDRDXHU2OTFDXHU1MUZBXHUzMDU1XHUzMDhDXHUzMDdFXHUzMDU3XHUzMDVGXHUzMDAyCi0gICAgICAgIGZyYWN0aW9uRGlnaXRzLXZhbGlkLXJlc3RyaWN0aW9uID0gZnJhY3Rpb25EaWdpdHMtdmFsaWQtcmVzdHJpY3Rpb246IFx1MzBENVx1MzBBMVx1MzBCQlx1MzBDM1x1MzBDOCcnZnJhY3Rpb25EaWdpdHMnJ1x1MzA2RVx1NTAyNCcnezB9JydcdTMwNkZcdTMwMDFcdTc5NTZcdTUxNDhcdTMwQkZcdTMwQTRcdTMwRDdcdTMwNkVcdTMwNDRcdTMwNUFcdTMwOENcdTMwNEJcdTMwNjcnJ3sxfScnXHUzMDZCXHU4QTJEXHU1QjlBXHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDhCJydmcmFjdGlvbkRpZ2l0cycnXHUzMDZFXHU1MDI0XHU0RUU1XHU0RTBCXHUzMDY3XHUzMDQyXHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhCXHUzMDVGXHUzMDgxXHUzMDAxezJ9XHUzMDZFXHU1QjlBXHU3RkE5XHUzMDY3XHUzMDZGXHU3MTIxXHU1MkI5XHUzMDY3XHUzMDU5XHUzMDAyCi0gICAgICAgIGZyYWN0aW9uRGlnaXRzLXRvdGFsRGlnaXRzID0gZnJhY3Rpb25EaWdpdHMtdG90YWxEaWdpdHM6IFx1MzBENVx1MzBBMVx1MzBCQlx1MzBDM1x1MzBDOCcnZnJhY3Rpb25EaWdpdHMnJ1x1MzA2RVx1NTAyNCcnezB9JydcdTMwNkZcdTMwMDEnJ3RvdGFsRGlnaXRzJydcdTMwNkVcdTUwMjQnJ3sxfScnXHU0RUU1XHU0RTBCXHUzMDY3XHUzMDQyXHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhCXHUzMDVGXHUzMDgxXHUzMDAxezJ9XHUzMDZFXHU1QjlBXHU3RkE5XHUzMDY3XHUzMDZGXHU3MTIxXHU1MkI5XHUzMDY3XHUzMDU5XHUzMDAyCi0gICAgICAgIGxlbmd0aC1taW5MZW5ndGgtbWF4TGVuZ3RoLjEuMSA9IGxlbmd0aC1taW5MZW5ndGgtbWF4TGVuZ3RoLjEuMTogXHUzMEJGXHUzMEE0XHUzMEQ3ezB9XHUzMDY3XHUzMDZGXHUzMDAxbGVuZ3RoXHUzMDZFXHU1MDI0Jyd7MX0nJ1x1MzA0Q21pbkxlbmd0aFx1MzA2RVx1NTAyNCcnezJ9JydcdTMwODhcdTMwOEFcdTVDMEZcdTMwNTVcdTMwNDRcdTMwNjhcdTMwMDFcdTMwQThcdTMwRTlcdTMwRkNcdTMwNkJcdTMwNkFcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIKLSAgICAgICAgbGVuZ3RoLW1pbkxlbmd0aC1tYXhMZW5ndGguMS4yLmEgPSBsZW5ndGgtbWluTGVuZ3RoLW1heExlbmd0aC4xLjIuYTogXHUzMEJGXHUzMEE0XHUzMEQ3ezB9XHUzMDY3XHUzMDZGXHUzMDAxXHU3M0ZFXHU1NzI4XHUzMDZFXHU1MjM2XHU5NjUwXHUzMDZFXHUzMEQ1XHUzMEExXHUzMEJCXHUzMEMzXHUzMEM4XHUzMDRDbWluTGVuZ3RoXHUzMDY3XHUzMDQyXHUzMDhBXHUzMDAxXHU3M0ZFXHU1NzI4XHUzMDZFXHU1MjM2XHU5NjUwXHUzMDdFXHUzMDVGXHUzMDZGXHUzMEQ5XHUzMEZDXHUzMEI5XHUzMDZFXHUzMEQ1XHUzMEExXHUzMEJCXHUzMEMzXHUzMEM4XHUzMDRDbGVuZ3RoXHUzMDY3XHUzMDQyXHUzMDhCXHU1ODM0XHU1NDA4XHUzMDAxXHUzMEQ5XHUzMEZDXHUzMEI5XHUzMDZCbWluTGVuZ3RoXHUzMEQ1XHUzMEExXHUzMEJCXHUzMEMzXHUzMEM4XHUzMDRDXHU1NDJCXHUzMDdFXHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDZBXHUzMDQ0XHUzMDY4XHUzMDAxXHUzMEE4XHUzMEU5XHUzMEZDXHUzMDZCXHUzMDZBXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIGxlbmd0aC1taW5MZW5ndGgtbWF4TGVuZ3RoLjEuMi5iID0gbGVuZ3RoLW1pbkxlbmd0aC1tYXhMZW5ndGguMS4yLmI6IFx1MzBCRlx1MzBBNFx1MzBEN3swfVx1MzA2N1x1MzA2Rlx1MzAwMVx1NzNGRVx1NTcyOFx1MzA2RW1pbkxlbmd0aCAnJ3sxfScnXHUzMDRDXHUzMEQ5XHUzMEZDXHUzMEI5XHUzMDZFbWluTGVuZ3RoICcnezJ9JydcdTMwNjhcdTdCNDlcdTMwNTdcdTMwNEZcdTMwNkFcdTMwNDRcdTMwNjhcdTMwMDFcdTMwQThcdTMwRTlcdTMwRkNcdTMwNkJcdTMwNkFcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIKLSAgICAgICAgbGVuZ3RoLW1pbkxlbmd0aC1tYXhMZW5ndGguMi4xID0gbGVuZ3RoLW1pbkxlbmd0aC1tYXhMZW5ndGguMi4xOiBcdTMwQkZcdTMwQTRcdTMwRDd7MH1cdTMwNjdcdTMwNkZcdTMwMDFsZW5ndGhcdTMwNkVcdTUwMjQnJ3sxfScnXHUzMDRDbWF4TGVuZ3RoXHUzMDZFXHU1MDI0Jyd7Mn0nJ1x1MzA4OFx1MzA4QVx1NTkyN1x1MzA0RFx1MzA0NFx1MzA2OFx1MzAwMVx1MzBBOFx1MzBFOVx1MzBGQ1x1MzA2Qlx1MzA2QVx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBsZW5ndGgtbWluTGVuZ3RoLW1heExlbmd0aC4yLjIuYSA9IGxlbmd0aC1taW5MZW5ndGgtbWF4TGVuZ3RoLjIuMi5hOiBcdTMwQkZcdTMwQTRcdTMwRDd7MH1cdTMwNjdcdTMwNkZcdTMwMDFcdTczRkVcdTU3MjhcdTMwNkVcdTUyMzZcdTk2NTBcdTMwNkVcdTMwRDVcdTMwQTFcdTMwQkJcdTMwQzNcdTMwQzhcdTMwNENtYXhMZW5ndGhcdTMwNjdcdTMwNDJcdTMwOEFcdTMwMDFcdTczRkVcdTU3MjhcdTMwNkVcdTUyMzZcdTk2NTBcdTMwN0VcdTMwNUZcdTMwNkZcdTMwRDlcdTMwRkNcdTMwQjlcdTMwNkVcdTMwRDVcdTMwQTFcdTMwQkJcdTMwQzNcdTMwQzhcdTMwNENsZW5ndGhcdTMwNjdcdTMwNDJcdTMwOEJcdTU4MzRcdTU0MDhcdTMwMDFcdTMwRDlcdTMwRkNcdTMwQjlcdTMwNkJtYXhMZW5ndGhcdTMwRDVcdTMwQTFcdTMwQkJcdTMwQzNcdTMwQzhcdTMwNENcdTU0MkJcdTMwN0VcdTMwOENcdTMwNjZcdTMwNDRcdTMwNkFcdTMwNDRcdTMwNjhcdTMwMDFcdTMwQThcdTMwRTlcdTMwRkNcdTMwNkJcdTMwNkFcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIKLSAgICAgICAgbGVuZ3RoLW1pbkxlbmd0aC1tYXhMZW5ndGguMi4yLmIgPSBsZW5ndGgtbWluTGVuZ3RoLW1heExlbmd0aC4yLjIuYjogXHUzMEJGXHUzMEE0XHUzMEQ3ezB9XHUzMDY3XHUzMDZGXHUzMDAxXHU3M0ZFXHU1NzI4XHUzMDZFbWF4TGVuZ3RoICcnezF9JydcdTMwNENcdTMwRDlcdTMwRkNcdTMwQjlcdTMwNkVtYXhMZW5ndGggJyd7Mn0nJ1x1MzA2OFx1N0I0OVx1MzA1N1x1MzA0Rlx1MzA2QVx1MzA0NFx1MzA2OFx1MzAwMVx1MzBBOFx1MzBFOVx1MzBGQ1x1MzA2Qlx1MzA2QVx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBsZW5ndGgtdmFsaWQtcmVzdHJpY3Rpb24gPSBsZW5ndGgtdmFsaWQtcmVzdHJpY3Rpb246IFx1MzBCRlx1MzBBNFx1MzBENycnezJ9JydcdTMwNkVcdTMwQThcdTMwRTlcdTMwRkNcdTMwMDJcdTk1NzdcdTMwNTVcdTMwNkVcdTUwMjQnJ3swfScnXHUzMDZGXHUzMEQ5XHUzMEZDXHUzMEI5XHUzMEZCXHUzMEJGXHUzMEE0XHUzMEQ3Jyd7MX0nJ1x1MzA2RWxlbmd0aFx1MzA2RVx1NTAyNFx1MzA2OFx1NTQwQ1x1MzA1OFx1MzA2N1x1MzA0Mlx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBtYXhFeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMSA9IG1heEV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4xOiBcdTMwQkZcdTMwQTRcdTMwRDcnJ3syfScnXHUzMDZFXHUzMEE4XHUzMEU5XHUzMEZDXHUzMDAybWF4RXhjbHVzaXZlXHUzMDZFXHU1MDI0Jyd7MH0nJ1x1MzA2Rlx1MzBEOVx1MzBGQ1x1MzBCOVx1MzBGQlx1MzBCRlx1MzBBNFx1MzBENycnezF9JydcdTMwNkVtYXhFeGNsdXNpdmVcdTRFRTVcdTRFMEJcdTMwNjdcdTMwNDJcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIKLSAgICAgICAgbWF4RXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjIgPSBtYXhFeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMjogXHUzMEJGXHUzMEE0XHUzMEQ3Jyd7Mn0nJ1x1MzA2RVx1MzBBOFx1MzBFOVx1MzBGQ1x1MzAwMm1heEV4Y2x1c2l2ZVx1MzA2RVx1NTAyNCcnezB9JydcdTMwNkZcdTMwRDlcdTMwRkNcdTMwQjlcdTMwRkJcdTMwQkZcdTMwQTRcdTMwRDcnJ3sxfScnXHUzMDZFbWF4SW5jbHVzaXZlXHU0RUU1XHU0RTBCXHUzMDY3XHUzMDQyXHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIG1heEV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4zID0gbWF4RXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjM6IFx1MzBCRlx1MzBBNFx1MzBENycnezJ9JydcdTMwNkVcdTMwQThcdTMwRTlcdTMwRkNcdTMwMDJtYXhFeGNsdXNpdmVcdTMwNkVcdTUwMjQnJ3swfScnXHUzMDZGXHUzMEQ5XHUzMEZDXHUzMEI5XHUzMEZCXHUzMEJGXHUzMEE0XHUzMEQ3Jyd7MX0nJ1x1MzA2RW1pbkluY2x1c2l2ZVx1MzA4OFx1MzA4QVx1NTkyN1x1MzA0RFx1MzA0Rlx1MzA1OVx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBtYXhFeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uNCA9IG1heEV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi40OiBcdTMwQkZcdTMwQTRcdTMwRDcnJ3syfScnXHUzMDZFXHUzMEE4XHUzMEU5XHUzMEZDXHUzMDAybWF4RXhjbHVzaXZlXHUzMDZFXHU1MDI0Jyd7MH0nJ1x1MzA2Rlx1MzBEOVx1MzBGQ1x1MzBCOVx1MzBGQlx1MzBCRlx1MzBBNFx1MzBENycnezF9JydcdTMwNkVtaW5FeGNsdXNpdmVcdTMwODhcdTMwOEFcdTU5MjdcdTMwNERcdTMwNEZcdTMwNTlcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIKLSAgICAgICAgbWF4SW5jbHVzaXZlLW1heEV4Y2x1c2l2ZSA9IG1heEluY2x1c2l2ZS1tYXhFeGNsdXNpdmU6IFx1NTQwQ1x1MzA1OFx1MzBDN1x1MzBGQ1x1MzBCRlx1NTc4Qlx1MzA2Qlx1NUJGRVx1MzA1N1x1MzA2Nm1heEluY2x1c2l2ZVx1MzA2OG1heEV4Y2x1c2l2ZVx1MzA2RVx1NEUyMVx1NjVCOVx1MzA5Mlx1NjMwN1x1NUI5QVx1MzA1N1x1MzA1Rlx1MzA1M1x1MzA2OFx1MzA2Qlx1MzA4OFx1MzA4Qlx1MzBBOFx1MzBFOVx1MzBGQ1x1MzA2N1x1MzA1OVx1MzAwMnsyfVx1MzA2N1x1MzA2Rlx1MzAwMW1heEluY2x1c2l2ZVx1MzA2RicnezB9JydcdTMwMDFtYXhFeGNsdXNpdmVcdTMwNkYnJ3sxfScnXHUzMDY3XHUzMDU5XHUzMDAyCi0gICAgICAgIG1heEluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4xID0gbWF4SW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjE6IFx1MzBCRlx1MzBBNFx1MzBENycnezJ9JydcdTMwNkVcdTMwQThcdTMwRTlcdTMwRkNcdTMwMDJtYXhJbmNsdXNpdmVcdTMwNkVcdTUwMjQnJ3swfScnXHUzMDZGXHUzMEQ5XHUzMEZDXHUzMEI5XHUzMEZCXHUzMEJGXHUzMEE0XHUzMEQ3Jyd7MX0nJ1x1MzA2RW1heEluY2x1c2l2ZVx1NEVFNVx1NEUwQlx1MzA2N1x1MzA0Mlx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBtYXhJbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMiA9IG1heEluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4yOiBcdTMwQkZcdTMwQTRcdTMwRDcnJ3syfScnXHUzMDZFXHUzMEE4XHUzMEU5XHUzMEZDXHUzMDAybWF4SW5jbHVzaXZlXHUzMDZFXHU1MDI0Jyd7MH0nJ1x1MzA2Rlx1MzBEOVx1MzBGQ1x1MzBCOVx1MzBGQlx1MzBCRlx1MzBBNFx1MzBENycnezF9JydcdTMwNkVtYXhFeGNsdXNpdmVcdTMwODhcdTMwOEFcdTVDMEZcdTMwNTVcdTMwNEZcdTMwNTlcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIKLSAgICAgICAgbWF4SW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjMgPSBtYXhJbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMzogXHUzMEJGXHUzMEE0XHUzMEQ3Jyd7Mn0nJ1x1MzA2RVx1MzBBOFx1MzBFOVx1MzBGQ1x1MzAwMm1heEluY2x1c2l2ZVx1MzA2RVx1NTAyNCcnezB9JydcdTMwNkZcdTMwRDlcdTMwRkNcdTMwQjlcdTMwRkJcdTMwQkZcdTMwQTRcdTMwRDcnJ3sxfScnXHUzMDZFbWluSW5jbHVzaXZlXHU0RUU1XHU0RTBBXHUzMDY3XHUzMDQyXHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIG1heEluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi40ID0gbWF4SW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjQ6IFx1MzBCRlx1MzBBNFx1MzBENycnezJ9JydcdTMwNkVcdTMwQThcdTMwRTlcdTMwRkNcdTMwMDJtYXhJbmNsdXNpdmVcdTMwNkVcdTUwMjQnJ3swfScnXHUzMDZGXHUzMEQ5XHUzMEZDXHUzMEI5XHUzMEZCXHUzMEJGXHUzMEE0XHUzMEQ3Jyd7MX0nJ1x1MzA2RW1pbkV4Y2x1c2l2ZVx1MzA4OFx1MzA4QVx1NTkyN1x1MzA0RFx1MzA0Rlx1MzA1OVx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBtYXhMZW5ndGgtdmFsaWQtcmVzdHJpY3Rpb24gPSBtYXhMZW5ndGgtdmFsaWQtcmVzdHJpY3Rpb246IHsyfVx1MzA2RVx1NUI5QVx1N0ZBOVx1MzA2N1x1MzA2Rlx1MzAwMW1heExlbmd0aFx1MzA2RVx1NTAyNCcnezB9JydcdTMwNkZcdTMwRDlcdTMwRkNcdTMwQjlcdTMwRkJcdTMwQkZcdTMwQTRcdTMwRDcnJ3sxfScnXHUzMDZFXHU1MDI0XHU0RUU1XHU0RTBCXHUzMDY3XHUzMDQyXHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIG1nLXByb3BzLWNvcnJlY3QuMiA9IG1nLXByb3BzLWNvcnJlY3QuMjogXHUzMEIwXHUzMEVCXHUzMEZDXHUzMEQ3Jyd7MH0nJ1x1MzA2N1x1NUZBQVx1NzRCMFx1NUI5QVx1N0ZBOVx1MzA0Q1x1NjkxQ1x1NTFGQVx1MzA1NVx1MzA4Q1x1MzA3RVx1MzA1N1x1MzA1Rlx1MzAwMlx1MzBEMVx1MzBGQ1x1MzBDNlx1MzBBM1x1MzBBRlx1MzBFQlx1MzA2RSd7J3Rlcm0nfSdcdTUwMjRcdTMwOTJcdTUxOERcdTVFMzBcdTc2ODRcdTMwNkJcdTMwNUZcdTMwNjlcdTMwOEJcdTMwNjhcdTMwMDEneyd0ZXJtJ30nXHUzMDRDXHUzMEIwXHUzMEVCXHUzMEZDXHUzMEQ3XHU4MUVBXHU0RjUzXHUzMDY3XHUzMDQyXHUzMDhCXHUzMEQxXHUzMEZDXHUzMEM2XHUzMEEzXHUzMEFGXHUzMEVCXHUzMDZCXHU5MDU0XHUzMDU3XHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIG1pbkV4Y2x1c2l2ZS1sZXNzLXRoYW4tZXF1YWwtdG8tbWF4RXhjbHVzaXZlID0gbWluRXhjbHVzaXZlLWxlc3MtdGhhbi1lcXVhbC10by1tYXhFeGNsdXNpdmU6IHsyfVx1MzA2RVx1NUI5QVx1N0ZBOVx1MzA2N1x1MzA2Rlx1MzAwMW1pbkV4Y2x1c2l2ZVx1MzA2RVx1NTAyNCcnezB9JydcdTMwNkZtYXhFeGNsdXNpdmVcdTMwNkVcdTUwMjQnJ3sxfScnXHU0RUU1XHU0RTBCXHUzMDY3XHUzMDQyXHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIG1pbkV4Y2x1c2l2ZS1sZXNzLXRoYW4tbWF4SW5jbHVzaXZlID0gbWluRXhjbHVzaXZlLWxlc3MtdGhhbi1tYXhJbmNsdXNpdmU6IHsyfVx1MzA2RVx1NUI5QVx1N0ZBOVx1MzA2N1x1MzA2Rlx1MzAwMW1pbkV4Y2x1c2l2ZVx1MzA2RVx1NTAyNCcnezB9JydcdTMwNkZtYXhJbmNsdXNpdmVcdTMwNkVcdTUwMjQnJ3sxfScnXHUzMDg4XHUzMDhBXHU1QzBGXHUzMDU1XHUzMDRGXHUzMDU5XHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIG1pbkV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4xID0gbWluRXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjE6IFx1MzBCRlx1MzBBNFx1MzBENycnezJ9JydcdTMwNkVcdTMwQThcdTMwRTlcdTMwRkNcdTMwMDJtaW5FeGNsdXNpdmVcdTMwNkVcdTUwMjQnJ3swfScnXHUzMDZGXHUzMEQ5XHUzMEZDXHUzMEI5XHUzMEZCXHUzMEJGXHUzMEE0XHUzMEQ3Jyd7MX0nJ1x1MzA2RW1pbkV4Y2x1c2l2ZVx1NEVFNVx1NEUwQVx1MzA2N1x1MzA0Mlx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBtaW5FeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMiA9IG1pbkV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4yOiAnJ1x1MzBCRlx1MzBBNFx1MzBENycnezJ9JydcdTMwNkVcdTMwQThcdTMwRTlcdTMwRkNcdTMwMDJtaW5FeGNsdXNpdmVcdTMwNkVcdTUwMjQnJ3swfScnXHUzMDZGXHUzMEQ5XHUzMEZDXHUzMEI5XHUzMEZCXHUzMEJGXHUzMEE0XHUzMEQ3Jyd7MX0nJ1x1MzA2RW1heEluY2x1c2l2ZVx1NEVFNVx1NEUwQlx1MzA2N1x1MzA0Mlx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBtaW5FeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMyA9IG1pbkV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4zOiBcdTMwQkZcdTMwQTRcdTMwRDcnJ3syfScnXHUzMDZFXHUzMEE4XHUzMEU5XHUzMEZDXHUzMDAybWluRXhjbHVzaXZlXHUzMDZFXHU1MDI0Jyd7MH0nJ1x1MzA2Rlx1MzBEOVx1MzBGQ1x1MzBCOVx1MzBGQlx1MzBCRlx1MzBBNFx1MzBENycnezF9JydcdTMwNkVtaW5JbmNsdXNpdmVcdTRFRTVcdTRFMEFcdTMwNjdcdTMwNDJcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIKLSAgICAgICAgbWluRXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjQgPSBtaW5FeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uNDogXHUzMEJGXHUzMEE0XHUzMEQ3Jyd7Mn0nJ1x1MzA2RVx1MzBBOFx1MzBFOVx1MzBGQ1x1MzAwMm1pbkV4Y2x1c2l2ZVx1MzA2RVx1NTAyNCcnezB9JydcdTMwNkZcdTMwRDlcdTMwRkNcdTMwQjlcdTMwRkJcdTMwQkZcdTMwQTRcdTMwRDcnJ3sxfScnXHUzMDZFbWF4RXhjbHVzaXZlXHUzMDg4XHUzMDhBXHU1QzBGXHUzMDU1XHUzMDRGXHUzMDU5XHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIG1pbkluY2x1c2l2ZS1sZXNzLXRoYW4tZXF1YWwtdG8tbWF4SW5jbHVzaXZlID0gbWluSW5jbHVzaXZlLWxlc3MtdGhhbi1lcXVhbC10by1tYXhJbmNsdXNpdmU6IHsyfVx1MzA2RVx1NUI5QVx1N0ZBOVx1MzA2N1x1MzA2Rlx1MzAwMW1pbkluY2x1c2l2ZVx1MzA2RVx1NTAyNCcnezB9JydcdTMwNkZtYXhJbmNsdXNpdmVcdTMwNkVcdTUwMjQnJ3sxfScnXHU0RUU1XHU0RTBCXHUzMDY3XHUzMDQyXHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIG1pbkluY2x1c2l2ZS1sZXNzLXRoYW4tbWF4RXhjbHVzaXZlID0gbWluSW5jbHVzaXZlLWxlc3MtdGhhbi1tYXhFeGNsdXNpdmU6IHsyfVx1MzA2RVx1NUI5QVx1N0ZBOVx1MzA2N1x1MzA2Rlx1MzAwMW1pbkluY2x1c2l2ZVx1MzA2RVx1NTAyNCcnezB9JydcdTMwNkZtYXhFeGNsdXNpdmVcdTMwNkVcdTUwMjQnJ3sxfScnXHUzMDg4XHUzMDhBXHU1QzBGXHUzMDU1XHUzMDRGXHUzMDU5XHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIG1pbkluY2x1c2l2ZS1taW5FeGNsdXNpdmUgPSBtaW5JbmNsdXNpdmUtbWluRXhjbHVzaXZlOiBcdTU0MENcdTMwNThcdTMwQzdcdTMwRkNcdTMwQkZcdTU3OEJcdTMwNkJcdTVCRkVcdTMwNTdcdTMwNjZtaW5JbmNsdXNpdmVcdTMwNjhtaW5FeGNsdXNpdmVcdTMwNkVcdTRFMjFcdTY1QjlcdTMwOTJcdTYzMDdcdTVCOUFcdTMwNTdcdTMwNUZcdTMwNTNcdTMwNjhcdTMwNkJcdTMwODhcdTMwOEJcdTMwQThcdTMwRTlcdTMwRkNcdTMwNjdcdTMwNTlcdTMwMDJ7Mn1cdTMwNjdcdTMwNkZcdTMwMDFtaW5JbmNsdXNpdmVcdTMwNkYnJ3swfScnXHUzMDAxbWluRXhjbHVzaXZlXHUzMDZGJyd7MX0nJ1x1MzA2N1x1MzA1OVx1MzAwMgotICAgICAgICBtaW5JbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMSA9IG1pbkluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4xOiBcdTMwQkZcdTMwQTRcdTMwRDcnJ3syfScnXHUzMDZFXHUzMEE4XHUzMEU5XHUzMEZDXHUzMDAybWluSW5jbHVzaXZlXHUzMDZFXHU1MDI0Jyd7MH0nJ1x1MzA2Rlx1MzBEOVx1MzBGQ1x1MzBCOVx1MzBGQlx1MzBCRlx1MzBBNFx1MzBENycnezF9JydcdTMwNkVtaW5JbmNsdXNpdmVcdTRFRTVcdTRFMEFcdTMwNjdcdTMwNDJcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIKLSAgICAgICAgbWluSW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjIgPSBtaW5JbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMjogXHUzMEJGXHUzMEE0XHUzMEQ3Jyd7Mn0nJ1x1MzA2RVx1MzBBOFx1MzBFOVx1MzBGQ1x1MzAwMm1pbkluY2x1c2l2ZVx1MzA2RVx1NTAyNCcnezB9JydcdTMwNkZcdTMwRDlcdTMwRkNcdTMwQjlcdTMwRkJcdTMwQkZcdTMwQTRcdTMwRDcnJ3sxfScnXHUzMDZFbWF4SW5jbHVzaXZlXHU0RUU1XHU0RTBCXHUzMDY3XHUzMDQyXHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIG1pbkluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4zID0gbWluSW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjM6IFx1MzBCRlx1MzBBNFx1MzBENycnezJ9JydcdTMwNkVcdTMwQThcdTMwRTlcdTMwRkNcdTMwMDJtaW5JbmNsdXNpdmVcdTMwNkVcdTUwMjQnJ3swfScnXHUzMDZGXHUzMEQ5XHUzMEZDXHUzMEI5XHUzMEZCXHUzMEJGXHUzMEE0XHUzMEQ3Jyd7MX0nJ1x1MzA2RW1pbkV4Y2x1c2l2ZVx1MzA4OFx1MzA4QVx1NTkyN1x1MzA0RFx1MzA0Rlx1MzA1OVx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBtaW5JbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uNCA9IG1pbkluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi40OiBcdTMwQkZcdTMwQTRcdTMwRDcnJ3syfScnXHUzMDZFXHUzMEE4XHUzMEU5XHUzMEZDXHUzMDAybWluSW5jbHVzaXZlXHUzMDZFXHU1MDI0Jyd7MH0nJ1x1MzA2Rlx1MzBEOVx1MzBGQ1x1MzBCOVx1MzBGQlx1MzBCRlx1MzBBNFx1MzBENycnezF9JydcdTMwNkVtYXhFeGNsdXNpdmVcdTMwODhcdTMwOEFcdTVDMEZcdTMwNTVcdTMwNEZcdTMwNTlcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIKLSAgICAgICAgbWluTGVuZ3RoLWxlc3MtdGhhbi1lcXVhbC10by1tYXhMZW5ndGggPSBtaW5MZW5ndGgtbGVzcy10aGFuLWVxdWFsLXRvLW1heExlbmd0aDogezJ9XHUzMDZFXHU1QjlBXHU3RkE5XHUzMDY3XHUzMDZGXHUzMDAxbWluTGVuZ3RoXHUzMDZFXHU1MDI0Jyd7MH0nJ1x1MzA2Rm1heExlbmd0aFx1MzA2RVx1NTAyNCcnezF9JydcdTMwODhcdTMwOEFcdTVDMEZcdTMwNTVcdTMwNEZcdTMwNTlcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIKLSAgICAgICAgbWluTGVuZ3RoLXZhbGlkLXJlc3RyaWN0aW9uID0gbWluTGVuZ3RoLXZhbGlkLXJlc3RyaWN0aW9uOiB7Mn1cdTMwNkVcdTVCOUFcdTdGQTlcdTMwNjdcdTMwNkZcdTMwMDFtaW5MZW5ndGhcdTMwNkVcdTUwMjQnJ3swfScnXHUzMDZGXHUzMEQ5XHUzMEZDXHUzMEI5XHUzMEZCXHUzMEJGXHUzMEE0XHUzMEQ3Jyd7MX0nJ1x1MzA2RVx1NTAyNFx1NEVFNVx1NEUwQVx1MzA2N1x1MzA0Mlx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBuby14bWxucyA9IG5vLXhtbG5zOiBcdTVDNUVcdTYwMjdcdTVCQTNcdThBMDBcdTMwNkV7bmFtZX1cdTMwOTIneG1sbnMnXHUzMDY4XHU1NDBDXHU0RTAwXHUzMDZCXHUzMDU5XHUzMDhCXHUzMDUzXHUzMDY4XHUzMDZGXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0gICAgICAgIG5vLXhzaSA9IG5vLXhzaTogXHU1QzVFXHU2MDI3XHU1QkEzXHU4QTAwXHUzMDZFJ3sndGFyZ2V0IG5hbWVzcGFjZSd9J1x1MzA5MicnezB9JydcdTMwNjhcdTU0MENcdTRFMDBcdTMwNkJcdTMwNTlcdTMwOEJcdTMwNTNcdTMwNjhcdTMwNkZcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLSAgICAgICAgcC1wcm9wcy1jb3JyZWN0LjIuMSA9IHAtcHJvcHMtY29ycmVjdC4yLjE6ICcnezB9JydcdTMwNkVcdTVCQTNcdThBMDBcdTMwNjdcdTMwNkZcdTMwMDEnJ21pbk9jY3VycycnXHUzMDZFXHU1MDI0XHUzMDZGJyd7MX0nJ1x1MzA2N1x1MzA1OVx1MzA0Q1x1MzAwMScnbWF4T2NjdXJzJydcdTMwNkVcdTUwMjQnJ3syfScnXHUzMDg4XHUzMDhBXHU1OTI3XHUzMDREXHUzMDRGXHUzMDU5XHUzMDhCXHUzMDUzXHUzMDY4XHUzMDZGXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0gICAgICAgIHJjYXNlLU1hcEFuZFN1bS4xID0gcmNhc2UtTWFwQW5kU3VtLjE6IFx1MzBEMVx1MzBGQ1x1MzBDNlx1MzBBM1x1MzBBRlx1MzBFQlx1OTU5M1x1MzA2Qlx1NUI4Q1x1NTE2OFx1MzA2QVx1NkE1Rlx1ODBGRFx1MzBERVx1MzBDM1x1MzBENFx1MzBGM1x1MzBCMFx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotICAgICAgICByY2FzZS1NYXBBbmRTdW0uMiA9IHJjYXNlLU1hcEFuZFN1bS4yOiBcdTMwQjBcdTMwRUJcdTMwRkNcdTMwRDdcdTMwNkVcdTUxRkFcdTczRkVcdTdCQzRcdTU2RjIoezB9LHsxfSlcdTMwNENcdTMwRDlcdTMwRkNcdTMwQjlcdTMwRkJcdTMwQjBcdTMwRUJcdTMwRkNcdTMwRDdcdTMwNkVcdTUxRkFcdTczRkVcdTdCQzRcdTU2RjIoezJ9LHszfSlcdTMwNkVcdTY3MDlcdTUyQjlcdTMwNkFcdTUyMzZcdTk2NTBcdTMwNjdcdTMwNkZcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLSAgICAgICAgcmNhc2UtTmFtZUFuZFR5cGVPSy4xID0gcmNhc2UtTmFtZUFuZFR5cGVPSy4xOiBcdTg5ODFcdTdEMjBcdTMwNkJcdTc1NzBcdTMwNkFcdTMwOEJcdTU0MERcdTUyNERcdTMwODRcdTMwQkZcdTMwRkNcdTMwQjJcdTMwQzNcdTMwQzhcdTMwRkJcdTMwQ0RcdTMwRkNcdTMwRTBcdTMwQjlcdTMwREFcdTMwRkNcdTMwQjlcdTMwNENcdTU0MkJcdTMwN0VcdTMwOENcdTMwN0VcdTMwNTk6IFx1MzBDRFx1MzBGQ1x1MzBFMFx1MzBCOVx1MzBEQVx1MzBGQ1x1MzBCOScnezF9JydcdTMwNkVcdTg5ODFcdTdEMjAnJ3swfScnXHUzMDRBXHUzMDg4XHUzMDczXHUzMENEXHUzMEZDXHUzMEUwXHUzMEI5XHUzMERBXHUzMEZDXHUzMEI5Jyd7M30nJ1x1MzA2RVx1ODk4MVx1N0QyMCcnezJ9JydcdTMwNjdcdTMwNTlcdTMwMDIKLSAgICAgICAgcmNhc2UtTmFtZUFuZFR5cGVPSy4yID0gcmNhc2UtTmFtZUFuZFR5cGVPSy4yOiAneyd0ZXJtJ30nXHUzMDRDXHU4OTgxXHU3RDIwXHU1QkEzXHU4QTAwJyd7MH0nJ1x1MzA2N1x1MzA0Mlx1MzA4Qlx1MzBEMVx1MzBGQ1x1MzBDNlx1MzBBM1x1MzBBRlx1MzBFQlx1MzA2RVx1MzBBOFx1MzBFOVx1MzBGQ1x1MzAwMlx1ODk4MVx1N0QyMFx1NUJBM1x1OEEwMFx1MzA2RSd7J25pbGxhYmxlJ30nXHUzMDZGdHJ1ZVx1MzA2N1x1MzA1OVx1MzA0Q1x1MzAwMVx1MzBEOVx1MzBGQ1x1MzBCOVx1MzBGQlx1MzBCRlx1MzBBNFx1MzBEN1x1MzA2RVx1NUJGRVx1NUZEQ1x1MzA1OVx1MzA4Qlx1MzBEMVx1MzBGQ1x1MzBDNlx1MzBBM1x1MzBBRlx1MzBFQlx1MzA2Qlx1MzA2Rid7J25pbGxhYmxlJ30nXHUzMDRDZmFsc2VcdTMwNkVcdTg5ODFcdTdEMjBcdTVCQTNcdThBMDBcdTMwNENcdTU0MkJcdTMwN0VcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTlcdTMwMDIKLSAgICAgICAgcmNhc2UtTmFtZUFuZFR5cGVPSy4zID0gcmNhc2UtTmFtZUFuZFR5cGVPSy4zOiAneyd0ZXJtJ30nXHUzMDRDXHU4OTgxXHU3RDIwXHU1QkEzXHU4QTAwJyd7MH0nJ1x1MzA2N1x1MzA0Mlx1MzA4Qlx1MzBEMVx1MzBGQ1x1MzBDNlx1MzBBM1x1MzBBRlx1MzBFQlx1MzA2RVx1MzBBOFx1MzBFOVx1MzBGQ1x1MzAwMlx1NTFGQVx1NzNGRVx1N0JDNFx1NTZGMih7MX0sezJ9KVx1MzA2Rlx1MzAwMVx1MzBEOVx1MzBGQ1x1MzBCOVx1MzBGQlx1MzBCRlx1MzBBNFx1MzBEN1x1MzA2RVx1NUJGRVx1NUZEQ1x1MzA1OVx1MzA4Qlx1MzBEMVx1MzBGQ1x1MzBDNlx1MzBBM1x1MzBBRlx1MzBFQlx1MzA2RVx1N0JDNFx1NTZGMih7M30sezR9XHUzMDZFXHU2NzA5XHU1MkI5XHUzMDZBXHU1MjM2XHU5NjUwXHUzMDY3XHUzMDZGXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0gICAgICAgIHJjYXNlLU5hbWVBbmRUeXBlT0suNC5hID0gcmNhc2UtTmFtZUFuZFR5cGVPSy40LmE6IFx1ODk4MVx1N0QyMCcnezB9JydcdTMwNkZcdTU2RkFcdTVCOUFcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTNcdTMwNENcdTMwMDFcdTMwRDlcdTMwRkNcdTMwQjlcdTMwRkJcdTMwQkZcdTMwQTRcdTMwRDdcdTMwNkVcdTVCRkVcdTVGRENcdTMwNTlcdTMwOEJcdTg5ODFcdTdEMjBcdTMwNkZcdTUwMjQnJ3sxfScnXHUzMDY3XHU1NkZBXHU1QjlBXHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIHJjYXNlLU5hbWVBbmRUeXBlT0suNC5iID0gcmNhc2UtTmFtZUFuZFR5cGVPSy40LmI6IFx1ODk4MVx1N0QyMCcnezB9JydcdTMwNkZcdTUwMjQnJ3sxfScnXHUzMDY3XHU1NkZBXHU1QjlBXHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5XHUzMDRDXHUzMDAxXHUzMEQ5XHUzMEZDXHUzMEI5XHUzMEZCXHUzMEJGXHUzMEE0XHUzMEQ3XHUzMDZFXHU1QkZFXHU1RkRDXHUzMDU5XHUzMDhCXHU4OTgxXHU3RDIwXHUzMDZGXHU1MDI0Jyd7Mn0nJ1x1MzA2N1x1NTZGQVx1NUI5QVx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICByY2FzZS1OYW1lQW5kVHlwZU9LLjUgPSByY2FzZS1OYW1lQW5kVHlwZU9LLjU6IFx1ODk4MVx1N0QyMCcnezB9JydcdTMwNkVcdTMwQTJcdTMwQTRcdTMwQzdcdTMwRjNcdTMwQzZcdTMwQTNcdTMwQzZcdTMwQTNcdTUyMzZcdTdEMDRcdTMwNENcdTMwRDlcdTMwRkNcdTMwQjlcdTMwNkVcdTMwQTJcdTMwQTRcdTMwQzdcdTMwRjNcdTMwQzZcdTMwQTNcdTMwQzZcdTMwQTNcdTUyMzZcdTdEMDRcdTMwNkVcdTMwQjVcdTMwRDZcdTMwQkJcdTMwQzNcdTMwQzhcdTMwNjdcdTMwNkZcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLSAgICAgICAgcmNhc2UtTmFtZUFuZFR5cGVPSy42ID0gcmNhc2UtTmFtZUFuZFR5cGVPSy42OiBcdTg5ODFcdTdEMjAnJ3swfScnXHUzMDZFZGlzYWxsb3dlZCBzdWJzdGl0dXRpb25zXHUzMDZGXHUzMEQ5XHUzMEZDXHUzMEI5XHUzMDZFZGlzYWxsb3dlZCBzdWJzdGl0dXRpb25zXHUzMDZFXHUzMEI5XHUzMEZDXHUzMEQxXHUzMEZDXHUzMEJCXHUzMEMzXHUzMEM4XHUzMDY3XHUzMDZGXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0gICAgICAgIHJjYXNlLU5hbWVBbmRUeXBlT0suNyA9IHJjYXNlLU5hbWVBbmRUeXBlT0suNzogXHU4OTgxXHU3RDIwJyd7MH0nJ1x1MzA2RVx1MzBCRlx1MzBBNFx1MzBENycnezF9JydcdTMwNkZcdTMwMDFcdTMwRDlcdTMwRkNcdTMwQjlcdTg5ODFcdTdEMjBcdTMwNkVcdTMwQkZcdTMwQTRcdTMwRDcnJ3syfScnXHUzMDRCXHUzMDg5XHU1QzBFXHU1MUZBXHUzMDU1XHUzMDhDXHUzMDVGXHUzMDgyXHUzMDZFXHUzMDY3XHUzMDZGXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0gICAgICAgIHJjYXNlLU5TQ29tcGF0LjEgPSByY2FzZS1OU0NvbXBhdC4xOiBcdTg5ODFcdTdEMjAnJ3swfScnXHUzMDZCXHUzMDAxXHUzMEQ5XHUzMEZDXHUzMEI5XHUzMDZFXHUzMEVGXHUzMEE0XHUzMEVCXHUzMEM5XHUzMEFCXHUzMEZDXHUzMEM5XHUzMDY3XHU4QTMxXHU1M0VGXHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDZBXHUzMDQ0XHUzMENEXHUzMEZDXHUzMEUwXHUzMEI5XHUzMERBXHUzMEZDXHUzMEI5Jyd7MX0nJ1x1MzA0Q1x1NTQyQlx1MzA3RVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICByY2FzZS1OU0NvbXBhdC4yID0gcmNhc2UtTlNDb21wYXQuMjogJ3sndGVybSd9J1x1MzA0Q1x1ODk4MVx1N0QyMFx1NUJBM1x1OEEwMCcnezB9JydcdTMwNjdcdTMwNDJcdTMwOEJcdTMwRDFcdTMwRkNcdTMwQzZcdTMwQTNcdTMwQUZcdTMwRUJcdTMwNkVcdTMwQThcdTMwRTlcdTMwRkNcdTMwMDJcdTUxRkFcdTczRkVcdTdCQzRcdTU2RjIoezF9LHsyfSlcdTMwNkZcdTMwMDFcdTMwRDlcdTMwRkNcdTMwQjlcdTMwRkJcdTMwQkZcdTMwQTRcdTMwRDdcdTMwNkVcdTVCRkVcdTVGRENcdTMwNTlcdTMwOEJcdTMwRDFcdTMwRkNcdTMwQzZcdTMwQTNcdTMwQUZcdTMwRUJcdTMwNkVcdTdCQzRcdTU2RjIoezN9LHs0fVx1MzA2RVx1NjcwOVx1NTJCOVx1MzA2QVx1NTIzNlx1OTY1MFx1MzA2N1x1MzA2Rlx1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotICAgICAgICByY2FzZS1OU1JlY3Vyc2VDaGVja0NhcmRpbmFsaXR5LjEgPSByY2FzZS1OU1JlY3Vyc2VDaGVja0NhcmRpbmFsaXR5LjE6IFx1MzBEMVx1MzBGQ1x1MzBDNlx1MzBBM1x1MzBBRlx1MzBFQlx1OTU5M1x1MzA2Qlx1NUI4Q1x1NTE2OFx1MzA2QVx1NkE1Rlx1ODBGRFx1MzBERVx1MzBDM1x1MzBENFx1MzBGM1x1MzBCMFx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotICAgICAgICByY2FzZS1OU1JlY3Vyc2VDaGVja0NhcmRpbmFsaXR5LjIgPSByY2FzZS1OU1JlY3Vyc2VDaGVja0NhcmRpbmFsaXR5LjI6IFx1MzBCMFx1MzBFQlx1MzBGQ1x1MzBEN1x1MzA2RVx1NTFGQVx1NzNGRVx1N0JDNFx1NTZGMih7MH0sezF9KVx1MzA0Q1x1MzBEOVx1MzBGQ1x1MzBCOVx1MzA2RVx1MzBFRlx1MzBBNFx1MzBFQlx1MzBDOVx1MzBBQlx1MzBGQ1x1MzBDOVx1MzA2RVx1N0JDNFx1NTZGMih7Mn0sezN9KVx1MzA2RVx1NjcwOVx1NTJCOVx1MzA2QVx1NTIzNlx1OTY1MFx1MzA2N1x1MzA2Rlx1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotICAgICAgICByY2FzZS1OU1N1YnNldC4xID0gcmNhc2UtTlNTdWJzZXQuMTogXHUzMEVGXHUzMEE0XHUzMEVCXHUzMEM5XHUzMEFCXHUzMEZDXHUzMEM5XHUzMDRDXHUzMDAxXHUzMEQ5XHUzMEZDXHUzMEI5XHUzMDZFXHU1QkZFXHU1RkRDXHUzMDU5XHUzMDhCXHUzMEVGXHUzMEE0XHUzMEVCXHUzMEM5XHUzMEFCXHUzMEZDXHUzMEM5XHUzMDZFXHUzMEI1XHUzMEQ2XHUzMEJCXHUzMEMzXHUzMEM4XHUzMDY3XHUzMDZGXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0gICAgICAgIHJjYXNlLU5TU3Vic2V0LjIgPSByY2FzZS1OU1N1YnNldC4yOiBcdTMwRUZcdTMwQTRcdTMwRUJcdTMwQzlcdTMwQUJcdTMwRkNcdTMwQzlcdTMwNkVcdTUxRkFcdTczRkVcdTdCQzRcdTU2RjIoezB9LHsxfSlcdTMwNkZcdTMwMDFcdTMwRDlcdTMwRkNcdTMwQjlcdTMwNkVcdTMwRUZcdTMwQTRcdTMwRUJcdTMwQzlcdTMwQUJcdTMwRkNcdTMwQzlcdTMwNkVcdTUxRkFcdTczRkVcdTdCQzRcdTU2RjIoezJ9LHszfSlcdTMwNkVcdTY3MDlcdTUyQjlcdTMwNkFcdTUyMzZcdTk2NTBcdTMwNjdcdTMwNkZcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLSAgICAgICAgcmNhc2UtTlNTdWJzZXQuMyA9IHJjYXNlLU5TU3Vic2V0LjM6IFx1MzBFRlx1MzBBNFx1MzBFQlx1MzBDOVx1MzBBQlx1MzBGQ1x1MzBDOVx1MzA2RVx1MzBEN1x1MzBFRFx1MzBCQlx1MzBCOVx1MzBGQlx1MzBCM1x1MzBGM1x1MzBDNlx1MzBGM1x1MzBDNCcnezB9JydcdTMwNENcdTMwMDFcdTMwRDlcdTMwRkNcdTMwQjlcdTMwNkVcdTMwODJcdTMwNkUnJ3sxfScnXHUzMDg4XHUzMDhBXHU1RjMxXHUzMDRGXHUzMDZBXHUzMDYzXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIHJjYXNlLVJlY3Vyc2UuMSA9IHJjYXNlLVJlY3Vyc2UuMTogXHUzMEIwXHUzMEVCXHUzMEZDXHUzMEQ3XHUzMDZFXHU1MUZBXHU3M0ZFXHU3QkM0XHU1NkYyKHswfSx7MX0pXHUzMDRDXHUzMEQ5XHUzMEZDXHUzMEI5XHUzMEZCXHUzMEIwXHUzMEVCXHUzMEZDXHUzMEQ3XHUzMDZFXHU1MUZBXHU3M0ZFXHU3QkM0XHU1NkYyKHsyfSx7M30pXHUzMDZFXHU2NzA5XHU1MkI5XHUzMDZBXHU1MjM2XHU5NjUwXHUzMDY3XHUzMDZGXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0gICAgICAgIHJjYXNlLVJlY3Vyc2UuMiA9IHJjYXNlLVJlY3Vyc2UuMjogXHUzMEQxXHUzMEZDXHUzMEM2XHUzMEEzXHUzMEFGXHUzMEVCXHU5NTkzXHUzMDZCXHU1QjhDXHU1MTY4XHUzMDZBXHU2QTVGXHU4MEZEXHUzMERFXHUzMEMzXHUzMEQ0XHUzMEYzXHUzMEIwXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0gICAgICAgIHJjYXNlLVJlY3Vyc2VMYXguMSA9IHJjYXNlLVJlY3Vyc2VMYXguMTogXHUzMEIwXHUzMEVCXHUzMEZDXHUzMEQ3XHUzMDZFXHU1MUZBXHU3M0ZFXHU3QkM0XHU1NkYyKHswfSx7MX0pXHUzMDRDXHUzMEQ5XHUzMEZDXHUzMEI5XHUzMEZCXHUzMEIwXHUzMEVCXHUzMEZDXHUzMEQ3XHUzMDZFXHU1MUZBXHU3M0ZFXHU3QkM0XHU1NkYyKHsyfSx7M30pXHUzMDZFXHU2NzA5XHU1MkI5XHUzMDZBXHU1MjM2XHU5NjUwXHUzMDY3XHUzMDZGXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0gICAgICAgIHJjYXNlLVJlY3Vyc2VMYXguMiA9IHJjYXNlLVJlY3Vyc2VMYXguMjogXHUzMEQxXHUzMEZDXHUzMEM2XHUzMEEzXHUzMEFGXHUzMEVCXHU5NTkzXHUzMDZCXHU1QjhDXHU1MTY4XHUzMDZBXHU2QTVGXHU4MEZEXHUzMERFXHUzMEMzXHUzMEQ0XHUzMEYzXHUzMEIwXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0gICAgICAgIHJjYXNlLVJlY3Vyc2VVbm9yZGVyZWQuMSA9IHJjYXNlLVJlY3Vyc2VVbm9yZGVyZWQuMTogXHUzMEIwXHUzMEVCXHUzMEZDXHUzMEQ3XHUzMDZFXHU1MUZBXHU3M0ZFXHU3QkM0XHU1NkYyKHswfSx7MX0pXHUzMDRDXHUzMEQ5XHUzMEZDXHUzMEI5XHUzMEZCXHUzMEIwXHUzMEVCXHUzMEZDXHUzMEQ3XHUzMDZFXHU1MUZBXHU3M0ZFXHU3QkM0XHU1NkYyKHsyfSx7M30pXHUzMDZFXHU2NzA5XHU1MkI5XHUzMDZBXHU1MjM2XHU5NjUwXHUzMDY3XHUzMDZGXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0gICAgICAgIHJjYXNlLVJlY3Vyc2VVbm9yZGVyZWQuMiA9IHJjYXNlLVJlY3Vyc2VVbm9yZGVyZWQuMjogXHUzMEQxXHUzMEZDXHUzMEM2XHUzMEEzXHUzMEFGXHUzMEVCXHU5NTkzXHUzMDZCXHU1QjhDXHU1MTY4XHUzMDZBXHU2QTVGXHU4MEZEXHUzMERFXHUzMEMzXHUzMEQ0XHUzMEYzXHUzMEIwXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0jICAgICAgICBXZSdyZSB1c2luZyBzY2gtcHJvcHMtY29ycmVjdC4yIGluc3RlYWQgb2YgdGhlIG9sZCBzcmMtcmVkZWZpbmUuMQotIyAgICAgICAgc3JjLXJlZGVmaW5lLjEgPSBzcmMtcmVkZWZpbmUuMTogVGhlIGNvbXBvbmVudCAnJ3swfScnIGlzIGJlZ2luIHJlZGVmaW5lZCwgYnV0IGl0cyBjb3JyZXNwb25kaW5nIGNvbXBvbmVudCBpc24ndCBpbiB0aGUgc2NoZW1hIGRvY3VtZW50IGJlaW5nIHJlZGVmaW5lZCAod2l0aCBuYW1lc3BhY2UgJyd7Mn0nJyksIGJ1dCBpbiBhIGRpZmZlcmVudCBkb2N1bWVudCwgd2l0aCBuYW1lc3BhY2UgJyd7MX0nJy4KLSAgICAgICAgc2NoLXByb3BzLWNvcnJlY3QuMiA9IHNjaC1wcm9wcy1jb3JyZWN0LjI6IFx1MzBCOVx1MzBBRFx1MzBGQ1x1MzBERVx1MzA2Qlx1MzA2Rlx1NTQwQ1x1MzA1OFx1NTQwRFx1NTI0RFx1MzA5Mlx1NjMwMVx1MzA2NDJcdTMwNjRcdTMwNkVcdTMwQjBcdTMwRURcdTMwRkNcdTMwRDBcdTMwRUJcdTMwRkJcdTMwQjNcdTMwRjNcdTMwRERcdTMwRkNcdTMwQ0RcdTMwRjNcdTMwQzhcdTMwOTJcdTU0MkJcdTMwODFcdTMwOEJcdTMwNTNcdTMwNjhcdTMwNkZcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDJcdTMwNTNcdTMwNkVcdTMwQjlcdTMwQURcdTMwRkNcdTMwREVcdTMwNkJcdTMwNkYnJ3swfScnXHUzMDRDMlx1MzA2NFx1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBzdC1wcm9wcy1jb3JyZWN0LjIgPSBzdC1wcm9wcy1jb3JyZWN0LjI6IFx1NTM1OFx1N0QxNFx1NTc4QicnezB9JydcdTMwNjdcdTVGQUFcdTc0QjBcdTVCOUFcdTdGQTlcdTMwNENcdTY5MUNcdTUxRkFcdTMwNTVcdTMwOENcdTMwN0VcdTMwNTdcdTMwNUZcdTMwMDJcdTMwNjRcdTMwN0VcdTMwOEFcdTMwMDEnJ3swfScnXHUzMDRDXHUzMDVEXHUzMDhDXHU4MUVBXHU0RjUzXHUzMDZFXHUzMEJGXHUzMEE0XHUzMEQ3XHU5NjhFXHU1QzY0XHUzMDZCXHU1NDJCXHUzMDdFXHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDhCXHUzMDVGXHUzMDgxXHUzMEE4XHUzMEU5XHUzMEZDXHUzMDZCXHUzMDZBXHUzMDYzXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIHN0LXByb3BzLWNvcnJlY3QuMyA9IHN0LXByb3BzLWNvcnJlY3QuMzogXHUzMEJGXHUzMEE0XHUzMEQ3Jyd7MH0nJ1x1MzA2RVx1MzBBOFx1MzBFOVx1MzBGQ1x1MzAwMid7J2Jhc2UgdHlwZSBkZWZpbml0aW9uJ30nXHUzMDZFJ3snZmluYWwnfSdcdTMwNkVcdTUwMjQnJ3sxfScnXHUzMDZGXHUzMDAxXHU1MjM2XHU5NjUwXHUzMDZCXHUzMDg4XHUzMDYzXHUzMDY2XHU1QzBFXHU1MUZBXHUzMDkyXHU3OTgxXHU2QjYyXHUzMDU3XHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIHRvdGFsRGlnaXRzLXZhbGlkLXJlc3RyaWN0aW9uID0gdG90YWxEaWdpdHMtdmFsaWQtcmVzdHJpY3Rpb246IFx1MzBENVx1MzBBMVx1MzBCQlx1MzBDM1x1MzBDOCcndG90YWxEaWdpdHMnJ1x1MzA2RVx1NTAyNCcnezB9JydcdTMwNkZcdTMwMDFcdTc5NTZcdTUxNDhcdTMwQkZcdTMwQTRcdTMwRDdcdTMwNkVcdTMwNDRcdTMwNUFcdTMwOENcdTMwNEJcdTMwNjcnJ3sxfScnXHUzMDZCXHU4QTJEXHU1QjlBXHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDhCJyd0b3RhbERpZ2l0cycnXHUzMDZFXHU1MDI0XHU0RUU1XHU0RTBCXHUzMDY3XHUzMDQyXHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhCXHUzMDVGXHUzMDgxXHUzMDAxezJ9XHUzMDZFXHU1QjlBXHU3RkE5XHUzMDY3XHUzMDZGXHU3MTIxXHU1MkI5XHUzMDY3XHUzMDU5XHUzMDAyCi0gICAgICAgIHdoaXRlU3BhY2UtdmFsaWQtcmVzdHJpY3Rpb24uMSA9IHdoaXRlU3BhY2UtdmFsaWQtcmVzdHJpY3Rpb24uMTogXHU3OTU2XHU1MTQ4XHUzMEJGXHUzMEE0XHUzMEQ3XHUzMDZFXHUzMDQ0XHUzMDVBXHUzMDhDXHUzMDRCXHUzMDY3Jyd3aGl0ZXNwYWNlJydcdTMwNkVcdTUwMjRcdTMwNEMnJ2NvbGxhcHNlJydcdTMwNkJcdThBMkRcdTVCOUFcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwOEJcdTMwNUZcdTMwODFcdTMwMDF7MH1cdTMwNkVcdTVCOUFcdTdGQTlcdTMwNjdcdTMwNkZcdTMwRDVcdTMwQTFcdTMwQkJcdTMwQzNcdTMwQzgnJ3doaXRlc3BhY2UnJ1x1MzA2RVx1NTAyNCcnezF9JydcdTMwNkZcdTcxMjFcdTUyQjlcdTMwNjdcdTMwNTlcdTMwMDIKLSAgICAgICAgd2hpdGVTcGFjZS12YWxpZC1yZXN0cmljdGlvbi4yID0gd2hpdGVTcGFjZS12YWxpZC1yZXN0cmljdGlvbi4yOiBcdTc5NTZcdTUxNDhcdTMwQkZcdTMwQTRcdTMwRDdcdTMwNkVcdTMwNDRcdTMwNUFcdTMwOENcdTMwNEJcdTMwNjcnJ3doaXRlc3BhY2UnJ1x1MzA2RVx1NTAyNFx1MzA0QycncmVwbGFjZScnXHUzMDZCXHU4QTJEXHU1QjlBXHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDhCXHUzMDVGXHUzMDgxXHUzMDAxezB9XHUzMDZFXHU1QjlBXHU3RkE5XHUzMDY3XHUzMDZGXHUzMEQ1XHUzMEExXHUzMEJCXHUzMEMzXHUzMEM4Jyd3aGl0ZXNwYWNlJydcdTMwNkVcdTUwMjQnJ3ByZXNlcnZlJydcdTMwNkZcdTcxMjFcdTUyQjlcdTMwNjdcdTMwNTlcdTMwMDIKLQotI3NjaGVtYSBmb3IgU2NoZW1hcwotCi0gICAgICAgIHM0cy1hdHQtaW52YWxpZC12YWx1ZSA9IHM0cy1hdHQtaW52YWxpZC12YWx1ZTogXHU4OTgxXHU3RDIwJyd7MH0nJ1x1MzA2RScnezF9JydcdTMwNkVcdTVDNUVcdTYwMjdcdTUwMjRcdTMwNENcdTcxMjFcdTUyQjlcdTMwNjdcdTMwNTlcdTMwMDJcdThBMThcdTkzMzJcdTMwNTVcdTMwOENcdTMwNUZcdTc0MDZcdTc1MzE6IHsyfQotICAgICAgICBzNHMtYXR0LW11c3QtYXBwZWFyID0gczRzLWF0dC1tdXN0LWFwcGVhcjogXHU4OTgxXHU3RDIwJyd7MH0nJ1x1MzA2Qlx1NUM1RVx1NjAyNycnezF9JydcdTMwOTJcdTU0MkJcdTMwODFcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIKLSAgICAgICAgczRzLWF0dC1ub3QtYWxsb3dlZCA9IHM0cy1hdHQtbm90LWFsbG93ZWQ6IFx1ODk4MVx1N0QyMCcnezB9JydcdTMwNkJcdTVDNUVcdTYwMjcnJ3sxfScnXHUzMDkyXHU1NDJCXHUzMDgxXHUzMDhCXHUzMDUzXHUzMDY4XHUzMDZGXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0gICAgICAgIHM0cy1lbHQtaW52YWxpZCA9IHM0cy1lbHQtaW52YWxpZDogXHU4OTgxXHU3RDIwJyd7MH0nJ1x1MzA2Rlx1MzBCOVx1MzBBRFx1MzBGQ1x1MzBERVx1MzBGQlx1MzBDOVx1MzBBRFx1MzBFNVx1MzBFMVx1MzBGM1x1MzBDOFx1MzA2RVx1NjcwOVx1NTJCOVx1MzA2QVx1ODk4MVx1N0QyMFx1MzA2N1x1MzA2Rlx1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotICAgICAgICBzNHMtZWx0LW11c3QtbWF0Y2guMSA9IHM0cy1lbHQtbXVzdC1tYXRjaC4xOiAnJ3swfScnXHUzMDZFXHUzMEIzXHUzMEYzXHUzMEM2XHUzMEYzXHUzMEM0XHUzMDZGezF9XHUzMDY4XHU0RTAwXHU4MUY0XHUzMDU5XHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyezJ9XHU0RUU1XHU5NjREXHUzMDZCXHU1NTRGXHU5ODRDXHUzMDRDXHU4OThCXHUzMDY0XHUzMDRCXHUzMDhBXHUzMDdFXHUzMDU3XHUzMDVGXHUzMDAyCi0gICAgICAgIHM0cy1lbHQtbXVzdC1tYXRjaC4yID0gczRzLWVsdC1tdXN0LW1hdGNoLjI6ICcnezB9JydcdTMwNkVcdTMwQjNcdTMwRjNcdTMwQzZcdTMwRjNcdTMwQzRcdTMwNkZ7MX1cdTMwNjhcdTRFMDBcdTgxRjRcdTMwNTlcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDJcdTUzNDFcdTUyMDZcdTMwNkFcdTg5ODFcdTdEMjBcdTMwNENcdTg5OEJcdTMwNjRcdTMwNEJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwNjdcdTMwNTdcdTMwNUZcdTMwMDIKLSAgICAgICAgIyB0aGUgImludmFsaWQtY29udGVudCIgbWVzc2FnZXMgcHJvdmlkZSBsZXNzIGluZm9ybWF0aW9uIHRoYW4gdGhlICJtdXN0LW1hdGNoIiBjb3VudGVycGFydHMgYWJvdmUuIFRoZXkncmUgdXNlZCBmb3IgY29tcGxleCB0eXBlcyB3aGVuIHByb3ZpZGluZyBhICJtYXRjaCIgd291bGQgYmUgYW4gaW5mb3JtYXRpb24gZHVtcAotICAgICAgICBzNHMtZWx0LWludmFsaWQtY29udGVudC4xID0gczRzLWVsdC1pbnZhbGlkLWNvbnRlbnQuMTogJyd7MH0nJ1x1MzA2RVx1MzBCM1x1MzBGM1x1MzBDNlx1MzBGM1x1MzBDNFx1MzA2Rlx1NzEyMVx1NTJCOVx1MzA2N1x1MzA1OVx1MzAwMlx1ODk4MVx1N0QyMCcnezF9JydcdTMwNENcdTcxMjFcdTUyQjlcdTMwNEJcdTMwMDFcdTRGNERcdTdGNkVcdTMwNENcdTZCNjNcdTMwNTdcdTMwNEZcdTMwNkFcdTMwNDRcdTMwNEJcdTMwMDFcdTUxRkFcdTczRkVcdTk4M0JcdTVFQTZcdTMwNENcdTlBRDhcdTMwNTlcdTMwNEVcdTMwN0VcdTMwNTlcdTMwMDIKLSAgICAgICAgczRzLWVsdC1pbnZhbGlkLWNvbnRlbnQuMiA9IHM0cy1lbHQtaW52YWxpZC1jb250ZW50LjI6ICcnezB9JydcdTMwNkVcdTMwQjNcdTMwRjNcdTMwQzZcdTMwRjNcdTMwQzRcdTMwNkZcdTcxMjFcdTUyQjlcdTMwNjdcdTMwNTlcdTMwMDJcdTg5ODFcdTdEMjAnJ3sxfScnXHUzMDZGXHU3QTdBXHUzMDZCXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0gICAgICAgIHM0cy1lbHQtaW52YWxpZC1jb250ZW50LjMgPSBzNHMtZWx0LWludmFsaWQtY29udGVudC4zOiBcdTMwQkZcdTMwQTRcdTMwRDcnJ3swfScnXHUzMDZFXHU4OTgxXHU3RDIwXHUzMDZGXHUzMDAxXHU1QkEzXHU4QTAwXHUzMDZFXHU1RjhDXHUzMDZCPHNjaGVtYT5cdTg5ODFcdTdEMjBcdTMwNkVcdTVCNTBcdTMwNjhcdTMwNTdcdTMwNjZcdTU0MkJcdTMwODFcdTMwOEJcdTMwNTNcdTMwNjhcdTMwNkZcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLSAgICAgICAgczRzLWVsdC1zY2hlbWEtbnMgPSBzNHMtZWx0LXNjaGVtYS1uczogXHU4OTgxXHU3RDIwJyd7MH0nJ1x1MzA2RVx1MzBDRFx1MzBGQ1x1MzBFMFx1MzBCOVx1MzBEQVx1MzBGQ1x1MzBCOVx1MzA2Rlx1MzBCOVx1MzBBRFx1MzBGQ1x1MzBERVx1MzA2RVx1MzBDRFx1MzBGQ1x1MzBFMFx1MzBCOVx1MzBEQVx1MzBGQ1x1MzBCOScnaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEnJ1x1MzA0Qlx1MzA4OVx1MzA2RVx1MzA4Mlx1MzA2RVx1MzA2N1x1MzA0Mlx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBzNHMtZWx0LWNoYXJhY3RlciA9IHM0cy1lbHQtY2hhcmFjdGVyOiAnJ3hzOmFwcGluZm8nJ1x1MzA2OCcneHM6ZG9jdW1lbnRhdGlvbicnXHU0RUU1XHU1OTE2XHUzMDZFXHUzMEI5XHUzMEFEXHUzMEZDXHUzMERFXHU4OTgxXHU3RDIwXHUzMDY3XHUzMDZGXHU5NzVFXHU3QTdBXHU3NjdEXHU2NTg3XHU1QjU3XHUzMDZGXHU4QTMxXHU1M0VGXHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyJyd7MH0nJ1x1MzA0Q1x1ODk4Qlx1MzA2NFx1MzA0Qlx1MzA4QVx1MzA3RVx1MzA1N1x1MzA1Rlx1MzAwMgotCi0jIGNvZGVzIG5vdCBkZWZpbmVkIGJ5IHRoZSBzcGVjCi0KLSAgICAgICAgYy1maWVsZHMteHBhdGhzID0gYy1maWVsZHMteHBhdGhzOiBmaWVsZFx1MzA2RVx1NTAyNCcnezB9JydcdTMwNENcdTcxMjFcdTUyQjlcdTMwNjdcdTMwNTlcdTMwMDIKLSAgICAgICAgYy1nZW5lcmFsLXhwYXRoID0gYy1nZW5lcmFsLXhwYXRoOiBcdTVGMEYnJ3swfScnXHUzMDZGXHUzMDAxWE1MXHUzMEI5XHUzMEFEXHUzMEZDXHUzMERFXHUzMDY3XHUzMEI1XHUzMEREXHUzMEZDXHUzMEM4XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDhCWFBhdGhcdTMwQjVcdTMwRDZcdTMwQkJcdTMwQzNcdTMwQzhcdTMwNkJcdTVCRkVcdTMwNTdcdTMwNjZcdTcxMjFcdTUyQjlcdTMwNjdcdTMwNTlcdTMwMDIKLSAgICAgICAgYy1nZW5lcmFsLXhwYXRoLW5zID0gYy1nZW5lcmFsLXhwYXRoLW5zOiBYUGF0aFx1NUYwRicnezB9JydcdTMwNkVcdTMwQ0RcdTMwRkNcdTMwRTBcdTMwQjlcdTMwREFcdTMwRkNcdTMwQjlcdTMwNkVcdTYzQTVcdTk4MkRcdThGOUVcdTMwNENcdTMwQ0RcdTMwRkNcdTMwRTBcdTMwQjlcdTMwREFcdTMwRkNcdTMwQjlcdTMwNkJcdTMwRDBcdTMwQTRcdTMwRjNcdTMwQzlcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTNcdTMwNjdcdTMwNTdcdTMwNUZcdTMwMDIKLSAgICAgICAgYy1zZWxlY3Rvci14cGF0aCA9IGMtc2VsZWN0b3IteHBhdGg6IHNlbGVjdG9yXHUzMDZFXHU1MDI0Jyd7MH0nJ1x1MzA2Rlx1NzEyMVx1NTJCOVx1MzA2N1x1MzA1OVx1MzAwMnNlbGVjdG9yXHUzMDZFWFBhdGhcdTMwNkJcdTMwNkZcdTVDNUVcdTYwMjdcdTMwOTJcdTU0MkJcdTMwODFcdTMwOEJcdTMwNTNcdTMwNjhcdTMwNkZcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLSAgICAgICAgRW1wdHlUYXJnZXROYW1lc3BhY2UgPSBFbXB0eVRhcmdldE5hbWVzcGFjZTogXHUzMEI5XHUzMEFEXHUzMEZDXHUzMERFXHUzMEZCXHUzMEM5XHUzMEFEXHUzMEU1XHUzMEUxXHUzMEYzXHUzMEM4Jyd7MH0nJ1x1MzA2N1x1MzA2Rlx1MzAwMScndGFyZ2V0TmFtZXNwYWNlJydcdTVDNUVcdTYwMjdcdTMwNkVcdTUwMjRcdTMwOTJcdTdBN0FcdTMwNkVcdTY1ODdcdTVCNTdcdTUyMTdcdTMwNkJcdTMwNTlcdTMwOEJcdTMwNTNcdTMwNjhcdTMwNkZcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLSAgICAgICAgRmFjZXRWYWx1ZUZyb21CYXNlID0gRmFjZXRWYWx1ZUZyb21CYXNlOiBcdTMwQkZcdTMwQTRcdTMwRDcnJ3swfScnXHUzMDZFXHU1QkEzXHU4QTAwXHUzMDY3XHUzMDZGXHUzMDAxXHUzMEQ1XHUzMEExXHUzMEJCXHUzMEMzXHUzMEM4Jyd7Mn0nJ1x1MzA2RVx1NTAyNCcnezF9JydcdTMwNkZcdTMwRDlcdTMwRkNcdTMwQjlcdTMwRkJcdTMwQkZcdTMwQTRcdTMwRDcnJ3szfScnXHUzMDZFXHU1MDI0XHU3QTdBXHU5NTkzXHUzMDRCXHUzMDg5XHUzMDZFXHUzMDgyXHUzMDZFXHUzMDY3XHUzMDQyXHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIEZpeGVkRmFjZXRWYWx1ZSA9IEZpeGVkRmFjZXRWYWx1ZTogezN9XHUzMDZFXHU1QjlBXHU3RkE5XHUzMDY3XHUzMDZGXHUzMEQ1XHUzMEExXHUzMEJCXHUzMEMzXHUzMEM4Jyd7MH0nJ1x1MzA2RVx1NTAyNCcnezF9JydcdTMwNkZcdTcxMjFcdTUyQjlcdTMwNjdcdTMwNTlcdTMwMDJcdTMwNTNcdTMwOENcdTMwNkZcdTMwMDEnJ3swfScnXHUzMDZFXHU1MDI0XHUzMDRDXHU3OTU2XHU1MTQ4XHUzMEJGXHUzMEE0XHUzMEQ3XHUzMDZFXHUzMDQ0XHUzMDVBXHUzMDhDXHUzMDRCXHUzMDY3Jyd7Mn0nJ1x1MzA2Qlx1OEEyRFx1NUI5QVx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0QVx1MzA4QVx1MzAwMSd7J2ZpeGVkJ30nID0gdHJ1ZVx1MzA2N1x1MzA0Mlx1MzA4Qlx1MzA1Rlx1MzA4MVx1MzA2N1x1MzA1OVx1MzAwMgotICAgICAgICBJbnZhbGlkUmVnZXggPSBJbnZhbGlkUmVnZXg6IHBhdHRlcm5cdTMwNkVcdTUwMjQnJ3swfScnXHUzMDZGXHU3MTIxXHU1MkI5XHUzMDZBXHU2QjYzXHU4OThGXHU4ODY4XHU3M0ZFXHUzMDY3XHUzMDU5XHUzMDAyXHU1MjE3Jyd7Mn0nJ1x1MzA2NycnezF9JydcdTMwQThcdTMwRTlcdTMwRkNcdTMwNENcdTU4MzFcdTU0NEFcdTMwNTVcdTMwOENcdTMwN0VcdTMwNTdcdTMwNUZcdTMwMDIKLSAgICAgICAgTWF4T2NjdXJMaW1pdCA9IFx1NzNGRVx1NTcyOFx1MzA2RVx1MzBEMVx1MzBGQ1x1MzBCNVx1MzBGQ1x1MzA2RVx1NjlDQlx1NjIxMFx1MzA2N1x1MzA2Rlx1MzAwMW1heE9jY3Vyc1x1NUM1RVx1NjAyN1x1MzA2Qlx1NTAyNHswfVx1MzA4OFx1MzA4QVx1NTkyN1x1MzA0RFx1MzA0NFx1NTAyNFx1MzA5Mlx1OEEyRFx1NUI5QVx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotICAgICAgICBQdWJsaWNTeXN0ZW1Pbk5vdGF0aW9uID0gUHVibGljU3lzdGVtT25Ob3RhdGlvbjogXHU4OTgxXHU3RDIwJydub3RhdGlvbicnXHUzMDZCXHUzMDZGJydwdWJsaWMnJ1x1MzA0QVx1MzA4OFx1MzA3Mycnc3lzdGVtJydcdTMwNkVcdTVDMTFcdTMwNkFcdTMwNEZcdTMwNjhcdTMwODIxXHUzMDY0XHUzMDRDXHU1RkM1XHU4OTgxXHUzMDY3XHUzMDU5XHUzMDAyCi0gICAgICAgIFNjaGVtYUxvY2F0aW9uID0gU2NoZW1hTG9jYXRpb246IHNjaGVtYUxvY2F0aW9uXHUzMDZFXHU1MDI0Jyd7MH0nJ1x1MzA2Qlx1MzA2Rlx1NTA3Nlx1NjU3MFx1NTAwQlx1MzA2RVVSSVx1MzA5Mlx1NjMwN1x1NUI5QVx1MzA1OVx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgotICAgICAgICBUYXJnZXROYW1lc3BhY2UuMSA9IFRhcmdldE5hbWVzcGFjZS4xOiBcdTMwQ0RcdTMwRkNcdTMwRTBcdTMwQjlcdTMwREFcdTMwRkNcdTMwQjknJ3swfScnXHUzMDRDXHU1RkM1XHU4OTgxXHUzMDY3XHUzMDU5XHUzMDRDXHUzMDAxXHUzMEI5XHUzMEFEXHUzMEZDXHUzMERFXHUzMEZCXHUzMEM5XHUzMEFEXHUzMEU1XHUzMEUxXHUzMEYzXHUzMEM4XHUzMDZFXHUzMEJGXHUzMEZDXHUzMEIyXHUzMEMzXHUzMEM4XHUzMEZCXHUzMENEXHUzMEZDXHUzMEUwXHUzMEI5XHUzMERBXHUzMEZDXHUzMEI5XHUzMDZGJyd7MX0nJ1x1MzA2N1x1MzA1OVx1MzAwMgotICAgICAgICBUYXJnZXROYW1lc3BhY2UuMiA9IFRhcmdldE5hbWVzcGFjZS4yOiBcdTMwQ0RcdTMwRkNcdTMwRTBcdTMwQjlcdTMwREFcdTMwRkNcdTMwQjlcdTMwNkZcdTVGQzVcdTg5ODFcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwNENcdTMwMDFcdTMwQjlcdTMwQURcdTMwRkNcdTMwREVcdTMwRkJcdTMwQzlcdTMwQURcdTMwRTVcdTMwRTFcdTMwRjNcdTMwQzhcdTMwNkInJ3sxfScnXHUzMDZFXHUzMEJGXHUzMEZDXHUzMEIyXHUzMEMzXHUzMEM4XHUzMEZCXHUzMENEXHUzMEZDXHUzMEUwXHUzMEI5XHUzMERBXHUzMEZDXHUzMEI5XHUzMDRDXHU1NDJCXHUzMDdFXHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgICAgIFVuZGVjbGFyZWRFbnRpdHkgPSBVbmRlY2xhcmVkRW50aXR5OiBcdTMwQThcdTMwRjNcdTMwQzZcdTMwQTNcdTMwQzZcdTMwQTMnJ3swfScnXHUzMDRDXHU1QkEzXHU4QTAwXHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0gICAgICAgIFVuZGVjbGFyZWRQcmVmaXggPSBVbmRlY2xhcmVkUHJlZml4OiAnJ3swfScnXHUzMDkyUU5hbWVcdTMwNjhcdTMwNTdcdTMwNjZcdTg5RTNcdTZDN0FcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDJcdTYzQTVcdTk4MkRcdThGOUUnJ3sxfScnXHUzMDRDXHU1QkEzXHU4QTAwXHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9YTUxTY2hlbWFNZXNzYWdlc19rby5wcm9wZXJ0aWVzIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MU2NoZW1hTWVzc2FnZXNfa28ucHJvcGVydGllcwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZmMzYjNkMy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9YTUxTY2hlbWFNZXNzYWdlc19rby5wcm9wZXJ0aWVzCisrKyAvZGV2L251bGwKQEAgLTEsMjkxICswLDAgQEAKLSMgVGhpcyBmaWxlIGNvbnRhaW5zIGVycm9yIGFuZCB3YXJuaW5nIG1lc3NhZ2VzIHJlbGF0ZWQgdG8gWE1MIFNjaGVtYQotIyBUaGUgbWVzc2FnZXMgYXJlIGFycmFuZ2VkIGluIGtleSBhbmQgdmFsdWUgdHVwbGVzIGluIGEgTGlzdFJlc291cmNlQnVuZGxlLgotIwotCi0gICAgICAgIEJhZE1lc3NhZ2VLZXkgPSBcdUJBNTRcdUMyRENcdUM5QzAgXHVEMEE0XHVDNUQwIFx1RDU3NFx1QjJGOVx1RDU1OFx1QjI5NCBcdUM2MjRcdUI5NTggXHVCQTU0XHVDMkRDXHVDOUMwXHVCOTdDIFx1Q0MzRVx1Qzc0NCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LgotICAgICAgICBGb3JtYXRGYWlsZWQgPSBcdUIyRTRcdUM3NEMgXHVCQTU0XHVDMkRDXHVDOUMwXHVDNzU4IFx1RDYxNVx1QzJERFx1Qzc0NCBcdUM5QzBcdUM4MTVcdUQ1NThcdUIyOTQgXHVDOTExIFx1QjBCNFx1QkQ4MCBcdUM2MjRcdUI5NThcdUFDMDAgXHVCQzFDXHVDMEREXHVENTg4XHVDMkI1XHVCMkM4XHVCMkU0LlxuCi0KLSMgRm9yIGludGVybmFsIHVzZQotCi0gICAgICAgIEludGVybmFsLUVycm9yID0gXHVCMEI0XHVCRDgwIFx1QzYyNFx1Qjk1ODogezB9LgotICAgICAgICBkdC13aGl0ZXNwYWNlID0gXHVENTY5XHVDOUQxXHVENTY5IHNpbXBsZVR5cGUgJyd7MH0nJ1x1QzVEMCBcdUIzMDBcdUQ1NUMgXHVBQ0Y1XHVCQzMxIFx1QkE3NCBcdUFDMTJcdUM3NDQgXHVDMEFDXHVDNkE5XHVENTYwIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuCi0gICAgICAgIEdyYW1tYXJDb25mbGljdCA9IFx1QzBBQ1x1QzZBOVx1Qzc5MCBcdUJCMzhcdUJDOTUgXHVENDgwXHVDNUQwXHVDMTFDIFx1QkMxOFx1RDY1OFx1QjQxQyBcdUJCMzhcdUJDOTUgXHVDOTExIFx1RDU1OFx1QjA5OFx1QUMwMCBcdUIyRTRcdUI5NzggXHVCQjM4XHVCQzk1XHVBQ0ZDIFx1Q0RBOVx1QjNDQ1x1RDU2OVx1QjJDOFx1QjJFNC4KLQotIyBJZGVudGl0eSBjb25zdHJhaW50cwotCi0gICAgICAgIEFic2VudEtleVZhbHVlID0gSUQgXHVDODFDXHVDNTdEIFx1Qzg3MFx1QUM3NCBcdUM2MjRcdUI5NTgoY3ZjLWlkZW50aXR5LWNvbnN0cmFpbnQuNC4yLjEpOiAiezB9IiBcdUM2OTRcdUMxOENcdUM1RDAgXHVBQzEyXHVDNzc0IFx1QzVDNlx1QjI5NCBcdUQwQTRcdUFDMDAgXHVDNzg4XHVDMkI1XHVCMkM4XHVCMkU0LgotICAgICAgICBEdXBsaWNhdGVGaWVsZCA9ICJ7MH0iIFx1RDU0NFx1QjREQyBcdUJDOTRcdUM3MDRcdUM1RDAgXHVDOTExXHVCQ0Y1IFx1QzBBQ1x1RDU2RFx1Qzc3NCBcdUM3ODhcdUMyQjVcdUIyQzhcdUIyRTQuCi0gICAgICAgIER1cGxpY2F0ZUtleSA9IFx1QzkxMVx1QkNGNSBcdUQwQTQgXHVBQzEyIFt7MH1dXHVDNzc0KFx1QUMwMCkgInsxfSIgXHVDNjk0XHVDMThDXHVDNzU4IElEIFx1QzgxQ1x1QzU3RCBcdUM4NzBcdUFDNzRcdUM1RDAgXHVCMzAwXHVENTc0IFx1QzEyMFx1QzVCOFx1QjQxOFx1QzVDOFx1QzJCNVx1QjJDOFx1QjJFNC4KLSAgICAgICAgRHVwbGljYXRlVW5pcXVlID0gXHVDOTExXHVCQ0Y1IFx1QUNFMFx1QzcyMCBcdUFDMTIgW3swfV1cdUM3NzQoXHVBQzAwKSAiezF9IiBcdUM2OTRcdUMxOENcdUM3NTggSUQgXHVDODFDXHVDNTdEIFx1Qzg3MFx1QUM3NFx1QzVEMCBcdUIzMDBcdUQ1NzQgXHVDMTIwXHVDNUI4XHVCNDE4XHVDNUM4XHVDMkI1XHVCMkM4XHVCMkU0LgotICAgICAgICBGaWVsZE11bHRpcGxlTWF0Y2ggPSBJRCBcdUM4MUNcdUM1N0QgXHVDODcwXHVBQzc0IFx1QzYyNFx1Qjk1ODogInswfSIgXHVENTQ0XHVCNERDXHVBQzAwIFx1RDU3NFx1QjJGOSBcdUMxMjBcdUQwRERcdUFFMzAgXHVCQzk0XHVDNzA0IFx1QjBCNFx1QzVEMCBcdUQzRUNcdUQ1NjhcdUI0MUMgXHVDNUVDXHVCN0VDIFx1QUMxMlx1QUNGQyBcdUM3N0NcdUNFNThcdUQ1NjlcdUIyQzhcdUIyRTQuIFx1RDU0NFx1QjREQ1x1QjI5NCBcdUFDRTBcdUM3MjAgXHVBQzEyXHVBQ0ZDIFx1Qzc3Q1x1Q0U1OFx1RDU3NFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIEZpeGVkRGlmZmVyc0Zyb21BY3R1YWwgPSBcdUM3NzQgXHVDNjk0XHVDMThDXHVDNzU4IFx1Q0Y1OFx1RDE1MFx1Q0UyMFx1QUMwMCBcdUMyQTRcdUQwQTRcdUI5QzhcdUM3NTggXHVDNjk0XHVDMThDIFx1QzEyMFx1QzVCOFx1QzVEMCBcdUM3ODhcdUIyOTQgImZpeGVkIiBcdUMxOERcdUMxMzFcdUFDMTJcdUFDRkMgXHVDNzdDXHVDRTU4XHVENTU4XHVDOUMwIFx1QzU0QVx1QzJCNVx1QjJDOFx1QjJFNC4KLSAgICAgICAgS2V5TWF0Y2hlc05pbGxhYmxlID0gSUQgXHVDODFDXHVDNTdEIFx1Qzg3MFx1QUM3NCBcdUM2MjRcdUI5NTgoY3ZjLWlkZW50aXR5LWNvbnN0cmFpbnQuNC4yLjMpOiAiezB9IiBcdUM2OTRcdUMxOENcdUM1RDAgbmlsbGFibGVcdUM3NzQgdHJ1ZVx1Qjg1QyBcdUMxMjRcdUM4MTVcdUI0MUMgXHVDNjk0XHVDMThDXHVDNjQwIFx1Qzc3Q1x1Q0U1OFx1RDU1OFx1QjI5NCBcdUQwQTRcdUFDMDAgXHVDNzg4XHVDMkI1XHVCMkM4XHVCMkU0LgotICAgICAgICBLZXlOb3RFbm91Z2hWYWx1ZXMgPSAiezB9IiBcdUM2OTRcdUMxOENcdUM3NTggPGtleSBuYW1lPSJ7MX0iPiBJRCBcdUM4MUNcdUM1N0QgXHVDODcwXHVBQzc0XHVDNUQwIFx1QjMwMFx1RDU3NCBcdUM5QzBcdUM4MTVcdUI0MUMgXHVBQzEyXHVDNzc0IFx1QkQ4MFx1Qzg3MVx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgS2V5Tm90Rm91bmQgPSAnJ3syfScnIFx1QzY5NFx1QzE4Q1x1Qzc1OCBJRCBcdUM4MUNcdUM1N0QgXHVDODcwXHVBQzc0XHVDNUQwIFx1QjMwMFx1RDU3NCBcdUFDMTJcdUM3NzQgJyd7MX0nJ1x1Qzc3OCAnJ3swfScnIFx1RDBBNFx1Qjk3QyBcdUNDM0VcdUM3NDQgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4KLSAgICAgICAgS2V5UmVmTm90RW5vdWdoVmFsdWVzID0gInswfSIgXHVDNjk0XHVDMThDXHVDNzU4IDxrZXlyZWYgbmFtZT0iezF9Ij4gSUQgXHVDODFDXHVDNTdEIFx1Qzg3MFx1QUM3NFx1QzVEMCBcdUIzMDBcdUQ1NzQgXHVDOUMwXHVDODE1XHVCNDFDIFx1QUMxMlx1Qzc3NCBcdUJEODBcdUM4NzFcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIEtleVJlZk91dE9mU2NvcGUgPSBJRCBcdUM4MUNcdUM1N0QgXHVDODcwXHVBQzc0IFx1QzYyNFx1Qjk1ODogSUQgXHVDODFDXHVDNTdEIFx1Qzg3MFx1QUM3NCAiezB9Ilx1Qzc1OCBrZXlyZWZcdUFDMDAgXHVCQzk0XHVDNzA0XHVDNUQwXHVDMTFDIFx1QkM5N1x1QzVCNFx1QjA5QyBcdUQwQTQgXHVCNjEwXHVCMjk0IFx1QUNFMFx1QzcyMCBcdUQ1NkRcdUJBQTlcdUM3NDQgXHVDQzM4XHVDODcwXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBLZXlSZWZSZWZlck5vdEZvdW5kID0gXHVEMEE0IFx1Q0MzOFx1Qzg3MCBcdUMxMjBcdUM1QjggInswfSJcdUM3NDAoXHVCMjk0KSBcdUM3NzRcdUI5ODRcdUM3NzQgInsxfSJcdUM3NzggXHVDNTRDIFx1QzIxOCBcdUM1QzZcdUIyOTQgXHVEMEE0XHVCOTdDIFx1Q0MzOFx1Qzg3MFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgVW5pcXVlTm90RW5vdWdoVmFsdWVzID0gInswfSIgXHVDNjk0XHVDMThDXHVDNzU4IDx1bmlxdWU+IElEIFx1QzgxQ1x1QzU3RCBcdUM4NzBcdUFDNzRcdUM1RDAgXHVCMzAwXHVENTc0IFx1QzlDMFx1QzgxNVx1QjQxQyBcdUFDMTJcdUM3NzQgXHVCRDgwXHVDODcxXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBVbmtub3duRmllbGQgPSBcdUIwQjRcdUJEODAgSUQgXHVDODFDXHVDNTdEIFx1Qzg3MFx1QUM3NCBcdUM2MjRcdUI5NTg6ICJ7MH0iXHVDNzQwKFx1QjI5NCkgXHVDNTRDIFx1QzIxOCBcdUM1QzZcdUIyOTQgXHVENTQ0XHVCNERDXHVDNzg1XHVCMkM4XHVCMkU0LgotCi0jIElkZWFsbHksIHdlIHNob3VsZCBvbmx5IHVzZSB0aGUgZm9sbG93aW5nIGVycm9yIGtleXMsIG5vdCB0aGUgb25lcyB1bmRlcgotIyAiSWRlbnRpdHkgY29uc3RyYWludHMiLiBBbmQgd2Ugc2hvdWxkIGNvdmVyIGFsbCBvZiB0aGUgZm9sbG93aW5nIGVycm9ycy4KLQotI3ZhbGlkYXRpb24gKDMuWC40KQotCi0gICAgICAgIGN2Yy1hdHRyaWJ1dGUuMyA9IGN2Yy1hdHRyaWJ1dGUuMzogJyd7MH0nJyBcdUM2OTRcdUMxOENcdUM3NTggJyd7MX0nJyBcdUMxOERcdUMxMzFcdUM1RDAgXHVCMzAwXHVENTVDICcnezJ9JycgXHVBQzEyXHVDNzc0ICcnezN9JycgXHVDNzIwXHVENjE1XHVDNUQwIFx1QjMwMFx1RDU3NCBcdUJEODBcdUM4MDFcdUQ1NjlcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIGN2Yy1hdHRyaWJ1dGUuNCA9IGN2Yy1hdHRyaWJ1dGUuNDogJyd7MH0nJyBcdUM2OTRcdUMxOENcdUM3NTggJyd7MX0nJyBcdUMxOERcdUMxMzFcdUM1RDAgXHVCMzAwXHVENTVDICcnezJ9JycgXHVBQzEyXHVDNzc0IFx1QUNFMFx1QzgxNVx1QjQxQyAneyd2YWx1ZSBjb25zdHJhaW50J30nXHVDNUQwIFx1QjMwMFx1RDU3NCBcdUJEODBcdUM4MDFcdUQ1NjlcdUQ1NjlcdUIyQzhcdUIyRTQuIFx1QzE4RFx1QzEzMVx1Qzc1OCBcdUFDMTJcdUM3NDAgJyd7M30nJ1x1Qzc3NFx1QzVCNFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuMi4xID0gY3ZjLWNvbXBsZXgtdHlwZS4yLjE6IFx1QzcyMFx1RDYxNVx1Qzc1OCBcdUNGNThcdUQxNTBcdUNFMjAgXHVDNzIwXHVENjE1XHVDNzc0IFx1QkU0NFx1QzVCNCBcdUM3ODhcdUM3M0NcdUJCQzBcdUI4NUMgJyd7MH0nJyBcdUM2OTRcdUMxOENcdUM1RDBcdUIyOTQgXHVCQjM4XHVDNzkwIFx1QjYxMFx1QjI5NCBcdUM2OTRcdUMxOEMgXHVDODE1XHVCQ0Y0IFx1RDU2RFx1QkFBOSBbY2hpbGRyZW5dXHVDNzc0IFx1QzVDNlx1QzVCNFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuMi4yID0gY3ZjLWNvbXBsZXgtdHlwZS4yLjI6ICcnezB9JycgXHVDNjk0XHVDMThDXHVDNUQwXHVCMjk0IFx1QzY5NFx1QzE4QyBbY2hpbGRyZW5dXHVDNzc0IFx1QzVDNlx1QzVCNFx1QzU3QyBcdUQ1NThcdUJBNzAgXHVBQzEyXHVDNzc0IFx1QzgwMVx1RDU2OVx1RDU3NFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuMi4zID0gY3ZjLWNvbXBsZXgtdHlwZS4yLjM6IFx1QzcyMFx1RDYxNVx1Qzc1OCBcdUNGNThcdUQxNTBcdUNFMjAgXHVDNzIwXHVENjE1XHVDNzc0IFx1QzY5NFx1QzE4QyBcdUM4MDRcdUM2QTlcdUM3NzRcdUJCQzBcdUI4NUMgJyd7MH0nJyBcdUM2OTRcdUMxOENcdUM1RDBcdUIyOTQgXHVCQjM4XHVDNzkwIFtjaGlsZHJlbl1cdUM3NzQgXHVEM0VDXHVENTY4XHVCNDIwIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuMi40LmEgPSBjdmMtY29tcGxleC10eXBlLjIuNC5hOiAnJ3swfScnIFx1QzY5NFx1QzE4Q1x1Qjg1QyBcdUMyRENcdUM3OTFcdUQ1NThcdUIyOTQgXHVCRDgwXHVDODAxXHVENTY5XHVENTVDIFx1Q0Y1OFx1RDE1MFx1Q0UyMFx1QUMwMCBcdUJDMUNcdUFDQUNcdUI0MThcdUM1QzhcdUMyQjVcdUIyQzhcdUIyRTQuICcnezF9JycgXHVDOTExIFx1RDU1OFx1QjA5OFx1QUMwMCBcdUQ1NDRcdUM2OTRcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuMi40LmIgPSBjdmMtY29tcGxleC10eXBlLjIuNC5iOiAnJ3swfScnIFx1QzY5NFx1QzE4Q1x1Qzc1OCBcdUNGNThcdUQxNTBcdUNFMjBcdUFDMDAgXHVCRDg4XHVDNjQ0XHVDODA0XHVENTY5XHVCMkM4XHVCMkU0LiAnJ3sxfScnIFx1QzkxMSBcdUQ1NThcdUIwOThcdUFDMDAgXHVENTQ0XHVDNjk0XHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBjdmMtY29tcGxleC10eXBlLjIuNC5jID0gY3ZjLWNvbXBsZXgtdHlwZS4yLjQuYzogXHVDNzdDXHVDRTU4XHVENTU4XHVCMjk0IFx1QzY0MFx1Qzc3Q1x1QjREQyBcdUNFNzRcdUI0REMgXHVCQjM4XHVDNzkwXHVBQzAwIFx1QzVDNFx1QUNBOVx1RDU1OFx1QUM4QyBcdUM4MDFcdUM2QTlcdUI0MThcdUM5QzBcdUI5Q0MgJyd7MH0nJyBcdUM2OTRcdUMxOENcdUM1RDAgXHVCMzAwXHVENTVDIFx1QzEyMFx1QzVCOFx1Qzc0NCBcdUNDM0VcdUM3NDQgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4KLSAgICAgICAgY3ZjLWNvbXBsZXgtdHlwZS4yLjQuZCA9IGN2Yy1jb21wbGV4LXR5cGUuMi40LmQ6ICcnezB9JycgXHVDNjk0XHVDMThDXHVCODVDIFx1QzJEQ1x1Qzc5MVx1RDU1OFx1QjI5NCBcdUJEODBcdUM4MDFcdUQ1NjlcdUQ1NUMgXHVDRjU4XHVEMTUwXHVDRTIwXHVBQzAwIFx1QkMxQ1x1QUNBQ1x1QjQxOFx1QzVDOFx1QzJCNVx1QjJDOFx1QjJFNC4gXHVDNUVDXHVBRTMwXHVDNUQwXHVCMjk0IFx1RDU1OFx1QzcwNCBcdUM2OTRcdUMxOENcdUFDMDAgXHVENTQ0XHVDNjk0XHVENTU4XHVDOUMwIFx1QzU0QVx1QzJCNVx1QjJDOFx1QjJFNC4KLSAgICAgICAgY3ZjLWNvbXBsZXgtdHlwZS4yLjQuZSA9IGN2Yy1jb21wbGV4LXR5cGUuMi40LmQ6ICcnezB9JycgXHVDNjk0XHVDMThDXHVCODVDIFx1QzJEQ1x1Qzc5MVx1RDU1OFx1QjI5NCBcdUJEODBcdUM4MDFcdUQ1NjlcdUQ1NUMgXHVDRjU4XHVEMTUwXHVDRTIwXHVBQzAwIFx1QkMxQ1x1QUNBQ1x1QjQxOFx1QzVDOFx1QzJCNVx1QjJDOFx1QjJFNC4gXHVDNUVDXHVBRTMwXHVDNUQwXHVCMjk0IFx1RDU1OFx1QzcwNCBcdUM2OTRcdUMxOEMgJyd7MX0nJ1x1Qzc3NChcdUFDMDApIFx1RDU0NFx1QzY5NFx1RDU1OFx1QzlDMCBcdUM1NEFcdUMyQjVcdUIyQzhcdUIyRTQuCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuMy4xID0gY3ZjLWNvbXBsZXgtdHlwZS4zLjE6ICcnezB9JycgXHVDNjk0XHVDMThDXHVDNzU4ICcnezF9JycgXHVDMThEXHVDMTMxXHVDNUQwIFx1QjMwMFx1RDU1QyAnJ3syfScnIFx1QUMxMlx1Qzc3NCBcdUQ1NzRcdUIyRjkgXHVDMThEXHVDMTMxIFx1QzBBQ1x1QzZBOVx1QzVEMCBcdUIzMDBcdUQ1NzQgXHVCRDgwXHVDODAxXHVENTY5XHVENTY5XHVCMkM4XHVCMkU0LiAnJ3sxfScnIFx1QzE4RFx1QzEzMVx1Qzc1OCBcdUFDRTBcdUM4MTVcdUI0MUMgXHVBQzEyXHVDNzc0ICcnezN9JydcdUM3ODVcdUIyQzhcdUIyRTQuCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuMy4yLjEgPSBjdmMtY29tcGxleC10eXBlLjMuMi4xOiAnJ3swfScnIFx1QzY5NFx1QzE4Q1x1QzVEMCAnJ3sxfScnIFx1QzE4RFx1QzEzMVx1QzVEMCBcdUIzMDBcdUQ1NUMgXHVDMThEXHVDMTMxIFx1QzY0MFx1Qzc3Q1x1QjREQyBcdUNFNzRcdUI0REMgXHVCQjM4XHVDNzkwXHVBQzAwIFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4KLSAgICAgICAgY3ZjLWNvbXBsZXgtdHlwZS4zLjIuMiA9IGN2Yy1jb21wbGV4LXR5cGUuMy4yLjI6ICcnezF9JycgXHVDMThEXHVDMTMxXHVDNzQwICcnezB9JycgXHVDNjk0XHVDMThDXHVDNUQwIFx1QjA5OFx1RDBDMFx1QjBBMCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LgotICAgICAgICBjdmMtY29tcGxleC10eXBlLjQgPSBjdmMtY29tcGxleC10eXBlLjQ6ICcnezF9JycgXHVDMThEXHVDMTMxXHVDNzQwICcnezB9JycgXHVDNjk0XHVDMThDXHVDNUQwIFx1QjA5OFx1RDBDMFx1QjA5OFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuNS4xID0gY3ZjLWNvbXBsZXgtdHlwZS41LjE6ICcnezB9JycgXHVDNjk0XHVDMThDXHVDNUQwXHVDMTFDICcnezF9JycgXHVDMThEXHVDMTMxXHVDNzc0IFx1QjMwMFx1Q0NCNCBJRFx1Qzc3NFx1QzlDMFx1QjlDQyBcdUIzMDBcdUNDQjQgSUQgJyd7Mn0nJ1x1Qzc3NChcdUFDMDApIFx1Qzc3NFx1QkJGOCBcdUM3ODhcdUMyQjVcdUIyQzhcdUIyRTQuIFx1RDU1OFx1QjA5OFx1QjlDQyBcdUMwQUNcdUM2QTlcdUQ1NjAgXHVDMjE4IFx1Qzc4OFx1QzJCNVx1QjJDOFx1QjJFNC4KLSAgICAgICAgY3ZjLWNvbXBsZXgtdHlwZS41LjIgPSBjdmMtY29tcGxleC10eXBlLjUuMjogJyd7MH0nJyBcdUM2OTRcdUMxOENcdUM1RDBcdUMxMUMgJyd7MX0nJyBcdUMxOERcdUMxMzFcdUM3NzQgXHVCMzAwXHVDQ0I0IElEXHVDNzc0XHVDOUMwXHVCOUNDICd7J2F0dHJpYnV0ZSB1c2VzJ30nIFx1QzkxMSBJRFx1QzVEMFx1QzExQyBcdUQzMENcdUMwRERcdUI0MUMgJyd7Mn0nJyBcdUMxOERcdUMxMzFcdUM3NzQgXHVDNzc0XHVCQkY4IFx1Qzc4OFx1QzJCNVx1QjJDOFx1QjJFNC4KLSAgICAgICAgY3ZjLWRhdGF0eXBlLXZhbGlkLjEuMi4xID0gY3ZjLWRhdGF0eXBlLXZhbGlkLjEuMi4xOiAnJ3swfScnXHVDNzQwKFx1QjI5NCkgJyd7MX0nJ1x1QzVEMCBcdUIzMDBcdUQ1NzQgXHVDODAxXHVENTY5XHVENTVDIFx1QUMxMlx1Qzc3NCBcdUM1NDRcdUIyRDlcdUIyQzhcdUIyRTQuCi0gICAgICAgIGN2Yy1kYXRhdHlwZS12YWxpZC4xLjIuMiA9IGN2Yy1kYXRhdHlwZS12YWxpZC4xLjIuMjogJyd7MH0nJ1x1Qzc0MChcdUIyOTQpIFx1QkFBOVx1Qjg1RCBcdUM3MjBcdUQ2MTUgJyd7MX0nJ1x1Qzc1OCBcdUM4MDFcdUQ1NjlcdUQ1NUMgXHVBQzEyXHVDNzc0IFx1QzU0NFx1QjJEOVx1QjJDOFx1QjJFNC4KLSAgICAgICAgY3ZjLWRhdGF0eXBlLXZhbGlkLjEuMi4zID0gY3ZjLWRhdGF0eXBlLXZhbGlkLjEuMi4zOiAnJ3swfScnXHVDNzQwKFx1QjI5NCkgXHVENTY5XHVDOUQxXHVENTY5IFx1QzcyMFx1RDYxNSAnJ3sxfScnXHVDNzU4IFx1QzgwMVx1RDU2OVx1RDU1QyBcdUFDMTJcdUM3NzQgXHVDNTQ0XHVCMkQ5XHVCMkM4XHVCMkU0LgotICAgICAgICBjdmMtZWx0LjEgPSBjdmMtZWx0LjE6ICcnezB9JycgXHVDNjk0XHVDMThDXHVDNzU4IFx1QzEyMFx1QzVCOFx1Qzc0NCBcdUNDM0VcdUM3NDQgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4KLSAgICAgICAgY3ZjLWVsdC4yID0gY3ZjLWVsdC4yOiAnJ3swfScnXHVDNUQwIFx1QjMwMFx1RDU1QyBcdUM2OTRcdUMxOEMgXHVDMTIwXHVDNUI4XHVDNUQwXHVDMTFDICd7J2Fic3RyYWN0J30nXHVDNzU4IFx1QUMxMlx1Qzc0MCBmYWxzZVx1QzVFQ1x1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIGN2Yy1lbHQuMy4xID0gY3ZjLWVsdC4zLjE6ICcnezB9JydcdUM3NTggJ3snbmlsbGFibGUnfScgXHVDMThEXHVDMTMxXHVDNzc0IGZhbHNlXHVDNzc0XHVCQkMwXHVCODVDICcnezF9JycgXHVDMThEXHVDMTMxXHVDNzQwICcnezB9JycgXHVDNjk0XHVDMThDXHVDNUQwIFx1QjA5OFx1RDBDMFx1QjA5OFx1QzlDMCBcdUM1NEFcdUM1NDRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBjdmMtZWx0LjMuMi4xID0gY3ZjLWVsdC4zLjIuMTogJyd7MX0nJ1x1Qzc3NChcdUFDMDApIFx1QzlDMFx1QzgxNVx1QjQxOFx1QzVDOFx1QzczQ1x1QkJDMFx1Qjg1QyAnJ3swfScnIFx1QzY5NFx1QzE4Q1x1QzVEMFx1QjI5NCBcdUJCMzhcdUM3OTAgXHVCNjEwXHVCMjk0IFx1QzY5NFx1QzE4QyBcdUM4MTVcdUJDRjQgW2NoaWxkcmVuXVx1Qzc3NCBcdUQzRUNcdUQ1NjhcdUI0MjAgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4KLSAgICAgICAgY3ZjLWVsdC4zLjIuMiA9IGN2Yy1lbHQuMy4yLjI6ICcnezF9JydcdUM3NzQoXHVBQzAwKSBcdUM5QzBcdUM4MTVcdUI0MThcdUM1QzhcdUM3M0NcdUJCQzBcdUI4NUMgJyd7MH0nJyBcdUM2OTRcdUMxOENcdUM1RDAgXHVCMzAwXHVENTc0IFx1QUNFMFx1QzgxNVx1QjQxQyAneyd2YWx1ZSBjb25zdHJhaW50J30nXHVBQzAwIFx1QzVDNlx1QzVCNFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIGN2Yy1lbHQuNC4xID0gY3ZjLWVsdC40LjE6ICcnezB9JycgXHVDNjk0XHVDMThDXHVDNzU4ICcnezF9JycgXHVDMThEXHVDMTMxXHVDNUQwIFx1QjMwMFx1RDU1QyAnJ3syfScnIFx1QUMxMlx1Qzc0MCBcdUM4MDFcdUQ1NjlcdUQ1NUMgUU5hbWVcdUM3NzQgXHVDNTQ0XHVCMkQ5XHVCMkM4XHVCMkU0LgotICAgICAgICBjdmMtZWx0LjQuMiA9IGN2Yy1lbHQuNC4yOiAnJ3sxfScnXHVDNzQ0KFx1Qjk3QykgJyd7MH0nJyBcdUM2OTRcdUMxOENcdUM1RDAgXHVCMzAwXHVENTVDIFx1QzcyMFx1RDYxNSBcdUM4MTVcdUM3NThcdUI4NUMgXHVCRDg0XHVDMTFEXHVENTYwIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuCi0gICAgICAgIGN2Yy1lbHQuNC4zID0gY3ZjLWVsdC40LjM6ICcnezF9JycgXHVDNzIwXHVENjE1XHVDNzQwICcnezB9JycgXHVDNjk0XHVDMThDXHVDNzU4IFx1QzcyMFx1RDYxNSBcdUM4MTVcdUM3NTggJyd7Mn0nJ1x1QzVEMFx1QzExQyBcdUM4MDFcdUQ1NjlcdUQ1NThcdUFDOEMgXHVEMzBDXHVDMEREXHVCNDFDIFx1QUM4M1x1Qzc3NCBcdUM1NDRcdUIyRDlcdUIyQzhcdUIyRTQuCi0gICAgICAgIGN2Yy1lbHQuNS4xLjEgPSBjdmMtZWx0LjUuMS4xOiAnJ3swfScnIFx1QzY5NFx1QzE4Q1x1Qzc1OCAneyd2YWx1ZSBjb25zdHJhaW50J30nICcnezJ9JydcdUM3NDAoXHVCMjk0KSAnJ3sxfScnIFx1QzcyMFx1RDYxNVx1QzVEMCBcdUIzMDBcdUQ1NzQgXHVDODAxXHVENTY5XHVENTVDIFx1QUUzMFx1QkNGOFx1QUMxMlx1Qzc3NCBcdUM1NDRcdUIyRDlcdUIyQzhcdUIyRTQuCi0gICAgICAgIGN2Yy1lbHQuNS4yLjIuMSA9IGN2Yy1lbHQuNS4yLjIuMTogJyd7MH0nJyBcdUM2OTRcdUMxOENcdUM1RDBcdUIyOTQgXHVDNjk0XHVDMThDIFx1QzgxNVx1QkNGNCBcdUQ1NkRcdUJBQTkgW2NoaWxkcmVuXVx1Qzc3NCBcdUM1QzZcdUM1QjRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBjdmMtZWx0LjUuMi4yLjIuMSA9IGN2Yy1lbHQuNS4yLjIuMi4xOiAnJ3swfScnIFx1QzY5NFx1QzE4Q1x1Qzc1OCAnJ3sxfScnIFx1QUMxMlx1Qzc3NCBcdUFDRTBcdUM4MTVcdUI0MUMgJ3sndmFsdWUgY29uc3RyYWludCd9JyBcdUFDMTIgJyd7Mn0nJ1x1QUNGQyhcdUM2NDApIFx1Qzc3Q1x1Q0U1OFx1RDU1OFx1QzlDMCBcdUM1NEFcdUMyQjVcdUIyQzhcdUIyRTQuCi0gICAgICAgIGN2Yy1lbHQuNS4yLjIuMi4yID0gY3ZjLWVsdC41LjIuMi4yLjI6ICcnezB9JycgXHVDNjk0XHVDMThDXHVDNzU4ICcnezF9JycgXHVBQzEyXHVDNzc0ICd7J3ZhbHVlIGNvbnN0cmFpbnQnfScgXHVBQzEyICcnezJ9JydcdUFDRkMoXHVDNjQwKSBcdUM3N0NcdUNFNThcdUQ1NThcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0LgotICAgICAgICBjdmMtZW51bWVyYXRpb24tdmFsaWQgPSBjdmMtZW51bWVyYXRpb24tdmFsaWQ6ICcnezB9JycgXHVBQzEyXHVDNzQwICcnezF9JycgXHVCQUE5XHVCODVEXHVDNUQwIFx1QjMwMFx1RDU3NCBcdUM4MDFcdUQ1NjlcdUQ1NUMgXHVCQTc0XHVDNzc0IFx1QzU0NFx1QjJEOVx1QjJDOFx1QjJFNC4gXHVCQUE5XHVCODVEXHVDNzU4IFx1QUMxMlx1Qzc3NFx1QzVCNFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIGN2Yy1mcmFjdGlvbkRpZ2l0cy12YWxpZCA9IGN2Yy1mcmFjdGlvbkRpZ2l0cy12YWxpZDogJyd7MH0nJyBcdUFDMTJcdUM3NTggXHVDMThDXHVDMjE4XHVDODEwIFx1Qzc3NFx1RDU1OCBcdUM3OTBcdUI5QkZcdUMyMThcdUFDMDAgezF9XHVDNzc0XHVDOUMwXHVCOUNDIFx1QzE4Q1x1QzIxOFx1QzgxMCBcdUM3NzRcdUQ1NTggXHVDNzkwXHVCOUJGXHVDMjE4XHVCMjk0IHsyfShcdUM3M0MpXHVCODVDIFx1QzgxQ1x1RDU1Q1x1QjQxOFx1QzVDOFx1QzJCNVx1QjJDOFx1QjJFNC4KLSAgICAgICAgY3ZjLWlkLjEgPSBjdmMtaWQuMTogSURSRUYgJyd7MH0nJ1x1QzVEMCBcdUIzMDBcdUQ1NUMgSUQvSURSRUYgXHVCQzE0XHVDNzc4XHVCNTI5XHVDNzc0IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4KLSAgICAgICAgY3ZjLWlkLjIgPSBjdmMtaWQuMjogSUQgXHVBQzEyICcnezB9JydcdUM3NzQoXHVBQzAwKSBcdUM1RUNcdUI3RUMgXHVCQzg4IFx1QkMxQ1x1QzBERFx1RDU4OFx1QzJCNVx1QjJDOFx1QjJFNC4KLSAgICAgICAgY3ZjLWlkLjMgPSBjdmMtaWQuMzogSUQgXHVDODFDXHVDNTdEIFx1Qzg3MFx1QUM3NCAnJ3swfScnXHVDNzU4IFx1RDU0NFx1QjREQ1x1QUMwMCAnJ3sxfScnIFx1QzY5NFx1QzE4Q1x1QzY0MCBcdUM3N0NcdUNFNThcdUQ1NThcdUM5QzBcdUI5Q0MgXHVDNzc0IFx1QzY5NFx1QzE4Q1x1QjI5NCBcdUIyRThcdUMyMUMgXHVDNzIwXHVENjE1XHVDNzQ0IFx1QzBBQ1x1QzZBOVx1RDU1OFx1QzlDMCBcdUM1NEFcdUMyQjVcdUIyQzhcdUIyRTQuCi0gICAgICAgIGN2Yy1sZW5ndGgtdmFsaWQgPSBjdmMtbGVuZ3RoLXZhbGlkOiBsZW5ndGggPSAnJ3sxfScnXHVDNzc4ICcnezB9JycgXHVBQzEyXHVDNzQwICcnezN9JycgXHVDNzIwXHVENjE1XHVDNzU4IGxlbmd0aCAnJ3syfScnXHVDNUQwIFx1QjMwMFx1RDU3NCBcdUM4MDFcdUQ1NjlcdUQ1NUMgXHVCQTc0XHVDNzc0IFx1QzU0NFx1QjJEOVx1QjJDOFx1QjJFNC4KLSAgICAgICAgY3ZjLW1heEV4Y2x1c2l2ZS12YWxpZCA9IGN2Yy1tYXhFeGNsdXNpdmUtdmFsaWQ6ICcnezB9JycgXHVBQzEyXHVDNzQwICcnezJ9JycgXHVDNzIwXHVENjE1XHVDNzU4IG1heEV4Y2x1c2l2ZSAnJ3sxfScnXHVDNUQwIFx1QjMwMFx1RDU3NCBcdUM4MDFcdUQ1NjlcdUQ1NUMgXHVCQTc0XHVDNzc0IFx1QzU0NFx1QjJEOVx1QjJDOFx1QjJFNC4KLSAgICAgICAgY3ZjLW1heEluY2x1c2l2ZS12YWxpZCA9IGN2Yy1tYXhJbmNsdXNpdmUtdmFsaWQ6ICcnezB9JycgXHVBQzEyXHVDNzQwICcnezJ9JycgXHVDNzIwXHVENjE1XHVDNzU4IG1heEluY2x1c2l2ZSAnJ3sxfScnXHVDNUQwIFx1QjMwMFx1RDU3NCBcdUM4MDFcdUQ1NjlcdUQ1NUMgXHVCQTc0XHVDNzc0IFx1QzU0NFx1QjJEOVx1QjJDOFx1QjJFNC4KLSAgICAgICAgY3ZjLW1heExlbmd0aC12YWxpZCA9IGN2Yy1tYXhMZW5ndGgtdmFsaWQ6IGxlbmd0aCA9ICcnezF9JydcdUM3NzggJyd7MH0nJyBcdUFDMTJcdUM3NDAgJyd7M30nJyBcdUM3MjBcdUQ2MTVcdUM3NTggbWF4TGVuZ3RoICcnezJ9JydcdUM1RDAgXHVCMzAwXHVENTc0IFx1QzgwMVx1RDU2OVx1RDU1QyBcdUJBNzRcdUM3NzQgXHVDNTQ0XHVCMkQ5XHVCMkM4XHVCMkU0LgotICAgICAgICBjdmMtbWluRXhjbHVzaXZlLXZhbGlkID0gY3ZjLW1pbkV4Y2x1c2l2ZS12YWxpZDogJyd7MH0nJyBcdUFDMTJcdUM3NDAgJyd7Mn0nJyBcdUM3MjBcdUQ2MTVcdUM3NTggbWluRXhjbHVzaXZlICcnezF9JydcdUM1RDAgXHVCMzAwXHVENTc0IFx1QzgwMVx1RDU2OVx1RDU1QyBcdUJBNzRcdUM3NzQgXHVDNTQ0XHVCMkQ5XHVCMkM4XHVCMkU0LgotICAgICAgICBjdmMtbWluSW5jbHVzaXZlLXZhbGlkID0gY3ZjLW1pbkluY2x1c2l2ZS12YWxpZDogJyd7MH0nJyBcdUFDMTJcdUM3NDAgJyd7Mn0nJyBcdUM3MjBcdUQ2MTVcdUM3NTggbWluSW5jbHVzaXZlICcnezF9JydcdUM1RDAgXHVCMzAwXHVENTc0IFx1QzgwMVx1RDU2OVx1RDU1QyBcdUJBNzRcdUM3NzQgXHVDNTQ0XHVCMkQ5XHVCMkM4XHVCMkU0LgotICAgICAgICBjdmMtbWluTGVuZ3RoLXZhbGlkID0gY3ZjLW1pbkxlbmd0aC12YWxpZDogbGVuZ3RoID0gJyd7MX0nJ1x1Qzc3OCAnJ3swfScnIFx1QUMxMlx1Qzc0MCAnJ3szfScnIFx1QzcyMFx1RDYxNVx1Qzc1OCBtaW5MZW5ndGggJyd7Mn0nJ1x1QzVEMCBcdUIzMDBcdUQ1NzQgXHVDODAxXHVENTY5XHVENTVDIFx1QkE3NFx1Qzc3NCBcdUM1NDRcdUIyRDlcdUIyQzhcdUIyRTQuCi0gICAgICAgIGN2Yy1wYXR0ZXJuLXZhbGlkID0gY3ZjLXBhdHRlcm4tdmFsaWQ6ICcnezB9JycgXHVBQzEyXHVDNzQwICcnezJ9JycgXHVDNzIwXHVENjE1XHVDNzU4ICcnezF9JycgXHVEMzI4XHVEMTM0XHVDNUQwIFx1QjMwMFx1RDU3NCBcdUM4MDFcdUQ1NjlcdUQ1NUMgXHVCQTc0XHVDNzc0IFx1QzU0NFx1QjJEOVx1QjJDOFx1QjJFNC4KLSAgICAgICAgY3ZjLXRvdGFsRGlnaXRzLXZhbGlkID0gY3ZjLXRvdGFsRGlnaXRzLXZhbGlkOiAnJ3swfScnIFx1QUMxMlx1Qzc1OCBcdUNEMUQgXHVDNzkwXHVCOUJGXHVDMjE4XHVBQzAwIHsxfVx1Qzc3NFx1QzlDMFx1QjlDQyBcdUNEMUQgXHVDNzkwXHVCOUJGXHVDMjE4XHVCMjk0IHsyfShcdUM3M0MpXHVCODVDIFx1QzgxQ1x1RDU1Q1x1QjQxOFx1QzVDOFx1QzJCNVx1QjJDOFx1QjJFNC4KLSAgICAgICAgY3ZjLXR5cGUuMiA9IGN2Yy10eXBlLjI6IHswfSBcdUM2OTRcdUMxOENcdUM1RDAgXHVCMzAwXHVENTVDIFx1QzcyMFx1RDYxNSBcdUM4MTVcdUM3NThcdUIyOTQgXHVDRDk0XHVDMEMxXHVDODAxXHVDNzdDIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuCi0gICAgICAgIGN2Yy10eXBlLjMuMS4xID0gY3ZjLXR5cGUuMy4xLjE6ICcnezB9JycgXHVDNjk0XHVDMThDXHVCMjk0IFx1QjJFOFx1QzIxQyBcdUM3MjBcdUQ2MTVcdUM3NzRcdUJCQzBcdUI4NUMgXHVCMTI0XHVDNzg0XHVDMkE0XHVEMzk4XHVDNzc0XHVDMkE0IFx1Qzc3NFx1Qjk4NFx1Qzc3NCAnJ2h0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlJydcdUM3NzRcdUJBNzAgW2xvY2FsIG5hbWVdXHVDNzc0ICcndHlwZScnLCAnJ25pbCcnLCAnJ3NjaGVtYUxvY2F0aW9uJycgXHVCNjEwXHVCMjk0ICcnbm9OYW1lc3BhY2VTY2hlbWFMb2NhdGlvbicnIFx1QzkxMSBcdUQ1NThcdUIwOThcdUM3NzggXHVDMThEXHVDMTMxXHVDNzQ0IFx1QzgxQ1x1QzY3OFx1RDU1OFx1QUNFMCBcdUIyRTRcdUI5NzggXHVDMThEXHVDMTMxXHVDNzQ0IFx1RDNFQ1x1RDU2OFx1RDU2MCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiBcdUQ1NThcdUM5QzBcdUI5Q0MgJyd7MX0nJyBcdUMxOERcdUMxMzFcdUM3NzQgXHVCQzFDXHVBQ0FDXHVCNDE4XHVDNUM4XHVDMkI1XHVCMkM4XHVCMkU0LgotICAgICAgICBjdmMtdHlwZS4zLjEuMiA9IGN2Yy10eXBlLjMuMS4yOiAnJ3swfScnIFx1QzY5NFx1QzE4Q1x1QjI5NCBcdUIyRThcdUMyMUMgXHVDNzIwXHVENjE1XHVDNzc0XHVCQkMwXHVCODVDIFx1QzY5NFx1QzE4QyBcdUM4MTVcdUJDRjQgXHVENTZEXHVCQUE5IFtjaGlsZHJlbl1cdUM3NDQgXHVEM0VDXHVENTY4XHVENTU4XHVDOUMwIFx1QzU0QVx1QzU0NFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIGN2Yy10eXBlLjMuMS4zID0gY3ZjLXR5cGUuMy4xLjM6ICcnezB9JycgXHVDNjk0XHVDMThDXHVDNzU4ICcnezF9JycgXHVBQzEyXHVDNzc0IFx1QkQ4MFx1QzgwMVx1RDU2OVx1RDU2OVx1QjJDOFx1QjJFNC4KLQotI3NjaGVtYSB2YWxpZCAoMy5YLjMpCi0KLSAgICAgICAgc2NoZW1hX3JlZmVyZW5jZS5hY2Nlc3MgPSBzY2hlbWFfcmVmZXJlbmNlOiBhY2Nlc3NFeHRlcm5hbFNjaGVtYSBcdUMxOERcdUMxMzFcdUM3M0NcdUI4NUMgXHVDMTI0XHVDODE1XHVCNDFDIFx1QzgxQ1x1RDU1Q1x1QzczQ1x1Qjg1QyBcdUM3NzhcdUQ1NzQgJyd7MX0nJyBcdUM1NjFcdUMxMzhcdUMyQTRcdUFDMDAgXHVENUM4XHVDNkE5XHVCNDE4XHVDOUMwIFx1QzU0QVx1QzczQ1x1QkJDMFx1Qjg1QyBcdUMyQTRcdUQwQTRcdUI5QzggXHVCQjM4XHVDMTFDICcnezB9JycgXHVDNzdEXHVBRTMwXHVCOTdDIFx1QzJFNFx1RDMyOFx1RDU4OFx1QzJCNVx1QjJDOFx1QjJFNC4gCi0gICAgICAgIHNjaGVtYV9yZWZlcmVuY2UuNCA9IHNjaGVtYV9yZWZlcmVuY2UuNDogXHVDMkE0XHVEMEE0XHVCOUM4IFx1QkIzOFx1QzExQyAnJ3swfScnIFx1Qzc3RFx1QUUzMFx1Qjk3QyBcdUMyRTRcdUQzMjhcdUQ1ODhcdUMyQjVcdUIyQzhcdUIyRTQuIFx1QzZEMFx1Qzc3ODogMSkgXHVCQjM4XHVDMTFDXHVCOTdDIFx1Q0MzRVx1Qzc0NCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiAyKSBcdUJCMzhcdUMxMUNcdUI5N0MgXHVDNzdEXHVDNzQ0IFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuIDMpIFx1QkIzOFx1QzExQ1x1Qzc1OCBcdUI4RThcdUQyQjggXHVDNjk0XHVDMThDXHVBQzAwIDx4c2Q6c2NoZW1hPlx1QUMwMCBcdUM1NDRcdUIyRDlcdUIyQzhcdUIyRTQuCi0gICAgICAgIHNyYy1hbm5vdGF0aW9uID0gc3JjLWFubm90YXRpb246IDxhbm5vdGF0aW9uPiBcdUM2OTRcdUMxOENcdUM1RDBcdUIyOTQgPGFwcGluZm8+IFx1QkMwRiA8ZG9jdW1lbnRhdGlvbj4gXHVDNjk0XHVDMThDXHVCOUNDIFx1RDNFQ1x1RDU2OFx1QjQyMCBcdUMyMTggXHVDNzg4XHVDOUMwXHVCOUNDICcnezB9JydcdUM3NzQoXHVBQzAwKSBcdUJDMUNcdUFDQUNcdUI0MThcdUM1QzhcdUMyQjVcdUIyQzhcdUIyRTQuCi0gICAgICAgIHNyYy1hdHRyaWJ1dGUuMSA9IHNyYy1hdHRyaWJ1dGUuMTogJydkZWZhdWx0JycgXHVCQzBGICcnZml4ZWQnJyBcdUMxOERcdUMxMzFcdUM3NDAgXHVDMThEXHVDMTMxIFx1QzEyMFx1QzVCOCAnJ3swfScnXHVDNUQwIFx1RDU2OFx1QUVEOCBcdUM4NzRcdUM3QUNcdUQ1NjAgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4gXHVENTU4XHVCMDk4XHVCOUNDIFx1QzBBQ1x1QzZBOVx1RDU1OFx1QzJFRFx1QzJEQ1x1QzYyNC4KLSAgICAgICAgc3JjLWF0dHJpYnV0ZS4yID0gc3JjLWF0dHJpYnV0ZS4yOiAnJ2RlZmF1bHQnJyBcdUMxOERcdUMxMzFcdUM3NzQgJyd7MH0nJyBcdUMxOERcdUMxMzFcdUM1RDAgXHVDODc0XHVDN0FDXHVENTU4XHVCQkMwXHVCODVDICcndXNlJycgXHVBQzEyXHVDNzQwICcnb3B0aW9uYWwnJ1x1Qzc3NFx1QzVCNFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIHNyYy1hdHRyaWJ1dGUuMy4xID0gc3JjLWF0dHJpYnV0ZS4zLjE6ICdyZWYnIFx1QjYxMFx1QjI5NCAnbmFtZScgXHVDOTExIFx1RDU1OFx1QjA5OFx1QUMwMCBcdUI4NUNcdUNFRUMgXHVDMThEXHVDMTMxIFx1QzEyMFx1QzVCOFx1QzVEMCBcdUM4NzRcdUM3QUNcdUQ1NzRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBzcmMtYXR0cmlidXRlLjMuMiA9IHNyYy1hdHRyaWJ1dGUuMy4yOiBcdUNGNThcdUQxNTBcdUNFMjBcdUFDMDAgXHVDMThEXHVDMTMxIFx1Q0MzOFx1Qzg3MCAnJ3swfScnXHVDNUQwIFx1QjMwMFx1RDU1QyAoYW5ub3RhdGlvbj8pXHVBQ0ZDIFx1Qzc3Q1x1Q0U1OFx1RDU3NFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIHNyYy1hdHRyaWJ1dGUuNCA9IHNyYy1hdHRyaWJ1dGUuNDogJyd7MH0nJyBcdUMxOERcdUMxMzFcdUM1RDAgJyd0eXBlJycgXHVDMThEXHVDMTMxXHVBQ0ZDIFx1Qzc3NVx1QkE4NVx1Qzc1OCAnJ3NpbXBsZVR5cGUnJyBcdUQ1NThcdUM3MDQgXHVDMThEXHVDMTMxXHVDNzc0IFx1QkFBOFx1QjQ1MCBcdUM3ODhcdUMyQjVcdUIyQzhcdUIyRTQuIFx1Qzc3NCBcdUM5MTEgXHVENTU4XHVCMDk4XHVCOUNDIFx1QzE4RFx1QzEzMVx1QzVEMCBcdUQ1QzhcdUM2QTlcdUI0MjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIHNyYy1hdHRyaWJ1dGVfZ3JvdXAuMiA9IHNyYy1hdHRyaWJ1dGVfZ3JvdXAuMjogXHVDMThEXHVDMTMxIFx1QURGOFx1QjhGOSAnJ3swfScnXHVDNUQwIFx1QjMwMFx1RDU3NCBcdUM2NDBcdUM3N0NcdUI0REMgXHVDRTc0XHVCNERDIFx1QkIzOFx1Qzc5MFx1Qzc1OCBcdUFENTBcdUM5RDFcdUQ1NjlcdUM3NDQgXHVENDVDXHVENjA0XHVENTYwIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuCi0gICAgICAgIHNyYy1hdHRyaWJ1dGVfZ3JvdXAuMyA9IHNyYy1hdHRyaWJ1dGVfZ3JvdXAuMzogXHVDMThEXHVDMTMxIFx1QURGOFx1QjhGOSAnJ3swfScnXHVDNUQwIFx1QjMwMFx1RDU1QyBcdUMyMUNcdUQ2NTggXHVDODE1XHVDNzU4XHVBQzAwIFx1QUMxMFx1QzlDMFx1QjQxOFx1QzVDOFx1QzJCNVx1QjJDOFx1QjJFNC4gXHVDMjFDXHVENjU4XHVDODAxXHVDNzNDXHVCODVDIFx1QjRBNFx1QzVEMCBcdUM2MjRcdUIyOTQgXHVDMThEXHVDMTMxIFx1QURGOFx1QjhGOSBcdUNDMzhcdUM4NzBcdUFDMDAgXHVBQ0IwXHVBRDZEIFx1Qzc5MFx1QzJFMFx1QzVEMFx1QUM4QyBcdUIzQ0NcdUM1NDRcdUM2MzVcdUIyQzhcdUIyRTQuCi0gICAgICAgIHNyYy1jdC4xID0gc3JjLWN0LjE6ICcnezB9JycgXHVDNzIwXHVENjE1XHVDNUQwIFx1QjMwMFx1RDU1QyBcdUJDRjVcdUQ1NjkgXHVDNzIwXHVENjE1IFx1QzgxNVx1Qzc1OCBcdUQ0NUNcdUQ2MDQgXHVDNjI0XHVCOTU4XHVBQzAwIFx1QkMxQ1x1QzBERFx1RDU4OFx1QzJCNVx1QjJDOFx1QjJFNC4gPGNvbXBsZXhDb250ZW50Plx1QUMwMCBcdUMwQUNcdUM2QTlcdUI0MThcdUIyOTQgXHVBQ0JEXHVDNkIwIGNvbXBsZXhUeXBlXHVDNzc0IFx1QUUzMFx1QkNGOCBcdUM3MjBcdUQ2MTVcdUM3NzRcdUM1QjRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LiAnJ3sxfScnXHVDNzQwKFx1QjI5NCkgc2ltcGxlVHlwZVx1Qzc4NVx1QjJDOFx1QjJFNC4KLSAgICAgICAgc3JjLWN0LjIuMSA9IHNyYy1jdC4yLjE6ICcnezB9JycgXHVDNzIwXHVENjE1XHVDNUQwIFx1QjMwMFx1RDU1QyBcdUJDRjVcdUQ1NjkgXHVDNzIwXHVENjE1IFx1QzgxNVx1Qzc1OCBcdUQ0NUNcdUQ2MDQgXHVDNjI0XHVCOTU4XHVBQzAwIFx1QkMxQ1x1QzBERFx1RDU4OFx1QzJCNVx1QjJDOFx1QjJFNC4gPHNpbXBsZUNvbnRlbnQ+XHVBQzAwIFx1QzBBQ1x1QzZBOVx1QjQxOFx1QjI5NCBcdUFDQkRcdUM2QjAgXHVDRjU4XHVEMTUwXHVDRTIwIFx1QzcyMFx1RDYxNVx1Qzc3NCBcdUIyRThcdUMyMUMgXHVDNzIwXHVENjE1XHVDNzc4IGNvbXBsZXhUeXBlLCBcdUQ2M0NcdUQ1NjkgXHVDRjU4XHVEMTUwXHVDRTIwIFx1QkMwRiBcdUJFNDRcdUM2QjggXHVDMjE4IFx1Qzc4OFx1QjI5NCBcdUM4NzBcdUFDMDFcdUM3NDQgXHVBQzAwXHVDOUM0IFx1QkNGNVx1RDU2OSBcdUM3MjBcdUQ2MTUoXHVDODFDXHVENTVDIFx1QzBBQ1x1RDU2RFx1Qzc3NCBcdUM5QzBcdUM4MTVcdUI0MUMgXHVBQ0JEXHVDNkIwXHVDNUQwXHVCOUNDKSBcdUI2MTBcdUIyOTQgXHVCMkU4XHVDMjFDIFx1QzcyMFx1RDYxNShcdUQ2NTVcdUM3QTVcdUM3NzQgXHVDOUMwXHVDODE1XHVCNDFDIFx1QUNCRFx1QzZCMFx1QzVEMFx1QjlDQylcdUM3NzQgXHVBRTMwXHVCQ0Y4IFx1QzcyMFx1RDYxNVx1Qzc3NFx1QzVCNFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuICcnezF9JydcdUM3NDAoXHVCMjk0KSBcdUM3NzRcdUI3RUNcdUQ1NUMgXHVDODcwXHVBQzc0XHVDNzQ0IFx1Q0RBOVx1Qzg3MVx1RDU1OFx1QzlDMCBcdUM1NEFcdUMyQjVcdUIyQzhcdUIyRTQuCi0gICAgICAgIHNyYy1jdC4yLjIgPSBzcmMtY3QuMi4yOiAnJ3swfScnIFx1QzcyMFx1RDYxNVx1QzVEMCBcdUIzMDBcdUQ1NUMgXHVCQ0Y1XHVENTY5IFx1QzcyMFx1RDYxNSBcdUM4MTVcdUM3NTggXHVENDVDXHVENjA0IFx1QzYyNFx1Qjk1OFx1QUMwMCBcdUJDMUNcdUMwRERcdUQ1ODhcdUMyQjVcdUIyQzhcdUIyRTQuIHNpbXBsZUNvbnRlbnRcdUI5N0MgXHVBQzAwXHVDOUM0IGNvbXBsZXhUeXBlXHVDNzc0IFx1RDYzQ1x1RDU2OSBcdUNGNThcdUQxNTBcdUNFMjAgXHVCQzBGIFx1QkU0NFx1QzZCOCBcdUMyMTggXHVDNzg4XHVCMjk0IFx1Qzg3MFx1QUMwMVx1Qzc0NCBcdUFDMDBcdUM5QzQgY29tcGxleFR5cGVcdUM3NDQgXHVDODFDXHVENTVDXHVENTU4XHVCMjk0IFx1QUNCRFx1QzZCMCA8cmVzdHJpY3Rpb24+XHVDNzU4IFx1RDU1OFx1QzcwNCBcdUQ1NkRcdUJBQTkgXHVDOTExIDxzaW1wbGVUeXBlPlx1Qzc3NCBcdUM3ODhcdUM1QjRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBzcmMtY3QuNCA9IHNyYy1jdC40OiAnJ3swfScnIFx1QzcyMFx1RDYxNVx1QzVEMCBcdUIzMDBcdUQ1NUMgXHVCQ0Y1XHVENTY5IFx1QzcyMFx1RDYxNSBcdUM4MTVcdUM3NTggXHVENDVDXHVENjA0IFx1QzYyNFx1Qjk1OFx1QUMwMCBcdUJDMUNcdUMwRERcdUQ1ODhcdUMyQjVcdUIyQzhcdUIyRTQuIFx1QzY0MFx1Qzc3Q1x1QjREQyBcdUNFNzRcdUI0REMgXHVCQjM4XHVDNzkwXHVDNzU4IFx1QUQ1MFx1QzlEMVx1RDU2OVx1Qzc0NCBcdUQ0NUNcdUQ2MDRcdUQ1NjAgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4KLSAgICAgICAgc3JjLWN0LjUgPSBzcmMtY3QuNTogJyd7MH0nJyBcdUM3MjBcdUQ2MTVcdUM1RDAgXHVCMzAwXHVENTVDIFx1QkNGNVx1RDU2OSBcdUM3MjBcdUQ2MTUgXHVDODE1XHVDNzU4IFx1RDQ1Q1x1RDYwNCBcdUM2MjRcdUI5NThcdUFDMDAgXHVCQzFDXHVDMEREXHVENTg4XHVDMkI1XHVCMkM4XHVCMkU0LiBcdUM2NDBcdUM3N0NcdUI0REMgXHVDRTc0XHVCNERDIFx1QkIzOFx1Qzc5MFx1Qzc1OCBcdUQ1NjlcdUM5RDFcdUQ1NjlcdUM3NDQgXHVENDVDXHVENjA0XHVENTYwIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuCi0gICAgICAgIHNyYy1lbGVtZW50LjEgPSBzcmMtZWxlbWVudC4xOiAnJ2RlZmF1bHQnJyBcdUJDMEYgJydmaXhlZCcnIFx1QzE4RFx1QzEzMVx1Qzc0MCBcdUM2OTRcdUMxOEMgXHVDMTIwXHVDNUI4ICcnezB9JydcdUM1RDAgXHVENTY4XHVBRUQ4IFx1Qzg3NFx1QzdBQ1x1RDU2MCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiBcdUQ1NThcdUIwOThcdUI5Q0MgXHVDMEFDXHVDNkE5XHVENTU4XHVDMkVEXHVDMkRDXHVDNjI0LgotICAgICAgICBzcmMtZWxlbWVudC4yLjEgPSBzcmMtZWxlbWVudC4yLjE6ICdyZWYnIFx1QjYxMFx1QjI5NCAnbmFtZScgXHVDOTExIFx1RDU1OFx1QjA5OFx1QUMwMCBcdUI4NUNcdUNFRUMgXHVDNjk0XHVDMThDIFx1QzEyMFx1QzVCOFx1QzVEMCBcdUM4NzRcdUM3QUNcdUQ1NzRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBzcmMtZWxlbWVudC4yLjIgPSBzcmMtZWxlbWVudC4yLjI6ICcnezB9JydcdUM1RDAgJydyZWYnJyBcdUMxOERcdUMxMzFcdUM3NzQgXHVEM0VDXHVENTY4XHVCNDE4XHVDNUI0IFx1Qzc4OFx1QzczQ1x1QkJDMFx1Qjg1QyBcdUQ1NzRcdUIyRjkgXHVDRjU4XHVEMTUwXHVDRTIwXHVCMjk0IChhbm5vdGF0aW9uPylcdUFDRkMgXHVDNzdDXHVDRTU4XHVENTc0XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4gXHVENTU4XHVDOUMwXHVCOUNDICcnezF9JydcdUM3NzQoXHVBQzAwKSBcdUJDMUNcdUFDQUNcdUI0MThcdUM1QzhcdUMyQjVcdUIyQzhcdUIyRTQuCi0gICAgICAgIHNyYy1lbGVtZW50LjMgPSBzcmMtZWxlbWVudC4zOiAnJ3swfScnIFx1QzY5NFx1QzE4Q1x1QzVEMCAnJ3R5cGUnJyBcdUMxOERcdUMxMzFcdUFDRkMgJydhbm9ueW1vdXMgdHlwZScnIFx1RDU1OFx1QzcwNCBcdUMxOERcdUMxMzFcdUM3NzQgXHVCQUE4XHVCNDUwIFx1Qzc4OFx1QzJCNVx1QjJDOFx1QjJFNC4gXHVDNzc0IFx1QzkxMSBcdUQ1NThcdUIwOThcdUI5Q0MgXHVDNjk0XHVDMThDXHVDNUQwIFx1RDVDOFx1QzZBOVx1QjQyOVx1QjJDOFx1QjJFNC4KLSAgICAgICAgc3JjLWltcG9ydC4xLjEgPSBzcmMtaW1wb3J0LjEuMTogPGltcG9ydD4gXHVDNjk0XHVDMThDIFx1QzgxNVx1QkNGNCBcdUQ1NkRcdUJBQTlcdUM3NTggXHVCMTI0XHVDNzg0XHVDMkE0XHVEMzk4XHVDNzc0XHVDMkE0IFx1QzE4RFx1QzEzMSAnJ3swfScnXHVDNzQwKFx1QjI5NCkgXHVDODc0XHVDN0FDXHVENTU4XHVCMjk0IFx1QzJBNFx1RDBBNFx1QjlDOFx1Qzc1OCB0YXJnZXROYW1lc3BhY2VcdUM2NDAgXHVCMkVDXHVCNzdDXHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgc3JjLWltcG9ydC4xLjIgPSBzcmMtaW1wb3J0LjEuMjogXHVCMTI0XHVDNzg0XHVDMkE0XHVEMzk4XHVDNzc0XHVDMkE0IFx1QzE4RFx1QzEzMVx1Qzc3NCA8aW1wb3J0PiBcdUM2OTRcdUMxOEMgXHVDODE1XHVCQ0Y0IFx1RDU2RFx1QkFBOVx1QzVEMCBcdUM4NzRcdUM3QUNcdUQ1NThcdUM5QzAgXHVDNTRBXHVDNzQ0IFx1QUNCRFx1QzZCMCBcdUQzRUNcdUQ1NjhcdUQ1NThcdUFDRTAgXHVDNzg4XHVCMjk0IFx1QzJBNFx1RDBBNFx1QjlDOFx1QzVEMCB0YXJnZXROYW1lc3BhY2VcdUFDMDAgXHVDNzg4XHVDNUI0XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgc3JjLWltcG9ydC4yID0gc3JjLWltcG9ydC4yOiAnJ3swfScnIFx1QkIzOFx1QzExQ1x1Qzc1OCBcdUI4RThcdUQyQjggXHVDNjk0XHVDMThDXHVDNUQwIFx1QjEyNFx1Qzc4NFx1QzJBNFx1RDM5OFx1Qzc3NFx1QzJBNCBcdUM3NzRcdUI5ODQgJydodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYScnXHVDNjQwIFx1Qjg1Q1x1Q0VFQyBcdUM3NzRcdUI5ODQgJydzY2hlbWEnJ1x1QUMwMCBcdUM3ODhcdUM1QjRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBzcmMtaW1wb3J0LjMuMSA9IHNyYy1pbXBvcnQuMy4xOiA8aW1wb3J0PiBcdUM2OTRcdUMxOEMgXHVDODE1XHVCQ0Y0IFx1RDU2RFx1QkFBOVx1Qzc1OCBcdUIxMjRcdUM3ODRcdUMyQTRcdUQzOThcdUM3NzRcdUMyQTQgXHVDMThEXHVDMTMxICcnezB9JydcdUM3NzQoXHVBQzAwKSBcdUM3ODRcdUQzRUNcdUQyQjhcdUI0MUMgXHVCQjM4XHVDMTFDXHVDNzU4IHRhcmdldE5hbWVzcGFjZSBcdUMxOERcdUMxMzEgJyd7MX0nJ1x1QUNGQyhcdUM2NDApIFx1QjNEOVx1Qzc3Q1x1RDU3NFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIHNyYy1pbXBvcnQuMy4yID0gc3JjLWltcG9ydC4zLjI6IFx1QjEyNFx1Qzc4NFx1QzJBNFx1RDM5OFx1Qzc3NFx1QzJBNCBcdUMxOERcdUMxMzFcdUM3NzQgXHVDNUM2XHVCMjk0IDxpbXBvcnQ+IFx1QzY5NFx1QzE4QyBcdUM4MTVcdUJDRjQgXHVENTZEXHVCQUE5XHVDNzc0IFx1QkMxQ1x1QUNBQ1x1QjQxOFx1QzVDOFx1QzczQ1x1QkJDMFx1Qjg1QyBcdUM3ODRcdUQzRUNcdUQyQjhcdUI0MUMgXHVCQjM4XHVDMTFDXHVDNUQwXHVCMjk0IHRhcmdldE5hbWVzcGFjZSBcdUMxOERcdUMxMzFcdUM3NzQgXHVEM0VDXHVENTY4XHVCNDIwIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuIFx1RDU1OFx1QzlDMFx1QjlDQyBcdUM3ODRcdUQzRUNcdUQyQjhcdUI0MUMgXHVCQjM4XHVDMTFDXHVDNUQwXHVDMTFDIHRhcmdldE5hbWVzcGFjZSAnJ3sxfScnXHVDNzc0KFx1QUMwMCkgXHVCQzFDXHVBQ0FDXHVCNDE4XHVDNUM4XHVDMkI1XHVCMkM4XHVCMkU0LgotICAgICAgICBzcmMtaW5jbHVkZS4xID0gc3JjLWluY2x1ZGUuMTogJyd7MH0nJyBcdUJCMzhcdUMxMUNcdUM3NTggXHVCOEU4XHVEMkI4IFx1QzY5NFx1QzE4Q1x1QzVEMCBcdUIxMjRcdUM3ODRcdUMyQTRcdUQzOThcdUM3NzRcdUMyQTQgXHVDNzc0XHVCOTg0ICcnaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEnJ1x1QzY0MCBcdUI4NUNcdUNFRUMgXHVDNzc0XHVCOTg0ICcnc2NoZW1hJydcdUFDMDAgXHVDNzg4XHVDNUI0XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgc3JjLWluY2x1ZGUuMi4xID0gc3JjLWluY2x1ZGUuMi4xOiBcdUNDMzhcdUM4NzBcdUI0MUMgXHVDMkE0XHVEMEE0XHVCOUM4KFx1RDYwNFx1QzdBQycnezF9JycpXHVDNjQwIFx1RDNFQ1x1RDU2OFx1RDU1OFx1QjI5NCBcdUMyQTRcdUQwQTRcdUI5QzgoXHVENjA0XHVDN0FDICcnezB9JycpXHVDNzU4IHRhcmdldE5hbWVzcGFjZVx1QjI5NCBcdUIzRDlcdUM3N0NcdUQ1NzRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBzcmMtcmVkZWZpbmUuMiA9IHNyYy1yZWRlZmluZS4yOiAnJ3swfScnIFx1QkIzOFx1QzExQ1x1Qzc1OCBcdUI4RThcdUQyQjggXHVDNjk0XHVDMThDXHVDNUQwIFx1QjEyNFx1Qzc4NFx1QzJBNFx1RDM5OFx1Qzc3NFx1QzJBNCBcdUM3NzRcdUI5ODQgJydodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYScnXHVDNjQwIFx1Qjg1Q1x1Q0VFQyBcdUM3NzRcdUI5ODQgJydzY2hlbWEnJ1x1QUMwMCBcdUM3ODhcdUM1QjRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBzcmMtcmVkZWZpbmUuMy4xID0gc3JjLXJlZGVmaW5lLjMuMTogXHVDQzM4XHVDODcwXHVCNDFDIFx1QzJBNFx1RDBBNFx1QjlDOChcdUQ2MDRcdUM3QUMnJ3sxfScnKVx1QzY0MCBcdUM3QUNcdUM4MTVcdUM3NThcdUQ1NThcdUIyOTQgXHVDMkE0XHVEMEE0XHVCOUM4KFx1RDYwNFx1QzdBQyAnJ3swfScnKVx1Qzc1OCB0YXJnZXROYW1lc3BhY2VcdUIyOTQgXHVCM0Q5XHVDNzdDXHVENTc0XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgc3JjLXJlZGVmaW5lLjUuYS5hID0gc3JjLXJlZGVmaW5lLjUuYS5hOiA8c2ltcGxlVHlwZT5cdUM3NTggXHVCRTQ0XHVDOEZDXHVDMTFEIFx1RDU1OFx1QzcwNCBcdUQ1NkRcdUJBQTlcdUM3NDQgXHVDQzNFXHVDNzQ0IFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuIDxyZWRlZmluZT4gXHVDNjk0XHVDMThDXHVDNzU4IDxzaW1wbGVUeXBlPiBcdUQ1NThcdUM3MDQgXHVENTZEXHVCQUE5XHVDNUQwXHVCMjk0IFx1Qzc5MFx1QzJFMFx1Qzc0NCBcdUNDMzhcdUM4NzBcdUQ1NThcdUIyOTQgJ2Jhc2UnIFx1QzE4RFx1QzEzMVx1Qzc0NCBcdUFDMDBcdUM5QzQgPHJlc3RyaWN0aW9uPiBcdUM4ODVcdUMxOEQgXHVENTZEXHVCQUE5XHVDNzc0IFx1Qzc4OFx1QzVCNFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIHNyYy1yZWRlZmluZS41LmEuYiA9IHNyYy1yZWRlZmluZS41LmEuYjogJyd7MH0nJ1x1Qzc0MChcdUIyOTQpIFx1QzgwMVx1RDU2OVx1RDU1QyBcdUQ1NThcdUM3MDQgXHVDNjk0XHVDMThDXHVBQzAwIFx1QzU0NFx1QjJEOVx1QjJDOFx1QjJFNC4gPHJlZGVmaW5lPiBcdUM2OTRcdUMxOENcdUM3NTggPHNpbXBsZVR5cGU+IFx1RDU1OFx1QzcwNCBcdUQ1NkRcdUJBQTlcdUM1RDBcdUIyOTQgXHVDNzkwXHVDMkUwXHVDNzQ0IFx1Q0MzOFx1Qzg3MFx1RDU1OFx1QjI5NCAnJ2Jhc2UnJyBcdUMxOERcdUMxMzFcdUM3NDQgXHVBQzAwXHVDOUM0IDxyZXN0cmljdGlvbj4gXHVDODg1XHVDMThEIFx1RDU2RFx1QkFBOVx1Qzc3NCBcdUM3ODhcdUM1QjRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBzcmMtcmVkZWZpbmUuNS5hLmMgPSBzcmMtcmVkZWZpbmUuNS5hLmM6ICcnezB9JydcdUM1RDAgXHVDN0FDXHVDODE1XHVDNzU4XHVCNDFDIFx1QzY5NFx1QzE4QyAnJ3sxfScnXHVDNzQ0KFx1Qjk3QykgXHVDQzM4XHVDODcwXHVENTU4XHVCMjk0ICcnYmFzZScnIFx1QzE4RFx1QzEzMVx1Qzc3NCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuIDxyZWRlZmluZT4gXHVDNjk0XHVDMThDXHVDNzU4IDxzaW1wbGVUeXBlPiBcdUQ1NThcdUM3MDQgXHVENTZEXHVCQUE5XHVDNUQwXHVCMjk0IFx1Qzc5MFx1QzJFMFx1Qzc0NCBcdUNDMzhcdUM4NzBcdUQ1NThcdUIyOTQgJydiYXNlJycgXHVDMThEXHVDMTMxXHVDNzQ0IFx1QUMwMFx1QzlDNCA8cmVzdHJpY3Rpb24+IFx1Qzg4NVx1QzE4RCBcdUQ1NkRcdUJBQTlcdUM3NzQgXHVDNzg4XHVDNUI0XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgc3JjLXJlZGVmaW5lLjUuYi5hID0gc3JjLXJlZGVmaW5lLjUuYi5hOiA8Y29tcGxleFR5cGU+XHVDNzU4IFx1QkU0NFx1QzhGQ1x1QzExRCBcdUQ1NThcdUM3MDQgXHVENTZEXHVCQUE5XHVDNzQ0IFx1Q0MzRVx1Qzc0NCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiA8cmVkZWZpbmU+IFx1QzY5NFx1QzE4Q1x1Qzc1OCA8Y29tcGxleFR5cGU+IFx1RDU1OFx1QzcwNCBcdUQ1NkRcdUJBQTlcdUM1RDBcdUIyOTQgXHVDNzkwXHVDMkUwXHVDNzQ0IFx1Q0MzOFx1Qzg3MFx1RDU1OFx1QjI5NCAnYmFzZScgXHVDMThEXHVDMTMxXHVDNzQ0IFx1QUMwMFx1QzlDNCA8ZXh0ZW5zaW9uPiBcdUI2MTBcdUIyOTQgPHJlc3RyaWN0aW9uPiBcdUM4ODVcdUMxOEQgXHVENTZEXHVCQUE5XHVDNzc0IFx1Qzc4OFx1QzVCNFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIHNyYy1yZWRlZmluZS41LmIuYiA9IHNyYy1yZWRlZmluZS41LmIuYjogPGNvbXBsZXhUeXBlPlx1Qzc1OCBcdUJFNDRcdUM4RkNcdUMxMUQgXHVDRDVDXHVENTU4XHVDNzA0IFx1RDU2RFx1QkFBOVx1Qzc0NCBcdUNDM0VcdUM3NDQgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4gPHJlZGVmaW5lPiBcdUM2OTRcdUMxOENcdUM3NTggPGNvbXBsZXhUeXBlPiBcdUQ1NThcdUM3MDQgXHVENTZEXHVCQUE5XHVDNUQwXHVCMjk0IFx1Qzc5MFx1QzJFMFx1Qzc0NCBcdUNDMzhcdUM4NzBcdUQ1NThcdUIyOTQgJ2Jhc2UnIFx1QzE4RFx1QzEzMVx1Qzc0NCBcdUFDMDBcdUM5QzQgPGV4dGVuc2lvbj4gXHVCNjEwXHVCMjk0IDxyZXN0cmljdGlvbj4gXHVDODg1XHVDMThEIFx1RDU2RFx1QkFBOVx1Qzc3NCBcdUM3ODhcdUM1QjRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBzcmMtcmVkZWZpbmUuNS5iLmMgPSBzcmMtcmVkZWZpbmUuNS5iLmM6ICcnezB9JydcdUM3NDAoXHVCMjk0KSBcdUM4MDFcdUQ1NjlcdUQ1NUMgXHVDRDVDXHVENTU4XHVDNzA0IFx1QzY5NFx1QzE4Q1x1QUMwMCBcdUM1NDRcdUIyRDlcdUIyQzhcdUIyRTQuIDxyZWRlZmluZT4gXHVDNjk0XHVDMThDXHVDNzU4IDxjb21wbGV4VHlwZT4gXHVENTU4XHVDNzA0IFx1RDU2RFx1QkFBOVx1QzVEMFx1QjI5NCBcdUM3OTBcdUMyRTBcdUM3NDQgXHVDQzM4XHVDODcwXHVENTU4XHVCMjk0ICcnYmFzZScnIFx1QzE4RFx1QzEzMVx1Qzc0NCBcdUFDMDBcdUM5QzQgPGV4dGVuc2lvbj4gXHVCNjEwXHVCMjk0IDxyZXN0cmljdGlvbj4gXHVDODg1XHVDMThEIFx1RDU2RFx1QkFBOVx1Qzc3NCBcdUM3ODhcdUM1QjRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBzcmMtcmVkZWZpbmUuNS5iLmQgPSBzcmMtcmVkZWZpbmUuNS5iLmQ6ICcnezB9JydcdUM1RDAgXHVDN0FDXHVDODE1XHVDNzU4XHVCNDFDIFx1QzY5NFx1QzE4QyAnJ3sxfScnXHVDNzQ0KFx1Qjk3QykgXHVDQzM4XHVDODcwXHVENTU4XHVCMjk0ICcnYmFzZScnIFx1QzE4RFx1QzEzMVx1Qzc3NCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuIDxyZWRlZmluZT4gXHVDNjk0XHVDMThDXHVDNzU4IDxjb21wbGV4VHlwZT4gXHVENTU4XHVDNzA0IFx1RDU2RFx1QkFBOVx1QzVEMFx1QjI5NCBcdUM3OTBcdUMyRTBcdUM3NDQgXHVDQzM4XHVDODcwXHVENTU4XHVCMjk0ICcnYmFzZScnIFx1QzE4RFx1QzEzMVx1Qzc0NCBcdUFDMDBcdUM5QzQgPGV4dGVuc2lvbj4gXHVCNjEwXHVCMjk0IDxyZXN0cmljdGlvbj4gXHVDODg1XHVDMThEIFx1RDU2RFx1QkFBOVx1Qzc3NCBcdUM3ODhcdUM1QjRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBzcmMtcmVkZWZpbmUuNi4xLjEgPSBzcmMtcmVkZWZpbmUuNi4xLjE6IDxyZWRlZmluZT4gXHVDNjk0XHVDMThDXHVDNzU4IFx1QURGOFx1QjhGOSBcdUQ1NThcdUM3MDRcdUM1RDAgXHVDNzkwXHVDMkUwXHVDNzQ0IFx1Q0MzOFx1Qzg3MFx1RDU1OFx1QjI5NCBcdUFERjhcdUI4RjlcdUM3NzQgXHVEM0VDXHVENTY4XHVCNDE4XHVDNUI0IFx1Qzc4OFx1Qzc0NCBcdUFDQkRcdUM2QjAgXHVDODE1XHVENjU1XHVENzg4IDFcdUM3NzRcdUM1QjRcdUM1N0MgXHVDMEFDXHVDNkE5XHVCNDE4XHVDNUI0XHVDNTdDIFx1RDU1OFx1QzlDMFx1QjlDQyAnJ3swfScnXHVDNzc0KFx1QUMwMCkgXHVDMEFDXHVDNkE5XHVCNDI5XHVCMkM4XHVCMkU0LgotICAgICAgICBzcmMtcmVkZWZpbmUuNi4xLjIgPSBzcmMtcmVkZWZpbmUuNi4xLjI6IFx1QzdBQ1x1QzgxNVx1Qzc1OFx1RDU1OFx1QjgyNFx1QjI5NCBcdUFERjhcdUI4RjlcdUM1RDAgXHVCMzAwXHVENTVDIFx1Q0MzOFx1Qzg3MFx1Qjk3QyBcdUQzRUNcdUQ1NjhcdUQ1NThcdUIyOTQgJyd7MH0nJyBcdUFERjhcdUI4RjlcdUM1RDBcdUIyOTQgJydtaW5PY2N1cnMnJyA9ICcnbWF4T2NjdXJzJycgPSAxXHVDNzc0IFx1QzBBQ1x1QzZBOVx1QjQxOFx1QzVCNFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIHNyYy1yZWRlZmluZS42LjIuMSA9IHNyYy1yZWRlZmluZS42LjIuMTogXHVDN0FDXHVDODE1XHVDNzU4XHVCNDFDIFx1QzJBNFx1RDBBNFx1QjlDOFx1QzVEMCBcdUM3NzRcdUI5ODRcdUM3NzQgJyd7MH0nJ1x1Qzc3OCBcdUFERjhcdUI4RjlcdUM3NzQgXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LgotICAgICAgICBzcmMtcmVkZWZpbmUuNi4yLjIgPSBzcmMtcmVkZWZpbmUuNi4yLjI6ICcnezB9JycgXHVBREY4XHVCOEY5XHVDNzQwIFx1QzdBQ1x1QzgxNVx1Qzc1OFx1RDU1OFx1QjI5NCBcdUFERjhcdUI4RjlcdUM3NDQgXHVDODFDXHVCMzAwXHVCODVDIFx1QzgxQ1x1RDU1Q1x1RDU1OFx1QzlDMCBcdUM1NEFcdUMyQjVcdUIyQzhcdUIyRTQuIFx1QzcwNFx1QkMxOFx1QjQxQyBcdUM4MUNcdUM1N0QgXHVDODcwXHVBQzc0OiAnJ3sxfScnLgotICAgICAgICBzcmMtcmVkZWZpbmUuNy4xID0gc3JjLXJlZGVmaW5lLjcuMTogPHJlZGVmaW5lPiBcdUM2OTRcdUMxOENcdUM3NTggYXR0cmlidXRlR3JvdXAgXHVENTU4XHVDNzA0XHVDNUQwIFx1Qzc5MFx1QzJFMFx1Qzc0NCBcdUNDMzhcdUM4NzBcdUQ1NThcdUIyOTQgYXR0cmlidXRlR3JvdXBcdUM3NzQgXHVEM0VDXHVENTY4XHVCNDE4XHVDNUI0IFx1Qzc4OFx1Qzc0NCBcdUFDQkRcdUM2QjAgXHVDODE1XHVENjU1XHVENzg4IDFcdUM3NzQgXHVDMEFDXHVDNkE5XHVCNDE4XHVDNUI0XHVDNTdDIFx1RDU1OFx1QzlDMFx1QjlDQyB7MH1cdUM3NzQoXHVBQzAwKSBcdUMwQUNcdUM2QTlcdUI0MjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIHNyYy1yZWRlZmluZS43LjIuMSA9IHNyYy1yZWRlZmluZS43LjIuMTogXHVDN0FDXHVDODE1XHVDNzU4XHVCNDFDIFx1QzJBNFx1RDBBNFx1QjlDOFx1QzVEMCBcdUM3NzRcdUI5ODRcdUM3NzQgJyd7MH0nJ1x1Qzc3OCBhdHRyaWJ1dGVHcm91cFx1Qzc3NCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuCi0gICAgICAgIHNyYy1yZWRlZmluZS43LjIuMiA9IHNyYy1yZWRlZmluZS43LjIuMjogQXR0cmlidXRlR3JvdXAgJyd7MH0nJ1x1Qzc0MChcdUIyOTQpIFx1QzdBQ1x1QzgxNVx1Qzc1OFx1RDU1OFx1QjI5NCBhdHRyaWJ1dGVHcm91cFx1Qzc0NCBcdUM4MUNcdUIzMDBcdUI4NUMgXHVDODFDXHVENTVDXHVENTU4XHVDOUMwIFx1QzU0QVx1QzJCNVx1QjJDOFx1QjJFNC4gXHVDNzA0XHVCQzE4XHVCNDFDIFx1QzgxQ1x1QzU3RCBcdUM4NzBcdUFDNzQ6ICcnezF9JycuCi0gICAgICAgIHNyYy1yZXNvbHZlID0gc3JjLXJlc29sdmU6ICcnezB9JycgXHVDNzc0XHVCOTg0XHVDNzQ0ICcnezF9JycgXHVBRDZDXHVDMTMxIFx1QzY5NFx1QzE4Q1x1Qjg1QyBcdUJEODRcdUMxMURcdUQ1NjAgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4KLSAgICAgICAgc3JjLXJlc29sdmUuNC4xID0gc3JjLXJlc29sdmUuNC4xOiAnJ3syfScnIFx1QUQ2Q1x1QzEzMSBcdUM2OTRcdUMxOENcdUI5N0MgXHVCRDg0XHVDMTFEXHVENTU4XHVCMjk0IFx1QzkxMSBcdUM2MjRcdUI5NThcdUFDMDAgXHVCQzFDXHVDMEREXHVENTg4XHVDMkI1XHVCMkM4XHVCMkU0LiAnJ3syfScnXHVDNUQwIFx1QjEyNFx1Qzc4NFx1QzJBNFx1RDM5OFx1Qzc3NFx1QzJBNFx1QUMwMCBcdUM1QzZcdUIyOTQgXHVBQzgzXHVDNzNDXHVCODVDIFx1RDY1NVx1Qzc3OFx1QjQxOFx1QzVDOFx1QzlDMFx1QjlDQyBcdUMyQTRcdUQwQTRcdUI5QzggXHVCQjM4XHVDMTFDICcnezB9JydcdUM1RDBcdUMxMUMgXHVCMzAwXHVDMEMxIFx1QjEyNFx1Qzc4NFx1QzJBNFx1RDM5OFx1Qzc3NFx1QzJBNFx1QUMwMCBcdUM1QzZcdUIyOTQgXHVBRDZDXHVDMTMxIFx1QzY5NFx1QzE4Q1x1Qjk3QyBcdUNDMzhcdUM4NzBcdUQ1NjAgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4gJyd7Mn0nJ1x1QzVEMCBcdUIxMjRcdUM3ODRcdUMyQTRcdUQzOThcdUM3NzRcdUMyQTRcdUFDMDAgXHVDNzg4XHVDNUI0XHVDNTdDIFx1RDU2MCBcdUFDQkRcdUM2QjAgXHVDODExXHVCNDUwXHVDNUI0XHVCOTdDIFx1QzgxQ1x1QUNGNVx1RDU3NFx1QzU3QyBcdUQ1NjAgXHVDMjE4IFx1Qzc4OFx1QzJCNVx1QjJDOFx1QjJFNC4gJyd7Mn0nJ1x1QzVEMCBcdUIxMjRcdUM3ODRcdUMyQTRcdUQzOThcdUM3NzRcdUMyQTRcdUFDMDAgXHVDNUM2XHVDNUI0XHVDNTdDIFx1RDU2MCBcdUFDQkRcdUM2QjAgIm5hbWVzcGFjZSIgXHVDMThEXHVDMTMxIFx1QzVDNlx1Qzc3NCAnJ2ltcG9ydCcnXHVCOTdDICcnezB9JydcdUM1RDAgXHVDRDk0XHVBQzAwXHVENTc0XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgc3JjLXJlc29sdmUuNC4yID0gc3JjLXJlc29sdmUuNC4yOiAnJ3syfScnIFx1QUQ2Q1x1QzEzMSBcdUM2OTRcdUMxOENcdUI5N0MgXHVCRDg0XHVDMTFEXHVENTU4XHVCMjk0IFx1QzkxMSBcdUM2MjRcdUI5NThcdUFDMDAgXHVCQzFDXHVDMEREXHVENTg4XHVDMkI1XHVCMkM4XHVCMkU0LiAnJ3syfScnXHVDNzc0KFx1QUMwMCkgJyd7MX0nJyBcdUIxMjRcdUM3ODRcdUMyQTRcdUQzOThcdUM3NzRcdUMyQTRcdUM1RDAgXHVDNzg4XHVCMjk0IFx1QUM4M1x1QzczQ1x1Qjg1QyBcdUQ2NTVcdUM3NzhcdUI0MThcdUM1QzhcdUM5QzBcdUI5Q0MgXHVDMkE0XHVEMEE0XHVCOUM4IFx1QkIzOFx1QzExQyAnJ3swfScnXHVDNUQwXHVDMTFDIFx1Qzc3NCBcdUIxMjRcdUM3ODRcdUMyQTRcdUQzOThcdUM3NzRcdUMyQTRcdUM3NTggXHVBRDZDXHVDMTMxIFx1QzY5NFx1QzE4Q1x1Qjk3QyBcdUNDMzhcdUM4NzBcdUQ1NjAgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4gXHVDNjJDXHVCQzE0XHVCOTc0XHVDOUMwIFx1QzU0QVx1Qzc0MCBcdUIxMjRcdUM3ODRcdUMyQTRcdUQzOThcdUM3NzRcdUMyQTRcdUM3N0MgXHVBQ0JEXHVDNkIwIFx1QzgxMVx1QjQ1MFx1QzVCNFx1Qzc3OCAnJ3syfScnXHVDNzQ0KFx1Qjk3QykgXHVCQ0MwXHVBQ0JEXHVENTc0XHVDNTdDIFx1RDU2MCBcdUMyMTggXHVDNzg4XHVDMkI1XHVCMkM4XHVCMkU0LiBcdUM2MkNcdUJDMTRcdUI5NzggXHVCMTI0XHVDNzg0XHVDMkE0XHVEMzk4XHVDNzc0XHVDMkE0XHVDNzdDIFx1QUNCRFx1QzZCMCBcdUM4MDFcdUQ1NjlcdUQ1NUMgJydpbXBvcnQnJyBcdUQwRENcdUFERjhcdUI5N0MgJyd7MH0nJ1x1QzVEMCBcdUNEOTRcdUFDMDBcdUQ1NzRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBzcmMtc2ltcGxlLXR5cGUuMi5hID0gc3JjLXNpbXBsZS10eXBlLjIuYTogXHVENTc0XHVCMkY5IFtjaGlsZHJlbl0gXHVDOTExIGJhc2UgW2F0dHJpYnV0ZV1cdUM2NDAgPHNpbXBsZVR5cGU+IFx1QzY5NFx1QzE4Q1x1QUMwMCBcdUJBQThcdUI0NTAgXHVDNzg4XHVCMjk0IDxyZXN0cmljdGlvbj4gXHVDNjk0XHVDMThDXHVBQzAwIFx1QkMxQ1x1QUNBQ1x1QjQxOFx1QzVDOFx1QzJCNVx1QjJDOFx1QjJFNC4gXHVENTU4XHVCMDk4XHVCOUNDIFx1RDVDOFx1QzZBOVx1QjQyOVx1QjJDOFx1QjJFNC4KLSAgICAgICAgc3JjLXNpbXBsZS10eXBlLjIuYiA9IHNyYy1zaW1wbGUtdHlwZS4yLmI6IFx1RDU3NFx1QjJGOSBbY2hpbGRyZW5dIFx1QzkxMSBiYXNlIFthdHRyaWJ1dGVdXHVDNjQwIDxzaW1wbGVUeXBlPiBcdUM2OTRcdUMxOENcdUFDMDAgXHVCQUE4XHVCNDUwIFx1QzVDNlx1QjI5NCA8cmVzdHJpY3Rpb24+IFx1QzY5NFx1QzE4Q1x1QUMwMCBcdUJDMUNcdUFDQUNcdUI0MThcdUM1QzhcdUMyQjVcdUIyQzhcdUIyRTQuIFx1RDU1OFx1QjA5OFx1QjlDQyBcdUQ1NDRcdUM2OTRcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIHNyYy1zaW1wbGUtdHlwZS4zLmEgPSBzcmMtc2ltcGxlLXR5cGUuMy5hOiBcdUQ1NzRcdUIyRjkgW2NoaWxkcmVuXSBcdUM5MTEgaXRlbVR5cGUgW2F0dHJpYnV0ZV1cdUM2NDAgPHNpbXBsZVR5cGU+IFx1QzY5NFx1QzE4Q1x1QUMwMCBcdUJBQThcdUI0NTAgXHVDNzg4XHVCMjk0IDxsaXN0PiBcdUM2OTRcdUMxOENcdUFDMDAgXHVCQzFDXHVBQ0FDXHVCNDE4XHVDNUM4XHVDMkI1XHVCMkM4XHVCMkU0LiBcdUQ1NThcdUIwOThcdUI5Q0MgXHVENUM4XHVDNkE5XHVCNDI5XHVCMkM4XHVCMkU0LgotICAgICAgICBzcmMtc2ltcGxlLXR5cGUuMy5iID0gc3JjLXNpbXBsZS10eXBlLjMuYjogXHVENTc0XHVCMkY5IFtjaGlsZHJlbl0gXHVDOTExIGl0ZW1UeXBlIFthdHRyaWJ1dGVdXHVDNjQwIDxzaW1wbGVUeXBlPiBcdUM2OTRcdUMxOENcdUFDMDAgXHVCQUE4XHVCNDUwIFx1QzVDNlx1QjI5NCA8bGlzdD4gXHVDNjk0XHVDMThDXHVBQzAwIFx1QkMxQ1x1QUNBQ1x1QjQxOFx1QzVDOFx1QzJCNVx1QjJDOFx1QjJFNC4gXHVENTU4XHVCMDk4XHVCOUNDIFx1RDU0NFx1QzY5NFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgc3JjLXNpbmdsZS1mYWNldC12YWx1ZSA9IHNyYy1zaW5nbGUtZmFjZXQtdmFsdWU6ICcnezB9JycgXHVCQTc0XHVDNzc0IFx1QjQ1MCBcdUJDODggXHVDNzc0XHVDMEMxIFx1QzgxNVx1Qzc1OFx1QjQxOFx1QzVDOFx1QzJCNVx1QjJDOFx1QjJFNC4KLSAgICAgICAgc3JjLXVuaW9uLW1lbWJlclR5cGVzLW9yLXNpbXBsZVR5cGVzID0gc3JjLXVuaW9uLW1lbWJlclR5cGVzLW9yLXNpbXBsZVR5cGVzOiA8dW5pb24+IFx1QzY5NFx1QzE4Q1x1QzVEMFx1QjI5NCBcdUQ1NzRcdUIyRjkgW2NoaWxkcmVuXSBcdUM5MTEgXHVCRTQ0XHVDNUI0IFx1Qzc4OFx1QzlDMCBcdUM1NEFcdUM3NDAgbWVtYmVyVHlwZXMgW2F0dHJpYnV0ZV0gXHVCNjEwXHVCMjk0IFx1RDU1OFx1QjA5OCBcdUM3NzRcdUMwQzFcdUM3NTggPHNpbXBsZVR5cGU+IFx1QzY5NFx1QzE4Q1x1QUMwMCBcdUM3ODhcdUM1QjRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotCi0jY29uc3RyYWludCB2YWxpZCAoMy5YLjYpCi0KLSAgICAgICAgYWctcHJvcHMtY29ycmVjdC4yID0gYWctcHJvcHMtY29ycmVjdC4yOiBcdUMxOERcdUMxMzEgXHVBREY4XHVCOEY5ICcnezB9JydcdUM1RDAgXHVCMzAwXHVENTc0IFx1QzYyNFx1Qjk1OFx1QUMwMCBcdUJDMUNcdUMwRERcdUQ1ODhcdUMyQjVcdUIyQzhcdUIyRTQuIFx1Qzc3NFx1Qjk4NCBcdUJDMEYgXHVCMzAwXHVDMEMxIFx1QjEyNFx1Qzc4NFx1QzJBNFx1RDM5OFx1Qzc3NFx1QzJBNFx1QUMwMCBcdUIzRDlcdUM3N0NcdUQ1NUMgXHVDOTExXHVCQ0Y1IFx1QzE4RFx1QzEzMSBcdUMwQUNcdUM2QTlcdUM3NzQgXHVDOUMwXHVDODE1XHVCNDE4XHVDNUM4XHVDMkI1XHVCMkM4XHVCMkU0LiBcdUM5MTFcdUJDRjUgXHVDMThEXHVDMTMxIFx1QzBBQ1x1QzZBOVx1Qzc1OCBcdUM3NzRcdUI5ODRcdUM3NDAgJyd7MX0nJ1x1Qzc4NVx1QjJDOFx1QjJFNC4KLSAgICAgICAgYWctcHJvcHMtY29ycmVjdC4zID0gYWctcHJvcHMtY29ycmVjdC4zOiBcdUMxOERcdUMxMzEgXHVBREY4XHVCOEY5ICcnezB9JydcdUM1RDAgXHVCMzAwXHVENTc0IFx1QzYyNFx1Qjk1OFx1QUMwMCBcdUJDMUNcdUMwRERcdUQ1ODhcdUMyQjVcdUIyQzhcdUIyRTQuIFx1QjQ1MCBcdUFDMUNcdUM3NTggXHVDMThEXHVDMTMxIFx1QzEyMFx1QzVCOCAnJ3sxfScnIFx1QkMwRiAnJ3syfScnXHVDNUQwIElEXHVDNUQwXHVDMTFDIFx1RDMwQ1x1QzBERFx1QjQxQyBcdUM3MjBcdUQ2MTVcdUM3NzQgXHVDNzg4XHVDMkI1XHVCMkM4XHVCMkU0LgotICAgICAgICBhLXByb3BzLWNvcnJlY3QuMiA9IGEtcHJvcHMtY29ycmVjdC4yOiAnJ3swfScnIFx1QzE4RFx1QzEzMVx1Qzc1OCBcdUFDMTIgXHVDODFDXHVDNTdEIFx1Qzg3MFx1QUM3NCBcdUFDMTIgJyd7MX0nJ1x1Qzc3NChcdUFDMDApIFx1QkQ4MFx1QzgwMVx1RDU2OVx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgYS1wcm9wcy1jb3JyZWN0LjMgPSBhLXByb3BzLWNvcnJlY3QuMzogXHVDMThEXHVDMTMxXHVDNzU4ICd7J3R5cGUgZGVmaW5pdGlvbid9J1x1Qzc3NCBJRFx1Qzc3NFx1QUM3MFx1QjA5OCBJRFx1QzVEMFx1QzExQyBcdUQzMENcdUMwRERcdUI0MUMgXHVBQzgzXHVDNzc0XHVCQkMwXHVCODVDICcnezB9JycgXHVDMThEXHVDMTMxXHVDNzQwICcnZml4ZWQnJyBcdUI2MTBcdUIyOTQgJydkZWZhdWx0JydcdUI5N0MgXHVDMEFDXHVDNkE5XHVENTYwIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuCi0gICAgICAgIGF1LXByb3BzLWNvcnJlY3QuMiA9IGF1LXByb3BzLWNvcnJlY3QuMjogJyd7MH0nJ1x1Qzc1OCBcdUMxOERcdUMxMzEgXHVDMTIwXHVDNUI4XHVDNUQwXHVDMTFDIFx1QUNFMFx1QzgxNVx1QjQxQyBcdUFDMTIgJyd7MX0nJ1x1Qzc3NChcdUFDMDApIFx1QzlDMFx1QzgxNVx1QjQxOFx1QzVDOFx1QzJCNVx1QjJDOFx1QjJFNC4gXHVCNTMwXHVCNzdDXHVDMTFDICcnezB9JydcdUM3NDQoXHVCOTdDKSBcdUNDMzhcdUM4NzBcdUQ1NThcdUIyOTQgXHVDMThEXHVDMTMxIFx1QzBBQ1x1QzZBOVx1QzVEMFx1QjNDNCAneyd2YWx1ZSBjb25zdHJhaW50J30nXHVBQzAwIFx1Qzc4OFx1Qzc0NCBcdUFDQkRcdUM2QjAgXHVBQ0UwXHVDODE1XHVCNDE4XHVDNUI0XHVDNTdDIFx1RDU1OFx1QkE3MCBcdUFDMTJcdUM3NDAgJyd7MX0nJ1x1Qzc3NFx1QzVCNFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIGNvcy1hbGwtbGltaXRlZC4xLjIgPSBjb3MtYWxsLWxpbWl0ZWQuMS4yOiAnYWxsJyBcdUJBQThcdUIzNzggXHVBREY4XHVCOEY5XHVDNzc0ICd7J21pbiBvY2N1cnMnfScgPSAneydtYXggb2NjdXJzJ30nID0gMVx1Qzc3OCBcdUM4NzBcdUFDMDFcdUM1RDAgXHVCMDk4XHVEMEMwXHVCMDk4XHVDNTdDIFx1RDU1OFx1QkE3MCBcdUQ1NzRcdUIyRjkgXHVDODcwXHVBQzAxXHVDNzQwIFx1QkNGNVx1RDU2OSBcdUM3MjBcdUQ2MTUgXHVDODE1XHVDNzU4XHVDNzU4ICd7J2NvbnRlbnQgdHlwZSd9J1x1Qzc0NCBcdUFENkNcdUMxMzFcdUQ1NThcdUIyOTQgXHVDMzBEXHVDNzU4IFx1Qzc3Q1x1QkQ4MFx1QzVFQ1x1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIGNvcy1hbGwtbGltaXRlZC4yID0gY29zLWFsbC1saW1pdGVkLjI6ICcnYWxsJycgXHVCQUE4XHVCMzc4IFx1QURGOFx1QjhGOVx1QzVEMCBcdUQzRUNcdUQ1NjhcdUI0MUMgXHVDNjk0XHVDMThDXHVDNzU4ICd7J21heCBvY2N1cnMnfSdcdUIyOTQgMCBcdUI2MTBcdUIyOTQgMVx1Qzc3NFx1QzVCNFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuICcnezF9JycgXHVDNjk0XHVDMThDXHVDNUQwIFx1QjMwMFx1RDU1QyAnJ3swfScnIFx1QUMxMlx1Qzc3NCBcdUJEODBcdUM4MDFcdUQ1NjlcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIGNvcy1hcHBsaWNhYmxlLWZhY2V0cyA9IGNvcy1hcHBsaWNhYmxlLWZhY2V0czogezF9IFx1QzcyMFx1RDYxNVx1QzVEMFx1QzExQ1x1QjI5NCAnJ3swfScnIFx1QkE3NFx1Qzc3NCBcdUQ1QzhcdUM2QTlcdUI0MThcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0LgotICAgICAgICBjb3MtY3QtZXh0ZW5kcy4xLjEgPSBjb3MtY3QtZXh0ZW5kcy4xLjE6ICcnezB9JycgXHVDNzIwXHVENjE1XHVDNzQwICcnezF9JycgXHVDNzIwXHVENjE1XHVDNUQwXHVDMTFDIFx1RDY1NVx1QzdBNVx1QzVEMCBcdUM3NThcdUQ1NzQgXHVEMzBDXHVDMEREXHVCNDE4XHVDNUM4XHVDOUMwXHVCOUNDICcnezF9JydcdUM3NTggJydmaW5hbCcnIFx1QzE4RFx1QzEzMVx1Qzc0MCBcdUQ2NTVcdUM3QTVcdUM1RDAgXHVDNzU4XHVENTVDIFx1RDMwQ1x1QzBERFx1Qzc0NCBcdUFFMDhcdUM5QzBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIGNvcy1jdC1leHRlbmRzLjEuNC4zLjIuMi4xLmEgPSBjb3MtY3QtZXh0ZW5kcy4xLjQuMy4yLjIuMS5hOiBcdUQzMENcdUMwRERcdUI0MUMgXHVDNzIwXHVENjE1XHVBQ0ZDIFx1RDU3NFx1QjJGOSBcdUFFMzBcdUJDRjggXHVDNzIwXHVENjE1XHVDNzU4IFx1Q0Y1OFx1RDE1MFx1Q0UyMCBcdUM3MjBcdUQ2MTVcdUM3NDAgXHVCQUE4XHVCNDUwIFx1RDYzQ1x1RDU2OVx1QjQxOFx1QUM3MFx1QjA5OCBcdUJBQThcdUI0NTAgXHVDNjk0XHVDMThDIFx1QzgwNFx1QzZBOVx1Qzc3NFx1QzVCNFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuICcnezB9JycgXHVDNzIwXHVENjE1XHVDNzQwIFx1QzY5NFx1QzE4QyBcdUM4MDRcdUM2QTlcdUM3NzRcdUM5QzBcdUI5Q0MgXHVENTc0XHVCMkY5IFx1QUUzMFx1QkNGOCBcdUM3MjBcdUQ2MTVcdUM3NDAgXHVDNjk0XHVDMThDIFx1QzgwNFx1QzZBOVx1Qzc3NCBcdUM1NDRcdUIyRDlcdUIyQzhcdUIyRTQuCi0gICAgICAgIGNvcy1jdC1leHRlbmRzLjEuNC4zLjIuMi4xLmIgPSBjb3MtY3QtZXh0ZW5kcy4xLjQuMy4yLjIuMS5iOiBcdUQzMENcdUMwRERcdUI0MUMgXHVDNzIwXHVENjE1XHVBQ0ZDIFx1RDU3NFx1QjJGOSBcdUFFMzBcdUJDRjggXHVDNzIwXHVENjE1XHVDNzU4IFx1Q0Y1OFx1RDE1MFx1Q0UyMCBcdUM3MjBcdUQ2MTVcdUM3NDAgXHVCQUE4XHVCNDUwIFx1RDYzQ1x1RDU2OVx1QjQxOFx1QUM3MFx1QjA5OCBcdUJBQThcdUI0NTAgXHVDNjk0XHVDMThDIFx1QzgwNFx1QzZBOVx1Qzc3NFx1QzVCNFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuICcnezB9JycgXHVDNzIwXHVENjE1XHVDNzQwIFx1RDYzQ1x1RDU2OVx1QjQxOFx1QzVCNCBcdUM3ODhcdUM5QzBcdUI5Q0MgXHVENTc0XHVCMkY5IFx1QUUzMFx1QkNGOCBcdUM3MjBcdUQ2MTVcdUM3NDAgXHVENjNDXHVENTY5XHVCNDE4XHVDNUI0IFx1Qzc4OFx1QzlDMCBcdUM1NEFcdUMyQjVcdUIyQzhcdUIyRTQuCi0gICAgICAgIGNvcy1lbGVtZW50LWNvbnNpc3RlbnQgPSBjb3MtZWxlbWVudC1jb25zaXN0ZW50OiAnJ3swfScnIFx1QzcyMFx1RDYxNVx1QzVEMCBcdUIzMDBcdUQ1NzQgXHVDNjI0XHVCOTU4XHVBQzAwIFx1QkMxQ1x1QzBERFx1RDU4OFx1QzJCNVx1QjJDOFx1QjJFNC4gXHVDNzc0XHVCOTg0XHVDNzc0ICcnezF9JydcdUM3NzRcdUJBNzAgXHVDNzIwXHVENjE1XHVDNzc0IFx1QjJFNFx1Qjk3OCBcdUM1RUNcdUI3RUMgXHVDNjk0XHVDMThDXHVBQzAwIFx1QkFBOFx1QjM3OCBcdUFERjhcdUI4RjlcdUM1RDAgXHVCMDk4XHVEMEMwXHVCMEE5XHVCMkM4XHVCMkU0LgotICAgICAgICBjb3MtbGlzdC1vZi1hdG9taWMgPSBjb3MtbGlzdC1vZi1hdG9taWM6IFx1QkFBOVx1Qjg1RCBcdUM3MjBcdUQ2MTUgJyd7MH0nJ1x1Qzc1OCBcdUM4MTVcdUM3NThcdUM1RDBcdUMxMUMgJyd7MX0nJyBcdUM3MjBcdUQ2MTVcdUM3NDAgXHVBRTMwXHVCQ0Y4IFx1QjJFOFx1QzcwNFx1QUMwMCBcdUM1NDRcdUIyQzhcdUJCQzBcdUI4NUMgXHVCRDgwXHVDODAxXHVENTY5XHVENTVDIFx1QkFBOVx1Qjg1RCBcdUM2OTRcdUMxOEMgXHVDNzIwXHVENjE1XHVDNzg1XHVCMkM4XHVCMkU0LiAnJ3sxfScnXHVDNzc0KFx1QUMwMCkgXHVCQUE5XHVCODVEIFx1QzcyMFx1RDYxNVx1Qzc3NFx1QUM3MFx1QjA5OCBcdUJBQTlcdUI4NURcdUM3NDQgXHVEM0VDXHVENTY4XHVENTU4XHVCMjk0IFx1RDU2OVx1QzlEMVx1RDU2OSBcdUM3MjBcdUQ2MTVcdUM3ODVcdUIyQzhcdUIyRTQuCi0gICAgICAgIGNvcy1ub25hbWJpZyA9IGNvcy1ub25hbWJpZzogezB9IFx1QkMwRiB7MX0oXHVCNjEwXHVCMjk0IFx1RDU3NFx1QjJGOSBcdUIzMDBcdUNDQjQgXHVBREY4XHVCOEY5XHVDNzU4IFx1QzY5NFx1QzE4QylcdUM3NzQoXHVBQzAwKSAiVW5pcXVlIFBhcnRpY2xlIEF0dHJpYnV0aW9uIlx1Qzc0NCBcdUM3MDRcdUJDMThcdUQ1NjlcdUIyQzhcdUIyRTQuIFx1Qzc3NCBcdUMyQTRcdUQwQTRcdUI5QzhcdUM1RDAgXHVCMzAwXHVENTVDIFx1QUM4MFx1Qzk5RCBcdUM5MTEgXHVDNzc0XHVCN0VDXHVENTVDIFx1QjQ1MCBcdUM4NzBcdUFDMDFcdUM3NzQgXHVCQUE4XHVENjM4XHVENTc0XHVDOUM4IFx1QzIxOCBcdUM3ODhcdUMyQjVcdUIyQzhcdUIyRTQuCi0gICAgICAgIGNvcy1wYXJ0aWNsZS1yZXN0cmljdC5hID0gY29zLXBhcnRpY2xlLXJlc3RyaWN0LmE6IFx1RDMwQ1x1QzBERFx1QjQxQyBcdUM4NzBcdUFDMDFcdUM3NzQgXHVCRTQ0XHVDNUI0IFx1Qzc4OFx1QzczQ1x1QkJDMFx1Qjg1QyBcdUFFMzBcdUJDRjggXHVDODcwXHVBQzAxXHVDNzQ0IFx1QkU0NFx1QzZCOCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LgotICAgICAgICBjb3MtcGFydGljbGUtcmVzdHJpY3QuYiA9IGNvcy1wYXJ0aWNsZS1yZXN0cmljdC5iOiBcdUFFMzBcdUJDRjggXHVDODcwXHVBQzAxXHVDNzQwIFx1QkU0NFx1QzVCNCBcdUM3ODhcdUM5QzBcdUI5Q0MgXHVEMzBDXHVDMEREXHVCNDFDIFx1Qzg3MFx1QUMwMVx1Qzc0MCBcdUJFNDRcdUM1QjQgXHVDNzg4XHVDOUMwIFx1QzU0QVx1QzJCNVx1QjJDOFx1QjJFNC4KLSAgICAgICAgY29zLXBhcnRpY2xlLXJlc3RyaWN0LjIgPSBjb3MtcGFydGljbGUtcmVzdHJpY3QuMjogXHVBRTA4XHVDOUMwXHVCNDFDIFx1Qzg3MFx1QUMwMSBcdUM4MUNcdUQ1NUMgXHVDMEFDXHVENTZEOiAnJ3swfScnLgotICAgICAgICBjb3Mtc3QtcmVzdHJpY3RzLjEuMSA9IGNvcy1zdC1yZXN0cmljdHMuMS4xOiAnJ3sxfScnIFx1QzcyMFx1RDYxNVx1Qzc3NCBcdUFFMzBcdUJDRjggXHVCMkU4XHVDNzA0XHVDNzc0XHVCQkMwXHVCODVDIFx1RDU3NFx1QjJGOSAneydiYXNlIHR5cGUgZGVmaW5pdGlvbid9JyAnJ3swfScnXHVDNzQwKFx1QjI5NCkgXHVBRTMwXHVCQ0Y4IFx1QjJFOFx1QzIxQyBcdUM3MjBcdUQ2MTUgXHVDODE1XHVDNzU4IFx1QjYxMFx1QjI5NCBcdUIwQjRcdUM3QTVcdUI0MUMgXHVBRTMwXHVCQ0Y4IFx1QjM3MFx1Qzc3NFx1RDEzMCBcdUM3MjBcdUQ2MTVcdUM3NzRcdUM1QjRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBjb3Mtc3QtcmVzdHJpY3RzLjIuMSA9IGNvcy1zdC1yZXN0cmljdHMuMi4xOiBcdUJBQTlcdUI4NUQgXHVDNzIwXHVENjE1ICcnezB9JydcdUM3NTggXHVDODE1XHVDNzU4XHVDNUQwXHVDMTFDICcnezF9JycgXHVDNzIwXHVENjE1XHVDNzQwIFx1QkFBOVx1Qjg1RCBcdUM3MjBcdUQ2MTVcdUM3NzRcdUFDNzBcdUIwOTggXHVCQUE5XHVCODVEXHVDNzQ0IFx1RDNFQ1x1RDU2OFx1RDU1OFx1QjI5NCBcdUQ1NjlcdUM5RDFcdUQ1NjkgXHVDNzIwXHVENjE1XHVDNzc0XHVCQkMwXHVCODVDIFx1QkQ4MFx1QzgwMVx1RDU2OVx1RDU1QyBcdUQ1NkRcdUJBQTkgXHVDNzIwXHVENjE1XHVDNzg1XHVCMkM4XHVCMkU0LgotICAgICAgICBjb3Mtc3QtcmVzdHJpY3RzLjIuMy4xLjEgPSBjb3Mtc3QtcmVzdHJpY3RzLjIuMy4xLjE6ICd7J2l0ZW0gdHlwZSBkZWZpbml0aW9uJ30nICcnezB9JydcdUM3NTggJ3snZmluYWwnfScgXHVBRDZDXHVDMTMxIFx1QzY5NFx1QzE4Q1x1QzVEMCAnJ2xpc3QnJ1x1QUMwMCBcdUQzRUNcdUQ1NjhcdUI0MThcdUM1QjQgXHVDNzg4XHVDMkI1XHVCMkM4XHVCMkU0LiBcdUI1MzBcdUI3N0NcdUMxMUMgJyd7MH0nJ1x1Qzc0NChcdUI5N0MpIFx1QkFBOVx1Qjg1RCBcdUM3MjBcdUQ2MTUgJyd7MX0nJ1x1QzVEMCBcdUIzMDBcdUQ1NUMgXHVENTZEXHVCQUE5IFx1QzcyMFx1RDYxNVx1QzczQ1x1Qjg1QyBcdUMwQUNcdUM2QTlcdUQ1NjAgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4KLSAgICAgICAgY29zLXN0LXJlc3RyaWN0cy4zLjMuMS4xID0gY29zLXN0LXJlc3RyaWN0cy4zLjMuMS4xOiAneydtZW1iZXIgdHlwZSBkZWZpbml0aW9ucyd9JyAnJ3swfScnXHVDNzU4ICd7J2ZpbmFsJ30nIFx1QUQ2Q1x1QzEzMSBcdUM2OTRcdUMxOENcdUM1RDAgJyd1bmlvbicnXHVDNzc0IFx1RDNFQ1x1RDU2OFx1QjQxOFx1QzVCNCBcdUM3ODhcdUMyQjVcdUIyQzhcdUIyRTQuIFx1QjUzMFx1Qjc3Q1x1QzExQyAnJ3swfScnXHVDNzQ0KFx1Qjk3QykgXHVENTY5XHVDOUQxXHVENTY5IFx1QzcyMFx1RDYxNSAnJ3sxfScnXHVDNUQwIFx1QjMwMFx1RDU1QyBcdUJBNjRcdUJDODQgXHVDNzIwXHVENjE1XHVDNzNDXHVCODVDIFx1QzBBQ1x1QzZBOVx1RDU2MCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LgotICAgICAgICBjb3MtdmFsaWQtZGVmYXVsdC4yLjEgPSBjb3MtdmFsaWQtZGVmYXVsdC4yLjE6ICcnezB9JycgXHVDNjk0XHVDMThDXHVDNUQwIFx1QUMxMiBcdUM4MUNcdUM1N0QgXHVDODcwXHVBQzc0XHVDNzc0IFx1Qzc4OFx1QzczQ1x1QkJDMFx1Qjg1QyBcdUQ2M0NcdUQ1NjkgXHVCNjEwXHVCMjk0IFx1QjJFOFx1QzIxQyBcdUNGNThcdUQxNTBcdUNFMjAgXHVCQUE4XHVCMzc4XHVDNzc0IFx1RDNFQ1x1RDU2OFx1QjQxOFx1QzVCNFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIGNvcy12YWxpZC1kZWZhdWx0LjIuMi4yID0gY29zLXZhbGlkLWRlZmF1bHQuMi4yLjI6ICcnezB9JycgXHVDNjk0XHVDMThDXHVDNUQwICd7J3ZhbHVlIGNvbnN0cmFpbnQnfSdcdUFDMDAgXHVDNzg4XHVDNzNDXHVCQTcwIFx1RDU3NFx1QjJGOSBcdUM3MjBcdUQ2MTUgXHVDODE1XHVDNzU4XHVDNUQwIFx1RDYzQ1x1RDU2OSAneydjb250ZW50IHR5cGUnfSdcdUM3NzQgXHVDNzg4XHVDNzNDXHVCQkMwXHVCODVDICd7J2NvbnRlbnQgdHlwZSd9J1x1Qzc1OCBcdUM4NzBcdUFDMDFcdUM3NDQgXHVCRTQ0XHVDNkI4IFx1QzIxOCBcdUM3ODhcdUM1QjRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBjLXByb3BzLWNvcnJlY3QuMiA9IGMtcHJvcHMtY29ycmVjdC4yOiBrZXlyZWYgJyd7MH0nJ1x1QUNGQyhcdUM2NDApIFx1RDBBNCAnJ3sxfScnXHVDNUQwIFx1QjMwMFx1RDU1QyBcdUQ1NDRcdUI0REMgXHVBRTMwXHVDMjE4XHVCMjk0IFx1QzExQ1x1Qjg1QyBcdUM3N0NcdUNFNThcdUQ1NzRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBjdC1wcm9wcy1jb3JyZWN0LjMgPSBjdC1wcm9wcy1jb3JyZWN0LjM6IFx1QkNGNVx1RDU2OSBcdUM3MjBcdUQ2MTUgJyd7MH0nJ1x1QzVEMCBcdUIzMDBcdUQ1NUMgXHVDMjFDXHVENjU4IFx1QzgxNVx1Qzc1OFx1QUMwMCBcdUFDMTBcdUM5QzBcdUI0MThcdUM1QzhcdUMyQjVcdUIyQzhcdUIyRTQuIFx1QjUzMFx1Qjc3Q1x1QzExQyAnJ3swfScnXHVDNzQwKFx1QjI5NCkgXHVBQ0UwXHVDNzIwXHVENTVDIFx1QzcyMFx1RDYxNSBcdUFDQzRcdUNFMzVcdUM1RDAgXHVEM0VDXHVENTY4XHVCNDFDIFx1QUM4M1x1Qzc3NFx1QkE3MCBcdUM3NzRcdUIyOTQgXHVDNjI0XHVCOTU4XHVDNzg1XHVCMkM4XHVCMkU0LgotICAgICAgICBjdC1wcm9wcy1jb3JyZWN0LjQgPSBjdC1wcm9wcy1jb3JyZWN0LjQ6ICcnezB9JycgXHVDNzIwXHVENjE1XHVDNUQwIFx1QjMwMFx1RDU3NCBcdUM2MjRcdUI5NThcdUFDMDAgXHVCQzFDXHVDMEREXHVENTg4XHVDMkI1XHVCMkM4XHVCMkU0LiBcdUM3NzRcdUI5ODQgXHVCQzBGIFx1QjMwMFx1QzBDMSBcdUIxMjRcdUM3ODRcdUMyQTRcdUQzOThcdUM3NzRcdUMyQTRcdUFDMDAgXHVCM0Q5XHVDNzdDXHVENTVDIFx1QzkxMVx1QkNGNSBcdUMxOERcdUMxMzEgXHVDMEFDXHVDNkE5XHVDNzc0IFx1QzlDMFx1QzgxNVx1QjQxOFx1QzVDOFx1QzJCNVx1QjJDOFx1QjJFNC4gXHVDOTExXHVCQ0Y1IFx1QzE4RFx1QzEzMSBcdUMwQUNcdUM2QTlcdUM3NTggXHVDNzc0XHVCOTg0XHVDNzQwICcnezF9JydcdUM3ODVcdUIyQzhcdUIyRTQuCi0gICAgICAgIGN0LXByb3BzLWNvcnJlY3QuNSA9IGN0LXByb3BzLWNvcnJlY3QuNTogJyd7MH0nJyBcdUM3MjBcdUQ2MTVcdUM1RDAgXHVCMzAwXHVENTc0IFx1QzYyNFx1Qjk1OFx1QUMwMCBcdUJDMUNcdUMwRERcdUQ1ODhcdUMyQjVcdUIyQzhcdUIyRTQuIFx1QjQ1MCBcdUFDMUNcdUM3NTggXHVDMThEXHVDMTMxIFx1QzEyMFx1QzVCOCAnJ3sxfScnIFx1QkMwRiAnJ3syfScnXHVDNUQwIElEXHVDNUQwXHVDMTFDIFx1RDMwQ1x1QzBERFx1QjQxQyBcdUM3MjBcdUQ2MTVcdUM3NzQgXHVDNzg4XHVDMkI1XHVCMkM4XHVCMkU0LgotICAgICAgICBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjEgPSBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjE6ICcnezB9JycgXHVDNzIwXHVENjE1XHVDNzQwICcnezF9JycgXHVDNzIwXHVENjE1XHVDNUQwXHVDMTFDIFx1QzgxQ1x1RDU1QyBcdUMwQUNcdUQ1NkRcdUM1RDAgXHVDNzU4XHVENTc0IFx1RDMwQ1x1QzBERFx1QjQxOFx1QzVDOFx1QzJCNVx1QjJDOFx1QjJFNC4gXHVENTU4XHVDOUMwXHVCOUNDICcnezF9JydcdUM1RDBcdUIyOTQgXHVDODFDXHVENTVDIFx1QzBBQ1x1RDU2RFx1QzVEMCBcdUM3NThcdUQ1NUMgXHVEMzBDXHVDMEREXHVDNzQ0IFx1QUUwOFx1QzlDMFx1RDU1OFx1QjI5NCAneydmaW5hbCd9JyBcdUMxOERcdUMxMzFcdUM3NzQgXHVDNzg4XHVDMkI1XHVCMkM4XHVCMkU0LgotICAgICAgICBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjIuMS4xID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4yLjEuMTogJyd7MH0nJyBcdUM3MjBcdUQ2MTVcdUM1RDAgXHVCMzAwXHVENTc0IFx1QzYyNFx1Qjk1OFx1QUMwMCBcdUJDMUNcdUMwRERcdUQ1ODhcdUMyQjVcdUIyQzhcdUIyRTQuIFx1Qzc3NCBcdUM3MjBcdUQ2MTVcdUM3NTggXHVDMThEXHVDMTMxIFx1QzBBQ1x1QzZBOSAnJ3sxfScnXHVDNUQwIFx1QjMwMFx1RDU1QyAnJ3VzZScnIFx1QUMxMlx1Qzc3NCAnJ3syfScnXHVDNzg1XHVCMkM4XHVCMkU0LiBcdUM3NzRcdUIyOTQgXHVBRTMwXHVCQ0Y4IFx1QzcyMFx1RDYxNVx1Qzc1OCBcdUM3N0NcdUNFNThcdUQ1NThcdUIyOTQgXHVDMThEXHVDMTMxIFx1QzBBQ1x1QzZBOVx1QzVEMCBcdUIzMDBcdUQ1NUMgXHVBQzEyXHVDNzc4ICcncmVxdWlyZWQnJ1x1QzY0MCBcdUIyRTRcdUI5ODVcdUIyQzhcdUIyRTQuCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMi4xLjIgPSBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjIuMS4yOiAnJ3swfScnIFx1QzcyMFx1RDYxNVx1QzVEMCBcdUIzMDBcdUQ1NzQgXHVDNjI0XHVCOTU4XHVBQzAwIFx1QkMxQ1x1QzBERFx1RDU4OFx1QzJCNVx1QjJDOFx1QjJFNC4gXHVDNzc0IFx1QzcyMFx1RDYxNVx1Qzc1OCBcdUMxOERcdUMxMzEgXHVDMEFDXHVDNkE5ICcnezF9JydcdUM1RDAgXHVCMzAwXHVENTVDIFx1QzcyMFx1RDYxNVx1Qzc3NCAnJ3syfScnXHVDNzg1XHVCMkM4XHVCMkU0LiBcdUM3NzRcdUIyOTQgXHVBRTMwXHVCQ0Y4IFx1QzcyMFx1RDYxNVx1Qzc1OCBcdUM3N0NcdUNFNThcdUQ1NThcdUIyOTQgXHVDMThEXHVDMTMxIFx1QzBBQ1x1QzZBOVx1QzVEMCBcdUIzMDBcdUQ1NUMgXHVDNzIwXHVENjE1XHVDNzc4ICcnezN9JydcdUM1RDBcdUMxMUMgXHVDODAxXHVENTY5XHVENTU4XHVBQzhDIFx1RDMwQ1x1QzBERFx1QjQxQyBcdUFDODNcdUM3NzQgXHVDNTQ0XHVCMkQ5XHVCMkM4XHVCMkU0LgotICAgICAgICBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjIuMS4zLmEgPSBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjIuMS4zLmE6ICcnezB9JycgXHVDNzIwXHVENjE1XHVDNUQwIFx1QjMwMFx1RDU3NCBcdUM2MjRcdUI5NThcdUFDMDAgXHVCQzFDXHVDMEREXHVENTg4XHVDMkI1XHVCMkM4XHVCMkU0LiBcdUM3NzQgXHVDNzIwXHVENjE1XHVDNzU4IFx1QzE4RFx1QzEzMSBcdUMwQUNcdUM2QTkgJyd7MX0nJ1x1QzVEMFx1QjI5NCBcdUFDRTBcdUM4MTVcdUI0MThcdUM5QzAgXHVDNTRBXHVDNzQwIFx1QzcyMFx1RDZBOFx1RDU1QyBcdUFDMTIgXHVDODFDXHVDNTdEIFx1Qzg3MFx1QUM3NFx1Qzc3NCBcdUM3ODhcdUM3M0NcdUJBNzAsIFx1QUUzMFx1QkNGOCBcdUM3MjBcdUQ2MTVcdUM3NTggXHVDNzdDXHVDRTU4XHVENTU4XHVCMjk0IFx1QzE4RFx1QzEzMSBcdUMwQUNcdUM2QTlcdUM1RDAgXHVCMzAwXHVENTVDIFx1QzcyMFx1RDZBOFx1RDU1QyBcdUFDMTIgXHVDODFDXHVDNTdEIFx1Qzg3MFx1QUM3NFx1Qzc0MCBcdUFDRTBcdUM4MTVcdUI0MThcdUM1QjQgXHVDNzg4XHVDMkI1XHVCMkM4XHVCMkU0LgotICAgICAgICBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjIuMS4zLmIgPSBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjIuMS4zLmI6ICcnezB9JycgXHVDNzIwXHVENjE1XHVDNUQwIFx1QjMwMFx1RDU3NCBcdUM2MjRcdUI5NThcdUFDMDAgXHVCQzFDXHVDMEREXHVENTg4XHVDMkI1XHVCMkM4XHVCMkU0LiBcdUM3NzQgXHVDNzIwXHVENjE1XHVDNzU4IFx1QzE4RFx1QzEzMSBcdUMwQUNcdUM2QTkgJyd7MX0nJ1x1QzVEMCAnJ3syfScnIFx1QUMxMlx1QzczQ1x1Qjg1QyBcdUFDRTBcdUM4MTVcdUI0MUMgXHVDNzIwXHVENkE4XHVENTVDIFx1QUMxMiBcdUM4MUNcdUM1N0QgXHVDODcwXHVBQzc0XHVDNzc0IFx1Qzc4OFx1QzJCNVx1QjJDOFx1QjJFNC4gXHVDNzc0XHVCMjk0IFx1QUUzMFx1QkNGOCBcdUM3MjBcdUQ2MTVcdUM3NTggXHVDNzdDXHVDRTU4XHVENTU4XHVCMjk0IFx1QzE4RFx1QzEzMSBcdUMwQUNcdUM2QTlcdUM1RDAgXHVCMzAwXHVENTVDIFx1QUNFMFx1QzgxNVx1QjQxQyBcdUM3MjBcdUQ2QThcdUQ1NUMgXHVBQzEyIFx1QzgxQ1x1QzU3RCBcdUM4NzBcdUFDNzRcdUM3NTggXHVBQzEyXHVDNzc4ICcnezN9JydcdUFDRkMoXHVDNjQwKSBcdUIyRTRcdUI5ODVcdUIyQzhcdUIyRTQuCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMi4yLmEgPSBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjIuMi5hOiAnJ3swfScnIFx1QzcyMFx1RDYxNVx1QzVEMCBcdUIzMDBcdUQ1NzQgXHVDNjI0XHVCOTU4XHVBQzAwIFx1QkMxQ1x1QzBERFx1RDU4OFx1QzJCNVx1QjJDOFx1QjJFNC4gXHVDNzc0IFx1QzcyMFx1RDYxNVx1Qzc1OCBcdUMxOERcdUMxMzEgXHVDMEFDXHVDNkE5ICcnezF9JydcdUFDRkMoXHVDNjQwKSBcdUFFMzBcdUJDRjggXHVDNzIwXHVENjE1XHVDNzU4IFx1QzE4RFx1QzEzMSBcdUMwQUNcdUM2QTlcdUM3NzQgXHVDNzdDXHVDRTU4XHVENTU4XHVDOUMwIFx1QzU0QVx1QzczQ1x1QkE3MCBcdUFFMzBcdUJDRjggXHVDNzIwXHVENjE1XHVDNUQwIFx1QzY0MFx1Qzc3Q1x1QjREQyBcdUNFNzRcdUI0REMgXHVCQjM4XHVDNzkwIFx1QzE4RFx1QzEzMVx1Qzc3NCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMi4yLmIgPSBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjIuMi5iOiAnJ3swfScnIFx1QzcyMFx1RDYxNVx1QzVEMCBcdUIzMDBcdUQ1NzQgXHVDNjI0XHVCOTU4XHVBQzAwIFx1QkMxQ1x1QzBERFx1RDU4OFx1QzJCNVx1QjJDOFx1QjJFNC4gXHVDNzc0IFx1QzcyMFx1RDYxNVx1Qzc1OCBcdUMxOERcdUMxMzEgXHVDMEFDXHVDNkE5ICcnezF9JydcdUFDRkMoXHVDNjQwKSBcdUFFMzBcdUJDRjggXHVDNzIwXHVENjE1XHVDNzU4IFx1QzE4RFx1QzEzMSBcdUMwQUNcdUM2QTlcdUM3NzQgXHVDNzdDXHVDRTU4XHVENTU4XHVDOUMwIFx1QzU0QVx1QzczQ1x1QkE3MCBcdUFFMzBcdUJDRjggXHVDNzIwXHVENjE1XHVDNzU4IFx1QzY0MFx1Qzc3Q1x1QjREQyBcdUNFNzRcdUI0REMgXHVCQjM4XHVDNzkwXHVBQzAwIFx1Qzc3NCBcdUMxOERcdUMxMzEgXHVDMEFDXHVDNkE5XHVDNzU4ICcnezJ9JycgXHVCMTI0XHVDNzg0XHVDMkE0XHVEMzk4XHVDNzc0XHVDMkE0XHVCOTdDIFx1RDVDOFx1QzZBOVx1RDU1OFx1QzlDMCBcdUM1NEFcdUMyQjVcdUIyQzhcdUIyRTQuCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMyA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMzogJyd7MH0nJyBcdUM3MjBcdUQ2MTVcdUM1RDAgXHVCMzAwXHVENTc0IFx1QzYyNFx1Qjk1OFx1QUMwMCBcdUJDMUNcdUMwRERcdUQ1ODhcdUMyQjVcdUIyQzhcdUIyRTQuIFx1QUUzMFx1QkNGOCBcdUM3MjBcdUQ2MTVcdUM3NTggXHVDMThEXHVDMTMxIFx1QzBBQ1x1QzZBOSAnJ3sxfScnXHVDNUQwIFx1QjMwMFx1RDU1QyBSRVFVSVJFRFx1QUMwMCB0cnVlXHVDNzc0XHVDOUMwXHVCOUNDIFx1RDMwQ1x1QzBERCBcdUM3MjBcdUQ2MTVcdUM1RDAgXHVDNzdDXHVDRTU4XHVENTU4XHVCMjk0IFx1QzE4RFx1QzEzMSBcdUMwQUNcdUM2QTlcdUM3NzQgXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LgotICAgICAgICBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjQuMSA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uNC4xOiAnJ3swfScnIFx1QzcyMFx1RDYxNVx1QzVEMCBcdUIzMDBcdUQ1NzQgXHVDNjI0XHVCOTU4XHVBQzAwIFx1QkMxQ1x1QzBERFx1RDU4OFx1QzJCNVx1QjJDOFx1QjJFNC4gXHVEMzBDXHVDMEREIFx1QzcyMFx1RDYxNVx1QzVEMFx1QjI5NCBcdUMxOERcdUMxMzEgXHVDNjQwXHVDNzdDXHVCNERDIFx1Q0U3NFx1QjREQyBcdUJCMzhcdUM3OTBcdUFDMDAgXHVDNzg4XHVDOUMwXHVCOUNDIFx1QUUzMFx1QkNGOCBcdUM3MjBcdUQ2MTVcdUM1RDBcdUIyOTQgXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LgotICAgICAgICBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjQuMiA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uNC4yOiAnJ3swfScnIFx1QzcyMFx1RDYxNVx1QzVEMCBcdUIzMDBcdUQ1NzQgXHVDNjI0XHVCOTU4XHVBQzAwIFx1QkMxQ1x1QzBERFx1RDU4OFx1QzJCNVx1QjJDOFx1QjJFNC4gXHVEMzBDXHVDMEREIFx1QzcyMFx1RDYxNVx1Qzc1OCBcdUM2NDBcdUM3N0NcdUI0REMgXHVDRTc0XHVCNERDIFx1QkIzOFx1Qzc5MFx1QUMwMCBcdUFFMzBcdUJDRjggXHVDNzIwXHVENjE1XHVDNzU4IFx1QzY0MFx1Qzc3Q1x1QjREQyBcdUNFNzRcdUI0REMgXHVCQjM4XHVDNzkwXHVDNUQwIFx1QjMwMFx1RDU3NCBcdUM4MDFcdUQ1NjlcdUQ1NUMgXHVDNjQwXHVDNzdDXHVCNERDIFx1Q0U3NFx1QjREQyBcdUJCMzhcdUM3OTAgXHVCRDgwXHVCRDg0IFx1QzlEMVx1RDU2OVx1Qzc3NCBcdUM1NDRcdUIyRDlcdUIyQzhcdUIyRTQuCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uNC4zID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi40LjM6ICcnezB9JycgXHVDNzIwXHVENjE1XHVDNUQwIFx1QjMwMFx1RDU3NCBcdUM2MjRcdUI5NThcdUFDMDAgXHVCQzFDXHVDMEREXHVENTg4XHVDMkI1XHVCMkM4XHVCMkU0LiBcdUQzMENcdUMwREQgXHVDNzIwXHVENjE1KHsxfSlcdUM3NTggXHVDNjQwXHVDNzdDXHVCNERDIFx1Q0U3NFx1QjREQyBcdUJCMzhcdUM3OTBcdUM1RDAgXHVCMzAwXHVENTVDIFx1RDUwNFx1Qjg1Q1x1QzEzOFx1QzJBNCBcdUNGNThcdUQxNTBcdUNFMjBcdUFDMDAgXHVBRTMwXHVCQ0Y4IFx1QzcyMFx1RDYxNSh7Mn0pXHVDNzU4IFx1QzY0MFx1Qzc3Q1x1QjREQyBcdUNFNzRcdUI0REMgXHVCQjM4XHVDNzkwXHVCQ0Y0XHVCMkU0IFx1RDU1OFx1QzcwNFx1Qzc4NVx1QjJDOFx1QjJFNC4KLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi41LjIuMi4xID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi41LjIuMi4xOiAnJ3swfScnIFx1QzcyMFx1RDYxNVx1QzVEMCBcdUIzMDBcdUQ1NzQgXHVDNjI0XHVCOTU4XHVBQzAwIFx1QkMxQ1x1QzBERFx1RDU4OFx1QzJCNVx1QjJDOFx1QjJFNC4gXHVDNzc0IFx1QzcyMFx1RDYxNSAnJ3sxfScnXHVDNzU4IFx1QjJFOFx1QzIxQyBcdUNGNThcdUQxNTBcdUNFMjAgXHVDNzIwXHVENjE1XHVDNzc0IFx1QUUzMFx1QkNGOCBcdUM3MjBcdUQ2MTUgJyd7Mn0nJ1x1Qzc1OCBcdUIyRThcdUMyMUMgXHVDRjU4XHVEMTUwXHVDRTIwIFx1QzcyMFx1RDYxNVx1QzVEMCBcdUIzMDBcdUQ1NzQgXHVDODAxXHVENTY5XHVENTVDIFx1QzgxQ1x1RDU1QyBcdUMwQUNcdUQ1NkRcdUM3NzQgXHVDNTQ0XHVCMkQ5XHVCMkM4XHVCMkU0LgotICAgICAgICBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjUuMy4yID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi41LjMuMjogJyd7MH0nJyBcdUM3MjBcdUQ2MTVcdUM1RDAgXHVCMzAwXHVENTc0IFx1QzYyNFx1Qjk1OFx1QUMwMCBcdUJDMUNcdUMwRERcdUQ1ODhcdUMyQjVcdUIyQzhcdUIyRTQuIFx1Qzc3NCBcdUM3MjBcdUQ2MTVcdUM3NTggXHVDRjU4XHVEMTUwXHVDRTIwIFx1QzcyMFx1RDYxNVx1Qzc3NCBcdUJFNDRcdUM1QjQgXHVDNzg4XHVDOUMwXHVCOUNDIFx1QUUzMFx1QkNGOCBcdUM3MjBcdUQ2MTUgJyd7MX0nJ1x1Qzc1OCBcdUNGNThcdUQxNTBcdUNFMjAgXHVDNzIwXHVENjE1XHVDNzQwIFx1QkU0NFx1QzVCNCBcdUM3ODhcdUM5QzAgXHVDNTRBXHVBQzcwXHVCMDk4IFx1QkU0NFx1QzZCOCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LgotICAgICAgICBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjUuNC4xLjIgPSBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjUuNC4xLjI6ICcnezB9JycgXHVDNzIwXHVENjE1XHVDNUQwIFx1QjMwMFx1RDU3NCBcdUM2MjRcdUI5NThcdUFDMDAgXHVCQzFDXHVDMEREXHVENTg4XHVDMkI1XHVCMkM4XHVCMkU0LiBcdUM3NzQgXHVDNzIwXHVENjE1XHVDNzU4IFx1Q0Y1OFx1RDE1MFx1Q0UyMCBcdUM3MjBcdUQ2MTVcdUM3NDAgXHVENjNDXHVENTY5XHVCNDE4XHVDNUI0IFx1Qzc4OFx1QzlDMFx1QjlDQyBcdUFFMzBcdUJDRjggXHVDNzIwXHVENjE1ICcnezF9JydcdUM3NTggXHVDRjU4XHVEMTUwXHVDRTIwIFx1QzcyMFx1RDYxNVx1Qzc0MCBcdUQ2M0NcdUQ1NjlcdUI0MThcdUM1QjQgXHVDNzg4XHVDOUMwIFx1QzU0QVx1QzJCNVx1QjJDOFx1QjJFNC4KLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi41LjQuMiA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uNS40LjI6ICcnezB9JycgXHVDNzIwXHVENjE1XHVDNUQwIFx1QjMwMFx1RDU3NCBcdUM2MjRcdUI5NThcdUFDMDAgXHVCQzFDXHVDMEREXHVENTg4XHVDMkI1XHVCMkM4XHVCMkU0LiBcdUM3MjBcdUQ2MTUgXHVDODcwXHVBQzAxXHVDNzc0IFx1QUUzMFx1QkNGOCBcdUM3MjBcdUQ2MTVcdUM3NTggXHVDODcwXHVBQzAxXHVDNUQwIFx1QjMwMFx1RDU3NCBcdUM4MDFcdUQ1NjlcdUQ1NUMgXHVDODFDXHVENTVDIFx1QzBBQ1x1RDU2RFx1Qzc3NCBcdUM1NDRcdUIyRDlcdUIyQzhcdUIyRTQuCi0gICAgICAgIGVudW1lcmF0aW9uLXJlcXVpcmVkLW5vdGF0aW9uID0gZW51bWVyYXRpb24tcmVxdWlyZWQtbm90YXRpb246IHsyfSAnJ3sxfScnXHVDNUQwIFx1QzBBQ1x1QzZBOVx1QjQxOFx1QjI5NCBOT1RBVElPTiBcdUM3MjBcdUQ2MTUgJyd7MH0nJ1x1QzVEMFx1QjI5NCBcdUM3NzQgXHVDNzIwXHVENjE1XHVDNUQwIFx1QzBBQ1x1QzZBOVx1QjQxOFx1QjI5NCBcdUQ0NUNcdUFFMzBcdUJDOTUgXHVDNjk0XHVDMThDXHVCOTdDIFx1QzlDMFx1QzgxNVx1RDU1OFx1QjI5NCBcdUJBQTlcdUI4NUQgXHVCQTc0IFx1QUMxMlx1Qzc3NCBcdUM3ODhcdUM1QjRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBlbnVtZXJhdGlvbi12YWxpZC1yZXN0cmljdGlvbiA9IGVudW1lcmF0aW9uLXZhbGlkLXJlc3RyaWN0aW9uOiBcdUJBQTlcdUI4NUQgXHVBQzEyICcnezB9JydcdUM3NzQoXHVBQzAwKSBcdUFFMzBcdUJDRjggXHVDNzIwXHVENjE1IHsxfVx1Qzc1OCBcdUFDMTIgXHVBQ0Y1XHVBQzA0XHVDNUQwIFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4KLSAgICAgICAgZS1wcm9wcy1jb3JyZWN0LjIgPSBlLXByb3BzLWNvcnJlY3QuMjogJyd7MH0nJyBcdUM2OTRcdUMxOENcdUM3NTggXHVBQzEyIFx1QzgxQ1x1QzU3RCBcdUM4NzBcdUFDNzQgXHVBQzEyICcnezF9JydcdUM3NzQoXHVBQzAwKSBcdUJEODBcdUM4MDFcdUQ1NjlcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIGUtcHJvcHMtY29ycmVjdC40ID0gZS1wcm9wcy1jb3JyZWN0LjQ6ICcnezB9JycgXHVDNjk0XHVDMThDXHVDNzU4ICd7J3R5cGUgZGVmaW5pdGlvbid9J1x1Qzc3NCBzdWJzdGl0dXRpb25IZWFkICcnezF9JydcdUM3NTggJ3sndHlwZSBkZWZpbml0aW9uJ30nXHVDNUQwXHVDMTFDIFx1QzgwMVx1RDU2OVx1RDU1OFx1QUM4QyBcdUQzMENcdUMwRERcdUI0MUMgXHVBQzgzXHVDNzc0IFx1QzU0NFx1QjJDOFx1QUM3MFx1QjA5OCAnJ3sxfScnXHVDNzU4ICd7J3N1YnN0aXR1dGlvbiBncm91cCBleGNsdXNpb25zJ30nIFx1QzE4RFx1QzEzMVx1Qzc3NCBcdUM3NzQgXHVEMzBDXHVDMEREXHVDNzQ0IFx1RDVDOFx1QzZBOVx1RDU1OFx1QzlDMCBcdUM1NEFcdUMyQjVcdUIyQzhcdUIyRTQuCi0gICAgICAgIGUtcHJvcHMtY29ycmVjdC41ID0gZS1wcm9wcy1jb3JyZWN0LjU6IFx1QzY5NFx1QzE4Q1x1Qzc1OCAneyd0eXBlIGRlZmluaXRpb24nfScgXHVCNjEwXHVCMjk0ICd7J3R5cGUgZGVmaW5pdGlvbid9J1x1Qzc1OCAneydjb250ZW50IHR5cGUnfSdcdUM3NzQgSURcdUM3NzRcdUFDNzBcdUIwOTggSURcdUM1RDBcdUMxMUMgXHVEMzBDXHVDMEREXHVCNDFDIFx1QUM4M1x1Qzc3NFx1QkJDMFx1Qjg1QyAneyd2YWx1ZSBjb25zdHJhaW50J30nXHVCMjk0ICcnezB9JycgXHVDNjk0XHVDMThDXHVDNUQwIFx1QzVDNlx1QzVCNFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIGUtcHJvcHMtY29ycmVjdC42ID0gZS1wcm9wcy1jb3JyZWN0LjY6ICcnezB9JycgXHVDNjk0XHVDMThDXHVDNUQwIFx1QjMwMFx1RDU1QyBcdUMyMUNcdUQ2NTggXHVCMzAwXHVDQ0I0IFx1QURGOFx1QjhGOVx1Qzc3NCBcdUFDMTBcdUM5QzBcdUI0MThcdUM1QzhcdUMyQjVcdUIyQzhcdUIyRTQuLgotICAgICAgICBmcmFjdGlvbkRpZ2l0cy12YWxpZC1yZXN0cmljdGlvbiA9IGZyYWN0aW9uRGlnaXRzLXZhbGlkLXJlc3RyaWN0aW9uOiB7Mn1cdUM3NTggXHVDODE1XHVDNzU4XHVDNUQwXHVDMTFDICcnZnJhY3Rpb25EaWdpdHMnJyBcdUJBNzRcdUM1RDAgXHVCMzAwXHVENTVDICcnezB9JycgXHVBQzEyXHVDNzc0IFx1QkQ4MFx1QzgwMVx1RDU2OVx1RDU2OVx1QjJDOFx1QjJFNC4gXHVDNzc0IFx1QUMxMlx1Qzc0MCBcdUM4NzBcdUMwQzEgXHVDNzIwXHVENjE1IFx1QzkxMSBcdUQ1NThcdUIwOThcdUM1RDBcdUMxMUMgJyd7MX0nJyhcdUM3M0MpXHVCODVDIFx1QzEyNFx1QzgxNVx1QjQxQyAnJ2ZyYWN0aW9uRGlnaXRzJydcdUM1RDAgXHVCMzAwXHVENTVDIFx1QUMxMlx1QkNGNFx1QjJFNCBcdUM3OTFcdUFDNzBcdUIwOTggXHVBQzE5XHVDNTQ0XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgZnJhY3Rpb25EaWdpdHMtdG90YWxEaWdpdHMgPSBmcmFjdGlvbkRpZ2l0cy10b3RhbERpZ2l0czogezJ9XHVDNzU4IFx1QzgxNVx1Qzc1OFx1QzVEMFx1QzExQyAnJ2ZyYWN0aW9uRGlnaXRzJycgXHVCQTc0XHVDNUQwIFx1QjMwMFx1RDU1QyAnJ3swfScnIFx1QUMxMlx1Qzc3NCBcdUJEODBcdUM4MDFcdUQ1NjlcdUQ1NjlcdUIyQzhcdUIyRTQuIFx1Qzc3NCBcdUFDMTJcdUM3NDAgJyd0b3RhbERpZ2l0cycnXHVDNUQwIFx1QjMwMFx1RDU1QyBcdUFDMTJcdUM3NzggJyd7MX0nJ1x1QkNGNFx1QjJFNCBcdUM3OTFcdUFDNzBcdUIwOTggXHVBQzE5XHVDNTQ0XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgbGVuZ3RoLW1pbkxlbmd0aC1tYXhMZW5ndGguMS4xID0gbGVuZ3RoLW1pbkxlbmd0aC1tYXhMZW5ndGguMS4xOiB7MH0gXHVDNzIwXHVENjE1XHVDNzU4IFx1QUNCRFx1QzZCMCBsZW5ndGggJyd7MX0nJ1x1Qzc1OCBcdUFDMTJcdUM3NDAgbWluTGVuZ3RoICcnezJ9JydcdUM3NTggXHVBQzEyXHVCQ0Y0XHVCMkU0IFx1Qzc5MVx1Qzc0NCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LgotICAgICAgICBsZW5ndGgtbWluTGVuZ3RoLW1heExlbmd0aC4xLjIuYSA9IGxlbmd0aC1taW5MZW5ndGgtbWF4TGVuZ3RoLjEuMi5hOiB7MH0gXHVDNzIwXHVENjE1XHVDNzU4IFx1QUNCRFx1QzZCMCBcdUQ2MDRcdUM3QUMgXHVDODFDXHVENTVDIFx1QzBBQ1x1RDU2RFx1QzVEMCBtaW5MZW5ndGggXHVCQTc0XHVDNzc0IFx1Qzc4OFx1QUNFMCBcdUQ2MDRcdUM3QUMgXHVDODFDXHVENTVDIFx1QzBBQ1x1RDU2RCBcdUI2MTBcdUIyOTQgXHVBRTMwXHVCQ0Y4IFx1QzcyMFx1RDYxNVx1QzVEMCBsZW5ndGggXHVCQTc0XHVDNzc0IFx1Qzc4OFx1Qzc0NCBcdUFDQkRcdUM2QjAgXHVBRTMwXHVCQ0Y4IFx1QzcyMFx1RDYxNVx1QzVEMCBtaW5MZW5ndGggXHVCQTc0XHVDNzc0IFx1Qzc4OFx1QzVCNFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIGxlbmd0aC1taW5MZW5ndGgtbWF4TGVuZ3RoLjEuMi5iID0gbGVuZ3RoLW1pbkxlbmd0aC1tYXhMZW5ndGguMS4yLmI6IHswfSBcdUM3MjBcdUQ2MTVcdUM3NTggXHVBQ0JEXHVDNkIwIFx1RDYwNFx1QzdBQyBtaW5MZW5ndGggJyd7MX0nJ1x1Qzc3NChcdUFDMDApIFx1QUUzMFx1QkNGOCBtaW5MZW5ndGggJyd7Mn0nJ1x1QUNGQyhcdUM2NDApIFx1QUMxOVx1QzU0NFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIGxlbmd0aC1taW5MZW5ndGgtbWF4TGVuZ3RoLjIuMSA9IGxlbmd0aC1taW5MZW5ndGgtbWF4TGVuZ3RoLjIuMTogezB9IFx1QzcyMFx1RDYxNVx1Qzc1OCBcdUFDQkRcdUM2QjAgbGVuZ3RoICcnezF9JydcdUM3NTggXHVBQzEyXHVDNzQwIG1heExlbmd0aCAnJ3syfScnXHVDNzU4IFx1QUMxMlx1QkNGNFx1QjJFNCBcdUQwNkNcdUM5QzAgXHVDNTRBXHVDNTQ0XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgbGVuZ3RoLW1pbkxlbmd0aC1tYXhMZW5ndGguMi4yLmEgPSBsZW5ndGgtbWluTGVuZ3RoLW1heExlbmd0aC4yLjIuYTogezB9IFx1QzcyMFx1RDYxNVx1Qzc1OCBcdUFDQkRcdUM2QjAgXHVENjA0XHVDN0FDIFx1QzgxQ1x1RDU1QyBcdUMwQUNcdUQ1NkRcdUM1RDAgbWF4TGVuZ3RoIFx1QkE3NFx1Qzc3NCBcdUM3ODhcdUFDRTAgXHVENjA0XHVDN0FDIFx1QzgxQ1x1RDU1QyBcdUMwQUNcdUQ1NkQgXHVCNjEwXHVCMjk0IFx1QUUzMFx1QkNGOCBcdUM3MjBcdUQ2MTVcdUM1RDAgbGVuZ3RoIFx1QkE3NFx1Qzc3NCBcdUM3ODhcdUM3NDQgXHVBQ0JEXHVDNkIwIFx1QUUzMFx1QkNGOCBcdUM3MjBcdUQ2MTVcdUM1RDAgbWF4TGVuZ3RoIFx1QkE3NFx1Qzc3NCBcdUM3ODhcdUM1QjRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBsZW5ndGgtbWluTGVuZ3RoLW1heExlbmd0aC4yLjIuYiA9IGxlbmd0aC1taW5MZW5ndGgtbWF4TGVuZ3RoLjIuMi5iOiB7MH0gXHVDNzIwXHVENjE1XHVDNzU4IFx1QUNCRFx1QzZCMCBcdUQ2MDRcdUM3QUMgbWF4TGVuZ3RoICcnezF9JydcdUM3NDAoXHVCMjk0KSBcdUFFMzBcdUJDRjggbWF4TGVuZ3RoICcnezJ9JydcdUFDRkMoXHVDNjQwKSBcdUFDMTlcdUM1NDRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBsZW5ndGgtdmFsaWQtcmVzdHJpY3Rpb24gPSBsZW5ndGgtdmFsaWQtcmVzdHJpY3Rpb246ICcnezJ9JycgXHVDNzIwXHVENjE1XHVDNUQwIFx1QjMwMFx1RDU3NCBcdUM2MjRcdUI5NThcdUFDMDAgXHVCQzFDXHVDMEREXHVENTg4XHVDMkI1XHVCMkM4XHVCMkU0LiBsZW5ndGggPSAnJ3swfScnXHVDNzc4IFx1QUMxMlx1Qzc0MCBcdUFFMzBcdUJDRjggXHVDNzIwXHVENjE1ICcnezF9JydcdUM3NTggXHVENTc0XHVCMkY5IFx1QUMxMlx1QUNGQyBcdUFDMTlcdUM1NDRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBtYXhFeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMSA9IG1heEV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4xOiAnJ3syfScnIFx1QzcyMFx1RDYxNVx1QzVEMCBcdUIzMDBcdUQ1NzQgXHVDNjI0XHVCOTU4XHVBQzAwIFx1QkMxQ1x1QzBERFx1RDU4OFx1QzJCNVx1QjJDOFx1QjJFNC4gbWF4RXhjbHVzaXZlIFx1QUMxMiA9ICcnezB9JydcdUM3NDAoXHVCMjk0KSBcdUFFMzBcdUJDRjggXHVDNzIwXHVENjE1ICcnezF9JydcdUM3NTggbWF4RXhjbHVzaXZlXHVCQ0Y0XHVCMkU0IFx1Qzc5MVx1QUM3MFx1QjA5OCBcdUFDMTlcdUM1NDRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBtYXhFeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMiA9IG1heEV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4yOiAnJ3syfScnIFx1QzcyMFx1RDYxNVx1QzVEMCBcdUIzMDBcdUQ1NzQgXHVDNjI0XHVCOTU4XHVBQzAwIFx1QkMxQ1x1QzBERFx1RDU4OFx1QzJCNVx1QjJDOFx1QjJFNC4gbWF4RXhjbHVzaXZlIFx1QUMxMiA9ICcnezB9JydcdUM3NDAoXHVCMjk0KSBcdUFFMzBcdUJDRjggXHVDNzIwXHVENjE1ICcnezF9JydcdUM3NTggbWF4SW5jbHVzaXZlXHVCQ0Y0XHVCMkU0IFx1Qzc5MVx1QUM3MFx1QjA5OCBcdUFDMTlcdUM1NDRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBtYXhFeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMyA9IG1heEV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4zOiAnJ3syfScnIFx1QzcyMFx1RDYxNVx1QzVEMCBcdUIzMDBcdUQ1NzQgXHVDNjI0XHVCOTU4XHVBQzAwIFx1QkMxQ1x1QzBERFx1RDU4OFx1QzJCNVx1QjJDOFx1QjJFNC4gbWF4RXhjbHVzaXZlIFx1QUMxMiA9ICcnezB9JydcdUM3NDAoXHVCMjk0KSBcdUFFMzBcdUJDRjggXHVDNzIwXHVENjE1ICcnezF9JydcdUM3NTggbWluSW5jbHVzaXZlXHVCQ0Y0XHVCMkU0IFx1Q0VFNFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIG1heEV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi40ID0gbWF4RXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjQ6ICcnezJ9JycgXHVDNzIwXHVENjE1XHVDNUQwIFx1QjMwMFx1RDU3NCBcdUM2MjRcdUI5NThcdUFDMDAgXHVCQzFDXHVDMEREXHVENTg4XHVDMkI1XHVCMkM4XHVCMkU0LiBtYXhFeGNsdXNpdmUgXHVBQzEyID0gJyd7MH0nJ1x1Qzc0MChcdUIyOTQpIFx1QUUzMFx1QkNGOCBcdUM3MjBcdUQ2MTUgJyd7MX0nJ1x1Qzc1OCBtaW5FeGNsdXNpdmVcdUJDRjRcdUIyRTQgXHVDRUU0XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgbWF4SW5jbHVzaXZlLW1heEV4Y2x1c2l2ZSA9IG1heEluY2x1c2l2ZS1tYXhFeGNsdXNpdmU6IG1heEluY2x1c2l2ZVx1QzY0MCBtYXhFeGNsdXNpdmVcdUIyOTQgXHVCM0Q5XHVDNzdDXHVENTVDIFx1QjM3MFx1Qzc3NFx1RDEzMCBcdUM3MjBcdUQ2MTVcdUM1RDAgXHVCMzAwXHVENTc0IFx1QzlDMFx1QzgxNVx1QjQxOFx1QzlDMCBcdUM1NEFcdUM1NDRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LiB7Mn1cdUM1RDAgbWF4SW5jbHVzaXZlID0gJyd7MH0nJ1x1QUNGQyhcdUM2NDApIG1heEV4Y2x1c2l2ZSA9ICcnezF9JydcdUM3NzQoXHVBQzAwKSBcdUM5QzBcdUM4MTVcdUI0MThcdUM1QzhcdUMyQjVcdUIyQzhcdUIyRTQuCi0gICAgICAgIG1heEluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4xID0gbWF4SW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjE6ICcnezJ9JycgXHVDNzIwXHVENjE1XHVDNUQwIFx1QjMwMFx1RDU3NCBcdUM2MjRcdUI5NThcdUFDMDAgXHVCQzFDXHVDMEREXHVENTg4XHVDMkI1XHVCMkM4XHVCMkU0LiBtYXhJbmNsdXNpdmUgXHVBQzEyID0gJyd7MH0nJ1x1Qzc0MChcdUIyOTQpIFx1QUUzMFx1QkNGOCBcdUM3MjBcdUQ2MTUgJyd7MX0nJ1x1Qzc1OCBtYXhJbmNsdXNpdmVcdUJDRjRcdUIyRTQgXHVDNzkxXHVBQzcwXHVCMDk4IFx1QUMxOVx1QzU0NFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIG1heEluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4yID0gbWF4SW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjI6ICcnezJ9JycgXHVDNzIwXHVENjE1XHVDNUQwIFx1QjMwMFx1RDU3NCBcdUM2MjRcdUI5NThcdUFDMDAgXHVCQzFDXHVDMEREXHVENTg4XHVDMkI1XHVCMkM4XHVCMkU0LiBtYXhJbmNsdXNpdmUgXHVBQzEyID0gJyd7MH0nJ1x1Qzc0MChcdUIyOTQpIFx1QUUzMFx1QkNGOCBcdUM3MjBcdUQ2MTUgJyd7MX0nJ1x1Qzc1OCBtYXhFeGNsdXNpdmVcdUJDRjRcdUIyRTQgXHVDNzkxXHVDNTQ0XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgbWF4SW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjMgPSBtYXhJbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMzogJyd7Mn0nJyBcdUM3MjBcdUQ2MTVcdUM1RDAgXHVCMzAwXHVENTc0IFx1QzYyNFx1Qjk1OFx1QUMwMCBcdUJDMUNcdUMwRERcdUQ1ODhcdUMyQjVcdUIyQzhcdUIyRTQuIG1heEluY2x1c2l2ZSBcdUFDMTIgPSAnJ3swfScnXHVDNzQwKFx1QjI5NCkgXHVBRTMwXHVCQ0Y4IFx1QzcyMFx1RDYxNSAnJ3sxfScnXHVDNzU4IG1pbkluY2x1c2l2ZVx1QkNGNFx1QjJFNCBcdUQwNkNcdUFDNzBcdUIwOTggXHVBQzE5XHVDNTQ0XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgbWF4SW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjQgPSBtYXhJbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uNDogJyd7Mn0nJyBcdUM3MjBcdUQ2MTVcdUM1RDAgXHVCMzAwXHVENTc0IFx1QzYyNFx1Qjk1OFx1QUMwMCBcdUJDMUNcdUMwRERcdUQ1ODhcdUMyQjVcdUIyQzhcdUIyRTQuIG1heEluY2x1c2l2ZSBcdUFDMTIgPSAnJ3swfScnXHVDNzQwKFx1QjI5NCkgXHVBRTMwXHVCQ0Y4IFx1QzcyMFx1RDYxNSAnJ3sxfScnXHVDNzU4IG1pbkV4Y2x1c2l2ZVx1QkNGNFx1QjJFNCBcdUNFRTRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBtYXhMZW5ndGgtdmFsaWQtcmVzdHJpY3Rpb24gPSBtYXhMZW5ndGgtdmFsaWQtcmVzdHJpY3Rpb246IHsyfVx1Qzc1OCBcdUM4MTVcdUM3NThcdUM1RDBcdUMxMUMgbWF4TGVuZ3RoIFx1QUMxMiA9ICcnezB9JydcdUM3NDAoXHVCMjk0KSBcdUFFMzBcdUJDRjggXHVDNzIwXHVENjE1ICcnezF9JydcdUM3NTggXHVBQzEyXHVCQ0Y0XHVCMkU0IFx1Qzc5MVx1QUM3MFx1QjA5OCBcdUFDMTlcdUM1NDRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBtZy1wcm9wcy1jb3JyZWN0LjIgPSBtZy1wcm9wcy1jb3JyZWN0LjI6ICcnezB9JycgXHVBREY4XHVCOEY5XHVDNUQwIFx1QjMwMFx1RDU1QyBcdUMyMUNcdUQ2NTggXHVDODE1XHVDNzU4XHVBQzAwIFx1QUMxMFx1QzlDMFx1QjQxOFx1QzVDOFx1QzJCNVx1QjJDOFx1QjJFNC4gXHVDMjFDXHVENjU4XHVDODAxXHVDNzNDXHVCODVDIFx1QjRBNFx1QzVEMCBcdUM2MjRcdUIyOTQgJ3sndGVybSd9JyBcdUM4NzBcdUFDMDEgXHVBQzEyXHVDNzc0ICd7J3Rlcm0nfSdcdUM3NzQgXHVBREY4XHVCOEY5IFx1Qzc5MFx1QzJFMFx1Qzc3OCBcdUM4NzBcdUFDMDFcdUM1RDAgXHVCM0M0XHVCMkVDXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBtaW5FeGNsdXNpdmUtbGVzcy10aGFuLWVxdWFsLXRvLW1heEV4Y2x1c2l2ZSA9IG1pbkV4Y2x1c2l2ZS1sZXNzLXRoYW4tZXF1YWwtdG8tbWF4RXhjbHVzaXZlOiB7Mn1cdUM3NTggXHVDODE1XHVDNzU4XHVDNUQwXHVDMTFDIG1pbkV4Y2x1c2l2ZSBcdUFDMTIgPSAnJ3swfScnXHVDNzQwKFx1QjI5NCkgbWF4RXhjbHVzaXZlIFx1QUMxMiA9ICcnezF9JydcdUJDRjRcdUIyRTQgXHVDNzkxXHVBQzcwXHVCMDk4IFx1QUMxOVx1QzU0NFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIG1pbkV4Y2x1c2l2ZS1sZXNzLXRoYW4tbWF4SW5jbHVzaXZlID0gbWluRXhjbHVzaXZlLWxlc3MtdGhhbi1tYXhJbmNsdXNpdmU6IHsyfVx1Qzc1OCBcdUM4MTVcdUM3NThcdUM1RDBcdUMxMUMgbWluRXhjbHVzaXZlIFx1QUMxMiA9ICcnezB9JydcdUM3NDAoXHVCMjk0KSBtYXhJbmNsdXNpdmUgXHVBQzEyID0gJyd7MX0nJ1x1QkNGNFx1QjJFNCBcdUM3OTFcdUM1NDRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBtaW5FeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMSA9IG1pbkV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4xOiAnJ3syfScnIFx1QzcyMFx1RDYxNVx1QzVEMCBcdUIzMDBcdUQ1NzQgXHVDNjI0XHVCOTU4XHVBQzAwIFx1QkMxQ1x1QzBERFx1RDU4OFx1QzJCNVx1QjJDOFx1QjJFNC4gbWluRXhjbHVzaXZlIFx1QUMxMiA9ICcnezB9JydcdUM3NDAoXHVCMjk0KSBcdUFFMzBcdUJDRjggXHVDNzIwXHVENjE1ICcnezF9JydcdUM3NTggbWluRXhjbHVzaXZlXHVCQ0Y0XHVCMkU0IFx1RDA2Q1x1QUM3MFx1QjA5OCBcdUFDMTlcdUM1NDRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBtaW5FeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMiA9IG1pbkV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4yOiAnJ3syfScnIFx1QzcyMFx1RDYxNVx1QzVEMCBcdUIzMDBcdUQ1NzQgXHVDNjI0XHVCOTU4XHVBQzAwIFx1QkMxQ1x1QzBERFx1RDU4OFx1QzJCNVx1QjJDOFx1QjJFNC4gbWluRXhjbHVzaXZlIFx1QUMxMiA9ICcnezB9JydcdUM3NDAoXHVCMjk0KSBcdUFFMzBcdUJDRjggXHVDNzIwXHVENjE1ICcnezF9JydcdUM3NTggbWF4SW5jbHVzaXZlXHVCQ0Y0XHVCMkU0IFx1Qzc5MVx1QUM3MFx1QjA5OCBcdUFDMTlcdUM1NDRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBtaW5FeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMyA9IG1pbkV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4zOiAnJ3syfScnIFx1QzcyMFx1RDYxNVx1QzVEMCBcdUIzMDBcdUQ1NzQgXHVDNjI0XHVCOTU4XHVBQzAwIFx1QkMxQ1x1QzBERFx1RDU4OFx1QzJCNVx1QjJDOFx1QjJFNC4gbWluRXhjbHVzaXZlIFx1QUMxMiA9ICcnezB9JydcdUM3NDAoXHVCMjk0KSBcdUFFMzBcdUJDRjggXHVDNzIwXHVENjE1ICcnezF9JydcdUM3NTggbWluSW5jbHVzaXZlXHVCQ0Y0XHVCMkU0IFx1RDA2Q1x1QUM3MFx1QjA5OCBcdUFDMTlcdUM1NDRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBtaW5FeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uNCA9IG1pbkV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi40OiAnJ3syfScnIFx1QzcyMFx1RDYxNVx1QzVEMCBcdUIzMDBcdUQ1NzQgXHVDNjI0XHVCOTU4XHVBQzAwIFx1QkMxQ1x1QzBERFx1RDU4OFx1QzJCNVx1QjJDOFx1QjJFNC4gbWluRXhjbHVzaXZlIFx1QUMxMiA9ICcnezB9JydcdUM3NDAoXHVCMjk0KSBcdUFFMzBcdUJDRjggXHVDNzIwXHVENjE1ICcnezF9JydcdUM3NTggbWF4RXhjbHVzaXZlXHVCQ0Y0XHVCMkU0IFx1Qzc5MVx1QzU0NFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIG1pbkluY2x1c2l2ZS1sZXNzLXRoYW4tZXF1YWwtdG8tbWF4SW5jbHVzaXZlID0gbWluSW5jbHVzaXZlLWxlc3MtdGhhbi1lcXVhbC10by1tYXhJbmNsdXNpdmU6IHsyfVx1Qzc1OCBcdUM4MTVcdUM3NThcdUM1RDBcdUMxMUMgbWluSW5jbHVzaXZlIFx1QUMxMiA9ICcnezB9JydcdUM3NDAoXHVCMjk0KSBtYXhJbmNsdXNpdmUgXHVBQzEyID0gJyd7MX0nJ1x1QkNGNFx1QjJFNCBcdUM3OTFcdUFDNzBcdUIwOTggXHVBQzE5XHVDNTQ0XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgbWluSW5jbHVzaXZlLWxlc3MtdGhhbi1tYXhFeGNsdXNpdmUgPSBtaW5JbmNsdXNpdmUtbGVzcy10aGFuLW1heEV4Y2x1c2l2ZTogezJ9XHVDNzU4IFx1QzgxNVx1Qzc1OFx1QzVEMFx1QzExQyBtaW5JbmNsdXNpdmUgXHVBQzEyID0gJyd7MH0nJ1x1Qzc0MChcdUIyOTQpIG1heEV4Y2x1c2l2ZSBcdUFDMTIgPSAnJ3sxfScnXHVCQ0Y0XHVCMkU0IFx1Qzc5MVx1QzU0NFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIG1pbkluY2x1c2l2ZS1taW5FeGNsdXNpdmUgPSBtaW5JbmNsdXNpdmUtbWluRXhjbHVzaXZlOiBtaW5JbmNsdXNpdmVcdUM2NDAgbWluRXhjbHVzaXZlXHVCMjk0IFx1QjNEOVx1Qzc3Q1x1RDU1QyBcdUIzNzBcdUM3NzRcdUQxMzAgXHVDNzIwXHVENjE1XHVDNUQwIFx1QjMwMFx1RDU3NCBcdUM5QzBcdUM4MTVcdUI0MThcdUM5QzAgXHVDNTRBXHVDNTQ0XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4gezJ9XHVDNUQwIG1pbkluY2x1c2l2ZSA9ICcnezB9JydcdUFDRkMoXHVDNjQwKSBtaW5FeGNsdXNpdmUgPSAnJ3sxfScnXHVDNzc0KFx1QUMwMCkgXHVDOUMwXHVDODE1XHVCNDE4XHVDNUM4XHVDMkI1XHVCMkM4XHVCMkU0LgotICAgICAgICBtaW5JbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMSA9IG1pbkluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4xOiAnJ3syfScnIFx1QzcyMFx1RDYxNVx1QzVEMCBcdUIzMDBcdUQ1NzQgXHVDNjI0XHVCOTU4XHVBQzAwIFx1QkMxQ1x1QzBERFx1RDU4OFx1QzJCNVx1QjJDOFx1QjJFNC4gbWluSW5jbHVzaXZlIFx1QUMxMiA9ICcnezB9JydcdUM3NDAoXHVCMjk0KSBcdUFFMzBcdUJDRjggXHVDNzIwXHVENjE1ICcnezF9JydcdUM3NTggbWluSW5jbHVzaXZlXHVCQ0Y0XHVCMkU0IFx1RDA2Q1x1QUM3MFx1QjA5OCBcdUFDMTlcdUM1NDRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBtaW5JbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMiA9IG1pbkluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4yOiAnJ3syfScnIFx1QzcyMFx1RDYxNVx1QzVEMCBcdUIzMDBcdUQ1NzQgXHVDNjI0XHVCOTU4XHVBQzAwIFx1QkMxQ1x1QzBERFx1RDU4OFx1QzJCNVx1QjJDOFx1QjJFNC4gbWluSW5jbHVzaXZlIFx1QUMxMiA9ICcnezB9JydcdUM3NDAoXHVCMjk0KSBcdUFFMzBcdUJDRjggXHVDNzIwXHVENjE1ICcnezF9JydcdUM3NTggbWF4SW5jbHVzaXZlXHVCQ0Y0XHVCMkU0IFx1Qzc5MVx1QUM3MFx1QjA5OCBcdUFDMTlcdUM1NDRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBtaW5JbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMyA9IG1pbkluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4zOiAnJ3syfScnIFx1QzcyMFx1RDYxNVx1QzVEMCBcdUIzMDBcdUQ1NzQgXHVDNjI0XHVCOTU4XHVBQzAwIFx1QkMxQ1x1QzBERFx1RDU4OFx1QzJCNVx1QjJDOFx1QjJFNC4gbWluSW5jbHVzaXZlIFx1QUMxMiA9ICcnezB9JydcdUM3NDAoXHVCMjk0KSBcdUFFMzBcdUJDRjggXHVDNzIwXHVENjE1ICcnezF9JydcdUM3NTggbWluRXhjbHVzaXZlXHVCQ0Y0XHVCMkU0IFx1Q0VFNFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIG1pbkluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi40ID0gbWluSW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjQ6ICcnezJ9JycgXHVDNzIwXHVENjE1XHVDNUQwIFx1QjMwMFx1RDU3NCBcdUM2MjRcdUI5NThcdUFDMDAgXHVCQzFDXHVDMEREXHVENTg4XHVDMkI1XHVCMkM4XHVCMkU0LiBtaW5JbmNsdXNpdmUgXHVBQzEyID0gJyd7MH0nJ1x1Qzc0MChcdUIyOTQpIFx1QUUzMFx1QkNGOCBcdUM3MjBcdUQ2MTUgJyd7MX0nJ1x1Qzc1OCBtYXhFeGNsdXNpdmVcdUJDRjRcdUIyRTQgXHVDNzkxXHVDNTQ0XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgbWluTGVuZ3RoLWxlc3MtdGhhbi1lcXVhbC10by1tYXhMZW5ndGggPSBtaW5MZW5ndGgtbGVzcy10aGFuLWVxdWFsLXRvLW1heExlbmd0aDogezJ9XHVDNzU4IFx1QzgxNVx1Qzc1OFx1QzVEMFx1QzExQyBtaW5MZW5ndGggXHVBQzEyID0gJyd7MH0nJ1x1Qzc0MChcdUIyOTQpIG1heExlbmd0aCBcdUFDMTIgPSAnJ3sxfScnXHVCQ0Y0XHVCMkU0IFx1Qzc5MVx1QzU0NFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIG1pbkxlbmd0aC12YWxpZC1yZXN0cmljdGlvbiA9IG1pbkxlbmd0aC12YWxpZC1yZXN0cmljdGlvbjogezJ9XHVDNzU4IFx1QzgxNVx1Qzc1OFx1QzVEMFx1QzExQyBtaW5MZW5ndGggPSAnJ3swfScnXHVDNzQwKFx1QjI5NCkgXHVBRTMwXHVCQ0Y4IFx1QzcyMFx1RDYxNSAnJ3sxfScnXHVDNzU4IFx1QUMxMlx1QkNGNFx1QjJFNCBcdUQwNkNcdUFDNzBcdUIwOTggXHVBQzE5XHVDNTQ0XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgbm8teG1sbnMgPSBuby14bWxuczogXHVDMThEXHVDMTMxIFx1QzEyMFx1QzVCOFx1Qzc1OCB7bmFtZX1cdUM3NDAgJ3htbG5zJ1x1QzY0MCBcdUM3N0NcdUNFNThcdUQ1NThcdUM5QzAgXHVDNTRBXHVDNTQ0XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgbm8teHNpID0gbm8teHNpOiBcdUMxOERcdUMxMzEgXHVDMTIwXHVDNUI4XHVDNzU4ICd7J3RhcmdldCBuYW1lc3BhY2UnfSdcdUIyOTQgJyd7MH0nJ1x1QUNGQyhcdUM2NDApIFx1Qzc3Q1x1Q0U1OFx1RDU1OFx1QzlDMCBcdUM1NEFcdUM1NDRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBwLXByb3BzLWNvcnJlY3QuMi4xID0gcC1wcm9wcy1jb3JyZWN0LjIuMTogJyd7MH0nJ1x1Qzc1OCBcdUMxMjBcdUM1QjhcdUM1RDBcdUMxMUMgJydtaW5PY2N1cnMnJyBcdUFDMTJcdUM3NzQgJyd7MX0nJ1x1Qzc3NFx1QzlDMFx1QjlDQyBcdUM3NzQgXHVBQzEyXHVDNzQwICcnbWF4T2NjdXJzJycgXHVBQzEyICcnezJ9JydcdUJDRjRcdUIyRTQgXHVEMDZDXHVDOUMwIFx1QzU0QVx1QzU0NFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIHJjYXNlLU1hcEFuZFN1bS4xID0gcmNhc2UtTWFwQW5kU3VtLjE6IFx1Qzg3MFx1QUMwMSBcdUFDMDQgXHVDODA0XHVDQ0I0IFx1QUUzMFx1QjJBNSBcdUI5RTRcdUQ1NTFcdUM3NzQgXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LgotICAgICAgICByY2FzZS1NYXBBbmRTdW0uMiA9IHJjYXNlLU1hcEFuZFN1bS4yOiBcdUFERjhcdUI4RjlcdUM3NTggXHVCQzFDXHVDMEREIFx1QkM5NFx1QzcwNCh7MH0sezF9KVx1QUMwMCBcdUFFMzBcdUJDRjggXHVBREY4XHVCOEY5XHVDNzU4IFx1QkMxQ1x1QzBERCBcdUJDOTRcdUM3MDQoezJ9LHszfSlcdUM1RDAgXHVCMzAwXHVENTc0IFx1QzgwMVx1RDU2OVx1RDU1QyBcdUM4MUNcdUQ1NUMgXHVDMEFDXHVENTZEXHVDNzc0IFx1QzU0NFx1QjJEOVx1QjJDOFx1QjJFNC4KLSAgICAgICAgcmNhc2UtTmFtZUFuZFR5cGVPSy4xID0gcmNhc2UtTmFtZUFuZFR5cGVPSy4xOiBcdUM2OTRcdUMxOENcdUM1RDAgXHVCM0Q5XHVDNzdDXHVENTU4XHVDOUMwIFx1QzU0QVx1Qzc0MCBcdUM3NzRcdUI5ODQgXHVCQzBGIFx1QjMwMFx1QzBDMSBcdUIxMjRcdUM3ODRcdUMyQTRcdUQzOThcdUM3NzRcdUMyQTQoJyd7MX0nJyBcdUIxMjRcdUM3ODRcdUMyQTRcdUQzOThcdUM3NzRcdUMyQTRcdUM3NTggJyd7MH0nJyBcdUM2OTRcdUMxOEMgXHVCQzBGICcnezN9JycgXHVCMTI0XHVDNzg0XHVDMkE0XHVEMzk4XHVDNzc0XHVDMkE0XHVDNzU4ICcnezJ9JycgXHVDNjk0XHVDMThDKVx1QUMwMCBcdUM3ODhcdUMyQjVcdUIyQzhcdUIyRTQuCi0gICAgICAgIHJjYXNlLU5hbWVBbmRUeXBlT0suMiA9IHJjYXNlLU5hbWVBbmRUeXBlT0suMjogJ3sndGVybSd9J1x1Qzc3NCBcdUM2OTRcdUMxOEMgXHVDMTIwXHVDNUI4ICcnezB9JydcdUM3NzggXHVDODcwXHVBQzAxXHVDNUQwIFx1QjMwMFx1RDU3NCBcdUM2MjRcdUI5NThcdUFDMDAgXHVCQzFDXHVDMEREXHVENTg4XHVDMkI1XHVCMkM4XHVCMkU0LiBcdUM2OTRcdUMxOEMgXHVDMTIwXHVDNUI4XHVDNzU4ICd7J25pbGxhYmxlJ30nXHVDNzc0IHRydWVcdUM3NzRcdUM5QzBcdUI5Q0MgXHVBRTMwXHVCQ0Y4IFx1QzcyMFx1RDYxNVx1Qzc1OCBcdUQ1NzRcdUIyRjkgXHVDODcwXHVBQzAxXHVDNUQwICd7J25pbGxhYmxlJ30nXHVDNzc0IGZhbHNlXHVDNzc4IFx1QzY5NFx1QzE4QyBcdUMxMjBcdUM1QjhcdUM3NzQgXHVDNzg4XHVDMkI1XHVCMkM4XHVCMkU0LgotICAgICAgICByY2FzZS1OYW1lQW5kVHlwZU9LLjMgPSByY2FzZS1OYW1lQW5kVHlwZU9LLjM6ICd7J3Rlcm0nfSdcdUM3NzQgXHVDNjk0XHVDMThDIFx1QzEyMFx1QzVCOCAnJ3swfScnXHVDNzc4IFx1Qzg3MFx1QUMwMVx1QzVEMCBcdUIzMDBcdUQ1NzQgXHVDNjI0XHVCOTU4XHVBQzAwIFx1QkMxQ1x1QzBERFx1RDU4OFx1QzJCNVx1QjJDOFx1QjJFNC4gXHVCQzE4XHVCQ0Y1IFx1QkM5NFx1QzcwNCh7MX0sezJ9KVx1QUMwMCBcdUFFMzBcdUJDRjggXHVDNzIwXHVENjE1XHVDNUQwIFx1Qzc4OFx1QjI5NCBcdUQ1NzRcdUIyRjkgXHVDODcwXHVBQzAxXHVDNzU4IFx1QkM5NFx1QzcwNCh7M30sezR9KVx1QzVEMCBcdUIzMDBcdUQ1NzQgXHVDODAxXHVENTY5XHVENTVDIFx1QzgxQ1x1RDU1QyBcdUMwQUNcdUQ1NkRcdUM3NzQgXHVDNTQ0XHVCMkQ5XHVCMkM4XHVCMkU0LgotICAgICAgICByY2FzZS1OYW1lQW5kVHlwZU9LLjQuYSA9IHJjYXNlLU5hbWVBbmRUeXBlT0suNC5hOiAnJ3swfScnIFx1QzY5NFx1QzE4Q1x1QjI5NCBcdUFDRTBcdUM4MTVcdUI0MThcdUM1QjQgXHVDNzg4XHVDOUMwIFx1QzU0QVx1QzlDMFx1QjlDQyBcdUFFMzBcdUJDRjggXHVDNzIwXHVENjE1XHVDNzU4IFx1RDU3NFx1QjJGOSBcdUM2OTRcdUMxOENcdUIyOTQgJyd7MX0nJyBcdUFDMTJcdUM3M0NcdUI4NUMgXHVBQ0UwXHVDODE1XHVCNDE4XHVDNUI0IFx1Qzc4OFx1QzJCNVx1QjJDOFx1QjJFNC4KLSAgICAgICAgcmNhc2UtTmFtZUFuZFR5cGVPSy40LmIgPSByY2FzZS1OYW1lQW5kVHlwZU9LLjQuYjogJyd7MH0nJyBcdUM2OTRcdUMxOENcdUIyOTQgJyd7MX0nJyBcdUFDMTJcdUM3M0NcdUI4NUMgXHVBQ0UwXHVDODE1XHVCNDE4XHVDNUI0IFx1Qzc4OFx1QzlDMFx1QjlDQyBcdUFFMzBcdUJDRjggXHVDNzIwXHVENjE1XHVDNzU4IFx1RDU3NFx1QjJGOSBcdUM2OTRcdUMxOENcdUIyOTQgJyd7Mn0nJyBcdUFDMTJcdUM3M0NcdUI4NUMgXHVBQ0UwXHVDODE1XHVCNDE4XHVDNUI0IFx1Qzc4OFx1QzJCNVx1QjJDOFx1QjJFNC4KLSAgICAgICAgcmNhc2UtTmFtZUFuZFR5cGVPSy41ID0gcmNhc2UtTmFtZUFuZFR5cGVPSy41OiAnJ3swfScnIFx1QzY5NFx1QzE4Q1x1QzVEMCBcdUIzMDBcdUQ1NUMgSUQgXHVDODFDXHVDNTdEIFx1Qzg3MFx1QUM3NFx1Qzc0MCBcdUFFMzBcdUJDRjggXHVDNzIwXHVENjE1XHVDNzU4IElEIFx1QzgxQ1x1QzU3RCBcdUM4NzBcdUFDNzRcdUM1RDAgXHVCMzAwXHVENTVDIFx1QkQ4MFx1QkQ4NCBcdUM5RDFcdUQ1NjlcdUM3NzQgXHVDNTQ0XHVCMkQ5XHVCMkM4XHVCMkU0LgotICAgICAgICByY2FzZS1OYW1lQW5kVHlwZU9LLjYgPSByY2FzZS1OYW1lQW5kVHlwZU9LLjY6ICcnezB9JycgXHVDNjk0XHVDMThDXHVDNUQwIFx1QjMwMFx1RDU3NCBcdUQ1QzhcdUM2QTlcdUI0MThcdUM5QzAgXHVDNTRBXHVCMjk0IFx1QjMwMFx1Q0NCNFx1QjI5NCBcdUFFMzBcdUJDRjggXHVDNzIwXHVENjE1XHVDNzU4IFx1RDU3NFx1QjJGOSBcdUIzMDBcdUNDQjRcdUM1RDAgXHVCMzAwXHVENTVDIFx1QjMwMFx1QzlEMVx1RDU2OVx1Qzc3NCBcdUM1NDRcdUIyRDlcdUIyQzhcdUIyRTQuCi0gICAgICAgIHJjYXNlLU5hbWVBbmRUeXBlT0suNyA9IHJjYXNlLU5hbWVBbmRUeXBlT0suNzogJyd7MH0nJyBcdUM2OTRcdUMxOENcdUM3NTggXHVDNzIwXHVENjE1ICcnezF9JydcdUM3NDAoXHVCMjk0KSBcdUFFMzBcdUJDRjggXHVDNjk0XHVDMThDXHVDNzU4IFx1QzcyMFx1RDYxNSAnJ3syfScnXHVDNUQwXHVDMTFDIFx1RDMwQ1x1QzBERFx1QjQxQyBcdUFDODNcdUM3NzQgXHVDNTQ0XHVCMkQ5XHVCMkM4XHVCMkU0LgotICAgICAgICByY2FzZS1OU0NvbXBhdC4xID0gcmNhc2UtTlNDb21wYXQuMTogJyd7MH0nJyBcdUM2OTRcdUMxOENcdUM1RDBcdUIyOTQgXHVBRTMwXHVCQ0Y4IFx1QzcyMFx1RDYxNVx1Qzc1OCBcdUM2NDBcdUM3N0NcdUI0REMgXHVDRTc0XHVCNERDIFx1QkIzOFx1Qzc5MFx1QzVEMFx1QzExQyBcdUQ1QzhcdUM2QTlcdUQ1NThcdUM5QzAgXHVDNTRBXHVCMjk0ICcnezF9JycgXHVCMTI0XHVDNzg0XHVDMkE0XHVEMzk4XHVDNzc0XHVDMkE0XHVBQzAwIFx1Qzc4OFx1QzJCNVx1QjJDOFx1QjJFNC4KLSAgICAgICAgcmNhc2UtTlNDb21wYXQuMiA9IHJjYXNlLU5TQ29tcGF0LjI6ICd7J3Rlcm0nfSdcdUM3NzQgXHVDNjk0XHVDMThDIFx1QzEyMFx1QzVCOCAnJ3swfScnXHVDNzc4IFx1Qzg3MFx1QUMwMVx1QzVEMCBcdUIzMDBcdUQ1NzQgXHVDNjI0XHVCOTU4XHVBQzAwIFx1QkMxQ1x1QzBERFx1RDU4OFx1QzJCNVx1QjJDOFx1QjJFNC4gXHVCQzE4XHVCQ0Y1IFx1QkM5NFx1QzcwNCh7MX0sezJ9KVx1QUMwMCBcdUFFMzBcdUJDRjggXHVDNzIwXHVENjE1XHVDNUQwIFx1Qzc4OFx1QjI5NCBcdUQ1NzRcdUIyRjkgXHVDODcwXHVBQzAxXHVDNzU4IFx1QkM5NFx1QzcwNCh7M30sezR9KVx1QzVEMCBcdUIzMDBcdUQ1NzQgXHVDODAxXHVENTY5XHVENTVDIFx1QzgxQ1x1RDU1QyBcdUMwQUNcdUQ1NkRcdUM3NzQgXHVDNTQ0XHVCMkQ5XHVCMkM4XHVCMkU0LgotICAgICAgICByY2FzZS1OU1JlY3Vyc2VDaGVja0NhcmRpbmFsaXR5LjEgPSByY2FzZS1OU1JlY3Vyc2VDaGVja0NhcmRpbmFsaXR5LjE6IFx1Qzg3MFx1QUMwMSBcdUFDMDQgXHVDODA0XHVDQ0I0IFx1QUUzMFx1QjJBNSBcdUI5RTRcdUQ1NTFcdUM3NzQgXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LgotICAgICAgICByY2FzZS1OU1JlY3Vyc2VDaGVja0NhcmRpbmFsaXR5LjIgPSByY2FzZS1OU1JlY3Vyc2VDaGVja0NhcmRpbmFsaXR5LjI6IFx1QURGOFx1QjhGOVx1Qzc1OCBcdUJDMUNcdUMwREQgXHVCQzk0XHVDNzA0KHswfSx7MX0pXHVBQzAwIFx1QUUzMFx1QkNGOCBcdUM2NDBcdUM3N0NcdUI0REMgXHVDRTc0XHVCNERDIFx1QkIzOFx1Qzc5MFx1Qzc1OCBcdUJDOTRcdUM3MDQoezJ9LHszfSlcdUM1RDAgXHVCMzAwXHVENTc0IFx1QzgwMVx1RDU2OVx1RDU1QyBcdUM4MUNcdUQ1NUMgXHVDMEFDXHVENTZEXHVDNzc0IFx1QzU0NFx1QjJEOVx1QjJDOFx1QjJFNC4KLSAgICAgICAgcmNhc2UtTlNTdWJzZXQuMSA9IHJjYXNlLU5TU3Vic2V0LjE6IFx1QzY0MFx1Qzc3Q1x1QjREQyBcdUNFNzRcdUI0REMgXHVCQjM4XHVDNzkwXHVBQzAwIFx1QUUzMFx1QkNGOCBcdUM3MjBcdUQ2MTVcdUM3NTggXHVENTc0XHVCMkY5IFx1QzY0MFx1Qzc3Q1x1QjREQyBcdUNFNzRcdUI0REMgXHVCQjM4XHVDNzkwXHVDNUQwIFx1QjMwMFx1RDU1QyBcdUJEODBcdUJEODQgXHVDOUQxXHVENTY5XHVDNzc0IFx1QzU0NFx1QjJEOVx1QjJDOFx1QjJFNC4KLSAgICAgICAgcmNhc2UtTlNTdWJzZXQuMiA9IHJjYXNlLU5TU3Vic2V0LjI6IFx1QzY0MFx1Qzc3Q1x1QjREQyBcdUNFNzRcdUI0REMgXHVCQjM4XHVDNzkwXHVDNzU4IFx1QkMxQ1x1QzBERCBcdUJDOTRcdUM3MDQoezB9LHsxfSlcdUFDMDAgXHVBRTMwXHVCQ0Y4IFx1QzcyMFx1RDYxNVx1Qzc1OCBcdUM2NDBcdUM3N0NcdUI0REMgXHVDRTc0XHVCNERDIFx1QkIzOFx1Qzc5MCBcdUJDOTRcdUM3MDQoezJ9LHszfSlcdUM1RDAgXHVCMzAwXHVENTc0IFx1QzgwMVx1RDU2OVx1RDU1QyBcdUM4MUNcdUQ1NUMgXHVDMEFDXHVENTZEXHVDNzc0IFx1QzU0NFx1QjJEOVx1QjJDOFx1QjJFNC4KLSAgICAgICAgcmNhc2UtTlNTdWJzZXQuMyA9IHJjYXNlLU5TU3Vic2V0LjM6IFx1QzY0MFx1Qzc3Q1x1QjREQyBcdUNFNzRcdUI0REMgXHVCQjM4XHVDNzkwXHVDNzU4IFx1RDUwNFx1Qjg1Q1x1QzEzOFx1QzJBNCBcdUNGNThcdUQxNTBcdUNFMjAgJyd7MH0nJ1x1Qzc3NChcdUFDMDApIFx1QUUzMFx1QkNGOCBcdUM3MjBcdUQ2MTVcdUM3NTggXHVDRjU4XHVEMTUwXHVDRTIwICcnezF9JydcdUJDRjRcdUIyRTQgXHVENTU4XHVDNzA0XHVDNzg1XHVCMkM4XHVCMkU0LgotICAgICAgICByY2FzZS1SZWN1cnNlLjEgPSByY2FzZS1SZWN1cnNlLjE6IFx1QURGOFx1QjhGOVx1Qzc1OCBcdUJDMUNcdUMwREQgXHVCQzk0XHVDNzA0KHswfSx7MX0pXHVBQzAwIFx1QUUzMFx1QkNGOCBcdUFERjhcdUI4RjlcdUM3NTggXHVCQzFDXHVDMEREIFx1QkM5NFx1QzcwNCh7Mn0sezN9KVx1QzVEMCBcdUIzMDBcdUQ1NzQgXHVDODAxXHVENTY5XHVENTVDIFx1QzgxQ1x1RDU1QyBcdUMwQUNcdUQ1NkRcdUM3NzQgXHVDNTQ0XHVCMkQ5XHVCMkM4XHVCMkU0LgotICAgICAgICByY2FzZS1SZWN1cnNlLjIgPSByY2FzZS1SZWN1cnNlLjI6IFx1Qzg3MFx1QUMwMSBcdUFDMDQgXHVDODA0XHVDQ0I0IFx1QUUzMFx1QjJBNSBcdUI5RTRcdUQ1NTFcdUM3NzQgXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LgotICAgICAgICByY2FzZS1SZWN1cnNlTGF4LjEgPSByY2FzZS1SZWN1cnNlTGF4LjE6IFx1QURGOFx1QjhGOVx1Qzc1OCBcdUJDMUNcdUMwREQgXHVCQzk0XHVDNzA0KHswfSx7MX0pXHVBQzAwIFx1QUUzMFx1QkNGOCBcdUFERjhcdUI4RjlcdUM3NTggXHVCQzFDXHVDMEREIFx1QkM5NFx1QzcwNCh7Mn0sezN9KVx1QzVEMCBcdUIzMDBcdUQ1NzQgXHVDODAxXHVENTY5XHVENTVDIFx1QzgxQ1x1RDU1QyBcdUMwQUNcdUQ1NkRcdUM3NzQgXHVDNTQ0XHVCMkQ5XHVCMkM4XHVCMkU0LgotICAgICAgICByY2FzZS1SZWN1cnNlTGF4LjIgPSByY2FzZS1SZWN1cnNlTGF4LjI6IFx1Qzg3MFx1QUMwMSBcdUFDMDQgXHVDODA0XHVDQ0I0IFx1QUUzMFx1QjJBNSBcdUI5RTRcdUQ1NTFcdUM3NzQgXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LgotICAgICAgICByY2FzZS1SZWN1cnNlVW5vcmRlcmVkLjEgPSByY2FzZS1SZWN1cnNlVW5vcmRlcmVkLjE6IFx1QURGOFx1QjhGOVx1Qzc1OCBcdUJDMUNcdUMwREQgXHVCQzk0XHVDNzA0KHswfSx7MX0pXHVBQzAwIFx1QUUzMFx1QkNGOCBcdUFERjhcdUI4RjlcdUM3NTggXHVCQzFDXHVDMEREIFx1QkM5NFx1QzcwNCh7Mn0sezN9KVx1QzVEMCBcdUIzMDBcdUQ1NzQgXHVDODAxXHVENTY5XHVENTVDIFx1QzgxQ1x1RDU1QyBcdUMwQUNcdUQ1NkRcdUM3NzQgXHVDNTQ0XHVCMkQ5XHVCMkM4XHVCMkU0LgotICAgICAgICByY2FzZS1SZWN1cnNlVW5vcmRlcmVkLjIgPSByY2FzZS1SZWN1cnNlVW5vcmRlcmVkLjI6IFx1Qzg3MFx1QUMwMSBcdUFDMDQgXHVDODA0XHVDQ0I0IFx1QUUzMFx1QjJBNSBcdUI5RTRcdUQ1NTFcdUM3NzQgXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LgotIyAgICAgICAgV2UncmUgdXNpbmcgc2NoLXByb3BzLWNvcnJlY3QuMiBpbnN0ZWFkIG9mIHRoZSBvbGQgc3JjLXJlZGVmaW5lLjEKLSMgICAgICAgIHNyYy1yZWRlZmluZS4xID0gc3JjLXJlZGVmaW5lLjE6IFRoZSBjb21wb25lbnQgJyd7MH0nJyBpcyBiZWdpbiByZWRlZmluZWQsIGJ1dCBpdHMgY29ycmVzcG9uZGluZyBjb21wb25lbnQgaXNuJ3QgaW4gdGhlIHNjaGVtYSBkb2N1bWVudCBiZWluZyByZWRlZmluZWQgKHdpdGggbmFtZXNwYWNlICcnezJ9JycpLCBidXQgaW4gYSBkaWZmZXJlbnQgZG9jdW1lbnQsIHdpdGggbmFtZXNwYWNlICcnezF9JycuCi0gICAgICAgIHNjaC1wcm9wcy1jb3JyZWN0LjIgPSBzY2gtcHJvcHMtY29ycmVjdC4yOiBcdUMyQTRcdUQwQTRcdUI5QzhcdUM1RDBcdUIyOTQgXHVCM0Q5XHVDNzdDXHVENTVDIFx1Qzc3NFx1Qjk4NFx1Qzc0NCBcdUFDMDBcdUM5QzQgXHVCNDUwIFx1QUMxQ1x1Qzc1OCBcdUM4MDRcdUM1RUQgXHVBRDZDXHVDMTMxIFx1QzY5NFx1QzE4Q1x1QUMwMCBcdUQzRUNcdUQ1NjhcdUI0MjAgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4gXHVDNzc0IFx1QzJBNFx1RDBBNFx1QjlDOFx1QzVEMFx1QjI5NCBcdUI0NTAgXHVBQzFDXHVDNzU4ICcnezB9JydcdUM3NzQoXHVBQzAwKSBcdUQzRUNcdUQ1NjhcdUI0MThcdUM1QjQgXHVDNzg4XHVDMkI1XHVCMkM4XHVCMkU0LgotICAgICAgICBzdC1wcm9wcy1jb3JyZWN0LjIgPSBzdC1wcm9wcy1jb3JyZWN0LjI6IFx1QjJFOFx1QzIxQyBcdUM3MjBcdUQ2MTUgJyd7MH0nJ1x1QzVEMCBcdUIzMDBcdUQ1NUMgXHVDMjFDXHVENjU4IFx1QzgxNVx1Qzc1OFx1QUMwMCBcdUFDMTBcdUM5QzBcdUI0MThcdUM1QzhcdUMyQjVcdUIyQzhcdUIyRTQuIFx1QjUzMFx1Qjc3Q1x1QzExQyAnJ3swfScnXHVDNzQwKFx1QjI5NCkgXHVBQ0UwXHVDNzIwXHVENTVDIFx1QzcyMFx1RDYxNSBcdUFDQzRcdUNFMzVcdUM1RDAgXHVEM0VDXHVENTY4XHVCNDFDIFx1QUM4M1x1Qzc3NFx1QkE3MCBcdUM3NzRcdUIyOTQgXHVDNjI0XHVCOTU4XHVDNzg1XHVCMkM4XHVCMkU0LgotICAgICAgICBzdC1wcm9wcy1jb3JyZWN0LjMgPSBzdC1wcm9wcy1jb3JyZWN0LjM6ICcnezB9JycgXHVDNzIwXHVENjE1XHVDNUQwIFx1QjMwMFx1RDU3NCBcdUM2MjRcdUI5NThcdUFDMDAgXHVCQzFDXHVDMEREXHVENTg4XHVDMkI1XHVCMkM4XHVCMkU0LiAneydiYXNlIHR5cGUgZGVmaW5pdGlvbid9JyAnJ3sxfScnXHVDNzU4ICd7J2ZpbmFsJ30nIFx1QUMxMlx1Qzc0MCBcdUM4MUNcdUQ1NUMgXHVDMEFDXHVENTZEXHVDNUQwIFx1Qzc1OFx1RDU1QyBcdUQzMENcdUMwRERcdUM3NDQgXHVBRTA4XHVDOUMwXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICB0b3RhbERpZ2l0cy12YWxpZC1yZXN0cmljdGlvbiA9IHRvdGFsRGlnaXRzLXZhbGlkLXJlc3RyaWN0aW9uOiB7Mn1cdUM3NTggXHVDODE1XHVDNzU4XHVDNUQwXHVDMTFDICcndG90YWxEaWdpdHMnJyBcdUJBNzRcdUM1RDAgXHVCMzAwXHVENTVDICcnezB9JycgXHVBQzEyXHVDNzc0IFx1QkQ4MFx1QzgwMVx1RDU2OVx1RDU2OVx1QjJDOFx1QjJFNC4gXHVDNzc0IFx1QUMxMlx1Qzc0MCBcdUM4NzBcdUMwQzEgXHVDNzIwXHVENjE1IFx1QzkxMSBcdUQ1NThcdUIwOThcdUM1RDBcdUMxMUMgJyd7MX0nJyhcdUM3M0MpXHVCODVDIFx1QzEyNFx1QzgxNVx1QjQxQyAnJ3RvdGFsRGlnaXRzJydcdUM1RDAgXHVCMzAwXHVENTVDIFx1QUMxMlx1QkNGNFx1QjJFNCBcdUM3OTFcdUFDNzBcdUIwOTggXHVBQzE5XHVDNTQ0XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgd2hpdGVTcGFjZS12YWxpZC1yZXN0cmljdGlvbi4xID0gd2hpdGVTcGFjZS12YWxpZC1yZXN0cmljdGlvbi4xOiB7MH1cdUM3NTggXHVDODE1XHVDNzU4XHVDNUQwXHVDMTFDICcnd2hpdGVzcGFjZScnIFx1QkE3NFx1QzVEMCBcdUIzMDBcdUQ1NUMgJyd7MX0nJyBcdUFDMTJcdUM3NzQgXHVCRDgwXHVDODAxXHVENTY5XHVENTY5XHVCMkM4XHVCMkU0LiAnJ3doaXRlc3BhY2UnJ1x1QzVEMCBcdUIzMDBcdUQ1NUMgXHVBQzEyXHVDNzc0IFx1Qzg3MFx1QzBDMSBcdUM3MjBcdUQ2MTUgXHVDOTExIFx1RDU1OFx1QjA5OFx1QzVEMFx1QzExQyAnJ2NvbGxhcHNlJydcdUI4NUMgXHVDMTI0XHVDODE1XHVCNDE4XHVDNUM4XHVBRTMwIFx1QjU0Q1x1QkIzOFx1Qzc4NVx1QjJDOFx1QjJFNC4KLSAgICAgICAgd2hpdGVTcGFjZS12YWxpZC1yZXN0cmljdGlvbi4yID0gd2hpdGVTcGFjZS12YWxpZC1yZXN0cmljdGlvbi4yOiB7MH1cdUM3NTggXHVDODE1XHVDNzU4XHVDNUQwXHVDMTFDICcnd2hpdGVzcGFjZScnIFx1QkE3NFx1QzVEMCBcdUIzMDBcdUQ1NUMgJydwcmVzZXJ2ZScnIFx1QUMxMlx1Qzc3NCBcdUJEODBcdUM4MDFcdUQ1NjlcdUQ1NjlcdUIyQzhcdUIyRTQuICcnd2hpdGVzcGFjZScnXHVDNUQwIFx1QjMwMFx1RDU1QyBcdUFDMTJcdUM3NzQgXHVDODcwXHVDMEMxIFx1QzcyMFx1RDYxNSBcdUM5MTEgXHVENTU4XHVCMDk4XHVDNUQwXHVDMTFDICcncmVwbGFjZScnXHVCODVDIFx1QzEyNFx1QzgxNVx1QjQxOFx1QzVDOFx1QUUzMCBcdUI1NENcdUJCMzhcdUM3ODVcdUIyQzhcdUIyRTQuCi0KLSNzY2hlbWEgZm9yIFNjaGVtYXMKLQotICAgICAgICBzNHMtYXR0LWludmFsaWQtdmFsdWUgPSBzNHMtYXR0LWludmFsaWQtdmFsdWU6ICcnezB9JycgXHVDNjk0XHVDMThDXHVDNzU4ICcnezF9JydcdUM1RDAgXHVCMzAwXHVENTVDIFx1QzE4RFx1QzEzMVx1QUMxMlx1Qzc3NCBcdUJEODBcdUM4MDFcdUQ1NjlcdUQ1NjlcdUIyQzhcdUIyRTQuIFx1QUUzMFx1Qjg1RFx1QjQxQyBcdUM2RDBcdUM3Nzg6IHsyfQotICAgICAgICBzNHMtYXR0LW11c3QtYXBwZWFyID0gczRzLWF0dC1tdXN0LWFwcGVhcjogJyd7MX0nJyBcdUMxOERcdUMxMzFcdUM3NDAgJyd7MH0nJyBcdUM2OTRcdUMxOENcdUM1RDAgXHVCMDk4XHVEMEMwXHVCMDk4XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgczRzLWF0dC1ub3QtYWxsb3dlZCA9IHM0cy1hdHQtbm90LWFsbG93ZWQ6ICcnezF9JycgXHVDMThEXHVDMTMxXHVDNzQwICcnezB9JycgXHVDNjk0XHVDMThDXHVDNUQwIFx1QjA5OFx1RDBDMFx1QjBBMCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LgotICAgICAgICBzNHMtZWx0LWludmFsaWQgPSBzNHMtZWx0LWludmFsaWQ6ICcnezB9JycgXHVDNjk0XHVDMThDXHVCMjk0IFx1QzJBNFx1RDBBNFx1QjlDOCBcdUJCMzhcdUMxMUNcdUM1RDBcdUMxMUMgXHVDODAxXHVENTY5XHVENTVDIFx1QzY5NFx1QzE4Q1x1QUMwMCBcdUM1NDRcdUIyRDlcdUIyQzhcdUIyRTQuCi0gICAgICAgIHM0cy1lbHQtbXVzdC1tYXRjaC4xID0gczRzLWVsdC1tdXN0LW1hdGNoLjE6ICcnezB9JydcdUM3NTggXHVDRjU4XHVEMTUwXHVDRTIwXHVCMjk0IHsxfVx1QUNGQyhcdUM2NDApIFx1Qzc3Q1x1Q0U1OFx1RDU3NFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuIHsyfVx1QzVEMFx1QzExQyBcdUMyRENcdUM3OTFcdUI0MUMgXHVCQjM4XHVDODFDXHVBQzAwIFx1QkMxQ1x1QUNBQ1x1QjQxOFx1QzVDOFx1QzJCNVx1QjJDOFx1QjJFNC4KLSAgICAgICAgczRzLWVsdC1tdXN0LW1hdGNoLjIgPSBzNHMtZWx0LW11c3QtbWF0Y2guMjogJyd7MH0nJ1x1Qzc1OCBcdUNGNThcdUQxNTBcdUNFMjBcdUIyOTQgezF9XHVBQ0ZDKFx1QzY0MCkgXHVDNzdDXHVDRTU4XHVENTc0XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4gXHVCQzFDXHVBQ0FDXHVCNDFDIFx1QzY5NFx1QzE4Q1x1QUMwMCBcdUJEODBcdUM4NzFcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgICMgdGhlICJpbnZhbGlkLWNvbnRlbnQiIG1lc3NhZ2VzIHByb3ZpZGUgbGVzcyBpbmZvcm1hdGlvbiB0aGFuIHRoZSAibXVzdC1tYXRjaCIgY291bnRlcnBhcnRzIGFib3ZlLiBUaGV5J3JlIHVzZWQgZm9yIGNvbXBsZXggdHlwZXMgd2hlbiBwcm92aWRpbmcgYSAibWF0Y2giIHdvdWxkIGJlIGFuIGluZm9ybWF0aW9uIGR1bXAKLSAgICAgICAgczRzLWVsdC1pbnZhbGlkLWNvbnRlbnQuMSA9IHM0cy1lbHQtaW52YWxpZC1jb250ZW50LjE6ICcnezB9JydcdUM3NTggXHVDRjU4XHVEMTUwXHVDRTIwXHVBQzAwIFx1QkQ4MFx1QzgwMVx1RDU2OVx1RDU2OVx1QjJDOFx1QjJFNC4gJyd7MX0nJyBcdUM2OTRcdUMxOENcdUFDMDAgXHVCRDgwXHVDODAxXHVENTY5XHVENTU4XHVBQzcwXHVCMDk4IFx1QjEwOFx1QkIzNCBcdUM3OTBcdUM4RkMgXHVCQzFDXHVDMEREXHVENTU4XHVBQzcwXHVCMDk4IFx1RDU3NFx1QjJGOSBcdUM2OTRcdUMxOENcdUM3NTggXHVDNzA0XHVDRTU4XHVBQzAwIFx1Qzc5OFx1QkFCQlx1QjQxOFx1QzVDOFx1QzJCNVx1QjJDOFx1QjJFNC4KLSAgICAgICAgczRzLWVsdC1pbnZhbGlkLWNvbnRlbnQuMiA9IHM0cy1lbHQtaW52YWxpZC1jb250ZW50LjI6ICcnezB9JydcdUM3NTggXHVDRjU4XHVEMTUwXHVDRTIwXHVBQzAwIFx1QkQ4MFx1QzgwMVx1RDU2OVx1RDU2OVx1QjJDOFx1QjJFNC4gJyd7MX0nJyBcdUM2OTRcdUMxOENcdUIyOTQgXHVCRTQ0XHVDNkNDIFx1QjQ1OCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LgotICAgICAgICBzNHMtZWx0LWludmFsaWQtY29udGVudC4zID0gczRzLWVsdC1pbnZhbGlkLWNvbnRlbnQuMzogJyd7MH0nJyBcdUM3MjBcdUQ2MTVcdUM3NTggXHVDNjk0XHVDMThDXHVCMjk0IDxzY2hlbWE+IFx1QzY5NFx1QzE4Q1x1Qzc1OCBcdUQ1NThcdUM3MDQgXHVENTZEXHVCQUE5XHVDNzNDXHVCODVDIFx1QzEyMFx1QzVCOCBcdUI0QTRcdUM1RDAgXHVCMDk4XHVEMEMwXHVCMEEwIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuCi0gICAgICAgIHM0cy1lbHQtc2NoZW1hLW5zID0gczRzLWVsdC1zY2hlbWEtbnM6ICcnezB9JycgXHVDNjk0XHVDMThDXHVDNzU4IFx1QjEyNFx1Qzc4NFx1QzJBNFx1RDM5OFx1Qzc3NFx1QzJBNFx1QjI5NCBcdUMyQTRcdUQwQTRcdUI5QzggXHVCMTI0XHVDNzg0XHVDMkE0XHVEMzk4XHVDNzc0XHVDMkE0ICcnaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEnJ1x1QzVEMFx1QzExQyBcdUM2NDBcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBzNHMtZWx0LWNoYXJhY3RlciA9IHM0cy1lbHQtY2hhcmFjdGVyOiAnJ3hzOmFwcGluZm8nJyBcdUJDMEYgJyd4czpkb2N1bWVudGF0aW9uJycgXHVDNjc4XHVDNUQwIFx1QjJFNFx1Qjk3OCBcdUMyQTRcdUQwQTRcdUI5QzggXHVDNjk0XHVDMThDXHVDNUQwXHVDMTFDXHVCMjk0IFx1QUNGNVx1QkMzMVx1Qzc3NCBcdUM1NDRcdUIyQ0MgXHVCQjM4XHVDNzkwXHVBQzAwIFx1RDVDOFx1QzZBOVx1QjQxOFx1QzlDMCBcdUM1NEFcdUMyQjVcdUIyQzhcdUIyRTQuICcnezB9JydcdUM3NzQoXHVBQzAwKSBcdUJDMUNcdUFDQUNcdUI0MThcdUM1QzhcdUMyQjVcdUIyQzhcdUIyRTQuCi0KLSMgY29kZXMgbm90IGRlZmluZWQgYnkgdGhlIHNwZWMKLQotICAgICAgICBjLWZpZWxkcy14cGF0aHMgPSBjLWZpZWxkcy14cGF0aHM6IFx1RDU0NFx1QjREQyBcdUFDMTIgPSAnJ3swfScnXHVDNzc0KFx1QUMwMCkgXHVCRDgwXHVDODAxXHVENTY5XHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBjLWdlbmVyYWwteHBhdGggPSBjLWdlbmVyYWwteHBhdGg6ICcnezB9JycgXHVENDVDXHVENjA0XHVDMkREXHVDNzQwIFhNTCBcdUMyQTRcdUQwQTRcdUI5QzhcdUFDMDAgXHVDOUMwXHVDNkQwXHVENTU4XHVCMjk0IFhQYXRoIFx1QkQ4MFx1QkQ4NCBcdUM5RDFcdUQ1NjlcdUM1RDAgXHVCMzAwXHVENTc0IFx1QkQ4MFx1QzgwMVx1RDU2OVx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICAgICAgYy1nZW5lcmFsLXhwYXRoLW5zID0gYy1nZW5lcmFsLXhwYXRoLW5zOiBYUGF0aCBcdUQ0NUNcdUQ2MDRcdUMyREQgJyd7MH0nJ1x1Qzc1OCBcdUIxMjRcdUM3ODRcdUMyQTRcdUQzOThcdUM3NzRcdUMyQTQgXHVDODExXHVCNDUwXHVDNUI0XHVBQzAwIFx1QjEyNFx1Qzc4NFx1QzJBNFx1RDM5OFx1Qzc3NFx1QzJBNFx1QzVEMCBcdUJDMTRcdUM3NzhcdUI0RENcdUI0MThcdUM5QzAgXHVDNTRBXHVDNTU4XHVDMkI1XHVCMkM4XHVCMkU0LgotICAgICAgICBjLXNlbGVjdG9yLXhwYXRoID0gYy1zZWxlY3Rvci14cGF0aDogXHVDMTIwXHVEMEREXHVBRTMwIFx1QUMxMiA9ICcnezB9JydcdUM3NzQoXHVBQzAwKSBcdUJEODBcdUM4MDFcdUQ1NjlcdUQ1NjlcdUIyQzhcdUIyRTQuIFx1QzEyMFx1RDBERFx1QUUzMCBYUGF0aFx1QzVEMFx1QjI5NCBcdUMxOERcdUMxMzFcdUM3NzQgXHVEM0VDXHVENTY4XHVCNDIwIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuCi0gICAgICAgIEVtcHR5VGFyZ2V0TmFtZXNwYWNlID0gRW1wdHlUYXJnZXROYW1lc3BhY2U6IFx1QzJBNFx1RDBBNFx1QjlDOCBcdUJCMzhcdUMxMUMgJyd7MH0nJ1x1Qzc1OCAnJ3RhcmdldE5hbWVzcGFjZScnIFx1QzE4RFx1QzEzMVx1QUMxMlx1Qzc0MCBcdUJFNDggXHVCQjM4XHVDNzkwXHVDNUY0XHVDNzdDIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuCi0gICAgICAgIEZhY2V0VmFsdWVGcm9tQmFzZSA9IEZhY2V0VmFsdWVGcm9tQmFzZTogJyd7MH0nJyBcdUM3MjBcdUQ2MTVcdUM3NTggXHVDMTIwXHVDNUI4XHVDNUQwXHVDMTFDICcnezJ9JycgXHVCQTc0XHVDNzU4ICcnezF9JycgXHVBQzEyXHVDNzQwIFx1QUUzMFx1QkNGOCBcdUM3MjBcdUQ2MTUgJyd7M30nJ1x1Qzc1OCBcdUFDMTIgXHVBQ0Y1XHVCQzMxXHVDNUQwXHVDMTFDIFx1QzY0MFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIEZpeGVkRmFjZXRWYWx1ZSA9IEZpeGVkRmFjZXRWYWx1ZTogezN9XHVDNzU4IFx1QzgxNVx1Qzc1OFx1QzVEMFx1QzExQyAnJ3swfScnIFx1QkE3NFx1QzVEMCBcdUIzMDBcdUQ1NUMgJyd7MX0nJyBcdUFDMTJcdUM3NzQgXHVCRDgwXHVDODAxXHVENTY5XHVENTY5XHVCMkM4XHVCMkU0LiAnJ3swfScnXHVDNUQwIFx1QjMwMFx1RDU1QyBcdUFDMTJcdUM3NzQgXHVDODcwXHVDMEMxIFx1QzcyMFx1RDYxNSBcdUM5MTEgXHVENTU4XHVCMDk4XHVDNUQwXHVDMTFDICcnezJ9JycoXHVDNzNDKVx1Qjg1QyBcdUMxMjRcdUM4MTVcdUI0MThcdUM1QzhcdUM3M0NcdUJBNzAgJ3snZml4ZWQnfScgPSB0cnVlXHVDNzc0XHVBRTMwIFx1QjU0Q1x1QkIzOFx1Qzc4NVx1QjJDOFx1QjJFNC4KLSAgICAgICAgSW52YWxpZFJlZ2V4ID0gSW52YWxpZFJlZ2V4OiBcdUQzMjhcdUQxMzQgXHVBQzEyICcnezB9JydcdUM3NDAoXHVCMjk0KSBcdUM4MDFcdUQ1NjlcdUQ1NUMgXHVDODE1XHVBRERDIFx1RDQ1Q1x1RDYwNFx1QzJERFx1Qzc3NCBcdUM1NDRcdUIyRDlcdUIyQzhcdUIyRTQuICcnezJ9JycgXHVDNUY0XHVDNUQwXHVDMTFDICcnezF9JycgXHVDNjI0XHVCOTU4XHVBQzAwIFx1QkNGNFx1QUNFMFx1QjQxOFx1QzVDOFx1QzJCNVx1QjJDOFx1QjJFNC4KLSAgICAgICAgTWF4T2NjdXJMaW1pdCA9IFx1QUQ2Q1x1QkIzOCBcdUJEODRcdUMxMURcdUFFMzBcdUM3NTggXHVENjA0XHVDN0FDIFx1QUQ2Q1x1QzEzMVx1QzVEMFx1QzExQyBtYXhPY2N1cnMgXHVDMThEXHVDMTMxXHVBQzEyXHVDNzQ0IHswfSBcdUFDMTJcdUJDRjRcdUIyRTQgXHVEMDZDXHVBQzhDIFx1QzEyNFx1QzgxNVx1RDU2MCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LgotICAgICAgICBQdWJsaWNTeXN0ZW1Pbk5vdGF0aW9uID0gUHVibGljU3lzdGVtT25Ob3RhdGlvbjogXHVENTU4XHVCMDk4IFx1Qzc3NFx1QzBDMVx1Qzc1OCAnJ3B1YmxpYycnXHVBQ0ZDICcnc3lzdGVtJydcdUM3NzQgJydub3RhdGlvbicnIFx1QzY5NFx1QzE4Q1x1QzVEMCBcdUIwOThcdUQwQzBcdUIwOThcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotICAgICAgICBTY2hlbWFMb2NhdGlvbiA9IFNjaGVtYUxvY2F0aW9uOiBzY2hlbWFMb2NhdGlvbiBcdUFDMTIgPSAnJ3swfScnXHVDNUQwXHVCMjk0IFx1QzlERFx1QzIxOCBcdUFDMUNcdUM3NTggVVJJXHVBQzAwIFx1Qzc4OFx1QzVCNFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi0gICAgICAgIFRhcmdldE5hbWVzcGFjZS4xID0gVGFyZ2V0TmFtZXNwYWNlLjE6ICcnezB9JycgXHVCMTI0XHVDNzg0XHVDMkE0XHVEMzk4XHVDNzc0XHVDMkE0XHVBQzAwIFx1RDU0NFx1QzY5NFx1RDU1OFx1QzlDMFx1QjlDQyBcdUMyQTRcdUQwQTRcdUI5QzggXHVCQjM4XHVDMTFDXHVDNzU4IFx1QjMwMFx1QzBDMSBcdUIxMjRcdUM3ODRcdUMyQTRcdUQzOThcdUM3NzRcdUMyQTRcdUFDMDAgJyd7MX0nJ1x1Qzc4NVx1QjJDOFx1QjJFNC4KLSAgICAgICAgVGFyZ2V0TmFtZXNwYWNlLjIgPSBUYXJnZXROYW1lc3BhY2UuMjogXHVCMTI0XHVDNzg0XHVDMkE0XHVEMzk4XHVDNzc0XHVDMkE0XHVBQzAwIFx1RDU0NFx1QzY5NFx1RDU1OFx1QzlDMCBcdUM1NEFcdUM5QzBcdUI5Q0MgXHVDMkE0XHVEMEE0XHVCOUM4IFx1QkIzOFx1QzExQ1x1Qzc1OCBcdUIzMDBcdUMwQzEgXHVCMTI0XHVDNzg0XHVDMkE0XHVEMzk4XHVDNzc0XHVDMkE0XHVBQzAwICcnezF9JydcdUM3ODVcdUIyQzhcdUIyRTQuCi0gICAgICAgIFVuZGVjbGFyZWRFbnRpdHkgPSBVbmRlY2xhcmVkRW50aXR5OiAnJ3swfScnIFx1QzVENFx1RDJGMFx1RDJGMFx1QUMwMCBcdUMxMjBcdUM1QjhcdUI0MThcdUM5QzAgXHVDNTRBXHVDNTU4XHVDMkI1XHVCMkM4XHVCMkU0LgotICAgICAgICBVbmRlY2xhcmVkUHJlZml4ID0gVW5kZWNsYXJlZFByZWZpeDogJyd7MH0nJ1x1Qzc0NChcdUI5N0MpIFFOYW1lXHVDNzNDXHVCODVDIFx1QkQ4NFx1QzExRFx1RDU2MCBcdUMyMTggXHVDNUM2XHVDNzRDOiAnJ3sxfScnIFx1QzgxMVx1QjQ1MFx1QzVCNFx1QUMwMCBcdUMxMjBcdUM1QjhcdUI0MThcdUM5QzAgXHVDNTRBXHVDNTU4XHVDMkI1XHVCMkM4XHVCMkU0LgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MU2NoZW1hTWVzc2FnZXNfcHRfQlIucHJvcGVydGllcyBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hNTFNjaGVtYU1lc3NhZ2VzX3B0X0JSLnByb3BlcnRpZXMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGQwNjMzMDIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MU2NoZW1hTWVzc2FnZXNfcHRfQlIucHJvcGVydGllcworKysgL2Rldi9udWxsCkBAIC0xLDI5MSArMCwwIEBACi0jIFRoaXMgZmlsZSBjb250YWlucyBlcnJvciBhbmQgd2FybmluZyBtZXNzYWdlcyByZWxhdGVkIHRvIFhNTCBTY2hlbWEKLSMgVGhlIG1lc3NhZ2VzIGFyZSBhcnJhbmdlZCBpbiBrZXkgYW5kIHZhbHVlIHR1cGxlcyBpbiBhIExpc3RSZXNvdXJjZUJ1bmRsZS4KLSMKLQotICAgICAgICBCYWRNZXNzYWdlS2V5ID0gTlx1MDBFM28gZm9pIHBvc3NcdTAwRUR2ZWwgZW5jb250cmFyIGEgbWVuc2FnZW0gZGUgZXJybyBjb3JyZXNwb25kZW50ZSBcdTAwRTAgY2hhdmUgZGEgbWVuc2FnZW0uCi0gICAgICAgIEZvcm1hdEZhaWxlZCA9IE9jb3JyZXUgdW0gZXJybyBpbnRlcm5vIGFvIGZvcm1hdGFyIGEgbWVuc2FnZW0gYSBzZWd1aXI6XG4KLQotIyBGb3IgaW50ZXJuYWwgdXNlCi0KLSAgICAgICAgSW50ZXJuYWwtRXJyb3IgPSBFcnJvIGludGVybm86IHswfS4KLSAgICAgICAgZHQtd2hpdGVzcGFjZSA9IE8gdmFsb3IgZG8gYXNwZWN0byBkbyBlc3BhXHUwMEU3byBlbSBicmFuY28gblx1MDBFM28gZXN0XHUwMEUxIGRpc3Bvblx1MDBFRHZlbCBwYXJhIG8gc2ltcGxlVHlwZSAnJ3swfScnIGRhIHVuaVx1MDBFM28KLSAgICAgICAgR3JhbW1hckNvbmZsaWN0ID0gVW1hIGRhcyBncmFtXHUwMEUxdGljYXMgcmV0b3JuYWRhcyBkbyBwb29sIGRlIGdyYW1cdTAwRTF0aWNhIGRvIHVzdVx1MDBFMXJpbyBlc3RcdTAwRTEgZW0gY29uZmxpdG8gY29tIG91dHJhLgotCi0jIElkZW50aXR5IGNvbnN0cmFpbnRzCi0KLSAgICAgICAgQWJzZW50S2V5VmFsdWUgPSBFcnJvIGRlIFJlc3RyaVx1MDBFN1x1MDBFM28gZGUgaWRlbnRpZGFkZSAoY3ZjLWlkZW50aXR5LWNvbnN0cmFpbnQuNC4yLjEpOiAgbyBlbGVtZW50byAiezB9IiB0ZW0gdW1hIGNoYXZlIHNlbSB2YWxvci4KLSAgICAgICAgRHVwbGljYXRlRmllbGQgPSBDb3JyZXNwb25kXHUwMEVBbmNpYSBkdXBsaWNhZGEgbm8gZXNjb3BvIGRvIGNhbXBvICJ7MH0iLgotICAgICAgICBEdXBsaWNhdGVLZXkgPSBWYWxvciBkYSBjaGF2ZSBkdXBsaWNhZG8gW3swfV0gZGVjbGFyYWRvIHBhcmEgYSByZXN0cmlcdTAwRTdcdTAwRTNvIGRlIGlkZW50aWRhZGUgZG8gZWxlbWVudG8gInsxfSIuCi0gICAgICAgIER1cGxpY2F0ZVVuaXF1ZSA9IFZhbG9yIGV4Y2x1c2l2byBkdXBsaWNhZG8gW3swfV0gZGVjbGFyYWRvIHBhcmEgYSByZXN0cmlcdTAwRTdcdTAwRTNvIGRlIGlkZW50aWRhZGUgZG8gZWxlbWVudG8gInsxfSIuCi0gICAgICAgIEZpZWxkTXVsdGlwbGVNYXRjaCA9IEVycm8gZGUgcmVzdHJpXHUwMEU3XHUwMEUzbyBkZSBpZGVudGlkYWRlOiBvIGNhbXBvICJ7MH0iIGNvcnJlc3BvbmRlIGEgbWFpcyBkZSB1bSB2YWxvciBubyBlc2NvcG8gZGVzdGUgc2VsZXRvcjsgb3MgY2FtcG9zIGRldmVtIGNvcnJlc3BvbmRlciBhIHZhbG9yZXMgZXhjbHVzaXZvcy4KLSAgICAgICAgRml4ZWREaWZmZXJzRnJvbUFjdHVhbCA9IE8gY29udGVcdTAwRkFkbyBkZXN0ZSBlbGVtZW50byBuXHUwMEUzbyBcdTAwRTkgZXF1aXZhbGVudGUgYW8gdmFsb3IgZG8gYXRyaWJ1dG8gImZpeGVkIiBuYSBkZWNsYXJhXHUwMEU3XHUwMEUzbyBkbyBlbGVtZW50byBkbyBlc3F1ZW1hLgotICAgICAgICBLZXlNYXRjaGVzTmlsbGFibGUgPSBFcnJvIGRlIHJlc3RyaVx1MDBFN1x1MDBFM28gZGUgaWRlbnRpZGFkZSAoY3ZjLWlkZW50aXR5LWNvbnN0cmFpbnQuNC4yLjMpOiBvIGVsZW1lbnRvICJ7MH0iIHRlbSB1bWEgY2hhdmUgcXVlIGNvcnJlc3BvbmRlIGEgdW0gZWxlbWVudG8gbyBxdWFsIHRlbSBhbnVsXHUwMEUxdmVsIGRlZmluaWRvIGNvbW8gdmVyZGFkZWlyby4KLSAgICAgICAgS2V5Tm90RW5vdWdoVmFsdWVzID0gTlx1MDBFM28gaFx1MDBFMSB2YWxvcmVzIHN1ZmljaWVudGVzIGVzcGVjaWZpY2Fkb3MgcGFyYSBhIHJlc3RyaVx1MDBFN1x1MDBFM28gZGUgaWRlbnRpZGFkZSBkZSA8a2V5IG5hbWU9InsxfSI+IGVzcGVjaWZpY2FkYSBwYXJhIG8gZWxlbWVudG8gInswfSIuCi0gICAgICAgIEtleU5vdEZvdW5kID0gQ2hhdmUgJyd7MH0nJyBjb20gdmFsb3IgJyd7MX0nJyBuXHUwMEUzbyBlbmNvbnRyYWRhIHBhcmEgYSByZXN0cmlcdTAwRTdcdTAwRTNvIGRlIGlkZW50aWRhZGUgZG8gZWxlbWVudG8gJyd7Mn0nJy4KLSAgICAgICAgS2V5UmVmTm90RW5vdWdoVmFsdWVzID0gTlx1MDBFM28gaFx1MDBFMSB2YWxvcmVzIHN1ZmljaWVudGVzIGVzcGVjaWZpY2Fkb3MgcGFyYSBhIHJlc3RyaVx1MDBFN1x1MDBFM28gZGUgaWRlbnRpZGFkZSBkZSA8a2V5cmVmIG5hbWU9InsxfSI+IGVzcGVjaWZpY2FkYSBwYXJhIG8gZWxlbWVudG8gInswfSIuCi0gICAgICAgIEtleVJlZk91dE9mU2NvcGUgPSBFcnJvIGRlIHJlc3RyaVx1MDBFN1x1MDBFM28gZGUgaWRlbnRpZGFkZTogYSByZXN0cmlcdTAwRTdcdTAwRTNvIGRlIGlkZW50aWRhZGUgInswfSIgdGVtIHVtYSBrZXlyZWYgcXVlIHNlIHJlZmVyZSBhIHVtYSBjaGF2ZSBleGNsdXNpdmEgYSBxdWFsIGVzdFx1MDBFMSBmb3JhIGRvIGVzY29wby4KLSAgICAgICAgS2V5UmVmUmVmZXJOb3RGb3VuZCA9IEEgZGVjbGFyYVx1MDBFN1x1MDBFM28gZGUgcmVmZXJcdTAwRUFuY2lhIGRhIGNoYXZlICJ7MH0iIHJlZmVyZS1zZSBhIHVtYSBjaGF2ZSBjb20gbyBub21lICJ7MX0iLgotICAgICAgICBVbmlxdWVOb3RFbm91Z2hWYWx1ZXMgPSBOXHUwMEUzbyBoXHUwMEUxIHZhbG9yZXMgc3VmaWNpZW50ZXMgZXNwZWNpZmljYWRvcyBwYXJhIGEgcmVzdHJpXHUwMEU3XHUwMEUzbyBkZSBpZGVudGlkYWRlIDx1bmlxdWU+IGVzcGVjaWZpY2FkYSBwYXJhIG8gZWxlbWVudG8gInswfSIuCi0gICAgICAgIFVua25vd25GaWVsZCA9IEVycm8gaW50ZXJubyBkZSByZXN0cmlcdTAwRTdcdTAwRTNvIGRlIGlkZW50aWRhZGU7IGNhbXBvIGRlc2NvbmhlY2lkbyAiezB9Ii4KLQotIyBJZGVhbGx5LCB3ZSBzaG91bGQgb25seSB1c2UgdGhlIGZvbGxvd2luZyBlcnJvciBrZXlzLCBub3QgdGhlIG9uZXMgdW5kZXIKLSMgIklkZW50aXR5IGNvbnN0cmFpbnRzIi4gQW5kIHdlIHNob3VsZCBjb3ZlciBhbGwgb2YgdGhlIGZvbGxvd2luZyBlcnJvcnMuCi0KLSN2YWxpZGF0aW9uICgzLlguNCkKLQotICAgICAgICBjdmMtYXR0cmlidXRlLjMgPSBjdmMtYXR0cmlidXRlLjM6IE8gdmFsb3IgJyd7Mn0nJyBkbyBhdHJpYnV0byAnJ3sxfScnIG5vIGVsZW1lbnRvICcnezB9Jycgblx1MDBFM28gXHUwMEU5IHZcdTAwRTFsaWRvIGVtIHJlbGFcdTAwRTdcdTAwRTNvIGFvIHNldSB0aXBvLCAnJ3szfScnLgotICAgICAgICBjdmMtYXR0cmlidXRlLjQgPSBjdmMtYXR0cmlidXRlLjQ6IE8gdmFsb3IgJyd7Mn0nJyBkbyBhdHJpYnV0byAnJ3sxfScnIG5vIGVsZW1lbnRvICcnezB9Jycgblx1MDBFM28gXHUwMEU5IHZcdTAwRTFsaWRvIGVtIHJlbGFcdTAwRTdcdTAwRTNvIFx1MDBFMCBzdWEgJ3sndmFsdWUgY29uc3RyYWludCd9JyBmaXhhLiBPIGF0cmlidXRvIGRldmUgdGVyIHVtIHZhbG9yICcnezN9JycuCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuMi4xID0gY3ZjLWNvbXBsZXgtdHlwZS4yLjE6IE8gZWxlbWVudG8gJyd7MH0nJyBuXHUwMEUzbyBkZXZlIHRlciB1bSBjYXJhY3RlcmUgb3UgdW0gaXRlbSBjb20gaW5mb3JtYVx1MDBFN1x1MDBGNWVzIGRvIGVsZW1lbnRvIFtjaGlsZHJlbl0gcG9ycXVlIG8gdGlwbyBkZSBjb250ZVx1MDBGQWRvIGRvIHRpcG8gXHUwMEU5IHZhemlvLgotICAgICAgICBjdmMtY29tcGxleC10eXBlLjIuMiA9IGN2Yy1jb21wbGV4LXR5cGUuMi4yOiBPIGVsZW1lbnRvICcnezB9Jycgblx1MDBFM28gZGV2ZSB0ZXIgdW0gZWxlbWVudG8gW2NoaWxkcmVuXSBlIG8gdmFsb3IgZGV2ZSBzZXIgdlx1MDBFMWxpZG8uCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuMi4zID0gY3ZjLWNvbXBsZXgtdHlwZS4yLjM6IE8gZWxlbWVudG8gJyd7MH0nJyBuXHUwMEUzbyBwb2RlIHRlciB1bSBjYXJhY3RlcmUgW2NoaWxkcmVuXSBwb3JxdWUgbyB0aXBvIGRlIGNvbnRlXHUwMEZBZG8gZG8gdGlwbyBcdTAwRTkgc29tZW50ZSBlbGVtZW50by4KLSAgICAgICAgY3ZjLWNvbXBsZXgtdHlwZS4yLjQuYSA9IGN2Yy1jb21wbGV4LXR5cGUuMi40LmE6IEZvaSBkZXRlY3RhZG8gdW0gY29udGVcdTAwRkFkbyBpbnZcdTAwRTFsaWRvIGNvbWVcdTAwRTdhbmRvIGNvbSBvIGVsZW1lbnRvICcnezB9JycuIEVyYSBlc3BlcmFkbyB1bSBkb3MgJyd7MX0nJy4KLSAgICAgICAgY3ZjLWNvbXBsZXgtdHlwZS4yLjQuYiA9IGN2Yy1jb21wbGV4LXR5cGUuMi40LmI6IE8gY29udGVcdTAwRkFkbyBkbyBlbGVtZW50byAnJ3swfScnIG5cdTAwRTNvIGVzdFx1MDBFMSBjb21wbGV0by4gRXJhIGVzcGVyYWRvIHVtIGRvcyAnJ3sxfScnLgotICAgICAgICBjdmMtY29tcGxleC10eXBlLjIuNC5jID0gY3ZjLWNvbXBsZXgtdHlwZS4yLjQuYzogTyBjdXJpbmdhIGNvcnJlc3BvbmRlbnRlIFx1MDBFOSByZXN0cml0bywgbWFzIG5lbmh1bWEgZGVjbGFyYVx1MDBFN1x1MDBFM28gcG9kZSBzZXIgZW5jb250cmFkYSBwYXJhIG8gZWxlbWVudG8gJyd7MH0nJy4KLSAgICAgICAgY3ZjLWNvbXBsZXgtdHlwZS4yLjQuZCA9IGN2Yy1jb21wbGV4LXR5cGUuMi40LmQ6IENvbnRlXHUwMEZBZG8gaW52XHUwMEUxbGlkbyBlbmNvbnRyYWRvIGFvIGluaWNpYXIgY29tIG8gZWxlbWVudG8gJyd7MH0nJy4gTmVuaHVtIGVsZW1lbnRvIGZpbGhvIFx1MDBFOSBlc3BlcmFkbyBuZXN0ZSBwb250by4KLSAgICAgICAgY3ZjLWNvbXBsZXgtdHlwZS4yLjQuZSA9IGN2Yy1jb21wbGV4LXR5cGUuMi40LmQ6IEZvaSBlbmNvbnRyYWRvIHVtIGNvbnRlXHUwMEZBZG8gaW52XHUwMEUxbGlkbyBjb21lXHUwMEU3YW5kbyBjb20gbyBlbGVtZW50byAnJ3swfScnLiBOZW5odW0gZWxlbWVudG8gZmlsaG8gInsxfSIgXHUwMEU5IGVzcGVyYWRvIG5lc3RlIHBvbnRvLgotICAgICAgICBjdmMtY29tcGxleC10eXBlLjMuMSA9IGN2Yy1jb21wbGV4LXR5cGUuMy4xOiBPIHZhbG9yICcnezJ9JycgZG8gYXRyaWJ1dG8gJyd7MX0nJyBkbyBlbGVtZW50byAnJ3swfScnIG5cdTAwRTNvIFx1MDBFOSB2XHUwMEUxbGlkbyBlbSByZWxhXHUwMEU3XHUwMEUzbyBhbyB1c28gZG8gYXRyaWJ1dG8gY29ycmVzcG9uZGVudGUuIE8gYXRyaWJ1dG8gJyd7MX0nJyB0ZW0gdW0gdmFsb3IgZml4byBkZSAnJ3szfScnLgotICAgICAgICBjdmMtY29tcGxleC10eXBlLjMuMi4xID0gY3ZjLWNvbXBsZXgtdHlwZS4zLjIuMTogTyBlbGVtZW50byAnJ3swfScnIG5cdTAwRTNvIHRlbSB1bSBjdXJpbmdhIGRvIGF0cmlidXRvICcnezF9JycuCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuMy4yLjIgPSBjdmMtY29tcGxleC10eXBlLjMuMi4yOiBPIGF0cmlidXRvICcnezF9Jycgblx1MDBFM28gcG9kZSBhcGFyZWNlciBubyBlbGVtZW50byAnJ3swfScnLgotICAgICAgICBjdmMtY29tcGxleC10eXBlLjQgPSBjdmMtY29tcGxleC10eXBlLjQ6IE8gYXRyaWJ1dG8gJyd7MX0nJyBkZXZlIGFwYXJlY2VyIG5vIGVsZW1lbnRvICcnezB9JycuCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuNS4xID0gY3ZjLWNvbXBsZXgtdHlwZS41LjE6IE5vIGVsZW1lbnRvICcnezB9JycsIG8gYXRyaWJ1dG8gJyd7MX0nJyBcdTAwRTkgdW0gSUQgQ3VyaW5nYSwgbWFzIGpcdTAwRTEgZXhpc3RlIHVtIElEIEN1cmluZ2EgJyd7Mn0nJy4gUG9kZSBoYXZlciBzb21lbnRlIHVtLgotICAgICAgICBjdmMtY29tcGxleC10eXBlLjUuMiA9IGN2Yy1jb21wbGV4LXR5cGUuNS4yOiBObyBlbGVtZW50bywgJyd7MH0nJywgbyBhdHJpYnV0byAnJ3sxfScnIFx1MDBFOSB1bSBJRCBDdXJpbmdhLCBtYXMgalx1MDBFMSBleGlzdGUgdW0gYXRyaWJ1dG8gJyd7Mn0nJyBvYnRpZG8gZG8gSUQgZW50cmUgb3MgJ3snYXR0cmlidXRlIHVzZXMnfScuCi0gICAgICAgIGN2Yy1kYXRhdHlwZS12YWxpZC4xLjIuMSA9IGN2Yy1kYXRhdHlwZS12YWxpZC4xLjIuMTogJyd7MH0nJyBuXHUwMEUzbyBcdTAwRTkgdW0gdmFsb3Igdlx1MDBFMWxpZG8gcGFyYSAnJ3sxfScnLgotICAgICAgICBjdmMtZGF0YXR5cGUtdmFsaWQuMS4yLjIgPSBjdmMtZGF0YXR5cGUtdmFsaWQuMS4yLjI6ICcnezB9Jycgblx1MDBFM28gXHUwMEU5IHVtIHZhbG9yIHZcdTAwRTFsaWRvIGRvIHRpcG8gZGUgbGlzdGEgJyd7MX0nJy4KLSAgICAgICAgY3ZjLWRhdGF0eXBlLXZhbGlkLjEuMi4zID0gY3ZjLWRhdGF0eXBlLXZhbGlkLjEuMi4zOiAnJ3swfScnIG5cdTAwRTNvIFx1MDBFOSB1bSB2YWxvciB2XHUwMEUxbGlkbyBkbyB0aXBvIGRlIHVuaVx1MDBFM28gJyd7MX0nJy4KLSAgICAgICAgY3ZjLWVsdC4xID0gY3ZjLWVsdC4xOiBOXHUwMEUzbyBwb2RlIGxvY2FsaXphciBhIGRlY2xhcmFcdTAwRTdcdTAwRTNvIGRvIGVsZW1lbnRvICcnezB9JycuCi0gICAgICAgIGN2Yy1lbHQuMiA9IGN2Yy1lbHQuMjogTyB2YWxvciBkZSAieyJhYnN0cmFjdCJ9IiBuYSBkZWNsYXJhXHUwMEU3XHUwMEUzbyBkbyBlbGVtZW50byBwYXJhICcnezB9JycgZGV2ZSBzZXIgZmFsc28uCi0gICAgICAgIGN2Yy1lbHQuMy4xID0gY3ZjLWVsdC4zLjE6IE8gYXRyaWJ1dG8gJyd7MX0nJyBuXHUwMEUzbyBkZXZlIGFwYXJlY2VyIG5vIGVsZW1lbnRvICcnezB9JycgcG9ycXVlIGEgcHJvcHJpZWRhZGUgJ3snbmlsbGFibGUnfScgZGUgJyd7MH0nJyBcdTAwRTkgZmFsc2EuCi0gICAgICAgIGN2Yy1lbHQuMy4yLjEgPSBjdmMtZWx0LjMuMi4xOiBPIGVsZW1lbnRvICcnezB9Jycgblx1MDBFM28gcG9kZSB0ZXIgaW5mb3JtYVx1MDBFN1x1MDBGNWVzIGRlIGNhcmFjdGVyZSBvdSBkZSBlbGVtZW50byBbY2hpbGRyZW5dIHBvcnF1ZSAnJ3sxfScnIGZvaSBlc3BlY2lmaWNhZG8uCi0gICAgICAgIGN2Yy1lbHQuMy4yLjIgPSBjdmMtZWx0LjMuMi4yOiBOXHUwMEUzbyBkZXZlIGhhdmVyICJ7InZhbHVlIGNvbnN0cmFpbnQifSIgZml4byBwYXJhIG8gZWxlbWVudG8gJyd7MH0nJyBwb3JxdWUgJyd7MX0nJyBmb2kgZXNwZWNpZmljYWRvLgotICAgICAgICBjdmMtZWx0LjQuMSA9IGN2Yy1lbHQuNC4xOiBPIHZhbG9yICcnezJ9JycgZG8gYXRyaWJ1dG8gJyd7MX0nJyBkbyBlbGVtZW50byAnJ3swfScnIG5cdTAwRTNvIFx1MDBFOSB1bSBRTmFtZSB2XHUwMEUxbGlkby4KLSAgICAgICAgY3ZjLWVsdC40LjIgPSBjdmMtZWx0LjQuMjogTlx1MDBFM28gXHUwMEU5IHBvc3NcdTAwRUR2ZWwgcmVzb2x2ZXIgJyd7MX0nJyBwYXJhIHVtYSBkZWZpbmlcdTAwRTdcdTAwRTNvIGRlIHRpcG8gZGUgZWxlbWVudG8gJyd7MH0nJy4KLSAgICAgICAgY3ZjLWVsdC40LjMgPSBjdmMtZWx0LjQuMzogTyB0aXBvICcnezF9Jycgblx1MDBFM28gXHUwMEU5IG9idGlkbyBkZSBmb3JtYSB2XHUwMEUxbGlkYSBkYSBkZWZpbmlcdTAwRTdcdTAwRTNvIGRvIHRpcG8sICcnezJ9JycsIGRvIGVsZW1lbnRvICcnezB9JycuCi0gICAgICAgIGN2Yy1lbHQuNS4xLjEgPSBjdmMtZWx0LjUuMS4xOiAieyJ2YWx1ZSBjb25zdHJhaW50In0iICcnezJ9JycgZG8gZWxlbWVudG8gJyd7MH0nJyBuXHUwMEUzbyBcdTAwRTkgdW0gdmFsb3IgcGFkclx1MDBFM28gdlx1MDBFMWxpZG8gcGFyYSBvIHRpcG8gJyd7MX0nJy4KLSAgICAgICAgY3ZjLWVsdC41LjIuMi4xID0gY3ZjLWVsdC41LjIuMi4xOiBPIGVsZW1lbnRvICcnezB9Jycgblx1MDBFM28gZGV2ZSB0ZXIgaXRlbSBkZSBpbmZvcm1hXHUwMEU3XHUwMEY1ZXMgZG8gZWxlbWVudG8gW2NoaWxkcmVuXS4KLSAgICAgICAgY3ZjLWVsdC41LjIuMi4yLjEgPSBjdmMtZWx0LjUuMi4yLjIuMTogTyB2YWxvciAnJ3sxfScnIGRvIGVsZW1lbnRvICcnezB9Jycgblx1MDBFM28gY29ycmVzcG9uZGUgYW8gdmFsb3IgZml4byBkZSAneyd2YWx1ZSBjb25zdHJhaW50J30nICcnezJ9JycuCi0gICAgICAgIGN2Yy1lbHQuNS4yLjIuMi4yID0gY3ZjLWVsdC41LjIuMi4yLjI6IE8gdmFsb3IgJyd7MX0nJyBkbyBlbGVtZW50byAnJ3swfScnIG5cdTAwRTNvIGNvcnJlc3BvbmRlIGFvIHZhbG9yIGRlICd7J3ZhbHVlIGNvbnN0cmFpbnQnfScgJyd7Mn0nJyAuCi0gICAgICAgIGN2Yy1lbnVtZXJhdGlvbi12YWxpZCA9IGN2Yy1lbnVtZXJhdGlvbi12YWxpZDogTyB2YWxvciAnJ3swfScnIG5cdTAwRTNvIHRlbSB1bSBhc3BlY3RvIHZcdTAwRTFsaWRvIGVtIHJlbGFcdTAwRTdcdTAwRTNvIFx1MDBFMCBlbnVtZXJhXHUwMEU3XHUwMEUzbyAnJ3sxfScnLiBEZXZlIHNlciB1bSB2YWxvciBkYSBlbnVtZXJhXHUwMEU3XHUwMEUzby4KLSAgICAgICAgY3ZjLWZyYWN0aW9uRGlnaXRzLXZhbGlkID0gY3ZjLWZyYWN0aW9uRGlnaXRzLXZhbGlkOiBPIHZhbG9yICcnezB9JycgdGVtIHsxfSBkXHUwMEVEZ2l0b3MgZnJhY2lvblx1MDBFMXJpb3MsIG1hcyBvIG5cdTAwRkFtZXJvIGRlIGRcdTAwRURnaXRvcyBmcmFjaW9uXHUwMEUxcmlvcyBmb2kgbGltaXRhZG8gYSB7Mn0uCi0gICAgICAgIGN2Yy1pZC4xID0gY3ZjLWlkLjE6IE5cdTAwRTNvIGhcdTAwRTEgYXNzb2NpYVx1MDBFN1x1MDBFM28gZGUgSUQvSURSRUYgcGFyYSBJRFJFRiAnJ3swfScnLgotICAgICAgICBjdmMtaWQuMiA9IGN2Yy1pZC4yOiBIXHUwMEUxIHZcdTAwRTFyaWFzIG9jb3JyXHUwMEVBbmNpYXMgZG8gdmFsb3IgZG8gSUQgJyd7MH0nJy4KLSAgICAgICAgY3ZjLWlkLjMgPSBjdmMtaWQuMzogVW0gY2FtcG8gZGEgcmVzdHJpXHUwMEU3XHUwMEUzbyBkZSBpZGVudGlkYWRlICcnezB9JycgY29ycmVzcG9uZGlhIGFvIGVsZW1lbnRvICcnezF9JycsIG1hcyBlc3RlIGVsZW1lbnRvIG5cdTAwRTNvIHRlbSB1bSB0aXBvIHNpbXBsZXMuCi0gICAgICAgIGN2Yy1sZW5ndGgtdmFsaWQgPSBjdmMtbGVuZ3RoLXZhbGlkOiBPIHZhbG9yICcnezB9JycgY29tIHRhbWFuaG8gPSAnJ3sxfScnIG5cdTAwRTNvIHRlbSB1bSBhc3BlY3RvIHZcdTAwRTFsaWRvIGVtIHJlbGFcdTAwRTdcdTAwRTNvIGFvIHRhbWFuaG8gJyd7Mn0nJyBkbyB0aXBvICcnezN9JycuCi0gICAgICAgIGN2Yy1tYXhFeGNsdXNpdmUtdmFsaWQgPSBjdmMtbWF4RXhjbHVzaXZlLXZhbGlkOiBPIHZhbG9yICcnezB9Jycgblx1MDBFM28gdGVtIHVtIGFzcGVjdG8gdlx1MDBFMWxpZG8gZW0gcmVsYVx1MDBFN1x1MDBFM28gYW8gbWF4RXhjbHVzaXZlICcnezF9JycgZG8gdGlwbyAnJ3syfScnLgotICAgICAgICBjdmMtbWF4SW5jbHVzaXZlLXZhbGlkID0gY3ZjLW1heEluY2x1c2l2ZS12YWxpZDogTyB2YWxvciAnJ3swfScnIG5cdTAwRTNvIHRlbSB1bSBhc3BlY3RvIHZcdTAwRTFsaWRvIGVtIHJlbGFcdTAwRTdcdTAwRTNvIGFvIG1heEluY2x1c2l2ZSAnJ3sxfScnIGRvIHRpcG8gJyd7Mn0nJy4KLSAgICAgICAgY3ZjLW1heExlbmd0aC12YWxpZCA9IGN2Yy1tYXhMZW5ndGgtdmFsaWQ6IE8gdmFsb3IgJyd7MH0nJyBjb20gdGFtYW5obyA9ICcnezF9Jycgblx1MDBFM28gdGVtIHVtIGFzcGVjdG8gdlx1MDBFMWxpZG8gZW0gcmVsYVx1MDBFN1x1MDBFM28gYW8gbWF4TGVuZ3RoICcnezJ9JycgZG8gdGlwbyAnJ3szfScnLgotICAgICAgICBjdmMtbWluRXhjbHVzaXZlLXZhbGlkID0gY3ZjLW1pbkV4Y2x1c2l2ZS12YWxpZDogTyB2YWxvciAnJ3swfScnIG5cdTAwRTNvIHRlbSB1bSBhc3BlY3RvIHZcdTAwRTFsaWRvIGVtIHJlbGFcdTAwRTdcdTAwRTNvIGFvIG1pbkV4Y2x1c2l2ZSAnJ3sxfScnIGRvIHRpcG8gJyd7Mn0nJy4KLSAgICAgICAgY3ZjLW1pbkluY2x1c2l2ZS12YWxpZCA9IGN2Yy1taW5JbmNsdXNpdmUtdmFsaWQ6IE8gdmFsb3IgJyd7MH0nJyBuXHUwMEUzbyB0ZW0gdW0gYXNwZWN0byB2XHUwMEUxbGlkbyBlbSByZWxhXHUwMEU3XHUwMEUzbyBhbyBtaW5JbmNsdXNpdmUgJyd7MX0nJyBkbyB0aXBvICcnezJ9JycuCi0gICAgICAgIGN2Yy1taW5MZW5ndGgtdmFsaWQgPSBjdmMtbWluTGVuZ3RoLXZhbGlkOiBPIHZhbG9yICcnezB9JycgY29tIHRhbWFuaG8gPSAnJ3sxfScnIG5cdTAwRTNvIHRlbSB1bSBhc3BlY3RvIHZcdTAwRTFsaWRvIGVtIHJlbGFcdTAwRTdcdTAwRTNvIGFvIG1pbkxlbmd0aCAnJ3syfScnIGRvIHRpcG8gJyd7M30nJy4KLSAgICAgICAgY3ZjLXBhdHRlcm4tdmFsaWQgPSBjdmMtcGF0dGVybi12YWxpZDogTyB2YWxvciAnJ3swfScnIG5cdTAwRTNvIHRlbSB1bSBhc3BlY3RvIHZcdTAwRTFsaWRvIGVtIHJlbGFcdTAwRTdcdTAwRTNvIGFvIHBhZHJcdTAwRTNvICcnezF9JycgZG8gdGlwbyAnJ3syfScnLgotICAgICAgICBjdmMtdG90YWxEaWdpdHMtdmFsaWQgPSBjdmMtdG90YWxEaWdpdHMtdmFsaWQ6IE8gdmFsb3IgJyd7MH0nJyB0ZW0gezF9IGRcdTAwRURnaXRvcyBkbyB0b3RhbCwgbWFzIG8gblx1MDBGQW1lcm8gZGUgZFx1MDBFRGdpdG9zIGRvIHRvdGFsIGZvaSBsaW1pdGFkbyBhIHsyfS4KLSAgICAgICAgY3ZjLXR5cGUuMiA9IGN2Yy10eXBlLjI6IEEgZGVmaW5pXHUwMEU3XHUwMEUzbyBkbyB0aXBvIG5cdTAwRTNvIHBvZGUgc2VyIGFic3RyYXRhIHBhcmEgbyBlbGVtZW50byB7MH0uCi0gICAgICAgIGN2Yy10eXBlLjMuMS4xID0gY3ZjLXR5cGUuMy4xLjE6IE8gZWxlbWVudG8gJyd7MH0nJyB0ZW0gdW0gdGlwbyBzaW1wbGVzLiBEZXNzYSBmb3JtYSwgblx1MDBFM28gcG9kZSBoYXZlciBhdHJpYnV0b3MsIGV4Y2V0byBhcXVlbGVzIGN1am8gbm9tZSBkbyBuYW1lc3BhY2UgXHUwMEU5IGlkXHUwMEVBbnRpY28gYSAnJ2h0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlJycgZSBjdWpvIFtsb2NhbCBuYW1lXSBcdTAwRTkgdW0gZG9zIHNlZ3VpbnRlcyAnJ3R5cGUnJywgJyduaWwnJywgJydzY2hlbWFMb2NhdGlvbicnIG91ICcnbm9OYW1lc3BhY2VTY2hlbWFMb2NhdGlvbicnLiBObyBlbnRhbnRvLCBvIGF0cmlidXRvICcnezF9JycgZm9pIGVuY29udHJhZG8uCi0gICAgICAgIGN2Yy10eXBlLjMuMS4yID0gY3ZjLXR5cGUuMy4xLjI6IE8gZWxlbWVudG8gJyd7MH0nJyB0ZW0gdW0gdGlwbyBzaW1wbGVzLiBEZXNzYSBmb3JtYSwgblx1MDBFM28gZGV2ZSBoYXZlciB1bSBpdGVtIGRlIGluZm9ybWFcdTAwRTdcdTAwRjVlcyBkbyBlbGVtZW50byBbY2hpbGRyZW5dLgotICAgICAgICBjdmMtdHlwZS4zLjEuMyA9IGN2Yy10eXBlLjMuMS4zOiBPIHZhbG9yICcnezF9JycgZG8gZWxlbWVudG8gJyd7MH0nJyBuXHUwMEUzbyBcdTAwRTkgdlx1MDBFMWxpZG8uCi0KLSNzY2hlbWEgdmFsaWQgKDMuWC4zKQotCi0gICAgICAgIHNjaGVtYV9yZWZlcmVuY2UuYWNjZXNzID0gc2NoZW1hX3JlZmVyZW5jZTogZmFsaGEgYW8gbGVyIG8gZG9jdW1lbnRvIGRlIGVzcXVlbWEgJyd7MH0nJyBwb3JxdWUgbyBhY2Vzc28gYSAnJ3sxfScnIG5cdTAwRTNvIFx1MDBFOSBwZXJtaXRpZG8gZW0gZGVjb3JyXHUwMEVBbmNpYSBkZSB1bWEgcmVzdHJpXHUwMEU3XHUwMEUzbyBkZWZpbmlkYSBwZWxhIHByb3ByaWVkYWRlIGFjY2Vzc0V4dGVybmFsU2NoZW1hLiAKLSAgICAgICAgc2NoZW1hX3JlZmVyZW5jZS40ID0gc2NoZW1hX3JlZmVyZW5jZS40OiBGYWxoYSBhbyBsZXIgbyBkb2N1bWVudG8gZG8gZXNxdWVtYSAnJ3swfScnIHBvcnF1ZSAxKSBuXHUwMEUzbyBmb2kgcG9zc1x1MDBFRHZlbCBlbmNvbnRyYXIgbyBkb2N1bWVudG87IDIpIG5cdTAwRTNvIGZvaSBwb3NzXHUwMEVEdmVsIGxlciBvIGRvY3VtZW50bzsgMykgbyBlbGVtZW50by1yYWl6IGRvIGRvY3VtZW50byBuXHUwMEUzbyBcdTAwRTkgPHhzZDpzY2hlbWE+LgotICAgICAgICBzcmMtYW5ub3RhdGlvbiA9IHNyYy1hbm5vdGF0aW9uOiBvcyBlbGVtZW50b3MgZGUgPGFubm90YXRpb24+IHBvZGVtIGNvbnRlciBzb21lbnRlIG9zIGVsZW1lbnRvcyA8YXBwaW5mbz4gZSA8ZG9jdW1lbnRhdGlvbj4sIG1hcyBmb2kgZW5jb250cmFkbyAnJ3swfScnLgotICAgICAgICBzcmMtYXR0cmlidXRlLjEgPSBzcmMtYXR0cmlidXRlLjE6IEFzIHByb3ByaWVkYWRlcyAnJ3BhZHJcdTAwRTNvJycgZSAnJ2ZpeGVkJycgblx1MDBFM28gcG9kZW0gZXN0YXIgcHJlc2VudGVzIG5hIGRlY2xhcmFcdTAwRTdcdTAwRTNvIGRvIGF0cmlidXRvICcnezB9JycuIFVzZSBzb21lbnRlIHVtYSBkZWxhcy4KLSAgICAgICAgc3JjLWF0dHJpYnV0ZS4yID0gc3JjLWF0dHJpYnV0ZS4yOiA6IEEgcHJvcHJpZWRhZGUgJydwYWRyXHUwMEUzbycnIGVzdFx1MDBFMSBwcmVzZW50ZSBubyBhdHJpYnV0byAnJ3swfScnLiBEZXNzYSBmb3JtYSwgbyB2YWxvciBkZSAnJ3VzZScnIGRldmUgc2VyICcnb3B0aW9uYWwnJy4KLSAgICAgICAgc3JjLWF0dHJpYnV0ZS4zLjEgPSBzcmMtYXR0cmlidXRlLjMuMTogJ3JlZicgb3UgJ25hbWUnIGRldmUgZXN0YXIgcHJlc2VudGUgbmEgZGVjbGFyYVx1MDBFN1x1MDBFM28gZG8gYXRyaWJ1dG8gZGUgbG9jYWwuCi0gICAgICAgIHNyYy1hdHRyaWJ1dGUuMy4yID0gc3JjLWF0dHJpYnV0ZS4zLjI6IE8gY29udGVcdTAwRkFkbyBkZXZlIGNvcnJlc3BvbmRlciBhIChhbm5vdGF0aW9uPykgZGEgcmVmZXJcdTAwRUFuY2lhIGRvIGF0cmlidXRvICcnezB9JycuCi0gICAgICAgIHNyYy1hdHRyaWJ1dGUuNCA9IHNyYy1hdHRyaWJ1dGUuNDogTyBhdHJpYnV0byAnJ3swfScnIHRlbSB1bSBhdHJpYnV0byAnJ3R5cGUnJyBlIHVtICcnc2ltcGxlVHlwZScnIGZpbGhvIGFuXHUwMEY0bmltby4gU29tZW50ZSB1bSBkZWxlcyBcdTAwRTkgcGVybWl0aWRvIHBhcmEgdW0gYXRyaWJ1dG8uCi0gICAgICAgIHNyYy1hdHRyaWJ1dGVfZ3JvdXAuMiA9IHNyYy1hdHRyaWJ1dGVfZ3JvdXAuMjogQSBpbnRlcnNlY1x1MDBFN1x1MDBFM28gZG9zIGN1cmluZ2FzIG5cdTAwRTNvIFx1MDBFOSBleHByZXNzXHUwMEVEdmVsIHBhcmEgbyBncnVwbyBkZSBhdHJpYnV0b3MgJyd7MH0nJy4KLSAgICAgICAgc3JjLWF0dHJpYnV0ZV9ncm91cC4zID0gc3JjLWF0dHJpYnV0ZV9ncm91cC4zOiBEZWZpbmlcdTAwRTdcdTAwRjVlcyBjaXJjdWxhcmVzIGRldGVjdGFkYXMgcGFyYSBvIGdydXBvIGRlIGF0cmlidXRvcyAnJ3swfScnLiBTZWd1aXIgYXMgcmVmZXJcdTAwRUFuY2lhcyBkbyBncnVwbyBkZSBhdHJpYnV0b3MgZGUgZm9ybWEgcmVjdXJzaXZhIGFjYWJhIGNvbmR1emluZG8gYSBlbGUgcHJcdTAwRjNwcmlvLgotICAgICAgICBzcmMtY3QuMSA9IHNyYy1jdC4xOiBFcnJvIGRlIFJlcHJlc2VudGFcdTAwRTdcdTAwRTNvIGRhIERlZmluaVx1MDBFN1x1MDBFM28gZG8gVGlwbyBDb21wbGV4byBwYXJhIG8gdGlwbyAnJ3swfScnLiBRdWFuZG8gPGNvbXBsZXhDb250ZW50PiBcdTAwRTkgdXNhZG8sIG8gdGlwbyBiYXNlIGRldmUgc2VyIHVtIGNvbXBsZXhUeXBlLiAnJ3sxfScnIFx1MDBFOSB1bSBzaW1wbGVUeXBlLgotICAgICAgICBzcmMtY3QuMi4xID0gc3JjLWN0LjIuMTogRXJybyBkZSBSZXByZXNlbnRhXHUwMEU3XHUwMEUzbyBkYSBEZWZpbmlcdTAwRTdcdTAwRTNvIGRvIFRpcG8gQ29tcGxleG8gZG8gdGlwbyAnJ3swfScnLiBRdWFuZG8gPHNpbXBsZUNvbnRlbnQ+IFx1MDBFOSB1c2FkbywgbyB0aXBvIGRlIGJhc2UgZGV2ZSBzZXIgdW0gY29tcGxleFR5cGUgY3VqbyB0aXBvIGRlIGNvbnRlXHUwMEZBZG8gXHUwMEU5IHNpbXBsZXMgb3UsIHNvbWVudGUgc2UgYSByZXN0cmlcdTAwRTdcdTAwRTNvIGZvciBlc3BlY2lmaWNhZGEsIHVtIHRpcG8gY29tcGxleG8gY29tIGNvbnRlXHUwMEZBZG8gbWlzdG8gZSB1bWEgcGFydFx1MDBFRGN1bGEgZXN2YXppXHUwMEUxdmVsLCBvdSwgc29tZW50ZSBzZSBhIGV4dGVuc1x1MDBFM28gZm9yIGVzcGVjaWZpY2FkYSwgdW0gdGlwbyBzaW1wbGVzLiAnJ3sxfScnIG5cdTAwRTNvIHNhdGlzZmF6IG5lbmh1bWEgZGVzc2FzIGNvbmRpXHUwMEU3XHUwMEY1ZXMuCi0gICAgICAgIHNyYy1jdC4yLjIgPSBzcmMtY3QuMi4yOiBFcnJvIGRlIFJlcHJlc2VudGFcdTAwRTdcdTAwRTNvIGRlIERlZmluaVx1MDBFN1x1MDBFM28gZG8gVGlwbyBDb21wbGV4byBkbyB0aXBvICcnezB9JycuIFF1YW5kbyB1bSBjb21wbGV4VHlwZSBjb20gc2ltcGxlQ29udGVudCBcdTAwRTkgcmVzdHJpdG8gYSB1bSBjb21wbGV4VHlwZSBjb20gY29udGVcdTAwRkFkbyBtaXN0byBlIHBhcnRcdTAwRURjdWxhIGVzdmF6aVx1MDBFMXZlbCwgZW50XHUwMEUzbyBkZXZlIGhhdmVyIHVtIDxzaW1wbGVUeXBlPiBlbnRyZSBvcyBmaWxob3MgZGUgPHJlc3RyaWN0aW9uPi4KLSAgICAgICAgc3JjLWN0LjQgPSBzcmMtY3QuNDogRXJybyBkZSBSZXByZXNlbnRhXHUwMEU3XHUwMEUzbyBkZSBEZWZpbmlcdTAwRTdcdTAwRTNvIGRlIFRpcG8gQ29tcGxleG8gZG8gdGlwbyAnJ3swfScnLiBBIGludGVyc2VjXHUwMEU3XHUwMEUzbyBkZSBjdXJpbmdhcyBuXHUwMEUzbyBcdTAwRTkgZXhwcmVzc1x1MDBFRHZlbC4KLSAgICAgICAgc3JjLWN0LjUgPSBzcmMtY3QuNTogRXJybyBkZSBSZXByZXNlbnRhXHUwMEU3XHUwMEUzbyBkYSBEZWZpbmlcdTAwRTdcdTAwRTNvIGRvIFRpcG8gQ29tcGxleG8gZG8gdGlwbyAnJ3swfScnLiBBIHVuaVx1MDBFM28gZGUgY3VyaW5nYXMgblx1MDBFM28gXHUwMEU5IGV4cHJlc3NcdTAwRUR2ZWwuCi0gICAgICAgIHNyYy1lbGVtZW50LjEgPSBzcmMtZWxlbWVudC4xOiBBcyBwcm9wcmllZGFkZXMgJydwYWRyXHUwMEUzbycnIGUgJydmaXhlZCcnIG5cdTAwRTNvIHBvZGVtIGVzdGFyIHByZXNlbnRlcyBuYSBkZWNsYXJhXHUwMEU3XHUwMEUzbyBkbyBlbGVtZW50byAnJ3swfScnLiBVc2Ugc29tZW50ZSB1bWEgZGVsYXMuCi0gICAgICAgIHNyYy1lbGVtZW50LjIuMSA9IHNyYy1hdHRyaWJ1dGUuMi4xOiAncmVmJyBvdSAnbmFtZScgZGV2ZSBlc3RhciBwcmVzZW50ZSBuYSBkZWNsYXJhXHUwMEU3XHUwMEUzbyBkZSBlbGVtZW50byBkbyBsb2NhbC4KLSAgICAgICAgc3JjLWVsZW1lbnQuMi4yID0gc3JjLWVsZW1lbnQuMi4yOiBDb21vICcnezB9JycgY29udFx1MDBFOW0gbyBhdHJpYnV0byAnJ3JlZicnLCBzZXUgY29udGVcdTAwRkFkbyBkZXZlIHNlciBjb3JyZXNwb25kZW50ZSAoYW5ub3RhdGlvbj8pLiBObyBlbnRhbnRvLCAnJ3sxfScnIGZvaSBlbmNvbnRyYWRvLgotICAgICAgICBzcmMtZWxlbWVudC4zID0gc3JjLWVsZW1lbnQuMzogTyBlbGVtZW50byAnJ3swfScnIHRlbSB1bSBhdHJpYnV0byAnJ3R5cGUnJyBlIHVtIGZpbGhvICcnYW5vbnltb3VzIHR5cGUnJy4gU29tZW50ZSB1bSBkZWxlcyBcdTAwRTkgcGVybWl0aWRvIHBhcmEgdW0gZWxlbWVudG8uCi0gICAgICAgIHNyYy1pbXBvcnQuMS4xID0gc3JjLWltcG9ydC4xLjE6IE8gYXRyaWJ1dG8gZG8gbmFtZXNwYWNlICcnezB9JycgZGUgdW0gaXRlbSBkZSBpbmZvcm1hXHUwMEU3XHUwMEUzbyBkbyBlbGVtZW50byA8aW1wb3J0PiBuXHUwMEUzbyBkZXZlIHNlciBpZ3VhbCBhbyB0YXJnZXROYW1lc3BhY2UgZG8gZXNxdWVtYSBleGlzdGVudGUgbmVsZS4KLSAgICAgICAgc3JjLWltcG9ydC4xLjIgPSBzcmMtaW1wb3J0LjEuMjogU2UgbyBhdHJpYnV0byBkbyBuYW1lc3BhY2Ugblx1MDBFM28gZXN0aXZlciBwcmVzZW50ZSBlbSB1bSBpdGVtIGRlIGluZm9ybWFcdTAwRTdcdTAwRTNvIGRvIGVsZW1lbnRvIDxpbXBvcnQ+LCBlbnRcdTAwRTNvIG8gZXNxdWVtYSBkZWxpbWl0YWRvciBkZXZlIHRlciB1bSB0YXJnZXROYW1lc3BhY2UuCi0gICAgICAgIHNyYy1pbXBvcnQuMiA9IHNyYy1pbXBvcnQuMjogTyBlbGVtZW50by1yYWl6IGRvIGRvY3VtZW50byAiezB9JycgZGV2ZSB0ZXIgbyBub21lIGRvIG5hbWVzcGFjZSAnJ2h0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hJycgZSBvIG5vbWUgZG8gbG9jYWwgJydzY2hlbWEnJy4KLSAgICAgICAgc3JjLWltcG9ydC4zLjEgPSBzcmMtaW1wb3J0LjMuMTogTyBhdHJpYnV0byBkbyBuYW1lc3BhY2UsICcnezB9JycsIGRlIHVtIGl0ZW0gZGUgaW5mb3JtYVx1MDBFN1x1MDBFM28gZG8gZWxlbWVudG8gPGltcG9ydD4gZGV2ZSBzZXIgaWRcdTAwRUFudGljbyBhbyBhdHJpYnV0byB0YXJnZXROYW1lc3BhY2UsICcnezF9JycsIGRvIGRvY3VtZW50byBpbXBvcnRhZG8uCi0gICAgICAgIHNyYy1pbXBvcnQuMy4yID0gc3JjLWltcG9ydC4zLjI6IFVtIGl0ZW0gZGUgaW5mb3JtYVx1MDBFN1x1MDBFM28gZG8gZWxlbWVudG8gPGltcG9ydD4gcXVlIG5cdTAwRTNvIHRpbmhhIGF0cmlidXRvIGRlIG5hbWVzcGFjZSBmb2kgZW5jb250cmFkby4gRGVzc2EgZm9ybWEsIG8gZG9jdW1lbnRvIGltcG9ydGFkbyBuXHUwMEUzbyBwb2RlIHRlciB1bSBhdHJpYnV0byBkZSB0YXJnZXROYW1lc3BhY2UuIE5vIGVudGFudG8sIG8gdGFyZ2V0TmFtZXNwYWNlICcnezF9JycgZm9pIGVuY29udHJhZG8gbm8gZG9jdW1lbnRvIGltcG9ydGFkby4KLSAgICAgICAgc3JjLWluY2x1ZGUuMSA9IHNyYy1pbmNsdWRlLjE6IE8gZWxlbWVudG8tcmFpeiBkbyBkb2N1bWVudG8gInswfScnIGRldmUgdGVyIG8gbm9tZSBkbyBuYW1lc3BhY2UgJydodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYScnIGUgbyBub21lIGRvIGxvY2FsICcnc2NoZW1hJycuCi0gICAgICAgIHNyYy1pbmNsdWRlLjIuMSA9IHNyYy1pbmNsdWRlLjIuMTogTyB0YXJnZXROYW1lc3BhY2UgZG8gZXNxdWVtYSBtZW5jaW9uYWRvLCBhdHVhbG1lbnRlICcnezF9JycsIGRldmUgc2VyIGlkXHUwMEVBbnRpY28gYW8gZG8gZXNxdWVtYSBkZSBpbmNsdXNcdTAwRTNvLCBhdHVhbG1lbnRlICcnezB9JycuCi0gICAgICAgIHNyYy1yZWRlZmluZS4yID0gc3JjLXJlZGVmaW5lLjI6IE8gZWxlbWVudG8tcmFpeiBkbyBkb2N1bWVudG8gInswfScnIGRldmUgdGVyIG8gbm9tZSBkbyBuYW1lc3BhY2UgJydodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYScnIGUgbyBub21lIGRvIGxvY2FsICcnc2NoZW1hJycuCi0gICAgICAgIHNyYy1yZWRlZmluZS4zLjEgPSBzcmMtcmVkZWZpbmUuMy4xOiBPIHRhcmdldE5hbWVzcGFjZSBkbyBlc3F1ZW1hIG1lbmNpb25hZG8sIGF0dWFsbWVudGUgJyd7MX0nJywgZGV2ZSBzZXIgaWRcdTAwRUFudGljbyBhbyBkbyBlc3F1ZW1hIGRlIHJlZGVmaW5pXHUwMEU3XHUwMEUzbywgYXR1YWxtZW50ZSAnJ3swfScnLgotICAgICAgICBzcmMtcmVkZWZpbmUuNS5hLmEgPSBzcmMtcmVkZWZpbmUuNS5hLmE6IE5cdTAwRTNvIGZvcmFtIGVuY29udHJhZG9zIGZpbGhvcyBzZW0gYW5vdGFcdTAwRTdcdTAwRTNvIGRlIDxzaW1wbGVUeXBlPi4gT3MgZmlsaG9zIDxzaW1wbGVUeXBlPiBkb3MgZWxlbWVudG9zIDxyZWRlZmluZT4gZGV2ZW0gdGVyIGRlc2NlbmRlbnRlcyBkZSA8cmVzdHJpY3Rpb24+IGNvbSBhdHJpYnV0b3MgJ2Jhc2UnIHF1ZSBmYXplbSByZWZlclx1MDBFQW5jaWEgYSBlbGVzIHByXHUwMEYzcHJpb3MuCi0gICAgICAgIHNyYy1yZWRlZmluZS41LmEuYiA9IHNyYy1yZWRlZmluZS41LmEuYjogJyd7MH0nJyBuXHUwMEUzbyBcdTAwRTkgdW0gZWxlbWVudG8gZmlsaG8gdlx1MDBFMWxpZG8uIE9zIGZpbGhvcyA8c2ltcGxlVHlwZT4gZG9zIGVsZW1lbnRvcyA8cmVkZWZpbmU+IGRldmVtIHRlciBkZXNjZW5kZW50ZXMgZGUgPHJlc3RyaWN0aW9uPiBjb20gYXRyaWJ1dG9zICcnYmFzZScnIHF1ZSBmYXplbSByZWZlclx1MDBFQW5jaWEgYSBlbGVzIHByXHUwMEYzcHJpb3MuCi0gICAgICAgIHNyYy1yZWRlZmluZS41LmEuYyA9IHNyYy1yZWRlZmluZS41LmEuYzogJyd7MH0nJyBuXHUwMEUzbyB0ZW0gdW0gYXRyaWJ1dG8gImJhc2UiIHF1ZSBmYXogcmVmZXJcdTAwRUFuY2lhIGFvIGVsZW1lbnRvICcnezF9JycuIDxzaW1wbGVUeXBlPiBmaWxob3MgZG9zIGVsZW1lbnRvcyA8cmVkZWZpbmU+IGRldmVtIHRlciBkZXNjZW5kZW50ZXMgZGUgPHJlc3RyaWN0aW9uPiBjb20gYXRyaWJ1dG9zICcnYmFzZScnIHF1ZSBmYXplbSByZWZlclx1MDBFQW5jaWEgYSBlbGVzIHByXHUwMEYzcHJpb3MuCi0gICAgICAgIHNyYy1yZWRlZmluZS41LmIuYSA9IHNyYy1yZWRlZmluZS41LmIuYTogTmVuaHVtIGZpbGhvIHNlbSBhbm90YVx1MDBFN1x1MDBFM28gZGUgPGNvbXBsZXhUeXBlPiBmb2kgZW5jb250cmFkby4gT3MgZmlsaG9zIGRlIDxjb21wbGV4VHlwZT4gZG9zIGVsZW1lbnRvcyA8cmVkZWZpbmU+IGRldmVtIHRlciBvcyBkZXNjZW5kZW50ZXMgPGV4dGVuc2lvbj4gb3UgPHJlc3RyaWN0aW9uPiwgY29tIGF0cmlidXRvcyAnYmFzZScgcXVlIGZhemVtIHJlZmVyXHUwMEVBbmNpYSBhIGVsZXMgcHJcdTAwRjNwcmlvcy4KLSAgICAgICAgc3JjLXJlZGVmaW5lLjUuYi5iID0gc3JjLXJlZGVmaW5lLjUuYi5iOiBOZW5odW0gbmV0byBzZW0gYW5vdGFcdTAwRTdcdTAwRTNvIGRlIDxjb21wbGV4VHlwZT4gZm9pIGVuY29udHJhZG8uIE9zIGZpbGhvcyBkZSA8Y29tcGxleFR5cGU+IGRvcyBlbGVtZW50b3MgPHJlZGVmaW5lPiBkZXZlbSB0ZXIgb3MgZGVzY2VuZGVudGVzIDxleHRlbnNpb24+IG91IDxyZXN0cmljdGlvbj4gY29tIGF0cmlidXRvcyAnYmFzZScgcXVlIGZhemVtIHJlZmVyXHUwMEVBbmNpYSBhIGVsZXMgcHJcdTAwRjNwcmlvcy4KLSAgICAgICAgc3JjLXJlZGVmaW5lLjUuYi5jID0gc3JjLXJlZGVmaW5lLjUuYi5jOiAnJ3swfScnIG5cdTAwRTNvIFx1MDBFOSB1bSBlbGVtZW50byBkbyBuZXRvIHZcdTAwRTFsaWRvLiBPcyBmaWxob3MgZGUgPGNvbXBsZXhUeXBlPiBkb3MgZWxlbWVudG9zIDxyZWRlZmluZT4gZGV2ZW0gdGVyIG9zIGRlc2NlbmRlbnRlcyA8ZXh0ZW5zaW9uPiBvdSA8cmVzdHJpY3Rpb24+IGNvbSBhdHJpYnV0b3MgJydiYXNlJycgcXVlIGZhemVtIHJlZmVyXHUwMEVBbmNpYSBhIGVsZXMgcHJcdTAwRjNwcmlvcy4KLSAgICAgICAgc3JjLXJlZGVmaW5lLjUuYi5kID0gc3JjLXJlZGVmaW5lLjUuYi5kOiAnJ3swfScnIG5cdTAwRTNvIHRlbSB1bSBhdHJpYnV0byAiYmFzZSIgcXVlIGZheiByZWZlclx1MDBFQW5jaWEgYW8gZWxlbWVudG8gcmVkZWZpbmlkbyAnJ3sxfScnLiBPcyBmaWxob3MgZGUgPGNvbXBsZXhUeXBlPiBkb3MgZWxlbWVudG9zIDxyZWRlZmluZT4gZGV2ZW0gdGVyIGRlc2NlbmRlbnRlcyBkZSA8ZXh0ZW5zaW9uPiBvdSA8cmVzdHJpY3Rpb24+IGNvbSBhdHJpYnV0b3MgJydiYXNlJycgcXVlIGZhemVtIHJlZmVyXHUwMEVBbmNpYSBhIGVsZXMgcHJcdTAwRjNwcmlvcy4KLSAgICAgICAgc3JjLXJlZGVmaW5lLjYuMS4xID0gc3JjLXJlZGVmaW5lLjYuMS4xOiBTZSB1bSBmaWxobyBkbyBncnVwbyBkZSB1bSBlbGVtZW50byA8cmVkZWZpbmU+IGNvbnRpdmVyIHVtIGdydXBvIHF1ZSBmYXogcmVmZXJcdTAwRUFuY2lhIGEgc2kgcHJcdTAwRjNwcmlvLCBlbGUgZGV2ZSB0ZXIgZXhhdGFtZW50ZSAxOyBlc3RlIHRlbSAnJ3swfScnLgotICAgICAgICBzcmMtcmVkZWZpbmUuNi4xLjIgPSBzcmMtcmVkZWZpbmUuNi4xLjI6IE8gZ3J1cG8gJyd7MH0nJyBxdWUgY29udFx1MDBFOW0gdW0gcmVmZXJcdTAwRUFuY2lhIGEgdW0gZ3J1cG8gcXVlIGVzdFx1MDBFMSBzZW5kbyByZWRlZmluaWRvIGRldmUgdGVyICcnbWluT2NjdXJzJycgPSAnJ21heE9jY3VycycnID0gMS4KLSAgICAgICAgc3JjLXJlZGVmaW5lLjYuMi4xID0gc3JjLXJlZGVmaW5lLjYuMi4xOiBOZW5odW0gZ3J1cG8gbm8gZXNxdWVtYSByZWRlZmluaWRvIHRlbSB1bWEgY29ycmVzcG9uZFx1MDBFQW5jaWEgZGUgbm9tZSAnJ3swfScnLgotICAgICAgICBzcmMtcmVkZWZpbmUuNi4yLjIgPSBzcmMtcmVkZWZpbmUuNi4yLjI6IE8gZ3J1cG8gJyd7MH0nJyBuXHUwMEUzbyByZXN0cmluZ2UgYWRlcXVhZGFtZW50ZSBvIGdydXBvIHF1ZSBlbGUgcmVkZWZpbmU7IHJlc3RyaVx1MDBFN1x1MDBFM28gdmlvbGFkYTogJyd7MX0nJy4KLSAgICAgICAgc3JjLXJlZGVmaW5lLjcuMSA9IHNyYy1yZWRlZmluZS43LjE6IFNlIHVtIGZpbGhvIGRlIGF0dHJpYnV0ZUdyb3VwIGRlIHVtIGVsZW1lbnRvIDxyZWRlZmluZT4gY29udGl2ZXIgdW0gYXR0cmlidXRlR3JvdXAgcXVlIGZheiByZWZlclx1MDBFQW5jaWEgYSBlbGUgcHJcdTAwRjNwcmlvLCBlbGUgZGV2ZSB0ZXIgZXhhdGFtZW50ZSAxOyBlc3RlIHRlbSB7MH0uCi0gICAgICAgIHNyYy1yZWRlZmluZS43LjIuMSA9IHNyYy1yZWRlZmluZS43LjIuMTogTmVuaHVtIGF0dHJpYnV0ZUdyb3VwIG5vIGVzcXVlbWEgcmVkZWZpbmlkbyB0ZW0gdW1hIGNvcnJlc3BvbmRcdTAwRUFuY2lhIGRlIG5vbWUgJyd7MH0nJy4KLSAgICAgICAgc3JjLXJlZGVmaW5lLjcuMi4yID0gc3JjLXJlZGVmaW5lLjcuMi4yOiBPIEF0dHJpYnV0ZUdyb3VwICcnezB9Jycgblx1MDBFM28gcmVzdHJpbmdlIGFkZXF1YWRhbWVudGUgbyBhdHRyaWJ1dGVHcm91cCBxdWUgZWxlIHJlZGVmaW5lOyByZXN0cmlcdTAwRTdcdTAwRTNvIHZpb2xhZGE6ICcnezF9JycuCi0gICAgICAgIHNyYy1yZXNvbHZlID0gc3JjLXJlc29sdmU6IE5cdTAwRTNvIFx1MDBFOSBwb3NzXHUwMEVEdmVsIHJlc29sdmVyIG8gbm9tZSAnJ3swfScnIHBhcmEgdW0gY29tcG9uZW50ZSAnJ3sxfScnLgotICAgICAgICBzcmMtcmVzb2x2ZS40LjEgPSBzcmMtcmVzb2x2ZS40LjE6IEVycm8gYW8gcmVzb2x2ZXIgbyBjb21wb25lbnRlICcnezJ9JycuIEZvaSBkZXRlY3RhZG8gcXVlICcnezJ9Jycgblx1MDBFM28gdGVtIG5hbWVzcGFjZSwgbWFzIG5cdTAwRTNvIFx1MDBFOSBwb3NzXHUwMEVEdmVsIGZhemVyIHJlZmVyXHUwMEVBbmNpYSBhb3MgY29tcG9uZW50ZXMgZW0gbmFtZXNwYWNlIGRlIGRlc3Rpbm8gdXNhbmRvIG8gZG9jdW1lbnRvIGRvIGVzcXVlbWEgJyd7MH0nJy4gU2UgJyd7Mn0nJyBmb3IgZGVzdGluYWRvIGEgdW0gbmFtZXNwYWNlLCB0YWx2ZXogc2VqYSBuZWNlc3NcdTAwRTFyaW8gdW0gcHJlZml4by4gU2UgZm9yIGRldGVybWluYWRvIHF1ZSAnJ3syfScnIG5cdTAwRTNvIHRlbSBuYW1lc3BhY2UsIGVudFx1MDBFM28gdW1hICJpbXBvcnRhXHUwMEU3XHUwMEUzbyIgc2VtIHVtIGF0cmlidXRvICJuYW1lc3BhY2UiIGRldmVyXHUwMEUxIHNlciBhZGljaW9uYWRhIGEgInswfSIuCi0gICAgICAgIHNyYy1yZXNvbHZlLjQuMiA9IHNyYy1yZXNvbHZlLjQuMjogRXJybyBhbyByZXNvbHZlciBvIGNvbXBvbmVudGUgJyd7Mn0nJy4gRm9pIGRldGVjdGFkbyBxdWUgJyd7Mn0nJyBlc3RcdTAwRTEgbm8gbmFtZXNwYWNlICcnezF9JycsIG1hcyBuXHUwMEUzbyBcdTAwRTkgcG9zc1x1MDBFRHZlbCBmYXplciByZWZlclx1MDBFQW5jaWEgYW9zIGNvbXBvbmVudGVzIGVtIG5hbWVzcGFjZSBkZSBkZXN0aW5vIHVzYW5kbyBvIGRvY3VtZW50byBkbyBlc3F1ZW1hICcnezB9JycuIFNlIGVzdGUgZm9yIG8gbmFtZXNwYWNlIGluY29ycmV0bywgdGFsdmV6IG8gcHJlZml4byBkZSAnJ3syfScnIHByZWNpc2Ugc2VyIGFsdGVyYWRvLiBTZSBlc3RlIGZvciBvIG5hbWVzcGFjZSBjb3JyZXRvLCBlbnRcdTAwRTNvIGEgdGFnIGRlICJpbXBvcnRhXHUwMEU3XHUwMEUzbyIgYXByb3ByaWFkYSBkZXZlclx1MDBFMSBzZXIgYWRpY2lvbmFkYSBhICcnezB9JycuCi0gICAgICAgIHNyYy1zaW1wbGUtdHlwZS4yLmEgPSBzcmMtc2ltcGxlLXR5cGUuMi5hOiBGb2kgZW5jb250cmFkbyB1bSBlbGVtZW50byA8cmVzdHJpY3Rpb24+IHF1ZSB0ZW0gdW0gW2F0dHJpYnV0ZV0gYmFzZSBlIHVtIGVsZW1lbnRvIDxzaW1wbGVUeXBlPiBlbnRyZSBzZXVzIFtjaGlsZHJlbl0uIFNvbWVudGUgdW0gXHUwMEU5IHBlcm1pdGlkby4KLSAgICAgICAgc3JjLXNpbXBsZS10eXBlLjIuYiA9IHNyYy1zaW1wbGUtdHlwZS4yLmI6IEZvaSBlbmNvbnRyYWRvIHVtIGVsZW1lbnRvIDxyZXN0cmljdGlvbj4gcXVlIG5cdTAwRTNvIHRlbSB1bSBbYXR0cmlidXRlXSBiYXNlIG5lbSB1bSBlbGVtZW50byA8c2ltcGxlVHlwZT4gZW50cmUgc2V1cyBbY2hpbGRyZW5dLiBcdTAwQzkgbmVjZXNzXHUwMEUxcmlvIHVtLgotICAgICAgICBzcmMtc2ltcGxlLXR5cGUuMy5hID0gc3JjLXNpbXBsZS10eXBlLjMuYTogRm9pIGVuY29udHJhZG8gdW0gZWxlbWVudG8gPGxpc3Q+IHF1ZSB0ZW0gdW0gaXRlbVR5cGUgW2F0dHJpYnV0ZV0gZSB1bSBlbGVtZW50byA8c2ltcGxlVHlwZT4gZW50cmUgc2V1cyBbY2hpbGRyZW5dLiBTb21lbnRlIHVtIFx1MDBFOSBwZXJtaXRpZG8uCi0gICAgICAgIHNyYy1zaW1wbGUtdHlwZS4zLmIgPSBzcmMtc2ltcGxlLXR5cGUuMy5iOiBGb2kgZW5jb250cmFkbyB1bSBlbGVtZW50byA8bGlzdD4gcXVlIG5cdTAwRTNvIHRlbSB1bSBpdGVtVHlwZSBbYXR0cmlidXRlXSBuZW0gdW0gZWxlbWVudG8gPHNpbXBsZVR5cGU+IGVudHJlIHNldXMgW2NoaWxkcmVuXS4gVW0gXHUwMEU5IG5lY2Vzc1x1MDBFMXJpby4KLSAgICAgICAgc3JjLXNpbmdsZS1mYWNldC12YWx1ZSA9IHNyYy1zaW5nbGUtZmFjZXQtdmFsdWU6IE8gYXNwZWN0byAnJ3swfScnIGZvaSBkZWZpbmlkbyBtYWlzIGRlIHVtYSB2ZXouCi0gICAgICAgIHNyYy11bmlvbi1tZW1iZXJUeXBlcy1vci1zaW1wbGVUeXBlcyA9IHNyYy11bmlvbi1tZW1iZXJUeXBlcy1vci1zaW1wbGVUeXBlczogVW0gZWxlbWVudG8gPHVuaW9uPiBkZXZlIHRlciB1bSBtZW1iZXJUeXBlcyBbYXR0cmlidXRlXSBuXHUwMEUzbyB2YXppbyBvdSBwZWxvIG1lbm9zIHVtIGVsZW1lbnRvIDxzaW1wbGVUeXBlPiBlbnRyZSBzZXVzIFtjaGlsZHJlbl0uCi0KLSNjb25zdHJhaW50IHZhbGlkICgzLlguNikKLQotICAgICAgICBhZy1wcm9wcy1jb3JyZWN0LjIgPSBhZy1wcm9wcy1jb3JyZWN0LjI6IEVycm8gZG8gZ3J1cG8gZGUgYXRyaWJ1dG9zICcnezB9JycuIE9zIHVzb3MgZG8gYXRyaWJ1dG8gZHVwbGljYWRvIGNvbSBvIG1lc21vIG5vbWUgZSBuYW1lc3BhY2UgZGUgZGVzdGlubyBmb3JhbSBlc3BlY2lmaWNhZG9zLiBPIG5vbWUgZGUgdXNvIGRvIGF0cmlidXRvIGR1cGxpY2FkbyBcdTAwRTkgJyd7MX0nJy4KLSAgICAgICAgYWctcHJvcHMtY29ycmVjdC4zID0gYWctcHJvcHMtY29ycmVjdC4zOiBFcnJvIGRvIGdydXBvIGRlIGF0cmlidXRvcyAnJ3swfScnLiBEdWFzIGRlY2xhcmFcdTAwRTdcdTAwRjVlcyBkZSBhdHJpYnV0byAnJ3sxfScnIGUgJyd7Mn0nJyB0XHUwMEVBbSB0aXBvcyBxdWUgc1x1MDBFM28gb2J0aWRvcyBkbyBJRC4KLSAgICAgICAgYS1wcm9wcy1jb3JyZWN0LjIgPSBhLXByb3BzLWNvcnJlY3QuMjogVmFsb3IgZGUgcmVzdHJpXHUwMEU3XHUwMEUzbyBpbnZcdTAwRTFsaWRvICcnezF9Jycgbm8gYXRyaWJ1dG8gJyd7MH0nJy4KLSAgICAgICAgYS1wcm9wcy1jb3JyZWN0LjMgPSBhLXByb3BzLWNvcnJlY3QuMzogTyBhdHJpYnV0byAnJ3swfScnIG5cdTAwRTNvIHBvZGUgdXNhciAnJ2ZpeGVkJycgb3UgJydwYWRyXHUwMEUzbycnIHBvcnF1ZSBvICd7J3R5cGUgZGVmaW5pdGlvbid9JyBkbyBhdHJpYnV0byBcdTAwRTkgSUQgb3UgXHUwMEU5IG9idGlkYSBkbyBJRC4KLSAgICAgICAgYXUtcHJvcHMtY29ycmVjdC4yID0gYXUtcHJvcHMtY29ycmVjdC4yOiBOYSBkZWNsYXJhXHUwMEU3XHUwMEUzbyBkbyBhdHJpYnV0byBkZSAnJ3swfScnLCBmb2kgZXNwZWNpZmljYWRvIHVtIHZhbG9yIGZpeG8gZGUgJyd7MX0nJy4gRGVzc2EgZm9ybWEsIHNlIG8gdXNvIGRvIGF0cmlidXRvIHF1ZSBmYXogcmVmZXJcdTAwRUFuY2lhIGEgJyd7MH0nJyB0YW1iXHUwMEU5bSB0aXZlciB1bWEgJ3sndmFsdWUgY29uc3RyYWludCd9JywgZWxlIGRldmUgc2VyIGNvcnJpZ2lkbyBlIHNldSB2YWxvciBkZXZlIHNlciAnJ3sxfScnLgotICAgICAgICBjb3MtYWxsLWxpbWl0ZWQuMS4yID0gY29zLWFsbC1saW1pdGVkLjEuMjogVW0gZ3J1cG8gZGUgbW9kZWxvcyAnYWxsJyBkZXZlIHNlciBleGliaWRvIGVtIHVtYSBwYXJ0XHUwMEVEY3VsYSBjb20gJ3snbWluIG9jY3Vycyd9JyA9ICd7J21heCBvY2N1cnMnfScgPSAxIGUgZXNzYSBwYXJ0XHUwMEVEY3VsYSBkZXZlIGZhemVyIHBhcnRlIGRlIHVtIHBhciBxdWUgY29uc3RpdHVpIG8gJ3snY29udGVudCB0eXBlJ30nIGRlIHVtYSBkZWZpbmlcdTAwRTdcdTAwRTNvIGRlIHRpcG8gY29tcGxleGEuCi0gICAgICAgIGNvcy1hbGwtbGltaXRlZC4yID0gY29zLWFsbC1saW1pdGVkLjI6IE8gInsibWF4IG9jY3VycyJ9IiBkZSB1bSBlbGVtZW50byBlbSB1bSBncnVwbyBkZSBtb2RlbG9zICcnYWxsJycgZGV2ZSBzZXIgMCBvdSAxLiBPIHZhbG9yICcnezB9JycgZG8gZWxlbWVudG8gJyd7MX0nJyBcdTAwRTkgaW52XHUwMEUxbGlkby4KLSAgICAgICAgY29zLWFwcGxpY2FibGUtZmFjZXRzID0gY29zLWFwcGxpY2FibGUtZmFjZXRzOiBPIGFzcGVjdG8gJyd7MH0nJyBuXHUwMEUzbyBcdTAwRTkgcGVybWl0aWRvIHBlbG8gdGlwbyB7MX0uCi0gICAgICAgIGNvcy1jdC1leHRlbmRzLjEuMSA9IGNvcy1jdC1leHRlbmRzLjEuMTogTyB0aXBvICcnezB9JycgZm9pIG9idGlkbyBhdHJhdlx1MDBFOXMgZGEgZXh0ZW5zXHUwMEUzbyBkbyB0aXBvICcnezF9JycuIE5vIGVudGFudG8sIG8gYXRyaWJ1dG8gJydmaW5hbCcnIGRlICcnezF9JycgcHJvXHUwMEVEYmUgYSBvYnRlblx1MDBFN1x1MDBFM28gcG9yIG1laW8gZGEgZXh0ZW5zXHUwMEUzby4KLSAgICAgICAgY29zLWN0LWV4dGVuZHMuMS40LjMuMi4yLjEuYSA9IGNvcy1jdC1leHRlbmRzLjEuNC4zLjIuMi4xLmE6IE8gdGlwbyBkZSBjb250ZVx1MDBGQWRvIGRlIHVtIHRpcG8gZGVyaXZhZG8gZSBvIGRlIHN1YSBiYXNlIGRldmUgc2VyIG1pc3RvIG91IGFtYm9zIGRldmVtIHNlciBkZSBzb21lbnRlIGRvIGVsZW1lbnRvLiBPIHRpcG8gJyd7MH0nJyBcdTAwRTkgc29tZW50ZSBkbyBlbGVtZW50bywgbWFzIHN1YSBiYXNlIG5cdTAwRTNvIFx1MDBFOS4KLSAgICAgICAgY29zLWN0LWV4dGVuZHMuMS40LjMuMi4yLjEuYiA9IGNvcy1jdC1leHRlbmRzLjEuNC4zLjIuMi4xLmI6IE8gdGlwbyBkZSBjb250ZVx1MDBGQWRvIGRlIHVtIHRpcG8gZGVyaXZhZG8gZSBzdWEgYmFzZSBkZXZlbSBzZXIgbWlzdG9zIG91IGFtYm9zIGRldmVtIHNlciBzb21lbnRlIGRlIGVsZW1lbnRvLiBPIHRpcG8gJyd7MH0nJyBcdTAwRTkgbWlzdG8sIG1hcyBzZXUgdGlwbyBkZSBiYXNlIG5cdTAwRTNvIFx1MDBFOS4KLSAgICAgICAgY29zLWVsZW1lbnQtY29uc2lzdGVudCA9IGNvcy1lbGVtZW50LWNvbnNpc3RlbnQ6IEVycm8gZG8gdGlwbyAnJ3swfScnLiBWXHUwMEUxcmlvcyBlbGVtZW50b3MgY29tIG8gbm9tZSAnJ3sxfScnIGNvbSBkaWZlcmVudGVzIHRpcG9zIGFwYXJlY2VtIG5vIGdydXBvIGRlIG1vZGVsb3MuCi0gICAgICAgIGNvcy1saXN0LW9mLWF0b21pYyA9IGNvcy1saXN0LW9mLWF0b21pYzogTmEgZGVmaW5pXHUwMEU3XHUwMEUzbyBkbyB0aXBvIGRlIGxpc3RhICcnezB9JycsIG8gdGlwbyAnJ3sxfScnIFx1MDBFOSB1bSB0aXBvIGRlIGVsZW1lbnRvIGRhIGxpc3RhIGludlx1MDBFMWxpZG8gcG9ycXVlIG5cdTAwRTNvIFx1MDBFOSBhdFx1MDBGNG1pY28gKCcnezF9JycgXHUwMEU5IHVtIHRpcG8gZGUgbGlzdGEgb3UgdW0gdGlwbyBkZSB1bmlcdTAwRTNvIHF1ZSBjb250XHUwMEU5bSB1bWEgbGlzdGEpLgotICAgICAgICBjb3Mtbm9uYW1iaWcgPSBjb3Mtbm9uYW1iaWc6IHswfSBlIHsxfSAob3UgZWxlbWVudG9zIGRlIHNldSBncnVwbyBkZSBzdWJzdGl0dWlcdTAwRTdcdTAwRTNvKSB2aW9sYW0gYSAiVW5pcXVlIFBhcnRpY2xlIEF0dHJpYnV0aW9uIi4gRHVyYW50ZSBhIHZhbGlkYVx1MDBFN1x1MDBFM28gZGVzdGUgZXNxdWVtYSwgYSBhbWJpZ3VpZGFkZSBzZXJcdTAwRTEgY3JpYWRhIHBhcmEgZXNzYXMgZHVhcyBwYXJ0XHUwMEVEY3VsYXMuCi0gICAgICAgIGNvcy1wYXJ0aWNsZS1yZXN0cmljdC5hID0gY29zLXBhcnRpY2xlLXJlc3RyaWN0LmE6IEEgcGFydFx1MDBFRGN1bGEgb2J0aWRhIGVzdFx1MDBFMSB2YXppYSBlIGEgYmFzZSBuXHUwMEUzbyBwb2RlIHNlciBlc3ZhemlhZGEuCi0gICAgICAgIGNvcy1wYXJ0aWNsZS1yZXN0cmljdC5iID0gY29zLXBhcnRpY2xlLXJlc3RyaWN0LmI6IEEgcGFydFx1MDBFRGN1bGEgYmFzZSBlc3RcdTAwRTEgdmF6aWEsIG1hcyBhIHBhcnRcdTAwRURjdWxhIG9idGlkYSBuXHUwMEUzbyBlc3RcdTAwRTEuCi0gICAgICAgIGNvcy1wYXJ0aWNsZS1yZXN0cmljdC4yID0gY29zLXBhcnRpY2xlLXJlc3RyaWN0LjI6IFJlc3RyaVx1MDBFN1x1MDBFM28gZGUgcGFydFx1MDBFRGN1bGEgcHJvaWJpZGE6ICcnezB9JycuCi0gICAgICAgIGNvcy1zdC1yZXN0cmljdHMuMS4xID0gY29zLXN0LXJlc3RyaWN0cy4xLjE6IE8gdGlwbyAnJ3sxfScnIFx1MDBFOSBhdFx1MDBGNG1pY28uIERlc3NhIGZvcm1hLCBzdWEgJ3snYmFzZSB0eXBlIGRlZmluaXRpb24nfScsICcnezB9JycsIGRldmUgc2VyIHVtYSBkZWZpbmlcdTAwRTdcdTAwRTNvIGRlIHRpcG8gc2ltcGxlcyBhdFx1MDBGNG1pY28gb3UgdW0gdGlwbyBkZSBkYWRvcyBwcmltaXRpdm8gY3JpYWRvLgotICAgICAgICBjb3Mtc3QtcmVzdHJpY3RzLjIuMSA9IGNvcy1zdC1yZXN0cmljdHMuMi4xOiBOYSBkZWZpbmlcdTAwRTdcdTAwRTNvIGRvIHRpcG8gZGUgbGlzdGEgJyd7MH0nJywgbyB0aXBvICcnezF9JycgXHUwMEU5IHVtIHRpcG8gZGUgaXRlbSBpbnZcdTAwRTFsaWRvIHBvcnF1ZSBcdTAwRTkgdW0gdGlwbyAgZGUgbGlzdGEgb3UgdW0gdGlwbyBkZSB1bmlcdTAwRTNvIHF1ZSBjb250XHUwMEU5bSB1bWEgbGlzdGEuCi0gICAgICAgIGNvcy1zdC1yZXN0cmljdHMuMi4zLjEuMSA9IGNvcy1zdC1yZXN0cmljdHMuMi4zLjEuMTogTyBjb21wb25lbnRlICJ7ImZpbmFsIn0iIGRhICJ7Iml0ZW0gdHlwZSBkZWZpbml0aW9uIn0iICcnezB9JycgY29udFx1MDBFOW0gJydsaXN0JycuIElzc28gc2lnbmlmaWNhIHF1ZSAnJ3swfScnIG5cdTAwRTNvIHBvZGUgc2VyIHVzYWRvIGNvbW8gdW0gdGlwbyBkZSBpdGVtIGRvIHRpcG8gZGUgbGlzdGEgJyd7MX0nJy4KLSAgICAgICAgY29zLXN0LXJlc3RyaWN0cy4zLjMuMS4xID0gY29zLXN0LXJlc3RyaWN0cy4zLjMuMS4xOiBPIGNvbXBvbmVudGUgInsiZmluYWwifSIgZGUgInsibWVtYmVyIHR5cGUgZGVmaW5pdGlvbnMifSIsICcnezB9JycsIGNvbnRcdTAwRTltICcndW5pb24nJy4gSXNzbyBzaWduaWZpY2EgcXVlICcnezB9Jycgblx1MDBFM28gcG9kZSBzZXIgdXNhZG8gY29tbyB1bSB0aXBvIGRlIG1lbWJybyBkbyB0aXBvIGRlIHVuaVx1MDBFM28gJyd7MX0nJy4KLSAgICAgICAgY29zLXZhbGlkLWRlZmF1bHQuMi4xID0gY29zLXZhbGlkLXBhZHJcdTAwRTNvLjIuMTogTyBlbGVtZW50byAnJ3swfScnIHRlbSB1bWEgcmVzdHJpXHUwMEU3XHUwMEUzbyBkZSB2YWxvciBlIGRldmUgdGVyIHVtIG1vZGVsbyBkZSBjb250ZVx1MDBGQWRvIHNpbXBsZXMgb3UgbWlzdG8uCi0gICAgICAgIGNvcy12YWxpZC1kZWZhdWx0LjIuMi4yID0gY29zLXZhbGlkLXBhZHJcdTAwRTNvLjIuMi4yOiBDb21vIG8gZWxlbWVudG8gJyd7MH0nJyB0ZW0gdW1hICd7J3ZhbHVlIGNvbnN0cmFpbnQnfScgZSBzdWEgZGVmaW5pXHUwMEU3XHUwMEUzbyBkZSB0aXBvIHRlbSB7Jydjb250ZW50IHR5cGUnfScgbWlzdG8sIGVudFx1MDBFM28gYSBwYXJ0XHUwMEVEY3VsYSBkbyAneydjb250ZW50IHR5cGUnfScgZGV2ZSBzZXIgZXN2YXppXHUwMEUxdmVsLgotICAgICAgICBjLXByb3BzLWNvcnJlY3QuMiA9IGMtcHJvcHMtY29ycmVjdC4yOiBBIGNhcmRpbmFsaWRhZGUgZG9zIENhbXBvcyBkZSBrZXlyZWYgJyd7MH0nJyBlIGNoYXZlICcnezF9JycgZGV2ZSBzZXIgY29ycmVzcG9uZGVudGUuCi0gICAgICAgIGN0LXByb3BzLWNvcnJlY3QuMyA9IGN0LXByb3BzLWNvcnJlY3QuMzogRGVmaW5pXHUwMEU3XHUwMEY1ZXMgY2lyY3VsYXJlcyBkZXRlY3RhZGFzIHBhcmEgbyB0aXBvIGNvbXBsZXhvICcnezB9JycuIElzc28gc2lnbmlmaWNhIHF1ZSAnJ3swfScnIGVzdFx1MDBFMSBjb250aWRvIGVtIHN1YSBwclx1MDBGM3ByaWEgaGllcmFycXVpYSBkZSB0aXBvLCBvIHF1ZSBcdTAwRTkgdW0gZXJyby4KLSAgICAgICAgY3QtcHJvcHMtY29ycmVjdC40ID0gY3QtcHJvcHMtY29ycmVjdC40OiBFcnJvIGRvIHRpcG8gJyd7MH0nJy4gT3MgdXNvcyBkbyBhdHJpYnV0byBkdXBsaWNhZG8gY29tIG8gbWVzbW8gbm9tZSBlIG5hbWVzcGFjZSBkZSBkZXN0aW5vIGZvcmFtIGVzcGVjaWZpY2Fkb3MuIE8gbm9tZSBkbyB1c28gZG8gYXRyaWJ1dG8gZHVwbGljYWRvIFx1MDBFOSAnJ3sxfScnLgotICAgICAgICBjdC1wcm9wcy1jb3JyZWN0LjUgPSBjdC1wcm9wcy1jb3JyZWN0LjU6IEVycm8gZG8gdGlwbyAnJ3swfScnLiBEdWFzIGRlY2xhcmFcdTAwRTdcdTAwRjVlcyBkbyBhdHJpYnV0byAnJ3sxfScnIGUgJyd7Mn0nJyB0XHUwMEVBbSB0aXBvcyBxdWUgc1x1MDBFM28gb2J0aWRvcyBkbyBJRC4KLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4xID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4xOiBPIHRpcG8gJyd7MH0nJyBmb2kgb2J0aWRvIHBvciBtZWlvIGRhIHJlc3RyaVx1MDBFN1x1MDBFM28gZG8gdGlwbyAnJ3sxfScnLiBObyBlbnRhbnRvLCAnJ3sxfScnIHRlbSB1bWEgcHJvcHJpZWRhZGUgJ3snZmluYWwnfScgcXVlIHByb1x1MDBFRGJlIGEgZGVyaXZhXHUwMEU3XHUwMEUzbyBwb3IgcmVzdHJpXHUwMEU3XHUwMEUzby4KLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4yLjEuMSA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMi4xLjE6IEVycm8gZG8gdGlwbyAnJ3swfScnLiBPIHVzbyBkbyBhdHJpYnV0byAnJ3sxfScnIG5lc3RlIHRpcG8gdGVtIHVtIHZhbG9yIGRlICcndXNvJycgZGUgJyd7Mn0nJywgcXVlIFx1MDBFOSBpbmNvbnNpc3RlbnRlIGNvbSBvIHZhbG9yICcnb2JyaWdhdFx1MDBGM3JpbycnIGVtIHVtIHVzbyBkZSBhdHJpYnV0byBjb3JyZXNwb25kZW50ZSBubyB0aXBvIGRlIGJhc2UuCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMi4xLjIgPSBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjIuMS4yOiBFcnJvIGRvIHRpcG8gJyd7MH0nJy4gTyB1c28gZG8gYXRyaWJ1dG8gJyd7MX0nJyBuZXN0ZSB0aXBvIHRlbSBvIHRpcG8gJyd7Mn0nJywgcXVlIFx1MDBFOSBvYnRpZG8gZGUgZm9ybWEgdlx1MDBFMWxpZGEgZGUgInszfSIsIG8gdGlwbyBkZSB1c28gZG8gYXRyaWJ1dG8gY29ycmVzcG9uZGVudGUgbm8gdGlwbyBkZSBiYXNlLgotICAgICAgICBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjIuMS4zLmEgPSBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjIuMS4zLmE6IEVycm8gZG8gdGlwbyAnJ3swfScnLiBPIHVzbyBkbyBhdHJpYnV0byAnJ3sxfScnIG5lc3RlIHRpcG8gdGVtIHVtYSByZXN0cmlcdTAwRTdcdTAwRTNvIGRlIHZhbG9yIGVmZXRpdm8gcXVlIG5cdTAwRTNvIFx1MDBFOSBmaXhhIGUgYSByZXN0cmlcdTAwRTdcdTAwRTNvIGRlIHZhbG9yIGVmZXRpdm8gZG8gYXRyaWJ1dG8gY29ycmVzcG9uZGVudGUgbm8gdGlwbyBkZSBiYXNlIFx1MDBFOSBmaXhhLgotICAgICAgICBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjIuMS4zLmIgPSBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjIuMS4zLmI6IEVycm8gZG8gdGlwbyAnJ3swfScnLiBPIHVzbyBkbyBhdHJpYnV0byAnJ3sxfScnIG5lc3RlIHRpcG8gdGVtIHVtYSByZXN0cmlcdTAwRTdcdTAwRTNvIGRlIHZhbG9yIGVmZXRpdm8gZml4YSBjb20gdW0gdmFsb3IgZGUgInsyfSIgcXVlIG5cdTAwRTNvIFx1MDBFOSBjb25zaXN0ZW50ZSBjb20gbyB2YWxvciBkZSAiezN9IiBwYXJhIGEgcmVzdHJpXHUwMEU3XHUwMEUzbyBkZSB2YWxvciBlZmV0aXZvIGZpeGEgZG8gdXNvIGRvIGF0cmlidXRvIGNvcnJlc3BvbmRlbnRlIG5vIHRpcG8gZGUgYmFzZS4KLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4yLjIuYSA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMi4yLmE6IEVycm8gZG8gdGlwbyAnJ3swfScnLiBPIHVzbyBkbyBhdHJpYnV0byAnJ3sxfScnIG5lc3RlIHRpcG8gblx1MDBFM28gdGVtIHVtIHVzbyBkZSBhdHJpYnV0byBjb3JyZXNwb25kZW50ZSBuYSBiYXNlIGUgbyB0aXBvIGRlIGJhc2Ugblx1MDBFM28gdGVtIHVtIGF0cmlidXRvIGN1cmluZ2EuCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMi4yLmIgPSBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjIuMi5iOiBFcnJvIGRvIHRpcG8gJyd7MH0nJy4gTyB1c28gZG8gYXRyaWJ1dG8gJyd7MX0nJyBuZXN0ZSB0aXBvIG5cdTAwRTNvIHRlbSB1bSB1c28gZGUgYXRyaWJ1dG8gY29ycmVzcG9uZGVudGUgbmEgYmFzZSBlIG8gY3VyaW5nYSBubyB0aXBvIGRlIGJhc2Ugblx1MDBFM28gcGVybWl0ZSBvIG5hbWVzcGFjZSAiezJ9IiBkZXN0ZSB1c28gZG8gYXRyaWJ1dG8uCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMyA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMzogRXJybyBkbyB0aXBvICcnezB9JycuIE8gdXNvIGRvIGF0cmlidXRvICcnezF9Jycgbm8gdGlwbyBkZSBiYXNlIHRlbSBSRVFVSVJFRCBjb21vIHZlcmRhZGVpcm8sIG1hcyBuXHUwMEUzbyBoXHUwMEUxIHVzbyBkZSBhdHJpYnV0byBjb3JyZXNwb25kZW50ZSBubyB0aXBvIG9idGlkby4KLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi40LjEgPSBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjQuMTogRXJybyBkbyB0aXBvICcnezB9JycuIEEgZGVyaXZhXHUwMEU3XHUwMEUzbyB0ZW0gdW0gY3VyaW5nYSBkZSBhdHJpYnV0bywgbWFzIGEgYmFzZSBuXHUwMEUzbyB0ZW0uCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uNC4yID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi40LjI6IEVycm8gZG8gdGlwbyAnJ3swfScnLiBPIGN1cmluZ2EgbmEgZGVyaXZhXHUwMEU3XHUwMEUzbyBuXHUwMEUzbyBcdTAwRTkgdW0gc3ViY29uanVudG8gZGUgY3VyaW5nYXMgdlx1MDBFMWxpZG8gZGFxdWVsZSBkYSBiYXNlLgotICAgICAgICBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjQuMyA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uNC4zOiBFcnJvIGRvIHRpcG8gJyd7MH0nJy4gTyBjb250ZVx1MDBGQWRvIGRvIHByb2Nlc3NvIGRvIGN1cmluZ2EgbmEgZGVyaXZhXHUwMEU3XHUwMEUzbyAoezF9KSBcdTAwRTkgbWFpcyBmcmFjbyBxdWUgYXF1ZWxlIGRhIGJhc2UgKHsyfSkuCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uNS4yLjIuMSA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uNS4yLjIuMTogRXJybyBkbyB0aXBvICcnezB9JycuIE8gdGlwbyBkZSBjb250ZVx1MDBGQWRvIHNpbXBsZXMgZGVzdGUgdGlwbyAnJ3sxfScnIG5cdTAwRTNvIHNlIHRyYXRhIGRlIHVtYSByZXN0cmlcdTAwRTdcdTAwRTNvIHZcdTAwRTFsaWRhIGRvIHRpcG8gZGUgY29udGVcdTAwRkFkbyBzaW1wbGVzIGRhIGJhc2UsICcnezJ9JycuCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uNS4zLjIgPSBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjUuMy4yOiBFcnJvIGRvIHRpcG8gJyd7MH0nJy4gTyB0aXBvIGRlIGNvbnRlXHUwMEZBZG8gZGVzdGUgdGlwbyBlc3RcdTAwRTEgdmF6aW8sIG1hcyBvIHRpcG8gZGUgY29udGVcdTAwRkFkbyBkYSBiYXNlLCAnJ3sxfScnLCBuXHUwMEUzbyBlc3RcdTAwRTEgdmF6aW8gb3UgXHUwMEU5IGVzdmF6aVx1MDBFMXZlbC4KLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi41LjQuMS4yID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi41LjQuMS4yOiBFcnJvIGRvIHRpcG8gJyd7MH0nJy4gTyB0aXBvIGRlIGNvbnRlXHUwMEZBZG8gZGVzdGUgdGlwbyBcdTAwRTkgbWlzdG8sIG1hcyBvIHRpcG8gZGUgY29udGVcdTAwRkFkbyBkYSBiYXNlICcnezF9Jycgblx1MDBFM28gXHUwMEU5LgotICAgICAgICBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjUuNC4yID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi41LjQuMjogRXJybyBkbyB0aXBvICcnezB9JycuIEEgcGFydFx1MDBFRGN1bGEgZG8gdGlwbyBuXHUwMEUzbyBcdTAwRTkgdW1hIHJlc3RyaVx1MDBFN1x1MDBFM28gdlx1MDBFMWxpZGEgZGEgcGFydFx1MDBFRGN1bGEgZGEgYmFzZS4KLSAgICAgICAgZW51bWVyYXRpb24tcmVxdWlyZWQtbm90YXRpb24gPSBlbnVtZXJhdGlvbi1yZXF1aXJlZC1ub3RhdGlvbjogTyB0aXBvIGRlIE5PVEFUSU9OLCAnJ3swfScnIHVzYWRvIHBvciB7Mn0gJyd7MX0nJywgZGV2ZSB0ZXIgdW0gdmFsb3IgZGUgYXNwZWN0byBkZSBlbnVtZXJhXHUwMEU3XHUwMEUzbyBxdWUgZXNwZWNpZmljYSBvcyBlbGVtZW50b3MgZGUgbm90YVx1MDBFN1x1MDBFM28gdXNhZG9zIHBvciBlc3RlIHRpcG8uCi0gICAgICAgIGVudW1lcmF0aW9uLXZhbGlkLXJlc3RyaWN0aW9uID0gZW51bWVyYXRpb24tdmFsaWQtcmVzdHJpY3Rpb246IE8gdmFsb3IgZGEgZW51bWVyYVx1MDBFN1x1MDBFM28gJyd7MH0nJyBuXHUwMEUzbyBcdTAwRTkgbyBlc3BhXHUwMEU3byBkbyB2YWxvciBkbyB0aXBvIGRlIGJhc2UsIHsxfS4KLSAgICAgICAgZS1wcm9wcy1jb3JyZWN0LjIgPSBlLXByb3BzLWNvcnJlY3QuMjogVmFsb3IgZGUgcmVzdHJpXHUwMEU3XHUwMEUzbyBkZSB2YWxvciBpbnZcdTAwRTFsaWRvICcnezF9Jycgbm8gZWxlbWVudG8gJyd7MH0nJy4KLSAgICAgICAgZS1wcm9wcy1jb3JyZWN0LjQgPSBlLXByb3BzLWNvcnJlY3QuNDogQSAieyJ0eXBlIGRlZmluaXRpb24ifSIgZG8gZWxlbWVudG8gJyd7MH0nJyBuXHUwMEUzbyBcdTAwRTkgb2J0aWRhIGRlIGZvcm1hIHZcdTAwRTFsaWRhIGEgcGFydGlyIGRhICJ7InR5cGUgZGVmaW5pdGlvbiJ9IiBkZSBzdWJzdGl0dXRpb25IZWFkICcnezF9Jycgb3UgYSBwcm9wcmllZGFkZSAieyJzdWJzdGl0dXRpb24gZ3JvdXAgZXhjbHVzaW9ucyJ9IiBkZSAnJ3sxfScnIG5cdTAwRTNvIHBlcm1pdGUgZXN0YSBkZXJpdmFcdTAwRTdcdTAwRTNvLgotICAgICAgICBlLXByb3BzLWNvcnJlY3QuNSA9IGUtcHJvcHMtY29ycmVjdC41OiBVbWEgInsidmFsdWUgY29uc3RyYWludCJ9IiBuXHUwMEUzbyBkZXZlIGVzdGFyIHByZXNlbnRlIG5vIGVsZW1lbnRvICcnezB9JycgcG9ycXVlIGEgInsidHlwZSBkZWZpbml0aW9uIn0iIGRvIGVsZW1lbnRvIG91IG8gInsiY29udGVudCB0eXBlIn0iIGRhICJ7InR5cGUgZGVmaW5pdGlvbiJ9IiBcdTAwRTkgSUQgb3Ugb2J0aWRhIGRvIElELgotICAgICAgICBlLXByb3BzLWNvcnJlY3QuNiA9IGUtcHJvcHMtY29ycmVjdC42OiBHcnVwbyBkZSBzdWJzdGl0dWlcdTAwRTdcdTAwRTNvIGNpcmN1bGFyIGRldGVjdGFkYSBwYXJhIG8gZWxlbWVudG8gJyd7MH0nJy4KLSAgICAgICAgZnJhY3Rpb25EaWdpdHMtdmFsaWQtcmVzdHJpY3Rpb24gPSBmcmFjdGlvbkRpZ2l0cy12YWxpZC1yZXN0cmljdGlvbjogTmEgZGVmaW5pXHUwMEU3XHUwMEUzbyBkZSB7Mn0sIG8gdmFsb3IgJyd7MH0nJyBkZSAnJ2ZyYWN0aW9uRGlnaXRzJycgZG8gYXNwZWN0byBcdTAwRTkgaW52XHUwMEUxbGlkbyBwb3JxdWUgZWxlIGRldmUgc2VyIDw9IGFvIHZhbG9yIGRlICcnZnJhY3Rpb25EaWdpdHMnJyBxdWUgZm9pIGRlZmluaWRvIGNvbW8gJyd7MX0nJyBlbSB1bSBkb3MgdGlwb3MgZGUgYW5jZXN0cmFpcy4KLSAgICAgICAgZnJhY3Rpb25EaWdpdHMtdG90YWxEaWdpdHMgPSBmcmFjdGlvbkRpZ2l0cy10b3RhbERpZ2l0czogTmEgZGVmaW5pXHUwMEU3XHUwMEUzbyBkZSB7Mn0sIG8gdmFsb3IgJyd7MH0nJyBkbyBhc3BlY3RvICcnZnJhY3Rpb25EaWdpdHMnJyBcdTAwRTkgaW52XHUwMEUxbGlkbyBwb3JxdWUgbyB2YWxvciBkZXZlIHNlciA8PSBvIHZhbG9yIGRlICcndG90YWxEaWdpdHMnJyBxdWUgXHUwMEU5ICcnezF9JycuCi0gICAgICAgIGxlbmd0aC1taW5MZW5ndGgtbWF4TGVuZ3RoLjEuMSA9IGxlbmd0aC1taW5MZW5ndGgtbWF4TGVuZ3RoLjEuMTogUGFyYSBvIHRpcG8gezB9LCBcdTAwRTkgdW0gZXJybyBwYXJhIHF1ZSBvIHZhbG9yIGRvIHRhbWFuaG8gJyd7MX0nJyBzZWphIG1lbm9yIHF1ZSBvIHZhbG9yIGRlIG1pbkxlbmd0aCAnJ3syfScnLgotICAgICAgICBsZW5ndGgtbWluTGVuZ3RoLW1heExlbmd0aC4xLjIuYSA9IGxlbmd0aC1taW5MZW5ndGgtbWF4TGVuZ3RoLjEuMi5hOiBQYXJhIG8gdGlwbyB7MH0sIFx1MDBFOSB1bSBlcnJvIHBhcmEgcXVlIGEgYmFzZSBuXHUwMEUzbyB0ZW5oYSB1bSBhc3BlY3RvIGRlIG1pbkxlbmd0aCwgc2UgYSByZXN0cmlcdTAwRTdcdTAwRTNvIGF0dWFsIHRpdmVyIG8gYXNwZWN0byBtaW5MZW5ndGggZSBhIHJlc3RyaVx1MDBFN1x1MDBFM28gYXR1YWwgb3UgYSBiYXNlIHRlbmhhIG8gYXNwZWN0byBkZSB0YW1hbmhvLgotICAgICAgICBsZW5ndGgtbWluTGVuZ3RoLW1heExlbmd0aC4xLjIuYiA9IGxlbmd0aC1taW5MZW5ndGgtbWF4TGVuZ3RoLjEuMi5iOiBQYXJhIG8gdGlwbyB7MH0sIFx1MDBFOSB1bSBlcnJvIHBhcmEgcXVlIG8gbWluTGVuZ3RoICcnezF9JycgYXR1YWwgblx1MDBFM28gc2VqYSBpZ3VhbCBhbyBtaW5MZW5ndGggJyd7Mn0nJyBiYXNlLgotICAgICAgICBsZW5ndGgtbWluTGVuZ3RoLW1heExlbmd0aC4yLjEgPSBsZW5ndGgtbWluTGVuZ3RoLW1heExlbmd0aC4xLjI6IFBhcmEgbyB0aXBvIHswfSwgXHUwMEU5IHVtIGVycm8gcGFyYSBxdWUgbyB2YWxvciBkbyB0YW1hbmhvICcnezF9Jycgc2VqYSBtYWlvciBxdWUgbyB2YWxvciBkZSBtYXhMZW5ndGggJyd7Mn0nJy4KLSAgICAgICAgbGVuZ3RoLW1pbkxlbmd0aC1tYXhMZW5ndGguMi4yLmEgPSBsZW5ndGgtbWluTGVuZ3RoLW1heExlbmd0aC4yLjIuYTogUGFyYSBvIHRpcG8gezB9LCBcdTAwRTkgdW0gZXJybyBwYXJhIHF1ZSBhIGJhc2Ugblx1MDBFM28gdGVuaGEgdW0gYXNwZWN0byBkZSBtYXhMZW5ndGgsIHNlIGEgcmVzdHJpXHUwMEU3XHUwMEUzbyBhdHVhbCB0aXZlciBvIGFzcGVjdG8gbWF4TGVuZ3RoIGUgYSByZXN0cmlcdTAwRTdcdTAwRTNvIGF0dWFsIG91IGEgYmFzZSB0aXZlciBvIGFzcGVjdG8gZGUgdGFtYW5oby4KLSAgICAgICAgbGVuZ3RoLW1pbkxlbmd0aC1tYXhMZW5ndGguMi4yLmIgPSBsZW5ndGgtbWluTGVuZ3RoLW1heExlbmd0aC4yLjIuYjogUGFyYSBvIHRpcG8gezB9LCBcdTAwRTkgdW0gZXJybyBwYXJhIHF1ZSBvIG1heExlbmd0aCAnJ3sxfScnIGF0dWFsIG5cdTAwRTNvIHNlamEgaWd1YWwgYW8gbWF4bkxlbmd0aCAnJ3syfScnIGJhc2UuCi0gICAgICAgIGxlbmd0aC12YWxpZC1yZXN0cmljdGlvbiA9IGxlbmd0aC12YWxpZC1yZXN0cmljdGlvbjogRXJybyBkbyB0aXBvICcnezJ9JycuIE8gdmFsb3IgZG8gdGFtYW5obyA9ICcnezB9JycgZGV2ZSBzZXIgPSBvIHZhbG9yIGRvIHRpcG8gZGUgYmFzZSAnJ3sxfScnLgotICAgICAgICBtYXhFeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMSA9IG1heEV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4xOiBFcnJvIGRvIHRpcG8gJyd7Mn0nJy4gTyB2YWxvciBtYXhFeGNsdXNpdmUgPScnezB9JycgZGV2ZSBzZXIgPD0gbWF4RXhjbHVzaXZlIGRvIHRpcG8gZGUgYmFzZSAnJ3sxfScnLgotICAgICAgICBtYXhFeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMiA9IG1heEV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4yOiBFcnJvIGRvIHRpcG8gJyd7Mn0nJy4gTyB2YWxvciBtYXhFeGNsdXNpdmUgPScnezB9JycgZGV2ZSBzZXIgPD0gbWF4SW5jbHVzaXZlIGRvIHRpcG8gZGUgYmFzZSAnJ3sxfScnLgotICAgICAgICBtYXhFeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMyA9IG1heEV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4zOiBFcnJvIGRvIHRpcG8gJyd7Mn0nJy4gTyB2YWxvciBtYXhFeGNsdXNpdmUgPScnezB9JycgZGV2ZSBzZXIgPiBtaW5FeGNsdXNpdmUgZG8gdGlwbyBkZSBiYXNlICcnezF9JycuCi0gICAgICAgIG1heEV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi40ID0gbWF4RXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjQ6IEVycm8gZG8gdGlwbyAnJ3syfScnLiBPIHZhbG9yIG1heEV4Y2x1c2l2ZSA9Jyd7MH0nJyBkZXZlIHNlciA+IG1pbkV4Y2x1c2l2ZSBkbyB0aXBvIGRlIGJhc2UgJyd7MX0nJy4KLSAgICAgICAgbWF4SW5jbHVzaXZlLW1heEV4Y2x1c2l2ZSA9IG1heEluY2x1c2l2ZS1tYXhFeGNsdXNpdmU6IFx1MDBDOSB1bSBlcnJvIHBhcmEgcXVlIG1heEluY2x1c2l2ZSBlIG1heEV4Y2x1c2l2ZSBzZWphbSBlc3BlY2lmaWNhZG9zIHBhcmEgbyBtZXNtbyB0aXBvIGRlIGRhZG9zLiBFbSB7Mn0sIG1heEluY2x1c2l2ZSA9ICcnezB9JycgZSBtYXhFeGNsdXNpdmUgPSAnJ3sxfScnLgotICAgICAgICBtYXhJbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMSA9IG1heEluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4xOiBFcnJvIGRvIHRpcG8gJyd7Mn0nJy4gTyB2YWxvciBtYXhJbmNsdXNpdmUgPScnezB9JycgZGV2ZSBzZXIgPD0gbWF4SW5jbHVzaXZlIGRvIHRpcG8gZGUgYmFzZSAnJ3sxfScnLgotICAgICAgICBtYXhJbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMiA9IG1heEluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4yOiBFcnJvIGRvIHRpcG8gJyd7Mn0nJy4gTyB2YWxvciBtYXhJbmNsdXNpdmUgPScnezB9JycgZGV2ZSBzZXIgPD0gbWF4RXhjbHVzaXZlIGRvIHRpcG8gZGUgYmFzZSAnJ3sxfScnLgotICAgICAgICBtYXhJbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMyA9IG1heEluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4zOiBFcnJvIGRvIHRpcG8gJyd7Mn0nJy4gTyB2YWxvciBtYXhJbmNsdXNpdmUgPScnezB9JycgZGV2ZSBzZXIgPiA9IG1pbkluY2x1c2l2ZSBkbyB0aXBvIGRlIGJhc2UgJyd7MX0nJy4KLSAgICAgICAgbWF4SW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjQgPSBtYXhJbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uNDogRXJybyBkbyB0aXBvICcnezJ9JycuIE8gdmFsb3IgbWF4SW5jbHVzaXZlID0nJ3swfScnIGRldmUgc2VyID4gbWluSW5jbHVzaXZlIGRvIHRpcG8gZGUgYmFzZSAnJ3sxfScnLgotICAgICAgICBtYXhMZW5ndGgtdmFsaWQtcmVzdHJpY3Rpb24gPSBtYXhMZW5ndGgtdmFsaWQtcmVzdHJpY3Rpb246IE5hIGRlZmluaVx1MDBFN1x1MDBFM28gZGUgezJ9LCBvIHZhbG9yIG1heExlbmd0aCA9ICcnezB9JycgZGV2ZSBzZXIgPD0gcXVlIG8gZG8gdGlwbyBkZSBiYXNlICcnezF9JycuCi0gICAgICAgIG1nLXByb3BzLWNvcnJlY3QuMiA9IG1nLXByb3BzLWNvcnJlY3QuMjogRGVmaW5pXHUwMEU3XHUwMEY1ZXMgY2lyY3VsYXJlcyBkZXRlY3RhZGFzIHBhcmEgbyBncnVwbyAnJ3swfScnLiBTZWd1aXIgZGUgZm9ybWEgcmVjdXJzaXZhIGRvcyB2YWxvcmVzIGRlICd7J3Rlcm0nfScgZGFzIHBhcnRcdTAwRURjdWxhcyBjb25kdXogYSB1bWEgcGFydFx1MDBFRGN1bGEgY3VqbyAneyd0ZXJtJ30nIFx1MDBFOSBvIHByXHUwMEYzcHJpbyBncnVwby4KLSAgICAgICAgbWluRXhjbHVzaXZlLWxlc3MtdGhhbi1lcXVhbC10by1tYXhFeGNsdXNpdmUgPSBtaW5FeGNsdXNpdmUtbGVzcy10aGFuLWVxdWFsLXRvLW1heEV4Y2x1c2l2ZTogTmEgZGVmaW5pXHUwMEU3XHUwMEUzbyBkZSB7Mn0sIG8gdmFsb3IgbWluRXhjbHVzaXZlID0gJyd7MH0nJyBkZXZlIHNlciA8PSBxdWUgbyB2YWxvciBtYXhFeGNsdXNpdmUgPSAnJ3sxfScnLgotICAgICAgICBtaW5FeGNsdXNpdmUtbGVzcy10aGFuLW1heEluY2x1c2l2ZSA9IG1pbkV4Y2x1c2l2ZS1sZXNzLXRoYW4tbWF4SW5jbHVzaXZlOiBOYSBkZWZpbmlcdTAwRTdcdTAwRTNvIGRlIHsyfSwgbyB2YWxvciBtaW5FeGNsdXNpdmUgPSAnJ3swfScnIGRldmUgc2VyIDw9IHF1ZSBvIHZhbG9yIG1heEluY2x1c2l2ZSA9ICcnezF9JycuCi0gICAgICAgIG1pbkV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4xID0gbWluRXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjE6IEVycm8gZG8gdGlwbyAnJ3syfScnLiBPIHZhbG9yIG1pbkV4Y2x1c2l2ZSA9Jyd7MH0nJyBkZXZlIHNlciA+PSBtaW5FeGNsdXNpdmUgZG8gdGlwbyBkZSBiYXNlICcnezF9JycuCi0gICAgICAgIG1pbkV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4yID0gbWluRXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjI6IEVycm8gZG8gdGlwbyAnJ3syfScnLiBPIHZhbG9yIG1pbkV4Y2x1c2l2ZSA9Jyd7MH0nJyBkZXZlIHNlciA8PSBtYXhFeGNsdXNpdmUgZG8gdGlwbyBkZSBiYXNlICcnezF9JycuCi0gICAgICAgIG1pbkV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4zID0gbWluRXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjM6IEVycm8gZG8gdGlwbyAnJ3syfScnLiBPIHZhbG9yIG1pbkV4Y2x1c2l2ZSA9Jyd7MH0nJyBkZXZlIHNlciA+PSBtaW5JbmNsdXNpdmUgZG8gdGlwbyBkZSBiYXNlICcnezF9JycuCi0gICAgICAgIG1pbkV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi40ID0gbWluRXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjQ6IEVycm8gZG8gdGlwbyAnJ3syfScnLiBPIHZhbG9yIG1pbkV4Y2x1c2l2ZSA9Jyd7MH0nJyBkZXZlIHNlciA8IG1heEV4Y2x1c2l2ZSBkbyB0aXBvIGRlIGJhc2UgJyd7MX0nJy4KLSAgICAgICAgbWluSW5jbHVzaXZlLWxlc3MtdGhhbi1lcXVhbC10by1tYXhJbmNsdXNpdmUgPSBtaW5JbmNsdXNpdmUtbGVzcy10aGFuLWVxdWFsLXRvLW1heEluY2x1c2l2ZTogTmEgZGVmaW5pXHUwMEU3XHUwMEUzbyBkZSB7Mn0sIG8gdmFsb3IgbWluSW5jbHVzaXZlID0gJyd7MH0nJyBkZXZlIHNlciA8PSBxdWUgbyB2YWxvciBtYXhJbmNsdXNpdmUgPSAnJ3sxfScnLgotICAgICAgICBtaW5JbmNsdXNpdmUtbGVzcy10aGFuLW1heEV4Y2x1c2l2ZSA9IG1pbkluY2x1c2l2ZS1sZXNzLXRoYW4tbWF4RXhjbHVzaXZlOiBOYSBkZWZpbmlcdTAwRTdcdTAwRTNvIGRlIHsyfSwgbyB2YWxvciBtaW5JbmNsdXNpdmUgPSAnJ3swfScnIGRldmUgc2VyIDw9IHF1ZSBvIHZhbG9yIG1heEV4Y2x1c2l2ZSA9ICcnezF9JycuCi0gICAgICAgIG1pbkluY2x1c2l2ZS1taW5FeGNsdXNpdmUgPSBtaW5JbmNsdXNpdmUtbWluRXhjbHVzaXZlOiBcdTAwQzkgdW0gZXJybyBwYXJhIHF1ZSBtaW5JbmNsdXNpdmUgZSBtaW5FeGNsdXNpdmUgc2VqYW0gZXNwZWNpZmljYWRvcyBwYXJhIG8gbWVzbW8gdGlwbyBkZSBkYWRvcy4gRW0gezJ9LCBtaW5JbmNsdXNpdmUgPSAnJ3swfScnIGUgbWluRXhjbHVzaXZlID0gJyd7MX0nJy4KLSAgICAgICAgbWluSW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjEgPSBtaW5JbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMTogRXJybyBkbyB0aXBvICcnezJ9JycuIE8gdmFsb3IgbWluSW5jbHVzaXZlID0nJ3swfScnIGRldmUgc2VyID49IG1pbkluY2x1c2l2ZSBkbyB0aXBvIGRlIGJhc2UgJyd7MX0nJy4KLSAgICAgICAgbWluSW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjIgPSBtaW5JbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMjogRXJybyBkbyB0aXBvICcnezJ9JycuIE8gdmFsb3IgbWluSW5jbHVzaXZlID0nJ3swfScnIGRldmUgc2VyIDw9IG1heEluY2x1c2l2ZSBkbyB0aXBvIGRlIGJhc2UgJyd7MX0nJy4KLSAgICAgICAgbWluSW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjMgPSBtaW5JbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMzogRXJybyBkbyB0aXBvICcnezJ9JycuIE8gdmFsb3IgbWluSW5jbHVzaXZlID0nJ3swfScnIGRldmUgc2VyID4gbWluRXhjbHVzaXZlIGRvIHRpcG8gZGUgYmFzZSAnJ3sxfScnLgotICAgICAgICBtaW5JbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uNCA9IG1pbkluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi40OiBFcnJvIGRvIHRpcG8gJyd7Mn0nJy4gTyB2YWxvciBtaW5JbmNsdXNpdmUgPScnezB9JycgZGV2ZSBzZXIgPD0gbWF4RXhjbHVzaXZlIGRvIHRpcG8gZGUgYmFzZSAnJ3sxfScnLgotICAgICAgICBtaW5MZW5ndGgtbGVzcy10aGFuLWVxdWFsLXRvLW1heExlbmd0aCA9IG1pbkxlbmd0aC1sZXNzLXRoYW4tZXF1YWwtdG8tbWF4TGVuZ3RoOiBOYSBkZWZpbmlcdTAwRTdcdTAwRTNvIGRlIHsyfSwgbyB2YWxvciBtaW5MZW5ndGggPSAnJ3swfScnIGRldmUgc2VyIDwgbyB2YWxvciBkZSBtYXhMZW5ndGggPSAnJ3sxfScnLgotICAgICAgICBtaW5MZW5ndGgtdmFsaWQtcmVzdHJpY3Rpb24gPSBtaW5MZW5ndGgtdmFsaWQtcmVzdHJpY3Rpb246IE5hIGRlZmluaVx1MDBFN1x1MDBFM28gZGUgezJ9LCBtaW5MZW5ndGggPSAnJ3swfScnIGRldmUgc2VyID49IHF1ZSBvIGRvIHRpcG8gZGUgYmFzZSAnJ3sxfScnLgotICAgICAgICBuby14bWxucyA9IG5vLXhtbG5zOiBPIHtuYW1lfSBkZSB1bWEgZGVjbGFyYVx1MDBFN1x1MDBFM28gZGUgYXRyaWJ1dG8gblx1MDBFM28gZGV2ZSBjb3JyZXNwb25kZXIgYSAneG1sbnMnLgotICAgICAgICBuby14c2kgPSBuby14c2k6IE8gInsidGFyZ2V0IG5hbWVzcGFjZSJ9IiBkZSB1bWEgZGVjbGFyYVx1MDBFN1x1MDBFM28gZG8gYXRyaWJ1dG8gblx1MDBFM28gZGV2ZSBjb3JyZXNwb25kZXIgYSAnJ3swfScnLgotICAgICAgICBwLXByb3BzLWNvcnJlY3QuMi4xID0gcC1wcm9wcy1jb3JyZWN0LjIuMTogTmEgZGVjbGFyYVx1MDBFN1x1MDBFM28gZGUgJyd7MH0nJywgbyB2YWxvciBkZSAnJ21pbk9jY3VycycnIFx1MDBFOSAnJ3sxfScnLCBtYXMgblx1MDBFM28gZGV2ZSBzZXIgbWFpb3IgcXVlIG8gdmFsb3IgZGUgJydtYXhPY2N1cnMnJywgcXVlIFx1MDBFOSAnJ3syfScnLgotICAgICAgICByY2FzZS1NYXBBbmRTdW0uMSA9IHJjYXNlLU1hcEFuZFN1bS4xOiBOXHUwMEUzbyBoXHUwMEUxIHVtIG1hcGVhbWVudG8gZnVuY2lvbmFsIGNvbXBsZXRvIGVudHJlIGFzIHBhcnRcdTAwRURjdWxhcy4KLSAgICAgICAgcmNhc2UtTWFwQW5kU3VtLjIgPSByY2FzZS1NYXBBbmRTdW0uMjogQSBmYWl4YSBkZSBvY29yclx1MDBFQW5jaWEgZG8gZ3J1cG8sICh7MH0sezF9KSwgblx1MDBFM28gXHUwMEU5IHVtYSByZXN0cmlcdTAwRTdcdTAwRTNvIHZcdTAwRTFsaWRhIGRhIGZhaXhhIGRlIG9jb3JyXHUwMEVBbmNpYSBkbyBncnVwbyBiYXNlLCAoezJ9LHszfSkuCi0gICAgICAgIHJjYXNlLU5hbWVBbmRUeXBlT0suMSA9IHJjYXNlLU5hbWVBbmRUeXBlT0suMTogT3MgZWxlbWVudG9zIHRcdTAwRUFtIG5vbWVzIGUgbmFtZXNwYWNlcyBkZSBkZXN0aW5vIHF1ZSBuXHUwMEUzbyBzXHUwMEUzbyBpZ3VhaXM6IEVsZW1lbnRvICcnezB9Jycgbm8gbmFtZXNwYWNlICcnezF9JycgZSBlbGVtZW50byAnJ3syfScnIG5vIG5hbWVzcGFjZSAnJ3szfScnLgotICAgICAgICByY2FzZS1OYW1lQW5kVHlwZU9LLjIgPSByY2FzZS1OYW1lQW5kVHlwZU9LLjI6IEVycm8gZGEgcGFydFx1MDBFRGN1bGEgY3VqbyAieyJ0ZXJtIn0iIFx1MDBFOSBhIGRlY2xhcmFcdTAwRTdcdTAwRTNvIGRvIGVsZW1lbnRvICcnezB9JycuIE8gInsibmlsbGFibGUifSIgZGEgZGVjbGFyYVx1MDBFN1x1MDBFM28gZG8gZWxlbWVudG8gXHUwMEU5IHZlcmRhZGVpcm8sIG1hcyBhIHBhcnRcdTAwRURjdWxhIGNvcnJlc3BvbmRlbnRlIG5vIHRpcG8gZGUgYmFzZSB0ZW0gdW1hIGRlY2xhcmFcdTAwRTdcdTAwRTNvIGRlIGVsZW1lbnRvIGN1am8gInsibmlsbGFibGUifSIgXHUwMEU5IGZhbHNvLgotICAgICAgICByY2FzZS1OYW1lQW5kVHlwZU9LLjMgPSByY2FzZS1OYW1lQW5kVHlwZU9LLjM6IEVycm8gZGEgcGFydFx1MDBFRGN1bGEgY3VqbyAieyJ0ZXJtIn0iIFx1MDBFOSBhIGRlY2xhcmFcdTAwRTdcdTAwRTNvIGRvIGVsZW1lbnRvICcnezB9JycuIFN1YSBmYWl4YSBkZSBvY29yclx1MDBFQW5jaWEsICh7MX0sezJ9KSBuXHUwMEUzbyBcdTAwRTkgdW1hIHJlc3RyaVx1MDBFN1x1MDBFM28gdlx1MDBFMWxpZGEgZGEgZmFpeGEsICh7M30sezR9IGRhIHBhcnRcdTAwRURjdWxhIGNvcnJlc3BvbmRlbnRlIG5vIHRpcG8gZGUgYmFzZS4KLSAgICAgICAgcmNhc2UtTmFtZUFuZFR5cGVPSy40LmEgPSByY2FzZS1OYW1lQW5kVHlwZU9LLjQuYTogTyBlbGVtZW50byAnJ3swfScnIG5cdTAwRTNvIGVzdFx1MDBFMSBmaXhhZG8sIG1hcyBvIGVsZW1lbnRvIGNvcnJlc3BvbmRlbnRlIG5vIHRpcG8gZGUgYmFzZSBlc3RcdTAwRTEgZml4YWRvIGNvbSBvIHZhbG9yICcnezF9JycuCi0gICAgICAgIHJjYXNlLU5hbWVBbmRUeXBlT0suNC5iID0gcmNhc2UtTmFtZUFuZFR5cGVPSy40LmI6IE8gZWxlbWVudG8gJyd7MH0nJyBlc3RcdTAwRTEgZml4YWRvIGNvbSBvIHZhbG9yICcnezF9JycsIG1hcyBvIGVsZW1lbnRvIGNvcnJlc3BvbmRlbnRlIG5vIHRpcG8gZGUgYmFzZSBlc3RcdTAwRTEgZml4YWRvIGNvbSBvIHZhbG9yICcnezJ9JycuCi0gICAgICAgIHJjYXNlLU5hbWVBbmRUeXBlT0suNSA9IHJjYXNlLU5hbWVBbmRUeXBlT0suNTogUmVzdHJpXHUwMEU3XHUwMEY1ZXMgZGUgaWRlbnRpZGFkZSBkbyBlbGVtZW50byAnJ3swfScnIG5cdTAwRTNvIHNcdTAwRTNvIHN1YmNvbmp1bnRvcyBkYXF1ZWxhcyBkYSBiYXNlLgotICAgICAgICByY2FzZS1OYW1lQW5kVHlwZU9LLjYgPSByY2FzZS1OYW1lQW5kVHlwZU9LLjY6IEFzIHN1YnN0aXR1aVx1MDBFN1x1MDBGNWVzIG5cdTAwRTNvIHBlcm1pdGlkYXMgZG8gZWxlbWVudG8gJyd7MH0nJyBuXHUwMEUzbyBzXHUwMEUzbyB1bSBzdXBlcmNvbmp1bnRvIGRhcXVlbGFzIGRhIGJhc2UuCi0gICAgICAgIHJjYXNlLU5hbWVBbmRUeXBlT0suNyA9IHJjYXNlLU5hbWVBbmRUeXBlT0suNzogTyB0aXBvIGRlIGVsZW1lbnRvICcnezB9JycsICcnezF9Jycgblx1MDBFM28gXHUwMEU5IG9idGlkbyBkbyB0aXBvIGRlIGVsZW1lbnRvIGJhc2UgJyd7Mn0nJy4KLSAgICAgICAgcmNhc2UtTlNDb21wYXQuMSA9IHJjYXNlLU5TQ29tcGF0LjE6IE8gZWxlbWVudG8gJyd7MH0nJyB0ZW0gdW0gbmFtZXNwYWNlICcnezF9JycgcXVlIG5cdTAwRTNvIFx1MDBFOSBwZXJtaXRpZG8gcGVsbyBjdXJpbmdhIG5hIGJhc2UuCi0gICAgICAgIHJjYXNlLU5TQ29tcGF0LjIgPSByY2FzZS1OU0NvbXBhdC4yOiBFcnJvIGRhIHBhcnRcdTAwRURjdWxhIGN1am8gInsidGVybSJ9IiBcdTAwRTkgYSBkZWNsYXJhXHUwMEU3XHUwMEUzbyBkbyBlbGVtZW50byAnJ3swfScnLiBTdWEgZmFpeGEgZGUgb2NvcnJcdTAwRUFuY2lhLCAoezF9LHsyfSksIG5cdTAwRTNvIFx1MDBFOSB1bWEgcmVzdHJpXHUwMEU3XHUwMEUzbyB2XHUwMEUxbGlkYSBkYSBmYWl4YSwgKHszfSx7NH0sIGRhIHBhcnRcdTAwRURjdWxhIGNvcnJlc3BvbmRlbnRlIG5vIHRpcG8gZGUgYmFzZS4KLSAgICAgICAgcmNhc2UtTlNSZWN1cnNlQ2hlY2tDYXJkaW5hbGl0eS4xID0gcmNhc2UtTlNSZWN1cnNlQ2hlY2tDYXJkaW5hbGl0eS4xOiBOXHUwMEUzbyBoXHUwMEUxIHVtIG1hcGVhbWVudG8gZnVuY2lvbmFsIGNvbXBsZXRvIGVudHJlIGFzIHBhcnRcdTAwRURjdWxhcy4KLSAgICAgICAgcmNhc2UtTlNSZWN1cnNlQ2hlY2tDYXJkaW5hbGl0eS4yID0gcmNhc2UtTlNSZWN1cnNlQ2hlY2tDYXJkaW5hbGl0eS4yOiBBIGZhaXhhIGRlIG9jb3JyXHUwMEVBbmNpYXMgZG8gZ3J1cG8sICh7MH0sezF9KSwgblx1MDBFM28gXHUwMEU5IHVtYSByZXN0cmlcdTAwRTdcdTAwRTNvIHZcdTAwRTFsaWRhIGRhIGZhaXhhIGRlIGN1cmluZ2FzIGJhc2UsICh7Mn0sezN9KS4KLSAgICAgICAgcmNhc2UtTlNTdWJzZXQuMSA9IHJjYXNlLU5TU3Vic2V0LjE6IEN1cmluZ2Egblx1MDBFM28gXHUwMEU5IHVtIHN1YmNvbmp1bnRvIGRlIGN1cmluZ2FzIGNvcnJlc3BvbmRlbnRlIG5hIGJhc2UuCi0gICAgICAgIHJjYXNlLU5TU3Vic2V0LjIgPSByY2FzZS1OU1N1YnNldC4yOiBBIGZhaXhhIGRlIG9jb3JyXHUwMEVBbmNpYXMgZGUgY3VyaW5nYSwgKHswfSx7MX0pLCBuXHUwMEUzbyBcdTAwRTkgdW1hIHJlc3RyaVx1MDBFN1x1MDBFM28gdlx1MDBFMWxpZGEgZGFxdWVsYSBkYSBiYXNlLCAoezJ9LHszfSksLgotICAgICAgICByY2FzZS1OU1N1YnNldC4zID0gcmNhc2UtTlNTdWJzZXQuMzogTyBjb250ZVx1MDBGQWRvIGRvIHByb2Nlc3NvIGRvIGN1cmluZ2EsICcnezB9JycsIFx1MDBFOSBtYWlzIGZyYWNvIHF1ZSBhcXVlbGUgZGEgYmFzZSwgJyd7MX0nJy4KLSAgICAgICAgcmNhc2UtUmVjdXJzZS4xID0gcmNhc2UtUmVjdXJzZS4xOiBBIGZhaXhhIGRlIG9jb3JyXHUwMEVBbmNpYSBkbyBncnVwbywgKHswfSx7MX0pLCBuXHUwMEUzbyBcdTAwRTkgdW1hIHJlc3RyaVx1MDBFN1x1MDBFM28gdlx1MDBFMWxpZGEgZGEgZmFpeGEgZGUgb2NvcnJcdTAwRUFuY2lhIGRvIGdydXBvIGJhc2UsICh7Mn0sezN9KS4KLSAgICAgICAgcmNhc2UtUmVjdXJzZS4yID0gcmNhc2UtUmVjdXJzZS4yOiBOXHUwMEUzbyBoXHUwMEUxIHVtIG1hcGVhbWVudG8gZnVuY2lvbmFsIGNvbXBsZXRvIGVudHJlIGFzIHBhcnRcdTAwRURjdWxhcy4KLSAgICAgICAgcmNhc2UtUmVjdXJzZUxheC4xID0gcmNhc2UtUmVjdXJzZUxheC4xOiBBIGZhaXhhIGRlIG9jb3JyXHUwMEVBbmNpYXMgZG8gZ3J1cG8sICh7MH0sezF9KSwgblx1MDBFM28gXHUwMEU5IHVtYSByZXN0cmlcdTAwRTdcdTAwRTNvIHZcdTAwRTFsaWRhIGRhIGZhaXhhIGRlIG9jb3JyXHUwMEVBbmNpYXMgZG8gZ3J1cG8gYmFzZSwgKHsyfSx7M30pLgotICAgICAgICByY2FzZS1SZWN1cnNlTGF4LjIgPSByY2FzZS1SZWN1cnNlTGF4LjI6IE5cdTAwRTNvIGhcdTAwRTEgdW0gbWFwZWFtZW50byBmdW5jaW9uYWwgY29tcGxldG8gZW50cmUgYXMgcGFydFx1MDBFRGN1bGFzLgotICAgICAgICByY2FzZS1SZWN1cnNlVW5vcmRlcmVkLjEgPSByY2FzZS1SZWN1cnNlVW5vcmRlcmVkLjE6IEEgZmFpeGEgZGUgb2NvcnJcdTAwRUFuY2lhcyBkbyBncnVwbywgKHswfSx7MX0pLCBuXHUwMEUzbyBcdTAwRTkgdW1hIHJlc3RyaVx1MDBFN1x1MDBFM28gdlx1MDBFMWxpZGEgZGEgZmFpeGEgZGUgb2NvcnJcdTAwRUFuY2lhcyBkbyBncnVwbyBiYXNlLCAoezJ9LHszfSkuCi0gICAgICAgIHJjYXNlLVJlY3Vyc2VVbm9yZGVyZWQuMiA9IHJjYXNlLVJlY3Vyc2VVbm9yZGVyZWQuMjogTlx1MDBFM28gaFx1MDBFMSB1bSBtYXBlYW1lbnRvIGZ1bmNpb25hbCBjb21wbGV0byBlbnRyZSBhcyBwYXJ0XHUwMEVEY3VsYXMuCi0jICAgICAgICBXZSdyZSB1c2luZyBzY2gtcHJvcHMtY29ycmVjdC4yIGluc3RlYWQgb2YgdGhlIG9sZCBzcmMtcmVkZWZpbmUuMQotIyAgICAgICAgc3JjLXJlZGVmaW5lLjEgPSBzcmMtcmVkZWZpbmUuMTogVGhlIGNvbXBvbmVudCAnJ3swfScnIGlzIGJlZ2luIHJlZGVmaW5lZCwgYnV0IGl0cyBjb3JyZXNwb25kaW5nIGNvbXBvbmVudCBpc24ndCBpbiB0aGUgc2NoZW1hIGRvY3VtZW50IGJlaW5nIHJlZGVmaW5lZCAod2l0aCBuYW1lc3BhY2UgJyd7Mn0nJyksIGJ1dCBpbiBhIGRpZmZlcmVudCBkb2N1bWVudCwgd2l0aCBuYW1lc3BhY2UgJyd7MX0nJy4KLSAgICAgICAgc2NoLXByb3BzLWNvcnJlY3QuMiA9IHNjaC1wcm9wcy1jb3JyZWN0LjI6IFVtIGVzcXVlbWEgblx1MDBFM28gcG9kZSBjb250ZXIgZG9pcyBjb21wb25lbnRlcyBnbG9iYWlzIGNvbSBvIG1lc21vIG5vbWU7IGVzdGUgZXNxdWVtYSBjb250XHUwMEU5bSBkdWFzIG9jb3JyXHUwMEVBbmNpYXMgZGUgJyd7MH0nJy4KLSAgICAgICAgc3QtcHJvcHMtY29ycmVjdC4yID0gc3QtcHJvcHMtY29ycmVjdC4yOiBEZWZpbmlcdTAwRTdcdTAwRjVlcyBjaXJjdWxhcmVzIGRldGVjdGFkYXMgcGFyYSBvIHRpcG8gc2ltcGxlcyB7MH0nJy4gSXNzbyBzaWduaWZpY2EgcXVlICcnezB9JycgZXN0XHUwMEUxIGNvbnRpZG8gZW0gc3VhIHByXHUwMEYzcHJpYSBoaWVyYXJxdWlhIGRlIHRpcG8sIG8gcXVlIFx1MDBFOSB1bSBlcnJvLgotICAgICAgICBzdC1wcm9wcy1jb3JyZWN0LjMgPSBzdC1wcm9wcy1jb3JyZWN0LjM6IEVycm8gZG8gdGlwbyAnJ3swfScnLiBPIHZhbG9yIGRlICd7J2ZpbmFsJ30nIGRhICd7J2Jhc2UgdHlwZSBkZWZpbml0aW9uJ30nLCAnJ3sxfScnLCBwcm9cdTAwRURiZSBhIG9idGVuXHUwMEU3XHUwMEUzbyBwb3IgcmVzdHJpXHUwMEU3XHUwMEUzby4KLSAgICAgICAgdG90YWxEaWdpdHMtdmFsaWQtcmVzdHJpY3Rpb24gPSB0b3RhbERpZ2l0cy12YWxpZC1yZXN0cmljdGlvbjogTmEgZGVmaW5pXHUwMEU3XHUwMEUzbyBkZSB7Mn0sIG8gdmFsb3IgJyd7MH0nJyBkbyAidG90YWxEaWdpdHMiJycgZG8gYXNwZWN0byBcdTAwRTkgaW52XHUwMEUxbGlkbyBwb3JxdWUgZWxlIGRldmUgc2VyIDw9IGFvIHZhbG9yIGRlICcndG90YWxEaWdpdHMiLCBxdWUgZm9pIGRlZmluaWRvIGNvbW8gJyd7MX0nJyBlbSB1bSBkb3MgdGlwb3MgZGUgYW5jZXN0cmFpcy4KLSAgICAgICAgd2hpdGVTcGFjZS12YWxpZC1yZXN0cmljdGlvbi4xID0gd2hpdGVTcGFjZS12YWxpZC1yZXN0cmljdGlvbi4xOiBOYSBkZWZpbmlcdTAwRTdcdTAwRTNvIGRlIHswfSwgbyB2YWxvciAnJ3sxfScnIGRvIGFzcGVjdG8gJyd3aGl0ZXNwYWNlJycgXHUwMEU5IGludlx1MDBFMWxpZG8gcG9ycXVlIG8gdmFsb3IgcGFyYSAnJ3doaXRlc3BhY2UnJyBmb2kgZGVmaW5pZG8gY29tbyAnJ2NvbGFwc2UnJyBlbSB1bSBkb3MgdGlwb3MgZGUgYW5jZXN0cmFpcy4KLSAgICAgICAgd2hpdGVTcGFjZS12YWxpZC1yZXN0cmljdGlvbi4yID0gd2hpdGVTcGFjZS12YWxpZC1yZXN0cmljdGlvbi4yOiBOYSBkZWZpbmlcdTAwRTdcdTAwRTNvIGRlIHswfSwgbyB2YWxvciBkbyBhc3BlY3RvICcncHJlc2VydmUnJyBcdTAwRTkgaW52XHUwMEUxbGlkbyBwYXJhIG8gYXNwZWN0byAid2hpdGVzcGFjZSIgcG9ycXVlIG8gdmFsb3IgcGFyYSAnJ3doaXRlc3BhY2UnJyBmb2kgZGVmaW5pZG8gY29tbyAnJ3JlcGxhY2UnJyBlbSB1bSBkb3MgdGlwb3MgZGUgYW5jZXN0cmFpcy4KLQotI3NjaGVtYSBmb3IgU2NoZW1hcwotCi0gICAgICAgIHM0cy1hdHQtaW52YWxpZC12YWx1ZSA9IHM0cy1hdHQtaW52YWxpZC12YWx1ZTogVmFsb3IgZGUgYXRyaWJ1dG8gaW52XHUwMEUxbGlkbyBwYXJhICcnezF9Jycgbm8gZWxlbWVudG8nJ3swfScnLiBNb3Rpdm8gZ3JhdmFkbzogezJ9Ci0gICAgICAgIHM0cy1hdHQtbXVzdC1hcHBlYXIgPSBzNHMtYXR0LW11c3QtYXBwZWFyOiBPIGF0cmlidXRvICcnezF9JycgZGV2ZSBhcGFyZWNlciBubyBlbGVtZW50byAnJ3swfScnLgotICAgICAgICBzNHMtYXR0LW5vdC1hbGxvd2VkID0gczRzLWF0dC1ub3QtYWxsb3dlZDogTyBhdHJpYnV0byAnJ3sxfScnIG5cdTAwRTNvIHBvZGUgYXBhcmVjZXIgbm8gZWxlbWVudG8gJyd7MH0nJy4KLSAgICAgICAgczRzLWVsdC1pbnZhbGlkID0gczRzLWVsdC1pbnZhbGlkOiBPIGVsZW1lbnRvICcnezB9Jycgblx1MDBFM28gXHUwMEU5IHVtIGVsZW1lbnRvIHZcdTAwRTFsaWRvIGVtIHVtIGRvY3VtZW50byBkbyBlc3F1ZW1hLgotICAgICAgICBzNHMtZWx0LW11c3QtbWF0Y2guMSA9IHM0cy1lbHQtbXVzdC1tYXRjaC4xOiBPIGNvbnRlXHUwMEZBZG8gZGUgJyd7MH0nJyBkZXZlIGNvcnJlc3BvbmRlciBhIHsxfS4gRm9pIGRldGVjdGFkbyB1bSBwcm9ibGVtYSBjb21lXHUwMEU3YW5kbyBlbTogezJ9LgotICAgICAgICBzNHMtZWx0LW11c3QtbWF0Y2guMiA9IHM0cy1lbHQtbXVzdC1tYXRjaC4yOiBPIGNvbnRlXHUwMEZBZG8gZGUgJyd7MH0nJyBkZXZlIGNvcnJlc3BvbmRlciBhIHsxfS4gTlx1MDBFM28gZm9yYW0gZW5jb250cmFkb3MgZWxlbWVudG9zIHN1ZmljaWVudGVzLgotICAgICAgICAjIHRoZSAiaW52YWxpZC1jb250ZW50IiBtZXNzYWdlcyBwcm92aWRlIGxlc3MgaW5mb3JtYXRpb24gdGhhbiB0aGUgIm11c3QtbWF0Y2giIGNvdW50ZXJwYXJ0cyBhYm92ZS4gVGhleSdyZSB1c2VkIGZvciBjb21wbGV4IHR5cGVzIHdoZW4gcHJvdmlkaW5nIGEgIm1hdGNoIiB3b3VsZCBiZSBhbiBpbmZvcm1hdGlvbiBkdW1wCi0gICAgICAgIHM0cy1lbHQtaW52YWxpZC1jb250ZW50LjEgPSBzNHMtZWx0LWludmFsaWQtY29udGVudC4xOiBPIGNvbnRlXHUwMEZBZG8gZGUgJyd7MH0nJyBcdTAwRTkgaW52XHUwMEUxbGlkby4gTyBlbGVtZW50byAnJ3sxfScnIFx1MDBFOSBpbnZcdTAwRTFsaWRvLCBtYWwgcG9zaWNpb25hZG8gb3Ugb2NvcnJlIGNvbSBtdWl0YSBmcmVxdVx1MDBFQW5jaWEuCi0gICAgICAgIHM0cy1lbHQtaW52YWxpZC1jb250ZW50LjIgPSBzNHMtZWx0LWludmFsaWQtY29udGVudC4yOiBPIGNvbnRlXHUwMEZBZG8gZGUgJyd7MH0nJyBcdTAwRTkgaW52XHUwMEUxbGlkby4gTyBlbGVtZW50byAnJ3sxfScnIG5cdTAwRTNvIHBvZGUgZmljYXIgdmF6aW8uCi0gICAgICAgIHM0cy1lbHQtaW52YWxpZC1jb250ZW50LjMgPSBzNHMtZWx0LWludmFsaWQtY29udGVudC4zOiBPcyBlbGVtZW50b3MgZG8gdGlwbyAnJ3swfScnIG5cdTAwRTNvIHBvZGVtIGFwYXJlY2VyIGFwXHUwMEYzcyBhcyBkZWNsYXJhXHUwMEU3XHUwMEY1ZXMgY29tbyBmaWxob3MgZGUgdW0gZWxlbWVudG8gZGUgPHNjaGVtYT4uCi0gICAgICAgIHM0cy1lbHQtc2NoZW1hLW5zID0gczRzLWVsdC1zY2hlbWEtbnM6IE8gbmFtZXNwYWNlIGRvIGVsZW1lbnRvICcnezB9JycgZGV2ZSBzZXIgZG8gbmFtZXNwYWNlIGRvIGVzcXVlbWEsICcnaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEnJy4KLSAgICAgICAgczRzLWVsdC1jaGFyYWN0ZXIgPSBzNHMtZWx0LWNoYXJhY3RlcjogTlx1MDBFM28gc1x1MDBFM28gcGVybWl0aWRvcyBjYXJhY3RlcmVzIHNlbSBlc3BhXHUwMEU3byBlbSBicmFuY28gbm9zIGVsZW1lbnRvcyBkbyBlc3F1ZW1hIGRpZmVyZW50ZXMgZGUgJyd4czphcHBpbmZvJycgZSAnJ3hzOmRvY3VtZW50YXRpb24nJy4gVmVyaWZpY2FkbyAnJ3swfScnLgotCi0jIGNvZGVzIG5vdCBkZWZpbmVkIGJ5IHRoZSBzcGVjCi0KLSAgICAgICAgYy1maWVsZHMteHBhdGhzID0gYy1maWVsZHMteHBhdGhzOiBPIHZhbG9yIGRvIGNhbXBvID0gJyd7MH0nJyBuXHUwMEUzbyBcdTAwRTkgdlx1MDBFMWxpZG8uCi0gICAgICAgIGMtZ2VuZXJhbC14cGF0aCA9IGMtZ2VuZXJhbC14cGF0aDogQSBleHByZXNzXHUwMEUzbyAnJ3swfScnIG5cdTAwRTNvIFx1MDBFOSB2XHUwMEUxbGlkYSBlbSByZWxhXHUwMEU3XHUwMEUzbyBhbyBzdWJjb25qdW50byBkZSBYUGF0aCBzdXBvcnRhZG8gcGVsbyBFc3F1ZW1hIFhNTC4KLSAgICAgICAgYy1nZW5lcmFsLXhwYXRoLW5zID0gYy1nZW5lcmFsLXhwYXRoLW5zOiBVbSBwcmVmaXhvIGRlIG5hbWVzcGFjZSBuYSBleHByZXNzXHUwMEUzbyBkZSBYUGF0aCAnJ3swfScnIG5cdTAwRTNvIGZvaSBhc3NvY2lhZG8gYSB1bSBuYW1lc3BhY2UuCi0gICAgICAgIGMtc2VsZWN0b3IteHBhdGggPSBjLXNlbGVjdG9yLXhwYXRoOiBPIHZhbG9yIGRvIHNlbGV0b3IgPSAnJ3swfScnIG5cdTAwRTNvIFx1MDBFOSB2XHUwMEUxbGlkbzsgb3MgeHBhdGhzIGRvIHNlbGV0b3Igblx1MDBFM28gcG9kZW0gY29udGVyIGF0cmlidXRvcy4KLSAgICAgICAgRW1wdHlUYXJnZXROYW1lc3BhY2UgPSBFbXB0eVRhcmdldE5hbWVzcGFjZTogTm8gZG9jdW1lbnRvIGRvIGVzcXVlbWEgJyd7MH0nJywgbyB2YWxvciBkbyBhdHJpYnV0byAnJ3RhcmdldE5hbWVzcGFjZScnIG5cdTAwRTNvIHBvZGUgc2VyIHVtYSBzdHJpbmcgdmF6aWEuCi0gICAgICAgIEZhY2V0VmFsdWVGcm9tQmFzZSA9IEZhY2V0VmFsdWVGcm9tQmFzZTogTmEgZGVjbGFyYVx1MDBFN1x1MDBFM28gZG8gdGlwbyAnJ3swfScnLCBvIHZhbG9yICcnezF9JycgZG8gYXNwZWN0byAnJ3syfScnIGRldmUgc2VyIHByb3ZlbmllbnRlIGRvIGVzcGFcdTAwRTdvIGRlIHZhbG9yIGRvIHRpcG8gZGUgYmFzZSwgJyd7M30nJy4KLSAgICAgICAgRml4ZWRGYWNldFZhbHVlID0gRml4ZWRGYWNldFZhbHVlOiBOYSBkZWZpbmlcdTAwRTdcdTAwRTNvIGRlIHszfSwgbyB2YWxvciAnJ3sxfScnIGRvIGFzcGVjdG8gJyd7MH0nJyBcdTAwRTkgaW52XHUwMEUxbGlkbyBwb3JxdWUgbyB2YWxvciBkZSAnJ3swfScnIGZvaSBlbnZpYWRvIHBhcmEgJyd7Mn0nJyBlbSB1bSBkb3MgdGlwb3MgZGUgYW5jZXN0cmFpcyBlICd7J2ZpeGVkJ30nID0gdHJ1ZS4KLSAgICAgICAgSW52YWxpZFJlZ2V4ID0gSW52YWxpZFJlZ2V4OiBPIHZhbG9yIGRvIHBhZHJcdTAwRTNvICcnezB9Jycgblx1MDBFM28gXHUwMEU5IHVtYSBleHByZXNzXHUwMEUzbyByZWd1bGFyIHZcdTAwRTFsaWRhLiBPIGVycm8gcmVwb3J0YWRvIGZvaTogJyd7MX0nJyBuYSBjb2x1bmEgJyd7Mn0nJy4KLSAgICAgICAgTWF4T2NjdXJMaW1pdCA9IEEgY29uZmlndXJhXHUwMEU3XHUwMEUzbyBhdHVhbCBkbyBwYXJzZXIgblx1MDBFM28gcGVybWl0ZSBxdWUgbyB2YWxvciBkZSB1bSBhdHJpYnV0byBtYXhPY2N1cnMgc2VqYSBkZWZpbmlkbyBjb21vIG1haW9yIHF1ZSBvIHZhbG9yIHswfS4KLSAgICAgICAgUHVibGljU3lzdGVtT25Ob3RhdGlvbiA9IFB1YmxpY1N5c3RlbU9uTm90YXRpb246IFBlbG8gbWVub3MgJydwdWJsaWMnJyBlICcnc3lzdGVtJycgZGV2ZW0gYXBhcmVjZXIgbm8gZWxlbWVudG8gJydub3RhdGlvbicnLgotICAgICAgICBTY2hlbWFMb2NhdGlvbiA9IFNjaGVtYUxvY2F0aW9uOiBzY2hlbWFMb2NhdGlvbiB2YWx1ZSA9ICcnezB9JydkZXZlIHRlciBuXHUwMEZBbWVybyBwYXIgZGUgVVJJcy4KLSAgICAgICAgVGFyZ2V0TmFtZXNwYWNlLjEgPSBUYXJnZXROYW1lc3BhY2UuMTogRXNwZXJhdmEgbyBuYW1lc3BhY2UgJyd7MH0nJywgbWFzIG8gbmFtZXNwYWNlIGRlIGRlc3Rpbm8gZG8gZG9jdW1lbnRvIGRvIGVzcXVlbWEgXHUwMEU5ICcnezF9JycuCi0gICAgICAgIFRhcmdldE5hbWVzcGFjZS4yID0gVGFyZ2V0TmFtZXNwYWNlLjI6IEV4Y2V0byBubyBuYW1lc3BhY2UsIG1hcyBvIGRvY3VtZW50byBkbyBlc3F1ZW1hIHRlbSB1bSBuYW1lc3BhY2UgZGUgZGVzdGlubyAnJ3sxfScnLgotICAgICAgICBVbmRlY2xhcmVkRW50aXR5ID0gVW5kZWNsYXJlZEVudGl0eTogQSBlbnRpZGFkZSAnJ3swfScnIG5cdTAwRTNvIGZvaSBkZWNsYXJhZGEuCi0gICAgICAgIFVuZGVjbGFyZWRQcmVmaXggPSBVbmRlY2xhcmVkUHJlZml4OiBOXHUwMEUzbyBcdTAwRTkgcG9zc1x1MDBFRHZlbCByZXNvbHZlciAnJ3swfScnIGNvbW8gdW0gUU5hbWU6IG8gcHJlZml4byAnJ3sxfScnIG5cdTAwRTNvIGZvaSBkZWNsYXJhZG8uCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9YTUxTY2hlbWFNZXNzYWdlc19zdi5wcm9wZXJ0aWVzIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MU2NoZW1hTWVzc2FnZXNfc3YucHJvcGVydGllcwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZmZlOWQ3OS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9YTUxTY2hlbWFNZXNzYWdlc19zdi5wcm9wZXJ0aWVzCisrKyAvZGV2L251bGwKQEAgLTEsMjkxICswLDAgQEAKLSMgVGhpcyBmaWxlIGNvbnRhaW5zIGVycm9yIGFuZCB3YXJuaW5nIG1lc3NhZ2VzIHJlbGF0ZWQgdG8gWE1MIFNjaGVtYQotIyBUaGUgbWVzc2FnZXMgYXJlIGFycmFuZ2VkIGluIGtleSBhbmQgdmFsdWUgdHVwbGVzIGluIGEgTGlzdFJlc291cmNlQnVuZGxlLgotIwotCi0gICAgICAgIEJhZE1lc3NhZ2VLZXkgPSBIaXR0YXIgaW50ZSBmZWxtZWRkZWxhbmRldCBzb20gbW90c3ZhcmFyIG1lZGRlbGFuZGVueWNrZWxuLgotICAgICAgICBGb3JtYXRGYWlsZWQgPSBFdHQgaW50ZXJudCBmZWwgaW50clx1MDBFNGZmYWRlIHZpZCBmb3JtYXRlcmluZyBhdiBmXHUwMEY2bGphbmRlIG1lZGRlbGFuZGU6XG4KLQotIyBGb3IgaW50ZXJuYWwgdXNlCi0KLSAgICAgICAgSW50ZXJuYWwtRXJyb3IgPSBJbnRlcm50IGZlbDogezB9LgotICAgICAgICBkdC13aGl0ZXNwYWNlID0gQXNwZWt0dlx1MDBFNHJkZSBmXHUwMEY2ciBibGFua3RlY2tlbiBcdTAwRTRyIGludGUgdGlsbGdcdTAwRTRuZ2xpZ3QgZlx1MDBGNnIgc2ltcGxlVHlwZSAnJ3swfScnIG1lZCB1bmlvbgotICAgICAgICBHcmFtbWFyQ29uZmxpY3QgPSBHZW5lcmVyYWQgZ3JhbW1hdGlrIGZyXHUwMEU1biBhbnZcdTAwRTRuZGFyZW5zIGdyYW1tYXRpa3Bvb2wgc3RyaWRlciBtb3QgYW5uYW4gZ3JhbW1hdGlrLgotCi0jIElkZW50aXR5IGNvbnN0cmFpbnRzCi0KLSAgICAgICAgQWJzZW50S2V5VmFsdWUgPSBGZWwgdmlkIGlkLWJlZ3JcdTAwRTRuc25pbmcgKGN2Yy1pZGVudGl0eS1jb25zdHJhaW50LjQuMi4xKTogZWxlbWVudGV0ICJ7MH0iIGhhciBlbiBueWNrZWwgc29tIHNha25hciB2XHUwMEU0cmRlLgotICAgICAgICBEdXBsaWNhdGVGaWVsZCA9IER1YmJsZXR0bWF0Y2huaW5nIGlub20gb21mYXR0bmluZ2VuIGF2IGZcdTAwRTRsdGV0ICJ7MH0iLgotICAgICAgICBEdXBsaWNhdGVLZXkgPSBEdXBsaWNlcmF0IG55Y2tlbHZcdTAwRTRyZGUgW3swfV0gaGFyIGRla2xhcmVyYXRzIGZcdTAwRjZyIGlkLWJlZ3JcdTAwRTRuc25pbmcgYXYgZWxlbWVudGV0ICJ7MX0iLgotICAgICAgICBEdXBsaWNhdGVVbmlxdWUgPSBEdXBsaWNlcmF0IHVuaWt0IHZcdTAwRTRyZGUgW3swfV0gaGFyIGRla2xhcmVyYXRzIGZcdTAwRjZyIGlkLWJlZ3JcdTAwRTRuc25pbmcgYXYgZWxlbWVudGV0ICJ7MX0iLgotICAgICAgICBGaWVsZE11bHRpcGxlTWF0Y2ggPSBGZWwgdmlkIGlkLWJlZ3JcdTAwRTRuc25pbmc6IGZcdTAwRTRsdGV0ICJ7MH0iIG1hdGNoYXIgZmxlciBcdTAwRTRuIGV0dCB2XHUwMEU0cmRlIGlub20gb21mYXR0bmluZ2VuIGF2IHZcdTAwRTRsamFyZW47IGZcdTAwRTRsdCBtXHUwMEU1c3RlIG1hdGNoYSB1bmlrYSB2XHUwMEU0cmRlbi4KLSAgICAgICAgRml4ZWREaWZmZXJzRnJvbUFjdHVhbCA9IEVsZW1lbnRldHMgaW5uZWhcdTAwRTVsbCBtb3RzdmFyYXIgaW50ZSB2XHUwMEU0cmRldCBhdiBhdHRyaWJ1dGV0IHNvbSBhbmdlcyBzb20gImZpeGVkIiBpIGVsZW1lbnRkZWtsYXJhdGlvbmVuIGkgc2NoZW1hdC4KLSAgICAgICAgS2V5TWF0Y2hlc05pbGxhYmxlID0gRmVsIHZpZCBpZC1iZWdyXHUwMEU0bnNuaW5nIChjdmMtaWRlbnRpdHktY29uc3RyYWludC40LjIuMyk6IGVsZW1lbnRldCAiezB9IiBoYXIgZW4gbnlja2VsIHNvbSBtYXRjaGFyIGV0dCBlbGVtZW50IG1lZCBudWxsYmFydCB2XHUwMEU0cmRlIGFuZ2l2ZXQgc29tIHRydWUuCi0gICAgICAgIEtleU5vdEVub3VnaFZhbHVlcyA9IERldCBmaW5ucyBpbnRlIHRpbGxyXHUwMEU0Y2tsaWd0IG1cdTAwRTVuZ2Egdlx1MDBFNHJkZW4gYW5naXZuYSBmXHUwMEY2ciA8a2V5IG5hbWU9InsxfSI+IHNvbSBpZC1iZWdyXHUwMEU0bnNuaW5nIGZcdTAwRjZyIGVsZW1lbnRldCAiezB9Ii4KLSAgICAgICAgS2V5Tm90Rm91bmQgPSBOeWNrZWxuICcnezB9JycgbWVkIHZcdTAwRTRyZGV0ICcnezF9JycgaGl0dGFkZXMgaW50ZSBmXHUwMEY2ciBpZC1iZWdyXHUwMEU0bnNuaW5nIGZcdTAwRjZyIGVsZW1lbnQgJyd7Mn0nJy4KLSAgICAgICAgS2V5UmVmTm90RW5vdWdoVmFsdWVzID0gRGV0IGZpbm5zIGludGUgdGlsbHJcdTAwRTRja2xpZ3QgbVx1MDBFNW5nYSB2XHUwMEU0cmRlbiBhbmdpdm5hIGZcdTAwRjZyIDxrZXlyZWYgbmFtZT0iezF9Ij4gc29tIGlkLWJlZ3JcdTAwRTRuc25pbmcgZlx1MDBGNnIgZWxlbWVudGV0ICJ7MH0iLgotICAgICAgICBLZXlSZWZPdXRPZlNjb3BlID0gRmVsIHZpZCBpZC1iZWdyXHUwMEU0bnNuaW5nOiBpZC1iZWdyXHUwMEU0bnNuaW5nICJ7MH0iIGhhciBlbiBueWNrZWxyZWZlcmVucyBzb20gcmVmZXJlcmFyIHRpbGwgbnlja2VsIGVsbGVyIHVuaWt0IHZcdTAwRTRyZGUgdXRhbmZcdTAwRjZyIGRlZmluaXRpb25zb21yXHUwMEU1ZGV0LgotICAgICAgICBLZXlSZWZSZWZlck5vdEZvdW5kID0gTnlja2VscmVmZXJlbnNkZWtsYXJhdGlvbmVuICJ7MH0iIHJlZmVyZXJhciB0aWxsIG9rXHUwMEU0bmQgbnlja2VsIG1lZCBuYW1uZXQgInsxfSIuCi0gICAgICAgIFVuaXF1ZU5vdEVub3VnaFZhbHVlcyA9IERldCBmaW5ucyBpbnRlIHRpbGxyXHUwMEU0Y2tsaWd0IG1cdTAwRTVuZ2Egdlx1MDBFNHJkZW4gYW5naXZuYSBmXHUwMEY2ciA8dW5pcXVlPiBzb20gaWQtYmVnclx1MDBFNG5zbmluZyBmXHUwMEY2ciBlbGVtZW50ZXQgInswfSIuCi0gICAgICAgIFVua25vd25GaWVsZCA9IEZlbCB2aWQgaW50ZXJuIGlkLWJlZ3JcdTAwRTRuc25pbmc7IG9rXHUwMEU0bnQgZlx1MDBFNGx0ICJ7MH0iLgotCi0jIElkZWFsbHksIHdlIHNob3VsZCBvbmx5IHVzZSB0aGUgZm9sbG93aW5nIGVycm9yIGtleXMsIG5vdCB0aGUgb25lcyB1bmRlcgotIyAiSWRlbnRpdHkgY29uc3RyYWludHMiLiBBbmQgd2Ugc2hvdWxkIGNvdmVyIGFsbCBvZiB0aGUgZm9sbG93aW5nIGVycm9ycy4KLQotI3ZhbGlkYXRpb24gKDMuWC40KQotCi0gICAgICAgIGN2Yy1hdHRyaWJ1dGUuMyA9IGN2Yy1hdHRyaWJ1dGUuMzogVlx1MDBFNHJkZXQgJyd7Mn0nJyBmXHUwMEY2ciBhdHRyaWJ1dGV0ICcnezF9JycgaSBlbGVtZW50ZXQgJyd7MH0nJyBoYXIgb2dpbHRpZyB0eXAsICcnezN9JycuCi0gICAgICAgIGN2Yy1hdHRyaWJ1dGUuNCA9IGN2Yy1hdHRyaWJ1dGUuNDogVlx1MDBFNHJkZXQgJyd7Mn0nJyBmXHUwMEY2ciBhdHRyaWJ1dGV0ICcnezF9JycgaSBlbGVtZW50ZXQgJyd7MH0nJyBoYXIgb2dpbHRpZyBmYXN0ICd7J3ZcdTAwRTRyZGViZWdyXHUwMEU0bnNuaW5nJ30nLiBBdHRyaWJ1dGV0IG1cdTAwRTVzdGUgaGEgdlx1MDBFNHJkZXQgJyd7M30nJy4KLSAgICAgICAgY3ZjLWNvbXBsZXgtdHlwZS4yLjEgPSBjdmMtY29tcGxleC10eXBlLjIuMTogRWxlbWVudGV0ICcnezB9JycgZlx1MDBFNXIgaW50ZSBoYSBbdW5kZXJvcmRuYWRlXSBvYmpla3QgbWVkIHRlY2tlbi0gZWxsZXIgZWxlbWVudGluZm9ybWF0aW9uLCBlZnRlcnNvbSBpbm5laFx1MDBFNWxsc3R5cCBcdTAwRTRyIHRvbXQuCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuMi4yID0gY3ZjLWNvbXBsZXgtdHlwZS4yLjI6IEVsZW1lbnRldCAnJ3swfScnIGZcdTAwRTVyIGludGUgaGEgW3VuZGVyb3JkbmFkZV0gZWxlbWVudCBvY2ggdlx1MDBFNHJkZXQgbVx1MDBFNXN0ZSB2YXJhIGdpbHRpZ3QuCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuMi4zID0gY3ZjLWNvbXBsZXgtdHlwZS4yLjM6IEVsZW1lbnRldCAnJ3swfScnIGZcdTAwRTVyIGludGUgaGEgW3VuZGVyb3JkbmFkZV0gdGVja2VuLCBlZnRlcnNvbSBpbm5laFx1MDBFNWxsc3R5cCBcdTAwRTRyIGVuZGFzdCBlbGVtZW50LgotICAgICAgICBjdmMtY29tcGxleC10eXBlLjIuNC5hID0gY3ZjLWNvbXBsZXgtdHlwZS4yLjQuYTogT2dpbHRpZ3QgaW5uZWhcdTAwRTVsbCBoaXR0YWRlcyBtZWQgYlx1MDBGNnJqYW4gbWVkIGVsZW1lbnRldCAnJ3swfScnLiBOXHUwMEU1Z290IGF2ICcnezF9JycgZlx1MDBGNnJ2XHUwMEU0bnRhcy4KLSAgICAgICAgY3ZjLWNvbXBsZXgtdHlwZS4yLjQuYiA9IGN2Yy1jb21wbGV4LXR5cGUuMi40LmI6IElubmVoXHUwMEU1bGxldCBpIGVsZW1lbnRldCAnJ3swfScnIFx1MDBFNHIgaW50ZSBmdWxsc3RcdTAwRTRuZGlndC4gTlx1MDBFNWdvdCBhdiAnJ3sxfScnIGZcdTAwRjZydlx1MDBFNG50YXMuCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuMi40LmMgPSBjdmMtY29tcGxleC10eXBlLjIuNC5jOiBNYXRjaG5pbmdlbiBhdiBqb2tlcnRlY2tlbiBcdTAwRTRyIHN0cmlrdCwgbWVuIGluZ2VuIGRla2xhcmF0aW9uIGhpdHRhZGVzIGZcdTAwRjZyIGVsZW1lbnRldCAnJ3swfScnLgotICAgICAgICBjdmMtY29tcGxleC10eXBlLjIuNC5kID0gY3ZjLWNvbXBsZXgtdHlwZS4yLjQuZDogT2dpbHRpZ3QgaW5uZWhcdTAwRTVsbCBoaXR0YWRlcyBtZWQgYlx1MDBGNnJqYW4gbWVkIGVsZW1lbnRldCAnJ3swfScnLiBJbmdldCB1bmRlcm9yZG5hdCBlbGVtZW50IGZcdTAwRjZydlx1MDBFNG50YXMgaSBkZXQgaFx1MDBFNHIgc2tlZGV0LgotICAgICAgICBjdmMtY29tcGxleC10eXBlLjIuNC5lID0gY3ZjLWNvbXBsZXgtdHlwZS4yLjQuZDogT2dpbHRpZ3QgaW5uZWhcdTAwRTVsbCBoaXR0YWRlcyBtZWQgYlx1MDBGNnJqYW4gbWVkIGVsZW1lbnRldCAnJ3swfScnLiBEZXQgdW5kZXJvcmRuYWRlIGVsZW1lbnRldCAnJ3sxfScnIGZcdTAwRjZydlx1MDBFNG50YXMgaSBkZXQgaFx1MDBFNHIgc2tlZGV0LgotICAgICAgICBjdmMtY29tcGxleC10eXBlLjMuMSA9IGN2Yy1jb21wbGV4LXR5cGUuMy4xOiBWXHUwMEU0cmRldCAnJ3syfScnIGZcdTAwRjZyIGF0dHJpYnV0ZXQgJyd7MX0nJyBpIGVsZW1lbnRldCAnJ3swfScnIFx1MDBFNHIgaW50ZSBnaWx0aWd0IG1lZCBtb3RzdmFyYW5kZSBhdHRyaWJ1dGFudlx1MDBFNG5kbmluZy4gQXR0cmlidXRldCAnJ3sxfScnIGhhciBkZXQgZmFzdGEgdlx1MDBFNHJkZXQgJyd7M30nJy4KLSAgICAgICAgY3ZjLWNvbXBsZXgtdHlwZS4zLjIuMSA9IGN2Yy1jb21wbGV4LXR5cGUuMy4yLjE6IEVsZW1lbnRldCAnJ3swfScnIHNha25hciBhdHRyaWJ1dGpva2VydGVja2VuIGZcdTAwRjZyIGF0dHJpYnV0ZXQgJyd7MX0nJy4KLSAgICAgICAgY3ZjLWNvbXBsZXgtdHlwZS4zLjIuMiA9IGN2Yy1jb21wbGV4LXR5cGUuMy4yLjI6IEF0dHJpYnV0ZXQgJyd7MX0nJyBcdTAwRTRyIGludGUgdGlsbFx1MDBFNXRldCBpIGVsZW1lbnRldCAnJ3swfScnLgotICAgICAgICBjdmMtY29tcGxleC10eXBlLjQgPSBjdmMtY29tcGxleC10eXBlLjQ6IEF0dHJpYnV0ZXQgJyd7MX0nJyBtXHUwMEU1c3RlIGFuZ2VyIGkgZWxlbWVudGV0ICcnezB9JycuCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuNS4xID0gY3ZjLWNvbXBsZXgtdHlwZS41LjE6IEkgZWxlbWVudGV0ICcnezB9JycgXHUwMEU0ciBhdHRyaWJ1dGV0ICcnezF9JycgZXR0IGpva2VyLWlkLiBKb2tlci1pZCAnJ3syfScnIGZpbm5zIHJlZGFuIG9jaCBlbmRhc3QgZXR0IGlkIGthbiBhbnZcdTAwRTRuZGFzLgotICAgICAgICBjdmMtY29tcGxleC10eXBlLjUuMiA9IGN2Yy1jb21wbGV4LXR5cGUuNS4yOiBJIGVsZW1lbnRldCAnJ3swfScnIFx1MDBFNHIgYXR0cmlidXRldCAnJ3sxfScnIGV0dCBqb2tlci1pZC4gRGV0IGZpbm5zIHJlZGFuIGV0dCBhdHRyaWJ1dCAnJ3syfScnIHNvbSB0YXMgZnJcdTAwRTVuIGlkIGJsYW5kICd7J2F0dHJpYnV0YW52XHUwMEU0bmRuaW5nYXInfScuCi0gICAgICAgIGN2Yy1kYXRhdHlwZS12YWxpZC4xLjIuMSA9IGN2Yy1kYXRhdHlwZS12YWxpZC4xLjIuMTogJyd7MH0nJyBcdTAwRTRyIGludGUgblx1MDBFNWdvdCBnaWx0aWd0IHZcdTAwRTRyZGUgZlx1MDBGNnIgJyd7MX0nJy4KLSAgICAgICAgY3ZjLWRhdGF0eXBlLXZhbGlkLjEuMi4yID0gY3ZjLWRhdGF0eXBlLXZhbGlkLjEuMi4yOiAnJ3swfScnIFx1MDBFNHIgaW50ZSBuXHUwMEU1Z290IGdpbHRpZ3Qgdlx1MDBFNHJkZSBmXHUwMEY2ciBsaXN0dHlwICcnezF9JycuCi0gICAgICAgIGN2Yy1kYXRhdHlwZS12YWxpZC4xLjIuMyA9IGN2Yy1kYXRhdHlwZS12YWxpZC4xLjIuMzogJyd7MH0nJyBcdTAwRTRyIGludGUgblx1MDBFNWdvdCBnaWx0aWd0IHZcdTAwRTRyZGUgZlx1MDBGNnIgdW5pb250eXAgJyd7MX0nJy4KLSAgICAgICAgY3ZjLWVsdC4xID0gY3ZjLWVsdC4xOiBLYW4gaW50ZSBoaXR0YSBkZWtsYXJhdGlvbmVuIGZcdTAwRjZyIGVsZW1lbnRldCAnJ3swfScnLgotICAgICAgICBjdmMtZWx0LjIgPSBjdmMtZWx0LjI6IFZcdTAwRTRyZGV0IGZcdTAwRjZyICd7J2Fic3RyYWt0J30nIGkgZWxlbWVudGRla2xhcmF0aW9uZW4gZlx1MDBGNnIgJyd7MH0nJyBtXHUwMEU1c3RlIGFuZ2VzIHNvbSBmYWxzZS4KLSAgICAgICAgY3ZjLWVsdC4zLjEgPSBjdmMtZWx0LjMuMTogQXR0cmlidXRldCAnJ3sxfScnIGZcdTAwRTVyIGludGUgYW5nZXMgaSBlbGVtZW50ZXQgJyd7MH0nJywgZWZ0ZXJzb20gJ3snbnVsbGJhcid9JyBlZ2Vuc2thcCBmXHUwMEY2ciAnJ3swfScnIGhhciBhbmdldHRzIHNvbSBmYWxzZS4KLSAgICAgICAgY3ZjLWVsdC4zLjIuMSA9IGN2Yy1lbHQuMy4yLjE6IEVsZW1lbnRldCAnJ3swfScnIGZcdTAwRTVyIGludGUgaW5uZWhcdTAwRTVsbGEgW3VuZGVyb3JkbmFkZV0gbWVkIHRlY2tlbi0gZWxsZXIgZWxlbWVudGluZm9ybWF0aW9uIGVmdGVyc29tICcnezF9JycgaGFyIGFuZ2V0dHMuCi0gICAgICAgIGN2Yy1lbHQuMy4yLjIgPSBjdmMtZWx0LjMuMi4yOiBEZXQgZlx1MDBFNXIgaW50ZSBmaW5uYXMgblx1MDBFNWdvbiBmYXN0ICd7J3ZcdTAwRTRyZGViZWdyXHUwMEU0bnNuaW5nJ30nIGZcdTAwRjZyIGVsZW1lbnRldCAnJ3swfScnIGVmdGVyc29tICcnezF9JycgaGFyIGFuZ2V0dHMuCi0gICAgICAgIGN2Yy1lbHQuNC4xID0gY3ZjLWVsdC40LjE6IFZcdTAwRTRyZGV0ICcnezJ9JycgZlx1MDBGNnIgYXR0cmlidXRldCAnJ3sxfScnIGkgZWxlbWVudGV0ICcnezB9JycgXHUwMEU0ciBpbnRlIG5cdTAwRTVnb3QgZ2lsdGlndCBRTmFtZS4KLSAgICAgICAgY3ZjLWVsdC40LjIgPSBjdmMtZWx0LjQuMjogS2FuIGludGUgbWF0Y2hhICcnezF9JycgbWVkIHR5cGRlZmluaXRpb24gZlx1MDBGNnIgZWxlbWVudGV0ICcnezB9JycuCi0gICAgICAgIGN2Yy1lbHQuNC4zID0gY3ZjLWVsdC40LjM6IFR5cCAnJ3sxfScnIFx1MDBFNHIgaW50ZSBnaWx0aWd0IGF0dCB0YXMgZnJcdTAwRTVuIHR5cGRlZmluaXRpb25lbiAnJ3syfScnIGkgZWxlbWVudGV0ICcnezB9JycuCi0gICAgICAgIGN2Yy1lbHQuNS4xLjEgPSBjdmMtZWx0LjUuMS4xOiAneyd2XHUwMEU0cmRlYmVnclx1MDBFNG5zbmluZyd9JyAnJ3syfScnIGkgZWxlbWVudGV0ICcnezB9JycgXHUwMEU0ciBpbnRlIG5cdTAwRTVnb3QgZ2lsdGlndCBzdGFuZGFyZHZcdTAwRTRyZGUgZlx1MDBGNnIgdHlwICcnezF9JycuCi0gICAgICAgIGN2Yy1lbHQuNS4yLjIuMSA9IGN2Yy1lbHQuNS4yLjIuMTogRWxlbWVudGV0ICcnezB9JycgZlx1MDBFNXIgaW50ZSBoYSBbdW5kZXJvcmRuYWRlXSBvYmpla3QgbWVkIGVsZW1lbnRpbmZvcm1hdGlvbi4KLSAgICAgICAgY3ZjLWVsdC41LjIuMi4yLjEgPSBjdmMtZWx0LjUuMi4yLjIuMTogVlx1MDBFNHJkZXQgJyd7MX0nJyBpIGVsZW1lbnRldCAnJ3swfScnIG1hdGNoYXIgaW50ZSB2XHUwMEU0cmRldCBtZWQgZmFzdCAneyd2XHUwMEU0cmRlYmVnclx1MDBFNG5zbmluZyd9JywgJyd7Mn0nJy4KLSAgICAgICAgY3ZjLWVsdC41LjIuMi4yLjIgPSBjdmMtZWx0LjUuMi4yLjIuMjogVlx1MDBFNHJkZXQgJyd7MX0nJyBpIGVsZW1lbnRldCAnJ3swfScnIG1hdGNoYXIgaW50ZSB2XHUwMEU0cmRldCBtZWQgJ3sndlx1MDBFNHJkZWJlZ3JcdTAwRTRuc25pbmcnfScsICcnezJ9JycuCi0gICAgICAgIGN2Yy1lbnVtZXJhdGlvbi12YWxpZCA9IGN2Yy1lbnVtZXJhdGlvbi12YWxpZDogVlx1MDBFNHJkZXQgJyd7MH0nJyBcdTAwRTRyIG9naWx0aWd0IG1lZCBha3R1ZWxsIHVwcHJcdTAwRTRrbmluZyAnJ3sxfScnLiBWXHUwMEU0cmRldCBtXHUwMEU1c3RlIGluZ1x1MDBFNSBpIHVwcHJcdTAwRTRrbmluZ2VuLgotICAgICAgICBjdmMtZnJhY3Rpb25EaWdpdHMtdmFsaWQgPSBjdmMtZnJhY3Rpb25EaWdpdHMtdmFsaWQ6IFZcdTAwRTRyZGV0ICcnezB9JycgaGFyIHsxfSBiclx1MDBFNWt0YWxzc2lmZnJvciwgbWVuIGFudGFsZXQgYnJcdTAwRTVrdGFsc3NpZmZyb3IgXHUwMEU0ciBiZWdyXHUwMEU0bnNhdCB0aWxsIHsyfS4KLSAgICAgICAgY3ZjLWlkLjEgPSBjdmMtaWQuMTogRGV0IGZpbm5zIGluZ2VuIElEL0lEUkVGLWJpbmRuaW5nIGZcdTAwRjZyIElEUkVGICcnezB9JycuCi0gICAgICAgIGN2Yy1pZC4yID0gY3ZjLWlkLjI6IERldCBmaW5ucyBmbGVyYSBmXHUwMEY2cmVrb21zdGVyIGF2IGlkLXZcdTAwRTRyZGV0ICcnezB9JycuCi0gICAgICAgIGN2Yy1pZC4zID0gY3ZjLWlkLjM6IEV0dCBmXHUwMEU0bHQgbWVkIGlkLWJlZ3JcdTAwRTRuc25pbmcgJyd7MH0nJyBtYXRjaGFkZSBlbGVtZW50ZXQgJyd7MX0nJywgbWVuIGVsZW1lbnRldCBzYWtuYXIgZW5rZWwgdHlwLgotICAgICAgICBjdmMtbGVuZ3RoLXZhbGlkID0gY3ZjLWxlbmd0aC12YWxpZDogVlx1MDBFNHJkZXQgJyd7MH0nJyBtZWQgbFx1MDBFNG5nZCA9ICcnezF9JycgXHUwMEU0ciBvZ2lsdGlndCBtZWQgZGVuIGFrdHVlbGxhIGxcdTAwRTRuZ2RlbiAnJ3syfScnIGZcdTAwRjZyIHR5cCAnJ3szfScnLgotICAgICAgICBjdmMtbWF4RXhjbHVzaXZlLXZhbGlkID0gY3ZjLW1heEV4Y2x1c2l2ZS12YWxpZDogVlx1MDBFNHJkZXQgJyd7MH0nJyBcdTAwRTRyIG9naWx0aWd0IG1lZCBha3R1ZWxsdCBtYXhFeGNsdXNpdmUgJyd7MX0nJyBmXHUwMEY2ciB0eXAgJyd7Mn0nJy4KLSAgICAgICAgY3ZjLW1heEluY2x1c2l2ZS12YWxpZCA9IGN2Yy1tYXhJbmNsdXNpdmUtdmFsaWQ6IFZcdTAwRTRyZGV0ICcnezB9JycgXHUwMEU0ciBvZ2lsdGlndCBtZWQgYWt0dWVsbHQgbWF4SW5jbHVzaXZlICcnezF9JycgZlx1MDBGNnIgdHlwICcnezJ9JycuCi0gICAgICAgIGN2Yy1tYXhMZW5ndGgtdmFsaWQgPSBjdmMtbWF4TGVuZ3RoLXZhbGlkOiBWXHUwMEU0cmRldCAnJ3swfScnIG1lZCBsXHUwMEU0bmdkID0gJyd7MX0nJyBcdTAwRTRyIG9naWx0aWd0IG1lZCBha3R1ZWxsdCBtYXhMZW5ndGggJyd7Mn0nJyBmXHUwMEY2ciB0eXAgJyd7M30nJy4KLSAgICAgICAgY3ZjLW1pbkV4Y2x1c2l2ZS12YWxpZCA9IGN2Yy1taW5FeGNsdXNpdmUtdmFsaWQ6IFZcdTAwRTRyZGV0ICcnezB9JycgXHUwMEU0ciBvZ2lsdGlndCBtZWQgYWt0dWVsbHQgbWluRXhjbHVzaXZlICcnezF9JycgZlx1MDBGNnIgdHlwICcnezJ9JycuCi0gICAgICAgIGN2Yy1taW5JbmNsdXNpdmUtdmFsaWQgPSBjdmMtbWluSW5jbHVzaXZlLXZhbGlkOiBWXHUwMEU0cmRldCAnJ3swfScnIFx1MDBFNHIgb2dpbHRpZ3QgbWVkIGFrdHVlbGx0IG1pbkluY2x1c2l2ZSAnJ3sxfScnIGZcdTAwRjZyIHR5cCAnJ3syfScnLgotICAgICAgICBjdmMtbWluTGVuZ3RoLXZhbGlkID0gY3ZjLW1pbkxlbmd0aC12YWxpZDogVlx1MDBFNHJkZXQgJyd7MH0nJyBtZWQgbFx1MDBFNG5nZCA9ICcnezF9JycgXHUwMEU0ciBvZ2lsdGlndCBtZWQgYWt0dWVsbHQgbWluTGVuZ3RoICcnezJ9JycgZlx1MDBGNnIgdHlwICcnezN9JycuCi0gICAgICAgIGN2Yy1wYXR0ZXJuLXZhbGlkID0gY3ZjLXBhdHRlcm4tdmFsaWQ6IFZcdTAwRTRyZGV0ICcnezB9JycgXHUwMEU0ciBvZ2lsdGlndCBtZWQgYWt0dWVsbHQgbVx1MDBGNm5zdGVyICcnezF9JycgZlx1MDBGNnIgdHlwICcnezJ9JycuCi0gICAgICAgIGN2Yy10b3RhbERpZ2l0cy12YWxpZCA9IGN2Yy10b3RhbERpZ2l0cy12YWxpZDogVlx1MDBFNHJkZXQgJyd7MH0nJyBoYXIgezF9IHNpZmZyb3IsIG1lbiBkZXQgdG90YWxhIGFudGFsZXQgc2lmZnJvciBcdTAwRTRyIGJlZ3JcdTAwRTRuc2F0IHRpbGwgezJ9LgotICAgICAgICBjdmMtdHlwZS4yID0gY3ZjLXR5cGUuMjogVHlwZGVmaW5pdGlvbmVuIGthbiBpbnRlIHZhcmEgYWJzdHJha3QgZlx1MDBGNnIgZWxlbWVudGV0IHswfS4KLSAgICAgICAgY3ZjLXR5cGUuMy4xLjEgPSBjdmMtdHlwZS4zLjEuMTogRWxlbWVudGV0ICcnezB9JycgaGFyIGVua2VsIHR5cCBvY2gga2FuIGludGUgaW5uZWhcdTAwRTVsbGEgYXR0cmlidXQsIHV0XHUwMEY2dmVyIHNcdTAwRTVkYW5hIHZhcnMgbmFtbnJ5bWQgXHUwMEU0ciBpZGVudGlzayBtZWQgJydodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZScnIG9jaCB2YXJzIFtsb2thbGEgbmFtbl0gaGFyIG5cdTAwRTVnb3RkZXJhIGF2ICcndHlwZScnLCAnJ25pbCcnLCAnJ3NjaGVtYUxvY2F0aW9uJycgZWxsZXIgJydub05hbWVzcGFjZVNjaGVtYUxvY2F0aW9uJycuIEhpdHRhZGUgZG9jayBhdHRyaWJ1dGV0ICcnezF9JycuCi0gICAgICAgIGN2Yy10eXBlLjMuMS4yID0gY3ZjLXR5cGUuMy4xLjI6IEVsZW1lbnRldCAnJ3swfScnIGhhciBlbmtlbCB0eXAgb2NoIGZcdTAwRTVyIGludGUgaW5uZWhcdTAwRTVsbGEgW3VuZGVyb3JkbmFkZV0gbWVkIGVsZW1lbnRpbmZvcm1hdGlvbi4KLSAgICAgICAgY3ZjLXR5cGUuMy4xLjMgPSBjdmMtdHlwZS4zLjEuMzogVlx1MDBFNHJkZXQgJyd7MX0nJyBpIGVsZW1lbnRldCAnJ3swfScnIFx1MDBFNHIgb2dpbHRpZ3QuCi0KLSNzY2hlbWEgdmFsaWQgKDMuWC4zKQotCi0gICAgICAgIHNjaGVtYV9yZWZlcmVuY2UuYWNjZXNzID0gc2NoZW1hX3JlZmVyZW5jZTogS3VuZGUgaW50ZSBsXHUwMEU0c2Egc2NoZW1hZG9rdW1lbnRldCAnJ3swfScnIGVmdGVyc29tICcnezF9JyctXHUwMEU1dGtvbXN0IGludGUgdGlsbFx1MDBFNXRzIHBcdTAwRTUgZ3J1bmQgYXYgYmVnclx1MDBFNG5zbmluZyBzb20gYW5nZXMgYXYgZWdlbnNrYXBlbiBhY2Nlc3NFeHRlcm5hbFNjaGVtYS4gCi0gICAgICAgIHNjaGVtYV9yZWZlcmVuY2UuNCA9IHNjaGVtYV9yZWZlcmVuY2UuNDogTFx1MDBFNHNuaW5nIGF2IHNjaGVtYWRva3VtZW50ICcnezB9JycgdXRmXHUwMEY2cmRlcyBpbnRlIHBcdTAwRTUgZ3J1bmQgYXYgMSkgZGV0IGdcdTAwRTVyIGludGUgYXR0IGhpdHRhIGRva3VtZW50ZXQ7IDIpIGRldCBnXHUwMEU1ciBpbnRlIGF0dCBsXHUwMEU0c2EgZG9rdW1lbnRldDsgMykgZG9rdW1lbnRldHMgcm90ZWxlbWVudCBcdTAwRTRyIGludGUgPHhzZDpzY2hlbWE+LgotICAgICAgICBzcmMtYW5ub3RhdGlvbiA9IHNyYy1hbm5vdGF0aW9uOiBlbGVtZW50IGZcdTAwRjZyIDxhbnRlY2tuaW5nYXI+IGZcdTAwRTVyIGVuZGFzdCBpbm5laFx1MDBFNWxsYSBlbGVtZW50IGZcdTAwRjZyIDxhcHBpbmZvPiBvY2ggPGRva3VtZW50YXRpb24+LCBtZW4gJyd7MH0nJyBoaXR0YWRlcy4KLSAgICAgICAgc3JjLWF0dHJpYnV0ZS4xID0gc3JjLWF0dHJpYnV0ZS4xOiBCXHUwMEU1ZGEgZWdlbnNrYXBlcm5hICcnZGVmYXVsdCcnIG9jaCAnJ2ZpeGVkJycga2FuIGludGUgc2FtdGlkaWd0IGluZ1x1MDBFNSBpIGF0dHJpYnV0ZGVrbGFyYXRpb25lbiAnJ3swfScnLiBBbnZcdTAwRTRuZCBlbiBhdiBkZW0uCi0gICAgICAgIHNyYy1hdHRyaWJ1dGUuMiA9IHNyYy1hdHRyaWJ1dGUuMjogRWdlbnNrYXBlbiAnJ2RlZmF1bHQnJyBmaW5ucyBtZWQgaSBhdHRyaWJ1dGV0ICcnezB9JycsIHZpbGtldCBpbm5lYlx1MDBFNHIgYXR0IHZcdTAwRTRyZGV0IGZcdTAwRjZyICcndXNlJycgbVx1MDBFNXN0ZSB2YXJhICcnb3B0aW9uYWwnJy4KLSAgICAgICAgc3JjLWF0dHJpYnV0ZS4zLjEgPSBzcmMtYXR0cmlidXRlLjMuMTogQW50aW5nZW4gJ3JlZicgZWxsZXIgJ25hbWUnIG1cdTAwRTVzdGUgZmlubmFzIG1lZCBpIGxva2FsIGF0dHJpYnV0ZGVrbGFyYXRpb24uCi0gICAgICAgIHNyYy1hdHRyaWJ1dGUuMy4yID0gc3JjLWF0dHJpYnV0ZS4zLjI6IElubmVoXHUwMEU1bGxldCBtXHUwMEU1c3RlIG1hdGNoYSAoYW5ub3RhdGlvbj8pIGZcdTAwRjZyIGF0dHJpYnV0cmVmZXJlbnMgJyd7MH0nJy4KLSAgICAgICAgc3JjLWF0dHJpYnV0ZS40ID0gc3JjLWF0dHJpYnV0ZS40OiBBdHRyaWJ1dGV0ICcnezB9JycgaGFyIGJcdTAwRTVkZSBldHQgJyd0eXAnJy1hdHRyaWJ1dCBvY2ggZW4gYW5vbnltICcnc2ltcGxlVHlwZScnLXVuZGVyb3JkbmFkLiBFbmRhc3QgZXR0IGF2IGRlc3NhIHRpbGxcdTAwRTV0cyBzb20gYXR0cmlidXQuCi0gICAgICAgIHNyYy1hdHRyaWJ1dGVfZ3JvdXAuMiA9IHNyYy1hdHRyaWJ1dGVfZ3JvdXAuMjogU25pdHRldCBtZWxsYW4gam9rZXJ0ZWNrZW4ga2FuIGludGUgdXR0cnlja2FzIGZcdTAwRjZyIGF0dHJpYnV0Z3J1cHBlbiAnJ3swfScnLgotICAgICAgICBzcmMtYXR0cmlidXRlX2dyb3VwLjMgPSBzcmMtYXR0cmlidXRlX2dyb3VwLjM6IENpcmt1bFx1MDBFNHJhIGRlZmluaXRpb25lciBoYXIgaWRlbnRpZmllcmF0cyBmXHUwMEY2ciBhdHRyaWJ1dGdydXBwZW4gJyd7MH0nJy4gUmVrdXJzaXZ0IGVmdGVyZlx1MDBGNmxqYW5kZSBhdHRyaWJ1dGdydXBwcmVmZXJlbnNlciBsZWRlciBzXHUwMEU1IHNtXHUwMEU1bmluZ29tIHRpbGxiYWthIHRpbGwgc2lnIHNqXHUwMEU0bHYuCi0gICAgICAgIHNyYy1jdC4xID0gc3JjLWN0LjE6IEZlbCBpbnRyXHUwMEU0ZmZhZGUgdmlkIHJlcHJlc2VudGF0aW9uZW4gYXYgZGVmaW5pdGlvbiBmXHUwMEY2ciB0eXAgJyd7MH0nJy4gT20gPGNvbXBsZXhDb250ZW50PiBhbnZcdTAwRTRuZHMgbVx1MDBFNXN0ZSBiYXN0eXAgdmFyYSBjb21wbGV4VHlwZS4gJyd7MX0nJyBcdTAwRTRyIHNpbXBsZVR5cGUuCi0gICAgICAgIHNyYy1jdC4yLjEgPSBzcmMtY3QuMi4xOiBGZWwgaW50clx1MDBFNGZmYWRlIHZpZCByZXByZXNlbnRhdGlvbmVuIGF2IGRlZmluaXRpb24gZlx1MDBGNnIgdHlwICcnezB9JycuIE9tIDxzaW1wbGVDb250ZW50PiBhbnZcdTAwRTRuZHMgbVx1MDBFNXN0ZSBiYXN0eXAgdmFyYSBjb21wbGV4VHlwZSB2YXJzIGlubmVoXHUwMEU1bGwgXHUwMEU0ciBlbmtlbHQsIGVsbGVyLCBvbSBkZXQgZmlubnMgZW4gYW5naXZlbiBiZWdyXHUwMEU0bnNuaW5nLCBrb21wbGV4IHR5cCBtZWQgYmxhbmRhdCBpbm5laFx1MDBFNWxsIG9jaCB0XHUwMEY2bW5pbmdzYmFyIHBhcnRpa2VsLCBlbGxlciwgb20gZGV0IGZpbm5zIGV0dCBhbmdpdmV0IHRpbGxcdTAwRTRnZywgZW5rZWwgdHlwLiAnJ3sxfScnIHVwcGZ5bGxlciBpbmdldCBhdiBkZXNzYSB2aWxsa29yLgotICAgICAgICBzcmMtY3QuMi4yID0gc3JjLWN0LjIuMjogRmVsIGludHJcdTAwRTRmZmFkZSB2aWQgcmVwcmVzZW50YXRpb25lbiBhdiBkZWZpbml0aW9uIGZcdTAwRjZyIHR5cCAnJ3swfScnLiBPbSBjb21wbGV4VHlwZSBtZWQgc2ltcGxlQ29udGVudCBiZWdyXHUwMEU0bnNhciBjb21wbGV4VHlwZSBtZWQgYmxhbmRhdCBpbm5laFx1MDBFNWxsIG9jaCB0XHUwMEY2bW5pbmdzYmFyIHBhcnRpa2VsIG1cdTAwRTVzdGUgZGV0IGZpbm5hcyBlbiA8c2ltcGxlVHlwZT4gYmxhbmQgdW5kZXJvcmRuYWRlIGkgPHJlc3RyaWN0aW9uPi4KLSAgICAgICAgc3JjLWN0LjQgPSBzcmMtY3QuNDogRmVsIGludHJcdTAwRTRmZmFkZSB2aWQgcmVwcmVzZW50YXRpb25lbiBhdiBkZWZpbml0aW9uIGZcdTAwRjZyIHR5cCAnJ3swfScnLiBTbml0dGV0IG1lbGxhbiBqb2tlcnRlY2tlbiBrYW4gaW50ZSB1dHRyeWNrYXMuCi0gICAgICAgIHNyYy1jdC41ID0gc3JjLWN0LjU6IEZlbCBpbnRyXHUwMEU0ZmZhZGUgdmlkIHJlcHJlc2VudGF0aW9uZW4gYXYgZGVmaW5pdGlvbiBmXHUwMEY2ciB0eXAgJyd7MH0nJy4gVW5pb25lbiBtZWxsYW4gam9rZXJ0ZWNrZW4ga2FuIGludGUgdXR0cnlja2FzLgotICAgICAgICBzcmMtZWxlbWVudC4xID0gc3JjLWVsZW1lbnQuMTogQlx1MDBFNWRhIGVnZW5za2FwZXJuYSAnJ2RlZmF1bHQnJyBvY2ggJydmaXhlZCcnIGthbiBpbnRlIHNhbXRpZGlndCBpbmdcdTAwRTUgaSBlbGVtZW50ZGVrbGFyYXRpb25lbiAnJ3swfScnLiBBbnZcdTAwRTRuZCBlbiBhdiBkZW0uCi0gICAgICAgIHNyYy1lbGVtZW50LjIuMSA9IHNyYy1lbGVtZW50LjIuMTogQW50aW5nZW4gJ3JlZicgZWxsZXIgJ25hbWUnIG1cdTAwRTVzdGUgYW5nZXMgaSBkZW4gbG9rYWxhIGVsZW1lbnRkZWtsYXJhdGlvbmVuLgotICAgICAgICBzcmMtZWxlbWVudC4yLjIgPSBzcmMtZWxlbWVudC4yLjI6IEVmdGVyc29tICcnezB9JycgaW5uZWhcdTAwRTVsbGVyIGV0dCAnJ3JlZicnLWF0dHJpYnV0IG1cdTAwRTVzdGUgaW5uZWhcdTAwRTVsbGV0IG1hdGNoYSAoYW5ub3RhdGlvbj8pLiAnJ3sxfScnIGhpdHRhZGVzIGRvY2sgaW50ZS4KLSAgICAgICAgc3JjLWVsZW1lbnQuMyA9IHNyYy1lbGVtZW50LjM6IEVsZW1lbnRldCAnJ3swfScnIGlubmVoXHUwMEU1bGxlciBiXHUwMEU1ZGUgJyd0eXBlJyctYXR0cmlidXQgb2NoIHVuZGVyb3JkbmF0ICcnYW5vbnltb3VzIHR5cGUnJy4gRW5kYXN0IGV0dCBhdiBkZXNzYSBcdTAwRTRyIHRpbGxcdTAwRTV0ZXQgaSBldHQgZWxlbWVudC4KLSAgICAgICAgc3JjLWltcG9ydC4xLjEgPSBzcmMtaW1wb3J0LjEuMTogTmFtbnJ5bWRzYXR0cmlidXRldCAnJ3swfScnIGkgZXR0IG9iamVrdCBtZWQgZWxlbWVudGluZm9ybWF0aW9uIGZcdTAwRjZyIDxpbXBvcnQ+IGZcdTAwRTVyIGludGUgdmFyYSBzYW1tYSBzb20gdGFyZ2V0TmFtZXNwYWNlIGkgZGV0IHNjaGVtYSBzb20gZGV0IGluZ1x1MDBFNXIgaS4KLSAgICAgICAgc3JjLWltcG9ydC4xLjIgPSBzcmMtaW1wb3J0LjEuMjogT20gbmFtbnJ5bWRzYXR0cmlidXRldCBpbnRlIGZpbm5zIG1lZCBpIGV0dCBvYmpla3QgbWVkIGVsZW1lbnRpbmZvcm1hdGlvbiBmXHUwMEY2ciA8aW1wb3J0PiBtXHUwMEU1c3RlIG9tc2x1dGFuZGUgc2NoZW1hIGhhIGV0dCBhbmdpdmV0IHRhcmdldE5hbWVzcGFjZS4KLSAgICAgICAgc3JjLWltcG9ydC4yID0gc3JjLWltcG9ydC4yOiBSb3RlbGVtZW50ZXQgZlx1MDBGNnIgZG9rdW1lbnRldCAnJ3swfScnIG1cdTAwRTVzdGUgaGEgbmFtbnJ5bWRzbmFtbmV0ICcnaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEnJyBvY2ggZGV0IGxva2FsYSBuYW1uZXQgJydzY2hlbWEnJy4KLSAgICAgICAgc3JjLWltcG9ydC4zLjEgPSBzcmMtaW1wb3J0LjMuMTogTmFtbnJ5bWRzYXR0cmlidXRldCAnJ3swfScnIGZcdTAwRjZyIGV0dCBvYmpla3QgbWVkIGVsZW1lbnRpbmZvcm1hdGlvbiBmXHUwMEY2ciA8aW1wb3J0PiBtXHUwMEU1c3RlIHZhcmEgaWRlbnRpc2t0IG1lZCB0YXJnZXROYW1lc3BhY2UtYXR0cmlidXRldCAnJ3sxfScnIGkgZGV0IGltcG9ydGVyYWRlIGRva3VtZW50ZXQuCi0gICAgICAgIHNyYy1pbXBvcnQuMy4yID0gc3JjLWltcG9ydC4zLjI6IEV0dCBvYmpla3QgbWVkIGVsZW1lbnRpbmZvcm1hdGlvbiBmXHUwMEY2ciA8aW1wb3J0PiBzb20gc2FrbmFkZSBuYW1ucnltZHNhdHRyaWJ1dCBoaXR0YWRlcyBvY2ggZFx1MDBFNHJmXHUwMEY2ciBrYW4gaW1wb3J0ZXJhdCBkb2t1bWVudCBpbnRlIGFudlx1MDBFNG5kYXMgbWVkIGF0dHJpYnV0ZXQgdGFyZ2V0TmFtZXNwYWNlLiB0YXJnZXROYW1lc3BhY2UgJyd7MX0nJyBoaXR0YWRlcyBkb2NrIGkgaW1wb3J0ZXJhdCBkb2t1bWVudC4KLSAgICAgICAgc3JjLWluY2x1ZGUuMSA9IHNyYy1pbmNsdWRlLjE6IFJvdGVsZW1lbnRldCBmXHUwMEY2ciBkb2t1bWVudGV0ICcnezB9JycgbVx1MDBFNXN0ZSBoYSBuYW1ucnltZHNuYW1uZXQgJydodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYScnIG9jaCBkZXQgbG9rYWxhIG5hbW5ldCAnJ3NjaGVtYScnLgotICAgICAgICBzcmMtaW5jbHVkZS4yLjEgPSBzcmMtaW5jbHVkZS4yLjE6IHRhcmdldE5hbWVzcGFjZSBmXHUwMEY2ciByZWZlcmVyYXQgc2NoZW1hLCBmXHUwMEY2ciBuXHUwMEU0cnZhcmFuZGUgJyd7MX0nJywgbVx1MDBFNXN0ZSB2YXJhIGlkZW50aXNrdCBtZWQgbW90c3ZhcmFuZGUgaSBpbmtsdWRlcmF0IHNjaGVtYSwgZlx1MDBGNnIgblx1MDBFNHJ2YXJhbmRlICcnezB9JycuCi0gICAgICAgIHNyYy1yZWRlZmluZS4yID0gc3JjLXJlZGVmaW5lLjI6IFJvdGVsZW1lbnRldCBmXHUwMEY2ciBkb2t1bWVudGV0ICcnezB9JycgbVx1MDBFNXN0ZSBoYSBuYW1ucnltZHNuYW1uZXQgJydodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYScnIG9jaCBkZXQgbG9rYWxhIG5hbW5ldCAnJ3NjaGVtYScnLgotICAgICAgICBzcmMtcmVkZWZpbmUuMy4xID0gc3JjLWluY2x1ZGUuMy4xOiB0YXJnZXROYW1lc3BhY2UgZlx1MDBGNnIgcmVmZXJlcmF0IHNjaGVtYSwgZlx1MDBGNnIgblx1MDBFNHJ2YXJhbmRlICcnezF9JycsIG1cdTAwRTVzdGUgdmFyYSBpZGVudGlza3QgbWVkIG1vdHN2YXJhbmRlIGkgb21kZWZpbmllcmFuZGUgc2NoZW1hLCBmXHUwMEY2ciBuXHUwMEU0cnZhcmFuZGUgJyd7MH0nJy4KLSAgICAgICAgc3JjLXJlZGVmaW5lLjUuYS5hID0gc3JjLXJlZGVmaW5lLjUuYS5hOiBIaXR0YWRlIGluZ2EgPHNpbXBsZVR5cGU+LXVuZGVyb3JkbmFkZSBtZWQgaWNrZS1hbnRlY2tuaW5nLiA8c2ltcGxlVHlwZT4tdW5kZXJvcmRuYWRlIGkgPHJlZGVmaW5lPi1lbGVtZW50IG1cdTAwRTVzdGUgaGEgPHJlc3RyaWN0aW9uPi11bmRlcm9yZG5hZGUsIG1lZCAnYmFzZSctYXR0cmlidXQgc29tIHJlZmVyZXJhciB0aWxsIHNpZyBzalx1MDBFNGx2YS4KLSAgICAgICAgc3JjLXJlZGVmaW5lLjUuYS5iID0gc3JjLXJlZGVmaW5lLjUuYS5iOiAnJ3swfScnIFx1MDBFNHIgaW50ZSBuXHUwMEU1Z290IGdpbHRpZ3QgdW5kZXJvcmRuYXQgZWxlbWVudC4gPHNpbXBsZVR5cGU+LXVuZGVyb3JkbmFkZSBpIDxyZWRlZmluZT4tZWxlbWVudCBtXHUwMEU1c3RlIGhhIDxyZXN0cmljdGlvbj4tdW5kZXJvcmRuYWRlLCBtZWQgJydiYXNlJyctYXR0cmlidXQgc29tIHJlZmVyZXJhciB0aWxsIHNpZyBzalx1MDBFNGx2YS4KLSAgICAgICAgc3JjLXJlZGVmaW5lLjUuYS5jID0gc3JjLXJlZGVmaW5lLjUuYS5jOiAnJ3swfScnIHNha25hciBldHQgJydiYXNlJyctYXR0cmlidXQgc29tIHJlZmVyZXJhciB0aWxsIGRldCBvbWRlZmluaWVyYWRlIGVsZW1lbnRldCAnJ3sxfScnLiA8c2ltcGxlVHlwZT4tdW5kZXJvcmRuYWRlIGkgPHJlZGVmaW5lPi1lbGVtZW50IG1cdTAwRTVzdGUgaGEgPHJlc3RyaWN0aW9uPi11bmRlcm9yZG5hZGUsIG1lZCAnJ2Jhc2UnJy1hdHRyaWJ1dCBzb20gcmVmZXJlcmFyIHRpbGwgc2lnIHNqXHUwMEU0bHZhLgotICAgICAgICBzcmMtcmVkZWZpbmUuNS5iLmEgPSBzcmMtcmVkZWZpbmUuNS5iLmE6IEhpdHRhZGUgaW5nYSA8Y29tcGxleFR5cGU+LXVuZGVyb3JkbmFkZSBtZWQgaWNrZS1hbnRlY2tuaW5nLiA8Y29tcGxleFR5cGU+LXVuZGVyb3JkbmFkZSBpIDxyZWRlZmluZT4tZWxlbWVudCBtXHUwMEU1c3RlIGhhIDxleHRlbnNpb24+LSBlbGxlciA8cmVzdHJpY3Rpb24+LXVuZGVyb3JkbmFkZSwgbWVkICdiYXNlJy1hdHRyaWJ1dCBzb20gcmVmZXJlcmFyIHRpbGwgc2lnIHNqXHUwMEU0bHZhLgotICAgICAgICBzcmMtcmVkZWZpbmUuNS5iLmIgPSBzcmMtcmVkZWZpbmUuNS5iLmI6IEhpdHRhZGUgaW5nYSA8Y29tcGxleFR5cGU+LXVuZGVyb3JkbmFkZSBwXHUwMEU1IGxcdTAwRTRnc3RhIG5pdlx1MDBFNSBtZWQgaWNrZS1hbnRlY2tuaW5nLiA8Y29tcGxleFR5cGU+LXVuZGVyb3JkbmFkZSBpIDxyZWRlZmluZT4tZWxlbWVudCBtXHUwMEU1c3RlIGhhIDxleHRlbnNpb24+LSBlbGxlciA8cmVzdHJpY3Rpb24+LXVuZGVyb3JkbmFkZSwgbWVkICdiYXNlJy1hdHRyaWJ1dCBzb20gcmVmZXJlcmFyIHRpbGwgc2lnIHNqXHUwMEU0bHZhLgotICAgICAgICBzcmMtcmVkZWZpbmUuNS5iLmMgPSBzcmMtcmVkZWZpbmUuNS5hLmM6ICcnezB9JycgXHUwMEU0ciBpbnRlIG5cdTAwRTVnb3QgZ2lsdGlndCB1bmRlcm9yZG5hdCBlbGVtZW50IHBcdTAwRTUgbFx1MDBFNGdzdGEgbml2XHUwMEU1LiA8Y29tcGxleFR5cGU+LXVuZGVyb3JkbmFkZSBpIDxyZWRlZmluZT4tZWxlbWVudCBtXHUwMEU1c3RlIGhhIDxleHRlbnNpb24+LSBlbGxlciA8cmVzdHJpY3Rpb24+LXVuZGVyb3JkbmFkZSwgbWVkICcnYmFzZScnLWF0dHJpYnV0IHNvbSByZWZlcmVyYXIgdGlsbCBzaWcgc2pcdTAwRTRsdmEuCi0gICAgICAgIHNyYy1yZWRlZmluZS41LmIuZCA9IHNyYy1yZWRlZmluZS41LmEuZDogJyd7MH0nJyBzYWtuYXIgZXR0ICcnYmFzZScnLWF0dHJpYnV0IHNvbSByZWZlcmVyYXIgdGlsbCBkZXQgb21kZWZpbmllcmFkZSBlbGVtZW50ZXQgJyd7MX0nJy4gPGNvbXBsZXhUeXBlPi11bmRlcm9yZG5hZGUgaSA8cmVkZWZpbmU+LWVsZW1lbnQgbVx1MDBFNXN0ZSBoYSA8ZXh0ZW5zaW9uPi0gZWxsZXIgPHJlc3RyaWN0aW9uPi11bmRlcm9yZG5hZGUsIG1lZCAnJ2Jhc2UnJy1hdHRyaWJ1dCBzb20gcmVmZXJlcmFyIHRpbGwgc2lnIHNqXHUwMEU0bHZhLgotICAgICAgICBzcmMtcmVkZWZpbmUuNi4xLjEgPSBzcmMtcmVkZWZpbmUuNi4xLjE6IE9tIGVuIHVuZGVyb3JkbmFkIGdydXBwIGkgZXR0IDxyZWRlZmluZT4tZWxlbWVudCBpbm5laFx1MDBFNWxsZXIgZW4gZ3J1cHAgc29tIHJlZmVyZXJhciBzaWcgc2pcdTAwRTRsdiBtXHUwMEU1c3RlIGRlbiBoYSBleGFrdCAxOyBkZW4gaFx1MDBFNHIgaGFyICcnezB9JycuCi0gICAgICAgIHNyYy1yZWRlZmluZS42LjEuMiA9IHNyYy1yZWRlZmluZS42LjEuMjogR3J1cHBlbiAnJ3swfScnLCBzb20gaW5uZWhcdTAwRTVsbGVyIGVuIHJlZmVyZW5zIHRpbGwgZW4gZ3J1cHAgc29tIG9tZGVmaW5pZXJhcywgbVx1MDBFNXN0ZSBhbmdlcyBzb20gJydtaW5PY2N1cnMnJyA9ICcnbWF4T2NjdXJzJycgPSAxLgotICAgICAgICBzcmMtcmVkZWZpbmUuNi4yLjEgPSBzcmMtcmVkZWZpbmUuNi4yLjE6IERldCBmaW5ucyBpbmdlbiBncnVwcCBpIGRldCBvbWRlZmluaWVyYWRlIHNjaGVtYXQgbWVkIGV0dCBuYW1uIHNvbSBtYXRjaGFyICcnezB9JycuCi0gICAgICAgIHNyYy1yZWRlZmluZS42LjIuMiA9IHNyYy1yZWRlZmluZS42LjIuMjogR3J1cHBlbiAnJ3swfScnIGdlciBpbmdlbiBrb3JyZWt0IGJlZ3JcdTAwRTRuc25pbmcgYXYgZ3J1cHBlbiBzb20gb21kZWZpbmllcmFzOyBicm90dCBtb3QgYmVnclx1MDBFNG5zbmluZzogJyd7MX0nJy4KLSAgICAgICAgc3JjLXJlZGVmaW5lLjcuMSA9IHNyYy1yZWRlZmluZS43LjE6IE9tIGVuIGF0dHJpYnV0ZUdyb3VwLXVuZGVyb3JkbmFkIGkgZXR0IDxyZWRlZmluZT4tZWxlbWVudCBpbm5laFx1MDBFNWxsZXIgYXR0cmlidXRlR3JvdXAgc29tIHJlZmVyZXJhciB0aWxsIHNpZyBzalx1MDBFNGx2IG1cdTAwRTVzdGUgZGVuIGhhIGV4YWt0IDE7IGRlbiBoXHUwMEU0ciBoYXIgezB9LgotICAgICAgICBzcmMtcmVkZWZpbmUuNy4yLjEgPSBzcmMtcmVkZWZpbmUuNy4yLjE6IERldCBmaW5ucyBpbmdlbiBhdHRyaWJ1dGVHcm91cCBpIGRldCBvbWRlZmluaWVyYWRlIHNjaGVtYXQgbWVkIGV0dCBuYW1uIHNvbSBtYXRjaGFyICcnezB9JycuCi0gICAgICAgIHNyYy1yZWRlZmluZS43LjIuMiA9IHNyYy1yZWRlZmluZS43LjIuMjogQXR0cmlidXRlR3JvdXAgJyd7MH0nJyBnZXIgaW5nZW4ga29ycmVrdCBiZWdyXHUwMEU0bnNuaW5nIGF2IGF0dHJpYnV0ZUdyb3VwIHNvbSBvbWRlZmluaWVyYXM7IGJyb3R0IG1vdCBiZWdyXHUwMEU0bnNuaW5nOiAnJ3sxfScnLgotICAgICAgICBzcmMtcmVzb2x2ZSA9IHNyYy1yZXNvbHZlOiBOYW1uZXQgJyd7MH0nJyBrYW4gaW50ZSBtYXRjaGFzIG1lZCBrb21wb25lbnRlbiAnJ3sxfScnLgotICAgICAgICBzcmMtcmVzb2x2ZS40LjEgPSBzcmMtcmVzb2x2ZS40LjE6IEV0dCBmZWwgaW50clx1MDBFNGZmYWRlIHZpZCBtYXRjaG5pbmcgYXYga29tcG9uZW50ZW4gJyd7Mn0nJy4gU3lzdGVtZXQgdXBwdFx1MDBFNGNrdGUgYXR0ICcnezJ9Jycgc2FrbmFyIG5hbW5yeW1kIG9jaCBrb21wb25lbnRlciB1dGFuIG5hbW5yeW1kIGthbiBpbnRlIHJlZmVyZXJhcyB0aWxsIGZyXHUwMEU1biBzY2hlbWFkb2t1bWVudGV0ICcnezB9JycuIE9tICcnezJ9Jycgc2thIGFudlx1MDBFNG5kYXMgbWVkIG5hbW5yeW1kIGthbnNrZSBkdSBiZWhcdTAwRjZ2ZXIgYW5nZSBldHQgcHJlZml4LiBPbSAnJ3syfScnIHNrYSBhbnZcdTAwRTRuZGFzIHV0YW4gbmFtbnJ5bWQgYlx1MDBGNnIgZHUgbFx1MDBFNGdnYSB0aWxsICcnaW1wb3J0JycgdXRhbiAibmFtZXNwYWNlIi1hdHRyaWJ1dCB0aWxsICcnezB9JycuCi0gICAgICAgIHNyYy1yZXNvbHZlLjQuMiA9IHNyYy1yZXNvbHZlLjQuMjogRXR0IGZlbCBpbnRyXHUwMEU0ZmZhZGUgdmlkIG1hdGNobmluZyBhdiBrb21wb25lbnQgJyd7Mn0nJy4gU3lzdGVtZXQgdXBwdFx1MDBFNGNrdGUgYXR0ICcnezJ9JycgZmlubnMgaSBuYW1ucnltZGVuICcnezF9Jycgb2NoIGtvbXBvbmVudGVyIGZyXHUwMEU1biBkZW5uYSBuYW1ucnltZCBrYW4gaW50ZSByZWZlcmVyYXMgdGlsbCBmclx1MDBFNW4gc2NoZW1hZG9rdW1lbnRldCAnJ3swfScnLiBPbSBkZXR0YSBcdTAwRTRyIGVuIGZlbGFrdGlnIG5hbW5yeW1kIGthbnNrZSBkdSBtXHUwMEU1c3RlIFx1MDBFNG5kcmEgcHJlZml4ZXQgJyd7Mn0nJy4gT20gbmFtbnJ5bWRlbiBcdTAwRTRyIGtvcnJla3QgYmVoXHUwMEY2dmVyIGR1IGxcdTAwRTRnZ2EgdGlsbCBsXHUwMEU0bXBsaWcgJydpbXBvcnQnJy10YWdnIGkgJyd7MH0nJy4KLSAgICAgICAgc3JjLXNpbXBsZS10eXBlLjIuYSA9IHNyYy1zaW1wbGUtdHlwZS4yLmE6IEV0dCA8cmVzdHJpY3Rpb24+LWVsZW1lbnQgaGl0dGFkZXMgbWVkIGJcdTAwRTVkZSBldHQgYmFzLVthdHRyaWJ1dF0gb2NoIGV0dCA8c2ltcGxlVHlwZT4tZWxlbWVudCBibGFuZCBbdW5kZXJvcmRuYWRlXS4gRW5kYXN0IGV0dCBhdiBkZW0gXHUwMEU0ciB0aWxsXHUwMEU1dGV0LgotICAgICAgICBzcmMtc2ltcGxlLXR5cGUuMi5iID0gc3JjLXNpbXBsZS10eXBlLjIuYjogRXR0IDxyZXN0cmljdGlvbj4tZWxlbWVudCBoaXR0YWRlcyBtZWQgdmFya2VuIGV0dCBiYXMtW2F0dHJpYnV0XSBlbGxlciBldHQgPHNpbXBsZVR5cGU+LWVsZW1lbnQgYmxhbmQgW3VuZGVyb3JkbmFkZV0uIE5cdTAwRTVnb3RkZXJhIGF2IGRlbSBrclx1MDBFNHZzLgotICAgICAgICBzcmMtc2ltcGxlLXR5cGUuMy5hID0gc3JjLXNpbXBsZS10eXBlLjMuYTogRXR0IDxsaXN0Pi1lbGVtZW50IGhpdHRhZGVzIG1lZCBiXHUwMEU1ZGUgZXR0IGl0ZW1UeXBlLVthdHRyaWJ1dF0gb2NoIGV0dCA8c2ltcGxlVHlwZT4tZWxlbWVudCBibGFuZCBbdW5kZXJvcmRuYWRlXS4gRW5kYXN0IGV0dCBhdiBkZW0gXHUwMEU0ciB0aWxsXHUwMEU1dGV0LgotICAgICAgICBzcmMtc2ltcGxlLXR5cGUuMy5iID0gc3JjLXNpbXBsZS10eXBlLjMuYjogRXR0IDxsaXN0Pi1lbGVtZW50IGhpdHRhZGVzIG1lZCB2YXJrZW4gZXR0IGl0ZW1UeXBlLVthdHRyaWJ1dF0gZWxsZXIgZXR0IDxzaW1wbGVUeXBlPi1lbGVtZW50IGJsYW5kIFt1bmRlcm9yZG5hZGVdLiBOXHUwMEU1Z290ZGVyYSBhdiBkZW0ga3JcdTAwRTR2cy4KLSAgICAgICAgc3JjLXNpbmdsZS1mYWNldC12YWx1ZSA9IHNyYy1zaW5nbGUtZmFjZXQtdmFsdWU6IEFzcGVrdGVuIChmYWNldCkgJyd7MH0nJyBoYXIgZGVmaW5pZXJhdHMgZmxlciBcdTAwRTRuIGVuIGdcdTAwRTVuZy4KLSAgICAgICAgc3JjLXVuaW9uLW1lbWJlclR5cGVzLW9yLXNpbXBsZVR5cGVzID0gc3JjLXVuaW9uLW1lbWJlclR5cGVzLW9yLXNpbXBsZVR5cGVzOiBFdHQgPHVuaW9uPi1lbGVtZW50IG1cdTAwRTVzdGUgYW5nZXMgbWVkIGFudGluZ2VuIGV0dCBpY2tlLXRvbXQgbWVtYmVyVHlwZXMtW2F0dHJpYnV0XSBlbGxlciBtaW5zdCBldHQgPHNpbXBsZVR5cGU+LWVsZW1lbnQgYmxhbmQgW3VuZGVyb3JkbmFkZV0uCi0KLSNjb25zdHJhaW50IHZhbGlkICgzLlguNikKLQotICAgICAgICBhZy1wcm9wcy1jb3JyZWN0LjIgPSBhZy1wcm9wcy1jb3JyZWN0LjI6IEV0dCBmZWwgaW50clx1MDBFNGZmYWRlIGZcdTAwRjZyIGF0dHJpYnV0Z3J1cHBlbiAnJ3swfScnLiBEdXBsaWNlcmFkIGF0dHJpYnV0YW52XHUwMEU0bmRuaW5nIG1lZCBzYW1tYSBuYW1uIG9jaCBuYW1ucnltZC4gTmFtbmV0IHBcdTAwRTUgZHViYmxldHRlbiBcdTAwRTRyICcnezF9JycuCi0gICAgICAgIGFnLXByb3BzLWNvcnJlY3QuMyA9IGFnLXByb3BzLWNvcnJlY3QuMzogRXR0IGZlbCBpbnRyXHUwMEU0ZmZhZGUgZlx1MDBGNnIgYXR0cmlidXRncnVwcGVuICcnezB9JycuIFR2XHUwMEU1IGF0dHJpYnV0ZGVrbGFyYXRpb25lciwgJyd7MX0nJyBvY2ggJyd7Mn0nJyBoYXIgYW5nZXR0cyBtZWQgdHlwZXIgc29tIGhcdTAwRTRybGVkcyBmclx1MDBFNW4gSUQuCi0gICAgICAgIGEtcHJvcHMtY29ycmVjdC4yID0gYS1wcm9wcy1jb3JyZWN0LjI6IE9naWx0aWd0IHZcdTAwRTRyZGUgZlx1MDBGNnIgYmVnclx1MDBFNG5zbmluZywgJyd7MX0nJywgaSBhdHRyaWJ1dGV0ICcnezB9JycuCi0gICAgICAgIGEtcHJvcHMtY29ycmVjdC4zID0gYS1wcm9wcy1jb3JyZWN0LjM6IEF0dHJpYnV0ZXQgJyd7MH0nJyBmXHUwMEU1ciBpbnRlIGFudlx1MDBFNG5kYSAnJ2ZpeGVkJycgZWxsZXIgJydkZWZhdWx0JycsIGVmdGVyc29tIGF0dHJpYnV0ZXRzICd7J3R5cGRlZmluaXRpb24nfScgXHUwMEU0ciBJRCBlbGxlciBoXHUwMEU0cmxlZHMgZnJcdTAwRTVuIElELgotICAgICAgICBhdS1wcm9wcy1jb3JyZWN0LjIgPSBhdS1wcm9wcy1jb3JyZWN0LjI6IERldCBmYXN0YSB2XHUwMEU0cmRldCAnJ3sxfScnIGhhciBhbmdldHRzIGkgYXR0cmlidXRkZWtsYXJhdGlvbmVuICcnezB9JycuIE9tIGF0dHJpYnV0ZXQgc29tIHJlZmVyZXJhciB0aWxsICcnezB9JycgXHUwMEU0dmVuIGlubmVoXHUwMEU1bGxlciBlbiAneyd2XHUwMEU0cmRlYmVnclx1MDBFNG5zbmluZyd9JyBtXHUwMEU1c3RlIGR1IGxcdTAwRjZzYSBkZXR0YSBvY2ggYW5nZSB2XHUwMEU0cmRldCAnJ3sxfScnLgotICAgICAgICBjb3MtYWxsLWxpbWl0ZWQuMS4yID0gY29zLWFsbC1saW1pdGVkLjEuMjogRW4gJ2FsbCctbW9kZWxsZ3J1cHAgbVx1MDBFNXN0ZSBhbmdlcyBpIGVuIHBhcnRpa2VsIG1lZCAneydtaW4gZlx1MDBGNnJla29tc3Rlcid9JyA9ICd7J21heCBmXHUwMEY2cmVrb21zdGVyJ30nID0gMSBvY2ggcGFydGlrZWxuIG1cdTAwRTVzdGUgdmFyYSBlbiBkZWwgaSBldHQgcGFyIHNvbSB1dGdcdTAwRjZyICd7J2lubmVoXHUwMEU1bGxzdHlwJ30nIGkgZW4ga29tcGxleCB0eXBkZWZpbml0aW9uLgotICAgICAgICBjb3MtYWxsLWxpbWl0ZWQuMiA9IGNvcy1hbGwtbGltaXRlZC4yOiBWXHUwMEU0cmRldCBmXHUwMEY2ciAneydtYXggZlx1MDBGNnJla29tc3Rlcid9JyBpIGV0dCBlbGVtZW50IGkgZW4gJydhbGwnJy1tb2RlbGxncnVwcCBtXHUwMEU1c3RlIHZhcmEgMCBlbGxlciAxLiBWXHUwMEU0cmRldCAnJ3swfScnIGZcdTAwRjZyIGVsZW1lbnRldCAnJ3sxfScnIFx1MDBFNHIgb2dpbHRpZ3QuCi0gICAgICAgIGNvcy1hcHBsaWNhYmxlLWZhY2V0cyA9IGNvcy1hcHBsaWNhYmxlLWZhY2V0czogQXNwZWt0ZW4gKGZhY2V0KSAnJ3swfScnIFx1MDBFNHIgaW50ZSB0aWxsXHUwMEU1dGVuIG1lZCB0eXAgezF9LgotICAgICAgICBjb3MtY3QtZXh0ZW5kcy4xLjEgPSBjb3MtY3QtZXh0ZW5kcy4xLjE6IFR5cCAnJ3swfScnIGhcdTAwRTRybGVkcyBmclx1MDBFNW4gZXR0IHRpbGxcdTAwRTRnZyBmclx1MDBFNW4gdHlwICcnezF9JycuIEF0dHJpYnV0ZXQgJydmaW5hbCcnIGkgJyd7MX0nJyB0aWxsXHUwMEU1dGVyIGRvY2sgaW50ZSBoXHUwMEU0cmxlZG5pbmcgYXYgdGlsbFx1MDBFNGdnLgotICAgICAgICBjb3MtY3QtZXh0ZW5kcy4xLjQuMy4yLjIuMS5hID0gY29zLWN0LWV4dGVuZHMuMS40LjMuMi4yLjEuYTogSW5uZWhcdTAwRTVsbHN0eXAgZlx1MDBGNnIgaFx1MDBFNHJsZWRkIHR5cCBvY2ggZlx1MDBGNnIgYmFzZW4gbVx1MDBFNXN0ZSBiXHUwMEU1ZGEgdmFyYSBibGFuZGFkZSBlbGxlciBlbmRhc3QgZWxlbWVudC4gVHlwICcnezB9JycgXHUwMEU0ciBlbmRhc3QgZWxlbWVudCwgbWVuIGRcdTAwRTRyZW1vdCBpbnRlIGJhc2VuLgotICAgICAgICBjb3MtY3QtZXh0ZW5kcy4xLjQuMy4yLjIuMS5iID0gY29zLWN0LWV4dGVuZHMuMS40LjMuMi4yLjEuYjogSW5uZWhcdTAwRTVsbHN0eXAgZlx1MDBGNnIgaFx1MDBFNHJsZWRkIHR5cCBvY2ggZlx1MDBGNnIgYmFzZW4gbVx1MDBFNXN0ZSBiXHUwMEU1ZGEgdmFyYSBibGFuZGFkZSBlbGxlciBlbmRhc3QgZWxlbWVudC4gVHlwICcnezB9JycgXHUwMEU0ciBibGFuZGF0LCBtZW4gZFx1MDBFNHJlbW90IGludGUgYmFzZW4uCi0gICAgICAgIGNvcy1lbGVtZW50LWNvbnNpc3RlbnQgPSBjb3MtZWxlbWVudC1jb25zaXN0ZW50OiBFdHQgZmVsIGludHJcdTAwRTRmZmFkZSBmXHUwMEY2ciB0eXAgJyd7MH0nJy4gRmxlcmEgZWxlbWVudCBtZWQgbmFtbmV0ICcnezF9JycsIG1lZCBvbGlrYSB0eXBlciwgaGFyIGFuZ2V0dHMgaSBtb2RlbGxncnVwcGVuLgotICAgICAgICBjb3MtbGlzdC1vZi1hdG9taWMgPSBjb3MtbGlzdC1vZi1hdG9taWM6IEkgZGVmaW5pdGlvbmVuIGF2IGxpc3R0eXAgJyd7MH0nJyBcdTAwRTRyIHR5cCAnJ3sxfScnIGVuIG9naWx0aWcgdHlwIGF2IGxpc3RlbGVtZW50IGVmdGVyc29tIGRlbiBpbnRlIFx1MDBFNHIgYXRvbWlzayAoJyd7MX0nJyBcdTAwRTRyIGFudGluZ2VuIGVuIGxpc3R0eXAgZWxsZXIgZW4gdW5pb250eXAgc29tIGlubmVoXHUwMEU1bGxlciBlbiBsaXN0YSkuCi0gICAgICAgIGNvcy1ub25hbWJpZyA9IGNvcy1ub25hbWJpZzogezB9IG9jaCB7MX0gKGVsbGVyIGVsZW1lbnQgZnJcdTAwRTVuIGVyc1x1MDBFNHR0bmluZ3NncnVwcGVuKSBicnl0ZXIgbW90ICJVbmlxdWUgUGFydGljbGUgQXR0cmlidXRpb24iLiBEZXR0YSBza2FwYXIgdHZldHlkaWdoZXQgZlx1MDBGNnIgcGFydGlrbGFybmEgdmlkIHZhbGlkZXJpbmcgZ2VudGVtb3QgZGV0dGEgc2NoZW1hLgotICAgICAgICBjb3MtcGFydGljbGUtcmVzdHJpY3QuYSA9IGNvcy1wYXJ0aWNsZS1yZXN0cmljdC5hOiBIXHUwMEU0cmxlZGQgcGFydGlrZWwgXHUwMEU0ciB0b20gb2NoIGJhc2VuIFx1MDBFNHIgaW50ZSB0XHUwMEY2bW5pbmdzYmFyLgotICAgICAgICBjb3MtcGFydGljbGUtcmVzdHJpY3QuYiA9IGNvcy1wYXJ0aWNsZS1yZXN0cmljdC5iOiBCYXNwYXJ0aWtlbG4gXHUwMEU0ciB0b20sIG1lbiBkZW4gaFx1MDBFNHJsZWRkYSBwYXJ0aWtlbG4gXHUwMEU0ciBpbnRlIGRldC4KLSAgICAgICAgY29zLXBhcnRpY2xlLXJlc3RyaWN0LjIgPSBjb3MtcGFydGljbGUtcmVzdHJpY3QuMjogRlx1MDBGNnJianVkZW4gcGFydGlrZWxiZWdyXHUwMEU0bnNuaW5nOiAnJ3swfScnLgotICAgICAgICBjb3Mtc3QtcmVzdHJpY3RzLjEuMSA9IGNvcy1zdC1yZXN0cmljdHMuMS4xOiBUeXAgJyd7MX0nJyBcdTAwRTRyIGF0b21pc2sgb2NoIGRcdTAwRTRyZlx1MDBGNnIgbVx1MDBFNXN0ZSAneydiYXN0eXBkZWZpbml0aW9uZW4nfScsICcnezB9JycsIGFuZ2VzIHNvbSBhdG9taXNrIGVua2VsIHR5cCBlbGxlciBpbmJ5Z2dkIHByaW1pdGl2IGRhdGF0eXAuCi0gICAgICAgIGNvcy1zdC1yZXN0cmljdHMuMi4xID0gY29zLXN0LXJlc3RyaWN0cy4yLjE6IEkgZGVmaW5pdGlvbmVuIGF2IGxpc3R0eXAgJyd7MH0nJyBcdTAwRTRyIHR5cCAnJ3sxfScnIGVuIG9naWx0aWcgb2JqZWt0dHlwIGVmdGVyc29tIGRldCBcdTAwRTRyIGFudGluZ2VuIGVuIGxpc3R0eXAgZWxsZXIgZW4gdW5pb250eXAgc29tIGlubmVoXHUwMEU1bGxlciBlbiBsaXN0YS4KLSAgICAgICAgY29zLXN0LXJlc3RyaWN0cy4yLjMuMS4xID0gY29zLXN0LXJlc3RyaWN0cy4yLjMuMS4xOiBEZW4gJ3snc2lzdGEnfScga29tcG9uZW50ZW4gaSAneydvYmpla3R0eXBkZWZpbml0aW9uZW4nfScsICcnezB9JycsIGlubmVoXHUwMEU1bGxlciAnJ2xpc3QnJy4gRGV0dGEgYmV0eWRlciBhdHQgJyd7MH0nJyBpbnRlIGthbiBhbnZcdTAwRTRuZGFzIHNvbSBvYmpla3R0eXAgZlx1MDBGNnIgbGlzdHR5cCAnJ3sxfScnLgotICAgICAgICBjb3Mtc3QtcmVzdHJpY3RzLjMuMy4xLjEgPSBjb3Mtc3QtcmVzdHJpY3RzLjMuMy4xLjE6IERlbiAneydzaXN0YSd9JyBrb21wb25lbnRlbiBpICd7J21lZGxlbXR5cGRlZmluaXRpb25lcm5hJ30nLCAnJ3swfScnLCBpbm5laFx1MDBFNWxsZXIgJyd1bmlvbicnLiBEZXR0YSBiZXR5ZGVyIGF0dCAnJ3swfScnIGludGUga2FuIGFudlx1MDBFNG5kYXMgc29tIG1lZGxlbXN0eXAgZlx1MDBGNnIgdW5pb250eXAgJyd7MX0nJy4KLSAgICAgICAgY29zLXZhbGlkLWRlZmF1bHQuMi4xID0gY29zLXZhbGlkLWRlZmF1bHQuMi4xOiBFbGVtZW50ZXQgJyd7MH0nJyBoYXIgZW4gdlx1MDBFNHJkZWJlZ3JcdTAwRTRuc25pbmcgb2NoIG1cdTAwRTVzdGUgaGEgZW4gYmxhbmRhZCBlbGxlciBlbmtlbCBpbm5laFx1MDBFNWxsc21vZGVsbC4KLSAgICAgICAgY29zLXZhbGlkLWRlZmF1bHQuMi4yLjIgPSBjb3MtdmFsaWQtZGVmYXVsdC4yLjIuMjogRWZ0ZXJzb20gZWxlbWVudGV0ICcnezB9JycgaGFyIGVuICd7J3ZcdTAwRTRyZGViZWdyXHUwMEU0bnNuaW5nJ30nIG9jaCB0eXBkZWZpbml0aW9uZW4gaGFyIGJsYW5kYWQgJ3snaW5uZWhcdTAwRTVsbHN0eXAnfScgc1x1MDBFNSBtXHUwMEU1c3RlIHBhcnRpa2VsbiBhdiAneydpbm5laFx1MDBFNWxsc3R5cCd9JyB2YXJhIHRcdTAwRjZtbmluZ3NiYXIuCi0gICAgICAgIGMtcHJvcHMtY29ycmVjdC4yID0gYy1wcm9wcy1jb3JyZWN0LjI6IEthcmRpbmFsaXRldCBhdiBmXHUwMEU0bHQgbWVkIG55Y2tlbHJlZmVyZW5zICcnezB9Jycgb2NoIG55Y2tlbCAnJ3sxfScnIG1cdTAwRTVzdGUgbWF0Y2hhIHZhcmFuZHJhLgotICAgICAgICBjdC1wcm9wcy1jb3JyZWN0LjMgPSBjdC1wcm9wcy1jb3JyZWN0LjM6IENpcmt1bFx1MDBFNHJhIGRlZmluaXRpb25lciBoYXIgaWRlbnRpZmllcmF0cyBmXHUwMEY2ciBrb21wbGV4IHR5cCAnJ3swfScnLiBEZXR0YSBpbm5lYlx1MDBFNHIgYXR0ICcnezB9JycgaW5nXHUwMEU1ciBpIHNpbiBlZ2VuIHR5cGhpZXJhcmtpLCB2aWxrZXQgXHUwMEU0ciBmZWwuCi0gICAgICAgIGN0LXByb3BzLWNvcnJlY3QuNCA9IGN0LXByb3BzLWNvcnJlY3QuNDogRXR0IGZlbCBpbnRyXHUwMEU0ZmZhZGUgZlx1MDBGNnIgdHlwICcnezB9JycuIER1cGxpY2VyYWQgYXR0cmlidXRhbnZcdTAwRTRuZG5pbmcgbWVkIHNhbW1hIG5hbW4gb2NoIG5hbW5yeW1kLiBOYW1uZXQgcFx1MDBFNSBkdWJibGV0dGVuIFx1MDBFNHIgJyd7MX0nJy4KLSAgICAgICAgY3QtcHJvcHMtY29ycmVjdC41ID0gY3QtcHJvcHMtY29ycmVjdC41OiBFdHQgZmVsIGludHJcdTAwRTRmZmFkZSBmXHUwMEY2ciB0eXAgJyd7MH0nJy4gVHZcdTAwRTUgYXR0cmlidXRkZWtsYXJhdGlvbmVyLCAnJ3sxfScnIG9jaCAnJ3syfScnLCBhbnZcdTAwRTRuZHMgbWVkIHR5cGVyIHNvbSBoXHUwMEU0cmxlZHMgZnJcdTAwRTVuIElELgotICAgICAgICBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjEgPSBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjE6IFR5cCAnJ3swfScnIGhcdTAwRTRybGVkZGVzIGdlbm9tIGJlZ3JcdTAwRTRuc25pbmcgZnJcdTAwRTVuIHR5cCAnJ3sxfScnLiAnJ3sxfScnIGhhciBkXHUwMEU0cmVtb3QgZW4gJ3snc2x1dGxpZyd9JyBlZ2Vuc2thcCBzb20gZlx1MDBGNnJianVkZXIgaFx1MDBFNHJsZWRuaW5nIHZpYSBiZWdyXHUwMEU0bnNuaW5nLgotICAgICAgICBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjIuMS4xID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4yLjEuMTogRXR0IGZlbCBpbnRyXHUwMEU0ZmZhZGUgZlx1MDBGNnIgdHlwICcnezB9JycuIEF0dHJpYnV0YW52XHUwMEU0bmRuaW5nICcnezF9JycgaSBkZW5uYSB0eXAgaGFyICcndXNlJyctdlx1MDBFNHJkZXQgJyd7Mn0nJyB2aWxrZXQgaW50ZSBcdTAwRTRyIGtvbnNla3ZlbnQgbWVkIHZcdTAwRTRyZGV0IGZcdTAwRjZyICcncmVxdWlyZWQnJyBpIG1hdGNoYW5kZSBhdHRyaWJ1dGFudlx1MDBFNG5kbmluZyBpIGJhc3R5cGVuLgotICAgICAgICBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjIuMS4yID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4yLjEuMjogRXR0IGZlbCBpbnRyXHUwMEU0ZmZhZGUgZlx1MDBGNnIgdHlwICcnezB9JycuIEF0dHJpYnV0YW52XHUwMEU0bmRuaW5nICcnezF9JycgaSBkZW5uYSB0eXAgaGFyIHR5cCAnJ3syfScnLCBzb20gaW50ZSBmXHUwMEU1ciBoXHUwMEU0cmxlZGFzIGZyXHUwMEU1biAnJ3szfScnLCB0eXAgaSBtYXRjaGFuZGUgYXR0cmlidXRhbnZcdTAwRTRuZG5pbmcgaSBiYXN0eXBlbi4KLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4yLjEuMy5hID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4yLjEuMy5hOiBFdHQgZmVsIGludHJcdTAwRTRmZmFkZSBmXHUwMEY2ciB0eXAgJyd7MH0nJy4gQXR0cmlidXRhbnZcdTAwRTRuZG5pbmcgJyd7MX0nJyBpIGRlbm5hIHR5cCBoYXIgZW4gZWZmZWt0aXYgdlx1MDBFNHJkZWJlZ3JcdTAwRTRuc25pbmcgc29tIGludGUgXHUwMEU0ciBmYXN0LCBtZWRhbiBkZW4gZWZmZWt0aXZhIHZcdTAwRTRyZGViZWdyXHUwMEU0bnNuaW5nZW4gaSBtYXRjaGFuZGUgYXR0cmlidXRhbnZcdTAwRTRuZG5pbmcgaSBiYXN0eXBlbiBcdTAwRTRyIGZhc3QuCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMi4xLjMuYiA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMi4xLjMuYjogRXR0IGZlbCBpbnRyXHUwMEU0ZmZhZGUgZlx1MDBGNnIgdHlwICcnezB9JycuIEF0dHJpYnV0YW52XHUwMEU0bmRuaW5nICcnezF9JycgaSBkZW5uYSB0eXAgaGFyIGVuIGVmZmVrdGl2IHZcdTAwRTRyZGViZWdyXHUwMEU0bnNuaW5nIG1lZCBkZXQgZmFzdGEgdlx1MDBFNHJkZXQgJyd7Mn0nJywgdmlsa2V0IGludGUgXHUwMEU0ciBrb25zZWt2ZW50IG1lZCB2XHUwMEU0cmRldCAnJ3szfScnIGZcdTAwRjZyIGRlbiBmYXN0YSBlZmZla3RpdmEgdlx1MDBFNHJkZWJlZ3JcdTAwRTRuc25pbmdlbiBmXHUwMEY2ciBtYXRjaGFuZGUgYXR0cmlidXRhbnZcdTAwRTRuZG5pbmcgaSBiYXN0eXBlbi4KLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4yLjIuYSA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMi4yLmE6IEV0dCBmZWwgaW50clx1MDBFNGZmYWRlIGZcdTAwRjZyIHR5cCAnJ3swfScnLiBBdHRyaWJ1dGFudlx1MDBFNG5kbmluZyAnJ3sxfScnIGkgZGVubmEgdHlwIGhhciBpbnRlIG5cdTAwRTVnb24gbWF0Y2hhbmRlIGF0dHJpYnV0YW52XHUwMEU0bmRuaW5nIGkgYmFzZW4gb2NoIGJhc3R5cGVuIHNha25hciBqb2tlcnRlY2tlbmF0dHJpYnV0LgotICAgICAgICBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjIuMi5iID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4yLjIuYjogRXR0IGZlbCBpbnRyXHUwMEU0ZmZhZGUgZlx1MDBGNnIgdHlwICcnezB9JycuIEF0dHJpYnV0YW52XHUwMEU0bmRuaW5nICcnezF9JycgaSBkZW5uYSB0eXAgaGFyIGludGUgblx1MDBFNWdvbiBtYXRjaGFuZGUgYXR0cmlidXRhbnZcdTAwRTRuZG5pbmcgaSBiYXNlbiBvY2ggbmFtbnJ5bWRlbiAnJ3syfScnIGkgZGVubmEgYXR0cmlidXRhbnZcdTAwRTRuZG5pbmcgdGlsbFx1MDBFNXRzIGludGUgYXYgam9rZXJ0ZWNrbmV0IGkgYmFzdHlwZW4uCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMyA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMzogRXR0IGZlbCBpbnRyXHUwMEU0ZmZhZGUgZlx1MDBGNnIgdHlwICcnezB9JycuIEF0dHJpYnV0YW52XHUwMEU0bmRuaW5nICcnezF9JycgaSBiYXN0eXBlbiBoYXIgUkVRVUlSRUQgYW5naXZldCBzb20gdHJ1ZSwgbWVuIGRldCBmaW5ucyBpbmdlbiBtYXRjaGFuZGUgYXR0cmlidXRhbnZcdTAwRTRuZG5pbmcgaSBoXHUwMEU0cmxlZGQgdHlwLgotICAgICAgICBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjQuMSA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uNC4xOiBFdHQgZmVsIGludHJcdTAwRTRmZmFkZSBmXHUwMEY2ciB0eXBlbiAnJ3swfScnLiBIXHUwMEU0cmxlZG5pbmdlbiBoYXIgZXR0IGF0dHJpYnV0am9rZXJ0ZWNrZW4sIG1lbiBtb3RzdmFyYW5kZSBpIGJhc2VuIHNha25hcy4KLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi40LjIgPSBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjQuMjogRXR0IGZlbCBpbnRyXHUwMEU0ZmZhZGUgZlx1MDBGNnIgdHlwZW4gJyd7MH0nJy4gSm9rZXJ0ZWNrbmV0IGkgaFx1MDBFNHJsZWRuaW5nZW4gXHUwMEU0ciBpbnRlIG5cdTAwRTVnb24gZ2lsdGlnIGpva2VydGVja2VuZGVsIHNvbSBtb3RzdmFyYXIgZGV0IGkgYmFzZW4uCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uNC4zID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi40LjM6IEV0dCBmZWwgaW50clx1MDBFNGZmYWRlIGZcdTAwRjZyIHR5cCAnJ3swfScnLiBQcm9jZXNzaW5uZWhcdTAwRTVsbGV0IGZcdTAwRjZyIGpva2VydGVja2VuIGkgaFx1MDBFNHJsZWRuaW5nICh7MX0pIFx1MDBFNHIgc3ZhZ2FyZSBcdTAwRTRuIGRldCBpIGJhc2VuICh7Mn0pLgotICAgICAgICBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjUuMi4yLjEgPSBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjUuMi4yLjE6IEV0dCBmZWwgaW50clx1MDBFNGZmYWRlIGZcdTAwRjZyIHR5cCAnJ3swfScnLiBEZW4gZW5rbGEgaW5uZWhcdTAwRTVsbHN0eXBlbiBmXHUwMEY2ciBkZW5uYSB0eXAsICcnezF9JycsIFx1MDBFNHIgaW50ZSBuXHUwMEU1Z29uIGdpbHRpZyBiZWdyXHUwMEU0bnNuaW5nIGF2IGRlbiBlbmtsYSBpbm5laFx1MDBFNWxsc3R5cGVuIGZcdTAwRjZyIGJhc2VuLCAnJ3syfScnLgotICAgICAgICBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjUuMy4yID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi41LjMuMjogRXR0IGZlbCBpbnRyXHUwMEU0ZmZhZGUgZlx1MDBGNnIgdHlwICcnezB9JycuIElubmVoXHUwMEU1bGxzdHlwZW4gZlx1MDBGNnIgZGVubmEgdHlwIFx1MDBFNHIgdG9tLCBtZW4gaW5uZWhcdTAwRTVsbHN0eXBlbiBmXHUwMEY2ciBiYXNlbiwgJyd7MX0nJywgXHUwMEU0ciBpbnRlIHRvbSBlbGxlciB0XHUwMEY2bW5pbmdzYmFyLgotICAgICAgICBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjUuNC4xLjIgPSBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjUuNC4xLjI6IEV0dCBmZWwgaW50clx1MDBFNGZmYWRlIGZcdTAwRjZyIHR5cCAnJ3swfScnLiBJbm5laFx1MDBFNWxsc3R5cGVuIGZcdTAwRjZyIGRlbm5hIHR5cCBcdTAwRTRyIGJsYW5kYWQsIG1lZGFuIGlubmVoXHUwMEU1bGxzdHlwZW4gZlx1MDBGNnIgYmFzZW4sICcnezF9JycsIGludGUgXHUwMEU0ciBkZXQuCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uNS40LjIgPSBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjUuNC4yOiBFdHQgZmVsIGludHJcdTAwRTRmZmFkZSBmXHUwMEY2ciB0eXAgJyd7MH0nJy4gVHlwcGFydGlrZWxuIFx1MDBFNHIgaW50ZSBuXHUwMEU1Z29uIGdpbHRpZyBiZWdyXHUwMEU0bnNuaW5nIGZcdTAwRjZyIHBhcnRpa2VsbiBpIGJhc2VuLgotICAgICAgICBlbnVtZXJhdGlvbi1yZXF1aXJlZC1ub3RhdGlvbiA9IGVudW1lcmF0aW9uLXJlcXVpcmVkLW5vdGF0aW9uOiBOT1RBVElPTi10eXAsICcnezB9JycgYW52XHUwMEU0bmRzIGF2IHsyfSAnJ3sxfScnLCBtXHUwMEU1c3RlIGFuZ2VzIG1lZCB1cHByXHUwMEU0a25pbmdzYXNwZWt0dlx1MDBFNHJkZSBzb20gc3BlY2lmaWNlcmFyIGRlIG5vdGF0aW9uc2VsZW1lbnQgc29tIGFudlx1MDBFNG5kcyBhdiBkZW5uYSB0eXAuCi0gICAgICAgIGVudW1lcmF0aW9uLXZhbGlkLXJlc3RyaWN0aW9uID0gZW51bWVyYXRpb24tdmFsaWQtcmVzdHJpY3Rpb246IFVwcHJcdTAwRTRrbmluZ3N2XHUwMEU0cmRldCAnJ3swfScnIGZpbm5zIGludGUgaSBiYXN0eXBlbnMsIHsxfSwgdlx1MDBFNHJkZXV0cnltbWUuCi0gICAgICAgIGUtcHJvcHMtY29ycmVjdC4yID0gZS1wcm9wcy1jb3JyZWN0LjI6IE9naWx0aWd0IHZcdTAwRTRyZGUgZlx1MDBGNnIgYmVnclx1MDBFNG5zbmluZ3N2XHUwMEU0cmRlICcnezF9JycgaSBlbGVtZW50ZXQgJyd7MH0nJy4KLSAgICAgICAgZS1wcm9wcy1jb3JyZWN0LjQgPSBlLXByb3BzLWNvcnJlY3QuNDogJ3snVHlwZGVmaW5pdGlvbid9JyBmXHUwMEY2ciBlbGVtZW50ZXQgJyd7MH0nJyBoYXIgZW4gb2dpbHRpZyBoXHUwMEU0cmxlZG5pbmcgZnJcdTAwRTVuICd7J3R5cGRlZmluaXRpb25lbid9JyBmXHUwMEY2ciBzdWJzdGl0dXRpb25IZWFkICcnezF9JycgZWxsZXIgc1x1MDBFNSB0aWxsXHUwMEU1dHMgaW50ZSBkZW5uYSBoXHUwMEU0cmxlZG5pbmcgYXYgZWdlbnNrYXBlbiAnJ3sxfScnIGZcdTAwRjZyICd7J2Vyc1x1MDBFNHR0bmluZ3NncnVwcGV4a2x1ZGVyaW5nYXInfScuCi0gICAgICAgIGUtcHJvcHMtY29ycmVjdC41ID0gZS1wcm9wcy1jb3JyZWN0LjU6IEVuICd7J3ZcdTAwRTRyZGViZWdyXHUwMEU0bnNuaW5nJ30nIGZcdTAwRTVyIGludGUgZmlubmFzIG1lZCBpIGVsZW1lbnRldCAnJ3swfScnIGVmdGVyc29tIGVsZW1lbnRldHMgJ3sndHlwZGVmaW5pdGlvbid9JyBlbGxlciAneyd0eXBkZWZpbml0aW9uZW5zJ30nICd7J2lubmVoXHUwMEU1bGxzdHlwJ30nIFx1MDBFNHIgSUQsIGVsbGVyIGhcdTAwRTRybGVkcyBmclx1MDBFNW4gSUQuCi0gICAgICAgIGUtcHJvcHMtY29ycmVjdC42ID0gZS1wcm9wcy1jb3JyZWN0LjY6IENpcmt1bFx1MDBFNHIgZXJzXHUwMEU0dHRuaW5nc2dydXBwIGlkZW50aWZpZXJhZGVzIGZcdTAwRjZyIGVsZW1lbnRldCAnJ3swfScnLgotICAgICAgICBmcmFjdGlvbkRpZ2l0cy12YWxpZC1yZXN0cmljdGlvbiA9IGZyYWN0aW9uRGlnaXRzLXZhbGlkLXJlc3RyaWN0aW9uOiBJIGRlZmluaXRpb25lbiBmXHUwMEY2ciB7Mn0gXHUwMEU0ciB2XHUwMEU0cmRldCAnJ3swfScnIGZcdTAwRjZyICcnZnJhY3Rpb25EaWdpdHMnJyBvZ2lsdGlndCBlZnRlcnNvbSBkZXQgbVx1MDBFNXN0ZSB2YXJhIG1pbmRyZSBcdTAwRTRuIGVsbGVyIGxpa2EgbWVkIHZcdTAwRTRyZGV0IGZcdTAwRjZyICcnZnJhY3Rpb25EaWdpdHMnJyBzb20gaGFyIGFuZ2V0dHMgc29tICcnezF9JycgaSBuXHUwMEU1Z29uIHR5cCBmXHUwMEY2ciBcdTAwRjZ2ZXJvcmRuYWQuCi0gICAgICAgIGZyYWN0aW9uRGlnaXRzLXRvdGFsRGlnaXRzID0gZnJhY3Rpb25EaWdpdHMtdG90YWxEaWdpdHM6IEkgZGVmaW5pdGlvbmVuIGF2IHsyfSBcdTAwRTRyIHZcdTAwRTRyZGV0ICcnezB9JycgZlx1MDBGNnIgJydmcmFjdGlvbkRpZ2l0cycnIG9naWx0aWd0IGVmdGVyc29tIHZcdTAwRTRyZGV0IG1cdTAwRTVzdGUgdmFyYSBtaW5kcmUgXHUwMEU0biBlbGxlciBsaWthIG1lZCB2XHUwMEU0cmRldCBmXHUwMEY2ciAnJ3RvdGFsRGlnaXRzJycgc29tIFx1MDBFNHIgJyd7MX0nJy4KLSAgICAgICAgbGVuZ3RoLW1pbkxlbmd0aC1tYXhMZW5ndGguMS4xID0gbGVuZ3RoLW1pbkxlbmd0aC1tYXhMZW5ndGguMS4xOiBWaWQgYW52XHUwMEU0bmRuaW5nIGF2IHR5cCB7MH0gXHUwMEU0ciBkZXQgZmVsIG9tIGxcdTAwRTRuZ2R2XHUwMEU0cmRldCAnJ3sxfScnIFx1MDBFNHIgbWluZHJlIFx1MDBFNG4gdlx1MDBFNHJkZXQgZlx1MDBGNnIgbWluTGVuZ3RoICcnezJ9JycuCi0gICAgICAgIGxlbmd0aC1taW5MZW5ndGgtbWF4TGVuZ3RoLjEuMi5hID0gbGVuZ3RoLW1pbkxlbmd0aC1tYXhMZW5ndGguMS4yLmE6IFZpZCBhbnZcdTAwRTRuZG5pbmcgYXYgdHlwIHswfSBcdTAwRTRyIGRldCBmZWwgb20gYmFzZW4gaW50ZSBoYXIgZW4gbWluTGVuZ3RoLWFzcGVrdCBuXHUwMEU0ciBha3R1ZWxsIGJlZ3JcdTAwRTRuc25pbmcgaGFyIG1pbkxlbmd0aC1hc3Bla3Qgb2NoIGFrdHVlbGwgYmVnclx1MDBFNG5zbmluZyBlbGxlciBiYXMgaGFyIGFuZ2V0dHMgbWVkIGxcdTAwRTRuZ2Rhc3Bla3QuCi0gICAgICAgIGxlbmd0aC1taW5MZW5ndGgtbWF4TGVuZ3RoLjEuMi5iID0gbGVuZ3RoLW1pbkxlbmd0aC1tYXhMZW5ndGguMS4yLmI6IFZpZCBhbnZcdTAwRTRuZG5pbmcgYXYgdHlwIHswfSBcdTAwRTRyIGRldCBmZWwgb20gYWt0dWVsbCBtaW5MZW5ndGggJyd7MX0nJyBpbnRlIFx1MDBFNHIgbGlrYSBtZWQgYmFzZW4gbWluTGVuZ3RoICcnezJ9JycuCi0gICAgICAgIGxlbmd0aC1taW5MZW5ndGgtbWF4TGVuZ3RoLjIuMSA9IGxlbmd0aC1taW5MZW5ndGgtbWF4TGVuZ3RoLjIuMTogVmlkIGFudlx1MDBFNG5kbmluZyBhdiB0eXAgezB9IFx1MDBFNHIgZGV0IGZlbCBvbSBsXHUwMEU0bmdkdlx1MDBFNHJkZXQgJyd7MX0nJyBcdTAwRTRyIHN0XHUwMEY2cnJlIFx1MDBFNG4gdlx1MDBFNHJkZXQgZlx1MDBGNnIgbWF4TGVuZ3RoICcnezJ9JycuCi0gICAgICAgIGxlbmd0aC1taW5MZW5ndGgtbWF4TGVuZ3RoLjIuMi5hID0gbGVuZ3RoLW1pbkxlbmd0aC1tYXhMZW5ndGguMi4yLmE6IFZpZCBhbnZcdTAwRTRuZG5pbmcgYXYgdHlwIHswfSBcdTAwRTRyIGRldCBmZWwgb20gYmFzZW4gaW50ZSBoYXIgZW4gbWF4TGVuZ3RoLWFzcGVrdCBuXHUwMEU0ciBha3R1ZWxsIGJlZ3JcdTAwRTRuc25pbmcgaGFyIG1heExlbmd0aC1hc3Bla3Qgb2NoIGFrdHVlbGwgYmVnclx1MDBFNG5zbmluZyBlbGxlciBiYXMgaGFyIGFuZ2V0dHMgbWVkIGxcdTAwRTRuZ2Rhc3Bla3QuCi0gICAgICAgIGxlbmd0aC1taW5MZW5ndGgtbWF4TGVuZ3RoLjIuMi5iID0gbGVuZ3RoLW1pbkxlbmd0aC1tYXhMZW5ndGguMi4yLmI6IFZpZCBhbnZcdTAwRTRuZG5pbmcgYXYgdHlwIHswfSBcdTAwRTRyIGRldCBmZWwgb20gYWt0dWVsbCBtYXhMZW5ndGggJyd7MX0nJyBpbnRlIFx1MDBFNHIgbGlrYSBtZWQgYmFzZW4gbWF4TGVuZ3RoICcnezJ9JycuCi0gICAgICAgIGxlbmd0aC12YWxpZC1yZXN0cmljdGlvbiA9IGxlbmd0aC12YWxpZC1yZXN0cmljdGlvbjogRXR0IGZlbCBpbnRyXHUwMEU0ZmZhZGUgZlx1MDBGNnIgdHlwICcnezJ9JycuIExcdTAwRTRuZ2R2XHUwMEU0cmRldCAnJ3swfScnIG1cdTAwRTVzdGUgdmFyYSBsaWthIG1lZCB2XHUwMEU0cmRldCBmXHUwMEY2ciBiYXN0eXAgJyd7MX0nJy4KLSAgICAgICAgbWF4RXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjEgPSBtYXhFeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMTogRXR0IGZlbCBpbnRyXHUwMEU0ZmZhZGUgZlx1MDBGNnIgdHlwICcnezJ9JycuIG1heEV4Y2x1c2l2ZS12XHUwMEU0cmRldCAnJ3swfScnIG1cdTAwRTVzdGUgdmFyYSBtaW5kcmUgXHUwMEU0biBlbGxlciBsaWthIG1lZCBtYXhFeGNsdXNpdmUgaSBiYXN0eXAgJyd7MX0nJy4KLSAgICAgICAgbWF4RXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjIgPSBtYXhFeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMjogRXR0IGZlbCBpbnRyXHUwMEU0ZmZhZGUgZlx1MDBGNnIgdHlwICcnezJ9JycuIG1heEV4Y2x1c2l2ZS12XHUwMEU0cmRldCAnJ3swfScnIG1cdTAwRTVzdGUgdmFyYSBtaW5kcmUgXHUwMEU0biBlbGxlciBsaWthIG1lZCBtYXhJbmNsdXNpdmUgaSBiYXN0eXAgJyd7MX0nJy4KLSAgICAgICAgbWF4RXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjMgPSBtYXhFeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMzogRXR0IGZlbCBpbnRyXHUwMEU0ZmZhZGUgZlx1MDBGNnIgdHlwICcnezJ9JycuIG1heEV4Y2x1c2l2ZS12XHUwMEU0cmRldCAnJ3swfScnIG1cdTAwRTVzdGUgdmFyYSBzdFx1MDBGNnJyZSBcdTAwRTRuIG1pbkluY2x1c2l2ZSBpIGJhc3R5cCAnJ3sxfScnLgotICAgICAgICBtYXhFeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uNCA9IG1heEV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi40OiBFdHQgZmVsIGludHJcdTAwRTRmZmFkZSBmXHUwMEY2ciB0eXAgJyd7Mn0nJy4gbWF4RXhjbHVzaXZlLXZcdTAwRTRyZGV0ICcnezB9JycgbVx1MDBFNXN0ZSB2YXJhIHN0XHUwMEY2cnJlIFx1MDBFNG4gbWluRXhjbHVzaXZlIGkgYmFzdHlwICcnezF9JycuCi0gICAgICAgIG1heEluY2x1c2l2ZS1tYXhFeGNsdXNpdmUgPSBtYXhJbmNsdXNpdmUtbWF4RXhjbHVzaXZlOiBEZXQgXHUwMEU0ciBmZWwgb20gYlx1MDBFNWRlIG1heEluY2x1c2l2ZSBvY2ggbWF4RXhjbHVzaXZlIGFuZ2VzIGZcdTAwRjZyIHNhbW1hIGRhdGF0eXAuIEkgezJ9IFx1MDBFNHIgbWF4SW5jbHVzaXZlICcnezB9Jycgb2NoIG1heEV4Y2x1c2l2ZSAnJ3sxfScnLgotICAgICAgICBtYXhJbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMSA9IG1heEluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4xOiBFdHQgZmVsIGludHJcdTAwRTRmZmFkZSBmXHUwMEY2ciB0eXAgJyd7Mn0nJy4gbWF4SW5jbHVzaXZlLXZcdTAwRTRyZGV0ICcnezB9JycgbVx1MDBFNXN0ZSB2YXJhIG1pbmRyZSBcdTAwRTRuIGVsbGVyIGxpa2EgbWVkIG1heEluY2x1c2l2ZSBpIGJhc3R5cCAnJ3sxfScnLgotICAgICAgICBtYXhJbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMiA9IG1heEluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4yOiBFdHQgZmVsIGludHJcdTAwRTRmZmFkZSBmXHUwMEY2ciB0eXAgJyd7Mn0nJy4gbWF4SW5jbHVzaXZlLXZcdTAwRTRyZGV0ICcnezB9JycgbVx1MDBFNXN0ZSB2YXJhIG1pbmRyZSBcdTAwRTRuIG1heEV4Y2x1c2l2ZSBpIGJhc3R5cCAnJ3sxfScnLgotICAgICAgICBtYXhJbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMyA9IG1heEluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4zOiBFdHQgZmVsIGludHJcdTAwRTRmZmFkZSBmXHUwMEY2ciB0eXAgJyd7Mn0nJy4gbWF4SW5jbHVzaXZlLXZcdTAwRTRyZGV0ICcnezB9JycgbVx1MDBFNXN0ZSB2YXJhIHN0XHUwMEY2cnJlIFx1MDBFNG4gZWxsZXIgbGlrYSBtZWQgbWluSW5jbHVzaXZlIGkgYmFzdHlwICcnezF9JycuCi0gICAgICAgIG1heEluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi40ID0gbWF4SW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjQ6IEV0dCBmZWwgaW50clx1MDBFNGZmYWRlIGZcdTAwRjZyIHR5cCAnJ3syfScnLiBtYXhJbmNsdXNpdmUtdlx1MDBFNHJkZXQgJyd7MH0nJyBtXHUwMEU1c3RlIHZhcmEgc3RcdTAwRjZycmUgXHUwMEU0biBtaW5FeGNsdXNpdmUgaSBiYXN0eXAgJyd7MX0nJy4KLSAgICAgICAgbWF4TGVuZ3RoLXZhbGlkLXJlc3RyaWN0aW9uID0gbWF4TGVuZ3RoLXZhbGlkLXJlc3RyaWN0aW9uOiBJIGRlZmluaXRpb25lbiBmXHUwMEY2ciB7Mn0gbVx1MDBFNXN0ZSBtYXhMZW5ndGgtdlx1MDBFNHJkZXQgJyd7MH0nJyB2YXJhIG1pbmRyZSBcdTAwRTRuIGVsbGVyIGxpa2EgbWVkIHZcdTAwRTRyZGV0IGkgYmFzdHlwICcnezF9JycuCi0gICAgICAgIG1nLXByb3BzLWNvcnJlY3QuMiA9IG1nLXByb3BzLWNvcnJlY3QuMjogQ2lya3VsXHUwMEU0cmEgZGVmaW5pdGlvbmVyIGlkZW50aWZpZXJhZGVzIGZcdTAwRjZyIGdydXBwZW4gJyd7MH0nJy4gUmVrdXJzaXZ0IGVmdGVyZlx1MDBGNmxqYW5kZSB2XHUwMEU0cmRlbmEgZlx1MDBGNnIgJ3sndGVybSd9JyBpIHBhcnRpa2xhcm5hIGxlZGVyIHRpbGwgZW4gcGFydGlrZWwgdmFycyAneyd0ZXJtJ30nIFx1MDBFNHIgZGVuIHVyc3BydW5nbGlnYSBncnVwcGVuLgotICAgICAgICBtaW5FeGNsdXNpdmUtbGVzcy10aGFuLWVxdWFsLXRvLW1heEV4Y2x1c2l2ZSA9IG1pbkV4Y2x1c2l2ZS1sZXNzLXRoYW4tZXF1YWwtdG8tbWF4RXhjbHVzaXZlOiBJIGRlZmluaXRpb25lbiBmXHUwMEY2ciB7Mn0gbVx1MDBFNXN0ZSBtaW5FeGNsdXNpdmUtdlx1MDBFNHJkZXQgJyd7MH0nJyB2YXJhIG1pbmRyZSBcdTAwRTRuIGVsbGVyIGxpa2EgbWVkIG1heEV4Y2x1c2l2ZS12XHUwMEU0cmRldCAnJ3sxfScnLgotICAgICAgICBtaW5FeGNsdXNpdmUtbGVzcy10aGFuLW1heEluY2x1c2l2ZSA9IG1pbkV4Y2x1c2l2ZS1sZXNzLXRoYW4tbWF4SW5jbHVzaXZlOiBJIGRlZmluaXRpb25lbiBmXHUwMEY2ciB7Mn0gbVx1MDBFNXN0ZSBtaW5FeGNsdXNpdmUtdlx1MDBFNHJkZXQgJyd7MH0nJyB2YXJhIG1pbmRyZSBcdTAwRTRuIG1heEluY2x1c2l2ZS12XHUwMEU0cmRldCAnJ3sxfScnLgotICAgICAgICBtaW5FeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMSA9IG1pbkV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4xOiBFdHQgZmVsIGludHJcdTAwRTRmZmFkZSBmXHUwMEY2ciB0eXAgJyd7Mn0nJy4gbWluRXhjbHVzaXZlLXZcdTAwRTRyZGV0ICcnezB9JycgbVx1MDBFNXN0ZSB2YXJhIHN0XHUwMEY2cnJlIFx1MDBFNG4gZWxsZXIgbGlrYSBtZWQgbWluRXhjbHVzaXZlIGkgYmFzdHlwICcnezF9JycuCi0gICAgICAgIG1pbkV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4yID0gbWluRXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjI6IEV0dCBmZWwgaW50clx1MDBFNGZmYWRlIGZcdTAwRjZyIHR5cCAnJ3syfScnLiBtaW5FeGNsdXNpdmUtdlx1MDBFNHJkZXQgJyd7MH0nJyBtXHUwMEU1c3RlIHZhcmEgbWluZHJlIFx1MDBFNG4gZWxsZXIgbGlrYSBtZWQgbWF4SW5jbHVzaXZlIGkgYmFzdHlwICcnezF9JycuCi0gICAgICAgIG1pbkV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4zID0gbWluRXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjM6IEV0dCBmZWwgaW50clx1MDBFNGZmYWRlIGZcdTAwRjZyIHR5cCAnJ3syfScnLiBtaW5FeGNsdXNpdmUtdlx1MDBFNHJkZXQgJyd7MH0nJyBtXHUwMEU1c3RlIHZhcmEgc3RcdTAwRjZycmUgXHUwMEU0biBlbGxlciBsaWthIG1lZCBtaW5JbmNsdXNpdmUgaSBiYXN0eXAgJyd7MX0nJy4KLSAgICAgICAgbWluRXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjQgPSBtaW5FeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uNDogRXR0IGZlbCBpbnRyXHUwMEU0ZmZhZGUgZlx1MDBGNnIgdHlwICcnezJ9JycuIG1pbkV4Y2x1c2l2ZS12XHUwMEU0cmRldCAnJ3swfScnIG1cdTAwRTVzdGUgdmFyYSBtaW5kcmUgXHUwMEU0biBtYXhFeGNsdXNpdmUgaSBiYXN0eXAgJyd7MX0nJy4KLSAgICAgICAgbWluSW5jbHVzaXZlLWxlc3MtdGhhbi1lcXVhbC10by1tYXhJbmNsdXNpdmUgPSBtaW5JbmNsdXNpdmUtbGVzcy10aGFuLWVxdWFsLXRvLW1heEluY2x1c2l2ZTogSSBkZWZpbml0aW9uZW4gZlx1MDBGNnIgezJ9IG1cdTAwRTVzdGUgbWluSW5jbHVzaXZlLXZcdTAwRTRyZGV0ICcnezB9JycgdmFyYSBtaW5kcmUgXHUwMEU0biBlbGxlciBsaWthIG1lZCBtYXhJbmNsdXNpdmUtdlx1MDBFNHJkZXQgJyd7MX0nJy4KLSAgICAgICAgbWluSW5jbHVzaXZlLWxlc3MtdGhhbi1tYXhFeGNsdXNpdmUgPSBtaW5JbmNsdXNpdmUtbGVzcy10aGFuLW1heEV4Y2x1c2l2ZTogSSBkZWZpbml0aW9uZW4gZlx1MDBGNnIgezJ9IG1cdTAwRTVzdGUgbWluSW5jbHVzaXZlLXZcdTAwRTRyZGV0ICcnezB9JycgdmFyYSBtaW5kcmUgXHUwMEU0biBtYXhFeGNsdXNpdmUtdlx1MDBFNHJkZXQgJyd7MX0nJy4KLSAgICAgICAgbWluSW5jbHVzaXZlLW1pbkV4Y2x1c2l2ZSA9IG1pbkluY2x1c2l2ZS1taW5FeGNsdXNpdmU6IERldCBcdTAwRTRyIGZlbCBvbSBiXHUwMEU1ZGUgbWluSW5jbHVzaXZlIG9jaCBtaW5FeGNsdXNpdmUgYW5nZXMgZlx1MDBGNnIgc2FtbWEgZGF0YXR5cC4gSSB7Mn0gXHUwMEU0ciBtaW5JbmNsdXNpdmUgJyd7MH0nJyBvY2ggbWluRXhjbHVzaXZlICcnezF9JycuCi0gICAgICAgIG1pbkluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4xID0gbWluSW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjE6IEV0dCBmZWwgaW50clx1MDBFNGZmYWRlIGZcdTAwRjZyIHR5cCAnJ3syfScnLiBtaW5JbmNsdXNpdmUtdlx1MDBFNHJkZXQgJyd7MH0nJyBtXHUwMEU1c3RlIHZhcmEgc3RcdTAwRjZycmUgXHUwMEU0biBlbGxlciBsaWthIG1lZCBtaW5JbmNsdXNpdmUgaSBiYXN0eXAgJyd7MX0nJy4KLSAgICAgICAgbWluSW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjIgPSBtaW5JbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMjogRXR0IGZlbCBpbnRyXHUwMEU0ZmZhZGUgZlx1MDBGNnIgdHlwICcnezJ9JycuIG1pbkluY2x1c2l2ZS12XHUwMEU0cmRldCAnJ3swfScnIG1cdTAwRTVzdGUgdmFyYSBtaW5kcmUgXHUwMEU0biBlbGxlciBsaWthIG1lZCBtYXhJbmNsdXNpdmUgaSBiYXN0eXAgJyd7MX0nJy4KLSAgICAgICAgbWluSW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjMgPSBtaW5JbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMzogRXR0IGZlbCBpbnRyXHUwMEU0ZmZhZGUgZlx1MDBGNnIgdHlwICcnezJ9JycuIG1pbkluY2x1c2l2ZS12XHUwMEU0cmRldCAnJ3swfScnIG1cdTAwRTVzdGUgdmFyYSBzdFx1MDBGNnJyZSBcdTAwRTRuIG1pbkV4Y2x1c2l2ZSBpIGJhc3R5cCAnJ3sxfScnLgotICAgICAgICBtaW5JbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uNCA9IG1pbkluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi40OiBFdHQgZmVsIGludHJcdTAwRTRmZmFkZSBmXHUwMEY2ciB0eXAgJyd7Mn0nJy4gbWluSW5jbHVzaXZlLXZcdTAwRTRyZGV0ICcnezB9JycgbVx1MDBFNXN0ZSB2YXJhIG1pbmRyZSBcdTAwRTRuIG1heEV4Y2x1c2l2ZSBpIGJhc3R5cCAnJ3sxfScnLgotICAgICAgICBtaW5MZW5ndGgtbGVzcy10aGFuLWVxdWFsLXRvLW1heExlbmd0aCA9IG1pbkxlbmd0aC1sZXNzLXRoYW4tZXF1YWwtdG8tbWF4TGVuZ3RoOiBJIGRlZmluaXRpb25lbiBmXHUwMEY2ciB7Mn0gbVx1MDBFNXN0ZSBtaW5MZW5ndGgtdlx1MDBFNHJkZXQgJyd7MH0nJyB2YXJhIG1pbmRyZSBcdTAwRTRuIG1heExlbmd0aC12XHUwMEU0cmRldCAnJ3sxfScnLgotICAgICAgICBtaW5MZW5ndGgtdmFsaWQtcmVzdHJpY3Rpb24gPSBtaW5MZW5ndGgtdmFsaWQtcmVzdHJpY3Rpb246IEkgZGVmaW5pdGlvbmVuIGZcdTAwRjZyIHsyfSBtXHUwMEU1c3RlIG1pbkxlbmd0aC12XHUwMEU0cmRldCAnJ3swfScnIHZhcmEgc3RcdTAwRjZycmUgXHUwMEU0biBlbGxlciBsaWthIG1lZCB2XHUwMEU0cmRldCBpIGJhc3R5cCAnJ3sxfScnLgotICAgICAgICBuby14bWxucyA9IG5vLXhtbG5zOiBFdHQge25hbW59IHBcdTAwRTUgZW4gYXR0cmlidXRkZWtsYXJhdGlvbiBmXHUwMEU1ciBpbnRlIG1hdGNoYSAneG1sbnMnLgotICAgICAgICBuby14c2kgPSBuby14c2k6IEVuICAneydtXHUwMEU1bG5hbW5yeW1kJ30nIGkgZW4gYXR0cmlidXRkZWtsYXJhdGlvbiBmXHUwMEU1ciBpbnRlIG1hdGNoYSAnJ3swfScnLgotICAgICAgICBwLXByb3BzLWNvcnJlY3QuMi4xID0gcC1wcm9wcy1jb3JyZWN0LjIuMTogSSBkZWtsYXJhdGlvbmVuICcnezB9JycgXHUwMEU0ciB2XHUwMEU0cmRldCBmXHUwMEY2ciAnJ21pbk9jY3VycycnICcnezF9JycsIG1lbiBkZXQgZlx1MDBFNXIgaW50ZSB2YXJhIHN0XHUwMEY2cnJlIFx1MDBFNG4gdlx1MDBFNHJkZXQgZlx1MDBGNnIgJydtYXhPY2N1cnMnJyAoc29tIFx1MDBFNHIgJyd7Mn0nJykuCi0gICAgICAgIHJjYXNlLU1hcEFuZFN1bS4xID0gcmNhc2UtTWFwQW5kU3VtLjE6IERldCBmaW5ucyBpbmdlbiBmdWxsc3RcdTAwRTRuZGlndCBmdW5nZXJhbmRlIG1hcHBuaW5nIG1lbGxhbiBwYXJ0aWtsYXJuYS4KLSAgICAgICAgcmNhc2UtTWFwQW5kU3VtLjIgPSByY2FzZS1NYXBBbmRTdW0uMjogR3J1cHBlbnMgZlx1MDBGNnJla29tc3RpbnRlcnZhbGwgKHswfSx7MX0pIFx1MDBFNHIgaW50ZSBuXHUwMEU1Z29uIGdpbHRpZyBiZWdyXHUwMEU0bnNuaW5nIGZcdTAwRjZyIGJhc2dydXBwZW5zIGZcdTAwRjZyZWtvbXN0aW50ZXJ2YWxsLCAoezJ9LHszfSkuCi0gICAgICAgIHJjYXNlLU5hbWVBbmRUeXBlT0suMSA9IHJjYXNlLU5hbWVBbmRUeXBlT0suMTogRWxlbWVudCBoYXIgbmFtbiBvY2ggbVx1MDBFNWxuYW1ucnltZGVyIHNvbSBpbnRlIFx1MDBFNHIgZGVzYW1tYTogRWxlbWVudGV0ICcnezB9JycgaSBuYW1ucnltZCAnJ3sxfScnIG9jaCBlbGVtZW50ZXQgJyd7Mn0nJyBpIG5hbW5yeW1kICcnezN9JycuCi0gICAgICAgIHJjYXNlLU5hbWVBbmRUeXBlT0suMiA9IHJjYXNlLU5hbWVBbmRUeXBlT0suMjogRXR0IGZlbCBpbnRyXHUwMEU0ZmZhZGUgZlx1MDBGNnIgcGFydGlrZWxuIHZhcnMgJ3sndGVybSd9JyBcdTAwRTRyIGVsZW1lbnRkZWtsYXJhdGlvbmVuICcnezB9JycuIEVsZW1lbnRkZWtsYXJhdGlvbmVucyB2XHUwMEU0cmRlIHNvbSBcdTAwRTRyICd7J251bGxiYXJ0J30nIGhhciBhbmdldHRzIHNvbSB0cnVlLCBtZW4gbW90c3ZhcmFuZGUgcGFydGlrZWwgaSBiYXN0eXBlbiBoYXIgZW4gZWxlbWVudGRla2xhcmF0aW9uIHZhcnMgdlx1MDBFNHJkZSBzb20gXHUwMEU0ciAneydudWxsYmFydCd9JyBoYXIgYW5nZXR0cyBzb20gZmFsc2UuCi0gICAgICAgIHJjYXNlLU5hbWVBbmRUeXBlT0suMyA9IHJjYXNlLU5hbWVBbmRUeXBlT0suMzogRXR0IGZlbCBpbnRyXHUwMEU0ZmZhZGUgZlx1MDBGNnIgcGFydGlrZWxuIHZhcnMgICd7J3Rlcm0nfScgXHUwMEU0ciBlbGVtZW50ZGVrbGFyYXRpb25lbiAnJ3swfScnLiBGXHUwMEY2cmVrb21zdGludGVydmFsbGV0LCAoezF9LHsyfSksIFx1MDBFNHIgaW50ZSBuXHUwMEU1Z29uIGdpbHRpZyBiZWdyXHUwMEU0bnNuaW5nIGZcdTAwRjZyIGludGVydmFsbGV0LCAoezN9LHs0fSwgaSBtb3RzdmFyYW5kZSBwYXJ0aWtlbCBpIGJhc3R5cGVuLgotICAgICAgICByY2FzZS1OYW1lQW5kVHlwZU9LLjQuYSA9IHJjYXNlLU5hbWVBbmRUeXBlT0suNC5hOiBFbGVtZW50ZXQgJyd7MH0nJyBoYXIgaW50ZSBuXHUwMEU1Z290IGZhc3Qgdlx1MDBFNHJkZSwgbWVuIG1vdHN2YXJhbmRlIGVsZW1lbnQgaSBiYXN0eXBlbiBoYXIgYW5nZXR0cyBtZWQgZGV0IGZhc3RhIHZcdTAwRTRyZGV0ICcnezF9JycuCi0gICAgICAgIHJjYXNlLU5hbWVBbmRUeXBlT0suNC5iID0gcmNhc2UtTmFtZUFuZFR5cGVPSy40LmI6IEVsZW1lbnRldCAnJ3swfScnIGhhciBkZXQgZmFzdGEgdlx1MDBFNHJkZXQgJyd7MX0nJywgbWVuIG1vdHN2YXJhbmRlIGVsZW1lbnQgaSBiYXN0eXBlbiBoYXIgYW5nZXR0cyBtZWQgZGV0IGZhc3RhIHZcdTAwRTRyZGV0ICcnezJ9JycuCi0gICAgICAgIHJjYXNlLU5hbWVBbmRUeXBlT0suNSA9IHJjYXNlLU5hbWVBbmRUeXBlT0suNTogSWRlbnRpdGV0c2JlZ3JcdTAwRTRuc25pbmdhcm5hIGZcdTAwRjZyIGVsZW1lbnRldCAnJ3swfScnIFx1MDBFNHIgaW50ZSBuXHUwMEU1Z29uIGRlbCBhdiBkZSBzb20gZmlubnMgaSBiYXNlbi4KLSAgICAgICAgcmNhc2UtTmFtZUFuZFR5cGVPSy42ID0gcmNhc2UtTmFtZUFuZFR5cGVPSy42OiBEZSBhdmFrdGl2ZXJhZGUgZXJzXHUwMEU0dHRuaW5nYXJuYSBmXHUwMEY2ciBlbGVtZW50ZXQgJyd7MH0nJyBcdTAwRTRyIGludGUgaW5uZXNsdXRuYSBpIGJhc2VuLgotICAgICAgICByY2FzZS1OYW1lQW5kVHlwZU9LLjcgPSByY2FzZS1OYW1lQW5kVHlwZU9LLjc6IEVsZW1lbnR0eXAgJyd7MH0nJywgJyd7MX0nJyBoXHUwMEU0cmxlZHMgaW50ZSBmclx1MDBFNW4gdHlwIGF2IGJhc2VsZW1lbnQsICcnezJ9JycuCi0gICAgICAgIHJjYXNlLU5TQ29tcGF0LjEgPSByY2FzZS1OU0NvbXBhdC4xOiBFbGVtZW50ZXQgJyd7MH0nJyBoYXIgbmFtbnJ5bWRlbiAnJ3sxfScnIHNvbSBpbnRlIFx1MDBFNHIgdGlsbFx1MDBFNXRldCBhdiBqb2tlcnRlY2tuZXQgaSBiYXNlbi4KLSAgICAgICAgcmNhc2UtTlNDb21wYXQuMiA9IHJjYXNlLU5TQ29tcGF0LjI6IEV0dCBmZWwgaW50clx1MDBFNGZmYWRlIGZcdTAwRjZyIHBhcnRpa2VsbiB2YXJzICd7J3Rlcm0nfScgXHUwMEU0ciBlbGVtZW50ZGVrbGFyYXRpb25lbiAnJ3swfScnLiBGXHUwMEY2cmVrb21zdGludGVydmFsbGV0LCAoezF9LHsyfSksIFx1MDBFNHIgaW50ZSBuXHUwMEU1Z29uIGdpbHRpZyBiZWdyXHUwMEU0bnNuaW5nIGZcdTAwRjZyIGludGVydmFsbGV0LCAoezN9LHs0fSwgaSBtb3RzdmFyYW5kZSBwYXJ0aWtlbCBpIGJhc3R5cGVuLgotICAgICAgICByY2FzZS1OU1JlY3Vyc2VDaGVja0NhcmRpbmFsaXR5LjEgPSByY2FzZS1OU1JlY3Vyc2VDaGVja0NhcmRpbmFsaXR5LjE6IERldCBmaW5ucyBpbmdlbiBmdWxsc3RcdTAwRTRuZGlndCBmdW5nZXJhbmRlIG1hcHBuaW5nIG1lbGxhbiBwYXJ0aWtsYXJuYS4KLSAgICAgICAgcmNhc2UtTlNSZWN1cnNlQ2hlY2tDYXJkaW5hbGl0eS4yID0gcmNhc2UtTlNSZWN1cnNlQ2hlY2tDYXJkaW5hbGl0eS4yOiBHcnVwcGVucyBmXHUwMEY2cmVrb21zdGludGVydmFsbCAoezB9LHsxfSkgXHUwMEU0ciBpbnRlIG5cdTAwRTVnb24gZ2lsdGlnIGJlZ3JcdTAwRTRuc25pbmcgZlx1MDBGNnIgYmFzam9rZXJ0ZWNrbmV0cyBpbnRlcnZhbGwsICh7Mn0sezN9KS4KLSAgICAgICAgcmNhc2UtTlNTdWJzZXQuMSA9IHJjYXNlLU5TU3Vic2V0LjE6IEpva2VydGVja25ldCBcdTAwRTRyIGludGUgblx1MDBFNWdvbiBkZWwgYXYgbW90c3ZhcmFuZGUgam9rZXJ0ZWNrZW4gaSBiYXNlbi4KLSAgICAgICAgcmNhc2UtTlNTdWJzZXQuMiA9IHJjYXNlLU5TU3Vic2V0LjI6IEpva2VydGVja25ldHMgZlx1MDBGNnJla29tc3RpbnRlcnZhbGwgKHswfSx7MX0pLCBcdTAwRTRyIGludGUgblx1MDBFNWdvbiBnaWx0aWcgYmVnclx1MDBFNG5zbmluZyBzb20gbW90c3ZhcmFyIGRlbiBpIGJhc2VuLCAoezJ9LHszfSksLgotICAgICAgICByY2FzZS1OU1N1YnNldC4zID0gcmNhc2UtTlNTdWJzZXQuMzogSm9rZXJ0ZWNrbmV0cyBwcm9jZXNzaW5uZWhcdTAwRTVsbCwgJyd7MH0nJywgXHUwMEU0ciBzdmFnYXJlIFx1MDBFNG4gZGV0IGkgYmFzZW4sICcnezF9JycuCi0gICAgICAgIHJjYXNlLVJlY3Vyc2UuMSA9IHJjYXNlLVJlY3Vyc2UuMTogR3J1cHBlbnMgZlx1MDBGNnJla29tc3RpbnRlcnZhbGwgKHswfSx7MX0pIFx1MDBFNHIgaW50ZSBuXHUwMEU1Z29uIGdpbHRpZyBiZWdyXHUwMEU0bnNuaW5nIGZcdTAwRjZyIGJhc2dydXBwZW5zIGZcdTAwRjZyZWtvbXN0aW50ZXJ2YWxsLCAoezJ9LHszfSkuCi0gICAgICAgIHJjYXNlLVJlY3Vyc2UuMiA9IHJjYXNlLVJlY3Vyc2UuMjogRGV0IGZpbm5zIGluZ2VuIGZ1bGxzdFx1MDBFNG5kaWd0IGZ1bmdlcmFuZGUgbWFwcG5pbmcgbWVsbGFuIHBhcnRpa2xhcm5hLgotICAgICAgICByY2FzZS1SZWN1cnNlTGF4LjEgPSByY2FzZS1SZWN1cnNlTGF4LjE6IEdydXBwZW5zIGZcdTAwRjZyZWtvbXN0aW50ZXJ2YWxsICh7MH0sezF9KSBcdTAwRTRyIGludGUgblx1MDBFNWdvbiBnaWx0aWcgYmVnclx1MDBFNG5zbmluZyBmXHUwMEY2ciBiYXNncnVwcGVucyBmXHUwMEY2cmVrb21zdGludGVydmFsbCwgKHsyfSx7M30pLgotICAgICAgICByY2FzZS1SZWN1cnNlTGF4LjIgPSByY2FzZS1SZWN1cnNlTGF4LjI6IERldCBmaW5ucyBpbmdlbiBmdWxsc3RcdTAwRTRuZGlndCBmdW5nZXJhbmRlIG1hcHBuaW5nIG1lbGxhbiBwYXJ0aWtsYXJuYS4KLSAgICAgICAgcmNhc2UtUmVjdXJzZVVub3JkZXJlZC4xID0gcmNhc2UtUmVjdXJzZVVub3JkZXJlZC4xOiBHcnVwcGVucyBmXHUwMEY2cmVrb21zdGludGVydmFsbCAoezB9LHsxfSkgXHUwMEU0ciBpbnRlIG5cdTAwRTVnb24gZ2lsdGlnIGJlZ3JcdTAwRTRuc25pbmcgZlx1MDBGNnIgYmFzZ3J1cHBlbnMgZlx1MDBGNnJla29tc3RpbnRlcnZhbGwsICh7Mn0sezN9KS4KLSAgICAgICAgcmNhc2UtUmVjdXJzZVVub3JkZXJlZC4yID0gcmNhc2UtUmVjdXJzZVVub3JkZXJlZC4yOiBEZXQgZmlubnMgaW5nZW4gZnVsbHN0XHUwMEU0bmRpZ3QgZnVuZ2VyYW5kZSBtYXBwbmluZyBtZWxsYW4gcGFydGlrbGFybmEuCi0jICAgICAgICBXZSdyZSB1c2luZyBzY2gtcHJvcHMtY29ycmVjdC4yIGluc3RlYWQgb2YgdGhlIG9sZCBzcmMtcmVkZWZpbmUuMQotIyAgICAgICAgc3JjLXJlZGVmaW5lLjEgPSBzcmMtcmVkZWZpbmUuMTogVGhlIGNvbXBvbmVudCAnJ3swfScnIGlzIGJlZ2luIHJlZGVmaW5lZCwgYnV0IGl0cyBjb3JyZXNwb25kaW5nIGNvbXBvbmVudCBpc24ndCBpbiB0aGUgc2NoZW1hIGRvY3VtZW50IGJlaW5nIHJlZGVmaW5lZCAod2l0aCBuYW1lc3BhY2UgJyd7Mn0nJyksIGJ1dCBpbiBhIGRpZmZlcmVudCBkb2N1bWVudCwgd2l0aCBuYW1lc3BhY2UgJyd7MX0nJy4KLSAgICAgICAgc2NoLXByb3BzLWNvcnJlY3QuMiA9IHNjaC1wcm9wcy1jb3JyZWN0LjI6IEV0dCBzY2hlbWEga2FuIGludGUgaW5uZWhcdTAwRTVsbGEgdHZcdTAwRTUgZ2xvYmFsYSBrb21wb25lbnRlciBtZWQgc2FtbWEgbmFtbi4gRGV0dGEgc2NoZW1hIGhhciB0dlx1MDBFNSBmXHUwMEY2cmVrb21zdGVyIGF2ICcnezB9JycuCi0gICAgICAgIHN0LXByb3BzLWNvcnJlY3QuMiA9IHN0LXByb3BzLWNvcnJlY3QuMjogQ2lya3VsXHUwMEU0cmEgZGVmaW5pdGlvbmVyIGhhciBpZGVudGlmaWVyYXRzIGZcdTAwRjZyIGVua2VsIHR5cCAnJ3swfScnLiBEZXR0YSBpbm5lYlx1MDBFNHIgYXR0ICcnezB9JycgaW5nXHUwMEU1ciBpIHNpbiBlZ2VuIHR5cGhpZXJhcmtpLCB2aWxrZXQgXHUwMEU0ciBmZWwuCi0gICAgICAgIHN0LXByb3BzLWNvcnJlY3QuMyA9IHN0LXByb3BzLWNvcnJlY3QuMzogRXR0IGZlbCBpbnRyXHUwMEU0ZmZhZGUgZlx1MDBGNnIgdHlwICcnezB9JycuIFZcdTAwRTRyZGV0IGZcdTAwRjZyICd7J3NsdXRnaWx0aWd0J30nIGkgJ3snYmFzdHlwZGVmaW5pdGlvbmVuJ30nLCAnJ3sxfScnLCBmXHUwMEY2cmJqdWRlciBoXHUwMEU0cmxlZG5pbmcgbWVkIGJlZ3JcdTAwRTRuc25pbmcuCi0gICAgICAgIHRvdGFsRGlnaXRzLXZhbGlkLXJlc3RyaWN0aW9uID0gdG90YWxEaWdpdHMtdmFsaWQtcmVzdHJpY3Rpb246IEkgZGVmaW5pdGlvbmVuIGZcdTAwRjZyIHsyfSBcdTAwRTRyIHZcdTAwRTRyZGV0ICcnezB9JycgZlx1MDBGNnIgJyd0b3RhbERpZ2l0cycnIG9naWx0aWd0IGVmdGVyc29tIGRldCBtXHUwMEU1c3RlIHZhcmEgbWluZHJlIFx1MDBFNG4gZWxsZXIgbGlrYSBtZWQgdlx1MDBFNHJkZXQgZlx1MDBGNnIgJyd0b3RhbERpZ2l0cycnIHNvbSBoYXIgYW5nZXR0cyBzb20gJyd7MX0nJyBpIG5cdTAwRTVnb24gdHlwIGZcdTAwRjZyIFx1MDBGNnZlcm9yZG5hZC4KLSAgICAgICAgd2hpdGVTcGFjZS12YWxpZC1yZXN0cmljdGlvbi4xID0gd2hpdGVTcGFjZS12YWxpZC1yZXN0cmljdGlvbi4xOiBJIGRlZmluaXRpb25lbiBmXHUwMEY2ciB7MH0gXHUwMEU0ciB2XHUwMEU0cmRldCAnJ3sxfScnIGZcdTAwRjZyICcnd2hpdGVzcGFjZScnIG9naWx0aWd0LCBlZnRlcnNvbSB2XHUwMEU0cmRldCBmXHUwMEY2ciAnJ3doaXRlc3BhY2UnJyBoYXIgYW5nZXR0cyBzb20gJydjb2xsYXBzZScnIGkgblx1MDBFNWdvbiB0eXAgZlx1MDBGNnIgXHUwMEY2dmVyb3JkbmFkLgotICAgICAgICB3aGl0ZVNwYWNlLXZhbGlkLXJlc3RyaWN0aW9uLjIgPSB3aGl0ZVNwYWNlLXZhbGlkLXJlc3RyaWN0aW9uLjI6IEkgZGVmaW5pdGlvbmVuIGZcdTAwRjZyIHswfSBcdTAwRTRyIHZcdTAwRTRyZGV0ICcncHJlc2VydmUnJyBmXHUwMEY2ciAnJ3doaXRlc3BhY2UnJyBvZ2lsdGlndCwgZWZ0ZXJzb20gdlx1MDBFNHJkZXQgZlx1MDBGNnIgJyd3aGl0ZXNwYWNlJycgaGFyIGFuZ2V0dHMgc29tICcncmVwbGFjZScnIGkgblx1MDBFNWdvbiB0eXAgZlx1MDBGNnIgXHUwMEY2dmVyb3JkbmFkLgotCi0jc2NoZW1hIGZvciBTY2hlbWFzCi0KLSAgICAgICAgczRzLWF0dC1pbnZhbGlkLXZhbHVlID0gczRzLWF0dC1pbnZhbGlkLXZhbHVlOiBBdHRyaWJ1dHZcdTAwRTRyZGV0IGZcdTAwRjZyICcnezF9JycgaSBlbGVtZW50ZXQgJyd7MH0nJyBcdTAwRTRyIG9naWx0aWd0LiBSZWdpc3RyZXJhZCBvcnNhazogezJ9Ci0gICAgICAgIHM0cy1hdHQtbXVzdC1hcHBlYXIgPSBzNHMtYXR0LW11c3QtYXBwZWFyOiBBdHRyaWJ1dGV0ICcnezF9JycgbVx1MDBFNXN0ZSBhbmdlcyBpIGVsZW1lbnRldCAnJ3swfScnLgotICAgICAgICBzNHMtYXR0LW5vdC1hbGxvd2VkID0gczRzLWF0dC1ub3QtYWxsb3dlZDogQXR0cmlidXRldCAnJ3sxfScnIGZcdTAwRTVyIGludGUgYW5nZXMgaSBlbGVtZW50ZXQgJyd7MH0nJy4KLSAgICAgICAgczRzLWVsdC1pbnZhbGlkID0gczRzLWVsdC1pbnZhbGlkOiBFbGVtZW50ZXQgJyd7MH0nJyBcdTAwRTRyIGludGUgblx1MDBFNWdvdCBnaWx0aWd0IGVsZW1lbnQgaSBzY2hlbWFkb2t1bWVudC4KLSAgICAgICAgczRzLWVsdC1tdXN0LW1hdGNoLjEgPSBzNHMtZWx0LW11c3QtbWF0Y2guMTogSW5uZWhcdTAwRTVsbGV0IGkgJyd7MH0nJyBtXHUwMEU1c3RlIG1hdGNoYSB7MX0uIEV0dCBwcm9ibGVtIGhpdHRhZGVzIG1lZCBiXHUwMEY2cmphbiBmclx1MDBFNW46IHsyfS4KLSAgICAgICAgczRzLWVsdC1tdXN0LW1hdGNoLjIgPSBzNHMtZWx0LW11c3QtbWF0Y2guMjogSW5uZWhcdTAwRTVsbGV0IGkgJyd7MH0nJyBtXHUwMEU1c3RlIG1hdGNoYSB7MX0uIEhpdHRhZGUgaW50ZSB0aWxsclx1MDBFNGNrbGlndCBtZWQgZWxlbWVudC4KLSAgICAgICAgIyB0aGUgImludmFsaWQtY29udGVudCIgbWVzc2FnZXMgcHJvdmlkZSBsZXNzIGluZm9ybWF0aW9uIHRoYW4gdGhlICJtdXN0LW1hdGNoIiBjb3VudGVycGFydHMgYWJvdmUuIFRoZXkncmUgdXNlZCBmb3IgY29tcGxleCB0eXBlcyB3aGVuIHByb3ZpZGluZyBhICJtYXRjaCIgd291bGQgYmUgYW4gaW5mb3JtYXRpb24gZHVtcAotICAgICAgICBzNHMtZWx0LWludmFsaWQtY29udGVudC4xID0gczRzLWVsdC1pbnZhbGlkLWNvbnRlbnQuMTogSW5uZWhcdTAwRTVsbGV0IGkgJyd7MH0nJyBcdTAwRTRyIG9naWx0aWd0LiBFbGVtZW50ZXQgJyd7MX0nJyBcdTAwRTRyIG9naWx0aWd0LCBmZWxwbGFjZXJhdCBlbGxlciBoYXIgZlx1MDBGNnIgbVx1MDBFNW5nYSBmXHUwMEY2cmVrb21zdGVyLgotICAgICAgICBzNHMtZWx0LWludmFsaWQtY29udGVudC4yID0gczRzLWVsdC1pbnZhbGlkLWNvbnRlbnQuMjogSW5uZWhcdTAwRTVsbGV0IGkgJyd7MH0nJyBcdTAwRTRyIG9naWx0aWd0LiBFbGVtZW50ZXQgJyd7MX0nJyBtXHUwMEU1c3RlIGFuZ2VzLgotICAgICAgICBzNHMtZWx0LWludmFsaWQtY29udGVudC4zID0gczRzLWVsdC1pbnZhbGlkLWNvbnRlbnQuMzogRWxlbWVudCBhdiB0eXAgJyd7MH0nJyBrYW4gaW50ZSBhbmdlcyBlZnRlciBkZWtsYXJhdGlvbmVyIHNvbSB1bmRlciB1bmRlcm9yZG5hZGUgaSA8c2NoZW1hPmVsZW1lbnQuCi0gICAgICAgIHM0cy1lbHQtc2NoZW1hLW5zID0gczRzLWVsdC1zY2hlbWEtbnM6IE5hbW5yeW1kZW4gaSBlbGVtZW50ZXQgJyd7MH0nJyBtXHUwMEU1c3RlIGtvbW1hIGZyXHUwMEU1biBzY2hlbWF0cyBuYW1ucnltZCwgJydodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYScnLgotICAgICAgICBzNHMtZWx0LWNoYXJhY3RlciA9IHM0cy1lbHQtY2hhcmFjdGVyOiBUZWNrZW4gc29tIGludGUgXHUwMEU0ciBibGFua3RlY2tlbiB0aWxsXHUwMEU1dHMgaW50ZSBpIGFuZHJhIHNjaGVtYWVsZW1lbnQgXHUwMEU0biAnJ3hzOmFwcGluZm8nJyBvY2ggJyd4czpkb2N1bWVudGF0aW9uJycuIFVwcHRcdTAwRTRja3RlICcnezB9JycuCi0KLSMgY29kZXMgbm90IGRlZmluZWQgYnkgdGhlIHNwZWMKLQotICAgICAgICBjLWZpZWxkcy14cGF0aHMgPSBjLWZpZWxkcy14cGF0aHM6IEZcdTAwRTRsdHZcdTAwRTRyZGV0ID0gJyd7MH0nJyBcdTAwRTRyIG9naWx0aWd0LgotICAgICAgICBjLWdlbmVyYWwteHBhdGggPSBjLWdlbmVyYWwteHBhdGg6IFV0dHJ5Y2tldCAnJ3swfScnIFx1MDBFNHIgb2dpbHRpZ3QgbWVkIGRlbiBYUGF0aC1kZWxtXHUwMEU0bmdkIHNvbSBzdFx1MDBGNmRzIGkgWE1MLXNjaGVtYS4KLSAgICAgICAgYy1nZW5lcmFsLXhwYXRoLW5zID0gYy1nZW5lcmFsLXhwYXRoLW5zOiBFdHQgbmFtbnJ5bWRzcHJlZml4IGkgWFBhdGgtdXR0cnlja2V0ICcnezB9JycgdmFyIGludGUgYnVuZGV0IHRpbGwgblx1MDBFNWdvbiBuYW1ucnltZC4KLSAgICAgICAgYy1zZWxlY3Rvci14cGF0aCA9IGMtc2VsZWN0b3IteHBhdGg6IFZcdTAwRTRsamFydlx1MDBFNHJkZXQgJyd7MH0nJyBcdTAwRTRyIG9naWx0aWd0OyB4cGF0aCBmXHUwMEY2ciB2XHUwMEU0bGphcmUgZlx1MDBFNXIgaW50ZSBpbm5laFx1MDBFNWxsYSBhdHRyaWJ1dC4KLSAgICAgICAgRW1wdHlUYXJnZXROYW1lc3BhY2UgPSBFbXB0eVRhcmdldE5hbWVzcGFjZTogSSBzY2hlbWFkb2t1bWVudGV0ICcnezB9JycgZlx1MDBFNXIgdlx1MDBFNHJkZXQgZlx1MDBGNnIgYXR0cmlidXRldCAnJ3RhcmdldE5hbWVzcGFjZScnIGludGUgdmFyYSBlbiB0b20gc3RyXHUwMEU0bmcuCi0gICAgICAgIEZhY2V0VmFsdWVGcm9tQmFzZSA9IEZhY2V0VmFsdWVGcm9tQmFzZTogSSBkZWtsYXJhdGlvbmVuIGF2IHR5cCAnJ3swfScnIG1cdTAwRTVzdGUgdlx1MDBFNHJkZXQgJyd7MX0nJyBmXHUwMEY2ciBhc3Bla3QgJyd7Mn0nJyBrb21tYSBmclx1MDBFNW4gdlx1MDBFNHJkZXV0cnltbWV0IGkgYmFzdHlwZW4gJyd7M30nJy4KLSAgICAgICAgRml4ZWRGYWNldFZhbHVlID0gRml4ZWRGYWNldFZhbHVlOiBJIGRlZmluaXRpb25lbiBmXHUwMEY2ciB7M30gXHUwMEU0ciB2XHUwMEU0cmRldCAnJ3sxfScnIGZcdTAwRjZyIGFzcGVrdGVuICcnezB9Jycgb2dpbHRpZ3QgZWZ0ZXJzb20gdlx1MDBFNHJkZXQgZlx1MDBGNnIgJyd7MH0nJyBoYXIgYW5nZXR0cyBzb20gJyd7Mn0nJyBpIG5cdTAwRTVnb24gYXYgdHlwZXJuYSBmXHUwMEY2ciBcdTAwRjZ2ZXJvcmRuYWRlIHNhbXRpZGlndCBzb20gJ3snZmFzdCd9JyA9IHRydWUuCi0gICAgICAgIEludmFsaWRSZWdleCA9IEludmFsaWRSZWdleDogTVx1MDBGNm5zdGVydlx1MDBFNHJkZXQgJyd7MH0nJyBcdTAwRTRyIGludGUgblx1MDBFNWdvdCBnaWx0aWd0IHJlZ3Vsalx1MDBFNHJ0IHV0dHJ5Y2suIERldCByYXBwb3J0ZXJhZGUgZmVsZXQgXHUwMEU0cjogJyd7MX0nJyBpIGtvbHVtbiAnJ3syfScnLgotICAgICAgICBNYXhPY2N1ckxpbWl0ID0gRGVuIGFrdHVlbGxhIGtvbmZpZ3VyYXRpb25lbiBmXHUwMEY2ciBwYXJzZXJuIHRpbGxcdTAwRTV0ZXIgaW50ZSBhdHQgYXR0cmlidXR2XHUwMEU0cmRldCBmXHUwMEY2ciBPY2N1cnMgYW5nZXMgc29tIHN0XHUwMEY2cnJlIFx1MDBFNG4gdlx1MDBFNHJkZXQgezB9LgotICAgICAgICBQdWJsaWNTeXN0ZW1Pbk5vdGF0aW9uID0gUHVibGljU3lzdGVtT25Ob3RhdGlvbjogXHUwMEM1dG1pbnN0b25lIGV0dCBhdiAnJ3B1YmxpYycnIG9jaCAnJ3N5c3RlbScnIG1cdTAwRTVzdGUgYW5nZXMgaSBlbGVtZW50ZXRzICcnbm90YXRpb24nJy4KLSAgICAgICAgU2NoZW1hTG9jYXRpb24gPSBTY2hlbWFMb2NhdGlvbjogc2NoZW1hTG9jYXRpb24tdlx1MDBFNHJkZXQgJyd7MH0nJyBtXHUwMEU1c3RlIGFuZ2VzIG1lZCBldHQgalx1MDBFNG1udCBhbnRhbCBVUkk6ZXIuCi0gICAgICAgIFRhcmdldE5hbWVzcGFjZS4xID0gVGFyZ2V0TmFtZXNwYWNlLjE6IEZcdTAwRjZydlx1MDBFNG50YWRlIG5hbW5yeW1kZW4gJyd7MH0nJywgbWVuIG1cdTAwRTVsbmFtbnJ5bWRlbiBmXHUwMEY2ciBzY2hlbWFkb2t1bWVudGV0IFx1MDBFNHIgJyd7MX0nJy4KLSAgICAgICAgVGFyZ2V0TmFtZXNwYWNlLjIgPSBUYXJnZXROYW1lc3BhY2UuMjogRlx1MDBGNnJ2XHUwMEU0bnRhZGUgaW50ZSBuXHUwMEU1Z29uIG5hbW5yeW1kLCBtZW4gc2NoZW1hZG9rdW1lbnRldCBoYXIgYW5nZXR0cyBtZWQgbVx1MDBFNWxuYW1ucnltZGVuICcnezF9JycuCi0gICAgICAgIFVuZGVjbGFyZWRFbnRpdHkgPSBVbmRlY2xhcmVkRW50aXR5OiBFbmhldCAnJ3swfScnIGhhciBpbnRlIGRla2xhcmVyYXRzLgotICAgICAgICBVbmRlY2xhcmVkUHJlZml4ID0gVW5kZWNsYXJlZFByZWZpeDogS2FuIGludGUgbWF0Y2hhICcnezB9Jycgc29tIFFOYW1lOiBwcmVmaXhldCAnJ3sxfScnIGhhciBpbnRlIGRla2xhcmVyYXRzLgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MU2NoZW1hTWVzc2FnZXNfemhfQ04ucHJvcGVydGllcyBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hNTFNjaGVtYU1lc3NhZ2VzX3poX0NOLnByb3BlcnRpZXMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGMwNWFhY2MuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MU2NoZW1hTWVzc2FnZXNfemhfQ04ucHJvcGVydGllcworKysgL2Rldi9udWxsCkBAIC0xLDI5MSArMCwwIEBACi0jIFRoaXMgZmlsZSBjb250YWlucyBlcnJvciBhbmQgd2FybmluZyBtZXNzYWdlcyByZWxhdGVkIHRvIFhNTCBTY2hlbWEKLSMgVGhlIG1lc3NhZ2VzIGFyZSBhcnJhbmdlZCBpbiBrZXkgYW5kIHZhbHVlIHR1cGxlcyBpbiBhIExpc3RSZXNvdXJjZUJ1bmRsZS4KLSMKLQotICAgICAgICBCYWRNZXNzYWdlS2V5ID0gXHU2MjdFXHU0RTBEXHU1MjMwXHU0RTBFXHU2RDg4XHU2MDZGXHU1MTczXHU5NTJFXHU1QjU3XHU1QkY5XHU1RTk0XHU3Njg0XHU5NTE5XHU4QkVGXHU2RDg4XHU2MDZGXHUzMDAyCi0gICAgICAgIEZvcm1hdEZhaWxlZCA9IFx1OEJCRVx1N0Y2RVx1NEVFNVx1NEUwQlx1NkQ4OFx1NjA2Rlx1NzY4NFx1NjgzQ1x1NUYwRlx1NjVGNlx1NTFGQVx1NzNCMFx1NTE4NVx1OTBFOFx1OTUxOVx1OEJFRjpcbgotCi0jIEZvciBpbnRlcm5hbCB1c2UKLQotICAgICAgICBJbnRlcm5hbC1FcnJvciA9IFx1NTE4NVx1OTBFOFx1OTUxOVx1OEJFRjogezB9XHUzMDAyCi0gICAgICAgIGR0LXdoaXRlc3BhY2UgPSBcdTdBN0FcdTc2N0RcdTk3NjJcdTUwM0NcdTRFMERcdTUzRUZcdTc1MjhcdTRFOEVcdTgwNTRcdTU0MDggc2ltcGxlVHlwZSAnJ3swfScnCi0gICAgICAgIEdyYW1tYXJDb25mbGljdCA9IFx1NzUyOFx1NjIzN1x1NzY4NFx1OEJFRFx1NkNENVx1NkM2MFx1OEZENFx1NTZERVx1NzY4NFx1OEJFRFx1NkNENVx1NEU0Qlx1NEUwMFx1NEUwRVx1NTNFNlx1NEUwMFx1NEUyQVx1OEJFRFx1NkNENVx1NTFCMlx1N0E4MVx1MzAwMgotCi0jIElkZW50aXR5IGNvbnN0cmFpbnRzCi0KLSAgICAgICAgQWJzZW50S2V5VmFsdWUgPSBcdThFQUJcdTRFRkRcdTdFQTZcdTY3NUZcdTY3NjFcdTRFRjZcdTk1MTlcdThCRUYgKGN2Yy1pZGVudGl0eS1jb25zdHJhaW50LjQuMi4xKTogXHU1MTQzXHU3RDIwICJ7MH0iIFx1NzY4NFx1NEUwMFx1NEUyQVx1NTE3M1x1OTUyRVx1NUI1N1x1NkNBMVx1NjcwOVx1NTAzQ1x1MzAwMgotICAgICAgICBEdXBsaWNhdGVGaWVsZCA9IFx1NUI1N1x1NkJCNSAiezB9IiBcdTU3MjhcdTRGNUNcdTc1MjhcdTU3REZcdTUxODVcdTY3MDlcdTkxQ0RcdTU5MERcdTUzMzlcdTkxNERcdTMwMDIKLSAgICAgICAgRHVwbGljYXRlS2V5ID0gXHU0RTNBXHU1MTQzXHU3RDIwICJ7MX0iIFx1NzY4NFx1OEVBQlx1NEVGRFx1N0VBNlx1Njc1Rlx1Njc2MVx1NEVGNlx1NThGMFx1NjYwRVx1NzY4NFx1NTE3M1x1OTUyRVx1NUI1N1x1NTAzQyBbezB9XSBcdTkxQ0RcdTU5MERcdTMwMDIKLSAgICAgICAgRHVwbGljYXRlVW5pcXVlID0gXHU0RTNBXHU1MTQzXHU3RDIwICJ7MX0iIFx1NzY4NFx1OEVBQlx1NEVGRFx1N0VBNlx1Njc1Rlx1Njc2MVx1NEVGNlx1NThGMFx1NjYwRVx1NzY4NFx1NTUyRlx1NEUwMFx1NTAzQyBbezB9XSBcdTkxQ0RcdTU5MERcdTMwMDIKLSAgICAgICAgRmllbGRNdWx0aXBsZU1hdGNoID0gXHU4RUFCXHU0RUZEXHU3RUE2XHU2NzVGXHU2NzYxXHU0RUY2XHU5NTE5XHU4QkVGOiBcdTVCNTdcdTZCQjUgInswfSIgXHU0RTBFXHU1MTc2XHU5MDA5XHU2MkU5XHU1NjY4XHU0RjVDXHU3NTI4XHU1N0RGXHU1MTg1XHU3Njg0XHU1OTFBXHU0RTJBXHU1MDNDXHU1MzM5XHU5MTREOyBcdTVCNTdcdTZCQjVcdTVGQzVcdTk4N0JcdTRFMEVcdTU1MkZcdTRFMDBcdTUwM0NcdTUzMzlcdTkxNERcdTMwMDIKLSAgICAgICAgRml4ZWREaWZmZXJzRnJvbUFjdHVhbCA9IFx1NkI2NFx1NTE0M1x1N0QyMFx1NzY4NFx1NTE4NVx1NUJCOVx1NEUwRVx1NjVCOVx1Njg0OFx1NEUyRFx1NTE0M1x1N0QyMFx1NThGMFx1NjYwRVx1NzY4NCAiZml4ZWQiIFx1NUM1RVx1NjAyN1x1NzY4NFx1NTAzQ1x1NEUwRFx1NzZGOFx1NTQwQ1x1MzAwMgotICAgICAgICBLZXlNYXRjaGVzTmlsbGFibGUgPSBcdThFQUJcdTRFRkRcdTdFQTZcdTY3NUZcdTY3NjFcdTRFRjZcdTk1MTlcdThCRUYgKGN2Yy1pZGVudGl0eS1jb25zdHJhaW50LjQuMi4zKTogXHU1MTQzXHU3RDIwICJ7MH0iIFx1NTE3N1x1NjcwOVx1NEUwMFx1NEUyQVx1NEUwRSBuaWxsYWJsZSBcdThCQkVcdTdGNkVcdTRFM0FcdTIwMUNcdTc3MUZcdTIwMURcdTc2ODRcdTUxNDNcdTdEMjBcdTUzMzlcdTkxNERcdTc2ODRcdTUxNzNcdTk1MkVcdTVCNTdcdTMwMDIKLSAgICAgICAgS2V5Tm90RW5vdWdoVmFsdWVzID0gXHU1QkY5XHU0RThFXHU0RTNBXHU1MTQzXHU3RDIwICJ7MH0iIFx1NjMwN1x1NUI5QVx1NzY4NCA8a2V5IG5hbWU9InsxfSI+IFx1OEVBQlx1NEVGRFx1N0VBNlx1Njc1Rlx1Njc2MVx1NEVGNiwgXHU2Q0ExXHU2NzA5XHU0RTNBXHU1QjgzXHU2MzA3XHU1QjlBXHU4REIzXHU1OTFGXHU3Njg0XHU1MDNDXHUzMDAyCi0gICAgICAgIEtleU5vdEZvdW5kID0gXHU2Q0ExXHU2NzA5XHU0RTNBXHU1MTQzXHU3RDIwICcnezJ9JycgXHU3Njg0XHU4RUFCXHU0RUZEXHU3RUE2XHU2NzVGXHU2NzYxXHU0RUY2XHU2MjdFXHU1MjMwXHU1MDNDXHU0RTNBICcnezF9JycgXHU3Njg0XHU1MTczXHU5NTJFXHU1QjU3ICcnezB9JydcdTMwMDIKLSAgICAgICAgS2V5UmVmTm90RW5vdWdoVmFsdWVzID0gXHU1QkY5XHU0RThFXHU0RTNBXHU1MTQzXHU3RDIwICJ7MH0iIFx1NjMwN1x1NUI5QVx1NzY4NCA8a2V5cmVmIG5hbWU9InsxfSI+IFx1OEVBQlx1NEVGRFx1N0VBNlx1Njc1Rlx1Njc2MVx1NEVGNiwgXHU2Q0ExXHU2NzA5XHU0RTNBXHU1QjgzXHU2MzA3XHU1QjlBXHU4REIzXHU1OTFGXHU3Njg0XHU1MDNDXHUzMDAyCi0gICAgICAgIEtleVJlZk91dE9mU2NvcGUgPSBcdThFQUJcdTRFRkRcdTdFQTZcdTY3NUZcdTY3NjFcdTRFRjZcdTk1MTlcdThCRUY6IFx1OEVBQlx1NEVGRFx1N0VBNlx1Njc1Rlx1Njc2MVx1NEVGNiAiezB9IiBcdTUxNzdcdTY3MDlcdTRFMDBcdTRFMkFcdTVGMTVcdTc1MjhcdTRFODZcdTRGNUNcdTc1MjhcdTU3REZcdTRFNEJcdTU5MTZcdTc2ODRcdTUxNzNcdTk1MkVcdTVCNTdcdTYyMTZcdTU1MkZcdTRFMDBcdTUwM0NcdTc2ODQga2V5cmVmXHUzMDAyCi0gICAgICAgIEtleVJlZlJlZmVyTm90Rm91bmQgPSBcdTUxNzNcdTk1MkVcdTVCNTdcdTVGMTVcdTc1MjhcdTU4RjBcdTY2MEUgInswfSIgXHU1RjE1XHU3NTI4XHU0RTg2XHU1NDBEXHU0RTNBICJ7MX0iIFx1NzY4NFx1NjcyQVx1NzdFNVx1NTE3M1x1OTUyRVx1NUI1N1x1MzAwMgotICAgICAgICBVbmlxdWVOb3RFbm91Z2hWYWx1ZXMgPSBcdTVCRjlcdTRFOEVcdTRFM0FcdTUxNDNcdTdEMjAgInswfSIgXHU2MzA3XHU1QjlBXHU3Njg0IDx1bmlxdWU+IFx1OEVBQlx1NEVGRFx1N0VBNlx1Njc1Rlx1Njc2MVx1NEVGNiwgXHU2Q0ExXHU2NzA5XHU0RTNBXHU1QjgzXHU2MzA3XHU1QjlBXHU4REIzXHU1OTFGXHU3Njg0XHU1MDNDXHUzMDAyCi0gICAgICAgIFVua25vd25GaWVsZCA9IFx1NTE4NVx1OTBFOFx1OEVBQlx1NEVGRFx1N0VBNlx1Njc1Rlx1Njc2MVx1NEVGNlx1OTUxOVx1OEJFRjsgXHU1QjU3XHU2QkI1ICJ7MH0iIFx1NjcyQVx1NzdFNVx1MzAwMgotCi0jIElkZWFsbHksIHdlIHNob3VsZCBvbmx5IHVzZSB0aGUgZm9sbG93aW5nIGVycm9yIGtleXMsIG5vdCB0aGUgb25lcyB1bmRlcgotIyAiSWRlbnRpdHkgY29uc3RyYWludHMiLiBBbmQgd2Ugc2hvdWxkIGNvdmVyIGFsbCBvZiB0aGUgZm9sbG93aW5nIGVycm9ycy4KLQotI3ZhbGlkYXRpb24gKDMuWC40KQotCi0gICAgICAgIGN2Yy1hdHRyaWJ1dGUuMyA9IGN2Yy1hdHRyaWJ1dGUuMzogXHU1NzI4XHU1MTQzXHU3RDIwICcnezB9JycgXHU0RTJELCBcdTVDNUVcdTYwMjcgJyd7MX0nJyBcdTc2ODRcdTUwM0MgJyd7Mn0nJyBcdTRFMEVcdTUxNzZcdTdDN0JcdTU3OEIgJyd7M30nJyBcdTRFMERcdTUzMzlcdTkxNERcdTMwMDIKLSAgICAgICAgY3ZjLWF0dHJpYnV0ZS40ID0gY3ZjLWF0dHJpYnV0ZS40OiBcdTU3MjhcdTUxNDNcdTdEMjAgJyd7MH0nJyBcdTRFMkQsIFx1NUM1RVx1NjAyNyAnJ3sxfScnIFx1NzY4NFx1NTAzQyAnJ3syfScnIFx1NEUwRVx1NTE3Nlx1NTZGQVx1NUI5QVx1NzY4NCAneyd2YWx1ZSBjb25zdHJhaW50J30nIFx1NEUwRFx1NTMzOVx1OTE0RFx1MzAwMlx1OEJFNVx1NUM1RVx1NjAyN1x1NzY4NFx1NTAzQ1x1NUZDNVx1OTg3Qlx1NEUzQSAnJ3szfScnXHUzMDAyCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuMi4xID0gY3ZjLWNvbXBsZXgtdHlwZS4yLjE6IFx1NTE0M1x1N0QyMCAnJ3swfScnIFx1NUZDNVx1OTg3Qlx1NEUwRFx1NTQyQlx1NUI1N1x1N0IyNlx1NjIxNlx1NTE0M1x1N0QyMFx1NEZFMVx1NjA2Rlx1OTg3OSBbXHU1QjUwXHU3RUE3XSwgXHU1NkUwXHU0RTNBXHU4QkU1XHU3QzdCXHU1NzhCXHU3Njg0XHU1MTg1XHU1QkI5XHU3QzdCXHU1NzhCXHU0RTNBXHU3QTdBXHUzMDAyCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuMi4yID0gY3ZjLWNvbXBsZXgtdHlwZS4yLjI6IFx1NTE0M1x1N0QyMCAnJ3swfScnIFx1NUZDNVx1OTg3Qlx1NEUwRFx1NTQyQlx1NTE0M1x1N0QyMCBbXHU1QjUwXHU3RUE3XSwgXHU1RTc2XHU0RTE0XHU1MTc2XHU1MDNDXHU1RkM1XHU5ODdCXHU2NzA5XHU2NTQ4XHUzMDAyCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuMi4zID0gY3ZjLWNvbXBsZXgtdHlwZS4yLjM6IFx1NTE0M1x1N0QyMCAnJ3swfScnIFx1NUZDNVx1OTg3Qlx1NEUwRFx1NTQyQlx1NUI1N1x1N0IyNiBbXHU1QjUwXHU3RUE3XSwgXHU1NkUwXHU0RTNBXHU4QkU1XHU3QzdCXHU1NzhCXHU3Njg0XHU1MTg1XHU1QkI5XHU3QzdCXHU1NzhCXHU0RTNBXHUyMDFDXHU0RUM1XHU1MTQzXHU3RDIwXHUyMDFEXHUzMDAyCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuMi40LmEgPSBjdmMtY29tcGxleC10eXBlLjIuNC5hOiBcdTUzRDFcdTczQjBcdTRFODZcdTRFRTVcdTUxNDNcdTdEMjAgJyd7MH0nJyBcdTVGMDBcdTU5MzRcdTc2ODRcdTY1RTBcdTY1NDhcdTUxODVcdTVCQjlcdTMwMDJcdTVFOTRcdTRFRTUgJyd7MX0nJyBcdTRFNEJcdTRFMDBcdTVGMDBcdTU5MzRcdTMwMDIKLSAgICAgICAgY3ZjLWNvbXBsZXgtdHlwZS4yLjQuYiA9IGN2Yy1jb21wbGV4LXR5cGUuMi40LmI6IFx1NTE0M1x1N0QyMCAnJ3swfScnIFx1NzY4NFx1NTE4NVx1NUJCOVx1NEUwRFx1NUI4Q1x1NjU3NFx1MzAwMlx1NUU5NFx1NEUzQSAnJ3sxfScnIFx1NEU0Qlx1NEUwMFx1MzAwMgotICAgICAgICBjdmMtY29tcGxleC10eXBlLjIuNC5jID0gY3ZjLWNvbXBsZXgtdHlwZS4yLjQuYzogXHU5MDFBXHU5MTREXHU3QjI2XHU3Njg0XHU1MzM5XHU5MTREXHU1Rjg4XHU1MTY4XHU5NzYyLCBcdTRGNDZcdTY1RTBcdTZDRDVcdTYyN0VcdTUyMzBcdTUxNDNcdTdEMjAgJyd7MH0nJyBcdTc2ODRcdTU4RjBcdTY2MEVcdTMwMDIKLSAgICAgICAgY3ZjLWNvbXBsZXgtdHlwZS4yLjQuZCA9IGN2Yy1jb21wbGV4LXR5cGUuMi40LmQ6IFx1NTNEMVx1NzNCMFx1NEU4Nlx1NEVFNVx1NTE0M1x1N0QyMCAnJ3swfScnIFx1NUYwMFx1NTkzNFx1NzY4NFx1NjVFMFx1NjU0OFx1NTE4NVx1NUJCOVx1MzAwMlx1NkI2NFx1NTkwNFx1NEUwRFx1NUU5NFx1NTQyQlx1NjcwOVx1NUI1MFx1NTE0M1x1N0QyMFx1MzAwMgotICAgICAgICBjdmMtY29tcGxleC10eXBlLjIuNC5lID0gY3ZjLWNvbXBsZXgtdHlwZS4yLjQuZDogXHU1M0QxXHU3M0IwXHU0RTg2XHU0RUU1XHU1MTQzXHU3RDIwICcnezB9JycgXHU1RjAwXHU1OTM0XHU3Njg0XHU2NUUwXHU2NTQ4XHU1MTg1XHU1QkI5XHUzMDAyXHU2QjY0XHU1OTA0XHU0RTBEXHU1RTk0XHU1NDJCXHU2NzA5XHU1QjUwXHU1MTQzXHU3RDIwICcnezF9JydcdTMwMDIKLSAgICAgICAgY3ZjLWNvbXBsZXgtdHlwZS4zLjEgPSBjdmMtY29tcGxleC10eXBlLjMuMTogXHU1NzI4XHU1MTQzXHU3RDIwICcnezB9JycgXHU0RTJELCBcdTVDNUVcdTYwMjcgJyd7MX0nJyBcdTc2ODRcdTUwM0MgJyd7Mn0nJyBcdTRFMEVcdTc2RjhcdTVFOTRcdTc2ODRcdTVDNUVcdTYwMjdcdTc1MjhcdTZDRDVcdTRFMERcdTUzMzlcdTkxNERcdTMwMDJcdTVDNUVcdTYwMjcgJyd7MX0nJyBcdTUxNzdcdTY3MDlcdTU2RkFcdTVCOUFcdTUwM0MgJyd7M30nJ1x1MzAwMgotICAgICAgICBjdmMtY29tcGxleC10eXBlLjMuMi4xID0gY3ZjLWNvbXBsZXgtdHlwZS4zLjIuMTogXHU1MTQzXHU3RDIwICcnezB9JycgXHU2Q0ExXHU2NzA5XHU1QzVFXHU2MDI3ICcnezF9JycgXHU3Njg0XHU1QzVFXHU2MDI3XHU5MDFBXHU5MTREXHU3QjI2XHUzMDAyCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuMy4yLjIgPSBjdmMtY29tcGxleC10eXBlLjMuMi4yOiBcdTUxNDNcdTdEMjAgJyd7MH0nJyBcdTRFMkRcdTRFMERcdTUxNDFcdThCQjhcdTUxRkFcdTczQjBcdTVDNUVcdTYwMjcgJyd7MX0nJ1x1MzAwMgotICAgICAgICBjdmMtY29tcGxleC10eXBlLjQgPSBjdmMtY29tcGxleC10eXBlLjQ6IFx1NTE0M1x1N0QyMCAnJ3swfScnIFx1NEUyRFx1NUZDNVx1OTg3Qlx1NTMwNVx1NTQyQlx1NUM1RVx1NjAyNyAnJ3sxfScnXHUzMDAyCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuNS4xID0gY3ZjLWNvbXBsZXgtdHlwZS41LjE6IFx1NTcyOFx1NTE0M1x1N0QyMCAnJ3swfScnIFx1NEUyRCwgXHU1QzVFXHU2MDI3ICcnezF9JycgXHU2NjJGXHU0RTAwXHU0RTJBXHU5MDFBXHU3NTI4IElEXHUzMDAyXHU0RjQ2XHU1REYyXHU1QjU4XHU1NzI4XHU5MDFBXHU3NTI4IElEICcnezJ9JydcdTMwMDJcdTUzRUFcdTgwRkRcdTY3MDlcdTRFMDBcdTRFMkFcdTkwMUFcdTc1MjggSURcdTMwMDIKLSAgICAgICAgY3ZjLWNvbXBsZXgtdHlwZS41LjIgPSBjdmMtY29tcGxleC10eXBlLjUuMjogXHU1NzI4XHU1MTQzXHU3RDIwICcnezB9JycgXHU0RTJELCBcdTVDNUVcdTYwMjcgJyd7MX0nJyBcdTY2MkZcdTRFMDBcdTRFMkFcdTkwMUFcdTc1MjggSURcdTMwMDJcdTRGNDZcdTVERjJcdTY3MDlcdTRFMDBcdTRFMkFcdTVDNUVcdTYwMjcgJyd7Mn0nJyBcdTY2MkZcdTRFQ0UgJ3snYXR0cmlidXRlIHVzZXMnfScgXHU0RTJEXHU3Njg0IElEIFx1NkQzRVx1NzUxRlx1NzY4NFx1MzAwMgotICAgICAgICBjdmMtZGF0YXR5cGUtdmFsaWQuMS4yLjEgPSBjdmMtZGF0YXR5cGUtdmFsaWQuMS4yLjE6ICcnezB9JycgXHU0RTBEXHU2NjJGICcnezF9JycgXHU3Njg0XHU2NzA5XHU2NTQ4XHU1MDNDXHUzMDAyCi0gICAgICAgIGN2Yy1kYXRhdHlwZS12YWxpZC4xLjIuMiA9IGN2Yy1kYXRhdHlwZS12YWxpZC4xLjIuMjogJyd7MH0nJyBcdTRFMERcdTY2MkZcdTUyMTdcdTg4NjhcdTdDN0JcdTU3OEIgJyd7MX0nJyBcdTc2ODRcdTY3MDlcdTY1NDhcdTUwM0NcdTMwMDIKLSAgICAgICAgY3ZjLWRhdGF0eXBlLXZhbGlkLjEuMi4zID0gY3ZjLWRhdGF0eXBlLXZhbGlkLjEuMi4zOiAnJ3swfScnIFx1NEUwRFx1NjYyRlx1ODA1NFx1NTQwOFx1N0M3Qlx1NTc4QiAnJ3sxfScnIFx1NzY4NFx1NjcwOVx1NjU0OFx1NTAzQ1x1MzAwMgotICAgICAgICBjdmMtZWx0LjEgPSBjdmMtZWx0LjE6IFx1NjI3RVx1NEUwRFx1NTIzMFx1NTE0M1x1N0QyMCAnJ3swfScnIFx1NzY4NFx1NThGMFx1NjYwRVx1MzAwMgotICAgICAgICBjdmMtZWx0LjIgPSBjdmMtZWx0LjI6ICcnezB9JycgXHU3Njg0XHU1MTQzXHU3RDIwXHU1OEYwXHU2NjBFXHU0RTJEICd7J2Fic3RyYWN0J30nIFx1NzY4NFx1NTAzQ1x1NUZDNVx1OTg3Qlx1NEUzQVx1MjAxQ1x1NTA0N1x1MjAxRFx1MzAwMgotICAgICAgICBjdmMtZWx0LjMuMSA9IGN2Yy1lbHQuMy4xOiBcdTUxNDNcdTdEMjAgJyd7MH0nJyBcdTRFMkRcdTRFMERcdTgwRkRcdTUzMDVcdTU0MkJcdTVDNUVcdTYwMjcgJyd7MX0nJywgXHU1NkUwXHU0RTNBICcnezB9JycgXHU3Njg0ICd7J25pbGxhYmxlJ30nIFx1NUM1RVx1NjAyN1x1NEUzQVx1MjAxQ1x1NTA0N1x1MjAxRFx1MzAwMgotICAgICAgICBjdmMtZWx0LjMuMi4xID0gY3ZjLWVsdC4zLjIuMTogXHU1MTQzXHU3RDIwICcnezB9JycgXHU1RkM1XHU5ODdCXHU0RTBEXHU1NDJCXHU1QjU3XHU3QjI2XHU2MjE2XHU1MTQzXHU3RDIwXHU0RkUxXHU2MDZGIFtcdTVCNTBcdTdFQTddLCBcdTU2RTBcdTRFM0FcdTVERjJcdTYzMDdcdTVCOUEgJyd7MX0nJ1x1MzAwMgotICAgICAgICBjdmMtZWx0LjMuMi4yID0gY3ZjLWVsdC4zLjIuMjogXHU1MTQzXHU3RDIwICcnezB9JycgXHU0RTBEXHU4MEZEXHU1MzA1XHU1NDJCXHU1NkZBXHU1QjlBXHU3Njg0ICd7J3ZhbHVlIGNvbnN0cmFpbnQnfScsIFx1NTZFMFx1NEUzQVx1NURGMlx1NjMwN1x1NUI5QSAnJ3sxfScnXHUzMDAyCi0gICAgICAgIGN2Yy1lbHQuNC4xID0gY3ZjLWVsdC40LjE6IFx1NTE0M1x1N0QyMCAnJ3swfScnIFx1NzY4NFx1NUM1RVx1NjAyNyAnJ3sxfScnIFx1NzY4NFx1NTAzQyAnJ3syfScnIFx1NEUwRFx1NjYyRlx1NjcwOVx1NjU0OFx1NzY4NFx1OTY1MFx1NUI5QVx1NTQwRFx1MzAwMgotICAgICAgICBjdmMtZWx0LjQuMiA9IGN2Yy1lbHQuNC4yOiBcdTY1RTBcdTZDRDVcdTVDMDYgJyd7MX0nJyBcdTg5RTNcdTY3OTBcdTRFM0FcdTUxNDNcdTdEMjAgJyd7MH0nJyBcdTc2ODRcdTdDN0JcdTU3OEJcdTVCOUFcdTRFNDlcdTMwMDIKLSAgICAgICAgY3ZjLWVsdC40LjMgPSBjdmMtZWx0LjQuMzogXHU3QzdCXHU1NzhCICcnezF9JycgXHU0RTBEXHU2NjJGXHU0RUNFXHU1MTQzXHU3RDIwICcnezB9JycgXHU3Njg0XHU3QzdCXHU1NzhCXHU1QjlBXHU0RTQ5ICcnezJ9JycgXHU2NzA5XHU2NTQ4XHU2RDNFXHU3NTFGXHU3Njg0XHUzMDAyCi0gICAgICAgIGN2Yy1lbHQuNS4xLjEgPSBjdmMtZWx0LjUuMS4xOiBcdTUxNDNcdTdEMjAgJyd7MH0nJyBcdTc2ODQgJ3sndmFsdWUgY29uc3RyYWludCd9JyAnJ3syfScnIFx1NEUwRFx1NjYyRlx1N0M3Qlx1NTc4QiAnJ3sxfScnIFx1NzY4NFx1NjcwOVx1NjU0OFx1OUVEOFx1OEJBNFx1NTAzQ1x1MzAwMgotICAgICAgICBjdmMtZWx0LjUuMi4yLjEgPSBjdmMtZWx0LjUuMi4yLjE6IFx1NTE0M1x1N0QyMCAnJ3swfScnIFx1NUZDNVx1OTg3Qlx1NEUwRFx1NTQyQlx1NTE0M1x1N0QyMFx1NEZFMVx1NjA2Rlx1OTg3OSBbXHU1QjUwXHU3RUE3XVx1MzAwMgotICAgICAgICBjdmMtZWx0LjUuMi4yLjIuMSA9IGN2Yy1lbHQuNS4yLjIuMi4xOiBcdTUxNDNcdTdEMjAgJyd7MH0nJyBcdTc2ODRcdTUwM0MgJyd7MX0nJyBcdTRFMEVcdTU2RkFcdTVCOUFcdTc2ODQgJ3sndmFsdWUgY29uc3RyYWludCd9JyBcdTUwM0MgJyd7Mn0nJyBcdTRFMERcdTUzMzlcdTkxNERcdTMwMDIKLSAgICAgICAgY3ZjLWVsdC41LjIuMi4yLjIgPSBjdmMtZWx0LjUuMi4yLjIuMjogXHU1MTQzXHU3RDIwICcnezB9JycgXHU3Njg0XHU1MDNDICcnezF9JycgXHU0RTBFICd7J3ZhbHVlIGNvbnN0cmFpbnQnfScgXHU1MDNDICcnezJ9JycgXHU0RTBEXHU1MzM5XHU5MTREXHUzMDAyCi0gICAgICAgIGN2Yy1lbnVtZXJhdGlvbi12YWxpZCA9IGN2Yy1lbnVtZXJhdGlvbi12YWxpZDogXHU1QkY5XHU0RThFXHU2NzlBXHU0RTNFICcnezF9JycsIFx1NTAzQyAnJ3swfScnIFx1NEUwRFx1NTE3N1x1NjcwOVx1OTc2Mlx1NjcwOVx1NjU0OFx1NjAyN1x1MzAwMlx1NUI4M1x1NUZDNVx1OTg3Qlx1NjYyRlx1Njc2NVx1ODFFQVx1Njc5QVx1NEUzRVx1NzY4NFx1NTAzQ1x1MzAwMgotICAgICAgICBjdmMtZnJhY3Rpb25EaWdpdHMtdmFsaWQgPSBjdmMtZnJhY3Rpb25EaWdpdHMtdmFsaWQ6IFx1NTAzQyAnJ3swfScnIFx1NTE3N1x1NjcwOSB7MX0gXHU0RjREXHU1QzBGXHU2NTcwLCBcdTRGNDZcdTVDMEZcdTY1NzBcdTRGNERcdTY1NzBcdTVERjJcdTk2NTBcdTUyMzZcdTRFM0EgezJ9XHUzMDAyCi0gICAgICAgIGN2Yy1pZC4xID0gY3ZjLWlkLjE6IElEUkVGICcnezB9JycgXHU2Q0ExXHU2NzA5IElEL0lEUkVGIFx1N0VEMVx1NUI5QVx1MzAwMgotICAgICAgICBjdmMtaWQuMiA9IGN2Yy1pZC4yOiBJRCBcdTUwM0MgJyd7MH0nJyBcdTUxRkFcdTczQjBcdTRFODZcdTU5MUFcdTZCMjFcdTMwMDIKLSAgICAgICAgY3ZjLWlkLjMgPSBjdmMtaWQuMzogXHU4RUFCXHU0RUZEXHU3RUE2XHU2NzVGXHU2NzYxXHU0RUY2ICcnezB9JycgXHU3Njg0XHU1QjU3XHU2QkI1XHU0RTBFXHU1MTQzXHU3RDIwICcnezF9JycgXHU1MzM5XHU5MTRELCBcdTRGNDZcdTZCNjRcdTUxNDNcdTdEMjBcdTZDQTFcdTY3MDlcdTdCODBcdTUzNTVcdTdDN0JcdTU3OEJcdTMwMDIKLSAgICAgICAgY3ZjLWxlbmd0aC12YWxpZCA9IGN2Yy1sZW5ndGgtdmFsaWQ6IFx1NUJGOVx1NEU4RVx1N0M3Qlx1NTc4Qlx1NEUzQSAnJ3szfScnIFx1NzY4NCBsZW5ndGggJyd7Mn0nJywgbGVuZ3RoID0gJyd7MX0nJyBcdTc2ODRcdTUwM0MgJyd7MH0nJyBcdTRFMERcdTUxNzdcdTY3MDlcdTk3NjJcdTY3MDlcdTY1NDhcdTYwMjdcdTMwMDIKLSAgICAgICAgY3ZjLW1heEV4Y2x1c2l2ZS12YWxpZCA9IGN2Yy1tYXhFeGNsdXNpdmUtdmFsaWQ6IFx1NUJGOVx1NEU4RVx1N0M3Qlx1NTc4Qlx1NEUzQSAnJ3syfScnIFx1NzY4NCBtYXhFeGNsdXNpdmUgJyd7MX0nJywgXHU1MDNDICcnezB9JycgXHU0RTBEXHU1MTc3XHU2NzA5XHU5NzYyXHU2NzA5XHU2NTQ4XHU2MDI3XHUzMDAyCi0gICAgICAgIGN2Yy1tYXhJbmNsdXNpdmUtdmFsaWQgPSBjdmMtbWF4SW5jbHVzaXZlLXZhbGlkOiBcdTVCRjlcdTRFOEVcdTdDN0JcdTU3OEJcdTRFM0EgJyd7Mn0nJyBcdTc2ODQgbWF4SW5jbHVzaXZlICcnezF9JycsIFx1NTAzQyAnJ3swfScnIFx1NEUwRFx1NTE3N1x1NjcwOVx1OTc2Mlx1NjcwOVx1NjU0OFx1NjAyN1x1MzAwMgotICAgICAgICBjdmMtbWF4TGVuZ3RoLXZhbGlkID0gY3ZjLW1heExlbmd0aC12YWxpZDogXHU1QkY5XHU0RThFXHU3QzdCXHU1NzhCXHU0RTNBICcnezN9JycgXHU3Njg0IG1heExlbmd0aCAnJ3syfScnLCBsZW5ndGggPSAnJ3sxfScnIFx1NzY4NFx1NTAzQyAnJ3swfScnIFx1NEUwRFx1NTE3N1x1NjcwOVx1OTc2Mlx1NjcwOVx1NjU0OFx1NjAyN1x1MzAwMgotICAgICAgICBjdmMtbWluRXhjbHVzaXZlLXZhbGlkID0gY3ZjLW1pbkV4Y2x1c2l2ZS12YWxpZDogXHU1QkY5XHU0RThFXHU3QzdCXHU1NzhCXHU0RTNBICcnezJ9JycgXHU3Njg0IG1pbkV4Y2x1c2l2ZSAnJ3sxfScnLCBcdTUwM0MgJyd7MH0nJyBcdTRFMERcdTUxNzdcdTY3MDlcdTk3NjJcdTY3MDlcdTY1NDhcdTYwMjdcdTMwMDIKLSAgICAgICAgY3ZjLW1pbkluY2x1c2l2ZS12YWxpZCA9IGN2Yy1taW5JbmNsdXNpdmUtdmFsaWQ6IFx1NUJGOVx1NEU4RVx1N0M3Qlx1NTc4Qlx1NEUzQSAnJ3syfScnIFx1NzY4NCBtaW5JbmNsdXNpdmUgJyd7MX0nJywgXHU1MDNDICcnezB9JycgXHU0RTBEXHU1MTc3XHU2NzA5XHU5NzYyXHU2NzA5XHU2NTQ4XHU2MDI3XHUzMDAyCi0gICAgICAgIGN2Yy1taW5MZW5ndGgtdmFsaWQgPSBjdmMtbWluTGVuZ3RoLXZhbGlkOiBcdTVCRjlcdTRFOEVcdTdDN0JcdTU3OEJcdTRFM0EgJyd7M30nJyBcdTc2ODQgbWluTGVuZ3RoICcnezJ9JycsIGxlbmd0aCA9ICcnezF9JycgXHU3Njg0XHU1MDNDICcnezB9JycgXHU0RTBEXHU1MTc3XHU2NzA5XHU5NzYyXHU2NzA5XHU2NTQ4XHU2MDI3XHUzMDAyCi0gICAgICAgIGN2Yy1wYXR0ZXJuLXZhbGlkID0gY3ZjLXBhdHRlcm4tdmFsaWQ6IFx1NUJGOVx1NEU4RVx1N0M3Qlx1NTc4Qlx1NEUzQSAnJ3syfScnIFx1NzY4NFx1NkEyMVx1NUYwRiAnJ3sxfScnLCBcdTUwM0MgJyd7MH0nJyBcdTRFMERcdTUxNzdcdTY3MDlcdTk3NjJcdTY3MDlcdTY1NDhcdTYwMjdcdTMwMDIKLSAgICAgICAgY3ZjLXRvdGFsRGlnaXRzLXZhbGlkID0gY3ZjLXRvdGFsRGlnaXRzLXZhbGlkOiBcdTUwM0MgJyd7MH0nJyBcdTYwM0JcdTUxNzFcdTY3MDkgezF9IFx1NEY0RCwgXHU0RjQ2XHU2MDNCXHU0RjREXHU2NTcwXHU1REYyXHU5NjUwXHU1MjM2XHU0RTNBIHsyfVx1MzAwMgotICAgICAgICBjdmMtdHlwZS4yID0gY3ZjLXR5cGUuMjogXHU2NUUwXHU2Q0Q1XHU0RTNBXHU1MTQzXHU3RDIwIHswfSBcdTYzRDBcdTUzRDZcdTdDN0JcdTU3OEJcdTVCOUFcdTRFNDlcdTMwMDIKLSAgICAgICAgY3ZjLXR5cGUuMy4xLjEgPSBjdmMtdHlwZS4zLjEuMTogXHU1MTQzXHU3RDIwICcnezB9JycgXHU2NjJGXHU3QjgwXHU1MzU1XHU3QzdCXHU1NzhCLCBcdTU2RTBcdTZCNjRcdTVGQzVcdTk4N0JcdTRFMERcdTU0MkJcdTVDNUVcdTYwMjcgKFx1OTY2NFx1NEU4Nlx1OTBBM1x1NEU5Qlx1NTQwRFx1NzlGMFx1N0E3QVx1OTVGNFx1NTQwRFx1NEUwRSAnJ2h0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlJycgXHU3NkY4XHU1NDBDXHU0RTE0IFtcdTY3MkNcdTU3MzBcdTU0MERcdTc5RjBdIFx1NEUzQSAnJ3R5cGUnJywgJyduaWwnJywgJydzY2hlbWFMb2NhdGlvbicnIFx1NjIxNiAnJ25vTmFtZXNwYWNlU2NoZW1hTG9jYXRpb24nJyBcdTc2ODRcdTUxNDNcdTdEMjApXHUzMDAyXHU0RjQ2XHU2NjJGXHU1M0QxXHU3M0IwXHU0RTg2XHU1QzVFXHU2MDI3ICcnezF9JydcdTMwMDIKLSAgICAgICAgY3ZjLXR5cGUuMy4xLjIgPSBjdmMtdHlwZS4zLjEuMjogXHU1MTQzXHU3RDIwICcnezB9JycgXHU2NjJGXHU3QjgwXHU1MzU1XHU3QzdCXHU1NzhCLCBcdTU2RTBcdTZCNjRcdTVCODNcdTVGQzVcdTk4N0JcdTRFMERcdTU0MkJcdTUxNDNcdTdEMjBcdTRGRTFcdTYwNkZcdTk4NzkgW1x1NUI1MFx1N0VBN11cdTMwMDIKLSAgICAgICAgY3ZjLXR5cGUuMy4xLjMgPSBjdmMtdHlwZS4zLjEuMzogXHU1MTQzXHU3RDIwICcnezB9JycgXHU3Njg0XHU1MDNDICcnezF9JycgXHU2NUUwXHU2NTQ4XHUzMDAyCi0KLSNzY2hlbWEgdmFsaWQgKDMuWC4zKQotCi0gICAgICAgIHNjaGVtYV9yZWZlcmVuY2UuYWNjZXNzID0gc2NoZW1hX3JlZmVyZW5jZTogXHU3NTMxXHU0RThFIGFjY2Vzc0V4dGVybmFsU2NoZW1hIFx1NUM1RVx1NjAyN1x1OEJCRVx1N0Y2RVx1NzY4NFx1OTY1MFx1NTIzNlx1ODAwQ1x1NEUwRFx1NTE0MVx1OEJCOCAnJ3sxfScnIFx1OEJCRlx1OTVFRSwgXHU1NkUwXHU2QjY0XHU2NUUwXHU2Q0Q1XHU4QkZCXHU1M0Q2XHU2NUI5XHU2ODQ4XHU2NTg3XHU2ODYzICcnezB9JydcdTMwMDIKLSAgICAgICAgc2NoZW1hX3JlZmVyZW5jZS40ID0gc2NoZW1hX3JlZmVyZW5jZS40OiBcdTY1RTBcdTZDRDVcdThCRkJcdTUzRDZcdTY1QjlcdTY4NDhcdTY1ODdcdTY4NjMgJyd7MH0nJywgXHU1MzlGXHU1NkUwXHU0RTNBIDEpIFx1NjVFMFx1NkNENVx1NjI3RVx1NTIzMFx1NjU4N1x1Njg2MzsgMikgXHU2NUUwXHU2Q0Q1XHU4QkZCXHU1M0Q2XHU2NTg3XHU2ODYzOyAzKSBcdTY1ODdcdTY4NjNcdTc2ODRcdTY4MzlcdTUxNDNcdTdEMjBcdTRFMERcdTY2MkYgPHhzZDpzY2hlbWE+XHUzMDAyCi0gICAgICAgIHNyYy1hbm5vdGF0aW9uID0gc3JjLWFubm90YXRpb246IDxhbm5vdGF0aW9uPiBcdTUxNDNcdTdEMjBcdTUzRUFcdTgwRkRcdTUzMDVcdTU0MkIgPGFwcGluZm8+IFx1NTQ4QyA8ZG9jdW1lbnRhdGlvbj4gXHU1MTQzXHU3RDIwLCBcdTRGNDZcdTUzRDFcdTczQjBcdTRFODYgJyd7MH0nJ1x1MzAwMgotICAgICAgICBzcmMtYXR0cmlidXRlLjEgPSBzcmMtYXR0cmlidXRlLjE6IFx1NUM1RVx1NjAyN1x1NThGMFx1NjYwRSAnJ3swfScnIFx1NEUyRFx1NEUwRFx1ODBGRFx1NTQwQ1x1NjVGNlx1NUI1OFx1NTcyOFx1NzI3OVx1NjAyNyAnJ2RlZmF1bHQnJyBcdTU0OEMgJydmaXhlZCcnXHUzMDAyXHU1RTk0XHU1M0VBXHU0RjdGXHU3NTI4XHU1MTc2XHU0RTJEXHU0RTAwXHU0RTJBXHUzMDAyCi0gICAgICAgIHNyYy1hdHRyaWJ1dGUuMiA9IHNyYy1hdHRyaWJ1dGUuMjogXHU1QzVFXHU2MDI3ICcnezB9JycgXHU0RTJEXHU1QjU4XHU1NzI4XHU3Mjc5XHU2MDI3ICcnZGVmYXVsdCcnLCBcdTU2RTBcdTZCNjQgJyd1c2UnJyBcdTc2ODRcdTUwM0NcdTVGQzVcdTk4N0JcdTRFM0EgJydvcHRpb25hbCcnXHUzMDAyCi0gICAgICAgIHNyYy1hdHRyaWJ1dGUuMy4xID0gc3JjLWF0dHJpYnV0ZS4zLjE6IFx1NjcyQ1x1NTczMFx1NUM1RVx1NjAyN1x1NThGMFx1NjYwRVx1NEUyRFx1NUZDNVx1OTg3Qlx1NUI1OFx1NTcyOCAncmVmJyBcdTYyMTYgJ25hbWUnIFx1NEU0Qlx1NEUwMFx1MzAwMgotICAgICAgICBzcmMtYXR0cmlidXRlLjMuMiA9IHNyYy1hdHRyaWJ1dGUuMy4yOiBcdTVDNUVcdTYwMjdcdTVGMTVcdTc1MjggJyd7MH0nJyBcdTRFMkRcdTc2ODRcdTUxODVcdTVCQjlcdTVGQzVcdTk4N0JcdTUzMzlcdTkxNEQgKFx1NkNFOFx1OTFDQT8pXHUzMDAyCi0gICAgICAgIHNyYy1hdHRyaWJ1dGUuNCA9IHNyYy1hdHRyaWJ1dGUuNDogXHU1QzVFXHU2MDI3ICcnezB9JycgXHU1NDBDXHU2NUY2XHU1MTc3XHU2NzA5ICcndHlwZScnIFx1NUM1RVx1NjAyN1x1NTQ4Q1x1NTMzRlx1NTQwRCAnJ3NpbXBsZVR5cGUnJyBcdTVCNTBcdTdFQTdcdTMwMDJcdTRFMDBcdTRFMkFcdTVDNUVcdTYwMjdcdTUzRUFcdTgwRkRcdTUxNzdcdTY3MDlcdThGRDlcdTRFMjRcdTgwMDVcdTRFNEJcdTRFMDBcdTMwMDIKLSAgICAgICAgc3JjLWF0dHJpYnV0ZV9ncm91cC4yID0gc3JjLWF0dHJpYnV0ZV9ncm91cC4yOiBcdTY1RTBcdTZDRDVcdTg4NjhcdThGQkVcdTVDNUVcdTYwMjdcdTdFQzQgJyd7MH0nJyBcdTc2ODRcdTkwMUFcdTkxNERcdTdCMjZcdTRFQTRcdTk2QzZcdTMwMDIKLSAgICAgICAgc3JjLWF0dHJpYnV0ZV9ncm91cC4zID0gc3JjLWF0dHJpYnV0ZV9ncm91cC4zOiBcdTU3MjhcdTVDNUVcdTYwMjdcdTdFQzQgJyd7MH0nJyBcdTRFMkRcdTY4QzBcdTZENEJcdTUyMzBcdTVGQUFcdTczQUZcdTVCOUFcdTRFNDlcdTMwMDJcdTkwMTJcdTVGNTJcdThEREZcdTk2OEZcdTVDNUVcdTYwMjdcdTdFQzRcdTVGMTVcdTc1MjhcdTY3MDBcdTdFQzhcdTVDMDZcdTVGMTVcdTVCRkNcdTU2REVcdTgxRUFcdThFQUJcdTMwMDIKLSAgICAgICAgc3JjLWN0LjEgPSBzcmMtY3QuMTogXHU3QzdCXHU1NzhCICcnezB9JycgXHU3Njg0XHU1OTBEXHU2NzQyXHU3QzdCXHU1NzhCXHU1QjlBXHU0RTQ5XHU3Njg0XHU4ODY4XHU4RkJFXHU1RjYyXHU1RjBGXHU5NTE5XHU4QkVGXHUzMDAyXHU0RjdGXHU3NTI4IDxjb21wbGV4Q29udGVudD4gXHU2NUY2LCBcdTU3RkFcdTdDN0JcdTU3OEJcdTVGQzVcdTk4N0JcdTRFM0EgY29tcGxleFR5cGVcdTMwMDInJ3sxfScnIFx1NjYyRiBzaW1wbGVUeXBlXHUzMDAyCi0gICAgICAgIHNyYy1jdC4yLjEgPSBzcmMtY3QuMi4xOiBcdTdDN0JcdTU3OEIgJyd7MH0nJyBcdTc2ODRcdTU5MERcdTY3NDJcdTdDN0JcdTU3OEJcdTVCOUFcdTRFNDlcdTc2ODRcdTg4NjhcdThGQkVcdTVGNjJcdTVGMEZcdTk1MTlcdThCRUZcdTMwMDJcdTRGN0ZcdTc1MjggPHNpbXBsZUNvbnRlbnQ+IFx1NjVGNiwgXHU1N0ZBXHU3QzdCXHU1NzhCXHU1RkM1XHU5ODdCXHU0RTNBIGNvbXBsZXhUeXBlLCBcdTUxNzZcdTUxODVcdTVCQjlcdTdDN0JcdTU3OEJcdTRFM0FcdTIwMUNcdTdCODBcdTUzNTVcdTIwMUQsIFx1NjIxNlx1ODAwNVx1NEUzQVx1NTE3N1x1NjcwOVx1MjAxQ1x1NkRGN1x1NTQwOFx1MjAxRFx1NTE4NVx1NUJCOVx1NTQ4Q1x1NTNFRlx1N0E3QVx1N0M5Mlx1NUI1MFx1NzY4NFx1NTkwRFx1Njc0Mlx1N0M3Qlx1NTc4QiAoXHU0RUM1XHU1RjUzXHU2MzA3XHU1QjlBXHU0RTg2XHU5NjUwXHU1MjM2XHU2NUY2KSwgXHU2MjE2XHU4MDA1XHU0RTNBXHU3QjgwXHU1MzU1XHU3QzdCXHU1NzhCIChcdTRFQzVcdTVGNTNcdTYzMDdcdTVCOUFcdTRFODZcdTYyNjlcdTVDNTVcdTY1RjYpXHUzMDAyJyd7MX0nJyBcdTRFMERcdTZFRTFcdThEQjNcdTYyNDBcdTY3MDlcdThGRDlcdTRFOUJcdTY3NjFcdTRFRjZcdTMwMDIKLSAgICAgICAgc3JjLWN0LjIuMiA9IHNyYy1jdC4yLjI6IFx1N0M3Qlx1NTc4QiAnJ3swfScnIFx1NzY4NFx1NTkwRFx1Njc0Mlx1N0M3Qlx1NTc4Qlx1NUI5QVx1NEU0OVx1NzY4NFx1ODg2OFx1OEZCRVx1NUY2Mlx1NUYwRlx1OTUxOVx1OEJFRlx1MzAwMlx1NTk4Mlx1Njc5Q1x1NTE3N1x1NjcwOSBzaW1wbGVDb250ZW50IFx1NzY4NCBjb21wbGV4VHlwZSBcdTk2NTBcdTUyMzZcdTUxNzdcdTY3MDlcdTIwMUNcdTZERjdcdTU0MDhcdTIwMURcdTUxODVcdTVCQjlcdTU0OENcdTUzRUZcdTdBN0FcdTdDOTJcdTVCNTBcdTc2ODQgY29tcGxleFR5cGUsIFx1OTBBM1x1NEU0OCA8cmVzdHJpY3Rpb24+IFx1NzY4NFx1NUI1MFx1N0VBN1x1NEUyRFx1NUZDNVx1OTg3Qlx1NUI1OFx1NTcyOCA8c2ltcGxlVHlwZT5cdTMwMDIKLSAgICAgICAgc3JjLWN0LjQgPSBzcmMtY3QuNDogXHU3QzdCXHU1NzhCICcnezB9JycgXHU3Njg0XHU1OTBEXHU2NzQyXHU3QzdCXHU1NzhCXHU1QjlBXHU0RTQ5XHU3Njg0XHU4ODY4XHU4RkJFXHU1RjYyXHU1RjBGXHU5NTE5XHU4QkVGXHUzMDAyXHU2NUUwXHU2Q0Q1XHU4ODY4XHU4RkJFXHU5MDFBXHU5MTREXHU3QjI2XHU3Njg0XHU0RUE0XHU5NkM2XHUzMDAyCi0gICAgICAgIHNyYy1jdC41ID0gc3JjLWN0LjU6IFx1N0M3Qlx1NTc4QiAnJ3swfScnIFx1NzY4NFx1NTkwRFx1Njc0Mlx1N0M3Qlx1NTc4Qlx1NUI5QVx1NEU0OVx1NzY4NFx1ODg2OFx1OEZCRVx1NUY2Mlx1NUYwRlx1OTUxOVx1OEJFRlx1MzAwMlx1NjVFMFx1NkNENVx1ODg2OFx1OEZCRVx1OTAxQVx1OTE0RFx1N0IyNlx1NzY4NFx1NUU3Nlx1OTZDNlx1MzAwMgotICAgICAgICBzcmMtZWxlbWVudC4xID0gc3JjLWVsZW1lbnQuMTogXHU1MTQzXHU3RDIwXHU1OEYwXHU2NjBFICcnezB9JycgXHU0RTJEXHU0RTBEXHU4MEZEXHU1NDBDXHU2NUY2XHU1QjU4XHU1NzI4XHU1QzVFXHU2MDI3ICcnZGVmYXVsdCcnIFx1NTQ4QyAnJ2ZpeGVkJydcdTMwMDJcdTVFOTRcdTUzRUFcdTRGN0ZcdTc1MjhcdTUxNzZcdTRFMkRcdTRFMDBcdTRFMkFcdTMwMDIKLSAgICAgICAgc3JjLWVsZW1lbnQuMi4xID0gc3JjLWVsZW1lbnQuMi4xOiBcdTY3MkNcdTU3MzBcdTUxNDNcdTdEMjBcdTU4RjBcdTY2MEVcdTRFMkRcdTVGQzVcdTk4N0JcdTVCNThcdTU3MjggJ3JlZicgXHU2MjE2ICduYW1lJ1x1MzAwMgotICAgICAgICBzcmMtZWxlbWVudC4yLjIgPSBzcmMtZWxlbWVudC4yLjI6IFx1NzUzMVx1NEU4RSAnJ3swfScnIFx1NTMwNVx1NTQyQiAnJ3JlZicnIFx1NUM1RVx1NjAyNywgXHU1MTc2XHU1MTg1XHU1QkI5XHU1RkM1XHU5ODdCXHU1MzM5XHU5MTREIChcdTZDRThcdTkxQ0E/KVx1MzAwMlx1NEY0Nlx1NjYyRiwgXHU1M0QxXHU3M0IwXHU0RTg2ICcnezF9JydcdTMwMDIKLSAgICAgICAgc3JjLWVsZW1lbnQuMyA9IHNyYy1lbGVtZW50LjM6IFx1NTE0M1x1N0QyMCAnJ3swfScnIFx1NTQwQ1x1NjVGNlx1NTE3N1x1NjcwOSAnJ3R5cGUnJyBcdTVDNUVcdTYwMjdcdTU0OEMgJydhbm9ueW1vdXMgdHlwZScnIFx1NUI1MFx1N0VBN1x1MzAwMlx1NTE0M1x1N0QyMFx1NEUyRFx1NTNFQVx1NTE0MVx1OEJCOFx1NTE3N1x1NjcwOVx1NTE3Nlx1NEUyRFx1NEUwMFx1OTg3OVx1MzAwMgotICAgICAgICBzcmMtaW1wb3J0LjEuMSA9IHNyYy1pbXBvcnQuMS4xOiA8aW1wb3J0PiBcdTUxNDNcdTdEMjBcdTRGRTFcdTYwNkZcdTk4NzlcdTc2ODRcdTU0MERcdTc5RjBcdTdBN0FcdTk1RjRcdTVDNUVcdTYwMjcgJyd7MH0nJyBcdTRFMERcdTgwRkRcdTRFMEVcdTY1QjlcdTY4NDhcdTRFMkRcdTUxNzZcdTYyRTVcdTY3MDlcdTc2ODQgdGFyZ2V0TmFtZXNwYWNlIFx1NzZGOFx1NTQwQ1x1MzAwMgotICAgICAgICBzcmMtaW1wb3J0LjEuMiA9IHNyYy1pbXBvcnQuMS4yOiBcdTU5ODJcdTY3OUMgPGltcG9ydD4gXHU1MTQzXHU3RDIwXHU0RkUxXHU2MDZGXHU5ODc5XHU0RTJEXHU0RTBEXHU1QjU4XHU1NzI4XHU1NDBEXHU3OUYwXHU3QTdBXHU5NUY0XHU1QzVFXHU2MDI3LCBcdTUyMTlcdTVDMDFcdTk1RURcdTY1QjlcdTY4NDhcdTRFMkRcdTVGQzVcdTk4N0JcdTUxNzdcdTY3MDkgdGFyZ2V0TmFtZXNwYWNlXHUzMDAyCi0gICAgICAgIHNyYy1pbXBvcnQuMiA9IHNyYy1pbXBvcnQuMjogXHU2NTg3XHU2ODYzICcnezB9JycgXHU3Njg0XHU2ODM5XHU1MTQzXHU3RDIwXHU1RkM1XHU5ODdCXHU1MTc3XHU2NzA5XHU1NDBEXHU3OUYwXHU3QTdBXHU5NUY0XHU1NDBEICcnaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEnJyBcdTU0OENcdTY3MkNcdTU3MzBcdTU0MERcdTc5RjAgJydzY2hlbWEnJ1x1MzAwMgotICAgICAgICBzcmMtaW1wb3J0LjMuMSA9IHNyYy1pbXBvcnQuMy4xOiA8aW1wb3J0PiBcdTUxNDNcdTdEMjBcdTRGRTFcdTYwNkZcdTk4NzlcdTc2ODRcdTU0MERcdTc5RjBcdTdBN0FcdTk1RjRcdTVDNUVcdTYwMjcgJyd7MH0nJyBcdTVGQzVcdTk4N0JcdTRFMEVcdTVCRkNcdTUxNjVcdTY1ODdcdTY4NjNcdTc2ODQgdGFyZ2V0TmFtZXNwYWNlIFx1NUM1RVx1NjAyNyAnJ3sxfScnIFx1NzZGOFx1NTQwQ1x1MzAwMgotICAgICAgICBzcmMtaW1wb3J0LjMuMiA9IHNyYy1pbXBvcnQuMy4yOiBcdTUzRDFcdTczQjBcdTRFODZcdTZDQTFcdTY3MDlcdTU0MERcdTc5RjBcdTdBN0FcdTk1RjRcdTVDNUVcdTYwMjdcdTc2ODQgPGltcG9ydD4gXHU1MTQzXHU3RDIwXHU0RkUxXHU2MDZGXHU5ODc5LCBcdTU2RTBcdTZCNjRcdTVCRkNcdTUxNjVcdTY1ODdcdTY4NjNcdTVGQzVcdTk4N0JcdTRFMERcdTU0MkIgdGFyZ2V0TmFtZXNwYWNlIFx1NUM1RVx1NjAyN1x1MzAwMlx1NEY0Nlx1NjYyRiwgXHU1NzI4XHU1QkZDXHU1MTY1XHU2NTg3XHU2ODYzXHU0RTJEXHU1M0QxXHU3M0IwXHU0RTg2IHRhcmdldE5hbWVzcGFjZSAnJ3sxfScnXHUzMDAyCi0gICAgICAgIHNyYy1pbmNsdWRlLjEgPSBzcmMtaW5jbHVkZS4xOiBcdTY1ODdcdTY4NjMgJyd7MH0nJyBcdTc2ODRcdTY4MzlcdTUxNDNcdTdEMjBcdTVGQzVcdTk4N0JcdTUxNzdcdTY3MDlcdTU0MERcdTc5RjBcdTdBN0FcdTk1RjRcdTU0MEQgJydodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYScnIFx1NTQ4Q1x1NjcyQ1x1NTczMFx1NTQwRFx1NzlGMCAnJ3NjaGVtYScnXHUzMDAyCi0gICAgICAgIHNyYy1pbmNsdWRlLjIuMSA9IHNyYy1pbmNsdWRlLjIuMTogXHU1RjE1XHU3NTI4XHU3Njg0XHU2NUI5XHU2ODQ4IChcdTVGNTNcdTUyNERcdTRFM0EgJyd7MX0nJykgXHU3Njg0IHRhcmdldE5hbWVzcGFjZSBcdTVGQzVcdTk4N0JcdTRFMEVcdTUzMDVcdTU0MkJcdTc2ODRcdTY1QjlcdTY4NDggKFx1NUY1M1x1NTI0RFx1NEUzQSAnJ3swfScnKSBcdTc2ODQgdGFyZ2V0TmFtZXNwYWNlIFx1NzZGOFx1NTQwQ1x1MzAwMgotICAgICAgICBzcmMtcmVkZWZpbmUuMiA9IHNyYy1yZWRlZmluZS4yOiBcdTY1ODdcdTY4NjMgJyd7MH0nJyBcdTc2ODRcdTY4MzlcdTUxNDNcdTdEMjBcdTVGQzVcdTk4N0JcdTUxNzdcdTY3MDlcdTU0MERcdTc5RjBcdTdBN0FcdTk1RjRcdTU0MEQgJydodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYScnIFx1NTQ4Q1x1NjcyQ1x1NTczMFx1NTQwRFx1NzlGMCAnJ3NjaGVtYScnXHUzMDAyCi0gICAgICAgIHNyYy1yZWRlZmluZS4zLjEgPSBzcmMtcmVkZWZpbmUuMy4xOiBcdTVGMTVcdTc1MjhcdTc2ODRcdTY1QjlcdTY4NDggKFx1NUY1M1x1NTI0RFx1NEUzQSAnJ3sxfScnKSBcdTc2ODQgdGFyZ2V0TmFtZXNwYWNlIFx1NUZDNVx1OTg3Qlx1NEUwRVx1OTFDRFx1NjVCMFx1NUI5QVx1NEU0OVx1NzY4NFx1NjVCOVx1Njg0OCAoXHU1RjUzXHU1MjREXHU0RTNBICcnezB9JycpIFx1NzY4NCB0YXJnZXROYW1lc3BhY2UgXHU3NkY4XHU1NDBDXHUzMDAyCi0gICAgICAgIHNyYy1yZWRlZmluZS41LmEuYSA9IHNyYy1yZWRlZmluZS41LmEuYTogXHU2MjdFXHU0RTBEXHU1MjMwIDxzaW1wbGVUeXBlPiBcdTc2ODRcdTk3NUVcdTZDRThcdTkxQ0FcdTVCNTBcdTdFQTdcdTMwMDI8cmVkZWZpbmU+IFx1NTE0M1x1N0QyMFx1NzY4NCA8c2ltcGxlVHlwZT4gXHU1QjUwXHU3RUE3XHU1RkM1XHU5ODdCXHU1MTc3XHU2NzA5IDxyZXN0cmljdGlvbj4gXHU1QjUwXHU5ODc5LCBcdTVFNzZcdTVFMjZcdTY3MDlcdTVGMTVcdTc1MjhcdTUxNzZcdTgxRUFcdThFQUJcdTc2ODQgJ2Jhc2UnIFx1NUM1RVx1NjAyN1x1MzAwMgotICAgICAgICBzcmMtcmVkZWZpbmUuNS5hLmIgPSBzcmMtcmVkZWZpbmUuNS5hLmI6ICcnezB9JycgXHU0RTBEXHU2NjJGXHU2NzA5XHU2NTQ4XHU3Njg0XHU1QjUwXHU1MTQzXHU3RDIwXHUzMDAyPHJlZGVmaW5lPiBcdTUxNDNcdTdEMjBcdTc2ODQgPHNpbXBsZVR5cGU+IFx1NUI1MFx1N0VBN1x1NUZDNVx1OTg3Qlx1NTE3N1x1NjcwOSA8cmVzdHJpY3Rpb24+IFx1NUI1MFx1OTg3OSwgXHU1RTc2XHU1RTI2XHU2NzA5XHU1RjE1XHU3NTI4XHU1MTc2XHU4MUVBXHU4RUFCXHU3Njg0ICcnYmFzZScnIFx1NUM1RVx1NjAyN1x1MzAwMgotICAgICAgICBzcmMtcmVkZWZpbmUuNS5hLmMgPSBzcmMtcmVkZWZpbmUuNS5hLmM6ICcnezB9JycgXHU0RTBEXHU1NDJCXHU1RjE1XHU3NTI4XHU5MUNEXHU2NUIwXHU1QjlBXHU0RTQ5XHU3Njg0XHU1MTQzXHU3RDIwICcnezF9JycgXHU3Njg0ICcnYmFzZScnIFx1NUM1RVx1NjAyN1x1MzAwMjxyZWRlZmluZT4gXHU1MTQzXHU3RDIwXHU3Njg0IDxzaW1wbGVUeXBlPiBcdTVCNTBcdTdFQTdcdTVGQzVcdTk4N0JcdTUxNzdcdTY3MDkgPHJlc3RyaWN0aW9uPiBcdTVCNTBcdTk4NzksIFx1NUU3Nlx1NUUyNlx1NjcwOVx1NUYxNVx1NzUyOFx1NTE3Nlx1ODFFQVx1OEVBQlx1NzY4NCAnJ2Jhc2UnJyBcdTVDNUVcdTYwMjdcdTMwMDIKLSAgICAgICAgc3JjLXJlZGVmaW5lLjUuYi5hID0gc3JjLXJlZGVmaW5lLjUuYi5hOiBcdTYyN0VcdTRFMERcdTUyMzAgPGNvbXBsZXhUeXBlPiBcdTc2ODRcdTk3NUVcdTZDRThcdTkxQ0FcdTVCNTBcdTdFQTdcdTMwMDI8cmVkZWZpbmU+IFx1NTE0M1x1N0QyMFx1NzY4NCA8Y29tcGxleFR5cGU+IFx1NUI1MFx1N0VBN1x1NUZDNVx1OTg3Qlx1NTE3N1x1NjcwOSA8ZXh0ZW5zaW9uPiBcdTYyMTYgPHJlc3RyaWN0aW9uPiBcdTVCNTBcdTk4NzksIFx1NUU3Nlx1NUUyNlx1NjcwOVx1NUYxNVx1NzUyOFx1NTE3Nlx1ODFFQVx1OEVBQlx1NzY4NCAnYmFzZScgXHU1QzVFXHU2MDI3XHUzMDAyCi0gICAgICAgIHNyYy1yZWRlZmluZS41LmIuYiA9IHNyYy1yZWRlZmluZS41LmIuYjogXHU2MjdFXHU0RTBEXHU1MjMwIDxjb21wbGV4VHlwZT4gXHU3Njg0XHU5NzVFXHU2Q0U4XHU5MUNBXHU1QjUwXHU1QjUwXHU3RUE3XHUzMDAyPHJlZGVmaW5lPiBcdTUxNDNcdTdEMjBcdTc2ODQgPGNvbXBsZXhUeXBlPiBcdTVCNTBcdTdFQTdcdTVGQzVcdTk4N0JcdTUxNzdcdTY3MDkgPGV4dGVuc2lvbj4gXHU2MjE2IDxyZXN0cmljdGlvbj4gXHU1QjUwXHU5ODc5LCBcdTVFNzZcdTVFMjZcdTY3MDlcdTVGMTVcdTc1MjhcdTUxNzZcdTgxRUFcdThFQUJcdTc2ODQgJ2Jhc2UnIFx1NUM1RVx1NjAyN1x1MzAwMgotICAgICAgICBzcmMtcmVkZWZpbmUuNS5iLmMgPSBzcmMtcmVkZWZpbmUuNS5iLmM6ICcnezB9JycgXHU0RTBEXHU2NjJGXHU2NzA5XHU2NTQ4XHU3Njg0XHU1QjUwXHU1QjUwXHU3RUE3XHU1MTQzXHU3RDIwXHUzMDAyPHJlZGVmaW5lPiBcdTUxNDNcdTdEMjBcdTc2ODQgPGNvbXBsZXhUeXBlPiBcdTVCNTBcdTdFQTdcdTVGQzVcdTk4N0JcdTUxNzdcdTY3MDkgPGV4dGVuc2lvbj4gXHU2MjE2IDxyZXN0cmljdGlvbj4gXHU1QjUwXHU5ODc5LCBcdTVFNzZcdTVFMjZcdTY3MDlcdTVGMTVcdTc1MjhcdTUxNzZcdTgxRUFcdThFQUJcdTc2ODQgJydiYXNlJycgXHU1QzVFXHU2MDI3XHUzMDAyCi0gICAgICAgIHNyYy1yZWRlZmluZS41LmIuZCA9IHNyYy1yZWRlZmluZS41LmIuZDogJyd7MH0nJyBcdTRFMERcdTU0MkJcdTVGMTVcdTc1MjhcdTkxQ0RcdTY1QjBcdTVCOUFcdTRFNDlcdTc2ODRcdTUxNDNcdTdEMjAgJyd7MX0nJyBcdTc2ODQgJydiYXNlJycgXHU1QzVFXHU2MDI3XHUzMDAyPHJlZGVmaW5lPiBcdTUxNDNcdTdEMjBcdTc2ODQgPGNvbXBsZXhUeXBlPiBcdTVCNTBcdTdFQTdcdTVGQzVcdTk4N0JcdTUxNzdcdTY3MDkgPGV4dGVuc2lvbj4gXHU2MjE2IDxyZXN0cmljdGlvbj4gXHU1QjUwXHU5ODc5LCBcdTVFNzZcdTVFMjZcdTY3MDlcdTVGMTVcdTc1MjhcdTUxNzZcdTgxRUFcdThFQUJcdTc2ODQgJydiYXNlJycgXHU1QzVFXHU2MDI3XHUzMDAyCi0gICAgICAgIHNyYy1yZWRlZmluZS42LjEuMSA9IHNyYy1yZWRlZmluZS42LjEuMTogXHU1OTgyXHU2NzlDIDxyZWRlZmluZT4gXHU1MTQzXHU3RDIwXHU3Njg0XHU3RUM0XHU1QjUwXHU3RUE3XHU1MzA1XHU1NDJCXHU1RjE1XHU3NTI4XHU1MTc2XHU4MUVBXHU4RUFCXHU3Njg0XHU3RUM0LCBcdTUyMTlcdTVCODNcdTVGQzVcdTk4N0JcdTZCNjNcdTU5N0RcdTUzMDVcdTU0MkJcdTRFMDBcdTRFMkFcdTdFQzQ7IFx1NkI2NFx1N0VDNFx1NTE3N1x1NjcwOSAnJ3swfScnXHUzMDAyCi0gICAgICAgIHNyYy1yZWRlZmluZS42LjEuMiA9IHNyYy1yZWRlZmluZS42LjEuMjogXHU3RUM0ICcnezB9JycgKFx1NTMwNVx1NTQyQlx1NUJGOVx1ODk4MVx1OTFDRFx1NjVCMFx1NUI5QVx1NEU0OVx1NzY4NFx1N0VDNFx1NzY4NFx1NUYxNVx1NzUyOCkgXHU1RkM1XHU5ODdCXHU2RUUxXHU4REIzICcnbWluT2NjdXJzJycgPSAnJ21heE9jY3VycycnID0gMVx1MzAwMgotICAgICAgICBzcmMtcmVkZWZpbmUuNi4yLjEgPSBzcmMtcmVkZWZpbmUuNi4yLjE6IFx1OTFDRFx1NjVCMFx1NUI5QVx1NEU0OVx1NzY4NFx1NjVCOVx1Njg0OFx1NEUyRFx1NjVFMFx1NTQwRFx1NzlGMFx1NEUwRSAnJ3swfScnIFx1NTMzOVx1OTE0RFx1NzY4NFx1N0VDNFx1MzAwMgotICAgICAgICBzcmMtcmVkZWZpbmUuNi4yLjIgPSBzcmMtcmVkZWZpbmUuNi4yLjI6IFx1N0VDNCAnJ3swfScnIFx1NjcyQVx1NkI2M1x1Nzg2RVx1OTY1MFx1NTIzNlx1NTE3Nlx1OTFDRFx1NjVCMFx1NUI5QVx1NEU0OVx1NzY4NFx1N0VDNDsgXHU4RkREXHU1M0NEXHU0RTg2XHU3RUE2XHU2NzVGXHU2NzYxXHU0RUY2OiAnJ3sxfScnXHUzMDAyCi0gICAgICAgIHNyYy1yZWRlZmluZS43LjEgPSBzcmMtcmVkZWZpbmUuNy4xOiBcdTU5ODJcdTY3OUMgPHJlZGVmaW5lPiBcdTUxNDNcdTdEMjBcdTc2ODQgYXR0cmlidXRlR3JvdXAgXHU1QjUwXHU3RUE3XHU1MzA1XHU1NDJCXHU1RjE1XHU3NTI4XHU1MTc2XHU4MUVBXHU4RUFCXHU3Njg0IGF0dHJpYnV0ZUdyb3VwLCBcdTUyMTlcdTVCODNcdTVGQzVcdTk4N0JcdTZCNjNcdTU5N0RcdTUzMDVcdTU0MkJcdTRFMDBcdTRFMkFcdTdFQzQ7IFx1NkI2NFx1N0VDNFx1NTE3N1x1NjcwOSB7MH1cdTMwMDIKLSAgICAgICAgc3JjLXJlZGVmaW5lLjcuMi4xID0gc3JjLXJlZGVmaW5lLjcuMi4xOiBcdTkxQ0RcdTY1QjBcdTVCOUFcdTRFNDlcdTc2ODRcdTY1QjlcdTY4NDhcdTRFMkRcdTZDQTFcdTY3MDlcdTU0MERcdTc5RjBcdTRFMEUgJyd7MH0nJyBcdTUzMzlcdTkxNERcdTc2ODQgYXR0cmlidXRlR3JvdXBcdTMwMDIKLSAgICAgICAgc3JjLXJlZGVmaW5lLjcuMi4yID0gc3JjLXJlZGVmaW5lLjcuMi4yOiBBdHRyaWJ1dGVHcm91cCAnJ3swfScnIFx1NjcyQVx1NkI2M1x1Nzg2RVx1OTY1MFx1NTIzNlx1NTE3Nlx1OTFDRFx1NjVCMFx1NUI5QVx1NEU0OVx1NzY4NCBhdHRyaWJ1dGVHcm91cDsgXHU4RkREXHU1M0NEXHU0RTg2XHU3RUE2XHU2NzVGXHU2NzYxXHU0RUY2OiAnJ3sxfScnXHUzMDAyCi0gICAgICAgIHNyYy1yZXNvbHZlID0gc3JjLXJlc29sdmU6IFx1NjVFMFx1NkNENVx1NUMwNlx1NTQwRFx1NzlGMCAnJ3swfScnIFx1ODlFM1x1Njc5MFx1NEUzQSAnJ3sxfScnIFx1N0VDNFx1NEVGNlx1MzAwMgotICAgICAgICBzcmMtcmVzb2x2ZS40LjEgPSBzcmMtcmVzb2x2ZS40LjE6IFx1ODlFM1x1Njc5MFx1N0VDNFx1NEVGNiAnJ3syfScnIFx1NjVGNlx1NTFGQVx1OTUxOVx1MzAwMlx1NTcyOFx1OEJFNVx1N0VDNFx1NEVGNlx1NEUyRFx1NjhDMFx1NkQ0Qlx1NTIzMCAnJ3syfScnIFx1NkNBMVx1NjcwOVx1NTQwRFx1NzlGMFx1N0E3QVx1OTVGNCwgXHU0RjQ2XHU2NUUwXHU2Q0Q1XHU0RUNFXHU2NUI5XHU2ODQ4XHU2NTg3XHU2ODYzICcnezB9JycgXHU1RjE1XHU3NTI4XHU2Q0ExXHU2NzA5XHU3NkVFXHU2ODA3XHU1NDBEXHU3OUYwXHU3QTdBXHU5NUY0XHU3Njg0XHU3RUM0XHU0RUY2XHUzMDAyXHU1OTgyXHU2NzlDICcnezJ9JycgXHU5NzAwXHU4OTgxXHU1MTc3XHU2NzA5XHU1NDBEXHU3OUYwXHU3QTdBXHU5NUY0LCBcdTUyMTlcdTVGODhcdTUzRUZcdTgwRkRcdTk3MDBcdTg5ODFcdTYzRDBcdTRGOUJcdTUyNERcdTdGMDBcdTMwMDJcdTU5ODJcdTY3OUMgJyd7Mn0nJyBcdTRFMERcdTk3MDBcdTg5ODFcdTUxNzdcdTY3MDlcdTU0MERcdTc5RjBcdTdBN0FcdTk1RjQsIFx1NTIxOVx1NUU5NFx1NUMwNlx1NkNBMVx1NjcwOSAibmFtZXNwYWNlIiBcdTVDNUVcdTYwMjdcdTc2ODQgJydpbXBvcnQnJyBcdTZERkJcdTUyQTBcdTUyMzAgJyd7MH0nJ1x1MzAwMgotICAgICAgICBzcmMtcmVzb2x2ZS40LjIgPSBzcmMtcmVzb2x2ZS40LjI6IFx1ODlFM1x1Njc5MFx1N0VDNFx1NEVGNiAnJ3syfScnIFx1NjVGNlx1NTFGQVx1OTUxOVx1MzAwMlx1NTcyOFx1OEJFNVx1N0VDNFx1NEVGNlx1NEUyRFx1NjhDMFx1NkQ0Qlx1NTIzMCAnJ3syfScnIFx1NEY0RFx1NEU4RVx1NTQwRFx1NzlGMFx1N0E3QVx1OTVGNCAnJ3sxfScnIFx1NEUyRCwgXHU0RjQ2XHU2NUUwXHU2Q0Q1XHU0RUNFXHU2NUI5XHU2ODQ4XHU2NTg3XHU2ODYzICcnezB9JycgXHU1RjE1XHU3NTI4XHU2QjY0XHU1NDBEXHU3OUYwXHU3QTdBXHU5NUY0XHU3Njg0XHU3RUM0XHU0RUY2XHUzMDAyXHU1OTgyXHU2NzlDXHU4RkQ5XHU2NjJGXHU0RTBEXHU2QjYzXHU3ODZFXHU3Njg0XHU1NDBEXHU3OUYwXHU3QTdBXHU5NUY0LCBcdTUyMTlcdTVGODhcdTUzRUZcdTgwRkRcdTk3MDBcdTg5ODFcdTY2RjRcdTY1MzkgJyd7Mn0nJyBcdTc2ODRcdTUyNERcdTdGMDBcdTMwMDJcdTU5ODJcdTY3OUNcdThGRDlcdTY2MkZcdTZCNjNcdTc4NkVcdTc2ODRcdTU0MERcdTc5RjBcdTdBN0FcdTk1RjQsIFx1NTIxOVx1NUU5NFx1NUMwNlx1OTAwMlx1NUY1M1x1NzY4NCAnJ2ltcG9ydCcnIFx1NjgwN1x1OEJCMFx1NkRGQlx1NTJBMFx1NTIzMCAnJ3swfScnXHUzMDAyCi0gICAgICAgIHNyYy1zaW1wbGUtdHlwZS4yLmEgPSBzcmMtc2ltcGxlLXR5cGUuMi5hOiBcdTUzRDFcdTczQjAgPHJlc3RyaWN0aW9uPiBcdTUxNDNcdTdEMjBcdTc2ODQgW1x1NUI1MFx1N0VBN10gXHU0RTJEXHU1NDBDXHU2NUY2XHU1MTc3XHU2NzA5XHU1N0ZBIFtcdTVDNUVcdTYwMjddIFx1NTQ4QyA8c2ltcGxlVHlwZT4gXHU1MTQzXHU3RDIwXHUzMDAyXHU1M0VBXHU1MTQxXHU4QkI4XHU1MTc3XHU2NzA5XHU0RTAwXHU0RTJBXHUzMDAyCi0gICAgICAgIHNyYy1zaW1wbGUtdHlwZS4yLmIgPSBzcmMtc2ltcGxlLXR5cGUuMi5iOiBcdTUzRDFcdTczQjAgPHJlc3RyaWN0aW9uPiBcdTUxNDNcdTdEMjBcdTc2ODQgW1x1NUI1MFx1N0VBN10gXHU0RTJEXHU2NUUyXHU2Q0ExXHU2NzA5XHU1N0ZBIFtcdTVDNUVcdTYwMjddLCBcdTRFNUZcdTZDQTFcdTY3MDkgPHNpbXBsZVR5cGU+IFx1NTE0M1x1N0QyMFx1MzAwMlx1NUZDNVx1OTg3Qlx1NTE3N1x1NjcwOVx1NTE3Nlx1NEUyRFx1NEUwMFx1NEUyQVx1MzAwMgotICAgICAgICBzcmMtc2ltcGxlLXR5cGUuMy5hID0gc3JjLXNpbXBsZS10eXBlLjMuYTogXHU1M0QxXHU3M0IwIDxsaXN0PiBcdTUxNDNcdTdEMjBcdTc2ODQgW1x1NUI1MFx1N0VBN10gXHU0RTJEXHU1NDBDXHU2NUY2XHU1MTc3XHU2NzA5IGl0ZW1UeXBlIFtcdTVDNUVcdTYwMjddIFx1NTQ4QyA8c2ltcGxlVHlwZT4gXHU1MTQzXHU3RDIwXHUzMDAyXHU1M0VBXHU1MTQxXHU4QkI4XHU1MTc3XHU2NzA5XHU0RTAwXHU0RTJBXHUzMDAyCi0gICAgICAgIHNyYy1zaW1wbGUtdHlwZS4zLmIgPSBzcmMtc2ltcGxlLXR5cGUuMy5iOiBcdTUzRDFcdTczQjAgPGxpc3Q+IFx1NTE0M1x1N0QyMFx1NzY4NCBbXHU1QjUwXHU3RUE3XSBcdTRFMkRcdTY1RTJcdTZDQTFcdTY3MDkgaXRlbVR5cGUgW1x1NUM1RVx1NjAyN10sIFx1NEU1Rlx1NkNBMVx1NjcwOSA8c2ltcGxlVHlwZT4gXHU1MTQzXHU3RDIwXHUzMDAyXHU1RkM1XHU5ODdCXHU1MTc3XHU2NzA5XHU1MTc2XHU0RTJEXHU0RTAwXHU0RTJBXHUzMDAyCi0gICAgICAgIHNyYy1zaW5nbGUtZmFjZXQtdmFsdWUgPSBzcmMtc2luZ2xlLWZhY2V0LXZhbHVlOiBcdTU5MUFcdTZCMjFcdTVCOUFcdTRFNDlcdTRFODZcdTk3NjIgJyd7MH0nJ1x1MzAwMgotICAgICAgICBzcmMtdW5pb24tbWVtYmVyVHlwZXMtb3Itc2ltcGxlVHlwZXMgPSBzcmMtdW5pb24tbWVtYmVyVHlwZXMtb3Itc2ltcGxlVHlwZXM6IDx1bmlvbj4gXHU1MTQzXHU3RDIwXHU3Njg0IFtcdTVCNTBcdTdFQTddIFx1NEUyRFx1NUZDNVx1OTg3Qlx1NTE3N1x1NjcwOVx1OTc1RVx1N0E3QSBtZW1iZXJUeXBlcyBbXHU1QzVFXHU2MDI3XSBcdTYyMTZcdTgxRjNcdTVDMTFcdTRFMDBcdTRFMkEgPHNpbXBsZVR5cGU+IFx1NTE0M1x1N0QyMFx1MzAwMgotCi0jY29uc3RyYWludCB2YWxpZCAoMy5YLjYpCi0KLSAgICAgICAgYWctcHJvcHMtY29ycmVjdC4yID0gYWctcHJvcHMtY29ycmVjdC4yOiBcdTVDNUVcdTYwMjdcdTdFQzQgJyd7MH0nJyBcdTk1MTlcdThCRUZcdTMwMDJcdTYzMDdcdTVCOUFcdTRFODZcdTUxNzdcdTY3MDlcdTc2RjhcdTU0MENcdTU0MERcdTc5RjBcdTU0OENcdTc2RUVcdTY4MDdcdTU0MERcdTc5RjBcdTdBN0FcdTk1RjRcdTc2ODRcdTkxQ0RcdTU5MERcdTVDNUVcdTYwMjdcdTc1MjhcdTZDRDVcdTMwMDJcdTkxQ0RcdTU5MERcdTVDNUVcdTYwMjdcdTc1MjhcdTZDRDVcdTc2ODRcdTU0MERcdTc5RjBcdTRFM0EgJyd7MX0nJ1x1MzAwMgotICAgICAgICBhZy1wcm9wcy1jb3JyZWN0LjMgPSBhZy1wcm9wcy1jb3JyZWN0LjM6IFx1NUM1RVx1NjAyN1x1N0VDNCAnJ3swfScnIFx1OTUxOVx1OEJFRlx1MzAwMlx1NEUyNFx1NEUyQVx1NUM1RVx1NjAyN1x1NThGMFx1NjYwRSAnJ3sxfScnIFx1NTQ4QyAnJ3syfScnIFx1NTE3N1x1NjcwOVx1NzY4NFx1N0M3Qlx1NTc4Qlx1NjYyRlx1NEVDRSBJRCBcdTZEM0VcdTc1MUZcdTc2ODRcdTMwMDIKLSAgICAgICAgYS1wcm9wcy1jb3JyZWN0LjIgPSBhLXByb3BzLWNvcnJlY3QuMjogXHU1QzVFXHU2MDI3ICcnezB9JycgXHU0RTJEXHU3Njg0XHU1MDNDXHU3RUE2XHU2NzVGXHU2NzYxXHU0RUY2XHU3Njg0XHU1MDNDICcnezF9JycgXHU2NUUwXHU2NTQ4XHUzMDAyCi0gICAgICAgIGEtcHJvcHMtY29ycmVjdC4zID0gYS1wcm9wcy1jb3JyZWN0LjM6IFx1NUM1RVx1NjAyNyAnJ3swfScnIFx1NEUwRFx1ODBGRFx1NEY3Rlx1NzUyOCAnJ2ZpeGVkJycgXHU2MjE2ICcnZGVmYXVsdCcnLCBcdTU2RTBcdTRFM0FcdTUxNzYgJ3sndHlwZSBkZWZpbml0aW9uJ30nIFx1NEUzQSBJRCwgXHU2MjE2XHU4MDA1XHU2NjJGXHU0RUNFIElEIFx1NkQzRVx1NzUxRlx1NzY4NFx1MzAwMgotICAgICAgICBhdS1wcm9wcy1jb3JyZWN0LjIgPSBhdS1wcm9wcy1jb3JyZWN0LjI6IFx1NTcyOCAnJ3swfScnIFx1NzY4NFx1NUM1RVx1NjAyN1x1NThGMFx1NjYwRVx1NEUyRCwgXHU2MzA3XHU1QjlBXHU0RTg2XHU1NkZBXHU1QjlBXHU1MDNDICcnezF9JydcdTMwMDJcdTU2RTBcdTZCNjRcdTU5ODJcdTY3OUNcdTVGMTVcdTc1MjggJyd7MH0nJyBcdTc2ODRcdTVDNUVcdTYwMjdcdTc1MjhcdTZDRDVcdTU0MENcdTY1RjZcdTUxNzdcdTY3MDkgJ3sndmFsdWUgY29uc3RyYWludCd9JywgXHU1MjE5XHU1QjgzXHU1RkM1XHU5ODdCXHU2NjJGXHU1NkZBXHU1QjlBXHU3Njg0LCBcdTVFNzZcdTRFMTRcdTUxNzZcdTUwM0NcdTVGQzVcdTk4N0JcdTRFM0EgJyd7MX0nJ1x1MzAwMgotICAgICAgICBjb3MtYWxsLWxpbWl0ZWQuMS4yID0gY29zLWFsbC1saW1pdGVkLjEuMjogJ3snbWluIG9jY3Vycyd9JyA9ICd7J21heCBvY2N1cnMnfScgPSAxIFx1NzY4NFx1N0M5Mlx1NUI1MFx1NEUyRFx1NUZDNVx1OTg3Qlx1NTMwNVx1NTQyQiAnYWxsJyBcdTZBMjFcdTU3OEJcdTdFQzQsIFx1OEJFNVx1N0M5Mlx1NUI1MFx1NUZDNVx1OTg3Qlx1NjYyRlx1N0VDNFx1NjIxMFx1NTkwRFx1Njc0Mlx1N0M3Qlx1NTc4Qlx1NUI5QVx1NEU0OVx1NzY4NCAneydjb250ZW50IHR5cGUnfScgXHU1QkY5XHU3Njg0XHU0RTAwXHU5MEU4XHU1MjA2XHUzMDAyCi0gICAgICAgIGNvcy1hbGwtbGltaXRlZC4yID0gY29zLWFsbC1saW1pdGVkLjI6IFx1NTcyOCAnJ2FsbCcnIFx1NkEyMVx1NTc4Qlx1N0VDNFx1NEUyRFx1NTE0M1x1N0QyMFx1NzY4NCAneydtYXggb2NjdXJzJ30nIFx1NUZDNVx1OTg3Qlx1NEUzQSAwIFx1NjIxNiAxXHUzMDAyXHU1MTQzXHU3RDIwICcnezF9JycgXHU3Njg0XHU1MDNDICcnezB9JycgXHU2NUUwXHU2NTQ4XHUzMDAyCi0gICAgICAgIGNvcy1hcHBsaWNhYmxlLWZhY2V0cyA9IGNvcy1hcHBsaWNhYmxlLWZhY2V0czogXHU3QzdCXHU1NzhCIHsxfSBcdTRFMERcdTUxNDFcdThCQjhcdTk3NjIgJyd7MH0nJ1x1MzAwMgotICAgICAgICBjb3MtY3QtZXh0ZW5kcy4xLjEgPSBjb3MtY3QtZXh0ZW5kcy4xLjE6IFx1N0M3Qlx1NTc4QiAnJ3swfScnIFx1NjYyRlx1NEVDRVx1N0M3Qlx1NTc4QiAnJ3sxfScnIFx1NzY4NFx1NjI2OVx1NUM1NVx1NkQzRVx1NzUxRlx1NzY4NFx1MzAwMlx1NEY0Nlx1NjYyRiwgJyd7MX0nJyBcdTc2ODQgJydmaW5hbCcnIFx1NUM1RVx1NjAyN1x1Nzk4MVx1NkI2Mlx1NzUzMVx1NjI2OVx1NUM1NVx1NkQzRVx1NzUxRlx1MzAwMgotICAgICAgICBjb3MtY3QtZXh0ZW5kcy4xLjQuMy4yLjIuMS5hID0gY29zLWN0LWV4dGVuZHMuMS40LjMuMi4yLjEuYTogXHU2RDNFXHU3NTFGXHU3QzdCXHU1NzhCXHU1M0NBXHU1MTc2XHU1N0ZBXHU3QzdCXHU1NzhCXHU3Njg0XHU1MTg1XHU1QkI5XHU3QzdCXHU1NzhCXHU5MEZEXHU1RkM1XHU5ODdCXHU0RTNBXHUyMDFDXHU2REY3XHU1NDA4XHUyMDFEXHU2MjE2XHUyMDFDXHU0RUM1XHU1MTQzXHU3RDIwXHUyMDFEXHUzMDAyXHU3QzdCXHU1NzhCICcnezB9JycgXHU0RTNBXHUyMDFDXHU0RUM1XHU1MTQzXHU3RDIwXHUyMDFELCBcdTRGNDZcdTUxNzZcdTU3RkFcdTdDN0JcdTU3OEJcdTRFMERcdTY2MkZcdTMwMDIKLSAgICAgICAgY29zLWN0LWV4dGVuZHMuMS40LjMuMi4yLjEuYiA9IGNvcy1jdC1leHRlbmRzLjEuNC4zLjIuMi4xLmI6IFx1NkQzRVx1NzUxRlx1N0M3Qlx1NTc4Qlx1NTNDQVx1NTE3Nlx1NTdGQVx1N0M3Qlx1NTc4Qlx1NzY4NFx1NTE4NVx1NUJCOVx1N0M3Qlx1NTc4Qlx1OTBGRFx1NUZDNVx1OTg3Qlx1NEUzQVx1MjAxQ1x1NkRGN1x1NTQwOFx1MjAxRFx1NjIxNlx1MjAxQ1x1NEVDNVx1NTE0M1x1N0QyMFx1MjAxRFx1MzAwMlx1N0M3Qlx1NTc4QiAnJ3swfScnIFx1NEUzQVx1MjAxQ1x1NkRGN1x1NTQwOFx1MjAxRCwgXHU0RjQ2XHU1MTc2XHU1N0ZBXHU3QzdCXHU1NzhCXHU0RTBEXHU2NjJGXHUzMDAyCi0gICAgICAgIGNvcy1lbGVtZW50LWNvbnNpc3RlbnQgPSBjb3MtZWxlbWVudC1jb25zaXN0ZW50OiBcdTdDN0JcdTU3OEIgJyd7MH0nJyBcdTk1MTlcdThCRUZcdTMwMDJcdTZBMjFcdTU3OEJcdTdFQzRcdTRFMkRcdTVCNThcdTU3MjhcdTU0MERcdTc5RjBcdTRFM0EgJyd7MX0nJyBcdTRFMTRcdTUxNzdcdTY3MDlcdTRFMERcdTU0MENcdTdDN0JcdTU3OEJcdTc2ODRcdTU5MUFcdTRFMkFcdTUxNDNcdTdEMjBcdTMwMDIKLSAgICAgICAgY29zLWxpc3Qtb2YtYXRvbWljID0gY29zLWxpc3Qtb2YtYXRvbWljOiBcdTU3MjhcdTUyMTdcdTg4NjhcdTdDN0JcdTU3OEIgJyd7MH0nJyBcdTc2ODRcdTVCOUFcdTRFNDlcdTRFMkQsIFx1N0M3Qlx1NTc4QiAnJ3sxfScnIFx1NjYyRlx1NjVFMFx1NjU0OFx1NzY4NFx1NTIxN1x1ODg2OFx1NTE0M1x1N0QyMFx1N0M3Qlx1NTc4QiwgXHU1NkUwXHU0RTNBXHU1QjgzXHU0RTBEXHU2NjJGXHU1MzlGXHU1QjUwICgnJ3sxfScnIFx1NjVFMlx1NEUwRFx1NjYyRlx1NTIxN1x1ODg2OFx1N0M3Qlx1NTc4QiwgXHU0RTVGXHU0RTBEXHU2NjJGXHU1MzA1XHU1NDJCXHU1MjE3XHU4ODY4XHU3Njg0XHU4MDU0XHU1NDA4XHU3QzdCXHU1NzhCKVx1MzAwMgotICAgICAgICBjb3Mtbm9uYW1iaWcgPSBjb3Mtbm9uYW1iaWc6IHswfSBcdTU0OEMgezF9IChcdTYyMTZcdTY3NjVcdTgxRUFcdTUxNzZcdTY2RkZcdTRFRTNcdTdFQzRcdTc2ODRcdTUxNDNcdTdEMjApIFx1OEZERFx1NTNDRFx1NEU4NiAiXHU1NTJGXHU0RTAwXHU3QzkyXHU1QjUwXHU1QzVFXHU2MDI3Ilx1MzAwMlx1NjgzOVx1NjM2RVx1NkI2NFx1NjVCOVx1Njg0OFx1OEZEQlx1ODg0Q1x1OUE4Q1x1OEJDMVx1NjcxRlx1OTVGNCwgXHU4RkQ5XHU0RTI0XHU0RTJBXHU3QzkyXHU1QjUwXHU0RjFBXHU5MDIwXHU2MjEwXHU2QjY3XHU0RTQ5XHUzMDAyCi0gICAgICAgIGNvcy1wYXJ0aWNsZS1yZXN0cmljdC5hID0gY29zLXBhcnRpY2xlLXJlc3RyaWN0LmE6IFx1NkQzRVx1NzUxRlx1NzY4NFx1N0M5Mlx1NUI1MFx1NEUzQVx1N0E3QSwgXHU4MDBDXHU1N0ZBXHU3QzkyXHU1QjUwXHU0RTBEXHU1M0VGXHU0RTNBXHU3QTdBXHUzMDAyCi0gICAgICAgIGNvcy1wYXJ0aWNsZS1yZXN0cmljdC5iID0gY29zLXBhcnRpY2xlLXJlc3RyaWN0LmI6IFx1NTdGQVx1N0M5Mlx1NUI1MFx1NEUzQVx1N0E3QSwgXHU0RjQ2XHU2RDNFXHU3NTFGXHU3QzkyXHU1QjUwXHU0RTBEXHU0RTNBXHU3QTdBXHUzMDAyCi0gICAgICAgIGNvcy1wYXJ0aWNsZS1yZXN0cmljdC4yID0gY29zLXBhcnRpY2xlLXJlc3RyaWN0LjI6IFx1Nzk4MVx1NkI2Mlx1N0M5Mlx1NUI1MFx1OTY1MFx1NTIzNjogJyd7MH0nJ1x1MzAwMgotICAgICAgICBjb3Mtc3QtcmVzdHJpY3RzLjEuMSA9IGNvcy1zdC1yZXN0cmljdHMuMS4xOiBcdTdDN0JcdTU3OEIgJyd7MX0nJyBcdTRFM0FcdTUzOUZcdTVCNTAsIFx1NTZFMFx1NkI2NFx1NTE3NiAneydiYXNlIHR5cGUgZGVmaW5pdGlvbid9JyAnJ3swfScnIFx1NUZDNVx1OTg3Qlx1NEUzQVx1NTM5Rlx1NUI1MFx1N0I4MFx1NTM1NVx1N0M3Qlx1NTc4Qlx1NUI5QVx1NEU0OVx1NjIxNlx1NTE4NVx1N0Y2RVx1NTdGQVx1NTE0M1x1NjU3MFx1NjM2RVx1N0M3Qlx1NTc4Qlx1MzAwMgotICAgICAgICBjb3Mtc3QtcmVzdHJpY3RzLjIuMSA9IGNvcy1zdC1yZXN0cmljdHMuMi4xOiBcdTU3MjhcdTUyMTdcdTg4NjhcdTdDN0JcdTU3OEIgJyd7MH0nJyBcdTc2ODRcdTVCOUFcdTRFNDlcdTRFMkQsIFx1N0M3Qlx1NTc4QiAnJ3sxfScnIFx1NjYyRlx1NjVFMFx1NjU0OFx1NzY4NFx1OTg3OVx1N0M3Qlx1NTc4QiwgXHU1NkUwXHU0RTNBXHU1QjgzXHU2NUUyXHU0RTBEXHU2NjJGXHU1MjE3XHU4ODY4XHU3QzdCXHU1NzhCLCBcdTRFNUZcdTRFMERcdTY2MkZcdTUzMDVcdTU0MkJcdTUyMTdcdTg4NjhcdTc2ODRcdTgwNTRcdTU0MDhcdTdDN0JcdTU3OEJcdTMwMDIKLSAgICAgICAgY29zLXN0LXJlc3RyaWN0cy4yLjMuMS4xID0gY29zLXN0LXJlc3RyaWN0cy4yLjMuMS4xOiAneydpdGVtIHR5cGUgZGVmaW5pdGlvbid9JyBcdTc2ODQgJ3snZmluYWwnfScgXHU3RUM0XHU0RUY2ICcnezB9JycgXHU1MzA1XHU1NDJCICcnbGlzdCcnXHUzMDAyXHU4RkQ5XHU4ODY4XHU3OTNBICcnezB9JycgXHU0RTBEXHU4MEZEXHU3NTI4XHU0RjVDXHU1MjE3XHU4ODY4XHU3QzdCXHU1NzhCICcnezF9JycgXHU3Njg0XHU5ODc5XHU3QzdCXHU1NzhCXHUzMDAyCi0gICAgICAgIGNvcy1zdC1yZXN0cmljdHMuMy4zLjEuMSA9IGNvcy1zdC1yZXN0cmljdHMuMy4zLjEuMTogJ3snbWVtYmVyIHR5cGUgZGVmaW5pdGlvbnMnfScgJyd7MH0nJyBcdTc2ODQgJ3snZmluYWwnfScgXHU3RUM0XHU0RUY2XHU1MzA1XHU1NDJCICcndW5pb24nJ1x1MzAwMlx1OEZEOVx1ODg2OFx1NzkzQSAnJ3swfScnIFx1NEUwRFx1ODBGRFx1NzUyOFx1NEY1Q1x1ODA1NFx1NTQwOFx1N0M3Qlx1NTc4QiAnJ3sxfScnIFx1NzY4NFx1NjIxMFx1NTQ1OFx1N0M3Qlx1NTc4Qlx1MzAwMgotICAgICAgICBjb3MtdmFsaWQtZGVmYXVsdC4yLjEgPSBjb3MtdmFsaWQtZGVmYXVsdC4yLjE6IFx1NTE0M1x1N0QyMCAnJ3swfScnIFx1NTE3N1x1NjcwOVx1NTAzQ1x1N0VBNlx1Njc1Rlx1Njc2MVx1NEVGNiwgXHU1RTc2XHU0RTE0XHU1RkM1XHU5ODdCXHU1MTc3XHU2NzA5XHUyMDFDXHU2REY3XHU1NDA4XHUyMDFEXHU2MjE2XHUyMDFDXHU3QjgwXHU1MzU1XHUyMDFEXHU1MTg1XHU1QkI5XHU2QTIxXHU1NzhCXHUzMDAyCi0gICAgICAgIGNvcy12YWxpZC1kZWZhdWx0LjIuMi4yID0gY29zLXZhbGlkLWRlZmF1bHQuMi4yLjI6IFx1NzUzMVx1NEU4RVx1NTE0M1x1N0QyMCAnJ3swfScnIFx1NTE3N1x1NjcwOSAneyd2YWx1ZSBjb25zdHJhaW50J30nLCBcdTVFNzZcdTRFMTRcdTUxNzZcdTdDN0JcdTU3OEJcdTVCOUFcdTRFNDlcdTUxNzdcdTY3MDlcdTZERjdcdTU0MDhcdTc2ODQgJ3snY29udGVudCB0eXBlJ30nLCBcdTUyMTkgJ3snY29udGVudCB0eXBlJ30nIFx1NzY4NFx1N0M5Mlx1NUI1MFx1NUZDNVx1OTg3Qlx1NTNFRlx1NEUzQVx1N0E3QVx1MzAwMgotICAgICAgICBjLXByb3BzLWNvcnJlY3QuMiA9IGMtcHJvcHMtY29ycmVjdC4yOiBcdTk1MkVcdTVGMTVcdTc1MjggJyd7MH0nJyBcdTU0OENcdTk1MkUgJyd7MX0nJyBcdTRFMkRcdTVCNTdcdTZCQjVcdTc2ODRcdTU3RkFcdTY1NzBcdTVGQzVcdTk4N0JcdTc2RjhcdTU0MENcdTMwMDIKLSAgICAgICAgY3QtcHJvcHMtY29ycmVjdC4zID0gY3QtcHJvcHMtY29ycmVjdC4zOiBcdTU3MjhcdTU5MERcdTY3NDJcdTdDN0JcdTU3OEIgJyd7MH0nJyBcdTRFMkRcdTY4QzBcdTZENEJcdTUyMzBcdTVGQUFcdTczQUZcdTVCOUFcdTRFNDlcdTMwMDJcdThGRDlcdTg4NjhcdTc5M0EgJyd7MH0nJyBcdTUzMDVcdTU0MkJcdTU3MjhcdTUxNzZcdTgxRUFcdThFQUJcdTc2ODRcdTdDN0JcdTU3OEJcdTUyMDZcdTVDNDJcdTdFRDNcdTY3ODRcdTRFMkQsIFx1OEZEOVx1NjYyRlx1OTUxOVx1OEJFRlx1NzY4NFx1MzAwMgotICAgICAgICBjdC1wcm9wcy1jb3JyZWN0LjQgPSBjdC1wcm9wcy1jb3JyZWN0LjQ6IFx1N0M3Qlx1NTc4QiAnJ3swfScnIFx1OTUxOVx1OEJFRlx1MzAwMlx1NjMwN1x1NUI5QVx1NEU4Nlx1NTE3N1x1NjcwOVx1NzZGOFx1NTQwQ1x1NTQwRFx1NzlGMFx1NTQ4Q1x1NzZFRVx1NjgwN1x1NTQwRFx1NzlGMFx1N0E3QVx1OTVGNFx1NzY4NFx1OTFDRFx1NTkwRFx1NUM1RVx1NjAyN1x1NzUyOFx1NkNENVx1MzAwMlx1OTFDRFx1NTkwRFx1NUM1RVx1NjAyN1x1NzUyOFx1NkNENVx1NzY4NFx1NTQwRFx1NzlGMFx1NEUzQSAnJ3sxfScnXHUzMDAyCi0gICAgICAgIGN0LXByb3BzLWNvcnJlY3QuNSA9IGN0LXByb3BzLWNvcnJlY3QuNTogXHU3QzdCXHU1NzhCICcnezB9JycgXHU5NTE5XHU4QkVGXHUzMDAyXHU0RTI0XHU0RTJBXHU1QzVFXHU2MDI3XHU1OEYwXHU2NjBFICcnezF9JycgXHU1NDhDICcnezJ9JycgXHU1MTc3XHU2NzA5XHU0RUNFIElEIFx1NkQzRVx1NzUxRlx1NzY4NFx1N0M3Qlx1NTc4Qlx1MzAwMgotICAgICAgICBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjEgPSBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjE6IFx1N0M3Qlx1NTc4QiAnJ3swfScnIFx1NzUzMVx1OTY1MFx1NTIzNlx1NEVDRVx1N0M3Qlx1NTc4QiAnJ3sxfScnIFx1NkQzRVx1NzUxRlx1MzAwMlx1NEY0Nlx1NjYyRiwgJyd7MX0nJyBcdTUxNzdcdTY3MDlcdTc5ODFcdTZCNjJcdTc1MzFcdTk2NTBcdTUyMzZcdTZEM0VcdTc1MUZcdTc2ODQgJ3snZmluYWwnfScgXHU1QzVFXHU2MDI3XHUzMDAyCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMi4xLjEgPSBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjIuMS4xOiBcdTdDN0JcdTU3OEIgJyd7MH0nJyBcdTk1MTlcdThCRUZcdTMwMDJcdTZCNjRcdTdDN0JcdTU3OEJcdTRFMkRcdTc2ODRcdTVDNUVcdTYwMjdcdTc1MjhcdTZDRDUgJyd7MX0nJyBcdTUxNzdcdTY3MDkgJyd7Mn0nJyBcdTc2ODQgJyd1c2UnJyBcdTUwM0MsIFx1OEZEOVx1NEUwRVx1NTdGQVx1N0M3Qlx1NTc4Qlx1NEUyRFx1NzY4NFx1NTMzOVx1OTE0RFx1NUM1RVx1NjAyN1x1NzUyOFx1NkNENVx1NzY4NCAnJ3JlcXVpcmVkJycgXHU1MDNDXHU0RTBEXHU0RTAwXHU4MUY0XHUzMDAyCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMi4xLjIgPSBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjIuMS4yOiBcdTdDN0JcdTU3OEIgJyd7MH0nJyBcdTk1MTlcdThCRUZcdTMwMDJcdTZCNjRcdTdDN0JcdTU3OEJcdTRFMkRcdTc2ODRcdTVDNUVcdTYwMjdcdTc1MjhcdTZDRDUgJyd7MX0nJyBcdTUxNzdcdTY3MDlcdTdDN0JcdTU3OEIgJyd7Mn0nJywgXHU1QjgzXHU0RTBEXHU2NjJGXHU0RUNFXHU1N0ZBXHU3QzdCXHU1NzhCXHU0RTJEXHU3Njg0XHU1MzM5XHU5MTREXHU1QzVFXHU2MDI3XHU3NTI4XHU2Q0Q1XHU3Njg0XHU3QzdCXHU1NzhCICcnezN9JycgXHU2NzA5XHU2NTQ4XHU2RDNFXHU3NTFGXHU3Njg0XHUzMDAyCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMi4xLjMuYSA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMi4xLjMuYTogXHU3QzdCXHU1NzhCICcnezB9JycgXHU5NTE5XHU4QkVGXHUzMDAyXHU2QjY0XHU3QzdCXHU1NzhCXHU0RTJEXHU3Njg0XHU1QzVFXHU2MDI3XHU3NTI4XHU2Q0Q1ICcnezF9JycgXHU1MTc3XHU2NzA5XHU0RTBEXHU1NkZBXHU1QjlBXHU3Njg0XHU2NzA5XHU2NTQ4XHU1MDNDXHU3RUE2XHU2NzVGXHU2NzYxXHU0RUY2LCBcdTgwMENcdTU3RkFcdTdDN0JcdTU3OEJcdTRFMkRcdTc2ODRcdTUzMzlcdTkxNERcdTVDNUVcdTYwMjdcdTc1MjhcdTZDRDVcdTc2ODRcdTY3MDlcdTY1NDhcdTUwM0NcdTdFQTZcdTY3NUZcdTY3NjFcdTRFRjZcdTY2MkZcdTU2RkFcdTVCOUFcdTc2ODRcdTMwMDIKLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4yLjEuMy5iID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4yLjEuMy5iOiBcdTdDN0JcdTU3OEIgJyd7MH0nJyBcdTk1MTlcdThCRUZcdTMwMDJcdTZCNjRcdTdDN0JcdTU3OEJcdTRFMkRcdTc2ODRcdTVDNUVcdTYwMjdcdTc1MjhcdTZDRDUgJyd7MX0nJyBcdTUxNzdcdTY3MDlcdTUwM0NcdTRFM0EgJyd7Mn0nJyBcdTc2ODRcdTU2RkFcdTVCOUFcdTY3MDlcdTY1NDhcdTUwM0NcdTdFQTZcdTY3NUZcdTY3NjFcdTRFRjYsIFx1OEZEOVx1NEUwRVx1NTdGQVx1N0M3Qlx1NTc4Qlx1NEUyRFx1NzY4NFx1NTMzOVx1OTE0RFx1NUM1RVx1NjAyN1x1NzUyOFx1NkNENVx1NzY4NFx1NTZGQVx1NUI5QVx1NjcwOVx1NjU0OFx1NTAzQ1x1N0VBNlx1Njc1Rlx1Njc2MVx1NEVGNlx1NzY4NFx1NTAzQyAnJ3szfScnIFx1NEUwRFx1NEUwMFx1ODFGNFx1MzAwMgotICAgICAgICBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjIuMi5hID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4yLjIuYTogXHU3QzdCXHU1NzhCICcnezB9JycgXHU5NTE5XHU4QkVGXHUzMDAyXHU2QjY0XHU3QzdCXHU1NzhCXHU0RTJEXHU3Njg0XHU1QzVFXHU2MDI3XHU3NTI4XHU2Q0Q1ICcnezF9JycgXHU1NzI4XHU1N0ZBXHU3QzdCXHU1NzhCXHU0RTJEXHU2Q0ExXHU2NzA5XHU1MzM5XHU5MTREXHU3Njg0XHU1QzVFXHU2MDI3XHU3NTI4XHU2Q0Q1LCBcdTVFNzZcdTRFMTRcdTU3RkFcdTdDN0JcdTU3OEJcdTZDQTFcdTY3MDlcdTkwMUFcdTkxNERcdTdCMjZcdTVDNUVcdTYwMjdcdTMwMDIKLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4yLjIuYiA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMi4yLmI6IFx1N0M3Qlx1NTc4QiAnJ3swfScnIFx1OTUxOVx1OEJFRlx1MzAwMlx1NkI2NFx1N0M3Qlx1NTc4Qlx1NEUyRFx1NzY4NFx1NUM1RVx1NjAyN1x1NzUyOFx1NkNENSAnJ3sxfScnIFx1NTcyOFx1NTdGQVx1N0M3Qlx1NTc4Qlx1NEUyRFx1NkNBMVx1NjcwOVx1NTMzOVx1OTE0RFx1NzY4NFx1NUM1RVx1NjAyN1x1NzUyOFx1NkNENSwgXHU1RTc2XHU0RTE0XHU1N0ZBXHU3QzdCXHU1NzhCXHU0RTJEXHU3Njg0XHU5MDFBXHU5MTREXHU3QjI2XHU0RTBEXHU1MTQxXHU4QkI4XHU2QjY0XHU1QzVFXHU2MDI3XHU3NTI4XHU2Q0Q1XHU3Njg0XHU1NDBEXHU3OUYwXHU3QTdBXHU5NUY0ICcnezJ9JydcdTMwMDIKLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4zID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4zOiBcdTdDN0JcdTU3OEIgJyd7MH0nJyBcdTk1MTlcdThCRUZcdTMwMDJcdTU3RkFcdTdDN0JcdTU3OEJcdTRFMkRcdTc2ODRcdTVDNUVcdTYwMjdcdTc1MjhcdTZDRDUgJyd7MX0nJyBcdTc2ODQgUkVRVUlSRUQgXHU0RTNBXHUyMDFDXHU3NzFGXHUyMDFELCBcdTRGNDZcdTU3MjhcdTZEM0VcdTc1MUZcdTdDN0JcdTU3OEJcdTRFMkRcdTZDQTFcdTY3MDlcdTUzMzlcdTkxNERcdTc2ODRcdTVDNUVcdTYwMjdcdTc1MjhcdTZDRDVcdTMwMDIKLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi40LjEgPSBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjQuMTogXHU3QzdCXHU1NzhCICcnezB9JycgXHU5NTE5XHU4QkVGXHUzMDAyXHU2RDNFXHU3NTFGXHU3QzdCXHU1NzhCXHU1MTc3XHU2NzA5XHU0RTAwXHU0RTJBXHU1QzVFXHU2MDI3XHU5MDFBXHU5MTREXHU3QjI2LCBcdTRGNDZcdTU3RkFcdTdDN0JcdTU3OEJcdTRFMERcdTUxNzdcdTY3MDlcdTVDNUVcdTYwMjdcdTkwMUFcdTkxNERcdTdCMjZcdTMwMDIKLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi40LjIgPSBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjQuMjogXHU3QzdCXHU1NzhCICcnezB9JycgXHU5NTE5XHU4QkVGXHUzMDAyXHU2RDNFXHU3NTFGXHU3QzdCXHU1NzhCXHU0RTJEXHU3Njg0XHU5MDFBXHU5MTREXHU3QjI2XHU0RTBEXHU2NjJGXHU1N0ZBXHU3QzdCXHU1NzhCXHU0RTJEXHU5MDFBXHU5MTREXHU3QjI2XHU3Njg0XHU2NzA5XHU2NTQ4XHU5MDFBXHU5MTREXHU3QjI2XHU1QjUwXHU5NkM2XHUzMDAyCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uNC4zID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi40LjM6IFx1N0M3Qlx1NTc4QiAnJ3swfScnIFx1OTUxOVx1OEJFRlx1MzAwMlx1NkQzRVx1NzUxRlx1N0M3Qlx1NTc4QiAoezF9KSBcdTRFMkRcdTkwMUFcdTkxNERcdTdCMjZcdTc2ODRcdTZENDFcdTdBMEJcdTUxODVcdTVCQjlcdTVGMzFcdTRFOEVcdTU3RkFcdTdDN0JcdTU3OEIgKHsyfSkgXHU0RTJEXHU5MDFBXHU5MTREXHU3QjI2XHU3Njg0XHU2RDQxXHU3QTBCXHU1MTg1XHU1QkI5XHUzMDAyCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uNS4yLjIuMSA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uNS4yLjIuMTogXHU3QzdCXHU1NzhCICcnezB9JycgXHU5NTE5XHU4QkVGXHUzMDAyXHU2QjY0XHU3QzdCXHU1NzhCXHU3Njg0XHU3QjgwXHU1MzU1XHU1MTg1XHU1QkI5XHU3QzdCXHU1NzhCICcnezF9JycgXHU0RTBEXHU1NzI4XHU1N0ZBXHU3QzdCXHU1NzhCXHU3Njg0XHU3QjgwXHU1MzU1XHU1MTg1XHU1QkI5XHU3QzdCXHU1NzhCICcnezJ9JycgXHU3Njg0XHU2NzA5XHU2NTQ4XHU5NjUwXHU1MjM2XHU0RTRCXHU1MTg1XHUzMDAyCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uNS4zLjIgPSBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjUuMy4yOiBcdTdDN0JcdTU3OEIgJyd7MH0nJyBcdTk1MTlcdThCRUZcdTMwMDJcdTZCNjRcdTdDN0JcdTU3OEJcdTc2ODRcdTUxODVcdTVCQjlcdTdDN0JcdTU3OEJcdTRFM0FcdTdBN0EsIFx1NEY0Nlx1NTdGQVx1N0M3Qlx1NTc4Qlx1NzY4NFx1NTE4NVx1NUJCOVx1N0M3Qlx1NTc4QiAnJ3sxfScnIFx1NEUwRFx1NEUzQVx1N0E3QVx1NjIxNlx1NEUwRFx1ODBGRFx1NEUzQVx1N0E3QVx1MzAwMgotICAgICAgICBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjUuNC4xLjIgPSBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjUuNC4xLjI6IFx1N0M3Qlx1NTc4QiAnJ3swfScnIFx1OTUxOVx1OEJFRlx1MzAwMlx1NkI2NFx1N0M3Qlx1NTc4Qlx1NzY4NFx1NTE4NVx1NUJCOVx1N0M3Qlx1NTc4Qlx1NEUzQVx1MjAxQ1x1NkRGN1x1NTQwOFx1MjAxRCwgXHU0RjQ2XHU1N0ZBXHU3QzdCXHU1NzhCXHU3Njg0XHU1MTg1XHU1QkI5XHU3QzdCXHU1NzhCICcnezF9JycgXHU0RTBEXHU0RTNBXHUyMDFDXHU2REY3XHU1NDA4XHUyMDFEXHUzMDAyCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uNS40LjIgPSBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjUuNC4yOiBcdTdDN0JcdTU3OEIgJyd7MH0nJyBcdTk1MTlcdThCRUZcdTMwMDJcdTZCNjRcdTdDN0JcdTU3OEJcdTc2ODRcdTdDOTJcdTVCNTBcdTRFMERcdTU3MjhcdTU3RkFcdTdDN0JcdTU3OEJcdTc2ODRcdTdDOTJcdTVCNTBcdTc2ODRcdTY3MDlcdTY1NDhcdTk2NTBcdTUyMzZcdTRFNEJcdTUxODVcdTMwMDIKLSAgICAgICAgZW51bWVyYXRpb24tcmVxdWlyZWQtbm90YXRpb24gPSBlbnVtZXJhdGlvbi1yZXF1aXJlZC1ub3RhdGlvbjogezJ9ICcnezF9JycgXHU0RjdGXHU3NTI4XHU3Njg0IE5PVEFUSU9OIFx1N0M3Qlx1NTc4QiAnJ3swfScnIFx1NUZDNVx1OTg3Qlx1NTE3N1x1NjcwOVx1Njc5QVx1NEUzRVx1OTc2Mlx1NTAzQywgXHU3NTI4XHU0RThFXHU2MzA3XHU1QjlBXHU2QjY0XHU3QzdCXHU1NzhCXHU0RjdGXHU3NTI4XHU3Njg0XHU2Q0U4XHU5MUNBXHU1MTQzXHU3RDIwXHUzMDAyCi0gICAgICAgIGVudW1lcmF0aW9uLXZhbGlkLXJlc3RyaWN0aW9uID0gZW51bWVyYXRpb24tdmFsaWQtcmVzdHJpY3Rpb246IFx1Njc5QVx1NEUzRVx1NTAzQyAnJ3swfScnIFx1NEUwRFx1NTcyOFx1NTdGQVx1N0M3Qlx1NTc4QiB7MX0gXHU3Njg0XHU1MDNDXHU3QTdBXHU5NUY0XHU0RTJEXHUzMDAyCi0gICAgICAgIGUtcHJvcHMtY29ycmVjdC4yID0gZS1wcm9wcy1jb3JyZWN0LjI6IFx1NTE0M1x1N0QyMCAnJ3swfScnIFx1NEUyRFx1NzY4NFx1NTAzQ1x1N0VBNlx1Njc1Rlx1Njc2MVx1NEVGNlx1NzY4NFx1NTAzQyAnJ3sxfScnIFx1NjVFMFx1NjU0OFx1MzAwMgotICAgICAgICBlLXByb3BzLWNvcnJlY3QuNCA9IGUtcHJvcHMtY29ycmVjdC40OiBcdTUxNDNcdTdEMjAgJyd7MH0nJyBcdTc2ODQgJ3sndHlwZSBkZWZpbml0aW9uJ30nIFx1NEUwRFx1NjYyRlx1NEVDRSBzdWJzdGl0dXRpb25IZWFkICcnezF9JycgXHU3Njg0ICd7J3R5cGUgZGVmaW5pdGlvbid9JyBcdTY3MDlcdTY1NDhcdTZEM0VcdTc1MUZcdTc2ODQsIFx1NjIxNlx1ODAwNSAnJ3sxfScnIFx1NzY4NCAneydzdWJzdGl0dXRpb24gZ3JvdXAgZXhjbHVzaW9ucyd9JyBcdTVDNUVcdTYwMjdcdTRFMERcdTUxNDFcdThCQjhcdThGREJcdTg4NENcdTZCNjRcdTZEM0VcdTc1MUZcdTMwMDIKLSAgICAgICAgZS1wcm9wcy1jb3JyZWN0LjUgPSBlLXByb3BzLWNvcnJlY3QuNTogXHU1MTQzXHU3RDIwICcnezB9JycgXHU0RTJEXHU0RTBEXHU4MEZEXHU1MzA1XHU1NDJCICd7J3ZhbHVlIGNvbnN0cmFpbnQnfScsIFx1NTZFMFx1NEUzQVx1NTE0M1x1N0QyMFx1NzY4NCAneyd0eXBlIGRlZmluaXRpb24nfScgXHU2MjE2ICd7J3R5cGUgZGVmaW5pdGlvbid9JyBcdTc2ODQgJ3snY29udGVudCB0eXBlJ30nIFx1NEUzQSBJRCwgXHU2MjE2XHU4MDA1XHU2NjJGXHU0RUNFIElEIFx1NkQzRVx1NzUxRlx1NzY4NFx1MzAwMgotICAgICAgICBlLXByb3BzLWNvcnJlY3QuNiA9IGUtcHJvcHMtY29ycmVjdC42OiBcdTU3MjhcdTUxNDNcdTdEMjAgJyd7MH0nJyBcdTRFMkRcdTY4QzBcdTZENEJcdTUyMzBcdTVGQUFcdTczQUZcdTY2RkZcdTRFRTNcdTdFQzRcdTMwMDIKLSAgICAgICAgZnJhY3Rpb25EaWdpdHMtdmFsaWQtcmVzdHJpY3Rpb24gPSBmcmFjdGlvbkRpZ2l0cy12YWxpZC1yZXN0cmljdGlvbjogXHU1NzI4IHsyfSBcdTc2ODRcdTVCOUFcdTRFNDlcdTRFMkQsIFx1OTc2MiAnJ2ZyYWN0aW9uRGlnaXRzJycgXHU3Njg0XHU1MDNDICcnezB9JycgXHU2NUUwXHU2NTQ4LCBcdTU2RTBcdTRFM0FcdThCRTVcdTUwM0NcdTVGQzVcdTk4N0JcdTVDMEZcdTRFOEVcdTdCNDlcdTRFOEUgJydmcmFjdGlvbkRpZ2l0cycnIFx1NzY4NFx1NTAzQywgXHU0RjQ2XHU1NzI4XHU1MzlGXHU3RUE3XHU3QzdCXHU1NzhCXHU0RTRCXHU0RTAwXHU0RTJEXHU1REYyXHU1QzA2XHU1MTc2XHU4QkJFXHU3RjZFXHU0RTNBICcnezF9JydcdTMwMDIKLSAgICAgICAgZnJhY3Rpb25EaWdpdHMtdG90YWxEaWdpdHMgPSBmcmFjdGlvbkRpZ2l0cy10b3RhbERpZ2l0czogXHU1NzI4IHsyfSBcdTc2ODRcdTVCOUFcdTRFNDlcdTRFMkQsIFx1OTc2MiAnJ2ZyYWN0aW9uRGlnaXRzJycgXHU3Njg0XHU1MDNDICcnezB9JycgXHU2NUUwXHU2NTQ4LCBcdTU2RTBcdTRFM0FcdThCRTVcdTUwM0NcdTVGQzVcdTk4N0JcdTVDMEZcdTRFOEVcdTdCNDlcdTRFOEUgJyd0b3RhbERpZ2l0cycnIFx1NzY4NFx1NTAzQyAnJ3sxfScnXHUzMDAyCi0gICAgICAgIGxlbmd0aC1taW5MZW5ndGgtbWF4TGVuZ3RoLjEuMSA9IGxlbmd0aC1taW5MZW5ndGgtbWF4TGVuZ3RoLjEuMTogXHU1QkY5XHU0RThFXHU3QzdCXHU1NzhCIHswfSwgXHU5NTdGXHU1RUE2ICcnezF9JycgXHU3Njg0XHU1MDNDXHU1QzBGXHU0RThFIG1pbkxlbmd0aCBcdTc2ODRcdTUwM0MgJyd7Mn0nJyBcdTY2MkZcdTk1MTlcdThCRUZcdTc2ODRcdTMwMDIKLSAgICAgICAgbGVuZ3RoLW1pbkxlbmd0aC1tYXhMZW5ndGguMS4yLmEgPSBsZW5ndGgtbWluTGVuZ3RoLW1heExlbmd0aC4xLjIuYTogXHU1QkY5XHU0RThFXHU3QzdCXHU1NzhCIHswfSwgXHU1OTgyXHU2NzlDXHU1RjUzXHU1MjREXHU5NjUwXHU1MjM2XHU1MTc3XHU2NzA5IG1pbkxlbmd0aCBcdTk3NjJcdTVFNzZcdTRFMTRcdTVGNTNcdTUyNERcdTk2NTBcdTUyMzZcdTYyMTZcdTU3RkFcdTdDN0JcdTU3OEJcdTUxNzdcdTY3MDkgbGVuZ3RoIFx1OTc2MiwgXHU1MjE5XHU1N0ZBXHU3QzdCXHU1NzhCXHU2Q0ExXHU2NzA5IG1pbkxlbmd0aCBcdTk3NjJcdTY2MkZcdTk1MTlcdThCRUZcdTc2ODRcdTMwMDIKLSAgICAgICAgbGVuZ3RoLW1pbkxlbmd0aC1tYXhMZW5ndGguMS4yLmIgPSBsZW5ndGgtbWluTGVuZ3RoLW1heExlbmd0aC4xLjIuYjogXHU1QkY5XHU0RThFXHU3QzdCXHU1NzhCIHswfSwgXHU1RjUzXHU1MjREIG1pbkxlbmd0aCAnJ3sxfScnIFx1NEUwRFx1N0I0OVx1NEU4RVx1NTdGQVx1N0M3Qlx1NTc4QiBtaW5MZW5ndGggJyd7Mn0nJyBcdTY2MkZcdTk1MTlcdThCRUZcdTc2ODRcdTMwMDIKLSAgICAgICAgbGVuZ3RoLW1pbkxlbmd0aC1tYXhMZW5ndGguMi4xID0gbGVuZ3RoLW1pbkxlbmd0aC1tYXhMZW5ndGguMi4xOiBcdTVCRjlcdTRFOEVcdTdDN0JcdTU3OEIgezB9LCBcdTk1N0ZcdTVFQTYgJyd7MX0nJyBcdTc2ODRcdTUwM0NcdTU5MjdcdTRFOEUgbWF4TGVuZ3RoICcnezJ9JycgXHU3Njg0XHU1MDNDXHU2NjJGXHU5NTE5XHU4QkVGXHU3Njg0XHUzMDAyCi0gICAgICAgIGxlbmd0aC1taW5MZW5ndGgtbWF4TGVuZ3RoLjIuMi5hID0gbGVuZ3RoLW1pbkxlbmd0aC1tYXhMZW5ndGguMi4yLmE6IFx1NUJGOVx1NEU4RVx1N0M3Qlx1NTc4QiB7MH0sIFx1NTk4Mlx1Njc5Q1x1NUY1M1x1NTI0RFx1OTY1MFx1NTIzNlx1NTE3N1x1NjcwOSBtYXhMZW5ndGggXHU5NzYyXHU1RTc2XHU0RTE0XHU1RjUzXHU1MjREXHU5NjUwXHU1MjM2XHU2MjE2XHU1N0ZBXHU3QzdCXHU1NzhCXHU1MTc3XHU2NzA5IGxlbmd0aCBcdTk3NjIsIFx1NTIxOVx1NTdGQVx1N0M3Qlx1NTc4Qlx1NkNBMVx1NjcwOSBtYXhMZW5ndGggXHU5NzYyXHU2NjJGXHU5NTE5XHU4QkVGXHU3Njg0XHUzMDAyCi0gICAgICAgIGxlbmd0aC1taW5MZW5ndGgtbWF4TGVuZ3RoLjIuMi5iID0gbGVuZ3RoLW1pbkxlbmd0aC1tYXhMZW5ndGguMi4yLmI6IFx1NUJGOVx1NEU4RVx1N0M3Qlx1NTc4QiB7MH0sIFx1NUY1M1x1NTI0RCBtYXhMZW5ndGggJyd7MX0nJyBcdTRFMERcdTdCNDlcdTRFOEVcdTU3RkFcdTdDN0JcdTU3OEIgbWF4TGVuZ3RoICcnezJ9JycgXHU2NjJGXHU5NTE5XHU4QkVGXHU3Njg0XHUzMDAyCi0gICAgICAgIGxlbmd0aC12YWxpZC1yZXN0cmljdGlvbiA9IGxlbmd0aC12YWxpZC1yZXN0cmljdGlvbjogXHU3QzdCXHU1NzhCICcnezJ9JycgXHU5NTE5XHU4QkVGXHUzMDAyXHU5NTdGXHU1RUE2XHU3Njg0XHU1MDNDICcnezB9JycgXHU1RkM1XHU5ODdCXHU3QjQ5XHU0RThFXHU1N0ZBXHU3QzdCXHU1NzhCICcnezF9JycgXHU3Njg0XHU5NTdGXHU1RUE2XHU1MDNDXHUzMDAyCi0gICAgICAgIG1heEV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4xID0gbWF4RXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjE6IFx1N0M3Qlx1NTc4QiAnJ3syfScnIFx1OTUxOVx1OEJFRlx1MzAwMm1heEV4Y2x1c2l2ZSBcdTUwM0MgJyd7MH0nJyBcdTVGQzVcdTk4N0JcdTVDMEZcdTRFOEVcdTdCNDlcdTRFOEVcdTU3RkFcdTdDN0JcdTU3OEIgJyd7MX0nJyBcdTc2ODQgbWF4RXhjbHVzaXZlXHUzMDAyCi0gICAgICAgIG1heEV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4yID0gbWF4RXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjI6IFx1N0M3Qlx1NTc4QiAnJ3syfScnIFx1OTUxOVx1OEJFRlx1MzAwMm1heEV4Y2x1c2l2ZSBcdTUwM0MgJyd7MH0nJyBcdTVGQzVcdTk4N0JcdTVDMEZcdTRFOEVcdTdCNDlcdTRFOEVcdTU3RkFcdTdDN0JcdTU3OEIgJyd7MX0nJyBcdTc2ODQgbWF4SW5jbHVzaXZlXHUzMDAyCi0gICAgICAgIG1heEV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4zID0gbWF4RXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjM6IFx1N0M3Qlx1NTc4QiAnJ3syfScnIFx1OTUxOVx1OEJFRlx1MzAwMm1heEV4Y2x1c2l2ZSBcdTUwM0MgJyd7MH0nJyBcdTVGQzVcdTk4N0JcdTU5MjdcdTRFOEVcdTU3RkFcdTdDN0JcdTU3OEIgJyd7MX0nJyBcdTc2ODQgbWluSW5jbHVzaXZlXHUzMDAyCi0gICAgICAgIG1heEV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi40ID0gbWF4RXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjQ6IFx1N0M3Qlx1NTc4QiAnJ3syfScnIFx1OTUxOVx1OEJFRlx1MzAwMm1heEV4Y2x1c2l2ZSBcdTUwM0MgJyd7MH0nJyBcdTVGQzVcdTk4N0JcdTU5MjdcdTRFOEVcdTU3RkFcdTdDN0JcdTU3OEIgJyd7MX0nJyBcdTc2ODQgbWluRXhjbHVzaXZlXHUzMDAyCi0gICAgICAgIG1heEluY2x1c2l2ZS1tYXhFeGNsdXNpdmUgPSBtYXhJbmNsdXNpdmUtbWF4RXhjbHVzaXZlOiBcdTRFM0FcdTU0MENcdTRFMDBcdTRFMkFcdTY1NzBcdTYzNkVcdTdDN0JcdTU3OEJcdTU0MENcdTY1RjZcdTYzMDdcdTVCOUEgbWF4SW5jbHVzaXZlIFx1NTQ4QyBtYXhFeGNsdXNpdmUgXHU2NjJGXHU5NTE5XHU4QkVGXHU3Njg0XHUzMDAyXHU1NzI4IHsyfSBcdTRFMkQsIG1heEluY2x1c2l2ZSA9ICcnezB9JycgXHU1RTc2XHU0RTE0IG1heEV4Y2x1c2l2ZSA9ICcnezF9JydcdTMwMDIKLSAgICAgICAgbWF4SW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjEgPSBtYXhJbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMTogXHU3QzdCXHU1NzhCICcnezJ9JycgXHU5NTE5XHU4QkVGXHUzMDAybWF4SW5jbHVzaXZlIFx1NTAzQyAnJ3swfScnIFx1NUZDNVx1OTg3Qlx1NUMwRlx1NEU4RVx1N0I0OVx1NEU4RVx1NTdGQVx1N0M3Qlx1NTc4QiAnJ3sxfScnIFx1NzY4NCBtYXhJbmNsdXNpdmVcdTMwMDIKLSAgICAgICAgbWF4SW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjIgPSBtYXhJbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMjogXHU3QzdCXHU1NzhCICcnezJ9JycgXHU5NTE5XHU4QkVGXHUzMDAybWF4SW5jbHVzaXZlIFx1NTAzQyAnJ3swfScnIFx1NUZDNVx1OTg3Qlx1NUMwRlx1NEU4RVx1NTdGQVx1N0M3Qlx1NTc4QiAnJ3sxfScnIFx1NzY4NCBtYXhFeGNsdXNpdmVcdTMwMDIKLSAgICAgICAgbWF4SW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjMgPSBtYXhJbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMzogXHU3QzdCXHU1NzhCICcnezJ9JycgXHU5NTE5XHU4QkVGXHUzMDAybWF4SW5jbHVzaXZlIFx1NTAzQyAnJ3swfScnIFx1NUZDNVx1OTg3Qlx1NTkyN1x1NEU4RVx1N0I0OVx1NEU4RVx1NTdGQVx1N0M3Qlx1NTc4QiAnJ3sxfScnIFx1NzY4NCBtaW5JbmNsdXNpdmVcdTMwMDIKLSAgICAgICAgbWF4SW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjQgPSBtYXhJbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uNDogXHU3QzdCXHU1NzhCICcnezJ9JycgXHU5NTE5XHU4QkVGXHUzMDAybWF4SW5jbHVzaXZlIFx1NTAzQyAnJ3swfScnIFx1NUZDNVx1OTg3Qlx1NTkyN1x1NEU4RVx1NTdGQVx1N0M3Qlx1NTc4QiAnJ3sxfScnIFx1NzY4NCBtaW5FeGNsdXNpdmVcdTMwMDIKLSAgICAgICAgbWF4TGVuZ3RoLXZhbGlkLXJlc3RyaWN0aW9uID0gbWF4TGVuZ3RoLXZhbGlkLXJlc3RyaWN0aW9uOiBcdTU3MjggezJ9IFx1NzY4NFx1NUI5QVx1NEU0OVx1NEUyRCwgbWF4TGVuZ3RoIFx1NTAzQyAnJ3swfScnIFx1NUZDNVx1OTg3Qlx1NUMwRlx1NEU4RVx1N0I0OVx1NEU4RVx1NTdGQVx1N0M3Qlx1NTc4QiAnJ3sxfScnIFx1NzY4NCBtYXhMZW5ndGhcdTMwMDIKLSAgICAgICAgbWctcHJvcHMtY29ycmVjdC4yID0gbWctcHJvcHMtY29ycmVjdC4yOiBcdTU3MjhcdTdFQzQgJyd7MH0nJyBcdTRFMkRcdTY4QzBcdTZENEJcdTUyMzBcdTVGQUFcdTczQUZcdTVCOUFcdTRFNDlcdTMwMDJcdTkwMTJcdTVGNTJcdThEREZcdTk2OEZcdTdDOTJcdTVCNTBcdTc2ODQgJ3sndGVybSd9JyBcdTRFRTVcdTRFMEJcdTUwM0NcdTRGMUFcdTVGMTVcdTVCRkNcdTUyMzBcdTUxNzYgJ3sndGVybSd9JyBcdTY2MkZcdTdFQzRcdTgxRUFcdThFQUJcdTc2ODRcdTdDOTJcdTVCNTBcdTMwMDIKLSAgICAgICAgbWluRXhjbHVzaXZlLWxlc3MtdGhhbi1lcXVhbC10by1tYXhFeGNsdXNpdmUgPSBtaW5FeGNsdXNpdmUtbGVzcy10aGFuLWVxdWFsLXRvLW1heEV4Y2x1c2l2ZTogXHU1NzI4IHsyfSBcdTc2ODRcdTVCOUFcdTRFNDlcdTRFMkQsIG1pbkV4Y2x1c2l2ZSBcdTUwM0MgJyd7MH0nJyBcdTVGQzVcdTk4N0JcdTVDMEZcdTRFOEVcdTdCNDlcdTRFOEUgbWF4RXhjbHVzaXZlIFx1NTAzQyAnJ3sxfScnXHUzMDAyCi0gICAgICAgIG1pbkV4Y2x1c2l2ZS1sZXNzLXRoYW4tbWF4SW5jbHVzaXZlID0gbWluRXhjbHVzaXZlLWxlc3MtdGhhbi1tYXhJbmNsdXNpdmU6IFx1NTcyOCB7Mn0gXHU3Njg0XHU1QjlBXHU0RTQ5XHU0RTJELCBtaW5FeGNsdXNpdmUgXHU1MDNDICcnezB9JycgXHU1RkM1XHU5ODdCXHU1QzBGXHU0RThFIG1heEluY2x1c2l2ZSBcdTUwM0MgJyd7MX0nJ1x1MzAwMgotICAgICAgICBtaW5FeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMSA9IG1pbkV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4xOiBcdTdDN0JcdTU3OEIgJyd7Mn0nJyBcdTk1MTlcdThCRUZcdTMwMDJtaW5FeGNsdXNpdmUgXHU1MDNDICcnezB9JycgXHU1RkM1XHU5ODdCXHU1OTI3XHU0RThFXHU3QjQ5XHU0RThFXHU1N0ZBXHU3QzdCXHU1NzhCICcnezF9JycgXHU3Njg0IG1pbkV4Y2x1c2l2ZVx1MzAwMgotICAgICAgICBtaW5FeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMiA9IG1pbkV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4yOiBcdTdDN0JcdTU3OEIgJyd7Mn0nJyBcdTk1MTlcdThCRUZcdTMwMDJtaW5FeGNsdXNpdmUgXHU1MDNDICcnezB9JycgXHU1RkM1XHU5ODdCXHU1QzBGXHU0RThFXHU3QjQ5XHU0RThFXHU1N0ZBXHU3QzdCXHU1NzhCICcnezF9JycgXHU3Njg0IG1heEluY2x1c2l2ZVx1MzAwMgotICAgICAgICBtaW5FeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMyA9IG1pbkV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4zOiBcdTdDN0JcdTU3OEIgJyd7Mn0nJyBcdTk1MTlcdThCRUZcdTMwMDJtaW5FeGNsdXNpdmUgXHU1MDNDICcnezB9JycgXHU1RkM1XHU5ODdCXHU1OTI3XHU0RThFXHU3QjQ5XHU0RThFXHU1N0ZBXHU3QzdCXHU1NzhCICcnezF9JycgXHU3Njg0IG1pbkluY2x1c2l2ZVx1MzAwMgotICAgICAgICBtaW5FeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uNCA9IG1pbkV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi40OiBcdTdDN0JcdTU3OEIgJyd7Mn0nJyBcdTk1MTlcdThCRUZcdTMwMDJtaW5FeGNsdXNpdmUgXHU1MDNDICcnezB9JycgXHU1RkM1XHU5ODdCXHU1QzBGXHU0RThFXHU1N0ZBXHU3QzdCXHU1NzhCICcnezF9JycgXHU3Njg0IG1heEV4Y2x1c2l2ZVx1MzAwMgotICAgICAgICBtaW5JbmNsdXNpdmUtbGVzcy10aGFuLWVxdWFsLXRvLW1heEluY2x1c2l2ZSA9IG1pbkluY2x1c2l2ZS1sZXNzLXRoYW4tZXF1YWwtdG8tbWF4SW5jbHVzaXZlOiBcdTU3MjggezJ9IFx1NzY4NFx1NUI5QVx1NEU0OVx1NEUyRCwgbWluSW5jbHVzaXZlIFx1NTAzQyAnJ3swfScnIFx1NUZDNVx1OTg3Qlx1NUMwRlx1NEU4RVx1N0I0OVx1NEU4RSBtYXhJbmNsdXNpdmUgXHU1MDNDICcnezF9JydcdTMwMDIKLSAgICAgICAgbWluSW5jbHVzaXZlLWxlc3MtdGhhbi1tYXhFeGNsdXNpdmUgPSBtaW5JbmNsdXNpdmUtbGVzcy10aGFuLW1heEV4Y2x1c2l2ZTogXHU1NzI4IHsyfSBcdTc2ODRcdTVCOUFcdTRFNDlcdTRFMkQsIG1pbkluY2x1c2l2ZSBcdTUwM0MgJyd7MH0nJyBcdTVGQzVcdTk4N0JcdTVDMEZcdTRFOEUgbWF4RXhjbHVzaXZlIFx1NTAzQyAnJ3sxfScnXHUzMDAyCi0gICAgICAgIG1pbkluY2x1c2l2ZS1taW5FeGNsdXNpdmUgPSBtaW5JbmNsdXNpdmUtbWluRXhjbHVzaXZlOiBcdTRFM0FcdTU0MENcdTRFMDBcdTRFMkFcdTY1NzBcdTYzNkVcdTdDN0JcdTU3OEJcdTU0MENcdTY1RjZcdTYzMDdcdTVCOUEgbWluSW5jbHVzaXZlIFx1NTQ4QyBtaW5FeGNsdXNpdmUgXHU2NjJGXHU5NTE5XHU4QkVGXHU3Njg0XHUzMDAyXHU1NzI4IHsyfSBcdTRFMkQsIG1pbkluY2x1c2l2ZSA9ICcnezB9JycgXHU1RTc2XHU0RTE0IG1pbkV4Y2x1c2l2ZSA9ICcnezF9JydcdTMwMDIKLSAgICAgICAgbWluSW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjEgPSBtaW5JbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMTogXHU3QzdCXHU1NzhCICcnezJ9JycgXHU5NTE5XHU4QkVGXHUzMDAybWluSW5jbHVzaXZlIFx1NTAzQyAnJ3swfScnIFx1NUZDNVx1OTg3Qlx1NTkyN1x1NEU4RVx1N0I0OVx1NEU4RVx1NTdGQVx1N0M3Qlx1NTc4QiAnJ3sxfScnIFx1NzY4NCBtaW5JbmNsdXNpdmVcdTMwMDIKLSAgICAgICAgbWluSW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjIgPSBtaW5JbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMjogXHU3QzdCXHU1NzhCICcnezJ9JycgXHU5NTE5XHU4QkVGXHUzMDAybWluSW5jbHVzaXZlIFx1NTAzQyAnJ3swfScnIFx1NUZDNVx1OTg3Qlx1NUMwRlx1NEU4RVx1N0I0OVx1NEU4RVx1NTdGQVx1N0M3Qlx1NTc4QiAnJ3sxfScnIFx1NzY4NCBtYXhJbmNsdXNpdmVcdTMwMDIKLSAgICAgICAgbWluSW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjMgPSBtaW5JbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMzogXHU3QzdCXHU1NzhCICcnezJ9JycgXHU5NTE5XHU4QkVGXHUzMDAybWluSW5jbHVzaXZlIFx1NTAzQyAnJ3swfScnIFx1NUZDNVx1OTg3Qlx1NTkyN1x1NEU4RVx1NTdGQVx1N0M3Qlx1NTc4QiAnJ3sxfScnIFx1NzY4NCBtaW5FeGNsdXNpdmVcdTMwMDIKLSAgICAgICAgbWluSW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjQgPSBtaW5JbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uNDogXHU3QzdCXHU1NzhCICcnezJ9JycgXHU5NTE5XHU4QkVGXHUzMDAybWluSW5jbHVzaXZlIFx1NTAzQyAnJ3swfScnIFx1NUZDNVx1OTg3Qlx1NUMwRlx1NEU4RVx1NTdGQVx1N0M3Qlx1NTc4QiAnJ3sxfScnIFx1NzY4NCBtYXhFeGNsdXNpdmVcdTMwMDIKLSAgICAgICAgbWluTGVuZ3RoLWxlc3MtdGhhbi1lcXVhbC10by1tYXhMZW5ndGggPSBtaW5MZW5ndGgtbGVzcy10aGFuLWVxdWFsLXRvLW1heExlbmd0aDogXHU1NzI4IHsyfSBcdTc2ODRcdTVCOUFcdTRFNDlcdTRFMkQsIG1pbkxlbmd0aCBcdTc2ODRcdTUwM0MgJyd7MH0nJyBcdTVGQzVcdTk4N0JcdTVDMEZcdTRFOEUgbWF4TGVuZ3RoIFx1NzY4NFx1NTAzQyAnJ3sxfScnXHUzMDAyCi0gICAgICAgIG1pbkxlbmd0aC12YWxpZC1yZXN0cmljdGlvbiA9IG1pbkxlbmd0aC12YWxpZC1yZXN0cmljdGlvbjogXHU1NzI4IHsyfSBcdTc2ODRcdTVCOUFcdTRFNDlcdTRFMkQsIG1pbkxlbmd0aCAnJ3swfScnIFx1NUZDNVx1OTg3Qlx1NTkyN1x1NEU4RVx1N0I0OVx1NEU4RVx1NTdGQVx1N0M3Qlx1NTc4Qlx1NzY4NCBtaW5MZW5ndGggJyd7MX0nJ1x1MzAwMgotICAgICAgICBuby14bWxucyA9IG5vLXhtbG5zOiBcdTVDNUVcdTYwMjdcdTU4RjBcdTY2MEVcdTc2ODQge25hbWV9IFx1NEUwRFx1ODBGRFx1NEUwRSAneG1sbnMnIFx1NTMzOVx1OTE0RFx1MzAwMgotICAgICAgICBuby14c2kgPSBuby14c2k6IFx1NUM1RVx1NjAyN1x1NThGMFx1NjYwRVx1NzY4NCAneyd0YXJnZXQgbmFtZXNwYWNlJ30nIFx1NEUwRFx1ODBGRFx1NEUwRSAnJ3swfScnIFx1NTMzOVx1OTE0RFx1MzAwMgotICAgICAgICBwLXByb3BzLWNvcnJlY3QuMi4xID0gcC1wcm9wcy1jb3JyZWN0LjIuMTogXHU1NzI4ICcnezB9JycgXHU3Njg0XHU1OEYwXHU2NjBFXHU0RTJELCAnJ21pbk9jY3VycycnIFx1NzY4NFx1NTAzQ1x1NEUzQSAnJ3sxfScnLCBcdTRGNDZcdThCRTVcdTUwM0NcdTRFMERcdTgwRkRcdTU5MjdcdTRFOEUgJydtYXhPY2N1cnMnJyBcdTc2ODRcdTUwM0MgJyd7Mn0nJ1x1MzAwMgotICAgICAgICByY2FzZS1NYXBBbmRTdW0uMSA9IHJjYXNlLU1hcEFuZFN1bS4xOiBcdTdDOTJcdTVCNTBcdTRFNEJcdTk1RjRcdTZDQTFcdTY3MDlcdTVCOENcdTY1NzRcdTc2ODRcdTUyOUZcdTgwRkRcdTY2MjBcdTVDMDRcdTMwMDIKLSAgICAgICAgcmNhc2UtTWFwQW5kU3VtLjIgPSByY2FzZS1NYXBBbmRTdW0uMjogXHU3RUM0XHU3Njg0XHU1M0QxXHU3NTFGXHU4MzAzXHU1NkY0ICh7MH0sezF9KSBcdTRFMERcdTU3MjhcdTU3RkFcdTdFQzRcdTc2ODRcdTUzRDFcdTc1MUZcdTgzMDNcdTU2RjQgKHsyfSx7M30pIFx1NzY4NFx1NjcwOVx1NjU0OFx1OTY1MFx1NTIzNlx1NEU0Qlx1NTE4NVx1MzAwMgotICAgICAgICByY2FzZS1OYW1lQW5kVHlwZU9LLjEgPSByY2FzZS1OYW1lQW5kVHlwZU9LLjE6IFx1NTE0M1x1N0QyMFx1NzY4NFx1NTQwRFx1NzlGMFx1NTQ4Q1x1NzZFRVx1NjgwN1x1NTQwRFx1NzlGMFx1N0E3QVx1OTVGNFx1NEUwRFx1NzZGOFx1NTQwQzogXHU1NDBEXHU3OUYwXHU3QTdBXHU5NUY0ICcnezF9JycgXHU0RTJEXHU3Njg0XHU1MTQzXHU3RDIwXHU0RTNBICcnezB9JycsIFx1NTQwRFx1NzlGMFx1N0E3QVx1OTVGNCAnJ3szfScnIFx1NEUyRFx1NzY4NFx1NTE0M1x1N0QyMFx1NEUzQSAnJ3syfScnXHUzMDAyCi0gICAgICAgIHJjYXNlLU5hbWVBbmRUeXBlT0suMiA9IHJjYXNlLU5hbWVBbmRUeXBlT0suMjogXHU1MTc2ICd7J3Rlcm0nfScgXHU0RTNBXHU1MTQzXHU3RDIwXHU1OEYwXHU2NjBFICcnezB9JycgXHU3Njg0XHU3QzkyXHU1QjUwXHU5NTE5XHU4QkVGXHUzMDAyXHU1MTQzXHU3RDIwXHU1OEYwXHU2NjBFXHU3Njg0ICd7J25pbGxhYmxlJ30nIFx1NEUzQVx1MjAxQ1x1NzcxRlx1MjAxRCwgXHU0RjQ2XHU1N0ZBXHU3QzdCXHU1NzhCXHU0RTJEXHU1QkY5XHU1RTk0XHU3Njg0XHU3QzkyXHU1QjUwXHU1MTc3XHU2NzA5ICd7J25pbGxhYmxlJ30nIFx1NEUzQVx1MjAxQ1x1NTA0N1x1MjAxRFx1NzY4NFx1NTE0M1x1N0QyMFx1NThGMFx1NjYwRVx1MzAwMgotICAgICAgICByY2FzZS1OYW1lQW5kVHlwZU9LLjMgPSByY2FzZS1OYW1lQW5kVHlwZU9LLjM6IFx1NTE3NiAneyd0ZXJtJ30nIFx1NEUzQVx1NTE0M1x1N0QyMFx1NThGMFx1NjYwRSAnJ3swfScnIFx1NzY4NFx1N0M5Mlx1NUI1MFx1OTUxOVx1OEJFRlx1MzAwMlx1OEJFNVx1N0M5Mlx1NUI1MFx1NzY4NFx1NTNEMVx1NzUxRlx1ODMwM1x1NTZGNCAoezF9LHsyfSkgXHU0RTBEXHU1NzI4XHU1N0ZBXHU3QzdCXHU1NzhCXHU0RTJEXHU1QkY5XHU1RTk0XHU3QzkyXHU1QjUwXHU3Njg0XHU4MzAzXHU1NkY0ICh7M30sezR9KSBcdTc2ODRcdTY3MDlcdTY1NDhcdTk2NTBcdTUyMzZcdTRFNEJcdTUxODVcdTMwMDIKLSAgICAgICAgcmNhc2UtTmFtZUFuZFR5cGVPSy40LmEgPSByY2FzZS1OYW1lQW5kVHlwZU9LLjQuYTogXHU1MTQzXHU3RDIwICcnezB9JycgXHU0RTBEXHU2NjJGXHU1NkZBXHU1QjlBXHU3Njg0LCBcdTRGNDZcdTU3RkFcdTdDN0JcdTU3OEJcdTRFMkRcdTc2ODRcdTVCRjlcdTVFOTRcdTUxNDNcdTdEMjBcdTY2MkZcdTU2RkFcdTVCOUFcdTc2ODQsIFx1NEUxNFx1NTAzQ1x1NEUzQSAnJ3sxfScnXHUzMDAyCi0gICAgICAgIHJjYXNlLU5hbWVBbmRUeXBlT0suNC5iID0gcmNhc2UtTmFtZUFuZFR5cGVPSy40LmI6IFx1NTE0M1x1N0QyMCAnJ3swfScnIFx1NjYyRlx1NTZGQVx1NUI5QVx1NzY4NCwgXHU0RTE0XHU1MDNDXHU0RTNBICcnezF9JycsIFx1NEY0Nlx1NTdGQVx1N0M3Qlx1NTc4Qlx1NEUyRFx1NzY4NFx1NUJGOVx1NUU5NFx1NTE0M1x1N0QyMFx1NjYyRlx1NTZGQVx1NUI5QVx1NzY4NCwgXHU0RTE0XHU1MDNDXHU0RTNBICcnezJ9JydcdTMwMDIKLSAgICAgICAgcmNhc2UtTmFtZUFuZFR5cGVPSy41ID0gcmNhc2UtTmFtZUFuZFR5cGVPSy41OiBcdTUxNDNcdTdEMjAgJyd7MH0nJyBcdTc2ODRcdThFQUJcdTRFRkRcdTdFQTZcdTY3NUZcdTY3NjFcdTRFRjZcdTRFMERcdTY2MkZcdTU3RkFcdTdDN0JcdTU3OEJcdTRFMkRcdTkwQTNcdTRFOUJcdThFQUJcdTRFRkRcdTdFQTZcdTY3NUZcdTY3NjFcdTRFRjZcdTc2ODRcdTVCNTBcdTk2QzZcdTMwMDIKLSAgICAgICAgcmNhc2UtTmFtZUFuZFR5cGVPSy42ID0gcmNhc2UtTmFtZUFuZFR5cGVPSy42OiBcdTUxNDNcdTdEMjAgJyd7MH0nJyBcdTc2ODRcdTRFMERcdTYzQTVcdTUzRDdcdTY2RkZcdTRFRTNcdTRFMERcdTY2MkZcdTU3RkFcdTUxNDNcdTdEMjBcdTRFMkRcdTRFMERcdTYzQTVcdTUzRDdcdTY2RkZcdTRFRTNcdTc2ODRcdThEODVcdTk2QzZcdTMwMDIKLSAgICAgICAgcmNhc2UtTmFtZUFuZFR5cGVPSy43ID0gcmNhc2UtTmFtZUFuZFR5cGVPSy43OiBcdTUxNDNcdTdEMjAgJyd7MH0nJyBcdTc2ODRcdTdDN0JcdTU3OEIgJyd7MX0nJyBcdTRFMERcdTY2MkZcdTRFQ0VcdTU3RkFcdTUxNDNcdTdEMjBcdTc2ODRcdTdDN0JcdTU3OEIgJyd7Mn0nJyBcdTZEM0VcdTc1MUZcdTc2ODRcdTMwMDIKLSAgICAgICAgcmNhc2UtTlNDb21wYXQuMSA9IHJjYXNlLU5TQ29tcGF0LjE6IFx1NTE0M1x1N0QyMCAnJ3swfScnIFx1NTE3N1x1NjcwOVx1NTQwRFx1NzlGMFx1N0E3QVx1OTVGNCAnJ3sxfScnLCBcdTU3MjhcdTU3RkFcdTUxNDNcdTdEMjBcdTRFMkQsIFx1OTAxQVx1OTE0RFx1N0IyNlx1NEUwRFx1NTE0MVx1OEJCOFx1NTE3N1x1NjcwOVx1NkI2NFx1NTQwRFx1NzlGMFx1N0E3QVx1OTVGNFx1MzAwMgotICAgICAgICByY2FzZS1OU0NvbXBhdC4yID0gcmNhc2UtTlNDb21wYXQuMjogXHU1MTc2ICd7J3Rlcm0nfScgXHU0RTNBXHU1MTQzXHU3RDIwXHU1OEYwXHU2NjBFICcnezB9JycgXHU3Njg0XHU3QzkyXHU1QjUwXHU5NTE5XHU4QkVGXHUzMDAyXHU4QkU1XHU3QzkyXHU1QjUwXHU3Njg0XHU1M0QxXHU3NTFGXHU4MzAzXHU1NkY0ICh7MX0sezJ9KSBcdTRFMERcdTU3MjhcdTU3RkFcdTdDN0JcdTU3OEJcdTRFMkRcdTVCRjlcdTVFOTRcdTdDOTJcdTVCNTBcdTc2ODRcdTgzMDNcdTU2RjQgKHszfSx7NH0pIFx1NzY4NFx1NjcwOVx1NjU0OFx1OTY1MFx1NTIzNlx1NEU0Qlx1NTE4NVx1MzAwMgotICAgICAgICByY2FzZS1OU1JlY3Vyc2VDaGVja0NhcmRpbmFsaXR5LjEgPSByY2FzZS1OU1JlY3Vyc2VDaGVja0NhcmRpbmFsaXR5LjE6IFx1N0M5Mlx1NUI1MFx1NEU0Qlx1OTVGNFx1NkNBMVx1NjcwOVx1NUI4Q1x1NjU3NFx1NzY4NFx1NTI5Rlx1ODBGRFx1NjYyMFx1NUMwNFx1MzAwMgotICAgICAgICByY2FzZS1OU1JlY3Vyc2VDaGVja0NhcmRpbmFsaXR5LjIgPSByY2FzZS1OU1JlY3Vyc2VDaGVja0NhcmRpbmFsaXR5LjI6IFx1N0VDNFx1NzY4NFx1NTNEMVx1NzUxRlx1ODMwM1x1NTZGNCAoezB9LHsxfSkgXHU0RTBEXHU1NzI4XHU1N0ZBXHU2NzJDXHU5MDFBXHU5MTREXHU3QjI2XHU4MzAzXHU1NkY0ICh7Mn0sezN9KSBcdTc2ODRcdTY3MDlcdTY1NDhcdTk2NTBcdTUyMzZcdTRFNEJcdTUxODVcdTMwMDIKLSAgICAgICAgcmNhc2UtTlNTdWJzZXQuMSA9IHJjYXNlLU5TU3Vic2V0LjE6IFx1OTAxQVx1OTE0RFx1N0IyNlx1NEUwRFx1NjYyRlx1NTdGQVx1NjcyQ1x1OTAxQVx1OTE0RFx1N0IyNlx1NEUyRFx1NUJGOVx1NUU5NFx1OTAxQVx1OTE0RFx1N0IyNlx1NzY4NFx1NUI1MFx1OTZDNlx1MzAwMgotICAgICAgICByY2FzZS1OU1N1YnNldC4yID0gcmNhc2UtTlNTdWJzZXQuMjogXHU5MDFBXHU5MTREXHU3QjI2XHU3Njg0XHU1M0QxXHU3NTFGXHU4MzAzXHU1NkY0ICh7MH0sezF9KSBcdTRFMERcdTU3MjhcdTU3RkFcdTY3MkNcdTkwMUFcdTkxNERcdTdCMjZcdTRFMkRcdTUzRDFcdTc1MUZcdTgzMDNcdTU2RjQgKHsyfSx7M30pIFx1NzY4NFx1NjcwOVx1NjU0OFx1OTY1MFx1NTIzNlx1NEU0Qlx1NTE4NVx1MzAwMgotICAgICAgICByY2FzZS1OU1N1YnNldC4zID0gcmNhc2UtTlNTdWJzZXQuMzogXHU5MDFBXHU5MTREXHU3QjI2XHU3Njg0XHU2RDQxXHU3QTBCXHU1MTg1XHU1QkI5ICcnezB9JycgXHU1RjMxXHU0RThFXHU1N0ZBXHU2NzJDXHU5MDFBXHU5MTREXHU3QjI2XHU0RTJEXHU3Njg0XHU2RDQxXHU3QTBCXHU1MTg1XHU1QkI5ICcnezF9JydcdTMwMDIKLSAgICAgICAgcmNhc2UtUmVjdXJzZS4xID0gcmNhc2UtUmVjdXJzZS4xOiBcdTdFQzRcdTc2ODRcdTUzRDFcdTc1MUZcdTgzMDNcdTU2RjQgKHswfSx7MX0pIFx1NEUwRFx1NTcyOFx1NTdGQVx1N0VDNFx1NzY4NFx1NTNEMVx1NzUxRlx1ODMwM1x1NTZGNCAoezJ9LHszfSkgXHU3Njg0XHU2NzA5XHU2NTQ4XHU5NjUwXHU1MjM2XHU0RTRCXHU1MTg1XHUzMDAyCi0gICAgICAgIHJjYXNlLVJlY3Vyc2UuMiA9IHJjYXNlLVJlY3Vyc2UuMjogXHU3QzkyXHU1QjUwXHU0RTRCXHU5NUY0XHU2Q0ExXHU2NzA5XHU1QjhDXHU2NTc0XHU3Njg0XHU1MjlGXHU4MEZEXHU2NjIwXHU1QzA0XHUzMDAyCi0gICAgICAgIHJjYXNlLVJlY3Vyc2VMYXguMSA9IHJjYXNlLVJlY3Vyc2VMYXguMTogXHU3RUM0XHU3Njg0XHU1M0QxXHU3NTFGXHU4MzAzXHU1NkY0ICh7MH0sezF9KSBcdTRFMERcdTU3MjhcdTU3RkFcdTdFQzRcdTc2ODRcdTUzRDFcdTc1MUZcdTgzMDNcdTU2RjQgKHsyfSx7M30pIFx1NzY4NFx1NjcwOVx1NjU0OFx1OTY1MFx1NTIzNlx1NEU0Qlx1NTE4NVx1MzAwMgotICAgICAgICByY2FzZS1SZWN1cnNlTGF4LjIgPSByY2FzZS1SZWN1cnNlTGF4LjI6IFx1N0M5Mlx1NUI1MFx1NEU0Qlx1OTVGNFx1NkNBMVx1NjcwOVx1NUI4Q1x1NjU3NFx1NzY4NFx1NTI5Rlx1ODBGRFx1NjYyMFx1NUMwNFx1MzAwMgotICAgICAgICByY2FzZS1SZWN1cnNlVW5vcmRlcmVkLjEgPSByY2FzZS1SZWN1cnNlVW5vcmRlcmVkLjE6IFx1N0VDNFx1NzY4NFx1NTNEMVx1NzUxRlx1ODMwM1x1NTZGNCAoezB9LHsxfSkgXHU0RTBEXHU1NzI4XHU1N0ZBXHU3RUM0XHU3Njg0XHU1M0QxXHU3NTFGXHU4MzAzXHU1NkY0ICh7Mn0sezN9KSBcdTc2ODRcdTY3MDlcdTY1NDhcdTk2NTBcdTUyMzZcdTRFNEJcdTUxODVcdTMwMDIKLSAgICAgICAgcmNhc2UtUmVjdXJzZVVub3JkZXJlZC4yID0gcmNhc2UtUmVjdXJzZVVub3JkZXJlZC4yOiBcdTdDOTJcdTVCNTBcdTRFNEJcdTk1RjRcdTZDQTFcdTY3MDlcdTVCOENcdTY1NzRcdTc2ODRcdTUyOUZcdTgwRkRcdTY2MjBcdTVDMDRcdTMwMDIKLSMgICAgICAgIFdlJ3JlIHVzaW5nIHNjaC1wcm9wcy1jb3JyZWN0LjIgaW5zdGVhZCBvZiB0aGUgb2xkIHNyYy1yZWRlZmluZS4xCi0jICAgICAgICBzcmMtcmVkZWZpbmUuMSA9IHNyYy1yZWRlZmluZS4xOiBUaGUgY29tcG9uZW50ICcnezB9JycgaXMgYmVnaW4gcmVkZWZpbmVkLCBidXQgaXRzIGNvcnJlc3BvbmRpbmcgY29tcG9uZW50IGlzbid0IGluIHRoZSBzY2hlbWEgZG9jdW1lbnQgYmVpbmcgcmVkZWZpbmVkICh3aXRoIG5hbWVzcGFjZSAnJ3syfScnKSwgYnV0IGluIGEgZGlmZmVyZW50IGRvY3VtZW50LCB3aXRoIG5hbWVzcGFjZSAnJ3sxfScnLgotICAgICAgICBzY2gtcHJvcHMtY29ycmVjdC4yID0gc2NoLXByb3BzLWNvcnJlY3QuMjogXHU2NUI5XHU2ODQ4XHU0RTBEXHU4MEZEXHU1MzA1XHU1NDJCXHU1MTc3XHU2NzA5XHU3NkY4XHU1NDBDXHU1NDBEXHU3OUYwXHU3Njg0XHU0RTI0XHU0RTJBXHU1MTY4XHU1QzQwXHU3RUM0XHU0RUY2OyBcdTgwMENcdTZCNjRcdTY1QjlcdTY4NDhcdTRFMkRcdTUzMDVcdTU0MkJcdTRFMjRcdTRFMkEgJyd7MH0nJ1x1MzAwMgotICAgICAgICBzdC1wcm9wcy1jb3JyZWN0LjIgPSBzdC1wcm9wcy1jb3JyZWN0LjI6IFx1NTcyOFx1N0I4MFx1NTM1NVx1N0M3Qlx1NTc4QiAnJ3swfScnIFx1NEUyRFx1NjhDMFx1NkQ0Qlx1NTIzMFx1NUZBQVx1NzNBRlx1NUI5QVx1NEU0OVx1MzAwMlx1OEZEOVx1ODg2OFx1NzkzQSAnJ3swfScnIFx1NTMwNVx1NTQyQlx1NTcyOFx1NTE3Nlx1ODFFQVx1OEVBQlx1NzY4NFx1N0M3Qlx1NTc4Qlx1NTIwNlx1NUM0Mlx1N0VEM1x1Njc4NFx1NEUyRCwgXHU4RkQ5XHU2NjJGXHU5NTE5XHU4QkVGXHU3Njg0XHUzMDAyCi0gICAgICAgIHN0LXByb3BzLWNvcnJlY3QuMyA9IHN0LXByb3BzLWNvcnJlY3QuMzogXHU3QzdCXHU1NzhCICcnezB9JycgXHU5NTE5XHU4QkVGXHUzMDAyJ3snYmFzZSB0eXBlIGRlZmluaXRpb24nfScgXHU3Njg0ICd7J2ZpbmFsJ30nIFx1NzY4NFx1NTAzQyAnJ3sxfScnIFx1Nzk4MVx1NkI2Mlx1NzUzMVx1OTY1MFx1NTIzNlx1NkQzRVx1NzUxRlx1MzAwMgotICAgICAgICB0b3RhbERpZ2l0cy12YWxpZC1yZXN0cmljdGlvbiA9IHRvdGFsRGlnaXRzLXZhbGlkLXJlc3RyaWN0aW9uOiBcdTU3MjggezJ9IFx1NzY4NFx1NUI5QVx1NEU0OVx1NEUyRCwgXHU5NzYyICcndG90YWxEaWdpdHMnJyBcdTc2ODRcdTUwM0MgJyd7MH0nJyBcdTY1RTBcdTY1NDgsIFx1NTZFMFx1NEUzQVx1OEJFNVx1NTAzQ1x1NUZDNVx1OTg3Qlx1NUMwRlx1NEU4RVx1N0I0OVx1NEU4RSAnJ3RvdGFsRGlnaXRzJycgXHU3Njg0XHU1MDNDLCBcdTgwMENcdTU3MjhcdTUzOUZcdTdFQTdcdTdDN0JcdTU3OEJcdTRFNEJcdTRFMDBcdTRFMkRcdTVERjJcdTVDMDZcdTUxNzZcdThCQkVcdTdGNkVcdTRFM0EgJyd7MX0nJ1x1MzAwMgotICAgICAgICB3aGl0ZVNwYWNlLXZhbGlkLXJlc3RyaWN0aW9uLjEgPSB3aGl0ZVNwYWNlLXZhbGlkLXJlc3RyaWN0aW9uLjE6IFx1NTcyOCB7MH0gXHU3Njg0XHU1QjlBXHU0RTQ5XHU0RTJELCBcdTk3NjIgJyd3aGl0ZXNwYWNlJycgXHU3Njg0XHU1MDNDICcnezF9JycgXHU2NUUwXHU2NTQ4LCBcdTU2RTBcdTRFM0EgJyd3aGl0ZXNwYWNlJycgXHU3Njg0XHU1MDNDXHU1REYyXHU1NzI4XHU1MzlGXHU3RUE3XHU3QzdCXHU1NzhCXHU0RTRCXHU0RTAwXHU0RTJEXHU4QkJFXHU3RjZFXHU0RTNBICcnY29sbGFwc2UnJ1x1MzAwMgotICAgICAgICB3aGl0ZVNwYWNlLXZhbGlkLXJlc3RyaWN0aW9uLjIgPSB3aGl0ZVNwYWNlLXZhbGlkLXJlc3RyaWN0aW9uLjI6IFx1NTcyOCB7MH0gXHU3Njg0XHU1QjlBXHU0RTQ5XHU0RTJELCBcdTk3NjIgJyd3aGl0ZXNwYWNlJycgXHU3Njg0XHU1MDNDICcncHJlc2VydmUnJyBcdTY1RTBcdTY1NDgsIFx1NTZFMFx1NEUzQSAnJ3doaXRlc3BhY2UnJyBcdTc2ODRcdTUwM0NcdTVERjJcdTU3MjhcdTUzOUZcdTdFQTdcdTdDN0JcdTU3OEJcdTRFNEJcdTRFMDBcdTRFMkRcdThCQkVcdTdGNkVcdTRFM0EgJydyZXBsYWNlJydcdTMwMDIKLQotI3NjaGVtYSBmb3IgU2NoZW1hcwotCi0gICAgICAgIHM0cy1hdHQtaW52YWxpZC12YWx1ZSA9IHM0cy1hdHQtaW52YWxpZC12YWx1ZTogXHU1MTQzXHU3RDIwICcnezB9JycgXHU0RTJEICcnezF9JycgXHU3Njg0XHU1QzVFXHU2MDI3XHU1MDNDXHU2NUUwXHU2NTQ4XHUzMDAyXHU4QkIwXHU1RjU1XHU3Njg0XHU1MzlGXHU1NkUwOiB7Mn0KLSAgICAgICAgczRzLWF0dC1tdXN0LWFwcGVhciA9IHM0cy1hdHQtbXVzdC1hcHBlYXI6IFx1NTE0M1x1N0QyMCAnJ3swfScnIFx1NEUyRFx1NUZDNVx1OTg3Qlx1NTMwNVx1NTQyQlx1NUM1RVx1NjAyNyAnJ3sxfScnXHUzMDAyCi0gICAgICAgIHM0cy1hdHQtbm90LWFsbG93ZWQgPSBzNHMtYXR0LW5vdC1hbGxvd2VkOiBcdTUxNDNcdTdEMjAgJyd7MH0nJyBcdTRFMkRcdTRFMERcdTgwRkRcdTUzMDVcdTU0MkJcdTVDNUVcdTYwMjcgJyd7MX0nJ1x1MzAwMgotICAgICAgICBzNHMtZWx0LWludmFsaWQgPSBzNHMtZWx0LWludmFsaWQ6IFx1NTE0M1x1N0QyMCAnJ3swfScnIFx1NEUwRFx1NjYyRlx1NjVCOVx1Njg0OFx1NjU4N1x1Njg2M1x1NEUyRFx1NzY4NFx1NjcwOVx1NjU0OFx1NTE0M1x1N0QyMFx1MzAwMgotICAgICAgICBzNHMtZWx0LW11c3QtbWF0Y2guMSA9IHM0cy1lbHQtbXVzdC1tYXRjaC4xOiAnJ3swfScnIFx1NzY4NFx1NTE4NVx1NUJCOVx1NUZDNVx1OTg3Qlx1NEUwRSB7MX0gXHU1MzM5XHU5MTREXHUzMDAyXHU1M0QxXHU3M0IwXHU5NUVFXHU5ODk4LCBcdTVGMDBcdTU5Q0JcdTRFOEU6IHsyfVx1MzAwMgotICAgICAgICBzNHMtZWx0LW11c3QtbWF0Y2guMiA9IHM0cy1lbHQtbXVzdC1tYXRjaC4yOiAnJ3swfScnIFx1NzY4NFx1NTE4NVx1NUJCOVx1NUZDNVx1OTg3Qlx1NEUwRSB7MX0gXHU1MzM5XHU5MTREXHUzMDAyXHU2MjdFXHU0RTBEXHU1MjMwXHU4REIzXHU1OTFGXHU3Njg0XHU1MTQzXHU3RDIwXHUzMDAyCi0gICAgICAgICMgdGhlICJpbnZhbGlkLWNvbnRlbnQiIG1lc3NhZ2VzIHByb3ZpZGUgbGVzcyBpbmZvcm1hdGlvbiB0aGFuIHRoZSAibXVzdC1tYXRjaCIgY291bnRlcnBhcnRzIGFib3ZlLiBUaGV5J3JlIHVzZWQgZm9yIGNvbXBsZXggdHlwZXMgd2hlbiBwcm92aWRpbmcgYSAibWF0Y2giIHdvdWxkIGJlIGFuIGluZm9ybWF0aW9uIGR1bXAKLSAgICAgICAgczRzLWVsdC1pbnZhbGlkLWNvbnRlbnQuMSA9IHM0cy1lbHQtaW52YWxpZC1jb250ZW50LjE6ICcnezB9JycgXHU3Njg0XHU1MTg1XHU1QkI5XHU2NUUwXHU2NTQ4XHUzMDAyXHU1MTQzXHU3RDIwICcnezF9JycgXHU2NUUwXHU2NTQ4LCBcdTYyNDBcdTY1M0VcdTRGNERcdTdGNkVcdTk1MTlcdThCRUZcdTYyMTZcdTUxRkFcdTczQjBcdTZCMjFcdTY1NzBcdThGQzdcdTU5MUFcdTMwMDIKLSAgICAgICAgczRzLWVsdC1pbnZhbGlkLWNvbnRlbnQuMiA9IHM0cy1lbHQtaW52YWxpZC1jb250ZW50LjI6ICcnezB9JycgXHU3Njg0XHU1MTg1XHU1QkI5XHU2NUUwXHU2NTQ4XHUzMDAyXHU1MTQzXHU3RDIwICcnezF9JycgXHU0RTBEXHU4MEZEXHU0RTNBXHU3QTdBXHUzMDAyCi0gICAgICAgIHM0cy1lbHQtaW52YWxpZC1jb250ZW50LjMgPSBzNHMtZWx0LWludmFsaWQtY29udGVudC4zOiBcdTdDN0JcdTU3OEJcdTRFM0EgJyd7MH0nJyBcdTc2ODRcdTUxNDNcdTdEMjBcdTRFMERcdTgwRkRcdTU3MjhcdTU4RjBcdTY2MEVcdTc2ODRcdTU0MEVcdTk3NjJcdTRGNUNcdTRFM0EgPHNjaGVtYT4gXHU1MTQzXHU3RDIwXHU3Njg0XHU1QjUwXHU3RUE3XHU1MUZBXHU3M0IwXHUzMDAyCi0gICAgICAgIHM0cy1lbHQtc2NoZW1hLW5zID0gczRzLWVsdC1zY2hlbWEtbnM6IFx1NTE0M1x1N0QyMCAnJ3swfScnIFx1NzY4NFx1NTQwRFx1NzlGMFx1N0E3QVx1OTVGNFx1NUZDNVx1OTg3Qlx1Njc2NVx1ODFFQVx1NjVCOVx1Njg0OFx1NTQwRFx1NzlGMFx1N0E3QVx1OTVGNCAnJ2h0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hJydcdTMwMDIKLSAgICAgICAgczRzLWVsdC1jaGFyYWN0ZXIgPSBzNHMtZWx0LWNoYXJhY3RlcjogXHU2NUI5XHU2ODQ4XHU1MTQzXHU3RDIwXHU0RTJEXHU0RTBEXHU1MTQxXHU4QkI4XHU1MUZBXHU3M0IwXHU5NjY0ICcneHM6YXBwaW5mbycnIFx1NTQ4QyAnJ3hzOmRvY3VtZW50YXRpb24nJyBcdTRFNEJcdTU5MTZcdTc2ODRcdTk3NUVcdTdBN0FcdTY4M0NcdTVCNTdcdTdCMjZcdTMwMDJcdTUzRDFcdTczQjBcdTRFODYgJyd7MH0nJ1x1MzAwMgotCi0jIGNvZGVzIG5vdCBkZWZpbmVkIGJ5IHRoZSBzcGVjCi0KLSAgICAgICAgYy1maWVsZHMteHBhdGhzID0gYy1maWVsZHMteHBhdGhzOiBcdTVCNTdcdTZCQjVcdTUwM0MgJyd7MH0nJyBcdTY1RTBcdTY1NDhcdTMwMDIKLSAgICAgICAgYy1nZW5lcmFsLXhwYXRoID0gYy1nZW5lcmFsLXhwYXRoOiBcdTg4NjhcdThGQkVcdTVGMEYgJyd7MH0nJyBcdTRFMEUgWE1MIFx1NjVCOVx1Njg0OFx1NjI0MFx1NjUyRlx1NjMwMVx1NzY4NCBYUGF0aCBcdTVCNTBcdTk2QzZcdTRFMERcdTUzMzlcdTkxNERcdTMwMDIKLSAgICAgICAgYy1nZW5lcmFsLXhwYXRoLW5zID0gYy1nZW5lcmFsLXhwYXRoLW5zOiBYUGF0aCBcdTg4NjhcdThGQkVcdTVGMEYgJyd7MH0nJyBcdTRFMkRcdTc2ODRcdTU0MERcdTc5RjBcdTdBN0FcdTk1RjRcdTUyNERcdTdGMDBcdTY3MkFcdTdFRDFcdTVCOUFcdTUyMzBcdTU0MERcdTc5RjBcdTdBN0FcdTk1RjRcdTMwMDIKLSAgICAgICAgYy1zZWxlY3Rvci14cGF0aCA9IGMtc2VsZWN0b3IteHBhdGg6IFx1OTAwOVx1NjJFOVx1NTY2OFx1NTAzQyAnJ3swfScnIFx1NjVFMFx1NjU0ODsgXHU5MDA5XHU2MkU5XHU1NjY4IHhwYXRoIFx1NEUwRFx1ODBGRFx1NTMwNVx1NTQyQlx1NUM1RVx1NjAyN1x1MzAwMgotICAgICAgICBFbXB0eVRhcmdldE5hbWVzcGFjZSA9IEVtcHR5VGFyZ2V0TmFtZXNwYWNlOiBcdTU3MjhcdTY1QjlcdTY4NDhcdTY1ODdcdTY4NjMgJyd7MH0nJyBcdTRFMkQsICcndGFyZ2V0TmFtZXNwYWNlJycgXHU1QzVFXHU2MDI3XHU3Njg0XHU1MDNDXHU0RTBEXHU4MEZEXHU0RTNBXHU3QTdBXHU1QjU3XHU3QjI2XHU0RTMyXHUzMDAyCi0gICAgICAgIEZhY2V0VmFsdWVGcm9tQmFzZSA9IEZhY2V0VmFsdWVGcm9tQmFzZTogXHU1NzI4XHU3QzdCXHU1NzhCICcnezB9JycgXHU3Njg0XHU1OEYwXHU2NjBFXHU0RTJELCBcdTk3NjIgJyd7Mn0nJyBcdTc2ODRcdTUwM0MgJyd7MX0nJyBcdTVGQzVcdTk4N0JcdTY3NjVcdTgxRUFcdTU3RkFcdTdDN0JcdTU3OEJcdTc2ODRcdTUwM0NcdTdBN0FcdTk1RjQgJyd7M30nJ1x1MzAwMgotICAgICAgICBGaXhlZEZhY2V0VmFsdWUgPSBGaXhlZEZhY2V0VmFsdWU6IFx1NTcyOCB7M30gXHU3Njg0XHU1QjlBXHU0RTQ5XHU0RTJELCBcdTk3NjIgJyd7MH0nJyBcdTc2ODRcdTUwM0MgJyd7MX0nJyBcdTY1RTBcdTY1NDgsIFx1NTZFMFx1NEUzQSAnJ3swfScnIFx1NzY4NFx1NTAzQ1x1NURGMlx1NTcyOFx1NTM5Rlx1N0VBN1x1N0M3Qlx1NTc4Qlx1NEU0Qlx1NEUwMFx1NEUyRFx1OEJCRVx1N0Y2RVx1NEUzQSAnJ3syfScnLCBcdTVFNzZcdTRFMTQgJ3snZml4ZWQnfScgPSB0cnVlXHUzMDAyCi0gICAgICAgIEludmFsaWRSZWdleCA9IEludmFsaWRSZWdleDogXHU2QTIxXHU1RjBGXHU1MDNDICcnezB9JycgXHU0RTBEXHU2NjJGXHU2NzA5XHU2NTQ4XHU3Njg0XHU2QjYzXHU1MjE5XHU4ODY4XHU4RkJFXHU1RjBGXHUzMDAyXHU1MjE3ICcnezJ9JycgXHU0RTBBXHU2MkE1XHU1NDRBXHU3Njg0XHU5NTE5XHU4QkVGXHU0RTNBOiAnJ3sxfScnXHUzMDAyCi0gICAgICAgIE1heE9jY3VyTGltaXQgPSBcdTg5RTNcdTY3OTBcdTU2NjhcdTc2ODRcdTVGNTNcdTUyNERcdTkxNERcdTdGNkVcdTRFMERcdTUxNDFcdThCQjhcdTVDMDYgbWF4T2NjdXJzIFx1NUM1RVx1NjAyN1x1NTAzQ1x1OEJCRVx1N0Y2RVx1NEUzQVx1NTkyN1x1NEU4RVx1NTAzQyB7MH1cdTMwMDIKLSAgICAgICAgUHVibGljU3lzdGVtT25Ob3RhdGlvbiA9IFB1YmxpY1N5c3RlbU9uTm90YXRpb246IFx1NTE0M1x1N0QyMCAnJ25vdGF0aW9uJycgXHU0RTJEXHU1RkM1XHU5ODdCXHU4MUYzXHU1QzExXHU1MUZBXHU3M0IwICcncHVibGljJycgXHU1NDhDICcnc3lzdGVtJycgXHU0RTJEXHU3Njg0XHU0RTAwXHU0RTJBXHUzMDAyCi0gICAgICAgIFNjaGVtYUxvY2F0aW9uID0gU2NoZW1hTG9jYXRpb246IHNjaGVtYUxvY2F0aW9uIFx1NTAzQyAnJ3swfScnIFx1NUZDNVx1OTg3Qlx1NTE3N1x1NjcwOVx1NTA3Nlx1NjU3MFx1NEUyQSBVUklcdTMwMDIKLSAgICAgICAgVGFyZ2V0TmFtZXNwYWNlLjEgPSBUYXJnZXROYW1lc3BhY2UuMTogXHU1RTk0XHU0RTNBXHU1NDBEXHU3OUYwXHU3QTdBXHU5NUY0ICcnezB9JycsIFx1NEY0Nlx1NjVCOVx1Njg0OFx1NjU4N1x1Njg2M1x1NzY4NFx1NzZFRVx1NjgwN1x1NTQwRFx1NzlGMFx1N0E3QVx1OTVGNFx1NEUzQSAnJ3sxfScnXHUzMDAyCi0gICAgICAgIFRhcmdldE5hbWVzcGFjZS4yID0gVGFyZ2V0TmFtZXNwYWNlLjI6IFx1NEUwRFx1OTcwMFx1ODk4MVx1NTQwRFx1NzlGMFx1N0E3QVx1OTVGNCwgXHU0RjQ2XHU2QjY0XHU2NUI5XHU2ODQ4XHU2NTg3XHU2ODYzXHU3Njg0XHU3NkVFXHU2ODA3XHU1NDBEXHU3OUYwXHU3QTdBXHU5NUY0XHU0RTNBICcnezF9JydcdTMwMDIKLSAgICAgICAgVW5kZWNsYXJlZEVudGl0eSA9IFVuZGVjbGFyZWRFbnRpdHk6IFx1NjcyQVx1NThGMFx1NjYwRVx1NUI5RVx1NEY1MyAnJ3swfScnXHUzMDAyCi0gICAgICAgIFVuZGVjbGFyZWRQcmVmaXggPSBVbmRlY2xhcmVkUHJlZml4OiBcdTY1RTBcdTZDRDVcdTVDMDYgJyd7MH0nJyBcdTg5RTNcdTY3OTBcdTRFM0FcdTk2NTBcdTVCOUFcdTU0MEQ6IFx1NjcyQVx1NThGMFx1NjYwRVx1NTI0RFx1N0YwMCAnJ3sxfScnXHUzMDAyCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9YTUxTY2hlbWFNZXNzYWdlc196aF9UVy5wcm9wZXJ0aWVzIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MU2NoZW1hTWVzc2FnZXNfemhfVFcucHJvcGVydGllcwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOWYxNzBiMS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9YTUxTY2hlbWFNZXNzYWdlc196aF9UVy5wcm9wZXJ0aWVzCisrKyAvZGV2L251bGwKQEAgLTEsMjkxICswLDAgQEAKLSMgVGhpcyBmaWxlIGNvbnRhaW5zIGVycm9yIGFuZCB3YXJuaW5nIG1lc3NhZ2VzIHJlbGF0ZWQgdG8gWE1MIFNjaGVtYQotIyBUaGUgbWVzc2FnZXMgYXJlIGFycmFuZ2VkIGluIGtleSBhbmQgdmFsdWUgdHVwbGVzIGluIGEgTGlzdFJlc291cmNlQnVuZGxlLgotIwotCi0gICAgICAgIEJhZE1lc3NhZ2VLZXkgPSBcdTYyN0VcdTRFMERcdTUyMzBcdTVDMERcdTYxQzlcdThBMEFcdTYwNkZcdTdEMjJcdTVGMTVcdTkzNzVcdTc2ODRcdTkzMkZcdThBQTRcdThBMEFcdTYwNkZcdTMwMDIKLSAgICAgICAgRm9ybWF0RmFpbGVkID0gXHU2ODNDXHU1RjBGXHU1MzE2XHU0RTBCXHU1MjE3XHU4QTBBXHU2MDZGXHU2NjQyXHU3NjdDXHU3NTFGXHU1MTY3XHU5MEU4XHU5MzJGXHU4QUE0OlxuCi0KLSMgRm9yIGludGVybmFsIHVzZQotCi0gICAgICAgIEludGVybmFsLUVycm9yID0gXHU1MTY3XHU5MEU4XHU5MzJGXHU4QUE0OiB7MH1cdTMwMDIKLSAgICAgICAgZHQtd2hpdGVzcGFjZSA9IFx1ODA2Rlx1OTZDNiBzaW1wbGVUeXBlICcnezB9JycgXHU2QzkyXHU2NzA5XHU1M0VGXHU3NTI4XHU3Njg0XHU3QTdBXHU2ODNDIEZhY2V0IFx1NTAzQwotICAgICAgICBHcmFtbWFyQ29uZmxpY3QgPSBcdTVGOUVcdTRGN0ZcdTc1MjhcdTgwMDVcdTY1ODdcdTZDRDVcdTk2QzZcdTUzNDBcdTRFMkRcdTUwQjNcdTU2REVcdTc2ODRcdTRFMDBcdTUwMEJcdTY1ODdcdTZDRDVcdTgyMDdcdTUxNzZcdTRFRDZcdTY1ODdcdTZDRDVcdTg4NURcdTdBODFcdTMwMDIKLQotIyBJZGVudGl0eSBjb25zdHJhaW50cwotCi0gICAgICAgIEFic2VudEtleVZhbHVlID0gXHU4QjU4XHU1MjI1XHU5NjUwXHU1MjM2XHU2ODlEXHU0RUY2XHU5MzJGXHU4QUE0IChjdmMtaWRlbnRpdHktY29uc3RyYWludC40LjIuMSk6ICBcdTUxNDNcdTdEMjAgInswfSIgXHU1MTc3XHU2NzA5XHU3Njg0XHU5MUQxXHU5NDcwXHU2QzkyXHU2NzA5XHU1MDNDXHUzMDAyCi0gICAgICAgIER1cGxpY2F0ZUZpZWxkID0gXHU3QkM0XHU1NzBEXHU0RTJEXHU3Njg0XHU2QjA0XHU0RjREICJ7MH0iIFx1OTFDRFx1ODkwN1x1OTE0RFx1NUMwRFx1MzAwMgotICAgICAgICBEdXBsaWNhdGVLZXkgPSBcdTcwQkFcdTUxNDNcdTdEMjAgInsxfSIgXHU3Njg0XHU4QjU4XHU1MjI1XHU5NjUwXHU1MjM2XHU2ODlEXHU0RUY2XHU1QkEzXHU1NDRBXHU0RTg2XHU5MUNEXHU4OTA3XHU3Njg0XHU5MUQxXHU5NDcwXHU1MDNDIFt7MH1dXHUzMDAyCi0gICAgICAgIER1cGxpY2F0ZVVuaXF1ZSA9IFx1NzBCQVx1NTE0M1x1N0QyMCAiezF9IiBcdTc2ODRcdThCNThcdTUyMjVcdTk2NTBcdTUyMzZcdTY4OURcdTRFRjZcdTVCQTNcdTU0NEFcdTRFODZcdTkxQ0RcdTg5MDdcdTc2ODRcdTU1MkZcdTRFMDBcdTUwM0MgW3swfV1cdTMwMDIKLSAgICAgICAgRmllbGRNdWx0aXBsZU1hdGNoID0gXHU4QjU4XHU1MjI1XHU5NjUwXHU1MjM2XHU2ODlEXHU0RUY2XHU5MzJGXHU4QUE0OiBcdTZCMDRcdTRGNEQgInswfSIgXHU3QjI2XHU1NDA4XHU1MTc2XHU5MDc4XHU1M0Q2XHU1NjY4XHU3QkM0XHU1NzBEXHU1MTY3XHU4RDg1XHU5MDRFXHU0RTAwXHU1MDBCXHU0RUU1XHU0RTBBXHU3Njg0XHU1MDNDOyBcdTZCMDRcdTRGNERcdTVGQzVcdTk4MDhcdTdCMjZcdTU0MDhcdTU1MkZcdTRFMDBcdTUwM0NcdTMwMDIKLSAgICAgICAgRml4ZWREaWZmZXJzRnJvbUFjdHVhbCA9IFx1NkI2NFx1NTE0M1x1N0QyMFx1NzY4NFx1NTE2N1x1NUJCOVx1NEUwRFx1N0I0OVx1NjVCQ1x1N0RCMVx1ODk4MVx1NTE0M1x1N0QyMFx1NUJBM1x1NTQ0QVx1NEUyRCAiZml4ZWQiIFx1NUM2Q1x1NjAyN1x1NzY4NFx1NTAzQ1x1MzAwMgotICAgICAgICBLZXlNYXRjaGVzTmlsbGFibGUgPSBcdThCNThcdTUyMjVcdTk2NTBcdTUyMzZcdTY4OURcdTRFRjZcdTkzMkZcdThBQTQgKGN2Yy1pZGVudGl0eS1jb25zdHJhaW50LjQuMi4zKTogIFx1NTE0M1x1N0QyMCAiezB9IiBcdTUxNzdcdTY3MDlcdTc2ODRcdTkxRDFcdTk0NzBcdUZGMENcdTdCMjZcdTU0MDggbmlsbGFibGUgXHU4QTJEXHU3MEJBXHU3NzFGXHU3Njg0XHU1MTQzXHU3RDIwXHUzMDAyCi0gICAgICAgIEtleU5vdEVub3VnaFZhbHVlcyA9IFx1NkM5Mlx1NjcwOVx1OERCM1x1NTkyMFx1NzY4NFx1NTAzQ1x1NjMwN1x1NUI5QVx1NTE0M1x1N0QyMCAiezB9IiBcdTYzMDdcdTVCOUFcdTc2ODQgPGtleSBuYW1lPSJ7MX0iPiBcdThCNThcdTUyMjVcdTk2NTBcdTUyMzZcdTY4OURcdTRFRjZcdTMwMDIKLSAgICAgICAgS2V5Tm90Rm91bmQgPSBcdTUxNDNcdTdEMjAgJyd7Mn0nJyBcdTc2ODRcdThCNThcdTUyMjVcdTk2NTBcdTUyMzZcdTY4OURcdTRFRjZcdTYyN0VcdTRFMERcdTUyMzBcdTUwM0MgJyd7MX0nJyBcdTc2ODRcdTkxRDFcdTk0NzAgJyd7MH0nJ1x1MzAwMgotICAgICAgICBLZXlSZWZOb3RFbm91Z2hWYWx1ZXMgPSBcdTZDOTJcdTY3MDlcdThEQjNcdTU5MjBcdTc2ODRcdTUwM0NcdTYzMDdcdTVCOUFcdTUxNDNcdTdEMjAgInswfSIgXHU2MzA3XHU1QjlBXHU3Njg0IDxrZXlyZWYgbmFtZT0iezF9Ij4gXHU4QjU4XHU1MjI1XHU5NjUwXHU1MjM2XHU2ODlEXHU0RUY2XHUzMDAyCi0gICAgICAgIEtleVJlZk91dE9mU2NvcGUgPSBcdThCNThcdTUyMjVcdTk2NTBcdTUyMzZcdTY4OURcdTRFRjZcdTkzMkZcdThBQTQ6IFx1OEI1OFx1NTIyNVx1OTY1MFx1NTIzNlx1Njg5RFx1NEVGNiAiezB9IiBcdTUxNzdcdTY3MDlcdTRFMDBcdTUwMEIga2V5cmVmXHVGRjBDXHU1QjgzXHU1M0MzXHU3MTY3XHU0RTg2XHU3QkM0XHU1NzBEXHU0RTRCXHU1OTE2XHU3Njg0XHU5MUQxXHU5NDcwXHU2MjE2XHU1NTJGXHU0RTAwXHU1MDNDXHUzMDAyCi0gICAgICAgIEtleVJlZlJlZmVyTm90Rm91bmQgPSBcdTkxRDFcdTk0NzBcdTUzQzNcdTcxNjdcdTVCQTNcdTU0NEEgInswfSIgXHU1M0MzXHU3MTY3XHU0RTg2XHU1NDBEXHU3QTMxXHU3MEJBICJ7MX0iIFx1NzY4NFx1NEUwRFx1NjYwRVx1OTFEMVx1OTQ3MFx1MzAwMgotICAgICAgICBVbmlxdWVOb3RFbm91Z2hWYWx1ZXMgPSBcdTZDOTJcdTY3MDlcdThEQjNcdTU5MjBcdTc2ODRcdTUwM0NcdTYzMDdcdTVCOUFcdTUxNDNcdTdEMjAgInswfSIgXHU2MzA3XHU1QjlBXHU3Njg0IDx1bmlxdWU+IFx1OEI1OFx1NTIyNVx1OTY1MFx1NTIzNlx1Njg5RFx1NEVGNlx1MzAwMgotICAgICAgICBVbmtub3duRmllbGQgPSBcdTUxNjdcdTkwRThcdThCNThcdTUyMjVcdTk2NTBcdTUyMzZcdTY4OURcdTRFRjZcdTkzMkZcdThBQTQ7IFx1NEUwRFx1NjYwRVx1NzY4NFx1NkIwNFx1NEY0RCAiezB9Ilx1MzAwMgotCi0jIElkZWFsbHksIHdlIHNob3VsZCBvbmx5IHVzZSB0aGUgZm9sbG93aW5nIGVycm9yIGtleXMsIG5vdCB0aGUgb25lcyB1bmRlcgotIyAiSWRlbnRpdHkgY29uc3RyYWludHMiLiBBbmQgd2Ugc2hvdWxkIGNvdmVyIGFsbCBvZiB0aGUgZm9sbG93aW5nIGVycm9ycy4KLQotI3ZhbGlkYXRpb24gKDMuWC40KQotCi0gICAgICAgIGN2Yy1hdHRyaWJ1dGUuMyA9IGN2Yy1hdHRyaWJ1dGUuMzogXHU1MTQzXHU3RDIwICcnezB9JycgXHU0RTBBXHU1QzZDXHU2MDI3ICcnezF9JycgXHU3Njg0XHU1MDNDICcnezJ9JycgXHU1QzBEXHU2NUJDXHU1MTc2XHU5ODVFXHU1NzhCICcnezN9JycgXHU3MTIxXHU2NTQ4XHUzMDAyCi0gICAgICAgIGN2Yy1hdHRyaWJ1dGUuNCA9IGN2Yy1hdHRyaWJ1dGUuNDogXHU1MTQzXHU3RDIwICcnezB9JycgXHU0RTBBXHU1QzZDXHU2MDI3ICcnezF9JycgXHU3Njg0XHU1MDNDICcnezJ9JycgXHU1QzBEXHU2NUJDXHU1MTc2XHU1NkZBXHU1QjlBICd7J3ZhbHVlIGNvbnN0cmFpbnQnfScgXHU3MTIxXHU2NTQ4XHUzMDAyXHU1QzZDXHU2MDI3XHU1RkM1XHU5ODA4XHU1MTc3XHU2NzA5ICcnezN9JycgXHU3Njg0XHU1MDNDXHUzMDAyCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuMi4xID0gY3ZjLWNvbXBsZXgtdHlwZS4yLjE6IFx1NTE0M1x1N0QyMCAnJ3swfScnIFx1NEUwRFx1ODBGRFx1NjcwOVx1NUI1N1x1NTE0M1x1NjIxNlx1NTE0M1x1N0QyMFx1OENDN1x1OEEwQVx1OTgwNVx1NzZFRSBbY2hpbGRyZW5dXHVGRjBDXHU1NkUwXHU3MEJBXHU5ODVFXHU1NzhCXHU3Njg0XHU1MTY3XHU1QkI5XHU5ODVFXHU1NzhCXHU3MEJBXHU3QTdBXHU3NjdEXHUzMDAyCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuMi4yID0gY3ZjLWNvbXBsZXgtdHlwZS4yLjI6IFx1NTE0M1x1N0QyMCAnJ3swfScnIFx1NEUwRFx1ODBGRFx1NjcwOVx1NTE0M1x1N0QyMCBbY2hpbGRyZW5dXHVGRjBDXHU0RTE0XHU1MDNDXHU1RkM1XHU5ODA4XHU2NzA5XHU2NTQ4XHUzMDAyCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuMi4zID0gY3ZjLWNvbXBsZXgtdHlwZS4yLjM6IFx1NTE0M1x1N0QyMCAnJ3swfScnIFx1NEUwRFx1ODBGRFx1NjcwOVx1NUI1N1x1NTE0MyBbY2hpbGRyZW5dXHVGRjBDXHU1NkUwXHU3MEJBXHU5ODVFXHU1NzhCXHU3Njg0XHU1MTY3XHU1QkI5XHU5ODVFXHU1NzhCXHU3MEJBIGVsZW1lbnQtb25seVx1MzAwMgotICAgICAgICBjdmMtY29tcGxleC10eXBlLjIuNC5hID0gY3ZjLWNvbXBsZXgtdHlwZS4yLjQuYTogXHU1RjlFXHU1MTQzXHU3RDIwICcnezB9JycgXHU5NThCXHU1OUNCXHU2MjdFXHU1MjMwXHU3MTIxXHU2NTQ4XHU3Njg0XHU1MTY3XHU1QkI5XHUzMDAyXHU5ODEwXHU2NzFGXHU0RTAwXHU1MDBCICcnezF9JydcdTMwMDIKLSAgICAgICAgY3ZjLWNvbXBsZXgtdHlwZS4yLjQuYiA9IGN2Yy1jb21wbGV4LXR5cGUuMi40LmI6IFx1NTE0M1x1N0QyMCAnJ3swfScnIFx1NzY4NFx1NTE2N1x1NUJCOVx1NEUwRFx1NUI4Q1x1NjU3NFx1MzAwMlx1OTgxMFx1NjcxRlx1NEUwMFx1NTAwQiAnJ3sxfScnXHUzMDAyCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuMi40LmMgPSBjdmMtY29tcGxleC10eXBlLjIuNC5jOiBcdTU2QjRcdTY4M0NcdTZCRDRcdTVDMERcdTg0MkNcdTc1MjhcdTVCNTdcdTUxNDNcdUZGMENcdTRGNDZcdTY2MkZcdTYyN0VcdTRFMERcdTUyMzBcdTUxNDNcdTdEMjAgJyd7MH0nJyBcdTc2ODRcdTVCQTNcdTU0NEFcdTMwMDIKLSAgICAgICAgY3ZjLWNvbXBsZXgtdHlwZS4yLjQuZCA9IGN2Yy1jb21wbGV4LXR5cGUuMi40LmQ6IFx1NUY5RVx1NTE0M1x1N0QyMCAnJ3swfScnIFx1OTU4Qlx1NTlDQlx1NjI3RVx1NTIzMFx1NzEyMVx1NjU0OFx1NzY4NFx1NTE2N1x1NUJCOVx1MzAwMlx1NkI2NFx1ODY1NVx1NjcyQVx1OTgxMFx1NjcxRlx1NUI1MFx1OTgwNVx1NTE0M1x1N0QyMFx1MzAwMgotICAgICAgICBjdmMtY29tcGxleC10eXBlLjIuNC5lID0gY3ZjLWNvbXBsZXgtdHlwZS4yLjQuZDogXHU1RjlFXHU1MTQzXHU3RDIwICcnezB9JycgXHU5NThCXHU1OUNCXHU2MjdFXHU1MjMwXHU3MTIxXHU2NTQ4XHU3Njg0XHU1MTY3XHU1QkI5XHUzMDAyXHU2QjY0XHU4NjU1XHU2NzJBXHU5ODEwXHU2NzFGXHU1QjUwXHU5ODA1XHU1MTQzXHU3RDIwICcnezF9JydcdTMwMDIKLSAgICAgICAgY3ZjLWNvbXBsZXgtdHlwZS4zLjEgPSBjdmMtY29tcGxleC10eXBlLjMuMTogXHU1MTQzXHU3RDIwICcnezB9JycgXHU1QzZDXHU2MDI3ICcnezF9JycgXHU3Njg0XHU1MDNDICcnezJ9JycgXHU1QzBEXHU2NUJDXHU1QzZDXHU2MDI3XHU0RjdGXHU3NTI4XHU3MTIxXHU2NTQ4XHUzMDAyXHU1QzZDXHU2MDI3ICcnezF9JycgXHU1MTc3XHU2NzA5ICcnezN9JycgXHU3Njg0XHU1NkZBXHU1QjlBXHU1MDNDXHUzMDAyCi0gICAgICAgIGN2Yy1jb21wbGV4LXR5cGUuMy4yLjEgPSBjdmMtY29tcGxleC10eXBlLjMuMi4xOiBcdTUxNDNcdTdEMjAgJyd7MH0nJyBcdTZDOTJcdTY3MDlcdTVDNkNcdTYwMjcgJyd7MX0nJyBcdTc2ODRcdTVDNkNcdTYwMjdcdTg0MkNcdTc1MjhcdTVCNTdcdTUxNDNcdTMwMDIKLSAgICAgICAgY3ZjLWNvbXBsZXgtdHlwZS4zLjIuMiA9IGN2Yy1jb21wbGV4LXR5cGUuMy4yLjI6IFx1NEUwRFx1NTE0MVx1OEEzMVx1NUM2Q1x1NjAyNyAnJ3sxfScnIFx1NTFGQVx1NzNGRVx1NTcyOFx1NTE0M1x1N0QyMCAnJ3swfScnIFx1NEUyRFx1MzAwMgotICAgICAgICBjdmMtY29tcGxleC10eXBlLjQgPSBjdmMtY29tcGxleC10eXBlLjQ6IFx1NUM2Q1x1NjAyNyAnJ3sxfScnIFx1NUZDNVx1OTgwOFx1NTFGQVx1NzNGRVx1NTcyOFx1NTE0M1x1N0QyMCAnJ3swfScnIFx1NEUyRFx1MzAwMgotICAgICAgICBjdmMtY29tcGxleC10eXBlLjUuMSA9IGN2Yy1jb21wbGV4LXR5cGUuNS4xOiBcdTU3MjhcdTUxNDNcdTdEMjAgJyd7MH0nJyBcdTRFMkRcdUZGMENcdTVDNkNcdTYwMjcgJyd7MX0nJyBcdTcwQkEgV2lsZCBJRFx1MzAwMlx1NEY0Nlx1NjYyRlx1NURGMlx1N0Q5M1x1NjcwOVx1NEUwMFx1NTAwQiBXaWxkIElEICcnezJ9JydcdTMwMDJcdTUzRUFcdTgwRkRcdTY3MDlcdTRFMDBcdTUwMEIgV2lsZCBJRFx1MzAwMgotICAgICAgICBjdmMtY29tcGxleC10eXBlLjUuMiA9IGN2Yy1jb21wbGV4LXR5cGUuNS4yOiBcdTU3MjhcdTUxNDNcdTdEMjAgJyd7MH0nJyBcdTRFMkRcdUZGMENcdTVDNkNcdTYwMjcgJyd7MX0nJyBcdTcwQkEgV2lsZCBJRFx1MzAwMlx1NEY0Nlx1NjYyRlx1NURGMlx1N0Q5M1x1NjcwOVx1NEUwMFx1NTAwQlx1NUY5RSAneydhdHRyaWJ1dGUgdXNlcyd9JyBcdTRFMkRcdTc2ODQgSUQgXHU4ODREXHU3NTFGXHU4MDBDXHU0Rjg2XHU3Njg0XHU1QzZDXHU2MDI3ICcnezJ9JydcdTMwMDIKLSAgICAgICAgY3ZjLWRhdGF0eXBlLXZhbGlkLjEuMi4xID0gY3ZjLWRhdGF0eXBlLXZhbGlkLjEuMi4xOiAnJ3swfScnIFx1NEUwRFx1NjYyRiAnJ3sxfScnIFx1NzY4NFx1NjcwOVx1NjU0OFx1NTAzQ1x1MzAwMgotICAgICAgICBjdmMtZGF0YXR5cGUtdmFsaWQuMS4yLjIgPSBjdmMtZGF0YXR5cGUtdmFsaWQuMS4yLjI6ICcnezB9JycgXHU0RTBEXHU2NjJGXHU2RTA1XHU1NUFFXHU5ODVFXHU1NzhCICcnezF9JycgXHU3Njg0XHU2NzA5XHU2NTQ4XHU1MDNDXHUzMDAyCi0gICAgICAgIGN2Yy1kYXRhdHlwZS12YWxpZC4xLjIuMyA9IGN2Yy1kYXRhdHlwZS12YWxpZC4xLjIuMzogJyd7MH0nJyBcdTRFMERcdTY2MkZcdTgwNkZcdTk2QzZcdTk4NUVcdTU3OEIgJyd7MX0nJyBcdTc2ODRcdTY3MDlcdTY1NDhcdTUwM0NcdTMwMDIKLSAgICAgICAgY3ZjLWVsdC4xID0gY3ZjLWVsdC4xOiBcdTYyN0VcdTRFMERcdTUyMzBcdTUxNDNcdTdEMjAgJyd7MH0nJyBcdTc2ODRcdTVCQTNcdTU0NEFcdTMwMDIKLSAgICAgICAgY3ZjLWVsdC4yID0gY3ZjLWVsdC4yOiAnJ3swfScnIFx1NTE0M1x1N0QyMFx1NUJBM1x1NTQ0QVx1NEUyRCAneydhYnN0cmFjdCd9JyBcdTc2ODRcdTUwM0NcdTVGQzVcdTk4MDhcdTcwQkFcdTUwN0RcdTMwMDIKLSAgICAgICAgY3ZjLWVsdC4zLjEgPSBjdmMtZWx0LjMuMTogXHU1QzZDXHU2MDI3ICcnezF9JycgXHU0RTBEXHU1M0VGXHU1MUZBXHU3M0ZFXHU1NzI4XHU1MTQzXHU3RDIwICcnezB9JycgXHU0RTJEXHVGRjBDXHU1NkUwXHU3MEJBICcnezB9JycgXHU3Njg0ICd7J25pbGxhYmxlJ30nIFx1NUM2Q1x1NjAyN1x1NzBCQVx1NTA3RFx1MzAwMgotICAgICAgICBjdmMtZWx0LjMuMi4xID0gY3ZjLWVsdC4zLjIuMTogXHU1MTQzXHU3RDIwICcnezB9JycgXHU0RTBEXHU1M0VGXHU2NzA5XHU1QjU3XHU1MTQzXHU2MjE2XHU1MTQzXHU3RDIwXHU4Q0M3XHU4QTBBIFtjaGlsZHJlbl1cdUZGMENcdTU2RTBcdTcwQkFcdTYzMDdcdTVCOUFcdTRFODYgJyd7MX0nJ1x1MzAwMgotICAgICAgICBjdmMtZWx0LjMuMi4yID0gY3ZjLWVsdC4zLjIuMjogXHU1MTQzXHU3RDIwICcnezB9JycgXHU0RTBEXHU1M0VGXHU2NzA5XHU1NkZBXHU1QjlBXHU3Njg0ICd7J3ZhbHVlIGNvbnN0cmFpbnQnfSdcdUZGMENcdTU2RTBcdTcwQkFcdTYzMDdcdTVCOUFcdTRFODYgJyd7MX0nJ1x1MzAwMgotICAgICAgICBjdmMtZWx0LjQuMSA9IGN2Yy1lbHQuNC4xOiBcdTUxNDNcdTdEMjAgJyd7MH0nJyBcdTVDNkNcdTYwMjcgJyd7MX0nJyBcdTc2ODRcdTUwM0MgJyd7Mn0nJyBcdTRFMERcdTY2MkZcdTY3MDlcdTY1NDhcdTc2ODQgUU5hbWVcdTMwMDIKLSAgICAgICAgY3ZjLWVsdC40LjIgPSBjdmMtZWx0LjQuMjogXHU3MTIxXHU2Q0Q1XHU1QzA3ICcnezF9JycgXHU4OUUzXHU2NzkwXHU3MEJBXHU1MTQzXHU3RDIwICcnezB9JycgXHU3Njg0XHU5ODVFXHU1NzhCXHU1QjlBXHU3RkE5XHUzMDAyCi0gICAgICAgIGN2Yy1lbHQuNC4zID0gY3ZjLWVsdC40LjM6IFx1OTg1RVx1NTc4QiAnJ3sxfScnIFx1NEUwRFx1NjYyRlx1NjcwOVx1NjU0OFx1ODg0RFx1NzUxRlx1ODFFQVx1NTE0M1x1N0QyMCAnJ3swfScnIFx1NzY4NFx1OTg1RVx1NTc4Qlx1NUI5QVx1N0ZBOSAnJ3syfScnXHUzMDAyCi0gICAgICAgIGN2Yy1lbHQuNS4xLjEgPSBjdmMtZWx0LjUuMS4xOiBcdTUxNDNcdTdEMjAgJyd7MH0nJyBcdTc2ODQgJ3sndmFsdWUgY29uc3RyYWludCd9JyAnJ3syfScnIFx1NEUwRFx1NjYyRlx1OTg1RVx1NTc4QiAnJ3sxfScnIFx1NzY4NFx1NjcwOVx1NjU0OFx1OTgxMFx1OEEyRFx1NTAzQ1x1MzAwMgotICAgICAgICBjdmMtZWx0LjUuMi4yLjEgPSBjdmMtZWx0LjUuMi4yLjE6IFx1NTE0M1x1N0QyMCAnJ3swfScnIFx1NEUwRFx1NTNFRlx1NjcwOVx1NTE0M1x1N0QyMFx1OENDN1x1OEEwQVx1OTgwNVx1NzZFRSBbY2hpbGRyZW5dXHUzMDAyCi0gICAgICAgIGN2Yy1lbHQuNS4yLjIuMi4xID0gY3ZjLWVsdC41LjIuMi4yLjE6IFx1NTE0M1x1N0QyMCAnJ3swfScnIFx1NzY4NFx1NTAzQyAnJ3sxfScnIFx1NEUwRFx1N0IyNlx1NTQwOFx1NTZGQVx1NUI5QSAneyd2YWx1ZSBjb25zdHJhaW50J30nIFx1NTAzQyAnJ3syfScnXHUzMDAyCi0gICAgICAgIGN2Yy1lbHQuNS4yLjIuMi4yID0gY3ZjLWVsdC41LjIuMi4yLjI6IFx1NTE0M1x1N0QyMCAnJ3swfScnIFx1NzY4NFx1NTAzQyAnJ3sxfScnIFx1NEUwRFx1N0IyNlx1NTQwOCAneyd2YWx1ZSBjb25zdHJhaW50J30nIFx1NTAzQyAnJ3syfScnXHUzMDAyCi0gICAgICAgIGN2Yy1lbnVtZXJhdGlvbi12YWxpZCA9IGN2Yy1lbnVtZXJhdGlvbi12YWxpZDogXHU1MDNDICcnezB9JycgXHU1QzBEXHU2NUJDXHU1MjE3XHU4MjA5ICcnezF9JycgXHU4MDBDXHU4QTAwXHU0RTI2XHU5NzVFIGZhY2V0LXZhbGlkXHUzMDAyXHU1QjgzXHU1RkM1XHU5ODA4XHU2NjJGXHU0Rjg2XHU4MUVBXHU1MjE3XHU4MjA5XHU3Njg0XHU1MDNDXHUzMDAyCi0gICAgICAgIGN2Yy1mcmFjdGlvbkRpZ2l0cy12YWxpZCA9IGN2Yy1mcmFjdGlvbkRpZ2l0cy12YWxpZDogXHU1MDNDICcnezB9JycgXHU1MTc3XHU2NzA5IHsxfSBcdTUyMDZcdTY1NzhcdTRGNERcdTY1NzhcdUZGMENcdTRGNDZcdTY2MkZcdTUyMDZcdTY1NzhcdTRGNERcdTY1NzhcdTc2ODRcdTY1NzhcdTc2RUVcdTk2NTBcdTUyMzZcdTcwQkEgezJ9XHUzMDAyCi0gICAgICAgIGN2Yy1pZC4xID0gY3ZjLWlkLjE6IElEUkVGICcnezB9JycgXHU2QzkyXHU2NzA5IElEL0lEUkVGIFx1OTAyM1x1N0Q1MFx1MzAwMgotICAgICAgICBjdmMtaWQuMiA9IGN2Yy1pZC4yOiBcdTY3MDlcdTU5MUFcdTUwMEIgSUQgXHU1MDNDICcnezB9JydcdTMwMDIKLSAgICAgICAgY3ZjLWlkLjMgPSBjdmMtaWQuMzogXHU4QjU4XHU1MjI1XHU5NjUwXHU1MjM2XHU2ODlEXHU0RUY2ICcnezB9JycgXHU3Njg0XHU2QjA0XHU0RjREXHU3QjI2XHU1NDA4XHU1MTQzXHU3RDIwICcnezF9JydcdUZGMENcdTRGNDZcdTY2MkZcdTZCNjRcdTUxNDNcdTdEMjBcdTZDOTJcdTY3MDlcdTdDMjFcdTU1QUVcdTk4NUVcdTU3OEJcdTMwMDIKLSAgICAgICAgY3ZjLWxlbmd0aC12YWxpZCA9IGN2Yy1sZW5ndGgtdmFsaWQ6IFx1OTU3N1x1NUVBNiA9ICcnezF9JycgXHU3Njg0XHU1MDNDICcnezB9JycgXHU1QzBEXHU2NUJDXHU5ODVFXHU1NzhCICcnezN9JycgXHU5NTc3XHU1RUE2ICcnezJ9JycgXHU4MDBDXHU4QTAwXHU0RTI2XHU5NzVFIGZhY2V0LXZhbGlkXHUzMDAyCi0gICAgICAgIGN2Yy1tYXhFeGNsdXNpdmUtdmFsaWQgPSBjdmMtbWF4RXhjbHVzaXZlLXZhbGlkOiBcdTUwM0MgJyd7MH0nJyBcdTVDMERcdTY1QkNcdTk4NUVcdTU3OEIgJyd7Mn0nJyBtYXhFeGNsdXNpdmUgJyd7MX0nJyBcdTgwMENcdThBMDBcdTRFMjZcdTk3NUUgZmFjZXQtdmFsaWRcdTMwMDIKLSAgICAgICAgY3ZjLW1heEluY2x1c2l2ZS12YWxpZCA9IGN2Yy1tYXhJbmNsdXNpdmUtdmFsaWQ6IFx1NTAzQyAnJ3swfScnIFx1NUMwRFx1NjVCQ1x1OTg1RVx1NTc4QiAnJ3syfScnIG1heEluY2x1c2l2ZSAnJ3sxfScnIFx1ODAwQ1x1OEEwMFx1NEUyNlx1OTc1RSBmYWNldC12YWxpZFx1MzAwMgotICAgICAgICBjdmMtbWF4TGVuZ3RoLXZhbGlkID0gY3ZjLW1heExlbmd0aC12YWxpZDogXHU5NTc3XHU1RUE2ID0gJyd7MX0nJyBcdTc2ODRcdTUwM0MgJyd7MH0nJyBcdTVDMERcdTY1QkNcdTk4NUVcdTU3OEIgJyd7M30nJyBtYXhMZW5ndGggJyd7Mn0nJyBcdTgwMENcdThBMDBcdTRFMjZcdTk3NUUgZmFjZXQtdmFsaWRcdTMwMDIKLSAgICAgICAgY3ZjLW1pbkV4Y2x1c2l2ZS12YWxpZCA9IGN2Yy1taW5FeGNsdXNpdmUtdmFsaWQ6IFx1NTAzQyAnJ3swfScnIFx1NUMwRFx1NjVCQ1x1OTg1RVx1NTc4QiAnJ3syfScnIG1pbkV4Y2x1c2l2ZSAnJ3sxfScnIFx1ODAwQ1x1OEEwMFx1NEUyNlx1OTc1RSBmYWNldC12YWxpZFx1MzAwMgotICAgICAgICBjdmMtbWluSW5jbHVzaXZlLXZhbGlkID0gY3ZjLW1pbkluY2x1c2l2ZS12YWxpZDogXHU1MDNDICcnezB9JycgXHU1QzBEXHU2NUJDXHU5ODVFXHU1NzhCICcnezJ9JycgbWluSW5jbHVzaXZlICcnezF9JycgXHU4MDBDXHU4QTAwXHU0RTI2XHU5NzVFIGZhY2V0LXZhbGlkXHUzMDAyCi0gICAgICAgIGN2Yy1taW5MZW5ndGgtdmFsaWQgPSBjdmMtbWluTGVuZ3RoLXZhbGlkOiBcdTk1NzdcdTVFQTYgPSAnJ3sxfScnIFx1NzY4NFx1NTAzQyAnJ3swfScnIFx1NUMwRFx1NjVCQ1x1OTg1RVx1NTc4QiAnJ3szfScnIG1pbkxlbmd0aCAnJ3syfScnIFx1ODAwQ1x1OEEwMFx1NEUyNlx1OTc1RSBmYWNldC12YWxpZFx1MzAwMgotICAgICAgICBjdmMtcGF0dGVybi12YWxpZCA9IGN2Yy1wYXR0ZXJuLXZhbGlkOiBcdTUwM0MgJyd7MH0nJyBcdTVDMERcdTY1QkNcdTk4NUVcdTU3OEIgJyd7Mn0nJyBcdTZBMjNcdTVGMEYgJyd7MX0nJyBcdTgwMENcdThBMDBcdTRFMjZcdTk3NUUgZmFjZXQtdmFsaWRcdTMwMDIKLSAgICAgICAgY3ZjLXRvdGFsRGlnaXRzLXZhbGlkID0gY3ZjLXRvdGFsRGlnaXRzLXZhbGlkOiBcdTUwM0MgJyd7MH0nJyBcdTUxNzdcdTY3MDkgezF9IFx1N0UzRFx1NEY0RFx1NjU3OFx1RkYwQ1x1NEY0Nlx1NjYyRlx1N0UzRFx1NEY0RFx1NjU3OFx1NzY4NFx1NjU3OFx1NzZFRVx1OTY1MFx1NTIzNlx1NzBCQSB7Mn1cdTMwMDIKLSAgICAgICAgY3ZjLXR5cGUuMiA9IGN2Yy10eXBlLjI6IFx1NTE0M1x1N0QyMCB7MH0gXHU3Njg0XHU5ODVFXHU1NzhCXHU1QjlBXHU3RkE5XHU0RTBEXHU1M0VGXHU3MEJBXHU2MkJEXHU4QzYxXHUzMDAyCi0gICAgICAgIGN2Yy10eXBlLjMuMS4xID0gY3ZjLXR5cGUuMy4xLjE6IFx1NTE0M1x1N0QyMCAnJ3swfScnIFx1NzBCQVx1N0MyMVx1NTVBRVx1OTg1RVx1NTc4Qlx1RkYwQ1x1NTZFMFx1NkI2NFx1NEUwRFx1ODBGRFx1NjcwOVx1NUM2Q1x1NjAyN1x1RkYwQ1x1NEY0Nlx1NEUwRFx1NTMwNVx1NjJFQ1x1NTQ3RFx1NTQwRFx1N0E3QVx1OTU5M1x1NTQwRFx1N0EzMVx1N0I0OVx1NjVCQyAnJ2h0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlJycgXHU4MjA3IFtsb2NhbCBuYW1lXSBcdTcwQkEgJyd0eXBlJydcdTMwMDEnJ25pbCcnXHUzMDAxJydzY2hlbWFMb2NhdGlvbicnIFx1NjIxNiAnJ25vTmFtZXNwYWNlU2NoZW1hTG9jYXRpb24nJyBcdTUxNzZcdTRFMkRcdTRFNEJcdTRFMDBcdTgwMDVcdTMwMDJcdTRFMERcdTkwNEVcdUZGMENcdTYyN0VcdTUyMzBcdTVDNkNcdTYwMjcgJyd7MX0nJ1x1MzAwMgotICAgICAgICBjdmMtdHlwZS4zLjEuMiA9IGN2Yy10eXBlLjMuMS4yOiBcdTUxNDNcdTdEMjAgJyd7MH0nJyBcdTcwQkFcdTdDMjFcdTU1QUVcdTk4NUVcdTU3OEJcdUZGMENcdTU2RTBcdTZCNjRcdTRFMERcdTUzRUZcdTY3MDlcdTUxNDNcdTdEMjBcdThDQzdcdThBMEFcdTk4MDVcdTc2RUUgW2NoaWxkcmVuXVx1MzAwMgotICAgICAgICBjdmMtdHlwZS4zLjEuMyA9IGN2Yy10eXBlLjMuMS4zOiBcdTUxNDNcdTdEMjAgJyd7MH0nJyBcdTc2ODRcdTUwM0MgJyd7MX0nJyBcdTcxMjFcdTY1NDhcdTMwMDIKLQotI3NjaGVtYSB2YWxpZCAoMy5YLjMpCi0KLSAgICAgICAgc2NoZW1hX3JlZmVyZW5jZS5hY2Nlc3MgPSBzY2hlbWFfcmVmZXJlbmNlOiBcdTcxMjFcdTZDRDVcdThCODBcdTUzRDZcdTdEQjFcdTg5ODFcdTY1ODdcdTRFRjYgJyd7MH0nJ1x1RkYwQ1x1NTZFMFx1NzBCQSBhY2Nlc3NFeHRlcm5hbFNjaGVtYSBcdTVDNkNcdTYwMjdcdThBMkRcdTVCOUFcdTc2ODRcdTk2NTBcdTUyMzZcdUZGMENcdTYyNDBcdTRFRTVcdTRFMERcdTUxNDFcdThBMzEgJyd7MX0nJyBcdTVCNThcdTUzRDZcdTMwMDIKLSAgICAgICAgc2NoZW1hX3JlZmVyZW5jZS40ID0gc2NoZW1hX3JlZmVyZW5jZS40OiBcdTcxMjFcdTZDRDVcdThCODBcdTUzRDZcdTdEQjFcdTg5ODFcdTY1ODdcdTRFRjYgJyd7MH0nJ1x1RkYwQ1x1NTZFMFx1NzBCQSAxKSBcdTYyN0VcdTRFMERcdTUyMzBcdTY1ODdcdTRFRjY7IDIpIFx1NzEyMVx1NkNENVx1OEI4MFx1NTNENlx1NjU4N1x1NEVGNjsgMykgXHU2NTg3XHU0RUY2XHU3Njg0XHU2ODM5XHU1MTQzXHU3RDIwXHU0RTBEXHU2NjJGIDx4c2Q6c2NoZW1hPlx1MzAwMgotICAgICAgICBzcmMtYW5ub3RhdGlvbiA9IHNyYy1hbm5vdGF0aW9uOiA8YW5ub3RhdGlvbj4gXHU1MTQzXHU3RDIwXHU1MEM1XHU4MEZEXHU1MzA1XHU1NDJCIDxhcHBpbmZvPiBcdTgyMDcgPGRvY3VtZW50YXRpb24+IFx1NTE0M1x1N0QyMFx1RkYwQ1x1NEY0Nlx1NjI3RVx1NTIzMCAnJ3swfScnXHUzMDAyCi0gICAgICAgIHNyYy1hdHRyaWJ1dGUuMSA9IHNyYy1hdHRyaWJ1dGUuMTogXHU1QzZDXHU2MDI3ICcnZGVmYXVsdCcnIFx1ODIwNyAnJ2ZpeGVkJycgXHU0RTBEXHU1M0VGXHU1NDBDXHU2NjQyXHU1MUZBXHU3M0ZFXHU1NzI4XHU1QzZDXHU2MDI3XHU1QkEzXHU1NDRBICcnezB9JycgXHU0RTJEXHUzMDAyXHU4QUNCXHU1M0VBXHU0RjdGXHU3NTI4XHU1MTc2XHU0RTJEXHU0RTAwXHU1MDBCXHUzMDAyCi0gICAgICAgIHNyYy1hdHRyaWJ1dGUuMiA9IHNyYy1hdHRyaWJ1dGUuMjogOiBcdTVDNkNcdTYwMjcgJydkZWZhdWx0JycgXHU1MUZBXHU3M0ZFXHU1NzI4XHU1QzZDXHU2MDI3ICcnezB9JycgXHU0RTJEXHVGRjBDXHU1NkUwXHU2QjY0ICcndXNlJycgXHU3Njg0XHU1MDNDXHU1RkM1XHU5ODA4XHU2NjJGICcnb3B0aW9uYWwnJ1x1MzAwMgotICAgICAgICBzcmMtYXR0cmlidXRlLjMuMSA9IHNyYy1hdHRyaWJ1dGUuMy4xOiAncmVmJyBcdTYyMTYgJ25hbWUnIFx1NTE3Nlx1NEUyRFx1NEU0Qlx1NEUwMFx1NUZDNVx1OTgwOFx1NTFGQVx1NzNGRVx1NTcyOFx1NTM0MFx1NTdERlx1NUM2Q1x1NjAyN1x1NUJBM1x1NTQ0QVx1NEUyRFx1MzAwMgotICAgICAgICBzcmMtYXR0cmlidXRlLjMuMiA9IHNyYy1hdHRyaWJ1dGUuMy4yOiBcdTUxNjdcdTVCQjlcdTVGQzVcdTk4MDhcdTdCMjZcdTU0MDggKGFubm90YXRpb24/KSBcdTVDNkNcdTYwMjdcdTUzQzNcdTcxNjcgJyd7MH0nJ1x1MzAwMgotICAgICAgICBzcmMtYXR0cmlidXRlLjQgPSBzcmMtYXR0cmlidXRlLjQ6IFx1NUM2Q1x1NjAyNyAnJ3swfScnIFx1NTQwQ1x1NjY0Mlx1NTE3N1x1NjcwOSAnJ3R5cGUnJyBcdTVDNkNcdTYwMjdcdTgyMDdcdTUzM0ZcdTU0MEQgJydzaW1wbGVUeXBlJycgXHU1QjUwXHU5ODA1XHUzMDAyXHU1QzZDXHU2MDI3XHU1MEM1XHU1MTQxXHU4QTMxXHU1MTc2XHU0RTJEXHU0RTRCXHU0RTAwXHUzMDAyCi0gICAgICAgIHNyYy1hdHRyaWJ1dGVfZ3JvdXAuMiA9IHNyYy1hdHRyaWJ1dGVfZ3JvdXAuMjogXHU4NDJDXHU3NTI4XHU1QjU3XHU1MTQzXHU3Njg0XHU0RUE0XHU5NkM2XHU1QzBEXHU2NUJDXHU1QzZDXHU2MDI3XHU3RkE0XHU3RDQ0ICcnezB9JycgXHU3MTIxXHU2Q0Q1XHU4ODY4XHU3OTNBXHUzMDAyCi0gICAgICAgIHNyYy1hdHRyaWJ1dGVfZ3JvdXAuMyA9IHNyYy1hdHRyaWJ1dGVfZ3JvdXAuMzogXHU1QzZDXHU2MDI3XHU3RkE0XHU3RDQ0ICcnezB9JycgXHU1MDc1XHU2RTJDXHU1MjMwXHU1RkFBXHU3NEIwXHU1QjlBXHU3RkE5XHUzMDAyXHU5MDVFXHU4RkY0XHU0RjdGXHU3NTI4XHU1QzZDXHU2MDI3XHU3RkE0XHU3RDQ0XHU1M0MzXHU3MTY3XHU1QzA3XHU2NzAzXHU1NkRFXHU1MjMwXHU2NzJDXHU4RUFCXHUzMDAyCi0gICAgICAgIHNyYy1jdC4xID0gc3JjLWN0LjE6IFx1OTg1RVx1NTc4QiAnJ3swfScnIFx1NzY4NFx1ODkwN1x1OTZEQ1x1OTg1RVx1NTc4Qlx1NUI5QVx1N0ZBOVx1ODg2OFx1NzkzQVx1OTMyRlx1OEFBNFx1MzAwMlx1NzU3Nlx1NEY3Rlx1NzUyOCA8Y29tcGxleENvbnRlbnQ+IFx1NjY0Mlx1RkYwQ1x1NTdGQVx1NzkwRVx1OTg1RVx1NTc4Qlx1NUZDNVx1OTgwOFx1NzBCQSBjb21wbGV4VHlwZVx1MzAwMicnezF9JycgXHU3MEJBIHNpbXBsZVR5cGVcdTMwMDIKLSAgICAgICAgc3JjLWN0LjIuMSA9IHNyYy1jdC4yLjE6IFx1OTg1RVx1NTc4QiAnJ3swfScnIFx1NzY4NFx1ODkwN1x1OTZEQ1x1OTg1RVx1NTc4Qlx1NUI5QVx1N0ZBOVx1ODg2OFx1NzkzQVx1OTMyRlx1OEFBNFx1MzAwMlx1NEY3Rlx1NzUyOCA8c2ltcGxlQ29udGVudD4gXHU2NjQyXHVGRjBDXHU1N0ZBXHU3OTBFXHU5ODVFXHU1NzhCXHU1RkM1XHU5ODA4XHU3MEJBIGNvbXBsZXhUeXBlXHVGRjBDXHU0RjQ2XHU1MTc2XHU1MTY3XHU1QkI5XHU5ODVFXHU1NzhCXHU3MEJBXHU3QzIxXHU1NUFFOyBcdTYyMTZcdTgwMDVcdTYzMDdcdTVCOUFcdTk2NTBcdTUyMzZcdTY2NDJcdUZGMENcdTUxNzZcdTUxNjdcdTVCQjlcdTcwQkFcdTZERjdcdTU0MDhcdTUxNjdcdTVCQjlcdTgyMDdcdTUzRUZcdTdBN0FcdTc2N0RcdTcyNjlcdTRFRjZcdTc2ODRcdTg5MDdcdTk2RENcdTk4NUVcdTU3OEI7IFx1NjIxNlx1ODAwNVx1NjMwN1x1NUI5QVx1NjRGNFx1NTE0NVx1NTk1N1x1NEVGNlx1NjY0Mlx1RkYwQ1x1NTE3Nlx1NTE2N1x1NUJCOVx1NzBCQVx1N0MyMVx1NTVBRVx1OTg1RVx1NTc4Qlx1MzAwMicnezF9JycgXHU0RTBEXHU3QjI2XHU1NDA4XHU5MDE5XHU0RTlCXHU2ODlEXHU0RUY2XHUzMDAyCi0gICAgICAgIHNyYy1jdC4yLjIgPSBzcmMtY3QuMi4yOiBcdTk4NUVcdTU3OEIgJyd7MH0nJyBcdTc2ODRcdTg5MDdcdTk2RENcdTk4NUVcdTU3OEJcdTVCOUFcdTdGQTlcdTg4NjhcdTc5M0FcdTkzMkZcdThBQTRcdTMwMDJcdTc1NzZcdTUxNzdcdTY3MDkgc2ltcGxlQ29udGVudCBcdTc2ODQgY29tcGxleFR5cGUgXHU5NjUwXHU1MjM2XHU1MTc3XHU2NzA5XHU2REY3XHU1NDA4XHU1MTY3XHU1QkI5XHU3Njg0IGNvbXBsZXhUeXBlIFx1ODIwN1x1NTNFRlx1N0E3QVx1NzY3RFx1NzI2OVx1NEVGNlx1NjY0Mlx1RkYwQ1x1NTcyOCA8cmVzdHJpY3Rpb24+IFx1NzY4NFx1NUI1MFx1OTgwNVx1NzU3Nlx1NEUyRFx1NUZDNVx1OTgwOFx1NjcwOVx1NEUwMFx1NTAwQiA8c2ltcGxlVHlwZT5cdTMwMDIKLSAgICAgICAgc3JjLWN0LjQgPSBzcmMtY3QuNDogXHU5ODVFXHU1NzhCICcnezB9JycgXHU3Njg0XHU4OTA3XHU5NkRDXHU5ODVFXHU1NzhCXHU1QjlBXHU3RkE5XHU4ODY4XHU3OTNBXHU5MzJGXHU4QUE0XHUzMDAyXHU4NDJDXHU3NTI4XHU1QjU3XHU1MTQzXHU3Njg0XHU0RUE0XHU5NkM2XHU3MTIxXHU2Q0Q1XHU4ODY4XHU3OTNBXHUzMDAyCi0gICAgICAgIHNyYy1jdC41ID0gc3JjLWN0LjU6IFx1OTg1RVx1NTc4QiAnJ3swfScnIFx1NzY4NFx1ODkwN1x1OTZEQ1x1OTg1RVx1NTc4Qlx1NUI5QVx1N0ZBOVx1ODg2OFx1NzkzQVx1OTMyRlx1OEFBNFx1MzAwMlx1ODQyQ1x1NzUyOFx1NUI1N1x1NTE0M1x1NzY4NFx1ODA2Rlx1OTZDNlx1NzEyMVx1NkNENVx1ODg2OFx1NzkzQVx1MzAwMgotICAgICAgICBzcmMtZWxlbWVudC4xID0gc3JjLWVsZW1lbnQuMTogXHU1QzZDXHU2MDI3ICcnZGVmYXVsdCcnIFx1ODIwNyAnJ2ZpeGVkJycgXHU0RTBEXHU1M0VGXHU1NDBDXHU2NjQyXHU1MUZBXHU3M0ZFXHU1NzI4XHU1MTQzXHU3RDIwXHU1QkEzXHU1NDRBICcnezB9JycgXHU0RTJEXHUzMDAyXHU4QUNCXHU1M0VBXHU0RjdGXHU3NTI4XHU1MTc2XHU0RTJEXHU0RTAwXHU1MDBCXHUzMDAyCi0gICAgICAgIHNyYy1lbGVtZW50LjIuMSA9IHNyYy1lbGVtZW50LjIuMTogOiAncmVmJyBcdTYyMTYgJ25hbWUnIFx1NTE3Nlx1NEUyRFx1NEU0Qlx1NEUwMFx1NUZDNVx1OTgwOFx1NTFGQVx1NzNGRVx1NTcyOFx1NTM0MFx1NTdERlx1NTE0M1x1N0QyMFx1NUJBM1x1NTQ0QVx1NEUyRFx1MzAwMgotICAgICAgICBzcmMtZWxlbWVudC4yLjIgPSBzcmMtZWxlbWVudC4yLjI6IFx1NzUzMVx1NjVCQyAnJ3swfScnIFx1NTMwNVx1NTQyQiAnJ3JlZicnIFx1NUM2Q1x1NjAyN1x1RkYwQ1x1NTE3Nlx1NTE2N1x1NUJCOVx1NUZDNVx1OTgwOFx1N0IyNlx1NTQwOCAoYW5ub3RhdGlvbj8pXHUzMDAyXHU0RTBEXHU5MDRFXHVGRjBDXHU2MjdFXHU1MjMwICcnezF9JydcdTMwMDIKLSAgICAgICAgc3JjLWVsZW1lbnQuMyA9IHNyYy1lbGVtZW50LjM6IFx1NTE0M1x1N0QyMCAnJ3swfScnIFx1NTQwQ1x1NjY0Mlx1NTE3N1x1NjcwOSAnJ3R5cGUnJyBcdTVDNkNcdTYwMjdcdTgyMDcgJydhbm9ueW1vdXMgdHlwZScnIFx1NUI1MFx1OTgwNVx1MzAwMlx1NTE0M1x1N0QyMFx1NTBDNVx1NTE0MVx1OEEzMVx1NTE3Nlx1NEUyRFx1NEU0Qlx1NEUwMFx1MzAwMgotICAgICAgICBzcmMtaW1wb3J0LjEuMSA9IHNyYy1pbXBvcnQuMS4xOiA8aW1wb3J0PiBcdTUxNDNcdTdEMjBcdThDQzdcdThBMEFcdTk4MDVcdTc2RUVcdTc2ODRcdTU0N0RcdTU0MERcdTdBN0FcdTk1OTNcdTVDNkNcdTYwMjcgJyd7MH0nJyBcdTRFMERcdTUzRUZcdTgyMDdcdTVCODNcdTYyNDBcdTVCNThcdTU3MjhcdTdEQjFcdTg5ODFcdTc2ODQgdGFyZ2V0TmFtZXNwYWNlIFx1NzZGOFx1NTQwQ1x1MzAwMgotICAgICAgICBzcmMtaW1wb3J0LjEuMiA9IHNyYy1pbXBvcnQuMS4yOiBcdTgyRTVcdTU0N0RcdTU0MERcdTdBN0FcdTk1OTNcdTVDNkNcdTYwMjdcdTY3MkFcdTUxRkFcdTczRkVcdTU3MjggPGltcG9ydD4gXHU1MTQzXHU3RDIwXHU4Q0M3XHU4QTBBXHU5ODA1XHU3NkVFXHU0RTBBXHVGRjBDXHU1MjQ3XHU1MzA1XHU1NDJCXHU3Njg0XHU3REIxXHU4OTgxXHU1RkM1XHU5ODA4XHU2NzA5IHRhcmdldE5hbWVzcGFjZVx1MzAwMgotICAgICAgICBzcmMtaW1wb3J0LjIgPSBzcmMtaW1wb3J0LjI6IFx1NjU4N1x1NEVGNiAnJ3swfScnIFx1NzY4NFx1NjgzOVx1NTE0M1x1N0QyMFx1NUZDNVx1OTgwOFx1NTE3N1x1NjcwOVx1NTQ3RFx1NTQwRFx1N0E3QVx1OTU5M1x1NTQwRFx1N0EzMSAnJ2h0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hJycgXHU4MjA3XHU1MzQwXHU1N0RGXHU1NDBEXHU3QTMxICcnc2NoZW1hJydcdTMwMDIKLSAgICAgICAgc3JjLWltcG9ydC4zLjEgPSBzcmMtaW1wb3J0LjMuMTogPGltcG9ydD4gXHU1MTQzXHU3RDIwXHU4Q0M3XHU4QTBBXHU5ODA1XHU3NkVFXHU3Njg0XHU1NDdEXHU1NDBEXHU3QTdBXHU5NTkzXHU1QzZDXHU2MDI3ICcnezB9JycgXHU1RkM1XHU5ODA4XHU3QjQ5XHU2NUJDXHU1MzJGXHU1MTY1XHU2NTg3XHU0RUY2XHU3Njg0IHRhcmdldE5hbWVzcGFjZSBcdTVDNkNcdTYwMjcgJyd7MX0nJ1x1MzAwMgotICAgICAgICBzcmMtaW1wb3J0LjMuMiA9IHNyYy1pbXBvcnQuMy4yOiBcdTYyN0VcdTUyMzBcdTZDOTJcdTY3MDlcdTU0N0RcdTU0MERcdTdBN0FcdTk1OTNcdTVDNkNcdTYwMjdcdTc2ODQgPGltcG9ydD4gXHU1MTQzXHU3RDIwXHU4Q0M3XHU4QTBBXHU5ODA1XHU3NkVFXHVGRjBDXHU1NkUwXHU2QjY0XHVGRjBDXHU1MzJGXHU1MTY1XHU3Njg0XHU2NTg3XHU0RUY2XHU0RTBEXHU4MEZEXHU1MTc3XHU2NzA5IHRhcmdldE5hbWVzcGFjZSBcdTVDNkNcdTYwMjdcdTMwMDJcdTRFMERcdTkwNEVcdUZGMENcdTU3MjhcdTUzMkZcdTUxNjVcdTc2ODRcdTY1ODdcdTRFRjZcdTRFMkRcdTYyN0VcdTUyMzAgdGFyZ2V0TmFtZXNwYWNlICcnezF9JydcdTMwMDIKLSAgICAgICAgc3JjLWluY2x1ZGUuMSA9IHNyYy1pbmNsdWRlLjE6IFx1NjU4N1x1NEVGNiAnJ3swfScnIFx1NzY4NFx1NjgzOVx1NTE0M1x1N0QyMFx1NUZDNVx1OTgwOFx1NTE3N1x1NjcwOVx1NTQ3RFx1NTQwRFx1N0E3QVx1OTU5M1x1NTQwRFx1N0EzMSAnJ2h0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hJycgXHU4MjA3XHU1MzQwXHU1N0RGXHU1NDBEXHU3QTMxICcnc2NoZW1hJydcdTMwMDIKLSAgICAgICAgc3JjLWluY2x1ZGUuMi4xID0gc3JjLWluY2x1ZGUuMi4xOiBcdTUzQzNcdTcxNjdcdTdEQjFcdTg5ODFcdTc2ODQgdGFyZ2V0TmFtZXNwYWNlIChcdTc2RUVcdTUyNERcdTcwQkEgJyd7MX0nJykgXHU1RkM1XHU5ODA4XHU3QjQ5XHU2NUJDXHU1MzA1XHU1NDJCXHU3REIxXHU4OTgxXHU3Njg0IHRhcmdldE5hbWVzcGFjZSAoXHU3NkVFXHU1MjREXHU3MEJBICcnezB9JycpXHUzMDAyCi0gICAgICAgIHNyYy1yZWRlZmluZS4yID0gc3JjLXJlZGVmaW5lLjI6IFx1NjU4N1x1NEVGNiAnJ3swfScnIFx1NzY4NFx1NjgzOVx1NTE0M1x1N0QyMFx1NUZDNVx1OTgwOFx1NTE3N1x1NjcwOVx1NTQ3RFx1NTQwRFx1N0E3QVx1OTU5M1x1NTQwRFx1N0EzMSAnJ2h0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hJycgXHU4MjA3XHU1MzQwXHU1N0RGXHU1NDBEXHU3QTMxICcnc2NoZW1hJydcdTMwMDIKLSAgICAgICAgc3JjLXJlZGVmaW5lLjMuMSA9IHNyYy1yZWRlZmluZS4zLjE6IFx1NTNDM1x1NzE2N1x1N0RCMVx1ODk4MVx1NzY4NCB0YXJnZXROYW1lc3BhY2UgKFx1NzZFRVx1NTI0RFx1NzBCQSAnJ3sxfScnKSBcdTVGQzVcdTk4MDhcdTdCNDlcdTY1QkNcdTkxQ0RcdTY1QjBcdTVCOUFcdTdGQTlcdTdEQjFcdTg5ODFcdTc2ODQgdGFyZ2V0TmFtZXNwYWNlIChcdTc2RUVcdTUyNERcdTcwQkEgJyd7MH0nJylcdTMwMDIKLSAgICAgICAgc3JjLXJlZGVmaW5lLjUuYS5hID0gc3JjLXJlZGVmaW5lLjUuYS5hOiBcdTYyN0VcdTRFMERcdTUyMzAgPHNpbXBsZVR5cGU+IFx1OTc1RVx1OEEzQlx1ODlFM1x1NUI1MFx1OTgwNVx1MzAwMjxyZWRlZmluZT4gXHU1MTQzXHU3RDIwXHU3Njg0IDxzaW1wbGVUeXBlPiBcdTVCNTBcdTk4MDVcdTVGQzVcdTk4MDhcdTUxNzdcdTY3MDkgPHJlc3RyaWN0aW9uPiBcdTVCNTBcdTdDRkJcdTgyMDdcdTUzQzNcdTcxNjdcdTY3MkNcdThFQUJcdTc2ODQgJ2Jhc2UnIFx1NUM2Q1x1NjAyN1x1MzAwMgotICAgICAgICBzcmMtcmVkZWZpbmUuNS5hLmIgPSBzcmMtcmVkZWZpbmUuNS5hLmI6ICcnezB9JycgXHU0RTBEXHU2NjJGXHU2NzA5XHU2NTQ4XHU1QjUwXHU5ODA1XHU1MTQzXHU3RDIwXHUzMDAyPHJlZGVmaW5lPiBcdTUxNDNcdTdEMjBcdTc2ODQgPHNpbXBsZVR5cGU+IFx1NUI1MFx1OTgwNVx1NUZDNVx1OTgwOFx1NTE3N1x1NjcwOSA8cmVzdHJpY3Rpb24+IFx1NUI1MFx1N0NGQlx1ODIwN1x1NTNDM1x1NzE2N1x1NjcyQ1x1OEVBQlx1NzY4NCAnJ2Jhc2UnJyBcdTVDNkNcdTYwMjdcdTMwMDIKLSAgICAgICAgc3JjLXJlZGVmaW5lLjUuYS5jID0gc3JjLXJlZGVmaW5lLjUuYS5jOiAnJ3swfScnIFx1NkM5Mlx1NjcwOVx1NTNDM1x1NzE2N1x1OTFDRFx1NjVCMFx1NUI5QVx1N0ZBOVx1NTE0M1x1N0QyMCAoJyd7MX0nJykgXHU3Njg0ICcnYmFzZScnIFx1NUM2Q1x1NjAyN1x1MzAwMjxyZWRlZmluZT4gXHU1MTQzXHU3RDIwXHU3Njg0IDxzaW1wbGVUeXBlPiBcdTVCNTBcdTk4MDVcdTVGQzVcdTk4MDhcdTUxNzdcdTY3MDkgPHJlc3RyaWN0aW9uPiBcdTVCNTBcdTdDRkJcdTgyMDdcdTUzQzNcdTcxNjdcdTY3MkNcdThFQUJcdTc2ODQgJydiYXNlJycgXHU1QzZDXHU2MDI3XHUzMDAyCi0gICAgICAgIHNyYy1yZWRlZmluZS41LmIuYSA9IHNyYy1yZWRlZmluZS41LmIuYTogXHU2MjdFXHU0RTBEXHU1MjMwIDxjb21wbGV4VHlwZT4gXHU3Njg0XHU5NzVFXHU4QTNCXHU4OUUzXHU1QjUwXHU5ODA1XHUzMDAyPHJlZGVmaW5lPiBcdTUxNDNcdTdEMjBcdTc2ODQgPGNvbXBsZXhUeXBlPiBcdTVCNTBcdTk4MDVcdTVGQzVcdTk4MDhcdTUxNzdcdTY3MDkgPGV4dGVuc2lvbj4gXHU2MjE2IDxyZXN0cmljdGlvbj4gXHU1QjUwXHU3Q0ZCXHU4MjA3XHU1M0MzXHU3MTY3XHU2NzJDXHU4RUFCXHU3Njg0ICdiYXNlJyBcdTVDNkNcdTYwMjdcdTMwMDIKLSAgICAgICAgc3JjLXJlZGVmaW5lLjUuYi5iID0gc3JjLXJlZGVmaW5lLjUuYi5iOiBcdTYyN0VcdTRFMERcdTUyMzAgPGNvbXBsZXhUeXBlPiBcdTc2ODRcdTk3NUVcdThBM0JcdTg5RTNcdTVCNkJcdTdDRkJcdTMwMDI8cmVkZWZpbmU+IFx1NTE0M1x1N0QyMFx1NzY4NCA8Y29tcGxleFR5cGU+IFx1NUI1MFx1OTgwNVx1NUZDNVx1OTgwOFx1NTE3N1x1NjcwOSA8ZXh0ZW5zaW9uPiBcdTYyMTYgPHJlc3RyaWN0aW9uPiBcdTVCNTBcdTdDRkJcdTgyMDdcdTUzQzNcdTcxNjdcdTY3MkNcdThFQUJcdTc2ODQgJ2Jhc2UnIFx1NUM2Q1x1NjAyN1x1MzAwMgotICAgICAgICBzcmMtcmVkZWZpbmUuNS5iLmMgPSBzcmMtcmVkZWZpbmUuNS5iLmM6ICcnezB9JycgXHU0RTBEXHU2NjJGXHU2NzA5XHU2NTQ4XHU1QjZCXHU3Q0ZCXHU1MTQzXHU3RDIwXHUzMDAyPHJlZGVmaW5lPiBcdTUxNDNcdTdEMjBcdTc2ODQgPGNvbXBsZXhUeXBlPiBcdTVCNTBcdTk4MDVcdTVGQzVcdTk4MDhcdTUxNzdcdTY3MDkgPGV4dGVuc2lvbj4gXHU2MjE2IDxyZXN0cmljdGlvbj4gXHU1QjUwXHU3Q0ZCXHU4MjA3XHU1M0MzXHU3MTY3XHU2NzJDXHU4RUFCXHU3Njg0ICcnYmFzZScnIFx1NUM2Q1x1NjAyN1x1MzAwMgotICAgICAgICBzcmMtcmVkZWZpbmUuNS5iLmQgPSBzcmMtcmVkZWZpbmUuNS5iLmQ6ICcnezB9JycgXHU2QzkyXHU2NzA5XHU1M0MzXHU3MTY3XHU5MUNEXHU2NUIwXHU1QjlBXHU3RkE5XHU1MTQzXHU3RDIwICgnJ3sxfScnKSBcdTc2ODQgJydiYXNlJycgXHU1QzZDXHU2MDI3XHUzMDAyPHJlZGVmaW5lPiBcdTUxNDNcdTdEMjBcdTc2ODQgPGNvbXBsZXhUeXBlPiBcdTVCNTBcdTk4MDVcdTVGQzVcdTk4MDhcdTUxNzdcdTY3MDkgPGV4dGVuc2lvbj4gXHU2MjE2IDxyZXN0cmljdGlvbj4gXHU1QjUwXHU3Q0ZCXHU4MjA3XHU1M0MzXHU3MTY3XHU2NzJDXHU4RUFCXHU3Njg0ICcnYmFzZScnIFx1NUM2Q1x1NjAyN1x1MzAwMgotICAgICAgICBzcmMtcmVkZWZpbmUuNi4xLjEgPSBzcmMtcmVkZWZpbmUuNi4xLjE6IFx1ODJFNSA8cmVkZWZpbmU+IFx1NTE0M1x1N0QyMFx1NzY4NFx1N0ZBNFx1N0Q0NFx1NUI1MFx1OTgwNVx1NTMwNVx1NTQyQlx1NTNDM1x1NzE2N1x1NjcyQ1x1OEVBQlx1NzY4NFx1N0ZBNFx1N0Q0NFx1RkYwQ1x1NUI4M1x1NUZDNVx1OTgwOFx1NTI1Qlx1NTk3RFx1NTNFQVx1NjcwOSAxIFx1NTAwQjsgXHU2QjY0XHU5ODA1XHU2NzA5ICcnezB9JycgXHU1MDBCXHUzMDAyCi0gICAgICAgIHNyYy1yZWRlZmluZS42LjEuMiA9IHNyYy1yZWRlZmluZS42LjEuMjogXHU1MzA1XHU1NDJCXHU5MUNEXHU2NUIwXHU1QjlBXHU3RkE5XHU3RkE0XHU3RDQ0XHU1M0MzXHU3MTY3XHU3Njg0XHU3RkE0XHU3RDQ0ICcnezB9JycgXHU1RkM1XHU5ODA4XHU1MTc3XHU2NzA5ICcnbWluT2NjdXJzJycgPSAnJ21heE9jY3VycycnID0gMVx1MzAwMgotICAgICAgICBzcmMtcmVkZWZpbmUuNi4yLjEgPSBzcmMtcmVkZWZpbmUuNi4yLjE6IFx1OTFDRFx1NjVCMFx1NUI5QVx1N0ZBOVx1N0RCMVx1ODk4MVx1NEUyRFx1NkM5Mlx1NjcwOVx1N0ZBNFx1N0Q0NFx1NTE3N1x1NjcwOVx1N0IyNlx1NTQwOCAnJ3swfScnIFx1NzY4NFx1NTQwRFx1N0EzMVx1MzAwMgotICAgICAgICBzcmMtcmVkZWZpbmUuNi4yLjIgPSBzcmMtcmVkZWZpbmUuNi4yLjI6IFx1N0ZBNFx1N0Q0NCAnJ3swfScnIFx1NjcyQVx1OTA2OVx1NzU3Nlx1OTY1MFx1NTIzNlx1NUI4M1x1OTFDRFx1NjVCMFx1NUI5QVx1N0ZBOVx1NzY4NFx1N0ZBNFx1N0Q0NDsgXHU5MDU1XHU1M0NEXHU5NjUwXHU1MjM2XHU2ODlEXHU0RUY2OiAgJyd7MX0nJ1x1MzAwMgotICAgICAgICBzcmMtcmVkZWZpbmUuNy4xID0gc3JjLXJlZGVmaW5lLjcuMTogXHU4MkU1IDxyZWRlZmluZT4gXHU1MTQzXHU3RDIwXHU3Njg0IGF0dHJpYnV0ZUdyb3VwIFx1NUI1MFx1OTgwNVx1NTMwNVx1NTQyQlx1NTNDM1x1NzE2N1x1NjcyQ1x1OEVBQlx1NzY4NCBhdHRyaWJ1dGVHcm91cFx1RkYwQ1x1NUI4M1x1NUZDNVx1OTgwOFx1NTI1Qlx1NTk3RFx1NTNFQVx1NjcwOSAxIFx1NTAwQjsgXHU2QjY0XHU5ODA1XHU2NzA5ICcnezB9JycgXHU1MDBCXHUzMDAyCi0gICAgICAgIHNyYy1yZWRlZmluZS43LjIuMSA9IHNyYy1yZWRlZmluZS43LjIuMTogXHU5MUNEXHU2NUIwXHU1QjlBXHU3RkE5XHU3REIxXHU4OTgxXHU0RTJEXHU2QzkyXHU2NzA5IGF0dHJpYnV0ZUdyb3VwIFx1NTE3N1x1NjcwOVx1N0IyNlx1NTQwOCAnJ3swfScnIFx1NzY4NFx1NTQwRFx1N0EzMVx1MzAwMgotICAgICAgICBzcmMtcmVkZWZpbmUuNy4yLjIgPSBzcmMtcmVkZWZpbmUuNy4yLjI6IEF0dHJpYnV0ZUdyb3VwICcnezB9JycgXHU2NzJBXHU5MDY5XHU3NTc2XHU5NjUwXHU1MjM2XHU1QjgzXHU5MUNEXHU2NUIwXHU1QjlBXHU3RkE5XHU3Njg0IEF0dHJpYnV0ZUdyb3VwOyBcdTkwNTVcdTUzQ0RcdTk2NTBcdTUyMzZcdTY4OURcdTRFRjY6ICAnJ3sxfScnXHUzMDAyCi0gICAgICAgIHNyYy1yZXNvbHZlID0gc3JjLXJlc29sdmU6IFx1NzEyMVx1NkNENVx1NUMwN1x1NTQwRFx1N0EzMSAnJ3swfScnIFx1ODlFM1x1Njc5MFx1NzBCQSAnJ3sxfScnIFx1NTE0M1x1NEVGNlx1MzAwMgotICAgICAgICBzcmMtcmVzb2x2ZS40LjEgPSBzcmMtcmVzb2x2ZS40LjE6IFx1ODlFM1x1Njc5MFx1NTE0M1x1NEVGNiAnJ3syfScnIFx1NjY0Mlx1NzY3Q1x1NzUxRlx1OTMyRlx1OEFBNFx1MzAwMlx1NTA3NVx1NkUyQ1x1NTIzMCAnJ3syfScnIFx1NkM5Mlx1NjcwOVx1NTQ3RFx1NTQwRFx1N0E3QVx1OTU5M1x1RkYwQ1x1NEY0Nlx1NjYyRlx1RkYwQ1x1NUY5RVx1N0RCMVx1ODk4MVx1NjU4N1x1NEVGNiAnJ3swfScnIFx1NzEyMVx1NkNENVx1NTNDM1x1NzE2N1x1NkM5Mlx1NjcwOVx1NzZFRVx1NkExOVx1NTQ3RFx1NTQwRFx1N0E3QVx1OTU5M1x1NzY4NFx1NTE0M1x1NEVGNlx1MzAwMlx1ODJFNVx1ODk4MVx1OEI5MyAnJ3syfScnIFx1NTE3N1x1NjcwOVx1NTQ3RFx1NTQwRFx1N0E3QVx1OTU5M1x1RkYwQ1x1NTNFRlx1ODAwM1x1NjE2RVx1NjNEMFx1NEY5Qlx1NTI0RFx1N0Y2RVx1NzhCQ1x1MzAwMlx1ODJFNVx1NEUwRFx1ODk4MVx1OEI5MyAnJ3syfScnIFx1NTE3N1x1NjcwOVx1NTQ3RFx1NTQwRFx1N0E3QVx1OTU5M1x1RkYwQ1x1NTI0N1x1NjFDOVx1NUMwN1x1NkM5Mlx1NjcwOSAibmFtZXNwYWNlIiBcdTVDNkNcdTYwMjdcdTc2ODQgJydpbXBvcnQnJyBcdTY1QjBcdTU4OUVcdTgxRjMgJyd7MH0nJ1x1MzAwMgotICAgICAgICBzcmMtcmVzb2x2ZS40LjIgPSBzcmMtcmVzb2x2ZS40LjI6IFx1ODlFM1x1Njc5MFx1NTE0M1x1NEVGNiAnJ3syfScnIFx1NjY0Mlx1NzY3Q1x1NzUxRlx1OTMyRlx1OEFBNFx1MzAwMlx1NTA3NVx1NkUyQ1x1NTIzMCAnJ3syfScnIFx1NEY0RFx1NjVCQ1x1NTQ3RFx1NTQwRFx1N0E3QVx1OTU5MyAnJ3sxfScnIFx1NEUyRFx1RkYwQ1x1NEY0Nlx1NjYyRlx1RkYwQ1x1NUY5RVx1N0RCMVx1ODk4MVx1NjU4N1x1NEVGNiAnJ3swfScnIFx1NzEyMVx1NkNENVx1NTNDM1x1NzE2N1x1NkI2NFx1NTQ3RFx1NTQwRFx1N0E3QVx1OTU5M1x1NzY4NFx1NTE0M1x1NEVGNlx1MzAwMlx1ODJFNVx1NkI2NFx1NzBCQVx1NEUwRFx1NkI2M1x1NzhCQVx1NzY4NFx1NTQ3RFx1NTQwRFx1N0E3QVx1OTU5M1x1RkYwQ1x1NTNFRlx1ODAwM1x1NjE2RVx1OEI4QVx1NjZGNCAnJ3syfScnIFx1NzY4NFx1NTI0RFx1N0Y2RVx1NzhCQ1x1MzAwMlx1ODJFNVx1NkI2NFx1NzBCQVx1NkI2M1x1NzhCQVx1NzY4NFx1NTQ3RFx1NTQwRFx1N0E3QVx1OTU5M1x1RkYwQ1x1NTI0N1x1NjFDOVx1NUMwN1x1OTA2OVx1NzU3Nlx1NzY4NCAnJ2ltcG9ydCcnIFx1NkExOVx1OEExOFx1NjVCMFx1NTg5RVx1ODFGMyAnJ3swfScnXHUzMDAyCi0gICAgICAgIHNyYy1zaW1wbGUtdHlwZS4yLmEgPSBzcmMtc2ltcGxlLXR5cGUuMi5hOiBcdTYyN0VcdTUyMzAgPHJlc3RyaWN0aW9uPiBcdTUxNDNcdTdEMjBcdUZGMENcdTU3MjhcdTUxNzYgW2NoaWxkcmVuXSBcdTRFMkRcdTU0MENcdTY2NDJcdTY3MDlcdTU3RkFcdTc5MEUgW2F0dHJpYnV0ZV0gXHU4MjA3IDxzaW1wbGVUeXBlPiBcdTUxNDNcdTdEMjBcdTMwMDJcdTUwQzVcdTUxNDFcdThBMzFcdTUxNzZcdTRFMkRcdTRFMDBcdTk4MDVcdTMwMDIKLSAgICAgICAgc3JjLXNpbXBsZS10eXBlLjIuYiA9IHNyYy1zaW1wbGUtdHlwZS4yLmI6IFx1NjI3RVx1NTIzMCA8cmVzdHJpY3Rpb24+IFx1NTE0M1x1N0QyMFx1RkYwQ1x1NTcyOFx1NTE3NiBbY2hpbGRyZW5dIFx1NEUyRFx1NkM5Mlx1NjcwOVx1NTdGQVx1NzkwRSBbYXR0cmlidXRlXVx1RkYwQ1x1NEU1Rlx1NkM5Mlx1NjcwOSA8c2ltcGxlVHlwZT4gXHU1MTQzXHU3RDIwXHUzMDAyXHU5NzAwXHU4OTgxXHU1MTc2XHU0RTJEXHU0RTAwXHU5ODA1XHUzMDAyCi0gICAgICAgIHNyYy1zaW1wbGUtdHlwZS4zLmEgPSBzcmMtc2ltcGxlLXR5cGUuMy5hOiBcdTYyN0VcdTUyMzAgPGxpc3Q+IFx1NTE0M1x1N0QyMFx1RkYwQ1x1NTcyOFx1NTE3NiBbY2hpbGRyZW5dIFx1NEUyRFx1NTQwQ1x1NjY0Mlx1NjcwOSBpdGVtVHlwZSBbYXR0cmlidXRlXSBcdTgyMDcgPHNpbXBsZVR5cGU+IFx1NTE0M1x1N0QyMFx1MzAwMlx1NTBDNVx1NTE0MVx1OEEzMVx1NTE3Nlx1NEUyRFx1NEUwMFx1OTgwNVx1MzAwMgotICAgICAgICBzcmMtc2ltcGxlLXR5cGUuMy5iID0gc3JjLXNpbXBsZS10eXBlLjMuYjogXHU2MjdFXHU1MjMwIDxsaXN0PiBcdTUxNDNcdTdEMjBcdUZGMENcdTU3MjhcdTUxNzYgW2NoaWxkcmVuXSBcdTRFMkRcdTZDOTJcdTY3MDkgaXRlbVR5cGUgW2F0dHJpYnV0ZV1cdUZGMENcdTRFNUZcdTZDOTJcdTY3MDkgPHNpbXBsZVR5cGU+IFx1NTE0M1x1N0QyMFx1MzAwMlx1OTcwMFx1ODk4MVx1NTE3Nlx1NEUyRFx1NEUwMFx1OTgwNVx1MzAwMgotICAgICAgICBzcmMtc2luZ2xlLWZhY2V0LXZhbHVlID0gc3JjLXNpbmdsZS1mYWNldC12YWx1ZTogXHU1QjlBXHU3RkE5IGZhY2V0ICcnezB9JycgXHU4RDg1XHU5MDRFXHU0RTAwXHU2QjIxXHU0RUU1XHU0RTBBXHUzMDAyCi0gICAgICAgIHNyYy11bmlvbi1tZW1iZXJUeXBlcy1vci1zaW1wbGVUeXBlcyA9IHNyYy11bmlvbi1tZW1iZXJUeXBlcy1vci1zaW1wbGVUeXBlczogPHVuaW9uPiBcdTUxNDNcdTdEMjBcdTU3MjhcdTUxNzYgW2NoaWxkcmVuXSBcdTRFMkRcdUZGMENcdTVGQzVcdTk4MDhcdTUxNzdcdTY3MDlcdTk3NUVcdTdBN0FcdTc2N0QgbWVtYmVyVHlwZXMgW2F0dHJpYnV0ZV0gXHU2MjE2XHU4MUYzXHU1QzExXHU0RTAwXHU1MDBCIDxzaW1wbGVUeXBlPiBcdTUxNDNcdTdEMjBcdTMwMDIKLQotI2NvbnN0cmFpbnQgdmFsaWQgKDMuWC42KQotCi0gICAgICAgIGFnLXByb3BzLWNvcnJlY3QuMiA9IGFnLXByb3BzLWNvcnJlY3QuMjogXHU1QzZDXHU2MDI3XHU3RkE0XHU3RDQ0ICcnezB9JycgXHU3Njg0XHU5MzJGXHU4QUE0XHUzMDAyXHU5MUNEXHU4OTA3XHU1QzZDXHU2MDI3XHU0RjdGXHU3NTI4XHU3NkY4XHU1NDBDXHU1NDBEXHU3QTMxXHU0RTE0XHU2MzA3XHU1QjlBXHU0RTg2XHU3NkVFXHU2QTE5XHU1NDdEXHU1NDBEXHU3QTdBXHU5NTkzXHUzMDAyXHU5MUNEXHU4OTA3XHU1QzZDXHU2MDI3XHU0RjdGXHU3NTI4XHU3Njg0XHU1NDBEXHU3QTMxXHU3MEJBICcnezF9JydcdTMwMDIKLSAgICAgICAgYWctcHJvcHMtY29ycmVjdC4zID0gYWctcHJvcHMtY29ycmVjdC4zOiBcdTVDNkNcdTYwMjdcdTdGQTRcdTdENDQgJyd7MH0nJyBcdTc2ODRcdTkzMkZcdThBQTRcdTMwMDJcdTUxNjlcdTUwMEJcdTVDNkNcdTYwMjdcdTVCQTNcdTU0NEEgJyd7MX0nJyBcdTgyMDcgJyd7Mn0nJyBcdTUxNzdcdTY3MDlcdTg4NERcdTc1MUZcdTgxRUEgSUQgXHU3Njg0XHU5ODVFXHU1NzhCXHUzMDAyCi0gICAgICAgIGEtcHJvcHMtY29ycmVjdC4yID0gYS1wcm9wcy1jb3JyZWN0LjI6IFx1NUM2Q1x1NjAyNyAnJ3swfScnIFx1NEUyRFx1NzY4NFx1NTAzQ1x1OTY1MFx1NTIzNlx1Njg5RFx1NEVGNlx1NTAzQyAnJ3sxfScnIFx1NzEyMVx1NjU0OFx1MzAwMgotICAgICAgICBhLXByb3BzLWNvcnJlY3QuMyA9IGEtcHJvcHMtY29ycmVjdC4zOiBcdTVDNkNcdTYwMjcgJyd7MH0nJyBcdTcxMjFcdTZDRDVcdTRGN0ZcdTc1MjggJydmaXhlZCcnIFx1NjIxNiAnJ2RlZmF1bHQnJ1x1RkYwQ1x1NTZFMFx1NzBCQVx1NUM2Q1x1NjAyN1x1NzY4NCAneyd0eXBlIGRlZmluaXRpb24nfScgXHU3MEJBIElEXHVGRjBDXHU2MjE2XHU4ODREXHU3NTFGXHU4MUVBIElEXHUzMDAyCi0gICAgICAgIGF1LXByb3BzLWNvcnJlY3QuMiA9IGF1LXByb3BzLWNvcnJlY3QuMjogXHU1NzI4ICcnezB9JycgXHU3Njg0XHU1QzZDXHU2MDI3XHU1QkEzXHU1NDRBXHU0RTJEXHVGRjBDXHU2MzA3XHU1QjlBXHU0RTg2ICcnezF9JycgXHU3Njg0XHU1NkZBXHU1QjlBXHU1MDNDXHUzMDAyXHU1NkUwXHU2QjY0XHVGRjBDXHU4MkU1XHU1M0MzXHU3MTY3ICcnezB9JycgXHU3Njg0XHU1QzZDXHU2MDI3XHU0RjdGXHU3NTI4XHU0RTVGXHU1MTc3XHU2NzA5ICd7J3ZhbHVlIGNvbnN0cmFpbnQnfSdcdUZGMENcdTVCODNcdTVGQzVcdTk4MDhcdTY2MkZcdTU2RkFcdTVCOUFcdTUwM0NcdTRFMTRcdTUwM0NcdTVGQzVcdTk4MDhcdTcwQkEgJyd7MX0nJ1x1MzAwMgotICAgICAgICBjb3MtYWxsLWxpbWl0ZWQuMS4yID0gY29zLWFsbC1saW1pdGVkLjEuMjogJ2FsbCcgXHU2QTIxXHU1NzhCXHU3RkE0XHU3RDQ0XHU1RkM1XHU5ODA4XHU1MUZBXHU3M0ZFXHU1NzI4ICd7J21pbiBvY2N1cnMnfScgPSAneydtYXggb2NjdXJzJ30nID0gMSBcdTc2ODRcdTcyNjlcdTRFRjZcdTRFMkRcdUZGMENcdTRFMTRcdThBNzJcdTcyNjlcdTRFRjZcdTVGQzVcdTk4MDhcdTY2MkZcdTRFMDBcdTVDMERcdTdENDRcdTYyMTBcdTg5MDdcdTk2RENcdTk4NUVcdTU3OEJcdTVCOUFcdTdGQTlcdTRFNEIgJ3snY29udGVudCB0eXBlJ30nIFx1NzI2OVx1NEVGNlx1NEUyRFx1NzY4NFx1NEUwMFx1OTBFOFx1NTIwNlx1MzAwMgotICAgICAgICBjb3MtYWxsLWxpbWl0ZWQuMiA9IGNvcy1hbGwtbGltaXRlZC4yOiAnJ2FsbCcnIFx1NkEyMVx1NTc4Qlx1N0ZBNFx1N0Q0NFx1NEUyRFx1NTE0M1x1N0QyMFx1NzY4NCAneydtYXggb2NjdXJzJ30nIFx1NUZDNVx1OTgwOFx1NjYyRiAwIFx1NjIxNiAxXHUzMDAyXHU1MTQzXHU3RDIwICcnezF9JycgXHU3Njg0XHU1MDNDICcnezB9JycgXHU3MTIxXHU2NTQ4XHUzMDAyCi0gICAgICAgIGNvcy1hcHBsaWNhYmxlLWZhY2V0cyA9IGNvcy1hcHBsaWNhYmxlLWZhY2V0czogXHU5ODVFXHU1NzhCIHsxfSBcdTRFMERcdTUxNDFcdThBMzEgRmFjZXQgJyd7MH0nJ1x1MzAwMgotICAgICAgICBjb3MtY3QtZXh0ZW5kcy4xLjEgPSBjb3MtY3QtZXh0ZW5kcy4xLjE6IFx1OTg1RVx1NTc4QiAnJ3swfScnIFx1NjYyRlx1NzUzMVx1NjRGNFx1NTE0NVx1NTk1N1x1NEVGNlx1NUY5RVx1OTg1RVx1NTc4QiAnJ3sxfScnIFx1ODg0RFx1NzUxRlx1MzAwMlx1NEUwRFx1OTA0RVx1RkYwQycnezF9JycgXHU3Njg0ICcnZmluYWwnJyBcdTVDNkNcdTYwMjdcdTc5ODFcdTZCNjJcdTc1MzFcdTY0RjRcdTUxNDVcdTU5NTdcdTRFRjZcdTg4NERcdTc1MUZcdTMwMDIKLSAgICAgICAgY29zLWN0LWV4dGVuZHMuMS40LjMuMi4yLjEuYSA9IGNvcy1jdC1leHRlbmRzLjEuNC4zLjIuMi4xLmE6IFx1ODg0RFx1NzUxRlx1OTg1RVx1NTc4Qlx1ODIwN1x1NTE3Nlx1NTdGQVx1NzkwRVx1NzY4NFx1NTE2N1x1NUJCOVx1OTg1RVx1NTc4Qlx1NzY4Nlx1NUZDNVx1OTgwOFx1NjYyRlx1NkRGN1x1NTQwOFx1OTg1RVx1NTc4Qlx1NjIxNlx1NTE2OVx1ODAwNVx1NzY4Nlx1NjYyRiBlbGVtZW50LW9ubHlcdTMwMDJcdTk4NUVcdTU3OEIgJyd7MH0nJyBcdTY2MkYgZWxlbWVudC1vbmx5XHVGRjBDXHU0RjQ2XHU1MTc2XHU1N0ZBXHU3OTBFXHU5ODVFXHU1NzhCXHU1MjQ3XHU1NDI2XHUzMDAyCi0gICAgICAgIGNvcy1jdC1leHRlbmRzLjEuNC4zLjIuMi4xLmIgPSBjb3MtY3QtZXh0ZW5kcy4xLjQuMy4yLjIuMS5iOiBcdTg4NERcdTc1MUZcdTk4NUVcdTU3OEJcdTgyMDdcdTUxNzZcdTU3RkFcdTc5MEVcdTc2ODRcdTUxNjdcdTVCQjlcdTk4NUVcdTU3OEJcdTc2ODZcdTVGQzVcdTk4MDhcdTY2MkZcdTZERjdcdTU0MDhcdTk4NUVcdTU3OEJcdTYyMTZcdTUxNjlcdTgwMDVcdTc2ODZcdTY2MkYgZWxlbWVudC1vbmx5XHUzMDAyXHU5ODVFXHU1NzhCICcnezB9JycgXHU3MEJBXHU2REY3XHU1NDA4XHU5ODVFXHU1NzhCXHVGRjBDXHU0RjQ2XHU1MTc2XHU1N0ZBXHU3OTBFXHU5ODVFXHU1NzhCXHU1MjQ3XHU1NDI2XHUzMDAyCi0gICAgICAgIGNvcy1lbGVtZW50LWNvbnNpc3RlbnQgPSBjb3MtZWxlbWVudC1jb25zaXN0ZW50OiBcdTk4NUVcdTU3OEIgJyd7MH0nJyBcdTc2ODRcdTkzMkZcdThBQTRcdTMwMDJcdTU3MjhcdTZBMjFcdTU3OEJcdTdGQTRcdTdENDRcdTRFMkRcdTUxRkFcdTczRkVcdTU0MERcdTdBMzEgJyd7MX0nJ1x1MzAwMVx1NEUwRFx1NTQwQ1x1OTg1RVx1NTc4Qlx1NzY4NFx1NTkxQVx1NTAwQlx1NTE0M1x1N0QyMFx1MzAwMgotICAgICAgICBjb3MtbGlzdC1vZi1hdG9taWMgPSBjb3MtbGlzdC1vZi1hdG9taWM6IFx1NkUwNVx1NTVBRVx1OTg1RVx1NTc4QiAnJ3swfScnIFx1NzY4NFx1NUI5QVx1N0ZBOVx1NEUyRFx1RkYwQ1x1OTg1RVx1NTc4QiAnJ3sxfScnIFx1NjYyRlx1NzEyMVx1NjU0OFx1NzY4NFx1NkUwNVx1NTVBRVx1NTE0M1x1N0QyMFx1OTg1RVx1NTc4Qlx1RkYwQ1x1NTZFMFx1NzBCQVx1NUI4M1x1NEUwRFx1NjYyRlx1NTVBRVx1NTE0M1x1OTg1RVx1NTc4QiAoJyd7MX0nJyBcdTcwQkFcdTZFMDVcdTU1QUVcdTk4NUVcdTU3OEJcdUZGMENcdTYyMTZcdTUzMDVcdTU0MkJcdTZFMDVcdTU1QUVcdTc2ODRcdTgwNkZcdTk2QzZcdTk4NUVcdTU3OEIpXHUzMDAyCi0gICAgICAgIGNvcy1ub25hbWJpZyA9IGNvcy1ub25hbWJpZzogezB9IFx1ODIwNyB7MX0gKFx1NjIxNlx1NEY4Nlx1ODFFQVx1NTE3Nlx1NjZGRlx1NEVFM1x1N0ZBNFx1N0Q0NFx1NzY4NFx1NTE0M1x1N0QyMCkgXHU5MDU1XHU1M0NEXHUzMDBDXHU1NTJGXHU0RTAwXHU3MjY5XHU0RUY2XHU1QzZDXHU2MDI3XHUzMDBEXHUzMDAyXHU0RjlEXHU2QjY0XHU3REIxXHU4OTgxXHU5QTU3XHU4QjQ5XHU2NzFGXHU5NTkzXHVGRjBDXHU3MEJBXHU5MDE5XHU1MTY5XHU1MDBCXHU3MjY5XHU0RUY2XHU1RUZBXHU3QUNCXHU0RTg2XHU0RTBEXHU3OEJBXHU1QjlBXHU2MDI3XHUzMDAyCi0gICAgICAgIGNvcy1wYXJ0aWNsZS1yZXN0cmljdC5hID0gY29zLXBhcnRpY2xlLXJlc3RyaWN0LmE6IFx1ODg0RFx1NzUxRlx1NzI2OVx1NEVGNlx1NzBCQVx1N0E3QVx1NzY3RFx1RkYwQ1x1NTI0N1x1NTdGQVx1NzkwRVx1NzI2OVx1NEVGNlx1NEUwRFx1NTNFRlx1NzBCQVx1N0E3QVx1NzY3RFx1MzAwMgotICAgICAgICBjb3MtcGFydGljbGUtcmVzdHJpY3QuYiA9IGNvcy1wYXJ0aWNsZS1yZXN0cmljdC5iOiBcdTU3RkFcdTc5MEVcdTcyNjlcdTRFRjZcdTcwQkFcdTdBN0FcdTc2N0RcdUZGMENcdTRGNDZcdTY2MkZcdTg4NERcdTc1MUZcdTcyNjlcdTRFRjZcdTUyNDdcdTU0MjZcdTMwMDIKLSAgICAgICAgY29zLXBhcnRpY2xlLXJlc3RyaWN0LjIgPSBjb3MtcGFydGljbGUtcmVzdHJpY3QuMjogXHU3OTgxXHU2QjYyXHU3Njg0XHU3MjY5XHU0RUY2XHU5NjUwXHU1MjM2OiAnJ3swfScnXHUzMDAyCi0gICAgICAgIGNvcy1zdC1yZXN0cmljdHMuMS4xID0gY29zLXN0LXJlc3RyaWN0cy4xLjE6IFx1OTg1RVx1NTc4QiAnJ3sxfScnIFx1NzBCQVx1NTVBRVx1NTE0M1x1OTg1RVx1NTc4Qlx1RkYwQ1x1NTZFMFx1NkI2NFx1NTE3NiAneydiYXNlIHR5cGUgZGVmaW5pdGlvbid9JyAoJyd7MH0nJykgXHU1RkM1XHU5ODA4XHU2NjJGXHU1NUFFXHU1MTQzXHU3QzIxXHU1NUFFXHU5ODVFXHU1NzhCXHU1QjlBXHU3RkE5XHU2MjE2XHU1MTY3XHU1RUZBXHU3Njg0XHU1MzlGXHU1OUNCXHU4Q0M3XHU2NTk5XHU5ODVFXHU1NzhCXHUzMDAyCi0gICAgICAgIGNvcy1zdC1yZXN0cmljdHMuMi4xID0gY29zLXN0LXJlc3RyaWN0cy4yLjE6IFx1NkUwNVx1NTVBRVx1OTg1RVx1NTc4QiAnJ3swfScnIFx1NzY4NFx1NUI5QVx1N0ZBOVx1NEUyRFx1RkYwQ1x1OTg1RVx1NTc4QiAnJ3sxfScnIFx1NjYyRlx1NzEyMVx1NjU0OFx1NzY4NFx1OTgwNVx1NzZFRVx1OTg1RVx1NTc4Qlx1RkYwQ1x1NTZFMFx1NzBCQVx1NUI4M1x1NjYyRlx1NkUwNVx1NTVBRVx1OTg1RVx1NTc4Qlx1RkYwQ1x1NjIxNlx1NTMwNVx1NTQyQlx1NkUwNVx1NTVBRVx1NzY4NFx1ODA2Rlx1OTZDNlx1OTg1RVx1NTc4Qlx1MzAwMgotICAgICAgICBjb3Mtc3QtcmVzdHJpY3RzLjIuMy4xLjEgPSBjb3Mtc3QtcmVzdHJpY3RzLjIuMy4xLjE6ICd7J2l0ZW0gdHlwZSBkZWZpbml0aW9uJ30nIFx1NzY4NCAneydmaW5hbCd9JyBcdTUxNDNcdTRFRjYgJyd7MH0nJyBcdTUzMDVcdTU0MkIgJydsaXN0JydcdTMwMDJcdTkwMTlcdTRFRTNcdTg4NjggJyd7MH0nJyBcdTcxMjFcdTZDRDVcdTRGNUNcdTcwQkFcdTZFMDVcdTU1QUVcdTk4NUVcdTU3OEIgJyd7MX0nJyBcdTc2ODRcdTk4MDVcdTc2RUVcdTk4NUVcdTU3OEJcdTMwMDIKLSAgICAgICAgY29zLXN0LXJlc3RyaWN0cy4zLjMuMS4xID0gY29zLXN0LXJlc3RyaWN0cy4zLjMuMS4xOiAneydtZW1iZXIgdHlwZSBkZWZpbml0aW9ucyd9JyBcdTc2ODQgJ3snZmluYWwnfScgXHU1MTQzXHU0RUY2ICcnezB9JycgXHU1MzA1XHU1NDJCICcndW5pb24nJ1x1MzAwMlx1OTAxOVx1NEVFM1x1ODg2OCAnJ3swfScnIFx1NzEyMVx1NkNENVx1NEY1Q1x1NzBCQVx1ODA2Rlx1OTZDNlx1OTg1RVx1NTc4QiAnJ3sxfScnIFx1NzY4NFx1NjIxMFx1NTRFMVx1OTg1RVx1NTc4Qlx1MzAwMgotICAgICAgICBjb3MtdmFsaWQtZGVmYXVsdC4yLjEgPSBjb3MtdmFsaWQtZGVmYXVsdC4yLjE6IFx1NTE0M1x1N0QyMCAnJ3swfScnIFx1NTE3N1x1NjcwOVx1NTAzQ1x1OTY1MFx1NTIzNlx1Njg5RFx1NEVGNlx1RkYwQ1x1NEUxNFx1NUZDNVx1OTgwOFx1NTE3N1x1NjcwOVx1NkRGN1x1NTQwOFx1NjIxNlx1N0MyMVx1NTVBRVx1NTE2N1x1NUJCOVx1NkEyMVx1NTc4Qlx1MzAwMgotICAgICAgICBjb3MtdmFsaWQtZGVmYXVsdC4yLjIuMiA9IGNvcy12YWxpZC1kZWZhdWx0LjIuMi4yOiBcdTc1MzFcdTY1QkNcdTUxNDNcdTdEMjAgJyd7MH0nJyBcdTUxNzdcdTY3MDkgJ3sndmFsdWUgY29uc3RyYWludCd9JyBcdTRFMTRcdTUxNzZcdTk4NUVcdTU3OEJcdTVCOUFcdTdGQTlcdTUxNzdcdTY3MDlcdTZERjdcdTU0MDhcdTc2ODQgJ3snY29udGVudCB0eXBlJ30nXHVGRjBDXHU1NkUwXHU2QjY0ICd7J2NvbnRlbnQgdHlwZSd9JyBcdTc2ODRcdTcyNjlcdTRFRjZcdTVGQzVcdTk4MDhcdTY2MkZcdTUzRUZcdTdBN0FcdTc2N0RcdTMwMDIKLSAgICAgICAgYy1wcm9wcy1jb3JyZWN0LjIgPSBjLXByb3BzLWNvcnJlY3QuMjoga2V5cmVmICcnezB9JycgXHU4MjA3IGtleSAnJ3sxfScnIFx1NzY4NCBGaWVsZHMgXHU1N0ZBXHU2NTc4XHU1RjdDXHU2QjY0XHU1RkM1XHU5ODA4XHU3NkY4XHU3QjI2XHUzMDAyCi0gICAgICAgIGN0LXByb3BzLWNvcnJlY3QuMyA9IGN0LXByb3BzLWNvcnJlY3QuMzogXHU1MDc1XHU2RTJDXHU1MjMwXHU4OTA3XHU5NkRDXHU5ODVFXHU1NzhCICcnezB9JycgXHU3Njg0XHU1RkFBXHU3NEIwXHU1QjlBXHU3RkE5XHUzMDAyXHU5MDE5XHU0RUUzXHU4ODY4ICcnezB9JycgXHU1MzA1XHU1NDJCXHU1NzI4XHU4MUVBXHU4RUFCXHU5ODVFXHU1NzhCXHU5NjhFXHU1QzY0XHU0RTJEXHVGRjBDXHU5MDE5XHU2NjJGXHU0RTAwXHU5ODA1XHU5MzJGXHU4QUE0XHUzMDAyCi0gICAgICAgIGN0LXByb3BzLWNvcnJlY3QuNCA9IGN0LXByb3BzLWNvcnJlY3QuNDogXHU5ODVFXHU1NzhCICcnezB9JycgXHU3Njg0XHU5MzJGXHU4QUE0XHUzMDAyXHU5MUNEXHU4OTA3XHU1QzZDXHU2MDI3XHU0RjdGXHU3NTI4XHU3NkY4XHU1NDBDXHU1NDBEXHU3QTMxXHU0RTE0XHU2MzA3XHU1QjlBXHU0RTg2XHU3NkVFXHU2QTE5XHU1NDdEXHU1NDBEXHU3QTdBXHU5NTkzXHUzMDAyXHU5MUNEXHU4OTA3XHU1QzZDXHU2MDI3XHU0RjdGXHU3NTI4XHU3Njg0XHU1NDBEXHU3QTMxXHU3MEJBICcnezF9JydcdTMwMDIKLSAgICAgICAgY3QtcHJvcHMtY29ycmVjdC41ID0gY3QtcHJvcHMtY29ycmVjdC41OiBcdTk4NUVcdTU3OEIgJyd7MH0nJyBcdTc2ODRcdTkzMkZcdThBQTRcdTMwMDJcdTUxNjlcdTUwMEJcdTVDNkNcdTYwMjdcdTVCQTNcdTU0NEEgJyd7MX0nJyBcdTgyMDcgJyd7Mn0nJyBcdTUxNzdcdTY3MDlcdTg4NERcdTc1MUZcdTgxRUEgSUQgXHU3Njg0XHU5ODVFXHU1NzhCXHUzMDAyCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMSA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMTogXHU5ODVFXHU1NzhCICcnezB9JycgXHU3NTMxXHU5NjUwXHU1MjM2XHU1RjlFXHU5ODVFXHU1NzhCICcnezF9JycgXHU4ODREXHU3NTFGXHUzMDAyXHU0RTBEXHU5MDRFXHVGRjBDJyd7MX0nJyBcdTUxNzdcdTY3MDkgJ3snZmluYWwnfScgXHU1QzZDXHU2MDI3XHVGRjBDXHU3OTgxXHU2QjYyXHU3NTMxXHU5NjUwXHU1MjM2XHU4ODREXHU3NTFGXHUzMDAyCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMi4xLjEgPSBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjIuMS4xOiBcdTk4NUVcdTU3OEIgJyd7MH0nJyBcdTc2ODRcdTkzMkZcdThBQTRcdTMwMDJcdTZCNjRcdTk4NUVcdTU3OEJcdTRFMkRcdTRGN0ZcdTc1MjggJyd7MX0nJyBcdTc2ODRcdTVDNkNcdTYwMjdcdTUxNzdcdTY3MDkgJyd1c2UnJyBcdTUwM0NcdTc2ODQgJyd7Mn0nJ1x1RkYwQ1x1OTAxOVx1ODIwN1x1NTdGQVx1NzkwRVx1OTg1RVx1NTc4Qlx1NEUyRFx1NEY3Rlx1NzUyOFx1N0IyNlx1NTQwOFx1NUM2Q1x1NjAyN1x1NzY4NCAnJ3JlcXVpcmVkJycgXHU1MDNDXHU0RTBEXHU0RTAwXHU4MUY0XHUzMDAyCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMi4xLjIgPSBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjIuMS4yOiBcdTk4NUVcdTU3OEIgJyd7MH0nJyBcdTc2ODRcdTkzMkZcdThBQTRcdTMwMDJcdTZCNjRcdTk4NUVcdTU3OEJcdTRFMkRcdTRGN0ZcdTc1MjggJyd7MX0nJyBcdTc2ODRcdTVDNkNcdTYwMjdcdTUxNzdcdTY3MDlcdTk4NUVcdTU3OEIgJyd7Mn0nJ1x1RkYwQ1x1OTAxOVx1NEUwRFx1NjYyRlx1NjcwOVx1NjU0OFx1ODg0RFx1NzUxRlx1ODFFQSAnJ3szfScnXHVGRjBDXHU0RUE2XHU1MzczXHU1N0ZBXHU3OTBFXHU5ODVFXHU1NzhCXHU0RTJEXHU0RjdGXHU3NTI4XHU3QjI2XHU1NDA4XHU1QzZDXHU2MDI3XHU3Njg0XHU5ODVFXHU1NzhCXHUzMDAyCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMi4xLjMuYSA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMi4xLjMuYTogXHU5ODVFXHU1NzhCICcnezB9JycgXHU3Njg0XHU5MzJGXHU4QUE0XHUzMDAyXHU2QjY0XHU5ODVFXHU1NzhCXHU0RTJEXHU0RjdGXHU3NTI4ICcnezF9JycgXHU3Njg0XHU1QzZDXHU2MDI3XHU1MTc3XHU2NzA5XHU2NzJBXHU1NkZBXHU1QjlBXHU3Njg0XHU2NzA5XHU2NTQ4XHU1MDNDXHU5NjUwXHU1MjM2XHU2ODlEXHU0RUY2XHVGRjBDXHU4MDBDXHU1N0ZBXHU3OTBFXHU5ODVFXHU1NzhCXHU0RTJEXHU0RjdGXHU3NTI4XHU3Njg0XHU3QjI2XHU1NDA4XHU1QzZDXHU2MDI3XHU2NzA5XHU2NTQ4XHU1MDNDXHU5NjUwXHU1MjM2XHU2ODlEXHU0RUY2XHU3MEJBXHU1NkZBXHU1QjlBXHU1RjBGXHUzMDAyCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMi4xLjMuYiA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMi4xLjMuYjogXHU5ODVFXHU1NzhCICcnezB9JycgXHU3Njg0XHU5MzJGXHU4QUE0XHUzMDAyXHU2QjY0XHU5ODVFXHU1NzhCXHU0RTJEXHU0RjdGXHU3NTI4ICcnezF9JycgXHU3Njg0XHU1QzZDXHU2MDI3XHU1MTc3XHU2NzA5ICcnezJ9JycgXHU1NkZBXHU1QjlBXHU1MDNDXHU3Njg0XHU2NzA5XHU2NTQ4XHU1MDNDXHU5NjUwXHU1MjM2XHU2ODlEXHU0RUY2XHVGRjBDXHU5MDE5XHU4MjA3XHU1N0ZBXHU3OTBFXHU5ODVFXHU1NzhCXHU0RTJEXHU0RjdGXHU3NTI4XHU3QjI2XHU1NDA4XHU1QzZDXHU2MDI3XHU3Njg0XHU1NkZBXHU1QjlBXHU2NzA5XHU2NTQ4XHU1MDNDXHU5NjUwXHU1MjM2XHU2ODlEXHU0RUY2ICcnezN9JycgXHU3Njg0XHU1MDNDXHU0RTBEXHU0RTAwXHU4MUY0XHUzMDAyCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMi4yLmEgPSBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjIuMi5hOiBcdTk4NUVcdTU3OEIgJyd7MH0nJyBcdTc2ODRcdTkzMkZcdThBQTRcdTMwMDJcdTZCNjRcdTk4NUVcdTU3OEJcdTRFMkRcdTRGN0ZcdTc1MjggJyd7MX0nJyBcdTc2ODRcdTVDNkNcdTYwMjdcdTU3MjhcdTU3RkFcdTc5MEVcdTk4NUVcdTU3OEJcdTRFMkRcdTZDOTJcdTY3MDlcdTRGN0ZcdTc1MjhcdTdCMjZcdTU0MDhcdTc2ODRcdTVDNkNcdTYwMjdcdUZGMENcdTRFMTRcdTU3RkFcdTc5MEVcdTk4NUVcdTU3OEJcdTZDOTJcdTY3MDlcdTg0MkNcdTc1MjhcdTVCNTdcdTUxNDNcdTVDNkNcdTYwMjdcdTMwMDIKLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4yLjIuYiA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMi4yLmI6IFx1OTg1RVx1NTc4QiAnJ3swfScnIFx1NzY4NFx1OTMyRlx1OEFBNFx1MzAwMlx1NkI2NFx1OTg1RVx1NTc4Qlx1NEUyRFx1NEY3Rlx1NzUyOCAnJ3sxfScnIFx1NzY4NFx1NUM2Q1x1NjAyN1x1NTcyOFx1NTdGQVx1NzkwRVx1OTg1RVx1NTc4Qlx1NEUyRFx1NkM5Mlx1NjcwOVx1NEY3Rlx1NzUyOFx1N0IyNlx1NTQwOFx1NzY4NFx1NUM2Q1x1NjAyN1x1RkYwQ1x1NEUxNFx1NTdGQVx1NzkwRVx1OTg1RVx1NTc4Qlx1NEUyRFx1NzY4NFx1ODQyQ1x1NzUyOFx1NUI1N1x1NTE0M1x1NEUwRFx1NTE0MVx1OEEzMVx1NEY3Rlx1NzUyOFx1NkI2NFx1NUM2Q1x1NjAyN1x1NzY4NFx1NTQ3RFx1NTQwRFx1N0E3QVx1OTU5MyAnJ3syfScnXHUzMDAyCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMyA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMzogXHU5ODVFXHU1NzhCICcnezB9JycgXHU3Njg0XHU5MzJGXHU4QUE0XHUzMDAyXHU1N0ZBXHU3OTBFXHU5ODVFXHU1NzhCXHU0RTJEXHU0RjdGXHU3NTI4ICcnezF9JycgXHU3Njg0XHU1QzZDXHU2MDI3IFJFUVVJUkVEIFx1NzBCQVx1NzcxRlx1RkYwQ1x1NEY0Nlx1NjYyRlx1ODg0RFx1NzUxRlx1OTg1RVx1NTc4Qlx1NEUyRFx1NkM5Mlx1NjcwOVx1NEY3Rlx1NzUyOFx1N0IyNlx1NTQwOFx1NzY4NFx1NUM2Q1x1NjAyN1x1MzAwMgotICAgICAgICBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjQuMSA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uNC4xOiBcdTk4NUVcdTU3OEIgJyd7MH0nJyBcdTc2ODRcdTkzMkZcdThBQTRcdTMwMDJcdTg4NERcdTc1MUZcdTUxNzdcdTY3MDlcdTVDNkNcdTYwMjdcdTg0MkNcdTc1MjhcdTVCNTdcdTUxNDNcdUZGMENcdTRGNDZcdTY2MkZcdTU3RkFcdTc5MEVcdTUyNDdcdTU0MjZcdTMwMDIKLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi40LjIgPSBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjQuMjogXHU5ODVFXHU1NzhCICcnezB9JycgXHU3Njg0XHU5MzJGXHU4QUE0XHUzMDAyXHU4ODREXHU3NTFGXHU0RTJEXHU3Njg0XHU4NDJDXHU3NTI4XHU1QjU3XHU1MTQzXHU0RTBEXHU2NjJGXHU1N0ZBXHU3OTBFXHU0RTJEXHU2NzA5XHU2NTQ4XHU3Njg0XHU4NDJDXHU3NTI4XHU1QjU3XHU1MTQzXHU1QjUwXHU5NkM2XHUzMDAyCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uNC4zID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi40LjM6IFx1OTg1RVx1NTc4QiAnJ3swfScnIFx1NzY4NFx1OTMyRlx1OEFBNFx1MzAwMlx1ODg0RFx1NzUxRiAoezF9KSBcdTRFMkRcdTg0MkNcdTc1MjhcdTVCNTdcdTUxNDNcdTc2ODRcdTg2NTVcdTc0MDZcdTRGNUNcdTY5NkRcdTUxNjdcdTVCQjlcdTZCRDRcdTU3RkFcdTc5MEUgKHsyfSkgXHU0RTJEXHU3Njg0XHU4NjU1XHU3NDA2XHU0RjVDXHU2OTZEXHU1MTY3XHU1QkI5XHU1RjMxXHUzMDAyCi0gICAgICAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uNS4yLjIuMSA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uNS4yLjIuMTogXHU5ODVFXHU1NzhCICcnezB9JycgXHU3Njg0XHU5MzJGXHU4QUE0XHUzMDAyXHU2QjY0XHU5ODVFXHU1NzhCXHU3Njg0XHU3QzIxXHU1NUFFXHU1MTY3XHU1QkI5XHU5ODVFXHU1NzhCICcnezF9JycgXHU0RTBEXHU2NjJGXHU1N0ZBXHU3OTBFXHU3Njg0XHU3QzIxXHU1NUFFXHU1MTY3XHU1QkI5XHU5ODVFXHU1NzhCICgnJ3syfScnKSBcdTc2ODRcdTY3MDlcdTY1NDhcdTk2NTBcdTUyMzZcdTMwMDIKLSAgICAgICAgZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi41LjMuMiA9IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uNS4zLjI6IFx1OTg1RVx1NTc4QiAnJ3swfScnIFx1NzY4NFx1OTMyRlx1OEFBNFx1MzAwMlx1NkI2NFx1OTg1RVx1NTc4Qlx1NzY4NFx1NTE2N1x1NUJCOVx1OTg1RVx1NTc4Qlx1NzBCQVx1N0E3QVx1NzY3RFx1RkYwQ1x1NEY0Nlx1NjYyRlx1NTdGQVx1NzkwRVx1NzY4NFx1NTE2N1x1NUJCOVx1OTg1RVx1NTc4QiAnJ3sxfScnIFx1NEUwRFx1NjYyRlx1N0E3QVx1NzY3RFx1NjIxNlx1NEUwRFx1NTNFRlx1NzBCQVx1N0E3QVx1NzY3RFx1MzAwMgotICAgICAgICBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjUuNC4xLjIgPSBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjUuNC4xLjI6IFx1OTg1RVx1NTc4QiAnJ3swfScnIFx1NzY4NFx1OTMyRlx1OEFBNFx1MzAwMlx1NkI2NFx1OTg1RVx1NTc4Qlx1NzY4NFx1NTE2N1x1NUJCOVx1OTg1RVx1NTc4Qlx1NzBCQVx1NkRGN1x1NTQwOFx1OTg1RVx1NTc4Qlx1RkYwQ1x1NEY0Nlx1NjYyRlx1NTdGQVx1NzkwRVx1NzY4NFx1NTE2N1x1NUJCOVx1OTg1RVx1NTc4QiAnJ3sxfScnIFx1NTI0N1x1NTQyNlx1MzAwMgotICAgICAgICBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjUuNC4yID0gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi41LjQuMjogXHU5ODVFXHU1NzhCICcnezB9JycgXHU3Njg0XHU5MzJGXHU4QUE0XHUzMDAyXHU5ODVFXHU1NzhCXHU3Njg0XHU3MjY5XHU0RUY2XHU0RTBEXHU2NjJGXHU1N0ZBXHU3OTBFXHU3MjY5XHU0RUY2XHU3Njg0XHU2NzA5XHU2NTQ4XHU5NjUwXHU1MjM2XHUzMDAyCi0gICAgICAgIGVudW1lcmF0aW9uLXJlcXVpcmVkLW5vdGF0aW9uID0gZW51bWVyYXRpb24tcmVxdWlyZWQtbm90YXRpb246IFx1NzUzMSB7Mn0gJyd7MX0nJyBcdTRGN0ZcdTc1MjhcdTc2ODQgTk9UQVRJT04gXHU5ODVFXHU1NzhCICcnezB9JydcdUZGMENcdTVGQzVcdTk4MDhcdTUxNzdcdTY3MDlcdTUyMTdcdTgyMDkgZmFjZXQgXHU1MDNDXHVGRjBDXHU0RUU1XHU2MzA3XHU1QjlBXHU2QjY0XHU5ODVFXHU1NzhCXHU0RjdGXHU3NTI4XHU3Njg0XHU4ODY4XHU3OTNBXHU2Q0Q1XHU1MTQzXHU3RDIwXHUzMDAyCi0gICAgICAgIGVudW1lcmF0aW9uLXZhbGlkLXJlc3RyaWN0aW9uID0gZW51bWVyYXRpb24tdmFsaWQtcmVzdHJpY3Rpb246IFx1NTIxN1x1ODIwOVx1NTAzQyAnJ3swfScnIFx1NEUwRFx1NTcyOFx1NTdGQVx1NzkwRVx1OTg1RVx1NTc4QiB7MX0gXHU3Njg0XHU1MDNDXHU3QTdBXHU5NTkzXHU0RTJEXHUzMDAyCi0gICAgICAgIGUtcHJvcHMtY29ycmVjdC4yID0gZS1wcm9wcy1jb3JyZWN0LjI6IFx1NTE0M1x1N0QyMCAnJ3swfScnIFx1NEUyRFx1NzY4NFx1NTAzQ1x1OTY1MFx1NTIzNlx1Njg5RFx1NEVGNlx1NTAzQyAnJ3sxfScnIFx1NzEyMVx1NjU0OFx1MzAwMgotICAgICAgICBlLXByb3BzLWNvcnJlY3QuNCA9IGUtcHJvcHMtY29ycmVjdC40OiBcdTUxNDNcdTdEMjAgJyd7MH0nJyBcdTc2ODQgJ3sndHlwZSBkZWZpbml0aW9uJ30nIFx1NEUwRFx1NjYyRlx1NjcwOVx1NjU0OFx1ODg0RFx1NzUxRlx1ODFFQSBzdWJzdGl0dXRpb25IZWFkICcnezF9JycgXHU3Njg0ICd7J3R5cGUgZGVmaW5pdGlvbid9J1x1RkYwQ1x1NjIxNlx1NjYyRiAnJ3sxfScnIFx1NzY4NCAneydzdWJzdGl0dXRpb24gZ3JvdXAgZXhjbHVzaW9ucyd9JyBcdTVDNkNcdTYwMjdcdTRFMERcdTUxNDFcdThBMzFcdTZCNjRcdTg4NERcdTc1MUZcdTMwMDIKLSAgICAgICAgZS1wcm9wcy1jb3JyZWN0LjUgPSBlLXByb3BzLWNvcnJlY3QuNTogJ3sndmFsdWUgY29uc3RyYWludCd9JyBcdTRFMERcdTUzRUZcdTUxRkFcdTczRkVcdTU3MjhcdTUxNDNcdTdEMjAgJyd7MH0nJyBcdTRFMEFcdUZGMENcdTU2RTBcdTcwQkFcdTUxNDNcdTdEMjBcdTc2ODQgJ3sndHlwZSBkZWZpbml0aW9uJ30nIFx1NjIxNiAneyd0eXBlIGRlZmluaXRpb24nfScgXHU3Njg0ICd7J2NvbnRlbnQgdHlwZSd9JyBcdTcwQkEgSURcdUZGMENcdTYyMTZcdTg4NERcdTc1MUZcdTgxRUEgSURcdTMwMDIKLSAgICAgICAgZS1wcm9wcy1jb3JyZWN0LjYgPSBlLXByb3BzLWNvcnJlY3QuNjogXHU1MDc1XHU2RTJDXHU1MjMwICcnezB9JycgXHU3Njg0XHU1RkFBXHU3NEIwXHU2NkZGXHU0RUUzXHU3RkE0XHU3RDQ0XHUzMDAyCi0gICAgICAgIGZyYWN0aW9uRGlnaXRzLXZhbGlkLXJlc3RyaWN0aW9uID0gZnJhY3Rpb25EaWdpdHMtdmFsaWQtcmVzdHJpY3Rpb246IFx1NTcyOCB7Mn0gXHU3Njg0XHU1QjlBXHU3RkE5XHU0RTJEXHVGRjBDZmFjZXQgJydmcmFjdGlvbkRpZ2l0cycnIFx1NzY4NFx1NTAzQyAnJ3swfScnIFx1NzEyMVx1NjU0OFx1RkYwQ1x1NTZFMFx1NzBCQVx1NUI4M1x1NUZDNVx1OTgwOFx1NUMwRlx1NjVCQ1x1NjIxNlx1N0I0OVx1NjVCQyAnJ2ZyYWN0aW9uRGlnaXRzJycgXHU3Njg0XHU1MDNDXHVGRjBDXHU2QjY0XHU1MDNDXHU0RUU1XHU1MTc2XHU0RTJEXHU0RTAwXHU1MDBCXHU3OTU2XHU3Q0ZCXHU5ODVFXHU1NzhCXHU4QTJEXHU3MEJBICcnezF9JydcdTMwMDIKLSAgICAgICAgZnJhY3Rpb25EaWdpdHMtdG90YWxEaWdpdHMgPSBmcmFjdGlvbkRpZ2l0cy10b3RhbERpZ2l0czogXHU1NzI4IHsyfSBcdTc2ODRcdTVCOUFcdTdGQTlcdTRFMkRcdUZGMENmYWNldCAnJ2ZyYWN0aW9uRGlnaXRzJycgXHU3Njg0XHU1MDNDICcnezB9JycgXHU3MTIxXHU2NTQ4XHVGRjBDXHU1NkUwXHU3MEJBXHU1MDNDXHU1RkM1XHU5ODA4XHU1QzBGXHU2NUJDXHU2MjE2XHU3QjQ5XHU2NUJDICcndG90YWxEaWdpdHMnJyBcdTc2ODRcdTUwM0NcdUZGMENcdTRFQTZcdTUzNzMgJyd7MX0nJ1x1MzAwMgotICAgICAgICBsZW5ndGgtbWluTGVuZ3RoLW1heExlbmd0aC4xLjEgPSBsZW5ndGgtbWluTGVuZ3RoLW1heExlbmd0aC4xLjE6IFx1OTFERFx1NUMwRFx1OTg1RVx1NTc4QiB7MH1cdUZGMENsZW5ndGggJyd7MX0nJyBcdTc2ODRcdTUwM0NcdTVDMEZcdTY1QkMgbWluTGVuZ3RoICcnezJ9JycgXHU3Njg0XHU1MDNDXHU2NjJGXHU0RTAwXHU5ODA1XHU5MzJGXHU4QUE0XHUzMDAyCi0gICAgICAgIGxlbmd0aC1taW5MZW5ndGgtbWF4TGVuZ3RoLjEuMi5hID0gbGVuZ3RoLW1pbkxlbmd0aC1tYXhMZW5ndGguMS4yLmE6IFx1OTFERFx1NUMwRFx1OTg1RVx1NTc4QiB7MH1cdUZGMENcdTgyRTVcdTc2RUVcdTUyNERcdTk2NTBcdTUyMzZcdTUxNzdcdTY3MDkgbWluTGVuZ3RoIGZhY2V0IFx1NEUxNFx1NzZFRVx1NTI0RFx1NzY4NFx1OTY1MFx1NTIzNlx1NjIxNlx1NTdGQVx1NzkwRVx1NTE3N1x1NjcwOSBsZW5ndGggZmFjZXRcdUZGMENcdTUyNDdcdTU3RkFcdTc5MEVcdTZDOTJcdTY3MDkgbWluTGVuZ3RoIGZhY2V0IFx1NjYyRlx1NEUwMFx1OTgwNVx1OTMyRlx1OEFBNFx1MzAwMgotICAgICAgICBsZW5ndGgtbWluTGVuZ3RoLW1heExlbmd0aC4xLjIuYiA9IGxlbmd0aC1taW5MZW5ndGgtbWF4TGVuZ3RoLjEuMi5iOiBcdTkxRERcdTVDMERcdTk4NUVcdTU3OEIgezB9XHVGRjBDXHU3NkVFXHU1MjREXHU3Njg0IG1pbkxlbmd0aCAnJ3sxfScnIFx1NEUwRFx1N0I0OVx1NjVCQ1x1NTdGQVx1NzkwRSBtaW5MZW5ndGggJyd7Mn0nJyBcdTY2MkZcdTRFMDBcdTk4MDVcdTkzMkZcdThBQTRcdTMwMDIKLSAgICAgICAgbGVuZ3RoLW1pbkxlbmd0aC1tYXhMZW5ndGguMi4xID0gbGVuZ3RoLW1pbkxlbmd0aC1tYXhMZW5ndGguMi4xOiBcdTkxRERcdTVDMERcdTk4NUVcdTU3OEIgezB9XHVGRjBDbGVuZ3RoICcnezF9JycgXHU3Njg0XHU1MDNDXHU1OTI3XHU2NUJDIG1heExlbmd0aCAnJ3syfScnIFx1NzY4NFx1NTAzQ1x1NjYyRlx1NEUwMFx1OTgwNVx1OTMyRlx1OEFBNFx1MzAwMgotICAgICAgICBsZW5ndGgtbWluTGVuZ3RoLW1heExlbmd0aC4yLjIuYSA9IGxlbmd0aC1taW5MZW5ndGgtbWF4TGVuZ3RoLjIuMi5hOiBcdTkxRERcdTVDMERcdTk4NUVcdTU3OEIgezB9XHVGRjBDXHU4MkU1XHU3NkVFXHU1MjREXHU3Njg0XHU5NjUwXHU1MjM2XHU1MTc3XHU2NzA5IG1heExlbmd0aCBmYWNldFx1RkYwQ1x1NEUxNFx1NzZFRVx1NTI0RFx1NzY4NFx1OTY1MFx1NTIzNlx1NjIxNlx1NTdGQVx1NzkwRVx1NTE3N1x1NjcwOSBsZW5ndGggZmFjZXRcdUZGMENcdTUyNDdcdTU3RkFcdTc5MEVcdTZDOTJcdTY3MDkgbWF4TGVuZ3RoIGZhY2V0IFx1NjYyRlx1NEUwMFx1OTgwNVx1OTMyRlx1OEFBNFx1MzAwMgotICAgICAgICBsZW5ndGgtbWluTGVuZ3RoLW1heExlbmd0aC4yLjIuYiA9IGxlbmd0aC1taW5MZW5ndGgtbWF4TGVuZ3RoLjIuMi5iOiBcdTkxRERcdTVDMERcdTk4NUVcdTU3OEIgezB9XHVGRjBDXHU3NkVFXHU1MjREXHU3Njg0IG1heExlbmd0aCAnJ3sxfScnIFx1NEUwRFx1N0I0OVx1NjVCQ1x1NTdGQVx1NzkwRSBtYXhMZW5ndGggJyd7Mn0nJyBcdTY2MkZcdTRFMDBcdTk4MDVcdTkzMkZcdThBQTRcdTMwMDIKLSAgICAgICAgbGVuZ3RoLXZhbGlkLXJlc3RyaWN0aW9uID0gbGVuZ3RoLXZhbGlkLXJlc3RyaWN0aW9uOiBcdTk4NUVcdTU3OEIgJyd7Mn0nJyBcdTc2ODRcdTkzMkZcdThBQTRcdTMwMDJcdTdCNDlcdTY1QkMgJyd7MH0nJyBcdTc2ODQgbGVuZ3RoIFx1NTAzQ1x1NUZDNVx1OTgwOFx1N0I0OVx1NjVCQ1x1NTdGQVx1NzkwRVx1OTg1RVx1NTc4QiAnJ3sxfScnIFx1NzY4NCBsZW5ndGggXHU1MDNDXHUzMDAyCi0gICAgICAgIG1heEV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4xID0gbWF4RXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjE6IFx1OTg1RVx1NTc4QiAnJ3syfScnIFx1NzY4NFx1OTMyRlx1OEFBNFx1MzAwMlx1N0I0OVx1NjVCQyAnJ3swfScnIFx1NzY4NCBtYXhFeGNsdXNpdmUgXHU1MDNDXHU1RkM1XHU5ODA4XHU1QzBGXHU2NUJDXHU2MjE2XHU3QjQ5XHU2NUJDXHU1N0ZBXHU3OTBFXHU5ODVFXHU1NzhCICcnezF9JycgXHU3Njg0IG1heEV4Y2x1c2l2ZVx1MzAwMgotICAgICAgICBtYXhFeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMiA9IG1heEV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4yOiBcdTk4NUVcdTU3OEIgJyd7Mn0nJyBcdTc2ODRcdTkzMkZcdThBQTRcdTMwMDJcdTdCNDlcdTY1QkMgJyd7MH0nJyBcdTc2ODQgbWF4RXhjbHVzaXZlIFx1NTAzQ1x1NUZDNVx1OTgwOFx1NUMwRlx1NjVCQ1x1NjIxNlx1N0I0OVx1NjVCQ1x1NTdGQVx1NzkwRVx1OTg1RVx1NTc4QiAnJ3sxfScnIFx1NzY4NCBtYXhJbmNsdXNpdmVcdTMwMDIKLSAgICAgICAgbWF4RXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjMgPSBtYXhFeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMzogXHU5ODVFXHU1NzhCICcnezJ9JycgXHU3Njg0XHU5MzJGXHU4QUE0XHUzMDAyXHU3QjQ5XHU2NUJDICcnezB9JycgXHU3Njg0IG1heEV4Y2x1c2l2ZSBcdTUwM0NcdTVGQzVcdTk4MDhcdTU5MjdcdTY1QkNcdTU3RkFcdTc5MEVcdTk4NUVcdTU3OEIgJyd7MX0nJyBcdTc2ODQgbWluSW5jbHVzaXZlXHUzMDAyCi0gICAgICAgIG1heEV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi40ID0gbWF4RXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjQ6IFx1OTg1RVx1NTc4QiAnJ3syfScnIFx1NzY4NFx1OTMyRlx1OEFBNFx1MzAwMlx1N0I0OVx1NjVCQyAnJ3swfScnIFx1NzY4NCBtYXhFeGNsdXNpdmUgXHU1MDNDXHU1RkM1XHU5ODA4XHU1OTI3XHU2NUJDXHU1N0ZBXHU3OTBFXHU5ODVFXHU1NzhCICcnezF9JycgXHU3Njg0IG1pbkV4Y2x1c2l2ZVx1MzAwMgotICAgICAgICBtYXhJbmNsdXNpdmUtbWF4RXhjbHVzaXZlID0gbWF4SW5jbHVzaXZlLW1heEV4Y2x1c2l2ZTogXHU3MEJBXHU3NkY4XHU1NDBDXHU4Q0M3XHU2NTk5XHU5ODVFXHU1NzhCXHU1NDBDXHU2NjQyXHU2MzA3XHU1QjlBIG1heEluY2x1c2l2ZSBcdTgyMDcgbWF4RXhjbHVzaXZlIFx1NjYyRlx1NEUwMFx1OTgwNVx1OTMyRlx1OEFBNFx1MzAwMlx1NTcyOCB7Mn0gXHU0RTJEXHVGRjBDbWF4SW5jbHVzaXZlIFx1N0I0OVx1NjVCQyAnJ3swfScnIFx1NEUxNCBtYXhFeGNsdXNpdmUgXHU3QjQ5XHU2NUJDICcnezF9JydcdTMwMDIKLSAgICAgICAgbWF4SW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjEgPSBtYXhJbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMTogXHU5ODVFXHU1NzhCICcnezJ9JycgXHU3Njg0XHU5MzJGXHU4QUE0XHUzMDAyXHU3QjQ5XHU2NUJDICcnezB9JycgXHU3Njg0IG1heEluY2x1c2l2ZSBcdTUwM0NcdTVGQzVcdTk4MDhcdTVDMEZcdTY1QkNcdTYyMTZcdTdCNDlcdTY1QkNcdTU3RkFcdTc5MEVcdTk4NUVcdTU3OEIgJyd7MX0nJyBcdTc2ODQgbWF4SW5jbHVzaXZlXHUzMDAyCi0gICAgICAgIG1heEluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4yID0gbWF4SW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjI6IFx1OTg1RVx1NTc4QiAnJ3syfScnIFx1NzY4NFx1OTMyRlx1OEFBNFx1MzAwMlx1N0I0OVx1NjVCQyAnJ3swfScnIFx1NzY4NCBtYXhJbmNsdXNpdmUgXHU1MDNDXHU1RkM1XHU5ODA4XHU1QzBGXHU2NUJDXHU1N0ZBXHU3OTBFXHU5ODVFXHU1NzhCICcnezF9JycgXHU3Njg0IG1heEV4Y2x1c2l2ZVx1MzAwMgotICAgICAgICBtYXhJbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMyA9IG1heEluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4zOiBcdTk4NUVcdTU3OEIgJyd7Mn0nJyBcdTc2ODRcdTkzMkZcdThBQTRcdTMwMDJcdTdCNDlcdTY1QkMgJyd7MH0nJyBcdTc2ODQgbWF4SW5jbHVzaXZlIFx1NTAzQ1x1NUZDNVx1OTgwOFx1NTkyN1x1NjVCQ1x1NjIxNlx1N0I0OVx1NjVCQ1x1NTdGQVx1NzkwRVx1OTg1RVx1NTc4QiAnJ3sxfScnIFx1NzY4NCBtaW5JbmNsdXNpdmVcdTMwMDIKLSAgICAgICAgbWF4SW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjQgPSBtYXhJbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uNDogXHU5ODVFXHU1NzhCICcnezJ9JycgXHU3Njg0XHU5MzJGXHU4QUE0XHUzMDAyXHU3QjQ5XHU2NUJDICcnezB9JycgXHU3Njg0IG1heEluY2x1c2l2ZSBcdTUwM0NcdTVGQzVcdTk4MDhcdTU5MjdcdTY1QkNcdTU3RkFcdTc5MEVcdTk4NUVcdTU3OEIgJyd7MX0nJyBcdTc2ODQgbWluRXhjbHVzaXZlXHUzMDAyCi0gICAgICAgIG1heExlbmd0aC12YWxpZC1yZXN0cmljdGlvbiA9IG1heExlbmd0aC12YWxpZC1yZXN0cmljdGlvbjogXHU1NzI4IHsyfSBcdTc2ODRcdTVCOUFcdTdGQTlcdTRFMkRcdUZGMENcdTdCNDlcdTY1QkMgJyd7MH0nJyBcdTc2ODQgbWF4TGVuZ3RoIFx1NTAzQ1x1NUZDNVx1OTgwOFx1NUMwRlx1NjVCQ1x1NjIxNlx1N0I0OVx1NjVCQ1x1NTdGQVx1NzkwRVx1OTg1RVx1NTc4QiAnJ3sxfScnIFx1NzY4NCBtYXhMZW5ndGggXHU1MDNDXHUzMDAyCi0gICAgICAgIG1nLXByb3BzLWNvcnJlY3QuMiA9IG1nLXByb3BzLWNvcnJlY3QuMjogXHU1MDc1XHU2RTJDXHU1MjMwXHU3RkE0XHU3RDQ0ICcnezB9JycgXHU3Njg0XHU1RkFBXHU3NEIwXHU1QjlBXHU3RkE5XHUzMDAyXHU5MDVFXHU4RkY0XHU0RjdGXHU3NTI4XHU3MjY5XHU0RUY2XHU3Njg0ICd7J3Rlcm0nfScgXHU1MDNDXHU1QzA3XHU1QzBFXHU4MUYzXHU1MTc2ICd7J3Rlcm0nfScgXHU3MEJBXHU3RkE0XHU3RDQ0XHU2NzJDXHU4RUFCXHU3Njg0XHU3MjY5XHU0RUY2XHUzMDAyCi0gICAgICAgIG1pbkV4Y2x1c2l2ZS1sZXNzLXRoYW4tZXF1YWwtdG8tbWF4RXhjbHVzaXZlID0gbWluRXhjbHVzaXZlLWxlc3MtdGhhbi1lcXVhbC10by1tYXhFeGNsdXNpdmU6IFx1NTcyOCB7Mn0gXHU3Njg0XHU1QjlBXHU3RkE5XHU0RTJEXHVGRjBDXHU3QjQ5XHU2NUJDICcnezB9JycgXHU3Njg0IG1pbkV4Y2x1c2l2ZSBcdTUwM0NcdTVGQzVcdTk4MDhcdTVDMEZcdTY1QkNcdTYyMTZcdTdCNDlcdTY1QkMgbWF4RXhjbHVzaXZlIFx1NTAzQyAoXHU3QjQ5XHU2NUJDICcnezF9JycpXHUzMDAyCi0gICAgICAgIG1pbkV4Y2x1c2l2ZS1sZXNzLXRoYW4tbWF4SW5jbHVzaXZlID0gbWluRXhjbHVzaXZlLWxlc3MtdGhhbi1tYXhJbmNsdXNpdmU6IFx1NTcyOCB7Mn0gXHU3Njg0XHU1QjlBXHU3RkE5XHU0RTJEXHVGRjBDXHU3QjQ5XHU2NUJDICcnezB9JycgXHU3Njg0IG1pbkV4Y2x1c2l2ZSBcdTUwM0NcdTVGQzVcdTk4MDhcdTVDMEZcdTY1QkMgbWF4SW5jbHVzaXZlIFx1NTAzQyAoXHU3QjQ5XHU2NUJDICcnezF9JycpXHUzMDAyCi0gICAgICAgIG1pbkV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4xID0gbWluRXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjE6IFx1OTg1RVx1NTc4QiAnJ3syfScnIFx1NzY4NFx1OTMyRlx1OEFBNFx1MzAwMlx1N0I0OVx1NjVCQyAnJ3swfScnIFx1NzY4NCBtaW5FeGNsdXNpdmUgXHU1MDNDXHU1RkM1XHU5ODA4XHU1OTI3XHU2NUJDXHU2MjE2XHU3QjQ5XHU2NUJDXHU1N0ZBXHU3OTBFXHU5ODVFXHU1NzhCICcnezF9JycgXHU3Njg0IG1pbkV4Y2x1c2l2ZVx1MzAwMgotICAgICAgICBtaW5FeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMiA9IG1pbkV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4yOiBcdTk4NUVcdTU3OEIgJyd7Mn0nJyBcdTc2ODRcdTkzMkZcdThBQTRcdTMwMDJcdTdCNDlcdTY1QkMgJyd7MH0nJyBcdTc2ODQgbWluRXhjbHVzaXZlIFx1NTAzQ1x1NUZDNVx1OTgwOFx1NUMwRlx1NjVCQ1x1NjIxNlx1N0I0OVx1NjVCQ1x1NTdGQVx1NzkwRVx1OTg1RVx1NTc4QiAnJ3sxfScnIFx1NzY4NCBtYXhJbmNsdXNpdmVcdTMwMDIKLSAgICAgICAgbWluRXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjMgPSBtaW5FeGNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMzogXHU5ODVFXHU1NzhCICcnezJ9JycgXHU3Njg0XHU5MzJGXHU4QUE0XHUzMDAyXHU3QjQ5XHU2NUJDICcnezB9JycgXHU3Njg0IG1pbkV4Y2x1c2l2ZSBcdTUwM0NcdTVGQzVcdTk4MDhcdTU5MjdcdTY1QkNcdTYyMTZcdTdCNDlcdTY1QkNcdTU3RkFcdTc5MEVcdTk4NUVcdTU3OEIgJyd7MX0nJyBcdTc2ODQgbWluSW5jbHVzaXZlXHUzMDAyCi0gICAgICAgIG1pbkV4Y2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi40ID0gbWluRXhjbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjQ6IFx1OTg1RVx1NTc4QiAnJ3syfScnIFx1NzY4NFx1OTMyRlx1OEFBNFx1MzAwMlx1N0I0OVx1NjVCQyAnJ3swfScnIFx1NzY4NCBtaW5FeGNsdXNpdmUgXHU1MDNDXHU1RkM1XHU5ODA4XHU1QzBGXHU2NUJDXHU1N0ZBXHU3OTBFXHU5ODVFXHU1NzhCICcnezF9JycgXHU3Njg0IG1heEV4Y2x1c2l2ZVx1MzAwMgotICAgICAgICBtaW5JbmNsdXNpdmUtbGVzcy10aGFuLWVxdWFsLXRvLW1heEluY2x1c2l2ZSA9IG1pbkluY2x1c2l2ZS1sZXNzLXRoYW4tZXF1YWwtdG8tbWF4SW5jbHVzaXZlOiBcdTU3MjggezJ9IFx1NzY4NFx1NUI5QVx1N0ZBOVx1NEUyRFx1RkYwQ1x1N0I0OVx1NjVCQyAnJ3swfScnIFx1NzY4NCBtaW5JbmNsdXNpdmUgXHU1MDNDXHU1RkM1XHU5ODA4XHU1QzBGXHU2NUJDXHU2MjE2XHU3QjQ5XHU2NUJDIG1heEluY2x1c2l2ZSBcdTUwM0MgKFx1N0I0OVx1NjVCQyAnJ3sxfScnKVx1MzAwMgotICAgICAgICBtaW5JbmNsdXNpdmUtbGVzcy10aGFuLW1heEV4Y2x1c2l2ZSA9IG1pbkluY2x1c2l2ZS1sZXNzLXRoYW4tbWF4RXhjbHVzaXZlOiBcdTU3MjggezJ9IFx1NzY4NFx1NUI5QVx1N0ZBOVx1NEUyRFx1RkYwQ1x1N0I0OVx1NjVCQyAnJ3swfScnIFx1NzY4NCBtaW5JbmNsdXNpdmUgXHU1MDNDXHU1RkM1XHU5ODA4XHU1QzBGXHU2NUJDIG1heEV4Y2x1c2l2ZSBcdTUwM0MgKFx1N0I0OVx1NjVCQyAnJ3sxfScnKVx1MzAwMgotICAgICAgICBtaW5JbmNsdXNpdmUtbWluRXhjbHVzaXZlID0gbWluSW5jbHVzaXZlLW1pbkV4Y2x1c2l2ZTogXHU3MEJBXHU3NkY4XHU1NDBDXHU4Q0M3XHU2NTk5XHU5ODVFXHU1NzhCXHU1NDBDXHU2NjQyXHU2MzA3XHU1QjlBIG1pbkluY2x1c2l2ZSBcdTgyMDcgbWluRXhjbHVzaXZlIFx1NjYyRlx1NEUwMFx1OTgwNVx1OTMyRlx1OEFBNFx1MzAwMlx1NTcyOCB7Mn0gbWluSW5jbHVzaXZlIFx1N0I0OVx1NjVCQyAnJ3swfScnIFx1NEUxNCBtaW5FeGNsdXNpdmUgXHU3QjQ5XHU2NUJDICcnezF9JydcdTMwMDIKLSAgICAgICAgbWluSW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjEgPSBtaW5JbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMTogXHU5ODVFXHU1NzhCICcnezJ9JycgXHU3Njg0XHU5MzJGXHU4QUE0XHUzMDAyXHU3QjQ5XHU2NUJDICcnezB9JycgXHU3Njg0IG1pbkluY2x1c2l2ZSBcdTUwM0NcdTVGQzVcdTk4MDhcdTU5MjdcdTY1QkNcdTYyMTZcdTdCNDlcdTY1QkNcdTU3RkFcdTc5MEVcdTk4NUVcdTU3OEIgJyd7MX0nJyBcdTc2ODQgbWluSW5jbHVzaXZlXHUzMDAyCi0gICAgICAgIG1pbkluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4yID0gbWluSW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjI6IFx1OTg1RVx1NTc4QiAnJ3syfScnIFx1NzY4NFx1OTMyRlx1OEFBNFx1MzAwMlx1N0I0OVx1NjVCQyAnJ3swfScnIFx1NzY4NCBtaW5JbmNsdXNpdmUgXHU1MDNDXHU1RkM1XHU5ODA4XHU1QzBGXHU2NUJDXHU2MjE2XHU3QjQ5XHU2NUJDXHU1N0ZBXHU3OTBFXHU5ODVFXHU1NzhCICcnezF9JycgXHU3Njg0IG1heEluY2x1c2l2ZVx1MzAwMgotICAgICAgICBtaW5JbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uMyA9IG1pbkluY2x1c2l2ZS12YWxpZC1yZXN0cmljdGlvbi4zOiBcdTk4NUVcdTU3OEIgJyd7Mn0nJyBcdTc2ODRcdTkzMkZcdThBQTRcdTMwMDJcdTdCNDlcdTY1QkMgJyd7MH0nJyBcdTc2ODQgbWluSW5jbHVzaXZlIFx1NTAzQ1x1NUZDNVx1OTgwOFx1NTkyN1x1NjVCQ1x1NTdGQVx1NzkwRVx1OTg1RVx1NTc4QiAnJ3sxfScnIFx1NzY4NCBtaW5FeGNsdXNpdmVcdTMwMDIKLSAgICAgICAgbWluSW5jbHVzaXZlLXZhbGlkLXJlc3RyaWN0aW9uLjQgPSBtaW5JbmNsdXNpdmUtdmFsaWQtcmVzdHJpY3Rpb24uNDogXHU5ODVFXHU1NzhCICcnezJ9JycgXHU3Njg0XHU5MzJGXHU4QUE0XHUzMDAyXHU3QjQ5XHU2NUJDICcnezB9JycgXHU3Njg0IG1pbkluY2x1c2l2ZSBcdTUwM0NcdTVGQzVcdTk4MDhcdTVDMEZcdTY1QkNcdTU3RkFcdTc5MEVcdTk4NUVcdTU3OEIgJyd7MX0nJyBcdTc2ODQgbWF4RXhjbHVzaXZlXHUzMDAyCi0gICAgICAgIG1pbkxlbmd0aC1sZXNzLXRoYW4tZXF1YWwtdG8tbWF4TGVuZ3RoID0gbWluTGVuZ3RoLWxlc3MtdGhhbi1lcXVhbC10by1tYXhMZW5ndGg6IFx1NTcyOCB7Mn0gXHU3Njg0XHU1QjlBXHU3RkE5XHU0RTJEXHVGRjBDXHU3QjQ5XHU2NUJDICcnezB9JycgXHU3Njg0IG1pbkxlbmd0aCBcdTUwM0NcdTVGQzVcdTk4MDhcdTVDMEZcdTY1QkMgbWF4TGVuZ3RoIFx1NTAzQyAoXHU3QjQ5XHU2NUJDICcnezF9JycpXHUzMDAyCi0gICAgICAgIG1pbkxlbmd0aC12YWxpZC1yZXN0cmljdGlvbiA9IG1pbkxlbmd0aC12YWxpZC1yZXN0cmljdGlvbjogXHU1NzI4IHsyfSBcdTc2ODRcdTVCOUFcdTdGQTlcdTRFMkRcdUZGMENcdTdCNDlcdTY1QkMgJyd7MH0nJyBcdTc2ODQgbWluTGVuZ3RoIFx1NUZDNVx1OTgwOFx1NTkyN1x1NjVCQ1x1NjIxNlx1N0I0OVx1NjVCQ1x1NTdGQVx1NzkwRVx1OTg1RVx1NTc4QiAnJ3sxfScnIFx1NzY4NCBtaW5MZW5ndGhcdTMwMDIKLSAgICAgICAgbm8teG1sbnMgPSBuby14bWxuczogXHU1QzZDXHU2MDI3XHU1QkEzXHU1NDRBXHU3Njg0IHtuYW1lfSBcdTRFMERcdTgwRkRcdTgyMDcgJ3htbG5zJyBcdTc2RjhcdTU0MENcdTMwMDIKLSAgICAgICAgbm8teHNpID0gbm8teHNpOiBcdTVDNkNcdTYwMjdcdTVCQTNcdTU0NEFcdTc2ODQgJ3sndGFyZ2V0IG5hbWVzcGFjZSd9JyBcdTRFMERcdTgwRkRcdTgyMDcgJyd7MH0nJyBcdTc2RjhcdTU0MENcdTMwMDIKLSAgICAgICAgcC1wcm9wcy1jb3JyZWN0LjIuMSA9IHAtcHJvcHMtY29ycmVjdC4yLjE6IFx1NTcyOCAnJ3swfScnIFx1NzY4NFx1NUJBM1x1NTQ0QVx1NEUyRFx1RkYwQycnbWluT2NjdXJzJycgXHU3Njg0XHU1MDNDXHU3MEJBICcnezF9JydcdUZGMENcdTRGNDZcdTY2MkZcdTVCODNcdTRFMERcdTUzRUZcdTU5MjdcdTY1QkMgJydtYXhPY2N1cnMnJyBcdTc2ODRcdTUwM0MgJyd7Mn0nJ1x1MzAwMgotICAgICAgICByY2FzZS1NYXBBbmRTdW0uMSA9IHJjYXNlLU1hcEFuZFN1bS4xOiBcdTcyNjlcdTRFRjZcdTRFNEJcdTk1OTNcdTZDOTJcdTY3MDlcdTVCOENcdTY1NzRcdTc2ODRcdTUyOUZcdTgwRkRcdTVDMERcdTYxQzlcdTMwMDIKLSAgICAgICAgcmNhc2UtTWFwQW5kU3VtLjIgPSByY2FzZS1NYXBBbmRTdW0uMjogXHU3RkE0XHU3RDQ0XHU3Njg0XHU3NjdDXHU3NTFGXHU3QkM0XHU1NzBEICh7MH1cdUZGMEN7MX0pIFx1NEUwRFx1NjYyRlx1NTdGQVx1NzkwRVx1N0ZBNFx1N0Q0NFx1NzY3Q1x1NzUxRlx1N0JDNFx1NTcwRCAoezJ9XHVGRjBDezN9KSBcdTc2ODRcdTY3MDlcdTY1NDhcdTk2NTBcdTUyMzZcdTMwMDIKLSAgICAgICAgcmNhc2UtTmFtZUFuZFR5cGVPSy4xID0gcmNhc2UtTmFtZUFuZFR5cGVPSy4xOiBcdTUxNDNcdTdEMjBcdTUxNzdcdTY3MDlcdTRFMERcdTc2RjhcdTU0MENcdTc2ODRcdTU0MERcdTdBMzFcdTgyMDdcdTc2RUVcdTZBMTlcdTU0N0RcdTU0MERcdTdBN0FcdTk1OTM6IFx1NTQ3RFx1NTQwRFx1N0E3QVx1OTU5MyAnJ3sxfScnIFx1NEUyRFx1NzY4NFx1NTE0M1x1N0QyMCAnJ3swfScnIFx1ODIwN1x1NTQ3RFx1NTQwRFx1N0E3QVx1OTU5MyAnJ3szfScnIFx1NEUyRFx1NzY4NFx1NTE0M1x1N0QyMCAnJ3syfScnXHUzMDAyCi0gICAgICAgIHJjYXNlLU5hbWVBbmRUeXBlT0suMiA9IHJjYXNlLU5hbWVBbmRUeXBlT0suMjogXHU3MjY5XHU0RUY2XHU3Njg0ICd7J3Rlcm0nfScgXHU3MEJBXHU1MTQzXHU3RDIwXHU1QkEzXHU1NDRBICcnezB9JycgXHU3Njg0XHU5MzJGXHU4QUE0XHUzMDAyXHU1MTQzXHU3RDIwXHU1QkEzXHU1NDRBXHU3Njg0ICd7J25pbGxhYmxlJ30nIFx1NzBCQVx1NzcxRlx1RkYwQ1x1NEY0Nlx1NjYyRlx1NTdGQVx1NzkwRVx1OTg1RVx1NTc4Qlx1NEUyRFx1NzY4NFx1NUMwRFx1NjFDOVx1NzI2OVx1NEVGNlx1NTE3N1x1NjcwOSAneyduaWxsYWJsZSd9JyBcdTcwQkFcdTUwN0RcdTc2ODRcdTUxNDNcdTdEMjBcdTVCQTNcdTU0NEFcdTMwMDIKLSAgICAgICAgcmNhc2UtTmFtZUFuZFR5cGVPSy4zID0gcmNhc2UtTmFtZUFuZFR5cGVPSy4zOiBcdTcyNjlcdTRFRjZcdTc2ODQgJ3sndGVybSd9JyBcdTcwQkFcdTUxNDNcdTdEMjBcdTVCQTNcdTU0NEEgJyd7MH0nJyBcdTc2ODRcdTkzMkZcdThBQTRcdTMwMDJcdTVCODNcdTc2ODRcdTc2N0NcdTc1MUZcdTdCQzRcdTU3MEQgKHsxfVx1RkYwQ3syfSkgXHU0RTBEXHU2NjJGXHU1N0ZBXHU3OTBFXHU5ODVFXHU1NzhCXHU0RTJEXHU1QzBEXHU2MUM5XHU3MjY5XHU0RUY2XHU3QkM0XHU1NzBEICh7M31cdUZGMEN7NH0pIFx1NzY4NFx1NjcwOVx1NjU0OFx1OTY1MFx1NTIzNlx1MzAwMgotICAgICAgICByY2FzZS1OYW1lQW5kVHlwZU9LLjQuYSA9IHJjYXNlLU5hbWVBbmRUeXBlT0suNC5hOiBcdTUxNDNcdTdEMjAgJyd7MH0nJyBcdTk3NUVcdTU2RkFcdTVCOUFcdTVGMEZcdUZGMENcdTRGNDZcdTY2MkZcdTU3RkFcdTc5MEVcdTk4NUVcdTU3OEJcdTRFMkRcdTVDMERcdTYxQzlcdTc2ODRcdTUxNDNcdTdEMjBcdTUxNzdcdTY3MDlcdTU2RkFcdTVCOUFcdTUwM0MgJyd7MX0nJ1x1MzAwMgotICAgICAgICByY2FzZS1OYW1lQW5kVHlwZU9LLjQuYiA9IHJjYXNlLU5hbWVBbmRUeXBlT0suNC5iOiBcdTUxNDNcdTdEMjAgJyd7MH0nJyBcdTUxNzdcdTY3MDlcdTU2RkFcdTVCOUFcdTUwM0MgJyd7MX0nJ1x1RkYwQ1x1NEY0Nlx1NjYyRlx1NTdGQVx1NzkwRVx1OTg1RVx1NTc4Qlx1NEUyRFx1NUMwRFx1NjFDOVx1NzY4NFx1NTE0M1x1N0QyMFx1NTE3N1x1NjcwOVx1NTZGQVx1NUI5QVx1NTAzQyAnJ3syfScnXHUzMDAyCi0gICAgICAgIHJjYXNlLU5hbWVBbmRUeXBlT0suNSA9IHJjYXNlLU5hbWVBbmRUeXBlT0suNTogXHU1MTQzXHU3RDIwICcnezB9JycgXHU3Njg0XHU4QjU4XHU1MjI1XHU5NjUwXHU1MjM2XHU2ODlEXHU0RUY2XHU0RTBEXHU2NjJGXHU1N0ZBXHU3OTBFXHU0RTJEXHU3Njg0XHU1QjUwXHU5NkM2XHUzMDAyCi0gICAgICAgIHJjYXNlLU5hbWVBbmRUeXBlT0suNiA9IHJjYXNlLU5hbWVBbmRUeXBlT0suNjogXHU1MTQzXHU3RDIwICcnezB9JycgXHU0RTBEXHU1MTQxXHU4QTMxXHU3Njg0XHU2NkZGXHU0RUUzXHU0RTBEXHU2NjJGXHU1N0ZBXHU3OTBFXHU0RTJEXHU3Njg0XHU4RDg1XHU5NkM2XHUzMDAyCi0gICAgICAgIHJjYXNlLU5hbWVBbmRUeXBlT0suNyA9IHJjYXNlLU5hbWVBbmRUeXBlT0suNzogXHU1MTQzXHU3RDIwICcnezB9JycgXHU3Njg0XHU5ODVFXHU1NzhCICcnezF9JycgXHU0RTBEXHU2NjJGXHU4ODREXHU3NTFGXHU4MUVBXHU1N0ZBXHU3OTBFXHU1MTQzXHU3RDIwICcnezJ9JycgXHU3Njg0XHU5ODVFXHU1NzhCXHUzMDAyCi0gICAgICAgIHJjYXNlLU5TQ29tcGF0LjEgPSByY2FzZS1OU0NvbXBhdC4xOiBcdTUxNDNcdTdEMjAgJyd7MH0nJyBcdTUxNzdcdTY3MDlcdTU3RkFcdTc5MEVcdTRFMkRcdTg0MkNcdTc1MjhcdTVCNTdcdTUxNDNcdTRFMERcdTUxNDFcdThBMzFcdTc2ODRcdTU0N0RcdTU0MERcdTdBN0FcdTk1OTMgJyd7MX0nJ1x1MzAwMgotICAgICAgICByY2FzZS1OU0NvbXBhdC4yID0gcmNhc2UtTlNDb21wYXQuMjogXHU3MjY5XHU0RUY2XHU3Njg0ICd7J3Rlcm0nfScgXHU3MEJBXHU1MTQzXHU3RDIwXHU1QkEzXHU1NDRBICcnezB9JycgXHU3Njg0XHU5MzJGXHU4QUE0XHUzMDAyXHU1QjgzXHU3Njg0XHU3NjdDXHU3NTFGXHU3QkM0XHU1NzBEICh7MX1cdUZGMEN7Mn0pIFx1NEUwRFx1NjYyRlx1NTdGQVx1NzkwRVx1OTg1RVx1NTc4Qlx1NEUyRFx1NUMwRFx1NjFDOVx1NzI2OVx1NEVGNlx1N0JDNFx1NTcwRCAoezN9XHVGRjBDezR9KSBcdTc2ODRcdTY3MDlcdTY1NDhcdTk2NTBcdTUyMzZcdTMwMDIKLSAgICAgICAgcmNhc2UtTlNSZWN1cnNlQ2hlY2tDYXJkaW5hbGl0eS4xID0gcmNhc2UtTlNSZWN1cnNlQ2hlY2tDYXJkaW5hbGl0eS4xOiBcdTcyNjlcdTRFRjZcdTRFNEJcdTk1OTNcdTZDOTJcdTY3MDlcdTVCOENcdTY1NzRcdTc2ODRcdTUyOUZcdTgwRkRcdTVDMERcdTYxQzlcdTMwMDIKLSAgICAgICAgcmNhc2UtTlNSZWN1cnNlQ2hlY2tDYXJkaW5hbGl0eS4yID0gcmNhc2UtTlNSZWN1cnNlQ2hlY2tDYXJkaW5hbGl0eS4yOiBcdTdGQTRcdTdENDRcdTc2ODRcdTc2N0NcdTc1MUZcdTdCQzRcdTU3MEQgKHswfVx1RkYwQ3sxfSkgXHU0RTBEXHU2NjJGXHU1N0ZBXHU3OTBFXHU4NDJDXHU3NTI4XHU1QjU3XHU1MTQzXHU3QkM0XHU1NzBEICh7Mn1cdUZGMEN7M30pIFx1NzY4NFx1NjcwOVx1NjU0OFx1OTY1MFx1NTIzNlx1MzAwMgotICAgICAgICByY2FzZS1OU1N1YnNldC4xID0gcmNhc2UtTlNTdWJzZXQuMTogXHU4NDJDXHU3NTI4XHU1QjU3XHU1MTQzXHU0RTBEXHU2NjJGXHU1N0ZBXHU3OTBFXHU0RTJEXHU1QzBEXHU2MUM5XHU4NDJDXHU3NTI4XHU1QjU3XHU1MTQzXHU3Njg0XHU1QjUwXHU5NkM2XHUzMDAyCi0gICAgICAgIHJjYXNlLU5TU3Vic2V0LjIgPSByY2FzZS1OU1N1YnNldC4yOiBcdTg0MkNcdTc1MjhcdTVCNTdcdTUxNDNcdTc2ODRcdTc2N0NcdTc1MUZcdTdCQzRcdTU3MEQgKHswfVx1RkYwQ3sxfSkgXHU0RTBEXHU2NjJGXHU1N0ZBXHU3OTBFXHU4NDJDXHU3NTI4XHU1QjU3XHU1MTQzXHU3QkM0XHU1NzBEICh7Mn1cdUZGMEN7M30pIFx1NzY4NFx1NjcwOVx1NjU0OFx1OTY1MFx1NTIzNlx1MzAwMgotICAgICAgICByY2FzZS1OU1N1YnNldC4zID0gcmNhc2UtTlNTdWJzZXQuMzogXHU4NDJDXHU3NTI4XHU1QjU3XHU1MTQzXHU3Njg0XHU4NjU1XHU3NDA2XHU0RjVDXHU2OTZEXHU1MTY3XHU1QkI5ICcnezB9JycgXHU2QkQ0XHU1N0ZBXHU3OTBFICcnezF9JycgXHU0RTJEXHU3Njg0XHU4NjU1XHU3NDA2XHU0RjVDXHU2OTZEXHU1MTY3XHU1QkI5XHU1RjMxXHUzMDAyCi0gICAgICAgIHJjYXNlLVJlY3Vyc2UuMSA9IHJjYXNlLVJlY3Vyc2UuMTogXHU3RkE0XHU3RDQ0XHU3Njg0XHU3NjdDXHU3NTFGXHU3QkM0XHU1NzBEICh7MH1cdUZGMEN7MX0pIFx1NEUwRFx1NjYyRlx1NTdGQVx1NzkwRVx1N0ZBNFx1N0Q0NFx1NzY3Q1x1NzUxRlx1N0JDNFx1NTcwRCAoezJ9XHVGRjBDezN9KSBcdTc2ODRcdTY3MDlcdTY1NDhcdTk2NTBcdTUyMzZcdTMwMDIKLSAgICAgICAgcmNhc2UtUmVjdXJzZS4yID0gcmNhc2UtUmVjdXJzZS4yOiBcdTcyNjlcdTRFRjZcdTRFNEJcdTk1OTNcdTZDOTJcdTY3MDlcdTVCOENcdTY1NzRcdTc2ODRcdTUyOUZcdTgwRkRcdTVDMERcdTYxQzlcdTMwMDIKLSAgICAgICAgcmNhc2UtUmVjdXJzZUxheC4xID0gcmNhc2UtUmVjdXJzZUxheC4xOiBcdTdGQTRcdTdENDRcdTc2ODRcdTc2N0NcdTc1MUZcdTdCQzRcdTU3MEQgKHswfVx1RkYwQ3sxfSkgXHU0RTBEXHU2NjJGXHU1N0ZBXHU3OTBFXHU3RkE0XHU3RDQ0XHU3NjdDXHU3NTFGXHU3QkM0XHU1NzBEICh7Mn1cdUZGMEN7M30pIFx1NzY4NFx1NjcwOVx1NjU0OFx1OTY1MFx1NTIzNlx1MzAwMgotICAgICAgICByY2FzZS1SZWN1cnNlTGF4LjIgPSByY2FzZS1SZWN1cnNlTGF4LjI6IFx1NzI2OVx1NEVGNlx1NEU0Qlx1OTU5M1x1NkM5Mlx1NjcwOVx1NUI4Q1x1NjU3NFx1NzY4NFx1NTI5Rlx1ODBGRFx1NUMwRFx1NjFDOVx1MzAwMgotICAgICAgICByY2FzZS1SZWN1cnNlVW5vcmRlcmVkLjEgPSByY2FzZS1SZWN1cnNlVW5vcmRlcmVkLjE6IFx1N0ZBNFx1N0Q0NFx1NzY4NFx1NzY3Q1x1NzUxRlx1N0JDNFx1NTcwRCAoezB9XHVGRjBDezF9KSBcdTRFMERcdTY2MkZcdTU3RkFcdTc5MEVcdTdGQTRcdTdENDRcdTc2N0NcdTc1MUZcdTdCQzRcdTU3MEQgKHsyfVx1RkYwQ3szfSkgXHU3Njg0XHU2NzA5XHU2NTQ4XHU5NjUwXHU1MjM2XHUzMDAyCi0gICAgICAgIHJjYXNlLVJlY3Vyc2VVbm9yZGVyZWQuMiA9IHJjYXNlLVJlY3Vyc2VVbm9yZGVyZWQuMjogXHU3MjY5XHU0RUY2XHU0RTRCXHU5NTkzXHU2QzkyXHU2NzA5XHU1QjhDXHU2NTc0XHU3Njg0XHU1MjlGXHU4MEZEXHU1QzBEXHU2MUM5XHUzMDAyCi0jICAgICAgICBXZSdyZSB1c2luZyBzY2gtcHJvcHMtY29ycmVjdC4yIGluc3RlYWQgb2YgdGhlIG9sZCBzcmMtcmVkZWZpbmUuMQotIyAgICAgICAgc3JjLXJlZGVmaW5lLjEgPSBzcmMtcmVkZWZpbmUuMTogVGhlIGNvbXBvbmVudCAnJ3swfScnIGlzIGJlZ2luIHJlZGVmaW5lZCwgYnV0IGl0cyBjb3JyZXNwb25kaW5nIGNvbXBvbmVudCBpc24ndCBpbiB0aGUgc2NoZW1hIGRvY3VtZW50IGJlaW5nIHJlZGVmaW5lZCAod2l0aCBuYW1lc3BhY2UgJyd7Mn0nJyksIGJ1dCBpbiBhIGRpZmZlcmVudCBkb2N1bWVudCwgd2l0aCBuYW1lc3BhY2UgJyd7MX0nJy4KLSAgICAgICAgc2NoLXByb3BzLWNvcnJlY3QuMiA9IHNjaC1wcm9wcy1jb3JyZWN0LjI6IFx1N0RCMVx1ODk4MVx1NzEyMVx1NkNENVx1NTMwNVx1NTQyQlx1NzZGOFx1NTQwQ1x1NTQwRFx1N0EzMVx1NzY4NFx1NTE2OVx1NTAwQlx1NTE2OFx1NTdERlx1NTE0M1x1NEVGNjsgXHU2QjY0XHU3REIxXHU4OTgxXHU1MzA1XHU1NDJCXHU1MTY5XHU1MDBCICcnezB9JydcdTMwMDIKLSAgICAgICAgc3QtcHJvcHMtY29ycmVjdC4yID0gc3QtcHJvcHMtY29ycmVjdC4yOiBcdTUwNzVcdTZFMkNcdTUyMzBcdTdDMjFcdTU1QUVcdTk4NUVcdTU3OEIgJyd7MH0nJyBcdTc2ODRcdTVGQUFcdTc0QjBcdTVCOUFcdTdGQTlcdTMwMDJcdTkwMTlcdTRFRTNcdTg4NjggJyd7MH0nJyBcdTUzMDVcdTU0MkJcdTU3MjhcdTgxRUFcdThFQUJcdTk4NUVcdTU3OEJcdTk2OEVcdTVDNjRcdTRFMkRcdUZGMENcdTkwMTlcdTY2MkZcdTRFMDBcdTk4MDVcdTkzMkZcdThBQTRcdTMwMDIKLSAgICAgICAgc3QtcHJvcHMtY29ycmVjdC4zID0gc3QtcHJvcHMtY29ycmVjdC4zOiBcdTk4NUVcdTU3OEIgJyd7MH0nJyBcdTc2ODRcdTkzMkZcdThBQTRcdTMwMDIneydiYXNlIHR5cGUgZGVmaW5pdGlvbid9JyBcdTc2ODQgJ3snZmluYWwnfScgXHU1MDNDICcnezF9JycgXHU5NjUwXHU1MjM2XHU3OTgxXHU2QjYyXHU4ODREXHU3NTFGXHUzMDAyCi0gICAgICAgIHRvdGFsRGlnaXRzLXZhbGlkLXJlc3RyaWN0aW9uID0gdG90YWxEaWdpdHMtdmFsaWQtcmVzdHJpY3Rpb246IFx1NTcyOCB7Mn0gXHU3Njg0XHU1QjlBXHU3RkE5XHU0RTJEXHVGRjBDZmFjZXQgJyd0b3RhbERpZ2l0cycnIFx1NzY4NFx1NTAzQyAnJ3swfScnIFx1NzEyMVx1NjU0OFx1RkYwQ1x1NTZFMFx1NzBCQVx1NUI4M1x1NUZDNVx1OTgwOFx1NUMwRlx1NjVCQ1x1NjIxNlx1N0I0OVx1NjVCQyAnJ3RvdGFsRGlnaXRzJycgXHU3Njg0XHU1MDNDXHVGRjBDXHU2QjY0XHU1MDNDXHU0RUU1XHU1MTc2XHU0RTJEXHU0RTAwXHU1MDBCXHU3OTU2XHU3Q0ZCXHU5ODVFXHU1NzhCXHU4QTJEXHU3MEJBICcnezF9JydcdTMwMDIKLSAgICAgICAgd2hpdGVTcGFjZS12YWxpZC1yZXN0cmljdGlvbi4xID0gd2hpdGVTcGFjZS12YWxpZC1yZXN0cmljdGlvbi4xOiBcdTU3MjggezB9IFx1NzY4NFx1NUI5QVx1N0ZBOVx1NEUyRFx1RkYwQ2ZhY2V0ICcnd2hpdGVzcGFjZScnIFx1NzY4NFx1NTAzQyAnJ3sxfScnIFx1NzEyMVx1NjU0OFx1RkYwQ1x1NTZFMFx1NzBCQSAnJ3doaXRlc3BhY2UnJyBcdTc2ODRcdTUwM0NcdTRFRTVcdTUxNzZcdTRFMkRcdTRFMDBcdTUwMEJcdTc5NTZcdTdDRkJcdTk4NUVcdTU3OEJcdThBMkRcdTcwQkEgJydjb2xsYXBzZScnXHUzMDAyCi0gICAgICAgIHdoaXRlU3BhY2UtdmFsaWQtcmVzdHJpY3Rpb24uMiA9IHdoaXRlU3BhY2UtdmFsaWQtcmVzdHJpY3Rpb24uMjogXHU1NzI4IHswfSBcdTc2ODRcdTVCOUFcdTdGQTlcdTRFMkRcdUZGMENmYWNldCAnJ3doaXRlc3BhY2UnJyBcdTc2ODRcdTUwM0MgJydwcmVzZXJ2ZScnIFx1NzEyMVx1NjU0OFx1RkYwQ1x1NTZFMFx1NzBCQSAnJ3doaXRlc3BhY2UnJyBcdTc2ODRcdTUwM0NcdTU3MjhcdTUxNzZcdTRFMkRcdTRFMDBcdTUwMEJcdTc5NTZcdTdDRkJcdTk4NUVcdTU3OEJcdTRFMkRcdThBMkRcdTcwQkEgJydyZXBsYWNlJydcdTMwMDIKLQotI3NjaGVtYSBmb3IgU2NoZW1hcwotCi0gICAgICAgIHM0cy1hdHQtaW52YWxpZC12YWx1ZSA9IHM0cy1hdHQtaW52YWxpZC12YWx1ZTogXHU1MTQzXHU3RDIwICcnezB9JycgXHU0RTJEICcnezF9JycgXHU3Njg0XHU1QzZDXHU2MDI3XHU1MDNDXHU3MTIxXHU2NTQ4XHUzMDAyXHU4QTE4XHU5MzA0XHU3Njg0XHU1MzlGXHU1NkUwOiB7Mn0KLSAgICAgICAgczRzLWF0dC1tdXN0LWFwcGVhciA9IHM0cy1hdHQtbXVzdC1hcHBlYXI6IFx1NUM2Q1x1NjAyNyAnJ3sxfScnIFx1NUZDNVx1OTgwOFx1NTFGQVx1NzNGRVx1NTcyOFx1NTE0M1x1N0QyMCAnJ3swfScnIFx1NEUyRFx1MzAwMgotICAgICAgICBzNHMtYXR0LW5vdC1hbGxvd2VkID0gczRzLWF0dC1ub3QtYWxsb3dlZDogXHU1QzZDXHU2MDI3ICcnezF9JycgXHU0RTBEXHU1M0VGXHU1MUZBXHU3M0ZFXHU1NzI4XHU1MTQzXHU3RDIwICcnezB9JycgXHU0RTJEXHUzMDAyCi0gICAgICAgIHM0cy1lbHQtaW52YWxpZCA9IHM0cy1lbHQtaW52YWxpZDogXHU1MTQzXHU3RDIwICcnezB9JycgXHU0RTBEXHU2NjJGXHU3REIxXHU4OTgxXHU2NTg3XHU0RUY2XHU0RTJEXHU3Njg0XHU2NzA5XHU2NTQ4XHU1MTQzXHU3RDIwXHUzMDAyCi0gICAgICAgIHM0cy1lbHQtbXVzdC1tYXRjaC4xID0gczRzLWVsdC1tdXN0LW1hdGNoLjE6ICcnezB9JycgXHU3Njg0XHU1MTY3XHU1QkI5XHU1RkM1XHU5ODA4XHU3QjI2XHU1NDA4IHsxfVx1MzAwMlx1NUY5RSB7Mn0gXHU5NThCXHU1OUNCXHU1MUZBXHU3M0ZFXHU1NTRGXHU5ODRDXHUzMDAyCi0gICAgICAgIHM0cy1lbHQtbXVzdC1tYXRjaC4yID0gczRzLWVsdC1tdXN0LW1hdGNoLjI6ICcnezB9JycgXHU3Njg0XHU1MTY3XHU1QkI5XHU1RkM1XHU5ODA4XHU3QjI2XHU1NDA4IHsxfVx1MzAwMlx1NjI3RVx1NEUwRFx1NTIzMFx1OERCM1x1NTkyMFx1NzY4NFx1NTE0M1x1N0QyMFx1MzAwMgotICAgICAgICAjIHRoZSAiaW52YWxpZC1jb250ZW50IiBtZXNzYWdlcyBwcm92aWRlIGxlc3MgaW5mb3JtYXRpb24gdGhhbiB0aGUgIm11c3QtbWF0Y2giIGNvdW50ZXJwYXJ0cyBhYm92ZS4gVGhleSdyZSB1c2VkIGZvciBjb21wbGV4IHR5cGVzIHdoZW4gcHJvdmlkaW5nIGEgIm1hdGNoIiB3b3VsZCBiZSBhbiBpbmZvcm1hdGlvbiBkdW1wCi0gICAgICAgIHM0cy1lbHQtaW52YWxpZC1jb250ZW50LjEgPSBzNHMtZWx0LWludmFsaWQtY29udGVudC4xOiAnJ3swfScnIFx1NzY4NFx1NTE2N1x1NUJCOVx1NzEyMVx1NjU0OFx1MzAwMlx1NTE0M1x1N0QyMCAnJ3sxfScnIFx1NzEyMVx1NjU0OFx1MzAwMVx1NEY0RFx1N0Y2RVx1OTMyRlx1OEFBNFx1NjIxNlx1NTkyQVx1NUUzOFx1NTFGQVx1NzNGRVx1MzAwMgotICAgICAgICBzNHMtZWx0LWludmFsaWQtY29udGVudC4yID0gczRzLWVsdC1pbnZhbGlkLWNvbnRlbnQuMjogJyd7MH0nJyBcdTc2ODRcdTUxNjdcdTVCQjlcdTcxMjFcdTY1NDhcdTMwMDJcdTUxNDNcdTdEMjAgJyd7MX0nJyBcdTRFMERcdTUzRUZcdTdBN0FcdTc2N0RcdTMwMDIKLSAgICAgICAgczRzLWVsdC1pbnZhbGlkLWNvbnRlbnQuMyA9IHM0cy1lbHQtaW52YWxpZC1jb250ZW50LjM6IFx1OTg1RVx1NTc4QiAnJ3swfScnIFx1NzY4NFx1NTE0M1x1N0QyMFx1NEUwRFx1NTNFRlx1NTFGQVx1NzNGRVx1NTcyOFx1NUJBM1x1NTQ0QVx1NEU0Qlx1NUY4Q1x1RkYwQ1x1NEY1Q1x1NzBCQSA8c2NoZW1hPiBcdTUxNDNcdTdEMjBcdTc2ODRcdTVCNTBcdTk4MDVcdTMwMDIKLSAgICAgICAgczRzLWVsdC1zY2hlbWEtbnMgPSBzNHMtZWx0LXNjaGVtYS1uczogXHU1MTQzXHU3RDIwICcnezB9JycgXHU3Njg0XHU1NDdEXHU1NDBEXHU3QTdBXHU5NTkzXHU1RkM1XHU5ODA4XHU0Rjg2XHU4MUVBXHU3REIxXHU4OTgxXHU1NDdEXHU1NDBEXHU3QTdBXHU5NTkzICcnaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEnJ1x1MzAwMgotICAgICAgICBzNHMtZWx0LWNoYXJhY3RlciA9IHM0cy1lbHQtY2hhcmFjdGVyOiBcdTdEQjFcdTg5ODFcdTUxNDNcdTdEMjBcdTRFMkRcdTRFMERcdTUxNDFcdThBMzFcdTk3NUVcdTdBN0FcdTc2N0RcdTVCNTdcdTUxNDNcdUZGMENcdTRGNDZcdTY2MkYgJyd4czphcHBpbmZvJycgXHU4MjA3ICcneHM6ZG9jdW1lbnRhdGlvbicnIFx1OTY2NFx1NTkxNlx1MzAwMlx1NzY3Q1x1NzNGRSAnJ3swfScnXHUzMDAyCi0KLSMgY29kZXMgbm90IGRlZmluZWQgYnkgdGhlIHNwZWMKLQotICAgICAgICBjLWZpZWxkcy14cGF0aHMgPSBjLWZpZWxkcy14cGF0aHM6IFx1N0I0OVx1NjVCQyAnJ3swfScnIFx1NzY4NFx1NkIwNFx1NEY0RFx1NTAzQ1x1NzEyMVx1NjU0OFx1MzAwMgotICAgICAgICBjLWdlbmVyYWwteHBhdGggPSBjLWdlbmVyYWwteHBhdGg6IFx1ODg2OFx1NzkzQVx1NUYwRiAnJ3swfScnIFx1NUMwRFx1NjVCQyBYTUwgXHU3REIxXHU4OTgxXHU2NTJGXHU2M0Y0XHU3Njg0IFhQYXRoIFx1NUI1MFx1OTZDNlx1ODAwQ1x1OEEwMFx1NzEyMVx1NjU0OFx1MzAwMgotICAgICAgICBjLWdlbmVyYWwteHBhdGgtbnMgPSBjLWdlbmVyYWwteHBhdGgtbnM6IFhQYXRoIFx1ODg2OFx1NzkzQVx1NUYwRiAnJ3swfScnIFx1NEUyRFx1NzY4NFx1NTQ3RFx1NTQwRFx1N0E3QVx1OTU5M1x1NTI0RFx1N0Y2RVx1NzhCQ1x1NjcyQVx1OTAyM1x1N0Q1MFx1NTQ3RFx1NTQwRFx1N0E3QVx1OTU5M1x1MzAwMgotICAgICAgICBjLXNlbGVjdG9yLXhwYXRoID0gYy1zZWxlY3Rvci14cGF0aDogXHU3QjQ5XHU2NUJDICcnezB9JycgXHU3Njg0XHU5MDc4XHU1M0Q2XHU1NjY4XHU1MDNDXHU3MTIxXHU2NTQ4OyBcdTkwNzhcdTUzRDZcdTU2NjggeHBhdGhzIFx1NEUwRFx1ODBGRFx1NTMwNVx1NTQyQlx1NUM2Q1x1NjAyN1x1MzAwMgotICAgICAgICBFbXB0eVRhcmdldE5hbWVzcGFjZSA9IEVtcHR5VGFyZ2V0TmFtZXNwYWNlOiBcdTU3MjhcdTdEQjFcdTg5ODFcdTY1ODdcdTRFRjYgJyd7MH0nJyBcdTRFMkRcdUZGMEMnJ3RhcmdldE5hbWVzcGFjZScnIFx1NUM2Q1x1NjAyN1x1NzY4NFx1NTAzQ1x1NEUwRFx1NTNFRlx1NzBCQVx1N0E3QVx1NzY3RFx1NUI1N1x1NEUzMlx1MzAwMgotICAgICAgICBGYWNldFZhbHVlRnJvbUJhc2UgPSBGYWNldFZhbHVlRnJvbUJhc2U6IFx1NTcyOFx1OTg1RVx1NTc4QiAnJ3swfScnIFx1NzY4NFx1NUJBM1x1NTQ0QVx1NEUyRFx1RkYwQ2ZhY2V0ICcnezJ9JycgXHU3Njg0XHU1MDNDICcnezF9JycgXHU1RkM1XHU5ODA4XHU0Rjg2XHU4MUVBXHU1N0ZBXHU3OTBFXHU5ODVFXHU1NzhCXHU3Njg0XHU1MDNDXHU3QTdBXHU5NTkzICcnezN9JydcdTMwMDIKLSAgICAgICAgRml4ZWRGYWNldFZhbHVlID0gRml4ZWRGYWNldFZhbHVlOiBcdTU3MjggezN9IFx1NzY4NFx1NUI5QVx1N0ZBOVx1NEUyRFx1RkYwQ2ZhY2V0ICcnezB9JycgXHU3Njg0XHU1MDNDICcnezF9JycgXHU3MTIxXHU2NTQ4XHVGRjBDXHU1NkUwXHU3MEJBICcnezB9JycgXHU3Njg0XHU1MDNDXHU0RUU1XHU1MTc2XHU0RTJEXHU0RTAwXHU1MDBCXHU3OTU2XHU3Q0ZCXHU5ODVFXHU1NzhCXHU4QTJEXHU3MEJBICcnezJ9JydcdUZGMENcdTRFMTQgJ3snZml4ZWQnfScgPSB0cnVlXHUzMDAyCi0gICAgICAgIEludmFsaWRSZWdleCA9IEludmFsaWRSZWdleDogXHU2QTIzXHU1RjBGXHU1MDNDICcnezB9JycgXHU0RTBEXHU2NjJGXHU2NzA5XHU2NTQ4XHU3Njg0XHU2QjYzXHU4OThGXHU4ODY4XHU3OTNBXHU1RjBGXHUzMDAyXHU1ODMxXHU1NDRBXHU3Njg0XHU5MzJGXHU4QUE0OiBcdTRGNERcdTY1QkNcdThDQzdcdTY1OTlcdTZCMDQgJyd7Mn0nJyBcdTc2ODQgJyd7MX0nJ1x1MzAwMgotICAgICAgICBNYXhPY2N1ckxpbWl0ID0gXHU1MjU2XHU2NzkwXHU1NjY4XHU3NkVFXHU1MjREXHU3Njg0XHU3RDQ0XHU2MTRCXHU0RTBEXHU1MTQxXHU4QTMxIG1heE9jY3VycyBcdTVDNkNcdTYwMjdcdTUwM0NcdThBMkRcdTcwQkFcdTU5MjdcdTY1QkNcdTUwM0MgezB9XHUzMDAyCi0gICAgICAgIFB1YmxpY1N5c3RlbU9uTm90YXRpb24gPSBQdWJsaWNTeXN0ZW1Pbk5vdGF0aW9uOiAnJ3B1YmxpYycnIFx1ODIwNyAnJ3N5c3RlbScnIFx1ODFGM1x1NUMxMVx1NTE3Nlx1NEUyRFx1NEU0Qlx1NEUwMFx1NUZDNVx1OTgwOFx1NTFGQVx1NzNGRVx1NTcyOFx1NTE0M1x1N0QyMCAnJ25vdGF0aW9uJycgXHU0RTJEXHUzMDAyCi0gICAgICAgIFNjaGVtYUxvY2F0aW9uID0gXHU3QjQ5XHU2NUJDICcnezB9JycgXHU3Njg0IFNjaGVtYUxvY2F0aW9uOiBzY2hlbWFMb2NhdGlvbiBcdTUwM0NcdTVGQzVcdTk4MDhcdTUxNzdcdTY3MDlcdTUwNzZcdTY1NzhcdTUwMEIgVVJJXHUzMDAyCi0gICAgICAgIFRhcmdldE5hbWVzcGFjZS4xID0gVGFyZ2V0TmFtZXNwYWNlLjE6IFx1OTgxMFx1NjcxRlx1NTQ3RFx1NTQwRFx1N0E3QVx1OTU5MyAnJ3swfScnXHVGRjBDXHU0RjQ2XHU2NjJGXHU3REIxXHU4OTgxXHU2NTg3XHU0RUY2XHU3Njg0XHU3NkVFXHU2QTE5XHU1NDdEXHU1NDBEXHU3QTdBXHU5NTkzXHU3MEJBICcnezF9JydcdTMwMDIKLSAgICAgICAgVGFyZ2V0TmFtZXNwYWNlLjIgPSBUYXJnZXROYW1lc3BhY2UuMjogXHU2NzJBXHU5ODEwXHU2NzFGXHU1NDdEXHU1NDBEXHU3QTdBXHU5NTkzXHVGRjBDXHU0RjQ2XHU2NjJGXHU3REIxXHU4OTgxXHU2NTg3XHU0RUY2XHU1MTc3XHU2NzA5XHU3NkVFXHU2QTE5XHU1NDdEXHU1NDBEXHU3QTdBXHU5NTkzICcnezF9JydcdTMwMDIKLSAgICAgICAgVW5kZWNsYXJlZEVudGl0eSA9IFVuZGVjbGFyZWRFbnRpdHk6IFx1NjcyQVx1NUJBM1x1NTQ0QVx1NUJFNlx1OUFENCAnJ3swfScnXHUzMDAyCi0gICAgICAgIFVuZGVjbGFyZWRQcmVmaXggPSBVbmRlY2xhcmVkUHJlZml4OiBcdTcxMjFcdTZDRDVcdTg5RTNcdTY3OTAgJyd7MH0nJyBcdTcwQkEgUU5hbWU6IFx1NjcyQVx1NUJBM1x1NTQ0QVx1NTI0RFx1N0Y2RVx1NzhCQyAnJ3sxfScnXHUzMDAyCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9YTUxTZXJpYWxpemVyTWVzc2FnZXMucHJvcGVydGllcyBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hNTFNlcmlhbGl6ZXJNZXNzYWdlcy5wcm9wZXJ0aWVzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxMzg3NGVkLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hNTFNlcmlhbGl6ZXJNZXNzYWdlcy5wcm9wZXJ0aWVzCisrKyAvZGV2L251bGwKQEAgLTEsMzIgKzAsMCBAQAotIyBUaGlzIGZpbGUgc3RvcmVzIGVycm9yIG1lc3NhZ2VzIGZvciB0aGUgWGVyY2VzIFhNTAotIyBzZXJpYWxpemVyLiAgTWFueSBET00gTG9hZC9TYXZlIGVycm9yIG1lc3NhZ2VzIGFsc28gCi0jIGxpdmUgaGVyZSwgc2luY2UgdGhlIHNlcmlhbGl6ZXIgbGFyZ2VseSBpbXBsZW1lbnRzIHRoYXQgcGFja2FnZS4KLSMKLSMgQXMgdXN1YWwgd2l0aCBwcm9wZXJ0aWVzIGZpbGVzLCB0aGUgbWVzc2FnZXMgYXJlIGFycmFuZ2VkIGluCi0jIGtleS92YWx1ZSB0dXBsZXMuCi0jIAotCi0gICAgQmFkTWVzc2FnZUtleSA9IFRoZSBlcnJvciBtZXNzYWdlIGNvcnJlc3BvbmRpbmcgdG8gdGhlIG1lc3NhZ2Uga2V5IGNhbiBub3QgYmUgZm91bmQuCi0gICAgRm9ybWF0RmFpbGVkID0gQW4gaW50ZXJuYWwgZXJyb3Igb2NjdXJyZWQgd2hpbGUgZm9ybWF0dGluZyB0aGUgZm9sbG93aW5nIG1lc3NhZ2U6XG4KLQotICAgIEFyZ3VtZW50SXNOdWxsID0gQXJndW1lbnQgJyd7MH0nJyBpcyBudWxsLgotICAgIE5vV3JpdGVyU3VwcGxpZWQgPSBObyB3cml0ZXIgc3VwcGxpZWQgZm9yIHNlcmlhbGl6ZXIuCi0gICAgTWV0aG9kTm90U3VwcG9ydGVkID0gVGhlIG1ldGhvZCAnJ3swfScnIGlzIG5vdCBzdXBwb3J0ZWQgYnkgdGhpcyBmYWN0b3J5LgotICAgIFJlc2V0SW5NaWRkbGUgPSBUaGUgc2VyaWFsaXplciBtYXkgbm90IGJlIHJlc2V0IGluIHRoZSBtaWRkbGUgb2Ygc2VyaWFsaXphdGlvbi4KLSAgICBJbnRlcm5hbCA9IEludGVybmFsIGVycm9yOiBlbGVtZW50IHN0YXRlIGlzIHplcm8uCi0gICAgTm9OYW1lID0gVGhlcmUgaXMgbm8gcmF3TmFtZSBhbmQgbG9jYWxOYW1lIGlzIG51bGwuCi0gICAgRWxlbWVudFFOYW1lID0gVGhlIGVsZW1lbnQgbmFtZSAnJ3swfScnIGlzIG5vdCBhIFFOYW1lLgotICAgIEVsZW1lbnRQcmVmaXggPSBFbGVtZW50ICcnezB9JycgZG9lcyBub3QgYmVsb25nIHRvIGFueSBuYW1lc3BhY2U6IHByZWZpeCBjb3VsZCBiZSB1bmRlY2xhcmVkIG9yIGJvdW5kIHRvIHNvbWUgbmFtZXNwYWNlLgotICAgIEF0dHJpYnV0ZVFOYW1lID0gVGhlIGF0dHJpYnV0ZSBuYW1lICcnezB9JycgaXMgbm90IGEgUU5hbWUuCi0gICAgQXR0cmlidXRlUHJlZml4ID0gQXR0cmlidXRlICcnezB9JycgZG9lcyBub3QgYmVsb25nIHRvIGFueSBuYW1lc3BhY2U6IHByZWZpeCBjb3VsZCBiZSB1bmRlY2xhcmVkIG9yIGJvdW5kIHRvIHNvbWUgbmFtZXNwYWNlLgotICAgIEludmFsaWROU0RlY2wgPSBOYW1lc3BhY2UgZGVjbGFyYXRpb24gc3ludGF4IGlzIGluY29ycmVjdDogezB9LgotICAgIEVuZGluZ0NEQVRBID0gVGhlIGNoYXJhY3RlciBzZXF1ZW5jZSBcIl1dPlwiIG11c3Qgbm90IGFwcGVhciBpbiBjb250ZW50IHVubGVzcyB1c2VkIHRvIG1hcmsgdGhlIGVuZCBvZiBhIENEQVRBIHNlY3Rpb24uCi0gICAgU3BsaXR0aW5nQ0RBVEEgPSBTcGxpdHRpbmcgYSBDREFUQSBzZWN0aW9uIGNvbnRhaW5pbmcgdGhlIENEQVRBIHNlY3Rpb24gdGVybWluYXRpb24gbWFya2VyIFwiXV0+XCIuCi0gICAgUmVzb3VyY2VOb3RGb3VuZCA9IFRoZSByZXNvdXJjZSAnJ3swfScnIGNvdWxkIG5vdCBiZSBmb3VuZC4KLSAgICBSZXNvdXJjZU5vdExvYWRlZCA9IFRoZSByZXNvdXJjZSAnJ3swfScnIGNvdWxkIG5vdCBiZSBsb2FkZWQuIHsxfQotICAgIFNlcmlhbGl6YXRpb25TdG9wcGVkID0gIFNlcmlhbGl6YXRpb24gc3RvcHBlZCBhdCB1c2VyIHJlcXVlc3QuCi0KLSAgICAjIERPTSBMZXZlbCAzIGxvYWQgYW5kIHNhdmUgbWVzc2FnZXMKLSAgICBuby1vdXRwdXQtc3BlY2lmaWVkID0gbm8tb3V0cHV0LXNwZWNpZmllZDogVGhlIG91dHB1dCBkZXN0aW5hdGlvbiBmb3IgZGF0YSB0byBiZSB3cml0dGVuIHRvIHdhcyBudWxsLgotICAgIHVuc3VwcG9ydGVkLWVuY29kaW5nID0gdW5zdXBwb3J0ZWQtZW5jb2Rpbmc6IEFuIHVuc3VwcG9ydGVkIGVuY29kaW5nIGlzIGVuY291bnRlcmVkLgotICAgIHVuYWJsZS10by1zZXJpYWxpemUtbm9kZSA9IHVuYWJsZS10by1zZXJpYWxpemUtbm9kZTogVGhlIG5vZGUgY291bGQgbm90IGJlIHNlcmlhbGl6ZWQuCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9YTUxTZXJpYWxpemVyTWVzc2FnZXNfZGUucHJvcGVydGllcyBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hNTFNlcmlhbGl6ZXJNZXNzYWdlc19kZS5wcm9wZXJ0aWVzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlOGZhMTdlLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hNTFNlcmlhbGl6ZXJNZXNzYWdlc19kZS5wcm9wZXJ0aWVzCisrKyAvZGV2L251bGwKQEAgLTEsMzIgKzAsMCBAQAotIyBUaGlzIGZpbGUgc3RvcmVzIGVycm9yIG1lc3NhZ2VzIGZvciB0aGUgWGVyY2VzIFhNTAotIyBzZXJpYWxpemVyLiAgTWFueSBET00gTG9hZC9TYXZlIGVycm9yIG1lc3NhZ2VzIGFsc28gCi0jIGxpdmUgaGVyZSwgc2luY2UgdGhlIHNlcmlhbGl6ZXIgbGFyZ2VseSBpbXBsZW1lbnRzIHRoYXQgcGFja2FnZS4KLSMKLSMgQXMgdXN1YWwgd2l0aCBwcm9wZXJ0aWVzIGZpbGVzLCB0aGUgbWVzc2FnZXMgYXJlIGFycmFuZ2VkIGluCi0jIGtleS92YWx1ZSB0dXBsZXMuCi0jIAotCi0gICAgQmFkTWVzc2FnZUtleSA9IERpZSB6dW0gTWVsZHVuZ3NzY2hsXHUwMEZDc3NlbCBnZWhcdTAwRjZyaWdlIEZlaGxlcm1lbGR1bmcga2FubiBuaWNodCBnZWZ1bmRlbiB3ZXJkZW4uCi0gICAgRm9ybWF0RmFpbGVkID0gQmVpbSBGb3JtYXRpZXJlbiBkZXIgZm9sZ2VuZGVuIE1lbGR1bmcgaXN0IGVpbiBpbnRlcm5lciBGZWhsZXIgYXVmZ2V0cmV0ZW46XG4KLQotICAgIEFyZ3VtZW50SXNOdWxsID0gQXJndW1lbnQgInswfSIgaXN0IG51bGwuCi0gICAgTm9Xcml0ZXJTdXBwbGllZCA9IEtlaW4gV3JpdGVyIGZcdTAwRkNyIFNlcmlhbGl6ZXIgYW5nZWdlYmVuLgotICAgIE1ldGhvZE5vdFN1cHBvcnRlZCA9IE1ldGhvZGUgInswfSIgd2lyZCB2b24gZGllc2VyIEZhY3RvcnkgbmljaHQgdW50ZXJzdFx1MDBGQ3R6dC4KLSAgICBSZXNldEluTWlkZGxlID0gU2VyaWFsaXplciBrYW5uIG5pY2h0IHdcdTAwRTRocmVuZCBkZXIgU2VyaWFsaXNpZXJ1bmcgenVyXHUwMEZDY2tnZXNldHp0IHdlcmRlbi4KLSAgICBJbnRlcm5hbCA9IEludGVybmVyIEZlaGxlcjogRWxlbWVudHN0YXR1cyBpc3QgbnVsbC4KLSAgICBOb05hbWUgPSBFcyBpc3Qga2VpbiByYXdOYW1lIHZvcmhhbmRlbiwgdW5kIGxvY2FsTmFtZSBpc3QgbnVsbC4KLSAgICBFbGVtZW50UU5hbWUgPSBFbGVtZW50bmFtZSAiezB9IiBpc3Qga2VpbiBRTmFtZS4KLSAgICBFbGVtZW50UHJlZml4ID0gRWxlbWVudCAiezB9IiBnZWhcdTAwRjZydCB6dSBrZWluZW0gTmFtZXNwYWNlOiBQclx1MDBFNGZpeCBpc3QgbVx1MDBGNmdsaWNoZXJ3ZWlzZSBuaWNodCBkZWtsYXJpZXJ0IG9kZXIgYW4gZWluZW4gTmFtZXNwYWNlIGdlYnVuZGVuLgotICAgIEF0dHJpYnV0ZVFOYW1lID0gQXR0cmlidXRuYW1lICJ7MH0iIGlzdCBrZWluIFFOYW1lLgotICAgIEF0dHJpYnV0ZVByZWZpeCA9IEF0dHJpYnV0ICJ7MH0iIGdlaFx1MDBGNnJ0IHp1IGtlaW5lbSBOYW1lc3BhY2U6IFByXHUwMEU0Zml4IGlzdCBtXHUwMEY2Z2xpY2hlcndlaXNlIG5pY2h0IGRla2xhcmllcnQgb2RlciBhbiBlaW5lbiBOYW1lc3BhY2UgZ2VidW5kZW4uCi0gICAgSW52YWxpZE5TRGVjbCA9IE5hbWVzcGFjZS1EZWtsYXJhdGlvbnNzeW50YXggaXN0IGZhbHNjaDogezB9LgotICAgIEVuZGluZ0NEQVRBID0gWmVpY2hlbmZvbGdlIiJdXT4iIGRhcmYgbnVyIGltIENvbnRlbnQgZW50aGFsdGVuIHNlaW4sIHdlbm4gc2llIGRhcyBFbmRlIGVpbmVzIENEQVRBLUFic2Nobml0dHMgbWFya2llcnQuCi0gICAgU3BsaXR0aW5nQ0RBVEEgPSBUZWlsZW4gZWluZXMgQ0RBVEEtQWJzY2huaXR0cyBtaXQgZGVtIENEQVRBLUFic2Nobml0dHNhYnNjaGx1c3N6ZWljaGVuICJdXT4iLgotICAgIFJlc291cmNlTm90Rm91bmQgPSBSZXNzb3VyY2UgInswfSIga29ubnRlIG5pY2h0IGdlZnVuZGVuIHdlcmRlbi4KLSAgICBSZXNvdXJjZU5vdExvYWRlZCA9IFJlc3NvdXJjZSAiezB9IiBrb25udGUgbmljaHQgZ2VsYWRlbiB3ZXJkZW4uIHsxfQotICAgIFNlcmlhbGl6YXRpb25TdG9wcGVkID0gIFNlcmlhbGlzaWVydW5nIGF1ZiBCZW51dHplcmFuZm9yZGVydW5nIGdlc3RvcHB0LgotCi0gICAgIyBET00gTGV2ZWwgMyBsb2FkIGFuZCBzYXZlIG1lc3NhZ2VzCi0gICAgbm8tb3V0cHV0LXNwZWNpZmllZCA9IG5vLW91dHB1dC1zcGVjaWZpZWQ6IEF1c2dhYmV6aWVsLCBpbiBkYXMgRGF0ZW4gZ2VzY2hyaWViZW4gd2VyZGVuIHNvbGx0ZW4sIHdhciBudWxsLgotICAgIHVuc3VwcG9ydGVkLWVuY29kaW5nID0gdW5zdXBwb3J0ZWQtZW5jb2Rpbmc6IE5pY2h0IHVudGVyc3RcdTAwRkN0enRlIENvZGllcnVuZyBnZWZ1bmRlbi4KLSAgICB1bmFibGUtdG8tc2VyaWFsaXplLW5vZGUgPSB1bmFibGUtdG8tc2VyaWFsaXplLW5vZGU6IEtub3RlbiBrb25udGUgbmljaHQgc2VyaWFsaXNpZXJ0IHdlcmRlbi4KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hNTFNlcmlhbGl6ZXJNZXNzYWdlc19lcy5wcm9wZXJ0aWVzIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MU2VyaWFsaXplck1lc3NhZ2VzX2VzLnByb3BlcnRpZXMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGE5NjA5YjkuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MU2VyaWFsaXplck1lc3NhZ2VzX2VzLnByb3BlcnRpZXMKKysrIC9kZXYvbnVsbApAQCAtMSwzMiArMCwwIEBACi0jIFRoaXMgZmlsZSBzdG9yZXMgZXJyb3IgbWVzc2FnZXMgZm9yIHRoZSBYZXJjZXMgWE1MCi0jIHNlcmlhbGl6ZXIuICBNYW55IERPTSBMb2FkL1NhdmUgZXJyb3IgbWVzc2FnZXMgYWxzbyAKLSMgbGl2ZSBoZXJlLCBzaW5jZSB0aGUgc2VyaWFsaXplciBsYXJnZWx5IGltcGxlbWVudHMgdGhhdCBwYWNrYWdlLgotIwotIyBBcyB1c3VhbCB3aXRoIHByb3BlcnRpZXMgZmlsZXMsIHRoZSBtZXNzYWdlcyBhcmUgYXJyYW5nZWQgaW4KLSMga2V5L3ZhbHVlIHR1cGxlcy4KLSMgCi0KLSAgICBCYWRNZXNzYWdlS2V5ID0gTm8gc2UgaGEgZW5jb250cmFkbyBlbCBtZW5zYWplIGRlIGVycm9yIHF1ZSBjb3JyZXNwb25kZSBhIGxhIGNsYXZlIGRlIG1lbnNhamUuCi0gICAgRm9ybWF0RmFpbGVkID0gU2UgaGEgcHJvZHVjaWRvIHVuIGVycm9yIGludGVybm8gYWwgZm9ybWF0ZWFyIGVsIHNpZ3VpZW50ZSBtZW5zYWplOlxuCi0KLSAgICBBcmd1bWVudElzTnVsbCA9IEVsIGFyZ3VtZW50byAnJ3swfScnIGVzIG51bG8uCi0gICAgTm9Xcml0ZXJTdXBwbGllZCA9IE5vIHNlIGhhIHN1bWluaXN0cmFkbyBuaW5nXHUwMEZBbiBlc2NyaXRvciBwYXJhIGVsIHNlcmlhbGl6YWRvci4KLSAgICBNZXRob2ROb3RTdXBwb3J0ZWQgPSBFbCBtXHUwMEU5dG9kbyAnJ3swfScnIG5vIGVzdFx1MDBFMSBzb3BvcnRhZG8gcG9yIGVzdGEgZlx1MDBFMWJyaWNhLgotICAgIFJlc2V0SW5NaWRkbGUgPSBObyBwdWVkZSByZWluaWNpYXJzZSBlbCBzZXJpYWxpemFkb3IgZW4gbWVkaW8gZGUgbGEgc2VyaWFsaXphY2lcdTAwRjNuLgotICAgIEludGVybmFsID0gRXJyb3IgaW50ZXJubzogZWwgZXN0YWRvIGRlbCBlbGVtZW50byBlcyBjZXJvLgotICAgIE5vTmFtZSA9IE5vIGhheSBuaW5nXHUwMEZBbiByYXdOYW1lIHkgbG9jYWxOYW1lIGVzIG51bG8uCi0gICAgRWxlbWVudFFOYW1lID0gRWwgbm9tYnJlIGRlbCBlbGVtZW50byAnJ3swfScnIG5vIGVzIHVuIFFOYW1lLgotICAgIEVsZW1lbnRQcmVmaXggPSBFbCBlbGVtZW50byAnJ3swfScnIG5vIHBlcnRlbmVjZSBhIG5pbmdcdTAwRkFuIGVzcGFjaW8gZGUgbm9tYnJlczogZWwgcHJlZmlqbyBwdWVkZSBzZXIgbm8gZGVjbGFyYWRvIG8gZXN0YXIgZW5sYXphZG8gYSBhbGdcdTAwRkFuIGVzcGFjaW8gZGUgbm9tYnJlcy4KLSAgICBBdHRyaWJ1dGVRTmFtZSA9IEVsIG5vbWJyZSBkZWwgYXRyaWJ1dG8gJyd7MH0nJyBubyBlcyB1biBRTmFtZS4KLSAgICBBdHRyaWJ1dGVQcmVmaXggPSBFbCBhdHJpYnV0byAnJ3swfScnIG5vIHBlcnRlbmVjZSBhIG5pbmdcdTAwRkFuIGVzcGFjaW8gZGUgbm9tYnJlczogZWwgcHJlZmlqbyBwdWVkZSBzZXIgbm8gZGVjbGFyYWRvIG8gZXN0YXIgZW5sYXphZG8gYSBhbGdcdTAwRkFuIGVzcGFjaW8gZGUgbm9tYnJlcy4KLSAgICBJbnZhbGlkTlNEZWNsID0gTGEgc2ludGF4aXMgZGUgbGEgZGVjbGFyYWNpXHUwMEYzbiBkZSBlc3BhY2lvIGRlIG5vbWJyZXMgbm8gZXMgY29ycmVjdGE6IHswfS4KLSAgICBFbmRpbmdDREFUQSA9IExhIHNlY3VlbmNpYSBkZSBjYXJhY3RlcmVzICJdXT4iIG5vIGRlYmUgYXBhcmVjZXIgZW4gZWwgY29udGVuaWRvIGEgbWVub3MgcXVlIHNlIHV0aWxpY2UgcGFyYSBtYXJjYXIgZWwgZmluYWwgZGUgdW5hIHNlY2NpXHUwMEYzbiBDREFUQS4KLSAgICBTcGxpdHRpbmdDREFUQSA9IERpdmlzaVx1MDBGM24gZGUgdW5hIHNlY2NpXHUwMEYzbiBDREFUQSBxdWUgY29udGllbmUgZWwgbWFyY2Fkb3IgZGUgdGVybWluYWNpXHUwMEYzbiBkZSBzZWNjaVx1MDBGM24gQ0RBVEEgIl1dPiIuCi0gICAgUmVzb3VyY2VOb3RGb3VuZCA9IE5vIHNlIGhhIGVuY29udHJhZG8gZWwgcmVjdXJzbyAnJ3swfScnLgotICAgIFJlc291cmNlTm90TG9hZGVkID0gTm8gc2UgaGEgcG9kaWRvIGNhcmdhciBlbCByZWN1cnNvICcnezB9JycuIHsxfQotICAgIFNlcmlhbGl6YXRpb25TdG9wcGVkID0gIExhIHNlcmlhbGl6YWNpXHUwMEYzbiBzZSBoYSBwYXJhZG8gYSBwZXRpY2lcdTAwRjNuIGRlbCB1c3VhcmlvLgotCi0gICAgIyBET00gTGV2ZWwgMyBsb2FkIGFuZCBzYXZlIG1lc3NhZ2VzCi0gICAgbm8tb3V0cHV0LXNwZWNpZmllZCA9IG5vLW91dHB1dC1zcGVjaWZpZWQ6IEVsIGRlc3Rpbm8gZGUgc2FsaWRhIGVuIGVsIHF1ZSBzZSBkZWJcdTAwRURhbiBlc2NyaWJpciBsb3MgZGF0b3MgZXJhIG51bG8uCi0gICAgdW5zdXBwb3J0ZWQtZW5jb2RpbmcgPSB1bnN1cHBvcnRlZC1lbmNvZGluZzogU2UgaGEgZW5jb250cmFkbyB1bmEgY29kaWZpY2FjaVx1MDBGM24gbm8gc29wb3J0YWRhLgotICAgIHVuYWJsZS10by1zZXJpYWxpemUtbm9kZSA9IHVuYWJsZS10by1zZXJpYWxpemUtbm9kZTogRWwgbm9kbyBubyBzZSBoYSBwb2RpZG8gc2VyaWFsaXphci4KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hNTFNlcmlhbGl6ZXJNZXNzYWdlc19mci5wcm9wZXJ0aWVzIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MU2VyaWFsaXplck1lc3NhZ2VzX2ZyLnByb3BlcnRpZXMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGU4NDQyNjcuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MU2VyaWFsaXplck1lc3NhZ2VzX2ZyLnByb3BlcnRpZXMKKysrIC9kZXYvbnVsbApAQCAtMSwzMiArMCwwIEBACi0jIFRoaXMgZmlsZSBzdG9yZXMgZXJyb3IgbWVzc2FnZXMgZm9yIHRoZSBYZXJjZXMgWE1MCi0jIHNlcmlhbGl6ZXIuICBNYW55IERPTSBMb2FkL1NhdmUgZXJyb3IgbWVzc2FnZXMgYWxzbyAKLSMgbGl2ZSBoZXJlLCBzaW5jZSB0aGUgc2VyaWFsaXplciBsYXJnZWx5IGltcGxlbWVudHMgdGhhdCBwYWNrYWdlLgotIwotIyBBcyB1c3VhbCB3aXRoIHByb3BlcnRpZXMgZmlsZXMsIHRoZSBtZXNzYWdlcyBhcmUgYXJyYW5nZWQgaW4KLSMga2V5L3ZhbHVlIHR1cGxlcy4KLSMgCi0KLSAgICBCYWRNZXNzYWdlS2V5ID0gTGUgbWVzc2FnZSBkJ2VycmV1ciBjb3JyZXNwb25kYW50IFx1MDBFMCBsYSBjbFx1MDBFOSBkZSBtZXNzYWdlIGVzdCBpbnRyb3V2YWJsZS4KLSAgICBGb3JtYXRGYWlsZWQgPSBVbmUgZXJyZXVyIGludGVybmUgZXN0IHN1cnZlbnVlIGxvcnMgZGUgbGEgbWlzZSBlbiBmb3JtZSBkdSBtZXNzYWdlIHN1aXZhbnQgOlxuCi0KLSAgICBBcmd1bWVudElzTnVsbCA9IEwnJ2FyZ3VtZW50ICcnezB9JycgZXN0IE5VTEwuCi0gICAgTm9Xcml0ZXJTdXBwbGllZCA9IEF1Y3VuIHByb2Nlc3N1cyBkJ1x1MDBFOWNyaXR1cmUgbidlc3QgZm91cm5pIHBvdXIgbGUgc2VyaWFsaXplci4KLSAgICBNZXRob2ROb3RTdXBwb3J0ZWQgPSBMYSBtXHUwMEU5dGhvZGUgJyd7MH0nJyBuJydlc3QgcGFzIHByaXNlIGVuIGNoYXJnZSBwYXIgY2V0dGUgZmFicmlxdWUuCi0gICAgUmVzZXRJbk1pZGRsZSA9IEltcG9zc2libGUgZGUgclx1MDBFOWluaXRpYWxpc2VyIGxlIHNlcmlhbGl6ZXIgYXUgY291cnMgZGUgbGEgc1x1MDBFOXJpYWxpc2F0aW9uLgotICAgIEludGVybmFsID0gRXJyZXVyIGludGVybmUgOiBsJ1x1MDBFOXRhdCBkZSBsJ1x1MDBFOWxcdTAwRTltZW50IGVzdCB6XHUwMEU5cm8uCi0gICAgTm9OYW1lID0gSWwgbidleGlzdGUgYXVjdW4gXHUwMEU5bFx1MDBFOW1lbnQgcmF3TmFtZSBldCBsJ1x1MDBFOWxcdTAwRTltZW50IGxvY2FsTmFtZSBlc3QgTlVMTC4KLSAgICBFbGVtZW50UU5hbWUgPSBMZSBub20gZCcnXHUwMEU5bFx1MDBFOW1lbnQgJyd7MH0nJyBuJydlc3QgcGFzIHVuIFFOYW1lLgotICAgIEVsZW1lbnRQcmVmaXggPSBMJydcdTAwRTlsXHUwMEU5bWVudCAnJ3swfScnIG4nJ2FwcGFydGllbnQgXHUwMEUwIGF1Y3VuIGVzcGFjZSBkZSBub21zIDogbGUgcHJcdTAwRTlmaXhlIGVzdCBwZXV0LVx1MDBFQXRyZSBub24gZFx1MDBFOWNsYXJcdTAwRTkgb3UgbGlcdTAwRTkgXHUwMEUwIHVuIGVzcGFjZSBkZSBub21zLgotICAgIEF0dHJpYnV0ZVFOYW1lID0gTGUgbm9tIGQnJ2F0dHJpYnV0ICcnezB9JycgbicnZXN0IHBhcyB1biBRTmFtZS4KLSAgICBBdHRyaWJ1dGVQcmVmaXggPSBMJydhdHRyaWJ1dCAnJ3swfScnIG4nJ2FwcGFydGllbnQgXHUwMEUwIGF1Y3VuIGVzcGFjZSBkZSBub21zIDogbGUgcHJcdTAwRTlmaXhlIGVzdCBwZXV0LVx1MDBFQXRyZSBub24gZFx1MDBFOWNsYXJcdTAwRTkgb3UgbGlcdTAwRTkgXHUwMEUwIHVuIGVzcGFjZSBkZSBub21zLgotICAgIEludmFsaWROU0RlY2wgPSBMYSBzeW50YXhlIGRlIGxhIGRcdTAwRTljbGFyYXRpb24gZCcnZXNwYWNlIGRlIG5vbXMgZXN0IGluY29ycmVjdGUgOiB7MH0uCi0gICAgRW5kaW5nQ0RBVEEgPSBMYSBzXHUwMEU5cXVlbmNlIGRlIGNhcmFjdFx1MDBFOHJlcyAiXV0+IiBuZSBwZXV0IGZpZ3VyZXIgZGFucyBsZSBjb250ZW51IHF1ZSBwb3VyIG1hcnF1ZXIgbGEgZmluIGRlIGxhIHNlY3Rpb24gQ0RBVEEuCi0gICAgU3BsaXR0aW5nQ0RBVEEgPSBGcmFjdGlvbm5lbWVudCBkJ3VuZSBzZWN0aW9uIENEQVRBIGNvbnRlbmFudCBsZSBtYXJxdWV1ciBkZSBmaW4gZGUgc2VjdGlvbiBDREFUQSAiXV0+Ii4KLSAgICBSZXNvdXJjZU5vdEZvdW5kID0gTGEgcmVzc291cmNlICcnezB9JycgZXN0IGludHJvdXZhYmxlLgotICAgIFJlc291cmNlTm90TG9hZGVkID0gTGEgcmVzc291cmNlICcnezB9JycgbicnYSBwYXMgcHUgXHUwMEVBdHJlIGNoYXJnXHUwMEU5ZS4gezF9Ci0gICAgU2VyaWFsaXphdGlvblN0b3BwZWQgPSAgTGEgc1x1MDBFOXJpYWxpc2F0aW9uIGEgXHUwMEU5dFx1MDBFOSBhcnJcdTAwRUF0XHUwMEU5ZSBcdTAwRTAgbGEgZGVtYW5kZSBkZSBsJ3V0aWxpc2F0ZXVyLgotCi0gICAgIyBET00gTGV2ZWwgMyBsb2FkIGFuZCBzYXZlIG1lc3NhZ2VzCi0gICAgbm8tb3V0cHV0LXNwZWNpZmllZCA9IHBhcyBkZSBzb3J0aWUgaW5kaXF1XHUwMEU5ZSA6IGxhIGRlc3RpbmF0aW9uIGRlIHNvcnRpZSBkYW5zIGxhcXVlbGxlIFx1MDBFOWNyaXJlIGxlcyBkb25uXHUwMEU5ZXMgZXN0IE5VTEwuCi0gICAgdW5zdXBwb3J0ZWQtZW5jb2RpbmcgPSBlbmNvZGFnZSBub24gcHJpcyBlbiBjaGFyZ2UgOiB1biBlbmNvZGFnZSBub24gcHJpcyBlbiBjaGFyZ2UgYSBcdTAwRTl0XHUwMEU5IGRcdTAwRTl0ZWN0XHUwMEU5LgotICAgIHVuYWJsZS10by1zZXJpYWxpemUtbm9kZSA9IGltcG9zc2libGUgZGUgc1x1MDBFOXJpYWxpc2VyIGxlIG5vZXVkIDogbGUgbm9ldWQgbidhIHBhcyBwdSBcdTAwRUF0cmUgc1x1MDBFOXJpYWxpc1x1MDBFOS4KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hNTFNlcmlhbGl6ZXJNZXNzYWdlc19pdC5wcm9wZXJ0aWVzIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MU2VyaWFsaXplck1lc3NhZ2VzX2l0LnByb3BlcnRpZXMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDRhMGExNzEuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MU2VyaWFsaXplck1lc3NhZ2VzX2l0LnByb3BlcnRpZXMKKysrIC9kZXYvbnVsbApAQCAtMSwzMiArMCwwIEBACi0jIFRoaXMgZmlsZSBzdG9yZXMgZXJyb3IgbWVzc2FnZXMgZm9yIHRoZSBYZXJjZXMgWE1MCi0jIHNlcmlhbGl6ZXIuICBNYW55IERPTSBMb2FkL1NhdmUgZXJyb3IgbWVzc2FnZXMgYWxzbyAKLSMgbGl2ZSBoZXJlLCBzaW5jZSB0aGUgc2VyaWFsaXplciBsYXJnZWx5IGltcGxlbWVudHMgdGhhdCBwYWNrYWdlLgotIwotIyBBcyB1c3VhbCB3aXRoIHByb3BlcnRpZXMgZmlsZXMsIHRoZSBtZXNzYWdlcyBhcmUgYXJyYW5nZWQgaW4KLSMga2V5L3ZhbHVlIHR1cGxlcy4KLSMgCi0KLSAgICBCYWRNZXNzYWdlS2V5ID0gSW1wb3NzaWJpbGUgdHJvdmFyZSBpbCBtZXNzYWdnaW8gZGkgZXJyb3JlIGNvcnJpc3BvbmRlbnRlIGFsbGEgY2hpYXZlIGRpIG1lc3NhZ2dpby4KLSAgICBGb3JtYXRGYWlsZWQgPSBTaSBcdTAwRTggdmVyaWZpY2F0byB1biBlcnJvcmUgaW50ZXJubyBkdXJhbnRlIGxhIGZvcm1hdHRhemlvbmUgZGVsIHNlZ3VlbnRlIG1lc3NhZ2dpbzpcbgotCi0gICAgQXJndW1lbnRJc051bGwgPSBMJydhcmdvbWVudG8gJyd7MH0nJyBcdTAwRTggbnVsbG8uCi0gICAgTm9Xcml0ZXJTdXBwbGllZCA9IE5lc3N1biBwcm9jZXNzbyBkaSBzY3JpdHR1cmEgZm9ybml0byBwZXIgaWwgc2VyaWFsaXp6YXRvcmUuCi0gICAgTWV0aG9kTm90U3VwcG9ydGVkID0gSWwgbWV0b2RvICcnezB9Jycgbm9uIFx1MDBFOCBzdXBwb3J0YXRvIGRhIHF1ZXN0byBmYWN0b3J5LgotICAgIFJlc2V0SW5NaWRkbGUgPSBJbXBvc3NpYmlsZSByZWltcG9zdGFyZSBpbCBzZXJpYWxpenphdG9yZSBkdXJhbnRlIHVuYSBzZXJpYWxpenphemlvbmUuCi0gICAgSW50ZXJuYWwgPSBFcnJvcmUgaW50ZXJubzogbG8gc3RhdG8gZGVsbCdlbGVtZW50byBcdTAwRTggemVyby4KLSAgICBOb05hbWUgPSBOb24gZXNpc3RlIGFsY3VuIHJhd05hbWUgZSBsb2NhbE5hbWUgXHUwMEU4IG51bGxvLgotICAgIEVsZW1lbnRRTmFtZSA9IElsIG5vbWUgZWxlbWVudG8gJyd7MH0nJyBub24gXHUwMEU4IHVuIFFOYW1lLgotICAgIEVsZW1lbnRQcmVmaXggPSBMJydlbGVtZW50byAnJ3swfScnIG5vbiBhcHBhcnRpZW5lIGFkIGFsY3VubyBzcGF6aW8gZGkgbm9taTogaWwgcHJlZmlzc28gZGV2ZSBlc3NlcmUgbm9uIGRpY2hpYXJhdG8gbyBhc3NvY2lhdG8gYSB1bm8gc3BhemlvIGRpIG5vbWkuCi0gICAgQXR0cmlidXRlUU5hbWUgPSBJbCBub21lIGF0dHJpYnV0byAnJ3swfScnIG5vbiBcdTAwRTggdW4gUU5hbWUuCi0gICAgQXR0cmlidXRlUHJlZml4ID0gTCcnYXR0cmlidXRvICcnezB9Jycgbm9uIGFwcGFydGllbmUgYWQgYWxjdW5vIHNwYXppbyBkaSBub21pOiBpbCBwcmVmaXNzbyBkZXZlIGVzc2VyZSBub24gZGljaGlhcmF0byBvIGFzc29jaWF0byBhIHVubyBzcGF6aW8gZGkgbm9taS4KLSAgICBJbnZhbGlkTlNEZWNsID0gTGEgc2ludGFzc2kgZGVsbGEgZGljaGlhcmF6aW9uZSBkZWxsbyBzcGF6aW8gZGkgbm9taSBcdTAwRTggZXJyYXRhOiB7MH0uCi0gICAgRW5kaW5nQ0RBVEEgPSBMYSBzZXF1ZW56YSBkaSBjYXJhdHRlcmkgIl1dPiIgbm9uIGRldmUgZXNzZXJlIHByZXNlbnRlIG5lbCBjb250ZW51dG8gYSBtZW5vIGNoZSBub24gc2lhIHV0aWxpenphdGEgcGVyIGNvbnRyYXNzZWduYXJlIGxhIGZpbmUgZGkgdW5hIHNlemlvbmUgQ0RBVEEuCi0gICAgU3BsaXR0aW5nQ0RBVEEgPSBWZXJyXHUwMEUwIHN1ZGRpdmlzYSB1bmEgc2V6aW9uZSBDREFUQSBjaGUgY29udGllbmUgbCdpbmRpY2F0b3JlIGRpIGZpbmUgZGVsbGEgc2V6aW9uZSBDREFUQSAiXV0+Ii4KLSAgICBSZXNvdXJjZU5vdEZvdW5kID0gSW1wb3NzaWJpbGUgdHJvdmFyZSBsYSByaXNvcnNhICcnezB9JycuCi0gICAgUmVzb3VyY2VOb3RMb2FkZWQgPSBJbXBvc3NpYmlsZSBjYXJpY2FyZSBsYSByaXNvcnNhICcnezB9JycuIHsxfQotICAgIFNlcmlhbGl6YXRpb25TdG9wcGVkID0gIFNlcmlhbGl6emF6aW9uZSBhcnJlc3RhdGEgc3UgcmljaGllc3RhIGRlbGwndXRlbnRlLgotCi0gICAgIyBET00gTGV2ZWwgMyBsb2FkIGFuZCBzYXZlIG1lc3NhZ2VzCi0gICAgbm8tb3V0cHV0LXNwZWNpZmllZCA9IG5vLW91dHB1dC1zcGVjaWZpZWQ6IGxhIGRlc3RpbmF6aW9uZSBkaSBvdXRwdXQgcGVyIGkgZGF0aSBkYSBzY3JpdmVyZSBcdTAwRTggbnVsbGEuCi0gICAgdW5zdXBwb3J0ZWQtZW5jb2RpbmcgPSB1bnN1cHBvcnRlZC1lbmNvZGluZzogXHUwMEU4IHN0YXRhIHJpbGV2YXRhIHVuYSBjb2RpZmljYSBub24gc3VwcG9ydGF0YS4KLSAgICB1bmFibGUtdG8tc2VyaWFsaXplLW5vZGUgPSB1bmFibGUtdG8tc2VyaWFsaXplLW5vZGU6IGltcG9zc2liaWxlIHNlcmlhbGl6emFyZSBpbCBub2RvLgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MU2VyaWFsaXplck1lc3NhZ2VzX2phLnByb3BlcnRpZXMgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9YTUxTZXJpYWxpemVyTWVzc2FnZXNfamEucHJvcGVydGllcwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNTk2NThjNi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9YTUxTZXJpYWxpemVyTWVzc2FnZXNfamEucHJvcGVydGllcworKysgL2Rldi9udWxsCkBAIC0xLDMyICswLDAgQEAKLSMgVGhpcyBmaWxlIHN0b3JlcyBlcnJvciBtZXNzYWdlcyBmb3IgdGhlIFhlcmNlcyBYTUwKLSMgc2VyaWFsaXplci4gIE1hbnkgRE9NIExvYWQvU2F2ZSBlcnJvciBtZXNzYWdlcyBhbHNvIAotIyBsaXZlIGhlcmUsIHNpbmNlIHRoZSBzZXJpYWxpemVyIGxhcmdlbHkgaW1wbGVtZW50cyB0aGF0IHBhY2thZ2UuCi0jCi0jIEFzIHVzdWFsIHdpdGggcHJvcGVydGllcyBmaWxlcywgdGhlIG1lc3NhZ2VzIGFyZSBhcnJhbmdlZCBpbgotIyBrZXkvdmFsdWUgdHVwbGVzLgotIyAKLQotICAgIEJhZE1lc3NhZ2VLZXkgPSBcdTMwRTFcdTMwQzNcdTMwQkJcdTMwRkNcdTMwQjhcdTMwRkJcdTMwQURcdTMwRkNcdTMwNkJcdTVCRkVcdTVGRENcdTMwNTlcdTMwOEJcdTMwQThcdTMwRTlcdTMwRkNcdTMwRkJcdTMwRTFcdTMwQzNcdTMwQkJcdTMwRkNcdTMwQjhcdTMwNENcdTg5OEJcdTMwNjRcdTMwNEJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLSAgICBGb3JtYXRGYWlsZWQgPSBcdTZCMjFcdTMwNkVcdTMwRTFcdTMwQzNcdTMwQkJcdTMwRkNcdTMwQjhcdTMwNkVcdTY2RjhcdTVGMEZcdThBMkRcdTVCOUFcdTRFMkRcdTMwNkJcdTUxODVcdTkwRThcdTMwQThcdTMwRTlcdTMwRkNcdTMwNENcdTc2N0FcdTc1MUZcdTMwNTdcdTMwN0VcdTMwNTdcdTMwNUY6XG4KLQotICAgIEFyZ3VtZW50SXNOdWxsID0gXHU1RjE1XHU2NTcwJyd7MH0nJ1x1MzA2Rm51bGxcdTMwNjdcdTMwNTlcdTMwMDIKLSAgICBOb1dyaXRlclN1cHBsaWVkID0gXHUzMEI3XHUzMEVBXHUzMEEyXHUzMEU5XHUzMEE0XHUzMEI2XHUzMDZCXHUzMEU5XHUzMEE0XHUzMEJGXHUzMEZDXHUzMDRDXHU2M0QwXHU0RjlCXHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0gICAgTWV0aG9kTm90U3VwcG9ydGVkID0gXHUzMDUzXHUzMDZFXHUzMEQ1XHUzMEExXHUzMEFGXHUzMEM4XHUzMEVBXHUzMDY3XHUzMDZGXHUzMDAxXHUzMEUxXHUzMEJEXHUzMEMzXHUzMEM5Jyd7MH0nJ1x1MzA2Rlx1MzBCNVx1MzBERFx1MzBGQ1x1MzBDOFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotICAgIFJlc2V0SW5NaWRkbGUgPSBcdTMwQjdcdTMwRUFcdTMwQTJcdTMwRTlcdTMwQTRcdTMwQjZcdTMwNkZcdTMwMDFcdTMwQjdcdTMwRUFcdTMwQTJcdTMwRTlcdTMwQTRcdTMwQkFcdTMwNkVcdTkwMTRcdTRFMkRcdTMwNjdcdTMwNkZcdTMwRUFcdTMwQkJcdTMwQzNcdTMwQzhcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLSAgICBJbnRlcm5hbCA9IFx1NTE4NVx1OTBFOFx1MzBBOFx1MzBFOVx1MzBGQzogXHU4OTgxXHU3RDIwXHUzMDZFXHU3MkI2XHU2MTRCXHUzMDRDXHUzMEJDXHUzMEVEXHUzMDY3XHUzMDU5XHUzMDAyCi0gICAgTm9OYW1lID0gcmF3TmFtZVx1MzA0Q1x1NUI1OFx1NTcyOFx1MzA1Qlx1MzA1QVx1MzAwMWxvY2FsTmFtZVx1MzA0Q251bGxcdTMwNjdcdTMwNTlcdTMwMDIKLSAgICBFbGVtZW50UU5hbWUgPSBcdTg5ODFcdTdEMjBcdTU0MEQnJ3swfScnXHUzMDZGUU5hbWVcdTMwNjdcdTMwNkZcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLSAgICBFbGVtZW50UHJlZml4ID0gXHU4OTgxXHU3RDIwJyd7MH0nJ1x1MzA0Q1x1MzA2OVx1MzA2RVx1MzBDRFx1MzBGQ1x1MzBFMFx1MzBCOVx1MzBEQVx1MzBGQ1x1MzBCOVx1MzA2Qlx1MzA4Mlx1NUM1RVx1MzA1N1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMlx1NjNBNVx1OTgyRFx1OEY5RVx1MzA0Q1x1NUJBM1x1OEEwMFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA2QVx1MzA0NFx1MzA0Qlx1MzAwMVx1MzA2QVx1MzA5M1x1MzA4OVx1MzA0Qlx1MzA2RVx1MzBDRFx1MzBGQ1x1MzBFMFx1MzBCOVx1MzBEQVx1MzBGQ1x1MzBCOVx1MzA2Qlx1MzBEMFx1MzBBNFx1MzBGM1x1MzBDOVx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA4Qlx1NTNFRlx1ODBGRFx1NjAyN1x1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgotICAgIEF0dHJpYnV0ZVFOYW1lID0gXHU1QzVFXHU2MDI3XHU1NDBEJyd7MH0nJ1x1MzA2RlFOYW1lXHUzMDY3XHUzMDZGXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi0gICAgQXR0cmlidXRlUHJlZml4ID0gXHU1QzVFXHU2MDI3Jyd7MH0nJ1x1MzA0Q1x1MzA2OVx1MzA2RVx1MzBDRFx1MzBGQ1x1MzBFMFx1MzBCOVx1MzBEQVx1MzBGQ1x1MzBCOVx1MzA2Qlx1MzA4Mlx1NUM1RVx1MzA1N1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMlx1NjNBNVx1OTgyRFx1OEY5RVx1MzA0Q1x1NUJBM1x1OEEwMFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA2QVx1MzA0NFx1MzA0Qlx1MzAwMVx1MzA2QVx1MzA5M1x1MzA4OVx1MzA0Qlx1MzA2RVx1MzBDRFx1MzBGQ1x1MzBFMFx1MzBCOVx1MzBEQVx1MzBGQ1x1MzBCOVx1MzA2Qlx1MzBEMFx1MzBBNFx1MzBGM1x1MzBDOVx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA4Qlx1NTNFRlx1ODBGRFx1NjAyN1x1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgotICAgIEludmFsaWROU0RlY2wgPSBcdTMwQ0RcdTMwRkNcdTMwRTBcdTMwQjlcdTMwREFcdTMwRkNcdTMwQjlcdTVCQTNcdThBMDBcdTMwNkVcdTY5Q0JcdTY1ODdcdTMwNENcdTZCNjNcdTMwNTdcdTMwNEZcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTM6IHswfVx1MzAwMgotICAgIEVuZGluZ0NEQVRBID0gXHU2NTg3XHU1QjU3XHUzMEI3XHUzMEZDXHUzMEIxXHUzMEYzXHUzMEI5Il1dPiJcdTMwNkZcdTMwMDFDREFUQVx1MzBCQlx1MzBBRlx1MzBCN1x1MzBFN1x1MzBGM1x1MzA2RVx1N0Q0Mlx1MzA4Rlx1MzA4QVx1MzA5Mlx1NzkzQVx1MzA1OVx1NzZFRVx1NzY4NFx1NEVFNVx1NTkxNlx1MzA2N1x1MzBCM1x1MzBGM1x1MzBDNlx1MzBGM1x1MzBDNFx1MzA2Qlx1NEY3Rlx1NzUyOFx1MzA1N1x1MzA2QVx1MzA0NFx1MzA2N1x1MzA0Rlx1MzA2MFx1MzA1NVx1MzA0NFx1MzAwMgotICAgIFNwbGl0dGluZ0NEQVRBID0gQ0RBVEFcdTMwQkJcdTMwQUZcdTMwQjdcdTMwRTdcdTMwRjNcdTdENDJcdTRFODZcdTMwREVcdTMwRkNcdTMwQUJcdTMwRkMiXV0+Ilx1MzA0Q1x1NTQyQlx1MzA3RVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA4QkNEQVRBXHUzMEJCXHUzMEFGXHUzMEI3XHUzMEU3XHUzMEYzXHUzMDkyXHU1MjA2XHU1MjcyXHUzMDU3XHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5XHUzMDAyCi0gICAgUmVzb3VyY2VOb3RGb3VuZCA9IFx1MzBFQVx1MzBCRFx1MzBGQ1x1MzBCOScnezB9JydcdTMwNENcdTg5OEJcdTMwNjRcdTMwNEJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwNjdcdTMwNTdcdTMwNUZcdTMwMDIKLSAgICBSZXNvdXJjZU5vdExvYWRlZCA9IFx1MzBFQVx1MzBCRFx1MzBGQ1x1MzBCOScnezB9JydcdTMwOTJcdTMwRURcdTMwRkNcdTMwQzlcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwNjdcdTMwNTdcdTMwNUZcdTMwMDIgezF9Ci0gICAgU2VyaWFsaXphdGlvblN0b3BwZWQgPSAgXHUzMEI3XHUzMEVBXHUzMEEyXHUzMEU5XHUzMEE0XHUzMEJBXHUzMDRDXHUzMEU2XHUzMEZDXHUzMEI2XHUzMEZDXHUzMEZCXHUzMEVBXHUzMEFGXHUzMEE4XHUzMEI5XHUzMEM4XHUzMDY3XHU1MDVDXHU2QjYyXHUzMDU1XHUzMDhDXHUzMDdFXHUzMDU3XHUzMDVGXHUzMDAyCi0KLSAgICAjIERPTSBMZXZlbCAzIGxvYWQgYW5kIHNhdmUgbWVzc2FnZXMKLSAgICBuby1vdXRwdXQtc3BlY2lmaWVkID0gbm8tb3V0cHV0LXNwZWNpZmllZDogXHU2NkY4XHUzMDREXHU4RkJDXHUzMDdFXHUzMDhDXHUzMDhCXHUzMEM3XHUzMEZDXHUzMEJGXHUzMDZFXHU1MUZBXHU1MjlCXHU1MTQ4XHUzMDRDbnVsbFx1MzA2Qlx1MzA2QVx1MzA2M1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OVx1MzAwMgotICAgIHVuc3VwcG9ydGVkLWVuY29kaW5nID0gdW5zdXBwb3J0ZWQtZW5jb2Rpbmc6IFx1MzBCNVx1MzBERFx1MzBGQ1x1MzBDOFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA2QVx1MzA0NFx1MzBBOFx1MzBGM1x1MzBCM1x1MzBGQ1x1MzBDN1x1MzBBM1x1MzBGM1x1MzBCMFx1MzA0Q1x1ODk4Qlx1MzA2NFx1MzA0Qlx1MzA4QVx1MzA3RVx1MzA1N1x1MzA1Rlx1MzAwMgotICAgIHVuYWJsZS10by1zZXJpYWxpemUtbm9kZSA9IHVuYWJsZS10by1zZXJpYWxpemUtbm9kZTogXHUzMENFXHUzMEZDXHUzMEM5XHUzMDkyXHUzMEI3XHUzMEVBXHUzMEEyXHUzMEU5XHUzMEE0XHUzMEJBXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDY3XHUzMDU3XHUzMDVGXHUzMDAyCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9YTUxTZXJpYWxpemVyTWVzc2FnZXNfa28ucHJvcGVydGllcyBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hNTFNlcmlhbGl6ZXJNZXNzYWdlc19rby5wcm9wZXJ0aWVzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwZGE3MmVkLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hNTFNlcmlhbGl6ZXJNZXNzYWdlc19rby5wcm9wZXJ0aWVzCisrKyAvZGV2L251bGwKQEAgLTEsMzIgKzAsMCBAQAotIyBUaGlzIGZpbGUgc3RvcmVzIGVycm9yIG1lc3NhZ2VzIGZvciB0aGUgWGVyY2VzIFhNTAotIyBzZXJpYWxpemVyLiAgTWFueSBET00gTG9hZC9TYXZlIGVycm9yIG1lc3NhZ2VzIGFsc28gCi0jIGxpdmUgaGVyZSwgc2luY2UgdGhlIHNlcmlhbGl6ZXIgbGFyZ2VseSBpbXBsZW1lbnRzIHRoYXQgcGFja2FnZS4KLSMKLSMgQXMgdXN1YWwgd2l0aCBwcm9wZXJ0aWVzIGZpbGVzLCB0aGUgbWVzc2FnZXMgYXJlIGFycmFuZ2VkIGluCi0jIGtleS92YWx1ZSB0dXBsZXMuCi0jIAotCi0gICAgQmFkTWVzc2FnZUtleSA9IFx1QkE1NFx1QzJEQ1x1QzlDMCBcdUQwQTRcdUM1RDAgXHVENTc0XHVCMkY5XHVENTU4XHVCMjk0IFx1QzYyNFx1Qjk1OCBcdUJBNTRcdUMyRENcdUM5QzBcdUI5N0MgXHVDQzNFXHVDNzQ0IFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuCi0gICAgRm9ybWF0RmFpbGVkID0gXHVCMkU0XHVDNzRDIFx1QkE1NFx1QzJEQ1x1QzlDMFx1Qzc1OCBcdUQ2MTVcdUMyRERcdUM3NDQgXHVDOUMwXHVDODE1XHVENTU4XHVCMjk0IFx1QzkxMSBcdUIwQjRcdUJEODAgXHVDNjI0XHVCOTU4XHVBQzAwIFx1QkMxQ1x1QzBERFx1RDU4OFx1QzJCNVx1QjJDOFx1QjJFNC5cbgotCi0gICAgQXJndW1lbnRJc051bGwgPSAnJ3swfScnIFx1Qzc3OFx1QzIxOFx1QUMwMCBcdUIxMTBcdUM3ODVcdUIyQzhcdUIyRTQuCi0gICAgTm9Xcml0ZXJTdXBwbGllZCA9IFNlcmlhbGl6ZXJcdUM1RDAgXHVCMzAwXHVENTc0IFx1QzgxQ1x1QUNGNVx1QjQxQyBcdUFFMzBcdUI4NUQgXHVDN0E1XHVDRTU4XHVBQzAwIFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4KLSAgICBNZXRob2ROb3RTdXBwb3J0ZWQgPSBcdUM3NzQgXHVEMzI5XHVEMUEwXHVCOUFDXHVCMjk0ICcnezB9JycgXHVCQTU0XHVDMThDXHVCNERDXHVCOTdDIFx1QzlDMFx1QzZEMFx1RDU1OFx1QzlDMCBcdUM1NEFcdUMyQjVcdUIyQzhcdUIyRTQuCi0gICAgUmVzZXRJbk1pZGRsZSA9IFx1QzlDMVx1QjgyQ1x1RDY1NCBcdUIzQzRcdUM5MTFcdUM1RDBcdUIyOTQgU2VyaWFsaXplclx1Qjk3QyBcdUM3QUNcdUMxMjRcdUM4MTVcdUQ1NjAgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4KLSAgICBJbnRlcm5hbCA9IFx1QjBCNFx1QkQ4MCBcdUM2MjRcdUI5NTg6IFx1QzY5NFx1QzE4QyBcdUMwQzFcdUQwRENcdUFDMDAgMFx1Qzc4NVx1QjJDOFx1QjJFNC4KLSAgICBOb05hbWUgPSByYXdOYW1lXHVDNzc0IFx1QzVDNlx1QzczQ1x1QkE3MCBsb2NhbE5hbWVcdUM3NzQgXHVCMTEwXHVDNzg1XHVCMkM4XHVCMkU0LgotICAgIEVsZW1lbnRRTmFtZSA9IFx1QzY5NFx1QzE4QyBcdUM3NzRcdUI5ODQgJyd7MH0nJ1x1Qzc0MChcdUIyOTQpIFFOYW1lXHVDNzc0IFx1QzU0NFx1QjJEOVx1QjJDOFx1QjJFNC4KLSAgICBFbGVtZW50UHJlZml4ID0gJyd7MH0nJyBcdUM2OTRcdUMxOENcdUFDMDAgXHVCMTI0XHVDNzg0XHVDMkE0XHVEMzk4XHVDNzc0XHVDMkE0XHVDNUQwIFx1QzE4RFx1RDU1OFx1QzlDMCBcdUM1NEFcdUM3NEM6IFx1QzgxMVx1QjQ1MFx1QzVCNFx1Qzc1OCBcdUMxMjBcdUM1QjhcdUM3NDQgXHVENTc0XHVDODFDXHVENTU4XHVBQzcwXHVCMDk4IFx1QzgxMVx1QjQ1MFx1QzVCNFx1Qjk3QyBcdUIxMjRcdUM3ODRcdUMyQTRcdUQzOThcdUM3NzRcdUMyQTRcdUM1RDAgXHVCQzE0XHVDNzc4XHVCNERDXHVENTYwIFx1QzIxOCBcdUM3ODhcdUMyQjVcdUIyQzhcdUIyRTQuCi0gICAgQXR0cmlidXRlUU5hbWUgPSBcdUMxOERcdUMxMzEgXHVDNzc0XHVCOTg0ICcnezB9JydcdUM3NDAoXHVCMjk0KSBRTmFtZVx1Qzc3NCBcdUM1NDRcdUIyRDlcdUIyQzhcdUIyRTQuCi0gICAgQXR0cmlidXRlUHJlZml4ID0gJyd7MH0nJyBcdUMxOERcdUMxMzFcdUM3NzQgXHVCMTI0XHVDNzg0XHVDMkE0XHVEMzk4XHVDNzc0XHVDMkE0XHVDNUQwIFx1QzE4RFx1RDU1OFx1QzlDMCBcdUM1NEFcdUM3NEM6IFx1QzgxMVx1QjQ1MFx1QzVCNFx1Qzc1OCBcdUMxMjBcdUM1QjhcdUM3NDQgXHVENTc0XHVDODFDXHVENTU4XHVBQzcwXHVCMDk4IFx1QzgxMVx1QjQ1MFx1QzVCNFx1Qjk3QyBcdUIxMjRcdUM3ODRcdUMyQTRcdUQzOThcdUM3NzRcdUMyQTRcdUM1RDAgXHVCQzE0XHVDNzc4XHVCNERDXHVENTYwIFx1QzIxOCBcdUM3ODhcdUMyQjVcdUIyQzhcdUIyRTQuCi0gICAgSW52YWxpZE5TRGVjbCA9IFx1QjEyNFx1Qzc4NFx1QzJBNFx1RDM5OFx1Qzc3NFx1QzJBNCBcdUMxMjBcdUM1QjggXHVBRDZDXHVCQjM4XHVDNzc0IFx1QzYyQ1x1QkMxNFx1Qjk3NFx1QzlDMCBcdUM1NEFcdUM3NEM6IHswfS4KLSAgICBFbmRpbmdDREFUQSA9IFx1QkIzOFx1Qzc5MCBcdUMyRENcdUQwMDBcdUMyQTQgIl1dPiJcdUIyOTQgQ0RBVEEgXHVDMTM5XHVDMTU4IFx1QjA1RFx1Qzc0NCBcdUQ0NUNcdUMyRENcdUQ1NThcdUIyOTQgXHVCMzcwIFx1QzBBQ1x1QzZBOVx1QjQxOFx1QzlDMCBcdUM1NEFcdUIyOTQgXHVBQ0JEXHVDNkIwIFx1Q0Y1OFx1RDE1MFx1Q0UyMFx1QzVEMCBcdUIwOThcdUQwQzBcdUIwOThcdUM5QzAgXHVDNTRBXHVDNTQ0XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4KLSAgICBTcGxpdHRpbmdDREFUQSA9IENEQVRBIFx1QzEzOVx1QzE1OCBcdUM4ODVcdUI4Q0MgXHVENDVDXHVDMkRDXHVDNzkwICJdXT4iXHVCOTdDIFx1RDNFQ1x1RDU2OFx1RDU1OFx1QjI5NCBDREFUQSBcdUMxMzlcdUMxNThcdUM3NDQgXHVCRDg0XHVENTYwXHVENTU4XHVCMjk0IFx1QzkxMVx1Qzc4NVx1QjJDOFx1QjJFNC4KLSAgICBSZXNvdXJjZU5vdEZvdW5kID0gJyd7MH0nJyBcdUI5QUNcdUMxOENcdUMyQTRcdUI5N0MgXHVDQzNFXHVDNzQ0IFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuCi0gICAgUmVzb3VyY2VOb3RMb2FkZWQgPSAnJ3swfScnIFx1QjlBQ1x1QzE4Q1x1QzJBNFx1Qjk3QyBcdUI4NUNcdUI0RENcdUQ1NjAgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4gezF9Ci0gICAgU2VyaWFsaXphdGlvblN0b3BwZWQgPSAgXHVDMEFDXHVDNkE5XHVDNzkwIFx1QzY5NFx1Q0NBRFx1QzVEMCBcdUI1MzBcdUI3N0MgXHVDOUMxXHVCODJDXHVENjU0XHVBQzAwIFx1QzgxNVx1QzlDMFx1QjQxOFx1QzVDOFx1QzJCNVx1QjJDOFx1QjJFNC4KLQotICAgICMgRE9NIExldmVsIDMgbG9hZCBhbmQgc2F2ZSBtZXNzYWdlcwotICAgIG5vLW91dHB1dC1zcGVjaWZpZWQgPSBuby1vdXRwdXQtc3BlY2lmaWVkOiBcdUIzNzBcdUM3NzRcdUQxMzBcdUI5N0MgXHVDNEY4IFx1Q0Q5Q1x1QjgyNSBcdUIzMDBcdUMwQzFcdUM3NzQgXHVCMTEwXHVDNzg1XHVCMkM4XHVCMkU0LgotICAgIHVuc3VwcG9ydGVkLWVuY29kaW5nID0gdW5zdXBwb3J0ZWQtZW5jb2Rpbmc6IFx1QzlDMFx1QzZEMFx1QjQxOFx1QzlDMCBcdUM1NEFcdUIyOTQgXHVDNzc4XHVDRjU0XHVCNTI5XHVDNzc0IFx1QkMxQ1x1QUNBQ1x1QjQxOFx1QzVDOFx1QzJCNVx1QjJDOFx1QjJFNC4KLSAgICB1bmFibGUtdG8tc2VyaWFsaXplLW5vZGUgPSB1bmFibGUtdG8tc2VyaWFsaXplLW5vZGU6IFx1QjE3OFx1QjREQ1x1Qjk3QyBcdUM5QzFcdUI4MkNcdUQ2NTRcdUQ1NjAgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hNTFNlcmlhbGl6ZXJNZXNzYWdlc19wdF9CUi5wcm9wZXJ0aWVzIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MU2VyaWFsaXplck1lc3NhZ2VzX3B0X0JSLnByb3BlcnRpZXMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDc3M2NlMzguLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MU2VyaWFsaXplck1lc3NhZ2VzX3B0X0JSLnByb3BlcnRpZXMKKysrIC9kZXYvbnVsbApAQCAtMSwzMiArMCwwIEBACi0jIFRoaXMgZmlsZSBzdG9yZXMgZXJyb3IgbWVzc2FnZXMgZm9yIHRoZSBYZXJjZXMgWE1MCi0jIHNlcmlhbGl6ZXIuICBNYW55IERPTSBMb2FkL1NhdmUgZXJyb3IgbWVzc2FnZXMgYWxzbyAKLSMgbGl2ZSBoZXJlLCBzaW5jZSB0aGUgc2VyaWFsaXplciBsYXJnZWx5IGltcGxlbWVudHMgdGhhdCBwYWNrYWdlLgotIwotIyBBcyB1c3VhbCB3aXRoIHByb3BlcnRpZXMgZmlsZXMsIHRoZSBtZXNzYWdlcyBhcmUgYXJyYW5nZWQgaW4KLSMga2V5L3ZhbHVlIHR1cGxlcy4KLSMgCi0KLSAgICBCYWRNZXNzYWdlS2V5ID0gTlx1MDBFM28gZm9pIHBvc3NcdTAwRUR2ZWwgZW5jb250cmFyIGEgbWVuc2FnZW0gZGUgZXJybyBjb3JyZXNwb25kZW50ZSBcdTAwRTAgY2hhdmUgZGEgbWVuc2FnZW0uCi0gICAgRm9ybWF0RmFpbGVkID0gT2NvcnJldSB1bSBlcnJvIGludGVybm8gYW8gZm9ybWF0YXIgYSBtZW5zYWdlbSBhIHNlZ3VpcjpcbgotCi0gICAgQXJndW1lbnRJc051bGwgPSBPIGFyZ3VtZW50byAnJ3swfScnIFx1MDBFOSBudWxvLgotICAgIE5vV3JpdGVyU3VwcGxpZWQgPSBOZW5odW0gZ3JhdmFkb3IgZm9ybmVjaWRvIHBhcmEgbyBzZXJpYWxpemFkb3IuCi0gICAgTWV0aG9kTm90U3VwcG9ydGVkID0gTyBtXHUwMEU5dG9kbyAnJ3swfScnIG5cdTAwRTNvIFx1MDBFOSBzdXBvcnRhZG8gcG9yIGVzdGUgZmFjdG9yeS4KLSAgICBSZXNldEluTWlkZGxlID0gTyBzZXJpYWxpemFkb3Igblx1MDBFM28gcG9kZSBzZXIgcmVkZWZpbmlkbyBubyBtZWlvIGRhIHNlcmlhbGl6YVx1MDBFN1x1MDBFM28uCi0gICAgSW50ZXJuYWwgPSBFcnJvIGludGVybm86IG8gZXN0YWRvIGRvIGVsZW1lbnRvIFx1MDBFOSB6ZXJvLgotICAgIE5vTmFtZSA9IE5cdTAwRTNvIGhcdTAwRTEgcmF3TmFtZSBlIGxvY2FsTmFtZSBcdTAwRTkgbnVsby4KLSAgICBFbGVtZW50UU5hbWUgPSBPIG5vbWUgZG8gZWxlbWVudG8gJyd7MH0nJyBuXHUwMEUzbyBcdTAwRTkgdW0gUU5hbWUuCi0gICAgRWxlbWVudFByZWZpeCA9IE8gZWxlbWVudG8gJyd7MH0nJyBuXHUwMEUzbyBwZXJ0ZW5jZSBhIG5lbmh1bSBuYW1lc3BhY2U6IG8gcHJlZml4byBuXHUwMEUzbyBwb2RlIHNlciBuXHUwMEUzbyBkZWNsYXJhZG8gb3UgdmluY3VsYWRvIGEgYWxndW0gbmFtZXNwYWNlLgotICAgIEF0dHJpYnV0ZVFOYW1lID0gTyBub21lIGRvIGF0cmlidXRvICcnezB9Jycgblx1MDBFM28gXHUwMEU5IFFOYW1lLgotICAgIEF0dHJpYnV0ZVByZWZpeCA9IE8gYXRyaWJ1dG8gJyd7MH0nJyBuXHUwMEUzbyBwZXJ0ZW5jZSBhIG5lbmh1bSBuYW1lc3BhY2U6IG8gcHJlZml4byBuXHUwMEUzbyBwb2RlIHNlciBuXHUwMEUzbyBkZWNsYXJhZG8gb3UgdmluY3VsYWRvIGEgYWxndW0gbmFtZXNwYWNlLgotICAgIEludmFsaWROU0RlY2wgPSBTaW50YXhlIGRlIGRlY2xhcmFcdTAwRTdcdTAwRTNvIGRlIG5hbWVzcGFjZSBpbmNvcnJldGE6IHswfS4KLSAgICBFbmRpbmdDREFUQSA9IEEgc2VxdVx1MDBFQW5jaWEgZGUgY2FyYWN0ZXJlcyAiXV0+IiBuXHUwMEUzbyBkZXZlIGFwYXJlY2VyIG5vIGNvbnRlXHUwMEZBZG8sIGEgbWVub3MgcXVlIHNlamEgdXNhZGEgcGFyYSBtYXJjYXIgbyBmaW0gZGUgdW1hIHNlXHUwMEU3XHUwMEUzbyBDREFUQS4KLSAgICBTcGxpdHRpbmdDREFUQSA9IERpdmlkaXIgdW1hIHNlXHUwMEU3XHUwMEUzbyBDREFUQSBxdWUgY29udFx1MDBFOW0gbyBtYXJjYWRvciAiXV0+IiBkZSB0ZXJtaW5hXHUwMEU3XHUwMEUzbyBkZSBzZVx1MDBFN1x1MDBFM28gQ0RBVEEuCi0gICAgUmVzb3VyY2VOb3RGb3VuZCA9IE5cdTAwRTNvIGZvaSBwb3NzXHUwMEVEdmVsIGVuY29udHJhciBvIHJlY3Vyc28gJyd7MH0nJy4KLSAgICBSZXNvdXJjZU5vdExvYWRlZCA9IE5cdTAwRTNvIGZvaSBwb3NzXHUwMEVEdmVsIGNhcnJlZ2FyIG8gcmVjdXJzbyAnJ3swfScnLiB7MX0KLSAgICBTZXJpYWxpemF0aW9uU3RvcHBlZCA9ICBTZXJpYWxpemFcdTAwRTdcdTAwRTNvIGludGVycm9tcGlkYSBuYSBzb2xpY2l0YVx1MDBFN1x1MDBFM28gZG8gdXN1XHUwMEUxcmlvLgotCi0gICAgIyBET00gTGV2ZWwgMyBsb2FkIGFuZCBzYXZlIG1lc3NhZ2VzCi0gICAgbm8tb3V0cHV0LXNwZWNpZmllZCA9IG5lbmh1bWEgc2FcdTAwRURkYSBlc3BlY2lmaWNhZGE6IE8gZGVzdGlubyBkYSBzYVx1MDBFRGRhIGRvcyBkYWRvcyBhIHNlcmVtIGdyYXZhZG9zIGVyYSBudWxvLgotICAgIHVuc3VwcG9ydGVkLWVuY29kaW5nID0gY29kaWZpY2FcdTAwRTdcdTAwRTNvIG5cdTAwRTNvIHN1cG9ydGFkYTogVW1hIGNvZGlmaWNhXHUwMEU3XHUwMEUzbyBuXHUwMEUzbyBzdXBvcnRhZGEgZm9pIGVuY29udHJhZGEuCi0gICAgdW5hYmxlLXRvLXNlcmlhbGl6ZS1ub2RlID0gblx1MDBFM28gXHUwMEU5IHBvc3NcdTAwRUR2ZWwgc2VyaWFsaXphciBvIG5cdTAwRjM6IE5cdTAwRTNvIGZvaSBwb3NzXHUwMEVEdmVsIHNlcmlhbGl6YXIgbyBuXHUwMEYzLgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MU2VyaWFsaXplck1lc3NhZ2VzX3N2LnByb3BlcnRpZXMgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9YTUxTZXJpYWxpemVyTWVzc2FnZXNfc3YucHJvcGVydGllcwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZDM1YzE3ZC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9YTUxTZXJpYWxpemVyTWVzc2FnZXNfc3YucHJvcGVydGllcworKysgL2Rldi9udWxsCkBAIC0xLDMyICswLDAgQEAKLSMgVGhpcyBmaWxlIHN0b3JlcyBlcnJvciBtZXNzYWdlcyBmb3IgdGhlIFhlcmNlcyBYTUwKLSMgc2VyaWFsaXplci4gIE1hbnkgRE9NIExvYWQvU2F2ZSBlcnJvciBtZXNzYWdlcyBhbHNvIAotIyBsaXZlIGhlcmUsIHNpbmNlIHRoZSBzZXJpYWxpemVyIGxhcmdlbHkgaW1wbGVtZW50cyB0aGF0IHBhY2thZ2UuCi0jCi0jIEFzIHVzdWFsIHdpdGggcHJvcGVydGllcyBmaWxlcywgdGhlIG1lc3NhZ2VzIGFyZSBhcnJhbmdlZCBpbgotIyBrZXkvdmFsdWUgdHVwbGVzLgotIyAKLQotICAgIEJhZE1lc3NhZ2VLZXkgPSBIaXR0YXIgaW50ZSBmZWxtZWRkZWxhbmRldCBzb20gbW90c3ZhcmFyIG1lZGRlbGFuZGVueWNrZWxuLgotICAgIEZvcm1hdEZhaWxlZCA9IEV0dCBpbnRlcm50IGZlbCBpbnRyXHUwMEU0ZmZhZGUgdmlkIGZvcm1hdGVyaW5nIGF2IGZcdTAwRjZsamFuZGUgbWVkZGVsYW5kZTpcbgotCi0gICAgQXJndW1lbnRJc051bGwgPSBBcmd1bWVudGV0ICcnezB9JycgXHUwMEU0ciBudWxsLgotICAgIE5vV3JpdGVyU3VwcGxpZWQgPSBEZXQgZmlubnMgaW5nZW4gc2tyaXZhcmUgZlx1MDBGNnIgc2VyaWFsaXplci4KLSAgICBNZXRob2ROb3RTdXBwb3J0ZWQgPSBNZXRvZGVuICcnezB9Jycgc3RcdTAwRjZkcyBpbnRlIGkgZGVubmEgZmFicmlrc2luc3RcdTAwRTRsbG5pbmcuCi0gICAgUmVzZXRJbk1pZGRsZSA9IFNlcmlhbGl6ZXIga2FuIGludGUgXHUwMEU1dGVyc3RcdTAwRTRsbGFzIHVuZGVyIHBcdTAwRTVnXHUwMEU1ZW5kZSBzZXJpYWxpc2VyaW5nLgotICAgIEludGVybmFsID0gSW50ZXJudCBmZWw6IGVsZW1lbnR0aWxsc3RcdTAwRTVuZCBcdTAwRTRyIG5vbGwuCi0gICAgTm9OYW1lID0gRGV0IGZpbm5zIGluZ2V0IHJhd05hbWUgb2NoIGxvY2FsTmFtZSBcdTAwRTRyIG51bGwuCi0gICAgRWxlbWVudFFOYW1lID0gRWxlbWVudG5hbW5ldCAnJ3swfScnIFx1MDBFNHIgaW50ZSBuXHUwMEU1Z290IFFOYW1lLgotICAgIEVsZW1lbnRQcmVmaXggPSBFbGVtZW50ZXQgJyd7MH0nJyB0aWxsaFx1MDBGNnIgaW50ZSBuXHUwMEU1Z29uIG5hbW5yeW1kOiBwcmVmaXhldCBrYW5za2UgaW50ZSBoYXIgZGVrbGFyZXJhdHMgZWxsZXIgXHUwMEU0ciBidW5kZXQgdGlsbCBhbm5hbiBuYW1ucnltZC4KLSAgICBBdHRyaWJ1dGVRTmFtZSA9IEF0dHJpYnV0bmFtbmV0ICcnezB9JycgXHUwMEU0ciBpbnRlIG5cdTAwRTVnb3QgUU5hbWUuCi0gICAgQXR0cmlidXRlUHJlZml4ID0gQXR0cmlidXRldCAnJ3swfScnIHRpbGxoXHUwMEY2ciBpbnRlIG5cdTAwRTVnb24gbmFtbnJ5bWQ6IHByZWZpeGV0IGthbnNrZSBpbnRlIGhhciBkZWtsYXJlcmF0cyBlbGxlciBcdTAwRTRyIGJ1bmRldCB0aWxsIGFubmFuIG5hbW5yeW1kLgotICAgIEludmFsaWROU0RlY2wgPSBGZWxha3RpZyBzeW50YXggaSBkZWtsYXJhdGlvbiBhdiBuYW1ucnltZDogezB9LgotICAgIEVuZGluZ0NEQVRBID0gVGVja2Vuc2VrdmVuc2VuICJdXT4iIGZcdTAwRTVyIGludGUgZlx1MDBGNnJla29tbWEgaSBpbm5laFx1MDBFNWxsZXQsIHNcdTAwRTV2aWRhIGRldCBpbnRlIGFudlx1MDBFNG5kcyBmXHUwMEY2ciBhdHQgbWFya2VyYSBzbHV0IGF2IENEQVRBLXNla3Rpb24uCi0gICAgU3BsaXR0aW5nQ0RBVEEgPSBEZWxhciBlbiBDREFUQS1zZWt0aW9uIHNvbSBpbm5laFx1MDBFNWxsZXIgQ0RBVEEtc2VrdGlvbmVucyBhdnNsdXRuaW5nc21hcmtcdTAwRjZyICJdXT4iLgotICAgIFJlc291cmNlTm90Rm91bmQgPSBSZXN1cnNlbiAnJ3swfScnIGhpdHRhZGVzIGludGUuCi0gICAgUmVzb3VyY2VOb3RMb2FkZWQgPSBSZXN1cnNlbiAnJ3swfScnIGt1bmRlIGludGUgbGFkZGFzLiB7MX0KLSAgICBTZXJpYWxpemF0aW9uU3RvcHBlZCA9ICBTZXJpYWxpc2VyaW5nZW4gc3RvcHBhZGVzIHZpZCBhbnZcdTAwRTRuZGFyYmVnXHUwMEU0cmFuLgotCi0gICAgIyBET00gTGV2ZWwgMyBsb2FkIGFuZCBzYXZlIG1lc3NhZ2VzCi0gICAgbm8tb3V0cHV0LXNwZWNpZmllZCA9IG5vLW91dHB1dC1zcGVjaWZpZWQ6IFV0ZGF0YWRlc3RpbmF0aW9uZW4gc29tIGRhdGEgc2thIHNrcml2YXMgdGlsbCBcdTAwRTRyIG51bGwuCi0gICAgdW5zdXBwb3J0ZWQtZW5jb2RpbmcgPSB1bnN1cHBvcnRlZC1lbmNvZGluZzogRW4ga29kbmluZyBzb20gaW50ZSBzdFx1MDBGNmRzIHBcdTAwRTV0clx1MDBFNGZmYWRlcy4KLSAgICB1bmFibGUtdG8tc2VyaWFsaXplLW5vZGUgPSB1bmFibGUtdG8tc2VyaWFsaXplLW5vZGU6IE5vZGVuIGt1bmRlIGludGUgc2VyaWFsaXNlcmFzLgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MU2VyaWFsaXplck1lc3NhZ2VzX3poX0NOLnByb3BlcnRpZXMgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9YTUxTZXJpYWxpemVyTWVzc2FnZXNfemhfQ04ucHJvcGVydGllcwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggM2E3NWY2Ni4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9YTUxTZXJpYWxpemVyTWVzc2FnZXNfemhfQ04ucHJvcGVydGllcworKysgL2Rldi9udWxsCkBAIC0xLDMyICswLDAgQEAKLSMgVGhpcyBmaWxlIHN0b3JlcyBlcnJvciBtZXNzYWdlcyBmb3IgdGhlIFhlcmNlcyBYTUwKLSMgc2VyaWFsaXplci4gIE1hbnkgRE9NIExvYWQvU2F2ZSBlcnJvciBtZXNzYWdlcyBhbHNvIAotIyBsaXZlIGhlcmUsIHNpbmNlIHRoZSBzZXJpYWxpemVyIGxhcmdlbHkgaW1wbGVtZW50cyB0aGF0IHBhY2thZ2UuCi0jCi0jIEFzIHVzdWFsIHdpdGggcHJvcGVydGllcyBmaWxlcywgdGhlIG1lc3NhZ2VzIGFyZSBhcnJhbmdlZCBpbgotIyBrZXkvdmFsdWUgdHVwbGVzLgotIyAKLQotICAgIEJhZE1lc3NhZ2VLZXkgPSBcdTYyN0VcdTRFMERcdTUyMzBcdTRFMEVcdTZEODhcdTYwNkZcdTUxNzNcdTk1MkVcdTVCNTdcdTVCRjlcdTVFOTRcdTc2ODRcdTk1MTlcdThCRUZcdTZEODhcdTYwNkZcdTMwMDIKLSAgICBGb3JtYXRGYWlsZWQgPSBcdThCQkVcdTdGNkVcdTRFRTVcdTRFMEJcdTZEODhcdTYwNkZcdTc2ODRcdTY4M0NcdTVGMEZcdTY1RjZcdTUxRkFcdTczQjBcdTUxODVcdTkwRThcdTk1MTlcdThCRUY6XG4KLQotICAgIEFyZ3VtZW50SXNOdWxsID0gXHU1M0MyXHU2NTcwICcnezB9JycgXHU0RTNBXHU3QTdBXHU1MDNDXHUzMDAyCi0gICAgTm9Xcml0ZXJTdXBwbGllZCA9IFx1NkNBMVx1NjcwOVx1NEUzQVx1NEUzMlx1ODg0Q1x1NTY2OFx1NjNEMFx1NEY5Qlx1NTE5OVx1OEZEQlx1N0EwQlx1MzAwMgotICAgIE1ldGhvZE5vdFN1cHBvcnRlZCA9IFx1NkI2NFx1NURFNVx1NTM4Mlx1NEUwRFx1NjUyRlx1NjMwMVx1NjVCOVx1NkNENSAnJ3swfScnXHUzMDAyCi0gICAgUmVzZXRJbk1pZGRsZSA9IFx1NEUwRFx1ODBGRFx1NTcyOFx1NUU4Rlx1NTIxN1x1NTMxNlx1NzY4NFx1OEZDN1x1N0EwQlx1NEUyRFx1OTFDRFx1N0Y2RVx1NEUzMlx1ODg0Q1x1NTY2OFx1MzAwMgotICAgIEludGVybmFsID0gXHU1MTg1XHU5MEU4XHU5NTE5XHU4QkVGOiBcdTUxNDNcdTdEMjBcdTcyQjZcdTYwMDFcdTRFM0FcdTk2RjZcdTMwMDIKLSAgICBOb05hbWUgPSBcdTZDQTFcdTY3MDkgcmF3TmFtZSBcdTU0OEMgbG9jYWxOYW1lIFx1NEUzQVx1N0E3QVx1NTAzQ1x1MzAwMgotICAgIEVsZW1lbnRRTmFtZSA9IFx1NTE0M1x1N0QyMFx1NTQwRFx1NzlGMCAnJ3swfScnIFx1NEUwRFx1NjYyRlx1OTY1MFx1NUI5QVx1NTQwRFx1MzAwMgotICAgIEVsZW1lbnRQcmVmaXggPSBcdTUxNDNcdTdEMjAgJyd7MH0nJyBcdTRFMERcdTVDNUVcdTRFOEVcdTRFRkJcdTRGNTVcdTU0MERcdTc5RjBcdTdBN0FcdTk1RjQ6IFx1NTNFRlx1ODBGRFx1NjcyQVx1NThGMFx1NjYwRVx1NTI0RFx1N0YwMCwgXHU2MjE2XHU4MDA1XHU1REYyXHU3RUNGXHU1QzA2XHU1MjREXHU3RjAwXHU3RUQxXHU1QjlBXHU1MjMwXHU2N0QwXHU0RTJBXHU1NDBEXHU3OUYwXHU3QTdBXHU5NUY0XHUzMDAyCi0gICAgQXR0cmlidXRlUU5hbWUgPSBcdTVDNUVcdTYwMjdcdTU0MEQgJyd7MH0nJyBcdTRFMERcdTY2MkZcdTk2NTBcdTVCOUFcdTU0MERcdTMwMDIKLSAgICBBdHRyaWJ1dGVQcmVmaXggPSBcdTVDNUVcdTYwMjcgJyd7MH0nJyBcdTRFMERcdTVDNUVcdTRFOEVcdTRFRkJcdTRGNTVcdTU0MERcdTc5RjBcdTdBN0FcdTk1RjQ6IFx1NTNFRlx1ODBGRFx1NjcyQVx1NThGMFx1NjYwRVx1NTI0RFx1N0YwMCwgXHU2MjE2XHU4MDA1XHU1REYyXHU3RUNGXHU1QzA2XHU1MjREXHU3RjAwXHU3RUQxXHU1QjlBXHU1MjMwXHU2N0QwXHU0RTJBXHU1NDBEXHU3OUYwXHU3QTdBXHU5NUY0XHUzMDAyCi0gICAgSW52YWxpZE5TRGVjbCA9IFx1NTQwRFx1NzlGMFx1N0E3QVx1OTVGNFx1NThGMFx1NjYwRVx1OEJFRFx1NkNENVx1NEUwRFx1NkI2M1x1Nzg2RTogezB9XHUzMDAyCi0gICAgRW5kaW5nQ0RBVEEgPSBcdTk2NjRcdTk3NUVcdTRGN0ZcdTc1MjhcdTVCNTdcdTdCMjZcdTVFOEZcdTUyMTcgIl1dPiIgXHU2NzY1XHU2ODA3XHU4QkIwIENEQVRBIFx1ODI4Mlx1NzY4NFx1N0VEM1x1NUMzRSwgXHU1NDI2XHU1MjE5XHU4QkU1XHU1QjU3XHU3QjI2XHU1RThGXHU1MjE3XHU0RTBEXHU4MEZEXHU1MUZBXHU3M0IwXHU1NzI4XHU1MTg1XHU1QkI5XHU0RTJEXHUzMDAyCi0gICAgU3BsaXR0aW5nQ0RBVEEgPSBcdTYyQzZcdTUyMDZcdTUzMDVcdTU0MkIgQ0RBVEEgXHU2QkI1XHU3RUM4XHU2QjYyXHU2ODA3XHU4QkIwICJdXT4iIFx1NzY4NCBDREFUQSBcdTZCQjVcdTMwMDIKLSAgICBSZXNvdXJjZU5vdEZvdW5kID0gXHU2MjdFXHU0RTBEXHU1MjMwXHU4RDQ0XHU2RTkwICcnezB9JydcdTMwMDIKLSAgICBSZXNvdXJjZU5vdExvYWRlZCA9IFx1NjVFMFx1NkNENVx1NTJBMFx1OEY3RFx1OEQ0NFx1NkU5MCAnJ3swfScnXHUzMDAyezF9Ci0gICAgU2VyaWFsaXphdGlvblN0b3BwZWQgPSAgXHU2ODM5XHU2MzZFXHU3NTI4XHU2MjM3XHU4QkY3XHU2QzQyXHU1MDVDXHU2QjYyXHU0RTg2XHU1RThGXHU1MjE3XHU1MzE2XHUzMDAyCi0KLSAgICAjIERPTSBMZXZlbCAzIGxvYWQgYW5kIHNhdmUgbWVzc2FnZXMKLSAgICBuby1vdXRwdXQtc3BlY2lmaWVkID0gbm8tb3V0cHV0LXNwZWNpZmllZDogXHU4OTgxXHU1QzA2XHU2NTcwXHU2MzZFXHU1MTk5XHU1MTY1XHU3Njg0XHU4RjkzXHU1MUZBXHU3NkVFXHU2ODA3XHU0RTNBXHU3QTdBXHU1MDNDXHUzMDAyCi0gICAgdW5zdXBwb3J0ZWQtZW5jb2RpbmcgPSB1bnN1cHBvcnRlZC1lbmNvZGluZzogXHU5MDQ3XHU1MjMwXHU0RTBEXHU2NTJGXHU2MzAxXHU3Njg0XHU3RjE2XHU3ODAxXHUzMDAyCi0gICAgdW5hYmxlLXRvLXNlcmlhbGl6ZS1ub2RlID0gdW5hYmxlLXRvLXNlcmlhbGl6ZS1ub2RlOiBcdTY1RTBcdTZDRDVcdTVFOEZcdTUyMTdcdTUzMTZcdTgyODJcdTcwQjlcdTMwMDIKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hNTFNlcmlhbGl6ZXJNZXNzYWdlc196aF9UVy5wcm9wZXJ0aWVzIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MU2VyaWFsaXplck1lc3NhZ2VzX3poX1RXLnByb3BlcnRpZXMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDM0YzE2MTUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWE1MU2VyaWFsaXplck1lc3NhZ2VzX3poX1RXLnByb3BlcnRpZXMKKysrIC9kZXYvbnVsbApAQCAtMSwzMiArMCwwIEBACi0jIFRoaXMgZmlsZSBzdG9yZXMgZXJyb3IgbWVzc2FnZXMgZm9yIHRoZSBYZXJjZXMgWE1MCi0jIHNlcmlhbGl6ZXIuICBNYW55IERPTSBMb2FkL1NhdmUgZXJyb3IgbWVzc2FnZXMgYWxzbyAKLSMgbGl2ZSBoZXJlLCBzaW5jZSB0aGUgc2VyaWFsaXplciBsYXJnZWx5IGltcGxlbWVudHMgdGhhdCBwYWNrYWdlLgotIwotIyBBcyB1c3VhbCB3aXRoIHByb3BlcnRpZXMgZmlsZXMsIHRoZSBtZXNzYWdlcyBhcmUgYXJyYW5nZWQgaW4KLSMga2V5L3ZhbHVlIHR1cGxlcy4KLSMgCi0KLSAgICBCYWRNZXNzYWdlS2V5ID0gXHU2MjdFXHU0RTBEXHU1MjMwXHU1QzBEXHU2MUM5XHU4QTBBXHU2MDZGXHU3RDIyXHU1RjE1XHU5Mzc1XHU3Njg0XHU5MzJGXHU4QUE0XHU4QTBBXHU2MDZGXHUzMDAyCi0gICAgRm9ybWF0RmFpbGVkID0gXHU2ODNDXHU1RjBGXHU1MzE2XHU0RTBCXHU1MjE3XHU4QTBBXHU2MDZGXHU2NjQyXHU3NjdDXHU3NTFGXHU1MTY3XHU5MEU4XHU5MzJGXHU4QUE0OlxuCi0KLSAgICBBcmd1bWVudElzTnVsbCA9IFx1NUYxNVx1NjU3OCAnJ3swfScnIFx1NzBCQVx1N0E3QVx1NTAzQ1x1MzAwMgotICAgIE5vV3JpdGVyU3VwcGxpZWQgPSBcdTY3MkFcdTYzRDBcdTRGOUJcdTVCRUJcdTUxNjVcdTU2NjhcdTdENjZcdTVFOEZcdTUyMTdcdTUzMTZcdTdBMEJcdTVGMEZcdTMwMDIKLSAgICBNZXRob2ROb3RTdXBwb3J0ZWQgPSBcdTZCNjRcdTg2NTVcdTc0MDZcdTdBRDlcdTRFMERcdTY1MkZcdTYzRjRcdTY1QjlcdTZDRDUgJyd7MH0nJ1x1MzAwMgotICAgIFJlc2V0SW5NaWRkbGUgPSBcdTU3MjhcdTVFOEZcdTUyMTdcdTUzMTZcdTY3MUZcdTk1OTNcdTUzRUZcdTgwRkRcdTcxMjFcdTZDRDVcdTkxQ0RcdThBMkRcdTVFOEZcdTUyMTdcdTUzMTZcdTdBMEJcdTVGMEZcdTMwMDIKLSAgICBJbnRlcm5hbCA9IFx1NTE2N1x1OTBFOFx1OTMyRlx1OEFBNDogXHU1MTQzXHU3RDIwXHU3MkMwXHU2MTRCXHU3MEJBXHU5NkY2XHUzMDAyCi0gICAgTm9OYW1lID0gXHU2QzkyXHU2NzA5IHJhd05hbWUgXHU0RTE0IGxvY2FsTmFtZSBcdTcwQkFcdTdBN0FcdTUwM0NcdTMwMDIKLSAgICBFbGVtZW50UU5hbWUgPSBcdTUxNDNcdTdEMjBcdTU0MERcdTdBMzEgJyd7MH0nJyBcdTRFMERcdTY2MkYgUU5hbWVcdTMwMDIKLSAgICBFbGVtZW50UHJlZml4ID0gXHU1MTQzXHU3RDIwICcnezB9JycgXHU0RTBEXHU1QzZDXHU2NUJDXHU0RUZCXHU0RjU1XHU1NDdEXHU1NDBEXHU3QTdBXHU5NTkzOiBcdTUzRUZcdTgwRkRcdTY3MkFcdTVCQTNcdTU0NEFcdTUyNERcdTdGNkVcdTc4QkNcdTYyMTZcdTUyNERcdTdGNkVcdTc4QkNcdTkwMjNcdTdENTBcdTUxNzZcdTRFRDZcdTU0N0RcdTU0MERcdTdBN0FcdTk1OTNcdTMwMDIKLSAgICBBdHRyaWJ1dGVRTmFtZSA9IFx1NUM2Q1x1NjAyN1x1NTQwRFx1N0EzMSAnJ3swfScnIFx1NEUwRFx1NjYyRiBRTmFtZVx1MzAwMgotICAgIEF0dHJpYnV0ZVByZWZpeCA9IFx1NUM2Q1x1NjAyNyAnJ3swfScnIFx1NEUwRFx1NUM2Q1x1NjVCQ1x1NEVGQlx1NEY1NVx1NTQ3RFx1NTQwRFx1N0E3QVx1OTU5MzogXHU1M0VGXHU4MEZEXHU2NzJBXHU1QkEzXHU1NDRBXHU1MjREXHU3RjZFXHU3OEJDXHU2MjE2XHU1MjREXHU3RjZFXHU3OEJDXHU5MDIzXHU3RDUwXHU1MTc2XHU0RUQ2XHU1NDdEXHU1NDBEXHU3QTdBXHU5NTkzXHUzMDAyCi0gICAgSW52YWxpZE5TRGVjbCA9IFx1NTQ3RFx1NTQwRFx1N0E3QVx1OTU5M1x1NUJBM1x1NTQ0QVx1OEE5RVx1NkNENVx1NEUwRFx1NkI2M1x1NzhCQTogezB9XHUzMDAyCi0gICAgRW5kaW5nQ0RBVEEgPSBcdTVCNTdcdTUxNDNcdTk4MDZcdTVFOEYgIl1dPiIgXHU0RTBEXHU1M0VGXHU1MUZBXHU3M0ZFXHU1NzI4XHU1MTY3XHU1QkI5XHU0RTJEXHVGRjBDXHU5NjY0XHU5NzVFXHU3NTI4XHU2NUJDXHU2QTE5XHU3OTNBIENEQVRBIFx1NkJCNVx1ODQzRFx1NzY4NFx1N0Q1MFx1NUMzRVx1MzAwMgotICAgIFNwbGl0dGluZ0NEQVRBID0gXHU1MjA2XHU1MjcyXHU1MzA1XHU1NDJCIENEQVRBIFx1NkJCNVx1ODQzRFx1N0Q0Mlx1NkI2Mlx1NkExOVx1OEExOCAiXV0+IiBcdTc2ODQgQ0RBVEEgXHU2QkI1XHU4NDNEXHUzMDAyCi0gICAgUmVzb3VyY2VOb3RGb3VuZCA9IFx1NjI3RVx1NEUwRFx1NTIzMFx1OENDN1x1NkU5MCAnJ3swfScnXHUzMDAyCi0gICAgUmVzb3VyY2VOb3RMb2FkZWQgPSBcdTcxMjFcdTZDRDVcdThGMDlcdTUxNjVcdThDQzdcdTZFOTAgJyd7MH0nJ1x1MzAwMnsxfQotICAgIFNlcmlhbGl6YXRpb25TdG9wcGVkID0gIFx1NEY5RFx1NzE2N1x1NEY3Rlx1NzUyOFx1ODAwNVx1ODk4MVx1NkM0Mlx1NTA1Q1x1NkI2Mlx1NUU4Rlx1NTIxN1x1NTMxNlx1MzAwMgotCi0gICAgIyBET00gTGV2ZWwgMyBsb2FkIGFuZCBzYXZlIG1lc3NhZ2VzCi0gICAgbm8tb3V0cHV0LXNwZWNpZmllZCA9IG5vLW91dHB1dC1zcGVjaWZpZWQ6IFx1ODk4MVx1NUJFQlx1NTE2NVx1OENDN1x1NjU5OVx1NzY4NFx1OEYzOFx1NTFGQVx1NzZFRVx1NzY4NFx1NTczMFx1NzBCQVx1N0E3QVx1NTAzQ1x1MzAwMgotICAgIHVuc3VwcG9ydGVkLWVuY29kaW5nID0gdW5zdXBwb3J0ZWQtZW5jb2Rpbmc6IFx1NTFGQVx1NzNGRVx1NEUwRFx1NjUyRlx1NjNGNFx1NzY4NFx1N0RFOFx1NzhCQ1x1MzAwMgotICAgIHVuYWJsZS10by1zZXJpYWxpemUtbm9kZSA9IHVuYWJsZS10by1zZXJpYWxpemUtbm9kZTogXHU3QkMwXHU5RURFXHU3MTIxXHU2Q0Q1XHU1RThGXHU1MjE3XHU1MzE2XHUzMDAyCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9YUG9pbnRlck1lc3NhZ2VzLnByb3BlcnRpZXMgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9YUG9pbnRlck1lc3NhZ2VzLnByb3BlcnRpZXMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGViZTQ4NzguLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWFBvaW50ZXJNZXNzYWdlcy5wcm9wZXJ0aWVzCisrKyAvZGV2L251bGwKQEAgLTEsMjYgKzAsMCBAQAotIyBUaGlzIGZpbGUgc3RvcmVzIGxvY2FsaXplZCBtZXNzYWdlcyBmb3IgdGhlIFhlcmNlcyBYUG9pbnRlciBpbXBsZW1lbnRhdGlvbi4KLSMKLSMgVGhlIG1lc3NhZ2VzIGFyZSBhcnJhbmdlZCBpbiBrZXkgYW5kIHZhbHVlIHR1cGxlcyBpbiBhIExpc3RSZXNvdXJjZUJ1bmRsZS4KLSMKLQotIyBNZXNzYWdlcyBmb3IgbWVzc2FnZSByZXBvcnRpbmcKLUJhZE1lc3NhZ2VLZXkgPSBUaGUgZXJyb3IgbWVzc2FnZSBjb3JyZXNwb25kaW5nIHRvIHRoZSBtZXNzYWdlIGtleSBjYW4gbm90IGJlIGZvdW5kLgotRm9ybWF0RmFpbGVkID0gQW4gaW50ZXJuYWwgZXJyb3Igb2NjdXJyZWQgd2hpbGUgZm9ybWF0dGluZyB0aGUgZm9sbG93aW5nIG1lc3NhZ2U6XG4gIAotCi0jIFhQb2ludGVyIEZyYW1ld29yayBFcnJvciBNZXNzYWdlcwotWFBvaW50ZXJQcm9jZXNzaW5nRXJyb3IgPSBYUG9pbnRlclByb2Nlc3NpbmdFcnJvcjogQW4gZXJyb3Igb2NjdXJyZWQgd2hpbGUgcHJvY2Vzc2luZyB0aGUgWFBvaW50ZXIgZXhwcmVzc2lvbi4KLUludmFsaWRYUG9pbnRlclRva2VuID0gSW52YWxpZFhQb2ludGVyVG9rZW46IFRoZSBYUG9pbnRlciBleHByZXNzaW9uIGNvbnRhaW5zIHRoZSBpbnZhbGlkIHRva2VuICcnezB9JycKLUludmFsaWRYUG9pbnRlckV4cHJlc3Npb24gPSBJbnZhbGlkWFBvaW50ZXJFeHByZXNzaW9uOiBUaGUgWFBvaW50ZXIgZXhwcmVzc2lvbiAnJ3swfScnIGlzIGludmFsaWQuCi1NdWx0aXBsZVNob3J0SGFuZFBvaW50ZXJzID0gTXVsdGlwbGVTaG9ydEhhbmRQb2ludGVyczogIFRoZSBYUG9pbnRlciBleHByZXNzaW9uICcnezB9JycgaXMgaW52YWxpZC4gIEl0IGhhcyBtb3JlIHRoYW4gb25lIFNob3J0SGFuZCBQb2ludGVyLiAKLVNjaGVtZURhdGFOb3RGb2xsb3dlZEJ5Q2xvc2VQYXJlbnRoZXNpcyA9IFNjaGVtZURhdGFOb3RGb2xsb3dlZEJ5Q2xvc2VQYXJlbnRoZXNpczogVGhlIFhQb2ludGVyIGV4cHJlc3Npb24gJyd7MH0nJyBpcyBpbnZhbGlkLiAgVGhlIFNjaGVtZURhdGEgd2FzIG5vdCBmb2xsb3dlZCBieSBhICcnKScnIGNoYXJhY3Rlci4gCi1TY2hlbWVVbnN1cHBvcnRlZCA9IFNjaGVtZVVuc3VwcG9ydGVkOiBUaGUgWFBvaW50ZXIgc2NoZW1lICcnezB9JycgaXMgbm90IHN1cHBvcnRlZC4KLUludmFsaWRTaG9ydEhhbmRQb2ludGVyID0gSW52YWxpZFNob3J0SGFuZFBvaW50ZXI6IFRoZSBOQ05hbWUgb2YgdGhlIFNob3J0SGFuZCBQb2ludGVyICcnezB9JycgaXMgaW52YWxpZC4KLVVuYmFsYW5jZWRQYXJlbnRoZXNpc0luWFBvaW50ZXJFeHByZXNzaW9uID0gVW5iYWxhbmNlZFBhcmVudGhlc2lzSW5YUG9pbnRlckV4cHJlc3Npb246IFRoZSBYUG9pbnRlciBleHByZXNzaW9uICcnezB9JycgaXMgaW52YWxpZC4gIFRoZSBudW1iZXIgb2Ygb3BlbiBwYXJlbnRoZXNpcyAnJ3sxfScnIGlzIG5vdCBlcXVhbCB0byB0aGUgbnVtYmVyIG9mIGNsb3NlIHBhcmVudGhlc2lzICcnezJ9JycuCi1JbnZhbGlkU2NoZW1lRGF0YUluWFBvaW50ZXIgPSBJbnZhbGlkU2NoZW1lRGF0YUluWFBvaW50ZXI6IFRoZSBYUG9pbnRlciBleHByZXNzaW9uICcnezB9JycgY29udGFpbnMgaW52YWxpZCBTY2hlbWVEYXRhLgotCi0jIFhQb2ludGVyIEVsZW1lbnQgU2NoZW1lIEVycm9yIE1lc3NhZ2VzCi1JbnZhbGlkRWxlbWVudFNjaGVtZVRva2VuID0gSW52YWxpZEVsZW1lbnRTY2hlbWVUb2tlbjogVGhlIGVsZW1lbnQoKSBzY2hlbWUgWFBvaW50ZXIgZXhwcmVzc2lvbiBjb250YWlucyB0aGUgaW52YWxpZCB0b2tlbiAnJ3swfScnCi1JbnZhbGlkRWxlbWVudFNjaGVtZVhQb2ludGVyID0gSW52YWxpZEVsZW1lbnRTY2hlbWVYUG9pbnRlcjogVGhlIEVsZW1lbnQgU2NoZW1lIFhQb2ludGVyIGV4cHJlc3Npb24gJyd7MH0nJyBpcyBpbnZhbGlkLgotWFBvaW50ZXJFbGVtZW50U2NoZW1lUHJvY2Vzc2luZ0Vycm9yID0gWFBvaW50ZXJFbGVtZW50U2NoZW1lUHJvY2Vzc2luZ0Vycm9yOiBBbiBlcnJvciBvY2N1cnJlZCB3aGlsZSBwcm9jZXNzaW5nIHRoZSBYUG9pbnRlciBlbGVtZW50KCkgU2NoZW1lIGV4cHJlc3Npb24uCi1JbnZhbGlkTkNOYW1lSW5FbGVtZW50U2NoZW1lRGF0YSA9IEludmFsaWROQ05hbWVJbkVsZW1lbnRTY2hlbWVEYXRhOiBUaGUgZWxlbWVudCgpIFNjaGVtZSBjb250YWlucyBhIFNob3J0SGFuZCBQb2ludGVyICcnezB9Jycgd2l0aCBhbiBpbnZhbGlkIE5DTmFtZS4KLUludmFsaWRDaGlsZFNlcXVlbmNlQ2hhcmFjdGVyID0gSW52YWxpZENoaWxkU2VxdWVuY2VDaGFyYWN0ZXI6IFRoZSBlbGVtZW50KCkgU2NoZW1lIGNvbnRhaW5zIGFuIGludmFsaWQgY2hpbGQgc2VxdWVuY2UgY2hhcmFjdGVyICcnezB9JycuIApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWFBvaW50ZXJNZXNzYWdlc19kZS5wcm9wZXJ0aWVzIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWFBvaW50ZXJNZXNzYWdlc19kZS5wcm9wZXJ0aWVzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhNTY3MTdmLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hQb2ludGVyTWVzc2FnZXNfZGUucHJvcGVydGllcworKysgL2Rldi9udWxsCkBAIC0xLDI2ICswLDAgQEAKLSMgVGhpcyBmaWxlIHN0b3JlcyBsb2NhbGl6ZWQgbWVzc2FnZXMgZm9yIHRoZSBYZXJjZXMgWFBvaW50ZXIgaW1wbGVtZW50YXRpb24uCi0jCi0jIFRoZSBtZXNzYWdlcyBhcmUgYXJyYW5nZWQgaW4ga2V5IGFuZCB2YWx1ZSB0dXBsZXMgaW4gYSBMaXN0UmVzb3VyY2VCdW5kbGUuCi0jCi0KLSMgTWVzc2FnZXMgZm9yIG1lc3NhZ2UgcmVwb3J0aW5nCi1CYWRNZXNzYWdlS2V5ID0gRGllIHp1bSBNZWxkdW5nc3NjaGxcdTAwRkNzc2VsIGdlaFx1MDBGNnJpZ2UgRmVobGVybWVsZHVuZyBrYW5uIG5pY2h0IGdlZnVuZGVuIHdlcmRlbi4KLUZvcm1hdEZhaWxlZCA9IEJlaW0gRm9ybWF0aWVyZW4gZGVyIGZvbGdlbmRlbiBNZWxkdW5nIGlzdCBlaW4gaW50ZXJuZXIgRmVobGVyIGF1ZmdldHJldGVuOlxuICAKLQotIyBYUG9pbnRlciBGcmFtZXdvcmsgRXJyb3IgTWVzc2FnZXMKLVhQb2ludGVyUHJvY2Vzc2luZ0Vycm9yID0gWFBvaW50ZXJQcm9jZXNzaW5nRXJyb3I6IEJlaW0gVmVyYXJiZWl0ZW4gZGVzIFhQb2ludGVyLUF1c2RydWNrcyBpc3QgZWluIEZlaGxlciBhdWZnZXRyZXRlbi4KLUludmFsaWRYUG9pbnRlclRva2VuID0gSW52YWxpZFhQb2ludGVyVG9rZW46IFhQb2ludGVyLUF1c2RydWNrIGVudGhcdTAwRTRsdCBkYXMgdW5nXHUwMEZDbHRpZ2UgVG9rZW4gInswfSIKLUludmFsaWRYUG9pbnRlckV4cHJlc3Npb24gPSBJbnZhbGlkWFBvaW50ZXJFeHByZXNzaW9uOiBYUG9pbnRlci1BdXNkcnVjayAiezB9IiBpc3QgdW5nXHUwMEZDbHRpZy4KLU11bHRpcGxlU2hvcnRIYW5kUG9pbnRlcnMgPSBNdWx0aXBsZVNob3J0SGFuZFBvaW50ZXJzOiBYUG9pbnRlci1BdXNkcnVjayAiezB9IiBpc3QgdW5nXHUwMEZDbHRpZy4gTWVocmVyZSBTaG9ydEhhbmQtWmVpZ2VyIHZvcmhhbmRlbi4KLVNjaGVtZURhdGFOb3RGb2xsb3dlZEJ5Q2xvc2VQYXJlbnRoZXNpcyA9IFNjaGVtZURhdGFOb3RGb2xsb3dlZEJ5Q2xvc2VQYXJlbnRoZXNpczogWFBvaW50ZXItQXVzZHJ1Y2sgInswfSIgaXN0IHVuZ1x1MDBGQ2x0aWcuIEF1ZiBTY2hlbWVEYXRhIGZvbGd0ZSBrZWluICIpIi1aZWljaGVuLiAKLVNjaGVtZVVuc3VwcG9ydGVkID0gU2NoZW1lVW5zdXBwb3J0ZWQ6IFhQb2ludGVyLVNjaGVtYSAiezB9IiB3aXJkIG5pY2h0IHVudGVyc3RcdTAwRkN0enQuCi1JbnZhbGlkU2hvcnRIYW5kUG9pbnRlciA9IEludmFsaWRTaG9ydEhhbmRQb2ludGVyOiBOQ05hbWUgdm9uIFNob3J0SGFuZC1aZWlnZXIgInswfSIgaXN0IHVuZ1x1MDBGQ2x0aWcuCi1VbmJhbGFuY2VkUGFyZW50aGVzaXNJblhQb2ludGVyRXhwcmVzc2lvbiA9IFVuYmFsYW5jZWRQYXJlbnRoZXNpc0luWFBvaW50ZXJFeHByZXNzaW9uOiBYUG9pbnRlci1BdXNkcnVjayAiezB9IiBpc3QgdW5nXHUwMEZDbHRpZy4gRGllIEFuemFobCBkZXIgXHUwMEY2ZmZuZW5kZW4gS2xhbW1lcm4gInsxfSIgZW50c3ByaWNodCBuaWNodCBkZXIgQW56YWhsIGRlciBzY2hsaWVcdTAwREZlbmRlbiBLbGFtbWVybiAiezJ9Ii4KLUludmFsaWRTY2hlbWVEYXRhSW5YUG9pbnRlciA9IEludmFsaWRTY2hlbWVEYXRhSW5YUG9pbnRlcjogWFBvaW50ZXItQXVzZHJ1Y2sgInswfSIgZW50aGFsdCB1bmdcdTAwRkNsdGlnZSBTY2hlbWVEYXRhLgotCi0jIFhQb2ludGVyIEVsZW1lbnQgU2NoZW1lIEVycm9yIE1lc3NhZ2VzCi1JbnZhbGlkRWxlbWVudFNjaGVtZVRva2VuID0gSW52YWxpZEVsZW1lbnRTY2hlbWVUb2tlbjogZWxlbWVudCgpLVNjaGVtYS1YUG9pbnRlci1BdXNkcnVjayBlbnRoXHUwMEU0bHQgZGFzIHVuZ1x1MDBGQ2x0aWdlIFRva2VuICJ7MH0iCi1JbnZhbGlkRWxlbWVudFNjaGVtZVhQb2ludGVyID0gSW52YWxpZEVsZW1lbnRTY2hlbWVYUG9pbnRlcjogRWxlbWVudHNjaGVtYS1YUG9pbnRlci1BdXNkcnVjayAiezB9IiBpc3QgdW5nXHUwMEZDbHRpZy4KLVhQb2ludGVyRWxlbWVudFNjaGVtZVByb2Nlc3NpbmdFcnJvciA9IFhQb2ludGVyRWxlbWVudFNjaGVtZVByb2Nlc3NpbmdFcnJvcjogQmVpbSBWZXJhcmJlaXRlbiBkZXMgWFBvaW50ZXItZWxlbWVudCgpLVNjaGVtYWF1c2RydWNrcyBpc3QgZWluIEZlaGxlciBhdWZnZXRyZXRlbi4KLUludmFsaWROQ05hbWVJbkVsZW1lbnRTY2hlbWVEYXRhID0gSW52YWxpZE5DTmFtZUluRWxlbWVudFNjaGVtZURhdGE6IGVsZW1lbnQoKS1TY2hlbWEgZW50aFx1MDBFNGx0IGVpbmVuIFNob3J0SGFuZC1aZWlnZXIgInswfSIgbWl0IGVpbmVtIHVuZ1x1MDBGQ2x0aWdlbiBOQ05hbWUuCi1JbnZhbGlkQ2hpbGRTZXF1ZW5jZUNoYXJhY3RlciA9IEludmFsaWRDaGlsZFNlcXVlbmNlQ2hhcmFjdGVyOiBlbGVtZW50KCktU2NoZW1hIGVudGhcdTAwRTRsdCBlaW4gdW50ZXJnZW9yZG5ldGVzIFNlcXVlbnp6ZWljaGVuICJ7MH0iLiAKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hQb2ludGVyTWVzc2FnZXNfZXMucHJvcGVydGllcyBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hQb2ludGVyTWVzc2FnZXNfZXMucHJvcGVydGllcwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZTc3MGZkYy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9YUG9pbnRlck1lc3NhZ2VzX2VzLnByb3BlcnRpZXMKKysrIC9kZXYvbnVsbApAQCAtMSwyNiArMCwwIEBACi0jIFRoaXMgZmlsZSBzdG9yZXMgbG9jYWxpemVkIG1lc3NhZ2VzIGZvciB0aGUgWGVyY2VzIFhQb2ludGVyIGltcGxlbWVudGF0aW9uLgotIwotIyBUaGUgbWVzc2FnZXMgYXJlIGFycmFuZ2VkIGluIGtleSBhbmQgdmFsdWUgdHVwbGVzIGluIGEgTGlzdFJlc291cmNlQnVuZGxlLgotIwotCi0jIE1lc3NhZ2VzIGZvciBtZXNzYWdlIHJlcG9ydGluZwotQmFkTWVzc2FnZUtleSA9IE5vIHNlIGhhIGVuY29udHJhZG8gZWwgbWVuc2FqZSBkZSBlcnJvciBxdWUgY29ycmVzcG9uZGUgYSBsYSBjbGF2ZSBkZSBtZW5zYWplLgotRm9ybWF0RmFpbGVkID0gU2UgaGEgcHJvZHVjaWRvIHVuIGVycm9yIGludGVybm8gYWwgZm9ybWF0ZWFyIGVsIHNpZ3VpZW50ZSBtZW5zYWplOlxuICAKLQotIyBYUG9pbnRlciBGcmFtZXdvcmsgRXJyb3IgTWVzc2FnZXMKLVhQb2ludGVyUHJvY2Vzc2luZ0Vycm9yID0gWFBvaW50ZXJQcm9jZXNzaW5nRXJyb3I6IFNlIGhhIHByb2R1Y2lkbyB1biBlcnJvciBhbCBwcm9jZXNhciBsYSBleHByZXNpXHUwMEYzbiBYUG9pbnRlci4KLUludmFsaWRYUG9pbnRlclRva2VuID0gSW52YWxpZFhQb2ludGVyVG9rZW46IExhIGV4cHJlc2lcdTAwRjNuIFhQb2ludGVyIGNvbnRpZW5lIGVsIHRva2VuIG5vIHZcdTAwRTFsaWRvICcnezB9JycKLUludmFsaWRYUG9pbnRlckV4cHJlc3Npb24gPSBJbnZhbGlkWFBvaW50ZXJFeHByZXNzaW9uOiBMYSBleHByZXNpXHUwMEYzbiBYUG9pbnRlciAnJ3swfScnIG5vIGVzIHZcdTAwRTFsaWRhLgotTXVsdGlwbGVTaG9ydEhhbmRQb2ludGVycyA9IE11bHRpcGxlU2hvcnRIYW5kUG9pbnRlcnM6ICBMYSBleHByZXNpXHUwMEYzbiBYUG9pbnRlciAnJ3swfScnIG5vIGVzIHZcdTAwRTFsaWRhLiBUaWVuZSBtXHUwMEUxcyBkZSB1biBwdW50ZXJvIGFicmV2aWFkby4gCi1TY2hlbWVEYXRhTm90Rm9sbG93ZWRCeUNsb3NlUGFyZW50aGVzaXMgPSBTY2hlbWVEYXRhTm90Rm9sbG93ZWRCeUNsb3NlUGFyZW50aGVzaXM6IExhIGV4cHJlc2lcdTAwRjNuIFhQb2ludGVyICcnezB9Jycgbm8gZXMgdlx1MDBFMWxpZGEuIFNjaGVtZURhdGEgbm8gdmllbmUgc2VndWlkbyBkZSB1biBjYXJcdTAwRTFjdGVyICcnKScnLiAKLVNjaGVtZVVuc3VwcG9ydGVkID0gU2NoZW1lVW5zdXBwb3J0ZWQ6IEVsIGVzcXVlbWEgWFBvaW50ZXIgJyd7MH0nJyBubyBlc3RcdTAwRTEgc29wb3J0YWRvLgotSW52YWxpZFNob3J0SGFuZFBvaW50ZXIgPSBJbnZhbGlkU2hvcnRIYW5kUG9pbnRlcjogRWwgdmFsb3IgZGUgTkNOYW1lIGRlbCBwdW50ZXJvIGFicmV2aWFkbyAnJ3swfScnIG5vIGVzIHZcdTAwRTFsaWRvLgotVW5iYWxhbmNlZFBhcmVudGhlc2lzSW5YUG9pbnRlckV4cHJlc3Npb24gPSBVbmJhbGFuY2VkUGFyZW50aGVzaXNJblhQb2ludGVyRXhwcmVzc2lvbjogTGEgZXhwcmVzaVx1MDBGM24gWFBvaW50ZXIgJyd7MH0nJyBubyBlcyB2XHUwMEUxbGlkYS4gRWwgblx1MDBGQW1lcm8gZGUgcGFyXHUwMEU5bnRlc2lzIGRlIGFwZXJ0dXJhICcnezF9Jycgbm8gZXMgaWd1YWwgYWwgblx1MDBGQW1lcm8gZGUgcGFyXHUwMEU5bnRlc2lzIGRlIGNpZXJyZSAnJ3syfScnLgotSW52YWxpZFNjaGVtZURhdGFJblhQb2ludGVyID0gSW52YWxpZFNjaGVtZURhdGFJblhQb2ludGVyOiBMYSBleHByZXNpXHUwMEYzbiBYUG9pbnRlciAnJ3swfScnIGNvbnRpZW5lIHVuIHZhbG9yIGRlIFNjaGVtZURhdGEgbm8gdlx1MDBFMWxpZG8uCi0KLSMgWFBvaW50ZXIgRWxlbWVudCBTY2hlbWUgRXJyb3IgTWVzc2FnZXMKLUludmFsaWRFbGVtZW50U2NoZW1lVG9rZW4gPSBJbnZhbGlkRWxlbWVudFNjaGVtZVRva2VuOiBMYSBleHByZXNpXHUwMEYzbiBYUG9pbnRlciBkZWwgZXNxdWVtYSBkZSBlbGVtZW50KCkgY29udGllbmUgZWwgdG9rZW4gbm8gdlx1MDBFMWxpZG8gJyd7MH0nJwotSW52YWxpZEVsZW1lbnRTY2hlbWVYUG9pbnRlciA9IEludmFsaWRFbGVtZW50U2NoZW1lWFBvaW50ZXI6IExhIGV4cHJlc2lcdTAwRjNuIFhQb2ludGVyIGRlbCBlc3F1ZW1hIGRlIGVsZW1lbnRvICcnezB9Jycgbm8gZXMgdlx1MDBFMWxpZGEuCi1YUG9pbnRlckVsZW1lbnRTY2hlbWVQcm9jZXNzaW5nRXJyb3IgPSBYUG9pbnRlckVsZW1lbnRTY2hlbWVQcm9jZXNzaW5nRXJyb3I6IFNlIGhhIHByb2R1Y2lkbyB1biBlcnJvciBhbCBwcm9jZXNhciBsYSBleHByZXNpXHUwMEYzbiBkZSBlc3F1ZW1hIFhQb2ludGVyIGVsZW1lbnQoKS4KLUludmFsaWROQ05hbWVJbkVsZW1lbnRTY2hlbWVEYXRhID0gSW52YWxpZE5DTmFtZUluRWxlbWVudFNjaGVtZURhdGE6IEVsIGVzcXVlbWEgZWxlbWVudCgpIGNvbnRpZW5lIHVuIHB1bnRlcm8gYWJyZXZpYWRvICcnezB9JycgY29uIHVuIHZhbG9yIGRlIE5DTmFtZSBubyB2XHUwMEUxbGlkby4KLUludmFsaWRDaGlsZFNlcXVlbmNlQ2hhcmFjdGVyID0gSW52YWxpZENoaWxkU2VxdWVuY2VDaGFyYWN0ZXI6IEVsIGVzcXVlbWEgZWxlbWVudCgpIGNvbnRpZW5lIHVuIGNhclx1MDBFMWN0ZXIgZGUgc2VjdWVuY2lhIHNlY3VuZGFyaWEgbm8gdlx1MDBFMWxpZG8gJyd7MH0nJy4gCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9YUG9pbnRlck1lc3NhZ2VzX2ZyLnByb3BlcnRpZXMgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9YUG9pbnRlck1lc3NhZ2VzX2ZyLnByb3BlcnRpZXMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGQyZDkzMzguLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWFBvaW50ZXJNZXNzYWdlc19mci5wcm9wZXJ0aWVzCisrKyAvZGV2L251bGwKQEAgLTEsMjYgKzAsMCBAQAotIyBUaGlzIGZpbGUgc3RvcmVzIGxvY2FsaXplZCBtZXNzYWdlcyBmb3IgdGhlIFhlcmNlcyBYUG9pbnRlciBpbXBsZW1lbnRhdGlvbi4KLSMKLSMgVGhlIG1lc3NhZ2VzIGFyZSBhcnJhbmdlZCBpbiBrZXkgYW5kIHZhbHVlIHR1cGxlcyBpbiBhIExpc3RSZXNvdXJjZUJ1bmRsZS4KLSMKLQotIyBNZXNzYWdlcyBmb3IgbWVzc2FnZSByZXBvcnRpbmcKLUJhZE1lc3NhZ2VLZXkgPSBMZSBtZXNzYWdlIGQnZXJyZXVyIGNvcnJlc3BvbmRhbnQgXHUwMEUwIGxhIGNsXHUwMEU5IGRlIG1lc3NhZ2UgZXN0IGludHJvdXZhYmxlLgotRm9ybWF0RmFpbGVkID0gVW5lIGVycmV1ciBpbnRlcm5lIGVzdCBzdXJ2ZW51ZSBsb3JzIGRlIGxhIG1pc2UgZW4gZm9ybWUgZHUgbWVzc2FnZSBzdWl2YW50IDpcbiAgCi0KLSMgWFBvaW50ZXIgRnJhbWV3b3JrIEVycm9yIE1lc3NhZ2VzCi1YUG9pbnRlclByb2Nlc3NpbmdFcnJvciA9IFhQb2ludGVyUHJvY2Vzc2luZ0Vycm9yIDogdW5lIGVycmV1ciBlc3Qgc3VydmVudWUgbG9ycyBkdSB0cmFpdGVtZW50IGRlIGwnZXhwcmVzc2lvbiBYUG9pbnRlci4KLUludmFsaWRYUG9pbnRlclRva2VuID0gSW52YWxpZFhQb2ludGVyVG9rZW4gOiBsJydleHByZXNzaW9uIFhQb2ludGVyIGNvbnRpZW50IGxlIGpldG9uIG5vbiB2YWxpZGUgJyd7MH0nJwotSW52YWxpZFhQb2ludGVyRXhwcmVzc2lvbiA9IEludmFsaWRYUG9pbnRlckV4cHJlc3Npb24gOiBsJydleHByZXNzaW9uIFhQb2ludGVyICcnezB9JycgbicnZXN0IHBhcyB2YWxpZGUuCi1NdWx0aXBsZVNob3J0SGFuZFBvaW50ZXJzID0gTXVsdGlwbGVTaG9ydEhhbmRQb2ludGVycyA6IGwnJ2V4cHJlc3Npb24gWFBvaW50ZXIgJyd7MH0nJyBuJydlc3QgcGFzIHZhbGlkZS4gRWxsZSBjb250aWVudCBwbHVzaWV1cnMgcG9pbnRldXJzIFNob3J0SGFuZC4gCi1TY2hlbWVEYXRhTm90Rm9sbG93ZWRCeUNsb3NlUGFyZW50aGVzaXMgPSBTY2hlbWVEYXRhTm90Rm9sbG93ZWRCeUNsb3NlUGFyZW50aGVzaXMgOiBsJydleHByZXNzaW9uIFhQb2ludGVyICcnezB9JycgbicnZXN0IHBhcyB2YWxpZGUuIEwnJ1x1MDBFOWxcdTAwRTltZW50IFNjaGVtZURhdGEgbicnZXN0IHBhcyBzdWl2aSBkJyd1biBjYXJhY3RcdTAwRThyZSAnJyknJy4gCi1TY2hlbWVVbnN1cHBvcnRlZCA9IFNjaGVtZVVuc3VwcG9ydGVkIDogbGUgcHJvY2Vzc3VzIFhQb2ludGVyICcnezB9JycgbicnZXN0IHBhcyBwcmlzIGVuIGNoYXJnZS4KLUludmFsaWRTaG9ydEhhbmRQb2ludGVyID0gSW52YWxpZFNob3J0SGFuZFBvaW50ZXIgOiBsZSBOQ05hbWUgZHUgcG9pbnRldXIgU2hvcnRIYW5kICcnezB9JycgbicnZXN0IHBhcyB2YWxpZGUuCi1VbmJhbGFuY2VkUGFyZW50aGVzaXNJblhQb2ludGVyRXhwcmVzc2lvbiA9IFVuYmFsYW5jZWRQYXJlbnRoZXNpc0luWFBvaW50ZXJFeHByZXNzaW9uIDogbCcnZXhwcmVzc2lvbiBYUG9pbnRlciAnJ3swfScnIG4nJ2VzdCBwYXMgdmFsaWRlLiBMZSBub21icmUgZGUgcGFyZW50aFx1MDBFOHNlcyBvdXZyYW50ZXMgJyd7MX0nJyBlc3QgZGlmZlx1MDBFOXJlbnQgZHUgbm9tYnJlIGRlIHBhcmVudGhcdTAwRThzZXMgZmVybWFudGVzICcnezJ9JycuCi1JbnZhbGlkU2NoZW1lRGF0YUluWFBvaW50ZXIgPSBJbnZhbGlkU2NoZW1lRGF0YUluWFBvaW50ZXIgOiBsJydleHByZXNzaW9uIFhQb2ludGVyICcnezB9JycgY29udGllbnQgdW4gXHUwMEU5bFx1MDBFOW1lbnQgU2NoZW1lRGF0YSBub24gdmFsaWRlLgotCi0jIFhQb2ludGVyIEVsZW1lbnQgU2NoZW1lIEVycm9yIE1lc3NhZ2VzCi1JbnZhbGlkRWxlbWVudFNjaGVtZVRva2VuID0gSW52YWxpZEVsZW1lbnRTY2hlbWVUb2tlbiA6IGwnJ2V4cHJlc3Npb24gWFBvaW50ZXIgZHUgcHJvY2Vzc3VzIGVsZW1lbnQoKSBjb250aWVudCBsZSBqZXRvbiBub24gdmFsaWRlICcnezB9JycKLUludmFsaWRFbGVtZW50U2NoZW1lWFBvaW50ZXIgPSBJbnZhbGlkRWxlbWVudFNjaGVtZVhQb2ludGVyIDogbCcnZXhwcmVzc2lvbiBYUG9pbnRlciBkZSBwcm9jZXNzdXMgZCcnXHUwMEU5bFx1MDBFOW1lbnQgJyd7MH0nJyBuJydlc3QgcGFzIHZhbGlkZS4KLVhQb2ludGVyRWxlbWVudFNjaGVtZVByb2Nlc3NpbmdFcnJvciA9IFhQb2ludGVyRWxlbWVudFNjaGVtZVByb2Nlc3NpbmdFcnJvciA6IHVuZSBlcnJldXIgZXN0IHN1cnZlbnVlIGxvcnMgZHUgdHJhaXRlbWVudCBkZSBsJ2V4cHJlc3Npb24gZGUgcHJvY2Vzc3VzIGVsZW1lbnQoKSBYUG9pbnRlci4KLUludmFsaWROQ05hbWVJbkVsZW1lbnRTY2hlbWVEYXRhID0gSW52YWxpZE5DTmFtZUluRWxlbWVudFNjaGVtZURhdGEgOiBsZSBwcm9jZXNzdXMgZWxlbWVudCgpIGNvbnRpZW50IHVuIHBvaW50ZXVyIFNob3J0SGFuZCAnJ3swfScnIGF2ZWMgdW4gTkNOYW1lIG5vbiB2YWxpZGUuCi1JbnZhbGlkQ2hpbGRTZXF1ZW5jZUNoYXJhY3RlciA9IEludmFsaWRDaGlsZFNlcXVlbmNlQ2hhcmFjdGVyIDogbGUgcHJvY2Vzc3VzIGVsZW1lbnQoKSBjb250aWVudCB1biBjYXJhY3RcdTAwRThyZSBkZSBzXHUwMEU5cXVlbmNlIGVuZmFudCBub24gdmFsaWRlICcnezB9JycuIApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWFBvaW50ZXJNZXNzYWdlc19pdC5wcm9wZXJ0aWVzIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWFBvaW50ZXJNZXNzYWdlc19pdC5wcm9wZXJ0aWVzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0YjI0NWI3Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hQb2ludGVyTWVzc2FnZXNfaXQucHJvcGVydGllcworKysgL2Rldi9udWxsCkBAIC0xLDI2ICswLDAgQEAKLSMgVGhpcyBmaWxlIHN0b3JlcyBsb2NhbGl6ZWQgbWVzc2FnZXMgZm9yIHRoZSBYZXJjZXMgWFBvaW50ZXIgaW1wbGVtZW50YXRpb24uCi0jCi0jIFRoZSBtZXNzYWdlcyBhcmUgYXJyYW5nZWQgaW4ga2V5IGFuZCB2YWx1ZSB0dXBsZXMgaW4gYSBMaXN0UmVzb3VyY2VCdW5kbGUuCi0jCi0KLSMgTWVzc2FnZXMgZm9yIG1lc3NhZ2UgcmVwb3J0aW5nCi1CYWRNZXNzYWdlS2V5ID0gSW1wb3NzaWJpbGUgdHJvdmFyZSBpbCBtZXNzYWdnaW8gZGkgZXJyb3JlIGNvcnJpc3BvbmRlbnRlIGFsbGEgY2hpYXZlIGRpIG1lc3NhZ2dpby4KLUZvcm1hdEZhaWxlZCA9IFNpIFx1MDBFOCB2ZXJpZmljYXRvIHVuIGVycm9yZSBpbnRlcm5vIGR1cmFudGUgbGEgZm9ybWF0dGF6aW9uZSBkZWwgc2VndWVudGUgbWVzc2FnZ2lvOlxuICAKLQotIyBYUG9pbnRlciBGcmFtZXdvcmsgRXJyb3IgTWVzc2FnZXMKLVhQb2ludGVyUHJvY2Vzc2luZ0Vycm9yID0gWFBvaW50ZXJQcm9jZXNzaW5nRXJyb3I6IHNpIFx1MDBFOCB2ZXJpZmljYXRvIHVuIGVycm9yZSBkdXJhbnRlIGwnZWxhYm9yYXppb25lIGRlbGwnJ2VzcHJlc3Npb25lIFhQb2ludGVyLgotSW52YWxpZFhQb2ludGVyVG9rZW4gPSBJbnZhbGlkWFBvaW50ZXJUb2tlbjogbCcnZXNwcmVzc2lvbmUgWFBvaW50ZXIgY29udGllbmUgaWwgdG9rZW4gbm9uIHZhbGlkbyAnJ3swfScnLgotSW52YWxpZFhQb2ludGVyRXhwcmVzc2lvbiA9IEludmFsaWRYUG9pbnRlckV4cHJlc3Npb246IGwnJ2VzcHJlc3Npb25lIFhQb2ludGVyICcnezB9Jycgbm9uIFx1MDBFOCB2YWxpZGEuCi1NdWx0aXBsZVNob3J0SGFuZFBvaW50ZXJzID0gTXVsdGlwbGVTaG9ydEhhbmRQb2ludGVyczogbCcnZXNwcmVzc2lvbmUgWFBvaW50ZXIgJyd7MH0nJyBub24gXHUwMEU4IHZhbGlkYS4gQ29udGllbmUgcGlcdTAwRjkgcHVudGF0b3JpIFNob3J0SGFuZC4gCi1TY2hlbWVEYXRhTm90Rm9sbG93ZWRCeUNsb3NlUGFyZW50aGVzaXMgPSBTY2hlbWVEYXRhTm90Rm9sbG93ZWRCeUNsb3NlUGFyZW50aGVzaXM6IGwnJ2VzcHJlc3Npb25lIFhQb2ludGVyICcnezB9Jycgbm9uIFx1MDBFOCB2YWxpZGEuIFNjaGVtZURhdGEgbm9uIFx1MDBFOCBzZWd1aXRvIGRhIHVuIGNhcmF0dGVyZSAnJyknJy4gCi1TY2hlbWVVbnN1cHBvcnRlZCA9IFNjaGVtZVVuc3VwcG9ydGVkOiBsbyBzY2hlbWEgWFBvaW50ZXIgJyd7MH0nJyBub24gXHUwMEU4IHN1cHBvcnRhdG8uCi1JbnZhbGlkU2hvcnRIYW5kUG9pbnRlciA9IEludmFsaWRTaG9ydEhhbmRQb2ludGVyOiBOQ05hbWUgZGVsIHB1bnRhdG9yZSBTaG9ydEhhbmQgJyd7MH0nJyBub24gdmFsaWRvLgotVW5iYWxhbmNlZFBhcmVudGhlc2lzSW5YUG9pbnRlckV4cHJlc3Npb24gPSBVbmJhbGFuY2VkUGFyZW50aGVzaXNJblhQb2ludGVyRXhwcmVzc2lvbjogbCcnZXNwcmVzc2lvbmUgWFBvaW50ZXIgJyd7MH0nJyBub24gXHUwMEU4IHZhbGlkYS4gSWwgbnVtZXJvIGRpIHBhcmVudGVzaSBhcGVydGUgJyd7MX0nJyBub24gY29ycmlzcG9uZGUgYWwgbnVtZXJvIGRpIHBhcmVudGVzaSBjaGl1c2UgJyd7Mn0nJy4KLUludmFsaWRTY2hlbWVEYXRhSW5YUG9pbnRlciA9IEludmFsaWRTY2hlbWVEYXRhSW5YUG9pbnRlcjogbCcnZXNwcmVzc2lvbmUgWFBvaW50ZXIgJyd7MH0nJyBjb250aWVuZSBTY2hlbWVEYXRhIG5vbiB2YWxpZGkuCi0KLSMgWFBvaW50ZXIgRWxlbWVudCBTY2hlbWUgRXJyb3IgTWVzc2FnZXMKLUludmFsaWRFbGVtZW50U2NoZW1lVG9rZW4gPSBJbnZhbGlkRWxlbWVudFNjaGVtZVRva2VuOiBsJydlc3ByZXNzaW9uZSBYUG9pbnRlciBkZWxsbyBzY2hlbWEgZWxlbWVudCgpIGNvbnRpZW5lIGlsIHRva2VuIG5vbiB2YWxpZG8gJyd7MH0nJy4KLUludmFsaWRFbGVtZW50U2NoZW1lWFBvaW50ZXIgPSBJbnZhbGlkRWxlbWVudFNjaGVtZVhQb2ludGVyOiBsJydlc3ByZXNzaW9uZSBYUG9pbnRlciAnJ3swfScnIGRlbGxvIHNjaGVtYSBkaSBlbGVtZW50byBub24gXHUwMEU4IHZhbGlkYS4KLVhQb2ludGVyRWxlbWVudFNjaGVtZVByb2Nlc3NpbmdFcnJvciA9IFhQb2ludGVyRWxlbWVudFNjaGVtZVByb2Nlc3NpbmdFcnJvcjogc2kgXHUwMEU4IHZlcmlmaWNhdG8gdW4gZXJyb3JlIGR1cmFudGUgbCdlbGFib3JhemlvbmUgZGVsbCcnZXNwcmVzc2lvbmUgZGkgc2NoZW1hIGVsZW1lbnQoKSBYUG9pbnRlci4KLUludmFsaWROQ05hbWVJbkVsZW1lbnRTY2hlbWVEYXRhID0gSW52YWxpZE5DTmFtZUluRWxlbWVudFNjaGVtZURhdGE6IGxvIHNjaGVtYSBlbGVtZW50KCkgY29udGllbmUgdW4gcHVudGF0b3JlIFNob3J0SGFuZCAnJ3swfScnIGNvbiBOQ05hbWUgbm9uIHZhbGlkby4KLUludmFsaWRDaGlsZFNlcXVlbmNlQ2hhcmFjdGVyID0gSW52YWxpZENoaWxkU2VxdWVuY2VDaGFyYWN0ZXI6IGxvIHNjaGVtYSBlbGVtZW50KCkgY29udGllbmUgdW4gY2FyYXR0ZXJlIGRpIHNlcXVlbnphIHNlY29uZGFyaWEgJyd7MH0nJyBub24gdmFsaWRvLiAKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hQb2ludGVyTWVzc2FnZXNfamEucHJvcGVydGllcyBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hQb2ludGVyTWVzc2FnZXNfamEucHJvcGVydGllcwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZWNhNzc5OC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9YUG9pbnRlck1lc3NhZ2VzX2phLnByb3BlcnRpZXMKKysrIC9kZXYvbnVsbApAQCAtMSwyNiArMCwwIEBACi0jIFRoaXMgZmlsZSBzdG9yZXMgbG9jYWxpemVkIG1lc3NhZ2VzIGZvciB0aGUgWGVyY2VzIFhQb2ludGVyIGltcGxlbWVudGF0aW9uLgotIwotIyBUaGUgbWVzc2FnZXMgYXJlIGFycmFuZ2VkIGluIGtleSBhbmQgdmFsdWUgdHVwbGVzIGluIGEgTGlzdFJlc291cmNlQnVuZGxlLgotIwotCi0jIE1lc3NhZ2VzIGZvciBtZXNzYWdlIHJlcG9ydGluZwotQmFkTWVzc2FnZUtleSA9IFx1MzBFMVx1MzBDM1x1MzBCQlx1MzBGQ1x1MzBCOFx1MzBGQlx1MzBBRFx1MzBGQ1x1MzA2Qlx1NUJGRVx1NUZEQ1x1MzA1OVx1MzA4Qlx1MzBBOFx1MzBFOVx1MzBGQ1x1MzBGQlx1MzBFMVx1MzBDM1x1MzBCQlx1MzBGQ1x1MzBCOFx1MzA0Q1x1ODk4Qlx1MzA2NFx1MzA0Qlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotRm9ybWF0RmFpbGVkID0gXHU2QjIxXHUzMDZFXHUzMEUxXHUzMEMzXHUzMEJCXHUzMEZDXHUzMEI4XHUzMDZFXHU2NkY4XHU1RjBGXHU4QTJEXHU1QjlBXHU0RTJEXHUzMDZCXHU1MTg1XHU5MEU4XHUzMEE4XHUzMEU5XHUzMEZDXHUzMDRDXHU3NjdBXHU3NTFGXHUzMDU3XHUzMDdFXHUzMDU3XHUzMDVGOlxuICAKLQotIyBYUG9pbnRlciBGcmFtZXdvcmsgRXJyb3IgTWVzc2FnZXMKLVhQb2ludGVyUHJvY2Vzc2luZ0Vycm9yID0gWFBvaW50ZXJQcm9jZXNzaW5nRXJyb3I6IFhQb2ludGVyXHU1RjBGXHUzMDZFXHU1MUU2XHU3NDA2XHU0RTJEXHUzMDZCXHUzMEE4XHUzMEU5XHUzMEZDXHUzMDRDXHU3NjdBXHU3NTFGXHUzMDU3XHUzMDdFXHUzMDU3XHUzMDVGXHUzMDAyCi1JbnZhbGlkWFBvaW50ZXJUb2tlbiA9IEludmFsaWRYUG9pbnRlclRva2VuOiBYUG9pbnRlclx1NUYwRlx1MzA2Qlx1NzEyMVx1NTJCOVx1MzA2QVx1MzBDOFx1MzBGQ1x1MzBBRlx1MzBGMycnezB9JydcdTMwNENcdTU0MkJcdTMwN0VcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTkKLUludmFsaWRYUG9pbnRlckV4cHJlc3Npb24gPSBJbnZhbGlkWFBvaW50ZXJFeHByZXNzaW9uOiBYUG9pbnRlclx1NUYwRicnezB9JydcdTMwNENcdTcxMjFcdTUyQjlcdTMwNjdcdTMwNTlcdTMwMDIKLU11bHRpcGxlU2hvcnRIYW5kUG9pbnRlcnMgPSBNdWx0aXBsZVNob3J0SGFuZFBvaW50ZXJzOiBYUG9pbnRlclx1NUYwRicnezB9JydcdTMwNENcdTcxMjFcdTUyQjlcdTMwNjdcdTMwNTlcdTMwMDJcdTg5MDdcdTY1NzBcdTMwNkVTaG9ydEhhbmRcdTMwRERcdTMwQTRcdTMwRjNcdTMwQkZcdTMwNENcdTU0MkJcdTMwN0VcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTlcdTMwMDIgCi1TY2hlbWVEYXRhTm90Rm9sbG93ZWRCeUNsb3NlUGFyZW50aGVzaXMgPSBTY2hlbWVEYXRhTm90Rm9sbG93ZWRCeUNsb3NlUGFyZW50aGVzaXM6IFhQb2ludGVyXHU1RjBGJyd7MH0nJ1x1MzA0Q1x1NzEyMVx1NTJCOVx1MzA2N1x1MzA1OVx1MzAwMlNjaGVtZURhdGFcdTMwNkVcdTVGOENcdTMwNkInJyknJ1x1NjU4N1x1NUI1N1x1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMiAKLVNjaGVtZVVuc3VwcG9ydGVkID0gU2NoZW1lVW5zdXBwb3J0ZWQ6IFhQb2ludGVyXHUzMEI5XHUzMEFEXHUzMEZDXHUzMEUwJyd7MH0nJ1x1MzA2Rlx1MzBCNVx1MzBERFx1MzBGQ1x1MzBDOFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotSW52YWxpZFNob3J0SGFuZFBvaW50ZXIgPSBJbnZhbGlkU2hvcnRIYW5kUG9pbnRlcjogU2hvcnRIYW5kXHUzMEREXHUzMEE0XHUzMEYzXHUzMEJGJyd7MH0nJ1x1MzA2RU5DTmFtZVx1MzA0Q1x1NzEyMVx1NTJCOVx1MzA2N1x1MzA1OVx1MzAwMgotVW5iYWxhbmNlZFBhcmVudGhlc2lzSW5YUG9pbnRlckV4cHJlc3Npb24gPSBVbmJhbGFuY2VkUGFyZW50aGVzaXNJblhQb2ludGVyRXhwcmVzc2lvbjogWFBvaW50ZXJcdTVGMEYnJ3swfScnXHUzMDRDXHU3MTIxXHU1MkI5XHUzMDY3XHUzMDU5XHUzMDAyXHU1REU2XHU0RTM4XHUzMEFCXHUzMEMzXHUzMEIzJyd7MX0nJ1x1MzA2RVx1NjU3MFx1MzA0Q1x1NTNGM1x1NEUzOFx1MzBBQlx1MzBDM1x1MzBCMycnezJ9JydcdTMwNkVcdTY1NzBcdTMwNjhcdTRFMDBcdTgxRjRcdTMwNTdcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLUludmFsaWRTY2hlbWVEYXRhSW5YUG9pbnRlciA9IEludmFsaWRTY2hlbWVEYXRhSW5YUG9pbnRlcjogWFBvaW50ZXJcdTVGMEYnJ3swfScnXHUzMDZCXHU3MTIxXHU1MkI5XHUzMDZBU2NoZW1lRGF0YVx1MzA0Q1x1NTQyQlx1MzA3RVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OVx1MzAwMgotCi0jIFhQb2ludGVyIEVsZW1lbnQgU2NoZW1lIEVycm9yIE1lc3NhZ2VzCi1JbnZhbGlkRWxlbWVudFNjaGVtZVRva2VuID0gSW52YWxpZEVsZW1lbnRTY2hlbWVUb2tlbjogZWxlbWVudCgpIFNjaGVtZSBYUG9pbnRlclx1NUYwRlx1MzA2Qlx1NzEyMVx1NTJCOVx1MzA2QVx1MzBDOFx1MzBGQ1x1MzBBRlx1MzBGMycnezB9JydcdTMwNENcdTU0MkJcdTMwN0VcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTlcdTMwMDIKLUludmFsaWRFbGVtZW50U2NoZW1lWFBvaW50ZXIgPSBJbnZhbGlkRWxlbWVudFNjaGVtZVhQb2ludGVyOiBFbGVtZW50IFNjaGVtZSBYUG9pbnRlclx1NUYwRicnezB9JydcdTMwNENcdTcxMjFcdTUyQjlcdTMwNjdcdTMwNTlcdTMwMDIKLVhQb2ludGVyRWxlbWVudFNjaGVtZVByb2Nlc3NpbmdFcnJvciA9IFhQb2ludGVyRWxlbWVudFNjaGVtZVByb2Nlc3NpbmdFcnJvcjogWFBvaW50ZXIgZWxlbWVudCgpIFNjaGVtZVx1NUYwRlx1MzA2RVx1NTFFNlx1NzQwNlx1NEUyRFx1MzA2Qlx1MzBBOFx1MzBFOVx1MzBGQ1x1MzA0Q1x1NzY3QVx1NzUxRlx1MzA1N1x1MzA3RVx1MzA1N1x1MzA1Rlx1MzAwMgotSW52YWxpZE5DTmFtZUluRWxlbWVudFNjaGVtZURhdGEgPSBJbnZhbGlkTkNOYW1lSW5FbGVtZW50U2NoZW1lRGF0YTogZWxlbWVudCgpIFNjaGVtZVx1MzA2Qlx1NzEyMVx1NTJCOVx1MzA2QU5DTmFtZVx1MzA5Mlx1NjMwMVx1MzA2NFNob3J0SGFuZFx1MzBERFx1MzBBNFx1MzBGM1x1MzBCRicnezB9JydcdTMwNENcdTU0MkJcdTMwN0VcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTlcdTMwMDIKLUludmFsaWRDaGlsZFNlcXVlbmNlQ2hhcmFjdGVyID0gSW52YWxpZENoaWxkU2VxdWVuY2VDaGFyYWN0ZXI6IGVsZW1lbnQoKSBTY2hlbWVcdTMwNkJcdTcxMjFcdTUyQjlcdTMwNkFcdTVCNTBcdTMwQjdcdTMwRkNcdTMwQjFcdTMwRjNcdTMwQjlcdTY1ODdcdTVCNTcnJ3swfScnXHUzMDRDXHU1NDJCXHUzMDdFXHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5XHUzMDAyIApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWFBvaW50ZXJNZXNzYWdlc19rby5wcm9wZXJ0aWVzIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWFBvaW50ZXJNZXNzYWdlc19rby5wcm9wZXJ0aWVzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2YTQxMzhhLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hQb2ludGVyTWVzc2FnZXNfa28ucHJvcGVydGllcworKysgL2Rldi9udWxsCkBAIC0xLDI2ICswLDAgQEAKLSMgVGhpcyBmaWxlIHN0b3JlcyBsb2NhbGl6ZWQgbWVzc2FnZXMgZm9yIHRoZSBYZXJjZXMgWFBvaW50ZXIgaW1wbGVtZW50YXRpb24uCi0jCi0jIFRoZSBtZXNzYWdlcyBhcmUgYXJyYW5nZWQgaW4ga2V5IGFuZCB2YWx1ZSB0dXBsZXMgaW4gYSBMaXN0UmVzb3VyY2VCdW5kbGUuCi0jCi0KLSMgTWVzc2FnZXMgZm9yIG1lc3NhZ2UgcmVwb3J0aW5nCi1CYWRNZXNzYWdlS2V5ID0gXHVCQTU0XHVDMkRDXHVDOUMwIFx1RDBBNFx1QzVEMCBcdUQ1NzRcdUIyRjlcdUQ1NThcdUIyOTQgXHVDNjI0XHVCOTU4IFx1QkE1NFx1QzJEQ1x1QzlDMFx1Qjk3QyBcdUNDM0VcdUM3NDQgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4KLUZvcm1hdEZhaWxlZCA9IFx1QjJFNFx1Qzc0QyBcdUJBNTRcdUMyRENcdUM5QzBcdUM3NTggXHVENjE1XHVDMkREXHVDNzQ0IFx1QzlDMFx1QzgxNVx1RDU1OFx1QjI5NCBcdUM5MTEgXHVCMEI0XHVCRDgwIFx1QzYyNFx1Qjk1OFx1QUMwMCBcdUJDMUNcdUMwRERcdUQ1ODhcdUMyQjVcdUIyQzhcdUIyRTQuXG4gIAotCi0jIFhQb2ludGVyIEZyYW1ld29yayBFcnJvciBNZXNzYWdlcwotWFBvaW50ZXJQcm9jZXNzaW5nRXJyb3IgPSBYUG9pbnRlclByb2Nlc3NpbmdFcnJvcjogWFBvaW50ZXIgXHVENDVDXHVENjA0XHVDMkREXHVDNzQ0IFx1Q0M5OFx1QjlBQ1x1RDU1OFx1QjI5NCBcdUM5MTEgXHVDNjI0XHVCOTU4XHVBQzAwIFx1QkMxQ1x1QzBERFx1RDU4OFx1QzJCNVx1QjJDOFx1QjJFNC4KLUludmFsaWRYUG9pbnRlclRva2VuID0gSW52YWxpZFhQb2ludGVyVG9rZW46IFhQb2ludGVyIFx1RDQ1Q1x1RDYwNFx1QzJERFx1QzVEMCBcdUJEODBcdUM4MDFcdUQ1NjlcdUQ1NUMgXHVEMUEwXHVEMDcwICcnezB9JydcdUM3NzQoXHVBQzAwKSBcdUQzRUNcdUQ1NjhcdUI0MThcdUM1QjQgXHVDNzg4XHVDMkI1XHVCMkM4XHVCMkU0LgotSW52YWxpZFhQb2ludGVyRXhwcmVzc2lvbiA9IEludmFsaWRYUG9pbnRlckV4cHJlc3Npb246IFhQb2ludGVyIFx1RDQ1Q1x1RDYwNFx1QzJERCAnJ3swfScnXHVDNzc0KFx1QUMwMCkgXHVCRDgwXHVDODAxXHVENTY5XHVENTY5XHVCMkM4XHVCMkU0LgotTXVsdGlwbGVTaG9ydEhhbmRQb2ludGVycyA9IE11bHRpcGxlU2hvcnRIYW5kUG9pbnRlcnM6IFhQb2ludGVyIFx1RDQ1Q1x1RDYwNFx1QzJERCAnJ3swfScnXHVDNzc0KFx1QUMwMCkgXHVCRDgwXHVDODAxXHVENTY5XHVENTY5XHVCMkM4XHVCMkU0LiBTaG9ydEhhbmQgUG9pbnRlclx1QUMwMCBcdUI0NTAgXHVBQzFDIFx1Qzc3NFx1QzBDMSBcdUQzRUNcdUQ1NjhcdUI0MThcdUM1QjQgXHVDNzg4XHVDMkI1XHVCMkM4XHVCMkU0LiAKLVNjaGVtZURhdGFOb3RGb2xsb3dlZEJ5Q2xvc2VQYXJlbnRoZXNpcyA9IFNjaGVtZURhdGFOb3RGb2xsb3dlZEJ5Q2xvc2VQYXJlbnRoZXNpczogWFBvaW50ZXIgXHVENDVDXHVENjA0XHVDMkREICcnezB9JydcdUM3NzQoXHVBQzAwKSBcdUJEODBcdUM4MDFcdUQ1NjlcdUQ1NjlcdUIyQzhcdUIyRTQuIFNjaGVtZURhdGEgXHVCNEE0XHVDNUQwICcnKScnIFx1QkIzOFx1Qzc5MFx1QUMwMCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuIAotU2NoZW1lVW5zdXBwb3J0ZWQgPSBTY2hlbWVVbnN1cHBvcnRlZDogWFBvaW50ZXIgXHVDQ0I0XHVBQ0M0ICcnezB9JydcdUM3NDAoXHVCMjk0KSBcdUM5QzBcdUM2RDBcdUI0MThcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0LgotSW52YWxpZFNob3J0SGFuZFBvaW50ZXIgPSBJbnZhbGlkU2hvcnRIYW5kUG9pbnRlcjogU2hvcnRIYW5kIFBvaW50ZXIgJyd7MH0nJ1x1Qzc1OCBOQ05hbWVcdUM3NzQgXHVCRDgwXHVDODAxXHVENTY5XHVENTY5XHVCMkM4XHVCMkU0LgotVW5iYWxhbmNlZFBhcmVudGhlc2lzSW5YUG9pbnRlckV4cHJlc3Npb24gPSBVbmJhbGFuY2VkUGFyZW50aGVzaXNJblhQb2ludGVyRXhwcmVzc2lvbjogWFBvaW50ZXIgXHVENDVDXHVENjA0XHVDMkREICcnezB9JydcdUM3NzQoXHVBQzAwKSBcdUJEODBcdUM4MDFcdUQ1NjlcdUQ1NjlcdUIyQzhcdUIyRTQuIFx1QzVFQ1x1QjI5NCBcdUFEMDRcdUQ2MzhcdUM3NTggXHVBQzFDXHVDMjE4ICcnezF9JydcdUFDRkMoXHVDNjQwKSBcdUIyRUJcdUIyOTQgXHVBRDA0XHVENjM4XHVDNzU4IFx1QUMxQ1x1QzIxOCAnJ3syfScnXHVDNzc0KFx1QUMwMCkgXHVDNzdDXHVDRTU4XHVENTU4XHVDOUMwIFx1QzU0QVx1QzJCNVx1QjJDOFx1QjJFNC4KLUludmFsaWRTY2hlbWVEYXRhSW5YUG9pbnRlciA9IEludmFsaWRTY2hlbWVEYXRhSW5YUG9pbnRlcjogWFBvaW50ZXIgXHVENDVDXHVENjA0XHVDMkREICcnezB9JydcdUM1RDAgXHVCRDgwXHVDODAxXHVENTY5XHVENTVDIFNjaGVtZURhdGFcdUFDMDAgXHVEM0VDXHVENTY4XHVCNDE4XHVDNUI0IFx1Qzc4OFx1QzJCNVx1QjJDOFx1QjJFNC4KLQotIyBYUG9pbnRlciBFbGVtZW50IFNjaGVtZSBFcnJvciBNZXNzYWdlcwotSW52YWxpZEVsZW1lbnRTY2hlbWVUb2tlbiA9IEludmFsaWRFbGVtZW50U2NoZW1lVG9rZW46IGVsZW1lbnQoKSBcdUNDQjRcdUFDQzQgWFBvaW50ZXIgXHVENDVDXHVENjA0XHVDMkREXHVDNUQwIFx1QkQ4MFx1QzgwMVx1RDU2OVx1RDU1QyBcdUQxQTBcdUQwNzAgJyd7MH0nJ1x1Qzc3NChcdUFDMDApIFx1RDNFQ1x1RDU2OFx1QjQxOFx1QzVCNCBcdUM3ODhcdUMyQjVcdUIyQzhcdUIyRTQuCi1JbnZhbGlkRWxlbWVudFNjaGVtZVhQb2ludGVyID0gSW52YWxpZEVsZW1lbnRTY2hlbWVYUG9pbnRlcjogXHVDNjk0XHVDMThDIFx1Q0NCNFx1QUNDNCBYUG9pbnRlciBcdUQ0NUNcdUQ2MDRcdUMyREQgJyd7MH0nJ1x1Qzc3NChcdUFDMDApIFx1QkQ4MFx1QzgwMVx1RDU2OVx1RDU2OVx1QjJDOFx1QjJFNC4KLVhQb2ludGVyRWxlbWVudFNjaGVtZVByb2Nlc3NpbmdFcnJvciA9IFhQb2ludGVyRWxlbWVudFNjaGVtZVByb2Nlc3NpbmdFcnJvcjogWFBvaW50ZXIgZWxlbWVudCgpIFx1Q0NCNFx1QUNDNCBcdUQ0NUNcdUQ2MDRcdUMyRERcdUM3NDQgXHVDQzk4XHVCOUFDXHVENTU4XHVCMjk0IFx1QzkxMSBcdUM2MjRcdUI5NThcdUFDMDAgXHVCQzFDXHVDMEREXHVENTg4XHVDMkI1XHVCMkM4XHVCMkU0LgotSW52YWxpZE5DTmFtZUluRWxlbWVudFNjaGVtZURhdGEgPSBJbnZhbGlkTkNOYW1lSW5FbGVtZW50U2NoZW1lRGF0YTogZWxlbWVudCgpIFx1Q0NCNFx1QUNDNFx1QzVEMCBOQ05hbWVcdUM3NzQgXHVCRDgwXHVDODAxXHVENTY5XHVENTVDIFNob3J0SGFuZCBQb2ludGVyICcnezB9JydcdUM3NzQoXHVBQzAwKSBcdUQzRUNcdUQ1NjhcdUI0MThcdUM1QjQgXHVDNzg4XHVDMkI1XHVCMkM4XHVCMkU0LgotSW52YWxpZENoaWxkU2VxdWVuY2VDaGFyYWN0ZXIgPSBJbnZhbGlkQ2hpbGRTZXF1ZW5jZUNoYXJhY3RlcjogZWxlbWVudCgpIFx1Q0NCNFx1QUNDNFx1QzVEMCBcdUJEODBcdUM4MDFcdUQ1NjlcdUQ1NUMgXHVENTU4XHVDNzA0IFx1QzJEQ1x1RDAwMFx1QzJBNCBcdUJCMzhcdUM3OTAgJyd7MH0nJ1x1Qzc3NChcdUFDMDApIFx1RDNFQ1x1RDU2OFx1QjQxOFx1QzVCNCBcdUM3ODhcdUMyQjVcdUIyQzhcdUIyRTQuIApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWFBvaW50ZXJNZXNzYWdlc19wdF9CUi5wcm9wZXJ0aWVzIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWFBvaW50ZXJNZXNzYWdlc19wdF9CUi5wcm9wZXJ0aWVzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkMGRhNWRlLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hQb2ludGVyTWVzc2FnZXNfcHRfQlIucHJvcGVydGllcworKysgL2Rldi9udWxsCkBAIC0xLDI2ICswLDAgQEAKLSMgVGhpcyBmaWxlIHN0b3JlcyBsb2NhbGl6ZWQgbWVzc2FnZXMgZm9yIHRoZSBYZXJjZXMgWFBvaW50ZXIgaW1wbGVtZW50YXRpb24uCi0jCi0jIFRoZSBtZXNzYWdlcyBhcmUgYXJyYW5nZWQgaW4ga2V5IGFuZCB2YWx1ZSB0dXBsZXMgaW4gYSBMaXN0UmVzb3VyY2VCdW5kbGUuCi0jCi0KLSMgTWVzc2FnZXMgZm9yIG1lc3NhZ2UgcmVwb3J0aW5nCi1CYWRNZXNzYWdlS2V5ID0gTlx1MDBFM28gZm9pIHBvc3NcdTAwRUR2ZWwgZW5jb250cmFyIGEgbWVuc2FnZW0gZGUgZXJybyBjb3JyZXNwb25kZW50ZSBcdTAwRTAgY2hhdmUgZGEgbWVuc2FnZW0uCi1Gb3JtYXRGYWlsZWQgPSBPY29ycmV1IHVtIGVycm8gaW50ZXJubyBhbyBmb3JtYXRhciBhIG1lbnNhZ2VtIGEgc2VndWlyOlxuICAKLQotIyBYUG9pbnRlciBGcmFtZXdvcmsgRXJyb3IgTWVzc2FnZXMKLVhQb2ludGVyUHJvY2Vzc2luZ0Vycm9yID0gWFBvaW50ZXJQcm9jZXNzaW5nRXJyb3I6IE9jb3JyZXUgdW0gZXJybyBhbyBwcm9jZXNzYXIgYSBleHByZXNzXHUwMEUzbyBYUG9pbnRlci4KLUludmFsaWRYUG9pbnRlclRva2VuID0gSW52YWxpZFhQb2ludGVyVG9rZW46IEEgZXhwcmVzc1x1MDBFM28gWFBvaW50ZXIgY29udFx1MDBFOW0gbyB0b2tlbiBpbnZcdTAwRTFsaWRvICcnezB9JycKLUludmFsaWRYUG9pbnRlckV4cHJlc3Npb24gPSBJbnZhbGlkWFBvaW50ZXJFeHByZXNzaW9uOiBBIGV4cHJlc3NcdTAwRTNvIFhQb2ludGVyICcnezB9JycgXHUwMEU5IGludlx1MDBFMWxpZGEuCi1NdWx0aXBsZVNob3J0SGFuZFBvaW50ZXJzID0gTXVsdGlwbGVTaG9ydEhhbmRQb2ludGVyczogQSBleHByZXNzXHUwMEUzbyBYUG9pbnRlciAnJ3swfScnIFx1MDBFOSBpbnZcdTAwRTFsaWRhLiBUZW0gbWFpcyBkZSB1bSBQb250ZWlybyBTaG9ydEhhbmQuIAotU2NoZW1lRGF0YU5vdEZvbGxvd2VkQnlDbG9zZVBhcmVudGhlc2lzID0gU2NoZW1lRGF0YU5vdEZvbGxvd2VkQnlDbG9zZVBhcmVudGhlc2lzOiBBIGV4cHJlc3NcdTAwRTNvIFhQb2ludGVyICcnezB9JycgXHUwMEU5IGludlx1MDBFMWxpZGEuIE8gU2NoZW1lRGF0YSBuXHUwMEUzbyBmb2kgc2VndWlkYSBwb3IgdW0gY2FyYWN0ZXJlICcnKSIuIAotU2NoZW1lVW5zdXBwb3J0ZWQgPSBTY2hlbWVVbnN1cHBvcnRlZDogTyBlc3F1ZW1hIFhQb2ludGVyICcnezB9Jycgblx1MDBFM28gXHUwMEU5IHN1cG9ydGFkby4KLUludmFsaWRTaG9ydEhhbmRQb2ludGVyID0gSW52YWxpZFNob3J0SGFuZFBvaW50ZXI6IE8gTkNOYW1lIGRvIFBvbnRlaXJvIGRvIFNob3J0SGFuZCAnJ3swfScnIFx1MDBFOSBpbnZcdTAwRTFsaWRvLgotVW5iYWxhbmNlZFBhcmVudGhlc2lzSW5YUG9pbnRlckV4cHJlc3Npb24gPSBVbmJhbGFuY2VkUGFyZW50aGVzaXNJblhQb2ludGVyRXhwcmVzc2lvbjogQSBleHByZXNzXHUwMEUzbyBYUG9pbnRlciAnJ3swfScnIFx1MDBFOSBpbnZcdTAwRTFsaWRhLiBPIG5cdTAwRkFtZXJvIGRlIHBhclx1MDBFQW50ZXNlcyBkZSBhYmVydHVyYSAnJ3sxfScnIG5cdTAwRTNvIFx1MDBFOSBpZ3VhbCBhbyBuXHUwMEZBbWVybyBkZSBwYXJcdTAwRUFudGVzZXMgZGUgZmVjaGFtZW50byAnJ3syfScnLgotSW52YWxpZFNjaGVtZURhdGFJblhQb2ludGVyID0gSW52YWxpZFNjaGVtZURhdGFJblhQb2ludGVyOiBBIGV4cHJlc3NcdTAwRTNvIFhQb2ludGVyICcnezB9JycgY29udFx1MDBFOW0gU2NoZW1lRGF0YSBpbnZcdTAwRTFsaWRvLgotCi0jIFhQb2ludGVyIEVsZW1lbnQgU2NoZW1lIEVycm9yIE1lc3NhZ2VzCi1JbnZhbGlkRWxlbWVudFNjaGVtZVRva2VuID0gSW52YWxpZEVsZW1lbnRTY2hlbWVUb2tlbjogQSBleHByZXNzXHUwMEUzbyBYUG9pbnRlciBkbyBlc3F1ZW1hIGVsZW1lbnQoKSBjb250XHUwMEU5bSBvIHRva2VuIGludlx1MDBFMWxpZG8gJyd7MH0nJwotSW52YWxpZEVsZW1lbnRTY2hlbWVYUG9pbnRlciA9IEludmFsaWRFbGVtZW50U2NoZW1lWFBvaW50ZXI6IEEgZXhwcmVzc1x1MDBFM28gWFBvaW50ZXIgZG8gRXNxdWVtYSBkbyBFbGVtZW50byAnJ3swfScnIFx1MDBFOSBpbnZcdTAwRTFsaWRhLgotWFBvaW50ZXJFbGVtZW50U2NoZW1lUHJvY2Vzc2luZ0Vycm9yID0gWFBvaW50ZXJFbGVtZW50U2NoZW1lUHJvY2Vzc2luZ0Vycm9yOiBPY29ycmV1IHVtIGVycm8gYW8gcHJvY2Vzc29hciBhIGV4cHJlc3NcdTAwRTNvIGRvIEVzcXVlbWEgZG8gZWxlbWVudCgpIGRvIFhQb2ludGVyLgotSW52YWxpZE5DTmFtZUluRWxlbWVudFNjaGVtZURhdGEgPSBJbnZhbGlkTkNOYW1lSW5FbGVtZW50U2NoZW1lRGF0YTogTyBFc3F1ZW1hIGRvIGVsZW1lbnQoKSBjb250XHUwMEU5bSB1bSBQb250ZWlybyBkZSBTaG9ydEhhbmQgJyd7MH0nJyBjb20gdW0gTkNOYW1lIGludlx1MDBFMWxpZG8uCi1JbnZhbGlkQ2hpbGRTZXF1ZW5jZUNoYXJhY3RlciA9IEludmFsaWRDaGlsZFNlcXVlbmNlQ2hhcmFjdGVyOiBPIEVzcXVlbWEgZGUgZWxlbWVudCgpIGNvbnRcdTAwRTltIHVtIGNhcmFjdGVyZSBkZSBzZXF1XHUwMEVBbmNpYSBmaWxobyBpbnZcdTAwRTFsaWRvICcnezB9JycuIApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWFBvaW50ZXJNZXNzYWdlc19zdi5wcm9wZXJ0aWVzIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWFBvaW50ZXJNZXNzYWdlc19zdi5wcm9wZXJ0aWVzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2Mjc3NGIxLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hQb2ludGVyTWVzc2FnZXNfc3YucHJvcGVydGllcworKysgL2Rldi9udWxsCkBAIC0xLDI2ICswLDAgQEAKLSMgVGhpcyBmaWxlIHN0b3JlcyBsb2NhbGl6ZWQgbWVzc2FnZXMgZm9yIHRoZSBYZXJjZXMgWFBvaW50ZXIgaW1wbGVtZW50YXRpb24uCi0jCi0jIFRoZSBtZXNzYWdlcyBhcmUgYXJyYW5nZWQgaW4ga2V5IGFuZCB2YWx1ZSB0dXBsZXMgaW4gYSBMaXN0UmVzb3VyY2VCdW5kbGUuCi0jCi0KLSMgTWVzc2FnZXMgZm9yIG1lc3NhZ2UgcmVwb3J0aW5nCi1CYWRNZXNzYWdlS2V5ID0gSGl0dGFyIGludGUgZmVsbWVkZGVsYW5kZXQgc29tIG1vdHN2YXJhciBtZWRkZWxhbmRlbnlja2Vsbi4KLUZvcm1hdEZhaWxlZCA9IEV0dCBpbnRlcm50IGZlbCBpbnRyXHUwMEU0ZmZhZGUgdmlkIGZvcm1hdGVyaW5nIGF2IGZcdTAwRjZsamFuZGUgbWVkZGVsYW5kZTpcbiAgCi0KLSMgWFBvaW50ZXIgRnJhbWV3b3JrIEVycm9yIE1lc3NhZ2VzCi1YUG9pbnRlclByb2Nlc3NpbmdFcnJvciA9IFhQb2ludGVyUHJvY2Vzc2luZ0Vycm9yOiBFdHQgZmVsIGludHJcdTAwRTRmZmFkZSB2aWQgYmVhcmJldG5pbmcgYXYgWFBvaW50ZXItdXR0cnlja2V0LgotSW52YWxpZFhQb2ludGVyVG9rZW4gPSBJbnZhbGlkWFBvaW50ZXJUb2tlbjogWFBvaW50ZXItdXR0cnlja2V0IGlubmVoXHUwMEU1bGxlciBvZ2lsdGlndCB0ZWNrZW4sICcnezB9JycKLUludmFsaWRYUG9pbnRlckV4cHJlc3Npb24gPSBJbnZhbGlkWFBvaW50ZXJFeHByZXNzaW9uOiBYUG9pbnRlci11dHRyeWNrZXQgJyd7MH0nJyBcdTAwRTRyIG9naWx0aWd0LgotTXVsdGlwbGVTaG9ydEhhbmRQb2ludGVycyA9IE11bHRpcGxlU2hvcnRIYW5kUG9pbnRlcnM6IFhQb2ludGVyLXV0dHJ5Y2tldCAnJ3swfScnIFx1MDBFNHIgb2dpbHRpZ3QuIERldCBpbm5laFx1MDBFNWxsZXIgZmxlciBcdTAwRTRuIGVuIFNob3J0SGFuZCBQb2ludGVyLiAKLVNjaGVtZURhdGFOb3RGb2xsb3dlZEJ5Q2xvc2VQYXJlbnRoZXNpcyA9IFNjaGVtZURhdGFOb3RGb2xsb3dlZEJ5Q2xvc2VQYXJlbnRoZXNpczogWFBvaW50ZXItdXR0cnlja2V0ICcnezB9JycgXHUwMEU0ciBvZ2lsdGlndC4gU2NoZW1lRGF0YSBlZnRlcmZcdTAwRjZsamRlcyBpbnRlIGF2IGV0dCAnJyknJy10ZWNrZW4uIAotU2NoZW1lVW5zdXBwb3J0ZWQgPSBTY2hlbWVVbnN1cHBvcnRlZDogWFBvaW50ZXItc2NoZW1hdCAnJ3swfScnIHN0XHUwMEY2ZHMgaW50ZS4KLUludmFsaWRTaG9ydEhhbmRQb2ludGVyID0gSW52YWxpZFNob3J0SGFuZFBvaW50ZXI6IE5DTmFtZSBpIFNob3J0SGFuZC1wZWthcmVuICcnezB9JycgXHUwMEU0ciBvZ2lsdGlndC4KLVVuYmFsYW5jZWRQYXJlbnRoZXNpc0luWFBvaW50ZXJFeHByZXNzaW9uID0gVW5iYWxhbmNlZFBhcmVudGhlc2lzSW5YUG9pbnRlckV4cHJlc3Npb246IFhQb2ludGVyLXV0dHJ5Y2tldCAnJ3swfScnIFx1MDBFNHIgb2dpbHRpZ3QuIEFudGFsZXQgdlx1MDBFNG5zdGVycGFyZW50ZXNlciAnJ3sxfScnIFx1MDBFNHIgaW50ZSBzYW1tYSBzb20gYW50YWxldCBoXHUwMEY2Z2VycGFyZW50ZXNlciAnJ3syfScnLgotSW52YWxpZFNjaGVtZURhdGFJblhQb2ludGVyID0gSW52YWxpZFNjaGVtZURhdGFJblhQb2ludGVyOiBYUG9pbnRlci11dHRyeWNrZXQgJyd7MH0nJyBpbm5laFx1MDBFNWxsZXIgb2dpbHRpZyBTY2hlbWVEYXRhLgotCi0jIFhQb2ludGVyIEVsZW1lbnQgU2NoZW1lIEVycm9yIE1lc3NhZ2VzCi1JbnZhbGlkRWxlbWVudFNjaGVtZVRva2VuID0gSW52YWxpZEVsZW1lbnRTY2hlbWVUb2tlbjogWFBvaW50ZXItdXR0cnlja2V0IGkgZWxlbWVudCgpLXNjaGVtYXQgaW5uZWhcdTAwRTVsbGVyIG9naWx0aWd0IHRlY2tlbiAnJ3swfScnCi1JbnZhbGlkRWxlbWVudFNjaGVtZVhQb2ludGVyID0gSW52YWxpZEVsZW1lbnRTY2hlbWVYUG9pbnRlcjogWFBvaW50ZXItdXR0cnlja2V0ICcnezB9JycgaSBlbGVtZW50c2NoZW1hdCBcdTAwRTRyIG9naWx0aWd0LgotWFBvaW50ZXJFbGVtZW50U2NoZW1lUHJvY2Vzc2luZ0Vycm9yID0gWFBvaW50ZXJFbGVtZW50U2NoZW1lUHJvY2Vzc2luZ0Vycm9yOiBFdHQgZmVsIGludHJcdTAwRTRmZmFkZSB2aWQgYmVhcmJldG5pbmcgYXYgc2NoZW1hdXR0cnlja2V0IGkgWFBvaW50ZXIgZWxlbWVudCgpLgotSW52YWxpZE5DTmFtZUluRWxlbWVudFNjaGVtZURhdGEgPSBJbnZhbGlkTkNOYW1lSW5FbGVtZW50U2NoZW1lRGF0YTogZWxlbWVudCgpLXNjaGVtYXQgaW5uZWhcdTAwRTVsbGVyIFNob3J0SGFuZC1wZWthcmVuICcnezB9JycgbWVkIG9naWx0aWd0IE5DTmFtZS4KLUludmFsaWRDaGlsZFNlcXVlbmNlQ2hhcmFjdGVyID0gSW52YWxpZENoaWxkU2VxdWVuY2VDaGFyYWN0ZXI6IGVsZW1lbnQoKS1zY2hlbWF0IGlubmVoXHUwMEU1bGxlciBldHQgb2dpbHRpZ3QgdGVja2VuICcnezB9JycgaSB1bmRlcm9yZG5hZCBzZWt2ZW5zLiAKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hQb2ludGVyTWVzc2FnZXNfemhfQ04ucHJvcGVydGllcyBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvbXNnL1hQb2ludGVyTWVzc2FnZXNfemhfQ04ucHJvcGVydGllcwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZDk5YTZlYy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9YUG9pbnRlck1lc3NhZ2VzX3poX0NOLnByb3BlcnRpZXMKKysrIC9kZXYvbnVsbApAQCAtMSwyNiArMCwwIEBACi0jIFRoaXMgZmlsZSBzdG9yZXMgbG9jYWxpemVkIG1lc3NhZ2VzIGZvciB0aGUgWGVyY2VzIFhQb2ludGVyIGltcGxlbWVudGF0aW9uLgotIwotIyBUaGUgbWVzc2FnZXMgYXJlIGFycmFuZ2VkIGluIGtleSBhbmQgdmFsdWUgdHVwbGVzIGluIGEgTGlzdFJlc291cmNlQnVuZGxlLgotIwotCi0jIE1lc3NhZ2VzIGZvciBtZXNzYWdlIHJlcG9ydGluZwotQmFkTWVzc2FnZUtleSA9IFx1NjI3RVx1NEUwRFx1NTIzMFx1NEUwRVx1NkQ4OFx1NjA2Rlx1NTE3M1x1OTUyRVx1NUI1N1x1NUJGOVx1NUU5NFx1NzY4NFx1OTUxOVx1OEJFRlx1NkQ4OFx1NjA2Rlx1MzAwMgotRm9ybWF0RmFpbGVkID0gXHU4QkJFXHU3RjZFXHU0RUU1XHU0RTBCXHU2RDg4XHU2MDZGXHU3Njg0XHU2ODNDXHU1RjBGXHU2NUY2XHU1MUZBXHU3M0IwXHU1MTg1XHU5MEU4XHU5NTE5XHU4QkVGOlxuICAKLQotIyBYUG9pbnRlciBGcmFtZXdvcmsgRXJyb3IgTWVzc2FnZXMKLVhQb2ludGVyUHJvY2Vzc2luZ0Vycm9yID0gWFBvaW50ZXJQcm9jZXNzaW5nRXJyb3I6IFx1NTkwNFx1NzQwNiBYUG9pbnRlciBcdTg4NjhcdThGQkVcdTVGMEZcdTY1RjZcdTUxRkFcdTk1MTlcdTMwMDIKLUludmFsaWRYUG9pbnRlclRva2VuID0gSW52YWxpZFhQb2ludGVyVG9rZW46IFhQb2ludGVyIFx1ODg2OFx1OEZCRVx1NUYwRlx1NTMwNVx1NTQyQlx1NjVFMFx1NjU0OFx1NzY4NFx1NjgwN1x1OEJCMCAnJ3swfScnCi1JbnZhbGlkWFBvaW50ZXJFeHByZXNzaW9uID0gSW52YWxpZFhQb2ludGVyRXhwcmVzc2lvbjogWFBvaW50ZXIgXHU4ODY4XHU4RkJFXHU1RjBGICcnezB9JycgXHU2NUUwXHU2NTQ4XHUzMDAyCi1NdWx0aXBsZVNob3J0SGFuZFBvaW50ZXJzID0gTXVsdGlwbGVTaG9ydEhhbmRQb2ludGVyczogWFBvaW50ZXIgXHU4ODY4XHU4RkJFXHU1RjBGICcnezB9JycgXHU2NUUwXHU2NTQ4XHUzMDAyXHU1QjgzXHU1MTc3XHU2NzA5XHU1OTFBXHU0RTJBIFNob3J0SGFuZCBcdTYzMDdcdTk0ODhcdTMwMDIKLVNjaGVtZURhdGFOb3RGb2xsb3dlZEJ5Q2xvc2VQYXJlbnRoZXNpcyA9IFNjaGVtZURhdGFOb3RGb2xsb3dlZEJ5Q2xvc2VQYXJlbnRoZXNpczogWFBvaW50ZXIgXHU4ODY4XHU4RkJFXHU1RjBGICcnezB9JycgXHU2NUUwXHU2NTQ4XHUzMDAyU2NoZW1lRGF0YSBcdTc2ODRcdTU0MEVcdTk3NjJcdTY3MkFcdThEREZcdTk2OEYgJycpJycgXHU1QjU3XHU3QjI2XHUzMDAyCi1TY2hlbWVVbnN1cHBvcnRlZCA9IFNjaGVtZVVuc3VwcG9ydGVkOiBcdTRFMERcdTY1MkZcdTYzMDEgWFBvaW50ZXIgXHU2NUI5XHU2ODQ4ICcnezB9JydcdTMwMDIKLUludmFsaWRTaG9ydEhhbmRQb2ludGVyID0gSW52YWxpZFNob3J0SGFuZFBvaW50ZXI6IFNob3J0SGFuZCBcdTYzMDdcdTk0ODggJyd7MH0nJyBcdTc2ODQgTkNOYW1lIFx1NjVFMFx1NjU0OFx1MzAwMgotVW5iYWxhbmNlZFBhcmVudGhlc2lzSW5YUG9pbnRlckV4cHJlc3Npb24gPSBVbmJhbGFuY2VkUGFyZW50aGVzaXNJblhQb2ludGVyRXhwcmVzc2lvbjogWFBvaW50ZXIgXHU4ODY4XHU4RkJFXHU1RjBGICcnezB9JycgXHU2NUUwXHU2NTQ4XHUzMDAyXHU1REU2XHU2MkVDXHU1M0Y3XHU3Njg0XHU2NTcwXHU5MUNGICcnezF9JycgXHU0RTBFXHU1M0YzXHU2MkVDXHU1M0Y3XHU3Njg0XHU2NTcwXHU5MUNGICcnezJ9JycgXHU0RTBEXHU3NkY4XHU3QjQ5XHUzMDAyCi1JbnZhbGlkU2NoZW1lRGF0YUluWFBvaW50ZXIgPSBJbnZhbGlkU2NoZW1lRGF0YUluWFBvaW50ZXI6IFhQb2ludGVyIFx1ODg2OFx1OEZCRVx1NUYwRiAnJ3swfScnIFx1NTMwNVx1NTQyQlx1NjVFMFx1NjU0OFx1NzY4NCBTY2hlbWVEYXRhXHUzMDAyCi0KLSMgWFBvaW50ZXIgRWxlbWVudCBTY2hlbWUgRXJyb3IgTWVzc2FnZXMKLUludmFsaWRFbGVtZW50U2NoZW1lVG9rZW4gPSBJbnZhbGlkRWxlbWVudFNjaGVtZVRva2VuOiBlbGVtZW50KCkgXHU2NUI5XHU2ODQ4XHU3Njg0IFhQb2ludGVyIFx1ODg2OFx1OEZCRVx1NUYwRlx1NTMwNVx1NTQyQlx1NjVFMFx1NjU0OFx1NzY4NFx1NjgwN1x1OEJCMCAnJ3swfScnCi1JbnZhbGlkRWxlbWVudFNjaGVtZVhQb2ludGVyID0gSW52YWxpZEVsZW1lbnRTY2hlbWVYUG9pbnRlcjogXHU1MTQzXHU3RDIwXHU2NUI5XHU2ODQ4XHU3Njg0IFhQb2ludGVyIFx1ODg2OFx1OEZCRVx1NUYwRiAnJ3swfScnIFx1NjVFMFx1NjU0OFx1MzAwMgotWFBvaW50ZXJFbGVtZW50U2NoZW1lUHJvY2Vzc2luZ0Vycm9yID0gWFBvaW50ZXJFbGVtZW50U2NoZW1lUHJvY2Vzc2luZ0Vycm9yOiBcdTU5MDRcdTc0MDYgWFBvaW50ZXIgZWxlbWVudCgpIFx1NjVCOVx1Njg0OFx1ODg2OFx1OEZCRVx1NUYwRlx1NjVGNlx1NTFGQVx1OTUxOVx1MzAwMgotSW52YWxpZE5DTmFtZUluRWxlbWVudFNjaGVtZURhdGEgPSBJbnZhbGlkTkNOYW1lSW5FbGVtZW50U2NoZW1lRGF0YTogZWxlbWVudCgpIFx1NjVCOVx1Njg0OFx1NTMwNVx1NTQyQiBOQ05hbWUgXHU2NUUwXHU2NTQ4XHU3Njg0IFNob3J0SGFuZCBcdTYzMDdcdTk0ODggJyd7MH0nJ1x1MzAwMgotSW52YWxpZENoaWxkU2VxdWVuY2VDaGFyYWN0ZXIgPSBJbnZhbGlkQ2hpbGRTZXF1ZW5jZUNoYXJhY3RlcjogZWxlbWVudCgpIFx1NjVCOVx1Njg0OFx1NTMwNVx1NTQyQlx1NjVFMFx1NjU0OFx1NzY4NFx1NUI1MFx1NUU4Rlx1NTIxN1x1NUI1N1x1N0IyNiAnJ3swfScnXHUzMDAyCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9YUG9pbnRlck1lc3NhZ2VzX3poX1RXLnByb3BlcnRpZXMgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL21zZy9YUG9pbnRlck1lc3NhZ2VzX3poX1RXLnByb3BlcnRpZXMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGJiNzQ3ZGQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC9tc2cvWFBvaW50ZXJNZXNzYWdlc196aF9UVy5wcm9wZXJ0aWVzCisrKyAvZGV2L251bGwKQEAgLTEsMjYgKzAsMCBAQAotIyBUaGlzIGZpbGUgc3RvcmVzIGxvY2FsaXplZCBtZXNzYWdlcyBmb3IgdGhlIFhlcmNlcyBYUG9pbnRlciBpbXBsZW1lbnRhdGlvbi4KLSMKLSMgVGhlIG1lc3NhZ2VzIGFyZSBhcnJhbmdlZCBpbiBrZXkgYW5kIHZhbHVlIHR1cGxlcyBpbiBhIExpc3RSZXNvdXJjZUJ1bmRsZS4KLSMKLQotIyBNZXNzYWdlcyBmb3IgbWVzc2FnZSByZXBvcnRpbmcKLUJhZE1lc3NhZ2VLZXkgPSBcdTYyN0VcdTRFMERcdTUyMzBcdTVDMERcdTYxQzlcdThBMEFcdTYwNkZcdTdEMjJcdTVGMTVcdTkzNzVcdTc2ODRcdTkzMkZcdThBQTRcdThBMEFcdTYwNkZcdTMwMDIKLUZvcm1hdEZhaWxlZCA9IFx1NjgzQ1x1NUYwRlx1NTMxNlx1NEUwQlx1NTIxN1x1OEEwQVx1NjA2Rlx1NjY0Mlx1NzY3Q1x1NzUxRlx1NTE2N1x1OTBFOFx1OTMyRlx1OEFBNDpcbgotCi0jIFhQb2ludGVyIEZyYW1ld29yayBFcnJvciBNZXNzYWdlcwotWFBvaW50ZXJQcm9jZXNzaW5nRXJyb3IgPSBYUG9pbnRlclByb2Nlc3NpbmdFcnJvcjogXHU4NjU1XHU3NDA2IFhQb2ludGVyIFx1ODg2OFx1NzkzQVx1NUYwRlx1NjY0Mlx1NzY3Q1x1NzUxRlx1OTMyRlx1OEFBNFx1MzAwMgotSW52YWxpZFhQb2ludGVyVG9rZW4gPSBJbnZhbGlkWFBvaW50ZXJUb2tlbjogWFBvaW50ZXIgXHU4ODY4XHU3OTNBXHU1RjBGXHU1MzA1XHU1NDJCXHU3MTIxXHU2NTQ4XHU4QTE4XHU4NjVGICcnezB9JycKLUludmFsaWRYUG9pbnRlckV4cHJlc3Npb24gPSBJbnZhbGlkWFBvaW50ZXJFeHByZXNzaW9uOiBYUG9pbnRlciBcdTg4NjhcdTc5M0FcdTVGMEYgJyd7MH0nJyBcdTcxMjFcdTY1NDhcdTMwMDIKLU11bHRpcGxlU2hvcnRIYW5kUG9pbnRlcnMgPSBNdWx0aXBsZVNob3J0SGFuZFBvaW50ZXJzOiBYUG9pbnRlciBcdTg4NjhcdTc5M0FcdTVGMEYgJyd7MH0nJyBcdTcxMjFcdTY1NDhcdTMwMDJcdTVCODNcdTUxNzdcdTY3MDlcdThEODVcdTkwNEVcdTRFMDBcdTUwMEJcdTRFRTVcdTRFMEFcdTc2ODQgU2hvcnRIYW5kIFx1NjMwN1x1NkExOVx1MzAwMgotU2NoZW1lRGF0YU5vdEZvbGxvd2VkQnlDbG9zZVBhcmVudGhlc2lzID0gU2NoZW1lRGF0YU5vdEZvbGxvd2VkQnlDbG9zZVBhcmVudGhlc2lzOiBYUG9pbnRlciBcdTg4NjhcdTc5M0FcdTVGMEYgJyd7MH0nJyBcdTcxMjFcdTY1NDhcdTMwMDJcdTdEQ0FcdTYzQTVcdTU3MjggU2NoZW1lRGF0YSBcdTRFNEJcdTVGOENcdTRFMERcdTY2MkYgJycpJycgXHU1QjU3XHU1MTQzXHUzMDAyCi1TY2hlbWVVbnN1cHBvcnRlZCA9IFNjaGVtZVVuc3VwcG9ydGVkOiBcdTRFMERcdTY1MkZcdTYzRjQgWFBvaW50ZXIgXHU5MTREXHU3RjZFICcnezB9JydcdTMwMDIKLUludmFsaWRTaG9ydEhhbmRQb2ludGVyID0gSW52YWxpZFNob3J0SGFuZFBvaW50ZXI6IFNob3J0SGFuZCBcdTYzMDdcdTZBMTkgJyd7MH0nJyBcdTc2ODQgTkNOYW1lIFx1NzEyMVx1NjU0OFx1MzAwMgotVW5iYWxhbmNlZFBhcmVudGhlc2lzSW5YUG9pbnRlckV4cHJlc3Npb24gPSBVbmJhbGFuY2VkUGFyZW50aGVzaXNJblhQb2ludGVyRXhwcmVzc2lvbjogWFBvaW50ZXIgXHU4ODY4XHU3OTNBXHU1RjBGICcnezB9JycgXHU3MTIxXHU2NTQ4XHUzMDAyXHU1REU2XHU2MkVDXHU4NjVGXHU3Njg0XHU2NTc4XHU3NkVFICcnezF9JycgXHU0RTBEXHU3QjQ5XHU2NUJDXHU1M0YzXHU2MkVDXHU4NjVGXHU3Njg0XHU2NTc4XHU3NkVFICcnezJ9JydcdTMwMDIKLUludmFsaWRTY2hlbWVEYXRhSW5YUG9pbnRlciA9IEludmFsaWRTY2hlbWVEYXRhSW5YUG9pbnRlcjogWFBvaW50ZXIgXHU4ODY4XHU3OTNBXHU1RjBGICcnezB9JycgXHU1MzA1XHU1NDJCXHU3MTIxXHU2NTQ4XHU3Njg0IFNjaGVtZURhdGFcdTMwMDIKLQotIyBYUG9pbnRlciBFbGVtZW50IFNjaGVtZSBFcnJvciBNZXNzYWdlcwotSW52YWxpZEVsZW1lbnRTY2hlbWVUb2tlbiA9IEludmFsaWRFbGVtZW50U2NoZW1lVG9rZW46IGVsZW1lbnQoKSBcdTkxNERcdTdGNkUgWFBvaW50ZXIgXHU4ODY4XHU3OTNBXHU1RjBGXHU1MzA1XHU1NDJCXHU3MTIxXHU2NTQ4XHU4QTE4XHU4NjVGICcnezB9JycKLUludmFsaWRFbGVtZW50U2NoZW1lWFBvaW50ZXIgPSBJbnZhbGlkRWxlbWVudFNjaGVtZVhQb2ludGVyOiBcdTUxNDNcdTdEMjBcdTkxNERcdTdGNkUgWFBvaW50ZXIgXHU4ODY4XHU3OTNBXHU1RjBGICcnezB9JycgXHU3MTIxXHU2NTQ4XHUzMDAyCi1YUG9pbnRlckVsZW1lbnRTY2hlbWVQcm9jZXNzaW5nRXJyb3IgPSBYUG9pbnRlckVsZW1lbnRTY2hlbWVQcm9jZXNzaW5nRXJyb3I6IFx1ODY1NVx1NzQwNiBYUG9pbnRlciBlbGVtZW50KCkgXHU5MTREXHU3RjZFXHU4ODY4XHU3OTNBXHU1RjBGXHU2NjQyXHU3NjdDXHU3NTFGXHU5MzJGXHU4QUE0XHUzMDAyCi1JbnZhbGlkTkNOYW1lSW5FbGVtZW50U2NoZW1lRGF0YSA9IEludmFsaWROQ05hbWVJbkVsZW1lbnRTY2hlbWVEYXRhOiBlbGVtZW50KCkgXHU5MTREXHU3RjZFXHU1MzA1XHU1NDJCXHU1MTc3XHU2NzA5XHU3MTIxXHU2NTQ4IE5DTmFtZSBcdTc2ODQgU2hvcnRIYW5kIFx1NjMwN1x1NkExOSAnJ3swfScnXHUzMDAyCi1JbnZhbGlkQ2hpbGRTZXF1ZW5jZUNoYXJhY3RlciA9IEludmFsaWRDaGlsZFNlcXVlbmNlQ2hhcmFjdGVyOiBlbGVtZW50KCkgXHU5MTREXHU3RjZFXHU1MzA1XHU1NDJCXHU3MTIxXHU2NTQ4XHU1QjUwXHU5ODA1XHU5ODA2XHU1RThGXHU1QjU3XHU1MTQzICcnezB9JydcdTMwMDIKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvdmFsaWRhdGlvbi9FbnRpdHlTdGF0ZS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC92YWxpZGF0aW9uL0VudGl0eVN0YXRlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDg2YTkyMTUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC92YWxpZGF0aW9uL0VudGl0eVN0YXRlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0OSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLCAyMDAyLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC52YWxpZGF0aW9uOwotCi0KLS8qKgotICogVGhlIGVudGl0eSBzdGF0ZSBpbnRlcmZhY2UgZGVmaW5lcyBtZXRob2RzIHRoYXQgbXVzdCBiZSBpbXBsZW1lbnRlZAotICogYnkgY29tcG9uZW50cyB0aGF0IHN0b3JlIGluZm9ybWF0aW9uIGFib3V0IGVudGl0eSBkZWNsYXJhdGlvbnMsIGFzIHdlbGwgYXMgYnkKLSAqIGVudGl0eSB2YWxpZGF0b3IgdGhhdCB3aWxsIG5lZWQgdG8gdmFsaWRhdGUgYXR0cmlidXRlcyBvZiB0eXBlIGVudGl0eS4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBFbGVuYSBMaXRhbmksIElCTQotICovCi1wdWJsaWMgaW50ZXJmYWNlIEVudGl0eVN0YXRlIHsKLSAgICAvKioKLSAgICAgKiBRdWVyeSBtZXRob2QgdG8gY2hlY2sgaWYgZW50aXR5IHdpdGggdGhpcyBuYW1lIHdhcyBkZWNsYXJlZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lCi0gICAgICogQHJldHVybiB0cnVlIGlmIG5hbWUgaXMgYSBkZWNsYXJlZCBlbnRpdHkKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0VudGl0eURlY2xhcmVkIChTdHJpbmcgbmFtZSk7Ci0KLSAgICAvKioKLSAgICAgKiBRdWVyeSBtZXRob2QgdG8gY2hlY2sgaWYgZW50aXR5IGlzIHVucGFyc2VkLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUKLSAgICAgKiBAcmV0dXJuIHRydWUgaWYgbmFtZSBpcyBhbiB1bnBhcnNlZCBlbnRpdHkKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0VudGl0eVVucGFyc2VkIChTdHJpbmcgbmFtZSk7Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3ZhbGlkYXRpb24vVmFsaWRhdGlvbk1hbmFnZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvdmFsaWRhdGlvbi9WYWxpZGF0aW9uTWFuYWdlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2N2U5NTM1Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvdmFsaWRhdGlvbi9WYWxpZGF0aW9uTWFuYWdlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsODUgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDAyLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC52YWxpZGF0aW9uOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotLyoqCi0gKiBWYWxpZGF0aW9uTWFuYWdlciBpcyBhIGNvb3JkaW5hdG9yIHByb3BlcnR5IGZvciB2YWxpZGF0b3JzIGluIHRoZQotICogcGlwZWxpbmUuIEVhY2ggdmFsaWRhdG9yIG11c3Qga25vdyBob3cgdG8gaW50ZXJhY3Qgd2l0aAotICogdGhpcyBwcm9wZXJ0eS4gVmFsaWRhdG9ycyBhcmUgbm90IHJlcXVpcmVkIHRvIGtub3cgd2hhdCBraW5kIG9mCi0gKiBvdGhlciB2YWxpZGF0b3JzIHByZXNlbnQgaW4gdGhlIHBpcGVsaW5lLCBidXQgc2hvdWxkIHVuZGVyc3RhbmQKLSAqIHRoYXQgdGhlcmUgYXJlIG90aGVycyBhbmQgdGhhdCBzb21lIGNvb3JkaW5hdGlvbiBpcyByZXF1aXJlZC4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBFbGVuYSBMaXRhbmksIElCTQotICovCi1wdWJsaWMgY2xhc3MgVmFsaWRhdGlvbk1hbmFnZXIgewotCi0gICAgcHJvdGVjdGVkIGZpbmFsIFZlY3RvciBmVlNzID0gbmV3IFZlY3RvcigpOwotICAgIHByb3RlY3RlZCBib29sZWFuIGZHcmFtbWFyRm91bmQgPSBmYWxzZTsKLQotICAgIC8vIHVzZWQgYnkgdGhlIERURCB2YWxpZGF0b3IgdG8gdGVsbCBvdGhlciBjb21wb25lbnRzIHRoYXQgaXQgaGFzIGEKLSAgICAvLyBjYWNoZWQgRFREIGluIGhhbmQgc28gdGhlcmUncyBubyByZWFzb24gdG8KLSAgICAvLyBzY2FuIGV4dGVybmFsIHN1YnNldCBvciBlbnRpdHkgZGVjbHMuCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZkNhY2hlZERURCA9IGZhbHNlOwotCi0gICAgLyoqCi0gICAgICogRWFjaCB2YWxpZGF0b3Igc2hvdWxkIGNhbGwgdGhpcyBtZXRob2QgdG8gYWRkIGl0cyBWYWxpZGF0aW9uU3RhdGUgaW50bwotICAgICAqIHRoZSB2YWxpZGF0aW9uIG1hbmFnZXIuCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIHZvaWQgYWRkVmFsaWRhdGlvblN0YXRlKFZhbGlkYXRpb25TdGF0ZSB2cykgewotICAgICAgICBmVlNzLmFkZEVsZW1lbnQodnMpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldCB0aGUgaW5mb3JtYXRpb24gcmVxdWlyZWQgdG8gdmFsaWRhdGUgZW50aXR5IHZhbHVlcy4KLSAgICAgKi8KLSAgICBwdWJsaWMgZmluYWwgdm9pZCBzZXRFbnRpdHlTdGF0ZShFbnRpdHlTdGF0ZSBzdGF0ZSkgewotICAgICAgICBmb3IgKGludCBpID0gZlZTcy5zaXplKCktMTsgaSA+PSAwOyBpLS0pIHsKLSAgICAgICAgICAgICgoVmFsaWRhdGlvblN0YXRlKWZWU3MuZWxlbWVudEF0KGkpKS5zZXRFbnRpdHlTdGF0ZShzdGF0ZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgZmluYWwgdm9pZCBzZXRHcmFtbWFyRm91bmQoYm9vbGVhbiBncmFtbWFyKXsKLSAgICAgICAgZkdyYW1tYXJGb3VuZCA9IGdyYW1tYXI7Ci0gICAgfQotCi0gICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNHcmFtbWFyRm91bmQoKXsKLSAgICAgICAgcmV0dXJuIGZHcmFtbWFyRm91bmQ7Ci0gICAgfQotCi0gICAgcHVibGljIGZpbmFsIHZvaWQgc2V0Q2FjaGVkRFREKGJvb2xlYW4gY2FjaGVkRFREKSB7Ci0gICAgICAgIGZDYWNoZWREVEQgPSBjYWNoZWREVEQ7Ci0gICAgfSAvLyBzZXRDYWNoZWREVEQoYm9vbGVhbikKLQotICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzQ2FjaGVkRFREKCkgewotICAgICAgICByZXR1cm4gZkNhY2hlZERURDsKLSAgICB9IC8vIGlzQ2FjaGVkRFREKCk6ICBib29sZWFuCi0KLQotICAgIHB1YmxpYyBmaW5hbCB2b2lkIHJlc2V0ICgpewotICAgICAgICBmVlNzLnJlbW92ZUFsbEVsZW1lbnRzKCk7Ci0gICAgICAgIGZHcmFtbWFyRm91bmQgPSBmYWxzZTsKLSAgICAgICAgZkNhY2hlZERURCA9IGZhbHNlOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvdmFsaWRhdGlvbi9WYWxpZGF0aW9uU3RhdGUuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwvdmFsaWRhdGlvbi9WYWxpZGF0aW9uU3RhdGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYTA0YzU3ZC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3ZhbGlkYXRpb24vVmFsaWRhdGlvblN0YXRlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMTIgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMSwgMjAwMiwyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwudmFsaWRhdGlvbjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5TeW1ib2xUYWJsZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYuVmFsaWRhdGlvbkNvbnRleHQ7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5OYW1lc3BhY2VDb250ZXh0OwotaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7Ci1pbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKLQotLyoqCi0gKiBJbXBsZW1lbnRhdGlvbiBvZiBWYWxpZGF0aW9uQ29udGV4dCBpbnRlZmFjZS4gVXNlZCB0byBlc3RhYmxpc2ggYW4KLSAqIGVudmlyb25tZW50IGZvciBzaW1wbGUgdHlwZSB2YWxpZGF0aW9uLgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIEVsZW5hIExpdGFuaSwgSUJNCi0gKiBAdmVyc2lvbiAkSWQ6IFZhbGlkYXRpb25TdGF0ZS5qYXZhLHYgMS43IDIwMTAtMTEtMDEgMDQ6Mzk6NTMgam9laHcgRXhwICQKLSAqLwotcHVibGljIGNsYXNzIFZhbGlkYXRpb25TdGF0ZSBpbXBsZW1lbnRzIFZhbGlkYXRpb25Db250ZXh0IHsKLQotICAgIC8vCi0gICAgLy8gcHJpdmF0ZSBkYXRhCi0gICAgLy8KLSAgICBwcml2YXRlIGJvb2xlYW4gZkV4dHJhQ2hlY2tpbmcgICAgICAgICAgICAgID0gdHJ1ZTsKLSAgICBwcml2YXRlIGJvb2xlYW4gZkZhY2V0Q2hlY2tpbmcgICAgICAgICAgICAgID0gdHJ1ZTsKLSAgICBwcml2YXRlIGJvb2xlYW4gZk5vcm1hbGl6ZSAgICAgICAgICAgICAgICAgID0gdHJ1ZTsKLSAgICBwcml2YXRlIGJvb2xlYW4gZk5hbWVzcGFjZXMgICAgICAgICAgICAgICAgID0gdHJ1ZTsKLQotICAgIHByaXZhdGUgRW50aXR5U3RhdGUgZkVudGl0eVN0YXRlICAgICAgICAgICAgPSBudWxsOwotICAgIHByaXZhdGUgTmFtZXNwYWNlQ29udGV4dCBmTmFtZXNwYWNlQ29udGV4dCAgPSBudWxsOwotICAgIHByaXZhdGUgU3ltYm9sVGFibGUgZlN5bWJvbFRhYmxlICAgICAgICAgICAgPSBudWxsOwotICAgIHByaXZhdGUgTG9jYWxlIGZMb2NhbGUgICAgICAgICAgICAgICAgICAgICAgPSBudWxsOwotCi0gICAgcHJpdmF0ZSBBcnJheUxpc3Q8U3RyaW5nPiBmSWRMaXN0OwotICAgIHByaXZhdGUgQXJyYXlMaXN0PFN0cmluZz4gZklkUmVmTGlzdDsKLQotICAgIC8vCi0gICAgLy8gcHVibGljIG1ldGhvZHMKLSAgICAvLwotICAgIHB1YmxpYyB2b2lkIHNldEV4dHJhQ2hlY2tpbmcoYm9vbGVhbiBuZXdWYWx1ZSkgewotICAgICAgICBmRXh0cmFDaGVja2luZyA9IG5ld1ZhbHVlOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldEZhY2V0Q2hlY2tpbmcoYm9vbGVhbiBuZXdWYWx1ZSkgewotICAgICAgICBmRmFjZXRDaGVja2luZyA9IG5ld1ZhbHVlOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldE5vcm1hbGl6YXRpb25SZXF1aXJlZCAoYm9vbGVhbiBuZXdWYWx1ZSkgewotICAgICAgICAgIGZOb3JtYWxpemUgPSBuZXdWYWx1ZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRVc2luZ05hbWVzcGFjZXMgKGJvb2xlYW4gbmV3VmFsdWUpIHsKLSAgICAgICAgICBmTmFtZXNwYWNlcyA9IG5ld1ZhbHVlOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldEVudGl0eVN0YXRlKEVudGl0eVN0YXRlIHN0YXRlKSB7Ci0gICAgICAgIGZFbnRpdHlTdGF0ZSA9IHN0YXRlOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldE5hbWVzcGFjZVN1cHBvcnQoTmFtZXNwYWNlQ29udGV4dCBuYW1lc3BhY2UpIHsKLSAgICAgICAgZk5hbWVzcGFjZUNvbnRleHQgPSBuYW1lc3BhY2U7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0U3ltYm9sVGFibGUoU3ltYm9sVGFibGUgc1RhYmxlKSB7Ci0gICAgICAgIGZTeW1ib2xUYWJsZSA9IHNUYWJsZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiByZXR1cm4gbnVsbCBpZiBhbGwgSURSRUYgdmFsdWVzIGhhdmUgYSBjb3JyZXNwb25kaW5nIElEIHZhbHVlOwotICAgICAqIG90aGVyd2lzZSByZXR1cm4gdGhlIGZpcnN0IElEUkVGIHZhbHVlIHdpdGhvdXQgYSBtYXRjaGluZyBJRCB2YWx1ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGNoZWNrSURSZWZJRCAoKSB7Ci0gICAgICAgIGlmIChmSWRMaXN0ID09IG51bGwpIHsKLSAgICAgICAgICAgIGlmIChmSWRSZWZMaXN0ICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZklkUmVmTGlzdC5nZXQoMCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoZklkUmVmTGlzdCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBTdHJpbmcga2V5OwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmSWRSZWZMaXN0LnNpemUoKTsgaSsrKSB7Ci0gICAgICAgICAgICAgICAga2V5ID0gZklkUmVmTGlzdC5nZXQoaSk7Ci0gICAgICAgICAgICAgICAgaWYgKCFmSWRMaXN0LmNvbnRhaW5zKGtleSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICByZXR1cm4ga2V5OwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCByZXNldCAoKSB7Ci0gICAgICAgIGZFeHRyYUNoZWNraW5nID0gdHJ1ZTsKLSAgICAgICAgZkZhY2V0Q2hlY2tpbmcgPSB0cnVlOwotICAgICAgICBmTmFtZXNwYWNlcyA9IHRydWU7Ci0gICAgICAgIGZJZExpc3QgPSBudWxsOwotICAgICAgICBmSWRSZWZMaXN0ID0gbnVsbDsKLSAgICAgICAgZkVudGl0eVN0YXRlID0gbnVsbDsKLSAgICAgICAgZk5hbWVzcGFjZUNvbnRleHQgPSBudWxsOwotICAgICAgICBmU3ltYm9sVGFibGUgPSBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoZSBzYW1lIHZhbGlkYXRpb24gc3RhdGUgY2FuIGJlIHVzZWQgdG8gdmFsaWRhdGUgbW9yZSB0aGFuIG9uZSAoc2NoZW1hKQotICAgICAqIHZhbGlkYXRpb24gcm9vdHMuIEVudGl0eS9OYW1lc3BhY2UvU3ltYm9sIGFyZSBzaGFyZWQsIGJ1dCBlYWNoIHZhbGlkYXRpb24KLSAgICAgKiByb290IG5lZWRzIGl0cyBvd24gaWQvaWRyZWYgdGFibGVzLiBTbyB3ZSBuZWVkIHRoaXMgbWV0aG9kIHRvIHJlc2V0IG9ubHkKLSAgICAgKiB0aGUgdHdvIHRhYmxlcy4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCByZXNldElEVGFibGVzKCkgewotICAgICAgICBmSWRMaXN0ID0gbnVsbDsKLSAgICAgICAgZklkUmVmTGlzdCA9IG51bGw7Ci0gICAgfQotCi0gICAgLy8KLSAgICAvLyBpbXBsZW1lbnRhdGlvbiBvZiBWYWxpZGF0aW9uQ29udGV4dCBtZXRob2RzCi0gICAgLy8KLQotICAgIC8vIHdoZXRoZXIgdG8gZG8gZXh0cmEgaWQvaWRyZWYvZW50aXR5IGNoZWNraW5nCi0gICAgcHVibGljIGJvb2xlYW4gbmVlZEV4dHJhQ2hlY2tpbmcoKSB7Ci0gICAgICAgIHJldHVybiBmRXh0cmFDaGVja2luZzsKLSAgICB9Ci0KLSAgICAvLyB3aGV0aGVyIHRvIHZhbGlkYXRlIGFnYWluc3QgZmFjZXRzCi0gICAgcHVibGljIGJvb2xlYW4gbmVlZEZhY2V0Q2hlY2tpbmcoKSB7Ci0gICAgICAgIHJldHVybiBmRmFjZXRDaGVja2luZzsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBuZWVkVG9Ob3JtYWxpemUgKCl7Ci0gICAgICAgIHJldHVybiBmTm9ybWFsaXplOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIHVzZU5hbWVzcGFjZXMoKSB7Ci0gICAgICAgIHJldHVybiBmTmFtZXNwYWNlczsKLSAgICB9Ci0KLSAgICAvLyBlbnRpdHkKLSAgICBwdWJsaWMgYm9vbGVhbiBpc0VudGl0eURlY2xhcmVkIChTdHJpbmcgbmFtZSkgewotICAgICAgICBpZiAoZkVudGl0eVN0YXRlICE9bnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIGZFbnRpdHlTdGF0ZS5pc0VudGl0eURlY2xhcmVkKGdldFN5bWJvbChuYW1lKSk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0VudGl0eVVucGFyc2VkIChTdHJpbmcgbmFtZSkgewotICAgICAgICBpZiAoZkVudGl0eVN0YXRlICE9bnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIGZFbnRpdHlTdGF0ZS5pc0VudGl0eVVucGFyc2VkKGdldFN5bWJvbChuYW1lKSk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIC8vIGlkCi0gICAgcHVibGljIGJvb2xlYW4gaXNJZERlY2xhcmVkKFN0cmluZyBuYW1lKSB7Ci0gICAgICAgIGlmIChmSWRMaXN0ID09IG51bGwpIHJldHVybiBmYWxzZTsKLSAgICAgICAgcmV0dXJuIGZJZExpc3QuY29udGFpbnMobmFtZSk7Ci0gICAgfQotICAgIHB1YmxpYyB2b2lkIGFkZElkKFN0cmluZyBuYW1lKSB7Ci0gICAgICAgIGlmIChmSWRMaXN0ID09IG51bGwpIGZJZExpc3QgPSBuZXcgQXJyYXlMaXN0KCk7Ci0gICAgICAgIGZJZExpc3QuYWRkKG5hbWUpOwotICAgIH0KLQotICAgIC8vIGlkcmVmCi0gICAgcHVibGljIHZvaWQgYWRkSWRSZWYoU3RyaW5nIG5hbWUpIHsKLSAgICAgICAgaWYgKGZJZFJlZkxpc3QgPT0gbnVsbCkgZklkUmVmTGlzdCA9IG5ldyBBcnJheUxpc3QoKTsKLSAgICAgICAgZklkUmVmTGlzdC5hZGQobmFtZSk7Ci0gICAgfQotICAgIC8vIGdldCBzeW1ib2xzCi0KLSAgICBwdWJsaWMgU3RyaW5nIGdldFN5bWJvbCAoU3RyaW5nIHN5bWJvbCkgewotICAgICAgICBpZiAoZlN5bWJvbFRhYmxlICE9IG51bGwpCi0gICAgICAgICAgICByZXR1cm4gZlN5bWJvbFRhYmxlLmFkZFN5bWJvbChzeW1ib2wpOwotICAgICAgICAvLyBpZiB0aGVyZSBpcyBubyBzeW1ib2wgdGFibGUsIHdlIHJldHVybiBqYXZhLWludGVybmFsaXplZCBzdHJpbmcsCi0gICAgICAgIC8vIGJlY2F1c2Ugc3ltYm9sIHRhYmxlIHN0cmluZ3MgYXJlIGFsc28gamF2YS1pbnRlcm5hbHppZWQuCi0gICAgICAgIC8vIHRoaXMgZ3VhcmFudGVlcyB0aGF0IHRoZSByZXR1cm5lZCBzdHJpbmcgZnJvbSB0aGlzIG1ldGhvZCBjYW4gYmUKLSAgICAgICAgLy8gY29tcGFyZWQgYnkgcmVmZXJlbmNlIHdpdGggb3RoZXIgc3ltYm9sIHRhYmxlIHN0cmluZy4gLVNHCi0gICAgICAgIHJldHVybiBzeW1ib2wuaW50ZXJuKCk7Ci0gICAgfQotICAgIC8vIHFuYW1lLCBub3RhdGlvbgotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VVJJKFN0cmluZyBwcmVmaXgpIHsKLSAgICAgICAgaWYgKGZOYW1lc3BhY2VDb250ZXh0ICE9bnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIGZOYW1lc3BhY2VDb250ZXh0LmdldFVSSShwcmVmaXgpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8vIExvY2FsZQotCi0gICAgcHVibGljIHZvaWQgc2V0TG9jYWxlKExvY2FsZSBsb2NhbGUpIHsKLSAgICAgICAgZkxvY2FsZSA9IGxvY2FsZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgTG9jYWxlIGdldExvY2FsZSgpIHsKLSAgICAgICAgcmV0dXJuIGZMb2NhbGU7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cGF0aC9YUGF0aC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cGF0aC9YUGF0aC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiZTJlMzExLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHBhdGgvWFBhdGguamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIwMjYgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAxNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqLwotLyoKLSAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQotICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCi0gKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCi0gKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAotICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKLSAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cGF0aDsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5TeW1ib2xUYWJsZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuWE1MQ2hhcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuWE1MU3ltYm9sczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5OYW1lc3BhY2VDb250ZXh0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlFOYW1lOwotaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwotaW1wb3J0IGphdmEudXRpbC5NYXA7Ci1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotLyoqCi0gKiBCYXJlIG1pbmltdW0gWFBhdGggcGFyc2VyLgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIEFuZHkgQ2xhcmssIElCTQotICogQGF1dGhvciBTdW5pdGhhIFJlZGR5LCBTdW4gTWljcm9zeXN0ZW1zCi0gKi8KLXB1YmxpYyBjbGFzcyBYUGF0aCB7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0YW50cwotICAgIC8vCi0KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIERFQlVHX0FMTCA9IGZhbHNlOwotCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbiBERUJVR19YUEFUSF9QQVJTRSA9IERFQlVHX0FMTCB8fCBmYWxzZTsKLQotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW4gREVCVUdfQU5ZID0gREVCVUdfWFBBVEhfUEFSU0U7Ci0KLSAgICAvLwotICAgIC8vIERhdGEKLSAgICAvLwotCi0gICAgLyoqIEV4cHJlc3Npb24uICovCi0gICAgcHJvdGVjdGVkIFN0cmluZyBmRXhwcmVzc2lvbjsKLQotICAgIC8qKiBTeW1ib2wgdGFibGUuICovCi0gICAgcHJvdGVjdGVkIFN5bWJvbFRhYmxlIGZTeW1ib2xUYWJsZTsKLQotICAgIC8qKiBMb2NhdGlvbiBwYXRocy4gKi8KLSAgICBwcm90ZWN0ZWQgTG9jYXRpb25QYXRoW10gZkxvY2F0aW9uUGF0aHM7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0cnVjdG9ycwotICAgIC8vCi0KLSAgICAvKiogQ29uc3RydWN0cyBhbiBYUGF0aCBvYmplY3QgZnJvbSB0aGUgc3BlY2lmaWVkIGV4cHJlc3Npb24uICovCi0gICAgcHVibGljIFhQYXRoKFN0cmluZyB4cGF0aCwgU3ltYm9sVGFibGUgc3ltYm9sVGFibGUsCi0gICAgICAgICAgICAgICAgIE5hbWVzcGFjZUNvbnRleHQgY29udGV4dCkKLSAgICAgICAgdGhyb3dzIFhQYXRoRXhjZXB0aW9uIHsKLSAgICAgICAgZkV4cHJlc3Npb24gPSB4cGF0aDsKLSAgICAgICAgZlN5bWJvbFRhYmxlID0gc3ltYm9sVGFibGU7Ci0gICAgICAgIHBhcnNlRXhwcmVzc2lvbihjb250ZXh0KTsKLSAgICB9IC8vIDxpbml0PihTdHJpbmcsU3ltYm9sVGFibGUsTmFtZXNwYWNlQ29udGV4dCkKLQotICAgIC8vCi0gICAgLy8gUHVibGljIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhIHJlcHJlc2VudGF0aW9uIG9mIGFsbCBsb2NhdGlvbiBwYXRocyBmb3IgdGhpcyBYUGF0aC4KLSAgICAgKiBYUGF0aCA9IGxvY2F0aW9uUGF0aCAoICd8JyBsb2NhdGlvblBhdGgpCi0gICAgICovCi0gICAgcHVibGljIExvY2F0aW9uUGF0aFtdIGdldExvY2F0aW9uUGF0aHMoKSB7Ci0gICAgICAgIExvY2F0aW9uUGF0aFtdIHJldD1uZXcgTG9jYXRpb25QYXRoW2ZMb2NhdGlvblBhdGhzLmxlbmd0aF07Ci0gICAgICAgIGZvciAoaW50IGk9MDtpPGZMb2NhdGlvblBhdGhzLmxlbmd0aDtpKyspewotICAgICAgICAgICAgcmV0W2ldPShMb2NhdGlvblBhdGgpZkxvY2F0aW9uUGF0aHNbaV0uY2xvbmUoKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gcmV0OwotICAgIH0gLy8gZ2V0TG9jYXRpb25QYXRoKExvY2F0aW9uUGF0aCkKLQotICAgIC8qKiBSZXR1cm5zIGEgcmVwcmVzZW50YXRpb24gb2YgdGhlIGZpcnN0IGxvY2F0aW9uIHBhdGggZm9yIHRoaXMgWFBhdGguICovCi0gICAgcHVibGljIExvY2F0aW9uUGF0aCBnZXRMb2NhdGlvblBhdGgoKSB7Ci0gICAgICAgIHJldHVybiAoTG9jYXRpb25QYXRoKWZMb2NhdGlvblBhdGhzWzBdLmNsb25lKCk7Ci0gICAgfSAvLyBnZXRMb2NhdGlvblBhdGgoTG9jYXRpb25QYXRoKQotCi0gICAgLy8KLSAgICAvLyBPYmplY3QgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKiogUmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIG9iamVjdC4gKi8KLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgICAgICBTdHJpbmdCdWZmZXIgYnVmPW5ldyBTdHJpbmdCdWZmZXIoKTsKLSAgICAgICAgZm9yIChpbnQgIGk9MDtpPGZMb2NhdGlvblBhdGhzLmxlbmd0aDtpKyspewotICAgICAgICAgICAgaWYgKGk+MCl7Ci0gICAgICAgICAgICAgICAgYnVmLmFwcGVuZCgifCIpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgYnVmLmFwcGVuZChmTG9jYXRpb25QYXRoc1tpXS50b1N0cmluZygpKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gYnVmLnRvU3RyaW5nKCk7Ci0gICAgfSAvLyB0b1N0cmluZygpOlN0cmluZwotCi0gICAgLy8KLSAgICAvLyBQcml2YXRlIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogVXNlZCBieSB0aGUge0BsaW5rICNwYXJzZUV4cHJlc3Npb24oTmFtZXNwYWNlQ29udGV4dCl9IG1ldGhvZAotICAgICAqIHRvIHZlcmlmeSB0aGUgYXNzdW1wdGlvbi4KLSAgICAgKgotICAgICAqIElmIDx0dD5iPC90dD4gaXMgZmFsc2UsIHRoaXMgbWV0aG9kIHRocm93cyBYUGF0aEV4Y2VwdGlvbgotICAgICAqIHRvIHJlcG9ydCB0aGUgZXJyb3IuCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBjaGVjayggYm9vbGVhbiBiICkgdGhyb3dzIFhQYXRoRXhjZXB0aW9uIHsKLSAgICAgICAgaWYoIWIpICAgICAgdGhyb3cgbmV3IFhQYXRoRXhjZXB0aW9uKCJjLWdlbmVyYWwteHBhdGgiKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBVc2VkIGJ5IHRoZSB7QGxpbmsgI3BhcnNlRXhwcmVzc2lvbihOYW1lc3BhY2VDb250ZXh0KX0gbWV0aG9kCi0gICAgICogdG8gYnVpbGQgYSB7QGxpbmsgTG9jYXRpb25QYXRofSBvYmplY3QgZnJvbSB0aGUgYWNjdW11bGF0ZWQKLSAgICAgKiB7QGxpbmsgU3RlcH1zLgotICAgICAqLwotICAgIHByaXZhdGUgTG9jYXRpb25QYXRoIGJ1aWxkTG9jYXRpb25QYXRoKCBWZWN0b3Igc3RlcHNWZWN0b3IgKSB0aHJvd3MgWFBhdGhFeGNlcHRpb24gewotICAgICAgICBpbnQgc2l6ZSA9IHN0ZXBzVmVjdG9yLnNpemUoKTsKLSAgICAgICAgY2hlY2soc2l6ZSE9MCk7Ci0gICAgICAgIFN0ZXBbXSBzdGVwcyA9IG5ldyBTdGVwW3NpemVdOwotICAgICAgICBzdGVwc1ZlY3Rvci5jb3B5SW50byhzdGVwcyk7Ci0gICAgICAgIHN0ZXBzVmVjdG9yLnJlbW92ZUFsbEVsZW1lbnRzKCk7Ci0KLSAgICAgICAgcmV0dXJuIG5ldyBMb2NhdGlvblBhdGgoc3RlcHMpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIGlzIGltcGxlbWVudGVkIGJ5IHVzaW5nIHRoZSBYUGF0aEV4cHJTY2FubmVyIGFuZAotICAgICAqIGV4YW1pbmluZyB0aGUgbGlzdCBvZiB0b2tlbnMgdGhhdCBpdCByZXR1cm5zLgotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCBwYXJzZUV4cHJlc3Npb24oZmluYWwgTmFtZXNwYWNlQ29udGV4dCBjb250ZXh0KQotICAgICAgICB0aHJvd3MgWFBhdGhFeGNlcHRpb24gewotCi0gICAgICAgIC8vIHRva2VucwotICAgICAgICBmaW5hbCBYUGF0aC5Ub2tlbnMgeHRva2VucyA9IG5ldyBYUGF0aC5Ub2tlbnMoZlN5bWJvbFRhYmxlKTsKLQotICAgICAgICAvLyBzY2FubmVyCi0gICAgICAgIFhQYXRoLlNjYW5uZXIgc2Nhbm5lciA9IG5ldyBYUGF0aC5TY2FubmVyKGZTeW1ib2xUYWJsZSkgewotICAgICAgICAgICAgcHJvdGVjdGVkIHZvaWQgYWRkVG9rZW4oWFBhdGguVG9rZW5zIHRva2VucywgaW50IHRva2VuKQotICAgICAgICAgICAgICAgIHRocm93cyBYUGF0aEV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICAgICAgaWYgKAotICAgICAgICAgICAgICAgICAgICB0b2tlbiA9PSBYUGF0aC5Ub2tlbnMuRVhQUlRPS0VOX0FUU0lHTiB8fAotICAgICAgICAgICAgICAgICAgICB0b2tlbiA9PSBYUGF0aC5Ub2tlbnMuRVhQUlRPS0VOX0FYSVNOQU1FX0FUVFJJQlVURSB8fAotICAgICAgICAgICAgICAgICAgICB0b2tlbiA9PSBYUGF0aC5Ub2tlbnMuRVhQUlRPS0VOX05BTUVURVNUX1FOQU1FIHx8Ci0gICAgICAgICAgICAgICAgICAgIHRva2VuID09IFhQYXRoLlRva2Vucy5FWFBSVE9LRU5fT1BFUkFUT1JfU0xBU0ggfHwKLSAgICAgICAgICAgICAgICAgICAgdG9rZW4gPT0gWFBhdGguVG9rZW5zLkVYUFJUT0tFTl9QRVJJT0QgfHwKLSAgICAgICAgICAgICAgICAgICAgdG9rZW4gPT0gWFBhdGguVG9rZW5zLkVYUFJUT0tFTl9OQU1FVEVTVF9BTlkgfHwKLSAgICAgICAgICAgICAgICAgICAgdG9rZW4gPT0gWFBhdGguVG9rZW5zLkVYUFJUT0tFTl9OQU1FVEVTVF9OQU1FU1BBQ0UgfHwKLSAgICAgICAgICAgICAgICAgICAgdG9rZW4gPT0gWFBhdGguVG9rZW5zLkVYUFJUT0tFTl9PUEVSQVRPUl9ET1VCTEVfU0xBU0ggfHwKLSAgICAgICAgICAgICAgICAgICAgdG9rZW4gPT0gWFBhdGguVG9rZW5zLkVYUFJUT0tFTl9PUEVSQVRPUl9VTklPTiB8fAotICAgICAgICAgICAgICAgICAgICB0b2tlbiA9PSBYUGF0aC5Ub2tlbnMuRVhQUlRPS0VOX0FYSVNOQU1FX0NISUxEIHx8Ci0gICAgICAgICAgICAgICAgICAgIHRva2VuID09IFhQYXRoLlRva2Vucy5FWFBSVE9LRU5fRE9VQkxFX0NPTE9OCi0gICAgICAgICAgICAgICAgICAgICkgewotICAgICAgICAgICAgICAgICAgICBzdXBlci5hZGRUb2tlbih0b2tlbnMsIHRva2VuKTsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWFBhdGhFeGNlcHRpb24oImMtZ2VuZXJhbC14cGF0aCIpOwotICAgICAgICAgICAgfQotICAgICAgICB9OwotCi0gICAgICAgIGludCBsZW5ndGggPSBmRXhwcmVzc2lvbi5sZW5ndGgoKTsKLQotICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSBzY2FubmVyLnNjYW5FeHByKGZTeW1ib2xUYWJsZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4dG9rZW5zLCBmRXhwcmVzc2lvbiwgMCwgbGVuZ3RoKTsKLSAgICAgICAgaWYoIXN1Y2Nlc3MpCi0gICAgICAgICAgICB0aHJvdyBuZXcgWFBhdGhFeGNlcHRpb24oImMtZ2VuZXJhbC14cGF0aCIpOwotCi0gICAgICAgIC8vZlRva2Vucy5kdW1wVG9rZW5zKCk7Ci0gICAgICAgIFZlY3RvciBzdGVwc1ZlY3RvciA9IG5ldyBWZWN0b3IoKTsKLSAgICAgICAgVmVjdG9yIGxvY2F0aW9uUGF0aHNWZWN0b3I9IG5ldyBWZWN0b3IoKTsKLQotICAgICAgICAvLyB0cnVlIHdoZW4gdGhlIG5leHQgdG9rZW4gc2hvdWxkIGJlICdTdGVwJyAoYXMgZGVmaW5lZCBpbgotICAgICAgICAvLyB0aGUgcHJvZHVjdGlvbiBydWxlIFszXSBvZiBYTUwgU2NoZW1hIFAxIHNlY3Rpb24gMy4xMS42Ci0gICAgICAgIC8vIGlmIGZhbHNlLCB3ZSBhcmUgZXhwZWN0aW5nIGVpdGhlciAnfCcgb3IgJy8nLgotICAgICAgICAvLwotICAgICAgICAvLyB0aGlzIGlzIHRvIG1ha2Ugc3VyZSB3ZSBjYW4gZGV0ZWN0IGEgdG9rZW4gbGlzdCBsaWtlCi0gICAgICAgIC8vICdhYmMnICcvJyAnLycgJ2RlZicgJ2doaScKLSAgICAgICAgYm9vbGVhbiBleHBlY3RpbmdTdGVwID0gdHJ1ZTsKLSAgICAgICAgYm9vbGVhbiBleHBlY3RpbmdEb3VibGVDb2xvbiA9IGZhbHNlOwotCi0gICAgICAgIHdoaWxlKHh0b2tlbnMuaGFzTW9yZSgpKSB7Ci0gICAgICAgICAgICBmaW5hbCBpbnQgdG9rZW4gPSB4dG9rZW5zLm5leHRUb2tlbigpOwotCi0gICAgICAgICAgICBzd2l0Y2ggKHRva2VuKSB7Ci0gICAgICAgICAgICAgICAgY2FzZSAgWFBhdGguVG9rZW5zLkVYUFJUT0tFTl9PUEVSQVRPUl9VTklPTiA6ewotICAgICAgICAgICAgICAgICAgICBjaGVjayghZXhwZWN0aW5nU3RlcCk7Ci0gICAgICAgICAgICAgICAgICAgIGxvY2F0aW9uUGF0aHNWZWN0b3IuYWRkRWxlbWVudChidWlsZExvY2F0aW9uUGF0aChzdGVwc1ZlY3RvcikpOwotICAgICAgICAgICAgICAgICAgICBleHBlY3RpbmdTdGVwPXRydWU7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIGNhc2UgWFBhdGguVG9rZW5zLkVYUFJUT0tFTl9BVFNJR046IHsKLSAgICAgICAgICAgICAgICAgICAgY2hlY2soZXhwZWN0aW5nU3RlcCk7Ci0gICAgICAgICAgICAgICAgICAgIFN0ZXAgc3RlcCA9IG5ldyBTdGVwKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBBeGlzKEF4aXMuQVRUUklCVVRFKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJzZU5vZGVUZXN0KHh0b2tlbnMubmV4dFRva2VuKCkseHRva2Vucyxjb250ZXh0KSk7Ci0gICAgICAgICAgICAgICAgICAgIHN0ZXBzVmVjdG9yLmFkZEVsZW1lbnQoc3RlcCk7Ci0gICAgICAgICAgICAgICAgICAgIGV4cGVjdGluZ1N0ZXA9ZmFsc2U7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBjYXNlIFhQYXRoLlRva2Vucy5FWFBSVE9LRU5fTkFNRVRFU1RfQU5ZOgotICAgICAgICAgICAgICAgIGNhc2UgWFBhdGguVG9rZW5zLkVYUFJUT0tFTl9OQU1FVEVTVF9OQU1FU1BBQ0U6Ci0gICAgICAgICAgICAgICAgY2FzZSBYUGF0aC5Ub2tlbnMuRVhQUlRPS0VOX05BTUVURVNUX1FOQU1FOiB7Ci0gICAgICAgICAgICAgICAgICAgIGNoZWNrKGV4cGVjdGluZ1N0ZXApOwotICAgICAgICAgICAgICAgICAgICBTdGVwIHN0ZXAgPSBuZXcgU3RlcCgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgQXhpcyhBeGlzLkNISUxEKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJzZU5vZGVUZXN0KHRva2VuLHh0b2tlbnMsY29udGV4dCkpOwotICAgICAgICAgICAgICAgICAgICBzdGVwc1ZlY3Rvci5hZGRFbGVtZW50KHN0ZXApOwotICAgICAgICAgICAgICAgICAgICBleHBlY3RpbmdTdGVwPWZhbHNlOwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBjYXNlIFhQYXRoLlRva2Vucy5FWFBSVE9LRU5fUEVSSU9EOiB7Ci0gICAgICAgICAgICAgICAgICAgIGNoZWNrKGV4cGVjdGluZ1N0ZXApOwotICAgICAgICAgICAgICAgICAgICBleHBlY3RpbmdTdGVwPWZhbHNlOwotCi0gICAgICAgICAgICAgICAgICAgIC8vIHVubGVzcyB0aGlzIGlzIHRoZSBmaXJzdCBzdGVwIGluIHRoaXMgbG9jYXRpb24gcGF0aCwKLSAgICAgICAgICAgICAgICAgICAgLy8gdGhlcmUncyByZWFsbHkgbm8gcmVhc29uIHRvIGtlZXAgdGhlbSBpbiBMb2NhdGlvblBhdGguCi0gICAgICAgICAgICAgICAgICAgIC8vIFRoaXMgYW1vdW50cyB0byBzaG9ydGVuICJhLy4vLi9iLy4vYyIgdG8gImEvYi9jIi4KLSAgICAgICAgICAgICAgICAgICAgLy8gQWxzbywgdGhlIG1hdGNoZXIgZmFpbHMgdG8gd29yayBjb3JyZWN0bHkgaWYgWFBhdGgKLSAgICAgICAgICAgICAgICAgICAgLy8gaGFzIHRob3NlIHJlZHVuZGFudCBkb3RzLgotICAgICAgICAgICAgICAgICAgICBpZiAoc3RlcHNWZWN0b3Iuc2l6ZSgpPT0wKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBidWlsZCBzdGVwCi0gICAgICAgICAgICAgICAgICAgICAgICBBeGlzIGF4aXMgPSBuZXcgQXhpcyhBeGlzLlNFTEYpOwotICAgICAgICAgICAgICAgICAgICAgICAgTm9kZVRlc3Qgbm9kZVRlc3QgPSBuZXcgTm9kZVRlc3QoTm9kZVRlc3QuTk9ERSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTdGVwIHN0ZXAgPSBuZXcgU3RlcChheGlzLCBub2RlVGVzdCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzdGVwc1ZlY3Rvci5hZGRFbGVtZW50KHN0ZXApOwotCi0gICAgICAgICAgICAgICAgICAgICAgICBpZiggeHRva2Vucy5oYXNNb3JlKCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAmJiB4dG9rZW5zLnBlZWtUb2tlbigpID09IFhQYXRoLlRva2Vucy5FWFBSVE9LRU5fT1BFUkFUT1JfRE9VQkxFX1NMQVNIKXsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjb25zdW1lICcvLycKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB4dG9rZW5zLm5leHRUb2tlbigpOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYnVpbGQgc3RlcAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF4aXMgPSBuZXcgQXhpcyhBeGlzLkRFU0NFTkRBTlQpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVUZXN0ID0gbmV3IE5vZGVUZXN0KE5vZGVUZXN0Lk5PREUpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZXAgPSBuZXcgU3RlcChheGlzLCBub2RlVGVzdCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RlcHNWZWN0b3IuYWRkRWxlbWVudChzdGVwKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHBlY3RpbmdTdGVwPXRydWU7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgY2FzZSBYUGF0aC5Ub2tlbnMuRVhQUlRPS0VOX09QRVJBVE9SX0RPVUJMRV9TTEFTSDp7Ci0gICAgICAgICAgICAgICAgICAgIC8vIHRoaXMgY2Fubm90IGFwcGVhciBpbiBhcmJpdHJhcnkgcG9zaXRpb24uCi0gICAgICAgICAgICAgICAgICAgIC8vIGl0IGlzIG9ubHkgYWxsb3dlZCByaWdodCBhZnRlciAnLicgd2hlbgotICAgICAgICAgICAgICAgICAgICAvLyAnLicgaXMgdGhlIGZpcnN0IHRva2VuIG9mIGEgbG9jYXRpb24gcGF0aC4KLSAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFhQYXRoRXhjZXB0aW9uKCJjLWdlbmVyYWwteHBhdGgiKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgY2FzZSBYUGF0aC5Ub2tlbnMuRVhQUlRPS0VOX09QRVJBVE9SX1NMQVNIOiB7Ci0gICAgICAgICAgICAgICAgICAgIGNoZWNrKCFleHBlY3RpbmdTdGVwKTsKLSAgICAgICAgICAgICAgICAgICAgZXhwZWN0aW5nU3RlcD10cnVlOwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgY2FzZSBYUGF0aC5Ub2tlbnMuRVhQUlRPS0VOX0FYSVNOQU1FX0FUVFJJQlVURTogewotICAgICAgICAgICAgICAgICAgICAgY2hlY2soZXhwZWN0aW5nU3RlcCk7Ci0gICAgICAgICAgICAgICAgICAgICBleHBlY3RpbmdEb3VibGVDb2xvbiA9IHRydWU7Ci0KLSAgICAgICAgICAgICAgICAgICAgIGlmICh4dG9rZW5zLm5leHRUb2tlbigpID09IFhQYXRoLlRva2Vucy5FWFBSVE9LRU5fRE9VQkxFX0NPTE9OKXsKLSAgICAgICAgICAgICAgICAgICAgICAgICBTdGVwIHN0ZXAgPSBuZXcgU3RlcCgKLSAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgQXhpcyhBeGlzLkFUVFJJQlVURSksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJzZU5vZGVUZXN0KHh0b2tlbnMubmV4dFRva2VuKCkseHRva2Vucyxjb250ZXh0KSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgc3RlcHNWZWN0b3IuYWRkRWxlbWVudChzdGVwKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICBleHBlY3RpbmdTdGVwPWZhbHNlOwotICAgICAgICAgICAgICAgICAgICAgICAgIGV4cGVjdGluZ0RvdWJsZUNvbG9uID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgY2FzZSBYUGF0aC5Ub2tlbnMuRVhQUlRPS0VOX0FYSVNOQU1FX0NISUxEOnsKLSAgICAgICAgICAgICAgICAgICAgY2hlY2soZXhwZWN0aW5nU3RlcCk7Ci0gICAgICAgICAgICAgICAgICAgIGV4cGVjdGluZ0RvdWJsZUNvbG9uID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGNhc2UgWFBhdGguVG9rZW5zLkVYUFJUT0tFTl9ET1VCTEVfQ09MT04gOnsKLSAgICAgICAgICAgICAgICAgICAgY2hlY2soZXhwZWN0aW5nU3RlcCk7Ci0gICAgICAgICAgICAgICAgICAgIGNoZWNrKGV4cGVjdGluZ0RvdWJsZUNvbG9uKTsKLSAgICAgICAgICAgICAgICAgICAgZXhwZWN0aW5nRG91YmxlQ29sb24gPSBmYWxzZTsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGRlZmF1bHQ6Ci0gICAgICAgICAgICAgICAgICAgIC8vIHdlIHNob3VsZCBoYXZlIGNvdmVyZWQgYWxsIHRoZSB0b2tlbnMgdGhhdCB3ZSBjYW4gcG9zc2libHkgc2VlLgotICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWFBhdGhFeGNlcHRpb24oImMtZ2VuZXJhbC14cGF0aCIpOwotICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBjaGVjayghZXhwZWN0aW5nU3RlcCk7Ci0KLSAgICAgICAgbG9jYXRpb25QYXRoc1ZlY3Rvci5hZGRFbGVtZW50KGJ1aWxkTG9jYXRpb25QYXRoKHN0ZXBzVmVjdG9yKSk7Ci0KLSAgICAgICAgLy8gc2F2ZSBsb2NhdGlvbiBwYXRoCi0gICAgICAgIGZMb2NhdGlvblBhdGhzPW5ldyBMb2NhdGlvblBhdGhbbG9jYXRpb25QYXRoc1ZlY3Rvci5zaXplKCldOwotICAgICAgICBsb2NhdGlvblBhdGhzVmVjdG9yLmNvcHlJbnRvKGZMb2NhdGlvblBhdGhzKTsKLQotCi0gICAgICAgIGlmIChERUJVR19YUEFUSF9QQVJTRSkgewotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCI+Pj4gIitmTG9jYXRpb25QYXRocyk7Ci0gICAgICAgIH0KLQotICAgIH0gLy8gcGFyc2VFeHByZXNzaW9uKFN5bWJvbFRhYmxlLE5hbWVzcGFjZUNvbnRleHQpCi0KLSAgICAvKioKLSAgICAgKiBVc2VkIGJ5IHtAbGluayAjcGFyc2VFeHByZXNzaW9ufSB0byBwYXJzZSBhIG5vZGUgdGVzdAotICAgICAqIGZyb20gdGhlIHRva2VuIGxpc3QuCi0gICAgICovCi0gICAgcHJpdmF0ZSBOb2RlVGVzdCBwYXJzZU5vZGVUZXN0KCBpbnQgdHlwZVRva2VuLCBUb2tlbnMgeHRva2VucywgTmFtZXNwYWNlQ29udGV4dCBjb250ZXh0ICkKLSAgICAgICAgdGhyb3dzIFhQYXRoRXhjZXB0aW9uIHsKLSAgICAgICAgc3dpdGNoKHR5cGVUb2tlbikgewotICAgICAgICBjYXNlIFhQYXRoLlRva2Vucy5FWFBSVE9LRU5fTkFNRVRFU1RfQU5ZOgotICAgICAgICAgICAgcmV0dXJuIG5ldyBOb2RlVGVzdChOb2RlVGVzdC5XSUxEQ0FSRCk7Ci0KLSAgICAgICAgY2FzZSBYUGF0aC5Ub2tlbnMuRVhQUlRPS0VOX05BTUVURVNUX05BTUVTUEFDRToKLSAgICAgICAgY2FzZSBYUGF0aC5Ub2tlbnMuRVhQUlRPS0VOX05BTUVURVNUX1FOQU1FOgotICAgICAgICAgICAgLy8gY29uc3VtZSBRTmFtZSB0b2tlbgotICAgICAgICAgICAgU3RyaW5nIHByZWZpeCA9IHh0b2tlbnMubmV4dFRva2VuQXNTdHJpbmcoKTsKLSAgICAgICAgICAgIFN0cmluZyB1cmkgPSBudWxsOwotICAgICAgICAgICAgaWYgKGNvbnRleHQgIT0gbnVsbCAmJiBwcmVmaXggIT0gWE1MU3ltYm9scy5FTVBUWV9TVFJJTkcpIHsKLSAgICAgICAgICAgICAgICB1cmkgPSBjb250ZXh0LmdldFVSSShwcmVmaXgpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKHByZWZpeCAhPSBYTUxTeW1ib2xzLkVNUFRZX1NUUklORyAmJiBjb250ZXh0ICE9IG51bGwgJiYgdXJpID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWFBhdGhFeGNlcHRpb24oImMtZ2VuZXJhbC14cGF0aC1ucyIpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAodHlwZVRva2VuPT1YUGF0aC5Ub2tlbnMuRVhQUlRPS0VOX05BTUVURVNUX05BTUVTUEFDRSkKLSAgICAgICAgICAgICAgICByZXR1cm4gbmV3IE5vZGVUZXN0KHByZWZpeCx1cmkpOwotCi0gICAgICAgICAgICBTdHJpbmcgbG9jYWxwYXJ0ID0geHRva2Vucy5uZXh0VG9rZW5Bc1N0cmluZygpOwotICAgICAgICAgICAgU3RyaW5nIHJhd25hbWUgPSBwcmVmaXggIT0gWE1MU3ltYm9scy5FTVBUWV9TVFJJTkcKLSAgICAgICAgICAgID8gZlN5bWJvbFRhYmxlLmFkZFN5bWJvbChwcmVmaXgrJzonK2xvY2FscGFydCkKLSAgICAgICAgICAgIDogbG9jYWxwYXJ0OwotCi0gICAgICAgICAgICByZXR1cm4gbmV3IE5vZGVUZXN0KG5ldyBRTmFtZShwcmVmaXgsIGxvY2FscGFydCwgcmF3bmFtZSwgdXJpKSk7Ci0KLSAgICAgICAgZGVmYXVsdDoKLSAgICAgICAgICAgIC8vIGFzc2VydGlvbiBlcnJvcgotICAgICAgICAgICAgdGhyb3cgbmV3IFhQYXRoRXhjZXB0aW9uKCJjLWdlbmVyYWwteHBhdGgiKTsKLQotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICAvLwotICAgIC8vIENsYXNzZXMKLSAgICAvLwotCi0gICAgLy8gbG9jYXRpb24gcGF0aCBpbmZvcm1hdGlvbgotCi0gICAgLyoqCi0gICAgICogQSBsb2NhdGlvbiBwYXRoIHJlcHJlc2VudGF0aW9uIGZvciBhbiBYUGF0aCBleHByZXNzaW9uLgotICAgICAqCi0gICAgICogQHhlcmNlcy5pbnRlcm5hbAotICAgICAqCi0gICAgICogQGF1dGhvciBBbmR5IENsYXJrLCBJQk0KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGNsYXNzIExvY2F0aW9uUGF0aAotICAgICAgICBpbXBsZW1lbnRzIENsb25lYWJsZSB7Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gRGF0YQotICAgICAgICAvLwotCi0gICAgICAgIC8qKiBMaXN0IG9mIHN0ZXBzLiAqLwotICAgICAgICBwdWJsaWMgU3RlcFtdIHN0ZXBzOwotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIENvbnN0cnVjdG9ycwotICAgICAgICAvLwotCi0gICAgICAgIC8qKiBDcmVhdGVzIGEgbG9jYXRpb24gcGF0aCBmcm9tIGEgc2VyaWVzIG9mIHN0ZXBzLiAqLwotICAgICAgICBwdWJsaWMgTG9jYXRpb25QYXRoKFN0ZXBbXSBzdGVwcykgewotICAgICAgICAgICAgdGhpcy5zdGVwcyA9IHN0ZXBzOwotICAgICAgICB9IC8vIDxpbml0PihTdGVwW10pCi0KLSAgICAgICAgLyoqIENvcHkgY29uc3RydWN0b3IuICovCi0gICAgICAgIHByb3RlY3RlZCBMb2NhdGlvblBhdGgoTG9jYXRpb25QYXRoIHBhdGgpIHsKLSAgICAgICAgICAgIHN0ZXBzID0gbmV3IFN0ZXBbcGF0aC5zdGVwcy5sZW5ndGhdOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzdGVwcy5sZW5ndGg7IGkrKykgewotICAgICAgICAgICAgICAgIHN0ZXBzW2ldID0gKFN0ZXApcGF0aC5zdGVwc1tpXS5jbG9uZSgpOwotICAgICAgICAgICAgfQotICAgICAgICB9IC8vIDxpbml0PihMb2NhdGlvblBhdGgpCi0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gT2JqZWN0IG1ldGhvZHMKLSAgICAgICAgLy8KLQotICAgICAgICAvKiogUmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIG9iamVjdC4gKi8KLSAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKLSAgICAgICAgICAgIFN0cmluZ0J1ZmZlciBzdHIgPSBuZXcgU3RyaW5nQnVmZmVyKCk7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHN0ZXBzLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGkgPiAwICAgICAgICYmIChzdGVwc1tpLTFdLmF4aXMudHlwZSE9QXhpcy5ERVNDRU5EQU5UCi0gICAgICAgICAgICAgICAgICAgICYmIHN0ZXBzW2ldLmF4aXMudHlwZSE9QXhpcy5ERVNDRU5EQU5UKSApewotICAgICAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKCcvJyk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHN0ci5hcHBlbmQoc3RlcHNbaV0udG9TdHJpbmcoKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyBERUJVRzogVGhpcyBjb2RlIGlzIGp1c3QgZm9yIGRlYnVnZ2luZyBhbmQgc2hvdWxkICpub3QqCi0gICAgICAgICAgICAvLyAgICAgICAgYmUgbGVmdCBpbiBiZWNhdXNlIGl0IHdpbGwgbWVzcyB1cCBoYXNoY29kZXMgb2YKLSAgICAgICAgICAgIC8vICAgICAgICBzZXJpYWxpemVkIHZlcnNpb25zIG9mIHRoaXMgb2JqZWN0LiAtQWMKLSAgICAgICAgICAgIGlmIChmYWxzZSkgewotICAgICAgICAgICAgICAgIHN0ci5hcHBlbmQoJ1snKTsKLSAgICAgICAgICAgICAgICBTdHJpbmcgcyA9IHN1cGVyLnRvU3RyaW5nKCk7Ci0gICAgICAgICAgICAgICAgc3RyLmFwcGVuZChzLnN1YnN0cmluZyhzLmluZGV4T2YoJ0AnKSkpOwotICAgICAgICAgICAgICAgIHN0ci5hcHBlbmQoJ10nKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiBzdHIudG9TdHJpbmcoKTsKLSAgICAgICAgfSAvLyB0b1N0cmluZygpOlN0cmluZwotCi0gICAgICAgIC8qKiBSZXR1cm5zIGEgY2xvbmUgb2YgdGhpcyBvYmplY3QuICovCi0gICAgICAgIHB1YmxpYyBPYmplY3QgY2xvbmUoKSB7Ci0gICAgICAgICAgICByZXR1cm4gbmV3IExvY2F0aW9uUGF0aCh0aGlzKTsKLSAgICAgICAgfSAvLyBjbG9uZSgpOk9iamVjdAotCi0gICAgfSAvLyBjbGFzcyBsb2NhdGlvblBhdGgKLQotICAgIC8qKgotICAgICAqIEEgbG9jYXRpb24gcGF0aCBzdGVwIGNvbXByaXNlZCBvZiBhbiBheGlzIGFuZCBub2RlIHRlc3QuCi0gICAgICoKLSAgICAgKiBAeGVyY2VzLmludGVybmFsCi0gICAgICoKLSAgICAgKiBAYXV0aG9yIEFuZHkgQ2xhcmssIElCTQotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgU3RlcAotICAgICAgICBpbXBsZW1lbnRzIENsb25lYWJsZSB7Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gRGF0YQotICAgICAgICAvLwotCi0gICAgICAgIC8qKiBBeGlzLiAqLwotICAgICAgICBwdWJsaWMgQXhpcyBheGlzOwotCi0gICAgICAgIC8qKiBOb2RlIHRlc3QuICovCi0gICAgICAgIHB1YmxpYyBOb2RlVGVzdCBub2RlVGVzdDsKLQotICAgICAgICAvLwotICAgICAgICAvLyBDb25zdHJ1Y3RvcnMKLSAgICAgICAgLy8KLQotICAgICAgICAvKiogQ29uc3RydWN0cyBhIHN0ZXAgZnJvbSBhbiBheGlzIGFuZCBub2RlIHRlc3QuICovCi0gICAgICAgIHB1YmxpYyBTdGVwKEF4aXMgYXhpcywgTm9kZVRlc3Qgbm9kZVRlc3QpIHsKLSAgICAgICAgICAgIHRoaXMuYXhpcyA9IGF4aXM7Ci0gICAgICAgICAgICB0aGlzLm5vZGVUZXN0ID0gbm9kZVRlc3Q7Ci0gICAgICAgIH0gLy8gPGluaXQ+KEF4aXMsTm9kZVRlc3QpCi0KLSAgICAgICAgLyoqIENvcHkgY29uc3RydWN0b3IuICovCi0gICAgICAgIHByb3RlY3RlZCBTdGVwKFN0ZXAgc3RlcCkgewotICAgICAgICAgICAgYXhpcyA9IChBeGlzKXN0ZXAuYXhpcy5jbG9uZSgpOwotICAgICAgICAgICAgbm9kZVRlc3QgPSAoTm9kZVRlc3Qpc3RlcC5ub2RlVGVzdC5jbG9uZSgpOwotICAgICAgICB9IC8vIDxpbml0PihTdGVwKQotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIE9iamVjdCBtZXRob2RzCi0gICAgICAgIC8vCi0KLSAgICAgICAgLyoqIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBvYmplY3QuICovCi0gICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0gICAgICAgICAgICBpZiAoYXhpcy50eXBlID09IEF4aXMuU0VMRikgewotICAgICAgICAgICAgICAgIHJldHVybiAiLiI7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoYXhpcy50eXBlID09IEF4aXMuQVRUUklCVVRFKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuICJAIiArIG5vZGVUZXN0LnRvU3RyaW5nKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoYXhpcy50eXBlID09IEF4aXMuQ0hJTEQpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gbm9kZVRlc3QudG9TdHJpbmcoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChheGlzLnR5cGUgPT0gQXhpcy5ERVNDRU5EQU5UKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuICIvLyI7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gIj8/PyAoIitheGlzLnR5cGUrJyknOwotICAgICAgICB9IC8vIHRvU3RyaW5nKCk6U3RyaW5nCi0KLSAgICAgICAgLyoqIFJldHVybnMgYSBjbG9uZSBvZiB0aGlzIG9iamVjdC4gKi8KLSAgICAgICAgcHVibGljIE9iamVjdCBjbG9uZSgpIHsKLSAgICAgICAgICAgIHJldHVybiBuZXcgU3RlcCh0aGlzKTsKLSAgICAgICAgfSAvLyBjbG9uZSgpOk9iamVjdAotCi0gICAgfSAvLyBjbGFzcyBTdGVwCi0KLSAgICAvKioKLSAgICAgKiBBeGlzLgotICAgICAqCi0gICAgICogQHhlcmNlcy5pbnRlcm5hbAotICAgICAqCi0gICAgICogQGF1dGhvciBBbmR5IENsYXJrLCBJQk0KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEF4aXMKLSAgICAgICAgaW1wbGVtZW50cyBDbG9uZWFibGUgewotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIENvbnN0YW50cwotICAgICAgICAvLwotCi0gICAgICAgIC8qKiBUeXBlOiBjaGlsZC4gKi8KLSAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBDSElMRCA9IDE7Ci0KLSAgICAgICAgLyoqIFR5cGU6IGF0dHJpYnV0ZS4gKi8KLSAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBBVFRSSUJVVEUgPSAyOwotCi0gICAgICAgIC8qKiBUeXBlOiBzZWxmLiAqLwotICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFNFTEYgPSAzOwotCi0KLSAgICAgICAgLyoqIFR5cGU6IGRlc2NlbmRhbnQuICovCi0gICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgREVTQ0VOREFOVCA9IDQ7Ci0gICAgICAgIC8vCi0gICAgICAgIC8vIERhdGEKLSAgICAgICAgLy8KLQotICAgICAgICAvKiogQXhpcyB0eXBlLiAqLwotICAgICAgICBwdWJsaWMgc2hvcnQgdHlwZTsKLQotICAgICAgICAvLwotICAgICAgICAvLyBDb25zdHJ1Y3RvcnMKLSAgICAgICAgLy8KLQotICAgICAgICAvKiogQ29uc3RydWN0cyBhbiBheGlzIHdpdGggdGhlIHNwZWNpZmllZCB0eXBlLiAqLwotICAgICAgICBwdWJsaWMgQXhpcyhzaG9ydCB0eXBlKSB7Ci0gICAgICAgICAgICB0aGlzLnR5cGUgPSB0eXBlOwotICAgICAgICB9IC8vIDxpbml0PihzaG9ydCkKLQotICAgICAgICAvKiogQ29weSBjb25zdHJ1Y3Rvci4gKi8KLSAgICAgICAgcHJvdGVjdGVkIEF4aXMoQXhpcyBheGlzKSB7Ci0gICAgICAgICAgICB0eXBlID0gYXhpcy50eXBlOwotICAgICAgICB9IC8vIDxpbml0PihBeGlzKQotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIE9iamVjdCBtZXRob2RzCi0gICAgICAgIC8vCi0KLSAgICAgICAgLyoqIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBvYmplY3QuICovCi0gICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0gICAgICAgICAgICBzd2l0Y2ggKHR5cGUpIHsKLSAgICAgICAgICAgICAgICBjYXNlIENISUxEOiByZXR1cm4gImNoaWxkIjsKLSAgICAgICAgICAgICAgICBjYXNlIEFUVFJJQlVURTogcmV0dXJuICJhdHRyaWJ1dGUiOwotICAgICAgICAgICAgICAgIGNhc2UgU0VMRjogcmV0dXJuICJzZWxmIjsKLSAgICAgICAgICAgICAgICBjYXNlIERFU0NFTkRBTlQ6IHJldHVybiAiZGVzY2VuZGFudCI7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gIj8/PyI7Ci0gICAgICAgIH0gLy8gdG9TdHJpbmcoKTpTdHJpbmcKLQotICAgICAgICAvKiogUmV0dXJucyBhIGNsb25lIG9mIHRoaXMgb2JqZWN0LiAqLwotICAgICAgICBwdWJsaWMgT2JqZWN0IGNsb25lKCkgewotICAgICAgICAgICAgcmV0dXJuIG5ldyBBeGlzKHRoaXMpOwotICAgICAgICB9IC8vIGNsb25lKCk6T2JqZWN0Ci0KLSAgICB9IC8vIGNsYXNzIEF4aXMKLQotICAgIC8qKgotICAgICAqIE5vZGUgdGVzdC4KLSAgICAgKgotICAgICAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAgICAgKgotICAgICAqIEBhdXRob3IgQW5keSBDbGFyaywgSUJNCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBjbGFzcyBOb2RlVGVzdAotICAgICAgICBpbXBsZW1lbnRzIENsb25lYWJsZSB7Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gQ29uc3RhbnRzCi0gICAgICAgIC8vCi0KLSAgICAgICAgLyoqIFR5cGU6IHF1YWxpZmllZCBuYW1lLiAqLwotICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFFOQU1FID0gMTsKLQotICAgICAgICAvKiogVHlwZTogd2lsZGNhcmQuICovCi0gICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgV0lMRENBUkQgPSAyOwotCi0gICAgICAgIC8qKiBUeXBlOiBub2RlLiAqLwotICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IE5PREUgPSAzOwotCi0gICAgICAgIC8qKiBUeXBlOiBuYW1lc3BhY2UgKi8KLSAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBOQU1FU1BBQ0U9IDQ7Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gRGF0YQotICAgICAgICAvLwotCi0gICAgICAgIC8qKiBOb2RlIHRlc3QgdHlwZS4gKi8KLSAgICAgICAgcHVibGljIHNob3J0IHR5cGU7Ci0KLSAgICAgICAgLyoqIE5vZGUgcXVhbGlmaWVkIG5hbWUuICovCi0gICAgICAgIHB1YmxpYyBmaW5hbCBRTmFtZSBuYW1lID0gbmV3IFFOYW1lKCk7Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gQ29uc3RydWN0b3JzCi0gICAgICAgIC8vCi0KLSAgICAgICAgLyoqIENvbnN0cnVjdHMgYSBub2RlIHRlc3Qgb2YgdHlwZSBXSUxEQ0FSRCBvciBOT0RFLiAqLwotICAgICAgICBwdWJsaWMgTm9kZVRlc3Qoc2hvcnQgdHlwZSkgewotICAgICAgICAgICAgdGhpcy50eXBlID0gdHlwZTsKLSAgICAgICAgfSAvLyA8aW5pdD4oaW50KQotCi0gICAgICAgIC8qKiBDb25zdHJ1Y3RzIGEgbm9kZSB0ZXN0IG9mIHR5cGUgUU5hbWUuICovCi0gICAgICAgIHB1YmxpYyBOb2RlVGVzdChRTmFtZSBuYW1lKSB7Ci0gICAgICAgICAgICB0aGlzLnR5cGUgPSBRTkFNRTsKLSAgICAgICAgICAgIHRoaXMubmFtZS5zZXRWYWx1ZXMobmFtZSk7Ci0gICAgICAgIH0gLy8gPGluaXQ+KFFOYW1lKQotICAgICAgICAvKiogQ29uc3RydWN0cyBhIG5vZGUgdGVzdCBvZiB0eXBlIE5hbWVzcGFjZS4gKi8KLSAgICAgICAgcHVibGljIE5vZGVUZXN0KFN0cmluZyBwcmVmaXgsIFN0cmluZyB1cmkpIHsKLSAgICAgICAgICAgIHRoaXMudHlwZSA9IE5BTUVTUEFDRTsKLSAgICAgICAgICAgIHRoaXMubmFtZS5zZXRWYWx1ZXMocHJlZml4LCBudWxsLCBudWxsLCB1cmkpOwotICAgICAgICB9IC8vIDxpbml0PihTdHJpbmcsU3RyaW5nKQotCi0gICAgICAgIC8qKiBDb3B5IGNvbnN0cnVjdG9yLiAqLwotICAgICAgICBwdWJsaWMgTm9kZVRlc3QoTm9kZVRlc3Qgbm9kZVRlc3QpIHsKLSAgICAgICAgICAgIHR5cGUgPSBub2RlVGVzdC50eXBlOwotICAgICAgICAgICAgbmFtZS5zZXRWYWx1ZXMobm9kZVRlc3QubmFtZSk7Ci0gICAgICAgIH0gLy8gPGluaXQ+KE5vZGVUZXN0KQotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIE9iamVjdCBtZXRob2RzCi0gICAgICAgIC8vCi0KLSAgICAgICAgLyoqIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBvYmplY3QuICovCi0gICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0KLSAgICAgICAgICAgIHN3aXRjaCAodHlwZSkgewotICAgICAgICAgICAgICAgIGNhc2UgUU5BTUU6IHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKG5hbWUucHJlZml4Lmxlbmd0aCgpICE9MCkgewotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5hbWUudXJpICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmFtZS5wcmVmaXgrJzonK25hbWUubG9jYWxwYXJ0OwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICJ7IituYW1lLnVyaSsnfScrbmFtZS5wcmVmaXgrJzonK25hbWUubG9jYWxwYXJ0OwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBuYW1lLmxvY2FscGFydDsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgY2FzZSBOQU1FU1BBQ0U6IHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKG5hbWUucHJlZml4Lmxlbmd0aCgpICE9MCkgewotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5hbWUudXJpICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmFtZS5wcmVmaXgrIjoqIjsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAieyIrbmFtZS51cmkrJ30nK25hbWUucHJlZml4KyI6KiI7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuICI/Pz86KiI7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGNhc2UgV0lMRENBUkQ6IHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuICIqIjsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgY2FzZSBOT0RFOiB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiAibm9kZSgpIjsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gIj8/PyI7Ci0KLSAgICAgICAgfSAvLyB0b1N0cmluZygpOlN0cmluZwotCi0gICAgICAgIC8qKiBSZXR1cm5zIGEgY2xvbmUgb2YgdGhpcyBvYmplY3QuICovCi0gICAgICAgIHB1YmxpYyBPYmplY3QgY2xvbmUoKSB7Ci0gICAgICAgICAgICByZXR1cm4gbmV3IE5vZGVUZXN0KHRoaXMpOwotICAgICAgICB9IC8vIGNsb25lKCk6T2JqZWN0Ci0KLSAgICB9IC8vIGNsYXNzIE5vZGVUZXN0Ci0KLSAgICAvLyB4cGF0aCBpbXBsZW1lbnRhdGlvbgotCi0gICAgLy8gTk9URTogVGhlIFhQYXRoIGltcGxlbWVudGF0aW9uIGNsYXNzZXMgYXJlIGtlcHQgaW50ZXJuYWwgYmVjYXVzZQotICAgIC8vICAgICAgIHRoaXMgaW1wbGVtZW50YXRpb24gaXMganVzdCBhIHRlbXBvcmFyeSBoYWNrIHVudGlsIGEgYmV0dGVyCi0gICAgLy8gICAgICAgYW5kL29yIG1vcmUgYXBwcm9wcmlhdGUgaW1wbGVtZW50YXRpb24gY2FuIGJlIHdyaXR0ZW4uCi0gICAgLy8gICAgICAga2VlcGluZyB0aGUgY29kZSBpbiBzZXBhcmF0ZSBzb3VyY2UgZmlsZXMgd291bGQgIm11ZGR5IiB0aGUKLSAgICAvLyAgICAgICBDVlMgZGlyZWN0b3J5IHdoZW4gaXQncyBub3QgbmVlZGVkLiAtQWMKLQotICAgIC8qKgotICAgICAqIExpc3Qgb2YgdG9rZW5zLgotICAgICAqCi0gICAgICogQHhlcmNlcy5pbnRlcm5hbAotICAgICAqCi0gICAgICogQGF1dGhvciBHbGVubiBNYXJjeSwgSUJNCi0gICAgICogQGF1dGhvciBBbmR5IENsYXJrLCBJQk0KLSAgICAgKgotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIFRva2VucyB7Ci0KLSAgICAgICAgc3RhdGljIGZpbmFsIGJvb2xlYW4gRFVNUF9UT0tFTlMgPSBmYWxzZTsKLQotICAgICAgICAvKioKLSAgICAgICAgICogWzI4XSBFeHByVG9rZW4gOjo9ICcoJyB8ICcpJyB8ICdbJyB8ICddJyB8ICcuJyB8ICcuLicgfCAnQCcgfCAnLCcgfCAnOjonCi0gICAgICAgICAqICAgICAgICAgICAgICAgICAgfCBOYW1lVGVzdCB8IE5vZGVUeXBlIHwgT3BlcmF0b3IgfCBGdW5jdGlvbk5hbWUKLSAgICAgICAgICogICAgICAgICAgICAgICAgICB8IEF4aXNOYW1lIHwgTGl0ZXJhbCB8IE51bWJlciB8IFZhcmlhYmxlUmVmZXJlbmNlCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludAotICAgICAgICAgICAgRVhQUlRPS0VOX09QRU5fUEFSRU4gICAgICAgICAgICAgICAgICAgID0gICAwLAotICAgICAgICAgICAgRVhQUlRPS0VOX0NMT1NFX1BBUkVOICAgICAgICAgICAgICAgICAgID0gICAxLAotICAgICAgICAgICAgRVhQUlRPS0VOX09QRU5fQlJBQ0tFVCAgICAgICAgICAgICAgICAgID0gICAyLAotICAgICAgICAgICAgRVhQUlRPS0VOX0NMT1NFX0JSQUNLRVQgICAgICAgICAgICAgICAgID0gICAzLAotICAgICAgICAgICAgRVhQUlRPS0VOX1BFUklPRCAgICAgICAgICAgICAgICAgICAgICAgID0gICA0LAotICAgICAgICAgICAgRVhQUlRPS0VOX0RPVUJMRV9QRVJJT0QgICAgICAgICAgICAgICAgID0gICA1LAotICAgICAgICAgICAgRVhQUlRPS0VOX0FUU0lHTiAgICAgICAgICAgICAgICAgICAgICAgID0gICA2LAotICAgICAgICAgICAgRVhQUlRPS0VOX0NPTU1BICAgICAgICAgICAgICAgICAgICAgICAgID0gICA3LAotICAgICAgICAgICAgRVhQUlRPS0VOX0RPVUJMRV9DT0xPTiAgICAgICAgICAgICAgICAgID0gICA4LAotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIC8vIFszN10gTmFtZVRlc3QgOjo9ICcqJyB8IE5DTmFtZSAnOicgJyonIHwgUU5hbWUKLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAvLyBmb2xsb3dlZCBieSBzeW1ib2wgaGFuZGxlIG9mIE5DTmFtZSBvciBRTmFtZQotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIEVYUFJUT0tFTl9OQU1FVEVTVF9BTlkgICAgICAgICAgICAgICAgICA9ICAgOSwKLSAgICAgICAgICAgIEVYUFJUT0tFTl9OQU1FVEVTVF9OQU1FU1BBQ0UgICAgICAgICAgICA9ICAxMCwKLSAgICAgICAgICAgIEVYUFJUT0tFTl9OQU1FVEVTVF9RTkFNRSAgICAgICAgICAgICAgICA9ICAxMSwKLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAvLyBbMzhdIE5vZGVUeXBlIDo6PSAnY29tbWVudCcgfCAndGV4dCcgfCAncHJvY2Vzc2luZy1pbnN0cnVjdGlvbicgfCAnbm9kZScKLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICBFWFBSVE9LRU5fTk9ERVRZUEVfQ09NTUVOVCAgICAgICAgICAgICAgPSAgMTIsCi0gICAgICAgICAgICBFWFBSVE9LRU5fTk9ERVRZUEVfVEVYVCAgICAgICAgICAgICAgICAgPSAgMTMsCi0gICAgICAgICAgICBFWFBSVE9LRU5fTk9ERVRZUEVfUEkgICAgICAgICAgICAgICAgICAgPSAgMTQsCi0gICAgICAgICAgICBFWFBSVE9LRU5fTk9ERVRZUEVfTk9ERSAgICAgICAgICAgICAgICAgPSAgMTUsCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgLy8gWzMyXSBPcGVyYXRvciA6Oj0gT3BlcmF0b3JOYW1lCi0gICAgICAgICAgICAvLyAgICAgICAgICAgICAgICAgfCBNdWx0aXBseU9wZXJhdG9yCi0gICAgICAgICAgICAvLyAgICAgICAgICAgICAgICAgfCAnLycgfCAnLy8nIHwgJ3wnIHwgJysnIHwgJy0nIHwgJz0nIHwgJyE9JyB8ICc8JyB8ICc8PScgfCAnPicgfCAnPj0nCi0gICAgICAgICAgICAvLyBbMzNdIE9wZXJhdG9yTmFtZSA6Oj0gJ2FuZCcgfCAnb3InIHwgJ21vZCcgfCAnZGl2JwotICAgICAgICAgICAgLy8gWzM0XSBNdWx0aXBseU9wZXJhdG9yIDo6PSAnKicKLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICBFWFBSVE9LRU5fT1BFUkFUT1JfQU5EICAgICAgICAgICAgICAgICAgPSAgMTYsCi0gICAgICAgICAgICBFWFBSVE9LRU5fT1BFUkFUT1JfT1IgICAgICAgICAgICAgICAgICAgPSAgMTcsCi0gICAgICAgICAgICBFWFBSVE9LRU5fT1BFUkFUT1JfTU9EICAgICAgICAgICAgICAgICAgPSAgMTgsCi0gICAgICAgICAgICBFWFBSVE9LRU5fT1BFUkFUT1JfRElWICAgICAgICAgICAgICAgICAgPSAgMTksCi0gICAgICAgICAgICBFWFBSVE9LRU5fT1BFUkFUT1JfTVVMVCAgICAgICAgICAgICAgICAgPSAgMjAsCi0gICAgICAgICAgICBFWFBSVE9LRU5fT1BFUkFUT1JfU0xBU0ggICAgICAgICAgICAgICAgPSAgMjEsCi0gICAgICAgICAgICBFWFBSVE9LRU5fT1BFUkFUT1JfRE9VQkxFX1NMQVNIICAgICAgICAgPSAgMjIsCi0gICAgICAgICAgICBFWFBSVE9LRU5fT1BFUkFUT1JfVU5JT04gICAgICAgICAgICAgICAgPSAgMjMsCi0gICAgICAgICAgICBFWFBSVE9LRU5fT1BFUkFUT1JfUExVUyAgICAgICAgICAgICAgICAgPSAgMjQsCi0gICAgICAgICAgICBFWFBSVE9LRU5fT1BFUkFUT1JfTUlOVVMgICAgICAgICAgICAgICAgPSAgMjUsCi0gICAgICAgICAgICBFWFBSVE9LRU5fT1BFUkFUT1JfRVFVQUwgICAgICAgICAgICAgICAgPSAgMjYsCi0gICAgICAgICAgICBFWFBSVE9LRU5fT1BFUkFUT1JfTk9UX0VRVUFMICAgICAgICAgICAgPSAgMjcsCi0gICAgICAgICAgICBFWFBSVE9LRU5fT1BFUkFUT1JfTEVTUyAgICAgICAgICAgICAgICAgPSAgMjgsCi0gICAgICAgICAgICBFWFBSVE9LRU5fT1BFUkFUT1JfTEVTU19FUVVBTCAgICAgICAgICAgPSAgMjksCi0gICAgICAgICAgICBFWFBSVE9LRU5fT1BFUkFUT1JfR1JFQVRFUiAgICAgICAgICAgICAgPSAgMzAsCi0gICAgICAgICAgICBFWFBSVE9LRU5fT1BFUkFUT1JfR1JFQVRFUl9FUVVBTCAgICAgICAgPSAgMzEsCi0KLSAgICAgICAgICAgIC8vRVhQUlRPS0VOX0ZJUlNUX09QRVJBVE9SICAgICAgICAgICAgICAgID0gRVhQUlRPS0VOX09QRVJBVE9SX0FORCwKLSAgICAgICAgICAgIC8vRVhQUlRPS0VOX0xBU1RfT1BFUkFUT1IgICAgICAgICAgICAgICAgID0gRVhQUlRPS0VOX09QRVJBVE9SX0dSRUFURVJfRVFVQUwsCi0KLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAvLyBbMzVdIEZ1bmN0aW9uTmFtZSA6Oj0gUU5hbWUgLSBOb2RlVHlwZQotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIC8vIGZvbGxvd2VkIGJ5IHN5bWJvbCBoYW5kbGUKLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICBFWFBSVE9LRU5fRlVOQ1RJT05fTkFNRSAgICAgICAgICAgICAgICAgPSAgMzIsCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgLy8gWzZdIEF4aXNOYW1lIDo6PSAnYW5jZXN0b3InIHwgJ2FuY2VzdG9yLW9yLXNlbGYnCi0gICAgICAgICAgICAvLyAgICAgICAgICAgICAgICB8ICdhdHRyaWJ1dGUnCi0gICAgICAgICAgICAvLyAgICAgICAgICAgICAgICB8ICdjaGlsZCcKLSAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgIHwgJ2Rlc2NlbmRhbnQnIHwgJ2Rlc2NlbmRhbnQtb3Itc2VsZicKLSAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgIHwgJ2ZvbGxvd2luZycgfCAnZm9sbG93aW5nLXNpYmxpbmcnCi0gICAgICAgICAgICAvLyAgICAgICAgICAgICAgICB8ICduYW1lc3BhY2UnCi0gICAgICAgICAgICAvLyAgICAgICAgICAgICAgICB8ICdwYXJlbnQnCi0gICAgICAgICAgICAvLyAgICAgICAgICAgICAgICB8ICdwcmVjZWRpbmcnIHwgJ3ByZWNlZGluZy1zaWJsaW5nJwotICAgICAgICAgICAgLy8gICAgICAgICAgICAgICAgfCAnc2VsZicKLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICBFWFBSVE9LRU5fQVhJU05BTUVfQU5DRVNUT1IgICAgICAgICAgICAgPSAgMzMsCi0gICAgICAgICAgICBFWFBSVE9LRU5fQVhJU05BTUVfQU5DRVNUT1JfT1JfU0VMRiAgICAgPSAgMzQsCi0gICAgICAgICAgICBFWFBSVE9LRU5fQVhJU05BTUVfQVRUUklCVVRFICAgICAgICAgICAgPSAgMzUsCi0gICAgICAgICAgICBFWFBSVE9LRU5fQVhJU05BTUVfQ0hJTEQgICAgICAgICAgICAgICAgPSAgMzYsCi0gICAgICAgICAgICBFWFBSVE9LRU5fQVhJU05BTUVfREVTQ0VOREFOVCAgICAgICAgICAgPSAgMzcsCi0gICAgICAgICAgICBFWFBSVE9LRU5fQVhJU05BTUVfREVTQ0VOREFOVF9PUl9TRUxGICAgPSAgMzgsCi0gICAgICAgICAgICBFWFBSVE9LRU5fQVhJU05BTUVfRk9MTE9XSU5HICAgICAgICAgICAgPSAgMzksCi0gICAgICAgICAgICBFWFBSVE9LRU5fQVhJU05BTUVfRk9MTE9XSU5HX1NJQkxJTkcgICAgPSAgNDAsCi0gICAgICAgICAgICBFWFBSVE9LRU5fQVhJU05BTUVfTkFNRVNQQUNFICAgICAgICAgICAgPSAgNDEsCi0gICAgICAgICAgICBFWFBSVE9LRU5fQVhJU05BTUVfUEFSRU5UICAgICAgICAgICAgICAgPSAgNDIsCi0gICAgICAgICAgICBFWFBSVE9LRU5fQVhJU05BTUVfUFJFQ0VESU5HICAgICAgICAgICAgPSAgNDMsCi0gICAgICAgICAgICBFWFBSVE9LRU5fQVhJU05BTUVfUFJFQ0VESU5HX1NJQkxJTkcgICAgPSAgNDQsCi0gICAgICAgICAgICBFWFBSVE9LRU5fQVhJU05BTUVfU0VMRiAgICAgICAgICAgICAgICAgPSAgNDUsCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgLy8gWzI5XSBMaXRlcmFsIDo6PSAnIicgW14iXSogJyInIHwgIiciIFteJ10qICInIgotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIC8vIGZvbGxvd2VkIGJ5IHN5bWJvbCBoYW5kbGUgZm9yIGxpdGVyYWwKLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICBFWFBSVE9LRU5fTElURVJBTCAgICAgICAgICAgICAgICAgICAgICAgPSAgNDYsCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgLy8gWzMwXSBOdW1iZXIgOjo9IERpZ2l0cyAoJy4nIERpZ2l0cz8pPyB8ICcuJyBEaWdpdHMKLSAgICAgICAgICAgIC8vIFszMV0gRGlnaXRzIDo6PSBbMC05XSsKLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAvLyBmb2xsb3dlZCBieSBudW1iZXIgaGFuZGxlCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgRVhQUlRPS0VOX05VTUJFUiAgICAgICAgICAgICAgICAgICAgICAgID0gIDQ3LAotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIC8vIFszNl0gVmFyaWFibGVSZWZlcmVuY2UgOjo9ICckJyBRTmFtZQotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIC8vIGZvbGxvd2VkIGJ5IHN5bWJvbCBoYW5kbGUgZm9yIFFOYW1lCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgRVhQUlRPS0VOX1ZBUklBQkxFX1JFRkVSRU5DRSAgICAgICAgICAgID0gIDQ4OwotCi0gICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZ1tdIGZnVG9rZW5OYW1lcyA9IHsKLSAgICAgICAgICAgICJFWFBSVE9LRU5fT1BFTl9QQVJFTiIsCi0gICAgICAgICAgICAiRVhQUlRPS0VOX0NMT1NFX1BBUkVOIiwKLSAgICAgICAgICAgICJFWFBSVE9LRU5fT1BFTl9CUkFDS0VUIiwKLSAgICAgICAgICAgICJFWFBSVE9LRU5fQ0xPU0VfQlJBQ0tFVCIsCi0gICAgICAgICAgICAiRVhQUlRPS0VOX1BFUklPRCIsCi0gICAgICAgICAgICAiRVhQUlRPS0VOX0RPVUJMRV9QRVJJT0QiLAotICAgICAgICAgICAgIkVYUFJUT0tFTl9BVFNJR04iLAotICAgICAgICAgICAgIkVYUFJUT0tFTl9DT01NQSIsCi0gICAgICAgICAgICAiRVhQUlRPS0VOX0RPVUJMRV9DT0xPTiIsCi0gICAgICAgICAgICAiRVhQUlRPS0VOX05BTUVURVNUX0FOWSIsCi0gICAgICAgICAgICAiRVhQUlRPS0VOX05BTUVURVNUX05BTUVTUEFDRSIsCi0gICAgICAgICAgICAiRVhQUlRPS0VOX05BTUVURVNUX1FOQU1FIiwKLSAgICAgICAgICAgICJFWFBSVE9LRU5fTk9ERVRZUEVfQ09NTUVOVCIsCi0gICAgICAgICAgICAiRVhQUlRPS0VOX05PREVUWVBFX1RFWFQiLAotICAgICAgICAgICAgIkVYUFJUT0tFTl9OT0RFVFlQRV9QSSIsCi0gICAgICAgICAgICAiRVhQUlRPS0VOX05PREVUWVBFX05PREUiLAotICAgICAgICAgICAgIkVYUFJUT0tFTl9PUEVSQVRPUl9BTkQiLAotICAgICAgICAgICAgIkVYUFJUT0tFTl9PUEVSQVRPUl9PUiIsCi0gICAgICAgICAgICAiRVhQUlRPS0VOX09QRVJBVE9SX01PRCIsCi0gICAgICAgICAgICAiRVhQUlRPS0VOX09QRVJBVE9SX0RJViIsCi0gICAgICAgICAgICAiRVhQUlRPS0VOX09QRVJBVE9SX01VTFQiLAotICAgICAgICAgICAgIkVYUFJUT0tFTl9PUEVSQVRPUl9TTEFTSCIsCi0gICAgICAgICAgICAiRVhQUlRPS0VOX09QRVJBVE9SX0RPVUJMRV9TTEFTSCIsCi0gICAgICAgICAgICAiRVhQUlRPS0VOX09QRVJBVE9SX1VOSU9OIiwKLSAgICAgICAgICAgICJFWFBSVE9LRU5fT1BFUkFUT1JfUExVUyIsCi0gICAgICAgICAgICAiRVhQUlRPS0VOX09QRVJBVE9SX01JTlVTIiwKLSAgICAgICAgICAgICJFWFBSVE9LRU5fT1BFUkFUT1JfRVFVQUwiLAotICAgICAgICAgICAgIkVYUFJUT0tFTl9PUEVSQVRPUl9OT1RfRVFVQUwiLAotICAgICAgICAgICAgIkVYUFJUT0tFTl9PUEVSQVRPUl9MRVNTIiwKLSAgICAgICAgICAgICJFWFBSVE9LRU5fT1BFUkFUT1JfTEVTU19FUVVBTCIsCi0gICAgICAgICAgICAiRVhQUlRPS0VOX09QRVJBVE9SX0dSRUFURVIiLAotICAgICAgICAgICAgIkVYUFJUT0tFTl9PUEVSQVRPUl9HUkVBVEVSX0VRVUFMIiwKLSAgICAgICAgICAgICJFWFBSVE9LRU5fRlVOQ1RJT05fTkFNRSIsCi0gICAgICAgICAgICAiRVhQUlRPS0VOX0FYSVNOQU1FX0FOQ0VTVE9SIiwKLSAgICAgICAgICAgICJFWFBSVE9LRU5fQVhJU05BTUVfQU5DRVNUT1JfT1JfU0VMRiIsCi0gICAgICAgICAgICAiRVhQUlRPS0VOX0FYSVNOQU1FX0FUVFJJQlVURSIsCi0gICAgICAgICAgICAiRVhQUlRPS0VOX0FYSVNOQU1FX0NISUxEIiwKLSAgICAgICAgICAgICJFWFBSVE9LRU5fQVhJU05BTUVfREVTQ0VOREFOVCIsCi0gICAgICAgICAgICAiRVhQUlRPS0VOX0FYSVNOQU1FX0RFU0NFTkRBTlRfT1JfU0VMRiIsCi0gICAgICAgICAgICAiRVhQUlRPS0VOX0FYSVNOQU1FX0ZPTExPV0lORyIsCi0gICAgICAgICAgICAiRVhQUlRPS0VOX0FYSVNOQU1FX0ZPTExPV0lOR19TSUJMSU5HIiwKLSAgICAgICAgICAgICJFWFBSVE9LRU5fQVhJU05BTUVfTkFNRVNQQUNFIiwKLSAgICAgICAgICAgICJFWFBSVE9LRU5fQVhJU05BTUVfUEFSRU5UIiwKLSAgICAgICAgICAgICJFWFBSVE9LRU5fQVhJU05BTUVfUFJFQ0VESU5HIiwKLSAgICAgICAgICAgICJFWFBSVE9LRU5fQVhJU05BTUVfUFJFQ0VESU5HX1NJQkxJTkciLAotICAgICAgICAgICAgIkVYUFJUT0tFTl9BWElTTkFNRV9TRUxGIiwKLSAgICAgICAgICAgICJFWFBSVE9LRU5fTElURVJBTCIsCi0gICAgICAgICAgICAiRVhQUlRPS0VOX05VTUJFUiIsCi0gICAgICAgICAgICAiRVhQUlRPS0VOX1ZBUklBQkxFX1JFRkVSRU5DRSIKLSAgICAgICAgfTsKLQotICAgICAgICAvKioKLSAgICAgICAgICoKLSAgICAgICAgICovCi0gICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBJTklUSUFMX1RPS0VOX0NPVU5UID0gMSA8PCA4OwotICAgICAgICBwcml2YXRlIGludFtdIGZUb2tlbnMgPSBuZXcgaW50W0lOSVRJQUxfVE9LRU5fQ09VTlRdOwotICAgICAgICBwcml2YXRlIGludCBmVG9rZW5Db3VudCA9IDA7ICAgIC8vIGZvciB3cml0aW5nCi0KLSAgICAgICAgcHJpdmF0ZSBTeW1ib2xUYWJsZSBmU3ltYm9sVGFibGU7Ci0KLSAgICAgICAgLy8gUkVWSVNJVDogQ29kZSBzb21ldGhpbmcgYmV0dGVyIGhlcmUuIC1BYwotICAgICAgICBwcml2YXRlIE1hcDxTdHJpbmcsIEludGVnZXI+IGZTeW1ib2xNYXBwaW5nID0gbmV3IEhhc2hNYXA8PigpOwotCi0gICAgICAgIC8vIFJFVklTSVQ6IENvZGUgc29tZXRoaW5nIGJldHRlciBoZXJlLiAtQWMKLSAgICAgICAgcHJpdmF0ZSBNYXA8SW50ZWdlciwgU3RyaW5nPiBmVG9rZW5OYW1lcyA9IG5ldyBIYXNoTWFwPD4oKTsKLQotICAgICAgICAvKioKLSAgICAgICAgICogQ3VycmVudCBwb3NpdGlvbiBpbiB0aGUgdG9rZW4gbGlzdC4KLSAgICAgICAgICovCi0gICAgICAgIHByaXZhdGUgaW50IGZDdXJyZW50VG9rZW5JbmRleDsKLQotICAgICAgICAvLwotICAgICAgICAvLyBDb25zdHJ1Y3RvcnMKLSAgICAgICAgLy8KLQotICAgICAgICBwdWJsaWMgVG9rZW5zKFN5bWJvbFRhYmxlIHN5bWJvbFRhYmxlKSB7Ci0gICAgICAgICAgICBmU3ltYm9sVGFibGUgPSBzeW1ib2xUYWJsZTsKLSAgICAgICAgICAgIGZpbmFsIFN0cmluZ1tdIHN5bWJvbHMgPSB7Ci0gICAgICAgICAgICAgICAgImFuY2VzdG9yIiwgICAgICJhbmNlc3Rvci1vci1zZWxmIiwgICAgICJhdHRyaWJ1dGUiLAotICAgICAgICAgICAgICAgICJjaGlsZCIsICAgICAgICAiZGVzY2VuZGFudCIsICAgICAgICAgICAiZGVzY2VuZGFudC1vci1zZWxmIiwKLSAgICAgICAgICAgICAgICAiZm9sbG93aW5nIiwgICAgImZvbGxvd2luZy1zaWJsaW5nIiwgICAgIm5hbWVzcGFjZSIsCi0gICAgICAgICAgICAgICAgInBhcmVudCIsICAgICAgICJwcmVjZWRpbmciLCAgICAgICAgICAgICJwcmVjZWRpbmctc2libGluZyIsCi0gICAgICAgICAgICAgICAgInNlbGYiLAotICAgICAgICAgICAgfTsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc3ltYm9scy5sZW5ndGg7IGkrKykgewotICAgICAgICAgICAgICAgIGZTeW1ib2xNYXBwaW5nLnB1dChmU3ltYm9sVGFibGUuYWRkU3ltYm9sKHN5bWJvbHNbaV0pLCBpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGZUb2tlbk5hbWVzLnB1dChFWFBSVE9LRU5fT1BFTl9QQVJFTiwgIkVYUFJUT0tFTl9PUEVOX1BBUkVOIik7Ci0gICAgICAgICAgICBmVG9rZW5OYW1lcy5wdXQoRVhQUlRPS0VOX0NMT1NFX1BBUkVOLCAiRVhQUlRPS0VOX0NMT1NFX1BBUkVOIik7Ci0gICAgICAgICAgICBmVG9rZW5OYW1lcy5wdXQoRVhQUlRPS0VOX09QRU5fQlJBQ0tFVCwgIkVYUFJUT0tFTl9PUEVOX0JSQUNLRVQiKTsKLSAgICAgICAgICAgIGZUb2tlbk5hbWVzLnB1dChFWFBSVE9LRU5fQ0xPU0VfQlJBQ0tFVCwgIkVYUFJUT0tFTl9DTE9TRV9CUkFDS0VUIik7Ci0gICAgICAgICAgICBmVG9rZW5OYW1lcy5wdXQoRVhQUlRPS0VOX1BFUklPRCwgIkVYUFJUT0tFTl9QRVJJT0QiKTsKLSAgICAgICAgICAgIGZUb2tlbk5hbWVzLnB1dChFWFBSVE9LRU5fRE9VQkxFX1BFUklPRCwgIkVYUFJUT0tFTl9ET1VCTEVfUEVSSU9EIik7Ci0gICAgICAgICAgICBmVG9rZW5OYW1lcy5wdXQoRVhQUlRPS0VOX0FUU0lHTiwgIkVYUFJUT0tFTl9BVFNJR04iKTsKLSAgICAgICAgICAgIGZUb2tlbk5hbWVzLnB1dChFWFBSVE9LRU5fQ09NTUEsICJFWFBSVE9LRU5fQ09NTUEiKTsKLSAgICAgICAgICAgIGZUb2tlbk5hbWVzLnB1dChFWFBSVE9LRU5fRE9VQkxFX0NPTE9OLCAiRVhQUlRPS0VOX0RPVUJMRV9DT0xPTiIpOwotICAgICAgICAgICAgZlRva2VuTmFtZXMucHV0KEVYUFJUT0tFTl9OQU1FVEVTVF9BTlksICJFWFBSVE9LRU5fTkFNRVRFU1RfQU5ZIik7Ci0gICAgICAgICAgICBmVG9rZW5OYW1lcy5wdXQoRVhQUlRPS0VOX05BTUVURVNUX05BTUVTUEFDRSwgIkVYUFJUT0tFTl9OQU1FVEVTVF9OQU1FU1BBQ0UiKTsKLSAgICAgICAgICAgIGZUb2tlbk5hbWVzLnB1dChFWFBSVE9LRU5fTkFNRVRFU1RfUU5BTUUsICJFWFBSVE9LRU5fTkFNRVRFU1RfUU5BTUUiKTsKLSAgICAgICAgICAgIGZUb2tlbk5hbWVzLnB1dChFWFBSVE9LRU5fTk9ERVRZUEVfQ09NTUVOVCwgIkVYUFJUT0tFTl9OT0RFVFlQRV9DT01NRU5UIik7Ci0gICAgICAgICAgICBmVG9rZW5OYW1lcy5wdXQoRVhQUlRPS0VOX05PREVUWVBFX1RFWFQsICJFWFBSVE9LRU5fTk9ERVRZUEVfVEVYVCIpOwotICAgICAgICAgICAgZlRva2VuTmFtZXMucHV0KEVYUFJUT0tFTl9OT0RFVFlQRV9QSSwgIkVYUFJUT0tFTl9OT0RFVFlQRV9QSSIpOwotICAgICAgICAgICAgZlRva2VuTmFtZXMucHV0KEVYUFJUT0tFTl9OT0RFVFlQRV9OT0RFLCAiRVhQUlRPS0VOX05PREVUWVBFX05PREUiKTsKLSAgICAgICAgICAgIGZUb2tlbk5hbWVzLnB1dChFWFBSVE9LRU5fT1BFUkFUT1JfQU5ELCAiRVhQUlRPS0VOX09QRVJBVE9SX0FORCIpOwotICAgICAgICAgICAgZlRva2VuTmFtZXMucHV0KEVYUFJUT0tFTl9PUEVSQVRPUl9PUiwgIkVYUFJUT0tFTl9PUEVSQVRPUl9PUiIpOwotICAgICAgICAgICAgZlRva2VuTmFtZXMucHV0KEVYUFJUT0tFTl9PUEVSQVRPUl9NT0QsICJFWFBSVE9LRU5fT1BFUkFUT1JfTU9EIik7Ci0gICAgICAgICAgICBmVG9rZW5OYW1lcy5wdXQoRVhQUlRPS0VOX09QRVJBVE9SX0RJViwgIkVYUFJUT0tFTl9PUEVSQVRPUl9ESVYiKTsKLSAgICAgICAgICAgIGZUb2tlbk5hbWVzLnB1dChFWFBSVE9LRU5fT1BFUkFUT1JfTVVMVCwgIkVYUFJUT0tFTl9PUEVSQVRPUl9NVUxUIik7Ci0gICAgICAgICAgICBmVG9rZW5OYW1lcy5wdXQoRVhQUlRPS0VOX09QRVJBVE9SX1NMQVNILCAiRVhQUlRPS0VOX09QRVJBVE9SX1NMQVNIIik7Ci0gICAgICAgICAgICBmVG9rZW5OYW1lcy5wdXQoRVhQUlRPS0VOX09QRVJBVE9SX0RPVUJMRV9TTEFTSCwgIkVYUFJUT0tFTl9PUEVSQVRPUl9ET1VCTEVfU0xBU0giKTsKLSAgICAgICAgICAgIGZUb2tlbk5hbWVzLnB1dChFWFBSVE9LRU5fT1BFUkFUT1JfVU5JT04sICJFWFBSVE9LRU5fT1BFUkFUT1JfVU5JT04iKTsKLSAgICAgICAgICAgIGZUb2tlbk5hbWVzLnB1dChFWFBSVE9LRU5fT1BFUkFUT1JfUExVUywgIkVYUFJUT0tFTl9PUEVSQVRPUl9QTFVTIik7Ci0gICAgICAgICAgICBmVG9rZW5OYW1lcy5wdXQoRVhQUlRPS0VOX09QRVJBVE9SX01JTlVTLCAiRVhQUlRPS0VOX09QRVJBVE9SX01JTlVTIik7Ci0gICAgICAgICAgICBmVG9rZW5OYW1lcy5wdXQoRVhQUlRPS0VOX09QRVJBVE9SX0VRVUFMLCAiRVhQUlRPS0VOX09QRVJBVE9SX0VRVUFMIik7Ci0gICAgICAgICAgICBmVG9rZW5OYW1lcy5wdXQoRVhQUlRPS0VOX09QRVJBVE9SX05PVF9FUVVBTCwgIkVYUFJUT0tFTl9PUEVSQVRPUl9OT1RfRVFVQUwiKTsKLSAgICAgICAgICAgIGZUb2tlbk5hbWVzLnB1dChFWFBSVE9LRU5fT1BFUkFUT1JfTEVTUywgIkVYUFJUT0tFTl9PUEVSQVRPUl9MRVNTIik7Ci0gICAgICAgICAgICBmVG9rZW5OYW1lcy5wdXQoRVhQUlRPS0VOX09QRVJBVE9SX0xFU1NfRVFVQUwsICJFWFBSVE9LRU5fT1BFUkFUT1JfTEVTU19FUVVBTCIpOwotICAgICAgICAgICAgZlRva2VuTmFtZXMucHV0KEVYUFJUT0tFTl9PUEVSQVRPUl9HUkVBVEVSLCAiRVhQUlRPS0VOX09QRVJBVE9SX0dSRUFURVIiKTsKLSAgICAgICAgICAgIGZUb2tlbk5hbWVzLnB1dChFWFBSVE9LRU5fT1BFUkFUT1JfR1JFQVRFUl9FUVVBTCwgIkVYUFJUT0tFTl9PUEVSQVRPUl9HUkVBVEVSX0VRVUFMIik7Ci0gICAgICAgICAgICBmVG9rZW5OYW1lcy5wdXQoRVhQUlRPS0VOX0ZVTkNUSU9OX05BTUUsICJFWFBSVE9LRU5fRlVOQ1RJT05fTkFNRSIpOwotICAgICAgICAgICAgZlRva2VuTmFtZXMucHV0KEVYUFJUT0tFTl9BWElTTkFNRV9BTkNFU1RPUiwgIkVYUFJUT0tFTl9BWElTTkFNRV9BTkNFU1RPUiIpOwotICAgICAgICAgICAgZlRva2VuTmFtZXMucHV0KEVYUFJUT0tFTl9BWElTTkFNRV9BTkNFU1RPUl9PUl9TRUxGLCAiRVhQUlRPS0VOX0FYSVNOQU1FX0FOQ0VTVE9SX09SX1NFTEYiKTsKLSAgICAgICAgICAgIGZUb2tlbk5hbWVzLnB1dChFWFBSVE9LRU5fQVhJU05BTUVfQVRUUklCVVRFLCAiRVhQUlRPS0VOX0FYSVNOQU1FX0FUVFJJQlVURSIpOwotICAgICAgICAgICAgZlRva2VuTmFtZXMucHV0KEVYUFJUT0tFTl9BWElTTkFNRV9DSElMRCwgIkVYUFJUT0tFTl9BWElTTkFNRV9DSElMRCIpOwotICAgICAgICAgICAgZlRva2VuTmFtZXMucHV0KEVYUFJUT0tFTl9BWElTTkFNRV9ERVNDRU5EQU5ULCAiRVhQUlRPS0VOX0FYSVNOQU1FX0RFU0NFTkRBTlQiKTsKLSAgICAgICAgICAgIGZUb2tlbk5hbWVzLnB1dChFWFBSVE9LRU5fQVhJU05BTUVfREVTQ0VOREFOVF9PUl9TRUxGLCAiRVhQUlRPS0VOX0FYSVNOQU1FX0RFU0NFTkRBTlRfT1JfU0VMRiIpOwotICAgICAgICAgICAgZlRva2VuTmFtZXMucHV0KEVYUFJUT0tFTl9BWElTTkFNRV9GT0xMT1dJTkcsICJFWFBSVE9LRU5fQVhJU05BTUVfRk9MTE9XSU5HIik7Ci0gICAgICAgICAgICBmVG9rZW5OYW1lcy5wdXQoRVhQUlRPS0VOX0FYSVNOQU1FX0ZPTExPV0lOR19TSUJMSU5HLCAiRVhQUlRPS0VOX0FYSVNOQU1FX0ZPTExPV0lOR19TSUJMSU5HIik7Ci0gICAgICAgICAgICBmVG9rZW5OYW1lcy5wdXQoRVhQUlRPS0VOX0FYSVNOQU1FX05BTUVTUEFDRSwgIkVYUFJUT0tFTl9BWElTTkFNRV9OQU1FU1BBQ0UiKTsKLSAgICAgICAgICAgIGZUb2tlbk5hbWVzLnB1dChFWFBSVE9LRU5fQVhJU05BTUVfUEFSRU5ULCAiRVhQUlRPS0VOX0FYSVNOQU1FX1BBUkVOVCIpOwotICAgICAgICAgICAgZlRva2VuTmFtZXMucHV0KEVYUFJUT0tFTl9BWElTTkFNRV9QUkVDRURJTkcsICJFWFBSVE9LRU5fQVhJU05BTUVfUFJFQ0VESU5HIik7Ci0gICAgICAgICAgICBmVG9rZW5OYW1lcy5wdXQoRVhQUlRPS0VOX0FYSVNOQU1FX1BSRUNFRElOR19TSUJMSU5HLCAiRVhQUlRPS0VOX0FYSVNOQU1FX1BSRUNFRElOR19TSUJMSU5HIik7Ci0gICAgICAgICAgICBmVG9rZW5OYW1lcy5wdXQoRVhQUlRPS0VOX0FYSVNOQU1FX1NFTEYsICJFWFBSVE9LRU5fQVhJU05BTUVfU0VMRiIpOwotICAgICAgICAgICAgZlRva2VuTmFtZXMucHV0KEVYUFJUT0tFTl9MSVRFUkFMLCAiRVhQUlRPS0VOX0xJVEVSQUwiKTsKLSAgICAgICAgICAgIGZUb2tlbk5hbWVzLnB1dChFWFBSVE9LRU5fTlVNQkVSLCAiRVhQUlRPS0VOX05VTUJFUiIpOwotICAgICAgICAgICAgZlRva2VuTmFtZXMucHV0KEVYUFJUT0tFTl9WQVJJQUJMRV9SRUZFUkVOQ0UsICJFWFBSVE9LRU5fVkFSSUFCTEVfUkVGRVJFTkNFIik7Ci0gICAgICAgIH0KLQotICAgICAgICAvLwotICAgICAgICAvLyBQdWJsaWMgbWV0aG9kcwotICAgICAgICAvLwotCi0vLyAgICAgICAgcHVibGljIFN0cmluZyBnZXRUb2tlbk5hbWUoaW50IHRva2VuKSB7Ci0vLyAgICAgICAgICAgIGlmICh0b2tlbiA8IDAgfHwgdG9rZW4gPj0gZmdUb2tlbk5hbWVzLmxlbmd0aCkKLS8vICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwotLy8gICAgICAgICAgICByZXR1cm4gZmdUb2tlbk5hbWVzW3Rva2VuXTsKLS8vICAgICAgICB9Ci0vLwotICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFRva2VuU3RyaW5nKGludCB0b2tlbikgewotICAgICAgICAgICAgcmV0dXJuIGZUb2tlbk5hbWVzLmdldCh0b2tlbik7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCBhZGRUb2tlbihTdHJpbmcgdG9rZW5TdHIpIHsKLSAgICAgICAgICAgIEludGVnZXIgdG9rZW5JbnQgPSBudWxsOwotICAgICAgICAgICAgZm9yIChNYXAuRW50cnk8SW50ZWdlciwgU3RyaW5nPiBlbnRyeSA6IGZUb2tlbk5hbWVzLmVudHJ5U2V0KCkpIHsKLSAgICAgICAgICAgICAgICBpZiAoZW50cnkuZ2V0VmFsdWUoKS5lcXVhbHModG9rZW5TdHIpKSB7Ci0gICAgICAgICAgICAgICAgICAgIHRva2VuSW50ID0gZW50cnkuZ2V0S2V5KCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKHRva2VuSW50ID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICB0b2tlbkludCA9IGZUb2tlbk5hbWVzLnNpemUoKTsKLSAgICAgICAgICAgICAgICBmVG9rZW5OYW1lcy5wdXQodG9rZW5JbnQsIHRva2VuU3RyKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGFkZFRva2VuKHRva2VuSW50KTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyB2b2lkIGFkZFRva2VuKGludCB0b2tlbikgewotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICBmVG9rZW5zW2ZUb2tlbkNvdW50XSA9IHRva2VuOwotICAgICAgICAgICAgfSBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4KSB7Ci0gICAgICAgICAgICAgICAgaW50W10gb2xkTGlzdCA9IGZUb2tlbnM7Ci0gICAgICAgICAgICAgICAgZlRva2VucyA9IG5ldyBpbnRbZlRva2VuQ291bnQgPDwgMV07Ci0gICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShvbGRMaXN0LCAwLCBmVG9rZW5zLCAwLCBmVG9rZW5Db3VudCk7Ci0gICAgICAgICAgICAgICAgZlRva2Vuc1tmVG9rZW5Db3VudF0gPSB0b2tlbjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGZUb2tlbkNvdW50Kys7Ci0gICAgICAgIH0KLS8vICAgICAgICBwdWJsaWMgaW50IGdldFRva2VuQ291bnQoKSB7Ci0vLyAgICAgICAgICAgIHJldHVybiBmVG9rZW5Db3VudDsKLS8vICAgICAgICB9Ci0vLyAgICAgICAgcHVibGljIGludCBnZXRUb2tlbihpbnQgdG9rZW5JbmRleCkgewotLy8gICAgICAgICAgICByZXR1cm4gZlRva2Vuc1t0b2tlbkluZGV4XTsKLS8vICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFJlc2V0cyB0aGUgY3VycmVudCBwb3NpdGlvbiB0byB0aGUgaGVhZCBvZiB0aGUgdG9rZW4gbGlzdC4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyB2b2lkIHJld2luZCgpIHsKLSAgICAgICAgICAgIGZDdXJyZW50VG9rZW5JbmRleD0wOwotICAgICAgICB9Ci0gICAgICAgIC8qKgotICAgICAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIHtAbGluayAjZ2V0TmV4dFRva2VuKCl9IG1ldGhvZAotICAgICAgICAgKiByZXR1cm5zIGEgdmFsaWQgdG9rZW4uCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNNb3JlKCkgewotICAgICAgICAgICAgcmV0dXJuIGZDdXJyZW50VG9rZW5JbmRleDxmVG9rZW5Db3VudDsKLSAgICAgICAgfQotICAgICAgICAvKioKLSAgICAgICAgICogT2J0YWlucyB0aGUgdG9rZW4gYXQgdGhlIGN1cnJlbnQgcG9zaXRpb24sIHRoZW4gYWR2YW5jZQotICAgICAgICAgKiB0aGUgY3VycmVudCBwb3NpdGlvbiBieSBvbmUuCi0gICAgICAgICAqCi0gICAgICAgICAqIElmIHRoZXJlJ3Mgbm8gc3VjaCBuZXh0IHRva2VuLCB0aGlzIG1ldGhvZCB0aHJvd3MKLSAgICAgICAgICogPHR0Pm5ldyBYUGF0aEV4Y2VwdGlvbigiYy1nZW5lcmFsLXhwYXRoIik7PC90dD4uCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgaW50IG5leHRUb2tlbigpIHRocm93cyBYUGF0aEV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICBpZiggZkN1cnJlbnRUb2tlbkluZGV4PT1mVG9rZW5Db3VudCApCi0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFhQYXRoRXhjZXB0aW9uKCJjLWdlbmVyYWwteHBhdGgiKTsKLSAgICAgICAgICAgIHJldHVybiBmVG9rZW5zW2ZDdXJyZW50VG9rZW5JbmRleCsrXTsKLSAgICAgICAgfQotICAgICAgICAvKioKLSAgICAgICAgICogT2J0YWlucyB0aGUgdG9rZW4gYXQgdGhlIGN1cnJlbnQgcG9zaXRpb24sIHdpdGhvdXQgYWR2YW5jaW5nCi0gICAgICAgICAqIHRoZSBjdXJyZW50IHBvc2l0aW9uLgotICAgICAgICAgKgotICAgICAgICAgKiBJZiB0aGVyZSdzIG5vIHN1Y2ggbmV4dCB0b2tlbiwgdGhpcyBtZXRob2QgdGhyb3dzCi0gICAgICAgICAqIDx0dD5uZXcgWFBhdGhFeGNlcHRpb24oImMtZ2VuZXJhbC14cGF0aCIpOzwvdHQ+LgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIGludCBwZWVrVG9rZW4oKSB0aHJvd3MgWFBhdGhFeGNlcHRpb24gewotICAgICAgICAgICAgaWYoIGZDdXJyZW50VG9rZW5JbmRleD09ZlRva2VuQ291bnQgKQotICAgICAgICAgICAgICAgIHRocm93IG5ldyBYUGF0aEV4Y2VwdGlvbigiYy1nZW5lcmFsLXhwYXRoIik7Ci0gICAgICAgICAgICByZXR1cm4gZlRva2Vuc1tmQ3VycmVudFRva2VuSW5kZXhdOwotICAgICAgICB9Ci0gICAgICAgIC8qKgotICAgICAgICAgKiBPYnRhaW5zIHRoZSB0b2tlbiBhdCB0aGUgY3VycmVudCBwb3NpdGlvbiBhcyBhIFN0cmluZy4KLSAgICAgICAgICoKLSAgICAgICAgICogSWYgdGhlcmUncyBubyBjdXJyZW50IHRva2VuIG9yIGlmIHRoZSBjdXJyZW50IHRva2VuCi0gICAgICAgICAqIGlzIG5vdCBhIHN0cmluZyB0b2tlbiwgdGhpcyBtZXRob2QgdGhyb3dzCi0gICAgICAgICAqIDx0dD5uZXcgWFBhdGhFeGNlcHRpb24oImMtZ2VuZXJhbC14cGF0aCIpOzwvdHQ+LgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIFN0cmluZyBuZXh0VG9rZW5Bc1N0cmluZygpIHRocm93cyBYUGF0aEV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICBTdHJpbmcgcyA9IGdldFRva2VuU3RyaW5nKG5leHRUb2tlbigpKTsKLSAgICAgICAgICAgIGlmKHM9PW51bGwpICAgICB0aHJvdyBuZXcgWFBhdGhFeGNlcHRpb24oImMtZ2VuZXJhbC14cGF0aCIpOwotICAgICAgICAgICAgcmV0dXJuIHM7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCBkdW1wVG9rZW5zKCkgewotICAgICAgICAgICAgLy9pZiAoRFVNUF9UT0tFTlMpIHsKLSAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZUb2tlbkNvdW50OyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChmVG9rZW5zW2ldKSB7Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgRVhQUlRPS0VOX09QRU5fUEFSRU46Ci0gICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCI8T1BFTl9QQVJFTi8+Iik7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgY2FzZSBFWFBSVE9LRU5fQ0xPU0VfUEFSRU46Ci0gICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCI8Q0xPU0VfUEFSRU4vPiIpOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgRVhQUlRPS0VOX09QRU5fQlJBQ0tFVDoKLSAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIjxPUEVOX0JSQUNLRVQvPiIpOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgRVhQUlRPS0VOX0NMT1NFX0JSQUNLRVQ6Ci0gICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCI8Q0xPU0VfQlJBQ0tFVC8+Iik7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgY2FzZSBFWFBSVE9LRU5fUEVSSU9EOgotICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiPFBFUklPRC8+Iik7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgY2FzZSBFWFBSVE9LRU5fRE9VQkxFX1BFUklPRDoKLSAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIjxET1VCTEVfUEVSSU9ELz4iKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICBjYXNlIEVYUFJUT0tFTl9BVFNJR046Ci0gICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCI8QVRTSUdOLz4iKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICBjYXNlIEVYUFJUT0tFTl9DT01NQToKLSAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIjxDT01NQS8+Iik7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgY2FzZSBFWFBSVE9LRU5fRE9VQkxFX0NPTE9OOgotICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiPERPVUJMRV9DT0xPTi8+Iik7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgY2FzZSBFWFBSVE9LRU5fTkFNRVRFU1RfQU5ZOgotICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiPE5BTUVURVNUX0FOWS8+Iik7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgY2FzZSBFWFBSVE9LRU5fTkFNRVRFU1RfTkFNRVNQQUNFOgotICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiPE5BTUVURVNUX05BTUVTUEFDRSIpOwotICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiIHByZWZpeD1cIiIgKyBnZXRUb2tlblN0cmluZyhmVG9rZW5zWysraV0pICsgIlwiIik7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCIvPiIpOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgRVhQUlRPS0VOX05BTUVURVNUX1FOQU1FOgotICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiPE5BTUVURVNUX1FOQU1FIik7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZlRva2Vuc1srK2ldICE9IC0xKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIiBwcmVmaXg9XCIiICsgZ2V0VG9rZW5TdHJpbmcoZlRva2Vuc1tpXSkgKyAiXCIiKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIiBsb2NhbHBhcnQ9XCIiICsgZ2V0VG9rZW5TdHJpbmcoZlRva2Vuc1srK2ldKSArICJcIiIpOwotICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiLz4iKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICBjYXNlIEVYUFJUT0tFTl9OT0RFVFlQRV9DT01NRU5UOgotICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiPE5PREVUWVBFX0NPTU1FTlQvPiIpOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgRVhQUlRPS0VOX05PREVUWVBFX1RFWFQ6Ci0gICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCI8Tk9ERVRZUEVfVEVYVC8+Iik7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgY2FzZSBFWFBSVE9LRU5fTk9ERVRZUEVfUEk6Ci0gICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCI8Tk9ERVRZUEVfUEkvPiIpOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgRVhQUlRPS0VOX05PREVUWVBFX05PREU6Ci0gICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCI8Tk9ERVRZUEVfTk9ERS8+Iik7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgY2FzZSBFWFBSVE9LRU5fT1BFUkFUT1JfQU5EOgotICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiPE9QRVJBVE9SX0FORC8+Iik7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgY2FzZSBFWFBSVE9LRU5fT1BFUkFUT1JfT1I6Ci0gICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCI8T1BFUkFUT1JfT1IvPiIpOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgRVhQUlRPS0VOX09QRVJBVE9SX01PRDoKLSAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIjxPUEVSQVRPUl9NT0QvPiIpOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgRVhQUlRPS0VOX09QRVJBVE9SX0RJVjoKLSAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIjxPUEVSQVRPUl9ESVYvPiIpOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgRVhQUlRPS0VOX09QRVJBVE9SX01VTFQ6Ci0gICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCI8T1BFUkFUT1JfTVVMVC8+Iik7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgY2FzZSBFWFBSVE9LRU5fT1BFUkFUT1JfU0xBU0g6Ci0gICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCI8T1BFUkFUT1JfU0xBU0gvPiIpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGkgKyAxIDwgZlRva2VuQ291bnQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCIgICIpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgRVhQUlRPS0VOX09QRVJBVE9SX0RPVUJMRV9TTEFTSDoKLSAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIjxPUEVSQVRPUl9ET1VCTEVfU0xBU0gvPiIpOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgRVhQUlRPS0VOX09QRVJBVE9SX1VOSU9OOgotICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiPE9QRVJBVE9SX1VOSU9OLz4iKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICBjYXNlIEVYUFJUT0tFTl9PUEVSQVRPUl9QTFVTOgotICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiPE9QRVJBVE9SX1BMVVMvPiIpOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgRVhQUlRPS0VOX09QRVJBVE9SX01JTlVTOgotICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiPE9QRVJBVE9SX01JTlVTLz4iKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICBjYXNlIEVYUFJUT0tFTl9PUEVSQVRPUl9FUVVBTDoKLSAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIjxPUEVSQVRPUl9FUVVBTC8+Iik7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgY2FzZSBFWFBSVE9LRU5fT1BFUkFUT1JfTk9UX0VRVUFMOgotICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiPE9QRVJBVE9SX05PVF9FUVVBTC8+Iik7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgY2FzZSBFWFBSVE9LRU5fT1BFUkFUT1JfTEVTUzoKLSAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIjxPUEVSQVRPUl9MRVNTLz4iKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICBjYXNlIEVYUFJUT0tFTl9PUEVSQVRPUl9MRVNTX0VRVUFMOgotICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiPE9QRVJBVE9SX0xFU1NfRVFVQUwvPiIpOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgRVhQUlRPS0VOX09QRVJBVE9SX0dSRUFURVI6Ci0gICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCI8T1BFUkFUT1JfR1JFQVRFUi8+Iik7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgY2FzZSBFWFBSVE9LRU5fT1BFUkFUT1JfR1JFQVRFUl9FUVVBTDoKLSAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIjxPUEVSQVRPUl9HUkVBVEVSX0VRVUFMLz4iKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICBjYXNlIEVYUFJUT0tFTl9GVU5DVElPTl9OQU1FOgotICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiPEZVTkNUSU9OX05BTUUiKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmVG9rZW5zWysraV0gIT0gLTEpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiIHByZWZpeD1cIiIgKyBnZXRUb2tlblN0cmluZyhmVG9rZW5zW2ldKSArICJcIiIpOwotICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiIGxvY2FscGFydD1cIiIgKyBnZXRUb2tlblN0cmluZyhmVG9rZW5zWysraV0pICsgIlwiIik7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCIvPiIpOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgRVhQUlRPS0VOX0FYSVNOQU1FX0FOQ0VTVE9SOgotICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiPEFYSVNOQU1FX0FOQ0VTVE9SLz4iKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICBjYXNlIEVYUFJUT0tFTl9BWElTTkFNRV9BTkNFU1RPUl9PUl9TRUxGOgotICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiPEFYSVNOQU1FX0FOQ0VTVE9SX09SX1NFTEYvPiIpOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgRVhQUlRPS0VOX0FYSVNOQU1FX0FUVFJJQlVURToKLSAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIjxBWElTTkFNRV9BVFRSSUJVVEUvPiIpOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgRVhQUlRPS0VOX0FYSVNOQU1FX0NISUxEOgotICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiPEFYSVNOQU1FX0NISUxELz4iKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICBjYXNlIEVYUFJUT0tFTl9BWElTTkFNRV9ERVNDRU5EQU5UOgotICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiPEFYSVNOQU1FX0RFU0NFTkRBTlQvPiIpOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgRVhQUlRPS0VOX0FYSVNOQU1FX0RFU0NFTkRBTlRfT1JfU0VMRjoKLSAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIjxBWElTTkFNRV9ERVNDRU5EQU5UX09SX1NFTEYvPiIpOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgRVhQUlRPS0VOX0FYSVNOQU1FX0ZPTExPV0lORzoKLSAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIjxBWElTTkFNRV9GT0xMT1dJTkcvPiIpOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgRVhQUlRPS0VOX0FYSVNOQU1FX0ZPTExPV0lOR19TSUJMSU5HOgotICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiPEFYSVNOQU1FX0ZPTExPV0lOR19TSUJMSU5HLz4iKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICBjYXNlIEVYUFJUT0tFTl9BWElTTkFNRV9OQU1FU1BBQ0U6Ci0gICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCI8QVhJU05BTUVfTkFNRVNQQUNFLz4iKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICBjYXNlIEVYUFJUT0tFTl9BWElTTkFNRV9QQVJFTlQ6Ci0gICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCI8QVhJU05BTUVfUEFSRU5ULz4iKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICBjYXNlIEVYUFJUT0tFTl9BWElTTkFNRV9QUkVDRURJTkc6Ci0gICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCI8QVhJU05BTUVfUFJFQ0VESU5HLz4iKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICBjYXNlIEVYUFJUT0tFTl9BWElTTkFNRV9QUkVDRURJTkdfU0lCTElORzoKLSAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIjxBWElTTkFNRV9QUkVDRURJTkdfU0lCTElORy8+Iik7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgY2FzZSBFWFBSVE9LRU5fQVhJU05BTUVfU0VMRjoKLSAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIjxBWElTTkFNRV9TRUxGLz4iKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICBjYXNlIEVYUFJUT0tFTl9MSVRFUkFMOgotICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiPExJVEVSQUwiKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIiB2YWx1ZT1cIiIgKyBnZXRUb2tlblN0cmluZyhmVG9rZW5zWysraV0pICsgIlwiIik7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCIvPiIpOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgRVhQUlRPS0VOX05VTUJFUjoKLSAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIjxOVU1CRVIiKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIiB3aG9sZT1cIiIgKyBnZXRUb2tlblN0cmluZyhmVG9rZW5zWysraV0pICsgIlwiIik7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCIgcGFydD1cIiIgKyBnZXRUb2tlblN0cmluZyhmVG9rZW5zWysraV0pICsgIlwiIik7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCIvPiIpOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgRVhQUlRPS0VOX1ZBUklBQkxFX1JFRkVSRU5DRToKLSAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIjxWQVJJQUJMRV9SRUZFUkVOQ0UiKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmVG9rZW5zWysraV0gIT0gLTEpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiIHByZWZpeD1cIiIgKyBnZXRUb2tlblN0cmluZyhmVG9rZW5zW2ldKSArICJcIiIpOwotICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiIGxvY2FscGFydD1cIiIgKyBnZXRUb2tlblN0cmluZyhmVG9rZW5zWysraV0pICsgIlwiIik7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCIvPiIpOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6Ci0gICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIjw/Pz8vPiIpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigpOwotICAgICAgICAgICAgLy99Ci0gICAgICAgIH0KLQotICAgIH0gLy8gY2xhc3MgVG9rZW5zCi0KLSAgICAvKioKLSAgICAgKiBAeGVyY2VzLmludGVybmFsCi0gICAgICoKLSAgICAgKiBAYXV0aG9yIEdsZW5uIE1hcmN5LCBJQk0KLSAgICAgKiBAYXV0aG9yIEFuZHkgQ2xhcmssIElCTQotICAgICAqCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgU2Nhbm5lciB7Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIDctYml0IEFTQ0lJIHN1YnNldAotICAgICAgICAgKgotICAgICAgICAgKiAgMCAgIDEgICAyICAgMyAgIDQgICA1ICAgNiAgIDcgICA4ICAgOSAgIEEgICBCICAgQyAgIEQgICBFICAgRgotICAgICAgICAgKiAgMCwgIDAsICAwLCAgMCwgIDAsICAwLCAgMCwgIDAsICAwLCBIVCwgTEYsICAwLCAgMCwgQ1IsICAwLCAgMCwgIC8vIDAKLSAgICAgICAgICogIDAsICAwLCAgMCwgIDAsICAwLCAgMCwgIDAsICAwLCAgMCwgIDAsICAwLCAgMCwgIDAsICAwLCAgMCwgIDAsICAvLyAxCi0gICAgICAgICAqIFNQLCAgISwgICIsICAjLCAgJCwgICUsICAmLCAgJywgICgsICApLCAgKiwgICssICAsLCAgLSwgIC4sICAvLCAgLy8gMgotICAgICAgICAgKiAgMCwgIDEsICAyLCAgMywgIDQsICA1LCAgNiwgIDcsICA4LCAgOSwgIDosICA7LCAgPCwgID0sICA+LCAgPywgIC8vIDMKLSAgICAgICAgICogIEAsICBBLCAgQiwgIEMsICBELCAgRSwgIEYsICBHLCAgSCwgIEksICBKLCAgSywgIEwsICBNLCAgTiwgIE8sICAvLyA0Ci0gICAgICAgICAqICBQLCAgUSwgIFIsICBTLCAgVCwgIFUsICBWLCAgVywgIFgsICBZLCAgWiwgIFssICBcLCAgXSwgIF4sICBfLCAgLy8gNQotICAgICAgICAgKiAgYCwgIGEsICBiLCAgYywgIGQsICBlLCAgZiwgIGcsICBoLCAgaSwgIGosICBrLCAgbCwgIG0sICBuLCAgbywgIC8vIDYKLSAgICAgICAgICogIHAsICBxLCAgciwgIHMsICB0LCAgdSwgIHYsICB3LCAgeCwgIHksICB6LCAgeywgIHwsICB9LCAgfiwgREVMICAvLyA3Ci0gICAgICAgICAqLwotICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlCi0gICAgICAgICAgICBDSEFSVFlQRV9JTlZBTElEICAgICAgICAgICAgPSAgMCwgICAvLyBpbnZhbGlkIFhNTCBjaGFyYWN0ZXIKLSAgICAgICAgICAgIENIQVJUWVBFX09USEVSICAgICAgICAgICAgICA9ICAxLCAgIC8vIG5vdCBzcGVjaWFsIC0gb25lIG9mICIjJSY7P1xeYHt9fiIgb3IgREVMCi0gICAgICAgICAgICBDSEFSVFlQRV9XSElURVNQQUNFICAgICAgICAgPSAgMiwgICAvLyBvbmUgb2YgIlx0XG5cciAiICgweDA5LCAweDBBLCAweDBELCAweDIwKQotICAgICAgICAgICAgQ0hBUlRZUEVfRVhDTEFNQVRJT04gICAgICAgID0gIDMsICAgLy8gJyEnICgweDIxKQotICAgICAgICAgICAgQ0hBUlRZUEVfUVVPVEUgICAgICAgICAgICAgID0gIDQsICAgLy8gJ1wiJyBvciAnXCcnICgweDIyIGFuZCAweDI3KQotICAgICAgICAgICAgQ0hBUlRZUEVfRE9MTEFSICAgICAgICAgICAgID0gIDUsICAgLy8gJyQnICgweDI0KQotICAgICAgICAgICAgQ0hBUlRZUEVfT1BFTl9QQVJFTiAgICAgICAgID0gIDYsICAgLy8gJygnICgweDI4KQotICAgICAgICAgICAgQ0hBUlRZUEVfQ0xPU0VfUEFSRU4gICAgICAgID0gIDcsICAgLy8gJyknICgweDI5KQotICAgICAgICAgICAgQ0hBUlRZUEVfU1RBUiAgICAgICAgICAgICAgID0gIDgsICAgLy8gJyonICgweDJBKQotICAgICAgICAgICAgQ0hBUlRZUEVfUExVUyAgICAgICAgICAgICAgID0gIDksICAgLy8gJysnICgweDJCKQotICAgICAgICAgICAgQ0hBUlRZUEVfQ09NTUEgICAgICAgICAgICAgID0gMTAsICAgLy8gJywnICgweDJDKQotICAgICAgICAgICAgQ0hBUlRZUEVfTUlOVVMgICAgICAgICAgICAgID0gMTEsICAgLy8gJy0nICgweDJEKQotICAgICAgICAgICAgQ0hBUlRZUEVfUEVSSU9EICAgICAgICAgICAgID0gMTIsICAgLy8gJy4nICgweDJFKQotICAgICAgICAgICAgQ0hBUlRZUEVfU0xBU0ggICAgICAgICAgICAgID0gMTMsICAgLy8gJy8nICgweDJGKQotICAgICAgICAgICAgQ0hBUlRZUEVfRElHSVQgICAgICAgICAgICAgID0gMTQsICAgLy8gJzAnLSc5JyAoMHgzMCB0byAweDM5KQotICAgICAgICAgICAgQ0hBUlRZUEVfQ09MT04gICAgICAgICAgICAgID0gMTUsICAgLy8gJzonICgweDNBKQotICAgICAgICAgICAgQ0hBUlRZUEVfTEVTUyAgICAgICAgICAgICAgID0gMTYsICAgLy8gJzwnICgweDNDKQotICAgICAgICAgICAgQ0hBUlRZUEVfRVFVQUwgICAgICAgICAgICAgID0gMTcsICAgLy8gJz0nICgweDNEKQotICAgICAgICAgICAgQ0hBUlRZUEVfR1JFQVRFUiAgICAgICAgICAgID0gMTgsICAgLy8gJz4nICgweDNFKQotICAgICAgICAgICAgQ0hBUlRZUEVfQVRTSUdOICAgICAgICAgICAgID0gMTksICAgLy8gJ0AnICgweDQwKQotICAgICAgICAgICAgQ0hBUlRZUEVfTEVUVEVSICAgICAgICAgICAgID0gMjAsICAgLy8gJ0EnLSdaJyBvciAnYSctJ3onICgweDQxIHRvIDB4NUEgYW5kIDB4NjEgdG8gMHg3QSkKLSAgICAgICAgICAgIENIQVJUWVBFX09QRU5fQlJBQ0tFVCAgICAgICA9IDIxLCAgIC8vICdbJyAoMHg1QikKLSAgICAgICAgICAgIENIQVJUWVBFX0NMT1NFX0JSQUNLRVQgICAgICA9IDIyLCAgIC8vICddJyAoMHg1RCkKLSAgICAgICAgICAgIENIQVJUWVBFX1VOREVSU0NPUkUgICAgICAgICA9IDIzLCAgIC8vICdfJyAoMHg1RikKLSAgICAgICAgICAgIENIQVJUWVBFX1VOSU9OICAgICAgICAgICAgICA9IDI0LCAgIC8vICd8JyAoMHg3QykKLSAgICAgICAgICAgIENIQVJUWVBFX05PTkFTQ0lJICAgICAgICAgICA9IDI1OyAgIC8vIE5vbi1BU0NJSSBVbmljb2RlIGNvZGVwb2ludCAoPj0gMHg4MCkKLQotICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW10gZkFTQ0lJQ2hhck1hcCA9IHsKLSAgICAgICAgICAgIDAsICAwLCAgMCwgIDAsICAwLCAgMCwgIDAsICAwLCAgMCwgIDIsICAyLCAgMCwgIDAsICAyLCAgMCwgIDAsCi0gICAgICAgICAgICAwLCAgMCwgIDAsICAwLCAgMCwgIDAsICAwLCAgMCwgIDAsICAwLCAgMCwgIDAsICAwLCAgMCwgIDAsICAwLAotICAgICAgICAgICAgMiwgIDMsICA0LCAgMSwgIDUsICAxLCAgMSwgIDQsICA2LCAgNywgIDgsICA5LCAxMCwgMTEsIDEyLCAxMywKLSAgICAgICAgICAgMTQsIDE0LCAxNCwgMTQsIDE0LCAxNCwgMTQsIDE0LCAxNCwgMTQsIDE1LCAgMSwgMTYsIDE3LCAxOCwgIDEsCi0gICAgICAgICAgIDE5LCAyMCwgMjAsIDIwLCAyMCwgMjAsIDIwLCAyMCwgMjAsIDIwLCAyMCwgMjAsIDIwLCAyMCwgMjAsIDIwLAotICAgICAgICAgICAyMCwgMjAsIDIwLCAyMCwgMjAsIDIwLCAyMCwgMjAsIDIwLCAyMCwgMjAsIDIxLCAgMSwgMjIsICAxLCAyMywKLSAgICAgICAgICAgIDEsIDIwLCAyMCwgMjAsIDIwLCAyMCwgMjAsIDIwLCAyMCwgMjAsIDIwLCAyMCwgMjAsIDIwLCAyMCwgMjAsCi0gICAgICAgICAgIDIwLCAyMCwgMjAsIDIwLCAyMCwgMjAsIDIwLCAyMCwgMjAsIDIwLCAyMCwgIDEsIDI0LCAgMSwgIDEsICAxCi0gICAgICAgIH07Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFN5bWJvbCBsaXRlcmFscwotICAgICAgICAgKi8KLQotICAgICAgICAvLwotICAgICAgICAvLyBEYXRhCi0gICAgICAgIC8vCi0KLSAgICAgICAgLyoqIFN5bWJvbCB0YWJsZS4gKi8KLSAgICAgICAgcHJpdmF0ZSBTeW1ib2xUYWJsZSBmU3ltYm9sVGFibGU7Ci0KLSAgICAgICAgLy8gc3ltYm9scwotCi0gICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBmQW5kU3ltYm9sID0gImFuZCIuaW50ZXJuKCk7Ci0gICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBmT3JTeW1ib2wgPSAib3IiLmludGVybigpOwotICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgZk1vZFN5bWJvbCA9ICJtb2QiLmludGVybigpOwotICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgZkRpdlN5bWJvbCA9ICJkaXYiLmludGVybigpOwotCi0gICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBmQ29tbWVudFN5bWJvbCA9ICJjb21tZW50Ii5pbnRlcm4oKTsKLSAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIGZUZXh0U3ltYm9sID0gInRleHQiLmludGVybigpOwotICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgZlBJU3ltYm9sID0gInByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24iLmludGVybigpOwotICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgZk5vZGVTeW1ib2wgPSAibm9kZSIuaW50ZXJuKCk7Ci0KLSAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIGZBbmNlc3RvclN5bWJvbCA9ICJhbmNlc3RvciIuaW50ZXJuKCk7Ci0gICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBmQW5jZXN0b3JPclNlbGZTeW1ib2wgPSAiYW5jZXN0b3Itb3Itc2VsZiIuaW50ZXJuKCk7Ci0gICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBmQXR0cmlidXRlU3ltYm9sID0gImF0dHJpYnV0ZSIuaW50ZXJuKCk7Ci0gICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBmQ2hpbGRTeW1ib2wgPSAiY2hpbGQiLmludGVybigpOwotICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgZkRlc2NlbmRhbnRTeW1ib2wgPSAiZGVzY2VuZGFudCIuaW50ZXJuKCk7Ci0gICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBmRGVzY2VuZGFudE9yU2VsZlN5bWJvbCA9ICJkZXNjZW5kYW50LW9yLXNlbGYiLmludGVybigpOwotICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgZkZvbGxvd2luZ1N5bWJvbCA9ICJmb2xsb3dpbmciLmludGVybigpOwotICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgZkZvbGxvd2luZ1NpYmxpbmdTeW1ib2wgPSAiZm9sbG93aW5nLXNpYmxpbmciLmludGVybigpOwotICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgZk5hbWVzcGFjZVN5bWJvbCA9ICJuYW1lc3BhY2UiLmludGVybigpOwotICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgZlBhcmVudFN5bWJvbCA9ICJwYXJlbnQiLmludGVybigpOwotICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgZlByZWNlZGluZ1N5bWJvbCA9ICJwcmVjZWRpbmciLmludGVybigpOwotICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgZlByZWNlZGluZ1NpYmxpbmdTeW1ib2wgPSAicHJlY2VkaW5nLXNpYmxpbmciLmludGVybigpOwotICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgZlNlbGZTeW1ib2wgPSAic2VsZiIuaW50ZXJuKCk7Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gQ29uc3RydWN0b3JzCi0gICAgICAgIC8vCi0KLSAgICAgICAgLyoqIENvbnN0cnVjdHMgYW4gWFBhdGggZXhwcmVzc2lvbiBzY2FubmVyLiAqLwotICAgICAgICBwdWJsaWMgU2Nhbm5lcihTeW1ib2xUYWJsZSBzeW1ib2xUYWJsZSkgewotCi0gICAgICAgICAgICAvLyBzYXZlIHBvb2wgYW5kIHRva2VucwotICAgICAgICAgICAgZlN5bWJvbFRhYmxlID0gc3ltYm9sVGFibGU7Ci0KLSAgICAgICAgfSAvLyA8aW5pdD4oU3ltYm9sVGFibGUpCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgYm9vbGVhbiBzY2FuRXhwcihTeW1ib2xUYWJsZSBzeW1ib2xUYWJsZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWFBhdGguVG9rZW5zIHRva2VucywgU3RyaW5nIGRhdGEsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBjdXJyZW50T2Zmc2V0LCBpbnQgZW5kT2Zmc2V0KQotICAgICAgICAgICAgdGhyb3dzIFhQYXRoRXhjZXB0aW9uIHsKLQotICAgICAgICAgICAgaW50IG5hbWVPZmZzZXQ7Ci0gICAgICAgICAgICBTdHJpbmcgbmFtZUhhbmRsZSwgcHJlZml4SGFuZGxlOwotICAgICAgICAgICAgYm9vbGVhbiBzdGFySXNNdWx0aXBseU9wZXJhdG9yID0gZmFsc2U7Ci0gICAgICAgICAgICBpbnQgY2g7Ci0KLSAgICAgICAgICAgIHdoaWxlICh0cnVlKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGN1cnJlbnRPZmZzZXQgPT0gZW5kT2Zmc2V0KSB7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBjaCA9IGRhdGEuY2hhckF0KGN1cnJlbnRPZmZzZXQpOwotICAgICAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAgICAgLy8gWzM5XSBFeHByV2hpdGVzcGFjZSA6Oj0gUwotICAgICAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAgICAgd2hpbGUgKGNoID09ICcgJyB8fCBjaCA9PSAweDBBIHx8IGNoID09IDB4MDkgfHwgY2ggPT0gMHgwRCkgewotICAgICAgICAgICAgICAgICAgICBpZiAoKytjdXJyZW50T2Zmc2V0ID09IGVuZE9mZnNldCkgewotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgY2ggPSBkYXRhLmNoYXJBdChjdXJyZW50T2Zmc2V0KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaWYgKGN1cnJlbnRPZmZzZXQgPT0gZW5kT2Zmc2V0KSB7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgIC8vIFsyOF0gRXhwclRva2VuIDo6PSAnKCcgfCAnKScgfCAnWycgfCAnXScgfCAnLicgfCAnLi4nIHwgJ0AnIHwgJywnIHwgJzo6JwotICAgICAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgICAgfCBOYW1lVGVzdCB8IE5vZGVUeXBlIHwgT3BlcmF0b3IgfCBGdW5jdGlvbk5hbWUKLSAgICAgICAgICAgICAgICAvLyAgICAgICAgICAgICAgICAgIHwgQXhpc05hbWUgfCBMaXRlcmFsIHwgTnVtYmVyIHwgVmFyaWFibGVSZWZlcmVuY2UKLSAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgIGJ5dGUgY2hhcnR5cGUgPSAoY2ggPj0gMHg4MCkgPyBDSEFSVFlQRV9OT05BU0NJSSA6IGZBU0NJSUNoYXJNYXBbY2hdOwotICAgICAgICAgICAgICAgIHN3aXRjaCAoY2hhcnR5cGUpIHsKLSAgICAgICAgICAgICAgICBjYXNlIENIQVJUWVBFX09QRU5fUEFSRU46ICAgICAgIC8vICcoJwotICAgICAgICAgICAgICAgICAgICBhZGRUb2tlbih0b2tlbnMsIFhQYXRoLlRva2Vucy5FWFBSVE9LRU5fT1BFTl9QQVJFTik7Ci0gICAgICAgICAgICAgICAgICAgIHN0YXJJc011bHRpcGx5T3BlcmF0b3IgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKCsrY3VycmVudE9mZnNldCA9PSBlbmRPZmZzZXQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGNhc2UgQ0hBUlRZUEVfQ0xPU0VfUEFSRU46ICAgICAgLy8gJyknCi0gICAgICAgICAgICAgICAgICAgIGFkZFRva2VuKHRva2VucywgWFBhdGguVG9rZW5zLkVYUFJUT0tFTl9DTE9TRV9QQVJFTik7Ci0gICAgICAgICAgICAgICAgICAgIHN0YXJJc011bHRpcGx5T3BlcmF0b3IgPSB0cnVlOwotICAgICAgICAgICAgICAgICAgICBpZiAoKytjdXJyZW50T2Zmc2V0ID09IGVuZE9mZnNldCkgewotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgY2FzZSBDSEFSVFlQRV9PUEVOX0JSQUNLRVQ6ICAgICAvLyAnWycKLSAgICAgICAgICAgICAgICAgICAgYWRkVG9rZW4odG9rZW5zLCBYUGF0aC5Ub2tlbnMuRVhQUlRPS0VOX09QRU5fQlJBQ0tFVCk7Ci0gICAgICAgICAgICAgICAgICAgIHN0YXJJc011bHRpcGx5T3BlcmF0b3IgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKCsrY3VycmVudE9mZnNldCA9PSBlbmRPZmZzZXQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGNhc2UgQ0hBUlRZUEVfQ0xPU0VfQlJBQ0tFVDogICAgLy8gJ10nCi0gICAgICAgICAgICAgICAgICAgIGFkZFRva2VuKHRva2VucywgWFBhdGguVG9rZW5zLkVYUFJUT0tFTl9DTE9TRV9CUkFDS0VUKTsKLSAgICAgICAgICAgICAgICAgICAgc3RhcklzTXVsdGlwbHlPcGVyYXRvciA9IHRydWU7Ci0gICAgICAgICAgICAgICAgICAgIGlmICgrK2N1cnJlbnRPZmZzZXQgPT0gZW5kT2Zmc2V0KSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgIC8vIFszMF0gTnVtYmVyIDo6PSBEaWdpdHMgKCcuJyBEaWdpdHM/KT8gfCAnLicgRGlnaXRzCi0gICAgICAgICAgICAgICAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF5eXl5eXl5eXl4KLSAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgIGNhc2UgQ0hBUlRZUEVfUEVSSU9EOiAgICAgICAgICAgLy8gJy4nLCAnLi4nIG9yICcuJyBEaWdpdHMKLSAgICAgICAgICAgICAgICAgICAgaWYgKGN1cnJlbnRPZmZzZXQgKyAxID09IGVuZE9mZnNldCkgewotICAgICAgICAgICAgICAgICAgICAgICAgYWRkVG9rZW4odG9rZW5zLCBYUGF0aC5Ub2tlbnMuRVhQUlRPS0VOX1BFUklPRCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzdGFySXNNdWx0aXBseU9wZXJhdG9yID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRPZmZzZXQrKzsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGNoID0gZGF0YS5jaGFyQXQoY3VycmVudE9mZnNldCArIDEpOwotICAgICAgICAgICAgICAgICAgICBpZiAoY2ggPT0gJy4nKSB7ICAgICAgICAgICAgLy8gJy4uJwotICAgICAgICAgICAgICAgICAgICAgICAgYWRkVG9rZW4odG9rZW5zLCBYUGF0aC5Ub2tlbnMuRVhQUlRPS0VOX0RPVUJMRV9QRVJJT0QpOwotICAgICAgICAgICAgICAgICAgICAgICAgc3RhcklzTXVsdGlwbHlPcGVyYXRvciA9IHRydWU7Ci0gICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50T2Zmc2V0ICs9IDI7Ci0gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoY2ggPj0gJzAnICYmIGNoIDw9ICc5JykgewotICAgICAgICAgICAgICAgICAgICAgICAgYWRkVG9rZW4odG9rZW5zLCBYUGF0aC5Ub2tlbnMuRVhQUlRPS0VOX05VTUJFUik7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzdGFySXNNdWx0aXBseU9wZXJhdG9yID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRPZmZzZXQgPSBzY2FuTnVtYmVyKHRva2VucywgZGF0YSwgZW5kT2Zmc2V0LCBjdXJyZW50T2Zmc2V0LyosIGVuY29kaW5nKi8pOwotICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNoID09ICcvJykgewotICAgICAgICAgICAgICAgICAgICAgICAgYWRkVG9rZW4odG9rZW5zLCBYUGF0aC5Ub2tlbnMuRVhQUlRPS0VOX1BFUklPRCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzdGFySXNNdWx0aXBseU9wZXJhdG9yID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRPZmZzZXQrKzsKLSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjaCA9PSAnfCcpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGFkZFRva2VuKHRva2VucywgWFBhdGguVG9rZW5zLkVYUFJUT0tFTl9QRVJJT0QpOwotICAgICAgICAgICAgICAgICAgICAgICAgc3RhcklzTXVsdGlwbHlPcGVyYXRvciA9IHRydWU7Ci0gICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50T2Zmc2V0Kys7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjaCA9PSAnICcgfHwgY2ggPT0gMHgwQSB8fCBjaCA9PSAweDA5IHx8IGNoID09IDB4MEQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoaXMgaXMgbGVnYWwgaWYgdGhlIG5leHQgdG9rZW4gaXMgbm9uLWV4aXN0ZW50IG9yIHwKLSAgICAgICAgICAgICAgICAgICAgICAgIGRvIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoKytjdXJyZW50T2Zmc2V0ID09IGVuZE9mZnNldCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2ggPSBkYXRhLmNoYXJBdChjdXJyZW50T2Zmc2V0KTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0gd2hpbGUgKGNoID09ICcgJyB8fCBjaCA9PSAweDBBIHx8IGNoID09IDB4MDkgfHwgY2ggPT0gMHgwRCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY3VycmVudE9mZnNldCA9PSBlbmRPZmZzZXQgfHwgY2ggPT0gJ3wnIHx8IGNoID09ICcvJykgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZFRva2VuKHRva2VucywgWFBhdGguVG9rZW5zLkVYUFJUT0tFTl9QRVJJT0QpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJJc011bHRpcGx5T3BlcmF0b3IgPSB0cnVlOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFhQYXRoRXhjZXB0aW9uICgiYy1nZW5lcmFsLXhwYXRoIik7Ci0gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7ICAgICAgICAgICAgICAgICAgICAvLyAnLicKLSAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBYUGF0aEV4Y2VwdGlvbiAoImMtZ2VuZXJhbC14cGF0aCIpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGlmIChjdXJyZW50T2Zmc2V0ID09IGVuZE9mZnNldCkgewotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgY2FzZSBDSEFSVFlQRV9BVFNJR046ICAgICAgICAgICAvLyAnQCcKLSAgICAgICAgICAgICAgICAgICAgYWRkVG9rZW4odG9rZW5zLCBYUGF0aC5Ub2tlbnMuRVhQUlRPS0VOX0FUU0lHTik7Ci0gICAgICAgICAgICAgICAgICAgIHN0YXJJc011bHRpcGx5T3BlcmF0b3IgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKCsrY3VycmVudE9mZnNldCA9PSBlbmRPZmZzZXQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGNhc2UgQ0hBUlRZUEVfQ09NTUE6ICAgICAgICAgICAgLy8gJywnCi0gICAgICAgICAgICAgICAgICAgIGFkZFRva2VuKHRva2VucywgWFBhdGguVG9rZW5zLkVYUFJUT0tFTl9DT01NQSk7Ci0gICAgICAgICAgICAgICAgICAgIHN0YXJJc011bHRpcGx5T3BlcmF0b3IgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKCsrY3VycmVudE9mZnNldCA9PSBlbmRPZmZzZXQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGNhc2UgQ0hBUlRZUEVfQ09MT046ICAgICAgICAgICAgLy8gJzo6JwotICAgICAgICAgICAgICAgICAgICBpZiAoKytjdXJyZW50T2Zmc2V0ID09IGVuZE9mZnNldCkgewotICAgICAgICAgICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiYWJvcnQgMWEiKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsgLy8gUkVWSVNJVAotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGNoID0gZGF0YS5jaGFyQXQoY3VycmVudE9mZnNldCk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChjaCAhPSAnOicpIHsKLSAgICAgICAgICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oImFib3J0IDFiIik7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7IC8vIFJFVklTSVQKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBhZGRUb2tlbih0b2tlbnMsIFhQYXRoLlRva2Vucy5FWFBSVE9LRU5fRE9VQkxFX0NPTE9OKTsKLSAgICAgICAgICAgICAgICAgICAgc3RhcklzTXVsdGlwbHlPcGVyYXRvciA9IGZhbHNlOwotICAgICAgICAgICAgICAgICAgICBpZiAoKytjdXJyZW50T2Zmc2V0ID09IGVuZE9mZnNldCkgewotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgY2FzZSBDSEFSVFlQRV9TTEFTSDogICAgICAgICAgICAvLyAnLycgYW5kICcvLycKLSAgICAgICAgICAgICAgICAgICAgaWYgKCsrY3VycmVudE9mZnNldCA9PSBlbmRPZmZzZXQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGFkZFRva2VuKHRva2VucywgWFBhdGguVG9rZW5zLkVYUFJUT0tFTl9PUEVSQVRPUl9TTEFTSCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzdGFySXNNdWx0aXBseU9wZXJhdG9yID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBjaCA9IGRhdGEuY2hhckF0KGN1cnJlbnRPZmZzZXQpOwotICAgICAgICAgICAgICAgICAgICBpZiAoY2ggPT0gJy8nKSB7IC8vICcvLycKLSAgICAgICAgICAgICAgICAgICAgICAgIGFkZFRva2VuKHRva2VucywgWFBhdGguVG9rZW5zLkVYUFJUT0tFTl9PUEVSQVRPUl9ET1VCTEVfU0xBU0gpOwotICAgICAgICAgICAgICAgICAgICAgICAgc3RhcklzTXVsdGlwbHlPcGVyYXRvciA9IGZhbHNlOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCsrY3VycmVudE9mZnNldCA9PSBlbmRPZmZzZXQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGFkZFRva2VuKHRva2VucywgWFBhdGguVG9rZW5zLkVYUFJUT0tFTl9PUEVSQVRPUl9TTEFTSCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzdGFySXNNdWx0aXBseU9wZXJhdG9yID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgY2FzZSBDSEFSVFlQRV9VTklPTjogICAgICAgICAgICAvLyAnfCcKLSAgICAgICAgICAgICAgICAgICAgYWRkVG9rZW4odG9rZW5zLCBYUGF0aC5Ub2tlbnMuRVhQUlRPS0VOX09QRVJBVE9SX1VOSU9OKTsKLSAgICAgICAgICAgICAgICAgICAgc3RhcklzTXVsdGlwbHlPcGVyYXRvciA9IGZhbHNlOwotICAgICAgICAgICAgICAgICAgICBpZiAoKytjdXJyZW50T2Zmc2V0ID09IGVuZE9mZnNldCkgewotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgY2FzZSBDSEFSVFlQRV9QTFVTOiAgICAgICAgICAgICAvLyAnKycKLSAgICAgICAgICAgICAgICAgICAgYWRkVG9rZW4odG9rZW5zLCBYUGF0aC5Ub2tlbnMuRVhQUlRPS0VOX09QRVJBVE9SX1BMVVMpOwotICAgICAgICAgICAgICAgICAgICBzdGFySXNNdWx0aXBseU9wZXJhdG9yID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgICAgIGlmICgrK2N1cnJlbnRPZmZzZXQgPT0gZW5kT2Zmc2V0KSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICBjYXNlIENIQVJUWVBFX01JTlVTOiAgICAgICAgICAgIC8vICctJwotICAgICAgICAgICAgICAgICAgICBhZGRUb2tlbih0b2tlbnMsIFhQYXRoLlRva2Vucy5FWFBSVE9LRU5fT1BFUkFUT1JfTUlOVVMpOwotICAgICAgICAgICAgICAgICAgICBzdGFySXNNdWx0aXBseU9wZXJhdG9yID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgICAgIGlmICgrK2N1cnJlbnRPZmZzZXQgPT0gZW5kT2Zmc2V0KSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICBjYXNlIENIQVJUWVBFX0VRVUFMOiAgICAgICAgICAgIC8vICc9JwotICAgICAgICAgICAgICAgICAgICBhZGRUb2tlbih0b2tlbnMsIFhQYXRoLlRva2Vucy5FWFBSVE9LRU5fT1BFUkFUT1JfRVFVQUwpOwotICAgICAgICAgICAgICAgICAgICBzdGFySXNNdWx0aXBseU9wZXJhdG9yID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgICAgIGlmICgrK2N1cnJlbnRPZmZzZXQgPT0gZW5kT2Zmc2V0KSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICBjYXNlIENIQVJUWVBFX0VYQ0xBTUFUSU9OOiAgICAgIC8vICchPScKLSAgICAgICAgICAgICAgICAgICAgaWYgKCsrY3VycmVudE9mZnNldCA9PSBlbmRPZmZzZXQpIHsKLSAgICAgICAgICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oImFib3J0IDJhIik7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7IC8vIFJFVklTSVQKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBjaCA9IGRhdGEuY2hhckF0KGN1cnJlbnRPZmZzZXQpOwotICAgICAgICAgICAgICAgICAgICBpZiAoY2ggIT0gJz0nKSB7Ci0gICAgICAgICAgICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJhYm9ydCAyYiIpOwotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOyAvLyBSRVZJU0lUCi0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgYWRkVG9rZW4odG9rZW5zLCBYUGF0aC5Ub2tlbnMuRVhQUlRPS0VOX09QRVJBVE9SX05PVF9FUVVBTCk7Ci0gICAgICAgICAgICAgICAgICAgIHN0YXJJc011bHRpcGx5T3BlcmF0b3IgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKCsrY3VycmVudE9mZnNldCA9PSBlbmRPZmZzZXQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGNhc2UgQ0hBUlRZUEVfTEVTUzogLy8gJzwnIGFuZCAnPD0nCi0gICAgICAgICAgICAgICAgICAgIGlmICgrK2N1cnJlbnRPZmZzZXQgPT0gZW5kT2Zmc2V0KSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBhZGRUb2tlbih0b2tlbnMsIFhQYXRoLlRva2Vucy5FWFBSVE9LRU5fT1BFUkFUT1JfTEVTUyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzdGFySXNNdWx0aXBseU9wZXJhdG9yID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBjaCA9IGRhdGEuY2hhckF0KGN1cnJlbnRPZmZzZXQpOwotICAgICAgICAgICAgICAgICAgICBpZiAoY2ggPT0gJz0nKSB7IC8vICc8PScKLSAgICAgICAgICAgICAgICAgICAgICAgIGFkZFRva2VuKHRva2VucywgWFBhdGguVG9rZW5zLkVYUFJUT0tFTl9PUEVSQVRPUl9MRVNTX0VRVUFMKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJJc011bHRpcGx5T3BlcmF0b3IgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmICgrK2N1cnJlbnRPZmZzZXQgPT0gZW5kT2Zmc2V0KSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBhZGRUb2tlbih0b2tlbnMsIFhQYXRoLlRva2Vucy5FWFBSVE9LRU5fT1BFUkFUT1JfTEVTUyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzdGFySXNNdWx0aXBseU9wZXJhdG9yID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgY2FzZSBDSEFSVFlQRV9HUkVBVEVSOiAvLyAnPicgYW5kICc+PScKLSAgICAgICAgICAgICAgICAgICAgaWYgKCsrY3VycmVudE9mZnNldCA9PSBlbmRPZmZzZXQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGFkZFRva2VuKHRva2VucywgWFBhdGguVG9rZW5zLkVYUFJUT0tFTl9PUEVSQVRPUl9HUkVBVEVSKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJJc011bHRpcGx5T3BlcmF0b3IgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGNoID0gZGF0YS5jaGFyQXQoY3VycmVudE9mZnNldCk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChjaCA9PSAnPScpIHsgLy8gJz49JwotICAgICAgICAgICAgICAgICAgICAgICAgYWRkVG9rZW4odG9rZW5zLCBYUGF0aC5Ub2tlbnMuRVhQUlRPS0VOX09QRVJBVE9SX0dSRUFURVJfRVFVQUwpOwotICAgICAgICAgICAgICAgICAgICAgICAgc3RhcklzTXVsdGlwbHlPcGVyYXRvciA9IGZhbHNlOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCsrY3VycmVudE9mZnNldCA9PSBlbmRPZmZzZXQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGFkZFRva2VuKHRva2VucywgWFBhdGguVG9rZW5zLkVYUFJUT0tFTl9PUEVSQVRPUl9HUkVBVEVSKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJJc011bHRpcGx5T3BlcmF0b3IgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgIC8vIFsyOV0gTGl0ZXJhbCA6Oj0gJyInIFteIl0qICciJyB8ICInIiBbXiddKiAiJyIKLSAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgIGNhc2UgQ0hBUlRZUEVfUVVPVEU6ICAgICAgICAgICAgLy8gJ1wiJyBvciAnXCcnCi0gICAgICAgICAgICAgICAgICAgIGludCBxY2hhciA9IGNoOwotICAgICAgICAgICAgICAgICAgICBpZiAoKytjdXJyZW50T2Zmc2V0ID09IGVuZE9mZnNldCkgewotICAgICAgICAgICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiYWJvcnQgMmMiKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsgLy8gUkVWSVNJVAotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGNoID0gZGF0YS5jaGFyQXQoY3VycmVudE9mZnNldCk7Ci0gICAgICAgICAgICAgICAgICAgIGludCBsaXRPZmZzZXQgPSBjdXJyZW50T2Zmc2V0OwotICAgICAgICAgICAgICAgICAgICB3aGlsZSAoY2ggIT0gcWNoYXIpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmICgrK2N1cnJlbnRPZmZzZXQgPT0gZW5kT2Zmc2V0KSB7Ci0gICAgICAgICAgICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJhYm9ydCAyZCIpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsgLy8gUkVWSVNJVAotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgY2ggPSBkYXRhLmNoYXJBdChjdXJyZW50T2Zmc2V0KTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBpbnQgbGl0TGVuZ3RoID0gY3VycmVudE9mZnNldCAtIGxpdE9mZnNldDsKLSAgICAgICAgICAgICAgICAgICAgYWRkVG9rZW4odG9rZW5zLCBYUGF0aC5Ub2tlbnMuRVhQUlRPS0VOX0xJVEVSQUwpOwotICAgICAgICAgICAgICAgICAgICBzdGFySXNNdWx0aXBseU9wZXJhdG9yID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgdG9rZW5zLmFkZFRva2VuKHN5bWJvbFRhYmxlLmFkZFN5bWJvbChkYXRhLnN1YnN0cmluZyhsaXRPZmZzZXQsIGxpdE9mZnNldCArIGxpdExlbmd0aCkpKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKCsrY3VycmVudE9mZnNldCA9PSBlbmRPZmZzZXQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAgICAgLy8gWzMwXSBOdW1iZXIgOjo9IERpZ2l0cyAoJy4nIERpZ2l0cz8pPyB8ICcuJyBEaWdpdHMKLSAgICAgICAgICAgICAgICAvLyBbMzFdIERpZ2l0cyA6Oj0gWzAtOV0rCi0gICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICBjYXNlIENIQVJUWVBFX0RJR0lUOgotICAgICAgICAgICAgICAgICAgICBhZGRUb2tlbih0b2tlbnMsIFhQYXRoLlRva2Vucy5FWFBSVE9LRU5fTlVNQkVSKTsKLSAgICAgICAgICAgICAgICAgICAgc3RhcklzTXVsdGlwbHlPcGVyYXRvciA9IHRydWU7Ci0gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRPZmZzZXQgPSBzY2FuTnVtYmVyKHRva2VucywgZGF0YSwgZW5kT2Zmc2V0LCBjdXJyZW50T2Zmc2V0LyosIGVuY29kaW5nKi8pOwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgIC8vIFszNl0gVmFyaWFibGVSZWZlcmVuY2UgOjo9ICckJyBRTmFtZQotICAgICAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAgICAgY2FzZSBDSEFSVFlQRV9ET0xMQVI6Ci0gICAgICAgICAgICAgICAgICAgIGlmICgrK2N1cnJlbnRPZmZzZXQgPT0gZW5kT2Zmc2V0KSB7Ci0gICAgICAgICAgICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJhYm9ydCAzYSIpOwotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOyAvLyBSRVZJU0lUCi0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgbmFtZU9mZnNldCA9IGN1cnJlbnRPZmZzZXQ7Ci0gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRPZmZzZXQgPSBzY2FuTkNOYW1lKGRhdGEsIGVuZE9mZnNldCwgY3VycmVudE9mZnNldCk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChjdXJyZW50T2Zmc2V0ID09IG5hbWVPZmZzZXQpIHsKLSAgICAgICAgICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oImFib3J0IDNiIik7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7IC8vIFJFVklTSVQKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBpZiAoY3VycmVudE9mZnNldCA8IGVuZE9mZnNldCkgewotICAgICAgICAgICAgICAgICAgICAgICAgY2ggPSBkYXRhLmNoYXJBdChjdXJyZW50T2Zmc2V0KTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGNoID0gLTE7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgbmFtZUhhbmRsZSA9IHN5bWJvbFRhYmxlLmFkZFN5bWJvbChkYXRhLnN1YnN0cmluZyhuYW1lT2Zmc2V0LCBjdXJyZW50T2Zmc2V0KSk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChjaCAhPSAnOicpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHByZWZpeEhhbmRsZSA9IFhNTFN5bWJvbHMuRU1QVFlfU1RSSU5HOwotICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgcHJlZml4SGFuZGxlID0gbmFtZUhhbmRsZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmICgrK2N1cnJlbnRPZmZzZXQgPT0gZW5kT2Zmc2V0KSB7Ci0gICAgICAgICAgICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJhYm9ydCA0YSIpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsgLy8gUkVWSVNJVAotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgbmFtZU9mZnNldCA9IGN1cnJlbnRPZmZzZXQ7Ci0gICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50T2Zmc2V0ID0gc2Nhbk5DTmFtZShkYXRhLCBlbmRPZmZzZXQsIGN1cnJlbnRPZmZzZXQpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGN1cnJlbnRPZmZzZXQgPT0gbmFtZU9mZnNldCkgewotICAgICAgICAgICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiYWJvcnQgNGIiKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7IC8vIFJFVklTSVQKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjdXJyZW50T2Zmc2V0IDwgZW5kT2Zmc2V0KSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2ggPSBkYXRhLmNoYXJBdChjdXJyZW50T2Zmc2V0KTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoID0gLTE7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBuYW1lSGFuZGxlID0gc3ltYm9sVGFibGUuYWRkU3ltYm9sKGRhdGEuc3Vic3RyaW5nKG5hbWVPZmZzZXQsIGN1cnJlbnRPZmZzZXQpKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBhZGRUb2tlbih0b2tlbnMsIFhQYXRoLlRva2Vucy5FWFBSVE9LRU5fVkFSSUFCTEVfUkVGRVJFTkNFKTsKLSAgICAgICAgICAgICAgICAgICAgc3RhcklzTXVsdGlwbHlPcGVyYXRvciA9IHRydWU7Ci0gICAgICAgICAgICAgICAgICAgIHRva2Vucy5hZGRUb2tlbihwcmVmaXhIYW5kbGUpOwotICAgICAgICAgICAgICAgICAgICB0b2tlbnMuYWRkVG9rZW4obmFtZUhhbmRsZSk7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAgICAgLy8gWzM3XSBOYW1lVGVzdCA6Oj0gJyonIHwgTkNOYW1lICc6JyAnKicgfCBRTmFtZQotICAgICAgICAgICAgICAgIC8vIFszNF0gTXVsdGlwbHlPcGVyYXRvciA6Oj0gJyonCi0gICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICBjYXNlIENIQVJUWVBFX1NUQVI6ICAgICAgICAgICAgIC8vICcqJwotICAgICAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgICAgICAvLyAzLjcgTGV4aWNhbCBTdHJ1Y3R1cmUKLSAgICAgICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICAgICAgLy8gIElmIHRoZXJlIGlzIGEgcHJlY2VkaW5nIHRva2VuIGFuZCB0aGUgcHJlY2VkaW5nIHRva2VuIGlzIG5vdCBvbmUgb2YgQCwgOjosICgsIFssICwgb3IKLSAgICAgICAgICAgICAgICAgICAgLy8gIGFuIE9wZXJhdG9yLCB0aGVuIGEgKiBtdXN0IGJlIHJlY29nbml6ZWQgYXMgYSBNdWx0aXBseU9wZXJhdG9yLgotICAgICAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgICAgICAvLyBPdGhlcndpc2UsIHRoZSB0b2tlbiBtdXN0IG5vdCBiZSByZWNvZ25pemVkIGFzIGEgTXVsdGlwbHlPcGVyYXRvci4KLSAgICAgICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICAgICAgaWYgKHN0YXJJc011bHRpcGx5T3BlcmF0b3IpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGFkZFRva2VuKHRva2VucywgWFBhdGguVG9rZW5zLkVYUFJUT0tFTl9PUEVSQVRPUl9NVUxUKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJJc011bHRpcGx5T3BlcmF0b3IgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGFkZFRva2VuKHRva2VucywgWFBhdGguVG9rZW5zLkVYUFJUT0tFTl9OQU1FVEVTVF9BTlkpOwotICAgICAgICAgICAgICAgICAgICAgICAgc3RhcklzTXVsdGlwbHlPcGVyYXRvciA9IHRydWU7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgaWYgKCsrY3VycmVudE9mZnNldCA9PSBlbmRPZmZzZXQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAgICAgLy8gTkNOYW1lLCBRTmFtZSBhbmQgbm9uLXRlcm1pbmFscwotICAgICAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAgICAgY2FzZSBDSEFSVFlQRV9OT05BU0NJSTogLy8gcG9zc2libHkgYSB2YWxpZCBub24tYXNjaWkgJ0xldHRlcicgKEJhc2VDaGFyIHwgSWRlb2dyYXBoaWMpCi0gICAgICAgICAgICAgICAgY2FzZSBDSEFSVFlQRV9MRVRURVI6Ci0gICAgICAgICAgICAgICAgY2FzZSBDSEFSVFlQRV9VTkRFUlNDT1JFOgotICAgICAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgICAgICAvLyAzLjcgTGV4aWNhbCBTdHJ1Y3R1cmUKLSAgICAgICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICAgICAgLy8gIElmIHRoZXJlIGlzIGEgcHJlY2VkaW5nIHRva2VuIGFuZCB0aGUgcHJlY2VkaW5nIHRva2VuIGlzIG5vdCBvbmUgb2YgQCwgOjosICgsIFssICwgb3IKLSAgICAgICAgICAgICAgICAgICAgLy8gIGFuIE9wZXJhdG9yLCB0aGVuIGFuIE5DTmFtZSBtdXN0IGJlIHJlY29nbml6ZWQgYXMgYW4gT3BlcmF0b3JOYW1lLgotICAgICAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgICAgICAvLyAgSWYgdGhlIGNoYXJhY3RlciBmb2xsb3dpbmcgYW4gTkNOYW1lIChwb3NzaWJseSBhZnRlciBpbnRlcnZlbmluZyBFeHByV2hpdGVzcGFjZSkgaXMgKCwKLSAgICAgICAgICAgICAgICAgICAgLy8gIHRoZW4gdGhlIHRva2VuIG11c3QgYmUgcmVjb2duaXplZCBhcyBhIE5vZGVUeXBlIG9yIGEgRnVuY3Rpb25OYW1lLgotICAgICAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgICAgICAvLyAgSWYgdGhlIHR3byBjaGFyYWN0ZXJzIGZvbGxvd2luZyBhbiBOQ05hbWUgKHBvc3NpYmx5IGFmdGVyIGludGVydmVuaW5nIEV4cHJXaGl0ZXNwYWNlKQotICAgICAgICAgICAgICAgICAgICAvLyAgYXJlIDo6LCB0aGVuIHRoZSB0b2tlbiBtdXN0IGJlIHJlY29nbml6ZWQgYXMgYW4gQXhpc05hbWUuCi0gICAgICAgICAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAgICAgICAgIC8vICBPdGhlcndpc2UsIHRoZSB0b2tlbiBtdXN0IG5vdCBiZSByZWNvZ25pemVkIGFzIGFuIE9wZXJhdG9yTmFtZSwgYSBOb2RlVHlwZSwgYQotICAgICAgICAgICAgICAgICAgICAvLyAgRnVuY3Rpb25OYW1lLCBvciBhbiBBeGlzTmFtZS4KLSAgICAgICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICAgICAgLy8gWzMzXSBPcGVyYXRvck5hbWUgOjo9ICdhbmQnIHwgJ29yJyB8ICdtb2QnIHwgJ2RpdicKLSAgICAgICAgICAgICAgICAgICAgLy8gWzM4XSBOb2RlVHlwZSA6Oj0gJ2NvbW1lbnQnIHwgJ3RleHQnIHwgJ3Byb2Nlc3NpbmctaW5zdHJ1Y3Rpb24nIHwgJ25vZGUnCi0gICAgICAgICAgICAgICAgICAgIC8vIFszNV0gRnVuY3Rpb25OYW1lIDo6PSBRTmFtZSAtIE5vZGVUeXBlCi0gICAgICAgICAgICAgICAgICAgIC8vIFs2XSBBeGlzTmFtZSA6Oj0gKHNlZSBhYm92ZSkKLSAgICAgICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICAgICAgLy8gWzM3XSBOYW1lVGVzdCA6Oj0gJyonIHwgTkNOYW1lICc6JyAnKicgfCBRTmFtZQotICAgICAgICAgICAgICAgICAgICAvLyBbNV0gTkNOYW1lIDo6PSAoTGV0dGVyIHwgJ18nKSAoTkNOYW1lQ2hhcikqCi0gICAgICAgICAgICAgICAgICAgIC8vIFs/XSBOQ05hbWVDaGFyIDo6PSBMZXR0ZXIgfCBEaWdpdCB8ICcuJyB8ICctJyB8ICdfJyAgKGFzY2lpIHN1YnNldCBvZiAnTkNOYW1lQ2hhcicpCi0gICAgICAgICAgICAgICAgICAgIC8vIFs/XSBRTmFtZSA6Oj0gKE5DTmFtZSAnOicpPyBOQ05hbWUKLSAgICAgICAgICAgICAgICAgICAgLy8gWz9dIExldHRlciA6Oj0gW0EtWmEtel0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYXNjaWkgc3Vic2V0IG9mICdMZXR0ZXInKQotICAgICAgICAgICAgICAgICAgICAvLyBbP10gRGlnaXQgOjo9IFswLTldICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChhc2NpaSBzdWJzZXQgb2YgJ0RpZ2l0JykKLSAgICAgICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICAgICAgbmFtZU9mZnNldCA9IGN1cnJlbnRPZmZzZXQ7Ci0gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRPZmZzZXQgPSBzY2FuTkNOYW1lKGRhdGEsIGVuZE9mZnNldCwgY3VycmVudE9mZnNldCk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChjdXJyZW50T2Zmc2V0ID09IG5hbWVPZmZzZXQpIHsKLSAgICAgICAgICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oImFib3J0IDRjIik7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7IC8vIFJFVklTSVQKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBpZiAoY3VycmVudE9mZnNldCA8IGVuZE9mZnNldCkgewotICAgICAgICAgICAgICAgICAgICAgICAgY2ggPSBkYXRhLmNoYXJBdChjdXJyZW50T2Zmc2V0KTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGNoID0gLTE7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgbmFtZUhhbmRsZSA9IHN5bWJvbFRhYmxlLmFkZFN5bWJvbChkYXRhLnN1YnN0cmluZyhuYW1lT2Zmc2V0LCBjdXJyZW50T2Zmc2V0KSk7Ci0gICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gaXNOYW1lVGVzdE5DTmFtZSA9IGZhbHNlOwotICAgICAgICAgICAgICAgICAgICBib29sZWFuIGlzQXhpc05hbWUgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICAgICAgcHJlZml4SGFuZGxlID0gWE1MU3ltYm9scy5FTVBUWV9TVFJJTkc7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChjaCA9PSAnOicpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmICgrK2N1cnJlbnRPZmZzZXQgPT0gZW5kT2Zmc2V0KSB7Ci0gICAgICAgICAgICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJhYm9ydCA1Iik7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOyAvLyBSRVZJU0lUCi0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBjaCA9IGRhdGEuY2hhckF0KGN1cnJlbnRPZmZzZXQpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNoID09ICcqJykgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgrK2N1cnJlbnRPZmZzZXQgPCBlbmRPZmZzZXQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2ggPSBkYXRhLmNoYXJBdChjdXJyZW50T2Zmc2V0KTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNOYW1lVGVzdE5DTmFtZSA9IHRydWU7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNoID09ICc6JykgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgrK2N1cnJlbnRPZmZzZXQgPCBlbmRPZmZzZXQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2ggPSBkYXRhLmNoYXJBdChjdXJyZW50T2Zmc2V0KTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNBeGlzTmFtZSA9IHRydWU7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZWZpeEhhbmRsZSA9IG5hbWVIYW5kbGU7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZU9mZnNldCA9IGN1cnJlbnRPZmZzZXQ7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudE9mZnNldCA9IHNjYW5OQ05hbWUoZGF0YSwgZW5kT2Zmc2V0LCBjdXJyZW50T2Zmc2V0KTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY3VycmVudE9mZnNldCA9PSBuYW1lT2Zmc2V0KSB7Ci0gICAgICAgICAgICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJhYm9ydCA1YiIpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7IC8vIFJFVklTSVQKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGN1cnJlbnRPZmZzZXQgPCBlbmRPZmZzZXQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2ggPSBkYXRhLmNoYXJBdChjdXJyZW50T2Zmc2V0KTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoID0gLTE7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVIYW5kbGUgPSBzeW1ib2xUYWJsZS5hZGRTeW1ib2woZGF0YS5zdWJzdHJpbmcobmFtZU9mZnNldCwgY3VycmVudE9mZnNldCkpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAgICAgICAgIC8vIFszOV0gRXhwcldoaXRlc3BhY2UgOjo9IFMKLSAgICAgICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGNoID09ICcgJyB8fCBjaCA9PSAweDBBIHx8IGNoID09IDB4MDkgfHwgY2ggPT0gMHgwRCkgewotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCsrY3VycmVudE9mZnNldCA9PSBlbmRPZmZzZXQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGNoID0gZGF0YS5jaGFyQXQoY3VycmVudE9mZnNldCk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICAgICAgLy8gIElmIHRoZXJlIGlzIGEgcHJlY2VkaW5nIHRva2VuIGFuZCB0aGUgcHJlY2VkaW5nIHRva2VuIGlzIG5vdCBvbmUgb2YgQCwgOjosICgsIFssICwgb3IKLSAgICAgICAgICAgICAgICAgICAgLy8gIGFuIE9wZXJhdG9yLCB0aGVuIGFuIE5DTmFtZSBtdXN0IGJlIHJlY29nbml6ZWQgYXMgYW4gT3BlcmF0b3JOYW1lLgotICAgICAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgICAgICBpZiAoc3RhcklzTXVsdGlwbHlPcGVyYXRvcikgewotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5hbWVIYW5kbGUgPT0gZkFuZFN5bWJvbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZFRva2VuKHRva2VucywgWFBhdGguVG9rZW5zLkVYUFJUT0tFTl9PUEVSQVRPUl9BTkQpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJJc011bHRpcGx5T3BlcmF0b3IgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAobmFtZUhhbmRsZSA9PSBmT3JTeW1ib2wpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRUb2tlbih0b2tlbnMsIFhQYXRoLlRva2Vucy5FWFBSVE9LRU5fT1BFUkFUT1JfT1IpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJJc011bHRpcGx5T3BlcmF0b3IgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAobmFtZUhhbmRsZSA9PSBmTW9kU3ltYm9sKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkVG9rZW4odG9rZW5zLCBYUGF0aC5Ub2tlbnMuRVhQUlRPS0VOX09QRVJBVE9SX01PRCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhcklzTXVsdGlwbHlPcGVyYXRvciA9IGZhbHNlOwotICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChuYW1lSGFuZGxlID09IGZEaXZTeW1ib2wpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRUb2tlbih0b2tlbnMsIFhQYXRoLlRva2Vucy5FWFBSVE9LRU5fT1BFUkFUT1JfRElWKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGFySXNNdWx0aXBseU9wZXJhdG9yID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiYWJvcnQgNiIpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsgLy8gUkVWSVNJVAotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzTmFtZVRlc3ROQ05hbWUpIHsKLSAgICAgICAgICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oImFib3J0IDciKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7IC8vIFJFVklTSVQgLSBOQ05hbWU6KiB3aGVyZSBhbiBPcGVyYXRvck5hbWUgaXMgcmVxdWlyZWQKLSAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNBeGlzTmFtZSkgewotICAgICAgICAgICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiYWJvcnQgOCIpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsgLy8gUkVWSVNJVCAtIEF4aXNOYW1lOjogd2hlcmUgYW4gT3BlcmF0b3JOYW1lIGlzIHJlcXVpcmVkCi0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgICAgICAvLyAgSWYgdGhlIGNoYXJhY3RlciBmb2xsb3dpbmcgYW4gTkNOYW1lIChwb3NzaWJseSBhZnRlciBpbnRlcnZlbmluZyBFeHByV2hpdGVzcGFjZSkgaXMgKCwKLSAgICAgICAgICAgICAgICAgICAgLy8gIHRoZW4gdGhlIHRva2VuIG11c3QgYmUgcmVjb2duaXplZCBhcyBhIE5vZGVUeXBlIG9yIGEgRnVuY3Rpb25OYW1lLgotICAgICAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgICAgICBpZiAoY2ggPT0gJygnICYmICFpc05hbWVUZXN0TkNOYW1lICYmICFpc0F4aXNOYW1lKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAobmFtZUhhbmRsZSA9PSBmQ29tbWVudFN5bWJvbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZFRva2VuKHRva2VucywgWFBhdGguVG9rZW5zLkVYUFJUT0tFTl9OT0RFVFlQRV9DT01NRU5UKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAobmFtZUhhbmRsZSA9PSBmVGV4dFN5bWJvbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZFRva2VuKHRva2VucywgWFBhdGguVG9rZW5zLkVYUFJUT0tFTl9OT0RFVFlQRV9URVhUKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAobmFtZUhhbmRsZSA9PSBmUElTeW1ib2wpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRUb2tlbih0b2tlbnMsIFhQYXRoLlRva2Vucy5FWFBSVE9LRU5fTk9ERVRZUEVfUEkpOwotICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChuYW1lSGFuZGxlID09IGZOb2RlU3ltYm9sKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkVG9rZW4odG9rZW5zLCBYUGF0aC5Ub2tlbnMuRVhQUlRPS0VOX05PREVUWVBFX05PREUpOwotICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRUb2tlbih0b2tlbnMsIFhQYXRoLlRva2Vucy5FWFBSVE9LRU5fRlVOQ1RJT05fTkFNRSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgdG9rZW5zLmFkZFRva2VuKHByZWZpeEhhbmRsZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgdG9rZW5zLmFkZFRva2VuKG5hbWVIYW5kbGUpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgYWRkVG9rZW4odG9rZW5zLCBYUGF0aC5Ub2tlbnMuRVhQUlRPS0VOX09QRU5fUEFSRU4pOwotICAgICAgICAgICAgICAgICAgICAgICAgc3RhcklzTXVsdGlwbHlPcGVyYXRvciA9IGZhbHNlOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCsrY3VycmVudE9mZnNldCA9PSBlbmRPZmZzZXQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAgICAgICAgIC8vICBJZiB0aGUgdHdvIGNoYXJhY3RlcnMgZm9sbG93aW5nIGFuIE5DTmFtZSAocG9zc2libHkgYWZ0ZXIgaW50ZXJ2ZW5pbmcgRXhwcldoaXRlc3BhY2UpCi0gICAgICAgICAgICAgICAgICAgIC8vICBhcmUgOjosIHRoZW4gdGhlIHRva2VuIG11c3QgYmUgcmVjb2duaXplZCBhcyBhbiBBeGlzTmFtZS4KLSAgICAgICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICAgICAgaWYgKGlzQXhpc05hbWUgfHwKLSAgICAgICAgICAgICAgICAgICAgICAgIChjaCA9PSAnOicgJiYgY3VycmVudE9mZnNldCArIDEgPCBlbmRPZmZzZXQgJiYKLSAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhLmNoYXJBdChjdXJyZW50T2Zmc2V0ICsgMSkgPT0gJzonKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5hbWVIYW5kbGUgPT0gZkFuY2VzdG9yU3ltYm9sKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkVG9rZW4odG9rZW5zLCBYUGF0aC5Ub2tlbnMuRVhQUlRPS0VOX0FYSVNOQU1FX0FOQ0VTVE9SKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAobmFtZUhhbmRsZSA9PSBmQW5jZXN0b3JPclNlbGZTeW1ib2wpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRUb2tlbih0b2tlbnMsIFhQYXRoLlRva2Vucy5FWFBSVE9LRU5fQVhJU05BTUVfQU5DRVNUT1JfT1JfU0VMRik7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG5hbWVIYW5kbGUgPT0gZkF0dHJpYnV0ZVN5bWJvbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZFRva2VuKHRva2VucywgWFBhdGguVG9rZW5zLkVYUFJUT0tFTl9BWElTTkFNRV9BVFRSSUJVVEUpOwotICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChuYW1lSGFuZGxlID09IGZDaGlsZFN5bWJvbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZFRva2VuKHRva2VucywgWFBhdGguVG9rZW5zLkVYUFJUT0tFTl9BWElTTkFNRV9DSElMRCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG5hbWVIYW5kbGUgPT0gZkRlc2NlbmRhbnRTeW1ib2wpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRUb2tlbih0b2tlbnMsIFhQYXRoLlRva2Vucy5FWFBSVE9LRU5fQVhJU05BTUVfREVTQ0VOREFOVCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG5hbWVIYW5kbGUgPT0gZkRlc2NlbmRhbnRPclNlbGZTeW1ib2wpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRUb2tlbih0b2tlbnMsIFhQYXRoLlRva2Vucy5FWFBSVE9LRU5fQVhJU05BTUVfREVTQ0VOREFOVF9PUl9TRUxGKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAobmFtZUhhbmRsZSA9PSBmRm9sbG93aW5nU3ltYm9sKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkVG9rZW4odG9rZW5zLCBYUGF0aC5Ub2tlbnMuRVhQUlRPS0VOX0FYSVNOQU1FX0ZPTExPV0lORyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG5hbWVIYW5kbGUgPT0gZkZvbGxvd2luZ1NpYmxpbmdTeW1ib2wpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRUb2tlbih0b2tlbnMsIFhQYXRoLlRva2Vucy5FWFBSVE9LRU5fQVhJU05BTUVfRk9MTE9XSU5HX1NJQkxJTkcpOwotICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChuYW1lSGFuZGxlID09IGZOYW1lc3BhY2VTeW1ib2wpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRUb2tlbih0b2tlbnMsIFhQYXRoLlRva2Vucy5FWFBSVE9LRU5fQVhJU05BTUVfTkFNRVNQQUNFKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAobmFtZUhhbmRsZSA9PSBmUGFyZW50U3ltYm9sKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkVG9rZW4odG9rZW5zLCBYUGF0aC5Ub2tlbnMuRVhQUlRPS0VOX0FYSVNOQU1FX1BBUkVOVCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG5hbWVIYW5kbGUgPT0gZlByZWNlZGluZ1N5bWJvbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZFRva2VuKHRva2VucywgWFBhdGguVG9rZW5zLkVYUFJUT0tFTl9BWElTTkFNRV9QUkVDRURJTkcpOwotICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChuYW1lSGFuZGxlID09IGZQcmVjZWRpbmdTaWJsaW5nU3ltYm9sKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkVG9rZW4odG9rZW5zLCBYUGF0aC5Ub2tlbnMuRVhQUlRPS0VOX0FYSVNOQU1FX1BSRUNFRElOR19TSUJMSU5HKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAobmFtZUhhbmRsZSA9PSBmU2VsZlN5bWJvbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZFRva2VuKHRva2VucywgWFBhdGguVG9rZW5zLkVYUFJUT0tFTl9BWElTTkFNRV9TRUxGKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJhYm9ydCA5Iik7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOyAvLyBSRVZJU0lUCi0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNOYW1lVGVzdE5DTmFtZSkgewotICAgICAgICAgICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiYWJvcnQgMTAiKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7IC8vIFJFVklTSVQgLSAiTkNOYW1lOiogOjoiIHdoZXJlICJBeGlzTmFtZSA6OiIgaXMgcmVxdWlyZWQKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGFkZFRva2VuKHRva2VucywgWFBhdGguVG9rZW5zLkVYUFJUT0tFTl9ET1VCTEVfQ09MT04pOwotICAgICAgICAgICAgICAgICAgICAgICAgc3RhcklzTXVsdGlwbHlPcGVyYXRvciA9IGZhbHNlOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFpc0F4aXNOYW1lKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudE9mZnNldCsrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgrK2N1cnJlbnRPZmZzZXQgPT0gZW5kT2Zmc2V0KSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAgICAgICAgIC8vICBPdGhlcndpc2UsIHRoZSB0b2tlbiBtdXN0IG5vdCBiZSByZWNvZ25pemVkIGFzIGFuIE9wZXJhdG9yTmFtZSwgYSBOb2RlVHlwZSwgYQotICAgICAgICAgICAgICAgICAgICAvLyAgRnVuY3Rpb25OYW1lLCBvciBhbiBBeGlzTmFtZS4KLSAgICAgICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICAgICAgaWYgKGlzTmFtZVRlc3ROQ05hbWUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGFkZFRva2VuKHRva2VucywgWFBhdGguVG9rZW5zLkVYUFJUT0tFTl9OQU1FVEVTVF9OQU1FU1BBQ0UpOwotICAgICAgICAgICAgICAgICAgICAgICAgc3RhcklzTXVsdGlwbHlPcGVyYXRvciA9IHRydWU7Ci0gICAgICAgICAgICAgICAgICAgICAgICB0b2tlbnMuYWRkVG9rZW4obmFtZUhhbmRsZSk7Ci0gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBhZGRUb2tlbih0b2tlbnMsIFhQYXRoLlRva2Vucy5FWFBSVE9LRU5fTkFNRVRFU1RfUU5BTUUpOwotICAgICAgICAgICAgICAgICAgICAgICAgc3RhcklzTXVsdGlwbHlPcGVyYXRvciA9IHRydWU7Ci0gICAgICAgICAgICAgICAgICAgICAgICB0b2tlbnMuYWRkVG9rZW4ocHJlZml4SGFuZGxlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHRva2Vucy5hZGRUb2tlbihuYW1lSGFuZGxlKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoWFBhdGguVG9rZW5zLkRVTVBfVE9LRU5TKSB7Ci0gICAgICAgICAgICAgICAgdG9rZW5zLmR1bXBUb2tlbnMoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0gICAgICAgIC8vCi0gICAgICAgIC8vIFs1XSBOQ05hbWUgOjo9IChMZXR0ZXIgfCAnXycpIChOQ05hbWVDaGFyKSoKLSAgICAgICAgLy8gWzZdIE5DTmFtZUNoYXIgOjo9IExldHRlciB8IERpZ2l0IHwgJy4nIHwgJy0nIHwgJ18nIHwgQ29tYmluaW5nQ2hhciB8IEV4dGVuZGVyCi0gICAgICAgIC8vCi0gICAgICAgIGludCBzY2FuTkNOYW1lKFN0cmluZyBkYXRhLCBpbnQgZW5kT2Zmc2V0LCBpbnQgY3VycmVudE9mZnNldCkgewotICAgICAgICAgICAgaW50IGNoID0gZGF0YS5jaGFyQXQoY3VycmVudE9mZnNldCk7Ci0gICAgICAgICAgICBpZiAoY2ggPj0gMHg4MCkgewotICAgICAgICAgICAgICAgIGlmICghWE1MQ2hhci5pc05hbWVTdGFydChjaCkpCi0gICAgICAgICAgICAgICAgLyoqKiAvLyBSRVZJU0lUOiBNYWtlIHN1cmUgdGhpcyBpcyBhIG5lZ2F0aW9uLiAqKioKLSAgICAgICAgICAgICAgICBpZiAoKFhNTENoYXJhY3RlclByb3BlcnRpZXMuZmdDaGFyRmxhZ3NbY2hdICYKLSAgICAgICAgICAgICAgICAgICAgIFhNTENoYXJhY3RlclByb3BlcnRpZXMuRV9Jbml0aWFsTmFtZUNoYXJGbGFnKSA9PSAwKQotICAgICAgICAgICAgICAgIC8qKiovCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gY3VycmVudE9mZnNldDsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBieXRlIGNoYXJ0eXBlID0gZkFTQ0lJQ2hhck1hcFtjaF07Ci0gICAgICAgICAgICAgICAgaWYgKGNoYXJ0eXBlICE9IENIQVJUWVBFX0xFVFRFUiAmJiBjaGFydHlwZSAhPSBDSEFSVFlQRV9VTkRFUlNDT1JFKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBjdXJyZW50T2Zmc2V0OwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHdoaWxlICgrK2N1cnJlbnRPZmZzZXQgPCBlbmRPZmZzZXQpIHsKLSAgICAgICAgICAgICAgICBjaCA9IGRhdGEuY2hhckF0KGN1cnJlbnRPZmZzZXQpOwotICAgICAgICAgICAgICAgIGlmIChjaCA+PSAweDgwKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmICghWE1MQ2hhci5pc05hbWUoY2gpKQotICAgICAgICAgICAgICAgICAgICAvKioqIC8vIFJFVklTSVQ6IE1ha2Ugc3VyZSB0aGlzIGlzIGEgbmVnYXRpb24uICoqKgotICAgICAgICAgICAgICAgICAgICBpZiAoKFhNTENoYXJhY3RlclByb3BlcnRpZXMuZmdDaGFyRmxhZ3NbY2hdICYKLSAgICAgICAgICAgICAgICAgICAgICAgICBYTUxDaGFyYWN0ZXJQcm9wZXJ0aWVzLkVfTmFtZUNoYXJGbGFnKSA9PSAwKQotICAgICAgICAgICAgICAgICAgICAvKioqLwotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgYnl0ZSBjaGFydHlwZSA9IGZBU0NJSUNoYXJNYXBbY2hdOwotICAgICAgICAgICAgICAgICAgICBpZiAoY2hhcnR5cGUgIT0gQ0hBUlRZUEVfTEVUVEVSICYmIGNoYXJ0eXBlICE9IENIQVJUWVBFX0RJR0lUICYmCi0gICAgICAgICAgICAgICAgICAgICAgICBjaGFydHlwZSAhPSBDSEFSVFlQRV9QRVJJT0QgJiYgY2hhcnR5cGUgIT0gQ0hBUlRZUEVfTUlOVVMgJiYKLSAgICAgICAgICAgICAgICAgICAgICAgIGNoYXJ0eXBlICE9IENIQVJUWVBFX1VOREVSU0NPUkUpCi0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnRPZmZzZXQ7Ci0gICAgICAgIH0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gWzMwXSBOdW1iZXIgOjo9IERpZ2l0cyAoJy4nIERpZ2l0cz8pPyB8ICcuJyBEaWdpdHMKLSAgICAgICAgLy8gWzMxXSBEaWdpdHMgOjo9IFswLTldKwotICAgICAgICAvLwotICAgICAgICBwcml2YXRlIGludCBzY2FuTnVtYmVyKFhQYXRoLlRva2VucyB0b2tlbnMsIFN0cmluZy8qYnl0ZVtdKi8gZGF0YSwgaW50IGVuZE9mZnNldCwgaW50IGN1cnJlbnRPZmZzZXQvKiwgRW5jb2RpbmdTdXBwb3J0IGVuY29kaW5nKi8pIHsKLSAgICAgICAgICAgIGludCBjaCA9IGRhdGEuY2hhckF0KGN1cnJlbnRPZmZzZXQpOwotICAgICAgICAgICAgaW50IHdob2xlID0gMDsKLSAgICAgICAgICAgIGludCBwYXJ0ID0gMDsKLSAgICAgICAgICAgIHdoaWxlIChjaCA+PSAnMCcgJiYgY2ggPD0gJzknKSB7Ci0gICAgICAgICAgICAgICAgd2hvbGUgPSAod2hvbGUgKiAxMCkgKyAoY2ggLSAnMCcpOwotICAgICAgICAgICAgICAgIGlmICgrK2N1cnJlbnRPZmZzZXQgPT0gZW5kT2Zmc2V0KSB7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBjaCA9IGRhdGEuY2hhckF0KGN1cnJlbnRPZmZzZXQpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKGNoID09ICcuJykgewotICAgICAgICAgICAgICAgIGlmICgrK2N1cnJlbnRPZmZzZXQgPCBlbmRPZmZzZXQpIHsKLSAgICAgICAgICAgICAgICAgICAgLyoqIGludCBzdGFydCA9IGN1cnJlbnRPZmZzZXQ7ICoqLwotICAgICAgICAgICAgICAgICAgICBjaCA9IGRhdGEuY2hhckF0KGN1cnJlbnRPZmZzZXQpOwotICAgICAgICAgICAgICAgICAgICB3aGlsZSAoY2ggPj0gJzAnICYmIGNoIDw9ICc5JykgewotICAgICAgICAgICAgICAgICAgICAgICAgcGFydCA9IChwYXJ0ICogMTApICsgKGNoIC0gJzAnKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmICgrK2N1cnJlbnRPZmZzZXQgPT0gZW5kT2Zmc2V0KSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBjaCA9IGRhdGEuY2hhckF0KGN1cnJlbnRPZmZzZXQpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGlmIChwYXJ0ICE9IDApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8qKioKLSAgICAgICAgICAgICAgICAgICAgICAgIHBhcnQgPSB0b2tlbnMuYWRkU3ltYm9sKGRhdGEsIHN0YXJ0LCBjdXJyZW50T2Zmc2V0IC0gc3RhcnQsIGVuY29kaW5nKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8qKiovCi0gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiZmluZCBhIHNvbHV0aW9uISIpOwotICAgICAgICAgICAgICAgICAgICAgICAgLy9wYXJ0ID0gZlN0cmluZ1Bvb2wuYWRkU3ltYm9sKGRhdGEuc3Vic3RyaW5nKHN0YXJ0LCBjdXJyZW50T2Zmc2V0KSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvKioqLwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgdG9rZW5zLmFkZFRva2VuKHdob2xlKTsKLSAgICAgICAgICAgIHRva2Vucy5hZGRUb2tlbihwYXJ0KTsKLSAgICAgICAgICAgIHJldHVybiBjdXJyZW50T2Zmc2V0OwotICAgICAgICB9Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gUHJvdGVjdGVkIG1ldGhvZHMKLSAgICAgICAgLy8KLQotICAgICAgICAvKioKLSAgICAgICAgICogVGhpcyBtZXRob2QgYWRkcyB0aGUgc3BlY2lmaWVkIHRva2VuIHRvIHRoZSB0b2tlbiBsaXN0LiBCeQotICAgICAgICAgKiBkZWZhdWx0LCB0aGlzIG1ldGhvZCBhbGxvd3MgYWxsIHRva2Vucy4gSG93ZXZlciwgc3ViY2xhc3NlcwotICAgICAgICAgKiBvZiB0aGUgWFBhdGhFeHByU2Nhbm5lciBjYW4gb3ZlcnJpZGUgdGhpcyBtZXRob2QgaW4gb3JkZXIKLSAgICAgICAgICogdG8gZGlzYWxsb3cgY2VydGFpbiB0b2tlbnMgZnJvbSBiZWluZyB1c2VkIGluIHRoZSBzY2FubmVkCi0gICAgICAgICAqIFhQYXRoIGV4cHJlc3Npb24uIFRoaXMgaXMgYSBjb252ZW5pZW50IHdheSBvZiBhbGxvd2luZyBvbmx5Ci0gICAgICAgICAqIGEgc3Vic2V0IG9mIFhQYXRoLgotICAgICAgICAgKi8KLSAgICAgICAgcHJvdGVjdGVkIHZvaWQgYWRkVG9rZW4oWFBhdGguVG9rZW5zIHRva2VucywgaW50IHRva2VuKQotICAgICAgICAgICAgdGhyb3dzIFhQYXRoRXhjZXB0aW9uIHsKLSAgICAgICAgICAgIHRva2Vucy5hZGRUb2tlbih0b2tlbik7Ci0gICAgICAgIH0gLy8gYWRkVG9rZW4oaW50KQotCi0gICAgfSAvLyBjbGFzcyBTY2FubmVyCi0KLSAgICAvLwotICAgIC8vIE1BSU4KLSAgICAvLwotCi0gICAgLyoqIE1haW4gcHJvZ3JhbSBlbnRyeS4gKi8KLSAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmd2KSB0aHJvd3MgRXhjZXB0aW9uIHsKLQotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGFyZ3YubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgIGZpbmFsIFN0cmluZyBleHByZXNzaW9uID0gYXJndltpXTsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiIyBYUGF0aCBleHByZXNzaW9uOiBcIiIrZXhwcmVzc2lvbisnIicpOwotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICBTeW1ib2xUYWJsZSBzeW1ib2xUYWJsZSA9IG5ldyBTeW1ib2xUYWJsZSgpOwotICAgICAgICAgICAgICAgIFhQYXRoIHhwYXRoID0gbmV3IFhQYXRoKGV4cHJlc3Npb24sIHN5bWJvbFRhYmxlLCBudWxsKTsKLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oImV4cGFuZGVkIHhwYXRoOiBcIiIreHBhdGgudG9TdHJpbmcoKSsnIicpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2F0Y2ggKFhQYXRoRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oImVycm9yOiAiK2UuZ2V0TWVzc2FnZSgpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgfSAvLyBtYWluKFN0cmluZ1tdKQotCi19IC8vIGNsYXNzIFhQYXRoCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hwYXRoL1hQYXRoRXhjZXB0aW9uLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hwYXRoL1hQYXRoRXhjZXB0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDVlNjhkOGIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cGF0aC9YUGF0aEV4Y2VwdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNjEgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMSwgMjAwMiwyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHBhdGg7Ci0KLS8qKgotICogWFBhdGggZXhjZXB0aW9uLgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIEFuZHkgQ2xhcmssIElCTQotICoKLSAqLwotcHVibGljIGNsYXNzIFhQYXRoRXhjZXB0aW9uCi0gICAgZXh0ZW5kcyBFeGNlcHRpb24gewotCi0gICAgLyoqIFNlcmlhbGl6YXRpb24gdmVyc2lvbi4gKi8KLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTk0ODQ4MjMxMjE2OTUxMjA4NUw7Ci0KLSAgICAvLyBEYXRhCi0KLSAgICAvLyBob2xkIHRoZSB2YWx1ZSBvZiB0aGUga2V5IHRoaXMgRXhjZXB0aW9uIHJlZmVycyB0by4KLSAgICBwcml2YXRlIFN0cmluZyBmS2V5OwotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKiBDb25zdHJ1Y3RzIGFuIGV4Y2VwdGlvbi4gKi8KLSAgICBwdWJsaWMgWFBhdGhFeGNlcHRpb24oKSB7Ci0gICAgICAgIHN1cGVyKCk7Ci0gICAgICAgIGZLZXkgPSAiYy1nZW5lcmFsLXhwYXRoIjsKLSAgICB9IC8vIDxpbml0PigpCi0KLSAgICAvKiogQ29uc3RydWN0cyBhbiBleGNlcHRpb24gd2l0aCB0aGUgc3BlY2lmaWVkIGtleS4gKi8KLSAgICBwdWJsaWMgWFBhdGhFeGNlcHRpb24oU3RyaW5nIGtleSkgewotICAgICAgICBzdXBlcigpOwotICAgICAgICBmS2V5ID0ga2V5OwotICAgIH0gLy8gPGluaXQ+KFN0cmluZykKLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0S2V5KCkgewotICAgICAgICByZXR1cm4gZktleTsKLSAgICB9IC8vIGdldEtleSgpOiAgU3RyaW5nCi0KLX0gLy8gY2xhc3MgWFBhdGhFeGNlcHRpb24KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHBhdGgvcmVnZXgvQk1QYXR0ZXJuLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hwYXRoL3JlZ2V4L0JNUGF0dGVybi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1ZmQ3OTZhLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHBhdGgvcmVnZXgvQk1QYXR0ZXJuLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMzcgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDAyLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cGF0aC5yZWdleDsKLQotaW1wb3J0IGphdmEudGV4dC5DaGFyYWN0ZXJJdGVyYXRvcjsKLQotLyoqCi0gKiBCb3llci1Nb29yZSBzZWFyY2hlci4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICovCi1wdWJsaWMgY2xhc3MgQk1QYXR0ZXJuIHsKLSAgICBjaGFyW10gcGF0dGVybjsKLSAgICBpbnRbXSBzaGlmdFRhYmxlOwotICAgIGJvb2xlYW4gaWdub3JlQ2FzZTsKLQotICAgIHB1YmxpYyBCTVBhdHRlcm4oU3RyaW5nIHBhdCwgYm9vbGVhbiBpZ25vcmVDYXNlKSB7Ci0gICAgICAgIHRoaXMocGF0LCAyNTYsIGlnbm9yZUNhc2UpOwotICAgIH0KLQotICAgIHB1YmxpYyBCTVBhdHRlcm4oU3RyaW5nIHBhdCwgaW50IHRhYmxlU2l6ZSwgYm9vbGVhbiBpZ25vcmVDYXNlKSB7Ci0gICAgICAgIHRoaXMucGF0dGVybiA9IHBhdC50b0NoYXJBcnJheSgpOwotICAgICAgICB0aGlzLnNoaWZ0VGFibGUgPSBuZXcgaW50W3RhYmxlU2l6ZV07Ci0gICAgICAgIHRoaXMuaWdub3JlQ2FzZSA9IGlnbm9yZUNhc2U7Ci0KLSAgICAgICAgaW50IGxlbmd0aCA9IHBhdHRlcm4ubGVuZ3RoOwotICAgICAgICBmb3IgKGludCBpID0gMDsgIGkgPCB0aGlzLnNoaWZ0VGFibGUubGVuZ3RoOyAgaSArKykKLSAgICAgICAgICAgIHRoaXMuc2hpZnRUYWJsZVtpXSA9IGxlbmd0aDsKLQotICAgICAgICBmb3IgKGludCBpID0gMDsgIGkgPCBsZW5ndGg7ICBpICsrKSB7Ci0gICAgICAgICAgICBjaGFyIGNoID0gdGhpcy5wYXR0ZXJuW2ldOwotICAgICAgICAgICAgaW50IGRpZmYgPSBsZW5ndGgtaS0xOwotICAgICAgICAgICAgaW50IGluZGV4ID0gY2ggJSB0aGlzLnNoaWZ0VGFibGUubGVuZ3RoOwotICAgICAgICAgICAgaWYgKGRpZmYgPCB0aGlzLnNoaWZ0VGFibGVbaW5kZXhdKQotICAgICAgICAgICAgICAgIHRoaXMuc2hpZnRUYWJsZVtpbmRleF0gPSBkaWZmOwotICAgICAgICAgICAgaWYgKHRoaXMuaWdub3JlQ2FzZSkgewotICAgICAgICAgICAgICAgIGNoID0gQ2hhcmFjdGVyLnRvVXBwZXJDYXNlKGNoKTsKLSAgICAgICAgICAgICAgICBpbmRleCA9IGNoICUgdGhpcy5zaGlmdFRhYmxlLmxlbmd0aDsKLSAgICAgICAgICAgICAgICBpZiAoZGlmZiA8IHRoaXMuc2hpZnRUYWJsZVtpbmRleF0pCi0gICAgICAgICAgICAgICAgICAgIHRoaXMuc2hpZnRUYWJsZVtpbmRleF0gPSBkaWZmOwotICAgICAgICAgICAgICAgIGNoID0gQ2hhcmFjdGVyLnRvTG93ZXJDYXNlKGNoKTsKLSAgICAgICAgICAgICAgICBpbmRleCA9IGNoICUgdGhpcy5zaGlmdFRhYmxlLmxlbmd0aDsKLSAgICAgICAgICAgICAgICBpZiAoZGlmZiA8IHRoaXMuc2hpZnRUYWJsZVtpbmRleF0pCi0gICAgICAgICAgICAgICAgICAgIHRoaXMuc2hpZnRUYWJsZVtpbmRleF0gPSBkaWZmOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIC0xIGlmIDx2YXI+aXRlcmF0b3I8L3Zhcj4gZG9lcyBub3QgY29udGFpbiB0aGlzIHBhdHRlcm4uCi0gICAgICovCi0gICAgcHVibGljIGludCBtYXRjaGVzKENoYXJhY3Rlckl0ZXJhdG9yIGl0ZXJhdG9yLCBpbnQgc3RhcnQsIGludCBsaW1pdCkgewotICAgICAgICBpZiAodGhpcy5pZ25vcmVDYXNlKSAgcmV0dXJuIHRoaXMubWF0Y2hlc0lnbm9yZUNhc2UoaXRlcmF0b3IsIHN0YXJ0LCBsaW1pdCk7Ci0gICAgICAgIGludCBwbGVuZ3RoID0gdGhpcy5wYXR0ZXJuLmxlbmd0aDsKLSAgICAgICAgaWYgKHBsZW5ndGggPT0gMCkgIHJldHVybiBzdGFydDsKLSAgICAgICAgaW50IGluZGV4ID0gc3RhcnQrcGxlbmd0aDsKLSAgICAgICAgd2hpbGUgKGluZGV4IDw9IGxpbWl0KSB7Ci0gICAgICAgICAgICBpbnQgcGluZGV4ID0gcGxlbmd0aDsKLSAgICAgICAgICAgIGludCBuaW5kZXggPSBpbmRleCsxOwotICAgICAgICAgICAgY2hhciBjaDsKLSAgICAgICAgICAgIGRvIHsKLSAgICAgICAgICAgICAgICBpZiAoKGNoID0gaXRlcmF0b3Iuc2V0SW5kZXgoLS1pbmRleCkpICE9IHRoaXMucGF0dGVyblstLXBpbmRleF0pCi0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGlmIChwaW5kZXggPT0gMCkKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGluZGV4OwotICAgICAgICAgICAgfSB3aGlsZSAocGluZGV4ID4gMCk7Ci0gICAgICAgICAgICBpbmRleCArPSB0aGlzLnNoaWZ0VGFibGVbY2ggJSB0aGlzLnNoaWZ0VGFibGUubGVuZ3RoXSsxOwotICAgICAgICAgICAgaWYgKGluZGV4IDwgbmluZGV4KSAgaW5kZXggPSBuaW5kZXg7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIC0xOwotICAgIH0KLQotICAgIC8qKgotICAgICAqCi0gICAgICogQHJldHVybiAtMSBpZiA8dmFyPnN0cjwvdmFyPiBkb2VzIG5vdCBjb250YWluIHRoaXMgcGF0dGVybi4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IG1hdGNoZXMoU3RyaW5nIHN0ciwgaW50IHN0YXJ0LCBpbnQgbGltaXQpIHsKLSAgICAgICAgaWYgKHRoaXMuaWdub3JlQ2FzZSkgIHJldHVybiB0aGlzLm1hdGNoZXNJZ25vcmVDYXNlKHN0ciwgc3RhcnQsIGxpbWl0KTsKLSAgICAgICAgaW50IHBsZW5ndGggPSB0aGlzLnBhdHRlcm4ubGVuZ3RoOwotICAgICAgICBpZiAocGxlbmd0aCA9PSAwKSAgcmV0dXJuIHN0YXJ0OwotICAgICAgICBpbnQgaW5kZXggPSBzdGFydCtwbGVuZ3RoOwotICAgICAgICB3aGlsZSAoaW5kZXggPD0gbGltaXQpIHsKLSAgICAgICAgICAgIC8vU3lzdGVtLmVyci5wcmludGxuKCJTdGFydHMgYXQgIitpbmRleCk7Ci0gICAgICAgICAgICBpbnQgcGluZGV4ID0gcGxlbmd0aDsKLSAgICAgICAgICAgIGludCBuaW5kZXggPSBpbmRleCsxOwotICAgICAgICAgICAgY2hhciBjaDsKLSAgICAgICAgICAgIGRvIHsKLSAgICAgICAgICAgICAgICBpZiAoKGNoID0gc3RyLmNoYXJBdCgtLWluZGV4KSkgIT0gdGhpcy5wYXR0ZXJuWy0tcGluZGV4XSkKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgaWYgKHBpbmRleCA9PSAwKQotICAgICAgICAgICAgICAgICAgICByZXR1cm4gaW5kZXg7Ci0gICAgICAgICAgICB9IHdoaWxlIChwaW5kZXggPiAwKTsKLSAgICAgICAgICAgIGluZGV4ICs9IHRoaXMuc2hpZnRUYWJsZVtjaCAlIHRoaXMuc2hpZnRUYWJsZS5sZW5ndGhdKzE7Ci0gICAgICAgICAgICBpZiAoaW5kZXggPCBuaW5kZXgpICBpbmRleCA9IG5pbmRleDsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gLTE7Ci0gICAgfQotICAgIC8qKgotICAgICAqCi0gICAgICogQHJldHVybiAtMSBpZiA8dmFyPmNoYXJzPC9jaGFyPiBkb2VzIG5vdCBjb250YWluIHRoaXMgcGF0dGVybi4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IG1hdGNoZXMoY2hhcltdIGNoYXJzLCBpbnQgc3RhcnQsIGludCBsaW1pdCkgewotICAgICAgICBpZiAodGhpcy5pZ25vcmVDYXNlKSAgcmV0dXJuIHRoaXMubWF0Y2hlc0lnbm9yZUNhc2UoY2hhcnMsIHN0YXJ0LCBsaW1pdCk7Ci0gICAgICAgIGludCBwbGVuZ3RoID0gdGhpcy5wYXR0ZXJuLmxlbmd0aDsKLSAgICAgICAgaWYgKHBsZW5ndGggPT0gMCkgIHJldHVybiBzdGFydDsKLSAgICAgICAgaW50IGluZGV4ID0gc3RhcnQrcGxlbmd0aDsKLSAgICAgICAgd2hpbGUgKGluZGV4IDw9IGxpbWl0KSB7Ci0gICAgICAgICAgICAvL1N5c3RlbS5lcnIucHJpbnRsbigiU3RhcnRzIGF0ICIraW5kZXgpOwotICAgICAgICAgICAgaW50IHBpbmRleCA9IHBsZW5ndGg7Ci0gICAgICAgICAgICBpbnQgbmluZGV4ID0gaW5kZXgrMTsKLSAgICAgICAgICAgIGNoYXIgY2g7Ci0gICAgICAgICAgICBkbyB7Ci0gICAgICAgICAgICAgICAgaWYgKChjaCA9IGNoYXJzWy0taW5kZXhdKSAhPSB0aGlzLnBhdHRlcm5bLS1waW5kZXhdKQotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICBpZiAocGluZGV4ID09IDApCi0gICAgICAgICAgICAgICAgICAgIHJldHVybiBpbmRleDsKLSAgICAgICAgICAgIH0gd2hpbGUgKHBpbmRleCA+IDApOwotICAgICAgICAgICAgaW5kZXggKz0gdGhpcy5zaGlmdFRhYmxlW2NoICUgdGhpcy5zaGlmdFRhYmxlLmxlbmd0aF0rMTsKLSAgICAgICAgICAgIGlmIChpbmRleCA8IG5pbmRleCkgIGluZGV4ID0gbmluZGV4OwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiAtMTsKLSAgICB9Ci0KLSAgICBpbnQgbWF0Y2hlc0lnbm9yZUNhc2UoQ2hhcmFjdGVySXRlcmF0b3IgaXRlcmF0b3IsIGludCBzdGFydCwgaW50IGxpbWl0KSB7Ci0gICAgICAgIGludCBwbGVuZ3RoID0gdGhpcy5wYXR0ZXJuLmxlbmd0aDsKLSAgICAgICAgaWYgKHBsZW5ndGggPT0gMCkgIHJldHVybiBzdGFydDsKLSAgICAgICAgaW50IGluZGV4ID0gc3RhcnQrcGxlbmd0aDsKLSAgICAgICAgd2hpbGUgKGluZGV4IDw9IGxpbWl0KSB7Ci0gICAgICAgICAgICBpbnQgcGluZGV4ID0gcGxlbmd0aDsKLSAgICAgICAgICAgIGludCBuaW5kZXggPSBpbmRleCsxOwotICAgICAgICAgICAgY2hhciBjaDsKLSAgICAgICAgICAgIGRvIHsKLSAgICAgICAgICAgICAgICBjaGFyIGNoMSA9IGNoID0gaXRlcmF0b3Iuc2V0SW5kZXgoLS1pbmRleCk7Ci0gICAgICAgICAgICAgICAgY2hhciBjaDIgPSB0aGlzLnBhdHRlcm5bLS1waW5kZXhdOwotICAgICAgICAgICAgICAgIGlmIChjaDEgIT0gY2gyKSB7Ci0gICAgICAgICAgICAgICAgICAgIGNoMSA9IENoYXJhY3Rlci50b1VwcGVyQ2FzZShjaDEpOwotICAgICAgICAgICAgICAgICAgICBjaDIgPSBDaGFyYWN0ZXIudG9VcHBlckNhc2UoY2gyKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGNoMSAhPSBjaDIgJiYgQ2hhcmFjdGVyLnRvTG93ZXJDYXNlKGNoMSkgIT0gQ2hhcmFjdGVyLnRvTG93ZXJDYXNlKGNoMikpCi0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaWYgKHBpbmRleCA9PSAwKQotICAgICAgICAgICAgICAgICAgICByZXR1cm4gaW5kZXg7Ci0gICAgICAgICAgICB9IHdoaWxlIChwaW5kZXggPiAwKTsKLSAgICAgICAgICAgIGluZGV4ICs9IHRoaXMuc2hpZnRUYWJsZVtjaCAlIHRoaXMuc2hpZnRUYWJsZS5sZW5ndGhdKzE7Ci0gICAgICAgICAgICBpZiAoaW5kZXggPCBuaW5kZXgpICBpbmRleCA9IG5pbmRleDsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gLTE7Ci0gICAgfQotCi0gICAgaW50IG1hdGNoZXNJZ25vcmVDYXNlKFN0cmluZyB0ZXh0LCBpbnQgc3RhcnQsIGludCBsaW1pdCkgewotICAgICAgICBpbnQgcGxlbmd0aCA9IHRoaXMucGF0dGVybi5sZW5ndGg7Ci0gICAgICAgIGlmIChwbGVuZ3RoID09IDApICByZXR1cm4gc3RhcnQ7Ci0gICAgICAgIGludCBpbmRleCA9IHN0YXJ0K3BsZW5ndGg7Ci0gICAgICAgIHdoaWxlIChpbmRleCA8PSBsaW1pdCkgewotICAgICAgICAgICAgaW50IHBpbmRleCA9IHBsZW5ndGg7Ci0gICAgICAgICAgICBpbnQgbmluZGV4ID0gaW5kZXgrMTsKLSAgICAgICAgICAgIGNoYXIgY2g7Ci0gICAgICAgICAgICBkbyB7Ci0gICAgICAgICAgICAgICAgY2hhciBjaDEgPSBjaCA9IHRleHQuY2hhckF0KC0taW5kZXgpOwotICAgICAgICAgICAgICAgIGNoYXIgY2gyID0gdGhpcy5wYXR0ZXJuWy0tcGluZGV4XTsKLSAgICAgICAgICAgICAgICBpZiAoY2gxICE9IGNoMikgewotICAgICAgICAgICAgICAgICAgICBjaDEgPSBDaGFyYWN0ZXIudG9VcHBlckNhc2UoY2gxKTsKLSAgICAgICAgICAgICAgICAgICAgY2gyID0gQ2hhcmFjdGVyLnRvVXBwZXJDYXNlKGNoMik7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChjaDEgIT0gY2gyICYmIENoYXJhY3Rlci50b0xvd2VyQ2FzZShjaDEpICE9IENoYXJhY3Rlci50b0xvd2VyQ2FzZShjaDIpKQotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGlmIChwaW5kZXggPT0gMCkKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGluZGV4OwotICAgICAgICAgICAgfSB3aGlsZSAocGluZGV4ID4gMCk7Ci0gICAgICAgICAgICBpbmRleCArPSB0aGlzLnNoaWZ0VGFibGVbY2ggJSB0aGlzLnNoaWZ0VGFibGUubGVuZ3RoXSsxOwotICAgICAgICAgICAgaWYgKGluZGV4IDwgbmluZGV4KSAgaW5kZXggPSBuaW5kZXg7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIC0xOwotICAgIH0KLSAgICBpbnQgbWF0Y2hlc0lnbm9yZUNhc2UoY2hhcltdIGNoYXJzLCBpbnQgc3RhcnQsIGludCBsaW1pdCkgewotICAgICAgICBpbnQgcGxlbmd0aCA9IHRoaXMucGF0dGVybi5sZW5ndGg7Ci0gICAgICAgIGlmIChwbGVuZ3RoID09IDApICByZXR1cm4gc3RhcnQ7Ci0gICAgICAgIGludCBpbmRleCA9IHN0YXJ0K3BsZW5ndGg7Ci0gICAgICAgIHdoaWxlIChpbmRleCA8PSBsaW1pdCkgewotICAgICAgICAgICAgaW50IHBpbmRleCA9IHBsZW5ndGg7Ci0gICAgICAgICAgICBpbnQgbmluZGV4ID0gaW5kZXgrMTsKLSAgICAgICAgICAgIGNoYXIgY2g7Ci0gICAgICAgICAgICBkbyB7Ci0gICAgICAgICAgICAgICAgY2hhciBjaDEgPSBjaCA9IGNoYXJzWy0taW5kZXhdOwotICAgICAgICAgICAgICAgIGNoYXIgY2gyID0gdGhpcy5wYXR0ZXJuWy0tcGluZGV4XTsKLSAgICAgICAgICAgICAgICBpZiAoY2gxICE9IGNoMikgewotICAgICAgICAgICAgICAgICAgICBjaDEgPSBDaGFyYWN0ZXIudG9VcHBlckNhc2UoY2gxKTsKLSAgICAgICAgICAgICAgICAgICAgY2gyID0gQ2hhcmFjdGVyLnRvVXBwZXJDYXNlKGNoMik7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChjaDEgIT0gY2gyICYmIENoYXJhY3Rlci50b0xvd2VyQ2FzZShjaDEpICE9IENoYXJhY3Rlci50b0xvd2VyQ2FzZShjaDIpKQotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGlmIChwaW5kZXggPT0gMCkKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGluZGV4OwotICAgICAgICAgICAgfSB3aGlsZSAocGluZGV4ID4gMCk7Ci0gICAgICAgICAgICBpbmRleCArPSB0aGlzLnNoaWZ0VGFibGVbY2ggJSB0aGlzLnNoaWZ0VGFibGUubGVuZ3RoXSsxOwotICAgICAgICAgICAgaWYgKGluZGV4IDwgbmluZGV4KSAgaW5kZXggPSBuaW5kZXg7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIC0xOwotICAgIH0KLQotICAgIC8qCi0gICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nW10gYXJndikgewotICAgICAgICB0cnkgewotICAgICAgICAgICAgaW50W10gc2hpZnRUYWJsZSA9IG5ldyBpbnRbMjU2XTsKLSAgICAgICAgICAgIGluaXRpYWxpemVCb3llck1vb3JlKGFyZ3ZbMF0sIHNoaWZ0VGFibGUsIHRydWUpOwotICAgICAgICAgICAgaW50IG8gPSAtMTsKLSAgICAgICAgICAgIENoYXJhY3Rlckl0ZXJhdG9yIGl0ZSA9IG5ldyBqYXZhLnRleHQuU3RyaW5nQ2hhcmFjdGVySXRlcmF0b3IoYXJndlsxXSk7Ci0gICAgICAgICAgICBsb25nIHN0YXJ0ID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7Ci0gICAgICAgICAgICAvL2ZvciAoaW50IGkgPSAwOyAgaSA8IDEwMDAwOyAgaSArKykKLSAgICAgICAgICAgICAgICBvID0gc2VhcmNoSWdub3JlQ2FzZXNXaXRoQm95ZXJNb29yZShpdGUsIDAsIGFyZ3ZbMF0sIHNoaWZ0VGFibGUpOwotICAgICAgICAgICAgc3RhcnQgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKS1zdGFydDsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiUmVzdWx0OiAiK28rIiwgRWxhcHNlZDogIitzdGFydCk7Ci0gICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgewotICAgICAgICAgICAgZXgucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgIH0KLSAgICB9Ki8KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHBhdGgvcmVnZXgvQ2FzZUluc2Vuc2l0aXZlTWFwLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hwYXRoL3JlZ2V4L0Nhc2VJbnNlbnNpdGl2ZU1hcC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyMDJmMjM5Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHBhdGgvcmVnZXgvQ2FzZUluc2Vuc2l0aXZlTWFwLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNzYgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKLSAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAotICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgotICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKLSAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCi0gKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHBhdGgucmVnZXg7Ci0KLS8qKgotICogQHZlcnNpb24gJElkOiBDYXNlSW5zZW5zaXRpdmVNYXAuamF2YSx2IDEuMSAyMDEwLzA3LzI3IDA2OjI5OjI3IGpvZWh3IEV4cCAkCi0gKi8KLQotcHVibGljIGNsYXNzIENhc2VJbnNlbnNpdGl2ZU1hcCB7Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBpbnQgQ0hVTktfU0hJRlQgPSAxMDsgICAgICAgICAgIC8qIDJeMTAgPSAxayAqLwotICAgIHByaXZhdGUgc3RhdGljIGludCBDSFVOS19TSVpFID0gKDE8PENIVU5LX1NISUZUKTsKLSAgICBwcml2YXRlIHN0YXRpYyBpbnQgQ0hVTktfTUFTSyA9IChDSFVOS19TSVpFLTEpOwotICAgIHByaXZhdGUgc3RhdGljIGludCBJTklUSUFMX0NIVU5LX0NPVU5UID0gNjQ7ICAgLyogdXAgdG8gMHhGRkZGICovCi0KLSAgICBwcml2YXRlIHN0YXRpYyBpbnRbXVtdW10gY2FzZUluc2Vuc2l0aXZlTWFwOwotICAgIHByaXZhdGUgc3RhdGljIEJvb2xlYW4gbWFwQnVpbHQgPSBCb29sZWFuLkZBTFNFOwotCi0gICAgcHJpdmF0ZSBzdGF0aWMgaW50IExPV0VSX0NBU0VfTUFUQ0ggPSAxOwotICAgIHByaXZhdGUgc3RhdGljIGludCBVUFBFUl9DQVNFX01BVENIID0gMjsKLQotICAgIC8qKgotICAgICAqICBSZXR1cm4gYSBsaXN0IG9mIGNvZGUgcG9pbnQgY2hhcmFjdGVycyAobm90IGluY2x1ZGluZyB0aGUgaW5wdXQgdmFsdWUpCi0gICAgICogIHRoYXQgY2FuIGJlIHN1YnN0aXR1dGVkIGluIGEgY2FzZSBpbnNlbnNpdGl2ZSBtYXRjaAotICAgICAqLwotICAgIHN0YXRpYyBwdWJsaWMgaW50W10gZ2V0KGludCBjb2RlUG9pbnQpIHsKLSAgICAgICAgaWYgKG1hcEJ1aWx0ID09IEJvb2xlYW4uRkFMU0UpIHsKLSAgICAgICAgICAgIHN5bmNocm9uaXplZCAobWFwQnVpbHQpIHsKLSAgICAgICAgICAgICAgICBpZiAobWFwQnVpbHQgPT0gQm9vbGVhbi5GQUxTRSkgewotICAgICAgICAgICAgICAgICAgICBidWlsZENhc2VJbnNlbnNpdGl2ZU1hcCgpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0gLy8gc3luY2hyb25pemVkCi0gICAgICAgIH0gLy8gaWYgbWFwQnVpbHQKLQotICAgICAgICByZXR1cm4gKGNvZGVQb2ludCA8IDB4MTAwMDApID8gZ2V0TWFwcGluZyhjb2RlUG9pbnQpIDogbnVsbDsKLSAgICB9Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBpbnRbXSBnZXRNYXBwaW5nKGludCBjb2RlUG9pbnQpIHsKLSAgICAgICAgaW50IGNodW5rID0gY29kZVBvaW50ID4+PiBDSFVOS19TSElGVDsKLSAgICAgICAgaW50IG9mZnNldCA9IGNvZGVQb2ludCAmIENIVU5LX01BU0s7Ci0KLSAgICAgICAgcmV0dXJuIGNhc2VJbnNlbnNpdGl2ZU1hcFtjaHVua11bb2Zmc2V0XTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGJ1aWxkQ2FzZUluc2Vuc2l0aXZlTWFwKCkgewotICAgICAgICBjYXNlSW5zZW5zaXRpdmVNYXAgPSBuZXcgaW50W0lOSVRJQUxfQ0hVTktfQ09VTlRdW11bXTsKLSAgICAgICAgZm9yIChpbnQgaT0wOyBpPElOSVRJQUxfQ0hVTktfQ09VTlQ7IGkrKykgewotICAgICAgICAgICAgY2FzZUluc2Vuc2l0aXZlTWFwW2ldID0gbmV3IGludFtDSFVOS19TSVpFXVtdOwotICAgICAgICB9Ci0KLSAgICAgICAgaW50IGxjLCB1YzsKLSAgICAgICAgZm9yIChpbnQgaT0wOyBpPDB4MTAwMDA7IGkrKykgewotICAgICAgICAgICAgbGMgPSBDaGFyYWN0ZXIudG9Mb3dlckNhc2UoaSk7Ci0gICAgICAgICAgICB1YyA9IENoYXJhY3Rlci50b1VwcGVyQ2FzZShpKTsKLQotICAgICAgICAgICAgLy8gbG93ZXIvdXBwZXIgY2FzZSB2YWx1ZSBpcyBub3QgdGhlIHNhbWUgYXMgY29kZSBwb2ludAotICAgICAgICAgICAgaWYgKGxjICE9IHVjIHx8IGxjICE9IGkpIHsKLSAgICAgICAgICAgICAgICBpbnRbXSBtYXAgPSBuZXcgaW50WzJdOwotICAgICAgICAgICAgICAgIGludCBpbmRleCA9IDA7Ci0KLSAgICAgICAgICAgICAgICBpZiAobGMgIT0gaSkgewotICAgICAgICAgICAgICAgICAgICBtYXBbaW5kZXgrK10gPSBsYzsKLSAgICAgICAgICAgICAgICAgICAgbWFwW2luZGV4KytdID0gTE9XRVJfQ0FTRV9NQVRDSDsKLSAgICAgICAgICAgICAgICAgICAgaW50W10gbGNNYXAgPSBnZXRNYXBwaW5nKGxjKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGxjTWFwICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIG1hcCA9IHVwZGF0ZU1hcChpLCBtYXAsIGxjLCBsY01hcCwgTE9XRVJfQ0FTRV9NQVRDSCk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBpZiAodWMgIT0gaSkgewotICAgICAgICAgICAgICAgICAgICBpZiAoaW5kZXggPT0gbWFwLmxlbmd0aCkgewotICAgICAgICAgICAgICAgICAgICAgICAgbWFwID0gZXhwYW5kTWFwKG1hcCwgMik7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgbWFwW2luZGV4KytdID0gdWM7Ci0gICAgICAgICAgICAgICAgICAgIG1hcFtpbmRleCsrXSA9IFVQUEVSX0NBU0VfTUFUQ0g7Ci0gICAgICAgICAgICAgICAgICAgIGludFtdIHVjTWFwID0gZ2V0TWFwcGluZyh1Yyk7Ci0gICAgICAgICAgICAgICAgICAgIGlmICh1Y01hcCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBtYXAgPSB1cGRhdGVNYXAoaSwgbWFwLCB1YywgdWNNYXAsIFVQUEVSX0NBU0VfTUFUQ0gpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgc2V0KGksIG1hcCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBtYXBCdWlsdCA9IEJvb2xlYW4uVFJVRTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBpbnRbXSBleHBhbmRNYXAoaW50W10gc3JjTWFwLCBpbnQgZXhwYW5kQnkpIHsKLSAgICAgICAgZmluYWwgaW50IG9sZExlbiA9IHNyY01hcC5sZW5ndGg7Ci0gICAgICAgIGludFtdIG5ld01hcCA9IG5ldyBpbnRbb2xkTGVuICsgZXhwYW5kQnldOwotCi0gICAgICAgIFN5c3RlbS5hcnJheWNvcHkoc3JjTWFwLCAwLCBuZXdNYXAsIDAsIG9sZExlbik7Ci0gICAgICAgIHJldHVybiBuZXdNYXA7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBzZXQoaW50IGNvZGVQb2ludCwgaW50W10gbWFwKSB7Ci0gICAgICAgIGludCBjaHVuayA9IGNvZGVQb2ludCA+Pj4gQ0hVTktfU0hJRlQ7Ci0gICAgICAgIGludCBvZmZzZXQgPSBjb2RlUG9pbnQgJiBDSFVOS19NQVNLOwotCi0gICAgICAgIGNhc2VJbnNlbnNpdGl2ZU1hcFtjaHVua11bb2Zmc2V0XSA9IG1hcDsKLSAgICB9Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBpbnRbXSB1cGRhdGVNYXAoaW50IGNvZGVQb2ludCwgaW50W10gY29kZVBvaW50TWFwLAotICAgICAgICAgICAgaW50IGNpQ29kZVBvaW50LCBpbnRbXSBjaUNvZGVQb2ludE1hcCwgaW50IG1hdGNoVHlwZSkgewotICAgICAgICBmb3IgKGludCBpPTA7IGk8Y2lDb2RlUG9pbnRNYXAubGVuZ3RoOyBpKz0yKSB7Ci0gICAgICAgICAgICBpbnQgYyA9IGNpQ29kZVBvaW50TWFwW2ldOwotICAgICAgICAgICAgaW50W10gY01hcCA9IGdldE1hcHBpbmcoYyk7Ci0gICAgICAgICAgICBpZiAoY01hcCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGNvbnRhaW5zKGNNYXAsIGNpQ29kZVBvaW50LCBtYXRjaFR5cGUpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmICghY29udGFpbnMoY01hcCwgY29kZVBvaW50KSkgewotICAgICAgICAgICAgICAgICAgICAgICAgY01hcCA9IGV4cGFuZEFuZEFkZChjTWFwLCBjb2RlUG9pbnQsIG1hdGNoVHlwZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzZXQoYywgY01hcCk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgaWYgKCFjb250YWlucyhjb2RlUG9pbnRNYXAsIGMpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBjb2RlUG9pbnRNYXAgPSBleHBhbmRBbmRBZGQoY29kZVBvaW50TWFwLCBjLG1hdGNoVHlwZSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoIWNvbnRhaW5zKGNpQ29kZVBvaW50TWFwLCBjb2RlUG9pbnQpKSB7Ci0gICAgICAgICAgICBjaUNvZGVQb2ludE1hcCA9IGV4cGFuZEFuZEFkZChjaUNvZGVQb2ludE1hcCwgY29kZVBvaW50LCBtYXRjaFR5cGUpOwotICAgICAgICAgICAgc2V0KGNpQ29kZVBvaW50LCBjaUNvZGVQb2ludE1hcCk7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gY29kZVBvaW50TWFwOwotICAgIH0KLQotICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gY29udGFpbnMoaW50W10gbWFwLCBpbnQgY29kZVBvaW50KSB7Ci0gICAgICAgIGZvciAoaW50IGk9MDsgaTxtYXAubGVuZ3RoOyBpICs9IDIpIHsKLSAgICAgICAgICAgIGlmIChtYXBbaV0gPT0gY29kZVBvaW50KSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gY29udGFpbnMoaW50W10gbWFwLCBpbnQgY29kZVBvaW50LCBpbnQgbWF0Y2hUeXBlKSB7Ci0gICAgICAgIGZvciAoaW50IGk9MDsgaTxtYXAubGVuZ3RoOyBpICs9IDIpIHsKLSAgICAgICAgICAgIGlmIChtYXBbaV0gPT0gY29kZVBvaW50ICYmIG1hcFtpKzFdID09IG1hdGNoVHlwZSkgewotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBpbnRbXSBleHBhbmRBbmRBZGQoaW50W10gc3JjTWFwLCBpbnQgY29kZVBvaW50LCBpbnQgbWF0Y2hUeXBlKSB7Ci0gICAgICAgIGZpbmFsIGludCBvbGRMZW4gPSBzcmNNYXAubGVuZ3RoOwotICAgICAgICBpbnRbXSBuZXdNYXAgPSBuZXcgaW50W29sZExlbiArIDJdOwotCi0gICAgICAgIFN5c3RlbS5hcnJheWNvcHkoc3JjTWFwLCAwLCBuZXdNYXAsIDAsIG9sZExlbik7Ci0gICAgICAgIG5ld01hcFtvbGRMZW5dID0gY29kZVBvaW50OwotICAgICAgICBuZXdNYXBbb2xkTGVuKzFdID0gbWF0Y2hUeXBlOwotICAgICAgICByZXR1cm4gbmV3TWFwOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHBhdGgvcmVnZXgvTWF0Y2guamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHBhdGgvcmVnZXgvTWF0Y2guamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZWNlNmM4My4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hwYXRoL3JlZ2V4L01hdGNoLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxODYgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDAyLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cGF0aC5yZWdleDsKLQotaW1wb3J0IGphdmEudGV4dC5DaGFyYWN0ZXJJdGVyYXRvcjsKLQotLyoqCi0gKiBBbiBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIGhhcyByYW5nZXMgY2FwdHVyZWQgaW4gbWF0Y2hpbmcuCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBzZWUgUmVndWxhckV4cHJlc3Npb24jbWF0Y2hlcyhjaGFyW10sIGludCwgaW50LCBNYXRjaCkKLSAqIEBzZWUgUmVndWxhckV4cHJlc3Npb24jbWF0Y2hlcyhjaGFyW10sIE1hdGNoKQotICogQHNlZSBSZWd1bGFyRXhwcmVzc2lvbiNtYXRjaGVzKGphdmEudGV4dC5DaGFyYWN0ZXJJdGVyYXRvciwgTWF0Y2gpCi0gKiBAc2VlIFJlZ3VsYXJFeHByZXNzaW9uI21hdGNoZXMoamF2YS5sYW5nLlN0cmluZywgaW50LCBpbnQsIE1hdGNoKQotICogQHNlZSBSZWd1bGFyRXhwcmVzc2lvbiNtYXRjaGVzKGphdmEubGFuZy5TdHJpbmcsIE1hdGNoKQotICogQGF1dGhvciBUQU1VUkEgS2VudCAmbHQ7a2VudEB0cmwuaWJtLmNvLmpwJmd0OwotICovCi1wdWJsaWMgY2xhc3MgTWF0Y2ggaW1wbGVtZW50cyBDbG9uZWFibGUgewotICAgIGludFtdIGJlZ2lucG9zID0gbnVsbDsKLSAgICBpbnRbXSBlbmRwb3MgPSBudWxsOwotICAgIGludCBub2Zncm91cHMgPSAwOwotCi0gICAgQ2hhcmFjdGVySXRlcmF0b3IgY2lTb3VyY2UgPSBudWxsOwotICAgIFN0cmluZyBzdHJTb3VyY2UgPSBudWxsOwotICAgIGNoYXJbXSBjaGFyU291cmNlID0gbnVsbDsKLQotICAgIC8qKgotICAgICAqIENyZWF0ZXMgYW4gaW5zdGFuY2UuCi0gICAgICovCi0gICAgcHVibGljIE1hdGNoKCkgewotICAgIH0KLQotICAgIC8qKgotICAgICAqCi0gICAgICovCi0gICAgcHVibGljIHN5bmNocm9uaXplZCBPYmplY3QgY2xvbmUoKSB7Ci0gICAgICAgIE1hdGNoIG1hID0gbmV3IE1hdGNoKCk7Ci0gICAgICAgIGlmICh0aGlzLm5vZmdyb3VwcyA+IDApIHsKLSAgICAgICAgICAgIG1hLnNldE51bWJlck9mR3JvdXBzKHRoaXMubm9mZ3JvdXBzKTsKLSAgICAgICAgICAgIGlmICh0aGlzLmNpU291cmNlICE9IG51bGwpICBtYS5zZXRTb3VyY2UodGhpcy5jaVNvdXJjZSk7Ci0gICAgICAgICAgICBpZiAodGhpcy5zdHJTb3VyY2UgIT0gbnVsbCkgIG1hLnNldFNvdXJjZSh0aGlzLnN0clNvdXJjZSk7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgIGkgPCB0aGlzLm5vZmdyb3VwczsgIGkgKyspIHsKLSAgICAgICAgICAgICAgICBtYS5zZXRCZWdpbm5pbmcoaSwgdGhpcy5nZXRCZWdpbm5pbmcoaSkpOwotICAgICAgICAgICAgICAgIG1hLnNldEVuZChpLCB0aGlzLmdldEVuZChpKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG1hOwotICAgIH0KLQotICAgIC8qKgotICAgICAqCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgc2V0TnVtYmVyT2ZHcm91cHMoaW50IG4pIHsKLSAgICAgICAgaW50IG9sZG4gPSB0aGlzLm5vZmdyb3VwczsKLSAgICAgICAgdGhpcy5ub2Zncm91cHMgPSBuOwotICAgICAgICBpZiAob2xkbiA8PSAwCi0gICAgICAgICAgICB8fCBvbGRuIDwgbiB8fCBuKjIgPCBvbGRuKSB7Ci0gICAgICAgICAgICB0aGlzLmJlZ2lucG9zID0gbmV3IGludFtuXTsKLSAgICAgICAgICAgIHRoaXMuZW5kcG9zID0gbmV3IGludFtuXTsKLSAgICAgICAgfQotICAgICAgICBmb3IgKGludCBpID0gMDsgIGkgPCBuOyAgaSArKykgewotICAgICAgICAgICAgdGhpcy5iZWdpbnBvc1tpXSA9IC0xOwotICAgICAgICAgICAgdGhpcy5lbmRwb3NbaV0gPSAtMTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgc2V0U291cmNlKENoYXJhY3Rlckl0ZXJhdG9yIGNpKSB7Ci0gICAgICAgIHRoaXMuY2lTb3VyY2UgPSBjaTsKLSAgICAgICAgdGhpcy5zdHJTb3VyY2UgPSBudWxsOwotICAgICAgICB0aGlzLmNoYXJTb3VyY2UgPSBudWxsOwotICAgIH0KLSAgICAvKioKLSAgICAgKgotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIHNldFNvdXJjZShTdHJpbmcgc3RyKSB7Ci0gICAgICAgIHRoaXMuY2lTb3VyY2UgPSBudWxsOwotICAgICAgICB0aGlzLnN0clNvdXJjZSA9IHN0cjsKLSAgICAgICAgdGhpcy5jaGFyU291cmNlID0gbnVsbDsKLSAgICB9Ci0gICAgLyoqCi0gICAgICoKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCBzZXRTb3VyY2UoY2hhcltdIGNoYXJzKSB7Ci0gICAgICAgIHRoaXMuY2lTb3VyY2UgPSBudWxsOwotICAgICAgICB0aGlzLnN0clNvdXJjZSA9IG51bGw7Ci0gICAgICAgIHRoaXMuY2hhclNvdXJjZSA9IGNoYXJzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgc2V0QmVnaW5uaW5nKGludCBpbmRleCwgaW50IHYpIHsKLSAgICAgICAgdGhpcy5iZWdpbnBvc1tpbmRleF0gPSB2OwotICAgIH0KLQotICAgIC8qKgotICAgICAqCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgc2V0RW5kKGludCBpbmRleCwgaW50IHYpIHsKLSAgICAgICAgdGhpcy5lbmRwb3NbaW5kZXhdID0gdjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIG51bWJlciBvZiByZWd1bGFyIGV4cHJlc3Npb24gZ3JvdXBzLgotICAgICAqIFRoaXMgbWV0aG9kIHJldHVybnMgMSB3aGVuIHRoZSByZWd1bGFyIGV4cHJlc3Npb24gaGFzIG5vIGNhcHR1cmluZy1wYXJlbnRoZXNpcy4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldE51bWJlck9mR3JvdXBzKCkgewotICAgICAgICBpZiAodGhpcy5ub2Zncm91cHMgPD0gMCkKLSAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oIkEgcmVzdWx0IGlzIG5vdCBzZXQuIik7Ci0gICAgICAgIHJldHVybiB0aGlzLm5vZmdyb3VwczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gYSBzdGFydCBwb3NpdGlvbiBpbiB0aGUgdGFyZ2V0IHRleHQgbWF0Y2hlZCB0byBzcGVjaWZpZWQgcmVndWxhciBleHByZXNzaW9uIGdyb3VwLgotICAgICAqCi0gICAgICogQHBhcmFtIGluZGV4IExlc3MgdGhhbiA8Y29kZT5nZXROdW1iZXJPZkdyb3VwcygpPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldEJlZ2lubmluZyhpbnQgaW5kZXgpIHsKLSAgICAgICAgaWYgKHRoaXMuYmVnaW5wb3MgPT0gbnVsbCkKLSAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oIkEgcmVzdWx0IGlzIG5vdCBzZXQuIik7Ci0gICAgICAgIGlmIChpbmRleCA8IDAgfHwgdGhpcy5ub2Zncm91cHMgPD0gaW5kZXgpCi0gICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJUaGUgcGFyYW1ldGVyIG11c3QgYmUgbGVzcyB0aGFuICIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgK3RoaXMubm9mZ3JvdXBzKyI6ICIraW5kZXgpOwotICAgICAgICByZXR1cm4gdGhpcy5iZWdpbnBvc1tpbmRleF07Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIGFuIGVuZCBwb3NpdGlvbiBpbiB0aGUgdGFyZ2V0IHRleHQgbWF0Y2hlZCB0byBzcGVjaWZpZWQgcmVndWxhciBleHByZXNzaW9uIGdyb3VwLgotICAgICAqCi0gICAgICogQHBhcmFtIGluZGV4IExlc3MgdGhhbiA8Y29kZT5nZXROdW1iZXJPZkdyb3VwcygpPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldEVuZChpbnQgaW5kZXgpIHsKLSAgICAgICAgaWYgKHRoaXMuZW5kcG9zID09IG51bGwpCi0gICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJBIHJlc3VsdCBpcyBub3Qgc2V0LiIpOwotICAgICAgICBpZiAoaW5kZXggPCAwIHx8IHRoaXMubm9mZ3JvdXBzIDw9IGluZGV4KQotICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiVGhlIHBhcmFtZXRlciBtdXN0IGJlIGxlc3MgdGhhbiAiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICt0aGlzLm5vZmdyb3VwcysiOiAiK2luZGV4KTsKLSAgICAgICAgcmV0dXJuIHRoaXMuZW5kcG9zW2luZGV4XTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gYW4gc3Vic3RyaW5nIG9mIHRoZSB0YXJnZXQgdGV4dCBtYXRjaGVkIHRvIHNwZWNpZmllZCByZWd1bGFyIGV4cHJlc3Npb24gZ3JvdXAuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaW5kZXggTGVzcyB0aGFuIDxjb2RlPmdldE51bWJlck9mR3JvdXBzKCk8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q2FwdHVyZWRUZXh0KGludCBpbmRleCkgewotICAgICAgICBpZiAodGhpcy5iZWdpbnBvcyA9PSBudWxsKQotICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigibWF0Y2goKSBoYXMgbmV2ZXIgYmVlbiBjYWxsZWQuIik7Ci0gICAgICAgIGlmIChpbmRleCA8IDAgfHwgdGhpcy5ub2Zncm91cHMgPD0gaW5kZXgpCi0gICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJUaGUgcGFyYW1ldGVyIG11c3QgYmUgbGVzcyB0aGFuICIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgK3RoaXMubm9mZ3JvdXBzKyI6ICIraW5kZXgpOwotICAgICAgICBTdHJpbmcgcmV0OwotICAgICAgICBpbnQgYmVnaW4gPSB0aGlzLmJlZ2lucG9zW2luZGV4XSwgZW5kID0gdGhpcy5lbmRwb3NbaW5kZXhdOwotICAgICAgICBpZiAoYmVnaW4gPCAwIHx8IGVuZCA8IDApICByZXR1cm4gbnVsbDsKLSAgICAgICAgaWYgKHRoaXMuY2lTb3VyY2UgIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0ID0gUkVVdGlsLnN1YnN0cmluZyh0aGlzLmNpU291cmNlLCBiZWdpbiwgZW5kKTsKLSAgICAgICAgfSBlbHNlIGlmICh0aGlzLnN0clNvdXJjZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXQgPSB0aGlzLnN0clNvdXJjZS5zdWJzdHJpbmcoYmVnaW4sIGVuZCk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICByZXQgPSBuZXcgU3RyaW5nKHRoaXMuY2hhclNvdXJjZSwgYmVnaW4sIGVuZC1iZWdpbik7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHJldDsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hwYXRoL3JlZ2V4L09wLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hwYXRoL3JlZ2V4L09wLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDM3MjI0MmYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cGF0aC9yZWdleC9PcC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjU0ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwMiwyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHBhdGgucmVnZXg7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi0vKioKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKi8KLWNsYXNzIE9wIHsKLSAgICBzdGF0aWMgZmluYWwgaW50IERPVCA9IDA7Ci0gICAgc3RhdGljIGZpbmFsIGludCBDSEFSID0gMTsgICAgICAgICAgICAgICAgICAvLyBTaW5nbGUgY2hhcmFjdGVyCi0gICAgc3RhdGljIGZpbmFsIGludCBSQU5HRSA9IDM7ICAgICAgICAgICAgICAgICAvLyBbYS16QS1aXQotICAgIHN0YXRpYyBmaW5hbCBpbnQgTlJBTkdFID0gNDsgICAgICAgICAgICAgICAgLy8gW15hLXpBLVpdCi0gICAgc3RhdGljIGZpbmFsIGludCBBTkNIT1IgPSA1OyAgICAgICAgICAgICAgICAvLyBeICQgLi4uCi0gICAgc3RhdGljIGZpbmFsIGludCBTVFJJTkcgPSA2OyAgICAgICAgICAgICAgICAvLyBsaXRlcmFsIFN0cmluZwotICAgIHN0YXRpYyBmaW5hbCBpbnQgQ0xPU1VSRSA9IDc7ICAgICAgICAgICAgICAgLy8gWCoKLSAgICBzdGF0aWMgZmluYWwgaW50IE5PTkdSRUVEWUNMT1NVUkUgPSA4OyAgICAgIC8vIFgqPwotICAgIHN0YXRpYyBmaW5hbCBpbnQgUVVFU1RJT04gPSA5OyAgICAgICAgICAgICAgLy8gWD8KLSAgICBzdGF0aWMgZmluYWwgaW50IE5PTkdSRUVEWVFVRVNUSU9OID0gMTA7ICAgIC8vIFg/PwotICAgIHN0YXRpYyBmaW5hbCBpbnQgVU5JT04gPSAxMTsgICAgICAgICAgICAgICAgLy8gWHxZCi0gICAgc3RhdGljIGZpbmFsIGludCBDQVBUVVJFID0gMTU7ICAgICAgICAgICAgICAvLyAoIGFuZCApCi0gICAgc3RhdGljIGZpbmFsIGludCBCQUNLUkVGRVJFTkNFID0gMTY7ICAgICAgICAvLyBcMSBcMiAuLi4KLSAgICBzdGF0aWMgZmluYWwgaW50IExPT0tBSEVBRCA9IDIwOyAgICAgICAgICAgIC8vICg/PS4uLikKLSAgICBzdGF0aWMgZmluYWwgaW50IE5FR0FUSVZFTE9PS0FIRUFEID0gMjE7ICAgIC8vICg/IS4uLikKLSAgICBzdGF0aWMgZmluYWwgaW50IExPT0tCRUhJTkQgPSAyMjsgICAgICAgICAgIC8vICg/PD0uLi4pCi0gICAgc3RhdGljIGZpbmFsIGludCBORUdBVElWRUxPT0tCRUhJTkQgPSAyMzsgICAvLyAoPzwhLi4uKQotICAgIHN0YXRpYyBmaW5hbCBpbnQgSU5ERVBFTkRFTlQgPSAyNDsgICAgICAgICAgLy8gKD8+Li4uKQotICAgIHN0YXRpYyBmaW5hbCBpbnQgTU9ESUZJRVIgPSAyNTsgICAgICAgICAgICAgLy8gKD9pbXMtaW1zOi4uLikKLSAgICBzdGF0aWMgZmluYWwgaW50IENPTkRJVElPTiA9IDI2OyAgICAgICAgICAgIC8vICg/KC4uKXllc3xubykKLQotICAgIHN0YXRpYyBpbnQgbm9maW5zdGFuY2VzID0gMDsKLSAgICBzdGF0aWMgZmluYWwgYm9vbGVhbiBDT1VOVCA9IGZhbHNlOwotCi0gICAgc3RhdGljIE9wIGNyZWF0ZURvdCgpIHsKLSAgICAgICAgaWYgKE9wLkNPVU5UKSAgT3Aubm9maW5zdGFuY2VzICsrOwotICAgICAgICByZXR1cm4gbmV3IE9wKE9wLkRPVCk7Ci0gICAgfQotICAgIHN0YXRpYyBDaGFyT3AgY3JlYXRlQ2hhcihpbnQgZGF0YSkgewotICAgICAgICBpZiAoT3AuQ09VTlQpICBPcC5ub2ZpbnN0YW5jZXMgKys7Ci0gICAgICAgIHJldHVybiBuZXcgQ2hhck9wKE9wLkNIQVIsIGRhdGEpOwotICAgIH0KLSAgICBzdGF0aWMgQ2hhck9wIGNyZWF0ZUFuY2hvcihpbnQgZGF0YSkgewotICAgICAgICBpZiAoT3AuQ09VTlQpICBPcC5ub2ZpbnN0YW5jZXMgKys7Ci0gICAgICAgIHJldHVybiBuZXcgQ2hhck9wKE9wLkFOQ0hPUiwgZGF0YSk7Ci0gICAgfQotICAgIHN0YXRpYyBDaGFyT3AgY3JlYXRlQ2FwdHVyZShpbnQgbnVtYmVyLCBPcCBuZXh0KSB7Ci0gICAgICAgIGlmIChPcC5DT1VOVCkgIE9wLm5vZmluc3RhbmNlcyArKzsKLSAgICAgICAgQ2hhck9wIG9wID0gbmV3IENoYXJPcChPcC5DQVBUVVJFLCBudW1iZXIpOwotICAgICAgICBvcC5uZXh0ID0gbmV4dDsKLSAgICAgICAgcmV0dXJuIG9wOwotICAgIH0KLSAgICBzdGF0aWMgVW5pb25PcCBjcmVhdGVVbmlvbihpbnQgc2l6ZSkgewotICAgICAgICBpZiAoT3AuQ09VTlQpICBPcC5ub2ZpbnN0YW5jZXMgKys7Ci0gICAgICAgIC8vU3lzdGVtLmVyci5wcmludGxuKCJDcmVhdGVzIFVuaW9uT3AiKTsKLSAgICAgICAgcmV0dXJuIG5ldyBVbmlvbk9wKE9wLlVOSU9OLCBzaXplKTsKLSAgICB9Ci0gICAgc3RhdGljIENoaWxkT3AgY3JlYXRlQ2xvc3VyZShpbnQgaWQpIHsKLSAgICAgICAgaWYgKE9wLkNPVU5UKSAgT3Aubm9maW5zdGFuY2VzICsrOwotICAgICAgICByZXR1cm4gbmV3IE1vZGlmaWVyT3AoT3AuQ0xPU1VSRSwgaWQsIC0xKTsKLSAgICB9Ci0gICAgc3RhdGljIENoaWxkT3AgY3JlYXRlTm9uR3JlZWR5Q2xvc3VyZSgpIHsKLSAgICAgICAgaWYgKE9wLkNPVU5UKSAgT3Aubm9maW5zdGFuY2VzICsrOwotICAgICAgICByZXR1cm4gbmV3IENoaWxkT3AoT3AuTk9OR1JFRURZQ0xPU1VSRSk7Ci0gICAgfQotICAgIHN0YXRpYyBDaGlsZE9wIGNyZWF0ZVF1ZXN0aW9uKGJvb2xlYW4gbm9uZ3JlZWR5KSB7Ci0gICAgICAgIGlmIChPcC5DT1VOVCkgIE9wLm5vZmluc3RhbmNlcyArKzsKLSAgICAgICAgcmV0dXJuIG5ldyBDaGlsZE9wKG5vbmdyZWVkeSA/IE9wLk5PTkdSRUVEWVFVRVNUSU9OIDogT3AuUVVFU1RJT04pOwotICAgIH0KLSAgICBzdGF0aWMgUmFuZ2VPcCBjcmVhdGVSYW5nZShUb2tlbiB0b2spIHsKLSAgICAgICAgaWYgKE9wLkNPVU5UKSAgT3Aubm9maW5zdGFuY2VzICsrOwotICAgICAgICByZXR1cm4gbmV3IFJhbmdlT3AoT3AuUkFOR0UsIHRvayk7Ci0gICAgfQotICAgIHN0YXRpYyBDaGlsZE9wIGNyZWF0ZUxvb2soaW50IHR5cGUsIE9wIG5leHQsIE9wIGJyYW5jaCkgewotICAgICAgICBpZiAoT3AuQ09VTlQpICBPcC5ub2ZpbnN0YW5jZXMgKys7Ci0gICAgICAgIENoaWxkT3Agb3AgPSBuZXcgQ2hpbGRPcCh0eXBlKTsKLSAgICAgICAgb3Auc2V0Q2hpbGQoYnJhbmNoKTsKLSAgICAgICAgb3AubmV4dCA9IG5leHQ7Ci0gICAgICAgIHJldHVybiBvcDsKLSAgICB9Ci0gICAgc3RhdGljIENoYXJPcCBjcmVhdGVCYWNrUmVmZXJlbmNlKGludCByZWZubykgewotICAgICAgICBpZiAoT3AuQ09VTlQpICBPcC5ub2ZpbnN0YW5jZXMgKys7Ci0gICAgICAgIHJldHVybiBuZXcgQ2hhck9wKE9wLkJBQ0tSRUZFUkVOQ0UsIHJlZm5vKTsKLSAgICB9Ci0gICAgc3RhdGljIFN0cmluZ09wIGNyZWF0ZVN0cmluZyhTdHJpbmcgbGl0ZXJhbCkgewotICAgICAgICBpZiAoT3AuQ09VTlQpICBPcC5ub2ZpbnN0YW5jZXMgKys7Ci0gICAgICAgIHJldHVybiBuZXcgU3RyaW5nT3AoT3AuU1RSSU5HLCBsaXRlcmFsKTsKLSAgICB9Ci0gICAgc3RhdGljIENoaWxkT3AgY3JlYXRlSW5kZXBlbmRlbnQoT3AgbmV4dCwgT3AgYnJhbmNoKSB7Ci0gICAgICAgIGlmIChPcC5DT1VOVCkgIE9wLm5vZmluc3RhbmNlcyArKzsKLSAgICAgICAgQ2hpbGRPcCBvcCA9IG5ldyBDaGlsZE9wKE9wLklOREVQRU5ERU5UKTsKLSAgICAgICAgb3Auc2V0Q2hpbGQoYnJhbmNoKTsKLSAgICAgICAgb3AubmV4dCA9IG5leHQ7Ci0gICAgICAgIHJldHVybiBvcDsKLSAgICB9Ci0gICAgc3RhdGljIE1vZGlmaWVyT3AgY3JlYXRlTW9kaWZpZXIoT3AgbmV4dCwgT3AgYnJhbmNoLCBpbnQgYWRkLCBpbnQgbWFzaykgewotICAgICAgICBpZiAoT3AuQ09VTlQpICBPcC5ub2ZpbnN0YW5jZXMgKys7Ci0gICAgICAgIE1vZGlmaWVyT3Agb3AgPSBuZXcgTW9kaWZpZXJPcChPcC5NT0RJRklFUiwgYWRkLCBtYXNrKTsKLSAgICAgICAgb3Auc2V0Q2hpbGQoYnJhbmNoKTsKLSAgICAgICAgb3AubmV4dCA9IG5leHQ7Ci0gICAgICAgIHJldHVybiBvcDsKLSAgICB9Ci0gICAgc3RhdGljIENvbmRpdGlvbk9wIGNyZWF0ZUNvbmRpdGlvbihPcCBuZXh0LCBpbnQgcmVmLCBPcCBjb25kaXRpb25mbG93LCBPcCB5ZXNmbG93LCBPcCBub2Zsb3cpIHsKLSAgICAgICAgaWYgKE9wLkNPVU5UKSAgT3Aubm9maW5zdGFuY2VzICsrOwotICAgICAgICBDb25kaXRpb25PcCBvcCA9IG5ldyBDb25kaXRpb25PcChPcC5DT05ESVRJT04sIHJlZiwgY29uZGl0aW9uZmxvdywgeWVzZmxvdywgbm9mbG93KTsKLSAgICAgICAgb3AubmV4dCA9IG5leHQ7Ci0gICAgICAgIHJldHVybiBvcDsKLSAgICB9Ci0KLSAgICBpbnQgdHlwZTsKLSAgICBPcCBuZXh0ID0gbnVsbDsKLQotICAgIHByb3RlY3RlZCBPcChpbnQgdHlwZSkgewotICAgICAgICB0aGlzLnR5cGUgPSB0eXBlOwotICAgIH0KLQotICAgIGludCBzaXplKCkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZm9yIFVOSU9OCi0gICAgICAgIHJldHVybiAwOwotICAgIH0KLSAgICBPcCBlbGVtZW50QXQoaW50IGluZGV4KSB7ICAgICAgICAgICAgICAgICAgIC8vIGZvciBVTklvTgotICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiSW50ZXJuYWwgRXJyb3I6IHR5cGU9Iit0aGlzLnR5cGUpOwotICAgIH0KLSAgICBPcCBnZXRDaGlsZCgpIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZvciBDTE9TVVJFLCBRVUVTVElPTgotICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiSW50ZXJuYWwgRXJyb3I6IHR5cGU9Iit0aGlzLnR5cGUpOwotICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE1vZGlmaWVyT3AKLSAgICBpbnQgZ2V0RGF0YSgpIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENoYXJPcCAgZm9yIENIQVIsIEJBQ0tSRUZFUkVOQ0UsIENBUFRVUkUsIEFOQ0hPUiwKLSAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIkludGVybmFsIEVycm9yOiB0eXBlPSIrdGhpcy50eXBlKTsKLSAgICB9Ci0gICAgaW50IGdldERhdGEyKCkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBNb2RpZmllck9wCi0gICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJJbnRlcm5hbCBFcnJvcjogdHlwZT0iK3RoaXMudHlwZSk7Ci0gICAgfQotICAgIFJhbmdlVG9rZW4gZ2V0VG9rZW4oKSB7ICAgICAgICAgICAgICAgICAgICAgLy8gUkFOR0UsIE5SQU5HRQotICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiSW50ZXJuYWwgRXJyb3I6IHR5cGU9Iit0aGlzLnR5cGUpOwotICAgIH0KLSAgICBTdHJpbmcgZ2V0U3RyaW5nKCkgeyAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNUUklORwotICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiSW50ZXJuYWwgRXJyb3I6IHR5cGU9Iit0aGlzLnR5cGUpOwotICAgIH0KLQotICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAgICBzdGF0aWMgY2xhc3MgQ2hhck9wIGV4dGVuZHMgT3AgewotICAgICAgICBpbnQgY2hhckRhdGE7Ci0gICAgICAgIENoYXJPcChpbnQgdHlwZSwgaW50IGRhdGEpIHsKLSAgICAgICAgICAgIHN1cGVyKHR5cGUpOwotICAgICAgICAgICAgdGhpcy5jaGFyRGF0YSA9IGRhdGE7Ci0gICAgICAgIH0KLSAgICAgICAgaW50IGdldERhdGEoKSB7Ci0gICAgICAgICAgICByZXR1cm4gdGhpcy5jaGFyRGF0YTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAgICBzdGF0aWMgY2xhc3MgVW5pb25PcCBleHRlbmRzIE9wIHsKLSAgICAgICAgVmVjdG9yIGJyYW5jaGVzOwotICAgICAgICBVbmlvbk9wKGludCB0eXBlLCBpbnQgc2l6ZSkgewotICAgICAgICAgICAgc3VwZXIodHlwZSk7Ci0gICAgICAgICAgICB0aGlzLmJyYW5jaGVzID0gbmV3IFZlY3RvcihzaXplKTsKLSAgICAgICAgfQotICAgICAgICB2b2lkIGFkZEVsZW1lbnQoT3Agb3ApIHsKLSAgICAgICAgICAgIHRoaXMuYnJhbmNoZXMuYWRkRWxlbWVudChvcCk7Ci0gICAgICAgIH0KLSAgICAgICAgaW50IHNpemUoKSB7Ci0gICAgICAgICAgICByZXR1cm4gdGhpcy5icmFuY2hlcy5zaXplKCk7Ci0gICAgICAgIH0KLSAgICAgICAgT3AgZWxlbWVudEF0KGludCBpbmRleCkgewotICAgICAgICAgICAgcmV0dXJuIChPcCl0aGlzLmJyYW5jaGVzLmVsZW1lbnRBdChpbmRleCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gICAgc3RhdGljIGNsYXNzIENoaWxkT3AgZXh0ZW5kcyBPcCB7Ci0gICAgICAgIE9wIGNoaWxkOwotICAgICAgICBDaGlsZE9wKGludCB0eXBlKSB7Ci0gICAgICAgICAgICBzdXBlcih0eXBlKTsKLSAgICAgICAgfQotICAgICAgICB2b2lkIHNldENoaWxkKE9wIGNoaWxkKSB7Ci0gICAgICAgICAgICB0aGlzLmNoaWxkID0gY2hpbGQ7Ci0gICAgICAgIH0KLSAgICAgICAgT3AgZ2V0Q2hpbGQoKSB7Ci0gICAgICAgICAgICByZXR1cm4gdGhpcy5jaGlsZDsKLSAgICAgICAgfQotICAgIH0KLSAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gICAgc3RhdGljIGNsYXNzIE1vZGlmaWVyT3AgZXh0ZW5kcyBDaGlsZE9wIHsKLSAgICAgICAgaW50IHYxOwotICAgICAgICBpbnQgdjI7Ci0gICAgICAgIE1vZGlmaWVyT3AoaW50IHR5cGUsIGludCB2MSwgaW50IHYyKSB7Ci0gICAgICAgICAgICBzdXBlcih0eXBlKTsKLSAgICAgICAgICAgIHRoaXMudjEgPSB2MTsKLSAgICAgICAgICAgIHRoaXMudjIgPSB2MjsKLSAgICAgICAgfQotICAgICAgICBpbnQgZ2V0RGF0YSgpIHsKLSAgICAgICAgICAgIHJldHVybiB0aGlzLnYxOwotICAgICAgICB9Ci0gICAgICAgIGludCBnZXREYXRhMigpIHsKLSAgICAgICAgICAgIHJldHVybiB0aGlzLnYyOwotICAgICAgICB9Ci0gICAgfQotICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAgICBzdGF0aWMgY2xhc3MgUmFuZ2VPcCBleHRlbmRzIE9wIHsKLSAgICAgICAgVG9rZW4gdG9rOwotICAgICAgICBSYW5nZU9wKGludCB0eXBlLCBUb2tlbiB0b2spIHsKLSAgICAgICAgICAgIHN1cGVyKHR5cGUpOwotICAgICAgICAgICAgdGhpcy50b2sgPSB0b2s7Ci0gICAgICAgIH0KLSAgICAgICAgUmFuZ2VUb2tlbiBnZXRUb2tlbigpIHsKLSAgICAgICAgICAgIHJldHVybiAoUmFuZ2VUb2tlbil0aGlzLnRvazsKLSAgICAgICAgfQotICAgIH0KLSAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gICAgc3RhdGljIGNsYXNzIFN0cmluZ09wIGV4dGVuZHMgT3AgewotICAgICAgICBTdHJpbmcgc3RyaW5nOwotICAgICAgICBTdHJpbmdPcChpbnQgdHlwZSwgU3RyaW5nIGxpdGVyYWwpIHsKLSAgICAgICAgICAgIHN1cGVyKHR5cGUpOwotICAgICAgICAgICAgdGhpcy5zdHJpbmcgPSBsaXRlcmFsOwotICAgICAgICB9Ci0gICAgICAgIFN0cmluZyBnZXRTdHJpbmcoKSB7Ci0gICAgICAgICAgICByZXR1cm4gdGhpcy5zdHJpbmc7Ci0gICAgICAgIH0KLSAgICB9Ci0gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICAgIHN0YXRpYyBjbGFzcyBDb25kaXRpb25PcCBleHRlbmRzIE9wIHsKLSAgICAgICAgaW50IHJlZk51bWJlcjsKLSAgICAgICAgT3AgY29uZGl0aW9uOwotICAgICAgICBPcCB5ZXM7Ci0gICAgICAgIE9wIG5vOwotICAgICAgICBDb25kaXRpb25PcChpbnQgdHlwZSwgaW50IHJlZm5vLCBPcCBjb25kaXRpb25mbG93LCBPcCB5ZXNmbG93LCBPcCBub2Zsb3cpIHsKLSAgICAgICAgICAgIHN1cGVyKHR5cGUpOwotICAgICAgICAgICAgdGhpcy5yZWZOdW1iZXIgPSByZWZubzsKLSAgICAgICAgICAgIHRoaXMuY29uZGl0aW9uID0gY29uZGl0aW9uZmxvdzsKLSAgICAgICAgICAgIHRoaXMueWVzID0geWVzZmxvdzsKLSAgICAgICAgICAgIHRoaXMubm8gPSBub2Zsb3c7Ci0gICAgICAgIH0KLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hwYXRoL3JlZ2V4L1BhcnNlRXhjZXB0aW9uLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hwYXRoL3JlZ2V4L1BhcnNlRXhjZXB0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGFjNDA0MWUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cGF0aC9yZWdleC9QYXJzZUV4Y2VwdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTUgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDAyLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cGF0aC5yZWdleDsKLQotLyoqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBUQU1VUkEgS2VudCAmbHQ7a2VudEB0cmwuaWJtLmNvLmpwJmd0OwotICovCi1wdWJsaWMgY2xhc3MgUGFyc2VFeGNlcHRpb24gZXh0ZW5kcyBSdW50aW1lRXhjZXB0aW9uIHsKLQotICAgIC8qKiBTZXJpYWxpemF0aW9uIHZlcnNpb24uICovCi0gICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC03MDEyNDAwMzE4MDk3NjkxMzcwTDsKLQotICAgIGludCBsb2NhdGlvbjsKLQotICAgIC8qCi0gICAgcHVibGljIFBhcnNlRXhjZXB0aW9uKFN0cmluZyBtZXMpIHsKLSAgICAgICAgdGhpcyhtZXMsIC0xKTsKLSAgICB9Ci0gICAgKi8KLSAgICAvKioKLSAgICAgKgotICAgICAqLwotICAgIHB1YmxpYyBQYXJzZUV4Y2VwdGlvbihTdHJpbmcgbWVzLCBpbnQgbG9jYXRpb24pIHsKLSAgICAgICAgc3VwZXIobWVzKTsKLSAgICAgICAgdGhpcy5sb2NhdGlvbiA9IGxvY2F0aW9uOwotICAgIH0KLQotICAgIC8qKgotICAgICAqCi0gICAgICogQHJldHVybiAtMSBpZiBsb2NhdGlvbiBpbmZvcm1hdGlvbiBpcyBub3QgYXZhaWxhYmxlLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0TG9jYXRpb24oKSB7Ci0gICAgICAgIHJldHVybiB0aGlzLmxvY2F0aW9uOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHBhdGgvcmVnZXgvUGFyc2VyRm9yWE1MU2NoZW1hLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hwYXRoL3JlZ2V4L1BhcnNlckZvclhNTFNjaGVtYS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0MjcwNjliLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHBhdGgvcmVnZXgvUGFyc2VyRm9yWE1MU2NoZW1hLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw1MTMgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAxNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqLwotLyoKLSAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQotICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCi0gKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCi0gKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAotICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKLSAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cGF0aC5yZWdleDsKLQotaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwotaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7Ci1pbXBvcnQgamF2YS51dGlsLk1hcDsKLQotLyoqCi0gKiBBIHJlZ3VsYXIgZXhwcmVzc2lvbiBwYXJzZXIgZm9yIHRoZSBYTUwgU2NoZW1hLgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIFRBTVVSQSBLZW50ICZsdDtrZW50QHRybC5pYm0uY28uanAmZ3Q7Ci0gKiBAdmVyc2lvbiAkSWQ6IFBhcnNlckZvclhNTFNjaGVtYS5qYXZhLHYgMS45IDIwMTAtMTEtMTIgMTg6MDk6NDUgam9laHcgRXhwICQKLSAqLwotY2xhc3MgUGFyc2VyRm9yWE1MU2NoZW1hIGV4dGVuZHMgUmVnZXhQYXJzZXIgewotCi0gICAgcHVibGljIFBhcnNlckZvclhNTFNjaGVtYSgpIHsKLSAgICAgICAgLy90aGlzLnNldExvY2FsZShMb2NhbGUuZ2V0RGVmYXVsdCgpKTsKLSAgICB9Ci0gICAgcHVibGljIFBhcnNlckZvclhNTFNjaGVtYShMb2NhbGUgbG9jYWxlKSB7Ci0gICAgICAgIHN1cGVyKGxvY2FsZSk7Ci0gICAgfQotCi0gICAgVG9rZW4gcHJvY2Vzc0NhcmV0KCkgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKLSAgICAgICAgdGhpcy5uZXh0KCk7Ci0gICAgICAgIHJldHVybiBUb2tlbi5jcmVhdGVDaGFyKCdeJyk7Ci0gICAgfQotICAgIFRva2VuIHByb2Nlc3NEb2xsYXIoKSB0aHJvd3MgUGFyc2VFeGNlcHRpb24gewotICAgICAgICB0aGlzLm5leHQoKTsKLSAgICAgICAgcmV0dXJuIFRva2VuLmNyZWF0ZUNoYXIoJyQnKTsKLSAgICAgfQotICAgIFRva2VuIHByb2Nlc3NMb29rYWhlYWQoKSB0aHJvd3MgUGFyc2VFeGNlcHRpb24gewotICAgICAgICB0aHJvdyBleCgicGFyc2VyLnByb2Nlc3MuMSIsIHRoaXMub2Zmc2V0KTsKLSAgICB9Ci0gICAgVG9rZW4gcHJvY2Vzc05lZ2F0aXZlbG9va2FoZWFkKCkgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKLSAgICAgICAgdGhyb3cgZXgoInBhcnNlci5wcm9jZXNzLjEiLCB0aGlzLm9mZnNldCk7Ci0gICAgfQotICAgIFRva2VuIHByb2Nlc3NMb29rYmVoaW5kKCkgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKLSAgICAgICAgdGhyb3cgZXgoInBhcnNlci5wcm9jZXNzLjEiLCB0aGlzLm9mZnNldCk7Ci0gICAgfQotICAgIFRva2VuIHByb2Nlc3NOZWdhdGl2ZWxvb2tiZWhpbmQoKSB0aHJvd3MgUGFyc2VFeGNlcHRpb24gewotICAgICAgICB0aHJvdyBleCgicGFyc2VyLnByb2Nlc3MuMSIsIHRoaXMub2Zmc2V0KTsKLSAgICB9Ci0gICAgVG9rZW4gcHJvY2Vzc0JhY2tzb2xpZHVzX0EoKSB0aHJvd3MgUGFyc2VFeGNlcHRpb24gewotICAgICAgICB0aHJvdyBleCgicGFyc2VyLnByb2Nlc3MuMSIsIHRoaXMub2Zmc2V0KTsKLSAgICB9Ci0gICAgVG9rZW4gcHJvY2Vzc0JhY2tzb2xpZHVzX1ooKSB0aHJvd3MgUGFyc2VFeGNlcHRpb24gewotICAgICAgICB0aHJvdyBleCgicGFyc2VyLnByb2Nlc3MuMSIsIHRoaXMub2Zmc2V0KTsKLSAgICB9Ci0gICAgVG9rZW4gcHJvY2Vzc0JhY2tzb2xpZHVzX3ooKSB0aHJvd3MgUGFyc2VFeGNlcHRpb24gewotICAgICAgICB0aHJvdyBleCgicGFyc2VyLnByb2Nlc3MuMSIsIHRoaXMub2Zmc2V0KTsKLSAgICB9Ci0gICAgVG9rZW4gcHJvY2Vzc0JhY2tzb2xpZHVzX2IoKSB0aHJvd3MgUGFyc2VFeGNlcHRpb24gewotICAgICAgICB0aHJvdyBleCgicGFyc2VyLnByb2Nlc3MuMSIsIHRoaXMub2Zmc2V0KTsKLSAgICB9Ci0gICAgVG9rZW4gcHJvY2Vzc0JhY2tzb2xpZHVzX0IoKSB0aHJvd3MgUGFyc2VFeGNlcHRpb24gewotICAgICAgICB0aHJvdyBleCgicGFyc2VyLnByb2Nlc3MuMSIsIHRoaXMub2Zmc2V0KTsKLSAgICB9Ci0gICAgVG9rZW4gcHJvY2Vzc0JhY2tzb2xpZHVzX2x0KCkgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKLSAgICAgICAgdGhyb3cgZXgoInBhcnNlci5wcm9jZXNzLjEiLCB0aGlzLm9mZnNldCk7Ci0gICAgfQotICAgIFRva2VuIHByb2Nlc3NCYWNrc29saWR1c19ndCgpIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7Ci0gICAgICAgIHRocm93IGV4KCJwYXJzZXIucHJvY2Vzcy4xIiwgdGhpcy5vZmZzZXQpOwotICAgIH0KLSAgICBUb2tlbiBwcm9jZXNzU3RhcihUb2tlbiB0b2spIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7Ci0gICAgICAgIHRoaXMubmV4dCgpOwotICAgICAgICByZXR1cm4gVG9rZW4uY3JlYXRlQ2xvc3VyZSh0b2spOwotICAgIH0KLSAgICBUb2tlbiBwcm9jZXNzUGx1cyhUb2tlbiB0b2spIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7Ci0gICAgICAgIC8vIFgrIC0+IFhYKgotICAgICAgICB0aGlzLm5leHQoKTsKLSAgICAgICAgcmV0dXJuIFRva2VuLmNyZWF0ZUNvbmNhdCh0b2ssIFRva2VuLmNyZWF0ZUNsb3N1cmUodG9rKSk7Ci0gICAgfQotICAgIFRva2VuIHByb2Nlc3NRdWVzdGlvbihUb2tlbiB0b2spIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7Ci0gICAgICAgIC8vIFg/IC0+IFh8Ci0gICAgICAgIHRoaXMubmV4dCgpOwotICAgICAgICBUb2tlbiBwYXIgPSBUb2tlbi5jcmVhdGVVbmlvbigpOwotICAgICAgICBwYXIuYWRkQ2hpbGQodG9rKTsKLSAgICAgICAgcGFyLmFkZENoaWxkKFRva2VuLmNyZWF0ZUVtcHR5KCkpOwotICAgICAgICByZXR1cm4gcGFyOwotICAgIH0KLSAgICBib29sZWFuIGNoZWNrUXVlc3Rpb24oaW50IG9mZikgewotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotICAgIFRva2VuIHByb2Nlc3NQYXJlbigpIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7Ci0gICAgICAgIHRoaXMubmV4dCgpOwotICAgICAgICBUb2tlbiB0b2sgPSBUb2tlbi5jcmVhdGVQYXJlbih0aGlzLnBhcnNlUmVnZXgoKSwgMCk7Ci0gICAgICAgIGlmICh0aGlzLnJlYWQoKSAhPSBUX1JQQVJFTikgIHRocm93IGV4KCJwYXJzZXIuZmFjdG9yLjEiLCB0aGlzLm9mZnNldC0xKTsKLSAgICAgICAgdGhpcy5uZXh0KCk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNraXBzICcpJwotICAgICAgICByZXR1cm4gdG9rOwotICAgIH0KLSAgICBUb2tlbiBwcm9jZXNzUGFyZW4yKCkgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKLSAgICAgICAgdGhyb3cgZXgoInBhcnNlci5wcm9jZXNzLjEiLCB0aGlzLm9mZnNldCk7Ci0gICAgfQotICAgIFRva2VuIHByb2Nlc3NDb25kaXRpb24oKSB0aHJvd3MgUGFyc2VFeGNlcHRpb24gewotICAgICAgICB0aHJvdyBleCgicGFyc2VyLnByb2Nlc3MuMSIsIHRoaXMub2Zmc2V0KTsKLSAgICB9Ci0gICAgVG9rZW4gcHJvY2Vzc01vZGlmaWVycygpIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7Ci0gICAgICAgIHRocm93IGV4KCJwYXJzZXIucHJvY2Vzcy4xIiwgdGhpcy5vZmZzZXQpOwotICAgIH0KLSAgICBUb2tlbiBwcm9jZXNzSW5kZXBlbmRlbnQoKSB0aHJvd3MgUGFyc2VFeGNlcHRpb24gewotICAgICAgICB0aHJvdyBleCgicGFyc2VyLnByb2Nlc3MuMSIsIHRoaXMub2Zmc2V0KTsKLSAgICB9Ci0gICAgVG9rZW4gcHJvY2Vzc0JhY2tzb2xpZHVzX2MoKSB0aHJvd3MgUGFyc2VFeGNlcHRpb24gewotICAgICAgICB0aGlzLm5leHQoKTsKLSAgICAgICAgcmV0dXJuIHRoaXMuZ2V0VG9rZW5Gb3JTaG9ydGhhbmQoJ2MnKTsKLSAgICB9Ci0gICAgVG9rZW4gcHJvY2Vzc0JhY2tzb2xpZHVzX0MoKSB0aHJvd3MgUGFyc2VFeGNlcHRpb24gewotICAgICAgICB0aGlzLm5leHQoKTsKLSAgICAgICAgcmV0dXJuIHRoaXMuZ2V0VG9rZW5Gb3JTaG9ydGhhbmQoJ0MnKTsKLSAgICB9Ci0gICAgVG9rZW4gcHJvY2Vzc0JhY2tzb2xpZHVzX2koKSB0aHJvd3MgUGFyc2VFeGNlcHRpb24gewotICAgICAgICB0aGlzLm5leHQoKTsKLSAgICAgICAgcmV0dXJuIHRoaXMuZ2V0VG9rZW5Gb3JTaG9ydGhhbmQoJ2knKTsKLSAgICB9Ci0gICAgVG9rZW4gcHJvY2Vzc0JhY2tzb2xpZHVzX0koKSB0aHJvd3MgUGFyc2VFeGNlcHRpb24gewotICAgICAgICB0aGlzLm5leHQoKTsKLSAgICAgICAgcmV0dXJuIHRoaXMuZ2V0VG9rZW5Gb3JTaG9ydGhhbmQoJ0knKTsKLSAgICB9Ci0gICAgVG9rZW4gcHJvY2Vzc0JhY2tzb2xpZHVzX2coKSB0aHJvd3MgUGFyc2VFeGNlcHRpb24gewotICAgICAgICB0aHJvdyB0aGlzLmV4KCJwYXJzZXIucHJvY2Vzcy4xIiwgdGhpcy5vZmZzZXQtMik7Ci0gICAgfQotICAgIFRva2VuIHByb2Nlc3NCYWNrc29saWR1c19YKCkgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKLSAgICAgICAgdGhyb3cgZXgoInBhcnNlci5wcm9jZXNzLjEiLCB0aGlzLm9mZnNldC0yKTsKLSAgICB9Ci0gICAgVG9rZW4gcHJvY2Vzc0JhY2tyZWZlcmVuY2UoKSB0aHJvd3MgUGFyc2VFeGNlcHRpb24gewotICAgICAgICB0aHJvdyBleCgicGFyc2VyLnByb2Nlc3MuMSIsIHRoaXMub2Zmc2V0LTQpOwotICAgIH0KLQotICAgIGludCBwcm9jZXNzQ0lpbkNoYXJhY3RlckNsYXNzKFJhbmdlVG9rZW4gdG9rLCBpbnQgYykgewotICAgICAgICB0b2subWVyZ2VSYW5nZXModGhpcy5nZXRUb2tlbkZvclNob3J0aGFuZChjKSk7Ci0gICAgICAgIHJldHVybiAtMTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFBhcnNlcyBhIGNoYXJhY3Rlci1jbGFzcy1leHByZXNzaW9uLCBub3QgYSBjaGFyYWN0ZXItY2xhc3MtZXNjYXBlLgotICAgICAqCi0gICAgICogYy1jLWV4cHJlc3Npb24gICA6Oj0gJ1snIGMtZ3JvdXAgJ10nCi0gICAgICogYy1ncm91cCAgICAgICAgICA6Oj0gcG9zaXRpdmUtYy1ncm91cCB8IG5lZ2F0aXZlLWMtZ3JvdXAgfCBjLWMtc3VidHJhY3Rpb24KLSAgICAgKiBwb3NpdGl2ZS1jLWdyb3VwIDo6PSAoYy1yYW5nZSB8IGMtYy1lc2NhcGUpKwotICAgICAqIG5lZ2F0aXZlLWMtZ3JvdXAgOjo9ICdeJyBwb3NpdGl2ZS1jLWdyb3VwCi0gICAgICogYy1jLXN1YnRyYWN0aW9uICA6Oj0gKHBvc2l0aXZlLWMtZ3JvdXAgfCBuZWdhdGl2ZS1jLWdyb3VwKSBzdWJ0cmFjdGlvbgotICAgICAqIHN1YnRyYWN0aW9uICAgICAgOjo9ICctJyBjLWMtZXhwcmVzc2lvbgotICAgICAqIGMtcmFuZ2UgICAgICAgICAgOjo9IHNpbmdsZS1yYW5nZSB8IGZyb20tdG8tcmFuZ2UKLSAgICAgKiBzaW5nbGUtcmFuZ2UgICAgIDo6PSBtdWx0aS1jLWVzY2FwZSB8IGNhdGVnb3J5LWMtZXNjYXBlIHwgYmxvY2stYy1lc2NhcGUgfCAmbHQ7YW55IFhNTCBjaGFyJmd0OwotICAgICAqIGNjLW5vcm1hbC1jICAgICAgOjo9ICZsdDthbnkgY2hhcmFjdGVyIGV4Y2VwdCBbLCBdLCBcJmd0OwotICAgICAqIGZyb20tdG8tcmFuZ2UgICAgOjo9IGNjLW5vcm1hbC1jICctJyBjYy1ub3JtYWwtYwotICAgICAqCi0gICAgICogQHBhcmFtIHVzZU5yYWdlIElnbm9yZWQuCi0gICAgICogQHJldHVybiBUaGlzIHJldHVybnMgbm8gTnJhZ2VUb2tlbi4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgUmFuZ2VUb2tlbiBwYXJzZUNoYXJhY3RlckNsYXNzKGJvb2xlYW4gdXNlTnJhbmdlKSB0aHJvd3MgUGFyc2VFeGNlcHRpb24gewotICAgICAgICB0aGlzLnNldENvbnRleHQoU19JTkJSQUNLRVRTKTsKLSAgICAgICAgdGhpcy5uZXh0KCk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICdbJwotICAgICAgICBib29sZWFuIG5yYW5nZSA9IGZhbHNlOwotICAgICAgICBib29sZWFuIHdhc0RlY29kZWQgPSBmYWxzZTsgICAgICAgICAgICAgICAgICAgICAvLyB1c2VkIHRvIGRldGVjdCBpZiB0aGUgbGFzdCAtIHdhcyBlc2NhcGVkLgotICAgICAgICBSYW5nZVRva2VuIGJhc2UgPSBudWxsOwotICAgICAgICBSYW5nZVRva2VuIHRvazsKLSAgICAgICAgaWYgKHRoaXMucmVhZCgpID09IFRfQ0hBUiAmJiB0aGlzLmNoYXJkYXRhID09ICdeJykgewotICAgICAgICAgICAgbnJhbmdlID0gdHJ1ZTsKLSAgICAgICAgICAgIHRoaXMubmV4dCgpOyAgICAgICAgICAgICAgICAgICAgICAgIC8vICdeJwotICAgICAgICAgICAgYmFzZSA9IFRva2VuLmNyZWF0ZVJhbmdlKCk7Ci0gICAgICAgICAgICBiYXNlLmFkZFJhbmdlKDAsIFRva2VuLlVURjE2X01BWCk7Ci0gICAgICAgICAgICB0b2sgPSBUb2tlbi5jcmVhdGVSYW5nZSgpOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgdG9rID0gVG9rZW4uY3JlYXRlUmFuZ2UoKTsKLSAgICAgICAgfQotICAgICAgICBpbnQgdHlwZTsKLSAgICAgICAgYm9vbGVhbiBmaXJzdGxvb3AgPSB0cnVlOwotICAgICAgICB3aGlsZSAoKHR5cGUgPSB0aGlzLnJlYWQoKSkgIT0gVF9FT0YpIHsgLy8gRG9uJ3QgdXNlICdjb3RpbnVlJyBmb3IgdGhpcyBsb29wLgotCi0gICAgICAgICAgICAgICAgd2FzRGVjb2RlZCA9IGZhbHNlOwotICAgICAgICAgICAgLy8gc2luZ2xlLXJhbmdlIHwgZnJvbS10by1yYW5nZSB8IHN1YnRyYWN0aW9uCi0gICAgICAgICAgICBpZiAodHlwZSA9PSBUX0NIQVIgJiYgdGhpcy5jaGFyZGF0YSA9PSAnXScgJiYgIWZpcnN0bG9vcCkgewotICAgICAgICAgICAgICAgIGlmIChucmFuZ2UpIHsKLSAgICAgICAgICAgICAgICAgICAgYmFzZS5zdWJ0cmFjdFJhbmdlcyh0b2spOwotICAgICAgICAgICAgICAgICAgICB0b2sgPSBiYXNlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGludCBjID0gdGhpcy5jaGFyZGF0YTsKLSAgICAgICAgICAgIGJvb2xlYW4gZW5kID0gZmFsc2U7Ci0gICAgICAgICAgICBpZiAodHlwZSA9PSBUX0JBQ0tTT0xJRFVTKSB7Ci0gICAgICAgICAgICAgICAgc3dpdGNoIChjKSB7Ci0gICAgICAgICAgICAgICAgICBjYXNlICdkJzogIGNhc2UgJ0QnOgotICAgICAgICAgICAgICAgICAgY2FzZSAndyc6ICBjYXNlICdXJzoKLSAgICAgICAgICAgICAgICAgIGNhc2UgJ3MnOiAgY2FzZSAnUyc6Ci0gICAgICAgICAgICAgICAgICAgIHRvay5tZXJnZVJhbmdlcyh0aGlzLmdldFRva2VuRm9yU2hvcnRoYW5kKGMpKTsKLSAgICAgICAgICAgICAgICAgICAgZW5kID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgICAgICAgICAgIGNhc2UgJ2knOiAgY2FzZSAnSSc6Ci0gICAgICAgICAgICAgICAgICBjYXNlICdjJzogIGNhc2UgJ0MnOgotICAgICAgICAgICAgICAgICAgICBjID0gdGhpcy5wcm9jZXNzQ0lpbkNoYXJhY3RlckNsYXNzKHRvaywgYyk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChjIDwgMCkgIGVuZCA9IHRydWU7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgICAgICAgICAgICBjYXNlICdwJzoKLSAgICAgICAgICAgICAgICAgIGNhc2UgJ1AnOgotICAgICAgICAgICAgICAgICAgICBpbnQgcHN0YXJ0ID0gdGhpcy5vZmZzZXQ7Ci0gICAgICAgICAgICAgICAgICAgIFJhbmdlVG9rZW4gdG9rMiA9IHRoaXMucHJvY2Vzc0JhY2tzb2xpZHVzX3BQKGMpOwotICAgICAgICAgICAgICAgICAgICBpZiAodG9rMiA9PSBudWxsKSAgdGhyb3cgdGhpcy5leCgicGFyc2VyLmF0b20uNSIsIHBzdGFydCk7Ci0gICAgICAgICAgICAgICAgICAgIHRvay5tZXJnZVJhbmdlcyh0b2syKTsKLSAgICAgICAgICAgICAgICAgICAgZW5kID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgICAgICAgICAgY2FzZSAnLSc6Ci0gICAgICAgICAgICAgICAgICAgICAgICBjID0gdGhpcy5kZWNvZGVFc2NhcGVkKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB3YXNEZWNvZGVkID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgICAgICAgICAgICBkZWZhdWx0OgotICAgICAgICAgICAgICAgICAgICBjID0gdGhpcy5kZWNvZGVFc2NhcGVkKCk7Ci0gICAgICAgICAgICAgICAgfSAvLyBcICsgYwotICAgICAgICAgICAgfSAvLyBiYWNrc29saWR1cwotICAgICAgICAgICAgZWxzZSBpZiAodHlwZSA9PSBUX1hNTFNDSEVNQV9DQ19TVUJUUkFDVElPTiAmJiAhZmlyc3Rsb29wKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTdWJyYWN0aW9uCi0gICAgICAgICAgICAgICAgaWYgKG5yYW5nZSkgewotICAgICAgICAgICAgICAgICAgICBiYXNlLnN1YnRyYWN0UmFuZ2VzKHRvayk7Ci0gICAgICAgICAgICAgICAgICAgIHRvayA9IGJhc2U7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIFJhbmdlVG9rZW4gcmFuZ2UyID0gdGhpcy5wYXJzZUNoYXJhY3RlckNsYXNzKGZhbHNlKTsKLSAgICAgICAgICAgICAgICB0b2suc3VidHJhY3RSYW5nZXMocmFuZ2UyKTsKLSAgICAgICAgICAgICAgICBpZiAodGhpcy5yZWFkKCkgIT0gVF9DSEFSIHx8IHRoaXMuY2hhcmRhdGEgIT0gJ10nKQotICAgICAgICAgICAgICAgICAgICB0aHJvdyB0aGlzLmV4KCJwYXJzZXIuY2MuNSIsIHRoaXMub2Zmc2V0KTsKLSAgICAgICAgICAgICAgICBicmVhazsgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEV4aXQgdGhpcyBsb29wCi0gICAgICAgICAgICB9Ci0gICAgICAgICAgICB0aGlzLm5leHQoKTsKLSAgICAgICAgICAgIGlmICghZW5kKSB7ICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlmIG5vdCBzaG9ydGhhbmRzLi4uCi0gICAgICAgICAgICAgICAgaWYgKHR5cGUgPT0gVF9DSEFSKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChjID09ICdbJykgIHRocm93IHRoaXMuZXgoInBhcnNlci5jYy42IiwgdGhpcy5vZmZzZXQtMik7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChjID09ICddJykgIHRocm93IHRoaXMuZXgoInBhcnNlci5jYy43IiwgdGhpcy5vZmZzZXQtMik7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChjID09ICctJyAmJiB0aGlzLmNoYXJkYXRhICE9ICddJyAmJiAhZmlyc3Rsb29wKSAgdGhyb3cgdGhpcy5leCgicGFyc2VyLmNjLjgiLCB0aGlzLm9mZnNldC0yKTsgICAvLyBpZiByZWdleCA9ICdbLV0nIHRoZW4gaW52YWxpZAotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpZiAodGhpcy5yZWFkKCkgIT0gVF9DSEFSIHx8IHRoaXMuY2hhcmRhdGEgIT0gJy0nIHx8IGMgPT0gJy0nICYmIGZpcnN0bG9vcCkgeyAvLyBIZXJlIGlzIG5vICctJy4KLSAgICAgICAgICAgICAgICAgICAgaWYgKCF0aGlzLmlzU2V0KFJlZ3VsYXJFeHByZXNzaW9uLklHTk9SRV9DQVNFKSB8fCBjID4gMHhmZmZmKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICB0b2suYWRkUmFuZ2UoYywgYyk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBhZGRDYXNlSW5zZW5zaXRpdmVDaGFyKHRvaywgYyk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9IGVsc2UgeyAgICAgICAgICAgICAgICAgICAgICAgIC8vIEZvdW5kICctJwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSXMgdGhpcyAnLScgaXMgYSBmcm9tLXRvIHRva2VuPz8KLSAgICAgICAgICAgICAgICAgICAgdGhpcy5uZXh0KCk7IC8vIFNraXBzICctJwotICAgICAgICAgICAgICAgICAgICBpZiAoKHR5cGUgPSB0aGlzLnJlYWQoKSkgPT0gVF9FT0YpICB0aHJvdyB0aGlzLmV4KCJwYXJzZXIuY2MuMiIsIHRoaXMub2Zmc2V0KTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGMgJy0nICddJyAtPiAnLScgaXMgYSBzaW5nbGUtcmFuZ2UuCi0gICAgICAgICAgICAgICAgICAgIGlmKHR5cGUgPT0gVF9DSEFSICYmIHRoaXMuY2hhcmRhdGEgPT0gJ10nKSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpZiAtIGlzIGF0IHRoZSBsYXN0IHBvc2l0aW9uIG9mIHRoZSBncm91cAotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF0aGlzLmlzU2V0KFJlZ3VsYXJFeHByZXNzaW9uLklHTk9SRV9DQVNFKSB8fCBjID4gMHhmZmZmKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgdG9rLmFkZFJhbmdlKGMsIGMpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkQ2FzZUluc2Vuc2l0aXZlQ2hhcih0b2ssIGMpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgdG9rLmFkZFJhbmdlKCctJywgJy0nKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICh0eXBlID09IFRfWE1MU0NIRU1BX0NDX1NVQlRSQUNUSU9OKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyB0aGlzLmV4KCJwYXJzZXIuY2MuOCIsIHRoaXMub2Zmc2V0LTEpOwotICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotCi0gICAgICAgICAgICAgICAgICAgICAgICBpbnQgcmFuZ2VlbmQgPSB0aGlzLmNoYXJkYXRhOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGUgPT0gVF9DSEFSKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJhbmdlZW5kID09ICdbJykgIHRocm93IHRoaXMuZXgoInBhcnNlci5jYy42IiwgdGhpcy5vZmZzZXQtMSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJhbmdlZW5kID09ICddJykgIHRocm93IHRoaXMuZXgoInBhcnNlci5jYy43IiwgdGhpcy5vZmZzZXQtMSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJhbmdlZW5kID09ICctJykgIHRocm93IHRoaXMuZXgoInBhcnNlci5jYy44IiwgdGhpcy5vZmZzZXQtMik7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICh0eXBlID09IFRfQkFDS1NPTElEVVMpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmFuZ2VlbmQgPSB0aGlzLmRlY29kZUVzY2FwZWQoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubmV4dCgpOwotCi0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYyA+IHJhbmdlZW5kKSAgdGhyb3cgdGhpcy5leCgicGFyc2VyLm9wZS4zIiwgdGhpcy5vZmZzZXQtMSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMuaXNTZXQoUmVndWxhckV4cHJlc3Npb24uSUdOT1JFX0NBU0UpIHx8Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjID4gMHhmZmZmICYmIHJhbmdlZW5kID4gMHhmZmZmKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvay5hZGRSYW5nZShjLCByYW5nZWVuZCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRDYXNlSW5zZW5zaXRpdmVDaGFyUmFuZ2UodG9rLCBjLCByYW5nZWVuZCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmaXJzdGxvb3AgPSBmYWxzZTsKLSAgICAgICAgfQotICAgICAgICBpZiAodGhpcy5yZWFkKCkgPT0gVF9FT0YpCi0gICAgICAgICAgICB0aHJvdyB0aGlzLmV4KCJwYXJzZXIuY2MuMiIsIHRoaXMub2Zmc2V0KTsKLSAgICAgICAgdG9rLnNvcnRSYW5nZXMoKTsKLSAgICAgICAgdG9rLmNvbXBhY3RSYW5nZXMoKTsKLSAgICAgICAgLy90b2suZHVtcFJhbmdlcygpOwotICAgICAgICB0aGlzLnNldENvbnRleHQoU19OT1JNQUwpOwotICAgICAgICB0aGlzLm5leHQoKTsgICAgICAgICAgICAgICAgICAgIC8vIFNraXBzICddJwotCi0gICAgICAgIHJldHVybiB0b2s7Ci0gICAgfQotCi0gICAgcHJvdGVjdGVkIFJhbmdlVG9rZW4gcGFyc2VTZXRPcGVyYXRpb25zKCkgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKLSAgICAgICAgdGhyb3cgdGhpcy5leCgicGFyc2VyLnByb2Nlc3MuMSIsIHRoaXMub2Zmc2V0KTsKLSAgICB9Ci0KLSAgICBUb2tlbiBnZXRUb2tlbkZvclNob3J0aGFuZChpbnQgY2gpIHsKLSAgICAgICAgc3dpdGNoIChjaCkgewotICAgICAgICAgIGNhc2UgJ2QnOgotICAgICAgICAgICAgcmV0dXJuIFBhcnNlckZvclhNTFNjaGVtYS5nZXRSYW5nZSgieG1sOmlzRGlnaXQiLCB0cnVlKTsKLSAgICAgICAgICBjYXNlICdEJzoKLSAgICAgICAgICAgIHJldHVybiBQYXJzZXJGb3JYTUxTY2hlbWEuZ2V0UmFuZ2UoInhtbDppc0RpZ2l0IiwgZmFsc2UpOwotICAgICAgICAgIGNhc2UgJ3cnOgotICAgICAgICAgICAgcmV0dXJuIFBhcnNlckZvclhNTFNjaGVtYS5nZXRSYW5nZSgieG1sOmlzV29yZCIsIHRydWUpOwotICAgICAgICAgIGNhc2UgJ1cnOgotICAgICAgICAgICAgcmV0dXJuIFBhcnNlckZvclhNTFNjaGVtYS5nZXRSYW5nZSgieG1sOmlzV29yZCIsIGZhbHNlKTsKLSAgICAgICAgICBjYXNlICdzJzoKLSAgICAgICAgICAgIHJldHVybiBQYXJzZXJGb3JYTUxTY2hlbWEuZ2V0UmFuZ2UoInhtbDppc1NwYWNlIiwgdHJ1ZSk7Ci0gICAgICAgICAgY2FzZSAnUyc6Ci0gICAgICAgICAgICByZXR1cm4gUGFyc2VyRm9yWE1MU2NoZW1hLmdldFJhbmdlKCJ4bWw6aXNTcGFjZSIsIGZhbHNlKTsKLSAgICAgICAgICBjYXNlICdjJzoKLSAgICAgICAgICAgIHJldHVybiBQYXJzZXJGb3JYTUxTY2hlbWEuZ2V0UmFuZ2UoInhtbDppc05hbWVDaGFyIiwgdHJ1ZSk7Ci0gICAgICAgICAgY2FzZSAnQyc6Ci0gICAgICAgICAgICByZXR1cm4gUGFyc2VyRm9yWE1MU2NoZW1hLmdldFJhbmdlKCJ4bWw6aXNOYW1lQ2hhciIsIGZhbHNlKTsKLSAgICAgICAgICBjYXNlICdpJzoKLSAgICAgICAgICAgIHJldHVybiBQYXJzZXJGb3JYTUxTY2hlbWEuZ2V0UmFuZ2UoInhtbDppc0luaXRpYWxOYW1lQ2hhciIsIHRydWUpOwotICAgICAgICAgIGNhc2UgJ0knOgotICAgICAgICAgICAgcmV0dXJuIFBhcnNlckZvclhNTFNjaGVtYS5nZXRSYW5nZSgieG1sOmlzSW5pdGlhbE5hbWVDaGFyIiwgZmFsc2UpOwotICAgICAgICAgIGRlZmF1bHQ6Ci0gICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiSW50ZXJuYWwgRXJyb3I6IHNob3J0aGFuZHM6IFxcdSIrSW50ZWdlci50b1N0cmluZyhjaCwgMTYpKTsKLSAgICAgICAgfQotICAgIH0KLSAgICBpbnQgZGVjb2RlRXNjYXBlZCgpIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmICh0aGlzLnJlYWQoKSAhPSBUX0JBQ0tTT0xJRFVTKSAgdGhyb3cgZXgoInBhcnNlci5uZXh0LjEiLCB0aGlzLm9mZnNldC0xKTsKLSAgICAgICAgaW50IGMgPSB0aGlzLmNoYXJkYXRhOwotICAgICAgICBzd2l0Y2ggKGMpIHsKLSAgICAgICAgICBjYXNlICduJzogIGMgPSAnXG4nOyAgYnJlYWs7IC8vIExJTkUgRkVFRCBVKzAwMEEKLSAgICAgICAgICBjYXNlICdyJzogIGMgPSAnXHInOyAgYnJlYWs7IC8vIENSUklBR0UgUkVUVVJOIFUrMDAwRAotICAgICAgICAgIGNhc2UgJ3QnOiAgYyA9ICdcdCc7ICBicmVhazsgLy8gSE9SSVpPTlRBTCBUQUJVTEFUSU9OIFUrMDAwOQotICAgICAgICAgIGNhc2UgJ1xcJzoKLSAgICAgICAgICBjYXNlICd8JzoKLSAgICAgICAgICBjYXNlICcuJzoKLSAgICAgICAgICBjYXNlICdeJzoKLSAgICAgICAgICBjYXNlICctJzoKLSAgICAgICAgICBjYXNlICc/JzoKLSAgICAgICAgICBjYXNlICcqJzoKLSAgICAgICAgICBjYXNlICcrJzoKLSAgICAgICAgICBjYXNlICd7JzoKLSAgICAgICAgICBjYXNlICd9JzoKLSAgICAgICAgICBjYXNlICcoJzoKLSAgICAgICAgICBjYXNlICcpJzoKLSAgICAgICAgICBjYXNlICdbJzoKLSAgICAgICAgICBjYXNlICddJzoKLSAgICAgICAgICAgIGJyZWFrOyAvLyByZXR1cm4gYWN0dWNhbCBjaGFyCi0gICAgICAgICAgZGVmYXVsdDoKLSAgICAgICAgICAgIHRocm93IGV4KCJwYXJzZXIucHJvY2Vzcy4xIiwgdGhpcy5vZmZzZXQtMik7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGM7Ci0gICAgfQotCi0gICAgc3RhdGljIHByaXZhdGUgTWFwPFN0cmluZywgVG9rZW4+IHJhbmdlcyA9IG51bGw7Ci0gICAgc3RhdGljIHByaXZhdGUgTWFwPFN0cmluZywgVG9rZW4+IHJhbmdlczIgPSBudWxsOwotICAgIHN0YXRpYyBzeW5jaHJvbml6ZWQgcHJvdGVjdGVkIFJhbmdlVG9rZW4gZ2V0UmFuZ2UoU3RyaW5nIG5hbWUsIGJvb2xlYW4gcG9zaXRpdmUpIHsKLSAgICAgICAgaWYgKHJhbmdlcyA9PSBudWxsKSB7Ci0gICAgICAgICAgICByYW5nZXMgPSBuZXcgSGFzaE1hcDw+KCk7Ci0gICAgICAgICAgICByYW5nZXMyID0gbmV3IEhhc2hNYXA8PigpOwotCi0gICAgICAgICAgICBUb2tlbiB0b2sgPSBUb2tlbi5jcmVhdGVSYW5nZSgpOwotICAgICAgICAgICAgc2V0dXBSYW5nZSh0b2ssIFNQQUNFUyk7Ci0gICAgICAgICAgICByYW5nZXMucHV0KCJ4bWw6aXNTcGFjZSIsIHRvayk7Ci0gICAgICAgICAgICByYW5nZXMyLnB1dCgieG1sOmlzU3BhY2UiLCBUb2tlbi5jb21wbGVtZW50UmFuZ2VzKHRvaykpOwotCi0gICAgICAgICAgICB0b2sgPSBUb2tlbi5jcmVhdGVSYW5nZSgpOwotICAgICAgICAgICAgc2V0dXBSYW5nZSh0b2ssIERJR0lUUyk7Ci0gICAgICAgICAgICBzZXR1cFJhbmdlKHRvaywgRElHSVRTX0lOVCk7Ci0gICAgICAgICAgICByYW5nZXMucHV0KCJ4bWw6aXNEaWdpdCIsIHRvayk7Ci0gICAgICAgICAgICByYW5nZXMyLnB1dCgieG1sOmlzRGlnaXQiLCBUb2tlbi5jb21wbGVtZW50UmFuZ2VzKHRvaykpOwotCi0gICAgICAgICAgICB0b2sgPSBUb2tlbi5jcmVhdGVSYW5nZSgpOwotICAgICAgICAgICAgc2V0dXBSYW5nZSh0b2ssIExFVFRFUlMpOwotICAgICAgICAgICAgc2V0dXBSYW5nZSh0b2ssIExFVFRFUlNfSU5UKTsKLSAgICAgICAgICAgIHRvay5tZXJnZVJhbmdlcyhyYW5nZXMuZ2V0KCJ4bWw6aXNEaWdpdCIpKTsKLSAgICAgICAgICAgIHJhbmdlcy5wdXQoInhtbDppc1dvcmQiLCB0b2spOwotICAgICAgICAgICAgcmFuZ2VzMi5wdXQoInhtbDppc1dvcmQiLCBUb2tlbi5jb21wbGVtZW50UmFuZ2VzKHRvaykpOwotCi0gICAgICAgICAgICB0b2sgPSBUb2tlbi5jcmVhdGVSYW5nZSgpOwotICAgICAgICAgICAgc2V0dXBSYW5nZSh0b2ssIE5BTUVDSEFSUyk7Ci0gICAgICAgICAgICByYW5nZXMucHV0KCJ4bWw6aXNOYW1lQ2hhciIsIHRvayk7Ci0gICAgICAgICAgICByYW5nZXMyLnB1dCgieG1sOmlzTmFtZUNoYXIiLCBUb2tlbi5jb21wbGVtZW50UmFuZ2VzKHRvaykpOwotCi0gICAgICAgICAgICB0b2sgPSBUb2tlbi5jcmVhdGVSYW5nZSgpOwotICAgICAgICAgICAgc2V0dXBSYW5nZSh0b2ssIExFVFRFUlMpOwotICAgICAgICAgICAgdG9rLmFkZFJhbmdlKCdfJywgJ18nKTsKLSAgICAgICAgICAgIHRvay5hZGRSYW5nZSgnOicsICc6Jyk7Ci0gICAgICAgICAgICByYW5nZXMucHV0KCJ4bWw6aXNJbml0aWFsTmFtZUNoYXIiLCB0b2spOwotICAgICAgICAgICAgcmFuZ2VzMi5wdXQoInhtbDppc0luaXRpYWxOYW1lQ2hhciIsIFRva2VuLmNvbXBsZW1lbnRSYW5nZXModG9rKSk7Ci0gICAgICAgIH0KLSAgICAgICAgUmFuZ2VUb2tlbiB0b2sgPSBwb3NpdGl2ZSA/IChSYW5nZVRva2VuKXJhbmdlcy5nZXQobmFtZSkKLSAgICAgICAgICAgIDogKFJhbmdlVG9rZW4pcmFuZ2VzMi5nZXQobmFtZSk7Ci0gICAgICAgIHJldHVybiB0b2s7Ci0gICAgfQotCi0gICAgc3RhdGljIHZvaWQgc2V0dXBSYW5nZShUb2tlbiByYW5nZSwgU3RyaW5nIHNyYykgewotICAgICAgICBpbnQgbGVuID0gc3JjLmxlbmd0aCgpOwotICAgICAgICBmb3IgKGludCBpID0gMDsgIGkgPCBsZW47ICBpICs9IDIpCi0gICAgICAgICAgICByYW5nZS5hZGRSYW5nZShzcmMuY2hhckF0KGkpLCBzcmMuY2hhckF0KGkrMSkpOwotICAgIH0KLQotICAgIHN0YXRpYyB2b2lkIHNldHVwUmFuZ2UoVG9rZW4gcmFuZ2UsIGludFtdIHNyYykgewotICAgICAgICBpbnQgbGVuID0gc3JjLmxlbmd0aDsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7ICBpIDwgbGVuOyAgaSArPSAyKQotICAgICAgICAgICAgcmFuZ2UuYWRkUmFuZ2Uoc3JjW2ldLCBzcmNbaSsxXSk7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFNQQUNFUyA9ICJcdFxuXHJcciAgIjsKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgTkFNRUNIQVJTID0KLSAgICAgICAgIlx1MDAyZFx1MDAyZVx1MDAzMFx1MDAzYVx1MDA0MVx1MDA1YVx1MDA1Zlx1MDA1Zlx1MDA2MVx1MDA3YVx1MDBiN1x1MDBiN1x1MDBjMFx1MDBkNiIKLSAgICAgICAgKyJcdTAwZDhcdTAwZjZcdTAwZjhcdTAxMzFcdTAxMzRcdTAxM2VcdTAxNDFcdTAxNDhcdTAxNGFcdTAxN2VcdTAxODBcdTAxYzNcdTAxY2RcdTAxZjAiCi0gICAgICAgICsiXHUwMWY0XHUwMWY1XHUwMWZhXHUwMjE3XHUwMjUwXHUwMmE4XHUwMmJiXHUwMmMxXHUwMmQwXHUwMmQxXHUwMzAwXHUwMzQ1XHUwMzYwXHUwMzYxIgotICAgICAgICArIlx1MDM4Nlx1MDM4YVx1MDM4Y1x1MDM4Y1x1MDM4ZVx1MDNhMVx1MDNhM1x1MDNjZVx1MDNkMFx1MDNkNlx1MDNkYVx1MDNkYVx1MDNkY1x1MDNkYyIKLSAgICAgICAgKyJcdTAzZGVcdTAzZGVcdTAzZTBcdTAzZTBcdTAzZTJcdTAzZjNcdTA0MDFcdTA0MGNcdTA0MGVcdTA0NGZcdTA0NTFcdTA0NWNcdTA0NWVcdTA0ODEiCi0gICAgICAgICsiXHUwNDgzXHUwNDg2XHUwNDkwXHUwNGM0XHUwNGM3XHUwNGM4XHUwNGNiXHUwNGNjXHUwNGQwXHUwNGViXHUwNGVlXHUwNGY1XHUwNGY4XHUwNGY5IgotICAgICAgICArIlx1MDUzMVx1MDU1Nlx1MDU1OVx1MDU1OVx1MDU2MVx1MDU4Nlx1MDU5MVx1MDVhMVx1MDVhM1x1MDViOVx1MDViYlx1MDViZFx1MDViZlx1MDViZiIKLSAgICAgICAgKyJcdTA1YzFcdTA1YzJcdTA1YzRcdTA1YzRcdTA1ZDBcdTA1ZWFcdTA1ZjBcdTA1ZjJcdTA2MjFcdTA2M2FcdTA2NDBcdTA2NTJcdTA2NjBcdTA2NjkiCi0gICAgICAgICsiXHUwNjcwXHUwNmI3XHUwNmJhXHUwNmJlXHUwNmMwXHUwNmNlXHUwNmQwXHUwNmQzXHUwNmQ1XHUwNmU4XHUwNmVhXHUwNmVkXHUwNmYwXHUwNmY5IgotICAgICAgICArIlx1MDkwMVx1MDkwM1x1MDkwNVx1MDkzOVx1MDkzY1x1MDk0ZFx1MDk1MVx1MDk1NFx1MDk1OFx1MDk2M1x1MDk2Nlx1MDk2Zlx1MDk4MVx1MDk4MyIKLSAgICAgICAgKyJcdTA5ODVcdTA5OGNcdTA5OGZcdTA5OTBcdTA5OTNcdTA5YThcdTA5YWFcdTA5YjBcdTA5YjJcdTA5YjJcdTA5YjZcdTA5YjlcdTA5YmNcdTA5YmMiCi0gICAgICAgICsiXHUwOWJlXHUwOWM0XHUwOWM3XHUwOWM4XHUwOWNiXHUwOWNkXHUwOWQ3XHUwOWQ3XHUwOWRjXHUwOWRkXHUwOWRmXHUwOWUzXHUwOWU2XHUwOWYxIgotICAgICAgICArIlx1MGEwMlx1MGEwMlx1MGEwNVx1MGEwYVx1MGEwZlx1MGExMFx1MGExM1x1MGEyOFx1MGEyYVx1MGEzMFx1MGEzMlx1MGEzM1x1MGEzNVx1MGEzNiIKLSAgICAgICAgKyJcdTBhMzhcdTBhMzlcdTBhM2NcdTBhM2NcdTBhM2VcdTBhNDJcdTBhNDdcdTBhNDhcdTBhNGJcdTBhNGRcdTBhNTlcdTBhNWNcdTBhNWVcdTBhNWUiCi0gICAgICAgICsiXHUwYTY2XHUwYTc0XHUwYTgxXHUwYTgzXHUwYTg1XHUwYThiXHUwYThkXHUwYThkXHUwYThmXHUwYTkxXHUwYTkzXHUwYWE4XHUwYWFhXHUwYWIwIgotICAgICAgICArIlx1MGFiMlx1MGFiM1x1MGFiNVx1MGFiOVx1MGFiY1x1MGFjNVx1MGFjN1x1MGFjOVx1MGFjYlx1MGFjZFx1MGFlMFx1MGFlMFx1MGFlNlx1MGFlZiIKLSAgICAgICAgKyJcdTBiMDFcdTBiMDNcdTBiMDVcdTBiMGNcdTBiMGZcdTBiMTBcdTBiMTNcdTBiMjhcdTBiMmFcdTBiMzBcdTBiMzJcdTBiMzNcdTBiMzZcdTBiMzkiCi0gICAgICAgICsiXHUwYjNjXHUwYjQzXHUwYjQ3XHUwYjQ4XHUwYjRiXHUwYjRkXHUwYjU2XHUwYjU3XHUwYjVjXHUwYjVkXHUwYjVmXHUwYjYxXHUwYjY2XHUwYjZmIgotICAgICAgICArIlx1MGI4Mlx1MGI4M1x1MGI4NVx1MGI4YVx1MGI4ZVx1MGI5MFx1MGI5Mlx1MGI5NVx1MGI5OVx1MGI5YVx1MGI5Y1x1MGI5Y1x1MGI5ZVx1MGI5ZiIKLSAgICAgICAgKyJcdTBiYTNcdTBiYTRcdTBiYThcdTBiYWFcdTBiYWVcdTBiYjVcdTBiYjdcdTBiYjlcdTBiYmVcdTBiYzJcdTBiYzZcdTBiYzhcdTBiY2FcdTBiY2QiCi0gICAgICAgICsiXHUwYmQ3XHUwYmQ3XHUwYmU3XHUwYmVmXHUwYzAxXHUwYzAzXHUwYzA1XHUwYzBjXHUwYzBlXHUwYzEwXHUwYzEyXHUwYzI4XHUwYzJhXHUwYzMzIgotICAgICAgICArIlx1MGMzNVx1MGMzOVx1MGMzZVx1MGM0NFx1MGM0Nlx1MGM0OFx1MGM0YVx1MGM0ZFx1MGM1NVx1MGM1Nlx1MGM2MFx1MGM2MVx1MGM2Nlx1MGM2ZiIKLSAgICAgICAgKyJcdTBjODJcdTBjODNcdTBjODVcdTBjOGNcdTBjOGVcdTBjOTBcdTBjOTJcdTBjYThcdTBjYWFcdTBjYjNcdTBjYjVcdTBjYjlcdTBjYmVcdTBjYzQiCi0gICAgICAgICsiXHUwY2M2XHUwY2M4XHUwY2NhXHUwY2NkXHUwY2Q1XHUwY2Q2XHUwY2RlXHUwY2RlXHUwY2UwXHUwY2UxXHUwY2U2XHUwY2VmXHUwZDAyXHUwZDAzIgotICAgICAgICArIlx1MGQwNVx1MGQwY1x1MGQwZVx1MGQxMFx1MGQxMlx1MGQyOFx1MGQyYVx1MGQzOVx1MGQzZVx1MGQ0M1x1MGQ0Nlx1MGQ0OFx1MGQ0YVx1MGQ0ZCIKLSAgICAgICAgKyJcdTBkNTdcdTBkNTdcdTBkNjBcdTBkNjFcdTBkNjZcdTBkNmZcdTBlMDFcdTBlMmVcdTBlMzBcdTBlM2FcdTBlNDBcdTBlNGVcdTBlNTBcdTBlNTkiCi0gICAgICAgICsiXHUwZTgxXHUwZTgyXHUwZTg0XHUwZTg0XHUwZTg3XHUwZTg4XHUwZThhXHUwZThhXHUwZThkXHUwZThkXHUwZTk0XHUwZTk3XHUwZTk5XHUwZTlmIgotICAgICAgICArIlx1MGVhMVx1MGVhM1x1MGVhNVx1MGVhNVx1MGVhN1x1MGVhN1x1MGVhYVx1MGVhYlx1MGVhZFx1MGVhZVx1MGViMFx1MGViOVx1MGViYlx1MGViZCIKLSAgICAgICAgKyJcdTBlYzBcdTBlYzRcdTBlYzZcdTBlYzZcdTBlYzhcdTBlY2RcdTBlZDBcdTBlZDlcdTBmMThcdTBmMTlcdTBmMjBcdTBmMjlcdTBmMzVcdTBmMzUiCi0gICAgICAgICsiXHUwZjM3XHUwZjM3XHUwZjM5XHUwZjM5XHUwZjNlXHUwZjQ3XHUwZjQ5XHUwZjY5XHUwZjcxXHUwZjg0XHUwZjg2XHUwZjhiXHUwZjkwXHUwZjk1IgotICAgICAgICArIlx1MGY5N1x1MGY5N1x1MGY5OVx1MGZhZFx1MGZiMVx1MGZiN1x1MGZiOVx1MGZiOVx1MTBhMFx1MTBjNVx1MTBkMFx1MTBmNlx1MTEwMFx1MTEwMCIKLSAgICAgICAgKyJcdTExMDJcdTExMDNcdTExMDVcdTExMDdcdTExMDlcdTExMDlcdTExMGJcdTExMGNcdTExMGVcdTExMTJcdTExM2NcdTExM2NcdTExM2VcdTExM2UiCi0gICAgICAgICsiXHUxMTQwXHUxMTQwXHUxMTRjXHUxMTRjXHUxMTRlXHUxMTRlXHUxMTUwXHUxMTUwXHUxMTU0XHUxMTU1XHUxMTU5XHUxMTU5XHUxMTVmXHUxMTYxIgotICAgICAgICArIlx1MTE2M1x1MTE2M1x1MTE2NVx1MTE2NVx1MTE2N1x1MTE2N1x1MTE2OVx1MTE2OVx1MTE2ZFx1MTE2ZVx1MTE3Mlx1MTE3M1x1MTE3NVx1MTE3NSIKLSAgICAgICAgKyJcdTExOWVcdTExOWVcdTExYThcdTExYThcdTExYWJcdTExYWJcdTExYWVcdTExYWZcdTExYjdcdTExYjhcdTExYmFcdTExYmFcdTExYmNcdTExYzIiCi0gICAgICAgICsiXHUxMWViXHUxMWViXHUxMWYwXHUxMWYwXHUxMWY5XHUxMWY5XHUxZTAwXHUxZTliXHUxZWEwXHUxZWY5XHUxZjAwXHUxZjE1XHUxZjE4XHUxZjFkIgotICAgICAgICArIlx1MWYyMFx1MWY0NVx1MWY0OFx1MWY0ZFx1MWY1MFx1MWY1N1x1MWY1OVx1MWY1OVx1MWY1Ylx1MWY1Ylx1MWY1ZFx1MWY1ZFx1MWY1Zlx1MWY3ZCIKLSAgICAgICAgKyJcdTFmODBcdTFmYjRcdTFmYjZcdTFmYmNcdTFmYmVcdTFmYmVcdTFmYzJcdTFmYzRcdTFmYzZcdTFmY2NcdTFmZDBcdTFmZDNcdTFmZDZcdTFmZGIiCi0gICAgICAgICsiXHUxZmUwXHUxZmVjXHUxZmYyXHUxZmY0XHUxZmY2XHUxZmZjXHUyMGQwXHUyMGRjXHUyMGUxXHUyMGUxXHUyMTI2XHUyMTI2XHUyMTJhXHUyMTJiIgotICAgICAgICArIlx1MjEyZVx1MjEyZVx1MjE4MFx1MjE4Mlx1MzAwNVx1MzAwNVx1MzAwN1x1MzAwN1x1MzAyMVx1MzAyZlx1MzAzMVx1MzAzNVx1MzA0MVx1MzA5NCIKLSAgICAgICAgKyJcdTMwOTlcdTMwOWFcdTMwOWRcdTMwOWVcdTMwYTFcdTMwZmFcdTMwZmNcdTMwZmVcdTMxMDVcdTMxMmNcdTRlMDBcdTlmYTVcdWFjMDBcdWQ3YTMiCi0gICAgICAgICsiIjsKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgTEVUVEVSUyA9Ci0gICAgICAgICJcdTAwNDFcdTAwNWFcdTAwNjFcdTAwN2FcdTAwYzBcdTAwZDZcdTAwZDhcdTAwZjZcdTAwZjhcdTAxMzFcdTAxMzRcdTAxM2VcdTAxNDFcdTAxNDgiCi0gICAgICAgICsiXHUwMTRhXHUwMTdlXHUwMTgwXHUwMWYwXHUwMWY0XHUwMWY1XHUwMWZhXHUwMjE3XHUwMjUwXHUwMmE4XHUwMmJiXHUwMmMxIgotICAgICAgICArIlx1MDJiMFx1MDJkMSIKLSAgICAgICAgKyJcdTAzODZcdTAzODZcdTAzODhcdTAzOGFcdTAzOGNcdTAzOGNcdTAzOGVcdTAzYTFcdTAzYTNcdTAzY2VcdTAzZDBcdTAzZDZcdTAzZGFcdTAzZGEiCi0gICAgICAgICsiXHUwM2RjXHUwM2RjXHUwM2RlXHUwM2RlXHUwM2UwXHUwM2UwXHUwM2UyXHUwM2YzXHUwNDAxXHUwNDBjXHUwNDBlXHUwNDRmXHUwNDUxXHUwNDVjIgotICAgICAgICArIlx1MDQ1ZVx1MDQ4MVx1MDQ5MFx1MDRjNFx1MDRjN1x1MDRjOFx1MDRjYlx1MDRjY1x1MDRkMFx1MDRlYlx1MDRlZVx1MDRmNVx1MDRmOFx1MDRmOSIKLSAgICAgICAgKyJcdTA1MzFcdTA1NTZcdTA1NTlcdTA1NTlcdTA1NjFcdTA1ODZcdTA1ZDBcdTA1ZWFcdTA1ZjBcdTA1ZjJcdTA2MjFcdTA2M2FcdTA2NDFcdTA2NGEiCi0gICAgICAgICsiXHUwNjcxXHUwNmI3XHUwNmJhXHUwNmJlXHUwNmMwXHUwNmNlXHUwNmQwXHUwNmQzXHUwNmQ1XHUwNmQ1XHUwNmU1XHUwNmU2XHUwOTA1XHUwOTM5IgotICAgICAgICArIlx1MDkzZFx1MDkzZFx1MDk1OFx1MDk2MVx1MDk4NVx1MDk4Y1x1MDk4Zlx1MDk5MFx1MDk5M1x1MDlhOFx1MDlhYVx1MDliMFx1MDliMlx1MDliMiIKLSAgICAgICAgKyJcdTA5YjZcdTA5YjlcdTA5ZGNcdTA5ZGRcdTA5ZGZcdTA5ZTFcdTA5ZjBcdTA5ZjFcdTBhMDVcdTBhMGFcdTBhMGZcdTBhMTBcdTBhMTNcdTBhMjgiCi0gICAgICAgICsiXHUwYTJhXHUwYTMwXHUwYTMyXHUwYTMzXHUwYTM1XHUwYTM2XHUwYTM4XHUwYTM5XHUwYTU5XHUwYTVjXHUwYTVlXHUwYTVlXHUwYTcyXHUwYTc0IgotICAgICAgICArIlx1MGE4NVx1MGE4Ylx1MGE4ZFx1MGE4ZFx1MGE4Zlx1MGE5MVx1MGE5M1x1MGFhOFx1MGFhYVx1MGFiMFx1MGFiMlx1MGFiM1x1MGFiNVx1MGFiOSIKLSAgICAgICAgKyJcdTBhYmRcdTBhYmRcdTBhZTBcdTBhZTBcdTBiMDVcdTBiMGNcdTBiMGZcdTBiMTBcdTBiMTNcdTBiMjhcdTBiMmFcdTBiMzBcdTBiMzJcdTBiMzMiCi0gICAgICAgICsiXHUwYjM2XHUwYjM5XHUwYjNkXHUwYjNkXHUwYjVjXHUwYjVkXHUwYjVmXHUwYjYxXHUwYjg1XHUwYjhhXHUwYjhlXHUwYjkwXHUwYjkyXHUwYjk1IgotICAgICAgICArIlx1MGI5OVx1MGI5YVx1MGI5Y1x1MGI5Y1x1MGI5ZVx1MGI5Zlx1MGJhM1x1MGJhNFx1MGJhOFx1MGJhYVx1MGJhZVx1MGJiNVx1MGJiN1x1MGJiOSIKLSAgICAgICAgKyJcdTBjMDVcdTBjMGNcdTBjMGVcdTBjMTBcdTBjMTJcdTBjMjhcdTBjMmFcdTBjMzNcdTBjMzVcdTBjMzlcdTBjNjBcdTBjNjFcdTBjODVcdTBjOGMiCi0gICAgICAgICsiXHUwYzhlXHUwYzkwXHUwYzkyXHUwY2E4XHUwY2FhXHUwY2IzXHUwY2I1XHUwY2I5XHUwY2RlXHUwY2RlXHUwY2UwXHUwY2UxXHUwZDA1XHUwZDBjIgotICAgICAgICArIlx1MGQwZVx1MGQxMFx1MGQxMlx1MGQyOFx1MGQyYVx1MGQzOVx1MGQ2MFx1MGQ2MVx1MGUwMVx1MGUyZVx1MGUzMFx1MGUzMFx1MGUzMlx1MGUzMyIKLSAgICAgICAgKyJcdTBlNDBcdTBlNDVcdTBlODFcdTBlODJcdTBlODRcdTBlODRcdTBlODdcdTBlODhcdTBlOGFcdTBlOGFcdTBlOGRcdTBlOGRcdTBlOTRcdTBlOTciCi0gICAgICAgICsiXHUwZTk5XHUwZTlmXHUwZWExXHUwZWEzXHUwZWE1XHUwZWE1XHUwZWE3XHUwZWE3XHUwZWFhXHUwZWFiXHUwZWFkXHUwZWFlXHUwZWIwXHUwZWIwIgotICAgICAgICArIlx1MGViMlx1MGViM1x1MGViZFx1MGViZFx1MGVjMFx1MGVjNFx1MGY0MFx1MGY0N1x1MGY0OVx1MGY2OVx1MTBhMFx1MTBjNVx1MTBkMFx1MTBmNiIKLSAgICAgICAgKyJcdTExMDBcdTExMDBcdTExMDJcdTExMDNcdTExMDVcdTExMDdcdTExMDlcdTExMDlcdTExMGJcdTExMGNcdTExMGVcdTExMTJcdTExM2NcdTExM2MiCi0gICAgICAgICsiXHUxMTNlXHUxMTNlXHUxMTQwXHUxMTQwXHUxMTRjXHUxMTRjXHUxMTRlXHUxMTRlXHUxMTUwXHUxMTUwXHUxMTU0XHUxMTU1XHUxMTU5XHUxMTU5IgotICAgICAgICArIlx1MTE1Zlx1MTE2MVx1MTE2M1x1MTE2M1x1MTE2NVx1MTE2NVx1MTE2N1x1MTE2N1x1MTE2OVx1MTE2OVx1MTE2ZFx1MTE2ZVx1MTE3Mlx1MTE3MyIKLSAgICAgICAgKyJcdTExNzVcdTExNzVcdTExOWVcdTExOWVcdTExYThcdTExYThcdTExYWJcdTExYWJcdTExYWVcdTExYWZcdTExYjdcdTExYjhcdTExYmFcdTExYmEiCi0gICAgICAgICsiXHUxMWJjXHUxMWMyXHUxMWViXHUxMWViXHUxMWYwXHUxMWYwXHUxMWY5XHUxMWY5XHUxZTAwXHUxZTliXHUxZWEwXHUxZWY5XHUxZjAwXHUxZjE1IgotICAgICAgICArIlx1MWYxOFx1MWYxZFx1MWYyMFx1MWY0NVx1MWY0OFx1MWY0ZFx1MWY1MFx1MWY1N1x1MWY1OVx1MWY1OVx1MWY1Ylx1MWY1Ylx1MWY1ZFx1MWY1ZCIKLSAgICAgICAgKyJcdTFmNWZcdTFmN2RcdTFmODBcdTFmYjRcdTFmYjZcdTFmYmNcdTFmYmVcdTFmYmVcdTFmYzJcdTFmYzRcdTFmYzZcdTFmY2NcdTFmZDBcdTFmZDMiCi0gICAgICAgICsiXHUxZmQ2XHUxZmRiXHUxZmUwXHUxZmVjXHUxZmYyXHUxZmY0XHUxZmY2XHUxZmZjXHUyMTI2XHUyMTI2XHUyMTJhXHUyMTJiXHUyMTJlXHUyMTJlIgotICAgICAgICArIlx1MjE4MFx1MjE4Mlx1MzAwN1x1MzAwN1x1MzAyMVx1MzAyOVx1MzA0MVx1MzA5NFx1MzBhMVx1MzBmYVx1MzEwNVx1MzEyY1x1NGUwMFx1OWZhNSIKLSAgICAgICAgKyJcdWFjMDBcdWQ3YTNcdWZmNjZcdWZmOWYiOwotCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50W10gTEVUVEVSU19JTlQgPSB7MHgxZDc5MCwgMHgxZDdhOCwgMHgxZDdhYSwgMHgxZDdjOSwgMHgyZmExYiwgMHgyZmExZH07Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRElHSVRTID0KLSAgICAgICAgIlx1MDAzMFx1MDAzOVx1MDY2MFx1MDY2OVx1MDZGMFx1MDZGOVx1MDk2Nlx1MDk2Rlx1MDlFNlx1MDlFRlx1MEE2Nlx1MEE2Rlx1MEFFNlx1MEFFRiIKLSAgICAgICAgKyJcdTBCNjZcdTBCNkZcdTBCRTdcdTBCRUZcdTBDNjZcdTBDNkZcdTBDRTZcdTBDRUZcdTBENjZcdTBENkZcdTBFNTBcdTBFNTlcdTBFRDBcdTBFRDkiCi0gICAgICAgICsiXHUwRjIwXHUwRjI5XHUxMDQwXHUxMDQ5XHUxMzY5XHUxMzcxXHUxN0UwXHUxN0U5XHUxODEwXHUxODE5XHVGRjEwXHVGRjE5IjsKLQotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludFtdIERJR0lUU19JTlQgPSB7MHgxRDdDRSwgMHgxRDdGRn07Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHBhdGgvcmVnZXgvUkVVdGlsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hwYXRoL3JlZ2V4L1JFVXRpbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4ZjBhN2Q2Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHBhdGgvcmVnZXgvUkVVdGlsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzMzUgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDAyLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cGF0aC5yZWdleDsKLQotaW1wb3J0IGphdmEudGV4dC5DaGFyYWN0ZXJJdGVyYXRvcjsKLQotLyoqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgUkVVdGlsIHsKLSAgICBwcml2YXRlIFJFVXRpbCgpIHsKLSAgICB9Ci0KLSAgICBzdGF0aWMgZmluYWwgaW50IGNvbXBvc2VGcm9tU3Vycm9nYXRlcyhpbnQgaGlnaCwgaW50IGxvdykgewotICAgICAgICByZXR1cm4gMHgxMDAwMCArICgoaGlnaC0weGQ4MDApPDwxMCkgKyBsb3ctMHhkYzAwOwotICAgIH0KLQotICAgIHN0YXRpYyBmaW5hbCBib29sZWFuIGlzTG93U3Vycm9nYXRlKGludCBjaCkgewotICAgICAgICByZXR1cm4gKGNoICYgMHhmYzAwKSA9PSAweGRjMDA7Ci0gICAgfQotCi0gICAgc3RhdGljIGZpbmFsIGJvb2xlYW4gaXNIaWdoU3Vycm9nYXRlKGludCBjaCkgewotICAgICAgICByZXR1cm4gKGNoICYgMHhmYzAwKSA9PSAweGQ4MDA7Ci0gICAgfQotCi0gICAgc3RhdGljIGZpbmFsIFN0cmluZyBkZWNvbXBvc2VUb1N1cnJvZ2F0ZXMoaW50IGNoKSB7Ci0gICAgICAgIGNoYXJbXSBjaHMgPSBuZXcgY2hhclsyXTsKLSAgICAgICAgY2ggLT0gMHgxMDAwMDsKLSAgICAgICAgY2hzWzBdID0gKGNoYXIpKChjaD4+MTApKzB4ZDgwMCk7Ci0gICAgICAgIGNoc1sxXSA9IChjaGFyKSgoY2gmMHgzZmYpKzB4ZGMwMCk7Ci0gICAgICAgIHJldHVybiBuZXcgU3RyaW5nKGNocyk7Ci0gICAgfQotCi0gICAgc3RhdGljIGZpbmFsIFN0cmluZyBzdWJzdHJpbmcoQ2hhcmFjdGVySXRlcmF0b3IgaXRlcmF0b3IsIGludCBiZWdpbiwgaW50IGVuZCkgewotICAgICAgICBjaGFyW10gc3JjID0gbmV3IGNoYXJbZW5kLWJlZ2luXTsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7ICBpIDwgc3JjLmxlbmd0aDsgIGkgKyspCi0gICAgICAgICAgICBzcmNbaV0gPSBpdGVyYXRvci5zZXRJbmRleChpK2JlZ2luKTsKLSAgICAgICAgcmV0dXJuIG5ldyBTdHJpbmcoc3JjKTsKLSAgICB9Ci0KLSAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0KLSAgICBzdGF0aWMgZmluYWwgaW50IGdldE9wdGlvblZhbHVlKGludCBjaCkgewotICAgICAgICBpbnQgcmV0ID0gMDsKLSAgICAgICAgc3dpdGNoIChjaCkgewotICAgICAgICAgIGNhc2UgJ2knOgotICAgICAgICAgICAgcmV0ID0gUmVndWxhckV4cHJlc3Npb24uSUdOT1JFX0NBU0U7Ci0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgICBjYXNlICdtJzoKLSAgICAgICAgICAgIHJldCA9IFJlZ3VsYXJFeHByZXNzaW9uLk1VTFRJUExFX0xJTkVTOwotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgY2FzZSAncyc6Ci0gICAgICAgICAgICByZXQgPSBSZWd1bGFyRXhwcmVzc2lvbi5TSU5HTEVfTElORTsKLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgIGNhc2UgJ3gnOgotICAgICAgICAgICAgcmV0ID0gUmVndWxhckV4cHJlc3Npb24uRVhURU5ERURfQ09NTUVOVDsKLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgIGNhc2UgJ3UnOgotICAgICAgICAgICAgcmV0ID0gUmVndWxhckV4cHJlc3Npb24uVVNFX1VOSUNPREVfQ0FURUdPUlk7Ci0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgICBjYXNlICd3JzoKLSAgICAgICAgICAgIHJldCA9IFJlZ3VsYXJFeHByZXNzaW9uLlVOSUNPREVfV09SRF9CT1VOREFSWTsKLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgIGNhc2UgJ0YnOgotICAgICAgICAgICAgcmV0ID0gUmVndWxhckV4cHJlc3Npb24uUFJPSElCSVRfRklYRURfU1RSSU5HX09QVElNSVpBVElPTjsKLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgIGNhc2UgJ0gnOgotICAgICAgICAgICAgcmV0ID0gUmVndWxhckV4cHJlc3Npb24uUFJPSElCSVRfSEVBRF9DSEFSQUNURVJfT1BUSU1JWkFUSU9OOwotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgY2FzZSAnWCc6Ci0gICAgICAgICAgICByZXQgPSBSZWd1bGFyRXhwcmVzc2lvbi5YTUxTQ0hFTUFfTU9ERTsKLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgIGNhc2UgJywnOgotICAgICAgICAgICAgcmV0ID0gUmVndWxhckV4cHJlc3Npb24uU1BFQ0lBTF9DT01NQTsKLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgIGRlZmF1bHQ6Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHJldDsKLSAgICB9Ci0KLSAgICBzdGF0aWMgZmluYWwgaW50IHBhcnNlT3B0aW9ucyhTdHJpbmcgb3B0cykgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKG9wdHMgPT0gbnVsbCkgIHJldHVybiAwOwotICAgICAgICBpbnQgb3B0aW9ucyA9IDA7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyAgaSA8IG9wdHMubGVuZ3RoKCk7ICBpICsrKSB7Ci0gICAgICAgICAgICBpbnQgdiA9IGdldE9wdGlvblZhbHVlKG9wdHMuY2hhckF0KGkpKTsKLSAgICAgICAgICAgIGlmICh2ID09IDApCi0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlRXhjZXB0aW9uKCJVbmtub3duIE9wdGlvbjogIitvcHRzLnN1YnN0cmluZyhpKSwgLTEpOwotICAgICAgICAgICAgb3B0aW9ucyB8PSB2OwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBvcHRpb25zOwotICAgIH0KLQotICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgY3JlYXRlT3B0aW9uU3RyaW5nKGludCBvcHRpb25zKSB7Ci0gICAgICAgIFN0cmluZ0J1ZmZlciBzYiA9IG5ldyBTdHJpbmdCdWZmZXIoOSk7Ci0gICAgICAgIGlmICgob3B0aW9ucyAmIFJlZ3VsYXJFeHByZXNzaW9uLlBST0hJQklUX0ZJWEVEX1NUUklOR19PUFRJTUlaQVRJT04pICE9IDApCi0gICAgICAgICAgICBzYi5hcHBlbmQoKGNoYXIpJ0YnKTsKLSAgICAgICAgaWYgKChvcHRpb25zICYgUmVndWxhckV4cHJlc3Npb24uUFJPSElCSVRfSEVBRF9DSEFSQUNURVJfT1BUSU1JWkFUSU9OKSAhPSAwKQotICAgICAgICAgICAgc2IuYXBwZW5kKChjaGFyKSdIJyk7Ci0gICAgICAgIGlmICgob3B0aW9ucyAmIFJlZ3VsYXJFeHByZXNzaW9uLlhNTFNDSEVNQV9NT0RFKSAhPSAwKQotICAgICAgICAgICAgc2IuYXBwZW5kKChjaGFyKSdYJyk7Ci0gICAgICAgIGlmICgob3B0aW9ucyAmIFJlZ3VsYXJFeHByZXNzaW9uLklHTk9SRV9DQVNFKSAhPSAwKQotICAgICAgICAgICAgc2IuYXBwZW5kKChjaGFyKSdpJyk7Ci0gICAgICAgIGlmICgob3B0aW9ucyAmIFJlZ3VsYXJFeHByZXNzaW9uLk1VTFRJUExFX0xJTkVTKSAhPSAwKQotICAgICAgICAgICAgc2IuYXBwZW5kKChjaGFyKSdtJyk7Ci0gICAgICAgIGlmICgob3B0aW9ucyAmIFJlZ3VsYXJFeHByZXNzaW9uLlNJTkdMRV9MSU5FKSAhPSAwKQotICAgICAgICAgICAgc2IuYXBwZW5kKChjaGFyKSdzJyk7Ci0gICAgICAgIGlmICgob3B0aW9ucyAmIFJlZ3VsYXJFeHByZXNzaW9uLlVTRV9VTklDT0RFX0NBVEVHT1JZKSAhPSAwKQotICAgICAgICAgICAgc2IuYXBwZW5kKChjaGFyKSd1Jyk7Ci0gICAgICAgIGlmICgob3B0aW9ucyAmIFJlZ3VsYXJFeHByZXNzaW9uLlVOSUNPREVfV09SRF9CT1VOREFSWSkgIT0gMCkKLSAgICAgICAgICAgIHNiLmFwcGVuZCgoY2hhcikndycpOwotICAgICAgICBpZiAoKG9wdGlvbnMgJiBSZWd1bGFyRXhwcmVzc2lvbi5FWFRFTkRFRF9DT01NRU5UKSAhPSAwKQotICAgICAgICAgICAgc2IuYXBwZW5kKChjaGFyKSd4Jyk7Ci0gICAgICAgIGlmICgob3B0aW9ucyAmIFJlZ3VsYXJFeHByZXNzaW9uLlNQRUNJQUxfQ09NTUEpICE9IDApCi0gICAgICAgICAgICBzYi5hcHBlbmQoKGNoYXIpJywnKTsKLSAgICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCkuaW50ZXJuKCk7Ci0gICAgfQotCi0gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotCi0gICAgc3RhdGljIFN0cmluZyBzdHJpcEV4dGVuZGVkQ29tbWVudChTdHJpbmcgcmVnZXgpIHsKLSAgICAgICAgaW50IGxlbiA9IHJlZ2V4Lmxlbmd0aCgpOwotICAgICAgICBTdHJpbmdCdWZmZXIgYnVmZmVyID0gbmV3IFN0cmluZ0J1ZmZlcihsZW4pOwotICAgICAgICBpbnQgb2Zmc2V0ID0gMDsKLSAgICAgICAgd2hpbGUgKG9mZnNldCA8IGxlbikgewotICAgICAgICAgICAgaW50IGNoID0gcmVnZXguY2hhckF0KG9mZnNldCsrKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNraXBzIGEgd2hpdGUgc3BhY2UuCi0gICAgICAgICAgICBpZiAoY2ggPT0gJ1x0JyB8fCBjaCA9PSAnXG4nIHx8IGNoID09ICdcZicgfHwgY2ggPT0gJ1xyJyB8fCBjaCA9PSAnICcpCi0gICAgICAgICAgICAgICAgY29udGludWU7Ci0KLSAgICAgICAgICAgIGlmIChjaCA9PSAnIycpIHsgICAgICAgICAgICAgICAgICAgIC8vIFNraXBzIGNocmFjdGVycyBiZXR3ZWVuICcjJyBhbmQgYSBsaW5lIGVuZC4KLSAgICAgICAgICAgICAgICB3aGlsZSAob2Zmc2V0IDwgbGVuKSB7Ci0gICAgICAgICAgICAgICAgICAgIGNoID0gcmVnZXguY2hhckF0KG9mZnNldCsrKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGNoID09ICdccicgfHwgY2ggPT0gJ1xuJykKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaW50IG5leHQ7ICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU3RyaXBzIGFuIGVzY2FwZWQgd2hpdGUgc3BhY2UuCi0gICAgICAgICAgICBpZiAoY2ggPT0gJ1xcJyAmJiBvZmZzZXQgPCBsZW4pIHsKLSAgICAgICAgICAgICAgICBpZiAoKG5leHQgPSByZWdleC5jaGFyQXQob2Zmc2V0KSkgPT0gJyMnCi0gICAgICAgICAgICAgICAgICAgIHx8IG5leHQgPT0gJ1x0JyB8fCBuZXh0ID09ICdcbicgfHwgbmV4dCA9PSAnXGYnCi0gICAgICAgICAgICAgICAgICAgIHx8IG5leHQgPT0gJ1xyJyB8fCBuZXh0ID09ICcgJykgewotICAgICAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKChjaGFyKW5leHQpOwotICAgICAgICAgICAgICAgICAgICBvZmZzZXQgKys7Ci0gICAgICAgICAgICAgICAgfSBlbHNlIHsgICAgICAgICAgICAgICAgICAgICAgICAvLyBPdGhlciBlc2NhcGVkIGNoYXJhY3Rlci4KLSAgICAgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgoY2hhciknXFwnKTsKLSAgICAgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgoY2hhciluZXh0KTsKLSAgICAgICAgICAgICAgICAgICAgb2Zmc2V0ICsrOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0gZWxzZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEFzIGlzLgotICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoKGNoYXIpY2gpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBidWZmZXIudG9TdHJpbmcoKTsKLSAgICB9Ci0KLSAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0KLSAgICAvKioKLSAgICAgKiBTYW1wbGUgZW50cnkuCi0gICAgICogPGRpdj5Vc2FnZTogPEtCRD5jb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWxzLnJlZ2V4LlJFVXRpbCAmbHQ7cmVnZXgmZ3Q7ICZsdDtzdHJpbmcmZ3Q7PC9LQkQ+PC9kaXY+Ci0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nW10gYXJndikgewotICAgICAgICBTdHJpbmcgcGF0dGVybiA9IG51bGw7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBTdHJpbmcgb3B0aW9ucyA9ICIiOwotICAgICAgICAgICAgU3RyaW5nIHRhcmdldCA9IG51bGw7Ci0gICAgICAgICAgICBpZiggYXJndi5sZW5ndGggPT0gMCApIHsKLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oICJFcnJvcjpVc2FnZTogamF2YSBSRVV0aWwgLWl8LW18LXN8LXV8LXd8LVggcmVndWxhckV4cHJlc3Npb24gU3RyaW5nIiApOwotICAgICAgICAgICAgICAgIFN5c3RlbS5leGl0KCAwICk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgIGkgPCBhcmd2Lmxlbmd0aDsgIGkgKyspIHsKLSAgICAgICAgICAgICAgICBpZiAoYXJndltpXS5sZW5ndGgoKSA9PSAwIHx8IGFyZ3ZbaV0uY2hhckF0KDApICE9ICctJykgewotICAgICAgICAgICAgICAgICAgICBpZiAocGF0dGVybiA9PSBudWxsKQotICAgICAgICAgICAgICAgICAgICAgICAgcGF0dGVybiA9IGFyZ3ZbaV07Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHRhcmdldCA9PSBudWxsKQotICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0ID0gYXJndltpXTsKLSAgICAgICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJVbm5lY2Vzc2FyeTogIithcmd2W2ldKTsKLSAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGFyZ3ZbaV0uZXF1YWxzKCItaSIpKSB7Ci0gICAgICAgICAgICAgICAgICAgIG9wdGlvbnMgKz0gImkiOwotICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYXJndltpXS5lcXVhbHMoIi1tIikpIHsKLSAgICAgICAgICAgICAgICAgICAgb3B0aW9ucyArPSAibSI7Ci0gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChhcmd2W2ldLmVxdWFscygiLXMiKSkgewotICAgICAgICAgICAgICAgICAgICBvcHRpb25zICs9ICJzIjsKLSAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGFyZ3ZbaV0uZXF1YWxzKCItdSIpKSB7Ci0gICAgICAgICAgICAgICAgICAgIG9wdGlvbnMgKz0gInUiOwotICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYXJndltpXS5lcXVhbHMoIi13IikpIHsKLSAgICAgICAgICAgICAgICAgICAgb3B0aW9ucyArPSAidyI7Ci0gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChhcmd2W2ldLmVxdWFscygiLVgiKSkgewotICAgICAgICAgICAgICAgICAgICBvcHRpb25zICs9ICJYIjsKLSAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIlVua25vd24gb3B0aW9uOiAiK2FyZ3ZbaV0pOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIFJlZ3VsYXJFeHByZXNzaW9uIHJlZyA9IG5ldyBSZWd1bGFyRXhwcmVzc2lvbihwYXR0ZXJuLCBvcHRpb25zKTsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiUmVndWxhckV4cHJlc3Npb246ICIrcmVnKTsKLSAgICAgICAgICAgIE1hdGNoIG1hdGNoID0gbmV3IE1hdGNoKCk7Ci0gICAgICAgICAgICByZWcubWF0Y2hlcyh0YXJnZXQsIG1hdGNoKTsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyAgaSA8IG1hdGNoLmdldE51bWJlck9mR3JvdXBzKCk7ICBpICsrKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGkgPT0gMCApICBTeXN0ZW0ub3V0LnByaW50KCJNYXRjaGVkIHJhbmdlIGZvciB0aGUgd2hvbGUgcGF0dGVybjogIik7Ci0gICAgICAgICAgICAgICAgZWxzZSBTeXN0ZW0ub3V0LnByaW50KCJbIitpKyJdOiAiKTsKLSAgICAgICAgICAgICAgICBpZiAobWF0Y2guZ2V0QmVnaW5uaW5nKGkpIDwgMCkKLSAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCItMSIpOwotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KG1hdGNoLmdldEJlZ2lubmluZyhpKSsiLCAiK21hdGNoLmdldEVuZChpKSsiLCAiKTsKLSAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJcIiIrbWF0Y2guZ2V0Q2FwdHVyZWRUZXh0KGkpKyJcIiIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfSBjYXRjaCAoUGFyc2VFeGNlcHRpb24gcGUpIHsKLSAgICAgICAgICAgIGlmIChwYXR0ZXJuID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBwZS5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWxzLnJlZ2V4LlBhcnNlRXhjZXB0aW9uOiAiK3BlLmdldE1lc3NhZ2UoKSk7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIGluZGVudCA9ICIgICAgICAgICI7Ci0gICAgICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKGluZGVudCtwYXR0ZXJuKTsKLSAgICAgICAgICAgICAgICBpbnQgbG9jID0gcGUuZ2V0TG9jYXRpb24oKTsKLSAgICAgICAgICAgICAgICBpZiAobG9jID49IDApIHsKLSAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludChpbmRlbnQpOwotICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgIGkgPCBsb2M7ICBpICsrKSAgU3lzdGVtLmVyci5wcmludCgiLSIpOwotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIl4iKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgc3RhdGljIGZpbmFsIGludCBDQUNIRVNJWkUgPSAyMDsKLSAgICBzdGF0aWMgZmluYWwgUmVndWxhckV4cHJlc3Npb25bXSByZWdleENhY2hlID0gbmV3IFJlZ3VsYXJFeHByZXNzaW9uW0NBQ0hFU0laRV07Ci0gICAgLyoqCi0gICAgICogQ3JlYXRlcyBhIFJlZ3VsYXJFeHByZXNzaW9uIGluc3RhbmNlLgotICAgICAqIFRoaXMgbWV0aG9kIGNhY2hlcyBjcmVhdGVkIGluc3RhbmNlcy4KLSAgICAgKgotICAgICAqIEBzZWUgUmVndWxhckV4cHJlc3Npb24jUmVndWxhckV4cHJlc3Npb24oamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZykKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFJlZ3VsYXJFeHByZXNzaW9uIGNyZWF0ZVJlZ2V4KFN0cmluZyBwYXR0ZXJuLCBTdHJpbmcgb3B0aW9ucykKLSAgICAgICAgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKLSAgICAgICAgUmVndWxhckV4cHJlc3Npb24gcmUgPSBudWxsOwotICAgICAgICBpbnQgaW50T3B0aW9ucyA9IFJFVXRpbC5wYXJzZU9wdGlvbnMob3B0aW9ucyk7Ci0gICAgICAgIHN5bmNocm9uaXplZCAoUkVVdGlsLnJlZ2V4Q2FjaGUpIHsKLSAgICAgICAgICAgIGludCBpOwotICAgICAgICAgICAgZm9yIChpID0gMDsgIGkgPCBSRVV0aWwuQ0FDSEVTSVpFOyAgaSArKykgewotICAgICAgICAgICAgICAgIFJlZ3VsYXJFeHByZXNzaW9uIGNhY2hlZCA9IFJFVXRpbC5yZWdleENhY2hlW2ldOwotICAgICAgICAgICAgICAgIGlmIChjYWNoZWQgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBpID0gLTE7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpZiAoY2FjaGVkLmVxdWFscyhwYXR0ZXJuLCBpbnRPcHRpb25zKSkgewotICAgICAgICAgICAgICAgICAgICByZSA9IGNhY2hlZDsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKHJlICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBpZiAoaSAhPSAwKSB7Ci0gICAgICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoUkVVdGlsLnJlZ2V4Q2FjaGUsIDAsIFJFVXRpbC5yZWdleENhY2hlLCAxLCBpKTsKLSAgICAgICAgICAgICAgICAgICAgUkVVdGlsLnJlZ2V4Q2FjaGVbMF0gPSByZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIHJlID0gbmV3IFJlZ3VsYXJFeHByZXNzaW9uKHBhdHRlcm4sIG9wdGlvbnMpOwotICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoUkVVdGlsLnJlZ2V4Q2FjaGUsIDAsIFJFVXRpbC5yZWdleENhY2hlLCAxLCBSRVV0aWwuQ0FDSEVTSVpFLTEpOwotICAgICAgICAgICAgICAgIFJFVXRpbC5yZWdleENhY2hlWzBdID0gcmU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHJlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqCi0gICAgICogQHNlZSBSZWd1bGFyRXhwcmVzc2lvbiNtYXRjaGVzKGphdmEubGFuZy5TdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBib29sZWFuIG1hdGNoZXMoU3RyaW5nIHJlZ2V4LCBTdHJpbmcgdGFyZ2V0KSB0aHJvd3MgUGFyc2VFeGNlcHRpb24gewotICAgICAgICByZXR1cm4gUkVVdGlsLmNyZWF0ZVJlZ2V4KHJlZ2V4LCBudWxsKS5tYXRjaGVzKHRhcmdldCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICoKLSAgICAgKiBAc2VlIFJlZ3VsYXJFeHByZXNzaW9uI21hdGNoZXMoamF2YS5sYW5nLlN0cmluZykKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gbWF0Y2hlcyhTdHJpbmcgcmVnZXgsIFN0cmluZyBvcHRpb25zLCBTdHJpbmcgdGFyZ2V0KSB0aHJvd3MgUGFyc2VFeGNlcHRpb24gewotICAgICAgICByZXR1cm4gUkVVdGlsLmNyZWF0ZVJlZ2V4KHJlZ2V4LCBvcHRpb25zKS5tYXRjaGVzKHRhcmdldCk7Ci0gICAgfQotCi0gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotCi0gICAgLyoqCi0gICAgICoKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBxdW90ZU1ldGEoU3RyaW5nIGxpdGVyYWwpIHsKLSAgICAgICAgaW50IGxlbiA9IGxpdGVyYWwubGVuZ3RoKCk7Ci0gICAgICAgIFN0cmluZ0J1ZmZlciBidWZmZXIgPSBudWxsOwotICAgICAgICBmb3IgKGludCBpID0gMDsgIGkgPCBsZW47ICBpICsrKSB7Ci0gICAgICAgICAgICBpbnQgY2ggPSBsaXRlcmFsLmNoYXJBdChpKTsKLSAgICAgICAgICAgIGlmICgiLiorP3tbKCl8XFxeJCIuaW5kZXhPZihjaCkgPj0gMCkgewotICAgICAgICAgICAgICAgIGlmIChidWZmZXIgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBidWZmZXIgPSBuZXcgU3RyaW5nQnVmZmVyKGkrKGxlbi1pKSoyKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGkgPiAwKSAgYnVmZmVyLmFwcGVuZChsaXRlcmFsLnN1YnN0cmluZygwLCBpKSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoKGNoYXIpJ1xcJyk7Ci0gICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgoY2hhciljaCk7Ci0gICAgICAgICAgICB9IGVsc2UgaWYgKGJ1ZmZlciAhPSBudWxsKQotICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoKGNoYXIpY2gpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBidWZmZXIgIT0gbnVsbCA/IGJ1ZmZlci50b1N0cmluZygpIDogbGl0ZXJhbDsKLSAgICB9Ci0KLSAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0KLSAgICBzdGF0aWMgdm9pZCBkdW1wU3RyaW5nKFN0cmluZyB2KSB7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyAgaSA8IHYubGVuZ3RoKCk7ICBpICsrKSB7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KEludGVnZXIudG9IZXhTdHJpbmcodi5jaGFyQXQoaSkpKTsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIiAiKTsKLSAgICAgICAgfQotICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hwYXRoL3JlZ2V4L1JhbmdlVG9rZW4uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHBhdGgvcmVnZXgvUmFuZ2VUb2tlbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzYTdhYzcwLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHBhdGgvcmVnZXgvUmFuZ2VUb2tlbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNjIzICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwMiwyMDA0LDIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cGF0aC5yZWdleDsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIHJlcHJlc2VudHMgYSBjaGFyYWN0ZXIgY2xhc3Mgc3VjaCBhcyBbYS16XSBvciBhIHBlcmlvZC4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICovCi1maW5hbCBjbGFzcyBSYW5nZVRva2VuIGV4dGVuZHMgVG9rZW4gaW1wbGVtZW50cyBqYXZhLmlvLlNlcmlhbGl6YWJsZSB7Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAzMjU3NTY4Mzk5NTkyMDEwNTQ1TDsKLQotICAgIGludFtdIHJhbmdlczsKLSAgICBib29sZWFuIHNvcnRlZDsKLSAgICBib29sZWFuIGNvbXBhY3RlZDsKLSAgICBSYW5nZVRva2VuIGljYXNlQ2FjaGUgPSBudWxsOwotICAgIGludFtdIG1hcCA9IG51bGw7Ci0gICAgaW50IG5vbk1hcEluZGV4OwotCi0gICAgUmFuZ2VUb2tlbihpbnQgdHlwZSkgewotICAgICAgICBzdXBlcih0eXBlKTsKLSAgICAgICAgdGhpcy5zZXRTb3J0ZWQoZmFsc2UpOwotICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZm9yIFJBTkdFIG9yIE5SQU5HRQotICAgIHByb3RlY3RlZCB2b2lkIGFkZFJhbmdlKGludCBzdGFydCwgaW50IGVuZCkgewotICAgICAgICB0aGlzLmljYXNlQ2FjaGUgPSBudWxsOwotICAgICAgICAvL1N5c3RlbS5lcnIucHJpbnRsbigiVG9rZW4jYWRkUmFuZ2UoKTogIitzdGFydCsiICIrZW5kKTsKLSAgICAgICAgaW50IHIxLCByMjsKLSAgICAgICAgaWYgKHN0YXJ0IDw9IGVuZCkgewotICAgICAgICAgICAgcjEgPSBzdGFydDsKLSAgICAgICAgICAgIHIyID0gZW5kOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgcjEgPSBlbmQ7Ci0gICAgICAgICAgICByMiA9IHN0YXJ0OwotICAgICAgICB9Ci0KLSAgICAgICAgaW50IHBvcyA9IDA7Ci0gICAgICAgIGlmICh0aGlzLnJhbmdlcyA9PSBudWxsKSB7Ci0gICAgICAgICAgICB0aGlzLnJhbmdlcyA9IG5ldyBpbnRbMl07Ci0gICAgICAgICAgICB0aGlzLnJhbmdlc1swXSA9IHIxOwotICAgICAgICAgICAgdGhpcy5yYW5nZXNbMV0gPSByMjsKLSAgICAgICAgICAgIHRoaXMuc2V0U29ydGVkKHRydWUpOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgcG9zID0gdGhpcy5yYW5nZXMubGVuZ3RoOwotICAgICAgICAgICAgaWYgKHRoaXMucmFuZ2VzW3Bvcy0xXSsxID09IHIxKSB7Ci0gICAgICAgICAgICAgICAgdGhpcy5yYW5nZXNbcG9zLTFdID0gcjI7Ci0gICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaW50W10gdGVtcCA9IG5ldyBpbnRbcG9zKzJdOwotICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weSh0aGlzLnJhbmdlcywgMCwgdGVtcCwgMCwgcG9zKTsKLSAgICAgICAgICAgIHRoaXMucmFuZ2VzID0gdGVtcDsKLSAgICAgICAgICAgIGlmICh0aGlzLnJhbmdlc1twb3MtMV0gPj0gcjEpCi0gICAgICAgICAgICAgICAgdGhpcy5zZXRTb3J0ZWQoZmFsc2UpOwotICAgICAgICAgICAgdGhpcy5yYW5nZXNbcG9zKytdID0gcjE7Ci0gICAgICAgICAgICB0aGlzLnJhbmdlc1twb3NdID0gcjI7Ci0gICAgICAgICAgICBpZiAoIXRoaXMuc29ydGVkKQotICAgICAgICAgICAgICAgIHRoaXMuc29ydFJhbmdlcygpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIGlzU29ydGVkKCkgewotICAgICAgICByZXR1cm4gdGhpcy5zb3J0ZWQ7Ci0gICAgfQotICAgIHByaXZhdGUgZmluYWwgdm9pZCBzZXRTb3J0ZWQoYm9vbGVhbiBzb3J0KSB7Ci0gICAgICAgIHRoaXMuc29ydGVkID0gc29ydDsKLSAgICAgICAgaWYgKCFzb3J0KSAgdGhpcy5jb21wYWN0ZWQgPSBmYWxzZTsKLSAgICB9Ci0gICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIGlzQ29tcGFjdGVkKCkgewotICAgICAgICByZXR1cm4gdGhpcy5jb21wYWN0ZWQ7Ci0gICAgfQotICAgIHByaXZhdGUgZmluYWwgdm9pZCBzZXRDb21wYWN0ZWQoKSB7Ci0gICAgICAgIHRoaXMuY29tcGFjdGVkID0gdHJ1ZTsKLSAgICB9Ci0KLSAgICBwcm90ZWN0ZWQgdm9pZCBzb3J0UmFuZ2VzKCkgewotICAgICAgICBpZiAodGhpcy5pc1NvcnRlZCgpKQotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICBpZiAodGhpcy5yYW5nZXMgPT0gbnVsbCkKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgLy9TeXN0ZW0uZXJyLnByaW50bG4oIkRvIHNvcnRpbmc6ICIrdGhpcy5yYW5nZXMubGVuZ3RoKTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQnViYmxlIHNvcnQKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdoeT8gLS0gSW4gbWFueSBjYXNlcywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgICAgICAgdGhpcy5yYW5nZXMgaGFzIGZldyBlbGVtZW50cy4KLSAgICAgICAgZm9yIChpbnQgaSA9IHRoaXMucmFuZ2VzLmxlbmd0aC00OyAgaSA+PSAwOyAgaSAtPSAyKSB7Ci0gICAgICAgICAgICBmb3IgKGludCBqID0gMDsgIGogPD0gaTsgIGogKz0gMikgewotICAgICAgICAgICAgICAgIGlmICh0aGlzLnJhbmdlc1tqXSA+IHRoaXMucmFuZ2VzW2orMl0KLSAgICAgICAgICAgICAgICAgICAgfHwgdGhpcy5yYW5nZXNbal0gPT0gdGhpcy5yYW5nZXNbaisyXSAmJiB0aGlzLnJhbmdlc1tqKzFdID4gdGhpcy5yYW5nZXNbaiszXSkgewotICAgICAgICAgICAgICAgICAgICBpbnQgdG1wOwotICAgICAgICAgICAgICAgICAgICB0bXAgPSB0aGlzLnJhbmdlc1tqKzJdOwotICAgICAgICAgICAgICAgICAgICB0aGlzLnJhbmdlc1tqKzJdID0gdGhpcy5yYW5nZXNbal07Ci0gICAgICAgICAgICAgICAgICAgIHRoaXMucmFuZ2VzW2pdID0gdG1wOwotICAgICAgICAgICAgICAgICAgICB0bXAgPSB0aGlzLnJhbmdlc1tqKzNdOwotICAgICAgICAgICAgICAgICAgICB0aGlzLnJhbmdlc1tqKzNdID0gdGhpcy5yYW5nZXNbaisxXTsKLSAgICAgICAgICAgICAgICAgICAgdGhpcy5yYW5nZXNbaisxXSA9IHRtcDsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgdGhpcy5zZXRTb3J0ZWQodHJ1ZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogdGhpcy5yYW5nZXMgaXMgc29ydGVkLgotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIGNvbXBhY3RSYW5nZXMoKSB7Ci0gICAgICAgIGJvb2xlYW4gREVCVUcgPSBmYWxzZTsKLSAgICAgICAgaWYgKHRoaXMucmFuZ2VzID09IG51bGwgfHwgdGhpcy5yYW5nZXMubGVuZ3RoIDw9IDIpCi0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIGlmICh0aGlzLmlzQ29tcGFjdGVkKCkpCi0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIGludCBiYXNlID0gMDsgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJbmRleCBvZiB3cml0aW5nIHBvaW50Ci0gICAgICAgIGludCB0YXJnZXQgPSAwOyAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJbmRleCBvZiBwcm9jZXNzaW5nIHBvaW50Ci0KLSAgICAgICAgd2hpbGUgKHRhcmdldCA8IHRoaXMucmFuZ2VzLmxlbmd0aCkgewotICAgICAgICAgICAgaWYgKGJhc2UgIT0gdGFyZ2V0KSB7Ci0gICAgICAgICAgICAgICAgdGhpcy5yYW5nZXNbYmFzZV0gPSB0aGlzLnJhbmdlc1t0YXJnZXQrK107Ci0gICAgICAgICAgICAgICAgdGhpcy5yYW5nZXNbYmFzZSsxXSA9IHRoaXMucmFuZ2VzW3RhcmdldCsrXTsKLSAgICAgICAgICAgIH0gZWxzZQotICAgICAgICAgICAgICAgIHRhcmdldCArPSAyOwotICAgICAgICAgICAgaW50IGJhc2VlbmQgPSB0aGlzLnJhbmdlc1tiYXNlKzFdOwotICAgICAgICAgICAgd2hpbGUgKHRhcmdldCA8IHRoaXMucmFuZ2VzLmxlbmd0aCkgewotICAgICAgICAgICAgICAgIGlmIChiYXNlZW5kKzEgPCB0aGlzLnJhbmdlc1t0YXJnZXRdKQotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICBpZiAoYmFzZWVuZCsxID09IHRoaXMucmFuZ2VzW3RhcmdldF0pIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKERFQlVHKQotICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJUb2tlbiNjb21wYWN0UmFuZ2VzKCk6IENvbXBhY3Rpb246IFsiK3RoaXMucmFuZ2VzW2Jhc2VdCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyIsICIrdGhpcy5yYW5nZXNbYmFzZSsxXQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsiXSwgWyIrdGhpcy5yYW5nZXNbdGFyZ2V0XQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsiLCAiK3RoaXMucmFuZ2VzW3RhcmdldCsxXQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsiXSAtPiBbIit0aGlzLnJhbmdlc1tiYXNlXQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsiLCAiK3RoaXMucmFuZ2VzW3RhcmdldCsxXQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsiXSIpOwotICAgICAgICAgICAgICAgICAgICB0aGlzLnJhbmdlc1tiYXNlKzFdID0gdGhpcy5yYW5nZXNbdGFyZ2V0KzFdOwotICAgICAgICAgICAgICAgICAgICBiYXNlZW5kID0gdGhpcy5yYW5nZXNbYmFzZSsxXTsKLSAgICAgICAgICAgICAgICAgICAgdGFyZ2V0ICs9IDI7Ci0gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChiYXNlZW5kID49IHRoaXMucmFuZ2VzW3RhcmdldCsxXSkgewotICAgICAgICAgICAgICAgICAgICBpZiAoREVCVUcpCi0gICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIlRva2VuI2NvbXBhY3RSYW5nZXMoKTogQ29tcGFjdGlvbjogWyIrdGhpcy5yYW5nZXNbYmFzZV0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIiwgIit0aGlzLnJhbmdlc1tiYXNlKzFdCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyJdLCBbIit0aGlzLnJhbmdlc1t0YXJnZXRdCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyIsICIrdGhpcy5yYW5nZXNbdGFyZ2V0KzFdCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyJdIC0+IFsiK3RoaXMucmFuZ2VzW2Jhc2VdCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyIsICIrdGhpcy5yYW5nZXNbYmFzZSsxXQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsiXSIpOwotICAgICAgICAgICAgICAgICAgICB0YXJnZXQgKz0gMjsKLSAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGJhc2VlbmQgPCB0aGlzLnJhbmdlc1t0YXJnZXQrMV0pIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKERFQlVHKQotICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJUb2tlbiNjb21wYWN0UmFuZ2VzKCk6IENvbXBhY3Rpb246IFsiK3RoaXMucmFuZ2VzW2Jhc2VdCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyIsICIrdGhpcy5yYW5nZXNbYmFzZSsxXQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsiXSwgWyIrdGhpcy5yYW5nZXNbdGFyZ2V0XQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsiLCAiK3RoaXMucmFuZ2VzW3RhcmdldCsxXQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsiXSAtPiBbIit0aGlzLnJhbmdlc1tiYXNlXQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsiLCAiK3RoaXMucmFuZ2VzW3RhcmdldCsxXQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsiXSIpOwotICAgICAgICAgICAgICAgICAgICB0aGlzLnJhbmdlc1tiYXNlKzFdID0gdGhpcy5yYW5nZXNbdGFyZ2V0KzFdOwotICAgICAgICAgICAgICAgICAgICBiYXNlZW5kID0gdGhpcy5yYW5nZXNbYmFzZSsxXTsKLSAgICAgICAgICAgICAgICAgICAgdGFyZ2V0ICs9IDI7Ci0gICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlRva2VuI2NvbXBhY3RSYW5nZXMoKTogSW50ZXJuZWwgRXJyb3I6IFsiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICt0aGlzLnJhbmdlc1tiYXNlXQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIiwiK3RoaXMucmFuZ2VzW2Jhc2UrMV0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyJdIFsiK3RoaXMucmFuZ2VzW3RhcmdldF0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyIsIit0aGlzLnJhbmdlc1t0YXJnZXQrMV0rIl0iKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9IC8vIHdoaWxlCi0gICAgICAgICAgICBiYXNlICs9IDI7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoYmFzZSAhPSB0aGlzLnJhbmdlcy5sZW5ndGgpIHsKLSAgICAgICAgICAgIGludFtdIHJlc3VsdCA9IG5ldyBpbnRbYmFzZV07Ci0gICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHRoaXMucmFuZ2VzLCAwLCByZXN1bHQsIDAsIGJhc2UpOwotICAgICAgICAgICAgdGhpcy5yYW5nZXMgPSByZXN1bHQ7Ci0gICAgICAgIH0KLSAgICAgICAgdGhpcy5zZXRDb21wYWN0ZWQoKTsKLSAgICB9Ci0KLSAgICBwcm90ZWN0ZWQgdm9pZCBtZXJnZVJhbmdlcyhUb2tlbiB0b2tlbikgewotICAgICAgICBSYW5nZVRva2VuIHRvayA9IChSYW5nZVRva2VuKXRva2VuOwotICAgICAgICB0aGlzLnNvcnRSYW5nZXMoKTsKLSAgICAgICAgdG9rLnNvcnRSYW5nZXMoKTsKLSAgICAgICAgaWYgKHRvay5yYW5nZXMgPT0gbnVsbCkKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgdGhpcy5pY2FzZUNhY2hlID0gbnVsbDsKLSAgICAgICAgdGhpcy5zZXRTb3J0ZWQodHJ1ZSk7Ci0gICAgICAgIGlmICh0aGlzLnJhbmdlcyA9PSBudWxsKSB7Ci0gICAgICAgICAgICB0aGlzLnJhbmdlcyA9IG5ldyBpbnRbdG9rLnJhbmdlcy5sZW5ndGhdOwotICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weSh0b2sucmFuZ2VzLCAwLCB0aGlzLnJhbmdlcywgMCwgdG9rLnJhbmdlcy5sZW5ndGgpOwotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0gICAgICAgIGludFtdIHJlc3VsdCA9IG5ldyBpbnRbdGhpcy5yYW5nZXMubGVuZ3RoK3Rvay5yYW5nZXMubGVuZ3RoXTsKLSAgICAgICAgZm9yIChpbnQgaSA9IDAsIGogPSAwLCBrID0gMDsgIGkgPCB0aGlzLnJhbmdlcy5sZW5ndGggfHwgaiA8IHRvay5yYW5nZXMubGVuZ3RoOykgewotICAgICAgICAgICAgaWYgKGkgPj0gdGhpcy5yYW5nZXMubGVuZ3RoKSB7Ci0gICAgICAgICAgICAgICAgcmVzdWx0W2srK10gPSB0b2sucmFuZ2VzW2orK107Ci0gICAgICAgICAgICAgICAgcmVzdWx0W2srK10gPSB0b2sucmFuZ2VzW2orK107Ci0gICAgICAgICAgICB9IGVsc2UgaWYgKGogPj0gdG9rLnJhbmdlcy5sZW5ndGgpIHsKLSAgICAgICAgICAgICAgICByZXN1bHRbaysrXSA9IHRoaXMucmFuZ2VzW2krK107Ci0gICAgICAgICAgICAgICAgcmVzdWx0W2srK10gPSB0aGlzLnJhbmdlc1tpKytdOwotICAgICAgICAgICAgfSBlbHNlIGlmICh0b2sucmFuZ2VzW2pdIDwgdGhpcy5yYW5nZXNbaV0KLSAgICAgICAgICAgICAgICAgICAgICAgfHwgdG9rLnJhbmdlc1tqXSA9PSB0aGlzLnJhbmdlc1tpXSAmJiB0b2sucmFuZ2VzW2orMV0gPCB0aGlzLnJhbmdlc1tpKzFdKSB7Ci0gICAgICAgICAgICAgICAgcmVzdWx0W2srK10gPSB0b2sucmFuZ2VzW2orK107Ci0gICAgICAgICAgICAgICAgcmVzdWx0W2srK10gPSB0b2sucmFuZ2VzW2orK107Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIHJlc3VsdFtrKytdID0gdGhpcy5yYW5nZXNbaSsrXTsKLSAgICAgICAgICAgICAgICByZXN1bHRbaysrXSA9IHRoaXMucmFuZ2VzW2krK107Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgdGhpcy5yYW5nZXMgPSByZXN1bHQ7Ci0gICAgfQotCi0gICAgcHJvdGVjdGVkIHZvaWQgc3VidHJhY3RSYW5nZXMoVG9rZW4gdG9rZW4pIHsKLSAgICAgICAgaWYgKHRva2VuLnR5cGUgPT0gTlJBTkdFKSB7Ci0gICAgICAgICAgICB0aGlzLmludGVyc2VjdFJhbmdlcyh0b2tlbik7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLSAgICAgICAgUmFuZ2VUb2tlbiB0b2sgPSAoUmFuZ2VUb2tlbil0b2tlbjsKLSAgICAgICAgaWYgKHRvay5yYW5nZXMgPT0gbnVsbCB8fCB0aGlzLnJhbmdlcyA9PSBudWxsKQotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB0aGlzLmljYXNlQ2FjaGUgPSBudWxsOwotICAgICAgICB0aGlzLnNvcnRSYW5nZXMoKTsKLSAgICAgICAgdGhpcy5jb21wYWN0UmFuZ2VzKCk7Ci0gICAgICAgIHRvay5zb3J0UmFuZ2VzKCk7Ci0gICAgICAgIHRvay5jb21wYWN0UmFuZ2VzKCk7Ci0KLSAgICAgICAgLy9TeXN0ZW0uZXJyLnByaW50bG4oIlRva2VuI3N1YnN0cmFjdFJhbmdlcygpOiBFbnRyeTogIit0aGlzLnJhbmdlcy5sZW5ndGgrIiwgIit0b2sucmFuZ2VzLmxlbmd0aCk7Ci0KLSAgICAgICAgaW50W10gcmVzdWx0ID0gbmV3IGludFt0aGlzLnJhbmdlcy5sZW5ndGgrdG9rLnJhbmdlcy5sZW5ndGhdOwotICAgICAgICBpbnQgd3AgPSAwLCBzcmMgPSAwLCBzdWIgPSAwOwotICAgICAgICB3aGlsZSAoc3JjIDwgdGhpcy5yYW5nZXMubGVuZ3RoICYmIHN1YiA8IHRvay5yYW5nZXMubGVuZ3RoKSB7Ci0gICAgICAgICAgICBpbnQgc3JjYmVnaW4gPSB0aGlzLnJhbmdlc1tzcmNdOwotICAgICAgICAgICAgaW50IHNyY2VuZCA9IHRoaXMucmFuZ2VzW3NyYysxXTsKLSAgICAgICAgICAgIGludCBzdWJiZWdpbiA9IHRvay5yYW5nZXNbc3ViXTsKLSAgICAgICAgICAgIGludCBzdWJlbmQgPSB0b2sucmFuZ2VzW3N1YisxXTsKLSAgICAgICAgICAgIGlmIChzcmNlbmQgPCBzdWJiZWdpbikgeyAgICAgICAgICAgIC8vIE5vdCBvdmVybGFwcGVkCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzcmM6IG8tLS0tLW8KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHN1YjogICAgICAgICBvLS0tLS1vCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyByZXM6IG8tLS0tLW8KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJldXNlIHN1YgotICAgICAgICAgICAgICAgIHJlc3VsdFt3cCsrXSA9IHRoaXMucmFuZ2VzW3NyYysrXTsKLSAgICAgICAgICAgICAgICByZXN1bHRbd3ArK10gPSB0aGlzLnJhbmdlc1tzcmMrK107Ci0gICAgICAgICAgICB9IGVsc2UgaWYgKHNyY2VuZCA+PSBzdWJiZWdpbgotICAgICAgICAgICAgICAgICAgICAgICAmJiBzcmNiZWdpbiA8PSBzdWJlbmQpIHsgLy8gT3ZlcmxhcHBlZAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc3JjOiAgICBvLS0tLS0tLS1vCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzdWI6ICBvLS0tLW8KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHN1YjogICAgICBvLS0tLW8KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHN1YjogICAgICAgICAgby0tLS1vCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzdWI6ICBvLS0tLS0tLS0tLS0tbwotICAgICAgICAgICAgICAgIGlmIChzdWJiZWdpbiA8PSBzcmNiZWdpbiAmJiBzcmNlbmQgPD0gc3ViZW5kKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzcmM6ICAgIG8tLS0tLS0tLW8KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHN1YjogIG8tLS0tLS0tLS0tLS1vCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyByZXM6IGVtcHR5Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBSZXVzZSBzdWIKLSAgICAgICAgICAgICAgICAgICAgc3JjICs9IDI7Ci0gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChzdWJiZWdpbiA8PSBzcmNiZWdpbikgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc3JjOiAgICBvLS0tLS0tLS1vCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzdWI6ICBvLS0tLW8KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHJlczogICAgICAgby0tLS0tbwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUmV1c2Ugc3JjKD1yZXMpCi0gICAgICAgICAgICAgICAgICAgIHRoaXMucmFuZ2VzW3NyY10gPSBzdWJlbmQrMTsKLSAgICAgICAgICAgICAgICAgICAgc3ViICs9IDI7Ci0gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChzcmNlbmQgPD0gc3ViZW5kKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzcmM6ICAgIG8tLS0tLS0tLW8KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHN1YjogICAgICAgICAgby0tLS1vCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyByZXM6ICAgIG8tLS0tLW8KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJldXNlIHN1YgotICAgICAgICAgICAgICAgICAgICByZXN1bHRbd3ArK10gPSBzcmNiZWdpbjsKLSAgICAgICAgICAgICAgICAgICAgcmVzdWx0W3dwKytdID0gc3ViYmVnaW4tMTsKLSAgICAgICAgICAgICAgICAgICAgc3JjICs9IDI7Ci0gICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNyYzogICAgby0tLS0tLS0tbwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc3ViOiAgICAgIG8tLS0tbwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcmVzOiAgICBvLW8gICAgby1vCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBSZXVzZSBzcmMoPXJpZ2h0IHJlcykKLSAgICAgICAgICAgICAgICAgICAgcmVzdWx0W3dwKytdID0gc3JjYmVnaW47Ci0gICAgICAgICAgICAgICAgICAgIHJlc3VsdFt3cCsrXSA9IHN1YmJlZ2luLTE7Ci0gICAgICAgICAgICAgICAgICAgIHRoaXMucmFuZ2VzW3NyY10gPSBzdWJlbmQrMTsKLSAgICAgICAgICAgICAgICAgICAgc3ViICs9IDI7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfSBlbHNlIGlmIChzdWJlbmQgPCBzcmNiZWdpbikgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTm90IG92ZXJsYXBwZWQKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNyYzogICAgICAgICAgby0tLS0tbwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc3ViOiBvLS0tLW8KLSAgICAgICAgICAgICAgICBzdWIgKz0gMjsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlRva2VuI3N1YnRyYWN0UmFuZ2VzKCk6IEludGVybmFsIEVycm9yOiBbIit0aGlzLnJhbmdlc1tzcmNdCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyIsIit0aGlzLnJhbmdlc1tzcmMrMV0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIl0gLSBbIit0b2sucmFuZ2VzW3N1Yl0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIiwiK3Rvay5yYW5nZXNbc3ViKzFdCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyJdIik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgd2hpbGUgKHNyYyA8IHRoaXMucmFuZ2VzLmxlbmd0aCkgewotICAgICAgICAgICAgcmVzdWx0W3dwKytdID0gdGhpcy5yYW5nZXNbc3JjKytdOwotICAgICAgICAgICAgcmVzdWx0W3dwKytdID0gdGhpcy5yYW5nZXNbc3JjKytdOwotICAgICAgICB9Ci0gICAgICAgIHRoaXMucmFuZ2VzID0gbmV3IGludFt3cF07Ci0gICAgICAgIFN5c3RlbS5hcnJheWNvcHkocmVzdWx0LCAwLCB0aGlzLnJhbmdlcywgMCwgd3ApOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhpcy5yYW5nZXMgaXMgc29ydGVkIGFuZCBjb21wYWN0ZWQuCi0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHBhcmFtIHRvayBJZ25vcmUgd2hldGhlciBpdCBpcyBOUkFOR0Ugb3Igbm90LgotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIGludGVyc2VjdFJhbmdlcyhUb2tlbiB0b2tlbikgewotICAgICAgICBSYW5nZVRva2VuIHRvayA9IChSYW5nZVRva2VuKXRva2VuOwotICAgICAgICBpZiAodG9rLnJhbmdlcyA9PSBudWxsIHx8IHRoaXMucmFuZ2VzID09IG51bGwpCi0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIHRoaXMuaWNhc2VDYWNoZSA9IG51bGw7Ci0gICAgICAgIHRoaXMuc29ydFJhbmdlcygpOwotICAgICAgICB0aGlzLmNvbXBhY3RSYW5nZXMoKTsKLSAgICAgICAgdG9rLnNvcnRSYW5nZXMoKTsKLSAgICAgICAgdG9rLmNvbXBhY3RSYW5nZXMoKTsKLQotICAgICAgICBpbnRbXSByZXN1bHQgPSBuZXcgaW50W3RoaXMucmFuZ2VzLmxlbmd0aCt0b2sucmFuZ2VzLmxlbmd0aF07Ci0gICAgICAgIGludCB3cCA9IDAsIHNyYzEgPSAwLCBzcmMyID0gMDsKLSAgICAgICAgd2hpbGUgKHNyYzEgPCB0aGlzLnJhbmdlcy5sZW5ndGggJiYgc3JjMiA8IHRvay5yYW5nZXMubGVuZ3RoKSB7Ci0gICAgICAgICAgICBpbnQgc3JjMWJlZ2luID0gdGhpcy5yYW5nZXNbc3JjMV07Ci0gICAgICAgICAgICBpbnQgc3JjMWVuZCA9IHRoaXMucmFuZ2VzW3NyYzErMV07Ci0gICAgICAgICAgICBpbnQgc3JjMmJlZ2luID0gdG9rLnJhbmdlc1tzcmMyXTsKLSAgICAgICAgICAgIGludCBzcmMyZW5kID0gdG9rLnJhbmdlc1tzcmMyKzFdOwotICAgICAgICAgICAgaWYgKHNyYzFlbmQgPCBzcmMyYmVnaW4pIHsgICAgICAgICAgLy8gTm90IG92ZXJsYXBwZWQKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNyYzE6IG8tLS0tLW8KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNyYzI6ICAgICAgICAgby0tLS0tbwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcmVzOiAgZW1wdHkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJldXNlIHNyYzIKLSAgICAgICAgICAgICAgICBzcmMxICs9IDI7Ci0gICAgICAgICAgICB9IGVsc2UgaWYgKHNyYzFlbmQgPj0gc3JjMmJlZ2luCi0gICAgICAgICAgICAgICAgICAgICAgICYmIHNyYzFiZWdpbiA8PSBzcmMyZW5kKSB7IC8vIE92ZXJsYXBwZWQKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNyYzE6ICAgIG8tLS0tLS0tLW8KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNyYzI6ICBvLS0tLW8KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNyYzI6ICAgICAgby0tLS1vCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzcmMyOiAgICAgICAgICBvLS0tLW8KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNyYzI6ICBvLS0tLS0tLS0tLS0tbwotICAgICAgICAgICAgICAgIGlmIChzcmMyYmVnaW4gPD0gc3JjMmJlZ2luICYmIHNyYzFlbmQgPD0gc3JjMmVuZCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc3JjMTogICAgby0tLS0tLS0tbwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc3JjMjogIG8tLS0tLS0tLS0tLS1vCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyByZXM6ICAgICBvLS0tLS0tLS1vCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBSZXVzZSBzcmMyCi0gICAgICAgICAgICAgICAgICAgIHJlc3VsdFt3cCsrXSA9IHNyYzFiZWdpbjsKLSAgICAgICAgICAgICAgICAgICAgcmVzdWx0W3dwKytdID0gc3JjMWVuZDsKLSAgICAgICAgICAgICAgICAgICAgc3JjMSArPSAyOwotICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoc3JjMmJlZ2luIDw9IHNyYzFiZWdpbikgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc3JjMTogICAgby0tLS0tLS0tbwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc3JjMjogIG8tLS0tbwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcmVzOiAgICAgby0tbwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUmV1c2UgdGhlIHJlc3Qgb2Ygc3JjMQotICAgICAgICAgICAgICAgICAgICByZXN1bHRbd3ArK10gPSBzcmMxYmVnaW47Ci0gICAgICAgICAgICAgICAgICAgIHJlc3VsdFt3cCsrXSA9IHNyYzJlbmQ7Ci0gICAgICAgICAgICAgICAgICAgIHRoaXMucmFuZ2VzW3NyYzFdID0gc3JjMmVuZCsxOwotICAgICAgICAgICAgICAgICAgICBzcmMyICs9IDI7Ci0gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChzcmMxZW5kIDw9IHNyYzJlbmQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNyYzE6ICAgIG8tLS0tLS0tLW8KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNyYzI6ICAgICAgICAgIG8tLS0tbwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcmVzOiAgICAgICAgICAgby0tbwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUmV1c2Ugc3JjMgotICAgICAgICAgICAgICAgICAgICByZXN1bHRbd3ArK10gPSBzcmMyYmVnaW47Ci0gICAgICAgICAgICAgICAgICAgIHJlc3VsdFt3cCsrXSA9IHNyYzFlbmQ7Ci0gICAgICAgICAgICAgICAgICAgIHNyYzEgKz0gMjsKLSAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc3JjMTogICAgby0tLS0tLS0tbwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc3JjMjogICAgICBvLS0tLW8KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHJlczogICAgICAgby0tLS1vCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBSZXVzZSB0aGUgcmVzdCBvZiBzcmMxCi0gICAgICAgICAgICAgICAgICAgIHJlc3VsdFt3cCsrXSA9IHNyYzJiZWdpbjsKLSAgICAgICAgICAgICAgICAgICAgcmVzdWx0W3dwKytdID0gc3JjMmVuZDsKLSAgICAgICAgICAgICAgICAgICAgdGhpcy5yYW5nZXNbc3JjMV0gPSBzcmMyZW5kKzE7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfSBlbHNlIGlmIChzcmMyZW5kIDwgc3JjMWJlZ2luKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBOb3Qgb3ZlcmxhcHBlZAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc3JjMTogICAgICAgICAgby0tLS0tbwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc3JjMjogby0tLS1vCi0gICAgICAgICAgICAgICAgc3JjMiArPSAyOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVG9rZW4jaW50ZXJzZWN0UmFuZ2VzKCk6IEludGVybmFsIEVycm9yOiBbIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICt0aGlzLnJhbmdlc1tzcmMxXQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsiLCIrdGhpcy5yYW5nZXNbc3JjMSsxXQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsiXSAmIFsiK3Rvay5yYW5nZXNbc3JjMl0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIiwiK3Rvay5yYW5nZXNbc3JjMisxXQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsiXSIpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHdoaWxlIChzcmMxIDwgdGhpcy5yYW5nZXMubGVuZ3RoKSB7Ci0gICAgICAgICAgICByZXN1bHRbd3ArK10gPSB0aGlzLnJhbmdlc1tzcmMxKytdOwotICAgICAgICAgICAgcmVzdWx0W3dwKytdID0gdGhpcy5yYW5nZXNbc3JjMSsrXTsKLSAgICAgICAgfQotICAgICAgICB0aGlzLnJhbmdlcyA9IG5ldyBpbnRbd3BdOwotICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHJlc3VsdCwgMCwgdGhpcy5yYW5nZXMsIDAsIHdwKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoaXMucmFuZ2VzIGlzIHNvcnRlZCBhbmQgY29tcGFjdGVkLgotICAgIH0KLQotICAgIC8qKgotICAgICAqIGZvciBSQU5HRTogQ3JlYXRlcyBjb21wbGVtZW50LgotICAgICAqIGZvciBOUkFOR0U6IENyZWF0ZXMgdGhlIHNhbWUgbWVhbmluZyBSQU5HRS4KLSAgICAgKi8KLSAgICBzdGF0aWMgVG9rZW4gY29tcGxlbWVudFJhbmdlcyhUb2tlbiB0b2tlbikgewotICAgICAgICBpZiAodG9rZW4udHlwZSAhPSBSQU5HRSAmJiB0b2tlbi50eXBlICE9IE5SQU5HRSkKLSAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIlRva2VuI2NvbXBsZW1lbnRSYW5nZXMoKTogbXVzdCBiZSBSQU5HRTogIit0b2tlbi50eXBlKTsKLSAgICAgICAgUmFuZ2VUb2tlbiB0b2sgPSAoUmFuZ2VUb2tlbil0b2tlbjsKLSAgICAgICAgdG9rLnNvcnRSYW5nZXMoKTsKLSAgICAgICAgdG9rLmNvbXBhY3RSYW5nZXMoKTsKLSAgICAgICAgaW50IGxlbiA9IHRvay5yYW5nZXMubGVuZ3RoKzI7Ci0gICAgICAgIGlmICh0b2sucmFuZ2VzWzBdID09IDApCi0gICAgICAgICAgICBsZW4gLT0gMjsKLSAgICAgICAgaW50IGxhc3QgPSB0b2sucmFuZ2VzW3Rvay5yYW5nZXMubGVuZ3RoLTFdOwotICAgICAgICBpZiAobGFzdCA9PSBVVEYxNl9NQVgpCi0gICAgICAgICAgICBsZW4gLT0gMjsKLSAgICAgICAgUmFuZ2VUb2tlbiByZXQgPSBUb2tlbi5jcmVhdGVSYW5nZSgpOwotICAgICAgICByZXQucmFuZ2VzID0gbmV3IGludFtsZW5dOwotICAgICAgICBpbnQgd3AgPSAwOwotICAgICAgICBpZiAodG9rLnJhbmdlc1swXSA+IDApIHsKLSAgICAgICAgICAgIHJldC5yYW5nZXNbd3ArK10gPSAwOwotICAgICAgICAgICAgcmV0LnJhbmdlc1t3cCsrXSA9IHRvay5yYW5nZXNbMF0tMTsKLSAgICAgICAgfQotICAgICAgICBmb3IgKGludCBpID0gMTsgIGkgPCB0b2sucmFuZ2VzLmxlbmd0aC0yOyAgaSArPSAyKSB7Ci0gICAgICAgICAgICByZXQucmFuZ2VzW3dwKytdID0gdG9rLnJhbmdlc1tpXSsxOwotICAgICAgICAgICAgcmV0LnJhbmdlc1t3cCsrXSA9IHRvay5yYW5nZXNbaSsxXS0xOwotICAgICAgICB9Ci0gICAgICAgIGlmIChsYXN0ICE9IFVURjE2X01BWCkgewotICAgICAgICAgICAgcmV0LnJhbmdlc1t3cCsrXSA9IGxhc3QrMTsKLSAgICAgICAgICAgIHJldC5yYW5nZXNbd3BdID0gVVRGMTZfTUFYOwotICAgICAgICB9Ci0gICAgICAgIHJldC5zZXRDb21wYWN0ZWQoKTsKLSAgICAgICAgcmV0dXJuIHJldDsKLSAgICB9Ci0KLSAgICBzeW5jaHJvbml6ZWQgUmFuZ2VUb2tlbiBnZXRDYXNlSW5zZW5zaXRpdmVUb2tlbigpIHsKLSAgICAgICAgaWYgKHRoaXMuaWNhc2VDYWNoZSAhPSBudWxsKQotICAgICAgICAgICAgcmV0dXJuIHRoaXMuaWNhc2VDYWNoZTsKLQotICAgICAgICBSYW5nZVRva2VuIHVwcGVycyA9IHRoaXMudHlwZSA9PSBUb2tlbi5SQU5HRSA/IFRva2VuLmNyZWF0ZVJhbmdlKCkgOiBUb2tlbi5jcmVhdGVOUmFuZ2UoKTsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7ICBpIDwgdGhpcy5yYW5nZXMubGVuZ3RoOyAgaSArPSAyKSB7Ci0gICAgICAgICAgICBmb3IgKGludCBjaCA9IHRoaXMucmFuZ2VzW2ldOyAgY2ggPD0gdGhpcy5yYW5nZXNbaSsxXTsgIGNoICsrKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGNoID4gMHhmZmZmKQotICAgICAgICAgICAgICAgICAgICB1cHBlcnMuYWRkUmFuZ2UoY2gsIGNoKTsKLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgY2hhciB1Y2ggPSBDaGFyYWN0ZXIudG9VcHBlckNhc2UoKGNoYXIpY2gpOwotICAgICAgICAgICAgICAgICAgICB1cHBlcnMuYWRkUmFuZ2UodWNoLCB1Y2gpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBSYW5nZVRva2VuIGxvd2VycyA9IHRoaXMudHlwZSA9PSBUb2tlbi5SQU5HRSA/IFRva2VuLmNyZWF0ZVJhbmdlKCkgOiBUb2tlbi5jcmVhdGVOUmFuZ2UoKTsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7ICBpIDwgdXBwZXJzLnJhbmdlcy5sZW5ndGg7ICBpICs9IDIpIHsKLSAgICAgICAgICAgIGZvciAoaW50IGNoID0gdXBwZXJzLnJhbmdlc1tpXTsgIGNoIDw9IHVwcGVycy5yYW5nZXNbaSsxXTsgIGNoICsrKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGNoID4gMHhmZmZmKQotICAgICAgICAgICAgICAgICAgICBsb3dlcnMuYWRkUmFuZ2UoY2gsIGNoKTsKLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgY2hhciB1Y2ggPSBDaGFyYWN0ZXIudG9VcHBlckNhc2UoKGNoYXIpY2gpOwotICAgICAgICAgICAgICAgICAgICBsb3dlcnMuYWRkUmFuZ2UodWNoLCB1Y2gpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBsb3dlcnMubWVyZ2VSYW5nZXModXBwZXJzKTsKLSAgICAgICAgbG93ZXJzLm1lcmdlUmFuZ2VzKHRoaXMpOwotICAgICAgICBsb3dlcnMuY29tcGFjdFJhbmdlcygpOwotCi0gICAgICAgIHRoaXMuaWNhc2VDYWNoZSA9IGxvd2VyczsKLSAgICAgICAgcmV0dXJuIGxvd2VyczsKLSAgICB9Ci0KLSAgICB2b2lkIGR1bXBSYW5nZXMoKSB7Ci0gICAgICAgIFN5c3RlbS5lcnIucHJpbnQoIlJBTkdFOiAiKTsKLSAgICAgICAgaWYgKHRoaXMucmFuZ2VzID09IG51bGwpCi0gICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIiBOVUxMIik7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyAgaSA8IHRoaXMucmFuZ2VzLmxlbmd0aDsgIGkgKz0gMikgewotICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludCgiWyIrdGhpcy5yYW5nZXNbaV0rIiwiK3RoaXMucmFuZ2VzW2krMV0rIl0gIik7Ci0gICAgICAgIH0KLSAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCIiKTsKLSAgICB9Ci0KLSAgICBib29sZWFuIG1hdGNoKGludCBjaCkgewotICAgICAgICBpZiAodGhpcy5tYXAgPT0gbnVsbCkgIHRoaXMuY3JlYXRlTWFwKCk7Ci0gICAgICAgIGJvb2xlYW4gcmV0OwotICAgICAgICBpZiAodGhpcy50eXBlID09IFJBTkdFKSB7Ci0gICAgICAgICAgICBpZiAoY2ggPCBNQVBTSVpFKQotICAgICAgICAgICAgICAgIHJldHVybiAodGhpcy5tYXBbY2gvMzJdICYgKDE8PChjaCYweDFmKSkpICE9IDA7Ci0gICAgICAgICAgICByZXQgPSBmYWxzZTsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSB0aGlzLm5vbk1hcEluZGV4OyAgaSA8IHRoaXMucmFuZ2VzLmxlbmd0aDsgIGkgKz0gMikgewotICAgICAgICAgICAgICAgIGlmICh0aGlzLnJhbmdlc1tpXSA8PSBjaCAmJiBjaCA8PSB0aGlzLnJhbmdlc1tpKzFdKQotICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIGlmIChjaCA8IE1BUFNJWkUpCi0gICAgICAgICAgICAgICAgcmV0dXJuICh0aGlzLm1hcFtjaC8zMl0gJiAoMTw8KGNoJjB4MWYpKSkgPT0gMDsKLSAgICAgICAgICAgIHJldCA9IHRydWU7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gdGhpcy5ub25NYXBJbmRleDsgIGkgPCB0aGlzLnJhbmdlcy5sZW5ndGg7ICBpICs9IDIpIHsKLSAgICAgICAgICAgICAgICBpZiAodGhpcy5yYW5nZXNbaV0gPD0gY2ggJiYgY2ggPD0gdGhpcy5yYW5nZXNbaSsxXSkKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiByZXQ7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE1BUFNJWkUgPSAyNTY7Ci0gICAgcHJpdmF0ZSB2b2lkIGNyZWF0ZU1hcCgpIHsKLSAgICAgICAgaW50IGFzaXplID0gTUFQU0laRS8zMjsgICAgICAgICAgICAgICAgIC8vIDMyIGlzIHRoZSBudW1iZXIgb2YgYml0cyBpbiBgaW50Jy4KLSAgICAgICAgaW50IFtdIG1hcCA9IG5ldyBpbnRbYXNpemVdOwotICAgICAgICBpbnQgbm9uTWFwSW5kZXggPSB0aGlzLnJhbmdlcy5sZW5ndGg7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYXNpemU7ICsraSkgewotICAgICAgICAgICAgbWFwW2ldID0gMDsKLSAgICAgICAgfQotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHRoaXMucmFuZ2VzLmxlbmd0aDsgIGkgKz0gMikgewotICAgICAgICAgICAgaW50IHMgPSB0aGlzLnJhbmdlc1tpXTsKLSAgICAgICAgICAgIGludCBlID0gdGhpcy5yYW5nZXNbaSsxXTsKLSAgICAgICAgICAgIGlmIChzIDwgTUFQU0laRSkgewotICAgICAgICAgICAgICAgIGZvciAoaW50IGogPSBzOyBqIDw9IGUgJiYgaiA8IE1BUFNJWkU7IGorKykgewotICAgICAgICAgICAgICAgICAgICBtYXBbai8zMl0gfD0gMTw8KGomMHgxZik7IC8vIHMmMHgxZiA6IDAtMzEKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBub25NYXBJbmRleCA9IGk7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoZSA+PSBNQVBTSVpFKSB7Ci0gICAgICAgICAgICAgICAgbm9uTWFwSW5kZXggPSBpOwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHRoaXMubWFwID0gbWFwOwotICAgICAgICB0aGlzLm5vbk1hcEluZGV4ID0gbm9uTWFwSW5kZXg7Ci0gICAgICAgIC8vZm9yIChpbnQgaSA9IDA7ICBpIDwgYXNpemU7ICBpICsrKSAgU3lzdGVtLmVyci5wcmludGxuKCJNYXA6ICIrSW50ZWdlci50b1N0cmluZyh0aGlzLm1hcFtpXSwgMTYpKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKGludCBvcHRpb25zKSB7Ci0gICAgICAgIFN0cmluZyByZXQ7Ci0gICAgICAgIGlmICh0aGlzLnR5cGUgPT0gUkFOR0UpIHsKLSAgICAgICAgICAgIGlmICh0aGlzID09IFRva2VuLnRva2VuX2RvdCkKLSAgICAgICAgICAgICAgICByZXQgPSAiLiI7Ci0gICAgICAgICAgICBlbHNlIGlmICh0aGlzID09IFRva2VuLnRva2VuXzB0bzkpCi0gICAgICAgICAgICAgICAgcmV0ID0gIlxcZCI7Ci0gICAgICAgICAgICBlbHNlIGlmICh0aGlzID09IFRva2VuLnRva2VuX3dvcmRjaGFycykKLSAgICAgICAgICAgICAgICByZXQgPSAiXFx3IjsKLSAgICAgICAgICAgIGVsc2UgaWYgKHRoaXMgPT0gVG9rZW4udG9rZW5fc3BhY2VzKQotICAgICAgICAgICAgICAgIHJldCA9ICJcXHMiOwotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nQnVmZmVyIHNiID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotICAgICAgICAgICAgICAgIHNiLmFwcGVuZCgiWyIpOwotICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyAgaSA8IHRoaXMucmFuZ2VzLmxlbmd0aDsgIGkgKz0gMikgewotICAgICAgICAgICAgICAgICAgICBpZiAoKG9wdGlvbnMgJiBSZWd1bGFyRXhwcmVzc2lvbi5TUEVDSUFMX0NPTU1BKSAhPSAwICYmIGkgPiAwKSAgc2IuYXBwZW5kKCIsIik7Ci0gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnJhbmdlc1tpXSA9PSB0aGlzLnJhbmdlc1tpKzFdKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzYi5hcHBlbmQoZXNjYXBlQ2hhckluQ2hhckNsYXNzKHRoaXMucmFuZ2VzW2ldKSk7Ci0gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzYi5hcHBlbmQoZXNjYXBlQ2hhckluQ2hhckNsYXNzKHRoaXMucmFuZ2VzW2ldKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzYi5hcHBlbmQoKGNoYXIpJy0nKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHNiLmFwcGVuZChlc2NhcGVDaGFySW5DaGFyQ2xhc3ModGhpcy5yYW5nZXNbaSsxXSkpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHNiLmFwcGVuZCgiXSIpOwotICAgICAgICAgICAgICAgIHJldCA9IHNiLnRvU3RyaW5nKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBpZiAodGhpcyA9PSBUb2tlbi50b2tlbl9ub3RfMHRvOSkKLSAgICAgICAgICAgICAgICByZXQgPSAiXFxEIjsKLSAgICAgICAgICAgIGVsc2UgaWYgKHRoaXMgPT0gVG9rZW4udG9rZW5fbm90X3dvcmRjaGFycykKLSAgICAgICAgICAgICAgICByZXQgPSAiXFxXIjsKLSAgICAgICAgICAgIGVsc2UgaWYgKHRoaXMgPT0gVG9rZW4udG9rZW5fbm90X3NwYWNlcykKLSAgICAgICAgICAgICAgICByZXQgPSAiXFxTIjsKLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIFN0cmluZ0J1ZmZlciBzYiA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLSAgICAgICAgICAgICAgICBzYi5hcHBlbmQoIlteIik7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7ICBpIDwgdGhpcy5yYW5nZXMubGVuZ3RoOyAgaSArPSAyKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmICgob3B0aW9ucyAmIFJlZ3VsYXJFeHByZXNzaW9uLlNQRUNJQUxfQ09NTUEpICE9IDAgJiYgaSA+IDApICBzYi5hcHBlbmQoIiwiKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMucmFuZ2VzW2ldID09IHRoaXMucmFuZ2VzW2krMV0pIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHNiLmFwcGVuZChlc2NhcGVDaGFySW5DaGFyQ2xhc3ModGhpcy5yYW5nZXNbaV0pKTsKLSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHNiLmFwcGVuZChlc2NhcGVDaGFySW5DaGFyQ2xhc3ModGhpcy5yYW5nZXNbaV0pKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHNiLmFwcGVuZCgnLScpOwotICAgICAgICAgICAgICAgICAgICAgICAgc2IuYXBwZW5kKGVzY2FwZUNoYXJJbkNoYXJDbGFzcyh0aGlzLnJhbmdlc1tpKzFdKSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgc2IuYXBwZW5kKCJdIik7Ci0gICAgICAgICAgICAgICAgcmV0ID0gc2IudG9TdHJpbmcoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gcmV0OwotICAgIH0KLQotICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBlc2NhcGVDaGFySW5DaGFyQ2xhc3MoaW50IGNoKSB7Ci0gICAgICAgIFN0cmluZyByZXQ7Ci0gICAgICAgIHN3aXRjaCAoY2gpIHsKLSAgICAgICAgICBjYXNlICdbJzogIGNhc2UgJ10nOiAgY2FzZSAnLSc6ICBjYXNlICdeJzoKLSAgICAgICAgICBjYXNlICcsJzogIGNhc2UgJ1xcJzoKLSAgICAgICAgICAgIHJldCA9ICJcXCIrKGNoYXIpY2g7Ci0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgICBjYXNlICdcZic6ICByZXQgPSAiXFxmIjsgIGJyZWFrOwotICAgICAgICAgIGNhc2UgJ1xuJzogIHJldCA9ICJcXG4iOyAgYnJlYWs7Ci0gICAgICAgICAgY2FzZSAnXHInOiAgcmV0ID0gIlxcciI7ICBicmVhazsKLSAgICAgICAgICBjYXNlICdcdCc6ICByZXQgPSAiXFx0IjsgIGJyZWFrOwotICAgICAgICAgIGNhc2UgMHgxYjogIHJldCA9ICJcXGUiOyAgYnJlYWs7Ci0gICAgICAgICAgLy9jYXNlIDB4MGI6ICByZXQgPSAiXFx2IjsgIGJyZWFrOwotICAgICAgICAgIGRlZmF1bHQ6Ci0gICAgICAgICAgICBpZiAoY2ggPCAweDIwKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIHByZSA9ICIwIitJbnRlZ2VyLnRvSGV4U3RyaW5nKGNoKTsKLSAgICAgICAgICAgICAgICByZXQgPSAiXFx4IitwcmUuc3Vic3RyaW5nKHByZS5sZW5ndGgoKS0yLCBwcmUubGVuZ3RoKCkpOwotICAgICAgICAgICAgfSBlbHNlIGlmIChjaCA+PSAweDEwMDAwKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIHByZSA9ICIwIitJbnRlZ2VyLnRvSGV4U3RyaW5nKGNoKTsKLSAgICAgICAgICAgICAgICByZXQgPSAiXFx2IitwcmUuc3Vic3RyaW5nKHByZS5sZW5ndGgoKS02LCBwcmUubGVuZ3RoKCkpOwotICAgICAgICAgICAgfSBlbHNlCi0gICAgICAgICAgICAgICAgcmV0ID0gIiIrKGNoYXIpY2g7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHJldDsKLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHBhdGgvcmVnZXgvUmVnZXhQYXJzZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHBhdGgvcmVnZXgvUmVnZXhQYXJzZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZWQxY2RhOS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hwYXRoL3JlZ2V4L1JlZ2V4UGFyc2VyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMjQxICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhwYXRoLnJlZ2V4OwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlscy5TZWN1cml0eVN1cHBvcnQ7Ci1pbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKLWltcG9ydCBqYXZhLnV0aWwuTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uOwotaW1wb3J0IGphdmEudXRpbC5SZXNvdXJjZUJ1bmRsZTsKLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi0vKioKLSAqIEEgUmVndWxhciBFeHByZXNzaW9uIFBhcnNlci4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQHZlcnNpb24gJElkOiBSZWdleFBhcnNlci5qYXZhLHYgMS44IDIwMTAtMTEtMDEgMDQ6Mzk6NTQgam9laHcgRXhwICQKLSAqLwotY2xhc3MgUmVnZXhQYXJzZXIgewotICAgIHN0YXRpYyBmaW5hbCBpbnQgVF9DSEFSID0gMDsKLSAgICBzdGF0aWMgZmluYWwgaW50IFRfRU9GID0gMTsKLSAgICBzdGF0aWMgZmluYWwgaW50IFRfT1IgPSAyOyAgICAgICAgICAgICAgICAgIC8vICd8JwotICAgIHN0YXRpYyBmaW5hbCBpbnQgVF9TVEFSID0gMzsgICAgICAgICAgICAgICAgLy8gJyonCi0gICAgc3RhdGljIGZpbmFsIGludCBUX1BMVVMgPSA0OyAgICAgICAgICAgICAgICAvLyAnKycKLSAgICBzdGF0aWMgZmluYWwgaW50IFRfUVVFU1RJT04gPSA1OyAgICAgICAgICAgIC8vICc/JwotICAgIHN0YXRpYyBmaW5hbCBpbnQgVF9MUEFSRU4gPSA2OyAgICAgICAgICAgICAgLy8gJygnCi0gICAgc3RhdGljIGZpbmFsIGludCBUX1JQQVJFTiA9IDc7ICAgICAgICAgICAgICAvLyAnKScKLSAgICBzdGF0aWMgZmluYWwgaW50IFRfRE9UID0gODsgICAgICAgICAgICAgICAgIC8vICcuJwotICAgIHN0YXRpYyBmaW5hbCBpbnQgVF9MQlJBQ0tFVCA9IDk7ICAgICAgICAgICAgLy8gJ1snCi0gICAgc3RhdGljIGZpbmFsIGludCBUX0JBQ0tTT0xJRFVTID0gMTA7ICAgICAgICAvLyAnXCcKLSAgICBzdGF0aWMgZmluYWwgaW50IFRfQ0FSRVQgPSAxMTsgICAgICAgICAgICAgIC8vICdeJwotICAgIHN0YXRpYyBmaW5hbCBpbnQgVF9ET0xMQVIgPSAxMjsgICAgICAgICAgICAgLy8gJyQnCi0gICAgc3RhdGljIGZpbmFsIGludCBUX0xQQVJFTjIgPSAxMzsgICAgICAgICAgICAvLyAnKD86JwotICAgIHN0YXRpYyBmaW5hbCBpbnQgVF9MT09LQUhFQUQgPSAxNDsgICAgICAgICAgLy8gJyg/PScKLSAgICBzdGF0aWMgZmluYWwgaW50IFRfTkVHQVRJVkVMT09LQUhFQUQgPSAxNTsgIC8vICcoPyEnCi0gICAgc3RhdGljIGZpbmFsIGludCBUX0xPT0tCRUhJTkQgPSAxNjsgICAgICAgICAvLyAnKD88PScKLSAgICBzdGF0aWMgZmluYWwgaW50IFRfTkVHQVRJVkVMT09LQkVISU5EID0gMTc7IC8vICcoPzwhJwotICAgIHN0YXRpYyBmaW5hbCBpbnQgVF9JTkRFUEVOREVOVCA9IDE4OyAgICAgICAgLy8gJyg/PicKLSAgICBzdGF0aWMgZmluYWwgaW50IFRfU0VUX09QRVJBVElPTlMgPSAxOTsgICAgIC8vICcoP1snCi0gICAgc3RhdGljIGZpbmFsIGludCBUX1BPU0lYX0NIQVJDTEFTU19TVEFSVCA9IDIwOyAvLyAnWzonIGluIGEgY2hhcmFjdGVyIGNsYXNzCi0gICAgc3RhdGljIGZpbmFsIGludCBUX0NPTU1FTlQgPSAyMTsgICAgICAgICAgICAvLyAnKD8jJwotICAgIHN0YXRpYyBmaW5hbCBpbnQgVF9NT0RJRklFUlMgPSAyMjsgICAgICAgICAgLy8gJyg/JyBbXC0sYS16LEEtWl0KLSAgICBzdGF0aWMgZmluYWwgaW50IFRfQ09ORElUSU9OID0gMjM7ICAgICAgICAgIC8vICcoPygnCi0gICAgc3RhdGljIGZpbmFsIGludCBUX1hNTFNDSEVNQV9DQ19TVUJUUkFDVElPTiA9IDI0OyAvLyAnLVsnIGluIGEgY2hhcmFjdGVyIGNsYXNzCi0KLSAgICBzdGF0aWMgY2xhc3MgUmVmZXJlbmNlUG9zaXRpb24gewotICAgICAgICBpbnQgcmVmTnVtYmVyOwotICAgICAgICBpbnQgcG9zaXRpb247Ci0gICAgICAgIFJlZmVyZW5jZVBvc2l0aW9uKGludCBuLCBpbnQgcG9zKSB7Ci0gICAgICAgICAgICB0aGlzLnJlZk51bWJlciA9IG47Ci0gICAgICAgICAgICB0aGlzLnBvc2l0aW9uID0gcG9zOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgaW50IG9mZnNldDsKLSAgICBTdHJpbmcgcmVnZXg7Ci0gICAgaW50IHJlZ2V4bGVuOwotICAgIGludCBvcHRpb25zOwotICAgIFJlc291cmNlQnVuZGxlIHJlc291cmNlczsKLSAgICBpbnQgY2hhcmRhdGE7Ci0gICAgaW50IG5leHR0b2tlbjsKLSAgICBzdGF0aWMgcHJvdGVjdGVkIGZpbmFsIGludCBTX05PUk1BTCA9IDA7Ci0gICAgc3RhdGljIHByb3RlY3RlZCBmaW5hbCBpbnQgU19JTkJSQUNLRVRTID0gMTsKLSAgICBzdGF0aWMgcHJvdGVjdGVkIGZpbmFsIGludCBTX0lOWEJSQUNLRVRTID0gMjsKLSAgICBpbnQgY29udGV4dCA9IFNfTk9STUFMOwotICAgIGludCBwYXJlbk9wZW5lZCA9IDE7Ci0gICAgaW50IHBhcmVubnVtYmVyID0gMTsKLSAgICBib29sZWFuIGhhc0JhY2tSZWZlcmVuY2VzOwotICAgIFZlY3RvciByZWZlcmVuY2VzID0gbnVsbDsKLSAgICBpbnQgcGFyZW5Db3VudCA9IDA7Ci0KLSAgICBwdWJsaWMgUmVnZXhQYXJzZXIoKSB7Ci0gICAgICAgIHRoaXMuc2V0TG9jYWxlKExvY2FsZS5nZXREZWZhdWx0KCkpOwotICAgIH0KLSAgICBwdWJsaWMgUmVnZXhQYXJzZXIoTG9jYWxlIGxvY2FsZSkgewotICAgICAgICB0aGlzLnNldExvY2FsZShsb2NhbGUpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldExvY2FsZShMb2NhbGUgbG9jYWxlKSB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBpZiAobG9jYWxlICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICB0aGlzLnJlc291cmNlcyA9IFNlY3VyaXR5U3VwcG9ydC5nZXRSZXNvdXJjZUJ1bmRsZSgiY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhwYXRoLnJlZ2V4Lm1lc3NhZ2UiLCBsb2NhbGUpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgdGhpcy5yZXNvdXJjZXMgPSBTZWN1cml0eVN1cHBvcnQuZ2V0UmVzb3VyY2VCdW5kbGUoImNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cGF0aC5yZWdleC5tZXNzYWdlIik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbiBtcmUpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJJbnN0YWxsYXRpb24gUHJvYmxlbT8/PyAgQ291bGRuJ3QgbG9hZCBtZXNzYWdlczogIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBtcmUuZ2V0TWVzc2FnZSgpKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIGZpbmFsIFBhcnNlRXhjZXB0aW9uIGV4KFN0cmluZyBrZXksIGludCBsb2MpIHsKLSAgICAgICAgcmV0dXJuIG5ldyBQYXJzZUV4Y2VwdGlvbih0aGlzLnJlc291cmNlcy5nZXRTdHJpbmcoa2V5KSwgbG9jKTsKLSAgICB9Ci0KLSAgICBwcm90ZWN0ZWQgZmluYWwgYm9vbGVhbiBpc1NldChpbnQgZmxhZykgewotICAgICAgICByZXR1cm4gKHRoaXMub3B0aW9ucyAmIGZsYWcpID09IGZsYWc7Ci0gICAgfQotCi0gICAgc3luY2hyb25pemVkIFRva2VuIHBhcnNlKFN0cmluZyByZWdleCwgaW50IG9wdGlvbnMpIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7Ci0gICAgICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7Ci0gICAgICAgIHRoaXMub2Zmc2V0ID0gMDsKLSAgICAgICAgdGhpcy5zZXRDb250ZXh0KFNfTk9STUFMKTsKLSAgICAgICAgdGhpcy5wYXJlbm51bWJlciA9IDE7Ci0gICAgICAgIHRoaXMucGFyZW5PcGVuZWQgPSAxOwotICAgICAgICB0aGlzLmhhc0JhY2tSZWZlcmVuY2VzID0gZmFsc2U7Ci0gICAgICAgIHRoaXMucmVnZXggPSByZWdleDsKLSAgICAgICAgaWYgKHRoaXMuaXNTZXQoUmVndWxhckV4cHJlc3Npb24uRVhURU5ERURfQ09NTUVOVCkpCi0gICAgICAgICAgICB0aGlzLnJlZ2V4ID0gUkVVdGlsLnN0cmlwRXh0ZW5kZWRDb21tZW50KHRoaXMucmVnZXgpOwotICAgICAgICB0aGlzLnJlZ2V4bGVuID0gdGhpcy5yZWdleC5sZW5ndGgoKTsKLQotCi0gICAgICAgIHRoaXMubmV4dCgpOwotICAgICAgICBUb2tlbiByZXQgPSB0aGlzLnBhcnNlUmVnZXgoKTsKLSAgICAgICAgaWYgKHRoaXMub2Zmc2V0ICE9IHRoaXMucmVnZXhsZW4pCi0gICAgICAgICAgICB0aHJvdyBleCgicGFyc2VyLnBhcnNlLjEiLCB0aGlzLm9mZnNldCk7Ci0gICAgICAgIGlmIChwYXJlbkNvdW50IDwgMCkKLSAgICAgICAgICAgIHRocm93IGV4KCJwYXJzZXIuZmFjdG9yLjAiLCB0aGlzLm9mZnNldCk7Ci0gICAgICAgIGlmICh0aGlzLnJlZmVyZW5jZXMgIT0gbnVsbCkgewotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7ICBpIDwgdGhpcy5yZWZlcmVuY2VzLnNpemUoKTsgIGkgKyspIHsKLSAgICAgICAgICAgICAgICBSZWZlcmVuY2VQb3NpdGlvbiBwb3NpdGlvbiA9IChSZWZlcmVuY2VQb3NpdGlvbil0aGlzLnJlZmVyZW5jZXMuZWxlbWVudEF0KGkpOwotICAgICAgICAgICAgICAgIGlmICh0aGlzLnBhcmVubnVtYmVyIDw9IHBvc2l0aW9uLnJlZk51bWJlcikKLSAgICAgICAgICAgICAgICAgICAgdGhyb3cgZXgoInBhcnNlci5wYXJzZS4yIiwgcG9zaXRpb24ucG9zaXRpb24pOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgdGhpcy5yZWZlcmVuY2VzLnJlbW92ZUFsbEVsZW1lbnRzKCk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHJldDsKLSAgICB9Ci0KLSAgICAvKgotICAgIHB1YmxpYyBSZWd1bGFyRXhwcmVzc2lvbiBjcmVhdGVSZWdleChTdHJpbmcgcmVnZXgsIGludCBvcHRpb25zKSB0aHJvd3MgUGFyc2VFeGNlcHRpb24gewotICAgICAgICBUb2tlbiB0b2sgPSB0aGlzLnBhcnNlKHJlZ2V4LCBvcHRpb25zKTsKLSAgICAgICAgcmV0dXJuIG5ldyBSZWd1bGFyRXhwcmVzc2lvbihyZWdleCwgdG9rLCB0aGlzLnBhcmVubnVtYmVyLCB0aGlzLmhhc0JhY2tSZWZlcmVuY2VzLCBvcHRpb25zKTsKLSAgICB9Ci0gICAgKi8KLQotICAgIHByb3RlY3RlZCBmaW5hbCB2b2lkIHNldENvbnRleHQoaW50IGNvbikgewotICAgICAgICB0aGlzLmNvbnRleHQgPSBjb247Ci0gICAgfQotCi0gICAgZmluYWwgaW50IHJlYWQoKSB7Ci0gICAgICAgIHJldHVybiB0aGlzLm5leHR0b2tlbjsKLSAgICB9Ci0KLSAgICBmaW5hbCB2b2lkIG5leHQoKSB7Ci0gICAgICAgIGlmICh0aGlzLm9mZnNldCA+PSB0aGlzLnJlZ2V4bGVuKSB7Ci0gICAgICAgICAgICB0aGlzLmNoYXJkYXRhID0gLTE7Ci0gICAgICAgICAgICB0aGlzLm5leHR0b2tlbiA9IFRfRU9GOwotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0KLSAgICAgICAgaW50IHJldDsKLSAgICAgICAgaW50IGNoID0gdGhpcy5yZWdleC5jaGFyQXQodGhpcy5vZmZzZXQrKyk7Ci0gICAgICAgIHRoaXMuY2hhcmRhdGEgPSBjaDsKLQotICAgICAgICBpZiAodGhpcy5jb250ZXh0ID09IFNfSU5CUkFDS0VUUykgewotICAgICAgICAgICAgLy8gSW4gYSBjaGFyYWN0ZXIgY2xhc3MsIHRoaXMuY2hhcmRhdGEgaGFzIG9uZSBjaGFyYWN0ZXIsIHRoYXQgaXMgdG8gc2F5LAotICAgICAgICAgICAgLy8gYSBwYWlyIG9mIHN1cnJvZ2F0ZXMgaXMgY29tcG9zZWQgYW5kIHN0b3JlZCB0byB0aGlzLmNoYXJkYXRhLgotICAgICAgICAgICAgc3dpdGNoIChjaCkgewotICAgICAgICAgICAgICBjYXNlICdcXCc6Ci0gICAgICAgICAgICAgICAgcmV0ID0gVF9CQUNLU09MSURVUzsKLSAgICAgICAgICAgICAgICBpZiAodGhpcy5vZmZzZXQgPj0gdGhpcy5yZWdleGxlbikKLSAgICAgICAgICAgICAgICAgICAgdGhyb3cgZXgoInBhcnNlci5uZXh0LjEiLCB0aGlzLm9mZnNldC0xKTsKLSAgICAgICAgICAgICAgICB0aGlzLmNoYXJkYXRhID0gdGhpcy5yZWdleC5jaGFyQXQodGhpcy5vZmZzZXQrKyk7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgICAgICAgY2FzZSAnLSc6Ci0gICAgICAgICAgICAgICAgLy8gQWxsb3cgY2hhcmFjdGVyIGNsYXNzIHN1YnRyYWN0aW9uIChyZWdhcmRsZXNzIG9mIHdoZXRoZXIgd2UgYXJlIGluCi0gICAgICAgICAgICAgICAgLy8gWE1MIFNjaGVtYSBtb2RlIG9yIG5vdCkKLSAgICAgICAgICAgICAgICBpZiAodGhpcy5vZmZzZXQgPCB0aGlzLnJlZ2V4bGVuICYmIHRoaXMucmVnZXguY2hhckF0KHRoaXMub2Zmc2V0KSA9PSAnWycpIHsKLSAgICAgICAgICAgICAgICAgICAgdGhpcy5vZmZzZXQrKzsKLSAgICAgICAgICAgICAgICAgICAgcmV0ID0gVF9YTUxTQ0hFTUFfQ0NfU1VCVFJBQ1RJT047Ci0gICAgICAgICAgICAgICAgfSBlbHNlCi0gICAgICAgICAgICAgICAgICAgIHJldCA9IFRfQ0hBUjsKLSAgICAgICAgICAgICAgICBicmVhazsKLQotICAgICAgICAgICAgICBjYXNlICdbJzoKLSAgICAgICAgICAgICAgICBpZiAoIXRoaXMuaXNTZXQoUmVndWxhckV4cHJlc3Npb24uWE1MU0NIRU1BX01PREUpCi0gICAgICAgICAgICAgICAgICAgICYmIHRoaXMub2Zmc2V0IDwgdGhpcy5yZWdleGxlbiAmJiB0aGlzLnJlZ2V4LmNoYXJBdCh0aGlzLm9mZnNldCkgPT0gJzonKSB7Ci0gICAgICAgICAgICAgICAgICAgIHRoaXMub2Zmc2V0Kys7Ci0gICAgICAgICAgICAgICAgICAgIHJldCA9IFRfUE9TSVhfQ0hBUkNMQVNTX1NUQVJUOwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICB9IC8vIFRocm91Z2ggZG93bgotICAgICAgICAgICAgICBkZWZhdWx0OgotICAgICAgICAgICAgICAgIGlmIChSRVV0aWwuaXNIaWdoU3Vycm9nYXRlKGNoKSAmJiB0aGlzLm9mZnNldCA8IHRoaXMucmVnZXhsZW4pIHsKLSAgICAgICAgICAgICAgICAgICAgaW50IGxvdyA9IHRoaXMucmVnZXguY2hhckF0KHRoaXMub2Zmc2V0KTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKFJFVXRpbC5pc0xvd1N1cnJvZ2F0ZShsb3cpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNoYXJkYXRhID0gUkVVdGlsLmNvbXBvc2VGcm9tU3Vycm9nYXRlcyhjaCwgbG93KTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMub2Zmc2V0ICsrOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHJldCA9IFRfQ0hBUjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHRoaXMubmV4dHRva2VuID0gcmV0OwotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0KLSAgICAgICAgc3dpdGNoIChjaCkgewotICAgICAgICAgIGNhc2UgJ3wnOiByZXQgPSBUX09SOyAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICBjYXNlICcqJzogcmV0ID0gVF9TVEFSOyAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgY2FzZSAnKyc6IHJldCA9IFRfUExVUzsgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgIGNhc2UgJz8nOiByZXQgPSBUX1FVRVNUSU9OOyAgICAgICBicmVhazsKLSAgICAgICAgICBjYXNlICcpJzogcmV0ID0gVF9SUEFSRU47ICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgY2FzZSAnLic6IHJldCA9IFRfRE9UOyAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgIGNhc2UgJ1snOiByZXQgPSBUX0xCUkFDS0VUOyAgICAgICBicmVhazsKLSAgICAgICAgICBjYXNlICdeJzoKLSAgICAgICAgICAgICAgaWYgKHRoaXMuaXNTZXQoUmVndWxhckV4cHJlc3Npb24uWE1MU0NIRU1BX01PREUpKSB7Ci0gICAgICAgICAgICAgICAgICByZXQgPSBUX0NIQVI7Ci0gICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICByZXQgPSBUX0NBUkVUOwotICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgIGNhc2UgJyQnOgotICAgICAgICAgICAgICBpZiAodGhpcy5pc1NldChSZWd1bGFyRXhwcmVzc2lvbi5YTUxTQ0hFTUFfTU9ERSkpIHsKLSAgICAgICAgICAgICAgICAgIHJldCA9IFRfQ0hBUjsKLSAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgIHJldCA9IFRfRE9MTEFSOwotICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgIGNhc2UgJygnOgotICAgICAgICAgICAgcmV0ID0gVF9MUEFSRU47Ci0gICAgICAgICAgICBwYXJlbkNvdW50Kys7Ci0gICAgICAgICAgICBpZiAodGhpcy5vZmZzZXQgPj0gdGhpcy5yZWdleGxlbikKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIGlmICh0aGlzLnJlZ2V4LmNoYXJBdCh0aGlzLm9mZnNldCkgIT0gJz8nKQotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgaWYgKCsrdGhpcy5vZmZzZXQgPj0gdGhpcy5yZWdleGxlbikKLSAgICAgICAgICAgICAgICB0aHJvdyBleCgicGFyc2VyLm5leHQuMiIsIHRoaXMub2Zmc2V0LTEpOwotICAgICAgICAgICAgY2ggPSB0aGlzLnJlZ2V4LmNoYXJBdCh0aGlzLm9mZnNldCsrKTsKLSAgICAgICAgICAgIHN3aXRjaCAoY2gpIHsKLSAgICAgICAgICAgICAgY2FzZSAnOic6ICByZXQgPSBUX0xQQVJFTjI7ICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgIGNhc2UgJz0nOiAgcmV0ID0gVF9MT09LQUhFQUQ7ICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICBjYXNlICchJzogIHJldCA9IFRfTkVHQVRJVkVMT09LQUhFQUQ7ICBicmVhazsKLSAgICAgICAgICAgICAgY2FzZSAnWyc6ICByZXQgPSBUX1NFVF9PUEVSQVRJT05TOyAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgIGNhc2UgJz4nOiAgcmV0ID0gVF9JTkRFUEVOREVOVDsgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICBjYXNlICc8JzoKLSAgICAgICAgICAgICAgICBpZiAodGhpcy5vZmZzZXQgPj0gdGhpcy5yZWdleGxlbikKLSAgICAgICAgICAgICAgICAgICAgdGhyb3cgZXgoInBhcnNlci5uZXh0LjIiLCB0aGlzLm9mZnNldC0zKTsKLSAgICAgICAgICAgICAgICBjaCA9IHRoaXMucmVnZXguY2hhckF0KHRoaXMub2Zmc2V0KyspOwotICAgICAgICAgICAgICAgIGlmIChjaCA9PSAnPScpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0ID0gVF9MT09LQkVISU5EOwotICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoY2ggPT0gJyEnKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldCA9IFRfTkVHQVRJVkVMT09LQkVISU5EOwotICAgICAgICAgICAgICAgIH0gZWxzZQotICAgICAgICAgICAgICAgICAgICB0aHJvdyBleCgicGFyc2VyLm5leHQuMyIsIHRoaXMub2Zmc2V0LTMpOwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICBjYXNlICcjJzoKLSAgICAgICAgICAgICAgICB3aGlsZSAodGhpcy5vZmZzZXQgPCB0aGlzLnJlZ2V4bGVuKSB7Ci0gICAgICAgICAgICAgICAgICAgIGNoID0gdGhpcy5yZWdleC5jaGFyQXQodGhpcy5vZmZzZXQrKyk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChjaCA9PSAnKScpICBicmVhazsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaWYgKGNoICE9ICcpJykKLSAgICAgICAgICAgICAgICAgICAgdGhyb3cgZXgoInBhcnNlci5uZXh0LjQiLCB0aGlzLm9mZnNldC0xKTsKLSAgICAgICAgICAgICAgICByZXQgPSBUX0NPTU1FTlQ7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgIGRlZmF1bHQ6Ci0gICAgICAgICAgICAgICAgaWYgKGNoID09ICctJyB8fCAnYScgPD0gY2ggJiYgY2ggPD0gJ3onIHx8ICdBJyA8PSBjaCAmJiBjaCA8PSAnWicpIHsvLyBPcHRpb25zCi0gICAgICAgICAgICAgICAgICAgIHRoaXMub2Zmc2V0IC0tOwotICAgICAgICAgICAgICAgICAgICByZXQgPSBUX01PRElGSUVSUzsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjaCA9PSAnKCcpIHsgICAgICAgICAvLyBjb25kaXRpb25hbAotICAgICAgICAgICAgICAgICAgICByZXQgPSBUX0NPTkRJVElPTjsgICAgICAgICAgLy8gdGhpcy5vZmZzZXRzIHBvaW50cyB0aGUgbmV4dCBvZiAnKCcuCi0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB0aHJvdyBleCgicGFyc2VyLm5leHQuMiIsIHRoaXMub2Zmc2V0LTIpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgICBjYXNlICdcXCc6Ci0gICAgICAgICAgICByZXQgPSBUX0JBQ0tTT0xJRFVTOwotICAgICAgICAgICAgaWYgKHRoaXMub2Zmc2V0ID49IHRoaXMucmVnZXhsZW4pCi0gICAgICAgICAgICAgICAgdGhyb3cgZXgoInBhcnNlci5uZXh0LjEiLCB0aGlzLm9mZnNldC0xKTsKLSAgICAgICAgICAgIHRoaXMuY2hhcmRhdGEgPSB0aGlzLnJlZ2V4LmNoYXJBdCh0aGlzLm9mZnNldCsrKTsKLSAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgICAgZGVmYXVsdDoKLSAgICAgICAgICAgIHJldCA9IFRfQ0hBUjsKLSAgICAgICAgfQotICAgICAgICB0aGlzLm5leHR0b2tlbiA9IHJldDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiByZWdleCA6Oj0gdGVybSAoYHxgIHRlcm0pKgotICAgICAqIHRlcm0gOjo9IGZhY3RvcisKLSAgICAgKiBmYWN0b3IgOjo9ICgnXicgfCAnJCcgfCAnXEEnIHwgJ1xaJyB8ICdceicgfCAnXGInIHwgJ1xCJyB8ICdcPCcgfCAnXD4nCi0gICAgICogICAgICAgICAgICB8IGF0b20gKCgnKicgfCAnKycgfCAnPycgfCBtaW5tYXggKSAnPyc/ICk/KQotICAgICAqICAgICAgICAgICAgfCAnKD89JyByZWdleCAnKScgIHwgJyg/IScgcmVnZXggJyknICB8ICcoPyZsdDs9JyByZWdleCAnKScgIHwgJyg/Jmx0OyEnIHJlZ2V4ICcpJwotICAgICAqIGF0b20gOjo9IGNoYXIgfCAnLicgfCByYW5nZSB8ICcoJyByZWdleCAnKScgfCAnKD86JyByZWdleCAnKScgfCAnXCcgWzAtOV0KLSAgICAgKiAgICAgICAgICB8ICdcdycgfCAnXFcnIHwgJ1xkJyB8ICdcRCcgfCAnXHMnIHwgJ1xTJyB8IGNhdGVnb3J5LWJsb2NrCi0gICAgICovCi0gICAgVG9rZW4gcGFyc2VSZWdleCgpIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7Ci0gICAgICAgIFRva2VuIHRvayA9IHRoaXMucGFyc2VUZXJtKCk7Ci0gICAgICAgIFRva2VuIHBhcmVudCA9IG51bGw7Ci0gICAgICAgIHdoaWxlICh0aGlzLnJlYWQoKSA9PSBUX09SKSB7Ci0gICAgICAgICAgICB0aGlzLm5leHQoKTsgICAgICAgICAgICAgICAgICAgIC8vICd8JwotICAgICAgICAgICAgaWYgKHBhcmVudCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgcGFyZW50ID0gVG9rZW4uY3JlYXRlVW5pb24oKTsKLSAgICAgICAgICAgICAgICBwYXJlbnQuYWRkQ2hpbGQodG9rKTsKLSAgICAgICAgICAgICAgICB0b2sgPSBwYXJlbnQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICB0b2suYWRkQ2hpbGQodGhpcy5wYXJzZVRlcm0oKSk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHRvazsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiB0ZXJtIDo6PSBmYWN0b3IrCi0gICAgICovCi0gICAgVG9rZW4gcGFyc2VUZXJtKCkgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKLSAgICAgICAgaW50IGNoID0gdGhpcy5yZWFkKCk7Ci0gICAgICAgIFRva2VuIHRvayA9IG51bGw7Ci0gICAgICAgIGlmIChjaCA9PSBUX09SIHx8IGNoID09IFRfUlBBUkVOIHx8IGNoID09IFRfRU9GKSB7Ci0gICAgICAgICAgICB0b2sgPSBUb2tlbi5jcmVhdGVFbXB0eSgpOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgdG9rID0gdGhpcy5wYXJzZUZhY3RvcigpOwotICAgICAgICAgICAgVG9rZW4gY29uY2F0ID0gbnVsbDsKLSAgICAgICAgICAgIHdoaWxlICgoY2ggPSB0aGlzLnJlYWQoKSkgIT0gVF9PUiAmJiBjaCAhPSBUX1JQQVJFTiAmJiBjaCAhPSBUX0VPRikgewotICAgICAgICAgICAgICAgIGlmIChjb25jYXQgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBjb25jYXQgPSBUb2tlbi5jcmVhdGVDb25jYXQoKTsKLSAgICAgICAgICAgICAgICAgICAgY29uY2F0LmFkZENoaWxkKHRvayk7Ci0gICAgICAgICAgICAgICAgICAgIHRvayA9IGNvbmNhdDsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgY29uY2F0LmFkZENoaWxkKHRoaXMucGFyc2VGYWN0b3IoKSk7Ci0gICAgICAgICAgICAgICAgLy90b2sgPSBUb2tlbi5jcmVhdGVDb25jYXQodG9rLCB0aGlzLnBhcnNlRmFjdG9yKCkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGlmIChjaCA9PSBUX1JQQVJFTikgewotICAgICAgICAgICAgcGFyZW5Db3VudC0tOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiB0b2s7Ci0gICAgfQotCi0gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotCi0gICAgVG9rZW4gcHJvY2Vzc0NhcmV0KCkgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKLSAgICAgICAgdGhpcy5uZXh0KCk7Ci0gICAgICAgIHJldHVybiBUb2tlbi50b2tlbl9saW5lYmVnaW5uaW5nOwotICAgIH0KLSAgICBUb2tlbiBwcm9jZXNzRG9sbGFyKCkgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKLSAgICAgICAgdGhpcy5uZXh0KCk7Ci0gICAgICAgIHJldHVybiBUb2tlbi50b2tlbl9saW5lZW5kOwotICAgIH0KLSAgICBUb2tlbiBwcm9jZXNzTG9va2FoZWFkKCkgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKLSAgICAgICAgdGhpcy5uZXh0KCk7Ci0gICAgICAgIFRva2VuIHRvayA9IFRva2VuLmNyZWF0ZUxvb2soVG9rZW4uTE9PS0FIRUFELCB0aGlzLnBhcnNlUmVnZXgoKSk7Ci0gICAgICAgIGlmICh0aGlzLnJlYWQoKSAhPSBUX1JQQVJFTikgIHRocm93IGV4KCJwYXJzZXIuZmFjdG9yLjEiLCB0aGlzLm9mZnNldC0xKTsKLSAgICAgICAgdGhpcy5uZXh0KCk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICcpJwotICAgICAgICByZXR1cm4gdG9rOwotICAgIH0KLSAgICBUb2tlbiBwcm9jZXNzTmVnYXRpdmVsb29rYWhlYWQoKSB0aHJvd3MgUGFyc2VFeGNlcHRpb24gewotICAgICAgICB0aGlzLm5leHQoKTsKLSAgICAgICAgVG9rZW4gdG9rID0gVG9rZW4uY3JlYXRlTG9vayhUb2tlbi5ORUdBVElWRUxPT0tBSEVBRCwgdGhpcy5wYXJzZVJlZ2V4KCkpOwotICAgICAgICBpZiAodGhpcy5yZWFkKCkgIT0gVF9SUEFSRU4pICB0aHJvdyBleCgicGFyc2VyLmZhY3Rvci4xIiwgdGhpcy5vZmZzZXQtMSk7Ci0gICAgICAgIHRoaXMubmV4dCgpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAnKScKLSAgICAgICAgcmV0dXJuIHRvazsKLSAgICB9Ci0gICAgVG9rZW4gcHJvY2Vzc0xvb2tiZWhpbmQoKSB0aHJvd3MgUGFyc2VFeGNlcHRpb24gewotICAgICAgICB0aGlzLm5leHQoKTsKLSAgICAgICAgVG9rZW4gdG9rID0gVG9rZW4uY3JlYXRlTG9vayhUb2tlbi5MT09LQkVISU5ELCB0aGlzLnBhcnNlUmVnZXgoKSk7Ci0gICAgICAgIGlmICh0aGlzLnJlYWQoKSAhPSBUX1JQQVJFTikgIHRocm93IGV4KCJwYXJzZXIuZmFjdG9yLjEiLCB0aGlzLm9mZnNldC0xKTsKLSAgICAgICAgdGhpcy5uZXh0KCk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICcpJwotICAgICAgICByZXR1cm4gdG9rOwotICAgIH0KLSAgICBUb2tlbiBwcm9jZXNzTmVnYXRpdmVsb29rYmVoaW5kKCkgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKLSAgICAgICAgdGhpcy5uZXh0KCk7Ci0gICAgICAgIFRva2VuIHRvayA9IFRva2VuLmNyZWF0ZUxvb2soVG9rZW4uTkVHQVRJVkVMT09LQkVISU5ELCB0aGlzLnBhcnNlUmVnZXgoKSk7Ci0gICAgICAgIGlmICh0aGlzLnJlYWQoKSAhPSBUX1JQQVJFTikgIHRocm93IGV4KCJwYXJzZXIuZmFjdG9yLjEiLCB0aGlzLm9mZnNldC0xKTsKLSAgICAgICAgdGhpcy5uZXh0KCk7ICAgICAgICAgICAgICAgICAgICAvLyAnKScKLSAgICAgICAgcmV0dXJuIHRvazsKLSAgICB9Ci0gICAgVG9rZW4gcHJvY2Vzc0JhY2tzb2xpZHVzX0EoKSB0aHJvd3MgUGFyc2VFeGNlcHRpb24gewotICAgICAgICB0aGlzLm5leHQoKTsKLSAgICAgICAgcmV0dXJuIFRva2VuLnRva2VuX3N0cmluZ2JlZ2lubmluZzsKLSAgICB9Ci0gICAgVG9rZW4gcHJvY2Vzc0JhY2tzb2xpZHVzX1ooKSB0aHJvd3MgUGFyc2VFeGNlcHRpb24gewotICAgICAgICB0aGlzLm5leHQoKTsKLSAgICAgICAgcmV0dXJuIFRva2VuLnRva2VuX3N0cmluZ2VuZDI7Ci0gICAgfQotICAgIFRva2VuIHByb2Nlc3NCYWNrc29saWR1c196KCkgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKLSAgICAgICAgdGhpcy5uZXh0KCk7Ci0gICAgICAgIHJldHVybiBUb2tlbi50b2tlbl9zdHJpbmdlbmQ7Ci0gICAgfQotICAgIFRva2VuIHByb2Nlc3NCYWNrc29saWR1c19iKCkgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKLSAgICAgICAgdGhpcy5uZXh0KCk7Ci0gICAgICAgIHJldHVybiBUb2tlbi50b2tlbl93b3JkZWRnZTsKLSAgICB9Ci0gICAgVG9rZW4gcHJvY2Vzc0JhY2tzb2xpZHVzX0IoKSB0aHJvd3MgUGFyc2VFeGNlcHRpb24gewotICAgICAgICB0aGlzLm5leHQoKTsKLSAgICAgICAgcmV0dXJuIFRva2VuLnRva2VuX25vdF93b3JkZWRnZTsKLSAgICB9Ci0gICAgVG9rZW4gcHJvY2Vzc0JhY2tzb2xpZHVzX2x0KCkgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKLSAgICAgICAgdGhpcy5uZXh0KCk7Ci0gICAgICAgIHJldHVybiBUb2tlbi50b2tlbl93b3JkYmVnaW5uaW5nOwotICAgIH0KLSAgICBUb2tlbiBwcm9jZXNzQmFja3NvbGlkdXNfZ3QoKSB0aHJvd3MgUGFyc2VFeGNlcHRpb24gewotICAgICAgICB0aGlzLm5leHQoKTsKLSAgICAgICAgcmV0dXJuIFRva2VuLnRva2VuX3dvcmRlbmQ7Ci0gICAgfQotICAgIFRva2VuIHByb2Nlc3NTdGFyKFRva2VuIHRvaykgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKLSAgICAgICAgdGhpcy5uZXh0KCk7Ci0gICAgICAgIGlmICh0aGlzLnJlYWQoKSA9PSBUX1FVRVNUSU9OKSB7Ci0gICAgICAgICAgICB0aGlzLm5leHQoKTsKLSAgICAgICAgICAgIHJldHVybiBUb2tlbi5jcmVhdGVOR0Nsb3N1cmUodG9rKTsKLSAgICAgICAgfSBlbHNlCi0gICAgICAgICAgICByZXR1cm4gVG9rZW4uY3JlYXRlQ2xvc3VyZSh0b2spOwotICAgIH0KLSAgICBUb2tlbiBwcm9jZXNzUGx1cyhUb2tlbiB0b2spIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7Ci0gICAgICAgIC8vIFgrIC0+IFhYKgotICAgICAgICB0aGlzLm5leHQoKTsKLSAgICAgICAgaWYgKHRoaXMucmVhZCgpID09IFRfUVVFU1RJT04pIHsKLSAgICAgICAgICAgIHRoaXMubmV4dCgpOwotICAgICAgICAgICAgcmV0dXJuIFRva2VuLmNyZWF0ZUNvbmNhdCh0b2ssIFRva2VuLmNyZWF0ZU5HQ2xvc3VyZSh0b2spKTsKLSAgICAgICAgfSBlbHNlCi0gICAgICAgICAgICByZXR1cm4gVG9rZW4uY3JlYXRlQ29uY2F0KHRvaywgVG9rZW4uY3JlYXRlQ2xvc3VyZSh0b2spKTsKLSAgICB9Ci0gICAgVG9rZW4gcHJvY2Vzc1F1ZXN0aW9uKFRva2VuIHRvaykgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKLSAgICAgICAgLy8gWD8gLT4gWHwKLSAgICAgICAgdGhpcy5uZXh0KCk7Ci0gICAgICAgIFRva2VuIHBhciA9IFRva2VuLmNyZWF0ZVVuaW9uKCk7Ci0gICAgICAgIGlmICh0aGlzLnJlYWQoKSA9PSBUX1FVRVNUSU9OKSB7Ci0gICAgICAgICAgICB0aGlzLm5leHQoKTsKLSAgICAgICAgICAgIHBhci5hZGRDaGlsZChUb2tlbi5jcmVhdGVFbXB0eSgpKTsKLSAgICAgICAgICAgIHBhci5hZGRDaGlsZCh0b2spOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgcGFyLmFkZENoaWxkKHRvayk7Ci0gICAgICAgICAgICBwYXIuYWRkQ2hpbGQoVG9rZW4uY3JlYXRlRW1wdHkoKSk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHBhcjsKLSAgICB9Ci0gICAgYm9vbGVhbiBjaGVja1F1ZXN0aW9uKGludCBvZmYpIHsKLSAgICAgICAgcmV0dXJuIG9mZiA8IHRoaXMucmVnZXhsZW4gJiYgdGhpcy5yZWdleC5jaGFyQXQob2ZmKSA9PSAnPyc7Ci0gICAgfQotICAgIFRva2VuIHByb2Nlc3NQYXJlbigpIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7Ci0gICAgICAgIHRoaXMubmV4dCgpOwotICAgICAgICBpbnQgcCA9IHRoaXMucGFyZW5PcGVuZWQrKzsKLSAgICAgICAgVG9rZW4gdG9rID0gVG9rZW4uY3JlYXRlUGFyZW4odGhpcy5wYXJzZVJlZ2V4KCksIHApOwotICAgICAgICBpZiAodGhpcy5yZWFkKCkgIT0gVF9SUEFSRU4pICB0aHJvdyBleCgicGFyc2VyLmZhY3Rvci4xIiwgdGhpcy5vZmZzZXQtMSk7Ci0gICAgICAgIHRoaXMucGFyZW5udW1iZXIrKzsKLSAgICAgICAgdGhpcy5uZXh0KCk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNraXBzICcpJwotICAgICAgICByZXR1cm4gdG9rOwotICAgIH0KLSAgICBUb2tlbiBwcm9jZXNzUGFyZW4yKCkgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKLSAgICAgICAgdGhpcy5uZXh0KCk7Ci0gICAgICAgIFRva2VuIHRvayA9IFRva2VuLmNyZWF0ZVBhcmVuKHRoaXMucGFyc2VSZWdleCgpLCAwKTsKLSAgICAgICAgaWYgKHRoaXMucmVhZCgpICE9IFRfUlBBUkVOKSAgdGhyb3cgZXgoInBhcnNlci5mYWN0b3IuMSIsIHRoaXMub2Zmc2V0LTEpOwotICAgICAgICB0aGlzLm5leHQoKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2tpcHMgJyknCi0gICAgICAgIHJldHVybiB0b2s7Ci0gICAgfQotICAgIFRva2VuIHByb2Nlc3NDb25kaXRpb24oKSB0aHJvd3MgUGFyc2VFeGNlcHRpb24gewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhpcy5vZmZzZXQgcG9pbnRzIHRoZSBuZXh0IG9mICcoJwotICAgICAgICBpZiAodGhpcy5vZmZzZXQrMSA+PSB0aGlzLnJlZ2V4bGVuKSAgdGhyb3cgZXgoInBhcnNlci5mYWN0b3IuNCIsIHRoaXMub2Zmc2V0KTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFBhcnNlcyBhIGNvbmRpdGlvbi4KLSAgICAgICAgaW50IHJlZm5vID0gLTE7Ci0gICAgICAgIFRva2VuIGNvbmRpdGlvbiA9IG51bGw7Ci0gICAgICAgIGludCBjaCA9IHRoaXMucmVnZXguY2hhckF0KHRoaXMub2Zmc2V0KTsKLSAgICAgICAgaWYgKCcxJyA8PSBjaCAmJiBjaCA8PSAnOScpIHsKLSAgICAgICAgICAgIHJlZm5vID0gY2gtJzAnOwotICAgICAgICAgICAgaW50IGZpbmFsUmVmbm8gPSByZWZubzsKLQotICAgICAgICAgICAgaWYgKHRoaXMucGFyZW5udW1iZXIgPD0gcmVmbm8pCi0gICAgICAgICAgICAgICAgdGhyb3cgZXgoInBhcnNlci5wYXJzZS4yIiwgdGhpcy5vZmZzZXQpOwotCi0gICAgICAgICAgICB3aGlsZSAodGhpcy5vZmZzZXQgKyAxIDwgdGhpcy5yZWdleGxlbikgewotICAgICAgICAgICAgICAgIGNoID0gdGhpcy5yZWdleC5jaGFyQXQodGhpcy5vZmZzZXQgKyAxKTsKLSAgICAgICAgICAgICAgICBpZiAoJzEnIDw9IGNoICYmIGNoIDw9ICc5JykgewotICAgICAgICAgICAgICAgICAgICByZWZubyA9IChyZWZubyAqIDEwKSArIChjaCAtICcwJyk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChyZWZubyA8IHRoaXMucGFyZW5udW1iZXIpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVmbm89IHJlZm5vOwotICAgICAgICAgICAgICAgICAgICAgICAgKyt0aGlzLm9mZnNldDsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIHRoaXMuaGFzQmFja1JlZmVyZW5jZXMgPSB0cnVlOwotICAgICAgICAgICAgaWYgKHRoaXMucmVmZXJlbmNlcyA9PSBudWxsKSAgdGhpcy5yZWZlcmVuY2VzID0gbmV3IFZlY3RvcigpOwotICAgICAgICAgICAgdGhpcy5yZWZlcmVuY2VzLmFkZEVsZW1lbnQobmV3IFJlZmVyZW5jZVBvc2l0aW9uKGZpbmFsUmVmbm8sIHRoaXMub2Zmc2V0KSk7Ci0gICAgICAgICAgICB0aGlzLm9mZnNldCArKzsKLSAgICAgICAgICAgIGlmICh0aGlzLnJlZ2V4LmNoYXJBdCh0aGlzLm9mZnNldCkgIT0gJyknKSAgdGhyb3cgZXgoInBhcnNlci5mYWN0b3IuMSIsIHRoaXMub2Zmc2V0KTsKLSAgICAgICAgICAgIHRoaXMub2Zmc2V0ICsrOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgaWYgKGNoID09ICc/JykgIHRoaXMub2Zmc2V0IC0tOyAvLyBQb2ludHMgJygnLgotICAgICAgICAgICAgdGhpcy5uZXh0KCk7Ci0gICAgICAgICAgICBjb25kaXRpb24gPSB0aGlzLnBhcnNlRmFjdG9yKCk7Ci0gICAgICAgICAgICBzd2l0Y2ggKGNvbmRpdGlvbi50eXBlKSB7Ci0gICAgICAgICAgICAgIGNhc2UgVG9rZW4uTE9PS0FIRUFEOgotICAgICAgICAgICAgICBjYXNlIFRva2VuLk5FR0FUSVZFTE9PS0FIRUFEOgotICAgICAgICAgICAgICBjYXNlIFRva2VuLkxPT0tCRUhJTkQ6Ci0gICAgICAgICAgICAgIGNhc2UgVG9rZW4uTkVHQVRJVkVMT09LQkVISU5EOgotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICBjYXNlIFRva2VuLkFOQ0hPUjoKLSAgICAgICAgICAgICAgICBpZiAodGhpcy5yZWFkKCkgIT0gVF9SUEFSRU4pICB0aHJvdyBleCgicGFyc2VyLmZhY3Rvci4xIiwgdGhpcy5vZmZzZXQtMSk7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgIGRlZmF1bHQ6Ci0gICAgICAgICAgICAgICAgdGhyb3cgZXgoInBhcnNlci5mYWN0b3IuNSIsIHRoaXMub2Zmc2V0KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUGFyc2VzIHllcy9uby1wYXR0ZXJucy4KLSAgICAgICAgdGhpcy5uZXh0KCk7Ci0gICAgICAgIFRva2VuIHllc1BhdHRlcm4gPSB0aGlzLnBhcnNlUmVnZXgoKTsKLSAgICAgICAgVG9rZW4gbm9QYXR0ZXJuID0gbnVsbDsKLSAgICAgICAgaWYgKHllc1BhdHRlcm4udHlwZSA9PSBUb2tlbi5VTklPTikgewotICAgICAgICAgICAgaWYgKHllc1BhdHRlcm4uc2l6ZSgpICE9IDIpICB0aHJvdyBleCgicGFyc2VyLmZhY3Rvci42IiwgdGhpcy5vZmZzZXQpOwotICAgICAgICAgICAgbm9QYXR0ZXJuID0geWVzUGF0dGVybi5nZXRDaGlsZCgxKTsKLSAgICAgICAgICAgIHllc1BhdHRlcm4gPSB5ZXNQYXR0ZXJuLmdldENoaWxkKDApOwotICAgICAgICB9Ci0gICAgICAgIGlmICh0aGlzLnJlYWQoKSAhPSBUX1JQQVJFTikgIHRocm93IGV4KCJwYXJzZXIuZmFjdG9yLjEiLCB0aGlzLm9mZnNldC0xKTsKLSAgICAgICAgdGhpcy5uZXh0KCk7Ci0gICAgICAgIHJldHVybiBUb2tlbi5jcmVhdGVDb25kaXRpb24ocmVmbm8sIGNvbmRpdGlvbiwgeWVzUGF0dGVybiwgbm9QYXR0ZXJuKTsKLSAgICB9Ci0gICAgVG9rZW4gcHJvY2Vzc01vZGlmaWVycygpIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGlzLm9mZnNldCBwb2ludHMgdGhlIG5leHQgb2YgJz8nLgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbW9kaWZpZXJzIDo6PSBbaW1zd10qICgnLScgW2ltc3ddKik/ICc6JwotICAgICAgICBpbnQgYWRkID0gMCwgbWFzayA9IDAsIGNoID0gLTE7Ci0gICAgICAgIHdoaWxlICh0aGlzLm9mZnNldCA8IHRoaXMucmVnZXhsZW4pIHsKLSAgICAgICAgICAgIGNoID0gdGhpcy5yZWdleC5jaGFyQXQodGhpcy5vZmZzZXQpOwotICAgICAgICAgICAgaW50IHYgPSBSRVV0aWwuZ2V0T3B0aW9uVmFsdWUoY2gpOwotICAgICAgICAgICAgaWYgKHYgPT0gMCkgIGJyZWFrOyAgICAgICAgICAgICAgICAgLy8gJy0nIG9yICc6Jz8KLSAgICAgICAgICAgIGFkZCB8PSB2OwotICAgICAgICAgICAgdGhpcy5vZmZzZXQgKys7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKHRoaXMub2Zmc2V0ID49IHRoaXMucmVnZXhsZW4pICB0aHJvdyBleCgicGFyc2VyLmZhY3Rvci4yIiwgdGhpcy5vZmZzZXQtMSk7Ci0gICAgICAgIGlmIChjaCA9PSAnLScpIHsKLSAgICAgICAgICAgIHRoaXMub2Zmc2V0ICsrOwotICAgICAgICAgICAgd2hpbGUgKHRoaXMub2Zmc2V0IDwgdGhpcy5yZWdleGxlbikgewotICAgICAgICAgICAgICAgIGNoID0gdGhpcy5yZWdleC5jaGFyQXQodGhpcy5vZmZzZXQpOwotICAgICAgICAgICAgICAgIGludCB2ID0gUkVVdGlsLmdldE9wdGlvblZhbHVlKGNoKTsKLSAgICAgICAgICAgICAgICBpZiAodiA9PSAwKSAgYnJlYWs7ICAgICAgICAgICAgIC8vICc6Jz8KLSAgICAgICAgICAgICAgICBtYXNrIHw9IHY7Ci0gICAgICAgICAgICAgICAgdGhpcy5vZmZzZXQgKys7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAodGhpcy5vZmZzZXQgPj0gdGhpcy5yZWdleGxlbikgIHRocm93IGV4KCJwYXJzZXIuZmFjdG9yLjIiLCB0aGlzLm9mZnNldC0xKTsKLSAgICAgICAgfQotICAgICAgICBUb2tlbiB0b2s7Ci0gICAgICAgIGlmIChjaCA9PSAnOicpIHsKLSAgICAgICAgICAgIHRoaXMub2Zmc2V0ICsrOwotICAgICAgICAgICAgdGhpcy5uZXh0KCk7Ci0gICAgICAgICAgICB0b2sgPSBUb2tlbi5jcmVhdGVNb2RpZmllckdyb3VwKHRoaXMucGFyc2VSZWdleCgpLCBhZGQsIG1hc2spOwotICAgICAgICAgICAgaWYgKHRoaXMucmVhZCgpICE9IFRfUlBBUkVOKSAgdGhyb3cgZXgoInBhcnNlci5mYWN0b3IuMSIsIHRoaXMub2Zmc2V0LTEpOwotICAgICAgICAgICAgdGhpcy5uZXh0KCk7Ci0gICAgICAgIH0gZWxzZSBpZiAoY2ggPT0gJyknKSB7ICAgICAgICAgICAgICAgICAvLyBzdWNoIGFzICg/LWkpCi0gICAgICAgICAgICB0aGlzLm9mZnNldCArKzsKLSAgICAgICAgICAgIHRoaXMubmV4dCgpOwotICAgICAgICAgICAgdG9rID0gVG9rZW4uY3JlYXRlTW9kaWZpZXJHcm91cCh0aGlzLnBhcnNlUmVnZXgoKSwgYWRkLCBtYXNrKTsKLSAgICAgICAgfSBlbHNlCi0gICAgICAgICAgICB0aHJvdyBleCgicGFyc2VyLmZhY3Rvci4zIiwgdGhpcy5vZmZzZXQpOwotCi0gICAgICAgIHJldHVybiB0b2s7Ci0gICAgfQotICAgIFRva2VuIHByb2Nlc3NJbmRlcGVuZGVudCgpIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7Ci0gICAgICAgIHRoaXMubmV4dCgpOwotICAgICAgICBUb2tlbiB0b2sgPSBUb2tlbi5jcmVhdGVMb29rKFRva2VuLklOREVQRU5ERU5ULCB0aGlzLnBhcnNlUmVnZXgoKSk7Ci0gICAgICAgIGlmICh0aGlzLnJlYWQoKSAhPSBUX1JQQVJFTikgIHRocm93IGV4KCJwYXJzZXIuZmFjdG9yLjEiLCB0aGlzLm9mZnNldC0xKTsKLSAgICAgICAgdGhpcy5uZXh0KCk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNraXBzICcpJwotICAgICAgICByZXR1cm4gdG9rOwotICAgIH0KLSAgICBUb2tlbiBwcm9jZXNzQmFja3NvbGlkdXNfYygpIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7Ci0gICAgICAgIGludCBjaDI7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBNdXN0IGJlIGluIDB4MDA0MC0weDAwNWYKLSAgICAgICAgaWYgKHRoaXMub2Zmc2V0ID49IHRoaXMucmVnZXhsZW4KLSAgICAgICAgICAgIHx8ICgoY2gyID0gdGhpcy5yZWdleC5jaGFyQXQodGhpcy5vZmZzZXQrKykpICYgMHhmZmUwKSAhPSAweDAwNDApCi0gICAgICAgICAgICB0aHJvdyBleCgicGFyc2VyLmF0b20uMSIsIHRoaXMub2Zmc2V0LTEpOwotICAgICAgICB0aGlzLm5leHQoKTsKLSAgICAgICAgcmV0dXJuIFRva2VuLmNyZWF0ZUNoYXIoY2gyLTB4NDApOwotICAgIH0KLSAgICBUb2tlbiBwcm9jZXNzQmFja3NvbGlkdXNfQygpIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7Ci0gICAgICAgIHRocm93IGV4KCJwYXJzZXIucHJvY2Vzcy4xIiwgdGhpcy5vZmZzZXQpOwotICAgIH0KLSAgICBUb2tlbiBwcm9jZXNzQmFja3NvbGlkdXNfaSgpIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7Ci0gICAgICAgIFRva2VuIHRvayA9IFRva2VuLmNyZWF0ZUNoYXIoJ2knKTsKLSAgICAgICAgdGhpcy5uZXh0KCk7Ci0gICAgICAgIHJldHVybiB0b2s7Ci0gICAgfQotICAgIFRva2VuIHByb2Nlc3NCYWNrc29saWR1c19JKCkgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKLSAgICAgICAgdGhyb3cgZXgoInBhcnNlci5wcm9jZXNzLjEiLCB0aGlzLm9mZnNldCk7Ci0gICAgfQotICAgIFRva2VuIHByb2Nlc3NCYWNrc29saWR1c19nKCkgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKLSAgICAgICAgdGhpcy5uZXh0KCk7Ci0gICAgICAgIHJldHVybiBUb2tlbi5nZXRHcmFwaGVtZVBhdHRlcm4oKTsKLSAgICB9Ci0gICAgVG9rZW4gcHJvY2Vzc0JhY2tzb2xpZHVzX1goKSB0aHJvd3MgUGFyc2VFeGNlcHRpb24gewotICAgICAgICB0aGlzLm5leHQoKTsKLSAgICAgICAgcmV0dXJuIFRva2VuLmdldENvbWJpbmluZ0NoYXJhY3RlclNlcXVlbmNlKCk7Ci0gICAgfQotICAgIFRva2VuIHByb2Nlc3NCYWNrcmVmZXJlbmNlKCkgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKLSAgICAgICAgaW50IHJlZm51bSA9IHRoaXMuY2hhcmRhdGEtJzAnOwotICAgICAgICBpbnQgZmluYWxSZWZudW0gPSByZWZudW07Ci0KLSAgICAgICAgaWYgKHRoaXMucGFyZW5udW1iZXIgPD0gcmVmbnVtKQotICAgICAgICAgICAgdGhyb3cgZXgoInBhcnNlci5wYXJzZS4yIiwgdGhpcy5vZmZzZXQtMik7Ci0KLSAgICAgICAgd2hpbGUgICh0aGlzLm9mZnNldCA8IHRoaXMucmVnZXhsZW4pIHsKLSAgICAgICAgICAgIGZpbmFsIGludCBjaCA9IHRoaXMucmVnZXguY2hhckF0KHRoaXMub2Zmc2V0KTsKLSAgICAgICAgICAgIGlmICgnMScgPD0gY2ggJiYgY2ggPD0gJzknKSB7Ci0gICAgICAgICAgICAgICAgcmVmbnVtID0gKHJlZm51bSAqIDEwKSArIChjaCAtICcwJyk7Ci0gICAgICAgICAgICAgICAgaWYgKHJlZm51bSA8IHRoaXMucGFyZW5udW1iZXIpIHsKLSAgICAgICAgICAgICAgICAgICAgKyt0aGlzLm9mZnNldDsKLSAgICAgICAgICAgICAgICAgICAgZmluYWxSZWZudW0gPSByZWZudW07Ci0gICAgICAgICAgICAgICAgICAgIHRoaXMuY2hhcmRhdGEgPSBjaDsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgVG9rZW4gdG9rID0gVG9rZW4uY3JlYXRlQmFja1JlZmVyZW5jZShmaW5hbFJlZm51bSk7Ci0gICAgICAgIHRoaXMuaGFzQmFja1JlZmVyZW5jZXMgPSB0cnVlOwotICAgICAgICBpZiAodGhpcy5yZWZlcmVuY2VzID09IG51bGwpICB0aGlzLnJlZmVyZW5jZXMgPSBuZXcgVmVjdG9yKCk7Ci0gICAgICAgIHRoaXMucmVmZXJlbmNlcy5hZGRFbGVtZW50KG5ldyBSZWZlcmVuY2VQb3NpdGlvbihmaW5hbFJlZm51bSwgdGhpcy5vZmZzZXQtMikpOwotICAgICAgICB0aGlzLm5leHQoKTsKLSAgICAgICAgcmV0dXJuIHRvazsKLSAgICB9Ci0KLSAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0KLSAgICAvKioKLSAgICAgKiBmYWN0b3IgOjo9ICgnXicgfCAnJCcgfCAnXEEnIHwgJ1xaJyB8ICdceicgfCAnXGInIHwgJ1xCJyB8ICdcPCcgfCAnXD4nCi0gICAgICogICAgICAgICAgICB8IGF0b20gKCgnKicgfCAnKycgfCAnPycgfCBtaW5tYXggKSAnPyc/ICk/KQotICAgICAqICAgICAgICAgICAgfCAnKD89JyByZWdleCAnKScgIHwgJyg/IScgcmVnZXggJyknICB8ICcoPyZsdDs9JyByZWdleCAnKScgIHwgJyg/Jmx0OyEnIHJlZ2V4ICcpJwotICAgICAqICAgICAgICAgICAgfCAnKD8jJyBbXildKiAnKScKLSAgICAgKiBtaW5tYXggOjo9ICd7JyBtaW4gKCcsJyBtYXg/KT8gJ30nCi0gICAgICogbWluIDo6PSBbMC05XSsKLSAgICAgKiBtYXggOjo9IFswLTldKwotICAgICAqLwotICAgIFRva2VuIHBhcnNlRmFjdG9yKCkgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKLSAgICAgICAgaW50IGNoID0gdGhpcy5yZWFkKCk7Ci0gICAgICAgIFRva2VuIHRvazsKLSAgICAgICAgc3dpdGNoIChjaCkgewotICAgICAgICAgIGNhc2UgVF9DQVJFVDogICAgICAgICByZXR1cm4gdGhpcy5wcm9jZXNzQ2FyZXQoKTsKLSAgICAgICAgICBjYXNlIFRfRE9MTEFSOiAgICAgICAgcmV0dXJuIHRoaXMucHJvY2Vzc0RvbGxhcigpOwotICAgICAgICAgIGNhc2UgVF9MT09LQUhFQUQ6ICAgICByZXR1cm4gdGhpcy5wcm9jZXNzTG9va2FoZWFkKCk7Ci0gICAgICAgICAgY2FzZSBUX05FR0FUSVZFTE9PS0FIRUFEOiByZXR1cm4gdGhpcy5wcm9jZXNzTmVnYXRpdmVsb29rYWhlYWQoKTsKLSAgICAgICAgICBjYXNlIFRfTE9PS0JFSElORDogICAgcmV0dXJuIHRoaXMucHJvY2Vzc0xvb2tiZWhpbmQoKTsKLSAgICAgICAgICBjYXNlIFRfTkVHQVRJVkVMT09LQkVISU5EOiByZXR1cm4gdGhpcy5wcm9jZXNzTmVnYXRpdmVsb29rYmVoaW5kKCk7Ci0KLSAgICAgICAgICBjYXNlIFRfQ09NTUVOVDoKLSAgICAgICAgICAgIHRoaXMubmV4dCgpOwotICAgICAgICAgICAgcmV0dXJuIFRva2VuLmNyZWF0ZUVtcHR5KCk7Ci0KLSAgICAgICAgICBjYXNlIFRfQkFDS1NPTElEVVM6Ci0gICAgICAgICAgICBzd2l0Y2ggKHRoaXMuY2hhcmRhdGEpIHsKLSAgICAgICAgICAgICAgY2FzZSAnQSc6IHJldHVybiB0aGlzLnByb2Nlc3NCYWNrc29saWR1c19BKCk7Ci0gICAgICAgICAgICAgIGNhc2UgJ1onOiByZXR1cm4gdGhpcy5wcm9jZXNzQmFja3NvbGlkdXNfWigpOwotICAgICAgICAgICAgICBjYXNlICd6JzogcmV0dXJuIHRoaXMucHJvY2Vzc0JhY2tzb2xpZHVzX3ooKTsKLSAgICAgICAgICAgICAgY2FzZSAnYic6IHJldHVybiB0aGlzLnByb2Nlc3NCYWNrc29saWR1c19iKCk7Ci0gICAgICAgICAgICAgIGNhc2UgJ0InOiByZXR1cm4gdGhpcy5wcm9jZXNzQmFja3NvbGlkdXNfQigpOwotICAgICAgICAgICAgICBjYXNlICc8JzogcmV0dXJuIHRoaXMucHJvY2Vzc0JhY2tzb2xpZHVzX2x0KCk7Ci0gICAgICAgICAgICAgIGNhc2UgJz4nOiByZXR1cm4gdGhpcy5wcm9jZXNzQmFja3NvbGlkdXNfZ3QoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRocm91Z2ggZG93bgotICAgICAgICB9Ci0gICAgICAgIHRvayA9IHRoaXMucGFyc2VBdG9tKCk7Ci0gICAgICAgIGNoID0gdGhpcy5yZWFkKCk7Ci0gICAgICAgIHN3aXRjaCAoY2gpIHsKLSAgICAgICAgICBjYXNlIFRfU1RBUjogIHJldHVybiB0aGlzLnByb2Nlc3NTdGFyKHRvayk7Ci0gICAgICAgICAgY2FzZSBUX1BMVVM6ICByZXR1cm4gdGhpcy5wcm9jZXNzUGx1cyh0b2spOwotICAgICAgICAgIGNhc2UgVF9RVUVTVElPTjogcmV0dXJuIHRoaXMucHJvY2Vzc1F1ZXN0aW9uKHRvayk7Ci0gICAgICAgICAgY2FzZSBUX0NIQVI6Ci0gICAgICAgICAgICBpZiAodGhpcy5jaGFyZGF0YSA9PSAneycgJiYgdGhpcy5vZmZzZXQgPCB0aGlzLnJlZ2V4bGVuKSB7Ci0KLSAgICAgICAgICAgICAgICBpbnQgb2ZmID0gdGhpcy5vZmZzZXQ7ICAgICAgICAgIC8vIHRoaXMub2Zmc2V0IC0+IG5leHQgb2YgJ3snCi0gICAgICAgICAgICAgICAgaW50IG1pbiA9IDAsIG1heCA9IC0xOwotCi0gICAgICAgICAgICAgICAgaWYgKChjaCA9IHRoaXMucmVnZXguY2hhckF0KG9mZisrKSkgPj0gJzAnICYmIGNoIDw9ICc5JykgewotCi0gICAgICAgICAgICAgICAgICAgIG1pbiA9IGNoIC0nMCc7Ci0gICAgICAgICAgICAgICAgICAgIHdoaWxlIChvZmYgPCB0aGlzLnJlZ2V4bGVuCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAmJiAoY2ggPSB0aGlzLnJlZ2V4LmNoYXJBdChvZmYrKykpID49ICcwJyAmJiBjaCA8PSAnOScpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIG1pbiA9IG1pbioxMCArY2gtJzAnOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1pbiA8IDApCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgZXgoInBhcnNlci5xdWFudGlmaWVyLjUiLCB0aGlzLm9mZnNldCk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIHRocm93IGV4KCJwYXJzZXIucXVhbnRpZmllci4xIiwgdGhpcy5vZmZzZXQpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIG1heCA9IG1pbjsKLSAgICAgICAgICAgICAgICBpZiAoY2ggPT0gJywnKSB7Ci0KLSAgICAgICAgICAgICAgICAgICBpZiAob2ZmID49IHRoaXMucmVnZXhsZW4pIHsKLSAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgZXgoInBhcnNlci5xdWFudGlmaWVyLjMiLCB0aGlzLm9mZnNldCk7Ci0gICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKChjaCA9IHRoaXMucmVnZXguY2hhckF0KG9mZisrKSkgPj0gJzAnICYmIGNoIDw9ICc5JykgewotCi0gICAgICAgICAgICAgICAgICAgICAgICBtYXggPSBjaCAtJzAnOyAgICAgICAvLyB7bWluLG1heH0KLSAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChvZmYgPCB0aGlzLnJlZ2V4bGVuCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgKGNoID0gdGhpcy5yZWdleC5jaGFyQXQob2ZmKyspKSA+PSAnMCcKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiBjaCA8PSAnOScpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXggPSBtYXgqMTAgK2NoLScwJzsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobWF4IDwgMCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgZXgoInBhcnNlci5xdWFudGlmaWVyLjUiLCB0aGlzLm9mZnNldCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtaW4gPiBtYXgpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgZXgoInBhcnNlci5xdWFudGlmaWVyLjQiLCB0aGlzLm9mZnNldCk7Ci0gICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgIGVsc2UgeyAvLyBhc3N1bWUge21pbix9Ci0gICAgICAgICAgICAgICAgICAgICAgICBtYXggPSAtMTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgaWYgKGNoICE9ICd9JykKLSAgICAgICAgICAgICAgICAgICB0aHJvdyBleCgicGFyc2VyLnF1YW50aWZpZXIuMiIsIHRoaXMub2Zmc2V0KTsKLQotICAgICAgICAgICAgICAgaWYgKHRoaXMuY2hlY2tRdWVzdGlvbihvZmYpKSB7ICAvLyBvZmYgLT4gbmV4dCBvZiAnfScKLSAgICAgICAgICAgICAgICAgICAgdG9rID0gVG9rZW4uY3JlYXRlTkdDbG9zdXJlKHRvayk7Ci0gICAgICAgICAgICAgICAgICAgIHRoaXMub2Zmc2V0ID0gb2ZmKzE7Ci0gICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgdG9rID0gVG9rZW4uY3JlYXRlQ2xvc3VyZSh0b2spOwotICAgICAgICAgICAgICAgICAgICB0aGlzLm9mZnNldCA9IG9mZjsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICB0b2suc2V0TWluKG1pbik7Ci0gICAgICAgICAgICAgICAgdG9rLnNldE1heChtYXgpOwotICAgICAgICAgICAgICAgIC8vU3lzdGVtLmVyci5wcmludGxuKCJDTE9TVVJFOiAiK21pbisiLCAiK21heCk7Ci0gICAgICAgICAgICAgICAgdGhpcy5uZXh0KCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHRvazsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBhdG9tIDo6PSBjaGFyIHwgJy4nIHwgY2hhci1jbGFzcyB8ICcoJyByZWdleCAnKScgfCAnKD86JyByZWdleCAnKScgfCAnXCcgWzAtOV0KLSAgICAgKiAgICAgICAgICB8ICdcdycgfCAnXFcnIHwgJ1xkJyB8ICdcRCcgfCAnXHMnIHwgJ1xTJyB8IGNhdGVnb3J5LWJsb2NrCi0gICAgICogICAgICAgICAgfCAnKD8+JyByZWdleCAnKScKLSAgICAgKiBjaGFyIDo6PSAnXFwnIHwgJ1wnIFtlZm5ydF0gfCBibXAtY29kZSB8IGNoYXJhY3Rlci0xCi0gICAgICovCi0gICAgVG9rZW4gcGFyc2VBdG9tKCkgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKLSAgICAgICAgaW50IGNoID0gdGhpcy5yZWFkKCk7Ci0gICAgICAgIFRva2VuIHRvayA9IG51bGw7Ci0gICAgICAgIHN3aXRjaCAoY2gpIHsKLSAgICAgICAgICBjYXNlIFRfTFBBUkVOOiAgICAgICAgcmV0dXJuIHRoaXMucHJvY2Vzc1BhcmVuKCk7Ci0gICAgICAgICAgY2FzZSBUX0xQQVJFTjI6ICAgICAgIHJldHVybiB0aGlzLnByb2Nlc3NQYXJlbjIoKTsgLy8gJyg/OicKLSAgICAgICAgICBjYXNlIFRfQ09ORElUSU9OOiAgICAgcmV0dXJuIHRoaXMucHJvY2Vzc0NvbmRpdGlvbigpOyAvLyAnKD8oJwotICAgICAgICAgIGNhc2UgVF9NT0RJRklFUlM6ICAgICByZXR1cm4gdGhpcy5wcm9jZXNzTW9kaWZpZXJzKCk7IC8vICg/bW9kaWZpZXJzIC4uLiApCi0gICAgICAgICAgY2FzZSBUX0lOREVQRU5ERU5UOiAgIHJldHVybiB0aGlzLnByb2Nlc3NJbmRlcGVuZGVudCgpOwotICAgICAgICAgIGNhc2UgVF9ET1Q6Ci0gICAgICAgICAgICB0aGlzLm5leHQoKTsgICAgICAgICAgICAgICAgICAgIC8vIFNraXBzICcuJwotICAgICAgICAgICAgdG9rID0gVG9rZW4udG9rZW5fZG90OwotICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgICAgIC8qKgotICAgICAgICAgICAgICogY2hhci1jbGFzcyA6Oj0gJ1snICggJ14nPyByYW5nZSAnLCc/KSsgJ10nCi0gICAgICAgICAgICAgKiByYW5nZSA6Oj0gJ1xkJyB8ICdcdycgfCAnXHMnIHwgY2F0ZWdvcnktYmxvY2sgfCByYW5nZS1jaGFyCi0gICAgICAgICAgICAgKiAgICAgICAgICAgfCByYW5nZS1jaGFyICctJyByYW5nZS1jaGFyCi0gICAgICAgICAgICAgKiByYW5nZS1jaGFyIDo6PSAnXFsnIHwgJ1xdJyB8ICdcXCcgfCAnXCcgWywtZWZucnR2XSB8IGJtcC1jb2RlIHwgY2hhcmFjdGVyLTIKLSAgICAgICAgICAgICAqIGJtcC1jaGFyIDo6PSAnXCcgJ3UnIFswLTlhLWZBLUZdIFswLTlhLWZBLUZdIFswLTlhLWZBLUZdIFswLTlhLWZBLUZdCi0gICAgICAgICAgICAgKi8KLSAgICAgICAgICBjYXNlIFRfTEJSQUNLRVQ6ICAgICAgcmV0dXJuIHRoaXMucGFyc2VDaGFyYWN0ZXJDbGFzcyh0cnVlKTsKLSAgICAgICAgICBjYXNlIFRfU0VUX09QRVJBVElPTlM6IHJldHVybiB0aGlzLnBhcnNlU2V0T3BlcmF0aW9ucygpOwotCi0gICAgICAgICAgY2FzZSBUX0JBQ0tTT0xJRFVTOgotICAgICAgICAgICAgc3dpdGNoICh0aGlzLmNoYXJkYXRhKSB7Ci0gICAgICAgICAgICAgIGNhc2UgJ2QnOiAgY2FzZSAnRCc6Ci0gICAgICAgICAgICAgIGNhc2UgJ3cnOiAgY2FzZSAnVyc6Ci0gICAgICAgICAgICAgIGNhc2UgJ3MnOiAgY2FzZSAnUyc6Ci0gICAgICAgICAgICAgICAgdG9rID0gdGhpcy5nZXRUb2tlbkZvclNob3J0aGFuZCh0aGlzLmNoYXJkYXRhKTsKLSAgICAgICAgICAgICAgICB0aGlzLm5leHQoKTsKLSAgICAgICAgICAgICAgICByZXR1cm4gdG9rOwotCi0gICAgICAgICAgICAgIGNhc2UgJ2UnOiAgY2FzZSAnZic6ICBjYXNlICduJzogIGNhc2UgJ3InOgotICAgICAgICAgICAgICBjYXNlICd0JzogIGNhc2UgJ3UnOiAgY2FzZSAndic6ICBjYXNlICd4JzoKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIGludCBjaDIgPSB0aGlzLmRlY29kZUVzY2FwZWQoKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGNoMiA8IDB4MTAwMDApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHRvayA9IFRva2VuLmNyZWF0ZUNoYXIoY2gyKTsKLSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHRvayA9IFRva2VuLmNyZWF0ZVN0cmluZyhSRVV0aWwuZGVjb21wb3NlVG9TdXJyb2dhdGVzKGNoMikpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgICAgICAgIGNhc2UgJ2MnOiByZXR1cm4gdGhpcy5wcm9jZXNzQmFja3NvbGlkdXNfYygpOwotICAgICAgICAgICAgICBjYXNlICdDJzogcmV0dXJuIHRoaXMucHJvY2Vzc0JhY2tzb2xpZHVzX0MoKTsKLSAgICAgICAgICAgICAgY2FzZSAnaSc6IHJldHVybiB0aGlzLnByb2Nlc3NCYWNrc29saWR1c19pKCk7Ci0gICAgICAgICAgICAgIGNhc2UgJ0knOiByZXR1cm4gdGhpcy5wcm9jZXNzQmFja3NvbGlkdXNfSSgpOwotICAgICAgICAgICAgICBjYXNlICdnJzogcmV0dXJuIHRoaXMucHJvY2Vzc0JhY2tzb2xpZHVzX2coKTsKLSAgICAgICAgICAgICAgY2FzZSAnWCc6IHJldHVybiB0aGlzLnByb2Nlc3NCYWNrc29saWR1c19YKCk7Ci0gICAgICAgICAgICAgIGNhc2UgJzEnOiAgY2FzZSAnMic6ICBjYXNlICczJzogIGNhc2UgJzQnOgotICAgICAgICAgICAgICBjYXNlICc1JzogIGNhc2UgJzYnOiAgY2FzZSAnNyc6ICBjYXNlICc4JzogIGNhc2UgJzknOgotICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnByb2Nlc3NCYWNrcmVmZXJlbmNlKCk7Ci0KLSAgICAgICAgICAgICAgY2FzZSAnUCc6Ci0gICAgICAgICAgICAgIGNhc2UgJ3AnOgotICAgICAgICAgICAgICAgIGludCBwc3RhcnQgPSB0aGlzLm9mZnNldDsKLSAgICAgICAgICAgICAgICB0b2sgPSBwcm9jZXNzQmFja3NvbGlkdXNfcFAodGhpcy5jaGFyZGF0YSk7Ci0gICAgICAgICAgICAgICAgaWYgKHRvayA9PSBudWxsKSAgdGhyb3cgdGhpcy5leCgicGFyc2VyLmF0b20uNSIsIHBzdGFydCk7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgICAgICAgZGVmYXVsdDoKLSAgICAgICAgICAgICAgICB0b2sgPSBUb2tlbi5jcmVhdGVDaGFyKHRoaXMuY2hhcmRhdGEpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgdGhpcy5uZXh0KCk7Ci0gICAgICAgICAgICBicmVhazsKLQotICAgICAgICAgIGNhc2UgVF9DSEFSOgotICAgICAgICAgICAgaWYgKHRoaXMuY2hhcmRhdGEgPT0gJ10nIHx8IHRoaXMuY2hhcmRhdGEgPT0gJ3snIHx8IHRoaXMuY2hhcmRhdGEgPT0gJ30nKQotICAgICAgICAgICAgICAgIHRocm93IHRoaXMuZXgoInBhcnNlci5hdG9tLjQiLCB0aGlzLm9mZnNldC0xKTsKLSAgICAgICAgICAgIHRvayA9IFRva2VuLmNyZWF0ZUNoYXIodGhpcy5jaGFyZGF0YSk7Ci0gICAgICAgICAgICBpbnQgaGlnaCA9IHRoaXMuY2hhcmRhdGE7Ci0gICAgICAgICAgICB0aGlzLm5leHQoKTsKLSAgICAgICAgICAgIGlmIChSRVV0aWwuaXNIaWdoU3Vycm9nYXRlKGhpZ2gpCi0gICAgICAgICAgICAgICAgJiYgdGhpcy5yZWFkKCkgPT0gVF9DSEFSICYmIFJFVXRpbC5pc0xvd1N1cnJvZ2F0ZSh0aGlzLmNoYXJkYXRhKSkgewotICAgICAgICAgICAgICAgIGNoYXJbXSBzdXIgPSBuZXcgY2hhclsyXTsKLSAgICAgICAgICAgICAgICBzdXJbMF0gPSAoY2hhciloaWdoOwotICAgICAgICAgICAgICAgIHN1clsxXSA9IChjaGFyKXRoaXMuY2hhcmRhdGE7Ci0gICAgICAgICAgICAgICAgdG9rID0gVG9rZW4uY3JlYXRlUGFyZW4oVG9rZW4uY3JlYXRlU3RyaW5nKG5ldyBTdHJpbmcoc3VyKSksIDApOwotICAgICAgICAgICAgICAgIHRoaXMubmV4dCgpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgICBkZWZhdWx0OgotICAgICAgICAgICAgdGhyb3cgdGhpcy5leCgicGFyc2VyLmF0b20uNCIsIHRoaXMub2Zmc2V0LTEpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiB0b2s7Ci0gICAgfQotCi0gICAgcHJvdGVjdGVkIFJhbmdlVG9rZW4gcHJvY2Vzc0JhY2tzb2xpZHVzX3BQKGludCBjKSB0aHJvd3MgUGFyc2VFeGNlcHRpb24gewotCi0gICAgICAgIHRoaXMubmV4dCgpOwotICAgICAgICBpZiAodGhpcy5yZWFkKCkgIT0gVF9DSEFSIHx8IHRoaXMuY2hhcmRhdGEgIT0gJ3snKQotICAgICAgICAgICAgdGhyb3cgdGhpcy5leCgicGFyc2VyLmF0b20uMiIsIHRoaXMub2Zmc2V0LTEpOwotCi0gICAgICAgIC8vIGhhbmRsZSBjYXRlZ29yeSBlc2NhcGUKLSAgICAgICAgYm9vbGVhbiBwb3NpdGl2ZSA9IGMgPT0gJ3AnOwotICAgICAgICBpbnQgbmFtZXN0YXJ0ID0gdGhpcy5vZmZzZXQ7Ci0gICAgICAgIGludCBuYW1lZW5kID0gdGhpcy5yZWdleC5pbmRleE9mKCd9JywgbmFtZXN0YXJ0KTsKLQotICAgICAgICBpZiAobmFtZWVuZCA8IDApCi0gICAgICAgICAgICB0aHJvdyB0aGlzLmV4KCJwYXJzZXIuYXRvbS4zIiwgdGhpcy5vZmZzZXQpOwotCi0gICAgICAgIFN0cmluZyBwbmFtZSA9IHRoaXMucmVnZXguc3Vic3RyaW5nKG5hbWVzdGFydCwgbmFtZWVuZCk7Ci0gICAgICAgIHRoaXMub2Zmc2V0ID0gbmFtZWVuZCsxOwotCi0gICAgICAgIHJldHVybiBUb2tlbi5nZXRSYW5nZShwbmFtZSwgcG9zaXRpdmUsIHRoaXMuaXNTZXQoUmVndWxhckV4cHJlc3Npb24uWE1MU0NIRU1BX01PREUpKTsKLSAgICB9Ci0KLSAgICBpbnQgcHJvY2Vzc0NJaW5DaGFyYWN0ZXJDbGFzcyhSYW5nZVRva2VuIHRvaywgaW50IGMpIHsKLSAgICAgICAgcmV0dXJuIHRoaXMuZGVjb2RlRXNjYXBlZCgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIGNoYXItY2xhc3MgOjo9ICdbJyAoICdeJz8gcmFuZ2UgJywnPykrICddJwotICAgICAqIHJhbmdlIDo6PSAnXGQnIHwgJ1x3JyB8ICdccycgfCBjYXRlZ29yeS1ibG9jayB8IHJhbmdlLWNoYXIKLSAgICAgKiAgICAgICAgICAgfCByYW5nZS1jaGFyICctJyByYW5nZS1jaGFyCi0gICAgICogcmFuZ2UtY2hhciA6Oj0gJ1xbJyB8ICdcXScgfCAnXFwnIHwgJ1wnIFssLWVmbnJ0dl0gfCBibXAtY29kZSB8IGNoYXJhY3Rlci0yCi0gICAgICogYm1wLWNvZGUgOjo9ICdcJyAndScgWzAtOWEtZkEtRl0gWzAtOWEtZkEtRl0gWzAtOWEtZkEtRl0gWzAtOWEtZkEtRl0KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgUmFuZ2VUb2tlbiBwYXJzZUNoYXJhY3RlckNsYXNzKGJvb2xlYW4gdXNlTnJhbmdlKSB0aHJvd3MgUGFyc2VFeGNlcHRpb24gewotICAgICAgICB0aGlzLnNldENvbnRleHQoU19JTkJSQUNLRVRTKTsKLSAgICAgICAgdGhpcy5uZXh0KCk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICdbJwotICAgICAgICBib29sZWFuIG5yYW5nZSA9IGZhbHNlOwotICAgICAgICBSYW5nZVRva2VuIGJhc2UgPSBudWxsOwotICAgICAgICBSYW5nZVRva2VuIHRvazsKLSAgICAgICAgaWYgKHRoaXMucmVhZCgpID09IFRfQ0hBUiAmJiB0aGlzLmNoYXJkYXRhID09ICdeJykgewotICAgICAgICAgICAgbnJhbmdlID0gdHJ1ZTsKLSAgICAgICAgICAgIHRoaXMubmV4dCgpOyAgICAgICAgICAgICAgICAgICAgICAgIC8vICdeJwotICAgICAgICAgICAgaWYgKHVzZU5yYW5nZSkgewotICAgICAgICAgICAgICAgIHRvayA9IFRva2VuLmNyZWF0ZU5SYW5nZSgpOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBiYXNlID0gVG9rZW4uY3JlYXRlUmFuZ2UoKTsKLSAgICAgICAgICAgICAgICBiYXNlLmFkZFJhbmdlKDAsIFRva2VuLlVURjE2X01BWCk7Ci0gICAgICAgICAgICAgICAgdG9rID0gVG9rZW4uY3JlYXRlUmFuZ2UoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIHRvayA9IFRva2VuLmNyZWF0ZVJhbmdlKCk7Ci0gICAgICAgIH0KLSAgICAgICAgaW50IHR5cGU7Ci0gICAgICAgIGJvb2xlYW4gZmlyc3Rsb29wID0gdHJ1ZTsKLSAgICAgICAgd2hpbGUgKCh0eXBlID0gdGhpcy5yZWFkKCkpICE9IFRfRU9GKSB7Ci0gICAgICAgICAgICBpZiAodHlwZSA9PSBUX0NIQVIgJiYgdGhpcy5jaGFyZGF0YSA9PSAnXScgJiYgIWZpcnN0bG9vcCkKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIGludCBjID0gdGhpcy5jaGFyZGF0YTsKLSAgICAgICAgICAgIGJvb2xlYW4gZW5kID0gZmFsc2U7Ci0gICAgICAgICAgICBpZiAodHlwZSA9PSBUX0JBQ0tTT0xJRFVTKSB7Ci0gICAgICAgICAgICAgICAgc3dpdGNoIChjKSB7Ci0gICAgICAgICAgICAgICAgICBjYXNlICdkJzogIGNhc2UgJ0QnOgotICAgICAgICAgICAgICAgICAgY2FzZSAndyc6ICBjYXNlICdXJzoKLSAgICAgICAgICAgICAgICAgIGNhc2UgJ3MnOiAgY2FzZSAnUyc6Ci0gICAgICAgICAgICAgICAgICAgIHRvay5tZXJnZVJhbmdlcyh0aGlzLmdldFRva2VuRm9yU2hvcnRoYW5kKGMpKTsKLSAgICAgICAgICAgICAgICAgICAgZW5kID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgICAgICAgICAgIGNhc2UgJ2knOiAgY2FzZSAnSSc6Ci0gICAgICAgICAgICAgICAgICBjYXNlICdjJzogIGNhc2UgJ0MnOgotICAgICAgICAgICAgICAgICAgICBjID0gdGhpcy5wcm9jZXNzQ0lpbkNoYXJhY3RlckNsYXNzKHRvaywgYyk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChjIDwgMCkgIGVuZCA9IHRydWU7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgICAgICAgICAgICBjYXNlICdwJzoKLSAgICAgICAgICAgICAgICAgIGNhc2UgJ1AnOgotICAgICAgICAgICAgICAgICAgICBpbnQgcHN0YXJ0ID0gdGhpcy5vZmZzZXQ7Ci0gICAgICAgICAgICAgICAgICAgIFJhbmdlVG9rZW4gdG9rMiA9IHRoaXMucHJvY2Vzc0JhY2tzb2xpZHVzX3BQKGMpOwotICAgICAgICAgICAgICAgICAgICBpZiAodG9rMiA9PSBudWxsKSAgdGhyb3cgdGhpcy5leCgicGFyc2VyLmF0b20uNSIsIHBzdGFydCk7Ci0gICAgICAgICAgICAgICAgICAgIHRvay5tZXJnZVJhbmdlcyh0b2syKTsKLSAgICAgICAgICAgICAgICAgICAgZW5kID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6Ci0gICAgICAgICAgICAgICAgICAgIGMgPSB0aGlzLmRlY29kZUVzY2FwZWQoKTsKLSAgICAgICAgICAgICAgICB9IC8vIFwgKyBjCi0gICAgICAgICAgICB9IC8vIGJhY2tzb2xpZHVzCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBQT1NJWCBDaGFyYWN0ZXIgY2xhc3Mgc3VjaCBhcyBbOmFsbnVtOl0KLSAgICAgICAgICAgIGVsc2UgaWYgKHR5cGUgPT0gVF9QT1NJWF9DSEFSQ0xBU1NfU1RBUlQpIHsKLSAgICAgICAgICAgICAgICBpbnQgbmFtZWVuZCA9IHRoaXMucmVnZXguaW5kZXhPZignOicsIHRoaXMub2Zmc2V0KTsKLSAgICAgICAgICAgICAgICBpZiAobmFtZWVuZCA8IDApIHRocm93IHRoaXMuZXgoInBhcnNlci5jYy4xIiwgdGhpcy5vZmZzZXQpOwotICAgICAgICAgICAgICAgIGJvb2xlYW4gcG9zaXRpdmUgPSB0cnVlOwotICAgICAgICAgICAgICAgIGlmICh0aGlzLnJlZ2V4LmNoYXJBdCh0aGlzLm9mZnNldCkgPT0gJ14nKSB7Ci0gICAgICAgICAgICAgICAgICAgIHRoaXMub2Zmc2V0ICsrOwotICAgICAgICAgICAgICAgICAgICBwb3NpdGl2ZSA9IGZhbHNlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBTdHJpbmcgbmFtZSA9IHRoaXMucmVnZXguc3Vic3RyaW5nKHRoaXMub2Zmc2V0LCBuYW1lZW5kKTsKLSAgICAgICAgICAgICAgICBSYW5nZVRva2VuIHJhbmdlID0gVG9rZW4uZ2V0UmFuZ2UobmFtZSwgcG9zaXRpdmUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaXNTZXQoUmVndWxhckV4cHJlc3Npb24uWE1MU0NIRU1BX01PREUpKTsKLSAgICAgICAgICAgICAgICBpZiAocmFuZ2UgPT0gbnVsbCkgIHRocm93IHRoaXMuZXgoInBhcnNlci5jYy4zIiwgdGhpcy5vZmZzZXQpOwotICAgICAgICAgICAgICAgIHRvay5tZXJnZVJhbmdlcyhyYW5nZSk7Ci0gICAgICAgICAgICAgICAgZW5kID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICBpZiAobmFtZWVuZCsxID49IHRoaXMucmVnZXhsZW4gfHwgdGhpcy5yZWdleC5jaGFyQXQobmFtZWVuZCsxKSAhPSAnXScpCi0gICAgICAgICAgICAgICAgICAgIHRocm93IHRoaXMuZXgoInBhcnNlci5jYy4xIiwgbmFtZWVuZCk7Ci0gICAgICAgICAgICAgICAgdGhpcy5vZmZzZXQgPSBuYW1lZW5kKzI7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmICh0eXBlID09IFRfWE1MU0NIRU1BX0NDX1NVQlRSQUNUSU9OICYmICFmaXJzdGxvb3ApIHsKLSAgICAgICAgICAgICAgICBpZiAobnJhbmdlKSB7Ci0gICAgICAgICAgICAgICAgICAgIG5yYW5nZSA9IGZhbHNlOwotICAgICAgICAgICAgICAgICAgICBpZiAodXNlTnJhbmdlKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICB0b2sgPSAoUmFuZ2VUb2tlbikgVG9rZW4uY29tcGxlbWVudFJhbmdlcyh0b2spOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgYmFzZS5zdWJ0cmFjdFJhbmdlcyh0b2spOwotICAgICAgICAgICAgICAgICAgICAgICAgdG9rID0gYmFzZTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBSYW5nZVRva2VuIHJhbmdlMiA9IHRoaXMucGFyc2VDaGFyYWN0ZXJDbGFzcyhmYWxzZSk7Ci0gICAgICAgICAgICAgICAgdG9rLnN1YnRyYWN0UmFuZ2VzKHJhbmdlMik7Ci0gICAgICAgICAgICAgICAgaWYgKHRoaXMucmVhZCgpICE9IFRfQ0hBUiB8fCB0aGlzLmNoYXJkYXRhICE9ICddJykgewotICAgICAgICAgICAgICAgICAgICB0aHJvdyB0aGlzLmV4KCJwYXJzZXIuY2MuNSIsIHRoaXMub2Zmc2V0KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgYnJlYWs7ICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBFeGl0IHRoaXMgbG9vcAotICAgICAgICAgICAgfQotICAgICAgICAgICAgdGhpcy5uZXh0KCk7Ci0gICAgICAgICAgICBpZiAoIWVuZCkgeyAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpZiBub3Qgc2hvcnRoYW5kcy4uLgotICAgICAgICAgICAgICAgIGlmICh0aGlzLnJlYWQoKSAhPSBUX0NIQVIgfHwgdGhpcy5jaGFyZGF0YSAhPSAnLScpIHsgLy8gSGVyZSBpcyBubyAnLScuCi0gICAgICAgICAgICAgICAgICAgIGlmICghdGhpcy5pc1NldChSZWd1bGFyRXhwcmVzc2lvbi5JR05PUkVfQ0FTRSkgfHwgYyA+IDB4ZmZmZikgewotICAgICAgICAgICAgICAgICAgICAgICAgdG9rLmFkZFJhbmdlKGMsIGMpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgYWRkQ2FzZUluc2Vuc2l0aXZlQ2hhcih0b2ssIGMpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGUgPT0gVF9YTUxTQ0hFTUFfQ0NfU1VCVFJBQ1RJT04pIHsKLSAgICAgICAgICAgICAgICAgICAgdGhyb3cgdGhpcy5leCgicGFyc2VyLmNjLjgiLCB0aGlzLm9mZnNldC0xKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIHRoaXMubmV4dCgpOyAvLyBTa2lwcyAnLScKLSAgICAgICAgICAgICAgICAgICAgaWYgKCh0eXBlID0gdGhpcy5yZWFkKCkpID09IFRfRU9GKSAgdGhyb3cgdGhpcy5leCgicGFyc2VyLmNjLjIiLCB0aGlzLm9mZnNldCk7Ci0gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlID09IFRfQ0hBUiAmJiB0aGlzLmNoYXJkYXRhID09ICddJykgewotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF0aGlzLmlzU2V0KFJlZ3VsYXJFeHByZXNzaW9uLklHTk9SRV9DQVNFKSB8fCBjID4gMHhmZmZmKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgdG9rLmFkZFJhbmdlKGMsIGMpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkQ2FzZUluc2Vuc2l0aXZlQ2hhcih0b2ssIGMpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgdG9rLmFkZFJhbmdlKCctJywgJy0nKTsKLSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGludCByYW5nZWVuZCA9IHRoaXMuY2hhcmRhdGE7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZSA9PSBUX0JBQ0tTT0xJRFVTKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmFuZ2VlbmQgPSB0aGlzLmRlY29kZUVzY2FwZWQoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubmV4dCgpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGMgPiByYW5nZWVuZCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IHRoaXMuZXgoInBhcnNlci5vcGUuMyIsIHRoaXMub2Zmc2V0LTEpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF0aGlzLmlzU2V0KFJlZ3VsYXJFeHByZXNzaW9uLklHTk9SRV9DQVNFKSB8fAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYyA+IDB4ZmZmZiAmJiByYW5nZWVuZCA+IDB4ZmZmZikpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b2suYWRkUmFuZ2UoYywgcmFuZ2VlbmQpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkQ2FzZUluc2Vuc2l0aXZlQ2hhclJhbmdlKHRvaywgYywgcmFuZ2VlbmQpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKHRoaXMuaXNTZXQoUmVndWxhckV4cHJlc3Npb24uU1BFQ0lBTF9DT01NQSkKLSAgICAgICAgICAgICAgICAmJiB0aGlzLnJlYWQoKSA9PSBUX0NIQVIgJiYgdGhpcy5jaGFyZGF0YSA9PSAnLCcpIHsKLSAgICAgICAgICAgICAgICB0aGlzLm5leHQoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGZpcnN0bG9vcCA9IGZhbHNlOwotICAgICAgICB9Ci0gICAgICAgIGlmICh0aGlzLnJlYWQoKSA9PSBUX0VPRikgewotICAgICAgICAgICAgdGhyb3cgdGhpcy5leCgicGFyc2VyLmNjLjIiLCB0aGlzLm9mZnNldCk7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoIXVzZU5yYW5nZSAmJiBucmFuZ2UpIHsKLSAgICAgICAgICAgIGJhc2Uuc3VidHJhY3RSYW5nZXModG9rKTsKLSAgICAgICAgICAgIHRvayA9IGJhc2U7Ci0gICAgICAgIH0KLSAgICAgICAgdG9rLnNvcnRSYW5nZXMoKTsKLSAgICAgICAgdG9rLmNvbXBhY3RSYW5nZXMoKTsKLSAgICAgICAgdGhpcy5zZXRDb250ZXh0KFNfTk9STUFMKTsKLSAgICAgICAgdGhpcy5uZXh0KCk7ICAgICAgICAgICAgICAgICAgICAvLyBTa2lwcyAnXScKLQotICAgICAgICByZXR1cm4gdG9rOwotICAgIH0KLQotICAgIC8qKgotICAgICAqICcoP1snIC4uLiAnXScgKCgnLScgfCAnKycgfCAnJicpICdbJyAuLi4gJ10nKT8gJyknCi0gICAgICovCi0gICAgcHJvdGVjdGVkIFJhbmdlVG9rZW4gcGFyc2VTZXRPcGVyYXRpb25zKCkgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKLSAgICAgICAgUmFuZ2VUb2tlbiB0b2sgPSB0aGlzLnBhcnNlQ2hhcmFjdGVyQ2xhc3MoZmFsc2UpOwotICAgICAgICBpbnQgdHlwZTsKLSAgICAgICAgd2hpbGUgKCh0eXBlID0gdGhpcy5yZWFkKCkpICE9IFRfUlBBUkVOKSB7Ci0gICAgICAgICAgICBpbnQgY2ggPSB0aGlzLmNoYXJkYXRhOwotICAgICAgICAgICAgaWYgKHR5cGUgPT0gVF9DSEFSICYmIChjaCA9PSAnLScgfHwgY2ggPT0gJyYnKQotICAgICAgICAgICAgICAgIHx8IHR5cGUgPT0gVF9QTFVTKSB7Ci0gICAgICAgICAgICAgICAgdGhpcy5uZXh0KCk7Ci0gICAgICAgICAgICAgICAgaWYgKHRoaXMucmVhZCgpICE9IFRfTEJSQUNLRVQpIHRocm93IGV4KCJwYXJzZXIub3BlLjEiLCB0aGlzLm9mZnNldC0xKTsKLSAgICAgICAgICAgICAgICBSYW5nZVRva2VuIHQyID0gdGhpcy5wYXJzZUNoYXJhY3RlckNsYXNzKGZhbHNlKTsKLSAgICAgICAgICAgICAgICBpZiAodHlwZSA9PSBUX1BMVVMpCi0gICAgICAgICAgICAgICAgICAgIHRvay5tZXJnZVJhbmdlcyh0Mik7Ci0gICAgICAgICAgICAgICAgZWxzZSBpZiAoY2ggPT0gJy0nKQotICAgICAgICAgICAgICAgICAgICB0b2suc3VidHJhY3RSYW5nZXModDIpOwotICAgICAgICAgICAgICAgIGVsc2UgaWYgKGNoID09ICcmJykKLSAgICAgICAgICAgICAgICAgICAgdG9rLmludGVyc2VjdFJhbmdlcyh0Mik7Ci0gICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiQVNTRVJUIik7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIHRocm93IGV4KCJwYXJzZXIub3BlLjIiLCB0aGlzLm9mZnNldC0xKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICB0aGlzLm5leHQoKTsKLSAgICAgICAgcmV0dXJuIHRvazsKLSAgICB9Ci0KLSAgICBUb2tlbiBnZXRUb2tlbkZvclNob3J0aGFuZChpbnQgY2gpIHsKLSAgICAgICAgVG9rZW4gdG9rOwotICAgICAgICBzd2l0Y2ggKGNoKSB7Ci0gICAgICAgICAgY2FzZSAnZCc6Ci0gICAgICAgICAgICB0b2sgPSB0aGlzLmlzU2V0KFJlZ3VsYXJFeHByZXNzaW9uLlVTRV9VTklDT0RFX0NBVEVHT1JZKQotICAgICAgICAgICAgICAgID8gVG9rZW4uZ2V0UmFuZ2UoIk5kIiwgdHJ1ZSkgOiBUb2tlbi50b2tlbl8wdG85OwotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgY2FzZSAnRCc6Ci0gICAgICAgICAgICB0b2sgPSB0aGlzLmlzU2V0KFJlZ3VsYXJFeHByZXNzaW9uLlVTRV9VTklDT0RFX0NBVEVHT1JZKQotICAgICAgICAgICAgICAgID8gVG9rZW4uZ2V0UmFuZ2UoIk5kIiwgZmFsc2UpIDogVG9rZW4udG9rZW5fbm90XzB0bzk7Ci0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgICBjYXNlICd3JzoKLSAgICAgICAgICAgIHRvayA9IHRoaXMuaXNTZXQoUmVndWxhckV4cHJlc3Npb24uVVNFX1VOSUNPREVfQ0FURUdPUlkpCi0gICAgICAgICAgICAgICAgPyBUb2tlbi5nZXRSYW5nZSgiSXNXb3JkIiwgdHJ1ZSkgOiBUb2tlbi50b2tlbl93b3JkY2hhcnM7Ci0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgICBjYXNlICdXJzoKLSAgICAgICAgICAgIHRvayA9IHRoaXMuaXNTZXQoUmVndWxhckV4cHJlc3Npb24uVVNFX1VOSUNPREVfQ0FURUdPUlkpCi0gICAgICAgICAgICAgICAgPyBUb2tlbi5nZXRSYW5nZSgiSXNXb3JkIiwgZmFsc2UpIDogVG9rZW4udG9rZW5fbm90X3dvcmRjaGFyczsKLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgIGNhc2UgJ3MnOgotICAgICAgICAgICAgdG9rID0gdGhpcy5pc1NldChSZWd1bGFyRXhwcmVzc2lvbi5VU0VfVU5JQ09ERV9DQVRFR09SWSkKLSAgICAgICAgICAgICAgICA/IFRva2VuLmdldFJhbmdlKCJJc1NwYWNlIiwgdHJ1ZSkgOiBUb2tlbi50b2tlbl9zcGFjZXM7Ci0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgICBjYXNlICdTJzoKLSAgICAgICAgICAgIHRvayA9IHRoaXMuaXNTZXQoUmVndWxhckV4cHJlc3Npb24uVVNFX1VOSUNPREVfQ0FURUdPUlkpCi0gICAgICAgICAgICAgICAgPyBUb2tlbi5nZXRSYW5nZSgiSXNTcGFjZSIsIGZhbHNlKSA6IFRva2VuLnRva2VuX25vdF9zcGFjZXM7Ci0gICAgICAgICAgICBicmVhazsKLQotICAgICAgICAgIGRlZmF1bHQ6Ci0gICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiSW50ZXJuYWwgRXJyb3I6IHNob3J0aGFuZHM6IFxcdSIrSW50ZWdlci50b1N0cmluZyhjaCwgMTYpKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gdG9rOwotICAgIH0KLQotICAgIC8qKgotICAgICAqLwotICAgIGludCBkZWNvZGVFc2NhcGVkKCkgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKHRoaXMucmVhZCgpICE9IFRfQkFDS1NPTElEVVMpICB0aHJvdyBleCgicGFyc2VyLm5leHQuMSIsIHRoaXMub2Zmc2V0LTEpOwotICAgICAgICBpbnQgYyA9IHRoaXMuY2hhcmRhdGE7Ci0gICAgICAgIHN3aXRjaCAoYykgewotICAgICAgICAgIGNhc2UgJ2UnOiAgYyA9IDB4MWI7ICBicmVhazsgLy8gRVNDQVBFIFUrMDAxQgotICAgICAgICAgIGNhc2UgJ2YnOiAgYyA9ICdcZic7ICBicmVhazsgLy8gRk9STSBGRUVEIFUrMDAwQwotICAgICAgICAgIGNhc2UgJ24nOiAgYyA9ICdcbic7ICBicmVhazsgLy8gTElORSBGRUVEIFUrMDAwQQotICAgICAgICAgIGNhc2UgJ3InOiAgYyA9ICdccic7ICBicmVhazsgLy8gQ1JSSUFHRSBSRVRVUk4gVSswMDBECi0gICAgICAgICAgY2FzZSAndCc6ICBjID0gJ1x0JzsgIGJyZWFrOyAvLyBIT1JJWk9OVEFMIFRBQlVMQVRJT04gVSswMDA5Ci0gICAgICAgICAgLy9jYXNlICd2JzogIGMgPSAweDBiOyAgYnJlYWs7IC8vIFZFUlRJQ0FMIFRBQlVMQVRJT04gVSswMDBCCi0gICAgICAgICAgY2FzZSAneCc6Ci0gICAgICAgICAgICB0aGlzLm5leHQoKTsKLSAgICAgICAgICAgIGlmICh0aGlzLnJlYWQoKSAhPSBUX0NIQVIpICB0aHJvdyBleCgicGFyc2VyLmRlc2NhcGUuMSIsIHRoaXMub2Zmc2V0LTEpOwotICAgICAgICAgICAgaWYgKHRoaXMuY2hhcmRhdGEgPT0gJ3snKSB7Ci0gICAgICAgICAgICAgICAgaW50IHYxID0gMDsKLSAgICAgICAgICAgICAgICBpbnQgdXYgPSAwOwotICAgICAgICAgICAgICAgIGRvIHsKLSAgICAgICAgICAgICAgICAgICAgdGhpcy5uZXh0KCk7Ci0gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnJlYWQoKSAhPSBUX0NIQVIpICB0aHJvdyBleCgicGFyc2VyLmRlc2NhcGUuMSIsIHRoaXMub2Zmc2V0LTEpOwotICAgICAgICAgICAgICAgICAgICBpZiAoKHYxID0gaGV4Q2hhcih0aGlzLmNoYXJkYXRhKSkgPCAwKQotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIGlmICh1diA+IHV2KjE2KSB0aHJvdyBleCgicGFyc2VyLmRlc2NhcGUuMiIsIHRoaXMub2Zmc2V0LTEpOwotICAgICAgICAgICAgICAgICAgICB1diA9IHV2KjE2K3YxOwotICAgICAgICAgICAgICAgIH0gd2hpbGUgKHRydWUpOwotICAgICAgICAgICAgICAgIGlmICh0aGlzLmNoYXJkYXRhICE9ICd9JykgIHRocm93IGV4KCJwYXJzZXIuZGVzY2FwZS4zIiwgdGhpcy5vZmZzZXQtMSk7Ci0gICAgICAgICAgICAgICAgaWYgKHV2ID4gVG9rZW4uVVRGMTZfTUFYKSAgdGhyb3cgZXgoInBhcnNlci5kZXNjYXBlLjQiLCB0aGlzLm9mZnNldC0xKTsKLSAgICAgICAgICAgICAgICBjID0gdXY7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIGludCB2MSA9IDA7Ci0gICAgICAgICAgICAgICAgaWYgKHRoaXMucmVhZCgpICE9IFRfQ0hBUiB8fCAodjEgPSBoZXhDaGFyKHRoaXMuY2hhcmRhdGEpKSA8IDApCi0gICAgICAgICAgICAgICAgICAgIHRocm93IGV4KCJwYXJzZXIuZGVzY2FwZS4xIiwgdGhpcy5vZmZzZXQtMSk7Ci0gICAgICAgICAgICAgICAgaW50IHV2ID0gdjE7Ci0gICAgICAgICAgICAgICAgdGhpcy5uZXh0KCk7Ci0gICAgICAgICAgICAgICAgaWYgKHRoaXMucmVhZCgpICE9IFRfQ0hBUiB8fCAodjEgPSBoZXhDaGFyKHRoaXMuY2hhcmRhdGEpKSA8IDApCi0gICAgICAgICAgICAgICAgICAgIHRocm93IGV4KCJwYXJzZXIuZGVzY2FwZS4xIiwgdGhpcy5vZmZzZXQtMSk7Ci0gICAgICAgICAgICAgICAgdXYgPSB1dioxNit2MTsKLSAgICAgICAgICAgICAgICBjID0gdXY7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBicmVhazsKLQotICAgICAgICAgIGNhc2UgJ3UnOgotICAgICAgICAgICAgaW50IHYxID0gMDsKLSAgICAgICAgICAgIHRoaXMubmV4dCgpOwotICAgICAgICAgICAgaWYgKHRoaXMucmVhZCgpICE9IFRfQ0hBUiB8fCAodjEgPSBoZXhDaGFyKHRoaXMuY2hhcmRhdGEpKSA8IDApCi0gICAgICAgICAgICAgICAgdGhyb3cgZXgoInBhcnNlci5kZXNjYXBlLjEiLCB0aGlzLm9mZnNldC0xKTsKLSAgICAgICAgICAgIGludCB1diA9IHYxOwotICAgICAgICAgICAgdGhpcy5uZXh0KCk7Ci0gICAgICAgICAgICBpZiAodGhpcy5yZWFkKCkgIT0gVF9DSEFSIHx8ICh2MSA9IGhleENoYXIodGhpcy5jaGFyZGF0YSkpIDwgMCkKLSAgICAgICAgICAgICAgICB0aHJvdyBleCgicGFyc2VyLmRlc2NhcGUuMSIsIHRoaXMub2Zmc2V0LTEpOwotICAgICAgICAgICAgdXYgPSB1dioxNit2MTsKLSAgICAgICAgICAgIHRoaXMubmV4dCgpOwotICAgICAgICAgICAgaWYgKHRoaXMucmVhZCgpICE9IFRfQ0hBUiB8fCAodjEgPSBoZXhDaGFyKHRoaXMuY2hhcmRhdGEpKSA8IDApCi0gICAgICAgICAgICAgICAgdGhyb3cgZXgoInBhcnNlci5kZXNjYXBlLjEiLCB0aGlzLm9mZnNldC0xKTsKLSAgICAgICAgICAgIHV2ID0gdXYqMTYrdjE7Ci0gICAgICAgICAgICB0aGlzLm5leHQoKTsKLSAgICAgICAgICAgIGlmICh0aGlzLnJlYWQoKSAhPSBUX0NIQVIgfHwgKHYxID0gaGV4Q2hhcih0aGlzLmNoYXJkYXRhKSkgPCAwKQotICAgICAgICAgICAgICAgIHRocm93IGV4KCJwYXJzZXIuZGVzY2FwZS4xIiwgdGhpcy5vZmZzZXQtMSk7Ci0gICAgICAgICAgICB1diA9IHV2KjE2K3YxOwotICAgICAgICAgICAgYyA9IHV2OwotICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgICBjYXNlICd2JzoKLSAgICAgICAgICAgIHRoaXMubmV4dCgpOwotICAgICAgICAgICAgaWYgKHRoaXMucmVhZCgpICE9IFRfQ0hBUiB8fCAodjEgPSBoZXhDaGFyKHRoaXMuY2hhcmRhdGEpKSA8IDApCi0gICAgICAgICAgICAgICAgdGhyb3cgZXgoInBhcnNlci5kZXNjYXBlLjEiLCB0aGlzLm9mZnNldC0xKTsKLSAgICAgICAgICAgIHV2ID0gdjE7Ci0gICAgICAgICAgICB0aGlzLm5leHQoKTsKLSAgICAgICAgICAgIGlmICh0aGlzLnJlYWQoKSAhPSBUX0NIQVIgfHwgKHYxID0gaGV4Q2hhcih0aGlzLmNoYXJkYXRhKSkgPCAwKQotICAgICAgICAgICAgICAgIHRocm93IGV4KCJwYXJzZXIuZGVzY2FwZS4xIiwgdGhpcy5vZmZzZXQtMSk7Ci0gICAgICAgICAgICB1diA9IHV2KjE2K3YxOwotICAgICAgICAgICAgdGhpcy5uZXh0KCk7Ci0gICAgICAgICAgICBpZiAodGhpcy5yZWFkKCkgIT0gVF9DSEFSIHx8ICh2MSA9IGhleENoYXIodGhpcy5jaGFyZGF0YSkpIDwgMCkKLSAgICAgICAgICAgICAgICB0aHJvdyBleCgicGFyc2VyLmRlc2NhcGUuMSIsIHRoaXMub2Zmc2V0LTEpOwotICAgICAgICAgICAgdXYgPSB1dioxNit2MTsKLSAgICAgICAgICAgIHRoaXMubmV4dCgpOwotICAgICAgICAgICAgaWYgKHRoaXMucmVhZCgpICE9IFRfQ0hBUiB8fCAodjEgPSBoZXhDaGFyKHRoaXMuY2hhcmRhdGEpKSA8IDApCi0gICAgICAgICAgICAgICAgdGhyb3cgZXgoInBhcnNlci5kZXNjYXBlLjEiLCB0aGlzLm9mZnNldC0xKTsKLSAgICAgICAgICAgIHV2ID0gdXYqMTYrdjE7Ci0gICAgICAgICAgICB0aGlzLm5leHQoKTsKLSAgICAgICAgICAgIGlmICh0aGlzLnJlYWQoKSAhPSBUX0NIQVIgfHwgKHYxID0gaGV4Q2hhcih0aGlzLmNoYXJkYXRhKSkgPCAwKQotICAgICAgICAgICAgICAgIHRocm93IGV4KCJwYXJzZXIuZGVzY2FwZS4xIiwgdGhpcy5vZmZzZXQtMSk7Ci0gICAgICAgICAgICB1diA9IHV2KjE2K3YxOwotICAgICAgICAgICAgdGhpcy5uZXh0KCk7Ci0gICAgICAgICAgICBpZiAodGhpcy5yZWFkKCkgIT0gVF9DSEFSIHx8ICh2MSA9IGhleENoYXIodGhpcy5jaGFyZGF0YSkpIDwgMCkKLSAgICAgICAgICAgICAgICB0aHJvdyBleCgicGFyc2VyLmRlc2NhcGUuMSIsIHRoaXMub2Zmc2V0LTEpOwotICAgICAgICAgICAgdXYgPSB1dioxNit2MTsKLSAgICAgICAgICAgIGlmICh1diA+IFRva2VuLlVURjE2X01BWCkgIHRocm93IGV4KCJwYXJzZXIuZGVzY2FwcGUuNCIsIHRoaXMub2Zmc2V0LTEpOwotICAgICAgICAgICAgYyA9IHV2OwotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgY2FzZSAnQSc6Ci0gICAgICAgICAgY2FzZSAnWic6Ci0gICAgICAgICAgY2FzZSAneic6Ci0gICAgICAgICAgICB0aHJvdyBleCgicGFyc2VyLmRlc2NhcGUuNSIsIHRoaXMub2Zmc2V0LTIpOwotICAgICAgICAgIGRlZmF1bHQ6Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGM7Ci0gICAgfQotCi0gICAgc3RhdGljIHByaXZhdGUgZmluYWwgaW50IGhleENoYXIoaW50IGNoKSB7Ci0gICAgICAgIGlmIChjaCA8ICcwJykgIHJldHVybiAtMTsKLSAgICAgICAgaWYgKGNoID4gJ2YnKSAgcmV0dXJuIC0xOwotICAgICAgICBpZiAoY2ggPD0gJzknKSAgcmV0dXJuIGNoLScwJzsKLSAgICAgICAgaWYgKGNoIDwgJ0EnKSAgcmV0dXJuIC0xOwotICAgICAgICBpZiAoY2ggPD0gJ0YnKSAgcmV0dXJuIGNoLSdBJysxMDsKLSAgICAgICAgaWYgKGNoIDwgJ2EnKSAgcmV0dXJuIC0xOwotICAgICAgICByZXR1cm4gY2gtJ2EnKzEwOwotICAgIH0KLQotICAgIHN0YXRpYyBwcm90ZWN0ZWQgZmluYWwgdm9pZCBhZGRDYXNlSW5zZW5zaXRpdmVDaGFyKFJhbmdlVG9rZW4gdG9rLCBpbnQgYykgewotICAgICAgICBmaW5hbCBpbnRbXSBjYXNlTWFwID0gQ2FzZUluc2Vuc2l0aXZlTWFwLmdldChjKTsKLSAgICAgICAgdG9rLmFkZFJhbmdlKGMsIGMpOwotCi0gICAgICAgIGlmIChjYXNlTWFwICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZvciAoaW50IGk9MDsgaTxjYXNlTWFwLmxlbmd0aDsgaSs9MikgewotICAgICAgICAgICAgICAgIHRvay5hZGRSYW5nZShjYXNlTWFwW2ldLCBjYXNlTWFwW2ldKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgfQotCi0gICAgc3RhdGljIHByb3RlY3RlZCBmaW5hbCB2b2lkIGFkZENhc2VJbnNlbnNpdGl2ZUNoYXJSYW5nZShSYW5nZVRva2VuIHRvaywgaW50IHN0YXJ0LCBpbnQgZW5kKSB7Ci0gICAgICAgIGludFtdIGNhc2VNYXA7Ci0gICAgICAgIGludCByMSwgcjI7Ci0gICAgICAgIGlmIChzdGFydCA8PSBlbmQpIHsKLSAgICAgICAgICAgIHIxID0gc3RhcnQ7Ci0gICAgICAgICAgICByMiA9IGVuZDsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIHIxID0gZW5kOwotICAgICAgICAgICAgcjIgPSBzdGFydDsKLSAgICAgICAgfQotCi0gICAgICAgIHRvay5hZGRSYW5nZShyMSwgcjIpOwotICAgICAgICBmb3IgKGludCBjaCA9IHIxOyAgY2ggPD0gcjI7ICBjaCsrKSB7Ci0gICAgICAgICAgICBjYXNlTWFwID0gQ2FzZUluc2Vuc2l0aXZlTWFwLmdldChjaCk7Ci0gICAgICAgICAgICBpZiAoY2FzZU1hcCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaT0wOyBpPGNhc2VNYXAubGVuZ3RoOyBpKz0yKSB7Ci0gICAgICAgICAgICAgICAgICAgIHRvay5hZGRSYW5nZShjYXNlTWFwW2ldLCBjYXNlTWFwW2ldKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hwYXRoL3JlZ2V4L1JlZ3VsYXJFeHByZXNzaW9uLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hwYXRoL3JlZ2V4L1JlZ3VsYXJFeHByZXNzaW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGZhNDg4ZDYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cGF0aC9yZWdleC9SZWd1bGFyRXhwcmVzc2lvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjQ0NiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDIsMjAwNCwyMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHBhdGgucmVnZXg7Ci0KLWltcG9ydCBqYXZhLnRleHQuQ2hhcmFjdGVySXRlcmF0b3I7Ci1pbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKLWltcG9ydCBqYXZhLnV0aWwuU3RhY2s7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuSW50U3RhY2s7Ci0KLS8qKgotICogQSByZWd1bGFyIGV4cHJlc3Npb24gbWF0Y2hpbmcgZW5naW5lIHVzaW5nIE5vbi1kZXRlcm1pbmlzdGljIEZpbml0ZSBBdXRvbWF0b24gKE5GQSkuCi0gKiBUaGlzIGVuZ2luZSBkb2VzIG5vdCBjb25mb3JtIHRvIHRoZSBQT1NJWCByZWd1bGFyIGV4cHJlc3Npb24uCi0gKgotICogPGhyIHdpZHRoPSI1MCUiPgotICogPGgzPkhvdyB0byB1c2U8L2gzPgotICoKLSAqIDxkbD4KLSAqICAgPGR0PkEuIFN0YW5kYXJkIHdheQotICogICA8ZGQ+Ci0gKiA8cHJlPgotICogUmVndWxhckV4cHJlc3Npb24gcmUgPSBuZXcgUmVndWxhckV4cHJlc3Npb24oPHZhcj5yZWdleDwvdmFyPik7Ci0gKiBpZiAocmUubWF0Y2hlcyh0ZXh0KSkgeyAuLi4gfQotICogPC9wcmU+Ci0gKgotICogICA8ZHQ+Qi4gQ2FwdHVyaW5nIGdyb3VwcwotICogICA8ZGQ+Ci0gKiA8cHJlPgotICogUmVndWxhckV4cHJlc3Npb24gcmUgPSBuZXcgUmVndWxhckV4cHJlc3Npb24oPHZhcj5yZWdleDwvdmFyPik7Ci0gKiBNYXRjaCBtYXRjaCA9IG5ldyBNYXRjaCgpOwotICogaWYgKHJlLm1hdGNoZXModGV4dCwgbWF0Y2gpKSB7Ci0gKiAgICAgLi4uIC8vIFlvdSBjYW4gcmVmZXIgY2FwdHVyZWQgdGV4dHMgd2l0aCBtZXRob2RzIG9mIHRoZSA8Y29kZT5NYXRjaDwvY29kZT4gY2xhc3MuCi0gKiB9Ci0gKiA8L3ByZT4KLSAqCi0gKiA8L2RsPgotICoKLSAqIDxoND5DYXNlLWluc2Vuc2l0aXZlIG1hdGNoaW5nPC9oND4KLSAqIDxwcmU+Ci0gKiBSZWd1bGFyRXhwcmVzc2lvbiByZSA9IG5ldyBSZWd1bGFyRXhwcmVzc2lvbig8dmFyPnJlZ2V4PC92YXI+LCAiaSIpOwotICogaWYgKHJlLm1hdGNoZXModGV4dCkgPj0gMCkgeyAuLi59Ci0gKiA8L3ByZT4KLSAqCi0gKiA8aDQ+T3B0aW9uczwvaDQ+Ci0gKiA8cD5Zb3UgY2FuIHNwZWNpZnkgb3B0aW9ucyB0byA8YSBocmVmPSIjUmVndWxhckV4cHJlc3Npb24oamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZykiPjxjb2RlPlJlZ3VsYXJFeHByZXNzaW9uKDwvY29kZT48dmFyPnJlZ2V4PC92YXI+PGNvZGU+LCA8L2NvZGU+PHZhcj5vcHRpb25zPC92YXI+PGNvZGU+KTwvY29kZT48L2E+Ci0gKiAgICBvciA8YSBocmVmPSIjc2V0UGF0dGVybihqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nKSI+PGNvZGU+c2V0UGF0dGVybig8L2NvZGU+PHZhcj5yZWdleDwvdmFyPjxjb2RlPiwgPC9jb2RlPjx2YXI+b3B0aW9uczwvdmFyPjxjb2RlPik8L2NvZGU+PC9hPi4KLSAqICAgIFRoaXMgPHZhcj5vcHRpb25zPC92YXI+IHBhcmFtZXRlciBjb25zaXN0cyBvZiB0aGUgZm9sbG93aW5nIGNoYXJhY3RlcnMuCi0gKiA8L3A+Ci0gKiA8ZGw+Ci0gKiAgIDxkdD48YSBuYW1lPSJJX09QVElPTiI+PGNvZGU+ImkiPC9jb2RlPjwvYT4KLSAqICAgPGRkPlRoaXMgb3B0aW9uIGluZGljYXRlcyBjYXNlLWluc2Vuc2l0aXZlIG1hdGNoaW5nLgotICogICA8ZHQ+PGEgbmFtZT0iTV9PUFRJT04iPjxjb2RlPiJtIjwvY29kZT48L2E+Ci0gKiAgIDxkZCBjbGFzcz0iUkVHRVgiPjxrYmQ+Xjwva2JkPiBhbmQgPGtiZD4kPC9rYmQ+IGNvbnNpZGVyIHRoZSBFT0wgY2hhcmFjdGVycyB3aXRoaW4gdGhlIHRleHQuCi0gKiAgIDxkdD48YSBuYW1lPSJTX09QVElPTiI+PGNvZGU+InMiPC9jb2RlPjwvYT4KLSAqICAgPGRkIGNsYXNzPSJSRUdFWCI+PGtiZD4uPC9rYmQ+IG1hdGNoZXMgYW55IG9uZSBjaGFyYWN0ZXIuCi0gKiAgIDxkdD48YSBuYW1lPSJVX09QVElPTiI+PGNvZGU+InUiPC9jb2RlPjwvYT4KLSAqICAgPGRkIGNsYXNzPSJSRUdFWCI+UmVkZWZpbmVzIDxLYmQ+XGQgXEQgXHcgXFcgXHMgXFMgXGIgXEIgXCZsdDsgXD48L2tiZD4gYXMgYmVjb21pbmcgdG8gVW5pY29kZS4KLSAqICAgPGR0PjxhIG5hbWU9IldfT1BUSU9OIj48Y29kZT4idyI8L2NvZGU+PC9hPgotICogICA8ZGQgY2xhc3M9IlJFR0VYIj5CeSB0aGlzIG9wdGlvbiwgPGtiZD5cYiBcQiBcJmx0OyBcPjwva2JkPiBhcmUgcHJvY2Vzc2VkIHdpdGggdGhlIG1ldGhvZCBvZgotICogICAgICAnVW5pY29kZSBSZWd1bGFyIEV4cHJlc3Npb24gR3VpZGVsaW5lcycgUmV2aXNpb24gNC4KLSAqICAgICAgV2hlbiAidyIgYW5kICJ1IiBhcmUgc3BlY2lmaWVkIGF0IHRoZSBzYW1lIHRpbWUsCi0gKiAgICAgIDxrYmQ+XGIgXEIgXCZsdDsgXD48L2tiZD4gYXJlIHByb2Nlc3NlZCBmb3IgdGhlICJ3IiBvcHRpb24uCi0gKiAgIDxkdD48YSBuYW1lPSJDT01NQV9PUFRJT04iPjxjb2RlPiIsIjwvY29kZT48L2E+Ci0gKiAgIDxkZD5UaGUgcGFyc2VyIHRyZWF0cyBhIGNvbW1hIGluIGEgY2hhcmFjdGVyIGNsYXNzIGFzIGEgcmFuZ2Ugc2VwYXJhdG9yLgotICogICAgICA8a2JkIGNsYXNzPSJSRUdFWCI+W2EsYl08L2tiZD4gbWF0Y2hlcyA8a2JkPmE8L2tiZD4gb3IgPGtiZD4sPC9rYmQ+IG9yIDxrYmQ+Yjwva2JkPiB3aXRob3V0IHRoaXMgb3B0aW9uLgotICogICAgICA8a2JkIGNsYXNzPSJSRUdFWCI+W2EsYl08L2tiZD4gbWF0Y2hlcyA8a2JkPmE8L2tiZD4gb3IgPGtiZD5iPC9rYmQ+IHdpdGggdGhpcyBvcHRpb24uCi0gKgotICogICA8ZHQ+PGEgbmFtZT0iWF9PUFRJT04iPjxjb2RlPiJYIjwvY29kZT48L2E+Ci0gKiAgIDxkZCBjbGFzcz0iUkVHRVgiPgotICogICAgICAgQnkgdGhpcyBvcHRpb24sIHRoZSBlbmdpbmUgY29uZm9tcyB0byA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAwL1dELXhtbHNjaGVtYS0yLTIwMDAwNDA3LyNyZWdleHMiPlhNTCBTY2hlbWE6IFJlZ3VsYXIgRXhwcmVzc2lvbjwvYT4uCi0gKiAgICAgICBUaGUgPGNvZGU+bWF0Y2goKTwvY29kZT4gbWV0aG9kIGRvZXMgbm90IGRvIHN1YnNyaW5nIG1hdGNoaW5nCi0gKiAgICAgICBidXQgZW50aXJlIHN0cmluZyBtYXRjaGluZy4KLSAqCi0gKiA8L2RsPgotICoKLSAqIDxociB3aWR0aD0iNTAlIj4KLSAqIDxoMz5TeW50YXg8L2gzPgotICogPHRhYmxlIGJvcmRlcj0iMSIgYmdjb2xvcj0iI2RkZWVmZiI+Ci0gKiAgIDx0cj4KLSAqICAgIDx0ZD4KLSAqICAgICA8aDQ+RGlmZmVyZW5jZXMgZnJvbSB0aGUgUGVybCA1IHJlZ3VsYXIgZXhwcmVzc2lvbjwvaDQ+Ci0gKiAgICAgPHVsPgotICogICAgICA8bGk+VGhlcmUgaXMgNi1kaWdpdCBoZXhhZGVjaW1hbCBjaGFyYWN0ZXIgcmVwcmVzZW50YXRpb24gICg8a2JkPlx1MDA1Y3Y8L2tiZD48dmFyPkhISEhISDwvdmFyPi4pCi0gKiAgICAgIDxsaT5TdXBwb3J0cyBzdWJ0cmFjdGlvbiwgdW5pb24sIGFuZCBpbnRlcnNlY3Rpb24gb3BlcmF0aW9ucyBmb3IgY2hhcmFjdGVyIGNsYXNzZXMuCi0gKiAgICAgIDxsaT5Ob3Qgc3VwcG9ydGVkOiA8a2JkPlw8L2tiZD48dmFyPm9vbzwvdmFyPiAoT2N0YWwgY2hhcmFjdGVyIHJlcHJlc2VudGF0aW9ucyksCi0gKiAgICAgICAgICA8S2JkPlxHPC9rYmQ+LCA8a2JkPlxDPC9rYmQ+LCA8a2JkPlxsPC9rYmQ+PHZhcj5jPC92YXI+LAotICogICAgICAgICAgPGtiZD5cdTAwNWMgdTwva2JkPjx2YXI+YzwvdmFyPiwgPGtiZD5cTDwva2JkPiwgPGtiZD5cVTwva2JkPiwKLSAqICAgICAgICAgIDxrYmQ+XEU8L2tiZD4sIDxrYmQ+XFE8L2tiZD4sIDxrYmQ+XE57PC9rYmQ+PHZhcj5uYW1lPC92YXI+PGtiZD59PC9rYmQ+LAotICogICAgICAgICAgPEtiZD4oP3s8a2JkPjx2YXI+Y29kZTwvdmFyPjxrYmQ+fSk8L2tiZD4sIDxLYmQ+KD8/ezxrYmQ+PHZhcj5jb2RlPC92YXI+PGtiZD59KTwva2JkPgotICogICAgIDwvdWw+Ci0gKiAgICA8L3RkPgotICogICA8L3RyPgotICogPC90YWJsZT4KLSAqCi0gKiA8UD5NZXRhIGNoYXJhY3RlcnMgYXJlIGA8S0JEPi4gKiArID8geyBbICggKSB8IFwgXiAkPC9LQkQ+Jy48L1A+Ci0gKiA8dWw+Ci0gKiAgIDxsaT5DaGFyYWN0ZXIKLSAqICAgICA8ZGw+Ci0gKiAgICAgICA8ZHQgY2xhc3M9IlJFR0VYIj48a2JkPi48L2tiZD4gKEEgcGVyaW9kKQotICogICAgICAgPGRkPk1hdGNoZXMgYW55IG9uZSBjaGFyYWN0ZXIgZXhjZXB0IHRoZSBmb2xsb3dpbmcgY2hhcmFjdGVycy4KLSAqICAgICAgIDxkZD5MSU5FIEZFRUQgKFUrMDAwQSksIENBUlJJQUdFIFJFVFVSTiAoVSswMDBEKSwKLSAqICAgICAgICAgICBQQVJBR1JBUEggU0VQQVJBVE9SIChVKzIwMjkpLCBMSU5FIFNFUEFSQVRPUiAoVSsyMDI4KQotICogICAgICAgPGRkPlRoaXMgZXhwcmVzc2lvbiBtYXRjaGVzIG9uZSBjb2RlIHBvaW50IGluIFVuaWNvZGUuIEl0IGNhbiBtYXRjaCBhIHBhaXIgb2Ygc3Vycm9nYXRlcy4KLSAqICAgICAgIDxkZD5XaGVuIDxhIGhyZWY9IiNTX09QVElPTiI+dGhlICJzIiBvcHRpb248L2E+IGlzIHNwZWNpZmllZCwKLSAqICAgICAgICAgICBpdCBtYXRjaGVzIGFueSBjaGFyYWN0ZXIgaW5jbHVkaW5nIHRoZSBhYm92ZSBmb3VyIGNoYXJhY3RlcnMuCi0gKgotICogICAgICAgPGR0IGNsYXNzPSJSRUdFWCI+PEtiZD5cZSBcZiBcbiBcciBcdDwva2JkPgotICogICAgICAgPGRkPk1hdGNoZXMgRVNDQVBFIChVKzAwMUIpLCBGT1JNIEZFRUQgKFUrMDAwQyksIExJTkUgRkVFRCAoVSswMDBBKSwKLSAqICAgICAgICAgICBDQVJSSUFHRSBSRVRVUk4gKFUrMDAwRCksIEhPUklaT05UQUwgVEFCVUxBVElPTiAoVSswMDA5KQotICoKLSAqICAgICAgIDxkdCBjbGFzcz0iUkVHRVgiPjxrYmQ+XGM8L2tiZD48dmFyPkM8L3Zhcj4KLSAqICAgICAgIDxkZD5NYXRjaGVzIGEgY29udHJvbCBjaGFyYWN0ZXIuCi0gKiAgICAgICAgICAgVGhlIDx2YXI+QzwvdmFyPiBtdXN0IGJlIG9uZSBvZiAnPGtiZD5APC9rYmQ+JywgJzxrYmQ+QTwva2JkPictJzxrYmQ+Wjwva2JkPicsCi0gKiAgICAgICAgICAgJzxrYmQ+Wzwva2JkPicsICc8a2JkPlx1MDA1Yzwva2JkPicsICc8a2JkPl08L2tiZD4nLCAnPGtiZD5ePC9rYmQ+JywgJzxrYmQ+Xzwva2JkPicuCi0gKiAgICAgICAgICAgSXQgbWF0Y2hlcyBhIGNvbnRyb2wgY2hhcmFjdGVyIG9mIHdoaWNoIHRoZSBjaGFyYWN0ZXIgY29kZSBpcyBsZXNzIHRoYW4KLSAqICAgICAgICAgICB0aGUgY2hhcmFjdGVyIGNvZGUgb2YgdGhlIDx2YXI+QzwvdmFyPiBieSAweDAwNDAuCi0gKiAgICAgICA8ZGQgY2xhc3M9IlJFR0VYIj5Gb3IgZXhhbXBsZSwgYSA8a2JkPlxjSjwva2JkPiBtYXRjaGVzIGEgTElORSBGRUVEIChVKzAwMEEpLAotICogICAgICAgICAgIGFuZCBhIDxrYmQ+XGNbPC9rYmQ+IG1hdGNoZXMgYW4gRVNDQVBFIChVKzAwMUIpLgotICoKLSAqICAgICAgIDxkdCBjbGFzcz0iUkVHRVgiPmEgbm9uLW1ldGEgY2hhcmFjdGVyCi0gKiAgICAgICA8ZGQ+TWF0Y2hlcyB0aGUgY2hhcmFjdGVyLgotICoKLSAqICAgICAgIDxkdCBjbGFzcz0iUkVHRVgiPjxLQkQ+XDwvS0JEPiArIGEgbWV0YSBjaGFyYWN0ZXIKLSAqICAgICAgIDxkZD5NYXRjaGVzIHRoZSBtZXRhIGNoYXJhY3Rlci4KLSAqCi0gKiAgICAgICA8ZHQgY2xhc3M9IlJFR0VYIj48a2JkPlx1MDA1Y3g8L2tiZD48dmFyPkhIPC92YXI+IDxrYmQ+XHUwMDVjeHs8L2tiZD48dmFyPkhISEg8L3Zhcj48a2JkPn08L2tiZD4KLSAqICAgICAgIDxkZD5NYXRjaGVzIGEgY2hhcmFjdGVyIG9mIHdoaWNoIGNvZGUgcG9pbnQgaXMgPHZhcj5ISDwvdmFyPiAoSGV4YWRlY2ltYWwpIGluIFVuaWNvZGUuCi0gKiAgICAgICAgICAgWW91IGNhbiB3cml0ZSBqdXN0IDIgZGlnaXRzIGZvciA8a2JkPlx1MDA1Y3g8L2tiZD48dmFyPkhIPC92YXI+LCBhbmQKLSAqICAgICAgICAgICB2YXJpYWJsZSBsZW5ndGggZGlnaXRzIGZvciA8a2JkPlx1MDA1Y3h7PC9rYmQ+PHZhcj5ISEhIPC92YXI+PGtiZD59PC9rYmQ+LgotICoKLSAqICAgICAgIDwhLS0KLSAqICAgICAgIDxkdCBjbGFzcz0iUkVHRVgiPjxrYmQ+XHUwMDVjIHU8L2tiZD48dmFyPkhISEg8L3Zhcj4KLSAqICAgICAgIDxkZD5NYXRjaGVzIGEgY2hhcmFjdGVyIG9mIHdoaWNoIGNvZGUgcG9pbnQgaXMgPHZhcj5ISEhIPC92YXI+IChIZXhhZGVjaW1hbCkgaW4gVW5pY29kZS4KLSAqICAgICAgIC0tPgotICoKLSAqICAgICAgIDxkdCBjbGFzcz0iUkVHRVgiPjxrYmQ+XHUwMDVjdjwva2JkPjx2YXI+SEhISEhIPC92YXI+Ci0gKiAgICAgICA8ZGQ+TWF0Y2hlcyBhIGNoYXJhY3RlciBvZiB3aGljaCBjb2RlIHBvaW50IGlzIDx2YXI+SEhISEhIPC92YXI+IChIZXhhZGVjaW1hbCkgaW4gVW5pY29kZS4KLSAqCi0gKiAgICAgICA8ZHQgY2xhc3M9IlJFR0VYIj48a2JkPlxnPC9rYmQ+Ci0gKiAgICAgICA8ZGQ+TWF0Y2hlcyBhIGdyYXBoZW1lLgotICogICAgICAgPGRkIGNsYXNzPSJSRUdFWCI+SXQgaXMgZXF1aXZhbGVudCB0byA8a2JkPig/W1xwe0FTU0lHTkVEfV0tW1xwe019XHB7Q31dKT8oPzpccHtNfXxbXHh7MDk0RH1ceHswOUNEfVx4ezBBNER9XHh7MEFDRH1ceHswQjNEfVx4ezBCQ0R9XHh7MEM0RH1ceHswQ0NEfVx4ezBENER9XHh7MEUzQX1ceHswRjg0fV1ccHtMfXxbXHh7MTE2MH0tXHh7MTFBN31dfFtceHsxMUE4fS1ceHsxMUZGfV18W1x4e0ZGOUV9XHh7RkY5Rn1dKSo8L2tiZD4KLSAqCi0gKiAgICAgICA8ZHQgY2xhc3M9IlJFR0VYIj48a2JkPlxYPC9rYmQ+Ci0gKiAgICAgICA8ZGQgY2xhc3M9IlJFR0VYIj5NYXRjaGVzIGEgY29tYmluaW5nIGNoYXJhY3RlciBzZXF1ZW5jZS4KLSAqICAgICAgIEl0IGlzIGVxdWl2YWxlbnQgdG8gPGtiZD4oPzpcUE1ccE0qKTwva2JkPgotICogICAgIDwvZGw+Ci0gKiAgIDwvbGk+Ci0gKgotICogICA8bGk+Q2hhcmFjdGVyIGNsYXNzCi0gKiAgICAgPGRsPgotKyAqICAgICAgIDxkdCBjbGFzcz0iUkVHRVgiPjxrYmQ+Wzwva2JkPjx2YXI+UjxzdWI+MTwvc3ViPjwvdmFyPjx2YXI+UjxzdWI+Mjwvc3ViPjwvdmFyPjx2YXI+Li4uPC92YXI+PHZhcj5SPHN1Yj5uPC9zdWI+PC92YXI+PGtiZD5dPC9rYmQ+ICh3aXRob3V0IDxhIGhyZWY9IiNDT01NQV9PUFRJT04iPiIsIiBvcHRpb248L2E+KQotKyAqICAgICAgIDxkdCBjbGFzcz0iUkVHRVgiPjxrYmQ+Wzwva2JkPjx2YXI+UjxzdWI+MTwvc3ViPjwvdmFyPjxrYmQ+LDwva2JkPjx2YXI+UjxzdWI+Mjwvc3ViPjwvdmFyPjxrYmQ+LDwva2JkPjx2YXI+Li4uPC92YXI+PGtiZD4sPC9rYmQ+PHZhcj5SPHN1Yj5uPC9zdWI+PC92YXI+PGtiZD5dPC9rYmQ+ICh3aXRoIDxhIGhyZWY9IiNDT01NQV9PUFRJT04iPiIsIiBvcHRpb248L2E+KQotICogICAgICAgPGRkPlBvc2l0aXZlIGNoYXJhY3RlciBjbGFzcy4gIEl0IG1hdGNoZXMgYSBjaGFyYWN0ZXIgaW4gcmFuZ2VzLgotICogICAgICAgPGRkPjx2YXI+UjxzdWI+bjwvc3ViPjwvdmFyPjoKLSAqICAgICAgIDx1bD4KLSAqICAgICAgICAgPGxpIGNsYXNzPSJSRUdFWCI+QSBjaGFyYWN0ZXIgKGluY2x1ZGluZyA8S2JkPlxlIFxmIFxuIFxyIFx0PC9rYmQ+IDxrYmQ+XHUwMDVjeDwva2JkPjx2YXI+SEg8L3Zhcj4gPGtiZD5cdTAwNWN4ezwva2JkPjx2YXI+SEhISDwvdmFyPjxrYmQ+fTwva2JkPiA8IS0ta2JkPlx1MDA1YyB1PC9rYmQ+PHZhcj5ISEhIPC92YXItLT4gPGtiZD5cdTAwNWN2PC9rYmQ+PHZhcj5ISEhISEg8L3Zhcj4pCi0gKiAgICAgICAgICAgICA8cD5UaGlzIHJhbmdlIG1hdGNoZXMgdGhlIGNoYXJhY3Rlci4KLSAqICAgICAgICAgPGxpIGNsYXNzPSJSRUdFWCI+PHZhcj5DPHN1Yj4xPC9zdWI+PC92YXI+PGtiZD4tPC9rYmQ+PHZhcj5DPHN1Yj4yPC9zdWI+PC92YXI+Ci0gKiAgICAgICAgICAgICA8cD5UaGlzIHJhbmdlIG1hdGNoZXMgYSBjaGFyYWN0ZXIgd2hpY2ggaGFzIGEgY29kZSBwb2ludCB0aGF0IGlzID49IDx2YXI+QzxzdWI+MTwvc3ViPjwvdmFyPidzIGNvZGUgcG9pbnQgYW5kICZsdDs9IDx2YXI+QzxzdWI+Mjwvc3ViPjwvdmFyPidzIGNvZGUgcG9pbnQuCi0rICogICAgICAgICA8bGkgY2xhc3M9IlJFR0VYIj5BIFBPU0lYIGNoYXJhY3RlciBjbGFzczogPEtiZD5bOmFscGhhOl0gWzphbG51bTpdIFs6YXNjaWk6XSBbOmNudHJsOl0gWzpkaWdpdDpdIFs6Z3JhcGg6XSBbOmxvd2VyOl0gWzpwcmludDpdIFs6cHVuY3Q6XSBbOnNwYWNlOl0gWzp1cHBlcjpdIFs6eGRpZ2l0Ol08L2tiZD4sCi0rICogICAgICAgICAgICAgYW5kIG5lZ2F0aXZlIFBPU0lYIGNoYXJhY3RlciBjbGFzc2VzIGluIFBlcmwgbGlrZSA8a2JkPls6XmFscGhhOl08L2tiZD4KLSAqICAgICAgICAgICAgIDxwPi4uLgotICogICAgICAgICA8bGkgY2xhc3M9IlJFR0VYIj48a2JkPlxkIFxEIFxzIFxTIFx3IFxXIFxwezwva2JkPjx2YXI+bmFtZTwvdmFyPjxrYmQ+fSBcUHs8L2tiZD48dmFyPm5hbWU8L3Zhcj48a2JkPn08L2tiZD4KLSAqICAgICAgICAgICAgIDxwPlRoZXNlIGV4cHJlc3Npb25zIHNwZWNpZmllcyB0aGUgc2FtZSByYW5nZXMgYXMgdGhlIGZvbGxvd2luZyBleHByZXNzaW9ucy4KLSAqICAgICAgIDwvdWw+Ci0gKiAgICAgICA8cCBjbGFzcz0iUkVHRVgiPkVudW1lcmF0ZWQgcmFuZ2VzIGFyZSBtZXJnZWQgKHVuaW9uIG9wZXJhdGlvbikuCi0gKiAgICAgICAgICA8a2JkPlthLWVjLXpdPC9rYmQ+IGlzIGVxdWl2YWxlbnQgdG8gPGtiZD5bYS16XTwva2JkPgotICoKLSAqICAgICAgIDxkdCBjbGFzcz0iUkVHRVgiPjxrYmQ+W148L2tiZD48dmFyPlI8c3ViPjE8L3N1Yj48L3Zhcj48dmFyPlI8c3ViPjI8L3N1Yj48L3Zhcj48dmFyPi4uLjwvdmFyPjx2YXI+UjxzdWI+bjwvc3ViPjwvdmFyPjxrYmQ+XTwva2JkPiAod2l0aG91dCBhIDxhIGhyZWY9IiNDT01NQV9PUFRJT04iPiIsIiBvcHRpb248L2E+KQotICogICAgICAgPGR0IGNsYXNzPSJSRUdFWCI+PGtiZD5bXjwva2JkPjx2YXI+UjxzdWI+MTwvc3ViPjwvdmFyPjxrYmQ+LDwva2JkPjx2YXI+UjxzdWI+Mjwvc3ViPjwvdmFyPjxrYmQ+LDwva2JkPjx2YXI+Li4uPC92YXI+PGtiZD4sPC9rYmQ+PHZhcj5SPHN1Yj5uPC9zdWI+PC92YXI+PGtiZD5dPC9rYmQ+ICh3aXRoIGEgPGEgaHJlZj0iI0NPTU1BX09QVElPTiI+IiwiIG9wdGlvbjwvYT4pCi0gKiAgICAgICA8ZGQ+TmVnYXRpdmUgY2hhcmFjdGVyIGNsYXNzLiAgSXQgbWF0Y2hlcyBhIGNoYXJhY3RlciBub3QgaW4gcmFuZ2VzLgotICoKLSAqICAgICAgIDxkdCBjbGFzcz0iUkVHRVgiPjxrYmQ+KD9bPC9rYmQ+PHZhcj5yYW5nZXM8L3Zhcj48a2JkPl08L2tiZD48dmFyPm9wPC92YXI+PGtiZD5bPC9rYmQ+PHZhcj5yYW5nZXM8L3Zhcj48a2JkPl08L2tiZD48dmFyPm9wPC92YXI+PGtiZD5bPC9rYmQ+PHZhcj5yYW5nZXM8L3Zhcj48a2JkPl08L2tiZD4gLi4uIDxLYmQ+KTwva2JkPgotICogICAgICAgKDx2YXI+b3A8L3Zhcj4gaXMgPGtiZD4tPC9rYmQ+IG9yIDxrYmQ+Kzwva2JkPiBvciA8a2JkPiY8L2tiZD4uKQotICogICAgICAgPGRkPlN1YnRyYWN0aW9uIG9yIHVuaW9uIG9yIGludGVyc2VjdGlvbiBmb3IgY2hhcmFjdGVyIGNsYXNzZXMuCi0gKiAgICAgICA8ZGQgY2xhc3M9IlJFR0VYIj5Gb3IgZXhtYXBsZSwgPGtiZD4oP1tBLVpdLVtDRl0pPC9rYmQ+IGlzIGVxdWl2YWxlbnQgdG8gPGtiZD5bQS1CRC1FRy1aXTwva2JkPiwgYW5kIDxrYmQ+KD9bMHgwMC0weDdmXS1bS10mW1xwe0x1fV0pPC9rYmQ+IGlzIGVxdWl2YWxlbnQgdG8gPGtiZD5bQS1KTC1aXTwva2JkPi4KLSAqICAgICAgIDxkZD5UaGUgcmVzdWx0IG9mIHRoaXMgb3BlcmF0aW9ucyBpcyBhIDx1PnBvc2l0aXZlIGNoYXJhY3RlciBjbGFzczwvdT4KLSAqICAgICAgICAgICBldmVuIGlmIGFuIGV4cHJlc3Npb24gaW5jbHVkZXMgYW55IG5lZ2F0aXZlIGNoYXJhY3RlciBjbGFzc2VzLgotICogICAgICAgICAgIFlvdSBoYXZlIHRvIHRha2UgY2FyZSBvbiB0aGlzIGluIGNhc2UtaW5zZW5zaXRpdmUgbWF0Y2hpbmcuCi0gKiAgICAgICAgICAgRm9yIGluc3RhbmNlLCA8a2JkPig/W15iXSk8L2tiZD4gaXMgZXF1aXZhbGVudCB0byA8a2JkPltceDAwLWFjLVx4ezEwZmZmZn1dPC9rYmQ+LAotICogICAgICAgICAgIHdoaWNoIGlzIGVxdWl2YWxlbnQgdG8gPGtiZD5bXmJdPC9rYmQ+IGluIGNhc2Utc2Vuc2l0aXZlIG1hdGNoaW5nLgotICogICAgICAgICAgIEJ1dCwgaW4gY2FzZS1pbnNlbnNpdGl2ZSBtYXRjaGluZywgPGtiZD4oP1teYl0pPC9rYmQ+IG1hdGNoZXMgYW55IGNoYXJhY3RlciBiZWNhdXNlCi0gKiAgICAgICAgICAgaXQgaW5jbHVkZXMgJzxrYmQ+Qjwva2JkPicgYW5kICc8a2JkPkI8L2tiZD4nIG1hdGNoZXMgJzxrYmQ+Yjwva2JkPicKLSAqICAgICAgICAgICB0aG91Z2ggPGtiZD5bXmJdPC9rYmQ+IGlzIHByb2Nlc3NlZCBhcyA8a2JkPlteQmJdPC9rYmQ+LgotICoKLSAqICAgICAgIDxkdCBjbGFzcz0iUkVHRVgiPjxrYmQ+Wzwva2JkPjx2YXI+UjxzdWI+MTwvc3ViPlI8c3ViPjI8L3N1Yj4uLi48L3Zhcj48a2JkPi1bPC9rYmQ+PHZhcj5SPHN1Yj5uPC9zdWI+UjxzdWI+bisxPC9zdWI+Li4uPC92YXI+PGtiZD5dXTwva2JkPiAod2l0aCBhbiA8YSBocmVmPSIjWF9PUFRJT04iPiJYIiBvcHRpb248L2E+KTwvZHQ+Ci0gKiAgICAgICA8ZGQ+Q2hhcmFjdGVyIGNsYXNzIHN1YnRyYWN0aW9uIGZvciB0aGUgWE1MIFNjaGVtYS4KLSAqICAgICAgICAgICBZb3UgY2FuIHVzZSB0aGlzIHN5bnRheCB3aGVuIHlvdSBzcGVjaWZ5IGFuIDxhIGhyZWY9IiNYX09QVElPTiI+IlgiIG9wdGlvbjwvYT4uCi0gKgotICogICAgICAgPGR0IGNsYXNzPSJSRUdFWCI+PGtiZD5cZDwva2JkPgotICogICAgICAgPGRkIGNsYXNzPSJSRUdFWCI+RXF1aXZhbGVudCB0byA8a2JkPlswLTldPC9rYmQ+LgotICogICAgICAgPGRkPldoZW4gPGEgaHJlZj0iI1VfT1BUSU9OIj5hICJ1IiBvcHRpb248L2E+IGlzIHNldCwgaXQgaXMgZXF1aXZhbGVudCB0bwotICogICAgICAgICAgIDxzcGFuIGNsYXNzPSJSRUdFWCI+PGtiZD5ccHtOZH08L2tiZD48L3NwYW4+LgotICoKLSAqICAgICAgIDxkdCBjbGFzcz0iUkVHRVgiPjxrYmQ+XEQ8L2tiZD4KLSAqICAgICAgIDxkZCBjbGFzcz0iUkVHRVgiPkVxdWl2YWxlbnQgdG8gPGtiZD5bXjAtOV08L2tiZD4KLSAqICAgICAgIDxkZD5XaGVuIDxhIGhyZWY9IiNVX09QVElPTiI+YSAidSIgb3B0aW9uPC9hPiBpcyBzZXQsIGl0IGlzIGVxdWl2YWxlbnQgdG8KLSAqICAgICAgICAgICA8c3BhbiBjbGFzcz0iUkVHRVgiPjxrYmQ+XFB7TmR9PC9rYmQ+PC9zcGFuPi4KLSAqCi0gKiAgICAgICA8ZHQgY2xhc3M9IlJFR0VYIj48a2JkPlxzPC9rYmQ+Ci0gKiAgICAgICA8ZGQgY2xhc3M9IlJFR0VYIj5FcXVpdmFsZW50IHRvIDxrYmQ+WyBcZlxuXHJcdF08L2tiZD4KLSAqICAgICAgIDxkZD5XaGVuIDxhIGhyZWY9IiNVX09QVElPTiI+YSAidSIgb3B0aW9uPC9hPiBpcyBzZXQsIGl0IGlzIGVxdWl2YWxlbnQgdG8KLSAqICAgICAgICAgICA8c3BhbiBjbGFzcz0iUkVHRVgiPjxrYmQ+WyBcZlxuXHJcdFxwe1p9XTwva2JkPjwvc3Bhbj4uCi0gKgotICogICAgICAgPGR0IGNsYXNzPSJSRUdFWCI+PGtiZD5cUzwva2JkPgotICogICAgICAgPGRkIGNsYXNzPSJSRUdFWCI+RXF1aXZhbGVudCB0byA8a2JkPlteIFxmXG5cclx0XTwva2JkPgotICogICAgICAgPGRkPldoZW4gPGEgaHJlZj0iI1VfT1BUSU9OIj5hICJ1IiBvcHRpb248L2E+IGlzIHNldCwgaXQgaXMgZXF1aXZhbGVudCB0bwotICogICAgICAgICAgIDxzcGFuIGNsYXNzPSJSRUdFWCI+PGtiZD5bXiBcZlxuXHJcdFxwe1p9XTwva2JkPjwvc3Bhbj4uCi0gKgotICogICAgICAgPGR0IGNsYXNzPSJSRUdFWCI+PGtiZD5cdzwva2JkPgotICogICAgICAgPGRkIGNsYXNzPSJSRUdFWCI+RXF1aXZhbGVudCB0byA8a2JkPlthLXpBLVowLTlfXTwva2JkPgotICogICAgICAgPGRkPldoZW4gPGEgaHJlZj0iI1VfT1BUSU9OIj5hICJ1IiBvcHRpb248L2E+IGlzIHNldCwgaXQgaXMgZXF1aXZhbGVudCB0bwotICogICAgICAgICAgIDxzcGFuIGNsYXNzPSJSRUdFWCI+PGtiZD5bXHB7THV9XHB7TGx9XHB7TG99XHB7TmR9X108L2tiZD48L3NwYW4+LgotICoKLSAqICAgICAgIDxkdCBjbGFzcz0iUkVHRVgiPjxrYmQ+XFc8L2tiZD4KLSAqICAgICAgIDxkZCBjbGFzcz0iUkVHRVgiPkVxdWl2YWxlbnQgdG8gPGtiZD5bXmEtekEtWjAtOV9dPC9rYmQ+Ci0gKiAgICAgICA8ZGQ+V2hlbiA8YSBocmVmPSIjVV9PUFRJT04iPmEgInUiIG9wdGlvbjwvYT4gaXMgc2V0LCBpdCBpcyBlcXVpdmFsZW50IHRvCi0gKiAgICAgICAgICAgPHNwYW4gY2xhc3M9IlJFR0VYIj48a2JkPlteXHB7THV9XHB7TGx9XHB7TG99XHB7TmR9X108L2tiZD48L3NwYW4+LgotICoKLSAqICAgICAgIDxkdCBjbGFzcz0iUkVHRVgiPjxrYmQ+XHB7PC9rYmQ+PHZhcj5uYW1lPC92YXI+PGtiZD59PC9rYmQ+Ci0gKiAgICAgICA8ZGQ+TWF0Y2hlcyBvbmUgY2hhcmFjdGVyIGluIHRoZSBzcGVjaWZpZWQgR2VuZXJhbCBDYXRlZ29yeSAodGhlIHNlY29uZCBmaWVsZCBpbiA8YSBocmVmPSJmdHA6Ly9mdHAudW5pY29kZS5vcmcvUHVibGljL1VOSURBVEEvVW5pY29kZURhdGEudHh0Ij48a2JkPlVuaWNvZGVEYXRhLnR4dDwva2JkPjwvYT4pIG9yIHRoZSBzcGVjaWZpZWQgPGEgaHJlZj0iZnRwOi8vZnRwLnVuaWNvZGUub3JnL1B1YmxpYy9VTklEQVRBL0Jsb2Nrcy50eHQiPkJsb2NrPC9hPi4KLSAqICAgICAgIFRoZSBmb2xsb3dpbmcgbmFtZXMgYXJlIGF2YWlsYWJsZToKLSAqICAgICAgIDxkbD4KLSAqICAgICAgICAgPGR0PlVuaWNvZGUgR2VuZXJhbCBDYXRlZ29yaWVzOgotICogICAgICAgICA8ZGQ+PGtiZD4KLSAqICAgICAgIEwsIE0sIE4sIFosIEMsIFAsIFMsIEx1LCBMbCwgTHQsIExtLCBMbywgTW4sIE1lLCBNYywgTmQsIE5sLCBObywgWnMsIFpsLCBacCwKLSAqICAgICAgIENjLCBDZiwgQ24sIENvLCBDcywgUGQsIFBzLCBQZSwgUGMsIFBvLCBTbSwgU2MsIFNrLCBTbywKLSAqICAgICAgICAgPC9rYmQ+Ci0gKiAgICAgICAgIDxkZD4oQ3VycmVudGx5IHRoZSBDbiBjYXRlZ29yeSBpbmNsdWRlcyBVKzEwMDAwLVUrMTBGRkZGIGNoYXJhY3RlcnMpCi0gKiAgICAgICAgIDxkdD5Vbmljb2RlIEJsb2NrczoKLSAqICAgICAgICAgPGRkPjxrYmQ+Ci0gKiAgICAgICBCYXNpYyBMYXRpbiwgTGF0aW4tMSBTdXBwbGVtZW50LCBMYXRpbiBFeHRlbmRlZC1BLCBMYXRpbiBFeHRlbmRlZC1CLAotICogICAgICAgSVBBIEV4dGVuc2lvbnMsIFNwYWNpbmcgTW9kaWZpZXIgTGV0dGVycywgQ29tYmluaW5nIERpYWNyaXRpY2FsIE1hcmtzLCBHcmVlaywKLSAqICAgICAgIEN5cmlsbGljLCBBcm1lbmlhbiwgSGVicmV3LCBBcmFiaWMsIERldmFuYWdhcmksIEJlbmdhbGksIEd1cm11a2hpLCBHdWphcmF0aSwKLSAqICAgICAgIE9yaXlhLCBUYW1pbCwgVGVsdWd1LCBLYW5uYWRhLCBNYWxheWFsYW0sIFRoYWksIExhbywgVGliZXRhbiwgR2VvcmdpYW4sCi0gKiAgICAgICBIYW5ndWwgSmFtbywgTGF0aW4gRXh0ZW5kZWQgQWRkaXRpb25hbCwgR3JlZWsgRXh0ZW5kZWQsIEdlbmVyYWwgUHVuY3R1YXRpb24sCi0gKiAgICAgICBTdXBlcnNjcmlwdHMgYW5kIFN1YnNjcmlwdHMsIEN1cnJlbmN5IFN5bWJvbHMsIENvbWJpbmluZyBNYXJrcyBmb3IgU3ltYm9scywKLSAqICAgICAgIExldHRlcmxpa2UgU3ltYm9scywgTnVtYmVyIEZvcm1zLCBBcnJvd3MsIE1hdGhlbWF0aWNhbCBPcGVyYXRvcnMsCi0gKiAgICAgICBNaXNjZWxsYW5lb3VzIFRlY2huaWNhbCwgQ29udHJvbCBQaWN0dXJlcywgT3B0aWNhbCBDaGFyYWN0ZXIgUmVjb2duaXRpb24sCi0gKiAgICAgICBFbmNsb3NlZCBBbHBoYW51bWVyaWNzLCBCb3ggRHJhd2luZywgQmxvY2sgRWxlbWVudHMsIEdlb21ldHJpYyBTaGFwZXMsCi0gKiAgICAgICBNaXNjZWxsYW5lb3VzIFN5bWJvbHMsIERpbmdiYXRzLCBDSksgU3ltYm9scyBhbmQgUHVuY3R1YXRpb24sIEhpcmFnYW5hLAotICogICAgICAgS2F0YWthbmEsIEJvcG9tb2ZvLCBIYW5ndWwgQ29tcGF0aWJpbGl0eSBKYW1vLCBLYW5idW4sCi0gKiAgICAgICBFbmNsb3NlZCBDSksgTGV0dGVycyBhbmQgTW9udGhzLCBDSksgQ29tcGF0aWJpbGl0eSwgQ0pLIFVuaWZpZWQgSWRlb2dyYXBocywKLSAqICAgICAgIEhhbmd1bCBTeWxsYWJsZXMsIEhpZ2ggU3Vycm9nYXRlcywgSGlnaCBQcml2YXRlIFVzZSBTdXJyb2dhdGVzLCBMb3cgU3Vycm9nYXRlcywKLSAqICAgICAgIFByaXZhdGUgVXNlLCBDSksgQ29tcGF0aWJpbGl0eSBJZGVvZ3JhcGhzLCBBbHBoYWJldGljIFByZXNlbnRhdGlvbiBGb3JtcywKLSAqICAgICAgIEFyYWJpYyBQcmVzZW50YXRpb24gRm9ybXMtQSwgQ29tYmluaW5nIEhhbGYgTWFya3MsIENKSyBDb21wYXRpYmlsaXR5IEZvcm1zLAotICogICAgICAgU21hbGwgRm9ybSBWYXJpYW50cywgQXJhYmljIFByZXNlbnRhdGlvbiBGb3Jtcy1CLCBTcGVjaWFscywKLSAqICAgICAgIEhhbGZ3aWR0aCBhbmQgRnVsbHdpZHRoIEZvcm1zCi0gKiAgICAgICAgIDwva2JkPgotICogICAgICAgICA8ZHQ+T3RoZXJzOgotICogICAgICAgICA8ZGQ+PGtiZD5BTEw8L2tiZD4gKEVxdWl2YWxlbnQgdG8gPGtiZD5bXHUwMDVjdTAwMDAtXHUwMDVjdjEwRkZGRl08L2tiZD4pCi0gKiAgICAgICAgIDxkZD48a2JkPkFTU0dJTkVEPC9rYmQ+ICg8a2JkPlxwe0FTU0lHTkVEfTwva2JkPiBpcyBlcXVpdmFsZW50IHRvIDxrYmQ+XFB7Q259PC9rYmQ+KQotICogICAgICAgICA8ZGQ+PGtiZD5VTkFTU0dJTkVEPC9rYmQ+Ci0gKiAgICAgICAgICAgICAoPGtiZD5ccHtVTkFTU0lHTkVEfTwva2JkPiBpcyBlcXVpdmFsZW50IHRvIDxrYmQ+XHB7Q259PC9rYmQ+KQotICogICAgICAgPC9kbD4KLSAqCi0gKiAgICAgICA8ZHQgY2xhc3M9IlJFR0VYIj48a2JkPlxQezwva2JkPjx2YXI+bmFtZTwvdmFyPjxrYmQ+fTwva2JkPgotICogICAgICAgPGRkPk1hdGNoZXMgb25lIGNoYXJhY3RlciBub3QgaW4gdGhlIHNwZWNpZmllZCBHZW5lcmFsIENhdGVnb3J5IG9yIHRoZSBzcGVjaWZpZWQgQmxvY2suCi0gKiAgICAgPC9kbD4KLSAqICAgPC9saT4KLSAqCi0gKiAgIDxsaT5TZWxlY3Rpb24gYW5kIFF1YW50aWZpZXIKLSAqICAgICA8ZGw+Ci0gKiAgICAgICA8ZHQgY2xhc3M9IlJFR0VYIj48VkFSPlg8L1ZBUj48a2JkPnw8L2tiZD48VkFSPlk8L1ZBUj4KLSAqICAgICAgIDxkZD4uLi4KLSAqCi0gKiAgICAgICA8ZHQgY2xhc3M9IlJFR0VYIj48VkFSPlg8L1ZBUj48a2JkPio8L0tCRD4KLSAqICAgICAgIDxkZD5NYXRjaGVzIDAgb3IgbW9yZSA8dmFyPlg8L3Zhcj4uCi0gKgotICogICAgICAgPGR0IGNsYXNzPSJSRUdFWCI+PFZBUj5YPC9WQVI+PGtiZD4rPC9LQkQ+Ci0gKiAgICAgICA8ZGQ+TWF0Y2hlcyAxIG9yIG1vcmUgPHZhcj5YPC92YXI+LgotICoKLSAqICAgICAgIDxkdCBjbGFzcz0iUkVHRVgiPjxWQVI+WDwvVkFSPjxrYmQ+PzwvS0JEPgotICogICAgICAgPGRkPk1hdGNoZXMgMCBvciAxIDx2YXI+WDwvdmFyPi4KLSAqCi0gKiAgICAgICA8ZHQgY2xhc3M9IlJFR0VYIj48dmFyPlg8L3Zhcj48a2JkPns8L2tiZD48dmFyPm51bWJlcjwvdmFyPjxrYmQ+fTwva2JkPgotICogICAgICAgPGRkPk1hdGNoZXMgPHZhcj5udW1iZXI8L3Zhcj4gdGltZXMuCi0gKgotICogICAgICAgPGR0IGNsYXNzPSJSRUdFWCI+PHZhcj5YPC92YXI+PGtiZD57PC9rYmQ+PHZhcj5taW48L3Zhcj48a2JkPix9PC9rYmQ+Ci0gKiAgICAgICA8ZGQ+Li4uCi0gKgotICogICAgICAgPGR0IGNsYXNzPSJSRUdFWCI+PHZhcj5YPC92YXI+PGtiZD57PC9rYmQ+PHZhcj5taW48L3Zhcj48a2JkPiw8L2tiZD48dmFyPm1heDwvdmFyPjxrYmQ+fTwva2JkPgotICogICAgICAgPGRkPi4uLgotICoKLSAqICAgICAgIDxkdCBjbGFzcz0iUkVHRVgiPjxWQVI+WDwvVkFSPjxrYmQ+Kj88L2tiZD4KLSAqICAgICAgIDxkdCBjbGFzcz0iUkVHRVgiPjxWQVI+WDwvVkFSPjxrYmQ+Kz88L2tiZD4KLSAqICAgICAgIDxkdCBjbGFzcz0iUkVHRVgiPjxWQVI+WDwvVkFSPjxrYmQ+Pz88L2tiZD4KLSAqICAgICAgIDxkdCBjbGFzcz0iUkVHRVgiPjx2YXI+WDwvdmFyPjxrYmQ+ezwva2JkPjx2YXI+bWluPC92YXI+PGtiZD4sfT88L2tiZD4KLSAqICAgICAgIDxkdCBjbGFzcz0iUkVHRVgiPjx2YXI+WDwvdmFyPjxrYmQ+ezwva2JkPjx2YXI+bWluPC92YXI+PGtiZD4sPC9rYmQ+PHZhcj5tYXg8L3Zhcj48a2JkPn0/PC9rYmQ+Ci0gKiAgICAgICA8ZGQ+Tm9uLWdyZWVkeSBtYXRjaGluZy4KLSAqICAgICA8L2RsPgotICogICA8L2xpPgotICoKLSAqICAgPGxpPkdyb3VwaW5nLCBDYXB0dXJpbmcsIGFuZCBCYWNrLXJlZmVyZW5jZQotICogICAgIDxkbD4KLSAqICAgICAgIDxkdCBjbGFzcz0iUkVHRVgiPjxLQkQ+KD86PC9rYmQ+PFZBUj5YPC9WQVI+PGtiZD4pPC9LQkQ+Ci0gKiAgICAgICA8ZGQ+R3JvdXBpbmcuICI8S0JEPmZvbys8L0tCRD4iIG1hdGNoZXMgIjxLQkQ+Zm9vPC9LQkQ+IiBvciAiPEtCRD5mb29vbzwvS0JEPiIuCi0gKiAgICAgICBJZiB5b3Ugd2FudCBpdCBtYXRjaGVzICI8S0JEPmZvb2ZvbzwvS0JEPiIgb3IgIjxLQkQ+Zm9vZm9vZm9vPC9LQkQ+IiwKLSAqICAgICAgIHlvdSBoYXZlIHRvIHdyaXRlICI8S0JEPig/OmZvbykrPC9LQkQ+Ii4KLSAqCi0gKiAgICAgICA8ZHQgY2xhc3M9IlJFR0VYIj48S0JEPig8L2tiZD48VkFSPlg8L1ZBUj48a2JkPik8L0tCRD4KLSAqICAgICAgIDxkZD5Hcm91cGluZyB3aXRoIGNhcHR1cmluZy4KLSAqIEl0IG1ha2UgYSBncm91cCBhbmQgYXBwbGljYXRpb25zIGNhbiBrbm93Ci0gKiB3aGVyZSBpbiB0YXJnZXQgdGV4dCBhIGdyb3VwIG1hdGNoZWQgd2l0aCBtZXRob2RzIG9mIGEgPGNvZGU+TWF0Y2g8L2NvZGU+IGluc3RhbmNlCi0gKiBhZnRlciA8Y29kZT48YSBocmVmPSIjbWF0Y2hlcyhqYXZhLmxhbmcuU3RyaW5nLCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWxzLnJlZ2V4Lk1hdGNoKSI+bWF0Y2hlcyhTdHJpbmcsTWF0Y2gpPC9hPjwvY29kZT4uCi0gKiBUaGUgMHRoIGdyb3VwIG1lYW5zIHdob2xlIG9mIHRoaXMgcmVndWxhciBleHByZXNzaW9uLgotICogVGhlIDxWQVI+TjwvVkFSPnRoIGdvcnVwIGlzIHRoZSBpbnNpZGUgb2YgdGhlIDxWQVI+TjwvVkFSPnRoIGxlZnQgcGFyZW50aGVzaXMuCi0gKgotICogICA8cD5Gb3IgaW5zdGFuY2UsIGEgcmVndWxhciBleHByZXNzaW9uIGlzCi0gKiAgICI8Rk9OVCBjb2xvcj1ibHVlPjxLQkQ+ICooW14mbHQ7Ol0qKSArJmx0OyhbXiZndDtdKikmZ3Q7ICo8L0tCRD48L0ZPTlQ+IgotICogICBhbmQgdGFyZ2V0IHRleHQgaXMKLSAqICAgIjxGT05UIGNvbG9yPXJlZD48S0JEPkZyb206IFRBTVVSQSBLZW50ICZsdDtrZW50QHRybC5pYm0uY28uanAmZ3Q7PC9LQkQ+PC9GT05UPiI6Ci0gKiAgIDx1bD4KLSAqICAgICA8bGk+PGNvZGU+TWF0Y2guZ2V0Q2FwdHVyZWRUZXh0KDApPC9jb2RlPjoKLSAqICAgICAiPEZPTlQgY29sb3I9cmVkPjxLQkQ+IFRBTVVSQSBLZW50ICZsdDtrZW50QHRybC5pYm0uY28uanAmZ3Q7PC9LQkQ+PC9GT05UPiIKLSAqICAgICA8bGk+PGNvZGU+TWF0Y2guZ2V0Q2FwdHVyZWRUZXh0KDEpPC9jb2RlPjogIjxGT05UIGNvbG9yPXJlZD48S0JEPlRBTVVSQSBLZW50PC9LQkQ+PC9GT05UPiIKLSAqICAgICA8bGk+PGNvZGU+TWF0Y2guZ2V0Q2FwdHVyZWRUZXh0KDIpPC9jb2RlPjogIjxGT05UIGNvbG9yPXJlZD48S0JEPmtlbnRAdHJsLmlibS5jby5qcDwvS0JEPjwvRk9OVD4iCi0gKiAgIDwvdWw+Ci0gKgotICogICAgICAgPGR0IGNsYXNzPSJSRUdFWCI+PGtiZD5cMSBcMiBcMyBcNCBcNSBcNiBcNyBcOCBcOTwva2JkPgotICogICAgICAgPGRkPgotICoKLSAqICAgICAgIDxkdCBjbGFzcz0iUkVHRVgiPjxrYmQ+KD8+PC9rYmQ+PHZhcj5YPC92YXI+PGtiZD4pPC9rYmQ+Ci0gKiAgICAgICA8ZGQ+SW5kZXBlbmRlbnQgZXhwcmVzc2lvbiBncm91cC4gLi4uLi4uLi4uLi4uLi4uLgotICoKLSAqICAgICAgIDxkdCBjbGFzcz0iUkVHRVgiPjxrYmQ+KD88L2tiZD48dmFyPm9wdGlvbnM8L3Zhcj48a2JkPjo8L2tiZD48dmFyPlg8L3Zhcj48a2JkPik8L2tiZD4KLSAqICAgICAgIDxkdCBjbGFzcz0iUkVHRVgiPjxrYmQ+KD88L2tiZD48dmFyPm9wdGlvbnM8L3Zhcj48a2JkPi08L2tiZD48dmFyPm9wdGlvbnMyPC92YXI+PGtiZD46PC9rYmQ+PHZhcj5YPC92YXI+PGtiZD4pPC9rYmQ+Ci0gKiAgICAgICA8ZGQ+Li4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLgotICogICAgICAgPGRkPlRoZSA8dmFyPm9wdGlvbnM8L3Zhcj4gb3IgdGhlIDx2YXI+b3B0aW9uczI8L3Zhcj4gY29uc2lzdHMgb2YgJ2knICdtJyAncycgJ3cnLgotICogICAgICAgICAgIE5vdGUgdGhhdCBpdCBjYW4gbm90IGNvbnRhaW4gJ3UnLgotICoKLSAqICAgICAgIDxkdCBjbGFzcz0iUkVHRVgiPjxrYmQ+KD88L2tiZD48dmFyPm9wdGlvbnM8L3Zhcj48a2JkPik8L2tiZD4KLSAqICAgICAgIDxkdCBjbGFzcz0iUkVHRVgiPjxrYmQ+KD88L2tiZD48dmFyPm9wdGlvbnM8L3Zhcj48a2JkPi08L2tiZD48dmFyPm9wdGlvbnMyPC92YXI+PGtiZD4pPC9rYmQ+Ci0gKiAgICAgICA8ZGQ+Li4uLi4uCi0gKiAgICAgICA8ZGQ+VGhlc2UgZXhwcmVzc2lvbnMgbXVzdCBiZSBhdCB0aGUgYmVnaW5uaW5nIG9mIGEgZ3JvdXAuCi0gKiAgICAgPC9kbD4KLSAqICAgPC9saT4KLSAqCi0gKiAgIDxsaT5BbmNob3IKLSAqICAgICA8ZGw+Ci0gKiAgICAgICA8ZHQgY2xhc3M9IlJFR0VYIj48a2JkPlxBPC9rYmQ+Ci0gKiAgICAgICA8ZGQ+TWF0Y2hlcyB0aGUgYmVnaW5uaWcgb2YgdGhlIHRleHQuCi0gKgotICogICAgICAgPGR0IGNsYXNzPSJSRUdFWCI+PGtiZD5cWjwva2JkPgotICogICAgICAgPGRkPk1hdGNoZXMgdGhlIGVuZCBvZiB0aGUgdGV4dCwgb3IgYmVmb3JlIGFuIEVPTCBjaGFyYWN0ZXIgYXQgdGhlIGVuZCBvZiB0aGUgdGV4dCwKLSAqICAgICAgICAgICBvciBDQVJSSUFHRSBSRVRVUk4gKyBMSU5FIEZFRUQgYXQgdGhlIGVuZCBvZiB0aGUgdGV4dC4KLSAqCi0gKiAgICAgICA8ZHQgY2xhc3M9IlJFR0VYIj48a2JkPlx6PC9rYmQ+Ci0gKiAgICAgICA8ZGQ+TWF0Y2hlcyB0aGUgZW5kIG9mIHRoZSB0ZXh0LgotICoKLSAqICAgICAgIDxkdCBjbGFzcz0iUkVHRVgiPjxrYmQ+Xjwva2JkPgotICogICAgICAgPGRkPk1hdGNoZXMgdGhlIGJlZ2lubmluZyBvZiB0aGUgdGV4dC4gIEl0IGlzIGVxdWl2YWxlbnQgdG8gPHNwYW4gY2xhc3M9IlJFR0VYIj48S2JkPlxBPC9rYmQ+PC9zcGFuPi4KLSAqICAgICAgIDxkZD5XaGVuIDxhIGhyZWY9IiNNX09QVElPTiI+YSAibSIgb3B0aW9uPC9hPiBpcyBzZXQsCi0gKiAgICAgICAgICAgaXQgbWF0Y2hlcyB0aGUgYmVnaW5uaW5nIG9mIHRoZSB0ZXh0LCBvciBhZnRlciBvbmUgb2YgRU9MIGNoYXJhY3RlcnMgKAotICogICAgICAgICAgIExJTkUgRkVFRCAoVSswMDBBKSwgQ0FSUklBR0UgUkVUVVJOIChVKzAwMEQpLCBMSU5FIFNFUEFSQVRPUiAoVSsyMDI4KSwKLSAqICAgICAgICAgICBQQVJBR1JBUEggU0VQQVJBVE9SIChVKzIwMjkpLikKLSAqCi0gKiAgICAgICA8ZHQgY2xhc3M9IlJFR0VYIj48a2JkPiQ8L2tiZD4KLSAqICAgICAgIDxkZD5NYXRjaGVzIHRoZSBlbmQgb2YgdGhlIHRleHQsIG9yIGJlZm9yZSBhbiBFT0wgY2hhcmFjdGVyIGF0IHRoZSBlbmQgb2YgdGhlIHRleHQsCi0gKiAgICAgICAgICAgb3IgQ0FSUklBR0UgUkVUVVJOICsgTElORSBGRUVEIGF0IHRoZSBlbmQgb2YgdGhlIHRleHQuCi0gKiAgICAgICA8ZGQ+V2hlbiA8YSBocmVmPSIjTV9PUFRJT04iPmEgIm0iIG9wdGlvbjwvYT4gaXMgc2V0LAotICogICAgICAgICAgIGl0IG1hdGNoZXMgdGhlIGVuZCBvZiB0aGUgdGV4dCwgb3IgYmVmb3JlIGFuIEVPTCBjaGFyYWN0ZXIuCi0gKgotICogICAgICAgPGR0IGNsYXNzPSJSRUdFWCI+PGtiZD5cYjwva2JkPgotICogICAgICAgPGRkPk1hdGNoZXMgd29yZCBib3VuZGFyeS4KLSAqICAgICAgICAgICAoU2VlIDxhIGhyZWY9IiNXX09QVElPTiI+YSAidyIgb3B0aW9uPC9hPikKLSAqCi0gKiAgICAgICA8ZHQgY2xhc3M9IlJFR0VYIj48a2JkPlxCPC9rYmQ+Ci0gKiAgICAgICA8ZGQ+TWF0Y2hlcyBub24gd29yZCBib3VuZGFyeS4KLSAqICAgICAgICAgICAoU2VlIDxhIGhyZWY9IiNXX09QVElPTiI+YSAidyIgb3B0aW9uPC9hPikKLSAqCi0gKiAgICAgICA8ZHQgY2xhc3M9IlJFR0VYIj48a2JkPlwmbHQ7PC9rYmQ+Ci0gKiAgICAgICA8ZGQ+TWF0Y2hlcyB0aGUgYmVnaW5uaW5nIG9mIGEgd29yZC4KLSAqICAgICAgICAgICAoU2VlIDxhIGhyZWY9IiNXX09QVElPTiI+YSAidyIgb3B0aW9uPC9hPikKLSAqCi0gKiAgICAgICA8ZHQgY2xhc3M9IlJFR0VYIj48a2JkPlwmZ3Q7PC9rYmQ+Ci0gKiAgICAgICA8ZGQ+TWF0Y2hlcyB0aGUgZW5kIG9mIGEgd29yZC4KLSAqICAgICAgICAgICAoU2VlIDxhIGhyZWY9IiNXX09QVElPTiI+YSAidyIgb3B0aW9uPC9hPikKLSAqICAgICA8L2RsPgotICogICA8L2xpPgotICogICA8bGk+TG9va2FoZWFkIGFuZCBsb29rYmVoaW5kCi0gKiAgICAgPGRsPgotICogICAgICAgPGR0IGNsYXNzPSJSRUdFWCI+PGtiZD4oPz08L2tiZD48dmFyPlg8L3Zhcj48a2JkPik8L2tiZD4KLSAqICAgICAgIDxkZD5Mb29rYWhlYWQuCi0gKgotICogICAgICAgPGR0IGNsYXNzPSJSRUdFWCI+PGtiZD4oPyE8L2tiZD48dmFyPlg8L3Zhcj48a2JkPik8L2tiZD4KLSAqICAgICAgIDxkZD5OZWdhdGl2ZSBsb29rYWhlYWQuCi0gKgotICogICAgICAgPGR0IGNsYXNzPSJSRUdFWCI+PGtiZD4oPyZsdDs9PC9rYmQ+PHZhcj5YPC92YXI+PGtiZD4pPC9rYmQ+Ci0gKiAgICAgICA8ZGQ+TG9va2JlaGluZC4KLSAqICAgICAgIDxkZD4oTm90ZSBmb3IgdGV4dCBjYXB0dXJpbmcuLi4uLi4pCi0gKgotICogICAgICAgPGR0IGNsYXNzPSJSRUdFWCI+PGtiZD4oPyZsdDshPC9rYmQ+PHZhcj5YPC92YXI+PGtiZD4pPC9rYmQ+Ci0gKiAgICAgICA8ZGQ+TmVnYXRpdmUgbG9va2JlaGluZC4KLSAqICAgICA8L2RsPgotICogICA8L2xpPgotICoKLSAqICAgPGxpPk1pc2MuCi0gKiAgICAgPGRsPgotICogICAgICAgPGR0IGNsYXNzPSJSRUdFWCI+PGtiZD4oPyg8L0tiZD48dmFyPmNvbmRpdGlvbjwvdmFyPjxLYmQ+KTwva2JkPjx2YXI+eWVzLXBhdHRlcm48L3Zhcj48a2JkPnw8L2tiZD48dmFyPm5vLXBhdHRlcm48L3Zhcj48a2JkPik8L2tiZD4sCi0gKiAgICAgICA8ZHQgY2xhc3M9IlJFR0VYIj48a2JkPig/KDwva2JkPjx2YXI+Y29uZGl0aW9uPC92YXI+PGtiZD4pPC9rYmQ+PHZhcj55ZXMtcGF0dGVybjwvdmFyPjxrYmQ+KTwva2JkPgotICogICAgICAgPGRkPi4uLi4uLgotICogICAgICAgPGR0IGNsYXNzPSJSRUdFWCI+PGtiZD4oPyM8L2tiZD48dmFyPmNvbW1lbnQ8L3Zhcj48a2JkPik8L2tiZD4KLSAqICAgICAgIDxkZD5Db21tZW50LiAgQSBjb21tZW50IHN0cmluZyBjb25zaXN0cyBvZiBjaGFyYWN0ZXJzIGV4Y2VwdCAnPGtiZD4pPC9rYmQ+Jy4KLSAqICAgICAgICAgICBZb3UgY2FuIG5vdCB3cml0ZSBjb21tZW50cyBpbiBjaGFyYWN0ZXIgY2xhc3NlcyBhbmQgYmVmb3JlIHF1YW50aWZpZXJzLgotICogICAgIDwvZGw+Ci0gKiAgIDwvbGk+Ci0gKiA8L3VsPgotICoKLSAqCi0gKiA8aHIgd2lkdGg9IjUwJSI+Ci0gKiA8aDM+Qk5GIGZvciB0aGUgcmVndWxhciBleHByZXNzaW9uPC9oMz4KLSAqIDxwcmU+Ci0gKiByZWdleCA6Oj0gKCcoPycgb3B0aW9ucyAnKScpPyB0ZXJtICgnfCcgdGVybSkqCi0gKiB0ZXJtIDo6PSBmYWN0b3IrCi0gKiBmYWN0b3IgOjo9IGFuY2hvcnMgfCBhdG9tICgoJyonIHwgJysnIHwgJz8nIHwgbWlubWF4ICkgJz8nPyApPwotICogICAgICAgICAgICB8ICcoPyMnIFteKV0qICcpJwotICogbWlubWF4IDo6PSAneycgKFswLTldKyB8IFswLTldKyAnLCcgfCAnLCcgWzAtOV0rIHwgWzAtOV0rICcsJyBbMC05XSspICd9JwotICogYXRvbSA6Oj0gY2hhciB8ICcuJyB8IGNoYXItY2xhc3MgfCAnKCcgcmVnZXggJyknIHwgJyg/OicgcmVnZXggJyknIHwgJ1wnIFswLTldCi0gKiAgICAgICAgICB8ICdcdycgfCAnXFcnIHwgJ1xkJyB8ICdcRCcgfCAnXHMnIHwgJ1xTJyB8IGNhdGVnb3J5LWJsb2NrIHwgJ1xYJwotICogICAgICAgICAgfCAnKD8+JyByZWdleCAnKScgfCAnKD8nIG9wdGlvbnMgJzonIHJlZ2V4ICcpJwotICogICAgICAgICAgfCAnKD8nICgnKCcgWzAtOV0gJyknIHwgJygnIGFuY2hvcnMgJyknIHwgbG9va3MpIHRlcm0gKCd8JyB0ZXJtKT8gJyknCi0gKiBvcHRpb25zIDo6PSBbaW1zd10qICgnLScgW2ltc3ddKyk/Ci0gKiBhbmNob3JzIDo6PSAnXicgfCAnJCcgfCAnXEEnIHwgJ1xaJyB8ICdceicgfCAnXGInIHwgJ1xCJyB8ICdcJmx0OycgfCAnXD4nCi0gKiBsb29rcyA6Oj0gJyg/PScgcmVnZXggJyknICB8ICcoPyEnIHJlZ2V4ICcpJwotICogICAgICAgICAgIHwgJyg/Jmx0Oz0nIHJlZ2V4ICcpJyB8ICcoPyZsdDshJyByZWdleCAnKScKLSAqIGNoYXIgOjo9ICdcXCcgfCAnXCcgW2VmbnJ0dl0gfCAnXGMnIFtALV9dIHwgY29kZS1wb2ludCB8IGNoYXJhY3Rlci0xCi0gKiBjYXRlZ29yeS1ibG9jayA6Oj0gJ1wnIFtwUF0gY2F0ZWdvcnktc3ltYm9sLTEKLSAqICAgICAgICAgICAgICAgICAgICB8ICgnXHB7JyB8ICdcUHsnKSAoY2F0ZWdvcnktc3ltYm9sIHwgYmxvY2stbmFtZQotICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IG90aGVyLXByb3BlcnRpZXMpICd9JwotICogY2F0ZWdvcnktc3ltYm9sLTEgOjo9ICdMJyB8ICdNJyB8ICdOJyB8ICdaJyB8ICdDJyB8ICdQJyB8ICdTJwotICogY2F0ZWdvcnktc3ltYm9sIDo6PSBjYXRlZ29yeS1zeW1ib2wtMSB8ICdMdScgfCAnTGwnIHwgJ0x0JyB8ICdMbScgfCBMbycKLSAqICAgICAgICAgICAgICAgICAgICAgfCAnTW4nIHwgJ01lJyB8ICdNYycgfCAnTmQnIHwgJ05sJyB8ICdObycKLSAqICAgICAgICAgICAgICAgICAgICAgfCAnWnMnIHwgJ1psJyB8ICdacCcgfCAnQ2MnIHwgJ0NmJyB8ICdDbicgfCAnQ28nIHwgJ0NzJwotICogICAgICAgICAgICAgICAgICAgICB8ICdQZCcgfCAnUHMnIHwgJ1BlJyB8ICdQYycgfCAnUG8nCi0gKiAgICAgICAgICAgICAgICAgICAgIHwgJ1NtJyB8ICdTYycgfCAnU2snIHwgJ1NvJwotICogYmxvY2stbmFtZSA6Oj0gKFNlZSBhYm92ZSkKLSAqIG90aGVyLXByb3BlcnRpZXMgOjo9ICdBTEwnIHwgJ0FTU0lHTkVEJyB8ICdVTkFTU0lHTkVEJwotICogY2hhcmFjdGVyLTEgOjo9IChhbnkgY2hhcmFjdGVyIGV4Y2VwdCBtZXRhLWNoYXJhY3RlcnMpCi0gKgotICogY2hhci1jbGFzcyA6Oj0gJ1snIHJhbmdlcyAnXScKLSAqICAgICAgICAgICAgICAgIHwgJyg/WycgcmFuZ2VzICddJyAoWy0rJl0gJ1snIHJhbmdlcyAnXScpPyAnKScKLSAqIHJhbmdlcyA6Oj0gJ14nPyAocmFuZ2UgPGEgaHJlZj0iI0NPTU1BX09QVElPTiI+JywnPzwvYT4pKwotICogcmFuZ2UgOjo9ICdcZCcgfCAnXHcnIHwgJ1xzJyB8ICdcRCcgfCAnXFcnIHwgJ1xTJyB8IGNhdGVnb3J5LWJsb2NrCi0gKiAgICAgICAgICAgfCByYW5nZS1jaGFyIHwgcmFuZ2UtY2hhciAnLScgcmFuZ2UtY2hhcgotICogcmFuZ2UtY2hhciA6Oj0gJ1xbJyB8ICdcXScgfCAnXFwnIHwgJ1wnIFssLWVmbnJ0dl0gfCBjb2RlLXBvaW50IHwgY2hhcmFjdGVyLTIKLSAqIGNvZGUtcG9pbnQgOjo9ICdceCcgaGV4LWNoYXIgaGV4LWNoYXIKLSAqICAgICAgICAgICAgICAgIHwgJ1x4eycgaGV4LWNoYXIrICd9JwotICogPCEtLSAgICAgICAgICAgICAgIHwgJ1x1MDA1YyB1JyBoZXgtY2hhciBoZXgtY2hhciBoZXgtY2hhciBoZXgtY2hhcgotICogLS0+ICAgICAgICAgICAgICAgfCAnXHYnIGhleC1jaGFyIGhleC1jaGFyIGhleC1jaGFyIGhleC1jaGFyIGhleC1jaGFyIGhleC1jaGFyCi0gKiBoZXgtY2hhciA6Oj0gWzAtOWEtZkEtRl0KLSAqIGNoYXJhY3Rlci0yIDo6PSAoYW55IGNoYXJhY3RlciBleGNlcHQgXFtdLSwpCi0gKiA8L3ByZT4KLSAqCi0gKiA8aHIgd2lkdGg9IjUwJSI+Ci0gKiA8aDM+VE9ETzwvaDM+Ci0gKiA8dWw+Ci0gKiAgIDxsaT48YSBocmVmPSJodHRwOi8vd3d3LnVuaWNvZGUub3JnL3VuaWNvZGUvcmVwb3J0cy90cjE4LyI+VW5pY29kZSBSZWd1bGFyIEV4cHJlc3Npb24gR3VpZGVsaW5lczwvYT4KLSAqICAgICA8dWw+Ci0gKiAgICAgICA8bGk+Mi40IENhbm9uaWNhbCBFcXVpdmFsZW50cwotICogICAgICAgPGxpPkxldmVsIDMKLSAqICAgICA8L3VsPgotICogICA8bGk+UGFyc2luZyBwZXJmb3JtYW5jZQotICogPC91bD4KLSAqCi0gKiA8aHIgd2lkdGg9IjUwJSI+Ci0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgVEFNVVJBIEtlbnQgJmx0O2tlbnRAdHJsLmlibS5jby5qcCZndDsKLSAqIEB2ZXJzaW9uICRJZDogUmVndWxhckV4cHJlc3Npb24uamF2YSx2IDEuOSAyMDEwLzA3LzI3IDA1OjAyOjM0IGpvZWh3IEV4cCAkCi0gKi8KLXB1YmxpYyBjbGFzcyBSZWd1bGFyRXhwcmVzc2lvbiBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKLQotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDYyNDI0OTkzMzQxOTUwMDY0MDFMOwotCi0gICAgc3RhdGljIGZpbmFsIGJvb2xlYW4gREVCVUcgPSBmYWxzZTsKLQotICAgIC8qKgotICAgICAqIENvbXBpbGVzIGEgdG9rZW4gdHJlZSBpbnRvIGFuIG9wZXJhdGlvbiBmbG93LgotICAgICAqLwotICAgIHByaXZhdGUgc3luY2hyb25pemVkIHZvaWQgY29tcGlsZShUb2tlbiB0b2spIHsKLSAgICAgICAgaWYgKHRoaXMub3BlcmF0aW9ucyAhPSBudWxsKQotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB0aGlzLm51bWJlck9mQ2xvc3VyZXMgPSAwOwotICAgICAgICB0aGlzLm9wZXJhdGlvbnMgPSB0aGlzLmNvbXBpbGUodG9rLCBudWxsLCBmYWxzZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29udmVydHMgYSB0b2tlbiB0byBhbiBvcGVyYXRpb24uCi0gICAgICovCi0gICAgcHJpdmF0ZSBPcCBjb21waWxlKFRva2VuIHRvaywgT3AgbmV4dCwgYm9vbGVhbiByZXZlcnNlKSB7Ci0gICAgICAgIE9wIHJldDsKLSAgICAgICAgc3dpdGNoICh0b2sudHlwZSkgewotICAgICAgICBjYXNlIFRva2VuLkRPVDoKLSAgICAgICAgICAgIHJldCA9IE9wLmNyZWF0ZURvdCgpOwotICAgICAgICAgICAgcmV0Lm5leHQgPSBuZXh0OwotICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgY2FzZSBUb2tlbi5DSEFSOgotICAgICAgICAgICAgcmV0ID0gT3AuY3JlYXRlQ2hhcih0b2suZ2V0Q2hhcigpKTsKLSAgICAgICAgICAgIHJldC5uZXh0ID0gbmV4dDsKLSAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgIGNhc2UgVG9rZW4uQU5DSE9SOgotICAgICAgICAgICAgcmV0ID0gT3AuY3JlYXRlQW5jaG9yKHRvay5nZXRDaGFyKCkpOwotICAgICAgICAgICAgcmV0Lm5leHQgPSBuZXh0OwotICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgY2FzZSBUb2tlbi5SQU5HRToKLSAgICAgICAgY2FzZSBUb2tlbi5OUkFOR0U6Ci0gICAgICAgICAgICByZXQgPSBPcC5jcmVhdGVSYW5nZSh0b2spOwotICAgICAgICAgICAgcmV0Lm5leHQgPSBuZXh0OwotICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgY2FzZSBUb2tlbi5DT05DQVQ6Ci0gICAgICAgICAgICByZXQgPSBuZXh0OwotICAgICAgICAgICAgaWYgKCFyZXZlcnNlKSB7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IHRvay5zaXplKCktMTsgIGkgPj0gMDsgIGkgLS0pIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0ID0gY29tcGlsZSh0b2suZ2V0Q2hpbGQoaSksIHJldCwgZmFsc2UpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7ICBpIDwgdG9rLnNpemUoKTsgIGkgKyspIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0ID0gY29tcGlsZSh0b2suZ2V0Q2hpbGQoaSksIHJldCwgdHJ1ZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgY2FzZSBUb2tlbi5VTklPTjoKLSAgICAgICAgICAgIE9wLlVuaW9uT3AgdW5pID0gT3AuY3JlYXRlVW5pb24odG9rLnNpemUoKSk7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgIGkgPCB0b2suc2l6ZSgpOyAgaSArKykgewotICAgICAgICAgICAgICAgIHVuaS5hZGRFbGVtZW50KGNvbXBpbGUodG9rLmdldENoaWxkKGkpLCBuZXh0LCByZXZlcnNlKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXQgPSB1bmk7ICAgICAgICAgICAgICAgICAgICAgICAgICAvLyByZXQubmV4dCBpcyBudWxsLgotICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgY2FzZSBUb2tlbi5DTE9TVVJFOgotICAgICAgICBjYXNlIFRva2VuLk5PTkdSRUVEWUNMT1NVUkU6Ci0gICAgICAgICAgICBUb2tlbiBjaGlsZCA9IHRvay5nZXRDaGlsZCgwKTsKLSAgICAgICAgICAgIGludCBtaW4gPSB0b2suZ2V0TWluKCk7Ci0gICAgICAgICAgICBpbnQgbWF4ID0gdG9rLmdldE1heCgpOwotICAgICAgICAgICAgaWYgKG1pbiA+PSAwICYmIG1pbiA9PSBtYXgpIHsgLy8ge259Ci0gICAgICAgICAgICAgICAgcmV0ID0gbmV4dDsKLSAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1pbjsgIGkgKyspIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0ID0gY29tcGlsZShjaGlsZCwgcmV0LCByZXZlcnNlKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAobWluID4gMCAmJiBtYXggPiAwKQotICAgICAgICAgICAgICAgIG1heCAtPSBtaW47Ci0gICAgICAgICAgICBpZiAobWF4ID4gMCkgewotICAgICAgICAgICAgICAgIC8vIFh7Miw2fSAtPiBYWChYKFgoWFg/KT8pPyk/Ci0gICAgICAgICAgICAgICAgcmV0ID0gbmV4dDsKLSAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgIGkgPCBtYXg7ICBpICsrKSB7Ci0gICAgICAgICAgICAgICAgICAgIE9wLkNoaWxkT3AgcSA9IE9wLmNyZWF0ZVF1ZXN0aW9uKHRvay50eXBlID09IFRva2VuLk5PTkdSRUVEWUNMT1NVUkUpOwotICAgICAgICAgICAgICAgICAgICBxLm5leHQgPSBuZXh0OwotICAgICAgICAgICAgICAgICAgICBxLnNldENoaWxkKGNvbXBpbGUoY2hpbGQsIHJldCwgcmV2ZXJzZSkpOwotICAgICAgICAgICAgICAgICAgICByZXQgPSBxOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgT3AuQ2hpbGRPcCBvcDsKLSAgICAgICAgICAgICAgICBpZiAodG9rLnR5cGUgPT0gVG9rZW4uTk9OR1JFRURZQ0xPU1VSRSkgewotICAgICAgICAgICAgICAgICAgICBvcCA9IE9wLmNyZWF0ZU5vbkdyZWVkeUNsb3N1cmUoKTsKLSAgICAgICAgICAgICAgICB9IGVsc2UgeyAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRva2VuLkNMT1NVUkUKLSAgICAgICAgICAgICAgICAgICAgb3AgPSBPcC5jcmVhdGVDbG9zdXJlKHRoaXMubnVtYmVyT2ZDbG9zdXJlcysrKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgb3AubmV4dCA9IG5leHQ7Ci0gICAgICAgICAgICAgICAgb3Auc2V0Q2hpbGQoY29tcGlsZShjaGlsZCwgb3AsIHJldmVyc2UpKTsKLSAgICAgICAgICAgICAgICByZXQgPSBvcDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChtaW4gPiAwKSB7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7ICBpIDwgbWluOyAgaSArKykgewotICAgICAgICAgICAgICAgICAgICByZXQgPSBjb21waWxlKGNoaWxkLCByZXQsIHJldmVyc2UpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgIGNhc2UgVG9rZW4uRU1QVFk6Ci0gICAgICAgICAgICByZXQgPSBuZXh0OwotICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgY2FzZSBUb2tlbi5TVFJJTkc6Ci0gICAgICAgICAgICByZXQgPSBPcC5jcmVhdGVTdHJpbmcodG9rLmdldFN0cmluZygpKTsKLSAgICAgICAgICAgIHJldC5uZXh0ID0gbmV4dDsKLSAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgIGNhc2UgVG9rZW4uQkFDS1JFRkVSRU5DRToKLSAgICAgICAgICAgIHJldCA9IE9wLmNyZWF0ZUJhY2tSZWZlcmVuY2UodG9rLmdldFJlZmVyZW5jZU51bWJlcigpKTsKLSAgICAgICAgICAgIHJldC5uZXh0ID0gbmV4dDsKLSAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgIGNhc2UgVG9rZW4uUEFSRU46Ci0gICAgICAgICAgICBpZiAodG9rLmdldFBhcmVuTnVtYmVyKCkgPT0gMCkgewotICAgICAgICAgICAgICAgIHJldCA9IGNvbXBpbGUodG9rLmdldENoaWxkKDApLCBuZXh0LCByZXZlcnNlKTsKLSAgICAgICAgICAgIH0gZWxzZSBpZiAocmV2ZXJzZSkgewotICAgICAgICAgICAgICAgIG5leHQgPSBPcC5jcmVhdGVDYXB0dXJlKHRvay5nZXRQYXJlbk51bWJlcigpLCBuZXh0KTsKLSAgICAgICAgICAgICAgICBuZXh0ID0gY29tcGlsZSh0b2suZ2V0Q2hpbGQoMCksIG5leHQsIHJldmVyc2UpOwotICAgICAgICAgICAgICAgIHJldCA9IE9wLmNyZWF0ZUNhcHR1cmUoLXRvay5nZXRQYXJlbk51bWJlcigpLCBuZXh0KTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgbmV4dCA9IE9wLmNyZWF0ZUNhcHR1cmUoLXRvay5nZXRQYXJlbk51bWJlcigpLCBuZXh0KTsKLSAgICAgICAgICAgICAgICBuZXh0ID0gY29tcGlsZSh0b2suZ2V0Q2hpbGQoMCksIG5leHQsIHJldmVyc2UpOwotICAgICAgICAgICAgICAgIHJldCA9IE9wLmNyZWF0ZUNhcHR1cmUodG9rLmdldFBhcmVuTnVtYmVyKCksIG5leHQpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgY2FzZSBUb2tlbi5MT09LQUhFQUQ6Ci0gICAgICAgICAgICByZXQgPSBPcC5jcmVhdGVMb29rKE9wLkxPT0tBSEVBRCwgbmV4dCwgY29tcGlsZSh0b2suZ2V0Q2hpbGQoMCksIG51bGwsIGZhbHNlKSk7Ci0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBUb2tlbi5ORUdBVElWRUxPT0tBSEVBRDoKLSAgICAgICAgICAgIHJldCA9IE9wLmNyZWF0ZUxvb2soT3AuTkVHQVRJVkVMT09LQUhFQUQsIG5leHQsIGNvbXBpbGUodG9rLmdldENoaWxkKDApLCBudWxsLCBmYWxzZSkpOwotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgVG9rZW4uTE9PS0JFSElORDoKLSAgICAgICAgICAgIHJldCA9IE9wLmNyZWF0ZUxvb2soT3AuTE9PS0JFSElORCwgbmV4dCwgY29tcGlsZSh0b2suZ2V0Q2hpbGQoMCksIG51bGwsIHRydWUpKTsKLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICBjYXNlIFRva2VuLk5FR0FUSVZFTE9PS0JFSElORDoKLSAgICAgICAgICAgIHJldCA9IE9wLmNyZWF0ZUxvb2soT3AuTkVHQVRJVkVMT09LQkVISU5ELCBuZXh0LCBjb21waWxlKHRvay5nZXRDaGlsZCgwKSwgbnVsbCwgdHJ1ZSkpOwotICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgY2FzZSBUb2tlbi5JTkRFUEVOREVOVDoKLSAgICAgICAgICAgIHJldCA9IE9wLmNyZWF0ZUluZGVwZW5kZW50KG5leHQsIGNvbXBpbGUodG9rLmdldENoaWxkKDApLCBudWxsLCByZXZlcnNlKSk7Ci0gICAgICAgICAgICBicmVhazsKLQotICAgICAgICBjYXNlIFRva2VuLk1PRElGSUVSR1JPVVA6Ci0gICAgICAgICAgICByZXQgPSBPcC5jcmVhdGVNb2RpZmllcihuZXh0LCBjb21waWxlKHRvay5nZXRDaGlsZCgwKSwgbnVsbCwgcmV2ZXJzZSksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKFRva2VuLk1vZGlmaWVyVG9rZW4pdG9rKS5nZXRPcHRpb25zKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKFRva2VuLk1vZGlmaWVyVG9rZW4pdG9rKS5nZXRPcHRpb25zTWFzaygpKTsKLSAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgIGNhc2UgVG9rZW4uQ09ORElUSU9OOgotICAgICAgICAgICAgVG9rZW4uQ29uZGl0aW9uVG9rZW4gY3RvayA9IChUb2tlbi5Db25kaXRpb25Ub2tlbil0b2s7Ci0gICAgICAgICAgICBpbnQgcmVmID0gY3Rvay5yZWZOdW1iZXI7Ci0gICAgICAgICAgICBPcCBjb25kaXRpb24gPSBjdG9rLmNvbmRpdGlvbiA9PSBudWxsID8gbnVsbCA6IGNvbXBpbGUoY3Rvay5jb25kaXRpb24sIG51bGwsIHJldmVyc2UpOwotICAgICAgICAgICAgT3AgeWVzID0gY29tcGlsZShjdG9rLnllcywgbmV4dCwgcmV2ZXJzZSk7Ci0gICAgICAgICAgICBPcCBubyA9IGN0b2subm8gPT0gbnVsbCA/IG51bGwgOiBjb21waWxlKGN0b2subm8sIG5leHQsIHJldmVyc2UpOwotICAgICAgICAgICAgcmV0ID0gT3AuY3JlYXRlQ29uZGl0aW9uKG5leHQsIHJlZiwgY29uZGl0aW9uLCB5ZXMsIG5vKTsKLSAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgIGRlZmF1bHQ6Ci0gICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVW5rbm93biB0b2tlbiB0eXBlOiAiK3Rvay50eXBlKTsKLSAgICAgICAgfSAvLyBzd2l0Y2ggKHRvay50eXBlKQotICAgICAgICByZXR1cm4gcmV0OwotICAgIH0KLQotCi0vL1B1YmxpYwotCi0gICAgLyoqCi0gICAgICogQ2hlY2tzIHdoZXRoZXIgdGhlIDx2YXI+dGFyZ2V0PC92YXI+IHRleHQgPHN0cm9uZz5jb250YWluczwvc3Ryb25nPiB0aGlzIHBhdHRlcm4gb3Igbm90LgotICAgICAqCi0gICAgICogQHJldHVybiB0cnVlIGlmIHRoZSB0YXJnZXQgaXMgbWF0Y2hlZCB0byB0aGlzIHJlZ3VsYXIgZXhwcmVzc2lvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBtYXRjaGVzKGNoYXJbXSAgdGFyZ2V0KSB7Ci0gICAgICAgIHJldHVybiB0aGlzLm1hdGNoZXModGFyZ2V0LCAwLCAgdGFyZ2V0IC5sZW5ndGggLCAoTWF0Y2gpbnVsbCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ2hlY2tzIHdoZXRoZXIgdGhlIDx2YXI+dGFyZ2V0PC92YXI+IHRleHQgPHN0cm9uZz5jb250YWluczwvc3Ryb25nPiB0aGlzIHBhdHRlcm4KLSAgICAgKiBpbiBzcGVjaWZpZWQgcmFuZ2Ugb3Igbm90LgotICAgICAqCi0gICAgICogQHBhcmFtIHN0YXJ0IFN0YXJ0IG9mZnNldCBvZiB0aGUgcmFuZ2UuCi0gICAgICogQHBhcmFtIGVuZCAgRW5kIG9mZnNldCArMSBvZiB0aGUgcmFuZ2UuCi0gICAgICogQHJldHVybiB0cnVlIGlmIHRoZSB0YXJnZXQgaXMgbWF0Y2hlZCB0byB0aGlzIHJlZ3VsYXIgZXhwcmVzc2lvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBtYXRjaGVzKGNoYXJbXSAgdGFyZ2V0LCBpbnQgc3RhcnQsIGludCBlbmQpIHsKLSAgICAgICAgcmV0dXJuIHRoaXMubWF0Y2hlcyh0YXJnZXQsIHN0YXJ0LCBlbmQsIChNYXRjaCludWxsKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDaGVja3Mgd2hldGhlciB0aGUgPHZhcj50YXJnZXQ8L3Zhcj4gdGV4dCA8c3Ryb25nPmNvbnRhaW5zPC9zdHJvbmc+IHRoaXMgcGF0dGVybiBvciBub3QuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbWF0Y2ggQSBNYXRjaCBpbnN0YW5jZSBmb3Igc3RvcmluZyBtYXRjaGluZyByZXN1bHQuCi0gICAgICogQHJldHVybiBPZmZzZXQgb2YgdGhlIHN0YXJ0IHBvc2l0aW9uIGluIDxWQVI+dGFyZ2V0PC9WQVI+OyBvciAtMSBpZiBub3QgbWF0Y2guCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gbWF0Y2hlcyhjaGFyW10gIHRhcmdldCwgTWF0Y2ggbWF0Y2gpIHsKLSAgICAgICAgcmV0dXJuIHRoaXMubWF0Y2hlcyh0YXJnZXQsIDAsICB0YXJnZXQgLmxlbmd0aCAsIG1hdGNoKTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIENoZWNrcyB3aGV0aGVyIHRoZSA8dmFyPnRhcmdldDwvdmFyPiB0ZXh0IDxzdHJvbmc+Y29udGFpbnM8L3N0cm9uZz4gdGhpcyBwYXR0ZXJuCi0gICAgICogaW4gc3BlY2lmaWVkIHJhbmdlIG9yIG5vdC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzdGFydCBTdGFydCBvZmZzZXQgb2YgdGhlIHJhbmdlLgotICAgICAqIEBwYXJhbSBlbmQgIEVuZCBvZmZzZXQgKzEgb2YgdGhlIHJhbmdlLgotICAgICAqIEBwYXJhbSBtYXRjaCBBIE1hdGNoIGluc3RhbmNlIGZvciBzdG9yaW5nIG1hdGNoaW5nIHJlc3VsdC4KLSAgICAgKiBAcmV0dXJuIE9mZnNldCBvZiB0aGUgc3RhcnQgcG9zaXRpb24gaW4gPFZBUj50YXJnZXQ8L1ZBUj47IG9yIC0xIGlmIG5vdCBtYXRjaC4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBtYXRjaGVzKGNoYXJbXSB0YXJnZXQsIGludCBzdGFydCwgaW50IGVuZCwgTWF0Y2ggbWF0Y2gpIHsKLQotICAgICAgICBzeW5jaHJvbml6ZWQgKHRoaXMpIHsKLSAgICAgICAgICAgIGlmICh0aGlzLm9wZXJhdGlvbnMgPT0gbnVsbCkKLSAgICAgICAgICAgICAgICB0aGlzLnByZXBhcmUoKTsKLSAgICAgICAgICAgIGlmICh0aGlzLmNvbnRleHQgPT0gbnVsbCkKLSAgICAgICAgICAgICAgICB0aGlzLmNvbnRleHQgPSBuZXcgQ29udGV4dCgpOwotICAgICAgICB9Ci0gICAgICAgIENvbnRleHQgY29uID0gbnVsbDsKLSAgICAgICAgc3luY2hyb25pemVkICh0aGlzLmNvbnRleHQpIHsKLSAgICAgICAgICAgIGNvbiA9IHRoaXMuY29udGV4dC5pbnVzZSA/IG5ldyBDb250ZXh0KCkgOiB0aGlzLmNvbnRleHQ7Ci0gICAgICAgICAgICBjb24ucmVzZXQodGFyZ2V0LCBzdGFydCwgZW5kLCB0aGlzLm51bWJlck9mQ2xvc3VyZXMpOwotICAgICAgICB9Ci0gICAgICAgIGlmIChtYXRjaCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBtYXRjaC5zZXROdW1iZXJPZkdyb3Vwcyh0aGlzLm5vZnBhcmVuKTsKLSAgICAgICAgICAgIG1hdGNoLnNldFNvdXJjZSh0YXJnZXQpOwotICAgICAgICB9IGVsc2UgaWYgKHRoaXMuaGFzQmFja1JlZmVyZW5jZXMpIHsKLSAgICAgICAgICAgIG1hdGNoID0gbmV3IE1hdGNoKCk7Ci0gICAgICAgICAgICBtYXRjaC5zZXROdW1iZXJPZkdyb3Vwcyh0aGlzLm5vZnBhcmVuKTsKLSAgICAgICAgICAgIC8vIE5lZWQgbm90IHRvIGNhbGwgc2V0U291cmNlKCkgYmVjYXVzZQotICAgICAgICAgICAgLy8gYSBjYWxsZXIgY2FuIG5vdCBhY2Nlc3MgdGhpcyBtYXRjaCBpbnN0YW5jZS4KLSAgICAgICAgfQotICAgICAgICBjb24ubWF0Y2ggPSBtYXRjaDsKLQotICAgICAgICBpZiAoUmVndWxhckV4cHJlc3Npb24uaXNTZXQodGhpcy5vcHRpb25zLCBYTUxTQ0hFTUFfTU9ERSkpIHsKLSAgICAgICAgICAgIGludCBtYXRjaEVuZCA9IHRoaXMuIG1hdGNoKGNvbiwgdGhpcy5vcGVyYXRpb25zLCBjb24uc3RhcnQsIDEsIHRoaXMub3B0aW9ucyk7Ci0gICAgICAgICAgICAvL1N5c3RlbS5lcnIucHJpbnRsbigiREVCVUc6IG1hdGNoRW5kPSIrbWF0Y2hFbmQpOwotICAgICAgICAgICAgaWYgKG1hdGNoRW5kID09IGNvbi5saW1pdCkgewotICAgICAgICAgICAgICAgIGlmIChjb24ubWF0Y2ggIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBjb24ubWF0Y2guc2V0QmVnaW5uaW5nKDAsIGNvbi5zdGFydCk7Ci0gICAgICAgICAgICAgICAgICAgIGNvbi5tYXRjaC5zZXRFbmQoMCwgbWF0Y2hFbmQpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBjb24uc2V0SW5Vc2UoZmFsc2UpOwotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoKLSAgICAgICAgICogVGhlIHBhdHRlcm4gaGFzIG9ubHkgZml4ZWQgc3RyaW5nLgotICAgICAgICAgKiBUaGUgZW5naW5lIHVzZXMgQm95ZXItTW9vcmUuCi0gICAgICAgICAqLwotICAgICAgICBpZiAodGhpcy5maXhlZFN0cmluZ09ubHkpIHsKLSAgICAgICAgICAgIC8vU3lzdGVtLmVyci5wcmludGxuKCJERUJVRzogZml4ZWQtb25seTogIit0aGlzLmZpeGVkU3RyaW5nKTsKLSAgICAgICAgICAgIGludCBvID0gdGhpcy5maXhlZFN0cmluZ1RhYmxlLm1hdGNoZXModGFyZ2V0LCBjb24uc3RhcnQsIGNvbi5saW1pdCk7Ci0gICAgICAgICAgICBpZiAobyA+PSAwKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGNvbi5tYXRjaCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGNvbi5tYXRjaC5zZXRCZWdpbm5pbmcoMCwgbyk7Ci0gICAgICAgICAgICAgICAgICAgIGNvbi5tYXRjaC5zZXRFbmQoMCwgbyt0aGlzLmZpeGVkU3RyaW5nLmxlbmd0aCgpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgY29uLnNldEluVXNlKGZhbHNlKTsKLSAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNvbi5zZXRJblVzZShmYWxzZSk7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLQotICAgICAgICAvKgotICAgICAgICAgKiBUaGUgcGF0dGVybiBjb250YWlucyBhIGZpeGVkIHN0cmluZy4KLSAgICAgICAgICogVGhlIGVuZ2luZSBjaGVja3Mgd2l0aCBCb3llci1Nb29yZSB3aGV0aGVyIHRoZSB0ZXh0IGNvbnRhaW5zIHRoZSBmaXhlZCBzdHJpbmcgb3Igbm90LgotICAgICAgICAgKiBJZiBub3QsIGl0IHJldHVybiB3aXRoIGZhbHNlLgotICAgICAgICAgKi8KLSAgICAgICAgaWYgKHRoaXMuZml4ZWRTdHJpbmcgIT0gbnVsbCkgewotICAgICAgICAgICAgaW50IG8gPSB0aGlzLmZpeGVkU3RyaW5nVGFibGUubWF0Y2hlcyh0YXJnZXQsIGNvbi5zdGFydCwgY29uLmxpbWl0KTsKLSAgICAgICAgICAgIGlmIChvIDwgMCkgewotICAgICAgICAgICAgICAgIC8vU3lzdGVtLmVyci5wcmludGxuKCJOb24tbWF0Y2ggaW4gZml4ZWQtc3RyaW5nIHNlYXJjaC4iKTsKLSAgICAgICAgICAgICAgICBjb24uc2V0SW5Vc2UoZmFsc2UpOwotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGludCBsaW1pdCA9IGNvbi5saW1pdC10aGlzLm1pbmxlbmd0aDsKLSAgICAgICAgaW50IG1hdGNoU3RhcnQ7Ci0gICAgICAgIGludCBtYXRjaEVuZCA9IC0xOwotCi0gICAgICAgIC8qCi0gICAgICAgICAqIENoZWNrcyB3aGV0aGVyIHRoZSBleHByZXNzaW9uIHN0YXJ0cyB3aXRoICIuKiIuCi0gICAgICAgICAqLwotICAgICAgICBpZiAodGhpcy5vcGVyYXRpb25zICE9IG51bGwKLSAgICAgICAgICAgICYmIHRoaXMub3BlcmF0aW9ucy50eXBlID09IE9wLkNMT1NVUkUgJiYgdGhpcy5vcGVyYXRpb25zLmdldENoaWxkKCkudHlwZSA9PSBPcC5ET1QpIHsKLSAgICAgICAgICAgIGlmIChpc1NldCh0aGlzLm9wdGlvbnMsIFNJTkdMRV9MSU5FKSkgewotICAgICAgICAgICAgICAgIG1hdGNoU3RhcnQgPSBjb24uc3RhcnQ7Ci0gICAgICAgICAgICAgICAgbWF0Y2hFbmQgPSB0aGlzLiBtYXRjaChjb24sIHRoaXMub3BlcmF0aW9ucywgY29uLnN0YXJ0LCAxLCB0aGlzLm9wdGlvbnMpOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBib29sZWFuIHByZXZpb3VzSXNFT0wgPSB0cnVlOwotICAgICAgICAgICAgICAgIGZvciAobWF0Y2hTdGFydCA9IGNvbi5zdGFydDsgIG1hdGNoU3RhcnQgPD0gbGltaXQ7ICBtYXRjaFN0YXJ0ICsrKSB7Ci0gICAgICAgICAgICAgICAgICAgIGludCBjaCA9ICB0YXJnZXQgWyAgbWF0Y2hTdGFydCBdIDsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGlzRU9MQ2hhcihjaCkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHByZXZpb3VzSXNFT0wgPSB0cnVlOwotICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHByZXZpb3VzSXNFT0wpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoMCA8PSAobWF0Y2hFbmQgPSB0aGlzLiBtYXRjaChjb24sIHRoaXMub3BlcmF0aW9ucywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRjaFN0YXJ0LCAxLCB0aGlzLm9wdGlvbnMpKSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBwcmV2aW91c0lzRU9MID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvKgotICAgICAgICAgKiBPcHRpbWl6YXRpb24gYWdhaW5zdCB0aGUgZmlyc3QgY2hhcmFjdGVyLgotICAgICAgICAgKi8KLSAgICAgICAgZWxzZSBpZiAodGhpcy5maXJzdENoYXIgIT0gbnVsbCkgewotICAgICAgICAgICAgLy9TeXN0ZW0uZXJyLnByaW50bG4oIkRFQlVHOiB3aXRoIGZpcnN0Y2hhci1tYXRjaGluZzogIit0aGlzLmZpcnN0Q2hhcik7Ci0gICAgICAgICAgICBSYW5nZVRva2VuIHJhbmdlID0gdGhpcy5maXJzdENoYXI7Ci0gICAgICAgICAgICBmb3IgKG1hdGNoU3RhcnQgPSBjb24uc3RhcnQ7ICBtYXRjaFN0YXJ0IDw9IGxpbWl0OyAgbWF0Y2hTdGFydCArKykgewotICAgICAgICAgICAgICAgIGludCBjaCA9ICB0YXJnZXQgW21hdGNoU3RhcnRdIDsKLSAgICAgICAgICAgICAgICBpZiAoUkVVdGlsLmlzSGlnaFN1cnJvZ2F0ZShjaCkgJiYgbWF0Y2hTdGFydCsxIDwgY29uLmxpbWl0KSB7Ci0gICAgICAgICAgICAgICAgICAgIGNoID0gUkVVdGlsLmNvbXBvc2VGcm9tU3Vycm9nYXRlcyhjaCwgdGFyZ2V0W21hdGNoU3RhcnQrMV0pOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpZiAoIXJhbmdlLm1hdGNoKGNoKSkgIHsKLSAgICAgICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGlmICgwIDw9IChtYXRjaEVuZCA9IHRoaXMuIG1hdGNoKGNvbiwgdGhpcy5vcGVyYXRpb25zLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdGNoU3RhcnQsIDEsIHRoaXMub3B0aW9ucykpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvKgotICAgICAgICAgKiBTdHJhaWdodGZvcndhcmQgbWF0Y2hpbmcuCi0gICAgICAgICAqLwotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIGZvciAobWF0Y2hTdGFydCA9IGNvbi5zdGFydDsgIG1hdGNoU3RhcnQgPD0gbGltaXQ7ICBtYXRjaFN0YXJ0ICsrKSB7Ci0gICAgICAgICAgICAgICAgaWYgKDAgPD0gKG1hdGNoRW5kID0gdGhpcy4gbWF0Y2goY29uLCB0aGlzLm9wZXJhdGlvbnMsIG1hdGNoU3RhcnQsIDEsIHRoaXMub3B0aW9ucykpKQotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGlmIChtYXRjaEVuZCA+PSAwKSB7Ci0gICAgICAgICAgICBpZiAoY29uLm1hdGNoICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBjb24ubWF0Y2guc2V0QmVnaW5uaW5nKDAsIG1hdGNoU3RhcnQpOwotICAgICAgICAgICAgICAgIGNvbi5tYXRjaC5zZXRFbmQoMCwgbWF0Y2hFbmQpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY29uLnNldEluVXNlKGZhbHNlKTsKLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgY29uLnNldEluVXNlKGZhbHNlKTsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIENoZWNrcyB3aGV0aGVyIHRoZSA8dmFyPnRhcmdldDwvdmFyPiB0ZXh0IDxzdHJvbmc+Y29udGFpbnM8L3N0cm9uZz4gdGhpcyBwYXR0ZXJuIG9yIG5vdC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgdGFyZ2V0IGlzIG1hdGNoZWQgdG8gdGhpcyByZWd1bGFyIGV4cHJlc3Npb24uCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gbWF0Y2hlcyhTdHJpbmcgIHRhcmdldCkgewotICAgICAgICByZXR1cm4gdGhpcy5tYXRjaGVzKHRhcmdldCwgMCwgIHRhcmdldCAubGVuZ3RoKCkgLCAoTWF0Y2gpbnVsbCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ2hlY2tzIHdoZXRoZXIgdGhlIDx2YXI+dGFyZ2V0PC92YXI+IHRleHQgPHN0cm9uZz5jb250YWluczwvc3Ryb25nPiB0aGlzIHBhdHRlcm4KLSAgICAgKiBpbiBzcGVjaWZpZWQgcmFuZ2Ugb3Igbm90LgotICAgICAqCi0gICAgICogQHBhcmFtIHN0YXJ0IFN0YXJ0IG9mZnNldCBvZiB0aGUgcmFuZ2UuCi0gICAgICogQHBhcmFtIGVuZCAgRW5kIG9mZnNldCArMSBvZiB0aGUgcmFuZ2UuCi0gICAgICogQHJldHVybiB0cnVlIGlmIHRoZSB0YXJnZXQgaXMgbWF0Y2hlZCB0byB0aGlzIHJlZ3VsYXIgZXhwcmVzc2lvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBtYXRjaGVzKFN0cmluZyAgdGFyZ2V0LCBpbnQgc3RhcnQsIGludCBlbmQpIHsKLSAgICAgICAgcmV0dXJuIHRoaXMubWF0Y2hlcyh0YXJnZXQsIHN0YXJ0LCBlbmQsIChNYXRjaCludWxsKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDaGVja3Mgd2hldGhlciB0aGUgPHZhcj50YXJnZXQ8L3Zhcj4gdGV4dCA8c3Ryb25nPmNvbnRhaW5zPC9zdHJvbmc+IHRoaXMgcGF0dGVybiBvciBub3QuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbWF0Y2ggQSBNYXRjaCBpbnN0YW5jZSBmb3Igc3RvcmluZyBtYXRjaGluZyByZXN1bHQuCi0gICAgICogQHJldHVybiBPZmZzZXQgb2YgdGhlIHN0YXJ0IHBvc2l0aW9uIGluIDxWQVI+dGFyZ2V0PC9WQVI+OyBvciAtMSBpZiBub3QgbWF0Y2guCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gbWF0Y2hlcyhTdHJpbmcgIHRhcmdldCwgTWF0Y2ggbWF0Y2gpIHsKLSAgICAgICAgcmV0dXJuIHRoaXMubWF0Y2hlcyh0YXJnZXQsIDAsICB0YXJnZXQgLmxlbmd0aCgpICwgbWF0Y2gpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENoZWNrcyB3aGV0aGVyIHRoZSA8dmFyPnRhcmdldDwvdmFyPiB0ZXh0IDxzdHJvbmc+Y29udGFpbnM8L3N0cm9uZz4gdGhpcyBwYXR0ZXJuCi0gICAgICogaW4gc3BlY2lmaWVkIHJhbmdlIG9yIG5vdC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzdGFydCBTdGFydCBvZmZzZXQgb2YgdGhlIHJhbmdlLgotICAgICAqIEBwYXJhbSBlbmQgIEVuZCBvZmZzZXQgKzEgb2YgdGhlIHJhbmdlLgotICAgICAqIEBwYXJhbSBtYXRjaCBBIE1hdGNoIGluc3RhbmNlIGZvciBzdG9yaW5nIG1hdGNoaW5nIHJlc3VsdC4KLSAgICAgKiBAcmV0dXJuIE9mZnNldCBvZiB0aGUgc3RhcnQgcG9zaXRpb24gaW4gPFZBUj50YXJnZXQ8L1ZBUj47IG9yIC0xIGlmIG5vdCBtYXRjaC4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBtYXRjaGVzKFN0cmluZyAgdGFyZ2V0LCBpbnQgc3RhcnQsIGludCBlbmQsIE1hdGNoIG1hdGNoKSB7Ci0KLSAgICAgICAgc3luY2hyb25pemVkICh0aGlzKSB7Ci0gICAgICAgICAgICBpZiAodGhpcy5vcGVyYXRpb25zID09IG51bGwpCi0gICAgICAgICAgICAgICAgdGhpcy5wcmVwYXJlKCk7Ci0gICAgICAgICAgICBpZiAodGhpcy5jb250ZXh0ID09IG51bGwpCi0gICAgICAgICAgICAgICAgdGhpcy5jb250ZXh0ID0gbmV3IENvbnRleHQoKTsKLSAgICAgICAgfQotICAgICAgICBDb250ZXh0IGNvbiA9IG51bGw7Ci0gICAgICAgIHN5bmNocm9uaXplZCAodGhpcy5jb250ZXh0KSB7Ci0gICAgICAgICAgICBjb24gPSB0aGlzLmNvbnRleHQuaW51c2UgPyBuZXcgQ29udGV4dCgpIDogdGhpcy5jb250ZXh0OwotICAgICAgICAgICAgY29uLnJlc2V0KHRhcmdldCwgc3RhcnQsIGVuZCwgdGhpcy5udW1iZXJPZkNsb3N1cmVzKTsKLSAgICAgICAgfQotICAgICAgICBpZiAobWF0Y2ggIT0gbnVsbCkgewotICAgICAgICAgICAgbWF0Y2guc2V0TnVtYmVyT2ZHcm91cHModGhpcy5ub2ZwYXJlbik7Ci0gICAgICAgICAgICBtYXRjaC5zZXRTb3VyY2UodGFyZ2V0KTsKLSAgICAgICAgfSBlbHNlIGlmICh0aGlzLmhhc0JhY2tSZWZlcmVuY2VzKSB7Ci0gICAgICAgICAgICBtYXRjaCA9IG5ldyBNYXRjaCgpOwotICAgICAgICAgICAgbWF0Y2guc2V0TnVtYmVyT2ZHcm91cHModGhpcy5ub2ZwYXJlbik7Ci0gICAgICAgICAgICAvLyBOZWVkIG5vdCB0byBjYWxsIHNldFNvdXJjZSgpIGJlY2F1c2UKLSAgICAgICAgICAgIC8vIGEgY2FsbGVyIGNhbiBub3QgYWNjZXNzIHRoaXMgbWF0Y2ggaW5zdGFuY2UuCi0gICAgICAgIH0KLSAgICAgICAgY29uLm1hdGNoID0gbWF0Y2g7Ci0KLSAgICAgICAgaWYgKFJlZ3VsYXJFeHByZXNzaW9uLmlzU2V0KHRoaXMub3B0aW9ucywgWE1MU0NIRU1BX01PREUpKSB7Ci0gICAgICAgICAgICBpZiAoREVCVUcpIHsKLSAgICAgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oInRhcmdldCBzdHJpbmc9Iit0YXJnZXQpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaW50IG1hdGNoRW5kID0gdGhpcy4gbWF0Y2goY29uLCB0aGlzLm9wZXJhdGlvbnMsIGNvbi5zdGFydCwgMSwgdGhpcy5vcHRpb25zKTsKLSAgICAgICAgICAgIGlmIChERUJVRykgewotICAgICAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigibWF0Y2hFbmQ9IittYXRjaEVuZCk7Ci0gICAgICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJjb24ubGltaXQ9Iitjb24ubGltaXQpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKG1hdGNoRW5kID09IGNvbi5saW1pdCkgewotICAgICAgICAgICAgICAgIGlmIChjb24ubWF0Y2ggIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBjb24ubWF0Y2guc2V0QmVnaW5uaW5nKDAsIGNvbi5zdGFydCk7Ci0gICAgICAgICAgICAgICAgICAgIGNvbi5tYXRjaC5zZXRFbmQoMCwgbWF0Y2hFbmQpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBjb24uc2V0SW5Vc2UoZmFsc2UpOwotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoKLSAgICAgICAgICogVGhlIHBhdHRlcm4gaGFzIG9ubHkgZml4ZWQgc3RyaW5nLgotICAgICAgICAgKiBUaGUgZW5naW5lIHVzZXMgQm95ZXItTW9vcmUuCi0gICAgICAgICAqLwotICAgICAgICBpZiAodGhpcy5maXhlZFN0cmluZ09ubHkpIHsKLSAgICAgICAgICAgIC8vU3lzdGVtLmVyci5wcmludGxuKCJERUJVRzogZml4ZWQtb25seTogIit0aGlzLmZpeGVkU3RyaW5nKTsKLSAgICAgICAgICAgIGludCBvID0gdGhpcy5maXhlZFN0cmluZ1RhYmxlLm1hdGNoZXModGFyZ2V0LCBjb24uc3RhcnQsIGNvbi5saW1pdCk7Ci0gICAgICAgICAgICBpZiAobyA+PSAwKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGNvbi5tYXRjaCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGNvbi5tYXRjaC5zZXRCZWdpbm5pbmcoMCwgbyk7Ci0gICAgICAgICAgICAgICAgICAgIGNvbi5tYXRjaC5zZXRFbmQoMCwgbyt0aGlzLmZpeGVkU3RyaW5nLmxlbmd0aCgpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgY29uLnNldEluVXNlKGZhbHNlKTsKLSAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNvbi5zZXRJblVzZShmYWxzZSk7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLQotICAgICAgICAvKgotICAgICAgICAgKiBUaGUgcGF0dGVybiBjb250YWlucyBhIGZpeGVkIHN0cmluZy4KLSAgICAgICAgICogVGhlIGVuZ2luZSBjaGVja3Mgd2l0aCBCb3llci1Nb29yZSB3aGV0aGVyIHRoZSB0ZXh0IGNvbnRhaW5zIHRoZSBmaXhlZCBzdHJpbmcgb3Igbm90LgotICAgICAgICAgKiBJZiBub3QsIGl0IHJldHVybiB3aXRoIGZhbHNlLgotICAgICAgICAgKi8KLSAgICAgICAgaWYgKHRoaXMuZml4ZWRTdHJpbmcgIT0gbnVsbCkgewotICAgICAgICAgICAgaW50IG8gPSB0aGlzLmZpeGVkU3RyaW5nVGFibGUubWF0Y2hlcyh0YXJnZXQsIGNvbi5zdGFydCwgY29uLmxpbWl0KTsKLSAgICAgICAgICAgIGlmIChvIDwgMCkgewotICAgICAgICAgICAgICAgIC8vU3lzdGVtLmVyci5wcmludGxuKCJOb24tbWF0Y2ggaW4gZml4ZWQtc3RyaW5nIHNlYXJjaC4iKTsKLSAgICAgICAgICAgICAgICBjb24uc2V0SW5Vc2UoZmFsc2UpOwotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGludCBsaW1pdCA9IGNvbi5saW1pdC10aGlzLm1pbmxlbmd0aDsKLSAgICAgICAgaW50IG1hdGNoU3RhcnQ7Ci0gICAgICAgIGludCBtYXRjaEVuZCA9IC0xOwotCi0gICAgICAgIC8qCi0gICAgICAgICAqIENoZWNrcyB3aGV0aGVyIHRoZSBleHByZXNzaW9uIHN0YXJ0cyB3aXRoICIuKiIuCi0gICAgICAgICAqLwotICAgICAgICBpZiAodGhpcy5vcGVyYXRpb25zICE9IG51bGwKLSAgICAgICAgICAgICYmIHRoaXMub3BlcmF0aW9ucy50eXBlID09IE9wLkNMT1NVUkUgJiYgdGhpcy5vcGVyYXRpb25zLmdldENoaWxkKCkudHlwZSA9PSBPcC5ET1QpIHsKLSAgICAgICAgICAgIGlmIChpc1NldCh0aGlzLm9wdGlvbnMsIFNJTkdMRV9MSU5FKSkgewotICAgICAgICAgICAgICAgIG1hdGNoU3RhcnQgPSBjb24uc3RhcnQ7Ci0gICAgICAgICAgICAgICAgbWF0Y2hFbmQgPSB0aGlzLm1hdGNoKGNvbiwgdGhpcy5vcGVyYXRpb25zLCBjb24uc3RhcnQsIDEsIHRoaXMub3B0aW9ucyk7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIGJvb2xlYW4gcHJldmlvdXNJc0VPTCA9IHRydWU7Ci0gICAgICAgICAgICAgICAgZm9yIChtYXRjaFN0YXJ0ID0gY29uLnN0YXJ0OyAgbWF0Y2hTdGFydCA8PSBsaW1pdDsgIG1hdGNoU3RhcnQgKyspIHsKLSAgICAgICAgICAgICAgICAgICAgaW50IGNoID0gIHRhcmdldCAuY2hhckF0KCAgbWF0Y2hTdGFydCApIDsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGlzRU9MQ2hhcihjaCkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHByZXZpb3VzSXNFT0wgPSB0cnVlOwotICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHByZXZpb3VzSXNFT0wpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoMCA8PSAobWF0Y2hFbmQgPSB0aGlzLm1hdGNoKGNvbiwgdGhpcy5vcGVyYXRpb25zLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0Y2hTdGFydCwgMSwgdGhpcy5vcHRpb25zKSkpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgcHJldmlvdXNJc0VPTCA9IGZhbHNlOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLyoKLSAgICAgICAgICogT3B0aW1pemF0aW9uIGFnYWluc3QgdGhlIGZpcnN0IGNoYXJhY3Rlci4KLSAgICAgICAgICovCi0gICAgICAgIGVsc2UgaWYgKHRoaXMuZmlyc3RDaGFyICE9IG51bGwpIHsKLSAgICAgICAgICAgIC8vU3lzdGVtLmVyci5wcmludGxuKCJERUJVRzogd2l0aCBmaXJzdGNoYXItbWF0Y2hpbmc6ICIrdGhpcy5maXJzdENoYXIpOwotICAgICAgICAgICAgUmFuZ2VUb2tlbiByYW5nZSA9IHRoaXMuZmlyc3RDaGFyOwotICAgICAgICAgICAgZm9yIChtYXRjaFN0YXJ0ID0gY29uLnN0YXJ0OyAgbWF0Y2hTdGFydCA8PSBsaW1pdDsgIG1hdGNoU3RhcnQgKyspIHsKLSAgICAgICAgICAgICAgICBpbnQgY2ggPSAgdGFyZ2V0IC5jaGFyQXQoICBtYXRjaFN0YXJ0ICkgOwotICAgICAgICAgICAgICAgIGlmIChSRVV0aWwuaXNIaWdoU3Vycm9nYXRlKGNoKSAmJiBtYXRjaFN0YXJ0KzEgPCBjb24ubGltaXQpIHsKLSAgICAgICAgICAgICAgICAgICAgY2ggPSBSRVV0aWwuY29tcG9zZUZyb21TdXJyb2dhdGVzKGNoLCB0YXJnZXQuY2hhckF0KG1hdGNoU3RhcnQrMSkpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpZiAoIXJhbmdlLm1hdGNoKGNoKSkgewotICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaWYgKDAgPD0gKG1hdGNoRW5kID0gdGhpcy5tYXRjaChjb24sIHRoaXMub3BlcmF0aW9ucywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdGNoU3RhcnQsIDEsIHRoaXMub3B0aW9ucykpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvKgotICAgICAgICAgKiBTdHJhaWdodGZvcndhcmQgbWF0Y2hpbmcuCi0gICAgICAgICAqLwotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIGZvciAobWF0Y2hTdGFydCA9IGNvbi5zdGFydDsgIG1hdGNoU3RhcnQgPD0gbGltaXQ7ICBtYXRjaFN0YXJ0ICsrKSB7Ci0gICAgICAgICAgICAgICAgaWYgKDAgPD0gKG1hdGNoRW5kID0gdGhpcy5tYXRjaChjb24sIHRoaXMub3BlcmF0aW9ucywgbWF0Y2hTdGFydCwgMSwgdGhpcy5vcHRpb25zKSkpCi0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKG1hdGNoRW5kID49IDApIHsKLSAgICAgICAgICAgIGlmIChjb24ubWF0Y2ggIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGNvbi5tYXRjaC5zZXRCZWdpbm5pbmcoMCwgbWF0Y2hTdGFydCk7Ci0gICAgICAgICAgICAgICAgY29uLm1hdGNoLnNldEVuZCgwLCBtYXRjaEVuZCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjb24uc2V0SW5Vc2UoZmFsc2UpOwotICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBjb24uc2V0SW5Vc2UoZmFsc2UpOwotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHJldHVybiAtMSB3aGVuIG5vdCBtYXRjaDsgb2Zmc2V0IG9mIHRoZSBlbmQgb2YgbWF0Y2hlZCBzdHJpbmcgd2hlbiBtYXRjaC4KLSAgICAgKi8KLSAgICBwcml2YXRlIGludCBtYXRjaChDb250ZXh0IGNvbiwgT3Agb3AsIGludCBvZmZzZXQsIGludCBkeCwgaW50IG9wdHMpIHsKLSAgICAgICAgZmluYWwgRXhwcmVzc2lvblRhcmdldCB0YXJnZXQgPSBjb24udGFyZ2V0OwotICAgICAgICBmaW5hbCBTdGFjayBvcFN0YWNrID0gbmV3IFN0YWNrKCk7Ci0gICAgICAgIGZpbmFsIEludFN0YWNrIGRhdGFTdGFjayA9IG5ldyBJbnRTdGFjaygpOwotICAgICAgICBmaW5hbCBib29sZWFuIGlzU2V0SWdub3JlQ2FzZSA9IGlzU2V0KG9wdHMsIElHTk9SRV9DQVNFKTsKLSAgICAgICAgaW50IHJldFZhbHVlID0gLTE7Ci0gICAgICAgIGJvb2xlYW4gcmV0dXJuZWQgPSBmYWxzZTsKLQotICAgICAgICBmb3IgKDs7KSB7Ci0gICAgICAgICAgICBpZiAob3AgPT0gbnVsbCB8fCBvZmZzZXQgPiBjb24ubGltaXQgfHwgb2Zmc2V0IDwgY29uLnN0YXJ0KSB7Ci0gICAgICAgICAgICAgICAgaWYgKG9wID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0VmFsdWUgPSBpc1NldChvcHRzLCBYTUxTQ0hFTUFfTU9ERSkgJiYgb2Zmc2V0ICE9IGNvbi5saW1pdCA/IC0xIDogb2Zmc2V0OwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICByZXRWYWx1ZSA9IC0xOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICByZXR1cm5lZCA9IHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlICB7Ci0gICAgICAgICAgICAgICAgcmV0VmFsdWUgPSAtMTsKLSAgICAgICAgICAgICAgICAvLyBkeCB2YWx1ZSBpcyBlaXRoZXIgMSBvciAtMQotICAgICAgICAgICAgICAgIHN3aXRjaCAob3AudHlwZSkgewotICAgICAgICAgICAgICAgIGNhc2UgT3AuQ0hBUjoKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IG8xID0gKGR4ID4gMCkgPyBvZmZzZXQgOiBvZmZzZXQgLTE7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAobzEgPj0gY29uLmxpbWl0IHx8IG8xIDwgMCB8fCAhbWF0Y2hDaGFyKG9wLmdldERhdGEoKSwgdGFyZ2V0LmNoYXJBdChvMSksIGlzU2V0SWdub3JlQ2FzZSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm5lZCA9IHRydWU7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQgKz0gZHg7Ci0gICAgICAgICAgICAgICAgICAgICAgICBvcCA9IG9wLm5leHQ7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgICAgICAgICBjYXNlIE9wLkRPVDoKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgaW50IG8xID0gKGR4ID4gMCkgPyBvZmZzZXQgOiBvZmZzZXQgLSAxOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG8xID49IGNvbi5saW1pdCB8fCBvMSA8IDApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm5lZCA9IHRydWU7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNTZXQob3B0cywgU0lOR0xFX0xJTkUpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKFJFVXRpbC5pc0hpZ2hTdXJyb2dhdGUodGFyZ2V0LmNoYXJBdChvMSkpICYmIG8xK2R4ID49IDAgJiYgbzErZHggPCBjb24ubGltaXQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbzEgKz0gZHg7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGNoID0gdGFyZ2V0LmNoYXJBdChvMSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKFJFVXRpbC5pc0hpZ2hTdXJyb2dhdGUoY2gpICYmIG8xK2R4ID49IDAgJiYgbzErZHggPCBjb24ubGltaXQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbzEgKz0gZHg7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoID0gUkVVdGlsLmNvbXBvc2VGcm9tU3Vycm9nYXRlcyhjaCwgdGFyZ2V0LmNoYXJBdChvMSkpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNFT0xDaGFyKGNoKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm5lZCA9IHRydWU7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldCA9IChkeCA+IDApID8gbzEgKyAxIDogbzE7Ci0gICAgICAgICAgICAgICAgICAgICAgICBvcCA9IG9wLm5leHQ7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgICAgICAgICBjYXNlIE9wLlJBTkdFOgotICAgICAgICAgICAgICAgIGNhc2UgT3AuTlJBTkdFOgotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpbnQgbzEgPSAoZHggPiAwKSA/IG9mZnNldCA6IG9mZnNldCAtMTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvMSA+PSBjb24ubGltaXQgfHwgbzEgPCAwKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuZWQgPSB0cnVlOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgaW50IGNoID0gdGFyZ2V0LmNoYXJBdChvZmZzZXQpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKFJFVXRpbC5pc0hpZ2hTdXJyb2dhdGUoY2gpICYmIG8xK2R4IDwgY29uLmxpbWl0ICYmIG8xK2R4ID49MCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG8xICs9IGR4OwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoID0gUkVVdGlsLmNvbXBvc2VGcm9tU3Vycm9nYXRlcyhjaCwgdGFyZ2V0LmNoYXJBdChvMSkpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgUmFuZ2VUb2tlbiB0b2sgPSBvcC5nZXRUb2tlbigpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF0b2subWF0Y2goY2gpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuZWQgPSB0cnVlOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0ID0gKGR4ID4gMCkgPyBvMSsxIDogbzE7Ci0gICAgICAgICAgICAgICAgICAgICAgICBvcCA9IG9wLm5leHQ7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgICAgICAgICBjYXNlIE9wLkFOQ0hPUjoKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFtYXRjaEFuY2hvcih0YXJnZXQsIG9wLCBjb24sIG9mZnNldCwgb3B0cykpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm5lZCA9IHRydWU7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBvcCA9IG9wLm5leHQ7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgICAgICAgICBjYXNlIE9wLkJBQ0tSRUZFUkVOQ0U6Ci0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGludCByZWZubyA9IG9wLmdldERhdGEoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZWZubyA8PSAwIHx8IHJlZm5vID49IHRoaXMubm9mcGFyZW4pIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiSW50ZXJuYWwgRXJyb3I6IFJlZmVyZW5jZSBudW1iZXIgbXVzdCBiZSBtb3JlIHRoYW4gemVybzogIityZWZubyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29uLm1hdGNoLmdldEJlZ2lubmluZyhyZWZubykgPCAwIHx8IGNvbi5tYXRjaC5nZXRFbmQocmVmbm8pIDwgMCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybmVkID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGludCBvMiA9IGNvbi5tYXRjaC5nZXRCZWdpbm5pbmcocmVmbm8pOwotICAgICAgICAgICAgICAgICAgICAgICAgaW50IGxpdGVyYWxsZW4gPSBjb24ubWF0Y2guZ2V0RW5kKHJlZm5vKS1vMjsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkeCA+IDApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXRhcmdldC5yZWdpb25NYXRjaGVzKGlzU2V0SWdub3JlQ2FzZSwgb2Zmc2V0LCBjb24ubGltaXQsIG8yLCBsaXRlcmFsbGVuKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm5lZCA9IHRydWU7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQgKz0gbGl0ZXJhbGxlbjsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdGFyZ2V0LnJlZ2lvbk1hdGNoZXMoaXNTZXRJZ25vcmVDYXNlLCBvZmZzZXQtbGl0ZXJhbGxlbiwgY29uLmxpbWl0LCBvMiwgbGl0ZXJhbGxlbikpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuZWQgPSB0cnVlOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0IC09IGxpdGVyYWxsZW47Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBvcCA9IG9wLm5leHQ7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgICAgICAgICBjYXNlIE9wLlNUUklORzoKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGxpdGVyYWwgPSBvcC5nZXRTdHJpbmcoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGludCBsaXRlcmFsbGVuID0gbGl0ZXJhbC5sZW5ndGgoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkeCA+IDApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXRhcmdldC5yZWdpb25NYXRjaGVzKGlzU2V0SWdub3JlQ2FzZSwgb2Zmc2V0LCBjb24ubGltaXQsIGxpdGVyYWwsIGxpdGVyYWxsZW4pKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybmVkID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldCArPSBsaXRlcmFsbGVuOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF0YXJnZXQucmVnaW9uTWF0Y2hlcyhpc1NldElnbm9yZUNhc2UsIG9mZnNldC1saXRlcmFsbGVuLCBjb24ubGltaXQsIGxpdGVyYWwsIGxpdGVyYWxsZW4pKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybmVkID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldCAtPSBsaXRlcmFsbGVuOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgb3AgPSBvcC5uZXh0OwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgICAgICAgICAgY2FzZSBPcC5DTE9TVVJFOgotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBTYXZlcyBjdXJyZW50IHBvc2l0aW9uIHRvIGF2b2lkIHplcm8td2lkdGggcmVwZWF0cy4KLSAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCBpZCA9IG9wLmdldERhdGEoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb24uY2xvc3VyZUNvbnRleHRzW2lkXS5jb250YWlucyhvZmZzZXQpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuZWQgPSB0cnVlOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgICAgICBjb24uY2xvc3VyZUNvbnRleHRzW2lkXS5hZGRPZmZzZXQob2Zmc2V0KTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAvLyBmYWxsIHRocm91Z2gKLQotICAgICAgICAgICAgICAgIGNhc2UgT3AuUVVFU1RJT046Ci0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIG9wU3RhY2sucHVzaChvcCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBkYXRhU3RhY2sucHVzaChvZmZzZXQpOwotICAgICAgICAgICAgICAgICAgICAgICAgb3AgPSBvcC5nZXRDaGlsZCgpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgICAgICAgICAgY2FzZSBPcC5OT05HUkVFRFlDTE9TVVJFOgotICAgICAgICAgICAgICAgIGNhc2UgT3AuTk9OR1JFRURZUVVFU1RJT046Ci0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIG9wU3RhY2sucHVzaChvcCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBkYXRhU3RhY2sucHVzaChvZmZzZXQpOwotICAgICAgICAgICAgICAgICAgICAgICAgb3AgPSBvcC5uZXh0OwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgICAgICAgICAgY2FzZSBPcC5VTklPTjoKLSAgICAgICAgICAgICAgICAgICAgaWYgKG9wLnNpemUoKSA9PSAwKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm5lZCA9IHRydWU7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBvcFN0YWNrLnB1c2gob3ApOwotICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVN0YWNrLnB1c2goMCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBkYXRhU3RhY2sucHVzaChvZmZzZXQpOwotICAgICAgICAgICAgICAgICAgICAgICAgb3AgPSBvcC5lbGVtZW50QXQoMCk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgICAgICAgICBjYXNlIE9wLkNBUFRVUkU6Ci0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCByZWZubyA9IG9wLmdldERhdGEoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb24ubWF0Y2ggIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZWZubyA+IDApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVN0YWNrLnB1c2goY29uLm1hdGNoLmdldEJlZ2lubmluZyhyZWZubykpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb24ubWF0Y2guc2V0QmVnaW5uaW5nKHJlZm5vLCBvZmZzZXQpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IGluZGV4ID0gLXJlZm5vOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhU3RhY2sucHVzaChjb24ubWF0Y2guZ2V0RW5kKGluZGV4KSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbi5tYXRjaC5zZXRFbmQoaW5kZXgsIG9mZnNldCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wU3RhY2sucHVzaChvcCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVN0YWNrLnB1c2gob2Zmc2V0KTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIG9wID0gb3AubmV4dDsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBicmVhazsKLQotICAgICAgICAgICAgICAgIGNhc2UgT3AuTE9PS0FIRUFEOgotICAgICAgICAgICAgICAgIGNhc2UgT3AuTkVHQVRJVkVMT09LQUhFQUQ6Ci0gICAgICAgICAgICAgICAgY2FzZSBPcC5MT09LQkVISU5EOgotICAgICAgICAgICAgICAgIGNhc2UgT3AuTkVHQVRJVkVMT09LQkVISU5EOgotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBvcFN0YWNrLnB1c2gob3ApOwotICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVN0YWNrLnB1c2goZHgpOwotICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVN0YWNrLnB1c2gob2Zmc2V0KTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGR4ID0gKG9wLnR5cGUgPT0gT3AuTE9PS0FIRUFEIHx8IG9wLnR5cGUgPT0gT3AuTkVHQVRJVkVMT09LQUhFQUQpID8gMSA6IC0xOwotICAgICAgICAgICAgICAgICAgICAgICAgb3AgPSBvcC5nZXRDaGlsZCgpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgICAgICAgICAgY2FzZSBPcC5JTkRFUEVOREVOVDoKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgb3BTdGFjay5wdXNoKG9wKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFTdGFjay5wdXNoKG9mZnNldCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBvcCA9IG9wLmdldENoaWxkKCk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgICAgICAgICBjYXNlIE9wLk1PRElGSUVSOgotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpbnQgbG9jYWxvcHRzID0gb3B0czsKLSAgICAgICAgICAgICAgICAgICAgICAgIGxvY2Fsb3B0cyB8PSBvcC5nZXREYXRhKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBsb2NhbG9wdHMgJj0gfm9wLmdldERhdGEyKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBvcFN0YWNrLnB1c2gob3ApOwotICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVN0YWNrLnB1c2gob3B0cyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBkYXRhU3RhY2sucHVzaChvZmZzZXQpOwotICAgICAgICAgICAgICAgICAgICAgICAgb3B0cyA9IGxvY2Fsb3B0czsKLSAgICAgICAgICAgICAgICAgICAgICAgIG9wID0gb3AuZ2V0Q2hpbGQoKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBicmVhazsKLQotICAgICAgICAgICAgICAgIGNhc2UgT3AuQ09ORElUSU9OOgotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBPcC5Db25kaXRpb25PcCBjb3AgPSAoT3AuQ29uZGl0aW9uT3Apb3A7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29wLnJlZk51bWJlciA+IDApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29wLnJlZk51bWJlciA+PSB0aGlzLm5vZnBhcmVuKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJJbnRlcm5hbCBFcnJvcjogUmVmZXJlbmNlIG51bWJlciBtdXN0IGJlIG1vcmUgdGhhbiB6ZXJvOiAiK2NvcC5yZWZOdW1iZXIpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29uLm1hdGNoLmdldEJlZ2lubmluZyhjb3AucmVmTnVtYmVyKSA+PSAwCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiBjb24ubWF0Y2guZ2V0RW5kKGNvcC5yZWZOdW1iZXIpID49IDApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3AgPSBjb3AueWVzOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChjb3Aubm8gIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcCA9IGNvcC5ubzsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wID0gY29wLm5leHQ7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgb3BTdGFjay5wdXNoKG9wKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhU3RhY2sucHVzaChvZmZzZXQpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wID0gY29wLmNvbmRpdGlvbjsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBicmVhazsKLQotICAgICAgICAgICAgICAgIGRlZmF1bHQ6Ci0gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJVbmtub3duIG9wZXJhdGlvbiB0eXBlOiAiICsgb3AudHlwZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBoYW5kbGUgcmVjdXJzaXZlIG9wZXJhdGlvbnMKLSAgICAgICAgICAgIHdoaWxlIChyZXR1cm5lZCkgewotICAgICAgICAgICAgICAgIC8vIGV4aGF1c3RlZCBhbGwgdGhlIG9wZXJhdGlvbnMKLSAgICAgICAgICAgICAgICBpZiAob3BTdGFjay5pc0VtcHR5KCkpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJldFZhbHVlOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIG9wID0gKE9wKSBvcFN0YWNrLnBvcCgpOwotICAgICAgICAgICAgICAgIG9mZnNldCA9IGRhdGFTdGFjay5wb3AoKTsKLQotICAgICAgICAgICAgICAgIHN3aXRjaCAob3AudHlwZSkgewotICAgICAgICAgICAgICAgIGNhc2UgT3AuQ0xPU1VSRToKLSAgICAgICAgICAgICAgICBjYXNlIE9wLlFVRVNUSU9OOgotICAgICAgICAgICAgICAgICAgICBpZiAocmV0VmFsdWUgPCAwKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBvcCA9IG9wLm5leHQ7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm5lZCA9IGZhbHNlOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgICAgICAgICAgY2FzZSBPcC5OT05HUkVFRFlDTE9TVVJFOgotICAgICAgICAgICAgICAgIGNhc2UgT3AuTk9OR1JFRURZUVVFU1RJT046Ci0gICAgICAgICAgICAgICAgICAgIGlmIChyZXRWYWx1ZSA8IDApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIG9wID0gb3AuZ2V0Q2hpbGQoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybmVkID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgICAgICAgICBjYXNlIE9wLlVOSU9OOgotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpbnQgdW5pb25JbmRleCA9IGRhdGFTdGFjay5wb3AoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChERUJVRykgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiVU5JT046ICIrdW5pb25JbmRleCsiLCByZXQ9IityZXRWYWx1ZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXRWYWx1ZSA8IDApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoKyt1bmlvbkluZGV4IDwgb3Auc2l6ZSgpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wU3RhY2sucHVzaChvcCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFTdGFjay5wdXNoKHVuaW9uSW5kZXgpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhU3RhY2sucHVzaChvZmZzZXQpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcCA9IG9wLmVsZW1lbnRBdCh1bmlvbkluZGV4KTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuZWQgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldFZhbHVlID0gLTE7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgICAgICAgICAgY2FzZSBPcC5DQVBUVVJFOgotICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgcmVmbm8gPSBvcC5nZXREYXRhKCk7Ci0gICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCBzYXZlZCA9IGRhdGFTdGFjay5wb3AoKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKHJldFZhbHVlIDwgMCkgewotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlZm5vID4gMCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbi5tYXRjaC5zZXRCZWdpbm5pbmcocmVmbm8sIHNhdmVkKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbi5tYXRjaC5zZXRFbmQoLXJlZm5vLCBzYXZlZCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgICAgICAgICBjYXNlIE9wLkxPT0tBSEVBRDoKLSAgICAgICAgICAgICAgICBjYXNlIE9wLkxPT0tCRUhJTkQ6Ci0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGR4ID0gZGF0YVN0YWNrLnBvcCgpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKDAgPD0gcmV0VmFsdWUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcCA9IG9wLm5leHQ7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuZWQgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIHJldFZhbHVlID0gLTE7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgICAgICAgICBjYXNlIE9wLk5FR0FUSVZFTE9PS0FIRUFEOgotICAgICAgICAgICAgICAgIGNhc2UgT3AuTkVHQVRJVkVMT09LQkVISU5EOgotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBkeCA9IGRhdGFTdGFjay5wb3AoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmICgwID4gcmV0VmFsdWUpICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgb3AgPSBvcC5uZXh0OwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybmVkID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXRWYWx1ZSA9IC0xOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgICAgICAgICAgY2FzZSBPcC5NT0RJRklFUjoKLSAgICAgICAgICAgICAgICAgICAgb3B0cyA9IGRhdGFTdGFjay5wb3AoKTsKLSAgICAgICAgICAgICAgICAgICAgLy8gZmFsbCB0aHJvdWdoCi0KLSAgICAgICAgICAgICAgICBjYXNlIE9wLklOREVQRU5ERU5UOgotICAgICAgICAgICAgICAgICAgICBpZiAocmV0VmFsdWUgPj0gMCkgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldCA9IHJldFZhbHVlOwotICAgICAgICAgICAgICAgICAgICAgICAgb3AgPSBvcC5uZXh0OwotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuZWQgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBicmVhazsKLQotICAgICAgICAgICAgICAgIGNhc2UgT3AuQ09ORElUSU9OOgotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBPcC5Db25kaXRpb25PcCBjb3AgPSAoT3AuQ29uZGl0aW9uT3Apb3A7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoMCA8PSByZXRWYWx1ZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wID0gY29wLnllczsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGNvcC5ubyAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgb3AgPSBjb3Aubm87Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcCA9IGNvcC5uZXh0OwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybmVkID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgICAgICAgICAgZGVmYXVsdDoKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBib29sZWFuIG1hdGNoQ2hhcihpbnQgY2gsIGludCBvdGhlciwgYm9vbGVhbiBpZ25vcmVDYXNlKSB7Ci0gICAgICAgIHJldHVybiAoaWdub3JlQ2FzZSkgPyBtYXRjaElnbm9yZUNhc2UoY2gsIG90aGVyKSA6IGNoID09IG90aGVyOwotICAgIH0KLQotICAgIGJvb2xlYW4gbWF0Y2hBbmNob3IoRXhwcmVzc2lvblRhcmdldCB0YXJnZXQsIE9wIG9wLCBDb250ZXh0IGNvbiwgaW50IG9mZnNldCwgaW50IG9wdHMpIHsKLSAgICAgICAgYm9vbGVhbiBnbyA9IGZhbHNlOwotICAgICAgICBzd2l0Y2ggKG9wLmdldERhdGEoKSkgewotICAgICAgICBjYXNlICdeJzoKLSAgICAgICAgICAgIGlmIChpc1NldChvcHRzLCBNVUxUSVBMRV9MSU5FUykpIHsKLSAgICAgICAgICAgICAgICBpZiAoIShvZmZzZXQgPT0gY29uLnN0YXJ0Ci0gICAgICAgICAgICAgICAgICAgICAgfHwgb2Zmc2V0ID4gY29uLnN0YXJ0ICYmIG9mZnNldCA8IGNvbi5saW1pdCAmJiBpc0VPTENoYXIodGFyZ2V0LmNoYXJBdChvZmZzZXQtMSkpKSkKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBpZiAob2Zmc2V0ICE9IGNvbi5zdGFydCkKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgY2FzZSAnQCc6ICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEludGVybmFsIHVzZSBvbmx5LgotICAgICAgICAgICAgLy8gVGhlIEAgYWx3YXlzIG1hdGNoZXMgbGluZSBiZWdpbm5pbmdzLgotICAgICAgICAgICAgaWYgKCEob2Zmc2V0ID09IGNvbi5zdGFydAotICAgICAgICAgICAgICAgICAgfHwgb2Zmc2V0ID4gY29uLnN0YXJ0ICYmIGlzRU9MQ2hhcih0YXJnZXQuY2hhckF0KG9mZnNldC0xKSkpKQotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgIGNhc2UgJyQnOgotICAgICAgICAgICAgaWYgKGlzU2V0KG9wdHMsIE1VTFRJUExFX0xJTkVTKSkgewotICAgICAgICAgICAgICAgIGlmICghKG9mZnNldCA9PSBjb24ubGltaXQKLSAgICAgICAgICAgICAgICAgICAgICB8fCBvZmZzZXQgPCBjb24ubGltaXQgJiYgaXNFT0xDaGFyKHRhcmdldC5jaGFyQXQob2Zmc2V0KSkpKQotICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIGlmICghKG9mZnNldCA9PSBjb24ubGltaXQKLSAgICAgICAgICAgICAgICAgICAgICB8fCBvZmZzZXQrMSA9PSBjb24ubGltaXQgJiYgaXNFT0xDaGFyKHRhcmdldC5jaGFyQXQob2Zmc2V0KSkKLSAgICAgICAgICAgICAgICAgICAgICB8fCBvZmZzZXQrMiA9PSBjb24ubGltaXQgJiYgIHRhcmdldC5jaGFyQXQob2Zmc2V0KSA9PSBDQVJSSUFHRV9SRVRVUk4KLSAgICAgICAgICAgICAgICAgICAgICAmJiAgdGFyZ2V0LmNoYXJBdChvZmZzZXQrMSkgPT0gTElORV9GRUVEKSkKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgY2FzZSAnQSc6Ci0gICAgICAgICAgICBpZiAob2Zmc2V0ICE9IGNvbi5zdGFydCkgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgIGNhc2UgJ1onOgotICAgICAgICAgICAgaWYgKCEob2Zmc2V0ID09IGNvbi5saW1pdAotICAgICAgICAgICAgICAgICAgfHwgb2Zmc2V0KzEgPT0gY29uLmxpbWl0ICYmIGlzRU9MQ2hhcih0YXJnZXQuY2hhckF0KG9mZnNldCkpCi0gICAgICAgICAgICAgICAgICB8fCBvZmZzZXQrMiA9PSBjb24ubGltaXQgJiYgIHRhcmdldC5jaGFyQXQob2Zmc2V0KSA9PSBDQVJSSUFHRV9SRVRVUk4KLSAgICAgICAgICAgICAgICAgICYmICB0YXJnZXQuY2hhckF0KG9mZnNldCsxKSA9PSBMSU5FX0ZFRUQpKQotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgIGNhc2UgJ3onOgotICAgICAgICAgICAgaWYgKG9mZnNldCAhPSBjb24ubGltaXQpICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICBicmVhazsKLQotICAgICAgICBjYXNlICdiJzoKLSAgICAgICAgICAgIGlmIChjb24ubGVuZ3RoID09IDApCi0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIGludCBhZnRlciA9IGdldFdvcmRUeXBlKHRhcmdldCwgY29uLnN0YXJ0LCBjb24ubGltaXQsIG9mZnNldCwgb3B0cyk7Ci0gICAgICAgICAgICAgICAgaWYgKGFmdGVyID09IFdUX0lHTk9SRSkgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgICAgICBpbnQgYmVmb3JlID0gZ2V0UHJldmlvdXNXb3JkVHlwZSh0YXJnZXQsIGNvbi5zdGFydCwgY29uLmxpbWl0LCBvZmZzZXQsIG9wdHMpOwotICAgICAgICAgICAgICAgIGlmIChhZnRlciA9PSBiZWZvcmUpICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBicmVhazsKLQotICAgICAgICBjYXNlICdCJzoKLSAgICAgICAgICAgIGlmIChjb24ubGVuZ3RoID09IDApCi0gICAgICAgICAgICAgICAgZ28gPSB0cnVlOwotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgaW50IGFmdGVyID0gZ2V0V29yZFR5cGUodGFyZ2V0LCBjb24uc3RhcnQsIGNvbi5saW1pdCwgb2Zmc2V0LCBvcHRzKTsKLSAgICAgICAgICAgICAgICBnbyA9IGFmdGVyID09IFdUX0lHTk9SRQotICAgICAgICAgICAgICAgICAgICAgfHwgYWZ0ZXIgPT0gZ2V0UHJldmlvdXNXb3JkVHlwZSh0YXJnZXQsIGNvbi5zdGFydCwgY29uLmxpbWl0LCBvZmZzZXQsIG9wdHMpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKCFnbykgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgIGNhc2UgJzwnOgotICAgICAgICAgICAgaWYgKGNvbi5sZW5ndGggPT0gMCB8fCBvZmZzZXQgPT0gY29uLmxpbWl0KSAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgaWYgKGdldFdvcmRUeXBlKHRhcmdldCwgY29uLnN0YXJ0LCBjb24ubGltaXQsIG9mZnNldCwgb3B0cykgIT0gV1RfTEVUVEVSCi0gICAgICAgICAgICAgICAgfHwgZ2V0UHJldmlvdXNXb3JkVHlwZSh0YXJnZXQsIGNvbi5zdGFydCwgY29uLmxpbWl0LCBvZmZzZXQsIG9wdHMpICE9IFdUX09USEVSKQotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgIGNhc2UgJz4nOgotICAgICAgICAgICAgaWYgKGNvbi5sZW5ndGggPT0gMCB8fCBvZmZzZXQgPT0gY29uLnN0YXJ0KSAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgaWYgKGdldFdvcmRUeXBlKHRhcmdldCwgY29uLnN0YXJ0LCBjb24ubGltaXQsIG9mZnNldCwgb3B0cykgIT0gV1RfT1RIRVIKLSAgICAgICAgICAgICAgICB8fCBnZXRQcmV2aW91c1dvcmRUeXBlKHRhcmdldCwgY29uLnN0YXJ0LCBjb24ubGltaXQsIG9mZnNldCwgb3B0cykgIT0gV1RfTEVUVEVSKQotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICB9IC8vIHN3aXRjaCBhbmNob3IgdHlwZQotCi0gICAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBnZXRQcmV2aW91c1dvcmRUeXBlKEV4cHJlc3Npb25UYXJnZXQgdGFyZ2V0LCBpbnQgYmVnaW4sIGludCBlbmQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG9mZnNldCwgaW50IG9wdHMpIHsKLSAgICAgICAgaW50IHJldCA9IGdldFdvcmRUeXBlKHRhcmdldCwgYmVnaW4sIGVuZCwgLS1vZmZzZXQsIG9wdHMpOwotICAgICAgICB3aGlsZSAocmV0ID09IFdUX0lHTk9SRSkKLSAgICAgICAgICAgIHJldCA9IGdldFdvcmRUeXBlKHRhcmdldCwgYmVnaW4sIGVuZCwgLS1vZmZzZXQsIG9wdHMpOwotICAgICAgICByZXR1cm4gcmV0OwotICAgIH0KLQotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBnZXRXb3JkVHlwZShFeHByZXNzaW9uVGFyZ2V0IHRhcmdldCwgaW50IGJlZ2luLCBpbnQgZW5kLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgb2Zmc2V0LCBpbnQgb3B0cykgewotICAgICAgICBpZiAob2Zmc2V0IDwgYmVnaW4gfHwgb2Zmc2V0ID49IGVuZCkgIHJldHVybiBXVF9PVEhFUjsKLSAgICAgICAgcmV0dXJuIGdldFdvcmRUeXBlMCh0YXJnZXQuY2hhckF0KG9mZnNldCkgLCBvcHRzKTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIENoZWNrcyB3aGV0aGVyIHRoZSA8dmFyPnRhcmdldDwvdmFyPiB0ZXh0IDxzdHJvbmc+Y29udGFpbnM8L3N0cm9uZz4gdGhpcyBwYXR0ZXJuIG9yIG5vdC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgdGFyZ2V0IGlzIG1hdGNoZWQgdG8gdGhpcyByZWd1bGFyIGV4cHJlc3Npb24uCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gbWF0Y2hlcyhDaGFyYWN0ZXJJdGVyYXRvciB0YXJnZXQpIHsKLSAgICAgICAgcmV0dXJuIHRoaXMubWF0Y2hlcyh0YXJnZXQsIChNYXRjaCludWxsKTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIENoZWNrcyB3aGV0aGVyIHRoZSA8dmFyPnRhcmdldDwvdmFyPiB0ZXh0IDxzdHJvbmc+Y29udGFpbnM8L3N0cm9uZz4gdGhpcyBwYXR0ZXJuIG9yIG5vdC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBtYXRjaCBBIE1hdGNoIGluc3RhbmNlIGZvciBzdG9yaW5nIG1hdGNoaW5nIHJlc3VsdC4KLSAgICAgKiBAcmV0dXJuIE9mZnNldCBvZiB0aGUgc3RhcnQgcG9zaXRpb24gaW4gPFZBUj50YXJnZXQ8L1ZBUj47IG9yIC0xIGlmIG5vdCBtYXRjaC4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBtYXRjaGVzKENoYXJhY3Rlckl0ZXJhdG9yICB0YXJnZXQsIE1hdGNoIG1hdGNoKSB7Ci0gICAgICAgIGludCBzdGFydCA9IHRhcmdldC5nZXRCZWdpbkluZGV4KCk7Ci0gICAgICAgIGludCBlbmQgPSB0YXJnZXQuZ2V0RW5kSW5kZXgoKTsKLQotCi0KLSAgICAgICAgc3luY2hyb25pemVkICh0aGlzKSB7Ci0gICAgICAgICAgICBpZiAodGhpcy5vcGVyYXRpb25zID09IG51bGwpCi0gICAgICAgICAgICAgICAgdGhpcy5wcmVwYXJlKCk7Ci0gICAgICAgICAgICBpZiAodGhpcy5jb250ZXh0ID09IG51bGwpCi0gICAgICAgICAgICAgICAgdGhpcy5jb250ZXh0ID0gbmV3IENvbnRleHQoKTsKLSAgICAgICAgfQotICAgICAgICBDb250ZXh0IGNvbiA9IG51bGw7Ci0gICAgICAgIHN5bmNocm9uaXplZCAodGhpcy5jb250ZXh0KSB7Ci0gICAgICAgICAgICBjb24gPSB0aGlzLmNvbnRleHQuaW51c2UgPyBuZXcgQ29udGV4dCgpIDogdGhpcy5jb250ZXh0OwotICAgICAgICAgICAgY29uLnJlc2V0KHRhcmdldCwgc3RhcnQsIGVuZCwgdGhpcy5udW1iZXJPZkNsb3N1cmVzKTsKLSAgICAgICAgfQotICAgICAgICBpZiAobWF0Y2ggIT0gbnVsbCkgewotICAgICAgICAgICAgbWF0Y2guc2V0TnVtYmVyT2ZHcm91cHModGhpcy5ub2ZwYXJlbik7Ci0gICAgICAgICAgICBtYXRjaC5zZXRTb3VyY2UodGFyZ2V0KTsKLSAgICAgICAgfSBlbHNlIGlmICh0aGlzLmhhc0JhY2tSZWZlcmVuY2VzKSB7Ci0gICAgICAgICAgICBtYXRjaCA9IG5ldyBNYXRjaCgpOwotICAgICAgICAgICAgbWF0Y2guc2V0TnVtYmVyT2ZHcm91cHModGhpcy5ub2ZwYXJlbik7Ci0gICAgICAgICAgICAvLyBOZWVkIG5vdCB0byBjYWxsIHNldFNvdXJjZSgpIGJlY2F1c2UKLSAgICAgICAgICAgIC8vIGEgY2FsbGVyIGNhbiBub3QgYWNjZXNzIHRoaXMgbWF0Y2ggaW5zdGFuY2UuCi0gICAgICAgIH0KLSAgICAgICAgY29uLm1hdGNoID0gbWF0Y2g7Ci0KLSAgICAgICAgaWYgKFJlZ3VsYXJFeHByZXNzaW9uLmlzU2V0KHRoaXMub3B0aW9ucywgWE1MU0NIRU1BX01PREUpKSB7Ci0gICAgICAgICAgICBpbnQgbWF0Y2hFbmQgPSB0aGlzLm1hdGNoKGNvbiwgdGhpcy5vcGVyYXRpb25zLCBjb24uc3RhcnQsIDEsIHRoaXMub3B0aW9ucyk7Ci0gICAgICAgICAgICAvL1N5c3RlbS5lcnIucHJpbnRsbigiREVCVUc6IG1hdGNoRW5kPSIrbWF0Y2hFbmQpOwotICAgICAgICAgICAgaWYgKG1hdGNoRW5kID09IGNvbi5saW1pdCkgewotICAgICAgICAgICAgICAgIGlmIChjb24ubWF0Y2ggIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBjb24ubWF0Y2guc2V0QmVnaW5uaW5nKDAsIGNvbi5zdGFydCk7Ci0gICAgICAgICAgICAgICAgICAgIGNvbi5tYXRjaC5zZXRFbmQoMCwgbWF0Y2hFbmQpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBjb24uc2V0SW5Vc2UoZmFsc2UpOwotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoKLSAgICAgICAgICogVGhlIHBhdHRlcm4gaGFzIG9ubHkgZml4ZWQgc3RyaW5nLgotICAgICAgICAgKiBUaGUgZW5naW5lIHVzZXMgQm95ZXItTW9vcmUuCi0gICAgICAgICAqLwotICAgICAgICBpZiAodGhpcy5maXhlZFN0cmluZ09ubHkpIHsKLSAgICAgICAgICAgIC8vU3lzdGVtLmVyci5wcmludGxuKCJERUJVRzogZml4ZWQtb25seTogIit0aGlzLmZpeGVkU3RyaW5nKTsKLSAgICAgICAgICAgIGludCBvID0gdGhpcy5maXhlZFN0cmluZ1RhYmxlLm1hdGNoZXModGFyZ2V0LCBjb24uc3RhcnQsIGNvbi5saW1pdCk7Ci0gICAgICAgICAgICBpZiAobyA+PSAwKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGNvbi5tYXRjaCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGNvbi5tYXRjaC5zZXRCZWdpbm5pbmcoMCwgbyk7Ci0gICAgICAgICAgICAgICAgICAgIGNvbi5tYXRjaC5zZXRFbmQoMCwgbyt0aGlzLmZpeGVkU3RyaW5nLmxlbmd0aCgpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgY29uLnNldEluVXNlKGZhbHNlKTsKLSAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNvbi5zZXRJblVzZShmYWxzZSk7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLQotICAgICAgICAvKgotICAgICAgICAgKiBUaGUgcGF0dGVybiBjb250YWlucyBhIGZpeGVkIHN0cmluZy4KLSAgICAgICAgICogVGhlIGVuZ2luZSBjaGVja3Mgd2l0aCBCb3llci1Nb29yZSB3aGV0aGVyIHRoZSB0ZXh0IGNvbnRhaW5zIHRoZSBmaXhlZCBzdHJpbmcgb3Igbm90LgotICAgICAgICAgKiBJZiBub3QsIGl0IHJldHVybiB3aXRoIGZhbHNlLgotICAgICAgICAgKi8KLSAgICAgICAgaWYgKHRoaXMuZml4ZWRTdHJpbmcgIT0gbnVsbCkgewotICAgICAgICAgICAgaW50IG8gPSB0aGlzLmZpeGVkU3RyaW5nVGFibGUubWF0Y2hlcyh0YXJnZXQsIGNvbi5zdGFydCwgY29uLmxpbWl0KTsKLSAgICAgICAgICAgIGlmIChvIDwgMCkgewotICAgICAgICAgICAgICAgIC8vU3lzdGVtLmVyci5wcmludGxuKCJOb24tbWF0Y2ggaW4gZml4ZWQtc3RyaW5nIHNlYXJjaC4iKTsKLSAgICAgICAgICAgICAgICBjb24uc2V0SW5Vc2UoZmFsc2UpOwotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGludCBsaW1pdCA9IGNvbi5saW1pdC10aGlzLm1pbmxlbmd0aDsKLSAgICAgICAgaW50IG1hdGNoU3RhcnQ7Ci0gICAgICAgIGludCBtYXRjaEVuZCA9IC0xOwotCi0gICAgICAgIC8qCi0gICAgICAgICAqIENoZWNrcyB3aGV0aGVyIHRoZSBleHByZXNzaW9uIHN0YXJ0cyB3aXRoICIuKiIuCi0gICAgICAgICAqLwotICAgICAgICBpZiAodGhpcy5vcGVyYXRpb25zICE9IG51bGwKLSAgICAgICAgICAgICYmIHRoaXMub3BlcmF0aW9ucy50eXBlID09IE9wLkNMT1NVUkUgJiYgdGhpcy5vcGVyYXRpb25zLmdldENoaWxkKCkudHlwZSA9PSBPcC5ET1QpIHsKLSAgICAgICAgICAgIGlmIChpc1NldCh0aGlzLm9wdGlvbnMsIFNJTkdMRV9MSU5FKSkgewotICAgICAgICAgICAgICAgIG1hdGNoU3RhcnQgPSBjb24uc3RhcnQ7Ci0gICAgICAgICAgICAgICAgbWF0Y2hFbmQgPSB0aGlzLm1hdGNoKGNvbiwgdGhpcy5vcGVyYXRpb25zLCBjb24uc3RhcnQsIDEsIHRoaXMub3B0aW9ucyk7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIGJvb2xlYW4gcHJldmlvdXNJc0VPTCA9IHRydWU7Ci0gICAgICAgICAgICAgICAgZm9yIChtYXRjaFN0YXJ0ID0gY29uLnN0YXJ0OyAgbWF0Y2hTdGFydCA8PSBsaW1pdDsgIG1hdGNoU3RhcnQgKyspIHsKLSAgICAgICAgICAgICAgICAgICAgaW50IGNoID0gIHRhcmdldCAuc2V0SW5kZXgoICBtYXRjaFN0YXJ0ICkgOwotICAgICAgICAgICAgICAgICAgICBpZiAoaXNFT0xDaGFyKGNoKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgcHJldmlvdXNJc0VPTCA9IHRydWU7Ci0gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAocHJldmlvdXNJc0VPTCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgwIDw9IChtYXRjaEVuZCA9IHRoaXMubWF0Y2goY29uLCB0aGlzLm9wZXJhdGlvbnMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRjaFN0YXJ0LCAxLCB0aGlzLm9wdGlvbnMpKSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBwcmV2aW91c0lzRU9MID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvKgotICAgICAgICAgKiBPcHRpbWl6YXRpb24gYWdhaW5zdCB0aGUgZmlyc3QgY2hhcmFjdGVyLgotICAgICAgICAgKi8KLSAgICAgICAgZWxzZSBpZiAodGhpcy5maXJzdENoYXIgIT0gbnVsbCkgewotICAgICAgICAgICAgLy9TeXN0ZW0uZXJyLnByaW50bG4oIkRFQlVHOiB3aXRoIGZpcnN0Y2hhci1tYXRjaGluZzogIit0aGlzLmZpcnN0Q2hhcik7Ci0gICAgICAgICAgICBSYW5nZVRva2VuIHJhbmdlID0gdGhpcy5maXJzdENoYXI7Ci0gICAgICAgICAgICBmb3IgKG1hdGNoU3RhcnQgPSBjb24uc3RhcnQ7ICBtYXRjaFN0YXJ0IDw9IGxpbWl0OyAgbWF0Y2hTdGFydCArKykgewotICAgICAgICAgICAgICAgIGludCBjaCA9ICB0YXJnZXQgLnNldEluZGV4KCAgbWF0Y2hTdGFydCApIDsKLSAgICAgICAgICAgICAgICBpZiAoUkVVdGlsLmlzSGlnaFN1cnJvZ2F0ZShjaCkgJiYgbWF0Y2hTdGFydCsxIDwgY29uLmxpbWl0KSB7Ci0gICAgICAgICAgICAgICAgICAgIGNoID0gUkVVdGlsLmNvbXBvc2VGcm9tU3Vycm9nYXRlcyhjaCwgdGFyZ2V0LnNldEluZGV4KG1hdGNoU3RhcnQrMSkpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpZiAoIXJhbmdlLm1hdGNoKGNoKSkgewotICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaWYgKDAgPD0gKG1hdGNoRW5kID0gdGhpcy5tYXRjaChjb24sIHRoaXMub3BlcmF0aW9ucywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdGNoU3RhcnQsIDEsIHRoaXMub3B0aW9ucykpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8qCi0gICAgICAgICAqIFN0cmFpZ2h0Zm9yd2FyZCBtYXRjaGluZy4KLSAgICAgICAgICovCi0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgZm9yIChtYXRjaFN0YXJ0ID0gY29uLnN0YXJ0OyAgbWF0Y2hTdGFydCA8PSBsaW1pdDsgIG1hdGNoU3RhcnQgKyspIHsKLSAgICAgICAgICAgICAgICBpZiAoMCA8PSAobWF0Y2hFbmQgPSB0aGlzLiBtYXRjaChjb24sIHRoaXMub3BlcmF0aW9ucywgbWF0Y2hTdGFydCwgMSwgdGhpcy5vcHRpb25zKSkpCi0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKG1hdGNoRW5kID49IDApIHsKLSAgICAgICAgICAgIGlmIChjb24ubWF0Y2ggIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGNvbi5tYXRjaC5zZXRCZWdpbm5pbmcoMCwgbWF0Y2hTdGFydCk7Ci0gICAgICAgICAgICAgICAgY29uLm1hdGNoLnNldEVuZCgwLCBtYXRjaEVuZCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjb24uc2V0SW5Vc2UoZmFsc2UpOwotICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBjb24uc2V0SW5Vc2UoZmFsc2UpOwotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotCi0gICAgLyoqCi0gICAgICogQSByZWd1bGFyIGV4cHJlc3Npb24uCi0gICAgICogQHNlcmlhbAotICAgICAqLwotICAgIFN0cmluZyByZWdleDsKLSAgICAvKioKLSAgICAgKiBAc2VyaWFsCi0gICAgICovCi0gICAgaW50IG9wdGlvbnM7Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgbnVtYmVyIG9mIHBhcmVudGhlc2lzIGluIHRoZSByZWd1bGFyIGV4cHJlc3Npb24uCi0gICAgICogQHNlcmlhbAotICAgICAqLwotICAgIGludCBub2ZwYXJlbjsKLSAgICAvKioKLSAgICAgKiBJbnRlcm5hbCByZXByZXNlbnRhdGlvbiBvZiB0aGUgcmVndWxhciBleHByZXNzaW9uLgotICAgICAqIEBzZXJpYWwKLSAgICAgKi8KLSAgICBUb2tlbiB0b2tlbnRyZWU7Ci0KLSAgICBib29sZWFuIGhhc0JhY2tSZWZlcmVuY2VzID0gZmFsc2U7Ci0KLSAgICB0cmFuc2llbnQgaW50IG1pbmxlbmd0aDsKLSAgICB0cmFuc2llbnQgT3Agb3BlcmF0aW9ucyA9IG51bGw7Ci0gICAgdHJhbnNpZW50IGludCBudW1iZXJPZkNsb3N1cmVzOwotICAgIHRyYW5zaWVudCBDb250ZXh0IGNvbnRleHQgPSBudWxsOwotICAgIHRyYW5zaWVudCBSYW5nZVRva2VuIGZpcnN0Q2hhciA9IG51bGw7Ci0KLSAgICB0cmFuc2llbnQgU3RyaW5nIGZpeGVkU3RyaW5nID0gbnVsbDsKLSAgICB0cmFuc2llbnQgaW50IGZpeGVkU3RyaW5nT3B0aW9uczsKLSAgICB0cmFuc2llbnQgQk1QYXR0ZXJuIGZpeGVkU3RyaW5nVGFibGUgPSBudWxsOwotICAgIHRyYW5zaWVudCBib29sZWFuIGZpeGVkU3RyaW5nT25seSA9IGZhbHNlOwotCi0gICAgc3RhdGljIGFic3RyYWN0IGNsYXNzIEV4cHJlc3Npb25UYXJnZXQgewotICAgICAgICBhYnN0cmFjdCBjaGFyIGNoYXJBdChpbnQgaW5kZXgpOwotICAgICAgICBhYnN0cmFjdCBib29sZWFuIHJlZ2lvbk1hdGNoZXMoYm9vbGVhbiBpZ25vcmVDYXNlLCBpbnQgb2Zmc2V0LCBpbnQgbGltaXQsIFN0cmluZyBwYXJ0LCBpbnQgcGFydGxlbik7Ci0gICAgICAgIGFic3RyYWN0IGJvb2xlYW4gcmVnaW9uTWF0Y2hlcyhib29sZWFuIGlnbm9yZUNhc2UsIGludCBvZmZzZXQsIGludCBsaW1pdCwgaW50IG9mZnNldDIsIGludCBwYXJ0bGVuKTsKLSAgICB9Ci0KLSAgICBzdGF0aWMgZmluYWwgY2xhc3MgU3RyaW5nVGFyZ2V0IGV4dGVuZHMgRXhwcmVzc2lvblRhcmdldCB7Ci0KLSAgICAgICAgcHJpdmF0ZSBTdHJpbmcgdGFyZ2V0OwotCi0gICAgICAgIFN0cmluZ1RhcmdldChTdHJpbmcgdGFyZ2V0KSB7Ci0gICAgICAgICAgICB0aGlzLnRhcmdldCA9IHRhcmdldDsKLSAgICAgICAgfQotCi0gICAgICAgIGZpbmFsIHZvaWQgcmVzZXRUYXJnZXQoU3RyaW5nIHRhcmdldCkgewotICAgICAgICAgICAgdGhpcy50YXJnZXQgPSB0YXJnZXQ7Ci0gICAgICAgIH0KLQotICAgICAgICBmaW5hbCBjaGFyIGNoYXJBdChpbnQgaW5kZXgpIHsKLSAgICAgICAgICAgIHJldHVybiB0YXJnZXQuY2hhckF0KGluZGV4KTsKLSAgICAgICAgfQotCi0gICAgICAgIGZpbmFsIGJvb2xlYW4gcmVnaW9uTWF0Y2hlcyhib29sZWFuIGlnbm9yZUNhc2UsIGludCBvZmZzZXQsIGludCBsaW1pdCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBwYXJ0LCBpbnQgcGFydGxlbikgewotICAgICAgICAgICAgaWYgKGxpbWl0LW9mZnNldCA8IHBhcnRsZW4pIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gKGlnbm9yZUNhc2UpID8gdGFyZ2V0LnJlZ2lvbk1hdGNoZXModHJ1ZSwgb2Zmc2V0LCBwYXJ0LCAwLCBwYXJ0bGVuKSA6IHRhcmdldC5yZWdpb25NYXRjaGVzKG9mZnNldCwgcGFydCwgMCwgcGFydGxlbik7Ci0gICAgICAgIH0KLQotICAgICAgICBmaW5hbCBib29sZWFuIHJlZ2lvbk1hdGNoZXMoYm9vbGVhbiBpZ25vcmVDYXNlLCBpbnQgb2Zmc2V0LCBpbnQgbGltaXQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgb2Zmc2V0MiwgaW50IHBhcnRsZW4pIHsKLSAgICAgICAgICAgIGlmIChsaW1pdC1vZmZzZXQgPCBwYXJ0bGVuKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIChpZ25vcmVDYXNlKSA/IHRhcmdldC5yZWdpb25NYXRjaGVzKHRydWUsIG9mZnNldCwgdGFyZ2V0LCBvZmZzZXQyLCBwYXJ0bGVuKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IHRhcmdldC5yZWdpb25NYXRjaGVzKG9mZnNldCwgdGFyZ2V0LCBvZmZzZXQyLCBwYXJ0bGVuKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHN0YXRpYyBmaW5hbCBjbGFzcyBDaGFyQXJyYXlUYXJnZXQgZXh0ZW5kcyBFeHByZXNzaW9uVGFyZ2V0IHsKLQotICAgICAgICBjaGFyW10gdGFyZ2V0OwotCi0gICAgICAgIENoYXJBcnJheVRhcmdldChjaGFyW10gdGFyZ2V0KSB7Ci0gICAgICAgICAgICB0aGlzLnRhcmdldCA9IHRhcmdldDsKLSAgICAgICAgfQotCi0gICAgICAgIGZpbmFsIHZvaWQgcmVzZXRUYXJnZXQoY2hhcltdIHRhcmdldCkgewotICAgICAgICAgICAgdGhpcy50YXJnZXQgPSB0YXJnZXQ7Ci0gICAgICAgIH0KLQotICAgICAgICBjaGFyIGNoYXJBdChpbnQgaW5kZXgpIHsKLSAgICAgICAgICAgIHJldHVybiB0YXJnZXRbaW5kZXhdOwotICAgICAgICB9Ci0KLSAgICAgICAgZmluYWwgYm9vbGVhbiByZWdpb25NYXRjaGVzKGJvb2xlYW4gaWdub3JlQ2FzZSwgaW50IG9mZnNldCwgaW50IGxpbWl0LAotICAgICAgICAgICAgICAgIFN0cmluZyBwYXJ0LCBpbnQgcGFydGxlbikgewotICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgbGltaXQtb2Zmc2V0IDwgcGFydGxlbikgIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gKGlnbm9yZUNhc2UpID8gcmVnaW9uTWF0Y2hlc0lnbm9yZUNhc2Uob2Zmc2V0LCBsaW1pdCwgcGFydCwgcGFydGxlbikKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiByZWdpb25NYXRjaGVzKG9mZnNldCwgbGltaXQsIHBhcnQsIHBhcnRsZW4pOwotICAgICAgICB9Ci0KLSAgICAgICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIHJlZ2lvbk1hdGNoZXMoaW50IG9mZnNldCwgaW50IGxpbWl0LCBTdHJpbmcgcGFydCwgaW50IHBhcnRsZW4pIHsKLSAgICAgICAgICAgIGludCBpID0gMDsKLSAgICAgICAgICAgIHdoaWxlIChwYXJ0bGVuLS0gPiAwKSB7Ci0gICAgICAgICAgICAgICAgaWYgKHRhcmdldFtvZmZzZXQrK10gIT0gcGFydC5jaGFyQXQoaSsrKSkgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgIH0KLQotICAgICAgICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gcmVnaW9uTWF0Y2hlc0lnbm9yZUNhc2UoaW50IG9mZnNldCwgaW50IGxpbWl0LCBTdHJpbmcgcGFydCwgaW50IHBhcnRsZW4pIHsKLSAgICAgICAgICAgIGludCBpID0gMDsKLSAgICAgICAgICAgIHdoaWxlIChwYXJ0bGVuLS0gPiAwKSB7Ci0gICAgICAgICAgICAgICAgZmluYWwgY2hhciBjaDEgPSB0YXJnZXRbb2Zmc2V0KytdIDsKLSAgICAgICAgICAgICAgICBmaW5hbCBjaGFyIGNoMiA9IHBhcnQuY2hhckF0KGkrKyk7Ci0gICAgICAgICAgICAgICAgaWYgKGNoMSA9PSBjaDIpIHsKLSAgICAgICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGZpbmFsIGNoYXIgdWNoMSA9IENoYXJhY3Rlci50b1VwcGVyQ2FzZShjaDEpOwotICAgICAgICAgICAgICAgIGZpbmFsIGNoYXIgdWNoMiA9IENoYXJhY3Rlci50b1VwcGVyQ2FzZShjaDIpOwotICAgICAgICAgICAgICAgIGlmICh1Y2gxID09IHVjaDIpIHsKLSAgICAgICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGlmIChDaGFyYWN0ZXIudG9Mb3dlckNhc2UodWNoMSkgIT0gQ2hhcmFjdGVyLnRvTG93ZXJDYXNlKHVjaDIpKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgfQotCi0gICAgICAgIGZpbmFsIGJvb2xlYW4gcmVnaW9uTWF0Y2hlcyhib29sZWFuIGlnbm9yZUNhc2UsIGludCBvZmZzZXQsIGludCBsaW1pdCwgaW50IG9mZnNldDIsIGludCBwYXJ0bGVuKSB7Ci0gICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBsaW1pdC1vZmZzZXQgPCBwYXJ0bGVuKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIChpZ25vcmVDYXNlKSA/IHJlZ2lvbk1hdGNoZXNJZ25vcmVDYXNlKG9mZnNldCwgbGltaXQsIG9mZnNldDIsIHBhcnRsZW4pCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogcmVnaW9uTWF0Y2hlcyhvZmZzZXQsIGxpbWl0LCBvZmZzZXQyLCBwYXJ0bGVuKTsKLSAgICAgICAgfQotCi0gICAgICAgIHByaXZhdGUgZmluYWwgYm9vbGVhbiByZWdpb25NYXRjaGVzKGludCBvZmZzZXQsIGludCBsaW1pdCwgaW50IG9mZnNldDIsIGludCBwYXJ0bGVuKSB7Ci0gICAgICAgICAgICBpbnQgaSA9IG9mZnNldDI7Ci0gICAgICAgICAgICB3aGlsZSAocGFydGxlbi0tID4gMCkgewotICAgICAgICAgICAgICAgIGlmICggdGFyZ2V0IFsgIG9mZnNldCsrIF0gICE9ICB0YXJnZXQgWyAgaSsrIF0gKQotICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgfQotCi0gICAgICAgIHByaXZhdGUgZmluYWwgYm9vbGVhbiByZWdpb25NYXRjaGVzSWdub3JlQ2FzZShpbnQgb2Zmc2V0LCBpbnQgbGltaXQsIGludCBvZmZzZXQyLCBpbnQgcGFydGxlbikgewotICAgICAgICAgICAgaW50IGkgPSBvZmZzZXQyOwotICAgICAgICAgICAgd2hpbGUgKHBhcnRsZW4tLSA+IDApIHsKLSAgICAgICAgICAgICAgICBmaW5hbCBjaGFyIGNoMSA9ICB0YXJnZXRbb2Zmc2V0KytdIDsKLSAgICAgICAgICAgICAgICBmaW5hbCBjaGFyIGNoMiA9ICB0YXJnZXRbaSsrXSA7Ci0gICAgICAgICAgICAgICAgaWYgKGNoMSA9PSBjaDIpIHsKLSAgICAgICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGZpbmFsIGNoYXIgdWNoMSA9IENoYXJhY3Rlci50b1VwcGVyQ2FzZShjaDEpOwotICAgICAgICAgICAgICAgIGZpbmFsIGNoYXIgdWNoMiA9IENoYXJhY3Rlci50b1VwcGVyQ2FzZShjaDIpOwotICAgICAgICAgICAgICAgIGlmICh1Y2gxID09IHVjaDIpIHsKLSAgICAgICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGlmIChDaGFyYWN0ZXIudG9Mb3dlckNhc2UodWNoMSkgIT0gQ2hhcmFjdGVyLnRvTG93ZXJDYXNlKHVjaDIpKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHN0YXRpYyBmaW5hbCBjbGFzcyBDaGFyYWN0ZXJJdGVyYXRvclRhcmdldCBleHRlbmRzIEV4cHJlc3Npb25UYXJnZXQgewotICAgICAgICBDaGFyYWN0ZXJJdGVyYXRvciB0YXJnZXQ7Ci0KLSAgICAgICAgQ2hhcmFjdGVySXRlcmF0b3JUYXJnZXQoQ2hhcmFjdGVySXRlcmF0b3IgdGFyZ2V0KSB7Ci0gICAgICAgICAgICB0aGlzLnRhcmdldCA9IHRhcmdldDsKLSAgICAgICAgfQotCi0gICAgICAgIGZpbmFsIHZvaWQgcmVzZXRUYXJnZXQoQ2hhcmFjdGVySXRlcmF0b3IgdGFyZ2V0KSB7Ci0gICAgICAgICAgICB0aGlzLnRhcmdldCA9IHRhcmdldDsKLSAgICAgICAgfQotCi0gICAgICAgIGZpbmFsIGNoYXIgY2hhckF0KGludCBpbmRleCkgewotICAgICAgICAgICAgcmV0dXJuIHRhcmdldC5zZXRJbmRleChpbmRleCk7Ci0gICAgICAgIH0KLQotICAgICAgICBmaW5hbCBib29sZWFuIHJlZ2lvbk1hdGNoZXMoYm9vbGVhbiBpZ25vcmVDYXNlLCBpbnQgb2Zmc2V0LCBpbnQgbGltaXQsCi0gICAgICAgICAgICAgICAgU3RyaW5nIHBhcnQsIGludCBwYXJ0bGVuKSB7Ci0gICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBsaW1pdC1vZmZzZXQgPCBwYXJ0bGVuKSAgewotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiAoaWdub3JlQ2FzZSkgPyByZWdpb25NYXRjaGVzSWdub3JlQ2FzZShvZmZzZXQsIGxpbWl0LCBwYXJ0LCBwYXJ0bGVuKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IHJlZ2lvbk1hdGNoZXMob2Zmc2V0LCBsaW1pdCwgcGFydCwgcGFydGxlbik7Ci0gICAgICAgIH0KLQotICAgICAgICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gcmVnaW9uTWF0Y2hlcyhpbnQgb2Zmc2V0LCBpbnQgbGltaXQsIFN0cmluZyBwYXJ0LCBpbnQgcGFydGxlbikgewotICAgICAgICAgICAgaW50IGkgPSAwOwotICAgICAgICAgICAgd2hpbGUgKHBhcnRsZW4tLSA+IDApIHsKLSAgICAgICAgICAgICAgICBpZiAodGFyZ2V0LnNldEluZGV4KG9mZnNldCsrKSAhPSBwYXJ0LmNoYXJBdChpKyspKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgfQotCi0gICAgICAgIHByaXZhdGUgZmluYWwgYm9vbGVhbiByZWdpb25NYXRjaGVzSWdub3JlQ2FzZShpbnQgb2Zmc2V0LCBpbnQgbGltaXQsIFN0cmluZyBwYXJ0LCBpbnQgcGFydGxlbikgewotICAgICAgICAgICAgaW50IGkgPSAwOwotICAgICAgICAgICAgd2hpbGUgKHBhcnRsZW4tLSA+IDApIHsKLSAgICAgICAgICAgICAgICBmaW5hbCBjaGFyIGNoMSA9IHRhcmdldC5zZXRJbmRleChvZmZzZXQrKykgOwotICAgICAgICAgICAgICAgIGZpbmFsIGNoYXIgY2gyID0gcGFydC5jaGFyQXQoaSsrKTsKLSAgICAgICAgICAgICAgICBpZiAoY2gxID09IGNoMikgewotICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZmluYWwgY2hhciB1Y2gxID0gQ2hhcmFjdGVyLnRvVXBwZXJDYXNlKGNoMSk7Ci0gICAgICAgICAgICAgICAgZmluYWwgY2hhciB1Y2gyID0gQ2hhcmFjdGVyLnRvVXBwZXJDYXNlKGNoMik7Ci0gICAgICAgICAgICAgICAgaWYgKHVjaDEgPT0gdWNoMikgewotICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaWYgKENoYXJhY3Rlci50b0xvd2VyQ2FzZSh1Y2gxKSAhPSBDaGFyYWN0ZXIudG9Mb3dlckNhc2UodWNoMikpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0KLSAgICAgICAgZmluYWwgYm9vbGVhbiByZWdpb25NYXRjaGVzKGJvb2xlYW4gaWdub3JlQ2FzZSwgaW50IG9mZnNldCwgaW50IGxpbWl0LCBpbnQgb2Zmc2V0MiwgaW50IHBhcnRsZW4pIHsKLSAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IGxpbWl0LW9mZnNldCA8IHBhcnRsZW4pIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gKGlnbm9yZUNhc2UpID8gcmVnaW9uTWF0Y2hlc0lnbm9yZUNhc2Uob2Zmc2V0LCBsaW1pdCwgb2Zmc2V0MiwgcGFydGxlbikKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiByZWdpb25NYXRjaGVzKG9mZnNldCwgbGltaXQsIG9mZnNldDIsIHBhcnRsZW4pOwotICAgICAgICB9Ci0KLSAgICAgICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIHJlZ2lvbk1hdGNoZXMoaW50IG9mZnNldCwgaW50IGxpbWl0LCBpbnQgb2Zmc2V0MiwgaW50IHBhcnRsZW4pIHsKLSAgICAgICAgICAgIGludCBpID0gb2Zmc2V0MjsKLSAgICAgICAgICAgIHdoaWxlIChwYXJ0bGVuLS0gPiAwKSB7Ci0gICAgICAgICAgICAgICAgaWYgKHRhcmdldC5zZXRJbmRleChvZmZzZXQrKykgIT0gdGFyZ2V0LnNldEluZGV4KGkrKykpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0KLSAgICAgICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIHJlZ2lvbk1hdGNoZXNJZ25vcmVDYXNlKGludCBvZmZzZXQsIGludCBsaW1pdCwgaW50IG9mZnNldDIsIGludCBwYXJ0bGVuKSB7Ci0gICAgICAgICAgICBpbnQgaSA9IG9mZnNldDI7Ci0gICAgICAgICAgICB3aGlsZSAocGFydGxlbi0tID4gMCkgewotICAgICAgICAgICAgICAgIGZpbmFsIGNoYXIgY2gxID0gdGFyZ2V0LnNldEluZGV4KG9mZnNldCsrKSA7Ci0gICAgICAgICAgICAgICAgZmluYWwgY2hhciBjaDIgPSB0YXJnZXQuc2V0SW5kZXgoaSsrKSA7Ci0gICAgICAgICAgICAgICAgaWYgKGNoMSA9PSBjaDIpIHsKLSAgICAgICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGZpbmFsIGNoYXIgdWNoMSA9IENoYXJhY3Rlci50b1VwcGVyQ2FzZShjaDEpOwotICAgICAgICAgICAgICAgIGZpbmFsIGNoYXIgdWNoMiA9IENoYXJhY3Rlci50b1VwcGVyQ2FzZShjaDIpOwotICAgICAgICAgICAgICAgIGlmICh1Y2gxID09IHVjaDIpIHsKLSAgICAgICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGlmIChDaGFyYWN0ZXIudG9Mb3dlckNhc2UodWNoMSkgIT0gQ2hhcmFjdGVyLnRvTG93ZXJDYXNlKHVjaDIpKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHN0YXRpYyBmaW5hbCBjbGFzcyBDbG9zdXJlQ29udGV4dCB7Ci0KLSAgICAgICAgaW50W10gb2Zmc2V0cyA9IG5ldyBpbnRbNF07Ci0gICAgICAgIGludCBjdXJyZW50SW5kZXggPSAwOwotCi0gICAgICAgIGJvb2xlYW4gY29udGFpbnMoaW50IG9mZnNldCkgewotICAgICAgICAgICAgZm9yIChpbnQgaT0wOyBpPGN1cnJlbnRJbmRleDsrK2kpIHsKLSAgICAgICAgICAgICAgICBpZiAob2Zmc2V0c1tpXSA9PSBvZmZzZXQpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0KLSAgICAgICAgdm9pZCByZXNldCgpIHsKLSAgICAgICAgICAgIGN1cnJlbnRJbmRleCA9IDA7Ci0gICAgICAgIH0KLQotICAgICAgICB2b2lkIGFkZE9mZnNldChpbnQgb2Zmc2V0KSB7Ci0gICAgICAgICAgICAvLyBXZSBkbyBub3QgY2hlY2sgZm9yIGR1cGxpY2F0ZXMsIGNhbGxlciBpcyByZXNwb25zaWJsZSBmb3IgdGhhdAotICAgICAgICAgICAgaWYgKGN1cnJlbnRJbmRleCA9PSBvZmZzZXRzLmxlbmd0aCkgewotICAgICAgICAgICAgICAgIG9mZnNldHMgPSBleHBhbmRPZmZzZXRzKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBvZmZzZXRzW2N1cnJlbnRJbmRleCsrXSA9IG9mZnNldDsKLSAgICAgICAgfQotCi0gICAgICAgIHByaXZhdGUgaW50W10gZXhwYW5kT2Zmc2V0cygpIHsKLSAgICAgICAgICAgIGZpbmFsIGludCBsZW4gPSBvZmZzZXRzLmxlbmd0aDsKLSAgICAgICAgICAgIGZpbmFsIGludCBuZXdMZW4gPSBsZW4gPDwgMTsKLSAgICAgICAgICAgIGludFtdIG5ld09mZnNldHMgPSBuZXcgaW50W25ld0xlbl07Ci0KLSAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkob2Zmc2V0cywgMCwgbmV3T2Zmc2V0cywgMCwgY3VycmVudEluZGV4KTsKLSAgICAgICAgICAgIHJldHVybiBuZXdPZmZzZXRzOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgc3RhdGljIGZpbmFsIGNsYXNzIENvbnRleHQgewotICAgICAgICBpbnQgc3RhcnQ7Ci0gICAgICAgIGludCBsaW1pdDsKLSAgICAgICAgaW50IGxlbmd0aDsKLSAgICAgICAgTWF0Y2ggbWF0Y2g7Ci0gICAgICAgIGJvb2xlYW4gaW51c2UgPSBmYWxzZTsKLSAgICAgICAgQ2xvc3VyZUNvbnRleHRbXSBjbG9zdXJlQ29udGV4dHM7Ci0KLSAgICAgICAgcHJpdmF0ZSBTdHJpbmdUYXJnZXQgc3RyaW5nVGFyZ2V0OwotICAgICAgICBwcml2YXRlIENoYXJBcnJheVRhcmdldCBjaGFyQXJyYXlUYXJnZXQ7Ci0gICAgICAgIHByaXZhdGUgQ2hhcmFjdGVySXRlcmF0b3JUYXJnZXQgY2hhcmFjdGVySXRlcmF0b3JUYXJnZXQ7Ci0KLSAgICAgICAgRXhwcmVzc2lvblRhcmdldCB0YXJnZXQ7Ci0KLSAgICAgICAgQ29udGV4dCgpIHsKLSAgICAgICAgfQotCi0gICAgICAgIHByaXZhdGUgdm9pZCByZXNldENvbW1vbihpbnQgbm9mY2xvc3VyZXMpIHsKLSAgICAgICAgICAgIHRoaXMubGVuZ3RoID0gdGhpcy5saW1pdC10aGlzLnN0YXJ0OwotICAgICAgICAgICAgc2V0SW5Vc2UodHJ1ZSk7Ci0gICAgICAgICAgICB0aGlzLm1hdGNoID0gbnVsbDsKLSAgICAgICAgICAgIGlmICh0aGlzLmNsb3N1cmVDb250ZXh0cyA9PSBudWxsIHx8IHRoaXMuY2xvc3VyZUNvbnRleHRzLmxlbmd0aCAhPSBub2ZjbG9zdXJlcykgewotICAgICAgICAgICAgICAgIHRoaXMuY2xvc3VyZUNvbnRleHRzID0gbmV3IENsb3N1cmVDb250ZXh0W25vZmNsb3N1cmVzXTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyAgaSA8IG5vZmNsb3N1cmVzOyAgaSArKykgIHsKLSAgICAgICAgICAgICAgICBpZiAodGhpcy5jbG9zdXJlQ29udGV4dHNbaV0gPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICB0aGlzLmNsb3N1cmVDb250ZXh0c1tpXSA9IG5ldyBDbG9zdXJlQ29udGV4dCgpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgdGhpcy5jbG9zdXJlQ29udGV4dHNbaV0ucmVzZXQoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICB2b2lkIHJlc2V0KENoYXJhY3Rlckl0ZXJhdG9yIHRhcmdldCwgaW50IHN0YXJ0LCBpbnQgbGltaXQsIGludCBub2ZjbG9zdXJlcykgewotICAgICAgICAgICAgaWYgKGNoYXJhY3Rlckl0ZXJhdG9yVGFyZ2V0ID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBjaGFyYWN0ZXJJdGVyYXRvclRhcmdldCA9IG5ldyBDaGFyYWN0ZXJJdGVyYXRvclRhcmdldCh0YXJnZXQpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgY2hhcmFjdGVySXRlcmF0b3JUYXJnZXQucmVzZXRUYXJnZXQodGFyZ2V0KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHRoaXMudGFyZ2V0ID0gY2hhcmFjdGVySXRlcmF0b3JUYXJnZXQ7Ci0gICAgICAgICAgICB0aGlzLnN0YXJ0ID0gc3RhcnQ7Ci0gICAgICAgICAgICB0aGlzLmxpbWl0ID0gbGltaXQ7Ci0gICAgICAgICAgICB0aGlzLnJlc2V0Q29tbW9uKG5vZmNsb3N1cmVzKTsKLSAgICAgICAgfQotCi0gICAgICAgIHZvaWQgcmVzZXQoU3RyaW5nIHRhcmdldCwgaW50IHN0YXJ0LCBpbnQgbGltaXQsIGludCBub2ZjbG9zdXJlcykgewotICAgICAgICAgICAgaWYgKHN0cmluZ1RhcmdldCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgc3RyaW5nVGFyZ2V0ID0gbmV3IFN0cmluZ1RhcmdldCh0YXJnZXQpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgc3RyaW5nVGFyZ2V0LnJlc2V0VGFyZ2V0KHRhcmdldCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICB0aGlzLnRhcmdldCA9IHN0cmluZ1RhcmdldDsKLSAgICAgICAgICAgIHRoaXMuc3RhcnQgPSBzdGFydDsKLSAgICAgICAgICAgIHRoaXMubGltaXQgPSBsaW1pdDsKLSAgICAgICAgICAgIHRoaXMucmVzZXRDb21tb24obm9mY2xvc3VyZXMpOwotICAgICAgICB9Ci0KLSAgICAgICAgdm9pZCByZXNldChjaGFyW10gdGFyZ2V0LCBpbnQgc3RhcnQsIGludCBsaW1pdCwgaW50IG5vZmNsb3N1cmVzKSB7Ci0gICAgICAgICAgICBpZiAoY2hhckFycmF5VGFyZ2V0ID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBjaGFyQXJyYXlUYXJnZXQgPSBuZXcgQ2hhckFycmF5VGFyZ2V0KHRhcmdldCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBjaGFyQXJyYXlUYXJnZXQucmVzZXRUYXJnZXQodGFyZ2V0KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHRoaXMudGFyZ2V0ID0gY2hhckFycmF5VGFyZ2V0OwotICAgICAgICAgICAgdGhpcy5zdGFydCA9IHN0YXJ0OwotICAgICAgICAgICAgdGhpcy5saW1pdCA9IGxpbWl0OwotICAgICAgICAgICAgdGhpcy5yZXNldENvbW1vbihub2ZjbG9zdXJlcyk7Ci0gICAgICAgIH0KLSAgICAgICAgc3luY2hyb25pemVkIHZvaWQgc2V0SW5Vc2UoYm9vbGVhbiBpblVzZSkgewotICAgICAgICAgICAgdGhpcy5pbnVzZSA9IGluVXNlOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUHJlcGFyZXMgZm9yIG1hdGNoaW5nLiAgVGhpcyBtZXRob2QgaXMgY2FsbGVkIGp1c3QgYmVmb3JlIHN0YXJ0aW5nIG1hdGNoaW5nLgotICAgICAqLwotICAgIHZvaWQgcHJlcGFyZSgpIHsKLSAgICAgICAgaWYgKE9wLkNPVU5UKSAgT3Aubm9maW5zdGFuY2VzID0gMDsKLSAgICAgICAgdGhpcy5jb21waWxlKHRoaXMudG9rZW50cmVlKTsKLSAgICAgICAgLyoKLSAgICAgICAgaWYgICh0aGlzLm9wZXJhdGlvbnMudHlwZSA9PSBPcC5DTE9TVVJFICYmIHRoaXMub3BlcmF0aW9ucy5nZXRDaGlsZCgpLnR5cGUgPT0gT3AuRE9UKSB7IC8vIC4qCi0gICAgICAgICAgICBPcCBhbmNob3IgPSBPcC5jcmVhdGVBbmNob3IoaXNTZXQodGhpcy5vcHRpb25zLCBTSU5HTEVfTElORSkgPyAnQScgOiAnQCcpOwotICAgICAgICAgICAgYW5jaG9yLm5leHQgPSB0aGlzLm9wZXJhdGlvbnM7Ci0gICAgICAgICAgICB0aGlzLm9wZXJhdGlvbnMgPSBhbmNob3I7Ci0gICAgICAgIH0KLSAgICAgICAgKi8KLSAgICAgICAgaWYgKE9wLkNPVU5UKSAgU3lzdGVtLmVyci5wcmludGxuKCJERUJVRzogVGhlIG51bWJlciBvZiBvcGVyYXRpb25zOiAiK09wLm5vZmluc3RhbmNlcyk7Ci0KLSAgICAgICAgdGhpcy5taW5sZW5ndGggPSB0aGlzLnRva2VudHJlZS5nZXRNaW5MZW5ndGgoKTsKLQotICAgICAgICB0aGlzLmZpcnN0Q2hhciA9IG51bGw7Ci0gICAgICAgIGlmICghaXNTZXQodGhpcy5vcHRpb25zLCBQUk9ISUJJVF9IRUFEX0NIQVJBQ1RFUl9PUFRJTUlaQVRJT04pCi0gICAgICAgICAgICAmJiAhaXNTZXQodGhpcy5vcHRpb25zLCBYTUxTQ0hFTUFfTU9ERSkpIHsKLSAgICAgICAgICAgIFJhbmdlVG9rZW4gZmlyc3RDaGFyID0gVG9rZW4uY3JlYXRlUmFuZ2UoKTsKLSAgICAgICAgICAgIGludCBmcmVzdWx0ID0gdGhpcy50b2tlbnRyZWUuYW5hbHl6ZUZpcnN0Q2hhcmFjdGVyKGZpcnN0Q2hhciwgdGhpcy5vcHRpb25zKTsKLSAgICAgICAgICAgIGlmIChmcmVzdWx0ID09IFRva2VuLkZDX1RFUk1JTkFMKSB7Ci0gICAgICAgICAgICAgICAgZmlyc3RDaGFyLmNvbXBhY3RSYW5nZXMoKTsKLSAgICAgICAgICAgICAgICB0aGlzLmZpcnN0Q2hhciA9IGZpcnN0Q2hhcjsKLSAgICAgICAgICAgICAgICBpZiAoREVCVUcpCi0gICAgICAgICAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiREVCVUc6IFVzZSB0aGUgZmlyc3QgY2hhcmFjdGVyIG9wdGltaXphdGlvbjogIitmaXJzdENoYXIpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKHRoaXMub3BlcmF0aW9ucyAhPSBudWxsCi0gICAgICAgICAgICAmJiAodGhpcy5vcGVyYXRpb25zLnR5cGUgPT0gT3AuU1RSSU5HIHx8IHRoaXMub3BlcmF0aW9ucy50eXBlID09IE9wLkNIQVIpCi0gICAgICAgICAgICAmJiB0aGlzLm9wZXJhdGlvbnMubmV4dCA9PSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAoREVCVUcpCi0gICAgICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludCgiICoqKiBPbmx5IGZpeGVkIHN0cmluZyEgKioqICIpOwotICAgICAgICAgICAgdGhpcy5maXhlZFN0cmluZ09ubHkgPSB0cnVlOwotICAgICAgICAgICAgaWYgKHRoaXMub3BlcmF0aW9ucy50eXBlID09IE9wLlNUUklORykKLSAgICAgICAgICAgICAgICB0aGlzLmZpeGVkU3RyaW5nID0gdGhpcy5vcGVyYXRpb25zLmdldFN0cmluZygpOwotICAgICAgICAgICAgZWxzZSBpZiAodGhpcy5vcGVyYXRpb25zLmdldERhdGEoKSA+PSAweDEwMDAwKSB7IC8vIE9wLkNIQVIKLSAgICAgICAgICAgICAgICB0aGlzLmZpeGVkU3RyaW5nID0gUkVVdGlsLmRlY29tcG9zZVRvU3Vycm9nYXRlcyh0aGlzLm9wZXJhdGlvbnMuZ2V0RGF0YSgpKTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgY2hhcltdIGFjID0gbmV3IGNoYXJbMV07Ci0gICAgICAgICAgICAgICAgYWNbMF0gPSAoY2hhcil0aGlzLm9wZXJhdGlvbnMuZ2V0RGF0YSgpOwotICAgICAgICAgICAgICAgIHRoaXMuZml4ZWRTdHJpbmcgPSBuZXcgU3RyaW5nKGFjKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHRoaXMuZml4ZWRTdHJpbmdPcHRpb25zID0gdGhpcy5vcHRpb25zOwotICAgICAgICAgICAgdGhpcy5maXhlZFN0cmluZ1RhYmxlID0gbmV3IEJNUGF0dGVybih0aGlzLmZpeGVkU3RyaW5nLCAyNTYsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzU2V0KHRoaXMuZml4ZWRTdHJpbmdPcHRpb25zLCBJR05PUkVfQ0FTRSkpOwotICAgICAgICB9IGVsc2UgaWYgKCFpc1NldCh0aGlzLm9wdGlvbnMsIFBST0hJQklUX0ZJWEVEX1NUUklOR19PUFRJTUlaQVRJT04pCi0gICAgICAgICAgICAgICAgICAgJiYgIWlzU2V0KHRoaXMub3B0aW9ucywgWE1MU0NIRU1BX01PREUpKSB7Ci0gICAgICAgICAgICBUb2tlbi5GaXhlZFN0cmluZ0NvbnRhaW5lciBjb250YWluZXIgPSBuZXcgVG9rZW4uRml4ZWRTdHJpbmdDb250YWluZXIoKTsKLSAgICAgICAgICAgIHRoaXMudG9rZW50cmVlLmZpbmRGaXhlZFN0cmluZyhjb250YWluZXIsIHRoaXMub3B0aW9ucyk7Ci0gICAgICAgICAgICB0aGlzLmZpeGVkU3RyaW5nID0gY29udGFpbmVyLnRva2VuID09IG51bGwgPyBudWxsIDogY29udGFpbmVyLnRva2VuLmdldFN0cmluZygpOwotICAgICAgICAgICAgdGhpcy5maXhlZFN0cmluZ09wdGlvbnMgPSBjb250YWluZXIub3B0aW9uczsKLSAgICAgICAgICAgIGlmICh0aGlzLmZpeGVkU3RyaW5nICE9IG51bGwgJiYgdGhpcy5maXhlZFN0cmluZy5sZW5ndGgoKSA8IDIpCi0gICAgICAgICAgICAgICAgdGhpcy5maXhlZFN0cmluZyA9IG51bGw7Ci0gICAgICAgICAgICAvLyBUaGlzIHBhdHRlcm4gaGFzIGEgZml4ZWQgc3RyaW5nIG9mIHdoaWNoIGxlbmd0aCBpcyBtb3JlIHRoYW4gb25lLgotICAgICAgICAgICAgaWYgKHRoaXMuZml4ZWRTdHJpbmcgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHRoaXMuZml4ZWRTdHJpbmdUYWJsZSA9IG5ldyBCTVBhdHRlcm4odGhpcy5maXhlZFN0cmluZywgMjU2LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNTZXQodGhpcy5maXhlZFN0cmluZ09wdGlvbnMsIElHTk9SRV9DQVNFKSk7Ci0gICAgICAgICAgICAgICAgaWYgKERFQlVHKSB7Ci0gICAgICAgICAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiREVCVUc6IFRoZSBsb25nZXN0IGZpeGVkIHN0cmluZzogIit0aGlzLmZpeGVkU3RyaW5nLmxlbmd0aCgpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIi8iIC8vK3RoaXMuZml4ZWRTdHJpbmcKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsiLyIrUkVVdGlsLmNyZWF0ZU9wdGlvblN0cmluZyh0aGlzLmZpeGVkU3RyaW5nT3B0aW9ucykpOwotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50KCJTdHJpbmc6ICIpOwotICAgICAgICAgICAgICAgICAgICBSRVV0aWwuZHVtcFN0cmluZyh0aGlzLmZpeGVkU3RyaW5nKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBbiBvcHRpb24uCi0gICAgICogSWYgeW91IHNwZWNpZnkgdGhpcyBvcHRpb24sIDxzcGFuIGNsYXNzPSJSRUdFWCI+PGtiZD4oPC9rYmQ+PHZhcj5YPC92YXI+PGtiZD4pPC9rYmQ+PC9zcGFuPgotICAgICAqIGNhcHR1cmVzIG1hdGNoZWQgdGV4dCwgYW5kIDxzcGFuIGNsYXNzPSJSRUdFWCI+PGtiZD4oOj88L2tiZD48dmFyPlg8L3Zhcj48a2JkPik8L2tiZD48L3NwYW4+Ci0gICAgICogZG9lcyBub3QgY2FwdHVyZS4KLSAgICAgKgotICAgICAqIEBzZWUgI1JlZ3VsYXJFeHByZXNzaW9uKGphdmEubGFuZy5TdHJpbmcsaW50KQotICAgICAqIEBzZWUgI3NldFBhdHRlcm4oamF2YS5sYW5nLlN0cmluZyxpbnQpCi0gICAgc3RhdGljIGZpbmFsIGludCBNQVJLX1BBUkVOUyA9IDE8PDA7Ci0gICAgICovCi0KLSAgICAvKioKLSAgICAgKiAiaSIKLSAgICAgKi8KLSAgICBzdGF0aWMgZmluYWwgaW50IElHTk9SRV9DQVNFID0gMTw8MTsKLQotICAgIC8qKgotICAgICAqICJzIgotICAgICAqLwotICAgIHN0YXRpYyBmaW5hbCBpbnQgU0lOR0xFX0xJTkUgPSAxPDwyOwotCi0gICAgLyoqCi0gICAgICogIm0iCi0gICAgICovCi0gICAgc3RhdGljIGZpbmFsIGludCBNVUxUSVBMRV9MSU5FUyA9IDE8PDM7Ci0KLSAgICAvKioKLSAgICAgKiAieCIKLSAgICAgKi8KLSAgICBzdGF0aWMgZmluYWwgaW50IEVYVEVOREVEX0NPTU1FTlQgPSAxPDw0OwotCi0gICAgLyoqCi0gICAgICogVGhpcyBvcHRpb24gcmVkZWZpbmVzIDxzcGFuIGNsYXNzPSJSRUdFWCI+PGtiZD5cZCBcRCBcdyBcVyBccyBcUzwva2JkPjwvc3Bhbj4uCi0gICAgICoKLSAgICAgKiBAc2VlICNSZWd1bGFyRXhwcmVzc2lvbihqYXZhLmxhbmcuU3RyaW5nLGludCkKLSAgICAgKiBAc2VlICNzZXRQYXR0ZXJuKGphdmEubGFuZy5TdHJpbmcsaW50KQotICAgICAqIEBzZWUgI1VOSUNPREVfV09SRF9CT1VOREFSWQotICAgICAqLwotICAgIHN0YXRpYyBmaW5hbCBpbnQgVVNFX1VOSUNPREVfQ0FURUdPUlkgPSAxPDw1OyAvLyAidSIKLQotICAgIC8qKgotICAgICAqIEFuIG9wdGlvbi4KLSAgICAgKiBUaGlzIGVuYWJsZXMgdG8gcHJvY2VzcyBsb2NhbGUtaW5kZXBlbmRlbnQgd29yZCBib3VuZGFyeSBmb3IgPHNwYW4gY2xhc3M9IlJFR0VYIj48a2JkPlxiIFxCIFwmbHQ7IFw+PC9rYmQ+PC9zcGFuPi4KLSAgICAgKiA8cD5CeSBkZWZhdWx0LCB0aGUgZW5naW5lIGNvbnNpZGVycyBhIHBvc2l0aW9uIGJldHdlZW4gYSB3b3JkIGNoYXJhY3RlcgotICAgICAqICg8c3BhbiBjbGFzcz0iUkVHRVgiPjxLYmQ+XHc8L2tiZD48L3NwYW4+KSBhbmQgYSBub24gd29yZCBjaGFyYWN0ZXIKLSAgICAgKiBpcyBhIHdvcmQgYm91bmRhcnkuCi0gICAgICogPHA+QnkgdGhpcyBvcHRpb24sIHRoZSBlbmdpbmUgY2hlY2tzIHdvcmQgYm91bmRhcmllcyB3aXRoIHRoZSBtZXRob2Qgb2YKLSAgICAgKiAnVW5pY29kZSBSZWd1bGFyIEV4cHJlc3Npb24gR3VpZGVsaW5lcycgUmV2aXNpb24gNC4KLSAgICAgKgotICAgICAqIEBzZWUgI1JlZ3VsYXJFeHByZXNzaW9uKGphdmEubGFuZy5TdHJpbmcsaW50KQotICAgICAqIEBzZWUgI3NldFBhdHRlcm4oamF2YS5sYW5nLlN0cmluZyxpbnQpCi0gICAgICovCi0gICAgc3RhdGljIGZpbmFsIGludCBVTklDT0RFX1dPUkRfQk9VTkRBUlkgPSAxPDw2OyAvLyAidyIKLQotICAgIC8qKgotICAgICAqICJIIgotICAgICAqLwotICAgIHN0YXRpYyBmaW5hbCBpbnQgUFJPSElCSVRfSEVBRF9DSEFSQUNURVJfT1BUSU1JWkFUSU9OID0gMTw8NzsKLSAgICAvKioKLSAgICAgKiAiRiIKLSAgICAgKi8KLSAgICBzdGF0aWMgZmluYWwgaW50IFBST0hJQklUX0ZJWEVEX1NUUklOR19PUFRJTUlaQVRJT04gPSAxPDw4OwotICAgIC8qKgotICAgICAqICJYIi4gWE1MIFNjaGVtYSBtb2RlLgotICAgICAqLwotICAgIHN0YXRpYyBmaW5hbCBpbnQgWE1MU0NIRU1BX01PREUgPSAxPDw5OwotICAgIC8qKgotICAgICAqICIsIi4KLSAgICAgKi8KLSAgICBzdGF0aWMgZmluYWwgaW50IFNQRUNJQUxfQ09NTUEgPSAxPDwxMDsKLQotCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbiBpc1NldChpbnQgb3B0aW9ucywgaW50IGZsYWcpIHsKLSAgICAgICAgcmV0dXJuIChvcHRpb25zICYgZmxhZykgPT0gZmxhZzsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGVzIGEgbmV3IFJlZ3VsYXJFeHByZXNzaW9uIGluc3RhbmNlLgotICAgICAqCi0gICAgICogQHBhcmFtIHJlZ2V4IEEgcmVndWxhciBleHByZXNzaW9uCi0gICAgICogQGV4Y2VwdGlvbiBvcmcuYXBhY2hlLnhlcmNlcy51dGlscy5yZWdleC5QYXJzZUV4Y2VwdGlvbiA8VkFSPnJlZ2V4PC9WQVI+IGlzIG5vdCBjb25mb3JtaW5nIHRvIHRoZSBzeW50YXguCi0gICAgICovCi0gICAgcHVibGljIFJlZ3VsYXJFeHByZXNzaW9uKFN0cmluZyByZWdleCkgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKLSAgICAgICAgdGhpcyhyZWdleCwgbnVsbCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlcyBhIG5ldyBSZWd1bGFyRXhwcmVzc2lvbiBpbnN0YW5jZSB3aXRoIG9wdGlvbnMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcmVnZXggQSByZWd1bGFyIGV4cHJlc3Npb24KLSAgICAgKiBAcGFyYW0gb3B0aW9ucyBBIFN0cmluZyBjb25zaXN0ZWQgb2YgImkiICJtIiAicyIgInUiICJ3IiAiLCIgIlgiCi0gICAgICogQGV4Y2VwdGlvbiBvcmcuYXBhY2hlLnhlcmNlcy51dGlscy5yZWdleC5QYXJzZUV4Y2VwdGlvbiA8VkFSPnJlZ2V4PC9WQVI+IGlzIG5vdCBjb25mb3JtaW5nIHRvIHRoZSBzeW50YXguCi0gICAgICovCi0gICAgcHVibGljIFJlZ3VsYXJFeHByZXNzaW9uKFN0cmluZyByZWdleCwgU3RyaW5nIG9wdGlvbnMpIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7Ci0gICAgICAgIHRoaXMuc2V0UGF0dGVybihyZWdleCwgb3B0aW9ucyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlcyBhIG5ldyBSZWd1bGFyRXhwcmVzc2lvbiBpbnN0YW5jZSB3aXRoIG9wdGlvbnMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcmVnZXggQSByZWd1bGFyIGV4cHJlc3Npb24KLSAgICAgKiBAcGFyYW0gb3B0aW9ucyBBIFN0cmluZyBjb25zaXN0ZWQgb2YgImkiICJtIiAicyIgInUiICJ3IiAiLCIgIlgiCi0gICAgICogQGV4Y2VwdGlvbiBvcmcuYXBhY2hlLnhlcmNlcy51dGlscy5yZWdleC5QYXJzZUV4Y2VwdGlvbiA8VkFSPnJlZ2V4PC9WQVI+IGlzIG5vdCBjb25mb3JtaW5nIHRvIHRoZSBzeW50YXguCi0gICAgICovCi0gICAgcHVibGljIFJlZ3VsYXJFeHByZXNzaW9uKFN0cmluZyByZWdleCwgU3RyaW5nIG9wdGlvbnMsIExvY2FsZSBsb2NhbGUpIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7Ci0gICAgICAgIHRoaXMuc2V0UGF0dGVybihyZWdleCwgb3B0aW9ucywgbG9jYWxlKTsKLSAgICB9Ci0KLSAgICBSZWd1bGFyRXhwcmVzc2lvbihTdHJpbmcgcmVnZXgsIFRva2VuIHRvaywgaW50IHBhcmVucywgYm9vbGVhbiBoYXNCYWNrUmVmZXJlbmNlcywgaW50IG9wdGlvbnMpIHsKLSAgICAgICAgdGhpcy5yZWdleCA9IHJlZ2V4OwotICAgICAgICB0aGlzLnRva2VudHJlZSA9IHRvazsKLSAgICAgICAgdGhpcy5ub2ZwYXJlbiA9IHBhcmVuczsKLSAgICAgICAgdGhpcy5vcHRpb25zID0gb3B0aW9uczsKLSAgICAgICAgdGhpcy5oYXNCYWNrUmVmZXJlbmNlcyA9IGhhc0JhY2tSZWZlcmVuY2VzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0UGF0dGVybihTdHJpbmcgbmV3UGF0dGVybikgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKLSAgICAgICAgdGhpcy5zZXRQYXR0ZXJuKG5ld1BhdHRlcm4sIExvY2FsZS5nZXREZWZhdWx0KCkpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldFBhdHRlcm4oU3RyaW5nIG5ld1BhdHRlcm4sIExvY2FsZSBsb2NhbGUpIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7Ci0gICAgICAgIHRoaXMuc2V0UGF0dGVybihuZXdQYXR0ZXJuLCB0aGlzLm9wdGlvbnMsIGxvY2FsZSk7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIHNldFBhdHRlcm4oU3RyaW5nIG5ld1BhdHRlcm4sIGludCBvcHRpb25zLCBMb2NhbGUgbG9jYWxlKSB0aHJvd3MgUGFyc2VFeGNlcHRpb24gewotICAgICAgICB0aGlzLnJlZ2V4ID0gbmV3UGF0dGVybjsKLSAgICAgICAgdGhpcy5vcHRpb25zID0gb3B0aW9uczsKLSAgICAgICAgUmVnZXhQYXJzZXIgcnAgPSBSZWd1bGFyRXhwcmVzc2lvbi5pc1NldCh0aGlzLm9wdGlvbnMsIFJlZ3VsYXJFeHByZXNzaW9uLlhNTFNDSEVNQV9NT0RFKQotICAgICAgICAgICAgICAgICAgICAgICAgID8gbmV3IFBhcnNlckZvclhNTFNjaGVtYShsb2NhbGUpIDogbmV3IFJlZ2V4UGFyc2VyKGxvY2FsZSk7Ci0gICAgICAgIHRoaXMudG9rZW50cmVlID0gcnAucGFyc2UodGhpcy5yZWdleCwgdGhpcy5vcHRpb25zKTsKLSAgICAgICAgdGhpcy5ub2ZwYXJlbiA9IHJwLnBhcmVubnVtYmVyOwotICAgICAgICB0aGlzLmhhc0JhY2tSZWZlcmVuY2VzID0gcnAuaGFzQmFja1JlZmVyZW5jZXM7Ci0KLSAgICAgICAgdGhpcy5vcGVyYXRpb25zID0gbnVsbDsKLSAgICAgICAgdGhpcy5jb250ZXh0ID0gbnVsbDsKLSAgICB9Ci0gICAgLyoqCi0gICAgICoKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRQYXR0ZXJuKFN0cmluZyBuZXdQYXR0ZXJuLCBTdHJpbmcgb3B0aW9ucykgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKLSAgICAgICAgdGhpcy5zZXRQYXR0ZXJuKG5ld1BhdHRlcm4sIG9wdGlvbnMsIExvY2FsZS5nZXREZWZhdWx0KCkpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldFBhdHRlcm4oU3RyaW5nIG5ld1BhdHRlcm4sIFN0cmluZyBvcHRpb25zLCBMb2NhbGUgbG9jYWxlKSB0aHJvd3MgUGFyc2VFeGNlcHRpb24gewotICAgICAgICB0aGlzLnNldFBhdHRlcm4obmV3UGF0dGVybiwgUkVVdGlsLnBhcnNlT3B0aW9ucyhvcHRpb25zKSwgbG9jYWxlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0UGF0dGVybigpIHsKLSAgICAgICAgcmV0dXJuIHRoaXMucmVnZXg7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmVwcmVzZW50cyB0aGlzIGluc3RlbmNlIGluIFN0cmluZy4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgICAgICByZXR1cm4gdGhpcy50b2tlbnRyZWUudG9TdHJpbmcodGhpcy5vcHRpb25zKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGEgb3B0aW9uIHN0cmluZy4KLSAgICAgKiBUaGUgb3JkZXIgb2YgbGV0dGVycyBpbiBpdCBtYXkgYmUgZGlmZmVyZW50IGZyb20gYSBzdHJpbmcgc3BlY2lmaWVkCi0gICAgICogaW4gYSBjb25zdHJ1Y3RvciBvciA8Y29kZT5zZXRQYXR0ZXJuKCk8L2NvZGU+LgotICAgICAqCi0gICAgICogQHNlZSAjUmVndWxhckV4cHJlc3Npb24oamF2YS5sYW5nLlN0cmluZyxqYXZhLmxhbmcuU3RyaW5nKQotICAgICAqIEBzZWUgI3NldFBhdHRlcm4oamF2YS5sYW5nLlN0cmluZyxqYXZhLmxhbmcuU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0T3B0aW9ucygpIHsKLSAgICAgICAgcmV0dXJuIFJFVXRpbC5jcmVhdGVPcHRpb25TdHJpbmcodGhpcy5vcHRpb25zKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiAgUmV0dXJuIHRydWUgaWYgcGF0dGVybnMgYXJlIHRoZSBzYW1lIGFuZCB0aGUgb3B0aW9ucyBhcmUgZXF1aXZhbGVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaikgewotICAgICAgICBpZiAob2JqID09IG51bGwpICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIFJlZ3VsYXJFeHByZXNzaW9uKSkKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgUmVndWxhckV4cHJlc3Npb24gciA9IChSZWd1bGFyRXhwcmVzc2lvbilvYmo7Ci0gICAgICAgIHJldHVybiB0aGlzLnJlZ2V4LmVxdWFscyhyLnJlZ2V4KSAmJiB0aGlzLm9wdGlvbnMgPT0gci5vcHRpb25zOwotICAgIH0KLQotICAgIGJvb2xlYW4gZXF1YWxzKFN0cmluZyBwYXR0ZXJuLCBpbnQgb3B0aW9ucykgewotICAgICAgICByZXR1cm4gdGhpcy5yZWdleC5lcXVhbHMocGF0dGVybikgJiYgdGhpcy5vcHRpb25zID09IG9wdGlvbnM7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICoKLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewotICAgICAgICByZXR1cm4gKHRoaXMucmVnZXgrIi8iK3RoaXMuZ2V0T3B0aW9ucygpKS5oYXNoQ29kZSgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybiB0aGUgbnVtYmVyIG9mIHJlZ3VsYXIgZXhwcmVzc2lvbiBncm91cHMuCi0gICAgICogVGhpcyBtZXRob2QgcmV0dXJucyAxIHdoZW4gdGhlIHJlZ3VsYXIgZXhwcmVzc2lvbiBoYXMgbm8gY2FwdHVyaW5nLXBhcmVudGhlc2lzLgotICAgICAqCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXROdW1iZXJPZkdyb3VwcygpIHsKLSAgICAgICAgcmV0dXJuIHRoaXMubm9mcGFyZW47Ci0gICAgfQotCi0gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFdUX0lHTk9SRSA9IDA7Ci0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFdUX0xFVFRFUiA9IDE7Ci0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFdUX09USEVSID0gMjsKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgZ2V0V29yZFR5cGUwKGNoYXIgY2gsIGludCBvcHRzKSB7Ci0gICAgICAgIGlmICghaXNTZXQob3B0cywgVU5JQ09ERV9XT1JEX0JPVU5EQVJZKSkgewotICAgICAgICAgICAgaWYgKGlzU2V0KG9wdHMsIFVTRV9VTklDT0RFX0NBVEVHT1JZKSkgewotICAgICAgICAgICAgICAgIHJldHVybiAoVG9rZW4uZ2V0UmFuZ2UoIklzV29yZCIsIHRydWUpLm1hdGNoKGNoKSkgPyBXVF9MRVRURVIgOiBXVF9PVEhFUjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiBpc1dvcmRDaGFyKGNoKSA/IFdUX0xFVFRFUiA6IFdUX09USEVSOwotICAgICAgICB9Ci0KLSAgICAgICAgc3dpdGNoIChDaGFyYWN0ZXIuZ2V0VHlwZShjaCkpIHsKLSAgICAgICAgY2FzZSBDaGFyYWN0ZXIuVVBQRVJDQVNFX0xFVFRFUjogICAgICAvLyBMCi0gICAgICAgIGNhc2UgQ2hhcmFjdGVyLkxPV0VSQ0FTRV9MRVRURVI6ICAgICAgLy8gTAotICAgICAgICBjYXNlIENoYXJhY3Rlci5USVRMRUNBU0VfTEVUVEVSOiAgICAgIC8vIEwKLSAgICAgICAgY2FzZSBDaGFyYWN0ZXIuTU9ESUZJRVJfTEVUVEVSOiAgICAgICAvLyBMCi0gICAgICAgIGNhc2UgQ2hhcmFjdGVyLk9USEVSX0xFVFRFUjogICAgICAgICAgLy8gTAotICAgICAgICBjYXNlIENoYXJhY3Rlci5MRVRURVJfTlVNQkVSOiAgICAgICAgIC8vIE4KLSAgICAgICAgY2FzZSBDaGFyYWN0ZXIuREVDSU1BTF9ESUdJVF9OVU1CRVI6ICAvLyBOCi0gICAgICAgIGNhc2UgQ2hhcmFjdGVyLk9USEVSX05VTUJFUjogICAgICAgICAgLy8gTgotICAgICAgICBjYXNlIENoYXJhY3Rlci5DT01CSU5JTkdfU1BBQ0lOR19NQVJLOiAvLyBNYwotICAgICAgICAgICAgcmV0dXJuIFdUX0xFVFRFUjsKLQotICAgICAgICBjYXNlIENoYXJhY3Rlci5GT1JNQVQ6ICAgICAgICAgICAgICAgIC8vIENmCi0gICAgICAgIGNhc2UgQ2hhcmFjdGVyLk5PTl9TUEFDSU5HX01BUks6ICAgICAgLy8gTW4KLSAgICAgICAgY2FzZSBDaGFyYWN0ZXIuRU5DTE9TSU5HX01BUks6ICAgICAgICAvLyBNYwotICAgICAgICAgICAgcmV0dXJuIFdUX0lHTk9SRTsKLQotICAgICAgICBjYXNlIENoYXJhY3Rlci5DT05UUk9MOiAgICAgICAgICAgICAgIC8vIENjCi0gICAgICAgICAgICBzd2l0Y2ggKGNoKSB7Ci0gICAgICAgICAgICBjYXNlICdcdCc6Ci0gICAgICAgICAgICBjYXNlICdcbic6Ci0gICAgICAgICAgICBjYXNlICdcdTAwMEInOgotICAgICAgICAgICAgY2FzZSAnXGYnOgotICAgICAgICAgICAgY2FzZSAnXHInOgotICAgICAgICAgICAgICAgIHJldHVybiBXVF9PVEhFUjsKLSAgICAgICAgICAgIGRlZmF1bHQ6Ci0gICAgICAgICAgICAgICAgcmV0dXJuIFdUX0lHTk9SRTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICBkZWZhdWx0OgotICAgICAgICAgICAgcmV0dXJuIFdUX09USEVSOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotCi0gICAgc3RhdGljIGZpbmFsIGludCBMSU5FX0ZFRUQgPSAweDAwMEE7Ci0gICAgc3RhdGljIGZpbmFsIGludCBDQVJSSUFHRV9SRVRVUk4gPSAweDAwMEQ7Ci0gICAgc3RhdGljIGZpbmFsIGludCBMSU5FX1NFUEFSQVRPUiA9IDB4MjAyODsKLSAgICBzdGF0aWMgZmluYWwgaW50IFBBUkFHUkFQSF9TRVBBUkFUT1IgPSAweDIwMjk7Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIGlzRU9MQ2hhcihpbnQgY2gpIHsKLSAgICAgICAgcmV0dXJuIGNoID09IExJTkVfRkVFRCB8fCBjaCA9PSBDQVJSSUFHRV9SRVRVUk4gfHwgY2ggPT0gTElORV9TRVBBUkFUT1IKLSAgICAgICAgfHwgY2ggPT0gUEFSQUdSQVBIX1NFUEFSQVRPUjsKLSAgICB9Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIGlzV29yZENoYXIoaW50IGNoKSB7IC8vIExlZ2FjeSB3b3JkIGNoYXJhY3RlcnMKLSAgICAgICAgaWYgKGNoID09ICdfJykgIHJldHVybiB0cnVlOwotICAgICAgICBpZiAoY2ggPCAnMCcpICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIGlmIChjaCA+ICd6JykgIHJldHVybiBmYWxzZTsKLSAgICAgICAgaWYgKGNoIDw9ICc5JykgIHJldHVybiB0cnVlOwotICAgICAgICBpZiAoY2ggPCAnQScpICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIGlmIChjaCA8PSAnWicpICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgaWYgKGNoIDwgJ2EnKSAgcmV0dXJuIGZhbHNlOwotICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIG1hdGNoSWdub3JlQ2FzZShpbnQgY2hhcmRhdGEsIGludCBjaCkgewotICAgICAgICBpZiAoY2hhcmRhdGEgPT0gY2gpICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgaWYgKGNoYXJkYXRhID4gMHhmZmZmIHx8IGNoID4gMHhmZmZmKSAgcmV0dXJuIGZhbHNlOwotICAgICAgICBjaGFyIHVjaDEgPSBDaGFyYWN0ZXIudG9VcHBlckNhc2UoKGNoYXIpY2hhcmRhdGEpOwotICAgICAgICBjaGFyIHVjaDIgPSBDaGFyYWN0ZXIudG9VcHBlckNhc2UoKGNoYXIpY2gpOwotICAgICAgICBpZiAodWNoMSA9PSB1Y2gyKSAgcmV0dXJuIHRydWU7Ci0gICAgICAgIHJldHVybiBDaGFyYWN0ZXIudG9Mb3dlckNhc2UodWNoMSkgPT0gQ2hhcmFjdGVyLnRvTG93ZXJDYXNlKHVjaDIpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHBhdGgvcmVnZXgvVG9rZW4uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHBhdGgvcmVnZXgvVG9rZW4uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZTM2NDk5NS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hwYXRoL3JlZ2V4L1Rva2VuLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNTc0ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKi8KLS8qCi0gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKLSAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAotICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgotICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKLSAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCi0gKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHBhdGgucmVnZXg7Ci0KLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotaW1wb3J0IGphdmEuaW8uT2JqZWN0SW5wdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5pby5PYmplY3RPdXRwdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5pby5PYmplY3RTdHJlYW1GaWVsZDsKLWltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwotaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaFNldDsKLWltcG9ydCBqYXZhLnV0aWwuTGlzdDsKLWltcG9ydCBqYXZhLnV0aWwuTWFwOwotaW1wb3J0IGphdmEudXRpbC5TZXQ7Ci1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIHJlcHJlc2VudHMgYSBub2RlIGluIHBhcnNlIHRyZWUuCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEB2ZXJzaW9uICRJZDogVG9rZW4uamF2YSx2IDEuNyAyMDEwLzA3LzI3IDA1OjAyOjM0IGpvZWh3IEV4cCAkCi0gKi8KLWNsYXNzIFRva2VuIGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUgewotCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gODQ4NDk3NjAwMjU4NTQ4NzQ4MUw7Ci0KLSAgICBzdGF0aWMgZmluYWwgYm9vbGVhbiBDT1VOVFRPS0VOUyA9IHRydWU7Ci0gICAgc3RhdGljIGludCB0b2tlbnMgPSAwOwotCi0gICAgc3RhdGljIGZpbmFsIGludCBDSEFSID0gMDsgICAgICAgICAgICAgICAgICAvLyBMaXRlcmFsIGNoYXIKLSAgICBzdGF0aWMgZmluYWwgaW50IERPVCA9IDExOyAgICAgICAgICAgICAgICAgIC8vIC4KLSAgICBzdGF0aWMgZmluYWwgaW50IENPTkNBVCA9IDE7ICAgICAgICAgICAgICAgIC8vIFhZCi0gICAgc3RhdGljIGZpbmFsIGludCBVTklPTiA9IDI7ICAgICAgICAgICAgICAgICAvLyBYfFl8WgotICAgIHN0YXRpYyBmaW5hbCBpbnQgQ0xPU1VSRSA9IDM7ICAgICAgICAgICAgICAgLy8gWCoKLSAgICBzdGF0aWMgZmluYWwgaW50IFJBTkdFID0gNDsgICAgICAgICAgICAgICAgIC8vIFthLXpBLVpdIGV0Yy4KLSAgICBzdGF0aWMgZmluYWwgaW50IE5SQU5HRSA9IDU7ICAgICAgICAgICAgICAgIC8vIFteYS16QS1aXSBldGMuCi0gICAgc3RhdGljIGZpbmFsIGludCBQQVJFTiA9IDY7ICAgICAgICAgICAgICAgICAvLyAoWCkgb3IgKD86WCkKLSAgICBzdGF0aWMgZmluYWwgaW50IEVNUFRZID0gNzsgICAgICAgICAgICAgICAgIC8vCi0gICAgc3RhdGljIGZpbmFsIGludCBBTkNIT1IgPSA4OyAgICAgICAgICAgICAgICAvLyBeICQgXGIgXEIgXDwgXD4gXEEgXFogXHoKLSAgICBzdGF0aWMgZmluYWwgaW50IE5PTkdSRUVEWUNMT1NVUkUgPSA5OyAgICAgIC8vICo/ICs/Ci0gICAgc3RhdGljIGZpbmFsIGludCBTVFJJTkcgPSAxMDsgICAgICAgICAgICAgICAvLyBzdHJpbmdzCi0gICAgc3RhdGljIGZpbmFsIGludCBCQUNLUkVGRVJFTkNFID0gMTI7ICAgICAgICAvLyBiYWNrIHJlZmVyZW5jZXMKLSAgICBzdGF0aWMgZmluYWwgaW50IExPT0tBSEVBRCA9IDIwOyAgICAgICAgICAgIC8vICg/PS4uLikKLSAgICBzdGF0aWMgZmluYWwgaW50IE5FR0FUSVZFTE9PS0FIRUFEID0gMjE7ICAgIC8vICg/IS4uLikKLSAgICBzdGF0aWMgZmluYWwgaW50IExPT0tCRUhJTkQgPSAyMjsgICAgICAgICAgIC8vICg/PD0uLi4pCi0gICAgc3RhdGljIGZpbmFsIGludCBORUdBVElWRUxPT0tCRUhJTkQgPSAyMzsgICAvLyAoPzwhLi4uKQotICAgIHN0YXRpYyBmaW5hbCBpbnQgSU5ERVBFTkRFTlQgPSAyNDsgICAgICAgICAgLy8gKD8+Li4uKQotICAgIHN0YXRpYyBmaW5hbCBpbnQgTU9ESUZJRVJHUk9VUCA9IDI1OyAgICAgICAgLy8gKD9pbXMtaW1zOi4uLikKLSAgICBzdGF0aWMgZmluYWwgaW50IENPTkRJVElPTiA9IDI2OyAgICAgICAgICAgIC8vICg/KC4uLil5ZXN8bm8pCi0KLSAgICBzdGF0aWMgZmluYWwgaW50IFVURjE2X01BWCA9IDB4MTBmZmZmOwotCi0gICAgZmluYWwgaW50IHR5cGU7Ci0KLSAgICBzdGF0aWMgVG9rZW4gdG9rZW5fZG90OwotICAgIHN0YXRpYyBUb2tlbiB0b2tlbl8wdG85OwotICAgIHN0YXRpYyBUb2tlbiB0b2tlbl93b3JkY2hhcnM7Ci0gICAgc3RhdGljIFRva2VuIHRva2VuX25vdF8wdG85OwotICAgIHN0YXRpYyBUb2tlbiB0b2tlbl9ub3Rfd29yZGNoYXJzOwotICAgIHN0YXRpYyBUb2tlbiB0b2tlbl9zcGFjZXM7Ci0gICAgc3RhdGljIFRva2VuIHRva2VuX25vdF9zcGFjZXM7Ci0gICAgc3RhdGljIFRva2VuIHRva2VuX2VtcHR5OwotICAgIHN0YXRpYyBUb2tlbiB0b2tlbl9saW5lYmVnaW5uaW5nOwotICAgIHN0YXRpYyBUb2tlbiB0b2tlbl9saW5lYmVnaW5uaW5nMjsKLSAgICBzdGF0aWMgVG9rZW4gdG9rZW5fbGluZWVuZDsKLSAgICBzdGF0aWMgVG9rZW4gdG9rZW5fc3RyaW5nYmVnaW5uaW5nOwotICAgIHN0YXRpYyBUb2tlbiB0b2tlbl9zdHJpbmdlbmQ7Ci0gICAgc3RhdGljIFRva2VuIHRva2VuX3N0cmluZ2VuZDI7Ci0gICAgc3RhdGljIFRva2VuIHRva2VuX3dvcmRlZGdlOwotICAgIHN0YXRpYyBUb2tlbiB0b2tlbl9ub3Rfd29yZGVkZ2U7Ci0gICAgc3RhdGljIFRva2VuIHRva2VuX3dvcmRiZWdpbm5pbmc7Ci0gICAgc3RhdGljIFRva2VuIHRva2VuX3dvcmRlbmQ7Ci0gICAgc3RhdGljIHsKLSAgICAgICAgVG9rZW4udG9rZW5fZW1wdHkgPSBuZXcgVG9rZW4oVG9rZW4uRU1QVFkpOwotCi0gICAgICAgIFRva2VuLnRva2VuX2xpbmViZWdpbm5pbmcgPSBUb2tlbi5jcmVhdGVBbmNob3IoJ14nKTsKLSAgICAgICAgVG9rZW4udG9rZW5fbGluZWJlZ2lubmluZzIgPSBUb2tlbi5jcmVhdGVBbmNob3IoJ0AnKTsKLSAgICAgICAgVG9rZW4udG9rZW5fbGluZWVuZCA9IFRva2VuLmNyZWF0ZUFuY2hvcignJCcpOwotICAgICAgICBUb2tlbi50b2tlbl9zdHJpbmdiZWdpbm5pbmcgPSBUb2tlbi5jcmVhdGVBbmNob3IoJ0EnKTsKLSAgICAgICAgVG9rZW4udG9rZW5fc3RyaW5nZW5kID0gVG9rZW4uY3JlYXRlQW5jaG9yKCd6Jyk7Ci0gICAgICAgIFRva2VuLnRva2VuX3N0cmluZ2VuZDIgPSBUb2tlbi5jcmVhdGVBbmNob3IoJ1onKTsKLSAgICAgICAgVG9rZW4udG9rZW5fd29yZGVkZ2UgPSBUb2tlbi5jcmVhdGVBbmNob3IoJ2InKTsKLSAgICAgICAgVG9rZW4udG9rZW5fbm90X3dvcmRlZGdlID0gVG9rZW4uY3JlYXRlQW5jaG9yKCdCJyk7Ci0gICAgICAgIFRva2VuLnRva2VuX3dvcmRiZWdpbm5pbmcgPSBUb2tlbi5jcmVhdGVBbmNob3IoJzwnKTsKLSAgICAgICAgVG9rZW4udG9rZW5fd29yZGVuZCA9IFRva2VuLmNyZWF0ZUFuY2hvcignPicpOwotCi0gICAgICAgIFRva2VuLnRva2VuX2RvdCA9IG5ldyBUb2tlbihUb2tlbi5ET1QpOwotCi0gICAgICAgIFRva2VuLnRva2VuXzB0bzkgPSBUb2tlbi5jcmVhdGVSYW5nZSgpOwotICAgICAgICBUb2tlbi50b2tlbl8wdG85LmFkZFJhbmdlKCcwJywgJzknKTsKLSAgICAgICAgVG9rZW4udG9rZW5fd29yZGNoYXJzID0gVG9rZW4uY3JlYXRlUmFuZ2UoKTsKLSAgICAgICAgVG9rZW4udG9rZW5fd29yZGNoYXJzLmFkZFJhbmdlKCcwJywgJzknKTsKLSAgICAgICAgVG9rZW4udG9rZW5fd29yZGNoYXJzLmFkZFJhbmdlKCdBJywgJ1onKTsKLSAgICAgICAgVG9rZW4udG9rZW5fd29yZGNoYXJzLmFkZFJhbmdlKCdfJywgJ18nKTsKLSAgICAgICAgVG9rZW4udG9rZW5fd29yZGNoYXJzLmFkZFJhbmdlKCdhJywgJ3onKTsKLSAgICAgICAgVG9rZW4udG9rZW5fc3BhY2VzID0gVG9rZW4uY3JlYXRlUmFuZ2UoKTsKLSAgICAgICAgVG9rZW4udG9rZW5fc3BhY2VzLmFkZFJhbmdlKCdcdCcsICdcdCcpOwotICAgICAgICBUb2tlbi50b2tlbl9zcGFjZXMuYWRkUmFuZ2UoJ1xuJywgJ1xuJyk7Ci0gICAgICAgIFRva2VuLnRva2VuX3NwYWNlcy5hZGRSYW5nZSgnXGYnLCAnXGYnKTsKLSAgICAgICAgVG9rZW4udG9rZW5fc3BhY2VzLmFkZFJhbmdlKCdccicsICdccicpOwotICAgICAgICBUb2tlbi50b2tlbl9zcGFjZXMuYWRkUmFuZ2UoJyAnLCAnICcpOwotCi0gICAgICAgIFRva2VuLnRva2VuX25vdF8wdG85ID0gVG9rZW4uY29tcGxlbWVudFJhbmdlcyhUb2tlbi50b2tlbl8wdG85KTsKLSAgICAgICAgVG9rZW4udG9rZW5fbm90X3dvcmRjaGFycyA9IFRva2VuLmNvbXBsZW1lbnRSYW5nZXMoVG9rZW4udG9rZW5fd29yZGNoYXJzKTsKLSAgICAgICAgVG9rZW4udG9rZW5fbm90X3NwYWNlcyA9IFRva2VuLmNvbXBsZW1lbnRSYW5nZXMoVG9rZW4udG9rZW5fc3BhY2VzKTsKLSAgICB9Ci0KLSAgICBzdGF0aWMgVG9rZW4uUGFyZW5Ub2tlbiBjcmVhdGVMb29rKGludCB0eXBlLCBUb2tlbiBjaGlsZCkgewotICAgICAgICBpZiAoQ09VTlRUT0tFTlMpICBUb2tlbi50b2tlbnMgKys7Ci0gICAgICAgIHJldHVybiBuZXcgVG9rZW4uUGFyZW5Ub2tlbih0eXBlLCBjaGlsZCwgMCk7Ci0gICAgfQotICAgIHN0YXRpYyBUb2tlbi5QYXJlblRva2VuIGNyZWF0ZVBhcmVuKFRva2VuIGNoaWxkLCBpbnQgcG51bWJlcikgewotICAgICAgICBpZiAoQ09VTlRUT0tFTlMpICBUb2tlbi50b2tlbnMgKys7Ci0gICAgICAgIHJldHVybiBuZXcgVG9rZW4uUGFyZW5Ub2tlbihUb2tlbi5QQVJFTiwgY2hpbGQsIHBudW1iZXIpOwotICAgIH0KLSAgICBzdGF0aWMgVG9rZW4uQ2xvc3VyZVRva2VuIGNyZWF0ZUNsb3N1cmUoVG9rZW4gdG9rKSB7Ci0gICAgICAgIGlmIChDT1VOVFRPS0VOUykgIFRva2VuLnRva2VucyArKzsKLSAgICAgICAgcmV0dXJuIG5ldyBUb2tlbi5DbG9zdXJlVG9rZW4oVG9rZW4uQ0xPU1VSRSwgdG9rKTsKLSAgICB9Ci0gICAgc3RhdGljIFRva2VuLkNsb3N1cmVUb2tlbiBjcmVhdGVOR0Nsb3N1cmUoVG9rZW4gdG9rKSB7Ci0gICAgICAgIGlmIChDT1VOVFRPS0VOUykgIFRva2VuLnRva2VucyArKzsKLSAgICAgICAgcmV0dXJuIG5ldyBUb2tlbi5DbG9zdXJlVG9rZW4oVG9rZW4uTk9OR1JFRURZQ0xPU1VSRSwgdG9rKTsKLSAgICB9Ci0gICAgc3RhdGljIFRva2VuLkNvbmNhdFRva2VuIGNyZWF0ZUNvbmNhdChUb2tlbiB0b2sxLCBUb2tlbiB0b2syKSB7Ci0gICAgICAgIGlmIChDT1VOVFRPS0VOUykgIFRva2VuLnRva2VucyArKzsKLSAgICAgICAgcmV0dXJuIG5ldyBUb2tlbi5Db25jYXRUb2tlbih0b2sxLCB0b2syKTsKLSAgICB9Ci0gICAgc3RhdGljIFRva2VuLlVuaW9uVG9rZW4gY3JlYXRlQ29uY2F0KCkgewotICAgICAgICBpZiAoQ09VTlRUT0tFTlMpICBUb2tlbi50b2tlbnMgKys7Ci0gICAgICAgIHJldHVybiBuZXcgVG9rZW4uVW5pb25Ub2tlbihUb2tlbi5DT05DQVQpOyAvLyAqKiogSXQgaXMgbm90IGEgYnVnLgotICAgIH0KLSAgICBzdGF0aWMgVG9rZW4uVW5pb25Ub2tlbiBjcmVhdGVVbmlvbigpIHsKLSAgICAgICAgaWYgKENPVU5UVE9LRU5TKSAgVG9rZW4udG9rZW5zICsrOwotICAgICAgICByZXR1cm4gbmV3IFRva2VuLlVuaW9uVG9rZW4oVG9rZW4uVU5JT04pOwotICAgIH0KLSAgICBzdGF0aWMgVG9rZW4gY3JlYXRlRW1wdHkoKSB7Ci0gICAgICAgIHJldHVybiBUb2tlbi50b2tlbl9lbXB0eTsKLSAgICB9Ci0gICAgc3RhdGljIFJhbmdlVG9rZW4gY3JlYXRlUmFuZ2UoKSB7Ci0gICAgICAgIGlmIChDT1VOVFRPS0VOUykgIFRva2VuLnRva2VucyArKzsKLSAgICAgICAgcmV0dXJuIG5ldyBSYW5nZVRva2VuKFRva2VuLlJBTkdFKTsKLSAgICB9Ci0gICAgc3RhdGljIFJhbmdlVG9rZW4gY3JlYXRlTlJhbmdlKCkgewotICAgICAgICBpZiAoQ09VTlRUT0tFTlMpICBUb2tlbi50b2tlbnMgKys7Ci0gICAgICAgIHJldHVybiBuZXcgUmFuZ2VUb2tlbihUb2tlbi5OUkFOR0UpOwotICAgIH0KLSAgICBzdGF0aWMgVG9rZW4uQ2hhclRva2VuIGNyZWF0ZUNoYXIoaW50IGNoKSB7Ci0gICAgICAgIGlmIChDT1VOVFRPS0VOUykgIFRva2VuLnRva2VucyArKzsKLSAgICAgICAgcmV0dXJuIG5ldyBUb2tlbi5DaGFyVG9rZW4oVG9rZW4uQ0hBUiwgY2gpOwotICAgIH0KLSAgICBzdGF0aWMgcHJpdmF0ZSBUb2tlbi5DaGFyVG9rZW4gY3JlYXRlQW5jaG9yKGludCBjaCkgewotICAgICAgICBpZiAoQ09VTlRUT0tFTlMpICBUb2tlbi50b2tlbnMgKys7Ci0gICAgICAgIHJldHVybiBuZXcgVG9rZW4uQ2hhclRva2VuKFRva2VuLkFOQ0hPUiwgY2gpOwotICAgIH0KLSAgICBzdGF0aWMgVG9rZW4uU3RyaW5nVG9rZW4gY3JlYXRlQmFja1JlZmVyZW5jZShpbnQgcmVmbm8pIHsKLSAgICAgICAgaWYgKENPVU5UVE9LRU5TKSAgVG9rZW4udG9rZW5zICsrOwotICAgICAgICByZXR1cm4gbmV3IFRva2VuLlN0cmluZ1Rva2VuKFRva2VuLkJBQ0tSRUZFUkVOQ0UsIG51bGwsIHJlZm5vKTsKLSAgICB9Ci0gICAgc3RhdGljIFRva2VuLlN0cmluZ1Rva2VuIGNyZWF0ZVN0cmluZyhTdHJpbmcgc3RyKSB7Ci0gICAgICAgIGlmIChDT1VOVFRPS0VOUykgIFRva2VuLnRva2VucyArKzsKLSAgICAgICAgcmV0dXJuIG5ldyBUb2tlbi5TdHJpbmdUb2tlbihUb2tlbi5TVFJJTkcsIHN0ciwgMCk7Ci0gICAgfQotICAgIHN0YXRpYyBUb2tlbi5Nb2RpZmllclRva2VuIGNyZWF0ZU1vZGlmaWVyR3JvdXAoVG9rZW4gY2hpbGQsIGludCBhZGQsIGludCBtYXNrKSB7Ci0gICAgICAgIGlmIChDT1VOVFRPS0VOUykgIFRva2VuLnRva2VucyArKzsKLSAgICAgICAgcmV0dXJuIG5ldyBUb2tlbi5Nb2RpZmllclRva2VuKGNoaWxkLCBhZGQsIG1hc2spOwotICAgIH0KLSAgICBzdGF0aWMgVG9rZW4uQ29uZGl0aW9uVG9rZW4gY3JlYXRlQ29uZGl0aW9uKGludCByZWZubywgVG9rZW4gY29uZGl0aW9uLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVG9rZW4geWVzcGF0LCBUb2tlbiBub3BhdCkgewotICAgICAgICBpZiAoQ09VTlRUT0tFTlMpICBUb2tlbi50b2tlbnMgKys7Ci0gICAgICAgIHJldHVybiBuZXcgVG9rZW4uQ29uZGl0aW9uVG9rZW4ocmVmbm8sIGNvbmRpdGlvbiwgeWVzcGF0LCBub3BhdCk7Ci0gICAgfQotCi0gICAgcHJvdGVjdGVkIFRva2VuKGludCB0eXBlKSB7Ci0gICAgICAgIHRoaXMudHlwZSA9IHR5cGU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQSBudW1iZXIgb2YgY2hpbGRyZW4uCi0gICAgICovCi0gICAgaW50IHNpemUoKSB7Ci0gICAgICAgIHJldHVybiAwOwotICAgIH0KLSAgICBUb2tlbiBnZXRDaGlsZChpbnQgaW5kZXgpIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotICAgIHZvaWQgYWRkQ2hpbGQoVG9rZW4gdG9rKSB7Ci0gICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJOb3Qgc3VwcG9ydGVkLiIpOwotICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZm9yIFJBTkdFIG9yIE5SQU5HRQotICAgIHByb3RlY3RlZCB2b2lkIGFkZFJhbmdlKGludCBzdGFydCwgaW50IGVuZCkgewotICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiTm90IHN1cHBvcnRlZC4iKTsKLSAgICB9Ci0gICAgcHJvdGVjdGVkIHZvaWQgc29ydFJhbmdlcygpIHsKLSAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIk5vdCBzdXBwb3J0ZWQuIik7Ci0gICAgfQotICAgIHByb3RlY3RlZCB2b2lkIGNvbXBhY3RSYW5nZXMoKSB7Ci0gICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJOb3Qgc3VwcG9ydGVkLiIpOwotICAgIH0KLSAgICBwcm90ZWN0ZWQgdm9pZCBtZXJnZVJhbmdlcyhUb2tlbiB0b2spIHsKLSAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIk5vdCBzdXBwb3J0ZWQuIik7Ci0gICAgfQotICAgIHByb3RlY3RlZCB2b2lkIHN1YnRyYWN0UmFuZ2VzKFRva2VuIHRvaykgewotICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiTm90IHN1cHBvcnRlZC4iKTsKLSAgICB9Ci0gICAgcHJvdGVjdGVkIHZvaWQgaW50ZXJzZWN0UmFuZ2VzKFRva2VuIHRvaykgewotICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiTm90IHN1cHBvcnRlZC4iKTsKLSAgICB9Ci0gICAgc3RhdGljIFRva2VuIGNvbXBsZW1lbnRSYW5nZXMoVG9rZW4gdG9rKSB7Ci0gICAgICAgIHJldHVybiBSYW5nZVRva2VuLmNvbXBsZW1lbnRSYW5nZXModG9rKTsKLSAgICB9Ci0KLQotICAgIHZvaWQgc2V0TWluKGludCBtaW4pIHsgICAgICAgICAgICAgICAgICAgICAgLy8gZm9yIENMT1NVUkUKLSAgICB9Ci0gICAgdm9pZCBzZXRNYXgoaW50IG1heCkgeyAgICAgICAgICAgICAgICAgICAgICAvLyBmb3IgQ0xPU1VSRQotICAgIH0KLSAgICBpbnQgZ2V0TWluKCkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZvciBDTE9TVVJFCi0gICAgICAgIHJldHVybiAtMTsKLSAgICB9Ci0gICAgaW50IGdldE1heCgpIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBmb3IgQ0xPU1VSRQotICAgICAgICByZXR1cm4gLTE7Ci0gICAgfQotICAgIGludCBnZXRSZWZlcmVuY2VOdW1iZXIoKSB7ICAgICAgICAgICAgICAgICAgLy8gZm9yIFNUUklORwotICAgICAgICByZXR1cm4gMDsKLSAgICB9Ci0gICAgU3RyaW5nIGdldFN0cmluZygpIHsgICAgICAgICAgICAgICAgICAgICAgICAvLyBmb3IgU1RSSU5HCi0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIGludCBnZXRQYXJlbk51bWJlcigpIHsKLSAgICAgICAgcmV0dXJuIDA7Ci0gICAgfQotICAgIGludCBnZXRDaGFyKCkgewotICAgICAgICByZXR1cm4gLTE7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKLSAgICAgICAgcmV0dXJuIHRoaXMudG9TdHJpbmcoMCk7Ci0gICAgfQotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoaW50IG9wdGlvbnMpIHsKLSAgICAgICAgcmV0dXJuIHRoaXMudHlwZSA9PSBUb2tlbi5ET1QgPyAiLiIgOiAiIjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBIb3cgbWFueSBjaGFyYWN0ZXJzIGFyZSBuZWVkZWQ/Ci0gICAgICovCi0gICAgZmluYWwgaW50IGdldE1pbkxlbmd0aCgpIHsKLSAgICAgICAgc3dpdGNoICh0aGlzLnR5cGUpIHsKLSAgICAgICAgICBjYXNlIENPTkNBVDoKLSAgICAgICAgICAgIGludCBzdW0gPSAwOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7ICBpIDwgdGhpcy5zaXplKCk7ICBpICsrKQotICAgICAgICAgICAgICAgIHN1bSArPSB0aGlzLmdldENoaWxkKGkpLmdldE1pbkxlbmd0aCgpOwotICAgICAgICAgICAgcmV0dXJuIHN1bTsKLQotICAgICAgICAgIGNhc2UgQ09ORElUSU9OOgotICAgICAgICAgIGNhc2UgVU5JT046Ci0gICAgICAgICAgICBpZiAodGhpcy5zaXplKCkgPT0gMCkKLSAgICAgICAgICAgICAgICByZXR1cm4gMDsKLSAgICAgICAgICAgIGludCByZXQgPSB0aGlzLmdldENoaWxkKDApLmdldE1pbkxlbmd0aCgpOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDE7ICBpIDwgdGhpcy5zaXplKCk7ICBpICsrKSB7Ci0gICAgICAgICAgICAgICAgaW50IG1pbiA9IHRoaXMuZ2V0Q2hpbGQoaSkuZ2V0TWluTGVuZ3RoKCk7Ci0gICAgICAgICAgICAgICAgaWYgKG1pbiA8IHJldCkgIHJldCA9IG1pbjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiByZXQ7Ci0KLSAgICAgICAgICBjYXNlIENMT1NVUkU6Ci0gICAgICAgICAgY2FzZSBOT05HUkVFRFlDTE9TVVJFOgotICAgICAgICAgICAgaWYgKHRoaXMuZ2V0TWluKCkgPj0gMCkKLSAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRNaW4oKSAqIHRoaXMuZ2V0Q2hpbGQoMCkuZ2V0TWluTGVuZ3RoKCk7Ci0gICAgICAgICAgICByZXR1cm4gMDsKLQotICAgICAgICAgIGNhc2UgRU1QVFk6Ci0gICAgICAgICAgY2FzZSBBTkNIT1I6Ci0gICAgICAgICAgICByZXR1cm4gMDsKLQotICAgICAgICAgIGNhc2UgRE9UOgotICAgICAgICAgIGNhc2UgQ0hBUjoKLSAgICAgICAgICBjYXNlIFJBTkdFOgotICAgICAgICAgIGNhc2UgTlJBTkdFOgotICAgICAgICAgICAgcmV0dXJuIDE7Ci0KLSAgICAgICAgICBjYXNlIElOREVQRU5ERU5UOgotICAgICAgICAgIGNhc2UgUEFSRU46Ci0gICAgICAgICAgY2FzZSBNT0RJRklFUkdST1VQOgotICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0Q2hpbGQoMCkuZ2V0TWluTGVuZ3RoKCk7Ci0KLSAgICAgICAgICBjYXNlIEJBQ0tSRUZFUkVOQ0U6Ci0gICAgICAgICAgICByZXR1cm4gMDsgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAqKioqKioqCi0KLSAgICAgICAgICBjYXNlIFNUUklORzoKLSAgICAgICAgICAgIHJldHVybiB0aGlzLmdldFN0cmluZygpLmxlbmd0aCgpOwotCi0gICAgICAgICAgY2FzZSBMT09LQUhFQUQ6Ci0gICAgICAgICAgY2FzZSBORUdBVElWRUxPT0tBSEVBRDoKLSAgICAgICAgICBjYXNlIExPT0tCRUhJTkQ6Ci0gICAgICAgICAgY2FzZSBORUdBVElWRUxPT0tCRUhJTkQ6Ci0gICAgICAgICAgICByZXR1cm4gMDsgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAqKioqKiBSZWFsbHk/Ci0KLSAgICAgICAgICBkZWZhdWx0OgotICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlRva2VuI2dldE1pbkxlbmd0aCgpOiBJbnZhbGlkIFR5cGU6ICIrdGhpcy50eXBlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIGZpbmFsIGludCBnZXRNYXhMZW5ndGgoKSB7Ci0gICAgICAgIHN3aXRjaCAodGhpcy50eXBlKSB7Ci0gICAgICAgICAgY2FzZSBDT05DQVQ6Ci0gICAgICAgICAgICBpbnQgc3VtID0gMDsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyAgaSA8IHRoaXMuc2l6ZSgpOyAgaSArKykgewotICAgICAgICAgICAgICAgIGludCBkID0gdGhpcy5nZXRDaGlsZChpKS5nZXRNYXhMZW5ndGgoKTsKLSAgICAgICAgICAgICAgICBpZiAoZCA8IDApICByZXR1cm4gLTE7Ci0gICAgICAgICAgICAgICAgc3VtICs9IGQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gc3VtOwotCi0gICAgICAgICAgY2FzZSBDT05ESVRJT046Ci0gICAgICAgICAgY2FzZSBVTklPTjoKLSAgICAgICAgICAgIGlmICh0aGlzLnNpemUoKSA9PSAwKQotICAgICAgICAgICAgICAgIHJldHVybiAwOwotICAgICAgICAgICAgaW50IHJldCA9IHRoaXMuZ2V0Q2hpbGQoMCkuZ2V0TWF4TGVuZ3RoKCk7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMTsgIHJldCA+PSAwICYmIGkgPCB0aGlzLnNpemUoKTsgIGkgKyspIHsKLSAgICAgICAgICAgICAgICBpbnQgbWF4ID0gdGhpcy5nZXRDaGlsZChpKS5nZXRNYXhMZW5ndGgoKTsKLSAgICAgICAgICAgICAgICBpZiAobWF4IDwgMCkgeyAgICAgICAgICAgICAgICAgIC8vIGluZmluaXR5Ci0gICAgICAgICAgICAgICAgICAgIHJldCA9IC0xOwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaWYgKG1heCA+IHJldCkgIHJldCA9IG1heDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiByZXQ7Ci0KLSAgICAgICAgICBjYXNlIENMT1NVUkU6Ci0gICAgICAgICAgY2FzZSBOT05HUkVFRFlDTE9TVVJFOgotICAgICAgICAgICAgaWYgKHRoaXMuZ2V0TWF4KCkgPj0gMCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdoZW4gdGhpcy5jaGlsZC5nZXRNYXhMZW5ndGgoKSA8IDAsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGlzIHJldHVybnMgbWludXMgdmFsdWUKLSAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRNYXgoKSAqIHRoaXMuZ2V0Q2hpbGQoMCkuZ2V0TWF4TGVuZ3RoKCk7Ci0gICAgICAgICAgICByZXR1cm4gLTE7Ci0KLSAgICAgICAgICBjYXNlIEVNUFRZOgotICAgICAgICAgIGNhc2UgQU5DSE9SOgotICAgICAgICAgICAgcmV0dXJuIDA7Ci0KLSAgICAgICAgICBjYXNlIENIQVI6Ci0gICAgICAgICAgICByZXR1cm4gMTsKLSAgICAgICAgICBjYXNlIERPVDoKLSAgICAgICAgICBjYXNlIFJBTkdFOgotICAgICAgICAgIGNhc2UgTlJBTkdFOgotICAgICAgICAgICAgcmV0dXJuIDI7Ci0KLSAgICAgICAgICBjYXNlIElOREVQRU5ERU5UOgotICAgICAgICAgIGNhc2UgUEFSRU46Ci0gICAgICAgICAgY2FzZSBNT0RJRklFUkdST1VQOgotICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0Q2hpbGQoMCkuZ2V0TWF4TGVuZ3RoKCk7Ci0KLSAgICAgICAgICBjYXNlIEJBQ0tSRUZFUkVOQ0U6Ci0gICAgICAgICAgICByZXR1cm4gLTE7ICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAqKioqKioKLQotICAgICAgICAgIGNhc2UgU1RSSU5HOgotICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0U3RyaW5nKCkubGVuZ3RoKCk7Ci0KLSAgICAgICAgICBjYXNlIExPT0tBSEVBRDoKLSAgICAgICAgICBjYXNlIE5FR0FUSVZFTE9PS0FIRUFEOgotICAgICAgICAgIGNhc2UgTE9PS0JFSElORDoKLSAgICAgICAgICBjYXNlIE5FR0FUSVZFTE9PS0JFSElORDoKLSAgICAgICAgICAgIHJldHVybiAwOyAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICoqKioqIFJlYWxseT8KLQotICAgICAgICAgIGRlZmF1bHQ6Ci0gICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVG9rZW4jZ2V0TWF4TGVuZ3RoKCk6IEludmFsaWQgVHlwZTogIit0aGlzLnR5cGUpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgc3RhdGljIGZpbmFsIGludCBGQ19DT05USU5VRSA9IDA7Ci0gICAgc3RhdGljIGZpbmFsIGludCBGQ19URVJNSU5BTCA9IDE7Ci0gICAgc3RhdGljIGZpbmFsIGludCBGQ19BTlkgPSAyOwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW4gaXNTZXQoaW50IG9wdGlvbnMsIGludCBmbGFnKSB7Ci0gICAgICAgIHJldHVybiAob3B0aW9ucyAmIGZsYWcpID09IGZsYWc7Ci0gICAgfQotICAgIGZpbmFsIGludCBhbmFseXplRmlyc3RDaGFyYWN0ZXIoUmFuZ2VUb2tlbiByZXN1bHQsIGludCBvcHRpb25zKSB7Ci0gICAgICAgIHN3aXRjaCAodGhpcy50eXBlKSB7Ci0gICAgICAgICAgY2FzZSBDT05DQVQ6Ci0gICAgICAgICAgICBpbnQgcmV0ID0gRkNfQ09OVElOVUU7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgIGkgPCB0aGlzLnNpemUoKTsgIGkgKyspCi0gICAgICAgICAgICAgICAgaWYgKChyZXQgPSB0aGlzLmdldENoaWxkKGkpLmFuYWx5emVGaXJzdENoYXJhY3RlcihyZXN1bHQsIG9wdGlvbnMpKSAhPSBGQ19DT05USU5VRSkKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICByZXR1cm4gcmV0OwotCi0gICAgICAgICAgY2FzZSBVTklPTjoKLSAgICAgICAgICAgIGlmICh0aGlzLnNpemUoKSA9PSAwKQotICAgICAgICAgICAgICAgIHJldHVybiBGQ19DT05USU5VRTsKLSAgICAgICAgICAgIC8qCi0gICAgICAgICAgICAgKiAgYXxifGMgLT4gRkNfVEVSTUlOQUwKLSAgICAgICAgICAgICAqICBhfC58YyAtPiBGQ19BTlkKLSAgICAgICAgICAgICAqICBhfGJ8ICAtPiBGQ19DT05USU5VRQotICAgICAgICAgICAgICovCi0gICAgICAgICAgICBpbnQgcmV0MiA9IEZDX0NPTlRJTlVFOwotICAgICAgICAgICAgYm9vbGVhbiBoYXNFbXB0eSA9IGZhbHNlOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7ICBpIDwgdGhpcy5zaXplKCk7ICBpICsrKSB7Ci0gICAgICAgICAgICAgICAgcmV0MiA9IHRoaXMuZ2V0Q2hpbGQoaSkuYW5hbHl6ZUZpcnN0Q2hhcmFjdGVyKHJlc3VsdCwgb3B0aW9ucyk7Ci0gICAgICAgICAgICAgICAgaWYgKHJldDIgPT0gRkNfQU5ZKQotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICBlbHNlIGlmIChyZXQyID09IEZDX0NPTlRJTlVFKQotICAgICAgICAgICAgICAgICAgICBoYXNFbXB0eSA9IHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gaGFzRW1wdHkgPyBGQ19DT05USU5VRSA6IHJldDI7Ci0KLSAgICAgICAgICBjYXNlIENPTkRJVElPTjoKLSAgICAgICAgICAgIGludCByZXQzID0gdGhpcy5nZXRDaGlsZCgwKS5hbmFseXplRmlyc3RDaGFyYWN0ZXIocmVzdWx0LCBvcHRpb25zKTsKLSAgICAgICAgICAgIGlmICh0aGlzLnNpemUoKSA9PSAxKSAgcmV0dXJuIEZDX0NPTlRJTlVFOwotICAgICAgICAgICAgaWYgKHJldDMgPT0gRkNfQU5ZKSAgcmV0dXJuIHJldDM7Ci0gICAgICAgICAgICBpbnQgcmV0NCA9IHRoaXMuZ2V0Q2hpbGQoMSkuYW5hbHl6ZUZpcnN0Q2hhcmFjdGVyKHJlc3VsdCwgb3B0aW9ucyk7Ci0gICAgICAgICAgICBpZiAocmV0NCA9PSBGQ19BTlkpICByZXR1cm4gcmV0NDsKLSAgICAgICAgICAgIHJldHVybiByZXQzID09IEZDX0NPTlRJTlVFIHx8IHJldDQgPT0gRkNfQ09OVElOVUUgPyBGQ19DT05USU5VRSA6IEZDX1RFUk1JTkFMOwotCi0gICAgICAgICAgY2FzZSBDTE9TVVJFOgotICAgICAgICAgIGNhc2UgTk9OR1JFRURZQ0xPU1VSRToKLSAgICAgICAgICAgIHRoaXMuZ2V0Q2hpbGQoMCkuYW5hbHl6ZUZpcnN0Q2hhcmFjdGVyKHJlc3VsdCwgb3B0aW9ucyk7Ci0gICAgICAgICAgICByZXR1cm4gRkNfQ09OVElOVUU7Ci0KLSAgICAgICAgICBjYXNlIEVNUFRZOgotICAgICAgICAgIGNhc2UgQU5DSE9SOgotICAgICAgICAgICAgcmV0dXJuIEZDX0NPTlRJTlVFOwotCi0gICAgICAgICAgY2FzZSBDSEFSOgotICAgICAgICAgICAgaW50IGNoID0gdGhpcy5nZXRDaGFyKCk7Ci0gICAgICAgICAgICByZXN1bHQuYWRkUmFuZ2UoY2gsIGNoKTsKLSAgICAgICAgICAgIGlmIChjaCA8IDB4MTAwMDAgJiYgaXNTZXQob3B0aW9ucywgUmVndWxhckV4cHJlc3Npb24uSUdOT1JFX0NBU0UpKSB7Ci0gICAgICAgICAgICAgICAgY2ggPSBDaGFyYWN0ZXIudG9VcHBlckNhc2UoKGNoYXIpY2gpOwotICAgICAgICAgICAgICAgIHJlc3VsdC5hZGRSYW5nZShjaCwgY2gpOwotICAgICAgICAgICAgICAgIGNoID0gQ2hhcmFjdGVyLnRvTG93ZXJDYXNlKChjaGFyKWNoKTsKLSAgICAgICAgICAgICAgICByZXN1bHQuYWRkUmFuZ2UoY2gsIGNoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiBGQ19URVJNSU5BTDsKLQotICAgICAgICAgIGNhc2UgRE9UOgotICAgICAgICAgICAgICByZXR1cm4gRkNfQU5ZOwotCi0gICAgICAgICAgY2FzZSBSQU5HRToKLSAgICAgICAgICAgIHJlc3VsdC5tZXJnZVJhbmdlcyh0aGlzKTsKLSAgICAgICAgICAgIHJldHVybiBGQ19URVJNSU5BTDsKLQotICAgICAgICAgIGNhc2UgTlJBTkdFOiAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gKioqKgotICAgICAgICAgICAgcmVzdWx0Lm1lcmdlUmFuZ2VzKFRva2VuLmNvbXBsZW1lbnRSYW5nZXModGhpcykpOwotICAgICAgICAgICAgcmV0dXJuIEZDX1RFUk1JTkFMOwotCi0gICAgICAgICAgY2FzZSBJTkRFUEVOREVOVDoKLSAgICAgICAgICBjYXNlIFBBUkVOOgotICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0Q2hpbGQoMCkuYW5hbHl6ZUZpcnN0Q2hhcmFjdGVyKHJlc3VsdCwgb3B0aW9ucyk7Ci0KLSAgICAgICAgICBjYXNlIE1PRElGSUVSR1JPVVA6Ci0gICAgICAgICAgICBvcHRpb25zIHw9ICgoTW9kaWZpZXJUb2tlbil0aGlzKS5nZXRPcHRpb25zKCk7Ci0gICAgICAgICAgICBvcHRpb25zICY9IH4oKE1vZGlmaWVyVG9rZW4pdGhpcykuZ2V0T3B0aW9uc01hc2soKTsKLSAgICAgICAgICAgIHJldHVybiB0aGlzLmdldENoaWxkKDApLmFuYWx5emVGaXJzdENoYXJhY3RlcihyZXN1bHQsIG9wdGlvbnMpOwotCi0gICAgICAgICAgY2FzZSBCQUNLUkVGRVJFTkNFOgotICAgICAgICAgICAgcmVzdWx0LmFkZFJhbmdlKDAsIFVURjE2X01BWCk7ICAvLyAqKioqIFdlIGNhbiBub3Qgb3B0aW1pemUuCi0gICAgICAgICAgICByZXR1cm4gRkNfQU5ZOwotCi0gICAgICAgICAgY2FzZSBTVFJJTkc6Ci0gICAgICAgICAgICBpbnQgY2hhID0gdGhpcy5nZXRTdHJpbmcoKS5jaGFyQXQoMCk7Ci0gICAgICAgICAgICBpbnQgY2gyOwotICAgICAgICAgICAgaWYgKFJFVXRpbC5pc0hpZ2hTdXJyb2dhdGUoY2hhKQotICAgICAgICAgICAgICAgICYmIHRoaXMuZ2V0U3RyaW5nKCkubGVuZ3RoKCkgPj0gMgotICAgICAgICAgICAgICAgICYmIFJFVXRpbC5pc0xvd1N1cnJvZ2F0ZSgoY2gyID0gdGhpcy5nZXRTdHJpbmcoKS5jaGFyQXQoMSkpKSkKLSAgICAgICAgICAgICAgICBjaGEgPSBSRVV0aWwuY29tcG9zZUZyb21TdXJyb2dhdGVzKGNoYSwgY2gyKTsKLSAgICAgICAgICAgIHJlc3VsdC5hZGRSYW5nZShjaGEsIGNoYSk7Ci0gICAgICAgICAgICBpZiAoY2hhIDwgMHgxMDAwMCAmJiBpc1NldChvcHRpb25zLCBSZWd1bGFyRXhwcmVzc2lvbi5JR05PUkVfQ0FTRSkpIHsKLSAgICAgICAgICAgICAgICBjaGEgPSBDaGFyYWN0ZXIudG9VcHBlckNhc2UoKGNoYXIpY2hhKTsKLSAgICAgICAgICAgICAgICByZXN1bHQuYWRkUmFuZ2UoY2hhLCBjaGEpOwotICAgICAgICAgICAgICAgIGNoYSA9IENoYXJhY3Rlci50b0xvd2VyQ2FzZSgoY2hhciljaGEpOwotICAgICAgICAgICAgICAgIHJlc3VsdC5hZGRSYW5nZShjaGEsIGNoYSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gRkNfVEVSTUlOQUw7Ci0KLSAgICAgICAgICBjYXNlIExPT0tBSEVBRDoKLSAgICAgICAgICBjYXNlIE5FR0FUSVZFTE9PS0FIRUFEOgotICAgICAgICAgIGNhc2UgTE9PS0JFSElORDoKLSAgICAgICAgICBjYXNlIE5FR0FUSVZFTE9PS0JFSElORDoKLSAgICAgICAgICAgIHJldHVybiBGQ19DT05USU5VRTsKLQotICAgICAgICAgIGRlZmF1bHQ6Ci0gICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVG9rZW4jYW5hbHl6ZUhlYWRDaGFyYWN0ZXIoKTogSW52YWxpZCBUeXBlOiAiK3RoaXMudHlwZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gaXNTaG9ydGVyVGhhbihUb2tlbiB0b2spIHsKLSAgICAgICAgaWYgKHRvayA9PSBudWxsKSAgcmV0dXJuIGZhbHNlOwotICAgICAgICAvKgotICAgICAgICBpbnQgbXlsZW5ndGg7Ci0gICAgICAgIGlmICh0aGlzLnR5cGUgPT0gU1RSSU5HKSAgbXlsZW5ndGggPSB0aGlzLmdldFN0cmluZygpLmxlbmd0aCgpOwotICAgICAgICBlbHNlIGlmICh0aGlzLnR5cGUgPT0gQ0hBUikgIG15bGVuZ3RoID0gdGhpcy5nZXRDaGFyKCkgPj0gMHgxMDAwMCA/IDIgOiAxOwotICAgICAgICBlbHNlIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJJbnRlcm5hbCBFcnJvcjogSWxsZWdhbCB0eXBlOiAiK3RoaXMudHlwZSk7Ci0gICAgICAgIGludCBvdGhlcmxlbmd0aDsKLSAgICAgICAgaWYgKHRvay50eXBlID09IFNUUklORykgIG90aGVybGVuZ3RoID0gdG9rLmdldFN0cmluZygpLmxlbmd0aCgpOwotICAgICAgICBlbHNlIGlmICh0b2sudHlwZSA9PSBDSEFSKSAgb3RoZXJsZW5ndGggPSB0b2suZ2V0Q2hhcigpID49IDB4MTAwMDAgPyAyIDogMTsKLSAgICAgICAgZWxzZSB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiSW50ZXJuYWwgRXJyb3I6IElsbGVnYWwgdHlwZTogIit0b2sudHlwZSk7Ci0gICAgICAgICovCi0gICAgICAgIGludCBteWxlbmd0aDsKLSAgICAgICAgaWYgKHRoaXMudHlwZSA9PSBTVFJJTkcpICBteWxlbmd0aCA9IHRoaXMuZ2V0U3RyaW5nKCkubGVuZ3RoKCk7Ci0gICAgICAgIGVsc2UgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIkludGVybmFsIEVycm9yOiBJbGxlZ2FsIHR5cGU6ICIrdGhpcy50eXBlKTsKLSAgICAgICAgaW50IG90aGVybGVuZ3RoOwotICAgICAgICBpZiAodG9rLnR5cGUgPT0gU1RSSU5HKSAgb3RoZXJsZW5ndGggPSB0b2suZ2V0U3RyaW5nKCkubGVuZ3RoKCk7Ci0gICAgICAgIGVsc2UgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIkludGVybmFsIEVycm9yOiBJbGxlZ2FsIHR5cGU6ICIrdG9rLnR5cGUpOwotICAgICAgICByZXR1cm4gbXlsZW5ndGggPCBvdGhlcmxlbmd0aDsKLSAgICB9Ci0KLSAgICBzdGF0aWMgY2xhc3MgRml4ZWRTdHJpbmdDb250YWluZXIgewotICAgICAgICBUb2tlbiB0b2tlbiA9IG51bGw7Ci0gICAgICAgIGludCBvcHRpb25zID0gMDsKLSAgICAgICAgRml4ZWRTdHJpbmdDb250YWluZXIoKSB7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBmaW5hbCB2b2lkIGZpbmRGaXhlZFN0cmluZyhGaXhlZFN0cmluZ0NvbnRhaW5lciBjb250YWluZXIsIGludCBvcHRpb25zKSB7Ci0gICAgICAgIHN3aXRjaCAodGhpcy50eXBlKSB7Ci0gICAgICAgICAgY2FzZSBDT05DQVQ6Ci0gICAgICAgICAgICBUb2tlbiBwcmV2VG9rZW4gPSBudWxsOwotICAgICAgICAgICAgaW50IHByZXZPcHRpb25zID0gMDsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyAgaSA8IHRoaXMuc2l6ZSgpOyAgaSArKykgewotICAgICAgICAgICAgICAgIHRoaXMuZ2V0Q2hpbGQoaSkuZmluZEZpeGVkU3RyaW5nKGNvbnRhaW5lciwgb3B0aW9ucyk7Ci0gICAgICAgICAgICAgICAgaWYgKHByZXZUb2tlbiA9PSBudWxsIHx8IHByZXZUb2tlbi5pc1Nob3J0ZXJUaGFuKGNvbnRhaW5lci50b2tlbikpIHsKLSAgICAgICAgICAgICAgICAgICAgcHJldlRva2VuID0gY29udGFpbmVyLnRva2VuOwotICAgICAgICAgICAgICAgICAgICBwcmV2T3B0aW9ucyA9IGNvbnRhaW5lci5vcHRpb25zOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNvbnRhaW5lci50b2tlbiA9IHByZXZUb2tlbjsKLSAgICAgICAgICAgIGNvbnRhaW5lci5vcHRpb25zID0gcHJldk9wdGlvbnM7Ci0gICAgICAgICAgICByZXR1cm47Ci0KLSAgICAgICAgICBjYXNlIFVOSU9OOgotICAgICAgICAgIGNhc2UgQ0xPU1VSRToKLSAgICAgICAgICBjYXNlIE5PTkdSRUVEWUNMT1NVUkU6Ci0gICAgICAgICAgY2FzZSBFTVBUWToKLSAgICAgICAgICBjYXNlIEFOQ0hPUjoKLSAgICAgICAgICBjYXNlIFJBTkdFOgotICAgICAgICAgIGNhc2UgRE9UOgotICAgICAgICAgIGNhc2UgTlJBTkdFOgotICAgICAgICAgIGNhc2UgQkFDS1JFRkVSRU5DRToKLSAgICAgICAgICBjYXNlIExPT0tBSEVBRDoKLSAgICAgICAgICBjYXNlIE5FR0FUSVZFTE9PS0FIRUFEOgotICAgICAgICAgIGNhc2UgTE9PS0JFSElORDoKLSAgICAgICAgICBjYXNlIE5FR0FUSVZFTE9PS0JFSElORDoKLSAgICAgICAgICBjYXNlIENPTkRJVElPTjoKLSAgICAgICAgICAgIGNvbnRhaW5lci50b2tlbiA9IG51bGw7Ci0gICAgICAgICAgICByZXR1cm47Ci0KLSAgICAgICAgICBjYXNlIENIQVI6ICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIElnbm9yZSBDSEFSIHRva2Vucy4KLSAgICAgICAgICAgIGNvbnRhaW5lci50b2tlbiA9IG51bGw7ICAgICAgICAgICAgIC8vICoqCi0gICAgICAgICAgICByZXR1cm47ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAqKgotCi0gICAgICAgICAgY2FzZSBTVFJJTkc6Ci0gICAgICAgICAgICBjb250YWluZXIudG9rZW4gPSB0aGlzOwotICAgICAgICAgICAgY29udGFpbmVyLm9wdGlvbnMgPSBvcHRpb25zOwotICAgICAgICAgICAgcmV0dXJuOwotCi0gICAgICAgICAgY2FzZSBJTkRFUEVOREVOVDoKLSAgICAgICAgICBjYXNlIFBBUkVOOgotICAgICAgICAgICAgdGhpcy5nZXRDaGlsZCgwKS5maW5kRml4ZWRTdHJpbmcoY29udGFpbmVyLCBvcHRpb25zKTsKLSAgICAgICAgICAgIHJldHVybjsKLQotICAgICAgICAgIGNhc2UgTU9ESUZJRVJHUk9VUDoKLSAgICAgICAgICAgIG9wdGlvbnMgfD0gKChNb2RpZmllclRva2VuKXRoaXMpLmdldE9wdGlvbnMoKTsKLSAgICAgICAgICAgIG9wdGlvbnMgJj0gfigoTW9kaWZpZXJUb2tlbil0aGlzKS5nZXRPcHRpb25zTWFzaygpOwotICAgICAgICAgICAgdGhpcy5nZXRDaGlsZCgwKS5maW5kRml4ZWRTdHJpbmcoY29udGFpbmVyLCBvcHRpb25zKTsKLSAgICAgICAgICAgIHJldHVybjsKLQotICAgICAgICAgIGRlZmF1bHQ6Ci0gICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVG9rZW4jZmluZEZpeGVkU3RyaW5nKCk6IEludmFsaWQgVHlwZTogIit0aGlzLnR5cGUpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgYm9vbGVhbiBtYXRjaChpbnQgY2gpIHsKLSAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIk5GQUFycm93I21hdGNoKCk6IEludGVybmFsIGVycm9yOiAiK3RoaXMudHlwZSk7Ci0gICAgfQotCi0gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgTWFwPFN0cmluZywgVG9rZW4+IGNhdGVnb3JpZXMgPSBuZXcgSGFzaE1hcDw+KCk7Ci0gICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgTWFwPFN0cmluZywgVG9rZW4+IGNhdGVnb3JpZXMyID0gbmV3IEhhc2hNYXA8PigpOwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZ1tdIGNhdGVnb3J5TmFtZXMgPSB7Ci0gICAgICAgICJDbiIsICJMdSIsICJMbCIsICJMdCIsICJMbSIsICJMbyIsICJNbiIsICJNZSIsICJNYyIsICJOZCIsCi0gICAgICAgICJObCIsICJObyIsICJacyIsICJabCIsICJacCIsICJDYyIsICJDZiIsIG51bGwsICJDbyIsICJDcyIsCi0gICAgICAgICJQZCIsICJQcyIsICJQZSIsICJQYyIsICJQbyIsICJTbSIsICJTYyIsICJTayIsICJTbyIsIC8vIDI4Ci0gICAgICAgICJQaSIsICJQZiIsICAvLyAyOSwgMzAKLSAgICAgICAgIkwiLCAiTSIsICJOIiwgIloiLCAiQyIsICJQIiwgIlMiLCAgICAgIC8vIDMxLTM3Ci0gICAgfTsKLQotICAgIC8vIFNjaGVtYSBSZWMuIHtEYXRhdHlwZXN9IC0gUHVuY3R1YXRpb24KLSAgICBzdGF0aWMgZmluYWwgaW50IENIQVJfSU5JVF9RVU9URSAgPSAyOTsgICAgIC8vIFBpIC0gaW5pdGlhbCBxdW90ZQotICAgIHN0YXRpYyBmaW5hbCBpbnQgQ0hBUl9GSU5BTF9RVU9URSA9IDMwOyAgICAgLy8gUGYgLSBmaW5hbCBxdW90ZQotICAgIHN0YXRpYyBmaW5hbCBpbnQgQ0hBUl9MRVRURVIgPSAzMTsKLSAgICBzdGF0aWMgZmluYWwgaW50IENIQVJfTUFSSyA9IDMyOwotICAgIHN0YXRpYyBmaW5hbCBpbnQgQ0hBUl9OVU1CRVIgPSAzMzsKLSAgICBzdGF0aWMgZmluYWwgaW50IENIQVJfU0VQQVJBVE9SID0gMzQ7Ci0gICAgc3RhdGljIGZpbmFsIGludCBDSEFSX09USEVSID0gMzU7Ci0gICAgc3RhdGljIGZpbmFsIGludCBDSEFSX1BVTkNUVUFUSU9OID0gMzY7Ci0gICAgc3RhdGljIGZpbmFsIGludCBDSEFSX1NZTUJPTCA9IDM3OwotCi0gICAgLy9ibG9ja05hbWVzIGluIFVOSUNPREUgMy4xIHRoYXQgc3VwcG9ydGVkIGJ5IFhNTCBTY2hlbWEgUkVDCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nW10gYmxvY2tOYW1lcyA9IHsKLSAgICAgICAgLyowMDAwLi4wMDdGOyovICJCYXNpYyBMYXRpbiIsCi0gICAgICAgIC8qMDA4MC4uMDBGRjsqLyAiTGF0aW4tMSBTdXBwbGVtZW50IiwKLSAgICAgICAgLyowMTAwLi4wMTdGOyovICJMYXRpbiBFeHRlbmRlZC1BIiwKLSAgICAgICAgLyowMTgwLi4wMjRGOyovICJMYXRpbiBFeHRlbmRlZC1CIiwKLSAgICAgICAgLyowMjUwLi4wMkFGOyovICJJUEEgRXh0ZW5zaW9ucyIsCi0gICAgICAgIC8qMDJCMC4uMDJGRjsqLyAiU3BhY2luZyBNb2RpZmllciBMZXR0ZXJzIiwKLSAgICAgICAgLyowMzAwLi4wMzZGOyovICJDb21iaW5pbmcgRGlhY3JpdGljYWwgTWFya3MiLAotICAgICAgICAvKjAzNzAuLjAzRkY7Ki8gIkdyZWVrIiwKLSAgICAgICAgLyowNDAwLi4wNEZGOyovICJDeXJpbGxpYyIsCi0gICAgICAgIC8qMDUzMC4uMDU4RjsqLyAiQXJtZW5pYW4iLAotICAgICAgICAvKjA1OTAuLjA1RkY7Ki8gIkhlYnJldyIsCi0gICAgICAgIC8qMDYwMC4uMDZGRjsqLyAiQXJhYmljIiwKLSAgICAgICAgLyowNzAwLi4wNzRGOyovICJTeXJpYWMiLAotICAgICAgICAvKjA3ODAuLjA3QkY7Ki8gIlRoYWFuYSIsCi0gICAgICAgIC8qMDkwMC4uMDk3RjsqLyAiRGV2YW5hZ2FyaSIsCi0gICAgICAgIC8qMDk4MC4uMDlGRjsqLyAiQmVuZ2FsaSIsCi0gICAgICAgIC8qMEEwMC4uMEE3RjsqLyAiR3VybXVraGkiLAotICAgICAgICAvKjBBODAuLjBBRkY7Ki8gIkd1amFyYXRpIiwKLSAgICAgICAgLyowQjAwLi4wQjdGOyovICJPcml5YSIsCi0gICAgICAgIC8qMEI4MC4uMEJGRjsqLyAiVGFtaWwiLAotICAgICAgICAvKjBDMDAuLjBDN0Y7Ki8gIlRlbHVndSIsCi0gICAgICAgIC8qMEM4MC4uMENGRjsqLyAiS2FubmFkYSIsCi0gICAgICAgIC8qMEQwMC4uMEQ3RjsqLyAiTWFsYXlhbGFtIiwKLSAgICAgICAgLyowRDgwLi4wREZGOyovICJTaW5oYWxhIiwKLSAgICAgICAgLyowRTAwLi4wRTdGOyovICJUaGFpIiwKLSAgICAgICAgLyowRTgwLi4wRUZGOyovICJMYW8iLAotICAgICAgICAvKjBGMDAuLjBGRkY7Ki8gIlRpYmV0YW4iLAotICAgICAgICAvKjEwMDAuLjEwOUY7Ki8gIk15YW5tYXIiLAotICAgICAgICAvKjEwQTAuLjEwRkY7Ki8gIkdlb3JnaWFuIiwKLSAgICAgICAgLyoxMTAwLi4xMUZGOyovICJIYW5ndWwgSmFtbyIsCi0gICAgICAgIC8qMTIwMC4uMTM3RjsqLyAiRXRoaW9waWMiLAotICAgICAgICAvKjEzQTAuLjEzRkY7Ki8gIkNoZXJva2VlIiwKLSAgICAgICAgLyoxNDAwLi4xNjdGOyovICJVbmlmaWVkIENhbmFkaWFuIEFib3JpZ2luYWwgU3lsbGFiaWNzIiwKLSAgICAgICAgLyoxNjgwLi4xNjlGOyovICJPZ2hhbSIsCi0gICAgICAgIC8qMTZBMC4uMTZGRjsqLyAiUnVuaWMiLAotICAgICAgICAvKjE3ODAuLjE3RkY7Ki8gIktobWVyIiwKLSAgICAgICAgLyoxODAwLi4xOEFGOyovICJNb25nb2xpYW4iLAotICAgICAgICAvKjFFMDAuLjFFRkY7Ki8gIkxhdGluIEV4dGVuZGVkIEFkZGl0aW9uYWwiLAotICAgICAgICAvKjFGMDAuLjFGRkY7Ki8gIkdyZWVrIEV4dGVuZGVkIiwKLSAgICAgICAgLyoyMDAwLi4yMDZGOyovICJHZW5lcmFsIFB1bmN0dWF0aW9uIiwKLSAgICAgICAgLyoyMDcwLi4yMDlGOyovICJTdXBlcnNjcmlwdHMgYW5kIFN1YnNjcmlwdHMiLAotICAgICAgICAvKjIwQTAuLjIwQ0Y7Ki8gIkN1cnJlbmN5IFN5bWJvbHMiLAotICAgICAgICAvKjIwRDAuLjIwRkY7Ki8gIkNvbWJpbmluZyBNYXJrcyBmb3IgU3ltYm9scyIsCi0gICAgICAgIC8qMjEwMC4uMjE0RjsqLyAiTGV0dGVybGlrZSBTeW1ib2xzIiwKLSAgICAgICAgLyoyMTUwLi4yMThGOyovICJOdW1iZXIgRm9ybXMiLAotICAgICAgICAvKjIxOTAuLjIxRkY7Ki8gIkFycm93cyIsCi0gICAgICAgIC8qMjIwMC4uMjJGRjsqLyAiTWF0aGVtYXRpY2FsIE9wZXJhdG9ycyIsCi0gICAgICAgIC8qMjMwMC4uMjNGRjsqLyAiTWlzY2VsbGFuZW91cyBUZWNobmljYWwiLAotICAgICAgICAvKjI0MDAuLjI0M0Y7Ki8gIkNvbnRyb2wgUGljdHVyZXMiLAotICAgICAgICAvKjI0NDAuLjI0NUY7Ki8gIk9wdGljYWwgQ2hhcmFjdGVyIFJlY29nbml0aW9uIiwKLSAgICAgICAgLyoyNDYwLi4yNEZGOyovICJFbmNsb3NlZCBBbHBoYW51bWVyaWNzIiwKLSAgICAgICAgLyoyNTAwLi4yNTdGOyovICJCb3ggRHJhd2luZyIsCi0gICAgICAgIC8qMjU4MC4uMjU5RjsqLyAiQmxvY2sgRWxlbWVudHMiLAotICAgICAgICAvKjI1QTAuLjI1RkY7Ki8gIkdlb21ldHJpYyBTaGFwZXMiLAotICAgICAgICAvKjI2MDAuLjI2RkY7Ki8gIk1pc2NlbGxhbmVvdXMgU3ltYm9scyIsCi0gICAgICAgIC8qMjcwMC4uMjdCRjsqLyAiRGluZ2JhdHMiLAotICAgICAgICAvKjI4MDAuLjI4RkY7Ki8gIkJyYWlsbGUgUGF0dGVybnMiLAotICAgICAgICAvKjJFODAuLjJFRkY7Ki8gIkNKSyBSYWRpY2FscyBTdXBwbGVtZW50IiwKLSAgICAgICAgLyoyRjAwLi4yRkRGOyovICJLYW5neGkgUmFkaWNhbHMiLAotICAgICAgICAvKjJGRjAuLjJGRkY7Ki8gIklkZW9ncmFwaGljIERlc2NyaXB0aW9uIENoYXJhY3RlcnMiLAotICAgICAgICAvKjMwMDAuLjMwM0Y7Ki8gIkNKSyBTeW1ib2xzIGFuZCBQdW5jdHVhdGlvbiIsCi0gICAgICAgIC8qMzA0MC4uMzA5RjsqLyAiSGlyYWdhbmEiLAotICAgICAgICAvKjMwQTAuLjMwRkY7Ki8gIkthdGFrYW5hIiwKLSAgICAgICAgLyozMTAwLi4zMTJGOyovICJCb3BvbW9mbyIsCi0gICAgICAgIC8qMzEzMC4uMzE4RjsqLyAiSGFuZ3VsIENvbXBhdGliaWxpdHkgSmFtbyIsCi0gICAgICAgIC8qMzE5MC4uMzE5RjsqLyAiS2FuYnVuIiwKLSAgICAgICAgLyozMUEwLi4zMUJGOyovICJCb3BvbW9mbyBFeHRlbmRlZCIsCi0gICAgICAgIC8qMzIwMC4uMzJGRjsqLyAiRW5jbG9zZWQgQ0pLIExldHRlcnMgYW5kIE1vbnRocyIsCi0gICAgICAgIC8qMzMwMC4uMzNGRjsqLyAiQ0pLIENvbXBhdGliaWxpdHkiLAotICAgICAgICAvKjM0MDAuLjREQjU7Ki8gIkNKSyBVbmlmaWVkIElkZW9ncmFwaHMgRXh0ZW5zaW9uIEEiLAotICAgICAgICAvKjRFMDAuLjlGRkY7Ki8gIkNKSyBVbmlmaWVkIElkZW9ncmFwaHMiLAotICAgICAgICAvKkEwMDAuLkE0OEY7Ki8gIllpIFN5bGxhYmxlcyIsCi0gICAgICAgIC8qQTQ5MC4uQTRDRjsqLyAiWWkgUmFkaWNhbHMiLAotICAgICAgICAvKkFDMDAuLkQ3QTM7Ki8gIkhhbmd1bCBTeWxsYWJsZXMiLAotICAgICAgICAvKkUwMDAuLkY4RkY7Ki8gIlByaXZhdGUgVXNlIiwKLSAgICAgICAgLypGOTAwLi5GQUZGOyovICJDSksgQ29tcGF0aWJpbGl0eSBJZGVvZ3JhcGhzIiwKLSAgICAgICAgLypGQjAwLi5GQjRGOyovICJBbHBoYWJldGljIFByZXNlbnRhdGlvbiBGb3JtcyIsCi0gICAgICAgIC8qRkI1MC4uRkRGRjsqLyAiQXJhYmljIFByZXNlbnRhdGlvbiBGb3Jtcy1BIiwKLSAgICAgICAgLypGRTIwLi5GRTJGOyovICJDb21iaW5pbmcgSGFsZiBNYXJrcyIsCi0gICAgICAgIC8qRkUzMC4uRkU0RjsqLyAiQ0pLIENvbXBhdGliaWxpdHkgRm9ybXMiLAotICAgICAgICAvKkZFNTAuLkZFNkY7Ki8gIlNtYWxsIEZvcm0gVmFyaWFudHMiLAotICAgICAgICAvKkZFNzAuLkZFRkU7Ki8gIkFyYWJpYyBQcmVzZW50YXRpb24gRm9ybXMtQiIsCi0gICAgICAgIC8qRkVGRi4uRkVGRjsqLyAiU3BlY2lhbHMiLAotICAgICAgICAvKkZGMDAuLkZGRUY7Ki8gIkhhbGZ3aWR0aCBhbmQgRnVsbHdpZHRoIEZvcm1zIiwKLSAgICAgICAgIC8vbWlzc2luZyBTcGVjaWFscyBhZGQgbWFudWFsbHkKLSAgICAgICAgLyoxMDMwMC4uMTAzMkY7Ki8gIk9sZCBJdGFsaWMiLCAgICAgICAgIC8vIDg0Ci0gICAgICAgIC8qMTAzMzAuLjEwMzRGOyovICJHb3RoaWMiLAotICAgICAgICAvKjEwNDAwLi4xMDQ0RjsqLyAiRGVzZXJldCIsCi0gICAgICAgIC8qMUQwMDAuLjFEMEZGOyovICJCeXphbnRpbmUgTXVzaWNhbCBTeW1ib2xzIiwKLSAgICAgICAgLyoxRDEwMC4uMUQxRkY7Ki8gIk11c2ljYWwgU3ltYm9scyIsCi0gICAgICAgIC8qMUQ0MDAuLjFEN0ZGOyovICJNYXRoZW1hdGljYWwgQWxwaGFudW1lcmljIFN5bWJvbHMiLAotICAgICAgICAvKjIwMDAwLi4yQTZENjsqLyAiQ0pLIFVuaWZpZWQgSWRlb2dyYXBocyBFeHRlbnNpb24gQiIsCi0gICAgICAgIC8qMkY4MDAuLjJGQTFGOyovICJDSksgQ29tcGF0aWJpbGl0eSBJZGVvZ3JhcGhzIFN1cHBsZW1lbnQiLAotICAgICAgICAvKkUwMDAwLi5FMDA3RjsqLyAiVGFncyIsCi0gICAgICAgIC8vbWlzc2luZyAyIHByaXZhdGUgdXNlIGFkZCBtYW51YWxseQotCi0gICAgfTsKLSAgICAvL0FERCBUSE9TRSBNQU5VQUxMWQotICAgIC8vRjAwMDAuLkZGRkZEOyAiUHJpdmF0ZSBVc2UiLAotICAgIC8vMTAwMDAwLi4xMEZGRkQ7ICJQcml2YXRlIFVzZSIKLSAgICAvL0ZGRjAuLkZGRkQ7ICJTcGVjaWFscyIsCi0gICAgc3RhdGljIGZpbmFsIFN0cmluZyBibG9ja1JhbmdlcyA9Ci0gICAgICAgIlx1MDAwMFx1MDA3Rlx1MDA4MFx1MDBGRlx1MDEwMFx1MDE3Rlx1MDE4MFx1MDI0Rlx1MDI1MFx1MDJBRlx1MDJCMFx1MDJGRlx1MDMwMFx1MDM2RiIKLSAgICAgICAgKyJcdTAzNzBcdTAzRkZcdTA0MDBcdTA0RkZcdTA1MzBcdTA1OEZcdTA1OTBcdTA1RkZcdTA2MDBcdTA2RkZcdTA3MDBcdTA3NEZcdTA3ODBcdTA3QkYiCi0gICAgICAgICsiXHUwOTAwXHUwOTdGXHUwOTgwXHUwOUZGXHUwQTAwXHUwQTdGXHUwQTgwXHUwQUZGXHUwQjAwXHUwQjdGXHUwQjgwXHUwQkZGXHUwQzAwXHUwQzdGXHUwQzgwXHUwQ0ZGIgotICAgICAgICArIlx1MEQwMFx1MEQ3Rlx1MEQ4MFx1MERGRlx1MEUwMFx1MEU3Rlx1MEU4MFx1MEVGRlx1MEYwMFx1MEZGRlx1MTAwMFx1MTA5Rlx1MTBBMFx1MTBGRlx1MTEwMFx1MTFGRiIKLSAgICAgICAgKyJcdTEyMDBcdTEzN0ZcdTEzQTBcdTEzRkZcdTE0MDBcdTE2N0ZcdTE2ODBcdTE2OUZcdTE2QTBcdTE2RkZcdTE3ODBcdTE3RkZcdTE4MDBcdTE4QUZcdTFFMDBcdTFFRkYiCi0gICAgICAgICsiXHUxRjAwXHUxRkZGXHUyMDAwXHUyMDZGXHUyMDcwXHUyMDlGXHUyMEEwXHUyMENGXHUyMEQwXHUyMEZGXHUyMTAwXHUyMTRGXHUyMTUwXHUyMThGXHUyMTkwXHUyMUZGXHUyMjAwXHUyMkZGIgotICAgICAgICArIlx1MjMwMFx1MjNGRlx1MjQwMFx1MjQzRlx1MjQ0MFx1MjQ1Rlx1MjQ2MFx1MjRGRlx1MjUwMFx1MjU3Rlx1MjU4MFx1MjU5Rlx1MjVBMFx1MjVGRlx1MjYwMFx1MjZGRlx1MjcwMFx1MjdCRiIKLSAgICAgICAgKyJcdTI4MDBcdTI4RkZcdTJFODBcdTJFRkZcdTJGMDBcdTJGREZcdTJGRjBcdTJGRkZcdTMwMDBcdTMwM0ZcdTMwNDBcdTMwOUZcdTMwQTBcdTMwRkZcdTMxMDBcdTMxMkZcdTMxMzBcdTMxOEYiCi0gICAgICAgICsiXHUzMTkwXHUzMTlGXHUzMUEwXHUzMUJGXHUzMjAwXHUzMkZGXHUzMzAwXHUzM0ZGXHUzNDAwXHU0REI1XHU0RTAwXHU5RkZGXHVBMDAwXHVBNDhGXHVBNDkwXHVBNENGIgotICAgICAgICArIlx1QUMwMFx1RDdBM1x1RTAwMFx1RjhGRlx1RjkwMFx1RkFGRlx1RkIwMFx1RkI0Rlx1RkI1MFx1RkRGRiIKLSAgICAgICAgKyJcdUZFMjBcdUZFMkZcdUZFMzBcdUZFNEZcdUZFNTBcdUZFNkZcdUZFNzBcdUZFRkVcdUZFRkZcdUZFRkZcdUZGMDBcdUZGRUYiOwotICAgIHN0YXRpYyBmaW5hbCBpbnRbXSBub25CTVBCbG9ja1JhbmdlcyA9IHsKLSAgICAgICAgMHgxMDMwMCwgMHgxMDMyRiwgICAgICAgLy8gODQKLSAgICAgICAgMHgxMDMzMCwgMHgxMDM0RiwKLSAgICAgICAgMHgxMDQwMCwgMHgxMDQ0RiwKLSAgICAgICAgMHgxRDAwMCwgMHgxRDBGRiwKLSAgICAgICAgMHgxRDEwMCwgMHgxRDFGRiwKLSAgICAgICAgMHgxRDQwMCwgMHgxRDdGRiwKLSAgICAgICAgMHgyMDAwMCwgMHgyQTZENiwKLSAgICAgICAgMHgyRjgwMCwgMHgyRkExRiwKLSAgICAgICAgMHhFMDAwMCwgMHhFMDA3RgotICAgIH07Ci0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE5PTkJNUF9CTE9DS19TVEFSVCA9IDg0OwotCi0gICAgc3RhdGljIHByb3RlY3RlZCBSYW5nZVRva2VuIGdldFJhbmdlKFN0cmluZyBuYW1lLCBib29sZWFuIHBvc2l0aXZlKSB7Ci0gICAgICAgIGlmIChUb2tlbi5jYXRlZ29yaWVzLnNpemUoKSA9PSAwKSB7Ci0gICAgICAgICAgICBzeW5jaHJvbml6ZWQgKFRva2VuLmNhdGVnb3JpZXMpIHsKLSAgICAgICAgICAgICAgICBUb2tlbltdIHJhbmdlcyA9IG5ldyBUb2tlbltUb2tlbi5jYXRlZ29yeU5hbWVzLmxlbmd0aF07Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7ICBpIDwgcmFuZ2VzLmxlbmd0aDsgIGkgKyspIHsKLSAgICAgICAgICAgICAgICAgICAgcmFuZ2VzW2ldID0gVG9rZW4uY3JlYXRlUmFuZ2UoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaW50IHR5cGU7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7ICBpIDwgMHgxMDAwMDsgIGkgKyspIHsKLSAgICAgICAgICAgICAgICAgICAgdHlwZSA9IENoYXJhY3Rlci5nZXRUeXBlKChjaGFyKWkpOwotICAgICAgICAgICAgICAgICAgICBpZiAodHlwZSA9PSBDaGFyYWN0ZXIuU1RBUlRfUFVOQ1RVQVRJT04gfHwKLSAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUgPT0gQ2hhcmFjdGVyLkVORF9QVU5DVFVBVElPTikgewotICAgICAgICAgICAgICAgICAgICAgICAgLy9idWlsZCB0YWJsZSBvZiBQaSB2YWx1ZXMKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpID09IDB4MDBBQiB8fCBpID09IDB4MjAxOCB8fCBpID09IDB4MjAxQiB8fCBpID09IDB4MjAxQyB8fAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgPT0gMHgyMDFGIHx8IGkgPT0gMHgyMDM5KSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZSA9IENIQVJfSU5JVF9RVU9URTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vYnVpbGQgdGFibGUgb2YgUGYgdmFsdWVzCi0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaSA9PSAweDAwQkIgfHwgaSA9PSAweDIwMTkgfHwgaSA9PSAweDIwMUQgfHwgaSA9PSAweDIwM0EgKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZSA9IENIQVJfRklOQUxfUVVPVEU7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgcmFuZ2VzW3R5cGVdLmFkZFJhbmdlKGksIGkpOwotICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKHR5cGUpIHsKLSAgICAgICAgICAgICAgICAgICAgICBjYXNlIENoYXJhY3Rlci5VUFBFUkNBU0VfTEVUVEVSOgotICAgICAgICAgICAgICAgICAgICAgIGNhc2UgQ2hhcmFjdGVyLkxPV0VSQ0FTRV9MRVRURVI6Ci0gICAgICAgICAgICAgICAgICAgICAgY2FzZSBDaGFyYWN0ZXIuVElUTEVDQVNFX0xFVFRFUjoKLSAgICAgICAgICAgICAgICAgICAgICBjYXNlIENoYXJhY3Rlci5NT0RJRklFUl9MRVRURVI6Ci0gICAgICAgICAgICAgICAgICAgICAgY2FzZSBDaGFyYWN0ZXIuT1RIRVJfTEVUVEVSOgotICAgICAgICAgICAgICAgICAgICAgICAgdHlwZSA9IENIQVJfTEVUVEVSOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgY2FzZSBDaGFyYWN0ZXIuTk9OX1NQQUNJTkdfTUFSSzoKLSAgICAgICAgICAgICAgICAgICAgICBjYXNlIENoYXJhY3Rlci5DT01CSU5JTkdfU1BBQ0lOR19NQVJLOgotICAgICAgICAgICAgICAgICAgICAgIGNhc2UgQ2hhcmFjdGVyLkVOQ0xPU0lOR19NQVJLOgotICAgICAgICAgICAgICAgICAgICAgICAgdHlwZSA9IENIQVJfTUFSSzsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgIGNhc2UgQ2hhcmFjdGVyLkRFQ0lNQUxfRElHSVRfTlVNQkVSOgotICAgICAgICAgICAgICAgICAgICAgIGNhc2UgQ2hhcmFjdGVyLkxFVFRFUl9OVU1CRVI6Ci0gICAgICAgICAgICAgICAgICAgICAgY2FzZSBDaGFyYWN0ZXIuT1RIRVJfTlVNQkVSOgotICAgICAgICAgICAgICAgICAgICAgICAgdHlwZSA9IENIQVJfTlVNQkVSOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgY2FzZSBDaGFyYWN0ZXIuU1BBQ0VfU0VQQVJBVE9SOgotICAgICAgICAgICAgICAgICAgICAgIGNhc2UgQ2hhcmFjdGVyLkxJTkVfU0VQQVJBVE9SOgotICAgICAgICAgICAgICAgICAgICAgIGNhc2UgQ2hhcmFjdGVyLlBBUkFHUkFQSF9TRVBBUkFUT1I6Ci0gICAgICAgICAgICAgICAgICAgICAgICB0eXBlID0gQ0hBUl9TRVBBUkFUT1I7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICBjYXNlIENoYXJhY3Rlci5DT05UUk9MOgotICAgICAgICAgICAgICAgICAgICAgIGNhc2UgQ2hhcmFjdGVyLkZPUk1BVDoKLSAgICAgICAgICAgICAgICAgICAgICBjYXNlIENoYXJhY3Rlci5TVVJST0dBVEU6Ci0gICAgICAgICAgICAgICAgICAgICAgY2FzZSBDaGFyYWN0ZXIuUFJJVkFURV9VU0U6Ci0gICAgICAgICAgICAgICAgICAgICAgY2FzZSBDaGFyYWN0ZXIuVU5BU1NJR05FRDoKLSAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUgPSBDSEFSX09USEVSOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgY2FzZSBDaGFyYWN0ZXIuQ09OTkVDVE9SX1BVTkNUVUFUSU9OOgotICAgICAgICAgICAgICAgICAgICAgIGNhc2UgQ2hhcmFjdGVyLkRBU0hfUFVOQ1RVQVRJT046Ci0gICAgICAgICAgICAgICAgICAgICAgY2FzZSBDaGFyYWN0ZXIuU1RBUlRfUFVOQ1RVQVRJT046Ci0gICAgICAgICAgICAgICAgICAgICAgY2FzZSBDaGFyYWN0ZXIuRU5EX1BVTkNUVUFUSU9OOgotICAgICAgICAgICAgICAgICAgICAgIGNhc2UgQ0hBUl9JTklUX1FVT1RFOgotICAgICAgICAgICAgICAgICAgICAgIGNhc2UgQ0hBUl9GSU5BTF9RVU9URToKLSAgICAgICAgICAgICAgICAgICAgICBjYXNlIENoYXJhY3Rlci5PVEhFUl9QVU5DVFVBVElPTjoKLSAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUgPSBDSEFSX1BVTkNUVUFUSU9OOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgY2FzZSBDaGFyYWN0ZXIuTUFUSF9TWU1CT0w6Ci0gICAgICAgICAgICAgICAgICAgICAgY2FzZSBDaGFyYWN0ZXIuQ1VSUkVOQ1lfU1lNQk9MOgotICAgICAgICAgICAgICAgICAgICAgIGNhc2UgQ2hhcmFjdGVyLk1PRElGSUVSX1NZTUJPTDoKLSAgICAgICAgICAgICAgICAgICAgICBjYXNlIENoYXJhY3Rlci5PVEhFUl9TWU1CT0w6Ci0gICAgICAgICAgICAgICAgICAgICAgICB0eXBlID0gQ0hBUl9TWU1CT0w7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgotICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIm9yZy5hcGFjaGUueGVyY2VzLnV0aWxzLnJlZ2V4LlRva2VuI2dldFJhbmdlKCk6IFVua25vd24gVW5pY29kZSBjYXRlZ29yeTogIit0eXBlKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICByYW5nZXNbdHlwZV0uYWRkUmFuZ2UoaSwgaSk7Ci0gICAgICAgICAgICAgICAgfSAvLyBmb3IgYWxsIGNoYXJhY3RlcnMKLSAgICAgICAgICAgICAgICByYW5nZXNbQ2hhcmFjdGVyLlVOQVNTSUdORURdLmFkZFJhbmdlKDB4MTAwMDAsIFRva2VuLlVURjE2X01BWCk7Ci0KLSAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgIGkgPCByYW5nZXMubGVuZ3RoOyAgaSArKykgewotICAgICAgICAgICAgICAgICAgICBpZiAoVG9rZW4uY2F0ZWdvcnlOYW1lc1tpXSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaSA9PSBDaGFyYWN0ZXIuVU5BU1NJR05FRCkgeyAvLyBVbmFzc2lnbmVkCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmFuZ2VzW2ldLmFkZFJhbmdlKDB4MTAwMDAsIFRva2VuLlVURjE2X01BWCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBUb2tlbi5jYXRlZ29yaWVzLnB1dChUb2tlbi5jYXRlZ29yeU5hbWVzW2ldLCByYW5nZXNbaV0pOwotICAgICAgICAgICAgICAgICAgICAgICAgVG9rZW4uY2F0ZWdvcmllczIucHV0KFRva2VuLmNhdGVnb3J5TmFtZXNbaV0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVG9rZW4uY29tcGxlbWVudFJhbmdlcyhyYW5nZXNbaV0pKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvL1JFVklTSVQ6IGRvIHdlIHJlYWxseSBuZWVkIHRvIHN1cHBvcnQgYmxvY2sgbmFtZXMgYXMgaW4gVW5pY29kZSAzLjEKLSAgICAgICAgICAgICAgICAvLyAgICAgICAgIG9yIHdlIGNhbiBqdXN0IGNyZWF0ZSBhbGwgdGhlIG5hbWVzIGluIElzQkxPQ0tOQU1FIGZvcm1hdCAoWE1MIFNjaGVtYSBSRUMpPwotICAgICAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAgICAgU3RyaW5nQnVpbGRlciBidWZmZXIgPSBuZXcgU3RyaW5nQnVpbGRlcig1MCk7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7ICBpIDwgVG9rZW4uYmxvY2tOYW1lcy5sZW5ndGg7ICBpICsrKSB7Ci0gICAgICAgICAgICAgICAgICAgIFRva2VuIHIxID0gVG9rZW4uY3JlYXRlUmFuZ2UoKTsKLSAgICAgICAgICAgICAgICAgICAgaW50IGxvY2F0aW9uOwotICAgICAgICAgICAgICAgICAgICBpZiAoaSA8IE5PTkJNUF9CTE9DS19TVEFSVCkgewotICAgICAgICAgICAgICAgICAgICAgICAgbG9jYXRpb24gPSBpKjI7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpbnQgcnN0YXJ0ID0gVG9rZW4uYmxvY2tSYW5nZXMuY2hhckF0KGxvY2F0aW9uKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGludCByZW5kID0gVG9rZW4uYmxvY2tSYW5nZXMuY2hhckF0KGxvY2F0aW9uKzEpOwotICAgICAgICAgICAgICAgICAgICAgICAgLy9ERUJVR0lORwotICAgICAgICAgICAgICAgICAgICAgICAgLy9TeXN0ZW0ub3V0LnByaW50bG4obisiICIgK0ludGVnZXIudG9IZXhTdHJpbmcocnN0YXJ0KQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgICAgICAgICAgICAgICAgICArIi0iKyBJbnRlZ2VyLnRvSGV4U3RyaW5nKHJlbmQpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHIxLmFkZFJhbmdlKHJzdGFydCwgcmVuZCk7Ci0gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBsb2NhdGlvbiA9IChpIC0gTk9OQk1QX0JMT0NLX1NUQVJUKSAqIDI7Ci0gICAgICAgICAgICAgICAgICAgICAgICByMS5hZGRSYW5nZShUb2tlbi5ub25CTVBCbG9ja1Jhbmdlc1tsb2NhdGlvbl0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUb2tlbi5ub25CTVBCbG9ja1Jhbmdlc1tsb2NhdGlvbiArIDFdKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbiA9IFRva2VuLmJsb2NrTmFtZXNbaV07Ci0gICAgICAgICAgICAgICAgICAgIGlmIChuLmVxdWFscygiU3BlY2lhbHMiKSkKLSAgICAgICAgICAgICAgICAgICAgICAgIHIxLmFkZFJhbmdlKDB4ZmZmMCwgMHhmZmZkKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKG4uZXF1YWxzKCJQcml2YXRlIFVzZSIpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByMS5hZGRSYW5nZSgweEYwMDAwLDB4RkZGRkQpOwotICAgICAgICAgICAgICAgICAgICAgICAgcjEuYWRkUmFuZ2UoMHgxMDAwMDAsMHgxMEZGRkQpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIFRva2VuLmNhdGVnb3JpZXMucHV0KG4sIHIxKTsKLSAgICAgICAgICAgICAgICAgICAgVG9rZW4uY2F0ZWdvcmllczIucHV0KG4sIFRva2VuLmNvbXBsZW1lbnRSYW5nZXMocjEpKTsKLSAgICAgICAgICAgICAgICAgICAgYnVmZmVyLnNldExlbmd0aCgwKTsKLSAgICAgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgiSXMiKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKG4uaW5kZXhPZignICcpID49IDApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGNpID0gMDsgIGNpIDwgbi5sZW5ndGgoKTsgIGNpICsrKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuLmNoYXJBdChjaSkgIT0gJyAnKSAgYnVmZmVyLmFwcGVuZCgoY2hhciluLmNoYXJBdChjaSkpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZChuKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBUb2tlbi5zZXRBbGlhcyhidWZmZXIudG9TdHJpbmcoKSwgbiwgdHJ1ZSk7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgLy8gVFIjMTggMS4yCi0gICAgICAgICAgICAgICAgVG9rZW4uc2V0QWxpYXMoIkFTU0lHTkVEIiwgIkNuIiwgZmFsc2UpOwotICAgICAgICAgICAgICAgIFRva2VuLnNldEFsaWFzKCJVTkFTU0lHTkVEIiwgIkNuIiwgdHJ1ZSk7Ci0gICAgICAgICAgICAgICAgVG9rZW4gYWxsID0gVG9rZW4uY3JlYXRlUmFuZ2UoKTsKLSAgICAgICAgICAgICAgICBhbGwuYWRkUmFuZ2UoMCwgVG9rZW4uVVRGMTZfTUFYKTsKLSAgICAgICAgICAgICAgICBUb2tlbi5jYXRlZ29yaWVzLnB1dCgiQUxMIiwgYWxsKTsKLSAgICAgICAgICAgICAgICBUb2tlbi5jYXRlZ29yaWVzMi5wdXQoIkFMTCIsIFRva2VuLmNvbXBsZW1lbnRSYW5nZXMoYWxsKSk7Ci0gICAgICAgICAgICAgICAgVG9rZW4ucmVnaXN0ZXJOb25YUygiQVNTSUdORUQiKTsKLSAgICAgICAgICAgICAgICBUb2tlbi5yZWdpc3Rlck5vblhTKCJVTkFTU0lHTkVEIik7Ci0gICAgICAgICAgICAgICAgVG9rZW4ucmVnaXN0ZXJOb25YUygiQUxMIik7Ci0KLSAgICAgICAgICAgICAgICBUb2tlbiBpc2FscGhhID0gVG9rZW4uY3JlYXRlUmFuZ2UoKTsKLSAgICAgICAgICAgICAgICBpc2FscGhhLm1lcmdlUmFuZ2VzKHJhbmdlc1tDaGFyYWN0ZXIuVVBQRVJDQVNFX0xFVFRFUl0pOyAvLyBMdQotICAgICAgICAgICAgICAgIGlzYWxwaGEubWVyZ2VSYW5nZXMocmFuZ2VzW0NoYXJhY3Rlci5MT1dFUkNBU0VfTEVUVEVSXSk7IC8vIExsCi0gICAgICAgICAgICAgICAgaXNhbHBoYS5tZXJnZVJhbmdlcyhyYW5nZXNbQ2hhcmFjdGVyLk9USEVSX0xFVFRFUl0pOyAvLyBMbwotICAgICAgICAgICAgICAgIFRva2VuLmNhdGVnb3JpZXMucHV0KCJJc0FscGhhIiwgaXNhbHBoYSk7Ci0gICAgICAgICAgICAgICAgVG9rZW4uY2F0ZWdvcmllczIucHV0KCJJc0FscGhhIiwgVG9rZW4uY29tcGxlbWVudFJhbmdlcyhpc2FscGhhKSk7Ci0gICAgICAgICAgICAgICAgVG9rZW4ucmVnaXN0ZXJOb25YUygiSXNBbHBoYSIpOwotCi0gICAgICAgICAgICAgICAgVG9rZW4gaXNhbG51bSA9IFRva2VuLmNyZWF0ZVJhbmdlKCk7Ci0gICAgICAgICAgICAgICAgaXNhbG51bS5tZXJnZVJhbmdlcyhpc2FscGhhKTsgICAvLyBMdSBMbCBMbwotICAgICAgICAgICAgICAgIGlzYWxudW0ubWVyZ2VSYW5nZXMocmFuZ2VzW0NoYXJhY3Rlci5ERUNJTUFMX0RJR0lUX05VTUJFUl0pOyAvLyBOZAotICAgICAgICAgICAgICAgIFRva2VuLmNhdGVnb3JpZXMucHV0KCJJc0FsbnVtIiwgaXNhbG51bSk7Ci0gICAgICAgICAgICAgICAgVG9rZW4uY2F0ZWdvcmllczIucHV0KCJJc0FsbnVtIiwgVG9rZW4uY29tcGxlbWVudFJhbmdlcyhpc2FsbnVtKSk7Ci0gICAgICAgICAgICAgICAgVG9rZW4ucmVnaXN0ZXJOb25YUygiSXNBbG51bSIpOwotCi0gICAgICAgICAgICAgICAgVG9rZW4gaXNzcGFjZSA9IFRva2VuLmNyZWF0ZVJhbmdlKCk7Ci0gICAgICAgICAgICAgICAgaXNzcGFjZS5tZXJnZVJhbmdlcyhUb2tlbi50b2tlbl9zcGFjZXMpOwotICAgICAgICAgICAgICAgIGlzc3BhY2UubWVyZ2VSYW5nZXMocmFuZ2VzW0NIQVJfU0VQQVJBVE9SXSk7IC8vIFoKLSAgICAgICAgICAgICAgICBUb2tlbi5jYXRlZ29yaWVzLnB1dCgiSXNTcGFjZSIsIGlzc3BhY2UpOwotICAgICAgICAgICAgICAgIFRva2VuLmNhdGVnb3JpZXMyLnB1dCgiSXNTcGFjZSIsIFRva2VuLmNvbXBsZW1lbnRSYW5nZXMoaXNzcGFjZSkpOwotICAgICAgICAgICAgICAgIFRva2VuLnJlZ2lzdGVyTm9uWFMoIklzU3BhY2UiKTsKLQotICAgICAgICAgICAgICAgIFRva2VuIGlzd29yZCA9IFRva2VuLmNyZWF0ZVJhbmdlKCk7Ci0gICAgICAgICAgICAgICAgaXN3b3JkLm1lcmdlUmFuZ2VzKGlzYWxudW0pOyAgICAgLy8gTHUgTGwgTG8gTmQKLSAgICAgICAgICAgICAgICBpc3dvcmQuYWRkUmFuZ2UoJ18nLCAnXycpOwotICAgICAgICAgICAgICAgIFRva2VuLmNhdGVnb3JpZXMucHV0KCJJc1dvcmQiLCBpc3dvcmQpOwotICAgICAgICAgICAgICAgIFRva2VuLmNhdGVnb3JpZXMyLnB1dCgiSXNXb3JkIiwgVG9rZW4uY29tcGxlbWVudFJhbmdlcyhpc3dvcmQpKTsKLSAgICAgICAgICAgICAgICBUb2tlbi5yZWdpc3Rlck5vblhTKCJJc1dvcmQiKTsKLQotICAgICAgICAgICAgICAgIFRva2VuIGlzYXNjaWkgPSBUb2tlbi5jcmVhdGVSYW5nZSgpOwotICAgICAgICAgICAgICAgIGlzYXNjaWkuYWRkUmFuZ2UoMCwgMTI3KTsKLSAgICAgICAgICAgICAgICBUb2tlbi5jYXRlZ29yaWVzLnB1dCgiSXNBU0NJSSIsIGlzYXNjaWkpOwotICAgICAgICAgICAgICAgIFRva2VuLmNhdGVnb3JpZXMyLnB1dCgiSXNBU0NJSSIsIFRva2VuLmNvbXBsZW1lbnRSYW5nZXMoaXNhc2NpaSkpOwotICAgICAgICAgICAgICAgIFRva2VuLnJlZ2lzdGVyTm9uWFMoIklzQVNDSUkiKTsKLQotICAgICAgICAgICAgICAgIFRva2VuIGlzbm90Z3JhcGggPSBUb2tlbi5jcmVhdGVSYW5nZSgpOwotICAgICAgICAgICAgICAgIGlzbm90Z3JhcGgubWVyZ2VSYW5nZXMocmFuZ2VzW0NIQVJfT1RIRVJdKTsKLSAgICAgICAgICAgICAgICBpc25vdGdyYXBoLmFkZFJhbmdlKCcgJywgJyAnKTsKLSAgICAgICAgICAgICAgICBUb2tlbi5jYXRlZ29yaWVzLnB1dCgiSXNHcmFwaCIsIFRva2VuLmNvbXBsZW1lbnRSYW5nZXMoaXNub3RncmFwaCkpOwotICAgICAgICAgICAgICAgIFRva2VuLmNhdGVnb3JpZXMyLnB1dCgiSXNHcmFwaCIsIGlzbm90Z3JhcGgpOwotICAgICAgICAgICAgICAgIFRva2VuLnJlZ2lzdGVyTm9uWFMoIklzR3JhcGgiKTsKLQotICAgICAgICAgICAgICAgIFRva2VuIGlzeGRpZ2l0ID0gVG9rZW4uY3JlYXRlUmFuZ2UoKTsKLSAgICAgICAgICAgICAgICBpc3hkaWdpdC5hZGRSYW5nZSgnMCcsICc5Jyk7Ci0gICAgICAgICAgICAgICAgaXN4ZGlnaXQuYWRkUmFuZ2UoJ0EnLCAnRicpOwotICAgICAgICAgICAgICAgIGlzeGRpZ2l0LmFkZFJhbmdlKCdhJywgJ2YnKTsKLSAgICAgICAgICAgICAgICBUb2tlbi5jYXRlZ29yaWVzLnB1dCgiSXNYRGlnaXQiLCBUb2tlbi5jb21wbGVtZW50UmFuZ2VzKGlzeGRpZ2l0KSk7Ci0gICAgICAgICAgICAgICAgVG9rZW4uY2F0ZWdvcmllczIucHV0KCJJc1hEaWdpdCIsIGlzeGRpZ2l0KTsKLSAgICAgICAgICAgICAgICBUb2tlbi5yZWdpc3Rlck5vblhTKCJJc1hEaWdpdCIpOwotCi0gICAgICAgICAgICAgICAgVG9rZW4uc2V0QWxpYXMoIklzRGlnaXQiLCAiTmQiLCB0cnVlKTsKLSAgICAgICAgICAgICAgICBUb2tlbi5zZXRBbGlhcygiSXNVcHBlciIsICJMdSIsIHRydWUpOwotICAgICAgICAgICAgICAgIFRva2VuLnNldEFsaWFzKCJJc0xvd2VyIiwgIkxsIiwgdHJ1ZSk7Ci0gICAgICAgICAgICAgICAgVG9rZW4uc2V0QWxpYXMoIklzQ250cmwiLCAiQyIsIHRydWUpOwotICAgICAgICAgICAgICAgIFRva2VuLnNldEFsaWFzKCJJc1ByaW50IiwgIkMiLCBmYWxzZSk7Ci0gICAgICAgICAgICAgICAgVG9rZW4uc2V0QWxpYXMoIklzUHVuY3QiLCAiUCIsIHRydWUpOwotICAgICAgICAgICAgICAgIFRva2VuLnJlZ2lzdGVyTm9uWFMoIklzRGlnaXQiKTsKLSAgICAgICAgICAgICAgICBUb2tlbi5yZWdpc3Rlck5vblhTKCJJc1VwcGVyIik7Ci0gICAgICAgICAgICAgICAgVG9rZW4ucmVnaXN0ZXJOb25YUygiSXNMb3dlciIpOwotICAgICAgICAgICAgICAgIFRva2VuLnJlZ2lzdGVyTm9uWFMoIklzQ250cmwiKTsKLSAgICAgICAgICAgICAgICBUb2tlbi5yZWdpc3Rlck5vblhTKCJJc1ByaW50Iik7Ci0gICAgICAgICAgICAgICAgVG9rZW4ucmVnaXN0ZXJOb25YUygiSXNQdW5jdCIpOwotCi0gICAgICAgICAgICAgICAgVG9rZW4uc2V0QWxpYXMoImFscGhhIiwgIklzQWxwaGEiLCB0cnVlKTsKLSAgICAgICAgICAgICAgICBUb2tlbi5zZXRBbGlhcygiYWxudW0iLCAiSXNBbG51bSIsIHRydWUpOwotICAgICAgICAgICAgICAgIFRva2VuLnNldEFsaWFzKCJhc2NpaSIsICJJc0FTQ0lJIiwgdHJ1ZSk7Ci0gICAgICAgICAgICAgICAgVG9rZW4uc2V0QWxpYXMoImNudHJsIiwgIklzQ250cmwiLCB0cnVlKTsKLSAgICAgICAgICAgICAgICBUb2tlbi5zZXRBbGlhcygiZGlnaXQiLCAiSXNEaWdpdCIsIHRydWUpOwotICAgICAgICAgICAgICAgIFRva2VuLnNldEFsaWFzKCJncmFwaCIsICJJc0dyYXBoIiwgdHJ1ZSk7Ci0gICAgICAgICAgICAgICAgVG9rZW4uc2V0QWxpYXMoImxvd2VyIiwgIklzTG93ZXIiLCB0cnVlKTsKLSAgICAgICAgICAgICAgICBUb2tlbi5zZXRBbGlhcygicHJpbnQiLCAiSXNQcmludCIsIHRydWUpOwotICAgICAgICAgICAgICAgIFRva2VuLnNldEFsaWFzKCJwdW5jdCIsICJJc1B1bmN0IiwgdHJ1ZSk7Ci0gICAgICAgICAgICAgICAgVG9rZW4uc2V0QWxpYXMoInNwYWNlIiwgIklzU3BhY2UiLCB0cnVlKTsKLSAgICAgICAgICAgICAgICBUb2tlbi5zZXRBbGlhcygidXBwZXIiLCAiSXNVcHBlciIsIHRydWUpOwotICAgICAgICAgICAgICAgIFRva2VuLnNldEFsaWFzKCJ3b3JkIiwgIklzV29yZCIsIHRydWUpOyAvLyBQZXJsIGV4dGVuc2lvbgotICAgICAgICAgICAgICAgIFRva2VuLnNldEFsaWFzKCJ4ZGlnaXQiLCAiSXNYRGlnaXQiLCB0cnVlKTsKLSAgICAgICAgICAgICAgICBUb2tlbi5yZWdpc3Rlck5vblhTKCJhbHBoYSIpOwotICAgICAgICAgICAgICAgIFRva2VuLnJlZ2lzdGVyTm9uWFMoImFsbnVtIik7Ci0gICAgICAgICAgICAgICAgVG9rZW4ucmVnaXN0ZXJOb25YUygiYXNjaWkiKTsKLSAgICAgICAgICAgICAgICBUb2tlbi5yZWdpc3Rlck5vblhTKCJjbnRybCIpOwotICAgICAgICAgICAgICAgIFRva2VuLnJlZ2lzdGVyTm9uWFMoImRpZ2l0Iik7Ci0gICAgICAgICAgICAgICAgVG9rZW4ucmVnaXN0ZXJOb25YUygiZ3JhcGgiKTsKLSAgICAgICAgICAgICAgICBUb2tlbi5yZWdpc3Rlck5vblhTKCJsb3dlciIpOwotICAgICAgICAgICAgICAgIFRva2VuLnJlZ2lzdGVyTm9uWFMoInByaW50Iik7Ci0gICAgICAgICAgICAgICAgVG9rZW4ucmVnaXN0ZXJOb25YUygicHVuY3QiKTsKLSAgICAgICAgICAgICAgICBUb2tlbi5yZWdpc3Rlck5vblhTKCJzcGFjZSIpOwotICAgICAgICAgICAgICAgIFRva2VuLnJlZ2lzdGVyTm9uWFMoInVwcGVyIik7Ci0gICAgICAgICAgICAgICAgVG9rZW4ucmVnaXN0ZXJOb25YUygid29yZCIpOwotICAgICAgICAgICAgICAgIFRva2VuLnJlZ2lzdGVyTm9uWFMoInhkaWdpdCIpOwotICAgICAgICAgICAgfSAvLyBzeW5jaHJvbml6ZWQKLSAgICAgICAgfSAvLyBpZiBudWxsCi0gICAgICAgIFJhbmdlVG9rZW4gdG9rID0gcG9zaXRpdmUgPyAoUmFuZ2VUb2tlbilUb2tlbi5jYXRlZ29yaWVzLmdldChuYW1lKQotICAgICAgICAgICAgOiAoUmFuZ2VUb2tlbilUb2tlbi5jYXRlZ29yaWVzMi5nZXQobmFtZSk7Ci0gICAgICAgIC8vaWYgKHRvayA9PSBudWxsKSBTeXN0ZW0ub3V0LnByaW50bG4obmFtZSk7Ci0gICAgICAgIHJldHVybiB0b2s7Ci0gICAgfQotICAgIHN0YXRpYyBwcm90ZWN0ZWQgUmFuZ2VUb2tlbiBnZXRSYW5nZShTdHJpbmcgbmFtZSwgYm9vbGVhbiBwb3NpdGl2ZSwgYm9vbGVhbiB4cykgewotICAgICAgICBSYW5nZVRva2VuIHJhbmdlID0gVG9rZW4uZ2V0UmFuZ2UobmFtZSwgcG9zaXRpdmUpOwotICAgICAgICBpZiAoeHMgJiYgcmFuZ2UgIT0gbnVsbCAmJiBUb2tlbi5pc1JlZ2lzdGVyTm9uWFMobmFtZSkpCi0gICAgICAgICAgICByYW5nZSA9IG51bGw7Ci0gICAgICAgIHJldHVybiByYW5nZTsKLSAgICB9Ci0KLSAgICBzdGF0aWMgZmluYWwgU2V0PFN0cmluZz4gbm9ueHMgPSBDb2xsZWN0aW9ucy5zeW5jaHJvbml6ZWRTZXQobmV3IEhhc2hTZXQ8PigpKTsKLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgb25seSBnZXRSYW5nZSgpLgotICAgICAqIFNvIHRoaXMgbWV0aG9kIG5lZWQgbm90IE1ULXNhZmUuCi0gICAgICovCi0gICAgc3RhdGljIHByb3RlY3RlZCB2b2lkIHJlZ2lzdGVyTm9uWFMoU3RyaW5nIG5hbWUpIHsKLSAgICAgICAgVG9rZW4ubm9ueHMuYWRkKG5hbWUpOwotICAgIH0KLQotICAgIHN0YXRpYyBwcm90ZWN0ZWQgYm9vbGVhbiBpc1JlZ2lzdGVyTm9uWFMoU3RyaW5nIG5hbWUpIHsKLSAgICAgICAgcmV0dXJuIFRva2VuLm5vbnhzLmNvbnRhaW5zKG5hbWUpOwotICAgIH0KLQotICAgIHByaXZhdGUgc3RhdGljIHZvaWQgc2V0QWxpYXMoU3RyaW5nIG5ld05hbWUsIFN0cmluZyBuYW1lLCBib29sZWFuIHBvc2l0aXZlKSB7Ci0gICAgICAgIFRva2VuIHQxID0gKFRva2VuKVRva2VuLmNhdGVnb3JpZXMuZ2V0KG5hbWUpOwotICAgICAgICBUb2tlbiB0MiA9IChUb2tlbilUb2tlbi5jYXRlZ29yaWVzMi5nZXQobmFtZSk7Ci0gICAgICAgIGlmIChwb3NpdGl2ZSkgewotICAgICAgICAgICAgVG9rZW4uY2F0ZWdvcmllcy5wdXQobmV3TmFtZSwgdDEpOwotICAgICAgICAgICAgVG9rZW4uY2F0ZWdvcmllczIucHV0KG5ld05hbWUsIHQyKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIFRva2VuLmNhdGVnb3JpZXMyLnB1dChuZXdOYW1lLCB0MSk7Ci0gICAgICAgICAgICBUb2tlbi5jYXRlZ29yaWVzLnB1dChuZXdOYW1lLCB0Mik7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLQotICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgdmlyYW1hU3RyaW5nID0KLSAgICAiXHUwOTREIi8vIDtERVZBTkFHQVJJIFNJR04gVklSQU1BO01uOzk7T047Ozs7O047Ozs7OwotICAgICsiXHUwOUNEIi8vO0JFTkdBTEkgU0lHTiBWSVJBTUE7TW47OTtPTjs7Ozs7Tjs7Ozs7Ci0gICAgKyJcdTBBNEQiLy87R1VSTVVLSEkgU0lHTiBWSVJBTUE7TW47OTtPTjs7Ozs7Tjs7Ozs7Ci0gICAgKyJcdTBBQ0QiLy87R1VKQVJBVEkgU0lHTiBWSVJBTUE7TW47OTtPTjs7Ozs7Tjs7Ozs7Ci0gICAgKyJcdTBCNEQiLy87T1JJWUEgU0lHTiBWSVJBTUE7TW47OTtPTjs7Ozs7Tjs7Ozs7Ci0gICAgKyJcdTBCQ0QiLy87VEFNSUwgU0lHTiBWSVJBTUE7TW47OTtPTjs7Ozs7Tjs7Ozs7Ci0gICAgKyJcdTBDNEQiLy87VEVMVUdVIFNJR04gVklSQU1BO01uOzk7T047Ozs7O047Ozs7OwotICAgICsiXHUwQ0NEIi8vO0tBTk5BREEgU0lHTiBWSVJBTUE7TW47OTtPTjs7Ozs7Tjs7Ozs7Ci0gICAgKyJcdTBENEQiLy87TUFMQVlBTEFNIFNJR04gVklSQU1BO01uOzk7T047Ozs7O047Ozs7OwotICAgICsiXHUwRTNBIi8vO1RIQUkgQ0hBUkFDVEVSIFBISU5USFU7TW47OTtPTjs7Ozs7TjtUSEFJIFZPV0VMIFNJR04gUEhJTlRIVTs7OzsKLSAgICArIlx1MEY4NCI7Ly87VElCRVRBTiBNQVJLIEhBTEFOVEE7TW47OTtPTjs7Ozs7TjtUSUJFVEFOIFZJUkFNQTs7OzsKLQotICAgIHN0YXRpYyBwcml2YXRlIFRva2VuIHRva2VuX2dyYXBoZW1lID0gbnVsbDsKLSAgICBzdGF0aWMgc3luY2hyb25pemVkIFRva2VuIGdldEdyYXBoZW1lUGF0dGVybigpIHsKLSAgICAgICAgaWYgKFRva2VuLnRva2VuX2dyYXBoZW1lICE9IG51bGwpCi0gICAgICAgICAgICByZXR1cm4gVG9rZW4udG9rZW5fZ3JhcGhlbWU7Ci0KLSAgICAgICAgVG9rZW4gYmFzZV9jaGFyID0gVG9rZW4uY3JlYXRlUmFuZ2UoKTsgIC8vIFt7QVNTSUdORUR9XS1be019LHtDfV0KLSAgICAgICAgYmFzZV9jaGFyLm1lcmdlUmFuZ2VzKFRva2VuLmdldFJhbmdlKCJBU1NJR05FRCIsIHRydWUpKTsKLSAgICAgICAgYmFzZV9jaGFyLnN1YnRyYWN0UmFuZ2VzKFRva2VuLmdldFJhbmdlKCJNIiwgdHJ1ZSkpOwotICAgICAgICBiYXNlX2NoYXIuc3VidHJhY3RSYW5nZXMoVG9rZW4uZ2V0UmFuZ2UoIkMiLCB0cnVlKSk7Ci0KLSAgICAgICAgVG9rZW4gdmlyYW1hID0gVG9rZW4uY3JlYXRlUmFuZ2UoKTsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7ICBpIDwgVG9rZW4udmlyYW1hU3RyaW5nLmxlbmd0aCgpOyBpKyspIHsKLSAgICAgICAgICAgIHZpcmFtYS5hZGRSYW5nZShpLCBpKTsKLSAgICAgICAgfQotCi0gICAgICAgIFRva2VuIGNvbWJpbmVyX3dvX3ZpcmFtYSA9IFRva2VuLmNyZWF0ZVJhbmdlKCk7Ci0gICAgICAgIGNvbWJpbmVyX3dvX3ZpcmFtYS5tZXJnZVJhbmdlcyhUb2tlbi5nZXRSYW5nZSgiTSIsIHRydWUpKTsKLSAgICAgICAgY29tYmluZXJfd29fdmlyYW1hLmFkZFJhbmdlKDB4MTE2MCwgMHgxMWZmKTsgLy8gaGFuZ3VsX21lZGlhbCBhbmQgaGFuZ3VsX2ZpbmFsCi0gICAgICAgIGNvbWJpbmVyX3dvX3ZpcmFtYS5hZGRSYW5nZSgweGZmOWUsIDB4ZmY5Zik7IC8vIGV4dHJhcwotCi0gICAgICAgIFRva2VuIGxlZnQgPSBUb2tlbi5jcmVhdGVVbmlvbigpOyAgICAgICAvLyBiYXNlX2NoYXI/Ci0gICAgICAgIGxlZnQuYWRkQ2hpbGQoYmFzZV9jaGFyKTsKLSAgICAgICAgbGVmdC5hZGRDaGlsZChUb2tlbi50b2tlbl9lbXB0eSk7Ci0KLSAgICAgICAgVG9rZW4gZm9vID0gVG9rZW4uY3JlYXRlVW5pb24oKTsKLSAgICAgICAgZm9vLmFkZENoaWxkKFRva2VuLmNyZWF0ZUNvbmNhdCh2aXJhbWEsIFRva2VuLmdldFJhbmdlKCJMIiwgdHJ1ZSkpKTsKLSAgICAgICAgZm9vLmFkZENoaWxkKGNvbWJpbmVyX3dvX3ZpcmFtYSk7Ci0KLSAgICAgICAgZm9vID0gVG9rZW4uY3JlYXRlQ2xvc3VyZShmb28pOwotCi0gICAgICAgIGZvbyA9IFRva2VuLmNyZWF0ZUNvbmNhdChsZWZ0LCBmb28pOwotCi0gICAgICAgIFRva2VuLnRva2VuX2dyYXBoZW1lID0gZm9vOwotICAgICAgICByZXR1cm4gVG9rZW4udG9rZW5fZ3JhcGhlbWU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29tYmluZyBDaGFyYWN0ZXIgU2VxdWVuY2UgaW4gUGVybCA1LjYuCi0gICAgICovCi0gICAgc3RhdGljIHByaXZhdGUgVG9rZW4gdG9rZW5fY2NzID0gbnVsbDsKLSAgICBzdGF0aWMgc3luY2hyb25pemVkIFRva2VuIGdldENvbWJpbmluZ0NoYXJhY3RlclNlcXVlbmNlKCkgewotICAgICAgICBpZiAoVG9rZW4udG9rZW5fY2NzICE9IG51bGwpCi0gICAgICAgICAgICByZXR1cm4gVG9rZW4udG9rZW5fY2NzOwotCi0gICAgICAgIFRva2VuIGZvbyA9IFRva2VuLmNyZWF0ZUNsb3N1cmUoVG9rZW4uZ2V0UmFuZ2UoIk0iLCB0cnVlKSk7IC8vIFxwTSoKLSAgICAgICAgZm9vID0gVG9rZW4uY3JlYXRlQ29uY2F0KFRva2VuLmdldFJhbmdlKCJNIiwgZmFsc2UpLCBmb28pOyAvLyBcUE0gKyBccE0qCi0gICAgICAgIFRva2VuLnRva2VuX2NjcyA9IGZvbzsKLSAgICAgICAgcmV0dXJuIFRva2VuLnRva2VuX2NjczsKLSAgICB9Ci0KLSAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLQotICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgIC8qKgotICAgICAqIFRoaXMgY2xhc3MgcmVwcmVzZW50cyBhIG5vZGUgaW4gcGFyc2UgdHJlZS4KLSAgICAgKi8KLSAgICBzdGF0aWMgY2xhc3MgU3RyaW5nVG9rZW4gZXh0ZW5kcyBUb2tlbiBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKLQotICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNDYxNDM2Njk0NDIxODUwNDE3Mkw7Ci0KLSAgICAgICAgU3RyaW5nIHN0cmluZzsKLSAgICAgICAgZmluYWwgaW50IHJlZk51bWJlcjsKLQotICAgICAgICBTdHJpbmdUb2tlbihpbnQgdHlwZSwgU3RyaW5nIHN0ciwgaW50IG4pIHsKLSAgICAgICAgICAgIHN1cGVyKHR5cGUpOwotICAgICAgICAgICAgdGhpcy5zdHJpbmcgPSBzdHI7Ci0gICAgICAgICAgICB0aGlzLnJlZk51bWJlciA9IG47Ci0gICAgICAgIH0KLQotICAgICAgICBpbnQgZ2V0UmVmZXJlbmNlTnVtYmVyKCkgeyAgICAgICAgICAgICAgLy8gZm9yIFNUUklORwotICAgICAgICAgICAgcmV0dXJuIHRoaXMucmVmTnVtYmVyOwotICAgICAgICB9Ci0gICAgICAgIFN0cmluZyBnZXRTdHJpbmcoKSB7ICAgICAgICAgICAgICAgICAgICAvLyBmb3IgU1RSSU5HCi0gICAgICAgICAgICByZXR1cm4gdGhpcy5zdHJpbmc7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKGludCBvcHRpb25zKSB7Ci0gICAgICAgICAgICBpZiAodGhpcy50eXBlID09IEJBQ0tSRUZFUkVOQ0UpCi0gICAgICAgICAgICAgICAgcmV0dXJuICJcXCIrdGhpcy5yZWZOdW1iZXI7Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgcmV0dXJuIFJFVXRpbC5xdW90ZU1ldGEodGhpcy5zdHJpbmcpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBjbGFzcyByZXByZXNlbnRzIGEgbm9kZSBpbiBwYXJzZSB0cmVlLgotICAgICAqLwotICAgIHN0YXRpYyBjbGFzcyBDb25jYXRUb2tlbiBleHRlbmRzIFRva2VuIGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUgewotCi0gICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDg3MTczMjE0MjU1NDEzNDYzODFMOwotCi0gICAgICAgIGZpbmFsIFRva2VuIGNoaWxkOwotICAgICAgICBmaW5hbCBUb2tlbiBjaGlsZDI7Ci0KLSAgICAgICAgQ29uY2F0VG9rZW4oVG9rZW4gdDEsIFRva2VuIHQyKSB7Ci0gICAgICAgICAgICBzdXBlcihUb2tlbi5DT05DQVQpOwotICAgICAgICAgICAgdGhpcy5jaGlsZCA9IHQxOwotICAgICAgICAgICAgdGhpcy5jaGlsZDIgPSB0MjsKLSAgICAgICAgfQotCi0gICAgICAgIGludCBzaXplKCkgewotICAgICAgICAgICAgcmV0dXJuIDI7Ci0gICAgICAgIH0KLSAgICAgICAgVG9rZW4gZ2V0Q2hpbGQoaW50IGluZGV4KSB7Ci0gICAgICAgICAgICByZXR1cm4gaW5kZXggPT0gMCA/IHRoaXMuY2hpbGQgOiB0aGlzLmNoaWxkMjsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoaW50IG9wdGlvbnMpIHsKLSAgICAgICAgICAgIFN0cmluZyByZXQ7Ci0gICAgICAgICAgICBpZiAodGhpcy5jaGlsZDIudHlwZSA9PSBDTE9TVVJFICYmIHRoaXMuY2hpbGQyLmdldENoaWxkKDApID09IHRoaXMuY2hpbGQpIHsKLSAgICAgICAgICAgICAgICByZXQgPSB0aGlzLmNoaWxkLnRvU3RyaW5nKG9wdGlvbnMpKyIrIjsKLSAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5jaGlsZDIudHlwZSA9PSBOT05HUkVFRFlDTE9TVVJFICYmIHRoaXMuY2hpbGQyLmdldENoaWxkKDApID09IHRoaXMuY2hpbGQpIHsKLSAgICAgICAgICAgICAgICByZXQgPSB0aGlzLmNoaWxkLnRvU3RyaW5nKG9wdGlvbnMpKyIrPyI7Ci0gICAgICAgICAgICB9IGVsc2UKLSAgICAgICAgICAgICAgICByZXQgPSB0aGlzLmNoaWxkLnRvU3RyaW5nKG9wdGlvbnMpK3RoaXMuY2hpbGQyLnRvU3RyaW5nKG9wdGlvbnMpOwotICAgICAgICAgICAgcmV0dXJuIHJldDsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgY2xhc3MgcmVwcmVzZW50cyBhIG5vZGUgaW4gcGFyc2UgdHJlZS4KLSAgICAgKi8KLSAgICBzdGF0aWMgY2xhc3MgQ2hhclRva2VuIGV4dGVuZHMgVG9rZW4gaW1wbGVtZW50cyBqYXZhLmlvLlNlcmlhbGl6YWJsZSB7Ci0KLSAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTQzOTQyNzI4MTYyNzk0OTY5ODlMOwotCi0gICAgICAgIGZpbmFsIGludCBjaGFyZGF0YTsKLQotICAgICAgICBDaGFyVG9rZW4oaW50IHR5cGUsIGludCBjaCkgewotICAgICAgICAgICAgc3VwZXIodHlwZSk7Ci0gICAgICAgICAgICB0aGlzLmNoYXJkYXRhID0gY2g7Ci0gICAgICAgIH0KLQotICAgICAgICBpbnQgZ2V0Q2hhcigpIHsKLSAgICAgICAgICAgIHJldHVybiB0aGlzLmNoYXJkYXRhOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZyhpbnQgb3B0aW9ucykgewotICAgICAgICAgICAgU3RyaW5nIHJldDsKLSAgICAgICAgICAgIHN3aXRjaCAodGhpcy50eXBlKSB7Ci0gICAgICAgICAgICAgIGNhc2UgQ0hBUjoKLSAgICAgICAgICAgICAgICBzd2l0Y2ggKHRoaXMuY2hhcmRhdGEpIHsKLSAgICAgICAgICAgICAgICAgIGNhc2UgJ3wnOiAgY2FzZSAnKic6ICBjYXNlICcrJzogIGNhc2UgJz8nOgotICAgICAgICAgICAgICAgICAgY2FzZSAnKCc6ICBjYXNlICcpJzogIGNhc2UgJy4nOiAgY2FzZSAnWyc6Ci0gICAgICAgICAgICAgICAgICBjYXNlICd7JzogIGNhc2UgJ1xcJzoKLSAgICAgICAgICAgICAgICAgICAgcmV0ID0gIlxcIisoY2hhcil0aGlzLmNoYXJkYXRhOwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgIGNhc2UgJ1xmJzogIHJldCA9ICJcXGYiOyAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICBjYXNlICdcbic6ICByZXQgPSAiXFxuIjsgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgY2FzZSAnXHInOiAgcmV0ID0gIlxcciI7ICBicmVhazsKLSAgICAgICAgICAgICAgICAgIGNhc2UgJ1x0JzogIHJldCA9ICJcXHQiOyAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICBjYXNlIDB4MWI6ICByZXQgPSAiXFxlIjsgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAvL2Nhc2UgMHgwYjogIHJldCA9ICJcXHYiOyAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICBkZWZhdWx0OgotICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5jaGFyZGF0YSA+PSAweDEwMDAwKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcHJlID0gIjAiK0ludGVnZXIudG9IZXhTdHJpbmcodGhpcy5jaGFyZGF0YSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXQgPSAiXFx2IitwcmUuc3Vic3RyaW5nKHByZS5sZW5ndGgoKS02LCBwcmUubGVuZ3RoKCkpOwotICAgICAgICAgICAgICAgICAgICB9IGVsc2UKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldCA9ICIiKyhjaGFyKXRoaXMuY2hhcmRhdGE7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgICAgICAgIGNhc2UgQU5DSE9SOgotICAgICAgICAgICAgICAgIGlmICh0aGlzID09IFRva2VuLnRva2VuX2xpbmViZWdpbm5pbmcgfHwgdGhpcyA9PSBUb2tlbi50b2tlbl9saW5lZW5kKQotICAgICAgICAgICAgICAgICAgICByZXQgPSAiIisoY2hhcil0aGlzLmNoYXJkYXRhOwotICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgICAgcmV0ID0gIlxcIisoY2hhcil0aGlzLmNoYXJkYXRhOwotICAgICAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgICAgICAgIGRlZmF1bHQ6Ci0gICAgICAgICAgICAgICAgcmV0ID0gbnVsbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiByZXQ7Ci0gICAgICAgIH0KLQotICAgICAgICBib29sZWFuIG1hdGNoKGludCBjaCkgewotICAgICAgICAgICAgaWYgKHRoaXMudHlwZSA9PSBDSEFSKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGNoID09IHRoaXMuY2hhcmRhdGE7Ci0gICAgICAgICAgICB9IGVsc2UKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiTkZBQXJyb3cjbWF0Y2goKTogSW50ZXJuYWwgZXJyb3I6ICIrdGhpcy50eXBlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgY2xhc3MgcmVwcmVzZW50cyBhIG5vZGUgaW4gcGFyc2UgdHJlZS4KLSAgICAgKi8KLSAgICBzdGF0aWMgY2xhc3MgQ2xvc3VyZVRva2VuIGV4dGVuZHMgVG9rZW4gaW1wbGVtZW50cyBqYXZhLmlvLlNlcmlhbGl6YWJsZSB7Ci0KLSAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMTMwODk3MTkzMDY3Mzk5NzQ1Mkw7Ci0KLSAgICAgICAgaW50IG1pbjsKLSAgICAgICAgaW50IG1heDsKLSAgICAgICAgZmluYWwgVG9rZW4gY2hpbGQ7Ci0KLSAgICAgICAgQ2xvc3VyZVRva2VuKGludCB0eXBlLCBUb2tlbiB0b2spIHsKLSAgICAgICAgICAgIHN1cGVyKHR5cGUpOwotICAgICAgICAgICAgdGhpcy5jaGlsZCA9IHRvazsKLSAgICAgICAgICAgIHRoaXMuc2V0TWluKC0xKTsKLSAgICAgICAgICAgIHRoaXMuc2V0TWF4KC0xKTsKLSAgICAgICAgfQotCi0gICAgICAgIGludCBzaXplKCkgewotICAgICAgICAgICAgcmV0dXJuIDE7Ci0gICAgICAgIH0KLSAgICAgICAgVG9rZW4gZ2V0Q2hpbGQoaW50IGluZGV4KSB7Ci0gICAgICAgICAgICByZXR1cm4gdGhpcy5jaGlsZDsKLSAgICAgICAgfQotCi0gICAgICAgIGZpbmFsIHZvaWQgc2V0TWluKGludCBtaW4pIHsKLSAgICAgICAgICAgIHRoaXMubWluID0gbWluOwotICAgICAgICB9Ci0gICAgICAgIGZpbmFsIHZvaWQgc2V0TWF4KGludCBtYXgpIHsKLSAgICAgICAgICAgIHRoaXMubWF4ID0gbWF4OwotICAgICAgICB9Ci0gICAgICAgIGZpbmFsIGludCBnZXRNaW4oKSB7Ci0gICAgICAgICAgICByZXR1cm4gdGhpcy5taW47Ci0gICAgICAgIH0KLSAgICAgICAgZmluYWwgaW50IGdldE1heCgpIHsKLSAgICAgICAgICAgIHJldHVybiB0aGlzLm1heDsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoaW50IG9wdGlvbnMpIHsKLSAgICAgICAgICAgIFN0cmluZyByZXQ7Ci0gICAgICAgICAgICBpZiAodGhpcy50eXBlID09IENMT1NVUkUpIHsKLSAgICAgICAgICAgICAgICBpZiAodGhpcy5nZXRNaW4oKSA8IDAgJiYgdGhpcy5nZXRNYXgoKSA8IDApIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0ID0gdGhpcy5jaGlsZC50b1N0cmluZyhvcHRpb25zKSsiKiI7Ci0gICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLmdldE1pbigpID09IHRoaXMuZ2V0TWF4KCkpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0ID0gdGhpcy5jaGlsZC50b1N0cmluZyhvcHRpb25zKSsieyIrdGhpcy5nZXRNaW4oKSsifSI7Ci0gICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLmdldE1pbigpID49IDAgJiYgdGhpcy5nZXRNYXgoKSA+PSAwKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldCA9IHRoaXMuY2hpbGQudG9TdHJpbmcob3B0aW9ucykrInsiK3RoaXMuZ2V0TWluKCkrIiwiK3RoaXMuZ2V0TWF4KCkrIn0iOwotICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5nZXRNaW4oKSA+PSAwICYmIHRoaXMuZ2V0TWF4KCkgPCAwKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldCA9IHRoaXMuY2hpbGQudG9TdHJpbmcob3B0aW9ucykrInsiK3RoaXMuZ2V0TWluKCkrIix9IjsKLSAgICAgICAgICAgICAgICB9IGVsc2UKLSAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlRva2VuI3RvU3RyaW5nKCk6IENMT1NVUkUgIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArdGhpcy5nZXRNaW4oKSsiLCAiK3RoaXMuZ2V0TWF4KCkpOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBpZiAodGhpcy5nZXRNaW4oKSA8IDAgJiYgdGhpcy5nZXRNYXgoKSA8IDApIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0ID0gdGhpcy5jaGlsZC50b1N0cmluZyhvcHRpb25zKSsiKj8iOwotICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5nZXRNaW4oKSA9PSB0aGlzLmdldE1heCgpKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldCA9IHRoaXMuY2hpbGQudG9TdHJpbmcob3B0aW9ucykrInsiK3RoaXMuZ2V0TWluKCkrIn0/IjsKLSAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuZ2V0TWluKCkgPj0gMCAmJiB0aGlzLmdldE1heCgpID49IDApIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0ID0gdGhpcy5jaGlsZC50b1N0cmluZyhvcHRpb25zKSsieyIrdGhpcy5nZXRNaW4oKSsiLCIrdGhpcy5nZXRNYXgoKSsifT8iOwotICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5nZXRNaW4oKSA+PSAwICYmIHRoaXMuZ2V0TWF4KCkgPCAwKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldCA9IHRoaXMuY2hpbGQudG9TdHJpbmcob3B0aW9ucykrInsiK3RoaXMuZ2V0TWluKCkrIix9PyI7Ci0gICAgICAgICAgICAgICAgfSBlbHNlCi0gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJUb2tlbiN0b1N0cmluZygpOiBOT05HUkVFRFlDTE9TVVJFICIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgK3RoaXMuZ2V0TWluKCkrIiwgIit0aGlzLmdldE1heCgpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiByZXQ7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIGNsYXNzIHJlcHJlc2VudHMgYSBub2RlIGluIHBhcnNlIHRyZWUuCi0gICAgICovCi0gICAgc3RhdGljIGNsYXNzIFBhcmVuVG9rZW4gZXh0ZW5kcyBUb2tlbiBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKLQotICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNTkzODAxNDcxOTgyNzk4NzcwNEw7Ci0KLSAgICAgICAgZmluYWwgVG9rZW4gY2hpbGQ7Ci0gICAgICAgIGZpbmFsIGludCBwYXJlbm51bWJlcjsKLQotICAgICAgICBQYXJlblRva2VuKGludCB0eXBlLCBUb2tlbiB0b2ssIGludCBwYXJlbikgewotICAgICAgICAgICAgc3VwZXIodHlwZSk7Ci0gICAgICAgICAgICB0aGlzLmNoaWxkID0gdG9rOwotICAgICAgICAgICAgdGhpcy5wYXJlbm51bWJlciA9IHBhcmVuOwotICAgICAgICB9Ci0KLSAgICAgICAgaW50IHNpemUoKSB7Ci0gICAgICAgICAgICByZXR1cm4gMTsKLSAgICAgICAgfQotICAgICAgICBUb2tlbiBnZXRDaGlsZChpbnQgaW5kZXgpIHsKLSAgICAgICAgICAgIHJldHVybiB0aGlzLmNoaWxkOwotICAgICAgICB9Ci0KLSAgICAgICAgaW50IGdldFBhcmVuTnVtYmVyKCkgewotICAgICAgICAgICAgcmV0dXJuIHRoaXMucGFyZW5udW1iZXI7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKGludCBvcHRpb25zKSB7Ci0gICAgICAgICAgICBTdHJpbmcgcmV0ID0gbnVsbDsKLSAgICAgICAgICAgIHN3aXRjaCAodGhpcy50eXBlKSB7Ci0gICAgICAgICAgICAgIGNhc2UgUEFSRU46Ci0gICAgICAgICAgICAgICAgaWYgKHRoaXMucGFyZW5udW1iZXIgPT0gMCkgewotICAgICAgICAgICAgICAgICAgICByZXQgPSAiKD86Iit0aGlzLmNoaWxkLnRvU3RyaW5nKG9wdGlvbnMpKyIpIjsKLSAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICByZXQgPSAiKCIrdGhpcy5jaGlsZC50b1N0cmluZyhvcHRpb25zKSsiKSI7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgICAgICAgIGNhc2UgTE9PS0FIRUFEOgotICAgICAgICAgICAgICAgIHJldCA9ICIoPz0iK3RoaXMuY2hpbGQudG9TdHJpbmcob3B0aW9ucykrIikiOwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICBjYXNlIE5FR0FUSVZFTE9PS0FIRUFEOgotICAgICAgICAgICAgICAgIHJldCA9ICIoPyEiK3RoaXMuY2hpbGQudG9TdHJpbmcob3B0aW9ucykrIikiOwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICBjYXNlIExPT0tCRUhJTkQ6Ci0gICAgICAgICAgICAgICAgcmV0ID0gIig/PD0iK3RoaXMuY2hpbGQudG9TdHJpbmcob3B0aW9ucykrIikiOwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICBjYXNlIE5FR0FUSVZFTE9PS0JFSElORDoKLSAgICAgICAgICAgICAgICByZXQgPSAiKD88ISIrdGhpcy5jaGlsZC50b1N0cmluZyhvcHRpb25zKSsiKSI7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgIGNhc2UgSU5ERVBFTkRFTlQ6Ci0gICAgICAgICAgICAgICAgcmV0ID0gIig/PiIrdGhpcy5jaGlsZC50b1N0cmluZyhvcHRpb25zKSsiKSI7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gcmV0OwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogKD8oY29uZGl0aW9uKXllcy1wYXR0ZXJufG5vLXBhdHRlcm4pCi0gICAgICovCi0gICAgc3RhdGljIGNsYXNzIENvbmRpdGlvblRva2VuIGV4dGVuZHMgVG9rZW4gaW1wbGVtZW50cyBqYXZhLmlvLlNlcmlhbGl6YWJsZSB7Ci0KLSAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNDM1Mzc2NTI3NzkxMDU5NDQxMUw7Ci0KLSAgICAgICAgZmluYWwgaW50IHJlZk51bWJlcjsKLSAgICAgICAgZmluYWwgVG9rZW4gY29uZGl0aW9uOwotICAgICAgICBmaW5hbCBUb2tlbiB5ZXM7Ci0gICAgICAgIGZpbmFsIFRva2VuIG5vOwotICAgICAgICBDb25kaXRpb25Ub2tlbihpbnQgcmVmbm8sIFRva2VuIGNvbmQsIFRva2VuIHllc3BhdCwgVG9rZW4gbm9wYXQpIHsKLSAgICAgICAgICAgIHN1cGVyKFRva2VuLkNPTkRJVElPTik7Ci0gICAgICAgICAgICB0aGlzLnJlZk51bWJlciA9IHJlZm5vOwotICAgICAgICAgICAgdGhpcy5jb25kaXRpb24gPSBjb25kOwotICAgICAgICAgICAgdGhpcy55ZXMgPSB5ZXNwYXQ7Ci0gICAgICAgICAgICB0aGlzLm5vID0gbm9wYXQ7Ci0gICAgICAgIH0KLSAgICAgICAgaW50IHNpemUoKSB7Ci0gICAgICAgICAgICByZXR1cm4gdGhpcy5ubyA9PSBudWxsID8gMSA6IDI7Ci0gICAgICAgIH0KLSAgICAgICAgVG9rZW4gZ2V0Q2hpbGQoaW50IGluZGV4KSB7Ci0gICAgICAgICAgICBpZiAoaW5kZXggPT0gMCkgIHJldHVybiB0aGlzLnllczsKLSAgICAgICAgICAgIGlmIChpbmRleCA9PSAxKSAgcmV0dXJuIHRoaXMubm87Ci0gICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiSW50ZXJuYWwgRXJyb3I6ICIraW5kZXgpOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZyhpbnQgb3B0aW9ucykgewotICAgICAgICAgICAgU3RyaW5nIHJldDsKLSAgICAgICAgICAgIGlmIChyZWZOdW1iZXIgPiAwKSB7Ci0gICAgICAgICAgICAgICAgcmV0ID0gIig/KCIrcmVmTnVtYmVyKyIpIjsKLSAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5jb25kaXRpb24udHlwZSA9PSBUb2tlbi5BTkNIT1IpIHsKLSAgICAgICAgICAgICAgICByZXQgPSAiKD8oIit0aGlzLmNvbmRpdGlvbisiKSI7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIHJldCA9ICIoPyIrdGhpcy5jb25kaXRpb247Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmICh0aGlzLm5vID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICByZXQgKz0gdGhpcy55ZXMrIikiOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICByZXQgKz0gdGhpcy55ZXMrInwiK3RoaXMubm8rIikiOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIHJldDsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIChpbXMtaW1zOiAuLi4uICkKLSAgICAgKi8KLSAgICBzdGF0aWMgY2xhc3MgTW9kaWZpZXJUb2tlbiBleHRlbmRzIFRva2VuIGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUgewotCi0gICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC05MTE0NTM2NTU5Njk2NDgwMzU2TDsKLQotICAgICAgICBmaW5hbCBUb2tlbiBjaGlsZDsKLSAgICAgICAgZmluYWwgaW50IGFkZDsKLSAgICAgICAgZmluYWwgaW50IG1hc2s7Ci0KLSAgICAgICAgTW9kaWZpZXJUb2tlbihUb2tlbiB0b2ssIGludCBhZGQsIGludCBtYXNrKSB7Ci0gICAgICAgICAgICBzdXBlcihUb2tlbi5NT0RJRklFUkdST1VQKTsKLSAgICAgICAgICAgIHRoaXMuY2hpbGQgPSB0b2s7Ci0gICAgICAgICAgICB0aGlzLmFkZCA9IGFkZDsKLSAgICAgICAgICAgIHRoaXMubWFzayA9IG1hc2s7Ci0gICAgICAgIH0KLQotICAgICAgICBpbnQgc2l6ZSgpIHsKLSAgICAgICAgICAgIHJldHVybiAxOwotICAgICAgICB9Ci0gICAgICAgIFRva2VuIGdldENoaWxkKGludCBpbmRleCkgewotICAgICAgICAgICAgcmV0dXJuIHRoaXMuY2hpbGQ7Ci0gICAgICAgIH0KLQotICAgICAgICBpbnQgZ2V0T3B0aW9ucygpIHsKLSAgICAgICAgICAgIHJldHVybiB0aGlzLmFkZDsKLSAgICAgICAgfQotICAgICAgICBpbnQgZ2V0T3B0aW9uc01hc2soKSB7Ci0gICAgICAgICAgICByZXR1cm4gdGhpcy5tYXNrOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZyhpbnQgb3B0aW9ucykgewotICAgICAgICAgICAgcmV0dXJuICIoPyIKLSAgICAgICAgICAgICAgICArKHRoaXMuYWRkID09IDAgPyAiIiA6IFJFVXRpbC5jcmVhdGVPcHRpb25TdHJpbmcodGhpcy5hZGQpKQotICAgICAgICAgICAgICAgICsodGhpcy5tYXNrID09IDAgPyAiIiA6IFJFVXRpbC5jcmVhdGVPcHRpb25TdHJpbmcodGhpcy5tYXNrKSkKLSAgICAgICAgICAgICAgICArIjoiCi0gICAgICAgICAgICAgICAgK3RoaXMuY2hpbGQudG9TdHJpbmcob3B0aW9ucykKLSAgICAgICAgICAgICAgICArIikiOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBjbGFzcyByZXByZXNlbnRzIGEgbm9kZSBpbiBwYXJzZSB0cmVlLgotICAgICAqIGZvciBVTklPTiBvciBDT05DQVQuCi0gICAgICovCi0gICAgc3RhdGljIGNsYXNzIFVuaW9uVG9rZW4gZXh0ZW5kcyBUb2tlbiBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKLQotICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMjU2ODg0Mzk0NTk4OTQ4OTg2MUw7Ci0KLSAgICAgICAgTGlzdDxUb2tlbj4gY2hpbGRyZW47Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIEBzZXJpYWxGaWVsZCBjaGlsZHJlbiBWZWN0b3IgY2hpbGRyZW4KLSAgICAgICAgICovCi0gICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIE9iamVjdFN0cmVhbUZpZWxkW10gc2VyaWFsUGVyc2lzdGVudEZpZWxkcyA9Ci0gICAgICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGRbXSB7Ci0gICAgICAgICAgICAgICAgbmV3IE9iamVjdFN0cmVhbUZpZWxkKCJjaGlsZHJlbiIsIFZlY3Rvci5jbGFzcyksCi0gICAgICAgICAgICB9OwotCi0gICAgICAgIFVuaW9uVG9rZW4oaW50IHR5cGUpIHsKLSAgICAgICAgICAgIHN1cGVyKHR5cGUpOwotICAgICAgICB9Ci0KLSAgICAgICAgQE92ZXJyaWRlCi0gICAgICAgIHZvaWQgYWRkQ2hpbGQoVG9rZW4gdG9rKSB7Ci0gICAgICAgICAgICBpZiAodG9rID09IG51bGwpICByZXR1cm47Ci0gICAgICAgICAgICBpZiAodGhpcy5jaGlsZHJlbiA9PSBudWxsKSAgdGhpcy5jaGlsZHJlbiA9IG5ldyBBcnJheUxpc3Q8PigpOwotICAgICAgICAgICAgaWYgKHRoaXMudHlwZSA9PSBVTklPTikgewotICAgICAgICAgICAgICAgIHRoaXMuY2hpbGRyZW4uYWRkKHRvayk7Ci0gICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhpcyBpcyBDT05DQVQsIGFuZCBuZXcgY2hpbGQgaXMgQ09OQ0FULgotICAgICAgICAgICAgaWYgKHRvay50eXBlID09IENPTkNBVCkgewotICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyAgaSA8IHRvay5zaXplKCk7ICBpICsrKQotICAgICAgICAgICAgICAgICAgICB0aGlzLmFkZENoaWxkKHRvay5nZXRDaGlsZChpKSk7IC8vIFJlY3Vyc2lvbgotICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGludCBzaXplID0gdGhpcy5jaGlsZHJlbi5zaXplKCk7Ci0gICAgICAgICAgICBpZiAoc2l6ZSA9PSAwKSB7Ci0gICAgICAgICAgICAgICAgdGhpcy5jaGlsZHJlbi5hZGQodG9rKTsKLSAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBUb2tlbiBwcmV2aW91cyA9IHRoaXMuY2hpbGRyZW4uZ2V0KHNpemUgLSAxKTsKLSAgICAgICAgICAgIGlmICghKChwcmV2aW91cy50eXBlID09IENIQVIgfHwgcHJldmlvdXMudHlwZSA9PSBTVFJJTkcpCi0gICAgICAgICAgICAgICAgICAmJiAodG9rLnR5cGUgPT0gQ0hBUiB8fCB0b2sudHlwZSA9PSBTVFJJTkcpKSkgewotICAgICAgICAgICAgICAgIHRoaXMuY2hpbGRyZW4uYWRkKHRvayk7Ci0gICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvL1N5c3RlbS5lcnIucHJpbnRsbigiTWVyZ2UgJyIrcHJldmlvdXMrIicgYW5kICciK3RvaysiJy4iKTsKLQotICAgICAgICAgICAgU3RyaW5nQnVpbGRlciBidWZmZXI7Ci0gICAgICAgICAgICBpbnQgbmV4dE1heExlbmd0aCA9ICh0b2sudHlwZSA9PSBDSEFSID8gMiA6IHRvay5nZXRTdHJpbmcoKS5sZW5ndGgoKSk7Ci0gICAgICAgICAgICBpZiAocHJldmlvdXMudHlwZSA9PSBDSEFSKSB7ICAgICAgICAvLyBSZXBsYWNlIHByZXZpb3VzIHRva2VuIGJ5IFNUUklORwotICAgICAgICAgICAgICAgIGJ1ZmZlciA9IG5ldyBTdHJpbmdCdWlsZGVyKDIgKyBuZXh0TWF4TGVuZ3RoKTsKLSAgICAgICAgICAgICAgICBpbnQgY2ggPSBwcmV2aW91cy5nZXRDaGFyKCk7Ci0gICAgICAgICAgICAgICAgaWYgKGNoID49IDB4MTAwMDApCi0gICAgICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoUkVVdGlsLmRlY29tcG9zZVRvU3Vycm9nYXRlcyhjaCkpOwotICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgoY2hhciljaCk7Ci0gICAgICAgICAgICAgICAgcHJldmlvdXMgPSBUb2tlbi5jcmVhdGVTdHJpbmcobnVsbCk7Ci0gICAgICAgICAgICAgICAgdGhpcy5jaGlsZHJlbi5zZXQoc2l6ZSAtIDEsIHByZXZpb3VzKTsKLSAgICAgICAgICAgIH0gZWxzZSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNUUklORwotICAgICAgICAgICAgICAgIGJ1ZmZlciA9IG5ldyBTdHJpbmdCdWlsZGVyKHByZXZpb3VzLmdldFN0cmluZygpLmxlbmd0aCgpICsgbmV4dE1heExlbmd0aCk7Ci0gICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZChwcmV2aW91cy5nZXRTdHJpbmcoKSk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmICh0b2sudHlwZSA9PSBDSEFSKSB7Ci0gICAgICAgICAgICAgICAgaW50IGNoID0gdG9rLmdldENoYXIoKTsKLSAgICAgICAgICAgICAgICBpZiAoY2ggPj0gMHgxMDAwMCkKLSAgICAgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZChSRVV0aWwuZGVjb21wb3NlVG9TdXJyb2dhdGVzKGNoKSk7Ci0gICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKChjaGFyKWNoKTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCh0b2suZ2V0U3RyaW5nKCkpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAoKFN0cmluZ1Rva2VuKXByZXZpb3VzKS5zdHJpbmcgPSBuZXcgU3RyaW5nKGJ1ZmZlcik7Ci0gICAgICAgIH0KLQotICAgICAgICBAT3ZlcnJpZGUKLSAgICAgICAgaW50IHNpemUoKSB7Ci0gICAgICAgICAgICByZXR1cm4gdGhpcy5jaGlsZHJlbiA9PSBudWxsID8gMCA6IHRoaXMuY2hpbGRyZW4uc2l6ZSgpOwotICAgICAgICB9Ci0gICAgICAgIEBPdmVycmlkZQotICAgICAgICBUb2tlbiBnZXRDaGlsZChpbnQgaW5kZXgpIHsKLSAgICAgICAgICAgIHJldHVybiB0aGlzLmNoaWxkcmVuLmdldChpbmRleCk7Ci0gICAgICAgIH0KLQotICAgICAgICBAT3ZlcnJpZGUKLSAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZyhpbnQgb3B0aW9ucykgewotICAgICAgICAgICAgU3RyaW5nIHJldDsKLSAgICAgICAgICAgIGlmICh0aGlzLnR5cGUgPT0gQ09OQ0FUKSB7Ci0gICAgICAgICAgICAgICAgaWYgKHRoaXMuY2hpbGRyZW4uc2l6ZSgpID09IDIpIHsKLSAgICAgICAgICAgICAgICAgICAgVG9rZW4gY2ggPSB0aGlzLmdldENoaWxkKDApOwotICAgICAgICAgICAgICAgICAgICBUb2tlbiBjaDIgPSB0aGlzLmdldENoaWxkKDEpOwotICAgICAgICAgICAgICAgICAgICBpZiAoY2gyLnR5cGUgPT0gQ0xPU1VSRSAmJiBjaDIuZ2V0Q2hpbGQoMCkgPT0gY2gpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldCA9IGNoLnRvU3RyaW5nKG9wdGlvbnMpKyIrIjsKLSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjaDIudHlwZSA9PSBOT05HUkVFRFlDTE9TVVJFICYmIGNoMi5nZXRDaGlsZCgwKSA9PSBjaCkgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0ID0gY2gudG9TdHJpbmcob3B0aW9ucykrIis/IjsKLSAgICAgICAgICAgICAgICAgICAgfSBlbHNlCi0gICAgICAgICAgICAgICAgICAgICAgICByZXQgPSBjaC50b1N0cmluZyhvcHRpb25zKStjaDIudG9TdHJpbmcob3B0aW9ucyk7Ci0gICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7Ci0gICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyAgaSA8IHRoaXMuY2hpbGRyZW4uc2l6ZSgpOyAgaSArKykgewotICAgICAgICAgICAgICAgICAgICAgICAgc2IuYXBwZW5kKCgoVG9rZW4pdGhpcy5jaGlsZHJlbi5nZXQoaSkpLnRvU3RyaW5nKG9wdGlvbnMpKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICByZXQgPSBuZXcgU3RyaW5nKHNiKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHJldDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmICh0aGlzLmNoaWxkcmVuLnNpemUoKSA9PSAyICYmIHRoaXMuZ2V0Q2hpbGQoMSkudHlwZSA9PSBFTVBUWSkgewotICAgICAgICAgICAgICAgIHJldCA9IHRoaXMuZ2V0Q2hpbGQoMCkudG9TdHJpbmcob3B0aW9ucykrIj8iOwotICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLmNoaWxkcmVuLnNpemUoKSA9PSAyCi0gICAgICAgICAgICAgICAgICAgICAgICYmIHRoaXMuZ2V0Q2hpbGQoMCkudHlwZSA9PSBFTVBUWSkgewotICAgICAgICAgICAgICAgIHJldCA9IHRoaXMuZ2V0Q2hpbGQoMSkudG9TdHJpbmcob3B0aW9ucykrIj8/IjsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7Ci0gICAgICAgICAgICAgICAgc2IuYXBwZW5kKCh0aGlzLmNoaWxkcmVuLmdldCgwKSkudG9TdHJpbmcob3B0aW9ucykpOwotICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAxOyAgaSA8IHRoaXMuY2hpbGRyZW4uc2l6ZSgpOyAgaSArKykgewotICAgICAgICAgICAgICAgICAgICBzYi5hcHBlbmQoKGNoYXIpJ3wnKTsKLSAgICAgICAgICAgICAgICAgICAgc2IuYXBwZW5kKCh0aGlzLmNoaWxkcmVuLmdldChpKSkudG9TdHJpbmcob3B0aW9ucykpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICByZXQgPSBuZXcgU3RyaW5nKHNiKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiByZXQ7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogQHNlcmlhbERhdGEgU2VyaWFsaXplZCBmaWVsZHMuIENvbnZlcnQgdGhlIExpc3QgdG8gVmVjdG9yIGZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5LgotICAgICAgICAgKi8KLSAgICAgICAgcHJpdmF0ZSB2b2lkIHdyaXRlT2JqZWN0KE9iamVjdE91dHB1dFN0cmVhbSBvdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgICAgICAvLyBDb252ZXJ0IExpc3QgdG8gVmVjdG9yCi0gICAgICAgICAgICBWZWN0b3I8VG9rZW4+IHZDaGlsZHJlbiA9IChjaGlsZHJlbiA9PSBudWxsKT8gbnVsbCA6IG5ldyBWZWN0b3I8PihjaGlsZHJlbik7Ci0KLSAgICAgICAgICAgIC8vIFdyaXRlIHNlcmlhbGl6ZWQgZmllbGRzCi0gICAgICAgICAgICBPYmplY3RPdXRwdXRTdHJlYW0uUHV0RmllbGQgcGYgPSBvdXQucHV0RmllbGRzKCk7Ci0gICAgICAgICAgICBwZi5wdXQoImNoaWxkcmVuIiwgdkNoaWxkcmVuKTsKLSAgICAgICAgICAgIG91dC53cml0ZUZpZWxkcygpOwotICAgICAgICB9Ci0KLSAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCi0gICAgICAgIHByaXZhdGUgdm9pZCByZWFkT2JqZWN0KE9iamVjdElucHV0U3RyZWFtIGluKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICAvLyBXZSBoYXZlIHRvIHJlYWQgc2VyaWFsaXplZCBmaWVsZHMgZmlyc3QuCi0gICAgICAgICAgICBPYmplY3RJbnB1dFN0cmVhbS5HZXRGaWVsZCBnZiA9IGluLnJlYWRGaWVsZHMoKTsKLSAgICAgICAgICAgIFZlY3RvcjxUb2tlbj4gdkNoaWxkcmVuID0gKFZlY3RvcjxUb2tlbj4pZ2YuZ2V0KCJjaGlsZHJlbiIsIG51bGwpOwotCi0gICAgICAgICAgICAvL2NvbnZlcnQgVmVjdG9yIGJhY2sgdG8gTGlzdAotICAgICAgICAgICAgaWYgKHZDaGlsZHJlbiAhPSBudWxsKSBjaGlsZHJlbiA9IG5ldyBBcnJheUxpc3Q8Pih2Q2hpbGRyZW4pOwotICAgICAgICB9Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cGF0aC9yZWdleC9tZXNzYWdlLnByb3BlcnRpZXMgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hwYXRoL3JlZ2V4L21lc3NhZ2UucHJvcGVydGllcwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDFmNDc1Yi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hwYXRoL3JlZ2V4L21lc3NhZ2UucHJvcGVydGllcworKysgL2Rldi9udWxsCkBAIC0xLDQxICswLDAgQEAKLXBhcnNlci5wYXJzZS4xPVdyb25nIGNoYXJhY3Rlci4KLXBhcnNlci5wYXJzZS4yPUludmFsaWQgcmVmZXJlbmNlIG51bWJlci4KLXBhcnNlci5uZXh0LjE9QSBjaGFyYWN0ZXIgaXMgcmVxdWlyZWQgYWZ0ZXIgXFwuCi1wYXJzZXIubmV4dC4yPSc/JyBpcyBub3QgZXhwZWN0ZWQuICAnKD86JyBvciAnKD89JyBvciAnKD8hJyBvciAnKD88JyBvciAnKD8jJyBvciAnKD8+Jz8KLXBhcnNlci5uZXh0LjM9Jyg/PD0nIG9yICcoPzwhJyBpcyBleHBlY3RlZC4KLXBhcnNlci5uZXh0LjQ9QSBjb21tZW50IGlzIG5vdCB0ZXJtaW5hdGVkLgotcGFyc2VyLmZhY3Rvci4xPScpJyBpcyBleHBlY3RlZC4KLXBhcnNlci5mYWN0b3IuMj1VbmV4cGVjdGVkIGVuZCBvZiB0aGUgcGF0dGVybiBpbiBhIG1vZGlmaWVyIGdyb3VwLgotcGFyc2VyLmZhY3Rvci4zPSc6JyBpcyBleHBlY3RlZC4KLXBhcnNlci5mYWN0b3IuND1VbmV4cGVjdGVkIGVuZCBvZiB0aGUgcGF0dGVybiBpbiBhIGNvbmRpdGlvbmFsIGdyb3VwLgotcGFyc2VyLmZhY3Rvci41PUEgYmFjayByZWZlcmVuY2Ugb3IgYW4gYW5jaG9yIG9yIGEgbG9va2FoZWFkIG9yIGEgbG9va2JlaGluZCBpcyBleHBlY3RlZCBpbiBhIGNvbmRpdGlvbmFsIHBhdHRlcm4uCi1wYXJzZXIuZmFjdG9yLjY9VGhlcmUgYXJlIG1vcmUgdGhhbiB0aHJlZSBjaG9pY2VzIGluIGEgY29uZGl0aW9uYWwgZ3JvdXAuCi1wYXJzZXIuYXRvbS4xPUEgY2hhcmFjdGVyIGluIFUrMDA0MC1VKzAwNWYgbXVzdCBmb2xsb3cgXFxjLgotcGFyc2VyLmF0b20uMj1BICd7JyBpcyByZXF1aXJlZCBiZWZvcmUgYSBjaGFyYWN0ZXIgY2F0ZWdvcnkuCi1wYXJzZXIuYXRvbS4zPUEgcHJvcGVydHkgbmFtZSBpcyBub3QgY2xvc2VkIGJ5ICd9Jy4KLXBhcnNlci5hdG9tLjQ9VW5leHBlY3RlZCBtZXRhIGNoYXJhY3Rlci4KLXBhcnNlci5hdG9tLjU9VW5rbm93biBwcm9wZXJ0eS4KLXBhcnNlci5jYy4xPUEgUE9TSVggY2hhcmFjdGVyIGNsYXNzIG11c3QgYmUgY2xvc2VkIGJ5ICc6XScuCi1wYXJzZXIuY2MuMj1VbmV4cGVjdGVkIGVuZCBvZiB0aGUgcGF0dGVybiBpbiBhIGNoYXJhY3RlciBjbGFzcy4KLXBhcnNlci5jYy4zPVVua25vd24gbmFtZSBmb3IgYSBQT1NJWCBjaGFyYWN0ZXIgY2xhc3MuCi1wYXJzZXIuY2MuND0nLScgaXMgaW52YWxpZCBoZXJlLgotcGFyc2VyLmNjLjU9J10nIGlzIGV4cGVjdGVkLgotcGFyc2VyLmNjLjY9J1snIGlzIGludmFsaWQgaW4gYSBjaGFyYWN0ZXIgY2xhc3MuICBXcml0ZSAnXFxbJy4KLXBhcnNlci5jYy43PSddJyBpcyBpbnZhbGlkIGluIGEgY2hhcmFjdGVyIGNsYXNzLiAgV3JpdGUgJ1xcXScuCi1wYXJzZXIuY2MuOD0nLScgaXMgYW4gaW52YWxpZCBjaGFyYWN0ZXIgcmFuZ2UuIFdyaXRlICdcXC0nLgotcGFyc2VyLm9wZS4xPSdbJyBpcyBleHBlY3RlZC4KLXBhcnNlci5vcGUuMj0nKScgb3IgJy1bJyBvciAnK1snIG9yICcmWycgaXMgZXhwZWN0ZWQuCi1wYXJzZXIub3BlLjM9VGhlIHJhbmdlIGVuZCBjb2RlIHBvaW50IGlzIGxlc3MgdGhhbiB0aGUgc3RhcnQgY29kZSBwb2ludC4KLXBhcnNlci5kZXNjYXBlLjE9SW52YWxpZCBVbmljb2RlIGhleCBub3RhdGlvbi4KLXBhcnNlci5kZXNjYXBlLjI9T3ZlcmZsb3cgaW4gYSBoZXggbm90YXRpb24uCi1wYXJzZXIuZGVzY2FwZS4zPSdcXHh7JyBtdXN0IGJlIGNsb3NlZCBieSAnfScuCi1wYXJzZXIuZGVzY2FwZS40PUludmFsaWQgVW5pY29kZSBjb2RlIHBvaW50LgotcGFyc2VyLmRlc2NhcGUuNT1BbiBhbmNob3IgbXVzdCBub3QgYmUgaGVyZS4KLXBhcnNlci5wcm9jZXNzLjE9VGhpcyBleHByZXNzaW9uIGlzIG5vdCBzdXBwb3J0ZWQgaW4gdGhlIGN1cnJlbnQgb3B0aW9uIHNldHRpbmcuCi1wYXJzZXIucXVhbnRpZmllci4xPUludmFsaWQgcXVhbnRpZmllci4gQSBkaWdpdCBpcyBleHBlY3RlZC4KLXBhcnNlci5xdWFudGlmaWVyLjI9SW52YWxpZCBxdWFudGlmaWVyLiBJbnZhbGlkIHF1YW50aXR5IG9yIGEgJ30nIGlzIG1pc3NpbmcuCi1wYXJzZXIucXVhbnRpZmllci4zPUludmFsaWQgcXVhbnRpZmllci4gQSBkaWdpdCBvciAnfScgaXMgZXhwZWN0ZWQuCi1wYXJzZXIucXVhbnRpZmllci40PUludmFsaWQgcXVhbnRpZmllci4gQSBtaW4gcXVhbnRpdHkgbXVzdCBiZSA8PSBhIG1heCBxdWFudGl0eS4KLXBhcnNlci5xdWFudGlmaWVyLjU9SW52YWxpZCBxdWFudGlmaWVyLiBBIHF1YW50aXR5IHZhbHVlIG92ZXJmbG93LgotbnVsbAotbnVsbApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cGF0aC9yZWdleC9tZXNzYWdlX2RlLnByb3BlcnRpZXMgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hwYXRoL3JlZ2V4L21lc3NhZ2VfZGUucHJvcGVydGllcwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYWFiNDg5OC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hwYXRoL3JlZ2V4L21lc3NhZ2VfZGUucHJvcGVydGllcworKysgL2Rldi9udWxsCkBAIC0xLDQxICswLDAgQEAKLXBhcnNlci5wYXJzZS4xPUZhbHNjaGVzIFplaWNoZW4uCi1wYXJzZXIucGFyc2UuMj1VbmdcdTAwRkNsdGlnZSBSZWZlcmVuem51bW1lci4KLXBhcnNlci5uZXh0LjE9TmFjaCBcXCBpc3QgZWluIFplaWNoZW4gZXJmb3JkZXJsaWNoLgotcGFyc2VyLm5leHQuMj0nPycgd2lyZCBuaWNodCBlcndhcnRldC4gICcoPzonIG9kZXIgJyg/PScgb2RlciAnKD8hJyBvZGVyICcoPzwnIG9kZXIgJyg/Iycgb2RlciAnKD8+Jz8KLXBhcnNlci5uZXh0LjM9Jyg/PD0nIG9kZXIgJyg/PCEnIHdpcmQgZXJ3YXJ0ZXQuCi1wYXJzZXIubmV4dC40PUVpbiBLb21tZW50YXIgaXN0IG5pY2h0IGFiZ2VzY2hsb3NzZW4uCi1wYXJzZXIuZmFjdG9yLjE9JyknIHdpcmQgZXJ3YXJ0ZXQuCi1wYXJzZXIuZmFjdG9yLjI9VW5lcndhcnRldGVzIEVuZGUgZGVzIE11c3RlcnMgaW4gZWluZXIgTW9kaWZpZXItR3J1cHBlLgotcGFyc2VyLmZhY3Rvci4zPSc6JyB3aXJkIGVyd2FydGV0LgotcGFyc2VyLmZhY3Rvci40PVVuZXJ3YXJ0ZXRlcyBFbmRlIGRlcyBNdXN0ZXJzIGluIGVpbmVyIEJlZGluZ3VuZ3NncnVwcGUuCi1wYXJzZXIuZmFjdG9yLjU9RWluZSBCYWNrLVJlZmVyZW56LCBlaW4gQW5rZXIsIGVpbiBMb29rYWhlYWQgb2RlciBlaW4gTG9va2JlaGluZCB3aXJkIGluIGVpbmVtIEJlZGluZ3VuZ3NtdXN0ZXIgZXJ3YXJ0ZXQKLXBhcnNlci5mYWN0b3IuNj1FcyBnaWJ0IG1laHIgYWxzIGRyZWkgQXVzd2FobG1cdTAwRjZnbGljaGtlaXRlbiBpbiBlaW5lciBCZWRpbmd1bmdzZ3J1cHBlLgotcGFyc2VyLmF0b20uMT1FaW4gWmVpY2hlbiBpbiBVKzAwNDAtVSswMDVmIG11c3MgYXVmIFxcYyBmb2xnZW4uCi1wYXJzZXIuYXRvbS4yPUVpbiAneycgaXN0IHZvciBlaW5lciBaZWljaGVua2F0ZWdvcmllIGVyZm9yZGVybGljaC4KLXBhcnNlci5hdG9tLjM9RWluIEVpZ2Vuc2NoYWZ0c25hbWUgbmljaHQgd2lyZCBkdXJjaCAnfScgYWJnZXNjaGxvc3Nlbi4KLXBhcnNlci5hdG9tLjQ9VW5lcndhcnRldGVzIE1ldGF6ZWljaGVuLgotcGFyc2VyLmF0b20uNT1VbmJla2FubnRlIEVpZ2Vuc2NoYWZ0LgotcGFyc2VyLmNjLjE9RWluZSBQT1NJWC1aZWljaGVua2xhc3NlIG11c3MgZHVyY2ggJzpdJyBhYmdlc2NobG9zc2VuIHdlcmRlbi4KLXBhcnNlci5jYy4yPVVuZXJ3YXJ0ZXRlcyBFbmRlIGRlcyBNdXN0ZXJzIGluIGVpbmVyIFplaWNoZW5rbGFzc2UuCi1wYXJzZXIuY2MuMz1VbmJla2FubnRlciBOYW1lIGZcdTAwRkNyIGVpbmUgUE9TSVgtWmVpY2hlbmtsYXNzZS4KLXBhcnNlci5jYy40PSctJyBpc3QgaGllciB1bmdcdTAwRkNsdGlnLgotcGFyc2VyLmNjLjU9J10nIHdpcmQgZXJ3YXJ0ZXQuCi1wYXJzZXIuY2MuNj0nWycgaXN0IGluIGVpbmVyIFplaWNoZW5rbGFzc2UgdW5nXHUwMEZDbHRpZy4gU2NocmVpYmVuIFNpZSAnXFxbJy4KLXBhcnNlci5jYy43PSddJyBpc3QgaW4gZWluZXIgWmVpY2hlbmtsYXNzZSB1bmdcdTAwRkNsdGlnLiBTY2hyZWliZW4gU2llICdcXF0nLgotcGFyc2VyLmNjLjg9Jy0nIGlzdCBlaW4gdW5nXHUwMEZDbHRpZ2VyIFplaWNoZW5iZXJlaWNoLiBTY2hyZWliZW4gU2llICdcXC0nLgotcGFyc2VyLm9wZS4xPSdbJyB3aXJkIGVyd2FydGV0LgotcGFyc2VyLm9wZS4yPScpJyBvZGVyICctWycgb2RlciAnK1snIG9kZXIgJyZbJyB3aXJkIGVyd2FydGV0LgotcGFyc2VyLm9wZS4zPURlciBFbmRjb2RlcHVua3QgZGVzIEJlcmVpY2hzIGlzdCBrbGVpbmVyIGFscyBkZXIgU3RhcnRjb2RlcHVua3QuCi1wYXJzZXIuZGVzY2FwZS4xPVVuZ1x1MDBGQ2x0aWdlIFVuaWNvZGUtSGV4LU5vdGF0aW9uLgotcGFyc2VyLmRlc2NhcGUuMj1cdTAwRENiZXJsYXVmIGluIGVpbmVyIEhleC1Ob3RhdGlvbi4KLXBhcnNlci5kZXNjYXBlLjM9J1xceHsnIG11c3MgZHVyY2ggJ30nIGFiZ2VzY2hsb3NzZW4gd2VyZGVuLgotcGFyc2VyLmRlc2NhcGUuND1VbmdcdTAwRkNsdGlnZXIgVW5pY29kZS1Db2RlcHVua3QuCi1wYXJzZXIuZGVzY2FwZS41PUVpbiBBbmtlciBkYXJmIG5pY2h0IGhpZXIgc2Vpbi4KLXBhcnNlci5wcm9jZXNzLjE9RGllc2VyIEF1c2RydWNrIHdpcmQgaW4gZGVyIGFrdHVlbGxlbiBPcHRpb25zZWluc3RlbGx1bmcgbmljaHQgdW50ZXJzdFx1MDBGQ3R6dC4KLXBhcnNlci5xdWFudGlmaWVyLjE9VW5nXHUwMEZDbHRpZ2VyIFF1YW50aWZpemllcmVyLiBFaW5lIFppZmZlciB3aXJkIGVyd2FydGV0LgotcGFyc2VyLnF1YW50aWZpZXIuMj1VbmdcdTAwRkNsdGlnZXIgUXVhbnRpZml6aWVyZXIuIFVuZ1x1MDBGQ2x0aWdlIE1lbmdlLCBvZGVyIGVpbiAnfScgZmVobHQuCi1wYXJzZXIucXVhbnRpZmllci4zPVVuZ1x1MDBGQ2x0aWdlciBRdWFudGlmaXppZXJlci4gRWluZSBTdGVsbGUgb2RlciAnfScgd2lyZCBlcndhcnRldC4KLXBhcnNlci5xdWFudGlmaWVyLjQ9VW5nXHUwMEZDbHRpZ2VyIFF1YW50aWZpemllcmVyLiBNaW5kZXN0bWVuZ2UgbXVzcyA8PSBNYXhpbWFsbWVuZ2Ugc2Vpbi4KLXBhcnNlci5xdWFudGlmaWVyLjU9VW5nXHUwMEZDbHRpZ2VyIFF1YW50aWZpemllcmVyLiBFaW4gTWVuZ2Vud2VydFx1MDBGQ2JlcmxhdWYuCi1udWxsCi1udWxsCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hwYXRoL3JlZ2V4L21lc3NhZ2VfZXMucHJvcGVydGllcyBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHBhdGgvcmVnZXgvbWVzc2FnZV9lcy5wcm9wZXJ0aWVzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiYjZlNmJiLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHBhdGgvcmVnZXgvbWVzc2FnZV9lcy5wcm9wZXJ0aWVzCisrKyAvZGV2L251bGwKQEAgLTEsNDEgKzAsMCBAQAotcGFyc2VyLnBhcnNlLjE9Q2FyXHUwMEUxY3RlciBpbmNvcnJlY3RvLgotcGFyc2VyLnBhcnNlLjI9Tlx1MDBGQW1lcm8gZGUgcmVmZXJlbmNpYSBubyB2XHUwMEUxbGlkby4KLXBhcnNlci5uZXh0LjE9RXMgbmVjZXNhcmlvIHVuIGNhclx1MDBFMWN0ZXIgZGVzcHVcdTAwRTlzIGRlIFxcLgotcGFyc2VyLm5leHQuMj1ObyBzZSBlc3BlcmFiYSAnPycuICcoPzonLCAnKD89JywgJyg/IScsICcoPzwnLCAnKD8jJyBvICcoPz4nPwotcGFyc2VyLm5leHQuMz1TZSBlc3BlcmFiYSAnKD88PScgbyAnKD88IScuCi1wYXJzZXIubmV4dC40PVVuIGNvbWVudGFyaW8gbm8gZXN0XHUwMEUxIHRlcm1pbmFkby4KLXBhcnNlci5mYWN0b3IuMT1TZSBlc3BlcmFiYSAnKScuCi1wYXJzZXIuZmFjdG9yLjI9RmluIGluZXNwZXJhZG8gZGVsIHBhdHJcdTAwRjNuIGVuIHVuIGdydXBvIGRlIG1vZGlmaWNhZG9yZXMuCi1wYXJzZXIuZmFjdG9yLjM9U2UgZXNwZXJhYmEgJzonLgotcGFyc2VyLmZhY3Rvci40PUZpbiBpbmVzcGVyYWRvIGRlbCBwYXRyXHUwMEYzbiBlbiB1biBncnVwbyBjb25kaWNpb25hbC4KLXBhcnNlci5mYWN0b3IuNT1TZSBlc3BlcmFiYSB1bmEgcmVmZXJlbmNpYSBoYWNpYSBhdHJcdTAwRTFzLCBhbmNsYWplLCBsb29rYWhlYWQgbyBsb29rYmVoaW5kIGVuIHVuIHBhdHJcdTAwRjNuIGNvbmRpY2lvbmFsLgotcGFyc2VyLmZhY3Rvci42PUhheSBtXHUwMEUxcyBkZSB0cmVzIG9wY2lvbmVzIGVuIHVuIGdydXBvIGNvbmRpY2lvbmFsLgotcGFyc2VyLmF0b20uMT1VbiBjYXJcdTAwRTFjdGVyIGVuIFUrMDA0MC1VKzAwNWYgZGViZSBzZWd1aXIgYSBcXGMuCi1wYXJzZXIuYXRvbS4yPVNlIG5lY2VzaXRhICd7JyBhbnRlcyBkZSB1bmEgY2F0ZWdvclx1MDBFRGEgZGUgY2FyXHUwMEUxY3Rlci4KLXBhcnNlci5hdG9tLjM9VW4gbm9tYnJlIGRlIHByb3BpZWRhZCBubyBlc3RcdTAwRTEgY2VycmFkbyBwb3IgJ30nLgotcGFyc2VyLmF0b20uND1NZXRhY2FyXHUwMEUxY3RlciBpbmVzcGVyYWRvLgotcGFyc2VyLmF0b20uNT1Qcm9waWVkYWQgZGVzY29ub2NpZGEuCi1wYXJzZXIuY2MuMT1VbmEgY2xhc2UgZGUgY2FyXHUwMEUxY3RlciBQT1NJWCBkZWJlIGVzdGFyIGNlcnJhZGEgcG9yICc6XScuCi1wYXJzZXIuY2MuMj1GaW4gaW5lc3BlcmFkbyBkZWwgcGF0clx1MDBGM24gZW4gdW5hIGNsYXNlIGRlIGNhclx1MDBFMWN0ZXIuCi1wYXJzZXIuY2MuMz1Ob21icmUgZGVzY29ub2NpZG8gcGFyYSB1bmEgY2xhc2UgZGUgY2FyXHUwMEUxY3RlciBQT1NJWC4KLXBhcnNlci5jYy40PSctJyBubyBlcyB2XHUwMEUxbGlkbyBhcXVcdTAwRUQuCi1wYXJzZXIuY2MuNT1TZSBlc3BlcmFiYSAnXScuCi1wYXJzZXIuY2MuNj0nWycgbm8gZXMgdlx1MDBFMWxpZG8gZW4gdW5hIGNsYXNlIGRlIGNhclx1MDBFMWN0ZXIuIEVzY3JpYmEgJ1xcWycuCi1wYXJzZXIuY2MuNz0nXScgbm8gZXMgdlx1MDBFMWxpZG8gZW4gdW5hIGNsYXNlIGRlIGNhclx1MDBFMWN0ZXIuIEVzY3JpYmEgJ1xcXScuCi1wYXJzZXIuY2MuOD0nLScgbm8gZXMgdW4gcmFuZ28gZGUgY2FyYWN0ZXJlcyB2XHUwMEUxbGlkby4gRXNjcmliYSAnXFwtJy4KLXBhcnNlci5vcGUuMT1TZSBlc3BlcmFiYSAnWycuCi1wYXJzZXIub3BlLjI9U2UgZXNwZXJhYmEgJyknLCAnLVsnLCAnK1snIG8gJyZbJy4KLXBhcnNlci5vcGUuMz1FbCBwdW50byBkZSBjXHUwMEYzZGlnbyBkZSBmaW4gZGUgcmFuZ28gZXMgbWVub3IgcXVlIGVsIHB1bnRvIGRlIGNcdTAwRjNkaWdvIGRlIGluaWNpby4KLXBhcnNlci5kZXNjYXBlLjE9Tm90YWNpXHUwMEYzbiBoZXhhZGVjaW1hbCBVbmljb2RlIG5vIHZcdTAwRTFsaWRhLgotcGFyc2VyLmRlc2NhcGUuMj1EZXNib3JkYW1pZW50byBlbiB1bmEgbm90YWNpXHUwMEYzbiBoZXhhZGVjaW1hbC4KLXBhcnNlci5kZXNjYXBlLjM9J1xceHsnIGRlYmUgZXN0YXIgY2VycmFkbyBwb3IgJ30nLgotcGFyc2VyLmRlc2NhcGUuND1QdW50byBkZSBjXHUwMEYzZGlnbyBVbmljb2RlIG5vIHZcdTAwRTFsaWRvLgotcGFyc2VyLmRlc2NhcGUuNT1ObyBkZWJlIGhhYmVyIHVuIGFuY2xhamUgYXF1XHUwMEVELgotcGFyc2VyLnByb2Nlc3MuMT1Fc3RhIGV4cHJlc2lcdTAwRjNuIG5vIGVzdFx1MDBFMSBzb3BvcnRhZGEgZW4gbGEgY29uZmlndXJhY2lcdTAwRjNuIGRlIGxhIG9wY2lcdTAwRjNuIGFjdHVhbC4KLXBhcnNlci5xdWFudGlmaWVyLjE9Q3VhbnRpZmljYWRvciBubyB2XHUwMEUxbGlkby4gU2UgZXNwZXJhYmEgdW4gZFx1MDBFRGdpdG8uCi1wYXJzZXIucXVhbnRpZmllci4yPUN1YW50aWZpY2Fkb3Igbm8gdlx1MDBFMWxpZG8uIExhIGNhbnRpZGFkIG5vIGVzIHZcdTAwRTFsaWRhIG8gZmFsdGEgJ30nLgotcGFyc2VyLnF1YW50aWZpZXIuMz1DdWFudGlmaWNhZG9yIG5vIHZcdTAwRTFsaWRvLiBTZSBlc3BlcmFiYSB1biBkXHUwMEVEZ2l0byBvICd9Jy4KLXBhcnNlci5xdWFudGlmaWVyLjQ9Q3VhbnRpZmljYWRvciBubyB2XHUwMEUxbGlkby4gVW5hIGNhbnRpZGFkIG1cdTAwRURuaW1hIGRlYmUgc2VyIDw9IHVuYSBjYW50aWRhZCBtXHUwMEUxeGltYS4KLXBhcnNlci5xdWFudGlmaWVyLjU9Q3VhbnRpZmljYWRvciBubyB2XHUwMEUxbGlkby4gRGVzYm9yZGFtaWVudG8gZGUgdW4gdmFsb3IgZGUgY2FudGlkYWQuCi1udWxsCi1udWxsCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hwYXRoL3JlZ2V4L21lc3NhZ2VfZnIucHJvcGVydGllcyBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHBhdGgvcmVnZXgvbWVzc2FnZV9mci5wcm9wZXJ0aWVzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlMjc3OWZlLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHBhdGgvcmVnZXgvbWVzc2FnZV9mci5wcm9wZXJ0aWVzCisrKyAvZGV2L251bGwKQEAgLTEsNDEgKzAsMCBAQAotcGFyc2VyLnBhcnNlLjE9Q2FyYWN0XHUwMEU4cmUgaW5jb3JyZWN0LgotcGFyc2VyLnBhcnNlLjI9TnVtXHUwMEU5cm8gZGUgclx1MDBFOWZcdTAwRTlyZW5jZSBub24gdmFsaWRlLgotcGFyc2VyLm5leHQuMT1VbiBjYXJhY3RcdTAwRThyZSBlc3Qgb2JsaWdhdG9pcmUgYXByXHUwMEU4cyBcXC4KLXBhcnNlci5uZXh0LjI9Jz8nIG4nZXN0IHBhcyBhdHRlbmR1LiAnKD86JyBvdSAnKD89JyBvdSAnKD8hJyBvdSAnKD88JyBvdSAnKD8jJyBvdSAnKD8+Jz8KLXBhcnNlci5uZXh0LjM9Jyg/PD0nIG91ICcoPzwhJyBlc3QgYXR0ZW5kdS4KLXBhcnNlci5uZXh0LjQ9VW4gY29tbWVudGFpcmUgbidlc3QgcGFzIHRlcm1pblx1MDBFOS4KLXBhcnNlci5mYWN0b3IuMT0nKScgZXN0IGF0dGVuZHUuCi1wYXJzZXIuZmFjdG9yLjI9RmluIGRlIG1vZFx1MDBFOGxlIGluYXR0ZW5kdWUgZGFucyB1biBncm91cGUgZGUgbW9kaWZpY2F0ZXVyLgotcGFyc2VyLmZhY3Rvci4zPSc6JyBlc3QgYXR0ZW5kdS4KLXBhcnNlci5mYWN0b3IuND1GaW4gZGUgbW9kXHUwMEU4bGUgaW5hdHRlbmR1ZSBkYW5zIHVuIGdyb3VwZSBjb25kaXRpb25uZWwKLXBhcnNlci5mYWN0b3IuNT1VbmUgclx1MDBFOWZcdTAwRTlyZW5jZSBhdXhpbGlhaXJlIChiYWNrIHJlZmVyZW5jZSksIHVuIGFuY3JhZ2UsIHVuZSByZWNoZXJjaGUgdmVycyBsJ2F2YW50IG91IHVuZSByZWNoZXJjaGUgdmVycyBsJ2FycmlcdTAwRThyZSBlc3QgYXR0ZW5kdSBkYW5zIHVuIG1vZFx1MDBFOGxlIGNvbmRpdGlvbm5lbC4KLXBhcnNlci5mYWN0b3IuNj1JbCBleGlzdGUgcGx1cyBkZSB0cm9pcyBjaG9peCBkYW5zIHVuIGdyb3VwZSBjb25kaXRpb25uZWwuCi1wYXJzZXIuYXRvbS4xPVVuIGNhcmFjdFx1MDBFOHJlIGNvbXByaXMgZW50cmUgVSswMDQwLVUrMDA1ZiBkb2l0IHN1aXZyZSBcXGMuCi1wYXJzZXIuYXRvbS4yPVVuZSBhY2NvbGFkZSAoJ3snKSBlc3Qgb2JsaWdhdG9pcmUgYXZhbnQgdW5lIGNhdFx1MDBFOWdvcmllIGRlIGNhcmFjdFx1MDBFOHJlcy4KLXBhcnNlci5hdG9tLjM9VW4gbm9tIGRlIHByb3ByaVx1MDBFOXRcdTAwRTkgbidlc3QgcGFzIGZlcm1cdTAwRTkgcGFyIHVuZSBhY2NvbGFkZSAoJ30nKS4KLXBhcnNlci5hdG9tLjQ9TVx1MDBFOXRhY2FyYWN0XHUwMEU4cmUgaW5hdHRlbmR1Ci1wYXJzZXIuYXRvbS41PVByb3ByaVx1MDBFOXRcdTAwRTkgaW5jb25udWUuCi1wYXJzZXIuY2MuMT1VbmUgY2xhc3NlIGRlIGNhcmFjdFx1MDBFOHJlcyBQT1NJWCBkb2l0IFx1MDBFQXRyZSBmZXJtXHUwMEU5ZSBwYXIgJzpdJy4KLXBhcnNlci5jYy4yPUZpbiBkZSBtb2RcdTAwRThsZSBpbmF0dGVuZHVlIGRhbnMgdW5lIGNsYXNzZSBkZSBjYXJhY3RcdTAwRThyZXMuCi1wYXJzZXIuY2MuMz1Ob20gaW5jb25udSBwb3VyIHVuZSBjbGFzc2UgZGUgY2FyYWN0XHUwMEU4cmVzIFBPU0lYLgotcGFyc2VyLmNjLjQ9Jy0nIG4nZXN0IHBhcyB2YWxpZGUgaWNpLgotcGFyc2VyLmNjLjU9J10nIGVzdCBhdHRlbmR1LgotcGFyc2VyLmNjLjY9J1snIG4nZXN0IHBhcyB2YWxpZGUgZGFucyB1bmUgY2xhc3NlIGRlIGNhcmFjdFx1MDBFOHJlcy4gRWNyaXZleiAnXFxbJy4KLXBhcnNlci5jYy43PSddJyBuJ2VzdCBwYXMgdmFsaWRlIGRhbnMgdW5lIGNsYXNzZSBkZSBjYXJhY3RcdTAwRThyZXMuIEVjcml2ZXogJ1xcXScuCi1wYXJzZXIuY2MuOD0nLScgZXN0IHVuZSBwbGFnZSBkZSBjYXJhY3RcdTAwRThyZXMgbm9uIHZhbGlkZS4gRWNyaXZleiAnXFwtJy4KLXBhcnNlci5vcGUuMT0nWycgZXN0IGF0dGVuZHUuCi1wYXJzZXIub3BlLjI9JyknIG91ICctWycgb3UgJytbJyBvdSAnJlsnIGVzdCBhdHRlbmR1LgotcGFyc2VyLm9wZS4zPUxlIHBvaW50IGNvZGUgZGUgZmluIGRlIGxhIHBsYWdlIGVzdCBpbmZcdTAwRTlyaWV1ciBhdSBwb2ludCBjb2RlIGRlIGRcdTAwRTlidXQuCi1wYXJzZXIuZGVzY2FwZS4xPU5vdGF0aW9uIGhleGFkXHUwMEU5Y2ltYWxlIFVuaWNvZGUgbm9uIHZhbGlkZS4KLXBhcnNlci5kZXNjYXBlLjI9RFx1MDBFOWJvcmRlbWVudCBkZSBjYXBhY2l0XHUwMEU5IGQndW5lIG5vdGF0aW9uIGhleGFkXHUwMEU5Y2ltYWxlLgotcGFyc2VyLmRlc2NhcGUuMz0nXFx4eycgZG9pdCBcdTAwRUF0cmUgZmVybVx1MDBFOSBwYXIgJ30nLgotcGFyc2VyLmRlc2NhcGUuND1Qb2ludCBjb2RlIFVuaWNvZGUgbm9uIHZhbGlkZS4KLXBhcnNlci5kZXNjYXBlLjU9QXVjdW4gcG9pbnQgZCdhbmNyYWdlIG5lIGRvaXQgc2UgdHJvdXZlciBpY2kuCi1wYXJzZXIucHJvY2Vzcy4xPUNldHRlIGV4cHJlc3Npb24gbidlc3QgcGFzIHByaXNlIGVuIGNoYXJnZSBkYW5zIGxlIHBhcmFtXHUwMEU4dHJlIGQnb3B0aW9uIGVuIGNvdXJzLgotcGFyc2VyLnF1YW50aWZpZXIuMT1RdWFudGlmaWNhdGV1ciBub24gdmFsaWRlLiBVbiBjaGlmZnJlIGVzdCBhdHRlbmR1LgotcGFyc2VyLnF1YW50aWZpZXIuMj1RdWFudGlmaWNhdGV1ciBub24gdmFsaWRlLiBRdWFudGl0XHUwMEU5IG5vbiB2YWxpZGUgb3UgYWNjb2xhZGUgKCd9JykgbWFucXVhbnRlLgotcGFyc2VyLnF1YW50aWZpZXIuMz1RdWFudGlmaWNhdGV1ciBub24gdmFsaWRlLiBVbiBjaGlmZnJlIG91IHVuZSBhY2NvbGFkZSAoJ30nKSBlc3QgYXR0ZW5kdS4KLXBhcnNlci5xdWFudGlmaWVyLjQ9UXVhbnRpZmljYXRldXIgbm9uIHZhbGlkZS4gVW5lIHF1YW50aXRcdTAwRTkgbWluaW1hbGUgZG9pdCBcdTAwRUF0cmUgPD0gdW5lIHF1YW50aXRcdTAwRTkgbWF4aW1hbGUuCi1wYXJzZXIucXVhbnRpZmllci41PVF1YW50aWZpY2F0ZXVyIG5vbiB2YWxpZGUuIERcdTAwRTlib3JkZW1lbnQgZGUgbGEgdmFsZXVyIGRlIHF1YW50aXRcdTAwRTkuCi1udWxsCi1udWxsCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hwYXRoL3JlZ2V4L21lc3NhZ2VfaXQucHJvcGVydGllcyBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHBhdGgvcmVnZXgvbWVzc2FnZV9pdC5wcm9wZXJ0aWVzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxOGRmNTJlLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHBhdGgvcmVnZXgvbWVzc2FnZV9pdC5wcm9wZXJ0aWVzCisrKyAvZGV2L251bGwKQEAgLTEsNDEgKzAsMCBAQAotcGFyc2VyLnBhcnNlLjE9Q2FyYXR0ZXJlIGVycmF0by4KLXBhcnNlci5wYXJzZS4yPU51bWVybyBkaSByaWZlcmltZW50byBub24gdmFsaWRvLgotcGFyc2VyLm5leHQuMT1cdTAwQzggbmVjZXNzYXJpbyB1biBjYXJhdHRlcmUgZG9wbyBcXC4KLXBhcnNlci5uZXh0LjI9Jz8nIG5vbiBwcmV2aXN0by4gJyg/OicgbyAnKD89JyBvICcoPyEnIG8gJyg/PCcgbyAnKD8jJyBvICcoPz4nPwotcGFyc2VyLm5leHQuMz0nKD88PScgbyAnKD88IScgcHJldmlzdG8uCi1wYXJzZXIubmV4dC40PVVuIGNvbW1lbnRvIG5vbiBcdTAwRTggdGVybWluYXRvLgotcGFyc2VyLmZhY3Rvci4xPVx1MDBFOCBwcmV2aXN0byAnKScuCi1wYXJzZXIuZmFjdG9yLjI9RmluZSBkZWwgcGF0dGVybiBpbXByZXZpc3RhIGluIHVuIGdydXBwbyBtb2RpZmljYXRvcmUuCi1wYXJzZXIuZmFjdG9yLjM9XHUwMEU4IHByZXZpc3RvICc6Jy4KLXBhcnNlci5mYWN0b3IuND1GaW5lIGRlbCBwYXR0ZXJuIGltcHJldmlzdGEgaW4gdW4gZ3J1cHBvIGNvbmRpemlvbmFsZS4KLXBhcnNlci5mYWN0b3IuNT1JbiB1biBwYXR0ZXJuIGNvbmRpemlvbmFsZSBcdTAwRTggcHJldmlzdG8gdW4gcmlmZXJpbWVudG8gYWxsJ2luZGlldHJvLCB1biBhbmNvcmFnZ2lvLCB1biBsb29rYWhlYWQgbyB1biBsb29rYmVoaW5kLgotcGFyc2VyLmZhY3Rvci42PUluIHVuIGdydXBwbyBjb25kaXppb25hbGUgc29ubyBkaXNwb25pYmlsaSBwaVx1MDBGOSBkaSB0cmUgc2NlbHRlLgotcGFyc2VyLmF0b20uMT1VbiBjYXJhdHRlcmUgaW4gVSswMDQwLVUrMDA1ZiBkZXZlIHNlZ3VpcmUgXFxjLgotcGFyc2VyLmF0b20uMj1VbiAneycgXHUwMEU4IG5lY2Vzc2FyaW8gcHJpbWEgZGkgdW5hIGNhdGVnb3JpYSBkaSBjYXJhdHRlcmUuCi1wYXJzZXIuYXRvbS4zPVVuIG5vbWUgZGkgcHJvcHJpZXRcdTAwRTAgbm9uIFx1MDBFOCBjaGl1c28gZGEgJ30nLgotcGFyc2VyLmF0b20uND1NZXRhY2FyYXR0ZXJlIGltcHJldmlzdG8uCi1wYXJzZXIuYXRvbS41PVByb3ByaWV0XHUwMEUwIHNjb25vc2NpdXRhLgotcGFyc2VyLmNjLjE9VW5hIGNsYXNzZSBjYXJhdHRlcmkgUE9TSVggZGV2ZSBlc3NlcmUgY2hpdXNhIGRhICc6XScuCi1wYXJzZXIuY2MuMj1GaW5lIGltcHJldmlzdGEgZGVsIHBhdHRlcm4gaW4gdW5hIGNsYXNzZSBjYXJhdHRlcmkuCi1wYXJzZXIuY2MuMz1Ob21lIHNjb25vc2NpdXRvIHBlciB1bmEgY2xhc3NlIGNhcmF0dGVyaSBQT1NJWC4KLXBhcnNlci5jYy40PSctJyBub24gXHUwMEU4IHZhbGlkbyBxdWkuCi1wYXJzZXIuY2MuNT1cdTAwRTggcHJldmlzdG8gJ10nLgotcGFyc2VyLmNjLjY9J1snIG5vbiBcdTAwRTggdmFsaWRvIGluIHVuYSBjbGFzc2UgY2FyYXR0ZXJpLiBTY3JpdmVyZSAnXFxbJy4KLXBhcnNlci5jYy43PSddJyBub24gXHUwMEU4IHZhbGlkbyBpbiB1bmEgY2xhc3NlIGNhcmF0dGVyaS4gU2NyaXZlcmUgJ1xcXScuCi1wYXJzZXIuY2MuOD0nLScgXHUwMEU4IHVuIGludGVydmFsbG8gZGkgY2FyYXR0ZXJpIG5vbiB2YWxpZG8uIFNjcml2ZXJlICdcXC0nLgotcGFyc2VyLm9wZS4xPVx1MDBFOCBwcmV2aXN0byAnWycuCi1wYXJzZXIub3BlLjI9XHUwMEU4IHByZXZpc3RvICcpJyBvICctWycgbyAnK1snIG8gJyZbJy4KLXBhcnNlci5vcGUuMz1JbCBwdW50byBkaSBjb2RpY2UgZmluYWxlIGRlbGwnaW50ZXJ2YWxsbyBcdTAwRTggbWlub3JlIGRlbCBwdW50byBkaSBjb2RpY2UgaW5pemlhbGUuCi1wYXJzZXIuZGVzY2FwZS4xPU5vdGF6aW9uZSBlc2FkZWNpbWFsZSBVbmljb2RlIG5vbiB2YWxpZGEuCi1wYXJzZXIuZGVzY2FwZS4yPU92ZXJmbG93IGluIHVuYSBub3RhemlvbmUgZXNhZGVjaW1hbGUuCi1wYXJzZXIuZGVzY2FwZS4zPSdcXHh7JyBkZXZlIGVzc2VyZSBjaGl1c28gZGEgJ30nLgotcGFyc2VyLmRlc2NhcGUuND1QdW50byBkaSBjb2RpY2UgVW5pY29kZSBub24gdmFsaWRvLgotcGFyc2VyLmRlc2NhcGUuNT1VbiBhbmNvcmFnZ2lvIG5vbiBkZXZlIGVzc2VyZSBwb3NpemlvbmF0byBxdWkuCi1wYXJzZXIucHJvY2Vzcy4xPVF1ZXN0YSBlc3ByZXNzaW9uZSBub24gXHUwMEU4IHN1cHBvcnRhdGEgbmVsbCdpbXBvc3RhemlvbmUgZGVsbCdvcHppb25lIGNvcnJlbnRlLgotcGFyc2VyLnF1YW50aWZpZXIuMT1RdWFudGlmaWNhdG9yZSBub24gdmFsaWRvLiBcdTAwQzggcHJldmlzdGEgdW5hIGNpZnJhLgotcGFyc2VyLnF1YW50aWZpZXIuMj1RdWFudGlmaWNhdG9yZSBub24gdmFsaWRvLiBRdWFudGl0XHUwMEUwIG5vbiB2YWxpZGEgbyAnfScgbWFuY2FudGUuCi1wYXJzZXIucXVhbnRpZmllci4zPVF1YW50aWZpY2F0b3JlIG5vbiB2YWxpZG8uIFx1MDBDOCBwcmV2aXN0YSB1bmEgY2lmcmEgbyAnfScuCi1wYXJzZXIucXVhbnRpZmllci40PVF1YW50aWZpY2F0b3JlIG5vbiB2YWxpZG8uVW5hIHF1YW50aXRcdTAwRTAgbWluaW1hIGRldmUgZXNzZXJlIDw9IGRpIHVuYSBxdWFudGl0XHUwMEUwIG1hc3NpbWEuCi1wYXJzZXIucXVhbnRpZmllci41PVF1YW50aWZpY2F0b3JlIG5vbiB2YWxpZG8uIE92ZXJmbG93IGRlbCB2YWxvcmUgZGkgcXVhbnRpdFx1MDBFMC4KLW51bGwKLW51bGwKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHBhdGgvcmVnZXgvbWVzc2FnZV9qYS5wcm9wZXJ0aWVzIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cGF0aC9yZWdleC9tZXNzYWdlX2phLnByb3BlcnRpZXMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDc5ZDE1NWIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cGF0aC9yZWdleC9tZXNzYWdlX2phLnByb3BlcnRpZXMKKysrIC9kZXYvbnVsbApAQCAtMSw0MSArMCwwIEBACi1wYXJzZXIucGFyc2UuMT1cdTY1ODdcdTVCNTdcdTMwNENcdTkwNTVcdTMwNjNcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTlcdTMwMDIKLXBhcnNlci5wYXJzZS4yPVx1NzEyMVx1NTJCOVx1MzA2QVx1NTNDMlx1NzE2N1x1NzU2QVx1NTNGN1x1MzA2N1x1MzA1OVx1MzAwMgotcGFyc2VyLm5leHQuMT1cXFx1MzA2RVx1NUY4Q1x1MzA2Qlx1NjU4N1x1NUI1N1x1MzA0Q1x1NUZDNVx1ODk4MVx1MzA2N1x1MzA1OVx1MzAwMgotcGFyc2VyLm5leHQuMj0nPydcdTMwNkZcdTYwRjNcdTVCOUFcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDInKD86J1x1MzAwMScoPz0nXHUzMDAxJyg/ISdcdTMwMDEnKD88J1x1MzAwMScoPyMnXHUzMDdFXHUzMDVGXHUzMDZGJyg/PidcdTMwNjdcdTMwNTlcdTMwNEJcdTMwMDIKLXBhcnNlci5uZXh0LjM9Jyg/PD0nXHUzMDdFXHUzMDVGXHUzMDZGJyg/PCEnXHUzMDRDXHU1RkM1XHU4OTgxXHUzMDY3XHUzMDU5XHUzMDAyCi1wYXJzZXIubmV4dC40PVx1MzBCM1x1MzBFMVx1MzBGM1x1MzBDOFx1MzA0Q1x1N0Q0Mlx1NEU4Nlx1MzA1N1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotcGFyc2VyLmZhY3Rvci4xPScpJ1x1MzA0Q1x1NUZDNVx1ODk4MVx1MzA2N1x1MzA1OVx1MzAwMgotcGFyc2VyLmZhY3Rvci4yPVx1NEZFRVx1OThGRVx1NUI1MFx1MzBCMFx1MzBFQlx1MzBGQ1x1MzBEN1x1MzA2RVx1MzBEMVx1MzBCRlx1MzBGQ1x1MzBGM1x1MzA0Q1x1NEU4OFx1NjcxRlx1MzA1Qlx1MzA1QVx1N0Q0Mlx1NEU4Nlx1MzA1N1x1MzA3RVx1MzA1N1x1MzA1Rlx1MzAwMgotcGFyc2VyLmZhY3Rvci4zPSc6J1x1MzA0Q1x1NUZDNVx1ODk4MVx1MzA2N1x1MzA1OVx1MzAwMgotcGFyc2VyLmZhY3Rvci40PVx1Njc2MVx1NEVGNlx1MzBCMFx1MzBFQlx1MzBGQ1x1MzBEN1x1MzA2RVx1MzBEMVx1MzBCRlx1MzBGQ1x1MzBGM1x1MzA0Q1x1NEU4OFx1NjcxRlx1MzA1Qlx1MzA1QVx1N0Q0Mlx1NEU4Nlx1MzA1N1x1MzA3RVx1MzA1N1x1MzA1Rlx1MzAwMgotcGFyc2VyLmZhY3Rvci41PVx1Njc2MVx1NEVGNlx1MzBEMVx1MzBCRlx1MzBGQ1x1MzBGM1x1MzA2Qlx1NUY4Q1x1NjVCOVx1NTNDMlx1NzE2N1x1MzAwMVx1MzBBMlx1MzBGM1x1MzBBQlx1MzBGQ1x1MzAwMVx1NTE0OFx1OEFBRFx1MzA3Rlx1MzA3RVx1MzA1Rlx1MzA2Rlx1NUY4Q1x1OEFBRFx1MzA3Rlx1MzA0Q1x1NUZDNVx1ODk4MVx1MzA2N1x1MzA1OVx1MzAwMgotcGFyc2VyLmZhY3Rvci42PVx1Njc2MVx1NEVGNlx1MzBCMFx1MzBFQlx1MzBGQ1x1MzBEN1x1MzA2QjNcdTUwMEJcdThEODVcdTMwNkVcdTkwNzhcdTYyOUVcdTgwQTJcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIKLXBhcnNlci5hdG9tLjE9XFxjXHUzMDZFXHU1RjhDXHUzMDZCVSswMDQwXHUzMDRCXHUzMDg5VSswMDVmXHUzMDdFXHUzMDY3XHUzMDZFXHU2NTg3XHU1QjU3XHUzMDRDXHU1RkM1XHU4OTgxXHUzMDY3XHUzMDU5XHUzMDAyCi1wYXJzZXIuYXRvbS4yPVx1NjU4N1x1NUI1N1x1MzBBQlx1MzBDNlx1MzBCNFx1MzBFQVx1MzA2RVx1NTI0RFx1MzA2Qid7J1x1MzA0Q1x1NUZDNVx1ODk4MVx1MzA2N1x1MzA1OVx1MzAwMgotcGFyc2VyLmF0b20uMz1cdTMwRDdcdTMwRURcdTMwRDFcdTMwQzZcdTMwQTNcdTU0MERcdTMwNEMnfSdcdTMwNjdcdTk1ODlcdTMwNThcdTMwODlcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKLXBhcnNlci5hdG9tLjQ9XHU0RTg4XHU2NzFGXHUzMDU3XHUzMDZBXHUzMDQ0XHUzMEUxXHUzMEJGXHU2NTg3XHU1QjU3XHUzMDY3XHUzMDU5XHUzMDAyCi1wYXJzZXIuYXRvbS41PVx1NEUwRFx1NjYwRVx1MzA2QVx1MzBEN1x1MzBFRFx1MzBEMVx1MzBDNlx1MzBBM1x1MzA2N1x1MzA1OVx1MzAwMgotcGFyc2VyLmNjLjE9UE9TSVhcdTY1ODdcdTVCNTdcdTMwQUZcdTMwRTlcdTMwQjlcdTMwNkYnOl0nXHUzMDY3XHU5NTg5XHUzMDU4XHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCi1wYXJzZXIuY2MuMj1cdTY1ODdcdTVCNTdcdTMwQUZcdTMwRTlcdTMwQjlcdTMwNkVcdTMwRDFcdTMwQkZcdTMwRkNcdTMwRjNcdTMwNENcdTRFODhcdTY3MUZcdTMwNUJcdTMwNUFcdTdENDJcdTRFODZcdTMwNTdcdTMwN0VcdTMwNTdcdTMwNUZcdTMwMDIKLXBhcnNlci5jYy4zPVBPU0lYXHU2NTg3XHU1QjU3XHUzMEFGXHUzMEU5XHUzMEI5XHUzMDZCXHU1QkZFXHUzMDU5XHUzMDhCXHU1NDBEXHU1MjREXHUzMDRDXHU0RTBEXHU2NjBFXHUzMDY3XHUzMDU5XHUzMDAyCi1wYXJzZXIuY2MuND0nLSdcdTMwNkZcdTMwNTNcdTMwNTNcdTMwNjdcdTMwNkZcdTcxMjFcdTUyQjlcdTMwNjdcdTMwNTlcdTMwMDIKLXBhcnNlci5jYy41PSddJ1x1MzA0Q1x1NUZDNVx1ODk4MVx1MzA2N1x1MzA1OVx1MzAwMgotcGFyc2VyLmNjLjY9J1snXHUzMDZGXHU2NTg3XHU1QjU3XHUzMEFGXHUzMEU5XHUzMEI5XHUzMDY3XHU3MTIxXHU1MkI5XHUzMDY3XHUzMDU5XHUzMDAyJ1xcWydcdTMwOTJcdThBMThcdThGRjBcdTMwNTdcdTMwN0VcdTMwNTlcdTMwMDIKLXBhcnNlci5jYy43PSddJ1x1MzA2Rlx1NjU4N1x1NUI1N1x1MzBBRlx1MzBFOVx1MzBCOVx1MzA2N1x1NzEyMVx1NTJCOVx1MzA2N1x1MzA1OVx1MzAwMidcXF0nXHUzMDkyXHU4QTE4XHU4RkYwXHUzMDU3XHUzMDdFXHUzMDU5XHUzMDAyCi1wYXJzZXIuY2MuOD0nLSdcdTMwNkZcdTcxMjFcdTUyQjlcdTMwNkFcdTY1ODdcdTVCNTdcdTdCQzRcdTU2RjJcdTMwNjdcdTMwNTlcdTMwMDInXFwtJ1x1MzA5Mlx1OEExOFx1OEZGMFx1MzA1N1x1MzA3RVx1MzA1OVx1MzAwMgotcGFyc2VyLm9wZS4xPSdbJ1x1MzA0Q1x1NUZDNVx1ODk4MVx1MzA2N1x1MzA1OVx1MzAwMgotcGFyc2VyLm9wZS4yPScpJ1x1MzAwMSctWydcdTMwMDEnK1snXHUzMDdFXHUzMDVGXHUzMDZGJyZbJ1x1MzA0Q1x1NUZDNVx1ODk4MVx1MzA2N1x1MzA1OVx1MzAwMgotcGFyc2VyLm9wZS4zPVx1N0JDNFx1NTZGMlx1MzA2RVx1N0Q0Mlx1NEU4Nlx1MzBCM1x1MzBGQ1x1MzBDOVx1MzBGQlx1MzBERFx1MzBBNFx1MzBGM1x1MzBDOFx1MzA0Q1x1OTU4Qlx1NTlDQlx1MzBCM1x1MzBGQ1x1MzBDOVx1MzBGQlx1MzBERFx1MzBBNFx1MzBGM1x1MzBDOFx1MzA4OFx1MzA4QVx1NUMwRlx1MzA1NVx1MzA0NFx1MzA2N1x1MzA1OVx1MzAwMgotcGFyc2VyLmRlc2NhcGUuMT1cdTcxMjFcdTUyQjlcdTMwNkFVbmljb2RlMTZcdTkwMzJcdTZDRDVcdTMwNjdcdTMwNTlcdTMwMDIKLXBhcnNlci5kZXNjYXBlLjI9MTZcdTkwMzJcdTZDRDVcdTMwNjdcdTMwQUFcdTMwRkNcdTMwRDBcdTMwRkNcdTMwRDVcdTMwRURcdTMwRkNcdTMwNTdcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTlcdTMwMDIKLXBhcnNlci5kZXNjYXBlLjM9J1xceHsnXHUzMDZGJ30nXHUzMDY3XHU5NTg5XHUzMDU4XHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCi1wYXJzZXIuZGVzY2FwZS40PVx1NzEyMVx1NTJCOVx1MzA2QVVuaWNvZGVcdTMwQjNcdTMwRkNcdTMwQzlcdTMwRkJcdTMwRERcdTMwQTRcdTMwRjNcdTMwQzhcdTMwNjdcdTMwNTlcdTMwMDIKLXBhcnNlci5kZXNjYXBlLjU9XHUzMEEyXHUzMEYzXHUzMEFCXHUzMEZDXHUzMDZGXHUzMDUzXHUzMDUzXHUzMDY3XHU0RjdGXHU3NTI4XHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi1wYXJzZXIucHJvY2Vzcy4xPVx1MzA1M1x1MzA2RVx1NUYwRlx1MzA2Rlx1MzAwMVx1NzNGRVx1NTcyOFx1MzA2RVx1MzBBQVx1MzBEN1x1MzBCN1x1MzBFN1x1MzBGM1x1OEEyRFx1NUI5QVx1MzA2N1x1MzBCNVx1MzBERFx1MzBGQ1x1MzBDOFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgotcGFyc2VyLnF1YW50aWZpZXIuMT1cdTcxMjFcdTUyQjlcdTMwNkFcdTY1NzBcdTkxQ0ZcdThBNUVcdTMwNjdcdTMwNTlcdTMwMDJcdTY1NzBcdTVCNTdcdTMwNENcdTVGQzVcdTg5ODFcdTMwNjdcdTMwNTlcdTMwMDIKLXBhcnNlci5xdWFudGlmaWVyLjI9XHU3MTIxXHU1MkI5XHUzMDZBXHU2NTcwXHU5MUNGXHU4QTVFXHUzMDY3XHUzMDU5XHUzMDAyJ30nXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCi1wYXJzZXIucXVhbnRpZmllci4zPVx1NzEyMVx1NTJCOVx1MzA2QVx1NjU3MFx1OTFDRlx1OEE1RVx1MzA2N1x1MzA1OVx1MzAwMlx1NjU3MFx1NUI1N1x1MzA3RVx1MzA1Rlx1MzA2Rid9J1x1MzA0Q1x1NUZDNVx1ODk4MVx1MzA2N1x1MzA1OVx1MzAwMgotcGFyc2VyLnF1YW50aWZpZXIuND1cdTcxMjFcdTUyQjlcdTMwNkFcdTY1NzBcdTkxQ0ZcdThBNUVcdTMwNjdcdTMwNTlcdTMwMDJcdTY3MDBcdTVDMEZcdTY1NzBcdTkxQ0ZcdTMwNkZcdTY3MDBcdTU5MjdcdTY1NzBcdTkxQ0ZcdTRFRTVcdTRFMEJcdTMwNjdcdTMwNDJcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIKLXBhcnNlci5xdWFudGlmaWVyLjU9XHU3MTIxXHU1MkI5XHUzMDZBXHU2NTcwXHU5MUNGXHU4QTVFXHUzMDY3XHUzMDU5XHUzMDAyXHU2NTcwXHU5MUNGXHU1MDI0XHUzMDRDXHUzMEFBXHUzMEZDXHUzMEQwXHUzMEZDXHUzMEQ1XHUzMEVEXHUzMEZDXHUzMDU3XHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5XHUzMDAyCi1udWxsCi1udWxsCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hwYXRoL3JlZ2V4L21lc3NhZ2Vfa28ucHJvcGVydGllcyBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHBhdGgvcmVnZXgvbWVzc2FnZV9rby5wcm9wZXJ0aWVzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA5OGNmNGZjLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHBhdGgvcmVnZXgvbWVzc2FnZV9rby5wcm9wZXJ0aWVzCisrKyAvZGV2L251bGwKQEAgLTEsNDEgKzAsMCBAQAotcGFyc2VyLnBhcnNlLjE9XHVDNzk4XHVCQUJCXHVCNDFDIFx1QkIzOFx1Qzc5MFx1Qzc4NVx1QjJDOFx1QjJFNC4KLXBhcnNlci5wYXJzZS4yPVx1QkQ4MFx1QzgwMVx1RDU2OVx1RDU1QyBcdUNDMzhcdUM4NzAgXHVCQzg4XHVENjM4XHVDNzg1XHVCMkM4XHVCMkU0LgotcGFyc2VyLm5leHQuMT1cXCBcdUI0QTRcdUM1RDAgXHVCQjM4XHVDNzkwXHVBQzAwIFx1RDU0NFx1QzY5NFx1RDU2OVx1QjJDOFx1QjJFNC4KLXBhcnNlci5uZXh0LjI9Jz8nXHVCMjk0IFx1RDU0NFx1QzY5NFx1RDU1OFx1QzlDMCBcdUM1NEFcdUMyQjVcdUIyQzhcdUIyRTQuICcoPzonIFx1QjYxMFx1QjI5NCAnKD89JyBcdUI2MTBcdUIyOTQgJyg/IScgXHVCNjEwXHVCMjk0ICcoPzwnIFx1QjYxMFx1QjI5NCAnKD8jJyBcdUI2MTBcdUIyOTQgJyg/Pic/Ci1wYXJzZXIubmV4dC4zPScoPzw9JyBcdUI2MTBcdUIyOTQgJyg/PCEnXHVBQzAwIFx1RDU0NFx1QzY5NFx1RDU2OVx1QjJDOFx1QjJFNC4KLXBhcnNlci5uZXh0LjQ9XHVDMTI0XHVCQTg1XHVDNzc0IFx1Qzg4NVx1QjhDQ1x1QjQxOFx1QzlDMCBcdUM1NEFcdUM1NThcdUMyQjVcdUIyQzhcdUIyRTQuCi1wYXJzZXIuZmFjdG9yLjE9JyknXHVBQzAwIFx1RDU0NFx1QzY5NFx1RDU2OVx1QjJDOFx1QjJFNC4KLXBhcnNlci5mYWN0b3IuMj1cdUMyMThcdUM4MTVcdUM3OTAgXHVBREY4XHVCOEY5XHVDNUQwIFx1QzYwOFx1QzBDMVx1Q0U1OCBcdUM1NEFcdUM3NDAgXHVEMzI4XHVEMTM0IFx1QjA1RFx1Qzc3NCBcdUM3ODhcdUMyQjVcdUIyQzhcdUIyRTQuCi1wYXJzZXIuZmFjdG9yLjM9JzonXHVDNzc0IFx1RDU0NFx1QzY5NFx1RDU2OVx1QjJDOFx1QjJFNC4KLXBhcnNlci5mYWN0b3IuND1cdUM4NzBcdUFDNzQgXHVBREY4XHVCOEY5XHVDNUQwIFx1QzYwOFx1QzBDMVx1Q0U1OCBcdUM1NEFcdUM3NDAgXHVEMzI4XHVEMTM0IFx1QjA1RFx1Qzc3NCBcdUM3ODhcdUMyQjVcdUIyQzhcdUIyRTQuCi1wYXJzZXIuZmFjdG9yLjU9XHVDODcwXHVBQzc0IFx1RDMyOFx1RDEzNFx1QzVEMCBcdUM1RURcdUNDMzhcdUM4NzAgXHVCNjEwXHVCMjk0IFx1QzU3NVx1Q0VFNCBcdUI2MTBcdUIyOTQgbG9va2FoZWFkIFx1QjYxMFx1QjI5NCBsb29rYmVoaW5kXHVBQzAwIFx1RDU0NFx1QzY5NFx1RDU2OVx1QjJDOFx1QjJFNC4KLXBhcnNlci5mYWN0b3IuNj1cdUM4NzBcdUFDNzQgXHVBREY4XHVCOEY5XHVDNUQwIDRcdUFDMUMgXHVDNzc0XHVDMEMxXHVDNzU4IFx1QzEyMFx1RDBERCBcdUQ1NkRcdUJBQTlcdUM3NzQgXHVDNzg4XHVDMkI1XHVCMkM4XHVCMkU0LgotcGFyc2VyLmF0b20uMT1VKzAwNDAtVSswMDVmXHVDNzU4IFx1QkIzOFx1Qzc5MFx1QUMwMCBcXGMgXHVCNEE0XHVDNUQwIFx1QzY0MFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi1wYXJzZXIuYXRvbS4yPVx1QkIzOFx1Qzc5MCBcdUJDOTRcdUM4RkMgXHVDNTVFXHVDNUQwICd7J1x1QUMwMCBcdUQ1NDRcdUM2OTRcdUQ1NjlcdUIyQzhcdUIyRTQuCi1wYXJzZXIuYXRvbS4zPVx1QzE4RFx1QzEzMSBcdUM3NzRcdUI5ODRcdUM3NzQgJ30nXHVCODVDIFx1QjJFQlx1RDc4OFx1QzlDMCBcdUM1NEFcdUM1NThcdUMyQjVcdUIyQzhcdUIyRTQuCi1wYXJzZXIuYXRvbS40PVx1QzYwOFx1QzBDMVx1Q0U1OCBcdUM1NEFcdUM3NDAgXHVCQTU0XHVEMEMwIFx1QkIzOFx1Qzc5MFx1Qzc4NVx1QjJDOFx1QjJFNC4KLXBhcnNlci5hdG9tLjU9XHVDNTRDIFx1QzIxOCBcdUM1QzZcdUIyOTQgXHVDMThEXHVDMTMxXHVDNzg1XHVCMkM4XHVCMkU0LgotcGFyc2VyLmNjLjE9UE9TSVggXHVCQjM4XHVDNzkwIFx1RDA3NFx1Qjc5OFx1QzJBNFx1Qjk3QyAnOl0nXHVCODVDIFx1QjJFQlx1QzU0NFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi1wYXJzZXIuY2MuMj1cdUJCMzhcdUM3OTAgXHVEMDc0XHVCNzk4XHVDMkE0XHVDNUQwIFx1QzYwOFx1QzBDMVx1Q0U1OCBcdUM1NEFcdUM3NDAgXHVEMzI4XHVEMTM0IFx1QjA1RFx1Qzc3NCBcdUM3ODhcdUMyQjVcdUIyQzhcdUIyRTQuCi1wYXJzZXIuY2MuMz1QT1NJWCBcdUJCMzhcdUM3OTAgXHVEMDc0XHVCNzk4XHVDMkE0XHVDNUQwIFx1QjMwMFx1RDU3NCBcdUM1NEMgXHVDMjE4IFx1QzVDNlx1QjI5NCBcdUM3NzRcdUI5ODRcdUM3ODVcdUIyQzhcdUIyRTQuCi1wYXJzZXIuY2MuND0nLSdcdUIyOTQgXHVDNUVDXHVBRTMwXHVDMTFDIFx1QkQ4MFx1QzgwMVx1RDU2OVx1RDU2OVx1QjJDOFx1QjJFNC4KLXBhcnNlci5jYy41PSddJ1x1QUMwMCBcdUQ1NDRcdUM2OTRcdUQ1NjlcdUIyQzhcdUIyRTQuCi1wYXJzZXIuY2MuNj1cdUJCMzhcdUM3OTAgXHVEMDc0XHVCNzk4XHVDMkE0XHVDNUQwXHVDMTFDICdbJ1x1QUMwMCBcdUJEODBcdUM4MDFcdUQ1NjlcdUQ1NjlcdUIyQzhcdUIyRTQuICdcXFsnXHVCOTdDIFx1QzRGMFx1QzJFRFx1QzJEQ1x1QzYyNC4KLXBhcnNlci5jYy43PVx1QkIzOFx1Qzc5MCBcdUQwNzRcdUI3OThcdUMyQTRcdUM1RDBcdUMxMUMgJ10nXHVBQzAwIFx1QkQ4MFx1QzgwMVx1RDU2OVx1RDU2OVx1QjJDOFx1QjJFNC4gJ1xcXSdcdUI5N0MgXHVDNEYwXHVDMkVEXHVDMkRDXHVDNjI0LgotcGFyc2VyLmNjLjg9Jy0nXHVDNzQwIFx1QkQ4MFx1QzgwMVx1RDU2OVx1RDU1QyBcdUJCMzhcdUM3OTAgXHVCQzk0XHVDNzA0XHVDNzg1XHVCMkM4XHVCMkU0LiAnXFwtJ1x1Qzc0NCBcdUM0RjBcdUMyRURcdUMyRENcdUM2MjQuCi1wYXJzZXIub3BlLjE9J1snXHVBQzAwIFx1RDU0NFx1QzY5NFx1RDU2OVx1QjJDOFx1QjJFNC4KLXBhcnNlci5vcGUuMj0nKScgXHVCNjEwXHVCMjk0ICctWycgXHVCNjEwXHVCMjk0ICcrWycgXHVCNjEwXHVCMjk0ICcmWydcdUFDMDAgXHVENTQ0XHVDNjk0XHVENTY5XHVCMkM4XHVCMkU0LgotcGFyc2VyLm9wZS4zPVx1QkM5NFx1QzcwNCBcdUIwNUQgXHVDRjU0XHVCNERDIFx1RDNFQ1x1Qzc3OFx1RDJCOFx1QUMwMCBcdUMyRENcdUM3OTEgXHVDRjU0XHVCNERDIFx1RDNFQ1x1Qzc3OFx1RDJCOFx1QkNGNFx1QjJFNCBcdUM3OTFcdUMyQjVcdUIyQzhcdUIyRTQuCi1wYXJzZXIuZGVzY2FwZS4xPVx1QkQ4MFx1QzgwMVx1RDU2OVx1RDU1QyBcdUM3MjBcdUIyQzhcdUNGNTRcdUI0REMgMTZcdUM5QzRcdUMyMTggXHVENDVDXHVBRTMwXHVCQzk1XHVDNzg1XHVCMkM4XHVCMkU0LgotcGFyc2VyLmRlc2NhcGUuMj0xNlx1QzlDNFx1QzIxOCBcdUQ0NUNcdUFFMzBcdUJDOTVcdUM3NTggXHVDNjI0XHVCQzg0XHVENTBDXHVCODVDXHVDNkIwXHVDNzg1XHVCMkM4XHVCMkU0LgotcGFyc2VyLmRlc2NhcGUuMz0nXFx4eydcdUIyOTQgJ30nXHVCODVDIFx1QjJFQlx1QzU0NFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuCi1wYXJzZXIuZGVzY2FwZS40PVx1QkQ4MFx1QzgwMVx1RDU2OVx1RDU1QyBcdUM3MjBcdUIyQzhcdUNGNTRcdUI0REMgXHVDRjU0XHVCNERDIFx1RDNFQ1x1Qzc3OFx1RDJCOFx1Qzc4NVx1QjJDOFx1QjJFNC4KLXBhcnNlci5kZXNjYXBlLjU9XHVDNTc1XHVDRUU0XHVBQzAwIFx1QzVFQ1x1QUUzMFx1QzVEMCBcdUM3ODhcdUM3M0NcdUJBNzQgXHVDNTQ4XHVCNDI5XHVCMkM4XHVCMkU0LgotcGFyc2VyLnByb2Nlc3MuMT1cdUM3NzQgXHVENDVDXHVENjA0XHVDMkREXHVDNzQwIFx1RDYwNFx1QzdBQyBcdUM2MzVcdUMxNTggXHVDMTI0XHVDODE1XHVDNUQwXHVDMTFDIFx1QzlDMFx1QzZEMFx1QjQxOFx1QzlDMCBcdUM1NEFcdUMyQjVcdUIyQzhcdUIyRTQuCi1wYXJzZXIucXVhbnRpZmllci4xPVx1QzIxOFx1QjdDOVx1QzBBQ1x1QUMwMCBcdUJEODBcdUM4MDFcdUQ1NjlcdUQ1NjlcdUIyQzhcdUIyRTQuIFx1QzIyQlx1Qzc5MFx1QUMwMCBcdUQ1NDRcdUM2OTRcdUQ1NjlcdUIyQzhcdUIyRTQuCi1wYXJzZXIucXVhbnRpZmllci4yPVx1QzIxOFx1QjdDOVx1QzBBQ1x1QUMwMCBcdUJEODBcdUM4MDFcdUQ1NjlcdUQ1NjlcdUIyQzhcdUIyRTQuIFx1QzIxOFx1QjdDOVx1Qzc3NCBcdUJEODBcdUM4MDFcdUQ1NjlcdUQ1NThcdUFDNzBcdUIwOTggJ30nXHVBQzAwIFx1QjIwNFx1Qjc3RFx1QjQxOFx1QzVDOFx1QzJCNVx1QjJDOFx1QjJFNC4KLXBhcnNlci5xdWFudGlmaWVyLjM9XHVDMjE4XHVCN0M5XHVDMEFDXHVBQzAwIFx1QkQ4MFx1QzgwMVx1RDU2OVx1RDU2OVx1QjJDOFx1QjJFNC4gXHVDMjJCXHVDNzkwXHVCMDk4ICd9J1x1QUMwMCBcdUQ1NDRcdUM2OTRcdUQ1NjlcdUIyQzhcdUIyRTQuCi1wYXJzZXIucXVhbnRpZmllci40PVx1QzIxOFx1QjdDOVx1QzBBQ1x1QUMwMCBcdUJEODBcdUM4MDFcdUQ1NjlcdUQ1NjlcdUIyQzhcdUIyRTQuIFx1Q0Q1Q1x1QzE4QyBcdUMyMThcdUI3QzlcdUM3NDAgXHVDRDVDXHVCMzAwIFx1QzIxOFx1QjdDOSBcdUM3NzRcdUQ1NThcdUM1RUNcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0LgotcGFyc2VyLnF1YW50aWZpZXIuNT1cdUMyMThcdUI3QzlcdUMwQUNcdUFDMDAgXHVCRDgwXHVDODAxXHVENTY5XHVENTY5XHVCMkM4XHVCMkU0LiBcdUMyMThcdUI3QzkgXHVBQzEyIFx1QzYyNFx1QkM4NFx1RDUwQ1x1Qjg1Q1x1QzZCMFx1Qzc4NVx1QjJDOFx1QjJFNC4KLW51bGwKLW51bGwKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHBhdGgvcmVnZXgvbWVzc2FnZV9wdF9CUi5wcm9wZXJ0aWVzIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cGF0aC9yZWdleC9tZXNzYWdlX3B0X0JSLnByb3BlcnRpZXMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDdjNGJmOWYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cGF0aC9yZWdleC9tZXNzYWdlX3B0X0JSLnByb3BlcnRpZXMKKysrIC9kZXYvbnVsbApAQCAtMSw0MSArMCwwIEBACi1wYXJzZXIucGFyc2UuMT1DYXJhY3RlcmUgaW5jb3JyZXRvLgotcGFyc2VyLnBhcnNlLjI9Tlx1MDBGQW1lcm8gZGUgcmVmZXJcdTAwRUFuY2lhIGludlx1MDBFMWxpZG8uCi1wYXJzZXIubmV4dC4xPVx1MDBDOSBvYnJpZ2F0XHUwMEYzcmlvIHVtIGNhcmFjdGVyZSBhcFx1MDBGM3MgXFwuCi1wYXJzZXIubmV4dC4yPSc/JyBuXHUwMEUzbyBcdTAwRTkgZXNwZXJhZG8uICAnKD86JyBvdSAnKD89JyBvdSAnKD8hJyBvdSAnKD88JyBvdSAnKD8jJyBvdSAnKD8+Jz8KLXBhcnNlci5uZXh0LjM9Jyg/PD0nIG91ICcoPzwhJyBcdTAwRTkgZXNwZXJhZG8uCi1wYXJzZXIubmV4dC40PVVtIGNvbWVudFx1MDBFMXJpbyBuXHUwMEUzbyBmb2kgZmluYWxpemFkby4KLXBhcnNlci5mYWN0b3IuMT0nKScgXHUwMEU5IGVzcGVyYWRvLgotcGFyc2VyLmZhY3Rvci4yPUZpbSBpbmVzcGVyYWRvIGRvIHBhZHJcdTAwRTNvIGVtIHVtIGdydXBvIGRlIG1vZGlmaWNhZG9yZXMuCi1wYXJzZXIuZmFjdG9yLjM9JzonIFx1MDBFOSBlc3BlcmFkby4KLXBhcnNlci5mYWN0b3IuND1GaW0gaW5lc3BlcmFkbyBkbyBwYWRyXHUwMEUzbyBlbSB1bSBncnVwbyBjb25kaWNpb25hbC4KLXBhcnNlci5mYWN0b3IuNT1FbSB1bSBwYWRyXHUwMEUzbyBjb25kaWNpb25hbCwgZXNwZXJhdmEtc2UgdW1hIHJlZmVyXHUwMEVBbmNpYSByZXRyb2F0aXZhLCBcdTAwRTJuY29yYSwgbG9va2FoZWFkIG91IGxvb2tiZWhpbmQuCi1wYXJzZXIuZmFjdG9yLjY9SFx1MDBFMSBtYWlzIGRlIHRyXHUwMEVBcyBvcFx1MDBFN1x1MDBGNWVzIGVtIHVtIGdydXBvIGNvbmRpY2lvbmFsLgotcGFyc2VyLmF0b20uMT1VbSBjYXJhY3RlcmUgZW0gVSswMDQwLVUrMDA1ZiB2aXIgYXBcdTAwRjNzIFxcYy4KLXBhcnNlci5hdG9tLjI9VW0gJ3snIFx1MDBFOSBvYnJpZ2F0XHUwMEYzcmlvIGFudGVzIGRlIHVtYSBjYXRlZ29yaWEgZGUgY2FyYWN0ZXJlLgotcGFyc2VyLmF0b20uMz1VbSBub21lIGRlIHByb3ByaWVkYWRlIG5cdTAwRTNvIGZvaSBmZWNoYWRvIHBvciAnfScuCi1wYXJzZXIuYXRvbS40PU1ldGFjYXJhY3RlcmUgaW5lc3BlcmFkby4KLXBhcnNlci5hdG9tLjU9UHJvcHJpZWRhZGUgZGVzY29uaGVjaWRhLgotcGFyc2VyLmNjLjE9VW1hIGNsYXNzZSBkZSBjYXJhY3RlcmUgUE9TSVggZGV2ZSBzZXIgZmVjaGFkYSBwb3IgJzpdJy4KLXBhcnNlci5jYy4yPUZpbSBpbmVzcGVyYWRvIGRvIHBhZHJcdTAwRTNvIGVtIHVtYSBjbGFzc2UgZGUgY2FyYWN0ZXJlLgotcGFyc2VyLmNjLjM9Tm9tZSBkZXNjb25oZWNpZG8gcGFyYSB1bWEgY2xhc3NlIGRlIGNhcmFjdGVyZSBQT1NJWC4KLXBhcnNlci5jYy40PSctJyBcdTAwRTkgaW52XHUwMEUxbGlkbyBhcXVpLgotcGFyc2VyLmNjLjU9J10nIFx1MDBFOSBlc3BlcmFkby4KLXBhcnNlci5jYy42PSdbJyBcdTAwRTkgaW52XHUwMEUxbGlkbyBlbSB1bWEgY2xhc3NlIGRlIGNhcmFjdGVyZS4gVXNlICdcXFsnLgotcGFyc2VyLmNjLjc9J10nIFx1MDBFOSBpbnZcdTAwRTFsaWRvIGVtIHVtYSBjbGFzc2UgZGUgY2FyYWN0ZXJlLiBVc2UgJ1xcXScuCi1wYXJzZXIuY2MuOD0nLScgXHUwMEU5IHVtYSBmYWl4YSBkZSBjYXJhY3RlcmVzIGludlx1MDBFMWxpZGEuIFVzZSAnXFwtJy4KLXBhcnNlci5vcGUuMT0nWycgXHUwMEU5IGVzcGVyYWRvLgotcGFyc2VyLm9wZS4yPScpJyBvdSAnLVsnIG91ICcrWycgb3UgJyZbJyBcdTAwRTkgZXNwZXJhZG8uCi1wYXJzZXIub3BlLjM9TyBjXHUwMEYzZGlnbyBkZSBmaW0gZGEgZmFpeGEgXHUwMEU5IGluZmVyaW9yIGFvIGRlIGluXHUwMEVEY2lvLgotcGFyc2VyLmRlc2NhcGUuMT1Ob3RhXHUwMEU3XHUwMEUzbyBoZXhhZGVjaW1hbCBVbmljb2RlIGludlx1MDBFMWxpZGEuCi1wYXJzZXIuZGVzY2FwZS4yPU92ZXJmbG93IGVtIHVtYSBub3RhXHUwMEU3XHUwMEUzbyBoZXhhZGVjaW1hbC4KLXBhcnNlci5kZXNjYXBlLjM9J1xceHsnIGRldmUgc2VyIGZlY2hhZG8gcG9yICd9Jy4KLXBhcnNlci5kZXNjYXBlLjQ9Q1x1MDBGM2RpZ28gVW5pY29kZSBpbnZcdTAwRTFsaWRvLgotcGFyc2VyLmRlc2NhcGUuNT1VbWEgXHUwMEUybmNvcmEgblx1MDBFM28gZGV2ZSBlc3RhciBhcXVpLgotcGFyc2VyLnByb2Nlc3MuMT1Fc3RhIGV4cHJlc3NcdTAwRTNvIG5cdTAwRTNvIFx1MDBFOSBzdXBvcnRhZGEgbmEgZGVmaW5pXHUwMEU3XHUwMEUzbyBkYSBvcFx1MDBFN1x1MDBFM28gYXR1YWwuCi1wYXJzZXIucXVhbnRpZmllci4xPVF1YW50aWZpY2Fkb3IgaW52XHUwMEUxbGlkby4gXHUwMEM5IGVzcGVyYWRvIHVtIGRcdTAwRURnaXRvLgotcGFyc2VyLnF1YW50aWZpZXIuMj1RdWFudGlmaWNhZG9yIGludlx1MDBFMWxpZG8uIEEgcXVhbnRpZGFkZSBcdTAwRTkgaW52XHUwMEUxbGlkYSBvdSBlc3RcdTAwRTEgZmFsdGFuZG8gdW0gJ30nLgotcGFyc2VyLnF1YW50aWZpZXIuMz1RdWFudGlmaWNhZG9yIGludlx1MDBFMWxpZG8uIFx1MDBDOSBlc3BlcmFkbyB1bSBkXHUwMEVEZ2l0byBvdSAnfScuCi1wYXJzZXIucXVhbnRpZmllci40PVF1YW50aWZpY2Fkb3IgaW52XHUwMEUxbGlkby4gVW1hIHF1YW50aWRhZGUgbVx1MDBFRG5pbWEgZGV2ZSBzZXIgPD0gdW1hIHF1YW50aWRhZGUgbVx1MDBFMXhpbWEuCi1wYXJzZXIucXVhbnRpZmllci41PVF1YW50aWZpY2Fkb3IgaW52XHUwMEUxbGlkby4gVW0gb3ZlcmZsb3cgZG8gdmFsb3IgZGUgcXVhbnRpZGFkZS4KLW51bGwKLW51bGwKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHBhdGgvcmVnZXgvbWVzc2FnZV9zdi5wcm9wZXJ0aWVzIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cGF0aC9yZWdleC9tZXNzYWdlX3N2LnByb3BlcnRpZXMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGM1YWNlMzYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cGF0aC9yZWdleC9tZXNzYWdlX3N2LnByb3BlcnRpZXMKKysrIC9kZXYvbnVsbApAQCAtMSw0MSArMCwwIEBACi1wYXJzZXIucGFyc2UuMT1GZWwgdGVja2VuLgotcGFyc2VyLnBhcnNlLjI9T2dpbHRpZ3QgcmVmZXJlbnNudW1tZXIuCi1wYXJzZXIubmV4dC4xPUV0dCB0ZWNrZW4ga3JcdTAwRTR2cyBlZnRlciBcXC4KLXBhcnNlci5uZXh0LjI9Jz8nIGZcdTAwRjZydlx1MDBFNG50YXMgaW50ZS4gICcoPzonIGVsbGVyICcoPz0nIGVsbGVyICcoPyEnIGVsbGVyICcoPzwnIGVsbGVyICcoPyMnIGVsbGVyICcoPz4nPwotcGFyc2VyLm5leHQuMz0nKD88PScgZWxsZXIgJyg/PCEnIGZcdTAwRjZydlx1MDBFNG50YXMuCi1wYXJzZXIubmV4dC40PUVuIGtvbW1lbnRhciBoYXIgaW50ZSBhdnNsdXRhdHMuCi1wYXJzZXIuZmFjdG9yLjE9JyknIGZcdTAwRjZydlx1MDBFNG50YXMuCi1wYXJzZXIuZmFjdG9yLjI9T3ZcdTAwRTRudGF0IGF2c2x1dCBwXHUwMEU1IG1cdTAwRjZuc3RyZXQgaSBlbiBtb2RpZmllcmFyZ3J1cHAuCi1wYXJzZXIuZmFjdG9yLjM9JzonIGZcdTAwRjZydlx1MDBFNG50YXMuCi1wYXJzZXIuZmFjdG9yLjQ9T3ZcdTAwRTRudGF0IGF2c2x1dCBwXHUwMEU1IG1cdTAwRjZuc3RyZXQgaSBlbiB2aWxsa29yc2dydXBwLgotcGFyc2VyLmZhY3Rvci41PUJha1x1MDBFNXRyZWZlcmVucyBlbGxlciBhbmthcmUgZWxsZXIgbG9va2FoZWFkIGVsbGVyIGxvb2tiZWhpbmQgZlx1MDBGNnJ2XHUwMEU0bnRhcyBpIGV0dCB2aWxsa29yc21cdTAwRjZuc3Rlci4KLXBhcnNlci5mYWN0b3IuNj1EZXQgZmlubnMgbWVyIFx1MDBFNG4gdHJlIHZhbCBpIGVuIHZpbGxrb3JzZ3J1cHAuCi1wYXJzZXIuYXRvbS4xPUV0dCB0ZWNrZW4gaSBVKzAwNDAtVSswMDVmIG1cdTAwRTVzdGUga29tbWEgZWZ0ZXIgXFxjLgotcGFyc2VyLmF0b20uMj1FdHQgJ3snIGtyXHUwMEU0dnMgZlx1MDBGNnJlIGVuIHRlY2tlbmthdGVnb3JpLgotcGFyc2VyLmF0b20uMz1FdHQgZWdlbnNrYXBzbmFtbiBoYXIgaW50ZSBzdFx1MDBFNG5ndHMgbWVkICd9Jy4KLXBhcnNlci5hdG9tLjQ9T3ZcdTAwRTRudGF0IG1ldGF0ZWNrZW4uCi1wYXJzZXIuYXRvbS41PU9rXHUwMEU0bmQgZWdlbnNrYXAuCi1wYXJzZXIuY2MuMT1FbiBQT1NJWC10ZWNrZW5rbGFzcyBtXHUwMEU1c3RlIHN0XHUwMEU0bmdhcyBhdiAnOl0nLgotcGFyc2VyLmNjLjI9T3ZcdTAwRTRudGF0IGF2c2x1dCBwXHUwMEU1IG1cdTAwRjZuc3RyZXQgaSBlbiB0ZWNrZW5rbGFzcy4KLXBhcnNlci5jYy4zPU9rXHUwMEU0bnQgbmFtbiBwXHUwMEU1IGVuIFBPU0lYLXRlY2tlbmtsYXNzLgotcGFyc2VyLmNjLjQ9Jy0nIFx1MDBFNHIgb2dpbHRpZ3QgaFx1MDBFNHIuCi1wYXJzZXIuY2MuNT0nXScgZlx1MDBGNnJ2XHUwMEU0bnRhcy4KLXBhcnNlci5jYy42PSdbJyBcdTAwRTRyIG9naWx0aWd0IGkgZW4gdGVja2Vua2xhc3MuIFNrcml2ICdcXFsnLgotcGFyc2VyLmNjLjc9J10nIFx1MDBFNHIgb2dpbHRpZ3QgaSBlbiB0ZWNrZW5rbGFzcy4gU2tyaXYgJ1xcXScuCi1wYXJzZXIuY2MuOD0nLScgXHUwMEU0ciBldHQgb2dpbHRpZ3QgdGVja2VuaW50ZXJ2YWxsLiBTa3JpdiAnXFwtJy4KLXBhcnNlci5vcGUuMT0nWycgZlx1MDBGNnJ2XHUwMEU0bnRhcy4KLXBhcnNlci5vcGUuMj0nKScgZWxsZXIgJy1bJyBlbGxlciAnK1snIGVsbGVyICcmWycgZlx1MDBGNnJ2XHUwMEU0bnRhcy4KLXBhcnNlci5vcGUuMz1TbHV0a29kc3B1bmt0ZW4gZlx1MDBGNnIgaW50ZXJ2YWxsZXQgXHUwMEU0ciBtaW5kcmUgXHUwMEU0biBzdGFydGtvZHNwdW5rdGVuLgotcGFyc2VyLmRlc2NhcGUuMT1PZ2lsdGlnIFVuaWNvZGUgaGV4LW5vdGF0aW9uLgotcGFyc2VyLmRlc2NhcGUuMj1TcGlsbCBpIGVuIGhleC1ub3RhdGlvbi4KLXBhcnNlci5kZXNjYXBlLjM9J1xceHsnIG1cdTAwRTVzdGUgc3RcdTAwRTRuZ2FzIGF2ICd9Jy4KLXBhcnNlci5kZXNjYXBlLjQ9T2dpbHRpZyBVbmljb2RlLWtvZHB1bmt0LgotcGFyc2VyLmRlc2NhcGUuNT1FdHQgYW5rYXJlIGZcdTAwRTVyIGludGUgdmFyYSBoXHUwMEU0ci4KLXBhcnNlci5wcm9jZXNzLjE9RGV0IGhcdTAwRTRyIHV0dHJ5Y2tldCBzdFx1MDBGNmRzIGludGUgaSBha3R1ZWxsIGFsdGVybmF0aXZpbnN0XHUwMEU0bGxuaW5nLgotcGFyc2VyLnF1YW50aWZpZXIuMT1PZ2lsdGlnIGt2YW50aWZpZXJhcmUuIEVuIHNpZmZyYSBmXHUwMEY2cnZcdTAwRTRudGFzLgotcGFyc2VyLnF1YW50aWZpZXIuMj1PZ2lsdGlnIGt2YW50aWZpZXJhcmUuIE9naWx0aWcga3ZhbnRpdGV0IGVsbGVyICd9JyBzYWtuYXMuCi1wYXJzZXIucXVhbnRpZmllci4zPU9naWx0aWcga3ZhbnRpZmllcmFyZS4gRW4gc2lmZnJhIGVsbGVyICd9JyBmXHUwMEY2cnZcdTAwRTRudGFzLgotcGFyc2VyLnF1YW50aWZpZXIuND1PZ2lsdGlnIGt2YW50aWZpZXJhcmUuIEVuIG1pbmt2YW50aXRldCBtXHUwMEU1c3RlIHZhcmEgPD0gZW4gbWF4a3ZhbnRpdGV0LgotcGFyc2VyLnF1YW50aWZpZXIuNT1PZ2lsdGlnIGt2YW50aWZpZXJhcmUuIEV0dCBrdmFudGl0ZXRzdlx1MDBFNHJkZXNzcGlsbC4KLW51bGwKLW51bGwKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHBhdGgvcmVnZXgvbWVzc2FnZV96aF9DTi5wcm9wZXJ0aWVzIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cGF0aC9yZWdleC9tZXNzYWdlX3poX0NOLnByb3BlcnRpZXMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDg0NzRhNWYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cGF0aC9yZWdleC9tZXNzYWdlX3poX0NOLnByb3BlcnRpZXMKKysrIC9kZXYvbnVsbApAQCAtMSw0MSArMCwwIEBACi1wYXJzZXIucGFyc2UuMT1cdTVCNTdcdTdCMjZcdTk1MTlcdThCRUZcdTMwMDIKLXBhcnNlci5wYXJzZS4yPVx1NUYxNVx1NzUyOFx1NTNGN1x1NjVFMFx1NjU0OFx1MzAwMgotcGFyc2VyLm5leHQuMT1cXCBcdTU0MEVcdTk3NjJcdTVGQzVcdTk4N0JcdTY3MDlcdTVCNTdcdTdCMjZcdTMwMDIKLXBhcnNlci5uZXh0LjI9XHU0RTBEXHU1RTk0XHU1MUZBXHU3M0IwICc/J1x1MzAwMicoPzonIFx1NjIxNiAnKD89JyBcdTYyMTYgJyg/IScgXHU2MjE2ICcoPzwnIFx1NjIxNiAnKD8jJyBcdTYyMTYgJyg/Pic/Ci1wYXJzZXIubmV4dC4zPVx1NUU5NFx1NEUzQSAnKD88PScgXHU2MjE2ICcoPzwhJ1x1MzAwMgotcGFyc2VyLm5leHQuND1cdTZDRThcdTkxQ0FcdTY3MkFcdTdFQzhcdTZCNjJcdTMwMDIKLXBhcnNlci5mYWN0b3IuMT1cdTVFOTRcdTRFM0EgJyknXHUzMDAyCi1wYXJzZXIuZmFjdG9yLjI9XHU0RkVFXHU5OTcwXHU3QjI2XHU3RUM0XHU0RTJEXHU2MTBGXHU1OTE2XHU3Njg0XHU2QTIxXHU1RjBGXHU3RUQzXHU1QzNFXHUzMDAyCi1wYXJzZXIuZmFjdG9yLjM9XHU1RTk0XHU0RTNBICc6J1x1MzAwMgotcGFyc2VyLmZhY3Rvci40PVx1Njc2MVx1NEVGNlx1N0VDNFx1NEUyRFx1NjEwRlx1NTkxNlx1NzY4NFx1NkEyMVx1NUYwRlx1N0VEM1x1NUMzRVx1MzAwMgotcGFyc2VyLmZhY3Rvci41PVx1NTcyOFx1Njc2MVx1NEVGNlx1NkEyMVx1NUYwRlx1NEUyRFx1NUU5NFx1NEUzQVx1NTQxMVx1NTQwRVx1NUYxNVx1NzUyOFx1NjIxNlx1OTUxQVx1NUI5QVx1NzBCOVx1NjIxNlx1NTQxMVx1NTI0RFx1NjdFNVx1NjI3RVx1NjIxNlx1NTQxMVx1NTQwRVx1NjdFNVx1NjI3RVx1MzAwMgotcGFyc2VyLmZhY3Rvci42PVx1Njc2MVx1NEVGNlx1N0VDNFx1NEUyRFx1NzY4NFx1OTAwOVx1OTg3OVx1NTkxQVx1NEU4RVx1NEUwOVx1NEUyQVx1MzAwMgotcGFyc2VyLmF0b20uMT1cXGMgXHU1NDBFXHU5NzYyXHU1RkM1XHU5ODdCXHU4RERGXHU2NzA5IFUrMDA0MC1VKzAwNWYgXHU0RTJEXHU3Njg0XHU1QjU3XHU3QjI2XHUzMDAyCi1wYXJzZXIuYXRvbS4yPVx1NUI1N1x1N0IyNlx1N0M3Qlx1NTIyQlx1NTI0RFx1NUZDNVx1OTg3Qlx1NjcwOSAneydcdTMwMDIKLXBhcnNlci5hdG9tLjM9XHU1QzVFXHU2MDI3XHU1NDBEXHU2NzJBXHU0RUU1ICd9JyBcdTdFRDNcdTY3NUZcdTMwMDIKLXBhcnNlci5hdG9tLjQ9XHU2MTBGXHU1OTE2XHU3Njg0XHU1MTQzXHU1QjU3XHU3QjI2XHUzMDAyCi1wYXJzZXIuYXRvbS41PVx1NjcyQVx1NzdFNVx1NUM1RVx1NjAyN1x1MzAwMgotcGFyc2VyLmNjLjE9UE9TSVggXHU1QjU3XHU3QjI2XHU3QzdCXHU1RkM1XHU5ODdCXHU0RUU1ICc6XScgXHU3RUQzXHU2NzVGXHUzMDAyCi1wYXJzZXIuY2MuMj1cdTVCNTdcdTdCMjZcdTdDN0JcdTRFMkRcdTYxMEZcdTU5MTZcdTc2ODRcdTZBMjFcdTVGMEZcdTdFRDNcdTVDM0VcdTMwMDIKLXBhcnNlci5jYy4zPVBPU0lYIFx1NUI1N1x1N0IyNlx1N0M3Qlx1NzY4NFx1NTQwRFx1NzlGMFx1NjcyQVx1NzdFNVx1MzAwMgotcGFyc2VyLmNjLjQ9XHU2QjY0XHU1OTA0ICctJyBcdTY2MkZcdTY1RTBcdTY1NDhcdTc2ODRcdTMwMDIKLXBhcnNlci5jYy41PVx1NUU5NFx1NEUzQSAnXSdcdTMwMDIKLXBhcnNlci5jYy42PSdbJyBcdTU3MjhcdTVCNTdcdTdCMjZcdTdDN0JcdTRFMkRcdTY2MkZcdTY1RTBcdTY1NDhcdTc2ODRcdTMwMDJcdTUxOTlcdTUxNjUgJ1xcWydcdTMwMDIKLXBhcnNlci5jYy43PSddJyBcdTU3MjhcdTVCNTdcdTdCMjZcdTdDN0JcdTRFMkRcdTY2MkZcdTY1RTBcdTY1NDhcdTc2ODRcdTMwMDJcdTUxOTlcdTUxNjUgJ1xcXSdcdTMwMDIKLXBhcnNlci5jYy44PSctJyBcdTY2MkZcdTY1RTBcdTY1NDhcdTc2ODRcdTVCNTdcdTdCMjZcdTgzMDNcdTU2RjRcdTMwMDJcdTUxOTlcdTUxNjUgJ1xcLSdcdTMwMDIKLXBhcnNlci5vcGUuMT1cdTVFOTRcdTRFM0EgJ1snXHUzMDAyCi1wYXJzZXIub3BlLjI9XHU1RTk0XHU0RTNBICcpJyBcdTYyMTYgJy1bJyBcdTYyMTYgJytbJyBcdTYyMTYgJyZbJ1x1MzAwMgotcGFyc2VyLm9wZS4zPVx1ODMwM1x1NTZGNFx1N0VEM1x1Njc1Rlx1NEVFM1x1NzgwMVx1NzBCOVx1NUMwRlx1NEU4RVx1NUYwMFx1NTlDQlx1NEVFM1x1NzgwMVx1NzBCOVx1MzAwMgotcGFyc2VyLmRlc2NhcGUuMT1Vbmljb2RlIFx1NTM0MVx1NTE2RFx1OEZEQlx1NTIzNlx1OEJCMFx1NTNGN1x1NjVFMFx1NjU0OFx1MzAwMgotcGFyc2VyLmRlc2NhcGUuMj1cdTUzNDFcdTUxNkRcdThGREJcdTUyMzZcdThCQjBcdTUzRjdcdTZFQTJcdTUxRkFcdTMwMDIKLXBhcnNlci5kZXNjYXBlLjM9J1xceHsnIFx1NUZDNVx1OTg3Qlx1NEVFNSAnfScgXHU3RUQzXHU2NzVGXHUzMDAyCi1wYXJzZXIuZGVzY2FwZS40PVVuaWNvZGUgXHU0RUUzXHU3ODAxXHU3MEI5XHU2NUUwXHU2NTQ4XHUzMDAyCi1wYXJzZXIuZGVzY2FwZS41PVx1NkI2NFx1NTkwNFx1NEUwRFx1ODBGRFx1NjcwOVx1OTUxQVx1NUI5QVx1NzBCOVx1MzAwMgotcGFyc2VyLnByb2Nlc3MuMT1cdTVGNTNcdTUyNERcdTc2ODRcdTkwMDlcdTk4NzlcdThCQkVcdTdGNkVcdTRFMERcdTY1MkZcdTYzMDFcdTZCNjRcdTg4NjhcdThGQkVcdTVGMEZcdTMwMDIKLXBhcnNlci5xdWFudGlmaWVyLjE9XHU5NjUwXHU1QjlBXHU3QjI2XHU2NUUwXHU2NTQ4XHUzMDAyXHU1RTk0XHU0RTNBXHU2NTcwXHU1QjU3XHUzMDAyCi1wYXJzZXIucXVhbnRpZmllci4yPVx1OTY1MFx1NUI5QVx1N0IyNlx1NjVFMFx1NjU0OFx1MzAwMlx1N0YzQVx1NUMxMVx1NjcwOVx1NjU0OFx1NzY4NFx1NjU3MFx1OTFDRlx1NjIxNiAnfSdcdTMwMDIKLXBhcnNlci5xdWFudGlmaWVyLjM9XHU5NjUwXHU1QjlBXHU3QjI2XHU2NUUwXHU2NTQ4XHUzMDAyXHU1RTk0XHU0RTNBXHU2NTcwXHU1QjU3XHU2MjE2ICd9J1x1MzAwMgotcGFyc2VyLnF1YW50aWZpZXIuND1cdTk2NTBcdTVCOUFcdTdCMjZcdTY1RTBcdTY1NDhcdTMwMDJcdTY3MDBcdTVDMEZcdTY1NzBcdTkxQ0ZcdTVGQzVcdTk4N0JcdTVDMEZcdTRFOEVcdTdCNDlcdTRFOEVcdTY3MDBcdTU5MjdcdTY1NzBcdTkxQ0ZcdTMwMDIKLXBhcnNlci5xdWFudGlmaWVyLjU9XHU5NjUwXHU1QjlBXHU3QjI2XHU2NUUwXHU2NTQ4XHUzMDAyXHU2NTcwXHU5MUNGXHU1MDNDXHU2RUEyXHU1MUZBXHUzMDAyCi1udWxsCi1udWxsCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hwYXRoL3JlZ2V4L21lc3NhZ2VfemhfVFcucHJvcGVydGllcyBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHBhdGgvcmVnZXgvbWVzc2FnZV96aF9UVy5wcm9wZXJ0aWVzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzOGU3NTFlLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHBhdGgvcmVnZXgvbWVzc2FnZV96aF9UVy5wcm9wZXJ0aWVzCisrKyAvZGV2L251bGwKQEAgLTEsNDEgKzAsMCBAQAotcGFyc2VyLnBhcnNlLjE9XHU0RTBEXHU2QjYzXHU3OEJBXHU3Njg0XHU1QjU3XHU1MTQzLgotcGFyc2VyLnBhcnNlLjI9XHU3MTIxXHU2NTQ4XHU3Njg0XHU1M0MzXHU3MTY3XHU4NjVGXHU3OEJDLgotcGFyc2VyLm5leHQuMT1cXCBcdTRFNEJcdTVGOENcdTVGQzVcdTk4MDhcdTg5ODFcdTY3MDlcdTRFMDBcdTUwMEJcdTVCNTdcdTUxNDMuCi1wYXJzZXIubmV4dC4yPVx1NEUwRFx1NjFDOVx1NzBCQSAnPycuICAnKD86JyBcdTYyMTYgJyg/PScgXHU2MjE2ICcoPyEnIFx1NjIxNiAnKD88JyBcdTYyMTYgJyg/IycgXHU2MjE2ICcoPz4nPwotcGFyc2VyLm5leHQuMz1cdTk4MTBcdTY3MUZcdTYxQzlcdTcwQkEgJyg/PD0nIFx1NjIxNiAnKD88IScuCi1wYXJzZXIubmV4dC40PVx1OEEzQlx1ODlFM1x1NjcyQVx1N0Q0Mlx1NkI2Mi4KLXBhcnNlci5mYWN0b3IuMT1cdTk4MTBcdTY3MUZcdTYxQzlcdTY3MDkgJyknLgotcGFyc2VyLmZhY3Rvci4yPVx1NEZFRVx1OThGRVx1Njg5RFx1NEVGNlx1N0ZBNFx1N0Q0NFx1NEUyRFx1NjcwOVx1NjcyQVx1OTgxMFx1NjcxRlx1NzY4NFx1NkEyM1x1NUYwRlx1N0Q1MFx1NUMzRS4KLXBhcnNlci5mYWN0b3IuMz1cdTk4MTBcdTY3MUZcdTYxQzlcdTY3MDkgJzonLgotcGFyc2VyLmZhY3Rvci40PVx1Njg5RFx1NEVGNlx1NjAyN1x1N0ZBNFx1N0Q0NFx1NEUyRFx1NjcwOVx1NjcyQVx1OTgxMFx1NjcxRlx1NzY4NFx1NkEyM1x1NUYwRlx1N0Q1MFx1NUMzRS4KLXBhcnNlci5mYWN0b3IuNT1cdTY4OURcdTRFRjZcdTYwMjdcdTZBMjNcdTVGMEZcdTRFMkRcdTYxQzlcdThBNzJcdTY3MDlcdTVGODBcdTU2REVcdTUzQzNcdTcxNjdcdTMwMDFcdTVCOUFcdTkzMjhcdTlFREVcdTMwMDFcdTU0MTFcdTUyNERcdTY3RTVcdTYyN0VcdTYyMTZcdTU0MTFcdTVGOENcdTY3RTVcdTYyN0UuCi1wYXJzZXIuZmFjdG9yLjY9XHU2ODlEXHU0RUY2XHU2MDI3XHU3RkE0XHU3RDQ0XHU0RTJEXHU2NzA5XHU0RTA5XHU1MDBCXHU0RUU1XHU0RTBBXHU3Njg0XHU5MDc4XHU5ODA1LgotcGFyc2VyLmF0b20uMT1VKzAwNDAtVSswMDVmIFx1NUI1N1x1NTE0M1x1NUZDNVx1OTgwOFx1NjNBNVx1ODQ1NyBcXGMuCi1wYXJzZXIuYXRvbS4yPVx1NUI1N1x1NTE0M1x1OTg1RVx1NTIyNVx1NTI0RFx1OTc2Mlx1NUZDNVx1OTgwOFx1ODk4MVx1NjcwOVx1NEUwMFx1NTAwQiAneycuCi1wYXJzZXIuYXRvbS4zPVx1NzI3OVx1NjAyN1x1NTQwRFx1N0EzMVx1NjcyQVx1NEVFNSAnfScgXHU3RDUwXHU2NzVGLgotcGFyc2VyLmF0b20uND1cdTY3MkFcdTk4MTBcdTY3MUZcdTc2ODRcdTYzQ0ZcdThGRjBcdTVCNTdcdTUxNDMuCi1wYXJzZXIuYXRvbS41PVx1NEUwRFx1NjYwRVx1NzY4NFx1NzI3OVx1NjAyNy4KLXBhcnNlci5jYy4xPVBPU0lYIFx1NUI1N1x1NTE0M1x1OTg1RVx1NTIyNVx1NUZDNVx1OTgwOFx1NEVFNSAnOl0nIFx1NEY1Q1x1NzBCQVx1N0Q1MFx1Njc1Ri4KLXBhcnNlci5jYy4yPVx1NUI1N1x1NTE0M1x1OTg1RVx1NTIyNVx1NEUyRFx1NjcwOVx1NjcyQVx1OTgxMFx1NjcxRlx1NzY4NFx1NkEyM1x1NUYwRlx1N0Q1MFx1NUMzRS4KLXBhcnNlci5jYy4zPVx1NEUwRFx1NjYwRVx1NzY4NCBQT1NJWCBcdTVCNTdcdTUxNDNcdTk4NUVcdTUyMjVcdTU0MERcdTdBMzEuCi1wYXJzZXIuY2MuND0nLScgXHU1NzI4XHU2QjY0XHU4NjU1XHU3MTIxXHU2NTQ4LgotcGFyc2VyLmNjLjU9XHU5ODEwXHU2NzFGXHU2MUM5XHU2NzA5ICddJy4KLXBhcnNlci5jYy42PSdbJyBcdTU3MjhcdTVCNTdcdTUxNDNcdTk4NUVcdTUyMjVcdTRFMkRcdTcxMjFcdTY1NDguICBcdTVCRUJcdTUxNjUgJ1xcWycuCi1wYXJzZXIuY2MuNz0nXScgXHU1NzI4XHU1QjU3XHU1MTQzXHU5ODVFXHU1MjI1XHU0RTJEXHU3MTIxXHU2NTQ4LiAgXHU1QkVCXHU1MTY1ICdcXF0nLgotcGFyc2VyLmNjLjg9Jy0nIFx1NzBCQVx1NzEyMVx1NjU0OFx1NzY4NFx1NUI1N1x1NTE0M1x1N0JDNFx1NTcwRC4gXHU1QkVCXHU1MTY1ICdcXC0nLgotcGFyc2VyLm9wZS4xPVx1OTgxMFx1NjcxRlx1NjFDOVx1NjcwOSAnWycuCi1wYXJzZXIub3BlLjI9XHU5ODEwXHU2NzFGXHU2MUM5XHU2NzA5ICcpJ1x1MzAwMSctWydcdTMwMDEnK1snIFx1NjIxNiAnJlsnLgotcGFyc2VyLm9wZS4zPVx1N0JDNFx1NTcwRFx1N0Q1MFx1Njc1Rlx1NUI1N1x1NzhCQ1x1NjMwN1x1NkExOVx1NUMwRlx1NjVCQ1x1OTU4Qlx1NTlDQlx1NUI1N1x1NzhCQ1x1NjMwN1x1NkExOS4KLXBhcnNlci5kZXNjYXBlLjE9XHU3MTIxXHU2NTQ4XHU3Njg0IFVuaWNvZGUgXHU1MzQxXHU1MTZEXHU5MDMyXHU0RjREXHU4ODY4XHU3OTNBXHU2Q0Q1LgotcGFyc2VyLmRlc2NhcGUuMj1cdTUzNDFcdTUxNkRcdTkwMzJcdTRGNERcdTg4NjhcdTc5M0FcdTZDRDVcdTZFQTJcdTRGNEQuCi1wYXJzZXIuZGVzY2FwZS4zPSdcXHh7JyBcdTVGQzVcdTk4MDhcdTRFRTUgJ30nIFx1NEY1Q1x1NzBCQVx1N0Q1MFx1Njc1Ri4KLXBhcnNlci5kZXNjYXBlLjQ9XHU3MTIxXHU2NTQ4XHU3Njg0IFVuaWNvZGUgXHU1QjU3XHU3OEJDXHU2MzA3XHU2QTE5LgotcGFyc2VyLmRlc2NhcGUuNT1cdTZCNjRcdTg2NTVcdTRFMERcdTUzRUZcdTY3MDlcdTVCOUFcdTkzMjhcdTlFREUuCi1wYXJzZXIucHJvY2Vzcy4xPVx1NzZFRVx1NTI0RFx1NzY4NFx1OTA3OFx1OTgwNVx1OEEyRFx1NUI5QVx1NEUwRFx1NjUyRlx1NjNGNFx1NkI2NFx1ODg2OFx1NzkzQVx1NUYwRgotcGFyc2VyLnF1YW50aWZpZXIuMT1cdTcxMjFcdTY1NDhcdTc2ODRcdTY1NzhcdTkxQ0ZcdThBNUUuIFx1OTgxMFx1NjcxRlx1NjFDOVx1NzBCQVx1NjU3OFx1NUI1Ny4KLXBhcnNlci5xdWFudGlmaWVyLjI9XHU3MTIxXHU2NTQ4XHU3Njg0XHU2NTc4XHU5MUNGXHU4QTVFLiBcdTcxMjFcdTY1NDhcdTc2ODRcdTY1NzhcdTkxQ0ZcdTYyMTZcdTkwN0FcdTZGMEYgJ30nLgotcGFyc2VyLnF1YW50aWZpZXIuMz1cdTcxMjFcdTY1NDhcdTc2ODRcdTY1NzhcdTkxQ0ZcdThBNUUuIFx1OTgxMFx1NjcxRlx1NjFDOVx1NzBCQVx1NjU3OFx1NUI1N1x1NjIxNiAnfScuCi1wYXJzZXIucXVhbnRpZmllci40PVx1NzEyMVx1NjU0OFx1NzY4NFx1NjU3OFx1OTFDRlx1OEE1RS4gXHU2NzAwXHU1QzBGXHU2NTc4XHU5MUNGXHU1RkM1XHU5ODA4XHU1QzBGXHU2NUJDXHU2MjE2XHU3QjQ5XHU2NUJDXHU2NzAwXHU1OTI3XHU2NTc4XHU5MUNGLgotcGFyc2VyLnF1YW50aWZpZXIuNT1cdTcxMjFcdTY1NDhcdTc2ODRcdTY1NzhcdTkxQ0ZcdThBNUUuIFx1NjU3OFx1OTFDRlx1NTAzQ1x1NkVBMlx1NEY0RC4KLW51bGwKLW51bGwKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvQXR0cmlidXRlUFNWSW1wbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9BdHRyaWJ1dGVQU1ZJbXBsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDE0ZmIwNzUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9BdHRyaWJ1dGVQU1ZJbXBsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMjIgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMC0yMDAyLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54czsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuU2hvcnRMaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuU3RyaW5nTGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTQXR0cmlidXRlRGVjbGFyYXRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU1NpbXBsZVR5cGVEZWZpbml0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNUeXBlRGVmaW5pdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMudXRpbC5TdHJpbmdMaXN0SW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLkF0dHJpYnV0ZVBTVkk7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU0NvbnN0YW50czsKLQotLyoqCi0gKiBBdHRyaWJ1dGUgUFNWIGluZm9zZXQgYXVnbWVudGF0aW9ucyBpbXBsZW1lbnRhdGlvbi4KLSAqIFRoZSBQU1ZJIGluZm9ybWF0aW9uIGZvciBhdHRyaWJ1dGVzIHdpbGwgYmUgYXZhaWxhYmxlIGF0IHRoZSBzdGFydEVsZW1lbnQgY2FsbC4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBFbGVuYSBMaXRhbmkgSUJNCi0gKi8KLXB1YmxpYyBjbGFzcyBBdHRyaWJ1dGVQU1ZJbXBsIGltcGxlbWVudHMgQXR0cmlidXRlUFNWSSB7Ci0KLSAgICAvKiogYXR0cmlidXRlIGRlY2xhcmF0aW9uICovCi0gICAgcHJvdGVjdGVkIFhTQXR0cmlidXRlRGVjbGFyYXRpb24gZkRlY2xhcmF0aW9uID0gbnVsbDsKLQotICAgIC8qKiB0eXBlIG9mIGF0dHJpYnV0ZSwgc2ltcGxlVHlwZSAqLwotICAgIHByb3RlY3RlZCBYU1R5cGVEZWZpbml0aW9uIGZUeXBlRGVjbCA9IG51bGw7Ci0KLSAgICAvKiogSWYgdGhpcyBhdHRyaWJ1dGUgd2FzIGV4cGxpY2l0bHkgZ2l2ZW4gYQotICAgICAqIHZhbHVlIGluIHRoZSBvcmlnaW5hbCBkb2N1bWVudCwgdGhpcyBpcyBmYWxzZTsgb3RoZXJ3aXNlLCBpdCBpcyB0cnVlICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZlNwZWNpZmllZCA9IGZhbHNlOwotCi0gICAgLyoqIHNjaGVtYSBub3JtYWxpemVkIHZhbHVlIHByb3BlcnR5ICovCi0gICAgcHJvdGVjdGVkIFN0cmluZyBmTm9ybWFsaXplZFZhbHVlID0gbnVsbDsKLQotICAgIC8qKiBzY2hlbWEgYWN0dWFsIHZhbHVlICovCi0gICAgcHJvdGVjdGVkIE9iamVjdCBmQWN0dWFsVmFsdWUgPSBudWxsOwotCi0gICAgLyoqIHNjaGVtYSBhY3R1YWwgdmFsdWUgdHlwZSAqLwotICAgIHByb3RlY3RlZCBzaG9ydCBmQWN0dWFsVmFsdWVUeXBlID0gWFNDb25zdGFudHMuVU5BVkFJTEFCTEVfRFQ7Ci0KLSAgICAvKiogYWN0dWFsIHZhbHVlIHR5cGVzIGlmIHRoZSB2YWx1ZSBpcyBhIGxpc3QgKi8KLSAgICBwcm90ZWN0ZWQgU2hvcnRMaXN0IGZJdGVtVmFsdWVUeXBlcyA9IG51bGw7Ci0KLSAgICAvKiogbWVtYmVyIHR5cGUgZGVmaW5pdGlvbiBhZ2FpbnN0IHdoaWNoIGF0dHJpYnV0ZSB3YXMgdmFsaWRhdGVkICovCi0gICAgcHJvdGVjdGVkIFhTU2ltcGxlVHlwZURlZmluaXRpb24gZk1lbWJlclR5cGUgPSBudWxsOwotCi0gICAgLyoqIHZhbGlkYXRpb24gYXR0ZW1wdGVkOiBub25lLCBwYXJ0aWFsLCBmdWxsICovCi0gICAgcHJvdGVjdGVkIHNob3J0IGZWYWxpZGF0aW9uQXR0ZW1wdGVkID0gQXR0cmlidXRlUFNWSS5WQUxJREFUSU9OX05PTkU7Ci0KLSAgICAvKiogdmFsaWRpdHk6IHZhbGlkLCBpbnZhbGlkLCB1bmtub3duICovCi0gICAgcHJvdGVjdGVkIHNob3J0IGZWYWxpZGl0eSA9IEF0dHJpYnV0ZVBTVkkuVkFMSURJVFlfTk9US05PV047Ci0KLSAgICAvKiogZXJyb3IgY29kZXMgKi8KLSAgICBwcm90ZWN0ZWQgU3RyaW5nW10gZkVycm9yQ29kZXMgPSBudWxsOwotCi0gICAgLyoqIHZhbGlkYXRpb24gY29udGV4dDogY291bGQgYmUgUU5hbWUgb3IgWFBhdGggZXhwcmVzc2lvbiovCi0gICAgcHJvdGVjdGVkIFN0cmluZyBmVmFsaWRhdGlvbkNvbnRleHQgPSBudWxsOwotCi0gICAgLy8KLSAgICAvLyBBdHRyaWJ1dGVQU1ZJIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogW3NjaGVtYSBkZWZhdWx0XQotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgY2Fub25pY2FsIGxleGljYWwgcmVwcmVzZW50YXRpb24gb2YgdGhlIGRlY2xhcmF0aW9uJ3Mge3ZhbHVlIGNvbnN0cmFpbnR9IHZhbHVlLgotICAgICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveG1sc2NoZW1hLTEvI2Utc2NoZW1hX2RlZmF1bHQ+WE1MIFNjaGVtYSBQYXJ0IDE6IFN0cnVjdHVyZXMgW3NjaGVtYSBkZWZhdWx0XTwvYT4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFNjaGVtYURlZmF1bHQoKSB7Ci0gICAgICAgIHJldHVybiBmRGVjbGFyYXRpb24gPT0gbnVsbCA/IG51bGwgOiBmRGVjbGFyYXRpb24uZ2V0Q29uc3RyYWludFZhbHVlKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogW3NjaGVtYSBub3JtYWxpemVkIHZhbHVlXQotICAgICAqCi0gICAgICoKLSAgICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3htbHNjaGVtYS0xLyNlLXNjaGVtYV9ub3JtYWxpemVkX3ZhbHVlPlhNTCBTY2hlbWEgUGFydCAxOiBTdHJ1Y3R1cmVzIFtzY2hlbWEgbm9ybWFsaXplZCB2YWx1ZV08L2E+Ci0gICAgICogQHJldHVybiB0aGUgbm9ybWFsaXplZCB2YWx1ZSBvZiB0aGlzIGl0ZW0gYWZ0ZXIgdmFsaWRhdGlvbgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0U2NoZW1hTm9ybWFsaXplZFZhbHVlKCkgewotICAgICAgICByZXR1cm4gZk5vcm1hbGl6ZWRWYWx1ZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBbc2NoZW1hIHNwZWNpZmllZF0KLSAgICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3htbHNjaGVtYS0xLyNlLXNjaGVtYV9zcGVjaWZpZWQiPlhNTCBTY2hlbWEgUGFydCAxOiBTdHJ1Y3R1cmVzIFtzY2hlbWEgc3BlY2lmaWVkXTwvYT4KLSAgICAgKiBAcmV0dXJuIHRydWUgLSB2YWx1ZSB3YXMgc3BlY2lmaWVkIGluIHNjaGVtYSwgZmFsc2UgLSB2YWx1ZSBjb21lcyBmcm9tIHRoZSBpbmZvc2V0Ci0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0SXNTY2hlbWFTcGVjaWZpZWQoKSB7Ci0gICAgICAgIHJldHVybiBmU3BlY2lmaWVkOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogRGV0ZXJtaW5lcyB0aGUgZXh0ZW50IHRvIHdoaWNoIHRoZSBkb2N1bWVudCBoYXMgYmVlbiB2YWxpZGF0ZWQKLSAgICAgKgotICAgICAqIEByZXR1cm4gcmV0dXJuIHRoZSBbdmFsaWRhdGlvbiBhdHRlbXB0ZWRdIHByb3BlcnR5LiBUaGUgcG9zc2libGUgdmFsdWVzIGFyZQotICAgICAqICAgICAgICAgTk9fVkFMSURBVElPTiwgUEFSVElBTF9WQUxJREFUSU9OIGFuZCBGVUxMX1ZBTElEQVRJT04KLSAgICAgKi8KLSAgICBwdWJsaWMgc2hvcnQgZ2V0VmFsaWRhdGlvbkF0dGVtcHRlZCgpIHsKLSAgICAgICAgcmV0dXJuIGZWYWxpZGF0aW9uQXR0ZW1wdGVkOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIERldGVybWluZSB0aGUgdmFsaWRpdHkgb2YgdGhlIG5vZGUgd2l0aCByZXNwZWN0Ci0gICAgICogdG8gdGhlIHZhbGlkYXRpb24gYmVpbmcgYXR0ZW1wdGVkCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHJldHVybiB0aGUgW3ZhbGlkaXR5XSBwcm9wZXJ0eS4gUG9zc2libGUgdmFsdWVzIGFyZToKLSAgICAgKiAgICAgICAgIFVOS05PV05fVkFMSURJVFksIElOVkFMSURfVkFMSURJVFksIFZBTElEX1ZBTElESVRZCi0gICAgICovCi0gICAgcHVibGljIHNob3J0IGdldFZhbGlkaXR5KCkgewotICAgICAgICByZXR1cm4gZlZhbGlkaXR5OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEEgbGlzdCBvZiBlcnJvciBjb2RlcyBnZW5lcmF0ZWQgZnJvbSB2YWxpZGF0aW9uIGF0dGVtcHRzLgotICAgICAqIE5lZWQgdG8gZmluZCBhbGwgdGhlIHBvc3NpYmxlIHN1YmNsYXVzZSByZXBvcnRzIHRoYXQgbmVlZCByZXBvcnRpbmcKLSAgICAgKgotICAgICAqIEByZXR1cm4gbGlzdCBvZiBlcnJvciBjb2RlcwotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmdMaXN0IGdldEVycm9yQ29kZXMoKSB7Ci0gICAgICAgIGlmIChmRXJyb3JDb2RlcyA9PSBudWxsKQotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIHJldHVybiBuZXcgU3RyaW5nTGlzdEltcGwoZkVycm9yQ29kZXMsIGZFcnJvckNvZGVzLmxlbmd0aCk7Ci0gICAgfQotCi0gICAgLy8gVGhpcyBpcyB0aGUgb25seSBpbmZvcm1hdGlvbiB3ZSBjYW4gcHJvdmlkZSBpbiBhIHBpcGVsaW5lLgotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VmFsaWRhdGlvbkNvbnRleHQoKSB7Ci0gICAgICAgIHJldHVybiBmVmFsaWRhdGlvbkNvbnRleHQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQW4gaXRlbSBpc29tb3JwaGljIHRvIHRoZSB0eXBlIGRlZmluaXRpb24gdXNlZCB0byB2YWxpZGF0ZSB0aGlzIGVsZW1lbnQuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuICBhIHR5cGUgZGVjbGFyYXRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgWFNUeXBlRGVmaW5pdGlvbiBnZXRUeXBlRGVmaW5pdGlvbigpIHsKLSAgICAgICAgcmV0dXJuIGZUeXBlRGVjbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJZiBhbmQgb25seSBpZiB0aGF0IHR5cGUgZGVmaW5pdGlvbiBpcyBhIHNpbXBsZSB0eXBlIGRlZmluaXRpb24KLSAgICAgKiB3aXRoIHt2YXJpZXR5fSB1bmlvbiwgb3IgYSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbiB3aG9zZSB7Y29udGVudCB0eXBlfQotICAgICAqIGlzIGEgc2ltcGxlIHRoeXBlIGRlZmluaXRpb24gd2l0aCB7dmFyaWV0eX0gdW5pb24sIHRoZW4gYW4gaXRlbSBpc29tb3JwaGljCi0gICAgICogdG8gdGhhdCBtZW1iZXIgb2YgdGhlIHVuaW9uJ3Mge21lbWJlciB0eXBlIGRlZmluaXRpb25zfSB3aGljaCBhY3R1YWxseQotICAgICAqIHZhbGlkYXRlZCB0aGUgZWxlbWVudCBpdGVtJ3Mgbm9ybWFsaXplZCB2YWx1ZS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gIGEgc2ltcGxlIHR5cGUgZGVjbGFyYXRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgWFNTaW1wbGVUeXBlRGVmaW5pdGlvbiBnZXRNZW1iZXJUeXBlRGVmaW5pdGlvbigpIHsKLSAgICAgICAgcmV0dXJuIGZNZW1iZXJUeXBlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEFuIGl0ZW0gaXNvbW9ycGhpYyB0byB0aGUgYXR0cmlidXRlIGRlY2xhcmF0aW9uIHVzZWQgdG8gdmFsaWRhdGUKLSAgICAgKiB0aGlzIGF0dHJpYnV0ZS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gIGFuIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbgotICAgICAqLwotICAgIHB1YmxpYyBYU0F0dHJpYnV0ZURlY2xhcmF0aW9uIGdldEF0dHJpYnV0ZURlY2xhcmF0aW9uKCkgewotICAgICAgICByZXR1cm4gZkRlY2xhcmF0aW9uOwotICAgIH0KLQotICAgIC8qIChub24tSmF2YWRvYykKLSAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuSXRlbVBTVkkjZ2V0QWN0dWFsTm9ybWFsaXplZFZhbHVlKCkKLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0IGdldEFjdHVhbE5vcm1hbGl6ZWRWYWx1ZSgpIHsKLSAgICAgICAgcmV0dXJuIHRoaXMuZkFjdHVhbFZhbHVlOwotICAgIH0KLQotICAgIC8qIChub24tSmF2YWRvYykKLSAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuSXRlbVBTVkkjZ2V0QWN0dWFsTm9ybWFsaXplZFZhbHVlVHlwZSgpCi0gICAgICovCi0gICAgcHVibGljIHNob3J0IGdldEFjdHVhbE5vcm1hbGl6ZWRWYWx1ZVR5cGUoKSB7Ci0gICAgICAgIHJldHVybiB0aGlzLmZBY3R1YWxWYWx1ZVR5cGU7Ci0gICAgfQotCi0gICAgLyogKG5vbi1KYXZhZG9jKQotICAgICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5JdGVtUFNWSSNnZXRJdGVtVmFsdWVUeXBlcygpCi0gICAgICovCi0gICAgcHVibGljIFNob3J0TGlzdCBnZXRJdGVtVmFsdWVUeXBlcygpIHsKLSAgICAgICAgcmV0dXJuIHRoaXMuZkl0ZW1WYWx1ZVR5cGVzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJlc2V0KCkKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCByZXNldCgpIHsKLSAgICAgICAgZk5vcm1hbGl6ZWRWYWx1ZSA9IG51bGw7Ci0gICAgICAgIGZBY3R1YWxWYWx1ZSA9IG51bGw7Ci0gICAgICAgIGZBY3R1YWxWYWx1ZVR5cGUgPSBYU0NvbnN0YW50cy5VTkFWQUlMQUJMRV9EVDsKLSAgICAgICAgZkl0ZW1WYWx1ZVR5cGVzID0gbnVsbDsKLSAgICAgICAgZkRlY2xhcmF0aW9uID0gbnVsbDsKLSAgICAgICAgZlR5cGVEZWNsID0gbnVsbDsKLSAgICAgICAgZlNwZWNpZmllZCA9IGZhbHNlOwotICAgICAgICBmTWVtYmVyVHlwZSA9IG51bGw7Ci0gICAgICAgIGZWYWxpZGF0aW9uQXR0ZW1wdGVkID0gQXR0cmlidXRlUFNWSS5WQUxJREFUSU9OX05PTkU7Ci0gICAgICAgIGZWYWxpZGl0eSA9IEF0dHJpYnV0ZVBTVkkuVkFMSURJVFlfTk9US05PV047Ci0gICAgICAgIGZFcnJvckNvZGVzID0gbnVsbDsKLSAgICAgICAgZlZhbGlkYXRpb25Db250ZXh0ID0gbnVsbDsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL0VsZW1lbnRQU1ZJbXBsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL0VsZW1lbnRQU1ZJbXBsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGI1YTc3MDYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9FbGVtZW50UFNWSW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjc3ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDAtMjAwMiwyMDA0LDIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54czsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuU2hvcnRMaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuU3RyaW5nTGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTRWxlbWVudERlY2xhcmF0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNNb2RlbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTTm90YXRpb25EZWNsYXJhdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTU2ltcGxlVHlwZURlZmluaXRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU1R5cGVEZWZpbml0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy51dGlsLlN0cmluZ0xpc3RJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuRWxlbWVudFBTVkk7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU0NvbnN0YW50czsKLQotLyoqCi0gKiBFbGVtZW50IFBTViBpbmZvc2V0IGF1Z21lbnRhdGlvbnMgaW1wbGVtZW50YXRpb24uCi0gKiBUaGUgZm9sbG93aW5nIGluZm9ybWF0aW9uIHdpbGwgYmUgYXZhaWxhYmxlIGF0IHRoZSBzdGFydEVsZW1lbnQgY2FsbDoKLSAqIG5hbWUsIG5hbWVzcGFjZSwgdHlwZSwgbm90YXRpb24sIHZhbGlkYXRpb24gY29udGV4dAotICoKLSAqIFRoZSBmb2xsb3dpbmcgaW5mb3JtYXRpb24gd2lsbCBiZSBhdmFpbGFibGUgYXQgdGhlIGVuZEVsZW1lbnQgY2FsbDoKLSAqIG5pbCwgc3BlY2lmaWVkLCBub3JtYWxpemVkIHZhbHVlLCBtZW1iZXIgdHlwZSwgdmFsaWRpdHksIGVycm9yIGNvZGVzLAotICogZGVmYXVsdAotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIEVsZW5hIExpdGFuaSBJQk0KLSAqLwotcHVibGljIGNsYXNzIEVsZW1lbnRQU1ZJbXBsIGltcGxlbWVudHMgRWxlbWVudFBTVkkgewotCi0gICAgLyoqIGVsZW1lbnQgZGVjbGFyYXRpb24gKi8KLSAgICBwcm90ZWN0ZWQgWFNFbGVtZW50RGVjbGFyYXRpb24gZkRlY2xhcmF0aW9uID0gbnVsbDsKLQotICAgIC8qKiB0eXBlIG9mIGVsZW1lbnQsIGNvdWxkIGJlIHhzaTp0eXBlICovCi0gICAgcHJvdGVjdGVkIFhTVHlwZURlZmluaXRpb24gZlR5cGVEZWNsID0gbnVsbDsKLQotICAgIC8qKiB0cnVlIGlmIGNsYXVzZSAzLjIgb2YgRWxlbWVudCBMb2NhbGx5IFZhbGlkIChFbGVtZW50KSAoMy4zLjQpCi0gICAgICAqIGlzIHNhdGlzZmllZCwgb3RoZXJ3aXNlIGZhbHNlCi0gICAgICAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIGZOaWwgPSBmYWxzZTsKLQotICAgIC8qKiB0cnVlIGlmIHRoZSBlbGVtZW50IHZhbHVlIHdhcyBwcm92aWRlZCBieSB0aGUgc2NoZW1hOyBmYWxzZSBvdGhlcndpc2UuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZlNwZWNpZmllZCA9IGZhbHNlOwotCi0gICAgLyoqIHNjaGVtYSBub3JtYWxpemVkIHZhbHVlIHByb3BlcnR5ICovCi0gICAgcHJvdGVjdGVkIFN0cmluZyBmTm9ybWFsaXplZFZhbHVlID0gbnVsbDsKLQotICAgIC8qKiBzY2hlbWEgYWN0dWFsIHZhbHVlICovCi0gICAgcHJvdGVjdGVkIE9iamVjdCBmQWN0dWFsVmFsdWUgPSBudWxsOwotCi0gICAgLyoqIHNjaGVtYSBhY3R1YWwgdmFsdWUgdHlwZSAqLwotICAgIHByb3RlY3RlZCBzaG9ydCBmQWN0dWFsVmFsdWVUeXBlID0gWFNDb25zdGFudHMuVU5BVkFJTEFCTEVfRFQ7Ci0KLSAgICAvKiogYWN0dWFsIHZhbHVlIHR5cGVzIGlmIHRoZSB2YWx1ZSBpcyBhIGxpc3QgKi8KLSAgICBwcm90ZWN0ZWQgU2hvcnRMaXN0IGZJdGVtVmFsdWVUeXBlcyA9IG51bGw7Ci0KLSAgICAvKiogaHR0cDovL3d3dy53My5vcmcvVFIveG1sc2NoZW1hLTEvI2Utbm90YXRpb24qLwotICAgIHByb3RlY3RlZCBYU05vdGF0aW9uRGVjbGFyYXRpb24gZk5vdGF0aW9uID0gbnVsbDsKLQotICAgIC8qKiBtZW1iZXIgdHlwZSBkZWZpbml0aW9uIGFnYWluc3Qgd2hpY2ggZWxlbWVudCB3YXMgdmFsaWRhdGVkICovCi0gICAgcHJvdGVjdGVkIFhTU2ltcGxlVHlwZURlZmluaXRpb24gZk1lbWJlclR5cGUgPSBudWxsOwotCi0gICAgLyoqIHZhbGlkYXRpb24gYXR0ZW1wdGVkOiBub25lLCBwYXJ0aWFsLCBmdWxsICovCi0gICAgcHJvdGVjdGVkIHNob3J0IGZWYWxpZGF0aW9uQXR0ZW1wdGVkID0gRWxlbWVudFBTVkkuVkFMSURBVElPTl9OT05FOwotCi0gICAgLyoqIHZhbGlkaXR5OiB2YWxpZCwgaW52YWxpZCwgdW5rbm93biAqLwotICAgIHByb3RlY3RlZCBzaG9ydCBmVmFsaWRpdHkgPSBFbGVtZW50UFNWSS5WQUxJRElUWV9OT1RLTk9XTjsKLQotICAgIC8qKiBlcnJvciBjb2RlcyAqLwotICAgIHByb3RlY3RlZCBTdHJpbmdbXSBmRXJyb3JDb2RlcyA9IG51bGw7Ci0KLSAgICAvKiogdmFsaWRhdGlvbiBjb250ZXh0OiBjb3VsZCBiZSBRTmFtZSBvciBYUGF0aCBleHByZXNzaW9uKi8KLSAgICBwcm90ZWN0ZWQgU3RyaW5nIGZWYWxpZGF0aW9uQ29udGV4dCA9IG51bGw7Ci0KLSAgICAvKiogZGVmZXJyZWQgWFNNb2RlbCAqKi8KLSAgICBwcm90ZWN0ZWQgU2NoZW1hR3JhbW1hcltdIGZHcmFtbWFycyA9IG51bGw7Ci0KLSAgICAvKiogdGhlIHNjaGVtYSBpbmZvcm1hdGlvbiBwcm9wZXJ0eSAqLwotICAgIHByb3RlY3RlZCBYU01vZGVsIGZTY2hlbWFJbmZvcm1hdGlvbiA9IG51bGw7Ci0KLSAgICAvLwotICAgIC8vIEVsZW1lbnRQU1ZJIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogW3NjaGVtYSBkZWZhdWx0XQotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgY2Fub25pY2FsIGxleGljYWwgcmVwcmVzZW50YXRpb24gb2YgdGhlIGRlY2xhcmF0aW9uJ3Mge3ZhbHVlIGNvbnN0cmFpbnR9IHZhbHVlLgotICAgICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveG1sc2NoZW1hLTEvI2Utc2NoZW1hX2RlZmF1bHQ+WE1MIFNjaGVtYSBQYXJ0IDE6IFN0cnVjdHVyZXMgW3NjaGVtYSBkZWZhdWx0XTwvYT4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFNjaGVtYURlZmF1bHQoKSB7Ci0gICAgICAgIHJldHVybiBmRGVjbGFyYXRpb24gPT0gbnVsbCA/IG51bGwgOiBmRGVjbGFyYXRpb24uZ2V0Q29uc3RyYWludFZhbHVlKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogW3NjaGVtYSBub3JtYWxpemVkIHZhbHVlXQotICAgICAqCi0gICAgICoKLSAgICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3htbHNjaGVtYS0xLyNlLXNjaGVtYV9ub3JtYWxpemVkX3ZhbHVlPlhNTCBTY2hlbWEgUGFydCAxOiBTdHJ1Y3R1cmVzIFtzY2hlbWEgbm9ybWFsaXplZCB2YWx1ZV08L2E+Ci0gICAgICogQHJldHVybiB0aGUgbm9ybWFsaXplZCB2YWx1ZSBvZiB0aGlzIGl0ZW0gYWZ0ZXIgdmFsaWRhdGlvbgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0U2NoZW1hTm9ybWFsaXplZFZhbHVlKCkgewotICAgICAgICByZXR1cm4gZk5vcm1hbGl6ZWRWYWx1ZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBbc2NoZW1hIHNwZWNpZmllZF0KLSAgICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3htbHNjaGVtYS0xLyNlLXNjaGVtYV9zcGVjaWZpZWQiPlhNTCBTY2hlbWEgUGFydCAxOiBTdHJ1Y3R1cmVzIFtzY2hlbWEgc3BlY2lmaWVkXTwvYT4KLSAgICAgKiBAcmV0dXJuIHRydWUgLSB2YWx1ZSB3YXMgc3BlY2lmaWVkIGluIHNjaGVtYSwgZmFsc2UgLSB2YWx1ZSBjb21lcyBmcm9tIHRoZSBpbmZvc2V0Ci0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0SXNTY2hlbWFTcGVjaWZpZWQoKSB7Ci0gICAgICAgIHJldHVybiBmU3BlY2lmaWVkOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIERldGVybWluZXMgdGhlIGV4dGVudCB0byB3aGljaCB0aGUgZG9jdW1lbnQgaGFzIGJlZW4gdmFsaWRhdGVkCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHJldHVybiB0aGUgW3ZhbGlkYXRpb24gYXR0ZW1wdGVkXSBwcm9wZXJ0eS4gVGhlIHBvc3NpYmxlIHZhbHVlcyBhcmUKLSAgICAgKiAgICAgICAgIE5PX1ZBTElEQVRJT04sIFBBUlRJQUxfVkFMSURBVElPTiBhbmQgRlVMTF9WQUxJREFUSU9OCi0gICAgICovCi0gICAgcHVibGljIHNob3J0IGdldFZhbGlkYXRpb25BdHRlbXB0ZWQoKSB7Ci0gICAgICAgIHJldHVybiBmVmFsaWRhdGlvbkF0dGVtcHRlZDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBEZXRlcm1pbmUgdGhlIHZhbGlkaXR5IG9mIHRoZSBub2RlIHdpdGggcmVzcGVjdAotICAgICAqIHRvIHRoZSB2YWxpZGF0aW9uIGJlaW5nIGF0dGVtcHRlZAotICAgICAqCi0gICAgICogQHJldHVybiByZXR1cm4gdGhlIFt2YWxpZGl0eV0gcHJvcGVydHkuIFBvc3NpYmxlIHZhbHVlcyBhcmU6Ci0gICAgICogICAgICAgICBVTktOT1dOX1ZBTElESVRZLCBJTlZBTElEX1ZBTElESVRZLCBWQUxJRF9WQUxJRElUWQotICAgICAqLwotICAgIHB1YmxpYyBzaG9ydCBnZXRWYWxpZGl0eSgpIHsKLSAgICAgICAgcmV0dXJuIGZWYWxpZGl0eTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBIGxpc3Qgb2YgZXJyb3IgY29kZXMgZ2VuZXJhdGVkIGZyb20gdmFsaWRhdGlvbiBhdHRlbXB0cy4KLSAgICAgKiBOZWVkIHRvIGZpbmQgYWxsIHRoZSBwb3NzaWJsZSBzdWJjbGF1c2UgcmVwb3J0cyB0aGF0IG5lZWQgcmVwb3J0aW5nCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIEFycmF5IG9mIGVycm9yIGNvZGVzCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZ0xpc3QgZ2V0RXJyb3JDb2RlcygpIHsKLSAgICAgICAgaWYgKGZFcnJvckNvZGVzID09IG51bGwpCi0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgcmV0dXJuIG5ldyBTdHJpbmdMaXN0SW1wbChmRXJyb3JDb2RlcywgZkVycm9yQ29kZXMubGVuZ3RoKTsKLSAgICB9Ci0KLQotICAgIC8vIFRoaXMgaXMgdGhlIG9ubHkgaW5mb3JtYXRpb24gd2UgY2FuIHByb3ZpZGUgaW4gYSBwaXBlbGluZS4KLSAgICBwdWJsaWMgU3RyaW5nIGdldFZhbGlkYXRpb25Db250ZXh0KCkgewotICAgICAgICByZXR1cm4gZlZhbGlkYXRpb25Db250ZXh0OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFtuaWxdCi0gICAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94bWxzY2hlbWEtMS8jZS1uaWw+WE1MIFNjaGVtYSBQYXJ0IDE6IFN0cnVjdHVyZXMgW25pbF08L2E+Ci0gICAgICogQHJldHVybiB0cnVlIGlmIGNsYXVzZSAzLjIgb2YgRWxlbWVudCBMb2NhbGx5IFZhbGlkIChFbGVtZW50KSAoMy4zLjQpIGFib3ZlIGlzIHNhdGlzZmllZCwgb3RoZXJ3aXNlIGZhbHNlCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0TmlsKCkgewotICAgICAgICByZXR1cm4gZk5pbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBbbm90YXRpb25dCi0gICAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94bWxzY2hlbWEtMS8jZS1ub3RhdGlvbj5YTUwgU2NoZW1hIFBhcnQgMTogU3RydWN0dXJlcyBbbm90YXRpb25dPC9hPgotICAgICAqIEByZXR1cm4gVGhlIG5vdGF0aW9uIGRlY2xhcmF0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBYU05vdGF0aW9uRGVjbGFyYXRpb24gZ2V0Tm90YXRpb24oKSB7Ci0gICAgICAgIHJldHVybiBmTm90YXRpb247Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQW4gaXRlbSBpc29tb3JwaGljIHRvIHRoZSB0eXBlIGRlZmluaXRpb24gdXNlZCB0byB2YWxpZGF0ZSB0aGlzIGVsZW1lbnQuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuICBhIHR5cGUgZGVjbGFyYXRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgWFNUeXBlRGVmaW5pdGlvbiBnZXRUeXBlRGVmaW5pdGlvbigpIHsKLSAgICAgICAgcmV0dXJuIGZUeXBlRGVjbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJZiBhbmQgb25seSBpZiB0aGF0IHR5cGUgZGVmaW5pdGlvbiBpcyBhIHNpbXBsZSB0eXBlIGRlZmluaXRpb24KLSAgICAgKiB3aXRoIHt2YXJpZXR5fSB1bmlvbiwgb3IgYSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbiB3aG9zZSB7Y29udGVudCB0eXBlfQotICAgICAqIGlzIGEgc2ltcGxlIHRoeXBlIGRlZmluaXRpb24gd2l0aCB7dmFyaWV0eX0gdW5pb24sIHRoZW4gYW4gaXRlbSBpc29tb3JwaGljCi0gICAgICogdG8gdGhhdCBtZW1iZXIgb2YgdGhlIHVuaW9uJ3Mge21lbWJlciB0eXBlIGRlZmluaXRpb25zfSB3aGljaCBhY3R1YWxseQotICAgICAqIHZhbGlkYXRlZCB0aGUgZWxlbWVudCBpdGVtJ3Mgbm9ybWFsaXplZCB2YWx1ZS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gIGEgc2ltcGxlIHR5cGUgZGVjbGFyYXRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgWFNTaW1wbGVUeXBlRGVmaW5pdGlvbiBnZXRNZW1iZXJUeXBlRGVmaW5pdGlvbigpIHsKLSAgICAgICAgcmV0dXJuIGZNZW1iZXJUeXBlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEFuIGl0ZW0gaXNvbW9ycGhpYyB0byB0aGUgZWxlbWVudCBkZWNsYXJhdGlvbiB1c2VkIHRvIHZhbGlkYXRlCi0gICAgICogdGhpcyBlbGVtZW50LgotICAgICAqCi0gICAgICogQHJldHVybiAgYW4gZWxlbWVudCBkZWNsYXJhdGlvbgotICAgICAqLwotICAgIHB1YmxpYyBYU0VsZW1lbnREZWNsYXJhdGlvbiBnZXRFbGVtZW50RGVjbGFyYXRpb24oKSB7Ci0gICAgICAgIHJldHVybiBmRGVjbGFyYXRpb247Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogW3NjaGVtYSBpbmZvcm1hdGlvbl0KLSAgICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3htbHNjaGVtYS0xLyNlLXNjaGVtYV9pbmZvcm1hdGlvbiI+WE1MIFNjaGVtYSBQYXJ0IDE6IFN0cnVjdHVyZXMgW3NjaGVtYSBpbmZvcm1hdGlvbl08L2E+Ci0gICAgICogQHJldHVybiBUaGUgc2NoZW1hIGluZm9ybWF0aW9uIHByb3BlcnR5IGlmIGl0J3MgdGhlIHZhbGlkYXRpb24gcm9vdCwKLSAgICAgKiAgICAgICAgIG51bGwgb3RoZXJ3aXNlLgotICAgICAqLwotICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgWFNNb2RlbCBnZXRTY2hlbWFJbmZvcm1hdGlvbigpIHsKLSAgICAgICAgaWYgKGZTY2hlbWFJbmZvcm1hdGlvbiA9PSBudWxsICYmIGZHcmFtbWFycyAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmU2NoZW1hSW5mb3JtYXRpb24gPSBuZXcgWFNNb2RlbEltcGwoZkdyYW1tYXJzKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZlNjaGVtYUluZm9ybWF0aW9uOwotICAgIH0KLQotICAgIC8qIChub24tSmF2YWRvYykKLSAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuSXRlbVBTVkkjZ2V0QWN0dWFsTm9ybWFsaXplZFZhbHVlKCkKLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0IGdldEFjdHVhbE5vcm1hbGl6ZWRWYWx1ZSgpIHsKLSAgICAgICAgcmV0dXJuIHRoaXMuZkFjdHVhbFZhbHVlOwotICAgIH0KLQotICAgIC8qIChub24tSmF2YWRvYykKLSAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuSXRlbVBTVkkjZ2V0QWN0dWFsTm9ybWFsaXplZFZhbHVlVHlwZSgpCi0gICAgICovCi0gICAgcHVibGljIHNob3J0IGdldEFjdHVhbE5vcm1hbGl6ZWRWYWx1ZVR5cGUoKSB7Ci0gICAgICAgIHJldHVybiB0aGlzLmZBY3R1YWxWYWx1ZVR5cGU7Ci0gICAgfQotCi0gICAgLyogKG5vbi1KYXZhZG9jKQotICAgICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5JdGVtUFNWSSNnZXRJdGVtVmFsdWVUeXBlcygpCi0gICAgICovCi0gICAgcHVibGljIFNob3J0TGlzdCBnZXRJdGVtVmFsdWVUeXBlcygpIHsKLSAgICAgICAgcmV0dXJuIHRoaXMuZkl0ZW1WYWx1ZVR5cGVzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJlc2V0KCkgc2hvdWxkIGJlIGNhbGxlZCBpbiB2YWxpZGF0b3Igc3RhcnRFbGVtZW50KC4uKSBtZXRob2QuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcmVzZXQoKSB7Ci0gICAgICAgIGZEZWNsYXJhdGlvbiA9IG51bGw7Ci0gICAgICAgIGZUeXBlRGVjbCA9IG51bGw7Ci0gICAgICAgIGZOaWwgPSBmYWxzZTsKLSAgICAgICAgZlNwZWNpZmllZCA9IGZhbHNlOwotICAgICAgICBmTm90YXRpb24gPSBudWxsOwotICAgICAgICBmTWVtYmVyVHlwZSA9IG51bGw7Ci0gICAgICAgIGZWYWxpZGF0aW9uQXR0ZW1wdGVkID0gRWxlbWVudFBTVkkuVkFMSURBVElPTl9OT05FOwotICAgICAgICBmVmFsaWRpdHkgPSBFbGVtZW50UFNWSS5WQUxJRElUWV9OT1RLTk9XTjsKLSAgICAgICAgZkVycm9yQ29kZXMgPSBudWxsOwotICAgICAgICBmVmFsaWRhdGlvbkNvbnRleHQgPSBudWxsOwotICAgICAgICBmTm9ybWFsaXplZFZhbHVlID0gbnVsbDsKLSAgICAgICAgZkFjdHVhbFZhbHVlID0gbnVsbDsKLSAgICAgICAgZkFjdHVhbFZhbHVlVHlwZSA9IFhTQ29uc3RhbnRzLlVOQVZBSUxBQkxFX0RUOwotICAgICAgICBmSXRlbVZhbHVlVHlwZXMgPSBudWxsOwotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9TY2hlbWFHcmFtbWFyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL1NjaGVtYUdyYW1tYXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZWE0NTAwMy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL1NjaGVtYUdyYW1tYXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE2ODggKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHM7Ci0KLWltcG9ydCBqYXZhLmxhbmcucmVmLlNvZnRSZWZlcmVuY2U7Ci1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5Db25zdGFudHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LlNjaGVtYURWRmFjdG9yeTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYuVmFsaWRhdGVkSW5mbzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYuWFNTaW1wbGVUeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi54cy5YU1NpbXBsZVR5cGVEZWNsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5pZGVudGl0eS5JZGVudGl0eUNvbnN0cmFpbnQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLnV0aWwuT2JqZWN0TGlzdEltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLnV0aWwuU2ltcGxlTG9jYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMudXRpbC5TdHJpbmdMaXN0SW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMudXRpbC5YU05hbWVkTWFwNFR5cGVzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy51dGlsLlhTTmFtZWRNYXBJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy51dGlsLlhTT2JqZWN0TGlzdEltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5wYXJzZXJzLkRPTVBhcnNlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnBhcnNlcnMuU0FYUGFyc2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwucGFyc2Vycy5YTUwxMUNvbmZpZ3VyYXRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlN5bWJvbEhhc2g7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlN5bWJvbFRhYmxlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLk5hbWVzcGFjZUNvbnRleHQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuZ3JhbW1hcnMuWE1MR3JhbW1hckRlc2NyaXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLmdyYW1tYXJzLlhTR3JhbW1hcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlN0cmluZ0xpc3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU0Fubm90YXRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU0F0dHJpYnV0ZURlY2xhcmF0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNBdHRyaWJ1dGVHcm91cERlZmluaXRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU0NvbnN0YW50czsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTRWxlbWVudERlY2xhcmF0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNNb2RlbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTTW9kZWxHcm91cERlZmluaXRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU05hbWVkTWFwOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNOYW1lc3BhY2VJdGVtOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNOb3RhdGlvbkRlY2xhcmF0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNPYmplY3RMaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNQYXJ0aWNsZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTVHlwZURlZmluaXRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU1dpbGRjYXJkOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuZGF0YXR5cGVzLk9iamVjdExpc3Q7Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgaXMgdG8gaG9sZCBhbGwgc2NoZW1hIGNvbXBvbmVudCBkZWNsYXJhdGlvbiB0aGF0IGFyZSBkZWNsYXJlZAotICogd2l0aGluIG9uZSBuYW1lc3BhY2UuCi0gKgotICogVGhlIEdyYW1tYXIgY2xhc3MgdGhpcyBjbGFzcyBleHRlbmRzIGNvbnRhaW5zIHdoYXQgbGl0dGxlCi0gKiBjb21tb25hbGl0eSB0aGVyZSBpcyBiZXR3ZWVuIFhNTCBTY2hlbWEgYW5kIERURCBncmFtbWFycy4gIEl0J3MKLSAqIHVzZWZ1bCB0byBkaXN0aW5ndWlzaCBncmFtbWFyIG9iamVjdHMgZnJvbSBvdGhlciBraW5kcyBvZiBvYmplY3QKLSAqIHdoZW4gdGhleSBleGlzdCBpbiBwb29scyBvciBjYWNoZXMuCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgU2FuZHkgR2FvLCBJQk0KLSAqIEBhdXRob3IgRWxlbmEgTGl0YW5pLCBJQk0KLSAqCi0gKiBAdmVyc2lvbiAkSWQ6IFNjaGVtYUdyYW1tYXIuamF2YSx2IDEuNyAyMDEwLTExLTAxIDA0OjM5OjU1IGpvZWh3IEV4cCAkCi0gKi8KLQotcHVibGljIGNsYXNzIFNjaGVtYUdyYW1tYXIgaW1wbGVtZW50cyBYU0dyYW1tYXIsIFhTTmFtZXNwYWNlSXRlbSB7Ci0KLSAgICAvLyB0aGUgdGFyZ2V0IG5hbWVzcGFjZSBvZiBncmFtbWFyCi0gICAgU3RyaW5nIGZUYXJnZXROYW1lc3BhY2U7Ci0KLSAgICAvLyBnbG9iYWwgZGVjbHM6IG1hcCBmcm9tIGRlY2wgbmFtZSB0byBkZWNsIG9iamVjdAotICAgIFN5bWJvbEhhc2ggZkdsb2JhbEF0dHJEZWNsczsKLSAgICBTeW1ib2xIYXNoIGZHbG9iYWxBdHRyR3JwRGVjbHM7Ci0gICAgU3ltYm9sSGFzaCBmR2xvYmFsRWxlbURlY2xzOwotICAgIFN5bWJvbEhhc2ggZkdsb2JhbEdyb3VwRGVjbHM7Ci0gICAgU3ltYm9sSGFzaCBmR2xvYmFsTm90YXRpb25EZWNsczsKLSAgICBTeW1ib2xIYXNoIGZHbG9iYWxJRENvbnN0cmFpbnREZWNsczsKLSAgICBTeW1ib2xIYXNoIGZHbG9iYWxUeXBlRGVjbHM7Ci0KLSAgICAvLyBleHRlbmRlZCBnbG9iYWwgZGVjbHM6IG1hcCBmcm9tIHNjaGVtYSBsb2NhdGlvbiArIGRlY2wgbmFtZSB0byBkZWNsIG9iamVjdAotICAgIC8vIGtleSBpcyBsb2NhdGlvbixuYW1lCi0gICAgU3ltYm9sSGFzaCBmR2xvYmFsQXR0ckRlY2xzRXh0OwotICAgIFN5bWJvbEhhc2ggZkdsb2JhbEF0dHJHcnBEZWNsc0V4dDsKLSAgICBTeW1ib2xIYXNoIGZHbG9iYWxFbGVtRGVjbHNFeHQ7Ci0gICAgU3ltYm9sSGFzaCBmR2xvYmFsR3JvdXBEZWNsc0V4dDsKLSAgICBTeW1ib2xIYXNoIGZHbG9iYWxOb3RhdGlvbkRlY2xzRXh0OwotICAgIFN5bWJvbEhhc2ggZkdsb2JhbElEQ29uc3RyYWludERlY2xzRXh0OwotICAgIFN5bWJvbEhhc2ggZkdsb2JhbFR5cGVEZWNsc0V4dDsKLQotICAgIC8vIEEgZ2xvYmFsIG1hcCBvZiBhbGwgZ2xvYmFsIGVsZW1lbnQgZGVjbGFyYXRpb25zIC0gdXNlZCBmb3Igc3Vic3RpdHV0aW9uIGdyb3VwIGNvbXB1dGF0aW9uCi0gICAgLy8gKGhhbmR5IHdoZW4gc2hhcmluZyBjb21wb25lbnRzIGJ5IHJlZmVyZW5jZSwgc2luY2Ugd2UgbWlnaHQgZW5kIHVwIHdpdGggZHVwbGljYXRlIGNvbXBvbmVudHMKLSAgICAvLyAgdGhhdCBhcmUgbm90IGFkZGVkIHRvIGVpdGhlciBvZiB0aGUgZ2xvYmFsIGVsZW1lbnQgZGVjbGFyYXRpb25zIGFib3ZlKQotICAgIFN5bWJvbEhhc2ggZkFsbEdsb2JhbEVsZW1EZWNsczsKLQotICAgIC8vIHRoZSBYTUxHcmFtbWFyRGVzY3JpcHRpb24gbWVtYmVyCi0gICAgWFNERGVzY3JpcHRpb24gZkdyYW1tYXJEZXNjcmlwdGlvbiA9IG51bGw7Ci0KLSAgICAvLyBhbm5vdGF0aW9ucyBhc3NvY2lhdGVkIHdpdGggdGhlICJyb290IiBzY2hlbWEgb2YgdGhpcyB0YXJnZXROYW1lc3BhY2UKLSAgICBYU0Fubm90YXRpb25JbXBsIFtdIGZBbm5vdGF0aW9ucyA9IG51bGw7Ci0KLSAgICAvLyBudW1iZXIgb2YgYW5ub3RhdGlvbnMgZGVjbGFyZWQKLSAgICBpbnQgZk51bUFubm90YXRpb25zOwotCi0gICAgLy8gc3ltYm9sIHRhYmxlIGZvciBjb25zdHJ1Y3RpbmcgcGFyc2VycyAoYW5ub3RhdGlvbiBzdXBwb3J0KQotICAgIHByaXZhdGUgU3ltYm9sVGFibGUgZlN5bWJvbFRhYmxlID0gbnVsbDsKLSAgICAvLyBwYXJzZXJzIGZvciBhbm5vdGF0aW9uIHN1cHBvcnQKLSAgICBwcml2YXRlIFNvZnRSZWZlcmVuY2UgZlNBWFBhcnNlciA9IG51bGw7Ci0gICAgcHJpdmF0ZSBTb2Z0UmVmZXJlbmNlIGZET01QYXJzZXIgPSBudWxsOwotCi0gICAgLy8gaXMgdGhpcyBncmFtbWFyIGltbXV0YWJsZT8gIChmdWxseSBjb25zdHJ1Y3RlZCBhbmQgbm90IGNoYW5nZWFibGUpCi0gICAgcHJpdmF0ZSBib29sZWFuIGZJc0ltbXV0YWJsZSA9IGZhbHNlOwotCi0gICAgLy8KLSAgICAvLyBDb25zdHJ1Y3RvcnMKLSAgICAvLwotCi0gICAgLy8gbmVlZGVkIHRvIG1ha2UgQnVpbHRpblNjaGVtYUdyYW1tYXIgd29yay4KLSAgICBwcm90ZWN0ZWQgU2NoZW1hR3JhbW1hcigpIHt9Ci0KLSAgICAvKioKLSAgICAgKiBEZWZhdWx0IGNvbnN0cnVjdG9yLgotICAgICAqCi0gICAgICogQHBhcmFtIHRhcmdldE5hbWVzcGFjZQotICAgICAqIEBwYXJhbSBncmFtbWFyRGVzYyB0aGUgWE1MR3JhbW1hckRlc2NyaXB0aW9uIGNvcnJlc3BvbmRpbmcgdG8gdGhpcyBvYmplYwotICAgICAqICAgICAgICAgIGF0IHRoZSBsZWFzdCBhIHN5c3RlbUlkIHNob3VsZCBhbHdheXMgYmUga25vd24uCi0gICAgICogQHBhcmFtIHN5bWJvbFRhYmxlICAgbmVlZGVkIGZvciBhbm5vdGF0aW9uIHN1cHBvcnQKLSAgICAgKi8KLSAgICBwdWJsaWMgU2NoZW1hR3JhbW1hcihTdHJpbmcgdGFyZ2V0TmFtZXNwYWNlLCBYU0REZXNjcmlwdGlvbiBncmFtbWFyRGVzYywKLSAgICAgICAgICAgICAgICBTeW1ib2xUYWJsZSBzeW1ib2xUYWJsZSkgewotICAgICAgICBmVGFyZ2V0TmFtZXNwYWNlID0gdGFyZ2V0TmFtZXNwYWNlOwotICAgICAgICBmR3JhbW1hckRlc2NyaXB0aW9uID0gZ3JhbW1hckRlc2M7Ci0gICAgICAgIGZTeW1ib2xUYWJsZSA9IHN5bWJvbFRhYmxlOwotCi0gICAgICAgIC8vIFJFVklTSVQ6IGRvIHdlIGtub3cgdGhlIG51bWJlcnMgb2YgdGhlIGZvbGxvd2luZyBnbG9iYWwgZGVjbHMKLSAgICAgICAgLy8gd2hlbiBjcmVhdGluZyB0aGlzIGdyYW1tYXI/IElmIHNvLCB3ZSBjYW4gcGFzcyB0aGUgbnVtYmVycyBpbiwKLSAgICAgICAgLy8gYW5kIHVzZSB0aGF0IG51bWJlciB0byBpbml0aWFsaXplIHRoZSBmb2xsb3dpbmcgaGFzaHRhYmxlcy4KLSAgICAgICAgZkdsb2JhbEF0dHJEZWNscyAgPSBuZXcgU3ltYm9sSGFzaCgpOwotICAgICAgICBmR2xvYmFsQXR0ckdycERlY2xzID0gbmV3IFN5bWJvbEhhc2goKTsKLSAgICAgICAgZkdsb2JhbEVsZW1EZWNscyA9IG5ldyBTeW1ib2xIYXNoKCk7Ci0gICAgICAgIGZHbG9iYWxHcm91cERlY2xzID0gbmV3IFN5bWJvbEhhc2goKTsKLSAgICAgICAgZkdsb2JhbE5vdGF0aW9uRGVjbHMgPSBuZXcgU3ltYm9sSGFzaCgpOwotICAgICAgICBmR2xvYmFsSURDb25zdHJhaW50RGVjbHMgPSBuZXcgU3ltYm9sSGFzaCgpOwotCi0gICAgICAgIC8vIEV4dGVuZGVkIHRhYmxlcwotICAgICAgICBmR2xvYmFsQXR0ckRlY2xzRXh0ICA9IG5ldyBTeW1ib2xIYXNoKCk7Ci0gICAgICAgIGZHbG9iYWxBdHRyR3JwRGVjbHNFeHQgPSBuZXcgU3ltYm9sSGFzaCgpOwotICAgICAgICBmR2xvYmFsRWxlbURlY2xzRXh0ID0gbmV3IFN5bWJvbEhhc2goKTsKLSAgICAgICAgZkdsb2JhbEdyb3VwRGVjbHNFeHQgPSBuZXcgU3ltYm9sSGFzaCgpOwotICAgICAgICBmR2xvYmFsTm90YXRpb25EZWNsc0V4dCA9IG5ldyBTeW1ib2xIYXNoKCk7Ci0gICAgICAgIGZHbG9iYWxJRENvbnN0cmFpbnREZWNsc0V4dCA9IG5ldyBTeW1ib2xIYXNoKCk7Ci0gICAgICAgIGZHbG9iYWxUeXBlRGVjbHNFeHQgPSBuZXcgU3ltYm9sSGFzaCgpOwotCi0gICAgICAgIC8vIEFsbCBnbG9iYWwgZWxlbWVudHMgdGFibGUKLSAgICAgICAgZkFsbEdsb2JhbEVsZW1EZWNscyA9IG5ldyBTeW1ib2xIYXNoKCk7Ci0KLSAgICAgICAgLy8gaWYgd2UgYXJlIHBhcnNpbmcgUzRTLCBwdXQgYnVpbHQtaW4gdHlwZXMgaW4gZmlyc3QKLSAgICAgICAgLy8gdGhleSBtaWdodCBnZXQgb3ZlcndyaXR0ZW4gYnkgdGhlIHR5cGVzIGZyb20gUzRTLCBidXQgdGhhdCdzCi0gICAgICAgIC8vIGNvbnNpZGVyZWQgd2hhdCB0aGUgYXBwbGljYXRpb24gd2FudHMgdG8gZG8uCi0gICAgICAgIGlmIChmVGFyZ2V0TmFtZXNwYWNlID09IFNjaGVtYVN5bWJvbHMuVVJJX1NDSEVNQUZPUlNDSEVNQSkKLSAgICAgICAgICAgIGZHbG9iYWxUeXBlRGVjbHMgPSBTR19TY2hlbWFOUy5mR2xvYmFsVHlwZURlY2xzLm1ha2VDbG9uZSgpOwotICAgICAgICBlbHNlCi0gICAgICAgICAgICBmR2xvYmFsVHlwZURlY2xzID0gbmV3IFN5bWJvbEhhc2goKTsKLSAgICB9IC8vIDxpbml0PihTdHJpbmcsIFhTRERlc2NyaXB0aW9uKQotCi0gICAgLy8gQ2xvbmUgYW4gZXhpc3Rpbmcgc2NoZW1hIGdyYW1tYXIKLSAgICBwdWJsaWMgU2NoZW1hR3JhbW1hcihTY2hlbWFHcmFtbWFyIGdyYW1tYXIpIHsKLSAgICAgICAgZlRhcmdldE5hbWVzcGFjZSA9IGdyYW1tYXIuZlRhcmdldE5hbWVzcGFjZTsKLSAgICAgICAgZkdyYW1tYXJEZXNjcmlwdGlvbiA9IGdyYW1tYXIuZkdyYW1tYXJEZXNjcmlwdGlvbi5tYWtlQ2xvbmUoKTsKLSAgICAgICAgLy9mR3JhbW1hckRlc2NyaXB0aW9uLmZDb250ZXh0VHlwZSB8PSBYU0REZXNjcmlwdGlvbi5DT05URVhUX0NPTExJU0lPTjsgLy8gUkVWSVNJVAotICAgICAgICBmU3ltYm9sVGFibGUgPSBncmFtbWFyLmZTeW1ib2xUYWJsZTsgLy8gUkVWSVNJVAotCi0gICAgICAgIGZHbG9iYWxBdHRyRGVjbHMgID0gZ3JhbW1hci5mR2xvYmFsQXR0ckRlY2xzLm1ha2VDbG9uZSgpOwotICAgICAgICBmR2xvYmFsQXR0ckdycERlY2xzID0gZ3JhbW1hci5mR2xvYmFsQXR0ckdycERlY2xzLm1ha2VDbG9uZSgpOwotICAgICAgICBmR2xvYmFsRWxlbURlY2xzID0gZ3JhbW1hci5mR2xvYmFsRWxlbURlY2xzLm1ha2VDbG9uZSgpOwotICAgICAgICBmR2xvYmFsR3JvdXBEZWNscyA9IGdyYW1tYXIuZkdsb2JhbEdyb3VwRGVjbHMubWFrZUNsb25lKCk7Ci0gICAgICAgIGZHbG9iYWxOb3RhdGlvbkRlY2xzID0gZ3JhbW1hci5mR2xvYmFsTm90YXRpb25EZWNscy5tYWtlQ2xvbmUoKTsKLSAgICAgICAgZkdsb2JhbElEQ29uc3RyYWludERlY2xzID0gZ3JhbW1hci5mR2xvYmFsSURDb25zdHJhaW50RGVjbHMubWFrZUNsb25lKCk7Ci0gICAgICAgIGZHbG9iYWxUeXBlRGVjbHMgPSBncmFtbWFyLmZHbG9iYWxUeXBlRGVjbHMubWFrZUNsb25lKCk7Ci0KLSAgICAgICAgLy8gRXh0ZW5kZWQgdGFibGVzCi0gICAgICAgIGZHbG9iYWxBdHRyRGVjbHNFeHQgID0gZ3JhbW1hci5mR2xvYmFsQXR0ckRlY2xzRXh0Lm1ha2VDbG9uZSgpOwotICAgICAgICBmR2xvYmFsQXR0ckdycERlY2xzRXh0ID0gZ3JhbW1hci5mR2xvYmFsQXR0ckdycERlY2xzRXh0Lm1ha2VDbG9uZSgpOwotICAgICAgICBmR2xvYmFsRWxlbURlY2xzRXh0ID0gZ3JhbW1hci5mR2xvYmFsRWxlbURlY2xzRXh0Lm1ha2VDbG9uZSgpOwotICAgICAgICBmR2xvYmFsR3JvdXBEZWNsc0V4dCA9IGdyYW1tYXIuZkdsb2JhbEdyb3VwRGVjbHNFeHQubWFrZUNsb25lKCk7Ci0gICAgICAgIGZHbG9iYWxOb3RhdGlvbkRlY2xzRXh0ID0gZ3JhbW1hci5mR2xvYmFsTm90YXRpb25EZWNsc0V4dC5tYWtlQ2xvbmUoKTsKLSAgICAgICAgZkdsb2JhbElEQ29uc3RyYWludERlY2xzRXh0ID0gZ3JhbW1hci5mR2xvYmFsSURDb25zdHJhaW50RGVjbHNFeHQubWFrZUNsb25lKCk7Ci0gICAgICAgIGZHbG9iYWxUeXBlRGVjbHNFeHQgPSBncmFtbWFyLmZHbG9iYWxUeXBlRGVjbHNFeHQubWFrZUNsb25lKCk7Ci0KLSAgICAgICAgLy8gQWxsIGdsb2JhbCBlbGVtZW50cyB0YWJsZQotICAgICAgICBmQWxsR2xvYmFsRWxlbURlY2xzID0gZ3JhbW1hci5mQWxsR2xvYmFsRWxlbURlY2xzLm1ha2VDbG9uZSgpOwotCi0gICAgICAgIC8vIEFubm90YXRpb25zIGFzc29jaWF0ZWQgd2l0aCB0aGUgInJvb3QiIHNjaGVtYSBvZiB0aGlzIHRhcmdldE5hbWVzcGFjZQotICAgICAgICBmTnVtQW5ub3RhdGlvbnMgPSBncmFtbWFyLmZOdW1Bbm5vdGF0aW9uczsKLSAgICAgICAgaWYgKGZOdW1Bbm5vdGF0aW9ucyA+IDApIHsKLSAgICAgICAgICAgIGZBbm5vdGF0aW9ucyA9IG5ldyBYU0Fubm90YXRpb25JbXBsW2dyYW1tYXIuZkFubm90YXRpb25zLmxlbmd0aF07Ci0gICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGdyYW1tYXIuZkFubm90YXRpb25zLCAwLCBmQW5ub3RhdGlvbnMsIDAsIGZOdW1Bbm5vdGF0aW9ucyk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBBbGwgc3Vic3RpdHV0aW9uIGdyb3VwIGluZm9ybWF0aW9uIGRlY2xhcmVkIGluIHRoaXMgbmFtZXNwYWNlCi0gICAgICAgIGZTdWJHcm91cENvdW50ID0gZ3JhbW1hci5mU3ViR3JvdXBDb3VudDsKLSAgICAgICAgaWYgKGZTdWJHcm91cENvdW50ID4gMCkgewotICAgICAgICAgICAgZlN1Ykdyb3VwcyA9IG5ldyBYU0VsZW1lbnREZWNsW2dyYW1tYXIuZlN1Ykdyb3Vwcy5sZW5ndGhdOwotICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShncmFtbWFyLmZTdWJHcm91cHMsIDAsIGZTdWJHcm91cHMsIDAsIGZTdWJHcm91cENvdW50KTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIEFycmF5IHRvIHN0b3JlIGNvbXBsZXggdHlwZSBkZWNscyBmb3IgY29uc3RyYWludCBjaGVja2luZwotICAgICAgICBmQ1RDb3VudCA9IGdyYW1tYXIuZkNUQ291bnQ7Ci0gICAgICAgIGlmIChmQ1RDb3VudCA+IDApIHsKLSAgICAgICAgICAgIGZDb21wbGV4VHlwZURlY2xzID0gbmV3IFhTQ29tcGxleFR5cGVEZWNsW2dyYW1tYXIuZkNvbXBsZXhUeXBlRGVjbHMubGVuZ3RoXTsKLSAgICAgICAgICAgIGZDVExvY2F0b3JzID0gbmV3IFNpbXBsZUxvY2F0b3JbZ3JhbW1hci5mQ1RMb2NhdG9ycy5sZW5ndGhdOwotICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShncmFtbWFyLmZDb21wbGV4VHlwZURlY2xzLCAwLCBmQ29tcGxleFR5cGVEZWNscywgMCwgZkNUQ291bnQpOwotICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShncmFtbWFyLmZDVExvY2F0b3JzLCAwLCBmQ1RMb2NhdG9ycywgMCwgZkNUQ291bnQpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gR3JvdXBzIGJlaW5nIHJlZGVmaW5lZCBieSByZXN0cmljdGlvbgotICAgICAgICBmUkdDb3VudCA9IGdyYW1tYXIuZlJHQ291bnQ7Ci0gICAgICAgIGlmIChmUkdDb3VudCA+IDApIHsKLSAgICAgICAgICAgIGZSZWRlZmluZWRHcm91cERlY2xzID0gbmV3IFhTR3JvdXBEZWNsW2dyYW1tYXIuZlJlZGVmaW5lZEdyb3VwRGVjbHMubGVuZ3RoXTsKLSAgICAgICAgICAgIGZSR0xvY2F0b3JzID0gbmV3IFNpbXBsZUxvY2F0b3JbZ3JhbW1hci5mUkdMb2NhdG9ycy5sZW5ndGhdOwotICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShncmFtbWFyLmZSZWRlZmluZWRHcm91cERlY2xzLCAwLCBmUmVkZWZpbmVkR3JvdXBEZWNscywgMCwgZlJHQ291bnQpOwotICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShncmFtbWFyLmZSR0xvY2F0b3JzLCAwLCBmUkdMb2NhdG9ycywgMCwgZlJHQ291bnQpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gTGlzdCBvZiBpbXBvcnRlZCBncmFtbWFycwotICAgICAgICBpZiAoZ3JhbW1hci5mSW1wb3J0ZWQgIT0gbnVsbCkgewotICAgICAgICAgICAgZkltcG9ydGVkID0gbmV3IFZlY3RvcigpOwotICAgICAgICAgICAgZm9yIChpbnQgaT0wOyBpPGdyYW1tYXIuZkltcG9ydGVkLnNpemUoKTsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgZkltcG9ydGVkLmFkZChncmFtbWFyLmZJbXBvcnRlZC5lbGVtZW50QXQoaSkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gTG9jYXRpb25zCi0gICAgICAgIGlmIChncmFtbWFyLmZMb2NhdGlvbnMgIT0gbnVsbCkgewotICAgICAgICAgICAgZm9yIChpbnQgaz0wOyBrPGdyYW1tYXIuZkxvY2F0aW9ucy5zaXplKCk7IGsrKykgewotICAgICAgICAgICAgICAgIGFkZERvY3VtZW50KG51bGwsIChTdHJpbmcpZ3JhbW1hci5mTG9jYXRpb25zLmVsZW1lbnRBdChrKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgIH0gLy8gPGluaXQ+KFN0cmluZywgWFNERGVzY3JpcHRpb24pCi0KLSAgICAvLyBudW1iZXIgb2YgYnVpbHQtaW4gWFNUeXBlcyB3ZSBuZWVkIHRvIGNyZWF0ZSBmb3IgYmFzZSBhbmQgZnVsbAotICAgIC8vIGRhdGF0eXBlIHNldAotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBCQVNJQ1NFVF9DT1VOVCA9IDI5OwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBGVUxMU0VUX0NPVU5UICA9IDQ2OwotCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEdSQU1NQVJfWFMgID0gMTsKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgR1JBTU1BUl9YU0kgPSAyOwotCi0gICAgLy8gdGhpcyBjbGFzcyBtYWtlcyBzdXJlIHRoZSBzdGF0aWMsIGJ1aWx0LWluIHNjaGVtYSBncmFtbWFycwotICAgIC8vIGFyZSBpbW11dGFibGUuCi0gICAgcHVibGljIHN0YXRpYyBjbGFzcyBCdWlsdGluU2NoZW1hR3JhbW1hciBleHRlbmRzIFNjaGVtYUdyYW1tYXIgewotCi0gICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBFWFRFTkRFRF9TQ0hFTUFfRkFDVE9SWV9DTEFTUyA9ICJjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYueHMuRXh0ZW5kZWRTY2hlbWFEVkZhY3RvcnlJbXBsIjsKLQotICAgICAgICAvKioKLSAgICAgICAgICogU3BlY2lhbCBjb25zdHJ1Y3RvciB0byBjcmVhdGUgdGhlIGdyYW1tYXJzIGZvciB0aGUgc2NoZW1hIG5hbWVzcGFjZXMKLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIGdyYW1tYXIKLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBCdWlsdGluU2NoZW1hR3JhbW1hcihpbnQgZ3JhbW1hciwgc2hvcnQgc2NoZW1hVmVyc2lvbikgewotICAgICAgICAgICAgU2NoZW1hRFZGYWN0b3J5IHNjaGVtYUZhY3Rvcnk7Ci0gICAgICAgICAgICBpZiAoc2NoZW1hVmVyc2lvbiA9PSBDb25zdGFudHMuU0NIRU1BX1ZFUlNJT05fMV8wKSB7Ci0gICAgICAgICAgICAgICAgc2NoZW1hRmFjdG9yeSA9IFNjaGVtYURWRmFjdG9yeS5nZXRJbnN0YW5jZSgpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgc2NoZW1hRmFjdG9yeSA9IFNjaGVtYURWRmFjdG9yeS5nZXRJbnN0YW5jZShFWFRFTkRFRF9TQ0hFTUFfRkFDVE9SWV9DTEFTUyk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmIChncmFtbWFyID09IEdSQU1NQVJfWFMpIHsKLSAgICAgICAgICAgICAgICAvLyB0YXJnZXQgbmFtZXNwYWNlCi0gICAgICAgICAgICAgICAgZlRhcmdldE5hbWVzcGFjZSA9IFNjaGVtYVN5bWJvbHMuVVJJX1NDSEVNQUZPUlNDSEVNQTsKLQotICAgICAgICAgICAgICAgIC8vIGdyYW1tYXIgZGVzY3JpcHRpb24KLSAgICAgICAgICAgICAgICBmR3JhbW1hckRlc2NyaXB0aW9uID0gbmV3IFhTRERlc2NyaXB0aW9uKCk7Ci0gICAgICAgICAgICAgICAgZkdyYW1tYXJEZXNjcmlwdGlvbi5mQ29udGV4dFR5cGUgPSBYU0REZXNjcmlwdGlvbi5DT05URVhUX1BSRVBBUlNFOwotICAgICAgICAgICAgICAgIGZHcmFtbWFyRGVzY3JpcHRpb24uc2V0TmFtZXNwYWNlKFNjaGVtYVN5bWJvbHMuVVJJX1NDSEVNQUZPUlNDSEVNQSk7Ci0KLSAgICAgICAgICAgICAgICAvLyBubyBnbG9iYWwgZGVjbHMgb3RoZXIgdGhhbiB0eXBlcwotICAgICAgICAgICAgICAgIGZHbG9iYWxBdHRyRGVjbHMgID0gbmV3IFN5bWJvbEhhc2goMSk7Ci0gICAgICAgICAgICAgICAgZkdsb2JhbEF0dHJHcnBEZWNscyA9IG5ldyBTeW1ib2xIYXNoKDEpOwotICAgICAgICAgICAgICAgIGZHbG9iYWxFbGVtRGVjbHMgPSBuZXcgU3ltYm9sSGFzaCgxKTsKLSAgICAgICAgICAgICAgICBmR2xvYmFsR3JvdXBEZWNscyA9IG5ldyBTeW1ib2xIYXNoKDEpOwotICAgICAgICAgICAgICAgIGZHbG9iYWxOb3RhdGlvbkRlY2xzID0gbmV3IFN5bWJvbEhhc2goMSk7Ci0gICAgICAgICAgICAgICAgZkdsb2JhbElEQ29uc3RyYWludERlY2xzID0gbmV3IFN5bWJvbEhhc2goMSk7Ci0KLSAgICAgICAgICAgICAgICAvLyBubyBleHRlbmRlZCBnbG9iYWwgZGVjbHMKLSAgICAgICAgICAgICAgICBmR2xvYmFsQXR0ckRlY2xzRXh0ICA9IG5ldyBTeW1ib2xIYXNoKDEpOwotICAgICAgICAgICAgICAgIGZHbG9iYWxBdHRyR3JwRGVjbHNFeHQgPSBuZXcgU3ltYm9sSGFzaCgxKTsKLSAgICAgICAgICAgICAgICBmR2xvYmFsRWxlbURlY2xzRXh0ID0gbmV3IFN5bWJvbEhhc2goMSk7Ci0gICAgICAgICAgICAgICAgZkdsb2JhbEdyb3VwRGVjbHNFeHQgPSBuZXcgU3ltYm9sSGFzaCgxKTsKLSAgICAgICAgICAgICAgICBmR2xvYmFsTm90YXRpb25EZWNsc0V4dCA9IG5ldyBTeW1ib2xIYXNoKDEpOwotICAgICAgICAgICAgICAgIGZHbG9iYWxJRENvbnN0cmFpbnREZWNsc0V4dCA9IG5ldyBTeW1ib2xIYXNoKDEpOwotICAgICAgICAgICAgICAgIGZHbG9iYWxUeXBlRGVjbHNFeHQgPSBuZXcgU3ltYm9sSGFzaCgxKTsKLQotICAgICAgICAgICAgICAgIC8vIGFsbCBnbG9iYWwgZWxlbWVudCBkZWNscyB0YWJsZQotICAgICAgICAgICAgICAgIGZBbGxHbG9iYWxFbGVtRGVjbHMgPSBuZXcgU3ltYm9sSGFzaCgxKTsKLQotICAgICAgICAgICAgICAgIC8vIGdldCBhbGwgYnVpbHQtaW4gdHlwZXMKLSAgICAgICAgICAgICAgICBmR2xvYmFsVHlwZURlY2xzID0gc2NoZW1hRmFjdG9yeS5nZXRCdWlsdEluVHlwZXMoKTsKLQotICAgICAgICAgICAgICAgIC8vIGFzc2lnbiB0aGUgYnVpbHQtaW4gc2NoZW1hIGdyYW1tYXIgYXMgdGhlIFhTTmFtZXNwYWNlSXRlbQotICAgICAgICAgICAgICAgIC8vIGZvciBlYWNoIG9mIHRoZSBidWlsdC1pbiBzaW1wbGUgdHlwZSBkZWZpbml0aW9ucy4KLSAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gZkdsb2JhbFR5cGVEZWNscy5nZXRMZW5ndGgoKTsKLSAgICAgICAgICAgICAgICBYU1R5cGVEZWZpbml0aW9uIFtdIHR5cGVEZWZpbml0aW9ucyA9IG5ldyBYU1R5cGVEZWZpbml0aW9uW2xlbmd0aF07Ci0gICAgICAgICAgICAgICAgZkdsb2JhbFR5cGVEZWNscy5nZXRWYWx1ZXModHlwZURlZmluaXRpb25zLCAwKTsKLSAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7Ci0gICAgICAgICAgICAgICAgICAgIFhTVHlwZURlZmluaXRpb24geHRkID0gdHlwZURlZmluaXRpb25zW2ldOwotICAgICAgICAgICAgICAgICAgICBpZiAoeHRkIGluc3RhbmNlb2YgWFNTaW1wbGVUeXBlRGVjbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgKChYU1NpbXBsZVR5cGVEZWNsKSB4dGQpLnNldE5hbWVzcGFjZUl0ZW0odGhpcyk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyBhZGQgYW55VHlwZQotICAgICAgICAgICAgICAgIGZHbG9iYWxUeXBlRGVjbHMucHV0KGZBbnlUeXBlLmdldE5hbWUoKSwgZkFueVR5cGUpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoZ3JhbW1hciA9PSBHUkFNTUFSX1hTSSkgewotICAgICAgICAgICAgICAgIC8vIHRhcmdldCBuYW1lc3BhY2UKLSAgICAgICAgICAgICAgICBmVGFyZ2V0TmFtZXNwYWNlID0gU2NoZW1hU3ltYm9scy5VUklfWFNJOwotICAgICAgICAgICAgICAgIC8vIGdyYW1tYXIgZGVzY3JpcHRpb24KLSAgICAgICAgICAgICAgICBmR3JhbW1hckRlc2NyaXB0aW9uID0gbmV3IFhTRERlc2NyaXB0aW9uKCk7Ci0gICAgICAgICAgICAgICAgZkdyYW1tYXJEZXNjcmlwdGlvbi5mQ29udGV4dFR5cGUgPSBYU0REZXNjcmlwdGlvbi5DT05URVhUX1BSRVBBUlNFOwotICAgICAgICAgICAgICAgIGZHcmFtbWFyRGVzY3JpcHRpb24uc2V0TmFtZXNwYWNlKFNjaGVtYVN5bWJvbHMuVVJJX1hTSSk7Ci0KLSAgICAgICAgICAgICAgICAvLyBubyBnbG9iYWwgZGVjbHMgb3RoZXIgdGhhbiBhdHRyaWJ1dGVzCi0gICAgICAgICAgICAgICAgZkdsb2JhbEF0dHJHcnBEZWNscyA9IG5ldyBTeW1ib2xIYXNoKDEpOwotICAgICAgICAgICAgICAgIGZHbG9iYWxFbGVtRGVjbHMgPSBuZXcgU3ltYm9sSGFzaCgxKTsKLSAgICAgICAgICAgICAgICBmR2xvYmFsR3JvdXBEZWNscyA9IG5ldyBTeW1ib2xIYXNoKDEpOwotICAgICAgICAgICAgICAgIGZHbG9iYWxOb3RhdGlvbkRlY2xzID0gbmV3IFN5bWJvbEhhc2goMSk7Ci0gICAgICAgICAgICAgICAgZkdsb2JhbElEQ29uc3RyYWludERlY2xzID0gbmV3IFN5bWJvbEhhc2goMSk7Ci0gICAgICAgICAgICAgICAgZkdsb2JhbFR5cGVEZWNscyA9IG5ldyBTeW1ib2xIYXNoKDEpOwotCi0gICAgICAgICAgICAgICAgLy8gbm8gZXh0ZW5kZWQgZ2xvYmFsIGRlY2xzCi0gICAgICAgICAgICAgICAgZkdsb2JhbEF0dHJEZWNsc0V4dCAgPSBuZXcgU3ltYm9sSGFzaCgxKTsKLSAgICAgICAgICAgICAgICBmR2xvYmFsQXR0ckdycERlY2xzRXh0ID0gbmV3IFN5bWJvbEhhc2goMSk7Ci0gICAgICAgICAgICAgICAgZkdsb2JhbEVsZW1EZWNsc0V4dCA9IG5ldyBTeW1ib2xIYXNoKDEpOwotICAgICAgICAgICAgICAgIGZHbG9iYWxHcm91cERlY2xzRXh0ID0gbmV3IFN5bWJvbEhhc2goMSk7Ci0gICAgICAgICAgICAgICAgZkdsb2JhbE5vdGF0aW9uRGVjbHNFeHQgPSBuZXcgU3ltYm9sSGFzaCgxKTsKLSAgICAgICAgICAgICAgICBmR2xvYmFsSURDb25zdHJhaW50RGVjbHNFeHQgPSBuZXcgU3ltYm9sSGFzaCgxKTsKLSAgICAgICAgICAgICAgICBmR2xvYmFsVHlwZURlY2xzRXh0ID0gbmV3IFN5bWJvbEhhc2goMSk7Ci0KLSAgICAgICAgICAgICAgICAvLyBubyBhbGwgZ2xvYmFsIGVsZW1lbnQgZGVjbHMKLSAgICAgICAgICAgICAgICBmQWxsR2xvYmFsRWxlbURlY2xzID0gbmV3IFN5bWJvbEhhc2goMSk7Ci0KLSAgICAgICAgICAgICAgICAvLyA0IGF0dHJpYnV0ZXMsIHNvIGluaXRpYWxpemUgdGhlIHNpemUgYXMgNCoyID0gOAotICAgICAgICAgICAgICAgIGZHbG9iYWxBdHRyRGVjbHMgID0gbmV3IFN5bWJvbEhhc2goOCk7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIG5hbWUgPSBudWxsOwotICAgICAgICAgICAgICAgIFN0cmluZyB0bnMgPSBudWxsOwotICAgICAgICAgICAgICAgIFhTU2ltcGxlVHlwZSB0eXBlID0gbnVsbDsKLSAgICAgICAgICAgICAgICBzaG9ydCBzY29wZSA9IFhTQ29uc3RhbnRzLlNDT1BFX0dMT0JBTDsKLQotICAgICAgICAgICAgICAgIC8vIHhzaTp0eXBlCi0gICAgICAgICAgICAgICAgbmFtZSA9IFNjaGVtYVN5bWJvbHMuWFNJX1RZUEU7Ci0gICAgICAgICAgICAgICAgdG5zID0gU2NoZW1hU3ltYm9scy5VUklfWFNJOwotICAgICAgICAgICAgICAgIHR5cGUgPSBzY2hlbWFGYWN0b3J5LmdldEJ1aWx0SW5UeXBlKFNjaGVtYVN5bWJvbHMuQVRUVkFMX1FOQU1FKTsKLSAgICAgICAgICAgICAgICBmR2xvYmFsQXR0ckRlY2xzLnB1dChuYW1lLCBuZXcgQnVpbHRpbkF0dHJEZWNsKG5hbWUsIHRucywgdHlwZSwgc2NvcGUpKTsKLQotICAgICAgICAgICAgICAgIC8vIHhzaTpuaWwKLSAgICAgICAgICAgICAgICBuYW1lID0gU2NoZW1hU3ltYm9scy5YU0lfTklMOwotICAgICAgICAgICAgICAgIHRucyA9IFNjaGVtYVN5bWJvbHMuVVJJX1hTSTsKLSAgICAgICAgICAgICAgICB0eXBlID0gc2NoZW1hRmFjdG9yeS5nZXRCdWlsdEluVHlwZShTY2hlbWFTeW1ib2xzLkFUVFZBTF9CT09MRUFOKTsKLSAgICAgICAgICAgICAgICBmR2xvYmFsQXR0ckRlY2xzLnB1dChuYW1lLCBuZXcgQnVpbHRpbkF0dHJEZWNsKG5hbWUsIHRucywgdHlwZSwgc2NvcGUpKTsKLQotICAgICAgICAgICAgICAgIFhTU2ltcGxlVHlwZSBhbnlVUkkgPSBzY2hlbWFGYWN0b3J5LmdldEJ1aWx0SW5UeXBlKFNjaGVtYVN5bWJvbHMuQVRUVkFMX0FOWVVSSSk7Ci0KLSAgICAgICAgICAgICAgICAvLyB4c2k6c2NoZW1hTG9jYXRpb24KLSAgICAgICAgICAgICAgICBuYW1lID0gU2NoZW1hU3ltYm9scy5YU0lfU0NIRU1BTE9DQVRJT047Ci0gICAgICAgICAgICAgICAgdG5zID0gU2NoZW1hU3ltYm9scy5VUklfWFNJOwotICAgICAgICAgICAgICAgIHR5cGUgPSBzY2hlbWFGYWN0b3J5LmNyZWF0ZVR5cGVMaXN0KCIjQW5vblR5cGVfc2NoZW1hTG9jYXRpb24iLCBTY2hlbWFTeW1ib2xzLlVSSV9YU0ksIChzaG9ydCkwLCBhbnlVUkksIG51bGwpOwotICAgICAgICAgICAgICAgIGlmICh0eXBlIGluc3RhbmNlb2YgWFNTaW1wbGVUeXBlRGVjbCkgewotICAgICAgICAgICAgICAgICAgICAoKFhTU2ltcGxlVHlwZURlY2wpdHlwZSkuc2V0QW5vbnltb3VzKHRydWUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBmR2xvYmFsQXR0ckRlY2xzLnB1dChuYW1lLCBuZXcgQnVpbHRpbkF0dHJEZWNsKG5hbWUsIHRucywgdHlwZSwgc2NvcGUpKTsKLQotICAgICAgICAgICAgICAgIC8vIHhzaTpub05hbWVzcGFjZVNjaGVtYUxvY2F0aW9uCi0gICAgICAgICAgICAgICAgbmFtZSA9IFNjaGVtYVN5bWJvbHMuWFNJX05PTkFNRVNQQUNFU0NIRU1BTE9DQVRJT047Ci0gICAgICAgICAgICAgICAgdG5zID0gU2NoZW1hU3ltYm9scy5VUklfWFNJOwotICAgICAgICAgICAgICAgIHR5cGUgPSBhbnlVUkk7Ci0gICAgICAgICAgICAgICAgZkdsb2JhbEF0dHJEZWNscy5wdXQobmFtZSwgbmV3IEJ1aWx0aW5BdHRyRGVjbChuYW1lLCB0bnMsIHR5cGUsIHNjb3BlKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gLy8gPGluaXQ+KGludCkKLQotICAgICAgICAvLyByZXR1cm4gdGhlIFhNTEdyYW1tYXJEZXNjcmlwdGlvbiBjb3JyZXNwb25kaW5nIHRvIHRoaXMKLSAgICAgICAgLy8gb2JqZWN0Ci0gICAgICAgIHB1YmxpYyBYTUxHcmFtbWFyRGVzY3JpcHRpb24gZ2V0R3JhbW1hckRlc2NyaXB0aW9uKCkgewotICAgICAgICAgICAgcmV0dXJuIGZHcmFtbWFyRGVzY3JpcHRpb24ubWFrZUNsb25lKCk7Ci0gICAgICAgIH0gLy8gZ2V0R3JhbW1hckRlc2NyaXB0aW9uKCk6ICBYTUxHcmFtbWFyRGVzY3JpcHRpb24KLQotICAgICAgICAvLyBvdmVycmlkZSB0aGVzZSBtZXRob2RzIHNvbGVseSBzbyB0aGF0IHRoZXNlCi0gICAgICAgIC8vIG9iamVjdHMgY2Fubm90IGJlIG1vZGlmaWVkIG9uY2UgdGhleSdyZSBjcmVhdGVkLgotICAgICAgICBwdWJsaWMgdm9pZCBzZXRJbXBvcnRlZEdyYW1tYXJzKFZlY3RvciBpbXBvcnRlZEdyYW1tYXJzKSB7Ci0gICAgICAgICAgICAvLyBpZ25vcmUKLSAgICAgICAgfQotICAgICAgICBwdWJsaWMgdm9pZCBhZGRHbG9iYWxBdHRyaWJ1dGVEZWNsKFhTQXR0cmlidXRlRGVjbCBkZWNsKSB7Ci0gICAgICAgICAgICAvLyBpZ25vcmUKLSAgICAgICAgfQotICAgICAgICBwdWJsaWMgdm9pZCBhZGRHbG9iYWxBdHRyaWJ1dGVEZWNsKFhTQXR0cmlidXRlRGVjbCBkZWNsLCBTdHJpbmcgbG9jYXRpb24pIHsKLSAgICAgICAgICAgIC8vIGlnbm9yZQotICAgICAgICB9Ci0gICAgICAgIHB1YmxpYyB2b2lkIGFkZEdsb2JhbEF0dHJpYnV0ZUdyb3VwRGVjbChYU0F0dHJpYnV0ZUdyb3VwRGVjbCBkZWNsKSB7Ci0gICAgICAgICAgICAvLyBpZ25vcmUKLSAgICAgICAgfQotICAgICAgICBwdWJsaWMgdm9pZCBhZGRHbG9iYWxBdHRyaWJ1dGVHcm91cERlY2woWFNBdHRyaWJ1dGVHcm91cERlY2wgZGVjbCwgU3RyaW5nIGxvY2F0aW9uKSB7Ci0gICAgICAgICAgICAvLyBpZ25vcmUKLSAgICAgICAgfQotICAgICAgICBwdWJsaWMgdm9pZCBhZGRHbG9iYWxFbGVtZW50RGVjbChYU0VsZW1lbnREZWNsIGRlY2wpIHsKLSAgICAgICAgICAgIC8vIGlnbm9yZQotICAgICAgICB9Ci0gICAgICAgIHB1YmxpYyB2b2lkIGFkZEdsb2JhbEVsZW1lbnREZWNsKFhTRWxlbWVudERlY2wgZGVjbCwgU3RyaW5nIGxvY2F0aW9uKSB7Ci0gICAgICAgICAgICAvLyBpZ25vcmUKLSAgICAgICAgfQotICAgICAgICBwdWJsaWMgdm9pZCBhZGRHbG9iYWxFbGVtZW50RGVjbEFsbChYU0VsZW1lbnREZWNsIGRlY2wpIHsKLSAgICAgICAgICAgIC8vIGlnbm9yZQotICAgICAgICB9Ci0gICAgICAgIHB1YmxpYyB2b2lkIGFkZEdsb2JhbEdyb3VwRGVjbChYU0dyb3VwRGVjbCBkZWNsKSB7Ci0gICAgICAgICAgICAvLyBpZ25vcmUKLSAgICAgICAgfQotICAgICAgICBwdWJsaWMgdm9pZCBhZGRHbG9iYWxHcm91cERlY2woWFNHcm91cERlY2wgZGVjbCwgU3RyaW5nIGxvY2F0aW9uKSB7Ci0gICAgICAgICAgICAvLyBpZ25vcmUKLSAgICAgICAgfQotICAgICAgICBwdWJsaWMgdm9pZCBhZGRHbG9iYWxOb3RhdGlvbkRlY2woWFNOb3RhdGlvbkRlY2wgZGVjbCkgewotICAgICAgICAgICAgLy8gaWdub3JlCi0gICAgICAgIH0KLSAgICAgICAgcHVibGljIHZvaWQgYWRkR2xvYmFsTm90YXRpb25EZWNsKFhTTm90YXRpb25EZWNsIGRlY2wsIFN0cmluZyBsb2NhdGlvbikgewotICAgICAgICAgICAgLy8gaWdub3JlCi0gICAgICAgIH0KLSAgICAgICAgcHVibGljIHZvaWQgYWRkR2xvYmFsVHlwZURlY2woWFNUeXBlRGVmaW5pdGlvbiBkZWNsKSB7Ci0gICAgICAgICAgICAvLyBpZ25vcmUKLSAgICAgICAgfQotICAgICAgICBwdWJsaWMgdm9pZCBhZGRHbG9iYWxUeXBlRGVjbChYU1R5cGVEZWZpbml0aW9uIGRlY2wsIFN0cmluZyBsb2NhdGlvbikgewotICAgICAgICAgICAgLy8gaWdub3JlCi0gICAgICAgIH0KLSAgICAgICAgcHVibGljIHZvaWQgYWRkR2xvYmFsQ29tcGxleFR5cGVEZWNsKFhTQ29tcGxleFR5cGVEZWNsIGRlY2wpIHsKLSAgICAgICAgICAgIC8vIGlnbm9yZQotICAgICAgICB9Ci0gICAgICAgIHB1YmxpYyB2b2lkIGFkZEdsb2JhbENvbXBsZXhUeXBlRGVjbChYU0NvbXBsZXhUeXBlRGVjbCBkZWNsLCBTdHJpbmcgbG9jYXRpb24pIHsKLSAgICAgICAgICAgIC8vIGlnbm9yZQotICAgICAgICB9Ci0gICAgICAgIHB1YmxpYyB2b2lkIGFkZEdsb2JhbFNpbXBsZVR5cGVEZWNsKFhTU2ltcGxlVHlwZSBkZWNsKSB7Ci0gICAgICAgICAgICAvLyBpZ25vcmUKLSAgICAgICAgfQotICAgICAgICBwdWJsaWMgdm9pZCBhZGRHbG9iYWxTaW1wbGVUeXBlRGVjbChYU1NpbXBsZVR5cGUgZGVjbCwgU3RyaW5nIGxvY2F0aW9uKSB7Ci0gICAgICAgICAgICAvLyBpZ25vcmUKLSAgICAgICAgfQotICAgICAgICBwdWJsaWMgdm9pZCBhZGRDb21wbGV4VHlwZURlY2woWFNDb21wbGV4VHlwZURlY2wgZGVjbCwgU2ltcGxlTG9jYXRvciBsb2NhdG9yKSB7Ci0gICAgICAgICAgICAvLyBpZ25vcmUKLSAgICAgICAgfQotICAgICAgICBwdWJsaWMgdm9pZCBhZGRSZWRlZmluZWRHcm91cERlY2woWFNHcm91cERlY2wgZGVyaXZlZCwgWFNHcm91cERlY2wgYmFzZSwgU2ltcGxlTG9jYXRvciBsb2NhdG9yKSB7Ci0gICAgICAgICAgICAvLyBpZ25vcmUKLSAgICAgICAgfQotICAgICAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgYWRkRG9jdW1lbnQoT2JqZWN0IGRvY3VtZW50LCBTdHJpbmcgbG9jYXRpb24pIHsKLSAgICAgICAgICAgIC8vIGlnbm9yZQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gYW5ub3RhdGlvbiBzdXBwb3J0Ci0gICAgICAgIHN5bmNocm9uaXplZCBET01QYXJzZXIgZ2V0RE9NUGFyc2VyKCkgewotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLSAgICAgICAgc3luY2hyb25pemVkIFNBWFBhcnNlciBnZXRTQVhQYXJzZXIoKSB7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPkEgcGFydGlhbCBzY2hlbWEgZm9yIHNjaGVtYXMgZm9yIHZhbGlkYXRpbmcgYW5ub3RhdGlvbnMuPC9wPgotICAgICAqCi0gICAgICogQHhlcmNlcy5pbnRlcm5hbAotICAgICAqCi0gICAgICogQGF1dGhvciBNaWNoYWVsIEdsYXZhc3NldmljaCwgSUJNCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBTY2hlbWE0QW5ub3RhdGlvbnMgZXh0ZW5kcyBTY2hlbWFHcmFtbWFyIHsKLQotICAgICAgICAvKioKLSAgICAgICAgICogU2luZ2xldG9uIGluc3RhbmNlLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTY2hlbWE0QW5ub3RhdGlvbnMgSU5TVEFOQ0UgPSBuZXcgU2NoZW1hNEFubm90YXRpb25zKCk7Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFNwZWNpYWwgY29uc3RydWN0b3IgdG8gY3JlYXRlIGEgc2NoZW1hCi0gICAgICAgICAqIGNhcGFibGUgb2YgdmFsaWRhdGluZyBhbm5vdGF0aW9ucy4KLSAgICAgICAgICovCi0gICAgICAgIHByaXZhdGUgU2NoZW1hNEFubm90YXRpb25zKCkgewotCi0gICAgICAgICAgICAvLyB0YXJnZXQgbmFtZXNwYWNlCi0gICAgICAgICAgICBmVGFyZ2V0TmFtZXNwYWNlID0gU2NoZW1hU3ltYm9scy5VUklfU0NIRU1BRk9SU0NIRU1BOwotCi0gICAgICAgICAgICAvLyBncmFtbWFyIGRlc2NyaXB0aW9uCi0gICAgICAgICAgICBmR3JhbW1hckRlc2NyaXB0aW9uID0gbmV3IFhTRERlc2NyaXB0aW9uKCk7Ci0gICAgICAgICAgICBmR3JhbW1hckRlc2NyaXB0aW9uLmZDb250ZXh0VHlwZSA9IFhTRERlc2NyaXB0aW9uLkNPTlRFWFRfUFJFUEFSU0U7Ci0gICAgICAgICAgICBmR3JhbW1hckRlc2NyaXB0aW9uLnNldE5hbWVzcGFjZShTY2hlbWFTeW1ib2xzLlVSSV9TQ0hFTUFGT1JTQ0hFTUEpOwotCi0gICAgICAgICAgICAvLyBubyBnbG9iYWwgZGVjbHMgb3RoZXIgdGhhbiB0eXBlcyBhbmQKLSAgICAgICAgICAgIC8vIGVsZW1lbnQgZGVjbGFyYXRpb25zIGZvciA8YW5ub3RhdGlvbj4sIDxkb2N1bWVudGF0aW9uPiBhbmQgPGFwcGluZm8+LgotICAgICAgICAgICAgZkdsb2JhbEF0dHJEZWNscyAgPSBuZXcgU3ltYm9sSGFzaCgxKTsKLSAgICAgICAgICAgIGZHbG9iYWxBdHRyR3JwRGVjbHMgPSBuZXcgU3ltYm9sSGFzaCgxKTsKLSAgICAgICAgICAgIGZHbG9iYWxFbGVtRGVjbHMgPSBuZXcgU3ltYm9sSGFzaCg2KTsKLSAgICAgICAgICAgIGZHbG9iYWxHcm91cERlY2xzID0gbmV3IFN5bWJvbEhhc2goMSk7Ci0gICAgICAgICAgICBmR2xvYmFsTm90YXRpb25EZWNscyA9IG5ldyBTeW1ib2xIYXNoKDEpOwotICAgICAgICAgICAgZkdsb2JhbElEQ29uc3RyYWludERlY2xzID0gbmV3IFN5bWJvbEhhc2goMSk7Ci0KLSAgICAgICAgICAgIC8vIG5vIGV4dGVuZGVkIGdsb2JhbCBkZWNscwotICAgICAgICAgICAgZkdsb2JhbEF0dHJEZWNsc0V4dCAgPSBuZXcgU3ltYm9sSGFzaCgxKTsKLSAgICAgICAgICAgIGZHbG9iYWxBdHRyR3JwRGVjbHNFeHQgPSBuZXcgU3ltYm9sSGFzaCgxKTsKLSAgICAgICAgICAgIGZHbG9iYWxFbGVtRGVjbHNFeHQgPSBuZXcgU3ltYm9sSGFzaCg2KTsKLSAgICAgICAgICAgIGZHbG9iYWxHcm91cERlY2xzRXh0ID0gbmV3IFN5bWJvbEhhc2goMSk7Ci0gICAgICAgICAgICBmR2xvYmFsTm90YXRpb25EZWNsc0V4dCA9IG5ldyBTeW1ib2xIYXNoKDEpOwotICAgICAgICAgICAgZkdsb2JhbElEQ29uc3RyYWludERlY2xzRXh0ID0gbmV3IFN5bWJvbEhhc2goMSk7Ci0gICAgICAgICAgICBmR2xvYmFsVHlwZURlY2xzRXh0ID0gbmV3IFN5bWJvbEhhc2goMSk7Ci0KLSAgICAgICAgICAgIC8vIGFsbCBnbG9iYWwgZWxlbWVudCBkZWNsYXJhdGlvbnMKLSAgICAgICAgICAgIGZBbGxHbG9iYWxFbGVtRGVjbHMgPSBuZXcgU3ltYm9sSGFzaCg2KTsKLQotICAgICAgICAgICAgLy8gZ2V0IGFsbCBidWlsdC1pbiB0eXBlcwotICAgICAgICAgICAgZkdsb2JhbFR5cGVEZWNscyA9IFNHX1NjaGVtYU5TLmZHbG9iYWxUeXBlRGVjbHM7Ci0KLSAgICAgICAgICAgIC8vIGNyZWF0ZSBlbGVtZW50IGRlY2xhcmF0aW9ucyBmb3IgPGFubm90YXRpb24+LCA8ZG9jdW1lbnRhdGlvbj4gYW5kIDxhcHBpbmZvPgotICAgICAgICAgICAgWFNFbGVtZW50RGVjbCBhbm5vdGF0aW9uRGVjbCA9IGNyZWF0ZUFubm90YXRpb25FbGVtZW50RGVjbChTY2hlbWFTeW1ib2xzLkVMVF9BTk5PVEFUSU9OKTsKLSAgICAgICAgICAgIFhTRWxlbWVudERlY2wgZG9jdW1lbnRhdGlvbkRlY2wgPSBjcmVhdGVBbm5vdGF0aW9uRWxlbWVudERlY2woU2NoZW1hU3ltYm9scy5FTFRfRE9DVU1FTlRBVElPTik7Ci0gICAgICAgICAgICBYU0VsZW1lbnREZWNsIGFwcGluZm9EZWNsID0gY3JlYXRlQW5ub3RhdGlvbkVsZW1lbnREZWNsKFNjaGVtYVN5bWJvbHMuRUxUX0FQUElORk8pOwotCi0gICAgICAgICAgICAvLyBhZGQgZ2xvYmFsIGVsZW1lbnQgZGVjbGFyYXRpb25zCi0gICAgICAgICAgICBmR2xvYmFsRWxlbURlY2xzLnB1dChhbm5vdGF0aW9uRGVjbC5mTmFtZSwgYW5ub3RhdGlvbkRlY2wpOwotICAgICAgICAgICAgZkdsb2JhbEVsZW1EZWNscy5wdXQoZG9jdW1lbnRhdGlvbkRlY2wuZk5hbWUsIGRvY3VtZW50YXRpb25EZWNsKTsKLSAgICAgICAgICAgIGZHbG9iYWxFbGVtRGVjbHMucHV0KGFwcGluZm9EZWNsLmZOYW1lLCBhcHBpbmZvRGVjbCk7Ci0KLSAgICAgICAgICAgIGZHbG9iYWxFbGVtRGVjbHNFeHQucHV0KCIsIithbm5vdGF0aW9uRGVjbC5mTmFtZSwgYW5ub3RhdGlvbkRlY2wpOwotICAgICAgICAgICAgZkdsb2JhbEVsZW1EZWNsc0V4dC5wdXQoIiwiK2RvY3VtZW50YXRpb25EZWNsLmZOYW1lLCBkb2N1bWVudGF0aW9uRGVjbCk7Ci0gICAgICAgICAgICBmR2xvYmFsRWxlbURlY2xzRXh0LnB1dCgiLCIrYXBwaW5mb0RlY2wuZk5hbWUsIGFwcGluZm9EZWNsKTsKLQotICAgICAgICAgICAgZkFsbEdsb2JhbEVsZW1EZWNscy5wdXQoYW5ub3RhdGlvbkRlY2wsIGFubm90YXRpb25EZWNsKTsKLSAgICAgICAgICAgIGZBbGxHbG9iYWxFbGVtRGVjbHMucHV0KGRvY3VtZW50YXRpb25EZWNsLCBkb2N1bWVudGF0aW9uRGVjbCk7Ci0gICAgICAgICAgICBmQWxsR2xvYmFsRWxlbURlY2xzLnB1dChhcHBpbmZvRGVjbCwgYXBwaW5mb0RlY2wpOwotCi0gICAgICAgICAgICAvLyBjcmVhdGUgY29tcGxleCB0eXBlIGRlY2xhcmF0aW9ucyBmb3IgPGFubm90YXRpb24+LCA8ZG9jdW1lbnRhdGlvbj4gYW5kIDxhcHBpbmZvPgotICAgICAgICAgICAgWFNDb21wbGV4VHlwZURlY2wgYW5ub3RhdGlvblR5cGUgPSBuZXcgWFNDb21wbGV4VHlwZURlY2woKTsKLSAgICAgICAgICAgIFhTQ29tcGxleFR5cGVEZWNsIGRvY3VtZW50YXRpb25UeXBlID0gbmV3IFhTQ29tcGxleFR5cGVEZWNsKCk7Ci0gICAgICAgICAgICBYU0NvbXBsZXhUeXBlRGVjbCBhcHBpbmZvVHlwZSA9IG5ldyBYU0NvbXBsZXhUeXBlRGVjbCgpOwotCi0gICAgICAgICAgICAvLyBzZXQgdGhlIHR5cGVzIG9uIHRoZWlyIGVsZW1lbnQgZGVjbGFyYXRpb25zCi0gICAgICAgICAgICBhbm5vdGF0aW9uRGVjbC5mVHlwZSA9IGFubm90YXRpb25UeXBlOwotICAgICAgICAgICAgZG9jdW1lbnRhdGlvbkRlY2wuZlR5cGUgPSBkb2N1bWVudGF0aW9uVHlwZTsKLSAgICAgICAgICAgIGFwcGluZm9EZWNsLmZUeXBlID0gYXBwaW5mb1R5cGU7Ci0KLSAgICAgICAgICAgIC8vIGNyZWF0ZSBhdHRyaWJ1dGUgZ3JvdXBzIGZvciA8YW5ub3RhdGlvbj4sIDxkb2N1bWVudGF0aW9uPiBhbmQgPGFwcGluZm8+Ci0gICAgICAgICAgICBYU0F0dHJpYnV0ZUdyb3VwRGVjbCBhbm5vdGF0aW9uQXR0cnMgPSBuZXcgWFNBdHRyaWJ1dGVHcm91cERlY2woKTsKLSAgICAgICAgICAgIFhTQXR0cmlidXRlR3JvdXBEZWNsIGRvY3VtZW50YXRpb25BdHRycyA9IG5ldyBYU0F0dHJpYnV0ZUdyb3VwRGVjbCgpOwotICAgICAgICAgICAgWFNBdHRyaWJ1dGVHcm91cERlY2wgYXBwaW5mb0F0dHJzID0gbmV3IFhTQXR0cmlidXRlR3JvdXBEZWNsKCk7Ci0KLSAgICAgICAgICAgIC8vIGZpbGwgaW4gYXR0cmlidXRlIGdyb3VwcwotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIC8vIGNyZWF0ZSBhbmQgZmlsbCBhdHRyaWJ1dGUgdXNlcyBmb3IgPGFubm90YXRpb24+LCA8ZG9jdW1lbnRhdGlvbj4gYW5kIDxhcHBpbmZvPgotICAgICAgICAgICAgICAgIFhTQXR0cmlidXRlVXNlSW1wbCBhbm5vdGF0aW9uSURBdHRyID0gbmV3IFhTQXR0cmlidXRlVXNlSW1wbCgpOwotICAgICAgICAgICAgICAgIGFubm90YXRpb25JREF0dHIuZkF0dHJEZWNsID0gbmV3IFhTQXR0cmlidXRlRGVjbCgpOwotICAgICAgICAgICAgICAgIGFubm90YXRpb25JREF0dHIuZkF0dHJEZWNsLnNldFZhbHVlcyhTY2hlbWFTeW1ib2xzLkFUVF9JRCwgbnVsbCwgKFhTU2ltcGxlVHlwZSkgZkdsb2JhbFR5cGVEZWNscy5nZXQoU2NoZW1hU3ltYm9scy5BVFRWQUxfSUQpLAotICAgICAgICAgICAgICAgICAgICAgICAgWFNDb25zdGFudHMuVkNfTk9ORSwgWFNDb25zdGFudHMuU0NPUEVfTE9DQUwsIG51bGwsIGFubm90YXRpb25UeXBlLCBudWxsKTsKLSAgICAgICAgICAgICAgICBhbm5vdGF0aW9uSURBdHRyLmZVc2UgPSBTY2hlbWFTeW1ib2xzLlVTRV9PUFRJT05BTDsKLSAgICAgICAgICAgICAgICBhbm5vdGF0aW9uSURBdHRyLmZDb25zdHJhaW50VHlwZSA9IFhTQ29uc3RhbnRzLlZDX05PTkU7Ci0KLSAgICAgICAgICAgICAgICBYU0F0dHJpYnV0ZVVzZUltcGwgZG9jdW1lbnRhdGlvblNvdXJjZUF0dHIgPSBuZXcgWFNBdHRyaWJ1dGVVc2VJbXBsKCk7Ci0gICAgICAgICAgICAgICAgZG9jdW1lbnRhdGlvblNvdXJjZUF0dHIuZkF0dHJEZWNsID0gbmV3IFhTQXR0cmlidXRlRGVjbCgpOwotICAgICAgICAgICAgICAgIGRvY3VtZW50YXRpb25Tb3VyY2VBdHRyLmZBdHRyRGVjbC5zZXRWYWx1ZXMoU2NoZW1hU3ltYm9scy5BVFRfU09VUkNFLCBudWxsLCAoWFNTaW1wbGVUeXBlKSBmR2xvYmFsVHlwZURlY2xzLmdldChTY2hlbWFTeW1ib2xzLkFUVFZBTF9BTllVUkkpLAotICAgICAgICAgICAgICAgICAgICAgICAgWFNDb25zdGFudHMuVkNfTk9ORSwgWFNDb25zdGFudHMuU0NPUEVfTE9DQUwsIG51bGwsIGRvY3VtZW50YXRpb25UeXBlLCBudWxsKTsKLSAgICAgICAgICAgICAgICBkb2N1bWVudGF0aW9uU291cmNlQXR0ci5mVXNlID0gU2NoZW1hU3ltYm9scy5VU0VfT1BUSU9OQUw7Ci0gICAgICAgICAgICAgICAgZG9jdW1lbnRhdGlvblNvdXJjZUF0dHIuZkNvbnN0cmFpbnRUeXBlID0gWFNDb25zdGFudHMuVkNfTk9ORTsKLQotICAgICAgICAgICAgICAgIFhTQXR0cmlidXRlVXNlSW1wbCBkb2N1bWVudGF0aW9uTGFuZ0F0dHIgPSBuZXcgWFNBdHRyaWJ1dGVVc2VJbXBsKCk7Ci0gICAgICAgICAgICAgICAgZG9jdW1lbnRhdGlvbkxhbmdBdHRyLmZBdHRyRGVjbCA9IG5ldyBYU0F0dHJpYnV0ZURlY2woKTsKLSAgICAgICAgICAgICAgICBkb2N1bWVudGF0aW9uTGFuZ0F0dHIuZkF0dHJEZWNsLnNldFZhbHVlcygibGFuZyIuaW50ZXJuKCksIE5hbWVzcGFjZUNvbnRleHQuWE1MX1VSSSwgKFhTU2ltcGxlVHlwZSkgZkdsb2JhbFR5cGVEZWNscy5nZXQoU2NoZW1hU3ltYm9scy5BVFRWQUxfTEFOR1VBR0UpLAotICAgICAgICAgICAgICAgICAgICAgICAgWFNDb25zdGFudHMuVkNfTk9ORSwgWFNDb25zdGFudHMuU0NPUEVfTE9DQUwsIG51bGwsIGRvY3VtZW50YXRpb25UeXBlLCBudWxsKTsKLSAgICAgICAgICAgICAgICBkb2N1bWVudGF0aW9uTGFuZ0F0dHIuZlVzZSA9IFNjaGVtYVN5bWJvbHMuVVNFX09QVElPTkFMOwotICAgICAgICAgICAgICAgIGRvY3VtZW50YXRpb25MYW5nQXR0ci5mQ29uc3RyYWludFR5cGUgPSBYU0NvbnN0YW50cy5WQ19OT05FOwotCi0gICAgICAgICAgICAgICAgWFNBdHRyaWJ1dGVVc2VJbXBsIGFwcGluZm9Tb3VyY2VBdHRyID0gbmV3IFhTQXR0cmlidXRlVXNlSW1wbCgpOwotICAgICAgICAgICAgICAgIGFwcGluZm9Tb3VyY2VBdHRyLmZBdHRyRGVjbCA9IG5ldyBYU0F0dHJpYnV0ZURlY2woKTsKLSAgICAgICAgICAgICAgICBhcHBpbmZvU291cmNlQXR0ci5mQXR0ckRlY2wuc2V0VmFsdWVzKFNjaGVtYVN5bWJvbHMuQVRUX1NPVVJDRSwgbnVsbCwgKFhTU2ltcGxlVHlwZSkgZkdsb2JhbFR5cGVEZWNscy5nZXQoU2NoZW1hU3ltYm9scy5BVFRWQUxfQU5ZVVJJKSwKLSAgICAgICAgICAgICAgICAgICAgICAgIFhTQ29uc3RhbnRzLlZDX05PTkUsIFhTQ29uc3RhbnRzLlNDT1BFX0xPQ0FMLCBudWxsLCBhcHBpbmZvVHlwZSwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgYXBwaW5mb1NvdXJjZUF0dHIuZlVzZSA9IFNjaGVtYVN5bWJvbHMuVVNFX09QVElPTkFMOwotICAgICAgICAgICAgICAgIGFwcGluZm9Tb3VyY2VBdHRyLmZDb25zdHJhaW50VHlwZSA9IFhTQ29uc3RhbnRzLlZDX05PTkU7Ci0KLSAgICAgICAgICAgICAgICAvLyBjcmVhdGUgbGF4IGF0dHJpYnV0ZSB3aWxkY2FyZCBmb3IgPGFubm90YXRpb24+LCA8ZG9jdW1lbnRhdGlvbj4gYW5kIDxhcHBpbmZvPgotICAgICAgICAgICAgICAgIFhTV2lsZGNhcmREZWNsIG90aGVyQXR0cnMgPSBuZXcgWFNXaWxkY2FyZERlY2woKTsKLSAgICAgICAgICAgICAgICBvdGhlckF0dHJzLmZOYW1lc3BhY2VMaXN0ID0gbmV3IFN0cmluZyBbXSB7ZlRhcmdldE5hbWVzcGFjZSwgbnVsbH07Ci0gICAgICAgICAgICAgICAgb3RoZXJBdHRycy5mVHlwZSA9IFhTV2lsZGNhcmQuTlNDT05TVFJBSU5UX05PVDsKLSAgICAgICAgICAgICAgICBvdGhlckF0dHJzLmZQcm9jZXNzQ29udGVudHMgPSBYU1dpbGRjYXJkLlBDX0xBWDsKLQotICAgICAgICAgICAgICAgIC8vIGFkZCBhdHRyaWJ1dGUgdXNlcyBhbmQgd2lsZGNhcmRzIHRvIGF0dHJpYnV0ZSBncm91cHMgZm9yIDxhbm5vdGF0aW9uPiwgPGRvY3VtZW50YXRpb24+IGFuZCA8YXBwaW5mbz4KLSAgICAgICAgICAgICAgICBhbm5vdGF0aW9uQXR0cnMuYWRkQXR0cmlidXRlVXNlKGFubm90YXRpb25JREF0dHIpOwotICAgICAgICAgICAgICAgIGFubm90YXRpb25BdHRycy5mQXR0cmlidXRlV0MgPSBvdGhlckF0dHJzOwotCi0gICAgICAgICAgICAgICAgZG9jdW1lbnRhdGlvbkF0dHJzLmFkZEF0dHJpYnV0ZVVzZShkb2N1bWVudGF0aW9uU291cmNlQXR0cik7Ci0gICAgICAgICAgICAgICAgZG9jdW1lbnRhdGlvbkF0dHJzLmFkZEF0dHJpYnV0ZVVzZShkb2N1bWVudGF0aW9uTGFuZ0F0dHIpOwotICAgICAgICAgICAgICAgIGRvY3VtZW50YXRpb25BdHRycy5mQXR0cmlidXRlV0MgPSBvdGhlckF0dHJzOwotCi0gICAgICAgICAgICAgICAgYXBwaW5mb0F0dHJzLmFkZEF0dHJpYnV0ZVVzZShhcHBpbmZvU291cmNlQXR0cik7Ci0gICAgICAgICAgICAgICAgYXBwaW5mb0F0dHJzLmZBdHRyaWJ1dGVXQyA9IG90aGVyQXR0cnM7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIGNyZWF0ZSBwYXJ0aWNsZXMgZm9yIDxhbm5vdGF0aW9uPgotICAgICAgICAgICAgWFNQYXJ0aWNsZURlY2wgYW5ub3RhdGlvblBhcnRpY2xlID0gY3JlYXRlVW5ib3VuZGVkTW9kZWxHcm91cFBhcnRpY2xlKCk7Ci0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgWFNNb2RlbEdyb3VwSW1wbCBhbm5vdGF0aW9uQ2hvaWNlID0gbmV3IFhTTW9kZWxHcm91cEltcGwoKTsKLSAgICAgICAgICAgICAgICBhbm5vdGF0aW9uQ2hvaWNlLmZDb21wb3NpdG9yID0gWFNNb2RlbEdyb3VwSW1wbC5NT0RFTEdST1VQX0NIT0lDRTsKLSAgICAgICAgICAgICAgICBhbm5vdGF0aW9uQ2hvaWNlLmZQYXJ0aWNsZUNvdW50ID0gMjsKLSAgICAgICAgICAgICAgICBhbm5vdGF0aW9uQ2hvaWNlLmZQYXJ0aWNsZXMgPSBuZXcgWFNQYXJ0aWNsZURlY2xbMl07Ci0gICAgICAgICAgICAgICAgYW5ub3RhdGlvbkNob2ljZS5mUGFydGljbGVzWzBdID0gY3JlYXRlQ2hvaWNlRWxlbWVudFBhcnRpY2xlKGFwcGluZm9EZWNsKTsKLSAgICAgICAgICAgICAgICBhbm5vdGF0aW9uQ2hvaWNlLmZQYXJ0aWNsZXNbMV0gPSBjcmVhdGVDaG9pY2VFbGVtZW50UGFydGljbGUoZG9jdW1lbnRhdGlvbkRlY2wpOwotICAgICAgICAgICAgICAgIGFubm90YXRpb25QYXJ0aWNsZS5mVmFsdWUgPSBhbm5vdGF0aW9uQ2hvaWNlOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBjcmVhdGUgd2lsZGNhcmQgcGFydGljbGUgZm9yIDxkb2N1bWVudGF0aW9uPiBhbmQgPGFwcGluZm8+Ci0gICAgICAgICAgICBYU1BhcnRpY2xlRGVjbCBhbnlXQ1NlcXVlbmNlUGFydGljbGUgPSBjcmVhdGVVbmJvdW5kZWRBbnlXaWxkY2FyZFNlcXVlbmNlUGFydGljbGUoKTsKLQotICAgICAgICAgICAgLy8gZmlsbCBjb21wbGV4IHR5cGVzCi0gICAgICAgICAgICBhbm5vdGF0aW9uVHlwZS5zZXRWYWx1ZXMoIiNBbm9uVHlwZV8iICsgU2NoZW1hU3ltYm9scy5FTFRfQU5OT1RBVElPTiwgZlRhcmdldE5hbWVzcGFjZSwgU2NoZW1hR3JhbW1hci5mQW55VHlwZSwKLSAgICAgICAgICAgICAgICAgICAgWFNDb25zdGFudHMuREVSSVZBVElPTl9SRVNUUklDVElPTiwgWFNDb25zdGFudHMuREVSSVZBVElPTl9OT05FLCAoc2hvcnQpIChYU0NvbnN0YW50cy5ERVJJVkFUSU9OX0VYVEVOU0lPTiB8IFhTQ29uc3RhbnRzLkRFUklWQVRJT05fUkVTVFJJQ1RJT04pLAotICAgICAgICAgICAgICAgICAgICBYU0NvbXBsZXhUeXBlRGVjbC5DT05URU5UVFlQRV9FTEVNRU5ULCBmYWxzZSwgYW5ub3RhdGlvbkF0dHJzLCBudWxsLCBhbm5vdGF0aW9uUGFydGljbGUsIG5ldyBYU09iamVjdExpc3RJbXBsKG51bGwsIDApKTsKLSAgICAgICAgICAgIGFubm90YXRpb25UeXBlLnNldE5hbWUoIiNBbm9uVHlwZV8iICsgU2NoZW1hU3ltYm9scy5FTFRfQU5OT1RBVElPTik7Ci0gICAgICAgICAgICBhbm5vdGF0aW9uVHlwZS5zZXRJc0Fub255bW91cygpOwotCi0gICAgICAgICAgICBkb2N1bWVudGF0aW9uVHlwZS5zZXRWYWx1ZXMoIiNBbm9uVHlwZV8iICsgU2NoZW1hU3ltYm9scy5FTFRfRE9DVU1FTlRBVElPTiwgZlRhcmdldE5hbWVzcGFjZSwgU2NoZW1hR3JhbW1hci5mQW55VHlwZSwKLSAgICAgICAgICAgICAgICAgICAgWFNDb25zdGFudHMuREVSSVZBVElPTl9SRVNUUklDVElPTiwgWFNDb25zdGFudHMuREVSSVZBVElPTl9OT05FLCAoc2hvcnQpIChYU0NvbnN0YW50cy5ERVJJVkFUSU9OX0VYVEVOU0lPTiB8IFhTQ29uc3RhbnRzLkRFUklWQVRJT05fUkVTVFJJQ1RJT04pLAotICAgICAgICAgICAgICAgICAgICBYU0NvbXBsZXhUeXBlRGVjbC5DT05URU5UVFlQRV9NSVhFRCwgZmFsc2UsIGRvY3VtZW50YXRpb25BdHRycywgbnVsbCwgYW55V0NTZXF1ZW5jZVBhcnRpY2xlLCBuZXcgWFNPYmplY3RMaXN0SW1wbChudWxsLCAwKSk7Ci0gICAgICAgICAgICBkb2N1bWVudGF0aW9uVHlwZS5zZXROYW1lKCIjQW5vblR5cGVfIiArIFNjaGVtYVN5bWJvbHMuRUxUX0RPQ1VNRU5UQVRJT04pOwotICAgICAgICAgICAgZG9jdW1lbnRhdGlvblR5cGUuc2V0SXNBbm9ueW1vdXMoKTsKLQotICAgICAgICAgICAgYXBwaW5mb1R5cGUuc2V0VmFsdWVzKCIjQW5vblR5cGVfIiArIFNjaGVtYVN5bWJvbHMuRUxUX0FQUElORk8sIGZUYXJnZXROYW1lc3BhY2UsIFNjaGVtYUdyYW1tYXIuZkFueVR5cGUsCi0gICAgICAgICAgICAgICAgICAgIFhTQ29uc3RhbnRzLkRFUklWQVRJT05fUkVTVFJJQ1RJT04sIFhTQ29uc3RhbnRzLkRFUklWQVRJT05fTk9ORSwgKHNob3J0KSAoWFNDb25zdGFudHMuREVSSVZBVElPTl9FWFRFTlNJT04gfCBYU0NvbnN0YW50cy5ERVJJVkFUSU9OX1JFU1RSSUNUSU9OKSwKLSAgICAgICAgICAgICAgICAgICAgWFNDb21wbGV4VHlwZURlY2wuQ09OVEVOVFRZUEVfTUlYRUQsIGZhbHNlLCBhcHBpbmZvQXR0cnMsIG51bGwsIGFueVdDU2VxdWVuY2VQYXJ0aWNsZSwgbmV3IFhTT2JqZWN0TGlzdEltcGwobnVsbCwgMCkpOwotICAgICAgICAgICAgYXBwaW5mb1R5cGUuc2V0TmFtZSgiI0Fub25UeXBlXyIgKyBTY2hlbWFTeW1ib2xzLkVMVF9BUFBJTkZPKTsKLSAgICAgICAgICAgIGFwcGluZm9UeXBlLnNldElzQW5vbnltb3VzKCk7Ci0KLSAgICAgICAgfSAvLyA8aW5pdD4oaW50KQotCi0gICAgICAgIC8vIHJldHVybiB0aGUgWE1MR3JhbW1hckRlc2NyaXB0aW9uIGNvcnJlc3BvbmRpbmcgdG8gdGhpcwotICAgICAgICAvLyBvYmplY3QKLSAgICAgICAgcHVibGljIFhNTEdyYW1tYXJEZXNjcmlwdGlvbiBnZXRHcmFtbWFyRGVzY3JpcHRpb24oKSB7Ci0gICAgICAgICAgICByZXR1cm4gZkdyYW1tYXJEZXNjcmlwdGlvbi5tYWtlQ2xvbmUoKTsKLSAgICAgICAgfSAvLyBnZXRHcmFtbWFyRGVzY3JpcHRpb24oKTogIFhNTEdyYW1tYXJEZXNjcmlwdGlvbgotCi0gICAgICAgIC8vIG92ZXJyaWRlIHRoZXNlIG1ldGhvZHMgc29sZWx5IHNvIHRoYXQgdGhlc2UKLSAgICAgICAgLy8gb2JqZWN0cyBjYW5ub3QgYmUgbW9kaWZpZWQgb25jZSB0aGV5J3JlIGNyZWF0ZWQuCi0gICAgICAgIHB1YmxpYyB2b2lkIHNldEltcG9ydGVkR3JhbW1hcnMoVmVjdG9yIGltcG9ydGVkR3JhbW1hcnMpIHsKLSAgICAgICAgICAgIC8vIGlnbm9yZQotICAgICAgICB9Ci0gICAgICAgIHB1YmxpYyB2b2lkIGFkZEdsb2JhbEF0dHJpYnV0ZURlY2woWFNBdHRyaWJ1dGVEZWNsIGRlY2wpIHsKLSAgICAgICAgICAgIC8vIGlnbm9yZQotICAgICAgICB9Ci0gICAgICAgIHB1YmxpYyB2b2lkIGFkZEdsb2JhbEF0dHJpYnV0ZURlY2woWFNBdHRyaWJ1dGVHcm91cERlY2wgZGVjbCwgU3RyaW5nIGxvY2F0aW9uKSB7Ci0gICAgICAgICAgICAvLyBpZ25vcmUKLSAgICAgICAgfQotICAgICAgICBwdWJsaWMgdm9pZCBhZGRHbG9iYWxBdHRyaWJ1dGVHcm91cERlY2woWFNBdHRyaWJ1dGVHcm91cERlY2wgZGVjbCkgewotICAgICAgICAgICAgLy8gaWdub3JlCi0gICAgICAgIH0KLSAgICAgICAgcHVibGljIHZvaWQgYWRkR2xvYmFsQXR0cmlidXRlR3JvdXBEZWNsKFhTQXR0cmlidXRlR3JvdXBEZWNsIGRlY2wsIFN0cmluZyBsb2NhdGlvbikgewotICAgICAgICAgICAgLy8gaWdub3JlCi0gICAgICAgIH0KLSAgICAgICAgcHVibGljIHZvaWQgYWRkR2xvYmFsRWxlbWVudERlY2woWFNFbGVtZW50RGVjbCBkZWNsKSB7Ci0gICAgICAgICAgICAvLyBpZ25vcmUKLSAgICAgICAgfQotICAgICAgICBwdWJsaWMgdm9pZCBhZGRHbG9iYWxFbGVtZW50RGVjbChYU0VsZW1lbnREZWNsIGRlY2wsIFN0cmluZyBsb2NhdGlvbikgewotICAgICAgICAgICAgLy8gaWdub3JlCi0gICAgICAgIH0KLSAgICAgICAgcHVibGljIHZvaWQgYWRkR2xvYmFsRWxlbWVudERlY2xBbGwoWFNFbGVtZW50RGVjbCBkZWNsKSB7Ci0gICAgICAgICAgICAvLyBpZ25vcmUKLSAgICAgICAgfQotICAgICAgICBwdWJsaWMgdm9pZCBhZGRHbG9iYWxHcm91cERlY2woWFNHcm91cERlY2wgZGVjbCkgewotICAgICAgICAgICAgLy8gaWdub3JlCi0gICAgICAgIH0KLSAgICAgICAgcHVibGljIHZvaWQgYWRkR2xvYmFsR3JvdXBEZWNsKFhTR3JvdXBEZWNsIGRlY2wsIFN0cmluZyBsb2NhdGlvbikgewotICAgICAgICAgICAgLy8gaWdub3JlCi0gICAgICAgIH0KLSAgICAgICAgcHVibGljIHZvaWQgYWRkR2xvYmFsTm90YXRpb25EZWNsKFhTTm90YXRpb25EZWNsIGRlY2wpIHsKLSAgICAgICAgICAgIC8vIGlnbm9yZQotICAgICAgICB9Ci0gICAgICAgIHB1YmxpYyB2b2lkIGFkZEdsb2JhbE5vdGF0aW9uRGVjbChYU05vdGF0aW9uRGVjbCBkZWNsLCBTdHJpbmcgbG9jYXRpb24pIHsKLSAgICAgICAgICAgIC8vIGlnbm9yZQotICAgICAgICB9Ci0gICAgICAgIHB1YmxpYyB2b2lkIGFkZEdsb2JhbFR5cGVEZWNsKFhTVHlwZURlZmluaXRpb24gZGVjbCkgewotICAgICAgICAgICAgLy8gaWdub3JlCi0gICAgICAgIH0KLSAgICAgICAgcHVibGljIHZvaWQgYWRkR2xvYmFsVHlwZURlY2woWFNUeXBlRGVmaW5pdGlvbiBkZWNsLCBTdHJpbmcgbG9jYXRpb24pIHsKLSAgICAgICAgICAgIC8vIGlnbm9yZQotICAgICAgICB9Ci0gICAgICAgIHB1YmxpYyB2b2lkIGFkZEdsb2JhbENvbXBsZXhUeXBlRGVjbChYU0NvbXBsZXhUeXBlRGVjbCBkZWNsKSB7Ci0gICAgICAgICAgICAvLyBpZ25vcmUKLSAgICAgICAgfQotICAgICAgICBwdWJsaWMgdm9pZCBhZGRHbG9iYWxDb21wbGV4VHlwZURlY2woWFNDb21wbGV4VHlwZURlY2wgZGVjbCwgU3RyaW5nIGxvY2F0aW9uKSB7Ci0gICAgICAgICAgICAvLyBpZ25vcmUKLSAgICAgICAgfQotICAgICAgICBwdWJsaWMgdm9pZCBhZGRHbG9iYWxTaW1wbGVUeXBlRGVjbChYU1NpbXBsZVR5cGUgZGVjbCkgewotICAgICAgICAgICAgLy8gaWdub3JlCi0gICAgICAgIH0KLSAgICAgICAgcHVibGljIHZvaWQgYWRkR2xvYmFsU2ltcGxlVHlwZURlY2woWFNTaW1wbGVUeXBlIGRlY2wsIFN0cmluZyBsb2NhdGlvbikgewotICAgICAgICAgICAgLy8gaWdub3JlCi0gICAgICAgIH0KLSAgICAgICAgcHVibGljIHZvaWQgYWRkQ29tcGxleFR5cGVEZWNsKFhTQ29tcGxleFR5cGVEZWNsIGRlY2wsIFNpbXBsZUxvY2F0b3IgbG9jYXRvcikgewotICAgICAgICAgICAgLy8gaWdub3JlCi0gICAgICAgIH0KLSAgICAgICAgcHVibGljIHZvaWQgYWRkUmVkZWZpbmVkR3JvdXBEZWNsKFhTR3JvdXBEZWNsIGRlcml2ZWQsIFhTR3JvdXBEZWNsIGJhc2UsIFNpbXBsZUxvY2F0b3IgbG9jYXRvcikgewotICAgICAgICAgICAgLy8gaWdub3JlCi0gICAgICAgIH0KLSAgICAgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIGFkZERvY3VtZW50KE9iamVjdCBkb2N1bWVudCwgU3RyaW5nIGxvY2F0aW9uKSB7Ci0gICAgICAgICAgICAvLyBpZ25vcmUKLSAgICAgICAgfQotCi0gICAgICAgIC8vIGFubm90YXRpb24gc3VwcG9ydAotICAgICAgICBzeW5jaHJvbml6ZWQgRE9NUGFyc2VyIGdldERPTVBhcnNlcigpIHsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgICAgIHN5bmNocm9uaXplZCBTQVhQYXJzZXIgZ2V0U0FYUGFyc2VyKCkgewotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLQotICAgICAgICAvLwotICAgICAgICAvLyBwcml2YXRlIGhlbHBlciBtZXRob2RzCi0gICAgICAgIC8vCi0KLSAgICAgICAgcHJpdmF0ZSBYU0VsZW1lbnREZWNsIGNyZWF0ZUFubm90YXRpb25FbGVtZW50RGVjbChTdHJpbmcgbG9jYWxOYW1lKSB7Ci0gICAgICAgICAgICBYU0VsZW1lbnREZWNsIGVEZWNsID0gbmV3IFhTRWxlbWVudERlY2woKTsKLSAgICAgICAgICAgIGVEZWNsLmZOYW1lID0gbG9jYWxOYW1lOwotICAgICAgICAgICAgZURlY2wuZlRhcmdldE5hbWVzcGFjZSA9IGZUYXJnZXROYW1lc3BhY2U7Ci0gICAgICAgICAgICBlRGVjbC5zZXRJc0dsb2JhbCgpOwotICAgICAgICAgICAgZURlY2wuZkJsb2NrID0gKFhTQ29uc3RhbnRzLkRFUklWQVRJT05fRVhURU5TSU9OIHwKLSAgICAgICAgICAgICAgICAgICAgWFNDb25zdGFudHMuREVSSVZBVElPTl9SRVNUUklDVElPTiB8IFhTQ29uc3RhbnRzLkRFUklWQVRJT05fU1VCU1RJVFVUSU9OKTsKLSAgICAgICAgICAgIGVEZWNsLnNldENvbnN0cmFpbnRUeXBlKFhTQ29uc3RhbnRzLlZDX05PTkUpOwotICAgICAgICAgICAgcmV0dXJuIGVEZWNsOwotICAgICAgICB9Ci0KLSAgICAgICAgcHJpdmF0ZSBYU1BhcnRpY2xlRGVjbCBjcmVhdGVVbmJvdW5kZWRNb2RlbEdyb3VwUGFydGljbGUoKSB7Ci0gICAgICAgICAgICBYU1BhcnRpY2xlRGVjbCBwYXJ0aWNsZSA9IG5ldyBYU1BhcnRpY2xlRGVjbCgpOwotICAgICAgICAgICAgcGFydGljbGUuZk1pbk9jY3VycyA9IDA7Ci0gICAgICAgICAgICBwYXJ0aWNsZS5mTWF4T2NjdXJzID0gU2NoZW1hU3ltYm9scy5PQ0NVUlJFTkNFX1VOQk9VTkRFRDsKLSAgICAgICAgICAgIHBhcnRpY2xlLmZUeXBlID0gWFNQYXJ0aWNsZURlY2wuUEFSVElDTEVfTU9ERUxHUk9VUDsKLSAgICAgICAgICAgIHJldHVybiBwYXJ0aWNsZTsKLSAgICAgICAgfQotCi0gICAgICAgIHByaXZhdGUgWFNQYXJ0aWNsZURlY2wgY3JlYXRlQ2hvaWNlRWxlbWVudFBhcnRpY2xlKFhTRWxlbWVudERlY2wgcmVmKSB7Ci0gICAgICAgICAgICBYU1BhcnRpY2xlRGVjbCBwYXJ0aWNsZSA9IG5ldyBYU1BhcnRpY2xlRGVjbCgpOwotICAgICAgICAgICAgcGFydGljbGUuZk1pbk9jY3VycyA9IDE7Ci0gICAgICAgICAgICBwYXJ0aWNsZS5mTWF4T2NjdXJzID0gMTsKLSAgICAgICAgICAgIHBhcnRpY2xlLmZUeXBlID0gWFNQYXJ0aWNsZURlY2wuUEFSVElDTEVfRUxFTUVOVDsKLSAgICAgICAgICAgIHBhcnRpY2xlLmZWYWx1ZSA9IHJlZjsKLSAgICAgICAgICAgIHJldHVybiBwYXJ0aWNsZTsKLSAgICAgICAgfQotCi0gICAgICAgIHByaXZhdGUgWFNQYXJ0aWNsZURlY2wgY3JlYXRlVW5ib3VuZGVkQW55V2lsZGNhcmRTZXF1ZW5jZVBhcnRpY2xlKCkgewotICAgICAgICAgICAgWFNQYXJ0aWNsZURlY2wgcGFydGljbGUgPSBjcmVhdGVVbmJvdW5kZWRNb2RlbEdyb3VwUGFydGljbGUoKTsKLSAgICAgICAgICAgIFhTTW9kZWxHcm91cEltcGwgc2VxdWVuY2UgPSBuZXcgWFNNb2RlbEdyb3VwSW1wbCgpOwotICAgICAgICAgICAgc2VxdWVuY2UuZkNvbXBvc2l0b3IgPSBYU01vZGVsR3JvdXBJbXBsLk1PREVMR1JPVVBfU0VRVUVOQ0U7Ci0gICAgICAgICAgICBzZXF1ZW5jZS5mUGFydGljbGVDb3VudCA9IDE7Ci0gICAgICAgICAgICBzZXF1ZW5jZS5mUGFydGljbGVzID0gbmV3IFhTUGFydGljbGVEZWNsWzFdOwotICAgICAgICAgICAgc2VxdWVuY2UuZlBhcnRpY2xlc1swXSA9IGNyZWF0ZUFueUxheFdpbGRjYXJkUGFydGljbGUoKTsKLSAgICAgICAgICAgIHBhcnRpY2xlLmZWYWx1ZSA9IHNlcXVlbmNlOwotICAgICAgICAgICAgcmV0dXJuIHBhcnRpY2xlOwotICAgICAgICB9Ci0KLSAgICAgICAgcHJpdmF0ZSBYU1BhcnRpY2xlRGVjbCBjcmVhdGVBbnlMYXhXaWxkY2FyZFBhcnRpY2xlKCkgewotICAgICAgICAgICAgWFNQYXJ0aWNsZURlY2wgcGFydGljbGUgPSBuZXcgWFNQYXJ0aWNsZURlY2woKTsKLSAgICAgICAgICAgIHBhcnRpY2xlLmZNaW5PY2N1cnMgPSAxOwotICAgICAgICAgICAgcGFydGljbGUuZk1heE9jY3VycyA9IDE7Ci0gICAgICAgICAgICBwYXJ0aWNsZS5mVHlwZSA9IFhTUGFydGljbGVEZWNsLlBBUlRJQ0xFX1dJTERDQVJEOwotCi0gICAgICAgICAgICBYU1dpbGRjYXJkRGVjbCBhbnlXQyA9IG5ldyBYU1dpbGRjYXJkRGVjbCgpOwotICAgICAgICAgICAgYW55V0MuZk5hbWVzcGFjZUxpc3QgPSBudWxsOwotICAgICAgICAgICAgYW55V0MuZlR5cGUgPSBYU1dpbGRjYXJkLk5TQ09OU1RSQUlOVF9BTlk7Ci0gICAgICAgICAgICBhbnlXQy5mUHJvY2Vzc0NvbnRlbnRzID0gWFNXaWxkY2FyZC5QQ19MQVg7Ci0KLSAgICAgICAgICAgIHBhcnRpY2xlLmZWYWx1ZSA9IGFueVdDOwotICAgICAgICAgICAgcmV0dXJuIHBhcnRpY2xlOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLy8gR3JhbW1hciBtZXRob2RzCi0KLSAgICAvLyByZXR1cm4gdGhlIFhNTEdyYW1tYXJEZXNjcmlwdGlvbiBjb3JyZXNwb25kaW5nIHRvIHRoaXMKLSAgICAvLyBvYmplY3QKLSAgICBwdWJsaWMgWE1MR3JhbW1hckRlc2NyaXB0aW9uIGdldEdyYW1tYXJEZXNjcmlwdGlvbigpIHsKLSAgICAgICAgcmV0dXJuIGZHcmFtbWFyRGVzY3JpcHRpb247Ci0gICAgfSAvLyBnZXRHcmFtbWFyRGVzY3JpcHRpb24oKTogIFhNTEdyYW1tYXJEZXNjcmlwdGlvbgotCi0gICAgLy8gRFRER3JhbW1hciBtZXRob2RzCi0gICAgcHVibGljIGJvb2xlYW4gaXNOYW1lc3BhY2VBd2FyZSAoKSB7Ci0gICAgICAgIHJldHVybiB0cnVlOwotICAgIH0gLy8gaXNOYW1lc3BhY2VBd2FyZSgpOmJvb2xlYW4KLQotICAgIFZlY3RvciBmSW1wb3J0ZWQgPSBudWxsOwotCi0gICAgcHVibGljIHZvaWQgc2V0SW1wb3J0ZWRHcmFtbWFycyhWZWN0b3IgaW1wb3J0ZWRHcmFtbWFycykgewotICAgICAgICBmSW1wb3J0ZWQgPSBpbXBvcnRlZEdyYW1tYXJzOwotICAgIH0KLQotICAgIHB1YmxpYyBWZWN0b3IgZ2V0SW1wb3J0ZWRHcmFtbWFycygpIHsKLSAgICAgICAgcmV0dXJuIGZJbXBvcnRlZDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoaXMgZ3JhbW1hcidzIHRhcmdldCBuYW1lc3BhY2UuCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIFN0cmluZyBnZXRUYXJnZXROYW1lc3BhY2UoKSB7Ci0gICAgICAgIHJldHVybiBmVGFyZ2V0TmFtZXNwYWNlOwotICAgIH0gLy8gZ2V0VGFyZ2V0TmFtZXNwYWNlKCk6U3RyaW5nCi0KLSAgICAvKioKLSAgICAgKiByZWdpc3RlciBvbmUgZ2xvYmFsIGF0dHJpYnV0ZQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGFkZEdsb2JhbEF0dHJpYnV0ZURlY2woWFNBdHRyaWJ1dGVEZWNsIGRlY2wpIHsKLSAgICAgICAgZkdsb2JhbEF0dHJEZWNscy5wdXQoZGVjbC5mTmFtZSwgZGVjbCk7Ci0gICAgICAgIGRlY2wuc2V0TmFtZXNwYWNlSXRlbSh0aGlzKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBhZGRHbG9iYWxBdHRyaWJ1dGVEZWNsKFhTQXR0cmlidXRlRGVjbCBkZWNsLCBTdHJpbmcgbG9jYXRpb24pIHsKLSAgICAgICAgZkdsb2JhbEF0dHJEZWNsc0V4dC5wdXQoKChsb2NhdGlvbiE9bnVsbCkgPyBsb2NhdGlvbiA6ICIiKSArICIsIiArIGRlY2wuZk5hbWUsIGRlY2wpOwotICAgICAgICBpZiAoZGVjbC5nZXROYW1lc3BhY2VJdGVtKCkgPT0gbnVsbCkgewotICAgICAgICAgICAgZGVjbC5zZXROYW1lc3BhY2VJdGVtKHRoaXMpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogcmVnaXN0ZXIgb25lIGdsb2JhbCBhdHRyaWJ1dGUgZ3JvdXAKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBhZGRHbG9iYWxBdHRyaWJ1dGVHcm91cERlY2woWFNBdHRyaWJ1dGVHcm91cERlY2wgZGVjbCkgewotICAgICAgICBmR2xvYmFsQXR0ckdycERlY2xzLnB1dChkZWNsLmZOYW1lLCBkZWNsKTsKLSAgICAgICAgZGVjbC5zZXROYW1lc3BhY2VJdGVtKHRoaXMpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGFkZEdsb2JhbEF0dHJpYnV0ZUdyb3VwRGVjbChYU0F0dHJpYnV0ZUdyb3VwRGVjbCBkZWNsLCBTdHJpbmcgbG9jYXRpb24pIHsKLSAgICAgICAgZkdsb2JhbEF0dHJHcnBEZWNsc0V4dC5wdXQoKChsb2NhdGlvbiE9bnVsbCkgPyBsb2NhdGlvbiA6ICIiKSArICIsIiArIGRlY2wuZk5hbWUsIGRlY2wpOwotICAgICAgICBpZiAoZGVjbC5nZXROYW1lc3BhY2VJdGVtKCkgPT0gbnVsbCkgewotICAgICAgICAgICAgZGVjbC5zZXROYW1lc3BhY2VJdGVtKHRoaXMpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogcmVnaXN0ZXIgb25lIGdsb2JhbCBlbGVtZW50Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgYWRkR2xvYmFsRWxlbWVudERlY2xBbGwoWFNFbGVtZW50RGVjbCBkZWNsKSB7Ci0gICAgICAgIGlmIChmQWxsR2xvYmFsRWxlbURlY2xzLmdldChkZWNsKSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBmQWxsR2xvYmFsRWxlbURlY2xzLnB1dChkZWNsLCBkZWNsKTsKLSAgICAgICAgICAgIC8vIGlmIHRoZXJlIGlzIGEgc3Vic3RpdHV0aW9uIGdyb3VwIGFmZmlsaWF0aW9uLCBzdG9yZSBpbiBhbiBhcnJheSwKLSAgICAgICAgICAgIC8vIGZvciBmdXJ0aGVyIGNvbnN0cmFpbnQgY2hlY2tpbmc6IFVQQSwgUEQsIEVEQwotICAgICAgICAgICAgaWYgKGRlY2wuZlN1Ykdyb3VwICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgIGlmIChmU3ViR3JvdXBDb3VudCA9PSBmU3ViR3JvdXBzLmxlbmd0aCkKLSAgICAgICAgICAgICAgICAgICAgZlN1Ykdyb3VwcyA9IHJlc2l6ZShmU3ViR3JvdXBzLCBmU3ViR3JvdXBDb3VudCtJTkNfU0laRSk7Ci0gICAgICAgICAgICAgICAgZlN1Ykdyb3Vwc1tmU3ViR3JvdXBDb3VudCsrXSA9IGRlY2w7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBhZGRHbG9iYWxFbGVtZW50RGVjbChYU0VsZW1lbnREZWNsIGRlY2wpIHsKLSAgICAgICAgZkdsb2JhbEVsZW1EZWNscy5wdXQoZGVjbC5mTmFtZSwgZGVjbCk7Ci0gICAgICAgIGRlY2wuc2V0TmFtZXNwYWNlSXRlbSh0aGlzKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBhZGRHbG9iYWxFbGVtZW50RGVjbChYU0VsZW1lbnREZWNsIGRlY2wsIFN0cmluZyBsb2NhdGlvbikgewotICAgICAgICBmR2xvYmFsRWxlbURlY2xzRXh0LnB1dCgoKGxvY2F0aW9uICE9IG51bGwpID8gbG9jYXRpb24gOiAiIikgKyAiLCIgKyBkZWNsLmZOYW1lLCBkZWNsKTsKLSAgICAgICAgaWYgKGRlY2wuZ2V0TmFtZXNwYWNlSXRlbSgpID09IG51bGwpIHsKLSAgICAgICAgICAgIGRlY2wuc2V0TmFtZXNwYWNlSXRlbSh0aGlzKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIHJlZ2lzdGVyIG9uZSBnbG9iYWwgZ3JvdXAKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBhZGRHbG9iYWxHcm91cERlY2woWFNHcm91cERlY2wgZGVjbCkgewotICAgICAgICBmR2xvYmFsR3JvdXBEZWNscy5wdXQoZGVjbC5mTmFtZSwgZGVjbCk7Ci0gICAgICAgIGRlY2wuc2V0TmFtZXNwYWNlSXRlbSh0aGlzKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBhZGRHbG9iYWxHcm91cERlY2woWFNHcm91cERlY2wgZGVjbCwgU3RyaW5nIGxvY2F0aW9uKSB7Ci0gICAgICAgIGZHbG9iYWxHcm91cERlY2xzRXh0LnB1dCgoKGxvY2F0aW9uIT1udWxsKSA/IGxvY2F0aW9uIDogIiIpICsgIiwiICsgZGVjbC5mTmFtZSwgZGVjbCk7Ci0gICAgICAgIGlmIChkZWNsLmdldE5hbWVzcGFjZUl0ZW0oKSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBkZWNsLnNldE5hbWVzcGFjZUl0ZW0odGhpcyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiByZWdpc3RlciBvbmUgZ2xvYmFsIG5vdGF0aW9uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgYWRkR2xvYmFsTm90YXRpb25EZWNsKFhTTm90YXRpb25EZWNsIGRlY2wpIHsKLSAgICAgICAgZkdsb2JhbE5vdGF0aW9uRGVjbHMucHV0KGRlY2wuZk5hbWUsIGRlY2wpOwotICAgICAgICBkZWNsLnNldE5hbWVzcGFjZUl0ZW0odGhpcyk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgYWRkR2xvYmFsTm90YXRpb25EZWNsKFhTTm90YXRpb25EZWNsIGRlY2wsIFN0cmluZyBsb2NhdGlvbikgewotICAgICAgICBmR2xvYmFsTm90YXRpb25EZWNsc0V4dC5wdXQoKChsb2NhdGlvbiE9bnVsbCkgPyBsb2NhdGlvbiA6ICIiKSArICIsIiArZGVjbC5mTmFtZSwgZGVjbCk7Ci0gICAgICAgIGlmIChkZWNsLmdldE5hbWVzcGFjZUl0ZW0oKSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBkZWNsLnNldE5hbWVzcGFjZUl0ZW0odGhpcyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiByZWdpc3RlciBvbmUgZ2xvYmFsIHR5cGUKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBhZGRHbG9iYWxUeXBlRGVjbChYU1R5cGVEZWZpbml0aW9uIGRlY2wpIHsKLSAgICAgICAgZkdsb2JhbFR5cGVEZWNscy5wdXQoZGVjbC5nZXROYW1lKCksIGRlY2wpOwotICAgICAgICBpZiAoZGVjbCBpbnN0YW5jZW9mIFhTQ29tcGxleFR5cGVEZWNsKSB7Ci0gICAgICAgICAgICAoKFhTQ29tcGxleFR5cGVEZWNsKSBkZWNsKS5zZXROYW1lc3BhY2VJdGVtKHRoaXMpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKGRlY2wgaW5zdGFuY2VvZiBYU1NpbXBsZVR5cGVEZWNsKSB7Ci0gICAgICAgICAgICAoKFhTU2ltcGxlVHlwZURlY2wpIGRlY2wpLnNldE5hbWVzcGFjZUl0ZW0odGhpcyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBhZGRHbG9iYWxUeXBlRGVjbChYU1R5cGVEZWZpbml0aW9uIGRlY2wsIFN0cmluZyBsb2NhdGlvbikgewotICAgICAgICBmR2xvYmFsVHlwZURlY2xzRXh0LnB1dCgoKGxvY2F0aW9uIT1udWxsKSA/IGxvY2F0aW9uIDogIiIpICsgIiwiICsgZGVjbC5nZXROYW1lKCksIGRlY2wpOwotICAgICAgICBpZiAoZGVjbC5nZXROYW1lc3BhY2VJdGVtKCkgPT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKGRlY2wgaW5zdGFuY2VvZiBYU0NvbXBsZXhUeXBlRGVjbCkgewotICAgICAgICAgICAgICAgICgoWFNDb21wbGV4VHlwZURlY2wpIGRlY2wpLnNldE5hbWVzcGFjZUl0ZW0odGhpcyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChkZWNsIGluc3RhbmNlb2YgWFNTaW1wbGVUeXBlRGVjbCkgewotICAgICAgICAgICAgICAgICgoWFNTaW1wbGVUeXBlRGVjbCkgZGVjbCkuc2V0TmFtZXNwYWNlSXRlbSh0aGlzKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIHJlZ2lzdGVyIG9uZSBnbG9iYWwgY29tcGxleCB0eXBlCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgYWRkR2xvYmFsQ29tcGxleFR5cGVEZWNsKFhTQ29tcGxleFR5cGVEZWNsIGRlY2wpIHsKLSAgICAgICAgZkdsb2JhbFR5cGVEZWNscy5wdXQoZGVjbC5nZXROYW1lKCksIGRlY2wpOwotICAgICAgICBkZWNsLnNldE5hbWVzcGFjZUl0ZW0odGhpcyk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgYWRkR2xvYmFsQ29tcGxleFR5cGVEZWNsKFhTQ29tcGxleFR5cGVEZWNsIGRlY2wsIFN0cmluZyBsb2NhdGlvbikgewotICAgICAgICBmR2xvYmFsVHlwZURlY2xzRXh0LnB1dCgoKGxvY2F0aW9uIT1udWxsKSA/IGxvY2F0aW9uIDogIiIpICsgIiwiICsgZGVjbC5nZXROYW1lKCksIGRlY2wpOwotICAgICAgICBpZiAoZGVjbC5nZXROYW1lc3BhY2VJdGVtKCkgPT0gbnVsbCkgewotICAgICAgICAgICAgZGVjbC5zZXROYW1lc3BhY2VJdGVtKHRoaXMpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogcmVnaXN0ZXIgb25lIGdsb2JhbCBzaW1wbGUgdHlwZQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGFkZEdsb2JhbFNpbXBsZVR5cGVEZWNsKFhTU2ltcGxlVHlwZSBkZWNsKSB7Ci0gICAgICAgIGZHbG9iYWxUeXBlRGVjbHMucHV0KGRlY2wuZ2V0TmFtZSgpLCBkZWNsKTsKLSAgICAgICAgaWYgKGRlY2wgaW5zdGFuY2VvZiBYU1NpbXBsZVR5cGVEZWNsKSB7Ci0gICAgICAgICAgICAoKFhTU2ltcGxlVHlwZURlY2wpIGRlY2wpLnNldE5hbWVzcGFjZUl0ZW0odGhpcyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBhZGRHbG9iYWxTaW1wbGVUeXBlRGVjbChYU1NpbXBsZVR5cGUgZGVjbCwgU3RyaW5nIGxvY2F0aW9uKSB7Ci0gICAgICAgIGZHbG9iYWxUeXBlRGVjbHNFeHQucHV0KCgobG9jYXRpb24gIT0gbnVsbCkgPyBsb2NhdGlvbiA6ICIiKSArICIsIiArIGRlY2wuZ2V0TmFtZSgpLCBkZWNsKTsKLSAgICAgICAgaWYgKGRlY2wuZ2V0TmFtZXNwYWNlSXRlbSgpID09IG51bGwgJiYgZGVjbCBpbnN0YW5jZW9mIFhTU2ltcGxlVHlwZURlY2wpIHsKLSAgICAgICAgICAgICgoWFNTaW1wbGVUeXBlRGVjbCkgZGVjbCkuc2V0TmFtZXNwYWNlSXRlbSh0aGlzKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIHJlZ2lzdGVyIG9uZSBpZGVudGl0eSBjb25zdHJhaW50Ci0gICAgICovCi0gICAgcHVibGljIGZpbmFsIHZvaWQgYWRkSURDb25zdHJhaW50RGVjbChYU0VsZW1lbnREZWNsIGVsbURlY2wsIElkZW50aXR5Q29uc3RyYWludCBkZWNsKSB7Ci0gICAgICAgIGVsbURlY2wuYWRkSURDb25zdHJhaW50KGRlY2wpOwotICAgICAgICBmR2xvYmFsSURDb25zdHJhaW50RGVjbHMucHV0KGRlY2wuZ2V0SWRlbnRpdHlDb25zdHJhaW50TmFtZSgpLCBkZWNsKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgZmluYWwgdm9pZCBhZGRJRENvbnN0cmFpbnREZWNsKFhTRWxlbWVudERlY2wgZWxtRGVjbCwgSWRlbnRpdHlDb25zdHJhaW50IGRlY2wsIFN0cmluZyBsb2NhdGlvbikgewotICAgICAgICBmR2xvYmFsSURDb25zdHJhaW50RGVjbHNFeHQucHV0KCgobG9jYXRpb24gIT0gbnVsbCkgPyBsb2NhdGlvbiA6ICIiKSArICIsIiArIGRlY2wuZ2V0SWRlbnRpdHlDb25zdHJhaW50TmFtZSgpLCBkZWNsKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBnZXQgb25lIGdsb2JhbCBhdHRyaWJ1dGUKLSAgICAgKi8KLSAgICBwdWJsaWMgZmluYWwgWFNBdHRyaWJ1dGVEZWNsIGdldEdsb2JhbEF0dHJpYnV0ZURlY2woU3RyaW5nIGRlY2xOYW1lKSB7Ci0gICAgICAgIHJldHVybihYU0F0dHJpYnV0ZURlY2wpZkdsb2JhbEF0dHJEZWNscy5nZXQoZGVjbE5hbWUpOwotICAgIH0KLQotICAgIHB1YmxpYyBmaW5hbCBYU0F0dHJpYnV0ZURlY2wgZ2V0R2xvYmFsQXR0cmlidXRlRGVjbChTdHJpbmcgZGVjbE5hbWUsIFN0cmluZyBsb2NhdGlvbikgewotICAgICAgICByZXR1cm4oWFNBdHRyaWJ1dGVEZWNsKWZHbG9iYWxBdHRyRGVjbHNFeHQuZ2V0KCgobG9jYXRpb24gIT0gbnVsbCkgPyBsb2NhdGlvbiA6ICIiKSArICIsIiArIGRlY2xOYW1lKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBnZXQgb25lIGdsb2JhbCBhdHRyaWJ1dGUgZ3JvdXAKLSAgICAgKi8KLSAgICBwdWJsaWMgZmluYWwgWFNBdHRyaWJ1dGVHcm91cERlY2wgZ2V0R2xvYmFsQXR0cmlidXRlR3JvdXBEZWNsKFN0cmluZyBkZWNsTmFtZSkgewotICAgICAgICByZXR1cm4oWFNBdHRyaWJ1dGVHcm91cERlY2wpZkdsb2JhbEF0dHJHcnBEZWNscy5nZXQoZGVjbE5hbWUpOwotICAgIH0KLQotICAgIHB1YmxpYyBmaW5hbCBYU0F0dHJpYnV0ZUdyb3VwRGVjbCBnZXRHbG9iYWxBdHRyaWJ1dGVHcm91cERlY2woU3RyaW5nIGRlY2xOYW1lLCBTdHJpbmcgbG9jYXRpb24pIHsKLSAgICAgICAgcmV0dXJuKFhTQXR0cmlidXRlR3JvdXBEZWNsKWZHbG9iYWxBdHRyR3JwRGVjbHNFeHQuZ2V0KCgobG9jYXRpb24gIT0gbnVsbCkgPyBsb2NhdGlvbiA6ICIiKSArICIsIiArIGRlY2xOYW1lKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBnZXQgb25lIGdsb2JhbCBlbGVtZW50Ci0gICAgICovCi0gICAgcHVibGljIGZpbmFsIFhTRWxlbWVudERlY2wgZ2V0R2xvYmFsRWxlbWVudERlY2woU3RyaW5nIGRlY2xOYW1lKSB7Ci0gICAgICAgIHJldHVybihYU0VsZW1lbnREZWNsKWZHbG9iYWxFbGVtRGVjbHMuZ2V0KGRlY2xOYW1lKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgZmluYWwgWFNFbGVtZW50RGVjbCBnZXRHbG9iYWxFbGVtZW50RGVjbChTdHJpbmcgZGVjbE5hbWUsIFN0cmluZyBsb2NhdGlvbikgewotICAgICAgICByZXR1cm4oWFNFbGVtZW50RGVjbClmR2xvYmFsRWxlbURlY2xzRXh0LmdldCgoKGxvY2F0aW9uICE9IG51bGwpID8gbG9jYXRpb24gOiAiIikgKyAiLCIgKyBkZWNsTmFtZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogZ2V0IG9uZSBnbG9iYWwgZ3JvdXAKLSAgICAgKi8KLSAgICBwdWJsaWMgZmluYWwgWFNHcm91cERlY2wgZ2V0R2xvYmFsR3JvdXBEZWNsKFN0cmluZyBkZWNsTmFtZSkgewotICAgICAgICByZXR1cm4oWFNHcm91cERlY2wpZkdsb2JhbEdyb3VwRGVjbHMuZ2V0KGRlY2xOYW1lKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgZmluYWwgWFNHcm91cERlY2wgZ2V0R2xvYmFsR3JvdXBEZWNsKFN0cmluZyBkZWNsTmFtZSwgU3RyaW5nIGxvY2F0aW9uKSB7Ci0gICAgICAgIHJldHVybihYU0dyb3VwRGVjbClmR2xvYmFsR3JvdXBEZWNsc0V4dC5nZXQoKChsb2NhdGlvbiAhPSBudWxsKSA/IGxvY2F0aW9uIDogIiIpICsgIiwiICsgZGVjbE5hbWUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIGdldCBvbmUgZ2xvYmFsIG5vdGF0aW9uCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIFhTTm90YXRpb25EZWNsIGdldEdsb2JhbE5vdGF0aW9uRGVjbChTdHJpbmcgZGVjbE5hbWUpIHsKLSAgICAgICAgcmV0dXJuKFhTTm90YXRpb25EZWNsKWZHbG9iYWxOb3RhdGlvbkRlY2xzLmdldChkZWNsTmFtZSk7Ci0gICAgfQotCi0gICAgcHVibGljIGZpbmFsIFhTTm90YXRpb25EZWNsIGdldEdsb2JhbE5vdGF0aW9uRGVjbChTdHJpbmcgZGVjbE5hbWUsIFN0cmluZyBsb2NhdGlvbikgewotICAgICAgICByZXR1cm4oWFNOb3RhdGlvbkRlY2wpZkdsb2JhbE5vdGF0aW9uRGVjbHNFeHQuZ2V0KCgobG9jYXRpb24gIT0gbnVsbCkgPyBsb2NhdGlvbiA6ICIiKSArICIsIiArIGRlY2xOYW1lKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBnZXQgb25lIGdsb2JhbCB0eXBlCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIFhTVHlwZURlZmluaXRpb24gZ2V0R2xvYmFsVHlwZURlY2woU3RyaW5nIGRlY2xOYW1lKSB7Ci0gICAgICAgIHJldHVybihYU1R5cGVEZWZpbml0aW9uKWZHbG9iYWxUeXBlRGVjbHMuZ2V0KGRlY2xOYW1lKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgZmluYWwgWFNUeXBlRGVmaW5pdGlvbiBnZXRHbG9iYWxUeXBlRGVjbChTdHJpbmcgZGVjbE5hbWUsIFN0cmluZyBsb2NhdGlvbikgewotICAgICAgICByZXR1cm4oWFNUeXBlRGVmaW5pdGlvbilmR2xvYmFsVHlwZURlY2xzRXh0LmdldCgoKGxvY2F0aW9uICE9IG51bGwpID8gbG9jYXRpb24gOiAiIikgKyAiLCIgKyBkZWNsTmFtZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogZ2V0IG9uZSBpZGVudGl0eSBjb25zdHJhaW50Ci0gICAgICovCi0gICAgcHVibGljIGZpbmFsIElkZW50aXR5Q29uc3RyYWludCBnZXRJRENvbnN0cmFpbnREZWNsKFN0cmluZyBkZWNsTmFtZSkgewotICAgICAgICByZXR1cm4oSWRlbnRpdHlDb25zdHJhaW50KWZHbG9iYWxJRENvbnN0cmFpbnREZWNscy5nZXQoZGVjbE5hbWUpOwotICAgIH0KLQotICAgIHB1YmxpYyBmaW5hbCBJZGVudGl0eUNvbnN0cmFpbnQgZ2V0SURDb25zdHJhaW50RGVjbChTdHJpbmcgZGVjbE5hbWUsIFN0cmluZyBsb2NhdGlvbikgewotICAgICAgICByZXR1cm4oSWRlbnRpdHlDb25zdHJhaW50KWZHbG9iYWxJRENvbnN0cmFpbnREZWNsc0V4dC5nZXQoKChsb2NhdGlvbiAhPSBudWxsKSA/IGxvY2F0aW9uIDogIiIpICsgIiwiICsgZGVjbE5hbWUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIGdldCBvbmUgaWRlbnRpdHkgY29uc3RyYWludAotICAgICAqLwotICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGhhc0lEQ29uc3RyYWludHMoKSB7Ci0gICAgICAgIHJldHVybiBmR2xvYmFsSURDb25zdHJhaW50RGVjbHMuZ2V0TGVuZ3RoKCkgPiAwOwotICAgIH0KLQotICAgIC8vIGFycmF5IHRvIHN0b3JlIGNvbXBsZXggdHlwZSBkZWNscwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBJTklUSUFMX1NJWkUgPSAxNjsKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgSU5DX1NJWkUgICAgID0gMTY7Ci0KLSAgICBwcml2YXRlIGludCBmQ1RDb3VudCA9IDA7Ci0gICAgcHJpdmF0ZSBYU0NvbXBsZXhUeXBlRGVjbFtdIGZDb21wbGV4VHlwZURlY2xzID0gbmV3IFhTQ29tcGxleFR5cGVEZWNsW0lOSVRJQUxfU0laRV07Ci0gICAgcHJpdmF0ZSBTaW1wbGVMb2NhdG9yW10gZkNUTG9jYXRvcnMgPSBuZXcgU2ltcGxlTG9jYXRvcltJTklUSUFMX1NJWkVdOwotCi0gICAgLy8gYW4gYXJyYXkgdG8gc3RvcmUgZ3JvdXBzIGJlaW5nIHJlZGVmaW5lZCBieSByZXN0cmljdGlvbgotICAgIC8vIGV2ZW4tbnVtYmVyZWQgZWxlbWVudHMgYXJlIHRoZSBkZXJpdmVkIGdyb3Vwcywgb2RkLW51bWJlcmVkIG9uZXMgdGhlaXIgYmFzZXMKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgUkVERUZJTkVEX0dST1VQX0lOSVRfU0laRSA9IDI7Ci0gICAgcHJpdmF0ZSBpbnQgZlJHQ291bnQgPSAwOwotICAgIHByaXZhdGUgWFNHcm91cERlY2xbXSBmUmVkZWZpbmVkR3JvdXBEZWNscyA9IG5ldyBYU0dyb3VwRGVjbFtSRURFRklORURfR1JPVVBfSU5JVF9TSVpFXTsKLSAgICBwcml2YXRlIFNpbXBsZUxvY2F0b3JbXSBmUkdMb2NhdG9ycyA9IG5ldyBTaW1wbGVMb2NhdG9yW1JFREVGSU5FRF9HUk9VUF9JTklUX1NJWkUvMl07Ci0KLSAgICAvLyBhIGZsYWcgdG8gaW5kaWNhdGUgd2hldGhlciB3ZSBoYXZlIGNoZWNrZWQgdGhlIDMgY29uc3RyYWludHMgb24gdGhpcwotICAgIC8vIGdyYW1tYXIuCi0gICAgYm9vbGVhbiBmRnVsbENoZWNrZWQgPSBmYWxzZTsKLQotICAgIC8qKgotICAgICAqIGFkZCBvbmUgY29tcGxleCB0eXBlIGRlY2w6IGZvciBsYXRlciBjb25zdHJhaW50IGNoZWNraW5nCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgYWRkQ29tcGxleFR5cGVEZWNsKFhTQ29tcGxleFR5cGVEZWNsIGRlY2wsIFNpbXBsZUxvY2F0b3IgbG9jYXRvcikgewotICAgICAgICBpZiAoZkNUQ291bnQgPT0gZkNvbXBsZXhUeXBlRGVjbHMubGVuZ3RoKSB7Ci0gICAgICAgICAgICBmQ29tcGxleFR5cGVEZWNscyA9IHJlc2l6ZShmQ29tcGxleFR5cGVEZWNscywgZkNUQ291bnQrSU5DX1NJWkUpOwotICAgICAgICAgICAgZkNUTG9jYXRvcnMgPSByZXNpemUoZkNUTG9jYXRvcnMsIGZDVENvdW50K0lOQ19TSVpFKTsKLSAgICAgICAgfQotICAgICAgICBmQ1RMb2NhdG9yc1tmQ1RDb3VudF0gPSBsb2NhdG9yOwotICAgICAgICBmQ29tcGxleFR5cGVEZWNsc1tmQ1RDb3VudCsrXSA9IGRlY2w7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogYWRkIGEgZ3JvdXAgcmVkZWZpbmVkIGJ5IHJlc3RyaWN0aW9uOiBmb3IgbGF0ZXIgY29uc3RyYWludCBjaGVja2luZwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGFkZFJlZGVmaW5lZEdyb3VwRGVjbChYU0dyb3VwRGVjbCBkZXJpdmVkLCBYU0dyb3VwRGVjbCBiYXNlLCBTaW1wbGVMb2NhdG9yIGxvY2F0b3IpIHsKLSAgICAgICAgaWYgKGZSR0NvdW50ID09IGZSZWRlZmluZWRHcm91cERlY2xzLmxlbmd0aCkgewotICAgICAgICAgICAgLy8gZG91YmxlIGFycmF5IHNpemUgZWFjaCB0aW1lLgotICAgICAgICAgICAgZlJlZGVmaW5lZEdyb3VwRGVjbHMgPSByZXNpemUoZlJlZGVmaW5lZEdyb3VwRGVjbHMsIGZSR0NvdW50IDw8IDEpOwotICAgICAgICAgICAgZlJHTG9jYXRvcnMgPSByZXNpemUoZlJHTG9jYXRvcnMsIGZSR0NvdW50KTsKLSAgICAgICAgfQotICAgICAgICBmUkdMb2NhdG9yc1tmUkdDb3VudC8yXSA9IGxvY2F0b3I7Ci0gICAgICAgIGZSZWRlZmluZWRHcm91cERlY2xzW2ZSR0NvdW50KytdID0gZGVyaXZlZDsKLSAgICAgICAgZlJlZGVmaW5lZEdyb3VwRGVjbHNbZlJHQ291bnQrK10gPSBiYXNlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIGdldCBhbGwgY29tcGxleCB0eXBlIGRlY2xzOiBmb3IgbGF0ZXIgY29uc3RyYWludCBjaGVja2luZwotICAgICAqLwotICAgIGZpbmFsIFhTQ29tcGxleFR5cGVEZWNsW10gZ2V0VW5jaGVja2VkQ29tcGxleFR5cGVEZWNscygpIHsKLSAgICAgICAgaWYgKGZDVENvdW50IDwgZkNvbXBsZXhUeXBlRGVjbHMubGVuZ3RoKSB7Ci0gICAgICAgICAgICBmQ29tcGxleFR5cGVEZWNscyA9IHJlc2l6ZShmQ29tcGxleFR5cGVEZWNscywgZkNUQ291bnQpOwotICAgICAgICAgICAgZkNUTG9jYXRvcnMgPSByZXNpemUoZkNUTG9jYXRvcnMsIGZDVENvdW50KTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZkNvbXBsZXhUeXBlRGVjbHM7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogZ2V0IHRoZSBlcnJvciBsb2NhdG9yIG9mIGFsbCBjb21wbGV4IHR5cGUgZGVjbHMKLSAgICAgKi8KLSAgICBmaW5hbCBTaW1wbGVMb2NhdG9yW10gZ2V0VW5jaGVja2VkQ1RMb2NhdG9ycygpIHsKLSAgICAgICAgaWYgKGZDVENvdW50IDwgZkNUTG9jYXRvcnMubGVuZ3RoKSB7Ci0gICAgICAgICAgICBmQ29tcGxleFR5cGVEZWNscyA9IHJlc2l6ZShmQ29tcGxleFR5cGVEZWNscywgZkNUQ291bnQpOwotICAgICAgICAgICAgZkNUTG9jYXRvcnMgPSByZXNpemUoZkNUTG9jYXRvcnMsIGZDVENvdW50KTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZkNUTG9jYXRvcnM7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogZ2V0IGFsbCByZWRlZmluZWQgZ3JvdXBzOiBmb3IgbGF0ZXIgY29uc3RyYWludCBjaGVja2luZwotICAgICAqLwotICAgIGZpbmFsIFhTR3JvdXBEZWNsW10gZ2V0UmVkZWZpbmVkR3JvdXBEZWNscygpIHsKLSAgICAgICAgaWYgKGZSR0NvdW50IDwgZlJlZGVmaW5lZEdyb3VwRGVjbHMubGVuZ3RoKSB7Ci0gICAgICAgICAgICBmUmVkZWZpbmVkR3JvdXBEZWNscyA9IHJlc2l6ZShmUmVkZWZpbmVkR3JvdXBEZWNscywgZlJHQ291bnQpOwotICAgICAgICAgICAgZlJHTG9jYXRvcnMgPSByZXNpemUoZlJHTG9jYXRvcnMsIGZSR0NvdW50LzIpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmUmVkZWZpbmVkR3JvdXBEZWNsczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBnZXQgdGhlIGVycm9yIGxvY2F0b3Igb2YgYWxsIHJlZGVmaW5lZCBncm91cHMKLSAgICAgKi8KLSAgICBmaW5hbCBTaW1wbGVMb2NhdG9yW10gZ2V0UkdMb2NhdG9ycygpIHsKLSAgICAgICAgaWYgKGZSR0NvdW50IDwgZlJlZGVmaW5lZEdyb3VwRGVjbHMubGVuZ3RoKSB7Ci0gICAgICAgICAgICBmUmVkZWZpbmVkR3JvdXBEZWNscyA9IHJlc2l6ZShmUmVkZWZpbmVkR3JvdXBEZWNscywgZlJHQ291bnQpOwotICAgICAgICAgICAgZlJHTG9jYXRvcnMgPSByZXNpemUoZlJHTG9jYXRvcnMsIGZSR0NvdW50LzIpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmUkdMb2NhdG9yczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBhZnRlciB0aGUgZmlyc3Qtcm91bmQgY2hlY2tpbmcsIHNvbWUgdHlwZXMgZG9uJ3QgbmVlZCB0byBiZSBjaGVja2VkCi0gICAgICogYWdhaW5zdCBVUEEgYWdhaW4uIGhlcmUgd2UgdHJpbSB0aGUgYXJyYXkgdG8gdGhlIHByb3BlciBzaXplLgotICAgICAqLwotICAgIGZpbmFsIHZvaWQgc2V0VW5jaGVja2VkVHlwZU51bShpbnQgbmV3U2l6ZSkgewotICAgICAgICBmQ1RDb3VudCA9IG5ld1NpemU7Ci0gICAgICAgIGZDb21wbGV4VHlwZURlY2xzID0gcmVzaXplKGZDb21wbGV4VHlwZURlY2xzLCBmQ1RDb3VudCk7Ci0gICAgICAgIGZDVExvY2F0b3JzID0gcmVzaXplKGZDVExvY2F0b3JzLCBmQ1RDb3VudCk7Ci0gICAgfQotCi0gICAgLy8gdXNlZCB0byBzdG9yZSBhbGwgc3Vic3RpdHV0aW9uIGdyb3VwIGluZm9ybWF0aW9uIGRlY2xhcmVkIGluCi0gICAgLy8gdGhpcyBuYW1lc3BhY2UKLSAgICBwcml2YXRlIGludCBmU3ViR3JvdXBDb3VudCA9IDA7Ci0gICAgcHJpdmF0ZSBYU0VsZW1lbnREZWNsW10gZlN1Ykdyb3VwcyA9IG5ldyBYU0VsZW1lbnREZWNsW0lOSVRJQUxfU0laRV07Ci0KLSAgICAvKioKLSAgICAgKiBnZXQgYWxsIHN1YnN0aXR1dGlvbiBncm91cCBpbmZvcm1hdGlvbjogZm9yIHRoZSAzIGNvbnN0cmFpbnQgY2hlY2tpbmcKLSAgICAgKi8KLSAgICBmaW5hbCBYU0VsZW1lbnREZWNsW10gZ2V0U3Vic3RpdHV0aW9uR3JvdXBzKCkgewotICAgICAgICBpZiAoZlN1Ykdyb3VwQ291bnQgPCBmU3ViR3JvdXBzLmxlbmd0aCkKLSAgICAgICAgICAgIGZTdWJHcm91cHMgPSByZXNpemUoZlN1Ykdyb3VwcywgZlN1Ykdyb3VwQ291bnQpOwotICAgICAgICByZXR1cm4gZlN1Ykdyb3VwczsKLSAgICB9Ci0KLSAgICAvLyBhbnlUeXBlIGFuZCBhbnlTaW1wbGVUeXBlOiBiZWNhdXNlIHRoZXJlIGFyZSBzbyBtYW55IHBsYWNlcyB3aGVyZQotICAgIC8vIHdlIG5lZWQgZGlyZWN0IGFjY2VzcyB0byB0aGVzZSB0d28gdHlwZXMKLSAgICBwdWJsaWMgZmluYWwgc3RhdGljIFhTQ29tcGxleFR5cGVEZWNsIGZBbnlUeXBlID0gbmV3IFhTQW55VHlwZSgpOwotICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIFhTQW55VHlwZSBleHRlbmRzIFhTQ29tcGxleFR5cGVEZWNsIHsKLSAgICAgICAgcHVibGljIFhTQW55VHlwZSAoKSB7Ci0gICAgICAgICAgICBmTmFtZSA9IFNjaGVtYVN5bWJvbHMuQVRUVkFMX0FOWVRZUEU7Ci0gICAgICAgICAgICBzdXBlci5mVGFyZ2V0TmFtZXNwYWNlID0gU2NoZW1hU3ltYm9scy5VUklfU0NIRU1BRk9SU0NIRU1BOwotICAgICAgICAgICAgZkJhc2VUeXBlID0gdGhpczsKLSAgICAgICAgICAgIGZEZXJpdmVkQnkgPSBYU0NvbnN0YW50cy5ERVJJVkFUSU9OX1JFU1RSSUNUSU9OOwotICAgICAgICAgICAgZkNvbnRlbnRUeXBlID0gWFNDb21wbGV4VHlwZURlY2wuQ09OVEVOVFRZUEVfTUlYRUQ7Ci0KLSAgICAgICAgICAgIGZQYXJ0aWNsZSA9IG51bGw7Ci0gICAgICAgICAgICBmQXR0ckdycCA9IG51bGw7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBvdmVycmlkZGVuIG1ldGhvZHMKLSAgICAgICAgcHVibGljIHZvaWQgc2V0VmFsdWVzKFN0cmluZyBuYW1lLCBTdHJpbmcgdGFyZ2V0TmFtZXNwYWNlLAotICAgICAgICAgICAgICAgIFhTVHlwZURlZmluaXRpb24gYmFzZVR5cGUsIHNob3J0IGRlcml2ZWRCeSwgc2hvcnQgc2NoZW1hRmluYWwsCi0gICAgICAgICAgICAgICAgc2hvcnQgYmxvY2ssIHNob3J0IGNvbnRlbnRUeXBlLAotICAgICAgICAgICAgICAgIGJvb2xlYW4gaXNBYnN0cmFjdCwgWFNBdHRyaWJ1dGVHcm91cERlY2wgYXR0ckdycCwKLSAgICAgICAgICAgICAgICBYU1NpbXBsZVR5cGUgc2ltcGxlVHlwZSwgWFNQYXJ0aWNsZURlY2wgcGFydGljbGUpIHsKLSAgICAgICAgICAgIC8vIGRvbid0IGFsbG93IHRoaXMuCi0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCBzZXROYW1lKFN0cmluZyBuYW1lKXsKLSAgICAgICAgICAgIC8vIGRvbid0IGFsbG93IHRoaXMuCi0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCBzZXRJc0Fic3RyYWN0VHlwZSgpIHsKLSAgICAgICAgICAgIC8vIG51bGwgaW1wbGVtZW50YXRpb24KLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyB2b2lkIHNldENvbnRhaW5zVHlwZUlEKCkgewotICAgICAgICAgICAgLy8gbnVsbCBpbXBsZW1lbnRhdGlvbgotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIHZvaWQgc2V0SXNBbm9ueW1vdXMoKSB7Ci0gICAgICAgICAgICAvLyBudWxsIGltcGxlbWVudGF0aW9uCi0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCByZXNldCgpIHsKLSAgICAgICAgICAgIC8vIG51bGwgaW1wbGVtZW50YXRpb24KLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyBYU09iamVjdExpc3QgZ2V0QXR0cmlidXRlVXNlcygpIHsKLSAgICAgICAgICAgIHJldHVybiBYU09iamVjdExpc3RJbXBsLkVNUFRZX0xJU1Q7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgWFNBdHRyaWJ1dGVHcm91cERlY2wgZ2V0QXR0ckdycCgpIHsKLSAgICAgICAgICAgIFhTV2lsZGNhcmREZWNsIHdpbGRjYXJkID0gbmV3IFhTV2lsZGNhcmREZWNsKCk7Ci0gICAgICAgICAgICB3aWxkY2FyZC5mUHJvY2Vzc0NvbnRlbnRzID0gWFNXaWxkY2FyZERlY2wuUENfTEFYOwotICAgICAgICAgICAgWFNBdHRyaWJ1dGVHcm91cERlY2wgYXR0ckdycCA9IG5ldyBYU0F0dHJpYnV0ZUdyb3VwRGVjbCgpOwotICAgICAgICAgICAgYXR0ckdycC5mQXR0cmlidXRlV0MgPSB3aWxkY2FyZDsKLSAgICAgICAgICAgIHJldHVybiBhdHRyR3JwOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIFhTV2lsZGNhcmQgZ2V0QXR0cmlidXRlV2lsZGNhcmQoKSB7Ci0gICAgICAgICAgICBYU1dpbGRjYXJkRGVjbCB3aWxkY2FyZCA9IG5ldyBYU1dpbGRjYXJkRGVjbCgpOwotICAgICAgICAgICAgd2lsZGNhcmQuZlByb2Nlc3NDb250ZW50cyA9IFhTV2lsZGNhcmREZWNsLlBDX0xBWDsKLSAgICAgICAgICAgIHJldHVybiB3aWxkY2FyZDsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyBYU1BhcnRpY2xlIGdldFBhcnRpY2xlKCkgewotICAgICAgICAgICAgLy8gdGhlIHdpbGRjYXJkIHVzZWQgaW4gYW55VHlwZSAoY29udGVudCBhbmQgYXR0cmlidXRlKQotICAgICAgICAgICAgLy8gdGhlIHNwZWMgd2lsbCBjaGFuZ2Ugc3RyaWN0IHRvIHNraXAgZm9yIGFueVR5cGUKLSAgICAgICAgICAgIFhTV2lsZGNhcmREZWNsIHdpbGRjYXJkID0gbmV3IFhTV2lsZGNhcmREZWNsKCk7Ci0gICAgICAgICAgICB3aWxkY2FyZC5mUHJvY2Vzc0NvbnRlbnRzID0gWFNXaWxkY2FyZERlY2wuUENfTEFYOwotICAgICAgICAgICAgLy8gdGhlIHBhcnRpY2xlIGZvciB0aGUgY29udGVudCB3aWxkY2FyZAotICAgICAgICAgICAgWFNQYXJ0aWNsZURlY2wgcGFydGljbGVXID0gbmV3IFhTUGFydGljbGVEZWNsKCk7Ci0gICAgICAgICAgICBwYXJ0aWNsZVcuZk1pbk9jY3VycyA9IDA7Ci0gICAgICAgICAgICBwYXJ0aWNsZVcuZk1heE9jY3VycyA9IFNjaGVtYVN5bWJvbHMuT0NDVVJSRU5DRV9VTkJPVU5ERUQ7Ci0gICAgICAgICAgICBwYXJ0aWNsZVcuZlR5cGUgPSBYU1BhcnRpY2xlRGVjbC5QQVJUSUNMRV9XSUxEQ0FSRDsKLSAgICAgICAgICAgIHBhcnRpY2xlVy5mVmFsdWUgPSB3aWxkY2FyZDsKLSAgICAgICAgICAgIC8vIHRoZSBtb2RlbCBncm91cCBvZiBhIHNlcXVlbmNlIG9mIHRoZSBhYm92ZSBwYXJ0aWNsZQotICAgICAgICAgICAgWFNNb2RlbEdyb3VwSW1wbCBncm91cCA9IG5ldyBYU01vZGVsR3JvdXBJbXBsKCk7Ci0gICAgICAgICAgICBncm91cC5mQ29tcG9zaXRvciA9IFhTTW9kZWxHcm91cEltcGwuTU9ERUxHUk9VUF9TRVFVRU5DRTsKLSAgICAgICAgICAgIGdyb3VwLmZQYXJ0aWNsZUNvdW50ID0gMTsKLSAgICAgICAgICAgIGdyb3VwLmZQYXJ0aWNsZXMgPSBuZXcgWFNQYXJ0aWNsZURlY2xbMV07Ci0gICAgICAgICAgICBncm91cC5mUGFydGljbGVzWzBdID0gcGFydGljbGVXOwotICAgICAgICAgICAgLy8gdGhlIGNvbnRlbnQgb2YgYW55VHlwZTogcGFydGljbGUgb2YgdGhlIGFib3ZlIG1vZGVsIGdyb3VwCi0gICAgICAgICAgICBYU1BhcnRpY2xlRGVjbCBwYXJ0aWNsZUcgPSBuZXcgWFNQYXJ0aWNsZURlY2woKTsKLSAgICAgICAgICAgIHBhcnRpY2xlRy5mVHlwZSA9IFhTUGFydGljbGVEZWNsLlBBUlRJQ0xFX01PREVMR1JPVVA7Ci0gICAgICAgICAgICBwYXJ0aWNsZUcuZlZhbHVlID0gZ3JvdXA7Ci0KLSAgICAgICAgICAgIHJldHVybiBwYXJ0aWNsZUc7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgWFNPYmplY3RMaXN0IGdldEFubm90YXRpb25zKCkgewotICAgICAgICAgICAgcmV0dXJuIFhTT2JqZWN0TGlzdEltcGwuRU1QVFlfTElTVDsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyBYU05hbWVzcGFjZUl0ZW0gZ2V0TmFtZXNwYWNlSXRlbSgpIHsKLSAgICAgICAgICAgIHJldHVybiBTR19TY2hlbWFOUzsKLSAgICAgICAgfQotICAgIH0KLSAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBCdWlsdGluQXR0ckRlY2wgZXh0ZW5kcyBYU0F0dHJpYnV0ZURlY2wgewotICAgICAgICBwdWJsaWMgQnVpbHRpbkF0dHJEZWNsKFN0cmluZyBuYW1lLCBTdHJpbmcgdG5zLAotICAgICAgICAgICAgICAgIFhTU2ltcGxlVHlwZSB0eXBlLCBzaG9ydCBzY29wZSkgewotICAgICAgICAgICAgZk5hbWUgPSBuYW1lOwotICAgICAgICAgICAgc3VwZXIuZlRhcmdldE5hbWVzcGFjZSA9IHRuczsKLSAgICAgICAgICAgIGZUeXBlID0gdHlwZTsKLSAgICAgICAgICAgIGZTY29wZSA9IHNjb3BlOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIHZvaWQgc2V0VmFsdWVzKFN0cmluZyBuYW1lLCBTdHJpbmcgdGFyZ2V0TmFtZXNwYWNlLAotICAgICAgICAgICAgICAgIFhTU2ltcGxlVHlwZSBzaW1wbGVUeXBlLCBzaG9ydCBjb25zdHJhaW50VHlwZSwgc2hvcnQgc2NvcGUsCi0gICAgICAgICAgICAgICAgVmFsaWRhdGVkSW5mbyB2YWxJbmZvLCBYU0NvbXBsZXhUeXBlRGVjbCBlbmNsb3NpbmdDVCkgewotICAgICAgICAgICAgLy8gaWdub3JlIHRoaXMgY2FsbC4KLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyB2b2lkIHJlc2V0ICgpIHsKLSAgICAgICAgICAgIC8vIGFsc28gaWdub3JlIHRoaXMgY2FsbC4KLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyBYU0Fubm90YXRpb24gZ2V0QW5ub3RhdGlvbigpIHsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIFhTTmFtZXNwYWNlSXRlbSBnZXROYW1lc3BhY2VJdGVtKCkgewotICAgICAgICAgICAgcmV0dXJuIFNHX1hTSTsKLSAgICAgICAgfQotCi0gICAgfSAvLyBjbGFzcyBCdWlsdGluQXR0ckRlY2wKLQotICAgIC8vIHRoZSBncmFtbWFycyB0byBob2xkIGNvbXBvbmVudHMgb2YgdGhlIHNjaGVtYSBuYW1lc3BhY2UKLSAgICBwdWJsaWMgZmluYWwgc3RhdGljIEJ1aWx0aW5TY2hlbWFHcmFtbWFyIFNHX1NjaGVtYU5TID0gbmV3IEJ1aWx0aW5TY2hlbWFHcmFtbWFyKEdSQU1NQVJfWFMsIENvbnN0YW50cy5TQ0hFTUFfVkVSU0lPTl8xXzApOwotICAgIHByaXZhdGUgZmluYWwgc3RhdGljIEJ1aWx0aW5TY2hlbWFHcmFtbWFyIFNHX1NjaGVtYU5TRXh0ZW5kZWQgPSBuZXcgQnVpbHRpblNjaGVtYUdyYW1tYXIoR1JBTU1BUl9YUywgQ29uc3RhbnRzLlNDSEVNQV9WRVJTSU9OXzFfMF9FWFRFTkRFRCk7Ci0KLSAgICBwdWJsaWMgZmluYWwgc3RhdGljIFhTU2ltcGxlVHlwZSBmQW55U2ltcGxlVHlwZSA9IChYU1NpbXBsZVR5cGUpU0dfU2NoZW1hTlMuZ2V0R2xvYmFsVHlwZURlY2woU2NoZW1hU3ltYm9scy5BVFRWQUxfQU5ZU0lNUExFVFlQRSk7Ci0KLSAgICAvLyB0aGUgZ3JhbW1hcnMgdG8gaG9sZCBjb21wb25lbnRzIG9mIHRoZSBzY2hlbWEtaW5zdGFuY2UgbmFtZXNwYWNlCi0gICAgcHVibGljIGZpbmFsIHN0YXRpYyBCdWlsdGluU2NoZW1hR3JhbW1hciBTR19YU0kgPSBuZXcgQnVpbHRpblNjaGVtYUdyYW1tYXIoR1JBTU1BUl9YU0ksIENvbnN0YW50cy5TQ0hFTUFfVkVSU0lPTl8xXzApOwotCi0gICAgcHVibGljIHN0YXRpYyBTY2hlbWFHcmFtbWFyIGdldFM0U0dyYW1tYXIoc2hvcnQgc2NoZW1hVmVyc2lvbikgewotICAgICAgICBpZiAoc2NoZW1hVmVyc2lvbiA9PSBDb25zdGFudHMuU0NIRU1BX1ZFUlNJT05fMV8wKSB7Ci0gICAgICAgICAgICByZXR1cm4gU0dfU2NoZW1hTlM7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gU0dfU2NoZW1hTlNFeHRlbmRlZDsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHN0YXRpYyBmaW5hbCBYU0NvbXBsZXhUeXBlRGVjbFtdIHJlc2l6ZShYU0NvbXBsZXhUeXBlRGVjbFtdIG9sZEFycmF5LCBpbnQgbmV3U2l6ZSkgewotICAgICAgICBYU0NvbXBsZXhUeXBlRGVjbFtdIG5ld0FycmF5ID0gbmV3IFhTQ29tcGxleFR5cGVEZWNsW25ld1NpemVdOwotICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KG9sZEFycmF5LCAwLCBuZXdBcnJheSwgMCwgTWF0aC5taW4ob2xkQXJyYXkubGVuZ3RoLCBuZXdTaXplKSk7Ci0gICAgICAgIHJldHVybiBuZXdBcnJheTsKLSAgICB9Ci0KLSAgICBzdGF0aWMgZmluYWwgWFNHcm91cERlY2xbXSByZXNpemUoWFNHcm91cERlY2xbXSBvbGRBcnJheSwgaW50IG5ld1NpemUpIHsKLSAgICAgICAgWFNHcm91cERlY2xbXSBuZXdBcnJheSA9IG5ldyBYU0dyb3VwRGVjbFtuZXdTaXplXTsKLSAgICAgICAgU3lzdGVtLmFycmF5Y29weShvbGRBcnJheSwgMCwgbmV3QXJyYXksIDAsIE1hdGgubWluKG9sZEFycmF5Lmxlbmd0aCwgbmV3U2l6ZSkpOwotICAgICAgICByZXR1cm4gbmV3QXJyYXk7Ci0gICAgfQotCi0gICAgc3RhdGljIGZpbmFsIFhTRWxlbWVudERlY2xbXSByZXNpemUoWFNFbGVtZW50RGVjbFtdIG9sZEFycmF5LCBpbnQgbmV3U2l6ZSkgewotICAgICAgICBYU0VsZW1lbnREZWNsW10gbmV3QXJyYXkgPSBuZXcgWFNFbGVtZW50RGVjbFtuZXdTaXplXTsKLSAgICAgICAgU3lzdGVtLmFycmF5Y29weShvbGRBcnJheSwgMCwgbmV3QXJyYXksIDAsIE1hdGgubWluKG9sZEFycmF5Lmxlbmd0aCwgbmV3U2l6ZSkpOwotICAgICAgICByZXR1cm4gbmV3QXJyYXk7Ci0gICAgfQotCi0gICAgc3RhdGljIGZpbmFsIFNpbXBsZUxvY2F0b3JbXSByZXNpemUoU2ltcGxlTG9jYXRvcltdIG9sZEFycmF5LCBpbnQgbmV3U2l6ZSkgewotICAgICAgICBTaW1wbGVMb2NhdG9yW10gbmV3QXJyYXkgPSBuZXcgU2ltcGxlTG9jYXRvcltuZXdTaXplXTsKLSAgICAgICAgU3lzdGVtLmFycmF5Y29weShvbGRBcnJheSwgMCwgbmV3QXJyYXksIDAsIE1hdGgubWluKG9sZEFycmF5Lmxlbmd0aCwgbmV3U2l6ZSkpOwotICAgICAgICByZXR1cm4gbmV3QXJyYXk7Ci0gICAgfQotCi0gICAgLy8gWFNOYW1lc3BhY2VJdGVtIG1ldGhvZHMKLQotICAgIC8vIHRoZSBtYXggaW5kZXggLyB0aGUgbWF4IHZhbHVlIG9mIFhTT2JqZWN0IHR5cGUKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBzaG9ydCBNQVhfQ09NUF9JRFggPSBYU1R5cGVEZWZpbml0aW9uLlNJTVBMRV9UWVBFOwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW5bXSBHTE9CQUxfQ09NUCA9IHtmYWxzZSwgICAgLy8gbnVsbAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlLCAgICAgLy8gYXR0cmlidXRlCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUsICAgICAvLyBlbGVtZW50Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUsICAgICAvLyB0eXBlCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlLCAgICAvLyBhdHRyaWJ1dGUgdXNlCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUsICAgICAvLyBhdHRyaWJ1dGUgZ3JvdXAKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ1ZSwgICAgIC8vIGdyb3VwCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlLCAgICAvLyBtb2RlbCBncm91cAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSwgICAgLy8gcGFydGljbGUKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UsICAgIC8vIHdpbGRjYXJkCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlLCAgICAvLyBpZGMKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ1ZSwgICAgIC8vIG5vdGF0aW9uCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlLCAgICAvLyBhbm5vdGF0aW9uCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlLCAgICAvLyBmYWNldAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSwgICAgLy8gbXVsdGkgdmFsdWUgZmFjZXQKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ1ZSwgICAgIC8vIGNvbXBsZXggdHlwZQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlICAgICAgLy8gc2ltcGxlIHR5cGUKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9OwotCi0gICAgLy8gc3RvcmUgYSBjZXJ0YWluIGtpbmQgb2YgY29tcG9uZW50cyBmcm9tIGFsbCBuYW1lc3BhY2VzCi0gICAgcHJpdmF0ZSBYU05hbWVkTWFwW10gZkNvbXBvbmVudHMgPSBudWxsOwotICAgIHByaXZhdGUgT2JqZWN0TGlzdFtdIGZDb21wb25lbnRzRXh0ID0gbnVsbDsKLQotICAgIC8vIHN0b3JlIHRoZSBkb2N1bWVudHMgYW5kIHRoZWlyIGxvY2F0aW9ucyBjb250cmlidXRpbmcgdG8gdGhpcyBuYW1lc3BhY2UKLSAgICAvLyBSRVZJU0lUOiB1c2UgU3RyaW5nTGlzdCBhbmQgWFNPYmplY3RMaXN0IGZvciB0aGVyZSBmaWVsZHMuCi0gICAgcHJpdmF0ZSBWZWN0b3IgZkRvY3VtZW50cyA9IG51bGw7Ci0gICAgcHJpdmF0ZSBWZWN0b3IgZkxvY2F0aW9ucyA9IG51bGw7Ci0KLSAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgYWRkRG9jdW1lbnQoT2JqZWN0IGRvY3VtZW50LCBTdHJpbmcgbG9jYXRpb24pIHsKLSAgICAgICAgaWYgKGZEb2N1bWVudHMgPT0gbnVsbCkgewotICAgICAgICAgICAgZkRvY3VtZW50cyA9IG5ldyBWZWN0b3IoKTsKLSAgICAgICAgICAgIGZMb2NhdGlvbnMgPSBuZXcgVmVjdG9yKCk7Ci0gICAgICAgIH0KLSAgICAgICAgZkRvY3VtZW50cy5hZGRFbGVtZW50KGRvY3VtZW50KTsKLSAgICAgICAgZkxvY2F0aW9ucy5hZGRFbGVtZW50KGxvY2F0aW9uKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgcmVtb3ZlRG9jdW1lbnQoaW50IGluZGV4KSB7Ci0gICAgICAgIGlmIChmRG9jdW1lbnRzICE9IG51bGwgJiYKLSAgICAgICAgICAgIGluZGV4ID49IDAgJiYKLSAgICAgICAgICAgIGluZGV4IDwgZkRvY3VtZW50cy5zaXplKCkpIHsKLSAgICAgICAgICAgIGZEb2N1bWVudHMucmVtb3ZlRWxlbWVudEF0KGluZGV4KTsKLSAgICAgICAgICAgIGZMb2NhdGlvbnMucmVtb3ZlRWxlbWVudEF0KGluZGV4KTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFtzY2hlbWEgbmFtZXNwYWNlXQotICAgICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveG1sc2NoZW1hLTEvI25zaS1zY2hlbWFfbmFtZXNwYWNlIj5bc2NoZW1hIG5hbWVzcGFjZV08L2E+Ci0gICAgICogQHJldHVybiBUaGUgdGFyZ2V0IG5hbWVzcGFjZSBvZiB0aGlzIGl0ZW0uCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRTY2hlbWFOYW1lc3BhY2UoKSB7Ci0gICAgICAgIHJldHVybiBmVGFyZ2V0TmFtZXNwYWNlOwotICAgIH0KLQotICAgIC8vIGFubm90YXRpb24gc3VwcG9ydAotICAgIHN5bmNocm9uaXplZCBET01QYXJzZXIgZ2V0RE9NUGFyc2VyKCkgewotICAgICAgICBpZiAoZkRPTVBhcnNlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBET01QYXJzZXIgcGFyc2VyID0gKERPTVBhcnNlcikgZkRPTVBhcnNlci5nZXQoKTsKLSAgICAgICAgICAgIGlmIChwYXJzZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJldHVybiBwYXJzZXI7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgLy8gUkVWSVNJVDogIHdoZW4gc2NoZW1hIGhhbmRsZXMgWE1MIDEuMSwgd2lsbCBuZWVkIHRvCi0gICAgICAgIC8vIHJldmlzaXQgdGhpcyAoYW5kIHRoZSBwcmFjdGljZSBvZiBub3QgcHJlcGVuZGluZyBhbiBYTUwgZGVjbCB0byB0aGUgYW5ub3RhdGlvbiBzdHJpbmcKLSAgICAgICAgWE1MMTFDb25maWd1cmF0aW9uIGNvbmZpZyA9IG5ldyBYTUwxMUNvbmZpZ3VyYXRpb24oZlN5bWJvbFRhYmxlKTsKLSAgICAgICAgLy8gbm90ZSB0aGF0IHRoaXMgc2hvdWxkIG5ldmVyIHByb2R1Y2UgZXJyb3JzIG9yIHJlcXVpcmUKLSAgICAgICAgLy8gZW50aXR5IHJlc29sdXRpb24sIHNvIGp1c3QgYSBiYXJlYm9uZXMgY29uZmlndXJhdGlvbiB3aXRoCi0gICAgICAgIC8vIGEgY291cGxlIG9mIGZlYXR1cmUgIHNldCB3aWxsIGRvIGZpbmUKLSAgICAgICAgY29uZmlnLnNldEZlYXR1cmUoQ29uc3RhbnRzLlNBWF9GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5OQU1FU1BBQ0VTX0ZFQVRVUkUsIHRydWUpOwotICAgICAgICBjb25maWcuc2V0RmVhdHVyZShDb25zdGFudHMuU0FYX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLlZBTElEQVRJT05fRkVBVFVSRSwgZmFsc2UpOwotCi0gICAgICAgIERPTVBhcnNlciBwYXJzZXIgPSBuZXcgRE9NUGFyc2VyKGNvbmZpZyk7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBwYXJzZXIuc2V0RmVhdHVyZShDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLkRFRkVSX05PREVfRVhQQU5TSU9OX0ZFQVRVUkUsIGZhbHNlKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoU0FYRXhjZXB0aW9uIGV4Yykge30KLSAgICAgICAgZkRPTVBhcnNlciA9IG5ldyBTb2Z0UmVmZXJlbmNlKHBhcnNlcik7Ci0gICAgICAgIHJldHVybiBwYXJzZXI7Ci0gICAgfQotCi0gICAgc3luY2hyb25pemVkIFNBWFBhcnNlciBnZXRTQVhQYXJzZXIoKSB7Ci0gICAgICAgIGlmIChmU0FYUGFyc2VyICE9IG51bGwpIHsKLSAgICAgICAgICAgIFNBWFBhcnNlciBwYXJzZXIgPSAoU0FYUGFyc2VyKSBmU0FYUGFyc2VyLmdldCgpOwotICAgICAgICAgICAgaWYgKHBhcnNlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHBhcnNlcjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICAvLyBSRVZJU0lUOiAgd2hlbiBzY2hlbWEgaGFuZGxlcyBYTUwgMS4xLCB3aWxsIG5lZWQgdG8KLSAgICAgICAgLy8gcmV2aXNpdCB0aGlzIChhbmQgdGhlIHByYWN0aWNlIG9mIG5vdCBwcmVwZW5kaW5nIGFuIFhNTCBkZWNsIHRvIHRoZSBhbm5vdGF0aW9uIHN0cmluZwotICAgICAgICBYTUwxMUNvbmZpZ3VyYXRpb24gY29uZmlnID0gbmV3IFhNTDExQ29uZmlndXJhdGlvbihmU3ltYm9sVGFibGUpOwotICAgICAgICAvLyBub3RlIHRoYXQgdGhpcyBzaG91bGQgbmV2ZXIgcHJvZHVjZSBlcnJvcnMgb3IgcmVxdWlyZQotICAgICAgICAvLyBlbnRpdHkgcmVzb2x1dGlvbiwgc28ganVzdCBhIGJhcmVib25lcyBjb25maWd1cmF0aW9uIHdpdGgKLSAgICAgICAgLy8gYSBjb3VwbGUgb2YgZmVhdHVyZSAgc2V0IHdpbGwgZG8gZmluZQotICAgICAgICBjb25maWcuc2V0RmVhdHVyZShDb25zdGFudHMuU0FYX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLk5BTUVTUEFDRVNfRkVBVFVSRSwgdHJ1ZSk7Ci0gICAgICAgIGNvbmZpZy5zZXRGZWF0dXJlKENvbnN0YW50cy5TQVhfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuVkFMSURBVElPTl9GRUFUVVJFLCBmYWxzZSk7Ci0gICAgICAgIFNBWFBhcnNlciBwYXJzZXIgPSBuZXcgU0FYUGFyc2VyKGNvbmZpZyk7Ci0gICAgICAgIGZTQVhQYXJzZXIgPSBuZXcgU29mdFJlZmVyZW5jZShwYXJzZXIpOwotICAgICAgICByZXR1cm4gcGFyc2VyOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFtzY2hlbWEgY29tcG9uZW50c106IGEgbGlzdCBvZiB0b3AtbGV2ZWwgY29tcG9uZW50cywgaS5lLiBlbGVtZW50Ci0gICAgICogZGVjbGFyYXRpb25zLCBhdHRyaWJ1dGUgZGVjbGFyYXRpb25zLCBldGMuCi0gICAgICogQHBhcmFtIG9iamVjdFR5cGUgVGhlIHR5cGUgb2YgdGhlIGRlY2xhcmF0aW9uLCBpLmUuCi0gICAgICogICA8Y29kZT5FTEVNRU5UX0RFQ0xBUkFUSU9OPC9jb2RlPi4gTm90ZSB0aGF0Ci0gICAgICogICA8Y29kZT5YU1R5cGVEZWZpbml0aW9uLlNJTVBMRV9UWVBFPC9jb2RlPiBhbmQKLSAgICAgKiAgIDxjb2RlPlhTVHlwZURlZmluaXRpb24uQ09NUExFWF9UWVBFPC9jb2RlPiBjYW4gYWxzbyBiZSB1c2VkIGFzIHRoZQotICAgICAqICAgPGNvZGU+b2JqZWN0VHlwZTwvY29kZT4gdG8gcmV0cmlldmUgb25seSBjb21wbGV4IHR5cGVzIG9yIHNpbXBsZQotICAgICAqICAgdHlwZXMsIGluc3RlYWQgb2YgYWxsIHR5cGVzLgotICAgICAqIEByZXR1cm4gIEEgbGlzdCBvZiB0b3AtbGV2ZWwgZGVmaW5pdGlvbiBvZiB0aGUgc3BlY2lmaWVkIHR5cGUgaW4KLSAgICAgKiAgIDxjb2RlPm9iamVjdFR5cGU8L2NvZGU+IG9yIGFuIGVtcHR5IDxjb2RlPlhTTmFtZWRNYXA8L2NvZGU+IGlmIG5vCi0gICAgICogICBzdWNoIGRlZmluaXRpb25zIGV4aXN0LgotICAgICAqLwotICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgWFNOYW1lZE1hcCBnZXRDb21wb25lbnRzKHNob3J0IG9iamVjdFR5cGUpIHsKLSAgICAgICAgaWYgKG9iamVjdFR5cGUgPD0gMCB8fCBvYmplY3RUeXBlID4gTUFYX0NPTVBfSURYIHx8Ci0gICAgICAgICAgICAhR0xPQkFMX0NPTVBbb2JqZWN0VHlwZV0pIHsKLSAgICAgICAgICAgIHJldHVybiBYU05hbWVkTWFwSW1wbC5FTVBUWV9NQVA7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoZkNvbXBvbmVudHMgPT0gbnVsbCkKLSAgICAgICAgICAgIGZDb21wb25lbnRzID0gbmV3IFhTTmFtZWRNYXBbTUFYX0NPTVBfSURYKzFdOwotCi0gICAgICAgIC8vIGdldCB0aGUgaGFzaHRhYmxlIGZvciB0aGlzIHR5cGUgb2YgY29tcG9uZW50cwotICAgICAgICBpZiAoZkNvbXBvbmVudHNbb2JqZWN0VHlwZV0gPT0gbnVsbCkgewotICAgICAgICAgICAgU3ltYm9sSGFzaCB0YWJsZSA9IG51bGw7Ci0gICAgICAgICAgICBzd2l0Y2ggKG9iamVjdFR5cGUpIHsKLSAgICAgICAgICAgIGNhc2UgWFNDb25zdGFudHMuVFlQRV9ERUZJTklUSU9OOgotICAgICAgICAgICAgY2FzZSBYU1R5cGVEZWZpbml0aW9uLkNPTVBMRVhfVFlQRToKLSAgICAgICAgICAgIGNhc2UgWFNUeXBlRGVmaW5pdGlvbi5TSU1QTEVfVFlQRToKLSAgICAgICAgICAgICAgICB0YWJsZSA9IGZHbG9iYWxUeXBlRGVjbHM7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICBjYXNlIFhTQ29uc3RhbnRzLkFUVFJJQlVURV9ERUNMQVJBVElPTjoKLSAgICAgICAgICAgICAgICB0YWJsZSA9IGZHbG9iYWxBdHRyRGVjbHM7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICBjYXNlIFhTQ29uc3RhbnRzLkVMRU1FTlRfREVDTEFSQVRJT046Ci0gICAgICAgICAgICAgICAgdGFibGUgPSBmR2xvYmFsRWxlbURlY2xzOwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgY2FzZSBYU0NvbnN0YW50cy5BVFRSSUJVVEVfR1JPVVA6Ci0gICAgICAgICAgICAgICAgdGFibGUgPSBmR2xvYmFsQXR0ckdycERlY2xzOwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgY2FzZSBYU0NvbnN0YW50cy5NT0RFTF9HUk9VUF9ERUZJTklUSU9OOgotICAgICAgICAgICAgICAgIHRhYmxlID0gZkdsb2JhbEdyb3VwRGVjbHM7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICBjYXNlIFhTQ29uc3RhbnRzLk5PVEFUSU9OX0RFQ0xBUkFUSU9OOgotICAgICAgICAgICAgICAgIHRhYmxlID0gZkdsb2JhbE5vdGF0aW9uRGVjbHM7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIGZvciBjb21wbGV4L3NpbXBsZSB0eXBlcywgY3JlYXRlIGEgc3BlY2lhbCBpbXBsZW1lbnRhdGlvbiwKLSAgICAgICAgICAgIC8vIHdoaWNoIHRha2Ugc3BlY2lmaWMgdHlwZXMgb3V0IG9mIHRoZSBoYXNoIHRhYmxlCi0gICAgICAgICAgICBpZiAob2JqZWN0VHlwZSA9PSBYU1R5cGVEZWZpbml0aW9uLkNPTVBMRVhfVFlQRSB8fAotICAgICAgICAgICAgICAgIG9iamVjdFR5cGUgPT0gWFNUeXBlRGVmaW5pdGlvbi5TSU1QTEVfVFlQRSkgewotICAgICAgICAgICAgICAgIGZDb21wb25lbnRzW29iamVjdFR5cGVdID0gbmV3IFhTTmFtZWRNYXA0VHlwZXMoZlRhcmdldE5hbWVzcGFjZSwgdGFibGUsIG9iamVjdFR5cGUpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgZkNvbXBvbmVudHNbb2JqZWN0VHlwZV0gPSBuZXcgWFNOYW1lZE1hcEltcGwoZlRhcmdldE5hbWVzcGFjZSwgdGFibGUpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIGZDb21wb25lbnRzW29iamVjdFR5cGVdOwotICAgIH0KLQotICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgT2JqZWN0TGlzdCBnZXRDb21wb25lbnRzRXh0KHNob3J0IG9iamVjdFR5cGUpIHsKLSAgICAgICAgaWYgKG9iamVjdFR5cGUgPD0gMCB8fCBvYmplY3RUeXBlID4gTUFYX0NPTVBfSURYIHx8Ci0gICAgICAgICAgICAhR0xPQkFMX0NPTVBbb2JqZWN0VHlwZV0pIHsKLSAgICAgICAgICAgIHJldHVybiBPYmplY3RMaXN0SW1wbC5FTVBUWV9MSVNUOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKGZDb21wb25lbnRzRXh0ID09IG51bGwpCi0gICAgICAgICAgICBmQ29tcG9uZW50c0V4dCA9IG5ldyBPYmplY3RMaXN0W01BWF9DT01QX0lEWCsxXTsKLQotICAgICAgICAvLyBnZXQgdGhlIGhhc2h0YWJsZSBmb3IgdGhpcyB0eXBlIG9mIGNvbXBvbmVudHMKLSAgICAgICAgaWYgKGZDb21wb25lbnRzRXh0W29iamVjdFR5cGVdID09IG51bGwpIHsKLSAgICAgICAgICAgIFN5bWJvbEhhc2ggdGFibGUgPSBudWxsOwotICAgICAgICAgICAgc3dpdGNoIChvYmplY3RUeXBlKSB7Ci0gICAgICAgICAgICBjYXNlIFhTQ29uc3RhbnRzLlRZUEVfREVGSU5JVElPTjoKLSAgICAgICAgICAgIGNhc2UgWFNUeXBlRGVmaW5pdGlvbi5DT01QTEVYX1RZUEU6Ci0gICAgICAgICAgICBjYXNlIFhTVHlwZURlZmluaXRpb24uU0lNUExFX1RZUEU6Ci0gICAgICAgICAgICAgICAgdGFibGUgPSBmR2xvYmFsVHlwZURlY2xzRXh0OwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgY2FzZSBYU0NvbnN0YW50cy5BVFRSSUJVVEVfREVDTEFSQVRJT046Ci0gICAgICAgICAgICAgICAgdGFibGUgPSBmR2xvYmFsQXR0ckRlY2xzRXh0OwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgY2FzZSBYU0NvbnN0YW50cy5FTEVNRU5UX0RFQ0xBUkFUSU9OOgotICAgICAgICAgICAgICAgIHRhYmxlID0gZkdsb2JhbEVsZW1EZWNsc0V4dDsKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIGNhc2UgWFNDb25zdGFudHMuQVRUUklCVVRFX0dST1VQOgotICAgICAgICAgICAgICAgIHRhYmxlID0gZkdsb2JhbEF0dHJHcnBEZWNsc0V4dDsKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIGNhc2UgWFNDb25zdGFudHMuTU9ERUxfR1JPVVBfREVGSU5JVElPTjoKLSAgICAgICAgICAgICAgICB0YWJsZSA9IGZHbG9iYWxHcm91cERlY2xzRXh0OwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgY2FzZSBYU0NvbnN0YW50cy5OT1RBVElPTl9ERUNMQVJBVElPTjoKLSAgICAgICAgICAgICAgICB0YWJsZSA9IGZHbG9iYWxOb3RhdGlvbkRlY2xzRXh0OwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBPYmplY3RbXSBlbnRyaWVzID0gdGFibGUuZ2V0RW50cmllcygpOwotICAgICAgICAgICAgZkNvbXBvbmVudHNFeHRbb2JqZWN0VHlwZV0gPSBuZXcgT2JqZWN0TGlzdEltcGwoZW50cmllcywgZW50cmllcy5sZW5ndGgpOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIGZDb21wb25lbnRzRXh0W29iamVjdFR5cGVdOwotICAgIH0KLQotICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCByZXNldENvbXBvbmVudHMoKSB7Ci0gICAgICAgIGZDb21wb25lbnRzID0gbnVsbDsKLSAgICAgICAgZkNvbXBvbmVudHNFeHQgPSBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbnZlbmllbmNlIG1ldGhvZC4gUmV0dXJucyBhIHRvcC1sZXZlbCBzaW1wbGUgb3IgY29tcGxleCB0eXBlCi0gICAgICogZGVmaW5pdGlvbi4KLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgZGVmaW5pdGlvbi4KLSAgICAgKiBAcmV0dXJuIEFuIDxjb2RlPlhTVHlwZURlZmluaXRpb248L2NvZGU+IG9yIG51bGwgaWYgc3VjaCBkZWZpbml0aW9uCi0gICAgICogICBkb2VzIG5vdCBleGlzdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFNUeXBlRGVmaW5pdGlvbiBnZXRUeXBlRGVmaW5pdGlvbihTdHJpbmcgbmFtZSkgewotICAgICAgICByZXR1cm4gZ2V0R2xvYmFsVHlwZURlY2wobmFtZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29udmVuaWVuY2UgbWV0aG9kLiBSZXR1cm5zIGEgdG9wLWxldmVsIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbi4KLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgZGVjbGFyYXRpb24uCi0gICAgICogQHJldHVybiBBIHRvcC1sZXZlbCBhdHRyaWJ1dGUgZGVjbGFyYXRpb24gb3IgbnVsbCBpZiBzdWNoIGRlY2xhcmF0aW9uCi0gICAgICogICBkb2VzIG5vdCBleGlzdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFNBdHRyaWJ1dGVEZWNsYXJhdGlvbiBnZXRBdHRyaWJ1dGVEZWNsYXJhdGlvbihTdHJpbmcgbmFtZSkgewotICAgICAgICByZXR1cm4gZ2V0R2xvYmFsQXR0cmlidXRlRGVjbChuYW1lKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb252ZW5pZW5jZSBtZXRob2QuIFJldHVybnMgYSB0b3AtbGV2ZWwgZWxlbWVudCBkZWNsYXJhdGlvbi4KLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgZGVjbGFyYXRpb24uCi0gICAgICogQHJldHVybiBBIHRvcC1sZXZlbCBlbGVtZW50IGRlY2xhcmF0aW9uIG9yIG51bGwgaWYgc3VjaCBkZWNsYXJhdGlvbgotICAgICAqICAgZG9lcyBub3QgZXhpc3QuCi0gICAgICovCi0gICAgcHVibGljIFhTRWxlbWVudERlY2xhcmF0aW9uIGdldEVsZW1lbnREZWNsYXJhdGlvbihTdHJpbmcgbmFtZSkgewotICAgICAgICByZXR1cm4gZ2V0R2xvYmFsRWxlbWVudERlY2wobmFtZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29udmVuaWVuY2UgbWV0aG9kLiBSZXR1cm5zIGEgdG9wLWxldmVsIGF0dHJpYnV0ZSBncm91cCBkZWZpbml0aW9uLgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBkZWZpbml0aW9uLgotICAgICAqIEByZXR1cm4gQSB0b3AtbGV2ZWwgYXR0cmlidXRlIGdyb3VwIGRlZmluaXRpb24gb3IgbnVsbCBpZiBzdWNoCi0gICAgICogICBkZWZpbml0aW9uIGRvZXMgbm90IGV4aXN0LgotICAgICAqLwotICAgIHB1YmxpYyBYU0F0dHJpYnV0ZUdyb3VwRGVmaW5pdGlvbiBnZXRBdHRyaWJ1dGVHcm91cChTdHJpbmcgbmFtZSkgewotICAgICAgICByZXR1cm4gZ2V0R2xvYmFsQXR0cmlidXRlR3JvdXBEZWNsKG5hbWUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbnZlbmllbmNlIG1ldGhvZC4gUmV0dXJucyBhIHRvcC1sZXZlbCBtb2RlbCBncm91cCBkZWZpbml0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgICAgICBUaGUgbmFtZSBvZiB0aGUgZGVmaW5pdGlvbi4KLSAgICAgKiBAcmV0dXJuIEEgdG9wLWxldmVsIG1vZGVsIGdyb3VwIGRlZmluaXRpb24gZGVmaW5pdGlvbiBvciBudWxsIGlmIHN1Y2gKLSAgICAgKiAgICAgICAgIGRlZmluaXRpb24gZG9lcyBub3QgZXhpc3QuCi0gICAgICovCi0gICAgcHVibGljIFhTTW9kZWxHcm91cERlZmluaXRpb24gZ2V0TW9kZWxHcm91cERlZmluaXRpb24oU3RyaW5nIG5hbWUpIHsKLSAgICAgICAgcmV0dXJuIGdldEdsb2JhbEdyb3VwRGVjbChuYW1lKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb252ZW5pZW5jZSBtZXRob2QuIFJldHVybnMgYSB0b3AtbGV2ZWwgbm90YXRpb24gZGVjbGFyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSAgICAgIFRoZSBuYW1lIG9mIHRoZSBkZWNsYXJhdGlvbi4KLSAgICAgKiBAcmV0dXJuIEEgdG9wLWxldmVsIG5vdGF0aW9uIGRlY2xhcmF0aW9uIG9yIG51bGwgaWYgc3VjaCBkZWNsYXJhdGlvbgotICAgICAqICAgICAgICAgZG9lcyBub3QgZXhpc3QuCi0gICAgICovCi0gICAgcHVibGljIFhTTm90YXRpb25EZWNsYXJhdGlvbiBnZXROb3RhdGlvbkRlY2xhcmF0aW9uKFN0cmluZyBuYW1lKSB7Ci0gICAgICAgIHJldHVybiBnZXRHbG9iYWxOb3RhdGlvbkRlY2wobmFtZSk7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBbZG9jdW1lbnQgbG9jYXRpb25dCi0gICAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94bWxzY2hlbWEtMS8jc2QtZG9jdW1lbnRfbG9jYXRpb24iPltkb2N1bWVudCBsb2NhdGlvbl08L2E+Ci0gICAgICogQHJldHVybiBhIGxpc3Qgb2YgZG9jdW1lbnQgaW5mb3JtYXRpb24gaXRlbQotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmdMaXN0IGdldERvY3VtZW50TG9jYXRpb25zKCkgewotICAgICAgICByZXR1cm4gbmV3IFN0cmluZ0xpc3RJbXBsKGZMb2NhdGlvbnMpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybiBhbiA8Y29kZT5YU01vZGVsPC9jb2RlPiB0aGF0IHJlcHJlc2VudHMgY29tcG9uZW50cyBpbiB0aGlzIHNjaGVtYQotICAgICAqIGdyYW1tYXIuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuICBhbiA8Y29kZT5YU01vZGVsPC9jb2RlPiByZXByZXNlbnRpbmcgdGhpcyBzY2hlbWEgZ3JhbW1hcgotICAgICAqLwotICAgIHB1YmxpYyBYU01vZGVsIHRvWFNNb2RlbCgpIHsKLSAgICAgICAgcmV0dXJuIG5ldyBYU01vZGVsSW1wbChuZXcgU2NoZW1hR3JhbW1hcltde3RoaXN9KTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgWFNNb2RlbCB0b1hTTW9kZWwoWFNHcmFtbWFyW10gZ3JhbW1hcnMpIHsKLSAgICAgICAgaWYgKGdyYW1tYXJzID09IG51bGwgfHwgZ3JhbW1hcnMubGVuZ3RoID09IDApCi0gICAgICAgICAgICByZXR1cm4gdG9YU01vZGVsKCk7Ci0KLSAgICAgICAgaW50IGxlbiA9IGdyYW1tYXJzLmxlbmd0aDsKLSAgICAgICAgYm9vbGVhbiBoYXNTZWxmID0gZmFsc2U7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKLSAgICAgICAgICAgIGlmIChncmFtbWFyc1tpXSA9PSB0aGlzKSB7Ci0gICAgICAgICAgICAgICAgaGFzU2VsZiA9IHRydWU7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBTY2hlbWFHcmFtbWFyW10gZ3MgPSBuZXcgU2NoZW1hR3JhbW1hcltoYXNTZWxmID8gbGVuIDogbGVuKzFdOwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbjsgaSsrKQotICAgICAgICAgICAgZ3NbaV0gPSAoU2NoZW1hR3JhbW1hcilncmFtbWFyc1tpXTsKLSAgICAgICAgaWYgKCFoYXNTZWxmKQotICAgICAgICAgICAgZ3NbbGVuXSA9IHRoaXM7Ci0gICAgICAgIHJldHVybiBuZXcgWFNNb2RlbEltcGwoZ3MpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgb3JnLmFwYWNoZS54ZXJjZXMueHMuWFNOYW1lc3BhY2VJdGVtI2dldEFubm90YXRpb25zKCkKLSAgICAgKi8KLSAgICBwdWJsaWMgWFNPYmplY3RMaXN0IGdldEFubm90YXRpb25zKCkgewotICAgICAgICBpZiAoZk51bUFubm90YXRpb25zID09IDApIHsKLSAgICAgICAgICAgIHJldHVybiBYU09iamVjdExpc3RJbXBsLkVNUFRZX0xJU1Q7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG5ldyBYU09iamVjdExpc3RJbXBsKGZBbm5vdGF0aW9ucywgZk51bUFubm90YXRpb25zKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBhZGRBbm5vdGF0aW9uKFhTQW5ub3RhdGlvbkltcGwgYW5ub3RhdGlvbikgewotICAgICAgICBpZiAoYW5ub3RhdGlvbiA9PSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGZBbm5vdGF0aW9ucyA9PSBudWxsKSB7Ci0gICAgICAgICAgICBmQW5ub3RhdGlvbnMgPSBuZXcgWFNBbm5vdGF0aW9uSW1wbFsyXTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChmTnVtQW5ub3RhdGlvbnMgPT0gZkFubm90YXRpb25zLmxlbmd0aCkgewotICAgICAgICAgICAgWFNBbm5vdGF0aW9uSW1wbFtdIG5ld0FycmF5ID0gbmV3IFhTQW5ub3RhdGlvbkltcGxbZk51bUFubm90YXRpb25zIDw8IDFdOwotICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShmQW5ub3RhdGlvbnMsIDAsIG5ld0FycmF5LCAwLCBmTnVtQW5ub3RhdGlvbnMpOwotICAgICAgICAgICAgZkFubm90YXRpb25zID0gbmV3QXJyYXk7Ci0gICAgICAgIH0KLSAgICAgICAgZkFubm90YXRpb25zW2ZOdW1Bbm5vdGF0aW9ucysrXSA9IGFubm90YXRpb247Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0SW1tdXRhYmxlKGJvb2xlYW4gaXNJbW11dGFibGUpIHsKLSAgICAgICAgZklzSW1tdXRhYmxlID0gaXNJbW11dGFibGU7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gaXNJbW11dGFibGUoKSB7Ci0gICAgICAgIHJldHVybiBmSXNJbW11dGFibGU7Ci0gICAgfQotCi19IC8vIGNsYXNzIFNjaGVtYUdyYW1tYXIKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvU2NoZW1hTmFtZXNwYWNlU3VwcG9ydC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9TY2hlbWFOYW1lc3BhY2VTdXBwb3J0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDU5MDk4NzUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9TY2hlbWFOYW1lc3BhY2VTdXBwb3J0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMTIgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMC0yMDAyLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54czsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5OYW1lc3BhY2VTdXBwb3J0OwotCi0vKioKLSAqIFRoaXMgY2xhc3MgY3VzdG9taXplcyB0aGUgYmVoYXZpb3VyIG9mIHRoZSB1dGlsLk5hbWVzcGFjZVN1cHBvcnQKLSAqIGNsYXNzIGluIG9yZGVyIHRvIGVhc2lseSBpbXBsZW1lbnQgc29tZSBmZWF0dXJlcyB0aGF0IHdlIG5lZWQgZm9yCi0gKiBlZmZpY2llbnQgc2NoZW1hIGhhbmRsaW5nLiAgSXQgd2lsbCBub3QgYmUgZ2VuZXJhbGx5IHVzZWZ1bC4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBOZWlsIEdyYWhhbSwgSUJNCi0gKgotICovCi1wdWJsaWMgY2xhc3MgU2NoZW1hTmFtZXNwYWNlU3VwcG9ydAotICAgIGV4dGVuZHMgTmFtZXNwYWNlU3VwcG9ydCB7Ci0KLSAgICBwdWJsaWMgU2NoZW1hTmFtZXNwYWNlU3VwcG9ydCAoKSB7Ci0gICAgICAgIHN1cGVyKCk7Ci0gICAgfSAvLyBjb25zdHJ1Y3RvcgotCi0gICAgLy8gbW9yZSBlZmZlY2llbnQgdGhhbiBOYW1lc3BhY2VTdXBwb3J0KE5hbWVzcGFjZUNvbnRleHQpCi0gICAgcHVibGljIFNjaGVtYU5hbWVzcGFjZVN1cHBvcnQoU2NoZW1hTmFtZXNwYWNlU3VwcG9ydCBuU3VwcG9ydCkgewotICAgICAgICBmTmFtZXNwYWNlU2l6ZSA9IG5TdXBwb3J0LmZOYW1lc3BhY2VTaXplOwotICAgICAgICBpZiAoZk5hbWVzcGFjZS5sZW5ndGggPCBmTmFtZXNwYWNlU2l6ZSkKLSAgICAgICAgICAgIGZOYW1lc3BhY2UgPSBuZXcgU3RyaW5nW2ZOYW1lc3BhY2VTaXplXTsKLSAgICAgICAgU3lzdGVtLmFycmF5Y29weShuU3VwcG9ydC5mTmFtZXNwYWNlLCAwLCBmTmFtZXNwYWNlLCAwLCBmTmFtZXNwYWNlU2l6ZSk7Ci0gICAgICAgIGZDdXJyZW50Q29udGV4dCA9IG5TdXBwb3J0LmZDdXJyZW50Q29udGV4dDsKLSAgICAgICAgaWYgKGZDb250ZXh0Lmxlbmd0aCA8PSBmQ3VycmVudENvbnRleHQpCi0gICAgICAgICAgICBmQ29udGV4dCA9IG5ldyBpbnRbZkN1cnJlbnRDb250ZXh0KzFdOwotICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KG5TdXBwb3J0LmZDb250ZXh0LCAwLCBmQ29udGV4dCwgMCwgZkN1cnJlbnRDb250ZXh0KzEpOwotICAgIH0gLy8gZW5kIGNvbnN0cnVjdG9yCi0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCB0YWtlcyBhIHNldCBvZiBTdHJpbmdzLCBhcyBzdG9yZWQgaW4gYQotICAgICAqIE5hbWVzcGFjZVN1cHBvcnQgb2JqZWN0LCBhbmQgImZvb2xzIiB0aGUgb2JqZWN0IGludG8gdGhpbmtpbmcKLSAgICAgKiB0aGF0IHRoaXMgaXMgb25lIHVuaWZpZWQgY29udGV4dC4gIFRoaXMgaXMgbWVhbnQgdG8gYmUgdXNlZCBpbgotICAgICAqIGNvbmp1bmN0aW9uIHdpdGggdGhpbmdzIGxpa2UgbG9jYWwgZWxlbWVudHMsIHdob3NlIGRlY2xhcmF0aW9ucwotICAgICAqIG1heSBiZSBkZWVwbHkgbmVzdGVkIGJ1dCB3aGljaCBmb3IgYWxsIHByYWN0aWNhbCBwdXJwb3NlcyBtYXkKLSAgICAgKiBiZSByZWdhcmRlZCBhcyBiZWluZyBvbmUgbGV2ZWwgYmVsb3cgdGhlIGdsb2JhbCA8c2NoZW1hPgotICAgICAqIGVsZW1lbnQtLWF0IGxlYXN0IHdpdGggcmVnYXJkIHRvIG5hbWVzcGFjZSBkZWNsYXJhdGlvbnMuCi0gICAgICogSXQncyB3b3J0aCBub3RpbmcgdGhhdCB0aGUgY29udGV4dCBmcm9tIHdoaWNoIHRoZSBzdHJpbmdzIGFyZQotICAgICAqIGJlaW5nIGltcG9ydGVkIGhhZCBiZXR0ZXIgYmUgdXNpbmcgdGhlIHNhbWUgU3ltYm9sVGFibGUuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RWZmZWN0aXZlQ29udGV4dCAoU3RyaW5nIFtdIG5hbWVzcGFjZURlY2xzKSB7Ci0gICAgICAgIGlmKG5hbWVzcGFjZURlY2xzID09IG51bGwgfHwgbmFtZXNwYWNlRGVjbHMubGVuZ3RoID09IDApIHJldHVybjsKLSAgICAgICAgcHVzaENvbnRleHQoKTsKLSAgICAgICAgaW50IG5ld1NpemUgPSBmTmFtZXNwYWNlU2l6ZSArIG5hbWVzcGFjZURlY2xzLmxlbmd0aDsKLSAgICAgICAgaWYgKGZOYW1lc3BhY2UubGVuZ3RoIDwgbmV3U2l6ZSkgewotICAgICAgICAgICAgLy8gZXhwYW5kIG5hbWVzcGFjZSdzIHNpemUuLi4KLSAgICAgICAgICAgIFN0cmluZ1tdIHRlbXBOU0FycmF5ID0gbmV3IFN0cmluZ1tuZXdTaXplXTsKLSAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZk5hbWVzcGFjZSwgMCwgdGVtcE5TQXJyYXksIDAsIGZOYW1lc3BhY2UubGVuZ3RoKTsKLSAgICAgICAgICAgIGZOYW1lc3BhY2UgPSB0ZW1wTlNBcnJheTsKLSAgICAgICAgfQotICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KG5hbWVzcGFjZURlY2xzLCAwLCBmTmFtZXNwYWNlLCBmTmFtZXNwYWNlU2l6ZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lc3BhY2VEZWNscy5sZW5ndGgpOwotICAgICAgICBmTmFtZXNwYWNlU2l6ZSA9IG5ld1NpemU7Ci0gICAgfSAvLyBzZXRFZmZlY3RpdmVDb250ZXh0KFN0cmluZyk6dm9pZAotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgcmV0dXJucyBhbiBhcnJheSBvZiBTdHJpbmdzLCBhcyB3b3VsZCBiZSBzdG9yZWQgaW4KLSAgICAgKiBhIE5hbWVzcGFjZVN1cHBvcnQgb2JqZWN0LiAgVGhpcyBhcnJheSBjb250YWlucyBhbGwKLSAgICAgKiBkZWNsYXJhdGlvbnMgZXhjZXB0IHRob3NlIGF0IHRoZSBnbG9iYWwgbGV2ZWwuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBbXSBnZXRFZmZlY3RpdmVMb2NhbENvbnRleHQoKSB7Ci0gICAgICAgIC8vIHRoZSB0cmljayBoZXJlIGlzIHRvIHJlY29nbml6ZSB0aGF0IGFsbCBsb2NhbCBjb250ZXh0cwotICAgICAgICAvLyBoYXBwZW4gdG8gc3RhcnQgYXQgZkNvbnRleHRbM10uCi0gICAgICAgIC8vIGNvbnRleHQgMTogZW1wdHkKLSAgICAgICAgLy8gY29udGV4dCAyOiBkZWNscyBmb3IgeG1sIGFuZCB4bWxuczsKLSAgICAgICAgLy8gY29udGV4dCAzOiBkZWNscyBvbiA8eHM6c2NoZW1hPjogdGhlIGdsb2JhbCBvbmVzCi0gICAgICAgIFN0cmluZ1tdIHJldHVyblZhbCA9IG51bGw7Ci0gICAgICAgIGlmIChmQ3VycmVudENvbnRleHQgPj0gMykgewotICAgICAgICAgICAgaW50IGJvdHRvbUxvY2FsQ29udGV4dCA9IGZDb250ZXh0WzNdOwotICAgICAgICAgICAgaW50IGNvcHlDb3VudCA9IGZOYW1lc3BhY2VTaXplIC0gYm90dG9tTG9jYWxDb250ZXh0OwotICAgICAgICAgICAgaWYgKGNvcHlDb3VudCA+IDApIHsKLSAgICAgICAgICAgICAgICByZXR1cm5WYWwgPSBuZXcgU3RyaW5nW2NvcHlDb3VudF07Ci0gICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShmTmFtZXNwYWNlLCBib3R0b21Mb2NhbENvbnRleHQsIHJldHVyblZhbCwgMCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvcHlDb3VudCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHJldHVyblZhbDsKLSAgICB9IC8vIGdldEVmZmVjdGl2ZUxvY2FsQ29udGV4dCgpOlN0cmluZwotCi0gICAgLy8gVGhpcyBtZXRob2QgcmVtb3ZlcyBmcm9tIHRoaXMgb2JqZWN0IGFsbCB0aGUgbmFtZXNwYWNlcwotICAgIC8vIHJldHVybmVkIGJ5IGdldEVmZmVjdGl2ZUxvY2FsQ29udGV4dC4KLSAgICBwdWJsaWMgdm9pZCBtYWtlR2xvYmFsKCkgewotICAgICAgICBpZiAoZkN1cnJlbnRDb250ZXh0ID49IDMpIHsKLSAgICAgICAgICAgIGZDdXJyZW50Q29udGV4dCA9IDM7Ci0gICAgICAgICAgICBmTmFtZXNwYWNlU2l6ZSA9IGZDb250ZXh0WzNdOwotICAgICAgICB9Ci0gICAgfSAvLyBtYWtlR2xvYmFsCi19IC8vIGNsYXNzIE5hbWVzcGFjZVN1cHBvcnQKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvU2NoZW1hU3ltYm9scy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9TY2hlbWFTeW1ib2xzLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDJlODIwNWMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9TY2hlbWFTeW1ib2xzLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMTcgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMC0yMDAyLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54czsKLQotCi0vKioKLSAqIENvbGxlY3Rpb24gb2Ygc3ltYm9scyB1c2VkIHRvIHBhcnNlIGEgU2NoZW1hIEdyYW1tYXIuCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgamVmZnJleSByb2RyaWd1ZXoKLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIFNjaGVtYVN5bWJvbHMgewotCi0gICAgLy8gc3RyaW5ncyB0aGF0J3Mgbm90IGFkZGVkIHRvIHRoZSBzY2hlbWEgc3ltYm9sIHRhYmxlLCBiZWNhdXNlIHRoZXkKLSAgICAvLyBhcmUgbm90IHN5bWJvbHMgaW4gdGhlIHNjaGVtYSBkb2N1bWVudC4KLSAgICAvLyB0aGUgdmFsaWRhdG9yIGNhbiBjaG9vc2UgdG8gYWRkIHRoZW0gYnkgaXRzZWxmLgotCi0gICAgLy8gdGhlIGZvbGxvd2luZyBzdHJpbmdzICh4c2k6LCB4c2QpIHdpbGwgYmUgYWRkZWQgaW50byB0aGUKLSAgICAvLyBzeW1ib2wgdGFibGUgdGhhdCBjb21lcyB3aXRoIHRoZSBwYXJzZXIKLQotICAgIC8vIHhzaSBhdHRyaWJ1dGVzOiBpbiB2YWxpZGF0b3IKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBVUklfWFNJICAgICAgICAgICAgICAgICAgICAgICAgPSAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiLmludGVybigpOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFhTSV9TQ0hFTUFMT0NBVElPTiAgICAgICAgICAgID0gInNjaGVtYUxvY2F0aW9uIi5pbnRlcm4oKTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBYU0lfTk9OQU1FU1BBQ0VTQ0hFTUFMT0NBVElPTiA9ICJub05hbWVzcGFjZVNjaGVtYUxvY2F0aW9uIi5pbnRlcm4oKTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBYU0lfVFlQRSAgICAgICAgICAgICAgICAgICAgICAgPSAidHlwZSIuaW50ZXJuKCk7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgWFNJX05JTCAgICAgICAgICAgICAgICAgICAgICAgID0gIm5pbCIuaW50ZXJuKCk7Ci0KLSAgICAvLyBzY2hlbWEgbmFtZXNwYWNlCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgVVJJX1NDSEVNQUZPUlNDSEVNQSAgICAgICAgICAgID0gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hIi5pbnRlcm4oKTsKLQotICAgIC8vIGFsbCBwb3NzaWJsZSBzY2hlbWEgZWxlbWVudCBuYW1lcwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVMVF9BTEwgICAgICAgICAgICAgICAgICA9ICJhbGwiLmludGVybigpOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVMVF9BTk5PVEFUSU9OICAgICAgICAgICA9ICJhbm5vdGF0aW9uIi5pbnRlcm4oKTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFTFRfQU5ZICAgICAgICAgICAgICAgICAgPSAiYW55Ii5pbnRlcm4oKTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFTFRfQU5ZQVRUUklCVVRFICAgICAgICAgPSAiYW55QXR0cmlidXRlIi5pbnRlcm4oKTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFTFRfQVBQSU5GTyAgICAgICAgICAgICAgPSAiYXBwaW5mbyIuaW50ZXJuKCk7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRUxUX0FUVFJJQlVURSAgICAgICAgICAgID0gImF0dHJpYnV0ZSIuaW50ZXJuKCk7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRUxUX0FUVFJJQlVURUdST1VQICAgICAgID0gImF0dHJpYnV0ZUdyb3VwIi5pbnRlcm4oKTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFTFRfQ0hPSUNFICAgICAgICAgICAgICAgPSAiY2hvaWNlIi5pbnRlcm4oKTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFTFRfQ09NUExFWENPTlRFTlQgICAgICAgPSAiY29tcGxleENvbnRlbnQiLmludGVybigpOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVMVF9DT01QTEVYVFlQRSAgICAgICAgICA9ICJjb21wbGV4VHlwZSIuaW50ZXJuKCk7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRUxUX0RPQ1VNRU5UQVRJT04gICAgICAgID0gImRvY3VtZW50YXRpb24iLmludGVybigpOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVMVF9FTEVNRU5UICAgICAgICAgICAgICA9ICJlbGVtZW50Ii5pbnRlcm4oKTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFTFRfRU5VTUVSQVRJT04gICAgICAgICAgPSAiZW51bWVyYXRpb24iLmludGVybigpOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVMVF9FWFRFTlNJT04gICAgICAgICAgICA9ICJleHRlbnNpb24iLmludGVybigpOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVMVF9GSUVMRCAgICAgICAgICAgICAgICA9ICJmaWVsZCIuaW50ZXJuKCk7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRUxUX0ZSQUNUSU9ORElHSVRTICAgICAgID0gImZyYWN0aW9uRGlnaXRzIi5pbnRlcm4oKTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFTFRfR1JPVVAgICAgICAgICAgICAgICAgPSAiZ3JvdXAiLmludGVybigpOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVMVF9JTVBPUlQgICAgICAgICAgICAgICA9ICJpbXBvcnQiLmludGVybigpOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVMVF9JTkNMVURFICAgICAgICAgICAgICA9ICJpbmNsdWRlIi5pbnRlcm4oKTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFTFRfS0VZICAgICAgICAgICAgICAgICAgPSAia2V5Ii5pbnRlcm4oKTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFTFRfS0VZUkVGICAgICAgICAgICAgICAgPSAia2V5cmVmIi5pbnRlcm4oKTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFTFRfTEVOR1RIICAgICAgICAgICAgICAgPSAibGVuZ3RoIi5pbnRlcm4oKTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFTFRfTElTVCAgICAgICAgICAgICAgICAgPSAibGlzdCIuaW50ZXJuKCk7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRUxUX01BWEVYQ0xVU0lWRSAgICAgICAgID0gIm1heEV4Y2x1c2l2ZSIuaW50ZXJuKCk7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRUxUX01BWElOQ0xVU0lWRSAgICAgICAgID0gIm1heEluY2x1c2l2ZSIuaW50ZXJuKCk7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRUxUX01BWExFTkdUSCAgICAgICAgICAgID0gIm1heExlbmd0aCIuaW50ZXJuKCk7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRUxUX01JTkVYQ0xVU0lWRSAgICAgICAgID0gIm1pbkV4Y2x1c2l2ZSIuaW50ZXJuKCk7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRUxUX01JTklOQ0xVU0lWRSAgICAgICAgID0gIm1pbkluY2x1c2l2ZSIuaW50ZXJuKCk7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRUxUX01JTkxFTkdUSCAgICAgICAgICAgID0gIm1pbkxlbmd0aCIuaW50ZXJuKCk7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRUxUX05PVEFUSU9OICAgICAgICAgICAgID0gIm5vdGF0aW9uIi5pbnRlcm4oKTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFTFRfUEFUVEVSTiAgICAgICAgICAgICAgPSAicGF0dGVybiIuaW50ZXJuKCk7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRUxUX1JFREVGSU5FICAgICAgICAgICAgID0gInJlZGVmaW5lIi5pbnRlcm4oKTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFTFRfUkVTVFJJQ1RJT04gICAgICAgICAgPSAicmVzdHJpY3Rpb24iLmludGVybigpOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVMVF9TQ0hFTUEgICAgICAgICAgICAgICA9ICJzY2hlbWEiLmludGVybigpOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVMVF9TRUxFQ1RPUiAgICAgICAgICAgICA9ICJzZWxlY3RvciIuaW50ZXJuKCk7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRUxUX1NFUVVFTkNFICAgICAgICAgICAgID0gInNlcXVlbmNlIi5pbnRlcm4oKTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFTFRfU0lNUExFQ09OVEVOVCAgICAgICAgPSAic2ltcGxlQ29udGVudCIuaW50ZXJuKCk7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRUxUX1NJTVBMRVRZUEUgICAgICAgICAgID0gInNpbXBsZVR5cGUiLmludGVybigpOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVMVF9UT1RBTERJR0lUUyAgICAgICAgICA9ICJ0b3RhbERpZ2l0cyIuaW50ZXJuKCk7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRUxUX1VOSU9OICAgICAgICAgICAgICAgID0gInVuaW9uIi5pbnRlcm4oKTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFTFRfVU5JUVVFICAgICAgICAgICAgICAgPSAidW5pcXVlIi5pbnRlcm4oKTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFTFRfV0hJVEVTUEFDRSAgICAgICAgICAgPSAid2hpdGVTcGFjZSIuaW50ZXJuKCk7Ci0KLSAgICAvLyBhbGwgcG9zc2libGUgc2NoZW1hIGF0dHJpYnV0ZSBuYW1lcyAoYW5kIHhtbDpsYW5nIGRlZmluZWQgb24gPHNjaGVtYT4gYW5kIDxkb2N1bWVudGF0aW9uPikKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRfQUJTVFJBQ1QgICAgICAgICAgICAgPSAiYWJzdHJhY3QiLmludGVybigpOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEFUVF9BVFRSSUJVVEVGT1JNREVGQVVMVCA9ICJhdHRyaWJ1dGVGb3JtRGVmYXVsdCIuaW50ZXJuKCk7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUX0JBU0UgICAgICAgICAgICAgICAgID0gImJhc2UiLmludGVybigpOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEFUVF9CTE9DSyAgICAgICAgICAgICAgICA9ICJibG9jayIuaW50ZXJuKCk7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUX0JMT0NLREVGQVVMVCAgICAgICAgID0gImJsb2NrRGVmYXVsdCIuaW50ZXJuKCk7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUX0RFRkFVTFQgICAgICAgICAgICAgID0gImRlZmF1bHQiLmludGVybigpOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEFUVF9FTEVNRU5URk9STURFRkFVTFQgICA9ICJlbGVtZW50Rm9ybURlZmF1bHQiLmludGVybigpOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEFUVF9GSU5BTCAgICAgICAgICAgICAgICA9ICJmaW5hbCIuaW50ZXJuKCk7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUX0ZJTkFMREVGQVVMVCAgICAgICAgID0gImZpbmFsRGVmYXVsdCIuaW50ZXJuKCk7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUX0ZJWEVEICAgICAgICAgICAgICAgID0gImZpeGVkIi5pbnRlcm4oKTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRfRk9STSAgICAgICAgICAgICAgICAgPSAiZm9ybSIuaW50ZXJuKCk7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUX0lEICAgICAgICAgICAgICAgICAgID0gImlkIi5pbnRlcm4oKTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRfSVRFTVRZUEUgICAgICAgICAgICAgPSAiaXRlbVR5cGUiLmludGVybigpOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEFUVF9NQVhPQ0NVUlMgICAgICAgICAgICA9ICJtYXhPY2N1cnMiLmludGVybigpOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEFUVF9NRU1CRVJUWVBFUyAgICAgICAgICA9ICJtZW1iZXJUeXBlcyIuaW50ZXJuKCk7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUX01JTk9DQ1VSUyAgICAgICAgICAgID0gIm1pbk9jY3VycyIuaW50ZXJuKCk7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUX01JWEVEICAgICAgICAgICAgICAgID0gIm1peGVkIi5pbnRlcm4oKTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRfTkFNRSAgICAgICAgICAgICAgICAgPSAibmFtZSIuaW50ZXJuKCk7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUX05BTUVTUEFDRSAgICAgICAgICAgID0gIm5hbWVzcGFjZSIuaW50ZXJuKCk7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUX05JTExBQkxFICAgICAgICAgICAgID0gIm5pbGxhYmxlIi5pbnRlcm4oKTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRfUFJPQ0VTU0NPTlRFTlRTICAgICAgPSAicHJvY2Vzc0NvbnRlbnRzIi5pbnRlcm4oKTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRfUkVGICAgICAgICAgICAgICAgICAgPSAicmVmIi5pbnRlcm4oKTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRfUkVGRVIgICAgICAgICAgICAgICAgPSAicmVmZXIiLmludGVybigpOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEFUVF9TQ0hFTUFMT0NBVElPTiAgICAgICA9ICJzY2hlbWFMb2NhdGlvbiIuaW50ZXJuKCk7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUX1NPVVJDRSAgICAgICAgICAgICAgID0gInNvdXJjZSIuaW50ZXJuKCk7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUX1NVQlNUSVRVVElPTkdST1VQICAgID0gInN1YnN0aXR1dGlvbkdyb3VwIi5pbnRlcm4oKTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRfU1lTVEVNICAgICAgICAgICAgICAgPSAic3lzdGVtIi5pbnRlcm4oKTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRfUFVCTElDICAgICAgICAgICAgICAgPSAicHVibGljIi5pbnRlcm4oKTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRfVEFSR0VUTkFNRVNQQUNFICAgICAgPSAidGFyZ2V0TmFtZXNwYWNlIi5pbnRlcm4oKTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRfVFlQRSAgICAgICAgICAgICAgICAgPSAidHlwZSIuaW50ZXJuKCk7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUX1VTRSAgICAgICAgICAgICAgICAgID0gInVzZSIuaW50ZXJuKCk7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUX1ZBTFVFICAgICAgICAgICAgICAgID0gInZhbHVlIi5pbnRlcm4oKTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRfVkVSU0lPTiAgICAgICAgICAgICAgPSAidmVyc2lvbiIuaW50ZXJuKCk7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUX1hNTF9MQU5HICAgICAgICAgICAgID0gInhtbDpsYW5nIi5pbnRlcm4oKTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRfWFBBVEggICAgICAgICAgICAgICAgPSAieHBhdGgiLmludGVybigpOwotCi0gICAgLy8gYWxsIHBvc3NpYmxlIHNjaGVtYSBhdHRyaWJ1dGUgdmFsdWVzCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUVkFMX1RXT1BPVU5EQU5ZICAgICAgID0gIiMjYW55IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRWQUxfVFdPUE9VTkRMT0NBTCAgICAgPSAiIyNsb2NhbCI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUVkFMX1RXT1BPVU5ET1RIRVIgICAgID0gIiMjb3RoZXIiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEFUVFZBTF9UV09QT1VORFRBUkdFVE5TICA9ICIjI3RhcmdldE5hbWVzcGFjZSI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUVkFMX1BPVU5EQUxMICAgICAgICAgID0gIiNhbGwiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEFUVFZBTF9GQUxTRV8wICAgICAgICAgICA9ICIwIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRWQUxfVFJVRV8xICAgICAgICAgICAgPSAiMSI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUVkFMX0FOWVNJTVBMRVRZUEUgICAgID0gImFueVNpbXBsZVR5cGUiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEFUVFZBTF9BTllUWVBFICAgICAgICAgICA9ICJhbnlUeXBlIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRWQUxfQU5ZVVJJICAgICAgICAgICAgPSAiYW55VVJJIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRWQUxfQkFTRTY0QklOQVJZICAgICAgPSAiYmFzZTY0QmluYXJ5IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRWQUxfQk9PTEVBTiAgICAgICAgICAgPSAiYm9vbGVhbiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUVkFMX0JZVEUgICAgICAgICAgICAgID0gImJ5dGUiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEFUVFZBTF9DT0xMQVBTRSAgICAgICAgICA9ICJjb2xsYXBzZSI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUVkFMX0RBVEUgICAgICAgICAgICAgID0gImRhdGUiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEFUVFZBTF9EQVRFVElNRSAgICAgICAgICA9ICJkYXRlVGltZSI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUVkFMX0RBWSAgICAgICAgICAgICAgID0gImdEYXkiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEFUVFZBTF9ERUNJTUFMICAgICAgICAgICA9ICJkZWNpbWFsIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRWQUxfRE9VQkxFICAgICAgICAgICAgPSAiZG91YmxlIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRWQUxfRFVSQVRJT04gICAgICAgICAgPSAiZHVyYXRpb24iOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEFUVFZBTF9FTlRJVFkgICAgICAgICAgICA9ICJFTlRJVFkiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEFUVFZBTF9FTlRJVElFUyAgICAgICAgICA9ICJFTlRJVElFUyI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUVkFMX0VYVEVOU0lPTiAgICAgICAgID0gImV4dGVuc2lvbiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUVkFMX0ZBTFNFICAgICAgICAgICAgID0gImZhbHNlIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRWQUxfRkxPQVQgICAgICAgICAgICAgPSAiZmxvYXQiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEFUVFZBTF9IRVhCSU5BUlkgICAgICAgICA9ICJoZXhCaW5hcnkiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEFUVFZBTF9JRCAgICAgICAgICAgICAgICA9ICJJRCI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUVkFMX0lEUkVGICAgICAgICAgICAgID0gIklEUkVGIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRWQUxfSURSRUZTICAgICAgICAgICAgPSAiSURSRUZTIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRWQUxfSU5UICAgICAgICAgICAgICAgPSAiaW50IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRWQUxfSU5URUdFUiAgICAgICAgICAgPSAiaW50ZWdlciI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUVkFMX0xBTkdVQUdFICAgICAgICAgID0gImxhbmd1YWdlIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRWQUxfTEFYICAgICAgICAgICAgICAgPSAibGF4IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRWQUxfTElTVCAgICAgICAgICAgICAgPSAibGlzdCI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUVkFMX0xPTkcgICAgICAgICAgICAgID0gImxvbmciOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEFUVFZBTF9OQU1FICAgICAgICAgICAgICA9ICJOYW1lIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRWQUxfTkVHQVRJVkVJTlRFR0VSICAgPSAibmVnYXRpdmVJbnRlZ2VyIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRWQUxfTU9OVEggICAgICAgICAgICAgPSAiZ01vbnRoIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRWQUxfTU9OVEhEQVkgICAgICAgICAgPSAiZ01vbnRoRGF5IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRWQUxfTkNOQU1FICAgICAgICAgICAgPSAiTkNOYW1lIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRWQUxfTk1UT0tFTiAgICAgICAgICAgPSAiTk1UT0tFTiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUVkFMX05NVE9LRU5TICAgICAgICAgID0gIk5NVE9LRU5TIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRWQUxfTk9OTkVHQVRJVkVJTlRFR0VSPSAibm9uTmVnYXRpdmVJbnRlZ2VyIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRWQUxfTk9OUE9TSVRJVkVJTlRFR0VSPSAibm9uUG9zaXRpdmVJbnRlZ2VyIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRWQUxfTk9STUFMSVpFRFNUUklORyAgPSAibm9ybWFsaXplZFN0cmluZyI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUVkFMX05PVEFUSU9OICAgICAgICAgID0gIk5PVEFUSU9OIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRWQUxfT1BUSU9OQUwgICAgICAgICAgPSAib3B0aW9uYWwiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEFUVFZBTF9QT1NJVElWRUlOVEVHRVIgICA9ICJwb3NpdGl2ZUludGVnZXIiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEFUVFZBTF9QUkVTRVJWRSAgICAgICAgICA9ICJwcmVzZXJ2ZSI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUVkFMX1BST0hJQklURUQgICAgICAgID0gInByb2hpYml0ZWQiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEFUVFZBTF9RTkFNRSAgICAgICAgICAgICA9ICJRTmFtZSI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUVkFMX1FVQUxJRklFRCAgICAgICAgID0gInF1YWxpZmllZCI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUVkFMX1JFUExBQ0UgICAgICAgICAgID0gInJlcGxhY2UiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEFUVFZBTF9SRVFVSVJFRCAgICAgICAgICA9ICJyZXF1aXJlZCI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUVkFMX1JFU1RSSUNUSU9OICAgICAgID0gInJlc3RyaWN0aW9uIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRWQUxfU0hPUlQgICAgICAgICAgICAgPSAic2hvcnQiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEFUVFZBTF9TS0lQICAgICAgICAgICAgICA9ICJza2lwIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRWQUxfU1RSSUNUICAgICAgICAgICAgPSAic3RyaWN0IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRWQUxfU1RSSU5HICAgICAgICAgICAgPSAic3RyaW5nIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRWQUxfU1VCU1RJVFVUSU9OICAgICAgPSAic3Vic3RpdHV0aW9uIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRWQUxfVElNRSAgICAgICAgICAgICAgPSAidGltZSI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUVkFMX1RPS0VOICAgICAgICAgICAgID0gInRva2VuIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRWQUxfVFJVRSAgICAgICAgICAgICAgPSAidHJ1ZSI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUVkFMX1VOQk9VTkRFRCAgICAgICAgID0gInVuYm91bmRlZCI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUVkFMX1VOSU9OICAgICAgICAgICAgID0gInVuaW9uIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRWQUxfVU5RVUFMSUZJRUQgICAgICAgPSAidW5xdWFsaWZpZWQiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEFUVFZBTF9VTlNJR05FREJZVEUgICAgICA9ICJ1bnNpZ25lZEJ5dGUiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEFUVFZBTF9VTlNJR05FRElOVCAgICAgICA9ICJ1bnNpZ25lZEludCI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUVkFMX1VOU0lHTkVETE9ORyAgICAgID0gInVuc2lnbmVkTG9uZyI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUVkFMX1VOU0lHTkVEU0hPUlQgICAgID0gInVuc2lnbmVkU2hvcnQiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEFUVFZBTF9ZRUFSICAgICAgICAgICAgICA9ICJnWWVhciI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUVkFMX1lFQVJNT05USCAgICAgICAgID0gImdZZWFyTW9udGgiOwotCi0gICAgLy8gZm9ybSBxdWFsaWZpZWQvdW5xdWFsaWZpZWQKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IEZPUk1fVU5RVUFMSUZJRUQgPSAwOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgRk9STV9RVUFMSUZJRUQgICA9IDE7Ci0KLSAgICAvLyBhdHRyaWJ1dGUgdXNlCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBVU0VfT1BUSU9OQUwgICA9IDA7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBVU0VfUkVRVUlSRUQgICA9IDE7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBVU0VfUFJPSElCSVRFRCA9IDI7Ci0KLSAgICAvLyBtYXhPY2N1cnMgPSAidW5ib3VuZGVkIgotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9DQ1VSUkVOQ0VfVU5CT1VOREVEID0gLTE7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvU3Vic3RpdHV0aW9uR3JvdXBIYW5kbGVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL1N1YnN0aXR1dGlvbkdyb3VwSGFuZGxlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiZDk1YjE3Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvU3Vic3RpdHV0aW9uR3JvdXBIYW5kbGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzNTIgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAxNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54czsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlFOYW1lOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNDb25zdGFudHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU09iamVjdExpc3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU1NpbXBsZVR5cGVEZWZpbml0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNUeXBlRGVmaW5pdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKLWltcG9ydCBqYXZhLnV0aWwuTWFwOwotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLS8qKgotICogVG8gc3RvcmUgYW5kIHZhbGlkYXRlIGluZm9ybWF0aW9uIGFib3V0IHN1YnN0aXR1dGlvbkdyb3VwCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgU2FuZHkgR2FvLCBJQk0KLSAqCi0gKiBAdmVyc2lvbiAkSWQ6IFN1YnN0aXR1dGlvbkdyb3VwSGFuZGxlci5qYXZhLHYgMS42IDIwMTAtMTEtMDEgMDQ6Mzk6NTUgam9laHcgRXhwICQKLSAqLwotcHVibGljIGNsYXNzIFN1YnN0aXR1dGlvbkdyb3VwSGFuZGxlciB7Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBYU0VsZW1lbnREZWNsW10gRU1QVFlfR1JPVVAgPSBuZXcgWFNFbGVtZW50RGVjbFswXTsKLQotICAgIC8vIGdyYW1tYXIgcmVzb2x2ZXIKLSAgICBYU0dyYW1tYXJCdWNrZXQgZkdyYW1tYXJCdWNrZXQ7Ci0KLSAgICAvKioKLSAgICAgKiBEZWZhdWx0IGNvbnN0cnVjdG9yCi0gICAgICovCi0gICAgcHVibGljIFN1YnN0aXR1dGlvbkdyb3VwSGFuZGxlcihYU0dyYW1tYXJCdWNrZXQgZ3JhbW1hckJ1Y2tldCkgewotICAgICAgICBmR3JhbW1hckJ1Y2tldCA9IGdyYW1tYXJCdWNrZXQ7Ci0gICAgfQotCi0gICAgLy8gMy45LjQgRWxlbWVudCBTZXF1ZW5jZSBMb2NhbGx5IFZhbGlkIChQYXJ0aWNsZSkgMi4zLjMKLSAgICAvLyBjaGVjayB3aGV0aGVyIG9uZSBlbGVtZW50IGRlY2wgbWF0Y2hlcyBhbiBlbGVtZW50IHdpdGggdGhlIGdpdmVuIHFuYW1lCi0gICAgcHVibGljIFhTRWxlbWVudERlY2wgZ2V0TWF0Y2hpbmdFbGVtRGVjbChRTmFtZSBlbGVtZW50LCBYU0VsZW1lbnREZWNsIGV4ZW1wbGFyKSB7Ci0gICAgICAgIGlmIChlbGVtZW50LmxvY2FscGFydCA9PSBleGVtcGxhci5mTmFtZSAmJgotICAgICAgICAgICAgZWxlbWVudC51cmkgPT0gZXhlbXBsYXIuZlRhcmdldE5hbWVzcGFjZSkgewotICAgICAgICAgICAgcmV0dXJuIGV4ZW1wbGFyOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gaWYgdGhlIGV4ZW1wbGFyIGlzIG5vdCBhIGdsb2JhbCBlbGVtZW50IGRlY2wsIHRoZW4gaXQncyBub3QgcG9zc2libGUKLSAgICAgICAgLy8gdG8gYmUgc3Vic3RpdHV0ZWQgYnkgYW5vdGhlciBlbGVtZW50LgotICAgICAgICBpZiAoZXhlbXBsYXIuZlNjb3BlICE9IFhTQ29uc3RhbnRzLlNDT1BFX0dMT0JBTCkKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotCi0gICAgICAgIC8vIGlmIHRoZSBkZWNsIGJsb2NrcyBzdWJzdGl0dXRpb24sIHJldHVybiBmYWxzZQotICAgICAgICBpZiAoKGV4ZW1wbGFyLmZCbG9jayAmIFhTQ29uc3RhbnRzLkRFUklWQVRJT05fU1VCU1RJVFVUSU9OKSAhPSAwKQotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0KLSAgICAgICAgLy8gZ2V0IGdyYW1tYXIgb2YgdGhlIGVsZW1lbnQKLSAgICAgICAgU2NoZW1hR3JhbW1hciBzR3JhbW1hciA9IGZHcmFtbWFyQnVja2V0LmdldEdyYW1tYXIoZWxlbWVudC51cmkpOwotICAgICAgICBpZiAoc0dyYW1tYXIgPT0gbnVsbCkKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotCi0gICAgICAgIC8vIGdldCB0aGUgZGVjbCBmb3IgdGhlIGVsZW1lbnQKLSAgICAgICAgWFNFbGVtZW50RGVjbCBlRGVjbCA9IHNHcmFtbWFyLmdldEdsb2JhbEVsZW1lbnREZWNsKGVsZW1lbnQubG9jYWxwYXJ0KTsKLSAgICAgICAgaWYgKGVEZWNsID09IG51bGwpCi0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLQotICAgICAgICAvLyBhbmQgY2hlY2sgYnkgdXNpbmcgc3Vic3RpdHV0aW9uR3JvdXAgaW5mb3JtYXRpb24KLSAgICAgICAgaWYgKHN1YnN0aXR1dGlvbkdyb3VwT0soZURlY2wsIGV4ZW1wbGFyLCBleGVtcGxhci5mQmxvY2spKQotICAgICAgICAgICAgcmV0dXJuIGVEZWNsOwotCi0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8vIDMuMy42IFN1YnN0aXR1dGlvbiBHcm91cCBPSyAoVHJhbnNpdGl2ZSkKLSAgICAvLyBjaGVjayB3aGV0aGVyIGVsZW1lbnQgY2FuIHN1YnN0aXR1dGUgZXhlbXBsYXIKLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBzdWJzdGl0dXRpb25Hcm91cE9LKFhTRWxlbWVudERlY2wgZWxlbWVudCwgWFNFbGVtZW50RGVjbCBleGVtcGxhciwgc2hvcnQgYmxvY2tpbmdDb25zdHJhaW50KSB7Ci0gICAgICAgIC8vIEZvciBhbiBlbGVtZW50IGRlY2xhcmF0aW9uIChjYWxsIGl0IEQpIHRvIGJlIHZhbGlkbHkgc3Vic3RpdHV0YWJsZSBmb3IgYW5vdGhlciBlbGVtZW50IGRlY2xhcmF0aW9uIChjYWxsIGl0IEMpIHN1YmplY3QgdG8gYSBibG9ja2luZyBjb25zdHJhaW50IChhIHN1YnNldCBvZiB7c3Vic3RpdHV0aW9uLCBleHRlbnNpb24sIHJlc3RyaWN0aW9ufSwgdGhlIHZhbHVlIG9mIGEge2Rpc2FsbG93ZWQgc3Vic3RpdHV0aW9uc30pIG9uZSBvZiB0aGUgZm9sbG93aW5nIG11c3QgYmUgdHJ1ZToKLSAgICAgICAgLy8gMS4gRCBhbmQgQyBhcmUgdGhlIHNhbWUgZWxlbWVudCBkZWNsYXJhdGlvbi4KLSAgICAgICAgaWYgKGVsZW1lbnQgPT0gZXhlbXBsYXIpCi0gICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLQotICAgICAgICAvLyAyIEFsbCBvZiB0aGUgZm9sbG93aW5nIG11c3QgYmUgdHJ1ZToKLSAgICAgICAgLy8gMi4xIFRoZSBibG9ja2luZyBjb25zdHJhaW50IGRvZXMgbm90IGNvbnRhaW4gc3Vic3RpdHV0aW9uLgotICAgICAgICBpZiAoKGJsb2NraW5nQ29uc3RyYWludCAmIFhTQ29uc3RhbnRzLkRFUklWQVRJT05fU1VCU1RJVFVUSU9OKSAhPSAwKQotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotCi0gICAgICAgIC8vIDIuMiBUaGVyZSBpcyBhIGNoYWluIG9mIHtzdWJzdGl0dXRpb24gZ3JvdXAgYWZmaWxpYXRpb259cyBmcm9tIEQgdG8gQywgdGhhdCBpcywgZWl0aGVyIEQncyB7c3Vic3RpdHV0aW9uIGdyb3VwIGFmZmlsaWF0aW9ufSBpcyBDLCBvciBEJ3Mge3N1YnN0aXR1dGlvbiBncm91cCBhZmZpbGlhdGlvbn0ncyB7c3Vic3RpdHV0aW9uIGdyb3VwIGFmZmlsaWF0aW9ufSBpcyBDLCBvciAuIC4gLgotICAgICAgICBYU0VsZW1lbnREZWNsIHN1Ykdyb3VwID0gZWxlbWVudC5mU3ViR3JvdXA7Ci0gICAgICAgIHdoaWxlIChzdWJHcm91cCAhPSBudWxsICYmIHN1Ykdyb3VwICE9IGV4ZW1wbGFyKSB7Ci0gICAgICAgICAgICBzdWJHcm91cCA9IHN1Ykdyb3VwLmZTdWJHcm91cDsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChzdWJHcm91cCA9PSBudWxsKQotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotCi0gICAgICAgIC8vIDIuMyBUaGUgc2V0IG9mIGFsbCB7ZGVyaXZhdGlvbiBtZXRob2R9cyBpbnZvbHZlZCBpbiB0aGUgZGVyaXZhdGlvbiBvZiBEJ3Mge3R5cGUgZGVmaW5pdGlvbn0gZnJvbSBDJ3Mge3R5cGUgZGVmaW5pdGlvbn0gZG9lcyBub3QgaW50ZXJzZWN0IHdpdGggdGhlIHVuaW9uIG9mIHRoZSBibG9ja2luZyBjb25zdHJhaW50LCBDJ3Mge3Byb2hpYml0ZWQgc3Vic3RpdHV0aW9uc30gKGlmIEMgaXMgY29tcGxleCwgb3RoZXJ3aXNlIHRoZSBlbXB0eSBzZXQpIGFuZCB0aGUge3Byb2hpYml0ZWQgc3Vic3RpdHV0aW9uc30gKHJlc3BlY3RpdmVseSB0aGUgZW1wdHkgc2V0KSBvZiBhbnkgaW50ZXJtZWRpYXRlIHt0eXBlIGRlZmluaXRpb259cyBpbiB0aGUgZGVyaXZhdGlvbiBvZiBEJ3Mge3R5cGUgZGVmaW5pdGlvbn0gZnJvbSBDJ3Mge3R5cGUgZGVmaW5pdGlvbn0uCi0gICAgICAgIC8vIHByZXBhcmUgdGhlIGNvbWJpbmF0aW9uIG9mIHtkZXJpdmF0aW9uIG1ldGhvZH0gYW5kCi0gICAgICAgIC8vIHtkaXNhbGxvd2VkIHN1YnN0aXR1dGlvbn0KLSAgICAgICAgcmV0dXJuIHR5cGVEZXJpdmF0aW9uT0soZWxlbWVudC5mVHlwZSwgZXhlbXBsYXIuZlR5cGUsIGJsb2NraW5nQ29uc3RyYWludCk7Ci0gICAgfQotICAgIHByaXZhdGUgYm9vbGVhbiB0eXBlRGVyaXZhdGlvbk9LKFhTVHlwZURlZmluaXRpb24gZGVyaXZlZCwgWFNUeXBlRGVmaW5pdGlvbiBiYXNlLCBzaG9ydCBibG9ja2luZ0NvbnN0cmFpbnQpIHsKLQotICAgICAgICBzaG9ydCBkZXZNZXRob2QgPSAwLCBibG9ja0NvbnN0cmFpbnQgPSBibG9ja2luZ0NvbnN0cmFpbnQ7Ci0KLSAgICAgICAgLy8gImRlcml2ZWQiIHNob3VsZCBiZSBkZXJpdmVkIGZyb20gImJhc2UiCi0gICAgICAgIC8vIGFkZCBkZXJpdmF0aW9uIG1ldGhvZHMgb2YgZGVyaXZlZCB0eXBlcyB0byBkZXZNZXRob2Q7Ci0gICAgICAgIC8vIGFkZCBibG9jayBvZiBiYXNlIHR5cGVzIHRvIGJsb2NrQ29uc3RyYWludC4KLSAgICAgICAgWFNUeXBlRGVmaW5pdGlvbiB0eXBlID0gZGVyaXZlZDsKLSAgICAgICAgd2hpbGUgKHR5cGUgIT0gYmFzZSAmJiB0eXBlICE9IFNjaGVtYUdyYW1tYXIuZkFueVR5cGUpIHsKLSAgICAgICAgICAgIGlmICh0eXBlLmdldFR5cGVDYXRlZ29yeSgpID09IFhTVHlwZURlZmluaXRpb24uQ09NUExFWF9UWVBFKSB7Ci0gICAgICAgICAgICAgICAgZGV2TWV0aG9kIHw9ICgoWFNDb21wbGV4VHlwZURlY2wpdHlwZSkuZkRlcml2ZWRCeTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIGRldk1ldGhvZCB8PSBYU0NvbnN0YW50cy5ERVJJVkFUSU9OX1JFU1RSSUNUSU9OOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgdHlwZSA9IHR5cGUuZ2V0QmFzZVR5cGUoKTsKLSAgICAgICAgICAgIC8vIHR5cGUgPT0gbnVsbCBtZWFucyB0aGUgY3VycmVudCB0eXBlIGlzIGFueVNpbXBsZVR5cGUsCi0gICAgICAgICAgICAvLyB3aG9zZSBiYXNlIHR5cGUgc2hvdWxkIGJlIGFueVR5cGUKLSAgICAgICAgICAgIGlmICh0eXBlID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICB0eXBlID0gU2NoZW1hR3JhbW1hci5mQW55VHlwZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmICh0eXBlLmdldFR5cGVDYXRlZ29yeSgpID09IFhTVHlwZURlZmluaXRpb24uQ09NUExFWF9UWVBFKSB7Ci0gICAgICAgICAgICAgICAgYmxvY2tDb25zdHJhaW50IHw9ICgoWFNDb21wbGV4VHlwZURlY2wpdHlwZSkuZkJsb2NrOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGlmICh0eXBlICE9IGJhc2UpIHsKLSAgICAgICAgICAgIC8vIElmIHRoZSBiYXNlIGlzIGEgdW5pb24sIGNoZWNrIGlmICJkZXJpdmVkIiBpcyBhbGxvd2VkIHRocm91Z2ggYW55IG9mIHRoZSBtZW1iZXIgdHlwZXMuCi0gICAgICAgICAgICBpZiAoYmFzZS5nZXRUeXBlQ2F0ZWdvcnkoKSA9PSBYU1R5cGVEZWZpbml0aW9uLlNJTVBMRV9UWVBFKSB7Ci0gICAgICAgICAgICAgICAgWFNTaW1wbGVUeXBlRGVmaW5pdGlvbiBzdCA9IChYU1NpbXBsZVR5cGVEZWZpbml0aW9uKSBiYXNlOwotICAgICAgICAgICAgICAgIGlmIChzdC5nZXRWYXJpZXR5KCkgPT0gIFhTU2ltcGxlVHlwZURlZmluaXRpb24uVkFSSUVUWV9VTklPTikgewotICAgICAgICAgICAgICAgICAgICBYU09iamVjdExpc3QgbWVtYmVyVHlwZXMgPSBzdC5nZXRNZW1iZXJUeXBlcygpOwotICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgbGVuZ3RoID0gbWVtYmVyVHlwZXMuZ2V0TGVuZ3RoKCk7Ci0gICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyArK2kpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlRGVyaXZhdGlvbk9LKGRlcml2ZWQsIChYU1R5cGVEZWZpbml0aW9uKSBtZW1iZXJUeXBlcy5pdGVtKGkpLCBibG9ja2luZ0NvbnN0cmFpbnQpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKChkZXZNZXRob2QgJiBibG9ja0NvbnN0cmFpbnQpICE9IDApIHsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICB9Ci0KLSAgICAvLyBjaGVjayB3aGV0aGVyIGVsZW1lbnQgaXMgaW4gZXhlbXBsYXIncyBzdWJzdGl0dXRpb24gZ3JvdXAKLSAgICBwdWJsaWMgYm9vbGVhbiBpblN1YnN0aXR1dGlvbkdyb3VwKFhTRWxlbWVudERlY2wgZWxlbWVudCwgWFNFbGVtZW50RGVjbCBleGVtcGxhcikgewotICAgICAgICAvLyBbRGVmaW5pdGlvbjpdICBFdmVyeSBlbGVtZW50IGRlY2xhcmF0aW9uIChjYWxsIHRoaXMgSEVBRCkgaW4gdGhlIHtlbGVtZW50IGRlY2xhcmF0aW9uc30gb2YgYSBzY2hlbWEgZGVmaW5lcyBhIHN1YnN0aXR1dGlvbiBncm91cCwgYSBzdWJzZXQgb2YgdGhvc2Uge2VsZW1lbnQgZGVjbGFyYXRpb25zfSwgYXMgZm9sbG93czoKLSAgICAgICAgLy8gRGVmaW5lIFBTRywgdGhlIHBvdGVudGlhbCBzdWJzdGl0dXRpb24gZ3JvdXAgZm9yIEhFQUQsIGFzIGZvbGxvd3M6Ci0gICAgICAgIC8vIDEgVGhlIGVsZW1lbnQgZGVjbGFyYXRpb24gaXRzZWxmIGlzIGluIFBTRzsKLSAgICAgICAgLy8gMiBQU0cgaXMgY2xvc2VkIHdpdGggcmVzcGVjdCB0byB7c3Vic3RpdHV0aW9uIGdyb3VwIGFmZmlsaWF0aW9ufSwgdGhhdCBpcywgaWYgYW55IGVsZW1lbnQgZGVjbGFyYXRpb24gaW4gdGhlIHtlbGVtZW50IGRlY2xhcmF0aW9uc30gaGFzIGEge3N1YnN0aXR1dGlvbiBncm91cCBhZmZpbGlhdGlvbn0gaW4gUFNHLCB0aGVuIGl0IGlzIGFsc28gaW4gUFNHIGl0c2VsZi4KLSAgICAgICAgLy8gSEVBRCdzIGFjdHVhbCBzdWJzdGl0dXRpb24gZ3JvdXAgaXMgdGhlbiB0aGUgc2V0IGNvbnNpc3Rpbmcgb2YgZWFjaCBtZW1iZXIgb2YgUFNHIHN1Y2ggdGhhdCBhbGwgb2YgdGhlIGZvbGxvd2luZyBtdXN0IGJlIHRydWU6Ci0gICAgICAgIC8vIDEgSXRzIHthYnN0cmFjdH0gaXMgZmFsc2UuCi0gICAgICAgIC8vIDIgSXQgaXMgdmFsaWRseSBzdWJzdGl0dXRhYmxlIGZvciBIRUFEIHN1YmplY3QgdG8gYW4gZW1wdHkgYmxvY2tpbmcgY29uc3RyYWludCwgYXMgZGVmaW5lZCBpbiBTdWJzdGl0dXRpb24gR3JvdXAgT0sgKFRyYW5zaXRpdmUpICgzLjMuNikuCi0gICAgICAgIHJldHVybiBzdWJzdGl0dXRpb25Hcm91cE9LKGVsZW1lbnQsIGV4ZW1wbGFyLCBleGVtcGxhci5mQmxvY2spOwotICAgIH0KLQotICAgIC8vIHRvIHN0b3JlIHN1YnN0aXR1dGlvbiBncm91cCBpbmZvcm1hdGlvbgotICAgIC8vIHRoZSBrZXkgdG8gdGhlIG1hcCBpcyBhbiBlbGVtZW50IGRlY2wsIGFuZCB0aGUgdmFsdWUgaXMKLSAgICAvLyAtIGEgVmVjdG9yLCB3aGljaCBjb250YWlucyBhbGwgZWxlbWVudHMgdGhhdCBoYXMgdGhpcyBlbGVtZW50IGFzIHRoZWlyCi0gICAgLy8gICBzdWJzdGl0dXRpb24gZ3JvdXAgYWZmaWxpY2F0aW9uCi0gICAgLy8gLSBhbiBhcnJheSBvZiBPbmVTdWJHcm91cCwgd2hpY2ggY29udGFpbnMgaXRzIHN1YnN0aXR1dGlvbiBncm91cCBiZWZvcmUgYmxvY2suCi0gICAgTWFwPFhTRWxlbWVudERlY2wsIE9iamVjdD4gZlN1Ykdyb3Vwc0IgPSBuZXcgSGFzaE1hcDw+KCk7Ci0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgT25lU3ViR3JvdXBbXSBFTVBUWV9WRUNUT1IgPSBuZXcgT25lU3ViR3JvdXBbMF07Ci0gICAgLy8gVGhlIHJlYWwgc3Vic3RpdHV0aW9uIGdyb3VwcyAoYWZ0ZXIgImJsb2NrIikKLSAgICBNYXA8WFNFbGVtZW50RGVjbCwgWFNFbGVtZW50RGVjbFtdPiBmU3ViR3JvdXBzID0gbmV3IEhhc2hNYXA8PigpOwotCi0gICAgLyoqCi0gICAgICogY2xlYXIgdGhlIGludGVybmFsIHJlZ2lzdHJ5IG9mIHN1YnN0aXR1dGlvbkdyb3VwIGluZm9ybWF0aW9uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcmVzZXQoKSB7Ci0gICAgICAgIGZTdWJHcm91cHNCLmNsZWFyKCk7Ci0gICAgICAgIGZTdWJHcm91cHMuY2xlYXIoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBhZGQgYSBsaXN0IG9mIHN1YnN0aXR1dGlvbiBncm91cCBpbmZvcm1hdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBhZGRTdWJzdGl0dXRpb25Hcm91cChYU0VsZW1lbnREZWNsW10gZWxlbWVudHMpIHsKLSAgICAgICAgWFNFbGVtZW50RGVjbCBzdWJIZWFkLCBlbGVtZW50OwotICAgICAgICBWZWN0b3Igc3ViR3JvdXA7Ci0gICAgICAgIC8vIGZvciBhbGwgZWxlbWVudHMgd2l0aCBzdWJzdGl0dXRpb24gZ3JvdXAgYWZmaWxpYXRpb24KLSAgICAgICAgZm9yIChpbnQgaSA9IGVsZW1lbnRzLmxlbmd0aC0xOyBpID49IDA7IGktLSkgewotICAgICAgICAgICAgZWxlbWVudCA9IGVsZW1lbnRzW2ldOwotICAgICAgICAgICAgc3ViSGVhZCA9IGVsZW1lbnQuZlN1Ykdyb3VwOwotICAgICAgICAgICAgLy8gY2hlY2sgd2hldGhlciB0aGlzIGFuIGVudHJ5IGZvciB0aGlzIGVsZW1lbnQKLSAgICAgICAgICAgIHN1Ykdyb3VwID0gKFZlY3RvcilmU3ViR3JvdXBzQi5nZXQoc3ViSGVhZCk7Ci0gICAgICAgICAgICBpZiAoc3ViR3JvdXAgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIC8vIGlmIG5vdCwgY3JlYXRlIGEgbmV3IG9uZQotICAgICAgICAgICAgICAgIHN1Ykdyb3VwID0gbmV3IFZlY3RvcigpOwotICAgICAgICAgICAgICAgIGZTdWJHcm91cHNCLnB1dChzdWJIZWFkLCBzdWJHcm91cCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyBhZGQgdG8gdGhlIHZhY3RvcgotICAgICAgICAgICAgc3ViR3JvdXAuYWRkRWxlbWVudChlbGVtZW50KTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIGdldCBhbGwgZWxlbWVudHMgdGhhdCBjYW4gc3Vic3RpdHV0ZSB0aGUgZ2l2ZW4gZWxlbWVudCwKLSAgICAgKiBhY2NvcmRpbmcgdG8gdGhlIHNwZWMsIHdlIHNob3VsZG4ndCBjb25zaWRlciB0aGUge2Jsb2NrfSBjb25zdHJhaW50cy4KLSAgICAgKgotICAgICAqIGZyb20gdGhlIHNwZWMsIHN1YnN0aXR1dGlvbiBncm91cCBvZiBhIGdpdmVuIGVsZW1lbnQgZGVjbCBhbHNvIGNvbnRhaW5zCi0gICAgICogdGhlIGVsZW1lbnQgaXRzZWxmLiBidXQgdGhlIGFycmF5IHJldHVybmVkIGZyb20gdGhpcyBtZXRob2QgZG9lc24ndAotICAgICAqIGNvbnRhaW50IHRoaXMgZWxlbWVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFNFbGVtZW50RGVjbFtdIGdldFN1YnN0aXR1dGlvbkdyb3VwKFhTRWxlbWVudERlY2wgZWxlbWVudCkgewotICAgICAgICAvLyBJZiB3ZSBhbHJlYWR5IGhhdmUgc3ViIGdyb3VwIGZvciB0aGlzIGVsZW1lbnQsIGp1c3QgcmV0dXJuIGl0LgotICAgICAgICBYU0VsZW1lbnREZWNsW10gc3ViR3JvdXAgPSBmU3ViR3JvdXBzLmdldChlbGVtZW50KTsKLSAgICAgICAgaWYgKHN1Ykdyb3VwICE9IG51bGwpCi0gICAgICAgICAgICByZXR1cm4gc3ViR3JvdXA7Ci0KLSAgICAgICAgaWYgKChlbGVtZW50LmZCbG9jayAmIFhTQ29uc3RhbnRzLkRFUklWQVRJT05fU1VCU1RJVFVUSU9OKSAhPSAwKSB7Ci0gICAgICAgICAgICBmU3ViR3JvdXBzLnB1dChlbGVtZW50LCBFTVBUWV9HUk9VUCk7Ci0gICAgICAgICAgICByZXR1cm4gRU1QVFlfR1JPVVA7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBPdGhlcndpc2UsIGdldCBhbGwgcG90ZW50aWFsIHN1YiBncm91cCBlbGVtZW50cwotICAgICAgICAvLyAod2l0aG91dCBjb25zaWRlcmluZyAiYmxvY2siIG9uIHRoaXMgZWxlbWVudAotICAgICAgICBPbmVTdWJHcm91cFtdIGdyb3VwQiA9IGdldFN1Ykdyb3VwQihlbGVtZW50LCBuZXcgT25lU3ViR3JvdXAoKSk7Ci0gICAgICAgIGludCBsZW4gPSBncm91cEIubGVuZ3RoLCBybGVuID0gMDsKLSAgICAgICAgWFNFbGVtZW50RGVjbFtdIHJldCA9IG5ldyBYU0VsZW1lbnREZWNsW2xlbl07Ci0gICAgICAgIC8vIEZvciBlYWNoIG9mIHN1Y2ggZWxlbWVudHMsIGNoZWNrIHdoZXRoZXIgdGhlIGRlcml2YXRpb24gbWV0aG9kcwotICAgICAgICAvLyBvdmVybGFwIHdpdGggImJsb2NrIi4gSWYgbm90LCBhZGQgaXQgdG8gdGhlIHN1YiBncm91cAotICAgICAgICBmb3IgKGludCBpID0gMCA7IGkgPCBsZW47IGkrKykgewotICAgICAgICAgICAgaWYgKChlbGVtZW50LmZCbG9jayAmIGdyb3VwQltpXS5kTWV0aG9kKSA9PSAwKQotICAgICAgICAgICAgICAgIHJldFtybGVuKytdID0gZ3JvdXBCW2ldLnN1YjsKLSAgICAgICAgfQotICAgICAgICAvLyBSZXNpemUgdGhlIGFycmF5IGlmIG5lY2Vzc2FyeQotICAgICAgICBpZiAocmxlbiA8IGxlbikgewotICAgICAgICAgICAgWFNFbGVtZW50RGVjbFtdIHJldDEgPSBuZXcgWFNFbGVtZW50RGVjbFtybGVuXTsKLSAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkocmV0LCAwLCByZXQxLCAwLCBybGVuKTsKLSAgICAgICAgICAgIHJldCA9IHJldDE7Ci0gICAgICAgIH0KLSAgICAgICAgLy8gU3RvcmUgdGhlIHN1Ymdyb3VwCi0gICAgICAgIGZTdWJHcm91cHMucHV0KGVsZW1lbnQsIHJldCk7Ci0KLSAgICAgICAgcmV0dXJuIHJldDsKLSAgICB9Ci0KLSAgICAvLyBHZXQgcG90ZW50aWFsIHN1YiBncm91cCBlbGVtZW50ICh3aXRob3V0IGNvbnNpZGVyaW5nICJibG9jayIpCi0gICAgcHJpdmF0ZSBPbmVTdWJHcm91cFtdIGdldFN1Ykdyb3VwQihYU0VsZW1lbnREZWNsIGVsZW1lbnQsIE9uZVN1Ykdyb3VwIG1ldGhvZHMpIHsKLSAgICAgICAgT2JqZWN0IHN1Ykdyb3VwID0gZlN1Ykdyb3Vwc0IuZ2V0KGVsZW1lbnQpOwotCi0gICAgICAgIC8vIHN1YnN0aXR1dGlvbiBncm91cCBmb3IgdGhpcyBvbmUgaXMgZW1wdHkKLSAgICAgICAgaWYgKHN1Ykdyb3VwID09IG51bGwpIHsKLSAgICAgICAgICAgIGZTdWJHcm91cHNCLnB1dChlbGVtZW50LCBFTVBUWV9WRUNUT1IpOwotICAgICAgICAgICAgcmV0dXJuIEVNUFRZX1ZFQ1RPUjsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIHdlJ3ZlIGFscmVhZHkgY2FsY3VsYXRlZCB0aGUgZWxlbWVudCwganVzdCByZXR1cm4uCi0gICAgICAgIGlmIChzdWJHcm91cCBpbnN0YW5jZW9mIE9uZVN1Ykdyb3VwW10pCi0gICAgICAgICAgICByZXR1cm4gKE9uZVN1Ykdyb3VwW10pc3ViR3JvdXA7Ci0KLSAgICAgICAgLy8gd2Ugb25seSBoYXZlIHRoZSAqZGlyZWN0KiBzdWJzdGl0dXRpb25zCi0gICAgICAgIFZlY3RvciBncm91cCA9IChWZWN0b3Ipc3ViR3JvdXAsIG5ld0dyb3VwID0gbmV3IFZlY3RvcigpOwotICAgICAgICBPbmVTdWJHcm91cFtdIGdyb3VwMTsKLSAgICAgICAgLy8gdGhlbiBmb3IgZWFjaCBvZiB0aGUgZGlyZWN0IHN1YnN0aXR1dGlvbnMsIGdldCBpdHMgc3Vic3RpdHV0aW9uCi0gICAgICAgIC8vIGdyb3VwLCBhbmQgY29tYmluZSB0aGUgZ3JvdXBzIHRvZ2V0aGVyLgotICAgICAgICBzaG9ydCBkTWV0aG9kLCBiTWV0aG9kLCBkU3ViTWV0aG9kLCBiU3ViTWV0aG9kOwotICAgICAgICBmb3IgKGludCBpID0gZ3JvdXAuc2l6ZSgpLTEsIGo7IGkgPj0gMDsgaS0tKSB7Ci0gICAgICAgICAgICAvLyBDaGVjayB3aGV0aGVyIHRoaXMgZWxlbWVudCBpcyBibG9ja2VkLiBJZiBzbywgaWdub3JlIGl0LgotICAgICAgICAgICAgWFNFbGVtZW50RGVjbCBzdWIgPSAoWFNFbGVtZW50RGVjbClncm91cC5lbGVtZW50QXQoaSk7Ci0gICAgICAgICAgICBpZiAoIWdldERCTWV0aG9kcyhzdWIuZlR5cGUsIGVsZW1lbnQuZlR5cGUsIG1ldGhvZHMpKQotICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgLy8gUmVtZW1iZXIgZGVyaXZhdGlvbiBtZXRob2RzIGFuZCBibG9ja3MgZnJvbSB0aGUgdHlwZXMKLSAgICAgICAgICAgIGRNZXRob2QgPSBtZXRob2RzLmRNZXRob2Q7Ci0gICAgICAgICAgICBiTWV0aG9kID0gbWV0aG9kcy5iTWV0aG9kOwotICAgICAgICAgICAgLy8gQWRkIHRoaXMgb25lIHRvIHBvdGVudGlhbCBncm91cAotICAgICAgICAgICAgbmV3R3JvdXAuYWRkRWxlbWVudChuZXcgT25lU3ViR3JvdXAoc3ViLCBtZXRob2RzLmRNZXRob2QsIG1ldGhvZHMuYk1ldGhvZCkpOwotICAgICAgICAgICAgLy8gR2V0IHBvdGVudGlhbCBncm91cCBmb3IgdGhpcyBlbGVtZW50Ci0gICAgICAgICAgICBncm91cDEgPSBnZXRTdWJHcm91cEIoc3ViLCBtZXRob2RzKTsKLSAgICAgICAgICAgIGZvciAoaiA9IGdyb3VwMS5sZW5ndGgtMTsgaiA+PSAwOyBqLS0pIHsKLSAgICAgICAgICAgICAgICAvLyBGb3IgZWFjaCBvZiB0aGVtLCBjaGVjayB3aGV0aGVyIGl0J3MgYmxvY2tlZCAoYnkgdHlwZSkKLSAgICAgICAgICAgICAgICBkU3ViTWV0aG9kID0gKHNob3J0KShkTWV0aG9kIHwgZ3JvdXAxW2pdLmRNZXRob2QpOwotICAgICAgICAgICAgICAgIGJTdWJNZXRob2QgPSAoc2hvcnQpKGJNZXRob2QgfCBncm91cDFbal0uYk1ldGhvZCk7Ci0gICAgICAgICAgICAgICAgLy8gSWdub3JlIGl0IGlmIGl0J3MgYmxvY2tlZAotICAgICAgICAgICAgICAgIGlmICgoZFN1Yk1ldGhvZCAmIGJTdWJNZXRob2QpICE9IDApCi0gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgICAgIG5ld0dyb3VwLmFkZEVsZW1lbnQobmV3IE9uZVN1Ykdyb3VwKGdyb3VwMVtqXS5zdWIsIGRTdWJNZXRob2QsIGJTdWJNZXRob2QpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICAvLyBDb252ZXJ0IHRvIGFuIGFycmF5Ci0gICAgICAgIE9uZVN1Ykdyb3VwW10gcmV0ID0gbmV3IE9uZVN1Ykdyb3VwW25ld0dyb3VwLnNpemUoKV07Ci0gICAgICAgIGZvciAoaW50IGkgPSBuZXdHcm91cC5zaXplKCktMTsgaSA+PSAwOyBpLS0pIHsKLSAgICAgICAgICAgIHJldFtpXSA9IChPbmVTdWJHcm91cCluZXdHcm91cC5lbGVtZW50QXQoaSk7Ci0gICAgICAgIH0KLSAgICAgICAgLy8gU3RvcmUgdGhlIHBvdGVudGlhbCBzdWIgZ3JvdXAKLSAgICAgICAgZlN1Ykdyb3Vwc0IucHV0KGVsZW1lbnQsIHJldCk7Ci0KLSAgICAgICAgcmV0dXJuIHJldDsKLSAgICB9Ci0KLSAgICBwcml2YXRlIGJvb2xlYW4gZ2V0REJNZXRob2RzKFhTVHlwZURlZmluaXRpb24gdHlwZWQsIFhTVHlwZURlZmluaXRpb24gdHlwZWIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPbmVTdWJHcm91cCBtZXRob2RzKSB7Ci0gICAgICAgIHNob3J0IGRNZXRob2QgPSAwLCBiTWV0aG9kID0gMDsKLSAgICAgICAgd2hpbGUgKHR5cGVkICE9IHR5cGViICYmIHR5cGVkICE9IFNjaGVtYUdyYW1tYXIuZkFueVR5cGUpIHsKLSAgICAgICAgICAgIGlmICh0eXBlZC5nZXRUeXBlQ2F0ZWdvcnkoKSA9PSBYU1R5cGVEZWZpbml0aW9uLkNPTVBMRVhfVFlQRSkKLSAgICAgICAgICAgICAgICBkTWV0aG9kIHw9ICgoWFNDb21wbGV4VHlwZURlY2wpdHlwZWQpLmZEZXJpdmVkQnk7Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgZE1ldGhvZCB8PSBYU0NvbnN0YW50cy5ERVJJVkFUSU9OX1JFU1RSSUNUSU9OOwotICAgICAgICAgICAgdHlwZWQgPSB0eXBlZC5nZXRCYXNlVHlwZSgpOwotICAgICAgICAgICAgLy8gdHlwZSA9PSBudWxsIG1lYW5zIHRoZSBjdXJyZW50IHR5cGUgaXMgYW55U2ltcGxlVHlwZSwKLSAgICAgICAgICAgIC8vIHdob3NlIGJhc2UgdHlwZSBzaG91bGQgYmUgYW55VHlwZQotICAgICAgICAgICAgaWYgKHR5cGVkID09IG51bGwpCi0gICAgICAgICAgICAgICAgdHlwZWQgPSBTY2hlbWFHcmFtbWFyLmZBbnlUeXBlOwotICAgICAgICAgICAgaWYgKHR5cGVkLmdldFR5cGVDYXRlZ29yeSgpID09IFhTVHlwZURlZmluaXRpb24uQ09NUExFWF9UWVBFKQotICAgICAgICAgICAgICAgIGJNZXRob2QgfD0gKChYU0NvbXBsZXhUeXBlRGVjbCl0eXBlZCkuZkJsb2NrOwotICAgICAgICB9Ci0gICAgICAgIC8vIE5vIGRlcml2YXRpb24gcmVsYXRpb24sIG9yIGJsb2NrZWQsIHJldHVybiBmYWxzZQotICAgICAgICBpZiAodHlwZWQgIT0gdHlwZWIgfHwgKGRNZXRob2QgJiBiTWV0aG9kKSAhPSAwKQotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotCi0gICAgICAgIC8vIFJlbWVtYmVyIHRoZSBkZXJpdmF0aW9uIG1ldGhvZHMgYW5kIGJsb2NrcywgcmV0dXJuIHRydWUuCi0gICAgICAgIG1ldGhvZHMuZE1ldGhvZCA9IGRNZXRob2Q7Ci0gICAgICAgIG1ldGhvZHMuYk1ldGhvZCA9IGJNZXRob2Q7Ci0gICAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotICAgIC8vIFJlY29yZCB0aGUgaW5mb3JtYXRpb24gYWJvdXQgaG93IG9uZSBlbGVtZW50IHN1YnN0aXR1dGUgYW5vdGhlciBvbmUKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBPbmVTdWJHcm91cCB7Ci0gICAgICAgIE9uZVN1Ykdyb3VwKCkge30KLSAgICAgICAgT25lU3ViR3JvdXAoWFNFbGVtZW50RGVjbCBzdWIsIHNob3J0IGRNZXRob2QsIHNob3J0IGJNZXRob2QpIHsKLSAgICAgICAgICAgIHRoaXMuc3ViID0gc3ViOwotICAgICAgICAgICAgdGhpcy5kTWV0aG9kID0gZE1ldGhvZDsKLSAgICAgICAgICAgIHRoaXMuYk1ldGhvZCA9IGJNZXRob2Q7Ci0gICAgICAgIH0KLSAgICAgICAgLy8gVGhlIGVsZW1lbnQgdGhhdCBzdWJzdGl0dXRlcyBhbm90aGVyIG9uZQotICAgICAgICBYU0VsZW1lbnREZWNsIHN1YjsKLSAgICAgICAgLy8gVGhlIGNvbWJpbmF0aW9uIG9mIGFsbCBkZXJpdmF0aW9uIG1ldGhvZHMgZnJvbSBzdWIncyB0eXBlIHRvCi0gICAgICAgIC8vIHRoZSBoZWFkJ3MgdHlwZQotICAgICAgICBzaG9ydCBkTWV0aG9kOwotICAgICAgICAvLyBUaGUgY29tYmluYXRpb24gb2Yge2Jsb2NrfSBvZiB0aGUgdHlwZXMgaW4gdGhlIGRlcml2YXRpb24gY2hhaW4KLSAgICAgICAgLy8gZXhjbHVkaW5nIHN1YidzIHR5cGUKLSAgICAgICAgc2hvcnQgYk1ldGhvZDsKLSAgICB9Ci19IC8vIGNsYXNzIFN1YnN0aXR1dGlvbkdyb3VwSGFuZGxlcgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9YTUxTY2hlbWFFeGNlcHRpb24uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvWE1MU2NoZW1hRXhjZXB0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDQ4YmM3MzMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9YTUxTY2hlbWFFeGNlcHRpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDUzICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEsIDIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54czsKLQotLyoqCi0gKiBUaGlzIGV4Y2VwdGlvbiBtaWdodCBiZSB0aHJvd24gYnkgYW55IGNvbnN0cmFpbnQgY2hlY2tpbmcgbWV0aG9kLgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIEVsZW5hIExpdGFuaSwgSUJNCi0gKgotICovCi1wdWJsaWMgY2xhc3MgWE1MU2NoZW1hRXhjZXB0aW9uIGV4dGVuZHMgRXhjZXB0aW9uIHsKLQotICAgIC8qKiBTZXJpYWxpemF0aW9uIHZlcnNpb24uICovCi0gICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC05MDk2OTg0NjQ4NTM3MDQ2MjE4TDsKLQotICAgIC8vIHN0b3JlIGEgZGF0YXR5cGUgZXJyb3I6IGVycm9yIGNvZGUgcGx1cyB0aGUgYXJndW1lbnRzCi0gICAgU3RyaW5nIGtleTsKLSAgICBPYmplY3RbXSBhcmdzOwotCi0gICAgLy8gcmVwb3J0IGFuIGVycm9yCi0gICAgcHVibGljIFhNTFNjaGVtYUV4Y2VwdGlvbihTdHJpbmcga2V5LCBPYmplY3RbXSBhcmdzKSB7Ci0gICAgICAgIHRoaXMua2V5ID0ga2V5OwotICAgICAgICB0aGlzLmFyZ3MgPSBhcmdzOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0S2V5KCkgewotICAgICAgICByZXR1cm4ga2V5OwotICAgIH0KLQotICAgIHB1YmxpYyBPYmplY3RbXSBnZXRBcmdzKCkgewotICAgICAgICByZXR1cm4gYXJnczsKLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvWE1MU2NoZW1hTG9hZGVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL1hNTFNjaGVtYUxvYWRlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzZTNlYzYzLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvWE1MU2NoZW1hTG9hZGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMzk0ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKi8KLS8qCi0gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKLSAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAotICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgotICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKLSAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCi0gKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54czsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tLkRPTUVycm9ySW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbS5ET01NZXNzYWdlRm9ybWF0dGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tLkRPTVN0cmluZ0xpc3RJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5Db25zdGFudHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLlhNTEVudGl0eU1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLlhNTEVycm9yUmVwb3J0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LkludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5TY2hlbWFEVkZhY3Rvcnk7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LnhzLlNjaGVtYURWRmFjdG9yeUltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLm1vZGVscy5DTUJ1aWxkZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLm1vZGVscy5DTU5vZGVGYWN0b3J5OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy50cmF2ZXJzZXJzLlhTREhhbmRsZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLkRPTUVudGl0eVJlc29sdmVyV3JhcHBlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuRE9NRXJyb3JIYW5kbGVyV3JhcHBlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuRGVmYXVsdEVycm9ySGFuZGxlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuUGFyc2VyQ29uZmlndXJhdGlvblNldHRpbmdzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5TdGF0dXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlN5bWJvbFRhYmxlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5YTUxTeW1ib2xzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbHMuU2VjdXJpdHlTdXBwb3J0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbHMuWE1MU2VjdXJpdHlNYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbHMuWE1MU2VjdXJpdHlQcm9wZXJ0eU1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE5JRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLmdyYW1tYXJzLkdyYW1tYXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuZ3JhbW1hcnMuWE1MR3JhbW1hckRlc2NyaXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLmdyYW1tYXJzLlhNTEdyYW1tYXJMb2FkZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuZ3JhbW1hcnMuWE1MR3JhbW1hclBvb2w7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuZ3JhbW1hcnMuWFNHcmFtbWFyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxDb21wb25lbnQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTENvbXBvbmVudE1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTEVudGl0eVJlc29sdmVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxFcnJvckhhbmRsZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTElucHV0U291cmNlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuTFNJbnB1dExpc3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5TdHJpbmdMaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNMb2FkZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU01vZGVsOwotaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRJbnB1dFN0cmVhbTsKLWltcG9ydCBqYXZhLmlvLkZpbGU7Ci1pbXBvcnQgamF2YS5pby5GaWxlSW5wdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5pby5GaWxlTm90Rm91bmRFeGNlcHRpb247Ci1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uUmVhZGVyOwotaW1wb3J0IGphdmEuaW8uU3RyaW5nUmVhZGVyOwotaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwotaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7Ci1pbXBvcnQgamF2YS51dGlsLk1hcDsKLWltcG9ydCBqYXZhLnV0aWwuU3RyaW5nVG9rZW5pemVyOwotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci1pbXBvcnQgamF2YXgueG1sLlhNTENvbnN0YW50czsKLWltcG9ydCBvcmcudzNjLmRvbS5ET01Db25maWd1cmF0aW9uOwotaW1wb3J0IG9yZy53M2MuZG9tLkRPTUVycm9yOwotaW1wb3J0IG9yZy53M2MuZG9tLkRPTUVycm9ySGFuZGxlcjsKLWltcG9ydCBvcmcudzNjLmRvbS5ET01FeGNlcHRpb247Ci1pbXBvcnQgb3JnLnczYy5kb20uRE9NU3RyaW5nTGlzdDsKLWltcG9ydCBvcmcudzNjLmRvbS5scy5MU0lucHV0OwotaW1wb3J0IG9yZy53M2MuZG9tLmxzLkxTUmVzb3VyY2VSZXNvbHZlcjsKLWltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGltcGxlbWVudHMgeG5pLmdyYW1tYXJzLlhNTEdyYW1tYXJMb2FkZXIuCi0gKiBJdCBhbHNvIHNlcnZlcyBhcyBpbXBsZW1lbnRhdGlvbiBvZiB4cy5YU0xvYWRlciBpbnRlcmZhY2UgYW5kIERPTUNvbmZpZ3VyYXRpb24gaW50ZXJmYWNlLgotICoKLSAqIFRoaXMgY2xhc3MgaXMgZGVzaWduZWQgdG8gaW50ZXJhY3QgZWl0aGVyIHdpdGggYSBwcm94eSBmb3IgYSB1c2VyIGFwcGxpY2F0aW9uCi0gKiB3aGljaCB3YW50cyB0byBwcmVwYXJzZSBzY2hlbWFzLCBvciB3aXRoIG91ciBvd24gU2NoZW1hIHZhbGlkYXRvci4KLSAqIEl0IGlzIGhvcGVkIHRoYXQgbm9uZSBvZiB0aGVzZSAiZXh0ZXJuYWwiIGNsYXNzZXMgd2lsbCB0aGVyZWZvcmUgbmVlZCB0byBjb21tdW5pY2F0ZSBkaXJlY3RseQotICogd2l0aCBYU0RIYW5kbGVyIGluIGZ1dHVyZS4KLSAqIDxwPlRoaXMgY2xhc3Mgb25seSBrbm93cyBob3cgdG8gbWFrZSBYU0RIYW5kbGVyIGRvIGl0cyB0aGluZy4KLSAqIFRoZSBjYWxsZXIgbXVzdCBlbnN1cmUgdGhhdCBhbGwgaXRzIHByb3BlcnRpZXMgKHNjaGVtYUxvY2F0aW9uLCBKQVhQU2NoZW1hU291cmNlCi0gKiBldGMuKSBoYXZlIGJlZW4gcHJvcGVybHkgc2V0LgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIE5laWwgR3JhaGFtLCBJQk0KLSAqIEB2ZXJzaW9uICRJZDogWE1MU2NoZW1hTG9hZGVyLmphdmEsdiAxLjEwIDIwMTAtMTEtMDEgMDQ6Mzk6NTUgam9laHcgRXhwICQKLSAqLwotCi1wdWJsaWMgY2xhc3MgWE1MU2NoZW1hTG9hZGVyIGltcGxlbWVudHMgWE1MR3JhbW1hckxvYWRlciwgWE1MQ29tcG9uZW50LAotLy8gWE1MIENvbXBvbmVudCBBUEkKLVhTTG9hZGVyLCBET01Db25maWd1cmF0aW9uIHsKLQotICAgIC8vIEZlYXR1cmUgaWRlbnRpZmllcnM6Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiBzY2hlbWEgZnVsbCBjaGVja2luZyovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgU0NIRU1BX0ZVTExfQ0hFQ0tJTkcgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLlNDSEVNQV9GVUxMX0NIRUNLSU5HOwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogY29udGludWUgYWZ0ZXIgZmF0YWwgZXJyb3IuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ09OVElOVUVfQUZURVJfRkFUQUxfRVJST1IgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLkNPTlRJTlVFX0FGVEVSX0ZBVEFMX0VSUk9SX0ZFQVRVUkU7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiBhbGxvdyBqYXZhIGVuY29kaW5ncyB0byBiZSByZWNvZ25pemVkIHdoZW4gcGFyc2luZyBzY2hlbWEgZG9jcy4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBBTExPV19KQVZBX0VOQ09ESU5HUyA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuQUxMT1dfSkFWQV9FTkNPRElOR1NfRkVBVFVSRTsKLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IHN0YW5kYXJkIHVyaSBjb25mb3JtYW50IGZlYXR1cmUuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1RBTkRBUkRfVVJJX0NPTkZPUk1BTlRfRkVBVFVSRSA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuU1RBTkRBUkRfVVJJX0NPTkZPUk1BTlRfRkVBVFVSRTsKLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IHZhbGlkYXRlIGFubm90YXRpb25zLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFZBTElEQVRFX0FOTk9UQVRJT05TID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5WQUxJREFURV9BTk5PVEFUSU9OU19GRUFUVVJFOwotCi0gICAgLyoqIEZlYXR1cmU6IGRpc2FsbG93IGRvY3R5cGUqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIERJU0FMTE9XX0RPQ1RZUEUgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLkRJU0FMTE9XX0RPQ1RZUEVfREVDTF9GRUFUVVJFOwotCi0gICAgLyoqIEZlYXR1cmU6IGdlbmVyYXRlIHN5bnRoZXRpYyBhbm5vdGF0aW9ucyAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIEdFTkVSQVRFX1NZTlRIRVRJQ19BTk5PVEFUSU9OUyA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuR0VORVJBVEVfU1lOVEhFVElDX0FOTk9UQVRJT05TX0ZFQVRVUkU7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiBob25vdXIgYWxsIHNjaGVtYUxvY2F0aW9ucyAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIEhPTk9VUl9BTExfU0NIRU1BTE9DQVRJT05TID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5IT05PVVJfQUxMX1NDSEVNQUxPQ0FUSU9OU19GRUFUVVJFOwotCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVVHTUVOVF9QU1ZJID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5TQ0hFTUFfQVVHTUVOVF9QU1ZJOwotCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgUEFSU0VSX1NFVFRJTkdTID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5QQVJTRVJfU0VUVElOR1M7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiBuYW1lc3BhY2UgZ3Jvd3RoICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgTkFNRVNQQUNFX0dST1dUSCA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuTkFNRVNQQUNFX0dST1dUSF9GRUFUVVJFOwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogdG9sZXJhdGUgZHVwbGljYXRlcyAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFRPTEVSQVRFX0RVUExJQ0FURVMgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLlRPTEVSQVRFX0RVUExJQ0FURVNfRkVBVFVSRTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBTY2hlbWEgRFYgRmFjdG9yeSAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFNDSEVNQV9EVl9GQUNUT1JZID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuU0NIRU1BX0RWX0ZBQ1RPUllfUFJPUEVSVFk7Ci0KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBVU0VfU0VSVklDRV9NRUNIQU5JU00gPSBDb25zdGFudHMuT1JBQ0xFX0ZFQVRVUkVfU0VSVklDRV9NRUNIQU5JU007Ci0KLSAgICAvLyByZWNvZ25pemVkIGZlYXR1cmVzOgotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZ1tdIFJFQ09HTklaRURfRkVBVFVSRVMgPSB7Ci0gICAgICAgIFNDSEVNQV9GVUxMX0NIRUNLSU5HLAotICAgICAgICBBVUdNRU5UX1BTVkksCi0gICAgICAgIENPTlRJTlVFX0FGVEVSX0ZBVEFMX0VSUk9SLAotICAgICAgICBBTExPV19KQVZBX0VOQ09ESU5HUywKLSAgICAgICAgU1RBTkRBUkRfVVJJX0NPTkZPUk1BTlRfRkVBVFVSRSwKLSAgICAgICAgRElTQUxMT1dfRE9DVFlQRSwKLSAgICAgICAgR0VORVJBVEVfU1lOVEhFVElDX0FOTk9UQVRJT05TLAotICAgICAgICBWQUxJREFURV9BTk5PVEFUSU9OUywKLSAgICAgICAgSE9OT1VSX0FMTF9TQ0hFTUFMT0NBVElPTlMsCi0gICAgICAgIE5BTUVTUEFDRV9HUk9XVEgsCi0gICAgICAgIFRPTEVSQVRFX0RVUExJQ0FURVMsCi0gICAgICAgIFVTRV9TRVJWSUNFX01FQ0hBTklTTQotICAgIH07Ci0KLSAgICAvLyBwcm9wZXJ0eSBpZGVudGlmaWVycwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IHN5bWJvbCB0YWJsZS4gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBTWU1CT0xfVEFCTEUgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5TWU1CT0xfVEFCTEVfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogZXJyb3IgcmVwb3J0ZXIuICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJST1JfUkVQT1JURVIgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5FUlJPUl9SRVBPUlRFUl9QUk9QRVJUWTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBlcnJvciBoYW5kbGVyLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUk9SX0hBTkRMRVIgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5FUlJPUl9IQU5ETEVSX1BST1BFUlRZOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IGVudGl0eSByZXNvbHZlci4gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFTlRJVFlfUkVTT0xWRVIgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5FTlRJVFlfUkVTT0xWRVJfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogZ3JhbW1hciBwb29sLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFhNTEdSQU1NQVJfUE9PTCA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLlhNTEdSQU1NQVJfUE9PTF9QUk9QRVJUWTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBzY2hlbWEgbG9jYXRpb24uICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgU0NIRU1BX0xPQ0FUSU9OID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuU0NIRU1BX0xPQ0FUSU9OOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IG5vIG5hbWVzcGFjZSBzY2hlbWEgbG9jYXRpb24uICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgU0NIRU1BX05PTlNfTE9DQVRJT04gPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5TQ0hFTUFfTk9OU19MT0NBVElPTjsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBKQVhQIHNjaGVtYSBzb3VyY2UuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgSkFYUF9TQ0hFTUFfU09VUkNFID0KLSAgICAgICAgQ29uc3RhbnRzLkpBWFBfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLlNDSEVNQV9TT1VSQ0U7Ci0KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBTRUNVUklUWV9NQU5BR0VSID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuU0VDVVJJVFlfTUFOQUdFUl9QUk9QRVJUWTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBsb2NhbGUuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgTE9DQUxFID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuTE9DQUxFX1BST1BFUlRZOwotCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgRU5USVRZX01BTkFHRVIgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5FTlRJVFlfTUFOQUdFUl9QUk9QRVJUWTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBTZWN1cml0eSBwcm9wZXJ0eSBtYW5hZ2VyLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxfU0VDVVJJVFlfUFJPUEVSVFlfTUFOQUdFUiA9Ci0gICAgICAgICAgICBDb25zdGFudHMuWE1MX1NFQ1VSSVRZX1BST1BFUlRZX01BTkFHRVI7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogYWNjZXNzIHRvIGV4dGVybmFsIGR0ZCAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEFDQ0VTU19FWFRFUk5BTF9EVEQgPSBYTUxDb25zdGFudHMuQUNDRVNTX0VYVEVSTkFMX0RURDsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBhY2Nlc3MgdG8gZXh0ZXJuYWwgc2NoZW1hICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQUNDRVNTX0VYVEVSTkFMX1NDSEVNQSA9IFhNTENvbnN0YW50cy5BQ0NFU1NfRVhURVJOQUxfU0NIRU1BOwotCi0gICAgLy8gcmVjb2duaXplZCBwcm9wZXJ0aWVzCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFtdIFJFQ09HTklaRURfUFJPUEVSVElFUyA9IHsKLSAgICAgICAgRU5USVRZX01BTkFHRVIsCi0gICAgICAgIFNZTUJPTF9UQUJMRSwKLSAgICAgICAgRVJST1JfUkVQT1JURVIsCi0gICAgICAgIEVSUk9SX0hBTkRMRVIsCi0gICAgICAgIEVOVElUWV9SRVNPTFZFUiwKLSAgICAgICAgWE1MR1JBTU1BUl9QT09MLAotICAgICAgICBTQ0hFTUFfTE9DQVRJT04sCi0gICAgICAgIFNDSEVNQV9OT05TX0xPQ0FUSU9OLAotICAgICAgICBKQVhQX1NDSEVNQV9TT1VSQ0UsCi0gICAgICAgIFNFQ1VSSVRZX01BTkFHRVIsCi0gICAgICAgIExPQ0FMRSwKLSAgICAgICAgU0NIRU1BX0RWX0ZBQ1RPUlksCi0gICAgICAgIFhNTF9TRUNVUklUWV9QUk9QRVJUWV9NQU5BR0VSCi0gICAgfTsKLQotICAgIC8vIERhdGEKLQotICAgIC8vIGZlYXR1cmVzIGFuZCBwcm9wZXJ0aWVzCi0gICAgcHJpdmF0ZSBQYXJzZXJDb25maWd1cmF0aW9uU2V0dGluZ3MgZkxvYWRlckNvbmZpZyA9IG5ldyBQYXJzZXJDb25maWd1cmF0aW9uU2V0dGluZ3MoKTsKLSAgICBwcml2YXRlIFN5bWJvbFRhYmxlIGZTeW1ib2xUYWJsZSA9IG51bGw7Ci0gICAgcHJpdmF0ZSBYTUxFcnJvclJlcG9ydGVyIGZFcnJvclJlcG9ydGVyID0gbmV3IFhNTEVycm9yUmVwb3J0ZXIgKCk7Ci0gICAgcHJpdmF0ZSBYTUxFbnRpdHlNYW5hZ2VyIGZFbnRpdHlNYW5hZ2VyID0gbnVsbDsKLSAgICBwcml2YXRlIFhNTEVudGl0eVJlc29sdmVyIGZVc2VyRW50aXR5UmVzb2x2ZXIgPSBudWxsOwotICAgIHByaXZhdGUgWE1MR3JhbW1hclBvb2wgZkdyYW1tYXJQb29sID0gbnVsbDsKLSAgICBwcml2YXRlIFN0cmluZyBmRXh0ZXJuYWxTY2hlbWFzID0gbnVsbDsKLSAgICBwcml2YXRlIFN0cmluZyBmRXh0ZXJuYWxOb05TU2NoZW1hID0gbnVsbDsKLSAgICAvLyBKQVhQIHByb3BlcnR5OiBzY2hlbWEgc291cmNlCi0gICAgcHJpdmF0ZSBPYmplY3QgZkpBWFBTb3VyY2UgPSBudWxsOwotICAgIC8vIGlzIFNjaGVtYSBGdWxsIENoZWNraW5nIGVuYWJsZWQKLSAgICBwcml2YXRlIGJvb2xlYW4gZklzQ2hlY2tlZEZ1bGx5ID0gZmFsc2U7Ci0gICAgLy8gYm9vbGVhbiB0aGF0IHRlbGxzIHdoZXRoZXIgd2UndmUgdGVzdGVkIHRoZSBKQVhQIHByb3BlcnR5LgotICAgIHByaXZhdGUgYm9vbGVhbiBmSkFYUFByb2Nlc3NlZCA9IGZhbHNlOwotICAgIC8vIGlmIGZlYXR1cmVzL3Byb3BlcnRpZXMgaGFzIG5vdCBiZWVuIGNoYW5nZWQsIHRoZSB2YWx1ZSBvZiB0aGlzIGF0dHJpYnV0ZSBpcyAiZmFsc2UiCi0gICAgcHJpdmF0ZSBib29sZWFuIGZTZXR0aW5nc0NoYW5nZWQgPSB0cnVlOwotCi0gICAgLy8geG1sIHNjaGVtYSBwYXJzaW5nCi0gICAgcHJpdmF0ZSBYU0RIYW5kbGVyIGZTY2hlbWFIYW5kbGVyOwotICAgIHByaXZhdGUgWFNHcmFtbWFyQnVja2V0IGZHcmFtbWFyQnVja2V0OwotICAgIHByaXZhdGUgWFNEZWNsYXJhdGlvblBvb2wgZkRlY2xQb29sID0gbnVsbDsKLSAgICBwcml2YXRlIFN1YnN0aXR1dGlvbkdyb3VwSGFuZGxlciBmU3ViR3JvdXBIYW5kbGVyOwotICAgIHByaXZhdGUgZmluYWwgQ01Ob2RlRmFjdG9yeSBmTm9kZUZhY3RvcnkgPSBuZXcgQ01Ob2RlRmFjdG9yeSgpOyAvL2NvbXBvbmVudCBtZ3Igd2lsbCBiZSBzZXQgbGF0ZXIKLSAgICBwcml2YXRlIENNQnVpbGRlciBmQ01CdWlsZGVyOwotICAgIHByaXZhdGUgWFNERGVzY3JpcHRpb24gZlhTRERlc2NyaXB0aW9uID0gbmV3IFhTRERlc2NyaXB0aW9uKCk7Ci0gICAgcHJpdmF0ZSBTdHJpbmcgZmFjY2Vzc0V4dGVybmFsU2NoZW1hID0gQ29uc3RhbnRzLkVYVEVSTkFMX0FDQ0VTU19ERUZBVUxUOwotCi0gICAgcHJpdmF0ZSBNYXAgZkpBWFBDYWNoZTsKLSAgICBwcml2YXRlIExvY2FsZSBmTG9jYWxlID0gTG9jYWxlLmdldERlZmF1bHQoKTsKLQotICAgIC8vIFhTTG9hZGVyIGF0dHJpYnV0ZXMKLSAgICBwcml2YXRlIERPTVN0cmluZ0xpc3QgZlJlY29nbml6ZWRQYXJhbWV0ZXJzID0gbnVsbDsKLQotICAgIC8qKiBET00gTDMgZXJyb3IgaGFuZGxlciAqLwotICAgIHByaXZhdGUgRE9NRXJyb3JIYW5kbGVyV3JhcHBlciBmRXJyb3JIYW5kbGVyID0gbnVsbDsKLQotICAgIC8qKiBET00gTDMgcmVzb3VyY2UgcmVzb2x2ZXIgKi8KLSAgICBwcml2YXRlIERPTUVudGl0eVJlc29sdmVyV3JhcHBlciBmUmVzb3VyY2VSZXNvbHZlciA9IG51bGw7Ci0KLSAgICAvLyBkZWZhdWx0IGNvbnN0cnVjdG9yLiAgQ3JlYXRlIG9iamVjdHMgd2UgYWJzb2x1dGVseSBuZWVkOgotICAgIHB1YmxpYyBYTUxTY2hlbWFMb2FkZXIoKSB7Ci0gICAgICAgIHRoaXMoIG5ldyBTeW1ib2xUYWJsZSgpLCBudWxsLCBuZXcgWE1MRW50aXR5TWFuYWdlcigpLCBudWxsLCBudWxsLCBudWxsKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgWE1MU2NoZW1hTG9hZGVyKFN5bWJvbFRhYmxlIHN5bWJvbFRhYmxlKSB7Ci0gICAgICAgIHRoaXMoIHN5bWJvbFRhYmxlLCBudWxsLCBuZXcgWE1MRW50aXR5TWFuYWdlcigpLCBudWxsLCBudWxsLCBudWxsKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIGNvbnN0cmFjdG9yIGlzIHVzZWQgYnkgdGhlIFhNTFNjaGVtYVZhbGlkYXRvci4gQWRkaXRpb25hbCBwcm9wZXJ0aWVzLCBpLmUuIFhNTEVudGl0eU1hbmFnZXIsCi0gICAgICogd2lsbCBiZSBwYXNzZWQgZHVyaW5nIHJlc2V0KFhNTENvbXBvbmVudE1hbmFnZXIpLgotICAgICAqIEBwYXJhbSBlcnJvclJlcG9ydGVyCi0gICAgICogQHBhcmFtIGdyYW1tYXJCdWNrZXQKLSAgICAgKiBAcGFyYW0gc0hhbmRsZXIKLSAgICAgKiBAcGFyYW0gYnVpbGRlcgotICAgICAqLwotICAgIFhNTFNjaGVtYUxvYWRlcihYTUxFcnJvclJlcG9ydGVyIGVycm9yUmVwb3J0ZXIsCi0gICAgICAgICAgICBYU0dyYW1tYXJCdWNrZXQgZ3JhbW1hckJ1Y2tldCwKLSAgICAgICAgICAgIFN1YnN0aXR1dGlvbkdyb3VwSGFuZGxlciBzSGFuZGxlciwgQ01CdWlsZGVyIGJ1aWxkZXIpIHsKLSAgICAgICAgdGhpcyhudWxsLCBlcnJvclJlcG9ydGVyLCBudWxsLCBncmFtbWFyQnVja2V0LCBzSGFuZGxlciwgYnVpbGRlcik7Ci0gICAgfQotCi0gICAgWE1MU2NoZW1hTG9hZGVyKFN5bWJvbFRhYmxlIHN5bWJvbFRhYmxlLAotICAgICAgICAgICAgWE1MRXJyb3JSZXBvcnRlciBlcnJvclJlcG9ydGVyLAotICAgICAgICAgICAgWE1MRW50aXR5TWFuYWdlciBlbnRpdHlSZXNvbHZlciwKLSAgICAgICAgICAgIFhTR3JhbW1hckJ1Y2tldCBncmFtbWFyQnVja2V0LAotICAgICAgICAgICAgU3Vic3RpdHV0aW9uR3JvdXBIYW5kbGVyIHNIYW5kbGVyLAotICAgICAgICAgICAgQ01CdWlsZGVyIGJ1aWxkZXIpIHsKLQotICAgICAgICAvLyBzdG9yZSBwcm9wZXJ0aWVzIGFuZCBmZWF0dXJlcyBpbiBjb25maWd1cmF0aW9uCi0gICAgICAgIGZMb2FkZXJDb25maWcuYWRkUmVjb2duaXplZEZlYXR1cmVzKFJFQ09HTklaRURfRkVBVFVSRVMpOwotICAgICAgICBmTG9hZGVyQ29uZmlnLmFkZFJlY29nbml6ZWRQcm9wZXJ0aWVzKFJFQ09HTklaRURfUFJPUEVSVElFUyk7Ci0gICAgICAgIGlmIChzeW1ib2xUYWJsZSAhPSBudWxsKXsKLSAgICAgICAgICAgIGZMb2FkZXJDb25maWcuc2V0UHJvcGVydHkoU1lNQk9MX1RBQkxFLCBzeW1ib2xUYWJsZSk7Ci0gICAgICAgIH0KLQotICAgICAgICBpZihlcnJvclJlcG9ydGVyID09IG51bGwpIHsKLSAgICAgICAgICAgIGVycm9yUmVwb3J0ZXIgPSBuZXcgWE1MRXJyb3JSZXBvcnRlciAoKTsKLSAgICAgICAgICAgIGVycm9yUmVwb3J0ZXIuc2V0TG9jYWxlKGZMb2NhbGUpOwotICAgICAgICAgICAgZXJyb3JSZXBvcnRlci5zZXRQcm9wZXJ0eShFUlJPUl9IQU5ETEVSLCBuZXcgRGVmYXVsdEVycm9ySGFuZGxlcigpKTsKLQotICAgICAgICB9Ci0gICAgICAgIGZFcnJvclJlcG9ydGVyID0gZXJyb3JSZXBvcnRlcjsKLSAgICAgICAgLy8gbWFrZSBzdXJlIGVycm9yIHJlcG9ydGVyIGtub3dzIGFib3V0IHNjaGVtYXMuLi4KLSAgICAgICAgaWYoZkVycm9yUmVwb3J0ZXIuZ2V0TWVzc2FnZUZvcm1hdHRlcihYU01lc3NhZ2VGb3JtYXR0ZXIuU0NIRU1BX0RPTUFJTikgPT0gbnVsbCkgewotICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucHV0TWVzc2FnZUZvcm1hdHRlcihYU01lc3NhZ2VGb3JtYXR0ZXIuU0NIRU1BX0RPTUFJTiwgbmV3IFhTTWVzc2FnZUZvcm1hdHRlcigpKTsKLSAgICAgICAgfQotICAgICAgICBmTG9hZGVyQ29uZmlnLnNldFByb3BlcnR5KEVSUk9SX1JFUE9SVEVSLCBmRXJyb3JSZXBvcnRlcik7Ci0gICAgICAgIGZFbnRpdHlNYW5hZ2VyID0gZW50aXR5UmVzb2x2ZXI7Ci0gICAgICAgIC8vIGVudGl0eSBtYW5hZ2VyIGlzIG51bGwgaWYgWE1MU2NoZW1hVmFsaWRhdG9yIGNyZWF0ZXMgdGhlIGxvYWRlcgotICAgICAgICBpZiAoZkVudGl0eU1hbmFnZXIgIT0gbnVsbCl7Ci0gICAgICAgICAgICBmTG9hZGVyQ29uZmlnLnNldFByb3BlcnR5KEVOVElUWV9NQU5BR0VSLCBmRW50aXR5TWFuYWdlcik7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBieSBkZWZhdWx0IGF1Z21lbnQgUFNWSSAoaS5lLiBkb24ndCB1c2UgZGVjbGFyYXRpb24gcG9vbCkKLSAgICAgICAgZkxvYWRlckNvbmZpZy5zZXRGZWF0dXJlKEFVR01FTlRfUFNWSSwgdHJ1ZSk7Ci0KLSAgICAgICAgaWYoZ3JhbW1hckJ1Y2tldCA9PSBudWxsICkgewotICAgICAgICAgICAgZ3JhbW1hckJ1Y2tldCA9IG5ldyBYU0dyYW1tYXJCdWNrZXQoKTsKLSAgICAgICAgfQotICAgICAgICBmR3JhbW1hckJ1Y2tldCA9IGdyYW1tYXJCdWNrZXQ7Ci0gICAgICAgIGlmKHNIYW5kbGVyID09IG51bGwpIHsKLSAgICAgICAgICAgIHNIYW5kbGVyID0gbmV3IFN1YnN0aXR1dGlvbkdyb3VwSGFuZGxlcihmR3JhbW1hckJ1Y2tldCk7Ci0gICAgICAgIH0KLSAgICAgICAgZlN1Ykdyb3VwSGFuZGxlciA9IHNIYW5kbGVyOwotCi0gICAgICAgIGlmKGJ1aWxkZXIgPT0gbnVsbCkgewotICAgICAgICAgICAgYnVpbGRlciA9IG5ldyBDTUJ1aWxkZXIoZk5vZGVGYWN0b3J5KTsKLSAgICAgICAgfQotICAgICAgICBmQ01CdWlsZGVyID0gYnVpbGRlcjsKLSAgICAgICAgZlNjaGVtYUhhbmRsZXIgPSBuZXcgWFNESGFuZGxlcihmR3JhbW1hckJ1Y2tldCk7Ci0gICAgICAgIGlmIChmRGVjbFBvb2wgIT0gbnVsbCkgewotICAgICAgICAgICAgZkRlY2xQb29sLnJlc2V0KCk7Ci0gICAgICAgIH0KLSAgICAgICAgZkpBWFBDYWNoZSA9IG5ldyBIYXNoTWFwKCk7Ci0KLSAgICAgICAgZlNldHRpbmdzQ2hhbmdlZCA9IHRydWU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhIGxpc3Qgb2YgZmVhdHVyZSBpZGVudGlmaWVycyB0aGF0IGFyZSByZWNvZ25pemVkIGJ5Ci0gICAgICogdGhpcyBYTUxHcmFtbWFyTG9hZGVyLiAgVGhpcyBtZXRob2QgbWF5IHJldHVybiBudWxsIGlmIG5vIGZlYXR1cmVzCi0gICAgICogYXJlIHJlY29nbml6ZWQuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZ1tdIGdldFJlY29nbml6ZWRGZWF0dXJlcygpIHsKLSAgICAgICAgcmV0dXJuIChTdHJpbmdbXSkoUkVDT0dOSVpFRF9GRUFUVVJFUy5jbG9uZSgpKTsKLSAgICB9IC8vIGdldFJlY29nbml6ZWRGZWF0dXJlcygpOiAgU3RyaW5nW10KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIHN0YXRlIG9mIGEgZmVhdHVyZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBmZWF0dXJlSWQgVGhlIGZlYXR1cmUgaWRlbnRpZmllci4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBUaHJvd24gb24gY29uZmlndXJhdGlvbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXRGZWF0dXJlKFN0cmluZyBmZWF0dXJlSWQpCi0gICAgdGhyb3dzIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gewotICAgICAgICByZXR1cm4gZkxvYWRlckNvbmZpZy5nZXRGZWF0dXJlKGZlYXR1cmVJZCk7Ci0gICAgfSAvLyBnZXRGZWF0dXJlIChTdHJpbmcpOiAgYm9vbGVhbgotCi0gICAgLyoqCi0gICAgICogU2V0cyB0aGUgc3RhdGUgb2YgYSBmZWF0dXJlLgotICAgICAqCi0gICAgICogQHBhcmFtIGZlYXR1cmVJZCBUaGUgZmVhdHVyZSBpZGVudGlmaWVyLgotICAgICAqIEBwYXJhbSBzdGF0ZSAgICAgVGhlIHN0YXRlIG9mIHRoZSBmZWF0dXJlLgotICAgICAqCi0gICAgICogQHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIFRocm93biB3aGVuIGEgZmVhdHVyZSBpcyBub3QKLSAgICAgKiAgICAgICAgICAgICAgICAgIHJlY29nbml6ZWQgb3IgY2Fubm90IGJlIHNldC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRGZWF0dXJlKFN0cmluZyBmZWF0dXJlSWQsCi0gICAgICAgICAgICBib29sZWFuIHN0YXRlKSB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiB7Ci0gICAgICAgIGZTZXR0aW5nc0NoYW5nZWQgPSB0cnVlOwotICAgICAgICBpZihmZWF0dXJlSWQuZXF1YWxzKENPTlRJTlVFX0FGVEVSX0ZBVEFMX0VSUk9SKSkgewotICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIuc2V0RmVhdHVyZShDT05USU5VRV9BRlRFUl9GQVRBTF9FUlJPUiwgc3RhdGUpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYoZmVhdHVyZUlkLmVxdWFscyhHRU5FUkFURV9TWU5USEVUSUNfQU5OT1RBVElPTlMpKSB7Ci0gICAgICAgICAgICBmU2NoZW1hSGFuZGxlci5zZXRHZW5lcmF0ZVN5bnRoZXRpY0Fubm90YXRpb25zKHN0YXRlKTsKLSAgICAgICAgfQotICAgICAgICBmTG9hZGVyQ29uZmlnLnNldEZlYXR1cmUoZmVhdHVyZUlkLCBzdGF0ZSk7Ci0gICAgfSAvLyBzZXRGZWF0dXJlKFN0cmluZywgYm9vbGVhbikKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYSBsaXN0IG9mIHByb3BlcnR5IGlkZW50aWZpZXJzIHRoYXQgYXJlIHJlY29nbml6ZWQgYnkKLSAgICAgKiB0aGlzIFhNTEdyYW1tYXJMb2FkZXIuICBUaGlzIG1ldGhvZCBtYXkgcmV0dXJuIG51bGwgaWYgbm8gcHJvcGVydGllcwotICAgICAqIGFyZSByZWNvZ25pemVkLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmdbXSBnZXRSZWNvZ25pemVkUHJvcGVydGllcygpIHsKLSAgICAgICAgcmV0dXJuIChTdHJpbmdbXSkoUkVDT0dOSVpFRF9QUk9QRVJUSUVTLmNsb25lKCkpOwotICAgIH0gLy8gZ2V0UmVjb2duaXplZFByb3BlcnRpZXMoKTogIFN0cmluZ1tdCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBzdGF0ZSBvZiBhIHByb3BlcnR5LgotICAgICAqCi0gICAgICogQHBhcmFtIHByb3BlcnR5SWQgVGhlIHByb3BlcnR5IGlkZW50aWZpZXIuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gVGhyb3duIG9uIGNvbmZpZ3VyYXRpb24gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIE9iamVjdCBnZXRQcm9wZXJ0eShTdHJpbmcgcHJvcGVydHlJZCkKLSAgICB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiB7Ci0gICAgICAgIHJldHVybiBmTG9hZGVyQ29uZmlnLmdldFByb3BlcnR5KHByb3BlcnR5SWQpOwotICAgIH0gLy8gZ2V0UHJvcGVydHkoU3RyaW5nKTogIE9iamVjdAotCi0gICAgLyoqCi0gICAgICogU2V0cyB0aGUgc3RhdGUgb2YgYSBwcm9wZXJ0eS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBwcm9wZXJ0eUlkIFRoZSBwcm9wZXJ0eSBpZGVudGlmaWVyLgotICAgICAqIEBwYXJhbSBzdGF0ZSAgICAgVGhlIHN0YXRlIG9mIHRoZSBwcm9wZXJ0eS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBUaHJvd24gd2hlbiBhIHByb3BlcnR5IGlzIG5vdAotICAgICAqICAgICAgICAgICAgICAgICAgcmVjb2duaXplZCBvciBjYW5ub3QgYmUgc2V0LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFByb3BlcnR5KFN0cmluZyBwcm9wZXJ0eUlkLAotICAgICAgICAgICAgT2JqZWN0IHN0YXRlKSB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiB7Ci0gICAgICAgIGZTZXR0aW5nc0NoYW5nZWQgPSB0cnVlOwotICAgICAgICBmTG9hZGVyQ29uZmlnLnNldFByb3BlcnR5KHByb3BlcnR5SWQsIHN0YXRlKTsKLSAgICAgICAgaWYgKHByb3BlcnR5SWQuZXF1YWxzKEpBWFBfU0NIRU1BX1NPVVJDRSkpIHsKLSAgICAgICAgICAgIGZKQVhQU291cmNlID0gc3RhdGU7Ci0gICAgICAgICAgICBmSkFYUFByb2Nlc3NlZCA9IGZhbHNlOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKHByb3BlcnR5SWQuZXF1YWxzKFhNTEdSQU1NQVJfUE9PTCkpIHsKLSAgICAgICAgICAgIGZHcmFtbWFyUG9vbCA9IChYTUxHcmFtbWFyUG9vbClzdGF0ZTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChwcm9wZXJ0eUlkLmVxdWFscyhTQ0hFTUFfTE9DQVRJT04pKSB7Ci0gICAgICAgICAgICBmRXh0ZXJuYWxTY2hlbWFzID0gKFN0cmluZylzdGF0ZTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChwcm9wZXJ0eUlkLmVxdWFscyhTQ0hFTUFfTk9OU19MT0NBVElPTikpIHsKLSAgICAgICAgICAgIGZFeHRlcm5hbE5vTlNTY2hlbWEgPSAoU3RyaW5nKSBzdGF0ZTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChwcm9wZXJ0eUlkLmVxdWFscyhMT0NBTEUpKSB7Ci0gICAgICAgICAgICBzZXRMb2NhbGUoKExvY2FsZSkgc3RhdGUpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKHByb3BlcnR5SWQuZXF1YWxzKEVOVElUWV9SRVNPTFZFUikpIHsKLSAgICAgICAgICAgIGZFbnRpdHlNYW5hZ2VyLnNldFByb3BlcnR5KEVOVElUWV9SRVNPTFZFUiwgc3RhdGUpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKHByb3BlcnR5SWQuZXF1YWxzKEVSUk9SX1JFUE9SVEVSKSkgewotICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIgPSAoWE1MRXJyb3JSZXBvcnRlcilzdGF0ZTsKLSAgICAgICAgICAgIGlmIChmRXJyb3JSZXBvcnRlci5nZXRNZXNzYWdlRm9ybWF0dGVyKFhTTWVzc2FnZUZvcm1hdHRlci5TQ0hFTUFfRE9NQUlOKSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucHV0TWVzc2FnZUZvcm1hdHRlcihYU01lc3NhZ2VGb3JtYXR0ZXIuU0NIRU1BX0RPTUFJTiwgbmV3IFhTTWVzc2FnZUZvcm1hdHRlcigpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChwcm9wZXJ0eUlkLmVxdWFscyhYTUxfU0VDVVJJVFlfUFJPUEVSVFlfTUFOQUdFUikpIHsKLSAgICAgICAgICAgIFhNTFNlY3VyaXR5UHJvcGVydHlNYW5hZ2VyIHNwbSA9IChYTUxTZWN1cml0eVByb3BlcnR5TWFuYWdlcilzdGF0ZTsKLSAgICAgICAgICAgIGZhY2Nlc3NFeHRlcm5hbFNjaGVtYSA9IHNwbS5nZXRWYWx1ZShYTUxTZWN1cml0eVByb3BlcnR5TWFuYWdlci5Qcm9wZXJ0eS5BQ0NFU1NfRVhURVJOQUxfU0NIRU1BKTsKLSAgICAgICAgfQotICAgIH0gLy8gc2V0UHJvcGVydHkoU3RyaW5nLCBPYmplY3QpCi0KLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIGxvY2FsZSB0byB1c2UgZm9yIG1lc3NhZ2VzLgotICAgICAqCi0gICAgICogQHBhcmFtIGxvY2FsZSBUaGUgbG9jYWxlIG9iamVjdCB0byB1c2UgZm9yIGxvY2FsaXphdGlvbiBvZiBtZXNzYWdlcy4KLSAgICAgKgotICAgICAqIEBleGNlcHRpb24gWE5JRXhjZXB0aW9uIFRocm93biBpZiB0aGUgcGFyc2VyIGRvZXMgbm90IHN1cHBvcnQgdGhlCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgc3BlY2lmaWVkIGxvY2FsZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRMb2NhbGUoTG9jYWxlIGxvY2FsZSkgewotICAgICAgICBmTG9jYWxlID0gbG9jYWxlOwotICAgICAgICBmRXJyb3JSZXBvcnRlci5zZXRMb2NhbGUobG9jYWxlKTsKLSAgICB9IC8vIHNldExvY2FsZShMb2NhbGUpCi0KLSAgICAvKiogUmV0dXJuIHRoZSBMb2NhbGUgdGhlIFhNTEdyYW1tYXJMb2FkZXIgaXMgdXNpbmcuICovCi0gICAgcHVibGljIExvY2FsZSBnZXRMb2NhbGUoKSB7Ci0gICAgICAgIHJldHVybiBmTG9jYWxlOwotICAgIH0gLy8gZ2V0TG9jYWxlKCk6ICBMb2NhbGUKLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIGVycm9yIGhhbmRsZXIuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZXJyb3JIYW5kbGVyIFRoZSBlcnJvciBoYW5kbGVyLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEVycm9ySGFuZGxlcihYTUxFcnJvckhhbmRsZXIgZXJyb3JIYW5kbGVyKSB7Ci0gICAgICAgIGZFcnJvclJlcG9ydGVyLnNldFByb3BlcnR5KEVSUk9SX0hBTkRMRVIsIGVycm9ySGFuZGxlcik7Ci0gICAgfSAvLyBzZXRFcnJvckhhbmRsZXIoWE1MRXJyb3JIYW5kbGVyKQotCi0gICAgLyoqIFJldHVybnMgdGhlIHJlZ2lzdGVyZWQgZXJyb3IgaGFuZGxlci4gICovCi0gICAgcHVibGljIFhNTEVycm9ySGFuZGxlciBnZXRFcnJvckhhbmRsZXIoKSB7Ci0gICAgICAgIHJldHVybiBmRXJyb3JSZXBvcnRlci5nZXRFcnJvckhhbmRsZXIoKTsKLSAgICB9IC8vIGdldEVycm9ySGFuZGxlcigpOiAgWE1MRXJyb3JIYW5kbGVyCi0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSBlbnRpdHkgcmVzb2x2ZXIuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZW50aXR5UmVzb2x2ZXIgVGhlIG5ldyBlbnRpdHkgcmVzb2x2ZXIuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RW50aXR5UmVzb2x2ZXIoWE1MRW50aXR5UmVzb2x2ZXIgZW50aXR5UmVzb2x2ZXIpIHsKLSAgICAgICAgZlVzZXJFbnRpdHlSZXNvbHZlciA9IGVudGl0eVJlc29sdmVyOwotICAgICAgICBmTG9hZGVyQ29uZmlnLnNldFByb3BlcnR5KEVOVElUWV9SRVNPTFZFUiwgZW50aXR5UmVzb2x2ZXIpOwotICAgICAgICBmRW50aXR5TWFuYWdlci5zZXRQcm9wZXJ0eShFTlRJVFlfUkVTT0xWRVIsIGVudGl0eVJlc29sdmVyKTsKLSAgICB9IC8vIHNldEVudGl0eVJlc29sdmVyKFhNTEVudGl0eVJlc29sdmVyKQotCi0gICAgLyoqIFJldHVybnMgdGhlIHJlZ2lzdGVyZWQgZW50aXR5IHJlc29sdmVyLiAgKi8KLSAgICBwdWJsaWMgWE1MRW50aXR5UmVzb2x2ZXIgZ2V0RW50aXR5UmVzb2x2ZXIoKSB7Ci0gICAgICAgIHJldHVybiBmVXNlckVudGl0eVJlc29sdmVyOwotICAgIH0gLy8gZ2V0RW50aXR5UmVzb2x2ZXIoKTogIFhNTEVudGl0eVJlc29sdmVyCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGEgR3JhbW1hciBvYmplY3QgYnkgcGFyc2luZyB0aGUgY29udGVudHMgb2YgdGhlCi0gICAgICogZW50aXRpZXMgcG9pbnRlZCB0byBieSBzb3VyY2VzLgotICAgICAqCi0gICAgICogQHBhcmFtIHNvdXJjZVtdICB0aGUgbG9jYXRpb25zIG9mIHRoZSBlbnRpdHkgd2hpY2ggZm9ybXMKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICB0aGUgc3RhcmluZyBwb2ludCBvZiB0aGUgZ3JhbW1hcnMgdG8gYmUgY29uc3RydWN0ZWQKLSAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uICB3aGVuIGEgcHJvYmxlbSBpcyBlbmNvdW50ZWQgcmVhZGluZyB0aGUgZW50aXR5Ci0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gd2hlbiBhIGNvbmRpdGlvbiBhcmlzZXMgKHN1Y2ggYXMgYSBGYXRhbEVycm9yKSB0aGF0IHJlcXVpcmVzIHBhcnNpbmcKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgb2YgdGhlIGVudGl0eSBiZSB0ZXJtaW5hdGVkCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgbG9hZEdyYW1tYXIoWE1MSW5wdXRTb3VyY2Ugc291cmNlW10pCi0gICAgdGhyb3dzIElPRXhjZXB0aW9uLCBYTklFeGNlcHRpb24gewotICAgICAgICBpbnQgbnVtU291cmNlID0gc291cmNlLmxlbmd0aDsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW1Tb3VyY2U7ICsraSkgewotICAgICAgICAgICAgbG9hZEdyYW1tYXIoc291cmNlW2ldKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYSBHcmFtbWFyIG9iamVjdCBieSBwYXJzaW5nIHRoZSBjb250ZW50cyBvZiB0aGUKLSAgICAgKiBlbnRpdHkgcG9pbnRlZCB0byBieSBzb3VyY2UuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc291cmNlICAgICAgICB0aGUgbG9jYXRpb24gb2YgdGhlIGVudGl0eSB3aGljaCBmb3JtcwotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICB0aGUgc3RhcnRpbmcgcG9pbnQgb2YgdGhlIGdyYW1tYXIgdG8gYmUgY29uc3RydWN0ZWQuCi0gICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiAgICAgIFdoZW4gYSBwcm9ibGVtIGlzIGVuY291bnRlcmVkIHJlYWRpbmcgdGhlIGVudGl0eQotICAgICAqICAgICAgICAgIFhOSUV4Y2VwdGlvbiAgICBXaGVuIGEgY29uZGl0aW9uIGFyaXNlcyAoc3VjaCBhcyBhIEZhdGFsRXJyb3IpIHRoYXQgcmVxdWlyZXMgcGFyc2luZwotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2YgdGhlIGVudGl0eSBiZSB0ZXJtaW5hdGVkLgotICAgICAqLwotICAgIHB1YmxpYyBHcmFtbWFyIGxvYWRHcmFtbWFyKFhNTElucHV0U291cmNlIHNvdXJjZSkKLSAgICB0aHJvd3MgSU9FeGNlcHRpb24sIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy8gUkVWSVNJVDogdGhpcyBtZXRob2Qgc2hvdWxkIGhhdmUgYSBuYW1lc3BhY2UgcGFyYW1ldGVyIHNwZWNpZmllZCBieQotICAgICAgICAvLyB1c2VyLiBJbiB0aGlzIGNhc2Ugd2UgY2FuIGVhc2lseSBkZXRlY3QgaWYgYSBzY2hlbWEgYXNrZWQgdG8gYmUgbG9hZGVkCi0gICAgICAgIC8vIGlzIGFscmVhZHkgaW4gdGhlIGxvY2FsIGNhY2hlLgotCi0gICAgICAgIHJlc2V0KGZMb2FkZXJDb25maWcpOwotICAgICAgICBmU2V0dGluZ3NDaGFuZ2VkID0gZmFsc2U7Ci0gICAgICAgIFhTRERlc2NyaXB0aW9uIGRlc2MgPSBuZXcgWFNERGVzY3JpcHRpb24oKTsKLSAgICAgICAgZGVzYy5mQ29udGV4dFR5cGUgPSBYU0REZXNjcmlwdGlvbi5DT05URVhUX1BSRVBBUlNFOwotICAgICAgICBkZXNjLnNldEJhc2VTeXN0ZW1JZChzb3VyY2UuZ2V0QmFzZVN5c3RlbUlkKCkpOwotICAgICAgICBkZXNjLnNldExpdGVyYWxTeXN0ZW1JZCggc291cmNlLmdldFN5c3RlbUlkKCkpOwotICAgICAgICAvLyBub25lIG9mIHRoZSBvdGhlciBmaWVsZHMgbWFrZSBzZW5zZSBmb3IgcHJlcGFyc2luZwotICAgICAgICBNYXAgbG9jYXRpb25QYWlycyA9IG5ldyBIYXNoTWFwKCk7Ci0gICAgICAgIC8vIFByb2Nlc3MgZXh0ZXJuYWwgc2NoZW1hIGxvY2F0aW9uIHByb3BlcnRpZXMuCi0gICAgICAgIC8vIFdlIGRvbid0IGNhbGwgdG9rZW5pemVTY2hlbWFMb2NhdGlvblN0ciBoZXJlLCBiZWNhdXNlIHdlIGFsc28gd2FudAotICAgICAgICAvLyB0byBjaGVjayB3aGV0aGVyIHRoZSB2YWx1ZXMgYXJlIHZhbGlkIFVSSS4KLSAgICAgICAgcHJvY2Vzc0V4dGVybmFsSGludHMoZkV4dGVybmFsU2NoZW1hcywgZkV4dGVybmFsTm9OU1NjaGVtYSwKLSAgICAgICAgICAgICAgICBsb2NhdGlvblBhaXJzLCBmRXJyb3JSZXBvcnRlcik7Ci0gICAgICAgIFNjaGVtYUdyYW1tYXIgZ3JhbW1hciA9IGxvYWRTY2hlbWEoZGVzYywgc291cmNlLCBsb2NhdGlvblBhaXJzKTsKLQotICAgICAgICBpZihncmFtbWFyICE9IG51bGwgJiYgZkdyYW1tYXJQb29sICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZHcmFtbWFyUG9vbC5jYWNoZUdyYW1tYXJzKFhNTEdyYW1tYXJEZXNjcmlwdGlvbi5YTUxfU0NIRU1BLCBmR3JhbW1hckJ1Y2tldC5nZXRHcmFtbWFycygpKTsKLSAgICAgICAgICAgIC8vIE5PVEU6IHdlIG9ubHkgbmVlZCB0byB2ZXJpZnkgZnVsbCBjaGVja2luZyBpbiBjYXNlIHRoZSBzY2hlbWEgd2FzIG5vdCBwcm92aWRlZCB2aWEgSkFYUAotICAgICAgICAgICAgLy8gc2luY2UgZnVsbCBjaGVja2luZyBhbHJlYWR5IHZlcmlmaWVkIGZvciBhbGwgSkFYUCBzY2hlbWFzCi0gICAgICAgICAgICBpZihmSXNDaGVja2VkRnVsbHkgJiYgZkpBWFBDYWNoZS5nZXQoZ3JhbW1hcikgIT0gZ3JhbW1hcikgewotICAgICAgICAgICAgICAgIFhTQ29uc3RyYWludHMuZnVsbFNjaGVtYUNoZWNraW5nKGZHcmFtbWFyQnVja2V0LCBmU3ViR3JvdXBIYW5kbGVyLCBmQ01CdWlsZGVyLCBmRXJyb3JSZXBvcnRlcik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGdyYW1tYXI7Ci0gICAgfSAvLyBsb2FkR3JhbW1hcihYTUxJbnB1dFNvdXJjZSk6ICBHcmFtbWFyCi0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgZWl0aGVyIGZyb20gWE1MR3JhbW1hckxvYWRlci5sb2FkR3JhbW1hciBvciBmcm9tIFhNTFNjaGVtYVZhbGlkYXRvci4KLSAgICAgKiBOb3RlOiBpbiBlaXRoZXIgY2FzZSwgdGhlIEVudGl0eU1hbmFnZXIgKG9yIEVudGl0eVJlc29sdmVycykgYXJlIG5vdCBnb2luZyB0byBiZSBpbnZva2VkCi0gICAgICogdG8gcmVzb2x2ZSB0aGUgbG9jYXRpb24gb2YgdGhlIHNjaGVtYSBpbiBYU0REZXNjcmlwdGlvbgotICAgICAqIEBwYXJhbSBkZXNjCi0gICAgICogQHBhcmFtIHNvdXJjZQotICAgICAqIEBwYXJhbSBsb2NhdGlvblBhaXJzCi0gICAgICogQHJldHVybiBBbiBYTUwgU2NoZW1hIGdyYW1tYXIKLSAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24KLSAgICAgKi8KLSAgICBTY2hlbWFHcmFtbWFyIGxvYWRTY2hlbWEoWFNERGVzY3JpcHRpb24gZGVzYywgWE1MSW5wdXRTb3VyY2Ugc291cmNlLAotICAgICAgICAgICAgTWFwPFN0cmluZywgTG9jYXRpb25BcnJheT4gbG9jYXRpb25QYWlycykgdGhyb3dzIElPRXhjZXB0aW9uLCBYTklFeGNlcHRpb24gewotCi0gICAgICAgIC8vIHRoaXMgc2hvdWxkIG9ubHkgYmUgZG9uZSBvbmNlIHBlciBpbnZvY2F0aW9uIG9mIHRoaXMgb2JqZWN0OwotICAgICAgICAvLyB1bmxlc3MgYXBwbGljYXRpb24gYWx0ZXJzIEpBWFBTb3VyY2UgaW4gdGhlIG1lYW4gdGltZS4KLSAgICAgICAgaWYoIWZKQVhQUHJvY2Vzc2VkKSB7Ci0gICAgICAgICAgICBwcm9jZXNzSkFYUFNjaGVtYVNvdXJjZShsb2NhdGlvblBhaXJzKTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChkZXNjLmlzRXh0ZXJuYWwoKSkgewotICAgICAgICAgICAgU3RyaW5nIGFjY2Vzc0Vycm9yID0gU2VjdXJpdHlTdXBwb3J0LmNoZWNrQWNjZXNzKGRlc2MuZ2V0RXhwYW5kZWRTeXN0ZW1JZCgpLCBmYWNjZXNzRXh0ZXJuYWxTY2hlbWEsIENvbnN0YW50cy5BQ0NFU1NfRVhURVJOQUxfQUxMKTsKLSAgICAgICAgICAgIGlmIChhY2Nlc3NFcnJvciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFhOSUV4Y2VwdGlvbihmRXJyb3JSZXBvcnRlci5yZXBvcnRFcnJvcihYU01lc3NhZ2VGb3JtYXR0ZXIuU0NIRU1BX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICJzY2hlbWFfcmVmZXJlbmNlLmFjY2VzcyIsCi0gICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBTZWN1cml0eVN1cHBvcnQuc2FuaXRpemVQYXRoKGRlc2MuZ2V0RXhwYW5kZWRTeXN0ZW1JZCgpKSwgYWNjZXNzRXJyb3IgfSwgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9FUlJPUikpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIFNjaGVtYUdyYW1tYXIgZ3JhbW1hciA9IGZTY2hlbWFIYW5kbGVyLnBhcnNlU2NoZW1hKHNvdXJjZSwgZGVzYywgbG9jYXRpb25QYWlycyk7Ci0KLSAgICAgICAgcmV0dXJuIGdyYW1tYXI7Ci0gICAgfSAvLyBsb2FkU2NoZW1hKFhTRERlc2NyaXB0aW9uLCBYTUxJbnB1dFNvdXJjZSk6ICBTY2hlbWFHcmFtbWFyCi0KLSAgICAvKiogVGhpcyBtZXRob2QgdHJpZXMgdG8gcmVzb2x2ZSBsb2NhdGlvbiBvZiB0aGUgZ2l2ZW4gc2NoZW1hLgotICAgICAqIFRoZSBsb2FkZXIgc3RvcmVzIHRoZSBuYW1lc3BhY2UvbG9jYXRpb24gcGFpcnMgaW4gYSBtYXAgKHVzZSAiIiBhcyB0aGUKLSAgICAgKiBuYW1lc3BhY2Ugb2YgYWJzZW50IG5hbWVzcGFjZSkuIFdoZW4gcmVzb2x2aW5nIGFuIGVudGl0eSwgbG9hZGVyIGZpcnN0IHRyaWVzCi0gICAgICogdG8gZmluZCBpbiB0aGUgbWFwIHdoZXRoZXIgdGhlcmUgaXMgYSB2YWx1ZSBmb3IgdGhhdCBuYW1lc3BhY2UsCi0gICAgICogaWYgc28sIHBhc3MgdGhhdCBsb2NhdGlvbiB2YWx1ZSB0byB0aGUgdXNlci1kZWZpbmVkIGVudGl0eSByZXNvbHZlci4KLSAgICAgKgotICAgICAqIEBwYXJhbSBkZXNjCi0gICAgICogQHBhcmFtIGxvY2F0aW9uUGFpcnMKLSAgICAgKiBAcGFyYW0gZW50aXR5UmVzb2x2ZXIKLSAgICAgKiBAcmV0dXJuCi0gICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgWE1MSW5wdXRTb3VyY2UgcmVzb2x2ZURvY3VtZW50KFhTRERlc2NyaXB0aW9uIGRlc2MsCi0gICAgICAgICAgICBNYXA8U3RyaW5nLCBMb2NhdGlvbkFycmF5PiBsb2NhdGlvblBhaXJzLAotICAgICAgICAgICAgWE1MRW50aXR5UmVzb2x2ZXIgZW50aXR5UmVzb2x2ZXIpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgIFN0cmluZyBsb2MgPSBudWxsOwotICAgICAgICAvLyB3ZSBjb25zaWRlciB0aGUgc2NoZW1hIGxvY2F0aW9uIHByb3BlcnRpZXMgZm9yIGltcG9ydAotICAgICAgICBpZiAoZGVzYy5nZXRDb250ZXh0VHlwZSgpID09IFhTRERlc2NyaXB0aW9uLkNPTlRFWFRfSU1QT1JUIHx8Ci0gICAgICAgICAgICAgICAgZGVzYy5mcm9tSW5zdGFuY2UoKSkgewotICAgICAgICAgICAgLy8gdXNlIGVtcHR5IHN0cmluZyBhcyB0aGUga2V5IGZvciBhYnNlbnQgbmFtZXNwYWNlCi0gICAgICAgICAgICBTdHJpbmcgbmFtZXNwYWNlID0gZGVzYy5nZXRUYXJnZXROYW1lc3BhY2UoKTsKLSAgICAgICAgICAgIFN0cmluZyBucyA9IG5hbWVzcGFjZSA9PSBudWxsID8gWE1MU3ltYm9scy5FTVBUWV9TVFJJTkcgOiBuYW1lc3BhY2U7Ci0gICAgICAgICAgICAvLyBnZXQgdGhlIGxvY2F0aW9uIGhpbnQgZm9yIHRoYXQgbmFtZXNwYWNlCi0gICAgICAgICAgICBMb2NhdGlvbkFycmF5IHRlbXBMQSA9IGxvY2F0aW9uUGFpcnMuZ2V0KG5zKTsKLSAgICAgICAgICAgIGlmKHRlbXBMQSAhPSBudWxsKQotICAgICAgICAgICAgICAgIGxvYyA9IHRlbXBMQS5nZXRGaXJzdExvY2F0aW9uKCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBpZiBpdCdzIG5vdCBpbXBvcnQsIG9yIGlmIHRoZSB0YXJnZXQgbmFtZXNwYWNlIGlzIG5vdCBzZXQKLSAgICAgICAgLy8gaW4gdGhlIHNjaGVtYSBsb2NhdGlvbiBwcm9wZXJ0aWVzLCB1c2UgbG9jYXRpb24gaGludAotICAgICAgICBpZiAobG9jID09IG51bGwpIHsKLSAgICAgICAgICAgIFN0cmluZ1tdIGhpbnRzID0gZGVzYy5nZXRMb2NhdGlvbkhpbnRzKCk7Ci0gICAgICAgICAgICBpZiAoaGludHMgIT0gbnVsbCAmJiBoaW50cy5sZW5ndGggPiAwKQotICAgICAgICAgICAgICAgIGxvYyA9IGhpbnRzWzBdOwotICAgICAgICB9Ci0KLSAgICAgICAgU3RyaW5nIGV4cGFuZGVkTG9jID0gWE1MRW50aXR5TWFuYWdlci5leHBhbmRTeXN0ZW1JZChsb2MsIGRlc2MuZ2V0QmFzZVN5c3RlbUlkKCksIGZhbHNlKTsKLSAgICAgICAgZGVzYy5zZXRMaXRlcmFsU3lzdGVtSWQobG9jKTsKLSAgICAgICAgZGVzYy5zZXRFeHBhbmRlZFN5c3RlbUlkKGV4cGFuZGVkTG9jKTsKLSAgICAgICAgcmV0dXJuIGVudGl0eVJlc29sdmVyLnJlc29sdmVFbnRpdHkoZGVzYyk7Ci0gICAgfQotCi0gICAgLy8gYWRkIGV4dGVybmFsIHNjaGVtYSBsb2NhdGlvbnMgdG8gdGhlIGxvY2F0aW9uIHBhaXJzCi0gICAgcHVibGljIHN0YXRpYyB2b2lkIHByb2Nlc3NFeHRlcm5hbEhpbnRzKFN0cmluZyBzbCwgU3RyaW5nIG5zbCwKLSAgICAgICAgICAgIE1hcDxTdHJpbmcsIFhNTFNjaGVtYUxvYWRlci5Mb2NhdGlvbkFycmF5PiBsb2NhdGlvbnMsCi0gICAgICAgICAgICBYTUxFcnJvclJlcG9ydGVyIGVyKSB7Ci0gICAgICAgIGlmIChzbCAhPSBudWxsKSB7Ci0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIC8vIGdldCB0aGUgYXR0cmlidXRlIGRlY2wgZm9yIHhzaTpzY2hlbWFMb2NhdGlvbgotICAgICAgICAgICAgICAgIC8vIGJlY2F1c2UgZXh0ZXJuYWwgc2NoZW1hIGxvY2F0aW9uIHByb3BlcnR5IGhhcyB0aGUgc2FtZSBzeW50YXgKLSAgICAgICAgICAgICAgICAvLyBhcyB4c2k6c2NoZW1hTG9jYXRpb24KLSAgICAgICAgICAgICAgICBYU0F0dHJpYnV0ZURlY2wgYXR0ckRlY2wgPSBTY2hlbWFHcmFtbWFyLlNHX1hTSS5nZXRHbG9iYWxBdHRyaWJ1dGVEZWNsKFNjaGVtYVN5bWJvbHMuWFNJX1NDSEVNQUxPQ0FUSU9OKTsKLSAgICAgICAgICAgICAgICAvLyB2YWxpZGF0aW9uIHRoZSBzdHJpbmcgdmFsdWUgdG8gZ2V0IHRoZSBsaXN0IG9mIFVSSSdzCi0gICAgICAgICAgICAgICAgYXR0ckRlY2wuZlR5cGUudmFsaWRhdGUoc2wsIG51bGwsIG51bGwpOwotICAgICAgICAgICAgICAgIGlmICghdG9rZW5pemVTY2hlbWFMb2NhdGlvblN0cihzbCwgbG9jYXRpb25zKSkgewotICAgICAgICAgICAgICAgICAgICAvLyByZXBvcnQgd2FybmluZyAob2RkIG51bWJlciBvZiBpdGVtcykKLSAgICAgICAgICAgICAgICAgICAgZXIucmVwb3J0RXJyb3IoWFNNZXNzYWdlRm9ybWF0dGVyLlNDSEVNQV9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNjaGVtYUxvY2F0aW9uIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117c2x9LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTEVycm9yUmVwb3J0ZXIuU0VWRVJJVFlfV0FSTklORyk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2F0Y2ggKEludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uIGV4KSB7Ci0gICAgICAgICAgICAgICAgLy8gcmVwb3J0IHdhcm5pbmcgKG5vdCBsaXN0IG9mIFVSSSdzKQotICAgICAgICAgICAgICAgIGVyLnJlcG9ydEVycm9yKFhTTWVzc2FnZUZvcm1hdHRlci5TQ0hFTUFfRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgZXguZ2V0S2V5KCksIGV4LmdldEFyZ3MoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgIFhNTEVycm9yUmVwb3J0ZXIuU0VWRVJJVFlfV0FSTklORyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAobnNsICE9IG51bGwpIHsKLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgLy8gc2ltaWxhcmx5IGZvciBubyBucyBzY2hlbWEgbG9jYXRpb24gcHJvcGVydHkKLSAgICAgICAgICAgICAgICBYU0F0dHJpYnV0ZURlY2wgYXR0ckRlY2wgPSBTY2hlbWFHcmFtbWFyLlNHX1hTSS5nZXRHbG9iYWxBdHRyaWJ1dGVEZWNsKFNjaGVtYVN5bWJvbHMuWFNJX05PTkFNRVNQQUNFU0NIRU1BTE9DQVRJT04pOwotICAgICAgICAgICAgICAgIGF0dHJEZWNsLmZUeXBlLnZhbGlkYXRlKG5zbCwgbnVsbCwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgTG9jYXRpb25BcnJheSBsYSA9ICgoTG9jYXRpb25BcnJheSlsb2NhdGlvbnMuZ2V0KFhNTFN5bWJvbHMuRU1QVFlfU1RSSU5HKSk7Ci0gICAgICAgICAgICAgICAgaWYobGEgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBsYSA9IG5ldyBMb2NhdGlvbkFycmF5KCk7Ci0gICAgICAgICAgICAgICAgICAgIGxvY2F0aW9ucy5wdXQoWE1MU3ltYm9scy5FTVBUWV9TVFJJTkcsIGxhKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgbGEuYWRkTG9jYXRpb24obnNsKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhdGNoIChJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbiBleCkgewotICAgICAgICAgICAgICAgIC8vIHJlcG9ydCB3YXJuaW5nIChub3QgYSBVUkkpCi0gICAgICAgICAgICAgICAgZXIucmVwb3J0RXJyb3IoWFNNZXNzYWdlRm9ybWF0dGVyLlNDSEVNQV9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICBleC5nZXRLZXkoKSwgZXguZ2V0QXJncygpLAotICAgICAgICAgICAgICAgICAgICAgICAgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9XQVJOSU5HKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLSAgICAvLyB0aGlzIG1ldGhvZCB0YWtlcyBhIFNjaGVtYUxvY2F0aW9uIHN0cmluZy4KLSAgICAvLyBJZiBhbiBlcnJvciBpcyBlbmNvdW50ZXJlZCwgZmFsc2UgaXMgcmV0dXJuZWQ7Ci0gICAgLy8gb3RoZXJ3aXNlLCB0cnVlIGlzIHJldHVybmVkLiAgSW4gZWl0aGVyIGNhc2UsIGxvY2F0aW9ucwotICAgIC8vIGlzIGF1Z21lbnRlZCB0byBpbmNsdWRlIGFzIG1hbnkgdG9rZW5zIGFzIHBvc3NpYmxlLgotICAgIC8vIEBwYXJhbSBzY2hlbWFTdHIgICAgIFRoZSBzY2hlbWFMb2NhdGlvbiBzdHJpbmcgdG8gdG9rZW5pemUKLSAgICAvLyBAcGFyYW0gbG9jYXRpb25zICAgICBIYXNoTWFwIG1hcHBpbmcgbmFtZXNwYWNlcyB0byBMb2NhdGlvbkFycmF5IG9iamVjdHMgaG9sZGluZyBsaXN0cyBvZiBsb2NhaXRvbnMKLSAgICAvLyBAcmV0dXJuIHRydWUgaWYgbm8gcHJvYmxlbXM7IGZhbHNlIGlmIHN0cmluZyBjb3VsZCBub3QgYmUgdG9rZW5pemVkCi0gICAgcHVibGljIHN0YXRpYyBib29sZWFuIHRva2VuaXplU2NoZW1hTG9jYXRpb25TdHIoU3RyaW5nIHNjaGVtYVN0ciwKLSAgICAgICAgICAgIE1hcDxTdHJpbmcsIFhNTFNjaGVtYUxvYWRlci5Mb2NhdGlvbkFycmF5PiBsb2NhdGlvbnMpIHsKLSAgICAgICAgaWYgKHNjaGVtYVN0ciE9IG51bGwpIHsKLSAgICAgICAgICAgIFN0cmluZ1Rva2VuaXplciB0ID0gbmV3IFN0cmluZ1Rva2VuaXplcihzY2hlbWFTdHIsICIgXG5cdFxyIik7Ci0gICAgICAgICAgICBTdHJpbmcgbmFtZXNwYWNlLCBsb2NhdGlvbjsKLSAgICAgICAgICAgIHdoaWxlICh0Lmhhc01vcmVUb2tlbnMoKSkgewotICAgICAgICAgICAgICAgIG5hbWVzcGFjZSA9IHQubmV4dFRva2VuICgpOwotICAgICAgICAgICAgICAgIGlmICghdC5oYXNNb3JlVG9rZW5zKCkpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOyAvLyBlcnJvciEKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgbG9jYXRpb24gPSB0Lm5leHRUb2tlbigpOwotICAgICAgICAgICAgICAgIExvY2F0aW9uQXJyYXkgbGEgPSBsb2NhdGlvbnMuZ2V0KG5hbWVzcGFjZSk7Ci0gICAgICAgICAgICAgICAgaWYobGEgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBsYSA9IG5ldyBMb2NhdGlvbkFycmF5KCk7Ci0gICAgICAgICAgICAgICAgICAgIGxvY2F0aW9ucy5wdXQobmFtZXNwYWNlLCBsYSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGxhLmFkZExvY2F0aW9uKGxvY2F0aW9uKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICB9IC8vIHRva2VuaXplU2NoZW1hTG9jYXRpb24oU3RyaW5nLCBIYXNoTWFwKTogIGJvb2xlYW4KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZSB0aGUgdmFyaW91cyBKQVhQIFNjaGVtYVNvdXJjZSBwcm9wZXJ0eSB0eXBlcyB0byBYTkkKLSAgICAgKiBYTUxJbnB1dFNvdXJjZS4gIFZhbGlkIHR5cGVzIGFyZTogU3RyaW5nLCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZSwKLSAgICAgKiBJbnB1dFN0cmVhbSwgRmlsZSwgb3IgT2JqZWN0W10gb2YgYW55IG9mIHByZXZpb3VzIHR5cGVzLgotICAgICAqIFJFVklTSVQ6ICB0aGUgSkFYUCAxLjIgc3BlYyBpcyBsZXNzIHRoYW4gY2xlYXIgYXMgdG8gd2hldGhlciB0aGlzIHByb3BlcnR5Ci0gICAgICogc2hvdWxkIGJlIGF2YWlsYWJsZSB0byBpbXBvcnRlZCBzY2hlbWFzLiAgSSBoYXZlIGFzc3VtZWQKLSAgICAgKiB0aGF0IGl0IHNob3VsZC4gIC0gTkcKLSAgICAgKiBOb3RlOiBhbGwgSkFYUCBzY2hlbWEgZmlsZXMgd2lsbCBiZSBjaGVja2VkIGZvciBmdWxsLXNjaGVtYSB2YWxpZGl0eSBpZiB0aGUgZmVhdHVyZSB3YXMgc2V0IHVwCi0gICAgICoKLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgcHJvY2Vzc0pBWFBTY2hlbWFTb3VyY2UoCi0gICAgICAgICAgICBNYXA8U3RyaW5nLCBMb2NhdGlvbkFycmF5PiBsb2NhdGlvblBhaXJzKSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgICAgICBmSkFYUFByb2Nlc3NlZCA9IHRydWU7Ci0gICAgICAgIGlmIChmSkFYUFNvdXJjZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLQotICAgICAgICBDbGFzcyBjb21wb25lbnRUeXBlID0gZkpBWFBTb3VyY2UuZ2V0Q2xhc3MoKS5nZXRDb21wb25lbnRUeXBlKCk7Ci0gICAgICAgIFhNTElucHV0U291cmNlIHhpcyA9IG51bGw7Ci0gICAgICAgIFN0cmluZyBzaWQgPSBudWxsOwotICAgICAgICBpZiAoY29tcG9uZW50VHlwZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAvLyBOb3QgYW4gYXJyYXkKLSAgICAgICAgICAgIGlmKGZKQVhQU291cmNlIGluc3RhbmNlb2YgSW5wdXRTdHJlYW0gfHwKLSAgICAgICAgICAgICAgICAgICAgZkpBWFBTb3VyY2UgaW5zdGFuY2VvZiBJbnB1dFNvdXJjZSkgewotICAgICAgICAgICAgICAgIFNjaGVtYUdyYW1tYXIgZyA9IChTY2hlbWFHcmFtbWFyKWZKQVhQQ2FjaGUuZ2V0KGZKQVhQU291cmNlKTsKLSAgICAgICAgICAgICAgICBpZihnICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgZkdyYW1tYXJCdWNrZXQucHV0R3JhbW1hcihnKTsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGZYU0REZXNjcmlwdGlvbi5yZXNldCgpOwotICAgICAgICAgICAgeGlzID0geHNkVG9YTUxJbnB1dFNvdXJjZShmSkFYUFNvdXJjZSk7Ci0gICAgICAgICAgICBzaWQgPSB4aXMuZ2V0U3lzdGVtSWQoKTsKLSAgICAgICAgICAgIGZYU0REZXNjcmlwdGlvbi5mQ29udGV4dFR5cGUgPSBYU0REZXNjcmlwdGlvbi5DT05URVhUX1BSRVBBUlNFOwotICAgICAgICAgICAgaWYgKHNpZCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZlhTRERlc2NyaXB0aW9uLnNldEJhc2VTeXN0ZW1JZCh4aXMuZ2V0QmFzZVN5c3RlbUlkKCkpOwotICAgICAgICAgICAgICAgIGZYU0REZXNjcmlwdGlvbi5zZXRMaXRlcmFsU3lzdGVtSWQoc2lkKTsKLSAgICAgICAgICAgICAgICBmWFNERGVzY3JpcHRpb24uc2V0RXhwYW5kZWRTeXN0ZW1JZChzaWQpOwotICAgICAgICAgICAgICAgIGZYU0REZXNjcmlwdGlvbi5mTG9jYXRpb25IaW50cyA9IG5ldyBTdHJpbmdbXXtzaWR9OwotICAgICAgICAgICAgfQotICAgICAgICAgICAgU2NoZW1hR3JhbW1hciBnID0gbG9hZFNjaGVtYShmWFNERGVzY3JpcHRpb24sIHhpcywgbG9jYXRpb25QYWlycyk7Ci0gICAgICAgICAgICAvLyBpdCBpcyBwb3NzaWJsZSB0aGF0IHdlIHdvbid0IGJlIGFibGUgdG8gcmVzb2x2ZSBKQVhQIHNjaGVtYS1zb3VyY2UgbG9jYXRpb24KLSAgICAgICAgICAgIGlmIChnICE9IG51bGwpewotICAgICAgICAgICAgICAgIGlmKGZKQVhQU291cmNlIGluc3RhbmNlb2YgSW5wdXRTdHJlYW0gfHwKLSAgICAgICAgICAgICAgICAgICAgICAgIGZKQVhQU291cmNlIGluc3RhbmNlb2YgSW5wdXRTb3VyY2UpIHsKLSAgICAgICAgICAgICAgICAgICAgZkpBWFBDYWNoZS5wdXQoZkpBWFBTb3VyY2UsIGcpOwotICAgICAgICAgICAgICAgICAgICBpZihmSXNDaGVja2VkRnVsbHkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIFhTQ29uc3RyYWludHMuZnVsbFNjaGVtYUNoZWNraW5nKGZHcmFtbWFyQnVja2V0LCBmU3ViR3JvdXBIYW5kbGVyLCBmQ01CdWlsZGVyLCBmRXJyb3JSZXBvcnRlcik7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZkdyYW1tYXJCdWNrZXQucHV0R3JhbW1hcihnKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiA7Ci0gICAgICAgIH0gZWxzZSBpZiAoIChjb21wb25lbnRUeXBlICE9IE9iamVjdC5jbGFzcykgJiYKLSAgICAgICAgICAgICAgICAoY29tcG9uZW50VHlwZSAhPSBTdHJpbmcuY2xhc3MpICYmCi0gICAgICAgICAgICAgICAgKGNvbXBvbmVudFR5cGUgIT0gRmlsZS5jbGFzcykgJiYKLSAgICAgICAgICAgICAgICAoY29tcG9uZW50VHlwZSAhPSBJbnB1dFN0cmVhbS5jbGFzcykgJiYKLSAgICAgICAgICAgICAgICAoY29tcG9uZW50VHlwZSAhPSBJbnB1dFNvdXJjZS5jbGFzcykKLSAgICAgICAgKSB7Ci0gICAgICAgICAgICAvLyBOb3QgYW4gT2JqZWN0W10sIFN0cmluZ1tdLCBGaWxlW10sIElucHV0U3RyZWFtW10sIElucHV0U291cmNlW10KLSAgICAgICAgICAgIHRocm93IG5ldyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICBTdGF0dXMuTk9UX1NVUFBPUlRFRCwgIlwiIitKQVhQX1NDSEVNQV9TT1VSQ0UrCi0gICAgICAgICAgICAgICAgICAgICJcIiBwcm9wZXJ0eSBjYW5ub3QgaGF2ZSBhbiBhcnJheSBvZiB0eXBlIHsiK2NvbXBvbmVudFR5cGUuZ2V0TmFtZSgpKwotICAgICAgICAgICAgICAgICAgICAifS4gUG9zc2libGUgdHlwZXMgb2YgdGhlIGFycmF5IHN1cHBvcnRlZCBhcmUgT2JqZWN0LCBTdHJpbmcsIEZpbGUsICIrCi0gICAgICAgICAgICAiSW5wdXRTdHJlYW0sIElucHV0U291cmNlLiIpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gSkFYUCBzcGVjLiBhbGxvdyBbXXMgb2YgdHlwZSBTdHJpbmcsIEZpbGUsIElucHV0U3RyZWFtLAotICAgICAgICAvLyBJbnB1dFNvdXJjZSBhbHNvLCBhcGFydCBmcm9tIFtdIG9mIHR5cGUgT2JqZWN0LgotICAgICAgICBPYmplY3RbXSBvYmpBcnIgPSAoT2JqZWN0W10pIGZKQVhQU291cmNlOwotICAgICAgICAvL21ha2UgbG9jYWwgdmVjdG9yIGZvciBzdG9yaW5nIHRhcmdldG4gbmFtZXNwYWNlcyBvZiBzY2hlbWFzb3VyY2VzIHNwZWNpZmllZCBpbiBvYmplY3QgYXJyYXlzLgotICAgICAgICBWZWN0b3IgamF4cFNjaGVtYVNvdXJjZU5hbWVzcGFjZXMgPSBuZXcgVmVjdG9yKCkgOwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG9iakFyci5sZW5ndGg7IGkrKykgewotICAgICAgICAgICAgaWYob2JqQXJyW2ldIGluc3RhbmNlb2YgSW5wdXRTdHJlYW0gfHwKLSAgICAgICAgICAgICAgICAgICAgb2JqQXJyW2ldIGluc3RhbmNlb2YgSW5wdXRTb3VyY2UpIHsKLSAgICAgICAgICAgICAgICBTY2hlbWFHcmFtbWFyIGcgPSAoU2NoZW1hR3JhbW1hcilmSkFYUENhY2hlLmdldChvYmpBcnJbaV0pOwotICAgICAgICAgICAgICAgIGlmIChnICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgZkdyYW1tYXJCdWNrZXQucHV0R3JhbW1hcihnKTsKLSAgICAgICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZlhTRERlc2NyaXB0aW9uLnJlc2V0KCk7Ci0gICAgICAgICAgICB4aXMgPSB4c2RUb1hNTElucHV0U291cmNlKG9iakFycltpXSk7Ci0gICAgICAgICAgICBzaWQgPSB4aXMuZ2V0U3lzdGVtSWQoKTsKLSAgICAgICAgICAgIGZYU0REZXNjcmlwdGlvbi5mQ29udGV4dFR5cGUgPSBYU0REZXNjcmlwdGlvbi5DT05URVhUX1BSRVBBUlNFOwotICAgICAgICAgICAgaWYgKHNpZCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZlhTRERlc2NyaXB0aW9uLnNldEJhc2VTeXN0ZW1JZCh4aXMuZ2V0QmFzZVN5c3RlbUlkKCkpOwotICAgICAgICAgICAgICAgIGZYU0REZXNjcmlwdGlvbi5zZXRMaXRlcmFsU3lzdGVtSWQoc2lkKTsKLSAgICAgICAgICAgICAgICBmWFNERGVzY3JpcHRpb24uc2V0RXhwYW5kZWRTeXN0ZW1JZChzaWQpOwotICAgICAgICAgICAgICAgIGZYU0REZXNjcmlwdGlvbi5mTG9jYXRpb25IaW50cyA9IG5ldyBTdHJpbmdbXXtzaWR9OwotICAgICAgICAgICAgfQotICAgICAgICAgICAgU3RyaW5nIHRhcmdldE5hbWVzcGFjZSA9IG51bGwgOwotICAgICAgICAgICAgLy8gbG9hZCBzY2hlbWEKLSAgICAgICAgICAgIFNjaGVtYUdyYW1tYXIgZ3JhbW1hciA9IGZTY2hlbWFIYW5kbGVyLnBhcnNlU2NoZW1hKHhpcyxmWFNERGVzY3JpcHRpb24sIGxvY2F0aW9uUGFpcnMpOwotCi0gICAgICAgICAgICBpZihmSXNDaGVja2VkRnVsbHkpIHsKLSAgICAgICAgICAgICAgICBYU0NvbnN0cmFpbnRzLmZ1bGxTY2hlbWFDaGVja2luZyhmR3JhbW1hckJ1Y2tldCwgZlN1Ykdyb3VwSGFuZGxlciwgZkNNQnVpbGRlciwgZkVycm9yUmVwb3J0ZXIpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYoZ3JhbW1hciAhPSBudWxsKXsKLSAgICAgICAgICAgICAgICB0YXJnZXROYW1lc3BhY2UgPSBncmFtbWFyLmdldFRhcmdldE5hbWVzcGFjZSgpIDsKLSAgICAgICAgICAgICAgICBpZihqYXhwU2NoZW1hU291cmNlTmFtZXNwYWNlcy5jb250YWlucyh0YXJnZXROYW1lc3BhY2UpKXsKLSAgICAgICAgICAgICAgICAgICAgLy93aGVuIGFuIGFycmF5IG9mIG9iamVjdHMgaXMgcGFzc2VkIGl0IGlzIGlsbGVnYWwgdG8gaGF2ZSB0d28gc2NoZW1hcyB0aGF0IHNoYXJlIHNhbWUgbmFtZXNwYWNlLgotICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIFdoZW4gdXNpbmcgYXJyYXkgb2YgT2JqZWN0cyBhcyB0aGUgdmFsdWUgb2YgU0NIRU1BX1NPVVJDRSBwcm9wZXJ0eSAsICIgKwotICAgICAgICAgICAgICAgICAgICAibm8gdHdvIFNjaGVtYXMgc2hvdWxkIHNoYXJlIHRoZSBzYW1lIHRhcmdldE5hbWVzcGFjZS4gIiApOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlewotICAgICAgICAgICAgICAgICAgICBqYXhwU2NoZW1hU291cmNlTmFtZXNwYWNlcy5hZGQodGFyZ2V0TmFtZXNwYWNlKSA7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGlmKG9iakFycltpXSBpbnN0YW5jZW9mIElucHV0U3RyZWFtIHx8Ci0gICAgICAgICAgICAgICAgICAgICAgICBvYmpBcnJbaV0gaW5zdGFuY2VvZiBJbnB1dFNvdXJjZSkgewotICAgICAgICAgICAgICAgICAgICBmSkFYUENhY2hlLnB1dChvYmpBcnJbaV0sIGdyYW1tYXIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBmR3JhbW1hckJ1Y2tldC5wdXRHcmFtbWFyKGdyYW1tYXIpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZXsKLSAgICAgICAgICAgICAgICAvL1JFVklTSVQ6IFdoYXQgc2hvdWxkIGJlIHRoZSBhY3V0YWwgYmVoYXZpb3IgaWYgZ3JhbW1hciBjYW4ndCBiZSBsb2FkZWQgYXMgc3BlY2lmaWVkIGluIHNjaGVtYSBzb3VyY2U/Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ly9wcm9jZXNzSkFYUFNjaGVtYVNvdXJjZQotCi0gICAgcHJpdmF0ZSBYTUxJbnB1dFNvdXJjZSB4c2RUb1hNTElucHV0U291cmNlKAotICAgICAgICAgICAgT2JqZWN0IHZhbCkKLSAgICB7Ci0gICAgICAgIGlmICh2YWwgaW5zdGFuY2VvZiBTdHJpbmcpIHsKLSAgICAgICAgICAgIC8vIFN0cmluZyB2YWx1ZSBpcyB0cmVhdGVkIGFzIGEgVVJJIHRoYXQgaXMgcGFzc2VkIHRocm91Z2ggdGhlCi0gICAgICAgICAgICAvLyBFbnRpdHlSZXNvbHZlcgotICAgICAgICAgICAgU3RyaW5nIGxvYyA9IChTdHJpbmcpIHZhbDsKLSAgICAgICAgICAgIGZYU0REZXNjcmlwdGlvbi5yZXNldCgpOwotICAgICAgICAgICAgZlhTRERlc2NyaXB0aW9uLnNldFZhbHVlcyhudWxsLCBsb2MsIG51bGwsIG51bGwpOwotICAgICAgICAgICAgWE1MSW5wdXRTb3VyY2UgeGlzID0gbnVsbDsKLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgeGlzID0gZkVudGl0eU1hbmFnZXIucmVzb2x2ZUVudGl0eShmWFNERGVzY3JpcHRpb24pOwotICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKLSAgICAgICAgICAgICAgICBmRXJyb3JSZXBvcnRlci5yZXBvcnRFcnJvcihYU01lc3NhZ2VGb3JtYXR0ZXIuU0NIRU1BX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICJzY2hlbWFfcmVmZXJlbmNlLjQiLAotICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgbG9jIH0sIFhNTEVycm9yUmVwb3J0ZXIuU0VWRVJJVFlfRVJST1IpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKHhpcyA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgLy8gUkVWSVNJVDogY2FuIHRoaXMgaGFwcGVuPwotICAgICAgICAgICAgICAgIC8vIFRyZWF0IHZhbHVlIGFzIGEgVVJJIGFuZCBwYXNzIGluIGFzIHN5c3RlbUlkCi0gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBYTUxJbnB1dFNvdXJjZShudWxsLCBsb2MsIG51bGwpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIHhpczsKLSAgICAgICAgfSBlbHNlIGlmICh2YWwgaW5zdGFuY2VvZiBJbnB1dFNvdXJjZSkgewotICAgICAgICAgICAgcmV0dXJuIHNheFRvWE1MSW5wdXRTb3VyY2UoKElucHV0U291cmNlKSB2YWwpOwotICAgICAgICB9IGVsc2UgaWYgKHZhbCBpbnN0YW5jZW9mIElucHV0U3RyZWFtKSB7Ci0gICAgICAgICAgICByZXR1cm4gbmV3IFhNTElucHV0U291cmNlKG51bGwsIG51bGwsIG51bGwsCi0gICAgICAgICAgICAgICAgICAgIChJbnB1dFN0cmVhbSkgdmFsLCBudWxsKTsKLSAgICAgICAgfSBlbHNlIGlmICh2YWwgaW5zdGFuY2VvZiBGaWxlKSB7Ci0gICAgICAgICAgICBGaWxlIGZpbGUgPSAoRmlsZSkgdmFsOwotICAgICAgICAgICAgSW5wdXRTdHJlYW0gaXMgPSBudWxsOwotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICBpcyA9IG5ldyBCdWZmZXJlZElucHV0U3RyZWFtKG5ldyBGaWxlSW5wdXRTdHJlYW0oZmlsZSkpOwotICAgICAgICAgICAgfSBjYXRjaCAoRmlsZU5vdEZvdW5kRXhjZXB0aW9uIGV4KSB7Ci0gICAgICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IoWFNNZXNzYWdlRm9ybWF0dGVyLlNDSEVNQV9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAic2NoZW1hX3JlZmVyZW5jZS40IiwgbmV3IE9iamVjdFtdIHsgZmlsZS50b1N0cmluZygpIH0sCi0gICAgICAgICAgICAgICAgICAgICAgICBYTUxFcnJvclJlcG9ydGVyLlNFVkVSSVRZX0VSUk9SKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiBuZXcgWE1MSW5wdXRTb3VyY2UobnVsbCwgbnVsbCwgbnVsbCwgaXMsIG51bGwpOwotICAgICAgICB9Ci0gICAgICAgIHRocm93IG5ldyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgIFN0YXR1cy5OT1RfU1VQUE9SVEVELCAiXCIiK0pBWFBfU0NIRU1BX1NPVVJDRSsKLSAgICAgICAgICAgICAgICAiXCIgcHJvcGVydHkgY2Fubm90IGhhdmUgYSB2YWx1ZSBvZiB0eXBlIHsiK3ZhbC5nZXRDbGFzcygpLmdldE5hbWUoKSsKLSAgICAgICAgICAgICAgICAifS4gUG9zc2libGUgdHlwZXMgb2YgdGhlIHZhbHVlIHN1cHBvcnRlZCBhcmUgU3RyaW5nLCBGaWxlLCBJbnB1dFN0cmVhbSwgIisKLSAgICAgICAgIklucHV0U291cmNlIE9SIGFuIGFycmF5IG9mIHRoZXNlIHR5cGVzLiIpOwotICAgIH0KLQotCi0gICAgLy9Db252ZXJ0IGEgU0FYIElucHV0U291cmNlIHRvIGFuIGVxdWl2YWxlbnQgWE5JIFhNTElucHV0U291cmNlCi0KLSAgICBwcml2YXRlIHN0YXRpYyBYTUxJbnB1dFNvdXJjZSBzYXhUb1hNTElucHV0U291cmNlKElucHV0U291cmNlIHNpcykgewotICAgICAgICBTdHJpbmcgcHVibGljSWQgPSBzaXMuZ2V0UHVibGljSWQoKTsKLSAgICAgICAgU3RyaW5nIHN5c3RlbUlkID0gc2lzLmdldFN5c3RlbUlkKCk7Ci0KLSAgICAgICAgUmVhZGVyIGNoYXJTdHJlYW0gPSBzaXMuZ2V0Q2hhcmFjdGVyU3RyZWFtKCk7Ci0gICAgICAgIGlmIChjaGFyU3RyZWFtICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBuZXcgWE1MSW5wdXRTb3VyY2UocHVibGljSWQsIHN5c3RlbUlkLCBudWxsLCBjaGFyU3RyZWFtLAotICAgICAgICAgICAgICAgICAgICBudWxsKTsKLSAgICAgICAgfQotCi0gICAgICAgIElucHV0U3RyZWFtIGJ5dGVTdHJlYW0gPSBzaXMuZ2V0Qnl0ZVN0cmVhbSgpOwotICAgICAgICBpZiAoYnl0ZVN0cmVhbSAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gbmV3IFhNTElucHV0U291cmNlKHB1YmxpY0lkLCBzeXN0ZW1JZCwgbnVsbCwgYnl0ZVN0cmVhbSwKLSAgICAgICAgICAgICAgICAgICAgc2lzLmdldEVuY29kaW5nKCkpOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIG5ldyBYTUxJbnB1dFNvdXJjZShwdWJsaWNJZCwgc3lzdGVtSWQsIG51bGwpOwotICAgIH0KLQotICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgTG9jYXRpb25BcnJheXsKLQotICAgICAgICBpbnQgbGVuZ3RoIDsKLSAgICAgICAgU3RyaW5nIFtdIGxvY2F0aW9ucyA9IG5ldyBTdHJpbmdbMl07Ci0KLSAgICAgICAgcHVibGljIHZvaWQgcmVzaXplKGludCBvbGRMZW5ndGggLCBpbnQgbmV3TGVuZ3RoKXsKLSAgICAgICAgICAgIFN0cmluZyBbXSB0ZW1wID0gbmV3IFN0cmluZ1tuZXdMZW5ndGhdIDsKLSAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkobG9jYXRpb25zLCAwLCB0ZW1wLCAwLCBNYXRoLm1pbihvbGRMZW5ndGgsIG5ld0xlbmd0aCkpOwotICAgICAgICAgICAgbG9jYXRpb25zID0gdGVtcCA7Ci0gICAgICAgICAgICBsZW5ndGggPSBNYXRoLm1pbihvbGRMZW5ndGgsIG5ld0xlbmd0aCk7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCBhZGRMb2NhdGlvbihTdHJpbmcgbG9jYXRpb24pewotICAgICAgICAgICAgaWYobGVuZ3RoID49IGxvY2F0aW9ucy5sZW5ndGggKXsKLSAgICAgICAgICAgICAgICByZXNpemUobGVuZ3RoLCBNYXRoLm1heCgxLCBsZW5ndGgqMikpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgbG9jYXRpb25zW2xlbmd0aCsrXSA9IGxvY2F0aW9uOwotICAgICAgICB9Ly9zZXRMb2NhdGlvbigpCi0KLSAgICAgICAgcHVibGljIFN0cmluZyBbXSBnZXRMb2NhdGlvbkFycmF5KCl7Ci0gICAgICAgICAgICBpZihsZW5ndGggPCBsb2NhdGlvbnMubGVuZ3RoICl7Ci0gICAgICAgICAgICAgICAgcmVzaXplKGxvY2F0aW9ucy5sZW5ndGgsIGxlbmd0aCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gbG9jYXRpb25zOwotICAgICAgICB9Ly9nZXRMb2NhdGlvbkFycmF5KCkKLQotICAgICAgICBwdWJsaWMgU3RyaW5nIGdldEZpcnN0TG9jYXRpb24oKXsKLSAgICAgICAgICAgIHJldHVybiBsZW5ndGggPiAwID8gbG9jYXRpb25zWzBdIDogbnVsbDsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyBpbnQgZ2V0TGVuZ3RoKCl7Ci0gICAgICAgICAgICByZXR1cm4gbGVuZ3RoIDsKLSAgICAgICAgfQotCi0gICAgfSAvL2xvY2F0aW9uQXJyYXkKLQotICAgIC8qIChub24tSmF2YWRvYykKLSAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxDb21wb25lbnQjZ2V0RmVhdHVyZURlZmF1bHQoamF2YS5sYW5nLlN0cmluZykKLSAgICAgKi8KLSAgICBwdWJsaWMgQm9vbGVhbiBnZXRGZWF0dXJlRGVmYXVsdChTdHJpbmcgZmVhdHVyZUlkKSB7Ci0gICAgICAgIGlmIChmZWF0dXJlSWQuZXF1YWxzKEFVR01FTlRfUFNWSSkpewotICAgICAgICAgICAgcmV0dXJuIEJvb2xlYW4uVFJVRTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICAvKiAobm9uLUphdmFkb2MpCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MQ29tcG9uZW50I2dldFByb3BlcnR5RGVmYXVsdChqYXZhLmxhbmcuU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyBPYmplY3QgZ2V0UHJvcGVydHlEZWZhdWx0KFN0cmluZyBwcm9wZXJ0eUlkKSB7Ci0gICAgICAgIC8vIFRPRE8gQXV0by1nZW5lcmF0ZWQgbWV0aG9kIHN0dWIKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLyogKG5vbi1KYXZhZG9jKQotICAgICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTENvbXBvbmVudCNyZXNldChjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MQ29tcG9uZW50TWFuYWdlcikKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCByZXNldChYTUxDb21wb25lbnRNYW5hZ2VyIGNvbXBvbmVudE1hbmFnZXIpIHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIHsKLQotICAgICAgICBYTUxTZWN1cml0eVByb3BlcnR5TWFuYWdlciBzcG0gPSAoWE1MU2VjdXJpdHlQcm9wZXJ0eU1hbmFnZXIpY29tcG9uZW50TWFuYWdlci5nZXRQcm9wZXJ0eShYTUxfU0VDVVJJVFlfUFJPUEVSVFlfTUFOQUdFUik7Ci0gICAgICAgIGlmIChzcG0gPT0gbnVsbCkgewotICAgICAgICAgICAgc3BtID0gbmV3IFhNTFNlY3VyaXR5UHJvcGVydHlNYW5hZ2VyKCk7Ci0gICAgICAgICAgICBzZXRQcm9wZXJ0eShYTUxfU0VDVVJJVFlfUFJPUEVSVFlfTUFOQUdFUiwgc3BtKTsKLSAgICAgICAgfQotCi0gICAgICAgIFhNTFNlY3VyaXR5TWFuYWdlciBzbSA9IChYTUxTZWN1cml0eU1hbmFnZXIpY29tcG9uZW50TWFuYWdlci5nZXRQcm9wZXJ0eShTRUNVUklUWV9NQU5BR0VSKTsKLSAgICAgICAgaWYgKHNtID09IG51bGwpCi0gICAgICAgICAgICBzZXRQcm9wZXJ0eShTRUNVUklUWV9NQU5BR0VSLG5ldyBYTUxTZWN1cml0eU1hbmFnZXIodHJ1ZSkpOwotCi0gICAgICAgIGZhY2Nlc3NFeHRlcm5hbFNjaGVtYSA9IHNwbS5nZXRWYWx1ZShYTUxTZWN1cml0eVByb3BlcnR5TWFuYWdlci5Qcm9wZXJ0eS5BQ0NFU1NfRVhURVJOQUxfU0NIRU1BKTsKLQotICAgICAgICBmR3JhbW1hckJ1Y2tldC5yZXNldCgpOwotCi0gICAgICAgIGZTdWJHcm91cEhhbmRsZXIucmVzZXQoKTsKLQotICAgICAgICBib29sZWFuIHBhcnNlcl9zZXR0aW5ncyA9IGNvbXBvbmVudE1hbmFnZXIuZ2V0RmVhdHVyZShQQVJTRVJfU0VUVElOR1MsIHRydWUpOwotCi0gICAgICAgIGlmICghcGFyc2VyX3NldHRpbmdzIHx8ICFmU2V0dGluZ3NDaGFuZ2VkKXsKLSAgICAgICAgICAgIC8vIG5lZWQgdG8gcmVwcm9jZXNzIEpBWFAgc2NoZW1hIHNvdXJjZXMKLSAgICAgICAgICAgIGZKQVhQUHJvY2Vzc2VkID0gZmFsc2U7Ci0gICAgICAgICAgICAvLyByZWluaXRpYWxpemUgZ3JhbW1hciBidWNrZXQKLSAgICAgICAgICAgIGluaXRHcmFtbWFyQnVja2V0KCk7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLQotICAgICAgICAvL3Bhc3MgdGhlIGNvbXBvbmVudCBtYW5hZ2VyIHRvIHRoZSBmYWN0b3J5Li4KLSAgICAgICAgZk5vZGVGYWN0b3J5LnJlc2V0KGNvbXBvbmVudE1hbmFnZXIpOwotCi0gICAgICAgIC8vIGdldCByZWdpc3RlcmVkIGVudGl0eSBtYW5hZ2VyIHRvIGJlIGFibGUgdG8gcmVzb2x2ZSBKQVhQIHNjaGVtYS1zb3VyY2UgcHJvcGVydHk6Ci0gICAgICAgIC8vIE5vdGU6IGluIGNhc2UgWE1MU2NoZW1hVmFsaWRhdG9yIGhhcyBjcmVhdGVkIHRoZSBsb2FkZXIsCi0gICAgICAgIC8vIHRoZSBlbnRpdHkgbWFuYWdlciBwcm9wZXJ0eSBpcyBudWxsCi0gICAgICAgIGZFbnRpdHlNYW5hZ2VyID0gKFhNTEVudGl0eU1hbmFnZXIpY29tcG9uZW50TWFuYWdlci5nZXRQcm9wZXJ0eShFTlRJVFlfTUFOQUdFUik7Ci0KLSAgICAgICAgLy8gZ2V0IHRoZSBlcnJvciByZXBvcnRlcgotICAgICAgICBmRXJyb3JSZXBvcnRlciA9IChYTUxFcnJvclJlcG9ydGVyKWNvbXBvbmVudE1hbmFnZXIuZ2V0UHJvcGVydHkoRVJST1JfUkVQT1JURVIpOwotCi0gICAgICAgIC8vIERldGVybWluZSBzY2hlbWEgZHYgZmFjdG9yeSB0byB1c2UKLSAgICAgICAgU2NoZW1hRFZGYWN0b3J5IGR2RmFjdG9yeSA9IG51bGw7Ci0gICAgICAgIGR2RmFjdG9yeSA9IGZTY2hlbWFIYW5kbGVyLmdldERWRmFjdG9yeSgpOwotICAgICAgICBpZiAoZHZGYWN0b3J5ID09IG51bGwpIHsKLSAgICAgICAgICAgIGR2RmFjdG9yeSA9IFNjaGVtYURWRmFjdG9yeS5nZXRJbnN0YW5jZSgpOwotICAgICAgICAgICAgZlNjaGVtYUhhbmRsZXIuc2V0RFZGYWN0b3J5KGR2RmFjdG9yeSk7Ci0gICAgICAgIH0KLQotICAgICAgICBib29sZWFuIHBzdmkgPSBjb21wb25lbnRNYW5hZ2VyLmdldEZlYXR1cmUoQVVHTUVOVF9QU1ZJLCBmYWxzZSk7Ci0KLSAgICAgICAgaWYgKCFwc3ZpKSB7Ci0gICAgICAgICAgICBpZiAoZkRlY2xQb29sICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmRGVjbFBvb2wucmVzZXQoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIGZEZWNsUG9vbCA9IG5ldyBYU0RlY2xhcmF0aW9uUG9vbCgpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZkNNQnVpbGRlci5zZXREZWNsUG9vbChmRGVjbFBvb2wpOwotICAgICAgICAgICAgZlNjaGVtYUhhbmRsZXIuc2V0RGVjbFBvb2woZkRlY2xQb29sKTsKLSAgICAgICAgICAgIGlmIChkdkZhY3RvcnkgaW5zdGFuY2VvZiBTY2hlbWFEVkZhY3RvcnlJbXBsKSB7Ci0gICAgICAgICAgICAgICAgZkRlY2xQb29sLnNldERWRmFjdG9yeSgoU2NoZW1hRFZGYWN0b3J5SW1wbClkdkZhY3RvcnkpOwotICAgICAgICAgICAgICAgICgoU2NoZW1hRFZGYWN0b3J5SW1wbClkdkZhY3RvcnkpLnNldERlY2xQb29sKGZEZWNsUG9vbCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBmQ01CdWlsZGVyLnNldERlY2xQb29sKG51bGwpOwotICAgICAgICAgICAgZlNjaGVtYUhhbmRsZXIuc2V0RGVjbFBvb2wobnVsbCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBnZXQgc2NoZW1hIGxvY2F0aW9uIHByb3BlcnRpZXMKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGZFeHRlcm5hbFNjaGVtYXMgPSAoU3RyaW5nKSBjb21wb25lbnRNYW5hZ2VyLmdldFByb3BlcnR5KFNDSEVNQV9MT0NBVElPTik7Ci0gICAgICAgICAgICBmRXh0ZXJuYWxOb05TU2NoZW1hID0gKFN0cmluZykgY29tcG9uZW50TWFuYWdlci5nZXRQcm9wZXJ0eShTQ0hFTUFfTk9OU19MT0NBVElPTik7Ci0gICAgICAgIH0gY2F0Y2ggKFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gZSkgewotICAgICAgICAgICAgZkV4dGVybmFsU2NoZW1hcyA9IG51bGw7Ci0gICAgICAgICAgICBmRXh0ZXJuYWxOb05TU2NoZW1hID0gbnVsbDsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIGdldCBKQVhQIHNvdXJjZXMgaWYgYXZhaWxhYmxlCi0gICAgICAgIGZKQVhQU291cmNlID0gY29tcG9uZW50TWFuYWdlci5nZXRQcm9wZXJ0eShKQVhQX1NDSEVNQV9TT1VSQ0UsIG51bGwpOwotICAgICAgICBmSkFYUFByb2Nlc3NlZCA9IGZhbHNlOwotCi0gICAgICAgIC8vIGNsZWFyIGdyYW1tYXJzLCBhbmQgcHV0IHRoZSBvbmUgZm9yIHNjaGVtYSBuYW1lc3BhY2UgdGhlcmUKLSAgICAgICAgZkdyYW1tYXJQb29sID0gKFhNTEdyYW1tYXJQb29sKSBjb21wb25lbnRNYW5hZ2VyLmdldFByb3BlcnR5KFhNTEdSQU1NQVJfUE9PTCwgbnVsbCk7Ci0gICAgICAgIGluaXRHcmFtbWFyQnVja2V0KCk7Ci0gICAgICAgIC8vIGdldCBjb250aW51ZS1hZnRlci1mYXRhbC1lcnJvciBmZWF0dXJlCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBib29sZWFuIGZhdGFsRXJyb3IgPSBjb21wb25lbnRNYW5hZ2VyLmdldEZlYXR1cmUoQ09OVElOVUVfQUZURVJfRkFUQUxfRVJST1IsIGZhbHNlKTsKLSAgICAgICAgICAgIGlmICghZmF0YWxFcnJvcikgewotICAgICAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnNldEZlYXR1cmUoQ09OVElOVUVfQUZURVJfRkFUQUxfRVJST1IsIGZhdGFsRXJyb3IpOwotICAgICAgICAgICAgfQotICAgICAgICB9IGNhdGNoIChYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgfQotICAgICAgICAvLyBzZXQgZnVsbCB2YWxpZGF0aW9uIHRvIGZhbHNlCi0gICAgICAgIGZJc0NoZWNrZWRGdWxseSA9IGNvbXBvbmVudE1hbmFnZXIuZ2V0RmVhdHVyZShTQ0hFTUFfRlVMTF9DSEVDS0lORywgZmFsc2UpOwotCi0gICAgICAgIC8vIGdldCBnZW5lcmF0ZS1zeW50aGV0aWMtYW5ub3RhdGlvbnMgZmVhdHVyZQotICAgICAgICBmU2NoZW1hSGFuZGxlci5zZXRHZW5lcmF0ZVN5bnRoZXRpY0Fubm90YXRpb25zKGNvbXBvbmVudE1hbmFnZXIuZ2V0RmVhdHVyZShHRU5FUkFURV9TWU5USEVUSUNfQU5OT1RBVElPTlMsIGZhbHNlKSk7Ci0gICAgICAgIGZTY2hlbWFIYW5kbGVyLnJlc2V0KGNvbXBvbmVudE1hbmFnZXIpOwotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBpbml0R3JhbW1hckJ1Y2tldCgpewotICAgICAgICBpZihmR3JhbW1hclBvb2wgIT0gbnVsbCkgewotICAgICAgICAgICAgR3JhbW1hciBbXSBpbml0aWFsR3JhbW1hcnMgPSBmR3JhbW1hclBvb2wucmV0cmlldmVJbml0aWFsR3JhbW1hclNldChYTUxHcmFtbWFyRGVzY3JpcHRpb24uWE1MX1NDSEVNQSk7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGluaXRpYWxHcmFtbWFycy5sZW5ndGg7IGkrKykgewotICAgICAgICAgICAgICAgIC8vIHB1dCB0aGlzIGdyYW1tYXIgaW50byB0aGUgYnVja2V0LCBhbG9uZyB3aXRoIGdyYW1tYXJzCi0gICAgICAgICAgICAgICAgLy8gaW1wb3J0ZWQgYnkgaXQgKGRpcmVjdGx5IG9yIGluZGlyZWN0bHkpCi0gICAgICAgICAgICAgICAgaWYgKCFmR3JhbW1hckJ1Y2tldC5wdXRHcmFtbWFyKChTY2hlbWFHcmFtbWFyKShpbml0aWFsR3JhbW1hcnNbaV0pLCB0cnVlKSkgewotICAgICAgICAgICAgICAgICAgICAvLyBSRVZJU0lUOiBhIGNvbmZsaWN0IGJldHdlZW4gbmV3IGdyYW1tYXIocykgYW5kIGdyYW1tYXJzCi0gICAgICAgICAgICAgICAgICAgIC8vIGluIHRoZSBidWNrZXQuIFdoYXQgdG8gZG8/IEEgd2FybmluZz8gQW4gZXhjZXB0aW9uPwotICAgICAgICAgICAgICAgICAgICBmRXJyb3JSZXBvcnRlci5yZXBvcnRFcnJvcihYU01lc3NhZ2VGb3JtYXR0ZXIuU0NIRU1BX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAiR3JhbW1hckNvbmZsaWN0IiwgbnVsbCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxFcnJvclJlcG9ydGVyLlNFVkVSSVRZX1dBUk5JTkcpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotCi0gICAgLyogKG5vbi1KYXZhZG9jKQotICAgICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU0xvYWRlciNnZXRDb25maWcoKQotICAgICAqLwotICAgIHB1YmxpYyBET01Db25maWd1cmF0aW9uIGdldENvbmZpZygpIHsKLSAgICAgICAgcmV0dXJuIHRoaXM7Ci0gICAgfQotCi0gICAgLyogKG5vbi1KYXZhZG9jKQotICAgICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU0xvYWRlciNsb2FkKG9yZy53M2MuZG9tLmxzLkxTSW5wdXQpCi0gICAgICovCi0gICAgcHVibGljIFhTTW9kZWwgbG9hZChMU0lucHV0IGlzKSB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBHcmFtbWFyIGcgPSBsb2FkR3JhbW1hcihkb20yeG1sSW5wdXRTb3VyY2UoaXMpKTsKLSAgICAgICAgICAgIHJldHVybiAoKFhTR3JhbW1hcikgZykudG9YU01vZGVsKCk7Ci0gICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICByZXBvcnRET01GYXRhbEVycm9yKGUpOwotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKiAobm9uLUphdmFkb2MpCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTTG9hZGVyI2xvYWRJbnB1dExpc3QoY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5ET01JbnB1dExpc3QpCi0gICAgICovCi0gICAgcHVibGljIFhTTW9kZWwgbG9hZElucHV0TGlzdChMU0lucHV0TGlzdCBpcykgewotICAgICAgICBpbnQgbGVuZ3RoID0gaXMuZ2V0TGVuZ3RoKCk7Ci0gICAgICAgIFNjaGVtYUdyYW1tYXJbXSBncyA9IG5ldyBTY2hlbWFHcmFtbWFyW2xlbmd0aF07Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgZ3NbaV0gPSAoU2NoZW1hR3JhbW1hcikgbG9hZEdyYW1tYXIoZG9tMnhtbElucHV0U291cmNlKGlzLml0ZW0oaSkpKTsKLSAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgcmVwb3J0RE9NRmF0YWxFcnJvcihlKTsKLSAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbmV3IFhTTW9kZWxJbXBsKGdzKTsKLSAgICB9Ci0KLSAgICAvKiAobm9uLUphdmFkb2MpCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTTG9hZGVyI2xvYWRVUkkoamF2YS5sYW5nLlN0cmluZykKLSAgICAgKi8KLSAgICBwdWJsaWMgWFNNb2RlbCBsb2FkVVJJKFN0cmluZyB1cmkpIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIEdyYW1tYXIgZyA9IGxvYWRHcmFtbWFyKG5ldyBYTUxJbnB1dFNvdXJjZShudWxsLCB1cmksIG51bGwpKTsKLSAgICAgICAgICAgIHJldHVybiAoKFhTR3JhbW1hcilnKS50b1hTTW9kZWwoKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGUpewotICAgICAgICAgICAgcmVwb3J0RE9NRmF0YWxFcnJvcihlKTsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyogKG5vbi1KYXZhZG9jKQotICAgICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU0xvYWRlciNsb2FkVVJJTGlzdChjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlN0cmluZ0xpc3QpCi0gICAgICovCi0gICAgcHVibGljIFhTTW9kZWwgbG9hZFVSSUxpc3QoU3RyaW5nTGlzdCB1cmlMaXN0KSB7Ci0gICAgICAgIGludCBsZW5ndGggPSB1cmlMaXN0LmdldExlbmd0aCgpOwotICAgICAgICBTY2hlbWFHcmFtbWFyW10gZ3MgPSBuZXcgU2NoZW1hR3JhbW1hcltsZW5ndGhdOwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIGdzW2ldID0KLSAgICAgICAgICAgICAgICAgICAgKFNjaGVtYUdyYW1tYXIpIGxvYWRHcmFtbWFyKG5ldyBYTUxJbnB1dFNvdXJjZShudWxsLCB1cmlMaXN0Lml0ZW0oaSksIG51bGwpKTsKLSAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgcmVwb3J0RE9NRmF0YWxFcnJvcihlKTsKLSAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbmV3IFhTTW9kZWxJbXBsKGdzKTsKLSAgICB9Ci0KLSAgICB2b2lkIHJlcG9ydERPTUZhdGFsRXJyb3IoRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICBpZiAoZkVycm9ySGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIERPTUVycm9ySW1wbCBlcnJvciA9IG5ldyBET01FcnJvckltcGwoKTsKLSAgICAgICAgICAgICAgICAgICAgZXJyb3IuZkV4Y2VwdGlvbiA9IGU7Ci0gICAgICAgICAgICAgICAgICAgIGVycm9yLmZNZXNzYWdlID0gZS5nZXRNZXNzYWdlKCk7Ci0gICAgICAgICAgICAgICAgICAgIGVycm9yLmZTZXZlcml0eSA9IERPTUVycm9yLlNFVkVSSVRZX0ZBVEFMX0VSUk9SOwotICAgICAgICAgICAgICAgICAgICBmRXJyb3JIYW5kbGVyLmdldEVycm9ySGFuZGxlcigpLmhhbmRsZUVycm9yKGVycm9yKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAvKiAobm9uLUphdmFkb2MpCi0gICAgICogQHNlZSBET01Db25maWd1cmF0aW9uI2NhblNldFBhcmFtZXRlcihTdHJpbmcsIE9iamVjdCkKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBjYW5TZXRQYXJhbWV0ZXIoU3RyaW5nIG5hbWUsIE9iamVjdCB2YWx1ZSkgewotICAgICAgICBpZih2YWx1ZSBpbnN0YW5jZW9mIEJvb2xlYW4pewotICAgICAgICAgICAgaWYgKG5hbWUuZXF1YWxzKENvbnN0YW50cy5ET01fVkFMSURBVEUpIHx8Ci0gICAgICAgICAgICAgICAgbmFtZS5lcXVhbHMoU0NIRU1BX0ZVTExfQ0hFQ0tJTkcpIHx8Ci0gICAgICAgICAgICAgICAgbmFtZS5lcXVhbHMoVkFMSURBVEVfQU5OT1RBVElPTlMpIHx8Ci0gICAgICAgICAgICAgICAgbmFtZS5lcXVhbHMoQ09OVElOVUVfQUZURVJfRkFUQUxfRVJST1IpIHx8Ci0gICAgICAgICAgICAgICAgbmFtZS5lcXVhbHMoQUxMT1dfSkFWQV9FTkNPRElOR1MpIHx8Ci0gICAgICAgICAgICAgICAgbmFtZS5lcXVhbHMoU1RBTkRBUkRfVVJJX0NPTkZPUk1BTlRfRkVBVFVSRSkgfHwKLSAgICAgICAgICAgICAgICBuYW1lLmVxdWFscyhHRU5FUkFURV9TWU5USEVUSUNfQU5OT1RBVElPTlMpIHx8Ci0gICAgICAgICAgICAgICAgbmFtZS5lcXVhbHMoSE9OT1VSX0FMTF9TQ0hFTUFMT0NBVElPTlMpIHx8Ci0gICAgICAgICAgICAgICAgbmFtZS5lcXVhbHMoTkFNRVNQQUNFX0dST1dUSCkgfHwKLSAgICAgICAgICAgICAgICBuYW1lLmVxdWFscyhUT0xFUkFURV9EVVBMSUNBVEVTKSB8fAotICAgICAgICAgICAgICAgIG5hbWUuZXF1YWxzKFVTRV9TRVJWSUNFX01FQ0hBTklTTSkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLQotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0gICAgICAgIGlmIChuYW1lLmVxdWFscyhDb25zdGFudHMuRE9NX0VSUk9SX0hBTkRMRVIpIHx8Ci0gICAgICAgICAgICBuYW1lLmVxdWFscyhDb25zdGFudHMuRE9NX1JFU09VUkNFX1JFU09MVkVSKSB8fAotICAgICAgICAgICAgbmFtZS5lcXVhbHMoU1lNQk9MX1RBQkxFKSB8fAotICAgICAgICAgICAgbmFtZS5lcXVhbHMoRVJST1JfUkVQT1JURVIpIHx8Ci0gICAgICAgICAgICBuYW1lLmVxdWFscyhFUlJPUl9IQU5ETEVSKSB8fAotICAgICAgICAgICAgbmFtZS5lcXVhbHMoRU5USVRZX1JFU09MVkVSKSB8fAotICAgICAgICAgICAgbmFtZS5lcXVhbHMoWE1MR1JBTU1BUl9QT09MKSB8fAotICAgICAgICAgICAgbmFtZS5lcXVhbHMoU0NIRU1BX0xPQ0FUSU9OKSB8fAotICAgICAgICAgICAgbmFtZS5lcXVhbHMoU0NIRU1BX05PTlNfTE9DQVRJT04pIHx8Ci0gICAgICAgICAgICBuYW1lLmVxdWFscyhKQVhQX1NDSEVNQV9TT1VSQ0UpIHx8Ci0gICAgICAgICAgICBuYW1lLmVxdWFscyhTQ0hFTUFfRFZfRkFDVE9SWSkpIHsKLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICAvKiAobm9uLUphdmFkb2MpCi0gICAgICogQHNlZSBET01Db25maWd1cmF0aW9uI2dldFBhcmFtZXRlcihTdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIE9iamVjdCBnZXRQYXJhbWV0ZXIoU3RyaW5nIG5hbWUpIHRocm93cyBET01FeGNlcHRpb24gewotCi0gICAgICAgIGlmIChuYW1lLmVxdWFscyhDb25zdGFudHMuRE9NX0VSUk9SX0hBTkRMRVIpKXsKLSAgICAgICAgICAgIHJldHVybiAoZkVycm9ySGFuZGxlciAhPSBudWxsKSA/IGZFcnJvckhhbmRsZXIuZ2V0RXJyb3JIYW5kbGVyKCkgOiBudWxsOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzKENvbnN0YW50cy5ET01fUkVTT1VSQ0VfUkVTT0xWRVIpKSB7Ci0gICAgICAgICAgICByZXR1cm4gKGZSZXNvdXJjZVJlc29sdmVyICE9IG51bGwpID8gZlJlc291cmNlUmVzb2x2ZXIuZ2V0RW50aXR5UmVzb2x2ZXIoKSA6IG51bGw7Ci0gICAgICAgIH0KLQotICAgICAgICB0cnkgewotICAgICAgICAgICAgYm9vbGVhbiBmZWF0dXJlID0gZ2V0RmVhdHVyZShuYW1lKTsKLSAgICAgICAgICAgIHJldHVybiAoZmVhdHVyZSkgPyBCb29sZWFuLlRSVUUgOiBCb29sZWFuLkZBTFNFOwotICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgT2JqZWN0IHByb3BlcnR5OwotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICBwcm9wZXJ0eSA9IGdldFByb3BlcnR5KG5hbWUpOwotICAgICAgICAgICAgICAgIHJldHVybiBwcm9wZXJ0eTsKLSAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgewotICAgICAgICAgICAgICAgIFN0cmluZyBtc2cgPQotICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICJGRUFUVVJFX05PVF9TVVBQT1JURUQiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7IG5hbWUgfSk7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIsIG1zZyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKiAobm9uLUphdmFkb2MpCi0gICAgICogQHNlZSBET01Db25maWd1cmF0aW9uI2dldFBhcmFtZXRlck5hbWVzKCkKLSAgICAgKi8KLSAgICBwdWJsaWMgRE9NU3RyaW5nTGlzdCBnZXRQYXJhbWV0ZXJOYW1lcygpIHsKLSAgICAgICAgaWYgKGZSZWNvZ25pemVkUGFyYW1ldGVycyA9PSBudWxsKXsKLSAgICAgICAgICAgIFZlY3RvciB2ID0gbmV3IFZlY3RvcigpOwotICAgICAgICAgICAgdi5hZGQoQ29uc3RhbnRzLkRPTV9WQUxJREFURSk7Ci0gICAgICAgICAgICB2LmFkZChDb25zdGFudHMuRE9NX0VSUk9SX0hBTkRMRVIpOwotICAgICAgICAgICAgdi5hZGQoQ29uc3RhbnRzLkRPTV9SRVNPVVJDRV9SRVNPTFZFUik7Ci0gICAgICAgICAgICB2LmFkZChTWU1CT0xfVEFCTEUpOwotICAgICAgICAgICAgdi5hZGQoRVJST1JfUkVQT1JURVIpOwotICAgICAgICAgICAgdi5hZGQoRVJST1JfSEFORExFUik7Ci0gICAgICAgICAgICB2LmFkZChFTlRJVFlfUkVTT0xWRVIpOwotICAgICAgICAgICAgdi5hZGQoWE1MR1JBTU1BUl9QT09MKTsKLSAgICAgICAgICAgIHYuYWRkKFNDSEVNQV9MT0NBVElPTik7Ci0gICAgICAgICAgICB2LmFkZChTQ0hFTUFfTk9OU19MT0NBVElPTik7Ci0gICAgICAgICAgICB2LmFkZChKQVhQX1NDSEVNQV9TT1VSQ0UpOwotICAgICAgICAgICAgdi5hZGQoU0NIRU1BX0ZVTExfQ0hFQ0tJTkcpOwotICAgICAgICAgICAgdi5hZGQoQ09OVElOVUVfQUZURVJfRkFUQUxfRVJST1IpOwotICAgICAgICAgICAgdi5hZGQoQUxMT1dfSkFWQV9FTkNPRElOR1MpOwotICAgICAgICAgICAgdi5hZGQoU1RBTkRBUkRfVVJJX0NPTkZPUk1BTlRfRkVBVFVSRSk7Ci0gICAgICAgICAgICB2LmFkZChWQUxJREFURV9BTk5PVEFUSU9OUyk7Ci0gICAgICAgICAgICB2LmFkZChHRU5FUkFURV9TWU5USEVUSUNfQU5OT1RBVElPTlMpOwotICAgICAgICAgICAgdi5hZGQoSE9OT1VSX0FMTF9TQ0hFTUFMT0NBVElPTlMpOwotICAgICAgICAgICAgdi5hZGQoTkFNRVNQQUNFX0dST1dUSCk7Ci0gICAgICAgICAgICB2LmFkZChUT0xFUkFURV9EVVBMSUNBVEVTKTsKLSAgICAgICAgICAgIHYuYWRkKFVTRV9TRVJWSUNFX01FQ0hBTklTTSk7Ci0gICAgICAgICAgICBmUmVjb2duaXplZFBhcmFtZXRlcnMgPSBuZXcgRE9NU3RyaW5nTGlzdEltcGwodik7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGZSZWNvZ25pemVkUGFyYW1ldGVyczsKLSAgICB9Ci0KLSAgICAvKiAobm9uLUphdmFkb2MpCi0gICAgICogQHNlZSBET01Db25maWd1cmF0aW9uI3NldFBhcmFtZXRlcihTdHJpbmcsIE9iamVjdCkKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRQYXJhbWV0ZXIoU3RyaW5nIG5hbWUsIE9iamVjdCB2YWx1ZSkgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIEJvb2xlYW4pIHsKLSAgICAgICAgICAgIGJvb2xlYW4gc3RhdGUgPSAoKEJvb2xlYW4pIHZhbHVlKS5ib29sZWFuVmFsdWUoKTsKLSAgICAgICAgICAgIGlmIChuYW1lLmVxdWFscygidmFsaWRhdGUiKSAmJiBzdGF0ZSkgewotICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgc2V0RmVhdHVyZShuYW1lLCBzdGF0ZSk7Ci0gICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgIFN0cmluZyBtc2cgPQotICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICJGRUFUVVJFX05PVF9TVVBQT1JURUQiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7IG5hbWUgfSk7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIsIG1zZyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKG5hbWUuZXF1YWxzKENvbnN0YW50cy5ET01fRVJST1JfSEFORExFUikpIHsKLSAgICAgICAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIERPTUVycm9ySGFuZGxlcikgewotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgIGZFcnJvckhhbmRsZXIgPSBuZXcgRE9NRXJyb3JIYW5kbGVyV3JhcHBlcigoRE9NRXJyb3JIYW5kbGVyKSB2YWx1ZSk7Ci0gICAgICAgICAgICAgICAgICAgIHNldEVycm9ySGFuZGxlcihmRXJyb3JIYW5kbGVyKTsKLSAgICAgICAgICAgICAgICB9IGNhdGNoIChYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIC8vIFJFVklTSVQ6IHR5cGUgbWlzbWF0Y2gKLSAgICAgICAgICAgICAgICBTdHJpbmcgbXNnID0KLSAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRkVBVFVSRV9OT1RfU1VQUE9SVEVEIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBuYW1lIH0pOwotICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSLCBtc2cpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuOwotCi0gICAgICAgIH0KLSAgICAgICAgaWYgKG5hbWUuZXF1YWxzKENvbnN0YW50cy5ET01fUkVTT1VSQ0VfUkVTT0xWRVIpKSB7Ci0gICAgICAgICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBMU1Jlc291cmNlUmVzb2x2ZXIpIHsKLSAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICBmUmVzb3VyY2VSZXNvbHZlciA9IG5ldyBET01FbnRpdHlSZXNvbHZlcldyYXBwZXIoKExTUmVzb3VyY2VSZXNvbHZlcikgdmFsdWUpOwotICAgICAgICAgICAgICAgICAgICBzZXRFbnRpdHlSZXNvbHZlcihmUmVzb3VyY2VSZXNvbHZlcik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGNhdGNoIChYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIGUpIHt9Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIC8vIFJFVklTSVQ6IHR5cGUgbWlzbWF0Y2gKLSAgICAgICAgICAgICAgICBTdHJpbmcgbXNnID0KLSAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRkVBVFVSRV9OT1RfU1VQUE9SVEVEIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBuYW1lIH0pOwotICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSLCBtc2cpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIHNldFByb3BlcnR5KG5hbWUsIHZhbHVlKTsKLSAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7Ci0KLSAgICAgICAgICAgIFN0cmluZyBtc2cgPQotICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZSgKLSAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICJGRUFUVVJFX05PVF9TVVBQT1JURUQiLAotICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgbmFtZSB9KTsKLSAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSLCBtc2cpOwotCi0gICAgICAgIH0KLQotICAgIH0KLQotICAgICAgICBYTUxJbnB1dFNvdXJjZSBkb20yeG1sSW5wdXRTb3VyY2UoTFNJbnB1dCBpcykgewotICAgICAgICAvLyBuZWVkIHRvIHdyYXAgdGhlIExTSW5wdXQgd2l0aCBhbiBYTUxJbnB1dFNvdXJjZQotICAgICAgICBYTUxJbnB1dFNvdXJjZSB4aXMgPSBudWxsOwotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBBbiBMU1BhcnNlciBsb29rcyBhdCBpbnB1dHMgc3BlY2lmaWVkIGluIExTSW5wdXQgaW4KLSAgICAgICAgICogdGhlIGZvbGxvd2luZyBvcmRlcjogY2hhcmFjdGVyU3RyZWFtLCBieXRlU3RyZWFtLAotICAgICAgICAgKiBzdHJpbmdEYXRhLCBzeXN0ZW1JZCwgcHVibGljSWQuIEZvciBjb25zaXN0ZW5jeQotICAgICAgICAgKiBoYXZlIHRoZSBzYW1lIGJlaGF2aW91ciBmb3IgWFNMb2FkZXIuCi0gICAgICAgICAqLwotCi0gICAgICAgIC8vIGNoZWNrIHdoZXRoZXIgdGhlcmUgaXMgYSBSZWFkZXIKLSAgICAgICAgLy8gYWNjb3JkaW5nIHRvIERPTSwgd2UgbmVlZCB0byB0cmVhdCBzdWNoIHJlYWRlciBhcyAiVVRGLTE2Ii4KLSAgICAgICAgaWYgKGlzLmdldENoYXJhY3RlclN0cmVhbSgpICE9IG51bGwpIHsKLSAgICAgICAgICAgIHhpcyA9IG5ldyBYTUxJbnB1dFNvdXJjZShpcy5nZXRQdWJsaWNJZCgpLCBpcy5nZXRTeXN0ZW1JZCgpLAotICAgICAgICAgICAgICAgICAgICBpcy5nZXRCYXNlVVJJKCksIGlzLmdldENoYXJhY3RlclN0cmVhbSgpLAotICAgICAgICAgICAgIlVURi0xNiIpOwotICAgICAgICB9Ci0gICAgICAgIC8vIGNoZWNrIHdoZXRoZXIgdGhlcmUgaXMgYW4gSW5wdXRTdHJlYW0KLSAgICAgICAgZWxzZSBpZiAoaXMuZ2V0Qnl0ZVN0cmVhbSgpICE9IG51bGwpIHsKLSAgICAgICAgICAgIHhpcyA9IG5ldyBYTUxJbnB1dFNvdXJjZShpcy5nZXRQdWJsaWNJZCgpLCBpcy5nZXRTeXN0ZW1JZCgpLAotICAgICAgICAgICAgICAgICAgICBpcy5nZXRCYXNlVVJJKCksIGlzLmdldEJ5dGVTdHJlYW0oKSwKLSAgICAgICAgICAgICAgICAgICAgaXMuZ2V0RW5jb2RpbmcoKSk7Ci0gICAgICAgIH0KLSAgICAgICAgLy8gaWYgdGhlcmUgaXMgYSBzdHJpbmcgZGF0YSwgdXNlIGEgU3RyaW5nUmVhZGVyCi0gICAgICAgIC8vIGFjY29yZGluZyB0byBET00sIHdlIG5lZWQgdG8gdHJlYXQgc3VjaCBkYXRhIGFzICJVVEYtMTYiLgotICAgICAgICBlbHNlIGlmIChpcy5nZXRTdHJpbmdEYXRhKCkgIT0gbnVsbCAmJiBpcy5nZXRTdHJpbmdEYXRhKCkubGVuZ3RoKCkgIT0gMCkgewotICAgICAgICAgICAgeGlzID0gbmV3IFhNTElucHV0U291cmNlKGlzLmdldFB1YmxpY0lkKCksIGlzLmdldFN5c3RlbUlkKCksCi0gICAgICAgICAgICAgICAgICAgIGlzLmdldEJhc2VVUkkoKSwgbmV3IFN0cmluZ1JlYWRlcihpcy5nZXRTdHJpbmdEYXRhKCkpLAotICAgICAgICAgICAgIlVURi0xNiIpOwotICAgICAgICB9Ci0gICAgICAgIC8vIG90aGVyd2lzZSwganVzdCB1c2UgdGhlIHB1YmxpYy9zeXN0ZW0vYmFzZSBJZHMKLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICB4aXMgPSBuZXcgWE1MSW5wdXRTb3VyY2UoaXMuZ2V0UHVibGljSWQoKSwgaXMuZ2V0U3lzdGVtSWQoKSwKLSAgICAgICAgICAgICAgICAgICAgaXMuZ2V0QmFzZVVSSSgpKTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiB4aXM7Ci0gICAgfQotCi19IC8vIFhNTEdyYW1tYXJMb2FkZXIKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvWE1MU2NoZW1hVmFsaWRhdG9yLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL1hNTFNjaGVtYVZhbGlkYXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjMTM4YjdmLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvWE1MU2NoZW1hVmFsaWRhdG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0MzA3ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKi8KLS8qCi0gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKLSAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAotICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgotICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKLSAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCi0gKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54czsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5Db25zdGFudHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLlJldmFsaWRhdGlvbkhhbmRsZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLlhNTEVudGl0eU1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLlhNTEVycm9yUmVwb3J0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LkRhdGF0eXBlRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5JbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYuVmFsaWRhdGVkSW5mbzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYuWFNTaW1wbGVUeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC52YWxpZGF0aW9uLlZhbGlkYXRpb25NYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC52YWxpZGF0aW9uLlZhbGlkYXRpb25TdGF0ZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMuaWRlbnRpdHkuRmllbGQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLmlkZW50aXR5LkZpZWxkQWN0aXZhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5pZGVudGl0eS5JZGVudGl0eUNvbnN0cmFpbnQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLmlkZW50aXR5LktleVJlZjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMuaWRlbnRpdHkuU2VsZWN0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLmlkZW50aXR5LlVuaXF1ZU9yS2V5OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5pZGVudGl0eS5WYWx1ZVN0b3JlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5pZGVudGl0eS5YUGF0aE1hdGNoZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLm1vZGVscy5DTUJ1aWxkZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLm1vZGVscy5DTU5vZGVGYWN0b3J5OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5tb2RlbHMuWFNDTVZhbGlkYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnBhcnNlcnMuWE1MUGFyc2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5BdWdtZW50YXRpb25zSW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuSW50U3RhY2s7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlN5bWJvbFRhYmxlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5VUkkuTWFsZm9ybWVkVVJJRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5YTUxBdHRyaWJ1dGVzSW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuWE1MQ2hhcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuWE1MU3ltYm9sczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5BdWdtZW50YXRpb25zOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLk5hbWVzcGFjZUNvbnRleHQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuUU5hbWU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MQXR0cmlidXRlczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxEb2N1bWVudEhhbmRsZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MTG9jYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxSZXNvdXJjZUlkZW50aWZpZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MU3RyaW5nOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhOSUV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5ncmFtbWFycy5YTUxHcmFtbWFyRGVzY3JpcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuZ3JhbW1hcnMuWE1MR3JhbW1hclBvb2w7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTENvbXBvbmVudDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MQ29tcG9uZW50TWFuYWdlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MRG9jdW1lbnRGaWx0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTERvY3VtZW50U291cmNlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxFbnRpdHlSZXNvbHZlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MSW5wdXRTb3VyY2U7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5BdHRyaWJ1dGVQU1ZJOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuRWxlbWVudFBTVkk7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5TaG9ydExpc3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5TdHJpbmdMaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNDb25zdGFudHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU09iamVjdExpc3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU1R5cGVEZWZpbml0aW9uOwotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci1pbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKLWltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7Ci1pbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7Ci1pbXBvcnQgamF2YS51dGlsLk1hcDsKLWltcG9ydCBqYXZhLnV0aWwuU3RhY2s7Ci1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotLyoqCi0gKiBUaGUgWE1MIFNjaGVtYSB2YWxpZGF0b3IuIFRoZSB2YWxpZGF0b3IgaW1wbGVtZW50cyBhIGRvY3VtZW50Ci0gKiBmaWx0ZXI6IHJlY2VpdmluZyBkb2N1bWVudCBldmVudHMgZnJvbSB0aGUgc2Nhbm5lcjsgdmFsaWRhdGluZwotICogdGhlIGNvbnRlbnQgYW5kIHN0cnVjdHVyZTsgYXVnbWVudGluZyB0aGUgSW5mb1NldCwgaWYgYXBwbGljYWJsZTsKLSAqIGFuZCBub3RpZnlpbmcgdGhlIHBhcnNlciBvZiB0aGUgaW5mb3JtYXRpb24gcmVzdWx0aW5nIGZyb20gdGhlCi0gKiB2YWxpZGF0aW9uIHByb2Nlc3MuCi0gKiA8cD4KLSAqIFRoaXMgY29tcG9uZW50IHJlcXVpcmVzIHRoZSBmb2xsb3dpbmcgZmVhdHVyZXMgYW5kIHByb3BlcnRpZXMgZnJvbSB0aGUKLSAqIGNvbXBvbmVudCBtYW5hZ2VyIHRoYXQgdXNlcyBpdDoKLSAqIDx1bD4KLSAqICA8bGk+aHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL3ZhbGlkYXRpb248L2xpPgotICogIDxsaT5odHRwOi8vYXBhY2hlLm9yZy94bWwvcHJvcGVydGllcy9pbnRlcm5hbC9zeW1ib2wtdGFibGU8L2xpPgotICogIDxsaT5odHRwOi8vYXBhY2hlLm9yZy94bWwvcHJvcGVydGllcy9pbnRlcm5hbC9lcnJvci1yZXBvcnRlcjwvbGk+Ci0gKiAgPGxpPmh0dHA6Ly9hcGFjaGUub3JnL3htbC9wcm9wZXJ0aWVzL2ludGVybmFsL2VudGl0eS1yZXNvbHZlcjwvbGk+Ci0gKiA8L3VsPgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIFNhbmR5IEdhbyBJQk0KLSAqIEBhdXRob3IgRWxlbmEgTGl0YW5pIElCTQotICogQGF1dGhvciBBbmR5IENsYXJrIElCTQotICogQGF1dGhvciBOZWVyYWogQmFqYWosIFN1biBNaWNyb3N5c3RlbXMsIGluYy4KLSAqIEB2ZXJzaW9uICRJZDogWE1MU2NoZW1hVmFsaWRhdG9yLmphdmEsdiAxLjE2IDIwMTAtMTEtMDEgMDQ6Mzk6NTUgam9laHcgRXhwICQKLSAqLwotcHVibGljIGNsYXNzIFhNTFNjaGVtYVZhbGlkYXRvcgotICAgIGltcGxlbWVudHMgWE1MQ29tcG9uZW50LCBYTUxEb2N1bWVudEZpbHRlciwgRmllbGRBY3RpdmF0b3IsIFJldmFsaWRhdGlvbkhhbmRsZXIgewotCi0gICAgLy8KLSAgICAvLyBDb25zdGFudHMKLSAgICAvLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW4gREVCVUcgPSBmYWxzZTsKLQotICAgIC8vIGZlYXR1cmUgaWRlbnRpZmllcnMKLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IHZhbGlkYXRpb24uICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgVkFMSURBVElPTiA9Ci0gICAgICAgIENvbnN0YW50cy5TQVhfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuVkFMSURBVElPTl9GRUFUVVJFOwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogdmFsaWRhdGlvbi4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBTQ0hFTUFfVkFMSURBVElPTiA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuU0NIRU1BX1ZBTElEQVRJT05fRkVBVFVSRTsKLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IHNjaGVtYSBmdWxsIGNoZWNraW5nKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBTQ0hFTUFfRlVMTF9DSEVDS0lORyA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuU0NIRU1BX0ZVTExfQ0hFQ0tJTkc7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiBkeW5hbWljIHZhbGlkYXRpb24uICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgRFlOQU1JQ19WQUxJREFUSU9OID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5EWU5BTUlDX1ZBTElEQVRJT05fRkVBVFVSRTsKLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IGV4cG9zZSBzY2hlbWEgbm9ybWFsaXplZCB2YWx1ZSAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIE5PUk1BTElaRV9EQVRBID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5TQ0hFTUFfTk9STUFMSVpFRF9WQUxVRTsKLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IHNlbmQgZWxlbWVudCBkZWZhdWx0IHZhbHVlIHZpYSBjaGFyYWN0ZXJzKCkgKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBTQ0hFTUFfRUxFTUVOVF9ERUZBVUxUID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5TQ0hFTUFfRUxFTUVOVF9ERUZBVUxUOwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogYXVnbWVudCBQU1ZJICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgU0NIRU1BX0FVR01FTlRfUFNWSSA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuU0NIRU1BX0FVR01FTlRfUFNWSTsKLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IHdoZXRoZXIgdG8gcmVjb2duaXplIGphdmEgZW5jb2RpbmcgbmFtZXMgKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBBTExPV19KQVZBX0VOQ09ESU5HUyA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuQUxMT1dfSkFWQV9FTkNPRElOR1NfRkVBVFVSRTsKLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IHN0YW5kYXJkIHVyaSBjb25mb3JtYW50IGZlYXR1cmUuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1RBTkRBUkRfVVJJX0NPTkZPUk1BTlRfRkVBVFVSRSA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuU1RBTkRBUkRfVVJJX0NPTkZPUk1BTlRfRkVBVFVSRTsKLQotICAgIC8qKiBGZWF0dXJlOiBnZW5lcmF0ZSBzeW50aGV0aWMgYW5ub3RhdGlvbnMgKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBHRU5FUkFURV9TWU5USEVUSUNfQU5OT1RBVElPTlMgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLkdFTkVSQVRFX1NZTlRIRVRJQ19BTk5PVEFUSU9OU19GRUFUVVJFOwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogdmFsaWRhdGUgYW5ub3RhdGlvbnMuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgVkFMSURBVEVfQU5OT1RBVElPTlMgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLlZBTElEQVRFX0FOTk9UQVRJT05TX0ZFQVRVUkU7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiBob25vdXIgYWxsIHNjaGVtYUxvY2F0aW9ucyAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIEhPTk9VUl9BTExfU0NIRU1BTE9DQVRJT05TID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5IT05PVVJfQUxMX1NDSEVNQUxPQ0FUSU9OU19GRUFUVVJFOwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogdXNlIGdyYW1tYXIgcG9vbCBvbmx5ICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgVVNFX0dSQU1NQVJfUE9PTF9PTkxZID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5VU0VfR1JBTU1BUl9QT09MX09OTFlfRkVBVFVSRTsKLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IHdoZXRoZXIgdG8gY29udGludWUgcGFyc2luZyBhIHNjaGVtYSBhZnRlciBhIGZhdGFsIGVycm9yIGlzIGVuY291bnRlcmVkICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ09OVElOVUVfQUZURVJfRkFUQUxfRVJST1IgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLkNPTlRJTlVFX0FGVEVSX0ZBVEFMX0VSUk9SX0ZFQVRVUkU7Ci0KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBQQVJTRVJfU0VUVElOR1MgPQotICAgICAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5QQVJTRVJfU0VUVElOR1M7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiBuYW1lc3BhY2UgZ3Jvd3RoICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgTkFNRVNQQUNFX0dST1dUSCA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuTkFNRVNQQUNFX0dST1dUSF9GRUFUVVJFOwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogdG9sZXJhdGUgZHVwbGljYXRlcyAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFRPTEVSQVRFX0RVUExJQ0FURVMgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLlRPTEVSQVRFX0RVUExJQ0FURVNfRkVBVFVSRTsKLQotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFJFUE9SVF9XSElURVNQQUNFID0KLSAgICAgICAgICAgIENvbnN0YW50cy5TVU5fU0NIRU1BX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLlNVTl9SRVBPUlRfSUdOT1JFRF9FTEVNRU5UX0NPTlRFTlRfV0hJVEVTUEFDRTsKLQotICAgIC8vIHByb3BlcnR5IGlkZW50aWZpZXJzCi0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogc3ltYm9sIHRhYmxlLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFNZTUJPTF9UQUJMRSA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLlNZTUJPTF9UQUJMRV9QUk9QRVJUWTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBlcnJvciByZXBvcnRlci4gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJPUl9SRVBPUlRFUiA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLkVSUk9SX1JFUE9SVEVSX1BST1BFUlRZOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IGVudGl0eSByZXNvbHZlci4gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFTlRJVFlfUkVTT0xWRVIgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5FTlRJVFlfUkVTT0xWRVJfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogZ3JhbW1hciBwb29sLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFhNTEdSQU1NQVJfUE9PTCA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLlhNTEdSQU1NQVJfUE9PTF9QUk9QRVJUWTsKLQotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFZBTElEQVRJT05fTUFOQUdFUiA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLlZBTElEQVRJT05fTUFOQUdFUl9QUk9QRVJUWTsKLQotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIEVOVElUWV9NQU5BR0VSID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuRU5USVRZX01BTkFHRVJfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogc2NoZW1hIGxvY2F0aW9uLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFNDSEVNQV9MT0NBVElPTiA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLlNDSEVNQV9MT0NBVElPTjsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBubyBuYW1lc3BhY2Ugc2NoZW1hIGxvY2F0aW9uLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFNDSEVNQV9OT05TX0xPQ0FUSU9OID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuU0NIRU1BX05PTlNfTE9DQVRJT047Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogSkFYUCBzY2hlbWEgc291cmNlLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIEpBWFBfU0NIRU1BX1NPVVJDRSA9Ci0gICAgICAgIENvbnN0YW50cy5KQVhQX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5TQ0hFTUFfU09VUkNFOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IEpBWFAgc2NoZW1hIGxhbmd1YWdlLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIEpBWFBfU0NIRU1BX0xBTkdVQUdFID0KLSAgICAgICAgQ29uc3RhbnRzLkpBWFBfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLlNDSEVNQV9MQU5HVUFHRTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBTY2hlbWEgRFYgRmFjdG9yeSAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFNDSEVNQV9EVl9GQUNUT1JZID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuU0NIRU1BX0RWX0ZBQ1RPUllfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogU2VjdXJpdHkgcHJvcGVydHkgbWFuYWdlci4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MX1NFQ1VSSVRZX1BST1BFUlRZX01BTkFHRVIgPQotICAgICAgICAgICAgQ29uc3RhbnRzLlhNTF9TRUNVUklUWV9QUk9QRVJUWV9NQU5BR0VSOwotCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgVVNFX1NFUlZJQ0VfTUVDSEFOSVNNID0gQ29uc3RhbnRzLk9SQUNMRV9GRUFUVVJFX1NFUlZJQ0VfTUVDSEFOSVNNOwotCi0gICAgLy8gcmVjb2duaXplZCBmZWF0dXJlcyBhbmQgcHJvcGVydGllcwotCi0gICAgLyoqIFJlY29nbml6ZWQgZmVhdHVyZXMuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nW10gUkVDT0dOSVpFRF9GRUFUVVJFUyA9Ci0gICAgICAgIHsKLSAgICAgICAgICAgIFZBTElEQVRJT04sCi0gICAgICAgICAgICBTQ0hFTUFfVkFMSURBVElPTiwKLSAgICAgICAgICAgIERZTkFNSUNfVkFMSURBVElPTiwKLSAgICAgICAgICAgIFNDSEVNQV9GVUxMX0NIRUNLSU5HLAotICAgICAgICAgICAgQUxMT1dfSkFWQV9FTkNPRElOR1MsCi0gICAgICAgICAgICBDT05USU5VRV9BRlRFUl9GQVRBTF9FUlJPUiwKLSAgICAgICAgICAgIFNUQU5EQVJEX1VSSV9DT05GT1JNQU5UX0ZFQVRVUkUsCi0gICAgICAgICAgICBHRU5FUkFURV9TWU5USEVUSUNfQU5OT1RBVElPTlMsCi0gICAgICAgICAgICBWQUxJREFURV9BTk5PVEFUSU9OUywKLSAgICAgICAgICAgIEhPTk9VUl9BTExfU0NIRU1BTE9DQVRJT05TLAotICAgICAgICAgICAgVVNFX0dSQU1NQVJfUE9PTF9PTkxZLAotICAgICAgICAgICAgTkFNRVNQQUNFX0dST1dUSCwKLSAgICAgICAgICAgIFRPTEVSQVRFX0RVUExJQ0FURVMsCi0gICAgICAgICAgICBVU0VfU0VSVklDRV9NRUNIQU5JU00KLSAgICB9OwotCi0gICAgLyoqIEZlYXR1cmUgZGVmYXVsdHMuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQm9vbGVhbltdIEZFQVRVUkVfREVGQVVMVFMgPSB7IG51bGwsCi0gICAgICAgIC8vIE5PVEU6IFRoZSBmb2xsb3dpbmcgZGVmYXVsdHMgYXJlIG51bGxlZCBvdXQgb24gcHVycG9zZS4KLSAgICAgICAgLy8gICAgICAgSWYgdGhleSBhcmUgc2V0LCB0aGVuIHdoZW4gdGhlIFhNTCBTY2hlbWEgdmFsaWRhdG9yCi0gICAgICAgIC8vICAgICAgIGlzIGNvbnN0cnVjdGVkIGR5bmFtaWNhbGx5LCB0aGVzZSB2YWx1ZXMgbWF5IG92ZXJyaWRlCi0gICAgICAgIC8vICAgICAgIHRob3NlIHNldCBieSB0aGUgYXBwbGljYXRpb24uIFRoaXMgZ29lcyBhZ2FpbnN0IHRoZQotICAgICAgICAvLyAgICAgICB3aG9sZSBwdXJwb3NlIG9mIFhNTENvbXBvbmVudCNnZXRGZWF0dXJlRGVmYXVsdCBidXQKLSAgICAgICAgLy8gICAgICAgaXQgY2FuJ3QgYmUgaGVscGVkIGluIHRoaXMgY2FzZS4gLUFjCi0gICAgICAgIG51bGwsIC8vQm9vbGVhbi5GQUxTRSwKLSAgICAgICAgbnVsbCwgLy9Cb29sZWFuLkZBTFNFLAotICAgICAgICBudWxsLCAvL0Jvb2xlYW4uRkFMU0UsCi0gICAgICAgIG51bGwsIC8vQm9vbGVhbi5GQUxTRSwKLSAgICAgICAgbnVsbCwgLy9Cb29sZWFuLkZBTFNFLAotICAgICAgICBudWxsLAotICAgICAgICBudWxsLAotICAgICAgICBudWxsLAotICAgICAgICBudWxsLAotICAgICAgICBudWxsLAotICAgICAgICBudWxsLAotICAgICAgICBudWxsLAotICAgICAgICBCb29sZWFuLlRSVUUKLSAgICB9OwotCi0gICAgLyoqIFJlY29nbml6ZWQgcHJvcGVydGllcy4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSBSRUNPR05JWkVEX1BST1BFUlRJRVMgPQotICAgICAgICB7Ci0gICAgICAgICAgICBTWU1CT0xfVEFCTEUsCi0gICAgICAgICAgICBFUlJPUl9SRVBPUlRFUiwKLSAgICAgICAgICAgIEVOVElUWV9SRVNPTFZFUiwKLSAgICAgICAgICAgIFZBTElEQVRJT05fTUFOQUdFUiwKLSAgICAgICAgICAgIFNDSEVNQV9MT0NBVElPTiwKLSAgICAgICAgICAgIFNDSEVNQV9OT05TX0xPQ0FUSU9OLAotICAgICAgICAgICAgSkFYUF9TQ0hFTUFfU09VUkNFLAotICAgICAgICAgICAgSkFYUF9TQ0hFTUFfTEFOR1VBR0UsCi0gICAgICAgICAgICBTQ0hFTUFfRFZfRkFDVE9SWSwKLSAgICAgICAgICAgIFhNTF9TRUNVUklUWV9QUk9QRVJUWV9NQU5BR0VSCi0gICAgICAgICAgICB9OwotCi0gICAgLyoqIFByb3BlcnR5IGRlZmF1bHRzLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIE9iamVjdFtdIFBST1BFUlRZX0RFRkFVTFRTID0KLSAgICAgICAgeyBudWxsLCBudWxsLCBudWxsLCBudWxsLCBudWxsLCBudWxsLCBudWxsLCBudWxsLCBudWxsLCBudWxsLCBudWxsLCBudWxsLCBudWxsfTsKLQotICAgIC8vIHRoaXMgaXMgdGhlIG51bWJlciBvZiB2YWx1ZXN0b3JlcyBvZiBlYWNoIGtpbmQKLSAgICAvLyB3ZSBleHBlY3QgYW4gZWxlbWVudCB0byBoYXZlLiAgSXQncyBhbG1vc3QKLSAgICAvLyBuZXZlciA+IDE7IHNvIGxlYXZlIGl0IGF0IHRoYXQuCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBpbnQgSURfQ09OU1RSQUlOVF9OVU0gPSAxOwotCi0gICAgLy8KLSAgICAvLyBEYXRhCi0gICAgLy8KLQotICAgIC8qKiBjdXJyZW50IFBTVkkgZWxlbWVudCBpbmZvICovCi0gICAgcHJvdGVjdGVkIEVsZW1lbnRQU1ZJbXBsIGZDdXJyZW50UFNWSSA9IG5ldyBFbGVtZW50UFNWSW1wbCgpOwotCi0gICAgLy8gc2luY2UgaXQgaXMgdGhlIHJlc3BvbnNpYmlsaXR5IG9mIGVhY2ggY29tcG9uZW50IHRvIGFuCi0gICAgLy8gQXVnbWVudGF0aW9ucyBwYXJhbWV0ZXIgaWYgb25lIGlzIG51bGwsIHRvIHNhdmUgb3Vyc2VsdmVzIGZyb20KLSAgICAvLyBoYXZpbmcgdG8gY3JlYXRlIHRoaXMgb2JqZWN0IGNvbnRpbnVhbGx5LCBpdCBpcyBjcmVhdGVkIGhlcmUuCi0gICAgLy8gSWYgaXQgaXMgbm90IHByZXNlbnQgaW4gY2FsbHMgdGhhdCB3ZSdyZSBwYXNzaW5nIG9uLCB3ZSAqbXVzdCoKLSAgICAvLyBjbGVhciB0aGlzIGJlZm9yZSB3ZSBpbnRyb2R1Y2UgaXQgaW50byB0aGUgcGlwZWxpbmUuCi0gICAgcHJvdGVjdGVkIGZpbmFsIEF1Z21lbnRhdGlvbnNJbXBsIGZBdWdtZW50YXRpb25zID0gbmV3IEF1Z21lbnRhdGlvbnNJbXBsKCk7Ci0KLSAgICAvKioKLSAgICAgKiBNYXAgd2hpY2ggaXMgdXNlZCB0byBjYXRjaCBpbnN0YW5jZSBkb2N1bWVudHMgdGhhdCB0cnkKLSAgICAgKiBhbmQgbWF0Y2ggYSBmaWVsZCBzZXZlcmFsIHRpbWVzIGluIHRoZSBzYW1lIHNjb3BlLgotICAgICAqLwotICAgIHByb3RlY3RlZCBmaW5hbCBIYXNoTWFwIGZNYXlNYXRjaEZpZWxkTWFwID0gbmV3IEhhc2hNYXAoKTsKLQotICAgIC8vIHRoaXMgaXMgaW5jbHVkZWQgZm9yIHRoZSBjb252ZW5pZW5jZSBvZiBoYW5kbGVFbmRFbGVtZW50Ci0gICAgcHJvdGVjdGVkIFhNTFN0cmluZyBmRGVmYXVsdFZhbHVlOwotCi0gICAgLy8gVmFsaWRhdGlvbiBmZWF0dXJlcwotICAgIHByb3RlY3RlZCBib29sZWFuIGZEeW5hbWljVmFsaWRhdGlvbiA9IGZhbHNlOwotICAgIHByb3RlY3RlZCBib29sZWFuIGZTY2hlbWFEeW5hbWljVmFsaWRhdGlvbiA9IGZhbHNlOwotICAgIHByb3RlY3RlZCBib29sZWFuIGZEb1ZhbGlkYXRpb24gPSBmYWxzZTsKLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBmRnVsbENoZWNraW5nID0gZmFsc2U7Ci0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZk5vcm1hbGl6ZURhdGEgPSB0cnVlOwotICAgIHByb3RlY3RlZCBib29sZWFuIGZTY2hlbWFFbGVtZW50RGVmYXVsdCA9IHRydWU7Ci0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZkF1Z1BTVkkgPSB0cnVlOwotICAgIHByb3RlY3RlZCBib29sZWFuIGZJZENvbnN0cmFpbnQgPSBmYWxzZTsKLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBmVXNlR3JhbW1hclBvb2xPbmx5ID0gZmFsc2U7Ci0KLSAgICAvLyBOYW1lc3BhY2UgZ3Jvd3RoIGZlYXR1cmUKLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBmTmFtZXNwYWNlR3Jvd3RoID0gZmFsc2U7Ci0KLSAgICAvKiogU2NoZW1hIHR5cGU6IE5vbmUsIERURCwgU2NoZW1hICovCi0gICAgcHJpdmF0ZSBTdHJpbmcgZlNjaGVtYVR5cGUgPSBudWxsOwotCi0gICAgLy8gdG8gaW5kaWNhdGUgd2hldGhlciB3ZSBhcmUgaW4gdGhlIHNjb3BlIG9mIGVudGl0eSByZWZlcmVuY2Ugb3IgQ0RhdGEKLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBmRW50aXR5UmVmID0gZmFsc2U7Ci0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZkluQ0RBVEEgPSBmYWxzZTsKLQotICAgIC8vIERpZCB3ZSBzZWUgb25seSB3aGl0ZXNwYWNlIGluIGVsZW1lbnQgY29udGVudD8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBmU2F3T25seVdoaXRlc3BhY2VJbkVsZW1lbnRDb250ZW50ID0gZmFsc2U7Ci0KLSAgICAvLyBwcm9wZXJ0aWVzCi0KLSAgICAvKiogU3ltYm9sIHRhYmxlLiAqLwotICAgIHByb3RlY3RlZCBTeW1ib2xUYWJsZSBmU3ltYm9sVGFibGU7Ci0KLSAgICAvKioKLSAgICAgKiBXaGlsZSBwYXJzaW5nIGEgZG9jdW1lbnQsIGtlZXAgdGhlIGxvY2F0aW9uIG9mIHRoZSBkb2N1bWVudC4KLSAgICAgKi8KLSAgICBwcml2YXRlIFhNTExvY2F0b3IgZkxvY2F0b3I7Ci0KLSAgICAvKioKLSAgICAgKiBBIHdyYXBwZXIgb2YgdGhlIHN0YW5kYXJkIGVycm9yIHJlcG9ydGVyLiBXZSdsbCBzdG9yZSBhbGwgc2NoZW1hIGVycm9ycwotICAgICAqIGluIHRoaXMgd3JhcHBlciBvYmplY3QsIHNvIHRoYXQgd2UgY2FuIGdldCBhbGwgZXJyb3JzIChlcnJvciBjb2Rlcykgb2YKLSAgICAgKiBhIHNwZWNpZmljIGVsZW1lbnQuIFRoaXMgaXMgdXNlZnVsIGZvciBQU1ZJLgotICAgICAqLwotICAgIHByb3RlY3RlZCBmaW5hbCBjbGFzcyBYU0lFcnJvclJlcG9ydGVyIHsKLQotICAgICAgICAvLyB0aGUgZXJyb3IgcmVwb3J0ZXIgcHJvcGVydHkKLSAgICAgICAgWE1MRXJyb3JSZXBvcnRlciBmRXJyb3JSZXBvcnRlcjsKLQotICAgICAgICAvLyBzdG9yZSBlcnJvciBjb2Rlczsgc3RhcnRpbmcgcG9zaXRpb24gb2YgdGhlIGVycm9ycyBmb3IgZWFjaCBlbGVtZW50OwotICAgICAgICAvLyBudW1iZXIgb2YgZWxlbWVudCAoZGVwdGgpOyBhbmQgd2hldGhlciB0byByZWNvcmQgZXJyb3IKLSAgICAgICAgVmVjdG9yIGZFcnJvcnMgPSBuZXcgVmVjdG9yKCk7Ci0gICAgICAgIGludFtdIGZDb250ZXh0ID0gbmV3IGludFtJTklUSUFMX1NUQUNLX1NJWkVdOwotICAgICAgICBpbnQgZkNvbnRleHRDb3VudDsKLQotICAgICAgICAvLyBzZXQgdGhlIGV4dGVybmFsIGVycm9yIHJlcG9ydGVyLCBjbGVhciBlcnJvcnMKLSAgICAgICAgcHVibGljIHZvaWQgcmVzZXQoWE1MRXJyb3JSZXBvcnRlciBlcnJvclJlcG9ydGVyKSB7Ci0gICAgICAgICAgICBmRXJyb3JSZXBvcnRlciA9IGVycm9yUmVwb3J0ZXI7Ci0gICAgICAgICAgICBmRXJyb3JzLnJlbW92ZUFsbEVsZW1lbnRzKCk7Ci0gICAgICAgICAgICBmQ29udGV4dENvdW50ID0gMDsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIHNob3VsZCBiZSBjYWxsZWQgd2hlbiBzdGFydGluZyBwcm9jZXNzIGFuIGVsZW1lbnQgb3IgYW4gYXR0cmlidXRlLgotICAgICAgICAvLyBzdG9yZSB0aGUgc3RhcnRpbmcgcG9zaXRpb24gZm9yIHRoZSBjdXJyZW50IGNvbnRleHQKLSAgICAgICAgcHVibGljIHZvaWQgcHVzaENvbnRleHQoKSB7Ci0gICAgICAgICAgICBpZiAoIWZBdWdQU1ZJKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gcmVzaXplIGFycmF5IGlmIG5lY2Vzc2FyeQotICAgICAgICAgICAgaWYgKGZDb250ZXh0Q291bnQgPT0gZkNvbnRleHQubGVuZ3RoKSB7Ci0gICAgICAgICAgICAgICAgaW50IG5ld1NpemUgPSBmQ29udGV4dENvdW50ICsgSU5DX1NUQUNLX1NJWkU7Ci0gICAgICAgICAgICAgICAgaW50W10gbmV3QXJyYXkgPSBuZXcgaW50W25ld1NpemVdOwotICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZkNvbnRleHQsIDAsIG5ld0FycmF5LCAwLCBmQ29udGV4dENvdW50KTsKLSAgICAgICAgICAgICAgICBmQ29udGV4dCA9IG5ld0FycmF5OwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBmQ29udGV4dFtmQ29udGV4dENvdW50KytdID0gZkVycm9ycy5zaXplKCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBzaG91bGQgYmUgY2FsbGVkIG9uIGVuZEVsZW1lbnQ6IGdldCBhbGwgZXJyb3JzIG9mIHRoZSBjdXJyZW50IGVsZW1lbnQKLSAgICAgICAgcHVibGljIFN0cmluZ1tdIHBvcENvbnRleHQoKSB7Ci0gICAgICAgICAgICBpZiAoIWZBdWdQU1ZJKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyBnZXQgc3RhcnRpbmcgcG9zaXRpb24gb2YgdGhlIGN1cnJlbnQgZWxlbWVudAotICAgICAgICAgICAgaW50IGNvbnRleHRQb3MgPSBmQ29udGV4dFstLWZDb250ZXh0Q291bnRdOwotICAgICAgICAgICAgLy8gbnVtYmVyIG9mIGVycm9ycyBvZiB0aGUgY3VycmVudCBlbGVtZW50Ci0gICAgICAgICAgICBpbnQgc2l6ZSA9IGZFcnJvcnMuc2l6ZSgpIC0gY29udGV4dFBvczsKLSAgICAgICAgICAgIC8vIGlmIG5vIGVycm9ycywgcmV0dXJuIG51bGwKLSAgICAgICAgICAgIGlmIChzaXplID09IDApCi0gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgICAgICAvLyBjb3B5IGVycm9ycyBmcm9tIHRoZSBsaXN0IHRvIGFuIHN0cmluZyBhcnJheQotICAgICAgICAgICAgU3RyaW5nW10gZXJyb3JzID0gbmV3IFN0cmluZ1tzaXplXTsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgZXJyb3JzW2ldID0gKFN0cmluZykgZkVycm9ycy5lbGVtZW50QXQoY29udGV4dFBvcyArIGkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gcmVtb3ZlIGVycm9ycyBvZiB0aGUgY3VycmVudCBlbGVtZW50Ci0gICAgICAgICAgICBmRXJyb3JzLnNldFNpemUoY29udGV4dFBvcyk7Ci0gICAgICAgICAgICByZXR1cm4gZXJyb3JzOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gc2hvdWxkIGJlIGNhbGxlZCB3aGVuIGFuIGF0dHJpYnV0ZSBpcyBkb25lOiBnZXQgYWxsIGVycm9ycyBvZgotICAgICAgICAvLyB0aGlzIGF0dHJpYnV0ZSwgYnV0IGxlYXZlIHRoZSBlcnJvcnMgdG8gdGhlIGNvbnRhaW5pbmcgZWxlbWVudAotICAgICAgICAvLyBhbHNvIGNhbGxlZCBhZnRlciBhbiBlbGVtZW50IHdhcyBzdHJpY3RseSBhc3Nlc3NlZC4KLSAgICAgICAgcHVibGljIFN0cmluZ1tdIG1lcmdlQ29udGV4dCgpIHsKLSAgICAgICAgICAgIGlmICghZkF1Z1BTVkkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIGdldCBzdGFydGluZyBwb3NpdGlvbiBvZiB0aGUgY3VycmVudCBlbGVtZW50Ci0gICAgICAgICAgICBpbnQgY29udGV4dFBvcyA9IGZDb250ZXh0Wy0tZkNvbnRleHRDb3VudF07Ci0gICAgICAgICAgICAvLyBudW1iZXIgb2YgZXJyb3JzIG9mIHRoZSBjdXJyZW50IGVsZW1lbnQKLSAgICAgICAgICAgIGludCBzaXplID0gZkVycm9ycy5zaXplKCkgLSBjb250ZXh0UG9zOwotICAgICAgICAgICAgLy8gaWYgbm8gZXJyb3JzLCByZXR1cm4gbnVsbAotICAgICAgICAgICAgaWYgKHNpemUgPT0gMCkKLSAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgICAgIC8vIGNvcHkgZXJyb3JzIGZyb20gdGhlIGxpc3QgdG8gYW4gc3RyaW5nIGFycmF5Ci0gICAgICAgICAgICBTdHJpbmdbXSBlcnJvcnMgPSBuZXcgU3RyaW5nW3NpemVdOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKLSAgICAgICAgICAgICAgICBlcnJvcnNbaV0gPSAoU3RyaW5nKSBmRXJyb3JzLmVsZW1lbnRBdChjb250ZXh0UG9zICsgaSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyBkb24ndCByZXNpemUgdGhlIHZlY3RvcjogbGVhdmUgdGhlIGVycm9ycyBmb3IgdGhpcyBhdHRyaWJ1dGUKLSAgICAgICAgICAgIC8vIHRvIHRoZSBjb250YWluaW5nIGVsZW1lbnQKLSAgICAgICAgICAgIHJldHVybiBlcnJvcnM7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCByZXBvcnRFcnJvcihTdHJpbmcgZG9tYWluLCBTdHJpbmcga2V5LCBPYmplY3RbXSBhcmd1bWVudHMsIHNob3J0IHNldmVyaXR5KQotICAgICAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICBmRXJyb3JSZXBvcnRlci5yZXBvcnRFcnJvcihkb21haW4sIGtleSwgYXJndW1lbnRzLCBzZXZlcml0eSk7Ci0gICAgICAgICAgICBpZiAoZkF1Z1BTVkkpIHsKLSAgICAgICAgICAgICAgICBmRXJyb3JzLmFkZEVsZW1lbnQoa2V5KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSAvLyByZXBvcnRFcnJvcihTdHJpbmcsU3RyaW5nLE9iamVjdFtdLHNob3J0KQotCi0gICAgICAgIHB1YmxpYyB2b2lkIHJlcG9ydEVycm9yKAotICAgICAgICAgICAgWE1MTG9jYXRvciBsb2NhdGlvbiwKLSAgICAgICAgICAgIFN0cmluZyBkb21haW4sCi0gICAgICAgICAgICBTdHJpbmcga2V5LAotICAgICAgICAgICAgT2JqZWN0W10gYXJndW1lbnRzLAotICAgICAgICAgICAgc2hvcnQgc2V2ZXJpdHkpCi0gICAgICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKGxvY2F0aW9uLCBkb21haW4sIGtleSwgYXJndW1lbnRzLCBzZXZlcml0eSk7Ci0gICAgICAgICAgICBpZiAoZkF1Z1BTVkkpIHsKLSAgICAgICAgICAgICAgICBmRXJyb3JzLmFkZEVsZW1lbnQoa2V5KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSAvLyByZXBvcnRFcnJvcihYTUxMb2NhdG9yLFN0cmluZyxTdHJpbmcsT2JqZWN0W10sc2hvcnQpCi0gICAgfQotCi0gICAgLyoqIEVycm9yIHJlcG9ydGVyLiAqLwotICAgIHByb3RlY3RlZCBmaW5hbCBYU0lFcnJvclJlcG9ydGVyIGZYU0lFcnJvclJlcG9ydGVyID0gbmV3IFhTSUVycm9yUmVwb3J0ZXIoKTsKLQotICAgIC8qKiBFbnRpdHkgcmVzb2x2ZXIgKi8KLSAgICBwcm90ZWN0ZWQgWE1MRW50aXR5UmVzb2x2ZXIgZkVudGl0eVJlc29sdmVyOwotCi0gICAgLy8gdXBkYXRlZCBkdXJpbmcgcmVzZXQKLSAgICBwcm90ZWN0ZWQgVmFsaWRhdGlvbk1hbmFnZXIgZlZhbGlkYXRpb25NYW5hZ2VyID0gbnVsbDsKLSAgICBwcm90ZWN0ZWQgVmFsaWRhdGlvblN0YXRlIGZWYWxpZGF0aW9uU3RhdGUgPSBuZXcgVmFsaWRhdGlvblN0YXRlKCk7Ci0gICAgcHJvdGVjdGVkIFhNTEdyYW1tYXJQb29sIGZHcmFtbWFyUG9vbDsKLQotICAgIC8vIHNjaGVtYSBsb2NhdGlvbiBwcm9wZXJ0eSB2YWx1ZXMKLSAgICBwcm90ZWN0ZWQgU3RyaW5nIGZFeHRlcm5hbFNjaGVtYXMgPSBudWxsOwotICAgIHByb3RlY3RlZCBTdHJpbmcgZkV4dGVybmFsTm9OYW1lc3BhY2VTY2hlbWEgPSBudWxsOwotCi0gICAgLy9KQVhQIFNjaGVtYSBTb3VyY2UgcHJvcGVydHkKLSAgICBwcm90ZWN0ZWQgT2JqZWN0IGZKYXhwU2NoZW1hU291cmNlID0gbnVsbDsKLQotICAgIC8qKiBTY2hlbWEgR3JhbW1hciBEZXNjcmlwdGlvbiBwYXNzZWQsICB0byBnaXZlIGEgY2hhbmNlIHRvIGFwcGxpY2F0aW9uIHRvIHN1cHBseSB0aGUgR3JhbW1hciAqLwotICAgIHByb3RlY3RlZCBmaW5hbCBYU0REZXNjcmlwdGlvbiBmWFNERGVzY3JpcHRpb24gPSBuZXcgWFNERGVzY3JpcHRpb24oKTsKLSAgICBwcm90ZWN0ZWQgZmluYWwgTWFwPFN0cmluZywgWE1MU2NoZW1hTG9hZGVyLkxvY2F0aW9uQXJyYXk+IGZMb2NhdGlvblBhaXJzID0gbmV3IEhhc2hNYXA8PigpOwotCi0KLSAgICAvLyBoYW5kbGVycwotCi0gICAgLyoqIERvY3VtZW50IGhhbmRsZXIuICovCi0gICAgcHJvdGVjdGVkIFhNTERvY3VtZW50SGFuZGxlciBmRG9jdW1lbnRIYW5kbGVyOwotCi0gICAgcHJvdGVjdGVkIFhNTERvY3VtZW50U291cmNlIGZEb2N1bWVudFNvdXJjZTsKLQotICAgIGJvb2xlYW4gcmVwb3J0V2hpdGVzcGFjZSA9IGZhbHNlOwotCi0gICAgLy8KLSAgICAvLyBYTUxDb21wb25lbnQgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGEgbGlzdCBvZiBmZWF0dXJlIGlkZW50aWZpZXJzIHRoYXQgYXJlIHJlY29nbml6ZWQgYnkKLSAgICAgKiB0aGlzIGNvbXBvbmVudC4gVGhpcyBtZXRob2QgbWF5IHJldHVybiBudWxsIGlmIG5vIGZlYXR1cmVzCi0gICAgICogYXJlIHJlY29nbml6ZWQgYnkgdGhpcyBjb21wb25lbnQuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZ1tdIGdldFJlY29nbml6ZWRGZWF0dXJlcygpIHsKLSAgICAgICAgcmV0dXJuIChTdHJpbmdbXSkgKFJFQ09HTklaRURfRkVBVFVSRVMuY2xvbmUoKSk7Ci0gICAgfSAvLyBnZXRSZWNvZ25pemVkRmVhdHVyZXMoKTpTdHJpbmdbXQotCi0gICAgLyoqCi0gICAgICogU2V0cyB0aGUgc3RhdGUgb2YgYSBmZWF0dXJlLiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgdGhlIGNvbXBvbmVudAotICAgICAqIG1hbmFnZXIgYW55IHRpbWUgYWZ0ZXIgcmVzZXQgd2hlbiBhIGZlYXR1cmUgY2hhbmdlcyBzdGF0ZS4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IENvbXBvbmVudHMgc2hvdWxkIHNpbGVudGx5IGlnbm9yZSBmZWF0dXJlcwotICAgICAqIHRoYXQgZG8gbm90IGFmZmVjdCB0aGUgb3BlcmF0aW9uIG9mIHRoZSBjb21wb25lbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZmVhdHVyZUlkIFRoZSBmZWF0dXJlIGlkZW50aWZpZXIuCi0gICAgICogQHBhcmFtIHN0YXRlICAgICBUaGUgc3RhdGUgb2YgdGhlIGZlYXR1cmUuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24gVGhlIGNvbXBvbmVudCBzaG91bGQgbm90IHRocm93Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMgZXhjZXB0aW9uLgotICAgICAqIEB0aHJvd3MgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIFRoZSBjb21wb25lbnQgc2hvdWxkIG5vdCB0aHJvdwotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMgZXhjZXB0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEZlYXR1cmUoU3RyaW5nIGZlYXR1cmVJZCwgYm9vbGVhbiBzdGF0ZSkgdGhyb3dzIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gewotICAgIH0gLy8gc2V0RmVhdHVyZShTdHJpbmcsYm9vbGVhbikKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYSBsaXN0IG9mIHByb3BlcnR5IGlkZW50aWZpZXJzIHRoYXQgYXJlIHJlY29nbml6ZWQgYnkKLSAgICAgKiB0aGlzIGNvbXBvbmVudC4gVGhpcyBtZXRob2QgbWF5IHJldHVybiBudWxsIGlmIG5vIHByb3BlcnRpZXMKLSAgICAgKiBhcmUgcmVjb2duaXplZCBieSB0aGlzIGNvbXBvbmVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nW10gZ2V0UmVjb2duaXplZFByb3BlcnRpZXMoKSB7Ci0gICAgICAgIHJldHVybiAoU3RyaW5nW10pIChSRUNPR05JWkVEX1BST1BFUlRJRVMuY2xvbmUoKSk7Ci0gICAgfSAvLyBnZXRSZWNvZ25pemVkUHJvcGVydGllcygpOlN0cmluZ1tdCi0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiBhIHByb3BlcnR5LiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgdGhlIGNvbXBvbmVudAotICAgICAqIG1hbmFnZXIgYW55IHRpbWUgYWZ0ZXIgcmVzZXQgd2hlbiBhIHByb3BlcnR5IGNoYW5nZXMgdmFsdWUuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBDb21wb25lbnRzIHNob3VsZCBzaWxlbnRseSBpZ25vcmUgcHJvcGVydGllcwotICAgICAqIHRoYXQgZG8gbm90IGFmZmVjdCB0aGUgb3BlcmF0aW9uIG9mIHRoZSBjb21wb25lbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcHJvcGVydHlJZCBUaGUgcHJvcGVydHkgaWRlbnRpZmllci4KLSAgICAgKiBAcGFyYW0gdmFsdWUgICAgICBUaGUgdmFsdWUgb2YgdGhlIHByb3BlcnR5LgotICAgICAqCi0gICAgICogQHRocm93cyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIFRoZSBjb21wb25lbnQgc2hvdWxkIG5vdCB0aHJvdwotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzIGV4Y2VwdGlvbi4KLSAgICAgKiBAdGhyb3dzIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBUaGUgY29tcG9uZW50IHNob3VsZCBub3QgdGhyb3cKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzIGV4Y2VwdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRQcm9wZXJ0eShTdHJpbmcgcHJvcGVydHlJZCwgT2JqZWN0IHZhbHVlKSB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiB7Ci0gICAgfSAvLyBzZXRQcm9wZXJ0eShTdHJpbmcsT2JqZWN0KQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgZGVmYXVsdCBzdGF0ZSBmb3IgYSBmZWF0dXJlLCBvciBudWxsIGlmIHRoaXMKLSAgICAgKiBjb21wb25lbnQgZG9lcyBub3Qgd2FudCB0byByZXBvcnQgYSBkZWZhdWx0IHZhbHVlIGZvciB0aGlzCi0gICAgICogZmVhdHVyZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBmZWF0dXJlSWQgVGhlIGZlYXR1cmUgaWRlbnRpZmllci4KLSAgICAgKgotICAgICAqIEBzaW5jZSBYZXJjZXMgMi4yLjAKLSAgICAgKi8KLSAgICBwdWJsaWMgQm9vbGVhbiBnZXRGZWF0dXJlRGVmYXVsdChTdHJpbmcgZmVhdHVyZUlkKSB7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgUkVDT0dOSVpFRF9GRUFUVVJFUy5sZW5ndGg7IGkrKykgewotICAgICAgICAgICAgaWYgKFJFQ09HTklaRURfRkVBVFVSRVNbaV0uZXF1YWxzKGZlYXR1cmVJZCkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gRkVBVFVSRV9ERUZBVUxUU1tpXTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9IC8vIGdldEZlYXR1cmVEZWZhdWx0KFN0cmluZyk6Qm9vbGVhbgotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgZGVmYXVsdCBzdGF0ZSBmb3IgYSBwcm9wZXJ0eSwgb3IgbnVsbCBpZiB0aGlzCi0gICAgICogY29tcG9uZW50IGRvZXMgbm90IHdhbnQgdG8gcmVwb3J0IGEgZGVmYXVsdCB2YWx1ZSBmb3IgdGhpcwotICAgICAqIHByb3BlcnR5LgotICAgICAqCi0gICAgICogQHBhcmFtIHByb3BlcnR5SWQgVGhlIHByb3BlcnR5IGlkZW50aWZpZXIuCi0gICAgICoKLSAgICAgKiBAc2luY2UgWGVyY2VzIDIuMi4wCi0gICAgICovCi0gICAgcHVibGljIE9iamVjdCBnZXRQcm9wZXJ0eURlZmF1bHQoU3RyaW5nIHByb3BlcnR5SWQpIHsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBSRUNPR05JWkVEX1BST1BFUlRJRVMubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgIGlmIChSRUNPR05JWkVEX1BST1BFUlRJRVNbaV0uZXF1YWxzKHByb3BlcnR5SWQpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIFBST1BFUlRZX0RFRkFVTFRTW2ldOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0gLy8gZ2V0UHJvcGVydHlEZWZhdWx0KFN0cmluZyk6T2JqZWN0Ci0KLSAgICAvLwotICAgIC8vIFhNTERvY3VtZW50U291cmNlIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqIFNldHMgdGhlIGRvY3VtZW50IGhhbmRsZXIgdG8gcmVjZWl2ZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgZG9jdW1lbnQuICovCi0gICAgcHVibGljIHZvaWQgc2V0RG9jdW1lbnRIYW5kbGVyKFhNTERvY3VtZW50SGFuZGxlciBkb2N1bWVudEhhbmRsZXIpIHsKLSAgICAgICAgZkRvY3VtZW50SGFuZGxlciA9IGRvY3VtZW50SGFuZGxlcjsKLQotICAgICAgICAvLyBJbml0IHJlcG9ydFdoaXRlc3BhY2UgZm9yIHRoaXMgaGFuZGxlcgotICAgICAgICBpZiAoZG9jdW1lbnRIYW5kbGVyIGluc3RhbmNlb2YgWE1MUGFyc2VyKSB7Ci0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIHJlcG9ydFdoaXRlc3BhY2UgPQotICAgICAgICAgICAgICAgICAgICAoKFhNTFBhcnNlcikgZG9jdW1lbnRIYW5kbGVyKS5nZXRGZWF0dXJlKFJFUE9SVF9XSElURVNQQUNFKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgIHJlcG9ydFdoaXRlc3BhY2UgPSBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0gLy8gc2V0RG9jdW1lbnRIYW5kbGVyKFhNTERvY3VtZW50SGFuZGxlcikKLQotICAgIC8qKiBSZXR1cm5zIHRoZSBkb2N1bWVudCBoYW5kbGVyICovCi0gICAgcHVibGljIFhNTERvY3VtZW50SGFuZGxlciBnZXREb2N1bWVudEhhbmRsZXIoKSB7Ci0gICAgICAgIHJldHVybiBmRG9jdW1lbnRIYW5kbGVyOwotICAgIH0gLy8gc2V0RG9jdW1lbnRIYW5kbGVyKFhNTERvY3VtZW50SGFuZGxlcikKLQotICAgIC8vCi0gICAgLy8gWE1MRG9jdW1lbnRIYW5kbGVyIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqIFNldHMgdGhlIGRvY3VtZW50IHNvdXJjZSAqLwotICAgIHB1YmxpYyB2b2lkIHNldERvY3VtZW50U291cmNlKFhNTERvY3VtZW50U291cmNlIHNvdXJjZSkgewotICAgICAgICBmRG9jdW1lbnRTb3VyY2UgPSBzb3VyY2U7Ci0gICAgfSAvLyBzZXREb2N1bWVudFNvdXJjZQotCi0gICAgLyoqIFJldHVybnMgdGhlIGRvY3VtZW50IHNvdXJjZSAqLwotICAgIHB1YmxpYyBYTUxEb2N1bWVudFNvdXJjZSBnZXREb2N1bWVudFNvdXJjZSgpIHsKLSAgICAgICAgcmV0dXJuIGZEb2N1bWVudFNvdXJjZTsKLSAgICB9IC8vIGdldERvY3VtZW50U291cmNlCi0KLSAgICAvKioKLSAgICAgKiBUaGUgc3RhcnQgb2YgdGhlIGRvY3VtZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIGxvY2F0b3IgVGhlIHN5c3RlbSBpZGVudGlmaWVyIG9mIHRoZSBlbnRpdHkgaWYgdGhlIGVudGl0eQotICAgICAqICAgICAgICAgICAgICAgICBpcyBleHRlcm5hbCwgbnVsbCBvdGhlcndpc2UuCi0gICAgICogQHBhcmFtIGVuY29kaW5nIFRoZSBhdXRvLWRldGVjdGVkIElBTkEgZW5jb2RpbmcgbmFtZSBvZiB0aGUgZW50aXR5Ci0gICAgICogICAgICAgICAgICAgICAgIHN0cmVhbS4gVGhpcyB2YWx1ZSB3aWxsIGJlIG51bGwgaW4gdGhvc2Ugc2l0dWF0aW9ucwotICAgICAqICAgICAgICAgICAgICAgICB3aGVyZSB0aGUgZW50aXR5IGVuY29kaW5nIGlzIG5vdCBhdXRvLWRldGVjdGVkIChlLmcuCi0gICAgICogICAgICAgICAgICAgICAgIGludGVybmFsIGVudGl0aWVzIG9yIGEgZG9jdW1lbnQgZW50aXR5IHRoYXQgaXMKLSAgICAgKiAgICAgICAgICAgICAgICAgcGFyc2VkIGZyb20gYSBqYXZhLmlvLlJlYWRlcikuCi0gICAgICogQHBhcmFtIG5hbWVzcGFjZUNvbnRleHQKLSAgICAgKiAgICAgICAgICAgICAgICAgVGhlIG5hbWVzcGFjZSBjb250ZXh0IGluIGVmZmVjdCBhdCB0aGUKLSAgICAgKiAgICAgICAgICAgICAgICAgc3RhcnQgb2YgdGhpcyBkb2N1bWVudC4KLSAgICAgKiAgICAgICAgICAgICAgICAgVGhpcyBvYmplY3QgcmVwcmVzZW50cyB0aGUgY3VycmVudCBjb250ZXh0LgotICAgICAqICAgICAgICAgICAgICAgICBJbXBsZW1lbnRvcnMgb2YgdGhpcyBjbGFzcyBhcmUgcmVzcG9uc2libGUKLSAgICAgKiAgICAgICAgICAgICAgICAgZm9yIGNvcHlpbmcgdGhlIG5hbWVzcGFjZSBiaW5kaW5ncyBmcm9tIHRoZQotICAgICAqICAgICAgICAgICAgICAgICB0aGUgY3VycmVudCBjb250ZXh0IChhbmQgaXRzIHBhcmVudCBjb250ZXh0cykKLSAgICAgKiAgICAgICAgICAgICAgICAgaWYgdGhhdCBpbmZvcm1hdGlvbiBpcyBpbXBvcnRhbnQuCi0gICAgICogQHBhcmFtIGF1Z3MgICAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydERvY3VtZW50KAotICAgICAgICBYTUxMb2NhdG9yIGxvY2F0b3IsCi0gICAgICAgIFN0cmluZyBlbmNvZGluZywKLSAgICAgICAgTmFtZXNwYWNlQ29udGV4dCBuYW1lc3BhY2VDb250ZXh0LAotICAgICAgICBBdWdtZW50YXRpb25zIGF1Z3MpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotCi0gICAgICAgIGZWYWxpZGF0aW9uU3RhdGUuc2V0TmFtZXNwYWNlU3VwcG9ydChuYW1lc3BhY2VDb250ZXh0KTsKLSAgICAgICAgZlN0YXRlNFhzaVR5cGUuc2V0TmFtZXNwYWNlU3VwcG9ydChuYW1lc3BhY2VDb250ZXh0KTsKLSAgICAgICAgZlN0YXRlNEFwcGx5RGVmYXVsdC5zZXROYW1lc3BhY2VTdXBwb3J0KG5hbWVzcGFjZUNvbnRleHQpOwotICAgICAgICBmTG9jYXRvciA9IGxvY2F0b3I7Ci0KLSAgICAgICAgaGFuZGxlU3RhcnREb2N1bWVudChsb2NhdG9yLCBlbmNvZGluZyk7Ci0gICAgICAgIC8vIGNhbGwgaGFuZGxlcnMKLSAgICAgICAgaWYgKGZEb2N1bWVudEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci5zdGFydERvY3VtZW50KGxvY2F0b3IsIGVuY29kaW5nLCBuYW1lc3BhY2VDb250ZXh0LCBhdWdzKTsKLSAgICAgICAgfQotCi0gICAgfSAvLyBzdGFydERvY3VtZW50KFhNTExvY2F0b3IsU3RyaW5nKQotCi0gICAgLyoqCi0gICAgICogTm90aWZpZXMgb2YgdGhlIHByZXNlbmNlIG9mIGFuIFhNTERlY2wgbGluZSBpbiB0aGUgZG9jdW1lbnQuIElmCi0gICAgICogcHJlc2VudCwgdGhpcyBtZXRob2Qgd2lsbCBiZSBjYWxsZWQgaW1tZWRpYXRlbHkgZm9sbG93aW5nIHRoZQotICAgICAqIHN0YXJ0RG9jdW1lbnQgY2FsbC4KLSAgICAgKgotICAgICAqIEBwYXJhbSB2ZXJzaW9uICAgIFRoZSBYTUwgdmVyc2lvbi4KLSAgICAgKiBAcGFyYW0gZW5jb2RpbmcgICBUaGUgSUFOQSBlbmNvZGluZyBuYW1lIG9mIHRoZSBkb2N1bWVudCwgb3IgbnVsbCBpZgotICAgICAqICAgICAgICAgICAgICAgICAgIG5vdCBzcGVjaWZpZWQuCi0gICAgICogQHBhcmFtIHN0YW5kYWxvbmUgVGhlIHN0YW5kYWxvbmUgdmFsdWUsIG9yIG51bGwgaWYgbm90IHNwZWNpZmllZC4KLSAgICAgKiBAcGFyYW0gYXVncyAgICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHhtbERlY2woU3RyaW5nIHZlcnNpb24sIFN0cmluZyBlbmNvZGluZywgU3RyaW5nIHN0YW5kYWxvbmUsIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy8gY2FsbCBoYW5kbGVycwotICAgICAgICBpZiAoZkRvY3VtZW50SGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLnhtbERlY2wodmVyc2lvbiwgZW5jb2RpbmcsIHN0YW5kYWxvbmUsIGF1Z3MpOwotICAgICAgICB9Ci0KLSAgICB9IC8vIHhtbERlY2woU3RyaW5nLFN0cmluZyxTdHJpbmcpCi0KLSAgICAvKioKLSAgICAgKiBOb3RpZmllcyBvZiB0aGUgcHJlc2VuY2Ugb2YgdGhlIERPQ1RZUEUgbGluZSBpbiB0aGUgZG9jdW1lbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcm9vdEVsZW1lbnQgVGhlIG5hbWUgb2YgdGhlIHJvb3QgZWxlbWVudC4KLSAgICAgKiBAcGFyYW0gcHVibGljSWQgICAgVGhlIHB1YmxpYyBpZGVudGlmaWVyIGlmIGFuIGV4dGVybmFsIERURCBvciBudWxsCi0gICAgICogICAgICAgICAgICAgICAgICAgIGlmIHRoZSBleHRlcm5hbCBEVEQgaXMgc3BlY2lmaWVkIHVzaW5nIFNZU1RFTS4KLSAgICAgKiBAcGFyYW0gc3lzdGVtSWQgICAgVGhlIHN5c3RlbSBpZGVudGlmaWVyIGlmIGFuIGV4dGVybmFsIERURCwgbnVsbAotICAgICAqICAgICAgICAgICAgICAgICAgICBvdGhlcndpc2UuCi0gICAgICogQHBhcmFtIGF1Z3MgICAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBkb2N0eXBlRGVjbCgKLSAgICAgICAgU3RyaW5nIHJvb3RFbGVtZW50LAotICAgICAgICBTdHJpbmcgcHVibGljSWQsCi0gICAgICAgIFN0cmluZyBzeXN0ZW1JZCwKLSAgICAgICAgQXVnbWVudGF0aW9ucyBhdWdzKQotICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLQotICAgICAgICAvLyBjYWxsIGhhbmRsZXJzCi0gICAgICAgIGlmIChmRG9jdW1lbnRIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZEb2N1bWVudEhhbmRsZXIuZG9jdHlwZURlY2wocm9vdEVsZW1lbnQsIHB1YmxpY0lkLCBzeXN0ZW1JZCwgYXVncyk7Ci0gICAgICAgIH0KLQotICAgIH0gLy8gZG9jdHlwZURlY2woU3RyaW5nLFN0cmluZyxTdHJpbmcpCi0KLSAgICAvKioKLSAgICAgKiBUaGUgc3RhcnQgb2YgYW4gZWxlbWVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlbGVtZW50ICAgIFRoZSBuYW1lIG9mIHRoZSBlbGVtZW50LgotICAgICAqIEBwYXJhbSBhdHRyaWJ1dGVzIFRoZSBlbGVtZW50IGF0dHJpYnV0ZXMuCi0gICAgICogQHBhcmFtIGF1Z3MgICAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQoUU5hbWUgZWxlbWVudCwgWE1MQXR0cmlidXRlcyBhdHRyaWJ1dGVzLCBBdWdtZW50YXRpb25zIGF1Z3MpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotCi0gICAgICAgIEF1Z21lbnRhdGlvbnMgbW9kaWZpZWRBdWdzID0gaGFuZGxlU3RhcnRFbGVtZW50KGVsZW1lbnQsIGF0dHJpYnV0ZXMsIGF1Z3MpOwotICAgICAgICAvLyBjYWxsIGhhbmRsZXJzCi0gICAgICAgIGlmIChmRG9jdW1lbnRIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZEb2N1bWVudEhhbmRsZXIuc3RhcnRFbGVtZW50KGVsZW1lbnQsIGF0dHJpYnV0ZXMsIG1vZGlmaWVkQXVncyk7Ci0gICAgICAgIH0KLQotICAgIH0gLy8gc3RhcnRFbGVtZW50KFFOYW1lLFhNTEF0dHJpYnV0ZXMsIEF1Z21lbnRhdGlvbnMpCi0KLSAgICAvKioKLSAgICAgKiBBbiBlbXB0eSBlbGVtZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIGVsZW1lbnQgICAgVGhlIG5hbWUgb2YgdGhlIGVsZW1lbnQuCi0gICAgICogQHBhcmFtIGF0dHJpYnV0ZXMgVGhlIGVsZW1lbnQgYXR0cmlidXRlcy4KLSAgICAgKiBAcGFyYW0gYXVncyAgICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVtcHR5RWxlbWVudChRTmFtZSBlbGVtZW50LCBYTUxBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMsIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgQXVnbWVudGF0aW9ucyBtb2RpZmllZEF1Z3MgPSBoYW5kbGVTdGFydEVsZW1lbnQoZWxlbWVudCwgYXR0cmlidXRlcywgYXVncyk7Ci0KLSAgICAgICAgLy8gaW4gdGhlIGNhc2Ugd2hlcmUgdGhlcmUgaXMgYSB7dmFsdWUgY29uc3RyYWludH0sIGFuZCB0aGUgZWxlbWVudAotICAgICAgICAvLyBkb2Vzbid0IGhhdmUgYW55IHRleHQgY29udGVudCwgY2hhbmdlIGVtcHR5RWxlbWVudCBjYWxsIHRvCi0gICAgICAgIC8vIHN0YXJ0ICsgY2hhcmFjdGVycyArIGVuZAotICAgICAgICBmRGVmYXVsdFZhbHVlID0gbnVsbDsKLSAgICAgICAgLy8gZkVsZW1lbnREZXB0aCA9PSAtMiBpbmRpY2F0ZXMgdGhhdCB0aGUgc2NoZW1hIHZhbGlkYXRvciB3YXMgcmVtb3ZlZAotICAgICAgICAvLyBmcm9tIHRoZSBwaXBlbGluZS4gdGhlbiB3ZSBkb24ndCBuZWVkIHRvIGNhbGwgaGFuZGxlRW5kRWxlbWVudC4KLSAgICAgICAgaWYgKGZFbGVtZW50RGVwdGggIT0gLTIpCi0gICAgICAgICAgICBtb2RpZmllZEF1Z3MgPSBoYW5kbGVFbmRFbGVtZW50KGVsZW1lbnQsIG1vZGlmaWVkQXVncyk7Ci0KLSAgICAgICAgLy8gY2FsbCBoYW5kbGVycwotICAgICAgICBpZiAoZkRvY3VtZW50SGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAoIWZTY2hlbWFFbGVtZW50RGVmYXVsdCB8fCBmRGVmYXVsdFZhbHVlID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLmVtcHR5RWxlbWVudChlbGVtZW50LCBhdHRyaWJ1dGVzLCBtb2RpZmllZEF1Z3MpOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLnN0YXJ0RWxlbWVudChlbGVtZW50LCBhdHRyaWJ1dGVzLCBtb2RpZmllZEF1Z3MpOwotICAgICAgICAgICAgICAgIGZEb2N1bWVudEhhbmRsZXIuY2hhcmFjdGVycyhmRGVmYXVsdFZhbHVlLCBudWxsKTsKLSAgICAgICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLmVuZEVsZW1lbnQoZWxlbWVudCwgbW9kaWZpZWRBdWdzKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0gLy8gZW1wdHlFbGVtZW50KFFOYW1lLFhNTEF0dHJpYnV0ZXMsIEF1Z21lbnRhdGlvbnMpCi0KLSAgICAvKioKLSAgICAgKiBDaGFyYWN0ZXIgY29udGVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSB0ZXh0IFRoZSBjb250ZW50LgotICAgICAqIEBwYXJhbSBhdWdzICAgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY2hhcmFjdGVycyhYTUxTdHJpbmcgdGV4dCwgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgdGV4dCA9IGhhbmRsZUNoYXJhY3RlcnModGV4dCk7Ci0KLSAgICAgICAgaWYgKGZTYXdPbmx5V2hpdGVzcGFjZUluRWxlbWVudENvbnRlbnQpIHsKLSAgICAgICAgICAgIGZTYXdPbmx5V2hpdGVzcGFjZUluRWxlbWVudENvbnRlbnQgPSBmYWxzZTsKLSAgICAgICAgICAgIGlmICghcmVwb3J0V2hpdGVzcGFjZSkgewotICAgICAgICAgICAgICAgIGlnbm9yYWJsZVdoaXRlc3BhY2UodGV4dCwgYXVncyk7Ci0gICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gY2FsbCBoYW5kbGVycwotICAgICAgICBpZiAoZkRvY3VtZW50SGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAoZk5vcm1hbGl6ZURhdGEgJiYgZlVuaW9uVHlwZSkgewotICAgICAgICAgICAgICAgIC8vIGZvciB1bmlvbiB0eXBlcyB3ZSBjYW4ndCBub3JtYWxpemUgZGF0YQotICAgICAgICAgICAgICAgIC8vIHRodXMgd2Ugb25seSBuZWVkIHRvIHNlbmQgYXVncyBpbmZvcm1hdGlvbiBpZiBhbnk7Ci0gICAgICAgICAgICAgICAgLy8gdGhlIG5vcm1hbGl6ZWQgZGF0YSBmb3IgdW5pb24gd2lsbCBiZSBzZW5kCi0gICAgICAgICAgICAgICAgLy8gYWZ0ZXIgbm9ybWFsaXphdGlvbiBpcyBwZXJmb3JtZWQgKGF0IHRoZSBlbmRFbGVtZW50KCkpCi0gICAgICAgICAgICAgICAgaWYgKGF1Z3MgIT0gbnVsbCkKLSAgICAgICAgICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci5jaGFyYWN0ZXJzKGZFbXB0eVhNTFN0ciwgYXVncyk7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIGZEb2N1bWVudEhhbmRsZXIuY2hhcmFjdGVycyh0ZXh0LCBhdWdzKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgfSAvLyBjaGFyYWN0ZXJzKFhNTFN0cmluZykKLQotICAgIC8qKgotICAgICAqIElnbm9yYWJsZSB3aGl0ZXNwYWNlLiBGb3IgdGhpcyBtZXRob2QgdG8gYmUgY2FsbGVkLCB0aGUgZG9jdW1lbnQKLSAgICAgKiBzb3VyY2UgbXVzdCBoYXZlIHNvbWUgd2F5IG9mIGRldGVybWluaW5nIHRoYXQgdGhlIHRleHQgY29udGFpbmluZwotICAgICAqIG9ubHkgd2hpdGVzcGFjZSBjaGFyYWN0ZXJzIHNob3VsZCBiZSBjb25zaWRlcmVkIGlnbm9yYWJsZS4gRm9yCi0gICAgICogZXhhbXBsZSwgdGhlIHZhbGlkYXRvciBjYW4gZGV0ZXJtaW5lIGlmIGEgbGVuZ3RoIG9mIHdoaXRlc3BhY2UKLSAgICAgKiBjaGFyYWN0ZXJzIGluIHRoZSBkb2N1bWVudCBhcmUgaWdub3JhYmxlIGJhc2VkIG9uIHRoZSBlbGVtZW50Ci0gICAgICogY29udGVudCBtb2RlbC4KLSAgICAgKgotICAgICAqIEBwYXJhbSB0ZXh0IFRoZSBpZ25vcmFibGUgd2hpdGVzcGFjZS4KLSAgICAgKiBAcGFyYW0gYXVncyAgICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGlnbm9yYWJsZVdoaXRlc3BhY2UoWE1MU3RyaW5nIHRleHQsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIGhhbmRsZUlnbm9yYWJsZVdoaXRlc3BhY2UodGV4dCk7Ci0gICAgICAgIC8vIGNhbGwgaGFuZGxlcnMKLSAgICAgICAgaWYgKGZEb2N1bWVudEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci5pZ25vcmFibGVXaGl0ZXNwYWNlKHRleHQsIGF1Z3MpOwotICAgICAgICB9Ci0KLSAgICB9IC8vIGlnbm9yYWJsZVdoaXRlc3BhY2UoWE1MU3RyaW5nKQotCi0gICAgLyoqCi0gICAgICogVGhlIGVuZCBvZiBhbiBlbGVtZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIGVsZW1lbnQgVGhlIG5hbWUgb2YgdGhlIGVsZW1lbnQuCi0gICAgICogQHBhcmFtIGF1Z3MgICAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbmRFbGVtZW50KFFOYW1lIGVsZW1lbnQsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy8gaW4gdGhlIGNhc2Ugd2hlcmUgdGhlcmUgaXMgYSB7dmFsdWUgY29uc3RyYWludH0sIGFuZCB0aGUgZWxlbWVudAotICAgICAgICAvLyBkb2Vzbid0IGhhdmUgYW55IHRleHQgY29udGVudCwgYWRkIGEgY2hhcmFjdGVycyBjYWxsLgotICAgICAgICBmRGVmYXVsdFZhbHVlID0gbnVsbDsKLSAgICAgICAgQXVnbWVudGF0aW9ucyBtb2RpZmllZEF1Z3MgPSBoYW5kbGVFbmRFbGVtZW50KGVsZW1lbnQsIGF1Z3MpOwotICAgICAgICAvLyBjYWxsIGhhbmRsZXJzCi0gICAgICAgIGlmIChmRG9jdW1lbnRIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGlmICghZlNjaGVtYUVsZW1lbnREZWZhdWx0IHx8IGZEZWZhdWx0VmFsdWUgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZEb2N1bWVudEhhbmRsZXIuZW5kRWxlbWVudChlbGVtZW50LCBtb2RpZmllZEF1Z3MpOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLmNoYXJhY3RlcnMoZkRlZmF1bHRWYWx1ZSwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci5lbmRFbGVtZW50KGVsZW1lbnQsIG1vZGlmaWVkQXVncyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9IC8vIGVuZEVsZW1lbnQoUU5hbWUsIEF1Z21lbnRhdGlvbnMpCi0KLSAgICAvKioKLSAgICAqIFRoZSBzdGFydCBvZiBhIENEQVRBIHNlY3Rpb24uCi0gICAgKgotICAgICogQHBhcmFtIGF1Z3MgICAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAqCi0gICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydENEQVRBKEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy8gUkVWSVNJVDogd2hhdCBzaG91bGQgd2UgZG8gaGVyZSBpZiBzY2hlbWEgbm9ybWFsaXphdGlvbiBpcyBvbj8/Ci0gICAgICAgIGZJbkNEQVRBID0gdHJ1ZTsKLSAgICAgICAgLy8gY2FsbCBoYW5kbGVycwotICAgICAgICBpZiAoZkRvY3VtZW50SGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLnN0YXJ0Q0RBVEEoYXVncyk7Ci0gICAgICAgIH0KLQotICAgIH0gLy8gc3RhcnRDREFUQSgpCi0KLSAgICAvKioKLSAgICAgKiBUaGUgZW5kIG9mIGEgQ0RBVEEgc2VjdGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBhdWdzICAgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kQ0RBVEEoQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLQotICAgICAgICAvLyBjYWxsIGhhbmRsZXJzCi0gICAgICAgIGZJbkNEQVRBID0gZmFsc2U7Ci0gICAgICAgIGlmIChmRG9jdW1lbnRIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZEb2N1bWVudEhhbmRsZXIuZW5kQ0RBVEEoYXVncyk7Ci0gICAgICAgIH0KLQotICAgIH0gLy8gZW5kQ0RBVEEoKQotCi0gICAgLyoqCi0gICAgICogVGhlIGVuZCBvZiB0aGUgZG9jdW1lbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYXVncyAgICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZERvY3VtZW50KEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgaGFuZGxlRW5kRG9jdW1lbnQoKTsKLQotICAgICAgICAvLyBjYWxsIGhhbmRsZXJzCi0gICAgICAgIGlmIChmRG9jdW1lbnRIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZEb2N1bWVudEhhbmRsZXIuZW5kRG9jdW1lbnQoYXVncyk7Ci0gICAgICAgIH0KLSAgICAgICAgZkxvY2F0b3IgPSBudWxsOwotCi0gICAgfSAvLyBlbmREb2N1bWVudChBdWdtZW50YXRpb25zKQotCi0gICAgLy8KLSAgICAvLyBET01SZXZhbGlkYXRpb25IYW5kbGVyIG1ldGhvZHMKLSAgICAvLwotCi0KLQotCi0KLSAgICBwdWJsaWMgYm9vbGVhbiBjaGFyYWN0ZXJEYXRhKFN0cmluZyBkYXRhLCBBdWdtZW50YXRpb25zIGF1Z3MpIHsKLQotICAgICAgICBmU2F3VGV4dCA9IGZTYXdUZXh0IHx8IGRhdGEubGVuZ3RoKCkgPiAwOwotCi0gICAgICAgIC8vIFJFVklTSVQ6IHRoaXMgbWV0aG9kcyBiYXNpY2FsbHkgZHVwbGljYXRlcyBpbXBsZW1lbnRhdGlvbiBvZgotICAgICAgICAvLyAgICAgICAgICBoYW5kbGVDaGFyYWN0ZXJzKCkuIFdlIHNob3VsZCBiZSBhYmxlIHRvIHJldXNlIHNvbWUgY29kZQotCi0gICAgICAgIC8vIGlmIHdoaXRlc3BhY2UgPT0gLTEgc2tpcCBub3JtYWxpemF0aW9uLCBiZWNhdXNlIGl0IGlzIGEgY29tcGxleFR5cGUKLSAgICAgICAgLy8gb3IgYSB1bmlvbiB0eXBlLgotICAgICAgICBpZiAoZk5vcm1hbGl6ZURhdGEgJiYgZldoaXRlU3BhY2UgIT0gLTEgJiYgZldoaXRlU3BhY2UgIT0gWFNTaW1wbGVUeXBlLldTX1BSRVNFUlZFKSB7Ci0gICAgICAgICAgICAvLyBub3JtYWxpemUgZGF0YQotICAgICAgICAgICAgbm9ybWFsaXplV2hpdGVzcGFjZShkYXRhLCBmV2hpdGVTcGFjZSA9PSBYU1NpbXBsZVR5cGUuV1NfQ09MTEFQU0UpOwotICAgICAgICAgICAgZkJ1ZmZlci5hcHBlbmQoZk5vcm1hbGl6ZWRTdHIuY2gsIGZOb3JtYWxpemVkU3RyLm9mZnNldCwgZk5vcm1hbGl6ZWRTdHIubGVuZ3RoKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIGlmIChmQXBwZW5kQnVmZmVyKQotICAgICAgICAgICAgICAgIGZCdWZmZXIuYXBwZW5kKGRhdGEpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gV2hlbiBpdCdzIGEgY29tcGxleCB0eXBlIHdpdGggZWxlbWVudC1vbmx5IGNvbnRlbnQsIHdlIG5lZWQgdG8KLSAgICAgICAgLy8gZmluZCBvdXQgd2hldGhlciB0aGUgY29udGVudCBjb250YWlucyBhbnkgbm9uLXdoaXRlc3BhY2UgY2hhcmFjdGVyLgotICAgICAgICBib29sZWFuIGFsbFdoaXRlU3BhY2UgPSB0cnVlOwotICAgICAgICBpZiAoZkN1cnJlbnRUeXBlICE9IG51bGwKLSAgICAgICAgICAgICYmIGZDdXJyZW50VHlwZS5nZXRUeXBlQ2F0ZWdvcnkoKSA9PSBYU1R5cGVEZWZpbml0aW9uLkNPTVBMRVhfVFlQRSkgewotICAgICAgICAgICAgWFNDb21wbGV4VHlwZURlY2wgY3R5cGUgPSAoWFNDb21wbGV4VHlwZURlY2wpIGZDdXJyZW50VHlwZTsKLSAgICAgICAgICAgIGlmIChjdHlwZS5mQ29udGVudFR5cGUgPT0gWFNDb21wbGV4VHlwZURlY2wuQ09OVEVOVFRZUEVfRUxFTUVOVCkgewotICAgICAgICAgICAgICAgIC8vIGRhdGEgb3V0c2lkZSBvZiBlbGVtZW50IGNvbnRlbnQKLSAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGRhdGEubGVuZ3RoKCk7IGkrKykgewotICAgICAgICAgICAgICAgICAgICBpZiAoIVhNTENoYXIuaXNTcGFjZShkYXRhLmNoYXJBdChpKSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGFsbFdoaXRlU3BhY2UgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZTYXdDaGFyYWN0ZXJzID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIGFsbFdoaXRlU3BhY2U7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgZWxlbWVudERlZmF1bHQoU3RyaW5nIGRhdGEpIHsKLSAgICAgICAgLy8gbm8tb3AKLSAgICB9Ci0KLSAgICAvLwotICAgIC8vIFhNTERvY3VtZW50SGFuZGxlciBhbmQgWE1MRFRESGFuZGxlciBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIG5vdGlmaWVzIHRoZSBzdGFydCBvZiBhIGdlbmVyYWwgZW50aXR5LgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gVGhpcyBtZXRob2QgaXMgbm90IGNhbGxlZCBmb3IgZW50aXR5IHJlZmVyZW5jZXMKLSAgICAgKiBhcHBlYXJpbmcgYXMgcGFydCBvZiBhdHRyaWJ1dGUgdmFsdWVzLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgICAgIFRoZSBuYW1lIG9mIHRoZSBnZW5lcmFsIGVudGl0eS4KLSAgICAgKiBAcGFyYW0gaWRlbnRpZmllciBUaGUgcmVzb3VyY2UgaWRlbnRpZmllci4KLSAgICAgKiBAcGFyYW0gZW5jb2RpbmcgVGhlIGF1dG8tZGV0ZWN0ZWQgSUFOQSBlbmNvZGluZyBuYW1lIG9mIHRoZSBlbnRpdHkKLSAgICAgKiAgICAgICAgICAgICAgICAgc3RyZWFtLiBUaGlzIHZhbHVlIHdpbGwgYmUgbnVsbCBpbiB0aG9zZSBzaXR1YXRpb25zCi0gICAgICogICAgICAgICAgICAgICAgIHdoZXJlIHRoZSBlbnRpdHkgZW5jb2RpbmcgaXMgbm90IGF1dG8tZGV0ZWN0ZWQgKGUuZy4KLSAgICAgKiAgICAgICAgICAgICAgICAgaW50ZXJuYWwgZW50aXRpZXMgb3IgYSBkb2N1bWVudCBlbnRpdHkgdGhhdCBpcwotICAgICAqICAgICAgICAgICAgICAgICBwYXJzZWQgZnJvbSBhIGphdmEuaW8uUmVhZGVyKS4KLSAgICAgKiBAcGFyYW0gYXVncyAgICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0R2VuZXJhbEVudGl0eSgKLSAgICAgICAgU3RyaW5nIG5hbWUsCi0gICAgICAgIFhNTFJlc291cmNlSWRlbnRpZmllciBpZGVudGlmaWVyLAotICAgICAgICBTdHJpbmcgZW5jb2RpbmcsCi0gICAgICAgIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy8gUkVWSVNJVDogd2hhdCBzaG91bGQgaGFwcGVuIGlmIG5vcm1hbGl6ZV9kYXRhXyBpcyBvbj8/Ci0gICAgICAgIGZFbnRpdHlSZWYgPSB0cnVlOwotICAgICAgICAvLyBjYWxsIGhhbmRsZXJzCi0gICAgICAgIGlmIChmRG9jdW1lbnRIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZEb2N1bWVudEhhbmRsZXIuc3RhcnRHZW5lcmFsRW50aXR5KG5hbWUsIGlkZW50aWZpZXIsIGVuY29kaW5nLCBhdWdzKTsKLSAgICAgICAgfQotCi0gICAgfSAvLyBzdGFydEVudGl0eShTdHJpbmcsU3RyaW5nLFN0cmluZyxTdHJpbmcsU3RyaW5nKQotCi0gICAgLyoqCi0gICAgICogTm90aWZpZXMgb2YgdGhlIHByZXNlbmNlIG9mIGEgVGV4dERlY2wgbGluZSBpbiBhbiBlbnRpdHkuIElmIHByZXNlbnQsCi0gICAgICogdGhpcyBtZXRob2Qgd2lsbCBiZSBjYWxsZWQgaW1tZWRpYXRlbHkgZm9sbG93aW5nIHRoZSBzdGFydEVudGl0eSBjYWxsLgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gVGhpcyBtZXRob2Qgd2lsbCBuZXZlciBiZSBjYWxsZWQgZm9yIHRoZQotICAgICAqIGRvY3VtZW50IGVudGl0eTsgaXQgaXMgb25seSBjYWxsZWQgZm9yIGV4dGVybmFsIGdlbmVyYWwgZW50aXRpZXMKLSAgICAgKiByZWZlcmVuY2VkIGluIGRvY3VtZW50IGNvbnRlbnQuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGlzIG1ldGhvZCBpcyBub3QgY2FsbGVkIGZvciBlbnRpdHkgcmVmZXJlbmNlcwotICAgICAqIGFwcGVhcmluZyBhcyBwYXJ0IG9mIGF0dHJpYnV0ZSB2YWx1ZXMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdmVyc2lvbiAgVGhlIFhNTCB2ZXJzaW9uLCBvciBudWxsIGlmIG5vdCBzcGVjaWZpZWQuCi0gICAgICogQHBhcmFtIGVuY29kaW5nIFRoZSBJQU5BIGVuY29kaW5nIG5hbWUgb2YgdGhlIGVudGl0eS4KLSAgICAgKiBAcGFyYW0gYXVncyAgICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRleHREZWNsKFN0cmluZyB2ZXJzaW9uLCBTdHJpbmcgZW5jb2RpbmcsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy8gY2FsbCBoYW5kbGVycwotICAgICAgICBpZiAoZkRvY3VtZW50SGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLnRleHREZWNsKHZlcnNpb24sIGVuY29kaW5nLCBhdWdzKTsKLSAgICAgICAgfQotCi0gICAgfSAvLyB0ZXh0RGVjbChTdHJpbmcsU3RyaW5nKQotCi0gICAgLyoqCi0gICAgICogQSBjb21tZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIHRleHQgVGhlIHRleHQgaW4gdGhlIGNvbW1lbnQuCi0gICAgICogQHBhcmFtIGF1Z3MgICAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBhcHBsaWNhdGlvbiB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY29tbWVudChYTUxTdHJpbmcgdGV4dCwgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLQotICAgICAgICAvLyBjYWxsIGhhbmRsZXJzCi0gICAgICAgIGlmIChmRG9jdW1lbnRIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZEb2N1bWVudEhhbmRsZXIuY29tbWVudCh0ZXh0LCBhdWdzKTsKLSAgICAgICAgfQotCi0gICAgfSAvLyBjb21tZW50KFhNTFN0cmluZykKLQotICAgIC8qKgotICAgICAqIEEgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbi4gUHJvY2Vzc2luZyBpbnN0cnVjdGlvbnMgY29uc2lzdCBvZiBhCi0gICAgICogdGFyZ2V0IG5hbWUgYW5kLCBvcHRpb25hbGx5LCB0ZXh0IGRhdGEuIFRoZSBkYXRhIGlzIG9ubHkgbWVhbmluZ2Z1bAotICAgICAqIHRvIHRoZSBhcHBsaWNhdGlvbi4KLSAgICAgKiA8cD4KLSAgICAgKiBUeXBpY2FsbHksIGEgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbidzIGRhdGEgd2lsbCBjb250YWluIGEgc2VyaWVzCi0gICAgICogb2YgcHNldWRvLWF0dHJpYnV0ZXMuIFRoZXNlIHBzZXVkby1hdHRyaWJ1dGVzIGZvbGxvdyB0aGUgZm9ybSBvZgotICAgICAqIGVsZW1lbnQgYXR0cmlidXRlcyBidXQgYXJlIDxzdHJvbmc+bm90PC9zdHJvbmc+IHBhcnNlZCBvciBwcmVzZW50ZWQKLSAgICAgKiB0byB0aGUgYXBwbGljYXRpb24gYXMgYW55dGhpbmcgb3RoZXIgdGhhbiB0ZXh0LiBUaGUgYXBwbGljYXRpb24gaXMKLSAgICAgKiByZXNwb25zaWJsZSBmb3IgcGFyc2luZyB0aGUgZGF0YS4KLSAgICAgKgotICAgICAqIEBwYXJhbSB0YXJnZXQgVGhlIHRhcmdldC4KLSAgICAgKiBAcGFyYW0gZGF0YSAgIFRoZSBkYXRhIG9yIG51bGwgaWYgbm9uZSBzcGVjaWZpZWQuCi0gICAgICogQHBhcmFtIGF1Z3MgICAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oU3RyaW5nIHRhcmdldCwgWE1MU3RyaW5nIGRhdGEsIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy8gY2FsbCBoYW5kbGVycwotICAgICAgICBpZiAoZkRvY3VtZW50SGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLnByb2Nlc3NpbmdJbnN0cnVjdGlvbih0YXJnZXQsIGRhdGEsIGF1Z3MpOwotICAgICAgICB9Ci0KLSAgICB9IC8vIHByb2Nlc3NpbmdJbnN0cnVjdGlvbihTdHJpbmcsWE1MU3RyaW5nKQotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2Qgbm90aWZpZXMgdGhlIGVuZCBvZiBhIGdlbmVyYWwgZW50aXR5LgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gVGhpcyBtZXRob2QgaXMgbm90IGNhbGxlZCBmb3IgZW50aXR5IHJlZmVyZW5jZXMKLSAgICAgKiBhcHBlYXJpbmcgYXMgcGFydCBvZiBhdHRyaWJ1dGUgdmFsdWVzLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgICBUaGUgbmFtZSBvZiB0aGUgZW50aXR5LgotICAgICAqIEBwYXJhbSBhdWdzICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBYTklFeGNlcHRpb24KLSAgICAgKiAgICAgICAgICAgICAgICAgICBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kR2VuZXJhbEVudGl0eShTdHJpbmcgbmFtZSwgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLQotICAgICAgICAvLyBjYWxsIGhhbmRsZXJzCi0gICAgICAgIGZFbnRpdHlSZWYgPSBmYWxzZTsKLSAgICAgICAgaWYgKGZEb2N1bWVudEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci5lbmRHZW5lcmFsRW50aXR5KG5hbWUsIGF1Z3MpOwotICAgICAgICB9Ci0KLSAgICB9IC8vIGVuZEVudGl0eShTdHJpbmcpCi0KLSAgICAvLyBjb25zdGFudHMKLQotICAgIHN0YXRpYyBmaW5hbCBpbnQgSU5JVElBTF9TVEFDS19TSVpFID0gODsKLSAgICBzdGF0aWMgZmluYWwgaW50IElOQ19TVEFDS19TSVpFID0gODsKLQotICAgIC8vCi0gICAgLy8gRGF0YQotICAgIC8vCi0KLSAgICAvLyBTY2hlbWEgTm9ybWFsaXphdGlvbgotCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbiBERUJVR19OT1JNQUxJWkFUSU9OID0gZmFsc2U7Ci0gICAgLy8gdGVtcG9yYXJ5IGVtcHR5IHN0cmluZyBidWZmZXIuCi0gICAgcHJpdmF0ZSBmaW5hbCBYTUxTdHJpbmcgZkVtcHR5WE1MU3RyID0gbmV3IFhNTFN0cmluZyhudWxsLCAwLCAtMSk7Ci0gICAgLy8gdGVtcG9yYXJ5IGNoYXJhY3RlciBidWZmZXIsIGFuZCBlbXB0eSBzdHJpbmcgYnVmZmVyLgotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBCVUZGRVJfU0laRSA9IDIwOwotICAgIHByaXZhdGUgZmluYWwgWE1MU3RyaW5nIGZOb3JtYWxpemVkU3RyID0gbmV3IFhNTFN0cmluZygpOwotICAgIHByaXZhdGUgYm9vbGVhbiBmRmlyc3RDaHVuayA9IHRydWU7Ci0gICAgLy8gZ290IGZpcnN0IGNodW5rIGluIGNoYXJhY3RlcnMoKSAoU0FYKQotICAgIHByaXZhdGUgYm9vbGVhbiBmVHJhaWxpbmcgPSBmYWxzZTsgLy8gUHJldmlvdXMgY2h1bmsgaGFkIGEgdHJhaWxpbmcgc3BhY2UKLSAgICBwcml2YXRlIHNob3J0IGZXaGl0ZVNwYWNlID0gLTE7IC8vd2hpdGVTcGFjZTogcHJlc2VydmUvcmVwbGFjZS9jb2xsYXBzZQotICAgIHByaXZhdGUgYm9vbGVhbiBmVW5pb25UeXBlID0gZmFsc2U7Ci0KLSAgICAvKiogU2NoZW1hIGdyYW1tYXIgcmVzb2x2ZXIuICovCi0gICAgcHJpdmF0ZSBmaW5hbCBYU0dyYW1tYXJCdWNrZXQgZkdyYW1tYXJCdWNrZXQgPSBuZXcgWFNHcmFtbWFyQnVja2V0KCk7Ci0gICAgcHJpdmF0ZSBmaW5hbCBTdWJzdGl0dXRpb25Hcm91cEhhbmRsZXIgZlN1Ykdyb3VwSGFuZGxlciA9IG5ldyBTdWJzdGl0dXRpb25Hcm91cEhhbmRsZXIoZkdyYW1tYXJCdWNrZXQpOwotCi0gICAgLyoqIHRoZSBEViB1c2QgdG8gY29udmVydCB4c2k6dHlwZSB0byBhIFFOYW1lICovCi0gICAgLy8gUkVWSVNJVDogaW4gbmV3IHNpbXBsZSB0eXBlIGRlc2lnbiwgbWFrZSB0aGluZ3MgaW4gRFZzIHN0YXRpYywKLSAgICAvLyAgICAgICAgICBzbyB0aGF0IHdlIGNhbiBRTmFtZURWLmdldENvbXBpbGVkRm9ybSgpCi0gICAgcHJpdmF0ZSBmaW5hbCBYU1NpbXBsZVR5cGUgZlFOYW1lRFYgPQotICAgICAgICAoWFNTaW1wbGVUeXBlKSBTY2hlbWFHcmFtbWFyLlNHX1NjaGVtYU5TLmdldEdsb2JhbFR5cGVEZWNsKFNjaGVtYVN5bWJvbHMuQVRUVkFMX1FOQU1FKTsKLQotICAgIHByaXZhdGUgZmluYWwgQ01Ob2RlRmFjdG9yeSBub2RlRmFjdG9yeSA9IG5ldyBDTU5vZGVGYWN0b3J5KCk7Ci0gICAgLyoqIHVzZWQgdG8gYnVpbGQgY29udGVudCBtb2RlbHMgKi8KLSAgICAvLyBSRVZJU0lUOiBjcmVhdGUgZGVjbCBwb29sLCBhbmQgcGFzcyBpdCB0byBlYWNoIHRyYXZlcnNlcnMKLSAgICBwcml2YXRlIGZpbmFsIENNQnVpbGRlciBmQ01CdWlsZGVyID0gbmV3IENNQnVpbGRlcihub2RlRmFjdG9yeSk7Ci0KLSAgICAvLyBTY2hlbWEgZ3JhbW1hciBsb2FkZXIKLSAgICBwcml2YXRlIGZpbmFsIFhNTFNjaGVtYUxvYWRlciBmU2NoZW1hTG9hZGVyID0KLSAgICAgICAgbmV3IFhNTFNjaGVtYUxvYWRlcigKLSAgICAgICAgICAgICAgICBmWFNJRXJyb3JSZXBvcnRlci5mRXJyb3JSZXBvcnRlciwKLSAgICAgICAgICAgICAgICBmR3JhbW1hckJ1Y2tldCwKLSAgICAgICAgICAgICAgICBmU3ViR3JvdXBIYW5kbGVyLAotICAgICAgICAgICAgICAgIGZDTUJ1aWxkZXIpOwotCi0gICAgLy8gc3RhdGUKLQotICAgIC8qKiBTdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIHZhbGlkYXRpb24gcm9vdC4gKi8KLSAgICAvLyBSRVZJU0lUOiB3aGF0IGRvIHdlIHN0b3JlIGhlcmU/IFFOYW1lLCBYUEFUSCwgc29tZSBJRD8gdXNlIHJhd25hbWUgbm93LgotICAgIHByaXZhdGUgU3RyaW5nIGZWYWxpZGF0aW9uUm9vdDsKLQotICAgIC8qKiBTa2lwIHZhbGlkYXRpb246IGFueXRoaW5nIGJlbG93IHRoaXMgbGV2ZWwgc2hvdWxkIGJlIHNraXBwZWQgKi8KLSAgICBwcml2YXRlIGludCBmU2tpcFZhbGlkYXRpb25EZXB0aDsKLQotICAgIC8qKiBhbnl0aGluZyBhYm92ZSB0aGlzIGxldmVsIGhhcyB2YWxpZGF0aW9uX2F0dGVtcHRlZCAhPSBmdWxsICovCi0gICAgcHJpdmF0ZSBpbnQgZk5GdWxsVmFsaWRhdGlvbkRlcHRoOwotCi0gICAgLyoqIGFueXRoaW5nIGFib3ZlIHRoaXMgbGV2ZWwgaGFzIHZhbGlkYXRpb25fYXR0ZW1wdGVkICE9IG5vbmUgKi8KLSAgICBwcml2YXRlIGludCBmTk5vbmVWYWxpZGF0aW9uRGVwdGg7Ci0KLSAgICAvKiogRWxlbWVudCBkZXB0aDogLTI6IHZhbGlkYXRvciBub3QgaW4gcGlwZWxpbmU7ID49IC0xIGN1cnJlbnQgZGVwdGguICovCi0gICAgcHJpdmF0ZSBpbnQgZkVsZW1lbnREZXB0aDsKLQotICAgIC8qKiBTZWVuIHN1YiBlbGVtZW50cy4gKi8KLSAgICBwcml2YXRlIGJvb2xlYW4gZlN1YkVsZW1lbnQ7Ci0KLSAgICAvKiogU2VlbiBzdWIgZWxlbWVudHMgc3RhY2suICovCi0gICAgcHJpdmF0ZSBib29sZWFuW10gZlN1YkVsZW1lbnRTdGFjayA9IG5ldyBib29sZWFuW0lOSVRJQUxfU1RBQ0tfU0laRV07Ci0KLSAgICAvKiogQ3VycmVudCBlbGVtZW50IGRlY2xhcmF0aW9uLiAqLwotICAgIHByaXZhdGUgWFNFbGVtZW50RGVjbCBmQ3VycmVudEVsZW1EZWNsOwotCi0gICAgLyoqIEVsZW1lbnQgZGVjbCBzdGFjay4gKi8KLSAgICBwcml2YXRlIFhTRWxlbWVudERlY2xbXSBmRWxlbURlY2xTdGFjayA9IG5ldyBYU0VsZW1lbnREZWNsW0lOSVRJQUxfU1RBQ0tfU0laRV07Ci0KLSAgICAvKiogbmlsIHZhbHVlIG9mIHRoZSBjdXJyZW50IGVsZW1lbnQgKi8KLSAgICBwcml2YXRlIGJvb2xlYW4gZk5pbDsKLQotICAgIC8qKiBuaWwgdmFsdWUgc3RhY2sgKi8KLSAgICBwcml2YXRlIGJvb2xlYW5bXSBmTmlsU3RhY2sgPSBuZXcgYm9vbGVhbltJTklUSUFMX1NUQUNLX1NJWkVdOwotCi0gICAgLyoqIG5vdGF0aW9uIHZhbHVlIG9mIHRoZSBjdXJyZW50IGVsZW1lbnQgKi8KLSAgICBwcml2YXRlIFhTTm90YXRpb25EZWNsIGZOb3RhdGlvbjsKLQotICAgIC8qKiBub3RhdGlvbiBzdGFjayAqLwotICAgIHByaXZhdGUgWFNOb3RhdGlvbkRlY2xbXSBmTm90YXRpb25TdGFjayA9IG5ldyBYU05vdGF0aW9uRGVjbFtJTklUSUFMX1NUQUNLX1NJWkVdOwotCi0gICAgLyoqIEN1cnJlbnQgdHlwZS4gKi8KLSAgICBwcml2YXRlIFhTVHlwZURlZmluaXRpb24gZkN1cnJlbnRUeXBlOwotCi0gICAgLyoqIHR5cGUgc3RhY2suICovCi0gICAgcHJpdmF0ZSBYU1R5cGVEZWZpbml0aW9uW10gZlR5cGVTdGFjayA9IG5ldyBYU1R5cGVEZWZpbml0aW9uW0lOSVRJQUxfU1RBQ0tfU0laRV07Ci0KLSAgICAvKiogQ3VycmVudCBjb250ZW50IG1vZGVsLiAqLwotICAgIHByaXZhdGUgWFNDTVZhbGlkYXRvciBmQ3VycmVudENNOwotCi0gICAgLyoqIENvbnRlbnQgbW9kZWwgc3RhY2suICovCi0gICAgcHJpdmF0ZSBYU0NNVmFsaWRhdG9yW10gZkNNU3RhY2sgPSBuZXcgWFNDTVZhbGlkYXRvcltJTklUSUFMX1NUQUNLX1NJWkVdOwotCi0gICAgLyoqIHRoZSBjdXJyZW50IHN0YXRlIG9mIHRoZSBjdXJyZW50IGNvbnRlbnQgbW9kZWwgKi8KLSAgICBwcml2YXRlIGludFtdIGZDdXJyQ01TdGF0ZTsKLQotICAgIC8qKiBzdGFjayB0byBob2xkIGNvbnRlbnQgbW9kZWwgc3RhdGVzICovCi0gICAgcHJpdmF0ZSBpbnRbXVtdIGZDTVN0YXRlU3RhY2sgPSBuZXcgaW50W0lOSVRJQUxfU1RBQ0tfU0laRV1bXTsKLQotICAgIC8qKiB3aGV0aGVyIHRoZSBjdXJyZXQgZWxlbWVudCBpcyBzdHJpY3RseSBhc3Nlc3NlZCAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBmU3RyaWN0QXNzZXNzID0gdHJ1ZTsKLQotICAgIC8qKiBzdHJpY3QgYXNzZXNzIHN0YWNrICovCi0gICAgcHJpdmF0ZSBib29sZWFuW10gZlN0cmljdEFzc2Vzc1N0YWNrID0gbmV3IGJvb2xlYW5bSU5JVElBTF9TVEFDS19TSVpFXTsKLQotICAgIC8qKiBUZW1wb3Jhcnkgc3RyaW5nIGJ1ZmZlcnMuICovCi0gICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmdCdWZmZXIgZkJ1ZmZlciA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLQotICAgIC8qKiBXaGV0aGVyIG5lZWQgdG8gYXBwZW5kIGNoYXJhY3RlcnMgdG8gZkJ1ZmZlciAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBmQXBwZW5kQnVmZmVyID0gdHJ1ZTsKLQotICAgIC8qKiBEaWQgd2Ugc2VlIGFueSBjaGFyYWN0ZXIgZGF0YT8gKi8KLSAgICBwcml2YXRlIGJvb2xlYW4gZlNhd1RleHQgPSBmYWxzZTsKLQotICAgIC8qKiBzdGFjayB0byByZWNvcmQgaWYgd2Ugc2F3IGNoYXJhY3RlciBkYXRhICovCi0gICAgcHJpdmF0ZSBib29sZWFuW10gZlNhd1RleHRTdGFjayA9IG5ldyBib29sZWFuW0lOSVRJQUxfU1RBQ0tfU0laRV07Ci0KLSAgICAvKiogRGlkIHdlIHNlZSBub24td2hpdGVzcGFjZSBjaGFyYWN0ZXIgZGF0YT8gKi8KLSAgICBwcml2YXRlIGJvb2xlYW4gZlNhd0NoYXJhY3RlcnMgPSBmYWxzZTsKLQotICAgIC8qKiBTdGFjayB0byByZWNvcmQgaWYgd2Ugc2F3IGNoYXJhY3RlciBkYXRhIG91dHNpZGUgb2YgZWxlbWVudCBjb250ZW50Ki8KLSAgICBwcml2YXRlIGJvb2xlYW5bXSBmU3RyaW5nQ29udGVudCA9IG5ldyBib29sZWFuW0lOSVRJQUxfU1RBQ0tfU0laRV07Ci0KLSAgICAvKiogdGVtcG9yYXJ5IHFuYW1lICovCi0gICAgcHJpdmF0ZSBmaW5hbCBRTmFtZSBmVGVtcFFOYW1lID0gbmV3IFFOYW1lKCk7Ci0KLSAgICAvKiogdGVtcG9yYXJ5IHZhbGlkYXRlZCBpbmZvICovCi0gICAgcHJpdmF0ZSBWYWxpZGF0ZWRJbmZvIGZWYWxpZGF0ZWRJbmZvID0gbmV3IFZhbGlkYXRlZEluZm8oKTsKLQotICAgIC8vIHVzZWQgdG8gdmFsaWRhdGUgZGVmYXVsdC9maXhlZCB2YWx1ZXMgYWdhaW5zdCB4c2k6dHlwZQotICAgIC8vIG9ubHkgbmVlZCB0byBjaGVjayBmYWNldHMsIHNvIHdlIHNldCBleHRyYUNoZWNraW5nIHRvIGZhbHNlIChpbiByZXNldCkKLSAgICBwcml2YXRlIFZhbGlkYXRpb25TdGF0ZSBmU3RhdGU0WHNpVHlwZSA9IG5ldyBWYWxpZGF0aW9uU3RhdGUoKTsKLQotICAgIC8vIHVzZWQgdG8gYXBwbHkgZGVmYXVsdC9maXhlZCB2YWx1ZXMKLSAgICAvLyBvbmx5IG5lZWQgdG8gY2hlY2sgaWQvaWRyZWYvZW50aXR5LCBzbyB3ZSBzZXQgY2hlY2tGYWNldHMgdG8gZmFsc2UKLSAgICBwcml2YXRlIFZhbGlkYXRpb25TdGF0ZSBmU3RhdGU0QXBwbHlEZWZhdWx0ID0gbmV3IFZhbGlkYXRpb25TdGF0ZSgpOwotCi0gICAgLy8gaWRlbnRpdHkgY29uc3RyYWludCBpbmZvcm1hdGlvbgotCi0gICAgLyoqCi0gICAgICogU3RhY2sgb2YgYWN0aXZlIFhQYXRoIG1hdGNoZXJzIGZvciBpZGVudGl0eSBjb25zdHJhaW50cy4gQWxsCi0gICAgICogYWN0aXZlIFhQYXRoIG1hdGNoZXJzIGFyZSBub3RpZmllZCBvZiBzdGFydEVsZW1lbnQKLSAgICAgKiBhbmQgZW5kRWxlbWVudCBjYWxsYmFja3MgaW4gb3JkZXIgdG8gcGVyZm9ybSB0aGVpciBtYXRjaGVzLgotICAgICAqIDxwPgotICAgICAqIEZvciBlYWNoIGVsZW1lbnQgd2l0aCBpZGVudGl0eSBjb25zdHJhaW50cywgdGhlIHNlbGVjdG9yIG9mCi0gICAgICogZWFjaCBpZGVudGl0eSBjb25zdHJhaW50IGlzIGFjdGl2YXRlZC4gV2hlbiB0aGUgc2VsZWN0b3IgbWF0Y2hlcwotICAgICAqIGl0cyBYUGF0aCwgdGhlbiBhbGwgdGhlIGZpZWxkcyBvZiB0aGUgaWRlbnRpdHkgY29uc3RyYWludCBhcmUKLSAgICAgKiBhY3RpdmF0ZWQuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBPbmNlIHRoZSBhY3RpdmF0aW9uIHNjb3BlIGlzIGxlZnQsIHRoZQotICAgICAqIFhQYXRoIG1hdGNoZXJzIGFyZSBhdXRvbWF0aWNhbGx5IHJlbW92ZWQgZnJvbSB0aGUgc3RhY2sgb2YKLSAgICAgKiBhY3RpdmUgbWF0Y2hlcnMgYW5kIG5vIGxvbmdlciByZWNlaXZlIGNhbGxiYWNrcy4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgWFBhdGhNYXRjaGVyU3RhY2sgZk1hdGNoZXJTdGFjayA9IG5ldyBYUGF0aE1hdGNoZXJTdGFjaygpOwotCi0gICAgLyoqIENhY2hlIG9mIHZhbHVlIHN0b3JlcyBmb3IgaWRlbnRpdHkgY29uc3RyYWludCBmaWVsZHMuICovCi0gICAgcHJvdGVjdGVkIFZhbHVlU3RvcmVDYWNoZSBmVmFsdWVTdG9yZUNhY2hlID0gbmV3IFZhbHVlU3RvcmVDYWNoZSgpOwotCi0gICAgLy8KLSAgICAvLyBDb25zdHJ1Y3RvcnMKLSAgICAvLwotCi0gICAgLyoqIERlZmF1bHQgY29uc3RydWN0b3IuICovCi0gICAgcHVibGljIFhNTFNjaGVtYVZhbGlkYXRvcigpIHsKLSAgICAgICAgZlN0YXRlNFhzaVR5cGUuc2V0RXh0cmFDaGVja2luZyhmYWxzZSk7Ci0gICAgICAgIGZTdGF0ZTRBcHBseURlZmF1bHQuc2V0RmFjZXRDaGVja2luZyhmYWxzZSk7Ci0KLSAgICB9IC8vIDxpbml0PigpCi0KLSAgICAvKgotICAgICAqIFJlc2V0cyB0aGUgY29tcG9uZW50LiBUaGUgY29tcG9uZW50IGNhbiBxdWVyeSB0aGUgY29tcG9uZW50IG1hbmFnZXIKLSAgICAgKiBhYm91dCBhbnkgZmVhdHVyZXMgYW5kIHByb3BlcnRpZXMgdGhhdCBhZmZlY3QgdGhlIG9wZXJhdGlvbiBvZiB0aGUKLSAgICAgKiBjb21wb25lbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29tcG9uZW50TWFuYWdlciBUaGUgY29tcG9uZW50IG1hbmFnZXIuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBUaHJvd24gYnkgY29tcG9uZW50IG9uIGZpbml0aWFsaXphdGlvbiBlcnJvci4KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBGb3IgZXhhbXBsZSwgaWYgYSBmZWF0dXJlIG9yIHByb3BlcnR5IGlzCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgcmVxdWlyZWQgZm9yIHRoZSBvcGVyYXRpb24gb2YgdGhlIGNvbXBvbmVudCwgdGhlCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgY29tcG9uZW50IG1hbmFnZXIgbWF5IHRocm93IGEKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIG9yIGEKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcmVzZXQoWE1MQ29tcG9uZW50TWFuYWdlciBjb21wb25lbnRNYW5hZ2VyKSB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiB7Ci0KLQotICAgICAgICBmSWRDb25zdHJhaW50ID0gZmFsc2U7Ci0gICAgICAgIC8vcmVzZXQgWFNERGVzY3JpcHRpb24KLSAgICAgICAgZkxvY2F0aW9uUGFpcnMuY2xlYXIoKTsKLQotICAgICAgICAvLyBjbGVhbnVwIGlkIHRhYmxlCi0gICAgICAgIGZWYWxpZGF0aW9uU3RhdGUucmVzZXRJRFRhYmxlcygpOwotCi0gICAgICAgIC8vcGFzcyB0aGUgY29tcG9uZW50IG1hbmFnZXIgdG8gdGhlIGZhY3RvcnkuLgotICAgICAgICBub2RlRmFjdG9yeS5yZXNldChjb21wb25lbnRNYW5hZ2VyKTsKLQotICAgICAgICAvLyByZXNldCBzY2hlbWEgbG9hZGVyCi0gICAgICAgIGZTY2hlbWFMb2FkZXIucmVzZXQoY29tcG9uZW50TWFuYWdlcik7Ci0KLSAgICAgICAgLy8gaW5pdGlhbGl6ZSBzdGF0ZQotICAgICAgICBmQ3VycmVudEVsZW1EZWNsID0gbnVsbDsKLSAgICAgICAgZkN1cnJlbnRDTSA9IG51bGw7Ci0gICAgICAgIGZDdXJyQ01TdGF0ZSA9IG51bGw7Ci0gICAgICAgIGZTa2lwVmFsaWRhdGlvbkRlcHRoID0gLTE7Ci0gICAgICAgIGZORnVsbFZhbGlkYXRpb25EZXB0aCA9IC0xOwotICAgICAgICBmTk5vbmVWYWxpZGF0aW9uRGVwdGggPSAtMTsKLSAgICAgICAgZkVsZW1lbnREZXB0aCA9IC0xOwotICAgICAgICBmU3ViRWxlbWVudCA9IGZhbHNlOwotICAgICAgICBmU2NoZW1hRHluYW1pY1ZhbGlkYXRpb24gPSBmYWxzZTsKLQotICAgICAgICAvLyBkYXRhdHlwZSBub3JtYWxpemF0aW9uCi0gICAgICAgIGZFbnRpdHlSZWYgPSBmYWxzZTsKLSAgICAgICAgZkluQ0RBVEEgPSBmYWxzZTsKLQotICAgICAgICBmTWF0Y2hlclN0YWNrLmNsZWFyKCk7Ci0KLSAgICAgICAgaWYgKCFmTWF5TWF0Y2hGaWVsZE1hcC5pc0VtcHR5KCkpIHsKLSAgICAgICAgICAgIC8vIHNob3VsZCBvbmx5IGNsZWFyIHRoaXMgaWYgdGhlIGxhc3Qgc2NoZW1hIGhhZCBpZGVudGl0eSBjb25zdHJhaW50cy4KLSAgICAgICAgICAgIGZNYXlNYXRjaEZpZWxkTWFwLmNsZWFyKCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBnZXQgZXJyb3IgcmVwb3J0ZXIKLSAgICAgICAgZlhTSUVycm9yUmVwb3J0ZXIucmVzZXQoKFhNTEVycm9yUmVwb3J0ZXIpIGNvbXBvbmVudE1hbmFnZXIuZ2V0UHJvcGVydHkoRVJST1JfUkVQT1JURVIpKTsKLQotICAgICAgICBib29sZWFuIHBhcnNlcl9zZXR0aW5ncyA9IGNvbXBvbmVudE1hbmFnZXIuZ2V0RmVhdHVyZShQQVJTRVJfU0VUVElOR1MsIHRydWUpOwotCi0gICAgICAgIGlmICghcGFyc2VyX3NldHRpbmdzKXsKLSAgICAgICAgICAgIC8vIHBhcnNlciBzZXR0aW5ncyBoYXZlIG5vdCBiZWVuIGNoYW5nZWQKLSAgICAgICAgICAgIGZWYWxpZGF0aW9uTWFuYWdlci5hZGRWYWxpZGF0aW9uU3RhdGUoZlZhbGlkYXRpb25TdGF0ZSk7Ci0gICAgICAgICAgICAvLyBSZS1wYXJzZSBleHRlcm5hbCBzY2hlbWEgbG9jYXRpb24gcHJvcGVydGllcy4KLSAgICAgICAgICAgIFhNTFNjaGVtYUxvYWRlci5wcm9jZXNzRXh0ZXJuYWxIaW50cygKLSAgICAgICAgICAgICAgICBmRXh0ZXJuYWxTY2hlbWFzLAotICAgICAgICAgICAgICAgIGZFeHRlcm5hbE5vTmFtZXNwYWNlU2NoZW1hLAotICAgICAgICAgICAgICAgIGZMb2NhdGlvblBhaXJzLAotICAgICAgICAgICAgICAgIGZYU0lFcnJvclJlcG9ydGVyLmZFcnJvclJlcG9ydGVyKTsKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotCi0KLSAgICAgICAgLy8gZ2V0IHN5bWJvbCB0YWJsZS4gaWYgaXQncyBhIG5ldyBvbmUsIGFkZCBzeW1ib2xzIHRvIGl0LgotICAgICAgICBTeW1ib2xUYWJsZSBzeW1ib2xUYWJsZSA9IChTeW1ib2xUYWJsZSkgY29tcG9uZW50TWFuYWdlci5nZXRQcm9wZXJ0eShTWU1CT0xfVEFCTEUpOwotICAgICAgICBpZiAoc3ltYm9sVGFibGUgIT0gZlN5bWJvbFRhYmxlKSB7Ci0gICAgICAgICAgICBmU3ltYm9sVGFibGUgPSBzeW1ib2xUYWJsZTsKLSAgICAgICAgfQotCi0gICAgICAgIGZOYW1lc3BhY2VHcm93dGggPSBjb21wb25lbnRNYW5hZ2VyLmdldEZlYXR1cmUoTkFNRVNQQUNFX0dST1dUSCwgZmFsc2UpOwotICAgICAgICBmRHluYW1pY1ZhbGlkYXRpb24gPSBjb21wb25lbnRNYW5hZ2VyLmdldEZlYXR1cmUoRFlOQU1JQ19WQUxJREFUSU9OLCBmYWxzZSk7Ci0KLSAgICAgICAgaWYgKGZEeW5hbWljVmFsaWRhdGlvbikgewotICAgICAgICAgICAgZkRvVmFsaWRhdGlvbiA9IHRydWU7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBmRG9WYWxpZGF0aW9uID0gY29tcG9uZW50TWFuYWdlci5nZXRGZWF0dXJlKFZBTElEQVRJT04sIGZhbHNlKTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChmRG9WYWxpZGF0aW9uKSB7Ci0gICAgICAgICAgICBmRG9WYWxpZGF0aW9uIHw9IGNvbXBvbmVudE1hbmFnZXIuZ2V0RmVhdHVyZShYTUxTY2hlbWFWYWxpZGF0b3IuU0NIRU1BX1ZBTElEQVRJT04sIGZhbHNlKTsKLSAgICAgICAgfQotCi0gICAgICAgIGZGdWxsQ2hlY2tpbmcgPSBjb21wb25lbnRNYW5hZ2VyLmdldEZlYXR1cmUoU0NIRU1BX0ZVTExfQ0hFQ0tJTkcsIGZhbHNlKTsKLSAgICAgICAgZk5vcm1hbGl6ZURhdGEgPSBjb21wb25lbnRNYW5hZ2VyLmdldEZlYXR1cmUoTk9STUFMSVpFX0RBVEEsIGZhbHNlKTsKLSAgICAgICAgZlNjaGVtYUVsZW1lbnREZWZhdWx0ID0gY29tcG9uZW50TWFuYWdlci5nZXRGZWF0dXJlKFNDSEVNQV9FTEVNRU5UX0RFRkFVTFQsIGZhbHNlKTsKLQotICAgICAgICBmQXVnUFNWSSA9IGNvbXBvbmVudE1hbmFnZXIuZ2V0RmVhdHVyZShTQ0hFTUFfQVVHTUVOVF9QU1ZJLCB0cnVlKTsKLQotICAgICAgICBmU2NoZW1hVHlwZSA9Ci0gICAgICAgICAgICAgICAgKFN0cmluZykgY29tcG9uZW50TWFuYWdlci5nZXRQcm9wZXJ0eSgKLSAgICAgICAgICAgICAgICAgICAgQ29uc3RhbnRzLkpBWFBfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLlNDSEVNQV9MQU5HVUFHRSwgbnVsbCk7Ci0KLSAgICAgICAgZlVzZUdyYW1tYXJQb29sT25seSA9IGNvbXBvbmVudE1hbmFnZXIuZ2V0RmVhdHVyZShVU0VfR1JBTU1BUl9QT09MX09OTFksIGZhbHNlKTsKLQotICAgICAgICBmRW50aXR5UmVzb2x2ZXIgPSAoWE1MRW50aXR5UmVzb2x2ZXIpIGNvbXBvbmVudE1hbmFnZXIuZ2V0UHJvcGVydHkoRU5USVRZX01BTkFHRVIpOwotCi0gICAgICAgIGZWYWxpZGF0aW9uTWFuYWdlciA9IChWYWxpZGF0aW9uTWFuYWdlcikgY29tcG9uZW50TWFuYWdlci5nZXRQcm9wZXJ0eShWQUxJREFUSU9OX01BTkFHRVIpOwotICAgICAgICBmVmFsaWRhdGlvbk1hbmFnZXIuYWRkVmFsaWRhdGlvblN0YXRlKGZWYWxpZGF0aW9uU3RhdGUpOwotICAgICAgICBmVmFsaWRhdGlvblN0YXRlLnNldFN5bWJvbFRhYmxlKGZTeW1ib2xUYWJsZSk7Ci0KLQotICAgICAgICAvLyBnZXQgc2NoZW1hIGxvY2F0aW9uIHByb3BlcnRpZXMKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGZFeHRlcm5hbFNjaGVtYXMgPSAoU3RyaW5nKSBjb21wb25lbnRNYW5hZ2VyLmdldFByb3BlcnR5KFNDSEVNQV9MT0NBVElPTik7Ci0gICAgICAgICAgICBmRXh0ZXJuYWxOb05hbWVzcGFjZVNjaGVtYSA9Ci0gICAgICAgICAgICAgICAgKFN0cmluZykgY29tcG9uZW50TWFuYWdlci5nZXRQcm9wZXJ0eShTQ0hFTUFfTk9OU19MT0NBVElPTik7Ci0gICAgICAgIH0gY2F0Y2ggKFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gZSkgewotICAgICAgICAgICAgZkV4dGVybmFsU2NoZW1hcyA9IG51bGw7Ci0gICAgICAgICAgICBmRXh0ZXJuYWxOb05hbWVzcGFjZVNjaGVtYSA9IG51bGw7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBzdG9yZSB0aGUgZXh0ZXJuYWwgc2NoZW1hIGxvY2F0aW9ucy4gdGhleSBhcmUgc2V0IHdoZW4gcmVzZXQgaXMgY2FsbGVkLAotICAgICAgICAvLyBzbyBhbnkgb3RoZXIgc2NoZW1hTG9jYXRpb24gZGVjbGFyYXRpb24gZm9yIHRoZSBzYW1lIG5hbWVzcGFjZSB3aWxsIGJlCi0gICAgICAgIC8vIGVmZmVjdGl2ZWx5IGlnbm9yZWQuIGJlY3Vhc2Ugd2UgY2hvb3NlIHRvIHRha2UgZmlyc3QgbG9jYXRpb24gaGludAotICAgICAgICAvLyBhdmFpbGFibGUgZm9yIGEgcGFydGljdWxhciBuYW1lc3BhY2UuCi0gICAgICAgIFhNTFNjaGVtYUxvYWRlci5wcm9jZXNzRXh0ZXJuYWxIaW50cygKLSAgICAgICAgICAgIGZFeHRlcm5hbFNjaGVtYXMsCi0gICAgICAgICAgICBmRXh0ZXJuYWxOb05hbWVzcGFjZVNjaGVtYSwKLSAgICAgICAgICAgIGZMb2NhdGlvblBhaXJzLAotICAgICAgICAgICAgZlhTSUVycm9yUmVwb3J0ZXIuZkVycm9yUmVwb3J0ZXIpOwotCi0gICAgICAgIGZKYXhwU2NoZW1hU291cmNlID0gY29tcG9uZW50TWFuYWdlci5nZXRQcm9wZXJ0eShKQVhQX1NDSEVNQV9TT1VSQ0UsIG51bGwpOwotCi0gICAgICAgIC8vIGNsZWFyIGdyYW1tYXJzLCBhbmQgcHV0IHRoZSBvbmUgZm9yIHNjaGVtYSBuYW1lc3BhY2UgdGhlcmUKLSAgICAgICAgZkdyYW1tYXJQb29sID0gKFhNTEdyYW1tYXJQb29sKSBjb21wb25lbnRNYW5hZ2VyLmdldFByb3BlcnR5KFhNTEdSQU1NQVJfUE9PTCwgbnVsbCk7Ci0KLSAgICAgICAgZlN0YXRlNFhzaVR5cGUuc2V0U3ltYm9sVGFibGUoc3ltYm9sVGFibGUpOwotICAgICAgICBmU3RhdGU0QXBwbHlEZWZhdWx0LnNldFN5bWJvbFRhYmxlKHN5bWJvbFRhYmxlKTsKLQotICAgIH0gLy8gcmVzZXQoWE1MQ29tcG9uZW50TWFuYWdlcikKLQotICAgIC8vCi0gICAgLy8gRmllbGRBY3RpdmF0b3IgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBTdGFydCB0aGUgdmFsdWUgc2NvcGUgZm9yIHRoZSBzcGVjaWZpZWQgaWRlbnRpdHkgY29uc3RyYWludC4gVGhpcwotICAgICAqIG1ldGhvZCBpcyBjYWxsZWQgd2hlbiB0aGUgc2VsZWN0b3IgbWF0Y2hlcyBpbiBvcmRlciB0byBpbml0aWFsaXplCi0gICAgICogdGhlIHZhbHVlIHN0b3JlLgotICAgICAqCi0gICAgICogQHBhcmFtIGlkZW50aXR5Q29uc3RyYWludCBUaGUgaWRlbnRpdHkgY29uc3RyYWludC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydFZhbHVlU2NvcGVGb3IoSWRlbnRpdHlDb25zdHJhaW50IGlkZW50aXR5Q29uc3RyYWludCwgaW50IGluaXRpYWxEZXB0aCkgewotCi0gICAgICAgIFZhbHVlU3RvcmVCYXNlIHZhbHVlU3RvcmUgPQotICAgICAgICAgICAgZlZhbHVlU3RvcmVDYWNoZS5nZXRWYWx1ZVN0b3JlRm9yKGlkZW50aXR5Q29uc3RyYWludCwgaW5pdGlhbERlcHRoKTsKLSAgICAgICAgdmFsdWVTdG9yZS5zdGFydFZhbHVlU2NvcGUoKTsKLQotICAgIH0gLy8gc3RhcnRWYWx1ZVNjb3BlRm9yKElkZW50aXR5Q29uc3RyYWludCBpZGVudGl0eUNvbnN0cmFpbnQpCi0KLSAgICAvKioKLSAgICAgKiBSZXF1ZXN0IHRvIGFjdGl2YXRlIHRoZSBzcGVjaWZpZWQgZmllbGQuIFRoaXMgbWV0aG9kIHJldHVybnMgdGhlCi0gICAgICogbWF0Y2hlciBmb3IgdGhlIGZpZWxkLgotICAgICAqCi0gICAgICogQHBhcmFtIGZpZWxkIFRoZSBmaWVsZCB0byBhY3RpdmF0ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFBhdGhNYXRjaGVyIGFjdGl2YXRlRmllbGQoRmllbGQgZmllbGQsIGludCBpbml0aWFsRGVwdGgpIHsKLSAgICAgICAgVmFsdWVTdG9yZSB2YWx1ZVN0b3JlID0KLSAgICAgICAgICAgIGZWYWx1ZVN0b3JlQ2FjaGUuZ2V0VmFsdWVTdG9yZUZvcihmaWVsZC5nZXRJZGVudGl0eUNvbnN0cmFpbnQoKSwgaW5pdGlhbERlcHRoKTsKLSAgICAgICAgc2V0TWF5TWF0Y2goZmllbGQsIEJvb2xlYW4uVFJVRSk7Ci0gICAgICAgIFhQYXRoTWF0Y2hlciBtYXRjaGVyID0gZmllbGQuY3JlYXRlTWF0Y2hlcih0aGlzLCB2YWx1ZVN0b3JlKTsKLSAgICAgICAgZk1hdGNoZXJTdGFjay5hZGRNYXRjaGVyKG1hdGNoZXIpOwotICAgICAgICBtYXRjaGVyLnN0YXJ0RG9jdW1lbnRGcmFnbWVudCgpOwotICAgICAgICByZXR1cm4gbWF0Y2hlcjsKLSAgICB9IC8vIGFjdGl2YXRlRmllbGQoRmllbGQpOlhQYXRoTWF0Y2hlcgotCi0gICAgLyoqCi0gICAgICogRW5kcyB0aGUgdmFsdWUgc2NvcGUgZm9yIHRoZSBzcGVjaWZpZWQgaWRlbnRpdHkgY29uc3RyYWludC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBpZGVudGl0eUNvbnN0cmFpbnQgVGhlIGlkZW50aXR5IGNvbnN0cmFpbnQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kVmFsdWVTY29wZUZvcihJZGVudGl0eUNvbnN0cmFpbnQgaWRlbnRpdHlDb25zdHJhaW50LCBpbnQgaW5pdGlhbERlcHRoKSB7Ci0KLSAgICAgICAgVmFsdWVTdG9yZUJhc2UgdmFsdWVTdG9yZSA9Ci0gICAgICAgICAgICBmVmFsdWVTdG9yZUNhY2hlLmdldFZhbHVlU3RvcmVGb3IoaWRlbnRpdHlDb25zdHJhaW50LCBpbml0aWFsRGVwdGgpOwotICAgICAgICB2YWx1ZVN0b3JlLmVuZFZhbHVlU2NvcGUoKTsKLQotICAgIH0gLy8gZW5kVmFsdWVTY29wZUZvcihJZGVudGl0eUNvbnN0cmFpbnQpCi0KLSAgICAvKioKLSAgICAgKiBTZXRzIHdoZXRoZXIgdGhlIGdpdmVuIGZpZWxkIGlzIHBlcm1pdHRlZCB0byBtYXRjaCBhIHZhbHVlLgotICAgICAqIFRoaXMgc2hvdWxkIGJlIHVzZWQgdG8gY2F0Y2ggaW5zdGFuY2UgZG9jdW1lbnRzIHRoYXQgdHJ5Ci0gICAgICogYW5kIG1hdGNoIGEgZmllbGQgc2V2ZXJhbCB0aW1lcyBpbiB0aGUgc2FtZSBzY29wZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBmaWVsZCBUaGUgZmllbGQgdGhhdCBtYXkgYmUgcGVybWl0dGVkIHRvIGJlIG1hdGNoZWQuCi0gICAgICogQHBhcmFtIHN0YXRlIEJvb2xlYW4gaW5kaWNpYXRpbmcgd2hldGhlciB0aGUgZmllbGQgbWF5IGJlIG1hdGNoZWQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0TWF5TWF0Y2goRmllbGQgZmllbGQsIEJvb2xlYW4gc3RhdGUpIHsKLSAgICAgICAgZk1heU1hdGNoRmllbGRNYXAucHV0KGZpZWxkLCBzdGF0ZSk7Ci0gICAgfSAvLyBzZXRNYXlNYXRjaChGaWVsZCwgQm9vbGVhbikKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgd2hldGhlciB0aGUgZ2l2ZW4gZmllbGQgaXMgcGVybWl0dGVkIHRvIG1hdGNoIGEgdmFsdWUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZmllbGQgVGhlIGZpZWxkIHRoYXQgbWF5IGJlIHBlcm1pdHRlZCB0byBiZSBtYXRjaGVkLgotICAgICAqIEByZXR1cm4gQm9vbGVhbiBpbmRpY2F0aW5nIHdoZXRoZXIgdGhlIGZpZWxkIG1heSBiZSBtYXRjaGVkLgotICAgICAqLwotICAgIHB1YmxpYyBCb29sZWFuIG1heU1hdGNoKEZpZWxkIGZpZWxkKSB7Ci0gICAgICAgIHJldHVybiAoQm9vbGVhbikgZk1heU1hdGNoRmllbGRNYXAuZ2V0KGZpZWxkKTsKLSAgICB9IC8vIG1heU1hdGNoKEZpZWxkKTpCb29sZWFuCi0KLSAgICAvLyBhIHV0aWxpdHkgbWV0aG9kIGZvciBJZGVudGl0eSBjb25zdHJhaW50cwotICAgIHByaXZhdGUgdm9pZCBhY3RpdmF0ZVNlbGVjdG9yRm9yKElkZW50aXR5Q29uc3RyYWludCBpYykgewotICAgICAgICBTZWxlY3RvciBzZWxlY3RvciA9IGljLmdldFNlbGVjdG9yKCk7Ci0gICAgICAgIEZpZWxkQWN0aXZhdG9yIGFjdGl2YXRvciA9IHRoaXM7Ci0gICAgICAgIGlmIChzZWxlY3RvciA9PSBudWxsKQotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICBYUGF0aE1hdGNoZXIgbWF0Y2hlciA9IHNlbGVjdG9yLmNyZWF0ZU1hdGNoZXIoYWN0aXZhdG9yLCBmRWxlbWVudERlcHRoKTsKLSAgICAgICAgZk1hdGNoZXJTdGFjay5hZGRNYXRjaGVyKG1hdGNoZXIpOwotICAgICAgICBtYXRjaGVyLnN0YXJ0RG9jdW1lbnRGcmFnbWVudCgpOwotICAgIH0KLQotICAgIC8vCi0gICAgLy8gUHJvdGVjdGVkIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqIGVuc3VyZSBlbGVtZW50IHN0YWNrIGNhcGFjaXR5ICovCi0gICAgdm9pZCBlbnN1cmVTdGFja0NhcGFjaXR5KCkgewotCi0gICAgICAgIGlmIChmRWxlbWVudERlcHRoID09IGZFbGVtRGVjbFN0YWNrLmxlbmd0aCkgewotICAgICAgICAgICAgaW50IG5ld1NpemUgPSBmRWxlbWVudERlcHRoICsgSU5DX1NUQUNLX1NJWkU7Ci0gICAgICAgICAgICBib29sZWFuW10gbmV3QXJyYXlCID0gbmV3IGJvb2xlYW5bbmV3U2l6ZV07Ci0gICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGZTdWJFbGVtZW50U3RhY2ssIDAsIG5ld0FycmF5QiwgMCwgZkVsZW1lbnREZXB0aCk7Ci0gICAgICAgICAgICBmU3ViRWxlbWVudFN0YWNrID0gbmV3QXJyYXlCOwotCi0gICAgICAgICAgICBYU0VsZW1lbnREZWNsW10gbmV3QXJyYXlFID0gbmV3IFhTRWxlbWVudERlY2xbbmV3U2l6ZV07Ci0gICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGZFbGVtRGVjbFN0YWNrLCAwLCBuZXdBcnJheUUsIDAsIGZFbGVtZW50RGVwdGgpOwotICAgICAgICAgICAgZkVsZW1EZWNsU3RhY2sgPSBuZXdBcnJheUU7Ci0KLSAgICAgICAgICAgIG5ld0FycmF5QiA9IG5ldyBib29sZWFuW25ld1NpemVdOwotICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShmTmlsU3RhY2ssIDAsIG5ld0FycmF5QiwgMCwgZkVsZW1lbnREZXB0aCk7Ci0gICAgICAgICAgICBmTmlsU3RhY2sgPSBuZXdBcnJheUI7Ci0KLSAgICAgICAgICAgIFhTTm90YXRpb25EZWNsW10gbmV3QXJyYXlOID0gbmV3IFhTTm90YXRpb25EZWNsW25ld1NpemVdOwotICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShmTm90YXRpb25TdGFjaywgMCwgbmV3QXJyYXlOLCAwLCBmRWxlbWVudERlcHRoKTsKLSAgICAgICAgICAgIGZOb3RhdGlvblN0YWNrID0gbmV3QXJyYXlOOwotCi0gICAgICAgICAgICBYU1R5cGVEZWZpbml0aW9uW10gbmV3QXJyYXlUID0gbmV3IFhTVHlwZURlZmluaXRpb25bbmV3U2l6ZV07Ci0gICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGZUeXBlU3RhY2ssIDAsIG5ld0FycmF5VCwgMCwgZkVsZW1lbnREZXB0aCk7Ci0gICAgICAgICAgICBmVHlwZVN0YWNrID0gbmV3QXJyYXlUOwotCi0gICAgICAgICAgICBYU0NNVmFsaWRhdG9yW10gbmV3QXJyYXlDID0gbmV3IFhTQ01WYWxpZGF0b3JbbmV3U2l6ZV07Ci0gICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGZDTVN0YWNrLCAwLCBuZXdBcnJheUMsIDAsIGZFbGVtZW50RGVwdGgpOwotICAgICAgICAgICAgZkNNU3RhY2sgPSBuZXdBcnJheUM7Ci0KLSAgICAgICAgICAgIG5ld0FycmF5QiA9IG5ldyBib29sZWFuW25ld1NpemVdOwotICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShmU2F3VGV4dFN0YWNrLCAwLCBuZXdBcnJheUIsIDAsIGZFbGVtZW50RGVwdGgpOwotICAgICAgICAgICAgZlNhd1RleHRTdGFjayA9IG5ld0FycmF5QjsKLQotICAgICAgICAgICAgbmV3QXJyYXlCID0gbmV3IGJvb2xlYW5bbmV3U2l6ZV07Ci0gICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGZTdHJpbmdDb250ZW50LCAwLCBuZXdBcnJheUIsIDAsIGZFbGVtZW50RGVwdGgpOwotICAgICAgICAgICAgZlN0cmluZ0NvbnRlbnQgPSBuZXdBcnJheUI7Ci0KLSAgICAgICAgICAgIG5ld0FycmF5QiA9IG5ldyBib29sZWFuW25ld1NpemVdOwotICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShmU3RyaWN0QXNzZXNzU3RhY2ssIDAsIG5ld0FycmF5QiwgMCwgZkVsZW1lbnREZXB0aCk7Ci0gICAgICAgICAgICBmU3RyaWN0QXNzZXNzU3RhY2sgPSBuZXdBcnJheUI7Ci0KLSAgICAgICAgICAgIGludFtdW10gbmV3QXJyYXlJQSA9IG5ldyBpbnRbbmV3U2l6ZV1bXTsKLSAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZkNNU3RhdGVTdGFjaywgMCwgbmV3QXJyYXlJQSwgMCwgZkVsZW1lbnREZXB0aCk7Ci0gICAgICAgICAgICBmQ01TdGF0ZVN0YWNrID0gbmV3QXJyYXlJQTsKLSAgICAgICAgfQotCi0gICAgfSAvLyBlbnN1cmVTdGFja0NhcGFjaXR5Ci0KLSAgICAvLyBoYW5kbGUgc3RhcnQgZG9jdW1lbnQKLSAgICB2b2lkIGhhbmRsZVN0YXJ0RG9jdW1lbnQoWE1MTG9jYXRvciBsb2NhdG9yLCBTdHJpbmcgZW5jb2RpbmcpIHsKLSAgICAgICAgZlZhbHVlU3RvcmVDYWNoZS5zdGFydERvY3VtZW50KCk7Ci0gICAgICAgIGlmIChmQXVnUFNWSSkgewotICAgICAgICAgICAgZkN1cnJlbnRQU1ZJLmZHcmFtbWFycyA9IG51bGw7Ci0gICAgICAgICAgICBmQ3VycmVudFBTVkkuZlNjaGVtYUluZm9ybWF0aW9uID0gbnVsbDsKLSAgICAgICAgfQotICAgIH0gLy8gaGFuZGxlU3RhcnREb2N1bWVudChYTUxMb2NhdG9yLFN0cmluZykKLQotICAgIHZvaWQgaGFuZGxlRW5kRG9jdW1lbnQoKSB7Ci0gICAgICAgIGZWYWx1ZVN0b3JlQ2FjaGUuZW5kRG9jdW1lbnQoKTsKLSAgICB9IC8vIGhhbmRsZUVuZERvY3VtZW50KCkKLQotICAgIC8vIGhhbmRsZSBjaGFyYWN0ZXIgY29udGVudHMKLSAgICAvLyByZXR1cm5zIHRoZSBub3JtYWxpemVkIHN0cmluZyBpZiBwb3NzaWJsZSwgb3RoZXJ3aXNlIHRoZSBvcmlnaW5hbCBzdHJpbmcKLSAgICBYTUxTdHJpbmcgaGFuZGxlQ2hhcmFjdGVycyhYTUxTdHJpbmcgdGV4dCkgewotCi0gICAgICAgIGlmIChmU2tpcFZhbGlkYXRpb25EZXB0aCA+PSAwKQotICAgICAgICAgICAgcmV0dXJuIHRleHQ7Ci0KLSAgICAgICAgZlNhd1RleHQgPSBmU2F3VGV4dCB8fCB0ZXh0Lmxlbmd0aCA+IDA7Ci0KLSAgICAgICAgLy8gTm90ZTogZGF0YSBpbiBFbnRpdHlSZWYgYW5kIENEQVRBIGlzIG5vcm1hbGl6ZWQgYXMgd2VsbAotICAgICAgICAvLyBpZiB3aGl0ZXNwYWNlID09IC0xIHNraXAgbm9ybWFsaXphdGlvbiwgYmVjYXVzZSBpdCBpcyBhIGNvbXBsZXhUeXBlCi0gICAgICAgIC8vIG9yIGEgdW5pb24gdHlwZS4KLSAgICAgICAgaWYgKGZOb3JtYWxpemVEYXRhICYmIGZXaGl0ZVNwYWNlICE9IC0xICYmIGZXaGl0ZVNwYWNlICE9IFhTU2ltcGxlVHlwZS5XU19QUkVTRVJWRSkgewotICAgICAgICAgICAgLy8gbm9ybWFsaXplIGRhdGEKLSAgICAgICAgICAgIG5vcm1hbGl6ZVdoaXRlc3BhY2UodGV4dCwgZldoaXRlU3BhY2UgPT0gWFNTaW1wbGVUeXBlLldTX0NPTExBUFNFKTsKLSAgICAgICAgICAgIHRleHQgPSBmTm9ybWFsaXplZFN0cjsKLSAgICAgICAgfQotICAgICAgICBpZiAoZkFwcGVuZEJ1ZmZlcikKLSAgICAgICAgICAgIGZCdWZmZXIuYXBwZW5kKHRleHQuY2gsIHRleHQub2Zmc2V0LCB0ZXh0Lmxlbmd0aCk7Ci0KLSAgICAgICAgLy8gV2hlbiBpdCdzIGEgY29tcGxleCB0eXBlIHdpdGggZWxlbWVudC1vbmx5IGNvbnRlbnQsIHdlIG5lZWQgdG8KLSAgICAgICAgLy8gZmluZCBvdXQgd2hldGhlciB0aGUgY29udGVudCBjb250YWlucyBhbnkgbm9uLXdoaXRlc3BhY2UgY2hhcmFjdGVyLgotICAgICAgICBmU2F3T25seVdoaXRlc3BhY2VJbkVsZW1lbnRDb250ZW50ID0gZmFsc2U7Ci0gICAgICAgIGlmIChmQ3VycmVudFR5cGUgIT0gbnVsbAotICAgICAgICAgICAgJiYgZkN1cnJlbnRUeXBlLmdldFR5cGVDYXRlZ29yeSgpID09IFhTVHlwZURlZmluaXRpb24uQ09NUExFWF9UWVBFKSB7Ci0gICAgICAgICAgICBYU0NvbXBsZXhUeXBlRGVjbCBjdHlwZSA9IChYU0NvbXBsZXhUeXBlRGVjbCkgZkN1cnJlbnRUeXBlOwotICAgICAgICAgICAgaWYgKGN0eXBlLmZDb250ZW50VHlwZSA9PSBYU0NvbXBsZXhUeXBlRGVjbC5DT05URU5UVFlQRV9FTEVNRU5UKSB7Ci0gICAgICAgICAgICAgICAgLy8gZGF0YSBvdXRzaWRlIG9mIGVsZW1lbnQgY29udGVudAotICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSB0ZXh0Lm9mZnNldDsgaSA8IHRleHQub2Zmc2V0ICsgdGV4dC5sZW5ndGg7IGkrKykgewotICAgICAgICAgICAgICAgICAgICBpZiAoIVhNTENoYXIuaXNTcGFjZSh0ZXh0LmNoW2ldKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgZlNhd0NoYXJhY3RlcnMgPSB0cnVlOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZlNhd09ubHlXaGl0ZXNwYWNlSW5FbGVtZW50Q29udGVudCA9ICFmU2F3Q2hhcmFjdGVyczsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gdGV4dDsKLSAgICB9IC8vIGhhbmRsZUNoYXJhY3RlcnMoWE1MU3RyaW5nKQotCi0gICAgLyoqCi0gICAgICogTm9ybWFsaXplIHdoaXRlc3BhY2UgaW4gYW4gWE1MU3RyaW5nIGFjY29yZGluZyB0byB0aGUgcnVsZXMgZGVmaW5lZAotICAgICAqIGluIFhNTCBTY2hlbWEgc3BlY2lmaWNhdGlvbnMuCi0gICAgICogQHBhcmFtIHZhbHVlICAgIFRoZSBzdHJpbmcgdG8gbm9ybWFsaXplLgotICAgICAqIEBwYXJhbSBjb2xsYXBzZSByZXBsYWNlIG9yIGNvbGxhcHNlCi0gICAgICovCi0gICAgcHJpdmF0ZSB2b2lkIG5vcm1hbGl6ZVdoaXRlc3BhY2UoWE1MU3RyaW5nIHZhbHVlLCBib29sZWFuIGNvbGxhcHNlKSB7Ci0gICAgICAgIGJvb2xlYW4gc2tpcFNwYWNlID0gY29sbGFwc2U7Ci0gICAgICAgIGJvb2xlYW4gc2F3Tm9uV1MgPSBmYWxzZTsKLSAgICAgICAgYm9vbGVhbiBsZWFkaW5nID0gZmFsc2U7Ci0gICAgICAgIGJvb2xlYW4gdHJhaWxpbmcgPSBmYWxzZTsKLSAgICAgICAgY2hhciBjOwotICAgICAgICBpbnQgc2l6ZSA9IHZhbHVlLm9mZnNldCArIHZhbHVlLmxlbmd0aDsKLQotICAgICAgICAvLyBlbnN1cmUgdGhlIGNoIGFycmF5IGlzIGJpZyBlbm91Z2gKLSAgICAgICAgaWYgKGZOb3JtYWxpemVkU3RyLmNoID09IG51bGwgfHwgZk5vcm1hbGl6ZWRTdHIuY2gubGVuZ3RoIDwgdmFsdWUubGVuZ3RoICsgMSkgewotICAgICAgICAgICAgZk5vcm1hbGl6ZWRTdHIuY2ggPSBuZXcgY2hhclt2YWx1ZS5sZW5ndGggKyAxXTsKLSAgICAgICAgfQotICAgICAgICAvLyBkb24ndCBpbmNsdWRlIHRoZSBsZWFkaW5nICcgJyBmb3Igbm93LiBtaWdodCBpbmNsdWRlIGl0IGxhdGVyLgotICAgICAgICBmTm9ybWFsaXplZFN0ci5vZmZzZXQgPSAxOwotICAgICAgICBmTm9ybWFsaXplZFN0ci5sZW5ndGggPSAxOwotCi0gICAgICAgIGZvciAoaW50IGkgPSB2YWx1ZS5vZmZzZXQ7IGkgPCBzaXplOyBpKyspIHsKLSAgICAgICAgICAgIGMgPSB2YWx1ZS5jaFtpXTsKLSAgICAgICAgICAgIGlmIChYTUxDaGFyLmlzU3BhY2UoYykpIHsKLSAgICAgICAgICAgICAgICBpZiAoIXNraXBTcGFjZSkgewotICAgICAgICAgICAgICAgICAgICAvLyB0YWtlIHRoZSBmaXJzdCB3aGl0ZXNwYWNlIGFzIGEgc3BhY2UgYW5kIHNraXAgdGhlIG90aGVycwotICAgICAgICAgICAgICAgICAgICBmTm9ybWFsaXplZFN0ci5jaFtmTm9ybWFsaXplZFN0ci5sZW5ndGgrK10gPSAnICc7Ci0gICAgICAgICAgICAgICAgICAgIHNraXBTcGFjZSA9IGNvbGxhcHNlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpZiAoIXNhd05vbldTKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIHRoaXMgaXMgYSBsZWFkaW5nIHdoaXRlc3BhY2UsIHJlY29yZCBpdAotICAgICAgICAgICAgICAgICAgICBsZWFkaW5nID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIGZOb3JtYWxpemVkU3RyLmNoW2ZOb3JtYWxpemVkU3RyLmxlbmd0aCsrXSA9IGM7Ci0gICAgICAgICAgICAgICAgc2tpcFNwYWNlID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgc2F3Tm9uV1MgPSB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGlmIChza2lwU3BhY2UpIHsKLSAgICAgICAgICAgIGlmIChmTm9ybWFsaXplZFN0ci5sZW5ndGggPiAxKSB7Ci0gICAgICAgICAgICAgICAgLy8gaWYgd2UgZmluaXNoZWQgb24gYSBzcGFjZSB0cmltIGl0IGJ1dCBhbHNvIHJlY29yZCBpdAotICAgICAgICAgICAgICAgIGZOb3JtYWxpemVkU3RyLmxlbmd0aC0tOwotICAgICAgICAgICAgICAgIHRyYWlsaW5nID0gdHJ1ZTsKLSAgICAgICAgICAgIH0gZWxzZSBpZiAobGVhZGluZyAmJiAhZkZpcnN0Q2h1bmspIHsKLSAgICAgICAgICAgICAgICAvLyBpZiBhbGwgd2UgaGFkIHdhcyB3aGl0ZXNwYWNlIHdlIHNraXBwZWQgcmVjb3JkIGl0IGFzCi0gICAgICAgICAgICAgICAgLy8gdHJhaWxpbmcgd2hpdGVzcGFjZSBhcyB3ZWxsCi0gICAgICAgICAgICAgICAgdHJhaWxpbmcgPSB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKGZOb3JtYWxpemVkU3RyLmxlbmd0aCA+IDEpIHsKLSAgICAgICAgICAgIGlmICghZkZpcnN0Q2h1bmsgJiYgKGZXaGl0ZVNwYWNlID09IFhTU2ltcGxlVHlwZS5XU19DT0xMQVBTRSkpIHsKLSAgICAgICAgICAgICAgICBpZiAoZlRyYWlsaW5nKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIHByZXZpb3VzIGNodW5rIGVuZGVkIG9uIHdoaXRlc3BhY2UKLSAgICAgICAgICAgICAgICAgICAgLy8gaW5zZXJ0IHdoaXRlc3BhY2UKLSAgICAgICAgICAgICAgICAgICAgZk5vcm1hbGl6ZWRTdHIub2Zmc2V0ID0gMDsKLSAgICAgICAgICAgICAgICAgICAgZk5vcm1hbGl6ZWRTdHIuY2hbMF0gPSAnICc7Ci0gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChsZWFkaW5nKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIHByZXZpb3VzIGNodW5rIGVuZGVkIG9uIGNoYXJhY3RlciwKLSAgICAgICAgICAgICAgICAgICAgLy8gdGhpcyBjaHVuayBzdGFydHMgd2l0aCB3aGl0ZXNwYWNlCi0gICAgICAgICAgICAgICAgICAgIGZOb3JtYWxpemVkU3RyLm9mZnNldCA9IDA7Ci0gICAgICAgICAgICAgICAgICAgIGZOb3JtYWxpemVkU3RyLmNoWzBdID0gJyAnOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIFRoZSBsZW5ndGggaW5jbHVkZXMgdGhlIGxlYWRpbmcgJyAnLiBOb3cgcmVtb3ZpbmcgaXQuCi0gICAgICAgIGZOb3JtYWxpemVkU3RyLmxlbmd0aCAtPSBmTm9ybWFsaXplZFN0ci5vZmZzZXQ7Ci0KLSAgICAgICAgZlRyYWlsaW5nID0gdHJhaWxpbmc7Ci0KLSAgICAgICAgaWYgKHRyYWlsaW5nIHx8IHNhd05vbldTKQotICAgICAgICAgICAgZkZpcnN0Q2h1bmsgPSBmYWxzZTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgbm9ybWFsaXplV2hpdGVzcGFjZShTdHJpbmcgdmFsdWUsIGJvb2xlYW4gY29sbGFwc2UpIHsKLSAgICAgICAgYm9vbGVhbiBza2lwU3BhY2UgPSBjb2xsYXBzZTsKLSAgICAgICAgY2hhciBjOwotICAgICAgICBpbnQgc2l6ZSA9IHZhbHVlLmxlbmd0aCgpOwotCi0gICAgICAgIC8vIGVuc3VyZSB0aGUgY2ggYXJyYXkgaXMgYmlnIGVub3VnaAotICAgICAgICBpZiAoZk5vcm1hbGl6ZWRTdHIuY2ggPT0gbnVsbCB8fCBmTm9ybWFsaXplZFN0ci5jaC5sZW5ndGggPCBzaXplKSB7Ci0gICAgICAgICAgICBmTm9ybWFsaXplZFN0ci5jaCA9IG5ldyBjaGFyW3NpemVdOwotICAgICAgICB9Ci0gICAgICAgIGZOb3JtYWxpemVkU3RyLm9mZnNldCA9IDA7Ci0gICAgICAgIGZOb3JtYWxpemVkU3RyLmxlbmd0aCA9IDA7Ci0KLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKLSAgICAgICAgICAgIGMgPSB2YWx1ZS5jaGFyQXQoaSk7Ci0gICAgICAgICAgICBpZiAoWE1MQ2hhci5pc1NwYWNlKGMpKSB7Ci0gICAgICAgICAgICAgICAgaWYgKCFza2lwU3BhY2UpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gdGFrZSB0aGUgZmlyc3Qgd2hpdGVzcGFjZSBhcyBhIHNwYWNlIGFuZCBza2lwIHRoZSBvdGhlcnMKLSAgICAgICAgICAgICAgICAgICAgZk5vcm1hbGl6ZWRTdHIuY2hbZk5vcm1hbGl6ZWRTdHIubGVuZ3RoKytdID0gJyAnOwotICAgICAgICAgICAgICAgICAgICBza2lwU3BhY2UgPSBjb2xsYXBzZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIGZOb3JtYWxpemVkU3RyLmNoW2ZOb3JtYWxpemVkU3RyLmxlbmd0aCsrXSA9IGM7Ci0gICAgICAgICAgICAgICAgc2tpcFNwYWNlID0gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKHNraXBTcGFjZSkgewotICAgICAgICAgICAgaWYgKGZOb3JtYWxpemVkU3RyLmxlbmd0aCAhPSAwKQotICAgICAgICAgICAgICAgIC8vIGlmIHdlIGZpbmlzaGVkIG9uIGEgc3BhY2UgdHJpbSBpdCBidXQgYWxzbyByZWNvcmQgaXQKLSAgICAgICAgICAgICAgICBmTm9ybWFsaXplZFN0ci5sZW5ndGgtLTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8vIGhhbmRsZSBpZ25vcmFibGUgd2hpdGVzcGFjZQotICAgIHZvaWQgaGFuZGxlSWdub3JhYmxlV2hpdGVzcGFjZShYTUxTdHJpbmcgdGV4dCkgewotCi0gICAgICAgIGlmIChmU2tpcFZhbGlkYXRpb25EZXB0aCA+PSAwKQotICAgICAgICAgICAgcmV0dXJuOwotCi0gICAgICAgIC8vIFJFVklTSVQ6IHRoZSBzYW1lIHByb2Nlc3MgbmVlZHMgdG8gYmUgcGVyZm9ybWVkIGFzIGhhbmRsZUNoYXJhY3RlcnMuCi0gICAgICAgIC8vIG9ubHkgaXQncyBzaW1wbGVyIGhlcmU6IHdlIGtub3cgYWxsIGNoYXJhY3RlcnMgYXJlIHdoaXRlc3BhY2VzLgotCi0gICAgfSAvLyBoYW5kbGVJZ25vcmFibGVXaGl0ZXNwYWNlKFhNTFN0cmluZykKLQotICAgIC8qKiBIYW5kbGUgZWxlbWVudC4gKi8KLSAgICBBdWdtZW50YXRpb25zIGhhbmRsZVN0YXJ0RWxlbWVudChRTmFtZSBlbGVtZW50LCBYTUxBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMsIEF1Z21lbnRhdGlvbnMgYXVncykgewotCi0gICAgICAgIGlmIChERUJVRykgewotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCI9PT5oYW5kbGVTdGFydEVsZW1lbnQ6ICIgKyBlbGVtZW50KTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIHJvb3QgZWxlbWVudAotICAgICAgICBpZiAoZkVsZW1lbnREZXB0aCA9PSAtMSAmJiBmVmFsaWRhdGlvbk1hbmFnZXIuaXNHcmFtbWFyRm91bmQoKSkgewotICAgICAgICAgICAgaWYgKGZTY2hlbWFUeXBlID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAvLyBzY2hlbWFUeXBlIGlzIG5vdCBzcGVjaWZpZWQKLSAgICAgICAgICAgICAgICAvLyBpZiBhIERURCBncmFtbWFyIGlzIGZvdW5kLCB3ZSBkbyB0aGUgc2FtZSB0aGluZyBhcyBEeW5hbWljOgotICAgICAgICAgICAgICAgIC8vIGlmIGEgc2NoZW1hIGdyYW1tYXIgaXMgZm91bmQsIHZhbGlkYXRpb24gaXMgcGVyZm9ybWVkOwotICAgICAgICAgICAgICAgIC8vIG90aGVyd2lzZSwgc2tpcCB0aGUgd2hvbGUgZG9jdW1lbnQuCi0gICAgICAgICAgICAgICAgZlNjaGVtYUR5bmFtaWNWYWxpZGF0aW9uID0gdHJ1ZTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgLy8gWzFdIEVpdGhlciBzY2hlbWFUeXBlIGlzIERURCwgYW5kIGluIHRoaXMgY2FzZSB2YWxpZGF0ZS9zY2hlbWEgaXMgdHVybmVkIG9mZgotICAgICAgICAgICAgICAgIC8vIFsyXSBWYWxpZGF0aW5nIGFnYWluc3QgWE1MIFNjaGVtYXMgb25seQotICAgICAgICAgICAgICAgIC8vICAgW2FdIGR5bmFtaWMgdmFsaWRhdGlvbiBpcyBmYWxzZTogcmVwb3J0IGVycm9yIGlmIFNjaGVtYUdyYW1tYXIgaXMgbm90IGZvdW5kCi0gICAgICAgICAgICAgICAgLy8gICBbYl0gZHluYW1pYyB2YWxpZGF0aW9uIGlzIHRydWU6IGlmIGdyYW1tYXIgaXMgbm90IGZvdW5kIGlnbm9yZS4KLSAgICAgICAgICAgIH0KLQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gZ2V0IHhzaTpzY2hlbWFMb2NhdGlvbiBhbmQgeHNpOm5vTmFtZXNwYWNlU2NoZW1hTG9jYXRpb24gYXR0cmlidXRlcywKLSAgICAgICAgLy8gcGFyc2UgdGhlbSB0byBnZXQgdGhlIGdyYW1tYXJzCi0KLSAgICAgICAgU3RyaW5nIHNMb2NhdGlvbiA9Ci0gICAgICAgICAgICBhdHRyaWJ1dGVzLmdldFZhbHVlKFNjaGVtYVN5bWJvbHMuVVJJX1hTSSwgU2NoZW1hU3ltYm9scy5YU0lfU0NIRU1BTE9DQVRJT04pOwotICAgICAgICBTdHJpbmcgbnNMb2NhdGlvbiA9Ci0gICAgICAgICAgICBhdHRyaWJ1dGVzLmdldFZhbHVlKFNjaGVtYVN5bWJvbHMuVVJJX1hTSSwgU2NoZW1hU3ltYm9scy5YU0lfTk9OQU1FU1BBQ0VTQ0hFTUFMT0NBVElPTik7Ci0gICAgICAgIC8vc3RvcmUgdGhlIGxvY2F0aW9uIGhpbnRzLi4gIHdlIG5lZWQgdG8gZG8gaXQgc28gdGhhdCB3ZSBjYW4gZGVmZXIgdGhlIGxvYWRpbmcgb2YgZ3JhbW1hciB1bnRpbAotICAgICAgICAvL3RoZXJlIGlzIGEgcmVmZXJlbmNlIHRvIGEgY29tcG9uZW50IGZyb20gdGhhdCBuYW1lc3BhY2UuIFRvIHByb3ZpZGUgbG9jYXRpb24gaGludHMgdG8gdGhlCi0gICAgICAgIC8vYXBwbGljYXRpb24gZm9yIGEgbmFtZXNwYWNlCi0gICAgICAgIHN0b3JlTG9jYXRpb25zKHNMb2NhdGlvbiwgbnNMb2NhdGlvbik7Ci0KLSAgICAgICAgLy8gaWYgd2UgYXJlIGluIHRoZSBjb250ZW50IG9mICJza2lwIiwgdGhlbiBqdXN0IHNraXAgdGhpcyBlbGVtZW50Ci0gICAgICAgIC8vIFJFVklTSVQ6ICBpcyB0aGlzIHRoZSBjb3JyZWN0IGJlaGF2aW91ciBmb3IgSUQgY29uc3RyYWludHM/ICAtTkcKLSAgICAgICAgaWYgKGZTa2lwVmFsaWRhdGlvbkRlcHRoID49IDApIHsKLSAgICAgICAgICAgIGZFbGVtZW50RGVwdGgrKzsKLSAgICAgICAgICAgIGlmIChmQXVnUFNWSSkKLSAgICAgICAgICAgICAgICBhdWdzID0gZ2V0RW1wdHlBdWdzKGF1Z3MpOwotICAgICAgICAgICAgcmV0dXJuIGF1Z3M7Ci0gICAgICAgIH0KLQotICAgICAgICAvL3RyeSB0byBmaW5kIHNjaGVtYSBncmFtbWFyIGJ5IGRpZmZlcmVudCBtZWFucy4uCi0gICAgICAgIFNjaGVtYUdyYW1tYXIgc0dyYW1tYXIgPQotICAgICAgICAgICAgZmluZFNjaGVtYUdyYW1tYXIoCi0gICAgICAgICAgICAgICAgWFNERGVzY3JpcHRpb24uQ09OVEVYVF9FTEVNRU5ULAotICAgICAgICAgICAgICAgIGVsZW1lbnQudXJpLAotICAgICAgICAgICAgICAgIG51bGwsCi0gICAgICAgICAgICAgICAgZWxlbWVudCwKLSAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzKTsKLQotICAgICAgICAvLyBpZiB3ZSBhcmUgbm90IHNraXBwaW5nIHRoaXMgZWxlbWVudCwgYW5kIHRoZXJlIGlzIGEgY29udGVudCBtb2RlbCwKLSAgICAgICAgLy8gd2UgdHJ5IHRvIGZpbmQgdGhlIGNvcnJlc3BvbmRpbmcgZGVjbCBvYmplY3QgZm9yIHRoaXMgZWxlbWVudC4KLSAgICAgICAgLy8gdGhlIHJlYXNvbiB3ZSBtb3ZlIHRoaXMgcGFydCBvZiBjb2RlIGhlcmUgaXMgdG8gbWFrZSBzdXJlIHRoZQotICAgICAgICAvLyBlcnJvciByZXBvcnRlZCBoZXJlIChpZiBhbnkpIGlzIHN0b3JlZCB3aXRoaW4gdGhlIHBhcmVudCBlbGVtZW50J3MKLSAgICAgICAgLy8gY29udGV4dCwgaW5zdGVhZCBvZiB0aGF0IG9mIHRoZSBjdXJyZW50IGVsZW1lbnQuCi0gICAgICAgIE9iamVjdCBkZWNsID0gbnVsbDsKLSAgICAgICAgaWYgKGZDdXJyZW50Q00gIT0gbnVsbCkgewotICAgICAgICAgICAgZGVjbCA9IGZDdXJyZW50Q00ub25lVHJhbnNpdGlvbihlbGVtZW50LCBmQ3VyckNNU3RhdGUsIGZTdWJHcm91cEhhbmRsZXIpOwotICAgICAgICAgICAgLy8gaXQgY291bGQgYmUgYW4gZWxlbWVudCBkZWNsIG9yIGEgd2lsZGNhcmQgZGVjbAotICAgICAgICAgICAgaWYgKGZDdXJyQ01TdGF0ZVswXSA9PSBYU0NNVmFsaWRhdG9yLkZJUlNUX0VSUk9SKSB7Ci0gICAgICAgICAgICAgICAgWFNDb21wbGV4VHlwZURlY2wgY3R5cGUgPSAoWFNDb21wbGV4VHlwZURlY2wpIGZDdXJyZW50VHlwZTsKLSAgICAgICAgICAgICAgICAvL1JFVklTSVQ6IGlzIGl0IHRoZSBvbmx5IGNhc2Ugd2Ugd2lsbCBoYXZlIHBhcnRpY2xlID0gbnVsbD8KLSAgICAgICAgICAgICAgICBWZWN0b3IgbmV4dDsKLSAgICAgICAgICAgICAgICBpZiAoY3R5cGUuZlBhcnRpY2xlICE9IG51bGwKLSAgICAgICAgICAgICAgICAgICAgJiYgKG5leHQgPSBmQ3VycmVudENNLndoYXRDYW5Hb0hlcmUoZkN1cnJDTVN0YXRlKSkuc2l6ZSgpID4gMCkgewotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgZXhwZWN0ZWQgPSBleHBlY3RlZFN0cihuZXh0KTsKLSAgICAgICAgICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoCi0gICAgICAgICAgICAgICAgICAgICAgICAiY3ZjLWNvbXBsZXgtdHlwZS4yLjQuYSIsCi0gICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBlbGVtZW50LnJhd25hbWUsIGV4cGVjdGVkIH0pOwotICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKCJjdmMtY29tcGxleC10eXBlLjIuNC5kIiwgbmV3IE9iamVjdFtdIHsgZWxlbWVudC5yYXduYW1lIH0pOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIGlmIGl0J3Mgbm90IHRoZSByb290IGVsZW1lbnQsIHdlIHB1c2ggdGhlIGN1cnJlbnQgc3RhdGVzIGluIHRoZSBzdGFja3MKLSAgICAgICAgaWYgKGZFbGVtZW50RGVwdGggIT0gLTEpIHsKLSAgICAgICAgICAgIGVuc3VyZVN0YWNrQ2FwYWNpdHkoKTsKLSAgICAgICAgICAgIGZTdWJFbGVtZW50U3RhY2tbZkVsZW1lbnREZXB0aF0gPSB0cnVlOwotICAgICAgICAgICAgZlN1YkVsZW1lbnQgPSBmYWxzZTsKLSAgICAgICAgICAgIGZFbGVtRGVjbFN0YWNrW2ZFbGVtZW50RGVwdGhdID0gZkN1cnJlbnRFbGVtRGVjbDsKLSAgICAgICAgICAgIGZOaWxTdGFja1tmRWxlbWVudERlcHRoXSA9IGZOaWw7Ci0gICAgICAgICAgICBmTm90YXRpb25TdGFja1tmRWxlbWVudERlcHRoXSA9IGZOb3RhdGlvbjsKLSAgICAgICAgICAgIGZUeXBlU3RhY2tbZkVsZW1lbnREZXB0aF0gPSBmQ3VycmVudFR5cGU7Ci0gICAgICAgICAgICBmU3RyaWN0QXNzZXNzU3RhY2tbZkVsZW1lbnREZXB0aF0gPSBmU3RyaWN0QXNzZXNzOwotICAgICAgICAgICAgZkNNU3RhY2tbZkVsZW1lbnREZXB0aF0gPSBmQ3VycmVudENNOwotICAgICAgICAgICAgZkNNU3RhdGVTdGFja1tmRWxlbWVudERlcHRoXSA9IGZDdXJyQ01TdGF0ZTsKLSAgICAgICAgICAgIGZTYXdUZXh0U3RhY2tbZkVsZW1lbnREZXB0aF0gPSBmU2F3VGV4dDsKLSAgICAgICAgICAgIGZTdHJpbmdDb250ZW50W2ZFbGVtZW50RGVwdGhdID0gZlNhd0NoYXJhY3RlcnM7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBpbmNyZWFzZSB0aGUgZWxlbWVudCBkZXB0aCBhZnRlciB3ZSd2ZSBzYXZlZAotICAgICAgICAvLyBhbGwgc3RhdGVzIGZvciB0aGUgcGFyZW50IGVsZW1lbnQKLSAgICAgICAgZkVsZW1lbnREZXB0aCsrOwotICAgICAgICBmQ3VycmVudEVsZW1EZWNsID0gbnVsbDsKLSAgICAgICAgWFNXaWxkY2FyZERlY2wgd2lsZGNhcmQgPSBudWxsOwotICAgICAgICBmQ3VycmVudFR5cGUgPSBudWxsOwotICAgICAgICBmU3RyaWN0QXNzZXNzID0gdHJ1ZTsKLSAgICAgICAgZk5pbCA9IGZhbHNlOwotICAgICAgICBmTm90YXRpb24gPSBudWxsOwotCi0gICAgICAgIC8vIGFuZCB0aGUgYnVmZmVyIHRvIGhvbGQgdGhlIHZhbHVlIG9mIHRoZSBlbGVtZW50Ci0gICAgICAgIGZCdWZmZXIuc2V0TGVuZ3RoKDApOwotICAgICAgICBmU2F3VGV4dCA9IGZhbHNlOwotICAgICAgICBmU2F3Q2hhcmFjdGVycyA9IGZhbHNlOwotCi0gICAgICAgIC8vIGNoZWNrIHdoYXQga2luZCBvZiBkZWNsYXJhdGlvbiB0aGUgImRlY2wiIGZyb20KLSAgICAgICAgLy8gb25lVHJhbnNpdGlvbigpIG1hcHMgdG8KLSAgICAgICAgaWYgKGRlY2wgIT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKGRlY2wgaW5zdGFuY2VvZiBYU0VsZW1lbnREZWNsKSB7Ci0gICAgICAgICAgICAgICAgZkN1cnJlbnRFbGVtRGVjbCA9IChYU0VsZW1lbnREZWNsKSBkZWNsOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICB3aWxkY2FyZCA9IChYU1dpbGRjYXJkRGVjbCkgZGVjbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIGlmIHRoZSB3aWxkY2FyZCBpcyBza2lwLCB0aGVuIHJldHVybgotICAgICAgICBpZiAod2lsZGNhcmQgIT0gbnVsbCAmJiB3aWxkY2FyZC5mUHJvY2Vzc0NvbnRlbnRzID09IFhTV2lsZGNhcmREZWNsLlBDX1NLSVApIHsKLSAgICAgICAgICAgIGZTa2lwVmFsaWRhdGlvbkRlcHRoID0gZkVsZW1lbnREZXB0aDsKLSAgICAgICAgICAgIGlmIChmQXVnUFNWSSkKLSAgICAgICAgICAgICAgICBhdWdzID0gZ2V0RW1wdHlBdWdzKGF1Z3MpOwotICAgICAgICAgICAgcmV0dXJuIGF1Z3M7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyB0cnkgYWdhaW4gdG8gZ2V0IHRoZSBlbGVtZW50IGRlY2w6Ci0gICAgICAgIC8vIGNhc2UgMTogZmluZCBkZWNsYXJhdGlvbiBmb3Igcm9vdCBlbGVtZW50Ci0gICAgICAgIC8vIGNhc2UgMjogZmluZCBkZWNsYXJhdGlvbiBmb3IgZWxlbWVudCBmcm9tIGFub3RoZXIgbmFtZXNwYWNlCi0gICAgICAgIGlmIChmQ3VycmVudEVsZW1EZWNsID09IG51bGwpIHsKLSAgICAgICAgICAgIGlmIChzR3JhbW1hciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZkN1cnJlbnRFbGVtRGVjbCA9IHNHcmFtbWFyLmdldEdsb2JhbEVsZW1lbnREZWNsKGVsZW1lbnQubG9jYWxwYXJ0KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGlmIChmQ3VycmVudEVsZW1EZWNsICE9IG51bGwpIHsKLSAgICAgICAgICAgIC8vIHRoZW4gZ2V0IHRoZSB0eXBlCi0gICAgICAgICAgICBmQ3VycmVudFR5cGUgPSBmQ3VycmVudEVsZW1EZWNsLmZUeXBlOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gZ2V0IHR5cGUgZnJvbSB4c2k6dHlwZQotICAgICAgICBTdHJpbmcgeHNpVHlwZSA9IGF0dHJpYnV0ZXMuZ2V0VmFsdWUoU2NoZW1hU3ltYm9scy5VUklfWFNJLCBTY2hlbWFTeW1ib2xzLlhTSV9UWVBFKTsKLQotICAgICAgICAvLyBpZiBubyBkZWNsL3R5cGUgZm91bmQgZm9yIHRoZSBjdXJyZW50IGVsZW1lbnQKLSAgICAgICAgaWYgKGZDdXJyZW50VHlwZSA9PSBudWxsICYmIHhzaVR5cGUgPT0gbnVsbCkgewotICAgICAgICAgICAgLy8gaWYgdGhpcyBpcyB0aGUgdmFsaWRhdGlvbiByb290LCByZXBvcnQgYW4gZXJyb3IsIGJlY2F1c2UKLSAgICAgICAgICAgIC8vIHdlIGNhbid0IGZpbmQgZWl0aCBkZWNsIG9yIHR5cGUgZm9yIHRoaXMgZWxlbWVudAotICAgICAgICAgICAgLy8gUkVWSVNJVDogc2hvdWxkIHdlIHJlcG9ydCBlcnJvciwgb3Igd2FybmluZz8KLSAgICAgICAgICAgIGlmIChmRWxlbWVudERlcHRoID09IDApIHsKLSAgICAgICAgICAgICAgICAvLyBmb3IgZHluYW1pYyB2YWxpZGF0aW9uLCBza2lwIHRoZSB3aG9sZSBjb250ZW50LAotICAgICAgICAgICAgICAgIC8vIGJlY2F1c2Ugbm8gZ3JhbW1hciB3YXMgZm91bmQuCi0gICAgICAgICAgICAgICAgaWYgKGZEeW5hbWljVmFsaWRhdGlvbiB8fCBmU2NoZW1hRHluYW1pY1ZhbGlkYXRpb24pIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gbm8gc2NoZW1hIGdyYW1tYXIgd2FzIGZvdW5kLCBidXQgaXQncyBlaXRoZXIgZHluYW1pYwotICAgICAgICAgICAgICAgICAgICAvLyB2YWxpZGF0aW9uLCBvciBhbm90aGVyIGtpbmQgb2YgZ3JhbW1hciB3YXMgZm91bmQgKERURCwKLSAgICAgICAgICAgICAgICAgICAgLy8gZm9yIGV4YW1wbGUpLiBUaGUgaW50ZW5kZWQgYmVoYXZpb3IgaGVyZSBpcyB0byBza2lwCi0gICAgICAgICAgICAgICAgICAgIC8vIHRoZSB3aG9sZSBkb2N1bWVudC4gVG8gaW1wcm92ZSBwZXJmb3JtYW5jZSwgd2UgdHJ5IHRvCi0gICAgICAgICAgICAgICAgICAgIC8vIHJlbW92ZSB0aGUgdmFsaWRhdG9yIGZyb20gdGhlIHBpcGVsaW5lLCBzaW5jZSBpdCdzIG5vdAotICAgICAgICAgICAgICAgICAgICAvLyBzdXBwb3NlZCB0byBkbyBhbnl0aGluZy4KLSAgICAgICAgICAgICAgICAgICAgaWYgKGZEb2N1bWVudFNvdXJjZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmRG9jdW1lbnRTb3VyY2Uuc2V0RG9jdW1lbnRIYW5kbGVyKGZEb2N1bWVudEhhbmRsZXIpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZEb2N1bWVudEhhbmRsZXIgIT0gbnVsbCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLnNldERvY3VtZW50U291cmNlKGZEb2N1bWVudFNvdXJjZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBpbmRpY2F0ZSB0aGF0IHRoZSB2YWxpZGF0b3Igd2FzIHJlbW92ZWQuCi0gICAgICAgICAgICAgICAgICAgICAgICBmRWxlbWVudERlcHRoID0gLTI7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYXVnczsKLSAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgIGZTa2lwVmFsaWRhdGlvbkRlcHRoID0gZkVsZW1lbnREZXB0aDsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGZBdWdQU1ZJKQotICAgICAgICAgICAgICAgICAgICAgICAgYXVncyA9IGdldEVtcHR5QXVncyhhdWdzKTsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGF1Z3M7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIC8vIFdlIGRvbid0IGNhbGwgcmVwb3J0U2NoZW1hRXJyb3IgaGVyZSwgYmVjYXVzZSB0aGUgc3BlYwotICAgICAgICAgICAgICAgIC8vIGRvZXNuJ3QgdGhpbmsgaXQncyBpbnZhbGlkIG5vdCB0byBiZSBhYmxlIHRvIGZpbmQgYQotICAgICAgICAgICAgICAgIC8vIGRlY2xhcmF0aW9uIG9yIHR5cGUgZGVmaW5pdGlvbiBmb3IgYW4gZWxlbWVudC4gWGVyY2VzIGlzCi0gICAgICAgICAgICAgICAgLy8gcmVwb3J0aW5nIGl0IGFzIGFuIGVycm9yIGZvciBoaXN0b3JpY2FsIHJlYXNvbnMsIGJ1dCBpbgotICAgICAgICAgICAgICAgIC8vIFBTVkksIHdlIHNob3VsZG4ndCBtYXJrIHRoaXMgZWxlbWVudCBhcyBpbnZhbGlkIGJlY2F1c2UKLSAgICAgICAgICAgICAgICAvLyBvZiB0aGlzLiAtIFNHCi0gICAgICAgICAgICAgICAgZlhTSUVycm9yUmVwb3J0ZXIuZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IoCi0gICAgICAgICAgICAgICAgICAgIFhTTWVzc2FnZUZvcm1hdHRlci5TQ0hFTUFfRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAiY3ZjLWVsdC4xIiwKLSAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgZWxlbWVudC5yYXduYW1lIH0sCi0gICAgICAgICAgICAgICAgICAgIFhNTEVycm9yUmVwb3J0ZXIuU0VWRVJJVFlfRVJST1IpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gaWYgd2lsZGNhcmQgPSBzdHJpY3QsIHJlcG9ydCBlcnJvci4KLSAgICAgICAgICAgIC8vIG5lZWRzIHRvIGJlIGNhbGxlZCBiZWZvcmUgZlhTSUVycm9yUmVwb3J0ZXIucHVzaENvbnRleHQoKQotICAgICAgICAgICAgLy8gc28gdGhhdCB0aGUgZXJyb3IgYmVsb25ncyB0byB0aGUgcGFyZW50IGVsZW1lbnQuCi0gICAgICAgICAgICBlbHNlIGlmICh3aWxkY2FyZCAhPSBudWxsICYmIHdpbGRjYXJkLmZQcm9jZXNzQ29udGVudHMgPT0gWFNXaWxkY2FyZERlY2wuUENfU1RSSUNUKSB7Ci0gICAgICAgICAgICAgICAgLy8gcmVwb3J0IGVycm9yLCBiZWNhdXNlIHdpbGNhcmQgPSBzdHJpY3QKLSAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcigiY3ZjLWNvbXBsZXgtdHlwZS4yLjQuYyIsIG5ldyBPYmplY3RbXSB7IGVsZW1lbnQucmF3bmFtZSB9KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIG5vIGVsZW1lbnQgZGVjbCBvciB0eXBlIGZvdW5kIGZvciB0aGlzIGVsZW1lbnQuCi0gICAgICAgICAgICAvLyBBbGxvd2VkIGJ5IHRoZSBzcGVjLCB3ZSBjYW4gY2hvb3NlIHRvIGVpdGhlciBsYXhseSBhc3Nlc3MgdGhpcwotICAgICAgICAgICAgLy8gZWxlbWVudCwgb3IgdG8gc2tpcCBpdC4gTm93IHdlIGNob29zZSBsYXggYXNzZXNzbWVudC4KLSAgICAgICAgICAgIGZDdXJyZW50VHlwZSA9IFNjaGVtYUdyYW1tYXIuZkFueVR5cGU7Ci0gICAgICAgICAgICBmU3RyaWN0QXNzZXNzID0gZmFsc2U7Ci0gICAgICAgICAgICBmTkZ1bGxWYWxpZGF0aW9uRGVwdGggPSBmRWxlbWVudERlcHRoOwotICAgICAgICAgICAgLy8gYW55IHR5cGUgaGFzIG1peGVkIGNvbnRlbnQsIHNvIHdlIGRvbid0IG5lZWQgdG8gYXBwZW5kIGJ1ZmZlcgotICAgICAgICAgICAgZkFwcGVuZEJ1ZmZlciA9IGZhbHNlOwotCi0gICAgICAgICAgICAvLyBwdXNoIGVycm9yIHJlcG9ydGVyIGNvbnRleHQ6IHJlY29yZCB0aGUgY3VycmVudCBwb3NpdGlvbgotICAgICAgICAgICAgLy8gVGhpcyBoYXMgdG8gaGFwcGVuIGFmdGVyIHdlIHByb2Nlc3Mgc2tpcCBjb250ZW50cywKLSAgICAgICAgICAgIC8vIG90aGVyd2lzZSBwdXNoIGFuZCBwb3Agd29uJ3QgYmUgY29ycmVjdGx5IHBhaXJlZC4KLSAgICAgICAgICAgIGZYU0lFcnJvclJlcG9ydGVyLnB1c2hDb250ZXh0KCk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAvLyBwdXNoIGVycm9yIHJlcG9ydGVyIGNvbnRleHQ6IHJlY29yZCB0aGUgY3VycmVudCBwb3NpdGlvbgotICAgICAgICAgICAgLy8gVGhpcyBoYXMgdG8gaGFwcGVuIGFmdGVyIHdlIHByb2Nlc3Mgc2tpcCBjb250ZW50cywKLSAgICAgICAgICAgIC8vIG90aGVyd2lzZSBwdXNoIGFuZCBwb3Agd29uJ3QgYmUgY29ycmVjdGx5IHBhaXJlZC4KLSAgICAgICAgICAgIGZYU0lFcnJvclJlcG9ydGVyLnB1c2hDb250ZXh0KCk7Ci0KLSAgICAgICAgICAgIC8vIGdldCB4c2k6dHlwZQotICAgICAgICAgICAgaWYgKHhzaVR5cGUgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIFhTVHlwZURlZmluaXRpb24gb2xkVHlwZSA9IGZDdXJyZW50VHlwZTsKLSAgICAgICAgICAgICAgICBmQ3VycmVudFR5cGUgPSBnZXRBbmRDaGVja1hzaVR5cGUoZWxlbWVudCwgeHNpVHlwZSwgYXR0cmlidXRlcyk7Ci0gICAgICAgICAgICAgICAgLy8gSWYgaXQgZmFpbHMsIHVzZSB0aGUgb2xkIHR5cGUuIFVzZSBhbnlUeXBlIGlmIHRoZXIgaXMgbm8gb2xkIHR5cGUuCi0gICAgICAgICAgICAgICAgaWYgKGZDdXJyZW50VHlwZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChvbGRUeXBlID09IG51bGwpCi0gICAgICAgICAgICAgICAgICAgICAgICBmQ3VycmVudFR5cGUgPSBTY2hlbWFHcmFtbWFyLmZBbnlUeXBlOwotICAgICAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgICAgICBmQ3VycmVudFR5cGUgPSBvbGRUeXBlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgZk5Ob25lVmFsaWRhdGlvbkRlcHRoID0gZkVsZW1lbnREZXB0aDsKLSAgICAgICAgICAgIC8vIGlmIHRoZSBlbGVtZW50IGhhcyBhIGZpeGVkIHZhbHVlIGNvbnN0cmFpbnQsIHdlIG5lZWQgdG8gYXBwZW5kCi0gICAgICAgICAgICBpZiAoZkN1cnJlbnRFbGVtRGVjbCAhPSBudWxsCi0gICAgICAgICAgICAgICAgJiYgZkN1cnJlbnRFbGVtRGVjbC5nZXRDb25zdHJhaW50VHlwZSgpID09IFhTQ29uc3RhbnRzLlZDX0ZJWEVEKSB7Ci0gICAgICAgICAgICAgICAgZkFwcGVuZEJ1ZmZlciA9IHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyBpZiB0aGUgdHlwZSBpcyBzaW1wbGUsIHdlIG5lZWQgdG8gYXBwZW5kCi0gICAgICAgICAgICBlbHNlIGlmIChmQ3VycmVudFR5cGUuZ2V0VHlwZUNhdGVnb3J5KCkgPT0gWFNUeXBlRGVmaW5pdGlvbi5TSU1QTEVfVFlQRSkgewotICAgICAgICAgICAgICAgIGZBcHBlbmRCdWZmZXIgPSB0cnVlOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAvLyBpZiB0aGUgdHlwZSBpcyBzaW1wbGUgY29udGVudCBjb21wbGV4IHR5cGUsIHdlIG5lZWQgdG8gYXBwZW5kCi0gICAgICAgICAgICAgICAgWFNDb21wbGV4VHlwZURlY2wgY3R5cGUgPSAoWFNDb21wbGV4VHlwZURlY2wpIGZDdXJyZW50VHlwZTsKLSAgICAgICAgICAgICAgICBmQXBwZW5kQnVmZmVyID0gKGN0eXBlLmZDb250ZW50VHlwZSA9PSBYU0NvbXBsZXhUeXBlRGVjbC5DT05URU5UVFlQRV9TSU1QTEUpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gRWxlbWVudCBMb2NhbGx5IFZhbGlkIChFbGVtZW50KQotICAgICAgICAvLyAyIEl0cyB7YWJzdHJhY3R9IG11c3QgYmUgZmFsc2UuCi0gICAgICAgIGlmIChmQ3VycmVudEVsZW1EZWNsICE9IG51bGwgJiYgZkN1cnJlbnRFbGVtRGVjbC5nZXRBYnN0cmFjdCgpKQotICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoImN2Yy1lbHQuMiIsIG5ldyBPYmplY3RbXSB7IGVsZW1lbnQucmF3bmFtZSB9KTsKLQotICAgICAgICAvLyBtYWtlIHRoZSBjdXJyZW50IGVsZW1lbnQgdmFsaWRhdGlvbiByb290Ci0gICAgICAgIGlmIChmRWxlbWVudERlcHRoID09IDApIHsKLSAgICAgICAgICAgIGZWYWxpZGF0aW9uUm9vdCA9IGVsZW1lbnQucmF3bmFtZTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIHVwZGF0ZSBub3JtYWxpemF0aW9uIGZsYWdzCi0gICAgICAgIGlmIChmTm9ybWFsaXplRGF0YSkgewotICAgICAgICAgICAgLy8gcmVzZXQgdmFsdWVzCi0gICAgICAgICAgICBmRmlyc3RDaHVuayA9IHRydWU7Ci0gICAgICAgICAgICBmVHJhaWxpbmcgPSBmYWxzZTsKLSAgICAgICAgICAgIGZVbmlvblR5cGUgPSBmYWxzZTsKLSAgICAgICAgICAgIGZXaGl0ZVNwYWNlID0gLTE7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBFbGVtZW50IExvY2FsbHkgVmFsaWQgKFR5cGUpCi0gICAgICAgIC8vIDIgSXRzIHthYnN0cmFjdH0gbXVzdCBiZSBmYWxzZS4KLSAgICAgICAgaWYgKGZDdXJyZW50VHlwZS5nZXRUeXBlQ2F0ZWdvcnkoKSA9PSBYU1R5cGVEZWZpbml0aW9uLkNPTVBMRVhfVFlQRSkgewotICAgICAgICAgICAgWFNDb21wbGV4VHlwZURlY2wgY3R5cGUgPSAoWFNDb21wbGV4VHlwZURlY2wpIGZDdXJyZW50VHlwZTsKLSAgICAgICAgICAgIGlmIChjdHlwZS5nZXRBYnN0cmFjdCgpKSB7Ci0gICAgICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoImN2Yy10eXBlLjIiLCBuZXcgT2JqZWN0W10geyBlbGVtZW50LnJhd25hbWUgfSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoZk5vcm1hbGl6ZURhdGEpIHsKLSAgICAgICAgICAgICAgICAvLyBmaW5kIG91dCBpZiB0aGUgY29udGVudCB0eXBlIGlzIHNpbXBsZSBhbmQgaWYgdmFyaWV0eSBpcyB1bmlvbgotICAgICAgICAgICAgICAgIC8vIHRvIGJlIGFibGUgdG8gZG8gY2hhcmFjdGVyIG5vcm1hbGl6YXRpb24KLSAgICAgICAgICAgICAgICBpZiAoY3R5cGUuZkNvbnRlbnRUeXBlID09IFhTQ29tcGxleFR5cGVEZWNsLkNPTlRFTlRUWVBFX1NJTVBMRSkgewotICAgICAgICAgICAgICAgICAgICBpZiAoY3R5cGUuZlhTU2ltcGxlVHlwZS5nZXRWYXJpZXR5KCkgPT0gWFNTaW1wbGVUeXBlLlZBUklFVFlfVU5JT04pIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZVbmlvblR5cGUgPSB0cnVlOwotICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmV2hpdGVTcGFjZSA9IGN0eXBlLmZYU1NpbXBsZVR5cGUuZ2V0V2hpdGVzcGFjZSgpOwotICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoRGF0YXR5cGVFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGRvIG5vdGhpbmcKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICAvLyBub3JtYWxpemF0aW9uOiBzaW1wbGUgdHlwZQotICAgICAgICBlbHNlIGlmIChmTm9ybWFsaXplRGF0YSkgewotICAgICAgICAgICAgLy8gaWYgIXVuaW9uIHR5cGUKLSAgICAgICAgICAgIFhTU2ltcGxlVHlwZSBkdiA9IChYU1NpbXBsZVR5cGUpIGZDdXJyZW50VHlwZTsKLSAgICAgICAgICAgIGlmIChkdi5nZXRWYXJpZXR5KCkgPT0gWFNTaW1wbGVUeXBlLlZBUklFVFlfVU5JT04pIHsKLSAgICAgICAgICAgICAgICBmVW5pb25UeXBlID0gdHJ1ZTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgZldoaXRlU3BhY2UgPSBkdi5nZXRXaGl0ZXNwYWNlKCk7Ci0gICAgICAgICAgICAgICAgfSBjYXRjaCAoRGF0YXR5cGVFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgICAgICAvLyBkbyBub3RoaW5nCi0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gdGhlbiB0cnkgdG8gZ2V0IHRoZSBjb250ZW50IG1vZGVsCi0gICAgICAgIGZDdXJyZW50Q00gPSBudWxsOwotICAgICAgICBpZiAoZkN1cnJlbnRUeXBlLmdldFR5cGVDYXRlZ29yeSgpID09IFhTVHlwZURlZmluaXRpb24uQ09NUExFWF9UWVBFKSB7Ci0gICAgICAgICAgICBmQ3VycmVudENNID0gKChYU0NvbXBsZXhUeXBlRGVjbCkgZkN1cnJlbnRUeXBlKS5nZXRDb250ZW50TW9kZWwoZkNNQnVpbGRlcik7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBhbmQgZ2V0IHRoZSBpbml0aWFsIGNvbnRlbnQgbW9kZWwgc3RhdGUKLSAgICAgICAgZkN1cnJDTVN0YXRlID0gbnVsbDsKLSAgICAgICAgaWYgKGZDdXJyZW50Q00gIT0gbnVsbCkKLSAgICAgICAgICAgIGZDdXJyQ01TdGF0ZSA9IGZDdXJyZW50Q00uc3RhcnRDb250ZW50TW9kZWwoKTsKLQotICAgICAgICAvLyBnZXQgaW5mb3JtYXRpb24gYWJvdXQgeHNpOm5pbAotICAgICAgICBTdHJpbmcgeHNpTmlsID0gYXR0cmlidXRlcy5nZXRWYWx1ZShTY2hlbWFTeW1ib2xzLlVSSV9YU0ksIFNjaGVtYVN5bWJvbHMuWFNJX05JTCk7Ci0gICAgICAgIC8vIG9ubHkgZGVhbCB3aXRoIHhzaTpuaWwgd2hlbiB0aGVyZSBpcyBhbiBlbGVtZW50IGRlY2xhcmF0aW9uCi0gICAgICAgIGlmICh4c2lOaWwgIT0gbnVsbCAmJiBmQ3VycmVudEVsZW1EZWNsICE9IG51bGwpCi0gICAgICAgICAgICBmTmlsID0gZ2V0WHNpTmlsKGVsZW1lbnQsIHhzaU5pbCk7Ci0KLSAgICAgICAgLy8gbm93IHZhbGlkYXRlIGV2ZXJ5dGhpbmcgcmVsYXRlZCB3aXRoIHRoZSBhdHRyaWJ1dGVzCi0gICAgICAgIC8vIGZpcnN0LCBnZXQgdGhlIGF0dHJpYnV0ZSBncm91cAotICAgICAgICBYU0F0dHJpYnV0ZUdyb3VwRGVjbCBhdHRyR3JwID0gbnVsbDsKLSAgICAgICAgaWYgKGZDdXJyZW50VHlwZS5nZXRUeXBlQ2F0ZWdvcnkoKSA9PSBYU1R5cGVEZWZpbml0aW9uLkNPTVBMRVhfVFlQRSkgewotICAgICAgICAgICAgWFNDb21wbGV4VHlwZURlY2wgY3R5cGUgPSAoWFNDb21wbGV4VHlwZURlY2wpIGZDdXJyZW50VHlwZTsKLSAgICAgICAgICAgIGF0dHJHcnAgPSBjdHlwZS5nZXRBdHRyR3JwKCk7Ci0gICAgICAgIH0KLSAgICAgICAgLy8gYWN0aXZhdGUgaWRlbnRpdHkgY29uc3RyYWludHMKLSAgICAgICAgZlZhbHVlU3RvcmVDYWNoZS5zdGFydEVsZW1lbnQoKTsKLSAgICAgICAgZk1hdGNoZXJTdGFjay5wdXNoQ29udGV4dCgpOwotICAgICAgICBpZiAoZkN1cnJlbnRFbGVtRGVjbCAhPSBudWxsICYmIGZDdXJyZW50RWxlbURlY2wuZklEQ1BvcyA+IDApIHsKLSAgICAgICAgICAgIGZJZENvbnN0cmFpbnQgPSB0cnVlOwotICAgICAgICAgICAgLy8gaW5pdGlhbGl6ZSB3aGVuIGlkZW50aXR5IGNvbnN0cmFpbnMgYXJlIGRlZmluZWQgZm9yIHRoZSBlbGVtCi0gICAgICAgICAgICBmVmFsdWVTdG9yZUNhY2hlLmluaXRWYWx1ZVN0b3Jlc0ZvcihmQ3VycmVudEVsZW1EZWNsLCB0aGlzKTsKLSAgICAgICAgfQotICAgICAgICBwcm9jZXNzQXR0cmlidXRlcyhlbGVtZW50LCBhdHRyaWJ1dGVzLCBhdHRyR3JwKTsKLQotICAgICAgICAvLyBhZGQgZGVmYXVsdCBhdHRyaWJ1dGVzCi0gICAgICAgIGlmIChhdHRyR3JwICE9IG51bGwpIHsKLSAgICAgICAgICAgIGFkZERlZmF1bHRBdHRyaWJ1dGVzKGVsZW1lbnQsIGF0dHJpYnV0ZXMsIGF0dHJHcnApOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gY2FsbCBhbGwgYWN0aXZlIGlkZW50aXR5IGNvbnN0cmFpbnRzCi0gICAgICAgIGludCBjb3VudCA9IGZNYXRjaGVyU3RhY2suZ2V0TWF0Y2hlckNvdW50KCk7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykgewotICAgICAgICAgICAgWFBhdGhNYXRjaGVyIG1hdGNoZXIgPSBmTWF0Y2hlclN0YWNrLmdldE1hdGNoZXJBdChpKTsKLSAgICAgICAgICAgIG1hdGNoZXIuc3RhcnRFbGVtZW50KCBlbGVtZW50LCBhdHRyaWJ1dGVzKTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChmQXVnUFNWSSkgewotICAgICAgICAgICAgYXVncyA9IGdldEVtcHR5QXVncyhhdWdzKTsKLQotICAgICAgICAgICAgLy8gUFNWSTogYWRkIHZhbGlkYXRpb24gY29udGV4dAotICAgICAgICAgICAgZkN1cnJlbnRQU1ZJLmZWYWxpZGF0aW9uQ29udGV4dCA9IGZWYWxpZGF0aW9uUm9vdDsKLSAgICAgICAgICAgIC8vIFBTVkk6IGFkZCBlbGVtZW50IGRlY2xhcmF0aW9uCi0gICAgICAgICAgICBmQ3VycmVudFBTVkkuZkRlY2xhcmF0aW9uID0gZkN1cnJlbnRFbGVtRGVjbDsKLSAgICAgICAgICAgIC8vIFBTVkk6IGFkZCBlbGVtZW50IHR5cGUKLSAgICAgICAgICAgIGZDdXJyZW50UFNWSS5mVHlwZURlY2wgPSBmQ3VycmVudFR5cGU7Ci0gICAgICAgICAgICAvLyBQU1ZJOiBhZGQgbm90YXRpb24gYXR0cmlidXRlCi0gICAgICAgICAgICBmQ3VycmVudFBTVkkuZk5vdGF0aW9uID0gZk5vdGF0aW9uOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIGF1Z3M7Ci0KLSAgICB9IC8vIGhhbmRsZVN0YXJ0RWxlbWVudChRTmFtZSxYTUxBdHRyaWJ1dGVzLGJvb2xlYW4pCi0KLSAgICAvKioKLSAgICAgKiAgSGFuZGxlIGVuZCBlbGVtZW50LiBJZiB0aGVyZSBpcyBub3QgdGV4dCBjb250ZW50LCBhbmQgdGhlcmUgaXMgYQotICAgICAqICB7dmFsdWUgY29uc3RyYWludH0gb24gdGhlIGNvcnJlc3BvbmRpbmcgZWxlbWVudCBkZWNsLCB0aGVuCi0gICAgICogc2V0IHRoZSBmRGVmYXVsdFZhbHVlIFhNTFN0cmluZyByZXByZXNlbnRpbmcgdGhlIGRlZmF1bHQgdmFsdWUuCi0gICAgICovCi0gICAgQXVnbWVudGF0aW9ucyBoYW5kbGVFbmRFbGVtZW50KFFOYW1lIGVsZW1lbnQsIEF1Z21lbnRhdGlvbnMgYXVncykgewotCi0gICAgICAgIGlmIChERUJVRykgewotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCI9PT5oYW5kbGVFbmRFbGVtZW50OiIgKyBlbGVtZW50KTsKLSAgICAgICAgfQotICAgICAgICAvLyBpZiB3ZSBhcmUgc2tpcHBpbmcsIHJldHVybgotICAgICAgICBpZiAoZlNraXBWYWxpZGF0aW9uRGVwdGggPj0gMCkgewotICAgICAgICAgICAgLy8gYnV0IGlmIHRoaXMgaXMgdGhlIHRvcCBlbGVtZW50IHRoYXQgd2UgYXJlIHNraXBwaW5nLAotICAgICAgICAgICAgLy8gcmVzdG9yZSB0aGUgc3RhdGVzLgotICAgICAgICAgICAgaWYgKGZTa2lwVmFsaWRhdGlvbkRlcHRoID09IGZFbGVtZW50RGVwdGggJiYgZlNraXBWYWxpZGF0aW9uRGVwdGggPiAwKSB7Ci0gICAgICAgICAgICAgICAgLy8gc2V0IHRoZSBwYXJ0aWFsIHZhbGlkYXRpb24gZGVwdGggdG8gdGhlIGRlcHRoIG9mIHBhcmVudAotICAgICAgICAgICAgICAgIGZORnVsbFZhbGlkYXRpb25EZXB0aCA9IGZTa2lwVmFsaWRhdGlvbkRlcHRoIC0gMTsKLSAgICAgICAgICAgICAgICBmU2tpcFZhbGlkYXRpb25EZXB0aCA9IC0xOwotICAgICAgICAgICAgICAgIGZFbGVtZW50RGVwdGgtLTsKLSAgICAgICAgICAgICAgICBmU3ViRWxlbWVudCA9IGZTdWJFbGVtZW50U3RhY2tbZkVsZW1lbnREZXB0aF07Ci0gICAgICAgICAgICAgICAgZkN1cnJlbnRFbGVtRGVjbCA9IGZFbGVtRGVjbFN0YWNrW2ZFbGVtZW50RGVwdGhdOwotICAgICAgICAgICAgICAgIGZOaWwgPSBmTmlsU3RhY2tbZkVsZW1lbnREZXB0aF07Ci0gICAgICAgICAgICAgICAgZk5vdGF0aW9uID0gZk5vdGF0aW9uU3RhY2tbZkVsZW1lbnREZXB0aF07Ci0gICAgICAgICAgICAgICAgZkN1cnJlbnRUeXBlID0gZlR5cGVTdGFja1tmRWxlbWVudERlcHRoXTsKLSAgICAgICAgICAgICAgICBmQ3VycmVudENNID0gZkNNU3RhY2tbZkVsZW1lbnREZXB0aF07Ci0gICAgICAgICAgICAgICAgZlN0cmljdEFzc2VzcyA9IGZTdHJpY3RBc3Nlc3NTdGFja1tmRWxlbWVudERlcHRoXTsKLSAgICAgICAgICAgICAgICBmQ3VyckNNU3RhdGUgPSBmQ01TdGF0ZVN0YWNrW2ZFbGVtZW50RGVwdGhdOwotICAgICAgICAgICAgICAgIGZTYXdUZXh0ID0gZlNhd1RleHRTdGFja1tmRWxlbWVudERlcHRoXTsKLSAgICAgICAgICAgICAgICBmU2F3Q2hhcmFjdGVycyA9IGZTdHJpbmdDb250ZW50W2ZFbGVtZW50RGVwdGhdOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgZkVsZW1lbnREZXB0aC0tOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBQU1ZJOiB2YWxpZGF0aW9uIGF0dGVtcHRlZDoKLSAgICAgICAgICAgIC8vIHVzZSBkZWZhdWx0IHZhbHVlcyBpbiBwc3ZpIGl0ZW0gZm9yCi0gICAgICAgICAgICAvLyB2YWxpZGF0aW9uIGF0dGVtcHRlZCwgdmFsaWRpdHksIGFuZCBlcnJvciBjb2RlcwotCi0gICAgICAgICAgICAvLyBjaGVjayBleHRyYSBzY2hlbWEgY29uc3RyYWludHMgb24gcm9vdCBlbGVtZW50Ci0gICAgICAgICAgICBpZiAoZkVsZW1lbnREZXB0aCA9PSAtMSAmJiBmRnVsbENoZWNraW5nKSB7Ci0gICAgICAgICAgICAgICAgWFNDb25zdHJhaW50cy5mdWxsU2NoZW1hQ2hlY2tpbmcoCi0gICAgICAgICAgICAgICAgICAgIGZHcmFtbWFyQnVja2V0LAotICAgICAgICAgICAgICAgICAgICBmU3ViR3JvdXBIYW5kbGVyLAotICAgICAgICAgICAgICAgICAgICBmQ01CdWlsZGVyLAotICAgICAgICAgICAgICAgICAgICBmWFNJRXJyb3JSZXBvcnRlci5mRXJyb3JSZXBvcnRlcik7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmIChmQXVnUFNWSSkKLSAgICAgICAgICAgICAgICBhdWdzID0gZ2V0RW1wdHlBdWdzKGF1Z3MpOwotICAgICAgICAgICAgcmV0dXJuIGF1Z3M7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBub3cgdmFsaWRhdGUgdGhlIGNvbnRlbnQgb2YgdGhlIGVsZW1lbnQKLSAgICAgICAgcHJvY2Vzc0VsZW1lbnRDb250ZW50KGVsZW1lbnQpOwotCi0gICAgICAgIC8vIEVsZW1lbnQgTG9jYWxseSBWYWxpZCAoRWxlbWVudCkKLSAgICAgICAgLy8gNiBUaGUgZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIG11c3QgYmUgdmFsaWQgd2l0aCByZXNwZWN0IHRvIGVhY2ggb2YgdGhlIHtpZGVudGl0eS1jb25zdHJhaW50IGRlZmluaXRpb25zfSBhcyBwZXIgSWRlbnRpdHktY29uc3RyYWludCBTYXRpc2ZpZWQgKDMuMTEuNCkuCi0KLSAgICAgICAgLy8gY2FsbCBtYXRjaGVycyBhbmQgZGUtYWN0aXZhdGUgY29udGV4dAotICAgICAgICBpbnQgb2xkQ291bnQgPSBmTWF0Y2hlclN0YWNrLmdldE1hdGNoZXJDb3VudCgpOwotICAgICAgICBmb3IgKGludCBpID0gb2xkQ291bnQgLSAxOyBpID49IDA7IGktLSkgewotICAgICAgICAgICAgWFBhdGhNYXRjaGVyIG1hdGNoZXIgPSBmTWF0Y2hlclN0YWNrLmdldE1hdGNoZXJBdChpKTsKLSAgICAgICAgICAgIGlmIChmQ3VycmVudEVsZW1EZWNsID09IG51bGwpCi0gICAgICAgICAgICAgICAgbWF0Y2hlci5lbmRFbGVtZW50KGVsZW1lbnQsIG51bGwsIGZhbHNlLCBmVmFsaWRhdGVkSW5mby5hY3R1YWxWYWx1ZSwgZlZhbGlkYXRlZEluZm8uYWN0dWFsVmFsdWVUeXBlLCBmVmFsaWRhdGVkSW5mby5pdGVtVmFsdWVUeXBlcyk7Ci0KLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICBtYXRjaGVyLmVuZEVsZW1lbnQoCi0gICAgICAgICAgICAgICAgICAgIGVsZW1lbnQsCi0gICAgICAgICAgICAgICAgICAgIGZDdXJyZW50VHlwZSwKLSAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbGVtRGVjbC5nZXROaWxsYWJsZSgpLAotICAgICAgICAgICAgICAgICAgICBmRGVmYXVsdFZhbHVlID09IG51bGwKLSAgICAgICAgICAgICAgICAgICAgICAgID8gZlZhbGlkYXRlZEluZm8uYWN0dWFsVmFsdWUKLSAgICAgICAgICAgICAgICAgICAgICAgIDogZkN1cnJlbnRFbGVtRGVjbC5mRGVmYXVsdC5hY3R1YWxWYWx1ZSwKLSAgICAgICAgICAgICAgICAgICAgZkRlZmF1bHRWYWx1ZSA9PSBudWxsCi0gICAgICAgICAgICAgICAgICAgICAgICA/IGZWYWxpZGF0ZWRJbmZvLmFjdHVhbFZhbHVlVHlwZQotICAgICAgICAgICAgICAgICAgICAgICAgOiBmQ3VycmVudEVsZW1EZWNsLmZEZWZhdWx0LmFjdHVhbFZhbHVlVHlwZSwKLSAgICAgICAgICAgICAgICAgICAgZkRlZmF1bHRWYWx1ZSA9PSBudWxsCi0gICAgICAgICAgICAgICAgICAgICAgICA/IGZWYWxpZGF0ZWRJbmZvLml0ZW1WYWx1ZVR5cGVzCi0gICAgICAgICAgICAgICAgICAgICAgICA6IGZDdXJyZW50RWxlbURlY2wuZkRlZmF1bHQuaXRlbVZhbHVlVHlwZXMpOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKGZNYXRjaGVyU3RhY2suc2l6ZSgpID4gMCkgewotICAgICAgICAgICAgZk1hdGNoZXJTdGFjay5wb3BDb250ZXh0KCk7Ci0gICAgICAgIH0KLQotICAgICAgICBpbnQgbmV3Q291bnQgPSBmTWF0Y2hlclN0YWNrLmdldE1hdGNoZXJDb3VudCgpOwotICAgICAgICAvLyBoYW5kbGUgZXZlcnl0aGluZyAqYnV0KiBrZXlyZWYncy4KLSAgICAgICAgZm9yIChpbnQgaSA9IG9sZENvdW50IC0gMTsgaSA+PSBuZXdDb3VudDsgaS0tKSB7Ci0gICAgICAgICAgICBYUGF0aE1hdGNoZXIgbWF0Y2hlciA9IGZNYXRjaGVyU3RhY2suZ2V0TWF0Y2hlckF0KGkpOwotICAgICAgICAgICAgaWYgKG1hdGNoZXIgaW5zdGFuY2VvZiBTZWxlY3Rvci5NYXRjaGVyKSB7Ci0gICAgICAgICAgICAgICAgU2VsZWN0b3IuTWF0Y2hlciBzZWxNYXRjaGVyID0gKFNlbGVjdG9yLk1hdGNoZXIpIG1hdGNoZXI7Ci0gICAgICAgICAgICAgICAgSWRlbnRpdHlDb25zdHJhaW50IGlkOwotICAgICAgICAgICAgICAgIGlmICgoaWQgPSBzZWxNYXRjaGVyLmdldElkZW50aXR5Q29uc3RyYWludCgpKSAhPSBudWxsCi0gICAgICAgICAgICAgICAgICAgICYmIGlkLmdldENhdGVnb3J5KCkgIT0gSWRlbnRpdHlDb25zdHJhaW50LklDX0tFWVJFRikgewotICAgICAgICAgICAgICAgICAgICBmVmFsdWVTdG9yZUNhY2hlLnRyYW5zcGxhbnQoaWQsIHNlbE1hdGNoZXIuZ2V0SW5pdGlhbERlcHRoKCkpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIG5vdyBoYW5kbGUga2V5cmVmJ3MvLi4uCi0gICAgICAgIGZvciAoaW50IGkgPSBvbGRDb3VudCAtIDE7IGkgPj0gbmV3Q291bnQ7IGktLSkgewotICAgICAgICAgICAgWFBhdGhNYXRjaGVyIG1hdGNoZXIgPSBmTWF0Y2hlclN0YWNrLmdldE1hdGNoZXJBdChpKTsKLSAgICAgICAgICAgIGlmIChtYXRjaGVyIGluc3RhbmNlb2YgU2VsZWN0b3IuTWF0Y2hlcikgewotICAgICAgICAgICAgICAgIFNlbGVjdG9yLk1hdGNoZXIgc2VsTWF0Y2hlciA9IChTZWxlY3Rvci5NYXRjaGVyKSBtYXRjaGVyOwotICAgICAgICAgICAgICAgIElkZW50aXR5Q29uc3RyYWludCBpZDsKLSAgICAgICAgICAgICAgICBpZiAoKGlkID0gc2VsTWF0Y2hlci5nZXRJZGVudGl0eUNvbnN0cmFpbnQoKSkgIT0gbnVsbAotICAgICAgICAgICAgICAgICAgICAmJiBpZC5nZXRDYXRlZ29yeSgpID09IElkZW50aXR5Q29uc3RyYWludC5JQ19LRVlSRUYpIHsKLSAgICAgICAgICAgICAgICAgICAgVmFsdWVTdG9yZUJhc2UgdmFsdWVzID0KLSAgICAgICAgICAgICAgICAgICAgICAgIGZWYWx1ZVN0b3JlQ2FjaGUuZ2V0VmFsdWVTdG9yZUZvcihpZCwgc2VsTWF0Y2hlci5nZXRJbml0aWFsRGVwdGgoKSk7Ci0gICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZXMgIT0gbnVsbCkgLy8gbm90aGluZyB0byBkbyBpZiBub3RoaW5nIG1hdGNoZWQhCi0gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZXMuZW5kRG9jdW1lbnRGcmFnbWVudCgpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBmVmFsdWVTdG9yZUNhY2hlLmVuZEVsZW1lbnQoKTsKLQotICAgICAgICBTY2hlbWFHcmFtbWFyW10gZ3JhbW1hcnMgPSBudWxsOwotICAgICAgICAvLyBoYXZlIHdlIHJlYWNoZWQgdGhlIGVuZCB0YWcgb2YgdGhlIHZhbGlkYXRpb24gcm9vdD8KLSAgICAgICAgaWYgKGZFbGVtZW50RGVwdGggPT0gMCkgewotICAgICAgICAgICAgLy8gNyBJZiB0aGUgZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIGlzIHRoZSB2YWxpZGF0aW9uIHJvb3QsIGl0IG11c3QgYmUgdmFsaWQgcGVyIFZhbGlkYXRpb24gUm9vdCBWYWxpZCAoSUQvSURSRUYpICgzLjMuNCkuCi0gICAgICAgICAgICBTdHJpbmcgaW52SWRSZWYgPSBmVmFsaWRhdGlvblN0YXRlLmNoZWNrSURSZWZJRCgpOwotICAgICAgICAgICAgZlZhbGlkYXRpb25TdGF0ZS5yZXNldElEVGFibGVzKCk7Ci0gICAgICAgICAgICBpZiAoaW52SWRSZWYgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKCJjdmMtaWQuMSIsIG5ldyBPYmplY3RbXSB7IGludklkUmVmIH0pOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gY2hlY2sgZXh0cmEgc2NoZW1hIGNvbnN0cmFpbnRzCi0gICAgICAgICAgICBpZiAoZkZ1bGxDaGVja2luZykgewotICAgICAgICAgICAgICAgIFhTQ29uc3RyYWludHMuZnVsbFNjaGVtYUNoZWNraW5nKAotICAgICAgICAgICAgICAgICAgICBmR3JhbW1hckJ1Y2tldCwKLSAgICAgICAgICAgICAgICAgICAgZlN1Ykdyb3VwSGFuZGxlciwKLSAgICAgICAgICAgICAgICAgICAgZkNNQnVpbGRlciwKLSAgICAgICAgICAgICAgICAgICAgZlhTSUVycm9yUmVwb3J0ZXIuZkVycm9yUmVwb3J0ZXIpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBncmFtbWFycyA9IGZHcmFtbWFyQnVja2V0LmdldEdyYW1tYXJzKCk7Ci0gICAgICAgICAgICAvLyByZXR1cm4gdGhlIGZpbmFsIHNldCBvZiBncmFtbWFycyB2YWxpZGF0b3IgZW5kZWQgdXAgd2l0aAotICAgICAgICAgICAgaWYgKGZHcmFtbWFyUG9vbCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgLy8gU2V0IGdyYW1tYXJzIGFzIGltbXV0YWJsZQotICAgICAgICAgICAgICAgIGZvciAoaW50IGs9MDsgayA8IGdyYW1tYXJzLmxlbmd0aDsgaysrKSB7Ci0gICAgICAgICAgICAgICAgICAgIGdyYW1tYXJzW2tdLnNldEltbXV0YWJsZSh0cnVlKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZkdyYW1tYXJQb29sLmNhY2hlR3JhbW1hcnMoWE1MR3JhbW1hckRlc2NyaXB0aW9uLlhNTF9TQ0hFTUEsIGdyYW1tYXJzKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGF1Z3MgPSBlbmRFbGVtZW50UFNWSSh0cnVlLCBncmFtbWFycywgYXVncyk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBhdWdzID0gZW5kRWxlbWVudFBTVkkoZmFsc2UsIGdyYW1tYXJzLCBhdWdzKTsKLQotICAgICAgICAgICAgLy8gZGVjcmVhc2UgZWxlbWVudCBkZXB0aCBhbmQgcmVzdG9yZSBzdGF0ZXMKLSAgICAgICAgICAgIGZFbGVtZW50RGVwdGgtLTsKLQotICAgICAgICAgICAgLy8gZ2V0IHRoZSBzdGF0ZXMgZm9yIHRoZSBwYXJlbnQgZWxlbWVudC4KLSAgICAgICAgICAgIGZTdWJFbGVtZW50ID0gZlN1YkVsZW1lbnRTdGFja1tmRWxlbWVudERlcHRoXTsKLSAgICAgICAgICAgIGZDdXJyZW50RWxlbURlY2wgPSBmRWxlbURlY2xTdGFja1tmRWxlbWVudERlcHRoXTsKLSAgICAgICAgICAgIGZOaWwgPSBmTmlsU3RhY2tbZkVsZW1lbnREZXB0aF07Ci0gICAgICAgICAgICBmTm90YXRpb24gPSBmTm90YXRpb25TdGFja1tmRWxlbWVudERlcHRoXTsKLSAgICAgICAgICAgIGZDdXJyZW50VHlwZSA9IGZUeXBlU3RhY2tbZkVsZW1lbnREZXB0aF07Ci0gICAgICAgICAgICBmQ3VycmVudENNID0gZkNNU3RhY2tbZkVsZW1lbnREZXB0aF07Ci0gICAgICAgICAgICBmU3RyaWN0QXNzZXNzID0gZlN0cmljdEFzc2Vzc1N0YWNrW2ZFbGVtZW50RGVwdGhdOwotICAgICAgICAgICAgZkN1cnJDTVN0YXRlID0gZkNNU3RhdGVTdGFja1tmRWxlbWVudERlcHRoXTsKLSAgICAgICAgICAgIGZTYXdUZXh0ID0gZlNhd1RleHRTdGFja1tmRWxlbWVudERlcHRoXTsKLSAgICAgICAgICAgIGZTYXdDaGFyYWN0ZXJzID0gZlN0cmluZ0NvbnRlbnRbZkVsZW1lbnREZXB0aF07Ci0KLSAgICAgICAgICAgIC8vIFdlIHNob3VsZCBoYXZlIGEgc3RhY2sgZm9yIHdoaXRlc3BhY2UgdmFsdWUsIGFuZCBwb3AgaXQgdXAgaGVyZS4KLSAgICAgICAgICAgIC8vIEJ1dCB3aGVuIGZXaGl0ZVNwYWNlICE9IC0xLCBhbmQgd2Ugc2VlIGEgc3ViLWVsZW1lbnQsIGl0IG11c3QgYmUKLSAgICAgICAgICAgIC8vIGFuIGVycm9yIChhdCBsZWFzdCBmb3IgU2NoZW1hIDEuMCkuIFNvIGZvciB2YWxpZCBkb2N1bWVudHMsIHRoZQotICAgICAgICAgICAgLy8gb25seSB2YWx1ZSB3ZSBhcmUgZ29pbmcgdG8gcHVzaC9wb3AgaW4gdGhlIHN0YWNrIGlzIC0xLgotICAgICAgICAgICAgLy8gSGVyZSB3ZSBqdXN0IG1pbWljIHRoZSBlZmZlY3Qgb2YgcG9wcGluZyAtMS4gLVNHCi0gICAgICAgICAgICBmV2hpdGVTcGFjZSA9IC0xOwotICAgICAgICAgICAgLy8gU2FtZSBmb3IgYXBwZW5kIGJ1ZmZlci4gU2ltcGxlIHR5cGVzIGFuZCBlbGVtZW50cyB3aXRoIGZpeGVkCi0gICAgICAgICAgICAvLyB2YWx1ZSBjb25zdHJhaW50IGRvbid0IGFsbG93IHN1Yi1lbGVtZW50cy4gLVNHCi0gICAgICAgICAgICBmQXBwZW5kQnVmZmVyID0gZmFsc2U7Ci0gICAgICAgICAgICAvLyBzYW1lIGhlcmUuCi0gICAgICAgICAgICBmVW5pb25UeXBlID0gZmFsc2U7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gYXVnczsKLSAgICB9IC8vIGhhbmRsZUVuZEVsZW1lbnQoUU5hbWUsYm9vbGVhbikqLwotCi0gICAgZmluYWwgQXVnbWVudGF0aW9ucyBlbmRFbGVtZW50UFNWSSgKLSAgICAgICAgYm9vbGVhbiByb290LAotICAgICAgICBTY2hlbWFHcmFtbWFyW10gZ3JhbW1hcnMsCi0gICAgICAgIEF1Z21lbnRhdGlvbnMgYXVncykgewotCi0gICAgICAgIGlmIChmQXVnUFNWSSkgewotICAgICAgICAgICAgYXVncyA9IGdldEVtcHR5QXVncyhhdWdzKTsKLQotICAgICAgICAgICAgLy8gdGhlIDQgcHJvcGVydGllcyBzZW50IG9uIHN0YXJ0RWxlbWVudCBjYWxscwotICAgICAgICAgICAgZkN1cnJlbnRQU1ZJLmZEZWNsYXJhdGlvbiA9IHRoaXMuZkN1cnJlbnRFbGVtRGVjbDsKLSAgICAgICAgICAgIGZDdXJyZW50UFNWSS5mVHlwZURlY2wgPSB0aGlzLmZDdXJyZW50VHlwZTsKLSAgICAgICAgICAgIGZDdXJyZW50UFNWSS5mTm90YXRpb24gPSB0aGlzLmZOb3RhdGlvbjsKLSAgICAgICAgICAgIGZDdXJyZW50UFNWSS5mVmFsaWRhdGlvbkNvbnRleHQgPSB0aGlzLmZWYWxpZGF0aW9uUm9vdDsKLSAgICAgICAgICAgIC8vIFBTVkk6IHZhbGlkYXRpb24gYXR0ZW1wdGVkCi0gICAgICAgICAgICAvLyBub3RoaW5nIGJlbG93IG9yIGF0IHRoZSBzYW1lIGxldmVsIGhhcyBub25lIG9yIHBhcnRpYWwKLSAgICAgICAgICAgIC8vICh3aGljaCBtZWFucyB0aGlzIGxldmVsIGlzIHN0cmljdGx5IGFzc2Vzc2VkLCBhbmQgYWxsIGNoaWRyZW4KLSAgICAgICAgICAgIC8vIGFyZSBmdWxsKSwgc28gdGhpcyBvbmUgaGFzIGZ1bGwKLSAgICAgICAgICAgIGlmIChmRWxlbWVudERlcHRoID4gZk5GdWxsVmFsaWRhdGlvbkRlcHRoKSB7Ci0gICAgICAgICAgICAgICAgZkN1cnJlbnRQU1ZJLmZWYWxpZGF0aW9uQXR0ZW1wdGVkID0gRWxlbWVudFBTVkkuVkFMSURBVElPTl9GVUxMOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gbm90aGluZyBiZWxvdyBvciBhdCB0aGUgc2FtZSBsZXZlbCBoYXMgZnVsbCBvciBwYXJ0aWFsCi0gICAgICAgICAgICAvLyAod2hpY2ggbWVhbnMgdGhpcyBsZXZlbCBpcyBub3Qgc3RyaWN0bHkgYXNzZXNzZWQsIGFuZCBhbGwgY2hpZHJlbgotICAgICAgICAgICAgLy8gYXJlIG5vbmUpLCBzbyB0aGlzIG9uZSBoYXMgbm9uZQotICAgICAgICAgICAgZWxzZSBpZiAoZkVsZW1lbnREZXB0aCA+IGZOTm9uZVZhbGlkYXRpb25EZXB0aCkgewotICAgICAgICAgICAgICAgIGZDdXJyZW50UFNWSS5mVmFsaWRhdGlvbkF0dGVtcHRlZCA9IEVsZW1lbnRQU1ZJLlZBTElEQVRJT05fTk9ORTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIG90aGVyd2lzZSBwYXJ0aWFsLCBhbmQgYW55dGhpbmcgYWJvdmUgdGhpcyBsZXZlbCB3aWxsIGJlIHBhcnRpYWwKLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIGZDdXJyZW50UFNWSS5mVmFsaWRhdGlvbkF0dGVtcHRlZCA9IEVsZW1lbnRQU1ZJLlZBTElEQVRJT05fUEFSVElBTDsKLSAgICAgICAgICAgICAgICBmTkZ1bGxWYWxpZGF0aW9uRGVwdGggPSBmTk5vbmVWYWxpZGF0aW9uRGVwdGggPSBmRWxlbWVudERlcHRoIC0gMTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKGZEZWZhdWx0VmFsdWUgIT0gbnVsbCkKLSAgICAgICAgICAgICAgICBmQ3VycmVudFBTVkkuZlNwZWNpZmllZCA9IHRydWU7Ci0gICAgICAgICAgICBmQ3VycmVudFBTVkkuZk5pbCA9IGZOaWw7Ci0gICAgICAgICAgICBmQ3VycmVudFBTVkkuZk1lbWJlclR5cGUgPSBmVmFsaWRhdGVkSW5mby5tZW1iZXJUeXBlOwotICAgICAgICAgICAgZkN1cnJlbnRQU1ZJLmZOb3JtYWxpemVkVmFsdWUgPSBmVmFsaWRhdGVkSW5mby5ub3JtYWxpemVkVmFsdWU7Ci0gICAgICAgICAgICBmQ3VycmVudFBTVkkuZkFjdHVhbFZhbHVlID0gZlZhbGlkYXRlZEluZm8uYWN0dWFsVmFsdWU7Ci0gICAgICAgICAgICBmQ3VycmVudFBTVkkuZkFjdHVhbFZhbHVlVHlwZSA9IGZWYWxpZGF0ZWRJbmZvLmFjdHVhbFZhbHVlVHlwZTsKLSAgICAgICAgICAgIGZDdXJyZW50UFNWSS5mSXRlbVZhbHVlVHlwZXMgPSBmVmFsaWRhdGVkSW5mby5pdGVtVmFsdWVUeXBlczsKLQotICAgICAgICAgICAgaWYgKGZTdHJpY3RBc3Nlc3MpIHsKLSAgICAgICAgICAgICAgICAvLyBnZXQgYWxsIGVycm9ycyBmb3IgdGhlIGN1cnJlbnQgZWxlbWVudCwgaXRzIGF0dHJpYnV0ZSwKLSAgICAgICAgICAgICAgICAvLyBhbmQgc3ViZWxlbWVudHMgKGlmIHRoZXkgd2VyZSBzdHJpY3RseSBhc3Nlc3NlZCkuCi0gICAgICAgICAgICAgICAgLy8gYW55IGVycm9yIHdvdWxkIG1ha2UgdGhpcyBlbGVtZW50IGludmFsaWQuCi0gICAgICAgICAgICAgICAgLy8gYW5kIHdlIG1lcmdlIHRoZXNlIGVycm9ycyB0byB0aGUgcGFyZW50IGVsZW1lbnQuCi0gICAgICAgICAgICAgICAgU3RyaW5nW10gZXJyb3JzID0gZlhTSUVycm9yUmVwb3J0ZXIubWVyZ2VDb250ZXh0KCk7Ci0KLSAgICAgICAgICAgICAgICAvLyBQU1ZJOiBlcnJvciBjb2RlcwotICAgICAgICAgICAgICAgIGZDdXJyZW50UFNWSS5mRXJyb3JDb2RlcyA9IGVycm9yczsKLSAgICAgICAgICAgICAgICAvLyBQU1ZJOiB2YWxpZGl0eQotICAgICAgICAgICAgICAgIGZDdXJyZW50UFNWSS5mVmFsaWRpdHkgPQotICAgICAgICAgICAgICAgICAgICAoZXJyb3JzID09IG51bGwpID8gRWxlbWVudFBTVkkuVkFMSURJVFlfVkFMSUQgOiBFbGVtZW50UFNWSS5WQUxJRElUWV9JTlZBTElEOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAvLyBQU1ZJOiB2YWxpZGl0eQotICAgICAgICAgICAgICAgIGZDdXJyZW50UFNWSS5mVmFsaWRpdHkgPSBFbGVtZW50UFNWSS5WQUxJRElUWV9OT1RLTk9XTjsKLSAgICAgICAgICAgICAgICAvLyBEaXNjYXJkIHRoZSBjdXJyZW50IGNvbnRleHQ6IGlnbm9yZSBhbnkgZXJyb3IgaGFwcGVuZWQgd2l0aGluCi0gICAgICAgICAgICAgICAgLy8gdGhlIHN1Yi1lbGVtZW50cy9hdHRyaWJ1dGVzIG9mIHRoaXMgZWxlbWVudCwgYmVjYXVzZSB0aG9zZQotICAgICAgICAgICAgICAgIC8vIGVycm9ycyB3b24ndCBhZmZlY3QgdGhlIHZhbGlkaXR5IG9mIHRoZSBwYXJlbnQgZWxlbWVudHMuCi0gICAgICAgICAgICAgICAgZlhTSUVycm9yUmVwb3J0ZXIucG9wQ29udGV4dCgpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAocm9vdCkgewotICAgICAgICAgICAgICAgIC8vIHN0b3JlIFtzY2hlbWEgaW5mb3JtYXRpb25dIGluIHRoZSBQU1ZJCi0gICAgICAgICAgICAgICAgZkN1cnJlbnRQU1ZJLmZHcmFtbWFycyA9IGdyYW1tYXJzOwotICAgICAgICAgICAgICAgIGZDdXJyZW50UFNWSS5mU2NoZW1hSW5mb3JtYXRpb24gPSBudWxsOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIGF1Z3M7Ci0KLSAgICB9Ci0KLSAgICBBdWdtZW50YXRpb25zIGdldEVtcHR5QXVncyhBdWdtZW50YXRpb25zIGF1Z3MpIHsKLSAgICAgICAgaWYgKGF1Z3MgPT0gbnVsbCkgewotICAgICAgICAgICAgYXVncyA9IGZBdWdtZW50YXRpb25zOwotICAgICAgICAgICAgYXVncy5yZW1vdmVBbGxJdGVtcygpOwotICAgICAgICB9Ci0gICAgICAgIGF1Z3MucHV0SXRlbShDb25zdGFudHMuRUxFTUVOVF9QU1ZJLCBmQ3VycmVudFBTVkkpOwotICAgICAgICBmQ3VycmVudFBTVkkucmVzZXQoKTsKLQotICAgICAgICByZXR1cm4gYXVnczsKLSAgICB9Ci0KLSAgICB2b2lkIHN0b3JlTG9jYXRpb25zKFN0cmluZyBzTG9jYXRpb24sIFN0cmluZyBuc0xvY2F0aW9uKSB7Ci0gICAgICAgIGlmIChzTG9jYXRpb24gIT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKCFYTUxTY2hlbWFMb2FkZXIudG9rZW5pemVTY2hlbWFMb2NhdGlvblN0cihzTG9jYXRpb24sIGZMb2NhdGlvblBhaXJzKSkgewotICAgICAgICAgICAgICAgIC8vIGVycm9yIQotICAgICAgICAgICAgICAgIGZYU0lFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKAotICAgICAgICAgICAgICAgICAgICBYU01lc3NhZ2VGb3JtYXR0ZXIuU0NIRU1BX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgIlNjaGVtYUxvY2F0aW9uIiwKLSAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgc0xvY2F0aW9uIH0sCi0gICAgICAgICAgICAgICAgICAgIFhNTEVycm9yUmVwb3J0ZXIuU0VWRVJJVFlfV0FSTklORyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKG5zTG9jYXRpb24gIT0gbnVsbCkgewotICAgICAgICAgICAgWE1MU2NoZW1hTG9hZGVyLkxvY2F0aW9uQXJyYXkgbGEgPSBmTG9jYXRpb25QYWlycy5nZXQoWE1MU3ltYm9scy5FTVBUWV9TVFJJTkcpOwotICAgICAgICAgICAgaWYgKGxhID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBsYSA9IG5ldyBYTUxTY2hlbWFMb2FkZXIuTG9jYXRpb25BcnJheSgpOwotICAgICAgICAgICAgICAgIGZMb2NhdGlvblBhaXJzLnB1dChYTUxTeW1ib2xzLkVNUFRZX1NUUklORywgbGEpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgbGEuYWRkTG9jYXRpb24obnNMb2NhdGlvbik7Ci0gICAgICAgIH0KLQotICAgIH0gLy9zdG9yZUxvY2F0aW9ucwotCi0gICAgLy90aGlzIGlzIHRoZSBmdW5jdGlvbiB3aGVyZSBsb2dpYyBvZiByZXRyaWV2aW5nIGdyYW1tYXIgaXMgd3JpdHRlbiAsIHBhcnNlciBmaXJzdCB0cmllcyB0byBnZXQgdGhlIGdyYW1tYXIgZnJvbQotICAgIC8vdGhlIGxvY2FsIHBvb2wsIGlmIG5vdCBpbiBsb2NhbCBwb29sLCBpdCBnaXZlcyBjaGFuY2UgdG8gYXBwbGljYXRpb24gdG8gYmUgYWJsZSB0byByZXRyaWV2ZSB0aGUgZ3JhbW1hciwgdGhlbiBpdAotICAgIC8vdHJpZXMgdG8gcGFyc2UgdGhlIGdyYW1tYXIgdXNpbmcgbG9jYXRpb24gaGludHMgZnJvbSB0aGUgZ2l2ZSBuYW1lc3BhY2UuCi0gICAgU2NoZW1hR3JhbW1hciBmaW5kU2NoZW1hR3JhbW1hcigKLSAgICAgICAgc2hvcnQgY29udGV4dFR5cGUsCi0gICAgICAgIFN0cmluZyBuYW1lc3BhY2UsCi0gICAgICAgIFFOYW1lIGVuY2xvc2luZ0VsZW1lbnQsCi0gICAgICAgIFFOYW1lIHRyaWdnZXJpbmdDb21wb25ldCwKLSAgICAgICAgWE1MQXR0cmlidXRlcyBhdHRyaWJ1dGVzKSB7Ci0gICAgICAgIFNjaGVtYUdyYW1tYXIgZ3JhbW1hciA9IG51bGw7Ci0gICAgICAgIC8vZ2V0IHRoZSBncmFtbWFyIGZyb20gbG9jYWwgcG9vbC4uLgotICAgICAgICBncmFtbWFyID0gZkdyYW1tYXJCdWNrZXQuZ2V0R3JhbW1hcihuYW1lc3BhY2UpOwotCi0gICAgICAgIGlmIChncmFtbWFyID09IG51bGwpIHsKLSAgICAgICAgICAgIGZYU0REZXNjcmlwdGlvbi5zZXROYW1lc3BhY2UobmFtZXNwYWNlKTsKLSAgICAgICAgICAgIC8vIGdpdmUgYSBjaGFuY2UgdG8gYXBwbGljYXRpb24gdG8gYmUgYWJsZSB0byByZXRyZWl2ZSB0aGUgZ3JhbW1hci4KLSAgICAgICAgICAgIGlmIChmR3JhbW1hclBvb2wgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGdyYW1tYXIgPSAoU2NoZW1hR3JhbW1hcikgZkdyYW1tYXJQb29sLnJldHJpZXZlR3JhbW1hcihmWFNERGVzY3JpcHRpb24pOwotICAgICAgICAgICAgICAgIGlmIChncmFtbWFyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gcHV0IHRoaXMgZ3JhbW1hciBpbnRvIHRoZSBidWNrZXQsIGFsb25nIHdpdGggZ3JhbW1hcnMKLSAgICAgICAgICAgICAgICAgICAgLy8gaW1wb3J0ZWQgYnkgaXQgKGRpcmVjdGx5IG9yIGluZGlyZWN0bHkpCi0gICAgICAgICAgICAgICAgICAgIGlmICghZkdyYW1tYXJCdWNrZXQucHV0R3JhbW1hcihncmFtbWFyLCB0cnVlLCBmTmFtZXNwYWNlR3Jvd3RoKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gUkVWSVNJVDogYSBjb25mbGljdCBiZXR3ZWVuIG5ldyBncmFtbWFyKHMpIGFuZCBncmFtbWFycwotICAgICAgICAgICAgICAgICAgICAgICAgLy8gaW4gdGhlIGJ1Y2tldC4gV2hhdCB0byBkbz8gQSB3YXJuaW5nPyBBbiBleGNlcHRpb24/Ci0gICAgICAgICAgICAgICAgICAgICAgICBmWFNJRXJyb3JSZXBvcnRlci5mRXJyb3JSZXBvcnRlci5yZXBvcnRFcnJvcigKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBYU01lc3NhZ2VGb3JtYXR0ZXIuU0NIRU1BX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAiR3JhbW1hckNvbmZsaWN0IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTEVycm9yUmVwb3J0ZXIuU0VWRVJJVFlfV0FSTklORyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBncmFtbWFyID0gbnVsbDsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBpZiAoKGdyYW1tYXIgPT0gbnVsbCAmJiAhZlVzZUdyYW1tYXJQb29sT25seSkgfHwgZk5hbWVzcGFjZUdyb3d0aCkgewotICAgICAgICAgICAgZlhTRERlc2NyaXB0aW9uLnJlc2V0KCk7Ci0gICAgICAgICAgICBmWFNERGVzY3JpcHRpb24uZkNvbnRleHRUeXBlID0gY29udGV4dFR5cGU7Ci0gICAgICAgICAgICBmWFNERGVzY3JpcHRpb24uc2V0TmFtZXNwYWNlKG5hbWVzcGFjZSk7Ci0gICAgICAgICAgICBmWFNERGVzY3JpcHRpb24uZkVuY2xvc2VkRWxlbWVudE5hbWUgPSBlbmNsb3NpbmdFbGVtZW50OwotICAgICAgICAgICAgZlhTRERlc2NyaXB0aW9uLmZUcmlnZ2VyaW5nQ29tcG9uZW50ID0gdHJpZ2dlcmluZ0NvbXBvbmV0OwotICAgICAgICAgICAgZlhTRERlc2NyaXB0aW9uLmZBdHRyaWJ1dGVzID0gYXR0cmlidXRlczsKLSAgICAgICAgICAgIGlmIChmTG9jYXRvciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZlhTRERlc2NyaXB0aW9uLnNldEJhc2VTeXN0ZW1JZChmTG9jYXRvci5nZXRFeHBhbmRlZFN5c3RlbUlkKCkpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBNYXA8U3RyaW5nLCBYTUxTY2hlbWFMb2FkZXIuTG9jYXRpb25BcnJheT4gbG9jYXRpb25QYWlycyA9IGZMb2NhdGlvblBhaXJzOwotICAgICAgICAgICAgWE1MU2NoZW1hTG9hZGVyLkxvY2F0aW9uQXJyYXkgbG9jYXRpb25BcnJheSA9Ci0gICAgICAgICAgICAgICAgbG9jYXRpb25QYWlycy5nZXQobmFtZXNwYWNlID09IG51bGwgPyBYTUxTeW1ib2xzLkVNUFRZX1NUUklORyA6IG5hbWVzcGFjZSk7Ci0gICAgICAgICAgICBpZiAobG9jYXRpb25BcnJheSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nW10gdGVtcCA9IGxvY2F0aW9uQXJyYXkuZ2V0TG9jYXRpb25BcnJheSgpOwotICAgICAgICAgICAgICAgIGlmICh0ZW1wLmxlbmd0aCAhPSAwKSB7Ci0gICAgICAgICAgICAgICAgICAgIHNldExvY2F0aW9uSGludHMoZlhTRERlc2NyaXB0aW9uLCB0ZW1wLCBncmFtbWFyKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmIChncmFtbWFyID09IG51bGwgfHwgZlhTRERlc2NyaXB0aW9uLmZMb2NhdGlvbkhpbnRzICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBib29sZWFuIHRvUGFyc2VTY2hlbWEgPSB0cnVlOwotICAgICAgICAgICAgICAgIGlmIChncmFtbWFyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgIC8vIHVzZSBsb2NhdGlvbiBoaW50cyBpbnN0ZWFkCi0gICAgICAgICAgICAgICAgICAgIGxvY2F0aW9uUGFpcnMgPSBDb2xsZWN0aW9ucy5lbXB0eU1hcCgpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8vIHRyeSB0byBwYXJzZSB0aGUgZ3JhbW1hciB1c2luZyBsb2NhdGlvbiBoaW50cyBmcm9tIHRoYXQgbmFtZXNwYWNlLi4KLSAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICBYTUxJbnB1dFNvdXJjZSB4aXMgPQotICAgICAgICAgICAgICAgICAgICAgICAgWE1MU2NoZW1hTG9hZGVyLnJlc29sdmVEb2N1bWVudCgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmWFNERGVzY3JpcHRpb24sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYXRpb25QYWlycywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmRW50aXR5UmVzb2x2ZXIpOwotICAgICAgICAgICAgICAgICAgICBpZiAoZ3JhbW1hciAhPSBudWxsICYmIGZOYW1lc3BhY2VHcm93dGgpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWYgd2UgYXJlIGRlYWxpbmcgd2l0aCBhIGRpZmZlcmVudCBzY2hlbWEgbG9jYXRpb24sIHRoZW4gaW5jbHVkZSB0aGUgbmV3IHNjaGVtYQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGludG8gdGhlIGV4aXN0aW5nIGdyYW1tYXIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZ3JhbW1hci5nZXREb2N1bWVudExvY2F0aW9ucygpLmNvbnRhaW5zKFhNTEVudGl0eU1hbmFnZXIuZXhwYW5kU3lzdGVtSWQoeGlzLmdldFN5c3RlbUlkKCksIHhpcy5nZXRCYXNlU3lzdGVtSWQoKSwgZmFsc2UpKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b1BhcnNlU2NoZW1hID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgY2F0Y2ggKE1hbGZvcm1lZFVSSUV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgaWYgKHRvUGFyc2VTY2hlbWEpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGdyYW1tYXIgPSBmU2NoZW1hTG9hZGVyLmxvYWRTY2hlbWEoZlhTRERlc2NyaXB0aW9uLCB4aXMsIGZMb2NhdGlvblBhaXJzKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7Ci0gICAgICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBbXSBsb2NhdGlvbkhpbnRzID0gZlhTRERlc2NyaXB0aW9uLmdldExvY2F0aW9uSGludHMoKTsKLSAgICAgICAgICAgICAgICAgICAgZlhTSUVycm9yUmVwb3J0ZXIuZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IoCi0gICAgICAgICAgICAgICAgICAgICAgICBYU01lc3NhZ2VGb3JtYXR0ZXIuU0NIRU1BX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICJzY2hlbWFfcmVmZXJlbmNlLjQiLAotICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgbG9jYXRpb25IaW50cyAhPSBudWxsID8gbG9jYXRpb25IaW50c1swXSA6IFhNTFN5bWJvbHMuRU1QVFlfU1RSSU5HIH0sCi0gICAgICAgICAgICAgICAgICAgICAgICBYTUxFcnJvclJlcG9ydGVyLlNFVkVSSVRZX1dBUk5JTkcpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBncmFtbWFyOwotCi0gICAgfSAvL2ZpbmRTY2hlbWFHcmFtbWFyCi0gICAgcHJpdmF0ZSB2b2lkIHNldExvY2F0aW9uSGludHMoWFNERGVzY3JpcHRpb24gZGVzYywgU3RyaW5nW10gbG9jYXRpb25zLCBTY2hlbWFHcmFtbWFyIGdyYW1tYXIpIHsKLSAgICAgICAgaW50IGxlbmd0aCA9IGxvY2F0aW9ucy5sZW5ndGg7Ci0gICAgICAgIGlmIChncmFtbWFyID09IG51bGwpIHsKLSAgICAgICAgICAgIGZYU0REZXNjcmlwdGlvbi5mTG9jYXRpb25IaW50cyA9IG5ldyBTdHJpbmdbbGVuZ3RoXTsKLSAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkobG9jYXRpb25zLCAwLCBmWFNERGVzY3JpcHRpb24uZkxvY2F0aW9uSGludHMsIDAsIGxlbmd0aCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBzZXRMb2NhdGlvbkhpbnRzKGRlc2MsIGxvY2F0aW9ucywgZ3JhbW1hci5nZXREb2N1bWVudExvY2F0aW9ucygpKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBzZXRMb2NhdGlvbkhpbnRzKFhTRERlc2NyaXB0aW9uIGRlc2MsIFN0cmluZ1tdIGxvY2F0aW9ucywgU3RyaW5nTGlzdCBkb2NMb2NhdGlvbnMpIHsKLSAgICAgICAgaW50IGxlbmd0aCA9IGxvY2F0aW9ucy5sZW5ndGg7Ci0gICAgICAgIFN0cmluZ1tdIGhpbnRzID0gbmV3IFN0cmluZ1tsZW5ndGhdOwotICAgICAgICBpbnQgY291bnRlciA9IDA7Ci0KLSAgICAgICAgZm9yIChpbnQgaT0wOyBpPGxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIFN0cmluZyBpZCA9IFhNTEVudGl0eU1hbmFnZXIuZXhwYW5kU3lzdGVtSWQobG9jYXRpb25zW2ldLCBkZXNjLmdldEJhc2VTeXN0ZW1JZCgpLCBmYWxzZSk7Ci0gICAgICAgICAgICAgICAgaWYgKCFkb2NMb2NhdGlvbnMuY29udGFpbnMoaWQpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGhpbnRzW2NvdW50ZXIrK10gPSBsb2NhdGlvbnNbaV07Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2F0Y2ggKE1hbGZvcm1lZFVSSUV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoY291bnRlciA+IDApIHsKLSAgICAgICAgICAgIGlmIChjb3VudGVyID09IGxlbmd0aCkgewotICAgICAgICAgICAgICAgIGZYU0REZXNjcmlwdGlvbi5mTG9jYXRpb25IaW50cyA9IGhpbnRzOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgZlhTRERlc2NyaXB0aW9uLmZMb2NhdGlvbkhpbnRzID0gbmV3IFN0cmluZ1tjb3VudGVyXTsKLSAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGhpbnRzLCAwLCBmWFNERGVzY3JpcHRpb24uZkxvY2F0aW9uSGludHMsIDAsIGNvdW50ZXIpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICBYU1R5cGVEZWZpbml0aW9uIGdldEFuZENoZWNrWHNpVHlwZShRTmFtZSBlbGVtZW50LCBTdHJpbmcgeHNpVHlwZSwgWE1MQXR0cmlidXRlcyBhdHRyaWJ1dGVzKSB7Ci0gICAgICAgIC8vIFRoaXMgbWV0aG9kIGFsc28gZGVhbHMgd2l0aCBjbGF1c2UgMS4yLjEuMiBvZiB0aGUgY29uc3RyYWludAotICAgICAgICAvLyBWYWxpZGF0aW9uIFJ1bGU6IFNjaGVtYS1WYWxpZGl0eSBBc3Nlc3NtZW50IChFbGVtZW50KQotCi0gICAgICAgIC8vIEVsZW1lbnQgTG9jYWxseSBWYWxpZCAoRWxlbWVudCkKLSAgICAgICAgLy8gNCBJZiB0aGVyZSBpcyBhbiBhdHRyaWJ1dGUgaW5mb3JtYXRpb24gaXRlbSBhbW9uZyB0aGUgZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtJ3MgW2F0dHJpYnV0ZXNdIHdob3NlIFtuYW1lc3BhY2UgbmFtZV0gaXMgaWRlbnRpY2FsIHRvIGh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIGFuZCB3aG9zZSBbbG9jYWwgbmFtZV0gaXMgdHlwZSwgdGhlbiBhbGwgb2YgdGhlIGZvbGxvd2luZyBtdXN0IGJlIHRydWU6Ci0gICAgICAgIC8vIDQuMSBUaGUgbm9ybWFsaXplZCB2YWx1ZSBvZiB0aGF0IGF0dHJpYnV0ZSBpbmZvcm1hdGlvbiBpdGVtIG11c3QgYmUgdmFsaWQgd2l0aCByZXNwZWN0IHRvIHRoZSBidWlsdC1pbiBRTmFtZSBzaW1wbGUgdHlwZSwgYXMgZGVmaW5lZCBieSBTdHJpbmcgVmFsaWQgKDMuMTQuNCk7Ci0gICAgICAgIFFOYW1lIHR5cGVOYW1lID0gbnVsbDsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIHR5cGVOYW1lID0gKFFOYW1lKSBmUU5hbWVEVi52YWxpZGF0ZSh4c2lUeXBlLCBmVmFsaWRhdGlvblN0YXRlLCBudWxsKTsKLSAgICAgICAgfSBjYXRjaCAoSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoZS5nZXRLZXkoKSwgZS5nZXRBcmdzKCkpOwotICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoCi0gICAgICAgICAgICAgICAgImN2Yy1lbHQuNC4xIiwKLSAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10gewotICAgICAgICAgICAgICAgICAgICBlbGVtZW50LnJhd25hbWUsCi0gICAgICAgICAgICAgICAgICAgIFNjaGVtYVN5bWJvbHMuVVJJX1hTSSArICIsIiArIFNjaGVtYVN5bWJvbHMuWFNJX1RZUEUsCi0gICAgICAgICAgICAgICAgICAgIHhzaVR5cGUgfSk7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIDQuMiBUaGUgbG9jYWwgbmFtZSBhbmQgbmFtZXNwYWNlIG5hbWUgKGFzIGRlZmluZWQgaW4gUU5hbWUgSW50ZXJwcmV0YXRpb24gKDMuMTUuMykpLCBvZiB0aGUgYWN0dWFsIHZhbHVlIG9mIHRoYXQgYXR0cmlidXRlIGluZm9ybWF0aW9uIGl0ZW0gbXVzdCByZXNvbHZlIHRvIGEgdHlwZSBkZWZpbml0aW9uLCBhcyBkZWZpbmVkIGluIFFOYW1lIHJlc29sdXRpb24gKEluc3RhbmNlKSAoMy4xNS40KQotICAgICAgICBYU1R5cGVEZWZpbml0aW9uIHR5cGUgPSBudWxsOwotICAgICAgICAvLyBpZiB0aGUgbmFtZXNwYWNlIGlzIHNjaGVtYSBuYW1lc3BhY2UsIGZpcnN0IHRyeSBidWlsdC1pbiB0eXBlcwotICAgICAgICBpZiAodHlwZU5hbWUudXJpID09IFNjaGVtYVN5bWJvbHMuVVJJX1NDSEVNQUZPUlNDSEVNQSkgewotICAgICAgICAgICAgdHlwZSA9IFNjaGVtYUdyYW1tYXIuU0dfU2NoZW1hTlMuZ2V0R2xvYmFsVHlwZURlY2wodHlwZU5hbWUubG9jYWxwYXJ0KTsKLSAgICAgICAgfQotICAgICAgICAvLyBpZiBpdCdzIG5vdCBzY2hlbWEgYnVpbHQtaW4gdHlwZXMsIHRoZW4gdHJ5IHRvIGdldCBhIGdyYW1tYXIKLSAgICAgICAgaWYgKHR5cGUgPT0gbnVsbCkgewotICAgICAgICAgICAgLy90cnkgdG8gZmluZCBzY2hlbWEgZ3JhbW1hciBieSBkaWZmZXJlbnQgbWVhbnMuLi4uCi0gICAgICAgICAgICBTY2hlbWFHcmFtbWFyIGdyYW1tYXIgPQotICAgICAgICAgICAgICAgIGZpbmRTY2hlbWFHcmFtbWFyKAotICAgICAgICAgICAgICAgICAgICBYU0REZXNjcmlwdGlvbi5DT05URVhUX1hTSVRZUEUsCi0gICAgICAgICAgICAgICAgICAgIHR5cGVOYW1lLnVyaSwKLSAgICAgICAgICAgICAgICAgICAgZWxlbWVudCwKLSAgICAgICAgICAgICAgICAgICAgdHlwZU5hbWUsCi0gICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXMpOwotCi0gICAgICAgICAgICBpZiAoZ3JhbW1hciAhPSBudWxsKQotICAgICAgICAgICAgICAgIHR5cGUgPSBncmFtbWFyLmdldEdsb2JhbFR5cGVEZWNsKHR5cGVOYW1lLmxvY2FscGFydCk7Ci0gICAgICAgIH0KLSAgICAgICAgLy8gc3RpbGwgY291bGRuJ3QgZmluZCB0aGUgdHlwZSwgcmVwb3J0IGFuIGVycm9yCi0gICAgICAgIGlmICh0eXBlID09IG51bGwpIHsKLSAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKCJjdmMtZWx0LjQuMiIsIG5ldyBPYmplY3RbXSB7IGVsZW1lbnQucmF3bmFtZSwgeHNpVHlwZSB9KTsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gaWYgdGhlcmUgaXMgbm8gY3VycmVudCB0eXBlLCBzZXQgdGhpcyBvbmUgYXMgY3VycmVudC4KLSAgICAgICAgLy8gYW5kIHdlIGRvbid0IG5lZWQgdG8gZG8gZXh0cmEgY2hlY2tpbmcKLSAgICAgICAgaWYgKGZDdXJyZW50VHlwZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAvLyA0LjMgVGhlIGxvY2FsIHR5cGUgZGVmaW5pdGlvbiBtdXN0IGJlIHZhbGlkbHkgZGVyaXZlZCBmcm9tIHRoZSB7dHlwZSBkZWZpbml0aW9ufSBnaXZlbiB0aGUgdW5pb24gb2YgdGhlIHtkaXNhbGxvd2VkIHN1YnN0aXR1dGlvbnN9IGFuZCB0aGUge3R5cGUgZGVmaW5pdGlvbn0ncyB7cHJvaGliaXRlZCBzdWJzdGl0dXRpb25zfSwgYXMgZGVmaW5lZCBpbiBUeXBlIERlcml2YXRpb24gT0sgKENvbXBsZXgpICgzLjQuNikgKGlmIGl0IGlzIGEgY29tcGxleCB0eXBlIGRlZmluaXRpb24pLCBvciBnaXZlbiB7ZGlzYWxsb3dlZCBzdWJzdGl0dXRpb25zfSBhcyBkZWZpbmVkIGluIFR5cGUgRGVyaXZhdGlvbiBPSyAoU2ltcGxlKSAoMy4xNC42KSAoaWYgaXQgaXMgYSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uKS4KLSAgICAgICAgICAgIHNob3J0IGJsb2NrID0gZkN1cnJlbnRFbGVtRGVjbC5mQmxvY2s7Ci0gICAgICAgICAgICBpZiAoZkN1cnJlbnRUeXBlLmdldFR5cGVDYXRlZ29yeSgpID09IFhTVHlwZURlZmluaXRpb24uQ09NUExFWF9UWVBFKQotICAgICAgICAgICAgICAgIGJsb2NrIHw9ICgoWFNDb21wbGV4VHlwZURlY2wpIGZDdXJyZW50VHlwZSkuZkJsb2NrOwotICAgICAgICAgICAgaWYgKCFYU0NvbnN0cmFpbnRzLmNoZWNrVHlwZURlcml2YXRpb25Payh0eXBlLCBmQ3VycmVudFR5cGUsIGJsb2NrKSkKLSAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcigKLSAgICAgICAgICAgICAgICAgICAgImN2Yy1lbHQuNC4zIiwKLSAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgZWxlbWVudC5yYXduYW1lLCB4c2lUeXBlLCBmQ3VycmVudFR5cGUuZ2V0TmFtZSgpfSk7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gdHlwZTsKLSAgICB9IC8vZ2V0QW5kQ2hlY2tYc2lUeXBlCi0KLSAgICBib29sZWFuIGdldFhzaU5pbChRTmFtZSBlbGVtZW50LCBTdHJpbmcgeHNpTmlsKSB7Ci0gICAgICAgIC8vIEVsZW1lbnQgTG9jYWxseSBWYWxpZCAoRWxlbWVudCkKLSAgICAgICAgLy8gMyBUaGUgYXBwcm9wcmlhdGUgY2FzZSBhbW9uZyB0aGUgZm9sbG93aW5nIG11c3QgYmUgdHJ1ZToKLSAgICAgICAgLy8gMy4xIElmIHtuaWxsYWJsZX0gaXMgZmFsc2UsIHRoZW4gdGhlcmUgbXVzdCBiZSBubyBhdHRyaWJ1dGUgaW5mb3JtYXRpb24gaXRlbSBhbW9uZyB0aGUgZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtJ3MgW2F0dHJpYnV0ZXNdIHdob3NlIFtuYW1lc3BhY2UgbmFtZV0gaXMgaWRlbnRpY2FsIHRvIGh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIGFuZCB3aG9zZSBbbG9jYWwgbmFtZV0gaXMgbmlsLgotICAgICAgICBpZiAoZkN1cnJlbnRFbGVtRGVjbCAhPSBudWxsICYmICFmQ3VycmVudEVsZW1EZWNsLmdldE5pbGxhYmxlKCkpIHsKLSAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKAotICAgICAgICAgICAgICAgICJjdmMtZWx0LjMuMSIsCi0gICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsKLSAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5yYXduYW1lLAotICAgICAgICAgICAgICAgICAgICBTY2hlbWFTeW1ib2xzLlVSSV9YU0kgKyAiLCIgKyBTY2hlbWFTeW1ib2xzLlhTSV9OSUwgfSk7Ci0gICAgICAgIH0KLSAgICAgICAgLy8gMy4yIElmIHtuaWxsYWJsZX0gaXMgdHJ1ZSBhbmQgdGhlcmUgaXMgc3VjaCBhbiBhdHRyaWJ1dGUgaW5mb3JtYXRpb24gaXRlbSBhbmQgaXRzIGFjdHVhbCB2YWx1ZSBpcyB0cnVlICwgdGhlbiBhbGwgb2YgdGhlIGZvbGxvd2luZyBtdXN0IGJlIHRydWU6Ci0gICAgICAgIC8vIDMuMi4yIFRoZXJlIG11c3QgYmUgbm8gZml4ZWQge3ZhbHVlIGNvbnN0cmFpbnR9LgotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIFN0cmluZyB2YWx1ZSA9IFhNTENoYXIudHJpbSh4c2lOaWwpOwotICAgICAgICAgICAgaWYgKHZhbHVlLmVxdWFscyhTY2hlbWFTeW1ib2xzLkFUVFZBTF9UUlVFKQotICAgICAgICAgICAgICAgIHx8IHZhbHVlLmVxdWFscyhTY2hlbWFTeW1ib2xzLkFUVFZBTF9UUlVFXzEpKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGZDdXJyZW50RWxlbURlY2wgIT0gbnVsbAotICAgICAgICAgICAgICAgICAgICAmJiBmQ3VycmVudEVsZW1EZWNsLmdldENvbnN0cmFpbnRUeXBlKCkgPT0gWFNDb25zdGFudHMuVkNfRklYRUQpIHsKLSAgICAgICAgICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoCi0gICAgICAgICAgICAgICAgICAgICAgICAiY3ZjLWVsdC4zLjIuMiIsCi0gICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10gewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQucmF3bmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBTY2hlbWFTeW1ib2xzLlVSSV9YU0kgKyAiLCIgKyBTY2hlbWFTeW1ib2xzLlhTSV9OSUwgfSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICB2b2lkIHByb2Nlc3NBdHRyaWJ1dGVzKFFOYW1lIGVsZW1lbnQsIFhNTEF0dHJpYnV0ZXMgYXR0cmlidXRlcywgWFNBdHRyaWJ1dGVHcm91cERlY2wgYXR0ckdycCkgewotCi0gICAgICAgIGlmIChERUJVRykgewotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCI9PT5wcm9jZXNzQXR0cmlidXRlczogIiArIGF0dHJpYnV0ZXMuZ2V0TGVuZ3RoKCkpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gd2hldGhlciB3ZSBoYXZlIHNlZW4gYSBXaWxkY2FyZCBJRC4KLSAgICAgICAgU3RyaW5nIHdpbGRjYXJkSUROYW1lID0gbnVsbDsKLQotICAgICAgICAvLyBmb3IgZWFjaCBwcmVzZW50IGF0dHJpYnV0ZQotICAgICAgICBpbnQgYXR0Q291bnQgPSBhdHRyaWJ1dGVzLmdldExlbmd0aCgpOwotCi0gICAgICAgIEF1Z21lbnRhdGlvbnMgYXVncyA9IG51bGw7Ci0gICAgICAgIEF0dHJpYnV0ZVBTVkltcGwgYXR0clBTVkkgPSBudWxsOwotCi0gICAgICAgIGJvb2xlYW4gaXNTaW1wbGUgPQotICAgICAgICAgICAgZkN1cnJlbnRUeXBlID09IG51bGwgfHwgZkN1cnJlbnRUeXBlLmdldFR5cGVDYXRlZ29yeSgpID09IFhTVHlwZURlZmluaXRpb24uU0lNUExFX1RZUEU7Ci0KLSAgICAgICAgWFNPYmplY3RMaXN0IGF0dHJVc2VzID0gbnVsbDsKLSAgICAgICAgaW50IHVzZUNvdW50ID0gMDsKLSAgICAgICAgWFNXaWxkY2FyZERlY2wgYXR0cldpbGRjYXJkID0gbnVsbDsKLSAgICAgICAgaWYgKCFpc1NpbXBsZSkgewotICAgICAgICAgICAgYXR0clVzZXMgPSBhdHRyR3JwLmdldEF0dHJpYnV0ZVVzZXMoKTsKLSAgICAgICAgICAgIHVzZUNvdW50ID0gYXR0clVzZXMuZ2V0TGVuZ3RoKCk7Ci0gICAgICAgICAgICBhdHRyV2lsZGNhcmQgPSBhdHRyR3JwLmZBdHRyaWJ1dGVXQzsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIEVsZW1lbnQgTG9jYWxseSBWYWxpZCAoQ29tcGxleCBUeXBlKQotICAgICAgICAvLyAzIEZvciBlYWNoIGF0dHJpYnV0ZSBpbmZvcm1hdGlvbiBpdGVtIGluIHRoZSBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0ncyBbYXR0cmlidXRlc10gZXhjZXB0aW5nIHRob3NlIHdob3NlIFtuYW1lc3BhY2UgbmFtZV0gaXMgaWRlbnRpY2FsIHRvIGh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIGFuZCB3aG9zZSBbbG9jYWwgbmFtZV0gaXMgb25lIG9mIHR5cGUsIG5pbCwgc2NoZW1hTG9jYXRpb24gb3Igbm9OYW1lc3BhY2VTY2hlbWFMb2NhdGlvbiwgdGhlIGFwcHJvcHJpYXRlIGNhc2UgYW1vbmcgdGhlIGZvbGxvd2luZyBtdXN0IGJlIHRydWU6Ci0gICAgICAgIC8vIGdldCB0aGUgY29ycmVzcG9uZGluZyBhdHRyaWJ1dGUgZGVjbAotICAgICAgICBmb3IgKGludCBpbmRleCA9IDA7IGluZGV4IDwgYXR0Q291bnQ7IGluZGV4KyspIHsKLQotICAgICAgICAgICAgYXR0cmlidXRlcy5nZXROYW1lKGluZGV4LCBmVGVtcFFOYW1lKTsKLQotICAgICAgICAgICAgaWYgKERFQlVHKSB7Ci0gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCI9PT5wcm9jZXNzIGF0dHJpYnV0ZTogIiArIGZUZW1wUU5hbWUpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAoZkF1Z1BTVkkgfHwgZklkQ29uc3RyYWludCkgewotICAgICAgICAgICAgICAgIGF1Z3MgPSBhdHRyaWJ1dGVzLmdldEF1Z21lbnRhdGlvbnMoaW5kZXgpOwotICAgICAgICAgICAgICAgIGF0dHJQU1ZJID0gKEF0dHJpYnV0ZVBTVkltcGwpIGF1Z3MuZ2V0SXRlbShDb25zdGFudHMuQVRUUklCVVRFX1BTVkkpOwotICAgICAgICAgICAgICAgIGlmIChhdHRyUFNWSSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGF0dHJQU1ZJLnJlc2V0KCk7Ci0gICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgYXR0clBTVkkgPSBuZXcgQXR0cmlidXRlUFNWSW1wbCgpOwotICAgICAgICAgICAgICAgICAgICBhdWdzLnB1dEl0ZW0oQ29uc3RhbnRzLkFUVFJJQlVURV9QU1ZJLCBhdHRyUFNWSSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIC8vIFBTVkkgYXR0cmlidXRlOiB2YWxpZGF0aW9uIGNvbnRleHQKLSAgICAgICAgICAgICAgICBhdHRyUFNWSS5mVmFsaWRhdGlvbkNvbnRleHQgPSBmVmFsaWRhdGlvblJvb3Q7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIEVsZW1lbnQgTG9jYWxseSBWYWxpZCAoVHlwZSkKLSAgICAgICAgICAgIC8vIDMuMS4xIFRoZSBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0ncyBbYXR0cmlidXRlc10gbXVzdCBiZSBlbXB0eSwgZXhjZXB0aW5nIHRob3NlCi0gICAgICAgICAgICAvLyB3aG9zZSBbbmFtZXNwYWNlIG5hbWVdIGlzIGlkZW50aWNhbCB0byBodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZSBhbmQKLSAgICAgICAgICAgIC8vIHdob3NlIFtsb2NhbCBuYW1lXSBpcyBvbmUgb2YgdHlwZSwgbmlsLCBzY2hlbWFMb2NhdGlvbiBvciBub05hbWVzcGFjZVNjaGVtYUxvY2F0aW9uLgotCi0gICAgICAgICAgICAvLyBmb3IgdGhlIDQgeHNpIGF0dHJpYnV0ZXMsIGdldCBhcHByb3ByaWF0ZSBkZWNsLCBhbmQgdmFsaWRhdGUKLSAgICAgICAgICAgIGlmIChmVGVtcFFOYW1lLnVyaSA9PSBTY2hlbWFTeW1ib2xzLlVSSV9YU0kpIHsKLSAgICAgICAgICAgICAgICBYU0F0dHJpYnV0ZURlY2wgYXR0ckRlY2wgPSBudWxsOwotICAgICAgICAgICAgICAgIGlmIChmVGVtcFFOYW1lLmxvY2FscGFydCA9PSBTY2hlbWFTeW1ib2xzLlhTSV9TQ0hFTUFMT0NBVElPTikKLSAgICAgICAgICAgICAgICAgICAgYXR0ckRlY2wgPQotICAgICAgICAgICAgICAgICAgICAgICAgU2NoZW1hR3JhbW1hci5TR19YU0kuZ2V0R2xvYmFsQXR0cmlidXRlRGVjbCgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBTY2hlbWFTeW1ib2xzLlhTSV9TQ0hFTUFMT0NBVElPTik7Ci0gICAgICAgICAgICAgICAgZWxzZSBpZiAoZlRlbXBRTmFtZS5sb2NhbHBhcnQgPT0gU2NoZW1hU3ltYm9scy5YU0lfTk9OQU1FU1BBQ0VTQ0hFTUFMT0NBVElPTikKLSAgICAgICAgICAgICAgICAgICAgYXR0ckRlY2wgPQotICAgICAgICAgICAgICAgICAgICAgICAgU2NoZW1hR3JhbW1hci5TR19YU0kuZ2V0R2xvYmFsQXR0cmlidXRlRGVjbCgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBTY2hlbWFTeW1ib2xzLlhTSV9OT05BTUVTUEFDRVNDSEVNQUxPQ0FUSU9OKTsKLSAgICAgICAgICAgICAgICBlbHNlIGlmIChmVGVtcFFOYW1lLmxvY2FscGFydCA9PSBTY2hlbWFTeW1ib2xzLlhTSV9OSUwpCi0gICAgICAgICAgICAgICAgICAgIGF0dHJEZWNsID0gU2NoZW1hR3JhbW1hci5TR19YU0kuZ2V0R2xvYmFsQXR0cmlidXRlRGVjbChTY2hlbWFTeW1ib2xzLlhTSV9OSUwpOwotICAgICAgICAgICAgICAgIGVsc2UgaWYgKGZUZW1wUU5hbWUubG9jYWxwYXJ0ID09IFNjaGVtYVN5bWJvbHMuWFNJX1RZUEUpCi0gICAgICAgICAgICAgICAgICAgIGF0dHJEZWNsID0gU2NoZW1hR3JhbW1hci5TR19YU0kuZ2V0R2xvYmFsQXR0cmlidXRlRGVjbChTY2hlbWFTeW1ib2xzLlhTSV9UWVBFKTsKLSAgICAgICAgICAgICAgICBpZiAoYXR0ckRlY2wgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBwcm9jZXNzT25lQXR0cmlidXRlKGVsZW1lbnQsIGF0dHJpYnV0ZXMsIGluZGV4LCBhdHRyRGVjbCwgbnVsbCwgYXR0clBTVkkpOwotICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIGZvciBuYW1lc3BhY2UgYXR0cmlidXRlcywgbm9fdmFsaWRhdGlvbi91bmtub3dfdmFsaWRpdHkKLSAgICAgICAgICAgIGlmIChmVGVtcFFOYW1lLnJhd25hbWUgPT0gWE1MU3ltYm9scy5QUkVGSVhfWE1MTlMKLSAgICAgICAgICAgICAgICB8fCBmVGVtcFFOYW1lLnJhd25hbWUuc3RhcnRzV2l0aCgieG1sbnM6IikpIHsKLSAgICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gc2ltcGxlIHR5cGUgZG9lc24ndCBhbGxvdyBhbnkgb3RoZXIgYXR0cmlidXRlcwotICAgICAgICAgICAgaWYgKGlzU2ltcGxlKSB7Ci0gICAgICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoCi0gICAgICAgICAgICAgICAgICAgICJjdmMtdHlwZS4zLjEuMSIsCi0gICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7IGVsZW1lbnQucmF3bmFtZSwgZlRlbXBRTmFtZS5yYXduYW1lIH0pOwotICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBpdCdzIG5vdCB4bWxucywgYW5kIG5vdCB4c2ksIHRoZW4gd2UgbmVlZCB0byBmaW5kIGEgZGVjbCBmb3IgaXQKLSAgICAgICAgICAgIFhTQXR0cmlidXRlVXNlSW1wbCBjdXJyVXNlID0gbnVsbCwgb25lVXNlOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB1c2VDb3VudDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgb25lVXNlID0gKFhTQXR0cmlidXRlVXNlSW1wbCkgYXR0clVzZXMuaXRlbShpKTsKLSAgICAgICAgICAgICAgICBpZiAob25lVXNlLmZBdHRyRGVjbC5mTmFtZSA9PSBmVGVtcFFOYW1lLmxvY2FscGFydAotICAgICAgICAgICAgICAgICAgICAmJiBvbmVVc2UuZkF0dHJEZWNsLmZUYXJnZXROYW1lc3BhY2UgPT0gZlRlbXBRTmFtZS51cmkpIHsKLSAgICAgICAgICAgICAgICAgICAgY3VyclVzZSA9IG9uZVVzZTsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyAzLjIgb3RoZXJ3aXNlIGFsbCBvZiB0aGUgZm9sbG93aW5nIG11c3QgYmUgdHJ1ZToKLSAgICAgICAgICAgIC8vIDMuMi4xIFRoZXJlIG11c3QgYmUgYW4ge2F0dHJpYnV0ZSB3aWxkY2FyZH0uCi0gICAgICAgICAgICAvLyAzLjIuMiBUaGUgYXR0cmlidXRlIGluZm9ybWF0aW9uIGl0ZW0gbXVzdCBiZSB2YWxpZCB3aXRoIHJlc3BlY3QgdG8gaXQgYXMgZGVmaW5lZCBpbiBJdGVtIFZhbGlkIChXaWxkY2FyZCkgKDMuMTAuNCkuCi0KLSAgICAgICAgICAgIC8vIGlmIGZhaWxlZCwgZ2V0IGl0IGZyb20gd2lsZGNhcmQKLSAgICAgICAgICAgIGlmIChjdXJyVXNlID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAvL2lmIChhdHRyV2lsZGNhcmQgPT0gbnVsbCkKLSAgICAgICAgICAgICAgICAvLyAgICByZXBvcnRTY2hlbWFFcnJvcigiY3ZjLWNvbXBsZXgtdHlwZS4zLjIuMSIsIG5ldyBPYmplY3RbXXtlbGVtZW50LnJhd25hbWUsIGZUZW1wUU5hbWUucmF3bmFtZX0pOwotICAgICAgICAgICAgICAgIGlmIChhdHRyV2lsZGNhcmQgPT0gbnVsbCB8fCAhYXR0cldpbGRjYXJkLmFsbG93TmFtZXNwYWNlKGZUZW1wUU5hbWUudXJpKSkgewotICAgICAgICAgICAgICAgICAgICAvLyBzbyB0aGlzIGF0dHJpYnV0ZSBpcyBub3QgYWxsb3dlZAotICAgICAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcigKLSAgICAgICAgICAgICAgICAgICAgICAgICJjdmMtY29tcGxleC10eXBlLjMuMi4yIiwKLSAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7IGVsZW1lbnQucmF3bmFtZSwgZlRlbXBRTmFtZS5yYXduYW1lIH0pOwotICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIFhTQXR0cmlidXRlRGVjbCBjdXJyRGVjbCA9IG51bGw7Ci0gICAgICAgICAgICBpZiAoY3VyclVzZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgY3VyckRlY2wgPSBjdXJyVXNlLmZBdHRyRGVjbDsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgLy8gd2hpY2ggbWVhbnMgaXQgbWF0Y2hlcyBhIHdpbGRjYXJkCi0gICAgICAgICAgICAgICAgLy8gc2tpcCBpdCBpZiBwcm9jZXNzQ29udGVudHMgaXMgc2tpcAotICAgICAgICAgICAgICAgIGlmIChhdHRyV2lsZGNhcmQuZlByb2Nlc3NDb250ZW50cyA9PSBYU1dpbGRjYXJkRGVjbC5QQ19TS0lQKQotICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKLQotICAgICAgICAgICAgICAgIC8vdHJ5IHRvIGZpbmQgZ3JhbW1hciBieSBkaWZmZXJlbnQgbWVhbnMuLi4KLSAgICAgICAgICAgICAgICBTY2hlbWFHcmFtbWFyIGdyYW1tYXIgPQotICAgICAgICAgICAgICAgICAgICBmaW5kU2NoZW1hR3JhbW1hcigKLSAgICAgICAgICAgICAgICAgICAgICAgIFhTRERlc2NyaXB0aW9uLkNPTlRFWFRfQVRUUklCVVRFLAotICAgICAgICAgICAgICAgICAgICAgICAgZlRlbXBRTmFtZS51cmksCi0gICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50LAotICAgICAgICAgICAgICAgICAgICAgICAgZlRlbXBRTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXMpOwotCi0gICAgICAgICAgICAgICAgaWYgKGdyYW1tYXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBjdXJyRGVjbCA9IGdyYW1tYXIuZ2V0R2xvYmFsQXR0cmlidXRlRGVjbChmVGVtcFFOYW1lLmxvY2FscGFydCk7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgLy8gaWYgY2FuJ3QgZmluZAotICAgICAgICAgICAgICAgIGlmIChjdXJyRGVjbCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIGlmIHN0cmljdCwgcmVwb3J0IGVycm9yCi0gICAgICAgICAgICAgICAgICAgIGlmIChhdHRyV2lsZGNhcmQuZlByb2Nlc3NDb250ZW50cyA9PSBYU1dpbGRjYXJkRGVjbC5QQ19TVFJJQ1QpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICJjdmMtY29tcGxleC10eXBlLjMuMi4yIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBlbGVtZW50LnJhd25hbWUsIGZUZW1wUU5hbWUucmF3bmFtZSB9KTsKLSAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgIC8vIHRoZW4gY29udGludWUgdG8gdGhlIG5leHQgYXR0cmlidXRlCi0gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIDUgTGV0IFtEZWZpbml0aW9uOl0gIHRoZSB3aWxkIElEcyBiZSB0aGUgc2V0IG9mIGFsbCBhdHRyaWJ1dGUgaW5mb3JtYXRpb24gaXRlbSB0byB3aGljaCBjbGF1c2UgMy4yIGFwcGxpZWQgYW5kIHdob3NlIHZhbGlkYXRpb24gcmVzdWx0ZWQgaW4gYSBjb250ZXh0LWRldGVybWluZWQgZGVjbGFyYXRpb24gb2YgbXVzdEZpbmQgb3Igbm8gY29udGV4dC1kZXRlcm1pbmVkIGRlY2xhcmF0aW9uIGF0IGFsbCwgYW5kIHdob3NlIFtsb2NhbCBuYW1lXSBhbmQgW25hbWVzcGFjZSBuYW1lXSByZXNvbHZlIChhcyBkZWZpbmVkIGJ5IFFOYW1lIHJlc29sdXRpb24gKEluc3RhbmNlKSAoMy4xNS40KSkgdG8gYW4gYXR0cmlidXRlIGRlY2xhcmF0aW9uIHdob3NlIHt0eXBlIGRlZmluaXRpb259IGlzIG9yIGlzIGRlcml2ZWQgZnJvbSBJRC4gVGhlbiBhbGwgb2YgdGhlIGZvbGxvd2luZyBtdXN0IGJlIHRydWU6Ci0gICAgICAgICAgICAgICAgICAgIC8vIDUuMSBUaGVyZSBtdXN0IGJlIG5vIG1vcmUgdGhhbiBvbmUgaXRlbSBpbiB3aWxkIElEcy4KLSAgICAgICAgICAgICAgICAgICAgaWYgKGN1cnJEZWNsLmZUeXBlLmdldFR5cGVDYXRlZ29yeSgpID09IFhTVHlwZURlZmluaXRpb24uU0lNUExFX1RZUEUKLSAgICAgICAgICAgICAgICAgICAgICAgICYmICgoWFNTaW1wbGVUeXBlKSBjdXJyRGVjbC5mVHlwZSkuaXNJRFR5cGUoKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHdpbGRjYXJkSUROYW1lICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcigKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImN2Yy1jb21wbGV4LXR5cGUuNS4xIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgZWxlbWVudC5yYXduYW1lLCBjdXJyRGVjbC5mTmFtZSwgd2lsZGNhcmRJRE5hbWUgfSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWxkY2FyZElETmFtZSA9IGN1cnJEZWNsLmZOYW1lOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBwcm9jZXNzT25lQXR0cmlidXRlKGVsZW1lbnQsIGF0dHJpYnV0ZXMsIGluZGV4LCBjdXJyRGVjbCwgY3VyclVzZSwgYXR0clBTVkkpOwotICAgICAgICB9IC8vIGVuZCBvZiBmb3IgKGFsbCBhdHRyaWJ1dGVzKQotCi0gICAgICAgIC8vIDUuMiBJZiB3aWxkIElEcyBpcyBub24tZW1wdHksIHRoZXJlIG11c3Qgbm90IGJlIGFueSBhdHRyaWJ1dGUgdXNlcyBhbW9uZyB0aGUge2F0dHJpYnV0ZSB1c2VzfSB3aG9zZSB7YXR0cmlidXRlIGRlY2xhcmF0aW9ufSdzIHt0eXBlIGRlZmluaXRpb259IGlzIG9yIGlzIGRlcml2ZWQgZnJvbSBJRC4KLSAgICAgICAgaWYgKCFpc1NpbXBsZSAmJiBhdHRyR3JwLmZJREF0dHJOYW1lICE9IG51bGwgJiYgd2lsZGNhcmRJRE5hbWUgIT0gbnVsbCkgewotICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoCi0gICAgICAgICAgICAgICAgImN2Yy1jb21wbGV4LXR5cGUuNS4yIiwKLSAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBlbGVtZW50LnJhd25hbWUsIHdpbGRjYXJkSUROYW1lLCBhdHRyR3JwLmZJREF0dHJOYW1lIH0pOwotICAgICAgICB9Ci0KLSAgICB9IC8vcHJvY2Vzc0F0dHJpYnV0ZXMKLQotICAgIHZvaWQgcHJvY2Vzc09uZUF0dHJpYnV0ZSgKLSAgICAgICAgUU5hbWUgZWxlbWVudCwKLSAgICAgICAgWE1MQXR0cmlidXRlcyBhdHRyaWJ1dGVzLAotICAgICAgICBpbnQgaW5kZXgsCi0gICAgICAgIFhTQXR0cmlidXRlRGVjbCBjdXJyRGVjbCwKLSAgICAgICAgWFNBdHRyaWJ1dGVVc2VJbXBsIGN1cnJVc2UsCi0gICAgICAgIEF0dHJpYnV0ZVBTVkltcGwgYXR0clBTVkkpIHsKLQotICAgICAgICBTdHJpbmcgYXR0clZhbHVlID0gYXR0cmlidXRlcy5nZXRWYWx1ZShpbmRleCk7Ci0gICAgICAgIGZYU0lFcnJvclJlcG9ydGVyLnB1c2hDb250ZXh0KCk7Ci0KLSAgICAgICAgLy8gQXR0cmlidXRlIExvY2FsbHkgVmFsaWQKLSAgICAgICAgLy8gRm9yIGFuIGF0dHJpYnV0ZSBpbmZvcm1hdGlvbiBpdGVtIHRvIGJlIGxvY2FsbHkgdmFsaWQgd2l0aCByZXNwZWN0IHRvIGFuIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbiBhbGwgb2YgdGhlIGZvbGxvd2luZyBtdXN0IGJlIHRydWU6Ci0gICAgICAgIC8vIDEgVGhlIGRlY2xhcmF0aW9uIG11c3Qgbm90IGJlIGFic2VudCAoc2VlIE1pc3NpbmcgU3ViLWNvbXBvbmVudHMgKDUuMykgZm9yIGhvdyB0aGlzIGNhbiBmYWlsIHRvIGJlIHRoZSBjYXNlKS4KLSAgICAgICAgLy8gMiBJdHMge3R5cGUgZGVmaW5pdGlvbn0gbXVzdCBub3QgYmUgYWJzZW50LgotICAgICAgICAvLyAzIFRoZSBpdGVtJ3Mgbm9ybWFsaXplZCB2YWx1ZSBtdXN0IGJlIGxvY2FsbHkgdmFsaWQgd2l0aCByZXNwZWN0IHRvIHRoYXQge3R5cGUgZGVmaW5pdGlvbn0gYXMgcGVyIFN0cmluZyBWYWxpZCAoMy4xNC40KS4KLSAgICAgICAgLy8gZ2V0IHNpbXBsZSB0eXBlCi0gICAgICAgIFhTU2ltcGxlVHlwZSBhdHREViA9IGN1cnJEZWNsLmZUeXBlOwotCi0gICAgICAgIE9iamVjdCBhY3R1YWxWYWx1ZSA9IG51bGw7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBhY3R1YWxWYWx1ZSA9IGF0dERWLnZhbGlkYXRlKGF0dHJWYWx1ZSwgZlZhbGlkYXRpb25TdGF0ZSwgZlZhbGlkYXRlZEluZm8pOwotICAgICAgICAgICAgLy8gc3RvcmUgdGhlIG5vcm1hbGl6ZWQgdmFsdWUKLSAgICAgICAgICAgIGlmIChmTm9ybWFsaXplRGF0YSkKLSAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzLnNldFZhbHVlKGluZGV4LCBmVmFsaWRhdGVkSW5mby5ub3JtYWxpemVkVmFsdWUpOwotICAgICAgICAgICAgaWYgKGF0dHJpYnV0ZXMgaW5zdGFuY2VvZiBYTUxBdHRyaWJ1dGVzSW1wbCkgewotICAgICAgICAgICAgICAgIFhNTEF0dHJpYnV0ZXNJbXBsIGF0dHJzID0gKFhNTEF0dHJpYnV0ZXNJbXBsKSBhdHRyaWJ1dGVzOwotICAgICAgICAgICAgICAgIGJvb2xlYW4gc2NoZW1hSWQgPQotICAgICAgICAgICAgICAgICAgICBmVmFsaWRhdGVkSW5mby5tZW1iZXJUeXBlICE9IG51bGwKLSAgICAgICAgICAgICAgICAgICAgICAgID8gZlZhbGlkYXRlZEluZm8ubWVtYmVyVHlwZS5pc0lEVHlwZSgpCi0gICAgICAgICAgICAgICAgICAgICAgICA6IGF0dERWLmlzSURUeXBlKCk7Ci0gICAgICAgICAgICAgICAgYXR0cnMuc2V0U2NoZW1hSWQoaW5kZXgsIHNjaGVtYUlkKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gUFNWSTogZWxlbWVudCBub3RhdGlvbgotICAgICAgICAgICAgaWYgKGF0dERWLmdldFZhcmlldHkoKSA9PSBYU1NpbXBsZVR5cGUuVkFSSUVUWV9BVE9NSUMKLSAgICAgICAgICAgICAgICAmJiBhdHREVi5nZXRQcmltaXRpdmVLaW5kKCkgPT0gWFNTaW1wbGVUeXBlLlBSSU1JVElWRV9OT1RBVElPTikgewotICAgICAgICAgICAgICAgIFFOYW1lIHFOYW1lID0gKFFOYW1lKSBhY3R1YWxWYWx1ZTsKLSAgICAgICAgICAgICAgICBTY2hlbWFHcmFtbWFyIGdyYW1tYXIgPSBmR3JhbW1hckJ1Y2tldC5nZXRHcmFtbWFyKHFOYW1lLnVyaSk7Ci0KLSAgICAgICAgICAgICAgICAvL1JFVklTSVQ6IGlzIGl0IHBvc3NpYmxlIGZvciB0aGUgbm90YXRpb24gdG8gYmUgaW4gZGlmZmVyZW50IG5hbWVzcGFjZSB0aGFuIHRoZSBhdHRyaWJ1dGUKLSAgICAgICAgICAgICAgICAvL3dpdGggd2hpY2ggaXQgaXMgYXNzb2NpYXRlZCwgQ0hFQ0sgISEgIDxmb2YgbjE6YXR0MSA9ICJuMjpub3RhdGlvbjEiIC4uPgotICAgICAgICAgICAgICAgIC8vIHNob3VsZCB3ZSBnaXZlIGNoYW5jZSB0byB0aGUgYXBwbGljYXRpb24gdG8gYmUgYWJsZSB0byAgcmV0cmlldmUgYSBncmFtbWFyIC0gbmIKLSAgICAgICAgICAgICAgICAvL1JFVklTSVQ6IHdoYXQgd291bGQgYmUgdGhlIHRyaWdnZXJpbmcgY29tcG9uZW50IGhlcmUuLiBpZiBpdCBpcyBhdHRyaWJ1dGUgdmFsdWUgdGhhdAotICAgICAgICAgICAgICAgIC8vIHRyaWdnZXJlZCB0aGUgbG9hZGluZyBvZiBncmFtbWFyID8/IC1uYgotCi0gICAgICAgICAgICAgICAgaWYgKGdyYW1tYXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBmTm90YXRpb24gPSBncmFtbWFyLmdldEdsb2JhbE5vdGF0aW9uRGVjbChxTmFtZS5sb2NhbHBhcnQpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfSBjYXRjaCAoSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24gaWR2ZSkgewotICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoaWR2ZS5nZXRLZXkoKSwgaWR2ZS5nZXRBcmdzKCkpOwotICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoCi0gICAgICAgICAgICAgICAgImN2Yy1hdHRyaWJ1dGUuMyIsCi0gICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgZWxlbWVudC5yYXduYW1lLCBmVGVtcFFOYW1lLnJhd25hbWUsIGF0dHJWYWx1ZSwgYXR0RFYuZ2V0TmFtZSgpfSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBnZXQgdGhlIHZhbHVlIGNvbnN0cmFpbnQgZnJvbSB1c2Ugb3IgZGVjbAotICAgICAgICAvLyA0IFRoZSBpdGVtJ3MgYWN0dWFsIHZhbHVlIG11c3QgbWF0Y2ggdGhlIHZhbHVlIG9mIHRoZSB7dmFsdWUgY29uc3RyYWludH0sIGlmIGl0IGlzIHByZXNlbnQgYW5kIGZpeGVkLiAgICAgICAgICAgICAgICAgLy8gbm93IGNoZWNrIHRoZSB2YWx1ZSBhZ2FpbnN0IHRoZSBzaW1wbGVUeXBlCi0gICAgICAgIGlmIChhY3R1YWxWYWx1ZSAhPSBudWxsICYmIGN1cnJEZWNsLmdldENvbnN0cmFpbnRUeXBlKCkgPT0gWFNDb25zdGFudHMuVkNfRklYRUQpIHsKLSAgICAgICAgICAgIGlmICghaXNDb21wYXJhYmxlKGZWYWxpZGF0ZWRJbmZvLCBjdXJyRGVjbC5mRGVmYXVsdCkgfHwgIWFjdHVhbFZhbHVlLmVxdWFscyhjdXJyRGVjbC5mRGVmYXVsdC5hY3R1YWxWYWx1ZSkpIHsKLSAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcigKLSAgICAgICAgICAgICAgICAgICAgImN2Yy1hdHRyaWJ1dGUuNCIsCi0gICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50LnJhd25hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICBmVGVtcFFOYW1lLnJhd25hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICBhdHRyVmFsdWUsCi0gICAgICAgICAgICAgICAgICAgICAgICBjdXJyRGVjbC5mRGVmYXVsdC5zdHJpbmdWYWx1ZSgpfSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyAzLjEgSWYgdGhlcmUgaXMgYW1vbmcgdGhlIHthdHRyaWJ1dGUgdXNlc30gYW4gYXR0cmlidXRlIHVzZSB3aXRoIGFuIHthdHRyaWJ1dGUgZGVjbGFyYXRpb259IHdob3NlIHtuYW1lfSBtYXRjaGVzIHRoZSBhdHRyaWJ1dGUgaW5mb3JtYXRpb24gaXRlbSdzIFtsb2NhbCBuYW1lXSBhbmQgd2hvc2Uge3RhcmdldCBuYW1lc3BhY2V9IGlzIGlkZW50aWNhbCB0byB0aGUgYXR0cmlidXRlIGluZm9ybWF0aW9uIGl0ZW0ncyBbbmFtZXNwYWNlIG5hbWVdICh3aGVyZSBhbiBhYnNlbnQge3RhcmdldCBuYW1lc3BhY2V9IGlzIHRha2VuIHRvIGJlIGlkZW50aWNhbCB0byBhIFtuYW1lc3BhY2UgbmFtZV0gd2l0aCBubyB2YWx1ZSksIHRoZW4gdGhlIGF0dHJpYnV0ZSBpbmZvcm1hdGlvbiBtdXN0IGJlIHZhbGlkIHdpdGggcmVzcGVjdCB0byB0aGF0IGF0dHJpYnV0ZSB1c2UgYXMgcGVyIEF0dHJpYnV0ZSBMb2NhbGx5IFZhbGlkIChVc2UpICgzLjUuNCkuIEluIHRoaXMgY2FzZSB0aGUge2F0dHJpYnV0ZSBkZWNsYXJhdGlvbn0gb2YgdGhhdCBhdHRyaWJ1dGUgdXNlIGlzIHRoZSBjb250ZXh0LWRldGVybWluZWQgZGVjbGFyYXRpb24gZm9yIHRoZSBhdHRyaWJ1dGUgaW5mb3JtYXRpb24gaXRlbSB3aXRoIHJlc3BlY3QgdG8gU2NoZW1hLVZhbGlkaXR5IEFzc2Vzc21lbnQgKEF0dHJpYnV0ZSkgKDMuMi40KSBhbmQgQXNzZXNzbWVudCBPdXRjb21lIChBdHRyaWJ1dGUpICgzLjIuNSkuCi0gICAgICAgIGlmIChhY3R1YWxWYWx1ZSAhPSBudWxsCi0gICAgICAgICAgICAmJiBjdXJyVXNlICE9IG51bGwKLSAgICAgICAgICAgICYmIGN1cnJVc2UuZkNvbnN0cmFpbnRUeXBlID09IFhTQ29uc3RhbnRzLlZDX0ZJWEVEKSB7Ci0gICAgICAgICAgICBpZiAoIWlzQ29tcGFyYWJsZShmVmFsaWRhdGVkSW5mbywgY3VyclVzZS5mRGVmYXVsdCkgfHwgIWFjdHVhbFZhbHVlLmVxdWFscyhjdXJyVXNlLmZEZWZhdWx0LmFjdHVhbFZhbHVlKSkgewotICAgICAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKAotICAgICAgICAgICAgICAgICAgICAiY3ZjLWNvbXBsZXgtdHlwZS4zLjEiLAotICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10gewotICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5yYXduYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgZlRlbXBRTmFtZS5yYXduYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgYXR0clZhbHVlLAotICAgICAgICAgICAgICAgICAgICAgICAgY3VyclVzZS5mRGVmYXVsdC5zdHJpbmdWYWx1ZSgpfSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGZJZENvbnN0cmFpbnQpIHsKLSAgICAgICAgICAgIGF0dHJQU1ZJLmZBY3R1YWxWYWx1ZSA9IGFjdHVhbFZhbHVlOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKGZBdWdQU1ZJKSB7Ci0gICAgICAgICAgICAvLyBQU1ZJOiBhdHRyaWJ1dGUgZGVjbGFyYXRpb24KLSAgICAgICAgICAgIGF0dHJQU1ZJLmZEZWNsYXJhdGlvbiA9IGN1cnJEZWNsOwotICAgICAgICAgICAgLy8gUFNWSTogYXR0cmlidXRlIHR5cGUKLSAgICAgICAgICAgIGF0dHJQU1ZJLmZUeXBlRGVjbCA9IGF0dERWOwotCi0gICAgICAgICAgICAvLyBQU1ZJOiBhdHRyaWJ1dGUgbWVtYmVyVHlwZQotICAgICAgICAgICAgYXR0clBTVkkuZk1lbWJlclR5cGUgPSBmVmFsaWRhdGVkSW5mby5tZW1iZXJUeXBlOwotICAgICAgICAgICAgLy8gUFNWSTogYXR0cmlidXRlIG5vcm1hbGl6ZWQgdmFsdWUKLSAgICAgICAgICAgIC8vIE5PVEU6IHdlIGFsd2F5cyBzdG9yZSB0aGUgbm9ybWFsaXplZCB2YWx1ZSwgZXZlbiBpZiBpdCdzIGludmxpZCwKLSAgICAgICAgICAgIC8vIGJlY2F1c2UgaXQgbWlnaHQgc3RpbGwgYmUgdXNlZnVsIHRvIHRoZSB1c2VyLiBCdXQgd2hlbiB0aGUgaXQncwotICAgICAgICAgICAgLy8gbm90IHZhbGlkLCB0aGUgbm9ybWFsaXplZCB2YWx1ZSBpcyBub3QgdHJ1c3RhYmxlLgotICAgICAgICAgICAgYXR0clBTVkkuZk5vcm1hbGl6ZWRWYWx1ZSA9IGZWYWxpZGF0ZWRJbmZvLm5vcm1hbGl6ZWRWYWx1ZTsKLSAgICAgICAgICAgIGF0dHJQU1ZJLmZBY3R1YWxWYWx1ZSA9IGZWYWxpZGF0ZWRJbmZvLmFjdHVhbFZhbHVlOwotICAgICAgICAgICAgYXR0clBTVkkuZkFjdHVhbFZhbHVlVHlwZSA9IGZWYWxpZGF0ZWRJbmZvLmFjdHVhbFZhbHVlVHlwZTsKLSAgICAgICAgICAgIGF0dHJQU1ZJLmZJdGVtVmFsdWVUeXBlcyA9IGZWYWxpZGF0ZWRJbmZvLml0ZW1WYWx1ZVR5cGVzOwotCi0KLQotICAgICAgICAgICAgLy8gUFNWSTogdmFsaWRhdGlvbiBhdHRlbXB0ZWQ6Ci0gICAgICAgICAgICBhdHRyUFNWSS5mVmFsaWRhdGlvbkF0dGVtcHRlZCA9IEF0dHJpYnV0ZVBTVkkuVkFMSURBVElPTl9GVUxMOwotCi0gICAgICAgICAgICBTdHJpbmdbXSBlcnJvcnMgPSBmWFNJRXJyb3JSZXBvcnRlci5tZXJnZUNvbnRleHQoKTsKLSAgICAgICAgICAgIC8vIFBTVkk6IGVycm9yIGNvZGVzCi0gICAgICAgICAgICBhdHRyUFNWSS5mRXJyb3JDb2RlcyA9IGVycm9yczsKLSAgICAgICAgICAgIC8vIFBTVkk6IHZhbGlkaXR5Ci0gICAgICAgICAgICBhdHRyUFNWSS5mVmFsaWRpdHkgPQotICAgICAgICAgICAgICAgIChlcnJvcnMgPT0gbnVsbCkgPyBBdHRyaWJ1dGVQU1ZJLlZBTElESVRZX1ZBTElEIDogQXR0cmlidXRlUFNWSS5WQUxJRElUWV9JTlZBTElEOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgdm9pZCBhZGREZWZhdWx0QXR0cmlidXRlcygKLSAgICAgICAgUU5hbWUgZWxlbWVudCwKLSAgICAgICAgWE1MQXR0cmlidXRlcyBhdHRyaWJ1dGVzLAotICAgICAgICBYU0F0dHJpYnV0ZUdyb3VwRGVjbCBhdHRyR3JwKSB7Ci0gICAgICAgIC8vIENoZWNrIGFmdGVyIGFsbCBzcGVjaWZpZWQgYXR0cnMgYXJlIHNjYW5uZWQKLSAgICAgICAgLy8gKDEpIHJlcG9ydCBlcnJvciBmb3IgUkVRVUlSRUQgYXR0cnMgdGhhdCBhcmUgbWlzc2luZyAoVl9UQUdjKQotICAgICAgICAvLyBSRVZJU0lUOiBzaG91bGQgd2UgY2hlY2sgcHJvaGliaXRlZCBhdHRyaWJ1dGVzPwotICAgICAgICAvLyAoMikgcmVwb3J0IGVycm9yIGZvciBQUk9ISUJJVEVEIGF0dHJzIHRoYXQgYXJlIHByZXNlbnQgKFZfVEFHYykKLSAgICAgICAgLy8gKDMpIGFkZCBkZWZhdWx0IGF0dHJzIChGSVhFRCBhbmQgTk9UX0ZJWEVEKQotICAgICAgICAvLwotICAgICAgICBpZiAoREVCVUcpIHsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiPT0+YWRkRGVmYXVsdEF0dHJpYnV0ZXM6ICIgKyBlbGVtZW50KTsKLSAgICAgICAgfQotICAgICAgICBYU09iamVjdExpc3QgYXR0clVzZXMgPSBhdHRyR3JwLmdldEF0dHJpYnV0ZVVzZXMoKTsKLSAgICAgICAgaW50IHVzZUNvdW50ID0gYXR0clVzZXMuZ2V0TGVuZ3RoKCk7Ci0gICAgICAgIFhTQXR0cmlidXRlVXNlSW1wbCBjdXJyVXNlOwotICAgICAgICBYU0F0dHJpYnV0ZURlY2wgY3VyckRlY2w7Ci0gICAgICAgIHNob3J0IGNvbnN0VHlwZTsKLSAgICAgICAgVmFsaWRhdGVkSW5mbyBkZWZhdWx0VmFsdWU7Ci0gICAgICAgIGJvb2xlYW4gaXNTcGVjaWZpZWQ7Ci0gICAgICAgIFFOYW1lIGF0dE5hbWU7Ci0gICAgICAgIC8vIGZvciBlYWNoIGF0dHJpYnV0ZSB1c2UKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB1c2VDb3VudDsgaSsrKSB7Ci0KLSAgICAgICAgICAgIGN1cnJVc2UgPSAoWFNBdHRyaWJ1dGVVc2VJbXBsKSBhdHRyVXNlcy5pdGVtKGkpOwotICAgICAgICAgICAgY3VyckRlY2wgPSBjdXJyVXNlLmZBdHRyRGVjbDsKLSAgICAgICAgICAgIC8vIGdldCB2YWx1ZSBjb25zdHJhaW50Ci0gICAgICAgICAgICBjb25zdFR5cGUgPSBjdXJyVXNlLmZDb25zdHJhaW50VHlwZTsKLSAgICAgICAgICAgIGRlZmF1bHRWYWx1ZSA9IGN1cnJVc2UuZkRlZmF1bHQ7Ci0gICAgICAgICAgICBpZiAoY29uc3RUeXBlID09IFhTQ29uc3RhbnRzLlZDX05PTkUpIHsKLSAgICAgICAgICAgICAgICBjb25zdFR5cGUgPSBjdXJyRGVjbC5nZXRDb25zdHJhaW50VHlwZSgpOwotICAgICAgICAgICAgICAgIGRlZmF1bHRWYWx1ZSA9IGN1cnJEZWNsLmZEZWZhdWx0OwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gd2hldGhlciB0aGlzIGF0dHJpYnV0ZSBpcyBzcGVjaWZpZWQKLSAgICAgICAgICAgIGlzU3BlY2lmaWVkID0gYXR0cmlidXRlcy5nZXRWYWx1ZShjdXJyRGVjbC5mVGFyZ2V0TmFtZXNwYWNlLCBjdXJyRGVjbC5mTmFtZSkgIT0gbnVsbDsKLQotICAgICAgICAgICAgLy8gRWxlbWVudCBMb2NhbGx5IFZhbGlkIChDb21wbGV4IFR5cGUpCi0gICAgICAgICAgICAvLyA0IFRoZSB7YXR0cmlidXRlIGRlY2xhcmF0aW9ufSBvZiBlYWNoIGF0dHJpYnV0ZSB1c2UgaW4gdGhlIHthdHRyaWJ1dGUgdXNlc30gd2hvc2UKLSAgICAgICAgICAgIC8vIHtyZXF1aXJlZH0gaXMgdHJ1ZSBtYXRjaGVzIG9uZSBvZiB0aGUgYXR0cmlidXRlIGluZm9ybWF0aW9uIGl0ZW1zIGluIHRoZSBlbGVtZW50Ci0gICAgICAgICAgICAvLyBpbmZvcm1hdGlvbiBpdGVtJ3MgW2F0dHJpYnV0ZXNdIGFzIHBlciBjbGF1c2UgMy4xIGFib3ZlLgotICAgICAgICAgICAgaWYgKGN1cnJVc2UuZlVzZSA9PSBTY2hlbWFTeW1ib2xzLlVTRV9SRVFVSVJFRCkgewotICAgICAgICAgICAgICAgIGlmICghaXNTcGVjaWZpZWQpCi0gICAgICAgICAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKAotICAgICAgICAgICAgICAgICAgICAgICAgImN2Yy1jb21wbGV4LXR5cGUuNCIsCi0gICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBlbGVtZW50LnJhd25hbWUsIGN1cnJEZWNsLmZOYW1lIH0pOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gaWYgdGhlIGF0dHJpYnV0ZSBpcyBub3Qgc3BlY2lmaWVkLCB0aGVuIGFwcGx5IHRoZSB2YWx1ZSBjb25zdHJhaW50Ci0gICAgICAgICAgICBpZiAoIWlzU3BlY2lmaWVkICYmIGNvbnN0VHlwZSAhPSBYU0NvbnN0YW50cy5WQ19OT05FKSB7Ci0gICAgICAgICAgICAgICAgYXR0TmFtZSA9Ci0gICAgICAgICAgICAgICAgICAgIG5ldyBRTmFtZShudWxsLCBjdXJyRGVjbC5mTmFtZSwgY3VyckRlY2wuZk5hbWUsIGN1cnJEZWNsLmZUYXJnZXROYW1lc3BhY2UpOwotICAgICAgICAgICAgICAgIFN0cmluZyBub3JtYWxpemVkID0gKGRlZmF1bHRWYWx1ZSAhPSBudWxsKSA/IGRlZmF1bHRWYWx1ZS5zdHJpbmdWYWx1ZSgpIDogIiI7Ci0gICAgICAgICAgICAgICAgaW50IGF0dHJJbmRleCA9IGF0dHJpYnV0ZXMuYWRkQXR0cmlidXRlKGF0dE5hbWUsICJDREFUQSIsIG5vcm1hbGl6ZWQpOwotICAgICAgICAgICAgICAgIGlmIChhdHRyaWJ1dGVzIGluc3RhbmNlb2YgWE1MQXR0cmlidXRlc0ltcGwpIHsKLSAgICAgICAgICAgICAgICAgICAgWE1MQXR0cmlidXRlc0ltcGwgYXR0cnMgPSAoWE1MQXR0cmlidXRlc0ltcGwpIGF0dHJpYnV0ZXM7Ci0gICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gc2NoZW1hSWQgPQotICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdFZhbHVlICE9IG51bGwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiBkZWZhdWx0VmFsdWUubWVtYmVyVHlwZSAhPSBudWxsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gZGVmYXVsdFZhbHVlLm1lbWJlclR5cGUuaXNJRFR5cGUoKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IGN1cnJEZWNsLmZUeXBlLmlzSURUeXBlKCk7Ci0gICAgICAgICAgICAgICAgICAgIGF0dHJzLnNldFNjaGVtYUlkKGF0dHJJbmRleCwgc2NoZW1hSWQpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIGlmIChmQXVnUFNWSSkgewotCi0gICAgICAgICAgICAgICAgICAgIC8vIFBTVkk6IGF0dHJpYnV0ZSBpcyAic2NoZW1hIiBzcGVjaWZpZWQKLSAgICAgICAgICAgICAgICAgICAgQXVnbWVudGF0aW9ucyBhdWdzID0gYXR0cmlidXRlcy5nZXRBdWdtZW50YXRpb25zKGF0dHJJbmRleCk7Ci0gICAgICAgICAgICAgICAgICAgIEF0dHJpYnV0ZVBTVkltcGwgYXR0clBTVkkgPSBuZXcgQXR0cmlidXRlUFNWSW1wbCgpOwotICAgICAgICAgICAgICAgICAgICBhdWdzLnB1dEl0ZW0oQ29uc3RhbnRzLkFUVFJJQlVURV9QU1ZJLCBhdHRyUFNWSSk7Ci0KLSAgICAgICAgICAgICAgICAgICAgYXR0clBTVkkuZkRlY2xhcmF0aW9uID0gY3VyckRlY2w7Ci0gICAgICAgICAgICAgICAgICAgIGF0dHJQU1ZJLmZUeXBlRGVjbCA9IGN1cnJEZWNsLmZUeXBlOwotICAgICAgICAgICAgICAgICAgICBhdHRyUFNWSS5mTWVtYmVyVHlwZSA9IGRlZmF1bHRWYWx1ZS5tZW1iZXJUeXBlOwotICAgICAgICAgICAgICAgICAgICBhdHRyUFNWSS5mTm9ybWFsaXplZFZhbHVlID0gbm9ybWFsaXplZDsKLSAgICAgICAgICAgICAgICAgICAgYXR0clBTVkkuZkFjdHVhbFZhbHVlID0gZGVmYXVsdFZhbHVlLmFjdHVhbFZhbHVlOwotICAgICAgICAgICAgICAgICAgICBhdHRyUFNWSS5mQWN0dWFsVmFsdWVUeXBlID0gZGVmYXVsdFZhbHVlLmFjdHVhbFZhbHVlVHlwZTsKLSAgICAgICAgICAgICAgICAgICAgYXR0clBTVkkuZkl0ZW1WYWx1ZVR5cGVzID0gZGVmYXVsdFZhbHVlLml0ZW1WYWx1ZVR5cGVzOwotICAgICAgICAgICAgICAgICAgICBhdHRyUFNWSS5mVmFsaWRhdGlvbkNvbnRleHQgPSBmVmFsaWRhdGlvblJvb3Q7Ci0gICAgICAgICAgICAgICAgICAgIGF0dHJQU1ZJLmZWYWxpZGl0eSA9IEF0dHJpYnV0ZVBTVkkuVkFMSURJVFlfVkFMSUQ7Ci0gICAgICAgICAgICAgICAgICAgIGF0dHJQU1ZJLmZWYWxpZGF0aW9uQXR0ZW1wdGVkID0gQXR0cmlidXRlUFNWSS5WQUxJREFUSU9OX0ZVTEw7Ci0gICAgICAgICAgICAgICAgICAgIGF0dHJQU1ZJLmZTcGVjaWZpZWQgPSB0cnVlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICB9IC8vIGZvcgotICAgIH0gLy8gYWRkRGVmYXVsdEF0dHJpYnV0ZXMKLQotICAgIC8qKgotICAgICAqICBJZiB0aGVyZSBpcyBub3QgdGV4dCBjb250ZW50LCBhbmQgdGhlcmUgaXMgYQotICAgICAqICB7dmFsdWUgY29uc3RyYWludH0gb24gdGhlIGNvcnJlc3BvbmRpbmcgZWxlbWVudCBkZWNsLCB0aGVuIHJldHVybgotICAgICAqICBhbiBYTUxTdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBkZWZhdWx0IHZhbHVlLgotICAgICAqLwotICAgIHZvaWQgcHJvY2Vzc0VsZW1lbnRDb250ZW50KFFOYW1lIGVsZW1lbnQpIHsKLSAgICAgICAgLy8gMSBJZiB0aGUgaXRlbSBpcyA/dmFsaWQ/IHdpdGggcmVzcGVjdCB0byBhbiBlbGVtZW50IGRlY2xhcmF0aW9uIGFzIHBlciBFbGVtZW50IExvY2FsbHkgVmFsaWQgKEVsZW1lbnQpICg/My4zLjQpIGFuZCB0aGUge3ZhbHVlIGNvbnN0cmFpbnR9IGlzIHByZXNlbnQsIGJ1dCBjbGF1c2UgMy4yIG9mIEVsZW1lbnQgTG9jYWxseSBWYWxpZCAoRWxlbWVudCkgKD8zLjMuNCkgYWJvdmUgaXMgbm90IHNhdGlzZmllZCBhbmQgdGhlIGl0ZW0gaGFzIG5vIGVsZW1lbnQgb3IgY2hhcmFjdGVyIGluZm9ybWF0aW9uIGl0ZW0gW2NoaWxkcmVuXSwgdGhlbiBzY2hlbWEuIEZ1cnRoZXJtb3JlLCB0aGUgcG9zdC1zY2hlbWEtdmFsaWRhdGlvbiBpbmZvc2V0IGhhcyB0aGUgY2Fub25pY2FsIGxleGljYWwgcmVwcmVzZW50YXRpb24gb2YgdGhlIHt2YWx1ZSBjb25zdHJhaW50fSB2YWx1ZSBhcyB0aGUgaXRlbSdzIFtzY2hlbWEgbm9ybWFsaXplZCB2YWx1ZV0gcHJvcGVydHkuCi0gICAgICAgIGlmIChmQ3VycmVudEVsZW1EZWNsICE9IG51bGwKLSAgICAgICAgICAgICYmIGZDdXJyZW50RWxlbURlY2wuZkRlZmF1bHQgIT0gbnVsbAotICAgICAgICAgICAgJiYgIWZTYXdUZXh0Ci0gICAgICAgICAgICAmJiAhZlN1YkVsZW1lbnQKLSAgICAgICAgICAgICYmICFmTmlsKSB7Ci0KLSAgICAgICAgICAgIFN0cmluZyBzdHJ2ID0gZkN1cnJlbnRFbGVtRGVjbC5mRGVmYXVsdC5zdHJpbmdWYWx1ZSgpOwotICAgICAgICAgICAgaW50IGJ1ZkxlbiA9IHN0cnYubGVuZ3RoKCk7Ci0gICAgICAgICAgICBpZiAoZk5vcm1hbGl6ZWRTdHIuY2ggPT0gbnVsbCB8fCBmTm9ybWFsaXplZFN0ci5jaC5sZW5ndGggPCBidWZMZW4pIHsKLSAgICAgICAgICAgICAgICBmTm9ybWFsaXplZFN0ci5jaCA9IG5ldyBjaGFyW2J1Zkxlbl07Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBzdHJ2LmdldENoYXJzKDAsIGJ1ZkxlbiwgZk5vcm1hbGl6ZWRTdHIuY2gsIDApOwotICAgICAgICAgICAgZk5vcm1hbGl6ZWRTdHIub2Zmc2V0ID0gMDsKLSAgICAgICAgICAgIGZOb3JtYWxpemVkU3RyLmxlbmd0aCA9IGJ1ZkxlbjsKLSAgICAgICAgICAgIGZEZWZhdWx0VmFsdWUgPSBmTm9ybWFsaXplZFN0cjsKLSAgICAgICAgfQotICAgICAgICAvLyBmaXhlZCB2YWx1ZXMgYXJlIGhhbmRsZWQgbGF0ZXIsIGFmdGVyIHhzaTp0eXBlIGRldGVybWluZWQuCi0KLSAgICAgICAgZlZhbGlkYXRlZEluZm8ubm9ybWFsaXplZFZhbHVlID0gbnVsbDsKLQotICAgICAgICAvLyBFbGVtZW50IExvY2FsbHkgVmFsaWQgKEVsZW1lbnQpCi0gICAgICAgIC8vIDMuMi4xIFRoZSBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0gbXVzdCBoYXZlIG5vIGNoYXJhY3RlciBvciBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0gW2NoaWxkcmVuXS4KLSAgICAgICAgaWYgKGZOaWwpIHsKLSAgICAgICAgICAgIGlmIChmU3ViRWxlbWVudCB8fCBmU2F3VGV4dCkgewotICAgICAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKAotICAgICAgICAgICAgICAgICAgICAiY3ZjLWVsdC4zLjIuMSIsCi0gICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50LnJhd25hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICBTY2hlbWFTeW1ib2xzLlVSSV9YU0kgKyAiLCIgKyBTY2hlbWFTeW1ib2xzLlhTSV9OSUwgfSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICB0aGlzLmZWYWxpZGF0ZWRJbmZvLnJlc2V0KCk7Ci0KLSAgICAgICAgLy8gNSBUaGUgYXBwcm9wcmlhdGUgY2FzZSBhbW9uZyB0aGUgZm9sbG93aW5nIG11c3QgYmUgdHJ1ZToKLSAgICAgICAgLy8gNS4xIElmIHRoZSBkZWNsYXJhdGlvbiBoYXMgYSB7dmFsdWUgY29uc3RyYWludH0sIHRoZSBpdGVtIGhhcyBuZWl0aGVyIGVsZW1lbnQgbm9yIGNoYXJhY3RlciBbY2hpbGRyZW5dIGFuZCBjbGF1c2UgMy4yIGhhcyBub3QgYXBwbGllZCwgdGhlbiBhbGwgb2YgdGhlIGZvbGxvd2luZyBtdXN0IGJlIHRydWU6Ci0gICAgICAgIGlmIChmQ3VycmVudEVsZW1EZWNsICE9IG51bGwKLSAgICAgICAgICAgICYmIGZDdXJyZW50RWxlbURlY2wuZ2V0Q29uc3RyYWludFR5cGUoKSAhPSBYU0NvbnN0YW50cy5WQ19OT05FCi0gICAgICAgICAgICAmJiAhZlN1YkVsZW1lbnQKLSAgICAgICAgICAgICYmICFmU2F3VGV4dAotICAgICAgICAgICAgJiYgIWZOaWwpIHsKLSAgICAgICAgICAgIC8vIDUuMS4xIElmIHRoZSBhY3R1YWwgdHlwZSBkZWZpbml0aW9uIGlzIGEgbG9jYWwgdHlwZSBkZWZpbml0aW9uIHRoZW4gdGhlIGNhbm9uaWNhbCBsZXhpY2FsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSB7dmFsdWUgY29uc3RyYWludH0gdmFsdWUgbXVzdCBiZSBhIHZhbGlkIGRlZmF1bHQgZm9yIHRoZSBhY3R1YWwgdHlwZSBkZWZpbml0aW9uIGFzIGRlZmluZWQgaW4gRWxlbWVudCBEZWZhdWx0IFZhbGlkIChJbW1lZGlhdGUpICgzLjMuNikuCi0gICAgICAgICAgICBpZiAoZkN1cnJlbnRUeXBlICE9IGZDdXJyZW50RWxlbURlY2wuZlR5cGUpIHsKLSAgICAgICAgICAgICAgICAvL1JFVklTSVQ6d2Ugc2hvdWxkIHBhc3MgVmFsaWRhdGVkSW5mbyBoZXJlLgotICAgICAgICAgICAgICAgIGlmIChYU0NvbnN0cmFpbnRzCi0gICAgICAgICAgICAgICAgICAgIC5FbGVtZW50RGVmYXVsdFZhbGlkSW1tZWRpYXRlKAotICAgICAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRUeXBlLAotICAgICAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbGVtRGVjbC5mRGVmYXVsdC5zdHJpbmdWYWx1ZSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgZlN0YXRlNFhzaVR5cGUsCi0gICAgICAgICAgICAgICAgICAgICAgICBudWxsKQotICAgICAgICAgICAgICAgICAgICA9PSBudWxsKQotICAgICAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcigKLSAgICAgICAgICAgICAgICAgICAgICAgICJjdmMtZWx0LjUuMS4xIiwKLSAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5yYXduYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZDdXJyZW50VHlwZS5nZXROYW1lKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbGVtRGVjbC5mRGVmYXVsdC5zdHJpbmdWYWx1ZSgpfSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyA1LjEuMiBUaGUgZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIHdpdGggdGhlIGNhbm9uaWNhbCBsZXhpY2FsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSB7dmFsdWUgY29uc3RyYWludH0gdmFsdWUgdXNlZCBhcyBpdHMgbm9ybWFsaXplZCB2YWx1ZSBtdXN0IGJlIHZhbGlkIHdpdGggcmVzcGVjdCB0byB0aGUgYWN0dWFsIHR5cGUgZGVmaW5pdGlvbiBhcyBkZWZpbmVkIGJ5IEVsZW1lbnQgTG9jYWxseSBWYWxpZCAoVHlwZSkgKDMuMy40KS4KLSAgICAgICAgICAgIC8vIFJFVklTSVQ6IGRvbid0IHVzZSB0b1N0cmluZywgYnV0IHZhbGlkYXRlQWN0dWFsVmFsdWUgaW5zdGVhZAotICAgICAgICAgICAgLy8gICAgICAgICAgdXNlIHRoZSBmU3RhdGU0QXBwbHlEZWZhdWx0Ci0gICAgICAgICAgICBlbGVtZW50TG9jYWxseVZhbGlkVHlwZShlbGVtZW50LCBmQ3VycmVudEVsZW1EZWNsLmZEZWZhdWx0LnN0cmluZ1ZhbHVlKCkpOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgLy8gVGhlIGZvbGxvd2luZyBtZXRob2QgY2FsbCBhbHNvIGRlYWwgd2l0aCBjbGF1c2UgMS4yLjIgb2YgdGhlIGNvbnN0cmFpbnQKLSAgICAgICAgICAgIC8vIFZhbGlkYXRpb24gUnVsZTogU2NoZW1hLVZhbGlkaXR5IEFzc2Vzc21lbnQgKEVsZW1lbnQpCi0KLSAgICAgICAgICAgIC8vIDUuMiBJZiB0aGUgZGVjbGFyYXRpb24gaGFzIG5vIHt2YWx1ZSBjb25zdHJhaW50fSBvciB0aGUgaXRlbSBoYXMgZWl0aGVyIGVsZW1lbnQgb3IgY2hhcmFjdGVyIFtjaGlsZHJlbl0gb3IgY2xhdXNlIDMuMiBoYXMgYXBwbGllZCwgdGhlbiBhbGwgb2YgdGhlIGZvbGxvd2luZyBtdXN0IGJlIHRydWU6Ci0gICAgICAgICAgICAvLyA1LjIuMSBUaGUgZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIG11c3QgYmUgdmFsaWQgd2l0aCByZXNwZWN0IHRvIHRoZSBhY3R1YWwgdHlwZSBkZWZpbml0aW9uIGFzIGRlZmluZWQgYnkgRWxlbWVudCBMb2NhbGx5IFZhbGlkIChUeXBlKSAoMy4zLjQpLgotICAgICAgICAgICAgT2JqZWN0IGFjdHVhbFZhbHVlID0gZWxlbWVudExvY2FsbHlWYWxpZFR5cGUoZWxlbWVudCwgZkJ1ZmZlcik7Ci0gICAgICAgICAgICAvLyA1LjIuMiBJZiB0aGVyZSBpcyBhIGZpeGVkIHt2YWx1ZSBjb25zdHJhaW50fSBhbmQgY2xhdXNlIDMuMiBoYXMgbm90IGFwcGxpZWQsIGFsbCBvZiB0aGUgZm9sbG93aW5nIG11c3QgYmUgdHJ1ZToKLSAgICAgICAgICAgIGlmIChmQ3VycmVudEVsZW1EZWNsICE9IG51bGwKLSAgICAgICAgICAgICAgICAmJiBmQ3VycmVudEVsZW1EZWNsLmdldENvbnN0cmFpbnRUeXBlKCkgPT0gWFNDb25zdGFudHMuVkNfRklYRUQKLSAgICAgICAgICAgICAgICAmJiAhZk5pbCkgewotICAgICAgICAgICAgICAgIFN0cmluZyBjb250ZW50ID0gZkJ1ZmZlci50b1N0cmluZygpOwotICAgICAgICAgICAgICAgIC8vIDUuMi4yLjEgVGhlIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSBtdXN0IGhhdmUgbm8gZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIFtjaGlsZHJlbl0uCi0gICAgICAgICAgICAgICAgaWYgKGZTdWJFbGVtZW50KQotICAgICAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcigiY3ZjLWVsdC41LjIuMi4xIiwgbmV3IE9iamVjdFtdIHsgZWxlbWVudC5yYXduYW1lIH0pOwotICAgICAgICAgICAgICAgIC8vIDUuMi4yLjIgVGhlIGFwcHJvcHJpYXRlIGNhc2UgYW1vbmcgdGhlIGZvbGxvd2luZyBtdXN0IGJlIHRydWU6Ci0gICAgICAgICAgICAgICAgaWYgKGZDdXJyZW50VHlwZS5nZXRUeXBlQ2F0ZWdvcnkoKSA9PSBYU1R5cGVEZWZpbml0aW9uLkNPTVBMRVhfVFlQRSkgewotICAgICAgICAgICAgICAgICAgICBYU0NvbXBsZXhUeXBlRGVjbCBjdHlwZSA9IChYU0NvbXBsZXhUeXBlRGVjbCkgZkN1cnJlbnRUeXBlOwotICAgICAgICAgICAgICAgICAgICAvLyA1LjIuMi4yLjEgSWYgdGhlIHtjb250ZW50IHR5cGV9IG9mIHRoZSBhY3R1YWwgdHlwZSBkZWZpbml0aW9uIGlzIG1peGVkLCB0aGVuIHRoZSBpbml0aWFsIHZhbHVlIG9mIHRoZSBpdGVtIG11c3QgbWF0Y2ggdGhlIGNhbm9uaWNhbCBsZXhpY2FsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSB7dmFsdWUgY29uc3RyYWludH0gdmFsdWUuCi0gICAgICAgICAgICAgICAgICAgIGlmIChjdHlwZS5mQ29udGVudFR5cGUgPT0gWFNDb21wbGV4VHlwZURlY2wuQ09OVEVOVFRZUEVfTUlYRUQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJFVklTSVQ6IGhvdyB0byBnZXQgdGhlIGluaXRpYWwgdmFsdWUsIGRvZXMgd2hpdGVTcGFjZSBjb3VudD8KLSAgICAgICAgICAgICAgICAgICAgICAgIGlmICghZkN1cnJlbnRFbGVtRGVjbC5mRGVmYXVsdC5ub3JtYWxpemVkVmFsdWUuZXF1YWxzKGNvbnRlbnQpKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiY3ZjLWVsdC41LjIuMi4yLjEiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10gewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5yYXduYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RWxlbURlY2wuZkRlZmF1bHQubm9ybWFsaXplZFZhbHVlIH0pOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIC8vIDUuMi4yLjIuMiBJZiB0aGUge2NvbnRlbnQgdHlwZX0gb2YgdGhlIGFjdHVhbCB0eXBlIGRlZmluaXRpb24gaXMgYSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uLCB0aGVuIHRoZSBhY3R1YWwgdmFsdWUgb2YgdGhlIGl0ZW0gbXVzdCBtYXRjaCB0aGUgY2Fub25pY2FsIGxleGljYWwgcmVwcmVzZW50YXRpb24gb2YgdGhlIHt2YWx1ZSBjb25zdHJhaW50fSB2YWx1ZS4KLSAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoY3R5cGUuZkNvbnRlbnRUeXBlID09IFhTQ29tcGxleFR5cGVEZWNsLkNPTlRFTlRUWVBFX1NJTVBMRSkgewotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFjdHVhbFZhbHVlICE9IG51bGwgJiYgKCFpc0NvbXBhcmFibGUoZlZhbGlkYXRlZEluZm8sIGZDdXJyZW50RWxlbURlY2wuZkRlZmF1bHQpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8ICFhY3R1YWxWYWx1ZS5lcXVhbHMoZkN1cnJlbnRFbGVtRGVjbC5mRGVmYXVsdC5hY3R1YWxWYWx1ZSkpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJjdmMtZWx0LjUuMi4yLjIuMiIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50LnJhd25hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbGVtRGVjbC5mRGVmYXVsdC5zdHJpbmdWYWx1ZSgpfSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGZDdXJyZW50VHlwZS5nZXRUeXBlQ2F0ZWdvcnkoKSA9PSBYU1R5cGVEZWZpbml0aW9uLlNJTVBMRV9UWVBFKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChhY3R1YWxWYWx1ZSAhPSBudWxsICYmICghaXNDb21wYXJhYmxlKGZWYWxpZGF0ZWRJbmZvLCBmQ3VycmVudEVsZW1EZWNsLmZEZWZhdWx0KQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8ICFhY3R1YWxWYWx1ZS5lcXVhbHMoZkN1cnJlbnRFbGVtRGVjbC5mRGVmYXVsdC5hY3R1YWxWYWx1ZSkpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBSRVZJU0lUOiB0aGUgc3BlYyBkaWRuJ3QgbWVudGlvbiB0aGlzIGNhc2U6IGZpeGVkCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyAgICAgICAgICB2YWx1ZSB3aXRoIHNpbXBsZSB0eXBlCi0gICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcigKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAiY3ZjLWVsdC41LjIuMi4yLjIiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQucmF3bmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbGVtRGVjbC5mRGVmYXVsdC5zdHJpbmdWYWx1ZSgpfSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoZkRlZmF1bHRWYWx1ZSA9PSBudWxsICYmIGZOb3JtYWxpemVEYXRhICYmIGZEb2N1bWVudEhhbmRsZXIgIT0gbnVsbCAmJiBmVW5pb25UeXBlKSB7Ci0gICAgICAgICAgICAvLyBmb3IgdW5pb24gdHlwZXMgd2UgbmVlZCB0byBzZW5kIGRhdGEgYmVjYXVzZSB3ZSBkZWxheWVkIHNlbmRpbmcKLSAgICAgICAgICAgIC8vIHRoaXMgZGF0YSB3aGVuIHdlIHJlY2VpdmVkIGl0IGluIHRoZSBjaGFyYWN0ZXJzKCkgY2FsbC4KLSAgICAgICAgICAgIFN0cmluZyBjb250ZW50ID0gZlZhbGlkYXRlZEluZm8ubm9ybWFsaXplZFZhbHVlOwotICAgICAgICAgICAgaWYgKGNvbnRlbnQgPT0gbnVsbCkKLSAgICAgICAgICAgICAgICBjb250ZW50ID0gZkJ1ZmZlci50b1N0cmluZygpOwotCi0gICAgICAgICAgICBpbnQgYnVmTGVuID0gY29udGVudC5sZW5ndGgoKTsKLSAgICAgICAgICAgIGlmIChmTm9ybWFsaXplZFN0ci5jaCA9PSBudWxsIHx8IGZOb3JtYWxpemVkU3RyLmNoLmxlbmd0aCA8IGJ1ZkxlbikgewotICAgICAgICAgICAgICAgIGZOb3JtYWxpemVkU3RyLmNoID0gbmV3IGNoYXJbYnVmTGVuXTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNvbnRlbnQuZ2V0Q2hhcnMoMCwgYnVmTGVuLCBmTm9ybWFsaXplZFN0ci5jaCwgMCk7Ci0gICAgICAgICAgICBmTm9ybWFsaXplZFN0ci5vZmZzZXQgPSAwOwotICAgICAgICAgICAgZk5vcm1hbGl6ZWRTdHIubGVuZ3RoID0gYnVmTGVuOwotICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci5jaGFyYWN0ZXJzKGZOb3JtYWxpemVkU3RyLCBudWxsKTsKLSAgICAgICAgfQotICAgIH0gLy8gcHJvY2Vzc0VsZW1lbnRDb250ZW50Ci0KLSAgICBPYmplY3QgZWxlbWVudExvY2FsbHlWYWxpZFR5cGUoUU5hbWUgZWxlbWVudCwgT2JqZWN0IHRleHRDb250ZW50KSB7Ci0gICAgICAgIGlmIChmQ3VycmVudFR5cGUgPT0gbnVsbCkKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotCi0gICAgICAgIE9iamVjdCByZXRWYWx1ZSA9IG51bGw7Ci0gICAgICAgIC8vIEVsZW1lbnQgTG9jYWxseSBWYWxpZCAoVHlwZSkKLSAgICAgICAgLy8gMyBUaGUgYXBwcm9wcmlhdGUgY2FzZSBhbW9uZyB0aGUgZm9sbG93aW5nIG11c3QgYmUgdHJ1ZToKLSAgICAgICAgLy8gMy4xIElmIHRoZSB0eXBlIGRlZmluaXRpb24gaXMgYSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uLCB0aGVuIGFsbCBvZiB0aGUgZm9sbG93aW5nIG11c3QgYmUgdHJ1ZToKLSAgICAgICAgaWYgKGZDdXJyZW50VHlwZS5nZXRUeXBlQ2F0ZWdvcnkoKSA9PSBYU1R5cGVEZWZpbml0aW9uLlNJTVBMRV9UWVBFKSB7Ci0gICAgICAgICAgICAvLyAzLjEuMiBUaGUgZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIG11c3QgaGF2ZSBubyBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0gW2NoaWxkcmVuXS4KLSAgICAgICAgICAgIGlmIChmU3ViRWxlbWVudCkKLSAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcigiY3ZjLXR5cGUuMy4xLjIiLCBuZXcgT2JqZWN0W10geyBlbGVtZW50LnJhd25hbWUgfSk7Ci0gICAgICAgICAgICAvLyAzLjEuMyBJZiBjbGF1c2UgMy4yIG9mIEVsZW1lbnQgTG9jYWxseSBWYWxpZCAoRWxlbWVudCkgKDMuMy40KSBkaWQgbm90IGFwcGx5LCB0aGVuIHRoZSBub3JtYWxpemVkIHZhbHVlIG11c3QgYmUgdmFsaWQgd2l0aCByZXNwZWN0IHRvIHRoZSB0eXBlIGRlZmluaXRpb24gYXMgZGVmaW5lZCBieSBTdHJpbmcgVmFsaWQgKDMuMTQuNCkuCi0gICAgICAgICAgICBpZiAoIWZOaWwpIHsKLSAgICAgICAgICAgICAgICBYU1NpbXBsZVR5cGUgZHYgPSAoWFNTaW1wbGVUeXBlKSBmQ3VycmVudFR5cGU7Ci0gICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKCFmTm9ybWFsaXplRGF0YSB8fCBmVW5pb25UeXBlKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmVmFsaWRhdGlvblN0YXRlLnNldE5vcm1hbGl6YXRpb25SZXF1aXJlZCh0cnVlKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICByZXRWYWx1ZSA9IGR2LnZhbGlkYXRlKHRleHRDb250ZW50LCBmVmFsaWRhdGlvblN0YXRlLCBmVmFsaWRhdGVkSW5mbyk7Ci0gICAgICAgICAgICAgICAgfSBjYXRjaCAoSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcihlLmdldEtleSgpLCBlLmdldEFyZ3MoKSk7Ci0gICAgICAgICAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKAotICAgICAgICAgICAgICAgICAgICAgICAgImN2Yy10eXBlLjMuMS4zIiwKLSAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7IGVsZW1lbnQucmF3bmFtZSwgdGV4dENvbnRlbnQgfSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgLy8gMy4yIElmIHRoZSB0eXBlIGRlZmluaXRpb24gaXMgYSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbiwgdGhlbiB0aGUgZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIG11c3QgYmUgdmFsaWQgd2l0aCByZXNwZWN0IHRvIHRoZSB0eXBlIGRlZmluaXRpb24gYXMgcGVyIEVsZW1lbnQgTG9jYWxseSBWYWxpZCAoQ29tcGxleCBUeXBlKSAoMy40LjQpOwotICAgICAgICAgICAgcmV0VmFsdWUgPSBlbGVtZW50TG9jYWxseVZhbGlkQ29tcGxleFR5cGUoZWxlbWVudCwgdGV4dENvbnRlbnQpOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIHJldFZhbHVlOwotICAgIH0gLy8gZWxlbWVudExvY2FsbHlWYWxpZFR5cGUKLQotICAgIE9iamVjdCBlbGVtZW50TG9jYWxseVZhbGlkQ29tcGxleFR5cGUoUU5hbWUgZWxlbWVudCwgT2JqZWN0IHRleHRDb250ZW50KSB7Ci0gICAgICAgIE9iamVjdCBhY3R1YWxWYWx1ZSA9IG51bGw7Ci0gICAgICAgIFhTQ29tcGxleFR5cGVEZWNsIGN0eXBlID0gKFhTQ29tcGxleFR5cGVEZWNsKSBmQ3VycmVudFR5cGU7Ci0KLSAgICAgICAgLy8gRWxlbWVudCBMb2NhbGx5IFZhbGlkIChDb21wbGV4IFR5cGUpCi0gICAgICAgIC8vIEZvciBhbiBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0gdG8gYmUgbG9jYWxseSB2YWxpZCB3aXRoIHJlc3BlY3QgdG8gYSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbiBhbGwgb2YgdGhlIGZvbGxvd2luZyBtdXN0IGJlIHRydWU6Ci0gICAgICAgIC8vIDEge2Fic3RyYWN0fSBpcyBmYWxzZS4KLSAgICAgICAgLy8gMiBJZiBjbGF1c2UgMy4yIG9mIEVsZW1lbnQgTG9jYWxseSBWYWxpZCAoRWxlbWVudCkgKDMuMy40KSBkaWQgbm90IGFwcGx5LCB0aGVuIHRoZSBhcHByb3ByaWF0ZSBjYXNlIGFtb25nIHRoZSBmb2xsb3dpbmcgbXVzdCBiZSB0cnVlOgotICAgICAgICBpZiAoIWZOaWwpIHsKLSAgICAgICAgICAgIC8vIDIuMSBJZiB0aGUge2NvbnRlbnQgdHlwZX0gaXMgZW1wdHksIHRoZW4gdGhlIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSBoYXMgbm8gY2hhcmFjdGVyIG9yIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSBbY2hpbGRyZW5dLgotICAgICAgICAgICAgaWYgKGN0eXBlLmZDb250ZW50VHlwZSA9PSBYU0NvbXBsZXhUeXBlRGVjbC5DT05URU5UVFlQRV9FTVBUWQotICAgICAgICAgICAgICAgICYmIChmU3ViRWxlbWVudCB8fCBmU2F3VGV4dCkpIHsKLSAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcigiY3ZjLWNvbXBsZXgtdHlwZS4yLjEiLCBuZXcgT2JqZWN0W10geyBlbGVtZW50LnJhd25hbWUgfSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyAyLjIgSWYgdGhlIHtjb250ZW50IHR5cGV9IGlzIGEgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiwgdGhlbiB0aGUgZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIGhhcyBubyBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0gW2NoaWxkcmVuXSwgYW5kIHRoZSBub3JtYWxpemVkIHZhbHVlIG9mIHRoZSBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0gaXMgdmFsaWQgd2l0aCByZXNwZWN0IHRvIHRoYXQgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiBhcyBkZWZpbmVkIGJ5IFN0cmluZyBWYWxpZCAoMy4xNC40KS4KLSAgICAgICAgICAgIGVsc2UgaWYgKGN0eXBlLmZDb250ZW50VHlwZSA9PSBYU0NvbXBsZXhUeXBlRGVjbC5DT05URU5UVFlQRV9TSU1QTEUpIHsKLSAgICAgICAgICAgICAgICBpZiAoZlN1YkVsZW1lbnQpCi0gICAgICAgICAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKCJjdmMtY29tcGxleC10eXBlLjIuMiIsIG5ldyBPYmplY3RbXSB7IGVsZW1lbnQucmF3bmFtZSB9KTsKLSAgICAgICAgICAgICAgICBYU1NpbXBsZVR5cGUgZHYgPSBjdHlwZS5mWFNTaW1wbGVUeXBlOwotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmICghZk5vcm1hbGl6ZURhdGEgfHwgZlVuaW9uVHlwZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgZlZhbGlkYXRpb25TdGF0ZS5zZXROb3JtYWxpemF0aW9uUmVxdWlyZWQodHJ1ZSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgYWN0dWFsVmFsdWUgPSBkdi52YWxpZGF0ZSh0ZXh0Q29udGVudCwgZlZhbGlkYXRpb25TdGF0ZSwgZlZhbGlkYXRlZEluZm8pOwotICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoZS5nZXRLZXkoKSwgZS5nZXRBcmdzKCkpOwotICAgICAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcigiY3ZjLWNvbXBsZXgtdHlwZS4yLjIiLCBuZXcgT2JqZWN0W10geyBlbGVtZW50LnJhd25hbWUgfSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIC8vIFJFVklTSVQ6IGV2ZW50dWFsbHksIHRoaXMgbWV0aG9kIHNob3VsZCByZXR1cm4gdGhlIHNhbWUgYWN0dWFsVmFsdWUgYXMgZWxlbWVudExvY2FsbHlWYWxpZFR5cGUuLi4KLSAgICAgICAgICAgICAgICAvLyBvYnZpb3VzbHkgaXQnbGwgcmV0dXJuIG51bGwgd2hlbiB0aGUgY29udGVudCBpcyBjb21wbGV4LgotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gMi4zIElmIHRoZSB7Y29udGVudCB0eXBlfSBpcyBlbGVtZW50LW9ubHksIHRoZW4gdGhlIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSBoYXMgbm8gY2hhcmFjdGVyIGluZm9ybWF0aW9uIGl0ZW0gW2NoaWxkcmVuXSBvdGhlciB0aGFuIHRob3NlIHdob3NlIFtjaGFyYWN0ZXIgY29kZV0gaXMgZGVmaW5lZCBhcyBhIHdoaXRlIHNwYWNlIGluIFtYTUwgMS4wIChTZWNvbmQgRWRpdGlvbildLgotICAgICAgICAgICAgZWxzZSBpZiAoY3R5cGUuZkNvbnRlbnRUeXBlID09IFhTQ29tcGxleFR5cGVEZWNsLkNPTlRFTlRUWVBFX0VMRU1FTlQpIHsKLSAgICAgICAgICAgICAgICBpZiAoZlNhd0NoYXJhY3RlcnMpIHsKLSAgICAgICAgICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoImN2Yy1jb21wbGV4LXR5cGUuMi4zIiwgbmV3IE9iamVjdFtdIHsgZWxlbWVudC5yYXduYW1lIH0pOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIDIuNCBJZiB0aGUge2NvbnRlbnQgdHlwZX0gaXMgZWxlbWVudC1vbmx5IG9yIG1peGVkLCB0aGVuIHRoZSBzZXF1ZW5jZSBvZiB0aGUgZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtJ3MgZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIFtjaGlsZHJlbl0sIGlmIGFueSwgdGFrZW4gaW4gb3JkZXIsIGlzIHZhbGlkIHdpdGggcmVzcGVjdCB0byB0aGUge2NvbnRlbnQgdHlwZX0ncyBwYXJ0aWNsZSwgYXMgZGVmaW5lZCBpbiBFbGVtZW50IFNlcXVlbmNlIExvY2FsbHkgVmFsaWQgKFBhcnRpY2xlKSAoMy45LjQpLgotICAgICAgICAgICAgaWYgKGN0eXBlLmZDb250ZW50VHlwZSA9PSBYU0NvbXBsZXhUeXBlRGVjbC5DT05URU5UVFlQRV9FTEVNRU5UCi0gICAgICAgICAgICAgICAgfHwgY3R5cGUuZkNvbnRlbnRUeXBlID09IFhTQ29tcGxleFR5cGVEZWNsLkNPTlRFTlRUWVBFX01JWEVEKSB7Ci0gICAgICAgICAgICAgICAgLy8gaWYgdGhlIGN1cnJlbnQgc3RhdGUgaXMgYSB2YWxpZCBzdGF0ZSwgY2hlY2sgd2hldGhlcgotICAgICAgICAgICAgICAgIC8vIGl0J3Mgb25lIG9mIHRoZSBmaW5hbCBzdGF0ZXMuCi0gICAgICAgICAgICAgICAgaWYgKERFQlVHKSB7Ci0gICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbihmQ3VyckNNU3RhdGUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpZiAoZkN1cnJDTVN0YXRlWzBdID49IDAgJiYgIWZDdXJyZW50Q00uZW5kQ29udGVudE1vZGVsKGZDdXJyQ01TdGF0ZSkpIHsKLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGV4cGVjdGVkID0gZXhwZWN0ZWRTdHIoZkN1cnJlbnRDTS53aGF0Q2FuR29IZXJlKGZDdXJyQ01TdGF0ZSkpOwotICAgICAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcigKLSAgICAgICAgICAgICAgICAgICAgICAgICJjdmMtY29tcGxleC10eXBlLjIuNC5iIiwKLSAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7IGVsZW1lbnQucmF3bmFtZSwgZXhwZWN0ZWQgfSk7Ci0gICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gQ29uc3RhbnQgc3BhY2UgYWxnb3JpdGhtIGZvciBhe24sbX0gZm9yIG4gPiAxIGFuZCBtIDw9IHVuYm91bmRlZAotICAgICAgICAgICAgICAgICAgICAvLyBBZnRlciB0aGUgREZBIGhhcyBjb21wbGV0ZWQsIGNoZWNrIG1pbk9jY3VycyBhbmQgbWF4T2NjdXJzCi0gICAgICAgICAgICAgICAgICAgIC8vIGZvciBhbGwgZWxlbWVudHMgYW5kIHdpbGRjYXJkcyBpbiB0aGlzIGNvbnRlbnQgbW9kZWwgd2hlcmUKLSAgICAgICAgICAgICAgICAgICAgLy8gYXtuLG19IGlzIHN1YnN1bWVkIHRvIGEqIG9yIGErCi0gICAgICAgICAgICAgICAgICAgIEFycmF5TGlzdCBlcnJvcnMgPSBmQ3VycmVudENNLmNoZWNrTWluTWF4Qm91bmRzKCk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcnMgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBlcnJvcnMuc2l6ZSgpOyBpICs9IDIpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcigKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFN0cmluZykgZXJyb3JzLmdldChpKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgZWxlbWVudC5yYXduYW1lLCBlcnJvcnMuZ2V0KGkgKyAxKSB9KTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGFjdHVhbFZhbHVlOwotICAgIH0gLy8gZWxlbWVudExvY2FsbHlWYWxpZENvbXBsZXhUeXBlCi0KLSAgICB2b2lkIHJlcG9ydFNjaGVtYUVycm9yKFN0cmluZyBrZXksIE9iamVjdFtdIGFyZ3VtZW50cykgewotICAgICAgICBpZiAoZkRvVmFsaWRhdGlvbikKLSAgICAgICAgICAgIGZYU0lFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKAotICAgICAgICAgICAgICAgIFhTTWVzc2FnZUZvcm1hdHRlci5TQ0hFTUFfRE9NQUlOLAotICAgICAgICAgICAgICAgIGtleSwKLSAgICAgICAgICAgICAgICBhcmd1bWVudHMsCi0gICAgICAgICAgICAgICAgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9FUlJPUik7Ci0gICAgfQotCi0gICAgLyoqIFJldHVybnMgdHJ1ZSBpZiB0aGUgdHdvIFZhbGlkYXRlZEluZm8gb2JqZWN0cyBjYW4gYmUgY29tcGFyZWQgaW4gdGhlIHNhbWUgdmFsdWUgc3BhY2UuICoqLwotICAgIHByaXZhdGUgYm9vbGVhbiBpc0NvbXBhcmFibGUoVmFsaWRhdGVkSW5mbyBpbmZvMSwgVmFsaWRhdGVkSW5mbyBpbmZvMikgewotICAgICAgICBmaW5hbCBzaG9ydCBwcmltaXRpdmVUeXBlMSA9IGNvbnZlcnRUb1ByaW1pdGl2ZUtpbmQoaW5mbzEuYWN0dWFsVmFsdWVUeXBlKTsKLSAgICAgICAgZmluYWwgc2hvcnQgcHJpbWl0aXZlVHlwZTIgPSBjb252ZXJ0VG9QcmltaXRpdmVLaW5kKGluZm8yLmFjdHVhbFZhbHVlVHlwZSk7Ci0gICAgICAgIGlmIChwcmltaXRpdmVUeXBlMSAhPSBwcmltaXRpdmVUeXBlMikgewotICAgICAgICAgICAgcmV0dXJuIChwcmltaXRpdmVUeXBlMSA9PSBYU0NvbnN0YW50cy5BTllTSU1QTEVUWVBFX0RUICYmIHByaW1pdGl2ZVR5cGUyID09IFhTQ29uc3RhbnRzLlNUUklOR19EVCB8fAotICAgICAgICAgICAgICAgICAgICBwcmltaXRpdmVUeXBlMSA9PSBYU0NvbnN0YW50cy5TVFJJTkdfRFQgJiYgcHJpbWl0aXZlVHlwZTIgPT0gWFNDb25zdGFudHMuQU5ZU0lNUExFVFlQRV9EVCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAocHJpbWl0aXZlVHlwZTEgPT0gWFNDb25zdGFudHMuTElTVF9EVCB8fCBwcmltaXRpdmVUeXBlMSA9PSBYU0NvbnN0YW50cy5MSVNUT0ZVTklPTl9EVCkgewotICAgICAgICAgICAgZmluYWwgU2hvcnRMaXN0IHR5cGVMaXN0MSA9IGluZm8xLml0ZW1WYWx1ZVR5cGVzOwotICAgICAgICAgICAgZmluYWwgU2hvcnRMaXN0IHR5cGVMaXN0MiA9IGluZm8yLml0ZW1WYWx1ZVR5cGVzOwotICAgICAgICAgICAgZmluYWwgaW50IHR5cGVMaXN0MUxlbmd0aCA9IHR5cGVMaXN0MSAhPSBudWxsID8gdHlwZUxpc3QxLmdldExlbmd0aCgpIDogMDsKLSAgICAgICAgICAgIGZpbmFsIGludCB0eXBlTGlzdDJMZW5ndGggPSB0eXBlTGlzdDIgIT0gbnVsbCA/IHR5cGVMaXN0Mi5nZXRMZW5ndGgoKSA6IDA7Ci0gICAgICAgICAgICBpZiAodHlwZUxpc3QxTGVuZ3RoICE9IHR5cGVMaXN0Mkxlbmd0aCkgewotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdHlwZUxpc3QxTGVuZ3RoOyArK2kpIHsKLSAgICAgICAgICAgICAgICBmaW5hbCBzaG9ydCBwcmltaXRpdmVJdGVtMSA9IGNvbnZlcnRUb1ByaW1pdGl2ZUtpbmQodHlwZUxpc3QxLml0ZW0oaSkpOwotICAgICAgICAgICAgICAgIGZpbmFsIHNob3J0IHByaW1pdGl2ZUl0ZW0yID0gY29udmVydFRvUHJpbWl0aXZlS2luZCh0eXBlTGlzdDIuaXRlbShpKSk7Ci0gICAgICAgICAgICAgICAgaWYgKHByaW1pdGl2ZUl0ZW0xICE9IHByaW1pdGl2ZUl0ZW0yKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChwcmltaXRpdmVJdGVtMSA9PSBYU0NvbnN0YW50cy5BTllTSU1QTEVUWVBFX0RUICYmIHByaW1pdGl2ZUl0ZW0yID09IFhTQ29uc3RhbnRzLlNUUklOR19EVCB8fAotICAgICAgICAgICAgICAgICAgICAgICAgcHJpbWl0aXZlSXRlbTEgPT0gWFNDb25zdGFudHMuU1RSSU5HX0RUICYmIHByaW1pdGl2ZUl0ZW0yID09IFhTQ29uc3RhbnRzLkFOWVNJTVBMRVRZUEVfRFQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBzaG9ydCBjb252ZXJ0VG9QcmltaXRpdmVLaW5kKHNob3J0IHZhbHVlVHlwZSkgewotICAgICAgICAvKiogUHJpbWl0aXZlIGRhdGF0eXBlcy4gKi8KLSAgICAgICAgaWYgKHZhbHVlVHlwZSA8PSBYU0NvbnN0YW50cy5OT1RBVElPTl9EVCkgewotICAgICAgICAgICAgcmV0dXJuIHZhbHVlVHlwZTsKLSAgICAgICAgfQotICAgICAgICAvKiogVHlwZXMgZGVyaXZlZCBmcm9tIHN0cmluZy4gKi8KLSAgICAgICAgaWYgKHZhbHVlVHlwZSA8PSBYU0NvbnN0YW50cy5FTlRJVFlfRFQpIHsKLSAgICAgICAgICAgIHJldHVybiBYU0NvbnN0YW50cy5TVFJJTkdfRFQ7Ci0gICAgICAgIH0KLSAgICAgICAgLyoqIFR5cGVzIGRlcml2ZWQgZnJvbSBkZWNpbWFsLiAqLwotICAgICAgICBpZiAodmFsdWVUeXBlIDw9IFhTQ29uc3RhbnRzLlBPU0lUSVZFSU5URUdFUl9EVCkgewotICAgICAgICAgICAgcmV0dXJuIFhTQ29uc3RhbnRzLkRFQ0lNQUxfRFQ7Ci0gICAgICAgIH0KLSAgICAgICAgLyoqIE90aGVyIHR5cGVzLiAqLwotICAgICAgICByZXR1cm4gdmFsdWVUeXBlOwotICAgIH0KLQotICAgIHByaXZhdGUgU3RyaW5nIGV4cGVjdGVkU3RyKFZlY3RvciBleHBlY3RlZCkgewotICAgICAgICBTdHJpbmdCdWZmZXIgcmV0ID0gbmV3IFN0cmluZ0J1ZmZlcigieyIpOwotICAgICAgICBpbnQgc2l6ZSA9IGV4cGVjdGVkLnNpemUoKTsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKLSAgICAgICAgICAgIGlmIChpID4gMCkKLSAgICAgICAgICAgICAgICByZXQuYXBwZW5kKCIsICIpOwotICAgICAgICAgICAgcmV0LmFwcGVuZChleHBlY3RlZC5lbGVtZW50QXQoaSkudG9TdHJpbmcoKSk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0LmFwcGVuZCgnfScpOwotICAgICAgICByZXR1cm4gcmV0LnRvU3RyaW5nKCk7Ci0gICAgfQotCi0gICAgLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi0KLSAgICAvLyB4cGF0aCBtYXRjaGVyIGluZm9ybWF0aW9uCi0KLSAgICAvKioKLSAgICAgKiBTdGFjayBvZiBYUGF0aCBtYXRjaGVycyBmb3IgaWRlbnRpdHkgY29uc3RyYWludHMuCi0gICAgICoKLSAgICAgKiBAYXV0aG9yIEFuZHkgQ2xhcmssIElCTQotICAgICAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgY2xhc3MgWFBhdGhNYXRjaGVyU3RhY2sgewotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIERhdGEKLSAgICAgICAgLy8KLQotICAgICAgICAvKiogQWN0aXZlIG1hdGNoZXJzLiAqLwotICAgICAgICBwcm90ZWN0ZWQgWFBhdGhNYXRjaGVyW10gZk1hdGNoZXJzID0gbmV3IFhQYXRoTWF0Y2hlcls0XTsKLQotICAgICAgICAvKiogQ291bnQgb2YgYWN0aXZlIG1hdGNoZXJzLiAqLwotICAgICAgICBwcm90ZWN0ZWQgaW50IGZNYXRjaGVyc0NvdW50OwotCi0gICAgICAgIC8qKiBPZmZzZXQgc3RhY2sgZm9yIGNvbnRleHRzLiAqLwotICAgICAgICBwcm90ZWN0ZWQgSW50U3RhY2sgZkNvbnRleHRTdGFjayA9IG5ldyBJbnRTdGFjaygpOwotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIENvbnN0cnVjdG9ycwotICAgICAgICAvLwotCi0gICAgICAgIHB1YmxpYyBYUGF0aE1hdGNoZXJTdGFjaygpIHsKLSAgICAgICAgfSAvLyA8aW5pdD4oKQotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIFB1YmxpYyBtZXRob2RzCi0gICAgICAgIC8vCi0KLSAgICAgICAgLyoqIFJlc2V0cyB0aGUgWFBhdGggbWF0Y2hlciBzdGFjay4gKi8KLSAgICAgICAgcHVibGljIHZvaWQgY2xlYXIoKSB7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZNYXRjaGVyc0NvdW50OyBpKyspIHsKLSAgICAgICAgICAgICAgICBmTWF0Y2hlcnNbaV0gPSBudWxsOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZk1hdGNoZXJzQ291bnQgPSAwOwotICAgICAgICAgICAgZkNvbnRleHRTdGFjay5jbGVhcigpOwotICAgICAgICB9IC8vIGNsZWFyKCkKLQotICAgICAgICAvKiogUmV0dXJucyB0aGUgc2l6ZSBvZiB0aGUgc3RhY2suICovCi0gICAgICAgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKLSAgICAgICAgICAgIHJldHVybiBmQ29udGV4dFN0YWNrLnNpemUoKTsKLSAgICAgICAgfSAvLyBzaXplKCk6aW50Ci0KLSAgICAgICAgLyoqIFJldHVybnMgdGhlIGNvdW50IG9mIFhQYXRoIG1hdGNoZXJzLiAqLwotICAgICAgICBwdWJsaWMgaW50IGdldE1hdGNoZXJDb3VudCgpIHsKLSAgICAgICAgICAgIHJldHVybiBmTWF0Y2hlcnNDb3VudDsKLSAgICAgICAgfSAvLyBnZXRNYXRjaGVyQ291bnQoKTppbnQKLQotICAgICAgICAvKiogQWRkcyBhIG1hdGNoZXIuICovCi0gICAgICAgIHB1YmxpYyB2b2lkIGFkZE1hdGNoZXIoWFBhdGhNYXRjaGVyIG1hdGNoZXIpIHsKLSAgICAgICAgICAgIGVuc3VyZU1hdGNoZXJDYXBhY2l0eSgpOwotICAgICAgICAgICAgZk1hdGNoZXJzW2ZNYXRjaGVyc0NvdW50KytdID0gbWF0Y2hlcjsKLSAgICAgICAgfSAvLyBhZGRNYXRjaGVyKFhQYXRoTWF0Y2hlcikKLQotICAgICAgICAvKiogUmV0dXJucyB0aGUgWFBhdGggbWF0Y2hlciBhdCB0aGUgc3BlY2lmaWVkIGluZGV4LiAqLwotICAgICAgICBwdWJsaWMgWFBhdGhNYXRjaGVyIGdldE1hdGNoZXJBdChpbnQgaW5kZXgpIHsKLSAgICAgICAgICAgIHJldHVybiBmTWF0Y2hlcnNbaW5kZXhdOwotICAgICAgICB9IC8vIGdldE1hdGNoZXJBdChpbmRleCk6WFBhdGhNYXRjaGVyCi0KLSAgICAgICAgLyoqIFB1c2hlcyBhIG5ldyBjb250ZXh0IG9udG8gdGhlIHN0YWNrLiAqLwotICAgICAgICBwdWJsaWMgdm9pZCBwdXNoQ29udGV4dCgpIHsKLSAgICAgICAgICAgIGZDb250ZXh0U3RhY2sucHVzaChmTWF0Y2hlcnNDb3VudCk7Ci0gICAgICAgIH0gLy8gcHVzaENvbnRleHQoKQotCi0gICAgICAgIC8qKiBQb3BzIGEgY29udGV4dCBvZmYgb2YgdGhlIHN0YWNrLiAqLwotICAgICAgICBwdWJsaWMgdm9pZCBwb3BDb250ZXh0KCkgewotICAgICAgICAgICAgZk1hdGNoZXJzQ291bnQgPSBmQ29udGV4dFN0YWNrLnBvcCgpOwotICAgICAgICB9IC8vIHBvcENvbnRleHQoKQotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIFByaXZhdGUgbWV0aG9kcwotICAgICAgICAvLwotCi0gICAgICAgIC8qKiBFbnN1cmVzIHRoZSBzaXplIG9mIHRoZSBtYXRjaGVycyBhcnJheS4gKi8KLSAgICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZU1hdGNoZXJDYXBhY2l0eSgpIHsKLSAgICAgICAgICAgIGlmIChmTWF0Y2hlcnNDb3VudCA9PSBmTWF0Y2hlcnMubGVuZ3RoKSB7Ci0gICAgICAgICAgICAgICAgWFBhdGhNYXRjaGVyW10gYXJyYXkgPSBuZXcgWFBhdGhNYXRjaGVyW2ZNYXRjaGVycy5sZW5ndGggKiAyXTsKLSAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGZNYXRjaGVycywgMCwgYXJyYXksIDAsIGZNYXRjaGVycy5sZW5ndGgpOwotICAgICAgICAgICAgICAgIGZNYXRjaGVycyA9IGFycmF5OwotICAgICAgICAgICAgfQotICAgICAgICB9IC8vIGVuc3VyZU1hdGNoZXJDYXBhY2l0eSgpCi0KLSAgICB9IC8vIGNsYXNzIFhQYXRoTWF0Y2hlclN0YWNrCi0KLSAgICAvLyB2YWx1ZSBzdG9yZSBpbXBsZW1lbnRhdGlvbnMKLQotICAgIC8qKgotICAgICAqIFZhbHVlIHN0b3JlIGltcGxlbWVudGF0aW9uIGJhc2UgY2xhc3MuIFRoZXJlIGFyZSBzcGVjaWZpYyBzdWJjbGFzc2VzCi0gICAgICogZm9yIGhhbmRsaW5nIHVuaXF1ZSwga2V5LCBhbmQga2V5cmVmLgotICAgICAqCi0gICAgICogQGF1dGhvciBBbmR5IENsYXJrLCBJQk0KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgYWJzdHJhY3QgY2xhc3MgVmFsdWVTdG9yZUJhc2UgaW1wbGVtZW50cyBWYWx1ZVN0b3JlIHsKLQotICAgICAgICAvLwotICAgICAgICAvLyBEYXRhCi0gICAgICAgIC8vCi0KLSAgICAgICAgLyoqIElkZW50aXR5IGNvbnN0cmFpbnQuICovCi0gICAgICAgIHByb3RlY3RlZCBJZGVudGl0eUNvbnN0cmFpbnQgZklkZW50aXR5Q29uc3RyYWludDsKLSAgICAgICAgcHJvdGVjdGVkIGludCBmRmllbGRDb3VudCA9IDA7Ci0gICAgICAgIHByb3RlY3RlZCBGaWVsZFtdIGZGaWVsZHMgPSBudWxsOwotICAgICAgICAvKiogY3VycmVudCBkYXRhICovCi0gICAgICAgIHByb3RlY3RlZCBPYmplY3RbXSBmTG9jYWxWYWx1ZXMgPSBudWxsOwotICAgICAgICBwcm90ZWN0ZWQgc2hvcnRbXSBmTG9jYWxWYWx1ZVR5cGVzID0gbnVsbDsKLSAgICAgICAgcHJvdGVjdGVkIFNob3J0TGlzdFtdIGZMb2NhbEl0ZW1WYWx1ZVR5cGVzID0gbnVsbDsKLQotICAgICAgICAvKiogQ3VycmVudCBkYXRhIHZhbHVlIGNvdW50LiAqLwotICAgICAgICBwcm90ZWN0ZWQgaW50IGZWYWx1ZXNDb3VudDsKLQotICAgICAgICAvKiogZ2xvYmFsIGRhdGEgKi8KLSAgICAgICAgcHVibGljIGZpbmFsIFZlY3RvciBmVmFsdWVzID0gbmV3IFZlY3RvcigpOwotICAgICAgICBwdWJsaWMgU2hvcnRWZWN0b3IgZlZhbHVlVHlwZXMgPSBudWxsOwotICAgICAgICBwdWJsaWMgVmVjdG9yIGZJdGVtVmFsdWVUeXBlcyA9IG51bGw7Ci0KLSAgICAgICAgcHJpdmF0ZSBib29sZWFuIGZVc2VWYWx1ZVR5cGVWZWN0b3IgPSBmYWxzZTsKLSAgICAgICAgcHJpdmF0ZSBpbnQgZlZhbHVlVHlwZXNMZW5ndGggPSAwOwotICAgICAgICBwcml2YXRlIHNob3J0IGZWYWx1ZVR5cGUgPSAwOwotCi0gICAgICAgIHByaXZhdGUgYm9vbGVhbiBmVXNlSXRlbVZhbHVlVHlwZVZlY3RvciA9IGZhbHNlOwotICAgICAgICBwcml2YXRlIGludCBmSXRlbVZhbHVlVHlwZXNMZW5ndGggPSAwOwotICAgICAgICBwcml2YXRlIFNob3J0TGlzdCBmSXRlbVZhbHVlVHlwZSA9IG51bGw7Ci0KLSAgICAgICAgLyoqIGJ1ZmZlciBmb3IgZXJyb3IgbWVzc2FnZXMgKi8KLSAgICAgICAgZmluYWwgU3RyaW5nQnVmZmVyIGZUZW1wQnVmZmVyID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIENvbnN0cnVjdG9ycwotICAgICAgICAvLwotCi0gICAgICAgIC8qKiBDb25zdHJ1Y3RzIGEgdmFsdWUgc3RvcmUgZm9yIHRoZSBzcGVjaWZpZWQgaWRlbnRpdHkgY29uc3RyYWludC4gKi8KLSAgICAgICAgcHJvdGVjdGVkIFZhbHVlU3RvcmVCYXNlKElkZW50aXR5Q29uc3RyYWludCBpZGVudGl0eUNvbnN0cmFpbnQpIHsKLSAgICAgICAgICAgIGZJZGVudGl0eUNvbnN0cmFpbnQgPSBpZGVudGl0eUNvbnN0cmFpbnQ7Ci0gICAgICAgICAgICBmRmllbGRDb3VudCA9IGZJZGVudGl0eUNvbnN0cmFpbnQuZ2V0RmllbGRDb3VudCgpOwotICAgICAgICAgICAgZkZpZWxkcyA9IG5ldyBGaWVsZFtmRmllbGRDb3VudF07Ci0gICAgICAgICAgICBmTG9jYWxWYWx1ZXMgPSBuZXcgT2JqZWN0W2ZGaWVsZENvdW50XTsKLSAgICAgICAgICAgIGZMb2NhbFZhbHVlVHlwZXMgPSBuZXcgc2hvcnRbZkZpZWxkQ291bnRdOwotICAgICAgICAgICAgZkxvY2FsSXRlbVZhbHVlVHlwZXMgPSBuZXcgU2hvcnRMaXN0W2ZGaWVsZENvdW50XTsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZkZpZWxkQ291bnQ7IGkrKykgewotICAgICAgICAgICAgICAgIGZGaWVsZHNbaV0gPSBmSWRlbnRpdHlDb25zdHJhaW50LmdldEZpZWxkQXQoaSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gLy8gPGluaXQ+KElkZW50aXR5Q29uc3RyYWludCkKLQotICAgICAgICAvLwotICAgICAgICAvLyBQdWJsaWMgbWV0aG9kcwotICAgICAgICAvLwotCi0gICAgICAgIC8vIGRlc3Ryb3lzIHRoaXMgVmFsdWVTdG9yZTsgdXNlZnVsIHdoZW4sIGZvciBpbnN0YW5jZSwgYQotICAgICAgICAvLyBsb2NhbGx5LXNjb3BlZCBJRCBjb25zdHJhaW50IGlzIGludm9sdmVkLgotICAgICAgICBwdWJsaWMgdm9pZCBjbGVhcigpIHsKLSAgICAgICAgICAgIGZWYWx1ZXNDb3VudCA9IDA7Ci0gICAgICAgICAgICBmVXNlVmFsdWVUeXBlVmVjdG9yID0gZmFsc2U7Ci0gICAgICAgICAgICBmVmFsdWVUeXBlc0xlbmd0aCA9IDA7Ci0gICAgICAgICAgICBmVmFsdWVUeXBlID0gMDsKLSAgICAgICAgICAgIGZVc2VJdGVtVmFsdWVUeXBlVmVjdG9yID0gZmFsc2U7Ci0gICAgICAgICAgICBmSXRlbVZhbHVlVHlwZXNMZW5ndGggPSAwOwotICAgICAgICAgICAgZkl0ZW1WYWx1ZVR5cGUgPSBudWxsOwotICAgICAgICAgICAgZlZhbHVlcy5zZXRTaXplKDApOwotICAgICAgICAgICAgaWYgKGZWYWx1ZVR5cGVzICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmVmFsdWVUeXBlcy5jbGVhcigpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKGZJdGVtVmFsdWVUeXBlcyAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZkl0ZW1WYWx1ZVR5cGVzLnNldFNpemUoMCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gLy8gZW5kIGNsZWFyKCk6dm9pZAotCi0gICAgICAgIC8vIGFwcGVuZHMgdGhlIGNvbnRlbnRzIG9mIG9uZSBWYWx1ZVN0b3JlIHRvIHRob3NlIG9mIHVzLgotICAgICAgICBwdWJsaWMgdm9pZCBhcHBlbmQoVmFsdWVTdG9yZUJhc2UgbmV3VmFsKSB7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG5ld1ZhbC5mVmFsdWVzLnNpemUoKTsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgZlZhbHVlcy5hZGRFbGVtZW50KG5ld1ZhbC5mVmFsdWVzLmVsZW1lbnRBdChpKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gLy8gYXBwZW5kKFZhbHVlU3RvcmVCYXNlKQotCi0gICAgICAgIC8qKiBTdGFydCBzY29wZSBmb3IgdmFsdWUgc3RvcmUuICovCi0gICAgICAgIHB1YmxpYyB2b2lkIHN0YXJ0VmFsdWVTY29wZSgpIHsKLSAgICAgICAgICAgIGZWYWx1ZXNDb3VudCA9IDA7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZGaWVsZENvdW50OyBpKyspIHsKLSAgICAgICAgICAgICAgICBmTG9jYWxWYWx1ZXNbaV0gPSBudWxsOwotICAgICAgICAgICAgICAgIGZMb2NhbFZhbHVlVHlwZXNbaV0gPSAwOwotICAgICAgICAgICAgICAgIGZMb2NhbEl0ZW1WYWx1ZVR5cGVzW2ldID0gbnVsbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSAvLyBzdGFydFZhbHVlU2NvcGUoKQotCi0gICAgICAgIC8qKiBFbmRzIHNjb3BlIGZvciB2YWx1ZSBzdG9yZS4gKi8KLSAgICAgICAgcHVibGljIHZvaWQgZW5kVmFsdWVTY29wZSgpIHsKLQotICAgICAgICAgICAgaWYgKGZWYWx1ZXNDb3VudCA9PSAwKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGZJZGVudGl0eUNvbnN0cmFpbnQuZ2V0Q2F0ZWdvcnkoKSA9PSBJZGVudGl0eUNvbnN0cmFpbnQuSUNfS0VZKSB7Ci0gICAgICAgICAgICAgICAgICAgIFN0cmluZyBjb2RlID0gIkFic2VudEtleVZhbHVlIjsKLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGVOYW1lID0gZklkZW50aXR5Q29uc3RyYWludC5nZXRFbGVtZW50TmFtZSgpOwotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgY05hbWUgPSBmSWRlbnRpdHlDb25zdHJhaW50LmdldElkZW50aXR5Q29uc3RyYWludE5hbWUoKTsKLSAgICAgICAgICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoY29kZSwgbmV3IE9iamVjdFtdIHsgZU5hbWUsIGNOYW1lIH0pOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIFZhbGlkYXRpb24gUnVsZTogSWRlbnRpdHktY29uc3RyYWludCBTYXRpc2ZpZWQKLSAgICAgICAgICAgIC8vIDQuMiBJZiB0aGUge2lkZW50aXR5LWNvbnN0cmFpbnQgY2F0ZWdvcnl9IGlzIGtleSwgdGhlbiBhbGwgb2YgdGhlIGZvbGxvd2luZyBtdXN0IGJlIHRydWU6Ci0gICAgICAgICAgICAvLyA0LjIuMSBUaGUgdGFyZ2V0IG5vZGUgc2V0IGFuZCB0aGUgcXVhbGlmaWVkIG5vZGUgc2V0IGFyZSBlcXVhbCwgdGhhdCBpcywgZXZlcnkgbWVtYmVyIG9mIHRoZQotICAgICAgICAgICAgLy8gdGFyZ2V0IG5vZGUgc2V0IGlzIGFsc28gYSBtZW1iZXIgb2YgdGhlIHF1YWxpZmllZCBub2RlIHNldCBhbmQgdmljZSB2ZXJzYS4KLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAvLyBJZiB0aGUgSURDIGlzIGEga2V5IGNoZWNrIHdoZXRoZXIgd2UgaGF2ZSBhbGwgdGhlIGZpZWxkcy4KLSAgICAgICAgICAgIGlmIChmVmFsdWVzQ291bnQgIT0gZkZpZWxkQ291bnQpIHsKLSAgICAgICAgICAgICAgICBpZiAoZklkZW50aXR5Q29uc3RyYWludC5nZXRDYXRlZ29yeSgpID09IElkZW50aXR5Q29uc3RyYWludC5JQ19LRVkpIHsKLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGNvZGUgPSAiS2V5Tm90RW5vdWdoVmFsdWVzIjsKLSAgICAgICAgICAgICAgICAgICAgVW5pcXVlT3JLZXkga2V5ID0gKFVuaXF1ZU9yS2V5KSBmSWRlbnRpdHlDb25zdHJhaW50OwotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgZU5hbWUgPSBmSWRlbnRpdHlDb25zdHJhaW50LmdldEVsZW1lbnROYW1lKCk7Ci0gICAgICAgICAgICAgICAgICAgIFN0cmluZyBjTmFtZSA9IGtleS5nZXRJZGVudGl0eUNvbnN0cmFpbnROYW1lKCk7Ci0gICAgICAgICAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKGNvZGUsIG5ldyBPYmplY3RbXSB7IGVOYW1lLCBjTmFtZSB9KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgfQotCi0gICAgICAgIH0gLy8gZW5kVmFsdWVTY29wZSgpCi0KLSAgICAgICAgLy8gVGhpcyBpcyBuZWVkZWQgdG8gYWxsb3cga2V5cmVmJ3MgdG8gbG9vayBmb3IgbWF0Y2hlZCBrZXlzCi0gICAgICAgIC8vIGluIHRoZSBjb3JyZWN0IHNjb3BlLiAgVW5pcXVlIGFuZCBLZXkgbWF5IGFsc28gbmVlZCB0bwotICAgICAgICAvLyBvdmVycmlkZSB0aGlzIG1ldGhvZCBmb3IgcHVycG9zZXMgb2YgdGhlaXIgb3duLgotICAgICAgICAvLyBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgd2hlbmV2ZXIgdGhlIERvY3VtZW50RnJhZ21lbnQKLSAgICAgICAgLy8gb2YgYW4gSUQgQ29uc3RyYWludCBnb2VzIG91dCBvZiBzY29wZS4KLSAgICAgICAgcHVibGljIHZvaWQgZW5kRG9jdW1lbnRGcmFnbWVudCgpIHsKLSAgICAgICAgfSAvLyBlbmREb2N1bWVudEZyYWdtZW50KCk6dm9pZAotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBTaWduYWxzIHRoZSBlbmQgb2YgdGhlIGRvY3VtZW50LiBUaGlzIGlzIHdoZXJlIHRoZSBzcGVjaWZpYwotICAgICAgICAgKiBpbnN0YW5jZXMgb2YgdmFsdWUgc3RvcmVzIGNhbiB2ZXJpZnkgdGhlIGludGVncml0eSBvZiB0aGUKLSAgICAgICAgICogaWRlbnRpdHkgY29uc3RyYWludHMuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgdm9pZCBlbmREb2N1bWVudCgpIHsKLSAgICAgICAgfSAvLyBlbmREb2N1bWVudCgpCi0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gVmFsdWVTdG9yZSBtZXRob2RzCi0gICAgICAgIC8vCi0KLSAgICAgICAgLyogcmVwb3J0cyBhbiBlcnJvciBpZiBhbiBlbGVtZW50IGlzIG1hdGNoZWQKLSAgICAgICAgICogaGFzIG5pbGxhYmxlIHRydWUgYW5kIGlzIG1hdGNoZWQgYnkgYSBrZXkuCi0gICAgICAgICAqLwotCi0gICAgICAgIHB1YmxpYyB2b2lkIHJlcG9ydEVycm9yKFN0cmluZyBrZXksIE9iamVjdFtdIGFyZ3MpIHsKLSAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKGtleSwgYXJncyk7Ci0gICAgICAgIH0gLy8gcmVwb3J0RXJyb3IoU3RyaW5nLE9iamVjdFtdKQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBBZGRzIHRoZSBzcGVjaWZpZWQgdmFsdWUgdG8gdGhlIHZhbHVlIHN0b3JlLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gZmllbGQgVGhlIGZpZWxkIGFzc29jaWF0ZWQgdG8gdGhlIHZhbHVlLiBUaGlzIHJlZmVyZW5jZQotICAgICAgICAgKiAgICAgICAgICAgICAgaXMgdXNlZCB0byBlbnN1cmUgdGhhdCBlYWNoIGZpZWxkIG9ubHkgYWRkcyBhIHZhbHVlCi0gICAgICAgICAqICAgICAgICAgICAgICBvbmNlIHdpdGhpbiBhIHNlbGVjdGlvbiBzY29wZS4KLSAgICAgICAgICogQHBhcmFtIGFjdHVhbFZhbHVlIFRoZSB2YWx1ZSB0byBhZGQuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgdm9pZCBhZGRWYWx1ZShGaWVsZCBmaWVsZCwgT2JqZWN0IGFjdHVhbFZhbHVlLCBzaG9ydCB2YWx1ZVR5cGUsIFNob3J0TGlzdCBpdGVtVmFsdWVUeXBlKSB7Ci0gICAgICAgICAgICBpbnQgaTsKLSAgICAgICAgICAgIGZvciAoaSA9IGZGaWVsZENvdW50IC0gMTsgaSA+IC0xOyBpLS0pIHsKLSAgICAgICAgICAgICAgICBpZiAoZkZpZWxkc1tpXSA9PSBmaWVsZCkgewotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyBkbyB3ZSBldmVuIGtub3cgdGhpcyBmaWVsZD8KLSAgICAgICAgICAgIGlmIChpID09IC0xKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIGNvZGUgPSAiVW5rbm93bkZpZWxkIjsKLSAgICAgICAgICAgICAgICBTdHJpbmcgZU5hbWUgPSBmSWRlbnRpdHlDb25zdHJhaW50LmdldEVsZW1lbnROYW1lKCk7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIGNOYW1lID0gZklkZW50aXR5Q29uc3RyYWludC5nZXRJZGVudGl0eUNvbnN0cmFpbnROYW1lKCk7Ci0gICAgICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoY29kZSwgbmV3IE9iamVjdFtdIHsgZmllbGQudG9TdHJpbmcoKSwgZU5hbWUsIGNOYW1lIH0pOwotICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChCb29sZWFuLlRSVUUgIT0gbWF5TWF0Y2goZmllbGQpKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIGNvZGUgPSAiRmllbGRNdWx0aXBsZU1hdGNoIjsKLSAgICAgICAgICAgICAgICBTdHJpbmcgY05hbWUgPSBmSWRlbnRpdHlDb25zdHJhaW50LmdldElkZW50aXR5Q29uc3RyYWludE5hbWUoKTsKLSAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcihjb2RlLCBuZXcgT2JqZWN0W10geyBmaWVsZC50b1N0cmluZygpLCBjTmFtZSB9KTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgZlZhbHVlc0NvdW50Kys7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmTG9jYWxWYWx1ZXNbaV0gPSBhY3R1YWxWYWx1ZTsKLSAgICAgICAgICAgIGZMb2NhbFZhbHVlVHlwZXNbaV0gPSB2YWx1ZVR5cGU7Ci0gICAgICAgICAgICBmTG9jYWxJdGVtVmFsdWVUeXBlc1tpXSA9IGl0ZW1WYWx1ZVR5cGU7Ci0gICAgICAgICAgICBpZiAoZlZhbHVlc0NvdW50ID09IGZGaWVsZENvdW50KSB7Ci0gICAgICAgICAgICAgICAgY2hlY2tEdXBsaWNhdGVWYWx1ZXMoKTsKLSAgICAgICAgICAgICAgICAvLyBzdG9yZSB2YWx1ZXMKLSAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgZkZpZWxkQ291bnQ7IGkrKykgewotICAgICAgICAgICAgICAgICAgICBmVmFsdWVzLmFkZEVsZW1lbnQoZkxvY2FsVmFsdWVzW2ldKTsKLSAgICAgICAgICAgICAgICAgICAgYWRkVmFsdWVUeXBlKGZMb2NhbFZhbHVlVHlwZXNbaV0pOwotICAgICAgICAgICAgICAgICAgICBhZGRJdGVtVmFsdWVUeXBlKGZMb2NhbEl0ZW1WYWx1ZVR5cGVzW2ldKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gLy8gYWRkVmFsdWUoU3RyaW5nLEZpZWxkKQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhpcyB2YWx1ZSBzdG9yZSBjb250YWlucyB0aGUgbG9jYWxseSBzY29wZWQgdmFsdWUgc3RvcmVzCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWlucygpIHsKLSAgICAgICAgICAgIC8vIFJFVklTSVQ6IHdlIGNhbiBpbXByb3ZlIHBlcmZvcm1hbmNlIGJ5IHVzaW5nIGhhc2ggY29kZXMsIGluc3RlYWQgb2YKLSAgICAgICAgICAgIC8vIHRyYXZlcnNpbmcgZ2xvYmFsIHZlY3RvciB0aGF0IGNvdWxkIGJlIHF1aXRlIGxhcmdlLgotICAgICAgICAgICAgaW50IG5leHQgPSAwOwotICAgICAgICAgICAgZmluYWwgaW50IHNpemUgPSBmVmFsdWVzLnNpemUoKTsKLSAgICAgICAgICAgIExPT1AgOiBmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkgPSBuZXh0KSB7Ci0gICAgICAgICAgICAgICAgbmV4dCA9IGkgKyBmRmllbGRDb3VudDsKLSAgICAgICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IGZGaWVsZENvdW50OyBqKyspIHsKLSAgICAgICAgICAgICAgICAgICAgT2JqZWN0IHZhbHVlMSA9IGZMb2NhbFZhbHVlc1tqXTsKLSAgICAgICAgICAgICAgICAgICAgT2JqZWN0IHZhbHVlMiA9IGZWYWx1ZXMuZWxlbWVudEF0KGkpOwotICAgICAgICAgICAgICAgICAgICBzaG9ydCB2YWx1ZVR5cGUxID0gZkxvY2FsVmFsdWVUeXBlc1tqXTsKLSAgICAgICAgICAgICAgICAgICAgc2hvcnQgdmFsdWVUeXBlMiA9IGdldFZhbHVlVHlwZUF0KGkpOwotICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWUxID09IG51bGwgfHwgdmFsdWUyID09IG51bGwgfHwgdmFsdWVUeXBlMSAhPSB2YWx1ZVR5cGUyIHx8ICEodmFsdWUxLmVxdWFscyh2YWx1ZTIpKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWUgTE9PUDsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlIGlmKHZhbHVlVHlwZTEgPT0gWFNDb25zdGFudHMuTElTVF9EVCB8fCB2YWx1ZVR5cGUxID09IFhTQ29uc3RhbnRzLkxJU1RPRlVOSU9OX0RUKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTaG9ydExpc3QgbGlzdDEgPSBmTG9jYWxJdGVtVmFsdWVUeXBlc1tqXTsKLSAgICAgICAgICAgICAgICAgICAgICAgIFNob3J0TGlzdCBsaXN0MiA9IGdldEl0ZW1WYWx1ZVR5cGVBdChpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmKGxpc3QxID09IG51bGwgfHwgbGlzdDIgPT0gbnVsbCB8fCAhbGlzdDEuZXF1YWxzKGxpc3QyKSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZSBMT09QOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGkrKzsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLy8gZm91bmQgaXQKLSAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIGRpZG4ndCBmaW5kIGl0Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0gLy8gY29udGFpbnMoKTpib29sZWFuCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFJldHVybnMgLTEgaWYgdGhpcyB2YWx1ZSBzdG9yZSBjb250YWlucyB0aGUgc3BlY2lmaWVkCi0gICAgICAgICAqIHZhbHVlcywgb3RoZXJ3aXNlIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgZmllbGQgaW4gdGhlCi0gICAgICAgICAqIGtleSBzZXF1ZW5jZS4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBpbnQgY29udGFpbnMoVmFsdWVTdG9yZUJhc2UgdnNiKSB7Ci0KLSAgICAgICAgICAgIGZpbmFsIFZlY3RvciB2YWx1ZXMgPSB2c2IuZlZhbHVlczsKLSAgICAgICAgICAgIGZpbmFsIGludCBzaXplMSA9IHZhbHVlcy5zaXplKCk7Ci0gICAgICAgICAgICBpZiAoZkZpZWxkQ291bnQgPD0gMSkgewotICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTE7ICsraSkgewotICAgICAgICAgICAgICAgICAgICBzaG9ydCB2YWwgPSB2c2IuZ2V0VmFsdWVUeXBlQXQoaSk7Ci0gICAgICAgICAgICAgICAgICAgIGlmICghdmFsdWVUeXBlQ29udGFpbnModmFsKSB8fCAhZlZhbHVlcy5jb250YWlucyh2YWx1ZXMuZWxlbWVudEF0KGkpKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZSBpZih2YWwgPT0gWFNDb25zdGFudHMuTElTVF9EVCB8fCB2YWwgPT0gWFNDb25zdGFudHMuTElTVE9GVU5JT05fRFQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIFNob3J0TGlzdCBsaXN0MSA9IHZzYi5nZXRJdGVtVmFsdWVUeXBlQXQoaSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWl0ZW1WYWx1ZVR5cGVDb250YWlucyhsaXN0MSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8qKiBIYW5kbGUgbi10dXBsZXMuICoqLwotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgZmluYWwgaW50IHNpemUyID0gZlZhbHVlcy5zaXplKCk7Ci0gICAgICAgICAgICAgICAgLyoqIEl0ZXJhdGUgb3ZlciBlYWNoIHNldCBvZiBmaWVsZHMuICoqLwotICAgICAgICAgICAgICAgIE9VVEVSOiBmb3IgKGludCBpID0gMDsgaSA8IHNpemUxOyBpICs9IGZGaWVsZENvdW50KSB7Ci0gICAgICAgICAgICAgICAgICAgIC8qKiBDaGVjayB3aGV0aGVyIHRoaXMgc2V0IGlzIGNvbnRhaW5lZCBpbiB0aGUgdmFsdWUgc3RvcmUuICoqLwotICAgICAgICAgICAgICAgICAgICBJTk5FUjogZm9yIChpbnQgaiA9IDA7IGogPCBzaXplMjsgaiArPSBmRmllbGRDb3VudCkgewotICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgayA9IDA7IGsgPCBmRmllbGRDb3VudDsgKytrKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgT2JqZWN0IHZhbHVlMSA9IHZhbHVlcy5lbGVtZW50QXQoaStrKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBPYmplY3QgdmFsdWUyID0gZlZhbHVlcy5lbGVtZW50QXQoaitrKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBzaG9ydCB2YWx1ZVR5cGUxID0gdnNiLmdldFZhbHVlVHlwZUF0KGkrayk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgc2hvcnQgdmFsdWVUeXBlMiA9IGdldFZhbHVlVHlwZUF0KGorayk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlMSAhPSB2YWx1ZTIgJiYgKHZhbHVlVHlwZTEgIT0gdmFsdWVUeXBlMiB8fCB2YWx1ZTEgPT0gbnVsbCB8fCAhdmFsdWUxLmVxdWFscyh2YWx1ZTIpKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZSBJTk5FUjsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZih2YWx1ZVR5cGUxID09IFhTQ29uc3RhbnRzLkxJU1RfRFQgfHwgdmFsdWVUeXBlMSA9PSBYU0NvbnN0YW50cy5MSVNUT0ZVTklPTl9EVCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTaG9ydExpc3QgbGlzdDEgPSB2c2IuZ2V0SXRlbVZhbHVlVHlwZUF0KGkrayk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNob3J0TGlzdCBsaXN0MiA9IGdldEl0ZW1WYWx1ZVR5cGVBdChqK2spOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobGlzdDEgPT0gbnVsbCB8fCBsaXN0MiA9PSBudWxsIHx8ICFsaXN0MS5lcXVhbHMobGlzdDIpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZSBJTk5FUjsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlIE9VVEVSOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiAtMTsKLQotICAgICAgICB9IC8vIGNvbnRhaW5zKFZlY3Rvcik6T2JqZWN0Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gUHJvdGVjdGVkIG1ldGhvZHMKLSAgICAgICAgLy8KLQotICAgICAgICBwcm90ZWN0ZWQgdm9pZCBjaGVja0R1cGxpY2F0ZVZhbHVlcygpIHsKLSAgICAgICAgICAgIC8vIG5vLW9wCi0gICAgICAgIH0gLy8gZHVwbGljYXRlVmFsdWUoTWFwKQotCi0gICAgICAgIC8qKiBSZXR1cm5zIGEgc3RyaW5nIG9mIHRoZSBzcGVjaWZpZWQgdmFsdWVzLiAqLwotICAgICAgICBwcm90ZWN0ZWQgU3RyaW5nIHRvU3RyaW5nKE9iamVjdFtdIHZhbHVlcykgewotCi0gICAgICAgICAgICAvLyBubyB2YWx1ZXMKLSAgICAgICAgICAgIGludCBzaXplID0gdmFsdWVzLmxlbmd0aDsKLSAgICAgICAgICAgIGlmIChzaXplID09IDApIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gIiI7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGZUZW1wQnVmZmVyLnNldExlbmd0aCgwKTsKLQotICAgICAgICAgICAgLy8gY29uc3RydWN0IHZhbHVlIHN0cmluZwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKLSAgICAgICAgICAgICAgICBpZiAoaSA+IDApIHsKLSAgICAgICAgICAgICAgICAgICAgZlRlbXBCdWZmZXIuYXBwZW5kKCcsJyk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGZUZW1wQnVmZmVyLmFwcGVuZCh2YWx1ZXNbaV0pOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIGZUZW1wQnVmZmVyLnRvU3RyaW5nKCk7Ci0KLSAgICAgICAgfSAvLyB0b1N0cmluZyhPYmplY3RbXSk6U3RyaW5nCi0KLSAgICAgICAgLyoqIFJldHVybnMgYSBzdHJpbmcgb2YgdGhlIHNwZWNpZmllZCB2YWx1ZXMuICovCi0gICAgICAgIHByb3RlY3RlZCBTdHJpbmcgdG9TdHJpbmcoVmVjdG9yIHZhbHVlcywgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKSB7Ci0KLSAgICAgICAgICAgIC8vIG5vIHZhbHVlcwotICAgICAgICAgICAgaWYgKGxlbmd0aCA9PSAwKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuICIiOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBvbmUgdmFsdWUKLSAgICAgICAgICAgIGlmIChsZW5ndGggPT0gMSkgewotICAgICAgICAgICAgICAgIHJldHVybiBTdHJpbmcudmFsdWVPZih2YWx1ZXMuZWxlbWVudEF0KHN0YXJ0KSk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIGNvbnN0cnVjdCB2YWx1ZSBzdHJpbmcKLSAgICAgICAgICAgIFN0cmluZ0J1ZmZlciBzdHIgPSBuZXcgU3RyaW5nQnVmZmVyKCk7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGkgPiAwKSB7Ci0gICAgICAgICAgICAgICAgICAgIHN0ci5hcHBlbmQoJywnKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgc3RyLmFwcGVuZCh2YWx1ZXMuZWxlbWVudEF0KHN0YXJ0ICsgaSkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIHN0ci50b1N0cmluZygpOwotCi0gICAgICAgIH0gLy8gdG9TdHJpbmcoVmVjdG9yLGludCxpbnQpOlN0cmluZwotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIE9iamVjdCBtZXRob2RzCi0gICAgICAgIC8vCi0KLSAgICAgICAgLyoqIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBvYmplY3QuICovCi0gICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0gICAgICAgICAgICBTdHJpbmcgcyA9IHN1cGVyLnRvU3RyaW5nKCk7Ci0gICAgICAgICAgICBpbnQgaW5kZXgxID0gcy5sYXN0SW5kZXhPZignJCcpOwotICAgICAgICAgICAgaWYgKGluZGV4MSAhPSAtMSkgewotICAgICAgICAgICAgICAgIHMgPSBzLnN1YnN0cmluZyhpbmRleDEgKyAxKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGludCBpbmRleDIgPSBzLmxhc3RJbmRleE9mKCcuJyk7Ci0gICAgICAgICAgICBpZiAoaW5kZXgyICE9IC0xKSB7Ci0gICAgICAgICAgICAgICAgcyA9IHMuc3Vic3RyaW5nKGluZGV4MiArIDEpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIHMgKyAnWycgKyBmSWRlbnRpdHlDb25zdHJhaW50ICsgJ10nOwotICAgICAgICB9IC8vIHRvU3RyaW5nKCk6U3RyaW5nCi0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gUHJpdmF0ZSBtZXRob2RzCi0gICAgICAgIC8vCi0KLSAgICAgICAgcHJpdmF0ZSB2b2lkIGFkZFZhbHVlVHlwZShzaG9ydCB0eXBlKSB7Ci0gICAgICAgICAgICBpZiAoZlVzZVZhbHVlVHlwZVZlY3RvcikgewotICAgICAgICAgICAgICAgIGZWYWx1ZVR5cGVzLmFkZCh0eXBlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKGZWYWx1ZVR5cGVzTGVuZ3RoKysgPT0gMCkgewotICAgICAgICAgICAgICAgIGZWYWx1ZVR5cGUgPSB0eXBlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoZlZhbHVlVHlwZSAhPSB0eXBlKSB7Ci0gICAgICAgICAgICAgICAgZlVzZVZhbHVlVHlwZVZlY3RvciA9IHRydWU7Ci0gICAgICAgICAgICAgICAgaWYgKGZWYWx1ZVR5cGVzID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgZlZhbHVlVHlwZXMgPSBuZXcgU2hvcnRWZWN0b3IoZlZhbHVlVHlwZXNMZW5ndGggKiAyKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDE7IGkgPCBmVmFsdWVUeXBlc0xlbmd0aDsgKytpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZWYWx1ZVR5cGVzLmFkZChmVmFsdWVUeXBlKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZlZhbHVlVHlwZXMuYWRkKHR5cGUpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgcHJpdmF0ZSBzaG9ydCBnZXRWYWx1ZVR5cGVBdChpbnQgaW5kZXgpIHsKLSAgICAgICAgICAgIGlmIChmVXNlVmFsdWVUeXBlVmVjdG9yKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZWYWx1ZVR5cGVzLnZhbHVlQXQoaW5kZXgpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIGZWYWx1ZVR5cGU7Ci0gICAgICAgIH0KLQotICAgICAgICBwcml2YXRlIGJvb2xlYW4gdmFsdWVUeXBlQ29udGFpbnMoc2hvcnQgdmFsdWUpIHsKLSAgICAgICAgICAgIGlmIChmVXNlVmFsdWVUeXBlVmVjdG9yKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZWYWx1ZVR5cGVzLmNvbnRhaW5zKHZhbHVlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiBmVmFsdWVUeXBlID09IHZhbHVlOwotICAgICAgICB9Ci0KLSAgICAgICAgcHJpdmF0ZSB2b2lkIGFkZEl0ZW1WYWx1ZVR5cGUoU2hvcnRMaXN0IGl0ZW1WYWx1ZVR5cGUpIHsKLSAgICAgICAgICAgIGlmIChmVXNlSXRlbVZhbHVlVHlwZVZlY3RvcikgewotICAgICAgICAgICAgICAgIGZJdGVtVmFsdWVUeXBlcy5hZGQoaXRlbVZhbHVlVHlwZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChmSXRlbVZhbHVlVHlwZXNMZW5ndGgrKyA9PSAwKSB7Ci0gICAgICAgICAgICAgICAgZkl0ZW1WYWx1ZVR5cGUgPSBpdGVtVmFsdWVUeXBlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoIShmSXRlbVZhbHVlVHlwZSA9PSBpdGVtVmFsdWVUeXBlIHx8Ci0gICAgICAgICAgICAgICAgICAgIChmSXRlbVZhbHVlVHlwZSAhPSBudWxsICYmIGZJdGVtVmFsdWVUeXBlLmVxdWFscyhpdGVtVmFsdWVUeXBlKSkpKSB7Ci0gICAgICAgICAgICAgICAgZlVzZUl0ZW1WYWx1ZVR5cGVWZWN0b3IgPSB0cnVlOwotICAgICAgICAgICAgICAgIGlmIChmSXRlbVZhbHVlVHlwZXMgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBmSXRlbVZhbHVlVHlwZXMgPSBuZXcgVmVjdG9yKGZJdGVtVmFsdWVUeXBlc0xlbmd0aCAqIDIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMTsgaSA8IGZJdGVtVmFsdWVUeXBlc0xlbmd0aDsgKytpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZJdGVtVmFsdWVUeXBlcy5hZGQoZkl0ZW1WYWx1ZVR5cGUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBmSXRlbVZhbHVlVHlwZXMuYWRkKGl0ZW1WYWx1ZVR5cGUpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgcHJpdmF0ZSBTaG9ydExpc3QgZ2V0SXRlbVZhbHVlVHlwZUF0KGludCBpbmRleCkgewotICAgICAgICAgICAgaWYgKGZVc2VJdGVtVmFsdWVUeXBlVmVjdG9yKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIChTaG9ydExpc3QpIGZJdGVtVmFsdWVUeXBlcy5lbGVtZW50QXQoaW5kZXgpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIGZJdGVtVmFsdWVUeXBlOwotICAgICAgICB9Ci0KLSAgICAgICAgcHJpdmF0ZSBib29sZWFuIGl0ZW1WYWx1ZVR5cGVDb250YWlucyhTaG9ydExpc3QgdmFsdWUpIHsKLSAgICAgICAgICAgIGlmIChmVXNlSXRlbVZhbHVlVHlwZVZlY3RvcikgewotICAgICAgICAgICAgICAgIHJldHVybiBmSXRlbVZhbHVlVHlwZXMuY29udGFpbnModmFsdWUpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIGZJdGVtVmFsdWVUeXBlID09IHZhbHVlIHx8Ci0gICAgICAgICAgICAgICAgKGZJdGVtVmFsdWVUeXBlICE9IG51bGwgJiYgZkl0ZW1WYWx1ZVR5cGUuZXF1YWxzKHZhbHVlKSk7Ci0gICAgICAgIH0KLQotICAgIH0gLy8gY2xhc3MgVmFsdWVTdG9yZUJhc2UKLQotICAgIC8qKgotICAgICAqIFVuaXF1ZSB2YWx1ZSBzdG9yZS4KLSAgICAgKgotICAgICAqIEBhdXRob3IgQW5keSBDbGFyaywgSUJNCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGNsYXNzIFVuaXF1ZVZhbHVlU3RvcmUgZXh0ZW5kcyBWYWx1ZVN0b3JlQmFzZSB7Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gQ29uc3RydWN0b3JzCi0gICAgICAgIC8vCi0KLSAgICAgICAgLyoqIENvbnN0cnVjdHMgYSB1bmlxdWUgdmFsdWUgc3RvcmUuICovCi0gICAgICAgIHB1YmxpYyBVbmlxdWVWYWx1ZVN0b3JlKFVuaXF1ZU9yS2V5IHVuaXF1ZSkgewotICAgICAgICAgICAgc3VwZXIodW5pcXVlKTsKLSAgICAgICAgfSAvLyA8aW5pdD4oVW5pcXVlKQotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIFZhbHVlU3RvcmVCYXNlIHByb3RlY3RlZCBtZXRob2RzCi0gICAgICAgIC8vCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIENhbGxlZCB3aGVuIGEgZHVwbGljYXRlIHZhbHVlIGlzIGFkZGVkLgotICAgICAgICAgKi8KLSAgICAgICAgcHJvdGVjdGVkIHZvaWQgY2hlY2tEdXBsaWNhdGVWYWx1ZXMoKSB7Ci0gICAgICAgICAgICAvLyBpcyB0aGlzIHZhbHVlIGFzIGEgZ3JvdXAgZHVwbGljYXRlZD8KLSAgICAgICAgICAgIGlmIChjb250YWlucygpKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIGNvZGUgPSAiRHVwbGljYXRlVW5pcXVlIjsKLSAgICAgICAgICAgICAgICBTdHJpbmcgdmFsdWUgPSB0b1N0cmluZyhmTG9jYWxWYWx1ZXMpOwotICAgICAgICAgICAgICAgIFN0cmluZyBlTmFtZSA9IGZJZGVudGl0eUNvbnN0cmFpbnQuZ2V0RWxlbWVudE5hbWUoKTsKLSAgICAgICAgICAgICAgICBTdHJpbmcgY05hbWUgPSBmSWRlbnRpdHlDb25zdHJhaW50LmdldElkZW50aXR5Q29uc3RyYWludE5hbWUoKTsKLSAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcihjb2RlLCBuZXcgT2JqZWN0W10geyB2YWx1ZSwgZU5hbWUsIGNOYW1lIH0pOwotICAgICAgICAgICAgfQotICAgICAgICB9IC8vIGR1cGxpY2F0ZVZhbHVlKE1hcCkKLQotICAgIH0gLy8gY2xhc3MgVW5pcXVlVmFsdWVTdG9yZQotCi0gICAgLyoqCi0gICAgICogS2V5IHZhbHVlIHN0b3JlLgotICAgICAqCi0gICAgICogQGF1dGhvciBBbmR5IENsYXJrLCBJQk0KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgY2xhc3MgS2V5VmFsdWVTdG9yZSBleHRlbmRzIFZhbHVlU3RvcmVCYXNlIHsKLQotICAgICAgICAvLyBSRVZJU0lUOiBJbXBsZW1lbnQgYSBtb3JlIGVmZmljaWVudCBzdG9yYWdlIG1lY2hhbmlzbS4gLUFjCi0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gQ29uc3RydWN0b3JzCi0gICAgICAgIC8vCi0KLSAgICAgICAgLyoqIENvbnN0cnVjdHMgYSBrZXkgdmFsdWUgc3RvcmUuICovCi0gICAgICAgIHB1YmxpYyBLZXlWYWx1ZVN0b3JlKFVuaXF1ZU9yS2V5IGtleSkgewotICAgICAgICAgICAgc3VwZXIoa2V5KTsKLSAgICAgICAgfSAvLyA8aW5pdD4oS2V5KQotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIFZhbHVlU3RvcmVCYXNlIHByb3RlY3RlZCBtZXRob2RzCi0gICAgICAgIC8vCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIENhbGxlZCB3aGVuIGEgZHVwbGljYXRlIHZhbHVlIGlzIGFkZGVkLgotICAgICAgICAgKi8KLSAgICAgICAgcHJvdGVjdGVkIHZvaWQgY2hlY2tEdXBsaWNhdGVWYWx1ZXMoKSB7Ci0gICAgICAgICAgICBpZiAoY29udGFpbnMoKSkgewotICAgICAgICAgICAgICAgIFN0cmluZyBjb2RlID0gIkR1cGxpY2F0ZUtleSI7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIHZhbHVlID0gdG9TdHJpbmcoZkxvY2FsVmFsdWVzKTsKLSAgICAgICAgICAgICAgICBTdHJpbmcgZU5hbWUgPSBmSWRlbnRpdHlDb25zdHJhaW50LmdldEVsZW1lbnROYW1lKCk7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIGNOYW1lID0gZklkZW50aXR5Q29uc3RyYWludC5nZXRJZGVudGl0eUNvbnN0cmFpbnROYW1lKCk7Ci0gICAgICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoY29kZSwgbmV3IE9iamVjdFtdIHsgdmFsdWUsIGVOYW1lLCBjTmFtZSB9KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSAvLyBkdXBsaWNhdGVWYWx1ZShNYXApCi0KLSAgICB9IC8vIGNsYXNzIEtleVZhbHVlU3RvcmUKLQotICAgIC8qKgotICAgICAqIEtleSByZWZlcmVuY2UgdmFsdWUgc3RvcmUuCi0gICAgICoKLSAgICAgKiBAYXV0aG9yIEFuZHkgQ2xhcmssIElCTQotICAgICAqLwotICAgIHByb3RlY3RlZCBjbGFzcyBLZXlSZWZWYWx1ZVN0b3JlIGV4dGVuZHMgVmFsdWVTdG9yZUJhc2UgewotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIERhdGEKLSAgICAgICAgLy8KLQotICAgICAgICAvKiogS2V5IHZhbHVlIHN0b3JlLiAqLwotICAgICAgICBwcm90ZWN0ZWQgVmFsdWVTdG9yZUJhc2UgZktleVZhbHVlU3RvcmU7Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gQ29uc3RydWN0b3JzCi0gICAgICAgIC8vCi0KLSAgICAgICAgLyoqIENvbnN0cnVjdHMgYSBrZXkgdmFsdWUgc3RvcmUuICovCi0gICAgICAgIHB1YmxpYyBLZXlSZWZWYWx1ZVN0b3JlKEtleVJlZiBrZXlSZWYsIEtleVZhbHVlU3RvcmUga2V5VmFsdWVTdG9yZSkgewotICAgICAgICAgICAgc3VwZXIoa2V5UmVmKTsKLSAgICAgICAgICAgIGZLZXlWYWx1ZVN0b3JlID0ga2V5VmFsdWVTdG9yZTsKLSAgICAgICAgfSAvLyA8aW5pdD4oS2V5UmVmKQotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIFZhbHVlU3RvcmVCYXNlIG1ldGhvZHMKLSAgICAgICAgLy8KLQotICAgICAgICAvLyBlbmQgdGhlIHZhbHVlIFNjb3BlOyBoZXJlJ3Mgd2hlcmUgd2UgaGF2ZSB0byB0aWUKLSAgICAgICAgLy8gdXAga2V5UmVmIGxvb3NlIGVuZHMuCi0gICAgICAgIHB1YmxpYyB2b2lkIGVuZERvY3VtZW50RnJhZ21lbnQoKSB7Ci0KLSAgICAgICAgICAgIC8vIGRvIGFsbCB0aGUgbmVjZXNzYXJ5IG1hbmFnZW1lbnQuLi4KLSAgICAgICAgICAgIHN1cGVyLmVuZERvY3VtZW50RnJhZ21lbnQoKTsKLQotICAgICAgICAgICAgLy8gdmVyaWZ5IHJlZmVyZW5jZXMKLSAgICAgICAgICAgIC8vIGdldCB0aGUga2V5IHN0b3JlIGNvcnJlc3BvbmRpbmcgKGlmIGl0IGV4aXN0cyk6Ci0gICAgICAgICAgICBmS2V5VmFsdWVTdG9yZSA9Ci0gICAgICAgICAgICAgICAgKFZhbHVlU3RvcmVCYXNlKSBmVmFsdWVTdG9yZUNhY2hlLmZHbG9iYWxJRENvbnN0cmFpbnRNYXAuZ2V0KAotICAgICAgICAgICAgICAgICAgICAoKEtleVJlZikgZklkZW50aXR5Q29uc3RyYWludCkuZ2V0S2V5KCkpOwotCi0gICAgICAgICAgICBpZiAoZktleVZhbHVlU3RvcmUgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIC8vIHJlcG9ydCBlcnJvcgotICAgICAgICAgICAgICAgIFN0cmluZyBjb2RlID0gIktleVJlZk91dE9mU2NvcGUiOwotICAgICAgICAgICAgICAgIFN0cmluZyB2YWx1ZSA9IGZJZGVudGl0eUNvbnN0cmFpbnQudG9TdHJpbmcoKTsKLSAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcihjb2RlLCBuZXcgT2JqZWN0W10geyB2YWx1ZSB9KTsKLSAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpbnQgZXJyb3JJbmRleCA9IGZLZXlWYWx1ZVN0b3JlLmNvbnRhaW5zKHRoaXMpOwotICAgICAgICAgICAgaWYgKGVycm9ySW5kZXggIT0gLTEpIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgY29kZSA9ICJLZXlOb3RGb3VuZCI7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIHZhbHVlcyA9IHRvU3RyaW5nKGZWYWx1ZXMsIGVycm9ySW5kZXgsIGZGaWVsZENvdW50KTsKLSAgICAgICAgICAgICAgICBTdHJpbmcgZWxlbWVudCA9IGZJZGVudGl0eUNvbnN0cmFpbnQuZ2V0RWxlbWVudE5hbWUoKTsKLSAgICAgICAgICAgICAgICBTdHJpbmcgbmFtZSA9IGZJZGVudGl0eUNvbnN0cmFpbnQuZ2V0TmFtZSgpOwotICAgICAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKGNvZGUsIG5ldyBPYmplY3RbXSB7IG5hbWUsIHZhbHVlcywgZWxlbWVudCB9KTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICB9IC8vIGVuZERvY3VtZW50RnJhZ21lbnQoKQotCi0gICAgICAgIC8qKiBFbmQgZG9jdW1lbnQuICovCi0gICAgICAgIHB1YmxpYyB2b2lkIGVuZERvY3VtZW50KCkgewotICAgICAgICAgICAgc3VwZXIuZW5kRG9jdW1lbnQoKTsKLQotICAgICAgICB9IC8vIGVuZERvY3VtZW50KCkKLQotICAgIH0gLy8gY2xhc3MgS2V5UmVmVmFsdWVTdG9yZQotCi0gICAgLy8gdmFsdWUgc3RvcmUgbWFuYWdlbWVudAotCi0gICAgLyoqCi0gICAgICogVmFsdWUgc3RvcmUgY2FjaGUuIFRoaXMgY2xhc3MgaXMgdXNlZCB0byBzdG9yZSB0aGUgdmFsdWVzIGZvcgotICAgICAqIGlkZW50aXR5IGNvbnN0cmFpbnRzLgotICAgICAqCi0gICAgICogQGF1dGhvciBBbmR5IENsYXJrLCBJQk0KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgY2xhc3MgVmFsdWVTdG9yZUNhY2hlIHsKLQotICAgICAgICAvLwotICAgICAgICAvLyBEYXRhCi0gICAgICAgIC8vCi0gICAgICAgIGZpbmFsIExvY2FsSURLZXkgZkxvY2FsSWQgPSBuZXcgTG9jYWxJREtleSgpOwotICAgICAgICAvLyB2YWx1ZXMgc3RvcmVzCi0KLSAgICAgICAgLyoqIHN0b3JlcyBhbGwgZ2xvYmFsIFZhbHVlcyBzdG9yZXMuICovCi0gICAgICAgIHByb3RlY3RlZCBmaW5hbCBWZWN0b3IgZlZhbHVlU3RvcmVzID0gbmV3IFZlY3RvcigpOwotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBWYWx1ZXMgc3RvcmVzIGFzc29jaWF0ZWQgdG8gc3BlY2lmaWMgaWRlbnRpdHkgY29uc3RyYWludHMuCi0gICAgICAgICAqIFRoaXMgbWFwIG1hcHMgSWRlbnRpdHlDb25zdHJhaW50cyBhbmQKLSAgICAgICAgICogdGhlIDAtYmFzZWQgZWxlbWVudCBvbiB3aGljaCB0aGVpciBzZWxlY3RvcnMgZmlyc3QgbWF0Y2hlZCB0bwotICAgICAgICAgKiBhIGNvcnJlc3BvbmRpbmcgVmFsdWVTdG9yZS4gIFRoaXMgc2hvdWxkIHRha2UgY2FyZQotICAgICAgICAgKiBvZiBhbGwgY2FzZXMsIGluY2x1ZGluZyB3aGVyZSBJRCBjb25zdHJhaW50cyB3aXRoCi0gICAgICAgICAqIGRlc2NlbmRhbnQtb3Itc2VsZiBheGVzIG9jY3VyIG9uIHJlY3Vyc2l2ZWx5LWRlZmluZWQKLSAgICAgICAgICogZWxlbWVudHMuCi0gICAgICAgICAqLwotICAgICAgICBwcm90ZWN0ZWQgZmluYWwgTWFwPExvY2FsSURLZXksIFZhbHVlU3RvcmVCYXNlPgotICAgICAgICAgICAgICAgIGZJZGVudGl0eUNvbnN0cmFpbnQyVmFsdWVTdG9yZU1hcCA9IG5ldyBIYXNoTWFwPD4oKTsKLQotICAgICAgICAvLyBza2V0Y2ggb2YgYWxnb3JpdGhtOgotICAgICAgICAvLyAtIHdoZW4gYSBjb25zdHJhaW50IGlzIGZpcnN0IGVuY291bnRlcmVkLCBpdHMKLSAgICAgICAgLy8gICB2YWx1ZXMgYXJlIHN0b3JlZCBpbiB0aGUgKGxvY2FsKSBmSWRlbnRpdHlDb25zdHJhaW50MlZhbHVlU3RvcmVNYXA7Ci0gICAgICAgIC8vIC0gT25jZSBpdCBpcyB2YWxpZGF0ZWQgKGkuZS4sIHdoZW4gaXQgZ29lcyBvdXQgb2Ygc2NvcGUpLAotICAgICAgICAvLyAgIGl0cyB2YWx1ZXMgYXJlIG1lcmdlZCBpbnRvIHRoZSBmR2xvYmFsSURDb25zdHJhaW50TWFwOwotICAgICAgICAvLyAtIGFzIHdlIGVuY291bnRlciBrZXlyZWYncywgd2UgbG9vayBhdCB0aGUgZ2xvYmFsIHRhYmxlIHRvCi0gICAgICAgIC8vICAgIHZhbGlkYXRlIHRoZW0uCi0gICAgICAgIC8vCi0gICAgICAgIC8vIFRoZSBmR2xvYmFsSURNYXBTdGFjayBoYXMgdGhlIGZvbGxvd2luZyBzdHJ1Y3R1cmU6Ci0gICAgICAgIC8vIC0gdmFsaWRhdGlvbiBhbHdheXMgb2NjdXJzIGFnYWluc3QgdGhlIGZHbG9iYWxJRENvbnN0cmFpbnRNYXAKLSAgICAgICAgLy8gKHdoaWNoIGNvbXByaXNlcyBhbGwgdGhlICJlbGlnaWJsZSIgaWQgY29uc3RyYWludHMpOwotICAgICAgICAvLyBXaGVuIGFuIGVuZEVsZW1lbnQgaXMgZm91bmQsIHRoaXMgTWFwIGlzIG1lcmdlZCB3aXRoIHRoZSBvbmUKLSAgICAgICAgLy8gYmVsb3cgaW4gdGhlIHN0YWNrLgotICAgICAgICAvLyBXaGVuIGEgc3RhcnQgdGFnIGlzIGVuY291bnRlcmVkLCB3ZSBjcmVhdGUgYSBuZXcKLSAgICAgICAgLy8gZkdsb2JhbElEQ29uc3RyYWludE1hcC4KLSAgICAgICAgLy8gaS5lLiwgdGhlIHRvcCBvZiB0aGUgZkdsb2JhbElETWFwU3RhY2sgYWx3YXlzIGNvbnRhaW5zCi0gICAgICAgIC8vIHRoZSBwcmVjZWRpbmcgc2libGluZ3MnIGVsaWdpYmxlIGlkIGNvbnN0cmFpbnRzOwotICAgICAgICAvLyB0aGUgZkdsb2JhbElEQ29uc3RyYWludE1hcCBjb250YWlucyBkZXNjZW5kYW50cytzZWxmLgotICAgICAgICAvLyBrZXlyZWZzIGNhbiBvbmx5IG1hdGNoIGRlc2NlbmRhbnRzK3NlbGYuCi0gICAgICAgIHByb3RlY3RlZCBmaW5hbCBTdGFjazxNYXA8SWRlbnRpdHlDb25zdHJhaW50LCBWYWx1ZVN0b3JlQmFzZT4+Ci0gICAgICAgICAgICAgICAgZkdsb2JhbE1hcFN0YWNrID0gbmV3IFN0YWNrPD4oKTsKLSAgICAgICAgcHJvdGVjdGVkIGZpbmFsIE1hcDxJZGVudGl0eUNvbnN0cmFpbnQsIFZhbHVlU3RvcmVCYXNlPgotICAgICAgICAgICAgICAgIGZHbG9iYWxJRENvbnN0cmFpbnRNYXAgPSBuZXcgSGFzaE1hcDw+KCk7Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gQ29uc3RydWN0b3JzCi0gICAgICAgIC8vCi0KLSAgICAgICAgLyoqIERlZmF1bHQgY29uc3RydWN0b3IuICovCi0gICAgICAgIHB1YmxpYyBWYWx1ZVN0b3JlQ2FjaGUoKSB7Ci0gICAgICAgIH0gLy8gPGluaXQ+KCkKLQotICAgICAgICAvLwotICAgICAgICAvLyBQdWJsaWMgbWV0aG9kcwotICAgICAgICAvLwotCi0gICAgICAgIC8qKiBSZXNldHMgdGhlIGlkZW50aXR5IGNvbnN0cmFpbnQgY2FjaGUuICovCi0gICAgICAgIHB1YmxpYyB2b2lkIHN0YXJ0RG9jdW1lbnQoKSB7Ci0gICAgICAgICAgICBmVmFsdWVTdG9yZXMucmVtb3ZlQWxsRWxlbWVudHMoKTsKLSAgICAgICAgICAgIGZJZGVudGl0eUNvbnN0cmFpbnQyVmFsdWVTdG9yZU1hcC5jbGVhcigpOwotICAgICAgICAgICAgZkdsb2JhbElEQ29uc3RyYWludE1hcC5jbGVhcigpOwotICAgICAgICAgICAgZkdsb2JhbE1hcFN0YWNrLnJlbW92ZUFsbEVsZW1lbnRzKCk7Ci0gICAgICAgIH0gLy8gc3RhcnREb2N1bWVudCgpCi0KLSAgICAgICAgLy8gc3RhcnRFbGVtZW50OiAgcHVzaGVzIHRoZSBjdXJyZW50IGZHbG9iYWxJRENvbnN0cmFpbnRNYXAKLSAgICAgICAgLy8gb250byBmR2xvYmFsTWFwU3RhY2sgYW5kIGNsZWFycyBmR2xvYmFsSURDb25zdHJhaW50IG1hcC4KLSAgICAgICAgcHVibGljIHZvaWQgc3RhcnRFbGVtZW50KCkgewotICAgICAgICAgICAgLy8gb25seSBjbG9uZSB0aGUgaGFzaHRhYmxlIHdoZW4gdGhlcmUgYXJlIGVsZW1lbnRzCi0gICAgICAgICAgICBpZiAoZkdsb2JhbElEQ29uc3RyYWludE1hcC5zaXplKCkgPiAwKQotICAgICAgICAgICAgICAgIGZHbG9iYWxNYXBTdGFjay5wdXNoKChNYXA8SWRlbnRpdHlDb25zdHJhaW50LCBWYWx1ZVN0b3JlQmFzZT4pCi0gICAgICAgICAgICAgICAgICAgICAgICAoKEhhc2hNYXApZkdsb2JhbElEQ29uc3RyYWludE1hcCkuY2xvbmUoKSk7Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgZkdsb2JhbE1hcFN0YWNrLnB1c2gobnVsbCk7Ci0gICAgICAgICAgICBmR2xvYmFsSURDb25zdHJhaW50TWFwLmNsZWFyKCk7Ci0gICAgICAgIH0gLy8gc3RhcnRFbGVtZW50KHZvaWQpCi0KLSAgICAgICAgLyoqIGVuZEVsZW1lbnQoKTogIG1lcmdlcyBjb250ZW50cyBvZiBmR2xvYmFsSURDb25zdHJhaW50TWFwIHdpdGggdGhlCi0gICAgICAgICAqIHRvcCBvZiBmR2xvYmFsTWFwU3RhY2sgaW50byBmR2xvYmFsSURDb25zdHJhaW50TWFwLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIHZvaWQgZW5kRWxlbWVudCgpIHsKLSAgICAgICAgICAgIGlmIChmR2xvYmFsTWFwU3RhY2suaXNFbXB0eSgpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuOyAvLyBtdXN0IGJlIGFuIGludmFsaWQgZG9jIQotICAgICAgICAgICAgfQotICAgICAgICAgICAgTWFwPElkZW50aXR5Q29uc3RyYWludCwgVmFsdWVTdG9yZUJhc2U+IG9sZE1hcCA9IGZHbG9iYWxNYXBTdGFjay5wb3AoKTsKLSAgICAgICAgICAgIC8vIHJldHVybiBpZiB0aGVyZSBpcyBubyBlbGVtZW50Ci0gICAgICAgICAgICBpZiAob2xkTWFwID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGZvciAoTWFwLkVudHJ5PElkZW50aXR5Q29uc3RyYWludCwgVmFsdWVTdG9yZUJhc2U+IGVudHJ5IDogb2xkTWFwLmVudHJ5U2V0KCkpIHsKLSAgICAgICAgICAgICAgICBJZGVudGl0eUNvbnN0cmFpbnQgaWQgPSBlbnRyeS5nZXRLZXkoKTsKLSAgICAgICAgICAgICAgICBWYWx1ZVN0b3JlQmFzZSBvbGRWYWwgPSBlbnRyeS5nZXRWYWx1ZSgpOwotICAgICAgICAgICAgICAgIGlmIChvbGRWYWwgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBWYWx1ZVN0b3JlQmFzZSBjdXJyVmFsID0gZkdsb2JhbElEQ29uc3RyYWludE1hcC5nZXQoaWQpOwotICAgICAgICAgICAgICAgICAgICBpZiAoY3VyclZhbCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmR2xvYmFsSURDb25zdHJhaW50TWFwLnB1dChpZCwgb2xkVmFsKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChjdXJyVmFsICE9IG9sZFZhbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgY3VyclZhbC5hcHBlbmQob2xkVmFsKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfSAvLyBlbmRFbGVtZW50KCkKLQotICAgICAgICAvKioKLSAgICAgICAgICogSW5pdGlhbGl6ZXMgdGhlIHZhbHVlIHN0b3JlcyBmb3IgdGhlIHNwZWNpZmllZCBlbGVtZW50Ci0gICAgICAgICAqIGRlY2xhcmF0aW9uLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIHZvaWQgaW5pdFZhbHVlU3RvcmVzRm9yKFhTRWxlbWVudERlY2wgZURlY2wsIEZpZWxkQWN0aXZhdG9yIGFjdGl2YXRvcikgewotICAgICAgICAgICAgLy8gaW5pdGlhbGl6ZSB2YWx1ZSBzdG9yZXMgZm9yIHVuaXF1ZSBmaWVsZHMKLSAgICAgICAgICAgIElkZW50aXR5Q29uc3RyYWludFtdIGljQXJyYXkgPSBlRGVjbC5mSURDb25zdHJhaW50czsKLSAgICAgICAgICAgIGludCBpY0NvdW50ID0gZURlY2wuZklEQ1BvczsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaWNDb3VudDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgc3dpdGNoIChpY0FycmF5W2ldLmdldENhdGVnb3J5KCkpIHsKLSAgICAgICAgICAgICAgICAgICAgY2FzZSAoSWRlbnRpdHlDb25zdHJhaW50LklDX1VOSVFVRSkgOgotICAgICAgICAgICAgICAgICAgICAgICAgLy8gaW5pdGlhbGl6ZSB2YWx1ZSBzdG9yZXMgZm9yIHVuaXF1ZSBmaWVsZHMKLSAgICAgICAgICAgICAgICAgICAgICAgIFVuaXF1ZU9yS2V5IHVuaXF1ZSA9IChVbmlxdWVPcktleSkgaWNBcnJheVtpXTsKLSAgICAgICAgICAgICAgICAgICAgICAgIExvY2FsSURLZXkgdG9IYXNoID0gbmV3IExvY2FsSURLZXkodW5pcXVlLCBmRWxlbWVudERlcHRoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIFVuaXF1ZVZhbHVlU3RvcmUgdW5pcXVlVmFsdWVTdG9yZSA9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgKFVuaXF1ZVZhbHVlU3RvcmUpIGZJZGVudGl0eUNvbnN0cmFpbnQyVmFsdWVTdG9yZU1hcC5nZXQodG9IYXNoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmICh1bmlxdWVWYWx1ZVN0b3JlID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmlxdWVWYWx1ZVN0b3JlID0gbmV3IFVuaXF1ZVZhbHVlU3RvcmUodW5pcXVlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmSWRlbnRpdHlDb25zdHJhaW50MlZhbHVlU3RvcmVNYXAucHV0KHRvSGFzaCwgdW5pcXVlVmFsdWVTdG9yZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuaXF1ZVZhbHVlU3RvcmUuY2xlYXIoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGZWYWx1ZVN0b3Jlcy5hZGRFbGVtZW50KHVuaXF1ZVZhbHVlU3RvcmUpOwotICAgICAgICAgICAgICAgICAgICAgICAgYWN0aXZhdGVTZWxlY3RvckZvcihpY0FycmF5W2ldKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICBjYXNlIChJZGVudGl0eUNvbnN0cmFpbnQuSUNfS0VZKSA6Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBpbml0aWFsaXplIHZhbHVlIHN0b3JlcyBmb3Iga2V5IGZpZWxkcwotICAgICAgICAgICAgICAgICAgICAgICAgVW5pcXVlT3JLZXkga2V5ID0gKFVuaXF1ZU9yS2V5KSBpY0FycmF5W2ldOwotICAgICAgICAgICAgICAgICAgICAgICAgdG9IYXNoID0gbmV3IExvY2FsSURLZXkoa2V5LCBmRWxlbWVudERlcHRoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIEtleVZhbHVlU3RvcmUga2V5VmFsdWVTdG9yZSA9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgKEtleVZhbHVlU3RvcmUpIGZJZGVudGl0eUNvbnN0cmFpbnQyVmFsdWVTdG9yZU1hcC5nZXQodG9IYXNoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChrZXlWYWx1ZVN0b3JlID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXlWYWx1ZVN0b3JlID0gbmV3IEtleVZhbHVlU3RvcmUoa2V5KTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmSWRlbnRpdHlDb25zdHJhaW50MlZhbHVlU3RvcmVNYXAucHV0KHRvSGFzaCwga2V5VmFsdWVTdG9yZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleVZhbHVlU3RvcmUuY2xlYXIoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGZWYWx1ZVN0b3Jlcy5hZGRFbGVtZW50KGtleVZhbHVlU3RvcmUpOwotICAgICAgICAgICAgICAgICAgICAgICAgYWN0aXZhdGVTZWxlY3RvckZvcihpY0FycmF5W2ldKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICBjYXNlIChJZGVudGl0eUNvbnN0cmFpbnQuSUNfS0VZUkVGKSA6Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBpbml0aWFsaXplIHZhbHVlIHN0b3JlcyBmb3Iga2V5UmVmIGZpZWxkcwotICAgICAgICAgICAgICAgICAgICAgICAgS2V5UmVmIGtleVJlZiA9IChLZXlSZWYpIGljQXJyYXlbaV07Ci0gICAgICAgICAgICAgICAgICAgICAgICB0b0hhc2ggPSBuZXcgTG9jYWxJREtleShrZXlSZWYsIGZFbGVtZW50RGVwdGgpOwotICAgICAgICAgICAgICAgICAgICAgICAgS2V5UmVmVmFsdWVTdG9yZSBrZXlSZWZWYWx1ZVN0b3JlID0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAoS2V5UmVmVmFsdWVTdG9yZSkgZklkZW50aXR5Q29uc3RyYWludDJWYWx1ZVN0b3JlTWFwLmdldCh0b0hhc2gpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGtleVJlZlZhbHVlU3RvcmUgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleVJlZlZhbHVlU3RvcmUgPSBuZXcgS2V5UmVmVmFsdWVTdG9yZShrZXlSZWYsIG51bGwpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZJZGVudGl0eUNvbnN0cmFpbnQyVmFsdWVTdG9yZU1hcC5wdXQodG9IYXNoLCBrZXlSZWZWYWx1ZVN0b3JlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5UmVmVmFsdWVTdG9yZS5jbGVhcigpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgZlZhbHVlU3RvcmVzLmFkZEVsZW1lbnQoa2V5UmVmVmFsdWVTdG9yZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBhY3RpdmF0ZVNlbGVjdG9yRm9yKGljQXJyYXlbaV0pOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9IC8vIGluaXRWYWx1ZVN0b3Jlc0ZvcihYU0VsZW1lbnREZWNsKQotCi0gICAgICAgIC8qKiBSZXR1cm5zIHRoZSB2YWx1ZSBzdG9yZSBhc3NvY2lhdGVkIHRvIHRoZSBzcGVjaWZpZWQgSWRlbnRpdHlDb25zdHJhaW50LiAqLwotICAgICAgICBwdWJsaWMgVmFsdWVTdG9yZUJhc2UgZ2V0VmFsdWVTdG9yZUZvcihJZGVudGl0eUNvbnN0cmFpbnQgaWQsIGludCBpbml0aWFsRGVwdGgpIHsKLSAgICAgICAgICAgIGZMb2NhbElkLmZEZXB0aCA9IGluaXRpYWxEZXB0aDsKLSAgICAgICAgICAgIGZMb2NhbElkLmZJZCA9IGlkOwotICAgICAgICAgICAgcmV0dXJuIGZJZGVudGl0eUNvbnN0cmFpbnQyVmFsdWVTdG9yZU1hcC5nZXQoZkxvY2FsSWQpOwotICAgICAgICB9IC8vIGdldFZhbHVlU3RvcmVGb3IoSWRlbnRpdHlDb25zdHJhaW50LCBpbnQpOlZhbHVlU3RvcmVCYXNlCi0KLSAgICAgICAgLyoqIFJldHVybnMgdGhlIGdsb2JhbCB2YWx1ZSBzdG9yZSBhc3NvY2lhdGVkIHRvIHRoZSBzcGVjaWZpZWQgSWRlbnRpdHlDb25zdHJhaW50LiAqLwotICAgICAgICBwdWJsaWMgVmFsdWVTdG9yZUJhc2UgZ2V0R2xvYmFsVmFsdWVTdG9yZUZvcihJZGVudGl0eUNvbnN0cmFpbnQgaWQpIHsKLSAgICAgICAgICAgIHJldHVybiBmR2xvYmFsSURDb25zdHJhaW50TWFwLmdldChpZCk7Ci0gICAgICAgIH0gLy8gZ2V0VmFsdWVTdG9yZUZvcihJZGVudGl0eUNvbnN0cmFpbnQpOlZhbHVlU3RvcmVCYXNlCi0KLSAgICAgICAgLy8gVGhpcyBtZXRob2QgdGFrZXMgdGhlIGNvbnRlbnRzIG9mIHRoZSAobG9jYWwpIFZhbHVlU3RvcmUKLSAgICAgICAgLy8gYXNzb2NpYXRlZCB3aXRoIGlkIGFuZCBtb3ZlcyB0aGVtIGludG8gdGhlIGdsb2JhbAotICAgICAgICAvLyBtYXAsIGlmIGlkIGlzIGEgPHVuaXF1ZT4gb3IgYSA8a2V5Pi4KLSAgICAgICAgLy8gSWYgaXQncyBhIDxrZXlSZWY+LCB0aGVuIHdlIGxlYXZlIGl0IGZvciBsYXRlci4KLSAgICAgICAgcHVibGljIHZvaWQgdHJhbnNwbGFudChJZGVudGl0eUNvbnN0cmFpbnQgaWQsIGludCBpbml0aWFsRGVwdGgpIHsKLSAgICAgICAgICAgIGZMb2NhbElkLmZEZXB0aCA9IGluaXRpYWxEZXB0aDsKLSAgICAgICAgICAgIGZMb2NhbElkLmZJZCA9IGlkOwotICAgICAgICAgICAgVmFsdWVTdG9yZUJhc2UgbmV3VmFscyA9IGZJZGVudGl0eUNvbnN0cmFpbnQyVmFsdWVTdG9yZU1hcC5nZXQoZkxvY2FsSWQpOwotICAgICAgICAgICAgaWYgKGlkLmdldENhdGVnb3J5KCkgPT0gSWRlbnRpdHlDb25zdHJhaW50LklDX0tFWVJFRikKLSAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICBWYWx1ZVN0b3JlQmFzZSBjdXJyVmFscyA9IGZHbG9iYWxJRENvbnN0cmFpbnRNYXAuZ2V0KGlkKTsKLSAgICAgICAgICAgIGlmIChjdXJyVmFscyAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgY3VyclZhbHMuYXBwZW5kKG5ld1ZhbHMpOwotICAgICAgICAgICAgICAgIGZHbG9iYWxJRENvbnN0cmFpbnRNYXAucHV0KGlkLCBjdXJyVmFscyk7Ci0gICAgICAgICAgICB9IGVsc2UKLSAgICAgICAgICAgICAgICBmR2xvYmFsSURDb25zdHJhaW50TWFwLnB1dChpZCwgbmV3VmFscyk7Ci0KLSAgICAgICAgfSAvLyB0cmFuc3BsYW50KGlkKQotCi0gICAgICAgIC8qKiBDaGVjayBpZGVudGl0eSBjb25zdHJhaW50cy4gKi8KLSAgICAgICAgcHVibGljIHZvaWQgZW5kRG9jdW1lbnQoKSB7Ci0KLSAgICAgICAgICAgIGludCBjb3VudCA9IGZWYWx1ZVN0b3Jlcy5zaXplKCk7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKLSAgICAgICAgICAgICAgICBWYWx1ZVN0b3JlQmFzZSB2YWx1ZVN0b3JlID0gKFZhbHVlU3RvcmVCYXNlKSBmVmFsdWVTdG9yZXMuZWxlbWVudEF0KGkpOwotICAgICAgICAgICAgICAgIHZhbHVlU3RvcmUuZW5kRG9jdW1lbnQoKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICB9IC8vIGVuZERvY3VtZW50KCkKLQotICAgICAgICAvLwotICAgICAgICAvLyBPYmplY3QgbWV0aG9kcwotICAgICAgICAvLwotCi0gICAgICAgIC8qKiBSZXR1cm5zIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgb2JqZWN0LiAqLwotICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgICAgICAgICAgU3RyaW5nIHMgPSBzdXBlci50b1N0cmluZygpOwotICAgICAgICAgICAgaW50IGluZGV4MSA9IHMubGFzdEluZGV4T2YoJyQnKTsKLSAgICAgICAgICAgIGlmIChpbmRleDEgIT0gLTEpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gcy5zdWJzdHJpbmcoaW5kZXgxICsgMSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpbnQgaW5kZXgyID0gcy5sYXN0SW5kZXhPZignLicpOwotICAgICAgICAgICAgaWYgKGluZGV4MiAhPSAtMSkgewotICAgICAgICAgICAgICAgIHJldHVybiBzLnN1YnN0cmluZyhpbmRleDIgKyAxKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiBzOwotICAgICAgICB9IC8vIHRvU3RyaW5nKCk6U3RyaW5nCi0KLSAgICB9IC8vIGNsYXNzIFZhbHVlU3RvcmVDYWNoZQotCi0gICAgLy8gdGhlIHB1cnBvc2Ugb2YgdGhpcyBjbGFzcyBpcyB0byBlbmFibGUgSWRlbnRpdHlDb25zdHJhaW50LGludAotICAgIC8vIHBhaXJzIHRvIGJlIHVzZWQgZWFzaWx5IGFzIGtleXMgaW4gTWFwcy4KLSAgICBwcm90ZWN0ZWQgY2xhc3MgTG9jYWxJREtleSB7Ci0KLSAgICAgICAgcHVibGljIElkZW50aXR5Q29uc3RyYWludCBmSWQ7Ci0gICAgICAgIHB1YmxpYyBpbnQgZkRlcHRoOwotCi0gICAgICAgIHB1YmxpYyBMb2NhbElES2V5KCkgewotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIExvY2FsSURLZXkoSWRlbnRpdHlDb25zdHJhaW50IGlkLCBpbnQgZGVwdGgpIHsKLSAgICAgICAgICAgIGZJZCA9IGlkOwotICAgICAgICAgICAgZkRlcHRoID0gZGVwdGg7Ci0gICAgICAgIH0gLy8gaW5pdChJZGVudGl0eUNvbnN0cmFpbnQsIGludCkKLQotICAgICAgICAvLyBvYmplY3QgbWV0aG9kCi0gICAgICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7Ci0gICAgICAgICAgICByZXR1cm4gZklkLmhhc2hDb2RlKCkgKyBmRGVwdGg7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IGxvY2FsSURLZXkpIHsKLSAgICAgICAgICAgIGlmIChsb2NhbElES2V5IGluc3RhbmNlb2YgTG9jYWxJREtleSkgewotICAgICAgICAgICAgICAgIExvY2FsSURLZXkgbElES2V5ID0gKExvY2FsSURLZXkpIGxvY2FsSURLZXk7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIChsSURLZXkuZklkID09IGZJZCAmJiBsSURLZXkuZkRlcHRoID09IGZEZXB0aCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLSAgICB9IC8vIGNsYXNzIExvY2FsSURLZXkKLQotICAgIC8qKgotICAgICAqIEEgc2ltcGxlIHZlY3RvciBmb3IgPGNvZGU+c2hvcnQ8L2NvZGU+cy4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGNsYXNzIFNob3J0VmVjdG9yIHsKLQotICAgICAgICAvLwotICAgICAgICAvLyBEYXRhCi0gICAgICAgIC8vCi0KLSAgICAgICAgLyoqIEN1cnJlbnQgbGVuZ3RoLiAqLwotICAgICAgICBwcml2YXRlIGludCBmTGVuZ3RoOwotCi0gICAgICAgIC8qKiBEYXRhLiAqLwotICAgICAgICBwcml2YXRlIHNob3J0W10gZkRhdGE7Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gQ29uc3RydWN0b3JzCi0gICAgICAgIC8vCi0KLSAgICAgICAgcHVibGljIFNob3J0VmVjdG9yKCkge30KLQotICAgICAgICBwdWJsaWMgU2hvcnRWZWN0b3IoaW50IGluaXRpYWxDYXBhY2l0eSkgewotICAgICAgICAgICAgZkRhdGEgPSBuZXcgc2hvcnRbaW5pdGlhbENhcGFjaXR5XTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIFB1YmxpYyBtZXRob2RzCi0gICAgICAgIC8vCi0KLSAgICAgICAgLyoqIFJldHVybnMgdGhlIGxlbmd0aCBvZiB0aGUgdmVjdG9yLiAqLwotICAgICAgICBwdWJsaWMgaW50IGxlbmd0aCgpIHsKLSAgICAgICAgICAgIHJldHVybiBmTGVuZ3RoOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqIEFkZHMgdGhlIHZhbHVlIHRvIHRoZSB2ZWN0b3IuICovCi0gICAgICAgIHB1YmxpYyB2b2lkIGFkZChzaG9ydCB2YWx1ZSkgewotICAgICAgICAgICAgZW5zdXJlQ2FwYWNpdHkoZkxlbmd0aCArIDEpOwotICAgICAgICAgICAgZkRhdGFbZkxlbmd0aCsrXSA9IHZhbHVlOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqIFJldHVybnMgdGhlIHNob3J0IHZhbHVlIGF0IHRoZSBzcGVjaWZpZWQgcG9zaXRpb24gaW4gdGhlIHZlY3Rvci4gKi8KLSAgICAgICAgcHVibGljIHNob3J0IHZhbHVlQXQoaW50IHBvc2l0aW9uKSB7Ci0gICAgICAgICAgICByZXR1cm4gZkRhdGFbcG9zaXRpb25dOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqIENsZWFycyB0aGUgdmVjdG9yLiAqLwotICAgICAgICBwdWJsaWMgdm9pZCBjbGVhcigpIHsKLSAgICAgICAgICAgIGZMZW5ndGggPSAwOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqIFJldHVybnMgd2hldGhlciB0aGUgc2hvcnQgaXMgY29udGFpbmVkIGluIHRoZSB2ZWN0b3IuICovCi0gICAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKHNob3J0IHZhbHVlKSB7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZMZW5ndGg7ICsraSkgewotICAgICAgICAgICAgICAgIGlmIChmRGF0YVtpXSA9PSB2YWx1ZSkgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLQotICAgICAgICAvLwotICAgICAgICAvLyBQcml2YXRlIG1ldGhvZHMKLSAgICAgICAgLy8KLQotICAgICAgICAvKiogRW5zdXJlcyBjYXBhY2l0eS4gKi8KLSAgICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUNhcGFjaXR5KGludCBzaXplKSB7Ci0gICAgICAgICAgICBpZiAoZkRhdGEgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZEYXRhID0gbmV3IHNob3J0WzhdOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoZkRhdGEubGVuZ3RoIDw9IHNpemUpIHsKLSAgICAgICAgICAgICAgICBzaG9ydFtdIG5ld2RhdGEgPSBuZXcgc2hvcnRbZkRhdGEubGVuZ3RoICogMl07Ci0gICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShmRGF0YSwgMCwgbmV3ZGF0YSwgMCwgZkRhdGEubGVuZ3RoKTsKLSAgICAgICAgICAgICAgICBmRGF0YSA9IG5ld2RhdGE7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLX0gLy8gY2xhc3MgU2NoZW1hVmFsaWRhdG9yCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL1hTQW5ub3RhdGlvbkltcGwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvWFNBbm5vdGF0aW9uSW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlNmU5MzNjLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvWFNBbm5vdGF0aW9uSW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTg3ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54czsKLQotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci1pbXBvcnQgamF2YS5pby5TdHJpbmdSZWFkZXI7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbS5Db3JlRG9jdW1lbnRJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwucGFyc2Vycy5ET01QYXJzZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5wYXJzZXJzLlNBWFBhcnNlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTQW5ub3RhdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNOYW1lc3BhY2VJdGVtOwotCi1pbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7Ci1pbXBvcnQgb3JnLnczYy5kb20uRWxlbWVudDsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotaW1wb3J0IG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LklucHV0U291cmNlOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKLS8qKgotICogVGhpcyBpcyBhbiBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgWFNBbm5vdGF0aW9uIHNjaGVtYSBjb21wb25lbnQuCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICovCi1wdWJsaWMgY2xhc3MgWFNBbm5vdGF0aW9uSW1wbCBpbXBsZW1lbnRzIFhTQW5ub3RhdGlvbiB7Ci0KLSAgICAvLyBEYXRhCi0KLSAgICAvLyB0aGUgY29udGVudCBvZiB0aGUgYW5ub3RhdGlvbiBub2RlLCBpbmNsdWRpbmcgYWxsIGNoaWxkcmVuLCBhbG9uZwotICAgIC8vIHdpdGggYW55IG5vbi1zY2hlbWEgYXR0cmlidXRlcyBmcm9tIGl0cyBwYXJlbnQKLSAgICBwcml2YXRlIFN0cmluZyBmRGF0YSA9IG51bGw7Ci0KLSAgICAvLyB0aGUgZ3JhbW1hciB3aGljaCBvd25zIHRoaXMgYW5ub3RhdGlvbjsgd2UgZ2V0IHBhcnNlcnMKLSAgICAvLyBmcm9tIGhlcmUgd2hlbiB3ZSBuZWVkIHRoZW0KLSAgICBwcml2YXRlIFNjaGVtYUdyYW1tYXIgZkdyYW1tYXIgPSBudWxsOwotCi0gICAgLy8gY29uc3RydWN0b3JzCi0gICAgcHVibGljIFhTQW5ub3RhdGlvbkltcGwoU3RyaW5nIGNvbnRlbnRzLCBTY2hlbWFHcmFtbWFyIGdyYW1tYXIpIHsKLSAgICAgICAgZkRhdGEgPSBjb250ZW50czsKLSAgICAgICAgZkdyYW1tYXIgPSBncmFtbWFyOwotICAgIH0KLQotICAgIC8qKgotICAgICAqICBXcml0ZSBjb250ZW50cyBvZiB0aGUgYW5ub3RhdGlvbiB0byB0aGUgc3BlY2lmaWVkIERPTSBvYmplY3QuIElmIHRoZQotICAgICAqIHNwZWNpZmllZCA8Y29kZT50YXJnZXQ8L2NvZGU+IG9iamVjdCBpcyBhIERPTSBpbi1zY29wZSBuYW1lc3BhY2UKLSAgICAgKiBkZWNsYXJhdGlvbnMgZm9yIDxjb2RlPmFubm90YXRpb248L2NvZGU+IGVsZW1lbnQgYXJlIGFkZGVkIGFzCi0gICAgICogYXR0cmlidXRlcyBub2RlcyBvZiB0aGUgc2VyaWFsaXplZCA8Y29kZT5hbm5vdGF0aW9uPC9jb2RlPiwgb3RoZXJ3aXNlCi0gICAgICogdGhlIGNvcnJlc3BvbmRpbmcgZXZlbnRzIGZvciBhbGwgaW4tc2NvcGUgbmFtZXNwYWNlIGRlY2xhcmF0aW9uIGFyZQotICAgICAqIHNlbnQgdmlhIHNwZWNpZmllZCBkb2N1bWVudCBoYW5kbGVyLgotICAgICAqIEBwYXJhbSB0YXJnZXQgIEEgdGFyZ2V0IHBvaW50ZXIgdG8gdGhlIGFubm90YXRpb24gdGFyZ2V0IG9iamVjdCwgaS5lLgotICAgICAqICAgPGNvZGU+b3JnLnczYy5kb20uRG9jdW1lbnQ8L2NvZGU+LAotICAgICAqICAgPGNvZGU+b3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXI8L2NvZGU+LgotICAgICAqIEBwYXJhbSB0YXJnZXRUeXBlICBBIHRhcmdldCB0eXBlLgotICAgICAqIEByZXR1cm4gSWYgdGhlIDxjb2RlPnRhcmdldDwvY29kZT4gaXMgcmVjb2duaXplZCB0eXBlIGFuZCBzdXBwb3J0ZWQgYnkKLSAgICAgKiAgIHRoaXMgaW1wbGVtZW50YXRpb24gcmV0dXJuIHRydWUsIG90aGVyd2lzZSByZXR1cm4gZmFsc2UuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gd3JpdGVBbm5vdGF0aW9uKE9iamVjdCB0YXJnZXQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNob3J0IHRhcmdldFR5cGUpIHsKLSAgICAgICAgaWYodGFyZ2V0VHlwZSA9PSBYU0Fubm90YXRpb24uVzNDX0RPTV9FTEVNRU5UIHx8IHRhcmdldFR5cGUgPT0gWFNBbm5vdGF0aW9uLlczQ19ET01fRE9DVU1FTlQpIHsKLSAgICAgICAgICAgIHdyaXRlVG9ET00oKE5vZGUpdGFyZ2V0LCB0YXJnZXRUeXBlKTsKLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9IGVsc2UgaWYgKHRhcmdldFR5cGUgPT0gU0FYX0NPTlRFTlRIQU5ETEVSKSB7Ci0gICAgICAgICAgICB3cml0ZVRvU0FYKChDb250ZW50SGFuZGxlcil0YXJnZXQpOwotICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEEgdGV4dCByZXByZXNlbnRhdGlvbiBvZiBhbm5vdGF0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0QW5ub3RhdGlvblN0cmluZygpIHsKLSAgICAgICAgcmV0dXJuIGZEYXRhOwotICAgIH0KLQotICAgIC8vIFhTT2JqZWN0IG1ldGhvZHMKLQotICAgIC8qKgotICAgICAqICBUaGUgPGNvZGU+dHlwZTwvY29kZT4gb2YgdGhpcyBvYmplY3QsIGkuZS4KLSAgICAgKiA8Y29kZT5FTEVNRU5UX0RFQ0xBUkFUSU9OPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgc2hvcnQgZ2V0VHlwZSgpIHsKLSAgICAgICAgcmV0dXJuIFhTQ29uc3RhbnRzLkFOTk9UQVRJT047Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhlIG5hbWUgb2YgdHlwZSA8Y29kZT5OQ05hbWU8L2NvZGU+IG9mIHRoaXMgZGVjbGFyYXRpb24gYXMgZGVmaW5lZCBpbgotICAgICAqIFhNTCBOYW1lc3BhY2VzLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogIFRoZSBbdGFyZ2V0IG5hbWVzcGFjZV0gb2YgdGhpcyBvYmplY3QsIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIGl0IGlzCi0gICAgICogdW5zcGVjaWZpZWQuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXROYW1lc3BhY2UoKSB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEEgbmFtZXNwYWNlIHNjaGVtYSBpbmZvcm1hdGlvbiBpdGVtIGNvcnJlc3BvbmRpbmcgdG8gdGhlIHRhcmdldAotICAgICAqIG5hbWVzcGFjZSBvZiB0aGUgY29tcG9uZW50LCBpZiBpdCdzIGdsb2JhbGx5IGRlY2xhcmVkOyBvciBudWxsCi0gICAgICogb3RoZXJ3aXNlLgotICAgICAqLwotICAgIHB1YmxpYyBYU05hbWVzcGFjZUl0ZW0gZ2V0TmFtZXNwYWNlSXRlbSgpIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLy8gcHJpdmF0ZSBtZXRob2RzCi0gICAgcHJpdmF0ZSBzeW5jaHJvbml6ZWQgdm9pZCB3cml0ZVRvU0FYKENvbnRlbnRIYW5kbGVyIGhhbmRsZXIpIHsKLSAgICAgICAgLy8gbm90aGluZyBtdXN0IGdvIHdyb25nIHdpdGggdGhpcyBwYXJzZS4uLgotICAgICAgICBTQVhQYXJzZXIgcGFyc2VyID0gZkdyYW1tYXIuZ2V0U0FYUGFyc2VyKCk7Ci0gICAgICAgIFN0cmluZ1JlYWRlciBhUmVhZGVyID0gbmV3IFN0cmluZ1JlYWRlcihmRGF0YSk7Ci0gICAgICAgIElucHV0U291cmNlIGFTb3VyY2UgPSBuZXcgSW5wdXRTb3VyY2UoYVJlYWRlcik7Ci0gICAgICAgIHBhcnNlci5zZXRDb250ZW50SGFuZGxlcihoYW5kbGVyKTsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIHBhcnNlci5wYXJzZShhU291cmNlKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIC8vIHRoaXMgc2hvdWxkIG5ldmVyIGhhcHBlbiEKLSAgICAgICAgICAgIC8vIFJFVklTSVQ6ICB3aGF0IHRvIGRvIHdpdGggdGhpcz87IHNob3VsZCByZWFsbHkgbm90Ci0gICAgICAgICAgICAvLyBlYXQgaXQuLi4KLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoSU9FeGNlcHRpb24gaSkgewotICAgICAgICAgICAgLy8gZGl0dG8gd2l0aCBhYm92ZQotICAgICAgICB9Ci0gICAgICAgIC8vIFJlbGVhc2UgdGhlIHJlZmVyZW5jZSB0byB0aGUgdXNlcidzIENvbnRlbnRIYW5kbGVyLgotICAgICAgICBwYXJzZXIuc2V0Q29udGVudEhhbmRsZXIobnVsbCk7Ci0gICAgfQotCi0gICAgLy8gdGhpcyBjcmVhdGVzIHRoZSBuZXcgQW5ub3RhdGlvbiBlbGVtZW50IGFzIHRoZSBmaXJzdCBjaGlsZAotICAgIC8vIG9mIHRoZSBOb2RlCi0gICAgcHJpdmF0ZSBzeW5jaHJvbml6ZWQgdm9pZCB3cml0ZVRvRE9NKE5vZGUgdGFyZ2V0LCBzaG9ydCB0eXBlKSB7Ci0gICAgICAgIERvY3VtZW50IGZ1dHVyZU93bmVyID0gKHR5cGUgPT0gWFNBbm5vdGF0aW9uLlczQ19ET01fRUxFTUVOVCkgPwotICAgICAgICAgICAgICAgIHRhcmdldC5nZXRPd25lckRvY3VtZW50KCkgOiAoRG9jdW1lbnQpdGFyZ2V0OwotICAgICAgICBET01QYXJzZXIgcGFyc2VyID0gZkdyYW1tYXIuZ2V0RE9NUGFyc2VyKCk7Ci0gICAgICAgIFN0cmluZ1JlYWRlciBhUmVhZGVyID0gbmV3IFN0cmluZ1JlYWRlcihmRGF0YSk7Ci0gICAgICAgIElucHV0U291cmNlIGFTb3VyY2UgPSBuZXcgSW5wdXRTb3VyY2UoYVJlYWRlcik7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBwYXJzZXIucGFyc2UoYVNvdXJjZSk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAvLyB0aGlzIHNob3VsZCBuZXZlciBoYXBwZW4hCi0gICAgICAgICAgICAvLyBSRVZJU0lUOiAgd2hhdCB0byBkbyB3aXRoIHRoaXM/OyBzaG91bGQgcmVhbGx5IG5vdAotICAgICAgICAgICAgLy8gZWF0IGl0Li4uCi0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKElPRXhjZXB0aW9uIGkpIHsKLSAgICAgICAgICAgIC8vIGRpdHRvIHdpdGggYWJvdmUKLSAgICAgICAgfQotICAgICAgICBEb2N1bWVudCBhRG9jdW1lbnQgPSBwYXJzZXIuZ2V0RG9jdW1lbnQoKTsKLSAgICAgICAgcGFyc2VyLmRyb3BEb2N1bWVudFJlZmVyZW5jZXMoKTsKLSAgICAgICAgRWxlbWVudCBhbm5vdGF0aW9uID0gYURvY3VtZW50LmdldERvY3VtZW50RWxlbWVudCgpOwotICAgICAgICBOb2RlIG5ld0VsZW0gPSBudWxsOwotICAgICAgICBpZiAoZnV0dXJlT3duZXIgaW5zdGFuY2VvZiBDb3JlRG9jdW1lbnRJbXBsKSB7Ci0gICAgICAgICAgICBuZXdFbGVtID0gZnV0dXJlT3duZXIuYWRvcHROb2RlKGFubm90YXRpb24pOwotICAgICAgICAgICAgLy8gYWRvcHROb2RlIHdpbGwgcmV0dXJuIG51bGwgd2hlbiB0aGUgRE9NIGltcGxlbWVudGF0aW9ucyBhcmUgbm90IGNvbXBhdGlibGUuCi0gICAgICAgICAgICBpZiAobmV3RWxlbSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgbmV3RWxlbSA9IGZ1dHVyZU93bmVyLmltcG9ydE5vZGUoYW5ub3RhdGlvbiwgdHJ1ZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBuZXdFbGVtID0gZnV0dXJlT3duZXIuaW1wb3J0Tm9kZShhbm5vdGF0aW9uLCB0cnVlKTsKLSAgICAgICAgfQotICAgICAgICB0YXJnZXQuaW5zZXJ0QmVmb3JlKG5ld0VsZW0sIHRhcmdldC5nZXRGaXJzdENoaWxkKCkpOwotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9YU0F0dHJpYnV0ZURlY2wuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvWFNBdHRyaWJ1dGVEZWNsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDE4M2M2ZjIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9YU0F0dHJpYnV0ZURlY2wuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIxNSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54czsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5WYWxpZGF0ZWRJbmZvOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5YU1NpbXBsZVR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLnV0aWwuWFNPYmplY3RMaXN0SW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5RTmFtZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlNob3J0TGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTQW5ub3RhdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTQXR0cmlidXRlRGVjbGFyYXRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU0NvbXBsZXhUeXBlRGVmaW5pdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNOYW1lc3BhY2VJdGVtOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNPYmplY3RMaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNTaW1wbGVUeXBlRGVmaW5pdGlvbjsKLQotLyoqCi0gKiBUaGUgWE1MIHJlcHJlc2VudGF0aW9uIGZvciBhbiBhdHRyaWJ1dGUgZGVjbGFyYXRpb24KLSAqIHNjaGVtYSBjb21wb25lbnQgaXMgYW4gPGF0dHJpYnV0ZT4gZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgRWxlbmEgTGl0YW5pLCBJQk0KLSAqIEBhdXRob3IgU2FuZHkgR2FvLCBJQk0KLSAqIEB2ZXJzaW9uICRJZDogWFNBdHRyaWJ1dGVEZWNsLmphdmEsdiAxLjcgMjAxMC0xMS0wMSAwNDozOTo1NSBqb2VodyBFeHAgJAotICovCi1wdWJsaWMgY2xhc3MgWFNBdHRyaWJ1dGVEZWNsIGltcGxlbWVudHMgWFNBdHRyaWJ1dGVEZWNsYXJhdGlvbiB7Ci0KLSAgICAvLyBzY29wZXMKLSAgICBwdWJsaWMgZmluYWwgc3RhdGljIHNob3J0ICAgICBTQ09QRV9BQlNFTlQgICAgICAgID0gMDsKLSAgICBwdWJsaWMgZmluYWwgc3RhdGljIHNob3J0ICAgICBTQ09QRV9HTE9CQUwgICAgICAgID0gMTsKLSAgICBwdWJsaWMgZmluYWwgc3RhdGljIHNob3J0ICAgICBTQ09QRV9MT0NBTCAgICAgICAgID0gMjsKLQotICAgIC8vIHRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUKLSAgICBTdHJpbmcgZk5hbWUgPSBudWxsOwotICAgIC8vIHRoZSB0YXJnZXQgbmFtZXNwYWNlIG9mIHRoZSBhdHRyaWJ1dGUKLSAgICBTdHJpbmcgZlRhcmdldE5hbWVzcGFjZSA9IG51bGw7Ci0gICAgLy8gdGhlIHNpbXBsZSB0eXBlIG9mIHRoZSBhdHRyaWJ1dGUKLSAgICBYU1NpbXBsZVR5cGUgZlR5cGUgPSBudWxsOwotICAgIHB1YmxpYyBRTmFtZSBmVW5yZXNvbHZlZFR5cGVOYW1lID0gbnVsbDsKLSAgICAvLyB2YWx1ZSBjb25zdHJhaW50IHR5cGU6IGRlZmF1bHQsIGZpeGVkIG9yICFzcGVjaWZpZWQKLSAgICBzaG9ydCBmQ29uc3RyYWludFR5cGUgPSBYU0NvbnN0YW50cy5WQ19OT05FOwotICAgIC8vIHNjb3BlCi0gICAgc2hvcnQgZlNjb3BlID0gWFNDb25zdGFudHMuU0NPUEVfQUJTRU5UOwotICAgIC8vIGVuY2xvc2luZyBjb21wbGV4IHR5cGUsIHdoZW4gdGhlIHNjb3BlIGlzIGxvY2FsCi0gICAgWFNDb21wbGV4VHlwZURlY2wgZkVuY2xvc2luZ0NUID0gbnVsbDsKLSAgICAvLyBvcHRpb25hbCBhbm5vdGF0aW9ucwotICAgIFhTT2JqZWN0TGlzdCBmQW5ub3RhdGlvbnMgPSBudWxsOwotICAgIC8vIHZhbHVlIGNvbnN0cmFpbnQgdmFsdWUKLSAgICBWYWxpZGF0ZWRJbmZvIGZEZWZhdWx0ID0gbnVsbDsKLSAgICAvLyBUaGUgbmFtZXNwYWNlIHNjaGVtYSBpbmZvcm1hdGlvbiBpdGVtIGNvcnJlc3BvbmRpbmcgdG8gdGhlIHRhcmdldCBuYW1lc3BhY2UKLSAgICAvLyBvZiB0aGUgYXR0cmlidXRlIGRlY2xhcmF0aW9uLCBpZiBpdCBpcyBnbG9iYWxseSBkZWNsYXJlZDsgb3IgbnVsbCBvdGhlcndpc2UuCi0gICAgcHJpdmF0ZSBYU05hbWVzcGFjZUl0ZW0gZk5hbWVzcGFjZUl0ZW0gPSBudWxsOwotCi0gICAgcHVibGljIHZvaWQgc2V0VmFsdWVzKFN0cmluZyBuYW1lLCBTdHJpbmcgdGFyZ2V0TmFtZXNwYWNlLAotICAgICAgICAgICAgWFNTaW1wbGVUeXBlIHNpbXBsZVR5cGUsIHNob3J0IGNvbnN0cmFpbnRUeXBlLCBzaG9ydCBzY29wZSwKLSAgICAgICAgICAgIFZhbGlkYXRlZEluZm8gdmFsSW5mbywgWFNDb21wbGV4VHlwZURlY2wgZW5jbG9zaW5nQ1QsCi0gICAgICAgICAgICBYU09iamVjdExpc3QgYW5ub3RhdGlvbnMpIHsKLSAgICAgICAgZk5hbWUgPSBuYW1lOwotICAgICAgICBmVGFyZ2V0TmFtZXNwYWNlID0gdGFyZ2V0TmFtZXNwYWNlOwotICAgICAgICBmVHlwZSA9IHNpbXBsZVR5cGU7Ci0gICAgICAgIGZDb25zdHJhaW50VHlwZSA9IGNvbnN0cmFpbnRUeXBlOwotICAgICAgICBmU2NvcGUgPSBzY29wZTsKLSAgICAgICAgZkRlZmF1bHQgPSB2YWxJbmZvOwotICAgICAgICBmRW5jbG9zaW5nQ1QgPSBlbmNsb3NpbmdDVDsKLSAgICAgICAgZkFubm90YXRpb25zID0gYW5ub3RhdGlvbnM7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgcmVzZXQoKXsKLSAgICAgICAgZk5hbWUgPSBudWxsOwotICAgICAgICBmVGFyZ2V0TmFtZXNwYWNlID0gbnVsbDsKLSAgICAgICAgZlR5cGUgPSBudWxsOwotICAgICAgICBmVW5yZXNvbHZlZFR5cGVOYW1lID0gbnVsbDsKLSAgICAgICAgZkNvbnN0cmFpbnRUeXBlID0gWFNDb25zdGFudHMuVkNfTk9ORTsKLSAgICAgICAgZlNjb3BlID0gWFNDb25zdGFudHMuU0NPUEVfQUJTRU5UOwotICAgICAgICBmRGVmYXVsdCA9IG51bGw7Ci0gICAgICAgIGZBbm5vdGF0aW9ucyA9IG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSB0eXBlIG9mIHRoZSBvYmplY3QsIGkuZSBFTEVNRU5UX0RFQ0xBUkFUSU9OLgotICAgICAqLwotICAgIHB1YmxpYyBzaG9ydCBnZXRUeXBlKCkgewotICAgICAgICByZXR1cm4gWFNDb25zdGFudHMuQVRUUklCVVRFX0RFQ0xBUkFUSU9OOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoZSA8Y29kZT5uYW1lPC9jb2RlPiBvZiB0aGlzIDxjb2RlPlhTT2JqZWN0PC9jb2RlPiBkZXBlbmRpbmcgb24gdGhlCi0gICAgICogPGNvZGU+WFNPYmplY3Q8L2NvZGU+IHR5cGUuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXROYW1lKCkgewotICAgICAgICByZXR1cm4gZk5hbWU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhlIG5hbWVzcGFjZSBVUkkgb2YgdGhpcyBub2RlLCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiBpdCBpcwotICAgICAqIHVuc3BlY2lmaWVkLiAgZGVmaW5lcyBob3cgYSBuYW1lc3BhY2UgVVJJIGlzIGF0dGFjaGVkIHRvIHNjaGVtYQotICAgICAqIGNvbXBvbmVudHMuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXROYW1lc3BhY2UoKSB7Ci0gICAgICAgIHJldHVybiBmVGFyZ2V0TmFtZXNwYWNlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEEgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbgotICAgICAqLwotICAgIHB1YmxpYyBYU1NpbXBsZVR5cGVEZWZpbml0aW9uIGdldFR5cGVEZWZpbml0aW9uKCkgewotICAgICAgICByZXR1cm4gZlR5cGU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogT3B0aW9uYWwuIEVpdGhlciBnbG9iYWwgb3IgYSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbiAoCi0gICAgICogPGNvZGU+Y3REZWZpbml0aW9uPC9jb2RlPikuIFRoaXMgcHJvcGVydHkgaXMgYWJzZW50IGluIHRoZSBjYXNlIG9mCi0gICAgICogZGVjbGFyYXRpb25zIHdpdGhpbiBhdHRyaWJ1dGUgZ3JvdXAgZGVmaW5pdGlvbnM6IHRoZWlyIHNjb3BlIHdpbGwgYmUKLSAgICAgKiBkZXRlcm1pbmVkIHdoZW4gdGhleSBhcmUgdXNlZCBpbiB0aGUgY29uc3RydWN0aW9uIG9mIGNvbXBsZXggdHlwZQotICAgICAqIGRlZmluaXRpb25zLgotICAgICAqLwotICAgIHB1YmxpYyBzaG9ydCBnZXRTY29wZSgpIHsKLSAgICAgICAgcmV0dXJuIGZTY29wZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBMb2NhbGx5IHNjb3BlZCBkZWNsYXJhdGlvbnMgYXJlIGF2YWlsYWJsZSBmb3IgdXNlIG9ubHkgd2l0aGluIHRoZQotICAgICAqIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uIGlkZW50aWZpZWQgYnkgdGhlIDxjb2RlPnNjb3BlPC9jb2RlPgotICAgICAqIHByb3BlcnR5LgotICAgICAqLwotICAgIHB1YmxpYyBYU0NvbXBsZXhUeXBlRGVmaW5pdGlvbiBnZXRFbmNsb3NpbmdDVERlZmluaXRpb24oKSB7Ci0gICAgICAgIHJldHVybiBmRW5jbG9zaW5nQ1Q7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVmFsdWUgY29uc3RyYWludDogb25lIG9mIGRlZmF1bHQsIGZpeGVkLgotICAgICAqLwotICAgIHB1YmxpYyBzaG9ydCBnZXRDb25zdHJhaW50VHlwZSgpIHsKLSAgICAgICAgcmV0dXJuIGZDb25zdHJhaW50VHlwZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBWYWx1ZSBjb25zdHJhaW50OiBUaGUgYWN0dWFsIHZhbHVlICh3aXRoIHJlc3BlY3QgdG8gdGhlIHt0eXBlCi0gICAgICogZGVmaW5pdGlvbn0pIFNob3VsZCB3ZSByZXR1cm4gT2JqZWN0IGluc3RlYWQgb2YgRE9NU3RyaW5nPwotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q29uc3RyYWludFZhbHVlKCkgewotICAgICAgICAvLyBSRVZJU0lUOiBTQ0FQSTogd2hhdCdzIHRoZSBwcm9wZXIgcmVwcmVzZW50YXRpb24KLSAgICAgICAgcmV0dXJuIGdldENvbnN0cmFpbnRUeXBlKCkgPT0gWFNDb25zdGFudHMuVkNfTk9ORSA/Ci0gICAgICAgICAgICAgICBudWxsIDoKLSAgICAgICAgICAgICAgIGZEZWZhdWx0LnN0cmluZ1ZhbHVlKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogT3B0aW9uYWwuIEFubm90YXRpb24uCi0gICAgICovCi0gICAgcHVibGljIFhTQW5ub3RhdGlvbiBnZXRBbm5vdGF0aW9uKCkgewotICAgICAgICByZXR1cm4gKGZBbm5vdGF0aW9ucyAhPSBudWxsKSA/IChYU0Fubm90YXRpb24pIGZBbm5vdGF0aW9ucy5pdGVtKDApIDogbnVsbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBPcHRpb25hbC4gQW5ub3RhdGlvbnMuCi0gICAgICovCi0gICAgcHVibGljIFhTT2JqZWN0TGlzdCBnZXRBbm5vdGF0aW9ucygpIHsKLSAgICAgICAgcmV0dXJuIChmQW5ub3RhdGlvbnMgIT0gbnVsbCkgPyBmQW5ub3RhdGlvbnMgOiBYU09iamVjdExpc3RJbXBsLkVNUFRZX0xJU1Q7Ci0gICAgfQotCi0gICAgcHVibGljIFZhbGlkYXRlZEluZm8gZ2V0VmFsSW5mbygpIHsKLSAgICAgICAgcmV0dXJuIGZEZWZhdWx0OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgb3JnLmFwYWNoZS54ZXJjZXMueHMuWFNPYmplY3QjZ2V0TmFtZXNwYWNlSXRlbSgpCi0gICAgICovCi0gICAgcHVibGljIFhTTmFtZXNwYWNlSXRlbSBnZXROYW1lc3BhY2VJdGVtKCkgewotICAgICAgICByZXR1cm4gZk5hbWVzcGFjZUl0ZW07Ci0gICAgfQotCi0gICAgdm9pZCBzZXROYW1lc3BhY2VJdGVtKFhTTmFtZXNwYWNlSXRlbSBuYW1lc3BhY2VJdGVtKSB7Ci0gICAgICAgIGZOYW1lc3BhY2VJdGVtID0gbmFtZXNwYWNlSXRlbTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgT2JqZWN0IGdldEFjdHVhbFZDKCkgewotICAgICAgICByZXR1cm4gZ2V0Q29uc3RyYWludFR5cGUoKSA9PSBYU0NvbnN0YW50cy5WQ19OT05FID8KLSAgICAgICAgICAgICAgIG51bGwgOgotICAgICAgICAgICAgICAgZkRlZmF1bHQuYWN0dWFsVmFsdWU7Ci0gICAgfQotCi0gICAgcHVibGljIHNob3J0IGdldEFjdHVhbFZDVHlwZSgpIHsKLSAgICAgICAgcmV0dXJuIGdldENvbnN0cmFpbnRUeXBlKCkgPT0gWFNDb25zdGFudHMuVkNfTk9ORSA/Ci0gICAgICAgICAgICAgICBYU0NvbnN0YW50cy5VTkFWQUlMQUJMRV9EVCA6Ci0gICAgICAgICAgICAgICBmRGVmYXVsdC5hY3R1YWxWYWx1ZVR5cGU7Ci0gICAgfQotCi0gICAgcHVibGljIFNob3J0TGlzdCBnZXRJdGVtVmFsdWVUeXBlcygpIHsKLSAgICAgICAgcmV0dXJuIGdldENvbnN0cmFpbnRUeXBlKCkgPT0gWFNDb25zdGFudHMuVkNfTk9ORSA/Ci0gICAgICAgICAgICAgICBudWxsIDoKLSAgICAgICAgICAgICAgIGZEZWZhdWx0Lml0ZW1WYWx1ZVR5cGVzOwotICAgIH0KLQotfSAvLyBjbGFzcyBYU0F0dHJpYnV0ZURlY2wKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvWFNBdHRyaWJ1dGVHcm91cERlY2wuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvWFNBdHRyaWJ1dGVHcm91cERlY2wuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOGU5MDcwNS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL1hTQXR0cmlidXRlR3JvdXBEZWNsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0MDIgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYuVmFsaWRhdGVkSW5mbzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMudXRpbC5YU09iamVjdExpc3RJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNBbm5vdGF0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNBdHRyaWJ1dGVHcm91cERlZmluaXRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU0F0dHJpYnV0ZVVzZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNOYW1lc3BhY2VJdGVtOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNPYmplY3RMaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNXaWxkY2FyZDsKLQotLyoqCi0gKiBUaGUgWE1MIHJlcHJlc2VudGF0aW9uIGZvciBhbiBhdHRyaWJ1dGUgZ3JvdXAgZGVjbGFyYXRpb24KLSAqIHNjaGVtYSBjb21wb25lbnQgaXMgYSBnbG9iYWwgPGF0dHJpYnV0ZUdyb3VwPiBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBTYW5keSBHYW8sIElCTQotICogQGF1dGhvciBSYWh1bCBTcml2YXN0YXZhLCBTdW4gTWljcm9zeXN0ZW1zIEluYy4KLSAqCi0gKiBAdmVyc2lvbiAkSWQ6IFhTQXR0cmlidXRlR3JvdXBEZWNsLmphdmEsdiAxLjcgMjAxMC0xMS0wMSAwNDozOTo1NSBqb2VodyBFeHAgJAotICovCi1wdWJsaWMgY2xhc3MgWFNBdHRyaWJ1dGVHcm91cERlY2wgaW1wbGVtZW50cyBYU0F0dHJpYnV0ZUdyb3VwRGVmaW5pdGlvbiB7Ci0KLSAgICAvLyBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUgZ3JvdXAKLSAgICBwdWJsaWMgU3RyaW5nIGZOYW1lID0gbnVsbDsKLSAgICAvLyB0YXJnZXQgbmFtZXNwYWNlIG9mIHRoZSBhdHRyaWJ1dGUgZ3JvdXAKLSAgICBwdWJsaWMgU3RyaW5nIGZUYXJnZXROYW1lc3BhY2UgPSBudWxsOwotICAgIC8vIG51bWJlciBvZiBhdHRyaWJ1dGUgdXNlcyBpbmNsdWRlZCBieSB0aGlzIGF0dHJpYnV0ZSBncm91cAotICAgIGludCBmQXR0clVzZU51bSA9IDA7Ci0gICAgLy8gYXR0cmlidXRlIHVzZXMgaW5jbHVkZWQgYnkgdGhpcyBhdHRyaWJ1dGUgZ3JvdXAKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgSU5JVElBTF9TSVpFID0gNTsKLSAgICBYU0F0dHJpYnV0ZVVzZUltcGxbXSBmQXR0cmlidXRlVXNlcyA9IG5ldyBYU0F0dHJpYnV0ZVVzZUltcGxbSU5JVElBTF9TSVpFXTsKLSAgICAvLyBhdHRyaWJ1dGUgd2lsZGNhcmQgaW5jbHVkZWQgYnkgdGhpcyBhdHRyaWJ1dGUgZ3JvdXAKLSAgICBwdWJsaWMgWFNXaWxkY2FyZERlY2wgZkF0dHJpYnV0ZVdDID0gbnVsbDsKLSAgICAvLyB3aGV0aGVyIHRoZXJlIGlzIGFuIGF0dHJpYnV0ZSB1c2Ugd2hvc2UgdHlwZSBpcyBvciBpcyBkZXJpdmVkIGZyb20gSUQuCi0gICAgcHVibGljIFN0cmluZyBmSURBdHRyTmFtZSA9IG51bGw7Ci0KLSAgICAvLyBvcHRpb25hbCBhbm5vdGF0aW9uCi0gICAgcHVibGljIFhTT2JqZWN0TGlzdCBmQW5ub3RhdGlvbnM7Ci0KLSAgICBwcm90ZWN0ZWQgWFNPYmplY3RMaXN0SW1wbCBmQXR0clVzZXMgPSBudWxsOwotCi0gICAgLy8gVGhlIG5hbWVzcGFjZSBzY2hlbWEgaW5mb3JtYXRpb24gaXRlbSBjb3JyZXNwb25kaW5nIHRvIHRoZSB0YXJnZXQgbmFtZXNwYWNlCi0gICAgLy8gb2YgdGhlIGF0dHJpYnV0ZSBncm91cCBkZWZpbml0aW9uLCBpZiBpdCBpcyBnbG9iYWxseSBkZWNsYXJlZDsgb3IgbnVsbCBvdGhlcndpc2UuCi0gICAgcHJpdmF0ZSBYU05hbWVzcGFjZUl0ZW0gZk5hbWVzcGFjZUl0ZW0gPSBudWxsOwotCi0gICAgLy8gYWRkIGFuIGF0dHJpYnV0ZSB1c2UKLSAgICAvLyBpZiB0aGUgdHlwZSBpcyBkZXJpdmVkIGZyb20gSUQsIGJ1dCB0aGVyZSBpcyBhbHJlYWR5IGFub3RoZXIgYXR0cmlidXRlCi0gICAgLy8gdXNlIG9mIHR5cGUgSUQsIHRoZW4gcmV0dXJuIHRoZSBuYW1lIG9mIHRoZSBvdGhlciBhdHRyaWJ1dGUgdXNlOwotICAgIC8vIG90aGVyd2lzZSwgcmV0dXJuIG51bGwKLSAgICBwdWJsaWMgU3RyaW5nIGFkZEF0dHJpYnV0ZVVzZShYU0F0dHJpYnV0ZVVzZUltcGwgYXR0clVzZSkgewotCi0gICAgICAgIC8vIGlmIHRoaXMgYXR0cmlidXRlIHVzZSBpcyBwcm9oaWJpdGVkLCB0aGVuIGRvbid0IGNoZWNrIHdoZXRoZXIgaXQncwotICAgICAgICAvLyBvZiB0eXBlIElECi0gICAgICAgIGlmIChhdHRyVXNlLmZVc2UgIT0gU2NoZW1hU3ltYm9scy5VU0VfUFJPSElCSVRFRCkgewotICAgICAgICAgICAgaWYgKGF0dHJVc2UuZkF0dHJEZWNsLmZUeXBlLmlzSURUeXBlKCkpIHsKLSAgICAgICAgICAgICAgICAvLyBpZiB0aGVyZSBpcyBhbHJlYWR5IGFuIGF0dHJpYnV0ZSB1c2Ugb2YgdHlwZSBJRCwKLSAgICAgICAgICAgICAgICAvLyByZXR1cm4gaXRzIG5hbWUgKGFuZCBkb24ndCBhZGQgaXQgdG8gdGhlIGxpc3QsIHRvIGF2b2lkCi0gICAgICAgICAgICAgICAgLy8gaW50ZXJydXB0aW9uIHRvIGluc3RhbmNlIHZhbGlkYXRpb24uCi0gICAgICAgICAgICAgICAgaWYgKGZJREF0dHJOYW1lID09IG51bGwpCi0gICAgICAgICAgICAgICAgICAgIGZJREF0dHJOYW1lID0gYXR0clVzZS5mQXR0ckRlY2wuZk5hbWU7Ci0gICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICByZXR1cm4gZklEQXR0ck5hbWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoZkF0dHJVc2VOdW0gPT0gZkF0dHJpYnV0ZVVzZXMubGVuZ3RoKSB7Ci0gICAgICAgICAgICBmQXR0cmlidXRlVXNlcyA9IHJlc2l6ZShmQXR0cmlidXRlVXNlcywgZkF0dHJVc2VOdW0qMik7Ci0gICAgICAgIH0KLSAgICAgICAgZkF0dHJpYnV0ZVVzZXNbZkF0dHJVc2VOdW0rK10gPSBhdHRyVXNlOwotCi0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHJlcGxhY2VBdHRyaWJ1dGVVc2UoWFNBdHRyaWJ1dGVVc2Ugb2xkVXNlLCBYU0F0dHJpYnV0ZVVzZUltcGwgbmV3VXNlKSB7Ci0gICAgICAgIGZvciAoaW50IGk9MDsgaTxmQXR0clVzZU51bTsgaSsrKSB7Ci0gICAgICAgICAgICBpZiAoZkF0dHJpYnV0ZVVzZXNbaV0gPT0gb2xkVXNlKSB7Ci0gICAgICAgICAgICAgICAgZkF0dHJpYnV0ZVVzZXNbaV0gPSBuZXdVc2U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgWFNBdHRyaWJ1dGVVc2UgZ2V0QXR0cmlidXRlVXNlKFN0cmluZyBuYW1lc3BhY2UsIFN0cmluZyBuYW1lKSB7Ci0gICAgICAgIGZvciAoaW50IGk9MDsgaTxmQXR0clVzZU51bTsgaSsrKSB7Ci0gICAgICAgICAgICBpZiAoIChmQXR0cmlidXRlVXNlc1tpXS5mQXR0ckRlY2wuZlRhcmdldE5hbWVzcGFjZSA9PSBuYW1lc3BhY2UpICYmCi0gICAgICAgICAgICAgICAgIChmQXR0cmlidXRlVXNlc1tpXS5mQXR0ckRlY2wuZk5hbWUgPT0gbmFtZSkgKQotICAgICAgICAgICAgICAgIHJldHVybiBmQXR0cmlidXRlVXNlc1tpXTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIHB1YmxpYyBYU0F0dHJpYnV0ZVVzZSBnZXRBdHRyaWJ1dGVVc2VOb1Byb2hpYml0ZWQoU3RyaW5nIG5hbWVzcGFjZSwgU3RyaW5nIG5hbWUpIHsKLSAgICAgICAgZm9yIChpbnQgaT0wOyBpPGZBdHRyVXNlTnVtOyBpKyspIHsKLSAgICAgICAgICAgIGlmICggKGZBdHRyaWJ1dGVVc2VzW2ldLmZBdHRyRGVjbC5mVGFyZ2V0TmFtZXNwYWNlID09IG5hbWVzcGFjZSkgJiYKLSAgICAgICAgICAgICAgICAgKGZBdHRyaWJ1dGVVc2VzW2ldLmZBdHRyRGVjbC5mTmFtZSA9PSBuYW1lKSAmJgotICAgICAgICAgICAgICAgICAoZkF0dHJpYnV0ZVVzZXNbaV0uZlVzZSAhPSBTY2hlbWFTeW1ib2xzLlVTRV9QUk9ISUJJVEVEKSkKLSAgICAgICAgICAgICAgICByZXR1cm4gZkF0dHJpYnV0ZVVzZXNbaV07Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCByZW1vdmVQcm9oaWJpdGVkQXR0cnMoKSB7Ci0gICAgICAgIGlmIChmQXR0clVzZU51bSA9PSAwKSByZXR1cm47Ci0gICAgICAgIC8vIFJlbW92ZSBhbGwgcHJvaGliaXRlZCBhdHRyaWJ1dGVzLgotICAgICAgICBpbnQgY291bnQgPSAwOwotICAgICAgICBYU0F0dHJpYnV0ZVVzZUltcGxbXSB1c2VzID0gbmV3IFhTQXR0cmlidXRlVXNlSW1wbFtmQXR0clVzZU51bV07Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZkF0dHJVc2VOdW07IGkrKykgewotICAgICAgICAgICAgaWYgKGZBdHRyaWJ1dGVVc2VzW2ldLmZVc2UgIT0gU2NoZW1hU3ltYm9scy5VU0VfUFJPSElCSVRFRCkgewotICAgICAgICAgICAgICAgIHVzZXNbY291bnQrK10gPSBmQXR0cmlidXRlVXNlc1tpXTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBmQXR0cmlidXRlVXNlcyA9IHVzZXM7Ci0gICAgICAgIGZBdHRyVXNlTnVtID0gY291bnQ7Ci0KLSAgICAgICAgLy8gRG8gbm90IHJlbW92ZSBhdHRyaWJ1dGVzIHRoYXQgaGF2ZSB0aGUgc2FtZSBuYW1lIGFzIHRoZSBwcm9oaWJpdGVkCi0gICAgICAgIC8vIG9uZXMsIGJlY2F1c2UgdGhleSBhcmUgc3BlY2lmaWVkIGF0IHRoZSBzYW1lIGxldmVsLiBQcm9oaWJpdGVkCi0gICAgICAgIC8vIGF0dHJpYnV0ZXMgYXJlIG9ubHkgdG8gcmVtb3ZlIGF0dHJpYnV0ZXMgZnJvbSB0aGUgYmFzZSB0eXBlIGluIGEKLSAgICAgICAgLy8gcmVzdHJpY3Rpb24uCi0vLyAgICAgICAgaW50IG5ld0NvdW50ID0gMDsKLS8vICAgICAgICBpZiAocENvdW50ID4gMCkgewotLy8gICAgICAgICAgICBPVVRFUjogZm9yIChpbnQgaSA9IDA7IGkgPCBmQXR0clVzZU51bTsgaSsrKSB7Ci0vLyAgICAgICAgICAgICAgICBpZiAoZkF0dHJpYnV0ZVVzZXNbaV0uZlVzZSA9PSBTY2hlbWFTeW1ib2xzLlVTRV9QUk9ISUJJVEVEKQotLy8gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotLy8gICAgICAgICAgICAgICAgZm9yIChpbnQgaiA9IDE7IGogPD0gcENvdW50OyBqKyspIHsKLS8vICAgICAgICAgICAgICAgICAgICBpZiAoZkF0dHJpYnV0ZVVzZXNbaV0uZkF0dHJEZWNsLmZOYW1lID09IHBVc2VzW2ZBdHRyVXNlTnVtLXBDb3VudF0uZkF0dHJEZWNsLmZOYW1lICYmCi0vLyAgICAgICAgICAgICAgICAgICAgICAgIGZBdHRyaWJ1dGVVc2VzW2ldLmZBdHRyRGVjbC5mVGFyZ2V0TmFtZXNwYWNlID09IHBVc2VzW2ZBdHRyVXNlTnVtLXBDb3VudF0uZkF0dHJEZWNsLmZUYXJnZXROYW1lc3BhY2UpIHsKLS8vICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWUgT1VURVI7Ci0vLyAgICAgICAgICAgICAgICAgICAgfQotLy8gICAgICAgICAgICAgICAgfQotLy8gICAgICAgICAgICAgICAgcFVzZXNbbmV3Q291bnQrK10gPSBmQXR0cmlidXRlVXNlc1tpXTsKLS8vICAgICAgICAgICAgfQotLy8gICAgICAgICAgICBmQXR0cmlidXRlVXNlcyA9IHBVc2VzOwotLy8gICAgICAgICAgICBmQXR0clVzZU51bSA9IG5ld0NvdW50OwotLy8gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDaGVjayB0aGF0IHRoZSBhdHRyaWJ1dGVzIGluIHRoaXMgZ3JvdXAgdmFsaWRseSByZXN0cmljdCB0aG9zZSBmcm9tIGEgYmFzZSBncm91cC4KLSAgICAgKiBJZiBhbiBlcnJvciBpcyBmb3VuZCwgYW4gT2JqZWN0W10gaXMgcmV0dXJuZWQuIFRoaXMgY29udGFpbnMgdGhlIGFyZ3VtZW50cyBmb3IgdGhlIGVycm9yIG1lc3NhZ2UKLSAgICAgKiBkZXNjcmliaW5nIHRoZSBlcnJvci4gVGhlIGxhc3QgZWxlbWVudCBpbiB0aGUgYXJyYXkgKGF0IGluZGV4IGFyci5sZW5ndGggLSAxKSBpcyB0aGUgdGhlIGVycm9yIGNvZGUuCi0gICAgICogUmV0dXJucyBudWxsIGlmIHRoZXJlIGlzIG5vIGVycm9yLgotICAgICAqCi0gICAgICogUkVWSVNJVDogaXMgdGhlcmUgYSBiZXR0ZXIgd2F5IG9mIHJldHVybmluZyB0aGUgYXBwcm9wcmlhdGUgaW5mb3JtYXRpb24gZm9yIHRoZSBlcnJvcj8KLSAgICAgKgotICAgICAqIEBwYXJhbSB0eXBlTmFtZSB0aGUgbmFtZSBvZiB0aGUgdHlwZSBjb250YWluaW5nIHRoaXMgYXR0cmlidXRlIGdyb3VwLCB1c2VkIGZvciBlcnJvciByZXBvcnRpbmcgcHVycG9zZXMKLSAgICAgKiBAcGFyYW0gYmFzZUdyb3VwIHRoZSBYU0F0dHJpYnV0ZUdyb3VwRGVjbCB0aGF0IGlzIHRoZSBiYXNlIHdlIGFyZSBjaGVja2luZyBhZ2FpbnN0Ci0gICAgICovCi0gICAgcHVibGljIE9iamVjdFtdIHZhbGlkUmVzdHJpY3Rpb25PZihTdHJpbmcgdHlwZU5hbWUsIFhTQXR0cmlidXRlR3JvdXBEZWNsIGJhc2VHcm91cCkgewotCi0gICAgICAgIE9iamVjdFtdIGVycm9yQXJncyA9IG51bGw7Ci0gICAgICAgIFhTQXR0cmlidXRlVXNlSW1wbCBhdHRyVXNlID0gbnVsbDsKLSAgICAgICAgWFNBdHRyaWJ1dGVEZWNsIGF0dHJEZWNsID0gbnVsbDsKLSAgICAgICAgWFNBdHRyaWJ1dGVVc2VJbXBsIGJhc2VBdHRyVXNlID0gbnVsbDsKLSAgICAgICAgWFNBdHRyaWJ1dGVEZWNsIGJhc2VBdHRyRGVjbCA9IG51bGw7Ci0KLSAgICAgICAgZm9yIChpbnQgaT0wOyBpPGZBdHRyVXNlTnVtOyBpKyspIHsKLQotICAgICAgICAgICAgYXR0clVzZSA9IGZBdHRyaWJ1dGVVc2VzW2ldOwotICAgICAgICAgICAgYXR0ckRlY2wgPSBhdHRyVXNlLmZBdHRyRGVjbDsKLQotICAgICAgICAgICAgLy8gTG9vayBmb3IgYSBtYXRjaCBpbiB0aGUgYmFzZQotICAgICAgICAgICAgYmFzZUF0dHJVc2UgPSAoWFNBdHRyaWJ1dGVVc2VJbXBsKWJhc2VHcm91cC5nZXRBdHRyaWJ1dGVVc2UoYXR0ckRlY2wuZlRhcmdldE5hbWVzcGFjZSxhdHRyRGVjbC5mTmFtZSk7Ci0gICAgICAgICAgICBpZiAoYmFzZUF0dHJVc2UgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAgICAgLy8gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4gIENvbnN0cmFpbnQgMi4xLjEKLSAgICAgICAgICAgICAgICAvLwotCi0gICAgICAgICAgICAgICAgaWYgKGJhc2VBdHRyVXNlLmdldFJlcXVpcmVkKCkgJiYgIWF0dHJVc2UuZ2V0UmVxdWlyZWQoKSkgewotICAgICAgICAgICAgICAgICAgICBlcnJvckFyZ3MgPSBuZXcgT2JqZWN0W117dHlwZU5hbWUsIGF0dHJEZWNsLmZOYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0clVzZS5mVXNlID09IFNjaGVtYVN5bWJvbHMuVVNFX09QVElPTkFMID8gU2NoZW1hU3ltYm9scy5BVFRWQUxfT1BUSU9OQUwgOiBTY2hlbWFTeW1ib2xzLkFUVFZBTF9QUk9ISUJJVEVELAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMi4xLjEifTsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVycm9yQXJnczsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyBpZiB0aGlzIGF0dHJpYnV0ZSBpcyBwcm9oaWJpdGVkIGluIHRoZSBkZXJpdmVkIHR5cGUsIGRvbid0Ci0gICAgICAgICAgICAgICAgLy8gbmVlZCB0byBjaGVjayBhbnkgb2YgdGhlIGZvbGxvd2luZyBjb25zdHJhaW50cy4KLSAgICAgICAgICAgICAgICBpZiAoYXR0clVzZS5mVXNlID09IFNjaGVtYVN5bWJvbHMuVVNFX1BST0hJQklURUQpIHsKLSAgICAgICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgYmFzZUF0dHJEZWNsID0gYmFzZUF0dHJVc2UuZkF0dHJEZWNsOwotICAgICAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAgICAgLy8gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4gIENvbnN0cmFpbnQgMi4xLjEKLSAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgIGlmICghIFhTQ29uc3RyYWludHMuY2hlY2tTaW1wbGVEZXJpdmF0aW9uT2soYXR0ckRlY2wuZlR5cGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXNlQXR0ckRlY2wuZlR5cGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXNlQXR0ckRlY2wuZlR5cGUuZ2V0RmluYWwoKSkgKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JBcmdzID0gbmV3IE9iamVjdFtde3R5cGVOYW1lLCBhdHRyRGVjbC5mTmFtZSwgYXR0ckRlY2wuZlR5cGUuZ2V0TmFtZSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmFzZUF0dHJEZWNsLmZUeXBlLmdldE5hbWUoKSwgImRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMi4xLjIifTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZXJyb3JBcmdzOwotICAgICAgICAgICAgICAgIH0KLQotCi0gICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICAvLyBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLiAgQ29uc3RyYWludCAyLjEuMwotICAgICAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAgICAgaW50IGJhc2VDb25zVHlwZT1iYXNlQXR0clVzZS5mQ29uc3RyYWludFR5cGUhPVhTQ29uc3RhbnRzLlZDX05PTkU/Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXNlQXR0clVzZS5mQ29uc3RyYWludFR5cGU6YmFzZUF0dHJEZWNsLmdldENvbnN0cmFpbnRUeXBlKCk7Ci0gICAgICAgICAgICAgICAgaW50IHRoaXNDb25zdFR5cGUgPSBhdHRyVXNlLmZDb25zdHJhaW50VHlwZSE9WFNDb25zdGFudHMuVkNfTk9ORT8KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJVc2UuZkNvbnN0cmFpbnRUeXBlOmF0dHJEZWNsLmdldENvbnN0cmFpbnRUeXBlKCk7Ci0KLSAgICAgICAgICAgICAgICBpZiAoYmFzZUNvbnNUeXBlID09IFhTQ29uc3RhbnRzLlZDX0ZJWEVEKSB7Ci0KLSAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXNDb25zdFR5cGUgIT0gWFNDb25zdGFudHMuVkNfRklYRUQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQXJncyA9IG5ldyBPYmplY3RbXXt0eXBlTmFtZSwgYXR0ckRlY2wuZk5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMi4xLjMuYSJ9OwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVycm9yQXJnczsKLSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNoZWNrIHRoZSB2YWx1ZXMgYXJlIHRoZSBzYW1lLgotICAgICAgICAgICAgICAgICAgICAgICAgVmFsaWRhdGVkSW5mbyBiYXNlRml4ZWRWYWx1ZT0oYmFzZUF0dHJVc2UuZkRlZmF1bHQhPW51bGwgPwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmFzZUF0dHJVc2UuZkRlZmF1bHQ6IGJhc2VBdHRyRGVjbC5mRGVmYXVsdCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBWYWxpZGF0ZWRJbmZvIHRoaXNGaXhlZFZhbHVlPShhdHRyVXNlLmZEZWZhdWx0IT1udWxsID8KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJVc2UuZkRlZmF1bHQ6IGF0dHJEZWNsLmZEZWZhdWx0KTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmICghYmFzZUZpeGVkVmFsdWUuYWN0dWFsVmFsdWUuZXF1YWxzKHRoaXNGaXhlZFZhbHVlLmFjdHVhbFZhbHVlKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckFyZ3MgPSBuZXcgT2JqZWN0W117dHlwZU5hbWUsIGF0dHJEZWNsLmZOYW1lLCB0aGlzRml4ZWRWYWx1ZS5zdHJpbmdWYWx1ZSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmFzZUZpeGVkVmFsdWUuc3RyaW5nVmFsdWUoKSwgImRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMi4xLjMuYiJ9OwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZXJyb3JBcmdzOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgLy8gTm8gbWF0Y2hpbmcgYXR0cmlidXRlIGluIGJhc2UgLSB0aGVyZSBzaG91bGQgYmUgYSBtYXRjaGluZyB3aWxkY2FyZAotCi0gICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICAvLyBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLiAgQ29uc3RyYWludCAyLjIKLSAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgIGlmIChiYXNlR3JvdXAuZkF0dHJpYnV0ZVdDID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckFyZ3MgPSBuZXcgT2JqZWN0W117dHlwZU5hbWUsIGF0dHJEZWNsLmZOYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4yLjIuYSJ9OwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBlcnJvckFyZ3M7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgaWYgKCFiYXNlR3JvdXAuZkF0dHJpYnV0ZVdDLmFsbG93TmFtZXNwYWNlKGF0dHJEZWNsLmZUYXJnZXROYW1lc3BhY2UpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JBcmdzID0gbmV3IE9iamVjdFtde3R5cGVOYW1lLCBhdHRyRGVjbC5mTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJEZWNsLmZUYXJnZXROYW1lc3BhY2U9PW51bGw/IiI6YXR0ckRlY2wuZlRhcmdldE5hbWVzcGFjZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMi4yLmIifTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZXJyb3JBcmdzOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIENoZWNrIHRoYXQgYW55IFJFUVVJUkVEIGF0dHJpYnV0ZXMgaW4gdGhlIGJhc2UgaGF2ZSBtYXRjaGluZyBhdHRyaWJ1dGVzCi0gICAgICAgIC8vIGluIHRoaXMgZ3JvdXAKLSAgICAgICAgLy8gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4gIENvbnN0cmFpbnQgMwotICAgICAgICAvLwotICAgICAgICBmb3IgKGludCBpPTA7IGk8YmFzZUdyb3VwLmZBdHRyVXNlTnVtOyBpKyspIHsKLQotICAgICAgICAgICAgYmFzZUF0dHJVc2UgPSBiYXNlR3JvdXAuZkF0dHJpYnV0ZVVzZXNbaV07Ci0KLSAgICAgICAgICAgIGlmIChiYXNlQXR0clVzZS5mVXNlID09IFNjaGVtYVN5bWJvbHMuVVNFX1JFUVVJUkVEKSB7Ci0KLSAgICAgICAgICAgICAgICBiYXNlQXR0ckRlY2wgPSBiYXNlQXR0clVzZS5mQXR0ckRlY2w7Ci0gICAgICAgICAgICAgICAgLy8gTG9vayBmb3IgYSBtYXRjaCBpbiB0aGlzIGdyb3VwCi0gICAgICAgICAgICAgICAgaWYgKGdldEF0dHJpYnV0ZVVzZShiYXNlQXR0ckRlY2wuZlRhcmdldE5hbWVzcGFjZSxiYXNlQXR0ckRlY2wuZk5hbWUpID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckFyZ3MgPSBuZXcgT2JqZWN0W117dHlwZU5hbWUsIGJhc2VBdHRyVXNlLmZBdHRyRGVjbC5mTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMyJ9OwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBlcnJvckFyZ3M7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLQotICAgICAgICAvLyBOb3csIGNoZWNrIHdpbGRjYXJkcwotICAgICAgICAvLwotICAgICAgICAvLyBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLiAgQ29uc3RyYWludCA0Ci0gICAgICAgIC8vCi0gICAgICAgIGlmIChmQXR0cmlidXRlV0MgIT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKGJhc2VHcm91cC5mQXR0cmlidXRlV0MgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckFyZ3MgPSBuZXcgT2JqZWN0W117dHlwZU5hbWUsICJkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjQuMSJ9OwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZXJyb3JBcmdzOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKCEgZkF0dHJpYnV0ZVdDLmlzU3Vic2V0T2YoYmFzZUdyb3VwLmZBdHRyaWJ1dGVXQykpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JBcmdzID0gbmV3IE9iamVjdFtde3R5cGVOYW1lLCAiZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi40LjIifTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVycm9yQXJnczsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChmQXR0cmlidXRlV0Mud2Vha2VyUHJvY2Vzc0NvbnRlbnRzKGJhc2VHcm91cC5mQXR0cmlidXRlV0MpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQXJncyA9IG5ldyBPYmplY3RbXXt0eXBlTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZBdHRyaWJ1dGVXQy5nZXRQcm9jZXNzQ29udGVudHNBc1N0cmluZygpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmFzZUdyb3VwLmZBdHRyaWJ1dGVXQy5nZXRQcm9jZXNzQ29udGVudHNBc1N0cmluZygpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uNC4zIn07Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBlcnJvckFyZ3M7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gbnVsbDsKLQotICAgIH0KLQotICAgIHN0YXRpYyBmaW5hbCBYU0F0dHJpYnV0ZVVzZUltcGxbXSByZXNpemUoWFNBdHRyaWJ1dGVVc2VJbXBsW10gb2xkQXJyYXksIGludCBuZXdTaXplKSB7Ci0gICAgICAgIFhTQXR0cmlidXRlVXNlSW1wbFtdIG5ld0FycmF5ID0gbmV3IFhTQXR0cmlidXRlVXNlSW1wbFtuZXdTaXplXTsKLSAgICAgICAgU3lzdGVtLmFycmF5Y29weShvbGRBcnJheSwgMCwgbmV3QXJyYXksIDAsIE1hdGgubWluKG9sZEFycmF5Lmxlbmd0aCwgbmV3U2l6ZSkpOwotICAgICAgICByZXR1cm4gbmV3QXJyYXk7Ci0gICAgfQotCi0gICAgLy8gcmVzZXQgdGhlIGF0dHJpYnV0ZSBncm91cCBkZWNsYXJhdGlvbgotICAgIHB1YmxpYyB2b2lkIHJlc2V0KCl7Ci0gICAgICAgIGZOYW1lID0gbnVsbDsKLSAgICAgICAgZlRhcmdldE5hbWVzcGFjZSA9IG51bGw7Ci0gICAgICAgIC8vIHJlc2V0IGF0dHJpYnV0ZSB1c2VzCi0gICAgICAgIGZvciAoaW50IGk9MDtpPGZBdHRyVXNlTnVtO2krKykgewotICAgICAgICAgICAgZkF0dHJpYnV0ZVVzZXNbaV0gPSBudWxsOwotICAgICAgICB9Ci0gICAgICAgIGZBdHRyVXNlTnVtID0gMDsKLSAgICAgICAgZkF0dHJpYnV0ZVdDID0gbnVsbDsKLSAgICAgICAgZkFubm90YXRpb25zID0gbnVsbDsKLSAgICAgICAgZklEQXR0ck5hbWUgPSBudWxsOwotCi0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSB0eXBlIG9mIHRoZSBvYmplY3QsIGkuZSBFTEVNRU5UX0RFQ0xBUkFUSU9OLgotICAgICAqLwotICAgIHB1YmxpYyBzaG9ydCBnZXRUeXBlKCkgewotICAgICAgICByZXR1cm4gWFNDb25zdGFudHMuQVRUUklCVVRFX0dST1VQOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoZSA8Y29kZT5uYW1lPC9jb2RlPiBvZiB0aGlzIDxjb2RlPlhTT2JqZWN0PC9jb2RlPiBkZXBlbmRpbmcgb24gdGhlCi0gICAgICogPGNvZGU+WFNPYmplY3Q8L2NvZGU+IHR5cGUuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXROYW1lKCkgewotICAgICAgICByZXR1cm4gZk5hbWU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhlIG5hbWVzcGFjZSBVUkkgb2YgdGhpcyBub2RlLCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiBpdCBpcwotICAgICAqIHVuc3BlY2lmaWVkLiAgZGVmaW5lcyBob3cgYSBuYW1lc3BhY2UgVVJJIGlzIGF0dGFjaGVkIHRvIHNjaGVtYQotICAgICAqIGNvbXBvbmVudHMuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXROYW1lc3BhY2UoKSB7Ci0gICAgICAgIHJldHVybiBmVGFyZ2V0TmFtZXNwYWNlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIHthdHRyaWJ1dGUgdXNlc30gQSBzZXQgb2YgYXR0cmlidXRlIHVzZXMuCi0gICAgICovCi0gICAgcHVibGljIFhTT2JqZWN0TGlzdCBnZXRBdHRyaWJ1dGVVc2VzKCkgewotICAgICAgICBpZiAoZkF0dHJVc2VzID09IG51bGwpewotICAgICAgICAgICAgZkF0dHJVc2VzID0gbmV3IFhTT2JqZWN0TGlzdEltcGwoZkF0dHJpYnV0ZVVzZXMsIGZBdHRyVXNlTnVtKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZkF0dHJVc2VzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIHthdHRyaWJ1dGUgd2lsZGNhcmR9IE9wdGlvbmFsLiBBIHdpbGRjYXJkLgotICAgICAqLwotICAgIHB1YmxpYyBYU1dpbGRjYXJkIGdldEF0dHJpYnV0ZVdpbGRjYXJkKCkgewotICAgICAgICByZXR1cm4gZkF0dHJpYnV0ZVdDOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIE9wdGlvbmFsLiBBbm5vdGF0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBYU0Fubm90YXRpb24gZ2V0QW5ub3RhdGlvbigpIHsKLSAgICAgICAgcmV0dXJuIChmQW5ub3RhdGlvbnMgIT0gbnVsbCkgPyAoWFNBbm5vdGF0aW9uKSBmQW5ub3RhdGlvbnMuaXRlbSgwKSA6IG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogT3B0aW9uYWwuIEFubm90YXRpb25zLgotICAgICAqLwotICAgIHB1YmxpYyBYU09iamVjdExpc3QgZ2V0QW5ub3RhdGlvbnMoKSB7Ci0gICAgICAgIHJldHVybiAoZkFubm90YXRpb25zICE9IG51bGwpID8gZkFubm90YXRpb25zIDogWFNPYmplY3RMaXN0SW1wbC5FTVBUWV9MSVNUOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgb3JnLmFwYWNoZS54ZXJjZXMueHMuWFNPYmplY3QjZ2V0TmFtZXNwYWNlSXRlbSgpCi0gICAgICovCi0gICAgcHVibGljIFhTTmFtZXNwYWNlSXRlbSBnZXROYW1lc3BhY2VJdGVtKCkgewotICAgICAgICByZXR1cm4gZk5hbWVzcGFjZUl0ZW07Ci0gICAgfQotCi0gICAgdm9pZCBzZXROYW1lc3BhY2VJdGVtKFhTTmFtZXNwYWNlSXRlbSBuYW1lc3BhY2VJdGVtKSB7Ci0gICAgICAgIGZOYW1lc3BhY2VJdGVtID0gbmFtZXNwYWNlSXRlbTsKLSAgICB9Ci0KLX0gLy8gY2xhc3MgWFNBdHRyaWJ1dGVHcm91cERlY2wKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvWFNBdHRyaWJ1dGVVc2VJbXBsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL1hTQXR0cmlidXRlVXNlSW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxNzRjMjg1Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvWFNBdHRyaWJ1dGVVc2VJbXBsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNTMgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDAyLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54czsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5WYWxpZGF0ZWRJbmZvOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy51dGlsLlhTT2JqZWN0TGlzdEltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5TaG9ydExpc3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU0F0dHJpYnV0ZURlY2xhcmF0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNBdHRyaWJ1dGVVc2U7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU0NvbnN0YW50czsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTTmFtZXNwYWNlSXRlbTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTT2JqZWN0TGlzdDsKLQotLyoqCi0gKiBUaGUgWE1MIHJlcHJlc2VudGF0aW9uIGZvciBhbiBhdHRyaWJ1dGUgdXNlCi0gKiBzY2hlbWEgY29tcG9uZW50IGlzIGEgbG9jYWwgPGF0dHJpYnV0ZT4gZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgU2FuZHkgR2FvLCBJQk0KLSAqIEB2ZXJzaW9uICRJZDogWFNBdHRyaWJ1dGVVc2VJbXBsLmphdmEsdiAxLjcgMjAxMC0xMS0wMSAwNDozOTo1NSBqb2VodyBFeHAgJAotICovCi1wdWJsaWMgY2xhc3MgWFNBdHRyaWJ1dGVVc2VJbXBsIGltcGxlbWVudHMgWFNBdHRyaWJ1dGVVc2UgewotCi0gICAgLy8gdGhlIHJlZmVycmVkIGF0dHJpYnV0ZSBkZWNsCi0gICAgcHVibGljIFhTQXR0cmlidXRlRGVjbCBmQXR0ckRlY2wgPSBudWxsOwotICAgIC8vIHVzZSBpbmZvcm1hdGlvbjogU2NoZW1hU3ltYm9scy5VU0VfT1BUSU9OQUwsIFJFUVVJUkVELCBQUk9ISUJJVEVECi0gICAgcHVibGljIHNob3J0IGZVc2UgPSBTY2hlbWFTeW1ib2xzLlVTRV9PUFRJT05BTDsKLSAgICAvLyB2YWx1ZSBjb25zdHJhaW50IHR5cGU6IGRlZmF1bHQsIGZpeGVkIG9yICFzcGVjaWZpZWQKLSAgICBwdWJsaWMgc2hvcnQgZkNvbnN0cmFpbnRUeXBlID0gWFNDb25zdGFudHMuVkNfTk9ORTsKLSAgICAvLyB2YWx1ZSBjb25zdHJhaW50IHZhbHVlCi0gICAgcHVibGljIFZhbGlkYXRlZEluZm8gZkRlZmF1bHQgPSBudWxsOwotICAgIC8vIG9wdGlvbmFsIGFubm90YXRpb24KLSAgICBwdWJsaWMgWFNPYmplY3RMaXN0IGZBbm5vdGF0aW9ucyA9IG51bGw7Ci0KLSAgICBwdWJsaWMgdm9pZCByZXNldCgpewotICAgICAgICBmRGVmYXVsdCA9IG51bGw7Ci0gICAgICAgIGZBdHRyRGVjbCA9IG51bGw7Ci0gICAgICAgIGZVc2UgPSBTY2hlbWFTeW1ib2xzLlVTRV9PUFRJT05BTDsKLSAgICAgICAgZkNvbnN0cmFpbnRUeXBlID0gWFNDb25zdGFudHMuVkNfTk9ORTsKLSAgICAgICAgZkFubm90YXRpb25zID0gbnVsbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIHR5cGUgb2YgdGhlIG9iamVjdCwgaS5lIEVMRU1FTlRfREVDTEFSQVRJT04uCi0gICAgICovCi0gICAgcHVibGljIHNob3J0IGdldFR5cGUoKSB7Ci0gICAgICAgIHJldHVybiBYU0NvbnN0YW50cy5BVFRSSUJVVEVfVVNFOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoZSA8Y29kZT5uYW1lPC9jb2RlPiBvZiB0aGlzIDxjb2RlPlhTT2JqZWN0PC9jb2RlPiBkZXBlbmRpbmcgb24gdGhlCi0gICAgICogPGNvZGU+WFNPYmplY3Q8L2NvZGU+IHR5cGUuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXROYW1lKCkgewotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgbmFtZXNwYWNlIFVSSSBvZiB0aGlzIG5vZGUsIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIGl0IGlzCi0gICAgICogdW5zcGVjaWZpZWQuICBkZWZpbmVzIGhvdyBhIG5hbWVzcGFjZSBVUkkgaXMgYXR0YWNoZWQgdG8gc2NoZW1hCi0gICAgICogY29tcG9uZW50cy4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWVzcGFjZSgpIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICoge3JlcXVpcmVkfSBkZXRlcm1pbmVzIHdoZXRoZXIgdGhpcyB1c2Ugb2YgYW4gYXR0cmlidXRlIGRlY2xhcmF0aW9uCi0gICAgICogcmVxdWlyZXMgYW4gYXBwcm9wcmlhdGUgYXR0cmlidXRlIGluZm9ybWF0aW9uIGl0ZW0gdG8gYmUgcHJlc2VudCwgb3IKLSAgICAgKiBtZXJlbHkgYWxsb3dzIGl0LgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGdldFJlcXVpcmVkKCkgewotICAgICAgICByZXR1cm4gZlVzZSA9PSBTY2hlbWFTeW1ib2xzLlVTRV9SRVFVSVJFRDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiB7YXR0cmlidXRlIGRlY2xhcmF0aW9ufSBwcm92aWRlcyB0aGUgYXR0cmlidXRlIGRlY2xhcmF0aW9uIGl0c2VsZiwKLSAgICAgKiB3aGljaCB3aWxsIGluIHR1cm4gZGV0ZXJtaW5lIHRoZSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uIHVzZWQuCi0gICAgICovCi0gICAgcHVibGljIFhTQXR0cmlidXRlRGVjbGFyYXRpb24gZ2V0QXR0ckRlY2xhcmF0aW9uKCkgewotICAgICAgICByZXR1cm4gZkF0dHJEZWNsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFZhbHVlIENvbnN0cmFpbnQ6IG9uZSBvZiBkZWZhdWx0LCBmaXhlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgc2hvcnQgZ2V0Q29uc3RyYWludFR5cGUoKSB7Ci0gICAgICAgIHJldHVybiBmQ29uc3RyYWludFR5cGU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVmFsdWUgQ29uc3RyYWludDogVGhlIGFjdHVhbCB2YWx1ZSAod2l0aCByZXNwZWN0IHRvIHRoZSB7dHlwZQotICAgICAqIGRlZmluaXRpb259KS4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldENvbnN0cmFpbnRWYWx1ZSgpIHsKLSAgICAgICAgLy8gUkVWSVNJVDogU0NBUEk6IHdoYXQncyB0aGUgcHJvcGVyIHJlcHJlc2VudGF0aW9uCi0gICAgICAgIHJldHVybiBnZXRDb25zdHJhaW50VHlwZSgpID09IFhTQ29uc3RhbnRzLlZDX05PTkUgPwotICAgICAgICAgICAgICAgbnVsbCA6Ci0gICAgICAgICAgICAgICBmRGVmYXVsdC5zdHJpbmdWYWx1ZSgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgb3JnLmFwYWNoZS54ZXJjZXMueHMuWFNPYmplY3QjZ2V0TmFtZXNwYWNlSXRlbSgpCi0gICAgICovCi0gICAgcHVibGljIFhTTmFtZXNwYWNlSXRlbSBnZXROYW1lc3BhY2VJdGVtKCkgewotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgT2JqZWN0IGdldEFjdHVhbFZDKCkgewotICAgICAgICByZXR1cm4gZ2V0Q29uc3RyYWludFR5cGUoKSA9PSBYU0NvbnN0YW50cy5WQ19OT05FID8KLSAgICAgICAgICAgICAgIG51bGwgOgotICAgICAgICAgICAgICAgZkRlZmF1bHQuYWN0dWFsVmFsdWU7Ci0gICAgfQotCi0gICAgcHVibGljIHNob3J0IGdldEFjdHVhbFZDVHlwZSgpIHsKLSAgICAgICAgcmV0dXJuIGdldENvbnN0cmFpbnRUeXBlKCkgPT0gWFNDb25zdGFudHMuVkNfTk9ORSA/Ci0gICAgICAgICAgICAgICBYU0NvbnN0YW50cy5VTkFWQUlMQUJMRV9EVCA6Ci0gICAgICAgICAgICAgICBmRGVmYXVsdC5hY3R1YWxWYWx1ZVR5cGU7Ci0gICAgfQotCi0gICAgcHVibGljIFNob3J0TGlzdCBnZXRJdGVtVmFsdWVUeXBlcygpIHsKLSAgICAgICAgcmV0dXJuIGdldENvbnN0cmFpbnRUeXBlKCkgPT0gWFNDb25zdGFudHMuVkNfTk9ORSA/Ci0gICAgICAgICAgICAgICBudWxsIDoKLSAgICAgICAgICAgICAgIGZEZWZhdWx0Lml0ZW1WYWx1ZVR5cGVzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIE9wdGlvbmFsLiBBbm5vdGF0aW9ucy4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFNPYmplY3RMaXN0IGdldEFubm90YXRpb25zKCkgewotICAgICAgICByZXR1cm4gKGZBbm5vdGF0aW9ucyAhPSBudWxsKSA/IGZBbm5vdGF0aW9ucyA6IFhTT2JqZWN0TGlzdEltcGwuRU1QVFlfTElTVDsKLSAgICB9Ci0KLX0gLy8gY2xhc3MgWFNBdHRyaWJ1dGVVc2VJbXBsCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL1hTQ29tcGxleFR5cGVEZWNsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL1hTQ29tcGxleFR5cGVEZWNsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDc5ZjI1MDAuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9YU0NvbXBsZXhUeXBlRGVjbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNzE5ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LlhTU2ltcGxlVHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLio7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLm1vZGVscy5YU0NNVmFsaWRhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5tb2RlbHMuQ01CdWlsZGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy51dGlsLlhTT2JqZWN0TGlzdEltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LnhzLlhTU2ltcGxlVHlwZURlY2w7Ci1pbXBvcnQgb3JnLnczYy5kb20uVHlwZUluZm87Ci0KLS8qKgotICogVGhlIFhNTCByZXByZXNlbnRhdGlvbiBmb3IgYSBjb21wbGV4VHlwZQotICogc2NoZW1hIGNvbXBvbmVudCBpcyBhIDxjb21wbGV4VHlwZT4gZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgRWxlbmEgTGl0YW5pLCBJQk0KLSAqIEBhdXRob3IgU2FuZHkgR2FvLCBJQk0KLSAqIEB2ZXJzaW9uICRJZDogWFNDb21wbGV4VHlwZURlY2wuamF2YSx2IDEuOCAyMDEwLTExLTAxIDA0OjM5OjU1IGpvZWh3IEV4cCAkCi0gKi8KLXB1YmxpYyBjbGFzcyBYU0NvbXBsZXhUeXBlRGVjbCBpbXBsZW1lbnRzIFhTQ29tcGxleFR5cGVEZWZpbml0aW9uLCBUeXBlSW5mbyB7Ci0KLSAgICAvLyBuYW1lIG9mIHRoZSBjb21wbGV4VHlwZQotICAgIFN0cmluZyBmTmFtZSA9IG51bGw7Ci0KLSAgICAvLyB0YXJnZXQgbmFtZXNwYWNlIG9mIHRoZSBjb21wbGV4VHlwZQotICAgIFN0cmluZyBmVGFyZ2V0TmFtZXNwYWNlID0gbnVsbDsKLQotICAgIC8vIGJhc2UgdHlwZSBvZiB0aGUgY29tcGxleFR5cGUKLSAgICBYU1R5cGVEZWZpbml0aW9uIGZCYXNlVHlwZSA9IG51bGw7Ci0KLSAgICAvLyBkZXJpdmF0aW9uIG1ldGhvZCBvZiB0aGUgY29tcGxleFR5cGUKLSAgICBzaG9ydCBmRGVyaXZlZEJ5ID0gWFNDb25zdGFudHMuREVSSVZBVElPTl9SRVNUUklDVElPTjsKLQotICAgIC8vIGZpbmFsIHNldCBvZiB0aGUgY29tcGxleFR5cGUKLSAgICBzaG9ydCBmRmluYWwgPSBYU0NvbnN0YW50cy5ERVJJVkFUSU9OX05PTkU7Ci0KLSAgICAvLyBibG9jayBzZXQgKHByb2hpYml0ZWQgc3Vic3RpdHV0aW9uKSBvZiB0aGUgY29tcGxleFR5cGUKLSAgICBzaG9ydCBmQmxvY2sgPSBYU0NvbnN0YW50cy5ERVJJVkFUSU9OX05PTkU7Ci0KLSAgICAvLyBmbGFnczogd2hldGhlciBpcyBhYnN0cmFjdDsgd2hldGhlciBjb250YWlucyBJRCB0eXBlOwotICAgIC8vICAgICAgICB3aGV0aGVyIGl0J3MgYW4gYW5vbnltb3VzIHRweWUKLSAgICBzaG9ydCBmTWlzY0ZsYWdzID0gMDsKLQotICAgIC8vIHRoZSBhdHRyaWJ1dGUgZ3JvdXAgdGhhdCBob2xkcyB0aGUgYXR0cmlidXRlIHVzZXMgYW5kIGF0dHJpYnV0ZSB3aWxkY2FyZAotICAgIFhTQXR0cmlidXRlR3JvdXBEZWNsIGZBdHRyR3JwID0gbnVsbDsKLQotICAgIC8vIHRoZSBjb250ZW50IHR5cGUgb2YgdGhlIGNvbXBsZXhUeXBlCi0gICAgc2hvcnQgZkNvbnRlbnRUeXBlID0gQ09OVEVOVFRZUEVfRU1QVFk7Ci0KLSAgICAvLyBpZiB0aGUgY29udGVudCB0eXBlIGlzIHNpbXBsZSwgdGhlbiB0aGUgY29ycmVzcG9uZGluZyBzaW1wbGVUeXBlCi0gICAgWFNTaW1wbGVUeXBlIGZYU1NpbXBsZVR5cGUgPSBudWxsOwotCi0gICAgLy8gaWYgdGhlIGNvbnRlbnQgdHlwZSBpcyBlbGVtZW50IG9yIG1peGVkLCB0aGUgcGFydGljbGUKLSAgICBYU1BhcnRpY2xlRGVjbCBmUGFydGljbGUgPSBudWxsOwotCi0gICAgLy8gaWYgdGhlcmUgaXMgYSBwYXJ0aWNsZSwgdGhlIGNvbnRlbnQgbW9kZWwgY29ycmVzcG9uZGluZyB0byB0aGF0IHBhcnRpY2xlCi0gICAgdm9sYXRpbGUgWFNDTVZhbGlkYXRvciBmQ01WYWxpZGF0b3IgPSBudWxsOwotCi0gICAgLy8gdGhlIGNvbnRlbnQgbW9kZWwgdGhhdCdzIHN1ZmZpY2llbnQgZm9yIGNvbXB1dGluZyBVUEEKLSAgICBYU0NNVmFsaWRhdG9yIGZVUEFDTVZhbGlkYXRvciA9IG51bGw7Ci0KLSAgICAvLyBsaXN0IG9mIGFubm90YXRpb25zIGFmZmlsaWF0ZWQgd2l0aCB0aGlzIHR5cGUKLSAgICBYU09iamVjdExpc3RJbXBsIGZBbm5vdGF0aW9ucyA9IG51bGw7Ci0KLSAgICAvLyBUaGUgbmFtZXNwYWNlIHNjaGVtYSBpbmZvcm1hdGlvbiBpdGVtIGNvcnJlc3BvbmRpbmcgdG8gdGhlIHRhcmdldCBuYW1lc3BhY2UKLSAgICAvLyBvZiB0aGUgY29tcGxleCB0eXBlIGRlZmluaXRpb24sIGlmIGl0IGlzIGdsb2JhbGx5IGRlY2xhcmVkOyBvciBudWxsIG90aGVyd2lzZS4KLSAgICBwcml2YXRlIFhTTmFtZXNwYWNlSXRlbSBmTmFtZXNwYWNlSXRlbSA9IG51bGw7Ci0KLSAgICAvLyBET00gTGV2ZWwgMyBUeXBlSW5mbyBEZXJpdmF0aW9uIE1ldGhvZCBjb25zdGFudHMKLSAgICBzdGF0aWMgZmluYWwgaW50IERFUklWQVRJT05fQU5ZID0gMDsKLSAgICBzdGF0aWMgZmluYWwgaW50IERFUklWQVRJT05fUkVTVFJJQ1RJT04gPSAxOwotICAgIHN0YXRpYyBmaW5hbCBpbnQgREVSSVZBVElPTl9FWFRFTlNJT04gPSAyOwotICAgIHN0YXRpYyBmaW5hbCBpbnQgREVSSVZBVElPTl9VTklPTiA9IDQ7Ci0gICAgc3RhdGljIGZpbmFsIGludCBERVJJVkFUSU9OX0xJU1QgPSA4OwotCi0gICAgcHVibGljIFhTQ29tcGxleFR5cGVEZWNsKCkgewotICAgICAgICAvLyBkby1ub3RoaW5nIGNvbnN0cnVjdG9yIGZvciBub3cuCi0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0VmFsdWVzKFN0cmluZyBuYW1lLCBTdHJpbmcgdGFyZ2V0TmFtZXNwYWNlLAotICAgICAgICAgICAgWFNUeXBlRGVmaW5pdGlvbiBiYXNlVHlwZSwgc2hvcnQgZGVyaXZlZEJ5LCBzaG9ydCBzY2hlbWFGaW5hbCwKLSAgICAgICAgICAgIHNob3J0IGJsb2NrLCBzaG9ydCBjb250ZW50VHlwZSwKLSAgICAgICAgICAgIGJvb2xlYW4gaXNBYnN0cmFjdCwgWFNBdHRyaWJ1dGVHcm91cERlY2wgYXR0ckdycCwKLSAgICAgICAgICAgIFhTU2ltcGxlVHlwZSBzaW1wbGVUeXBlLCBYU1BhcnRpY2xlRGVjbCBwYXJ0aWNsZSwKLSAgICAgICAgICAgIFhTT2JqZWN0TGlzdEltcGwgYW5ub3RhdGlvbnMpIHsKLSAgICAgICAgZlRhcmdldE5hbWVzcGFjZSA9IHRhcmdldE5hbWVzcGFjZTsKLSAgICAgICAgZkJhc2VUeXBlID0gYmFzZVR5cGU7Ci0gICAgICAgIGZEZXJpdmVkQnkgPSBkZXJpdmVkQnk7Ci0gICAgICAgIGZGaW5hbCA9IHNjaGVtYUZpbmFsOwotICAgICAgICBmQmxvY2sgPSBibG9jazsKLSAgICAgICAgZkNvbnRlbnRUeXBlID0gY29udGVudFR5cGU7Ci0gICAgICAgIGlmKGlzQWJzdHJhY3QpCi0gICAgICAgICAgICBmTWlzY0ZsYWdzIHw9IENUX0lTX0FCU1RSQUNUOwotICAgICAgICBmQXR0ckdycCA9IGF0dHJHcnA7Ci0gICAgICAgIGZYU1NpbXBsZVR5cGUgPSBzaW1wbGVUeXBlOwotICAgICAgICBmUGFydGljbGUgPSBwYXJ0aWNsZTsKLSAgICAgICAgZkFubm90YXRpb25zID0gYW5ub3RhdGlvbnM7Ci0gICB9Ci0KLSAgIHB1YmxpYyB2b2lkIHNldE5hbWUoU3RyaW5nIG5hbWUpIHsKLSAgICAgICAgZk5hbWUgPSBuYW1lOwotICAgfQotCi0gICAgcHVibGljIHNob3J0IGdldFR5cGVDYXRlZ29yeSgpIHsKLSAgICAgICAgcmV0dXJuIENPTVBMRVhfVFlQRTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldFR5cGVOYW1lKCkgewotICAgICAgICByZXR1cm4gZk5hbWU7Ci0gICAgfQotCi0gICAgcHVibGljIHNob3J0IGdldEZpbmFsU2V0KCl7Ci0gICAgICAgIHJldHVybiBmRmluYWw7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXROYW1lc3BhY2UoKXsKLSAgICAgICAgcmV0dXJuIGZUYXJnZXROYW1lc3BhY2U7Ci0gICAgfQotCi0gICAgLy8gZmxhZ3MgZm9yIHRoZSBtaXNjIGZsYWcKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBzaG9ydCBDVF9JU19BQlNUUkFDVCA9IDE7Ci0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgc2hvcnQgQ1RfSEFTX1RZUEVfSUQgPSAyOwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHNob3J0IENUX0lTX0FOT05ZTU9VUyA9IDQ7Ci0KLSAgICAvLyBtZXRob2RzIHRvIGdldC9zZXQgbWlzYyBmbGFnCi0KLSAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1R5cGVJRCAoKSB7Ci0gICAgICAgIHJldHVybigoZk1pc2NGbGFncyAmIENUX0hBU19UWVBFX0lEKSAhPSAwKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRJc0Fic3RyYWN0VHlwZSgpIHsKLSAgICAgICAgZk1pc2NGbGFncyB8PSBDVF9JU19BQlNUUkFDVDsKLSAgICB9Ci0gICAgcHVibGljIHZvaWQgc2V0Q29udGFpbnNUeXBlSUQoKSB7Ci0gICAgICAgIGZNaXNjRmxhZ3MgfD0gQ1RfSEFTX1RZUEVfSUQ7Ci0gICAgfQotICAgIHB1YmxpYyB2b2lkIHNldElzQW5vbnltb3VzKCkgewotICAgICAgICBmTWlzY0ZsYWdzIHw9IENUX0lTX0FOT05ZTU9VUzsKLSAgICB9Ci0KLSAgICBwdWJsaWMgWFNDTVZhbGlkYXRvciBnZXRDb250ZW50TW9kZWwoQ01CdWlsZGVyIGNtQnVpbGRlcikgewotICAgICAgICAvLyBmb3IgY29tcGxleCB0eXBlIHdpdGggZW1wdHkgb3Igc2ltcGxlIGNvbnRlbnQsCi0gICAgICAgIC8vIHRoZXJlIGlzIG5vIGNvbnRlbnQgbW9kZWwgdmFsaWRhdG9yCi0gICAgICAgIGlmIChmQ29udGVudFR5cGUgPT0gWFNDb21wbGV4VHlwZURlY2wuQ09OVEVOVFRZUEVfU0lNUExFIHx8Ci0gICAgICAgICAgICBmQ29udGVudFR5cGUgPT0gWFNDb21wbGV4VHlwZURlY2wuQ09OVEVOVFRZUEVfRU1QVFkpIHsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgICAgIGlmIChmQ01WYWxpZGF0b3IgPT0gbnVsbCkKLSAgICAgICAgICAgIHN5bmNocm9uaXplZCAodGhpcykgewotICAgICAgICAgICAgICAgIGlmIChmQ01WYWxpZGF0b3IgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBmQ01WYWxpZGF0b3IgPSBjbUJ1aWxkZXIuZ2V0Q29udGVudE1vZGVsKHRoaXMpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGZDTVZhbGlkYXRvcjsKLSAgICB9Ci0KLSAgICAvLyBzb21lIHV0aWxpdHkgbWV0aG9kczoKLQotICAgIC8vIHJldHVybiB0aGUgYXR0cmlidXRlIGdyb3VwIGZvciB0aGlzIGNvbXBsZXggdHlwZQotICAgIHB1YmxpYyBYU0F0dHJpYnV0ZUdyb3VwRGVjbCBnZXRBdHRyR3JwKCkgewotICAgICAgICByZXR1cm4gZkF0dHJHcnA7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKLSAgICAgICAgU3RyaW5nQnVpbGRlciBzdHIgPSBuZXcgU3RyaW5nQnVpbGRlcigxOTIpOwotICAgICAgICBhcHBlbmRUeXBlSW5mbyhzdHIpOwotICAgICAgICByZXR1cm4gc3RyLnRvU3RyaW5nKCk7Ci0gICAgfQotCi0gICAgdm9pZCBhcHBlbmRUeXBlSW5mbyhTdHJpbmdCdWlsZGVyIHN0cikgewotICAgICAgICBTdHJpbmcgY29udGVudFR5cGVbXSA9IHsiRU1QVFkiLCAiU0lNUExFIiwgIkVMRU1FTlQiLCAiTUlYRUQifTsKLSAgICAgICAgU3RyaW5nIGRlcml2ZWRCeVtdID0geyJFTVBUWSIsICJFWFRFTlNJT04iLCAiUkVTVFJJQ1RJT04ifTsKLQotICAgICAgICBzdHIuYXBwZW5kKCJDb21wbGV4IHR5cGUgbmFtZT0nIikuYXBwZW5kKGZUYXJnZXROYW1lc3BhY2UpLmFwcGVuZCgnLCcpLmFwcGVuZChnZXRUeXBlTmFtZSgpKS5hcHBlbmQoIicsICIpOwotICAgICAgICBpZiAoZkJhc2VUeXBlICE9IG51bGwpIHsKLSAgICAgICAgICAgIHN0ci5hcHBlbmQoIiBiYXNlIHR5cGUgbmFtZT0nIikuYXBwZW5kKGZCYXNlVHlwZS5nZXROYW1lKCkpLmFwcGVuZCgiJywgIik7Ci0gICAgICAgIH0KLSAgICAgICAgc3RyLmFwcGVuZCgiIGNvbnRlbnQgdHlwZT0nIikuYXBwZW5kKGNvbnRlbnRUeXBlW2ZDb250ZW50VHlwZV0pLmFwcGVuZCgiJywgIik7Ci0gICAgICAgIHN0ci5hcHBlbmQoIiBpc0Fic3RyYWN0PSciKS5hcHBlbmQoZ2V0QWJzdHJhY3QoKSkuYXBwZW5kKCInLCAiKTsKLSAgICAgICAgc3RyLmFwcGVuZCgiIGhhc1R5cGVJZD0nIikuYXBwZW5kKGNvbnRhaW5zVHlwZUlEKCkpLmFwcGVuZCgiJywgIik7Ci0gICAgICAgIHN0ci5hcHBlbmQoIiBmaW5hbD0nIikuYXBwZW5kKGZGaW5hbCkuYXBwZW5kKCInLCAiKTsKLSAgICAgICAgc3RyLmFwcGVuZCgiIGJsb2NrPSciKS5hcHBlbmQoZkJsb2NrKS5hcHBlbmQoIicsICIpOwotICAgICAgICBpZiAoZlBhcnRpY2xlICE9IG51bGwpIHsKLSAgICAgICAgICAgIHN0ci5hcHBlbmQoIiBwYXJ0aWNsZT0nIikuYXBwZW5kKGZQYXJ0aWNsZS50b1N0cmluZygpKS5hcHBlbmQoIicsICIpOwotICAgICAgICB9Ci0gICAgICAgIHN0ci5hcHBlbmQoIiBkZXJpdmVkQnk9JyIpLmFwcGVuZChkZXJpdmVkQnlbZkRlcml2ZWRCeV0pLmFwcGVuZCgiJy4gIik7Ci0KLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBkZXJpdmVkRnJvbVR5cGUoWFNUeXBlRGVmaW5pdGlvbiBhbmNlc3Rvciwgc2hvcnQgZGVyaXZhdGlvbk1ldGhvZCkgewotICAgICAgICAvLyBhbmNlc3RvciBpcyBudWxsLCByZXR1ciBmYWxzZQotICAgICAgICBpZiAoYW5jZXN0b3IgPT0gbnVsbCkKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgLy8gYW5jZXN0b3IgaXMgYW55VHlwZSwgcmV0dXJuIHRydWUKLSAgICAgICAgaWYgKGFuY2VzdG9yID09IFNjaGVtYUdyYW1tYXIuZkFueVR5cGUpCi0gICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgLy8gcmVjdXJzaXZlbHkgZ2V0IGJhc2UsIGFuZCBjb21wYXJlIGl0IHdpdGggYW5jZXN0b3IKLSAgICAgICAgWFNUeXBlRGVmaW5pdGlvbiB0eXBlID0gdGhpczsKLSAgICAgICAgd2hpbGUgKHR5cGUgIT0gYW5jZXN0b3IgJiYgICAgICAgICAgICAgICAgICAgICAvLyBjb21wYXJlIHdpdGggYW5jZXN0b3IKLSAgICAgICAgICAgICAgIHR5cGUgIT0gU2NoZW1hR3JhbW1hci5mQW55U2ltcGxlVHlwZSAmJiAgLy8gcmVhY2hlZCBhbnlTaW1wbGVUeXBlCi0gICAgICAgICAgICAgICB0eXBlICE9IFNjaGVtYUdyYW1tYXIuZkFueVR5cGUpIHsgICAgICAgIC8vIHJlYWNoZWQgYW55VHlwZQotICAgICAgICAgICAgdHlwZSA9IHR5cGUuZ2V0QmFzZVR5cGUoKTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiB0eXBlID09IGFuY2VzdG9yOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGRlcml2ZWRGcm9tKFN0cmluZyBhbmNlc3Rvck5TLCBTdHJpbmcgYW5jZXN0b3JOYW1lLCBzaG9ydCBkZXJpdmF0aW9uTWV0aG9kKSB7Ci0gICAgICAgIC8vIGFuY2VzdG9yIGlzIG51bGwsIHJldHVyIGZhbHNlCi0gICAgICAgIGlmIChhbmNlc3Rvck5hbWUgPT0gbnVsbCkKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgLy8gYW5jZXN0b3IgaXMgYW55VHlwZSwgcmV0dXJuIHRydWUKLSAgICAgICAgaWYgKGFuY2VzdG9yTlMgIT0gbnVsbCAmJgotICAgICAgICAgICAgYW5jZXN0b3JOUy5lcXVhbHMoU2NoZW1hU3ltYm9scy5VUklfU0NIRU1BRk9SU0NIRU1BKSAmJgotICAgICAgICAgICAgYW5jZXN0b3JOYW1lLmVxdWFscyhTY2hlbWFTeW1ib2xzLkFUVFZBTF9BTllUWVBFKSkgewotICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyByZWN1cnNpdmVseSBnZXQgYmFzZSwgYW5kIGNvbXBhcmUgaXQgd2l0aCBhbmNlc3RvcgotICAgICAgICBYU1R5cGVEZWZpbml0aW9uIHR5cGUgPSB0aGlzOwotICAgICAgICB3aGlsZSAoIShhbmNlc3Rvck5hbWUuZXF1YWxzKHR5cGUuZ2V0TmFtZSgpKSAmJgotICAgICAgICAgICAgICAgICAoKGFuY2VzdG9yTlMgPT0gbnVsbCAmJiB0eXBlLmdldE5hbWVzcGFjZSgpID09IG51bGwpIHx8Ci0gICAgICAgICAgICAgICAgICAoYW5jZXN0b3JOUyAhPSBudWxsICYmIGFuY2VzdG9yTlMuZXF1YWxzKHR5cGUuZ2V0TmFtZXNwYWNlKCkpKSkpICYmICAgLy8gY29tcGFyZSB3aXRoIGFuY2VzdG9yCi0gICAgICAgICAgICAgICB0eXBlICE9IFNjaGVtYUdyYW1tYXIuZkFueVNpbXBsZVR5cGUgJiYgIC8vIHJlYWNoZWQgYW55U2ltcGxlVHlwZQotICAgICAgICAgICAgICAgdHlwZSAhPSBTY2hlbWFHcmFtbWFyLmZBbnlUeXBlKSB7ICAgICAgICAvLyByZWFjaGVkIGFueVR5cGUKLSAgICAgICAgICAgIHR5cGUgPSAoWFNUeXBlRGVmaW5pdGlvbil0eXBlLmdldEJhc2VUeXBlKCk7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gdHlwZSAhPSBTY2hlbWFHcmFtbWFyLmZBbnlTaW1wbGVUeXBlICYmCi0gICAgICAgIHR5cGUgIT0gU2NoZW1hR3JhbW1hci5mQW55VHlwZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDaGVja3MgaWYgYSB0eXBlIGlzIGRlcml2ZWQgZnJvbSBhbm90aGVyIGdpdmVuIHRoZSB0aGUgbmFtZSwgbmFtZXNwYWNlCi0gICAgICogYW5kIGRlcml2YXRpb24gbWV0aG9kLiBTZWU6Ci0gICAgICogaHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMtRE9NLUxldmVsLTMtQ29yZS0yMDA0MDQwNy9jb3JlLmh0bWwjVHlwZUluZm8taXNEZXJpdmVkRnJvbQotICAgICAqCi0gICAgICogQHBhcmFtIGFuY2VzdG9yTlMKLSAgICAgKiAgICAgICAgICAgIFRoZSBuYW1zcGFjZSBvZiB0aGUgYW5jZXN0b3IgdHlwZSBkZWNsYXJhdGlvbgotICAgICAqIEBwYXJhbSBhbmNlc3Rvck5hbWUKLSAgICAgKiAgICAgICAgICAgIFRoZSBuYW1lIG9mIHRoZSBhbmNlc3RvciB0eXBlIGRlY2xhcmF0aW9uCi0gICAgICogQHBhcmFtIGRlcml2YXRpb25NZXRob2QKLSAgICAgKiAgICAgICAgICAgIFRoZSBkZXJpdmF0aW9uIG1ldGhvZAotICAgICAqCi0gICAgICogQHJldHVybiBib29sZWFuIFRydWUgaWYgdGhlIGFuY2VzdG9yIHR5cGUgaXMgZGVyaXZlZCBmcm9tIHRoZSByZWZlcmVuY2UKLSAgICAgKiAgICAgICAgIHR5cGUgYnkgdGhlIHNwZWNpZmlpZWQgZGVyaXZhdGlvbiBtZXRob2QuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNET01EZXJpdmVkRnJvbShTdHJpbmcgYW5jZXN0b3JOUywgU3RyaW5nIGFuY2VzdG9yTmFtZSwKLSAgICAgICAgICAgIGludCBkZXJpdmF0aW9uTWV0aG9kKSB7Ci0gICAgICAgIC8vIGFuY2VzdG9yIGlzIG51bGwsIHJldHVyIGZhbHNlCi0gICAgICAgIGlmIChhbmNlc3Rvck5hbWUgPT0gbnVsbCkKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLQotICAgICAgICAvLyBhbmNlc3RvciBpcyBhbnlUeXBlLCByZXR1cm4gdHJ1ZQotICAgICAgICBpZiAoYW5jZXN0b3JOUyAhPSBudWxsCi0gICAgICAgICAgICAgICAgJiYgYW5jZXN0b3JOUy5lcXVhbHMoU2NoZW1hU3ltYm9scy5VUklfU0NIRU1BRk9SU0NIRU1BKQotICAgICAgICAgICAgICAgICYmIGFuY2VzdG9yTmFtZS5lcXVhbHMoU2NoZW1hU3ltYm9scy5BVFRWQUxfQU5ZVFlQRSkKLSAgICAgICAgICAgICAgICAmJiAoZGVyaXZhdGlvbk1ldGhvZCA9PSBERVJJVkFUSU9OX1JFU1RSSUNUSU9OCi0gICAgICAgICAgICAgICAgJiYgZGVyaXZhdGlvbk1ldGhvZCA9PSBERVJJVkFUSU9OX0VYVEVOU0lPTikpIHsKLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gcmVzdHJpY3Rpb24KLSAgICAgICAgaWYgKChkZXJpdmF0aW9uTWV0aG9kICYgREVSSVZBVElPTl9SRVNUUklDVElPTikgIT0gMCkgewotICAgICAgICAgICAgaWYgKGlzRGVyaXZlZEJ5UmVzdHJpY3Rpb24oYW5jZXN0b3JOUywgYW5jZXN0b3JOYW1lLAotICAgICAgICAgICAgICAgICAgICBkZXJpdmF0aW9uTWV0aG9kLCB0aGlzKSkgewotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gZXh0ZW5zaW9uCi0gICAgICAgIGlmICgoZGVyaXZhdGlvbk1ldGhvZCAmIERFUklWQVRJT05fRVhURU5TSU9OKSAhPSAwKSB7Ci0gICAgICAgICAgICBpZiAoaXNEZXJpdmVkQnlFeHRlbnNpb24oYW5jZXN0b3JOUywgYW5jZXN0b3JOYW1lLAotICAgICAgICAgICAgICAgICAgICBkZXJpdmF0aW9uTWV0aG9kLCB0aGlzKSkgewotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gbGlzdCBvciB1bmlvbgotICAgICAgICBpZiAoKCgoZGVyaXZhdGlvbk1ldGhvZCAmIERFUklWQVRJT05fTElTVCkgIT0gMCkgfHwgKChkZXJpdmF0aW9uTWV0aG9kICYgREVSSVZBVElPTl9VTklPTikgIT0gMCkpCi0gICAgICAgICAgICAgICAgJiYgKChkZXJpdmF0aW9uTWV0aG9kICYgREVSSVZBVElPTl9SRVNUUklDVElPTikgPT0gMCkKLSAgICAgICAgICAgICAgICAmJiAoKGRlcml2YXRpb25NZXRob2QgJiBERVJJVkFUSU9OX0VYVEVOU0lPTikgPT0gMCkpIHsKLQotICAgICAgICAgICAgaWYgKGFuY2VzdG9yTlMuZXF1YWxzKFNjaGVtYVN5bWJvbHMuVVJJX1NDSEVNQUZPUlNDSEVNQSkKLSAgICAgICAgICAgICAgICAgICAgJiYgYW5jZXN0b3JOYW1lLmVxdWFscyhTY2hlbWFTeW1ib2xzLkFUVFZBTF9BTllUWVBFKSkgewotICAgICAgICAgICAgICAgIGFuY2VzdG9yTmFtZSA9IFNjaGVtYVN5bWJvbHMuQVRUVkFMX0FOWVNJTVBMRVRZUEU7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmKCEoZk5hbWUuZXF1YWxzKFNjaGVtYVN5bWJvbHMuQVRUVkFMX0FOWVRZUEUpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgZlRhcmdldE5hbWVzcGFjZS5lcXVhbHMoU2NoZW1hU3ltYm9scy5VUklfU0NIRU1BRk9SU0NIRU1BKSkpewotICAgICAgICAgICAgICAgIGlmIChmQmFzZVR5cGUgIT0gbnVsbCAmJiBmQmFzZVR5cGUgaW5zdGFuY2VvZiBYU1NpbXBsZVR5cGVEZWNsKSB7Ci0KLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuICgoWFNTaW1wbGVUeXBlRGVjbCkgZkJhc2VUeXBlKS5pc0RPTURlcml2ZWRGcm9tKGFuY2VzdG9yTlMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5jZXN0b3JOYW1lLCBkZXJpdmF0aW9uTWV0aG9kKTsKLSAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGZCYXNlVHlwZSAhPSBudWxsCi0gICAgICAgICAgICAgICAgICAgICAgICAmJiBmQmFzZVR5cGUgaW5zdGFuY2VvZiBYU0NvbXBsZXhUeXBlRGVjbCkgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gKChYU0NvbXBsZXhUeXBlRGVjbCkgZkJhc2VUeXBlKS5pc0RPTURlcml2ZWRGcm9tKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuY2VzdG9yTlMsIGFuY2VzdG9yTmFtZSwgZGVyaXZhdGlvbk1ldGhvZCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gSWYgdGhlIHZhbHVlIG9mIHRoZSBwYXJhbWV0ZXIgaXMgMCBpLmUuIG5vIGJpdCAoY29ycmVzcG9uZGluZyB0bwotICAgICAgICAvLyByZXN0cmljdGlvbiwgbGlzdCwgZXh0ZW5zaW9uIG9yIHVuaW9uKSBpcyBzZXQgdG8gMSBmb3IgdGhlCi0gICAgICAgIC8vIGRlcml2YXRpb25NZXRob2QgcGFyYW1ldGVyLgotICAgICAgICBpZiAoKChkZXJpdmF0aW9uTWV0aG9kICAmIERFUklWQVRJT05fRVhURU5TSU9OKSA9PSAwKQotICAgICAgICAgICAgICAgICYmICgoKGRlcml2YXRpb25NZXRob2QgJiBERVJJVkFUSU9OX1JFU1RSSUNUSU9OKSA9PSAwKQotICAgICAgICAgICAgICAgICAgICAgICAgJiYgKChkZXJpdmF0aW9uTWV0aG9kICYgREVSSVZBVElPTl9MSVNUKSA9PSAwKQotICAgICAgICAgICAgICAgICAgICAgICAgJiYgKChkZXJpdmF0aW9uTWV0aG9kICYgREVSSVZBVElPTl9VTklPTikgPT0gMCkpKSB7Ci0gICAgICAgICAgICByZXR1cm4gaXNEZXJpdmVkQnlBbnkoYW5jZXN0b3JOUywgYW5jZXN0b3JOYW1lLCBkZXJpdmF0aW9uTWV0aG9kLCB0aGlzKTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDaGVja3MgaWYgYSB0eXBlIGlzIGRlcml2ZWQgZnJvbSBhbm90aGVyIGJ5IGFueSBjb21iaW5hdGlvbiBvZgotICAgICAqIHJlc3RyaWN0aW9uLCBsaXN0IGlyIHVuaW9uLiBTZWU6Ci0gICAgICogaHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMtRE9NLUxldmVsLTMtQ29yZS0yMDA0MDQwNy9jb3JlLmh0bWwjVHlwZUluZm8taXNEZXJpdmVkRnJvbQotICAgICAqCi0gICAgICogQHBhcmFtIGFuY2VzdG9yTlMKLSAgICAgKiAgICAgICAgICAgIFRoZSBuYW1zcGFjZSBvZiB0aGUgYW5jZXN0b3IgdHlwZSBkZWNsYXJhdGlvbgotICAgICAqIEBwYXJhbSBhbmNlc3Rvck5hbWUKLSAgICAgKiAgICAgICAgICAgIFRoZSBuYW1lIG9mIHRoZSBhbmNlc3RvciB0eXBlIGRlY2xhcmF0aW9uCi0gICAgICogQHBhcmFtIGRlcml2YXRpb25NZXRob2QKLSAgICAgKiAgICAgICAgICAgIEEgc2hvcnQgaW5kaWNhdGlvbiB0aGUgbWV0aG9kIG9mIGRlcml2YXRpb24KLSAgICAgKiBAcGFyYW0gdHlwZQotICAgICAqICAgICAgICAgICAgVGhlIHJlZmVyZW5jZSB0eXBlIGRlZmluaXRpb24KLSAgICAgKgotICAgICAqIEByZXR1cm4gYm9vbGVhbiBUcnVlIGlmIHRoZSB0eXBlIGlzIGRlcml2ZWQgYnkgYW55IG1ldGhvZCBmb3IgdGhlCi0gICAgICogICAgICAgICByZWZlcmVuY2UgdHlwZQotICAgICAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBpc0Rlcml2ZWRCeUFueShTdHJpbmcgYW5jZXN0b3JOUywgU3RyaW5nIGFuY2VzdG9yTmFtZSwKLSAgICAgICAgICAgIGludCBkZXJpdmF0aW9uTWV0aG9kLCBYU1R5cGVEZWZpbml0aW9uIHR5cGUpIHsKLSAgICAgICAgWFNUeXBlRGVmaW5pdGlvbiBvbGRUeXBlID0gbnVsbDsKLSAgICAgICAgYm9vbGVhbiBkZXJpdmVkRnJvbSA9IGZhbHNlOwotICAgICAgICB3aGlsZSAodHlwZSAhPSBudWxsICYmIHR5cGUgIT0gb2xkVHlwZSkgewotCi0gICAgICAgICAgICAvLyBJZiB0aGUgYW5jZXN0b3IgdHlwZSBpcyByZWFjaGVkIG9yIGlzIHRoZSBzYW1lIGFzIHRoaXMgdHlwZS4KLSAgICAgICAgICAgIGlmICgoYW5jZXN0b3JOYW1lLmVxdWFscyh0eXBlLmdldE5hbWUoKSkpCi0gICAgICAgICAgICAgICAgICAgICYmICgoYW5jZXN0b3JOUyA9PSBudWxsICYmIHR5cGUuZ2V0TmFtZXNwYWNlKCkgPT0gbnVsbCkKLSAgICAgICAgICAgICAgICAgICAgICAgIHx8IChhbmNlc3Rvck5TICE9IG51bGwgJiYgYW5jZXN0b3JOUy5lcXVhbHModHlwZS5nZXROYW1lc3BhY2UoKSkpKSkgewotICAgICAgICAgICAgICAgIGRlcml2ZWRGcm9tID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gQ2hlY2sgaWYgdGhpcyB0eXBlIGlzIGRlcml2ZWQgZnJvbSB0aGUgYmFzZSBieSByZXN0cmljdGlvbiBvcgotICAgICAgICAgICAgLy8gZXh0ZW5zaW9uCi0gICAgICAgICAgICBpZiAoaXNEZXJpdmVkQnlSZXN0cmljdGlvbihhbmNlc3Rvck5TLCBhbmNlc3Rvck5hbWUsCi0gICAgICAgICAgICAgICAgICAgIGRlcml2YXRpb25NZXRob2QsIHR5cGUpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICB9IGVsc2UgaWYgKCFpc0Rlcml2ZWRCeUV4dGVuc2lvbihhbmNlc3Rvck5TLCBhbmNlc3Rvck5hbWUsCi0gICAgICAgICAgICAgICAgICAgIGRlcml2YXRpb25NZXRob2QsIHR5cGUpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBvbGRUeXBlID0gdHlwZTsKLSAgICAgICAgICAgIHR5cGUgPSB0eXBlLmdldEJhc2VUeXBlKCk7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gZGVyaXZlZEZyb207Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ2hlY2tzIGlmIGEgdHlwZSBpcyBkZXJpdmVkIGZyb20gYW5vdGhlciBieSByZXN0cmljdGlvbi4gU2VlOgotICAgICAqIGh0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLURPTS1MZXZlbC0zLUNvcmUtMjAwNDA0MDcvY29yZS5odG1sI1R5cGVJbmZvLWlzRGVyaXZlZEZyb20KLSAgICAgKgotICAgICAqIEBwYXJhbSBhbmNlc3Rvck5TCi0gICAgICogICAgICAgICAgICBUaGUgbmFtc3BhY2Ugb2YgdGhlIGFuY2VzdG9yIHR5cGUgZGVjbGFyYXRpb24KLSAgICAgKiBAcGFyYW0gYW5jZXN0b3JOYW1lCi0gICAgICogICAgICAgICAgICBUaGUgbmFtZSBvZiB0aGUgYW5jZXN0b3IgdHlwZSBkZWNsYXJhdGlvbgotICAgICAqIEBwYXJhbSBkZXJpdmF0aW9uTWV0aG9kCi0gICAgICogICAgICAgICAgICBBIHNob3J0IGluZGljYXRpb24gdGhlIG1ldGhvZCBvZiBkZXJpdmF0aW9uICoKLSAgICAgKiBAcGFyYW0gdHlwZQotICAgICAqICAgICAgICAgICAgVGhlIHJlZmVyZW5jZSB0eXBlIGRlZmluaXRpb24KLSAgICAgKgotICAgICAqIEByZXR1cm4gYm9vbGVhbiBUcnVlIGlmIHRoZSB0eXBlIGlzIGRlcml2ZWQgYnkgcmVzdHJpY2l0b24gZm9yIHRoZQotICAgICAqICAgICAgICAgcmVmZXJlbmNlIHR5cGUKLSAgICAgKi8KLSAgICBwcml2YXRlIGJvb2xlYW4gaXNEZXJpdmVkQnlSZXN0cmljdGlvbihTdHJpbmcgYW5jZXN0b3JOUywKLSAgICAgICAgICAgIFN0cmluZyBhbmNlc3Rvck5hbWUsIGludCBkZXJpdmF0aW9uTWV0aG9kLCBYU1R5cGVEZWZpbml0aW9uIHR5cGUpIHsKLQotICAgICAgICBYU1R5cGVEZWZpbml0aW9uIG9sZFR5cGUgPSBudWxsOwotICAgICAgICB3aGlsZSAodHlwZSAhPSBudWxsICYmIHR5cGUgIT0gb2xkVHlwZSkgewotCi0gICAgICAgICAgICAvLyBhbmNlc3RvciBpcyBhbnlTaW1wbGVUeXBlLCByZXR1cm4gZmFsc2UKLSAgICAgICAgICAgIGlmIChhbmNlc3Rvck5TICE9IG51bGwKLSAgICAgICAgICAgICAgICAgICAgJiYgYW5jZXN0b3JOUy5lcXVhbHMoU2NoZW1hU3ltYm9scy5VUklfU0NIRU1BRk9SU0NIRU1BKQotICAgICAgICAgICAgICAgICAgICAmJiBhbmNlc3Rvck5hbWUuZXF1YWxzKFNjaGVtYVN5bWJvbHMuQVRUVkFMX0FOWVNJTVBMRVRZUEUpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBpZiB0aGUgbmFtZSBhbmQgbmFtZXNwYWNlIG9mIHRoaXMgdHlwZSBpcyB0aGUgc2FtZSBhcyB0aGUKLSAgICAgICAgICAgIC8vIGFuY2VzdG9yIHJldHVybiB0cnVlCi0gICAgICAgICAgICBpZiAoKGFuY2VzdG9yTmFtZS5lcXVhbHModHlwZS5nZXROYW1lKCkpKQotICAgICAgICAgICAgICAgICAgICAmJiAoYW5jZXN0b3JOUyAhPSBudWxsICYmIGFuY2VzdG9yTlMuZXF1YWxzKHR5cGUuZ2V0TmFtZXNwYWNlKCkpKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8ICgodHlwZS5nZXROYW1lc3BhY2UoKSA9PSBudWxsICYmIGFuY2VzdG9yTlMgPT0gbnVsbCkpKSB7Ci0KLSAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gSWYgdGhlIGJhc2UgdHlwZSBpcyBhIGNvbXBsZXhUeXBlIHdpdGggc2ltcGxlQ29udGVudAotICAgICAgICAgICAgaWYgKHR5cGUgaW5zdGFuY2VvZiBYU1NpbXBsZVR5cGVEZWNsKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGFuY2VzdG9yTlMuZXF1YWxzKFNjaGVtYVN5bWJvbHMuVVJJX1NDSEVNQUZPUlNDSEVNQSkKLSAgICAgICAgICAgICAgICAgICAgICAgICYmIGFuY2VzdG9yTmFtZS5lcXVhbHMoU2NoZW1hU3ltYm9scy5BVFRWQUxfQU5ZVFlQRSkpIHsKLSAgICAgICAgICAgICAgICAgICAgYW5jZXN0b3JOYW1lID0gU2NoZW1hU3ltYm9scy5BVFRWQUxfQU5ZU0lNUExFVFlQRTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgcmV0dXJuICgoWFNTaW1wbGVUeXBlRGVjbCkgdHlwZSkuaXNET01EZXJpdmVkRnJvbShhbmNlc3Rvck5TLAotICAgICAgICAgICAgICAgICAgICAgICAgYW5jZXN0b3JOYW1lLCBkZXJpdmF0aW9uTWV0aG9kKTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgLy8gSWYgdGhlIGJhc2UgdHlwZSBpcyBhIGNvbXBsZXggdHlwZQotICAgICAgICAgICAgICAgIC8vIEV2ZXJ5IGRlcml2YXRpb24gc3RlcCB0aWxsIHRoZSBiYXNlIHR5cGUgc2hvdWxkIGJlCi0gICAgICAgICAgICAgICAgLy8gcmVzdHJpY3Rpb24uIElmIG5vdCByZXR1cm4gZmFsc2UKLSAgICAgICAgICAgICAgICBpZiAoKChYU0NvbXBsZXhUeXBlRGVjbCkgdHlwZSkuZ2V0RGVyaXZhdGlvbk1ldGhvZCgpICE9IFhTQ29uc3RhbnRzLkRFUklWQVRJT05fUkVTVFJJQ1RJT04pIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIG9sZFR5cGUgPSB0eXBlOwotICAgICAgICAgICAgdHlwZSA9IHR5cGUuZ2V0QmFzZVR5cGUoKTsKLQotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENoZWNrcyBpZiBhIHR5cGUgaXMgZGVyaXZlZCBmcm9tIGFub3RoZXIgYnkgZXh0ZW5zaW9uLiBTZWU6Ci0gICAgICogaHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMtRE9NLUxldmVsLTMtQ29yZS0yMDA0MDQwNy9jb3JlLmh0bWwjVHlwZUluZm8taXNEZXJpdmVkRnJvbQotICAgICAqCi0gICAgICogQHBhcmFtIGFuY2VzdG9yTlMKLSAgICAgKiAgICAgICAgICAgIFRoZSBuYW1zcGFjZSBvZiB0aGUgYW5jZXN0b3IgdHlwZSBkZWNsYXJhdGlvbgotICAgICAqIEBwYXJhbSBhbmNlc3Rvck5hbWUKLSAgICAgKiAgICAgICAgICAgIFRoZSBuYW1lIG9mIHRoZSBhbmNlc3RvciB0eXBlIGRlY2xhcmF0aW9uCi0gICAgICogQHBhcmFtIGRlcml2YXRpb25NZXRob2QKLSAgICAgKiAgICAgICAgICAgIEEgc2hvcnQgaW5kaWNhdGlvbiB0aGUgbWV0aG9kIG9mIGRlcml2YXRpb24KLSAgICAgKiBAcGFyYW0gdHlwZQotICAgICAqICAgICAgICAgICAgVGhlIHJlZmVyZW5jZSB0eXBlIGRlZmluaXRpb24KLSAgICAgKgotICAgICAqIEByZXR1cm4gYm9vbGVhbiBUcnVlIGlmIHRoZSB0eXBlIGlzIGRlcml2ZWQgYnkgZXh0ZW5zaW9uIGZvciB0aGUKLSAgICAgKiAgICAgICAgIHJlZmVyZW5jZSB0eXBlCi0gICAgICovCi0gICAgcHJpdmF0ZSBib29sZWFuIGlzRGVyaXZlZEJ5RXh0ZW5zaW9uKFN0cmluZyBhbmNlc3Rvck5TLAotICAgICAgICAgICAgU3RyaW5nIGFuY2VzdG9yTmFtZSwgaW50IGRlcml2YXRpb25NZXRob2QsIFhTVHlwZURlZmluaXRpb24gdHlwZSkgewotCi0gICAgICAgIGJvb2xlYW4gZXh0ZW5zaW9uID0gZmFsc2U7Ci0gICAgICAgIFhTVHlwZURlZmluaXRpb24gb2xkVHlwZSA9IG51bGw7Ci0gICAgICAgIHdoaWxlICh0eXBlICE9IG51bGwgJiYgdHlwZSAhPSBvbGRUeXBlKSB7Ci0gICAgICAgICAgICAvLyBJZiBhbmNlc3RvciBpcyBhbnlTaW1wbGVUeXBlIHJldHVybiBmYWxzZS4KLSAgICAgICAgICAgIGlmIChhbmNlc3Rvck5TICE9IG51bGwKLSAgICAgICAgICAgICAgICAgICAgJiYgYW5jZXN0b3JOUy5lcXVhbHMoU2NoZW1hU3ltYm9scy5VUklfU0NIRU1BRk9SU0NIRU1BKQotICAgICAgICAgICAgICAgICAgICAmJiBhbmNlc3Rvck5hbWUuZXF1YWxzKFNjaGVtYVN5bWJvbHMuQVRUVkFMX0FOWVNJTVBMRVRZUEUpCi0gICAgICAgICAgICAgICAgICAgICYmIFNjaGVtYVN5bWJvbHMuVVJJX1NDSEVNQUZPUlNDSEVNQS5lcXVhbHModHlwZS5nZXROYW1lc3BhY2UoKSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiBTY2hlbWFTeW1ib2xzLkFUVFZBTF9BTllUWVBFLmVxdWFscyh0eXBlLmdldE5hbWUoKSkpIHsKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKChhbmNlc3Rvck5hbWUuZXF1YWxzKHR5cGUuZ2V0TmFtZSgpKSkKLSAgICAgICAgICAgICAgICAgICAgJiYgKChhbmNlc3Rvck5TID09IG51bGwgJiYgdHlwZS5nZXROYW1lc3BhY2UoKSA9PSBudWxsKQotICAgICAgICAgICAgICAgICAgICAgICAgfHwgKGFuY2VzdG9yTlMgIT0gbnVsbCAmJiBhbmNlc3Rvck5TLmVxdWFscyh0eXBlLmdldE5hbWVzcGFjZSgpKSkpKSB7Ci0gICAgICAgICAgICAgICAgLy8gcmV0dXJucyB0cnVlIGlmIGF0bGVhc3Qgb25lIGRlcml2YXRpb24gc3RlcCB3YXMgZXh0ZW5zaW9uCi0gICAgICAgICAgICAgICAgcmV0dXJuIGV4dGVuc2lvbjsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gSWYgdGhlIGJhc2UgdHlwZSBpcyBhIGNvbXBsZXhUeXBlIHdpdGggc2ltcGxlQ29udGVudAotICAgICAgICAgICAgaWYgKHR5cGUgaW5zdGFuY2VvZiBYU1NpbXBsZVR5cGVEZWNsKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGFuY2VzdG9yTlMuZXF1YWxzKFNjaGVtYVN5bWJvbHMuVVJJX1NDSEVNQUZPUlNDSEVNQSkKLSAgICAgICAgICAgICAgICAgICAgICAgICYmIGFuY2VzdG9yTmFtZS5lcXVhbHMoU2NoZW1hU3ltYm9scy5BVFRWQUxfQU5ZVFlQRSkpIHsKLSAgICAgICAgICAgICAgICAgICAgYW5jZXN0b3JOYW1lID0gU2NoZW1hU3ltYm9scy5BVFRWQUxfQU5ZU0lNUExFVFlQRTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyBkZXJpdmF0aW9uTWV0aG9kIGV4dGVuc2lvbiB3aWxsIGFsd2F5cyByZXR1cm4gZmFsc2UgZm9yIGEKLSAgICAgICAgICAgICAgICAvLyBzaW1wbGVUeXBlLAotICAgICAgICAgICAgICAgIC8vIHdlIHRyZWF0IGl0IGxpa2UgYSByZXN0cmljdGlvbgotICAgICAgICAgICAgICAgIGlmICgoZGVyaXZhdGlvbk1ldGhvZCAmIERFUklWQVRJT05fRVhURU5TSU9OKSAhPSAwKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBleHRlbnNpb24KLSAgICAgICAgICAgICAgICAgICAgJiAoKFhTU2ltcGxlVHlwZURlY2wpIHR5cGUpLmlzRE9NRGVyaXZlZEZyb20oCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5jZXN0b3JOUywgYW5jZXN0b3JOYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIChkZXJpdmF0aW9uTWV0aG9kICYgREVSSVZBVElPTl9SRVNUUklDVElPTikpOwotICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBleHRlbnNpb24KLSAgICAgICAgICAgICAgICAgICAgJiAoKFhTU2ltcGxlVHlwZURlY2wpIHR5cGUpLmlzRE9NRGVyaXZlZEZyb20oCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5jZXN0b3JOUywgYW5jZXN0b3JOYW1lLCBkZXJpdmF0aW9uTWV0aG9kKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgLy8gSWYgdGhlIGJhc2UgdHlwZSBpcyBhIGNvbXBsZXggdHlwZQotICAgICAgICAgICAgICAgIC8vIEF0IGxlYXN0IG9uZSBkZXJpdmF0aW9uIHN0ZXAgdXB0byB0aGUgYW5jZXN0b3IgdHlwZSBzaG91bGQgYmUKLSAgICAgICAgICAgICAgICAvLyBleHRlbnNpb24uCi0gICAgICAgICAgICAgICAgaWYgKCgoWFNDb21wbGV4VHlwZURlY2wpIHR5cGUpLmdldERlcml2YXRpb25NZXRob2QoKSA9PSBYU0NvbnN0YW50cy5ERVJJVkFUSU9OX0VYVEVOU0lPTikgewotICAgICAgICAgICAgICAgICAgICBleHRlbnNpb24gPSBleHRlbnNpb24gfCB0cnVlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIG9sZFR5cGUgPSB0eXBlOwotICAgICAgICAgICAgdHlwZSA9IHR5cGUuZ2V0QmFzZVR5cGUoKTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLQotCi0gICAgcHVibGljIHZvaWQgcmVzZXQoKXsKLSAgICAgICAgZk5hbWUgPSBudWxsOwotICAgICAgICBmVGFyZ2V0TmFtZXNwYWNlID0gbnVsbDsKLSAgICAgICAgZkJhc2VUeXBlID0gbnVsbDsKLSAgICAgICAgZkRlcml2ZWRCeSA9IFhTQ29uc3RhbnRzLkRFUklWQVRJT05fUkVTVFJJQ1RJT047Ci0gICAgICAgIGZGaW5hbCA9IFhTQ29uc3RhbnRzLkRFUklWQVRJT05fTk9ORTsKLSAgICAgICAgZkJsb2NrID0gWFNDb25zdGFudHMuREVSSVZBVElPTl9OT05FOwotCi0gICAgICAgIGZNaXNjRmxhZ3MgPSAwOwotCi0gICAgICAgIC8vIHJlc2V0IGF0dHJpYnV0ZSBncm91cAotICAgICAgICBmQXR0ckdycC5yZXNldCgpOwotICAgICAgICBmQ29udGVudFR5cGUgPSBDT05URU5UVFlQRV9FTVBUWTsKLSAgICAgICAgZlhTU2ltcGxlVHlwZSA9IG51bGw7Ci0gICAgICAgIGZQYXJ0aWNsZSA9IG51bGw7Ci0gICAgICAgIGZDTVZhbGlkYXRvciA9IG51bGw7Ci0gICAgICAgIGZVUEFDTVZhbGlkYXRvciA9IG51bGw7Ci0gICAgICAgIGlmKGZBbm5vdGF0aW9ucyAhPSBudWxsKSB7Ci0gICAgICAgICAgICAvLyBoZWxwIG91dCB0aGUgZ2FyYmFnZSBjb2xsZWN0b3IKLSAgICAgICAgICAgIGZBbm5vdGF0aW9ucy5jbGVhclhTT2JqZWN0TGlzdCgpOwotICAgICAgICB9Ci0gICAgICAgIGZBbm5vdGF0aW9ucyA9IG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSB0eXBlIG9mIHRoZSBvYmplY3QsIGkuZSBFTEVNRU5UX0RFQ0xBUkFUSU9OLgotICAgICAqLwotICAgIHB1YmxpYyBzaG9ydCBnZXRUeXBlKCkgewotICAgICAgICByZXR1cm4gWFNDb25zdGFudHMuVFlQRV9ERUZJTklUSU9OOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoZSA8Y29kZT5uYW1lPC9jb2RlPiBvZiB0aGlzIDxjb2RlPlhTT2JqZWN0PC9jb2RlPiBkZXBlbmRpbmcgb24gdGhlCi0gICAgICogPGNvZGU+WFNPYmplY3Q8L2NvZGU+IHR5cGUuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXROYW1lKCkgewotICAgICAgICByZXR1cm4gZ2V0QW5vbnltb3VzKCkgPyBudWxsIDogZk5hbWU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQSBib29sZWFuIHRoYXQgc3BlY2lmaWVzIGlmIHRoZSB0eXBlIGRlZmluaXRpb24gaXMgYW5vbnltb3VzLgotICAgICAqIENvbnZlbmllbmNlIGF0dHJpYnV0ZS4gVGhpcyBpcyBhIGZpZWxkIGlzIG5vdCBwYXJ0IG9mCi0gICAgICogWE1MIFNjaGVtYSBjb21wb25lbnQgbW9kZWwuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0QW5vbnltb3VzKCkgewotICAgICAgICByZXR1cm4oKGZNaXNjRmxhZ3MgJiBDVF9JU19BTk9OWU1PVVMpICE9IDApOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoZSBuYW1lc3BhY2UgVVJJIG9mIHRoaXMgbm9kZSwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgaXQgaXMKLSAgICAgKiB1bnNwZWNpZmllZC4gIGRlZmluZXMgaG93IGEgbmFtZXNwYWNlIFVSSSBpcyBhdHRhY2hlZCB0byBzY2hlbWEKLSAgICAgKiBjb21wb25lbnRzLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZXNwYWNlKCkgewotICAgICAgICByZXR1cm4gZlRhcmdldE5hbWVzcGFjZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiB7YmFzZSB0eXBlIGRlZmluaXRpb259IEVpdGhlciBhIHNpbXBsZSB0eXBlIGRlZmluaXRpb24gb3IgYSBjb21wbGV4Ci0gICAgICogdHlwZSBkZWZpbml0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBYU1R5cGVEZWZpbml0aW9uIGdldEJhc2VUeXBlKCkgewotICAgICAgICByZXR1cm4gZkJhc2VUeXBlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIHtkZXJpdmF0aW9uIG1ldGhvZH0gRWl0aGVyIGV4dGVuc2lvbiBvciByZXN0cmljdGlvbi4gVGhlIHZhbGlkIGNvbnN0YW50Ci0gICAgICogdmFsdWUgZm9yIHRoaXMgPGNvZGU+WFNDb25zdGFudHM8L2NvZGU+IEVYVEVOVElPTiwgUkVTVFJJQ1RJT04uCi0gICAgICovCi0gICAgcHVibGljIHNob3J0IGdldERlcml2YXRpb25NZXRob2QoKSB7Ci0gICAgICAgIHJldHVybiBmRGVyaXZlZEJ5OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIHtmaW5hbH0gRm9yIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uIGl0IGlzIGEgc3Vic2V0IG9mIHtleHRlbnNpb24sCi0gICAgICogcmVzdHJpY3Rpb259LiBGb3Igc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiBpdCBpcyBhIHN1YnNldCBvZgotICAgICAqIHtleHRlbnNpb24sIGxpc3QsIHJlc3RyaWN0aW9uLCB1bmlvbn0uCi0gICAgICogQHBhcmFtIGRlcml2YXRpb24gIEV4dGVuc2lvbiwgcmVzdHJpY3Rpb24sIGxpc3QsIHVuaW9uIGNvbnN0YW50cwotICAgICAqICAgKGRlZmluZWQgaW4gPGNvZGU+WFNDb25zdGFudHM8L2NvZGU+KS4KLSAgICAgKiBAcmV0dXJuIFRydWUgaWYgZGVyaXZhdGlvbiBpcyBpbiB0aGUgZmluYWwgc2V0LCBvdGhlcndpc2UgZmFsc2UuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNGaW5hbChzaG9ydCBkZXJpdmF0aW9uKSB7Ci0gICAgICAgIHJldHVybiAoZkZpbmFsICYgZGVyaXZhdGlvbikgIT0gMDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiB7ZmluYWx9IEZvciBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbiBpdCBpcyBhIHN1YnNldCBvZiB7ZXh0ZW5zaW9uLCByZXN0cmljdGlvbn0uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIEEgYml0IGZsYWcgdGhhdCByZXByZXNlbnRzOgotICAgICAqICAgICAgICAge2V4dGVuc2lvbiwgcmVzdHJpY3Rpb24pIG9yIG5vbmUgZm9yIGNvbXBsZXhUeXBlczsKLSAgICAgKiAgICAgICAgIHtleHRlbnNpb24sIGxpc3QsIHJlc3RyaWN0aW9uLCB1bmlvbn0gb3Igbm9uZSBmb3Igc2ltcGxlVHlwZXM7Ci0gICAgICovCi0gICAgcHVibGljIHNob3J0IGdldEZpbmFsKCkgewotICAgICAgICByZXR1cm4gZkZpbmFsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIHthYnN0cmFjdH0gQSBib29sZWFuLiBDb21wbGV4IHR5cGVzIGZvciB3aGljaCB7YWJzdHJhY3R9IGlzIHRydWUgbXVzdAotICAgICAqIG5vdCBiZSB1c2VkIGFzIHRoZSB7dHlwZSBkZWZpbml0aW9ufSBmb3IgdGhlIHZhbGlkYXRpb24gb2YgZWxlbWVudAotICAgICAqIGluZm9ybWF0aW9uIGl0ZW1zLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGdldEFic3RyYWN0KCkgewotICAgICAgICByZXR1cm4oKGZNaXNjRmxhZ3MgJiBDVF9JU19BQlNUUkFDVCkgIT0gMCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogIHthdHRyaWJ1dGUgdXNlc30gQSBzZXQgb2YgYXR0cmlidXRlIHVzZXMuCi0gICAgICovCi0gICAgcHVibGljIFhTT2JqZWN0TGlzdCBnZXRBdHRyaWJ1dGVVc2VzKCkgewotICAgICAgICByZXR1cm4gZkF0dHJHcnAuZ2V0QXR0cmlidXRlVXNlcygpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIHthdHRyaWJ1dGUgd2lsZGNhcmR9IE9wdGlvbmFsLiBBIHdpbGRjYXJkLgotICAgICAqLwotICAgIHB1YmxpYyBYU1dpbGRjYXJkIGdldEF0dHJpYnV0ZVdpbGRjYXJkKCkgewotICAgICAgICByZXR1cm4gZkF0dHJHcnAuZ2V0QXR0cmlidXRlV2lsZGNhcmQoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiB7Y29udGVudCB0eXBlfSBPbmUgb2YgZW1wdHksIGEgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiAoc2VlCi0gICAgICogPGNvZGU+c2ltcGxlVHlwZTwvY29kZT4sIG9yIG1peGVkLCBlbGVtZW50LW9ubHkgKHNlZQotICAgICAqIDxjb2RlPmNtUGFydGljbGU8L2NvZGU+KS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc2hvcnQgZ2V0Q29udGVudFR5cGUoKSB7Ci0gICAgICAgIHJldHVybiBmQ29udGVudFR5cGU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uIGNvcnJlc3BvbmRpbmcgdG8gc2ltcGxlIGNvbnRlbnQgbW9kZWwsCi0gICAgICogb3RoZXJ3aXNlIDxjb2RlPm51bGw8L2NvZGU+Ci0gICAgICovCi0gICAgcHVibGljIFhTU2ltcGxlVHlwZURlZmluaXRpb24gZ2V0U2ltcGxlVHlwZSgpIHsKLSAgICAgICAgcmV0dXJuIGZYU1NpbXBsZVR5cGU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQSBwYXJ0aWNsZSBmb3IgbWl4ZWQgb3IgZWxlbWVudC1vbmx5IGNvbnRlbnQgbW9kZWwsIG90aGVyd2lzZQotICAgICAqIDxjb2RlPm51bGw8L2NvZGU+Ci0gICAgICovCi0gICAgcHVibGljIFhTUGFydGljbGUgZ2V0UGFydGljbGUoKSB7Ci0gICAgICAgIHJldHVybiBmUGFydGljbGU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICoge3Byb2hpYml0ZWQgc3Vic3RpdHV0aW9uc30gQSBzdWJzZXQgb2Yge2V4dGVuc2lvbiwgcmVzdHJpY3Rpb259LgotICAgICAqIEBwYXJhbSBwcm9oaWJpdGVkICBleHRlbnRpb24gb3IgcmVzdHJpY3Rpb24gY29uc3RhbnRzIChkZWZpbmVkIGluCi0gICAgICogICA8Y29kZT5YU0NvbnN0YW50czwvY29kZT4pLgotICAgICAqIEByZXR1cm4gVHJ1ZSBpZiBwcm9oaWJpdGVkIGlzIGEgcHJvaGliaXRlZCBzdWJzdGl0dXRpb24sIG90aGVyd2lzZQotICAgICAqICAgZmFsc2UuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNQcm9oaWJpdGVkU3Vic3RpdHV0aW9uKHNob3J0IHByb2hpYml0ZWQpIHsKLSAgICAgICAgcmV0dXJuIChmQmxvY2sgJiBwcm9oaWJpdGVkKSAhPSAwOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIHtwcm9oaWJpdGVkIHN1YnN0aXR1dGlvbnN9Ci0gICAgICoKLSAgICAgKiBAcmV0dXJuIEEgYml0IGZsYWcgY29ycmVzcG9uZGluZyB0byBwcm9oaWJpdGVkIHN1YnN0aXR1dGlvbnMKLSAgICAgKi8KLSAgICBwdWJsaWMgc2hvcnQgZ2V0UHJvaGliaXRlZFN1YnN0aXR1dGlvbnMoKSB7Ci0gICAgICAgIHJldHVybiBmQmxvY2s7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogT3B0aW9uYWwuIEFubm90YXRpb24uCi0gICAgICovCi0gICAgcHVibGljIFhTT2JqZWN0TGlzdCBnZXRBbm5vdGF0aW9ucygpIHsKLSAgICAgICAgcmV0dXJuIChmQW5ub3RhdGlvbnMgIT0gbnVsbCkgPyBmQW5ub3RhdGlvbnMgOiBYU09iamVjdExpc3RJbXBsLkVNUFRZX0xJU1Q7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBvcmcuYXBhY2hlLnhlcmNlcy54cy5YU09iamVjdCNnZXROYW1lc3BhY2VJdGVtKCkKLSAgICAgKi8KLSAgICBwdWJsaWMgWFNOYW1lc3BhY2VJdGVtIGdldE5hbWVzcGFjZUl0ZW0oKSB7Ci0gICAgICAgIHJldHVybiBmTmFtZXNwYWNlSXRlbTsKLSAgICB9Ci0KLSAgICB2b2lkIHNldE5hbWVzcGFjZUl0ZW0oWFNOYW1lc3BhY2VJdGVtIG5hbWVzcGFjZUl0ZW0pIHsKLSAgICAgICAgZk5hbWVzcGFjZUl0ZW0gPSBuYW1lc3BhY2VJdGVtOwotICAgIH0KLQotICAgIC8qIChub24tSmF2YWRvYykKLSAgICAgKiBAc2VlIG9yZy5hcGFjaGUueGVyY2VzLnhzLlhTQ29tcGxleFR5cGVEZWZpbml0aW9uI2dldEF0dHJpYnV0ZVVzZShqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyBYU0F0dHJpYnV0ZVVzZSBnZXRBdHRyaWJ1dGVVc2UoU3RyaW5nIG5hbWVzcGFjZSwgU3RyaW5nIG5hbWUpIHsKLSAgICAgICAgIHJldHVybiBmQXR0ckdycC5nZXRBdHRyaWJ1dGVVc2UobmFtZXNwYWNlLCBuYW1lKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldFR5cGVOYW1lc3BhY2UoKSB7Ci0gICAgICAgIHJldHVybiBnZXROYW1lc3BhY2UoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0Rlcml2ZWRGcm9tKFN0cmluZyB0eXBlTmFtZXNwYWNlQXJnLCBTdHJpbmcgdHlwZU5hbWVBcmcsIGludCBkZXJpdmF0aW9uTWV0aG9kKSB7Ci0gICAgICAgIHJldHVybiBpc0RPTURlcml2ZWRGcm9tKHR5cGVOYW1lc3BhY2VBcmcsIHR5cGVOYW1lQXJnLCBkZXJpdmF0aW9uTWV0aG9kKTsKLSAgICB9Ci0KLX0gLy8gY2xhc3MgWFNDb21wbGV4VHlwZURlY2wKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvWFNDb25zdHJhaW50cy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9YU0NvbnN0cmFpbnRzLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGM1NmFkMGQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9YU0NvbnN0cmFpbnRzLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNTMzICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzOwotCi1pbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOwotaW1wb3J0IGphdmEudXRpbC5Db21wYXJhdG9yOwotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuWE1MRXJyb3JSZXBvcnRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYuSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LlZhbGlkYXRlZEluZm87Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LlZhbGlkYXRpb25Db250ZXh0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5YU1NpbXBsZVR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLm1vZGVscy5DTUJ1aWxkZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLm1vZGVscy5YU0NNVmFsaWRhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy51dGlsLlNpbXBsZUxvY2F0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLnV0aWwuWFNPYmplY3RMaXN0SW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuU3ltYm9sSGFzaDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNPYmplY3RMaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNUeXBlRGVmaW5pdGlvbjsKLQotLyoqCi0gKiBDb25zdGFpbnRzIHNoYXJlZCBieSB0cmF2ZXJzZXJzIGFuZCB2YWxpZGF0b3IKLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBTYW5keSBHYW8sIElCTQotICoKLSAqIEB2ZXJzaW9uICRJZDogWFNDb25zdHJhaW50cy5qYXZhLHYgMS43IDIwMTAtMTEtMDEgMDQ6Mzk6NTUgam9laHcgRXhwICQKLSAqLwotcHVibGljIGNsYXNzIFhTQ29uc3RyYWludHMgewotCi0gICAgLy8gSUhSOiBWaXNpdGVkIG9uIDIwMDYtMTEtMTcKLSAgICAvLyBBZGRlZCBhIGJvb2xlYW4gcmV0dXJuIHZhbHVlIHRvIHBhcnRpY2xlVmFsaWRSZXN0cmljdGlvbiAoaXQgd2FzIGEgdm9pZCBmdW5jdGlvbikKLSAgICAvLyB0byBoZWxwIHRoZSBjaGVja1JlY3Vyc2VMYXggdG8ga25vdyB3aGVuIGV4cGFuc2lvbiBoYXMgaGFwcGVuZWQgYW5kIG5vIG9yZGVyIGlzIHJlcXVpcmVkCi0gICAgLy8gKElIUkB4YnJsLm9yZykgKElnbmFjaW9ASGVybmFuZGV6LVJvcy5jb20pCi0KLSAgICBzdGF0aWMgZmluYWwgaW50IE9DQ1VSUkVOQ0VfVU5LTk9XTiA9IFNjaGVtYVN5bWJvbHMuT0NDVVJSRU5DRV9VTkJPVU5ERUQtMTsKLSAgICBzdGF0aWMgZmluYWwgWFNTaW1wbGVUeXBlIFNUUklOR19UWVBFID0gKFhTU2ltcGxlVHlwZSlTY2hlbWFHcmFtbWFyLlNHX1NjaGVtYU5TLmdldEdsb2JhbFR5cGVEZWNsKFNjaGVtYVN5bWJvbHMuQVRUVkFMX1NUUklORyk7Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBYU1BhcnRpY2xlRGVjbCBmRW1wdHlQYXJ0aWNsZSA9IG51bGw7Ci0gICAgcHVibGljIHN0YXRpYyBYU1BhcnRpY2xlRGVjbCBnZXRFbXB0eVNlcXVlbmNlKCkgewotICAgICAgICBpZiAoZkVtcHR5UGFydGljbGUgPT0gbnVsbCkgewotICAgICAgICAgICAgWFNNb2RlbEdyb3VwSW1wbCBncm91cCA9IG5ldyBYU01vZGVsR3JvdXBJbXBsKCk7Ci0gICAgICAgICAgICBncm91cC5mQ29tcG9zaXRvciA9IFhTTW9kZWxHcm91cEltcGwuTU9ERUxHUk9VUF9TRVFVRU5DRTsKLSAgICAgICAgICAgIGdyb3VwLmZQYXJ0aWNsZUNvdW50ID0gMDsKLSAgICAgICAgICAgIGdyb3VwLmZQYXJ0aWNsZXMgPSBudWxsOwotICAgICAgICAgICAgZ3JvdXAuZkFubm90YXRpb25zID0gWFNPYmplY3RMaXN0SW1wbC5FTVBUWV9MSVNUOwotICAgICAgICAgICAgWFNQYXJ0aWNsZURlY2wgcGFydGljbGUgPSBuZXcgWFNQYXJ0aWNsZURlY2woKTsKLSAgICAgICAgICAgIHBhcnRpY2xlLmZUeXBlID0gWFNQYXJ0aWNsZURlY2wuUEFSVElDTEVfTU9ERUxHUk9VUDsKLSAgICAgICAgICAgIHBhcnRpY2xlLmZWYWx1ZSA9IGdyb3VwOwotICAgICAgICAgICAgcGFydGljbGUuZkFubm90YXRpb25zID0gWFNPYmplY3RMaXN0SW1wbC5FTVBUWV9MSVNUOwotICAgICAgICAgICAgZkVtcHR5UGFydGljbGUgPSBwYXJ0aWNsZTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZkVtcHR5UGFydGljbGU7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQ29tcGFyYXRvciBFTEVNRU5UX1BBUlRJQ0xFX0NPTVBBUkFUT1IgPSBuZXcgQ29tcGFyYXRvcigpIHsKLQotICAgICAgICBwdWJsaWMgaW50IGNvbXBhcmUoT2JqZWN0IG8xLCBPYmplY3QgbzIpIHsKLSAgICAgICAgICAgIFhTUGFydGljbGVEZWNsIHBEZWNsMSA9IChYU1BhcnRpY2xlRGVjbCkgbzE7Ci0gICAgICAgICAgICBYU1BhcnRpY2xlRGVjbCBwRGVjbDIgPSAoWFNQYXJ0aWNsZURlY2wpIG8yOwotICAgICAgICAgICAgWFNFbGVtZW50RGVjbCBkZWNsMSA9IChYU0VsZW1lbnREZWNsKSBwRGVjbDEuZlZhbHVlOwotICAgICAgICAgICAgWFNFbGVtZW50RGVjbCBkZWNsMiA9IChYU0VsZW1lbnREZWNsKSBwRGVjbDIuZlZhbHVlOwotCi0gICAgICAgICAgICBTdHJpbmcgbmFtZXNwYWNlMSA9IGRlY2wxLmdldE5hbWVzcGFjZSgpOwotICAgICAgICAgICAgU3RyaW5nIG5hbWVzcGFjZTIgPSBkZWNsMi5nZXROYW1lc3BhY2UoKTsKLSAgICAgICAgICAgIFN0cmluZyBuYW1lMSA9IGRlY2wxLmdldE5hbWUoKTsKLSAgICAgICAgICAgIFN0cmluZyBuYW1lMiA9IGRlY2wyLmdldE5hbWUoKTsKLQotICAgICAgICAgICAgYm9vbGVhbiBzYW1lTmFtZXNwYWNlID0gKG5hbWVzcGFjZTEgPT0gbmFtZXNwYWNlMik7Ci0gICAgICAgICAgICBpbnQgbmFtZXNwYWNlQ29tcGFyaXNvbiA9IDA7Ci0KLSAgICAgICAgICAgIGlmICghc2FtZU5hbWVzcGFjZSkgewotICAgICAgICAgICAgICAgIGlmIChuYW1lc3BhY2UxICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKG5hbWVzcGFjZTIgIT0gbnVsbCl7Ci0gICAgICAgICAgICAgICAgICAgICAgICBuYW1lc3BhY2VDb21wYXJpc29uID0gbmFtZXNwYWNlMS5jb21wYXJlVG8obmFtZXNwYWNlMik7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBuYW1lc3BhY2VDb21wYXJpc29uID0gMTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgbmFtZXNwYWNlQ29tcGFyaXNvbiA9IC0xOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vVGhpcyBhc3N1bWVzIHRoYXQgdGhlIG5hbWVzIGFyZSBuZXZlciBudWxsLgotICAgICAgICAgICAgcmV0dXJuIG5hbWVzcGFjZUNvbXBhcmlzb24gIT0gMCA/IG5hbWVzcGFjZUNvbXBhcmlzb24gOiBuYW1lMS5jb21wYXJlVG8obmFtZTIpOwotICAgICAgICB9Ci0gICAgfTsKLQotICAgIC8qKgotICAgICAqIGNoZWNrIHdoZXRoZXIgZGVyaXZlZCBpcyB2YWxpZCBkZXJpdmVkIGZyb20gYmFzZSwgZ2l2ZW4gYSBzdWJzZXQKLSAgICAgKiBvZiB7cmVzdHJpY3Rpb24sIGV4dGVuc2lvbn0uQgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBjaGVja1R5cGVEZXJpdmF0aW9uT2soWFNUeXBlRGVmaW5pdGlvbiBkZXJpdmVkLCBYU1R5cGVEZWZpbml0aW9uIGJhc2UsIHNob3J0IGJsb2NrKSB7Ci0gICAgICAgIC8vIGlmIGRlcml2ZWQgaXMgYW55VHlwZSwgdGhlbiBpdCdzIHZhbGlkIG9ubHkgaWYgYmFzZSBpcyBhbnlUeXBlIHRvbwotICAgICAgICBpZiAoZGVyaXZlZCA9PSBTY2hlbWFHcmFtbWFyLmZBbnlUeXBlKQotICAgICAgICAgICAgcmV0dXJuIGRlcml2ZWQgPT0gYmFzZTsKLSAgICAgICAgLy8gaWYgZGVyaXZlZCBpcyBhbnlTaW1wbGVUeXBlLCB0aGVuIGl0J3MgdmFsaWQgb25seSBpZiB0aGUgYmFzZQotICAgICAgICAvLyBpcyB1ci10eXBlCi0gICAgICAgIGlmIChkZXJpdmVkID09IFNjaGVtYUdyYW1tYXIuZkFueVNpbXBsZVR5cGUpIHsKLSAgICAgICAgICAgIHJldHVybiAoYmFzZSA9PSBTY2hlbWFHcmFtbWFyLmZBbnlUeXBlIHx8Ci0gICAgICAgICAgICAgICAgICAgIGJhc2UgPT0gU2NoZW1hR3JhbW1hci5mQW55U2ltcGxlVHlwZSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBpZiBkZXJpdmVkIGlzIHNpbXBsZSB0eXBlCi0gICAgICAgIGlmIChkZXJpdmVkLmdldFR5cGVDYXRlZ29yeSgpID09IFhTVHlwZURlZmluaXRpb24uU0lNUExFX1RZUEUpIHsKLSAgICAgICAgICAgIC8vIGlmIGJhc2UgaXMgY29tcGxleCB0eXBlCi0gICAgICAgICAgICBpZiAoYmFzZS5nZXRUeXBlQ2F0ZWdvcnkoKSA9PSBYU1R5cGVEZWZpbml0aW9uLkNPTVBMRVhfVFlQRSkgewotICAgICAgICAgICAgICAgIC8vIGlmIGJhc2UgaXMgYW55VHlwZSwgY2hhbmdlIGJhc2UgdG8gYW55U2ltcGxlVHlwZSwKLSAgICAgICAgICAgICAgICAvLyBvdGhlcndpc2UsIG5vdCB2YWxpZAotICAgICAgICAgICAgICAgIGlmIChiYXNlID09IFNjaGVtYUdyYW1tYXIuZkFueVR5cGUpCi0gICAgICAgICAgICAgICAgICAgIGJhc2UgPSBTY2hlbWFHcmFtbWFyLmZBbnlTaW1wbGVUeXBlOwotICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIGNoZWNrU2ltcGxlRGVyaXZhdGlvbigoWFNTaW1wbGVUeXBlKWRlcml2ZWQsCi0gICAgICAgICAgICAgICAgICAgIChYU1NpbXBsZVR5cGUpYmFzZSwgYmxvY2spOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIGNoZWNrQ29tcGxleERlcml2YXRpb24oKFhTQ29tcGxleFR5cGVEZWNsKWRlcml2ZWQsIGJhc2UsIGJsb2NrKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIGNoZWNrIHdoZXRoZXIgc2ltcGxlIHR5cGUgZGVyaXZlZCBpcyB2YWxpZCBkZXJpdmVkIGZyb20gYmFzZSwKLSAgICAgKiBnaXZlbiBhIHN1YnNldCBvZiB7cmVzdHJpY3Rpb24sIGV4dGVuc2lvbn0uCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBib29sZWFuIGNoZWNrU2ltcGxlRGVyaXZhdGlvbk9rKFhTU2ltcGxlVHlwZSBkZXJpdmVkLCBYU1R5cGVEZWZpbml0aW9uIGJhc2UsIHNob3J0IGJsb2NrKSB7Ci0gICAgICAgIC8vIGlmIGRlcml2ZWQgaXMgYW55U2ltcGxlVHlwZSwgdGhlbiBpdCdzIHZhbGlkIG9ubHkgaWYgdGhlIGJhc2UKLSAgICAgICAgLy8gaXMgdXItdHlwZQotICAgICAgICBpZiAoZGVyaXZlZCA9PSBTY2hlbWFHcmFtbWFyLmZBbnlTaW1wbGVUeXBlKSB7Ci0gICAgICAgICAgICByZXR1cm4gKGJhc2UgPT0gU2NoZW1hR3JhbW1hci5mQW55VHlwZSB8fAotICAgICAgICAgICAgICAgICAgICBiYXNlID09IFNjaGVtYUdyYW1tYXIuZkFueVNpbXBsZVR5cGUpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gaWYgYmFzZSBpcyBjb21wbGV4IHR5cGUKLSAgICAgICAgaWYgKGJhc2UuZ2V0VHlwZUNhdGVnb3J5KCkgPT0gWFNUeXBlRGVmaW5pdGlvbi5DT01QTEVYX1RZUEUpIHsKLSAgICAgICAgICAgIC8vIGlmIGJhc2UgaXMgYW55VHlwZSwgY2hhbmdlIGJhc2UgdG8gYW55U2ltcGxlVHlwZSwKLSAgICAgICAgICAgIC8vIG90aGVyd2lzZSwgbm90IHZhbGlkCi0gICAgICAgICAgICBpZiAoYmFzZSA9PSBTY2hlbWFHcmFtbWFyLmZBbnlUeXBlKQotICAgICAgICAgICAgICAgIGJhc2UgPSBTY2hlbWFHcmFtbWFyLmZBbnlTaW1wbGVUeXBlOwotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gY2hlY2tTaW1wbGVEZXJpdmF0aW9uKChYU1NpbXBsZVR5cGUpZGVyaXZlZCwKLSAgICAgICAgICAgICAgICAoWFNTaW1wbGVUeXBlKWJhc2UsIGJsb2NrKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBjaGVjayB3aGV0aGVyIGNvbXBsZXggdHlwZSBkZXJpdmVkIGlzIHZhbGlkIGRlcml2ZWQgZnJvbSBiYXNlLAotICAgICAqIGdpdmVuIGEgc3Vic2V0IG9mIHtyZXN0cmljdGlvbiwgZXh0ZW5zaW9ufS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gY2hlY2tDb21wbGV4RGVyaXZhdGlvbk9rKFhTQ29tcGxleFR5cGVEZWNsIGRlcml2ZWQsIFhTVHlwZURlZmluaXRpb24gYmFzZSwgc2hvcnQgYmxvY2spIHsKLSAgICAgICAgLy8gaWYgZGVyaXZlZCBpcyBhbnlUeXBlLCB0aGVuIGl0J3MgdmFsaWQgb25seSBpZiBiYXNlIGlzIGFueVR5cGUgdG9vCi0gICAgICAgIGlmIChkZXJpdmVkID09IFNjaGVtYUdyYW1tYXIuZkFueVR5cGUpCi0gICAgICAgICAgICByZXR1cm4gZGVyaXZlZCA9PSBiYXNlOwotICAgICAgICByZXR1cm4gY2hlY2tDb21wbGV4RGVyaXZhdGlvbigoWFNDb21wbGV4VHlwZURlY2wpZGVyaXZlZCwgYmFzZSwgYmxvY2spOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIE5vdGU6IHRoaXMgd2lsbCBiZSBhIHByaXZhdGUgbWV0aG9kLCBhbmQgaXQgYXNzdW1lcyB0aGF0IGRlcml2ZWQgaXMgbm90Ci0gICAgICogICAgICAgYW55U2ltcGxlVHlwZSwgYW5kIGJhc2UgaXMgbm90IGFueVR5cGUuIEFub3RoZXIgbWV0aG9kIHdpbGwgYmUKLSAgICAgKiAgICAgICBpbnRyb2R1Y2VkIGZvciBwdWJsaWMgdXNlLCB3aGljaCB3aWxsIGNhbGwgdGhpcyBtZXRob2QuCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBjaGVja1NpbXBsZURlcml2YXRpb24oWFNTaW1wbGVUeXBlIGRlcml2ZWQsIFhTU2ltcGxlVHlwZSBiYXNlLCBzaG9ydCBibG9jaykgewotICAgICAgICAvLyAxIFRoZXkgYXJlIHRoZSBzYW1lIHR5cGUgZGVmaW5pdGlvbi4KLSAgICAgICAgaWYgKGRlcml2ZWQgPT0gYmFzZSkKLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotCi0gICAgICAgIC8vIDIgQWxsIG9mIHRoZSBmb2xsb3dpbmcgbXVzdCBiZSB0cnVlOgotICAgICAgICAvLyAyLjEgcmVzdHJpY3Rpb24gaXMgbm90IGluIHRoZSBzdWJzZXQsIG9yIGluIHRoZSB7ZmluYWx9IG9mIGl0cyBvd24ge2Jhc2UgdHlwZSBkZWZpbml0aW9ufTsKLSAgICAgICAgaWYgKChibG9jayAmIFhTQ29uc3RhbnRzLkRFUklWQVRJT05fUkVTVFJJQ1RJT04pICE9IDAgfHwKLSAgICAgICAgICAgICAgICAoZGVyaXZlZC5nZXRCYXNlVHlwZSgpLmdldEZpbmFsKCkgJiBYU0NvbnN0YW50cy5ERVJJVkFUSU9OX1JFU1RSSUNUSU9OKSAhPSAwKSB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyAyLjIgT25lIG9mIHRoZSBmb2xsb3dpbmcgbXVzdCBiZSB0cnVlOgotICAgICAgICAvLyAyLjIuMSBEJ3MgYmFzZSB0eXBlIGRlZmluaXRpb24gaXMgQi4KLSAgICAgICAgWFNTaW1wbGVUeXBlIGRpcmVjdEJhc2UgPSAoWFNTaW1wbGVUeXBlKWRlcml2ZWQuZ2V0QmFzZVR5cGUoKTsKLSAgICAgICAgaWYgKGRpcmVjdEJhc2UgPT0gYmFzZSkKLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotCi0gICAgICAgIC8vIDIuMi4yIEQncyBiYXNlIHR5cGUgZGVmaW5pdGlvbiBpcyBub3QgdGhlIHNpbXBsZSB1ci10eXBlIGRlZmluaXRpb24gYW5kIGlzIHZhbGlkbHkgZGVyaXZlZCBmcm9tIEIgZ2l2ZW4gdGhlIHN1YnNldCwgYXMgZGVmaW5lZCBieSB0aGlzIGNvbnN0cmFpbnQuCi0gICAgICAgIGlmIChkaXJlY3RCYXNlICE9IFNjaGVtYUdyYW1tYXIuZkFueVNpbXBsZVR5cGUgJiYKLSAgICAgICAgICAgICAgICBjaGVja1NpbXBsZURlcml2YXRpb24oZGlyZWN0QmFzZSwgYmFzZSwgYmxvY2spKSB7Ci0gICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIDIuMi4zIEQncyB7dmFyaWV0eX0gaXMgbGlzdCBvciB1bmlvbiBhbmQgQiBpcyB0aGUgc2ltcGxlIHVyLXR5cGUgZGVmaW5pdGlvbi4KLSAgICAgICAgaWYgKChkZXJpdmVkLmdldFZhcmlldHkoKSA9PSBYU1NpbXBsZVR5cGUuVkFSSUVUWV9MSVNUIHx8Ci0gICAgICAgICAgICAgICAgZGVyaXZlZC5nZXRWYXJpZXR5KCkgPT0gWFNTaW1wbGVUeXBlLlZBUklFVFlfVU5JT04pICYmCi0gICAgICAgICAgICAgICAgYmFzZSA9PSBTY2hlbWFHcmFtbWFyLmZBbnlTaW1wbGVUeXBlKSB7Ci0gICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIDIuMi40IEIncyB7dmFyaWV0eX0gaXMgdW5pb24gYW5kIEQgaXMgdmFsaWRseSBkZXJpdmVkIGZyb20gYSB0eXBlIGRlZmluaXRpb24gaW4gQidzIHttZW1iZXIgdHlwZSBkZWZpbml0aW9uc30gZ2l2ZW4gdGhlIHN1YnNldCwgYXMgZGVmaW5lZCBieSB0aGlzIGNvbnN0cmFpbnQuCi0gICAgICAgIGlmIChiYXNlLmdldFZhcmlldHkoKSA9PSBYU1NpbXBsZVR5cGUuVkFSSUVUWV9VTklPTikgewotICAgICAgICAgICAgWFNPYmplY3RMaXN0IHN1YlVuaW9uTWVtYmVyRFYgPSBiYXNlLmdldE1lbWJlclR5cGVzKCk7Ci0gICAgICAgICAgICBpbnQgc3ViVW5pb25TaXplID0gc3ViVW5pb25NZW1iZXJEVi5nZXRMZW5ndGgoKTsKLSAgICAgICAgICAgIGZvciAoaW50IGk9MDsgaTxzdWJVbmlvblNpemU7IGkrKykgewotICAgICAgICAgICAgICAgIGJhc2UgPSAoWFNTaW1wbGVUeXBlKXN1YlVuaW9uTWVtYmVyRFYuaXRlbShpKTsKLSAgICAgICAgICAgICAgICBpZiAoY2hlY2tTaW1wbGVEZXJpdmF0aW9uKGRlcml2ZWQsIGJhc2UsIGJsb2NrKSkKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogTm90ZTogdGhpcyB3aWxsIGJlIGEgcHJpdmF0ZSBtZXRob2QsIGFuZCBpdCBhc3N1bWVzIHRoYXQgZGVyaXZlZCBpcyBub3QKLSAgICAgKiAgICAgICBhbnlUeXBlLiBBbm90aGVyIG1ldGhvZCB3aWxsIGJlIGludHJvZHVjZWQgZm9yIHB1YmxpYyB1c2UsCi0gICAgICogICAgICAgd2hpY2ggd2lsbCBjYWxsIHRoaXMgbWV0aG9kLgotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gY2hlY2tDb21wbGV4RGVyaXZhdGlvbihYU0NvbXBsZXhUeXBlRGVjbCBkZXJpdmVkLCBYU1R5cGVEZWZpbml0aW9uIGJhc2UsIHNob3J0IGJsb2NrKSB7Ci0gICAgICAgIC8vIDIuMSBCIGFuZCBEIG11c3QgYmUgdGhlIHNhbWUgdHlwZSBkZWZpbml0aW9uLgotICAgICAgICBpZiAoZGVyaXZlZCA9PSBiYXNlKQotICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0KLSAgICAgICAgLy8gMSBJZiBCIGFuZCBEIGFyZSBub3QgdGhlIHNhbWUgdHlwZSBkZWZpbml0aW9uLCB0aGVuIHRoZSB7ZGVyaXZhdGlvbiBtZXRob2R9IG9mIEQgbXVzdCBub3QgYmUgaW4gdGhlIHN1YnNldC4KLSAgICAgICAgaWYgKChkZXJpdmVkLmZEZXJpdmVkQnkgJiBibG9jaykgIT0gMCkKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLQotICAgICAgICAvLyAyIE9uZSBvZiB0aGUgZm9sbG93aW5nIG11c3QgYmUgdHJ1ZToKLSAgICAgICAgWFNUeXBlRGVmaW5pdGlvbiBkaXJlY3RCYXNlID0gZGVyaXZlZC5mQmFzZVR5cGU7Ci0gICAgICAgIC8vIDIuMiBCIG11c3QgYmUgRCdzIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0uCi0gICAgICAgIGlmIChkaXJlY3RCYXNlID09IGJhc2UpCi0gICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLQotICAgICAgICAvLyAyLjMgQWxsIG9mIHRoZSBmb2xsb3dpbmcgbXVzdCBiZSB0cnVlOgotICAgICAgICAvLyAyLjMuMSBEJ3Mge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSBtdXN0IG5vdCBiZSB0aGUgdXItdHlwZSBkZWZpbml0aW9uLgotICAgICAgICBpZiAoZGlyZWN0QmFzZSA9PSBTY2hlbWFHcmFtbWFyLmZBbnlUeXBlIHx8Ci0gICAgICAgICAgICAgICAgZGlyZWN0QmFzZSA9PSBTY2hlbWFHcmFtbWFyLmZBbnlTaW1wbGVUeXBlKSB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyAyLjMuMiBUaGUgYXBwcm9wcmlhdGUgY2FzZSBhbW9uZyB0aGUgZm9sbG93aW5nIG11c3QgYmUgdHJ1ZToKLSAgICAgICAgLy8gMi4zLjIuMSBJZiBEJ3Mge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSBpcyBjb21wbGV4LCB0aGVuIGl0IG11c3QgYmUgdmFsaWRseSBkZXJpdmVkIGZyb20gQiBnaXZlbiB0aGUgc3Vic2V0IGFzIGRlZmluZWQgYnkgdGhpcyBjb25zdHJhaW50LgotICAgICAgICBpZiAoZGlyZWN0QmFzZS5nZXRUeXBlQ2F0ZWdvcnkoKSA9PSBYU1R5cGVEZWZpbml0aW9uLkNPTVBMRVhfVFlQRSkKLSAgICAgICAgICAgIHJldHVybiBjaGVja0NvbXBsZXhEZXJpdmF0aW9uKChYU0NvbXBsZXhUeXBlRGVjbClkaXJlY3RCYXNlLCBiYXNlLCBibG9jayk7Ci0KLSAgICAgICAgLy8gMi4zLjIuMiBJZiBEJ3Mge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSBpcyBzaW1wbGUsIHRoZW4gaXQgbXVzdCBiZSB2YWxpZGx5IGRlcml2ZWQgZnJvbSBCIGdpdmVuIHRoZSBzdWJzZXQgYXMgZGVmaW5lZCBpbiBUeXBlIERlcml2YXRpb24gT0sgKFNpbXBsZSkgKDMuMTQuNikuCi0gICAgICAgIGlmIChkaXJlY3RCYXNlLmdldFR5cGVDYXRlZ29yeSgpID09IFhTVHlwZURlZmluaXRpb24uU0lNUExFX1RZUEUpIHsKLSAgICAgICAgICAgIC8vIGlmIGJhc2UgaXMgY29tcGxleCB0eXBlCi0gICAgICAgICAgICBpZiAoYmFzZS5nZXRUeXBlQ2F0ZWdvcnkoKSA9PSBYU1R5cGVEZWZpbml0aW9uLkNPTVBMRVhfVFlQRSkgewotICAgICAgICAgICAgICAgIC8vIGlmIGJhc2UgaXMgYW55VHlwZSwgY2hhbmdlIGJhc2UgdG8gYW55U2ltcGxlVHlwZSwKLSAgICAgICAgICAgICAgICAvLyBvdGhlcndpc2UsIG5vdCB2YWxpZAotICAgICAgICAgICAgICAgIGlmIChiYXNlID09IFNjaGVtYUdyYW1tYXIuZkFueVR5cGUpCi0gICAgICAgICAgICAgICAgICAgIGJhc2UgPSBTY2hlbWFHcmFtbWFyLmZBbnlTaW1wbGVUeXBlOwotICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIGNoZWNrU2ltcGxlRGVyaXZhdGlvbigoWFNTaW1wbGVUeXBlKWRpcmVjdEJhc2UsCi0gICAgICAgICAgICAgICAgICAgIChYU1NpbXBsZVR5cGUpYmFzZSwgYmxvY2spOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIGNoZWNrIHdoZXRoZXIgYSB2YWx1ZSBpcyBhIHZhbGlkIGRlZmF1bHQgZm9yIHNvbWUgdHlwZQotICAgICAqIHJldHVybnMgdGhlIGNvbXBpbGVkIGZvcm0gb2YgdGhlIHZhbHVlCi0gICAgICogVGhlIHBhcmFtZXRlciB2YWx1ZSBjb3VsZCBiZSBlaXRoZXIgYSBTdHJpbmcgb3IgYSBWYWxpZGF0ZWRJbmZvIG9iamVjdAotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgT2JqZWN0IEVsZW1lbnREZWZhdWx0VmFsaWRJbW1lZGlhdGUoWFNUeXBlRGVmaW5pdGlvbiB0eXBlLCBTdHJpbmcgdmFsdWUsIFZhbGlkYXRpb25Db250ZXh0IGNvbnRleHQsIFZhbGlkYXRlZEluZm8gdmluZm8pIHsKLQotICAgICAgICBYU1NpbXBsZVR5cGUgZHYgPSBudWxsOwotCi0gICAgICAgIC8vIGUtcHJvcHMtY29ycmVjdAotICAgICAgICAvLyBGb3IgYSBzdHJpbmcgdG8gYmUgYSB2YWxpZCBkZWZhdWx0IHdpdGggcmVzcGVjdCB0byBhIHR5cGUgZGVmaW5pdGlvbiB0aGUgYXBwcm9wcmlhdGUgY2FzZSBhbW9uZyB0aGUgZm9sbG93aW5nIG11c3QgYmUgdHJ1ZToKLSAgICAgICAgLy8gMSBJZiB0aGUgdHlwZSBkZWZpbml0aW9uIGlzIGEgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiwgdGhlbiB0aGUgc3RyaW5nIG11c3QgYmUgdmFsaWQgd2l0aCByZXNwZWN0IHRvIHRoYXQgZGVmaW5pdGlvbiBhcyBkZWZpbmVkIGJ5IFN0cmluZyBWYWxpZCAoMy4xNC40KS4KLSAgICAgICAgaWYgKHR5cGUuZ2V0VHlwZUNhdGVnb3J5KCkgPT0gWFNUeXBlRGVmaW5pdGlvbi5TSU1QTEVfVFlQRSkgewotICAgICAgICAgICAgZHYgPSAoWFNTaW1wbGVUeXBlKXR5cGU7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyAyIElmIHRoZSB0eXBlIGRlZmluaXRpb24gaXMgYSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbiwgdGhlbiBhbGwgb2YgdGhlIGZvbGxvd2luZyBtdXN0IGJlIHRydWU6Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgLy8gMi4xIGl0cyB7Y29udGVudCB0eXBlfSBtdXN0IGJlIGEgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiBvciBtaXhlZC4KLSAgICAgICAgICAgIFhTQ29tcGxleFR5cGVEZWNsIGN0eXBlID0gKFhTQ29tcGxleFR5cGVEZWNsKXR5cGU7Ci0gICAgICAgICAgICAvLyAyLjIgVGhlIGFwcHJvcHJpYXRlIGNhc2UgYW1vbmcgdGhlIGZvbGxvd2luZyBtdXN0IGJlIHRydWU6Ci0gICAgICAgICAgICAvLyAyLjIuMSBJZiB0aGUge2NvbnRlbnQgdHlwZX0gaXMgYSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uLCB0aGVuIHRoZSBzdHJpbmcgbXVzdCBiZSB2YWxpZCB3aXRoIHJlc3BlY3QgdG8gdGhhdCBzaW1wbGUgdHlwZSBkZWZpbml0aW9uIGFzIGRlZmluZWQgYnkgU3RyaW5nIFZhbGlkICgzLjE0LjQpLgotICAgICAgICAgICAgaWYgKGN0eXBlLmZDb250ZW50VHlwZSA9PSBYU0NvbXBsZXhUeXBlRGVjbC5DT05URU5UVFlQRV9TSU1QTEUpIHsKLSAgICAgICAgICAgICAgICBkdiA9IGN0eXBlLmZYU1NpbXBsZVR5cGU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyAyLjIuMiBJZiB0aGUge2NvbnRlbnQgdHlwZX0gaXMgbWl4ZWQsIHRoZW4gdGhlIHtjb250ZW50IHR5cGV9J3MgcGFydGljbGUgbXVzdCBiZSBlbXB0aWFibGUgYXMgZGVmaW5lZCBieSBQYXJ0aWNsZSBFbXB0aWFibGUgKDMuOS42KS4KLSAgICAgICAgICAgIGVsc2UgaWYgKGN0eXBlLmZDb250ZW50VHlwZSA9PSBYU0NvbXBsZXhUeXBlRGVjbC5DT05URU5UVFlQRV9NSVhFRCkgewotICAgICAgICAgICAgICAgIGlmICghKChYU1BhcnRpY2xlRGVjbCljdHlwZS5nZXRQYXJ0aWNsZSgpKS5lbXB0aWFibGUoKSkKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIGdldCB0aGUgc2ltcGxlIHR5cGUgZGVjbGFyYXRpb24sIGFuZCB2YWxpZGF0ZQotICAgICAgICBPYmplY3QgYWN0dWFsVmFsdWUgPSBudWxsOwotICAgICAgICBpZiAoZHYgPT0gbnVsbCkgewotICAgICAgICAgICAgLy8gY29tcGxleCB0eXBlIHdpdGggbWl4ZWQuIHRvIG1ha2Ugc3VyZSB0aGF0IHdlIHN0b3JlIGNvcnJlY3QKLSAgICAgICAgICAgIC8vIGluZm9ybWF0aW9uIGluIHZpbmZvIGFuZCByZXR1cm4gdGhlIGNvcnJlY3QgdmFsdWUsIHdlIHVzZQotICAgICAgICAgICAgLy8gInN0cmluZyIgdHlwZSBmb3IgdmFsaWRhdGlvbgotICAgICAgICAgICAgZHYgPSBTVFJJTkdfVFlQRTsKLSAgICAgICAgfQotICAgICAgICB0cnkgewotICAgICAgICAgICAgLy8gdmFsaWRhdGUgdGhlIG9yaWdpbmFsIGxleGljYWwgcmVwLCBhbmQgc2V0IHRoZSBhY3R1YWwgdmFsdWUKLSAgICAgICAgICAgIGFjdHVhbFZhbHVlID0gZHYudmFsaWRhdGUodmFsdWUsIGNvbnRleHQsIHZpbmZvKTsKLSAgICAgICAgICAgIC8vIHZhbGlkYXRlIHRoZSBjYW5vbmljYWwgbGV4aWNhbCByZXAKLSAgICAgICAgICAgIGlmICh2aW5mbyAhPSBudWxsKQotICAgICAgICAgICAgICAgIGFjdHVhbFZhbHVlID0gZHYudmFsaWRhdGUodmluZm8uc3RyaW5nVmFsdWUoKSwgY29udGV4dCwgdmluZm8pOwotICAgICAgICB9IGNhdGNoIChJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbiBpZGUpIHsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIGFjdHVhbFZhbHVlOwotICAgIH0KLQotICAgIHN0YXRpYyB2b2lkIHJlcG9ydFNjaGVtYUVycm9yKFhNTEVycm9yUmVwb3J0ZXIgZXJyb3JSZXBvcnRlciwKLSAgICAgICAgICAgIFNpbXBsZUxvY2F0b3IgbG9jLAotICAgICAgICAgICAgU3RyaW5nIGtleSwgT2JqZWN0W10gYXJncykgewotICAgICAgICBpZiAobG9jICE9IG51bGwpIHsKLSAgICAgICAgICAgIGVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IobG9jLCBYU01lc3NhZ2VGb3JtYXR0ZXIuU0NIRU1BX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAga2V5LCBhcmdzLCBYTUxFcnJvclJlcG9ydGVyLlNFVkVSSVRZX0VSUk9SKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIGVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IoWFNNZXNzYWdlRm9ybWF0dGVyLlNDSEVNQV9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgIGtleSwgYXJncywgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9FUlJPUik7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiB1c2VkIHRvIGNoZWNrIHRoZSAzIGNvbnN0cmFpbnRzIGFnYWluc3QgZWFjaCBjb21wbGV4IHR5cGUKLSAgICAgKiAoc2hvdWxkIGJlIGVhY2ggbW9kZWwgZ3JvdXApOgotICAgICAqIFVuaXF1ZSBQYXJ0aWNsZSBBdHRyaWJ1dGlvbiwgUGFydGljbGUgRGVyaXZhdGlvbiAoUmVzdHJpY3Rpb24pLAotICAgICAqIEVsZW1lbnQgRGVjbHJhdGlvbnMgQ29uc2lzdGVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIHZvaWQgZnVsbFNjaGVtYUNoZWNraW5nKFhTR3JhbW1hckJ1Y2tldCBncmFtbWFyQnVja2V0LAotICAgICAgICAgICAgU3Vic3RpdHV0aW9uR3JvdXBIYW5kbGVyIFNHSGFuZGxlciwKLSAgICAgICAgICAgIENNQnVpbGRlciBjbUJ1aWxkZXIsCi0gICAgICAgICAgICBYTUxFcnJvclJlcG9ydGVyIGVycm9yUmVwb3J0ZXIpIHsKLSAgICAgICAgLy8gZ2V0IGFsbCBncmFtbWFycywgYW5kIHB1dCBhbGwgc3Vic3RpdHV0aW9uIGdyb3VwIGluZm9ybWF0aW9uCi0gICAgICAgIC8vIGluIHRoZSBzdWJzdGl0dXRpb24gZ3JvdXAgaGFuZGxlcgotICAgICAgICBTY2hlbWFHcmFtbWFyW10gZ3JhbW1hcnMgPSBncmFtbWFyQnVja2V0LmdldEdyYW1tYXJzKCk7Ci0gICAgICAgIGZvciAoaW50IGkgPSBncmFtbWFycy5sZW5ndGgtMTsgaSA+PSAwOyBpLS0pIHsKLSAgICAgICAgICAgIFNHSGFuZGxlci5hZGRTdWJzdGl0dXRpb25Hcm91cChncmFtbWFyc1tpXS5nZXRTdWJzdGl0dXRpb25Hcm91cHMoKSk7Ci0gICAgICAgIH0KLQotICAgICAgICBYU1BhcnRpY2xlRGVjbCBmYWtlRGVyaXZlZCA9IG5ldyBYU1BhcnRpY2xlRGVjbCgpOwotICAgICAgICBYU1BhcnRpY2xlRGVjbCBmYWtlQmFzZSA9IG5ldyBYU1BhcnRpY2xlRGVjbCgpOwotICAgICAgICBmYWtlRGVyaXZlZC5mVHlwZSA9IFhTUGFydGljbGVEZWNsLlBBUlRJQ0xFX01PREVMR1JPVVA7Ci0gICAgICAgIGZha2VCYXNlLmZUeXBlID0gWFNQYXJ0aWNsZURlY2wuUEFSVElDTEVfTU9ERUxHUk9VUDsKLSAgICAgICAgLy8gYmVmb3JlIHdvcnJ5aW5nIGFib3V0IGNvbXBsZXhUeXBlcywgbGV0J3MgZ2V0Ci0gICAgICAgIC8vIGdyb3VwcyByZWRlZmluZWQgYnkgcmVzdHJpY3Rpb24gb3V0IG9mIHRoZSB3YXkuCi0gICAgICAgIGZvciAoaW50IGcgPSBncmFtbWFycy5sZW5ndGgtMTsgZyA+PSAwOyBnLS0pIHsKLSAgICAgICAgICAgIFhTR3JvdXBEZWNsIFtdIHJlZGVmaW5lZEdyb3VwcyA9IGdyYW1tYXJzW2ddLmdldFJlZGVmaW5lZEdyb3VwRGVjbHMoKTsKLSAgICAgICAgICAgIFNpbXBsZUxvY2F0b3IgW10gcmdMb2NhdG9ycyA9IGdyYW1tYXJzW2ddLmdldFJHTG9jYXRvcnMoKTsKLSAgICAgICAgICAgIGZvcihpbnQgaT0wOyBpPHJlZGVmaW5lZEdyb3Vwcy5sZW5ndGg7ICkgewotICAgICAgICAgICAgICAgIFhTR3JvdXBEZWNsIGRlcml2ZWRHcnAgPSByZWRlZmluZWRHcm91cHNbaSsrXTsKLSAgICAgICAgICAgICAgICBYU01vZGVsR3JvdXBJbXBsIGRlcml2ZWRNRyA9IGRlcml2ZWRHcnAuZk1vZGVsR3JvdXA7Ci0gICAgICAgICAgICAgICAgWFNHcm91cERlY2wgYmFzZUdycCA9IHJlZGVmaW5lZEdyb3Vwc1tpKytdOwotICAgICAgICAgICAgICAgIFhTTW9kZWxHcm91cEltcGwgYmFzZU1HID0gYmFzZUdycC5mTW9kZWxHcm91cDsKLSAgICAgICAgICAgICAgICBmYWtlRGVyaXZlZC5mVmFsdWUgPSBkZXJpdmVkTUc7Ci0gICAgICAgICAgICAgICAgZmFrZUJhc2UuZlZhbHVlID0gYmFzZU1HOwotICAgICAgICAgICAgICAgIGlmKGJhc2VNRyA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmKGRlcml2ZWRNRyAhPSBudWxsKSB7IC8vIGNhbid0IGJlIGEgcmVzdHJpY3Rpb24hCi0gICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcihlcnJvclJlcG9ydGVyLCByZ0xvY2F0b3JzW2kvMi0xXSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInNyYy1yZWRlZmluZS42LjIuMiIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXtkZXJpdmVkR3JwLmZOYW1lLCAicmNhc2UtUmVjdXJzZS4yIn0pOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChkZXJpdmVkTUcgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBpZiAoIWZha2VCYXNlLmVtcHRpYWJsZSgpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcihlcnJvclJlcG9ydGVyLCByZ0xvY2F0b3JzW2kvMi0xXSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInNyYy1yZWRlZmluZS42LjIuMiIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXtkZXJpdmVkR3JwLmZOYW1lLCAicmNhc2UtUmVjdXJzZS4yIn0pOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHBhcnRpY2xlVmFsaWRSZXN0cmljdGlvbihmYWtlRGVyaXZlZCwgU0dIYW5kbGVyLCBmYWtlQmFzZSwgU0dIYW5kbGVyKTsKLSAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoWE1MU2NoZW1hRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBrZXkgPSBlLmdldEtleSgpOwotICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoZXJyb3JSZXBvcnRlciwgcmdMb2NhdG9yc1tpLzItMV0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZS5nZXRBcmdzKCkpOwotICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoZXJyb3JSZXBvcnRlciwgcmdMb2NhdG9yc1tpLzItMV0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJzcmMtcmVkZWZpbmUuNi4yLjIiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117ZGVyaXZlZEdycC5mTmFtZSwga2V5fSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBmb3IgZWFjaCBjb21wbGV4IHR5cGUsIGNoZWNrIHRoZSAzIGNvbnN0cmFpbnRzLgotICAgICAgICAvLyB0eXBlcyBuZWVkIHRvIGJlIGNoZWNrZWQKLSAgICAgICAgWFNDb21wbGV4VHlwZURlY2xbXSB0eXBlczsKLSAgICAgICAgU2ltcGxlTG9jYXRvciBbXSBjdExvY2F0b3JzOwotICAgICAgICAvLyB0byBob2xkIHRoZSBlcnJvcnMKLSAgICAgICAgLy8gUkVWSVNJVDogZG8gd2Ugd2FudCB0byByZXBvcnQgYWxsIGVycm9ycz8gb3IganVzdCBvbmU/Ci0gICAgICAgIC8vWE1MU2NoZW1hRXJyb3IxRCBlcnJvcnMgPSBuZXcgWE1MU2NoZW1hRXJyb3IxRCgpOwotICAgICAgICAvLyB3aGV0aGVyIG5lZWQgdG8gY2hlY2sgdGhpcyB0eXBlIGFnYWluOwotICAgICAgICAvLyB3aGV0aGVyIG9ubHkgZG8gVVBBIGNoZWNraW5nCi0gICAgICAgIGJvb2xlYW4gZnVydGhlciwgZnVsbENoZWNrZWQ7Ci0gICAgICAgIC8vIGlmIGRvIGFsbCBjaGVja2luZ3MsIGhvdyBtYW55IG5lZWQgdG8gYmUgY2hlY2tlZCBhZ2Fpbi4KLSAgICAgICAgaW50IGtlZXBUeXBlOwotICAgICAgICAvLyBpOiBncmFtbWFyOyBqOiB0eXBlOyBrOiBlcnJvcgotICAgICAgICAvLyBmb3IgYWxsIGdyYW1tYXJzCi0gICAgICAgIFN5bWJvbEhhc2ggZWxlbVRhYmxlID0gbmV3IFN5bWJvbEhhc2goKTsKLSAgICAgICAgZm9yIChpbnQgaSA9IGdyYW1tYXJzLmxlbmd0aC0xLCBqOyBpID49IDA7IGktLSkgewotICAgICAgICAgICAgLy8gZ2V0IHdoZXRoZXIgdG8gc2tpcCBFREMsIGFuZCB0eXBlcyBuZWVkIHRvIGJlIGNoZWNrZWQKLSAgICAgICAgICAgIGtlZXBUeXBlID0gMDsKLSAgICAgICAgICAgIGZ1bGxDaGVja2VkID0gZ3JhbW1hcnNbaV0uZkZ1bGxDaGVja2VkOwotICAgICAgICAgICAgdHlwZXMgPSBncmFtbWFyc1tpXS5nZXRVbmNoZWNrZWRDb21wbGV4VHlwZURlY2xzKCk7Ci0gICAgICAgICAgICBjdExvY2F0b3JzID0gZ3JhbW1hcnNbaV0uZ2V0VW5jaGVja2VkQ1RMb2NhdG9ycygpOwotICAgICAgICAgICAgLy8gZm9yIGVhY2ggdHlwZQotICAgICAgICAgICAgZm9yIChqID0gMDsgaiA8IHR5cGVzLmxlbmd0aDsgaisrKSB7Ci0gICAgICAgICAgICAgICAgLy8gaWYgd2UndmUgYWxyZWFkeSBmdWxsLWNoZWNrZWQgdGhpcyBncmFtbWFyLCB0aGVuCi0gICAgICAgICAgICAgICAgLy8gc2tpcCB0aGUgRURDIGNvbnN0cmFpbnQKLSAgICAgICAgICAgICAgICBpZiAoIWZ1bGxDaGVja2VkKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIDEuIEVsZW1lbnQgRGVjbCBDb25zaXN0ZW50Ci0gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlc1tqXS5mUGFydGljbGUhPW51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1UYWJsZS5jbGVhcigpOwotICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGVja0VsZW1lbnREZWNsc0NvbnNpc3RlbnQodHlwZXNbal0sIHR5cGVzW2pdLmZQYXJ0aWNsZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1UYWJsZSwgU0dIYW5kbGVyKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGNhdGNoIChYTUxTY2hlbWFFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKGVycm9yUmVwb3J0ZXIsIGN0TG9jYXRvcnNbal0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlLmdldEtleSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZS5nZXRBcmdzKCkpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgLy8gMi4gUGFydGljbGUgRGVyaXZhdGlvbgotCi0gICAgICAgICAgICAgICAgaWYgKHR5cGVzW2pdLmZCYXNlVHlwZSAhPSBudWxsICYmCi0gICAgICAgICAgICAgICAgICAgICAgICB0eXBlc1tqXS5mQmFzZVR5cGUgIT0gU2NoZW1hR3JhbW1hci5mQW55VHlwZSAmJgotICAgICAgICAgICAgICAgICAgICAgICAgdHlwZXNbal0uZkRlcml2ZWRCeSA9PSBYU0NvbnN0YW50cy5ERVJJVkFUSU9OX1JFU1RSSUNUSU9OICYmCi0gICAgICAgICAgICAgICAgICAgICAgICAodHlwZXNbal0uZkJhc2VUeXBlIGluc3RhbmNlb2YgWFNDb21wbGV4VHlwZURlY2wpKSB7Ci0KLSAgICAgICAgICAgICAgICAgICAgWFNQYXJ0aWNsZURlY2wgZGVyaXZlZFBhcnRpY2xlPXR5cGVzW2pdLmZQYXJ0aWNsZTsKLSAgICAgICAgICAgICAgICAgICAgWFNQYXJ0aWNsZURlY2wgYmFzZVBhcnRpY2xlPQotICAgICAgICAgICAgICAgICAgICAgICAgKChYU0NvbXBsZXhUeXBlRGVjbCkodHlwZXNbal0uZkJhc2VUeXBlKSkuZlBhcnRpY2xlOwotICAgICAgICAgICAgICAgICAgICBpZiAoZGVyaXZlZFBhcnRpY2xlPT1udWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYmFzZVBhcnRpY2xlIT1udWxsICYmICFiYXNlUGFydGljbGUuZW1wdGlhYmxlKCkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcihlcnJvclJlcG9ydGVyLGN0TG9jYXRvcnNbal0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi41LjMuMiIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117dHlwZXNbal0uZk5hbWUsIHR5cGVzW2pdLmZCYXNlVHlwZS5nZXROYW1lKCl9KTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChiYXNlUGFydGljbGUhPW51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFydGljbGVWYWxpZFJlc3RyaWN0aW9uKHR5cGVzW2pdLmZQYXJ0aWNsZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNHSGFuZGxlciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoWFNDb21wbGV4VHlwZURlY2wpKHR5cGVzW2pdLmZCYXNlVHlwZSkpLmZQYXJ0aWNsZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNHSGFuZGxlcik7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChYTUxTY2hlbWFFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKGVycm9yUmVwb3J0ZXIsIGN0TG9jYXRvcnNbal0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlLmdldEtleSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZS5nZXRBcmdzKCkpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKGVycm9yUmVwb3J0ZXIsIGN0TG9jYXRvcnNbal0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi41LjQuMiIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117dHlwZXNbal0uZk5hbWV9KTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKGVycm9yUmVwb3J0ZXIsIGN0TG9jYXRvcnNbal0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjUuNC4yIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde3R5cGVzW2pdLmZOYW1lfSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLy8gMy4gVVBBCi0gICAgICAgICAgICAgICAgLy8gZ2V0IHRoZSBjb250ZW50IG1vZGVsIGFuZCBjaGVjayBVUEEKLSAgICAgICAgICAgICAgICBYU0NNVmFsaWRhdG9yIGNtID0gdHlwZXNbal0uZ2V0Q29udGVudE1vZGVsKGNtQnVpbGRlcik7Ci0gICAgICAgICAgICAgICAgZnVydGhlciA9IGZhbHNlOwotICAgICAgICAgICAgICAgIGlmIChjbSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmdXJ0aGVyID0gY20uY2hlY2tVbmlxdWVQYXJ0aWNsZUF0dHJpYnV0aW9uKFNHSGFuZGxlcik7Ci0gICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFhNTFNjaGVtYUV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcihlcnJvclJlcG9ydGVyLCBjdExvY2F0b3JzW2pdLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlLmdldEtleSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlLmdldEFyZ3MoKSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLy8gbm93IHJlcG9ydCBhbGwgZXJyb3JzCi0gICAgICAgICAgICAgICAgLy8gUkVWSVNJVDogZG8gd2Ugd2FudCB0byByZXBvcnQgYWxsIGVycm9ycz8gb3IganVzdCBvbmU/Ci0gICAgICAgICAgICAgICAgLypmb3IgKGsgPSBlcnJvcnMuZ2V0RXJyb3JDb2RlTnVtKCktMTsgayA+PSAwOyBrLS0pIHsKLSAgICAgICAgICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoZXJyb3JSZXBvcnRlciwgY3RMb2NhdG9yc1tqXSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JzLmdldEVycm9yQ29kZShrKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JzLmdldEFyZ3MoaykpOwotICAgICAgICAgICAgICAgIH0qLwotCi0gICAgICAgICAgICAgICAgLy8gaWYgd2UgYXJlIGRvaW5nIGFsbCBjaGVja2luZ3MsIGFuZCB0aGlzIG9uZSBuZWVkcyBmdXJ0aGVyCi0gICAgICAgICAgICAgICAgLy8gY2hlY2tpbmcsIHN0b3JlIGl0IGluIHRoZSB0eXBlIGFycmF5LgotICAgICAgICAgICAgICAgIGlmICghZnVsbENoZWNrZWQgJiYgZnVydGhlcikKLSAgICAgICAgICAgICAgICAgICAgdHlwZXNba2VlcFR5cGUrK10gPSB0eXBlc1tqXTsKLQotICAgICAgICAgICAgICAgIC8vIGNsZWFyIGVycm9ycyBmb3IgdGhlIG5leHQgdHlwZS4KLSAgICAgICAgICAgICAgICAvLyBSRVZJU0lUOiBkbyB3ZSB3YW50IHRvIHJlcG9ydCBhbGwgZXJyb3JzPyBvciBqdXN0IG9uZT8KLSAgICAgICAgICAgICAgICAvL2Vycm9ycy5jbGVhcigpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gd2UndmUgZG9uZSB3aXRoIHRoZSB0eXBlcyBpbiB0aGlzIGdyYW1tYXIuIGlmIHdlIGFyZSBjaGVja2luZwotICAgICAgICAgICAgLy8gYWxsIGNvbnN0cmFpbnRzLCBuZWVkIHRvIHRyaW0gdHlwZSBhcnJheSB0byBhIHByb3BlciBzaXplOgotICAgICAgICAgICAgLy8gb25seSBjb250YWluIHRob3NlIG5lZWQgZnVydGhlciBjaGVja2luZy4KLSAgICAgICAgICAgIC8vIGFuZCBtYXJrIHRoaXMgZ3JhbW1hciB0aGF0IGl0IG9ubHkgbmVlZHMgVVBBIGNoZWNraW5nLgotICAgICAgICAgICAgaWYgKCFmdWxsQ2hlY2tlZCkgewotICAgICAgICAgICAgICAgIGdyYW1tYXJzW2ldLnNldFVuY2hlY2tlZFR5cGVOdW0oa2VlcFR5cGUpOwotICAgICAgICAgICAgICAgIGdyYW1tYXJzW2ldLmZGdWxsQ2hlY2tlZCA9IHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKgotICAgICAgIENoZWNrIHRoYXQgYSBnaXZlbiBwYXJ0aWNsZSBpcyBhIHZhbGlkIHJlc3RyaWN0aW9uIG9mIGEgYmFzZSBwYXJ0aWNsZS4KLSAgICAgKi8KLQotICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBjaGVja0VsZW1lbnREZWNsc0NvbnNpc3RlbnQoWFNDb21wbGV4VHlwZURlY2wgdHlwZSwKLSAgICAgICAgICAgIFhTUGFydGljbGVEZWNsIHBhcnRpY2xlLAotICAgICAgICAgICAgU3ltYm9sSGFzaCBlbGVtRGVjbEhhc2gsCi0gICAgICAgICAgICBTdWJzdGl0dXRpb25Hcm91cEhhbmRsZXIgc2dIYW5kbGVyKQotICAgICAgICB0aHJvd3MgWE1MU2NoZW1hRXhjZXB0aW9uIHsKLQotICAgICAgICAvLyBjaGVjayBmb3IgZWxlbWVudHMgaW4gdGhlIHRyZWUgd2l0aCB0aGUgc2FtZSBuYW1lIGFuZCBuYW1lc3BhY2UKLQotICAgICAgICBpbnQgcFR5cGUgPSBwYXJ0aWNsZS5mVHlwZTsKLQotICAgICAgICBpZiAocFR5cGUgPT0gWFNQYXJ0aWNsZURlY2wuUEFSVElDTEVfV0lMRENBUkQpCi0gICAgICAgICAgICByZXR1cm47Ci0KLSAgICAgICAgaWYgKHBUeXBlID09IFhTUGFydGljbGVEZWNsLlBBUlRJQ0xFX0VMRU1FTlQpIHsKLSAgICAgICAgICAgIFhTRWxlbWVudERlY2wgZWxlbSA9IChYU0VsZW1lbnREZWNsKShwYXJ0aWNsZS5mVmFsdWUpOwotICAgICAgICAgICAgZmluZEVsZW1JblRhYmxlKHR5cGUsIGVsZW0sIGVsZW1EZWNsSGFzaCk7Ci0KLSAgICAgICAgICAgIGlmIChlbGVtLmZTY29wZSA9PSBYU0NvbnN0YW50cy5TQ09QRV9HTE9CQUwpIHsKLSAgICAgICAgICAgICAgICAvLyBDaGVjayBmb3Igc3Vic2l0dXRpb24gZ3JvdXBzLgotICAgICAgICAgICAgICAgIFhTRWxlbWVudERlY2xbXSBzdWJHcm91cCA9IHNnSGFuZGxlci5nZXRTdWJzdGl0dXRpb25Hcm91cChlbGVtKTsKLSAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHN1Ykdyb3VwLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZpbmRFbGVtSW5UYWJsZSh0eXBlLCBzdWJHcm91cFtpXSwgZWxlbURlY2xIYXNoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLQotICAgICAgICBYU01vZGVsR3JvdXBJbXBsIGdyb3VwID0gKFhTTW9kZWxHcm91cEltcGwpcGFydGljbGUuZlZhbHVlOwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGdyb3VwLmZQYXJ0aWNsZUNvdW50OyBpKyspCi0gICAgICAgICAgICBjaGVja0VsZW1lbnREZWNsc0NvbnNpc3RlbnQodHlwZSwgZ3JvdXAuZlBhcnRpY2xlc1tpXSwgZWxlbURlY2xIYXNoLCBzZ0hhbmRsZXIpOwotICAgIH0KLQotICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBmaW5kRWxlbUluVGFibGUoWFNDb21wbGV4VHlwZURlY2wgdHlwZSwgWFNFbGVtZW50RGVjbCBlbGVtLAotICAgICAgICAgICAgU3ltYm9sSGFzaCBlbGVtRGVjbEhhc2gpCi0gICAgICAgIHRocm93cyBYTUxTY2hlbWFFeGNlcHRpb24gewotCi0gICAgICAgIC8vIEhvdyBjYW4gd2UgYXZvaWQgdGhpcyBjb25jYXQ/ICBMTS4KLSAgICAgICAgU3RyaW5nIG5hbWUgPSBlbGVtLmZOYW1lICsgIiwiICsgZWxlbS5mVGFyZ2V0TmFtZXNwYWNlOwotCi0gICAgICAgIFhTRWxlbWVudERlY2wgZXhpc3RpbmdFbGVtID0gbnVsbDsKLSAgICAgICAgaWYgKChleGlzdGluZ0VsZW0gPSAoWFNFbGVtZW50RGVjbCkoZWxlbURlY2xIYXNoLmdldChuYW1lKSkpID09IG51bGwpIHsKLSAgICAgICAgICAgIC8vIGp1c3QgYWRkIGl0IGluCi0gICAgICAgICAgICBlbGVtRGVjbEhhc2gucHV0KG5hbWUsIGVsZW0pOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgLy8gSWYgdGhpcyBpcyB0aGUgc2FtZSBjaGVjayBlbGVtZW50LCB3ZSdyZSBPLksuCi0gICAgICAgICAgICBpZiAoZWxlbSA9PSBleGlzdGluZ0VsZW0pCi0gICAgICAgICAgICAgICAgcmV0dXJuOwotCi0gICAgICAgICAgICBpZiAoZWxlbS5mVHlwZSAhPSBleGlzdGluZ0VsZW0uZlR5cGUpIHsKLSAgICAgICAgICAgICAgICAvLyBUeXBlcyBhcmUgbm90IHRoZSBzYW1lCi0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFhNTFNjaGVtYUV4Y2VwdGlvbigiY29zLWVsZW1lbnQtY29uc2lzdGVudCIsCi0gICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10ge3R5cGUuZk5hbWUsIGVsZW0uZk5hbWV9KTsKLQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgLy8gQ2hlY2sgdGhhdCBhIGdpdmVuIHBhcnRpY2xlIGlzIGEgdmFsaWQgcmVzdHJpY3Rpb24gb2YgYSBiYXNlIHBhcnRpY2xlLgotICAgIC8vCi0gICAgLy8gSUhSOiAyMDA2LzExLzE3Ci0gICAgLy8gUmV0dXJucyBhIGJvb2xlYW4gaW5kaWNhdGluZyBpZiB0aGVyZSBoYXMgYmVlbiBleHBhbnNpb24gb2Ygc3Vic3RpdHV0aW9uIGdyb3VwCi0gICAgLy8gaW4gdGhlIGJQYXJ0aWNsZS4KLSAgICAvLyBXaXRoIHRoaXMgaW5mb3JtYXRpb24gdGhlIGNoZWNrUmVjdXJzZUxheCBmdW5jdGlvbiBrbm93cyB3aGVuIGlzCi0gICAgLy8gdG8ga2VlcCB0aGUgb3JkZXIgYW5kIHdoZW4gdG8gaWdub3JlIGl0LgotICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gcGFydGljbGVWYWxpZFJlc3RyaWN0aW9uKFhTUGFydGljbGVEZWNsIGRQYXJ0aWNsZSwKLSAgICAgICAgICAgIFN1YnN0aXR1dGlvbkdyb3VwSGFuZGxlciBkU0dIYW5kbGVyLAotICAgICAgICAgICAgWFNQYXJ0aWNsZURlY2wgYlBhcnRpY2xlLAotICAgICAgICAgICAgU3Vic3RpdHV0aW9uR3JvdXBIYW5kbGVyIGJTR0hhbmRsZXIpCi0gICAgICAgIHRocm93cyBYTUxTY2hlbWFFeGNlcHRpb24gewotICAgICAgICByZXR1cm4gcGFydGljbGVWYWxpZFJlc3RyaWN0aW9uKGRQYXJ0aWNsZSwgZFNHSGFuZGxlciwgYlBhcnRpY2xlLCBiU0dIYW5kbGVyLCB0cnVlKTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIHBhcnRpY2xlVmFsaWRSZXN0cmljdGlvbihYU1BhcnRpY2xlRGVjbCBkUGFydGljbGUsCi0gICAgICAgICAgICBTdWJzdGl0dXRpb25Hcm91cEhhbmRsZXIgZFNHSGFuZGxlciwKLSAgICAgICAgICAgIFhTUGFydGljbGVEZWNsIGJQYXJ0aWNsZSwKLSAgICAgICAgICAgIFN1YnN0aXR1dGlvbkdyb3VwSGFuZGxlciBiU0dIYW5kbGVyLAotICAgICAgICAgICAgYm9vbGVhbiBjaGVja1dDT2NjdXJyZW5jZSkKLSAgICAgICAgdGhyb3dzIFhNTFNjaGVtYUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgVmVjdG9yIGRDaGlsZHJlbiA9IG51bGw7Ci0gICAgICAgIFZlY3RvciBiQ2hpbGRyZW4gPSBudWxsOwotICAgICAgICBpbnQgZE1pbkVmZmVjdGl2ZVRvdGFsUmFuZ2U9T0NDVVJSRU5DRV9VTktOT1dOOwotICAgICAgICBpbnQgZE1heEVmZmVjdGl2ZVRvdGFsUmFuZ2U9T0NDVVJSRU5DRV9VTktOT1dOOwotCi0gICAgICAgIC8vIEJ5IGRlZmF1bHQgdGhlcmUgaGFzIGJlZW4gbm8gZXhwYW5zaW9uCi0gICAgICAgIGJvb2xlYW4gYkV4cGFuc2lvbkhhcHBlbmVkID0gZmFsc2U7Ci0KLSAgICAgICAgLy8gQ2hlY2sgZm9yIGVtcHR5IHBhcnRpY2xlcy4gICBJZiBlaXRoZXIgYmFzZSBvciBkZXJpdmVkIHBhcnRpY2xlIGlzIGVtcHR5LAotICAgICAgICAvLyAoYW5kIHRoZSBvdGhlciBpc24ndCkgaXQncyBhbiBlcnJvci4KLSAgICAgICAgaWYgKGRQYXJ0aWNsZS5pc0VtcHR5KCkgJiYgIWJQYXJ0aWNsZS5lbXB0aWFibGUoKSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFhNTFNjaGVtYUV4Y2VwdGlvbigiY29zLXBhcnRpY2xlLXJlc3RyaWN0LmEiLCBudWxsKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICghZFBhcnRpY2xlLmlzRW1wdHkoKSAmJiBiUGFydGljbGUuaXNFbXB0eSgpKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWE1MU2NoZW1hRXhjZXB0aW9uKCJjb3MtcGFydGljbGUtcmVzdHJpY3QuYiIsIG51bGwpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gRG8gc2V0dXAgcHJpb3IgdG8gaW52b2tpbmcgdGhlIFBhcnRpY2xlIChSZXN0cmljdGlvbikgY2FzZXMuCi0gICAgICAgIC8vIFRoaXMgaW52b2x2ZXM6Ci0gICAgICAgIC8vICAgLSByZW1vdmluZyBwb2ludGxlc3Mgb2NjdXJyZW5jZXMgZm9yIGdyb3VwcywgYW5kIHJldHJpZXZpbmcgYSB2ZWN0b3Igb2YKLSAgICAgICAgLy8gICAgIG5vbi1wb2ludGxlc3MgY2hpbGRyZW4KLSAgICAgICAgLy8gICAtIHR1cm5pbmcgdG9wLWxldmVsIGVsZW1lbnRzIHdpdGggc3Vic3RpdHV0aW9uIGdyb3VwcyBpbnRvIENIT0lDRSBncm91cHMuCi0gICAgICAgIC8vCi0KLSAgICAgICAgc2hvcnQgZFR5cGUgPSBkUGFydGljbGUuZlR5cGU7Ci0gICAgICAgIC8vCi0gICAgICAgIC8vIEhhbmRsZSBwb2ludGxlc3MgZ3JvdXBzIGZvciB0aGUgZGVyaXZlZCBwYXJ0aWNsZQotICAgICAgICAvLwotICAgICAgICBpZiAoZFR5cGUgPT0gWFNQYXJ0aWNsZURlY2wuUEFSVElDTEVfTU9ERUxHUk9VUCkgewotICAgICAgICAgICAgZFR5cGUgPSAoKFhTTW9kZWxHcm91cEltcGwpZFBhcnRpY2xlLmZWYWx1ZSkuZkNvbXBvc2l0b3I7Ci0KLSAgICAgICAgICAgIC8vIEZpbmQgYSBncm91cCwgc3RhcnRpbmcgd2l0aCB0aGlzIHBhcnRpY2xlLCB3aXRoIG1vcmUgdGhhbiAxIGNoaWxkLiAgIFRoZXJlCi0gICAgICAgICAgICAvLyBtYXkgYmUgbm9uZSwgYW5kIHRoZSBwYXJ0aWNsZSBvZiBpbnRlcmVzdCB0cml2aWFsbHkgYmVjb21lcyBhbiBlbGVtZW50IG9yCi0gICAgICAgICAgICAvLyB3aWxkY2FyZC4KLSAgICAgICAgICAgIFhTUGFydGljbGVEZWNsIGR0bXAgPSBnZXROb25VbmFyeUdyb3VwKGRQYXJ0aWNsZSk7Ci0gICAgICAgICAgICBpZiAoZHRtcCAhPSBkUGFydGljbGUpIHsKLSAgICAgICAgICAgICAgICAvLyBQYXJ0aWNsZSBoYXMgYmVlbiByZXBsYWNlZC4gICBSZXRyaWV2ZSBuZXcgdHlwZSBpbmZvLgotICAgICAgICAgICAgICAgIGRQYXJ0aWNsZSA9IGR0bXA7Ci0gICAgICAgICAgICAgICAgZFR5cGUgPSBkUGFydGljbGUuZlR5cGU7Ci0gICAgICAgICAgICAgICAgaWYgKGRUeXBlID09IFhTUGFydGljbGVEZWNsLlBBUlRJQ0xFX01PREVMR1JPVVApCi0gICAgICAgICAgICAgICAgICAgIGRUeXBlID0gKChYU01vZGVsR3JvdXBJbXBsKWRQYXJ0aWNsZS5mVmFsdWUpLmZDb21wb3NpdG9yOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBGaWxsIGluIGEgdmVjdG9yIHdpdGggdGhlIGNoaWxkcmVuIG9mIHRoZSBwYXJ0aWNsZSwgcmVtb3ZpbmcgYW55Ci0gICAgICAgICAgICAvLyBwb2ludGxlc3MgbW9kZWwgZ3JvdXBzIGluIHRoZSBwcm9jZXNzLgotICAgICAgICAgICAgZENoaWxkcmVuID0gcmVtb3ZlUG9pbnRsZXNzQ2hpbGRyZW4oZFBhcnRpY2xlKTsKLSAgICAgICAgfQotCi0gICAgICAgIGludCBkTWluT2NjdXJzID0gZFBhcnRpY2xlLmZNaW5PY2N1cnM7Ci0gICAgICAgIGludCBkTWF4T2NjdXJzID0gZFBhcnRpY2xlLmZNYXhPY2N1cnM7Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gRm9yIGVsZW1lbnRzIHdoaWNoIGFyZSB0aGUgaGVhZHMgb2Ygc3Vic3RpdHV0aW9uIGdyb3VwcywgdHJlYXQgYXMgQ0hPSUNFCi0gICAgICAgIC8vCi0gICAgICAgIGlmIChkU0dIYW5kbGVyICE9IG51bGwgJiYgZFR5cGUgPT0gWFNQYXJ0aWNsZURlY2wuUEFSVElDTEVfRUxFTUVOVCkgewotICAgICAgICAgICAgWFNFbGVtZW50RGVjbCBkRWxlbWVudCA9IChYU0VsZW1lbnREZWNsKWRQYXJ0aWNsZS5mVmFsdWU7Ci0KLSAgICAgICAgICAgIGlmIChkRWxlbWVudC5mU2NvcGUgPT0gWFNDb25zdGFudHMuU0NPUEVfR0xPQkFMKSB7Ci0gICAgICAgICAgICAgICAgLy8gQ2hlY2sgZm9yIHN1YnNpdHV0aW9uIGdyb3Vwcy4gICBUcmVhdCBhbnkgZWxlbWVudCB0aGF0IGhhcyBhCi0gICAgICAgICAgICAgICAgLy8gc3Vic2l0dXRpb24gZ3JvdXAgYXMgYSBjaG9pY2UuICAgRmlsbCBpbiB0aGUgY2hpbGRyZW4gdmVjdG9yIHdpdGggdGhlCi0gICAgICAgICAgICAgICAgLy8gbWVtYmVycyBvZiB0aGUgc3Vic3RpdHV0aW9uIGdyb3VwCi0gICAgICAgICAgICAgICAgWFNFbGVtZW50RGVjbFtdIHN1Ykdyb3VwID0gZFNHSGFuZGxlci5nZXRTdWJzdGl0dXRpb25Hcm91cChkRWxlbWVudCk7Ci0gICAgICAgICAgICAgICAgaWYgKHN1Ykdyb3VwLmxlbmd0aCA+MCApIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gTm93LCBzZXQgdGhlIHR5cGUgdG8gYmUgQ0hPSUNFLiAgVGhlICJncm91cCIgd2lsbCBoYXZlIHRoZSBzYW1lCi0gICAgICAgICAgICAgICAgICAgIC8vIG9jY3VycmVuY2UgaW5mb3JtYXRpb24gYXMgdGhlIG9yaWdpbmFsIHBhcnRpY2xlLgotICAgICAgICAgICAgICAgICAgICBkVHlwZSA9IFhTTW9kZWxHcm91cEltcGwuTU9ERUxHUk9VUF9DSE9JQ0U7Ci0gICAgICAgICAgICAgICAgICAgIGRNaW5FZmZlY3RpdmVUb3RhbFJhbmdlID0gZE1pbk9jY3VyczsKLSAgICAgICAgICAgICAgICAgICAgZE1heEVmZmVjdGl2ZVRvdGFsUmFuZ2UgPSBkTWF4T2NjdXJzOwotCi0gICAgICAgICAgICAgICAgICAgIC8vIEZpbGwgaW4gdGhlIHZlY3RvciBvZiBjaGlsZHJlbgotICAgICAgICAgICAgICAgICAgICBkQ2hpbGRyZW4gPSBuZXcgVmVjdG9yKHN1Ykdyb3VwLmxlbmd0aCsxKTsKLSAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzdWJHcm91cC5sZW5ndGg7IGkrKykgewotICAgICAgICAgICAgICAgICAgICAgICAgYWRkRWxlbWVudFRvUGFydGljbGVWZWN0b3IoZENoaWxkcmVuLCBzdWJHcm91cFtpXSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgYWRkRWxlbWVudFRvUGFydGljbGVWZWN0b3IoZENoaWxkcmVuLCBkRWxlbWVudCk7Ci0gICAgICAgICAgICAgICAgICAgIENvbGxlY3Rpb25zLnNvcnQoZENoaWxkcmVuLCBFTEVNRU5UX1BBUlRJQ0xFX0NPTVBBUkFUT1IpOwotCi0gICAgICAgICAgICAgICAgICAgIC8vIFNldCB0aGUgaGFuZGxlciB0byBudWxsLCB0byBpbmRpY2F0ZSB0aGF0IHdlJ3ZlIGZpbmlzaGVkIGhhbmRsaW5nCi0gICAgICAgICAgICAgICAgICAgIC8vIHN1YnN0aXR1dGlvbiBncm91cHMgZm9yIHRoaXMgcGFydGljbGUuCi0gICAgICAgICAgICAgICAgICAgIGRTR0hhbmRsZXIgPSBudWxsOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHNob3J0IGJUeXBlID0gYlBhcnRpY2xlLmZUeXBlOwotICAgICAgICAvLwotICAgICAgICAvLyBIYW5kbGUgcG9pbnRsZXNzIGdyb3VwcyBmb3IgdGhlIGJhc2UgcGFydGljbGUKLSAgICAgICAgLy8KLSAgICAgICAgaWYgKGJUeXBlID09IFhTUGFydGljbGVEZWNsLlBBUlRJQ0xFX01PREVMR1JPVVApIHsKLSAgICAgICAgICAgIGJUeXBlID0gKChYU01vZGVsR3JvdXBJbXBsKWJQYXJ0aWNsZS5mVmFsdWUpLmZDb21wb3NpdG9yOwotCi0gICAgICAgICAgICAvLyBGaW5kIGEgZ3JvdXAsIHN0YXJ0aW5nIHdpdGggdGhpcyBwYXJ0aWNsZSwgd2l0aCBtb3JlIHRoYW4gMSBjaGlsZC4gICBUaGVyZQotICAgICAgICAgICAgLy8gbWF5IGJlIG5vbmUsIGFuZCB0aGUgcGFydGljbGUgb2YgaW50ZXJlc3QgdHJpdmlhbGx5IGJlY29tZXMgYW4gZWxlbWVudCBvcgotICAgICAgICAgICAgLy8gd2lsZGNhcmQuCi0gICAgICAgICAgICBYU1BhcnRpY2xlRGVjbCBidG1wID0gZ2V0Tm9uVW5hcnlHcm91cChiUGFydGljbGUpOwotICAgICAgICAgICAgaWYgKGJ0bXAgIT0gYlBhcnRpY2xlKSB7Ci0gICAgICAgICAgICAgICAgLy8gUGFydGljbGUgaGFzIGJlZW4gcmVwbGFjZWQuICAgUmV0cmlldmUgbmV3IHR5cGUgaW5mby4KLSAgICAgICAgICAgICAgICBiUGFydGljbGUgPSBidG1wOwotICAgICAgICAgICAgICAgIGJUeXBlID0gYlBhcnRpY2xlLmZUeXBlOwotICAgICAgICAgICAgICAgIGlmIChiVHlwZSA9PSBYU1BhcnRpY2xlRGVjbC5QQVJUSUNMRV9NT0RFTEdST1VQKQotICAgICAgICAgICAgICAgICAgICBiVHlwZSA9ICgoWFNNb2RlbEdyb3VwSW1wbCliUGFydGljbGUuZlZhbHVlKS5mQ29tcG9zaXRvcjsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gRmlsbCBpbiBhIHZlY3RvciB3aXRoIHRoZSBjaGlsZHJlbiBvZiB0aGUgcGFydGljbGUsIHJlbW92aW5nIGFueQotICAgICAgICAgICAgLy8gcG9pbnRsZXNzIG1vZGVsIGdyb3VwcyBpbiB0aGUgcHJvY2Vzcy4KLSAgICAgICAgICAgIGJDaGlsZHJlbiA9IHJlbW92ZVBvaW50bGVzc0NoaWxkcmVuKGJQYXJ0aWNsZSk7Ci0gICAgICAgIH0KLQotICAgICAgICBpbnQgYk1pbk9jY3VycyA9IGJQYXJ0aWNsZS5mTWluT2NjdXJzOwotICAgICAgICBpbnQgYk1heE9jY3VycyA9IGJQYXJ0aWNsZS5mTWF4T2NjdXJzOwotCi0gICAgICAgIGlmIChiU0dIYW5kbGVyICE9IG51bGwgJiYgYlR5cGUgPT0gWFNQYXJ0aWNsZURlY2wuUEFSVElDTEVfRUxFTUVOVCkgewotICAgICAgICAgICAgWFNFbGVtZW50RGVjbCBiRWxlbWVudCA9IChYU0VsZW1lbnREZWNsKWJQYXJ0aWNsZS5mVmFsdWU7Ci0KLSAgICAgICAgICAgIGlmIChiRWxlbWVudC5mU2NvcGUgPT0gWFNDb25zdGFudHMuU0NPUEVfR0xPQkFMKSB7Ci0gICAgICAgICAgICAgICAgLy8gQ2hlY2sgZm9yIHN1YnNpdHV0aW9uIGdyb3Vwcy4gICBUcmVhdCBhbnkgZWxlbWVudCB0aGF0IGhhcyBhCi0gICAgICAgICAgICAgICAgLy8gc3Vic2l0dXRpb24gZ3JvdXAgYXMgYSBjaG9pY2UuICAgRmlsbCBpbiB0aGUgY2hpbGRyZW4gdmVjdG9yIHdpdGggdGhlCi0gICAgICAgICAgICAgICAgLy8gbWVtYmVycyBvZiB0aGUgc3Vic3RpdHV0aW9uIGdyb3VwCi0gICAgICAgICAgICAgICAgWFNFbGVtZW50RGVjbFtdIGJzdWJHcm91cCA9IGJTR0hhbmRsZXIuZ2V0U3Vic3RpdHV0aW9uR3JvdXAoYkVsZW1lbnQpOwotICAgICAgICAgICAgICAgIGlmIChic3ViR3JvdXAubGVuZ3RoID4wICkgewotICAgICAgICAgICAgICAgICAgICAvLyBOb3csIHNldCB0aGUgdHlwZSB0byBiZSBDSE9JQ0UKLSAgICAgICAgICAgICAgICAgICAgYlR5cGUgPSBYU01vZGVsR3JvdXBJbXBsLk1PREVMR1JPVVBfQ0hPSUNFOwotCi0gICAgICAgICAgICAgICAgICAgIGJDaGlsZHJlbiA9IG5ldyBWZWN0b3IoYnN1Ykdyb3VwLmxlbmd0aCsxKTsKLSAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBic3ViR3JvdXAubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGFkZEVsZW1lbnRUb1BhcnRpY2xlVmVjdG9yKGJDaGlsZHJlbiwgYnN1Ykdyb3VwW2ldKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBhZGRFbGVtZW50VG9QYXJ0aWNsZVZlY3RvcihiQ2hpbGRyZW4sIGJFbGVtZW50KTsKLSAgICAgICAgICAgICAgICAgICAgQ29sbGVjdGlvbnMuc29ydChiQ2hpbGRyZW4sIEVMRU1FTlRfUEFSVElDTEVfQ09NUEFSQVRPUik7Ci0gICAgICAgICAgICAgICAgICAgIC8vIFNldCB0aGUgaGFuZGxlciB0byBudWxsLCB0byBpbmRpY2F0ZSB0aGF0IHdlJ3ZlIGZpbmlzaGVkIGhhbmRsaW5nCi0gICAgICAgICAgICAgICAgICAgIC8vIHN1YnN0aXR1dGlvbiBncm91cHMgZm9yIHRoaXMgcGFydGljbGUuCi0gICAgICAgICAgICAgICAgICAgIGJTR0hhbmRsZXIgPSBudWxsOwotCi0gICAgICAgICAgICAgICAgICAgIC8vIGlmIHdlIGFyZSBoZXJlIGV4cGFuc2lvbiBvZiBiUGFydGljbGUgaGFwcGVuZWQKLSAgICAgICAgICAgICAgICAgICAgYkV4cGFuc2lvbkhhcHBlbmVkID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLwotICAgICAgICAvLyBPLksuIC0gRmlndXJlIG91dCB3aGljaCBwYXJ0aWNsZSBkZXJpdmF0aW9uIHJ1bGUgYXBwbGllcyBhbmQgY2FsbCBpdAotICAgICAgICAvLwotICAgICAgICBzd2l0Y2ggKGRUeXBlKSB7Ci0gICAgICAgICAgICBjYXNlIFhTUGFydGljbGVEZWNsLlBBUlRJQ0xFX0VMRU1FTlQ6Ci0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgc3dpdGNoIChiVHlwZSkgewotCi0gICAgICAgICAgICAgICAgICAgIC8vIEVsdDpFbHQgTmFtZUFuZFR5cGVPSwotICAgICAgICAgICAgICAgICAgICBjYXNlIFhTUGFydGljbGVEZWNsLlBBUlRJQ0xFX0VMRU1FTlQ6Ci0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGNoZWNrTmFtZUFuZFR5cGVPSygoWFNFbGVtZW50RGVjbClkUGFydGljbGUuZlZhbHVlLGRNaW5PY2N1cnMsZE1heE9jY3VycywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFhTRWxlbWVudERlY2wpYlBhcnRpY2xlLmZWYWx1ZSxiTWluT2NjdXJzLGJNYXhPY2N1cnMpOwotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGJFeHBhbnNpb25IYXBwZW5lZDsKLSAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgIC8vIEVsdDpBbnkgTlNDb21wYXQKLSAgICAgICAgICAgICAgICAgICAgY2FzZSBYU1BhcnRpY2xlRGVjbC5QQVJUSUNMRV9XSUxEQ0FSRDoKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tOU0NvbXBhdCgoWFNFbGVtZW50RGVjbClkUGFydGljbGUuZlZhbHVlLGRNaW5PY2N1cnMsZE1heE9jY3VycywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFhTV2lsZGNhcmREZWNsKWJQYXJ0aWNsZS5mVmFsdWUsYk1pbk9jY3VycyxiTWF4T2NjdXJzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGVja1dDT2NjdXJyZW5jZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYkV4cGFuc2lvbkhhcHBlbmVkOwotICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgLy8gRWx0OkFsbCBSZWN1cnNlQXNJZkdyb3VwCi0gICAgICAgICAgICAgICAgICAgIGNhc2UgWFNNb2RlbEdyb3VwSW1wbC5NT0RFTEdST1VQX0NIT0lDRToKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gVHJlYXQgdGhlIGVsZW1lbnQgYXMgaWYgaXQgd2VyZSBpbiBhIGdyb3VwIG9mIHRoZSBzYW1lIHR5cGUKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFzIHRoZSBiYXNlIFBhcnRpY2xlCi0gICAgICAgICAgICAgICAgICAgICAgICBkQ2hpbGRyZW4gPSBuZXcgVmVjdG9yKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBkQ2hpbGRyZW4uYWRkRWxlbWVudChkUGFydGljbGUpOwotCi0gICAgICAgICAgICAgICAgICAgICAgICBjaGVja1JlY3Vyc2VMYXgoZENoaWxkcmVuLCAxLCAxLCBkU0dIYW5kbGVyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiQ2hpbGRyZW4sIGJNaW5PY2N1cnMsIGJNYXhPY2N1cnMsIGJTR0hhbmRsZXIpOwotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGJFeHBhbnNpb25IYXBwZW5lZDsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBjYXNlIFhTTW9kZWxHcm91cEltcGwuTU9ERUxHUk9VUF9TRVFVRU5DRToKLSAgICAgICAgICAgICAgICAgICAgY2FzZSBYU01vZGVsR3JvdXBJbXBsLk1PREVMR1JPVVBfQUxMOgotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBUcmVhdCB0aGUgZWxlbWVudCBhcyBpZiBpdCB3ZXJlIGluIGEgZ3JvdXAgb2YgdGhlIHNhbWUgdHlwZQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gYXMgdGhlIGJhc2UgUGFydGljbGUKLSAgICAgICAgICAgICAgICAgICAgICAgIGRDaGlsZHJlbiA9IG5ldyBWZWN0b3IoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGRDaGlsZHJlbi5hZGRFbGVtZW50KGRQYXJ0aWNsZSk7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIGNoZWNrUmVjdXJzZShkQ2hpbGRyZW4sIDEsIDEsIGRTR0hhbmRsZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJDaGlsZHJlbiwgYk1pbk9jY3VycywgYk1heE9jY3VycywgYlNHSGFuZGxlcik7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYkV4cGFuc2lvbkhhcHBlbmVkOwotICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFhNTFNjaGVtYUV4Y2VwdGlvbigiSW50ZXJuYWwtRXJyb3IiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117ImluIHBhcnRpY2xlVmFsaWRSZXN0cmljdGlvbiJ9KTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgY2FzZSBYU1BhcnRpY2xlRGVjbC5QQVJUSUNMRV9XSUxEQ0FSRDoKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBzd2l0Y2ggKGJUeXBlKSB7Ci0KLSAgICAgICAgICAgICAgICAgICAgLy8gQW55OkFueSBOU1N1YnNldAotICAgICAgICAgICAgICAgICAgICBjYXNlIFhTUGFydGljbGVEZWNsLlBBUlRJQ0xFX1dJTERDQVJEOgotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBjaGVja05TU3Vic2V0KChYU1dpbGRjYXJkRGVjbClkUGFydGljbGUuZlZhbHVlLCBkTWluT2NjdXJzLCBkTWF4T2NjdXJzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoWFNXaWxkY2FyZERlY2wpYlBhcnRpY2xlLmZWYWx1ZSwgYk1pbk9jY3VycywgYk1heE9jY3Vycyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYkV4cGFuc2lvbkhhcHBlbmVkOwotICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgY2FzZSBYU01vZGVsR3JvdXBJbXBsLk1PREVMR1JPVVBfQ0hPSUNFOgotICAgICAgICAgICAgICAgICAgICBjYXNlIFhTTW9kZWxHcm91cEltcGwuTU9ERUxHUk9VUF9TRVFVRU5DRToKLSAgICAgICAgICAgICAgICAgICAgY2FzZSBYU01vZGVsR3JvdXBJbXBsLk1PREVMR1JPVVBfQUxMOgotICAgICAgICAgICAgICAgICAgICBjYXNlIFhTUGFydGljbGVEZWNsLlBBUlRJQ0xFX0VMRU1FTlQ6Ci0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBYTUxTY2hlbWFFeGNlcHRpb24oImNvcy1wYXJ0aWNsZS1yZXN0cmljdC4yIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdeyJhbnk6Y2hvaWNlLHNlcXVlbmNlLGFsbCxlbHQifSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWE1MU2NoZW1hRXhjZXB0aW9uKCJJbnRlcm5hbC1FcnJvciIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXsiaW4gcGFydGljbGVWYWxpZFJlc3RyaWN0aW9uIn0pOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBjYXNlIFhTTW9kZWxHcm91cEltcGwuTU9ERUxHUk9VUF9BTEw6Ci0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgc3dpdGNoIChiVHlwZSkgewotCi0gICAgICAgICAgICAgICAgICAgIC8vIEFsbDpBbnkgTlNSZWN1cnNlQ2hlY2tDYXJkaW5hbGl0eQotICAgICAgICAgICAgICAgICAgICBjYXNlIFhTUGFydGljbGVEZWNsLlBBUlRJQ0xFX1dJTERDQVJEOgotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZE1pbkVmZmVjdGl2ZVRvdGFsUmFuZ2UgPT0gT0NDVVJSRU5DRV9VTktOT1dOKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRNaW5FZmZlY3RpdmVUb3RhbFJhbmdlID0gZFBhcnRpY2xlLm1pbkVmZmVjdGl2ZVRvdGFsUmFuZ2UoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkTWF4RWZmZWN0aXZlVG90YWxSYW5nZSA9PSBPQ0NVUlJFTkNFX1VOS05PV04pCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZE1heEVmZmVjdGl2ZVRvdGFsUmFuZ2UgPSBkUGFydGljbGUubWF4RWZmZWN0aXZlVG90YWxSYW5nZSgpOwotCi0gICAgICAgICAgICAgICAgICAgICAgICBjaGVja05TUmVjdXJzZUNoZWNrQ2FyZGluYWxpdHkoZENoaWxkcmVuLCBkTWluRWZmZWN0aXZlVG90YWxSYW5nZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZE1heEVmZmVjdGl2ZVRvdGFsUmFuZ2UsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRTR0hhbmRsZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJQYXJ0aWNsZSxiTWluT2NjdXJzLGJNYXhPY2N1cnMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoZWNrV0NPY2N1cnJlbmNlKTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGJFeHBhbnNpb25IYXBwZW5lZDsKLSAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgIGNhc2UgWFNNb2RlbEdyb3VwSW1wbC5NT0RFTEdST1VQX0FMTDoKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tSZWN1cnNlKGRDaGlsZHJlbiwgZE1pbk9jY3VycywgZE1heE9jY3VycywgZFNHSGFuZGxlciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYkNoaWxkcmVuLCBiTWluT2NjdXJzLCBiTWF4T2NjdXJzLCBiU0dIYW5kbGVyKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBiRXhwYW5zaW9uSGFwcGVuZWQ7Ci0gICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICBjYXNlIFhTTW9kZWxHcm91cEltcGwuTU9ERUxHUk9VUF9DSE9JQ0U6Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgWFNNb2RlbEdyb3VwSW1wbC5NT0RFTEdST1VQX1NFUVVFTkNFOgotICAgICAgICAgICAgICAgICAgICBjYXNlIFhTUGFydGljbGVEZWNsLlBBUlRJQ0xFX0VMRU1FTlQ6Ci0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBYTUxTY2hlbWFFeGNlcHRpb24oImNvcy1wYXJ0aWNsZS1yZXN0cmljdC4yIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdeyJhbGw6Y2hvaWNlLHNlcXVlbmNlLGVsdCJ9KTsKLSAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6Ci0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBYTUxTY2hlbWFFeGNlcHRpb24oIkludGVybmFsLUVycm9yIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdeyJpbiBwYXJ0aWNsZVZhbGlkUmVzdHJpY3Rpb24ifSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGNhc2UgWFNNb2RlbEdyb3VwSW1wbC5NT0RFTEdST1VQX0NIT0lDRToKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBzd2l0Y2ggKGJUeXBlKSB7Ci0KLSAgICAgICAgICAgICAgICAgICAgLy8gQ2hvaWNlOkFueSBOU1JlY3Vyc2VDaGVja0NhcmRpbmFsaXR5Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgWFNQYXJ0aWNsZURlY2wuUEFSVElDTEVfV0lMRENBUkQ6Ci0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkTWluRWZmZWN0aXZlVG90YWxSYW5nZSA9PSBPQ0NVUlJFTkNFX1VOS05PV04pCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZE1pbkVmZmVjdGl2ZVRvdGFsUmFuZ2UgPSBkUGFydGljbGUubWluRWZmZWN0aXZlVG90YWxSYW5nZSgpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRNYXhFZmZlY3RpdmVUb3RhbFJhbmdlID09IE9DQ1VSUkVOQ0VfVU5LTk9XTikKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBkTWF4RWZmZWN0aXZlVG90YWxSYW5nZSA9IGRQYXJ0aWNsZS5tYXhFZmZlY3RpdmVUb3RhbFJhbmdlKCk7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIGNoZWNrTlNSZWN1cnNlQ2hlY2tDYXJkaW5hbGl0eShkQ2hpbGRyZW4sIGRNaW5FZmZlY3RpdmVUb3RhbFJhbmdlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkTWF4RWZmZWN0aXZlVG90YWxSYW5nZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZFNHSGFuZGxlciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYlBhcnRpY2xlLGJNaW5PY2N1cnMsYk1heE9jY3VycywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tXQ09jY3VycmVuY2UpOwotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGJFeHBhbnNpb25IYXBwZW5lZDsKLSAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgIGNhc2UgWFNNb2RlbEdyb3VwSW1wbC5NT0RFTEdST1VQX0NIT0lDRToKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tSZWN1cnNlTGF4KGRDaGlsZHJlbiwgZE1pbk9jY3VycywgZE1heE9jY3VycywgZFNHSGFuZGxlciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYkNoaWxkcmVuLCBiTWluT2NjdXJzLCBiTWF4T2NjdXJzLCBiU0dIYW5kbGVyKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBiRXhwYW5zaW9uSGFwcGVuZWQ7Ci0gICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICBjYXNlIFhTTW9kZWxHcm91cEltcGwuTU9ERUxHUk9VUF9BTEw6Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgWFNNb2RlbEdyb3VwSW1wbC5NT0RFTEdST1VQX1NFUVVFTkNFOgotICAgICAgICAgICAgICAgICAgICBjYXNlIFhTUGFydGljbGVEZWNsLlBBUlRJQ0xFX0VMRU1FTlQ6Ci0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBYTUxTY2hlbWFFeGNlcHRpb24oImNvcy1wYXJ0aWNsZS1yZXN0cmljdC4yIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdeyJjaG9pY2U6YWxsLHNlcXVlbmNlLGVsdCJ9KTsKLSAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6Ci0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBYTUxTY2hlbWFFeGNlcHRpb24oIkludGVybmFsLUVycm9yIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdeyJpbiBwYXJ0aWNsZVZhbGlkUmVzdHJpY3Rpb24ifSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLQotICAgICAgICAgICAgY2FzZSBYU01vZGVsR3JvdXBJbXBsLk1PREVMR1JPVVBfU0VRVUVOQ0U6Ci0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgc3dpdGNoIChiVHlwZSkgewotCi0gICAgICAgICAgICAgICAgICAgIC8vIENob2ljZTpBbnkgTlNSZWN1cnNlQ2hlY2tDYXJkaW5hbGl0eQotICAgICAgICAgICAgICAgICAgICBjYXNlIFhTUGFydGljbGVEZWNsLlBBUlRJQ0xFX1dJTERDQVJEOgotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZE1pbkVmZmVjdGl2ZVRvdGFsUmFuZ2UgPT0gT0NDVVJSRU5DRV9VTktOT1dOKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRNaW5FZmZlY3RpdmVUb3RhbFJhbmdlID0gZFBhcnRpY2xlLm1pbkVmZmVjdGl2ZVRvdGFsUmFuZ2UoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkTWF4RWZmZWN0aXZlVG90YWxSYW5nZSA9PSBPQ0NVUlJFTkNFX1VOS05PV04pCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZE1heEVmZmVjdGl2ZVRvdGFsUmFuZ2UgPSBkUGFydGljbGUubWF4RWZmZWN0aXZlVG90YWxSYW5nZSgpOwotCi0gICAgICAgICAgICAgICAgICAgICAgICBjaGVja05TUmVjdXJzZUNoZWNrQ2FyZGluYWxpdHkoZENoaWxkcmVuLCBkTWluRWZmZWN0aXZlVG90YWxSYW5nZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZE1heEVmZmVjdGl2ZVRvdGFsUmFuZ2UsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRTR0hhbmRsZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJQYXJ0aWNsZSxiTWluT2NjdXJzLGJNYXhPY2N1cnMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoZWNrV0NPY2N1cnJlbmNlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBiRXhwYW5zaW9uSGFwcGVuZWQ7Ci0gICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICBjYXNlIFhTTW9kZWxHcm91cEltcGwuTU9ERUxHUk9VUF9BTEw6Ci0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGNoZWNrUmVjdXJzZVVub3JkZXJlZChkQ2hpbGRyZW4sIGRNaW5PY2N1cnMsIGRNYXhPY2N1cnMsIGRTR0hhbmRsZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJDaGlsZHJlbiwgYk1pbk9jY3VycywgYk1heE9jY3VycywgYlNHSGFuZGxlcik7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYkV4cGFuc2lvbkhhcHBlbmVkOwotICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgY2FzZSBYU01vZGVsR3JvdXBJbXBsLk1PREVMR1JPVVBfU0VRVUVOQ0U6Ci0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGNoZWNrUmVjdXJzZShkQ2hpbGRyZW4sIGRNaW5PY2N1cnMsIGRNYXhPY2N1cnMsIGRTR0hhbmRsZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJDaGlsZHJlbiwgYk1pbk9jY3VycywgYk1heE9jY3VycywgYlNHSGFuZGxlcik7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYkV4cGFuc2lvbkhhcHBlbmVkOwotICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgY2FzZSBYU01vZGVsR3JvdXBJbXBsLk1PREVMR1JPVVBfQ0hPSUNFOgotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpbnQgbWluMSA9IGRNaW5PY2N1cnMgKiBkQ2hpbGRyZW4uc2l6ZSgpOwotICAgICAgICAgICAgICAgICAgICAgICAgaW50IG1heDEgPSAoZE1heE9jY3VycyA9PSBTY2hlbWFTeW1ib2xzLk9DQ1VSUkVOQ0VfVU5CT1VOREVEKT8KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZE1heE9jY3VycyA6IGRNYXhPY2N1cnMgKiBkQ2hpbGRyZW4uc2l6ZSgpOwotICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tNYXBBbmRTdW0oZENoaWxkcmVuLCBtaW4xLCBtYXgxLCBkU0dIYW5kbGVyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiQ2hpbGRyZW4sIGJNaW5PY2N1cnMsIGJNYXhPY2N1cnMsIGJTR0hhbmRsZXIpOwotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGJFeHBhbnNpb25IYXBwZW5lZDsKLSAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgIGNhc2UgWFNQYXJ0aWNsZURlY2wuUEFSVElDTEVfRUxFTUVOVDoKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFhNTFNjaGVtYUV4Y2VwdGlvbigiY29zLXBhcnRpY2xlLXJlc3RyaWN0LjIiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117InNlcTplbHQifSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWE1MU2NoZW1hRXhjZXB0aW9uKCJJbnRlcm5hbC1FcnJvciIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXsiaW4gcGFydGljbGVWYWxpZFJlc3RyaWN0aW9uIn0pOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gYkV4cGFuc2lvbkhhcHBlbmVkOwotICAgIH0KLQotICAgIHByaXZhdGUgc3RhdGljIHZvaWQgYWRkRWxlbWVudFRvUGFydGljbGVWZWN0b3IgKFZlY3RvciB2LCBYU0VsZW1lbnREZWNsIGQpICB7Ci0KLSAgICAgICAgWFNQYXJ0aWNsZURlY2wgcCA9IG5ldyBYU1BhcnRpY2xlRGVjbCgpOwotICAgICAgICBwLmZWYWx1ZSA9IGQ7Ci0gICAgICAgIHAuZlR5cGUgPSBYU1BhcnRpY2xlRGVjbC5QQVJUSUNMRV9FTEVNRU5UOwotICAgICAgICB2LmFkZEVsZW1lbnQocCk7Ci0KLSAgICB9Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBYU1BhcnRpY2xlRGVjbCBnZXROb25VbmFyeUdyb3VwKFhTUGFydGljbGVEZWNsIHApIHsKLQotICAgICAgICBpZiAocC5mVHlwZSA9PSBYU1BhcnRpY2xlRGVjbC5QQVJUSUNMRV9FTEVNRU5UIHx8Ci0gICAgICAgICAgICAgICAgcC5mVHlwZSA9PSBYU1BhcnRpY2xlRGVjbC5QQVJUSUNMRV9XSUxEQ0FSRCkKLSAgICAgICAgICAgIHJldHVybiBwOwotCi0gICAgICAgIGlmIChwLmZNaW5PY2N1cnM9PTEgJiYgcC5mTWF4T2NjdXJzPT0xICYmCi0gICAgICAgICAgICAgICAgcC5mVmFsdWUhPW51bGwgJiYgKChYU01vZGVsR3JvdXBJbXBsKXAuZlZhbHVlKS5mUGFydGljbGVDb3VudCA9PSAxKQotICAgICAgICAgICAgcmV0dXJuIGdldE5vblVuYXJ5R3JvdXAoKChYU01vZGVsR3JvdXBJbXBsKXAuZlZhbHVlKS5mUGFydGljbGVzWzBdKTsKLSAgICAgICAgZWxzZQotICAgICAgICAgICAgcmV0dXJuIHA7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBzdGF0aWMgVmVjdG9yIHJlbW92ZVBvaW50bGVzc0NoaWxkcmVuKFhTUGFydGljbGVEZWNsIHApICB7Ci0KLSAgICAgICAgaWYgKHAuZlR5cGUgPT0gWFNQYXJ0aWNsZURlY2wuUEFSVElDTEVfRUxFTUVOVCB8fAotICAgICAgICAgICAgICAgIHAuZlR5cGUgPT0gWFNQYXJ0aWNsZURlY2wuUEFSVElDTEVfV0lMRENBUkQpCi0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLQotICAgICAgICBWZWN0b3IgY2hpbGRyZW4gPSBuZXcgVmVjdG9yKCk7Ci0KLSAgICAgICAgWFNNb2RlbEdyb3VwSW1wbCBncm91cCA9IChYU01vZGVsR3JvdXBJbXBsKXAuZlZhbHVlOwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGdyb3VwLmZQYXJ0aWNsZUNvdW50OyBpKyspCi0gICAgICAgICAgICBnYXRoZXJDaGlsZHJlbihncm91cC5mQ29tcG9zaXRvciwgZ3JvdXAuZlBhcnRpY2xlc1tpXSwgY2hpbGRyZW4pOwotCi0gICAgICAgIHJldHVybiBjaGlsZHJlbjsKLSAgICB9Ci0KLQotICAgIHByaXZhdGUgc3RhdGljIHZvaWQgZ2F0aGVyQ2hpbGRyZW4oaW50IHBhcmVudFR5cGUsIFhTUGFydGljbGVEZWNsIHAsIFZlY3RvciBjaGlsZHJlbikgewotCi0gICAgICAgIGludCBtaW4gPSBwLmZNaW5PY2N1cnM7Ci0gICAgICAgIGludCBtYXggPSBwLmZNYXhPY2N1cnM7Ci0gICAgICAgIGludCB0eXBlID0gcC5mVHlwZTsKLSAgICAgICAgaWYgKHR5cGUgPT0gWFNQYXJ0aWNsZURlY2wuUEFSVElDTEVfTU9ERUxHUk9VUCkKLSAgICAgICAgICAgIHR5cGUgPSAoKFhTTW9kZWxHcm91cEltcGwpcC5mVmFsdWUpLmZDb21wb3NpdG9yOwotCi0gICAgICAgIGlmICh0eXBlID09IFhTUGFydGljbGVEZWNsLlBBUlRJQ0xFX0VMRU1FTlQgfHwKLSAgICAgICAgICAgICAgICB0eXBlPT0gWFNQYXJ0aWNsZURlY2wuUEFSVElDTEVfV0lMRENBUkQpIHsKLSAgICAgICAgICAgIGNoaWxkcmVuLmFkZEVsZW1lbnQocCk7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoISAobWluPT0xICYmIG1heD09MSkpIHsKLSAgICAgICAgICAgIGNoaWxkcmVuLmFkZEVsZW1lbnQocCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAocGFyZW50VHlwZSA9PSB0eXBlKSB7Ci0gICAgICAgICAgICBYU01vZGVsR3JvdXBJbXBsIGdyb3VwID0gKFhTTW9kZWxHcm91cEltcGwpcC5mVmFsdWU7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGdyb3VwLmZQYXJ0aWNsZUNvdW50OyBpKyspCi0gICAgICAgICAgICAgICAgZ2F0aGVyQ2hpbGRyZW4odHlwZSwgZ3JvdXAuZlBhcnRpY2xlc1tpXSwgY2hpbGRyZW4pOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKCFwLmlzRW1wdHkoKSkgewotICAgICAgICAgICAgY2hpbGRyZW4uYWRkRWxlbWVudChwKTsKLSAgICAgICAgfQotCi0gICAgfQotCi0gICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBjaGVja05hbWVBbmRUeXBlT0soWFNFbGVtZW50RGVjbCBkRWxlbWVudCwgaW50IGRNaW4sIGludCBkTWF4LAotICAgICAgICAgICAgWFNFbGVtZW50RGVjbCBiRWxlbWVudCwgaW50IGJNaW4sIGludCBiTWF4KQotICAgICAgICB0aHJvd3MgWE1MU2NoZW1hRXhjZXB0aW9uIHsKLQotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIENoZWNrIHRoYXQgdGhlIG5hbWVzIGFyZSB0aGUgc2FtZQotICAgICAgICAvLwotICAgICAgICBpZiAoZEVsZW1lbnQuZk5hbWUgIT0gYkVsZW1lbnQuZk5hbWUgfHwKLSAgICAgICAgICAgICAgICBkRWxlbWVudC5mVGFyZ2V0TmFtZXNwYWNlICE9IGJFbGVtZW50LmZUYXJnZXROYW1lc3BhY2UpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBYTUxTY2hlbWFFeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgICJyY2FzZS1OYW1lQW5kVHlwZU9LLjEiLG5ldyBPYmplY3RbXXtkRWxlbWVudC5mTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBkRWxlbWVudC5mVGFyZ2V0TmFtZXNwYWNlLCBiRWxlbWVudC5mTmFtZSwgYkVsZW1lbnQuZlRhcmdldE5hbWVzcGFjZX0pOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gQ2hlY2sgbmlsbGFibGUKLSAgICAgICAgLy8KLSAgICAgICAgaWYgKCFiRWxlbWVudC5nZXROaWxsYWJsZSgpICYmIGRFbGVtZW50LmdldE5pbGxhYmxlKCkpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBYTUxTY2hlbWFFeGNlcHRpb24oInJjYXNlLU5hbWVBbmRUeXBlT0suMiIsCi0gICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXtkRWxlbWVudC5mTmFtZX0pOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gQ2hlY2sgb2NjdXJyZW5jZSByYW5nZQotICAgICAgICAvLwotICAgICAgICBpZiAoIWNoZWNrT2NjdXJyZW5jZVJhbmdlKGRNaW4sIGRNYXgsIGJNaW4sIGJNYXgpKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWE1MU2NoZW1hRXhjZXB0aW9uKCJyY2FzZS1OYW1lQW5kVHlwZU9LLjMiLAotICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117Ci0gICAgICAgICAgICAgICAgICAgIGRFbGVtZW50LmZOYW1lLAotICAgICAgICAgICAgICAgICAgICBJbnRlZ2VyLnRvU3RyaW5nKGRNaW4pLAotICAgICAgICAgICAgICAgICAgICBkTWF4PT1TY2hlbWFTeW1ib2xzLk9DQ1VSUkVOQ0VfVU5CT1VOREVEPyJ1bmJvdW5kZWQiOkludGVnZXIudG9TdHJpbmcoZE1heCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgSW50ZWdlci50b1N0cmluZyhiTWluKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBiTWF4PT1TY2hlbWFTeW1ib2xzLk9DQ1VSUkVOQ0VfVU5CT1VOREVEPyJ1bmJvdW5kZWQiOkludGVnZXIudG9TdHJpbmcoYk1heCl9KTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIENoZWNrIGZvciBjb25zaXN0ZW50IGZpeGVkIHZhbHVlcwotICAgICAgICAvLwotICAgICAgICBpZiAoYkVsZW1lbnQuZ2V0Q29uc3RyYWludFR5cGUoKSA9PSBYU0NvbnN0YW50cy5WQ19GSVhFRCkgewotICAgICAgICAgICAgLy8gZGVyaXZlZCBvbmUgaGFzIHRvIGhhdmUgYSBmaXhlZCB2YWx1ZQotICAgICAgICAgICAgaWYgKGRFbGVtZW50LmdldENvbnN0cmFpbnRUeXBlKCkgIT0gWFNDb25zdGFudHMuVkNfRklYRUQpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWE1MU2NoZW1hRXhjZXB0aW9uKCJyY2FzZS1OYW1lQW5kVHlwZU9LLjQuYSIsCi0gICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117ZEVsZW1lbnQuZk5hbWUsIGJFbGVtZW50LmZEZWZhdWx0LnN0cmluZ1ZhbHVlKCl9KTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gZ2V0IHNpbXBsZSB0eXBlCi0gICAgICAgICAgICBib29sZWFuIGlzU2ltcGxlID0gZmFsc2U7Ci0gICAgICAgICAgICBpZiAoZEVsZW1lbnQuZlR5cGUuZ2V0VHlwZUNhdGVnb3J5KCkgPT0gWFNUeXBlRGVmaW5pdGlvbi5TSU1QTEVfVFlQRSB8fAotICAgICAgICAgICAgICAgICAgICAoKFhTQ29tcGxleFR5cGVEZWNsKWRFbGVtZW50LmZUeXBlKS5mQ29udGVudFR5cGUgPT0gWFNDb21wbGV4VHlwZURlY2wuQ09OVEVOVFRZUEVfU0lNUExFKSB7Ci0gICAgICAgICAgICAgICAgaXNTaW1wbGUgPSB0cnVlOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBpZiB0aGVyZSBpcyBubyBzaW1wbGUgdHlwZSwgdGhlbiBjb21wYXJlIGJhc2VkIG9uIHN0cmluZwotICAgICAgICAgICAgaWYgKCFpc1NpbXBsZSAmJiAhYkVsZW1lbnQuZkRlZmF1bHQubm9ybWFsaXplZFZhbHVlLmVxdWFscyhkRWxlbWVudC5mRGVmYXVsdC5ub3JtYWxpemVkVmFsdWUpIHx8Ci0gICAgICAgICAgICAgICAgICAgIGlzU2ltcGxlICYmICFiRWxlbWVudC5mRGVmYXVsdC5hY3R1YWxWYWx1ZS5lcXVhbHMoZEVsZW1lbnQuZkRlZmF1bHQuYWN0dWFsVmFsdWUpKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFhNTFNjaGVtYUV4Y2VwdGlvbigicmNhc2UtTmFtZUFuZFR5cGVPSy40LmIiLAotICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde2RFbGVtZW50LmZOYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgZEVsZW1lbnQuZkRlZmF1bHQuc3RyaW5nVmFsdWUoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgIGJFbGVtZW50LmZEZWZhdWx0LnN0cmluZ1ZhbHVlKCl9KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIENoZWNrIGlkZW50aXR5IGNvbnN0cmFpbnRzCi0gICAgICAgIC8vCi0gICAgICAgIGNoZWNrSURDb25zdHJhaW50UmVzdHJpY3Rpb24oZEVsZW1lbnQsIGJFbGVtZW50KTsKLQotICAgICAgICAvLwotICAgICAgICAvLyBDaGVjayBmb3IgZGlzYWxsb3dlZCBzdWJzdGl0dXRpb25zCi0gICAgICAgIC8vCi0gICAgICAgIGludCBibG9ja1NldDEgPSBkRWxlbWVudC5mQmxvY2s7Ci0gICAgICAgIGludCBibG9ja1NldDIgPSBiRWxlbWVudC5mQmxvY2s7Ci0gICAgICAgIGlmICgoKGJsb2NrU2V0MSAmIGJsb2NrU2V0MikhPWJsb2NrU2V0MikgfHwKLSAgICAgICAgICAgICAgICAoYmxvY2tTZXQxPT1YU0NvbnN0YW50cy5ERVJJVkFUSU9OX05PTkUgJiYgYmxvY2tTZXQyIT1YU0NvbnN0YW50cy5ERVJJVkFUSU9OX05PTkUpKQotICAgICAgICAgICAgdGhyb3cgbmV3IFhNTFNjaGVtYUV4Y2VwdGlvbigicmNhc2UtTmFtZUFuZFR5cGVPSy42IiwKLSAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde2RFbGVtZW50LmZOYW1lfSk7Ci0KLQotICAgICAgICAvLwotICAgICAgICAvLyBDaGVjayB0aGF0IHRoZSBkZXJpdmVkIGVsZW1lbnQncyB0eXBlIGlzIGRlcml2ZWQgZnJvbSB0aGUgYmFzZSdzLgotICAgICAgICAvLwotICAgICAgICBpZiAoIWNoZWNrVHlwZURlcml2YXRpb25PayhkRWxlbWVudC5mVHlwZSwgYkVsZW1lbnQuZlR5cGUsCi0gICAgICAgICAgICAgICAgKHNob3J0KShYU0NvbnN0YW50cy5ERVJJVkFUSU9OX0VYVEVOU0lPTnxYU0NvbnN0YW50cy5ERVJJVkFUSU9OX0xJU1R8WFNDb25zdGFudHMuREVSSVZBVElPTl9VTklPTikpKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWE1MU2NoZW1hRXhjZXB0aW9uKCJyY2FzZS1OYW1lQW5kVHlwZU9LLjciLAotICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117ZEVsZW1lbnQuZk5hbWUsIGRFbGVtZW50LmZUeXBlLmdldE5hbWUoKSwgYkVsZW1lbnQuZlR5cGUuZ2V0TmFtZSgpfSk7Ci0gICAgICAgIH0KLQotICAgIH0KLQotCi0gICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBjaGVja0lEQ29uc3RyYWludFJlc3RyaWN0aW9uKFhTRWxlbWVudERlY2wgZGVyaXZlZEVsZW1EZWNsLAotICAgICAgICAgICAgWFNFbGVtZW50RGVjbCBiYXNlRWxlbURlY2wpCi0gICAgICAgIHRocm93cyBYTUxTY2hlbWFFeGNlcHRpb24gewotICAgICAgICAvLyBUT0RPCi0gICAgfSAvLyBjaGVja0lEQ29uc3RyYWludFJlc3RyaWN0aW9uCi0KLQotICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gY2hlY2tPY2N1cnJlbmNlUmFuZ2UoaW50IG1pbjEsIGludCBtYXgxLCBpbnQgbWluMiwgaW50IG1heDIpIHsKLQotICAgICAgICBpZiAoKG1pbjEgPj0gbWluMikgJiYKLSAgICAgICAgICAgICAgICAoKG1heDI9PVNjaGVtYVN5bWJvbHMuT0NDVVJSRU5DRV9VTkJPVU5ERUQpIHx8Ci0gICAgICAgICAgICAgICAgICAgICAgICAobWF4MSE9U2NoZW1hU3ltYm9scy5PQ0NVUlJFTkNFX1VOQk9VTkRFRCAmJiBtYXgxPD1tYXgyKSkpCi0gICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgZWxzZQotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIHByaXZhdGUgc3RhdGljIHZvaWQgY2hlY2tOU0NvbXBhdChYU0VsZW1lbnREZWNsIGVsZW0sIGludCBtaW4xLCBpbnQgbWF4MSwKLSAgICAgICAgICAgIFhTV2lsZGNhcmREZWNsIHdpbGRjYXJkLCBpbnQgbWluMiwgaW50IG1heDIsCi0gICAgICAgICAgICBib29sZWFuIGNoZWNrV0NPY2N1cnJlbmNlKQotICAgICAgICB0aHJvd3MgWE1MU2NoZW1hRXhjZXB0aW9uIHsKLQotICAgICAgICAvLyBjaGVjayBPY2N1cnJlbmNlIHJhbmdlcwotICAgICAgICBpZiAoY2hlY2tXQ09jY3VycmVuY2UgJiYgIWNoZWNrT2NjdXJyZW5jZVJhbmdlKG1pbjEsbWF4MSxtaW4yLG1heDIpKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWE1MU2NoZW1hRXhjZXB0aW9uKCJyY2FzZS1OU0NvbXBhdC4yIiwKLSAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdewotICAgICAgICAgICAgICAgICAgICBlbGVtLmZOYW1lLAotICAgICAgICAgICAgICAgICAgICBJbnRlZ2VyLnRvU3RyaW5nKG1pbjEpLAotICAgICAgICAgICAgICAgICAgICBtYXgxPT1TY2hlbWFTeW1ib2xzLk9DQ1VSUkVOQ0VfVU5CT1VOREVEPyJ1bmJvdW5kZWQiOkludGVnZXIudG9TdHJpbmcobWF4MSksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgSW50ZWdlci50b1N0cmluZyhtaW4yKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXgyPT1TY2hlbWFTeW1ib2xzLk9DQ1VSUkVOQ0VfVU5CT1VOREVEPyJ1bmJvdW5kZWQiOkludGVnZXIudG9TdHJpbmcobWF4Mil9KTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIGNoZWNrIHdpbGRjYXJkIGFsbG93cyBuYW1lc3BhY2Ugb2YgZWxlbWVudAotICAgICAgICBpZiAoIXdpbGRjYXJkLmFsbG93TmFtZXNwYWNlKGVsZW0uZlRhcmdldE5hbWVzcGFjZSkpICB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWE1MU2NoZW1hRXhjZXB0aW9uKCJyY2FzZS1OU0NvbXBhdC4xIiwKLSAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde2VsZW0uZk5hbWUsZWxlbS5mVGFyZ2V0TmFtZXNwYWNlfSk7Ci0gICAgICAgIH0KLQotICAgIH0KLQotICAgIHByaXZhdGUgc3RhdGljIHZvaWQgY2hlY2tOU1N1YnNldChYU1dpbGRjYXJkRGVjbCBkV2lsZGNhcmQsIGludCBtaW4xLCBpbnQgbWF4MSwKLSAgICAgICAgICAgIFhTV2lsZGNhcmREZWNsIGJXaWxkY2FyZCwgaW50IG1pbjIsIGludCBtYXgyKQotICAgICAgICB0aHJvd3MgWE1MU2NoZW1hRXhjZXB0aW9uIHsKLQotICAgICAgICAvLyBjaGVjayBPY2N1cnJlbmNlIHJhbmdlcwotICAgICAgICBpZiAoIWNoZWNrT2NjdXJyZW5jZVJhbmdlKG1pbjEsbWF4MSxtaW4yLG1heDIpKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWE1MU2NoZW1hRXhjZXB0aW9uKCJyY2FzZS1OU1N1YnNldC4yIiwgbmV3IE9iamVjdFtdewotICAgICAgICAgICAgICAgICAgICBJbnRlZ2VyLnRvU3RyaW5nKG1pbjEpLAotICAgICAgICAgICAgICAgICAgICBtYXgxPT1TY2hlbWFTeW1ib2xzLk9DQ1VSUkVOQ0VfVU5CT1VOREVEPyJ1bmJvdW5kZWQiOkludGVnZXIudG9TdHJpbmcobWF4MSksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgSW50ZWdlci50b1N0cmluZyhtaW4yKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXgyPT1TY2hlbWFTeW1ib2xzLk9DQ1VSUkVOQ0VfVU5CT1VOREVEPyJ1bmJvdW5kZWQiOkludGVnZXIudG9TdHJpbmcobWF4Mil9KTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIGNoZWNrIHdpbGRjYXJkIHN1YnNldAotICAgICAgICBpZiAoIWRXaWxkY2FyZC5pc1N1YnNldE9mKGJXaWxkY2FyZCkpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBYTUxTY2hlbWFFeGNlcHRpb24oInJjYXNlLU5TU3Vic2V0LjEiLCBudWxsKTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChkV2lsZGNhcmQud2Vha2VyUHJvY2Vzc0NvbnRlbnRzKGJXaWxkY2FyZCkpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBYTUxTY2hlbWFFeGNlcHRpb24oInJjYXNlLU5TU3Vic2V0LjMiLAotICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117ZFdpbGRjYXJkLmdldFByb2Nlc3NDb250ZW50c0FzU3RyaW5nKCksCi0gICAgICAgICAgICAgICAgICAgIGJXaWxkY2FyZC5nZXRQcm9jZXNzQ29udGVudHNBc1N0cmluZygpfSk7Ci0gICAgICAgIH0KLQotICAgIH0KLQotCi0gICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBjaGVja05TUmVjdXJzZUNoZWNrQ2FyZGluYWxpdHkoVmVjdG9yIGNoaWxkcmVuLCBpbnQgbWluMSwgaW50IG1heDEsCi0gICAgICAgICAgICBTdWJzdGl0dXRpb25Hcm91cEhhbmRsZXIgZFNHSGFuZGxlciwKLSAgICAgICAgICAgIFhTUGFydGljbGVEZWNsIHdpbGRjYXJkLCBpbnQgbWluMiwgaW50IG1heDIsCi0gICAgICAgICAgICBib29sZWFuIGNoZWNrV0NPY2N1cnJlbmNlKQotICAgICAgICB0aHJvd3MgWE1MU2NoZW1hRXhjZXB0aW9uIHsKLQotCi0gICAgICAgIC8vIGNoZWNrIE9jY3VycmVuY2UgcmFuZ2VzCi0gICAgICAgIGlmIChjaGVja1dDT2NjdXJyZW5jZSAmJiAhY2hlY2tPY2N1cnJlbmNlUmFuZ2UobWluMSxtYXgxLG1pbjIsbWF4MikpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBYTUxTY2hlbWFFeGNlcHRpb24oInJjYXNlLU5TUmVjdXJzZUNoZWNrQ2FyZGluYWxpdHkuMiIsIG5ldyBPYmplY3RbXXsKLSAgICAgICAgICAgICAgICAgICAgSW50ZWdlci50b1N0cmluZyhtaW4xKSwKLSAgICAgICAgICAgICAgICAgICAgbWF4MT09U2NoZW1hU3ltYm9scy5PQ0NVUlJFTkNFX1VOQk9VTkRFRD8idW5ib3VuZGVkIjpJbnRlZ2VyLnRvU3RyaW5nKG1heDEpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIEludGVnZXIudG9TdHJpbmcobWluMiksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF4Mj09U2NoZW1hU3ltYm9scy5PQ0NVUlJFTkNFX1VOQk9VTkRFRD8idW5ib3VuZGVkIjpJbnRlZ2VyLnRvU3RyaW5nKG1heDIpfSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBDaGVjayB0aGF0IGVhY2ggbWVtYmVyIG9mIHRoZSBncm91cCBpcyBhIHZhbGlkIHJlc3RyaWN0aW9uIG9mIHRoZSB3aWxkY2FyZAotICAgICAgICBpbnQgY291bnQgPSBjaGlsZHJlbi5zaXplKCk7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKLSAgICAgICAgICAgICAgICBYU1BhcnRpY2xlRGVjbCBwYXJ0aWNsZTEgPSAoWFNQYXJ0aWNsZURlY2wpY2hpbGRyZW4uZWxlbWVudEF0KGkpOwotICAgICAgICAgICAgICAgIHBhcnRpY2xlVmFsaWRSZXN0cmljdGlvbihwYXJ0aWNsZTEsIGRTR0hhbmRsZXIsIHdpbGRjYXJkLCBudWxsLCBmYWxzZSk7Ci0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICAvLyBSRVZJU0lUOiBzaG91bGQgd2UgcmVhbGx5IGp1c3QgaWdub3JlIG9yaWdpbmFsIGNhdXNlIG9mIHRoaXMgZXJyb3I/Ci0gICAgICAgIC8vICAgICAgICAgIGhvdyBjYW4gd2UgcmVwb3J0IGl0PwotICAgICAgICBjYXRjaCAoWE1MU2NoZW1hRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBYTUxTY2hlbWFFeGNlcHRpb24oInJjYXNlLU5TUmVjdXJzZUNoZWNrQ2FyZGluYWxpdHkuMSIsIG51bGwpOwotICAgICAgICB9Ci0KLSAgICB9Ci0KLSAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGNoZWNrUmVjdXJzZShWZWN0b3IgZENoaWxkcmVuLCBpbnQgbWluMSwgaW50IG1heDEsCi0gICAgICAgICAgICBTdWJzdGl0dXRpb25Hcm91cEhhbmRsZXIgZFNHSGFuZGxlciwKLSAgICAgICAgICAgIFZlY3RvciBiQ2hpbGRyZW4sIGludCBtaW4yLCBpbnQgbWF4MiwKLSAgICAgICAgICAgIFN1YnN0aXR1dGlvbkdyb3VwSGFuZGxlciBiU0dIYW5kbGVyKQotICAgICAgICB0aHJvd3MgWE1MU2NoZW1hRXhjZXB0aW9uIHsKLQotICAgICAgICAvLyBjaGVjayBPY2N1cnJlbmNlIHJhbmdlcwotICAgICAgICBpZiAoIWNoZWNrT2NjdXJyZW5jZVJhbmdlKG1pbjEsbWF4MSxtaW4yLG1heDIpKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWE1MU2NoZW1hRXhjZXB0aW9uKCJyY2FzZS1SZWN1cnNlLjEiLCBuZXcgT2JqZWN0W117Ci0gICAgICAgICAgICAgICAgICAgIEludGVnZXIudG9TdHJpbmcobWluMSksCi0gICAgICAgICAgICAgICAgICAgIG1heDE9PVNjaGVtYVN5bWJvbHMuT0NDVVJSRU5DRV9VTkJPVU5ERUQ/InVuYm91bmRlZCI6SW50ZWdlci50b1N0cmluZyhtYXgxKSwKLSAgICAgICAgICAgICAgICAgICAgSW50ZWdlci50b1N0cmluZyhtaW4yKSwKLSAgICAgICAgICAgICAgICAgICAgbWF4Mj09U2NoZW1hU3ltYm9scy5PQ0NVUlJFTkNFX1VOQk9VTkRFRD8idW5ib3VuZGVkIjpJbnRlZ2VyLnRvU3RyaW5nKG1heDIpfSk7Ci0gICAgICAgIH0KLQotICAgICAgICBpbnQgY291bnQxPSBkQ2hpbGRyZW4uc2l6ZSgpOwotICAgICAgICBpbnQgY291bnQyPSBiQ2hpbGRyZW4uc2l6ZSgpOwotCi0gICAgICAgIGludCBjdXJyZW50ID0gMDsKLSAgICAgICAgbGFiZWw6IGZvciAoaW50IGkgPSAwOyBpPGNvdW50MTsgaSsrKSB7Ci0KLSAgICAgICAgICAgIFhTUGFydGljbGVEZWNsIHBhcnRpY2xlMSA9IChYU1BhcnRpY2xlRGVjbClkQ2hpbGRyZW4uZWxlbWVudEF0KGkpOwotICAgICAgICAgICAgZm9yIChpbnQgaiA9IGN1cnJlbnQ7IGo8Y291bnQyOyBqKyspIHsKLSAgICAgICAgICAgICAgICBYU1BhcnRpY2xlRGVjbCBwYXJ0aWNsZTIgPSAoWFNQYXJ0aWNsZURlY2wpYkNoaWxkcmVuLmVsZW1lbnRBdChqKTsKLSAgICAgICAgICAgICAgICBjdXJyZW50ICs9MTsKLSAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICBwYXJ0aWNsZVZhbGlkUmVzdHJpY3Rpb24ocGFydGljbGUxLCBkU0dIYW5kbGVyLCBwYXJ0aWNsZTIsIGJTR0hhbmRsZXIpOwotICAgICAgICAgICAgICAgICAgICBjb250aW51ZSBsYWJlbDsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgY2F0Y2ggKFhNTFNjaGVtYUV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmICghcGFydGljbGUyLmVtcHRpYWJsZSgpKQotICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFhNTFNjaGVtYUV4Y2VwdGlvbigicmNhc2UtUmVjdXJzZS4yIiwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgdGhyb3cgbmV3IFhNTFNjaGVtYUV4Y2VwdGlvbigicmNhc2UtUmVjdXJzZS4yIiwgbnVsbCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBOb3csIHNlZSBpZiB0aGVyZSBhcmUgc29tZSBlbGVtZW50cyBpbiB0aGUgYmFzZSB3ZSBkaWRuJ3QgbWF0Y2ggdXAKLSAgICAgICAgZm9yIChpbnQgaj1jdXJyZW50OyBqIDwgY291bnQyOyBqKyspIHsKLSAgICAgICAgICAgIFhTUGFydGljbGVEZWNsIHBhcnRpY2xlMiA9IChYU1BhcnRpY2xlRGVjbCliQ2hpbGRyZW4uZWxlbWVudEF0KGopOwotICAgICAgICAgICAgaWYgKCFwYXJ0aWNsZTIuZW1wdGlhYmxlKCkpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWE1MU2NoZW1hRXhjZXB0aW9uKCJyY2FzZS1SZWN1cnNlLjIiLCBudWxsKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgfQotCi0gICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBjaGVja1JlY3Vyc2VVbm9yZGVyZWQoVmVjdG9yIGRDaGlsZHJlbiwgaW50IG1pbjEsIGludCBtYXgxLAotICAgICAgICAgICAgU3Vic3RpdHV0aW9uR3JvdXBIYW5kbGVyIGRTR0hhbmRsZXIsCi0gICAgICAgICAgICBWZWN0b3IgYkNoaWxkcmVuLCBpbnQgbWluMiwgaW50IG1heDIsCi0gICAgICAgICAgICBTdWJzdGl0dXRpb25Hcm91cEhhbmRsZXIgYlNHSGFuZGxlcikKLSAgICAgICAgdGhyb3dzIFhNTFNjaGVtYUV4Y2VwdGlvbiB7Ci0KLQotICAgICAgICAvLyBjaGVjayBPY2N1cnJlbmNlIHJhbmdlcwotICAgICAgICBpZiAoIWNoZWNrT2NjdXJyZW5jZVJhbmdlKG1pbjEsbWF4MSxtaW4yLG1heDIpKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWE1MU2NoZW1hRXhjZXB0aW9uKCJyY2FzZS1SZWN1cnNlVW5vcmRlcmVkLjEiLCBuZXcgT2JqZWN0W117Ci0gICAgICAgICAgICAgICAgICAgIEludGVnZXIudG9TdHJpbmcobWluMSksCi0gICAgICAgICAgICAgICAgICAgIG1heDE9PVNjaGVtYVN5bWJvbHMuT0NDVVJSRU5DRV9VTkJPVU5ERUQ/InVuYm91bmRlZCI6SW50ZWdlci50b1N0cmluZyhtYXgxKSwKLSAgICAgICAgICAgICAgICAgICAgSW50ZWdlci50b1N0cmluZyhtaW4yKSwKLSAgICAgICAgICAgICAgICAgICAgbWF4Mj09U2NoZW1hU3ltYm9scy5PQ0NVUlJFTkNFX1VOQk9VTkRFRD8idW5ib3VuZGVkIjpJbnRlZ2VyLnRvU3RyaW5nKG1heDIpfSk7Ci0gICAgICAgIH0KLQotICAgICAgICBpbnQgY291bnQxPSBkQ2hpbGRyZW4uc2l6ZSgpOwotICAgICAgICBpbnQgY291bnQyID0gYkNoaWxkcmVuLnNpemUoKTsKLQotICAgICAgICBib29sZWFuIGZvdW5kSXRbXSA9IG5ldyBib29sZWFuW2NvdW50Ml07Ci0KLSAgICAgICAgbGFiZWw6IGZvciAoaW50IGkgPSAwOyBpPGNvdW50MTsgaSsrKSB7Ci0gICAgICAgICAgICBYU1BhcnRpY2xlRGVjbCBwYXJ0aWNsZTEgPSAoWFNQYXJ0aWNsZURlY2wpZENoaWxkcmVuLmVsZW1lbnRBdChpKTsKLQotICAgICAgICAgICAgZm9yIChpbnQgaiA9IDA7IGo8Y291bnQyOyBqKyspIHsKLSAgICAgICAgICAgICAgICBYU1BhcnRpY2xlRGVjbCBwYXJ0aWNsZTIgPSAoWFNQYXJ0aWNsZURlY2wpYkNoaWxkcmVuLmVsZW1lbnRBdChqKTsKLSAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICBwYXJ0aWNsZVZhbGlkUmVzdHJpY3Rpb24ocGFydGljbGUxLCBkU0dIYW5kbGVyLCBwYXJ0aWNsZTIsIGJTR0hhbmRsZXIpOwotICAgICAgICAgICAgICAgICAgICBpZiAoZm91bmRJdFtqXSkKLSAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBYTUxTY2hlbWFFeGNlcHRpb24oInJjYXNlLVJlY3Vyc2VVbm9yZGVyZWQuMiIsIG51bGwpOwotICAgICAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgICAgICBmb3VuZEl0W2pdPXRydWU7Ci0KLSAgICAgICAgICAgICAgICAgICAgY29udGludWUgbGFiZWw7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGNhdGNoIChYTUxTY2hlbWFFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIGRpZG4ndCBmaW5kIGEgbWF0Y2guICBEZXRlY3QgYW4gZXJyb3IKLSAgICAgICAgICAgIHRocm93IG5ldyBYTUxTY2hlbWFFeGNlcHRpb24oInJjYXNlLVJlY3Vyc2VVbm9yZGVyZWQuMiIsIG51bGwpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gTm93LCBzZWUgaWYgdGhlcmUgYXJlIHNvbWUgZWxlbWVudHMgaW4gdGhlIGJhc2Ugd2UgZGlkbid0IG1hdGNoIHVwCi0gICAgICAgIGZvciAoaW50IGo9MDsgaiA8IGNvdW50MjsgaisrKSB7Ci0gICAgICAgICAgICBYU1BhcnRpY2xlRGVjbCBwYXJ0aWNsZTIgPSAoWFNQYXJ0aWNsZURlY2wpYkNoaWxkcmVuLmVsZW1lbnRBdChqKTsKLSAgICAgICAgICAgIGlmICghZm91bmRJdFtqXSAmJiAhcGFydGljbGUyLmVtcHRpYWJsZSgpKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFhNTFNjaGVtYUV4Y2VwdGlvbigicmNhc2UtUmVjdXJzZVVub3JkZXJlZC4yIiwgbnVsbCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgIH0KLQotICAgIHByaXZhdGUgc3RhdGljIHZvaWQgY2hlY2tSZWN1cnNlTGF4KFZlY3RvciBkQ2hpbGRyZW4sIGludCBtaW4xLCBpbnQgbWF4MSwKLSAgICAgICAgICAgIFN1YnN0aXR1dGlvbkdyb3VwSGFuZGxlciBkU0dIYW5kbGVyLAotICAgICAgICAgICAgVmVjdG9yIGJDaGlsZHJlbiwgaW50IG1pbjIsIGludCBtYXgyLAotICAgICAgICAgICAgU3Vic3RpdHV0aW9uR3JvdXBIYW5kbGVyICBiU0dIYW5kbGVyKQotICAgICAgICB0aHJvd3MgWE1MU2NoZW1hRXhjZXB0aW9uIHsKLQotICAgICAgICAvLyBjaGVjayBPY2N1cnJlbmNlIHJhbmdlcwotICAgICAgICBpZiAoIWNoZWNrT2NjdXJyZW5jZVJhbmdlKG1pbjEsbWF4MSxtaW4yLG1heDIpKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWE1MU2NoZW1hRXhjZXB0aW9uKCJyY2FzZS1SZWN1cnNlTGF4LjEiLCBuZXcgT2JqZWN0W117Ci0gICAgICAgICAgICAgICAgICAgIEludGVnZXIudG9TdHJpbmcobWluMSksCi0gICAgICAgICAgICAgICAgICAgIG1heDE9PVNjaGVtYVN5bWJvbHMuT0NDVVJSRU5DRV9VTkJPVU5ERUQ/InVuYm91bmRlZCI6SW50ZWdlci50b1N0cmluZyhtYXgxKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbnRlZ2VyLnRvU3RyaW5nKG1pbjIpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1heDI9PVNjaGVtYVN5bWJvbHMuT0NDVVJSRU5DRV9VTkJPVU5ERUQ/InVuYm91bmRlZCI6SW50ZWdlci50b1N0cmluZyhtYXgyKX0pOwotICAgICAgICB9Ci0KLSAgICAgICAgaW50IGNvdW50MT0gZENoaWxkcmVuLnNpemUoKTsKLSAgICAgICAgaW50IGNvdW50MiA9IGJDaGlsZHJlbi5zaXplKCk7Ci0KLSAgICAgICAgaW50IGN1cnJlbnQgPSAwOwotICAgICAgICBsYWJlbDogZm9yIChpbnQgaSA9IDA7IGk8Y291bnQxOyBpKyspIHsKLQotICAgICAgICAgICAgWFNQYXJ0aWNsZURlY2wgcGFydGljbGUxID0gKFhTUGFydGljbGVEZWNsKWRDaGlsZHJlbi5lbGVtZW50QXQoaSk7Ci0gICAgICAgICAgICBmb3IgKGludCBqID0gY3VycmVudDsgajxjb3VudDI7IGorKykgewotICAgICAgICAgICAgICAgIFhTUGFydGljbGVEZWNsIHBhcnRpY2xlMiA9IChYU1BhcnRpY2xlRGVjbCliQ2hpbGRyZW4uZWxlbWVudEF0KGopOwotICAgICAgICAgICAgICAgIGN1cnJlbnQgKz0xOwotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIElIUjogZ28gYmFjayBvbmUgZWxlbWVudCBvbiBiIGxpc3QgYmVjYXVzZSB0aGUgbmV4dCBlbGVtZW50IG1heSBtYXRjaAotICAgICAgICAgICAgICAgICAgICAvLyB0aGlzIGFzIHdlbGwuCi0gICAgICAgICAgICAgICAgICAgIGlmIChwYXJ0aWNsZVZhbGlkUmVzdHJpY3Rpb24ocGFydGljbGUxLCBkU0dIYW5kbGVyLCBwYXJ0aWNsZTIsIGJTR0hhbmRsZXIpKQotICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudC0tOwotICAgICAgICAgICAgICAgICAgICBjb250aW51ZSBsYWJlbDsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgY2F0Y2ggKFhNTFNjaGVtYUV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gZGlkbid0IGZpbmQgYSBtYXRjaC4gIERldGVjdCBhbiBlcnJvcgotICAgICAgICAgICAgdGhyb3cgbmV3IFhNTFNjaGVtYUV4Y2VwdGlvbigicmNhc2UtUmVjdXJzZUxheC4yIiwgbnVsbCk7Ci0KLSAgICAgICAgfQotCi0gICAgfQotCi0gICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBjaGVja01hcEFuZFN1bShWZWN0b3IgZENoaWxkcmVuLCBpbnQgbWluMSwgaW50IG1heDEsCi0gICAgICAgICAgICBTdWJzdGl0dXRpb25Hcm91cEhhbmRsZXIgZFNHSGFuZGxlciwKLSAgICAgICAgICAgIFZlY3RvciBiQ2hpbGRyZW4sIGludCBtaW4yLCBpbnQgbWF4MiwKLSAgICAgICAgICAgIFN1YnN0aXR1dGlvbkdyb3VwSGFuZGxlciBiU0dIYW5kbGVyKQotICAgICAgICB0aHJvd3MgWE1MU2NoZW1hRXhjZXB0aW9uIHsKLQotICAgICAgICAvLyBTZWUgaWYgdGhlIHNlcXVlbmNlIGdyb3VwIGlzIGEgdmFsaWQgcmVzdHJpY3Rpb24gb2YgdGhlIGNob2ljZQotCi0gICAgICAgIC8vIEhlcmUgaXMgYW4gZXhhbXBsZSBvZiBhIHZhbGlkIHJlc3RyaWN0aW9uOgotICAgICAgICAvLyAgIDxjaG9pY2UgbWluT2NjdXJzPSIyIj4KLSAgICAgICAgLy8gICAgICAgPGEvPgotICAgICAgICAvLyAgICAgICA8Yi8+Ci0gICAgICAgIC8vICAgICAgIDxjLz4KLSAgICAgICAgLy8gICA8L2Nob2ljZT4KLSAgICAgICAgLy8KLSAgICAgICAgLy8gICA8c2VxdWVuY2U+Ci0gICAgICAgIC8vICAgICAgICA8Yi8+Ci0gICAgICAgIC8vICAgICAgICA8YS8+Ci0gICAgICAgIC8vICAgPC9zZXF1ZW5jZT4KLQotICAgICAgICAvLyBjaGVjayBPY2N1cnJlbmNlIHJhbmdlcwotICAgICAgICBpZiAoIWNoZWNrT2NjdXJyZW5jZVJhbmdlKG1pbjEsbWF4MSxtaW4yLG1heDIpKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWE1MU2NoZW1hRXhjZXB0aW9uKCJyY2FzZS1NYXBBbmRTdW0uMiIsCi0gICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXtJbnRlZ2VyLnRvU3RyaW5nKG1pbjEpLAotICAgICAgICAgICAgICAgICAgICBtYXgxPT1TY2hlbWFTeW1ib2xzLk9DQ1VSUkVOQ0VfVU5CT1VOREVEPyJ1bmJvdW5kZWQiOkludGVnZXIudG9TdHJpbmcobWF4MSksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgSW50ZWdlci50b1N0cmluZyhtaW4yKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXgyPT1TY2hlbWFTeW1ib2xzLk9DQ1VSUkVOQ0VfVU5CT1VOREVEPyJ1bmJvdW5kZWQiOkludGVnZXIudG9TdHJpbmcobWF4Mil9KTsKLSAgICAgICAgfQotCi0gICAgICAgIGludCBjb3VudDEgPSBkQ2hpbGRyZW4uc2l6ZSgpOwotICAgICAgICBpbnQgY291bnQyID0gYkNoaWxkcmVuLnNpemUoKTsKLQotICAgICAgICBsYWJlbDogZm9yIChpbnQgaSA9IDA7IGk8Y291bnQxOyBpKyspIHsKLQotICAgICAgICAgICAgWFNQYXJ0aWNsZURlY2wgcGFydGljbGUxID0gKFhTUGFydGljbGVEZWNsKWRDaGlsZHJlbi5lbGVtZW50QXQoaSk7Ci0gICAgICAgICAgICBmb3IgKGludCBqID0gMDsgajxjb3VudDI7IGorKykgewotICAgICAgICAgICAgICAgIFhTUGFydGljbGVEZWNsIHBhcnRpY2xlMiA9IChYU1BhcnRpY2xlRGVjbCliQ2hpbGRyZW4uZWxlbWVudEF0KGopOwotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgIHBhcnRpY2xlVmFsaWRSZXN0cmljdGlvbihwYXJ0aWNsZTEsIGRTR0hhbmRsZXIsIHBhcnRpY2xlMiwgYlNHSGFuZGxlcik7Ci0gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlIGxhYmVsOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBjYXRjaCAoWE1MU2NoZW1hRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyBkaWRuJ3QgZmluZCBhIG1hdGNoLiAgRGV0ZWN0IGFuIGVycm9yCi0gICAgICAgICAgICB0aHJvdyBuZXcgWE1MU2NoZW1hRXhjZXB0aW9uKCJyY2FzZS1NYXBBbmRTdW0uMSIsIG51bGwpOwotICAgICAgICB9Ci0gICAgfQotICAgIC8vIHRvIGNoZWNrIHdoZXRoZXIgdHdvIGVsZW1lbnQgb3ZlcmxhcCwgYXMgZGVmaW5lZCBpbiBjb25zdHJhaW50IFVQQQotICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBvdmVybGFwVVBBKFhTRWxlbWVudERlY2wgZWxlbWVudDEsCi0gICAgICAgICAgICBYU0VsZW1lbnREZWNsIGVsZW1lbnQyLAotICAgICAgICAgICAgU3Vic3RpdHV0aW9uR3JvdXBIYW5kbGVyIHNnSGFuZGxlcikgewotICAgICAgICAvLyBpZiB0aGUgdHdvIGVsZW1lbnQgaGF2ZSB0aGUgc2FtZSBuYW1lIGFuZCBuYW1lc3BhY2UsCi0gICAgICAgIGlmIChlbGVtZW50MS5mTmFtZSA9PSBlbGVtZW50Mi5mTmFtZSAmJgotICAgICAgICAgICAgICAgIGVsZW1lbnQxLmZUYXJnZXROYW1lc3BhY2UgPT0gZWxlbWVudDIuZlRhcmdldE5hbWVzcGFjZSkgewotICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBvciBpZiB0aGVyZSBpcyBhbiBlbGVtZW50IGRlY2wgaW4gZWxlbWVudDEncyBzdWJzdGl0dXRpb24gZ3JvdXAsCi0gICAgICAgIC8vIHdobyBoYXMgdGhlIHNhbWUgbmFtZS9uYW1lc3BhY2Ugd2l0aCBlbGVtZW50MgotICAgICAgICBYU0VsZW1lbnREZWNsW10gc3ViR3JvdXAgPSBzZ0hhbmRsZXIuZ2V0U3Vic3RpdHV0aW9uR3JvdXAoZWxlbWVudDEpOwotICAgICAgICBmb3IgKGludCBpID0gc3ViR3JvdXAubGVuZ3RoLTE7IGkgPj0gMDsgaS0tKSB7Ci0gICAgICAgICAgICBpZiAoc3ViR3JvdXBbaV0uZk5hbWUgPT0gZWxlbWVudDIuZk5hbWUgJiYKLSAgICAgICAgICAgICAgICAgICAgc3ViR3JvdXBbaV0uZlRhcmdldE5hbWVzcGFjZSA9PSBlbGVtZW50Mi5mVGFyZ2V0TmFtZXNwYWNlKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBvciBpZiB0aGVyZSBpcyBhbiBlbGVtZW50IGRlY2wgaW4gZWxlbWVudDIncyBzdWJzdGl0dXRpb24gZ3JvdXAsCi0gICAgICAgIC8vIHdobyBoYXMgdGhlIHNhbWUgbmFtZS9uYW1lc3BhY2Ugd2l0aCBlbGVtZW50MQotICAgICAgICBzdWJHcm91cCA9IHNnSGFuZGxlci5nZXRTdWJzdGl0dXRpb25Hcm91cChlbGVtZW50Mik7Ci0gICAgICAgIGZvciAoaW50IGkgPSBzdWJHcm91cC5sZW5ndGgtMTsgaSA+PSAwOyBpLS0pIHsKLSAgICAgICAgICAgIGlmIChzdWJHcm91cFtpXS5mTmFtZSA9PSBlbGVtZW50MS5mTmFtZSAmJgotICAgICAgICAgICAgICAgICAgICBzdWJHcm91cFtpXS5mVGFyZ2V0TmFtZXNwYWNlID09IGVsZW1lbnQxLmZUYXJnZXROYW1lc3BhY2UpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICAvLyB0byBjaGVjayB3aGV0aGVyIGFuIGVsZW1lbnQgb3ZlcmxhcHMgd2l0aCBhIHdpbGRjYXJkLAotICAgIC8vIGFzIGRlZmluZWQgaW4gY29uc3RyYWludCBVUEEKLSAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gb3ZlcmxhcFVQQShYU0VsZW1lbnREZWNsIGVsZW1lbnQsCi0gICAgICAgICAgICBYU1dpbGRjYXJkRGVjbCB3aWxkY2FyZCwKLSAgICAgICAgICAgIFN1YnN0aXR1dGlvbkdyb3VwSGFuZGxlciBzZ0hhbmRsZXIpIHsKLSAgICAgICAgLy8gaWYgdGhlIHdpbGRjYXJkIGFsbG93cyB0aGUgZWxlbWVudAotICAgICAgICBpZiAod2lsZGNhcmQuYWxsb3dOYW1lc3BhY2UoZWxlbWVudC5mVGFyZ2V0TmFtZXNwYWNlKSkKLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotCi0gICAgICAgIC8vIG9yIGlmIHRoZSB3aWxkY2FyZCBhbGxvd3MgYW55IGVsZW1lbnQgaW4gdGhlIHN1YnN0aXR1dGlvbiBncm91cAotICAgICAgICBYU0VsZW1lbnREZWNsW10gc3ViR3JvdXAgPSBzZ0hhbmRsZXIuZ2V0U3Vic3RpdHV0aW9uR3JvdXAoZWxlbWVudCk7Ci0gICAgICAgIGZvciAoaW50IGkgPSBzdWJHcm91cC5sZW5ndGgtMTsgaSA+PSAwOyBpLS0pIHsKLSAgICAgICAgICAgIGlmICh3aWxkY2FyZC5hbGxvd05hbWVzcGFjZShzdWJHcm91cFtpXS5mVGFyZ2V0TmFtZXNwYWNlKSkKLSAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gb3ZlcmxhcFVQQShYU1dpbGRjYXJkRGVjbCB3aWxkY2FyZDEsCi0gICAgICAgICAgICBYU1dpbGRjYXJkRGVjbCB3aWxkY2FyZDIpIHsKLSAgICAgICAgLy8gaWYgdGhlIGludGVyc2VjdGlvbiBvZiB0aGUgdHdvIHdpbGRjYXJkIGlzIG5vdCBlbXB0eSBsaXN0Ci0gICAgICAgIFhTV2lsZGNhcmREZWNsIGludGVyc2VjdCA9IHdpbGRjYXJkMS5wZXJmb3JtSW50ZXJzZWN0aW9uV2l0aCh3aWxkY2FyZDIsIHdpbGRjYXJkMS5mUHJvY2Vzc0NvbnRlbnRzKTsKLSAgICAgICAgaWYgKGludGVyc2VjdCA9PSBudWxsIHx8Ci0gICAgICAgICAgICAgICAgaW50ZXJzZWN0LmZUeXBlICE9IFhTV2lsZGNhcmREZWNsLk5TQ09OU1RSQUlOVF9MSVNUIHx8Ci0gICAgICAgICAgICAgICAgaW50ZXJzZWN0LmZOYW1lc3BhY2VMaXN0Lmxlbmd0aCAhPSAwKSB7Ci0gICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICAvLyBjYWxsIG9uZSBvZiB0aGUgYWJvdmUgbWV0aG9kcyBhY2NvcmRpbmcgdG8gdGhlIHR5cGUgb2YgZGVjbHMKLSAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gb3ZlcmxhcFVQQShPYmplY3QgZGVjbDEsIE9iamVjdCBkZWNsMiwKLSAgICAgICAgICAgIFN1YnN0aXR1dGlvbkdyb3VwSGFuZGxlciBzZ0hhbmRsZXIpIHsKLSAgICAgICAgaWYgKGRlY2wxIGluc3RhbmNlb2YgWFNFbGVtZW50RGVjbCkgewotICAgICAgICAgICAgaWYgKGRlY2wyIGluc3RhbmNlb2YgWFNFbGVtZW50RGVjbCkgewotICAgICAgICAgICAgICAgIHJldHVybiBvdmVybGFwVVBBKChYU0VsZW1lbnREZWNsKWRlY2wxLAotICAgICAgICAgICAgICAgICAgICAgICAgKFhTRWxlbWVudERlY2wpZGVjbDIsCi0gICAgICAgICAgICAgICAgICAgICAgICBzZ0hhbmRsZXIpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIG92ZXJsYXBVUEEoKFhTRWxlbWVudERlY2wpZGVjbDEsCi0gICAgICAgICAgICAgICAgICAgICAgICAoWFNXaWxkY2FyZERlY2wpZGVjbDIsCi0gICAgICAgICAgICAgICAgICAgICAgICBzZ0hhbmRsZXIpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgaWYgKGRlY2wyIGluc3RhbmNlb2YgWFNFbGVtZW50RGVjbCkgewotICAgICAgICAgICAgICAgIHJldHVybiBvdmVybGFwVVBBKChYU0VsZW1lbnREZWNsKWRlY2wyLAotICAgICAgICAgICAgICAgICAgICAgICAgKFhTV2lsZGNhcmREZWNsKWRlY2wxLAotICAgICAgICAgICAgICAgICAgICAgICAgc2dIYW5kbGVyKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIHJldHVybiBvdmVybGFwVVBBKChYU1dpbGRjYXJkRGVjbClkZWNsMSwKLSAgICAgICAgICAgICAgICAgICAgICAgIChYU1dpbGRjYXJkRGVjbClkZWNsMik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLX0gLy8gY2xhc3MgWFNDb250cmFpbnRzCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL1hTRERlc2NyaXB0aW9uLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL1hTRERlc2NyaXB0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGMzNWJhYTguLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9YU0REZXNjcmlwdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjc0ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDIsIDIwMDMsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlhNTFJlc291cmNlSWRlbnRpZmllckltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuUU5hbWU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MQXR0cmlidXRlczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5ncmFtbWFycy5YTUxHcmFtbWFyRGVzY3JpcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuZ3JhbW1hcnMuWE1MU2NoZW1hRGVzY3JpcHRpb247Ci0KLS8qKgotICogQWxsIGluZm9ybWF0aW9uIHNwZWNpZmljIHRvIFhNTCBTY2hlbWEgZ3JhbW1hcnMuCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgTmVpbCBHcmFoYW0sIElCTQotICogQGF1dGhvciBOZWVyYWogQmFqYWosIFNVTiBNaWNyb3N5c3RlbXMuCi0gKgotICogQHZlcnNpb24gJElkOiBYU0REZXNjcmlwdGlvbi5qYXZhLHYgMS42IDIwMTAtMTEtMDEgMDQ6Mzk6NTUgam9laHcgRXhwICQKLSAqLwotcHVibGljIGNsYXNzIFhTRERlc2NyaXB0aW9uIGV4dGVuZHMgWE1MUmVzb3VyY2VJZGVudGlmaWVySW1wbAotICAgICAgICAgICAgICAgIGltcGxlbWVudHMgWE1MU2NoZW1hRGVzY3JpcHRpb24gewotICAgIC8vIHVzZWQgdG8gaW5kaWNhdGUgd2hhdCB0cmlnZ2VyZWQgdGhlIGNhbGwKLSAgICAvKioKLSAgICAgKiBJbmRpY2F0ZSB0aGF0IHRoaXMgZGVzY3JpcHRpb24gd2FzIGp1c3QgaW5pdGlhbGl6ZWQuCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIHN0YXRpYyBzaG9ydCBDT05URVhUX0lOSVRJQUxJWkUgPSAtMTsKLSAgICAvKioKLSAgICAgKiBJbmRpY2F0ZSB0aGF0IHRoZSBjdXJyZW50IHNjaGVtYSBkb2N1bWVudCBpcyA8aW5jbHVkZT5kIGJ5IGFub3RoZXIKLSAgICAgKiBzY2hlbWEgZG9jdW1lbnQuCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIHN0YXRpYyBzaG9ydCBDT05URVhUX0lOQ0xVREUgICA9IDA7Ci0gICAgLyoqCi0gICAgICogSW5kaWNhdGUgdGhhdCB0aGUgY3VycmVudCBzY2hlbWEgZG9jdW1lbnQgaXMgPHJlZGVmaW5lPmQgYnkgYW5vdGhlcgotICAgICAqIHNjaGVtYSBkb2N1bWVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgZmluYWwgc3RhdGljIHNob3J0IENPTlRFWFRfUkVERUZJTkUgID0gMTsKLSAgICAvKioKLSAgICAgKiBJbmRpY2F0ZSB0aGF0IHRoZSBjdXJyZW50IHNjaGVtYSBkb2N1bWVudCBpcyA8aW1wb3J0PmVkIGJ5IGFub3RoZXIKLSAgICAgKiBzY2hlbWEgZG9jdW1lbnQuCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIHN0YXRpYyBzaG9ydCBDT05URVhUX0lNUE9SVCAgICA9IDI7Ci0gICAgLyoqCi0gICAgICogSW5kaWNhdGUgdGhhdCB0aGUgY3VycmVudCBzY2hlbWEgZG9jdW1lbnQgaXMgYmVpbmcgcHJlcGFyc2VkLgotICAgICAqLwotICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgc2hvcnQgQ09OVEVYVF9QUkVQQVJTRSAgPSAzOwotICAgIC8qKgotICAgICAqIEluZGljYXRlIHRoYXQgdGhlIHBhcnNlIG9mIHRoZSBjdXJyZW50IHNjaGVtYSBkb2N1bWVudCBpcyB0cmlnZ2VyZWQKLSAgICAgKiBieSB4c2k6c2NoZW1hTG9jYXRpb24vbm9OYW1lc3BhY2VTY2hlbWFMb2NhdGlvbiBhdHRyaWJ1dGUocykgaW4gdGhlCi0gICAgICogaW5zdGFuY2UgZG9jdW1lbnQuIFRoaXMgdmFsdWUgaXMgb25seSB1c2VkIGlmIHdlIGRvbid0IGRlZmVyIHRoZSBsb2FkaW5nCi0gICAgICogb2Ygc2NoZW1hIGRvY3VtZW50cy4KLSAgICAgKi8KLSAgICBwdWJsaWMgZmluYWwgc3RhdGljIHNob3J0IENPTlRFWFRfSU5TVEFOQ0UgID0gNDsKLSAgICAvKioKLSAgICAgKiBJbmRpY2F0ZSB0aGF0IHRoZSBwYXJzZSBvZiB0aGUgY3VycmVudCBzY2hlbWEgZG9jdW1lbnQgaXMgdHJpZ2dlcmVkIGJ5Ci0gICAgICogdGhlIG9jY3VycmVuY2Ugb2YgYW4gZWxlbWVudCB3aG9zZSBuYW1lc3BhY2UgaXMgdGhlIHRhcmdldCBuYW1lc3BhY2UKLSAgICAgKiBvZiB0aGlzIHNjaGVtYSBkb2N1bWVudC4gVGhpcyB2YWx1ZSBpcyBvbmx5IHVzZWQgaWYgd2UgZG8gZGVmZXIgdGhlCi0gICAgICogbG9hZGluZyBvZiBzY2hlbWEgZG9jdW1lbnRzIHVudGlsIGEgY29tcG9uZW50IGZyb20gdGhhdCBuYW1lc3BhY2UgaXMKLSAgICAgKiByZWZlcmVuY2VkIGZyb20gdGhlIGluc3RhbmNlLgotICAgICAqLwotICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgc2hvcnQgQ09OVEVYVF9FTEVNRU5UICAgPSA1OwotICAgIC8qKgotICAgICAqIEluZGljYXRlIHRoYXQgdGhlIHBhcnNlIG9mIHRoZSBjdXJyZW50IHNjaGVtYSBkb2N1bWVudCBpcyB0cmlnZ2VyZWQgYnkKLSAgICAgKiB0aGUgb2NjdXJyZW5jZSBvZiBhbiBhdHRyaWJ1dGUgd2hvc2UgbmFtZXNwYWNlIGlzIHRoZSB0YXJnZXQgbmFtZXNwYWNlCi0gICAgICogb2YgdGhpcyBzY2hlbWEgZG9jdW1lbnQuIFRoaXMgdmFsdWUgaXMgb25seSB1c2VkIGlmIHdlIGRvIGRlZmVyIHRoZQotICAgICAqIGxvYWRpbmcgb2Ygc2NoZW1hIGRvY3VtZW50cyB1bnRpbCBhIGNvbXBvbmVudCBmcm9tIHRoYXQgbmFtZXNwYWNlIGlzCi0gICAgICogcmVmZXJlbmNlZCBmcm9tIHRoZSBpbnN0YW5jZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgZmluYWwgc3RhdGljIHNob3J0IENPTlRFWFRfQVRUUklCVVRFID0gNjsKLSAgICAvKioKLSAgICAgKiBJbmRpY2F0ZSB0aGF0IHRoZSBwYXJzZSBvZiB0aGUgY3VycmVudCBzY2hlbWEgZG9jdW1lbnQgaXMgdHJpZ2dlcmVkIGJ5Ci0gICAgICogdGhlIG9jY3VycmVuY2Ugb2YgYW4gInhzaTp0eXBlIiBhdHRyaWJ1dGUsIHdob3NlIHZhbHVlIChhIFFOYW1lKSBoYXMKLSAgICAgKiB0aGUgdGFyZ2V0IG5hbWVzcGFjZSBvZiB0aGlzIHNjaGVtYSBkb2N1bWVudCBhcyBpdHMgbmFtZXNwYWNlLgotICAgICAqIFRoaXMgdmFsdWUgaXMgb25seSB1c2VkIGlmIHdlIGRvIGRlZmVyIHRoZSBsb2FkaW5nIG9mIHNjaGVtYSBkb2N1bWVudHMKLSAgICAgKiB1bnRpbCBhIGNvbXBvbmVudCBmcm9tIHRoYXQgbmFtZXNwYWNlIGlzIHJlZmVyZW5jZWQgZnJvbSB0aGUgaW5zdGFuY2UuCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIHN0YXRpYyBzaG9ydCBDT05URVhUX1hTSVRZUEUgICA9IDc7Ci0KLSAgICAvLyBSRVZJU0lUOiB3cml0ZSBkZXNjcmlwdGlvbiBvZiB0aGVzZSBmaWVsZHMKLSAgICBwcm90ZWN0ZWQgc2hvcnQgZkNvbnRleHRUeXBlOwotICAgIHByb3RlY3RlZCBTdHJpbmcgW10gZkxvY2F0aW9uSGludHMgOwotICAgIHByb3RlY3RlZCBRTmFtZSBmVHJpZ2dlcmluZ0NvbXBvbmVudDsKLSAgICBwcm90ZWN0ZWQgUU5hbWUgZkVuY2xvc2VkRWxlbWVudE5hbWU7Ci0gICAgcHJvdGVjdGVkIFhNTEF0dHJpYnV0ZXMgIGZBdHRyaWJ1dGVzOwotCi0gICAgLyoqCi0gICAgICogdGhlIHR5cGUgb2YgdGhlIGdyYW1tYXIgKGUuZy4sIERURCBvciBYU0QpOwotICAgICAqCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5ncmFtbWFycy5HcmFtbWFyCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRHcmFtbWFyVHlwZSgpIHsKLSAgICAgICAgcmV0dXJuIFhNTEdyYW1tYXJEZXNjcmlwdGlvbi5YTUxfU0NIRU1BOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgY29udGV4dC4gVGhlIHJldHVybmVkIHZhbHVlIGlzIG9uZSBvZiB0aGUgcHJlLWRlZmluZWQKLSAgICAgKiBDT05URVhUX3h4eCBjb25zdGFudHMuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuICB0aGUgdmFsdWUgaW5kaWNhdGluZyB0aGUgY29udGV4dAotICAgICAqLwotICAgIHB1YmxpYyBzaG9ydCBnZXRDb250ZXh0VHlwZSgpIHsKLSAgICAgICAgcmV0dXJuIGZDb250ZXh0VHlwZSA7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSWYgdGhlIGNvbnRleHQgaXMgImluY2x1ZGUiIG9yICJyZWRlZmluZSIsIHRoZW4gcmV0dXJuIHRoZSB0YXJnZXQKLSAgICAgKiBuYW1lc3BhY2Ugb2YgdGhlIGVuY2xvc2luZyBzY2hlbWEgZG9jdW1lbnQ7IG90aGVyd2lzZSwgdGhlIGV4cGVjdGVkCi0gICAgICogdGFyZ2V0IG5hbWVzcGFjZSBvZiB0aGlzIGRvY3VtZW50LgotICAgICAqCi0gICAgICogQHJldHVybiAgdGhlIGV4cGVjdGVkL2VuY2xvc2luZyB0YXJnZXQgbmFtZXNwYWNlCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXROYW1lc3BhY2UoKSB7Ci0gICAgICAgIHJldHVybiBmTmFtZXNwYWNlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEZvciBpbXBvcnQgYW5kIHJlZmVyZW5jZXMgZnJvbSB0aGUgaW5zdGFuY2UgZG9jdW1lbnQsIGl0J3MgcG9zc2libGUgdG8KLSAgICAgKiBoYXZlIG11bHRpcGxlIGhpbnRzIGZvciBvbmUgbmFtZXNwYWNlLiBTbyB0aGlzIG1ldGhvZCByZXR1cm5zIGFuIGFycmF5LAotICAgICAqIHdoaWNoIGNvbnRhaW5zIGFsbCBsb2NhdGlvbiBoaW50cy4KLSAgICAgKgotICAgICAqIEByZXR1cm4gIGFuIGFycmF5IG9mIGFsbCBsb2NhdGlvbiBoaW50cyBhc3NvY2lhdGVkIHRvIHRoZSBleHBlY3RlZAotICAgICAqICAgICAgICAgIHRhcmdldCBuYW1lc3BhY2UKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nW10gZ2V0TG9jYXRpb25IaW50cygpIHsKLSAgICAgICAgcmV0dXJuIGZMb2NhdGlvbkhpbnRzIDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJZiBhIGNhbGwgaXMgdHJpZ2dlcmVkIGJ5IGFuIGVsZW1lbnQvYXR0cmlidXRlL3hzaTp0eXBlIGluIHRoZSBpbnN0YW5jZSwKLSAgICAgKiB0aGlzIGNhbGwgcmV0dXJucyB0aGUgbmFtZSBvZiBzdWNoIHRyaWdnZXJpbmcgY29tcG9uZW50OiB0aGUgbmFtZSBvZgotICAgICAqIHRoZSBlbGVtZW50L2F0dHJpYnV0ZSwgb3IgdGhlIHZhbHVlIG9mIHRoZSB4c2k6dHlwZS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gIHRoZSBuYW1lIG9mIHRoZSB0cmlnZ2VyaW5nIGNvbXBvbmVudAotICAgICAqLwotICAgIHB1YmxpYyBRTmFtZSBnZXRUcmlnZ2VyaW5nQ29tcG9uZW50KCkgewotICAgICAgICByZXR1cm4gZlRyaWdnZXJpbmdDb21wb25lbnQgOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIElmIGEgY2FsbCBpcyB0cmlnZ2VyZWQgYnkgYW4gYXR0cmlidXRlIG9yIHhzaTp0eXBlLCB0aGVuIHRoaXMgbWVodG9kCi0gICAgICogcmV0dXJucyB0aGUgZW5jbG9zaW5nIGVsZW1lbnQgb2Ygc3VjaCBlbGVtZW50LgotICAgICAqCi0gICAgICogQHJldHVybiAgdGhlIG5hbWUgb2YgdGhlIGVuY2xvc2luZyBlbGVtZW50Ci0gICAgICovCi0gICAgcHVibGljIFFOYW1lIGdldEVuY2xvc2luZ0VsZW1lbnROYW1lKCkgewotICAgICAgICByZXR1cm4gZkVuY2xvc2VkRWxlbWVudE5hbWUgOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIElmIGEgY2FsbCBpcyB0cmlnZ2VyZWQgYnkgYW4gZWxlbWVudC9hdHRyaWJ1dGUveHNpOnR5cGUgaW4gdGhlIGluc3RhbmNlLAotICAgICAqIHRoaXMgY2FsbCByZXR1cm5zIGFsbCBhdHRyaWJ1dGUgb2Ygc3VjaCBlbGVtZW50IChvciBlbmNsb3NpbmcgZWxlbWVudCkuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuICBhbGwgYXR0cmlidXRlcyBvZiB0aGUgdGlnZ2VyaW5nL2VuY2xvc2luZyBlbGVtZW50Ci0gICAgICovCi0gICAgcHVibGljIFhNTEF0dHJpYnV0ZXMgZ2V0QXR0cmlidXRlcygpIHsKLSAgICAgICAgcmV0dXJuIGZBdHRyaWJ1dGVzOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGZyb21JbnN0YW5jZSgpIHsKLSAgICAgICAgcmV0dXJuIGZDb250ZXh0VHlwZSA9PSBDT05URVhUX0FUVFJJQlVURSB8fAotICAgICAgICAgICAgICAgZkNvbnRleHRUeXBlID09IENPTlRFWFRfRUxFTUVOVCB8fAotICAgICAgICAgICAgICAgZkNvbnRleHRUeXBlID09IENPTlRFWFRfSU5TVEFOQ0UgfHwKLSAgICAgICAgICAgICAgIGZDb250ZXh0VHlwZSA9PSBDT05URVhUX1hTSVRZUEU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHJldHVybiB0cnVlIGlzIHRoZSBzY2hlbWEgaXMgZXh0ZXJuYWwKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0V4dGVybmFsKCkgewotICAgICAgICByZXR1cm4gZkNvbnRleHRUeXBlID09IENPTlRFWFRfSU5DTFVERSB8fAotICAgICAgICAgICAgICAgZkNvbnRleHRUeXBlID09IENPTlRFWFRfUkVERUZJTkUgfHwKLSAgICAgICAgICAgICAgIGZDb250ZXh0VHlwZSA9PSBDT05URVhUX0lNUE9SVCB8fAotICAgICAgICAgICAgICAgZkNvbnRleHRUeXBlID09IENPTlRFWFRfRUxFTUVOVCB8fAotICAgICAgICAgICAgICAgZkNvbnRleHRUeXBlID09IENPTlRFWFRfQVRUUklCVVRFIHx8Ci0gICAgICAgICAgICAgICBmQ29udGV4dFR5cGUgPT0gQ09OVEVYVF9YU0lUWVBFOwotICAgIH0KLSAgICAvKioKLSAgICAgKiBDb21wYXJlcyB0aGlzIGdyYW1tYXIgd2l0aCB0aGUgZ2l2ZW4gZ3JhbW1hci4gQ3VycmVudGx5LCB3ZSBjb21wYXJlCi0gICAgICogdGhlIHRhcmdldCBuYW1lc3BhY2VzLgotICAgICAqCi0gICAgICogQHBhcmFtIGRlc2NPYmogVGhlIGRlc2NyaXB0aW9uIG9mIHRoZSBncmFtbWFyIHRvIGJlIGNvbXBhcmVkIHdpdGgKLSAgICAgKiBAcmV0dXJuICAgICAgICBUcnVlIGlmIHRoZXkgYXJlIGVxdWFsLCBlbHNlIGZhbHNlCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBkZXNjT2JqKSB7Ci0gICAgICAgIGlmKCEoZGVzY09iaiBpbnN0YW5jZW9mIFhNTFNjaGVtYURlc2NyaXB0aW9uKSkgcmV0dXJuIGZhbHNlOwotICAgICAgICBYTUxTY2hlbWFEZXNjcmlwdGlvbiBkZXNjID0gKFhNTFNjaGVtYURlc2NyaXB0aW9uKWRlc2NPYmo7Ci0gICAgICAgIGlmIChmTmFtZXNwYWNlICE9IG51bGwpCi0gICAgICAgICAgICByZXR1cm4gZk5hbWVzcGFjZS5lcXVhbHMoZGVzYy5nZXRUYXJnZXROYW1lc3BhY2UoKSk7Ci0gICAgICAgIGVsc2UgLy8gZk5hbWVzcGFjZSA9PSBudWxsCi0gICAgICAgICAgICByZXR1cm4gZGVzYy5nZXRUYXJnZXROYW1lc3BhY2UoKSA9PSBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIGhhc2ggY29kZSBvZiB0aGlzIGdyYW1tYXIKLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIGhhc2ggY29kZQotICAgICAqLwotICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7Ci0gICAgICAgICByZXR1cm4gKGZOYW1lc3BhY2UgPT0gbnVsbCkgPyAwIDogZk5hbWVzcGFjZS5oYXNoQ29kZSgpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldENvbnRleHRUeXBlKHNob3J0IGNvbnRleHRUeXBlKXsKLSAgICAgICAgZkNvbnRleHRUeXBlID0gY29udGV4dFR5cGUgOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldFRhcmdldE5hbWVzcGFjZShTdHJpbmcgdGFyZ2V0TmFtZXNwYWNlKXsKLSAgICAgICAgZk5hbWVzcGFjZSA9IHRhcmdldE5hbWVzcGFjZSA7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0TG9jYXRpb25IaW50cyhTdHJpbmcgW10gbG9jYXRpb25IaW50cyl7Ci0gICAgICAgIGludCBsZW5ndGggPSBsb2NhdGlvbkhpbnRzLmxlbmd0aCA7Ci0gICAgICAgIGZMb2NhdGlvbkhpbnRzICA9IG5ldyBTdHJpbmdbbGVuZ3RoXTsKLSAgICAgICAgU3lzdGVtLmFycmF5Y29weShsb2NhdGlvbkhpbnRzLCAwLCBmTG9jYXRpb25IaW50cywgMCwgbGVuZ3RoKTsKLSAgICAgICAgLy9mTG9jYXRpb25IaW50cyA9IGxvY2F0aW9uSGludHMgOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldFRyaWdnZXJpbmdDb21wb25lbnQoUU5hbWUgdHJpZ2dlcmluZ0NvbXBvbmVudCl7Ci0gICAgICAgIGZUcmlnZ2VyaW5nQ29tcG9uZW50ID0gdHJpZ2dlcmluZ0NvbXBvbmVudCA7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0RW5jbG9zaW5nRWxlbWVudE5hbWUoUU5hbWUgZW5jbG9zZWRFbGVtZW50TmFtZSl7Ci0gICAgICAgIGZFbmNsb3NlZEVsZW1lbnROYW1lID0gZW5jbG9zZWRFbGVtZW50TmFtZSA7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0QXR0cmlidXRlcyhYTUxBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMpewotICAgICAgICBmQXR0cmlidXRlcyA9IGF0dHJpYnV0ZXMgOwotICAgIH0KLQotICAgIC8qKgotICAgICAqICByZXNldHMgYWxsIHRoZSBmaWVsZHMKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCByZXNldCgpewotICAgICAgICBzdXBlci5jbGVhcigpOwotICAgICAgICBmQ29udGV4dFR5cGUgPSBDT05URVhUX0lOSVRJQUxJWkU7Ci0gICAgICAgIGZMb2NhdGlvbkhpbnRzICA9IG51bGwgOwotICAgICAgICBmVHJpZ2dlcmluZ0NvbXBvbmVudCA9IG51bGwgOwotICAgICAgICBmRW5jbG9zZWRFbGVtZW50TmFtZSA9IG51bGwgOwotICAgICAgICBmQXR0cmlidXRlcyA9IG51bGwgOwotICAgIH0KLQotICAgIHB1YmxpYyBYU0REZXNjcmlwdGlvbiBtYWtlQ2xvbmUoKSB7Ci0gICAgICAgIFhTRERlc2NyaXB0aW9uIGRlc2MgPSBuZXcgWFNERGVzY3JpcHRpb24oKTsKLSAgICAgICAgZGVzYy5mQXR0cmlidXRlcyA9IHRoaXMuZkF0dHJpYnV0ZXM7Ci0gICAgICAgIGRlc2MuZkJhc2VTeXN0ZW1JZCA9IHRoaXMuZkJhc2VTeXN0ZW1JZDsKLSAgICAgICAgZGVzYy5mQ29udGV4dFR5cGUgPSB0aGlzLmZDb250ZXh0VHlwZTsKLSAgICAgICAgZGVzYy5mRW5jbG9zZWRFbGVtZW50TmFtZSA9IHRoaXMuZkVuY2xvc2VkRWxlbWVudE5hbWU7Ci0gICAgICAgIGRlc2MuZkV4cGFuZGVkU3lzdGVtSWQgPSB0aGlzLmZFeHBhbmRlZFN5c3RlbUlkOwotICAgICAgICBkZXNjLmZMaXRlcmFsU3lzdGVtSWQgPSB0aGlzLmZMaXRlcmFsU3lzdGVtSWQ7Ci0gICAgICAgIGRlc2MuZkxvY2F0aW9uSGludHMgPSB0aGlzLmZMb2NhdGlvbkhpbnRzOwotICAgICAgICBkZXNjLmZQdWJsaWNJZCA9IHRoaXMuZlB1YmxpY0lkOwotICAgICAgICBkZXNjLmZOYW1lc3BhY2UgPSB0aGlzLmZOYW1lc3BhY2U7Ci0gICAgICAgIGRlc2MuZlRyaWdnZXJpbmdDb21wb25lbnQgPSB0aGlzLmZUcmlnZ2VyaW5nQ29tcG9uZW50OwotICAgICAgICByZXR1cm4gZGVzYzsKLSAgICB9Ci0KLX0gLy8gWFNERGVzY3JpcHRpb24KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvWFNEZWNsYXJhdGlvblBvb2wuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvWFNEZWNsYXJhdGlvblBvb2wuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNTU3OGRhMi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL1hTRGVjbGFyYXRpb25Qb29sLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzMTggKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMSwgMjAwMiwyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYueHMuU2NoZW1hRFZGYWN0b3J5SW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYueHMuWFNTaW1wbGVUeXBlRGVjbDsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGlzIHBvb2wgdGhhdCBlbmFibGVzIGNhY2hpbmcgb2YgWE1MIFNjaGVtYSBkZWNsYXJhdGlvbiBvYmplY3RzLgotICogQmVmb3JlIGEgY29tcGlsZWQgZ3JhbW1hciBvYmplY3QgaXMgZ2FyYmFnZSBjb2xsZWN0ZWQsCi0gKiB0aGUgaW1wbGVtZW50YXRpb24gd2lsbCBhZGQgYWxsIFhNTCBTY2hlbWEgY29tcG9uZW50Ci0gKiBkZWNsYXJhdGlvbnMgdG8gdGhlIHBvb2wuCi0gKiBOb3RlOiBUaGUgY2FzaGluZyBtZWNoYW5pc20gaXMgbm90IGltcGxlbWVudGVkIHlldC4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBFbGVuYSBMaXRhbmksIElCTQotICogQHZlcnNpb24gJElkOiBYU0RlY2xhcmF0aW9uUG9vbC5qYXZhLHYgMS43IDIwMTAtMTEtMDEgMDQ6Mzk6NTUgam9laHcgRXhwICQKLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIFhTRGVjbGFyYXRpb25Qb29sIHsKLSAgICAvKiogQ2h1bmsgc2hpZnQgKDgpLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBDSFVOS19TSElGVCA9IDg7IC8vIDJeOCA9IDI1NgotCi0gICAgLyoqIENodW5rIHNpemUgKDEgPDwgQ0hVTktfU0hJRlQpLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBDSFVOS19TSVpFID0gMSA8PCBDSFVOS19TSElGVDsKLQotICAgIC8qKiBDaHVuayBtYXNrIChDSFVOS19TSVpFIC0gMSkuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IENIVU5LX01BU0sgPSBDSFVOS19TSVpFIC0gMTsKLQotICAgIC8qKiBJbml0aWFsIGNodW5rIGNvdW50ICgpLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBJTklUSUFMX0NIVU5LX0NPVU5UID0gKDEgPDwgKDEwIC0gQ0hVTktfU0hJRlQpKTsgLy8gMl4xMCA9IDFrCi0KLSAgICAvKiogRWxlbWVudCBkZWNsYXJhdGlvbiBwb29sKi8KLSAgICBwcml2YXRlIFhTRWxlbWVudERlY2wgZkVsZW1lbnREZWNsW11bXSA9IG5ldyBYU0VsZW1lbnREZWNsW0lOSVRJQUxfQ0hVTktfQ09VTlRdW107Ci0gICAgcHJpdmF0ZSBpbnQgZkVsZW1lbnREZWNsSW5kZXggPSAwOwotCi0gICAgLyoqIFBhcnRpY2xlIGRlY2xhcmF0aW9uIHBvb2wgKi8KLSAgICBwcml2YXRlIFhTUGFydGljbGVEZWNsIGZQYXJ0aWNsZURlY2xbXVtdID0gbmV3IFhTUGFydGljbGVEZWNsW0lOSVRJQUxfQ0hVTktfQ09VTlRdW107Ci0gICAgcHJpdmF0ZSBpbnQgZlBhcnRpY2xlRGVjbEluZGV4ID0gMDsKLQotICAgIC8qKiBQYXJ0aWNsZSBkZWNsYXJhdGlvbiBwb29sICovCi0gICAgcHJpdmF0ZSBYU01vZGVsR3JvdXBJbXBsIGZNb2RlbEdyb3VwW11bXSA9IG5ldyBYU01vZGVsR3JvdXBJbXBsW0lOSVRJQUxfQ0hVTktfQ09VTlRdW107Ci0gICAgcHJpdmF0ZSBpbnQgZk1vZGVsR3JvdXBJbmRleCA9IDA7Ci0KLSAgICAvKiogQXR0cmlidXRlIGRlY2xhcmF0aW9uIHBvb2wgKi8KLSAgICBwcml2YXRlIFhTQXR0cmlidXRlRGVjbCBmQXR0ckRlY2xbXVtdID0gbmV3IFhTQXR0cmlidXRlRGVjbFtJTklUSUFMX0NIVU5LX0NPVU5UXVtdOwotICAgIHByaXZhdGUgaW50IGZBdHRyRGVjbEluZGV4ID0gMDsKLQotICAgIC8qKiBDb21wbGV4VHlwZSBkZWNsYXJhdGlvbiBwb29sICovCi0gICAgcHJpdmF0ZSBYU0NvbXBsZXhUeXBlRGVjbCBmQ1REZWNsW11bXSA9IG5ldyBYU0NvbXBsZXhUeXBlRGVjbFtJTklUSUFMX0NIVU5LX0NPVU5UXVtdOwotICAgIHByaXZhdGUgaW50IGZDVERlY2xJbmRleCA9IDA7Ci0KLSAgICAvKiogU2ltcGxlVHlwZSBkZWNsYXJhdGlvbiBwb29sICovCi0gICAgcHJpdmF0ZSBYU1NpbXBsZVR5cGVEZWNsIGZTVERlY2xbXVtdID0gbmV3IFhTU2ltcGxlVHlwZURlY2xbSU5JVElBTF9DSFVOS19DT1VOVF1bXTsKLSAgICBwcml2YXRlIGludCBmU1REZWNsSW5kZXggPSAwOwotCi0gICAgLyoqIEF0dHJpYnV0ZVVzZSBkZWNsYXJhdGlvbiBwb29sICovCi0gICAgcHJpdmF0ZSBYU0F0dHJpYnV0ZVVzZUltcGwgZkF0dHJpYnV0ZVVzZVtdW10gPSBuZXcgWFNBdHRyaWJ1dGVVc2VJbXBsW0lOSVRJQUxfQ0hVTktfQ09VTlRdW107Ci0gICAgcHJpdmF0ZSBpbnQgZkF0dHJpYnV0ZVVzZUluZGV4ID0gMDsKLQotICAgIHByaXZhdGUgU2NoZW1hRFZGYWN0b3J5SW1wbCBkdkZhY3Rvcnk7Ci0gICAgcHVibGljIHZvaWQgc2V0RFZGYWN0b3J5KFNjaGVtYURWRmFjdG9yeUltcGwgZHZGYWN0b3J5KSB7Ci0gICAgICAgIHRoaXMuZHZGYWN0b3J5ID0gZHZGYWN0b3J5OwotICAgIH0KLQotICAgIHB1YmxpYyBmaW5hbCAgWFNFbGVtZW50RGVjbCBnZXRFbGVtZW50RGVjbCgpewotICAgICAgICBpbnQgICAgIGNodW5rICAgICAgID0gZkVsZW1lbnREZWNsSW5kZXggPj4gQ0hVTktfU0hJRlQ7Ci0gICAgICAgIGludCAgICAgaW5kZXggICAgICAgPSBmRWxlbWVudERlY2xJbmRleCAmICBDSFVOS19NQVNLOwotICAgICAgICBlbnN1cmVFbGVtZW50RGVjbENhcGFjaXR5KGNodW5rKTsKLSAgICAgICAgaWYgKGZFbGVtZW50RGVjbFtjaHVua11baW5kZXhdID09IG51bGwpIHsKLSAgICAgICAgICAgIGZFbGVtZW50RGVjbFtjaHVua11baW5kZXhdID0gbmV3IFhTRWxlbWVudERlY2woKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIGZFbGVtZW50RGVjbFtjaHVua11baW5kZXhdLnJlc2V0KCk7Ci0gICAgICAgIH0KLSAgICAgICAgZkVsZW1lbnREZWNsSW5kZXgrKzsKLSAgICAgICAgcmV0dXJuIGZFbGVtZW50RGVjbFtjaHVua11baW5kZXhdOwotICAgIH0KLQotICAgIHB1YmxpYyBmaW5hbCBYU0F0dHJpYnV0ZURlY2wgZ2V0QXR0cmlidXRlRGVjbCgpewotICAgICAgICBpbnQgICAgIGNodW5rICAgICAgID0gZkF0dHJEZWNsSW5kZXggPj4gQ0hVTktfU0hJRlQ7Ci0gICAgICAgIGludCAgICAgaW5kZXggICAgICAgPSBmQXR0ckRlY2xJbmRleCAmICBDSFVOS19NQVNLOwotICAgICAgICBlbnN1cmVBdHRyRGVjbENhcGFjaXR5KGNodW5rKTsKLSAgICAgICAgaWYgKGZBdHRyRGVjbFtjaHVua11baW5kZXhdID09IG51bGwpIHsKLSAgICAgICAgICAgIGZBdHRyRGVjbFtjaHVua11baW5kZXhdID0gbmV3IFhTQXR0cmlidXRlRGVjbCgpOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgZkF0dHJEZWNsW2NodW5rXVtpbmRleF0ucmVzZXQoKTsKLSAgICAgICAgfQotICAgICAgICBmQXR0ckRlY2xJbmRleCsrOwotICAgICAgICByZXR1cm4gZkF0dHJEZWNsW2NodW5rXVtpbmRleF07Ci0KLSAgICB9Ci0KLSAgICBwdWJsaWMgZmluYWwgWFNBdHRyaWJ1dGVVc2VJbXBsIGdldEF0dHJpYnV0ZVVzZSgpewotICAgICAgICBpbnQgICAgIGNodW5rICAgICAgID0gZkF0dHJpYnV0ZVVzZUluZGV4ID4+IENIVU5LX1NISUZUOwotICAgICAgICBpbnQgICAgIGluZGV4ICAgICAgID0gZkF0dHJpYnV0ZVVzZUluZGV4ICYgIENIVU5LX01BU0s7Ci0gICAgICAgIGVuc3VyZUF0dHJpYnV0ZVVzZUNhcGFjaXR5KGNodW5rKTsKLSAgICAgICAgaWYgKGZBdHRyaWJ1dGVVc2VbY2h1bmtdW2luZGV4XSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBmQXR0cmlidXRlVXNlW2NodW5rXVtpbmRleF0gPSBuZXcgWFNBdHRyaWJ1dGVVc2VJbXBsKCk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBmQXR0cmlidXRlVXNlW2NodW5rXVtpbmRleF0ucmVzZXQoKTsKLSAgICAgICAgfQotICAgICAgICBmQXR0cmlidXRlVXNlSW5kZXgrKzsKLSAgICAgICAgcmV0dXJuIGZBdHRyaWJ1dGVVc2VbY2h1bmtdW2luZGV4XTsKLQotICAgIH0KLQotICAgIHB1YmxpYyBmaW5hbCBYU0NvbXBsZXhUeXBlRGVjbCBnZXRDb21wbGV4VHlwZURlY2woKXsKLSAgICAgICAgaW50ICAgICBjaHVuayAgICAgICA9IGZDVERlY2xJbmRleCA+PiBDSFVOS19TSElGVDsKLSAgICAgICAgaW50ICAgICBpbmRleCAgICAgICA9IGZDVERlY2xJbmRleCAmICBDSFVOS19NQVNLOwotICAgICAgICBlbnN1cmVDVERlY2xDYXBhY2l0eShjaHVuayk7Ci0gICAgICAgIGlmIChmQ1REZWNsW2NodW5rXVtpbmRleF0gPT0gbnVsbCkgewotCi0gICAgICAgICAgICBmQ1REZWNsW2NodW5rXVtpbmRleF0gPSBuZXcgWFNDb21wbGV4VHlwZURlY2woKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIGZDVERlY2xbY2h1bmtdW2luZGV4XS5yZXNldCgpOwotICAgICAgICB9Ci0gICAgICAgIGZDVERlY2xJbmRleCsrOwotICAgICAgICByZXR1cm4gZkNURGVjbFtjaHVua11baW5kZXhdOwotICAgIH0KLQotICAgIHB1YmxpYyBmaW5hbCBYU1NpbXBsZVR5cGVEZWNsIGdldFNpbXBsZVR5cGVEZWNsKCl7Ci0gICAgICAgIGludCAgICAgY2h1bmsgICAgICAgPSBmU1REZWNsSW5kZXggPj4gQ0hVTktfU0hJRlQ7Ci0gICAgICAgIGludCAgICAgaW5kZXggICAgICAgPSBmU1REZWNsSW5kZXggJiAgQ0hVTktfTUFTSzsKLSAgICAgICAgZW5zdXJlU1REZWNsQ2FwYWNpdHkoY2h1bmspOwotICAgICAgICBpZiAoZlNURGVjbFtjaHVua11baW5kZXhdID09IG51bGwpIHsKLSAgICAgICAgICAgIGZTVERlY2xbY2h1bmtdW2luZGV4XSA9IGR2RmFjdG9yeS5uZXdYU1NpbXBsZVR5cGVEZWNsKCk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBmU1REZWNsW2NodW5rXVtpbmRleF0ucmVzZXQoKTsKLSAgICAgICAgfQotICAgICAgICBmU1REZWNsSW5kZXgrKzsKLSAgICAgICAgcmV0dXJuIGZTVERlY2xbY2h1bmtdW2luZGV4XTsKLQotICAgIH0KLQotICAgIHB1YmxpYyBmaW5hbCBYU1BhcnRpY2xlRGVjbCBnZXRQYXJ0aWNsZURlY2woKXsKLSAgICAgICAgaW50ICAgICBjaHVuayAgICAgICA9IGZQYXJ0aWNsZURlY2xJbmRleCA+PiBDSFVOS19TSElGVDsKLSAgICAgICAgaW50ICAgICBpbmRleCAgICAgICA9IGZQYXJ0aWNsZURlY2xJbmRleCAmICBDSFVOS19NQVNLOwotICAgICAgICBlbnN1cmVQYXJ0aWNsZURlY2xDYXBhY2l0eShjaHVuayk7Ci0gICAgICAgIGlmIChmUGFydGljbGVEZWNsW2NodW5rXVtpbmRleF0gPT0gbnVsbCkgewotICAgICAgICAgICAgZlBhcnRpY2xlRGVjbFtjaHVua11baW5kZXhdID0gbmV3IFhTUGFydGljbGVEZWNsKCk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBmUGFydGljbGVEZWNsW2NodW5rXVtpbmRleF0ucmVzZXQoKTsKLSAgICAgICAgfQotICAgICAgICBmUGFydGljbGVEZWNsSW5kZXgrKzsKLSAgICAgICAgcmV0dXJuIGZQYXJ0aWNsZURlY2xbY2h1bmtdW2luZGV4XTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgZmluYWwgWFNNb2RlbEdyb3VwSW1wbCBnZXRNb2RlbEdyb3VwKCl7Ci0gICAgICAgIGludCAgICAgY2h1bmsgICAgICAgPSBmTW9kZWxHcm91cEluZGV4ID4+IENIVU5LX1NISUZUOwotICAgICAgICBpbnQgICAgIGluZGV4ICAgICAgID0gZk1vZGVsR3JvdXBJbmRleCAmICBDSFVOS19NQVNLOwotICAgICAgICBlbnN1cmVNb2RlbEdyb3VwQ2FwYWNpdHkoY2h1bmspOwotICAgICAgICBpZiAoZk1vZGVsR3JvdXBbY2h1bmtdW2luZGV4XSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBmTW9kZWxHcm91cFtjaHVua11baW5kZXhdID0gbmV3IFhTTW9kZWxHcm91cEltcGwoKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIGZNb2RlbEdyb3VwW2NodW5rXVtpbmRleF0ucmVzZXQoKTsKLSAgICAgICAgfQotICAgICAgICBmTW9kZWxHcm91cEluZGV4Kys7Ci0gICAgICAgIHJldHVybiBmTW9kZWxHcm91cFtjaHVua11baW5kZXhdOwotICAgIH0KLQotICAgIC8vIFJFVklTSVQ6IGRvIHdlIG5lZWQgZGVjbCBwb29sIGZvciBncm91cCBkZWNsYXJhdGlvbnMsIGF0dHJpYnV0ZSBncm91cCwKLSAgICAvLyAgICAgICAgICBub3RhdGlvbnM/Ci0gICAgLy8gICAgICAgICAgaXQgc2VlbXMgbGlrZSBlYWNoIHNjaGVtYSB3b3VsZCB1c2UgYSBzbWFsbCBudW1iZXIgb2YgdGhvc2UKLSAgICAvLyAgICAgICAgICBjb21wb25lbnRzLCBzbyBpdCBwcm9iYWJseSBpcyBub3Qgd29ydGgga2VlcGluZyB0aG9zZSBjb21wb25lbnRzCi0gICAgLy8gICAgICAgICAgaW4gdGhlIHBvb2wuCi0KLSAgICBwcml2YXRlIGJvb2xlYW4gZW5zdXJlRWxlbWVudERlY2xDYXBhY2l0eShpbnQgY2h1bmspIHsKLSAgICAgICAgaWYgKGNodW5rID49IGZFbGVtZW50RGVjbC5sZW5ndGgpIHsKLSAgICAgICAgICAgIGZFbGVtZW50RGVjbCA9IHJlc2l6ZShmRWxlbWVudERlY2wsIGZFbGVtZW50RGVjbC5sZW5ndGggKiAyKTsKLSAgICAgICAgfSBlbHNlIGlmIChmRWxlbWVudERlY2xbY2h1bmtdICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotCi0gICAgICAgIGZFbGVtZW50RGVjbFtjaHVua10gPSBuZXcgWFNFbGVtZW50RGVjbFtDSFVOS19TSVpFXTsKLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBzdGF0aWMgWFNFbGVtZW50RGVjbFtdW10gcmVzaXplKFhTRWxlbWVudERlY2wgYXJyYXlbXVtdLCBpbnQgbmV3c2l6ZSkgewotICAgICAgICBYU0VsZW1lbnREZWNsIG5ld2FycmF5W11bXSA9IG5ldyBYU0VsZW1lbnREZWNsW25ld3NpemVdW107Ci0gICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYXJyYXksIDAsIG5ld2FycmF5LCAwLCBhcnJheS5sZW5ndGgpOwotICAgICAgICByZXR1cm4gbmV3YXJyYXk7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBib29sZWFuIGVuc3VyZVBhcnRpY2xlRGVjbENhcGFjaXR5KGludCBjaHVuaykgewotICAgICAgICBpZiAoY2h1bmsgPj0gZlBhcnRpY2xlRGVjbC5sZW5ndGgpIHsKLSAgICAgICAgICAgIGZQYXJ0aWNsZURlY2wgPSByZXNpemUoZlBhcnRpY2xlRGVjbCwgZlBhcnRpY2xlRGVjbC5sZW5ndGggKiAyKTsKLSAgICAgICAgfSBlbHNlIGlmIChmUGFydGljbGVEZWNsW2NodW5rXSAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLQotICAgICAgICBmUGFydGljbGVEZWNsW2NodW5rXSA9IG5ldyBYU1BhcnRpY2xlRGVjbFtDSFVOS19TSVpFXTsKLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBib29sZWFuIGVuc3VyZU1vZGVsR3JvdXBDYXBhY2l0eShpbnQgY2h1bmspIHsKLSAgICAgICAgaWYgKGNodW5rID49IGZNb2RlbEdyb3VwLmxlbmd0aCkgewotICAgICAgICAgICAgZk1vZGVsR3JvdXAgPSByZXNpemUoZk1vZGVsR3JvdXAsIGZNb2RlbEdyb3VwLmxlbmd0aCAqIDIpOwotICAgICAgICB9IGVsc2UgaWYgKGZNb2RlbEdyb3VwW2NodW5rXSAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLQotICAgICAgICBmTW9kZWxHcm91cFtjaHVua10gPSBuZXcgWFNNb2RlbEdyb3VwSW1wbFtDSFVOS19TSVpFXTsKLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBzdGF0aWMgWFNQYXJ0aWNsZURlY2xbXVtdIHJlc2l6ZShYU1BhcnRpY2xlRGVjbCBhcnJheVtdW10sIGludCBuZXdzaXplKSB7Ci0gICAgICAgIFhTUGFydGljbGVEZWNsIG5ld2FycmF5W11bXSA9IG5ldyBYU1BhcnRpY2xlRGVjbFtuZXdzaXplXVtdOwotICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGFycmF5LCAwLCBuZXdhcnJheSwgMCwgYXJyYXkubGVuZ3RoKTsKLSAgICAgICAgcmV0dXJuIG5ld2FycmF5OwotICAgIH0KLQotICAgIHByaXZhdGUgc3RhdGljIFhTTW9kZWxHcm91cEltcGxbXVtdIHJlc2l6ZShYU01vZGVsR3JvdXBJbXBsIGFycmF5W11bXSwgaW50IG5ld3NpemUpIHsKLSAgICAgICAgWFNNb2RlbEdyb3VwSW1wbCBuZXdhcnJheVtdW10gPSBuZXcgWFNNb2RlbEdyb3VwSW1wbFtuZXdzaXplXVtdOwotICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGFycmF5LCAwLCBuZXdhcnJheSwgMCwgYXJyYXkubGVuZ3RoKTsKLSAgICAgICAgcmV0dXJuIG5ld2FycmF5OwotICAgIH0KLQotICAgIHByaXZhdGUgYm9vbGVhbiBlbnN1cmVBdHRyRGVjbENhcGFjaXR5KGludCBjaHVuaykgewotICAgICAgICBpZiAoY2h1bmsgPj0gZkF0dHJEZWNsLmxlbmd0aCkgewotICAgICAgICAgICAgZkF0dHJEZWNsID0gcmVzaXplKGZBdHRyRGVjbCwgZkF0dHJEZWNsLmxlbmd0aCAqIDIpOwotICAgICAgICB9IGVsc2UgaWYgKGZBdHRyRGVjbFtjaHVua10gIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0KLSAgICAgICAgZkF0dHJEZWNsW2NodW5rXSA9IG5ldyBYU0F0dHJpYnV0ZURlY2xbQ0hVTktfU0laRV07Ci0gICAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotICAgIHByaXZhdGUgc3RhdGljIFhTQXR0cmlidXRlRGVjbFtdW10gcmVzaXplKFhTQXR0cmlidXRlRGVjbCBhcnJheVtdW10sIGludCBuZXdzaXplKSB7Ci0gICAgICAgIFhTQXR0cmlidXRlRGVjbCBuZXdhcnJheVtdW10gPSBuZXcgWFNBdHRyaWJ1dGVEZWNsW25ld3NpemVdW107Ci0gICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYXJyYXksIDAsIG5ld2FycmF5LCAwLCBhcnJheS5sZW5ndGgpOwotICAgICAgICByZXR1cm4gbmV3YXJyYXk7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBib29sZWFuIGVuc3VyZUF0dHJpYnV0ZVVzZUNhcGFjaXR5KGludCBjaHVuaykgewotICAgICAgICBpZiAoY2h1bmsgPj0gZkF0dHJpYnV0ZVVzZS5sZW5ndGgpIHsKLSAgICAgICAgICAgIGZBdHRyaWJ1dGVVc2UgPSByZXNpemUoZkF0dHJpYnV0ZVVzZSwgZkF0dHJpYnV0ZVVzZS5sZW5ndGggKiAyKTsKLSAgICAgICAgfSBlbHNlIGlmIChmQXR0cmlidXRlVXNlW2NodW5rXSAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLQotICAgICAgICBmQXR0cmlidXRlVXNlW2NodW5rXSA9IG5ldyBYU0F0dHJpYnV0ZVVzZUltcGxbQ0hVTktfU0laRV07Ci0gICAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotICAgIHByaXZhdGUgc3RhdGljIFhTQXR0cmlidXRlVXNlSW1wbFtdW10gcmVzaXplKFhTQXR0cmlidXRlVXNlSW1wbCBhcnJheVtdW10sIGludCBuZXdzaXplKSB7Ci0gICAgICAgIFhTQXR0cmlidXRlVXNlSW1wbCBuZXdhcnJheVtdW10gPSBuZXcgWFNBdHRyaWJ1dGVVc2VJbXBsW25ld3NpemVdW107Ci0gICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYXJyYXksIDAsIG5ld2FycmF5LCAwLCBhcnJheS5sZW5ndGgpOwotICAgICAgICByZXR1cm4gbmV3YXJyYXk7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBib29sZWFuIGVuc3VyZVNURGVjbENhcGFjaXR5KGludCBjaHVuaykgewotICAgICAgICBpZiAoY2h1bmsgPj0gZlNURGVjbC5sZW5ndGgpIHsKLSAgICAgICAgICAgIGZTVERlY2wgPSByZXNpemUoZlNURGVjbCwgZlNURGVjbC5sZW5ndGggKiAyKTsKLSAgICAgICAgfSBlbHNlIGlmIChmU1REZWNsW2NodW5rXSAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLQotICAgICAgICBmU1REZWNsW2NodW5rXSA9IG5ldyBYU1NpbXBsZVR5cGVEZWNsW0NIVU5LX1NJWkVdOwotICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBYU1NpbXBsZVR5cGVEZWNsW11bXSByZXNpemUoWFNTaW1wbGVUeXBlRGVjbCBhcnJheVtdW10sIGludCBuZXdzaXplKSB7Ci0gICAgICAgIFhTU2ltcGxlVHlwZURlY2wgbmV3YXJyYXlbXVtdID0gbmV3IFhTU2ltcGxlVHlwZURlY2xbbmV3c2l6ZV1bXTsKLSAgICAgICAgU3lzdGVtLmFycmF5Y29weShhcnJheSwgMCwgbmV3YXJyYXksIDAsIGFycmF5Lmxlbmd0aCk7Ci0gICAgICAgIHJldHVybiBuZXdhcnJheTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIGJvb2xlYW4gZW5zdXJlQ1REZWNsQ2FwYWNpdHkoaW50IGNodW5rKSB7Ci0KLSAgICAgICAgaWYgKGNodW5rID49IGZDVERlY2wubGVuZ3RoKSB7Ci0gICAgICAgICAgICBmQ1REZWNsID0gcmVzaXplKGZDVERlY2wsIGZDVERlY2wubGVuZ3RoICogMik7Ci0gICAgICAgIH0gZWxzZSBpZiAoZkNURGVjbFtjaHVua10gIT0gbnVsbCl7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLQotICAgICAgICBmQ1REZWNsW2NodW5rXSA9IG5ldyBYU0NvbXBsZXhUeXBlRGVjbFtDSFVOS19TSVpFXTsKLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBzdGF0aWMgWFNDb21wbGV4VHlwZURlY2xbXVtdIHJlc2l6ZShYU0NvbXBsZXhUeXBlRGVjbCBhcnJheVtdW10sIGludCBuZXdzaXplKSB7Ci0gICAgICAgIFhTQ29tcGxleFR5cGVEZWNsIG5ld2FycmF5W11bXSA9IG5ldyBYU0NvbXBsZXhUeXBlRGVjbFtuZXdzaXplXVtdOwotICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGFycmF5LCAwLCBuZXdhcnJheSwgMCwgYXJyYXkubGVuZ3RoKTsKLSAgICAgICAgcmV0dXJuIG5ld2FycmF5OwotICAgIH0KLQotCi0KLSAgICBwdWJsaWMgdm9pZCByZXNldCgpewotICAgICAgICBmRWxlbWVudERlY2xJbmRleCA9IDA7Ci0gICAgICAgIGZQYXJ0aWNsZURlY2xJbmRleCA9IDA7Ci0gICAgICAgIGZNb2RlbEdyb3VwSW5kZXggPSAwOwotICAgICAgICBmU1REZWNsSW5kZXggPSAwOwotICAgICAgICBmQ1REZWNsSW5kZXggPSAwOwotICAgICAgICBmQXR0ckRlY2xJbmRleCA9IDA7Ci0gICAgICAgIGZBdHRyaWJ1dGVVc2VJbmRleCA9IDA7Ci0gICAgfQotCi0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvWFNFbGVtZW50RGVjbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9YU0VsZW1lbnREZWNsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDE5MGRhYTcuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9YU0VsZW1lbnREZWNsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzODggKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYuVmFsaWRhdGVkSW5mbzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMuaWRlbnRpdHkuSWRlbnRpdHlDb25zdHJhaW50OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy51dGlsLlhTTmFtZWRNYXBJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy51dGlsLlhTT2JqZWN0TGlzdEltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuUU5hbWU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5TaG9ydExpc3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU0Fubm90YXRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU0NvbXBsZXhUeXBlRGVmaW5pdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNFbGVtZW50RGVjbGFyYXRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU05hbWVkTWFwOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNOYW1lc3BhY2VJdGVtOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNPYmplY3RMaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNUeXBlRGVmaW5pdGlvbjsKLQotLyoqCi0gKiBUaGUgWE1MIHJlcHJlc2VudGF0aW9uIGZvciBhbiBlbGVtZW50IGRlY2xhcmF0aW9uCi0gKiBzY2hlbWEgY29tcG9uZW50IGlzIGFuIDxlbGVtZW50PiBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBFbGVuYSBMaXRhbmksIElCTQotICogQGF1dGhvciBTYW5keSBHYW8sIElCTQotICogQHZlcnNpb24gJElkOiBYU0VsZW1lbnREZWNsLmphdmEsdiAxLjcgMjAxMC0xMS0wMSAwNDozOTo1NSBqb2VodyBFeHAgJAotICovCi1wdWJsaWMgY2xhc3MgWFNFbGVtZW50RGVjbCBpbXBsZW1lbnRzIFhTRWxlbWVudERlY2xhcmF0aW9uIHsKLQotICAgIC8vIHNjb3BlcwotICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgc2hvcnQgICAgIFNDT1BFX0FCU0VOVCAgICAgICAgPSAwOwotICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgc2hvcnQgICAgIFNDT1BFX0dMT0JBTCAgICAgICAgPSAxOwotICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgc2hvcnQgICAgIFNDT1BFX0xPQ0FMICAgICAgICAgPSAyOwotCi0gICAgLy8gbmFtZSBvZiB0aGUgZWxlbWVudAotICAgIHB1YmxpYyBTdHJpbmcgZk5hbWUgPSBudWxsOwotICAgIC8vIHRhcmdldCBuYW1lc3BhY2Ugb2YgdGhlIGVsZW1lbnQKLSAgICBwdWJsaWMgU3RyaW5nIGZUYXJnZXROYW1lc3BhY2UgPSBudWxsOwotICAgIC8vIHR5cGUgb2YgdGhlIGVsZW1lbnQKLSAgICBwdWJsaWMgWFNUeXBlRGVmaW5pdGlvbiBmVHlwZSA9IG51bGw7Ci0gICAgcHVibGljIFFOYW1lIGZVbnJlc29sdmVkVHlwZU5hbWUgPSBudWxsOwotICAgIC8vIG1pc2MgZmxhZyBvZiB0aGUgZWxlbWVudDogbmlsbGFibGUvYWJzdHJhY3QvZml4ZWQKLSAgICBzaG9ydCBmTWlzY0ZsYWdzID0gMDsKLSAgICBwdWJsaWMgc2hvcnQgZlNjb3BlID0gWFNDb25zdGFudHMuU0NPUEVfQUJTRU5UOwotICAgIC8vIGVuY2xvc2luZyBjb21wbGV4IHR5cGUsIHdoZW4gdGhlIHNjb3BlIGlzIGxvY2FsCi0gICAgWFNDb21wbGV4VHlwZURlY2wgZkVuY2xvc2luZ0NUID0gbnVsbDsKLSAgICAvLyBibG9jayBzZXQgKGRpc2FsbG93ZWQgc3Vic3RpdHV0aW9ucykgb2YgdGhlIGVsZW1lbnQKLSAgICBwdWJsaWMgc2hvcnQgZkJsb2NrID0gWFNDb25zdGFudHMuREVSSVZBVElPTl9OT05FOwotICAgIC8vIGZpbmFsIHNldCAoc3Vic3RpdHV0aW9uIGdyb3VwIGV4Y2x1c2lvbnMpIG9mIHRoZSBlbGVtZW50Ci0gICAgcHVibGljIHNob3J0IGZGaW5hbCA9IFhTQ29uc3RhbnRzLkRFUklWQVRJT05fTk9ORTsKLSAgICAvLyBvcHRpb25hbCBhbm5vdGF0aW9uCi0gICAgcHVibGljIFhTT2JqZWN0TGlzdCBmQW5ub3RhdGlvbnMgPSBudWxsOwotICAgIC8vIHZhbHVlIGNvbnN0cmFpbnQgdmFsdWUKLSAgICBwdWJsaWMgVmFsaWRhdGVkSW5mbyBmRGVmYXVsdCA9IG51bGw7Ci0gICAgLy8gdGhlIHN1YnN0aXR1dGlvbiBncm91cCBhZmZpbGlhdGlvbiBvZiB0aGUgZWxlbWVudAotICAgIHB1YmxpYyBYU0VsZW1lbnREZWNsIGZTdWJHcm91cCA9IG51bGw7Ci0gICAgLy8gaWRlbnRpdHkgY29uc3RyYWludHMKLSAgICBzdGF0aWMgZmluYWwgaW50IElOSVRJQUxfU0laRSA9IDI7Ci0gICAgaW50IGZJRENQb3MgPSAwOwotICAgIElkZW50aXR5Q29uc3RyYWludFtdIGZJRENvbnN0cmFpbnRzID0gbmV3IElkZW50aXR5Q29uc3RyYWludFtJTklUSUFMX1NJWkVdOwotICAgIC8vIFRoZSBuYW1lc3BhY2Ugc2NoZW1hIGluZm9ybWF0aW9uIGl0ZW0gY29ycmVzcG9uZGluZyB0byB0aGUgdGFyZ2V0IG5hbWVzcGFjZQotICAgIC8vIG9mIHRoZSBlbGVtZW50IGRlY2xhcmF0aW9uLCBpZiBpdCBpcyBnbG9iYWxseSBkZWNsYXJlZDsgb3IgbnVsbCBvdGhlcndpc2UuCi0gICAgcHJpdmF0ZSBYU05hbWVzcGFjZUl0ZW0gZk5hbWVzcGFjZUl0ZW0gPSBudWxsOwotCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgc2hvcnQgQ09OU1RSQUlOVF9NQVNLID0gMzsKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBzaG9ydCBOSUxMQUJMRSAgICAgICAgPSA0OwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHNob3J0IEFCU1RSQUNUICAgICAgICA9IDg7Ci0KLSAgICAvLyBtZXRob2RzIHRvIGdldC9zZXQgbWlzYyBmbGFnCi0gICAgcHVibGljIHZvaWQgc2V0Q29uc3RyYWludFR5cGUoc2hvcnQgY29uc3RyYWludFR5cGUpIHsKLSAgICAgICAgLy8gZmlyc3QgY2xlYXIgdGhlIGJpdHMKLSAgICAgICAgZk1pc2NGbGFncyBePSAoZk1pc2NGbGFncyAmIENPTlNUUkFJTlRfTUFTSyk7Ci0gICAgICAgIC8vIHRoZW4gc2V0IHRoZSBwcm9wZXIgb25lCi0gICAgICAgIGZNaXNjRmxhZ3MgfD0gKGNvbnN0cmFpbnRUeXBlICYgQ09OU1RSQUlOVF9NQVNLKTsKLSAgICB9Ci0gICAgcHVibGljIHZvaWQgc2V0SXNOaWxsYWJsZSgpIHsKLSAgICAgICAgZk1pc2NGbGFncyB8PSBOSUxMQUJMRTsKLSAgICB9Ci0gICAgcHVibGljIHZvaWQgc2V0SXNBYnN0cmFjdCgpIHsKLSAgICAgICAgZk1pc2NGbGFncyB8PSBBQlNUUkFDVDsKLSAgICB9Ci0gICAgcHVibGljIHZvaWQgc2V0SXNHbG9iYWwoKSB7Ci0gICAgICAgIGZTY29wZSA9IFNDT1BFX0dMT0JBTDsKLSAgICB9Ci0gICAgcHVibGljIHZvaWQgc2V0SXNMb2NhbChYU0NvbXBsZXhUeXBlRGVjbCBlbmNsb3NpbmdDVCkgewotICAgICAgICBmU2NvcGUgPSBTQ09QRV9MT0NBTDsKLSAgICAgICAgZkVuY2xvc2luZ0NUID0gZW5jbG9zaW5nQ1Q7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgYWRkSURDb25zdHJhaW50KElkZW50aXR5Q29uc3RyYWludCBpZGMpIHsKLSAgICAgICAgaWYgKGZJRENQb3MgPT0gZklEQ29uc3RyYWludHMubGVuZ3RoKSB7Ci0gICAgICAgICAgICBmSURDb25zdHJhaW50cyA9IHJlc2l6ZShmSURDb25zdHJhaW50cywgZklEQ1BvcyoyKTsKLSAgICAgICAgfQotICAgICAgICBmSURDb25zdHJhaW50c1tmSURDUG9zKytdID0gaWRjOwotICAgIH0KLQotICAgIHB1YmxpYyBJZGVudGl0eUNvbnN0cmFpbnRbXSBnZXRJRENvbnN0cmFpbnRzKCkgewotICAgICAgICBpZiAoZklEQ1BvcyA9PSAwKSB7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotICAgICAgICBpZiAoZklEQ1BvcyA8IGZJRENvbnN0cmFpbnRzLmxlbmd0aCkgewotICAgICAgICAgICAgZklEQ29uc3RyYWludHMgPSByZXNpemUoZklEQ29uc3RyYWludHMsIGZJRENQb3MpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmSURDb25zdHJhaW50czsKLSAgICB9Ci0KLSAgICBzdGF0aWMgZmluYWwgSWRlbnRpdHlDb25zdHJhaW50W10gcmVzaXplKElkZW50aXR5Q29uc3RyYWludFtdIG9sZEFycmF5LCBpbnQgbmV3U2l6ZSkgewotICAgICAgICBJZGVudGl0eUNvbnN0cmFpbnRbXSBuZXdBcnJheSA9IG5ldyBJZGVudGl0eUNvbnN0cmFpbnRbbmV3U2l6ZV07Ci0gICAgICAgIFN5c3RlbS5hcnJheWNvcHkob2xkQXJyYXksIDAsIG5ld0FycmF5LCAwLCBNYXRoLm1pbihvbGRBcnJheS5sZW5ndGgsIG5ld1NpemUpKTsKLSAgICAgICAgcmV0dXJuIG5ld0FycmF5OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIGdldCB0aGUgc3RyaW5nIGRlc2NyaXB0aW9uIG9mIHRoaXMgZWxlbWVudAotICAgICAqLwotICAgIHByaXZhdGUgU3RyaW5nIGZEZXNjcmlwdGlvbiA9IG51bGw7Ci0gICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKLSAgICAgICAgaWYgKGZEZXNjcmlwdGlvbiA9PSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAoZlRhcmdldE5hbWVzcGFjZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nQnVmZmVyIGJ1ZmZlciA9IG5ldyBTdHJpbmdCdWZmZXIoCi0gICAgICAgICAgICAgICAgICAgIGZUYXJnZXROYW1lc3BhY2UubGVuZ3RoKCkgKwotICAgICAgICAgICAgICAgICAgICAoKGZOYW1lICE9IG51bGwpID8gZk5hbWUubGVuZ3RoKCkgOiA0KSArIDMpOwotICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoJyInKTsKLSAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKGZUYXJnZXROYW1lc3BhY2UpOwotICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoJyInKTsKLSAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCc6Jyk7Ci0gICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZChmTmFtZSk7Ci0gICAgICAgICAgICAgICAgZkRlc2NyaXB0aW9uID0gYnVmZmVyLnRvU3RyaW5nKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBmRGVzY3JpcHRpb24gPSBmTmFtZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZkRlc2NyaXB0aW9uOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIGdldCB0aGUgaGFzaCBjb2RlCi0gICAgICovCi0gICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKLSAgICAgICAgaW50IGNvZGUgPSBmTmFtZS5oYXNoQ29kZSgpOwotICAgICAgICBpZiAoZlRhcmdldE5hbWVzcGFjZSAhPSBudWxsKQotICAgICAgICAgICAgY29kZSA9IChjb2RlPDwxNikrZlRhcmdldE5hbWVzcGFjZS5oYXNoQ29kZSgpOwotICAgICAgICByZXR1cm4gY29kZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiB3aGV0aGVyIHR3byBkZWNscyBhcmUgdGhlIHNhbWUKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG8pIHsKLSAgICAgICAgcmV0dXJuIG8gPT0gdGhpczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgICogUmVzZXQgY3VycmVudCBlbGVtZW50IGRlY2xhcmF0aW9uCi0gICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHJlc2V0KCl7Ci0gICAgICAgIGZTY29wZSA9IFhTQ29uc3RhbnRzLlNDT1BFX0FCU0VOVDsKLSAgICAgICAgZk5hbWUgPSBudWxsOwotICAgICAgICBmVGFyZ2V0TmFtZXNwYWNlID0gbnVsbDsKLSAgICAgICAgZlR5cGUgPSBudWxsOwotICAgICAgICBmVW5yZXNvbHZlZFR5cGVOYW1lID0gbnVsbDsKLSAgICAgICAgZk1pc2NGbGFncyA9IDA7Ci0gICAgICAgIGZCbG9jayA9IFhTQ29uc3RhbnRzLkRFUklWQVRJT05fTk9ORTsKLSAgICAgICAgZkZpbmFsID0gWFNDb25zdGFudHMuREVSSVZBVElPTl9OT05FOwotICAgICAgICBmRGVmYXVsdCA9IG51bGw7Ci0gICAgICAgIGZBbm5vdGF0aW9ucyA9IG51bGw7Ci0gICAgICAgIGZTdWJHcm91cCA9IG51bGw7Ci0gICAgICAgIC8vIHJlc2V0IGlkZW50aXR5IGNvbnN0cmFpbnRzCi0gICAgICAgIGZvciAoaW50IGk9MDtpPGZJRENQb3M7aSsrKSB7Ci0gICAgICAgICAgICBmSURDb25zdHJhaW50c1tpXSA9IG51bGw7Ci0gICAgICAgIH0KLQotICAgICAgICBmSURDUG9zID0gMDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIHR5cGUgb2YgdGhlIG9iamVjdCwgaS5lIEVMRU1FTlRfREVDTEFSQVRJT04uCi0gICAgICovCi0gICAgcHVibGljIHNob3J0IGdldFR5cGUoKSB7Ci0gICAgICAgIHJldHVybiBYU0NvbnN0YW50cy5FTEVNRU5UX0RFQ0xBUkFUSU9OOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoZSA8Y29kZT5uYW1lPC9jb2RlPiBvZiB0aGlzIDxjb2RlPlhTT2JqZWN0PC9jb2RlPiBkZXBlbmRpbmcgb24gdGhlCi0gICAgICogPGNvZGU+WFNPYmplY3Q8L2NvZGU+IHR5cGUuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXROYW1lKCkgewotICAgICAgICByZXR1cm4gZk5hbWU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhlIG5hbWVzcGFjZSBVUkkgb2YgdGhpcyBub2RlLCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiBpdCBpcwotICAgICAqIHVuc3BlY2lmaWVkLiAgZGVmaW5lcyBob3cgYSBuYW1lc3BhY2UgVVJJIGlzIGF0dGFjaGVkIHRvIHNjaGVtYQotICAgICAqIGNvbXBvbmVudHMuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXROYW1lc3BhY2UoKSB7Ci0gICAgICAgIHJldHVybiBmVGFyZ2V0TmFtZXNwYWNlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEVpdGhlciBhIHNpbXBsZSB0eXBlIGRlZmluaXRpb24gb3IgYSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFNUeXBlRGVmaW5pdGlvbiBnZXRUeXBlRGVmaW5pdGlvbigpIHsKLSAgICAgICAgcmV0dXJuIGZUeXBlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIE9wdGlvbmFsLiBFaXRoZXIgZ2xvYmFsIG9yIGEgY29tcGxleCB0eXBlIGRlZmluaXRpb24gKAotICAgICAqIDxjb2RlPmN0RGVmaW5pdGlvbjwvY29kZT4pLiBUaGlzIHByb3BlcnR5IGlzIGFic2VudCBpbiB0aGUgY2FzZSBvZgotICAgICAqIGRlY2xhcmF0aW9ucyB3aXRoaW4gbmFtZWQgbW9kZWwgZ3JvdXBzOiB0aGVpciBzY29wZSB3aWxsIGJlCi0gICAgICogZGV0ZXJtaW5lZCB3aGVuIHRoZXkgYXJlIHVzZWQgaW4gdGhlIGNvbnN0cnVjdGlvbiBvZiBjb21wbGV4IHR5cGUKLSAgICAgKiBkZWZpbml0aW9ucy4KLSAgICAgKi8KLSAgICBwdWJsaWMgc2hvcnQgZ2V0U2NvcGUoKSB7Ci0gICAgICAgIHJldHVybiBmU2NvcGU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogTG9jYWxseSBzY29wZWQgZGVjbGFyYXRpb25zIGFyZSBhdmFpbGFibGUgZm9yIHVzZSBvbmx5IHdpdGhpbiB0aGUKLSAgICAgKiBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbiBpZGVudGlmaWVkIGJ5IHRoZSA8Y29kZT5zY29wZTwvY29kZT4KLSAgICAgKiBwcm9wZXJ0eS4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFNDb21wbGV4VHlwZURlZmluaXRpb24gZ2V0RW5jbG9zaW5nQ1REZWZpbml0aW9uKCkgewotICAgICAgICByZXR1cm4gZkVuY2xvc2luZ0NUOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEEgdmFsdWUgY29uc3RyYWludDogb25lIG9mIGRlZmF1bHQsIGZpeGVkLgotICAgICAqLwotICAgIHB1YmxpYyBzaG9ydCBnZXRDb25zdHJhaW50VHlwZSgpIHsKLSAgICAgICAgcmV0dXJuIChzaG9ydCkoZk1pc2NGbGFncyAmIENPTlNUUkFJTlRfTUFTSyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQSB2YWx1ZSBjb25zdHJhaW50OiBUaGUgYWN0dWFsIHZhbHVlICh3aXRoIHJlc3BlY3QgdG8gdGhlIHt0eXBlCi0gICAgICogZGVmaW5pdGlvbn0pCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRDb25zdHJhaW50VmFsdWUoKSB7Ci0gICAgICAgIC8vIFJFVklTSVQ6IFNDQVBJOiB3aGF0J3MgdGhlIHByb3BlciByZXByZXNlbnRhdGlvbgotICAgICAgICByZXR1cm4gZ2V0Q29uc3RyYWludFR5cGUoKSA9PSBYU0NvbnN0YW50cy5WQ19OT05FID8KLSAgICAgICAgICAgICAgIG51bGwgOgotICAgICAgICAgICAgICAgZkRlZmF1bHQuc3RyaW5nVmFsdWUoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJZiB7bmlsbGFibGV9IGlzIHRydWUsIHRoZW4gYW4gZWxlbWVudCBtYXkgYWxzbyBiZSB2YWxpZCBpZiBpdCBjYXJyaWVzCi0gICAgICogdGhlIG5hbWVzcGFjZSBxdWFsaWZpZWQgYXR0cmlidXRlIHdpdGggW2xvY2FsIG5hbWVdIG5pbCBmcm9tCi0gICAgICogbmFtZXNwYWNlIGh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIGFuZCB2YWx1ZSB0cnVlCi0gICAgICogKHNlZSB4c2k6bmlsICgyLjYuMikpIGV2ZW4gaWYgaXQgaGFzIG5vIHRleHQgb3IgZWxlbWVudCBjb250ZW50Ci0gICAgICogZGVzcGl0ZSBhIHtjb250ZW50IHR5cGV9IHdoaWNoIHdvdWxkIG90aGVyd2lzZSByZXF1aXJlIGNvbnRlbnQuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0TmlsbGFibGUoKSB7Ci0gICAgICAgIHJldHVybiAoKGZNaXNjRmxhZ3MgJiBOSUxMQUJMRSkgIT0gMCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICoge2lkZW50aXR5LWNvbnN0cmFpbnQgZGVmaW5pdGlvbnN9IEEgc2V0IG9mIGNvbnN0cmFpbnQgZGVmaW5pdGlvbnMuCi0gICAgICovCi0gICAgcHVibGljIFhTTmFtZWRNYXAgZ2V0SWRlbnRpdHlDb25zdHJhaW50cygpIHsKLSAgICAgICAgcmV0dXJuIG5ldyBYU05hbWVkTWFwSW1wbChmSURDb25zdHJhaW50cywgZklEQ1Bvcyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICoge3N1YnN0aXR1dGlvbiBncm91cCBhZmZpbGlhdGlvbn0gT3B0aW9uYWwuIEEgdG9wLWxldmVsIGVsZW1lbnQKLSAgICAgKiBkZWZpbml0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBYU0VsZW1lbnREZWNsYXJhdGlvbiBnZXRTdWJzdGl0dXRpb25Hcm91cEFmZmlsaWF0aW9uKCkgewotICAgICAgICByZXR1cm4gZlN1Ykdyb3VwOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbnZlbmllbmNlIG1ldGhvZC4gQ2hlY2sgaWYgPGNvZGU+ZXhjbHVzaW9uPC9jb2RlPiBpcyBhIHN1YnN0aXR1dGlvbgotICAgICAqIGdyb3VwIGV4Y2x1c2lvbiBmb3IgdGhpcyBlbGVtZW50IGRlY2xhcmF0aW9uLgotICAgICAqIEBwYXJhbSBleGNsdXNpb24gRXh0ZW5zaW9uLCByZXN0cmljdGlvbiBvciBub25lLiBSZXByZXNlbnRzIGZpbmFsCi0gICAgICogICBzZXQgZm9yIHRoZSBlbGVtZW50LgotICAgICAqIEByZXR1cm4gVHJ1ZSBpZiA8Y29kZT5leGNsdXNpb248L2NvZGU+IGlzIGEgcGFydCBvZiB0aGUgc3Vic3RpdHV0aW9uCi0gICAgICogICBncm91cCBleGNsdXNpb24gc3Vic2V0LgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzU3Vic3RpdHV0aW9uR3JvdXBFeGNsdXNpb24oc2hvcnQgZXhjbHVzaW9uKSB7Ci0gICAgICAgIHJldHVybiAoZkZpbmFsICYgZXhjbHVzaW9uKSAhPSAwOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNwZWNpZmllcyBpZiB0aGlzIGRlY2xhcmF0aW9uIGNhbiBiZSBub21pbmF0ZWQgYXMKLSAgICAgKiB0aGUge3N1YnN0aXR1dGlvbiBncm91cCBhZmZpbGlhdGlvbn0gb2Ygb3RoZXIKLSAgICAgKiBlbGVtZW50IGRlY2xhcmF0aW9ucyBoYXZpbmcgdGhlIHNhbWUge3R5cGUgZGVmaW5pdGlvbn0KLSAgICAgKiBvciB0eXBlcyBkZXJpdmVkIHRoZXJlZnJvbS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gQSBiaXQgZmxhZyByZXByZXNlbnRpbmcge2V4dGVuc2lvbiwgcmVzdHJpY3Rpb259IG9yIE5PTkUuCi0gICAgICovCi0gICAgcHVibGljIHNob3J0IGdldFN1YnN0aXR1dGlvbkdyb3VwRXhjbHVzaW9ucygpIHsKLSAgICAgICAgcmV0dXJuIGZGaW5hbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb252ZW5pZW5jZSBtZXRob2QuIENoZWNrIGlmIDxjb2RlPmRpc2FsbG93ZWQ8L2NvZGU+IGlzIGEgZGlzYWxsb3dlZAotICAgICAqIHN1YnN0aXR1dGlvbiBmb3IgdGhpcyBlbGVtZW50IGRlY2xhcmF0aW9uLgotICAgICAqIEBwYXJhbSBkaXNhbGxvd2VkIFN1YnN0aXR1dGlvbiwgZXh0ZW5zaW9uLCByZXN0cmljdGlvbiBvciBub25lLgotICAgICAqICAgUmVwcmVzZW50cyBhIGJsb2NrIHNldCBmb3IgdGhlIGVsZW1lbnQuCi0gICAgICogQHJldHVybiBUcnVlIGlmIDxjb2RlPmRpc2FsbG93ZWQ8L2NvZGU+IGlzIGEgcGFydCBvZiB0aGUgc3Vic3RpdHV0aW9uCi0gICAgICogICBncm91cCBleGNsdXNpb24gc3Vic2V0LgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzRGlzYWxsb3dlZFN1YnN0aXR1dGlvbihzaG9ydCBkaXNhbGxvd2VkKSB7Ci0gICAgICAgIHJldHVybiAoZkJsb2NrICYgZGlzYWxsb3dlZCkgIT0gMDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgc3VwcGxpZWQgdmFsdWVzIGZvciB7ZGlzYWxsb3dlZCBzdWJzdGl0dXRpb25zfQotICAgICAqCi0gICAgICogQHJldHVybiBBIGJpdCBmbGFnIHJlcHJlc2VudGluZyB7c3Vic3RpdHV0aW9uLCBleHRlbnNpb24sIHJlc3RyaWN0aW9ufSBvciBOT05FLgotICAgICAqLwotICAgIHB1YmxpYyBzaG9ydCBnZXREaXNhbGxvd2VkU3Vic3RpdHV0aW9ucygpIHsKLSAgICAgICAgcmV0dXJuIGZCbG9jazsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiB7YWJzdHJhY3R9IEEgYm9vbGVhbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXRBYnN0cmFjdCgpIHsKLSAgICAgICAgcmV0dXJuICgoZk1pc2NGbGFncyAmIEFCU1RSQUNUKSAhPSAwKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBPcHRpb25hbC4gQW5ub3RhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFNBbm5vdGF0aW9uIGdldEFubm90YXRpb24oKSB7Ci0gICAgICAgIHJldHVybiAoZkFubm90YXRpb25zICE9IG51bGwpID8gKFhTQW5ub3RhdGlvbikgZkFubm90YXRpb25zLml0ZW0oMCkgOiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIE9wdGlvbmFsLiBBbm5vdGF0aW9ucy4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFNPYmplY3RMaXN0IGdldEFubm90YXRpb25zKCkgewotICAgICAgICByZXR1cm4gKGZBbm5vdGF0aW9ucyAhPSBudWxsKSA/IGZBbm5vdGF0aW9ucyA6IFhTT2JqZWN0TGlzdEltcGwuRU1QVFlfTElTVDsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIEBzZWUgb3JnLmFwYWNoZS54ZXJjZXMueHMuWFNPYmplY3QjZ2V0TmFtZXNwYWNlSXRlbSgpCi0gICAgICovCi0gICAgcHVibGljIFhTTmFtZXNwYWNlSXRlbSBnZXROYW1lc3BhY2VJdGVtKCkgewotICAgICAgICByZXR1cm4gZk5hbWVzcGFjZUl0ZW07Ci0gICAgfQotCi0gICAgdm9pZCBzZXROYW1lc3BhY2VJdGVtKFhTTmFtZXNwYWNlSXRlbSBuYW1lc3BhY2VJdGVtKSB7Ci0gICAgICAgIGZOYW1lc3BhY2VJdGVtID0gbmFtZXNwYWNlSXRlbTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgT2JqZWN0IGdldEFjdHVhbFZDKCkgewotICAgICAgICByZXR1cm4gZ2V0Q29uc3RyYWludFR5cGUoKSA9PSBYU0NvbnN0YW50cy5WQ19OT05FID8KLSAgICAgICAgICAgICAgIG51bGwgOgotICAgICAgICAgICAgICAgZkRlZmF1bHQuYWN0dWFsVmFsdWU7Ci0gICAgfQotCi0gICAgcHVibGljIHNob3J0IGdldEFjdHVhbFZDVHlwZSgpIHsKLSAgICAgICAgcmV0dXJuIGdldENvbnN0cmFpbnRUeXBlKCkgPT0gWFNDb25zdGFudHMuVkNfTk9ORSA/Ci0gICAgICAgICAgICAgICBYU0NvbnN0YW50cy5VTkFWQUlMQUJMRV9EVCA6Ci0gICAgICAgICAgICAgICBmRGVmYXVsdC5hY3R1YWxWYWx1ZVR5cGU7Ci0gICAgfQotCi0gICAgcHVibGljIFNob3J0TGlzdCBnZXRJdGVtVmFsdWVUeXBlcygpIHsKLSAgICAgICAgcmV0dXJuIGdldENvbnN0cmFpbnRUeXBlKCkgPT0gWFNDb25zdGFudHMuVkNfTk9ORSA/Ci0gICAgICAgICAgICAgICBudWxsIDoKLSAgICAgICAgICAgICAgIGZEZWZhdWx0Lml0ZW1WYWx1ZVR5cGVzOwotICAgIH0KLQotfSAvLyBjbGFzcyBYU0VsZW1lbnREZWNsCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL1hTR3JhbW1hckJ1Y2tldC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9YU0dyYW1tYXJCdWNrZXQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNTI1YWZlZS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL1hTR3JhbW1hckJ1Y2tldC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjQwICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKi8KLS8qCi0gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKLSAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAotICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgotICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKLSAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCi0gKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHM7Ci0KLWltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKLWltcG9ydCBqYXZhLnV0aWwuTWFwOwotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLS8qKgotICogQSBjbGFzcyB1c2VkIHRvIGhvbGQgdGhlIGludGVybmFsIHNjaGVtYSBncmFtbWFyIHNldCBmb3IgdGhlIGN1cnJlbnQgaW5zdGFuY2UKLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBTYW5keSBHYW8sIElCTQotICogQHZlcnNpb24gJElkOiBYU0dyYW1tYXJCdWNrZXQuamF2YSx2IDEuNyAyMDEwLTExLTAxIDA0OjM5OjU1IGpvZWh3IEV4cCAkCi0gKi8KLXB1YmxpYyBjbGFzcyBYU0dyYW1tYXJCdWNrZXQgewotCi0gICAgLy8gRGF0YQotCi0gICAgLyoqCi0gICAgICogTWFwIHRoYXQgbWFwcyBiZXR3ZWVuIE5hbWVzcGFjZSBhbmQgYSBHcmFtbWFyCi0gICAgICovCi0gICAgTWFwPFN0cmluZywgU2NoZW1hR3JhbW1hcj4gZkdyYW1tYXJSZWdpc3RyeSA9IG5ldyBIYXNoTWFwKCk7Ci0gICAgU2NoZW1hR3JhbW1hciBmTm9OU0dyYW1tYXIgPSBudWxsOwotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBzY2hlbWEgZ3JhbW1hciBmb3IgdGhlIHNwZWNpZmllZCBuYW1lc3BhY2UKLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lc3BhY2UKLSAgICAgKiBAcmV0dXJuIFNjaGVtYUdyYW1tYXIgYXNzb2NpYXRlZCB3aXRoIHRoZSBuYW1lc3BhY2UKLSAgICAgKi8KLSAgICBwdWJsaWMgU2NoZW1hR3JhbW1hciBnZXRHcmFtbWFyKFN0cmluZyBuYW1lc3BhY2UpIHsKLSAgICAgICAgaWYgKG5hbWVzcGFjZSA9PSBudWxsKQotICAgICAgICAgICAgcmV0dXJuIGZOb05TR3JhbW1hcjsKLSAgICAgICAgcmV0dXJuIChTY2hlbWFHcmFtbWFyKWZHcmFtbWFyUmVnaXN0cnkuZ2V0KG5hbWVzcGFjZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUHV0IGEgc2NoZW1hIGdyYW1tYXIgaW50byB0aGUgcmVnaXN0cnkKLSAgICAgKiBUaGlzIG1ldGhvZCBpcyBmb3IgaW50ZXJuYWwgdXNlIG9ubHk6IGl0IGFzc3VtZXMgdGhhdCBhIGdyYW1tYXIgd2l0aAotICAgICAqIHRoZSBzYW1lIHRhcmdldCBuYW1lc3BhY2UgaXMgbm90IGFscmVhZHkgaW4gdGhlIGJ1Y2tldC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBncmFtbWFyICAgdGhlIGdyYW1tYXIgdG8gcHV0IGluIHRoZSByZWdpc3RyeQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHB1dEdyYW1tYXIoU2NoZW1hR3JhbW1hciBncmFtbWFyKSB7Ci0gICAgICAgIGlmIChncmFtbWFyLmdldFRhcmdldE5hbWVzcGFjZSgpID09IG51bGwpCi0gICAgICAgICAgICBmTm9OU0dyYW1tYXIgPSBncmFtbWFyOwotICAgICAgICBlbHNlCi0gICAgICAgICAgICBmR3JhbW1hclJlZ2lzdHJ5LnB1dChncmFtbWFyLmdldFRhcmdldE5hbWVzcGFjZSgpLCBncmFtbWFyKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBwdXQgYSBzY2hlbWEgZ3JhbW1hciBhbmQgYW55IGdyYW1tYXJzIGltcG9ydGVkIGJ5IGl0IChkaXJlY3RseSBvcgotICAgICAqIGluZGVyZWN0bHkpIGludG8gdGhlIHJlZ2lzdHJ5LiB3aGVuIGEgZ3JhbW1hciB3aXRoIHRoZSBzYW1lIHRhcmdldAotICAgICAqIG5hbWVzcGFjZSBpcyBhbHJlYWR5IGluIHRoZSBidWNrZXQsIGFuZCBkaWZmZXJlbnQgZnJvbSB0aGUgb25lIGJlaW5nCi0gICAgICogYWRkZWQsIGl0J3MgYW4gZXJyb3IsIGFuZCBubyBncmFtbWFyIHdpbGwgYmUgYWRkZWQgaW50byB0aGUgYnVja2V0LgotICAgICAqCi0gICAgICogQHBhcmFtIGdyYW1tYXIgICB0aGUgZ3JhbW1hciB0byBwdXQgaW4gdGhlIHJlZ2lzdHJ5Ci0gICAgICogQHBhcmFtIGRlZXAgICAgICB3aGV0aGVyIHRvIGFkZCBpbXBvcnRlZCBncmFtbWFycwotICAgICAqIEByZXR1cm4gICAgICAgICAgd2hldGhlciB0aGUgcHJvY2VzcyBzdWNjZWVkZWQKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBwdXRHcmFtbWFyKFNjaGVtYUdyYW1tYXIgZ3JhbW1hciwgYm9vbGVhbiBkZWVwKSB7Ci0gICAgICAgIC8vIHdoZXRoZXIgdGhlcmUgaXMgb25lIHdpdGggdGhlIHNhbWUgdG5zCi0gICAgICAgIFNjaGVtYUdyYW1tYXIgc2cgPSBnZXRHcmFtbWFyKGdyYW1tYXIuZlRhcmdldE5hbWVzcGFjZSk7Ci0gICAgICAgIGlmIChzZyAhPSBudWxsKSB7Ci0gICAgICAgICAgICAvLyBpZiB0aGUgb25lIHdlIGhhdmUgaXMgZGlmZmVyZW50IGZyb20gdGhlIG9uZSBwYXNzZWQsIGl0J3MgYW4gZXJyb3IKLSAgICAgICAgICAgIHJldHVybiBzZyA9PSBncmFtbWFyOwotICAgICAgICB9Ci0gICAgICAgIC8vIG5vdCBkZWVwIGltcG9ydCwgdGhlbiBqdXN0IGFkZCB0aGlzIG9uZSBncmFtbWFyCi0gICAgICAgIGlmICghZGVlcCkgewotICAgICAgICAgICAgcHV0R3JhbW1hcihncmFtbWFyKTsKLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gZ2V0IGFsbCBpbXBvcnRlZCBncmFtbWFycywgYW5kIG1ha2UgYSBjb3B5IG9mIHRoZSBWZWN0b3IsIHNvIHRoYXQKLSAgICAgICAgLy8gd2UgY2FuIHJlY3Vyc2l2ZWx5IHByb2Nlc3MgdGhlIGdyYW1tYXJzLCBhbmQgYWRkIGRpc3RpbmN0IG9uZXMKLSAgICAgICAgLy8gdG8gdGhlIHNhbWUgdmVjdG9yCi0gICAgICAgIFZlY3RvciBjdXJyR3JhbW1hcnMgPSAoVmVjdG9yKWdyYW1tYXIuZ2V0SW1wb3J0ZWRHcmFtbWFycygpOwotICAgICAgICBpZiAoY3VyckdyYW1tYXJzID09IG51bGwpIHsKLSAgICAgICAgICAgIHB1dEdyYW1tYXIoZ3JhbW1hcik7Ci0gICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgfQotCi0gICAgICAgIFZlY3RvciBncmFtbWFycyA9ICgoVmVjdG9yKWN1cnJHcmFtbWFycy5jbG9uZSgpKTsKLSAgICAgICAgU2NoZW1hR3JhbW1hciBzZzEsIHNnMjsKLSAgICAgICAgVmVjdG9yIGdzOwotICAgICAgICAvLyBmb3IgYWxsIChyZWN1cnNpdmVseSkgaW1wb3J0ZWQgZ3JhbW1hcnMKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBncmFtbWFycy5zaXplKCk7IGkrKykgewotICAgICAgICAgICAgLy8gZ2V0IHRoZSBncmFtbWFyCi0gICAgICAgICAgICBzZzEgPSAoU2NoZW1hR3JhbW1hcilncmFtbWFycy5lbGVtZW50QXQoaSk7Ci0gICAgICAgICAgICAvLyBjaGVjayB3aGV0aGVyIHRoZSBidWNrZXQgaGFzIG9uZSB3aXRoIHRoZSBzYW1lIHRucwotICAgICAgICAgICAgc2cyID0gZ2V0R3JhbW1hcihzZzEuZlRhcmdldE5hbWVzcGFjZSk7Ci0gICAgICAgICAgICBpZiAoc2cyID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAvLyB3ZSBuZWVkIHRvIGFkZCBncmFtbWFycyBpbXBvcnRlZCBieSBzZzEgdG9vCi0gICAgICAgICAgICAgICAgZ3MgPSBzZzEuZ2V0SW1wb3J0ZWRHcmFtbWFycygpOwotICAgICAgICAgICAgICAgIC8vIGZvciBhbGwgZ3JhbW1hcnMgaW1wb3J0ZWQgYnkgc2cyLCBidXQgbm90IGluIHRoZSB2ZWN0b3IKLSAgICAgICAgICAgICAgICAvLyB3ZSBhZGQgdGhlbSB0byB0aGUgdmVjdG9yCi0gICAgICAgICAgICAgICAgaWYoZ3MgPT0gbnVsbCkgY29udGludWU7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaiA9IGdzLnNpemUoKSAtIDE7IGogPj0gMDsgai0tKSB7Ci0gICAgICAgICAgICAgICAgICAgIHNnMiA9IChTY2hlbWFHcmFtbWFyKWdzLmVsZW1lbnRBdChqKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKCFncmFtbWFycy5jb250YWlucyhzZzIpKQotICAgICAgICAgICAgICAgICAgICAgICAgZ3JhbW1hcnMuYWRkRWxlbWVudChzZzIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIHdlIGZvdW5kIG9uZSB3aXRoIHRoZSBzYW1lIHRhcmdldCBuYW1lc3BhY2UKLSAgICAgICAgICAgIC8vIGlmIHRoZSB0d28gZ3JhbW1hcnMgYXJlIG5vdCB0aGUgc2FtZSBvYmplY3QsIHRoZW4gaXQncyBhbiBlcnJvcgotICAgICAgICAgICAgZWxzZSBpZiAoc2cyICE9IHNnMSkgewotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIG5vdyB3ZSBoYXZlIGFsbCBpbXBvcnRlZCBncmFtbWFycyBzdG9yZWQgaW4gdGhlIHZlY3Rvci4gYWRkIHRoZW0KLSAgICAgICAgcHV0R3JhbW1hcihncmFtbWFyKTsKLSAgICAgICAgZm9yIChpbnQgaSA9IGdyYW1tYXJzLnNpemUoKSAtIDE7IGkgPj0gMDsgaS0tKQotICAgICAgICAgICAgcHV0R3JhbW1hcigoU2NoZW1hR3JhbW1hcilncmFtbWFycy5lbGVtZW50QXQoaSkpOwotCi0gICAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIHB1dCBhIHNjaGVtYSBncmFtbWFyIGFuZCBhbnkgZ3JhbW1hcnMgaW1wb3J0ZWQgYnkgaXQgKGRpcmVjdGx5IG9yCi0gICAgICogaW5kZXJlY3RseSkgaW50byB0aGUgcmVnaXN0cnkuIHdoZW4gYSBncmFtbWFyIHdpdGggdGhlIHNhbWUgdGFyZ2V0Ci0gICAgICogbmFtZXNwYWNlIGlzIGFscmVhZHkgaW4gdGhlIGJ1Y2tldCwgYW5kIGRpZmZlcmVudCBmcm9tIHRoZSBvbmUgYmVpbmcKLSAgICAgKiBhZGRlZCwgbm8gZ3JhbW1hciB3aWxsIGJlIGFkZGVkIGludG8gdGhlIGJ1Y2tldC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBncmFtbWFyICAgICAgICB0aGUgZ3JhbW1hciB0byBwdXQgaW4gdGhlIHJlZ2lzdHJ5Ci0gICAgICogQHBhcmFtIGRlZXAgICAgICAgICAgIHdoZXRoZXIgdG8gYWRkIGltcG9ydGVkIGdyYW1tYXJzCi0gICAgICogQHBhcmFtIGlnbm9yZUNvbmZsaWN0IHdoZXRoZXIgdG8gaWdub3JlIGdyYW1tYXJzIHRoYXQgYWxyZWFkeSBleGlzdCBpbiB0aGUgZ3JhbW1hcgotICAgICAqICAgICAgICAgICAgICAgICAgICAgICBidWNrZXQgb3Igbm90IC0gaW5jbHVkaW5nICdncmFtbWFyJyBwYXJhbWV0ZXIuCi0gICAgICogQHJldHVybiAgICAgICAgICAgICAgIHdoZXRoZXIgdGhlIHByb2Nlc3Mgc3VjY2VlZGVkCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gcHV0R3JhbW1hcihTY2hlbWFHcmFtbWFyIGdyYW1tYXIsIGJvb2xlYW4gZGVlcCwgYm9vbGVhbiBpZ25vcmVDb25mbGljdCkgewotICAgICAgICBpZiAoIWlnbm9yZUNvbmZsaWN0KSB7Ci0gICAgICAgICAgICByZXR1cm4gcHV0R3JhbW1hcihncmFtbWFyLCBkZWVwKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIGlmIGdyYW1tYXIgYWxyZWFkeSBleGlzdCBpbiB0aGUgYnVja2V0LCB3ZSBpZ25vcmUgdGhlIHJlcXVlc3QKLSAgICAgICAgU2NoZW1hR3JhbW1hciBzZyA9IGdldEdyYW1tYXIoZ3JhbW1hci5mVGFyZ2V0TmFtZXNwYWNlKTsKLSAgICAgICAgaWYgKHNnID09IG51bGwpIHsKLSAgICAgICAgICAgIHB1dEdyYW1tYXIoZ3JhbW1hcik7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBub3QgYWRkaW5nIHRoZSBpbXBvcnRlZCBncmFtbWFycwotICAgICAgICBpZiAoIWRlZXApIHsKLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gZ2V0IGFsbCBpbXBvcnRlZCBncmFtbWFycywgYW5kIG1ha2UgYSBjb3B5IG9mIHRoZSBWZWN0b3IsIHNvIHRoYXQKLSAgICAgICAgLy8gd2UgY2FuIHJlY3Vyc2l2ZWx5IHByb2Nlc3MgdGhlIGdyYW1tYXJzLCBhbmQgYWRkIGRpc3RpbmN0IG9uZXMKLSAgICAgICAgLy8gdG8gdGhlIHNhbWUgdmVjdG9yCi0gICAgICAgIFZlY3RvciBjdXJyR3JhbW1hcnMgPSAoVmVjdG9yKWdyYW1tYXIuZ2V0SW1wb3J0ZWRHcmFtbWFycygpOwotICAgICAgICBpZiAoY3VyckdyYW1tYXJzID09IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0KLSAgICAgICAgVmVjdG9yIGdyYW1tYXJzID0gKChWZWN0b3IpY3VyckdyYW1tYXJzLmNsb25lKCkpOwotICAgICAgICBTY2hlbWFHcmFtbWFyIHNnMSwgc2cyOwotICAgICAgICBWZWN0b3IgZ3M7Ci0gICAgICAgIC8vIGZvciBhbGwgKHJlY3Vyc2l2ZWx5KSBpbXBvcnRlZCBncmFtbWFycwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGdyYW1tYXJzLnNpemUoKTsgaSsrKSB7Ci0gICAgICAgICAgICAvLyBnZXQgdGhlIGdyYW1tYXIKLSAgICAgICAgICAgIHNnMSA9IChTY2hlbWFHcmFtbWFyKWdyYW1tYXJzLmVsZW1lbnRBdChpKTsKLSAgICAgICAgICAgIC8vIGNoZWNrIHdoZXRoZXIgdGhlIGJ1Y2tldCBoYXMgb25lIHdpdGggdGhlIHNhbWUgdG5zCi0gICAgICAgICAgICBzZzIgPSBnZXRHcmFtbWFyKHNnMS5mVGFyZ2V0TmFtZXNwYWNlKTsKLSAgICAgICAgICAgIGlmIChzZzIgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIC8vIHdlIG5lZWQgdG8gYWRkIGdyYW1tYXJzIGltcG9ydGVkIGJ5IHNnMSB0b28KLSAgICAgICAgICAgICAgICBncyA9IHNnMS5nZXRJbXBvcnRlZEdyYW1tYXJzKCk7Ci0gICAgICAgICAgICAgICAgLy8gZm9yIGFsbCBncmFtbWFycyBpbXBvcnRlZCBieSBzZzIsIGJ1dCBub3QgaW4gdGhlIHZlY3RvcgotICAgICAgICAgICAgICAgIC8vIHdlIGFkZCB0aGVtIHRvIHRoZSB2ZWN0b3IKLSAgICAgICAgICAgICAgICBpZihncyA9PSBudWxsKSBjb250aW51ZTsKLSAgICAgICAgICAgICAgICBmb3IgKGludCBqID0gZ3Muc2l6ZSgpIC0gMTsgaiA+PSAwOyBqLS0pIHsKLSAgICAgICAgICAgICAgICAgICAgc2cyID0gKFNjaGVtYUdyYW1tYXIpZ3MuZWxlbWVudEF0KGopOwotICAgICAgICAgICAgICAgICAgICBpZiAoIWdyYW1tYXJzLmNvbnRhaW5zKHNnMikpCi0gICAgICAgICAgICAgICAgICAgICAgICBncmFtbWFycy5hZGRFbGVtZW50KHNnMik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gd2UgZm91bmQgb25lIHdpdGggdGhlIHNhbWUgdGFyZ2V0IG5hbWVzcGFjZSwgaWdub3JlIGl0Ci0gICAgICAgICAgICBlbHNlICB7Ci0gICAgICAgICAgICAgICAgZ3JhbW1hcnMucmVtb3ZlKHNnMSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBub3cgd2UgaGF2ZSBhbGwgaW1wb3J0ZWQgZ3JhbW1hcnMgc3RvcmVkIGluIHRoZSB2ZWN0b3IuIGFkZCB0aGVtCi0gICAgICAgIGZvciAoaW50IGkgPSBncmFtbWFycy5zaXplKCkgLSAxOyBpID49IDA7IGktLSkgewotICAgICAgICAgICAgcHV0R3JhbW1hcigoU2NoZW1hR3JhbW1hcilncmFtbWFycy5lbGVtZW50QXQoaSkpOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogZ2V0IGFsbCBncmFtbWFycyBpbiB0aGUgcmVnaXN0cnkKLSAgICAgKgotICAgICAqIEByZXR1cm4gYW4gYXJyYXkgb2YgU2NoZW1hR3JhbW1hcnMuCi0gICAgICovCi0gICAgcHVibGljIFNjaGVtYUdyYW1tYXJbXSBnZXRHcmFtbWFycygpIHsKLSAgICAgICAgLy8gZ2V0IHRoZSBudW1iZXIgb2YgZ3JhbW1hcnMKLSAgICAgICAgaW50IGNvdW50ID0gZkdyYW1tYXJSZWdpc3RyeS5zaXplKCkgKyAoZk5vTlNHcmFtbWFyPT1udWxsID8gMCA6IDEpOwotICAgICAgICBTY2hlbWFHcmFtbWFyW10gZ3JhbW1hcnMgPSBuZXcgU2NoZW1hR3JhbW1hcltjb3VudF07Ci0gICAgICAgIC8vIGdldCBncmFtbWFycyB3aXRoIHRhcmdldCBuYW1lc3BhY2UKLSAgICAgICAgaW50IGkgPSAwOwotICAgICAgICBmb3IoTWFwLkVudHJ5PFN0cmluZywgU2NoZW1hR3JhbW1hcj4gZW50cnkgOiBmR3JhbW1hclJlZ2lzdHJ5LmVudHJ5U2V0KCkpewotICAgICAgICAgICAgZ3JhbW1hcnNbaSsrXSA9IGVudHJ5LmdldFZhbHVlKCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBhZGQgdGhlIGdyYW1tYXIgd2l0aG91dCB0YXJnZXQgbmFtZXNwYWNlLCBpZiBhbnkKLSAgICAgICAgaWYgKGZOb05TR3JhbW1hciAhPSBudWxsKQotICAgICAgICAgICAgZ3JhbW1hcnNbY291bnQtMV0gPSBmTm9OU0dyYW1tYXI7Ci0gICAgICAgIHJldHVybiBncmFtbWFyczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDbGVhciB0aGUgcmVnaXN0cnkuCi0gICAgICogUkVWSVNJVDogdXBkYXRlIHRvIHVzZSBhbm90aGVyIFhTR3JhbW1hckJ1Y2tldAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHJlc2V0KCkgewotICAgICAgICBmTm9OU0dyYW1tYXIgPSBudWxsOwotICAgICAgICBmR3JhbW1hclJlZ2lzdHJ5LmNsZWFyKCk7Ci0gICAgfQotCi19IC8vIGNsYXNzIFhTR3JhbW1hckJ1Y2tldApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9YU0dyb3VwRGVjbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9YU0dyb3VwRGVjbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhNzEwZTUzLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvWFNHcm91cERlY2wuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExMSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54czsKLQotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLnV0aWwuWFNPYmplY3RMaXN0SW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTQW5ub3RhdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNNb2RlbEdyb3VwOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNNb2RlbEdyb3VwRGVmaW5pdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTTmFtZXNwYWNlSXRlbTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTT2JqZWN0TGlzdDsKLQotLyoqCi0gKiBUaGUgWE1MIHJlcHJlc2VudGF0aW9uIGZvciBhIGdyb3VwIGRlY2xhcmF0aW9uCi0gKiBzY2hlbWEgY29tcG9uZW50IGlzIGEgZ2xvYmFsIDxncm91cD4gZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgU2FuZHkgR2FvLCBJQk0KLSAqIEB2ZXJzaW9uICRJZDogWFNHcm91cERlY2wuamF2YSx2IDEuNyAyMDEwLTExLTAxIDA0OjM5OjU1IGpvZWh3IEV4cCAkCi0gKi8KLXB1YmxpYyBjbGFzcyBYU0dyb3VwRGVjbCBpbXBsZW1lbnRzIFhTTW9kZWxHcm91cERlZmluaXRpb24gewotCi0gICAgLy8gbmFtZSBvZiB0aGUgZ3JvdXAKLSAgICBwdWJsaWMgU3RyaW5nIGZOYW1lID0gbnVsbDsKLSAgICAvLyB0YXJnZXQgbmFtZXNwYWNlIG9mIHRoZSBncm91cAotICAgIHB1YmxpYyBTdHJpbmcgZlRhcmdldE5hbWVzcGFjZSA9IG51bGw7Ci0gICAgLy8gbW9kZWwgZ3JvdXAgb2YgdGhlIGdyb3VwCi0gICAgcHVibGljIFhTTW9kZWxHcm91cEltcGwgZk1vZGVsR3JvdXAgPSBudWxsOwotICAgIC8vIG9wdGlvbmFsIGFubm90YXRpb25zCi0gICAgcHVibGljIFhTT2JqZWN0TGlzdCBmQW5ub3RhdGlvbnMgPSBudWxsOwotICAgIC8vIFRoZSBuYW1lc3BhY2Ugc2NoZW1hIGluZm9ybWF0aW9uIGl0ZW0gY29ycmVzcG9uZGluZyB0byB0aGUgdGFyZ2V0IG5hbWVzcGFjZQotICAgIC8vIG9mIHRoZSBtb2RlbCBncm91cCBkZWZpbml0aW9uLCBpZiBpdCBpcyBnbG9iYWxseSBkZWNsYXJlZDsgb3IgbnVsbCBvdGhlcndpc2UuCi0gICAgcHJpdmF0ZSBYU05hbWVzcGFjZUl0ZW0gZk5hbWVzcGFjZUl0ZW0gPSBudWxsOwotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSB0eXBlIG9mIHRoZSBvYmplY3QsIGkuZSBFTEVNRU5UX0RFQ0xBUkFUSU9OLgotICAgICAqLwotICAgIHB1YmxpYyBzaG9ydCBnZXRUeXBlKCkgewotICAgICAgICByZXR1cm4gWFNDb25zdGFudHMuTU9ERUxfR1JPVVBfREVGSU5JVElPTjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgPGNvZGU+bmFtZTwvY29kZT4gb2YgdGhpcyA8Y29kZT5YU09iamVjdDwvY29kZT4gZGVwZW5kaW5nIG9uIHRoZQotICAgICAqIDxjb2RlPlhTT2JqZWN0PC9jb2RlPiB0eXBlLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpIHsKLSAgICAgICAgcmV0dXJuIGZOYW1lOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoZSBuYW1lc3BhY2UgVVJJIG9mIHRoaXMgbm9kZSwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgaXQgaXMKLSAgICAgKiB1bnNwZWNpZmllZC4gIGRlZmluZXMgaG93IGEgbmFtZXNwYWNlIFVSSSBpcyBhdHRhY2hlZCB0byBzY2hlbWEKLSAgICAgKiBjb21wb25lbnRzLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZXNwYWNlKCkgewotICAgICAgICByZXR1cm4gZlRhcmdldE5hbWVzcGFjZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiB7bW9kZWwgZ3JvdXB9IEEgbW9kZWwgZ3JvdXAuCi0gICAgICovCi0gICAgcHVibGljIFhTTW9kZWxHcm91cCBnZXRNb2RlbEdyb3VwKCkgewotICAgICAgICByZXR1cm4gZk1vZGVsR3JvdXA7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogT3B0aW9uYWwuIEFubm90YXRpb24uCi0gICAgICovCi0gICAgcHVibGljIFhTQW5ub3RhdGlvbiBnZXRBbm5vdGF0aW9uKCkgewotICAgICAgICByZXR1cm4gKGZBbm5vdGF0aW9ucyAhPSBudWxsKSA/IChYU0Fubm90YXRpb24pIGZBbm5vdGF0aW9ucy5pdGVtKDApIDogbnVsbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBPcHRpb25hbC4gQW5ub3RhdGlvbnMuCi0gICAgICovCi0gICAgcHVibGljIFhTT2JqZWN0TGlzdCBnZXRBbm5vdGF0aW9ucygpIHsKLSAgICAgICAgcmV0dXJuIChmQW5ub3RhdGlvbnMgIT0gbnVsbCkgPyBmQW5ub3RhdGlvbnMgOiBYU09iamVjdExpc3RJbXBsLkVNUFRZX0xJU1Q7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBvcmcuYXBhY2hlLnhlcmNlcy54cy5YU09iamVjdCNnZXROYW1lc3BhY2VJdGVtKCkKLSAgICAgKi8KLSAgICBwdWJsaWMgWFNOYW1lc3BhY2VJdGVtIGdldE5hbWVzcGFjZUl0ZW0oKSB7Ci0gICAgICAgIHJldHVybiBmTmFtZXNwYWNlSXRlbTsKLSAgICB9Ci0KLSAgICB2b2lkIHNldE5hbWVzcGFjZUl0ZW0oWFNOYW1lc3BhY2VJdGVtIG5hbWVzcGFjZUl0ZW0pIHsKLSAgICAgICAgZk5hbWVzcGFjZUl0ZW0gPSBuYW1lc3BhY2VJdGVtOwotICAgIH0KLQotfSAvLyBjbGFzcyBYU0dyb3VwRGVjbApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9YU0ltcGxlbWVudGF0aW9uSW1wbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9YU0ltcGxlbWVudGF0aW9uSW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4Y2YwYzRhLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvWFNJbXBsZW1lbnRhdGlvbkltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExOSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAzLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54czsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tLkNvcmVET01JbXBsZW1lbnRhdGlvbkltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5kb20uRE9NTWVzc2FnZUZvcm1hdHRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMudXRpbC5TdHJpbmdMaXN0SW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlN0cmluZ0xpc3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU0V4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTSW1wbGVtZW50YXRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU0xvYWRlcjsKLWltcG9ydCBvcmcudzNjLmRvbS5ET01JbXBsZW1lbnRhdGlvbjsKLQotCi0vKioKLSAqIEltcGxlbWVudHMgWFNJbXBsZW1lbnRhdGlvbiBpbnRlcmZhY2UgdGhhdCBhbGxvd3Mgb25lIHRvIHJldHJpZXZlIGFuIGluc3RhbmNlIG9mIDxjb2RlPlhTTG9hZGVyPC9jb2RlPi4KLSAqIFRoaXMgaW50ZXJmYWNlIHNob3VsZCBiZSBpbXBsZW1lbnRlZCBvbiB0aGUgc2FtZSBvYmplY3QgdGhhdCBpbXBsZW1lbnRzCi0gKiBET01JbXBsZW1lbnRhdGlvbi4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBFbGVuYSBMaXRhbmksIElCTQotICovCi1wdWJsaWMgY2xhc3MgWFNJbXBsZW1lbnRhdGlvbkltcGwgZXh0ZW5kcyBDb3JlRE9NSW1wbGVtZW50YXRpb25JbXBsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbXBsZW1lbnRzIFhTSW1wbGVtZW50YXRpb24gewotCi0gICAgLy8KLSAgICAvLyBEYXRhCi0gICAgLy8KLQotICAgIC8vIHN0YXRpYwotCi0gICAgLyoqIERvbSBpbXBsZW1lbnRhdGlvbiBzaW5nbGV0b24uICovCi0gICAgc3RhdGljIFhTSW1wbGVtZW50YXRpb25JbXBsIHNpbmdsZXRvbiA9IG5ldyBYU0ltcGxlbWVudGF0aW9uSW1wbCgpOwotCi0gICAgLy8KLSAgICAvLyBQdWJsaWMgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKiogTk9OLURPTTogT2J0YWluIGFuZCByZXR1cm4gdGhlIHNpbmdsZSBzaGFyZWQgb2JqZWN0ICovCi0gICAgcHVibGljIHN0YXRpYyBET01JbXBsZW1lbnRhdGlvbiBnZXRET01JbXBsZW1lbnRhdGlvbigpIHsKLSAgICAgICAgcmV0dXJuIHNpbmdsZXRvbjsKLSAgICB9Ci0KLSAgICAvLwotICAgIC8vIERPTUltcGxlbWVudGF0aW9uIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogVGVzdCBpZiB0aGUgRE9NIGltcGxlbWVudGF0aW9uIHN1cHBvcnRzIGEgc3BlY2lmaWMgImZlYXR1cmUiIC0tCi0gICAgICogY3VycmVudGx5IG1lYW5pbmcgbGFuZ3VhZ2UgYW5kIGxldmVsIHRoZXJlb2YuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZmVhdHVyZSAgICAgIFRoZSBwYWNrYWdlIG5hbWUgb2YgdGhlIGZlYXR1cmUgdG8gdGVzdC4KLSAgICAgKiBJbiBMZXZlbCAxLCBzdXBwb3J0ZWQgdmFsdWVzIGFyZSAiSFRNTCIgYW5kICJYTUwiIChjYXNlLWluc2Vuc2l0aXZlKS4KLSAgICAgKiBBdCB0aGlzIHdyaXRpbmcsIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tIHN1cHBvcnRzIG9ubHkgWE1MLgotICAgICAqCi0gICAgICogQHBhcmFtIHZlcnNpb24gICAgICBUaGUgdmVyc2lvbiBudW1iZXIgb2YgdGhlIGZlYXR1cmUgYmVpbmcgdGVzdGVkLgotICAgICAqIFRoaXMgaXMgaW50ZXJwcmV0ZWQgYXMgIlZlcnNpb24gb2YgdGhlIERPTSBBUEkgc3VwcG9ydGVkIGZvciB0aGUKLSAgICAgKiBzcGVjaWZpZWQgRmVhdHVyZSIsIGFuZCBpbiBMZXZlbCAxIHNob3VsZCBiZSAiMS4wIgotICAgICAqCi0gICAgICogQHJldHVybiAgICB0cnVlIGlmZiB0aGlzIGltcGxlbWVudGF0aW9uIGlzIGNvbXBhdGFibGUgd2l0aCB0aGUgc3BlY2lmaWVkCi0gICAgICogZmVhdHVyZSBhbmQgdmVyc2lvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBoYXNGZWF0dXJlKFN0cmluZyBmZWF0dXJlLCBTdHJpbmcgdmVyc2lvbikgewotCi0gICAgICAgIHJldHVybiAoZmVhdHVyZS5lcXVhbHNJZ25vcmVDYXNlKCJYUy1Mb2FkZXIiKSAmJiAodmVyc2lvbiA9PSBudWxsIHx8IHZlcnNpb24uZXF1YWxzKCIxLjAiKSkgfHwKLSAgICAgICAgICAgICAgICBzdXBlci5oYXNGZWF0dXJlKGZlYXR1cmUsIHZlcnNpb24pKTsKLSAgICB9IC8vIGhhc0ZlYXR1cmUoU3RyaW5nLFN0cmluZyk6Ym9vbGVhbgotCi0KLQotICAgIC8qIChub24tSmF2YWRvYykKLSAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNJbXBsZW1lbnRhdGlvbiNjcmVhdGVYU0xvYWRlcihjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlN0cmluZ0xpc3QpCi0gICAgICovCi0gICAgcHVibGljIFhTTG9hZGVyIGNyZWF0ZVhTTG9hZGVyKFN0cmluZ0xpc3QgdmVyc2lvbnMpIHRocm93cyBYU0V4Y2VwdGlvbiB7Ci0gICAgICAgIFhTTG9hZGVyIGxvYWRlciA9IG5ldyBYU0xvYWRlckltcGwoKTsKLSAgICAgICAgaWYgKHZlcnNpb25zID09IG51bGwpewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGxvYWRlcjsKLSAgICAgICAgfQotICAgICAgICBmb3IgKGludCBpPTA7IGk8dmVyc2lvbnMuZ2V0TGVuZ3RoKCk7aSsrKXsKLSAgICAgICAgICAgICAgICBpZiAoIXZlcnNpb25zLml0ZW0oaSkuZXF1YWxzKCIxLjAiKSl7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBtc2cgPQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZSgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJGRUFUVVJFX05PVF9TVVBQT1JURUQiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgdmVyc2lvbnMuaXRlbShpKSB9KTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFhTRXhjZXB0aW9uKFhTRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSLCBtc2cpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbG9hZGVyOwotICAgIH0KLQotICAgIC8qIChub24tSmF2YWRvYykKLSAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNJbXBsZW1lbnRhdGlvbiNnZXRSZWNvZ25pemVkVmVyc2lvbnMoKQotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmdMaXN0IGdldFJlY29nbml6ZWRWZXJzaW9ucygpIHsKLSAgICAgICAgU3RyaW5nTGlzdEltcGwgbGlzdCA9IG5ldyBTdHJpbmdMaXN0SW1wbChuZXcgU3RyaW5nW117IjEuMCJ9LCAxKTsKLSAgICAgICAgcmV0dXJuIGxpc3Q7Ci0gICAgfQotCi19IC8vIGNsYXNzIFhTSW1wbGVtZW50YXRpb25JbXBsCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL1hTTG9hZGVySW1wbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9YU0xvYWRlckltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMTM2ZDY5ZS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL1hTTG9hZGVySW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzIyICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54czsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy51dGlsLlhTR3JhbW1hclBvb2w7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuZ3JhbW1hcnMuR3JhbW1hcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5ncmFtbWFycy5YTUxHcmFtbWFyRGVzY3JpcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuZ3JhbW1hcnMuWFNHcmFtbWFyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxJbnB1dFNvdXJjZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLkxTSW5wdXRMaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuU3RyaW5nTGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNMb2FkZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU01vZGVsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNOYW1lZE1hcDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTT2JqZWN0TGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTVHlwZURlZmluaXRpb247Ci1pbXBvcnQgb3JnLnczYy5kb20uRE9NQ29uZmlndXJhdGlvbjsKLWltcG9ydCBvcmcudzNjLmRvbS5ET01FeGNlcHRpb247Ci1pbXBvcnQgb3JnLnczYy5kb20uRE9NU3RyaW5nTGlzdDsKLWltcG9ydCBvcmcudzNjLmRvbS5scy5MU0lucHV0OwotCi0vKioKLSAqIDxwPkFuIGltcGxlbWVudGF0aW9uIG9mIFhTTG9hZGVyIHdoaWNoIHdyYXBzIFhNTFNjaGVtYUxvYWRlci48L3A+Ci0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgTWljaGFlbCBHbGF2YXNzZXZpY2gsIElCTQotICoKLSAqIEB2ZXJzaW9uICRJZDogWFNMb2FkZXJJbXBsLmphdmEsdiAxLjcgMjAxMC0xMS0wMSAwNDozOTo1NSBqb2VodyBFeHAgJAotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgWFNMb2FkZXJJbXBsIGltcGxlbWVudHMgWFNMb2FkZXIsIERPTUNvbmZpZ3VyYXRpb24gewotCi0gICAgLyoqCi0gICAgICogR3JhbW1hciBwb29sLiBOZWVkIHRoaXMgdG8gcHJldmVudCB1cyBmcm9tCi0gICAgICogZ2V0dGluZyB0d28gZ3JhbW1hcnMgZnJvbSB0aGUgc2FtZSBuYW1lc3BhY2UuCi0gICAgICovCi0gICAgcHJpdmF0ZSBmaW5hbCBYU0dyYW1tYXJQb29sIGZHcmFtbWFyUG9vbCA9IG5ldyBYU0dyYW1tYXJNZXJnZXIoKTsKLQotICAgIC8qKiBTY2hlbWEgbG9hZGVyLiAqKi8KLSAgICBwcml2YXRlIGZpbmFsIFhNTFNjaGVtYUxvYWRlciBmU2NoZW1hTG9hZGVyID0gbmV3IFhNTFNjaGVtYUxvYWRlcigpOwotCi0gICAgLyoqCi0gICAgICogTm8tYXJncyBjb25zdHJ1Y3Rvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFNMb2FkZXJJbXBsKCkgewotICAgICAgICBmU2NoZW1hTG9hZGVyLnNldFByb3BlcnR5KFhNTFNjaGVtYUxvYWRlci5YTUxHUkFNTUFSX1BPT0wsIGZHcmFtbWFyUG9vbCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogIFRoZSBjb25maWd1cmF0aW9uIG9mIGEgZG9jdW1lbnQuIEl0IG1haW50YWlucyBhIHRhYmxlIG9mIHJlY29nbml6ZWQKLSAgICAgKiBwYXJhbWV0ZXJzLiBVc2luZyB0aGUgY29uZmlndXJhdGlvbiwgaXQgaXMgcG9zc2libGUgdG8gY2hhbmdlIHRoZQotICAgICAqIGJlaGF2aW9yIG9mIHRoZSBsb2FkIG1ldGhvZHMuIFRoZSBjb25maWd1cmF0aW9uIG1heSBzdXBwb3J0IHRoZQotICAgICAqIHNldHRpbmcgb2YgYW5kIHRoZSByZXRyaWV2YWwgb2YgdGhlIGZvbGxvd2luZyBub24tYm9vbGVhbiBwYXJhbWV0ZXJzCi0gICAgICogZGVmaW5lZCBvbiB0aGUgPGNvZGU+RE9NQ29uZmlndXJhdGlvbjwvY29kZT4gaW50ZXJmYWNlOgotICAgICAqIDxjb2RlPmVycm9yLWhhbmRsZXI8L2NvZGU+ICg8Y29kZT5ET01FcnJvckhhbmRsZXI8L2NvZGU+KSBhbmQKLSAgICAgKiA8Y29kZT5yZXNvdXJjZS1yZXNvbHZlcjwvY29kZT4gKDxjb2RlPkxTUmVzb3VyY2VSZXNvbHZlcjwvY29kZT4pLgotICAgICAqIDxicj4gVGhlIGZvbGxvd2luZyBsaXN0IG9mIGJvb2xlYW4gcGFyYW1ldGVycyBpcyBkZWZpbmVkOgotICAgICAqIDxkbD4KLSAgICAgKiA8ZHQ+Ci0gICAgICogPGNvZGU+InZhbGlkYXRlIjwvY29kZT48L2R0PgotICAgICAqIDxkZD4KLSAgICAgKiA8ZGw+Ci0gICAgICogPGR0Pjxjb2RlPnRydWU8L2NvZGU+PC9kdD4KLSAgICAgKiA8ZGQ+W3JlcXVpcmVkXSAoZGVmYXVsdCkgVmFsaWRhdGUgYW4gWE1MCi0gICAgICogU2NoZW1hIGR1cmluZyBsb2FkaW5nLiBJZiB2YWxpZGF0aW9uIGVycm9ycyBhcmUgZm91bmQsIHRoZSBlcnJvcgotICAgICAqIGhhbmRsZXIgaXMgbm90aWZpZWQuIDwvZGQ+Ci0gICAgICogPGR0Pjxjb2RlPmZhbHNlPC9jb2RlPjwvZHQ+Ci0gICAgICogPGRkPltvcHRpb25hbF0gRG8gbm90Ci0gICAgICogcmVwb3J0IGVycm9ycyBkdXJpbmcgdGhlIGxvYWRpbmcgb2YgYW4gWE1MIFNjaGVtYSBkb2N1bWVudC4gPC9kZD4KLSAgICAgKiA8L2RsPjwvZGQ+Ci0gICAgICogPC9kbD4KLSAgICAgKi8KLSAgICBwdWJsaWMgRE9NQ29uZmlndXJhdGlvbiBnZXRDb25maWcoKSB7Ci0gICAgICAgIHJldHVybiB0aGlzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFBhcnNlcyB0aGUgY29udGVudCBvZiBYTUwgU2NoZW1hIGRvY3VtZW50cyBzcGVjaWZpZWQgYXMgdGhlIGxpc3Qgb2YgVVJJCi0gICAgICogcmVmZXJlbmNlcy4gSWYgdGhlIFVSSSBjb250YWlucyBhIGZyYWdtZW50IGlkZW50aWZpZXIsIHRoZSBiZWhhdmlvcgotICAgICAqIGlzIG5vdCBkZWZpbmVkIGJ5IHRoaXMgc3BlY2lmaWNhdGlvbi4KLSAgICAgKiBAcGFyYW0gdXJpTGlzdCBUaGUgbGlzdCBvZiBVUkkgbG9jYXRpb25zLgotICAgICAqIEByZXR1cm4gQW4gWFNNb2RlbCByZXByZXNlbnRpbmcgdGhlIHNjaGVtYSBkb2N1bWVudHMuCi0gICAgICovCi0gICAgcHVibGljIFhTTW9kZWwgbG9hZFVSSUxpc3QoU3RyaW5nTGlzdCB1cmlMaXN0KSB7Ci0gICAgICAgIGludCBsZW5ndGggPSB1cmlMaXN0LmdldExlbmd0aCgpOwotICAgICAgICB0cnkgewotICAgICAgICAgICAgZkdyYW1tYXJQb29sLmNsZWFyKCk7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7Ci0gICAgICAgICAgICAgICAgZlNjaGVtYUxvYWRlci5sb2FkR3JhbW1hcihuZXcgWE1MSW5wdXRTb3VyY2UobnVsbCwgdXJpTGlzdC5pdGVtKGkpLCBudWxsKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gZkdyYW1tYXJQb29sLnRvWFNNb2RlbCgpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgZlNjaGVtYUxvYWRlci5yZXBvcnRET01GYXRhbEVycm9yKGUpOwotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiAgUGFyc2VzIHRoZSBjb250ZW50IG9mIFhNTCBTY2hlbWEgZG9jdW1lbnRzIHNwZWNpZmllZCBhcyBhIGxpc3Qgb2YKLSAgICAgKiA8Y29kZT5MU0lucHV0PC9jb2RlPnMuCi0gICAgICogQHBhcmFtIGlzICBUaGUgbGlzdCBvZiA8Y29kZT5MU0lucHV0PC9jb2RlPnMgZnJvbSB3aGljaCB0aGUgWE1MCi0gICAgICogICBTY2hlbWEgZG9jdW1lbnRzIGFyZSB0byBiZSByZWFkLgotICAgICAqIEByZXR1cm4gQW4gWFNNb2RlbCByZXByZXNlbnRpbmcgdGhlIHNjaGVtYSBkb2N1bWVudHMuCi0gICAgICovCi0gICAgcHVibGljIFhTTW9kZWwgbG9hZElucHV0TGlzdChMU0lucHV0TGlzdCBpcykgewotICAgICAgICBmaW5hbCBpbnQgbGVuZ3RoID0gaXMuZ2V0TGVuZ3RoKCk7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBmR3JhbW1hclBvb2wuY2xlYXIoKTsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyArK2kpIHsKLSAgICAgICAgICAgICAgICBmU2NoZW1hTG9hZGVyLmxvYWRHcmFtbWFyKGZTY2hlbWFMb2FkZXIuZG9tMnhtbElucHV0U291cmNlKGlzLml0ZW0oaSkpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiBmR3JhbW1hclBvb2wudG9YU01vZGVsKCk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICBmU2NoZW1hTG9hZGVyLnJlcG9ydERPTUZhdGFsRXJyb3IoZSk7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFBhcnNlIGFuIFhNTCBTY2hlbWEgZG9jdW1lbnQgZnJvbSBhIGxvY2F0aW9uIGlkZW50aWZpZWQgYnkgYSBVUkkKLSAgICAgKiByZWZlcmVuY2UuIElmIHRoZSBVUkkgY29udGFpbnMgYSBmcmFnbWVudCBpZGVudGlmaWVyLCB0aGUgYmVoYXZpb3IgaXMKLSAgICAgKiBub3QgZGVmaW5lZCBieSB0aGlzIHNwZWNpZmljYXRpb24uCi0gICAgICogQHBhcmFtIHVyaSBUaGUgbG9jYXRpb24gb2YgdGhlIFhNTCBTY2hlbWEgZG9jdW1lbnQgdG8gYmUgcmVhZC4KLSAgICAgKiBAcmV0dXJuIEFuIFhTTW9kZWwgcmVwcmVzZW50aW5nIHRoaXMgc2NoZW1hLgotICAgICAqLwotICAgIHB1YmxpYyBYU01vZGVsIGxvYWRVUkkoU3RyaW5nIHVyaSkgewotICAgICAgICB0cnkgewotICAgICAgICAgICAgZkdyYW1tYXJQb29sLmNsZWFyKCk7Ci0gICAgICAgICAgICByZXR1cm4gKChYU0dyYW1tYXIpIGZTY2hlbWFMb2FkZXIubG9hZEdyYW1tYXIobmV3IFhNTElucHV0U291cmNlKG51bGwsIHVyaSwgbnVsbCkpKS50b1hTTW9kZWwoKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGUpewotICAgICAgICAgICAgZlNjaGVtYUxvYWRlci5yZXBvcnRET01GYXRhbEVycm9yKGUpOwotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiAgUGFyc2UgYW4gWE1MIFNjaGVtYSBkb2N1bWVudCBmcm9tIGEgcmVzb3VyY2UgaWRlbnRpZmllZCBieSBhCi0gICAgICogPGNvZGU+TFNJbnB1dDwvY29kZT4gLgotICAgICAqIEBwYXJhbSBpcyAgVGhlIDxjb2RlPkxTSW5wdXQ8L2NvZGU+IGZyb20gd2hpY2ggdGhlIHNvdXJjZQotICAgICAqICAgZG9jdW1lbnQgaXMgdG8gYmUgcmVhZC4KLSAgICAgKiBAcmV0dXJuIEFuIFhTTW9kZWwgcmVwcmVzZW50aW5nIHRoaXMgc2NoZW1hLgotICAgICAqLwotICAgIHB1YmxpYyBYU01vZGVsIGxvYWQoTFNJbnB1dCBpcykgewotICAgICAgICB0cnkgewotICAgICAgICAgICAgZkdyYW1tYXJQb29sLmNsZWFyKCk7Ci0gICAgICAgICAgICByZXR1cm4gKChYU0dyYW1tYXIpIGZTY2hlbWFMb2FkZXIubG9hZEdyYW1tYXIoZlNjaGVtYUxvYWRlci5kb20yeG1sSW5wdXRTb3VyY2UoaXMpKSkudG9YU01vZGVsKCk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICBmU2NoZW1hTG9hZGVyLnJlcG9ydERPTUZhdGFsRXJyb3IoZSk7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qIChub24tSmF2YWRvYykKLSAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tMy5ET01Db25maWd1cmF0aW9uI3NldFBhcmFtZXRlcihqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuT2JqZWN0KQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFBhcmFtZXRlcihTdHJpbmcgbmFtZSwgT2JqZWN0IHZhbHVlKSB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKLSAgICAgICAgZlNjaGVtYUxvYWRlci5zZXRQYXJhbWV0ZXIobmFtZSwgdmFsdWUpOwotICAgIH0KLQotICAgIC8qIChub24tSmF2YWRvYykKLSAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tMy5ET01Db25maWd1cmF0aW9uI2dldFBhcmFtZXRlcihqYXZhLmxhbmcuU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyBPYmplY3QgZ2V0UGFyYW1ldGVyKFN0cmluZyBuYW1lKSB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKLSAgICAgICAgcmV0dXJuIGZTY2hlbWFMb2FkZXIuZ2V0UGFyYW1ldGVyKG5hbWUpOwotICAgIH0KLQotICAgIC8qIChub24tSmF2YWRvYykKLSAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tMy5ET01Db25maWd1cmF0aW9uI2NhblNldFBhcmFtZXRlcihqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuT2JqZWN0KQotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGNhblNldFBhcmFtZXRlcihTdHJpbmcgbmFtZSwgT2JqZWN0IHZhbHVlKSB7Ci0gICAgICAgIHJldHVybiBmU2NoZW1hTG9hZGVyLmNhblNldFBhcmFtZXRlcihuYW1lLCB2YWx1ZSk7Ci0gICAgfQotCi0gICAgLyogKG5vbi1KYXZhZG9jKQotICAgICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5kb20zLkRPTUNvbmZpZ3VyYXRpb24jZ2V0UGFyYW1ldGVyTmFtZXMoKQotICAgICAqLwotICAgIHB1YmxpYyBET01TdHJpbmdMaXN0IGdldFBhcmFtZXRlck5hbWVzKCkgewotICAgICAgICByZXR1cm4gZlNjaGVtYUxvYWRlci5nZXRQYXJhbWV0ZXJOYW1lcygpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdyYW1tYXIgcG9vbCB3aGljaCBtZXJnZXMgZ3JhbW1hcnMgZnJvbSB0aGUgc2FtZSBuYW1lc3BhY2UgaW50byBvbmUuIFRoaXMgZWxpbWluYXRlcwotICAgICAqIGR1cGxpY2F0ZSBuYW1lZCBjb21wb25lbnRzLiBJdCBkb2Vzbid0IGVuc3VyZSB0aGF0IHRoZSBncmFtbWFyIGlzIGNvbnNpc3RlbnQsIGhvd2V2ZXIKLSAgICAgKiB0aGlzIG5vIHdvcnNlIHRoYW4gdGhhbiB0aGUgYmVoYXZpb3VyIG9mIFhNTFNjaGVtYUxvYWRlciBhbG9uZSB3aGVuIHVzZWQgYXMgYW4gWFNMb2FkZXIuCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgWFNHcmFtbWFyTWVyZ2VyIGV4dGVuZHMgWFNHcmFtbWFyUG9vbCB7Ci0KLSAgICAgICAgcHVibGljIFhTR3JhbW1hck1lcmdlciAoKSB7fQotCi0gICAgICAgIHB1YmxpYyB2b2lkIHB1dEdyYW1tYXIoR3JhbW1hciBncmFtbWFyKSB7Ci0gICAgICAgICAgICBTY2hlbWFHcmFtbWFyIGNhY2hlZEdyYW1tYXIgPQotICAgICAgICAgICAgICAgIHRvU2NoZW1hR3JhbW1hcihzdXBlci5nZXRHcmFtbWFyKGdyYW1tYXIuZ2V0R3JhbW1hckRlc2NyaXB0aW9uKCkpKTsKLSAgICAgICAgICAgIGlmIChjYWNoZWRHcmFtbWFyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBTY2hlbWFHcmFtbWFyIG5ld0dyYW1tYXIgPSB0b1NjaGVtYUdyYW1tYXIoZ3JhbW1hcik7Ci0gICAgICAgICAgICAgICAgaWYgKG5ld0dyYW1tYXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBtZXJnZVNjaGVtYUdyYW1tYXJzKGNhY2hlZEdyYW1tYXIsIG5ld0dyYW1tYXIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIHN1cGVyLnB1dEdyYW1tYXIoZ3JhbW1hcik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBwcml2YXRlIFNjaGVtYUdyYW1tYXIgdG9TY2hlbWFHcmFtbWFyIChHcmFtbWFyIGdyYW1tYXIpIHsKLSAgICAgICAgICAgIHJldHVybiAoZ3JhbW1hciBpbnN0YW5jZW9mIFNjaGVtYUdyYW1tYXIpID8gKFNjaGVtYUdyYW1tYXIpIGdyYW1tYXIgOiBudWxsOwotICAgICAgICB9Ci0KLSAgICAgICAgcHJpdmF0ZSB2b2lkIG1lcmdlU2NoZW1hR3JhbW1hcnMoU2NoZW1hR3JhbW1hciBjYWNoZWRHcmFtbWFyLCBTY2hlbWFHcmFtbWFyIG5ld0dyYW1tYXIpIHsKLQotICAgICAgICAgICAgLyoqIEFkZCBuZXcgdG9wLWxldmVsIGVsZW1lbnQgZGVjbGFyYXRpb25zLiAqKi8KLSAgICAgICAgICAgIFhTTmFtZWRNYXAgbWFwID0gbmV3R3JhbW1hci5nZXRDb21wb25lbnRzKFhTQ29uc3RhbnRzLkVMRU1FTlRfREVDTEFSQVRJT04pOwotICAgICAgICAgICAgaW50IGxlbmd0aCA9IG1hcC5nZXRMZW5ndGgoKTsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyArK2kpIHsKLSAgICAgICAgICAgICAgICBYU0VsZW1lbnREZWNsIGRlY2wgPSAoWFNFbGVtZW50RGVjbCkgbWFwLml0ZW0oaSk7Ci0gICAgICAgICAgICAgICAgaWYgKGNhY2hlZEdyYW1tYXIuZ2V0R2xvYmFsRWxlbWVudERlY2woZGVjbC5nZXROYW1lKCkpID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgY2FjaGVkR3JhbW1hci5hZGRHbG9iYWxFbGVtZW50RGVjbChkZWNsKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8qKiBBZGQgbmV3IHRvcC1sZXZlbCBhdHRyaWJ1dGUgZGVjbGFyYXRpb25zLiAqKi8KLSAgICAgICAgICAgIG1hcCA9IG5ld0dyYW1tYXIuZ2V0Q29tcG9uZW50cyhYU0NvbnN0YW50cy5BVFRSSUJVVEVfREVDTEFSQVRJT04pOwotICAgICAgICAgICAgbGVuZ3RoID0gbWFwLmdldExlbmd0aCgpOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkgewotICAgICAgICAgICAgICAgIFhTQXR0cmlidXRlRGVjbCBkZWNsID0gKFhTQXR0cmlidXRlRGVjbCkgbWFwLml0ZW0oaSk7Ci0gICAgICAgICAgICAgICAgaWYgKGNhY2hlZEdyYW1tYXIuZ2V0R2xvYmFsQXR0cmlidXRlRGVjbChkZWNsLmdldE5hbWUoKSkgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBjYWNoZWRHcmFtbWFyLmFkZEdsb2JhbEF0dHJpYnV0ZURlY2woZGVjbCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvKiogQWRkIG5ldyB0b3AtbGV2ZWwgdHlwZSBkZWZpbml0aW9ucy4gKiovCi0gICAgICAgICAgICBtYXAgPSBuZXdHcmFtbWFyLmdldENvbXBvbmVudHMoWFNDb25zdGFudHMuVFlQRV9ERUZJTklUSU9OKTsKLSAgICAgICAgICAgIGxlbmd0aCA9IG1hcC5nZXRMZW5ndGgoKTsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyArK2kpIHsKLSAgICAgICAgICAgICAgICBYU1R5cGVEZWZpbml0aW9uIGRlY2wgPSAoWFNUeXBlRGVmaW5pdGlvbikgbWFwLml0ZW0oaSk7Ci0gICAgICAgICAgICAgICAgaWYgKGNhY2hlZEdyYW1tYXIuZ2V0R2xvYmFsVHlwZURlY2woZGVjbC5nZXROYW1lKCkpID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgY2FjaGVkR3JhbW1hci5hZGRHbG9iYWxUeXBlRGVjbChkZWNsKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8qKiBBZGQgbmV3IHRvcC1sZXZlbCBhdHRyaWJ1dGUgZ3JvdXAgZGVmaW5pdGlvbnMuICoqLwotICAgICAgICAgICAgbWFwID0gbmV3R3JhbW1hci5nZXRDb21wb25lbnRzKFhTQ29uc3RhbnRzLkFUVFJJQlVURV9HUk9VUCk7Ci0gICAgICAgICAgICBsZW5ndGggPSBtYXAuZ2V0TGVuZ3RoKCk7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7Ci0gICAgICAgICAgICAgICAgWFNBdHRyaWJ1dGVHcm91cERlY2wgZGVjbCA9IChYU0F0dHJpYnV0ZUdyb3VwRGVjbCkgbWFwLml0ZW0oaSk7Ci0gICAgICAgICAgICAgICAgaWYgKGNhY2hlZEdyYW1tYXIuZ2V0R2xvYmFsQXR0cmlidXRlR3JvdXBEZWNsKGRlY2wuZ2V0TmFtZSgpKSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGNhY2hlZEdyYW1tYXIuYWRkR2xvYmFsQXR0cmlidXRlR3JvdXBEZWNsKGRlY2wpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLyoqIEFkZCBuZXcgdG9wLWxldmVsIG1vZGVsIGdyb3VwIGRlZmluaXRpb25zLiAqKi8KLSAgICAgICAgICAgIG1hcCA9IG5ld0dyYW1tYXIuZ2V0Q29tcG9uZW50cyhYU0NvbnN0YW50cy5NT0RFTF9HUk9VUCk7Ci0gICAgICAgICAgICBsZW5ndGggPSBtYXAuZ2V0TGVuZ3RoKCk7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7Ci0gICAgICAgICAgICAgICAgWFNHcm91cERlY2wgZGVjbCA9IChYU0dyb3VwRGVjbCkgbWFwLml0ZW0oaSk7Ci0gICAgICAgICAgICAgICAgaWYgKGNhY2hlZEdyYW1tYXIuZ2V0R2xvYmFsR3JvdXBEZWNsKGRlY2wuZ2V0TmFtZSgpKSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGNhY2hlZEdyYW1tYXIuYWRkR2xvYmFsR3JvdXBEZWNsKGRlY2wpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLyoqIEFkZCBuZXcgdG9wLWxldmVsIG5vdGF0aW9uIGRlY2xhcmF0aW9ucy4gKiovCi0gICAgICAgICAgICBtYXAgPSBuZXdHcmFtbWFyLmdldENvbXBvbmVudHMoWFNDb25zdGFudHMuTk9UQVRJT05fREVDTEFSQVRJT04pOwotICAgICAgICAgICAgbGVuZ3RoID0gbWFwLmdldExlbmd0aCgpOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkgewotICAgICAgICAgICAgICAgIFhTTm90YXRpb25EZWNsIGRlY2wgPSAoWFNOb3RhdGlvbkRlY2wpIG1hcC5pdGVtKGkpOwotICAgICAgICAgICAgICAgIGlmIChjYWNoZWRHcmFtbWFyLmdldEdsb2JhbE5vdGF0aW9uRGVjbChkZWNsLmdldE5hbWUoKSkgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBjYWNoZWRHcmFtbWFyLmFkZEdsb2JhbE5vdGF0aW9uRGVjbChkZWNsKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8qKgotICAgICAgICAgICAgICogQWRkIGFsbCBhbm5vdGF0aW9ucy4gU2luY2UgdGhlc2UgY29tcG9uZW50cyBhcmUgbm90IG5hbWVkIGl0J3MKLSAgICAgICAgICAgICAqIHBvc3NpYmxlIHdlJ2xsIGFkZCBkdXBsaWNhdGUgY29tcG9uZW50cy4gVGhlcmUgaXNuJ3QgbXVjaCB3ZSBjYW4KLSAgICAgICAgICAgICAqIGRvLiBJdCdzIG5vIHdvcnNlIHRoYW4gWE1MU2NoZW1hTG9hZGVyIHdoZW4gdXNlZCBhcyBhbiBYU0xvYWRlci4KLSAgICAgICAgICAgICAqLwotICAgICAgICAgICAgWFNPYmplY3RMaXN0IGFubm90YXRpb25zID0gbmV3R3JhbW1hci5nZXRBbm5vdGF0aW9ucygpOwotICAgICAgICAgICAgbGVuZ3RoID0gYW5ub3RhdGlvbnMuZ2V0TGVuZ3RoKCk7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7Ci0gICAgICAgICAgICAgICAgY2FjaGVkR3JhbW1hci5hZGRBbm5vdGF0aW9uKChYU0Fubm90YXRpb25JbXBsKSBhbm5vdGF0aW9ucy5pdGVtKGkpKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNHcmFtbWFyKFhNTEdyYW1tYXJEZXNjcmlwdGlvbiBkZXNjKSB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgR3JhbW1hciBnZXRHcmFtbWFyKFhNTEdyYW1tYXJEZXNjcmlwdGlvbiBkZXNjKSB7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyBHcmFtbWFyIHJldHJpZXZlR3JhbW1hcihYTUxHcmFtbWFyRGVzY3JpcHRpb24gZGVzYykgewotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgR3JhbW1hciBbXSByZXRyaWV2ZUluaXRpYWxHcmFtbWFyU2V0IChTdHJpbmcgZ3JhbW1hclR5cGUpIHsKLSAgICAgICAgICAgIHJldHVybiBuZXcgR3JhbW1hclswXTsKLSAgICAgICAgfQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvWFNNZXNzYWdlRm9ybWF0dGVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL1hTTWVzc2FnZUZvcm1hdHRlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwYTUxYTNjLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvWFNNZXNzYWdlRm9ybWF0dGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5NSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLCAyMDAyLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54czsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5NZXNzYWdlRm9ybWF0dGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbHMuU2VjdXJpdHlTdXBwb3J0OwotaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7Ci1pbXBvcnQgamF2YS51dGlsLk1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuUmVzb3VyY2VCdW5kbGU7Ci0KLQotLyoqCi0gKiBTY2hlbWFNZXNzYWdlUHJvdmlkZXIgaW1wbGVtZW50cyBhbiBYTUxNZXNzYWdlUHJvdmlkZXIgdGhhdAotICogcHJvdmlkZXMgbG9jYWxpemFibGUgZXJyb3IgbWVzc2FnZXMgZm9yIHRoZSBXM0MgWE1MIFNjaGVtYSBMYW5ndWFnZQotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIEVsZW5hIExpdGFuaSwgSUJNCi0gKiBAdmVyc2lvbiAkSWQ6IFhTTWVzc2FnZUZvcm1hdHRlci5qYXZhLHYgMS42IDIwMTAtMTEtMDEgMDQ6Mzk6NTUgam9laHcgRXhwICQKLSAqLwotcHVibGljIGNsYXNzIFhTTWVzc2FnZUZvcm1hdHRlciBpbXBsZW1lbnRzIE1lc3NhZ2VGb3JtYXR0ZXIgewotICAgIC8qKgotICAgICAqIFRoZSBkb21haW4gb2YgbWVzc2FnZXMgY29uY2VybmluZyB0aGUgWE1MIFNjaGVtYTogU3RydWN0dXJlcyBzcGVjaWZpY2F0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFNDSEVNQV9ET01BSU4gPSAiaHR0cDovL3d3dy53My5vcmcvVFIveG1sLXNjaGVtYS0xIjsKLQotCi0gICAgLy8gcHJpdmF0ZSBvYmplY3RzIHRvIGNhY2hlIHRoZSBsb2NhbGUgYW5kIHJlc291cmNlIGJ1bmRsZQotICAgIHByaXZhdGUgTG9jYWxlIGZMb2NhbGUgPSBudWxsOwotICAgIHByaXZhdGUgUmVzb3VyY2VCdW5kbGUgZlJlc291cmNlQnVuZGxlID0gbnVsbDsKLQotICAgIC8qKgotICAgICAqIEZvcm1hdHMgYSBtZXNzYWdlIHdpdGggdGhlIHNwZWNpZmllZCBhcmd1bWVudHMgdXNpbmcgdGhlIGdpdmVuCi0gICAgICogbG9jYWxlIGluZm9ybWF0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIGxvY2FsZSAgICBUaGUgbG9jYWxlIG9mIHRoZSBtZXNzYWdlLgotICAgICAqIEBwYXJhbSBrZXkgICAgICAgVGhlIG1lc3NhZ2Uga2V5LgotICAgICAqIEBwYXJhbSBhcmd1bWVudHMgVGhlIG1lc3NhZ2UgcmVwbGFjZW1lbnQgdGV4dCBhcmd1bWVudHMuIFRoZSBvcmRlcgotICAgICAqICAgICAgICAgICAgICAgICAgb2YgdGhlIGFyZ3VtZW50cyBtdXN0IG1hdGNoIHRoYXQgb2YgdGhlIHBsYWNlaG9sZGVycwotICAgICAqICAgICAgICAgICAgICAgICAgaW4gdGhlIGFjdHVhbCBtZXNzYWdlLgotICAgICAqCi0gICAgICogQHJldHVybiBSZXR1cm5zIHRoZSBmb3JtYXR0ZWQgbWVzc2FnZS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uIFRocm93biBpZiB0aGUgbWVzc2FnZSB3aXRoIHRoZQotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwZWNpZmllZCBrZXkgY2Fubm90IGJlIGZvdW5kLgotICAgICAqLwotICAgICBwdWJsaWMgU3RyaW5nIGZvcm1hdE1lc3NhZ2UoTG9jYWxlIGxvY2FsZSwgU3RyaW5nIGtleSwgT2JqZWN0W10gYXJndW1lbnRzKQotICAgICAgICB0aHJvd3MgTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uIHsKLQotICAgICAgICBpZiAoZlJlc291cmNlQnVuZGxlID09IG51bGwgfHwgbG9jYWxlICE9IGZMb2NhbGUpIHsKLSAgICAgICAgICAgIGlmIChsb2NhbGUgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZSZXNvdXJjZUJ1bmRsZSA9IFNlY3VyaXR5U3VwcG9ydC5nZXRSZXNvdXJjZUJ1bmRsZSgiY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLm1zZy5YTUxTY2hlbWFNZXNzYWdlcyIsIGxvY2FsZSk7Ci0gICAgICAgICAgICAgICAgLy8gbWVtb3JpemUgdGhlIG1vc3QtcmVjZW50IGxvY2FsZQotICAgICAgICAgICAgICAgIGZMb2NhbGUgPSBsb2NhbGU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoZlJlc291cmNlQnVuZGxlID09IG51bGwpCi0gICAgICAgICAgICAgICAgZlJlc291cmNlQnVuZGxlID0gU2VjdXJpdHlTdXBwb3J0LmdldFJlc291cmNlQnVuZGxlKCJjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwubXNnLlhNTFNjaGVtYU1lc3NhZ2VzIik7Ci0gICAgICAgIH0KLQotICAgICAgICBTdHJpbmcgbXNnID0gZlJlc291cmNlQnVuZGxlLmdldFN0cmluZyhrZXkpOwotICAgICAgICBpZiAoYXJndW1lbnRzICE9IG51bGwpIHsKLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgbXNnID0gamF2YS50ZXh0Lk1lc3NhZ2VGb3JtYXQuZm9ybWF0KG1zZywgYXJndW1lbnRzKTsKLSAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgbXNnID0gZlJlc291cmNlQnVuZGxlLmdldFN0cmluZygiRm9ybWF0RmFpbGVkIik7Ci0gICAgICAgICAgICAgICAgbXNnICs9ICIgIiArIGZSZXNvdXJjZUJ1bmRsZS5nZXRTdHJpbmcoa2V5KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGlmIChtc2cgPT0gbnVsbCkgewotICAgICAgICAgICAgbXNnID0gZlJlc291cmNlQnVuZGxlLmdldFN0cmluZygiQmFkTWVzc2FnZUtleSIpOwotICAgICAgICAgICAgdGhyb3cgbmV3IE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbihtc2csICJjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwubXNnLlNjaGVtYU1lc3NhZ2VzIiwga2V5KTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBtc2c7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9YU01vZGVsR3JvdXBJbXBsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL1hTTW9kZWxHcm91cEltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNDQxNDAwMy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL1hTTW9kZWxHcm91cEltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI0NiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAyLDIwMDMtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLnV0aWwuWFNPYmplY3RMaXN0SW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTQW5ub3RhdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNNb2RlbEdyb3VwOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNOYW1lc3BhY2VJdGVtOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNPYmplY3RMaXN0OwotCi0vKioKLSAqIFN0b3JlIHNjaGVtYSBtb2RlbCBncm91cCBkZWNsYXJhdGlvbi4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBTYW5keSBHYW8sIElCTQotICoKLSAqIEB2ZXJzaW9uICRJZDogWFNNb2RlbEdyb3VwSW1wbC5qYXZhLHYgMS43IDIwMTAtMTEtMDEgMDQ6Mzk6NTUgam9laHcgRXhwICQKLSAqLwotcHVibGljIGNsYXNzIFhTTW9kZWxHcm91cEltcGwgaW1wbGVtZW50cyBYU01vZGVsR3JvdXAgewotCi0gICAgLy8gdHlwZXMgb2YgbW9kZWwgZ3JvdXBzCi0gICAgLy8gUkVWSVNJVDogY2FuJ3QgdXNlIHNhbWUgY29uc3RhbnRzIGFzIHRob3NlIGZvciBwYXJ0aWNsZXMsIGJlY2F1c2UKLSAgICAvLyB0aGVyZSBhcmUgcGxhY2Ugd2hlcmUgdGhlIGNvbnN0YW50cyBhcmUgdXNlZCB0b2dldGhlci4gRm9yIGV4YW1wbGUsCi0gICAgLy8gdG8gY2hlY2sgd2hldGhlciB0aGUgY29udGVudCBpcyBhbiBlbGVtZW50IG9yIGEgc2VxdWVuY2UuCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBNT0RFTEdST1VQX0NIT0lDRSAgICAgICA9IDEwMTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IE1PREVMR1JPVVBfU0VRVUVOQ0UgICAgID0gMTAyOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgTU9ERUxHUk9VUF9BTEwgICAgICAgICAgPSAxMDM7Ci0KLSAgICAvLyBjb21wb3NpdG9yIG9mIHRoZSBtb2RlbCBncm91cAotICAgIHB1YmxpYyBzaG9ydCBmQ29tcG9zaXRvcjsKLQotICAgIC8vIHBhcnRpY2xlcwotICAgIHB1YmxpYyBYU1BhcnRpY2xlRGVjbFtdIGZQYXJ0aWNsZXMgPSBudWxsOwotICAgIHB1YmxpYyBpbnQgZlBhcnRpY2xlQ291bnQgPSAwOwotCi0gICAgLy8gdGhpcyBwYXJ0aWNsZSdzIG9wdGlvbmFsIGFubm90YXRpb25zCi0gICAgcHVibGljIFhTT2JqZWN0TGlzdCBmQW5ub3RhdGlvbnMgPSBudWxsOwotCi0gICAgLy8gd2hldGhlciB0aGlzIG1vZGVsIGdyb3VwIGNvbnRhaW5zIG5vdGhpbmcKLSAgICBwdWJsaWMgYm9vbGVhbiBpc0VtcHR5KCkgewotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZQYXJ0aWNsZUNvdW50OyBpKyspIHsKLSAgICAgICAgICAgIGlmICghZlBhcnRpY2xlc1tpXS5pc0VtcHR5KCkpCi0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIDMuOC42IEVmZmVjdGl2ZSBUb3RhbCBSYW5nZSAoYWxsIGFuZCBzZXF1ZW5jZSkgYW5kCi0gICAgICogICAgICAgRWZmZWN0aXZlIFRvdGFsIFJhbmdlIChjaG9pY2UpCi0gICAgICogVGhlIGZvbGxvd2luZyBtZXRob2RzIGFyZSB1c2VkIHRvIHJldHVybiBtaW4vbWF4IHJhbmdlIGZvciBhIHBhcnRpY2xlLgotICAgICAqIFRoZXkgYXJlIG5vdCBleGFjdGx5IHRoZSBzYW1lIGFzIGl0J3MgZGVzY3JpYmVkIGluIHRoZSBzcGVjLCBidXQgYWxsIHRoZQotICAgICAqIHZhbHVlcyBmcm9tIHRoZSBzcGVjIGFyZSByZXRyaWV2YWJsZSBieSB0aGVzZSBtZXRob2RzLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgbWluRWZmZWN0aXZlVG90YWxSYW5nZSgpIHsKLSAgICAgICAgaWYgKGZDb21wb3NpdG9yID09IE1PREVMR1JPVVBfQ0hPSUNFKQotICAgICAgICAgICAgcmV0dXJuIG1pbkVmZmVjdGl2ZVRvdGFsUmFuZ2VDaG9pY2UoKTsKLSAgICAgICAgZWxzZQotICAgICAgICAgICAgcmV0dXJuIG1pbkVmZmVjdGl2ZVRvdGFsUmFuZ2VBbGxTZXEoKTsKLSAgICB9Ci0KLSAgICAvLyByZXR1cm4gdGhlIHN1bSBvZiBhbGwgbWluIHZhbHVlcyBvZiB0aGUgcGFydGljbGVzCi0gICAgcHJpdmF0ZSBpbnQgbWluRWZmZWN0aXZlVG90YWxSYW5nZUFsbFNlcSgpIHsKLSAgICAgICAgaW50IHRvdGFsID0gMDsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmUGFydGljbGVDb3VudDsgaSsrKQotICAgICAgICAgICAgdG90YWwgKz0gZlBhcnRpY2xlc1tpXS5taW5FZmZlY3RpdmVUb3RhbFJhbmdlKCk7Ci0gICAgICAgIHJldHVybiB0b3RhbDsKLSAgICB9Ci0KLSAgICAvLyByZXR1cm4gdGhlIG1pbiBvZiBhbGwgbWluIHZhbHVlcyBvZiB0aGUgcGFydGljbGVzCi0gICAgcHJpdmF0ZSBpbnQgbWluRWZmZWN0aXZlVG90YWxSYW5nZUNob2ljZSgpIHsKLSAgICAgICAgaW50IG1pbiA9IDAsIG9uZTsKLSAgICAgICAgaWYgKGZQYXJ0aWNsZUNvdW50ID4gMCkKLSAgICAgICAgICAgIG1pbiA9IGZQYXJ0aWNsZXNbMF0ubWluRWZmZWN0aXZlVG90YWxSYW5nZSgpOwotCi0gICAgICAgIGZvciAoaW50IGkgPSAxOyBpIDwgZlBhcnRpY2xlQ291bnQ7IGkrKykgewotICAgICAgICAgICAgb25lID0gZlBhcnRpY2xlc1tpXS5taW5FZmZlY3RpdmVUb3RhbFJhbmdlKCk7Ci0gICAgICAgICAgICBpZiAob25lIDwgbWluKQotICAgICAgICAgICAgICAgIG1pbiA9IG9uZTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBtaW47Ci0gICAgfQotCi0gICAgcHVibGljIGludCBtYXhFZmZlY3RpdmVUb3RhbFJhbmdlKCkgewotICAgICAgICBpZiAoZkNvbXBvc2l0b3IgPT0gTU9ERUxHUk9VUF9DSE9JQ0UpCi0gICAgICAgICAgICByZXR1cm4gbWF4RWZmZWN0aXZlVG90YWxSYW5nZUNob2ljZSgpOwotICAgICAgICBlbHNlCi0gICAgICAgICAgICByZXR1cm4gbWF4RWZmZWN0aXZlVG90YWxSYW5nZUFsbFNlcSgpOwotICAgIH0KLQotICAgIC8vIGlmIG9uZSBvZiB0aGUgbWF4IHZhbHVlIG9mIHRoZSBwYXJ0aWNsZXMgaXMgdW5ib3VuZGVkLCByZXR1cm4gdW5ib3VuZGVkOwotICAgIC8vIG90aGVyd2lzZSByZXR1cm4gdGhlIHN1bSBvZiBhbGwgbWF4IHZhbHVlcwotICAgIHByaXZhdGUgaW50IG1heEVmZmVjdGl2ZVRvdGFsUmFuZ2VBbGxTZXEoKSB7Ci0gICAgICAgIGludCB0b3RhbCA9IDAsIG9uZTsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmUGFydGljbGVDb3VudDsgaSsrKSB7Ci0gICAgICAgICAgICBvbmUgPSBmUGFydGljbGVzW2ldLm1heEVmZmVjdGl2ZVRvdGFsUmFuZ2UoKTsKLSAgICAgICAgICAgIGlmIChvbmUgPT0gU2NoZW1hU3ltYm9scy5PQ0NVUlJFTkNFX1VOQk9VTkRFRCkKLSAgICAgICAgICAgICAgICByZXR1cm4gU2NoZW1hU3ltYm9scy5PQ0NVUlJFTkNFX1VOQk9VTkRFRDsKLSAgICAgICAgICAgIHRvdGFsICs9IG9uZTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gdG90YWw7Ci0gICAgfQotCi0gICAgLy8gaWYgb25lIG9mIHRoZSBtYXggdmFsdWUgb2YgdGhlIHBhcnRpY2xlcyBpcyB1bmJvdW5kZWQsIHJldHVybiB1bmJvdW5kZWQ7Ci0gICAgLy8gb3RoZXJ3aXNlIHJldHVybiB0aGUgbWF4IG9mIGFsbCBtYXggdmFsdWVzCi0gICAgcHJpdmF0ZSBpbnQgbWF4RWZmZWN0aXZlVG90YWxSYW5nZUNob2ljZSgpIHsKLSAgICAgICAgaW50IG1heCA9IDAsIG9uZTsKLSAgICAgICAgaWYgKGZQYXJ0aWNsZUNvdW50ID4gMCkgewotICAgICAgICAgICAgbWF4ID0gZlBhcnRpY2xlc1swXS5tYXhFZmZlY3RpdmVUb3RhbFJhbmdlKCk7Ci0gICAgICAgICAgICBpZiAobWF4ID09IFNjaGVtYVN5bWJvbHMuT0NDVVJSRU5DRV9VTkJPVU5ERUQpCi0gICAgICAgICAgICAgICAgcmV0dXJuIFNjaGVtYVN5bWJvbHMuT0NDVVJSRU5DRV9VTkJPVU5ERUQ7Ci0gICAgICAgIH0KLQotICAgICAgICBmb3IgKGludCBpID0gMTsgaSA8IGZQYXJ0aWNsZUNvdW50OyBpKyspIHsKLSAgICAgICAgICAgIG9uZSA9IGZQYXJ0aWNsZXNbaV0ubWF4RWZmZWN0aXZlVG90YWxSYW5nZSgpOwotICAgICAgICAgICAgaWYgKG9uZSA9PSBTY2hlbWFTeW1ib2xzLk9DQ1VSUkVOQ0VfVU5CT1VOREVEKQotICAgICAgICAgICAgICAgIHJldHVybiBTY2hlbWFTeW1ib2xzLk9DQ1VSUkVOQ0VfVU5CT1VOREVEOwotICAgICAgICAgICAgaWYgKG9uZSA+IG1heCkKLSAgICAgICAgICAgICAgICBtYXggPSBvbmU7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG1heDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBnZXQgdGhlIHN0cmluZyBkZXNjcmlwdGlvbiBvZiB0aGlzIHBhcnRpY2xlCi0gICAgICovCi0gICAgcHJpdmF0ZSBTdHJpbmcgZkRlc2NyaXB0aW9uID0gbnVsbDsKLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgICAgICAvLyBSRVZJU0lUOiBDb21tZW50ZWQgY29kZSBtYXkgaGVscCB0byBlbGltaW5hdGUgcmVkdW5kYW50IHBhcmVudGhlc2VzICh0ZXN0IGZpcnN0IGJlZm9yZSBjb21taXR0aW5nKQotICAgICAgICBpZiAoZkRlc2NyaXB0aW9uID09IG51bGwpIHsKLSAgICAgICAgICAgIFN0cmluZ0J1ZmZlciBidWZmZXIgPSBuZXcgU3RyaW5nQnVmZmVyKCk7Ci0gICAgICAgICAgICBpZiAoZkNvbXBvc2l0b3IgPT0gTU9ERUxHUk9VUF9BTEwpCi0gICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgiYWxsKCIpOwotICAgICAgICAgICAgZWxzZSAgLy9pZiAoZk1pbk9jY3VycyAhPSAxIHx8IGZNYXhPY2N1cnMgIT0gMSkKLSAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCcoJyk7Ci0gICAgICAgICAgICBpZiAoZlBhcnRpY2xlQ291bnQgPiAwKQotICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoZlBhcnRpY2xlc1swXS50b1N0cmluZygpKTsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAxOyBpIDwgZlBhcnRpY2xlQ291bnQ7IGkrKykgewotICAgICAgICAgICAgICAgIGlmIChmQ29tcG9zaXRvciA9PSBNT0RFTEdST1VQX0NIT0lDRSkKLSAgICAgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgnfCcpOwotICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgnLCcpOwotICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoZlBhcnRpY2xlc1tpXS50b1N0cmluZygpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vaWYgKGZDb21wb3NpdG9yID09IE1PREVMR1JPVVBfQUxMIHx8IGZNaW5PY2N1cnMgIT0gMSB8fCBmTWF4T2NjdXJzICE9IDEpCi0gICAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCcpJyk7Ci0gICAgICAgICAgICBmRGVzY3JpcHRpb24gPSBidWZmZXIudG9TdHJpbmcoKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZkRlc2NyaXB0aW9uOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHJlc2V0KCl7Ci0gICAgICAgIGZDb21wb3NpdG9yID0gTU9ERUxHUk9VUF9TRVFVRU5DRTsKLSAgICAgICAgZlBhcnRpY2xlcyA9IG51bGw7Ci0gICAgICAgIGZQYXJ0aWNsZUNvdW50ID0gMDsKLSAgICAgICAgZkRlc2NyaXB0aW9uID0gbnVsbDsKLSAgICAgICAgZkFubm90YXRpb25zID0gbnVsbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIHR5cGUgb2YgdGhlIG9iamVjdCwgaS5lIEVMRU1FTlRfREVDTEFSQVRJT04uCi0gICAgICovCi0gICAgcHVibGljIHNob3J0IGdldFR5cGUoKSB7Ci0gICAgICAgIHJldHVybiBYU0NvbnN0YW50cy5NT0RFTF9HUk9VUDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgPGNvZGU+bmFtZTwvY29kZT4gb2YgdGhpcyA8Y29kZT5YU09iamVjdDwvY29kZT4gZGVwZW5kaW5nIG9uIHRoZQotICAgICAqIDxjb2RlPlhTT2JqZWN0PC9jb2RlPiB0eXBlLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhlIG5hbWVzcGFjZSBVUkkgb2YgdGhpcyBub2RlLCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiBpdCBpcwotICAgICAqIHVuc3BlY2lmaWVkLiAgZGVmaW5lcyBob3cgYSBuYW1lc3BhY2UgVVJJIGlzIGF0dGFjaGVkIHRvIHNjaGVtYQotICAgICAqIGNvbXBvbmVudHMuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXROYW1lc3BhY2UoKSB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIHtjb21wb3NpdG9yfSBPbmUgb2YgYWxsLCBjaG9pY2Ugb3Igc2VxdWVuY2UuIFRoZSB2YWxpZCBjb25zdGFudHMgdmFsdWVzCi0gICAgICogYXJlOiBBTEwsIENIT0lDRSwgU0VRVUVOQ0UuCi0gICAgICovCi0gICAgcHVibGljIHNob3J0IGdldENvbXBvc2l0b3IoKSB7Ci0gICAgICAgIGlmIChmQ29tcG9zaXRvciA9PSBNT0RFTEdST1VQX0NIT0lDRSkKLSAgICAgICAgICAgIHJldHVybiBYU01vZGVsR3JvdXAuQ09NUE9TSVRPUl9DSE9JQ0U7Ci0gICAgICAgIGVsc2UgaWYgKGZDb21wb3NpdG9yID09IE1PREVMR1JPVVBfU0VRVUVOQ0UpCi0gICAgICAgICAgICByZXR1cm4gWFNNb2RlbEdyb3VwLkNPTVBPU0lUT1JfU0VRVUVOQ0U7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICAgIHJldHVybiBYU01vZGVsR3JvdXAuQ09NUE9TSVRPUl9BTEw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICoge3BhcnRpY2xlc30gQSBsaXN0IG9mIHBhcnRpY2xlcwotICAgICAqLwotICAgIHB1YmxpYyBYU09iamVjdExpc3QgZ2V0UGFydGljbGVzKCkgewotICAgICAgICByZXR1cm4gbmV3IFhTT2JqZWN0TGlzdEltcGwoZlBhcnRpY2xlcywgZlBhcnRpY2xlQ291bnQpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIE9wdGlvbmFsLiBBbm5vdGF0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBYU0Fubm90YXRpb24gZ2V0QW5ub3RhdGlvbigpIHsKLSAgICAgICAgcmV0dXJuIChmQW5ub3RhdGlvbnMgIT0gbnVsbCkgPyAoWFNBbm5vdGF0aW9uKSBmQW5ub3RhdGlvbnMuaXRlbSgwKSA6IG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogT3B0aW9uYWwuIEFubm90YXRpb25zLgotICAgICAqLwotICAgIHB1YmxpYyBYU09iamVjdExpc3QgZ2V0QW5ub3RhdGlvbnMoKSB7Ci0gICAgICAgIHJldHVybiAoZkFubm90YXRpb25zICE9IG51bGwpID8gZkFubm90YXRpb25zIDogWFNPYmplY3RMaXN0SW1wbC5FTVBUWV9MSVNUOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgb3JnLmFwYWNoZS54ZXJjZXMueHMuWFNPYmplY3QjZ2V0TmFtZXNwYWNlSXRlbSgpCi0gICAgICovCi0gICAgcHVibGljIFhTTmFtZXNwYWNlSXRlbSBnZXROYW1lc3BhY2VJdGVtKCkgewotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLX0gLy8gY2xhc3MgWFNNb2RlbEdyb3VwSW1wbApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9YU01vZGVsSW1wbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9YU01vZGVsSW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiZGVkMjk1Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvWFNNb2RlbEltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDgwOSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAyLTIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54czsKLQotaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkFycmF5OwotaW1wb3J0IGphdmEudXRpbC5BYnN0cmFjdExpc3Q7Ci1pbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOwotaW1wb3J0IGphdmEudXRpbC5MaXN0SXRlcmF0b3I7Ci1pbXBvcnQgamF2YS51dGlsLk5vU3VjaEVsZW1lbnRFeGNlcHRpb247Ci1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5Db25zdGFudHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLnV0aWwuU3RyaW5nTGlzdEltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLnV0aWwuWFNOYW1lZE1hcDRUeXBlczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMudXRpbC5YU05hbWVkTWFwSW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMudXRpbC5YU09iamVjdExpc3RJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5TeW1ib2xIYXNoOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5YTUxTeW1ib2xzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuU3RyaW5nTGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTQXR0cmlidXRlRGVjbGFyYXRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU0F0dHJpYnV0ZUdyb3VwRGVmaW5pdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNFbGVtZW50RGVjbGFyYXRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU01vZGVsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNNb2RlbEdyb3VwRGVmaW5pdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTTmFtZWRNYXA7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU05hbWVzcGFjZUl0ZW07Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU05hbWVzcGFjZUl0ZW1MaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNOb3RhdGlvbkRlY2xhcmF0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNPYmplY3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU09iamVjdExpc3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU1R5cGVEZWZpbml0aW9uOwotCi0vKioKLSAqIEltcGxlbWVudHMgWFNNb2RlbDogIGEgcmVhZC1vbmx5IGludGVyZmFjZSB0aGF0IHJlcHJlc2VudHMgYW4gWE1MIFNjaGVtYSwKLSAqIHdoaWNoIGNvdWxkIGJlIGNvbXBvbmVudHMgZnJvbSBkaWZmZXJlbnQgbmFtZXNwYWNlcy4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBTYW5keSBHYW8sIElCTQotICoKLSAqIEB2ZXJzaW9uICRJZDogWFNNb2RlbEltcGwuamF2YSx2IDEuNyAyMDEwLTExLTAxIDA0OjM5OjU1IGpvZWh3IEV4cCAkCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBYU01vZGVsSW1wbCBleHRlbmRzIEFic3RyYWN0TGlzdCBpbXBsZW1lbnRzIFhTTW9kZWwsIFhTTmFtZXNwYWNlSXRlbUxpc3QgewotCi0gICAgLy8gdGhlIG1heCBpbmRleCAvIHRoZSBtYXggdmFsdWUgb2YgWFNPYmplY3QgdHlwZQotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHNob3J0IE1BWF9DT01QX0lEWCA9IFhTVHlwZURlZmluaXRpb24uU0lNUExFX1RZUEU7Ci0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbltdIEdMT0JBTF9DT01QID0ge2ZhbHNlLCAgICAvLyBudWxsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUsICAgICAvLyBhdHRyaWJ1dGUKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ1ZSwgICAgIC8vIGVsZW1lbnQKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ1ZSwgICAgIC8vIHR5cGUKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UsICAgIC8vIGF0dHJpYnV0ZSB1c2UKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ1ZSwgICAgIC8vIGF0dHJpYnV0ZSBncm91cAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlLCAgICAgLy8gZ3JvdXAKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UsICAgIC8vIG1vZGVsIGdyb3VwCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlLCAgICAvLyBwYXJ0aWNsZQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSwgICAgLy8gd2lsZGNhcmQKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UsICAgIC8vIGlkYwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlLCAgICAgLy8gbm90YXRpb24KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UsICAgIC8vIGFubm90YXRpb24KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UsICAgIC8vIGZhY2V0Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlLCAgICAvLyBtdWx0aSB2YWx1ZSBmYWNldAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlLCAgICAgLy8gY29tcGxleCB0eXBlCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUgICAgICAvLyBzaW1wbGUgdHlwZQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07Ci0KLSAgICAvLyBudW1iZXIgb2YgZ3JhbW1hcnMvbmFtZXNwYWNlcyBzdG9yZWQgaGVyZQotICAgIHByaXZhdGUgZmluYWwgaW50IGZHcmFtbWFyQ291bnQ7Ci0gICAgLy8gYWxsIHRhcmdldCBuYW1lc3BhY2VzCi0gICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmdbXSBmTmFtZXNwYWNlczsKLSAgICAvLyBhbGwgc2NoZW1hIGdyYW1tYXIgb2JqZWN0cyAoZm9yIGVhY2ggbmFtZXNwYWNlKQotICAgIHByaXZhdGUgZmluYWwgU2NoZW1hR3JhbW1hcltdIGZHcmFtbWFyTGlzdDsKLSAgICAvLyBhIG1hcCBmcm9tIG5hbWVzcGFjZSB0byBzY2hlbWEgZ3JhbW1hcgotICAgIHByaXZhdGUgZmluYWwgU3ltYm9sSGFzaCBmR3JhbW1hck1hcDsKLSAgICAvLyBhIG1hcCBmcm9tIGVsZW1lbnQgZGVjbGFyYXRpb24gdG8gaXRzIHN1YnN0aXR1dGlvbiBncm91cAotICAgIHByaXZhdGUgZmluYWwgU3ltYm9sSGFzaCBmU3ViR3JvdXBNYXA7Ci0KLSAgICAvLyBzdG9yZSBhIGNlcnRhaW4ga2luZCBvZiBjb21wb25lbnRzIGZyb20gYWxsIG5hbWVzcGFjZXMKLSAgICBwcml2YXRlIGZpbmFsIFhTTmFtZWRNYXBbXSBmR2xvYmFsQ29tcG9uZW50czsKLSAgICAvLyBzdG9yZSBhIGNlcnRhaW4ga2luZCBvZiBjb21wb25lbnRzIGZyb20gb25lIG5hbWVzcGFjZQotICAgIHByaXZhdGUgZmluYWwgWFNOYW1lZE1hcFtdW10gZk5TQ29tcG9uZW50czsKLQotICAgIC8vIGEgc3RyaW5nIGxpc3Qgb2YgYWxsIHRoZSB0YXJnZXQgbmFtZXNwYWNlcy4KLSAgICBwcml2YXRlIGZpbmFsIFN0cmluZ0xpc3QgZk5hbWVzcGFjZXNMaXN0OwotICAgIC8vIHN0b3JlIGFsbCBhbm5vdGF0aW9ucwotICAgIHByaXZhdGUgWFNPYmplY3RMaXN0IGZBbm5vdGF0aW9ucyA9IG51bGw7Ci0KLSAgICAvLyB3aGV0aGVyIHRoZXJlIGlzIGFueSBJREMgaW4gdGhpcyBYU01vZGVsCi0gICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIGZIYXNJREM7Ci0KLSAgIC8qKgotICAgICogQ29uc3RydWN0IGFuIFhTTW9kZWxJbXBsLCBieSBzdG9yaW5nIHNvbWUgZ3JhbW1hcnMgYW5kIGdyYW1tYXJzIGltcG9ydGVkCi0gICAgKiBieSB0aGVtIHRvIHRoaXMgb2JqZWN0LgotICAgICoKLSAgICAqIEBwYXJhbSBncmFtbWFycyAgIHRoZSBhcnJheSBvZiBzY2hlbWEgZ3JhbW1hcnMKLSAgICAqLwotICAgIHB1YmxpYyBYU01vZGVsSW1wbChTY2hlbWFHcmFtbWFyW10gZ3JhbW1hcnMpIHsKLSAgICAgICAgdGhpcyhncmFtbWFycywgQ29uc3RhbnRzLlNDSEVNQV9WRVJTSU9OXzFfMCk7Ci0gICAgfQotCi0gICAgcHVibGljIFhTTW9kZWxJbXBsKFNjaGVtYUdyYW1tYXJbXSBncmFtbWFycywgc2hvcnQgczRzVmVyc2lvbikgewotICAgICAgICAvLyBjb3B5IG5hbWVzcGFjZXMvZ3JhbW1hcnMgZnJvbSB0aGUgYXJyYXkgdG8gb3VyIGFycmF5cwotICAgICAgICBpbnQgbGVuID0gZ3JhbW1hcnMubGVuZ3RoOwotICAgICAgICBmaW5hbCBpbnQgaW5pdGlhbFNpemUgPSBNYXRoLm1heChsZW4rMSwgNSk7Ci0gICAgICAgIFN0cmluZ1tdIG5hbWVzcGFjZXMgPSBuZXcgU3RyaW5nW2luaXRpYWxTaXplXTsKLSAgICAgICAgU2NoZW1hR3JhbW1hcltdIGdyYW1tYXJMaXN0ID0gbmV3IFNjaGVtYUdyYW1tYXJbaW5pdGlhbFNpemVdOwotICAgICAgICBib29sZWFuIGhhc1M0UyA9IGZhbHNlOwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbjsgaSsrKSB7Ci0gICAgICAgICAgICBmaW5hbCBTY2hlbWFHcmFtbWFyIHNnID0gZ3JhbW1hcnNbaV07Ci0gICAgICAgICAgICBmaW5hbCBTdHJpbmcgdG5zID0gc2cuZ2V0VGFyZ2V0TmFtZXNwYWNlKCk7Ci0gICAgICAgICAgICBuYW1lc3BhY2VzW2ldID0gdG5zOwotICAgICAgICAgICAgZ3JhbW1hckxpc3RbaV0gPSBzZzsKLSAgICAgICAgICAgIGlmICh0bnMgPT0gU2NoZW1hU3ltYm9scy5VUklfU0NIRU1BRk9SU0NIRU1BKSB7Ci0gICAgICAgICAgICAgICAgaGFzUzRTID0gdHJ1ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICAvLyBJZiBhIHNjaGVtYSBmb3IgdGhlIHNjaGVtYSBuYW1lc3BhY2UgaXNuJ3QgaW5jbHVkZWQsIGluY2x1ZGUgaXQgaGVyZS4KLSAgICAgICAgaWYgKCFoYXNTNFMpIHsKLSAgICAgICAgICAgIG5hbWVzcGFjZXNbbGVuXSA9IFNjaGVtYVN5bWJvbHMuVVJJX1NDSEVNQUZPUlNDSEVNQTsKLSAgICAgICAgICAgIGdyYW1tYXJMaXN0W2xlbisrXSA9IFNjaGVtYUdyYW1tYXIuZ2V0UzRTR3JhbW1hcihzNHNWZXJzaW9uKTsKLSAgICAgICAgfQotCi0gICAgICAgIFNjaGVtYUdyYW1tYXIgc2cxLCBzZzI7Ci0gICAgICAgIFZlY3RvciBnczsKLSAgICAgICAgaW50IGksIGosIGs7Ci0gICAgICAgIC8vIGFuZCByZWN1cnNpdmVseSBnZXQgYWxsIGltcG9ydGVkIGdyYW1tYXJzLCBhZGQgdGhlbSB0byBvdXIgYXJyYXlzCi0gICAgICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKykgewotICAgICAgICAgICAgLy8gZ2V0IHRoZSBncmFtbWFyCi0gICAgICAgICAgICBzZzEgPSBncmFtbWFyTGlzdFtpXTsKLSAgICAgICAgICAgIGdzID0gc2cxLmdldEltcG9ydGVkR3JhbW1hcnMoKTsKLSAgICAgICAgICAgIC8vIGZvciBlYWNoIGltcG9ydGVkIGdyYW1tYXIKLSAgICAgICAgICAgIGZvciAoaiA9IGdzID09IG51bGwgPyAtMSA6IGdzLnNpemUoKSAtIDE7IGogPj0gMDsgai0tKSB7Ci0gICAgICAgICAgICAgICAgc2cyID0gKFNjaGVtYUdyYW1tYXIpZ3MuZWxlbWVudEF0KGopOwotICAgICAgICAgICAgICAgIC8vIGNoZWNrIHdoZXRoZXIgdGhpcyBncmFtbWFyIGlzIGFscmVhZHkgaW4gdGhlIGxpc3QKLSAgICAgICAgICAgICAgICBmb3IgKGsgPSAwOyBrIDwgbGVuOyBrKyspIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKHNnMiA9PSBncmFtbWFyTGlzdFtrXSkgewotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLy8gaWYgaXQncyBub3QsIGFkZCBpdCB0byB0aGUgbGlzdAotICAgICAgICAgICAgICAgIGlmIChrID09IGxlbikgewotICAgICAgICAgICAgICAgICAgICAvLyBlbnN1cmUgdGhlIGNhcGFjaXR5IG9mIHRoZSBhcnJheXMKLSAgICAgICAgICAgICAgICAgICAgaWYgKGxlbiA9PSBncmFtbWFyTGlzdC5sZW5ndGgpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1tdIG5ld1NBID0gbmV3IFN0cmluZ1tsZW4qMl07Ci0gICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KG5hbWVzcGFjZXMsIDAsIG5ld1NBLCAwLCBsZW4pOwotICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXNwYWNlcyA9IG5ld1NBOwotICAgICAgICAgICAgICAgICAgICAgICAgU2NoZW1hR3JhbW1hcltdIG5ld0dBID0gbmV3IFNjaGVtYUdyYW1tYXJbbGVuKjJdOwotICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShncmFtbWFyTGlzdCwgMCwgbmV3R0EsIDAsIGxlbik7Ci0gICAgICAgICAgICAgICAgICAgICAgICBncmFtbWFyTGlzdCA9IG5ld0dBOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZXNbbGVuXSA9IHNnMi5nZXRUYXJnZXROYW1lc3BhY2UoKTsKLSAgICAgICAgICAgICAgICAgICAgZ3JhbW1hckxpc3RbbGVuXSA9IHNnMjsKLSAgICAgICAgICAgICAgICAgICAgbGVuKys7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgZk5hbWVzcGFjZXMgPSBuYW1lc3BhY2VzOwotICAgICAgICBmR3JhbW1hckxpc3QgPSBncmFtbWFyTGlzdDsKLQotICAgICAgICBib29sZWFuIGhhc0lEQyA9IGZhbHNlOwotICAgICAgICAvLyBlc3RhYmxpc2ggdGhlIG1hcHBpbmcgZnJvbSBuYW1lc3BhY2UgdG8gZ3JhbW1hcnMKLSAgICAgICAgZkdyYW1tYXJNYXAgPSBuZXcgU3ltYm9sSGFzaChsZW4qMik7Ci0gICAgICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKykgewotICAgICAgICAgICAgZkdyYW1tYXJNYXAucHV0KG51bGwyRW1wdHlTdHJpbmcoZk5hbWVzcGFjZXNbaV0pLCBmR3JhbW1hckxpc3RbaV0pOwotICAgICAgICAgICAgLy8gdXBkYXRlIHRoZSBpZGMgZmllbGQKLSAgICAgICAgICAgIGlmIChmR3JhbW1hckxpc3RbaV0uaGFzSURDb25zdHJhaW50cygpKSB7Ci0gICAgICAgICAgICAgICAgaGFzSURDID0gdHJ1ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGZIYXNJREMgPSBoYXNJREM7Ci0gICAgICAgIGZHcmFtbWFyQ291bnQgPSBsZW47Ci0gICAgICAgIGZHbG9iYWxDb21wb25lbnRzID0gbmV3IFhTTmFtZWRNYXBbTUFYX0NPTVBfSURYKzFdOwotICAgICAgICBmTlNDb21wb25lbnRzID0gbmV3IFhTTmFtZWRNYXBbbGVuXVtNQVhfQ09NUF9JRFgrMV07Ci0gICAgICAgIGZOYW1lc3BhY2VzTGlzdCA9IG5ldyBTdHJpbmdMaXN0SW1wbChmTmFtZXNwYWNlcywgZkdyYW1tYXJDb3VudCk7Ci0KLSAgICAgICAgLy8gYnVpbGQgc3Vic3RpdHV0aW9uIGdyb3VwcwotICAgICAgICBmU3ViR3JvdXBNYXAgPSBidWlsZFN1Ykdyb3VwcygpOwotICAgIH0KLQotICAgIHByaXZhdGUgU3ltYm9sSGFzaCBidWlsZFN1Ykdyb3Vwc19PcmcoKSB7Ci0gICAgICAgIFN1YnN0aXR1dGlvbkdyb3VwSGFuZGxlciBzZ0hhbmRsZXIgPSBuZXcgU3Vic3RpdHV0aW9uR3JvdXBIYW5kbGVyKG51bGwpOwotICAgICAgICBmb3IgKGludCBpID0gMCA7IGkgPCBmR3JhbW1hckNvdW50OyBpKyspIHsKLSAgICAgICAgICAgIHNnSGFuZGxlci5hZGRTdWJzdGl0dXRpb25Hcm91cChmR3JhbW1hckxpc3RbaV0uZ2V0U3Vic3RpdHV0aW9uR3JvdXBzKCkpOwotICAgICAgICB9Ci0KLSAgICAgICAgZmluYWwgWFNOYW1lZE1hcCBlbGVtZW50cyA9IGdldENvbXBvbmVudHMoWFNDb25zdGFudHMuRUxFTUVOVF9ERUNMQVJBVElPTik7Ci0gICAgICAgIGZpbmFsIGludCBsZW4gPSBlbGVtZW50cy5nZXRMZW5ndGgoKTsKLSAgICAgICAgZmluYWwgU3ltYm9sSGFzaCBzdWJHcm91cE1hcCA9IG5ldyBTeW1ib2xIYXNoKGxlbioyKTsKLSAgICAgICAgWFNFbGVtZW50RGVjbCBoZWFkOwotICAgICAgICBYU0VsZW1lbnREZWNsYXJhdGlvbltdIHN1Ykdyb3VwOwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbjsgaSsrKSB7Ci0gICAgICAgICAgICBoZWFkID0gKFhTRWxlbWVudERlY2wpZWxlbWVudHMuaXRlbShpKTsKLSAgICAgICAgICAgIHN1Ykdyb3VwID0gc2dIYW5kbGVyLmdldFN1YnN0aXR1dGlvbkdyb3VwKGhlYWQpOwotICAgICAgICAgICAgc3ViR3JvdXBNYXAucHV0KGhlYWQsIHN1Ykdyb3VwLmxlbmd0aCA+IDAgPwotICAgICAgICAgICAgICAgICAgICBuZXcgWFNPYmplY3RMaXN0SW1wbChzdWJHcm91cCwgc3ViR3JvdXAubGVuZ3RoKSA6IFhTT2JqZWN0TGlzdEltcGwuRU1QVFlfTElTVCk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHN1Ykdyb3VwTWFwOwotICAgIH0KLQotICAgIHByaXZhdGUgU3ltYm9sSGFzaCBidWlsZFN1Ykdyb3VwcygpIHsKLSAgICAgICAgU3Vic3RpdHV0aW9uR3JvdXBIYW5kbGVyIHNnSGFuZGxlciA9IG5ldyBTdWJzdGl0dXRpb25Hcm91cEhhbmRsZXIobnVsbCk7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwIDsgaSA8IGZHcmFtbWFyQ291bnQ7IGkrKykgewotICAgICAgICAgICAgc2dIYW5kbGVyLmFkZFN1YnN0aXR1dGlvbkdyb3VwKGZHcmFtbWFyTGlzdFtpXS5nZXRTdWJzdGl0dXRpb25Hcm91cHMoKSk7Ci0gICAgICAgIH0KLQotICAgICAgICBmaW5hbCBYU09iamVjdExpc3RJbXBsIGVsZW1lbnRzID0gZ2V0R2xvYmFsRWxlbWVudHMoKTsKLSAgICAgICAgZmluYWwgaW50IGxlbiA9IGVsZW1lbnRzLmdldExlbmd0aCgpOwotICAgICAgICBmaW5hbCBTeW1ib2xIYXNoIHN1Ykdyb3VwTWFwID0gbmV3IFN5bWJvbEhhc2gobGVuKjIpOwotICAgICAgICBYU0VsZW1lbnREZWNsIGhlYWQ7Ci0gICAgICAgIFhTRWxlbWVudERlY2xhcmF0aW9uW10gc3ViR3JvdXA7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKLSAgICAgICAgICAgIGhlYWQgPSAoWFNFbGVtZW50RGVjbCllbGVtZW50cy5pdGVtKGkpOwotICAgICAgICAgICAgc3ViR3JvdXAgPSBzZ0hhbmRsZXIuZ2V0U3Vic3RpdHV0aW9uR3JvdXAoaGVhZCk7Ci0gICAgICAgICAgICBzdWJHcm91cE1hcC5wdXQoaGVhZCwgc3ViR3JvdXAubGVuZ3RoID4gMCA/Ci0gICAgICAgICAgICAgICAgICAgIG5ldyBYU09iamVjdExpc3RJbXBsKHN1Ykdyb3VwLCBzdWJHcm91cC5sZW5ndGgpIDogWFNPYmplY3RMaXN0SW1wbC5FTVBUWV9MSVNUKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gc3ViR3JvdXBNYXA7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBYU09iamVjdExpc3RJbXBsIGdldEdsb2JhbEVsZW1lbnRzKCkgewotICAgICAgICBmaW5hbCBTeW1ib2xIYXNoW10gdGFibGVzID0gbmV3IFN5bWJvbEhhc2hbZkdyYW1tYXJDb3VudF07Ci0gICAgICAgIGludCBsZW5ndGggPSAwOwotCi0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZkdyYW1tYXJDb3VudDsgaSsrKSB7Ci0gICAgICAgICAgICB0YWJsZXNbaV0gPSBmR3JhbW1hckxpc3RbaV0uZkFsbEdsb2JhbEVsZW1EZWNsczsKLSAgICAgICAgICAgIGxlbmd0aCArPSB0YWJsZXNbaV0uZ2V0TGVuZ3RoKCk7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAobGVuZ3RoID09IDApIHsKLSAgICAgICAgICAgIHJldHVybiBYU09iamVjdExpc3RJbXBsLkVNUFRZX0xJU1Q7Ci0gICAgICAgIH0KLQotICAgICAgICBmaW5hbCBYU09iamVjdFtdIGNvbXBvbmVudHMgPSBuZXcgWFNPYmplY3RbbGVuZ3RoXTsKLQotICAgICAgICBpbnQgc3RhcnQgPSAwOwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZHcmFtbWFyQ291bnQ7IGkrKykgewotICAgICAgICAgICAgdGFibGVzW2ldLmdldFZhbHVlcyhjb21wb25lbnRzLCBzdGFydCk7Ci0gICAgICAgICAgICBzdGFydCArPSB0YWJsZXNbaV0uZ2V0TGVuZ3RoKCk7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gbmV3IFhTT2JqZWN0TGlzdEltcGwoY29tcG9uZW50cywgbGVuZ3RoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb252ZW5pZW5jZSBtZXRob2QuIFJldHVybnMgYSBsaXN0IG9mIGFsbCBuYW1lc3BhY2VzIHRoYXQgYmVsb25nIHRvCi0gICAgICogdGhpcyBzY2hlbWEuCi0gICAgICogQHJldHVybiBBIGxpc3Qgb2YgYWxsIG5hbWVzcGFjZXMgdGhhdCBiZWxvbmcgdG8gdGhpcyBzY2hlbWEgb3IKLSAgICAgKiAgIDxjb2RlPm51bGw8L2NvZGU+IGlmIGFsbCBjb21wb25lbnRzIGRvbid0IGhhdmUgYSB0YXJnZXROYW1lc3BhY2UuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZ0xpc3QgZ2V0TmFtZXNwYWNlcygpIHsKLSAgICAgICAgcmV0dXJuIGZOYW1lc3BhY2VzTGlzdDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBIHNldCBvZiBuYW1lc3BhY2Ugc2NoZW1hIGluZm9ybWF0aW9uIGluZm9ybWF0aW9uIGl0ZW1zIChvZiB0eXBlCi0gICAgICogPGNvZGU+WFNOYW1lc3BhY2VJdGVtPC9jb2RlPiksIG9uZSBmb3IgZWFjaCBuYW1lc3BhY2UgbmFtZSB3aGljaAotICAgICAqIGFwcGVhcnMgYXMgdGhlIHRhcmdldCBuYW1lc3BhY2Ugb2YgYW55IHNjaGVtYSBjb21wb25lbnQgaW4gdGhlIHNjaGVtYQotICAgICAqIHVzZWQgZm9yIHRoYXQgYXNzZXNzbWVudCwgYW5kIG9uZSBmb3IgYWJzZW50IGlmIGFueSBzY2hlbWEgY29tcG9uZW50Ci0gICAgICogaW4gdGhlIHNjaGVtYSBoYWQgbm8gdGFyZ2V0IG5hbWVzcGFjZS4gRm9yIG1vcmUgaW5mb3JtYXRpb24gc2VlCi0gICAgICogc2NoZW1hIGluZm9ybWF0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBYU05hbWVzcGFjZUl0ZW1MaXN0IGdldE5hbWVzcGFjZUl0ZW1zKCkgewotICAgICAgICByZXR1cm4gdGhpczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGEgbGlzdCBvZiB0b3AtbGV2ZWwgY29tcG9uZW50cywgaS5lLiBlbGVtZW50IGRlY2xhcmF0aW9ucywKLSAgICAgKiBhdHRyaWJ1dGUgZGVjbGFyYXRpb25zLCBldGMuCi0gICAgICogQHBhcmFtIG9iamVjdFR5cGUgVGhlIHR5cGUgb2YgdGhlIGRlY2xhcmF0aW9uLCBpLmUuCi0gICAgICogICA8Y29kZT5FTEVNRU5UX0RFQ0xBUkFUSU9OPC9jb2RlPi4gTm90ZSB0aGF0Ci0gICAgICogICA8Y29kZT5YU1R5cGVEZWZpbml0aW9uLlNJTVBMRV9UWVBFPC9jb2RlPiBhbmQKLSAgICAgKiAgIDxjb2RlPlhTVHlwZURlZmluaXRpb24uQ09NUExFWF9UWVBFPC9jb2RlPiBjYW4gYWxzbyBiZSB1c2VkIGFzIHRoZQotICAgICAqICAgPGNvZGU+b2JqZWN0VHlwZTwvY29kZT4gdG8gcmV0cmlldmUgb25seSBjb21wbGV4IHR5cGVzIG9yIHNpbXBsZQotICAgICAqICAgdHlwZXMsIGluc3RlYWQgb2YgYWxsIHR5cGVzLgotICAgICAqIEByZXR1cm4gIEEgbGlzdCBvZiB0b3AtbGV2ZWwgZGVmaW5pdGlvbnMgb2YgdGhlIHNwZWNpZmllZCB0eXBlIGluCi0gICAgICogICA8Y29kZT5vYmplY3RUeXBlPC9jb2RlPiBvciBhbiBlbXB0eSA8Y29kZT5YU05hbWVkTWFwPC9jb2RlPiBpZiBubwotICAgICAqICAgc3VjaCBkZWZpbml0aW9ucyBleGlzdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3luY2hyb25pemVkIFhTTmFtZWRNYXAgZ2V0Q29tcG9uZW50cyhzaG9ydCBvYmplY3RUeXBlKSB7Ci0gICAgICAgIGlmIChvYmplY3RUeXBlIDw9IDAgfHwgb2JqZWN0VHlwZSA+IE1BWF9DT01QX0lEWCB8fAotICAgICAgICAgICAgIUdMT0JBTF9DT01QW29iamVjdFR5cGVdKSB7Ci0gICAgICAgICAgICByZXR1cm4gWFNOYW1lZE1hcEltcGwuRU1QVFlfTUFQOwotICAgICAgICB9Ci0KLSAgICAgICAgU3ltYm9sSGFzaFtdIHRhYmxlcyA9IG5ldyBTeW1ib2xIYXNoW2ZHcmFtbWFyQ291bnRdOwotICAgICAgICAvLyBnZXQgYWxsIGhhc2h0YWJsZXMgZnJvbSBhbGwgbmFtZXNwYWNlcyBmb3IgdGhpcyB0eXBlIG9mIGNvbXBvbmVudHMKLSAgICAgICAgaWYgKGZHbG9iYWxDb21wb25lbnRzW29iamVjdFR5cGVdID09IG51bGwpIHsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZkdyYW1tYXJDb3VudDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgc3dpdGNoIChvYmplY3RUeXBlKSB7Ci0gICAgICAgICAgICAgICAgY2FzZSBYU0NvbnN0YW50cy5UWVBFX0RFRklOSVRJT046Ci0gICAgICAgICAgICAgICAgY2FzZSBYU1R5cGVEZWZpbml0aW9uLkNPTVBMRVhfVFlQRToKLSAgICAgICAgICAgICAgICBjYXNlIFhTVHlwZURlZmluaXRpb24uU0lNUExFX1RZUEU6Ci0gICAgICAgICAgICAgICAgICAgIHRhYmxlc1tpXSA9IGZHcmFtbWFyTGlzdFtpXS5mR2xvYmFsVHlwZURlY2xzOwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICBjYXNlIFhTQ29uc3RhbnRzLkFUVFJJQlVURV9ERUNMQVJBVElPTjoKLSAgICAgICAgICAgICAgICAgICAgdGFibGVzW2ldID0gZkdyYW1tYXJMaXN0W2ldLmZHbG9iYWxBdHRyRGVjbHM7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGNhc2UgWFNDb25zdGFudHMuRUxFTUVOVF9ERUNMQVJBVElPTjoKLSAgICAgICAgICAgICAgICAgICAgdGFibGVzW2ldID0gZkdyYW1tYXJMaXN0W2ldLmZHbG9iYWxFbGVtRGVjbHM7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGNhc2UgWFNDb25zdGFudHMuQVRUUklCVVRFX0dST1VQOgotICAgICAgICAgICAgICAgICAgICB0YWJsZXNbaV0gPSBmR3JhbW1hckxpc3RbaV0uZkdsb2JhbEF0dHJHcnBEZWNsczsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgY2FzZSBYU0NvbnN0YW50cy5NT0RFTF9HUk9VUF9ERUZJTklUSU9OOgotICAgICAgICAgICAgICAgICAgICB0YWJsZXNbaV0gPSBmR3JhbW1hckxpc3RbaV0uZkdsb2JhbEdyb3VwRGVjbHM7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGNhc2UgWFNDb25zdGFudHMuTk9UQVRJT05fREVDTEFSQVRJT046Ci0gICAgICAgICAgICAgICAgICAgIHRhYmxlc1tpXSA9IGZHcmFtbWFyTGlzdFtpXS5mR2xvYmFsTm90YXRpb25EZWNsczsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gZm9yIGNvbXBsZXgvc2ltcGxlIHR5cGVzLCBjcmVhdGUgYSBzcGVjaWFsIGltcGxlbWVudGF0aW9uLAotICAgICAgICAgICAgLy8gd2hpY2ggdGFrZSBzcGVjaWZpYyB0eXBlcyBvdXQgb2YgdGhlIGhhc2ggdGFibGUKLSAgICAgICAgICAgIGlmIChvYmplY3RUeXBlID09IFhTVHlwZURlZmluaXRpb24uQ09NUExFWF9UWVBFIHx8Ci0gICAgICAgICAgICAgICAgb2JqZWN0VHlwZSA9PSBYU1R5cGVEZWZpbml0aW9uLlNJTVBMRV9UWVBFKSB7Ci0gICAgICAgICAgICAgICAgZkdsb2JhbENvbXBvbmVudHNbb2JqZWN0VHlwZV0gPSBuZXcgWFNOYW1lZE1hcDRUeXBlcyhmTmFtZXNwYWNlcywgdGFibGVzLCBmR3JhbW1hckNvdW50LCBvYmplY3RUeXBlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIGZHbG9iYWxDb21wb25lbnRzW29iamVjdFR5cGVdID0gbmV3IFhTTmFtZWRNYXBJbXBsKGZOYW1lc3BhY2VzLCB0YWJsZXMsIGZHcmFtbWFyQ291bnQpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIGZHbG9iYWxDb21wb25lbnRzW29iamVjdFR5cGVdOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbnZlbmllbmNlIG1ldGhvZC4gUmV0dXJucyBhIGxpc3Qgb2YgdG9wLWxldmVsIGNvbXBvbmVudCBkZWNsYXJhdGlvbnMKLSAgICAgKiB0aGF0IGFyZSBkZWZpbmVkIHdpdGhpbiB0aGUgc3BlY2lmaWVkIG5hbWVzcGFjZSwgaS5lLiBlbGVtZW50Ci0gICAgICogZGVjbGFyYXRpb25zLCBhdHRyaWJ1dGUgZGVjbGFyYXRpb25zLCBldGMuCi0gICAgICogQHBhcmFtIG9iamVjdFR5cGUgVGhlIHR5cGUgb2YgdGhlIGRlY2xhcmF0aW9uLCBpLmUuCi0gICAgICogICA8Y29kZT5FTEVNRU5UX0RFQ0xBUkFUSU9OPC9jb2RlPi4KLSAgICAgKiBAcGFyYW0gbmFtZXNwYWNlIFRoZSBuYW1lc3BhY2UgdG8gd2hpY2ggdGhlIGRlY2xhcmF0aW9uIGJlbG9uZ3Mgb3IKLSAgICAgKiAgIDxjb2RlPm51bGw8L2NvZGU+IChmb3IgY29tcG9uZW50cyB3aXRoIG5vIHRhcmdldCBuYW1lc3BhY2UpLgotICAgICAqIEByZXR1cm4gIEEgbGlzdCBvZiB0b3AtbGV2ZWwgZGVmaW5pdGlvbnMgb2YgdGhlIHNwZWNpZmllZCB0eXBlIGluCi0gICAgICogICA8Y29kZT5vYmplY3RUeXBlPC9jb2RlPiBhbmQgZGVmaW5lZCBpbiB0aGUgc3BlY2lmaWVkCi0gICAgICogICA8Y29kZT5uYW1lc3BhY2U8L2NvZGU+IG9yIGFuIGVtcHR5IDxjb2RlPlhTTmFtZWRNYXA8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgWFNOYW1lZE1hcCBnZXRDb21wb25lbnRzQnlOYW1lc3BhY2Uoc2hvcnQgb2JqZWN0VHlwZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBuYW1lc3BhY2UpIHsKLSAgICAgICAgaWYgKG9iamVjdFR5cGUgPD0gMCB8fCBvYmplY3RUeXBlID4gTUFYX0NPTVBfSURYIHx8Ci0gICAgICAgICAgICAhR0xPQkFMX0NPTVBbb2JqZWN0VHlwZV0pIHsKLSAgICAgICAgICAgIHJldHVybiBYU05hbWVkTWFwSW1wbC5FTVBUWV9NQVA7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyB0cnkgdG8gZmluZCB0aGUgZ3JhbW1hcgotICAgICAgICBpbnQgaSA9IDA7Ci0gICAgICAgIGlmIChuYW1lc3BhY2UgIT0gbnVsbCkgewotICAgICAgICAgICAgZm9yICg7IGkgPCBmR3JhbW1hckNvdW50OyArK2kpIHsKLSAgICAgICAgICAgICAgICBpZiAobmFtZXNwYWNlLmVxdWFscyhmTmFtZXNwYWNlc1tpXSkpIHsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgZm9yICg7IGkgPCBmR3JhbW1hckNvdW50OyArK2kpIHsKLSAgICAgICAgICAgICAgICBpZiAoZk5hbWVzcGFjZXNbaV0gPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGkgPT0gZkdyYW1tYXJDb3VudCkgewotICAgICAgICAgICAgcmV0dXJuIFhTTmFtZWRNYXBJbXBsLkVNUFRZX01BUDsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIGdldCB0aGUgaGFzaHRhYmxlIGZvciB0aGlzIHR5cGUgb2YgY29tcG9uZW50cwotICAgICAgICBpZiAoZk5TQ29tcG9uZW50c1tpXVtvYmplY3RUeXBlXSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBTeW1ib2xIYXNoIHRhYmxlID0gbnVsbDsKLSAgICAgICAgICAgIHN3aXRjaCAob2JqZWN0VHlwZSkgewotICAgICAgICAgICAgY2FzZSBYU0NvbnN0YW50cy5UWVBFX0RFRklOSVRJT046Ci0gICAgICAgICAgICBjYXNlIFhTVHlwZURlZmluaXRpb24uQ09NUExFWF9UWVBFOgotICAgICAgICAgICAgY2FzZSBYU1R5cGVEZWZpbml0aW9uLlNJTVBMRV9UWVBFOgotICAgICAgICAgICAgICAgIHRhYmxlID0gZkdyYW1tYXJMaXN0W2ldLmZHbG9iYWxUeXBlRGVjbHM7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICBjYXNlIFhTQ29uc3RhbnRzLkFUVFJJQlVURV9ERUNMQVJBVElPTjoKLSAgICAgICAgICAgICAgICB0YWJsZSA9IGZHcmFtbWFyTGlzdFtpXS5mR2xvYmFsQXR0ckRlY2xzOwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgY2FzZSBYU0NvbnN0YW50cy5FTEVNRU5UX0RFQ0xBUkFUSU9OOgotICAgICAgICAgICAgICAgIHRhYmxlID0gZkdyYW1tYXJMaXN0W2ldLmZHbG9iYWxFbGVtRGVjbHM7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICBjYXNlIFhTQ29uc3RhbnRzLkFUVFJJQlVURV9HUk9VUDoKLSAgICAgICAgICAgICAgICB0YWJsZSA9IGZHcmFtbWFyTGlzdFtpXS5mR2xvYmFsQXR0ckdycERlY2xzOwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgY2FzZSBYU0NvbnN0YW50cy5NT0RFTF9HUk9VUF9ERUZJTklUSU9OOgotICAgICAgICAgICAgICAgIHRhYmxlID0gZkdyYW1tYXJMaXN0W2ldLmZHbG9iYWxHcm91cERlY2xzOwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgY2FzZSBYU0NvbnN0YW50cy5OT1RBVElPTl9ERUNMQVJBVElPTjoKLSAgICAgICAgICAgICAgICB0YWJsZSA9IGZHcmFtbWFyTGlzdFtpXS5mR2xvYmFsTm90YXRpb25EZWNsczsKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gZm9yIGNvbXBsZXgvc2ltcGxlIHR5cGVzLCBjcmVhdGUgYSBzcGVjaWFsIGltcGxlbWVudGF0aW9uLAotICAgICAgICAgICAgLy8gd2hpY2ggdGFrZSBzcGVjaWZpYyB0eXBlcyBvdXQgb2YgdGhlIGhhc2ggdGFibGUKLSAgICAgICAgICAgIGlmIChvYmplY3RUeXBlID09IFhTVHlwZURlZmluaXRpb24uQ09NUExFWF9UWVBFIHx8Ci0gICAgICAgICAgICAgICAgb2JqZWN0VHlwZSA9PSBYU1R5cGVEZWZpbml0aW9uLlNJTVBMRV9UWVBFKSB7Ci0gICAgICAgICAgICAgICAgZk5TQ29tcG9uZW50c1tpXVtvYmplY3RUeXBlXSA9IG5ldyBYU05hbWVkTWFwNFR5cGVzKG5hbWVzcGFjZSwgdGFibGUsIG9iamVjdFR5cGUpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgZk5TQ29tcG9uZW50c1tpXVtvYmplY3RUeXBlXSA9IG5ldyBYU05hbWVkTWFwSW1wbChuYW1lc3BhY2UsIHRhYmxlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBmTlNDb21wb25lbnRzW2ldW29iamVjdFR5cGVdOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbnZlbmllbmNlIG1ldGhvZC4gUmV0dXJucyBhIHRvcC1sZXZlbCBzaW1wbGUgb3IgY29tcGxleCB0eXBlCi0gICAgICogZGVmaW5pdGlvbi4KLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgZGVmaW5pdGlvbi4KLSAgICAgKiBAcGFyYW0gbmFtZXNwYWNlIFRoZSBuYW1lc3BhY2Ugb2YgdGhlIGRlZmluaXRpb24sIG90aGVyd2lzZSBudWxsLgotICAgICAqIEByZXR1cm4gQW4gPGNvZGU+WFNUeXBlRGVmaW5pdGlvbjwvY29kZT4gb3IgbnVsbCBpZiBzdWNoIGRlZmluaXRpb24KLSAgICAgKiAgIGRvZXMgbm90IGV4aXN0LgotICAgICAqLwotICAgIHB1YmxpYyBYU1R5cGVEZWZpbml0aW9uIGdldFR5cGVEZWZpbml0aW9uKFN0cmluZyBuYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBuYW1lc3BhY2UpIHsKLSAgICAgICAgU2NoZW1hR3JhbW1hciBzZyA9IChTY2hlbWFHcmFtbWFyKWZHcmFtbWFyTWFwLmdldChudWxsMkVtcHR5U3RyaW5nKG5hbWVzcGFjZSkpOwotICAgICAgICBpZiAoc2cgPT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIChYU1R5cGVEZWZpbml0aW9uKXNnLmZHbG9iYWxUeXBlRGVjbHMuZ2V0KG5hbWUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbnZlbmllbmNlIG1ldGhvZC4gUmV0dXJucyBhIHRvcC1sZXZlbCBzaW1wbGUgb3IgY29tcGxleCB0eXBlCi0gICAgICogZGVmaW5pdGlvbi4KLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgZGVmaW5pdGlvbi4KLSAgICAgKiBAcGFyYW0gbmFtZXNwYWNlIFRoZSBuYW1lc3BhY2Ugb2YgdGhlIGRlZmluaXRpb24sIG90aGVyd2lzZSBudWxsLgotICAgICAqIEBwYXJhbSBsb2MgVGhlIHNjaGVtYSBsb2NhdGlvbiB3aGVyZSB0aGUgY29tcG9uZW50IHdhcyBkZWZpbmVkCi0gICAgICogQHJldHVybiBBbiA8Y29kZT5YU1R5cGVEZWZpbml0aW9uPC9jb2RlPiBvciBudWxsIGlmIHN1Y2ggZGVmaW5pdGlvbgotICAgICAqICAgZG9lcyBub3QgZXhpc3QuCi0gICAgICovCi0gICAgcHVibGljIFhTVHlwZURlZmluaXRpb24gZ2V0VHlwZURlZmluaXRpb24oU3RyaW5nIG5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG5hbWVzcGFjZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbG9jKSB7Ci0gICAgICAgIFNjaGVtYUdyYW1tYXIgc2cgPSAoU2NoZW1hR3JhbW1hcilmR3JhbW1hck1hcC5nZXQobnVsbDJFbXB0eVN0cmluZyhuYW1lc3BhY2UpKTsKLSAgICAgICAgaWYgKHNnID09IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBzZy5nZXRHbG9iYWxUeXBlRGVjbChuYW1lLCBsb2MpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbnZlbmllbmNlIG1ldGhvZC4gUmV0dXJucyBhIHRvcC1sZXZlbCBhdHRyaWJ1dGUgZGVjbGFyYXRpb24uCi0gICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGRlY2xhcmF0aW9uLgotICAgICAqIEBwYXJhbSBuYW1lc3BhY2UgVGhlIG5hbWVzcGFjZSBvZiB0aGUgZGVmaW5pdGlvbiwgb3RoZXJ3aXNlIG51bGwuCi0gICAgICogQHJldHVybiBBIHRvcC1sZXZlbCBhdHRyaWJ1dGUgZGVjbGFyYXRpb24gb3IgbnVsbCBpZiBzdWNoIGRlY2xhcmF0aW9uCi0gICAgICogICBkb2VzIG5vdCBleGlzdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFNBdHRyaWJ1dGVEZWNsYXJhdGlvbiBnZXRBdHRyaWJ1dGVEZWNsYXJhdGlvbihTdHJpbmcgbmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBuYW1lc3BhY2UpIHsKLSAgICAgICAgU2NoZW1hR3JhbW1hciBzZyA9IChTY2hlbWFHcmFtbWFyKWZHcmFtbWFyTWFwLmdldChudWxsMkVtcHR5U3RyaW5nKG5hbWVzcGFjZSkpOwotICAgICAgICBpZiAoc2cgPT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIChYU0F0dHJpYnV0ZURlY2xhcmF0aW9uKXNnLmZHbG9iYWxBdHRyRGVjbHMuZ2V0KG5hbWUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbnZlbmllbmNlIG1ldGhvZC4gUmV0dXJucyBhIHRvcC1sZXZlbCBhdHRyaWJ1dGUgZGVjbGFyYXRpb24uCi0gICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGRlY2xhcmF0aW9uLgotICAgICAqIEBwYXJhbSBuYW1lc3BhY2UgVGhlIG5hbWVzcGFjZSBvZiB0aGUgZGVmaW5pdGlvbiwgb3RoZXJ3aXNlIG51bGwuCi0gICAgICogQHBhcmFtIGxvYyBUaGUgc2NoZW1hIGxvY2F0aW9uIHdoZXJlIHRoZSBjb21wb25lbnQgd2FzIGRlZmluZWQKLSAgICAgKiBAcmV0dXJuIEEgdG9wLWxldmVsIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbiBvciBudWxsIGlmIHN1Y2ggZGVjbGFyYXRpb24KLSAgICAgKiAgIGRvZXMgbm90IGV4aXN0LgotICAgICAqLwotICAgIHB1YmxpYyBYU0F0dHJpYnV0ZURlY2xhcmF0aW9uIGdldEF0dHJpYnV0ZURlY2xhcmF0aW9uKFN0cmluZyBuYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG5hbWVzcGFjZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBsb2MpIHsKLSAgICAgICAgU2NoZW1hR3JhbW1hciBzZyA9IChTY2hlbWFHcmFtbWFyKWZHcmFtbWFyTWFwLmdldChudWxsMkVtcHR5U3RyaW5nKG5hbWVzcGFjZSkpOwotICAgICAgICBpZiAoc2cgPT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHNnLmdldEdsb2JhbEF0dHJpYnV0ZURlY2wobmFtZSwgbG9jKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb252ZW5pZW5jZSBtZXRob2QuIFJldHVybnMgYSB0b3AtbGV2ZWwgZWxlbWVudCBkZWNsYXJhdGlvbi4KLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgZGVjbGFyYXRpb24uCi0gICAgICogQHBhcmFtIG5hbWVzcGFjZSBUaGUgbmFtZXNwYWNlIG9mIHRoZSBkZWZpbml0aW9uLCBvdGhlcndpc2UgbnVsbC4KLSAgICAgKiBAcmV0dXJuIEEgdG9wLWxldmVsIGVsZW1lbnQgZGVjbGFyYXRpb24gb3IgbnVsbCBpZiBzdWNoIGRlY2xhcmF0aW9uCi0gICAgICogICBkb2VzIG5vdCBleGlzdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFNFbGVtZW50RGVjbGFyYXRpb24gZ2V0RWxlbWVudERlY2xhcmF0aW9uKFN0cmluZyBuYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbmFtZXNwYWNlKSB7Ci0gICAgICAgIFNjaGVtYUdyYW1tYXIgc2cgPSAoU2NoZW1hR3JhbW1hcilmR3JhbW1hck1hcC5nZXQobnVsbDJFbXB0eVN0cmluZyhuYW1lc3BhY2UpKTsKLSAgICAgICAgaWYgKHNnID09IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiAoWFNFbGVtZW50RGVjbGFyYXRpb24pc2cuZkdsb2JhbEVsZW1EZWNscy5nZXQobmFtZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29udmVuaWVuY2UgbWV0aG9kLiBSZXR1cm5zIGEgdG9wLWxldmVsIGVsZW1lbnQgZGVjbGFyYXRpb24uCi0gICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGRlY2xhcmF0aW9uLgotICAgICAqIEBwYXJhbSBuYW1lc3BhY2UgVGhlIG5hbWVzcGFjZSBvZiB0aGUgZGVmaW5pdGlvbiwgb3RoZXJ3aXNlIG51bGwuCi0gICAgICogQHBhcmFtIGxvYyBUaGUgc2NoZW1hIGxvY2F0aW9uIHdoZXJlIHRoZSBjb21wb25lbnQgd2FzIGRlZmluZWQKLSAgICAgKiBAcmV0dXJuIEEgdG9wLWxldmVsIGVsZW1lbnQgZGVjbGFyYXRpb24gb3IgbnVsbCBpZiBzdWNoIGRlY2xhcmF0aW9uCi0gICAgICogICBkb2VzIG5vdCBleGlzdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFNFbGVtZW50RGVjbGFyYXRpb24gZ2V0RWxlbWVudERlY2xhcmF0aW9uKFN0cmluZyBuYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbmFtZXNwYWNlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbG9jKSB7Ci0gICAgICAgIFNjaGVtYUdyYW1tYXIgc2cgPSAoU2NoZW1hR3JhbW1hcilmR3JhbW1hck1hcC5nZXQobnVsbDJFbXB0eVN0cmluZyhuYW1lc3BhY2UpKTsKLSAgICAgICAgaWYgKHNnID09IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBzZy5nZXRHbG9iYWxFbGVtZW50RGVjbChuYW1lLCBsb2MpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbnZlbmllbmNlIG1ldGhvZC4gUmV0dXJucyBhIHRvcC1sZXZlbCBhdHRyaWJ1dGUgZ3JvdXAgZGVmaW5pdGlvbi4KLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgZGVmaW5pdGlvbi4KLSAgICAgKiBAcGFyYW0gbmFtZXNwYWNlIFRoZSBuYW1lc3BhY2Ugb2YgdGhlIGRlZmluaXRpb24sIG90aGVyd2lzZSBudWxsLgotICAgICAqIEByZXR1cm4gQSB0b3AtbGV2ZWwgYXR0cmlidXRlIGdyb3VwIGRlZmluaXRpb24gb3IgbnVsbCBpZiBzdWNoCi0gICAgICogICBkZWZpbml0aW9uIGRvZXMgbm90IGV4aXN0LgotICAgICAqLwotICAgIHB1YmxpYyBYU0F0dHJpYnV0ZUdyb3VwRGVmaW5pdGlvbiBnZXRBdHRyaWJ1dGVHcm91cChTdHJpbmcgbmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG5hbWVzcGFjZSkgewotICAgICAgICBTY2hlbWFHcmFtbWFyIHNnID0gKFNjaGVtYUdyYW1tYXIpZkdyYW1tYXJNYXAuZ2V0KG51bGwyRW1wdHlTdHJpbmcobmFtZXNwYWNlKSk7Ci0gICAgICAgIGlmIChzZyA9PSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gKFhTQXR0cmlidXRlR3JvdXBEZWZpbml0aW9uKXNnLmZHbG9iYWxBdHRyR3JwRGVjbHMuZ2V0KG5hbWUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbnZlbmllbmNlIG1ldGhvZC4gUmV0dXJucyBhIHRvcC1sZXZlbCBhdHRyaWJ1dGUgZ3JvdXAgZGVmaW5pdGlvbi4KLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgZGVmaW5pdGlvbi4KLSAgICAgKiBAcGFyYW0gbmFtZXNwYWNlIFRoZSBuYW1lc3BhY2Ugb2YgdGhlIGRlZmluaXRpb24sIG90aGVyd2lzZSBudWxsLgotICAgICAqIEBwYXJhbSBsb2MgVGhlIHNjaGVtYSBsb2NhdGlvbiB3aGVyZSB0aGUgY29tcG9uZW50IHdhcyBkZWZpbmVkCi0gICAgICogQHJldHVybiBBIHRvcC1sZXZlbCBhdHRyaWJ1dGUgZ3JvdXAgZGVmaW5pdGlvbiBvciBudWxsIGlmIHN1Y2gKLSAgICAgKiAgIGRlZmluaXRpb24gZG9lcyBub3QgZXhpc3QuCi0gICAgICovCi0gICAgcHVibGljIFhTQXR0cmlidXRlR3JvdXBEZWZpbml0aW9uIGdldEF0dHJpYnV0ZUdyb3VwKFN0cmluZyBuYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbmFtZXNwYWNlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbG9jKSB7Ci0gICAgICAgIFNjaGVtYUdyYW1tYXIgc2cgPSAoU2NoZW1hR3JhbW1hcilmR3JhbW1hck1hcC5nZXQobnVsbDJFbXB0eVN0cmluZyhuYW1lc3BhY2UpKTsKLSAgICAgICAgaWYgKHNnID09IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBzZy5nZXRHbG9iYWxBdHRyaWJ1dGVHcm91cERlY2wobmFtZSwgbG9jKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb252ZW5pZW5jZSBtZXRob2QuIFJldHVybnMgYSB0b3AtbGV2ZWwgbW9kZWwgZ3JvdXAgZGVmaW5pdGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lICAgICAgVGhlIG5hbWUgb2YgdGhlIGRlZmluaXRpb24uCi0gICAgICogQHBhcmFtIG5hbWVzcGFjZSBUaGUgbmFtZXNwYWNlIG9mIHRoZSBkZWZpbml0aW9uLCBvdGhlcndpc2UgbnVsbC4KLSAgICAgKiBAcmV0dXJuIEEgdG9wLWxldmVsIG1vZGVsIGdyb3VwIGRlZmluaXRpb24gZGVmaW5pdGlvbiBvciBudWxsIGlmIHN1Y2gKLSAgICAgKiAgICAgICAgIGRlZmluaXRpb24gZG9lcyBub3QgZXhpc3QuCi0gICAgICovCi0gICAgcHVibGljIFhTTW9kZWxHcm91cERlZmluaXRpb24gZ2V0TW9kZWxHcm91cERlZmluaXRpb24oU3RyaW5nIG5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG5hbWVzcGFjZSkgewotICAgICAgICBTY2hlbWFHcmFtbWFyIHNnID0gKFNjaGVtYUdyYW1tYXIpZkdyYW1tYXJNYXAuZ2V0KG51bGwyRW1wdHlTdHJpbmcobmFtZXNwYWNlKSk7Ci0gICAgICAgIGlmIChzZyA9PSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gKFhTTW9kZWxHcm91cERlZmluaXRpb24pc2cuZkdsb2JhbEdyb3VwRGVjbHMuZ2V0KG5hbWUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbnZlbmllbmNlIG1ldGhvZC4gUmV0dXJucyBhIHRvcC1sZXZlbCBtb2RlbCBncm91cCBkZWZpbml0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgICAgICBUaGUgbmFtZSBvZiB0aGUgZGVmaW5pdGlvbi4KLSAgICAgKiBAcGFyYW0gbmFtZXNwYWNlIFRoZSBuYW1lc3BhY2Ugb2YgdGhlIGRlZmluaXRpb24sIG90aGVyd2lzZSBudWxsLgotICAgICAqIEBwYXJhbSBsb2MgVGhlIHNjaGVtYSBsb2NhdGlvbiB3aGVyZSB0aGUgY29tcG9uZW50IHdhcyBkZWZpbmVkCi0gICAgICogQHJldHVybiBBIHRvcC1sZXZlbCBtb2RlbCBncm91cCBkZWZpbml0aW9uIGRlZmluaXRpb24gb3IgbnVsbCBpZiBzdWNoCi0gICAgICogICAgICAgICBkZWZpbml0aW9uIGRvZXMgbm90IGV4aXN0LgotICAgICAqLwotICAgIHB1YmxpYyBYU01vZGVsR3JvdXBEZWZpbml0aW9uIGdldE1vZGVsR3JvdXBEZWZpbml0aW9uKFN0cmluZyBuYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBuYW1lc3BhY2UsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGxvYykgewotICAgICAgICBTY2hlbWFHcmFtbWFyIHNnID0gKFNjaGVtYUdyYW1tYXIpZkdyYW1tYXJNYXAuZ2V0KG51bGwyRW1wdHlTdHJpbmcobmFtZXNwYWNlKSk7Ci0gICAgICAgIGlmIChzZyA9PSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gc2cuZ2V0R2xvYmFsR3JvdXBEZWNsKG5hbWUsIGxvYyk7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBAc2VlIG9yZy5hcGFjaGUueGVyY2VzLnhzLlhTTW9kZWwjZ2V0Tm90YXRpb25EZWNsYXJhdGlvbihTdHJpbmcsIFN0cmluZykKLSAgICAgKi8KLSAgICBwdWJsaWMgWFNOb3RhdGlvbkRlY2xhcmF0aW9uIGdldE5vdGF0aW9uRGVjbGFyYXRpb24oU3RyaW5nIG5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG5hbWVzcGFjZSkgewotICAgICAgICBTY2hlbWFHcmFtbWFyIHNnID0gKFNjaGVtYUdyYW1tYXIpZkdyYW1tYXJNYXAuZ2V0KG51bGwyRW1wdHlTdHJpbmcobmFtZXNwYWNlKSk7Ci0gICAgICAgIGlmIChzZyA9PSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gKFhTTm90YXRpb25EZWNsYXJhdGlvbilzZy5mR2xvYmFsTm90YXRpb25EZWNscy5nZXQobmFtZSk7Ci0gICAgfQotCi0gICAgcHVibGljIFhTTm90YXRpb25EZWNsYXJhdGlvbiBnZXROb3RhdGlvbkRlY2xhcmF0aW9uKFN0cmluZyBuYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBuYW1lc3BhY2UsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGxvYykgewotICAgICAgICBTY2hlbWFHcmFtbWFyIHNnID0gKFNjaGVtYUdyYW1tYXIpZkdyYW1tYXJNYXAuZ2V0KG51bGwyRW1wdHlTdHJpbmcobmFtZXNwYWNlKSk7Ci0gICAgICAgIGlmIChzZyA9PSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gc2cuZ2V0R2xvYmFsTm90YXRpb25EZWNsKG5hbWUsIGxvYyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogIFthbm5vdGF0aW9uc106IGEgc2V0IG9mIGFubm90YXRpb25zIGlmIGl0IGV4aXN0cywgb3RoZXJ3aXNlIGFuIGVtcHR5Ci0gICAgICogPGNvZGU+WFNPYmplY3RMaXN0PC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3luY2hyb25pemVkIFhTT2JqZWN0TGlzdCBnZXRBbm5vdGF0aW9ucygpIHsKLSAgICAgICAgaWYgKGZBbm5vdGF0aW9ucyAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gZkFubm90YXRpb25zOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gZG8gdGhpcyBpbiB0d28gcGFzc2VzIHRvIGF2b2lkIGluYWNjdXJhdGUgYXJyYXkgc2l6ZQotICAgICAgICBpbnQgdG90YWxBbm5vdGF0aW9ucyA9IDA7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZkdyYW1tYXJDb3VudDsgaSsrKSB7Ci0gICAgICAgICAgICB0b3RhbEFubm90YXRpb25zICs9IGZHcmFtbWFyTGlzdFtpXS5mTnVtQW5ub3RhdGlvbnM7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKHRvdGFsQW5ub3RhdGlvbnMgPT0gMCkgewotICAgICAgICAgICAgZkFubm90YXRpb25zID0gWFNPYmplY3RMaXN0SW1wbC5FTVBUWV9MSVNUOwotICAgICAgICAgICAgcmV0dXJuIGZBbm5vdGF0aW9uczsKLSAgICAgICAgfQotICAgICAgICBYU0Fubm90YXRpb25JbXBsIFtdIGFubm90YXRpb25zID0gbmV3IFhTQW5ub3RhdGlvbkltcGwgW3RvdGFsQW5ub3RhdGlvbnNdOwotICAgICAgICBpbnQgY3VyclBvcyA9IDA7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZkdyYW1tYXJDb3VudDsgaSsrKSB7Ci0gICAgICAgICAgICBTY2hlbWFHcmFtbWFyIGN1cnJHcmFtbWFyID0gZkdyYW1tYXJMaXN0W2ldOwotICAgICAgICAgICAgaWYgKGN1cnJHcmFtbWFyLmZOdW1Bbm5vdGF0aW9ucyA+IDApIHsKLSAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGN1cnJHcmFtbWFyLmZBbm5vdGF0aW9ucywgMCwgYW5ub3RhdGlvbnMsIGN1cnJQb3MsIGN1cnJHcmFtbWFyLmZOdW1Bbm5vdGF0aW9ucyk7Ci0gICAgICAgICAgICAgICAgY3VyclBvcyArPSBjdXJyR3JhbW1hci5mTnVtQW5ub3RhdGlvbnM7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZkFubm90YXRpb25zID0gbmV3IFhTT2JqZWN0TGlzdEltcGwoYW5ub3RhdGlvbnMsIGFubm90YXRpb25zLmxlbmd0aCk7Ci0gICAgICAgIHJldHVybiBmQW5ub3RhdGlvbnM7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIG51bGwyRW1wdHlTdHJpbmcoU3RyaW5nIHN0cikgewotICAgICAgICByZXR1cm4gc3RyID09IG51bGwgPyBYTUxTeW1ib2xzLkVNUFRZX1NUUklORyA6IHN0cjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSRVZJU0lUOiB0byBleHBvc2UgaWRlbnRpdHkgY29uc3RyYWludHMgZnJvbSBYU01vZGVsLgotICAgICAqIEZvciBub3csIHdlIG9ubHkgZXhwb3NlIHdoZXRoZXIgdGhlcmUgYXJlIGFueSBJRENzLgotICAgICAqIFdlIGFsc28gbmVlZCB0byBhZGQgdGhlc2UgbWV0aG9kcyB0byB0aGUgcHVibGljCi0gICAgICogWFNNb2RlbCBpbnRlcmZhY2UuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaGFzSURDb25zdHJhaW50cygpIHsKLSAgICAgICAgcmV0dXJuIGZIYXNJREM7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29udmVuaWVuY2UgbWV0aG9kLiBSZXR1cm5zIGEgbGlzdCBjb250YWluaW5nIHRoZSBtZW1iZXJzIG9mIHRoZQotICAgICAqIHN1YnN0aXR1dGlvbiBncm91cCBmb3IgdGhlIGdpdmVuIDxjb2RlPlhTRWxlbWVudERlY2xhcmF0aW9uPC9jb2RlPgotICAgICAqIG9yIGFuIGVtcHR5IDxjb2RlPlhTT2JqZWN0TGlzdDwvY29kZT4gaWYgdGhlIHN1YnN0aXR1dGlvbiBncm91cAotICAgICAqIGNvbnRhaW5zIG5vIG1lbWJlcnMuCi0gICAgICogQHBhcmFtIGhlYWQgVGhlIHN1YnN0aXR1dGlvbiBncm91cCBoZWFkLgotICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIG1lbWJlcnMgb2YgdGhlIHN1YnN0aXR1dGlvbiBncm91cAotICAgICAqICBmb3IgdGhlIGdpdmVuIDxjb2RlPlhTRWxlbWVudERlY2xhcmF0aW9uPC9jb2RlPiBvciBhbiBlbXB0eQotICAgICAqICA8Y29kZT5YU09iamVjdExpc3Q8L2NvZGU+IGlmIHRoZSBzdWJzdGl0dXRpb24gZ3JvdXAgY29udGFpbnMKLSAgICAgKiAgbm8gbWVtYmVycy4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFNPYmplY3RMaXN0IGdldFN1YnN0aXR1dGlvbkdyb3VwKFhTRWxlbWVudERlY2xhcmF0aW9uIGhlYWQpIHsKLSAgICAgICAgcmV0dXJuIChYU09iamVjdExpc3QpZlN1Ykdyb3VwTWFwLmdldChoZWFkKTsKLSAgICB9Ci0KLSAgICAvLwotICAgIC8vIFhTTmFtZXNwYWNlSXRlbUxpc3QgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBUaGUgbnVtYmVyIG9mIDxjb2RlPlhTTmFtZXNwYWNlSXRlbTwvY29kZT5zIGluIHRoZSBsaXN0LiBUaGUgcmFuZ2Ugb2YKLSAgICAgKiB2YWxpZCBjaGlsZCBvYmplY3QgaW5kaWNlcyBpcyAwIHRvIDxjb2RlPmxlbmd0aC0xPC9jb2RlPiBpbmNsdXNpdmUuCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRMZW5ndGgoKSB7Ci0gICAgICAgIHJldHVybiBmR3JhbW1hckNvdW50OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIDxjb2RlPmluZGV4PC9jb2RlPnRoIGl0ZW0gaW4gdGhlIGNvbGxlY3Rpb24gb3IKLSAgICAgKiA8Y29kZT5udWxsPC9jb2RlPiBpZiA8Y29kZT5pbmRleDwvY29kZT4gaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvCi0gICAgICogdGhlIG51bWJlciBvZiBvYmplY3RzIGluIHRoZSBsaXN0LiBUaGUgaW5kZXggc3RhcnRzIGF0IDAuCi0gICAgICogQHBhcmFtIGluZGV4ICBpbmRleCBpbnRvIHRoZSBjb2xsZWN0aW9uLgotICAgICAqIEByZXR1cm4gIFRoZSA8Y29kZT5YU05hbWVzcGFjZUl0ZW08L2NvZGU+IGF0IHRoZSA8Y29kZT5pbmRleDwvY29kZT50aAotICAgICAqICAgcG9zaXRpb24gaW4gdGhlIDxjb2RlPlhTTmFtZXNwYWNlSXRlbUxpc3Q8L2NvZGU+LCBvcgotICAgICAqICAgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlIGluZGV4IHNwZWNpZmllZCBpcyBub3QgdmFsaWQuCi0gICAgICovCi0gICAgcHVibGljIFhTTmFtZXNwYWNlSXRlbSBpdGVtKGludCBpbmRleCkgewotICAgICAgICBpZiAoaW5kZXggPCAwIHx8IGluZGV4ID49IGZHcmFtbWFyQ291bnQpIHsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmR3JhbW1hckxpc3RbaW5kZXhdOwotICAgIH0KLQotICAgIC8vCi0gICAgLy8gamF2YS51dGlsLkxpc3QgbWV0aG9kcwotICAgIC8vCi0KLSAgICBwdWJsaWMgT2JqZWN0IGdldChpbnQgaW5kZXgpIHsKLSAgICAgICAgaWYgKGluZGV4ID49IDAgJiYgaW5kZXggPCBmR3JhbW1hckNvdW50KSB7Ci0gICAgICAgICAgICByZXR1cm4gZkdyYW1tYXJMaXN0W2luZGV4XTsKLSAgICAgICAgfQotICAgICAgICB0aHJvdyBuZXcgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigiSW5kZXg6ICIgKyBpbmRleCk7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBzaXplKCkgewotICAgICAgICByZXR1cm4gZ2V0TGVuZ3RoKCk7Ci0gICAgfQotCi0gICAgcHVibGljIEl0ZXJhdG9yIGl0ZXJhdG9yKCkgewotICAgICAgICByZXR1cm4gbGlzdEl0ZXJhdG9yMCgwKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgTGlzdEl0ZXJhdG9yIGxpc3RJdGVyYXRvcigpIHsKLSAgICAgICAgcmV0dXJuIGxpc3RJdGVyYXRvcjAoMCk7Ci0gICAgfQotCi0gICAgcHVibGljIExpc3RJdGVyYXRvciBsaXN0SXRlcmF0b3IoaW50IGluZGV4KSB7Ci0gICAgICAgIGlmIChpbmRleCA+PSAwICYmIGluZGV4IDwgZkdyYW1tYXJDb3VudCkgewotICAgICAgICAgICAgcmV0dXJuIGxpc3RJdGVyYXRvcjAoaW5kZXgpOwotICAgICAgICB9Ci0gICAgICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCJJbmRleDogIiArIGluZGV4KTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIExpc3RJdGVyYXRvciBsaXN0SXRlcmF0b3IwKGludCBpbmRleCkgewotICAgICAgICByZXR1cm4gbmV3IFhTTmFtZXNwYWNlSXRlbUxpc3RJdGVyYXRvcihpbmRleCk7Ci0gICAgfQotCi0gICAgcHVibGljIE9iamVjdFtdIHRvQXJyYXkoKSB7Ci0gICAgICAgIE9iamVjdFtdIGEgPSBuZXcgT2JqZWN0W2ZHcmFtbWFyQ291bnRdOwotICAgICAgICB0b0FycmF5MChhKTsKLSAgICAgICAgcmV0dXJuIGE7Ci0gICAgfQotCi0gICAgcHVibGljIE9iamVjdFtdIHRvQXJyYXkoT2JqZWN0W10gYSkgewotICAgICAgICBpZiAoYS5sZW5ndGggPCBmR3JhbW1hckNvdW50KSB7Ci0gICAgICAgICAgICBDbGFzcyBhcnJheUNsYXNzID0gYS5nZXRDbGFzcygpOwotICAgICAgICAgICAgQ2xhc3MgY29tcG9uZW50VHlwZSA9IGFycmF5Q2xhc3MuZ2V0Q29tcG9uZW50VHlwZSgpOwotICAgICAgICAgICAgYSA9IChPYmplY3RbXSkgQXJyYXkubmV3SW5zdGFuY2UoY29tcG9uZW50VHlwZSwgZkdyYW1tYXJDb3VudCk7Ci0gICAgICAgIH0KLSAgICAgICAgdG9BcnJheTAoYSk7Ci0gICAgICAgIGlmIChhLmxlbmd0aCA+IGZHcmFtbWFyQ291bnQpIHsKLSAgICAgICAgICAgIGFbZkdyYW1tYXJDb3VudF0gPSBudWxsOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBhOwotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCB0b0FycmF5MChPYmplY3RbXSBhKSB7Ci0gICAgICAgIGlmIChmR3JhbW1hckNvdW50ID4gMCkgewotICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShmR3JhbW1hckxpc3QsIDAsIGEsIDAsIGZHcmFtbWFyQ291bnQpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBmaW5hbCBjbGFzcyBYU05hbWVzcGFjZUl0ZW1MaXN0SXRlcmF0b3IgaW1wbGVtZW50cyBMaXN0SXRlcmF0b3IgewotICAgICAgICBwcml2YXRlIGludCBpbmRleDsKLSAgICAgICAgcHVibGljIFhTTmFtZXNwYWNlSXRlbUxpc3RJdGVyYXRvcihpbnQgaW5kZXgpIHsKLSAgICAgICAgICAgIHRoaXMuaW5kZXggPSBpbmRleDsKLSAgICAgICAgfQotICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNOZXh0KCkgewotICAgICAgICAgICAgcmV0dXJuIChpbmRleCA8IGZHcmFtbWFyQ291bnQpOwotICAgICAgICB9Ci0gICAgICAgIHB1YmxpYyBPYmplY3QgbmV4dCgpIHsKLSAgICAgICAgICAgIGlmIChpbmRleCA8IGZHcmFtbWFyQ291bnQpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZkdyYW1tYXJMaXN0W2luZGV4KytdOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oKTsKLSAgICAgICAgfQotICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNQcmV2aW91cygpIHsKLSAgICAgICAgICAgIHJldHVybiAoaW5kZXggPiAwKTsKLSAgICAgICAgfQotICAgICAgICBwdWJsaWMgT2JqZWN0IHByZXZpb3VzKCkgewotICAgICAgICAgICAgaWYgKGluZGV4ID4gMCkgewotICAgICAgICAgICAgICAgIHJldHVybiBmR3JhbW1hckxpc3RbLS1pbmRleF07Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbigpOwotICAgICAgICB9Ci0gICAgICAgIHB1YmxpYyBpbnQgbmV4dEluZGV4KCkgewotICAgICAgICAgICAgcmV0dXJuIGluZGV4OwotICAgICAgICB9Ci0gICAgICAgIHB1YmxpYyBpbnQgcHJldmlvdXNJbmRleCgpIHsKLSAgICAgICAgICAgIHJldHVybiBpbmRleCAtIDE7Ci0gICAgICAgIH0KLSAgICAgICAgcHVibGljIHZvaWQgcmVtb3ZlKCkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7Ci0gICAgICAgIH0KLSAgICAgICAgcHVibGljIHZvaWQgc2V0KE9iamVjdCBvKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKLSAgICAgICAgfQotICAgICAgICBwdWJsaWMgdm9pZCBhZGQoT2JqZWN0IG8pIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOwotICAgICAgICB9Ci0gICAgfQotCi19IC8vIGNsYXNzIFhTTW9kZWxJbXBsCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL1hTTm90YXRpb25EZWNsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL1hTTm90YXRpb25EZWNsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDk0NTA1ZjkuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9YU05vdGF0aW9uRGVjbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTIxICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLnV0aWwuWFNPYmplY3RMaXN0SW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTQW5ub3RhdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNOYW1lc3BhY2VJdGVtOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNOb3RhdGlvbkRlY2xhcmF0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNPYmplY3RMaXN0OwotCi0vKioKLSAqIFRoZSBYTUwgcmVwcmVzZW50YXRpb24gZm9yIGEgTk9UQVRJT04gZGVjbGFyYXRpb24KLSAqIHNjaGVtYSBjb21wb25lbnQgaXMgYSBnbG9iYWwgPG5vdGF0aW9uPiBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBSYWh1bCBTcml2YXN0YXZhLCBTdW4gTWljcm9zeXN0ZW1zIEluYy4KLSAqIEB2ZXJzaW9uICRJZDogWFNOb3RhdGlvbkRlY2wuamF2YSx2IDEuNyAyMDEwLTExLTAxIDA0OjM5OjU1IGpvZWh3IEV4cCAkCi0gKi8KLXB1YmxpYyBjbGFzcyBYU05vdGF0aW9uRGVjbCBpbXBsZW1lbnRzIFhTTm90YXRpb25EZWNsYXJhdGlvbiB7Ci0KLSAgICAvLyBuYW1lIG9mIHRoZSBncm91cAotICAgIHB1YmxpYyBTdHJpbmcgZk5hbWUgPSBudWxsOwotICAgIC8vIHRhcmdldCBuYW1lc3BhY2Ugb2YgdGhlIGdyb3VwCi0gICAgcHVibGljIFN0cmluZyBmVGFyZ2V0TmFtZXNwYWNlID0gbnVsbDsKLSAgICAvLyBwdWJsaWMgaWQgb2YgdGhlIG5vdGF0aW9uCi0gICAgcHVibGljIFN0cmluZyBmUHVibGljSWQgPSBudWxsOwotICAgIC8vIHN5c3RlbSBpZCBvZiB0aGUgbm90YXRpb24KLSAgICBwdWJsaWMgU3RyaW5nIGZTeXN0ZW1JZCA9IG51bGw7Ci0KLSAgICAvLyBvcHRpb25hbCBhbm5vdGF0aW9uCi0gICAgcHVibGljIFhTT2JqZWN0TGlzdCBmQW5ub3RhdGlvbnMgPSBudWxsOwotCi0gICAgLy8gVGhlIG5hbWVzcGFjZSBzY2hlbWEgaW5mb3JtYXRpb24gaXRlbSBjb3JyZXNwb25kaW5nIHRvIHRoZSB0YXJnZXQgbmFtZXNwYWNlCi0gICAgLy8gb2YgdGhlIG5vdGF0aW9uIGRlY2xhcmF0aW9uLCBpZiBpdCBpcyBnbG9iYWxseSBkZWNsYXJlZDsgb3IgbnVsbCBvdGhlcndpc2UuCi0gICAgcHJpdmF0ZSBYU05hbWVzcGFjZUl0ZW0gZk5hbWVzcGFjZUl0ZW0gPSBudWxsOwotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSB0eXBlIG9mIHRoZSBvYmplY3QsIGkuZSBFTEVNRU5UX0RFQ0xBUkFUSU9OLgotICAgICAqLwotICAgIHB1YmxpYyBzaG9ydCBnZXRUeXBlKCkgewotICAgICAgICByZXR1cm4gWFNDb25zdGFudHMuTk9UQVRJT05fREVDTEFSQVRJT047Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhlIDxjb2RlPm5hbWU8L2NvZGU+IG9mIHRoaXMgPGNvZGU+WFNPYmplY3Q8L2NvZGU+IGRlcGVuZGluZyBvbiB0aGUKLSAgICAgKiA8Y29kZT5YU09iamVjdDwvY29kZT4gdHlwZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKSB7Ci0gICAgICAgIHJldHVybiBmTmFtZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgbmFtZXNwYWNlIFVSSSBvZiB0aGlzIG5vZGUsIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIGl0IGlzCi0gICAgICogdW5zcGVjaWZpZWQuICBkZWZpbmVzIGhvdyBhIG5hbWVzcGFjZSBVUkkgaXMgYXR0YWNoZWQgdG8gc2NoZW1hCi0gICAgICogY29tcG9uZW50cy4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWVzcGFjZSgpIHsKLSAgICAgICAgcmV0dXJuIGZUYXJnZXROYW1lc3BhY2U7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogT3B0aW9uYWwgaWYge3B1YmxpYyBpZGVudGlmaWVyfSBpcyBwcmVzZW50LiBBIFVSSSByZWZlcmVuY2UuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRTeXN0ZW1JZCgpIHsKLSAgICAgICAgcmV0dXJuIGZTeXN0ZW1JZDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBPcHRpb25hbCBpZiB7c3lzdGVtIGlkZW50aWZpZXJ9IGlzIHByZXNlbnQuIEEgcHVibGljIGlkZW50aWZpZXIsCi0gICAgICogYXMgZGVmaW5lZCBpbiBbWE1MIDEuMCAoU2Vjb25kIEVkaXRpb24pXS4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFB1YmxpY0lkKCkgewotICAgICAgICByZXR1cm4gZlB1YmxpY0lkOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIE9wdGlvbmFsLiBBbm5vdGF0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBYU0Fubm90YXRpb24gZ2V0QW5ub3RhdGlvbigpIHsKLSAgICAgICAgcmV0dXJuIChmQW5ub3RhdGlvbnMgIT0gbnVsbCkgPyAoWFNBbm5vdGF0aW9uKSBmQW5ub3RhdGlvbnMuaXRlbSgwKSA6IG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogT3B0aW9uYWwuIEFubm90YXRpb25zLgotICAgICAqLwotICAgIHB1YmxpYyBYU09iamVjdExpc3QgZ2V0QW5ub3RhdGlvbnMoKSB7Ci0gICAgICAgIHJldHVybiAoZkFubm90YXRpb25zICE9IG51bGwpID8gZkFubm90YXRpb25zIDogWFNPYmplY3RMaXN0SW1wbC5FTVBUWV9MSVNUOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgb3JnLmFwYWNoZS54ZXJjZXMueHMuWFNPYmplY3QjZ2V0TmFtZXNwYWNlSXRlbSgpCi0gICAgICovCi0gICAgcHVibGljIFhTTmFtZXNwYWNlSXRlbSBnZXROYW1lc3BhY2VJdGVtKCkgewotICAgICAgICByZXR1cm4gZk5hbWVzcGFjZUl0ZW07Ci0gICAgfQotCi0gICAgdm9pZCBzZXROYW1lc3BhY2VJdGVtKFhTTmFtZXNwYWNlSXRlbSBuYW1lc3BhY2VJdGVtKSB7Ci0gICAgICAgIGZOYW1lc3BhY2VJdGVtID0gbmFtZXNwYWNlSXRlbTsKLSAgICB9Ci0KLX0gLy8gY2xhc3MgWFNOb3RhdGlvbkRlY2wKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvWFNQYXJ0aWNsZURlY2wuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvWFNQYXJ0aWNsZURlY2wuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNDY4ZjY1Mi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL1hTUGFydGljbGVEZWNsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyNDggKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMSwgMjAwMiwyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMudXRpbC5YU09iamVjdExpc3RJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNDb25zdGFudHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU05hbWVzcGFjZUl0ZW07Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU09iamVjdExpc3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU1BhcnRpY2xlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNUZXJtOwotCi0vKioKLSAqIFN0b3JlIHNjaGVtYSBwYXJ0aWNsZSBkZWNsYXJhdGlvbi4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBTYW5keSBHYW8sIElCTQotICoKLSAqIEB2ZXJzaW9uICRJZDogWFNQYXJ0aWNsZURlY2wuamF2YSx2IDEuNyAyMDEwLTExLTAxIDA0OjM5OjU1IGpvZWh3IEV4cCAkCi0gKi8KLXB1YmxpYyBjbGFzcyBYU1BhcnRpY2xlRGVjbCBpbXBsZW1lbnRzIFhTUGFydGljbGUgewotCi0gICAgLy8gdHlwZXMgb2YgcGFydGljbGVzCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBQQVJUSUNMRV9FTVBUWSAgICAgICAgPSAwOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgUEFSVElDTEVfRUxFTUVOVCAgICAgID0gMTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFBBUlRJQ0xFX1dJTERDQVJEICAgICA9IDI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBQQVJUSUNMRV9NT0RFTEdST1VQICAgPSAzOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgUEFSVElDTEVfWkVST19PUl9NT1JFID0gNDsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFBBUlRJQ0xFX1pFUk9fT1JfT05FICA9IDU7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBQQVJUSUNMRV9PTkVfT1JfTU9SRSAgPSA2OwotCi0gICAgLy8gdHlwZSBvZiB0aGUgcGFydGljbGUKLSAgICBwdWJsaWMgc2hvcnQgZlR5cGUgPSBQQVJUSUNMRV9FTVBUWTsKLQotICAgIC8vIHRlcm0gb2YgdGhlIHBhcnRpY2xlCi0gICAgLy8gZm9yIFBBUlRJQ0xFX0VMRU1FTlQgOiB0aGUgZWxlbWVudCBkZWNsCi0gICAgLy8gZm9yIFBBUlRJQ0xFX1dJTERDQVJEOiB0aGUgd2lsZGNhcmQgZGVjbAotICAgIC8vIGZvciBQQVJUSUNMRV9NT0RFTEdST1VQOiB0aGUgbW9kZWwgZ3JvdXAKLSAgICBwdWJsaWMgWFNUZXJtIGZWYWx1ZSA9IG51bGw7Ci0KLSAgICAvLyBtaW5pbXVtIG9jY3VycmVuY2Ugb2YgdGhpcyBwYXJ0aWNsZQotICAgIHB1YmxpYyBpbnQgZk1pbk9jY3VycyA9IDE7Ci0gICAgLy8gbWF4aW11bSBvY2N1cnJlbmNlIG9mIHRoaXMgcGFydGljbGUKLSAgICBwdWJsaWMgaW50IGZNYXhPY2N1cnMgPSAxOwotICAgIC8vIG9wdGlvbmFsIGFubm90YXRpb24KLSAgICBwdWJsaWMgWFNPYmplY3RMaXN0IGZBbm5vdGF0aW9ucyA9IG51bGw7Ci0KLSAgICAvLyBjbG9uZSB0aGlzIGRlY2wKLSAgICBwdWJsaWMgWFNQYXJ0aWNsZURlY2wgbWFrZUNsb25lKCkgewotICAgICAgICBYU1BhcnRpY2xlRGVjbCBwYXJ0aWNsZSA9IG5ldyBYU1BhcnRpY2xlRGVjbCgpOwotICAgICAgICBwYXJ0aWNsZS5mVHlwZSA9IGZUeXBlOwotICAgICAgICBwYXJ0aWNsZS5mTWluT2NjdXJzID0gZk1pbk9jY3VyczsKLSAgICAgICAgcGFydGljbGUuZk1heE9jY3VycyA9IGZNYXhPY2N1cnM7Ci0gICAgICAgIHBhcnRpY2xlLmZEZXNjcmlwdGlvbiA9IGZEZXNjcmlwdGlvbjsKLSAgICAgICAgcGFydGljbGUuZlZhbHVlID0gZlZhbHVlOwotICAgICAgICBwYXJ0aWNsZS5mQW5ub3RhdGlvbnMgPSBmQW5ub3RhdGlvbnM7Ci0gICAgICAgIHJldHVybiBwYXJ0aWNsZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiAzLjkuNiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6IFBhcnRpY2xlIEVtcHRpYWJsZQotICAgICAqIHdoZXRoZXIgdGhpcyBwYXJ0aWNsZSBpcyBlbXB0aWJsZQotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGVtcHRpYWJsZSgpIHsKLSAgICAgICAgcmV0dXJuIG1pbkVmZmVjdGl2ZVRvdGFsUmFuZ2UoKSA9PSAwOwotICAgIH0KLQotICAgIC8vIHdoZXRoZXIgdGhpcyBwYXJ0aWNsZSBjb250YWlucyBub3RoaW5nCi0gICAgcHVibGljIGJvb2xlYW4gaXNFbXB0eSgpIHsKLSAgICAgICAgaWYgKGZUeXBlID09IFBBUlRJQ0xFX0VNUFRZKQotICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICBpZiAoZlR5cGUgPT0gUEFSVElDTEVfRUxFTUVOVCB8fCBmVHlwZSA9PSBQQVJUSUNMRV9XSUxEQ0FSRCkKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLQotICAgICAgICByZXR1cm4gKChYU01vZGVsR3JvdXBJbXBsKWZWYWx1ZSkuaXNFbXB0eSgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIDMuOC42IEVmZmVjdGl2ZSBUb3RhbCBSYW5nZSAoYWxsIGFuZCBzZXF1ZW5jZSkgYW5kCi0gICAgICogICAgICAgRWZmZWN0aXZlIFRvdGFsIFJhbmdlIChjaG9pY2UpCi0gICAgICogVGhlIGZvbGxvd2luZyBtZXRob2RzIGFyZSB1c2VkIHRvIHJldHVybiBtaW4vbWF4IHJhbmdlIGZvciBhIHBhcnRpY2xlLgotICAgICAqIFRoZXkgYXJlIG5vdCBleGFjdGx5IHRoZSBzYW1lIGFzIGl0J3MgZGVzY3JpYmVkIGluIHRoZSBzcGVjLCBidXQgYWxsIHRoZQotICAgICAqIHZhbHVlcyBmcm9tIHRoZSBzcGVjIGFyZSByZXRyaWV2YWJsZSBieSB0aGVzZSBtZXRob2RzLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgbWluRWZmZWN0aXZlVG90YWxSYW5nZSgpIHsKLSAgICAgICAgaWYgKGZUeXBlID09IFhTUGFydGljbGVEZWNsLlBBUlRJQ0xFX0VNUFRZKSB7Ci0gICAgICAgICAgICByZXR1cm4gMDsKLSAgICAgICAgfQotICAgICAgICBpZiAoZlR5cGUgPT0gUEFSVElDTEVfTU9ERUxHUk9VUCkgewotICAgICAgICAgICAgcmV0dXJuICgoWFNNb2RlbEdyb3VwSW1wbClmVmFsdWUpLm1pbkVmZmVjdGl2ZVRvdGFsUmFuZ2UoKSAqIGZNaW5PY2N1cnM7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGZNaW5PY2N1cnM7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBtYXhFZmZlY3RpdmVUb3RhbFJhbmdlKCkgewotICAgICAgICBpZiAoZlR5cGUgPT0gWFNQYXJ0aWNsZURlY2wuUEFSVElDTEVfRU1QVFkpIHsKLSAgICAgICAgICAgIHJldHVybiAwOwotICAgICAgICB9Ci0gICAgICAgIGlmIChmVHlwZSA9PSBQQVJUSUNMRV9NT0RFTEdST1VQKSB7Ci0gICAgICAgICAgICBpbnQgbWF4ID0gKChYU01vZGVsR3JvdXBJbXBsKWZWYWx1ZSkubWF4RWZmZWN0aXZlVG90YWxSYW5nZSgpOwotICAgICAgICAgICAgaWYgKG1heCA9PSBTY2hlbWFTeW1ib2xzLk9DQ1VSUkVOQ0VfVU5CT1VOREVEKQotICAgICAgICAgICAgICAgIHJldHVybiBTY2hlbWFTeW1ib2xzLk9DQ1VSUkVOQ0VfVU5CT1VOREVEOwotICAgICAgICAgICAgaWYgKG1heCAhPSAwICYmIGZNYXhPY2N1cnMgPT0gU2NoZW1hU3ltYm9scy5PQ0NVUlJFTkNFX1VOQk9VTkRFRCkKLSAgICAgICAgICAgICAgICByZXR1cm4gU2NoZW1hU3ltYm9scy5PQ0NVUlJFTkNFX1VOQk9VTkRFRDsKLSAgICAgICAgICAgIHJldHVybiBtYXggKiBmTWF4T2NjdXJzOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmTWF4T2NjdXJzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIGdldCB0aGUgc3RyaW5nIGRlc2NyaXB0aW9uIG9mIHRoaXMgcGFydGljbGUKLSAgICAgKi8KLSAgICBwcml2YXRlIFN0cmluZyBmRGVzY3JpcHRpb24gPSBudWxsOwotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0gICAgICAgIGlmIChmRGVzY3JpcHRpb24gPT0gbnVsbCkgewotICAgICAgICAgICAgU3RyaW5nQnVmZmVyIGJ1ZmZlciA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLSAgICAgICAgICAgIGFwcGVuZFBhcnRpY2xlKGJ1ZmZlcik7Ci0gICAgICAgICAgICBpZiAoIShmTWluT2NjdXJzID09IDAgJiYgZk1heE9jY3VycyA9PSAwIHx8Ci0gICAgICAgICAgICAgICAgICBmTWluT2NjdXJzID09IDEgJiYgZk1heE9jY3VycyA9PSAxKSkgewotICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoJ3snKS5hcHBlbmQoZk1pbk9jY3Vycyk7Ci0gICAgICAgICAgICAgICAgaWYgKGZNYXhPY2N1cnMgPT0gU2NoZW1hU3ltYm9scy5PQ0NVUlJFTkNFX1VOQk9VTkRFRCkKLSAgICAgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgiLVVOQk9VTkRFRCIpOwotICAgICAgICAgICAgICAgIGVsc2UgaWYgKGZNaW5PY2N1cnMgIT0gZk1heE9jY3VycykKLSAgICAgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgnLScpLmFwcGVuZChmTWF4T2NjdXJzKTsKLSAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCd9Jyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmRGVzY3JpcHRpb24gPSBidWZmZXIudG9TdHJpbmcoKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZkRlc2NyaXB0aW9uOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIGFwcGVuZCB0aGUgc3RyaW5nIGRlc2NyaXB0aW9uIG9mIHRoaXMgcGFydGljbGUgdG8gdGhlIHN0cmluZyBidWZmZXIKLSAgICAgKiB0aGlzIGlzIGZvciBlcnJvciBtZXNzYWdlLgotICAgICAqLwotICAgIHZvaWQgYXBwZW5kUGFydGljbGUoU3RyaW5nQnVmZmVyIGJ1ZmZlcikgewotICAgICAgICBzd2l0Y2ggKGZUeXBlKSB7Ci0gICAgICAgIGNhc2UgUEFSVElDTEVfRU1QVFk6Ci0gICAgICAgICAgICBidWZmZXIuYXBwZW5kKCJFTVBUWSIpOwotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgUEFSVElDTEVfRUxFTUVOVDoKLSAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoZlZhbHVlLnRvU3RyaW5nKCkpOwotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgUEFSVElDTEVfV0lMRENBUkQ6Ci0gICAgICAgICAgICBidWZmZXIuYXBwZW5kKCcoJyk7Ci0gICAgICAgICAgICBidWZmZXIuYXBwZW5kKGZWYWx1ZS50b1N0cmluZygpKTsKLSAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoJyknKTsKLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICBjYXNlIFBBUlRJQ0xFX01PREVMR1JPVVA6Ci0gICAgICAgICAgICBidWZmZXIuYXBwZW5kKGZWYWx1ZS50b1N0cmluZygpKTsKLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgcmVzZXQoKXsKLSAgICAgICAgZlR5cGUgPSBQQVJUSUNMRV9FTVBUWTsKLSAgICAgICAgZlZhbHVlID0gbnVsbDsKLSAgICAgICAgZk1pbk9jY3VycyA9IDE7Ci0gICAgICAgIGZNYXhPY2N1cnMgPSAxOwotICAgICAgICBmRGVzY3JpcHRpb24gPSBudWxsOwotICAgICAgICBmQW5ub3RhdGlvbnMgPSBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgdHlwZSBvZiB0aGUgb2JqZWN0LCBpLmUgRUxFTUVOVF9ERUNMQVJBVElPTi4KLSAgICAgKi8KLSAgICBwdWJsaWMgc2hvcnQgZ2V0VHlwZSgpIHsKLSAgICAgICAgcmV0dXJuIFhTQ29uc3RhbnRzLlBBUlRJQ0xFOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoZSA8Y29kZT5uYW1lPC9jb2RlPiBvZiB0aGlzIDxjb2RlPlhTT2JqZWN0PC9jb2RlPiBkZXBlbmRpbmcgb24gdGhlCi0gICAgICogPGNvZGU+WFNPYmplY3Q8L2NvZGU+IHR5cGUuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXROYW1lKCkgewotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgbmFtZXNwYWNlIFVSSSBvZiB0aGlzIG5vZGUsIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIGl0IGlzCi0gICAgICogdW5zcGVjaWZpZWQuICBkZWZpbmVzIGhvdyBhIG5hbWVzcGFjZSBVUkkgaXMgYXR0YWNoZWQgdG8gc2NoZW1hCi0gICAgICogY29tcG9uZW50cy4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWVzcGFjZSgpIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICoge21pbiBvY2N1cnN9IGRldGVybWluZXMgdGhlIG1pbmltdW0gbnVtYmVyIG9mIHRlcm1zIHRoYXQgY2FuIG9jY3VyLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0TWluT2NjdXJzKCkgewotICAgICAgICByZXR1cm4gZk1pbk9jY3VyczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiB7bWF4IG9jY3Vyc30gd2hldGhlciB0aGUgbWF4T2NjdXJzIHZhbHVlIGlzIHVuYm91bmRlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXRNYXhPY2N1cnNVbmJvdW5kZWQoKSB7Ci0gICAgICAgIHJldHVybiBmTWF4T2NjdXJzID09IFNjaGVtYVN5bWJvbHMuT0NDVVJSRU5DRV9VTkJPVU5ERUQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICoge21heCBvY2N1cnN9IGRldGVybWluZXMgdGhlIG1heGltdW0gbnVtYmVyIG9mIHRlcm1zIHRoYXQgY2FuIG9jY3VyLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0TWF4T2NjdXJzKCkgewotICAgICAgICByZXR1cm4gZk1heE9jY3VyczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiB7dGVybX0gT25lIG9mIGEgbW9kZWwgZ3JvdXAsIGEgd2lsZGNhcmQsIG9yIGFuIGVsZW1lbnQgZGVjbGFyYXRpb24uCi0gICAgICovCi0gICAgcHVibGljIFhTVGVybSBnZXRUZXJtKCkgewotICAgICAgICByZXR1cm4gZlZhbHVlOwotICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogQHNlZSBvcmcuYXBhY2hlLnhlcmNlcy54cy5YU09iamVjdCNnZXROYW1lc3BhY2VJdGVtKCkKLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBYU05hbWVzcGFjZUl0ZW0gZ2V0TmFtZXNwYWNlSXRlbSgpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotCi0gICAgLyoqCi0gICAgICogT3B0aW9uYWwuIEFubm90YXRpb25zLgotICAgICAqLwotICAgIHB1YmxpYyBYU09iamVjdExpc3QgZ2V0QW5ub3RhdGlvbnMoKSB7Ci0gICAgICAgIHJldHVybiAoZkFubm90YXRpb25zICE9IG51bGwpID8gZkFubm90YXRpb25zIDogWFNPYmplY3RMaXN0SW1wbC5FTVBUWV9MSVNUOwotICAgIH0KLQotfSAvLyBjbGFzcyBYU1BhcnRpY2xlRGVjbApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9YU1dpbGRjYXJkRGVjbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9YU1dpbGRjYXJkRGVjbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhYzNhMDBlLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvWFNXaWxkY2FyZERlY2wuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDU5OSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54czsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy51dGlsLlN0cmluZ0xpc3RJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy51dGlsLlhTT2JqZWN0TGlzdEltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5TdHJpbmdMaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNBbm5vdGF0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNDb25zdGFudHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU05hbWVzcGFjZUl0ZW07Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU1dpbGRjYXJkOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNPYmplY3RMaXN0OwotCi0vKioKLSAqIFRoZSBYTUwgcmVwcmVzZW50YXRpb24gZm9yIGEgd2lsZGNhcmQgZGVjbGFyYXRpb24KLSAqIHNjaGVtYSBjb21wb25lbnQgaXMgYW4gPGFueT4gb3IgPGFueUF0dHJpYnV0ZT4gZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgU2FuZHkgR2FvLCBJQk0KLSAqIEBhdXRob3IgUmFodWwgU3JpdmFzdGF2YSwgU3VuIE1pY3Jvc3lzdGVtcyBJbmMuCi0gKgotICogQHZlcnNpb24gJElkOiBYU1dpbGRjYXJkRGVjbC5qYXZhLHYgMS43IDIwMTAtMTEtMDEgMDQ6Mzk6NTUgam9laHcgRXhwICQKLSAqLwotcHVibGljIGNsYXNzIFhTV2lsZGNhcmREZWNsIGltcGxlbWVudHMgWFNXaWxkY2FyZCB7Ci0KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBQlNFTlQgPSBudWxsOwotCi0gICAgLy8gdGhlIHR5cGUgb2Ygd2lsZGNhcmQ6IGFueSwgb3RoZXIsIG9yIGxpc3QKLSAgICBwdWJsaWMgc2hvcnQgZlR5cGUgPSBOU0NPTlNUUkFJTlRfQU5ZOwotICAgIC8vIHRoZSB0eXBlIG9mIHByb2Nlc3MgY29udGVudHM6IHN0cmljdCwgbGF4LCBvciBza2lwCi0gICAgcHVibGljIHNob3J0IGZQcm9jZXNzQ29udGVudHMgPSBQQ19TVFJJQ1Q7Ci0gICAgLy8gdGhlIG5hbWVzcGFjZSBsaXN0OgotICAgIC8vIGZvciBOU0NPTlNUUkFJTlRfTElTVCwgaXQgbWVhbnMgb25lIG9mIHRoZSBuYW1lc3BhY2VzIGluIHRoZSBsaXN0Ci0gICAgLy8gZm9yIE5TQ09OU1RSQUlOVF9OT1QsIGl0IG1lYW5zIG5vdCBhbnkgb2YgdGhlIG5hbWVzcGFjZXMgaW4gdGhlIGxpc3QKLSAgICBwdWJsaWMgU3RyaW5nW10gZk5hbWVzcGFjZUxpc3Q7Ci0KLSAgICAvLyBvcHRpb25hbCBhbm5vdGF0aW9uCi0gICAgcHVibGljIFhTT2JqZWN0TGlzdCBmQW5ub3RhdGlvbnMgPSBudWxsOwotCi0gICAgLy8gSSdtIHRyeWluZyB0byBpbXBsZW1lbnQgdGhlIGZvbGxvd2luZyBjb25zdHJhaW50IGV4YWN0bHkgYXMgd2hhdCB0aGUKLSAgICAvLyBzcGVjIGRlc2NyaWJlcy4gU29tZXRpbWVzIGl0IHNlZW1zIHJlZHVuZGFudCwgYW5kIHNvbWV0aW1lcyB0aGVyZSBzZWVtcwotICAgIC8vIHRvIGJlIG11Y2ggZWFzaWVyIHNvbHV0aW9ucy4gQnV0IGl0IG1ha2VzIGl0IGVhc3kgdG8gdW5kZXJzdGFuZCwKLSAgICAvLyBlYXN5IHRvIG1haW50YWluLCBhbmQgZWFzeSB0byBmaW5kIGEgYnVnIChlaXRoZXIgaW4gdGhlIGNvZGUsIG9yIGluIHRoZQotICAgIC8vIHNwZWMpLiAtU0cKLSAgICAvLwotICAgIC8vIE5PVEU6IFNjaGVtYSBzcGVjIG9ubHkgcmVxdWlyZXMgdGhhdCAjI290aGVyIG5vdCh0TlMsYWJzZW50KS4KLSAgICAvLyAgICAgICBUaGUgd2F5IHdlIHN0b3JlICMjb3RoZXIgaXMgbm90KE5TMSxOUzIsLi4uLE5TTiksIHdoaWNoIGNvdmVycwotICAgIC8vICAgICAgIHdoYXQncyByZXF1aXJlZCBieSBTY2hlbWEsIGFuZCBhbGxvd3MgZnV0dXJlIGVuaGFuY2VkIGZlYXR1cmVzLgotICAgIC8vCi0gICAgLy8gSW4gdGhlIGZvbGxvd2luZyBpbi1saW5lIGNvbW1lbnRzOgotICAgIC8vIC0gQnVsbGV0IHJlbW92ZWQgZnJvbSB3M2Mgc3BlY2lmaWNhdGlvbi4KLSAgICAvLyArIEJ1bGxldCBhZGRlZCBhcyBwcm9wb3NlZCBieSBTYW5keSBHYW8sIElCTS4KLSAgICAvLyAvIFNpbmNlIHdlIHN0b3JlICMjb3RoZXIgYXMgbm90KE5TMSxOUzIsLi4uLE5TTiksIHdlIG5lZWQgdG8gcHV0IHNvbWUKLSAgICAvLyAgIGNvbW1lbnRzIG9uIHdoZXJlIHdlIGRpZG4ndCBmb2xsb3cgdGhlIHNwZWMgZXhhY3RseS4KLSAgICAvLyAqIFdoZW4gd2UgcmVhbGx5IHN1cHBvcnQgbm90KE5TMSxOUzIsLi4uLE5TTiksIHdlIG5lZWQgdG8gcmV2aXNpdCB0aGVzZSBpdGVtcy4KLQotICAgIC8qKgotICAgICAqIFZhbGlkYXRpb24gUnVsZTogV2lsZGNhcmQgYWxsb3dzIE5hbWVzcGFjZSBOYW1lCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gYWxsb3dOYW1lc3BhY2UoU3RyaW5nIG5hbWVzcGFjZSkgewotICAgICAgICAvLyBGb3IgYSB2YWx1ZSB3aGljaCBpcyBlaXRoZXIgYSBuYW1lc3BhY2UgbmFtZSBvciBhYnNlbnQgdG8gYmUgdmFsaWQgd2l0aCByZXNwZWN0IHRvIGEgd2lsZGNhcmQgY29uc3RyYWludCAodGhlIHZhbHVlIG9mIGEge25hbWVzcGFjZSBjb25zdHJhaW50fSkgb25lIG9mIHRoZSBmb2xsb3dpbmcgbXVzdCBiZSB0cnVlOgotCi0gICAgICAgIC8vIDEgVGhlIGNvbnN0cmFpbnQgbXVzdCBiZSBhbnkuCi0gICAgICAgIGlmIChmVHlwZSA9PSBOU0NPTlNUUkFJTlRfQU5ZKQotICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0KLSAgICAgICAgLy8gMiBBbGwgb2YgdGhlIGZvbGxvd2luZyBtdXN0IGJlIHRydWU6Ci0gICAgICAgIC8vIDIuMSBUaGUgY29uc3RyYWludCBpcyBhIHBhaXIgb2Ygbm90IGFuZCBhIG5hbWVzcGFjZSBuYW1lIG9yIGFic2VudCAoW0RlZmluaXRpb246XSAgY2FsbCB0aGlzIHRoZSBuYW1lc3BhY2UgdGVzdCkuCi0gICAgICAgIC8vIDIuMiBUaGUgdmFsdWUgbXVzdCBub3QgYmUgaWRlbnRpY2FsIHRvIHRoZSBuYW1lc3BhY2UgdGVzdC4KLSAgICAgICAgLy8gMi4zIFRoZSB2YWx1ZSBtdXN0IG5vdCBiZSBhYnNlbnQuCi0gICAgICAgIC8vIC8gd2Ugc3RvcmUgIyNvdGhlciBhcyBub3QobGlzdCksIHNvIG91ciBhY3R1YWwgcnVsZSBpcwotICAgICAgICAvLyAvIDIgVGhlIGNvbnN0cmFpbnQgaXMgYSBwYWlyIG9mIG5vdCBhbmQgYSBzZXQsIGFuZCB0aGUgdmFsdWUgaXMgbm90IGluIHN1Y2ggc2V0LgotICAgICAgICBpZiAoZlR5cGUgPT0gTlNDT05TVFJBSU5UX05PVCkgewotICAgICAgICAgICAgYm9vbGVhbiBmb3VuZCA9IGZhbHNlOwotICAgICAgICAgICAgaW50IGxpc3ROdW0gPSBmTmFtZXNwYWNlTGlzdC5sZW5ndGg7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxpc3ROdW0gJiYgIWZvdW5kOyBpKyspIHsKLSAgICAgICAgICAgICAgICBpZiAobmFtZXNwYWNlID09IGZOYW1lc3BhY2VMaXN0W2ldKQotICAgICAgICAgICAgICAgICAgICBmb3VuZCA9IHRydWU7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmICghZm91bmQpCi0gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyAzIFRoZSBjb25zdHJhaW50IGlzIGEgc2V0LCBhbmQgdGhlIHZhbHVlIGlzIGlkZW50aWNhbCB0byBvbmUgb2YgdGhlIG1lbWJlcnMgb2YgdGhlIHNldC4KLSAgICAgICAgaWYgKGZUeXBlID09IE5TQ09OU1RSQUlOVF9MSVNUKSB7Ci0gICAgICAgICAgICBpbnQgbGlzdE51bSA9IGZOYW1lc3BhY2VMaXN0Lmxlbmd0aDsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGlzdE51bTsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgaWYgKG5hbWVzcGFjZSA9PSBmTmFtZXNwYWNlTGlzdFtpXSkKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBub25lIG9mIHRoZSBhYm92ZSBjb25kaXRpb25zIGFwcGxpZWQsIHNvIHJldHVybiBmYWxzZS4KLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqICBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6IFdpbGRjYXJkIFN1YnNldAotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzU3Vic2V0T2YoWFNXaWxkY2FyZERlY2wgc3VwZXJXaWxkY2FyZCkgewotICAgICAgICAvLyBpZiB0aGUgc3VwZXIgaXMgbnVsbCAobm90IGV4cHJlc3NpYmxlKSwgcmV0dXJuIGZhbHNlCi0gICAgICAgIGlmIChzdXBlcldpbGRjYXJkID09IG51bGwpCi0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0KLSAgICAgICAgLy8gRm9yIGEgbmFtZXNwYWNlIGNvbnN0cmFpbnQgKGNhbGwgaXQgc3ViKSB0byBiZSBhbiBpbnRlbnNpb25hbCBzdWJzZXQgb2YgYW5vdGhlcgotICAgICAgICAvLyBuYW1lc3BhY2UgY29uc3RyYWludCAoY2FsbCBpdCBzdXBlcikgb25lIG9mIHRoZSBmb2xsb3dpbmcgbXVzdCBiZSB0cnVlOgotCi0gICAgICAgIC8vIDEgc3VwZXIgbXVzdCBiZSBhbnkuCi0gICAgICAgIGlmIChzdXBlcldpbGRjYXJkLmZUeXBlID09IE5TQ09OU1RSQUlOVF9BTlkpIHsKLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gMiBBbGwgb2YgdGhlIGZvbGxvd2luZyBtdXN0IGJlIHRydWU6Ci0gICAgICAgIC8vICAgMi4xIHN1YiBtdXN0IGJlIGEgcGFpciBvZiBub3QgYW5kIGEgbmFtZXNwYWNlIG5hbWUgb3IgYWJzZW50LgotICAgICAgICAvLyAgIDIuMiBzdXBlciBtdXN0IGJlIGEgcGFpciBvZiBub3QgYW5kIHRoZSBzYW1lIHZhbHVlLgotICAgICAgICAvLyAgICogd2UgY2FuJ3QganVzdCBjb21wYXJlIHdoZXRoZXIgdGhlIG5hbWVzcGFjZSBhcmUgdGhlIHNhbWUgdmFsdWUKLSAgICAgICAgLy8gICAgIHNpbmNlIHdlIHN0b3JlIG90aGVyIGFzIG5vdChsaXN0KQotICAgICAgICBpZiAoZlR5cGUgPT0gTlNDT05TVFJBSU5UX05PVCkgewotICAgICAgICAgICAgaWYgKHN1cGVyV2lsZGNhcmQuZlR5cGUgPT0gTlNDT05TVFJBSU5UX05PVCAmJgotICAgICAgICAgICAgICAgIGZOYW1lc3BhY2VMaXN0WzBdID09IHN1cGVyV2lsZGNhcmQuZk5hbWVzcGFjZUxpc3RbMF0pIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIDMgQWxsIG9mIHRoZSBmb2xsb3dpbmcgbXVzdCBiZSB0cnVlOgotICAgICAgICAvLyAgIDMuMSBzdWIgbXVzdCBiZSBhIHNldCB3aG9zZSBtZW1iZXJzIGFyZSBlaXRoZXIgbmFtZXNwYWNlIG5hbWVzIG9yIGFic2VudC4KLSAgICAgICAgLy8gICAzLjIgT25lIG9mIHRoZSBmb2xsb3dpbmcgbXVzdCBiZSB0cnVlOgotICAgICAgICAvLyAgICAgICAzLjIuMSBzdXBlciBtdXN0IGJlIHRoZSBzYW1lIHNldCBvciBhIHN1cGVyc2V0IHRoZXJlb2YuCi0gICAgICAgIC8vICAgICAgIC0zLjIuMiBzdXBlciBtdXN0IGJlIGEgcGFpciBvZiBub3QgYW5kIGEgbmFtZXNwYWNlIG5hbWUgb3IgYWJzZW50IGFuZAotICAgICAgICAvLyAgICAgICAgICAgICAgdGhhdCB2YWx1ZSBtdXN0IG5vdCBiZSBpbiBzdWIncyBzZXQuCi0gICAgICAgIC8vICAgICAgICszLjIuMiBzdXBlciBtdXN0IGJlIGEgcGFpciBvZiBub3QgYW5kIGEgbmFtZXNwYWNlIG5hbWUgb3IgYWJzZW50IGFuZAotICAgICAgICAvLyAgICAgICAgICAgICAgZWl0aGVyIHRoYXQgdmFsdWUgb3IgYWJzZW50IG11c3Qgbm90IGJlIGluIHN1YidzIHNldC4KLSAgICAgICAgLy8gICAgICAgKiBzaW5jZSB3ZSBzdG9yZSAjI290aGVyIGFzIG5vdChsaXN0KSwgd2UgYWN0dXJhbGx5IG5lZWQgdG8gbWFrZSBzdXJlCi0gICAgICAgIC8vICAgICAgICAgdGhhdCBub25lIG9mIHRoZSBuYW1lc3BhY2VzIGluIHN1cGVyLmxpc3QgaXMgaW4gc3ViLmxpc3QuCi0gICAgICAgIGlmIChmVHlwZSA9PSBOU0NPTlNUUkFJTlRfTElTVCkgewotICAgICAgICAgICAgaWYgKHN1cGVyV2lsZGNhcmQuZlR5cGUgPT0gTlNDT05TVFJBSU5UX0xJU1QgJiYKLSAgICAgICAgICAgICAgICBzdWJzZXQyc2V0cyhmTmFtZXNwYWNlTGlzdCwgc3VwZXJXaWxkY2FyZC5mTmFtZXNwYWNlTGlzdCkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKHN1cGVyV2lsZGNhcmQuZlR5cGUgPT0gTlNDT05TVFJBSU5UX05PVCAmJgotICAgICAgICAgICAgICAgICFlbGVtZW50SW5TZXQoc3VwZXJXaWxkY2FyZC5mTmFtZXNwYWNlTGlzdFswXSwgZk5hbWVzcGFjZUxpc3QpICYmCi0gICAgICAgICAgICAgICAgIWVsZW1lbnRJblNldChBQlNFTlQsIGZOYW1lc3BhY2VMaXN0KSkgewotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gbm9uZSBvZiB0aGUgYWJvdmUgY29uZGl0aW9ucyBhcHBsaWVkLCBzbyByZXR1cm4gZmFsc2UuCi0gICAgICAgIHJldHVybiBmYWxzZTsKLQotICAgIH0gLy8gaXNTdWJzZXRPZgotCi0gICAgLyoqCi0gICAgICogQ2hlY2sgd2hldGhlciB0aGlzIHdpbGRjYXJkIGhhcyBhIHdlYWtlciBwcm9jZXNzIGNvbnRlbnRzIHRoYW4gdGhlIHN1cGVyLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIHdlYWtlclByb2Nlc3NDb250ZW50cyhYU1dpbGRjYXJkRGVjbCBzdXBlcldpbGRjYXJkKSB7Ci0gICAgICAgIHJldHVybiBmUHJvY2Vzc0NvbnRlbnRzID09IFhTV2lsZGNhcmREZWNsLlBDX0xBWCAmJgotICAgICAgICAgICAgICAgc3VwZXJXaWxkY2FyZC5mUHJvY2Vzc0NvbnRlbnRzID09IFhTV2lsZGNhcmREZWNsLlBDX1NUUklDVCB8fAotICAgICAgICAgICAgICAgZlByb2Nlc3NDb250ZW50cyA9PSBYU1dpbGRjYXJkRGVjbC5QQ19TS0lQICYmCi0gICAgICAgICAgICAgICBzdXBlcldpbGRjYXJkLmZQcm9jZXNzQ29udGVudHMgIT0gWFNXaWxkY2FyZERlY2wuUENfU0tJUDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6IEF0dHJpYnV0ZSBXaWxkY2FyZCBVbmlvbgotICAgICAqLwotICAgIHB1YmxpYyBYU1dpbGRjYXJkRGVjbCBwZXJmb3JtVW5pb25XaXRoKFhTV2lsZGNhcmREZWNsIHdpbGRjYXJkLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNob3J0IHByb2Nlc3NDb250ZW50cykgewotICAgICAgICAvLyBpZiB0aGUgb3RoZXIgd2lsZGNhcmQgaXMgbm90IGV4cHJlc3NpYmxlLCB0aGUgcmVzdWx0IGlzIHN0aWxsIG5vdCBleHByZXNzaWJsZQotICAgICAgICBpZiAod2lsZGNhcmQgPT0gbnVsbCkKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotCi0gICAgICAgIC8vIEZvciBhIHdpbGRjYXJkJ3Mge25hbWVzcGFjZSBjb25zdHJhaW50fSB2YWx1ZSB0byBiZSB0aGUgaW50ZW5zaW9uYWwgdW5pb24gb2YgdHdvCi0gICAgICAgIC8vIG90aGVyIHN1Y2ggdmFsdWVzIChjYWxsIHRoZW0gTzEgYW5kIE8yKTogdGhlIGFwcHJvcHJpYXRlIGNhc2UgYW1vbmcgdGhlIGZvbGxvd2luZwotICAgICAgICAvLyBtdXN0IGJlIHRydWU6Ci0KLSAgICAgICAgWFNXaWxkY2FyZERlY2wgdW5pb25XaWxkY2FyZCA9IG5ldyBYU1dpbGRjYXJkRGVjbCgpOwotICAgICAgICB1bmlvbldpbGRjYXJkLmZQcm9jZXNzQ29udGVudHMgPSBwcm9jZXNzQ29udGVudHM7Ci0KLSAgICAgICAgLy8gMSBJZiBPMSBhbmQgTzIgYXJlIHRoZSBzYW1lIHZhbHVlLCB0aGVuIHRoYXQgdmFsdWUgbXVzdCBiZSB0aGUgdmFsdWUuCi0gICAgICAgIGlmIChhcmVTYW1lKHdpbGRjYXJkKSkgewotICAgICAgICAgICAgdW5pb25XaWxkY2FyZC5mVHlwZSA9IGZUeXBlOwotICAgICAgICAgICAgdW5pb25XaWxkY2FyZC5mTmFtZXNwYWNlTGlzdCA9IGZOYW1lc3BhY2VMaXN0OwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gMiBJZiBlaXRoZXIgTzEgb3IgTzIgaXMgYW55LCB0aGVuIGFueSBtdXN0IGJlIHRoZSB2YWx1ZS4KLSAgICAgICAgZWxzZSBpZiAoIChmVHlwZSA9PSBOU0NPTlNUUkFJTlRfQU5ZKSB8fCAod2lsZGNhcmQuZlR5cGUgPT0gTlNDT05TVFJBSU5UX0FOWSkgKSB7Ci0gICAgICAgICAgICB1bmlvbldpbGRjYXJkLmZUeXBlID0gTlNDT05TVFJBSU5UX0FOWTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIDMgSWYgYm90aCBPMSBhbmQgTzIgYXJlIHNldHMgb2YgKG5hbWVzcGFjZSBuYW1lcyBvciBhYnNlbnQpLCB0aGVuIHRoZSB1bmlvbiBvZgotICAgICAgICAvLyAgIHRob3NlIHNldHMgbXVzdCBiZSB0aGUgdmFsdWUuCi0gICAgICAgIGVsc2UgaWYgKCAoZlR5cGUgPT0gTlNDT05TVFJBSU5UX0xJU1QpICYmICh3aWxkY2FyZC5mVHlwZSA9PSBOU0NPTlNUUkFJTlRfTElTVCkgKSB7Ci0gICAgICAgICAgICB1bmlvbldpbGRjYXJkLmZUeXBlID0gTlNDT05TVFJBSU5UX0xJU1Q7Ci0gICAgICAgICAgICB1bmlvbldpbGRjYXJkLmZOYW1lc3BhY2VMaXN0ID0gdW5pb24yc2V0cyhmTmFtZXNwYWNlTGlzdCwgd2lsZGNhcmQuZk5hbWVzcGFjZUxpc3QpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gLTQgSWYgdGhlIHR3byBhcmUgbmVnYXRpb25zIG9mIGRpZmZlcmVudCBuYW1lc3BhY2UgbmFtZXMsIHRoZW4gdGhlIGludGVyc2VjdGlvbgotICAgICAgICAvLyAgICBpcyBub3QgZXhwcmVzc2libGUuCi0gICAgICAgIC8vICs0IElmIHRoZSB0d28gYXJlIG5lZ2F0aW9ucyBvZiBkaWZmZXJlbnQgbmFtZXNwYWNlIG5hbWVzIG9yIGFic2VudCwgdGhlbgotICAgICAgICAvLyAgICBhIHBhaXIgb2Ygbm90IGFuZCBhYnNlbnQgbXVzdCBiZSB0aGUgdmFsdWUuCi0gICAgICAgIC8vICogbm93IHdlIHN0b3JlICMjb3RoZXIgYXMgbm90KGxpc3QpLCB0aGUgcmVzdWx0IHNob3VsZCBiZQotICAgICAgICAvLyAgIG5vdChpbnRlcnNlY3Rpb24gb2YgdHdvIGxpc3RzKS4KLSAgICAgICAgZWxzZSBpZiAoZlR5cGUgPT0gTlNDT05TVFJBSU5UX05PVCAmJiB3aWxkY2FyZC5mVHlwZSA9PSBOU0NPTlNUUkFJTlRfTk9UKSB7Ci0gICAgICAgICAgICB1bmlvbldpbGRjYXJkLmZUeXBlID0gTlNDT05TVFJBSU5UX05PVDsKLSAgICAgICAgICAgIHVuaW9uV2lsZGNhcmQuZk5hbWVzcGFjZUxpc3QgPSBuZXcgU3RyaW5nWzJdOwotICAgICAgICAgICAgdW5pb25XaWxkY2FyZC5mTmFtZXNwYWNlTGlzdFswXSA9IEFCU0VOVDsKLSAgICAgICAgICAgIHVuaW9uV2lsZGNhcmQuZk5hbWVzcGFjZUxpc3RbMV0gPSBBQlNFTlQ7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyA1IElmIGVpdGhlciBPMSBvciBPMiBpcyBhIHBhaXIgb2Ygbm90IGFuZCBhIG5hbWVzcGFjZSBuYW1lIGFuZCB0aGUgb3RoZXIgaXMgYSBzZXQgb2YKLSAgICAgICAgLy8gICAobmFtZXNwYWNlIG5hbWVzIG9yIGFic2VudCksIHRoZW4gVGhlIGFwcHJvcHJpYXRlIGNhc2UgYW1vbmcgdGhlIGZvbGxvd2luZyBtdXN0IGJlIHRydWU6Ci0gICAgICAgIC8vICAgICAgLTUuMSBJZiB0aGUgc2V0IGluY2x1ZGVzIHRoZSBuZWdhdGVkIG5hbWVzcGFjZSBuYW1lLCB0aGVuIGFueSBtdXN0IGJlIHRoZSB2YWx1ZS4KLSAgICAgICAgLy8gICAgICAtNS4yIElmIHRoZSBzZXQgZG9lcyBub3QgaW5jbHVkZSB0aGUgbmVnYXRlZCBuYW1lc3BhY2UgbmFtZSwgdGhlbiB3aGljaGV2ZXIgb2YgTzEgb3IgTzIKLSAgICAgICAgLy8gICAgICAgICAgIGlzIGEgcGFpciBvZiBub3QgYW5kIGEgbmFtZXNwYWNlIG5hbWUgbXVzdCBiZSB0aGUgdmFsdWUuCi0gICAgICAgIC8vICAgICs1LjEgSWYgdGhlIG5lZ2F0ZWQgdmFsdWUgaXMgYSBuYW1lc3BhY2UgbmFtZSwgdGhlbiBUaGUgYXBwcm9wcmlhdGUgY2FzZQotICAgICAgICAvLyAgICAgICAgIGFtb25nIHRoZSBmb2xsb3dpbmcgbXVzdCBiZSB0cnVlOgotICAgICAgICAvLyAgICAgICAgKzUuMS4xIElmIHRoZSBzZXQgaW5jbHVkZXMgYm90aCB0aGUgbmFtZXNwYWNlIG5hbWUgYW5kIGFic2VudCwgdGhlbiBhbnkKLSAgICAgICAgLy8gICAgICAgICAgICAgICBtdXN0IGJlIHRoZSB2YWx1ZS4KLSAgICAgICAgLy8gICAgICAgICs1LjEuMiBJZiB0aGUgc2V0IGluY2x1ZGVzIHRoZSBuYW1lc3BhY2UgbmFtZSBidXQgZG9lcyBub3QgaW5jbHVkZQotICAgICAgICAvLyAgICAgICAgICAgICAgIGFic2VudCwgdGhlbiBhIHBhaXIgb2Ygbm90IGFuZCBhYnNlbnQgbXVzdCBiZSB0aGUgdmFsdWUuCi0gICAgICAgIC8vICAgICAgICArNS4xLjMgSWYgdGhlIHNldCBkb2VzIG5vdCBpbmNsdWRlIHRoZSBuYW1lc3BhY2UgbmFtZSBidXQgaW5jbHVkZXMKLSAgICAgICAgLy8gICAgICAgICAgICAgICBhYnNlbnQsIHRoZW4gdGhlIHVuaW9uIGlzIG5vdCBleHByZXNzaWJsZS4KLSAgICAgICAgLy8gICAgICAgICs1LjEuNCBJZiB0aGUgc2V0IGRvZXMgbm90IGluY2x1ZGUgZWl0aGVyIHRoZSBuYW1lc3BhY2UgbmFtZSBvciBhYnNlbnQsCi0gICAgICAgIC8vICAgICAgICAgICAgICAgdGhlbiB3aGljaGV2ZXIgb2YgTzEgb3IgTzIgaXMgYSBwYWlyIG9mIG5vdCBhbmQgYSBuYW1lc3BhY2UgbmFtZSBtdXN0IGJlCi0gICAgICAgIC8vICAgICAgICAgICAgICAgdGhlIHZhbHVlLgotICAgICAgICAvLyAgICArNS4yIElmIHRoZSBuZWdhdGVkIHZhbHVlIGlzIGFic2VudCwgdGhlbiBUaGUgYXBwcm9wcmlhdGUgY2FzZSBhbW9uZyB0aGUKLSAgICAgICAgLy8gICAgICAgICBmb2xsb3dpbmcgbXVzdCBiZSB0cnVlOgotICAgICAgICAvLyAgICAgICAgKzUuMi4xIElmIHRoZSBzZXQgaW5jbHVkZXMgYWJzZW50LCB0aGVuIGFueSBtdXN0IGJlIHRoZSB2YWx1ZS4KLSAgICAgICAgLy8gICAgICAgICs1LjIuMiBJZiB0aGUgc2V0IGRvZXMgbm90IGluY2x1ZGUgYWJzZW50LCB0aGVuIHdoaWNoZXZlciBvZiBPMSBvciBPMiBpcwotICAgICAgICAvLyAgICAgICAgICAgICAgIGEgcGFpciBvZiBub3QgYW5kIGEgbmFtZXNwYWNlIG5hbWUgbXVzdCBiZSB0aGUgdmFsdWUuCi0gICAgICAgIC8vICogd2hlbiB3ZSBoYXZlIG5vdChsaXN0KSwgdGhlIG9wZXJhdGlvbiBpcyBqdXN0IG5vdChvdGhlcmxpc3QtbGlzdCkKLSAgICAgICAgZWxzZSBpZiAoICgoZlR5cGUgPT0gTlNDT05TVFJBSU5UX05PVCkgJiYgKHdpbGRjYXJkLmZUeXBlID09IE5TQ09OU1RSQUlOVF9MSVNUKSkgfHwKLSAgICAgICAgICAgICAgICAgICgoZlR5cGUgPT0gTlNDT05TVFJBSU5UX0xJU1QpICYmICh3aWxkY2FyZC5mVHlwZSA9PSBOU0NPTlNUUkFJTlRfTk9UKSkgKSB7Ci0gICAgICAgICAgICBTdHJpbmdbXSBvdGhlciA9IG51bGw7Ci0gICAgICAgICAgICBTdHJpbmdbXSBsaXN0ID0gbnVsbDsKLQotICAgICAgICAgICAgaWYgKGZUeXBlID09IE5TQ09OU1RSQUlOVF9OT1QpIHsKLSAgICAgICAgICAgICAgICBvdGhlciA9IGZOYW1lc3BhY2VMaXN0OwotICAgICAgICAgICAgICAgIGxpc3QgPSB3aWxkY2FyZC5mTmFtZXNwYWNlTGlzdDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIG90aGVyID0gd2lsZGNhcmQuZk5hbWVzcGFjZUxpc3Q7Ci0gICAgICAgICAgICAgICAgbGlzdCA9IGZOYW1lc3BhY2VMaXN0OwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBib29sZWFuIGZvdW5kQWJzZW50ID0gZWxlbWVudEluU2V0KEFCU0VOVCwgbGlzdCk7Ci0KLSAgICAgICAgICAgIGlmIChvdGhlclswXSAhPSBBQlNFTlQpIHsKLSAgICAgICAgICAgICAgICBib29sZWFuIGZvdW5kTlMgPSBlbGVtZW50SW5TZXQob3RoZXJbMF0sIGxpc3QpOwotICAgICAgICAgICAgICAgIGlmIChmb3VuZE5TICYmIGZvdW5kQWJzZW50KSB7Ci0gICAgICAgICAgICAgICAgICAgIHVuaW9uV2lsZGNhcmQuZlR5cGUgPSBOU0NPTlNUUkFJTlRfQU5ZOwotICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZm91bmROUyAmJiAhZm91bmRBYnNlbnQpIHsKLSAgICAgICAgICAgICAgICAgICAgdW5pb25XaWxkY2FyZC5mVHlwZSA9IE5TQ09OU1RSQUlOVF9OT1Q7Ci0gICAgICAgICAgICAgICAgICAgIHVuaW9uV2lsZGNhcmQuZk5hbWVzcGFjZUxpc3QgPSBuZXcgU3RyaW5nWzJdOwotICAgICAgICAgICAgICAgICAgICB1bmlvbldpbGRjYXJkLmZOYW1lc3BhY2VMaXN0WzBdID0gQUJTRU5UOwotICAgICAgICAgICAgICAgICAgICB1bmlvbldpbGRjYXJkLmZOYW1lc3BhY2VMaXN0WzFdID0gQUJTRU5UOwotICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIWZvdW5kTlMgJiYgZm91bmRBYnNlbnQpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgICAgICAgICAgfSBlbHNlIHsgLy8gIWZvdW5kTlMgJiYgIWZvdW5kQWJzZW50Ci0gICAgICAgICAgICAgICAgICAgIHVuaW9uV2lsZGNhcmQuZlR5cGUgPSBOU0NPTlNUUkFJTlRfTk9UOwotICAgICAgICAgICAgICAgICAgICB1bmlvbldpbGRjYXJkLmZOYW1lc3BhY2VMaXN0ID0gb3RoZXI7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfSBlbHNlIHsgLy8gb3RoZXJbMF0gPT0gQUJTRU5UCi0gICAgICAgICAgICAgICAgaWYgKGZvdW5kQWJzZW50KSB7Ci0gICAgICAgICAgICAgICAgICAgIHVuaW9uV2lsZGNhcmQuZlR5cGUgPSBOU0NPTlNUUkFJTlRfQU5ZOwotICAgICAgICAgICAgICAgIH0gZWxzZSB7IC8vICFmb3VuZEFic2VudAotICAgICAgICAgICAgICAgICAgICB1bmlvbldpbGRjYXJkLmZUeXBlID0gTlNDT05TVFJBSU5UX05PVDsKLSAgICAgICAgICAgICAgICAgICAgdW5pb25XaWxkY2FyZC5mTmFtZXNwYWNlTGlzdCA9IG90aGVyOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiB1bmlvbldpbGRjYXJkOwotCi0gICAgfSAvLyBwZXJmb3JtVW5pb25XaXRoCi0KLSAgICAvKioKLSAgICAgKiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6IEF0dHJpYnV0ZSBXaWxkY2FyZCBJbnRlcnNlY3Rpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgWFNXaWxkY2FyZERlY2wgcGVyZm9ybUludGVyc2VjdGlvbldpdGgoWFNXaWxkY2FyZERlY2wgd2lsZGNhcmQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNob3J0IHByb2Nlc3NDb250ZW50cykgewotICAgICAgICAvLyBpZiB0aGUgb3RoZXIgd2lsZGNhcmQgaXMgbm90IGV4cHJlc3NpYmxlLCB0aGUgcmVzdWx0IGlzIHN0aWxsIG5vdCBleHByZXNzaWJsZQotICAgICAgICBpZiAod2lsZGNhcmQgPT0gbnVsbCkKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotCi0gICAgICAgIC8vIEZvciBhIHdpbGRjYXJkJ3Mge25hbWVzcGFjZSBjb25zdHJhaW50fSB2YWx1ZSB0byBiZSB0aGUgaW50ZW5zaW9uYWwgaW50ZXJzZWN0aW9uIG9mCi0gICAgICAgIC8vIHR3byBvdGhlciBzdWNoIHZhbHVlcyAoY2FsbCB0aGVtIE8xIGFuZCBPMik6IHRoZSBhcHByb3ByaWF0ZSBjYXNlIGFtb25nIHRoZSBmb2xsb3dpbmcKLSAgICAgICAgLy8gbXVzdCBiZSB0cnVlOgotCi0gICAgICAgIFhTV2lsZGNhcmREZWNsIGludGVyc2VjdFdpbGRjYXJkID0gbmV3IFhTV2lsZGNhcmREZWNsKCk7Ci0gICAgICAgIGludGVyc2VjdFdpbGRjYXJkLmZQcm9jZXNzQ29udGVudHMgPSBwcm9jZXNzQ29udGVudHM7Ci0KLSAgICAgICAgLy8gMSBJZiBPMSBhbmQgTzIgYXJlIHRoZSBzYW1lIHZhbHVlLCB0aGVuIHRoYXQgdmFsdWUgbXVzdCBiZSB0aGUgdmFsdWUuCi0gICAgICAgIGlmIChhcmVTYW1lKHdpbGRjYXJkKSkgewotICAgICAgICAgICAgaW50ZXJzZWN0V2lsZGNhcmQuZlR5cGUgPSBmVHlwZTsKLSAgICAgICAgICAgIGludGVyc2VjdFdpbGRjYXJkLmZOYW1lc3BhY2VMaXN0ID0gZk5hbWVzcGFjZUxpc3Q7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyAyIElmIGVpdGhlciBPMSBvciBPMiBpcyBhbnksIHRoZW4gdGhlIG90aGVyIG11c3QgYmUgdGhlIHZhbHVlLgotICAgICAgICBlbHNlIGlmICggKGZUeXBlID09IE5TQ09OU1RSQUlOVF9BTlkpIHx8ICh3aWxkY2FyZC5mVHlwZSA9PSBOU0NPTlNUUkFJTlRfQU5ZKSApIHsKLSAgICAgICAgICAgIC8vIGJvdGggY2Fubm90IGJlIEFOWSwgaWYgd2UgaGF2ZSByZWFjaGVkIGhlcmUuCi0gICAgICAgICAgICBYU1dpbGRjYXJkRGVjbCBvdGhlciA9IHRoaXM7Ci0KLSAgICAgICAgICAgIGlmIChmVHlwZSA9PSBOU0NPTlNUUkFJTlRfQU5ZKQotICAgICAgICAgICAgICAgIG90aGVyID0gd2lsZGNhcmQ7Ci0KLSAgICAgICAgICAgIGludGVyc2VjdFdpbGRjYXJkLmZUeXBlID0gb3RoZXIuZlR5cGU7Ci0gICAgICAgICAgICBpbnRlcnNlY3RXaWxkY2FyZC5mTmFtZXNwYWNlTGlzdCA9IG90aGVyLmZOYW1lc3BhY2VMaXN0OwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gLTMgSWYgZWl0aGVyIE8xIG9yIE8yIGlzIGEgcGFpciBvZiBub3QgYW5kIGEgbmFtZXNwYWNlIG5hbWUgYW5kIHRoZSBvdGhlciBpcyBhIHNldCBvZgotICAgICAgICAvLyAgICAobmFtZXNwYWNlIG5hbWVzIG9yIGFic2VudCksIHRoZW4gdGhhdCBzZXQsIG1pbnVzIHRoZSBuZWdhdGVkIG5hbWVzcGFjZSBuYW1lIGlmCi0gICAgICAgIC8vICAgIGl0IHdhcyBpbiB0aGUgc2V0LCBtdXN0IGJlIHRoZSB2YWx1ZS4KLSAgICAgICAgLy8gKzMgSWYgZWl0aGVyIE8xIG9yIE8yIGlzIGEgcGFpciBvZiBub3QgYW5kIGEgbmFtZXNwYWNlIG5hbWUgYW5kIHRoZSBvdGhlcgotICAgICAgICAvLyAgICBpcyBhIHNldCBvZiAobmFtZXNwYWNlIG5hbWVzIG9yIGFic2VudCksIHRoZW4gdGhhdCBzZXQsIG1pbnVzIHRoZSBuZWdhdGVkCi0gICAgICAgIC8vICAgIG5hbWVzcGFjZSBuYW1lIGlmIGl0IHdhcyBpbiB0aGUgc2V0LCB0aGVuIG1pbnVzIGFic2VudCBpZiBpdCB3YXMgaW4gdGhlCi0gICAgICAgIC8vICAgIHNldCwgbXVzdCBiZSB0aGUgdmFsdWUuCi0gICAgICAgIC8vICogd2hlbiB3ZSBoYXZlIG5vdChsaXN0KSwgdGhlIG9wZXJhdGlvbiBpcyBqdXN0IGxpc3Qtb3RoZXJsaXN0Ci0gICAgICAgIGVsc2UgaWYgKCAoKGZUeXBlID09IE5TQ09OU1RSQUlOVF9OT1QpICYmICh3aWxkY2FyZC5mVHlwZSA9PSBOU0NPTlNUUkFJTlRfTElTVCkpIHx8Ci0gICAgICAgICAgICAgICAgICAoKGZUeXBlID09IE5TQ09OU1RSQUlOVF9MSVNUKSAmJiAod2lsZGNhcmQuZlR5cGUgPT0gTlNDT05TVFJBSU5UX05PVCkpICkgewotICAgICAgICAgICAgU3RyaW5nW10gbGlzdCA9IG51bGw7Ci0gICAgICAgICAgICBTdHJpbmdbXSBvdGhlciA9IG51bGw7Ci0KLSAgICAgICAgICAgIGlmIChmVHlwZSA9PSBOU0NPTlNUUkFJTlRfTk9UKSB7Ci0gICAgICAgICAgICAgICAgb3RoZXIgPSBmTmFtZXNwYWNlTGlzdDsKLSAgICAgICAgICAgICAgICBsaXN0ID0gd2lsZGNhcmQuZk5hbWVzcGFjZUxpc3Q7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBvdGhlciA9IHdpbGRjYXJkLmZOYW1lc3BhY2VMaXN0OwotICAgICAgICAgICAgICAgIGxpc3QgPSBmTmFtZXNwYWNlTGlzdDsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaW50IGxpc3RTaXplID0gbGlzdC5sZW5ndGg7Ci0gICAgICAgICAgICBTdHJpbmdbXSBpbnRlcnNlY3QgPSBuZXcgU3RyaW5nW2xpc3RTaXplXTsKLSAgICAgICAgICAgIGludCBuZXdTaXplID0gMDsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGlzdFNpemU7IGkrKykgewotICAgICAgICAgICAgICAgIGlmIChsaXN0W2ldICE9IG90aGVyWzBdICYmIGxpc3RbaV0gIT0gQUJTRU5UKQotICAgICAgICAgICAgICAgICAgICBpbnRlcnNlY3RbbmV3U2l6ZSsrXSA9IGxpc3RbaV07Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGludGVyc2VjdFdpbGRjYXJkLmZUeXBlID0gTlNDT05TVFJBSU5UX0xJU1Q7Ci0gICAgICAgICAgICBpbnRlcnNlY3RXaWxkY2FyZC5mTmFtZXNwYWNlTGlzdCA9IG5ldyBTdHJpbmdbbmV3U2l6ZV07Ci0gICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGludGVyc2VjdCwgMCwgaW50ZXJzZWN0V2lsZGNhcmQuZk5hbWVzcGFjZUxpc3QsIDAsIG5ld1NpemUpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gNCBJZiBib3RoIE8xIGFuZCBPMiBhcmUgc2V0cyBvZiAobmFtZXNwYWNlIG5hbWVzIG9yIGFic2VudCksIHRoZW4gdGhlIGludGVyc2VjdGlvbiBvZiB0aG9zZQotICAgICAgICAvLyAgIHNldHMgbXVzdCBiZSB0aGUgdmFsdWUuCi0gICAgICAgIGVsc2UgaWYgKCAoZlR5cGUgPT0gTlNDT05TVFJBSU5UX0xJU1QpICYmICh3aWxkY2FyZC5mVHlwZSA9PSBOU0NPTlNUUkFJTlRfTElTVCkgKSB7Ci0gICAgICAgICAgICBpbnRlcnNlY3RXaWxkY2FyZC5mVHlwZSA9IE5TQ09OU1RSQUlOVF9MSVNUOwotICAgICAgICAgICAgaW50ZXJzZWN0V2lsZGNhcmQuZk5hbWVzcGFjZUxpc3QgPSBpbnRlcnNlY3Qyc2V0cyhmTmFtZXNwYWNlTGlzdCwgd2lsZGNhcmQuZk5hbWVzcGFjZUxpc3QpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gLTUgSWYgdGhlIHR3byBhcmUgbmVnYXRpb25zIG9mIGRpZmZlcmVudCBuYW1lc3BhY2UgbmFtZXMsIHRoZW4gdGhlIGludGVyc2VjdGlvbiBpcyBub3QgZXhwcmVzc2libGUuCi0gICAgICAgIC8vICs1IElmIHRoZSB0d28gYXJlIG5lZ2F0aW9ucyBvZiBuYW1lc3BhY2UgbmFtZXMgb3IgYWJzZW50LCB0aGVuIFRoZQotICAgICAgICAvLyAgICBhcHByb3ByaWF0ZSBjYXNlIGFtb25nIHRoZSBmb2xsb3dpbmcgbXVzdCBiZSB0cnVlOgotICAgICAgICAvLyAgICArNS4xIElmIHRoZSB0d28gYXJlIG5lZ2F0aW9ucyBvZiBkaWZmZXJlbnQgbmFtZXNwYWNlIG5hbWVzLCB0aGVuIHRoZQotICAgICAgICAvLyAgICAgICAgIGludGVyc2VjdGlvbiBpcyBub3QgZXhwcmVzc2libGUuCi0gICAgICAgIC8vICAgICs1LjIgSWYgb25lIG9mIHRoZSB0d28gaXMgYSBwYWlyIG9mIG5vdCBhbmQgYWJzZW50LCB0aGUgb3RoZXIgbXVzdCBiZQotICAgICAgICAvLyAgICAgICAgIHRoZSB2YWx1ZS4KLSAgICAgICAgLy8gKiB3aGVuIHdlIGhhdmUgbm90KGxpc3QpLCB0aGUgb3BlcmF0aW9uIGlzIGp1c3Qgbm90KG9uZWxpc3Qrb3RoZXJsaXN0KQotICAgICAgICBlbHNlIGlmIChmVHlwZSA9PSBOU0NPTlNUUkFJTlRfTk9UICYmIHdpbGRjYXJkLmZUeXBlID09IE5TQ09OU1RSQUlOVF9OT1QpIHsKLSAgICAgICAgICAgIGlmIChmTmFtZXNwYWNlTGlzdFswXSAhPSBBQlNFTlQgJiYgd2lsZGNhcmQuZk5hbWVzcGFjZUxpc3RbMF0gIT0gQUJTRU5UKQotICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwotCi0gICAgICAgICAgICBYU1dpbGRjYXJkRGVjbCBvdGhlciA9IHRoaXM7Ci0gICAgICAgICAgICBpZiAoZk5hbWVzcGFjZUxpc3RbMF0gPT0gQUJTRU5UKQotICAgICAgICAgICAgICAgIG90aGVyID0gd2lsZGNhcmQ7Ci0KLSAgICAgICAgICAgIGludGVyc2VjdFdpbGRjYXJkLmZUeXBlID0gb3RoZXIuZlR5cGU7Ci0gICAgICAgICAgICBpbnRlcnNlY3RXaWxkY2FyZC5mTmFtZXNwYWNlTGlzdCA9IG90aGVyLmZOYW1lc3BhY2VMaXN0OwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIGludGVyc2VjdFdpbGRjYXJkOwotCi0gICAgfSAvLyBwZXJmb3JtSW50ZXJzZWN0aW9uV2l0aAotCi0gICAgcHJpdmF0ZSBib29sZWFuIGFyZVNhbWUoWFNXaWxkY2FyZERlY2wgd2lsZGNhcmQpIHsKLSAgICAgICAgaWYgKGZUeXBlID09IHdpbGRjYXJkLmZUeXBlKSB7Ci0gICAgICAgICAgICAvLyAjI2FueSwgdHJ1ZQotICAgICAgICAgICAgaWYgKGZUeXBlID09IE5TQ09OU1RSQUlOVF9BTlkpCi0gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0KLSAgICAgICAgICAgIC8vICMjb3RoZXIsIG9ubHkgY2hlY2sgdGhlIG5lZ2F0ZWQgdmFsdWUKLSAgICAgICAgICAgIC8vICogd2hlbiB3ZSBzdXBwb3J0IG5vdChsaXN0KSwgd2UgbmVlZCB0byBjaGVjayBpbiB0aGUgc2FtZSB3YXkKLSAgICAgICAgICAgIC8vICAgYXMgZm9yIE5TQ09OU1RSQUlOVF9MSVNULgotICAgICAgICAgICAgaWYgKGZUeXBlID09IE5TQ09OU1RSQUlOVF9OT1QpCi0gICAgICAgICAgICAgICAgcmV0dXJuIGZOYW1lc3BhY2VMaXN0WzBdID09IHdpbGRjYXJkLmZOYW1lc3BhY2VMaXN0WzBdOwotCi0gICAgICAgICAgICAvLyAjIyBsaXN0LCBtdXN0IGhhdmUgdGhlIHNhbWUgbGVuZ3RoLAotICAgICAgICAgICAgLy8gYW5kIGVhY2ggaXRlbSBpbiBvbmUgbGlzdCBtdXN0IGFwcGVhciBpbiB0aGUgb3RoZXIgb25lCi0gICAgICAgICAgICAvLyAod2UgYXJlIGFzc3VtaW5nIHRoYXQgdGhlcmUgYXJlIG5vIGR1cGxpY2F0ZSBpdGVtcyBpbiBhIGxpc3QpCi0gICAgICAgICAgICBpZiAoZk5hbWVzcGFjZUxpc3QubGVuZ3RoID09IHdpbGRjYXJkLmZOYW1lc3BhY2VMaXN0Lmxlbmd0aCkgewotICAgICAgICAgICAgICAgIGZvciAoaW50IGk9MDsgaTxmTmFtZXNwYWNlTGlzdC5sZW5ndGg7IGkrKykgewotICAgICAgICAgICAgICAgICAgICBpZiAoIWVsZW1lbnRJblNldChmTmFtZXNwYWNlTGlzdFtpXSwgd2lsZGNhcmQuZk5hbWVzcGFjZUxpc3QpKQotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9IC8vIGFyZVNhbWUKLQotICAgIFN0cmluZ1tdIGludGVyc2VjdDJzZXRzKFN0cmluZ1tdIG9uZSwgU3RyaW5nW10gdGhlT3RoZXIpewotICAgICAgICBTdHJpbmdbXSByZXN1bHQgPSBuZXcgU3RyaW5nW01hdGgubWluKG9uZS5sZW5ndGgsdGhlT3RoZXIubGVuZ3RoKV07Ci0KLSAgICAgICAgLy8gc2ltcGxlIGltcGxlbWVudGlvbiwKLSAgICAgICAgaW50IGNvdW50ID0gMDsKLSAgICAgICAgZm9yIChpbnQgaT0wOyBpPG9uZS5sZW5ndGg7IGkrKykgewotICAgICAgICAgICAgaWYgKGVsZW1lbnRJblNldChvbmVbaV0sIHRoZU90aGVyKSkKLSAgICAgICAgICAgICAgICByZXN1bHRbY291bnQrK10gPSBvbmVbaV07Ci0gICAgICAgIH0KLQotICAgICAgICBTdHJpbmdbXSByZXN1bHQyID0gbmV3IFN0cmluZ1tjb3VudF07Ci0gICAgICAgIFN5c3RlbS5hcnJheWNvcHkocmVzdWx0LCAwLCByZXN1bHQyLCAwLCBjb3VudCk7Ci0KLSAgICAgICAgcmV0dXJuIHJlc3VsdDI7Ci0gICAgfQotCi0gICAgU3RyaW5nW10gdW5pb24yc2V0cyhTdHJpbmdbXSBvbmUsIFN0cmluZ1tdIHRoZU90aGVyKXsKLSAgICAgICAgU3RyaW5nW10gcmVzdWx0MSA9IG5ldyBTdHJpbmdbb25lLmxlbmd0aF07Ci0KLSAgICAgICAgLy8gc2ltcGxlIGltcGxlbWVudGlvbiwKLSAgICAgICAgaW50IGNvdW50ID0gMDsKLSAgICAgICAgZm9yIChpbnQgaT0wOyBpPG9uZS5sZW5ndGg7IGkrKykgewotICAgICAgICAgICAgaWYgKCFlbGVtZW50SW5TZXQob25lW2ldLCB0aGVPdGhlcikpCi0gICAgICAgICAgICAgICAgcmVzdWx0MVtjb3VudCsrXSA9IG9uZVtpXTsKLSAgICAgICAgfQotCi0gICAgICAgIFN0cmluZ1tdIHJlc3VsdDIgPSBuZXcgU3RyaW5nW2NvdW50K3RoZU90aGVyLmxlbmd0aF07Ci0gICAgICAgIFN5c3RlbS5hcnJheWNvcHkocmVzdWx0MSwgMCwgcmVzdWx0MiwgMCwgY291bnQpOwotICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHRoZU90aGVyLCAwLCByZXN1bHQyLCBjb3VudCwgdGhlT3RoZXIubGVuZ3RoKTsKLQotICAgICAgICByZXR1cm4gcmVzdWx0MjsKLSAgICB9Ci0KLSAgICBib29sZWFuIHN1YnNldDJzZXRzKFN0cmluZ1tdIHN1YlNldCwgU3RyaW5nW10gc3VwZXJTZXQpewotICAgICAgICBmb3IgKGludCBpPTA7IGk8c3ViU2V0Lmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICBpZiAoIWVsZW1lbnRJblNldChzdWJTZXRbaV0sIHN1cGVyU2V0KSkKLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICB9Ci0KLSAgICBib29sZWFuIGVsZW1lbnRJblNldChTdHJpbmcgZWxlLCBTdHJpbmdbXSBzZXQpewotICAgICAgICBib29sZWFuIGZvdW5kID0gZmFsc2U7Ci0gICAgICAgIGZvciAoaW50IGk9MDsgaTxzZXQubGVuZ3RoICYmICFmb3VuZDsgaSsrKSB7Ci0gICAgICAgICAgICBpZiAoZWxlPT1zZXRbaV0pCi0gICAgICAgICAgICAgICAgZm91bmQgPSB0cnVlOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIGZvdW5kOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIGdldCB0aGUgc3RyaW5nIGRlc2NyaXB0aW9uIG9mIHRoaXMgd2lsZGNhcmQKLSAgICAgKi8KLSAgICBwcml2YXRlIFN0cmluZyBmRGVzY3JpcHRpb24gPSBudWxsOwotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0gICAgICAgIGlmIChmRGVzY3JpcHRpb24gPT0gbnVsbCkgewotICAgICAgICAgICAgU3RyaW5nQnVmZmVyIGJ1ZmZlciA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLSAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoIldDWyIpOwotICAgICAgICAgICAgc3dpdGNoIChmVHlwZSkgewotICAgICAgICAgICAgY2FzZSBOU0NPTlNUUkFJTlRfQU5ZOgotICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoU2NoZW1hU3ltYm9scy5BVFRWQUxfVFdPUE9VTkRBTlkpOwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgY2FzZSBOU0NPTlNUUkFJTlRfTk9UOgotICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoU2NoZW1hU3ltYm9scy5BVFRWQUxfVFdPUE9VTkRPVEhFUik7Ci0gICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgiOlwiIik7Ci0gICAgICAgICAgICAgICAgaWYgKGZOYW1lc3BhY2VMaXN0WzBdICE9IG51bGwpCi0gICAgICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoZk5hbWVzcGFjZUxpc3RbMF0pOwotICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoIlwiIik7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICBjYXNlIE5TQ09OU1RSQUlOVF9MSVNUOgotICAgICAgICAgICAgICAgIGlmIChmTmFtZXNwYWNlTGlzdC5sZW5ndGggPT0gMCkKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgiXCIiKTsKLSAgICAgICAgICAgICAgICBpZiAoZk5hbWVzcGFjZUxpc3RbMF0gIT0gbnVsbCkKLSAgICAgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZChmTmFtZXNwYWNlTGlzdFswXSk7Ci0gICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgiXCIiKTsKLSAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMTsgaSA8IGZOYW1lc3BhY2VMaXN0Lmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoIixcIiIpOwotICAgICAgICAgICAgICAgICAgICBpZiAoZk5hbWVzcGFjZUxpc3RbaV0gIT0gbnVsbCkKLSAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoZk5hbWVzcGFjZUxpc3RbaV0pOwotICAgICAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCJcIiIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoJ10nKTsKLSAgICAgICAgICAgIGZEZXNjcmlwdGlvbiA9IGJ1ZmZlci50b1N0cmluZygpOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIGZEZXNjcmlwdGlvbjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIHR5cGUgb2YgdGhlIG9iamVjdCwgaS5lIEVMRU1FTlRfREVDTEFSQVRJT04uCi0gICAgICovCi0gICAgcHVibGljIHNob3J0IGdldFR5cGUoKSB7Ci0gICAgICAgIHJldHVybiBYU0NvbnN0YW50cy5XSUxEQ0FSRDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgPGNvZGU+bmFtZTwvY29kZT4gb2YgdGhpcyA8Y29kZT5YU09iamVjdDwvY29kZT4gZGVwZW5kaW5nIG9uIHRoZQotICAgICAqIDxjb2RlPlhTT2JqZWN0PC9jb2RlPiB0eXBlLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhlIG5hbWVzcGFjZSBVUkkgb2YgdGhpcyBub2RlLCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiBpdCBpcwotICAgICAqIHVuc3BlY2lmaWVkLiAgZGVmaW5lcyBob3cgYSBuYW1lc3BhY2UgVVJJIGlzIGF0dGFjaGVkIHRvIHNjaGVtYQotICAgICAqIGNvbXBvbmVudHMuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXROYW1lc3BhY2UoKSB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIE5hbWVzcGFjZSBjb25zdHJhaW50OiBBIGNvbnN0cmFpbnQgdHlwZTogYW55LCBub3QsIGxpc3QuCi0gICAgICovCi0gICAgcHVibGljIHNob3J0IGdldENvbnN0cmFpbnRUeXBlKCkgewotICAgICAgICByZXR1cm4gZlR5cGU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogTmFtZXNwYWNlIGNvbnN0cmFpbnQuIEZvciA8Y29kZT5jb25zdHJhaW50VHlwZTwvY29kZT4KLSAgICAgKiBMSVNUX05TQ09OU1RSQUlOVCwgdGhlIGxpc3QgY29udGFpbnMgYWxsb3dlZCBuYW1lc3BhY2VzLiBGb3IKLSAgICAgKiA8Y29kZT5jb25zdHJhaW50VHlwZTwvY29kZT4gTk9UX05TQ09OU1RSQUlOVCwgdGhlIGxpc3QgY29udGFpbnMKLSAgICAgKiBkaXNhbGxvd2VkIG5hbWVzcGFjZXMuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZ0xpc3QgZ2V0TnNDb25zdHJhaW50TGlzdCgpIHsKLSAgICAgICAgcmV0dXJuIG5ldyBTdHJpbmdMaXN0SW1wbChmTmFtZXNwYWNlTGlzdCwgZk5hbWVzcGFjZUxpc3QgPT0gbnVsbCA/IDAgOiBmTmFtZXNwYWNlTGlzdC5sZW5ndGgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIHtwcm9jZXNzIGNvbnRlbnRzfSBPbmUgb2Ygc2tpcCwgbGF4IG9yIHN0cmljdC4gVmFsaWQgY29uc3RhbnRzIHZhbHVlcwotICAgICAqIGFyZTogUENfU0tJUCwgUENfTEFYLCBQQ19TVFJJQ1QuCi0gICAgICovCi0gICAgcHVibGljIHNob3J0IGdldFByb2Nlc3NDb250ZW50cygpIHsKLSAgICAgICAgcmV0dXJuIGZQcm9jZXNzQ29udGVudHM7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU3RyaW5nIHZhbGlkIG9mIHtwcm9jZXNzIGNvbnRlbnRzfS4gT25lIG9mICJza2lwIiwgImxheCIgb3IgInN0cmljdCIuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRQcm9jZXNzQ29udGVudHNBc1N0cmluZygpIHsKLSAgICAgICAgc3dpdGNoIChmUHJvY2Vzc0NvbnRlbnRzKSB7Ci0gICAgICAgICAgICBjYXNlIFhTV2lsZGNhcmREZWNsLlBDX1NLSVA6IHJldHVybiAic2tpcCI7Ci0gICAgICAgICAgICBjYXNlIFhTV2lsZGNhcmREZWNsLlBDX0xBWDogcmV0dXJuICJsYXgiOwotICAgICAgICAgICAgY2FzZSBYU1dpbGRjYXJkRGVjbC5QQ19TVFJJQ1Q6IHJldHVybiAic3RyaWN0IjsKLSAgICAgICAgICAgIGRlZmF1bHQ6IHJldHVybiAiaW52YWxpZCB2YWx1ZSI7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBPcHRpb25hbC4gQW5ub3RhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFNBbm5vdGF0aW9uIGdldEFubm90YXRpb24oKSB7Ci0gICAgICAgIHJldHVybiAoZkFubm90YXRpb25zICE9IG51bGwpID8gKFhTQW5ub3RhdGlvbikgZkFubm90YXRpb25zLml0ZW0oMCkgOiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIE9wdGlvbmFsLiBBbm5vdGF0aW9ucy4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFNPYmplY3RMaXN0IGdldEFubm90YXRpb25zKCkgewotICAgICAgICByZXR1cm4gKGZBbm5vdGF0aW9ucyAhPSBudWxsKSA/IGZBbm5vdGF0aW9ucyA6IFhTT2JqZWN0TGlzdEltcGwuRU1QVFlfTElTVDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAc2VlIG9yZy5hcGFjaGUueGVyY2VzLnhzLlhTT2JqZWN0I2dldE5hbWVzcGFjZUl0ZW0oKQotICAgICAqLwotICAgIHB1YmxpYyBYU05hbWVzcGFjZUl0ZW0gZ2V0TmFtZXNwYWNlSXRlbSgpIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi19IC8vIGNsYXNzIFhTV2lsZGNhcmREZWNsCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL2lkZW50aXR5L0ZpZWxkLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL2lkZW50aXR5L0ZpZWxkLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGNhOTY4ZjguLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9pZGVudGl0eS9GaWVsZC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjQ5ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLmlkZW50aXR5OwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhwYXRoLlhQYXRoRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy51dGlsLlNob3J0TGlzdEltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlN5bWJvbFRhYmxlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLk5hbWVzcGFjZUNvbnRleHQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5TaG9ydExpc3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU0NvbXBsZXhUeXBlRGVmaW5pdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNUeXBlRGVmaW5pdGlvbjsKLQotLyoqCi0gKiBTY2hlbWEgaWRlbnRpdHkgY29uc3RyYWludCBmaWVsZC4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBBbmR5IENsYXJrLCBJQk0KLSAqIEB2ZXJzaW9uICRJZDogRmllbGQuamF2YSx2IDEuNiAyMDEwLTExLTAxIDA0OjM5OjU3IGpvZWh3IEV4cCAkCi0gKi8KLXB1YmxpYyBjbGFzcyBGaWVsZCB7Ci0KLSAgICAvLwotICAgIC8vIERhdGEKLSAgICAvLwotCi0gICAgLyoqIEZpZWxkIFhQYXRoLiAqLwotICAgIHByb3RlY3RlZCBGaWVsZC5YUGF0aCBmWFBhdGg7Ci0KLQotICAgIC8qKiBJZGVudGl0eSBjb25zdHJhaW50LiAqLwotICAgIHByb3RlY3RlZCBJZGVudGl0eUNvbnN0cmFpbnQgZklkZW50aXR5Q29uc3RyYWludDsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKiBDb25zdHJ1Y3RzIGEgZmllbGQuICovCi0gICAgcHVibGljIEZpZWxkKEZpZWxkLlhQYXRoIHhwYXRoLAotICAgICAgICAgICAgICAgICBJZGVudGl0eUNvbnN0cmFpbnQgaWRlbnRpdHlDb25zdHJhaW50KSB7Ci0gICAgICAgIGZYUGF0aCA9IHhwYXRoOwotICAgICAgICBmSWRlbnRpdHlDb25zdHJhaW50ID0gaWRlbnRpdHlDb25zdHJhaW50OwotICAgIH0gLy8gPGluaXQ+KEZpZWxkLlhQYXRoLElkZW50aXR5Q29uc3RyYWludCkKLQotICAgIC8vCi0gICAgLy8gUHVibGljIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqIFJldHVybnMgdGhlIGZpZWxkIFhQYXRoLiAqLwotICAgIHB1YmxpYyBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHBhdGguWFBhdGggZ2V0WFBhdGgoKSB7Ci0gICAgICAgIHJldHVybiBmWFBhdGg7Ci0gICAgfSAvLyBnZXRYUGF0aCgpOmNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC52MS5zY2hlbWEuaWRlbnRpdHkuWFBhdGgKLQotICAgIC8qKiBSZXR1cm5zIHRoZSBpZGVudGl0eSBjb25zdHJhaW50LiAqLwotICAgIHB1YmxpYyBJZGVudGl0eUNvbnN0cmFpbnQgZ2V0SWRlbnRpdHlDb25zdHJhaW50KCkgewotICAgICAgICByZXR1cm4gZklkZW50aXR5Q29uc3RyYWludDsKLSAgICB9IC8vIGdldElkZW50aXR5Q29uc3RyYWludCgpOklkZW50aXR5Q29uc3RyYWludAotCi0gICAgLy8gZmFjdG9yeSBtZXRob2QKLQotICAgIC8qKiBDcmVhdGVzIGEgZmllbGQgbWF0Y2hlci4gKi8KLSAgICBwdWJsaWMgWFBhdGhNYXRjaGVyIGNyZWF0ZU1hdGNoZXIoRmllbGRBY3RpdmF0b3IgYWN0aXZhdG9yLCBWYWx1ZVN0b3JlIHN0b3JlKSB7Ci0gICAgICAgIHJldHVybiBuZXcgRmllbGQuTWF0Y2hlcihmWFBhdGgsIGFjdGl2YXRvciwgc3RvcmUpOwotICAgIH0gLy8gY3JlYXRlTWF0Y2hlcihWYWx1ZVN0b3JlKTpYUGF0aE1hdGNoZXIKLQotICAgIC8vCi0gICAgLy8gT2JqZWN0IG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBvYmplY3QuICovCi0gICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKLSAgICAgICAgcmV0dXJuIGZYUGF0aC50b1N0cmluZygpOwotICAgIH0gLy8gdG9TdHJpbmcoKTpTdHJpbmcKLQotICAgIC8vCi0gICAgLy8gQ2xhc3NlcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBGaWVsZCBYUGF0aC4KLSAgICAgKgotICAgICAqIEBhdXRob3IgQW5keSBDbGFyaywgSUJNCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBjbGFzcyBYUGF0aAotICAgICAgICBleHRlbmRzIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cGF0aC5YUGF0aCB7Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gQ29uc3RydWN0b3JzCi0gICAgICAgIC8vCi0KLSAgICAgICAgLyoqIENvbnN0cnVjdHMgYSBmaWVsZCBYUGF0aCBleHByZXNzaW9uLiAqLwotICAgICAgICBwdWJsaWMgWFBhdGgoU3RyaW5nIHhwYXRoLAotICAgICAgICAgICAgICAgICAgICAgU3ltYm9sVGFibGUgc3ltYm9sVGFibGUsCi0gICAgICAgICAgICAgICAgICAgICBOYW1lc3BhY2VDb250ZXh0IGNvbnRleHQpIHRocm93cyBYUGF0aEV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICAvLyBOT1RFOiBXZSBoYXZlIHRvIHByZWZpeCB0aGUgZmllbGQgWFBhdGggd2l0aCAiLi8iIGluCi0gICAgICAgICAgICAvLyAgICAgICBvcmRlciB0byBoYW5kbGUgc2VsZWN0b3JzIHN1Y2ggYXMgIkBhdHRyIiB0aGF0Ci0gICAgICAgICAgICAvLyAgICAgICBzZWxlY3QgdGhlIGF0dHJpYnV0ZSBiZWNhdXNlIHRoZSBmaWVsZHMgY291bGQgYmUKLSAgICAgICAgICAgIC8vICAgICAgIHJlbGF0aXZlIHRvIHRoZSBzZWxlY3RvciBlbGVtZW50LiAtQWMKLSAgICAgICAgICAgIC8vICAgICAgIFVubGVzcyB4cGF0aCBzdGFydHMgd2l0aCBhIGRlc2NlbmRhbnQgbm9kZSAtQWNoaWxsZSBGb2tvdWUKLSAgICAgICAgICAgIC8vICAgICAgLi4uIG9yIGEgLyBvciBhIC4gLSBORwotICAgICAgICAgICAgc3VwZXIoKCh4cGF0aC50cmltKCkuc3RhcnRzV2l0aCgiLyIpIHx8eHBhdGgudHJpbSgpLnN0YXJ0c1dpdGgoIi4iKSk/Ci0gICAgICAgICAgICAgICAgICAgIHhwYXRoOiIuLyIreHBhdGgpLAotICAgICAgICAgICAgICAgICAgc3ltYm9sVGFibGUsIGNvbnRleHQpOwotCi0gICAgICAgICAgICAvLyB2ZXJpZnkgdGhhdCBvbmx5IG9uZSBhdHRyaWJ1dGUgaXMgc2VsZWN0ZWQgcGVyIGJyYW5jaAotICAgICAgICAgICAgZm9yIChpbnQgaT0wO2k8ZkxvY2F0aW9uUGF0aHMubGVuZ3RoO2krKykgewotICAgICAgICAgICAgICAgIGZvcihpbnQgaj0wOyBqPGZMb2NhdGlvblBhdGhzW2ldLnN0ZXBzLmxlbmd0aDsgaisrKSB7Ci0gICAgICAgICAgICAgICAgICAgIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cGF0aC5YUGF0aC5BeGlzIGF4aXMgPQotICAgICAgICAgICAgICAgICAgICAgICAgZkxvY2F0aW9uUGF0aHNbaV0uc3RlcHNbal0uYXhpczsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGF4aXMudHlwZSA9PSBYUGF0aC5BeGlzLkFUVFJJQlVURSAmJgotICAgICAgICAgICAgICAgICAgICAgICAgICAgIChqIDwgZkxvY2F0aW9uUGF0aHNbaV0uc3RlcHMubGVuZ3RoLTEpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWFBhdGhFeGNlcHRpb24oImMtZmllbGRzLXhwYXRocyIpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9IC8vIDxpbml0PihTdHJpbmcsU3ltYm9sVGFibGUsTmFtZXNwYWNlc0NvbnRleHQpCi0KLSAgICB9IC8vIGNsYXNzIFhQYXRoCi0KLSAgICAvKioKLSAgICAgKiBGaWVsZCBtYXRjaGVyLgotICAgICAqCi0gICAgICogQGF1dGhvciBBbmR5IENsYXJrLCBJQk0KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgY2xhc3MgTWF0Y2hlcgotICAgICAgICBleHRlbmRzIFhQYXRoTWF0Y2hlciB7Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gRGF0YQotICAgICAgICAvLwotCi0gICAgICAgIC8qKiBGaWVsZCBhY3RpdmF0b3IuICovCi0gICAgICAgIHByb3RlY3RlZCBGaWVsZEFjdGl2YXRvciBmRmllbGRBY3RpdmF0b3I7Ci0KLSAgICAgICAgLyoqIFZhbHVlIHN0b3JlIGZvciBkYXRhIHZhbHVlcy4gKi8KLSAgICAgICAgcHJvdGVjdGVkIFZhbHVlU3RvcmUgZlN0b3JlOwotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIENvbnN0cnVjdG9ycwotICAgICAgICAvLwotCi0gICAgICAgIC8qKiBDb25zdHJ1Y3RzIGEgZmllbGQgbWF0Y2hlci4gKi8KLSAgICAgICAgcHVibGljIE1hdGNoZXIoRmllbGQuWFBhdGggeHBhdGgsIEZpZWxkQWN0aXZhdG9yIGFjdGl2YXRvciwgVmFsdWVTdG9yZSBzdG9yZSkgewotICAgICAgICAgICAgc3VwZXIoeHBhdGgpOwotICAgICAgICAgICAgZkZpZWxkQWN0aXZhdG9yID0gYWN0aXZhdG9yOwotICAgICAgICAgICAgZlN0b3JlID0gc3RvcmU7Ci0gICAgICAgIH0gLy8gPGluaXQ+KEZpZWxkLlhQYXRoLFZhbHVlU3RvcmUpCi0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gWFBhdGhIYW5kbGVyIG1ldGhvZHMKLSAgICAgICAgLy8KLQotICAgICAgICAvKioKLSAgICAgICAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIHdoZW4gdGhlIFhQYXRoIGhhbmRsZXIgbWF0Y2hlcyB0aGUKLSAgICAgICAgICogWFBhdGggZXhwcmVzc2lvbi4KLSAgICAgICAgICovCi0gICAgICAgIHByb3RlY3RlZCB2b2lkIG1hdGNoZWQoT2JqZWN0IGFjdHVhbFZhbHVlLCBzaG9ydCB2YWx1ZVR5cGUsIFNob3J0TGlzdCBpdGVtVmFsdWVUeXBlLCBib29sZWFuIGlzTmlsKSB7Ci0gICAgICAgICAgICBzdXBlci5tYXRjaGVkKGFjdHVhbFZhbHVlLCB2YWx1ZVR5cGUsIGl0ZW1WYWx1ZVR5cGUsIGlzTmlsKTsKLSAgICAgICAgICAgIGlmKGlzTmlsICYmIChmSWRlbnRpdHlDb25zdHJhaW50LmdldENhdGVnb3J5KCkgPT0gSWRlbnRpdHlDb25zdHJhaW50LklDX0tFWSkpIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgY29kZSA9ICJLZXlNYXRjaGVzTmlsbGFibGUiOwotICAgICAgICAgICAgICAgIGZTdG9yZS5yZXBvcnRFcnJvcihjb2RlLAotICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117ZklkZW50aXR5Q29uc3RyYWludC5nZXRFbGVtZW50TmFtZSgpLCBmSWRlbnRpdHlDb25zdHJhaW50LmdldElkZW50aXR5Q29uc3RyYWludE5hbWUoKX0pOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZlN0b3JlLmFkZFZhbHVlKEZpZWxkLnRoaXMsIGFjdHVhbFZhbHVlLCBjb252ZXJ0VG9QcmltaXRpdmVLaW5kKHZhbHVlVHlwZSksIGNvbnZlcnRUb1ByaW1pdGl2ZUtpbmQoaXRlbVZhbHVlVHlwZSkpOwotICAgICAgICAgICAgLy8gb25jZSB3ZSd2ZSBzdG9yZWQgdGhlIHZhbHVlIGZvciB0aGlzIGZpZWxkLCB3ZSBzZXQgdGhlIG1heU1hdGNoCi0gICAgICAgICAgICAvLyBtZW1iZXIgdG8gZmFsc2Ugc28gdGhhdCwgaW4gdGhlIHNhbWUgc2NvcGUsIHdlIGRvbid0IG1hdGNoIGFueSBtb3JlCi0gICAgICAgICAgICAvLyB2YWx1ZXMgKGFuZCB0aHJvdyBhbiBlcnJvciBpbnN0ZWFkKS4KLSAgICAgICAgICAgIGZGaWVsZEFjdGl2YXRvci5zZXRNYXlNYXRjaChGaWVsZC50aGlzLCBCb29sZWFuLkZBTFNFKTsKLSAgICAgICAgfSAvLyBtYXRjaGVkKFN0cmluZykKLQotICAgICAgICBwcml2YXRlIHNob3J0IGNvbnZlcnRUb1ByaW1pdGl2ZUtpbmQoc2hvcnQgdmFsdWVUeXBlKSB7Ci0gICAgICAgICAgICAvKiogUHJpbWl0aXZlIGRhdGF0eXBlcy4gKi8KLSAgICAgICAgICAgIGlmICh2YWx1ZVR5cGUgPD0gWFNDb25zdGFudHMuTk9UQVRJT05fRFQpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWVUeXBlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLyoqIFR5cGVzIGRlcml2ZWQgZnJvbSBzdHJpbmcuICovCi0gICAgICAgICAgICBpZiAodmFsdWVUeXBlIDw9IFhTQ29uc3RhbnRzLkVOVElUWV9EVCkgewotICAgICAgICAgICAgICAgIHJldHVybiBYU0NvbnN0YW50cy5TVFJJTkdfRFQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvKiogVHlwZXMgZGVyaXZlZCBmcm9tIGRlY2ltYWwuICovCi0gICAgICAgICAgICBpZiAodmFsdWVUeXBlIDw9IFhTQ29uc3RhbnRzLlBPU0lUSVZFSU5URUdFUl9EVCkgewotICAgICAgICAgICAgICAgIHJldHVybiBYU0NvbnN0YW50cy5ERUNJTUFMX0RUOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLyoqIE90aGVyIHR5cGVzLiAqLwotICAgICAgICAgICAgcmV0dXJuIHZhbHVlVHlwZTsKLSAgICAgICAgfQotCi0gICAgICAgIHByaXZhdGUgU2hvcnRMaXN0IGNvbnZlcnRUb1ByaW1pdGl2ZUtpbmQoU2hvcnRMaXN0IGl0ZW1WYWx1ZVR5cGUpIHsKLSAgICAgICAgICAgIGlmIChpdGVtVmFsdWVUeXBlICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBpbnQgaTsKLSAgICAgICAgICAgICAgICBmaW5hbCBpbnQgbGVuZ3RoID0gaXRlbVZhbHVlVHlwZS5nZXRMZW5ndGgoKTsKLSAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbGVuZ3RoOyArK2kpIHsKLSAgICAgICAgICAgICAgICAgICAgc2hvcnQgdHlwZSA9IGl0ZW1WYWx1ZVR5cGUuaXRlbShpKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGUgIT0gY29udmVydFRvUHJpbWl0aXZlS2luZCh0eXBlKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaWYgKGkgIT0gbGVuZ3RoKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZpbmFsIHNob3J0IFtdIGFyciA9IG5ldyBzaG9ydFtsZW5ndGhdOwotICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IGk7ICsraikgewotICAgICAgICAgICAgICAgICAgICAgICAgYXJyW2pdID0gaXRlbVZhbHVlVHlwZS5pdGVtKGopOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGZvcig7IGkgPCBsZW5ndGg7ICsraSkgewotICAgICAgICAgICAgICAgICAgICAgICAgYXJyW2ldID0gY29udmVydFRvUHJpbWl0aXZlS2luZChpdGVtVmFsdWVUeXBlLml0ZW0oaSkpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgU2hvcnRMaXN0SW1wbChhcnIsIGFyci5sZW5ndGgpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiBpdGVtVmFsdWVUeXBlOwotICAgICAgICB9Ci0KLSAgICAgICAgcHJvdGVjdGVkIHZvaWQgaGFuZGxlQ29udGVudChYU1R5cGVEZWZpbml0aW9uIHR5cGUsIGJvb2xlYW4gbmlsbGFibGUsIE9iamVjdCBhY3R1YWxWYWx1ZSwgc2hvcnQgdmFsdWVUeXBlLCBTaG9ydExpc3QgaXRlbVZhbHVlVHlwZSkgewotICAgICAgICAgICAgaWYgKHR5cGUgPT0gbnVsbCB8fAotICAgICAgICAgICAgICAgdHlwZS5nZXRUeXBlQ2F0ZWdvcnkoKSA9PSBYU1R5cGVEZWZpbml0aW9uLkNPTVBMRVhfVFlQRSAmJgotICAgICAgICAgICAgICAgKChYU0NvbXBsZXhUeXBlRGVmaW5pdGlvbikgdHlwZSkuZ2V0Q29udGVudFR5cGUoKQotICAgICAgICAgICAgICAgICE9IFhTQ29tcGxleFR5cGVEZWZpbml0aW9uLkNPTlRFTlRUWVBFX1NJTVBMRSkgewotCi0gICAgICAgICAgICAgICAgICAgIC8vIHRoZSBjb250ZW50IG11c3QgYmUgc2ltcGxlVHlwZSBjb250ZW50Ci0gICAgICAgICAgICAgICAgICAgIGZTdG9yZS5yZXBvcnRFcnJvciggImN2Yy1pZC4zIiwgbmV3IE9iamVjdFtdIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmSWRlbnRpdHlDb25zdHJhaW50LmdldE5hbWUoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmSWRlbnRpdHlDb25zdHJhaW50LmdldEVsZW1lbnROYW1lKCl9KTsKLQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZk1hdGNoZWRTdHJpbmcgPSBhY3R1YWxWYWx1ZTsKLSAgICAgICAgICAgIG1hdGNoZWQoZk1hdGNoZWRTdHJpbmcsIHZhbHVlVHlwZSwgaXRlbVZhbHVlVHlwZSwgbmlsbGFibGUpOwotICAgICAgICB9IC8vIGhhbmRsZUNvbnRlbnQoWFNFbGVtZW50RGVjbCwgU3RyaW5nKQotCi0gICAgfSAvLyBjbGFzcyBNYXRjaGVyCi0KLX0gLy8gY2xhc3MgRmllbGQKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvaWRlbnRpdHkvRmllbGRBY3RpdmF0b3IuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvaWRlbnRpdHkvRmllbGRBY3RpdmF0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZmE1YmQwNS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL2lkZW50aXR5L0ZpZWxkQWN0aXZhdG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4OCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLDIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLmlkZW50aXR5OwotCi0KLS8qKgotICogSW50ZXJmYWNlIGZvciBhIGZpZWxkIGFjdGl2YXRvci4gVGhlIGZpZWxkIGFjdGl2YXRvciBpcyByZXNwb25zaWJsZQotICogZm9yIGFjdGl2YXRpbmcgZmllbGRzIHdpdGhpbiBhIHNwZWNpZmljIHNjb3BlOyB0aGUgY2FsbGVyIG1lcmVseQotICogcmVxdWVzdHMgdGhlIGZpZWxkcyB0byBiZSBhY3RpdmF0ZWQuCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgQW5keSBDbGFyaywgSUJNCi0gKgotICovCi1wdWJsaWMgaW50ZXJmYWNlIEZpZWxkQWN0aXZhdG9yIHsKLQotICAgIC8vCi0gICAgLy8gRmllbGRBY3RpdmF0b3IgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBTdGFydCB0aGUgdmFsdWUgc2NvcGUgZm9yIHRoZSBzcGVjaWZpZWQgaWRlbnRpdHkgY29uc3RyYWludC4gVGhpcwotICAgICAqIG1ldGhvZCBpcyBjYWxsZWQgd2hlbiB0aGUgc2VsZWN0b3IgbWF0Y2hlcyBpbiBvcmRlciB0byBpbml0aWFsaXplCi0gICAgICogdGhlIHZhbHVlIHN0b3JlLgotICAgICAqCi0gICAgICogQHBhcmFtIGlkZW50aXR5Q29uc3RyYWludCBUaGUgaWRlbnRpdHkgY29uc3RyYWludC4KLSAgICAgKiBAcGFyYW0gaW5pdGlhbERlcHRoICB0aGUgZGVwdGggYXQgd2hpY2ggdGhlIHNlbGVjdG9yIGJlZ2FuIG1hdGNoaW5nCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnRWYWx1ZVNjb3BlRm9yKElkZW50aXR5Q29uc3RyYWludCBpZGVudGl0eUNvbnN0cmFpbnQsCi0gICAgICAgICAgICBpbnQgaW5pdGlhbERlcHRoKTsKLQotICAgIC8qKgotICAgICAqIFJlcXVlc3QgdG8gYWN0aXZhdGUgdGhlIHNwZWNpZmllZCBmaWVsZC4gVGhpcyBtZXRob2QgcmV0dXJucyB0aGUKLSAgICAgKiBtYXRjaGVyIGZvciB0aGUgZmllbGQuCi0gICAgICogSXQncyBhbHNvIGltcG9ydGFudCBmb3IgdGhlIGltcGxlbWVudG9yIHRvIGVuc3VyZSB0aGF0IGl0IG1hcmtzIHdoZXRoZXIgYSBGaWVsZAotICAgICAqIGlzIHBlcm1pdHRlZCB0byBtYXRjaCBhIHZhbHVlLS10aGF0IGlzLCB0byBjYWxsIHRoZSBzZXRNYXlNYXRjaChGaWVsZCwgQm9vbGVhbikgbWV0aG9kLgotICAgICAqCi0gICAgICogQHBhcmFtIGZpZWxkIFRoZSBmaWVsZCB0byBhY3RpdmF0ZS4KLSAgICAgKiBAcGFyYW0gaW5pdGlhbERlcHRoIHRoZSAwLWluZGV4ZWQgZGVwdGggaW4gdGhlIGluc3RhbmNlIGRvY3VtZW50IGF0IHdoaWNoIHRoZSBTZWxlY3RvciBiZWdhbiB0byBtYXRjaC4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFBhdGhNYXRjaGVyIGFjdGl2YXRlRmllbGQoRmllbGQgZmllbGQsIGludCBpbml0aWFsRGVwdGgpOwotCi0gICAgLyoqCi0gICAgICogU2V0cyB3aGV0aGVyIHRoZSBnaXZlbiBmaWVsZCBpcyBwZXJtaXR0ZWQgdG8gbWF0Y2ggYSB2YWx1ZS4KLSAgICAgKiBUaGlzIHNob3VsZCBiZSB1c2VkIHRvIGNhdGNoIGluc3RhbmNlIGRvY3VtZW50cyB0aGF0IHRyeQotICAgICAqIGFuZCBtYXRjaCBhIGZpZWxkIHNldmVyYWwgdGltZXMgaW4gdGhlIHNhbWUgc2NvcGUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZmllbGQgVGhlIGZpZWxkIHRoYXQgbWF5IGJlIHBlcm1pdHRlZCB0byBiZSBtYXRjaGVkLgotICAgICAqIEBwYXJhbSBzdGF0ZSBCb29sZWFuIGluZGljaWF0aW5nIHdoZXRoZXIgdGhlIGZpZWxkIG1heSBiZSBtYXRjaGVkLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldE1heU1hdGNoKEZpZWxkIGZpZWxkLCBCb29sZWFuIHN0YXRlKTsKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgd2hldGhlciB0aGUgZ2l2ZW4gZmllbGQgaXMgcGVybWl0dGVkIHRvIG1hdGNoIGEgdmFsdWUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZmllbGQgVGhlIGZpZWxkIHRoYXQgbWF5IGJlIHBlcm1pdHRlZCB0byBiZSBtYXRjaGVkLgotICAgICAqIEByZXR1cm4gQm9vbGVhbiBpbmRpY2F0aW5nIHdoZXRoZXIgdGhlIGZpZWxkIG1heSBiZSBtYXRjaGVkLgotICAgICAqLwotICAgIHB1YmxpYyBCb29sZWFuIG1heU1hdGNoKEZpZWxkIGZpZWxkKTsKLQotICAgIC8qKgotICAgICAqIEVuZHMgdGhlIHZhbHVlIHNjb3BlIGZvciB0aGUgc3BlY2lmaWVkIGlkZW50aXR5IGNvbnN0cmFpbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaWRlbnRpdHlDb25zdHJhaW50IFRoZSBpZGVudGl0eSBjb25zdHJhaW50LgotICAgICAqIEBwYXJhbSBpbml0aWFsRGVwdGggIHRoZSAwLWluZGV4ZWQgZGVwdGggd2hlcmUgdGhlIFNlbGVjdG9yIGJlZ2FuIHRvIG1hdGNoLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZFZhbHVlU2NvcGVGb3IoSWRlbnRpdHlDb25zdHJhaW50IGlkZW50aXR5Q29uc3RyYWludCwgaW50IGluaXRpYWxEZXB0aCk7Ci0KLX0gLy8gaW50ZXJmYWNlIEZpZWxkQWN0aXZhdG9yCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL2lkZW50aXR5L0lkZW50aXR5Q29uc3RyYWludC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9pZGVudGl0eS9JZGVudGl0eUNvbnN0cmFpbnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZDYyZGMwNS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL2lkZW50aXR5L0lkZW50aXR5Q29uc3RyYWludC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjUwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLmlkZW50aXR5OwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU0lEQ0RlZmluaXRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5TdHJpbmdMaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNOYW1lc3BhY2VJdGVtOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNPYmplY3RMaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNDb25zdGFudHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLnV0aWwuU3RyaW5nTGlzdEltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLnV0aWwuWFNPYmplY3RMaXN0SW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMuWFNBbm5vdGF0aW9uSW1wbDsKLQotLyoqCi0gKiBCYXNlIGNsYXNzIG9mIFNjaGVtYSBpZGVudGl0eSBjb25zdHJhaW50LgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIEFuZHkgQ2xhcmssIElCTQotICovCi1wdWJsaWMgYWJzdHJhY3QgY2xhc3MgSWRlbnRpdHlDb25zdHJhaW50IGltcGxlbWVudHMgWFNJRENEZWZpbml0aW9uIHsKLQotICAgIC8vCi0gICAgLy8gRGF0YQotICAgIC8vCi0KLSAgICAvKiogdHlwZSAqLwotICAgIHByb3RlY3RlZCBzaG9ydCB0eXBlOwotCi0gICAgLyoqIHRhcmdldCBuYW1lc3BhY2UgKi8KLSAgICBwcm90ZWN0ZWQgU3RyaW5nIGZOYW1lc3BhY2U7Ci0KLSAgICAvKiogSWRlbnRpdHkgY29uc3RyYWludCBuYW1lLiAqLwotICAgIHByb3RlY3RlZCBTdHJpbmcgZklkZW50aXR5Q29uc3RyYWludE5hbWU7Ci0KLSAgICAvKiogbmFtZSBvZiBvd25pbmcgZWxlbWVudCAqLwotICAgIHByb3RlY3RlZCBTdHJpbmcgZkVsZW1lbnROYW1lOwotCi0gICAgLyoqIFNlbGVjdG9yLiAqLwotICAgIHByb3RlY3RlZCBTZWxlY3RvciBmU2VsZWN0b3I7Ci0KLSAgICAvKiogRmllbGQgY291bnQuICovCi0gICAgcHJvdGVjdGVkIGludCBmRmllbGRDb3VudDsKLQotICAgIC8qKiBGaWVsZHMuICovCi0gICAgcHJvdGVjdGVkIEZpZWxkW10gZkZpZWxkczsKLQotICAgIC8vIG9wdGlvbmFsIGFubm90YXRpb25zCi0gICAgcHJvdGVjdGVkIFhTQW5ub3RhdGlvbkltcGwgW10gZkFubm90YXRpb25zID0gbnVsbDsKLQotICAgIC8vIG51bWJlciBvZiBhbm5vdGF0aW9ucyBpbiB0aGlzIGlkZW50aXR5IGNvbnN0cmFpbnQKLSAgICBwcm90ZWN0ZWQgaW50IGZOdW1Bbm5vdGF0aW9uczsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKiBEZWZhdWx0IGNvbnN0cnVjdG9yLiAqLwotICAgIHByb3RlY3RlZCBJZGVudGl0eUNvbnN0cmFpbnQoU3RyaW5nIG5hbWVzcGFjZSwgU3RyaW5nIGlkZW50aXR5Q29uc3RyYWludE5hbWUsIFN0cmluZyBlbGVtTmFtZSkgewotICAgICAgICBmTmFtZXNwYWNlID0gbmFtZXNwYWNlOwotICAgICAgICBmSWRlbnRpdHlDb25zdHJhaW50TmFtZSA9IGlkZW50aXR5Q29uc3RyYWludE5hbWU7Ci0gICAgICAgIGZFbGVtZW50TmFtZSA9IGVsZW1OYW1lOwotICAgIH0gLy8gPGluaXQ+KFN0cmluZyxTdHJpbmcpCi0KLSAgICAvLwotICAgIC8vIFB1YmxpYyBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKiBSZXR1cm5zIHRoZSBpZGVudGl0eSBjb25zdHJhaW50IG5hbWUuICovCi0gICAgcHVibGljIFN0cmluZyBnZXRJZGVudGl0eUNvbnN0cmFpbnROYW1lKCkgewotICAgICAgICByZXR1cm4gZklkZW50aXR5Q29uc3RyYWludE5hbWU7Ci0gICAgfSAvLyBnZXRJZGVudGl0eUNvbnN0cmFpbnROYW1lKCk6U3RyaW5nCi0KLSAgICAvKiogU2V0cyB0aGUgc2VsZWN0b3IuICovCi0gICAgcHVibGljIHZvaWQgc2V0U2VsZWN0b3IoU2VsZWN0b3Igc2VsZWN0b3IpIHsKLSAgICAgICAgZlNlbGVjdG9yID0gc2VsZWN0b3I7Ci0gICAgfSAvLyBzZXRTZWxlY3RvcihTZWxlY3RvcikKLQotICAgIC8qKiBSZXR1cm5zIHRoZSBzZWxlY3Rvci4gKi8KLSAgICBwdWJsaWMgU2VsZWN0b3IgZ2V0U2VsZWN0b3IoKSB7Ci0gICAgICAgIHJldHVybiBmU2VsZWN0b3I7Ci0gICAgfSAvLyBnZXRTZWxlY3RvcigpOlNlbGVjdG9yCi0KLSAgICAvKiogQWRkcyBhIGZpZWxkLiAqLwotICAgIHB1YmxpYyB2b2lkIGFkZEZpZWxkKEZpZWxkIGZpZWxkKSB7Ci0gICAgICAgIGlmIChmRmllbGRzID09IG51bGwpCi0gICAgICAgICAgICBmRmllbGRzID0gbmV3IEZpZWxkWzRdOwotICAgICAgICBlbHNlIGlmIChmRmllbGRDb3VudCA9PSBmRmllbGRzLmxlbmd0aCkKLSAgICAgICAgICAgIGZGaWVsZHMgPSByZXNpemUoZkZpZWxkcywgZkZpZWxkQ291bnQqMik7Ci0gICAgICAgIGZGaWVsZHNbZkZpZWxkQ291bnQrK10gPSBmaWVsZDsKLSAgICB9IC8vIGFkZEZpZWxkKEZpZWxkKQotCi0gICAgLyoqIFJldHVybnMgdGhlIGZpZWxkIGNvdW50LiAqLwotICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRDb3VudCgpIHsKLSAgICAgICAgcmV0dXJuIGZGaWVsZENvdW50OwotICAgIH0gLy8gZ2V0RmllbGRDb3VudCgpOmludAotCi0gICAgLyoqIFJldHVybnMgdGhlIGZpZWxkIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXguICovCi0gICAgcHVibGljIEZpZWxkIGdldEZpZWxkQXQoaW50IGluZGV4KSB7Ci0gICAgICAgIHJldHVybiBmRmllbGRzW2luZGV4XTsKLSAgICB9IC8vIGdldEZpZWxkQXQoaW50KTpGaWVsZAotCi0gICAgLy8gZ2V0IHRoZSBuYW1lIG9mIHRoZSBvd25pbmcgZWxlbWVudAotICAgIHB1YmxpYyBTdHJpbmcgZ2V0RWxlbWVudE5hbWUgKCkgewotICAgICAgICByZXR1cm4gZkVsZW1lbnROYW1lOwotICAgIH0gLy8gZ2V0RWxlbWVudE5hbWUoKTogU3RyaW5nCi0KLSAgICAvLwotICAgIC8vIE9iamVjdCBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKiBSZXR1cm5zIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgb2JqZWN0LiAqLwotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0gICAgICAgIFN0cmluZyBzID0gc3VwZXIudG9TdHJpbmcoKTsKLSAgICAgICAgaW50IGluZGV4MSA9IHMubGFzdEluZGV4T2YoJyQnKTsKLSAgICAgICAgaWYgKGluZGV4MSAhPSAtMSkgewotICAgICAgICAgICAgcmV0dXJuIHMuc3Vic3RyaW5nKGluZGV4MSArIDEpOwotICAgICAgICB9Ci0gICAgICAgIGludCBpbmRleDIgPSBzLmxhc3RJbmRleE9mKCcuJyk7Ci0gICAgICAgIGlmIChpbmRleDIgIT0gLTEpIHsKLSAgICAgICAgICAgIHJldHVybiBzLnN1YnN0cmluZyhpbmRleDIgKyAxKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gczsKLSAgICB9IC8vIHRvU3RyaW5nKCk6U3RyaW5nCi0KLSAgICAvLyBlcXVhbHM6ICByZXR1cm5zIHRydWUgaWYgYW5kIG9ubHkgaWYgdGhlIFN0cmluZwotICAgIC8vIHJlcHJlc2VudGF0aW9ucyBvZiBhbGwgbWVtYmVycyBvZiBib3RoIG9iamVjdHMgKGV4Y2VwdCBmb3IKLSAgICAvLyB0aGUgZWxlbmVtdE5hbWUgZmllbGQpIGFyZSBlcXVhbC4KLSAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoSWRlbnRpdHlDb25zdHJhaW50IGlkKSB7Ci0gICAgICAgIGJvb2xlYW4gYXJlRXF1YWwgPSBmSWRlbnRpdHlDb25zdHJhaW50TmFtZS5lcXVhbHMoaWQuZklkZW50aXR5Q29uc3RyYWludE5hbWUpOwotICAgICAgICBpZighYXJlRXF1YWwpIHJldHVybiBmYWxzZTsKLSAgICAgICAgYXJlRXF1YWwgPSBmU2VsZWN0b3IudG9TdHJpbmcoKS5lcXVhbHMoaWQuZlNlbGVjdG9yLnRvU3RyaW5nKCkpOwotICAgICAgICBpZighYXJlRXF1YWwpIHJldHVybiBmYWxzZTsKLSAgICAgICAgYXJlRXF1YWwgPSAoZkZpZWxkQ291bnQgPT0gaWQuZkZpZWxkQ291bnQpOwotICAgICAgICBpZighYXJlRXF1YWwpIHJldHVybiBmYWxzZTsKLSAgICAgICAgZm9yKGludCBpPTA7IGk8ZkZpZWxkQ291bnQ7IGkrKykKLSAgICAgICAgICAgIGlmKCFmRmllbGRzW2ldLnRvU3RyaW5nKCkuZXF1YWxzKGlkLmZGaWVsZHNbaV0udG9TdHJpbmcoKSkpIHJldHVybiBmYWxzZTsKLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfSAvLyBlcXVhbHMKLQotICAgIHN0YXRpYyBmaW5hbCBGaWVsZFtdIHJlc2l6ZShGaWVsZFtdIG9sZEFycmF5LCBpbnQgbmV3U2l6ZSkgewotICAgICAgICBGaWVsZFtdIG5ld0FycmF5ID0gbmV3IEZpZWxkW25ld1NpemVdOwotICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KG9sZEFycmF5LCAwLCBuZXdBcnJheSwgMCwgb2xkQXJyYXkubGVuZ3RoKTsKLSAgICAgICAgcmV0dXJuIG5ld0FycmF5OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgdHlwZSBvZiB0aGUgb2JqZWN0LCBpLmUgRUxFTUVOVF9ERUNMQVJBVElPTi4KLSAgICAgKi8KLSAgICBwdWJsaWMgc2hvcnQgZ2V0VHlwZSgpIHsKLSAgICAgICAgcmV0dXJuIFhTQ29uc3RhbnRzLklERU5USVRZX0NPTlNUUkFJTlQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhlIDxjb2RlPm5hbWU8L2NvZGU+IG9mIHRoaXMgPGNvZGU+WFNPYmplY3Q8L2NvZGU+IGRlcGVuZGluZyBvbiB0aGUKLSAgICAgKiA8Y29kZT5YU09iamVjdDwvY29kZT4gdHlwZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKSB7Ci0gICAgICAgIHJldHVybiBmSWRlbnRpdHlDb25zdHJhaW50TmFtZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgbmFtZXNwYWNlIFVSSSBvZiB0aGlzIG5vZGUsIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIGl0IGlzCi0gICAgICogdW5zcGVjaWZpZWQuICBkZWZpbmVzIGhvdyBhIG5hbWVzcGFjZSBVUkkgaXMgYXR0YWNoZWQgdG8gc2NoZW1hCi0gICAgICogY29tcG9uZW50cy4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWVzcGFjZSgpIHsKLSAgICAgICAgcmV0dXJuIGZOYW1lc3BhY2U7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICoge2lkZW50aXR5LWNvbnN0cmFpbnQgY2F0ZWdvcnl9IE9uZSBvZiBrZXksIGtleXJlZiBvciB1bmlxdWUuCi0gICAgICovCi0gICAgcHVibGljIHNob3J0IGdldENhdGVnb3J5KCkgewotICAgICAgICByZXR1cm4gdHlwZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiB7c2VsZWN0b3J9IEEgcmVzdHJpY3RlZCBYUGF0aCAoW1hQYXRoXSkgZXhwcmVzc2lvbgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0U2VsZWN0b3JTdHIoKSB7Ci0gICAgICAgIHJldHVybiAoZlNlbGVjdG9yICE9IG51bGwpID8gZlNlbGVjdG9yLnRvU3RyaW5nKCkgOiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIHtmaWVsZHN9IEEgbm9uLWVtcHR5IGxpc3Qgb2YgcmVzdHJpY3RlZCBYUGF0aCAoW1hQYXRoXSkgZXhwcmVzc2lvbnMuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZ0xpc3QgZ2V0RmllbGRTdHJzKCkgewotICAgICAgICBTdHJpbmdbXSBzdHJzID0gbmV3IFN0cmluZ1tmRmllbGRDb3VudF07Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZkZpZWxkQ291bnQ7IGkrKykKLSAgICAgICAgICAgIHN0cnNbaV0gPSBmRmllbGRzW2ldLnRvU3RyaW5nKCk7Ci0gICAgICAgIHJldHVybiBuZXcgU3RyaW5nTGlzdEltcGwoc3RycywgZkZpZWxkQ291bnQpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIHtyZWZlcmVuY2VkIGtleX0gUmVxdWlyZWQgaWYge2lkZW50aXR5LWNvbnN0cmFpbnQgY2F0ZWdvcnl9IGlzIGtleXJlZiwKLSAgICAgKiBmb3JiaWRkZW4gb3RoZXJ3aXNlLiBBbiBpZGVudGl0eS1jb25zdHJhaW50IGRlZmluaXRpb24gd2l0aAotICAgICAqIHtpZGVudGl0eS1jb25zdHJhaW50IGNhdGVnb3J5fSBlcXVhbCB0byBrZXkgb3IgdW5pcXVlLgotICAgICAqLwotICAgIHB1YmxpYyBYU0lEQ0RlZmluaXRpb24gZ2V0UmVmS2V5KCkgewotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBPcHRpb25hbC4gQW5ub3RhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFNPYmplY3RMaXN0IGdldEFubm90YXRpb25zKCkgewotICAgICAgICByZXR1cm4gbmV3IFhTT2JqZWN0TGlzdEltcGwoZkFubm90YXRpb25zLCBmTnVtQW5ub3RhdGlvbnMpOwotICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTT2JqZWN0I2dldE5hbWVzcGFjZUl0ZW0oKQotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIFhTTmFtZXNwYWNlSXRlbSBnZXROYW1lc3BhY2VJdGVtKCkgewotICAgICAgICAvLyBSRVZJU0lUOiBpbXBsZW1lbnQKLSAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotCi0gICAgcHVibGljIHZvaWQgYWRkQW5ub3RhdGlvbihYU0Fubm90YXRpb25JbXBsIGFubm90YXRpb24pIHsKLSAgICAgICAgaWYoYW5ub3RhdGlvbiA9PSBudWxsKQotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICBpZihmQW5ub3RhdGlvbnMgPT0gbnVsbCkgewotICAgICAgICAgICAgZkFubm90YXRpb25zID0gbmV3IFhTQW5ub3RhdGlvbkltcGxbMl07Ci0gICAgICAgIH0gZWxzZSBpZihmTnVtQW5ub3RhdGlvbnMgPT0gZkFubm90YXRpb25zLmxlbmd0aCkgewotICAgICAgICAgICAgWFNBbm5vdGF0aW9uSW1wbFtdIG5ld0FycmF5ID0gbmV3IFhTQW5ub3RhdGlvbkltcGxbZk51bUFubm90YXRpb25zIDw8IDFdOwotICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShmQW5ub3RhdGlvbnMsIDAsIG5ld0FycmF5LCAwLCBmTnVtQW5ub3RhdGlvbnMpOwotICAgICAgICAgICAgZkFubm90YXRpb25zID0gbmV3QXJyYXk7Ci0gICAgICAgIH0KLSAgICAgICAgZkFubm90YXRpb25zW2ZOdW1Bbm5vdGF0aW9ucysrXSA9IGFubm90YXRpb247Ci0gICAgfQotCi19IC8vIGNsYXNzIElkZW50aXR5Q29uc3RyYWludApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9pZGVudGl0eS9LZXlSZWYuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvaWRlbnRpdHkvS2V5UmVmLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDQwNThiNTAuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9pZGVudGl0eS9LZXlSZWYuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDcyICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEsIDIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLmlkZW50aXR5OwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU0lEQ0RlZmluaXRpb247Ci0KLS8qKgotICogU2NoZW1hIGtleSByZWZlcmVuY2UgaWRlbnRpdHkgY29uc3RyYWludC4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBBbmR5IENsYXJrLCBJQk0KLSAqLwotcHVibGljIGNsYXNzIEtleVJlZgotICAgIGV4dGVuZHMgSWRlbnRpdHlDb25zdHJhaW50IHsKLQotICAgIC8vCi0gICAgLy8gRGF0YQotICAgIC8vCi0KLSAgICAvKiogVGhlIGtleSAob3IgdW5pcXVlKSBiZWluZyByZWZlcnJlZCB0by4gKi8KLSAgICBwcm90ZWN0ZWQgVW5pcXVlT3JLZXkgZktleTsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKiBDb25zdHJ1Y3RzIGEga2V5cmVmIHdpdGggdGhlIHNwZWNpZmllZCBuYW1lLiAqLwotICAgIHB1YmxpYyBLZXlSZWYoU3RyaW5nIG5hbWVzcGFjZSwgU3RyaW5nIGlkZW50aXR5Q29uc3RyYWludE5hbWUsCi0gICAgICAgICAgICAgICAgICBTdHJpbmcgZWxlbU5hbWUsIFVuaXF1ZU9yS2V5IGtleSkgewotICAgICAgICBzdXBlcihuYW1lc3BhY2UsIGlkZW50aXR5Q29uc3RyYWludE5hbWUsIGVsZW1OYW1lKTsKLSAgICAgICAgZktleSA9IGtleTsKLSAgICAgICAgdHlwZSA9IElDX0tFWVJFRjsKLSAgICB9IC8vIDxpbml0PihTdHJpbmcsU3RyaW5nLFN0cmluZykKLQotICAgIC8vCi0gICAgLy8gUHVibGljIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqIFJldHVybnMgdGhlIGtleSBiZWluZyByZWZlcnJlZCB0by4gICovCi0gICAgcHVibGljIFVuaXF1ZU9yS2V5IGdldEtleSgpIHsKLSAgICAgICAgcmV0dXJuIGZLZXk7Ci0gICAgfSAvLyBnZXRLZXkoKTogaW50Ci0KLSAgICAvKioKLSAgICAgKiB7cmVmZXJlbmNlZCBrZXl9IFJlcXVpcmVkIGlmIHtpZGVudGl0eS1jb25zdHJhaW50IGNhdGVnb3J5fSBpcyBrZXlyZWYsCi0gICAgICogZm9yYmlkZGVuIG90aGVyd2lzZS4gQW4gaWRlbnRpdHktY29uc3RyYWludCBkZWZpbml0aW9uIHdpdGgKLSAgICAgKiB7aWRlbnRpdHktY29uc3RyYWludCBjYXRlZ29yeX0gZXF1YWwgdG8ga2V5IG9yIHVuaXF1ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFNJRENEZWZpbml0aW9uIGdldFJlZktleSgpIHsKLSAgICAgICAgcmV0dXJuIGZLZXk7Ci0gICAgfQotCi19IC8vIGNsYXNzIEtleVJlZgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9pZGVudGl0eS9TZWxlY3Rvci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9pZGVudGl0eS9TZWxlY3Rvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmMzZlNWVlLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvaWRlbnRpdHkvU2VsZWN0b3IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI1NyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLCAyMDAyLDIwMDQsMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLmlkZW50aXR5OwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhwYXRoLlhQYXRoRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5TeW1ib2xUYWJsZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuWE1MQ2hhcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5OYW1lc3BhY2VDb250ZXh0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlFOYW1lOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTEF0dHJpYnV0ZXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5TaG9ydExpc3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU1R5cGVEZWZpbml0aW9uOwotCi0vKioKLSAqIFNjaGVtYSBpZGVudGl0eSBjb25zdHJhaW50IHNlbGVjdG9yLgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIEFuZHkgQ2xhcmssIElCTQotICogQHZlcnNpb24gJElkOiBTZWxlY3Rvci5qYXZhLHYgMS43IDIwMTAtMTEtMDEgMDQ6Mzk6NTcgam9laHcgRXhwICQKLSAqLwotcHVibGljIGNsYXNzIFNlbGVjdG9yIHsKLQotICAgIC8vCi0gICAgLy8gRGF0YQotICAgIC8vCi0KLSAgICAvKiogWFBhdGguICovCi0gICAgcHJvdGVjdGVkIGZpbmFsIFNlbGVjdG9yLlhQYXRoIGZYUGF0aDsKLQotICAgIC8qKiBJZGVudGl0eSBjb25zdHJhaW50LiAqLwotICAgIHByb3RlY3RlZCBmaW5hbCBJZGVudGl0eUNvbnN0cmFpbnQgZklkZW50aXR5Q29uc3RyYWludDsKLQotICAgIC8vIHRoZSBJZGVudGl0eSBjb25zdHJhaW50IHdlJ3JlIHRoZSBtYXRjaGVyIGZvci4gIE9ubHkKLSAgICAvLyB1c2VkIGZvciBzZWxlY3RvcnMhCi0gICAgcHJvdGVjdGVkIElkZW50aXR5Q29uc3RyYWludCBmSURDb25zdHJhaW50OwotCi0gICAgLy8KLSAgICAvLyBDb25zdHJ1Y3RvcnMKLSAgICAvLwotCi0gICAgLyoqIENvbnN0cnVjdHMgYSBzZWxlY3Rvci4gKi8KLSAgICBwdWJsaWMgU2VsZWN0b3IoU2VsZWN0b3IuWFBhdGggeHBhdGgsCi0gICAgICAgICAgICAgICAgICAgIElkZW50aXR5Q29uc3RyYWludCBpZGVudGl0eUNvbnN0cmFpbnQpIHsKLSAgICAgICAgZlhQYXRoID0geHBhdGg7Ci0gICAgICAgIGZJZGVudGl0eUNvbnN0cmFpbnQgPSBpZGVudGl0eUNvbnN0cmFpbnQ7Ci0gICAgfSAvLyA8aW5pdD4oU2VsZWN0b3IuWFBhdGgsSWRlbnRpdHlDb25zdHJhaW50KQotCi0gICAgLy8KLSAgICAvLyBQdWJsaWMgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKiogUmV0dXJucyB0aGUgc2VsZWN0b3IgWFBhdGguICovCi0gICAgcHVibGljIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cGF0aC5YUGF0aCBnZXRYUGF0aCgpIHsKLSAgICAgICAgcmV0dXJuIGZYUGF0aDsKLSAgICB9IC8vIGdldFhQYXRoKCk6Y29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC52MS5zY2hlbWEuaWRlbnRpdHkuWFBhdGgKLQotICAgIC8qKiBSZXR1cm5zIHRoZSBpZGVudGl0eSBjb25zdHJhaW50LiAqLwotICAgIHB1YmxpYyBJZGVudGl0eUNvbnN0cmFpbnQgZ2V0SURDb25zdHJhaW50KCkgewotICAgICAgICByZXR1cm4gZklkZW50aXR5Q29uc3RyYWludDsKLSAgICB9IC8vIGdldElEQ29uc3RyYWludCgpOklkZW50aXR5Q29uc3RyYWludAotCi0gICAgLy8gZmFjdG9yeSBtZXRob2QKLQotICAgIC8qKiBDcmVhdGVzIGEgc2VsZWN0b3IgbWF0Y2hlci4KLSAgICAgKiBAcGFyYW0gYWN0aXZhdG9yICAgICBUaGUgYWN0aXZhdG9yIGZvciB0aGlzIHNlbGVjdG9yJ3MgZmllbGRzLgotICAgICAqIEBwYXJhbSBpbml0aWFsRGVwdGggIFRoZSBkZXB0aCBpbiB0aGUgZG9jdW1lbnQgYXQgd2hpY2ggdGhpcyBtYXRjaGVyIGJlZ2FuIGl0cyBsaWZlOwotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICB1c2VkIGluIGNvcnJlY3RseSBoYW5kbGluZyByZWN1cnNpdmUgZWxlbWVudHMuCi0gICAgICovCi0gICAgcHVibGljIFhQYXRoTWF0Y2hlciBjcmVhdGVNYXRjaGVyKEZpZWxkQWN0aXZhdG9yIGFjdGl2YXRvciwgaW50IGluaXRpYWxEZXB0aCkgewotICAgICAgICByZXR1cm4gbmV3IFNlbGVjdG9yLk1hdGNoZXIoZlhQYXRoLCBhY3RpdmF0b3IsIGluaXRpYWxEZXB0aCk7Ci0gICAgfSAvLyBjcmVhdGVNYXRjaGVyKEZpZWxkQWN0aXZhdG9yKTpYUGF0aE1hdGNoZXIKLQotICAgIC8vCi0gICAgLy8gT2JqZWN0IG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBvYmplY3QuICovCi0gICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKLSAgICAgICAgcmV0dXJuIGZYUGF0aC50b1N0cmluZygpOwotICAgIH0gLy8gdG9TdHJpbmcoKTpTdHJpbmcKLQotICAgIC8vCi0gICAgLy8gQ2xhc3NlcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBTY2hlbWEgaWRlbnRpdHkgY29uc3RyYWludCBzZWxlY3RvciBYUGF0aCBleHByZXNzaW9uLgotICAgICAqCi0gICAgICogQGF1dGhvciBBbmR5IENsYXJrLCBJQk0KLSAgICAgKiBAdmVyc2lvbiAkSWQ6IFNlbGVjdG9yLmphdmEsdiAxLjcgMjAxMC0xMS0wMSAwNDozOTo1NyBqb2VodyBFeHAgJAotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgWFBhdGgKLSAgICBleHRlbmRzIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cGF0aC5YUGF0aCB7Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gQ29uc3RydWN0b3JzCi0gICAgICAgIC8vCi0KLSAgICAgICAgLyoqIENvbnN0cnVjdHMgYSBzZWxlY3RvciBYUGF0aCBleHByZXNzaW9uLiAqLwotICAgICAgICBwdWJsaWMgWFBhdGgoU3RyaW5nIHhwYXRoLCBTeW1ib2xUYWJsZSBzeW1ib2xUYWJsZSwKLSAgICAgICAgICAgICAgICAgICAgIE5hbWVzcGFjZUNvbnRleHQgY29udGV4dCkgdGhyb3dzIFhQYXRoRXhjZXB0aW9uIHsKLSAgICAgICAgICAgIHN1cGVyKG5vcm1hbGl6ZSh4cGF0aCksIHN5bWJvbFRhYmxlLCBjb250ZXh0KTsKLSAgICAgICAgICAgIC8vIHZlcmlmeSB0aGF0IGFuIGF0dHJpYnV0ZSBpcyBub3Qgc2VsZWN0ZWQKLSAgICAgICAgICAgIGZvciAoaW50IGk9MDtpPGZMb2NhdGlvblBhdGhzLmxlbmd0aDtpKyspIHsKLSAgICAgICAgICAgICAgICBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHBhdGguWFBhdGguQXhpcyBheGlzID0KLSAgICAgICAgICAgICAgICBmTG9jYXRpb25QYXRoc1tpXS5zdGVwc1tmTG9jYXRpb25QYXRoc1tpXS5zdGVwcy5sZW5ndGgtMV0uYXhpczsKLSAgICAgICAgICAgICAgICBpZiAoYXhpcy50eXBlID09IFhQYXRoLkF4aXMuQVRUUklCVVRFKSB7Ci0gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBYUGF0aEV4Y2VwdGlvbigiYy1zZWxlY3Rvci14cGF0aCIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICB9IC8vIDxpbml0PihTdHJpbmcsU3ltYm9sVGFibGUsTmFtZXNwYWNlc1Njb3BlKQotCi0gICAgICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBub3JtYWxpemUoU3RyaW5nIHhwYXRoKSB7Ci0gICAgICAgICAgICAvLyBOT1RFOiBXZSBoYXZlIHRvIHByZWZpeCB0aGUgc2VsZWN0b3IgWFBhdGggd2l0aCAiLi8iIGluCi0gICAgICAgICAgICAvLyAgICAgICBvcmRlciB0byBoYW5kbGUgc2VsZWN0b3JzIHN1Y2ggYXMgIi4iIHRoYXQgc2VsZWN0Ci0gICAgICAgICAgICAvLyAgICAgICB0aGUgZWxlbWVudCBjb250YWluZXIgYmVjYXVzZSB0aGUgZmllbGRzIGNvdWxkIGJlCi0gICAgICAgICAgICAvLyAgICAgICByZWxhdGl2ZSB0byB0aGF0IGVsZW1lbnQuIC1BYwotICAgICAgICAgICAgLy8gICAgICAgVW5sZXNzIHhwYXRoIHN0YXJ0cyB3aXRoIGEgZGVzY2VuZGFudCBub2RlIC1BY2hpbGxlIEZva291ZQotICAgICAgICAgICAgLy8gICAgICAuLi4gb3IgYSAnLicgb3IgYSAnLycgLSBORwotICAgICAgICAgICAgLy8gIEFuZCB3ZSBhbHNvIG5lZWQgdG8gcHJlZml4IGV4cHJzIHRvIHRoZSByaWdodCBvZiB8IHdpdGggLi8gLSBORwotICAgICAgICAgICAgU3RyaW5nQnVmZmVyIG1vZGlmaWVkWFBhdGggPSBuZXcgU3RyaW5nQnVmZmVyKHhwYXRoLmxlbmd0aCgpKzUpOwotICAgICAgICAgICAgaW50IHVuaW9uSW5kZXggPSAtMTsKLSAgICAgICAgICAgIGRvIHsKLSAgICAgICAgICAgICAgICBpZighKFhNTENoYXIudHJpbSh4cGF0aCkuc3RhcnRzV2l0aCgiLyIpIHx8IFhNTENoYXIudHJpbSh4cGF0aCkuc3RhcnRzV2l0aCgiLiIpKSkgewotICAgICAgICAgICAgICAgICAgICBtb2RpZmllZFhQYXRoLmFwcGVuZCgiLi8iKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgdW5pb25JbmRleCA9IHhwYXRoLmluZGV4T2YoJ3wnKTsKLSAgICAgICAgICAgICAgICBpZih1bmlvbkluZGV4ID09IC0xKSB7Ci0gICAgICAgICAgICAgICAgICAgIG1vZGlmaWVkWFBhdGguYXBwZW5kKHhwYXRoKTsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIG1vZGlmaWVkWFBhdGguYXBwZW5kKHhwYXRoLnN1YnN0cmluZygwLHVuaW9uSW5kZXgrMSkpOwotICAgICAgICAgICAgICAgIHhwYXRoID0geHBhdGguc3Vic3RyaW5nKHVuaW9uSW5kZXgrMSwgeHBhdGgubGVuZ3RoKCkpOwotICAgICAgICAgICAgfSB3aGlsZSh0cnVlKTsKLSAgICAgICAgICAgIHJldHVybiBtb2RpZmllZFhQYXRoLnRvU3RyaW5nKCk7Ci0gICAgICAgIH0KLQotICAgIH0gLy8gY2xhc3MgU2VsZWN0b3IuWFBhdGgKLQotICAgIC8qKgotICAgICAqIFNlbGVjdG9yIG1hdGNoZXIuCi0gICAgICoKLSAgICAgKiBAYXV0aG9yIEFuZHkgQ2xhcmssIElCTQotICAgICAqLwotICAgIHB1YmxpYyBjbGFzcyBNYXRjaGVyCi0gICAgZXh0ZW5kcyBYUGF0aE1hdGNoZXIgewotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIERhdGEKLSAgICAgICAgLy8KLQotICAgICAgICAvKiogRmllbGQgYWN0aXZhdG9yLiAqLwotICAgICAgICBwcm90ZWN0ZWQgZmluYWwgRmllbGRBY3RpdmF0b3IgZkZpZWxkQWN0aXZhdG9yOwotCi0gICAgICAgIC8qKiBJbml0aWFsIGRlcHRoIGluIHRoZSBkb2N1bWVudCBhdCB3aGljaCB0aGlzIG1hdGNoZXIgd2FzIGNyZWF0ZWQuICovCi0gICAgICAgIHByb3RlY3RlZCBmaW5hbCBpbnQgZkluaXRpYWxEZXB0aDsKLQotICAgICAgICAvKiogRWxlbWVudCBkZXB0aC4gKi8KLSAgICAgICAgcHJvdGVjdGVkIGludCBmRWxlbWVudERlcHRoOwotCi0gICAgICAgIC8qKiBEZXB0aCBhdCBtYXRjaC4gKi8KLSAgICAgICAgcHJvdGVjdGVkIGludCBmTWF0Y2hlZERlcHRoOwotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIENvbnN0cnVjdG9ycwotICAgICAgICAvLwotCi0gICAgICAgIC8qKiBDb25zdHJ1Y3RzIGEgc2VsZWN0b3IgbWF0Y2hlci4gKi8KLSAgICAgICAgcHVibGljIE1hdGNoZXIoU2VsZWN0b3IuWFBhdGggeHBhdGgsIEZpZWxkQWN0aXZhdG9yIGFjdGl2YXRvciwKLSAgICAgICAgICAgICAgICBpbnQgaW5pdGlhbERlcHRoKSB7Ci0gICAgICAgICAgICBzdXBlcih4cGF0aCk7Ci0gICAgICAgICAgICBmRmllbGRBY3RpdmF0b3IgPSBhY3RpdmF0b3I7Ci0gICAgICAgICAgICBmSW5pdGlhbERlcHRoID0gaW5pdGlhbERlcHRoOwotICAgICAgICB9IC8vIDxpbml0PihTZWxlY3Rvci5YUGF0aCxGaWVsZEFjdGl2YXRvcikKLQotICAgICAgICAvLwotICAgICAgICAvLyBYTUxEb2N1bWVudEZyYWdtZW50SGFuZGxlciBtZXRob2RzCi0gICAgICAgIC8vCi0KLSAgICAgICAgcHVibGljIHZvaWQgc3RhcnREb2N1bWVudEZyYWdtZW50KCl7Ci0gICAgICAgICAgICBzdXBlci5zdGFydERvY3VtZW50RnJhZ21lbnQoKTsKLSAgICAgICAgICAgIGZFbGVtZW50RGVwdGggPSAwOwotICAgICAgICAgICAgZk1hdGNoZWREZXB0aCA9IC0xOwotICAgICAgICB9IC8vIHN0YXJ0RG9jdW1lbnRGcmFnbWVudCgpCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFRoZSBzdGFydCBvZiBhbiBlbGVtZW50LiBJZiB0aGUgZG9jdW1lbnQgc3BlY2lmaWVzIHRoZSBzdGFydCBlbGVtZW50Ci0gICAgICAgICAqIGJ5IHVzaW5nIGFuIGVtcHR5IHRhZywgdGhlbiB0aGUgc3RhcnRFbGVtZW50IG1ldGhvZCB3aWxsIGltbWVkaWF0ZWx5Ci0gICAgICAgICAqIGJlIGZvbGxvd2VkIGJ5IHRoZSBlbmRFbGVtZW50IG1ldGhvZCwgd2l0aCBubyBpbnRlcnZlbmluZyBtZXRob2RzLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gZWxlbWVudCAgICBUaGUgbmFtZSBvZiB0aGUgZWxlbWVudC4KLSAgICAgICAgICogQHBhcmFtIGF0dHJpYnV0ZXMgVGhlIGVsZW1lbnQgYXR0cmlidXRlcy4KLSAgICAgICAgICoKLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudChRTmFtZSBlbGVtZW50LCBYTUxBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMpIHsKLSAgICAgICAgICAgIHN1cGVyLnN0YXJ0RWxlbWVudChlbGVtZW50LCBhdHRyaWJ1dGVzKTsKLSAgICAgICAgICAgIGZFbGVtZW50RGVwdGgrKzsKLSAgICAgICAgICAgIC8vIGFjdGl2YXRlIHRoZSBmaWVsZHMsIGlmIHNlbGVjdG9yIGlzIG1hdGNoZWQKLSAgICAgICAgICAgIC8vaW50IG1hdGNoZWQgPSBpc01hdGNoZWQoKTsKLQotICAgICAgICAgICAgaWYgKGlzTWF0Y2hlZCgpKSB7Ci0vKiAgICAgICAgICAgIChmTWF0Y2hlZERlcHRoID09IC0xICYmICgobWF0Y2hlZCAmIE1BVENIRUQpID09IE1BVENIRUQpKSB8fAotICAgICAgICAgICAgICAgICAgICAoKG1hdGNoZWQgJiBNQVRDSEVEX0RFU0NFTkRBTlQpID09IE1BVENIRURfREVTQ0VOREFOVCkpIHsgKi8KLSAgICAgICAgICAgICAgICBmTWF0Y2hlZERlcHRoID0gZkVsZW1lbnREZXB0aDsKLSAgICAgICAgICAgICAgICBmRmllbGRBY3RpdmF0b3Iuc3RhcnRWYWx1ZVNjb3BlRm9yKGZJZGVudGl0eUNvbnN0cmFpbnQsIGZJbml0aWFsRGVwdGgpOwotICAgICAgICAgICAgICAgIGludCBjb3VudCA9IGZJZGVudGl0eUNvbnN0cmFpbnQuZ2V0RmllbGRDb3VudCgpOwotICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykgewotICAgICAgICAgICAgICAgICAgICBGaWVsZCBmaWVsZCA9IGZJZGVudGl0eUNvbnN0cmFpbnQuZ2V0RmllbGRBdChpKTsKLSAgICAgICAgICAgICAgICAgICAgWFBhdGhNYXRjaGVyIG1hdGNoZXIgPSBmRmllbGRBY3RpdmF0b3IuYWN0aXZhdGVGaWVsZChmaWVsZCwgZkluaXRpYWxEZXB0aCk7Ci0gICAgICAgICAgICAgICAgICAgIG1hdGNoZXIuc3RhcnRFbGVtZW50KGVsZW1lbnQsIGF0dHJpYnV0ZXMpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICB9IC8vIHN0YXJ0RWxlbWVudChRTmFtZSxYTUxBdHRyTGlzdCxpbnQpCi0KLSAgICAgICAgcHVibGljIHZvaWQgZW5kRWxlbWVudChRTmFtZSBlbGVtZW50LCBYU1R5cGVEZWZpbml0aW9uIHR5cGUsIGJvb2xlYW4gbmlsbGFibGUsIE9iamVjdCBhY3R1YWxWYWx1ZSwgc2hvcnQgdmFsdWVUeXBlLCBTaG9ydExpc3QgaXRlbVZhbHVlVHlwZSkgewotICAgICAgICAgICAgc3VwZXIuZW5kRWxlbWVudChlbGVtZW50LCB0eXBlLCBuaWxsYWJsZSwgYWN0dWFsVmFsdWUsIHZhbHVlVHlwZSwgaXRlbVZhbHVlVHlwZSk7Ci0gICAgICAgICAgICBpZiAoZkVsZW1lbnREZXB0aC0tID09IGZNYXRjaGVkRGVwdGgpIHsKLSAgICAgICAgICAgICAgICBmTWF0Y2hlZERlcHRoID0gLTE7Ci0gICAgICAgICAgICAgICAgZkZpZWxkQWN0aXZhdG9yLmVuZFZhbHVlU2NvcGVGb3IoZklkZW50aXR5Q29uc3RyYWludCwgZkluaXRpYWxEZXB0aCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvKiogUmV0dXJucyB0aGUgaWRlbnRpdHkgY29uc3RyYWludC4gKi8KLSAgICAgICAgcHVibGljIElkZW50aXR5Q29uc3RyYWludCBnZXRJZGVudGl0eUNvbnN0cmFpbnQoKSB7Ci0gICAgICAgICAgICByZXR1cm4gZklkZW50aXR5Q29uc3RyYWludDsKLSAgICAgICAgfSAvLyBnZXRJZGVudGl0eUNvbnN0cmFpbnQoKTpJZGVudGl0eUNvbnN0cmFpbnQKLQotICAgICAgICAvKiogZ2V0IHRoZSBpbml0aWFsIGRlcHRoIGF0IHdoaWNoIHRoaXMgc2VsZWN0b3IgbWF0Y2hlZC4gKi8KLSAgICAgICAgcHVibGljIGludCBnZXRJbml0aWFsRGVwdGgoKSB7Ci0gICAgICAgICAgICByZXR1cm4gZkluaXRpYWxEZXB0aDsKLSAgICAgICAgfSAvLyBnZXRJbml0aWFsRGVwdGgoKTogIGludAotCi0KLSAgICB9IC8vIGNsYXNzIE1hdGNoZXIKLQotfSAvLyBjbGFzcyBTZWxlY3RvcgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9pZGVudGl0eS9VbmlxdWVPcktleS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9pZGVudGl0eS9VbmlxdWVPcktleS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhODZjNjY0Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvaWRlbnRpdHkvVW5pcXVlT3JLZXkuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDUxICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEsIDIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLmlkZW50aXR5OwotCi0vKioKLSAqIFNjaGVtYSB1bmlxdWUgb3Iga2V5IGlkZW50aXR5IGNvbnN0cmFpbnQuCi0gKiBUaGVzZSB0d28ga2luZHMgb2YgaWRlbnRpdHkgY29uc3RyYWludCBoYXZlIGJlZW4gY29tYmluZWQgdG8gc2F2ZQotICogdGhlIGNyZWF0aW9uIG9mIGEgc2VwYXJhdGUgVmVjdG9yIG9iamVjdCBmb3IgYW55IGVsZW1lbnQgdGhhdAotICogaGFzIGJvdGguICBBIHNob3J0IGludCBpcyB1c2VkIHRvIGRpc3Rpbmd1aXNoIHdoaWNoIHRoaXMgb2JqZWN0IGlzLgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIEFuZHkgQ2xhcmssIElCTQotICovCi1wdWJsaWMgY2xhc3MgVW5pcXVlT3JLZXkKLSAgICBleHRlbmRzIElkZW50aXR5Q29uc3RyYWludCB7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0cnVjdG9ycwotICAgIC8vCi0KLSAgICAvKiogQ29uc3RydWN0cyBhIHVuaXF1ZSBvciBhIGtleSBpZGVudGl0eSBjb25zdHJhaW50LiAqLwotICAgIHB1YmxpYyBVbmlxdWVPcktleShTdHJpbmcgbmFtZXNwYWNlLCBTdHJpbmcgaWRlbnRpdHlDb25zdHJhaW50TmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGVsZW1OYW1lLCBzaG9ydCB0eXBlKSB7Ci0gICAgICAgIHN1cGVyKG5hbWVzcGFjZSwgaWRlbnRpdHlDb25zdHJhaW50TmFtZSwgZWxlbU5hbWUpOwotICAgICAgICB0aGlzLnR5cGUgPSB0eXBlOwotICAgIH0gLy8gPGluaXQ+KFN0cmluZyxTdHJpbmcpCi0KLSAgICAvLwotICAgIC8vIFB1YmxpYyBtZXRob2RzCi0gICAgLy8KLQotfSAvLyBjbGFzcyBVbmlxdWUKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvaWRlbnRpdHkvVmFsdWVTdG9yZS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9pZGVudGl0eS9WYWx1ZVN0b3JlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDQzNDc3MTkuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9pZGVudGl0eS9WYWx1ZVN0b3JlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3MCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLCAyMDAyLDIwMDQsMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLmlkZW50aXR5OwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5TaG9ydExpc3Q7Ci0KLQotLyoqCi0gKiBJbnRlcmZhY2UgZm9yIHN0b3JpbmcgdmFsdWVzIGFzc29jaWF0ZWQgdG8gYW4gaWRlbnRpdHkgY29uc3RyYWludC4KLSAqIEVhY2ggdmFsdWUgc3RvcmVkIGNvcnJlc3BvbmRzIHRvIGEgZmllbGQgZGVjbGFyZWQgZm9yIHRoZSBpZGVudGl0eQotICogY29uc3RyYWludC4gT25lIGluc3RhbmNlIG9mIGFuIG9iamVjdCBpbXBsZW1lbnRpbmcgdGhpcyBpbnRlcmZhY2UKLSAqIGlzIGNyZWF0ZWQgZm9yIGVhY2ggaWRlbnRpdHkgY29uc3RyYWludCBwZXIgZWxlbWVudCBkZWNsYXJhdGlvbiBpbgotICogdGhlIGluc3RhbmNlIGRvY3VtZW50IHRvIHN0b3JlIHRoZSBpbmZvcm1hdGlvbiBmb3IgdGhpcyBpZGVudGl0eQotICogY29uc3RyYWludC4KLSAqIDxwPgotICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGUgY29tcG9uZW50IHBlcmZvcm1pbmcgaWRlbnRpdHkgY29uc3RyYWludAotICogY29sbGVjdGlvbiBhbmQgdmFsaWRhdGlvbiBpcyByZXNwb25zaWJsZSBmb3IgcHJvdmlkaW5nIGFuCi0gKiBpbXBsZW1lbnRhdGlvbiBvZiB0aGlzIGludGVyZmFjZS4gVGhlIGNvbXBvbmVudCBpcyBhbHNvIHJlc3BvbnNpYmxlCi0gKiBmb3IgcGVyZm9ybWluZyB0aGUgbmVjZXNzYXJ5IGNoZWNrcyByZXF1aXJlZCBieSBlYWNoIHR5cGUgb2YgaWRlbnRpdHkKLSAqIGNvbnN0cmFpbnQuCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgQW5keSBDbGFyaywgSUJNCi0gKgotICovCi1wdWJsaWMgaW50ZXJmYWNlIFZhbHVlU3RvcmUgewotCi0gICAgLy8KLSAgICAvLyBWYWx1ZVN0b3JlIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogQWRkcyB0aGUgc3BlY2lmaWVkIHZhbHVlIHRvIHRoZSB2YWx1ZSBzdG9yZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBmaWVsZCBUaGUgZmllbGQgYXNzb2NpYXRlZCB0byB0aGUgdmFsdWUuIFRoaXMgcmVmZXJlbmNlCi0gICAgICogICAgICAgICAgICAgIGlzIHVzZWQgdG8gZW5zdXJlIHRoYXQgZWFjaCBmaWVsZCBvbmx5IGFkZHMgYSB2YWx1ZQotICAgICAqICAgICAgICAgICAgICBvbmNlIHdpdGhpbiBhIHNlbGVjdGlvbiBzY29wZS4KLSAgICAgKiBAcGFyYW0gYWN0dWFsVmFsdWUgVGhlIHZhbHVlIHRvIGFkZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBhZGRWYWx1ZShGaWVsZCBmaWVsZCwgT2JqZWN0IGFjdHVhbFZhbHVlLCBzaG9ydCB2YWx1ZVR5cGUsIFNob3J0TGlzdCBpdGVtVmFsdWVUeXBlKTsKLQotICAgIC8qKgotICAgICAqIFNpbmNlIHRoZSB2YWx1ZVN0b3JlIHdpbGwgaGF2ZSBhY2Nlc3MgdG8gYW4gZXJyb3IgcmVwb3J0ZXIsIHRoaXMKLSAgICAgKiBhbGxvd3MgaXQgdG8gYmUgY2FsbGVkIGFwcHJvcHJpYXRlbHkuCi0gICAgICogQHBhcmFtIGtleSAgdGhlIGtleSBvZiB0aGUgbG9jYWxpemVkIGVycm9yIG1lc3NhZ2UKLSAgICAgKiBAcGFyYW0gYXJncyAgdGhlIGxpc3Qgb2YgYXJndW1lbnRzIGZvciBzdWJzdGl0dXRpb24uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcmVwb3J0RXJyb3IoU3RyaW5nIGtleSwgT2JqZWN0W10gYXJncyk7Ci0KLQotfSAvLyBpbnRlcmZhY2UgVmFsdWVTdG9yZQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9pZGVudGl0eS9YUGF0aE1hdGNoZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvaWRlbnRpdHkvWFBhdGhNYXRjaGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGQ4Nzg5MzIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9pZGVudGl0eS9YUGF0aE1hdGNoZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDUyMiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLCAyMDAyLDIwMDQsMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLmlkZW50aXR5OwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLkNvbnN0YW50czsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHBhdGguWFBhdGg7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLkludFN0YWNrOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlFOYW1lOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTEF0dHJpYnV0ZXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5BdHRyaWJ1dGVQU1ZJOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuU2hvcnRMaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNUeXBlRGVmaW5pdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci0KLQotLyoqCi0gKiBYUGF0aCBtYXRjaGVyLgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIEFuZHkgQ2xhcmssIElCTQotICoKLSAqLwotcHVibGljIGNsYXNzIFhQYXRoTWF0Y2hlciB7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0YW50cwotICAgIC8vCi0KLSAgICAvLyBkZWJ1Z2dpbmcKLQotICAgIC8qKiBDb21waWxlIHRvIHRydWUgdG8gZGVidWcgZXZlcnl0aGluZy4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGJvb2xlYW4gREVCVUdfQUxMID0gZmFsc2U7Ci0KLSAgICAvKiogQ29tcGlsZSB0byB0cnVlIHRvIGRlYnVnIG1ldGhvZCBjYWxsYmFja3MuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBib29sZWFuIERFQlVHX01FVEhPRFMgPSBmYWxzZSB8fCBERUJVR19BTEw7Ci0KLSAgICAvKiogQ29tcGlsZSB0byB0cnVlIHRvIGRlYnVnIGltcG9ydGFudCBtZXRob2QgY2FsbGJhY2tzLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgYm9vbGVhbiBERUJVR19NRVRIT0RTMiA9IGZhbHNlIHx8IERFQlVHX01FVEhPRFMgfHwgREVCVUdfQUxMOwotCi0gICAgLyoqIENvbXBpbGUgdG8gdHJ1ZSB0byBkZWJ1ZyB0aGUgPGVtPnJlYWxseTwvZW0+IGltcG9ydGFudCBtZXRob2RzLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgYm9vbGVhbiBERUJVR19NRVRIT0RTMyA9IGZhbHNlIHx8IERFQlVHX01FVEhPRFMgfHwgREVCVUdfQUxMOwotCi0gICAgLyoqIENvbXBpbGUgdG8gdHJ1ZSB0byBkZWJ1ZyBtYXRjaC4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGJvb2xlYW4gREVCVUdfTUFUQ0ggPSBmYWxzZSB8fCBERUJVR19BTEw7Ci0KLSAgICAvKiogQ29tcGlsZSB0byB0cnVlIHRvIGRlYnVnIHN0ZXAgaW5kZXggc3RhY2suICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBib29sZWFuIERFQlVHX1NUQUNLID0gZmFsc2UgfHwgREVCVUdfQUxMOwotCi0gICAgLyoqIERvbid0IHRvdWNoIHRoaXMgdmFsdWUgdW5sZXNzIHlvdSBhZGQgbW9yZSBkZWJ1ZyBjb25zdGFudHMuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBib29sZWFuIERFQlVHX0FOWSA9IERFQlVHX01FVEhPRFMgfHwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgREVCVUdfTUVUSE9EUzIgfHwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgREVCVUdfTUVUSE9EUzMgfHwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgREVCVUdfTUFUQ0ggfHwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgREVCVUdfU1RBQ0s7Ci0KLSAgICAvLyBjb25zdGFudHMgZGVzY3JpYmluZyB3aGV0aGVyIGEgbWF0Y2ggd2FzIG1hZGUsCi0gICAgLy8gYW5kIGlmIHNvIGhvdy4KLSAgICAvLyBtYXRjaGVkIGFueSB3YXkKLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBNQVRDSEVEID0gMTsKLSAgICAvLyBtYXRjaGVkIG9uIHRoZSBhdHRyaWJ1dGUgYXhpcwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgaW50IE1BVENIRURfQVRUUklCVVRFID0gMzsKLSAgICAvLyBtYXRjaGVkIG9uIHRoZSBkZXNjZW5kYW50LW9yLXNlbGYgYXhpeHMKLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBNQVRDSEVEX0RFU0NFTkRBTlQgPSA1OwotICAgIC8vIG1hdGNoZWQgc29tZSBwcmV2aW91cyAoYW5jZXN0b3IpIG5vZGUgb24gdGhlIGRlc2NlbmRhbnQtb3Itc2VsZi1heGlzLCBidXQgbm90IHRoaXMgbm9kZQotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgaW50IE1BVENIRURfREVTQ0VOREFOVF9QUkVWSU9VUyA9IDEzOwotCi0gICAgLy8KLSAgICAvLyBEYXRhCi0gICAgLy8KLQotICAgIC8qKiBYUGF0aCBsb2NhdGlvbiBwYXRoLiAqLwotICAgIHByaXZhdGUgWFBhdGguTG9jYXRpb25QYXRoW10gZkxvY2F0aW9uUGF0aHM7Ci0KLSAgICAvKiogVHJ1ZSBpZiBYUGF0aCBoYXMgYmVlbiBtYXRjaGVkLiAqLwotICAgIHByaXZhdGUgaW50W10gZk1hdGNoZWQ7Ci0KLSAgICAvKiogVGhlIG1hdGNoaW5nIHN0cmluZy4gKi8KLSAgICBwcm90ZWN0ZWQgT2JqZWN0IGZNYXRjaGVkU3RyaW5nOwotCi0gICAgLyoqIEludGVnZXIgc3RhY2sgb2Ygc3RlcCBpbmRleGVzLiAqLwotICAgIHByaXZhdGUgSW50U3RhY2tbXSBmU3RlcEluZGV4ZXM7Ci0KLSAgICAvKiogQ3VycmVudCBzdGVwLiAqLwotICAgIHByaXZhdGUgaW50W10gZkN1cnJlbnRTdGVwOwotCi0gICAgLyoqCi0gICAgICogTm8gbWF0Y2ggZGVwdGguIFRoZSB2YWx1ZSBvZiB0aGlzIGZpZWxkIHdpbGwgYmUgemVybyB3aGlsZQotICAgICAqIG1hdGNoaW5nIGlzIHN1Y2Nlc3NmdWwgZm9yIHRoZSBnaXZlbiB4cGF0aCBleHByZXNzaW9uLgotICAgICAqLwotICAgIHByaXZhdGUgaW50IFtdIGZOb01hdGNoRGVwdGg7Ci0KLSAgICBmaW5hbCBRTmFtZSBmUU5hbWUgPSBuZXcgUU5hbWUoKTsKLQotCi0gICAgLy8KLSAgICAvLyBDb25zdHJ1Y3RvcnMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0cyBhbiBYUGF0aCBtYXRjaGVyIHRoYXQgaW1wbGVtZW50cyBhIGRvY3VtZW50IGZyYWdtZW50Ci0gICAgICogaGFuZGxlci4KLSAgICAgKgotICAgICAqIEBwYXJhbSB4cGF0aCAgIFRoZSB4cGF0aC4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFBhdGhNYXRjaGVyKFhQYXRoIHhwYXRoKSB7Ci0gICAgICAgIGZMb2NhdGlvblBhdGhzID0geHBhdGguZ2V0TG9jYXRpb25QYXRocygpOwotICAgICAgICBmU3RlcEluZGV4ZXMgPSBuZXcgSW50U3RhY2tbZkxvY2F0aW9uUGF0aHMubGVuZ3RoXTsKLSAgICAgICAgZm9yKGludCBpPTA7IGk8ZlN0ZXBJbmRleGVzLmxlbmd0aDsgaSsrKSBmU3RlcEluZGV4ZXNbaV0gPSBuZXcgSW50U3RhY2soKTsKLSAgICAgICAgZkN1cnJlbnRTdGVwID0gbmV3IGludFtmTG9jYXRpb25QYXRocy5sZW5ndGhdOwotICAgICAgICBmTm9NYXRjaERlcHRoID0gbmV3IGludFtmTG9jYXRpb25QYXRocy5sZW5ndGhdOwotICAgICAgICBmTWF0Y2hlZCA9IG5ldyBpbnRbZkxvY2F0aW9uUGF0aHMubGVuZ3RoXTsKLSAgICB9IC8vIDxpbml0PihYUGF0aCkKLQotICAgIC8vCi0gICAgLy8gUHVibGljIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB2YWx1ZSBvZiBmaXJzdCBtZW1iZXIgb2YgZk1hdGNoZWQgdGhhdAotICAgICAqIGlzIG5vbnplcm8uCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNNYXRjaGVkKCkgewotICAgICAgICAvLyB4cGF0aCBoYXMgYmVlbiBtYXRjaGVkIGlmIGFueSBvbmUgb2YgdGhlIG1lbWJlcnMgb2YgdGhlIHVuaW9uIGhhdmUgbWF0Y2hlZC4KLSAgICAgICAgZm9yIChpbnQgaT0wOyBpIDwgZkxvY2F0aW9uUGF0aHMubGVuZ3RoOyBpKyspCi0gICAgICAgICAgICBpZiAoKChmTWF0Y2hlZFtpXSAmIE1BVENIRUQpID09IE1BVENIRUQpCi0gICAgICAgICAgICAgICAgICAgICYmICgoZk1hdGNoZWRbaV0gJiBNQVRDSEVEX0RFU0NFTkRBTlRfUFJFVklPVVMpICE9IE1BVENIRURfREVTQ0VOREFOVF9QUkVWSU9VUykKLSAgICAgICAgICAgICAgICAgICAgJiYgKChmTm9NYXRjaERlcHRoW2ldID09IDApCi0gICAgICAgICAgICAgICAgICAgIHx8ICgoZk1hdGNoZWRbaV0gJiBNQVRDSEVEX0RFU0NFTkRBTlQpID09IE1BVENIRURfREVTQ0VOREFOVCkpKQotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotCi0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9IC8vIGlzTWF0Y2hlZCgpOmludAotCi0gICAgLy8KLSAgICAvLyBQcm90ZWN0ZWQgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvLyBhIHBsYWNlLWhvbGRlciBtZXRob2Q7IHRvIGJlIG92ZXJyaWRkZW4gYnkgc3ViY2xhc3NlcwotICAgIC8vIHRoYXQgY2FyZSBhYm91dCBtYXRjaGluZyBlbGVtZW50IGNvbnRlbnQuCi0gICAgcHJvdGVjdGVkIHZvaWQgaGFuZGxlQ29udGVudChYU1R5cGVEZWZpbml0aW9uIHR5cGUsIGJvb2xlYW4gbmlsbGFibGUsIE9iamVjdCB2YWx1ZSwgc2hvcnQgdmFsdWVUeXBlLCBTaG9ydExpc3QgaXRlbVZhbHVlVHlwZSkgewotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCB3aGVuIHRoZSBYUGF0aCBoYW5kbGVyIG1hdGNoZXMgdGhlCi0gICAgICogWFBhdGggZXhwcmVzc2lvbi4gU3ViY2xhc3NlcyBjYW4gb3ZlcnJpZGUgdGhpcyBtZXRob2QgdG8KLSAgICAgKiBwcm92aWRlIGRlZmF1bHQgaGFuZGxpbmcgdXBvbiBhIG1hdGNoLgotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIG1hdGNoZWQoT2JqZWN0IGFjdHVhbFZhbHVlLCBzaG9ydCB2YWx1ZVR5cGUsIFNob3J0TGlzdCBpdGVtVmFsdWVUeXBlLCBib29sZWFuIGlzTmlsKSB7Ci0gICAgICAgIGlmIChERUJVR19NRVRIT0RTMykgewotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKHRvU3RyaW5nKCkrIiNtYXRjaGVkKFwiIithY3R1YWxWYWx1ZSsiXCIpIik7Ci0gICAgICAgIH0KLSAgICB9IC8vIG1hdGNoZWQoU3RyaW5nIGNvbnRlbnQsIFhTU2ltcGxlVHlwZSB2YWwpCi0KLSAgICAvLwotICAgIC8vIH5YTUxEb2N1bWVudEZyYWdtZW50SGFuZGxlciBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFRoZSBzdGFydCBvZiB0aGUgZG9jdW1lbnQgZnJhZ21lbnQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnREb2N1bWVudEZyYWdtZW50KCl7Ci0gICAgICAgIGlmIChERUJVR19NRVRIT0RTKSB7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4odG9TdHJpbmcoKSsiI3N0YXJ0RG9jdW1lbnRGcmFnbWVudCgiKwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIpIik7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyByZXNldCBzdGF0ZQotICAgICAgICBmTWF0Y2hlZFN0cmluZyA9IG51bGw7Ci0gICAgICAgIGZvcihpbnQgaSA9IDA7IGkgPCBmTG9jYXRpb25QYXRocy5sZW5ndGg7IGkrKykgewotICAgICAgICAgICAgZlN0ZXBJbmRleGVzW2ldLmNsZWFyKCk7Ci0gICAgICAgICAgICBmQ3VycmVudFN0ZXBbaV0gPSAwOwotICAgICAgICAgICAgZk5vTWF0Y2hEZXB0aFtpXSA9IDA7Ci0gICAgICAgICAgICBmTWF0Y2hlZFtpXSA9IDA7Ci0gICAgICAgIH0KLQotCi0gICAgfSAvLyBzdGFydERvY3VtZW50RnJhZ21lbnQoKQotCi0gICAgLyoqCi0gICAgICogVGhlIHN0YXJ0IG9mIGFuIGVsZW1lbnQuIElmIHRoZSBkb2N1bWVudCBzcGVjaWZpZXMgdGhlIHN0YXJ0IGVsZW1lbnQKLSAgICAgKiBieSB1c2luZyBhbiBlbXB0eSB0YWcsIHRoZW4gdGhlIHN0YXJ0RWxlbWVudCBtZXRob2Qgd2lsbCBpbW1lZGlhdGVseQotICAgICAqIGJlIGZvbGxvd2VkIGJ5IHRoZSBlbmRFbGVtZW50IG1ldGhvZCwgd2l0aCBubyBpbnRlcnZlbmluZyBtZXRob2RzLgotICAgICAqCi0gICAgICogQHBhcmFtIGVsZW1lbnQgICAgVGhlIG5hbWUgb2YgdGhlIGVsZW1lbnQuCi0gICAgICogQHBhcmFtIGF0dHJpYnV0ZXMgVGhlIGVsZW1lbnQgYXR0cmlidXRlcy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQoUU5hbWUgZWxlbWVudCwgWE1MQXR0cmlidXRlcyBhdHRyaWJ1dGVzKXsKLSAgICAgICAgaWYgKERFQlVHX01FVEhPRFMyKSB7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4odG9TdHJpbmcoKSsiI3N0YXJ0RWxlbWVudCgiKwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJlbGVtZW50PXsiK2VsZW1lbnQrIn0sIisKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYXR0cmlidXRlcz0uLi4iK2F0dHJpYnV0ZXMrCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIikiKTsKLSAgICAgICAgfQotCi0gICAgICAgIGZvcihpbnQgaSA9IDA7IGkgPCBmTG9jYXRpb25QYXRocy5sZW5ndGg7IGkrKykgewotICAgICAgICAgICAgLy8gcHVzaCBjb250ZXh0Ci0gICAgICAgICAgICBpbnQgc3RhcnRTdGVwID0gZkN1cnJlbnRTdGVwW2ldOwotICAgICAgICAgICAgZlN0ZXBJbmRleGVzW2ldLnB1c2goc3RhcnRTdGVwKTsKLQotICAgICAgICAgICAgLy8gdHJ5IG5leHQgeHBhdGgsIGlmIG5vdCBtYXRjaGluZwotICAgICAgICAgICAgaWYgKChmTWF0Y2hlZFtpXSAmIE1BVENIRURfREVTQ0VOREFOVCkgPT0gTUFUQ0hFRCB8fCBmTm9NYXRjaERlcHRoW2ldID4gMCkgewotICAgICAgICAgICAgICAgIGZOb01hdGNoRGVwdGhbaV0rKzsKLSAgICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmKChmTWF0Y2hlZFtpXSAmIE1BVENIRURfREVTQ0VOREFOVCkgPT0gTUFUQ0hFRF9ERVNDRU5EQU5UKSB7Ci0gICAgICAgICAgICAgICAgZk1hdGNoZWRbaV0gPSBNQVRDSEVEX0RFU0NFTkRBTlRfUFJFVklPVVM7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmIChERUJVR19TVEFDSykgewotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbih0b1N0cmluZygpKyI6ICIrZlN0ZXBJbmRleGVzW2ldKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gY29uc3VtZSBzZWxmOjpub2RlKCkgc3RlcHMKLSAgICAgICAgICAgIFhQYXRoLlN0ZXBbXSBzdGVwcyA9IGZMb2NhdGlvblBhdGhzW2ldLnN0ZXBzOwotICAgICAgICAgICAgd2hpbGUgKGZDdXJyZW50U3RlcFtpXSA8IHN0ZXBzLmxlbmd0aCAmJgotICAgICAgICAgICAgICAgICAgICBzdGVwc1tmQ3VycmVudFN0ZXBbaV1dLmF4aXMudHlwZSA9PSBYUGF0aC5BeGlzLlNFTEYpIHsKLSAgICAgICAgICAgICAgICBpZiAoREVCVUdfTUFUQ0gpIHsKLSAgICAgICAgICAgICAgICAgICAgWFBhdGguU3RlcCBzdGVwID0gc3RlcHNbZkN1cnJlbnRTdGVwW2ldXTsKLSAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKHRvU3RyaW5nKCkrIiBbU0VMRl0gTUFUQ0hFRCEiKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZkN1cnJlbnRTdGVwW2ldKys7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoZkN1cnJlbnRTdGVwW2ldID09IHN0ZXBzLmxlbmd0aCkgewotICAgICAgICAgICAgICAgIGlmIChERUJVR19NQVRDSCkgewotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4odG9TdHJpbmcoKSsiIFhQYXRoIE1BVENIRUQhIik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGZNYXRjaGVkW2ldID0gTUFUQ0hFRDsKLSAgICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gbm93IGlmIHRoZSBjdXJyZW50IHN0ZXAgaXMgYSBkZXNjZW5kYW50IHN0ZXAsIHdlIGxldCB0aGUgbmV4dAotICAgICAgICAgICAgLy8gc3RlcCBkbyBpdHMgdGhpbmc7IGlmIGl0IGZhaWxzLCB3ZSByZXNldCBvdXJzZWx2ZXMKLSAgICAgICAgICAgIC8vIHRvIGxvb2sgYXQgdGhpcyBzdGVwIGZvciBuZXh0IHRpbWUgd2UncmUgY2FsbGVkLgotICAgICAgICAgICAgLy8gc28gZmlyc3QgY29uc3VtZSBhbGwgZGVzY2VuZGFudHM6Ci0gICAgICAgICAgICBpbnQgZGVzY2VuZGFudFN0ZXAgPSBmQ3VycmVudFN0ZXBbaV07Ci0gICAgICAgICAgICB3aGlsZShmQ3VycmVudFN0ZXBbaV0gPCBzdGVwcy5sZW5ndGggJiYgc3RlcHNbZkN1cnJlbnRTdGVwW2ldXS5heGlzLnR5cGUgPT0gWFBhdGguQXhpcy5ERVNDRU5EQU5UKSB7Ci0gICAgICAgICAgICAgICAgaWYgKERFQlVHX01BVENIKSB7Ci0gICAgICAgICAgICAgICAgICAgIFhQYXRoLlN0ZXAgc3RlcCA9IHN0ZXBzW2ZDdXJyZW50U3RlcFtpXV07Ci0gICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbih0b1N0cmluZygpKyIgW0RFU0NFTkRBTlRdIE1BVENIRUQhIik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGZDdXJyZW50U3RlcFtpXSsrOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgYm9vbGVhbiBzYXdEZXNjZW5kYW50ID0gZkN1cnJlbnRTdGVwW2ldID4gZGVzY2VuZGFudFN0ZXA7Ci0gICAgICAgICAgICBpZiAoZkN1cnJlbnRTdGVwW2ldID09IHN0ZXBzLmxlbmd0aCkgewotICAgICAgICAgICAgICAgIGlmIChERUJVR19NQVRDSCkgewotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4odG9TdHJpbmcoKSsiIFhQYXRoIERJRE4nVCBNQVRDSCEiKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZk5vTWF0Y2hEZXB0aFtpXSsrOwotICAgICAgICAgICAgICAgIGlmIChERUJVR19NQVRDSCkgewotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4odG9TdHJpbmcoKSsiIFtDSElMRF0gYWZ0ZXIgTk8gTUFUQ0giKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIG1hdGNoIGNoaWxkOjouLi4gc3RlcCwgaWYgaGF2ZW4ndCBjb25zdW1lZCBhbnkgc2VsZjo6bm9kZSgpCi0gICAgICAgICAgICBpZiAoKGZDdXJyZW50U3RlcFtpXSA9PSBzdGFydFN0ZXAgfHwgZkN1cnJlbnRTdGVwW2ldID4gZGVzY2VuZGFudFN0ZXApICYmCi0gICAgICAgICAgICAgICAgc3RlcHNbZkN1cnJlbnRTdGVwW2ldXS5heGlzLnR5cGUgPT0gWFBhdGguQXhpcy5DSElMRCkgewotICAgICAgICAgICAgICAgIFhQYXRoLlN0ZXAgc3RlcCA9IHN0ZXBzW2ZDdXJyZW50U3RlcFtpXV07Ci0gICAgICAgICAgICAgICAgWFBhdGguTm9kZVRlc3Qgbm9kZVRlc3QgPSBzdGVwLm5vZGVUZXN0OwotICAgICAgICAgICAgICAgIGlmIChERUJVR19NQVRDSCkgewotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4odG9TdHJpbmcoKSsiIFtDSElMRF0gYmVmb3JlIik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGlmIChub2RlVGVzdC50eXBlID09IFhQYXRoLk5vZGVUZXN0LlFOQU1FKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmICghbm9kZVRlc3QubmFtZS5lcXVhbHMoZWxlbWVudCkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmKGZDdXJyZW50U3RlcFtpXSA+IGRlc2NlbmRhbnRTdGVwKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRTdGVwW2ldID0gZGVzY2VuZGFudFN0ZXA7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBmTm9NYXRjaERlcHRoW2ldKys7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoREVCVUdfTUFUQ0gpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4odG9TdHJpbmcoKSsiIFtDSElMRF0gYWZ0ZXIgTk8gTUFUQ0giKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGZDdXJyZW50U3RlcFtpXSsrOwotICAgICAgICAgICAgICAgIGlmIChERUJVR19NQVRDSCkgewotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4odG9TdHJpbmcoKSsiIFtDSElMRF0gYWZ0ZXIgTUFUQ0hFRCEiKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoZkN1cnJlbnRTdGVwW2ldID09IHN0ZXBzLmxlbmd0aCkgewotICAgICAgICAgICAgICAgIGlmKHNhd0Rlc2NlbmRhbnQpIHsKLSAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRTdGVwW2ldID0gZGVzY2VuZGFudFN0ZXA7Ci0gICAgICAgICAgICAgICAgICAgIGZNYXRjaGVkW2ldID0gTUFUQ0hFRF9ERVNDRU5EQU5UOwotICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIGZNYXRjaGVkW2ldID0gTUFUQ0hFRDsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIG1hdGNoIGF0dHJpYnV0ZTo6Li4uIHN0ZXAKLSAgICAgICAgICAgIGlmIChmQ3VycmVudFN0ZXBbaV0gPCBzdGVwcy5sZW5ndGggJiYKLSAgICAgICAgICAgICAgICBzdGVwc1tmQ3VycmVudFN0ZXBbaV1dLmF4aXMudHlwZSA9PSBYUGF0aC5BeGlzLkFUVFJJQlVURSkgewotICAgICAgICAgICAgICAgIGlmIChERUJVR19NQVRDSCkgewotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4odG9TdHJpbmcoKSsiIFtBVFRSSUJVVEVdIGJlZm9yZSIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpbnQgYXR0ckNvdW50ID0gYXR0cmlidXRlcy5nZXRMZW5ndGgoKTsKLSAgICAgICAgICAgICAgICBpZiAoYXR0ckNvdW50ID4gMCkgewotICAgICAgICAgICAgICAgICAgICBYUGF0aC5Ob2RlVGVzdCBub2RlVGVzdCA9IHN0ZXBzW2ZDdXJyZW50U3RlcFtpXV0ubm9kZVRlc3Q7Ci0KLSAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgYUluZGV4ID0gMDsgYUluZGV4IDwgYXR0ckNvdW50OyBhSW5kZXgrKykgewotICAgICAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlcy5nZXROYW1lKGFJbmRleCwgZlFOYW1lKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChub2RlVGVzdC50eXBlICE9IFhQYXRoLk5vZGVUZXN0LlFOQU1FIHx8Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZVRlc3QubmFtZS5lcXVhbHMoZlFOYW1lKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZDdXJyZW50U3RlcFtpXSsrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmQ3VycmVudFN0ZXBbaV0gPT0gc3RlcHMubGVuZ3RoKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZNYXRjaGVkW2ldID0gTUFUQ0hFRF9BVFRSSUJVVEU7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBqPTA7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcig7IGo8aSAmJiAoKGZNYXRjaGVkW2pdICYgTUFUQ0hFRCkgIT0gTUFUQ0hFRCk7IGorKyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKGo9PWkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0dHJpYnV0ZVBTVkkgYXR0clBTVkkgPSAoQXR0cmlidXRlUFNWSSlhdHRyaWJ1dGVzLmdldEF1Z21lbnRhdGlvbnMoYUluZGV4KS5nZXRJdGVtKENvbnN0YW50cy5BVFRSSUJVVEVfUFNWSSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmTWF0Y2hlZFN0cmluZyA9IGF0dHJQU1ZJLmdldEFjdHVhbE5vcm1hbGl6ZWRWYWx1ZSgpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0Y2hlZChmTWF0Y2hlZFN0cmluZywgYXR0clBTVkkuZ2V0QWN0dWFsTm9ybWFsaXplZFZhbHVlVHlwZSgpLCBhdHRyUFNWSS5nZXRJdGVtVmFsdWVUeXBlcygpLCBmYWxzZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaWYgKChmTWF0Y2hlZFtpXSAmIE1BVENIRUQpICE9IE1BVENIRUQpIHsKLSAgICAgICAgICAgICAgICAgICAgaWYoZkN1cnJlbnRTdGVwW2ldID4gZGVzY2VuZGFudFN0ZXApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZDdXJyZW50U3RlcFtpXSA9IGRlc2NlbmRhbnRTdGVwOwotICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZk5vTWF0Y2hEZXB0aFtpXSsrOwotICAgICAgICAgICAgICAgICAgICBpZiAoREVCVUdfTUFUQ0gpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbih0b1N0cmluZygpKyIgW0FUVFJJQlVURV0gYWZ0ZXIiKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaWYgKERFQlVHX01BVENIKSB7Ci0gICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbih0b1N0cmluZygpKyIgW0FUVFJJQlVURV0gYWZ0ZXIgTUFUQ0hFRCEiKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgIH0KLSAgICAvLyBzdGFydEVsZW1lbnQoUU5hbWUsWE1MQXR0ckxpc3QsaW50KQotCi0gICAgLyoqCi0gICAgICAgKiBAcGFyYW0gZWxlbWVudAotICAgICAgICogICAgICAgIG5hbWUgb2YgdGhlIGVsZW1lbnQuCi0gICAgICAgKiBAcGFyYW0gdHlwZQotICAgICAgICogICAgICAgIGNvbnRlbnQgdHlwZSBvZiB0aGlzIGVsZW1lbnQuIElPVywgdGhlIFhNTCBzY2hlbWEgdHlwZQotICAgICAgICogICAgICAgIG9mIHRoZSA8dHQ+dmFsdWU8L3R0Pi4gTm90ZSB0aGF0IHRoaXMgbWF5IG5vdCBiZSB0aGUgdHlwZSBkZWNsYXJlZAotICAgICAgICogICAgICAgIGluIHRoZSBlbGVtZW50IGRlY2xhcmF0aW9uLCBidXQgaXQgaXMgInRoZSBhY3R1YWwgdHlwZSIuIEZvciBleGFtcGxlLAotICAgICAgICogICAgICAgIGlmIHRoZSBYTUwgaXMgJmx0O2ZvbyB4c2k6dHlwZT0ieHM6c3RyaW5nIj5hYWEmbHQ7L2Zvbz4sIHRoaXMKLSAgICAgICAqICAgICAgICBwYXJhbWV0ZXIgd2lsbCBiZSAieHM6c3RyaW5nIi4KLSAgICAgICAqIEBwYXJhbSBuaWxsYWJsZSAtIG5pbGxhYmxlCi0gICAgICAgKiAgICAgICAgdHJ1ZSBpZiB0aGUgZWxlbWVudCBkZWNsYXJhdGlvbiBpcyBuaWxsYWJsZS4KLSAgICAgICAqIEBwYXJhbSB2YWx1ZSAtIGFjdHVhbCB2YWx1ZQotICAgICAgICogICAgICAgIHRoZSB0eXBlZCB2YWx1ZSBvZiB0aGUgY29udGVudCBvZiB0aGlzIGVsZW1lbnQuCi0gICAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbmRFbGVtZW50KFFOYW1lIGVsZW1lbnQsIFhTVHlwZURlZmluaXRpb24gdHlwZSwgYm9vbGVhbiBuaWxsYWJsZSwgT2JqZWN0IHZhbHVlLCBzaG9ydCB2YWx1ZVR5cGUsIFNob3J0TGlzdCBpdGVtVmFsdWVUeXBlKSB7Ci0gICAgICAgIGlmIChERUJVR19NRVRIT0RTMikgewotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKHRvU3RyaW5nKCkrIiNlbmRFbGVtZW50KCIrCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImVsZW1lbnQ9eyIrZWxlbWVudCsifSwiKwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIpIik7Ci0gICAgICAgIH0KLSAgICAgICAgZm9yKGludCBpID0gMDsgaTxmTG9jYXRpb25QYXRocy5sZW5ndGg7IGkrKykgewotICAgICAgICAgICAgLy8gZ28gYmFjayBhIHN0ZXAKLSAgICAgICAgICAgIGZDdXJyZW50U3RlcFtpXSA9IGZTdGVwSW5kZXhlc1tpXS5wb3AoKTsKLQotICAgICAgICAgICAgLy8gZG9uJ3QgZG8gYW55dGhpbmcsIGlmIG5vdCBtYXRjaGluZwotICAgICAgICAgICAgaWYgKGZOb01hdGNoRGVwdGhbaV0gPiAwKSB7Ci0gICAgICAgICAgICAgICAgZk5vTWF0Y2hEZXB0aFtpXS0tOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBzaWduYWwgbWF0Y2gsIGlmIGFwcHJvcHJpYXRlCi0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBpbnQgaj0wOwotICAgICAgICAgICAgICAgIGZvcig7IGo8aSAmJiAoKGZNYXRjaGVkW2pdICYgTUFUQ0hFRCkgIT0gTUFUQ0hFRCk7IGorKyk7Ci0gICAgICAgICAgICAgICAgaWYgKChqPGkpIHx8IChmTWF0Y2hlZFtqXSA9PSAwKSB8fAotICAgICAgICAgICAgICAgICAgICAgICAgKChmTWF0Y2hlZFtqXSAmIE1BVENIRURfQVRUUklCVVRFKSA9PSBNQVRDSEVEX0FUVFJJQlVURSkpIHsKLSAgICAgICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIC8vIG9ubHkgY2VydGFpbiBraW5kcyBvZiBtYXRjaGVycyBhY3R1YWxseQotICAgICAgICAgICAgICAgIC8vIG1hdGNoIGVsZW1lbnQgY29udGVudC4gIFRoaXMgcGVybWl0cwotICAgICAgICAgICAgICAgIC8vIHRoZW0gYSB3YXkgdG8gb3ZlcnJpZGUgdGhpcyB0byBkbyBub3RoaW5nCi0gICAgICAgICAgICAgICAgLy8gYW5kIGhvcGVmdWxseSBzYXZlIGEgZmV3IG9wZXJhdGlvbnMuCi0gICAgICAgICAgICAgICAgaGFuZGxlQ29udGVudCh0eXBlLCBuaWxsYWJsZSwgdmFsdWUsIHZhbHVlVHlwZSwgaXRlbVZhbHVlVHlwZSk7Ci0gICAgICAgICAgICAgICAgZk1hdGNoZWRbaV0gPSAwOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAoREVCVUdfU1RBQ0spIHsKLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4odG9TdHJpbmcoKSsiOiAiK2ZTdGVwSW5kZXhlc1tpXSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgIH0gLy8gZW5kRWxlbWVudChRTmFtZSkKLQotICAgIC8vCi0gICAgLy8gT2JqZWN0IG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBvYmplY3QuICovCi0gICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKLSAgICAgICAgLyoqKgotICAgICAgICByZXR1cm4gZkxvY2F0aW9uUGF0aC50b1N0cmluZygpOwotICAgICAgICAvKioqLwotICAgICAgICBTdHJpbmdCdWZmZXIgc3RyID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotICAgICAgICBTdHJpbmcgcyA9IHN1cGVyLnRvU3RyaW5nKCk7Ci0gICAgICAgIGludCBpbmRleDIgPSBzLmxhc3RJbmRleE9mKCcuJyk7Ci0gICAgICAgIGlmIChpbmRleDIgIT0gLTEpIHsKLSAgICAgICAgICAgIHMgPSBzLnN1YnN0cmluZyhpbmRleDIgKyAxKTsKLSAgICAgICAgfQotICAgICAgICBzdHIuYXBwZW5kKHMpOwotICAgICAgICBmb3IoaW50IGkgPTA7aTxmTG9jYXRpb25QYXRocy5sZW5ndGg7IGkrKykgewotICAgICAgICAgICAgc3RyLmFwcGVuZCgnWycpOwotICAgICAgICAgICAgWFBhdGguU3RlcFtdIHN0ZXBzID0gZkxvY2F0aW9uUGF0aHNbaV0uc3RlcHM7Ci0gICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IHN0ZXBzLmxlbmd0aDsgaisrKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGogPT0gZkN1cnJlbnRTdGVwW2ldKSB7Ci0gICAgICAgICAgICAgICAgICAgIHN0ci5hcHBlbmQoJ14nKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgc3RyLmFwcGVuZChzdGVwc1tqXS50b1N0cmluZygpKTsKLSAgICAgICAgICAgICAgICBpZiAoaiA8IHN0ZXBzLmxlbmd0aCAtIDEpIHsKLSAgICAgICAgICAgICAgICAgICAgc3RyLmFwcGVuZCgnLycpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChmQ3VycmVudFN0ZXBbaV0gPT0gc3RlcHMubGVuZ3RoKSB7Ci0gICAgICAgICAgICAgICAgc3RyLmFwcGVuZCgnXicpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgc3RyLmFwcGVuZCgnXScpOwotICAgICAgICAgICAgc3RyLmFwcGVuZCgnLCcpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBzdHIudG9TdHJpbmcoKTsKLSAgICB9IC8vIHRvU3RyaW5nKCk6U3RyaW5nCi0KLSAgICAvLwotICAgIC8vIFByaXZhdGUgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKiogTm9ybWFsaXplcyB0ZXh0LiAqLwotICAgIHByaXZhdGUgU3RyaW5nIG5vcm1hbGl6ZShTdHJpbmcgcykgewotICAgICAgICBTdHJpbmdCdWZmZXIgc3RyID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotICAgICAgICBpbnQgbGVuZ3RoID0gcy5sZW5ndGgoKTsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykgewotICAgICAgICAgICAgY2hhciBjID0gcy5jaGFyQXQoaSk7Ci0gICAgICAgICAgICBzd2l0Y2ggKGMpIHsKLSAgICAgICAgICAgICAgICBjYXNlICdcbic6IHsKLSAgICAgICAgICAgICAgICAgICAgc3RyLmFwcGVuZCgiXFxuIik7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBkZWZhdWx0OiB7Ci0gICAgICAgICAgICAgICAgICAgIHN0ci5hcHBlbmQoYyk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBzdHIudG9TdHJpbmcoKTsKLSAgICB9IC8vIG5vcm1hbGl6ZShTdHJpbmcpOlN0cmluZwotCi0gICAgLy8KLSAgICAvLyBNQUlOCi0gICAgLy8KLQotICAgIC8vIE5PVEU6IFRoZSBtYWluIG9mIHRoaXMgY2xhc3MgaXMgaGVyZSBmb3IgZGVidWdnaW5nIHB1cnBvc2VzLgotICAgIC8vICAgICAgIEhvd2V2ZXIsIGphdmFjIChKREsgMS4xLjgpIGhhcyBhbiBpbnRlcm5hbCBjb21waWxlcgotICAgIC8vICAgICAgIGVycm9yIHdoZW4gY29tcGlsaW5nLiBKaWtlcyBoYXMgbm8gcHJvYmxlbSwgdGhvdWdoLgotICAgIC8vCi0gICAgLy8gICAgICAgSWYgeW91IHdhbnQgdG8gdXNlIHRoaXMgbWFpbiwgdXNlIEppa2VzIHRvIGNvbXBpbGUgYnV0Ci0gICAgLy8gICAgICAgKm5ldmVyKiBjaGVjayBpbiB0aGlzIGNvZGUgdG8gQ1ZTIHdpdGhvdXQgY29tbWVudGluZyBpdAotICAgIC8vICAgICAgIG91dC4gLUFjCi0KLSAgICAvKiogTWFpbiBwcm9ncmFtLiAqLwotICAgIC8qKioKLSAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmd2KSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLQotICAgICAgICBpZiAoREVCVUdfQU5ZKSB7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGFyZ3YubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgZXhwciA9IGFyZ3ZbaV07Ci0gICAgICAgICAgICAgICAgZmluYWwgWFBhdGggeHBhdGggPSBuZXcgWFBhdGgoZXhwciwgc3ltYm9scywgbnVsbCk7Ci0gICAgICAgICAgICAgICAgZmluYWwgWFBhdGhNYXRjaGVyIG1hdGNoZXIgPSBuZXcgWFBhdGhNYXRjaGVyKHhwYXRoLCB0cnVlKTsKLSAgICAgICAgICAgICAgICBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnBhcnNlcnMuU0FYUGFyc2VyIHBhcnNlciA9Ci0gICAgICAgICAgICAgICAgICAgIG5ldyBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnBhcnNlcnMuU0FYUGFyc2VyKHN5bWJvbHMpIHsKLSAgICAgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgc3RhcnREb2N1bWVudCgpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICAgICAgICAgICAgICAgICAgbWF0Y2hlci5zdGFydERvY3VtZW50RnJhZ21lbnQoc3ltYm9scywgbnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgc3RhcnRFbGVtZW50KFFOYW1lIGVsZW1lbnQsIFhNTEF0dHJMaXN0IGF0dHJpYnV0ZXMsIGludCBoYW5kbGUpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICAgICAgICAgICAgICAgICAgbWF0Y2hlci5zdGFydEVsZW1lbnQoZWxlbWVudCwgYXR0cmlidXRlcywgaGFuZGxlKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCBjaGFyYWN0ZXJzKGNoYXJbXSBjaCwgaW50IG9mZnNldCwgaW50IGxlbmd0aCkgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBtYXRjaGVyLmNoYXJhY3RlcnMoY2gsIG9mZnNldCwgbGVuZ3RoKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCBlbmRFbGVtZW50KFFOYW1lIGVsZW1lbnQpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICAgICAgICAgICAgICAgICAgbWF0Y2hlci5lbmRFbGVtZW50KGVsZW1lbnQpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIGVuZERvY3VtZW50KCkgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBtYXRjaGVyLmVuZERvY3VtZW50RnJhZ21lbnQoKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH07Ci0gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCIjIyMjIGFyZ3ZbIitpKyJdOiBcIiIrZXhwcisiXCIgLT4gXCIiK3hwYXRoLnRvU3RyaW5nKCkrJyInKTsKLSAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgdXJpID0gYXJndlsrK2ldOwotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiIyMjIyBhcmd2WyIraSsiXTogIit1cmkpOwotICAgICAgICAgICAgICAgIHBhcnNlci5wYXJzZSh1cmkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICB9IC8vIG1haW4oU3RyaW5nW10pCi0gICAgLyoqKi8KLQotfSAvLyBjbGFzcyBYUGF0aE1hdGNoZXIKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvbW9kZWxzL0NNQnVpbGRlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9tb2RlbHMvQ01CdWlsZGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGNhODgxNTQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9tb2RlbHMvQ01CdWlsZGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0NTAgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMubW9kZWxzOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR0ZC5tb2RlbHMuQ01Ob2RlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5TY2hlbWFTeW1ib2xzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5YU0NvbXBsZXhUeXBlRGVjbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMuWFNEZWNsYXJhdGlvblBvb2w7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlhTRWxlbWVudERlY2w7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlhTTW9kZWxHcm91cEltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlhTUGFydGljbGVEZWNsOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgY29uc3RydWN0cyBjb250ZW50IG1vZGVscyBmb3IgYSBnaXZlbiBncmFtbWFyLgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIEVsZW5hIExpdGFuaSwgSUJNCi0gKiBAYXV0aG9yIFNhbmR5IEdhbywgSUJNCi0gKgotICogQHZlcnNpb24gJElkOiBDTUJ1aWxkZXIuamF2YSx2IDEuMTEgMjAxMC8wOC8wNiAyMzo0OTo0MyBqb2VodyBFeHAgJAotICovCi1wdWJsaWMgY2xhc3MgQ01CdWlsZGVyIHsKLQotICAgIC8vIFJFVklTSVQ6IHNob3VsZCB1cGRhdGUgdGhlIGRlY2wgcG9vbCB0byBjYWNoZSBYU0NNIG9iamVjdHMgdG9vCi0gICAgcHJpdmF0ZSBYU0RlY2xhcmF0aW9uUG9vbCBmRGVjbFBvb2wgPSBudWxsOwotCi0gICAgLy8gSXQgbmV2ZXIgY2hhbmdlcywgc28gYSBzdGF0aWMgbWVtYmVyIGlzIGdvb2QgZW5vdWdoCi0gICAgcHJpdmF0ZSBzdGF0aWMgWFNFbXB0eUNNIGZFbXB0eUNNID0gbmV3IFhTRW1wdHlDTSgpOwotCi0gICAgLy8gbmVlZGVkIGZvciBERkEgY29uc3RydWN0aW9uCi0gICAgcHJpdmF0ZSBpbnQgZkxlYWZDb3VudDsKLSAgICAvLyBuZWVkZWQgZm9yIFVQQQotICAgIHByaXZhdGUgaW50IGZQYXJ0aWNsZUNvdW50OwotICAgIC8vRmFjdG9yeSB0byBjcmVhdGUgQmluLCBVbmksIExlYWYgbm9kZXMKLSAgICBwcml2YXRlIENNTm9kZUZhY3RvcnkgZk5vZGVGYWN0b3J5IDsKLQotICAgIHB1YmxpYyBDTUJ1aWxkZXIoQ01Ob2RlRmFjdG9yeSBub2RlRmFjdG9yeSkgewotICAgICAgICBmRGVjbFBvb2wgPSBudWxsOwotICAgICAgICBmTm9kZUZhY3RvcnkgPSBub2RlRmFjdG9yeSA7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0RGVjbFBvb2woWFNEZWNsYXJhdGlvblBvb2wgZGVjbFBvb2wpIHsKLSAgICAgICAgZkRlY2xQb29sID0gZGVjbFBvb2w7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IGNvbnRlbnQgbW9kZWwgZm9yIHRoZSBhIGdpdmVuIHR5cGUKLSAgICAgKgotICAgICAqIEBwYXJhbSB0eXBlRGVjbCAgZ2V0IGNvbnRlbnQgbW9kZWwgZm9yIHdoaWNoIGNvbXBsZXggdHlwZQotICAgICAqIEByZXR1cm4gICAgICAgICAgYSBjb250ZW50IG1vZGVsIHZhbGlkYXRvcgotICAgICAqLwotICAgIHB1YmxpYyBYU0NNVmFsaWRhdG9yIGdldENvbnRlbnRNb2RlbChYU0NvbXBsZXhUeXBlRGVjbCB0eXBlRGVjbCkgewotCi0gICAgICAgIC8vIGZvciBjb21wbGV4IHR5cGUgd2l0aCBlbXB0eSBvciBzaW1wbGUgY29udGVudCwKLSAgICAgICAgLy8gdGhlcmUgaXMgbm8gY29udGVudCBtb2RlbCB2YWxpZGF0b3IKLSAgICAgICAgc2hvcnQgY29udGVudFR5cGUgPSB0eXBlRGVjbC5nZXRDb250ZW50VHlwZSgpOwotICAgICAgICBpZiAoY29udGVudFR5cGUgPT0gWFNDb21wbGV4VHlwZURlY2wuQ09OVEVOVFRZUEVfU0lNUExFIHx8Ci0gICAgICAgICAgICBjb250ZW50VHlwZSA9PSBYU0NvbXBsZXhUeXBlRGVjbC5DT05URU5UVFlQRV9FTVBUWSkgewotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLQotICAgICAgICBYU1BhcnRpY2xlRGVjbCBwYXJ0aWNsZSA9IChYU1BhcnRpY2xlRGVjbCl0eXBlRGVjbC5nZXRQYXJ0aWNsZSgpOwotCi0gICAgICAgIC8vIGlmIHRoZSBjb250ZW50IGlzIGVsZW1lbnQgb25seSBvciBtaXhlZCwgYnV0IG5vIHBhcnRpY2xlCi0gICAgICAgIC8vIGlzIGRlZmluZWQsIHJldHVybiB0aGUgZW1wdHkgY29udGVudCBtb2RlbAotICAgICAgICBpZiAocGFydGljbGUgPT0gbnVsbCkKLSAgICAgICAgICAgIHJldHVybiBmRW1wdHlDTTsKLQotICAgICAgICAvLyBpZiB0aGUgY29udGVudCBtb2RlbCBjb250YWlucyAiYWxsIiBtb2RlbCBncm91cCwKLSAgICAgICAgLy8gd2UgY3JlYXRlIGFuICJhbGwiIGNvbnRlbnQgbW9kZWwsIG90aGVyd2lzZSBhIERGQSBjb250ZW50IG1vZGVsCi0gICAgICAgIFhTQ01WYWxpZGF0b3IgY21WYWxpZGF0b3IgPSBudWxsOwotICAgICAgICBpZiAocGFydGljbGUuZlR5cGUgPT0gWFNQYXJ0aWNsZURlY2wuUEFSVElDTEVfTU9ERUxHUk9VUCAmJgotICAgICAgICAgICAgKChYU01vZGVsR3JvdXBJbXBsKXBhcnRpY2xlLmZWYWx1ZSkuZkNvbXBvc2l0b3IgPT0gWFNNb2RlbEdyb3VwSW1wbC5NT0RFTEdST1VQX0FMTCkgewotICAgICAgICAgICAgY21WYWxpZGF0b3IgPSBjcmVhdGVBbGxDTShwYXJ0aWNsZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBjbVZhbGlkYXRvciA9IGNyZWF0ZURGQUNNKHBhcnRpY2xlKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vbm93IHdlIGFyZSB0aHJvdWdodCBidWlsZGluZyBjb250ZW50IG1vZGVsIGFuZCBoYXZlIHBhc3NlZCBzdWNlc3NmdWxseSBvZiB0aGUgbm9kZWNvdW50IGNoZWNrCi0gICAgICAgIC8vaWYgc2V0IGJ5IHRoZSBhcHBsaWNhdGlvbgotICAgICAgICBmTm9kZUZhY3RvcnkucmVzZXROb2RlQ291bnQoKSA7Ci0KLSAgICAgICAgLy8gaWYgdGhlIHZhbGlkYXRvciByZXR1cm5lZCBpcyBudWxsLCBpdCBtZWFucyB0aGVyZSBpcyBub3RoaW5nIGluCi0gICAgICAgIC8vIHRoZSBjb250ZW50IG1vZGVsLCBzbyB3ZSByZXR1cm4gdGhlIGVtcHR5IGNvbnRlbnQgbW9kZWwuCi0gICAgICAgIGlmIChjbVZhbGlkYXRvciA9PSBudWxsKQotICAgICAgICAgICAgY21WYWxpZGF0b3IgPSBmRW1wdHlDTTsKLQotICAgICAgICByZXR1cm4gY21WYWxpZGF0b3I7Ci0gICAgfQotCi0gICAgWFNDTVZhbGlkYXRvciBjcmVhdGVBbGxDTShYU1BhcnRpY2xlRGVjbCBwYXJ0aWNsZSkgewotICAgICAgICBpZiAocGFydGljbGUuZk1heE9jY3VycyA9PSAwKQotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0KLSAgICAgICAgLy8gZ2V0IHRoZSBtb2RlbCBncm91cCwgYW5kIGFkZCBhbGwgY2hpbGRyZW4gb2YgaXQgdG8gdGhlIGNvbnRlbnQgbW9kZWwKLSAgICAgICAgWFNNb2RlbEdyb3VwSW1wbCBncm91cCA9IChYU01vZGVsR3JvdXBJbXBsKXBhcnRpY2xlLmZWYWx1ZTsKLSAgICAgICAgLy8gY3JlYXRlIGFuIGFsbCBjb250ZW50IG1vZGVsLiB0aGUgcGFyYW1ldGVyIGluZGljYXRlcyB3aGV0aGVyCi0gICAgICAgIC8vIHRoZSA8YWxsPiBpdHNlbGYgaXMgb3B0aW9uYWwKLSAgICAgICAgWFNBbGxDTSBhbGxDb250ZW50ID0gbmV3IFhTQWxsQ00ocGFydGljbGUuZk1pbk9jY3VycyA9PSAwLCBncm91cC5mUGFydGljbGVDb3VudCk7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZ3JvdXAuZlBhcnRpY2xlQ291bnQ7IGkrKykgewotICAgICAgICAgICAgLy8gYWRkIHRoZSBlbGVtZW50IGRlY2wgdG8gdGhlIGFsbCBjb250ZW50IG1vZGVsCi0gICAgICAgICAgICBhbGxDb250ZW50LmFkZEVsZW1lbnQoKFhTRWxlbWVudERlY2wpZ3JvdXAuZlBhcnRpY2xlc1tpXS5mVmFsdWUsCi0gICAgICAgICAgICBncm91cC5mUGFydGljbGVzW2ldLmZNaW5PY2N1cnMgPT0gMCk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGFsbENvbnRlbnQ7Ci0gICAgfQotCi0gICAgWFNDTVZhbGlkYXRvciBjcmVhdGVERkFDTShYU1BhcnRpY2xlRGVjbCBwYXJ0aWNsZSkgewotICAgICAgICBmTGVhZkNvdW50ID0gMDsKLSAgICAgICAgZlBhcnRpY2xlQ291bnQgPSAwOwotICAgICAgICAvLyBjb252ZXJ0IHBhcnRpY2xlIHRyZWUgdG8gQ00gdHJlZQotICAgICAgICBDTU5vZGUgbm9kZSA9IHVzZVJlcGVhdGluZ0xlYWZOb2RlcyhwYXJ0aWNsZSkgPyBidWlsZENvbXBhY3RTeW50YXhUcmVlKHBhcnRpY2xlKSA6IGJ1aWxkU3ludGF4VHJlZShwYXJ0aWNsZSwgdHJ1ZSk7Ci0gICAgICAgIGlmIChub2RlID09IG51bGwpCi0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgLy8gYnVpbGQgREZBIGNvbnRlbnQgbW9kZWwgZnJvbSB0aGUgQ00gdHJlZQotICAgICAgICByZXR1cm4gbmV3IFhTREZBQ00obm9kZSwgZkxlYWZDb3VudCk7Ci0gICAgfQotCi0gICAgLy8gMS4gY29udmVydCBwYXJ0aWNsZSB0cmVlIHRvIENNIHRyZWU6Ci0gICAgLy8gMi4gZXhwYW5kIGFsbCBvY2N1cnJlbmNlIHZhbHVlczogYXtuLCB1bmJvdW5kZWR9IC0+IGEsIGEsIC4uLiwgYSsKLSAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhe24sIG19IC0+IGEsIGEsIC4uLiwgYT8sIGE/LCAuLi4KLSAgICAvLyAzLiBjb252ZXJ0IG1vZGVsIGdyb3VwcyAoYSwgYiwgYywgLi4uKSBvciAoYSB8IGIgfCBjIHwgLi4uKSB0bwotICAgIC8vICAgIGJpbmFyeSB0cmVlOiAoKChhLGIpLGMpLC4uLikgb3IgKCgoYXxiKXxjKXwuLi4pCi0gICAgLy8gNC4gbWFrZSBzdXJlIGVhY2ggbGVhZiBub2RlIChYU0NNTGVhZikgaGFzIGEgZGlzdGluY3QgcG9zaXRpb24KLSAgICBwcml2YXRlIENNTm9kZSBidWlsZFN5bnRheFRyZWUoWFNQYXJ0aWNsZURlY2wgcGFydGljbGUsIGJvb2xlYW4gb3B0aW1pemUpIHsKLQotICAgICAgICBpbnQgbWF4T2NjdXJzID0gcGFydGljbGUuZk1heE9jY3VyczsKLSAgICAgICAgaW50IG1pbk9jY3VycyA9IHBhcnRpY2xlLmZNaW5PY2N1cnM7Ci0gICAgICAgIHNob3J0IHR5cGUgPSBwYXJ0aWNsZS5mVHlwZTsKLSAgICAgICAgQ01Ob2RlIG5vZGVSZXQgPSBudWxsOwotCi0gICAgICAgIGlmICgodHlwZSA9PSBYU1BhcnRpY2xlRGVjbC5QQVJUSUNMRV9XSUxEQ0FSRCkgfHwKLSAgICAgICAgICAgICh0eXBlID09IFhTUGFydGljbGVEZWNsLlBBUlRJQ0xFX0VMRU1FTlQpKSB7Ci0gICAgICAgICAgICAvLyAodGFzayAxKSBlbGVtZW50IGFuZCB3aWxkY2FyZCBwYXJ0aWNsZXMgc2hvdWxkIGJlIGNvbnZlcnRlZCB0bwotICAgICAgICAgICAgLy8gbGVhZiBub2RlcwotICAgICAgICAgICAgLy8gUkVWSVNJVDogTWFrZSBhIGNsb25lIG9mIHRoZSBsZWFmIHBhcnRpY2xlLCBzbyB0aGF0IGlmIHRoZXJlCi0gICAgICAgICAgICAvLyBhcmUgdHdvIHJlZmVyZW5jZXMgdG8gdGhlIHNhbWUgZ3JvdXAsIHdlIGhhdmUgdHdvIGRpZmZlcmVudAotICAgICAgICAgICAgLy8gbGVhZiBwYXJ0aWNsZXMgZm9yIHRoZSBzYW1lIGVsZW1lbnQgb3Igd2lsZGNhcmQgZGVjbC4KLSAgICAgICAgICAgIC8vIFRoaXMgaXMgdXNlZnVsIGZvciBjaGVja2luZyBVUEEuCi0gICAgICAgICAgICBub2RlUmV0ID0gZk5vZGVGYWN0b3J5LmdldENNTGVhZk5vZGUocGFydGljbGUuZlR5cGUsIHBhcnRpY2xlLmZWYWx1ZSwgZlBhcnRpY2xlQ291bnQrKywgZkxlYWZDb3VudCsrKTsKLSAgICAgICAgICAgIC8vICh0YXNrIDIpIGV4cGFuZCBvY2N1cnJlbmNlIHZhbHVlcwotICAgICAgICAgICAgbm9kZVJldCA9IGV4cGFuZENvbnRlbnRNb2RlbChub2RlUmV0LCBtaW5PY2N1cnMsIG1heE9jY3Vycywgb3B0aW1pemUpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKHR5cGUgPT0gWFNQYXJ0aWNsZURlY2wuUEFSVElDTEVfTU9ERUxHUk9VUCkgewotICAgICAgICAgICAgLy8gKHRhc2sgMSwzKSBjb252ZXJ0IG1vZGVsIGdyb3VwcyB0byBiaW5hcnkgdHJlZXMKLSAgICAgICAgICAgIFhTTW9kZWxHcm91cEltcGwgZ3JvdXAgPSAoWFNNb2RlbEdyb3VwSW1wbClwYXJ0aWNsZS5mVmFsdWU7Ci0gICAgICAgICAgICBDTU5vZGUgdGVtcCA9IG51bGw7Ci0gICAgICAgICAgICAvLyB3aGVuIHRoZSBtb2RlbCBncm91cCBpcyBhIGNob2ljZSBvZiBtb3JlIHRoYW4gb25lIHBhcnRpY2xlcywgYnV0Ci0gICAgICAgICAgICAvLyBvbmx5IG9uZSBvZiB0aGUgcGFydGljbGUgaXMgbm90IGVtcHR5LCAoZm9yIGV4YW1wbGUKLSAgICAgICAgICAgIC8vIDxjaG9pY2U+Ci0gICAgICAgICAgICAvLyAgIDxzZXF1ZW5jZS8+Ci0gICAgICAgICAgICAvLyAgIDxlbGVtZW50IG5hbWU9ImUiLz4KLSAgICAgICAgICAgIC8vIDwvY2hvaWNlPgotICAgICAgICAgICAgLy8gKSB3ZSBjYW4ndCBub3QgcmV0dXJuIHRoYXQgb25lIHBhcnRpY2xlICgiZSIpLiBpbnN0ZWFkLCB3ZSBzaG91bGQKLSAgICAgICAgICAgIC8vIHRyZWF0IHN1Y2ggcGFydGljbGUgYXMgb3B0aW9uYWwgKCJlPyIpLgotICAgICAgICAgICAgLy8gdGhlIGZvbGxvd2luZyBib29sZWFuIHZhcmlhYmxlIGlzIHRydWUgd2hlbiB0aGVyZSBhcmUgYXQgbGVhc3QKLSAgICAgICAgICAgIC8vIDIgbm9uLWVtcHR5IGNoaWxkcmVuLgotICAgICAgICAgICAgYm9vbGVhbiB0d29DaGlsZHJlbiA9IGZhbHNlOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBncm91cC5mUGFydGljbGVDb3VudDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgLy8gZmlyc3QgY29udmVydCBlYWNoIGNoaWxkIHRvIGEgQ00gdHJlZQotICAgICAgICAgICAgICAgIHRlbXAgPSBidWlsZFN5bnRheFRyZWUoZ3JvdXAuZlBhcnRpY2xlc1tpXSwKLSAgICAgICAgICAgICAgICAgICAgICAgIG9wdGltaXplICYmCi0gICAgICAgICAgICAgICAgICAgICAgICBtaW5PY2N1cnMgPT0gMSAmJiBtYXhPY2N1cnMgPT0gMSAmJgotICAgICAgICAgICAgICAgICAgICAgICAgKGdyb3VwLmZDb21wb3NpdG9yID09IFhTTW9kZWxHcm91cEltcGwuTU9ERUxHUk9VUF9TRVFVRU5DRSB8fAotICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwLmZQYXJ0aWNsZUNvdW50ID09IDEpKTsKLSAgICAgICAgICAgICAgICAvLyB0aGVuIGNvbWJpbmUgdGhlbSB1c2luZyBiaW5hcnkgb3BlcmF0aW9uCi0gICAgICAgICAgICAgICAgaWYgKHRlbXAgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBpZiAobm9kZVJldCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBub2RlUmV0ID0gdGVtcDsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVSZXQgPSBmTm9kZUZhY3RvcnkuZ2V0Q01CaW5PcE5vZGUoZ3JvdXAuZkNvbXBvc2l0b3IsIG5vZGVSZXQsIHRlbXApOwotICAgICAgICAgICAgICAgICAgICAgICAgLy8gcmVjb3JkIHRoZSBmYWN0IHRoYXQgdGhlcmUgYXJlIGF0IGxlYXN0IDIgY2hpbGRyZW4KLSAgICAgICAgICAgICAgICAgICAgICAgIHR3b0NoaWxkcmVuID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vICh0YXNrIDIpIGV4cGFuZCBvY2N1cnJlbmNlIHZhbHVlcwotICAgICAgICAgICAgaWYgKG5vZGVSZXQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIC8vIHdoZW4gdGhlIGdyb3VwIGlzICJjaG9pY2UiLCB0aGVyZSBpcyBvbmx5IG9uZSBub24tZW1wdHkKLSAgICAgICAgICAgICAgICAvLyBjaGlsZCwgYW5kIHRoZSBncm91cCBoYWQgbW9yZSB0aGFuIG9uZSBjaGlsZHJlbiwgd2UgbmVlZAotICAgICAgICAgICAgICAgIC8vIHRvIGNyZWF0ZSBhIHplcm8tb3Itb25lIChvcHRpb25hbCkgbm9kZSBmb3IgdGhlIG5vbi1lbXB0eQotICAgICAgICAgICAgICAgIC8vIHBhcnRpY2xlLgotICAgICAgICAgICAgICAgIGlmIChncm91cC5mQ29tcG9zaXRvciA9PSBYU01vZGVsR3JvdXBJbXBsLk1PREVMR1JPVVBfQ0hPSUNFICYmCi0gICAgICAgICAgICAgICAgICAgICF0d29DaGlsZHJlbiAmJiBncm91cC5mUGFydGljbGVDb3VudCA+IDEpIHsKLSAgICAgICAgICAgICAgICAgICAgbm9kZVJldCA9IGZOb2RlRmFjdG9yeS5nZXRDTVVuaU9wTm9kZShYU1BhcnRpY2xlRGVjbC5QQVJUSUNMRV9aRVJPX09SX09ORSwgbm9kZVJldCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIG5vZGVSZXQgPSBleHBhbmRDb250ZW50TW9kZWwobm9kZVJldCwgbWluT2NjdXJzLCBtYXhPY2N1cnMsIGZhbHNlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBub2RlUmV0OwotICAgIH0KLQotICAgIC8vIDIuIGV4cGFuZCBhbGwgb2NjdXJyZW5jZSB2YWx1ZXM6IGF7biwgdW5ib3VuZGVkfSAtPiBhLCBhLCAuLi4sIGErCi0gICAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXtuLCBtfSAtPiBhLCBhLCAuLi4sIGE/LCBhPywgLi4uCi0gICAgLy8gNC4gbWFrZSBzdXJlIGVhY2ggbGVhZiBub2RlIChYU0NNTGVhZikgaGFzIGEgZGlzdGluY3QgcG9zaXRpb24KLSAgICBwcml2YXRlIENNTm9kZSBleHBhbmRDb250ZW50TW9kZWwoQ01Ob2RlIG5vZGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBtaW5PY2N1cnMsIGludCBtYXhPY2N1cnMsIGJvb2xlYW4gb3B0aW1pemUpIHsKLQotICAgICAgICBDTU5vZGUgbm9kZVJldCA9IG51bGw7Ci0KLSAgICAgICAgaWYgKG1pbk9jY3Vycz09MSAmJiBtYXhPY2N1cnM9PTEpIHsKLSAgICAgICAgICAgIG5vZGVSZXQgPSBub2RlOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKG1pbk9jY3Vycz09MCAmJiBtYXhPY2N1cnM9PTEpIHsKLSAgICAgICAgICAgIC8vemVybyBvciBvbmUKLSAgICAgICAgICAgIG5vZGVSZXQgPSBmTm9kZUZhY3RvcnkuZ2V0Q01VbmlPcE5vZGUoWFNQYXJ0aWNsZURlY2wuUEFSVElDTEVfWkVST19PUl9PTkUsIG5vZGUpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKG1pbk9jY3VycyA9PSAwICYmIG1heE9jY3Vycz09U2NoZW1hU3ltYm9scy5PQ0NVUlJFTkNFX1VOQk9VTkRFRCkgewotICAgICAgICAgICAgLy96ZXJvIG9yIG1vcmUKLSAgICAgICAgICAgIG5vZGVSZXQgPSBmTm9kZUZhY3RvcnkuZ2V0Q01VbmlPcE5vZGUoWFNQYXJ0aWNsZURlY2wuUEFSVElDTEVfWkVST19PUl9NT1JFLCBub2RlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChtaW5PY2N1cnMgPT0gMSAmJiBtYXhPY2N1cnM9PVNjaGVtYVN5bWJvbHMuT0NDVVJSRU5DRV9VTkJPVU5ERUQpIHsKLSAgICAgICAgICAgIC8vb25lIG9yIG1vcmUKLSAgICAgICAgICAgIG5vZGVSZXQgPSBmTm9kZUZhY3RvcnkuZ2V0Q01VbmlPcE5vZGUoWFNQYXJ0aWNsZURlY2wuUEFSVElDTEVfT05FX09SX01PUkUsIG5vZGUpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKG9wdGltaXplICYmIG5vZGUudHlwZSgpID09IFhTUGFydGljbGVEZWNsLlBBUlRJQ0xFX0VMRU1FTlQgfHwKLSAgICAgICAgICAgICAgICAgbm9kZS50eXBlKCkgPT0gWFNQYXJ0aWNsZURlY2wuUEFSVElDTEVfV0lMRENBUkQpIHsKLSAgICAgICAgICAgIC8vIE9ubHkgZm9yIGVsZW1lbnRzIGFuZCB3aWxkY2FyZHMsIHN1YnN1bWUgZXtuLG19IGFuZCBle24sdW5ib3VuZGVkfSB0byBlKgotICAgICAgICAgICAgLy8gb3IgZSsgYW5kLCBvbmNlIHRoZSBERkEgcmVhY2hlcyBhIGZpbmFsIHN0YXRlLCBjaGVjayBpZiB0aGUgYWN0dWFsIG51bWJlcgotICAgICAgICAgICAgLy8gb2YgZWxlbWVudHMgaXMgYmV0d2VlbiBtaW5PY2N1cnMgYW5kIG1heE9jY3Vycy4gVGhpcyBuZXcgYWxnb3JpdGhtIHJ1bnMKLSAgICAgICAgICAgIC8vIGluIGNvbnN0YW50IHNwYWNlLgotCi0gICAgICAgICAgICAvLyBUT0RPOiBXaGF0IGlzIHRoZSBpbXBhY3Qgb2YgdGhpcyBvcHRpbWl6YXRpb24gb24gdGhlIFBTVkk/Ci0gICAgICAgICAgICBub2RlUmV0ID0gZk5vZGVGYWN0b3J5LmdldENNVW5pT3BOb2RlKAotICAgICAgICAgICAgICAgICAgICBtaW5PY2N1cnMgPT0gMCA/IFhTUGFydGljbGVEZWNsLlBBUlRJQ0xFX1pFUk9fT1JfTU9SRQotICAgICAgICAgICAgICAgICAgICAgICAgOiBYU1BhcnRpY2xlRGVjbC5QQVJUSUNMRV9PTkVfT1JfTU9SRSwgbm9kZSk7Ci0gICAgICAgICAgICBub2RlUmV0LnNldFVzZXJEYXRhKG5ldyBpbnRbXSB7IG1pbk9jY3VycywgbWF4T2NjdXJzIH0pOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKG1heE9jY3VycyA9PSBTY2hlbWFTeW1ib2xzLk9DQ1VSUkVOQ0VfVU5CT1VOREVEKSB7Ci0gICAgICAgICAgICAvLyA9PiBhLGEsLi4sYSsKLSAgICAgICAgICAgIC8vIGNyZWF0ZSBhKyBub2RlIGZpcnN0LCB0aGVuIHB1dCBtaW5PY2N1cnMtMSBhJ3MgaW4gZnJvbnQgb2YgaXQKLSAgICAgICAgICAgIC8vIGZvciB0aGUgZmlyc3QgdGltZSAibm9kZSIgaXMgdXNlZCwgd2UgZG9uJ3QgbmVlZCB0byBtYWtlIGEgY29weQotICAgICAgICAgICAgLy8gYW5kIGZvciBvdGhlciByZWZlcmVuY2VzIHRvIG5vZGUsIHdlIG1ha2UgY29waWVzCi0gICAgICAgICAgICBub2RlUmV0ID0gZk5vZGVGYWN0b3J5LmdldENNVW5pT3BOb2RlKFhTUGFydGljbGVEZWNsLlBBUlRJQ0xFX09ORV9PUl9NT1JFLCBub2RlKTsKLSAgICAgICAgICAgIC8vICh0YXNrIDQpIHdlIG5lZWQgdG8gY2FsbCBjb3B5Tm9kZSBoZXJlLCBzbyB0aGF0IHdlIGFwcGVuZAotICAgICAgICAgICAgLy8gYW4gZW50aXJlIG5ldyBjb3B5IG9mIHRoZSBub2RlIChhIHN1YnRyZWUpLiB0aGlzIGlzIHRvIGVuc3VyZQotICAgICAgICAgICAgLy8gYWxsIGxlYWYgbm9kZXMgaGF2ZSBkaXN0aW5jdCBwb3NpdGlvbgotICAgICAgICAgICAgLy8gd2Uga25vdyB0aGF0IG1pbk9jY3VycyA+IDEKLSAgICAgICAgICAgIG5vZGVSZXQgPSBmTm9kZUZhY3RvcnkuZ2V0Q01CaW5PcE5vZGUoWFNNb2RlbEdyb3VwSW1wbC5NT0RFTEdST1VQX1NFUVVFTkNFLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtdWx0aU5vZGVzKG5vZGUsIG1pbk9jY3Vycy0xLCB0cnVlKSwgbm9kZVJldCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAvLyB7bixtfSA9PiBhLGEsYSwuLi4oYSksKGEpLC4uLgotICAgICAgICAgICAgLy8gZmlyc3QgbiBhJ3MsIHRoZW4gbS1uIGE/J3MuCi0gICAgICAgICAgICAvLyBjb3B5Tm9kZSBpcyBjYWxsZWQsIGZvciB0aGUgc2FtZSByZWFzb24gYXMgYWJvdmUKLSAgICAgICAgICAgIGlmIChtaW5PY2N1cnMgPiAwKSB7Ci0gICAgICAgICAgICAgICAgbm9kZVJldCA9IG11bHRpTm9kZXMobm9kZSwgbWluT2NjdXJzLCBmYWxzZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAobWF4T2NjdXJzID4gbWluT2NjdXJzKSB7Ci0gICAgICAgICAgICAgICAgbm9kZSA9IGZOb2RlRmFjdG9yeS5nZXRDTVVuaU9wTm9kZShYU1BhcnRpY2xlRGVjbC5QQVJUSUNMRV9aRVJPX09SX09ORSwgbm9kZSk7Ci0gICAgICAgICAgICAgICAgaWYgKG5vZGVSZXQgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBub2RlUmV0ID0gbXVsdGlOb2Rlcyhub2RlLCBtYXhPY2N1cnMtbWluT2NjdXJzLCBmYWxzZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICBub2RlUmV0ID0gZk5vZGVGYWN0b3J5LmdldENNQmluT3BOb2RlKFhTTW9kZWxHcm91cEltcGwuTU9ERUxHUk9VUF9TRVFVRU5DRSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlUmV0LCBtdWx0aU5vZGVzKG5vZGUsIG1heE9jY3Vycy1taW5PY2N1cnMsIHRydWUpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gbm9kZVJldDsKLSAgICB9Ci0KLSAgICBwcml2YXRlIENNTm9kZSBtdWx0aU5vZGVzKENNTm9kZSBub2RlLCBpbnQgbnVtLCBib29sZWFuIGNvcHlGaXJzdCkgewotICAgICAgICBpZiAobnVtID09IDApIHsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgICAgIGlmIChudW0gPT0gMSkgewotICAgICAgICAgICAgcmV0dXJuIGNvcHlGaXJzdCA/IGNvcHlOb2RlKG5vZGUpIDogbm9kZTsKLSAgICAgICAgfQotICAgICAgICBpbnQgbnVtMSA9IG51bS8yOwotICAgICAgICByZXR1cm4gZk5vZGVGYWN0b3J5LmdldENNQmluT3BOb2RlKFhTTW9kZWxHcm91cEltcGwuTU9ERUxHUk9VUF9TRVFVRU5DRSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtdWx0aU5vZGVzKG5vZGUsIG51bTEsIGNvcHlGaXJzdCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXVsdGlOb2Rlcyhub2RlLCBudW0tbnVtMSwgdHJ1ZSkpOwotICAgIH0KLQotICAgIC8vIDQuIG1ha2Ugc3VyZSBlYWNoIGxlYWYgbm9kZSAoWFNDTUxlYWYpIGhhcyBhIGRpc3RpbmN0IHBvc2l0aW9uCi0gICAgcHJpdmF0ZSBDTU5vZGUgY29weU5vZGUoQ01Ob2RlIG5vZGUpIHsKLSAgICAgICAgaW50IHR5cGUgPSBub2RlLnR5cGUoKTsKLSAgICAgICAgLy8gZm9yIGNob2ljZSBvciBzZXF1ZW5jZSwgY29weSB0aGUgdHdvIHN1YnRyZWVzLCBhbmQgY29tYmluZSB0aGVtCi0gICAgICAgIGlmICh0eXBlID09IFhTTW9kZWxHcm91cEltcGwuTU9ERUxHUk9VUF9DSE9JQ0UgfHwKLSAgICAgICAgICAgIHR5cGUgPT0gWFNNb2RlbEdyb3VwSW1wbC5NT0RFTEdST1VQX1NFUVVFTkNFKSB7Ci0gICAgICAgICAgICBYU0NNQmluT3AgYmluID0gKFhTQ01CaW5PcClub2RlOwotICAgICAgICAgICAgbm9kZSA9IGZOb2RlRmFjdG9yeS5nZXRDTUJpbk9wTm9kZSh0eXBlLCBjb3B5Tm9kZShiaW4uZ2V0TGVmdCgpKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvcHlOb2RlKGJpbi5nZXRSaWdodCgpKSk7Ci0gICAgICAgIH0KLSAgICAgICAgLy8gZm9yID8rKiwgY29weSB0aGUgc3VidHJlZSwgYW5kIHB1dCBpdCBpbiBhIG5ldyA/Kyogbm9kZQotICAgICAgICBlbHNlIGlmICh0eXBlID09IFhTUGFydGljbGVEZWNsLlBBUlRJQ0xFX1pFUk9fT1JfTU9SRSB8fAotICAgICAgICAgICAgICAgICB0eXBlID09IFhTUGFydGljbGVEZWNsLlBBUlRJQ0xFX09ORV9PUl9NT1JFIHx8Ci0gICAgICAgICAgICAgICAgIHR5cGUgPT0gWFNQYXJ0aWNsZURlY2wuUEFSVElDTEVfWkVST19PUl9PTkUpIHsKLSAgICAgICAgICAgIFhTQ01VbmlPcCB1bmkgPSAoWFNDTVVuaU9wKW5vZGU7Ci0gICAgICAgICAgICBub2RlID0gZk5vZGVGYWN0b3J5LmdldENNVW5pT3BOb2RlKHR5cGUsIGNvcHlOb2RlKHVuaS5nZXRDaGlsZCgpKSk7Ci0gICAgICAgIH0KLSAgICAgICAgLy8gZm9yIGVsZW1lbnQvd2lsZGNhcmQgKGxlYWYpLCBtYWtlIGEgbmV3IGxlYWYgbm9kZSwKLSAgICAgICAgLy8gd2l0aCBhIGRpc3RpbmN0IHBvc2l0aW9uCi0gICAgICAgIGVsc2UgaWYgKHR5cGUgPT0gWFNQYXJ0aWNsZURlY2wuUEFSVElDTEVfRUxFTUVOVCB8fAotICAgICAgICAgICAgICAgICB0eXBlID09IFhTUGFydGljbGVEZWNsLlBBUlRJQ0xFX1dJTERDQVJEKSB7Ci0gICAgICAgICAgICBYU0NNTGVhZiBsZWFmID0gKFhTQ01MZWFmKW5vZGU7Ci0gICAgICAgICAgICBub2RlID0gZk5vZGVGYWN0b3J5LmdldENNTGVhZk5vZGUobGVhZi50eXBlKCksIGxlYWYuZ2V0TGVhZigpLCBsZWFmLmdldFBhcnRpY2xlSWQoKSwgZkxlYWZDb3VudCsrKTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBub2RlOwotICAgIH0KLQotICAgIC8vIEEgc3BlY2lhbCB2ZXJzaW9uIG9mIGJ1aWxkU3ludGF4VHJlZSgpIHdoaWNoIGJ1aWxkcyBhIGNvbXBhY3Qgc3ludGF4IHRyZWUKLSAgICAvLyBjb250YWluaW5nIGNvbXBvdW5kIGxlYWYgbm9kZXMgd2hpY2ggY2Fycnkgb2NjdXJlbmNlIGluZm9ybWF0aW9uLiBUaGlzIG1ldGhvZAotICAgIC8vIGZvciBidWlsZGluZyB0aGUgc3ludGF4IHRyZWUgaXMgY2hvc2VuIG92ZXIgYnVpbGRTeW50YXhUcmVlKCkgd2hlbgotICAgIC8vIHVzZVJlcGVhdGluZ0xlYWZOb2RlcygpIHJldHVybnMgdHJ1ZS4KLSAgICBwcml2YXRlIENNTm9kZSBidWlsZENvbXBhY3RTeW50YXhUcmVlKFhTUGFydGljbGVEZWNsIHBhcnRpY2xlKSB7Ci0gICAgICAgIGludCBtYXhPY2N1cnMgPSBwYXJ0aWNsZS5mTWF4T2NjdXJzOwotICAgICAgICBpbnQgbWluT2NjdXJzID0gcGFydGljbGUuZk1pbk9jY3VyczsKLSAgICAgICAgc2hvcnQgdHlwZSA9IHBhcnRpY2xlLmZUeXBlOwotICAgICAgICBDTU5vZGUgbm9kZVJldCA9IG51bGw7Ci0KLSAgICAgICAgaWYgKCh0eXBlID09IFhTUGFydGljbGVEZWNsLlBBUlRJQ0xFX1dJTERDQVJEKSB8fAotICAgICAgICAgICAgKHR5cGUgPT0gWFNQYXJ0aWNsZURlY2wuUEFSVElDTEVfRUxFTUVOVCkpIHsKLSAgICAgICAgICAgIHJldHVybiBidWlsZENvbXBhY3RTeW50YXhUcmVlMihwYXJ0aWNsZSwgbWluT2NjdXJzLCBtYXhPY2N1cnMpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKHR5cGUgPT0gWFNQYXJ0aWNsZURlY2wuUEFSVElDTEVfTU9ERUxHUk9VUCkgewotICAgICAgICAgICAgWFNNb2RlbEdyb3VwSW1wbCBncm91cCA9IChYU01vZGVsR3JvdXBJbXBsKXBhcnRpY2xlLmZWYWx1ZTsKLSAgICAgICAgICAgIGlmIChncm91cC5mUGFydGljbGVDb3VudCA9PSAxICYmIChtaW5PY2N1cnMgIT0gMSB8fCBtYXhPY2N1cnMgIT0gMSkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gYnVpbGRDb21wYWN0U3ludGF4VHJlZTIoZ3JvdXAuZlBhcnRpY2xlc1swXSwgbWluT2NjdXJzLCBtYXhPY2N1cnMpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgQ01Ob2RlIHRlbXAgPSBudWxsOwotCi0gICAgICAgICAgICAgICAgLy8gd2hlbiB0aGUgbW9kZWwgZ3JvdXAgaXMgYSBjaG9pY2Ugb2YgbW9yZSB0aGFuIG9uZSBwYXJ0aWNsZXMsIGJ1dAotICAgICAgICAgICAgICAgIC8vIG9ubHkgb25lIG9mIHRoZSBwYXJ0aWNsZSBpcyBub3QgZW1wdHksIChmb3IgZXhhbXBsZQotICAgICAgICAgICAgICAgIC8vIDxjaG9pY2U+Ci0gICAgICAgICAgICAgICAgLy8gICA8c2VxdWVuY2UvPgotICAgICAgICAgICAgICAgIC8vICAgPGVsZW1lbnQgbmFtZT0iZSIvPgotICAgICAgICAgICAgICAgIC8vIDwvY2hvaWNlPgotICAgICAgICAgICAgICAgIC8vICkgd2UgY2FuJ3Qgbm90IHJldHVybiB0aGF0IG9uZSBwYXJ0aWNsZSAoImUiKS4gaW5zdGVhZCwgd2Ugc2hvdWxkCi0gICAgICAgICAgICAgICAgLy8gdHJlYXQgc3VjaCBwYXJ0aWNsZSBhcyBvcHRpb25hbCAoImU/IikuCi0gICAgICAgICAgICAgICAgLy8gdGhlIGZvbGxvd2luZyBpbnQgdmFyaWFibGUga2VlcHMgdHJhY2sgb2YgdGhlIG51bWJlciBvZiBub24tZW1wdHkgY2hpbGRyZW4KLSAgICAgICAgICAgICAgICBpbnQgY291bnQgPSAwOwotICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZ3JvdXAuZlBhcnRpY2xlQ291bnQ7IGkrKykgewotICAgICAgICAgICAgICAgICAgICAvLyBmaXJzdCBjb252ZXJ0IGVhY2ggY2hpbGQgdG8gYSBDTSB0cmVlCi0gICAgICAgICAgICAgICAgICAgIHRlbXAgPSBidWlsZENvbXBhY3RTeW50YXhUcmVlKGdyb3VwLmZQYXJ0aWNsZXNbaV0pOwotICAgICAgICAgICAgICAgICAgICAvLyB0aGVuIGNvbWJpbmUgdGhlbSB1c2luZyBiaW5hcnkgb3BlcmF0aW9uCi0gICAgICAgICAgICAgICAgICAgIGlmICh0ZW1wICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICsrY291bnQ7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAobm9kZVJldCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZVJldCA9IHRlbXA7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlUmV0ID0gZk5vZGVGYWN0b3J5LmdldENNQmluT3BOb2RlKGdyb3VwLmZDb21wb3NpdG9yLCBub2RlUmV0LCB0ZW1wKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpZiAobm9kZVJldCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIHdoZW4gdGhlIGdyb3VwIGlzICJjaG9pY2UiIGFuZCB0aGUgZ3JvdXAgaGFzIG9uZSBvciBtb3JlIGVtcHR5IGNoaWxkcmVuLAotICAgICAgICAgICAgICAgICAgICAvLyB3ZSBuZWVkIHRvIGNyZWF0ZSBhIHplcm8tb3Itb25lIChvcHRpb25hbCkgbm9kZSBmb3IgdGhlIG5vbi1lbXB0eSBwYXJ0aWNsZXMuCi0gICAgICAgICAgICAgICAgICAgIGlmIChncm91cC5mQ29tcG9zaXRvciA9PSBYU01vZGVsR3JvdXBJbXBsLk1PREVMR1JPVVBfQ0hPSUNFICYmIGNvdW50IDwgZ3JvdXAuZlBhcnRpY2xlQ291bnQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVSZXQgPSBmTm9kZUZhY3RvcnkuZ2V0Q01VbmlPcE5vZGUoWFNQYXJ0aWNsZURlY2wuUEFSVElDTEVfWkVST19PUl9PTkUsIG5vZGVSZXQpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBub2RlUmV0OwotICAgIH0KLQotICAgIHByaXZhdGUgQ01Ob2RlIGJ1aWxkQ29tcGFjdFN5bnRheFRyZWUyKFhTUGFydGljbGVEZWNsIHBhcnRpY2xlLCBpbnQgbWluT2NjdXJzLCBpbnQgbWF4T2NjdXJzKSB7Ci0gICAgICAgIC8vIENvbnZlcnQgZWxlbWVudCBhbmQgd2lsZGNhcmQgcGFydGljbGVzIHRvIGxlYWYgbm9kZXMuIFdyYXAgcmVwZWF0aW5nIHBhcnRpY2xlcyBpbiBhIENNVW5pT3BOb2RlLgotICAgICAgICBDTU5vZGUgbm9kZVJldCA9IG51bGw7Ci0gICAgICAgIGlmIChtaW5PY2N1cnMgPT0gMSAmJiBtYXhPY2N1cnMgPT0gMSkgewotICAgICAgICAgICAgbm9kZVJldCA9IGZOb2RlRmFjdG9yeS5nZXRDTUxlYWZOb2RlKHBhcnRpY2xlLmZUeXBlLCBwYXJ0aWNsZS5mVmFsdWUsIGZQYXJ0aWNsZUNvdW50KyssIGZMZWFmQ291bnQrKyk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAobWluT2NjdXJzID09IDAgJiYgbWF4T2NjdXJzID09IDEpIHsKLSAgICAgICAgICAgIC8vIHplcm8gb3Igb25lCi0gICAgICAgICAgICBub2RlUmV0ID0gZk5vZGVGYWN0b3J5LmdldENNTGVhZk5vZGUocGFydGljbGUuZlR5cGUsIHBhcnRpY2xlLmZWYWx1ZSwgZlBhcnRpY2xlQ291bnQrKywgZkxlYWZDb3VudCsrKTsKLSAgICAgICAgICAgIG5vZGVSZXQgPSBmTm9kZUZhY3RvcnkuZ2V0Q01VbmlPcE5vZGUoWFNQYXJ0aWNsZURlY2wuUEFSVElDTEVfWkVST19PUl9PTkUsIG5vZGVSZXQpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKG1pbk9jY3VycyA9PSAwICYmIG1heE9jY3Vycz09U2NoZW1hU3ltYm9scy5PQ0NVUlJFTkNFX1VOQk9VTkRFRCkgewotICAgICAgICAgICAgLy8gemVybyBvciBtb3JlCi0gICAgICAgICAgICBub2RlUmV0ID0gZk5vZGVGYWN0b3J5LmdldENNTGVhZk5vZGUocGFydGljbGUuZlR5cGUsIHBhcnRpY2xlLmZWYWx1ZSwgZlBhcnRpY2xlQ291bnQrKywgZkxlYWZDb3VudCsrKTsKLSAgICAgICAgICAgIG5vZGVSZXQgPSBmTm9kZUZhY3RvcnkuZ2V0Q01VbmlPcE5vZGUoWFNQYXJ0aWNsZURlY2wuUEFSVElDTEVfWkVST19PUl9NT1JFLCBub2RlUmV0KTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChtaW5PY2N1cnMgPT0gMSAmJiBtYXhPY2N1cnM9PVNjaGVtYVN5bWJvbHMuT0NDVVJSRU5DRV9VTkJPVU5ERUQpIHsKLSAgICAgICAgICAgIC8vIG9uZSBvciBtb3JlCi0gICAgICAgICAgICBub2RlUmV0ID0gZk5vZGVGYWN0b3J5LmdldENNTGVhZk5vZGUocGFydGljbGUuZlR5cGUsIHBhcnRpY2xlLmZWYWx1ZSwgZlBhcnRpY2xlQ291bnQrKywgZkxlYWZDb3VudCsrKTsKLSAgICAgICAgICAgIG5vZGVSZXQgPSBmTm9kZUZhY3RvcnkuZ2V0Q01VbmlPcE5vZGUoWFNQYXJ0aWNsZURlY2wuUEFSVElDTEVfT05FX09SX01PUkUsIG5vZGVSZXQpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgLy8ge24sbX06IEluc3RlYWQgb2YgZXhwYW5kaW5nIHRoaXMgb3V0LCBjcmVhdGUgYSBjb21wb3VuZCBsZWFmIG5vZGUgd2hpY2ggY2FycmllcyB0aGUKLSAgICAgICAgICAgIC8vIG9jY3VyZW5jZSBpbmZvcm1hdGlvbiBhbmQgd3JhcCBpdCBpbiB0aGUgYXBwcm9wcmlhdGUgQ01VbmlPcE5vZGUuCi0gICAgICAgICAgICBub2RlUmV0ID0gZk5vZGVGYWN0b3J5LmdldENNUmVwZWF0aW5nTGVhZk5vZGUocGFydGljbGUuZlR5cGUsIHBhcnRpY2xlLmZWYWx1ZSwgbWluT2NjdXJzLCBtYXhPY2N1cnMsIGZQYXJ0aWNsZUNvdW50KyssIGZMZWFmQ291bnQrKyk7Ci0gICAgICAgICAgICBpZiAobWluT2NjdXJzID09IDApIHsKLSAgICAgICAgICAgICAgICBub2RlUmV0ID0gZk5vZGVGYWN0b3J5LmdldENNVW5pT3BOb2RlKFhTUGFydGljbGVEZWNsLlBBUlRJQ0xFX1pFUk9fT1JfTU9SRSwgbm9kZVJldCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBub2RlUmV0ID0gZk5vZGVGYWN0b3J5LmdldENNVW5pT3BOb2RlKFhTUGFydGljbGVEZWNsLlBBUlRJQ0xFX09ORV9PUl9NT1JFLCBub2RlUmV0KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbm9kZVJldDsKLSAgICB9Ci0KLSAgICAvLyBUaGlzIG1ldGhvZCBjaGVja3MgaWYgdGhpcyBwYXJ0aWNsZSBjYW4gYmUgdHJhbnNmb3JtZWQgaW50byBhIGNvbXBhY3Qgc3ludGF4Ci0gICAgLy8gdHJlZSBjb250YWluaW5nIGNvbXBvdW5kIGxlYWYgbm9kZXMgd2hpY2ggY2Fycnkgb2NjdXJlbmNlIGluZm9ybWF0aW9uLiBDdXJyZW50bHkKLSAgICAvLyBpdCByZXR1cm5zIHRydWUgaWYgZWFjaCBtb2RlbCBncm91cCBoYXMgbWluT2NjdXJzL21heE9jY3VycyA9PSAxIG9yCi0gICAgLy8gY29udGFpbnMgb25seSBvbmUgZWxlbWVudC93aWxkY2FyZCBwYXJ0aWNsZSB3aXRoIG1pbk9jY3Vycy9tYXhPY2N1cnMgPT0gMS4KLSAgICBwcml2YXRlIGJvb2xlYW4gdXNlUmVwZWF0aW5nTGVhZk5vZGVzKFhTUGFydGljbGVEZWNsIHBhcnRpY2xlKSB7Ci0gICAgICAgIGludCBtYXhPY2N1cnMgPSBwYXJ0aWNsZS5mTWF4T2NjdXJzOwotICAgICAgICBpbnQgbWluT2NjdXJzID0gcGFydGljbGUuZk1pbk9jY3VyczsKLSAgICAgICAgc2hvcnQgdHlwZSA9IHBhcnRpY2xlLmZUeXBlOwotCi0gICAgICAgIGlmICh0eXBlID09IFhTUGFydGljbGVEZWNsLlBBUlRJQ0xFX01PREVMR1JPVVApIHsKLSAgICAgICAgICAgIFhTTW9kZWxHcm91cEltcGwgZ3JvdXAgPSAoWFNNb2RlbEdyb3VwSW1wbCkgcGFydGljbGUuZlZhbHVlOwotICAgICAgICAgICAgaWYgKG1pbk9jY3VycyAhPSAxIHx8IG1heE9jY3VycyAhPSAxKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGdyb3VwLmZQYXJ0aWNsZUNvdW50ID09IDEpIHsKLSAgICAgICAgICAgICAgICAgICAgWFNQYXJ0aWNsZURlY2wgcGFydGljbGUyID0gKFhTUGFydGljbGVEZWNsKSBncm91cC5mUGFydGljbGVzWzBdOwotICAgICAgICAgICAgICAgICAgICBzaG9ydCB0eXBlMiA9IHBhcnRpY2xlMi5mVHlwZTsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuICgodHlwZTIgPT0gWFNQYXJ0aWNsZURlY2wuUEFSVElDTEVfRUxFTUVOVCB8fAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUyID09IFhTUGFydGljbGVEZWNsLlBBUlRJQ0xFX1dJTERDQVJEKSAmJgotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcnRpY2xlMi5mTWluT2NjdXJzID09IDEgJiYKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJ0aWNsZTIuZk1heE9jY3VycyA9PSAxKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgcmV0dXJuIChncm91cC5mUGFydGljbGVDb3VudCA9PSAwKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZ3JvdXAuZlBhcnRpY2xlQ291bnQ7ICsraSkgewotICAgICAgICAgICAgICAgIGlmICghdXNlUmVwZWF0aW5nTGVhZk5vZGVzKGdyb3VwLmZQYXJ0aWNsZXNbaV0pKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9tb2RlbHMvQ01Ob2RlRmFjdG9yeS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9tb2RlbHMvQ01Ob2RlRmFjdG9yeS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkMDk0YTViLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvbW9kZWxzL0NNTm9kZUZhY3RvcnkuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE2OCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAzLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLm1vZGVsczsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5Db25zdGFudHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLlhNTEVycm9yUmVwb3J0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR0ZC5tb2RlbHMuQ01Ob2RlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5YU01lc3NhZ2VGb3JtYXR0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlscy5YTUxTZWN1cml0eU1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTENvbXBvbmVudE1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci0KLS8qKgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yICBOZWVyYWogQmFqYWoKLSAqCi0gKiBAdmVyc2lvbiAkSWQ6IENNTm9kZUZhY3RvcnkuamF2YSx2IDEuNyAyMDEwLTExLTAxIDA0OjM5OjU4IGpvZWh3IEV4cCAkCi0gKi8KLXB1YmxpYyBjbGFzcyBDTU5vZGVGYWN0b3J5IHsKLQotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IGVycm9yIHJlcG9ydGVyLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJPUl9SRVBPUlRFUiA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLkVSUk9SX1JFUE9SVEVSX1BST1BFUlRZOwotCi0gICAgLyoqIHByb3BlcnR5IGlkZW50aWZpZXI6IHNlY3VyaXR5IG1hbmFnZXIuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFNFQ1VSSVRZX01BTkFHRVIgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5TRUNVUklUWV9NQU5BR0VSX1BST1BFUlRZOwotCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbiBERUJVRyA9IGZhbHNlIDsKLQotICAgIC8vCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE1VTFRJUExJQ0lUWSA9IDEgOwotCi0gICAgLy9jb3VudCBvZiBudW1iZXIgb2Ygbm9kZXMgY3JlYXRlZAotICAgIHByaXZhdGUgaW50IG5vZGVDb3VudCA9IDA7Ci0KLSAgICAvL05vLiBvZiBub2RlcyBhbGxvd2VkLgotICAgIHByaXZhdGUgaW50IG1heE5vZGVMaW1pdCA7Ci0KLQotICAgIC8qKgotICAgICAqIEVycm9yIHJlcG9ydGVyLiBUaGlzIHByb3BlcnR5IGlkZW50aWZpZXIgaXM6Ci0gICAgICogaHR0cDovL2FwYWNoZS5vcmcveG1sL3Byb3BlcnRpZXMvaW50ZXJuYWwvZXJyb3ItcmVwb3J0ZXIKLSAgICAgKi8KLSAgICBwcml2YXRlIFhNTEVycm9yUmVwb3J0ZXIgZkVycm9yUmVwb3J0ZXI7Ci0KLSAgICAvLyBzdG9yZXMgZGVmYXVsdHMgZm9yIGRpZmZlcmVudCBzZWN1cml0eSBob2xlcyAobWF4T2NjdXJMaW1pdCBpbiBjdXJyZW50IGNvbnRleHQpIGlmIGl0IGhhcwotICAgIC8vIGJlZW4gc2V0IG9uIHRoZSBjb25maWd1cmF0aW9uLgotICAgIHByaXZhdGUgWE1MU2VjdXJpdHlNYW5hZ2VyIGZTZWN1cml0eU1hbmFnZXIgPSBudWxsOwotCi0gICAgLyoqIGRlZmF1bHQgY29uc3RydWN0b3IgKi8KLSAgICBwdWJsaWMgQ01Ob2RlRmFjdG9yeSgpIHsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCByZXNldChYTUxDb21wb25lbnRNYW5hZ2VyIGNvbXBvbmVudE1hbmFnZXIpewotICAgICAgICBmRXJyb3JSZXBvcnRlciA9IChYTUxFcnJvclJlcG9ydGVyKWNvbXBvbmVudE1hbmFnZXIuZ2V0UHJvcGVydHkoRVJST1JfUkVQT1JURVIpOwotICAgICAgICB0cnkgewotICAgICAgICAgICAgZlNlY3VyaXR5TWFuYWdlciA9IChYTUxTZWN1cml0eU1hbmFnZXIpY29tcG9uZW50TWFuYWdlci5nZXRQcm9wZXJ0eShTRUNVUklUWV9NQU5BR0VSKTsKLSAgICAgICAgICAgIC8vd2UgYXJlIHNldHRpbmcgdGhlIGxpbWl0IG9mIG51bWJlciBvZiBub2RlcyB0byAzdGltZXMgdGhlIG1heE9jY3VyIHZhbHVlLi4KLSAgICAgICAgICAgIGlmKGZTZWN1cml0eU1hbmFnZXIgIT0gbnVsbCl7Ci0gICAgICAgICAgICAgICAgbWF4Tm9kZUxpbWl0ID0gZlNlY3VyaXR5TWFuYWdlci5nZXRMaW1pdChYTUxTZWN1cml0eU1hbmFnZXIuTGltaXQuTUFYX09DQ1VSX05PREVfTElNSVQpICogTVVMVElQTElDSVRZIDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICBmU2VjdXJpdHlNYW5hZ2VyID0gbnVsbDsKLSAgICAgICAgfQotCi0gICAgfS8vcmVzZXQoKQotCi0gICAgcHVibGljIENNTm9kZSBnZXRDTUxlYWZOb2RlKGludCB0eXBlLCBPYmplY3QgbGVhZiwgaW50IGlkLCBpbnQgcG9zaXRpb24pIHsKLSAgICAgICAgcmV0dXJuIG5ldyBYU0NNTGVhZih0eXBlLCBsZWFmLCBpZCwgcG9zaXRpb24pIDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgQ01Ob2RlIGdldENNUmVwZWF0aW5nTGVhZk5vZGUoaW50IHR5cGUsIE9iamVjdCBsZWFmLAotICAgICAgICAgICAgaW50IG1pbk9jY3VycywgaW50IG1heE9jY3VycywgaW50IGlkLCBpbnQgcG9zaXRpb24pIHsKLSAgICAgICAgbm9kZUNvdW50Q2hlY2soKTsKLSAgICAgICAgcmV0dXJuIG5ldyBYU0NNUmVwZWF0aW5nTGVhZih0eXBlLCBsZWFmLCBtaW5PY2N1cnMsIG1heE9jY3VycywgaWQsIHBvc2l0aW9uKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgQ01Ob2RlIGdldENNVW5pT3BOb2RlKGludCB0eXBlLCBDTU5vZGUgY2hpbGROb2RlKSB7Ci0gICAgICAgIG5vZGVDb3VudENoZWNrKCk7Ci0gICAgICAgIHJldHVybiBuZXcgWFNDTVVuaU9wKHR5cGUsIGNoaWxkTm9kZSkgOwotICAgIH0KLQotICAgIHB1YmxpYyBDTU5vZGUgZ2V0Q01CaW5PcE5vZGUoaW50IHR5cGUsIENNTm9kZSBsZWZ0Tm9kZSwgQ01Ob2RlIHJpZ2h0Tm9kZSkgewotICAgICAgICByZXR1cm4gbmV3IFhTQ01CaW5PcCh0eXBlLCBsZWZ0Tm9kZSwgcmlnaHROb2RlKSA7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgbm9kZUNvdW50Q2hlY2soKXsKLSAgICAgICAgaWYoIGZTZWN1cml0eU1hbmFnZXIgIT0gbnVsbCAmJiAhZlNlY3VyaXR5TWFuYWdlci5pc05vTGltaXQobWF4Tm9kZUxpbWl0KSAmJgotICAgICAgICAgICAgICAgIG5vZGVDb3VudCsrID4gbWF4Tm9kZUxpbWl0KXsKLSAgICAgICAgICAgIGlmKERFQlVHKXsKLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIm5vZGVDb3VudCA9ICIgKyBub2RlQ291bnQgKSA7Ci0gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJub2RlTGltaXQgPSAiICsgbWF4Tm9kZUxpbWl0ICkgOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IoWFNNZXNzYWdlRm9ybWF0dGVyLlNDSEVNQV9ET01BSU4sICJNYXhPY2N1ckxpbWl0IiwgbmV3IE9iamVjdFtdeyBuZXcgSW50ZWdlcihtYXhOb2RlTGltaXQpIH0sIFhNTEVycm9yUmVwb3J0ZXIuU0VWRVJJVFlfRkFUQUxfRVJST1IpOwotICAgICAgICAgICAgLy8gc2ltaWxhcmx5IHRvIGVudGl0eSBtYW5hZ2VyIGJlaGF2aW91ciwgdGFrZSBpbnRvIGFjY29udAotICAgICAgICAgICAgLy8gYmVoYXZpb3VyIGlmIGNvbnRpbnVlLWFmdGVyLWZhdGFsLWVycm9yIGlzIHNldC4KLSAgICAgICAgICAgIG5vZGVDb3VudCA9IDA7Ci0gICAgICAgIH0KLQotICAgIH0vL25vZGVDb3VudENoZWNrKCkKLQotICAgIC8vcmVzZXQgdGhlIG5vZGUgY291bnQKLSAgICBwdWJsaWMgdm9pZCByZXNldE5vZGVDb3VudCgpewotICAgICAgICBub2RlQ291bnQgPSAwIDsKLSAgICB9Ci0gICAgICAgIC8qKgotICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIGEgcHJvcGVydHkuIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSB0aGUgY29tcG9uZW50Ci0gICAgICogbWFuYWdlciBhbnkgdGltZSBhZnRlciByZXNldCB3aGVuIGEgcHJvcGVydHkgY2hhbmdlcyB2YWx1ZS4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IENvbXBvbmVudHMgc2hvdWxkIHNpbGVudGx5IGlnbm9yZSBwcm9wZXJ0aWVzCi0gICAgICogdGhhdCBkbyBub3QgYWZmZWN0IHRoZSBvcGVyYXRpb24gb2YgdGhlIGNvbXBvbmVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBwcm9wZXJ0eUlkIFRoZSBwcm9wZXJ0eSBpZGVudGlmaWVyLgotICAgICAqIEBwYXJhbSB2YWx1ZSAgICAgIFRoZSB2YWx1ZSBvZiB0aGUgcHJvcGVydHkuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24gVGhlIGNvbXBvbmVudCBzaG91bGQgbm90IHRocm93Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMgZXhjZXB0aW9uLgotICAgICAqIEB0aHJvd3MgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIFRoZSBjb21wb25lbnQgc2hvdWxkIG5vdCB0aHJvdwotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMgZXhjZXB0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFByb3BlcnR5KFN0cmluZyBwcm9wZXJ0eUlkLCBPYmplY3QgdmFsdWUpCi0gICAgICAgIHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIHsKLQotICAgICAgICAvLyBYZXJjZXMgcHJvcGVydGllcwotICAgICAgICBpZiAocHJvcGVydHlJZC5zdGFydHNXaXRoKENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYKSkgewotICAgICAgICAgICAgICAgIGZpbmFsIGludCBzdWZmaXhMZW5ndGggPSBwcm9wZXJ0eUlkLmxlbmd0aCgpIC0gQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVgubGVuZ3RoKCk7Ci0KLSAgICAgICAgICAgIGlmIChzdWZmaXhMZW5ndGggPT0gQ29uc3RhbnRzLlNFQ1VSSVRZX01BTkFHRVJfUFJPUEVSVFkubGVuZ3RoKCkgJiYKLSAgICAgICAgICAgICAgICBwcm9wZXJ0eUlkLmVuZHNXaXRoKENvbnN0YW50cy5TRUNVUklUWV9NQU5BR0VSX1BST1BFUlRZKSkgewotICAgICAgICAgICAgICAgIGZTZWN1cml0eU1hbmFnZXIgPSAoWE1MU2VjdXJpdHlNYW5hZ2VyKXZhbHVlOwotICAgICAgICAgICAgICAgIG1heE5vZGVMaW1pdCA9IChmU2VjdXJpdHlNYW5hZ2VyICE9IG51bGwpID8KLSAgICAgICAgICAgICAgICAgICAgICAgIGZTZWN1cml0eU1hbmFnZXIuZ2V0TGltaXQoWE1MU2VjdXJpdHlNYW5hZ2VyLkxpbWl0Lk1BWF9PQ0NVUl9OT0RFX0xJTUlUKSAqIE1VTFRJUExJQ0lUWSA6IDAgOwotICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChzdWZmaXhMZW5ndGggPT0gQ29uc3RhbnRzLkVSUk9SX1JFUE9SVEVSX1BST1BFUlRZLmxlbmd0aCgpICYmCi0gICAgICAgICAgICAgICAgcHJvcGVydHlJZC5lbmRzV2l0aChDb25zdGFudHMuRVJST1JfUkVQT1JURVJfUFJPUEVSVFkpKSB7Ci0gICAgICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIgPSAoWE1MRXJyb3JSZXBvcnRlcil2YWx1ZTsKLSAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgIH0gLy8gc2V0UHJvcGVydHkoU3RyaW5nLE9iamVjdCkKLQotfS8vQ01Ob2RlRmFjdG9yeSgpCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL21vZGVscy9YU0FsbENNLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL21vZGVscy9YU0FsbENNLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGYyY2YwYTcuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9tb2RlbHMvWFNBbGxDTS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjI0ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLm1vZGVsczsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlFOYW1lOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5YU0VsZW1lbnREZWNsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5TdWJzdGl0dXRpb25Hcm91cEhhbmRsZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlhNTFNjaGVtYUV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMuWFNDb25zdHJhaW50czsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci1pbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKLQotLyoqCi0gKiBYU0FsbENNIGltcGxlbWVudHMgWFNDTVZhbGlkYXRvciBhbmQgaGFuZGxlcyAmbHQ7YWxsJmd0Oy4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBQYXZhbmkgTXVrdGhpcHVkaSwgU3VuIE1pY3Jvc3lzdGVtcyBJbmMuCi0gKiBAdmVyc2lvbiAkSWQ6IFhTQWxsQ00uamF2YSx2IDEuMTAgMjAxMC0xMS0wMSAwNDozOTo1OCBqb2VodyBFeHAgJAotICovCi1wdWJsaWMgY2xhc3MgWFNBbGxDTSBpbXBsZW1lbnRzIFhTQ01WYWxpZGF0b3IgewotCi0gICAgLy8KLSAgICAvLyBDb25zdGFudHMKLSAgICAvLwotCi0gICAgLy8gc3RhcnQgdGhlIGNvbnRlbnQgbW9kZWw6IGRpZCBub3Qgc2VlIGFueSBjaGlsZHJlbgotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHNob3J0IFNUQVRFX1NUQVJUID0gMDsKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBzaG9ydCBTVEFURV9WQUxJRCA9IDE7Ci0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgc2hvcnQgU1RBVEVfQ0hJTEQgPSAxOwotCi0KLSAgICAvLwotICAgIC8vIERhdGEKLSAgICAvLwotCi0gICAgcHJpdmF0ZSBYU0VsZW1lbnREZWNsIGZBbGxFbGVtZW50c1tdOwotICAgIHByaXZhdGUgYm9vbGVhbiBmSXNPcHRpb25hbEVsZW1lbnRbXTsKLSAgICBwcml2YXRlIGJvb2xlYW4gZkhhc09wdGlvbmFsQ29udGVudCA9IGZhbHNlOwotICAgIHByaXZhdGUgaW50IGZOdW1FbGVtZW50cyA9IDA7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0cnVjdG9ycwotICAgIC8vCi0KLSAgICBwdWJsaWMgWFNBbGxDTSAoYm9vbGVhbiBoYXNPcHRpb25hbENvbnRlbnQsIGludCBzaXplKSB7Ci0gICAgICAgIGZIYXNPcHRpb25hbENvbnRlbnQgPSBoYXNPcHRpb25hbENvbnRlbnQ7Ci0gICAgICAgIGZBbGxFbGVtZW50cyA9IG5ldyBYU0VsZW1lbnREZWNsW3NpemVdOwotICAgICAgICBmSXNPcHRpb25hbEVsZW1lbnQgPSBuZXcgYm9vbGVhbltzaXplXTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBhZGRFbGVtZW50IChYU0VsZW1lbnREZWNsIGVsZW1lbnQsIGJvb2xlYW4gaXNPcHRpb25hbCkgewotICAgICAgICBmQWxsRWxlbWVudHNbZk51bUVsZW1lbnRzXSA9IGVsZW1lbnQ7Ci0gICAgICAgIGZJc09wdGlvbmFsRWxlbWVudFtmTnVtRWxlbWVudHNdID0gaXNPcHRpb25hbDsKLSAgICAgICAgZk51bUVsZW1lbnRzKys7Ci0gICAgfQotCi0KLSAgICAvLwotICAgIC8vIFhTQ01WYWxpZGF0b3IgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZHMgdG8gYmUgY2FsbGVkIG9uIGVudGVyaW5nIGEgZmlyc3QgZWxlbWVudCB3aG9zZSB0eXBlCi0gICAgICogaGFzIHRoaXMgY29udGVudCBtb2RlbC4gSXQgd2lsbCByZXR1cm4gdGhlIGluaXRpYWwgc3RhdGUgb2YgdGhlCi0gICAgICogY29udGVudCBtb2RlbAotICAgICAqCi0gICAgICogQHJldHVybiBTdGFydCBzdGF0ZSBvZiB0aGUgY29udGVudCBtb2RlbAotICAgICAqLwotICAgIHB1YmxpYyBpbnRbXSBzdGFydENvbnRlbnRNb2RlbCgpIHsKLQotICAgICAgICBpbnRbXSBzdGF0ZSA9IG5ldyBpbnRbZk51bUVsZW1lbnRzICsgMV07Ci0KLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPD0gZk51bUVsZW1lbnRzOyBpKyspIHsKLSAgICAgICAgICAgIHN0YXRlW2ldID0gU1RBVEVfU1RBUlQ7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHN0YXRlOwotICAgIH0KLQotICAgIC8vIGNvbnZpbmllbnQgbWV0aG9kOiB3aGVuIGVycm9yIG9jY3VycywgdG8gZmluZCBhIG1hdGNoaW5nIGRlY2wKLSAgICAvLyBmcm9tIHRoZSBjYW5kaWRhdGUgZWxlbWVudHMuCi0gICAgT2JqZWN0IGZpbmRNYXRjaGluZ0RlY2woUU5hbWUgZWxlbWVudE5hbWUsIFN1YnN0aXR1dGlvbkdyb3VwSGFuZGxlciBzdWJHcm91cEhhbmRsZXIpIHsKLSAgICAgICAgT2JqZWN0IG1hdGNoaW5nRGVjbCA9IG51bGw7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZk51bUVsZW1lbnRzOyBpKyspIHsKLSAgICAgICAgICAgIG1hdGNoaW5nRGVjbCA9IHN1Ykdyb3VwSGFuZGxlci5nZXRNYXRjaGluZ0VsZW1EZWNsKGVsZW1lbnROYW1lLCBmQWxsRWxlbWVudHNbaV0pOwotICAgICAgICAgICAgaWYgKG1hdGNoaW5nRGVjbCAhPSBudWxsKQotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBtYXRjaGluZ0RlY2w7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhlIG1ldGhvZCBjb3JyZXNwb25kcyB0byBvbmUgdHJhbnNpdGlvbiBpbiB0aGUgY29udGVudCBtb2RlbC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlbGVtZW50TmFtZQotICAgICAqIEBwYXJhbSBjdXJyZW50U3RhdGUgIEN1cnJlbnQgc3RhdGUKLSAgICAgKiBAcmV0dXJuIGFuIGVsZW1lbnQgZGVjbCBvYmplY3QKLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0IG9uZVRyYW5zaXRpb24gKFFOYW1lIGVsZW1lbnROYW1lLCBpbnRbXSBjdXJyZW50U3RhdGUsIFN1YnN0aXR1dGlvbkdyb3VwSGFuZGxlciBzdWJHcm91cEhhbmRsZXIpIHsKLQotICAgICAgICAvLyBlcnJvciBzdGF0ZQotICAgICAgICBpZiAoY3VycmVudFN0YXRlWzBdIDwgMCkgewotICAgICAgICAgICAgY3VycmVudFN0YXRlWzBdID0gWFNDTVZhbGlkYXRvci5TVUJTRVFVRU5UX0VSUk9SOwotICAgICAgICAgICAgcmV0dXJuIGZpbmRNYXRjaGluZ0RlY2woZWxlbWVudE5hbWUsIHN1Ykdyb3VwSGFuZGxlcik7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBzZWVuIGNoaWxkCi0gICAgICAgIGN1cnJlbnRTdGF0ZVswXSA9IFNUQVRFX0NISUxEOwotCi0gICAgICAgIE9iamVjdCBtYXRjaGluZ0RlY2wgPSBudWxsOwotCi0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZk51bUVsZW1lbnRzOyBpKyspIHsKLSAgICAgICAgICAgIC8vIHdlIG9ubHkgdHJ5IHRvIGxvb2sgZm9yIGEgbWF0Y2hpbmcgZGVjbCBpZiB3ZSBoYXZlIG5vdCBzZWVuCi0gICAgICAgICAgICAvLyB0aGlzIGVsZW1lbnQgeWV0LgotICAgICAgICAgICAgaWYgKGN1cnJlbnRTdGF0ZVtpKzFdICE9IFNUQVRFX1NUQVJUKQotICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgbWF0Y2hpbmdEZWNsID0gc3ViR3JvdXBIYW5kbGVyLmdldE1hdGNoaW5nRWxlbURlY2woZWxlbWVudE5hbWUsIGZBbGxFbGVtZW50c1tpXSk7Ci0gICAgICAgICAgICBpZiAobWF0Y2hpbmdEZWNsICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAvLyBmb3VuZCB0aGUgZGVjbCwgbWFyayB0aGlzIGVsZW1lbnQgYXMgInNlZW4iLgotICAgICAgICAgICAgICAgIGN1cnJlbnRTdGF0ZVtpKzFdID0gU1RBVEVfVkFMSUQ7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIG1hdGNoaW5nRGVjbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIGNvdWxkbid0IGZpbmQgdGhlIGRlY2wsIGNoYW5nZSB0byBlcnJvciBzdGF0ZS4KLSAgICAgICAgY3VycmVudFN0YXRlWzBdID0gWFNDTVZhbGlkYXRvci5GSVJTVF9FUlJPUjsKLSAgICAgICAgcmV0dXJuIGZpbmRNYXRjaGluZ0RlY2woZWxlbWVudE5hbWUsIHN1Ykdyb3VwSGFuZGxlcik7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBUaGUgbWV0aG9kIGluZGljYXRlcyB0aGUgZW5kIG9mIGxpc3Qgb2YgY2hpbGRyZW4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjdXJyZW50U3RhdGUgIEN1cnJlbnQgc3RhdGUgb2YgdGhlIGNvbnRlbnQgbW9kZWwKLSAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGxhc3Qgc3RhdGUgd2FzIGEgdmFsaWQgZmluYWwgc3RhdGUKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBlbmRDb250ZW50TW9kZWwgKGludFtdIGN1cnJlbnRTdGF0ZSkgewotCi0gICAgICAgIGludCBzdGF0ZSA9IGN1cnJlbnRTdGF0ZVswXTsKLQotICAgICAgICBpZiAoc3RhdGUgPT0gWFNDTVZhbGlkYXRvci5GSVJTVF9FUlJPUiB8fCBzdGF0ZSA9PSBYU0NNVmFsaWRhdG9yLlNVQlNFUVVFTlRfRVJST1IpIHsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIElmIDxhbGw+IGhhcyBtaW5PY2N1cnMgb2YgemVybyBhbmQgdGhlcmUgYXJlCi0gICAgICAgIC8vIG5vIGNoaWxkcmVuIHRvIHZhbGlkYXRlLCBpdCBpcyB0cml2aWFsbHkgdmFsaWQKLSAgICAgICAgaWYgKGZIYXNPcHRpb25hbENvbnRlbnQgJiYgc3RhdGUgPT0gU1RBVEVfU1RBUlQpIHsKLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0KLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmTnVtRWxlbWVudHM7IGkrKykgewotICAgICAgICAgICAgLy8gaWYgb25lIGVsZW1lbnQgaXMgcmVxdWlyZWQsIGJ1dCBub3QgcHJlc2VudCwgdGhlbiBlcnJvcgotICAgICAgICAgICAgaWYgKCFmSXNPcHRpb25hbEVsZW1lbnRbaV0gJiYgY3VycmVudFN0YXRlW2krMV0gPT0gU1RBVEVfU1RBUlQpCi0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogY2hlY2sgd2hldGhlciB0aGlzIGNvbnRlbnQgdmlvbGF0ZXMgVVBBIGNvbnN0cmFpbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc3ViR3JvdXBIYW5kbGVyIHRoZSBzdWJzdGl0dXRpb24gZ3JvdXAgaGFuZGxlcgotICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGlzIGNvbnRlbnQgbW9kZWwgY29udGFpbnMgb3RoZXIgb3IgbGlzdCB3aWxkY2FyZAotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGNoZWNrVW5pcXVlUGFydGljbGVBdHRyaWJ1dGlvbihTdWJzdGl0dXRpb25Hcm91cEhhbmRsZXIgc3ViR3JvdXBIYW5kbGVyKSB0aHJvd3MgWE1MU2NoZW1hRXhjZXB0aW9uIHsKLSAgICAgICAgLy8gY2hlY2sgd2hldGhlciB0aGVyZSBpcyBjb25mbGljdCBiZXR3ZWVuIGFueSB0d28gbGVhdmVzCi0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZk51bUVsZW1lbnRzOyBpKyspIHsKLSAgICAgICAgICAgIGZvciAoaW50IGogPSBpKzE7IGogPCBmTnVtRWxlbWVudHM7IGorKykgewotICAgICAgICAgICAgICAgIGlmIChYU0NvbnN0cmFpbnRzLm92ZXJsYXBVUEEoZkFsbEVsZW1lbnRzW2ldLCBmQWxsRWxlbWVudHNbal0sIHN1Ykdyb3VwSGFuZGxlcikpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gUkVWSVNJVDogZG8gd2Ugd2FudCB0byByZXBvcnQgYWxsIGVycm9ycz8gb3IganVzdCBvbmU/Ci0gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBYTUxTY2hlbWFFeGNlcHRpb24oImNvcy1ub25hbWJpZyIsIG5ldyBPYmplY3RbXXtmQWxsRWxlbWVudHNbaV0udG9TdHJpbmcoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZBbGxFbGVtZW50c1tqXS50b1N0cmluZygpfSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENoZWNrIHdoaWNoIGVsZW1lbnRzIGFyZSB2YWxpZCB0byBhcHBlYXIgYXQgdGhpcyBwb2ludC4gVGhpcyBtZXRob2QgYWxzbwotICAgICAqIHdvcmtzIGlmIHRoZSBzdGF0ZSBpcyBpbiBlcnJvciwgaW4gd2hpY2ggY2FzZSBpdCByZXR1cm5zIHdoYXQgc2hvdWxkCi0gICAgICogaGF2ZSBiZWVuIHNlZW4uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc3RhdGUgIHRoZSBjdXJyZW50IHN0YXRlCi0gICAgICogQHJldHVybiAgICAgICBhIFZlY3RvciB3aG9zZSBlbnRyaWVzIGFyZSBpbnN0YW5jZXMgb2YKLSAgICAgKiAgICAgICAgICAgICAgIGVpdGhlciBYU1dpbGRjYXJkRGVjbCBvciBYU0VsZW1lbnREZWNsLgotICAgICAqLwotICAgIHB1YmxpYyBWZWN0b3Igd2hhdENhbkdvSGVyZShpbnRbXSBzdGF0ZSkgewotICAgICAgICBWZWN0b3IgcmV0ID0gbmV3IFZlY3RvcigpOwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZOdW1FbGVtZW50czsgaSsrKSB7Ci0gICAgICAgICAgICAvLyB3ZSBvbmx5IHRyeSB0byBsb29rIGZvciBhIG1hdGNoaW5nIGRlY2wgaWYgd2UgaGF2ZSBub3Qgc2VlbgotICAgICAgICAgICAgLy8gdGhpcyBlbGVtZW50IHlldC4KLSAgICAgICAgICAgIGlmIChzdGF0ZVtpKzFdID09IFNUQVRFX1NUQVJUKQotICAgICAgICAgICAgICAgIHJldC5hZGRFbGVtZW50KGZBbGxFbGVtZW50c1tpXSk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHJldDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgQXJyYXlMaXN0IGNoZWNrTWluTWF4Qm91bmRzKCkgewotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLX0gLy8gY2xhc3MgWFNBbGxDTQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9tb2RlbHMvWFNDTUJpbk9wLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL21vZGVscy9YU0NNQmluT3AuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYmU2MmYzOC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL21vZGVscy9YU0NNQmluT3AuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE0MSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLm1vZGVsczsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdGQubW9kZWxzLkNNTm9kZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHRkLm1vZGVscy5DTVN0YXRlU2V0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5YU01vZGVsR3JvdXBJbXBsOwotCi0vKioKLSAqCi0gKiBDb250ZW50IG1vZGVsIEJpbi1PcCBub2RlLgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIE5laWwgR3JhaGFtLCBJQk0KLSAqLwotcHVibGljIGNsYXNzIFhTQ01CaW5PcCBleHRlbmRzIENNTm9kZSB7Ci0gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgIC8vICBDb25zdHJ1Y3RvcnMKLSAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgcHVibGljIFhTQ01CaW5PcChpbnQgdHlwZSwgQ01Ob2RlIGxlZnROb2RlLCBDTU5vZGUgcmlnaHROb2RlKQotICAgIHsKLSAgICAgICAgc3VwZXIodHlwZSk7Ci0KLSAgICAgICAgLy8gSW5zdXJlIHRoYXQgaXRzIG9uZSBvZiB0aGUgdHlwZXMgd2UgcmVxdWlyZQotICAgICAgICBpZiAoKHR5cGUoKSAhPSBYU01vZGVsR3JvdXBJbXBsLk1PREVMR1JPVVBfQ0hPSUNFKQotICAgICAgICAmJiAgKHR5cGUoKSAhPSBYU01vZGVsR3JvdXBJbXBsLk1PREVMR1JPVVBfU0VRVUVOQ0UpKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiSW1wbGVtZW50YXRpb25NZXNzYWdlcy5WQUxfQlNUIik7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBTdG9yZSB0aGUgbm9kZXMgYW5kIGluaXQgYW55IGRhdGEgdGhhdCBuZWVkcyBpdAotICAgICAgICBmTGVmdENoaWxkID0gbGVmdE5vZGU7Ci0gICAgICAgIGZSaWdodENoaWxkID0gcmlnaHROb2RlOwotICAgIH0KLQotCi0gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgIC8vICBQYWNrYWdlLCBmaW5hbCBtZXRob2RzCi0gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgIGZpbmFsIENNTm9kZSBnZXRMZWZ0KCkgewotICAgICAgICByZXR1cm4gZkxlZnRDaGlsZDsKLSAgICB9Ci0KLSAgICBmaW5hbCBDTU5vZGUgZ2V0UmlnaHQoKSB7Ci0gICAgICAgIHJldHVybiBmUmlnaHRDaGlsZDsKLSAgICB9Ci0KLQotICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICAvLyAgUGFja2FnZSwgaW5oZXJpdGVkIG1ldGhvZHMKLSAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgcHVibGljIGJvb2xlYW4gaXNOdWxsYWJsZSgpIHsKLSAgICAgICAgLy8KLSAgICAgICAgLy8gIElmIGl0cyBhbiBhbHRlcm5hdGlvbiwgdGhlbiBpZiBlaXRoZXIgY2hpbGQgaXMgbnVsbGFibGUgdGhlbgotICAgICAgICAvLyAgdGhpcyBub2RlIGlzIG51bGxhYmxlLiBJZiBpdHMgYSBjb25jYXRlbmF0aW9uLCB0aGVuIGJvdGggb2YKLSAgICAgICAgLy8gIHRoZW0gaGF2ZSB0byBiZSBudWxsYWJsZS4KLSAgICAgICAgLy8KLSAgICAgICAgaWYgKHR5cGUoKSA9PSBYU01vZGVsR3JvdXBJbXBsLk1PREVMR1JPVVBfQ0hPSUNFKQotICAgICAgICAgICAgcmV0dXJuIChmTGVmdENoaWxkLmlzTnVsbGFibGUoKSB8fCBmUmlnaHRDaGlsZC5pc051bGxhYmxlKCkpOwotICAgICAgICBlbHNlIGlmICh0eXBlKCkgPT0gWFNNb2RlbEdyb3VwSW1wbC5NT0RFTEdST1VQX1NFUVVFTkNFKQotICAgICAgICAgICAgcmV0dXJuIChmTGVmdENoaWxkLmlzTnVsbGFibGUoKSAmJiBmUmlnaHRDaGlsZC5pc051bGxhYmxlKCkpOwotICAgICAgICBlbHNlCi0gICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiSW1wbGVtZW50YXRpb25NZXNzYWdlcy5WQUxfQlNUIik7Ci0gICAgfQotCi0KLSAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgLy8gIFByb3RlY3RlZCwgaW5oZXJpdGVkIG1ldGhvZHMKLSAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgcHJvdGVjdGVkIHZvaWQgY2FsY0ZpcnN0UG9zKENNU3RhdGVTZXQgdG9TZXQpIHsKLSAgICAgICAgaWYgKHR5cGUoKSA9PSBYU01vZGVsR3JvdXBJbXBsLk1PREVMR1JPVVBfQ0hPSUNFKSB7Ci0gICAgICAgICAgICAvLyBJdHMgdGhlIHRoZSB1bmlvbiBvZiB0aGUgZmlyc3QgcG9zaXRpb25zIG9mIG91ciBjaGlsZHJlbi4KLSAgICAgICAgICAgIHRvU2V0LnNldFRvKGZMZWZ0Q2hpbGQuZmlyc3RQb3MoKSk7Ci0gICAgICAgICAgICB0b1NldC51bmlvbihmUmlnaHRDaGlsZC5maXJzdFBvcygpKTsKLSAgICAgICAgfQotICAgICAgICAgZWxzZSBpZiAodHlwZSgpID09IFhTTW9kZWxHcm91cEltcGwuTU9ERUxHUk9VUF9TRVFVRU5DRSkgewotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIC8vICBJZiBvdXIgbGVmdCBjaGlsZCBpcyBudWxsYWJsZSwgdGhlbiBpdHMgdGhlIHVuaW9uIG9mIG91cgotICAgICAgICAgICAgLy8gIGNoaWxkcmVuJ3MgZmlyc3QgcG9zaXRpb25zLiBFbHNlIGlzIG91ciBsZWZ0IGNoaWxkJ3MgZmlyc3QKLSAgICAgICAgICAgIC8vICBwb3NpdGlvbnMuCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgdG9TZXQuc2V0VG8oZkxlZnRDaGlsZC5maXJzdFBvcygpKTsKLSAgICAgICAgICAgIGlmIChmTGVmdENoaWxkLmlzTnVsbGFibGUoKSkKLSAgICAgICAgICAgICAgICB0b1NldC51bmlvbihmUmlnaHRDaGlsZC5maXJzdFBvcygpKTsKLSAgICAgICAgfQotICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiSW1wbGVtZW50YXRpb25NZXNzYWdlcy5WQUxfQlNUIik7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwcm90ZWN0ZWQgdm9pZCBjYWxjTGFzdFBvcyhDTVN0YXRlU2V0IHRvU2V0KSB7Ci0gICAgICAgIGlmICh0eXBlKCkgPT0gWFNNb2RlbEdyb3VwSW1wbC5NT0RFTEdST1VQX0NIT0lDRSkgewotICAgICAgICAgICAgLy8gSXRzIHRoZSB0aGUgdW5pb24gb2YgdGhlIGZpcnN0IHBvc2l0aW9ucyBvZiBvdXIgY2hpbGRyZW4uCi0gICAgICAgICAgICB0b1NldC5zZXRUbyhmTGVmdENoaWxkLmxhc3RQb3MoKSk7Ci0gICAgICAgICAgICB0b1NldC51bmlvbihmUmlnaHRDaGlsZC5sYXN0UG9zKCkpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKHR5cGUoKSA9PSBYU01vZGVsR3JvdXBJbXBsLk1PREVMR1JPVVBfU0VRVUVOQ0UpIHsKLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAvLyAgSWYgb3VyIHJpZ2h0IGNoaWxkIGlzIG51bGxhYmxlLCB0aGVuIGl0cyB0aGUgdW5pb24gb2Ygb3VyCi0gICAgICAgICAgICAvLyAgY2hpbGRyZW4ncyBsYXN0IHBvc2l0aW9ucy4gRWxzZSBpcyBvdXIgcmlnaHQgY2hpbGQncyBsYXN0Ci0gICAgICAgICAgICAvLyAgcG9zaXRpb25zLgotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIHRvU2V0LnNldFRvKGZSaWdodENoaWxkLmxhc3RQb3MoKSk7Ci0gICAgICAgICAgICBpZiAoZlJpZ2h0Q2hpbGQuaXNOdWxsYWJsZSgpKQotICAgICAgICAgICAgICAgIHRvU2V0LnVuaW9uKGZMZWZ0Q2hpbGQubGFzdFBvcygpKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJJbXBsZW1lbnRhdGlvbk1lc3NhZ2VzLlZBTF9CU1QiKTsKLSAgICAgICAgfQotICAgIH0KLQotCi0gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgIC8vICBQcml2YXRlIGRhdGEgbWVtYmVycwotICAgIC8vCi0gICAgLy8gIGZMZWZ0Q2hpbGQKLSAgICAvLyAgZlJpZ2h0Q2hpbGQKLSAgICAvLyAgICAgIFRoZXNlIGFyZSB0aGUgcmVmZXJlbmNlcyB0byB0aGUgdHdvIG5vZGVzIHRoYXQgYXJlIG9uIGVpdGhlcgotICAgIC8vICAgICAgc2lkZSBvZiB0aGlzIGJpbmFyeSBvcGVyYXRpb24uCi0gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgIHByaXZhdGUgQ01Ob2RlICBmTGVmdENoaWxkOwotICAgIHByaXZhdGUgQ01Ob2RlICBmUmlnaHRDaGlsZDsKLX0gLy8gWFNDTUJpbk9wCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL21vZGVscy9YU0NNTGVhZi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9tb2RlbHMvWFNDTUxlYWYuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOTM1OWQyMS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL21vZGVscy9YU0NNTGVhZi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTM1ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwMiwyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMubW9kZWxzOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR0ZC5tb2RlbHMuQ01Ob2RlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdGQubW9kZWxzLkNNU3RhdGVTZXQ7Ci0KLS8qKgotICogQ29udGVudCBtb2RlbCBsZWFmIG5vZGUuCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgTmVpbCBHcmFoYW0sIElCTQotICovCi1wdWJsaWMgY2xhc3MgWFNDTUxlYWYKLSAgICBleHRlbmRzIENNTm9kZSB7Ci0KLSAgICAvLwotICAgIC8vIERhdGEKLSAgICAvLwotCi0gICAgLyoqIFRoaXMgaXMgdGhlIGxlYWY6IGVsZW1lbnQgZGVjbCBvciB3aWxkY2FyZCBkZWNsLiAqLwotICAgIHByaXZhdGUgT2JqZWN0IGZMZWFmID0gbnVsbDsKLQotICAgIC8qKgotICAgICAqIElkZW50aWZ5IHRoZSBwYXJ0aWNsZTogZm9yIFVQQSBjaGVja2luZwotICAgICAqLwotICAgIHByaXZhdGUgaW50IGZQYXJ0aWNsZUlkID0gLTE7Ci0KLSAgICAvKioKLSAgICAgKiBQYXJ0IG9mIHRoZSBhbGdvcml0aG0gdG8gY29udmVydCBhIHJlZ2V4IGRpcmVjdGx5IHRvIGEgREZBCi0gICAgICogbnVtYmVycyBlYWNoIGxlYWYgc2VxdWVudGlhbGx5LiBJZiBpdHMgLTEsIHRoYXQgbWVhbnMgaXRzIGFuCi0gICAgICogZXBzaWxvbiBub2RlLiBaZXJvIGFuZCBncmVhdGVyIGFyZSBub24tZXBzaWxvbiBwb3NpdGlvbnMuCi0gICAgICovCi0gICAgcHJpdmF0ZSBpbnQgZlBvc2l0aW9uID0gLTE7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0cnVjdG9ycwotICAgIC8vCi0KLSAgICAvKiogQ29uc3RydWN0cyBhIGNvbnRlbnQgbW9kZWwgbGVhZi4gKi8KLSAgICBwdWJsaWMgWFNDTUxlYWYoaW50IHR5cGUsIE9iamVjdCBsZWFmLCBpbnQgaWQsIGludCBwb3NpdGlvbikgIHsKLSAgICAgICAgc3VwZXIodHlwZSk7Ci0KLSAgICAgICAgLy8gU3RvcmUgdGhlIGVsZW1lbnQgaW5kZXggYW5kIHBvc2l0aW9uCi0gICAgICAgIGZMZWFmID0gbGVhZjsKLSAgICAgICAgZlBhcnRpY2xlSWQgPSBpZDsKLSAgICAgICAgZlBvc2l0aW9uID0gcG9zaXRpb247Ci0gICAgfQotCi0gICAgLy8KLSAgICAvLyBQYWNrYWdlIG1ldGhvZHMKLSAgICAvLwotCi0gICAgZmluYWwgT2JqZWN0IGdldExlYWYoKSB7Ci0gICAgICAgIHJldHVybiBmTGVhZjsKLSAgICB9Ci0KLSAgICBmaW5hbCBpbnQgZ2V0UGFydGljbGVJZCgpIHsKLSAgICAgICAgcmV0dXJuIGZQYXJ0aWNsZUlkOwotICAgIH0KLQotICAgIGZpbmFsIGludCBnZXRQb3NpdGlvbigpIHsKLSAgICAgICAgcmV0dXJuIGZQb3NpdGlvbjsKLSAgICB9Ci0KLSAgICBmaW5hbCB2b2lkIHNldFBvc2l0aW9uKGludCBuZXdQb3NpdGlvbikgewotICAgICAgICBmUG9zaXRpb24gPSBuZXdQb3NpdGlvbjsKLSAgICB9Ci0KLSAgICAvLwotICAgIC8vIENNTm9kZSBtZXRob2RzCi0gICAgLy8KLQotICAgIC8vIHBhY2thZ2UKLQotICAgIHB1YmxpYyBib29sZWFuIGlzTnVsbGFibGUoKSB7Ci0gICAgICAgIC8vIExlYWYgbm9kZXMgYXJlIG5ldmVyIG51bGxhYmxlIHVubGVzcyBpdHMgYW4gZXBzaWxvbiBub2RlCi0gICAgICAgIHJldHVybiAoZlBvc2l0aW9uID09IC0xKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgICAgICBTdHJpbmdCdWZmZXIgc3RyUmV0ID0gbmV3IFN0cmluZ0J1ZmZlcihmTGVhZi50b1N0cmluZygpKTsKLSAgICAgICAgaWYgKGZQb3NpdGlvbiA+PSAwKSB7Ci0gICAgICAgICAgICBzdHJSZXQuYXBwZW5kCi0gICAgICAgICAgICAoCi0gICAgICAgICAgICAgICAgIiAoUG9zOiIKLSAgICAgICAgICAgICAgICArIEludGVnZXIudG9TdHJpbmcoZlBvc2l0aW9uKQotICAgICAgICAgICAgICAgICsgIikiCi0gICAgICAgICAgICApOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBzdHJSZXQudG9TdHJpbmcoKTsKLSAgICB9Ci0KLSAgICAvLyBwcm90ZWN0ZWQKLQotICAgIHByb3RlY3RlZCB2b2lkIGNhbGNGaXJzdFBvcyhDTVN0YXRlU2V0IHRvU2V0KSB7Ci0gICAgICAgIC8vIElmIHdlIGFyZSBhbiBlcHNpbG9uIG5vZGUsIHRoZW4gdGhlIGZpcnN0IHBvcyBpcyBhbiBlbXB0eSBzZXQKLSAgICAgICAgaWYgKGZQb3NpdGlvbiA9PSAtMSkKLSAgICAgICAgICAgIHRvU2V0Lnplcm9CaXRzKCk7Ci0KLSAgICAgICAgLy8gT3RoZXJ3aXNlLCBpdHMganVzdCB0aGUgb25lIGJpdCBvZiBvdXIgcG9zaXRpb24KLSAgICAgICAgZWxzZQotICAgICAgICAgICAgdG9TZXQuc2V0Qml0KGZQb3NpdGlvbik7Ci0gICAgfQotCi0gICAgcHJvdGVjdGVkIHZvaWQgY2FsY0xhc3RQb3MoQ01TdGF0ZVNldCB0b1NldCkgewotICAgICAgICAvLyBJZiB3ZSBhcmUgYW4gZXBzaWxvbiBub2RlLCB0aGVuIHRoZSBsYXN0IHBvcyBpcyBhbiBlbXB0eSBzZXQKLSAgICAgICAgaWYgKGZQb3NpdGlvbiA9PSAtMSkKLSAgICAgICAgICAgIHRvU2V0Lnplcm9CaXRzKCk7Ci0KLSAgICAgICAgLy8gT3RoZXJ3aXNlLCBpdHMganVzdCB0aGUgb25lIGJpdCBvZiBvdXIgcG9zaXRpb24KLSAgICAgICAgZWxzZQotICAgICAgICAgICAgdG9TZXQuc2V0Qml0KGZQb3NpdGlvbik7Ci0gICAgfQotCi19IC8vIGNsYXNzIFhTQ01MZWFmCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL21vZGVscy9YU0NNUmVwZWF0aW5nTGVhZi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9tb2RlbHMvWFNDTVJlcGVhdGluZ0xlYWYuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNDY3ODg5Ni4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL21vZGVscy9YU0NNUmVwZWF0aW5nTGVhZi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTEgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKLSAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAotICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgotICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKLSAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCi0gKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMubW9kZWxzOwotCi0vKioKLSAqIEEgY29tcG91bmQgY29udGVudCBtb2RlbCBsZWFmIG5vZGUgd2hpY2ggY2FycmllcyBvY2N1cmVuY2UgaW5mb3JtYXRpb24uCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgTWljaGFlbCBHbGF2YXNzZXZpY2gsIElCTQotICogQHZlcnNpb24gJElkOiBYU0NNUmVwZWF0aW5nTGVhZi5qYXZhLHYgMS4xIDIwMTAvMDgvMDYgMjM6NDk6NDMgam9laHcgRXhwICQKLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIFhTQ01SZXBlYXRpbmdMZWFmIGV4dGVuZHMgWFNDTUxlYWYgewotCi0gICAgcHJpdmF0ZSBmaW5hbCBpbnQgZk1pbk9jY3VyczsKLSAgICBwcml2YXRlIGZpbmFsIGludCBmTWF4T2NjdXJzOwotCi0gICAgcHVibGljIFhTQ01SZXBlYXRpbmdMZWFmKGludCB0eXBlLCBPYmplY3QgbGVhZiwKLSAgICAgICAgICAgIGludCBtaW5PY2N1cnMsIGludCBtYXhPY2N1cnMsIGludCBpZCwgaW50IHBvc2l0aW9uKSB7Ci0gICAgICAgIHN1cGVyKHR5cGUsIGxlYWYsIGlkLCBwb3NpdGlvbik7Ci0gICAgICAgIGZNaW5PY2N1cnMgPSBtaW5PY2N1cnM7Ci0gICAgICAgIGZNYXhPY2N1cnMgPSBtYXhPY2N1cnM7Ci0gICAgfQotCi0gICAgZmluYWwgaW50IGdldE1pbk9jY3VycygpIHsKLSAgICAgICAgcmV0dXJuIGZNaW5PY2N1cnM7Ci0gICAgfQotCi0gICAgZmluYWwgaW50IGdldE1heE9jY3VycygpIHsKLSAgICAgICAgcmV0dXJuIGZNYXhPY2N1cnM7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9tb2RlbHMvWFNDTVVuaU9wLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL21vZGVscy9YU0NNVW5pT3AuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggODdiMDU5Ni4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL21vZGVscy9YU0NNVW5pT3AuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExMiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLm1vZGVsczsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdGQubW9kZWxzLkNNTm9kZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHRkLm1vZGVscy5DTVN0YXRlU2V0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5YU1BhcnRpY2xlRGVjbDsKLQotLyoqCi0gKgotICogQ29udGVudCBtb2RlbCBVbmktT3Agbm9kZS4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBOZWlsIEdyYWhhbSwgSUJNCi0gKiBAdmVyc2lvbiAkJAotICovCi1wdWJsaWMgY2xhc3MgWFNDTVVuaU9wIGV4dGVuZHMgQ01Ob2RlIHsKLSAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgLy8gIENvbnN0cnVjdG9ycwotICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICBwdWJsaWMgWFNDTVVuaU9wKGludCB0eXBlLCBDTU5vZGUgY2hpbGROb2RlKSB7Ci0gICAgICAgIHN1cGVyKHR5cGUpOwotCi0gICAgICAgIC8vIEluc3VyZSB0aGF0IGl0cyBvbmUgb2YgdGhlIHR5cGVzIHdlIHJlcXVpcmUKLSAgICAgICAgaWYgKCh0eXBlKCkgIT0gWFNQYXJ0aWNsZURlY2wuUEFSVElDTEVfWkVST19PUl9PTkUpCi0gICAgICAgICYmICAodHlwZSgpICE9IFhTUGFydGljbGVEZWNsLlBBUlRJQ0xFX1pFUk9fT1JfTU9SRSkKLSAgICAgICAgJiYgICh0eXBlKCkgIT0gWFNQYXJ0aWNsZURlY2wuUEFSVElDTEVfT05FX09SX01PUkUpKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiSW1wbGVtZW50YXRpb25NZXNzYWdlcy5WQUxfVVNUIik7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBTdG9yZSB0aGUgbm9kZSBhbmQgaW5pdCBhbnkgZGF0YSB0aGF0IG5lZWRzIGl0Ci0gICAgICAgIGZDaGlsZCA9IGNoaWxkTm9kZTsKLSAgICB9Ci0KLQotICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICAvLyAgUGFja2FnZSwgZmluYWwgbWV0aG9kcwotICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICBmaW5hbCBDTU5vZGUgZ2V0Q2hpbGQoKSB7Ci0gICAgICAgIHJldHVybiBmQ2hpbGQ7Ci0gICAgfQotCi0KLSAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgLy8gIFBhY2thZ2UsIGluaGVyaXRlZCBtZXRob2RzCi0gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgIHB1YmxpYyBib29sZWFuIGlzTnVsbGFibGUoKSB7Ci0gICAgICAgIC8vCi0gICAgICAgIC8vICBGb3IgZGVidWdnaW5nIHB1cnBvc2VzLCBtYWtlIHN1cmUgd2UgZ290IHJpZCBvZiBhbGwgbm9uICcqJwotICAgICAgICAvLyAgcmVwZXRpdGlvbnMuIE90aGVyd2lzZSwgJyonIHN0eWxlIG5vZGVzIGFyZSBhbHdheXMgbnVsbGFibGUuCi0gICAgICAgIC8vCi0gICAgICAgIGlmICh0eXBlKCkgPT0gWFNQYXJ0aWNsZURlY2wuUEFSVElDTEVfT05FX09SX01PUkUpCi0gICAgICAgICAgICAgICAgcmV0dXJuIGZDaGlsZC5pc051bGxhYmxlKCk7Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotCi0KLSAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgLy8gIFByb3RlY3RlZCwgaW5oZXJpdGVkIG1ldGhvZHMKLSAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgcHJvdGVjdGVkIHZvaWQgY2FsY0ZpcnN0UG9zKENNU3RhdGVTZXQgdG9TZXQpIHsKLSAgICAgICAgLy8gSXRzIGp1c3QgYmFzZWQgb24gb3VyIGNoaWxkIG5vZGUncyBmaXJzdCBwb3MKLSAgICAgICAgdG9TZXQuc2V0VG8oZkNoaWxkLmZpcnN0UG9zKCkpOwotICAgIH0KLQotICAgIHByb3RlY3RlZCB2b2lkIGNhbGNMYXN0UG9zKENNU3RhdGVTZXQgdG9TZXQpIHsKLSAgICAgICAgLy8gSXRzIGp1c3QgYmFzZWQgb24gb3VyIGNoaWxkIG5vZGUncyBsYXN0IHBvcwotICAgICAgICB0b1NldC5zZXRUbyhmQ2hpbGQubGFzdFBvcygpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBbGxvd3MgdGhlIHVzZXIgdG8gc2V0IGFyYml0cmFyeSBkYXRhIG9uIHRoaXMgY29udGVudCBtb2RlbAotICAgICAqIG5vZGUuIFRoaXMgaXMgdXNlZCBieSB0aGUgYXtuLG19IG9wdGltaXphdGlvbiB0aGF0IHJ1bnMKLSAgICAgKiBpbiBjb25zdGFudCBzcGFjZS4gRm9yIGNvbnZlbmllbmNlLCBzZXQgdXNlciBkYXRhIGluCi0gICAgICogY2hpbGRyZW4gbm9kZSB0b28uCi0gICAgICovCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIHZvaWQgc2V0VXNlckRhdGEoT2JqZWN0IHVzZXJEYXRhKSB7Ci0gICAgICAgIHN1cGVyLnNldFVzZXJEYXRhKHVzZXJEYXRhKTsKLSAgICAgICAgZkNoaWxkLnNldFVzZXJEYXRhKHVzZXJEYXRhKTsKLSAgICB9Ci0KLQotICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICAvLyAgUHJpdmF0ZSBkYXRhIG1lbWJlcnMKLSAgICAvLwotICAgIC8vICBmQ2hpbGQKLSAgICAvLyAgICAgIFRoaXMgaXMgdGhlIHJlZmVyZW5jZSB0byB0aGUgb25lIGNoaWxkIHRoYXQgd2UgaGF2ZSBmb3IgdGhpcwotICAgIC8vICAgICAgdW5hcnkgb3BlcmF0aW9uLgotICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICBwcml2YXRlIENNTm9kZSAgZkNoaWxkOwotfSAvLyBYU0NNVW5pT3AKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvbW9kZWxzL1hTQ01WYWxpZGF0b3IuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvbW9kZWxzL1hTQ01WYWxpZGF0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMzQxZDg4Yi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL21vZGVscy9YU0NNVmFsaWRhdG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMTEgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMubW9kZWxzOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuUU5hbWU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlN1YnN0aXR1dGlvbkdyb3VwSGFuZGxlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMuWE1MU2NoZW1hRXhjZXB0aW9uOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLWltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwotCi0vKioKLSAqIE5vdGU6IFN0YXRlIG9mIHRoZSBjb250ZW50IG1vZGVsIGlzIHN0b3JlZCBpbiB0aGUgdmFsaWRhdG9yCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgU2FuZHkgR2FvLCBJQk0KLSAqIEBhdXRob3IgRWxlbmEgTGl0YW5pLCBJQk0KLSAqIEB2ZXJzaW9uICRJZDogWFNDTVZhbGlkYXRvci5qYXZhLHYgMS42IDIwMDkvMDcvMjggMTU6MTg6MTIgc3BlcmljYXMgRXhwICQKLSAqLwotcHVibGljIGludGVyZmFjZSBYU0NNVmFsaWRhdG9yIHsKLQotCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBGSVJTVF9FUlJPUiA9IC0xOwotCi0gICAgLy8gb24gc3Vic2VxdWVudCBlcnJvcnMgdGhlIHZhbGlkYXRvciBzaG91bGQgbm90IHJlcG9ydAotICAgIC8vIGFuIGVycm9yCi0gICAgLy8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFNVQlNFUVVFTlRfRVJST1IgPSAtMjsKLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kcyB0byBiZSBjYWxsZWQgb24gZW50ZXJpbmcgYSBmaXJzdCBlbGVtZW50IHdob3NlIHR5cGUKLSAgICAgKiBoYXMgdGhpcyBjb250ZW50IG1vZGVsLiBJdCB3aWxsIHJldHVybiB0aGUgaW5pdGlhbCBzdGF0ZSBvZiB0aGUgY29udGVudCBtb2RlbAotICAgICAqCi0gICAgICogQHJldHVybiBTdGFydCBzdGF0ZSBvZiB0aGUgY29udGVudCBtb2RlbAotICAgICAqLwotICAgIHB1YmxpYyBpbnRbXSBzdGFydENvbnRlbnRNb2RlbCgpOwotCi0KLSAgICAvKioKLSAgICAgKiBUaGUgbWV0aG9kIGNvcnJlc3BvbmRzIHRvIG9uZSB0cmFuc2FjdGlvbiBpbiB0aGUgY29udGVudCBtb2RlbC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlbGVtZW50TmFtZQotICAgICAqIEBwYXJhbSBzdGF0ZSAgQ3VycmVudCBzdGF0ZQotICAgICAqIEByZXR1cm4gZWxlbWVudCBkZWNsIG9yIHdpbGRjYXJkIGRlY2wgdGhhdAotICAgICAqICAgICAgICAgY29ycmVzcG9uZHMgdG8gdGhlIGVsZW1lbnQgZnJvbSB0aGUgU2NoZW1hIGdyYW1tYXIKLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0IG9uZVRyYW5zaXRpb24gKFFOYW1lIGVsZW1lbnROYW1lLCBpbnRbXSBzdGF0ZSwgU3Vic3RpdHV0aW9uR3JvdXBIYW5kbGVyIHN1Ykdyb3VwSGFuZGxlcik7Ci0KLQotICAgIC8qKgotICAgICAqIFRoZSBtZXRob2QgaW5kaWNhdGVzIHRoZSBlbmQgb2YgbGlzdCBvZiBjaGlsZHJlbgotICAgICAqCi0gICAgICogQHBhcmFtIHN0YXRlICBDdXJyZW50IHN0YXRlIG9mIHRoZSBjb250ZW50IG1vZGVsCi0gICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBsYXN0IHN0YXRlIHdhcyBhIHZhbGlkIGZpbmFsIHN0YXRlCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZW5kQ29udGVudE1vZGVsIChpbnRbXSBzdGF0ZSk7Ci0KLSAgICAvKioKLSAgICAgKiBjaGVjayB3aGV0aGVyIHRoaXMgY29udGVudCB2aW9sYXRlcyBVUEEgY29uc3RyYWludC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzdWJHcm91cEhhbmRsZXIgdGhlIHN1YnN0aXR1dGlvbiBncm91cCBoYW5kbGVyCi0gICAgICogQHJldHVybiB0cnVlIGlmIHRoaXMgY29udGVudCBtb2RlbCBjb250YWlucyBvdGhlciBvciBsaXN0IHdpbGRjYXJkCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gY2hlY2tVbmlxdWVQYXJ0aWNsZUF0dHJpYnV0aW9uKFN1YnN0aXR1dGlvbkdyb3VwSGFuZGxlciBzdWJHcm91cEhhbmRsZXIpIHRocm93cyBYTUxTY2hlbWFFeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBDaGVjayB3aGljaCBlbGVtZW50cyBhcmUgdmFsaWQgdG8gYXBwZWFyIGF0IHRoaXMgcG9pbnQuIFRoaXMgbWV0aG9kIGFsc28KLSAgICAgKiB3b3JrcyBpZiB0aGUgc3RhdGUgaXMgaW4gZXJyb3IsIGluIHdoaWNoIGNhc2UgaXQgcmV0dXJucyB3aGF0IHNob3VsZAotICAgICAqIGhhdmUgYmVlbiBzZWVuLgotICAgICAqCi0gICAgICogQHBhcmFtIHN0YXRlICB0aGUgY3VycmVudCBzdGF0ZQotICAgICAqIEByZXR1cm4gICAgICAgYSBWZWN0b3Igd2hvc2UgZW50cmllcyBhcmUgaW5zdGFuY2VzIG9mCi0gICAgICogICAgICAgICAgICAgICBlaXRoZXIgWFNXaWxkY2FyZERlY2wgb3IgWFNFbGVtZW50RGVjbC4KLSAgICAgKi8KLSAgICBwdWJsaWMgVmVjdG9yIHdoYXRDYW5Hb0hlcmUoaW50W10gc3RhdGUpOwotCi0gICAgLyoqCi0gICAgICogVXNlZCBieSBjb25zdGFudCBzcGFjZSBhbGdvcml0aG0gZm9yIGF7bixtfSBmb3IgbiA+IDEgYW5kCi0gICAgICogbSA8PSB1bmJvdW5kZWQuIENhbGxlZCBieSBhIHZhbGlkYXRvciBpZiB2YWxpZGF0aW9uIG9mCi0gICAgICogY291bnRlbnQgbW9kZWwgc3VjY2VlZHMgYWZ0ZXIgc3Vic3VtaW5nIGF7bixtfSB0byBhKgotICAgICAqIChvciBhKykgdG8gY2hlY2sgdGhlIG4gYW5kIG0gYm91bmRzLgotICAgICAqIFJldHVybnMgPGNvZGU+bnVsbDwvY29kZT4gaWYgdmFsaWRhdGlvbiBvZiBib3VuZHMgaXMKLSAgICAgKiBzdWNjZXNzZnVsLiBSZXR1cm5zIGEgbGlzdCBvZiBzdHJpbmdzIHdpdGggZXJyb3IgaW5mbwotICAgICAqIGlmIG5vdC4gRXZlbiBlbnRyaWVzIGluIGxpc3QgcmV0dXJuZWQgYXJlIGVycm9yIGNvZGVzCi0gICAgICogKHVzZWQgdG8gbG9vayB1cCBwcm9wZXJ0aWVzKSBhbmQgb2RkIGVudHJpZXMgYXJlIHBhcmFtZXRlcnMKLSAgICAgKiB0byBiZSBwYXNzZWQgd2hlbiBmb3JtYXR0aW5nIGVycm9yIG1lc3NhZ2UuIEVhY2ggcGFyYW1ldGVyCi0gICAgICogaXMgYXNzb2NpYXRlZCB3aXRoIHRoZSBlcnJvciBjb2RlIHRoYXQgcHJlY2VlZHMgaXQgaW4KLSAgICAgKiB0aGUgbGlzdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgQXJyYXlMaXN0IGNoZWNrTWluTWF4Qm91bmRzKCk7Ci0KLX0gLy8gWFNDTVZhbGlkYXRvcgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9tb2RlbHMvWFNERkFDTS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9tb2RlbHMvWFNERkFDTS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlNGI1ZWUyLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvbW9kZWxzL1hTREZBQ00uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEyNDIgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMubW9kZWxzOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuUU5hbWU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR0ZC5tb2RlbHMuQ01Ob2RlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdGQubW9kZWxzLkNNU3RhdGVTZXQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlNjaGVtYVN5bWJvbHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlN1YnN0aXR1dGlvbkdyb3VwSGFuZGxlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMuWFNFbGVtZW50RGVjbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMuWFNQYXJ0aWNsZURlY2w7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlhTTW9kZWxHcm91cEltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlhTV2lsZGNhcmREZWNsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5YTUxTY2hlbWFFeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlhTQ29uc3RyYWludHM7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7Ci1pbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7Ci0KLS8qKgotICogREZBQ29udGVudE1vZGVsIGlzIHRoZSBpbXBsZW1lbnRhdGlvbiBvZiBYU0NNVmFsaWRhdG9yIHRoYXQgZG9lcwotICogYWxsIG9mIHRoZSBub24tdHJpdmlhbCBlbGVtZW50IGNvbnRlbnQgdmFsaWRhdGlvbi4gVGhpcyBjbGFzcyBkb2VzCi0gKiB0aGUgY29udmVyc2lvbiBmcm9tIHRoZSByZWd1bGFyIGV4cHJlc3Npb24gdG8gdGhlIERGQSB0aGF0Ci0gKiBpdCB0aGVuIHVzZXMgaW4gaXRzIHZhbGlkYXRpb24gYWxnb3JpdGhtLgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIE5laWwgR3JhaGFtLCBJQk0KLSAqIEB2ZXJzaW9uICRJZDogWFNERkFDTS5qYXZhLHYgMS45IDIwMTAvMDgvMDYgMjM6NDk6NDMgam9laHcgRXhwICQKLSAqLwotcHVibGljIGNsYXNzIFhTREZBQ00KLSAgICBpbXBsZW1lbnRzIFhTQ01WYWxpZGF0b3IgewotCi0gICAgLy8KLSAgICAvLyBDb25zdGFudHMKLSAgICAvLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW4gREVCVUcgPSBmYWxzZTsKLQotICAgIC8vIHNwZWNpYWwgc3RyaW5ncwotCi0gICAgLy8gZGVidWdnaW5nCi0KLSAgICAvKiogU2V0IHRvIHRydWUgdG8gZGVidWcgY29udGVudCBtb2RlbCB2YWxpZGF0aW9uLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW4gREVCVUdfVkFMSURBVEVfQ09OVEVOVCA9IGZhbHNlOwotCi0gICAgLy8KLSAgICAvLyBEYXRhCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFRoaXMgaXMgdGhlIG1hcCBvZiB1bmlxdWUgaW5wdXQgc3ltYm9sIGVsZW1lbnRzIHRvIGluZGljZXMgaW50bwotICAgICAqIGVhY2ggc3RhdGUncyBwZXItaW5wdXQgc3ltYm9sIHRyYW5zaXRpb24gdGFibGUgZW50cnkuIFRoaXMgaXMgcGFydAotICAgICAqIG9mIHRoZSBidWlsdCBERkEgaW5mb3JtYXRpb24gdGhhdCBtdXN0IGJlIGtlcHQgYXJvdW5kIHRvIGRvIHRoZQotICAgICAqIGFjdHVhbCB2YWxpZGF0aW9uLiAgTm90ZSB0YXQgc2luY2UgZWl0aGVyIFhTRWxlbWVudERlY2wgb3IgWFNQYXJ0aWNsZURlY2wgb2JqZWN0Ci0gICAgICogY2FuIGxpdmUgaGVyZSwgd2UndmUgZ290IHRvIHVzZSBhbiBPYmplY3QuCi0gICAgICovCi0gICAgcHJpdmF0ZSBPYmplY3QgZkVsZW1NYXBbXSA9IG51bGw7Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIGlzIGEgbWFwIG9mIHdoZXRoZXIgdGhlIGVsZW1lbnQgbWFwIGNvbnRhaW5zIGluZm9ybWF0aW9uCi0gICAgICogcmVsYXRlZCB0byBBTlkgbW9kZWxzLgotICAgICAqLwotICAgIHByaXZhdGUgaW50IGZFbGVtTWFwVHlwZVtdID0gbnVsbDsKLQotICAgIC8qKgotICAgICAqIGlkIG9mIHRoZSB1bmlxdWUgaW5wdXQgc3ltYm9sCi0gICAgICovCi0gICAgcHJpdmF0ZSBpbnQgZkVsZW1NYXBJZFtdID0gbnVsbDsKLQotICAgIC8qKiBUaGUgZWxlbWVudCBtYXAgc2l6ZS4gKi8KLSAgICBwcml2YXRlIGludCBmRWxlbU1hcFNpemUgPSAwOwotCi0gICAgLyoqCi0gICAgICogVGhpcyBpcyBhbiBhcnJheSBvZiBib29sZWFucywgb25lIHBlciBzdGF0ZSAodGhlcmUgYXJlCi0gICAgICogZlRyYW5zVGFibGVTaXplIHN0YXRlcyBpbiB0aGUgREZBKSB0aGF0IGluZGljYXRlcyB3aGV0aGVyIHRoYXQKLSAgICAgKiBzdGF0ZSBpcyBhIGZpbmFsIHN0YXRlLgotICAgICAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBmRmluYWxTdGF0ZUZsYWdzW10gPSBudWxsOwotCi0gICAgLyoqCi0gICAgICogVGhlIGxpc3Qgb2YgZm9sbG93IHBvc2l0aW9ucyBmb3IgZWFjaCBORkEgcG9zaXRpb24gKGkuZS4gZm9yIGVhY2gKLSAgICAgKiBub24tZXBzaWxvbiBsZWFmIG5vZGUuKSBUaGlzIGlzIG9ubHkgdXNlZCBkdXJpbmcgdGhlIGJ1aWxkaW5nIG9mCi0gICAgICogdGhlIERGQSwgYW5kIGlzIGxldCBnbyBhZnRlcndhcmRzLgotICAgICAqLwotICAgIHByaXZhdGUgQ01TdGF0ZVNldCBmRm9sbG93TGlzdFtdID0gbnVsbDsKLQotICAgIC8qKgotICAgICAqIFRoaXMgaXMgdGhlIGhlYWQgbm9kZSBvZiBvdXIgaW50ZXJtZWRpYXRlIHJlcHJlc2VudGF0aW9uLiBJdCBpcwotICAgICAqIG9ubHkgbm9uLW51bGwgZHVyaW5nIHRoZSBidWlsZGluZyBvZiB0aGUgREZBIChqdXN0IHNvIHRoYXQgaXQKLSAgICAgKiBkb2VzIG5vdCBoYXZlIHRvIGJlIHBhc3NlZCBhbGwgYXJvdW5kLikgT25jZSB0aGUgREZBIGlzIGJ1aWx0LAotICAgICAqIHRoaXMgaXMgbm8gbG9uZ2VyIHJlcXVpcmVkIHNvIGl0cyBudWxsZWQgb3V0LgotICAgICAqLwotICAgIHByaXZhdGUgQ01Ob2RlIGZIZWFkTm9kZSA9IG51bGw7Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgY291bnQgb2YgbGVhZiBub2Rlcy4gVGhpcyBpcyBhbiBpbXBvcnRhbnQgbnVtYmVyIHRoYXQgc2V0IHNvbWUKLSAgICAgKiBsaW1pdHMgb24gdGhlIHNpemVzIG9mIGRhdGEgc3RydWN0dXJlcyBpbiB0aGUgREZBIHByb2Nlc3MuCi0gICAgICovCi0gICAgcHJpdmF0ZSBpbnQgZkxlYWZDb3VudCA9IDA7Ci0KLSAgICAvKioKLSAgICAgKiBBbiBhcnJheSBvZiBub24tZXBzaWxvbiBsZWFmIG5vZGVzLCB3aGljaCBpcyB1c2VkIGR1cmluZyB0aGUgREZBCi0gICAgICogYnVpbGQgb3BlcmF0aW9uLCB0aGVuIGRyb3BwZWQuCi0gICAgICovCi0gICAgcHJpdmF0ZSBYU0NNTGVhZiBmTGVhZkxpc3RbXSA9IG51bGw7Ci0KLSAgICAvKiogQXJyYXkgbWFwcGluZyBBTlkgdHlwZXMgdG8gdGhlIGxlYWYgbGlzdC4gKi8KLSAgICBwcml2YXRlIGludCBmTGVhZkxpc3RUeXBlW10gPSBudWxsOwotCi0gICAgLyoqCi0gICAgICogVGhpcyBpcyB0aGUgdHJhbnNpdGlvbiB0YWJsZSB0aGF0IGlzIHRoZSBtYWluIGJ5IHByb2R1Y3Qgb2YgYWxsCi0gICAgICogb2YgdGhlIGVmZm9ydCBoZXJlLiBJdCBpcyBhbiBhcnJheSBvZiBhcnJheXMgb2YgaW50cy4gVGhlIGZpcnN0Ci0gICAgICogZGltZW5zaW9uIGlzIHRoZSBudW1iZXIgb2Ygc3RhdGVzIHdlIGVuZCB1cCB3aXRoIGluIHRoZSBERkEuIFRoZQotICAgICAqIHNlY29uZCBkaW1lbnNpb25zIGlzIHRoZSBudW1iZXIgb2YgdW5pcXVlIGVsZW1lbnRzIGluIHRoZSBjb250ZW50Ci0gICAgICogbW9kZWwgKGZFbGVtTWFwU2l6ZSkuIEVhY2ggZW50cnkgaW4gdGhlIHNlY29uZCBkaW1lbnNpb24gaW5kaWNhdGVzCi0gICAgICogdGhlIG5ldyBzdGF0ZSBnaXZlbiB0aGF0IGlucHV0IGZvciB0aGUgZmlyc3QgZGltZW5zaW9uJ3Mgc3RhcnQKLSAgICAgKiBzdGF0ZS4KLSAgICAgKiA8cD4KLSAgICAgKiBUaGUgZkVsZW1NYXAgYXJyYXkgaGFuZGxlcyBtYXBwaW5nIGZyb20gZWxlbWVudCBpbmRleGVzIHRvCi0gICAgICogcG9zaXRpb25zIGluIHRoZSBzZWNvbmQgZGltZW5zaW9uIG9mIHRoZSB0cmFuc2l0aW9uIHRhYmxlLgotICAgICAqLwotICAgIHByaXZhdGUgaW50IGZUcmFuc1RhYmxlW11bXSA9IG51bGw7Ci0gICAgLyoqCi0gICAgICogQXJyYXkgY29udGFpbmluZyBvY2N1cmVuY2UgaW5mb3JtYXRpb24gZm9yIGxvb3Bpbmcgc3RhdGVzCi0gICAgICogd2hpY2ggdXNlIGNvdW50ZXJzIHRvIGNoZWNrIG1pbk9jY3Vycy9tYXhPY2N1cnMuCi0gICAgICovCi0gICAgcHJpdmF0ZSBPY2N1cmVuY2UgW10gZkNvdW50aW5nU3RhdGVzID0gbnVsbDsKLSAgICBzdGF0aWMgZmluYWwgY2xhc3MgT2NjdXJlbmNlIHsKLSAgICAgICAgZmluYWwgaW50IG1pbk9jY3VyczsKLSAgICAgICAgZmluYWwgaW50IG1heE9jY3VyczsKLSAgICAgICAgZmluYWwgaW50IGVsZW1JbmRleDsKLSAgICAgICAgcHVibGljIE9jY3VyZW5jZSAoWFNDTVJlcGVhdGluZ0xlYWYgbGVhZiwgaW50IGVsZW1JbmRleCkgewotICAgICAgICAgICAgbWluT2NjdXJzID0gbGVhZi5nZXRNaW5PY2N1cnMoKTsKLSAgICAgICAgICAgIG1heE9jY3VycyA9IGxlYWYuZ2V0TWF4T2NjdXJzKCk7Ci0gICAgICAgICAgICB0aGlzLmVsZW1JbmRleCA9IGVsZW1JbmRleDsKLSAgICAgICAgfQotICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgICAgICAgICAgcmV0dXJuICJtaW5PY2N1cnM9IiArIG1pbk9jY3VycwotICAgICAgICAgICAgICAgICsgIjttYXhPY2N1cnM9IiArCi0gICAgICAgICAgICAgICAgKChtYXhPY2N1cnMgIT0gU2NoZW1hU3ltYm9scy5PQ0NVUlJFTkNFX1VOQk9VTkRFRCkKLSAgICAgICAgICAgICAgICAgICAgICAgID8gSW50ZWdlci50b1N0cmluZyhtYXhPY2N1cnMpIDogInVuYm91bmRlZCIpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhlIG51bWJlciBvZiB2YWxpZCBlbnRyaWVzIGluIHRoZSB0cmFuc2l0aW9uIHRhYmxlLCBhbmQgaW4gdGhlIG90aGVyCi0gICAgICogcmVsYXRlZCB0YWJsZXMgc3VjaCBhcyBmRmluYWxTdGF0ZUZsYWdzLgotICAgICAqLwotICAgIHByaXZhdGUgaW50IGZUcmFuc1RhYmxlU2l6ZSA9IDA7Ci0KLSAgICAvKioKLSAgICAgKiBBcnJheSBvZiBjb3VudGVycyBmb3IgYWxsIHRoZSBmb3IgZWxlbWVudHMgKG9yIHdpbGRjYXJkcykKLSAgICAgKiBvZiB0aGUgZm9ybSBhe24sbX0gd2hlcmUgbiA+IDEgYW5kIG0gPD0gdW5ib3VuZGVkLiBVc2VkCi0gICAgICogdG8gY291bnQgdGhlIGEncyB0byBsYXRlciBjaGVjayBhZ2FpbnN0IG4gYW5kIG0uIENvdW50ZXIKLSAgICAgKiBzZXQgdG8gLTEgaWYgZWxlbWVudCAob3Igd2lsZGNhcmQpIG5vdCBvcHRpbWl6ZWQgYnkKLSAgICAgKiBjb25zdGFudCBzcGFjZSBhbGdvcml0aG0uCi0gICAgICovCi0gICAgcHJpdmF0ZSBpbnQgZkVsZW1NYXBDb3VudGVyW107Ci0KLSAgICAvKioKLSAgICAgKiBBcnJheSBvZiBsb3dlciBib3VuZHMgZm9yIGFsbCB0aGUgZm9yIGVsZW1lbnRzIChvciB3aWxkY2FyZHMpCi0gICAgICogb2YgdGhlIGZvcm0gYXtuLG19IHdoZXJlIG4gPiAxIGFuZCBtIDw9IHVuYm91bmRlZC4gVGhpcyBhcnJheQotICAgICAqIHN0b3JlcyB0aGUgbidzIGZvciB0aG9zZSBlbGVtZW50cyAob3Igd2lsZGNhcmRzKSBmb3Igd2hpY2gKLSAgICAgKiB0aGUgY29uc3RhbnQgc3BhY2UgYWxnb3JpdGhtIGFwcGxpZXMgKG9yIC0xIG90aGVyd2lzZSkuCi0gICAgICovCi0gICAgcHJpdmF0ZSBpbnQgZkVsZW1NYXBDb3VudGVyTG93ZXJCb3VuZFtdOwotCi0gICAgLyoqCi0gICAgICogQXJyYXkgb2YgdXBwZXIgYm91bmRzIGZvciBhbGwgdGhlIGZvciBlbGVtZW50cyAob3Igd2lsZGNhcmRzKQotICAgICAqIG9mIHRoZSBmb3JtIGF7bixtfSB3aGVyZSBuID4gMSBhbmQgbSA8PSB1bmJvdW5kZWQuIFRoaXMgYXJyYXkKLSAgICAgKiBzdG9yZXMgdGhlIG4ncyBmb3IgdGhvc2UgZWxlbWVudHMgKG9yIHdpbGRjYXJkcykgZm9yIHdoaWNoCi0gICAgICogdGhlIGNvbnN0YW50IHNwYWNlIGFsZ29yaXRobSBhcHBsaWVzLCBvciAtMSBpZiBhbGdvcml0aG0gZG9lcwotICAgICAqIG5vdCBhcHBseSBvciBtID0gdW5ib3VuZGVkLgotICAgICAqLwotICAgIHByaXZhdGUgaW50IGZFbGVtTWFwQ291bnRlclVwcGVyQm91bmRbXTsgICAvLyAtMSBpZiBubyB1cHBlciBib3VuZAotCi0gICAgLy8gdGVtcCB2YXJpYWJsZXMKLQotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHMgYSBERkEgY29udGVudCBtb2RlbC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzeW50YXhUcmVlICAgIFRoZSBzeW50YXggdHJlZSBvZiB0aGUgY29udGVudCBtb2RlbC4KLSAgICAgKiBAcGFyYW0gbGVhZkNvdW50ICAgICBUaGUgbnVtYmVyIG9mIGxlYXZlcy4KLSAgICAgKgotICAgICAqIEBleGNlcHRpb24gUnVudGltZUV4Y2VwdGlvbiBUaHJvd24gaWYgREZBIGNhbid0IGJlIGJ1aWx0LgotICAgICAqLwotCi0gICBwdWJsaWMgWFNERkFDTShDTU5vZGUgc3ludGF4VHJlZSwgaW50IGxlYWZDb3VudCkgewotCi0gICAgICAgIC8vIFN0b3JlIGF3YXkgb3VyIGluZGV4IGFuZCBwb29scyBpbiBtZW1iZXJzCi0gICAgICAgIGZMZWFmQ291bnQgPSBsZWFmQ291bnQ7Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gIENyZWF0ZSBzb21lIHN0cmluZyBwb29sIGluZGV4ZXMgdGhhdCByZXByZXNlbnQgdGhlIG5hbWVzIG9mIHNvbWUKLSAgICAgICAgLy8gIG1hZ2ljYWwgbm9kZXMgaW4gdGhlIHN5bnRheCB0cmVlLgotICAgICAgICAvLyAgKGFscmVhZHkgZG9uZSBpbiBzdGF0aWMgaW5pdGlhbGl6YXRpb24uLi4KLSAgICAgICAgLy8KLQotICAgICAgICAvLwotICAgICAgICAvLyAgT2ssIHNvIGxldHMgZ3JpbmQgdGhyb3VnaCB0aGUgYnVpbGRpbmcgb2YgdGhlIERGQS4gVGhpcyBtZXRob2QKLSAgICAgICAgLy8gIGhhbmRsZXMgdGhlIGhpZ2ggbGV2ZWwgbG9naWMgb2YgdGhlIGFsZ29yaXRobSwgYnV0IGl0IHVzZXMgYQotICAgICAgICAvLyAgbnVtYmVyIG9mIGhlbHBlciBjbGFzc2VzIHRvIGRvIGl0cyB0aGluZy4KLSAgICAgICAgLy8KLSAgICAgICAgLy8gIEluIG9yZGVyIHRvIGF2b2lkIGhhdmluZyBodW5kcmVkcyBvZiByZWZlcmVuY2VzIHRvIHRoZSBlcnJvciBhbmQKLSAgICAgICAgLy8gIHN0cmluZyBoYW5kbGVycyBhcm91bmQsIHRoaXMgZ3V5IGFuZCBhbGwgb2YgaGlzIGhlbHBlciBjbGFzc2VzCi0gICAgICAgIC8vICBqdXN0IHRocm93IGEgc2ltcGxlIGV4Y2VwdGlvbiBhbmQgd2UgdGhlbiBwYXNzIGl0IGFsb25nLgotICAgICAgICAvLwotCi0gICAgICAgIGlmKERFQlVHX1ZBTElEQVRFX0NPTlRFTlQpIHsKLSAgICAgICAgICAgIFhTREZBQ00udGltZSAtPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKLSAgICAgICAgfQotCi0gICAgICAgIGJ1aWxkREZBKHN5bnRheFRyZWUpOwotCi0gICAgICAgIGlmKERFQlVHX1ZBTElEQVRFX0NPTlRFTlQpIHsKLSAgICAgICAgICAgIFhTREZBQ00udGltZSArPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiREZBIGJ1aWxkOiAiICsgWFNERkFDTS50aW1lICsgIm1zIik7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBsb25nIHRpbWUgPSAwOwotCi0gICAgLy8KLSAgICAvLyBYU0NNVmFsaWRhdG9yIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogY2hlY2sgd2hldGhlciB0aGUgZ2l2ZW4gc3RhdGUgaXMgb25lIG9mIHRoZSBmaW5hbCBzdGF0ZXMKLSAgICAgKgotICAgICAqIEBwYXJhbSBzdGF0ZSAgICAgICB0aGUgc3RhdGUgdG8gY2hlY2sKLSAgICAgKgotICAgICAqIEByZXR1cm4gd2hldGhlciBpdCdzIGEgZmluYWwgc3RhdGUKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0ZpbmFsU3RhdGUgKGludCBzdGF0ZSkgewotICAgICAgICByZXR1cm4gKHN0YXRlIDwgMCk/IGZhbHNlIDoKLSAgICAgICAgICAgIGZGaW5hbFN0YXRlRmxhZ3Nbc3RhdGVdOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIG9uZSB0cmFuc2l0aW9uIG9ubHkKLSAgICAgKgotICAgICAqIEBwYXJhbSBjdXJFbGVtIFRoZSBjdXJyZW50IGVsZW1lbnQncyBRTmFtZQotICAgICAqIEBwYXJhbSBzdGF0ZSBzdGFjayB0byBzdG9yZSB0aGUgcHJldmlvdXMgc3RhdGUKLSAgICAgKiBAcGFyYW0gc3ViR3JvdXBIYW5kbGVyIHRoZSBzdWJzdGl0dXRpb24gZ3JvdXAgaGFuZGxlcgotICAgICAqCi0gICAgICogQHJldHVybiAgbnVsbCBpZiB0cmFuc2l0aW9uIGlzIGludmFsaWQ7IG90aGVyd2lzZSB0aGUgT2JqZWN0IGNvcnJlc3BvbmRpbmcgdG8gdGhlCi0gICAgICogICAgICBYU0VsZW1lbnREZWNsIG9yIFhTV2lsZGNhcmREZWNsIGlkZW50aWZpZWQuICBBbHNvLCB0aGUKLSAgICAgKiAgICAgIHN0YXRlIGFycmF5IHdpbGwgYmUgbW9kaWZpZWQgdG8gaW5jbHVkZSB0aGUgbmV3IHN0YXRlOyB0aGlzIHNvIHRoYXQgdGhlIHZhbGlkYXRvciBjYW4KLSAgICAgKiAgICAgIHN0b3JlIGl0IGF3YXkuCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIFJ1bnRpbWVFeGNlcHRpb24gdGhyb3duIG9uIGVycm9yCi0gICAgICovCi0gICAgcHVibGljIE9iamVjdCBvbmVUcmFuc2l0aW9uKFFOYW1lIGN1ckVsZW0sIGludFtdIHN0YXRlLCBTdWJzdGl0dXRpb25Hcm91cEhhbmRsZXIgc3ViR3JvdXBIYW5kbGVyKSB7Ci0gICAgICAgIGludCBjdXJTdGF0ZSA9IHN0YXRlWzBdOwotCi0gICAgICAgIGlmKGN1clN0YXRlID09IFhTQ01WYWxpZGF0b3IuRklSU1RfRVJST1IgfHwgY3VyU3RhdGUgPT0gWFNDTVZhbGlkYXRvci5TVUJTRVFVRU5UX0VSUk9SKSB7Ci0gICAgICAgICAgICAvLyB0aGVyZSB3YXMgYW4gZXJyb3IgbGFzdCB0aW1lOyBzbyBqdXN0IGdvIGZpbmQgY29ycmVjdCBPYmplY3QgaW4gZkVsZW1tTWFwLgotICAgICAgICAgICAgLy8gLi4uIGFmdGVyIHJlc2V0dGluZyBzdGF0ZVswXS4KLSAgICAgICAgICAgIGlmKGN1clN0YXRlID09IFhTQ01WYWxpZGF0b3IuRklSU1RfRVJST1IpCi0gICAgICAgICAgICAgICAgc3RhdGVbMF0gPSBYU0NNVmFsaWRhdG9yLlNVQlNFUVVFTlRfRVJST1I7Ci0KLSAgICAgICAgICAgIHJldHVybiBmaW5kTWF0Y2hpbmdEZWNsKGN1ckVsZW0sIHN1Ykdyb3VwSGFuZGxlcik7Ci0gICAgICAgIH0KLQotICAgICAgICBpbnQgbmV4dFN0YXRlID0gMDsKLSAgICAgICAgaW50IGVsZW1JbmRleCA9IDA7Ci0gICAgICAgIE9iamVjdCBtYXRjaGluZ0RlY2wgPSBudWxsOwotCi0gICAgICAgIGZvciAoOyBlbGVtSW5kZXggPCBmRWxlbU1hcFNpemU7IGVsZW1JbmRleCsrKSB7Ci0gICAgICAgICAgICBuZXh0U3RhdGUgPSBmVHJhbnNUYWJsZVtjdXJTdGF0ZV1bZWxlbUluZGV4XTsKLSAgICAgICAgICAgIGlmIChuZXh0U3RhdGUgPT0gLTEpCi0gICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICBpbnQgdHlwZSA9IGZFbGVtTWFwVHlwZVtlbGVtSW5kZXhdIDsKLSAgICAgICAgICAgIGlmICh0eXBlID09IFhTUGFydGljbGVEZWNsLlBBUlRJQ0xFX0VMRU1FTlQpIHsKLSAgICAgICAgICAgICAgICBtYXRjaGluZ0RlY2wgPSBzdWJHcm91cEhhbmRsZXIuZ2V0TWF0Y2hpbmdFbGVtRGVjbChjdXJFbGVtLCAoWFNFbGVtZW50RGVjbClmRWxlbU1hcFtlbGVtSW5kZXhdKTsKLSAgICAgICAgICAgICAgICBpZiAobWF0Y2hpbmdEZWNsICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gSW5jcmVtZW50IGNvdW50ZXIgaWYgY29uc3RhbnQgc3BhY2UgYWxnb3JpdGhtIGFwcGxpZXMKLSAgICAgICAgICAgICAgICAgICAgaWYgKGZFbGVtTWFwQ291bnRlcltlbGVtSW5kZXhdID49IDApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZFbGVtTWFwQ291bnRlcltlbGVtSW5kZXhdKys7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAodHlwZSA9PSBYU1BhcnRpY2xlRGVjbC5QQVJUSUNMRV9XSUxEQ0FSRCkgewotICAgICAgICAgICAgICAgIGlmICgoKFhTV2lsZGNhcmREZWNsKWZFbGVtTWFwW2VsZW1JbmRleF0pLmFsbG93TmFtZXNwYWNlKGN1ckVsZW0udXJpKSkgewotICAgICAgICAgICAgICAgICAgICBtYXRjaGluZ0RlY2wgPSBmRWxlbU1hcFtlbGVtSW5kZXhdOwotICAgICAgICAgICAgICAgICAgICAvLyBJbmNyZW1lbnQgY291bnRlciBpZiBjb25zdGFudCBzcGFjZSBhbGdvcml0aG0gYXBwbGllcwotICAgICAgICAgICAgICAgICAgICBpZiAoZkVsZW1NYXBDb3VudGVyW2VsZW1JbmRleF0gPj0gMCkgewotICAgICAgICAgICAgICAgICAgICAgICAgZkVsZW1NYXBDb3VudGVyW2VsZW1JbmRleF0rKzsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBpZiB3ZSBzdGlsbCBjYW4ndCBmaW5kIGEgbWF0Y2gsIHNldCB0aGUgc3RhdGUgdG8gZmlyc3RfZXJyb3IKLSAgICAgICAgLy8gYW5kIHJldHVybiBudWxsCi0gICAgICAgIGlmIChlbGVtSW5kZXggPT0gZkVsZW1NYXBTaXplKSB7Ci0gICAgICAgICAgICBzdGF0ZVsxXSA9IHN0YXRlWzBdOwotICAgICAgICAgICAgc3RhdGVbMF0gPSBYU0NNVmFsaWRhdG9yLkZJUlNUX0VSUk9SOwotICAgICAgICAgICAgcmV0dXJuIGZpbmRNYXRjaGluZ0RlY2woY3VyRWxlbSwgc3ViR3JvdXBIYW5kbGVyKTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChmQ291bnRpbmdTdGF0ZXMgIT0gbnVsbCkgewotICAgICAgICAgICAgT2NjdXJlbmNlIG8gPSBmQ291bnRpbmdTdGF0ZXNbY3VyU3RhdGVdOwotICAgICAgICAgICAgaWYgKG8gIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGlmIChjdXJTdGF0ZSA9PSBuZXh0U3RhdGUpIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKCsrc3RhdGVbMl0gPiBvLm1heE9jY3VycyAmJgotICAgICAgICAgICAgICAgICAgICAgICAgby5tYXhPY2N1cnMgIT0gU2NoZW1hU3ltYm9scy5PQ0NVUlJFTkNFX1VOQk9VTkRFRCkgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gSXQncyBsaWtlbHkgdGhhdCB3ZSBsb29wZWQgdG9vIG1hbnkgdGltZXMgb24gdGhlIGN1cnJlbnQgc3RhdGUKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGhvd2V2ZXIgaXQncyBwb3NzaWJsZSB0aGF0IHdlIGFjdHVhbGx5IG1hdGNoZWQgYW5vdGhlciBwYXJ0aWNsZQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gd2hpY2ggYWxsb3dzIHRoZSBzYW1lIG5hbWUuCi0gICAgICAgICAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ29uc2lkZXI6Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgICAgICAgICAgLy8gPHhzOnNlcXVlbmNlPgotICAgICAgICAgICAgICAgICAgICAgICAgLy8gIDx4czplbGVtZW50IG5hbWU9ImZvbyIgdHlwZT0ieHM6c3RyaW5nIiBtaW5PY2N1cnM9IjMiIG1heE9jY3Vycz0iMyIvPgotICAgICAgICAgICAgICAgICAgICAgICAgLy8gIDx4czplbGVtZW50IG5hbWU9ImZvbyIgdHlwZT0ieHM6c3RyaW5nIiBmaXhlZD0iYmFyIi8+Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyA8L3hzOnNlcXVlbmNlPgotICAgICAgICAgICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFuZAotICAgICAgICAgICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIDx4czpzZXF1ZW5jZT4KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vICA8eHM6ZWxlbWVudCBuYW1lPSJmb28iIHR5cGU9InhzOnN0cmluZyIgbWluT2NjdXJzPSIzIiBtYXhPY2N1cnM9IjMiLz4KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vICA8eHM6YW55IG5hbWVzcGFjZT0iIyNhbnkiIHByb2Nlc3NDb250ZW50cz0ic2tpcCIvPgotICAgICAgICAgICAgICAgICAgICAgICAgLy8gPC94czpzZXF1ZW5jZT4KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBJbiB0aGUgREZBIHRoZXJlIHdpbGwgYmUgdHdvIHRyYW5zaXRpb25zIGZyb20gdGhlIGN1cnJlbnQgc3RhdGUgd2hpY2gKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFsbG93ICJmb28iLiBOb3RlIHRoYXQgdGhpcyBpcyBub3QgYSBVUEEgdmlvbGF0aW9uLiBUaGUgYW1iaWd1aXR5IG9mIHdoaWNoCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyB0cmFuc2l0aW9uIHRvIHRha2UgaXMgcmVzb2x2ZWQgYnkgdGhlIGN1cnJlbnQgdmFsdWUgb2YgdGhlIGNvdW50ZXIuIFNpbmNlCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyB3ZSd2ZSBhbHJlYWR5IHNlZW4gZW5vdWdoIGluc3RhbmNlcyBvZiB0aGUgZmlyc3QgImZvbyIgcGVyaGFwcyB0aGVyZSBpcwotICAgICAgICAgICAgICAgICAgICAgICAgLy8gYW5vdGhlciBlbGVtZW50IGRlY2xhcmF0aW9uIG9yIHdpbGRjYXJkIGRlZXBlciBpbiB0aGUgZWxlbWVudCBtYXAgd2hpY2gKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIG1hdGNoZXMuCi0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmluZE1hdGNoaW5nRGVjbChjdXJFbGVtLCBzdGF0ZSwgc3ViR3JvdXBIYW5kbGVyLCBlbGVtSW5kZXgpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgaWYgKHN0YXRlWzJdIDwgby5taW5PY2N1cnMpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gbm90IGVub3VnaCBsb29wcyBvbiB0aGUgY3VycmVudCBzdGF0ZS4KLSAgICAgICAgICAgICAgICAgICAgc3RhdGVbMV0gPSBzdGF0ZVswXTsKLSAgICAgICAgICAgICAgICAgICAgc3RhdGVbMF0gPSBYU0NNVmFsaWRhdG9yLkZJUlNUX0VSUk9SOwotICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmluZE1hdGNoaW5nRGVjbChjdXJFbGVtLCBzdWJHcm91cEhhbmRsZXIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gRXhpdGluZyBhIGNvdW50aW5nIHN0YXRlLiBJZiB3ZSdyZSBlbnRlcmluZyBhIG5ldwotICAgICAgICAgICAgICAgICAgICAvLyBjb3VudGluZyBzdGF0ZSwgcmVzZXQgdGhlIGNvdW50ZXIuCi0gICAgICAgICAgICAgICAgICAgIG8gPSBmQ291bnRpbmdTdGF0ZXNbbmV4dFN0YXRlXTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKG8gIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgc3RhdGVbMl0gPSAoZWxlbUluZGV4ID09IG8uZWxlbUluZGV4KSA/IDEgOiAwOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgbyA9IGZDb3VudGluZ1N0YXRlc1tuZXh0U3RhdGVdOwotICAgICAgICAgICAgICAgIGlmIChvICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gRW50ZXJpbmcgYSBuZXcgY291bnRpbmcgc3RhdGUuIFJlc2V0IHRoZSBjb3VudGVyLgotICAgICAgICAgICAgICAgICAgICAvLyBJZiB3ZSd2ZSBhbHJlYWR5IHNlZW4gb25lIGluc3RhbmNlIG9mIHRoZSBsb29waW5nCi0gICAgICAgICAgICAgICAgICAgIC8vIHBhcnRpY2xlIHNldCB0aGUgY291bnRlciB0byAxLCBvdGhlcndpc2Ugc2V0IGl0Ci0gICAgICAgICAgICAgICAgICAgIC8vIHRvIDAuCi0gICAgICAgICAgICAgICAgICAgIHN0YXRlWzJdID0gKGVsZW1JbmRleCA9PSBvLmVsZW1JbmRleCkgPyAxIDogMDsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBzdGF0ZVswXSA9IG5leHRTdGF0ZTsKLSAgICAgICAgcmV0dXJuIG1hdGNoaW5nRGVjbDsKLSAgICB9IC8vIG9uZVRyYW5zaXRpb24oUU5hbWUsIGludFtdLCBTdWJzdGl0dXRpb25Hcm91cEhhbmRsZXIpOiAgT2JqZWN0Ci0KLSAgICBPYmplY3QgZmluZE1hdGNoaW5nRGVjbChRTmFtZSBjdXJFbGVtLCBTdWJzdGl0dXRpb25Hcm91cEhhbmRsZXIgc3ViR3JvdXBIYW5kbGVyKSB7Ci0gICAgICAgIE9iamVjdCBtYXRjaGluZ0RlY2wgPSBudWxsOwotCi0gICAgICAgIGZvciAoaW50IGVsZW1JbmRleCA9IDA7IGVsZW1JbmRleCA8IGZFbGVtTWFwU2l6ZTsgZWxlbUluZGV4KyspIHsKLSAgICAgICAgICAgIGludCB0eXBlID0gZkVsZW1NYXBUeXBlW2VsZW1JbmRleF0gOwotICAgICAgICAgICAgaWYgKHR5cGUgPT0gWFNQYXJ0aWNsZURlY2wuUEFSVElDTEVfRUxFTUVOVCkgewotICAgICAgICAgICAgICAgIG1hdGNoaW5nRGVjbCA9IHN1Ykdyb3VwSGFuZGxlci5nZXRNYXRjaGluZ0VsZW1EZWNsKGN1ckVsZW0sIChYU0VsZW1lbnREZWNsKWZFbGVtTWFwW2VsZW1JbmRleF0pOwotICAgICAgICAgICAgICAgIGlmIChtYXRjaGluZ0RlY2wgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gbWF0Y2hpbmdEZWNsOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKHR5cGUgPT0gWFNQYXJ0aWNsZURlY2wuUEFSVElDTEVfV0lMRENBUkQpIHsKLSAgICAgICAgICAgICAgICBpZigoKFhTV2lsZGNhcmREZWNsKWZFbGVtTWFwW2VsZW1JbmRleF0pLmFsbG93TmFtZXNwYWNlKGN1ckVsZW0udXJpKSkKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZFbGVtTWFwW2VsZW1JbmRleF07Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9IC8vIGZpbmRNYXRjaGluZ0RlY2woUU5hbWUsIFN1YnN0aXR1dGlvbkdyb3VwSGFuZGxlcik6IE9iamVjdAotCi0gICAgT2JqZWN0IGZpbmRNYXRjaGluZ0RlY2woUU5hbWUgY3VyRWxlbSwgaW50W10gc3RhdGUsIFN1YnN0aXR1dGlvbkdyb3VwSGFuZGxlciBzdWJHcm91cEhhbmRsZXIsIGludCBlbGVtSW5kZXgpIHsKLQotICAgICAgICBpbnQgY3VyU3RhdGUgPSBzdGF0ZVswXTsKLSAgICAgICAgaW50IG5leHRTdGF0ZSA9IDA7Ci0gICAgICAgIE9iamVjdCBtYXRjaGluZ0RlY2wgPSBudWxsOwotCi0gICAgICAgIHdoaWxlICgrK2VsZW1JbmRleCA8IGZFbGVtTWFwU2l6ZSkgewotICAgICAgICAgICAgbmV4dFN0YXRlID0gZlRyYW5zVGFibGVbY3VyU3RhdGVdW2VsZW1JbmRleF07Ci0gICAgICAgICAgICBpZiAobmV4dFN0YXRlID09IC0xKQotICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgaW50IHR5cGUgPSBmRWxlbU1hcFR5cGVbZWxlbUluZGV4XSA7Ci0gICAgICAgICAgICBpZiAodHlwZSA9PSBYU1BhcnRpY2xlRGVjbC5QQVJUSUNMRV9FTEVNRU5UKSB7Ci0gICAgICAgICAgICAgICAgbWF0Y2hpbmdEZWNsID0gc3ViR3JvdXBIYW5kbGVyLmdldE1hdGNoaW5nRWxlbURlY2woY3VyRWxlbSwgKFhTRWxlbWVudERlY2wpZkVsZW1NYXBbZWxlbUluZGV4XSk7Ci0gICAgICAgICAgICAgICAgaWYgKG1hdGNoaW5nRGVjbCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKHR5cGUgPT0gWFNQYXJ0aWNsZURlY2wuUEFSVElDTEVfV0lMRENBUkQpIHsKLSAgICAgICAgICAgICAgICBpZiAoKChYU1dpbGRjYXJkRGVjbClmRWxlbU1hcFtlbGVtSW5kZXhdKS5hbGxvd05hbWVzcGFjZShjdXJFbGVtLnVyaSkpIHsKLSAgICAgICAgICAgICAgICAgICAgbWF0Y2hpbmdEZWNsID0gZkVsZW1NYXBbZWxlbUluZGV4XTsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gaWYgd2Ugc3RpbGwgY2FuJ3QgZmluZCBhIG1hdGNoLCBzZXQgdGhlIHN0YXRlIHRvIEZJUlNUX0VSUk9SIGFuZCByZXR1cm4gbnVsbAotICAgICAgICBpZiAoZWxlbUluZGV4ID09IGZFbGVtTWFwU2l6ZSkgewotICAgICAgICAgICAgc3RhdGVbMV0gPSBzdGF0ZVswXTsKLSAgICAgICAgICAgIHN0YXRlWzBdID0gWFNDTVZhbGlkYXRvci5GSVJTVF9FUlJPUjsKLSAgICAgICAgICAgIHJldHVybiBmaW5kTWF0Y2hpbmdEZWNsKGN1ckVsZW0sIHN1Ykdyb3VwSGFuZGxlcik7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBpZiB3ZSBmb3VuZCBhIG1hdGNoLCBzZXQgdGhlIG5leHQgc3RhdGUgYW5kIHJlc2V0IHRoZQotICAgICAgICAvLyBjb3VudGVyIGlmIHRoZSBuZXh0IHN0YXRlIGlzIGEgY291bnRpbmcgc3RhdGUuCi0gICAgICAgIHN0YXRlWzBdID0gbmV4dFN0YXRlOwotICAgICAgICBmaW5hbCBPY2N1cmVuY2UgbyA9IGZDb3VudGluZ1N0YXRlc1tuZXh0U3RhdGVdOwotICAgICAgICBpZiAobyAhPSBudWxsKSB7Ci0gICAgICAgICAgICBzdGF0ZVsyXSA9IChlbGVtSW5kZXggPT0gby5lbGVtSW5kZXgpID8gMSA6IDA7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG1hdGNoaW5nRGVjbDsKLSAgICB9IC8vIGZpbmRNYXRjaGluZ0RlY2woUU5hbWUsIGludFtdLCBTdWJzdGl0dXRpb25Hcm91cEhhbmRsZXIsIGludCk6IE9iamVjdAotCi0gICAgLy8gVGhpcyBtZXRob2QgcmV0dXJucyB0aGUgc3RhcnQgc3RhdGVzIG9mIHRoZSBjb250ZW50IG1vZGVsLgotICAgIHB1YmxpYyBpbnRbXSBzdGFydENvbnRlbnRNb2RlbCgpIHsKLSAgICAgICAgLy8gQ2xlYXIgYWxsIGNvbnN0YW50IHNwYWNlIGFsZ29yaXRobSBjb3VudGVycyBpbiB1c2UKLSAgICAgICAgZm9yIChpbnQgZWxlbUluZGV4ID0gMDsgZWxlbUluZGV4IDwgZkVsZW1NYXBTaXplOyBlbGVtSW5kZXgrKykgewotICAgICAgICAgICAgaWYgKGZFbGVtTWFwQ291bnRlcltlbGVtSW5kZXhdICE9IC0xKSB7Ci0gICAgICAgICAgICAgICAgZkVsZW1NYXBDb3VudGVyW2VsZW1JbmRleF0gPSAwOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIC8vIFswXSA6IHRoZSBjdXJyZW50IHN0YXRlCi0gICAgICAgIC8vIFsxXSA6IGlmIFswXSBpcyBhbiBlcnJvciBzdGF0ZSB0aGVuIHRoZQotICAgICAgICAvLyAgICAgICBsYXN0IHZhbGlkIHN0YXRlIGJlZm9yZSB0aGUgZXJyb3IKLSAgICAgICAgLy8gWzJdIDogb2NjdXJlbmNlIGNvdW50ZXIgZm9yIGNvdW50aW5nIHN0YXRlcwotICAgICAgICByZXR1cm4gbmV3IGludCBbM107Ci0gICAgfSAvLyBzdGFydENvbnRlbnRNb2RlbCgpOmludFtdCi0KLSAgICAvLyB0aGlzIG1ldGhvZCByZXR1cm5zIHdoZXRoZXIgdGhlIGxhc3Qgc3RhdGUgd2FzIGEgdmFsaWQgZmluYWwgc3RhdGUKLSAgICBwdWJsaWMgYm9vbGVhbiBlbmRDb250ZW50TW9kZWwoaW50W10gc3RhdGUpIHsKLSAgICAgICAgZmluYWwgaW50IGN1clN0YXRlID0gc3RhdGVbMF07Ci0gICAgICAgIGlmIChmRmluYWxTdGF0ZUZsYWdzW2N1clN0YXRlXSkgewotICAgICAgICAgICAgaWYgKGZDb3VudGluZ1N0YXRlcyAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgT2NjdXJlbmNlIG8gPSBmQ291bnRpbmdTdGF0ZXNbY3VyU3RhdGVdOwotICAgICAgICAgICAgICAgIGlmIChvICE9IG51bGwgJiYgc3RhdGVbMl0gPCBvLm1pbk9jY3VycykgewotICAgICAgICAgICAgICAgICAgICAvLyBub3QgZW5vdWdoIGxvb3BzIG9uIHRoZSBjdXJyZW50IHN0YXRlIHRvIGJlIGNvbnNpZGVyZWQgZmluYWwuCi0gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfSAvLyBlbmRDb250ZW50TW9kZWwoaW50W10pOiAgYm9vbGVhbgotCi0gICAgLy8gS2lsbGVkIG9mZiB3aGF0Q2FuR29IZXJlOyB3ZSBtYXkgbmVlZCBpdCBmb3IgRE9NIGNhbkluc2VydCguLi4pIGV0Yy4sCi0gICAgLy8gYnV0IHdlIGNhbiBwdXQgaXQgYmFjayBsYXRlci4KLQotICAgIC8vCi0gICAgLy8gUHJpdmF0ZSBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIEJ1aWxkcyB0aGUgaW50ZXJuYWwgREZBIHRyYW5zaXRpb24gdGFibGUgZnJvbSB0aGUgZ2l2ZW4gc3ludGF4IHRyZWUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc3ludGF4VHJlZSBUaGUgc3ludGF4IHRyZWUuCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIFJ1bnRpbWVFeGNlcHRpb24gVGhyb3duIGlmIERGQSBjYW5ub3QgYmUgYnVpbHQuCi0gICAgICovCi0gICAgcHJpdmF0ZSB2b2lkIGJ1aWxkREZBKENNTm9kZSBzeW50YXhUcmVlKSB7Ci0gICAgICAgIC8vCi0gICAgICAgIC8vICBUaGUgZmlyc3Qgc3RlcCB3ZSBuZWVkIHRvIHRha2UgaXMgdG8gcmV3cml0ZSB0aGUgY29udGVudCBtb2RlbAotICAgICAgICAvLyAgdXNpbmcgb3VyIENNTm9kZSBvYmplY3RzLCBhbmQgaW4gdGhlIHByb2Nlc3MgZ2V0IHJpZCBvZiBhbnkKLSAgICAgICAgLy8gIHJlcGV0aXRpb24gc2hvcnQgY3V0cywgY29udmVydGluZyB0aGVtIGludG8gJyonIHN0eWxlIHJlcGV0aXRpb25zCi0gICAgICAgIC8vICBvciBnZXR0aW5nIHJpZCBvZiByZXBldGl0aW9ucyBhbHRvZ2V0aGVyLgotICAgICAgICAvLwotICAgICAgICAvLyAgVGhlIGNvbnZlcnNpb25zIGRvbmUgYXJlOgotICAgICAgICAvLwotICAgICAgICAvLyAgeCsgLT4gKHh8eCopCi0gICAgICAgIC8vICB4PyAtPiAoeHxlcHNpbG9uKQotICAgICAgICAvLwotICAgICAgICAvLyAgVGhpcyBpcyBhIHJlbGF0aXZlbHkgY29tcGxleCBzY2VuYXJpby4gV2hhdCBpcyBoYXBwZW5pbmcgaXMgdGhhdAotICAgICAgICAvLyAgd2UgY3JlYXRlIGEgdG9wIGxldmVsIGJpbmFyeSBub2RlIG9mIHdoaWNoIHRoZSBzcGVjaWFsIEVPQyB2YWx1ZQotICAgICAgICAvLyAgaXMgc2V0IGFzIHRoZSByaWdodCBzaWRlIG5vZGUuIFRoZSB0aGUgbGVmdCBzaWRlIGlzIHNldCB0byB0aGUKLSAgICAgICAgLy8gIHJld3JpdHRlbiBzeW50YXggdHJlZS4gVGhlIHNvdXJjZSBpcyB0aGUgb3JpZ2luYWwgY29udGVudCBtb2RlbAotICAgICAgICAvLyAgaW5mbyBmcm9tIHRoZSBkZWNsIHBvb2wuIFRoZSByZXdyaXRlIGlzIGRvbmUgYnkgYnVpbGRTeW50YXhUcmVlKCkKLSAgICAgICAgLy8gIHdoaWNoIHJlY3Vyc2VzIHRoZSBkZWNsIHBvb2wncyBjb250ZW50IG9mIHRoZSBlbGVtZW50IGFuZCBidWlsZHMKLSAgICAgICAgLy8gIGEgbmV3IHRyZWUgaW4gdGhlIHByb2Nlc3MuCi0gICAgICAgIC8vCi0gICAgICAgIC8vICBOb3RlIHRoYXQsIGR1cmluZyB0aGlzIG9wZXJhdGlvbiwgd2Ugc2V0IGVhY2ggbm9uLWVwc2lsb24gbGVhZgotICAgICAgICAvLyAgbm9kZSdzIERGQSBzdGF0ZSBwb3NpdGlvbiBhbmQgY291bnQgdGhlIG51bWJlciBvZiBzdWNoIGxlYWZzLCB3aGljaAotICAgICAgICAvLyAgaXMgbGVmdCBpbiB0aGUgZkxlYWZDb3VudCBtZW1iZXIuCi0gICAgICAgIC8vCi0gICAgICAgIC8vICBUaGUgbm9kZVRtcCBvYmplY3QgaXMgcGFzc2VkIGluIGp1c3QgYXMgYSB0ZW1wIG5vZGUgdG8gdXNlIGR1cmluZwotICAgICAgICAvLyAgdGhlIHJlY3Vyc2lvbi4gT3RoZXJ3aXNlLCB3ZSdkIGhhdmUgdG8gY3JlYXRlIGEgbmV3IG5vZGUgb24gZXZlcnkKLSAgICAgICAgLy8gIGxldmVsIG9mIHJlY3Vyc2lvbiwgd2hpY2ggd291bGQgYmUgcGlnZ3kgaW4gSmF2YSAoYXMgaXMgZXZlcnl0aGluZwotICAgICAgICAvLyAgZm9yIHRoYXQgbWF0dGVyLikKLSAgICAgICAgLy8KLQotICAgICAgICAvKiBNT0RJRklFRCAoSmFuLCAyMDAxKQotICAgICAgICAgKgotICAgICAgICAgKiBVc2UgZm9sbG93aW5nIHJ1bGVzLgotICAgICAgICAgKiAgIG51bGxhYmxlKHgrKSA6PSBudWxsYWJsZSh4KSwgZmlyc3QoeCspIDo9IGZpcnN0KHgpLCAgbGFzdCh4KykgOj0gbGFzdCh4KQotICAgICAgICAgKiAgIG51bGxhYmxlKHg/KSA6PSB0cnVlLCBmaXJzdCh4PykgOj0gZmlyc3QoeCksICBsYXN0KHg/KSA6PSBsYXN0KHgpCi0gICAgICAgICAqCi0gICAgICAgICAqIFRoZSBzYW1lIGNvbXB1dGF0aW9uIG9mIGZvbGxvdyBhcyB4KiBpcyBhcHBsaWVkIHRvIHgrCi0gICAgICAgICAqCi0gICAgICAgICAqIFRoZSBtb2RpZmljYXRpb24gZHJhc3RpY2FsbHkgcmVkdWNlcyBjb21wdXRhdGlvbiB0aW1lIG9mCi0gICAgICAgICAqICIoYSwgKGIsIGErLCAoYywgKGIsIGErKSssIGErLCAoZCwgIChjLCAoYiwgYSspKywgYSspKywgKGIsIGErKSssIGErKSspKykrKSsiCi0gICAgICAgICAqLwotCi0gICAgICAgIC8vCi0gICAgICAgIC8vICBBbmQgaGFuZGxlIHNwZWNpYWxseSB0aGUgRU9DIG5vZGUsIHdoaWNoIGFsc28gbXVzdCBiZSBudW1iZXJlZAotICAgICAgICAvLyAgYW5kIGNvdW50ZWQgYXMgYSBub24tZXBzaWxvbiBsZWFmIG5vZGUuIEl0IGNvdWxkIG5vdCBiZSBoYW5kbGVkCi0gICAgICAgIC8vICBpbiB0aGUgYWJvdmUgdHJlZSBidWlsZCBiZWNhdXNlIGl0IHdhcyBjcmVhdGVkIGJlZm9yZSBhbGwgdGhhdAotICAgICAgICAvLyAgc3RhcnRlZC4gV2Ugc2F2ZSB0aGUgRU9DIHBvc2l0aW9uIHNpbmNlIGl0cyB1c2VkIGR1cmluZyB0aGUgREZBCi0gICAgICAgIC8vICBidWlsZGluZyBsb29wLgotICAgICAgICAvLwotICAgICAgICBpbnQgRU9DUG9zID0gZkxlYWZDb3VudDsKLSAgICAgICAgWFNDTUxlYWYgbm9kZUVPQyA9IG5ldyBYU0NNTGVhZihYU1BhcnRpY2xlRGVjbC5QQVJUSUNMRV9FTEVNRU5ULCBudWxsLCAtMSwgZkxlYWZDb3VudCsrKTsKLSAgICAgICAgZkhlYWROb2RlID0gbmV3IFhTQ01CaW5PcCgKLSAgICAgICAgICAgIFhTTW9kZWxHcm91cEltcGwuTU9ERUxHUk9VUF9TRVFVRU5DRSwKLSAgICAgICAgICAgIHN5bnRheFRyZWUsCi0gICAgICAgICAgICBub2RlRU9DCi0gICAgICAgICk7Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gIE9rLCBzbyBub3cgd2UgaGF2ZSB0byBpdGVyYXRlIHRoZSBuZXcgdHJlZSBhbmQgZG8gYSBsaXR0bGUgbW9yZQotICAgICAgICAvLyAgd29yayBub3cgdGhhdCB3ZSBrbm93IHRoZSBsZWFmIGNvdW50LiBPbmUgdGhpbmcgd2UgbmVlZCB0byBkbyBpcwotICAgICAgICAvLyAgdG8gY2FsY3VsYXRlIHRoZSBmaXJzdCBhbmQgbGFzdCBwb3NpdGlvbiBzZXRzIG9mIGVhY2ggbm9kZS4gVGhpcwotICAgICAgICAvLyAgaXMgY2FjaGVkIGF3YXkgaW4gZWFjaCBvZiB0aGUgbm9kZXMuCi0gICAgICAgIC8vCi0gICAgICAgIC8vICBBbG9uZyB0aGUgd2F5IHdlIGFsc28gc2V0IHRoZSBsZWFmIGNvdW50IGluIGVhY2ggbm9kZSBhcyB0aGUKLSAgICAgICAgLy8gIG1heGltdW0gc3RhdGUgY291bnQuIFRoZXkgbXVzdCBrbm93IHRoaXMgaW4gb3JkZXIgdG8gY3JlYXRlIHRoZWlyCi0gICAgICAgIC8vICBmaXJzdC9sYXN0IHBvcyBzZXRzLgotICAgICAgICAvLwotICAgICAgICAvLyAgV2UgYWxzbyBuZWVkIHRvIGJ1aWxkIGFuIGFycmF5IG9mIHJlZmVyZW5jZXMgdG8gdGhlIG5vbi1lcHNpbG9uCi0gICAgICAgIC8vICBsZWFmIG5vZGVzLiBTaW5jZSB3ZSBpdGVyYXRlIGl0IGluIHRoZSBzYW1lIHdheSBhcyBiZWZvcmUsIHRoaXMKLSAgICAgICAgLy8gIHdpbGwgcHV0IHRoZW0gaW4gdGhlIGFycmF5IGFjY29yZGluZyB0byB0aGVpciBwb3NpdGlvbiB2YWx1ZXMuCi0gICAgICAgIC8vCi0gICAgICAgIGZMZWFmTGlzdCA9IG5ldyBYU0NNTGVhZltmTGVhZkNvdW50XTsKLSAgICAgICAgZkxlYWZMaXN0VHlwZSA9IG5ldyBpbnRbZkxlYWZDb3VudF07Ci0gICAgICAgIHBvc3RUcmVlQnVpbGRJbml0KGZIZWFkTm9kZSk7Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gIEFuZCwgbW92aW5nIG9ud2FyZC4uLiBXZSBub3cgbmVlZCB0byBidWlsZCB0aGUgZm9sbG93IHBvc2l0aW9uCi0gICAgICAgIC8vICBzZXRzIGZvciBhbGwgdGhlIG5vZGVzLiBTbyB3ZSBhbGxvY2F0ZSBhbiBhcnJheSBvZiBzdGF0ZSBzZXRzLAotICAgICAgICAvLyAgb25lIGZvciBlYWNoIGxlYWYgbm9kZSAoaS5lLiBlYWNoIERGQSBwb3NpdGlvbi4pCi0gICAgICAgIC8vCi0gICAgICAgIGZGb2xsb3dMaXN0ID0gbmV3IENNU3RhdGVTZXRbZkxlYWZDb3VudF07Ci0gICAgICAgIGZvciAoaW50IGluZGV4ID0gMDsgaW5kZXggPCBmTGVhZkNvdW50OyBpbmRleCsrKQotICAgICAgICAgICAgZkZvbGxvd0xpc3RbaW5kZXhdID0gbmV3IENNU3RhdGVTZXQoZkxlYWZDb3VudCk7Ci0gICAgICAgIGNhbGNGb2xsb3dMaXN0KGZIZWFkTm9kZSk7Ci0gICAgICAgIC8vCi0gICAgICAgIC8vICBBbmQgZmluYWxseSB0aGUgYmlnIHB1c2guLi4gTm93IHdlIGJ1aWxkIHRoZSBERkEgdXNpbmcgYWxsIHRoZQotICAgICAgICAvLyAgc3RhdGVzIGFuZCB0aGUgdHJlZSB3ZSd2ZSBidWlsdCB1cC4gRmlyc3Qgd2Ugc2V0IHVwIHRoZSB2YXJpb3VzCi0gICAgICAgIC8vICBkYXRhIHN0cnVjdHVyZXMgd2UgYXJlIGdvaW5nIHRvIHVzZSB3aGlsZSB3ZSBkbyB0aGlzLgotICAgICAgICAvLwotICAgICAgICAvLyAgRmlyc3Qgb2YgYWxsIHdlIG5lZWQgYW4gYXJyYXkgb2YgdW5pcXVlIGVsZW1lbnQgbmFtZXMgaW4gb3VyCi0gICAgICAgIC8vICBjb250ZW50IG1vZGVsLiBGb3IgZWFjaCB0cmFuc2l0aW9uIHRhYmxlIGVudHJ5LCB3ZSBuZWVkIGEgc2V0IG9mCi0gICAgICAgIC8vICBjb250aWd1b3VzIGluZGljZXMgdG8gcmVwcmVzZW50IHRoZSB0cmFuc2l0aW9ucyBmb3IgYSBwYXJ0aWN1bGFyCi0gICAgICAgIC8vICBpbnB1dCBlbGVtZW50LiBTbyB3ZSBuZWVkIHRvIGEgemVybyBiYXNlZCByYW5nZSBvZiBpbmRleGVzIHRoYXQKLSAgICAgICAgLy8gIG1hcCB0byBlbGVtZW50IHR5cGVzLiBUaGlzIGVsZW1lbnQgbWFwIHByb3ZpZGVzIHRoYXQgbWFwcGluZy4KLSAgICAgICAgLy8KLSAgICAgICAgZkVsZW1NYXAgPSBuZXcgT2JqZWN0W2ZMZWFmQ291bnRdOwotICAgICAgICBmRWxlbU1hcFR5cGUgPSBuZXcgaW50W2ZMZWFmQ291bnRdOwotICAgICAgICBmRWxlbU1hcElkID0gbmV3IGludFtmTGVhZkNvdW50XTsKLQotICAgICAgICBmRWxlbU1hcENvdW50ZXIgPSBuZXcgaW50W2ZMZWFmQ291bnRdOwotICAgICAgICBmRWxlbU1hcENvdW50ZXJMb3dlckJvdW5kID0gbmV3IGludFtmTGVhZkNvdW50XTsKLSAgICAgICAgZkVsZW1NYXBDb3VudGVyVXBwZXJCb3VuZCA9IG5ldyBpbnRbZkxlYWZDb3VudF07Ci0KLSAgICAgICAgZkVsZW1NYXBTaXplID0gMDsKLSAgICAgICAgT2NjdXJlbmNlIFtdIGVsZW1PY2N1cmVuY2VNYXAgPSBudWxsOwotCi0gICAgICAgIGZvciAoaW50IG91dEluZGV4ID0gMDsgb3V0SW5kZXggPCBmTGVhZkNvdW50OyBvdXRJbmRleCsrKSB7Ci0gICAgICAgICAgICAvLyBvcHRpbWl6YXRpb24gZnJvbSBIZW5yeSBab25nYXJvOgotICAgICAgICAgICAgLy9mRWxlbU1hcFtvdXRJbmRleF0gPSBuZXcgT2JqZWN0ICgpOwotICAgICAgICAgICAgZkVsZW1NYXBbb3V0SW5kZXhdID0gbnVsbDsKLQotICAgICAgICAgICAgaW50IGluSW5kZXggPSAwOwotICAgICAgICAgICAgZmluYWwgaW50IGlkID0gZkxlYWZMaXN0W291dEluZGV4XS5nZXRQYXJ0aWNsZUlkKCk7Ci0gICAgICAgICAgICBmb3IgKDsgaW5JbmRleCA8IGZFbGVtTWFwU2l6ZTsgaW5JbmRleCsrKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGlkID09IGZFbGVtTWFwSWRbaW5JbmRleF0pCi0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBJZiBpdCB3YXMgbm90IGluIHRoZSBsaXN0LCB0aGVuIGFkZCBpdCwgaWYgbm90IHRoZSBFT0Mgbm9kZQotICAgICAgICAgICAgaWYgKGluSW5kZXggPT0gZkVsZW1NYXBTaXplKSB7Ci0gICAgICAgICAgICAgICAgWFNDTUxlYWYgbGVhZiA9IGZMZWFmTGlzdFtvdXRJbmRleF07Ci0gICAgICAgICAgICAgICAgZkVsZW1NYXBbZkVsZW1NYXBTaXplXSA9IGxlYWYuZ2V0TGVhZigpOwotICAgICAgICAgICAgICAgIGlmIChsZWFmIGluc3RhbmNlb2YgWFNDTVJlcGVhdGluZ0xlYWYpIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGVsZW1PY2N1cmVuY2VNYXAgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgZWxlbU9jY3VyZW5jZU1hcCA9IG5ldyBPY2N1cmVuY2VbZkxlYWZDb3VudF07Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxlbU9jY3VyZW5jZU1hcFtmRWxlbU1hcFNpemVdID0gbmV3IE9jY3VyZW5jZSgoWFNDTVJlcGVhdGluZ0xlYWYpIGxlYWYsIGZFbGVtTWFwU2l6ZSk7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgZkVsZW1NYXBUeXBlW2ZFbGVtTWFwU2l6ZV0gPSBmTGVhZkxpc3RUeXBlW291dEluZGV4XTsKLSAgICAgICAgICAgICAgICBmRWxlbU1hcElkW2ZFbGVtTWFwU2l6ZV0gPSBpZDsKLQotICAgICAgICAgICAgICAgIC8vIEluaXQgY291bnRlcnMgYW5kIGJvdW5kcyBmb3IgYXtuLG19IGFsZ29yaXRobQotICAgICAgICAgICAgICAgIGludFtdIGJvdW5kcyA9IChpbnRbXSkgbGVhZi5nZXRVc2VyRGF0YSgpOwotICAgICAgICAgICAgICAgIGlmIChib3VuZHMgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBmRWxlbU1hcENvdW50ZXJbZkVsZW1NYXBTaXplXSA9IDA7Ci0gICAgICAgICAgICAgICAgICAgIGZFbGVtTWFwQ291bnRlckxvd2VyQm91bmRbZkVsZW1NYXBTaXplXSA9IGJvdW5kc1swXTsKLSAgICAgICAgICAgICAgICAgICAgZkVsZW1NYXBDb3VudGVyVXBwZXJCb3VuZFtmRWxlbU1hcFNpemVdID0gYm91bmRzWzFdOwotICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIGZFbGVtTWFwQ291bnRlcltmRWxlbU1hcFNpemVdID0gLTE7Ci0gICAgICAgICAgICAgICAgICAgIGZFbGVtTWFwQ291bnRlckxvd2VyQm91bmRbZkVsZW1NYXBTaXplXSA9IC0xOwotICAgICAgICAgICAgICAgICAgICBmRWxlbU1hcENvdW50ZXJVcHBlckJvdW5kW2ZFbGVtTWFwU2l6ZV0gPSAtMTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBmRWxlbU1hcFNpemUrKzsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIHRoZSBsYXN0IGVudHJ5IGluIHRoZSBlbGVtZW50IG1hcCBtdXN0IGJlIHRoZSBFT0MgZWxlbWVudC4KLSAgICAgICAgLy8gcmVtb3ZlIGl0IGZyb20gdGhlIG1hcC4KLSAgICAgICAgaWYgKERFQlVHKSB7Ci0gICAgICAgICAgICBpZiAoZkVsZW1NYXBJZFtmRWxlbU1hcFNpemUtMV0gIT0gLTEpCi0gICAgICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJpbnRlcmFsIGVycm9yIGluIERGQTogbGFzdCBlbGVtZW50IGlzIG5vdCBFT0MuIik7Ci0gICAgICAgIH0KLSAgICAgICAgZkVsZW1NYXBTaXplLS07Ci0KLSAgICAgICAgLyoqKgotICAgICAgICAgKiBPcHRpbWl6YXRpb24oSmFuLCAyMDAxKTsgV2Ugc29ydCBmTGVhZkxpc3QgYWNjb3JkaW5nIHRvCi0gICAgICAgICAqIGVsZW1JbmRleCB3aGljaCBpcyAqdW5pcXVlbHkqIGFzc29jaWF0ZWQgdG8gZWFjaCBsZWFmLgotICAgICAgICAgKiBXZSBhcmUgKmFzc3VtaW5nKiB0aGF0IGVhY2ggZWxlbWVudCBhcHBlYXJzIGluIGF0IGxlYXN0IG9uZSBsZWFmLgotICAgICAgICAgKiovCi0KLSAgICAgICAgaW50W10gZkxlYWZTb3J0ZXIgPSBuZXcgaW50W2ZMZWFmQ291bnQgKyBmRWxlbU1hcFNpemVdOwotICAgICAgICBpbnQgZlNvcnRDb3VudCA9IDA7Ci0KLSAgICAgICAgZm9yIChpbnQgZWxlbUluZGV4ID0gMDsgZWxlbUluZGV4IDwgZkVsZW1NYXBTaXplOyBlbGVtSW5kZXgrKykgewotICAgICAgICAgICAgZmluYWwgaW50IGlkID0gZkVsZW1NYXBJZFtlbGVtSW5kZXhdOwotICAgICAgICAgICAgZm9yIChpbnQgbGVhZkluZGV4ID0gMDsgbGVhZkluZGV4IDwgZkxlYWZDb3VudDsgbGVhZkluZGV4KyspIHsKLSAgICAgICAgICAgICAgICBpZiAoaWQgPT0gZkxlYWZMaXN0W2xlYWZJbmRleF0uZ2V0UGFydGljbGVJZCgpKQotICAgICAgICAgICAgICAgICAgICBmTGVhZlNvcnRlcltmU29ydENvdW50KytdID0gbGVhZkluZGV4OwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZkxlYWZTb3J0ZXJbZlNvcnRDb3VudCsrXSA9IC0xOwotICAgICAgICB9Ci0KLSAgICAgICAgLyogT3B0aW1pemF0aW9uKEphbiwgMjAwMSkgKi8KLQotICAgICAgICAvLwotICAgICAgICAvLyAgTmV4dCBsZXRzIGNyZWF0ZSBzb21lIGFycmF5cywgc29tZSB0aGF0IGhvbGQgdHJhbnNpZW50Ci0gICAgICAgIC8vICBpbmZvcm1hdGlvbiBkdXJpbmcgdGhlIERGQSBidWlsZCBhbmQgc29tZSB0aGF0IGFyZSBwZXJtYW1lbnQuCi0gICAgICAgIC8vICBUaGVzZSBhcmUga2luZCBvZiBzdGlja3kgc2luY2Ugd2UgY2Fubm90IGtub3cgaG93IGJpZyB0aGV5IHdpbGwKLSAgICAgICAgLy8gIGdldCwgYnV0IHdlIGRvbid0IHdhbnQgdG8gdXNlIGFueSBKYXZhIGNvbGxlY3Rpb25zIGJlY2F1c2Ugb2YKLSAgICAgICAgLy8gIHBlcmZvcm1hbmNlLgotICAgICAgICAvLwotICAgICAgICAvLyAgQmFzaWNhbGx5IHRoZXkgd2lsbCBwcm9iYWJseSBiZSBhYm91dCBmTGVhZkNvdW50KjIgb24gYXZlcmFnZSwKLSAgICAgICAgLy8gIGJ1dCBjYW4gYmUgYXMgbGFyZ2UgYXMgMl4oZkxlYWZDb3VudCoyKSwgd29yc3QgY2FzZS4gU28gd2Ugc3RhcnQKLSAgICAgICAgLy8gIHdpdGggZkxlYWZDb3VudCo0IGFzIGEgbWlkZGxlIGdyb3VuZC4gVGhpcyB3aWxsIGJlIHZlcnkgdW5saWtlbHkKLSAgICAgICAgLy8gIHRvIGV2ZXIgaGF2ZSB0byBleHBhbmQsIHRob3VnaCBpdCBpZiBkb2VzLCB0aGUgb3ZlcmhlYWQgd2lsbCBiZQotICAgICAgICAvLyAgc29tZXdoYXQgdWdseS4KLSAgICAgICAgLy8KLSAgICAgICAgaW50IGN1ckFycmF5U2l6ZSA9IGZMZWFmQ291bnQgKiA0OwotICAgICAgICBDTVN0YXRlU2V0W10gc3RhdGVzVG9EbyA9IG5ldyBDTVN0YXRlU2V0W2N1ckFycmF5U2l6ZV07Ci0gICAgICAgIGZGaW5hbFN0YXRlRmxhZ3MgPSBuZXcgYm9vbGVhbltjdXJBcnJheVNpemVdOwotICAgICAgICBmVHJhbnNUYWJsZSA9IG5ldyBpbnRbY3VyQXJyYXlTaXplXVtdOwotCi0gICAgICAgIC8vCi0gICAgICAgIC8vICBPayB3ZSBzdGFydCB3aXRoIHRoZSBpbml0aWFsIHNldCBhcyB0aGUgZmlyc3QgcG9zIHNldCBvZiB0aGUKLSAgICAgICAgLy8gIGhlYWQgbm9kZSAod2hpY2ggaXMgdGhlIHNlcSBub2RlIHRoYXQgaG9sZHMgdGhlIGNvbnRlbnQgbW9kZWwKLSAgICAgICAgLy8gIGFuZCB0aGUgRU9DIG5vZGUuKQotICAgICAgICAvLwotICAgICAgICBDTVN0YXRlU2V0IHNldFQgPSBmSGVhZE5vZGUuZmlyc3RQb3MoKTsKLQotICAgICAgICAvLwotICAgICAgICAvLyAgSW5pdCBvdXIgdHdvIHN0YXRlIGZsYWdzLiBCYXNpY2FsbHkgdGhlIHVubWFya2VkIHN0YXRlIGNvdW50ZXIKLSAgICAgICAgLy8gIGlzIGFsd2F5cyBjaGFzaW5nIHRoZSBjdXJyZW50IHN0YXRlIGNvdW50ZXIuIFdoZW4gaXQgY2F0Y2hlcyB1cCwKLSAgICAgICAgLy8gIHRoYXQgbWVhbnMgd2UgbWFkZSBhIHBhc3MgdGhyb3VnaCB0aGF0IGRpZCBub3QgYWRkIGFueSBuZXcgc3RhdGVzCi0gICAgICAgIC8vICB0byB0aGUgbGlzdHMsIGF0IHdoaWNoIHRpbWUgd2UgYXJlIGRvbmUuIFdlIGNvdWxkIGhhdmUgdXNlZCBhCi0gICAgICAgIC8vICBleHBhbmRpbmcgYXJyYXkgb2YgZmxhZ3Mgd2hpY2ggd2UgdXNlZCB0byBtYXJrIG9mZiBzdGF0ZXMgYXMgd2UKLSAgICAgICAgLy8gIGNvbXBsZXRlIHRoZW0sIGJ1dCB0aGlzIGlzIGVhc2llciB0aG91Z2ggbGVzcyByZWFkYWJsZSBtYXliZS4KLSAgICAgICAgLy8KLSAgICAgICAgaW50IHVubWFya2VkU3RhdGUgPSAwOwotICAgICAgICBpbnQgY3VyU3RhdGUgPSAwOwotCi0gICAgICAgIC8vCi0gICAgICAgIC8vICBJbml0IHRoZSBmaXJzdCB0cmFuc2l0aW9uIHRhYmxlIGVudHJ5LCBhbmQgcHV0IHRoZSBpbml0aWFsIHN0YXRlCi0gICAgICAgIC8vICBpbnRvIHRoZSBzdGF0ZXMgdG8gZG8gbGlzdCwgdGhlbiBidW1wIHRoZSBjdXJyZW50IHN0YXRlLgotICAgICAgICAvLwotICAgICAgICBmVHJhbnNUYWJsZVtjdXJTdGF0ZV0gPSBtYWtlRGVmU3RhdGVMaXN0KCk7Ci0gICAgICAgIHN0YXRlc1RvRG9bY3VyU3RhdGVdID0gc2V0VDsKLSAgICAgICAgY3VyU3RhdGUrKzsKLQotICAgICAgICAvKiBPcHRpbWl6YXRpb24oSmFuLCAyMDAxKTsgVGhpcyBpcyBmYXN0ZXIgZm9yCi0gICAgICAgICAqIGEgbGFyZ2UgY29udGVudCBtb2RlbCBzdWNoIGFzLCAiKHQwMDErfHQwMDIrfC4uLi4gfHQ1MDArKSIuCi0gICAgICAgICAqLwotCi0gICAgICAgIEhhc2hNYXAgc3RhdGVUYWJsZSA9IG5ldyBIYXNoTWFwKCk7Ci0KLSAgICAgICAgLyogT3B0aW1pemF0aW9uKEphbiwgMjAwMSkgKi8KLQotICAgICAgICAvLwotICAgICAgICAvLyAgT2ssIGFsbW9zdCBkb25lIHdpdGggdGhlIGFsZ29yaXRobS4uLiBXZSBub3cgZW50ZXIgdGhlCi0gICAgICAgIC8vICBsb29wIHdoZXJlIHdlIGdvIHVudGlsIHRoZSBzdGF0ZXMgZG9uZSBjb3VudGVyIGNhdGNoZXMgdXAgd2l0aAotICAgICAgICAvLyAgdGhlIHN0YXRlcyB0byBkbyBjb3VudGVyLgotICAgICAgICAvLwotICAgICAgICB3aGlsZSAodW5tYXJrZWRTdGF0ZSA8IGN1clN0YXRlKSB7Ci0gICAgICAgICAgICAvLwotICAgICAgICAgICAgLy8gIEdldCB0aGUgZmlyc3QgdW5tYXJrZWQgc3RhdGUgb3V0IG9mIHRoZSBsaXN0IG9mIHN0YXRlcyB0byBkby4KLSAgICAgICAgICAgIC8vICBBbmQgZ2V0IHRoZSBhc3NvY2lhdGVkIHRyYW5zaXRpb24gdGFibGUgZW50cnkuCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgc2V0VCA9IHN0YXRlc1RvRG9bdW5tYXJrZWRTdGF0ZV07Ci0gICAgICAgICAgICBpbnRbXSB0cmFuc0VudHJ5ID0gZlRyYW5zVGFibGVbdW5tYXJrZWRTdGF0ZV07Ci0KLSAgICAgICAgICAgIC8vIE1hcmsgdGhpcyBvbmUgZmluYWwgaWYgaXQgY29udGFpbnMgdGhlIEVPQyBzdGF0ZQotICAgICAgICAgICAgZkZpbmFsU3RhdGVGbGFnc1t1bm1hcmtlZFN0YXRlXSA9IHNldFQuZ2V0Qml0KEVPQ1Bvcyk7Ci0KLSAgICAgICAgICAgIC8vIEJ1bXAgdXAgdGhlIHVubWFya2VkIHN0YXRlIGNvdW50LCBtYXJraW5nIHRoaXMgc3RhdGUgZG9uZQotICAgICAgICAgICAgdW5tYXJrZWRTdGF0ZSsrOwotCi0gICAgICAgICAgICAvLyBMb29wIHRocm91Z2ggZWFjaCBwb3NzaWJsZSBpbnB1dCBzeW1ib2wgaW4gdGhlIGVsZW1lbnQgbWFwCi0gICAgICAgICAgICBDTVN0YXRlU2V0IG5ld1NldCA9IG51bGw7Ci0gICAgICAgICAgICAvKiBPcHRpbWl6YXRpb24oSmFuLCAyMDAxKSAqLwotICAgICAgICAgICAgaW50IHNvcnRlckluZGV4ID0gMDsKLSAgICAgICAgICAgIC8qIE9wdGltaXphdGlvbihKYW4sIDIwMDEpICovCi0gICAgICAgICAgICBmb3IgKGludCBlbGVtSW5kZXggPSAwOyBlbGVtSW5kZXggPCBmRWxlbU1hcFNpemU7IGVsZW1JbmRleCsrKSB7Ci0gICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICAvLyAgQnVpbGQgdXAgYSBzZXQgb2Ygc3RhdGVzIHdoaWNoIGlzIHRoZSB1bmlvbiBvZiBhbGwgb2YKLSAgICAgICAgICAgICAgICAvLyAgdGhlIGZvbGxvdyBzZXRzIG9mIERGQSBwb3NpdGlvbnMgdGhhdCBhcmUgaW4gdGhlIGN1cnJlbnQKLSAgICAgICAgICAgICAgICAvLyAgc3RhdGUuIElmIHdlIGdhdmUgYXdheSB0aGUgbmV3IHNldCBsYXN0IHRpbWUgdGhyb3VnaCB0aGVuCi0gICAgICAgICAgICAgICAgLy8gIGNyZWF0ZSBhIG5ldyBvbmUuIE90aGVyd2lzZSwgemVybyBvdXQgdGhlIGV4aXN0aW5nIG9uZS4KLSAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgIGlmIChuZXdTZXQgPT0gbnVsbCkKLSAgICAgICAgICAgICAgICAgICAgbmV3U2V0ID0gbmV3IENNU3RhdGVTZXQoZkxlYWZDb3VudCk7Ci0gICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICBuZXdTZXQuemVyb0JpdHMoKTsKLQotICAgICAgICAgICAgICAgIC8qIE9wdGltaXphdGlvbihKYW4sIDIwMDEpICovCi0gICAgICAgICAgICAgICAgaW50IGxlYWZJbmRleCA9IGZMZWFmU29ydGVyW3NvcnRlckluZGV4KytdOwotCi0gICAgICAgICAgICAgICAgd2hpbGUgKGxlYWZJbmRleCAhPSAtMSkgewotICAgICAgICAgICAgICAgICAgICAvLyBJZiB0aGlzIGxlYWYgaW5kZXggKERGQSBwb3NpdGlvbikgaXMgaW4gdGhlIGN1cnJlbnQgc2V0Li4uCi0gICAgICAgICAgICAgICAgICAgIGlmIChzZXRULmdldEJpdChsZWFmSW5kZXgpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgICAgICAgICAgLy8gIElmIHRoaXMgbGVhZiBpcyB0aGUgY3VycmVudCBpbnB1dCBzeW1ib2wsIHRoZW4gd2UKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vICB3YW50IHRvIGFkZCBpdHMgZm9sbG93IGxpc3QgdG8gdGhlIHNldCBvZiBzdGF0ZXMgdG8KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vICB0cmFuc2l0aW9uIHRvIGZyb20gdGhlIGN1cnJlbnQgc3RhdGUuCi0gICAgICAgICAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgICAgICAgICAgbmV3U2V0LnVuaW9uKGZGb2xsb3dMaXN0W2xlYWZJbmRleF0pOwotICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICBsZWFmSW5kZXggPSBmTGVhZlNvcnRlcltzb3J0ZXJJbmRleCsrXTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLyogT3B0aW1pemF0aW9uKEphbiwgMjAwMSkgKi8KLQotICAgICAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAgICAgLy8gIElmIHRoaXMgbmV3IHNldCBpcyBub3QgZW1wdHksIHRoZW4gc2VlIGlmIGl0cyBpbiB0aGUgbGlzdAotICAgICAgICAgICAgICAgIC8vICBvZiBzdGF0ZXMgdG8gZG8uIElmIG5vdCwgdGhlbiBhZGQgaXQuCi0gICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICBpZiAoIW5ld1NldC5pc0VtcHR5KCkpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICAgICAgLy8gIFNlYXJjaCB0aGUgJ3N0YXRlcyB0byBkbycgbGlzdCB0byBzZWUgaWYgdGhpcyBuZXcKLSAgICAgICAgICAgICAgICAgICAgLy8gIHN0YXRlIHNldCBpcyBhbHJlYWR5IGluIHRoZXJlLgotICAgICAgICAgICAgICAgICAgICAvLwotCi0gICAgICAgICAgICAgICAgICAgIC8qIE9wdGltaXphdGlvbihKYW4sIDIwMDEpICovCi0gICAgICAgICAgICAgICAgICAgIEludGVnZXIgc3RhdGVPYmogPSAoSW50ZWdlcilzdGF0ZVRhYmxlLmdldChuZXdTZXQpOwotICAgICAgICAgICAgICAgICAgICBpbnQgc3RhdGVJbmRleCA9IChzdGF0ZU9iaiA9PSBudWxsID8gY3VyU3RhdGUgOiBzdGF0ZU9iai5pbnRWYWx1ZSgpKTsKLSAgICAgICAgICAgICAgICAgICAgLyogT3B0aW1pemF0aW9uKEphbiwgMjAwMSkgKi8KLQotICAgICAgICAgICAgICAgICAgICAvLyBJZiB3ZSBkaWQgbm90IGZpbmQgaXQsIHRoZW4gYWRkIGl0Ci0gICAgICAgICAgICAgICAgICAgIGlmIChzdGF0ZUluZGV4ID09IGN1clN0YXRlKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgICAgICAgICAgLy8gIFB1dCB0aGlzIG5ldyBzdGF0ZSBpbnRvIHRoZSBzdGF0ZXMgdG8gZG8gYW5kIGluaXQKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vICBhIG5ldyBlbnRyeSBhdCB0aGUgc2FtZSBpbmRleCBpbiB0aGUgdHJhbnNpdGlvbgotICAgICAgICAgICAgICAgICAgICAgICAgLy8gIHRhYmxlLgotICAgICAgICAgICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlc1RvRG9bY3VyU3RhdGVdID0gbmV3U2V0OwotICAgICAgICAgICAgICAgICAgICAgICAgZlRyYW5zVGFibGVbY3VyU3RhdGVdID0gbWFrZURlZlN0YXRlTGlzdCgpOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAvKiBPcHRpbWl6YXRpb24oSmFuLCAyMDAxKSAqLwotICAgICAgICAgICAgICAgICAgICAgICAgc3RhdGVUYWJsZS5wdXQobmV3U2V0LCBuZXcgSW50ZWdlcihjdXJTdGF0ZSkpOwotICAgICAgICAgICAgICAgICAgICAgICAgLyogT3B0aW1pemF0aW9uKEphbiwgMjAwMSkgKi8KLQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gV2Ugbm93IGhhdmUgYSBuZXcgc3RhdGUgdG8gZG8gc28gYnVtcCB0aGUgY291bnQKLSAgICAgICAgICAgICAgICAgICAgICAgIGN1clN0YXRlKys7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyAgTnVsbCBvdXQgdGhlIG5ldyBzZXQgdG8gaW5kaWNhdGUgd2UgYWRvcHRlZCBpdC4KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vICBUaGlzIHdpbGwgY2F1c2UgdGhlIGNyZWF0aW9uIG9mIGEgbmV3IHNldCBvbiB0aGUKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vICBuZXh0IHRpbWUgYXJvdW5kIHRoZSBsb29wLgotICAgICAgICAgICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICAgICAgICAgIG5ld1NldCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgICAgICAvLyAgTm93IHNldCB0aGlzIHN0YXRlIGluIHRoZSB0cmFuc2l0aW9uIHRhYmxlJ3MgZW50cnkKLSAgICAgICAgICAgICAgICAgICAgLy8gIGZvciB0aGlzIGVsZW1lbnQgKHVzaW5nIGl0cyBpbmRleCksIHdpdGggdGhlIERGQQotICAgICAgICAgICAgICAgICAgICAvLyAgc3RhdGUgd2Ugd2lsbCBtb3ZlIHRvIGZyb20gdGhlIGN1cnJlbnQgc3RhdGUgd2hlbiB3ZQotICAgICAgICAgICAgICAgICAgICAvLyAgc2VlIHRoaXMgaW5wdXQgZWxlbWVudC4KLSAgICAgICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICAgICAgdHJhbnNFbnRyeVtlbGVtSW5kZXhdID0gc3RhdGVJbmRleDsKLQotICAgICAgICAgICAgICAgICAgICAvLyBFeHBhbmQgdGhlIGFycmF5cyBpZiB3ZSdyZSBmdWxsCi0gICAgICAgICAgICAgICAgICAgIGlmIChjdXJTdGF0ZSA9PSBjdXJBcnJheVNpemUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyAgWWlrZXMsIHdlIG92ZXJmbG93ZWQgdGhlIGluaXRpYWwgYXJyYXkgc2l6ZSwgc28KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vICB3ZSd2ZSBnb3QgdG8gZXhwYW5kIGFsbCBvZiB0aGVzZSBhcnJheXMuIFNvIGFkanVzdAotICAgICAgICAgICAgICAgICAgICAgICAgLy8gIHVwIHRoZSBzaXplIGJ5IDUwJSBhbmQgYWxsb2NhdGUgbmV3IGFycmF5cy4KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgbmV3U2l6ZSA9IChpbnQpKGN1ckFycmF5U2l6ZSAqIDEuNSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBDTVN0YXRlU2V0W10gbmV3VG9EbyA9IG5ldyBDTVN0YXRlU2V0W25ld1NpemVdOwotICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbltdIG5ld0ZpbmFsRmxhZ3MgPSBuZXcgYm9vbGVhbltuZXdTaXplXTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGludFtdW10gbmV3VHJhbnNUYWJsZSA9IG5ldyBpbnRbbmV3U2l6ZV1bXTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ29weSBvdmVyIGFsbCBvZiB0aGUgZXhpc3RpbmcgY29udGVudAotICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShzdGF0ZXNUb0RvLCAwLCBuZXdUb0RvLCAwLCBjdXJBcnJheVNpemUpOwotICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShmRmluYWxTdGF0ZUZsYWdzLCAwLCBuZXdGaW5hbEZsYWdzLCAwLCBjdXJBcnJheVNpemUpOwotICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShmVHJhbnNUYWJsZSwgMCwgbmV3VHJhbnNUYWJsZSwgMCwgY3VyQXJyYXlTaXplKTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gU3RvcmUgdGhlIG5ldyBhcnJheSBzaXplCi0gICAgICAgICAgICAgICAgICAgICAgICBjdXJBcnJheVNpemUgPSBuZXdTaXplOwotICAgICAgICAgICAgICAgICAgICAgICAgc3RhdGVzVG9EbyA9IG5ld1RvRG87Ci0gICAgICAgICAgICAgICAgICAgICAgICBmRmluYWxTdGF0ZUZsYWdzID0gbmV3RmluYWxGbGFnczsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZUcmFuc1RhYmxlID0gbmV3VHJhbnNUYWJsZTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIEZpbGwgaW4gdGhlIG9jY3VyZW5jZSBpbmZvcm1hdGlvbiBmb3IgZWFjaCBsb29waW5nIHN0YXRlCi0gICAgICAgIC8vIGlmIHdlJ3JlIHVzaW5nIGNvdW50ZXJzLgotICAgICAgICAvLwotICAgICAgICBpZiAoZWxlbU9jY3VyZW5jZU1hcCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmQ291bnRpbmdTdGF0ZXMgPSBuZXcgT2NjdXJlbmNlW2N1clN0YXRlXTsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY3VyU3RhdGU7ICsraSkgewotICAgICAgICAgICAgICAgIGludCBbXSB0cmFuc2l0aW9ucyA9IGZUcmFuc1RhYmxlW2ldOwotICAgICAgICAgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgdHJhbnNpdGlvbnMubGVuZ3RoOyArK2opIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGkgPT0gdHJhbnNpdGlvbnNbal0pIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZDb3VudGluZ1N0YXRlc1tpXSA9IGVsZW1PY2N1cmVuY2VNYXBbal07Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vCi0gICAgICAgIC8vICBBbmQgbm93IHdlIGNhbiBzYXkgYnllIGJ5ZSB0byB0aGUgdGVtcCByZXByZXNlbnRhdGlvbiBzaW5jZSB3ZSd2ZQotICAgICAgICAvLyAgYnVpbHQgdGhlIERGQS4KLSAgICAgICAgLy8KLSAgICAgICAgaWYgKERFQlVHX1ZBTElEQVRFX0NPTlRFTlQpCi0gICAgICAgICAgICBkdW1wVHJlZShmSGVhZE5vZGUsIDApOwotICAgICAgICBmSGVhZE5vZGUgPSBudWxsOwotICAgICAgICBmTGVhZkxpc3QgPSBudWxsOwotICAgICAgICBmRm9sbG93TGlzdCA9IG51bGw7Ci0gICAgICAgIGZMZWFmTGlzdFR5cGUgPSBudWxsOwotICAgICAgICBmRWxlbU1hcElkID0gbnVsbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDYWxjdWxhdGVzIHRoZSBmb2xsb3cgbGlzdCBvZiB0aGUgY3VycmVudCBub2RlLgotICAgICAqCi0gICAgICogQHBhcmFtIG5vZGVDdXIgVGhlIGN1cmVudCBub2RlLgotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBSdW50aW1lRXhjZXB0aW9uIFRocm93biBpZiBmb2xsb3cgbGlzdCBjYW5ub3QgYmUgY2FsY3VsYXRlZC4KLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgY2FsY0ZvbGxvd0xpc3QoQ01Ob2RlIG5vZGVDdXIpIHsKLSAgICAgICAgLy8gUmVjdXJzZSBhcyByZXF1aXJlZAotICAgICAgICBpZiAobm9kZUN1ci50eXBlKCkgPT0gWFNNb2RlbEdyb3VwSW1wbC5NT0RFTEdST1VQX0NIT0lDRSkgewotICAgICAgICAgICAgLy8gUmVjdXJzZSBvbmx5Ci0gICAgICAgICAgICBjYWxjRm9sbG93TGlzdCgoKFhTQ01CaW5PcClub2RlQ3VyKS5nZXRMZWZ0KCkpOwotICAgICAgICAgICAgY2FsY0ZvbGxvd0xpc3QoKChYU0NNQmluT3Apbm9kZUN1cikuZ2V0UmlnaHQoKSk7Ci0gICAgICAgIH0KLSAgICAgICAgIGVsc2UgaWYgKG5vZGVDdXIudHlwZSgpID09IFhTTW9kZWxHcm91cEltcGwuTU9ERUxHUk9VUF9TRVFVRU5DRSkgewotICAgICAgICAgICAgLy8gUmVjdXJzZSBmaXJzdAotICAgICAgICAgICAgY2FsY0ZvbGxvd0xpc3QoKChYU0NNQmluT3Apbm9kZUN1cikuZ2V0TGVmdCgpKTsKLSAgICAgICAgICAgIGNhbGNGb2xsb3dMaXN0KCgoWFNDTUJpbk9wKW5vZGVDdXIpLmdldFJpZ2h0KCkpOwotCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgLy8gIE5vdyBoYW5kbGUgb3VyIGxldmVsLiBXZSB1c2Ugb3VyIGxlZnQgY2hpbGQncyBsYXN0IHBvcwotICAgICAgICAgICAgLy8gIHNldCBhbmQgb3VyIHJpZ2h0IGNoaWxkJ3MgZmlyc3QgcG9zIHNldCwgc28gZ28gYWhlYWQgYW5kCi0gICAgICAgICAgICAvLyAgZ2V0IHRoZW0gYWhlYWQgb2YgdGltZS4KLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICBmaW5hbCBDTVN0YXRlU2V0IGxhc3QgID0gKChYU0NNQmluT3Apbm9kZUN1cikuZ2V0TGVmdCgpLmxhc3RQb3MoKTsKLSAgICAgICAgICAgIGZpbmFsIENNU3RhdGVTZXQgZmlyc3QgPSAoKFhTQ01CaW5PcClub2RlQ3VyKS5nZXRSaWdodCgpLmZpcnN0UG9zKCk7Ci0KLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAvLyAgTm93LCBmb3IgZXZlcnkgcG9zaXRpb24gd2hpY2ggaXMgaW4gb3VyIGxlZnQgY2hpbGQncyBsYXN0IHNldAotICAgICAgICAgICAgLy8gIGFkZCBhbGwgb2YgdGhlIHN0YXRlcyBpbiBvdXIgcmlnaHQgY2hpbGQncyBmaXJzdCBzZXQgdG8gdGhlCi0gICAgICAgICAgICAvLyAgZm9sbG93IHNldCBmb3IgdGhhdCBwb3NpdGlvbi4KLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICBmb3IgKGludCBpbmRleCA9IDA7IGluZGV4IDwgZkxlYWZDb3VudDsgaW5kZXgrKykgewotICAgICAgICAgICAgICAgIGlmIChsYXN0LmdldEJpdChpbmRleCkpCi0gICAgICAgICAgICAgICAgICAgIGZGb2xsb3dMaXN0W2luZGV4XS51bmlvbihmaXJzdCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgIGVsc2UgaWYgKG5vZGVDdXIudHlwZSgpID09IFhTUGFydGljbGVEZWNsLlBBUlRJQ0xFX1pFUk9fT1JfTU9SRQotICAgICAgICB8fCBub2RlQ3VyLnR5cGUoKSA9PSBYU1BhcnRpY2xlRGVjbC5QQVJUSUNMRV9PTkVfT1JfTU9SRSkgewotICAgICAgICAgICAgLy8gUmVjdXJzZSBmaXJzdAotICAgICAgICAgICAgY2FsY0ZvbGxvd0xpc3QoKChYU0NNVW5pT3Apbm9kZUN1cikuZ2V0Q2hpbGQoKSk7Ci0KLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAvLyAgTm93IGhhbmRsZSBvdXIgbGV2ZWwuIFdlIHVzZSBvdXIgb3duIGZpcnN0IGFuZCBsYXN0IHBvc2l0aW9uCi0gICAgICAgICAgICAvLyAgc2V0cywgc28gZ2V0IHRoZW0gdXAgZnJvbnQuCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgZmluYWwgQ01TdGF0ZVNldCBmaXJzdCA9IG5vZGVDdXIuZmlyc3RQb3MoKTsKLSAgICAgICAgICAgIGZpbmFsIENNU3RhdGVTZXQgbGFzdCAgPSBub2RlQ3VyLmxhc3RQb3MoKTsKLQotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIC8vICBGb3IgZXZlcnkgcG9zaXRpb24gd2hpY2ggaXMgaW4gb3VyIGxhc3QgcG9zaXRpb24gc2V0LCBhZGQgYWxsCi0gICAgICAgICAgICAvLyAgb2Ygb3VyIGZpcnN0IHBvc2l0aW9uIHN0YXRlcyB0byB0aGUgZm9sbG93IHNldCBmb3IgdGhhdAotICAgICAgICAgICAgLy8gIHBvc2l0aW9uLgotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIGZvciAoaW50IGluZGV4ID0gMDsgaW5kZXggPCBmTGVhZkNvdW50OyBpbmRleCsrKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGxhc3QuZ2V0Qml0KGluZGV4KSkKLSAgICAgICAgICAgICAgICAgICAgZkZvbGxvd0xpc3RbaW5kZXhdLnVuaW9uKGZpcnN0KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGVsc2UgaWYgKG5vZGVDdXIudHlwZSgpID09IFhTUGFydGljbGVEZWNsLlBBUlRJQ0xFX1pFUk9fT1JfT05FKSB7Ci0gICAgICAgICAgICAvLyBSZWN1cnNlIG9ubHkKLSAgICAgICAgICAgIGNhbGNGb2xsb3dMaXN0KCgoWFNDTVVuaU9wKW5vZGVDdXIpLmdldENoaWxkKCkpOwotICAgICAgICB9Ci0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBEdW1wcyB0aGUgdHJlZSBvZiB0aGUgY3VycmVudCBub2RlIHRvIHN0YW5kYXJkIG91dHB1dC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBub2RlQ3VyIFRoZSBjdXJyZW50IG5vZGUuCi0gICAgICogQHBhcmFtIGxldmVsICAgVGhlIG1heGltdW0gbGV2ZWxzIHRvIG91dHB1dC4KLSAgICAgKgotICAgICAqIEBleGNlcHRpb24gUnVudGltZUV4Y2VwdGlvbiBUaHJvd24gb24gZXJyb3IuCi0gICAgICovCi0gICAgcHJpdmF0ZSB2b2lkIGR1bXBUcmVlKENNTm9kZSBub2RlQ3VyLCBpbnQgbGV2ZWwpIHsKLSAgICAgICAgZm9yIChpbnQgaW5kZXggPSAwOyBpbmRleCA8IGxldmVsOyBpbmRleCsrKQotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiICAgIik7Ci0KLSAgICAgICAgaW50IHR5cGUgPSBub2RlQ3VyLnR5cGUoKTsKLQotICAgICAgICBzd2l0Y2godHlwZSApIHsKLQotICAgICAgICBjYXNlIFhTTW9kZWxHcm91cEltcGwuTU9ERUxHUk9VUF9DSE9JQ0U6Ci0gICAgICAgIGNhc2UgWFNNb2RlbEdyb3VwSW1wbC5NT0RFTEdST1VQX1NFUVVFTkNFOiB7Ci0gICAgICAgICAgICBpZiAodHlwZSA9PSBYU01vZGVsR3JvdXBJbXBsLk1PREVMR1JPVVBfQ0hPSUNFKQotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIkNob2ljZSBOb2RlICIpOwotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIlNlcSBOb2RlICIpOwotCi0gICAgICAgICAgICBpZiAobm9kZUN1ci5pc051bGxhYmxlKCkpCi0gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiTnVsbGFibGUgIik7Ci0KLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoImZpcnN0UG9zPSIpOwotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludChub2RlQ3VyLmZpcnN0UG9zKCkudG9TdHJpbmcoKSk7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCIgbGFzdFBvcz0iKTsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbihub2RlQ3VyLmxhc3RQb3MoKS50b1N0cmluZygpKTsKLQotICAgICAgICAgICAgZHVtcFRyZWUoKChYU0NNQmluT3Apbm9kZUN1cikuZ2V0TGVmdCgpLCBsZXZlbCsxKTsKLSAgICAgICAgICAgIGR1bXBUcmVlKCgoWFNDTUJpbk9wKW5vZGVDdXIpLmdldFJpZ2h0KCksIGxldmVsKzEpOwotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIH0KLSAgICAgICAgY2FzZSBYU1BhcnRpY2xlRGVjbC5QQVJUSUNMRV9aRVJPX09SX01PUkU6Ci0gICAgICAgIGNhc2UgWFNQYXJ0aWNsZURlY2wuUEFSVElDTEVfT05FX09SX01PUkU6Ci0gICAgICAgIGNhc2UgWFNQYXJ0aWNsZURlY2wuUEFSVElDTEVfWkVST19PUl9PTkU6IHsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIlJlcCBOb2RlICIpOwotCi0gICAgICAgICAgICBpZiAobm9kZUN1ci5pc051bGxhYmxlKCkpCi0gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiTnVsbGFibGUgIik7Ci0KLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoImZpcnN0UG9zPSIpOwotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludChub2RlQ3VyLmZpcnN0UG9zKCkudG9TdHJpbmcoKSk7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCIgbGFzdFBvcz0iKTsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbihub2RlQ3VyLmxhc3RQb3MoKS50b1N0cmluZygpKTsKLQotICAgICAgICAgICAgZHVtcFRyZWUoKChYU0NNVW5pT3Apbm9kZUN1cikuZ2V0Q2hpbGQoKSwgbGV2ZWwrMSk7Ci0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgfQotICAgICAgICBjYXNlIFhTUGFydGljbGVEZWNsLlBBUlRJQ0xFX0VMRU1FTlQ6IHsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQKLSAgICAgICAgICAgICgKLSAgICAgICAgICAgICAgICAiTGVhZjogKHBvcz0iCi0gICAgICAgICAgICAgICAgKyAoKFhTQ01MZWFmKW5vZGVDdXIpLmdldFBvc2l0aW9uKCkKLSAgICAgICAgICAgICAgICArICIpLCAiCi0gICAgICAgICAgICAgICAgKyAiKGVsZW1JbmRleD0iCi0gICAgICAgICAgICAgICAgKyAoKFhTQ01MZWFmKW5vZGVDdXIpLmdldExlYWYoKQotICAgICAgICAgICAgICAgICsgIikgIgotICAgICAgICAgICAgKTsKLQotICAgICAgICAgICAgaWYgKG5vZGVDdXIuaXNOdWxsYWJsZSgpKQotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIiBOdWxsYWJsZSAiKTsKLQotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiZmlyc3RQb3M9Iik7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KG5vZGVDdXIuZmlyc3RQb3MoKS50b1N0cmluZygpKTsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIiBsYXN0UG9zPSIpOwotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKG5vZGVDdXIubGFzdFBvcygpLnRvU3RyaW5nKCkpOwotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIH0KLSAgICAgICAgY2FzZSBYU1BhcnRpY2xlRGVjbC5QQVJUSUNMRV9XSUxEQ0FSRDoKLSAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiQW55IE5vZGU6ICIpOwotCi0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCJmaXJzdFBvcz0iKTsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQobm9kZUN1ci5maXJzdFBvcygpLnRvU3RyaW5nKCkpOwotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiIGxhc3RQb3M9Iik7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4obm9kZUN1ci5sYXN0UG9zKCkudG9TdHJpbmcoKSk7Ci0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgZGVmYXVsdDogewotICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIkltcGxlbWVudGF0aW9uTWVzc2FnZXMuVkFMX05JSUNNIik7Ci0gICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiAtMSBpcyB1c2VkIHRvIHJlcHJlc2VudCBiYWQgdHJhbnNpdGlvbnMgaW4gdGhlIHRyYW5zaXRpb24gdGFibGUKLSAgICAgKiBlbnRyeSBmb3IgZWFjaCBzdGF0ZS4gU28gZWFjaCBlbnRyeSBpcyBpbml0aWFsaXplZCB0byBhbiBhbGwgLTEKLSAgICAgKiBhcnJheS4gVGhpcyBtZXRob2QgY3JlYXRlcyBhIG5ldyBlbnRyeSBhbmQgaW5pdGlhbGl6ZXMgaXQuCi0gICAgICovCi0gICAgcHJpdmF0ZSBpbnRbXSBtYWtlRGVmU3RhdGVMaXN0KCkKLSAgICB7Ci0gICAgICAgIGludFtdIHJldEFycmF5ID0gbmV3IGludFtmRWxlbU1hcFNpemVdOwotICAgICAgICBmb3IgKGludCBpbmRleCA9IDA7IGluZGV4IDwgZkVsZW1NYXBTaXplOyBpbmRleCsrKQotICAgICAgICAgICAgcmV0QXJyYXlbaW5kZXhdID0gLTE7Ci0gICAgICAgIHJldHVybiByZXRBcnJheTsKLSAgICB9Ci0KLSAgICAvKiogUG9zdCB0cmVlIGJ1aWxkIGluaXRpYWxpemF0aW9uLiAqLwotICAgIHByaXZhdGUgdm9pZCBwb3N0VHJlZUJ1aWxkSW5pdChDTU5vZGUgbm9kZUN1cikgdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gewotICAgICAgICAvLyBTZXQgdGhlIG1heGltdW0gc3RhdGVzIG9uIHRoaXMgbm9kZQotICAgICAgICBub2RlQ3VyLnNldE1heFN0YXRlcyhmTGVhZkNvdW50KTsKLQotICAgICAgICBYU0NNTGVhZiBsZWFmID0gbnVsbDsKLSAgICAgICAgaW50IHBvcyA9IDA7Ci0gICAgICAgIC8vIFJlY3Vyc2UgYXMgcmVxdWlyZWQKLSAgICAgICAgaWYgKG5vZGVDdXIudHlwZSgpID09IFhTUGFydGljbGVEZWNsLlBBUlRJQ0xFX1dJTERDQVJEKSB7Ci0gICAgICAgICAgICBsZWFmID0gKFhTQ01MZWFmKW5vZGVDdXI7Ci0gICAgICAgICAgICBwb3MgPSBsZWFmLmdldFBvc2l0aW9uKCk7Ci0gICAgICAgICAgICBmTGVhZkxpc3RbcG9zXSA9IGxlYWY7Ci0gICAgICAgICAgICBmTGVhZkxpc3RUeXBlW3Bvc10gPSBYU1BhcnRpY2xlRGVjbC5QQVJUSUNMRV9XSUxEQ0FSRDsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICgobm9kZUN1ci50eXBlKCkgPT0gWFNNb2RlbEdyb3VwSW1wbC5NT0RFTEdST1VQX0NIT0lDRSkgfHwKLSAgICAgICAgICAgICAgICAgKG5vZGVDdXIudHlwZSgpID09IFhTTW9kZWxHcm91cEltcGwuTU9ERUxHUk9VUF9TRVFVRU5DRSkpIHsKLSAgICAgICAgICAgIHBvc3RUcmVlQnVpbGRJbml0KCgoWFNDTUJpbk9wKW5vZGVDdXIpLmdldExlZnQoKSk7Ci0gICAgICAgICAgICBwb3N0VHJlZUJ1aWxkSW5pdCgoKFhTQ01CaW5PcClub2RlQ3VyKS5nZXRSaWdodCgpKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChub2RlQ3VyLnR5cGUoKSA9PSBYU1BhcnRpY2xlRGVjbC5QQVJUSUNMRV9aRVJPX09SX01PUkUgfHwKLSAgICAgICAgICAgICAgICAgbm9kZUN1ci50eXBlKCkgPT0gWFNQYXJ0aWNsZURlY2wuUEFSVElDTEVfT05FX09SX01PUkUgfHwKLSAgICAgICAgICAgICAgICAgbm9kZUN1ci50eXBlKCkgPT0gWFNQYXJ0aWNsZURlY2wuUEFSVElDTEVfWkVST19PUl9PTkUpIHsKLSAgICAgICAgICAgIHBvc3RUcmVlQnVpbGRJbml0KCgoWFNDTVVuaU9wKW5vZGVDdXIpLmdldENoaWxkKCkpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKG5vZGVDdXIudHlwZSgpID09IFhTUGFydGljbGVEZWNsLlBBUlRJQ0xFX0VMRU1FTlQpIHsKLSAgICAgICAgICAgIC8vICBQdXQgdGhpcyBub2RlIGluIHRoZSBsZWFmIGxpc3QgYXQgdGhlIGN1cnJlbnQgaW5kZXggaWYgaXRzCi0gICAgICAgICAgICAvLyAgYSBub24tZXBzaWxvbiBsZWFmLgotICAgICAgICAgICAgbGVhZiA9IChYU0NNTGVhZilub2RlQ3VyOwotICAgICAgICAgICAgcG9zID0gbGVhZi5nZXRQb3NpdGlvbigpOwotICAgICAgICAgICAgZkxlYWZMaXN0W3Bvc10gPSBsZWFmOwotICAgICAgICAgICAgZkxlYWZMaXN0VHlwZVtwb3NdID0gWFNQYXJ0aWNsZURlY2wuUEFSVElDTEVfRUxFTUVOVDsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJJbXBsZW1lbnRhdGlvbk1lc3NhZ2VzLlZBTF9OSUlDTSIpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogY2hlY2sgd2hldGhlciB0aGlzIGNvbnRlbnQgdmlvbGF0ZXMgVVBBIGNvbnN0cmFpbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc3ViR3JvdXBIYW5kbGVyIHRoZSBzdWJzdGl0dXRpb24gZ3JvdXAgaGFuZGxlcgotICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGlzIGNvbnRlbnQgbW9kZWwgY29udGFpbnMgb3RoZXIgb3IgbGlzdCB3aWxkY2FyZAotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGNoZWNrVW5pcXVlUGFydGljbGVBdHRyaWJ1dGlvbihTdWJzdGl0dXRpb25Hcm91cEhhbmRsZXIgc3ViR3JvdXBIYW5kbGVyKSB0aHJvd3MgWE1MU2NoZW1hRXhjZXB0aW9uIHsKLSAgICAgICAgLy8gVW5pcXVlIFBhcnRpY2xlIEF0dHJpYnV0aW9uCi0gICAgICAgIC8vIHN0b3JlIHRoZSBjb25mbGljdCByZXN1bHRzIGJldHdlZW4gYW55IHR3byBlbGVtZW50cyBpbiBmRWxlbU1hcAotICAgICAgICAvLyAwOiBub3QgY29tcGFyZWQ7IC0xOiBubyBjb25mbGljdDsgMTogY29uZmxpY3QKLSAgICAgICAgLy8gaW5pdGlhbGl6ZSB0aGUgY29uZmxpY3QgdGFibGUgKGFsbCAwIGluaXRpYWxseSkKLSAgICAgICAgYnl0ZSBjb25mbGljdFRhYmxlW11bXSA9IG5ldyBieXRlW2ZFbGVtTWFwU2l6ZV1bZkVsZW1NYXBTaXplXTsKLQotICAgICAgICAvLyBmb3IgZWFjaCBzdGF0ZSwgY2hlY2sgd2hldGhlciBpdCBoYXMgb3ZlcmxhcCB0cmFuc2l0aW9ucwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZUcmFuc1RhYmxlLmxlbmd0aCAmJiBmVHJhbnNUYWJsZVtpXSAhPSBudWxsOyBpKyspIHsKLSAgICAgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgZkVsZW1NYXBTaXplOyBqKyspIHsKLSAgICAgICAgICAgICAgICBmb3IgKGludCBrID0gaisxOyBrIDwgZkVsZW1NYXBTaXplOyBrKyspIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGZUcmFuc1RhYmxlW2ldW2pdICE9IC0xICYmCi0gICAgICAgICAgICAgICAgICAgICAgICBmVHJhbnNUYWJsZVtpXVtrXSAhPSAtMSkgewotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvbmZsaWN0VGFibGVbal1ba10gPT0gMCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChYU0NvbnN0cmFpbnRzLm92ZXJsYXBVUEEKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChmRWxlbU1hcFtqXSwgZkVsZW1NYXBba10sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1Ykdyb3VwSGFuZGxlcikpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZDb3VudGluZ1N0YXRlcyAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPY2N1cmVuY2UgbyA9IGZDb3VudGluZ1N0YXRlc1tpXTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIElmICJpIiBpcyBhIGNvdW50aW5nIHN0YXRlIGFuZCBleGFjdGx5IG9uZSBvZiB0aGUgdHJhbnNpdGlvbnMKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGxvb3BzIGJhY2sgdG8gImkiIHRoZW4gdGhlIHR3byBwYXJ0aWNsZXMgZG8gbm90IG92ZXJsYXAgaWYKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG1pbk9jY3VycyA9PSBtYXhPY2N1cnMuCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobyAhPSBudWxsICYmCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZlRyYW5zVGFibGVbaV1bal0gPT0gaSBeIGZUcmFuc1RhYmxlW2ldW2tdID09IGkgJiYKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvLm1pbk9jY3VycyA9PSBvLm1heE9jY3VycykgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZsaWN0VGFibGVbal1ba10gPSAoYnl0ZSkgLTE7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZmxpY3RUYWJsZVtqXVtrXSA9IChieXRlKSAxOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZmxpY3RUYWJsZVtqXVtrXSA9IChieXRlKSAtMTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyByZXBvcnQgYWxsIGVycm9ycwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZFbGVtTWFwU2l6ZTsgaSsrKSB7Ci0gICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IGZFbGVtTWFwU2l6ZTsgaisrKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGNvbmZsaWN0VGFibGVbaV1bal0gPT0gMSkgewotICAgICAgICAgICAgICAgICAgICAvL2Vycm9ycy5uZXdFcnJvcigiY29zLW5vbmFtYmlnIiwgbmV3IE9iamVjdFtde2ZFbGVtTWFwW2ldLnRvU3RyaW5nKCksCi0gICAgICAgICAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkVsZW1NYXBbal0udG9TdHJpbmcoKX0pOwotICAgICAgICAgICAgICAgICAgICAvLyBSRVZJU0lUOiBkbyB3ZSB3YW50IHRvIHJlcG9ydCBhbGwgZXJyb3JzPyBvciBqdXN0IG9uZT8KLSAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFhNTFNjaGVtYUV4Y2VwdGlvbigiY29zLW5vbmFtYmlnIiwgbmV3IE9iamVjdFtde2ZFbGVtTWFwW2ldLnRvU3RyaW5nKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmRWxlbU1hcFtqXS50b1N0cmluZygpfSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gaWYgdGhlcmUgaXMgYSBvdGhlciBvciBsaXN0IHdpbGRjYXJkLCB3ZSBuZWVkIHRvIGNoZWNrIHRoaXMgQ00KLSAgICAgICAgLy8gYWdhaW4sIGlmIHRoaXMgZ3JhbW1hciBpcyBjYWNoZWQuCi0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZkVsZW1NYXBTaXplOyBpKyspIHsKLSAgICAgICAgICAgIGlmIChmRWxlbU1hcFR5cGVbaV0gPT0gWFNQYXJ0aWNsZURlY2wuUEFSVElDTEVfV0lMRENBUkQpIHsKLSAgICAgICAgICAgICAgICBYU1dpbGRjYXJkRGVjbCB3aWxkY2FyZCA9IChYU1dpbGRjYXJkRGVjbClmRWxlbU1hcFtpXTsKLSAgICAgICAgICAgICAgICBpZiAod2lsZGNhcmQuZlR5cGUgPT0gWFNXaWxkY2FyZERlY2wuTlNDT05TVFJBSU5UX0xJU1QgfHwKLSAgICAgICAgICAgICAgICAgICAgd2lsZGNhcmQuZlR5cGUgPT0gWFNXaWxkY2FyZERlY2wuTlNDT05TVFJBSU5UX05PVCkgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ2hlY2sgd2hpY2ggZWxlbWVudHMgYXJlIHZhbGlkIHRvIGFwcGVhciBhdCB0aGlzIHBvaW50LiBUaGlzIG1ldGhvZCBhbHNvCi0gICAgICogd29ya3MgaWYgdGhlIHN0YXRlIGlzIGluIGVycm9yLCBpbiB3aGljaCBjYXNlIGl0IHJldHVybnMgd2hhdCBzaG91bGQKLSAgICAgKiBoYXZlIGJlZW4gc2Vlbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzdGF0ZSAgdGhlIGN1cnJlbnQgc3RhdGUKLSAgICAgKiBAcmV0dXJuICAgICAgIGEgVmVjdG9yIHdob3NlIGVudHJpZXMgYXJlIGluc3RhbmNlcyBvZgotICAgICAqICAgICAgICAgICAgICAgZWl0aGVyIFhTV2lsZGNhcmREZWNsIG9yIFhTRWxlbWVudERlY2wuCi0gICAgICovCi0gICAgcHVibGljIFZlY3RvciB3aGF0Q2FuR29IZXJlKGludFtdIHN0YXRlKSB7Ci0gICAgICAgIGludCBjdXJTdGF0ZSA9IHN0YXRlWzBdOwotICAgICAgICBpZiAoY3VyU3RhdGUgPCAwKQotICAgICAgICAgICAgY3VyU3RhdGUgPSBzdGF0ZVsxXTsKLSAgICAgICAgT2NjdXJlbmNlIG8gPSAoZkNvdW50aW5nU3RhdGVzICE9IG51bGwpID8KLSAgICAgICAgICAgICAgICBmQ291bnRpbmdTdGF0ZXNbY3VyU3RhdGVdIDogbnVsbDsKLSAgICAgICAgaW50IGNvdW50ID0gc3RhdGVbMl07Ci0KLSAgICAgICAgVmVjdG9yIHJldCA9IG5ldyBWZWN0b3IoKTsKLSAgICAgICAgZm9yIChpbnQgZWxlbUluZGV4ID0gMDsgZWxlbUluZGV4IDwgZkVsZW1NYXBTaXplOyBlbGVtSW5kZXgrKykgewotICAgICAgICAgICAgaW50IG5leHRTdGF0ZSA9IGZUcmFuc1RhYmxlW2N1clN0YXRlXVtlbGVtSW5kZXhdOwotICAgICAgICAgICAgaWYgKG5leHRTdGF0ZSAhPSAtMSkgewotICAgICAgICAgICAgICAgIGlmIChvICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGN1clN0YXRlID09IG5leHRTdGF0ZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gRG8gbm90IGluY2x1ZGUgdHJhbnNpdGlvbnMgd2hpY2ggbG9vcCBiYWNrIHRvIHRoZQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gY3VycmVudCBzdGF0ZSBpZiB3ZSd2ZSBsb29wZWQgdGhlIG1heGltdW0gbnVtYmVyCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBvZiB0aW1lcyBvciBncmVhdGVyLgotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvdW50ID49IG8ubWF4T2NjdXJzICYmCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgby5tYXhPY2N1cnMgIT0gU2NoZW1hU3ltYm9scy5PQ0NVUlJFTkNFX1VOQk9VTkRFRCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIC8vIERvIG5vdCBpbmNsdWRlIHRyYW5zaXRpb25zIHdoaWNoIGFkdmFuY2UgcGFzdCB0aGUKLSAgICAgICAgICAgICAgICAgICAgLy8gY3VycmVudCBzdGF0ZSBpZiB3ZSBoYXZlIG5vdCBsb29wZWQgZW5vdWdoIHRpbWVzLgotICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChjb3VudCA8IG8ubWluT2NjdXJzKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICByZXQuYWRkRWxlbWVudChmRWxlbU1hcFtlbGVtSW5kZXhdKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gcmV0OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFVzZWQgYnkgY29uc3RhbnQgc3BhY2UgYWxnb3JpdGhtIGZvciBhe24sbX0gZm9yIG4gPiAxIGFuZAotICAgICAqIG0gPD0gdW5ib3VuZGVkLiBDYWxsZWQgYnkgYSB2YWxpZGF0b3IgaWYgdmFsaWRhdGlvbiBvZgotICAgICAqIGNvdW50ZW50IG1vZGVsIHN1Y2NlZWRzIGFmdGVyIHN1YnN1bWluZyBhe24sbX0gdG8gYSoKLSAgICAgKiAob3IgYSspIHRvIGNoZWNrIHRoZSBuIGFuZCBtIGJvdW5kcy4KLSAgICAgKiBSZXR1cm5zIDxjb2RlPm51bGw8L2NvZGU+IGlmIHZhbGlkYXRpb24gb2YgYm91bmRzIGlzCi0gICAgICogc3VjY2Vzc2Z1bC4gUmV0dXJucyBhIGxpc3Qgb2Ygc3RyaW5ncyB3aXRoIGVycm9yIGluZm8KLSAgICAgKiBpZiBub3QuIEV2ZW4gZW50cmllcyBpbiBsaXN0IHJldHVybmVkIGFyZSBlcnJvciBjb2RlcwotICAgICAqICh1c2VkIHRvIGxvb2sgdXAgcHJvcGVydGllcykgYW5kIG9kZCBlbnRyaWVzIGFyZSBwYXJhbWV0ZXJzCi0gICAgICogdG8gYmUgcGFzc2VkIHdoZW4gZm9ybWF0dGluZyBlcnJvciBtZXNzYWdlLiBFYWNoIHBhcmFtZXRlcgotICAgICAqIGlzIGFzc29jaWF0ZWQgd2l0aCB0aGUgZXJyb3IgY29kZSB0aGF0IHByZWNlZWRzIGl0IGluCi0gICAgICogdGhlIGxpc3QuCi0gICAgICovCi0gICAgcHVibGljIEFycmF5TGlzdCBjaGVja01pbk1heEJvdW5kcygpIHsKLSAgICAgICAgQXJyYXlMaXN0IHJlc3VsdCA9IG51bGw7Ci0gICAgICAgIGZvciAoaW50IGVsZW1JbmRleCA9IDA7IGVsZW1JbmRleCA8IGZFbGVtTWFwU2l6ZTsgZWxlbUluZGV4KyspIHsKLSAgICAgICAgICAgIGludCBjb3VudCA9IGZFbGVtTWFwQ291bnRlcltlbGVtSW5kZXhdOwotICAgICAgICAgICAgaWYgKGNvdW50ID09IC0xKSB7Ci0gICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmaW5hbCBpbnQgbWluT2NjdXJzID0gZkVsZW1NYXBDb3VudGVyTG93ZXJCb3VuZFtlbGVtSW5kZXhdOwotICAgICAgICAgICAgZmluYWwgaW50IG1heE9jY3VycyA9IGZFbGVtTWFwQ291bnRlclVwcGVyQm91bmRbZWxlbUluZGV4XTsKLSAgICAgICAgICAgIGlmIChjb3VudCA8IG1pbk9jY3VycykgewotICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgPT0gbnVsbCkgcmVzdWx0ID0gbmV3IEFycmF5TGlzdCgpOwotICAgICAgICAgICAgICAgIHJlc3VsdC5hZGQoImN2Yy1jb21wbGV4LXR5cGUuMi40LmIiKTsKLSAgICAgICAgICAgICAgICByZXN1bHQuYWRkKCJ7IiArIGZFbGVtTWFwW2VsZW1JbmRleF0gKyAifSIpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKG1heE9jY3VycyAhPSAtMSAmJiBjb3VudCA+IG1heE9jY3VycykgewotICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgPT0gbnVsbCkgcmVzdWx0ID0gbmV3IEFycmF5TGlzdCgpOwotICAgICAgICAgICAgICAgIHJlc3VsdC5hZGQoImN2Yy1jb21wbGV4LXR5cGUuMi40LmUiKTsKLSAgICAgICAgICAgICAgICByZXN1bHQuYWRkKCJ7IiArIGZFbGVtTWFwW2VsZW1JbmRleF0gKyAifSIpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiByZXN1bHQ7Ci0gICAgfQotCi19IC8vIGNsYXNzIERGQUNvbnRlbnRNb2RlbApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9tb2RlbHMvWFNFbXB0eUNNLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL21vZGVscy9YU0VtcHR5Q00uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNjczMjExZi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL21vZGVscy9YU0VtcHR5Q00uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE0MSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5tb2RlbHM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5RTmFtZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMuU3Vic3RpdHV0aW9uR3JvdXBIYW5kbGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5YTUxTY2hlbWFFeGNlcHRpb247Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7Ci0KLS8qKgotICogWFNFbXB0eUNNIGlzIGEgZGVyaXZhdGl2ZSBvZiB0aGUgYWJzdHJhY3QgY29udGVudCBtb2RlbCBiYXNlIGNsYXNzIHRoYXQKLSAqIGhhbmRsZXMgYSBjb250ZW50IG1vZGVsIHdpdGggbm8gY2hpbHJlbiAoZWxlbWVudHMpLgotICoKLSAqIFRoaXMgbW9kZWwgdmFsaWRhdGVkIG9uIHRoZSB3YXkgaW4uCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgRWxlbmEgTGl0YW5pLCBMaXNhIE1hcnRpbgotICogQGF1dGhvciBJQk0KLSAqIEB2ZXJzaW9uICRJZDogWFNFbXB0eUNNLmphdmEsdiAxLjcgMjAwOS8wNy8yOCAxNToxODoxMSBzcGVyaWNhcyBFeHAgJAotICovCi1wdWJsaWMgY2xhc3MgWFNFbXB0eUNNICBpbXBsZW1lbnRzIFhTQ01WYWxpZGF0b3IgewotCi0gICAgLy8KLSAgICAvLyBDb25zdGFudHMKLSAgICAvLwotCi0gICAgLy8gc3RhcnQgdGhlIGNvbnRlbnQgbW9kZWw6IGRpZCBub3Qgc2VlIGFueSBjaGlsZHJlbgotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHNob3J0IFNUQVRFX1NUQVJUID0gMDsKLQotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFZlY3RvciBFTVBUWSA9IG5ldyBWZWN0b3IoMCk7Ci0KLSAgICAvLwotICAgIC8vIERhdGEKLSAgICAvLwotCi0gICAgLy8KLSAgICAvLyBYU0NNVmFsaWRhdG9yIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2RzIHRvIGJlIGNhbGxlZCBvbiBlbnRlcmluZyBhIGZpcnN0IGVsZW1lbnQgd2hvc2UgdHlwZQotICAgICAqIGhhcyB0aGlzIGNvbnRlbnQgbW9kZWwuIEl0IHdpbGwgcmV0dXJuIHRoZSBpbml0aWFsIHN0YXRlIG9mIHRoZSBjb250ZW50IG1vZGVsCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFN0YXJ0IHN0YXRlIG9mIHRoZSBjb250ZW50IG1vZGVsCi0gICAgICovCi0gICAgcHVibGljIGludFtdIHN0YXJ0Q29udGVudE1vZGVsKCl7Ci0gICAgICAgIHJldHVybiAobmV3IGludFtdIHtTVEFURV9TVEFSVH0pOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogVGhlIG1ldGhvZCBjb3JyZXNwb25kcyB0byBvbmUgdHJhbnNhY3Rpb24gaW4gdGhlIGNvbnRlbnQgbW9kZWwuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZWxlbWVudE5hbWUgdGhlIHF1YWxpZmllZCBuYW1lIG9mIHRoZSBlbGVtZW50Ci0gICAgICogQHBhcmFtIGN1cnJlbnRTdGF0ZSBDdXJyZW50IHN0YXRlCi0gICAgICogQHBhcmFtIHN1Ykdyb3VwSGFuZGxlciB0aGUgc3Vic3RpdHV0aW9uIGdyb3VwIGhhbmRsZXIKLSAgICAgKiBAcmV0dXJuIGVsZW1lbnQgaW5kZXggY29ycmVzcG9uZGluZyB0byB0aGUgZWxlbWVudCBmcm9tIHRoZSBTY2hlbWEgZ3JhbW1hcgotICAgICAqLwotICAgIHB1YmxpYyBPYmplY3Qgb25lVHJhbnNpdGlvbiAoUU5hbWUgZWxlbWVudE5hbWUsIGludFtdIGN1cnJlbnRTdGF0ZSwgU3Vic3RpdHV0aW9uR3JvdXBIYW5kbGVyIHN1Ykdyb3VwSGFuZGxlcil7Ci0KLSAgICAgICAgLy8gZXJyb3Igc3RhdGUKLSAgICAgICAgaWYgKGN1cnJlbnRTdGF0ZVswXSA8IDApIHsKLSAgICAgICAgICAgIGN1cnJlbnRTdGF0ZVswXSA9IFhTQ01WYWxpZGF0b3IuU1VCU0VRVUVOVF9FUlJPUjsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0KLSAgICAgICAgY3VycmVudFN0YXRlWzBdID0gWFNDTVZhbGlkYXRvci5GSVJTVF9FUlJPUjsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBUaGUgbWV0aG9kIGluZGljYXRlcyB0aGUgZW5kIG9mIGxpc3Qgb2YgY2hpbGRyZW4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjdXJyZW50U3RhdGUgQ3VycmVudCBzdGF0ZSBvZiB0aGUgY29udGVudCBtb2RlbAotICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgbGFzdCBzdGF0ZSB3YXMgYSB2YWxpZCBmaW5hbCBzdGF0ZQotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGVuZENvbnRlbnRNb2RlbCAoaW50W10gY3VycmVudFN0YXRlKXsKLSAgICAgICAgYm9vbGVhbiBpc0ZpbmFsID0gIGZhbHNlOwotICAgICAgICBpbnQgc3RhdGUgPSBjdXJyZW50U3RhdGVbMF07Ci0KLSAgICAgICAgLy8gcmVzdG9yZSBjb250ZW50IG1vZGVsIHN0YXRlOgotCi0gICAgICAgIC8vIGVycm9yCi0gICAgICAgIGlmIChzdGF0ZSA8IDApIHsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotCi0KLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogY2hlY2sgd2hldGhlciB0aGlzIGNvbnRlbnQgdmlvbGF0ZXMgVVBBIGNvbnN0cmFpbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc3ViR3JvdXBIYW5kbGVyIHRoZSBzdWJzdGl0dXRpb24gZ3JvdXAgaGFuZGxlcgotICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGlzIGNvbnRlbnQgbW9kZWwgY29udGFpbnMgb3RoZXIgb3IgbGlzdCB3aWxkY2FyZAotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGNoZWNrVW5pcXVlUGFydGljbGVBdHRyaWJ1dGlvbihTdWJzdGl0dXRpb25Hcm91cEhhbmRsZXIgc3ViR3JvdXBIYW5kbGVyKSB0aHJvd3MgWE1MU2NoZW1hRXhjZXB0aW9uIHsKLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENoZWNrIHdoaWNoIGVsZW1lbnRzIGFyZSB2YWxpZCB0byBhcHBlYXIgYXQgdGhpcyBwb2ludC4gVGhpcyBtZXRob2QgYWxzbwotICAgICAqIHdvcmtzIGlmIHRoZSBzdGF0ZSBpcyBpbiBlcnJvciwgaW4gd2hpY2ggY2FzZSBpdCByZXR1cm5zIHdoYXQgc2hvdWxkCi0gICAgICogaGF2ZSBiZWVuIHNlZW4uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc3RhdGUgIHRoZSBjdXJyZW50IHN0YXRlCi0gICAgICogQHJldHVybiAgICAgICBhIFZlY3RvciB3aG9zZSBlbnRyaWVzIGFyZSBpbnN0YW5jZXMgb2YKLSAgICAgKiAgICAgICAgICAgICAgIGVpdGhlciBYU1dpbGRjYXJkRGVjbCBvciBYU0VsZW1lbnREZWNsLgotICAgICAqLwotICAgIHB1YmxpYyBWZWN0b3Igd2hhdENhbkdvSGVyZShpbnRbXSBzdGF0ZSkgewotICAgICAgICByZXR1cm4gRU1QVFk7Ci0gICAgfQotCi0gICAgcHVibGljIEFycmF5TGlzdCBjaGVja01pbk1heEJvdW5kcygpIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi19IC8vIGNsYXNzIFhTRW1wdHlDTQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9vcHRpL0F0dHJJbXBsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL29wdGkvQXR0ckltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMzMxZmMyNi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL29wdGkvQXR0ckltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE1MiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxLCAyMDAyIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGVyY2VzIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBJbnRlcm5hdGlvbmFsCi0gKiBCdXNpbmVzcyBNYWNoaW5lcywgSW5jLiwgaHR0cDovL3d3dy5hcGFjaGUub3JnLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLm9wdGk7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5BdHRyOwotaW1wb3J0IG9yZy53M2MuZG9tLkRPTUV4Y2VwdGlvbjsKLWltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKLWltcG9ydCBvcmcudzNjLmRvbS5FbGVtZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci1pbXBvcnQgb3JnLnczYy5kb20uVHlwZUluZm87Ci0KLS8qKgotICogVGhpcyBjbGFzcyByZXByZXNlbnRzIGEgc2luZ2xlIGF0dHJpYnV0ZS4KLSAqCi0gKiBAYXV0aG9yIFJhaHVsIFNyaXZhc3RhdmEsIFN1biBNaWNyb3N5c3RlbXMgSW5jLgotICoKLSAqIEB2ZXJzaW9uICRJZDogQXR0ckltcGwuamF2YSx2IDEuNSAyMDEwLTExLTAxIDA0OjQwOjAxIGpvZWh3IEV4cCAkCi0gKi8KLXB1YmxpYyBjbGFzcyBBdHRySW1wbCBleHRlbmRzIE5vZGVJbXBsCi0gICAgICAgICAgICAgICAgICAgICAgaW1wbGVtZW50cyBBdHRyIHsKLQotICAgIEVsZW1lbnQgZWxlbWVudDsKLSAgICBTdHJpbmcgdmFsdWU7Ci0KLSAgICAvKiogRGVmYXVsdCBDb25zdHJ1Y3RvciAqLwotICAgIHB1YmxpYyBBdHRySW1wbCgpIHsKLSAgICAgICAgbm9kZVR5cGUgPSBOb2RlLkFUVFJJQlVURV9OT0RFOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHMgYW4gYXR0cmlidXRlLgotICAgICAqCi0gICAgICogQHBhcmFtIGVsZW1lbnQgRWxlbWVudCB3aGljaCBvd25zIHRoaXMgYXR0cmlidXRlCi0gICAgICogQHBhcmFtIHByZWZpeCBUaGUgUU5hbWUgcHJlZml4LgotICAgICAqIEBwYXJhbSBsb2NhbHBhcnQgVGhlIFFOYW1lIGxvY2FscGFydC4KLSAgICAgKiBAcGFyYW0gcmF3bmFtZSBUaGUgUU5hbWUgcmF3bmFtZS4KLSAgICAgKiBAcGFyYW0gdXJpIFRoZSB1cmkgYmluZGluZyBmb3IgdGhlIGFzc29jaWF0ZWQgcHJlZml4LgotICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgQXR0ckltcGwoRWxlbWVudCBlbGVtZW50LCBTdHJpbmcgcHJlZml4LCBTdHJpbmcgbG9jYWxwYXJ0LCBTdHJpbmcgcmF3bmFtZSwgU3RyaW5nIHVyaSwgU3RyaW5nIHZhbHVlKSB7Ci0gICAgICAgIHN1cGVyKHByZWZpeCwgbG9jYWxwYXJ0LCByYXduYW1lLCB1cmksIE5vZGUuQVRUUklCVVRFX05PREUpOwotICAgICAgICB0aGlzLmVsZW1lbnQgPSBlbGVtZW50OwotICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXROYW1lKCkgewotICAgICAgICByZXR1cm4gcmF3bmFtZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXRTcGVjaWZpZWQoKSB7Ci0gICAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VmFsdWUoKSB7Ci0gICAgICAgIHJldHVybiB2YWx1ZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldE5vZGVWYWx1ZSgpIHsKLSAgICAgICAgcmV0dXJuIGdldFZhbHVlKCk7Ci0gICAgfQotCi0gICAgcHVibGljIEVsZW1lbnQgZ2V0T3duZXJFbGVtZW50KCkgewotICAgICAgICByZXR1cm4gZWxlbWVudDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgRG9jdW1lbnQgZ2V0T3duZXJEb2N1bWVudCgpIHsKLSAgICAgICAgcmV0dXJuIGVsZW1lbnQuZ2V0T3duZXJEb2N1bWVudCgpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldFZhbHVlKFN0cmluZyB2YWx1ZSkgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0gICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0lkKCl7Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBNZXRob2QgZ2V0U2NoZW1hVHlwZUluZm8uCi0gICAgICogQHJldHVybiBUeXBlSW5mbwotICAgICAqLwotICAgIHB1YmxpYyBUeXBlSW5mbyBnZXRTY2hlbWFUeXBlSW5mbygpewotICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLyoqIE5PTi1ET00gbWV0aG9kIGZvciBkZWJ1Z2dpbmcgY29udmVuaWVuY2UgKi8KLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgICAgICByZXR1cm4gZ2V0TmFtZSgpICsgIj0iICsgIlwiIiArIGdldFZhbHVlKCkgKyAiXCIiOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvb3B0aS9EZWZhdWx0RG9jdW1lbnQuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvb3B0aS9EZWZhdWx0RG9jdW1lbnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggODMyMmU4Ny4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL29wdGkvRGVmYXVsdERvY3VtZW50LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyOTEgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMSwgMjAwMiwyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMub3B0aTsKLQotaW1wb3J0IG9yZy53M2MuZG9tLkRPTUNvbmZpZ3VyYXRpb247Ci1pbXBvcnQgb3JnLnczYy5kb20uQXR0cjsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotaW1wb3J0IG9yZy53M2MuZG9tLlRleHQ7Ci1pbXBvcnQgb3JnLnczYy5kb20uRWxlbWVudDsKLWltcG9ydCBvcmcudzNjLmRvbS5Db21tZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGVMaXN0OwotaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50VHlwZTsKLWltcG9ydCBvcmcudzNjLmRvbS5DREFUQVNlY3Rpb247Ci1pbXBvcnQgb3JnLnczYy5kb20uRW50aXR5UmVmZXJlbmNlOwotaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50RnJhZ21lbnQ7Ci1pbXBvcnQgb3JnLnczYy5kb20uRE9NSW1wbGVtZW50YXRpb247Ci1pbXBvcnQgb3JnLnczYy5kb20uUHJvY2Vzc2luZ0luc3RydWN0aW9uOwotCi1pbXBvcnQgb3JnLnczYy5kb20uRE9NRXhjZXB0aW9uOwotCi0KLS8qKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgUmFodWwgU3JpdmFzdGF2YSwgU3VuIE1pY3Jvc3lzdGVtcyBJbmMuCi0gKgotICovCi1wdWJsaWMgY2xhc3MgRGVmYXVsdERvY3VtZW50IGV4dGVuZHMgTm9kZUltcGwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW1wbGVtZW50cyBEb2N1bWVudCB7Ci0KLSAgICBwcml2YXRlIFN0cmluZyBmRG9jdW1lbnRVUkkgPSBudWxsOwotCi0gICAgLy8gZGVmYXVsdCBjb25zdHJ1Y3RvcgotICAgIHB1YmxpYyBEZWZhdWx0RG9jdW1lbnQoKSB7Ci0gICAgfQotCi0gICAgLy8KLSAgICAvLyBvcmcudzNjLmRvbS5Eb2N1bWVudCBtZXRob2RzCi0gICAgLy8KLQotICAgIHB1YmxpYyBEb2N1bWVudFR5cGUgZ2V0RG9jdHlwZSgpIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgRE9NSW1wbGVtZW50YXRpb24gZ2V0SW1wbGVtZW50YXRpb24oKSB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotCi0gICAgcHVibGljIEVsZW1lbnQgZ2V0RG9jdW1lbnRFbGVtZW50KCkgewotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLQotICAgIHB1YmxpYyBOb2RlTGlzdCBnZXRFbGVtZW50c0J5VGFnTmFtZShTdHJpbmcgdGFnbmFtZSkgewotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLQotICAgIHB1YmxpYyBOb2RlTGlzdCBnZXRFbGVtZW50c0J5VGFnTmFtZU5TKFN0cmluZyBuYW1lc3BhY2VVUkksIFN0cmluZyBsb2NhbE5hbWUpIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgRWxlbWVudCBnZXRFbGVtZW50QnlJZChTdHJpbmcgZWxlbWVudElkKSB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotCi0gICAgcHVibGljIE5vZGUgaW1wb3J0Tm9kZShOb2RlIGltcG9ydGVkTm9kZSwgYm9vbGVhbiBkZWVwKSB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKLSAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIsICJNZXRob2Qgbm90IHN1cHBvcnRlZCIpOwotICAgIH0KLQotCi0gICAgcHVibGljIEVsZW1lbnQgY3JlYXRlRWxlbWVudChTdHJpbmcgdGFnTmFtZSkgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0gICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSLCAiTWV0aG9kIG5vdCBzdXBwb3J0ZWQiKTsKLSAgICB9Ci0KLQotICAgIHB1YmxpYyBEb2N1bWVudEZyYWdtZW50IGNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKSB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotCi0gICAgcHVibGljIFRleHQgY3JlYXRlVGV4dE5vZGUoU3RyaW5nIGRhdGEpIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgcHVibGljIENvbW1lbnQgY3JlYXRlQ29tbWVudChTdHJpbmcgZGF0YSkgewotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLQotICAgIHB1YmxpYyBDREFUQVNlY3Rpb24gY3JlYXRlQ0RBVEFTZWN0aW9uKFN0cmluZyBkYXRhKSB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKLSAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIsICJNZXRob2Qgbm90IHN1cHBvcnRlZCIpOwotICAgIH0KLQotCi0gICAgcHVibGljIFByb2Nlc3NpbmdJbnN0cnVjdGlvbiBjcmVhdGVQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oU3RyaW5nIHRhcmdldCwgU3RyaW5nIGRhdGEpIHRocm93cyBET01FeGNlcHRpb24gewotICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUiwgIk1ldGhvZCBub3Qgc3VwcG9ydGVkIik7Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgQXR0ciBjcmVhdGVBdHRyaWJ1dGUoU3RyaW5nIG5hbWUpIHRocm93cyBET01FeGNlcHRpb24gewotICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUiwgIk1ldGhvZCBub3Qgc3VwcG9ydGVkIik7Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgRW50aXR5UmVmZXJlbmNlIGNyZWF0ZUVudGl0eVJlZmVyZW5jZShTdHJpbmcgbmFtZSkgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0gICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSLCAiTWV0aG9kIG5vdCBzdXBwb3J0ZWQiKTsKLSAgICB9Ci0KLQotICAgIHB1YmxpYyBFbGVtZW50IGNyZWF0ZUVsZW1lbnROUyhTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgcXVhbGlmaWVkTmFtZSkgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0gICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSLCAiTWV0aG9kIG5vdCBzdXBwb3J0ZWQiKTsKLSAgICB9Ci0KLQotICAgIHB1YmxpYyBBdHRyIGNyZWF0ZUF0dHJpYnV0ZU5TKFN0cmluZyBuYW1lc3BhY2VVUkksIFN0cmluZyBxdWFsaWZpZWROYW1lKSB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKLSAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIsICJNZXRob2Qgbm90IHN1cHBvcnRlZCIpOwotICAgIH0KLQotICAgIC8vIERPTSBMZXZlbCAzIG1ldGhvZHMuCi0KLSAgICBwdWJsaWMgU3RyaW5nIGdldElucHV0RW5jb2RpbmcoKXsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgcHVibGljIHZvaWQgc2V0SW5wdXRFbmNvZGluZyhTdHJpbmcgYWN0dWFsRW5jb2RpbmcpewotICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSLCAiTWV0aG9kIG5vdCBzdXBwb3J0ZWQiKTsKLSAgICB9Ci0gICAgICAgICovCi0KLSAgICBwdWJsaWMgU3RyaW5nIGdldFhtbEVuY29kaW5nKCl7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogQW4gYXR0cmlidXRlIHNwZWNpZnlpbmcsIGFzIHBhcnQgb2YgdGhlIFhNTCBkZWNsYXJhdGlvbiwgdGhlIGVuY29kaW5nCi0gICAgICogb2YgdGhpcyBkb2N1bWVudC4gVGhpcyBpcyA8Y29kZT5udWxsPC9jb2RlPiB3aGVuIHVuc3BlY2lmaWVkLgotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgIHB1YmxpYyB2b2lkIHNldFhtbEVuY29kaW5nKFN0cmluZyBlbmNvZGluZyl7Ci0gICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSLCAiTWV0aG9kIG5vdCBzdXBwb3J0ZWQiKTsKLSAgICB9Ci0gICAgICovCi0KLSAgICAvKioKLSAgICAgKiBBbiBhdHRyaWJ1dGUgc3BlY2lmeWluZywgYXMgcGFydCBvZiB0aGUgWE1MIGRlY2xhcmF0aW9uLCB3aGV0aGVyIHRoaXMKLSAgICAgKiBkb2N1bWVudCBpcyBzdGFuZGFsb25lLgotICAgICAqIDxicj4gVGhpcyBhdHRyaWJ1dGUgcmVwcmVzZW50cyB0aGUgcHJvcGVydHkgW3N0YW5kYWxvbmVdIGRlZmluZWQgaW4gLgotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGdldFhtbFN0YW5kYWxvbmUoKXsKLSAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIsICJNZXRob2Qgbm90IHN1cHBvcnRlZCIpOwotICAgIH0KLSAgICAvKioKLSAgICAgKiBBbiBhdHRyaWJ1dGUgc3BlY2lmeWluZywgYXMgcGFydCBvZiB0aGUgWE1MIGRlY2xhcmF0aW9uLCB3aGV0aGVyIHRoaXMKLSAgICAgKiBkb2N1bWVudCBpcyBzdGFuZGFsb25lLgotICAgICAqIDxicj4gVGhpcyBhdHRyaWJ1dGUgcmVwcmVzZW50cyB0aGUgcHJvcGVydHkgW3N0YW5kYWxvbmVdIGRlZmluZWQgaW4gLgotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFhtbFN0YW5kYWxvbmUoYm9vbGVhbiBzdGFuZGFsb25lKXsKLSAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIsICJNZXRob2Qgbm90IHN1cHBvcnRlZCIpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEFuIGF0dHJpYnV0ZSBzcGVjaWZ5aW5nLCBhcyBwYXJ0IG9mIHRoZSBYTUwgZGVjbGFyYXRpb24sIHRoZSB2ZXJzaW9uCi0gICAgICogbnVtYmVyIG9mIHRoaXMgZG9jdW1lbnQuIFRoaXMgaXMgPGNvZGU+bnVsbDwvY29kZT4gd2hlbiB1bnNwZWNpZmllZC4KLSAgICAgKiA8YnI+IFRoaXMgYXR0cmlidXRlIHJlcHJlc2VudHMgdGhlIHByb3BlcnR5IFt2ZXJzaW9uXSBkZWZpbmVkIGluIC4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgTk9UX1NVUFBPUlRFRF9FUlI6IFJhaXNlZCBpZiB0aGUgdmVyc2lvbiBpcyBzZXQgdG8gYSB2YWx1ZSB0aGF0IGlzCi0gICAgICogICBub3Qgc3VwcG9ydGVkIGJ5IHRoaXMgPGNvZGU+RG9jdW1lbnQ8L2NvZGU+LgotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0WG1sVmVyc2lvbigpewotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0gICAgLyoqCi0gICAgICogQW4gYXR0cmlidXRlIHNwZWNpZnlpbmcsIGFzIHBhcnQgb2YgdGhlIFhNTCBkZWNsYXJhdGlvbiwgdGhlIHZlcnNpb24KLSAgICAgKiBudW1iZXIgb2YgdGhpcyBkb2N1bWVudC4gVGhpcyBpcyA8Y29kZT5udWxsPC9jb2RlPiB3aGVuIHVuc3BlY2lmaWVkLgotICAgICAqIDxicj4gVGhpcyBhdHRyaWJ1dGUgcmVwcmVzZW50cyB0aGUgcHJvcGVydHkgW3ZlcnNpb25dIGRlZmluZWQgaW4gLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBOT1RfU1VQUE9SVEVEX0VSUjogUmFpc2VkIGlmIHRoZSB2ZXJzaW9uIGlzIHNldCB0byBhIHZhbHVlIHRoYXQgaXMKLSAgICAgKiAgIG5vdCBzdXBwb3J0ZWQgYnkgdGhpcyA8Y29kZT5Eb2N1bWVudDwvY29kZT4uCi0gICAgICogQHNpbmNlIERPTSBMZXZlbCAzCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0WG1sVmVyc2lvbihTdHJpbmcgdmVyc2lvbikgdGhyb3dzIERPTUV4Y2VwdGlvbnsKLSAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIsICJNZXRob2Qgbm90IHN1cHBvcnRlZCIpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEFuIGF0dHJpYnV0ZSBzcGVjaWZ5aW5nIHdoZXRoZXIgZXJyb3JzIGNoZWNraW5nIGlzIGVuZm9yY2VkIG9yIG5vdC4KLSAgICAgKiBXaGVuIHNldCB0byA8Y29kZT5mYWxzZTwvY29kZT4sIHRoZSBpbXBsZW1lbnRhdGlvbiBpcyBmcmVlIHRvIG5vdAotICAgICAqIHRlc3QgZXZlcnkgcG9zc2libGUgZXJyb3IgY2FzZSBub3JtYWxseSBkZWZpbmVkIG9uIERPTSBvcGVyYXRpb25zLAotICAgICAqIGFuZCBub3QgcmFpc2UgYW55IDxjb2RlPkRPTUV4Y2VwdGlvbjwvY29kZT4uIEluIGNhc2Ugb2YgZXJyb3IsIHRoZQotICAgICAqIGJlaGF2aW9yIGlzIHVuZGVmaW5lZC4gVGhpcyBhdHRyaWJ1dGUgaXMgPGNvZGU+dHJ1ZTwvY29kZT4gYnkKLSAgICAgKiBkZWZhdWx0cy4KLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXRTdHJpY3RFcnJvckNoZWNraW5nKCl7Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0gICAgLyoqCi0gICAgICogQW4gYXR0cmlidXRlIHNwZWNpZnlpbmcgd2hldGhlciBlcnJvcnMgY2hlY2tpbmcgaXMgZW5mb3JjZWQgb3Igbm90LgotICAgICAqIFdoZW4gc2V0IHRvIDxjb2RlPmZhbHNlPC9jb2RlPiwgdGhlIGltcGxlbWVudGF0aW9uIGlzIGZyZWUgdG8gbm90Ci0gICAgICogdGVzdCBldmVyeSBwb3NzaWJsZSBlcnJvciBjYXNlIG5vcm1hbGx5IGRlZmluZWQgb24gRE9NIG9wZXJhdGlvbnMsCi0gICAgICogYW5kIG5vdCByYWlzZSBhbnkgPGNvZGU+RE9NRXhjZXB0aW9uPC9jb2RlPi4gSW4gY2FzZSBvZiBlcnJvciwgdGhlCi0gICAgICogYmVoYXZpb3IgaXMgdW5kZWZpbmVkLiBUaGlzIGF0dHJpYnV0ZSBpcyA8Y29kZT50cnVlPC9jb2RlPiBieQotICAgICAqIGRlZmF1bHRzLgotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFN0cmljdEVycm9yQ2hlY2tpbmcoYm9vbGVhbiBzdHJpY3RFcnJvckNoZWNraW5nKXsKLSAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIsICJNZXRob2Qgbm90IHN1cHBvcnRlZCIpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoZSBsb2NhdGlvbiBvZiB0aGUgZG9jdW1lbnQgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdW5kZWZpbmVkLgotICAgICAqIDxicj5CZXdhcmUgdGhhdCB3aGVuIHRoZSA8Y29kZT5Eb2N1bWVudDwvY29kZT4gc3VwcG9ydHMgdGhlIGZlYXR1cmUKLSAgICAgKiAiSFRNTCIgLCB0aGUgaHJlZiBhdHRyaWJ1dGUgb2YgdGhlIEhUTUwgQkFTRSBlbGVtZW50IHRha2VzIHByZWNlZGVuY2UKLSAgICAgKiBvdmVyIHRoaXMgYXR0cmlidXRlLgotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0RG9jdW1lbnRVUkkoKSB7Ci0gICAgICAgIHJldHVybiBmRG9jdW1lbnRVUkk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhlIGxvY2F0aW9uIG9mIHRoZSBkb2N1bWVudCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiB1bmRlZmluZWQuCi0gICAgICogPGJyPkJld2FyZSB0aGF0IHdoZW4gdGhlIDxjb2RlPkRvY3VtZW50PC9jb2RlPiBzdXBwb3J0cyB0aGUgZmVhdHVyZQotICAgICAqICJIVE1MIiAsIHRoZSBocmVmIGF0dHJpYnV0ZSBvZiB0aGUgSFRNTCBCQVNFIGVsZW1lbnQgdGFrZXMgcHJlY2VkZW5jZQotICAgICAqIG92ZXIgdGhpcyBhdHRyaWJ1dGUuCi0gICAgICogQHNpbmNlIERPTSBMZXZlbCAzCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RG9jdW1lbnRVUkkoU3RyaW5nIGRvY3VtZW50VVJJKSB7Ci0gICAgICAgIGZEb2N1bWVudFVSSSA9IGRvY3VtZW50VVJJOwotICAgIH0KLQotICAgIC8qKiBET00gTGV2ZWwgMyovCi0gICAgcHVibGljIE5vZGUgYWRvcHROb2RlKE5vZGUgc291cmNlKSB0aHJvd3MgRE9NRXhjZXB0aW9uewotICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUiwgIk1ldGhvZCBub3Qgc3VwcG9ydGVkIik7Ci0gICAgfQotCi0gICAgLyoqIERPTSBMZXZlbCAzKi8KLSAgICBwdWJsaWMgdm9pZCBub3JtYWxpemVEb2N1bWVudCgpewotICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUiwgIk1ldGhvZCBub3Qgc3VwcG9ydGVkIik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogIFRoZSBjb25maWd1cmF0aW9uIHVzZWQgd2hlbiA8Y29kZT5Eb2N1bWVudC5ub3JtYWxpemVEb2N1bWVudDwvY29kZT4gaXMKLSAgICAgKiBpbnZva2VkLgotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgICAqLwotICAgIHB1YmxpYyBET01Db25maWd1cmF0aW9uIGdldERvbUNvbmZpZygpewotICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUiwgIk1ldGhvZCBub3Qgc3VwcG9ydGVkIik7Ci0gICAgfQotCi0gICAgLyoqIERPTSBMZXZlbCAzKi8KLSAgICBwdWJsaWMgTm9kZSByZW5hbWVOb2RlKE5vZGUgbixTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgbmFtZSkgdGhyb3dzIERPTUV4Y2VwdGlvbnsKLSAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIsICJNZXRob2Qgbm90IHN1cHBvcnRlZCIpOwotICAgIH0KLQotCi0KLQotCi0KLQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL29wdGkvRGVmYXVsdEVsZW1lbnQuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvb3B0aS9EZWZhdWx0RWxlbWVudC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjNGRiNmQ4Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvb3B0aS9EZWZhdWx0RWxlbWVudC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTUxICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEsIDIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLm9wdGk7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5UeXBlSW5mbzsKLWltcG9ydCBvcmcudzNjLmRvbS5BdHRyOwotaW1wb3J0IG9yZy53M2MuZG9tLkVsZW1lbnQ7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZUxpc3Q7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5ET01FeGNlcHRpb247Ci0KLQotLyoqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBSYWh1bCBTcml2YXN0YXZhLCBTdW4gTWljcm9zeXN0ZW1zIEluYy4KLSAqCi0gKi8KLXB1YmxpYyBjbGFzcyBEZWZhdWx0RWxlbWVudCBleHRlbmRzIE5vZGVJbXBsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW1wbGVtZW50cyBFbGVtZW50IHsKLQotICAgIC8vIGRlZmF1bHQgY29uc3RydWN0b3IKLSAgICBwdWJsaWMgRGVmYXVsdEVsZW1lbnQoKSB7Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgRGVmYXVsdEVsZW1lbnQoU3RyaW5nIHByZWZpeCwgU3RyaW5nIGxvY2FscGFydCwgU3RyaW5nIHJhd25hbWUsIFN0cmluZyB1cmksIHNob3J0IG5vZGVUeXBlKSB7Ci0gICAgICAgIHN1cGVyKHByZWZpeCwgbG9jYWxwYXJ0LCByYXduYW1lLCB1cmksIG5vZGVUeXBlKTsKLSAgICB9Ci0KLQotICAgIC8vCi0gICAgLy8gb3JnLnczYy5kb20uRWxlbWVudCBtZXRob2RzCi0gICAgLy8KLQotICAgIC8vIGdldHRlciBtZXRob2RzCi0gICAgcHVibGljIFN0cmluZyBnZXRUYWdOYW1lKCkgewotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0QXR0cmlidXRlKFN0cmluZyBuYW1lKSB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotCi0gICAgcHVibGljIEF0dHIgZ2V0QXR0cmlidXRlTm9kZShTdHJpbmcgbmFtZSkgewotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLQotICAgIHB1YmxpYyBOb2RlTGlzdCBnZXRFbGVtZW50c0J5VGFnTmFtZShTdHJpbmcgbmFtZSkgewotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0QXR0cmlidXRlTlMoU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIGxvY2FsTmFtZSkgewotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLQotICAgIHB1YmxpYyBBdHRyIGdldEF0dHJpYnV0ZU5vZGVOUyhTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgbG9jYWxOYW1lKSB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotCi0gICAgcHVibGljIE5vZGVMaXN0IGdldEVsZW1lbnRzQnlUYWdOYW1lTlMoU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIGxvY2FsTmFtZSkgewotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLQotICAgIHB1YmxpYyBib29sZWFuIGhhc0F0dHJpYnV0ZShTdHJpbmcgbmFtZSkgewotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgYm9vbGVhbiBoYXNBdHRyaWJ1dGVOUyhTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgbG9jYWxOYW1lKSB7Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgVHlwZUluZm8gZ2V0U2NoZW1hVHlwZUluZm8oKXsKLSAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotCi0gICAgLy8gc2V0dGVyIG1ldGhvZHMKLSAgICBwdWJsaWMgdm9pZCBzZXRBdHRyaWJ1dGUoU3RyaW5nIG5hbWUsIFN0cmluZyB2YWx1ZSkgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0gICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSLCAiTWV0aG9kIG5vdCBzdXBwb3J0ZWQiKTsKLSAgICB9Ci0KLQotICAgIHB1YmxpYyB2b2lkIHJlbW92ZUF0dHJpYnV0ZShTdHJpbmcgbmFtZSkgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0gICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSLCAiTWV0aG9kIG5vdCBzdXBwb3J0ZWQiKTsKLSAgICB9Ci0KLQotICAgIHB1YmxpYyBBdHRyIHJlbW92ZUF0dHJpYnV0ZU5vZGUoQXR0ciBvbGRBdHRyKSB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKLSAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIsICJNZXRob2Qgbm90IHN1cHBvcnRlZCIpOwotICAgIH0KLQotCi0gICAgcHVibGljIEF0dHIgc2V0QXR0cmlidXRlTm9kZShBdHRyIG5ld0F0dHIpIHRocm93cyBET01FeGNlcHRpb24gewotICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUiwgIk1ldGhvZCBub3Qgc3VwcG9ydGVkIik7Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgdm9pZCBzZXRBdHRyaWJ1dGVOUyhTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgcXVhbGlmaWVkTmFtZSwgU3RyaW5nIHZhbHVlKSB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKLSAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIsICJNZXRob2Qgbm90IHN1cHBvcnRlZCIpOwotICAgIH0KLQotCi0gICAgcHVibGljIHZvaWQgcmVtb3ZlQXR0cmlidXRlTlMoU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIGxvY2FsTmFtZSkgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0gICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSLCAiTWV0aG9kIG5vdCBzdXBwb3J0ZWQiKTsKLSAgICB9Ci0KLQotICAgIHB1YmxpYyBBdHRyIHNldEF0dHJpYnV0ZU5vZGVOUyhBdHRyIG5ld0F0dHIpIHRocm93cyBET01FeGNlcHRpb24gewotICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUiwgIk1ldGhvZCBub3Qgc3VwcG9ydGVkIik7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0SWRBdHRyaWJ1dGVOb2RlKEF0dHIgYXQsIGJvb2xlYW4gbWFrZUlkKSB0aHJvd3MgRE9NRXhjZXB0aW9uewotICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUiwgIk1ldGhvZCBub3Qgc3VwcG9ydGVkIik7Ci0gICAgfQotICAgIHB1YmxpYyB2b2lkIHNldElkQXR0cmlidXRlKFN0cmluZyBuYW1lLCBib29sZWFuIG1ha2VJZCkgdGhyb3dzIERPTUV4Y2VwdGlvbnsKLSAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIsICJNZXRob2Qgbm90IHN1cHBvcnRlZCIpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldElkQXR0cmlidXRlTlMoU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIGxvY2FsTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gbWFrZUlkKSB0aHJvd3MgRE9NRXhjZXB0aW9uewotICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUiwgIk1ldGhvZCBub3Qgc3VwcG9ydGVkIik7Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL29wdGkvRGVmYXVsdE5vZGUuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvb3B0aS9EZWZhdWx0Tm9kZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxNTA5NjYzLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvb3B0aS9EZWZhdWx0Tm9kZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjE4ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEsIDIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLm9wdGk7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5Vc2VyRGF0YUhhbmRsZXI7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlTGlzdDsKLWltcG9ydCBvcmcudzNjLmRvbS5OYW1lZE5vZGVNYXA7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5ET01FeGNlcHRpb247Ci0KLQotLyoqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBSYWh1bCBTcml2YXN0YXZhLCBTdW4gTWljcm9zeXN0ZW1zIEluYy4KLSAqCi0gKi8KLXB1YmxpYyBjbGFzcyBEZWZhdWx0Tm9kZSBpbXBsZW1lbnRzIE5vZGUgewotCi0gICAgLy8gZGVmYXVsdCBjb25zdHJ1Y3RvcgotICAgIHB1YmxpYyBEZWZhdWx0Tm9kZSgpIHsKLSAgICB9Ci0KLSAgICAvLwotICAgIC8vIG9yZy53M2MuZG9tLk5vZGUgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvLyBnZXR0ZXIgbWV0aG9kcwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Tm9kZU5hbWUoKSB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotCi0gICAgcHVibGljIFN0cmluZyBnZXROb2RlVmFsdWUoKSB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgc2hvcnQgZ2V0Tm9kZVR5cGUoKSB7Ci0gICAgICAgIHJldHVybiAtMTsKLSAgICB9Ci0KLQotICAgIHB1YmxpYyBOb2RlIGdldFBhcmVudE5vZGUoKSB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotCi0gICAgcHVibGljIE5vZGVMaXN0IGdldENoaWxkTm9kZXMoKSB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotCi0gICAgcHVibGljIE5vZGUgZ2V0Rmlyc3RDaGlsZCgpIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgTm9kZSBnZXRMYXN0Q2hpbGQoKSB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotCi0gICAgcHVibGljIE5vZGUgZ2V0UHJldmlvdXNTaWJsaW5nKCkgewotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLQotICAgIHB1YmxpYyBOb2RlIGdldE5leHRTaWJsaW5nKCkgewotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLQotICAgIHB1YmxpYyBOYW1lZE5vZGVNYXAgZ2V0QXR0cmlidXRlcygpIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgRG9jdW1lbnQgZ2V0T3duZXJEb2N1bWVudCgpIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgYm9vbGVhbiBoYXNDaGlsZE5vZGVzKCkgewotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgTm9kZSBjbG9uZU5vZGUoYm9vbGVhbiBkZWVwKSB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotCi0gICAgcHVibGljIHZvaWQgbm9ybWFsaXplKCkgewotICAgIH0KLQotCi0gICAgcHVibGljIGJvb2xlYW4gaXNTdXBwb3J0ZWQoU3RyaW5nIGZlYXR1cmUsIFN0cmluZyB2ZXJzaW9uKSB7Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZXNwYWNlVVJJKCkgewotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0UHJlZml4KCkgewotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TG9jYWxOYW1lKCkgewotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0gICAgLyoqIERPTSBMZXZlbCAzKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEJhc2VVUkkoKXsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0KLQotICAgIHB1YmxpYyBib29sZWFuIGhhc0F0dHJpYnV0ZXMoKSB7Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICAvLyBzZXR0ZXIgbWV0aG9kcwotICAgIHB1YmxpYyB2b2lkIHNldE5vZGVWYWx1ZShTdHJpbmcgbm9kZVZhbHVlKSB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKLSAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIsICJNZXRob2Qgbm90IHN1cHBvcnRlZCIpOwotICAgIH0KLQotCi0gICAgcHVibGljIE5vZGUgaW5zZXJ0QmVmb3JlKE5vZGUgbmV3Q2hpbGQsIE5vZGUgcmVmQ2hpbGQpIHRocm93cyBET01FeGNlcHRpb24gewotICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUiwgIk1ldGhvZCBub3Qgc3VwcG9ydGVkIik7Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgTm9kZSByZXBsYWNlQ2hpbGQoTm9kZSBuZXdDaGlsZCwgTm9kZSBvbGRDaGlsZCkgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0gICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSLCAiTWV0aG9kIG5vdCBzdXBwb3J0ZWQiKTsKLSAgICB9Ci0KLQotICAgIHB1YmxpYyBOb2RlIHJlbW92ZUNoaWxkKE5vZGUgb2xkQ2hpbGQpIHRocm93cyBET01FeGNlcHRpb24gewotICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUiwgIk1ldGhvZCBub3Qgc3VwcG9ydGVkIik7Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgTm9kZSBhcHBlbmRDaGlsZChOb2RlIG5ld0NoaWxkKSB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKLSAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIsICJNZXRob2Qgbm90IHN1cHBvcnRlZCIpOwotICAgIH0KLQotCi0gICAgcHVibGljIHZvaWQgc2V0UHJlZml4KFN0cmluZyBwcmVmaXgpIHRocm93cyBET01FeGNlcHRpb24gewotICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUiwgIk1ldGhvZCBub3Qgc3VwcG9ydGVkIik7Ci0gICAgfQotCi0gICAgcHVibGljIHNob3J0IGNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKE5vZGUgb3RoZXIpewotICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUiwgIk1ldGhvZCBub3Qgc3VwcG9ydGVkIik7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRUZXh0Q29udGVudCgpIHRocm93cyBET01FeGNlcHRpb257Ci0gICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSLCAiTWV0aG9kIG5vdCBzdXBwb3J0ZWQiKTsKLSAgICB9Ci0gICAgcHVibGljIHZvaWQgc2V0VGV4dENvbnRlbnQoU3RyaW5nIHRleHRDb250ZW50KXRocm93cyBET01FeGNlcHRpb257Ci0gICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSLCAiTWV0aG9kIG5vdCBzdXBwb3J0ZWQiKTsKLSAgICB9Ci0gICAgcHVibGljIGJvb2xlYW4gaXNTYW1lTm9kZShOb2RlIG90aGVyKXsKLSAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIsICJNZXRob2Qgbm90IHN1cHBvcnRlZCIpOwotCi0gICAgfQotICAgIHB1YmxpYyBTdHJpbmcgbG9va3VwUHJlZml4KFN0cmluZyBuYW1lc3BhY2VVUkkpewotICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUiwgIk1ldGhvZCBub3Qgc3VwcG9ydGVkIik7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgIHB1YmxpYyBib29sZWFuIGlzRGVmYXVsdE5hbWVzcGFjZShTdHJpbmcgbmFtZXNwYWNlVVJJKXsKLSAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIsICJNZXRob2Qgbm90IHN1cHBvcnRlZCIpOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgbG9va3VwTmFtZXNwYWNlVVJJKFN0cmluZyBwcmVmaXgpewotICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUiwgIk1ldGhvZCBub3Qgc3VwcG9ydGVkIik7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gaXNFcXVhbE5vZGUoTm9kZSBhcmcpewotICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSLCAiTWV0aG9kIG5vdCBzdXBwb3J0ZWQiKTsKLQotICAgIH0KLQotICAgIHB1YmxpYyBPYmplY3QgZ2V0RmVhdHVyZShTdHJpbmcgZmVhdHVyZSwgU3RyaW5nIHZlcnNpb24pewotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0gICAgcHVibGljIE9iamVjdCBzZXRVc2VyRGF0YShTdHJpbmcga2V5LCAgT2JqZWN0IGRhdGEsIFVzZXJEYXRhSGFuZGxlciBoYW5kbGVyKXsKLSAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUiwgIk1ldGhvZCBub3Qgc3VwcG9ydGVkIik7Ci0gICAgfQotICAgIHB1YmxpYyBPYmplY3QgZ2V0VXNlckRhdGEoU3RyaW5nIGtleSl7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL29wdGkvRGVmYXVsdFRleHQuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvb3B0aS9EZWZhdWx0VGV4dC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0Zjc1MGIxLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvb3B0aS9EZWZhdWx0VGV4dC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjM4ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLm9wdGk7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5UZXh0OwotaW1wb3J0IG9yZy53M2MuZG9tLkRPTUV4Y2VwdGlvbjsKLQotLyoKLSAqIEBhdXRob3IgTmVpbCBHcmFoYW0sIElCTQotICovCi0vKioKLSAqIFRoZSA8Y29kZT5UZXh0PC9jb2RlPiBpbnRlcmZhY2UgaW5oZXJpdHMgZnJvbSA8Y29kZT5DaGFyYWN0ZXJEYXRhPC9jb2RlPgotICogYW5kIHJlcHJlc2VudHMgdGhlIHRleHR1YWwgY29udGVudCAodGVybWVkIGNoYXJhY3RlciBkYXRhIGluIFhNTCkgb2YgYW4KLSAqIDxjb2RlPkVsZW1lbnQ8L2NvZGU+IG9yIDxjb2RlPkF0dHI8L2NvZGU+LiBJZiB0aGVyZSBpcyBubyBtYXJrdXAgaW5zaWRlCi0gKiBhbiBlbGVtZW50J3MgY29udGVudCwgdGhlIHRleHQgaXMgY29udGFpbmVkIGluIGEgc2luZ2xlIG9iamVjdAotICogaW1wbGVtZW50aW5nIHRoZSA8Y29kZT5UZXh0PC9jb2RlPiBpbnRlcmZhY2UgdGhhdCBpcyB0aGUgb25seSBjaGlsZCBvZgotICogdGhlIGVsZW1lbnQuIElmIHRoZXJlIGlzIG1hcmt1cCwgaXQgaXMgcGFyc2VkIGludG8gdGhlIGluZm9ybWF0aW9uIGl0ZW1zCi0gKiAoZWxlbWVudHMsIGNvbW1lbnRzLCBldGMuKSBhbmQgPGNvZGU+VGV4dDwvY29kZT4gbm9kZXMgdGhhdCBmb3JtIHRoZSBsaXN0Ci0gKiBvZiBjaGlsZHJlbiBvZiB0aGUgZWxlbWVudC4KLSAqIDxwPldoZW4gYSBkb2N1bWVudCBpcyBmaXJzdCBtYWRlIGF2YWlsYWJsZSB2aWEgdGhlIERPTSwgdGhlcmUgaXMgb25seSBvbmUKLSAqIDxjb2RlPlRleHQ8L2NvZGU+IG5vZGUgZm9yIGVhY2ggYmxvY2sgb2YgdGV4dC4gVXNlcnMgbWF5IGNyZWF0ZSBhZGphY2VudAotICogPGNvZGU+VGV4dDwvY29kZT4gbm9kZXMgdGhhdCByZXByZXNlbnQgdGhlIGNvbnRlbnRzIG9mIGEgZ2l2ZW4gZWxlbWVudAotICogd2l0aG91dCBhbnkgaW50ZXJ2ZW5pbmcgbWFya3VwLCBidXQgc2hvdWxkIGJlIGF3YXJlIHRoYXQgdGhlcmUgaXMgbm8gd2F5Ci0gKiB0byByZXByZXNlbnQgdGhlIHNlcGFyYXRpb25zIGJldHdlZW4gdGhlc2Ugbm9kZXMgaW4gWE1MIG9yIEhUTUwsIHNvIHRoZXkKLSAqIHdpbGwgbm90IChpbiBnZW5lcmFsKSBwZXJzaXN0IGJldHdlZW4gRE9NIGVkaXRpbmcgc2Vzc2lvbnMuIFRoZQotICogPGNvZGU+bm9ybWFsaXplKCk8L2NvZGU+IG1ldGhvZCBvbiA8Y29kZT5Ob2RlPC9jb2RlPiBtZXJnZXMgYW55IHN1Y2gKLSAqIGFkamFjZW50IDxjb2RlPlRleHQ8L2NvZGU+IG9iamVjdHMgaW50byBhIHNpbmdsZSBub2RlIGZvciBlYWNoIGJsb2NrIG9mCi0gKiB0ZXh0LgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDAvUkVDLURPTS1MZXZlbC0yLUNvcmUtMjAwMDExMTMnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAyIENvcmUgU3BlY2lmaWNhdGlvbjwvYT4uCi0gKgotICogVGhpcyBpcyBhbiBlbXB0eSBpbXBsZW1lbnRhdGlvbi4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKi8KLXB1YmxpYyBjbGFzcyBEZWZhdWx0VGV4dCBleHRlbmRzIE5vZGVJbXBsIGltcGxlbWVudHMgVGV4dCB7Ci0KLSAgICAvLyBDaGFyYWN0ZXJEYXRhIG1ldGhvZHMKLQotICAgIC8qKgotICAgICAqIFRoZSBjaGFyYWN0ZXIgZGF0YSBvZiB0aGUgbm9kZSB0aGF0IGltcGxlbWVudHMgdGhpcyBpbnRlcmZhY2UuIFRoZSBET00KLSAgICAgKiBpbXBsZW1lbnRhdGlvbiBtYXkgbm90IHB1dCBhcmJpdHJhcnkgbGltaXRzIG9uIHRoZSBhbW91bnQgb2YgZGF0YQotICAgICAqIHRoYXQgbWF5IGJlIHN0b3JlZCBpbiBhIDxjb2RlPkNoYXJhY3RlckRhdGE8L2NvZGU+IG5vZGUuIEhvd2V2ZXIsCi0gICAgICogaW1wbGVtZW50YXRpb24gbGltaXRzIG1heSBtZWFuIHRoYXQgdGhlIGVudGlyZXR5IG9mIGEgbm9kZSdzIGRhdGEgbWF5Ci0gICAgICogbm90IGZpdCBpbnRvIGEgc2luZ2xlIDxjb2RlPkRPTVN0cmluZzwvY29kZT4uIEluIHN1Y2ggY2FzZXMsIHRoZSB1c2VyCi0gICAgICogbWF5IGNhbGwgPGNvZGU+c3Vic3RyaW5nRGF0YTwvY29kZT4gdG8gcmV0cmlldmUgdGhlIGRhdGEgaW4KLSAgICAgKiBhcHByb3ByaWF0ZWx5IHNpemVkIHBpZWNlcy4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgd2hlbiB0aGUgbm9kZSBpcyByZWFkb25seS4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgRE9NU1RSSU5HX1NJWkVfRVJSOiBSYWlzZWQgd2hlbiBpdCB3b3VsZCByZXR1cm4gbW9yZSBjaGFyYWN0ZXJzIHRoYW4KLSAgICAgKiAgIGZpdCBpbiBhIDxjb2RlPkRPTVN0cmluZzwvY29kZT4gdmFyaWFibGUgb24gdGhlIGltcGxlbWVudGF0aW9uCi0gICAgICogICBwbGF0Zm9ybS4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldERhdGEoKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb24gewotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgY2hhcmFjdGVyIGRhdGEgb2YgdGhlIG5vZGUgdGhhdCBpbXBsZW1lbnRzIHRoaXMgaW50ZXJmYWNlLiBUaGUgRE9NCi0gICAgICogaW1wbGVtZW50YXRpb24gbWF5IG5vdCBwdXQgYXJiaXRyYXJ5IGxpbWl0cyBvbiB0aGUgYW1vdW50IG9mIGRhdGEKLSAgICAgKiB0aGF0IG1heSBiZSBzdG9yZWQgaW4gYSA8Y29kZT5DaGFyYWN0ZXJEYXRhPC9jb2RlPiBub2RlLiBIb3dldmVyLAotICAgICAqIGltcGxlbWVudGF0aW9uIGxpbWl0cyBtYXkgbWVhbiB0aGF0IHRoZSBlbnRpcmV0eSBvZiBhIG5vZGUncyBkYXRhIG1heQotICAgICAqIG5vdCBmaXQgaW50byBhIHNpbmdsZSA8Y29kZT5ET01TdHJpbmc8L2NvZGU+LiBJbiBzdWNoIGNhc2VzLCB0aGUgdXNlcgotICAgICAqIG1heSBjYWxsIDxjb2RlPnN1YnN0cmluZ0RhdGE8L2NvZGU+IHRvIHJldHJpZXZlIHRoZSBkYXRhIGluCi0gICAgICogYXBwcm9wcmlhdGVseSBzaXplZCBwaWVjZXMuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIHdoZW4gdGhlIG5vZGUgaXMgcmVhZG9ubHkuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIERPTVNUUklOR19TSVpFX0VSUjogUmFpc2VkIHdoZW4gaXQgd291bGQgcmV0dXJuIG1vcmUgY2hhcmFjdGVycyB0aGFuCi0gICAgICogICBmaXQgaW4gYSA8Y29kZT5ET01TdHJpbmc8L2NvZGU+IHZhcmlhYmxlIG9uIHRoZSBpbXBsZW1lbnRhdGlvbgotICAgICAqICAgcGxhdGZvcm0uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RGF0YShTdHJpbmcgZGF0YSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKLSAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIsICJNZXRob2Qgbm90IHN1cHBvcnRlZCIpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoZSBudW1iZXIgb2YgMTYtYml0IHVuaXRzIHRoYXQgYXJlIGF2YWlsYWJsZSB0aHJvdWdoIDxjb2RlPmRhdGE8L2NvZGU+Ci0gICAgICogYW5kIHRoZSA8Y29kZT5zdWJzdHJpbmdEYXRhPC9jb2RlPiBtZXRob2QgYmVsb3cuIFRoaXMgbWF5IGhhdmUgdGhlCi0gICAgICogdmFsdWUgemVybywgaS5lLiwgPGNvZGU+Q2hhcmFjdGVyRGF0YTwvY29kZT4gbm9kZXMgbWF5IGJlIGVtcHR5LgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0TGVuZ3RoKCkgewotICAgICAgICByZXR1cm4gMDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBFeHRyYWN0cyBhIHJhbmdlIG9mIGRhdGEgZnJvbSB0aGUgbm9kZS4KLSAgICAgKiBAcGFyYW0gb2Zmc2V0IFN0YXJ0IG9mZnNldCBvZiBzdWJzdHJpbmcgdG8gZXh0cmFjdC4KLSAgICAgKiBAcGFyYW0gY291bnQgVGhlIG51bWJlciBvZiAxNi1iaXQgdW5pdHMgdG8gZXh0cmFjdC4KLSAgICAgKiBAcmV0dXJuIFRoZSBzcGVjaWZpZWQgc3Vic3RyaW5nLiBJZiB0aGUgc3VtIG9mIDxjb2RlPm9mZnNldDwvY29kZT4gYW5kCi0gICAgICogICA8Y29kZT5jb3VudDwvY29kZT4gZXhjZWVkcyB0aGUgPGNvZGU+bGVuZ3RoPC9jb2RlPiwgdGhlbiBhbGwgMTYtYml0Ci0gICAgICogICB1bml0cyB0byB0aGUgZW5kIG9mIHRoZSBkYXRhIGFyZSByZXR1cm5lZC4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgSU5ERVhfU0laRV9FUlI6IFJhaXNlZCBpZiB0aGUgc3BlY2lmaWVkIDxjb2RlPm9mZnNldDwvY29kZT4gaXMKLSAgICAgKiAgIG5lZ2F0aXZlIG9yIGdyZWF0ZXIgdGhhbiB0aGUgbnVtYmVyIG9mIDE2LWJpdCB1bml0cyBpbgotICAgICAqICAgPGNvZGU+ZGF0YTwvY29kZT4sIG9yIGlmIHRoZSBzcGVjaWZpZWQgPGNvZGU+Y291bnQ8L2NvZGU+IGlzCi0gICAgICogICBuZWdhdGl2ZS4KLSAgICAgKiAgIDxicj5ET01TVFJJTkdfU0laRV9FUlI6IFJhaXNlZCBpZiB0aGUgc3BlY2lmaWVkIHJhbmdlIG9mIHRleHQgZG9lcwotICAgICAqICAgbm90IGZpdCBpbnRvIGEgPGNvZGU+RE9NU3RyaW5nPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIHN1YnN0cmluZ0RhdGEoaW50IG9mZnNldCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGNvdW50KQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKLSAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIsICJNZXRob2Qgbm90IHN1cHBvcnRlZCIpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEFwcGVuZCB0aGUgc3RyaW5nIHRvIHRoZSBlbmQgb2YgdGhlIGNoYXJhY3RlciBkYXRhIG9mIHRoZSBub2RlLiBVcG9uCi0gICAgICogc3VjY2VzcywgPGNvZGU+ZGF0YTwvY29kZT4gcHJvdmlkZXMgYWNjZXNzIHRvIHRoZSBjb25jYXRlbmF0aW9uIG9mCi0gICAgICogPGNvZGU+ZGF0YTwvY29kZT4gYW5kIHRoZSA8Y29kZT5ET01TdHJpbmc8L2NvZGU+IHNwZWNpZmllZC4KLSAgICAgKiBAcGFyYW0gYXJnIFRoZSA8Y29kZT5ET01TdHJpbmc8L2NvZGU+IHRvIGFwcGVuZC4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBub2RlIGlzIHJlYWRvbmx5LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGFwcGVuZERhdGEoU3RyaW5nIGFyZykKLSAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb24gewotICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUiwgIk1ldGhvZCBub3Qgc3VwcG9ydGVkIik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSW5zZXJ0IGEgc3RyaW5nIGF0IHRoZSBzcGVjaWZpZWQgMTYtYml0IHVuaXQgb2Zmc2V0LgotICAgICAqIEBwYXJhbSBvZmZzZXQgVGhlIGNoYXJhY3RlciBvZmZzZXQgYXQgd2hpY2ggdG8gaW5zZXJ0LgotICAgICAqIEBwYXJhbSBhcmcgVGhlIDxjb2RlPkRPTVN0cmluZzwvY29kZT4gdG8gaW5zZXJ0LgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBJTkRFWF9TSVpFX0VSUjogUmFpc2VkIGlmIHRoZSBzcGVjaWZpZWQgPGNvZGU+b2Zmc2V0PC9jb2RlPiBpcwotICAgICAqICAgbmVnYXRpdmUgb3IgZ3JlYXRlciB0aGFuIHRoZSBudW1iZXIgb2YgMTYtYml0IHVuaXRzIGluCi0gICAgICogICA8Y29kZT5kYXRhPC9jb2RlPi4KLSAgICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIG5vZGUgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgaW5zZXJ0RGF0YShpbnQgb2Zmc2V0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGFyZykKLSAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb24gewotICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUiwgIk1ldGhvZCBub3Qgc3VwcG9ydGVkIik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmVtb3ZlIGEgcmFuZ2Ugb2YgMTYtYml0IHVuaXRzIGZyb20gdGhlIG5vZGUuIFVwb24gc3VjY2VzcywKLSAgICAgKiA8Y29kZT5kYXRhPC9jb2RlPiBhbmQgPGNvZGU+bGVuZ3RoPC9jb2RlPiByZWZsZWN0IHRoZSBjaGFuZ2UuCi0gICAgICogQHBhcmFtIG9mZnNldCBUaGUgb2Zmc2V0IGZyb20gd2hpY2ggdG8gc3RhcnQgcmVtb3ZpbmcuCi0gICAgICogQHBhcmFtIGNvdW50IFRoZSBudW1iZXIgb2YgMTYtYml0IHVuaXRzIHRvIGRlbGV0ZS4gSWYgdGhlIHN1bSBvZgotICAgICAqICAgPGNvZGU+b2Zmc2V0PC9jb2RlPiBhbmQgPGNvZGU+Y291bnQ8L2NvZGU+IGV4Y2VlZHMKLSAgICAgKiAgIDxjb2RlPmxlbmd0aDwvY29kZT4gdGhlbiBhbGwgMTYtYml0IHVuaXRzIGZyb20gPGNvZGU+b2Zmc2V0PC9jb2RlPgotICAgICAqICAgdG8gdGhlIGVuZCBvZiB0aGUgZGF0YSBhcmUgZGVsZXRlZC4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgSU5ERVhfU0laRV9FUlI6IFJhaXNlZCBpZiB0aGUgc3BlY2lmaWVkIDxjb2RlPm9mZnNldDwvY29kZT4gaXMKLSAgICAgKiAgIG5lZ2F0aXZlIG9yIGdyZWF0ZXIgdGhhbiB0aGUgbnVtYmVyIG9mIDE2LWJpdCB1bml0cyBpbgotICAgICAqICAgPGNvZGU+ZGF0YTwvY29kZT4sIG9yIGlmIHRoZSBzcGVjaWZpZWQgPGNvZGU+Y291bnQ8L2NvZGU+IGlzCi0gICAgICogICBuZWdhdGl2ZS4KLSAgICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIG5vZGUgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZGVsZXRlRGF0YShpbnQgb2Zmc2V0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGNvdW50KQotICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0gICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSLCAiTWV0aG9kIG5vdCBzdXBwb3J0ZWQiKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXBsYWNlIHRoZSBjaGFyYWN0ZXJzIHN0YXJ0aW5nIGF0IHRoZSBzcGVjaWZpZWQgMTYtYml0IHVuaXQgb2Zmc2V0Ci0gICAgICogd2l0aCB0aGUgc3BlY2lmaWVkIHN0cmluZy4KLSAgICAgKiBAcGFyYW0gb2Zmc2V0IFRoZSBvZmZzZXQgZnJvbSB3aGljaCB0byBzdGFydCByZXBsYWNpbmcuCi0gICAgICogQHBhcmFtIGNvdW50IFRoZSBudW1iZXIgb2YgMTYtYml0IHVuaXRzIHRvIHJlcGxhY2UuIElmIHRoZSBzdW0gb2YKLSAgICAgKiAgIDxjb2RlPm9mZnNldDwvY29kZT4gYW5kIDxjb2RlPmNvdW50PC9jb2RlPiBleGNlZWRzCi0gICAgICogICA8Y29kZT5sZW5ndGg8L2NvZGU+LCB0aGVuIGFsbCAxNi1iaXQgdW5pdHMgdG8gdGhlIGVuZCBvZiB0aGUgZGF0YQotICAgICAqICAgYXJlIHJlcGxhY2VkOyAoaS5lLiwgdGhlIGVmZmVjdCBpcyB0aGUgc2FtZSBhcyBhIDxjb2RlPnJlbW92ZTwvY29kZT4KLSAgICAgKiAgICBtZXRob2QgY2FsbCB3aXRoIHRoZSBzYW1lIHJhbmdlLCBmb2xsb3dlZCBieSBhbiA8Y29kZT5hcHBlbmQ8L2NvZGU+Ci0gICAgICogICAgbWV0aG9kIGludm9jYXRpb24pLgotICAgICAqIEBwYXJhbSBhcmcgVGhlIDxjb2RlPkRPTVN0cmluZzwvY29kZT4gd2l0aCB3aGljaCB0aGUgcmFuZ2UgbXVzdCBiZQotICAgICAqICAgcmVwbGFjZWQuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIElOREVYX1NJWkVfRVJSOiBSYWlzZWQgaWYgdGhlIHNwZWNpZmllZCA8Y29kZT5vZmZzZXQ8L2NvZGU+IGlzCi0gICAgICogICBuZWdhdGl2ZSBvciBncmVhdGVyIHRoYW4gdGhlIG51bWJlciBvZiAxNi1iaXQgdW5pdHMgaW4KLSAgICAgKiAgIDxjb2RlPmRhdGE8L2NvZGU+LCBvciBpZiB0aGUgc3BlY2lmaWVkIDxjb2RlPmNvdW50PC9jb2RlPiBpcwotICAgICAqICAgbmVnYXRpdmUuCi0gICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBub2RlIGlzIHJlYWRvbmx5LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHJlcGxhY2VEYXRhKGludCBvZmZzZXQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGNvdW50LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBhcmcpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0gICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSLCAiTWV0aG9kIG5vdCBzdXBwb3J0ZWQiKTsKLSAgICB9Ci0KLSAgICAvLyBUZXh0IG5vZGUgbWV0aG9kcwotICAgIC8qKgotICAgICAqIEJyZWFrcyB0aGlzIG5vZGUgaW50byB0d28gbm9kZXMgYXQgdGhlIHNwZWNpZmllZCA8Y29kZT5vZmZzZXQ8L2NvZGU+LAotICAgICAqIGtlZXBpbmcgYm90aCBpbiB0aGUgdHJlZSBhcyBzaWJsaW5ncy4gQWZ0ZXIgYmVpbmcgc3BsaXQsIHRoaXMgbm9kZQotICAgICAqIHdpbGwgY29udGFpbiBhbGwgdGhlIGNvbnRlbnQgdXAgdG8gdGhlIDxjb2RlPm9mZnNldDwvY29kZT4gcG9pbnQuIEEKLSAgICAgKiBuZXcgbm9kZSBvZiB0aGUgc2FtZSB0eXBlLCB3aGljaCBjb250YWlucyBhbGwgdGhlIGNvbnRlbnQgYXQgYW5kCi0gICAgICogYWZ0ZXIgdGhlIDxjb2RlPm9mZnNldDwvY29kZT4gcG9pbnQsIGlzIHJldHVybmVkLiBJZiB0aGUgb3JpZ2luYWwKLSAgICAgKiBub2RlIGhhZCBhIHBhcmVudCBub2RlLCB0aGUgbmV3IG5vZGUgaXMgaW5zZXJ0ZWQgYXMgdGhlIG5leHQgc2libGluZwotICAgICAqIG9mIHRoZSBvcmlnaW5hbCBub2RlLiBXaGVuIHRoZSA8Y29kZT5vZmZzZXQ8L2NvZGU+IGlzIGVxdWFsIHRvIHRoZQotICAgICAqIGxlbmd0aCBvZiB0aGlzIG5vZGUsIHRoZSBuZXcgbm9kZSBoYXMgbm8gZGF0YS4KLSAgICAgKiBAcGFyYW0gb2Zmc2V0IFRoZSAxNi1iaXQgdW5pdCBvZmZzZXQgYXQgd2hpY2ggdG8gc3BsaXQsIHN0YXJ0aW5nIGZyb20KLSAgICAgKiAgIDxjb2RlPjA8L2NvZGU+LgotICAgICAqIEByZXR1cm4gVGhlIG5ldyBub2RlLCBvZiB0aGUgc2FtZSB0eXBlIGFzIHRoaXMgbm9kZS4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgSU5ERVhfU0laRV9FUlI6IFJhaXNlZCBpZiB0aGUgc3BlY2lmaWVkIG9mZnNldCBpcyBuZWdhdGl2ZSBvciBncmVhdGVyCi0gICAgICogICB0aGFuIHRoZSBudW1iZXIgb2YgMTYtYml0IHVuaXRzIGluIDxjb2RlPmRhdGE8L2NvZGU+LgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgbm9kZSBpcyByZWFkb25seS4KLSAgICAgKi8KLSAgICBwdWJsaWMgVGV4dCBzcGxpdFRleHQoaW50IG9mZnNldCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0gICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSLCAiTWV0aG9kIG5vdCBzdXBwb3J0ZWQiKTsKLSAgICB9Ci0KLSAgICAvKiogRE9NIExldmVsIDMgQ1IgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0VsZW1lbnRDb250ZW50V2hpdGVzcGFjZSgpewotICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUiwgIk1ldGhvZCBub3Qgc3VwcG9ydGVkIik7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRXaG9sZVRleHQoKXsKLSAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIsICJNZXRob2Qgbm90IHN1cHBvcnRlZCIpOwotICAgIH0KLQotICAgIHB1YmxpYyBUZXh0IHJlcGxhY2VXaG9sZVRleHQoU3RyaW5nIGNvbnRlbnQpIHRocm93cyBET01FeGNlcHRpb24gewotICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUiwgIk1ldGhvZCBub3Qgc3VwcG9ydGVkIik7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9vcHRpL0RlZmF1bHRYTUxEb2N1bWVudEhhbmRsZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvb3B0aS9EZWZhdWx0WE1MRG9jdW1lbnRIYW5kbGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGRkMGFjOWIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9vcHRpL0RlZmF1bHRYTUxEb2N1bWVudEhhbmRsZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDg3MSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLCAyMDAyLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5vcHRpOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuUU5hbWU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MU3RyaW5nOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLk5hbWVzcGFjZUNvbnRleHQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MTG9jYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5BdWdtZW50YXRpb25zOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTEF0dHJpYnV0ZXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MRFRESGFuZGxlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxEb2N1bWVudEhhbmRsZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MRFREQ29udGVudE1vZGVsSGFuZGxlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxSZXNvdXJjZUlkZW50aWZpZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTERvY3VtZW50U291cmNlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxEVERTb3VyY2U7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTERURENvbnRlbnRNb2RlbFNvdXJjZTsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhOSUV4Y2VwdGlvbjsKLQotLyoqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBSYWh1bCBTcml2YXN0YXZhLCBTdW4gTWljcm9zeXN0ZW1zIEluYy4KLSAqIEBhdXRob3IgU2FuZHkgR2FvLCBJQk0KLSAqCi0gKi8KLXB1YmxpYyBjbGFzcyBEZWZhdWx0WE1MRG9jdW1lbnRIYW5kbGVyIGltcGxlbWVudHMgWE1MRG9jdW1lbnRIYW5kbGVyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxEVERIYW5kbGVyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxEVERDb250ZW50TW9kZWxIYW5kbGVyIHsKLQotICAgIC8qKiBEZWZhdWx0IENvbnN0cnVjdG9yICovCi0gICAgcHVibGljIERlZmF1bHRYTUxEb2N1bWVudEhhbmRsZXIoKSB7Ci0gICAgfQotCi0gICAgLy8KLSAgICAvLyBYTUxEb2N1bWVudEhhbmRsZXIgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBUaGUgc3RhcnQgb2YgdGhlIGRvY3VtZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIGxvY2F0b3IgIFRoZSBkb2N1bWVudCBsb2NhdG9yLCBvciBudWxsIGlmIHRoZSBkb2N1bWVudAotICAgICAqICAgICAgICAgICAgICAgICBsb2NhdGlvbiBjYW5ub3QgYmUgcmVwb3J0ZWQgZHVyaW5nIHRoZSBwYXJzaW5nCi0gICAgICogICAgICAgICAgICAgICAgIG9mIHRoaXMgZG9jdW1lbnQuIEhvd2V2ZXIsIGl0IGlzIDxlbT5zdHJvbmdseTwvZW0+Ci0gICAgICogICAgICAgICAgICAgICAgIHJlY29tbWVuZGVkIHRoYXQgYSBsb2NhdG9yIGJlIHN1cHBsaWVkIHRoYXQgY2FuCi0gICAgICogICAgICAgICAgICAgICAgIGF0IGxlYXN0IHJlcG9ydCB0aGUgc3lzdGVtIGlkZW50aWZpZXIgb2YgdGhlCi0gICAgICogICAgICAgICAgICAgICAgIGRvY3VtZW50LgotICAgICAqIEBwYXJhbSBlbmNvZGluZyBUaGUgYXV0by1kZXRlY3RlZCBJQU5BIGVuY29kaW5nIG5hbWUgb2YgdGhlIGVudGl0eQotICAgICAqICAgICAgICAgICAgICAgICBzdHJlYW0uIFRoaXMgdmFsdWUgd2lsbCBiZSBudWxsIGluIHRob3NlIHNpdHVhdGlvbnMKLSAgICAgKiAgICAgICAgICAgICAgICAgd2hlcmUgdGhlIGVudGl0eSBlbmNvZGluZyBpcyBub3QgYXV0by1kZXRlY3RlZCAoZS5nLgotICAgICAqICAgICAgICAgICAgICAgICBpbnRlcm5hbCBlbnRpdGllcyBvciBhIGRvY3VtZW50IGVudGl0eSB0aGF0IGlzCi0gICAgICogICAgICAgICAgICAgICAgIHBhcnNlZCBmcm9tIGEgamF2YS5pby5SZWFkZXIpLgotICAgICAqIEBwYXJhbSBhdWdzICAgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICogQGV4Y2VwdGlvbiBYTklFeGNlcHRpb24KLSAgICAgKiAgICAgICAgICAgICAgICAgICBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnREb2N1bWVudChYTUxMb2NhdG9yIGxvY2F0b3IsIFN0cmluZyBlbmNvZGluZywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5hbWVzcGFjZUNvbnRleHQgY29udGV4dCwgQXVnbWVudGF0aW9ucyBhdWdzKQotICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBOb3RpZmllcyBvZiB0aGUgcHJlc2VuY2Ugb2YgYW4gWE1MRGVjbCBsaW5lIGluIHRoZSBkb2N1bWVudC4gSWYKLSAgICAgKiBwcmVzZW50LCB0aGlzIG1ldGhvZCB3aWxsIGJlIGNhbGxlZCBpbW1lZGlhdGVseSBmb2xsb3dpbmcgdGhlCi0gICAgICogc3RhcnREb2N1bWVudCBjYWxsLgotICAgICAqCi0gICAgICogQHBhcmFtIHZlcnNpb24gICAgVGhlIFhNTCB2ZXJzaW9uLgotICAgICAqIEBwYXJhbSBlbmNvZGluZyAgIFRoZSBJQU5BIGVuY29kaW5nIG5hbWUgb2YgdGhlIGRvY3VtZW50LCBvciBudWxsIGlmCi0gICAgICogICAgICAgICAgICAgICAgICAgbm90IHNwZWNpZmllZC4KLSAgICAgKiBAcGFyYW0gc3RhbmRhbG9uZSBUaGUgc3RhbmRhbG9uZSB2YWx1ZSwgb3IgbnVsbCBpZiBub3Qgc3BlY2lmaWVkLgotICAgICAqIEBwYXJhbSBhdWdzICAgICAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKgotICAgICAqIEBleGNlcHRpb24gWE5JRXhjZXB0aW9uCi0gICAgICogICAgICAgICAgICAgICAgICAgVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHhtbERlY2woU3RyaW5nIHZlcnNpb24sIFN0cmluZyBlbmNvZGluZywgU3RyaW5nIHN0YW5kYWxvbmUsIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogTm90aWZpZXMgb2YgdGhlIHByZXNlbmNlIG9mIHRoZSBET0NUWVBFIGxpbmUgaW4gdGhlIGRvY3VtZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIHJvb3RFbGVtZW50Ci0gICAgICogICAgICAgICAgICAgICAgIFRoZSBuYW1lIG9mIHRoZSByb290IGVsZW1lbnQuCi0gICAgICogQHBhcmFtIHB1YmxpY0lkIFRoZSBwdWJsaWMgaWRlbnRpZmllciBpZiBhbiBleHRlcm5hbCBEVEQgb3IgbnVsbAotICAgICAqICAgICAgICAgICAgICAgICBpZiB0aGUgZXh0ZXJuYWwgRFREIGlzIHNwZWNpZmllZCB1c2luZyBTWVNURU0uCi0gICAgICogQHBhcmFtIHN5c3RlbUlkIFRoZSBzeXN0ZW0gaWRlbnRpZmllciBpZiBhbiBleHRlcm5hbCBEVEQsIG51bGwKLSAgICAgKiAgICAgICAgICAgICAgICAgb3RoZXJ3aXNlLgotICAgICAqIEBwYXJhbSBhdWdzICAgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIFhOSUV4Y2VwdGlvbgotICAgICAqICAgICAgICAgICAgICAgICAgIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBkb2N0eXBlRGVjbChTdHJpbmcgcm9vdEVsZW1lbnQsIFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkLCBBdWdtZW50YXRpb25zIGF1Z3MpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotICAgIH0KLQotICAgIC8qKgotICAgICAqIEEgY29tbWVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSB0ZXh0ICAgVGhlIHRleHQgaW4gdGhlIGNvbW1lbnQuCi0gICAgICogQHBhcmFtIGF1Z3MgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIFhOSUV4Y2VwdGlvbgotICAgICAqICAgICAgICAgICAgICAgICAgIFRocm93biBieSBhcHBsaWNhdGlvbiB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY29tbWVudChYTUxTdHJpbmcgdGV4dCwgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24uIFByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb25zIGNvbnNpc3Qgb2YgYQotICAgICAqIHRhcmdldCBuYW1lIGFuZCwgb3B0aW9uYWxseSwgdGV4dCBkYXRhLiBUaGUgZGF0YSBpcyBvbmx5IG1lYW5pbmdmdWwKLSAgICAgKiB0byB0aGUgYXBwbGljYXRpb24uCi0gICAgICogPHA+Ci0gICAgICogVHlwaWNhbGx5LCBhIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24ncyBkYXRhIHdpbGwgY29udGFpbiBhIHNlcmllcwotICAgICAqIG9mIHBzZXVkby1hdHRyaWJ1dGVzLiBUaGVzZSBwc2V1ZG8tYXR0cmlidXRlcyBmb2xsb3cgdGhlIGZvcm0gb2YKLSAgICAgKiBlbGVtZW50IGF0dHJpYnV0ZXMgYnV0IGFyZSA8c3Ryb25nPm5vdDwvc3Ryb25nPiBwYXJzZWQgb3IgcHJlc2VudGVkCi0gICAgICogdG8gdGhlIGFwcGxpY2F0aW9uIGFzIGFueXRoaW5nIG90aGVyIHRoYW4gdGV4dC4gVGhlIGFwcGxpY2F0aW9uIGlzCi0gICAgICogcmVzcG9uc2libGUgZm9yIHBhcnNpbmcgdGhlIGRhdGEuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdGFyZ2V0IFRoZSB0YXJnZXQuCi0gICAgICogQHBhcmFtIGRhdGEgICBUaGUgZGF0YSBvciBudWxsIGlmIG5vbmUgc3BlY2lmaWVkLgotICAgICAqIEBwYXJhbSBhdWdzICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBYTklFeGNlcHRpb24KLSAgICAgKiAgICAgICAgICAgICAgICAgICBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcHJvY2Vzc2luZ0luc3RydWN0aW9uKFN0cmluZyB0YXJnZXQsIFhNTFN0cmluZyBkYXRhLCBBdWdtZW50YXRpb25zIGF1Z3MpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoZSBzdGFydCBvZiBhIG5hbWVzcGFjZSBwcmVmaXggbWFwcGluZy4gVGhpcyBtZXRob2Qgd2lsbCBvbmx5IGJlCi0gICAgICogY2FsbGVkIHdoZW4gbmFtZXNwYWNlIHByb2Nlc3NpbmcgaXMgZW5hYmxlZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBwcmVmaXggVGhlIG5hbWVzcGFjZSBwcmVmaXguCi0gICAgICogQHBhcmFtIHVyaSAgICBUaGUgVVJJIGJvdW5kIHRvIHRoZSBwcmVmaXguCi0gICAgICogQHBhcmFtIGF1Z3MgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIFhOSUV4Y2VwdGlvbgotICAgICAqICAgICAgICAgICAgICAgICAgIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydFByZWZpeE1hcHBpbmcoU3RyaW5nIHByZWZpeCwgU3RyaW5nIHVyaSwgQXVnbWVudGF0aW9ucyBhdWdzKQotICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgc3RhcnQgb2YgYW4gZWxlbWVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlbGVtZW50ICAgIFRoZSBuYW1lIG9mIHRoZSBlbGVtZW50LgotICAgICAqIEBwYXJhbSBhdHRyaWJ1dGVzIFRoZSBlbGVtZW50IGF0dHJpYnV0ZXMuCi0gICAgICogQHBhcmFtIGF1Z3MgICAgICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBYTklFeGNlcHRpb24KLSAgICAgKiAgICAgICAgICAgICAgICAgICBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnRFbGVtZW50KFFOYW1lIGVsZW1lbnQsIFhNTEF0dHJpYnV0ZXMgYXR0cmlidXRlcywgQXVnbWVudGF0aW9ucyBhdWdzKQotICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBbiBlbXB0eSBlbGVtZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIGVsZW1lbnQgICAgVGhlIG5hbWUgb2YgdGhlIGVsZW1lbnQuCi0gICAgICogQHBhcmFtIGF0dHJpYnV0ZXMgVGhlIGVsZW1lbnQgYXR0cmlidXRlcy4KLSAgICAgKiBAcGFyYW0gYXVncyAgICAgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIFhOSUV4Y2VwdGlvbgotICAgICAqICAgICAgICAgICAgICAgICAgIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbXB0eUVsZW1lbnQoUU5hbWUgZWxlbWVudCwgWE1MQXR0cmlidXRlcyBhdHRyaWJ1dGVzLCBBdWdtZW50YXRpb25zIGF1Z3MpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIG5vdGlmaWVzIHRoZSBzdGFydCBvZiBhIGdlbmVyYWwgZW50aXR5LgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gVGhpcyBtZXRob2QgaXMgbm90IGNhbGxlZCBmb3IgZW50aXR5IHJlZmVyZW5jZXMKLSAgICAgKiBhcHBlYXJpbmcgYXMgcGFydCBvZiBhdHRyaWJ1dGUgdmFsdWVzLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgICAgIFRoZSBuYW1lIG9mIHRoZSBnZW5lcmFsIGVudGl0eS4KLSAgICAgKiBAcGFyYW0gaWRlbnRpZmllciBUaGUgcmVzb3VyY2UgaWRlbnRpZmllci4KLSAgICAgKiBAcGFyYW0gZW5jb2RpbmcgVGhlIGF1dG8tZGV0ZWN0ZWQgSUFOQSBlbmNvZGluZyBuYW1lIG9mIHRoZSBlbnRpdHkKLSAgICAgKiAgICAgICAgICAgICAgICAgc3RyZWFtLiBUaGlzIHZhbHVlIHdpbGwgYmUgbnVsbCBpbiB0aG9zZSBzaXR1YXRpb25zCi0gICAgICogICAgICAgICAgICAgICAgIHdoZXJlIHRoZSBlbnRpdHkgZW5jb2RpbmcgaXMgbm90IGF1dG8tZGV0ZWN0ZWQgKGUuZy4KLSAgICAgKiAgICAgICAgICAgICAgICAgaW50ZXJuYWwgZW50aXRpZXMgb3IgYSBkb2N1bWVudCBlbnRpdHkgdGhhdCBpcwotICAgICAqICAgICAgICAgICAgICAgICBwYXJzZWQgZnJvbSBhIGphdmEuaW8uUmVhZGVyKS4KLSAgICAgKiBAcGFyYW0gYXVncyAgICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0R2VuZXJhbEVudGl0eShTdHJpbmcgbmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MUmVzb3VyY2VJZGVudGlmaWVyIGlkZW50aWZpZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBlbmNvZGluZywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBOb3RpZmllcyBvZiB0aGUgcHJlc2VuY2Ugb2YgYSBUZXh0RGVjbCBsaW5lIGluIGFuIGVudGl0eS4gSWYgcHJlc2VudCwKLSAgICAgKiB0aGlzIG1ldGhvZCB3aWxsIGJlIGNhbGxlZCBpbW1lZGlhdGVseSBmb2xsb3dpbmcgdGhlIHN0YXJ0RW50aXR5IGNhbGwuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGlzIG1ldGhvZCB3aWxsIG5ldmVyIGJlIGNhbGxlZCBmb3IgdGhlCi0gICAgICogZG9jdW1lbnQgZW50aXR5OyBpdCBpcyBvbmx5IGNhbGxlZCBmb3IgZXh0ZXJuYWwgZ2VuZXJhbCBlbnRpdGllcwotICAgICAqIHJlZmVyZW5jZWQgaW4gZG9jdW1lbnQgY29udGVudC4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoaXMgbWV0aG9kIGlzIG5vdCBjYWxsZWQgZm9yIGVudGl0eSByZWZlcmVuY2VzCi0gICAgICogYXBwZWFyaW5nIGFzIHBhcnQgb2YgYXR0cmlidXRlIHZhbHVlcy4KLSAgICAgKgotICAgICAqIEBwYXJhbSB2ZXJzaW9uICBUaGUgWE1MIHZlcnNpb24sIG9yIG51bGwgaWYgbm90IHNwZWNpZmllZC4KLSAgICAgKiBAcGFyYW0gZW5jb2RpbmcgVGhlIElBTkEgZW5jb2RpbmcgbmFtZSBvZiB0aGUgZW50aXR5LgotICAgICAqIEBwYXJhbSBhdWdzICAgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIFhOSUV4Y2VwdGlvbgotICAgICAqICAgICAgICAgICAgICAgICAgIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0ZXh0RGVjbChTdHJpbmcgdmVyc2lvbiwgU3RyaW5nIGVuY29kaW5nLCBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIG5vdGlmaWVzIHRoZSBlbmQgb2YgYSBnZW5lcmFsIGVudGl0eS4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoaXMgbWV0aG9kIGlzIG5vdCBjYWxsZWQgZm9yIGVudGl0eSByZWZlcmVuY2VzCi0gICAgICogYXBwZWFyaW5nIGFzIHBhcnQgb2YgYXR0cmlidXRlIHZhbHVlcy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lICAgVGhlIG5hbWUgb2YgdGhlIGVudGl0eS4KLSAgICAgKiBAcGFyYW0gYXVncyAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKgotICAgICAqIEBleGNlcHRpb24gWE5JRXhjZXB0aW9uCi0gICAgICogICAgICAgICAgICAgICAgICAgVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZEdlbmVyYWxFbnRpdHkoU3RyaW5nIG5hbWUsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ2hhcmFjdGVyIGNvbnRlbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdGV4dCAgIFRoZSBjb250ZW50LgotICAgICAqIEBwYXJhbSBhdWdzICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBYTklFeGNlcHRpb24KLSAgICAgKiAgICAgICAgICAgICAgICAgICBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY2hhcmFjdGVycyhYTUxTdHJpbmcgdGV4dCwgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJZ25vcmFibGUgd2hpdGVzcGFjZS4gRm9yIHRoaXMgbWV0aG9kIHRvIGJlIGNhbGxlZCwgdGhlIGRvY3VtZW50Ci0gICAgICogc291cmNlIG11c3QgaGF2ZSBzb21lIHdheSBvZiBkZXRlcm1pbmluZyB0aGF0IHRoZSB0ZXh0IGNvbnRhaW5pbmcKLSAgICAgKiBvbmx5IHdoaXRlc3BhY2UgY2hhcmFjdGVycyBzaG91bGQgYmUgY29uc2lkZXJlZCBpZ25vcmFibGUuIEZvcgotICAgICAqIGV4YW1wbGUsIHRoZSB2YWxpZGF0b3IgY2FuIGRldGVybWluZSBpZiBhIGxlbmd0aCBvZiB3aGl0ZXNwYWNlCi0gICAgICogY2hhcmFjdGVycyBpbiB0aGUgZG9jdW1lbnQgYXJlIGlnbm9yYWJsZSBiYXNlZCBvbiB0aGUgZWxlbWVudAotICAgICAqIGNvbnRlbnQgbW9kZWwuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdGV4dCAgIFRoZSBpZ25vcmFibGUgd2hpdGVzcGFjZS4KLSAgICAgKiBAcGFyYW0gYXVncyAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKgotICAgICAqIEBleGNlcHRpb24gWE5JRXhjZXB0aW9uCi0gICAgICogICAgICAgICAgICAgICAgICAgVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGlnbm9yYWJsZVdoaXRlc3BhY2UoWE1MU3RyaW5nIHRleHQsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhlIGVuZCBvZiBhbiBlbGVtZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIGVsZW1lbnQgVGhlIG5hbWUgb2YgdGhlIGVsZW1lbnQuCi0gICAgICogQHBhcmFtIGF1Z3MgICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBYTklFeGNlcHRpb24KLSAgICAgKiAgICAgICAgICAgICAgICAgICBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kRWxlbWVudChRTmFtZSBlbGVtZW50LCBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoZSBlbmQgb2YgYSBuYW1lc3BhY2UgcHJlZml4IG1hcHBpbmcuIFRoaXMgbWV0aG9kIHdpbGwgb25seSBiZQotICAgICAqIGNhbGxlZCB3aGVuIG5hbWVzcGFjZSBwcm9jZXNzaW5nIGlzIGVuYWJsZWQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcHJlZml4IFRoZSBuYW1lc3BhY2UgcHJlZml4LgotICAgICAqIEBwYXJhbSBhdWdzICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBYTklFeGNlcHRpb24KLSAgICAgKiAgICAgICAgICAgICAgICAgICBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kUHJlZml4TWFwcGluZyhTdHJpbmcgcHJlZml4LCBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoZSBzdGFydCBvZiBhIENEQVRBIHNlY3Rpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYXVncyAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKgotICAgICAqIEBleGNlcHRpb24gWE5JRXhjZXB0aW9uCi0gICAgICogICAgICAgICAgICAgICAgICAgVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0Q0RBVEEoQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgZW5kIG9mIGEgQ0RBVEEgc2VjdGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBhdWdzICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBYTklFeGNlcHRpb24KLSAgICAgKiAgICAgICAgICAgICAgICAgICBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kQ0RBVEEoQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgZW5kIG9mIHRoZSBkb2N1bWVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBhdWdzICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBYTklFeGNlcHRpb24KLSAgICAgKiAgICAgICAgICAgICAgICAgICBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kRG9jdW1lbnQoQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICB9Ci0KLQotICAgIC8vCi0gICAgLy8gWE1MRFRESGFuZGxlciBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFRoZSBzdGFydCBvZiB0aGUgRFRELgotICAgICAqCi0gICAgICogQHBhcmFtIGxvY2F0b3IgIFRoZSBkb2N1bWVudCBsb2NhdG9yLCBvciBudWxsIGlmIHRoZSBkb2N1bWVudAotICAgICAqICAgICAgICAgICAgICAgICBsb2NhdGlvbiBjYW5ub3QgYmUgcmVwb3J0ZWQgZHVyaW5nIHRoZSBwYXJzaW5nIG9mCi0gICAgICogICAgICAgICAgICAgICAgIHRoZSBkb2N1bWVudCBEVEQuIEhvd2V2ZXIsIGl0IGlzIDxlbT5zdHJvbmdseTwvZW0+Ci0gICAgICogICAgICAgICAgICAgICAgIHJlY29tbWVuZGVkIHRoYXQgYSBsb2NhdG9yIGJlIHN1cHBsaWVkIHRoYXQgY2FuCi0gICAgICogICAgICAgICAgICAgICAgIGF0IGxlYXN0IHJlcG9ydCB0aGUgYmFzZSBzeXN0ZW0gaWRlbnRpZmllciBvZiB0aGUKLSAgICAgKiAgICAgICAgICAgICAgICAgRFRELgotICAgICAqIEBwYXJhbSBhdWdtZW50YXRpb25zIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydERURChYTUxMb2NhdG9yIGxvY2F0b3IsIEF1Z21lbnRhdGlvbnMgYXVnbWVudGF0aW9ucykKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2Qgbm90aWZpZXMgb2YgdGhlIHN0YXJ0IG9mIGEgcGFyYW1ldGVyIGVudGl0eS4gVGhlIHBhcmFtZXRlcgotICAgICAqIGVudGl0eSBuYW1lIHN0YXJ0IHdpdGggYSAnJScgY2hhcmFjdGVyLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgICAgIFRoZSBuYW1lIG9mIHRoZSBwYXJhbWV0ZXIgZW50aXR5LgotICAgICAqIEBwYXJhbSBpZGVudGlmaWVyIFRoZSByZXNvdXJjZSBpZGVudGlmaWVyLgotICAgICAqIEBwYXJhbSBlbmNvZGluZyBUaGUgYXV0by1kZXRlY3RlZCBJQU5BIGVuY29kaW5nIG5hbWUgb2YgdGhlIGVudGl0eQotICAgICAqICAgICAgICAgICAgICAgICBzdHJlYW0uIFRoaXMgdmFsdWUgd2lsbCBiZSBudWxsIGluIHRob3NlIHNpdHVhdGlvbnMKLSAgICAgKiAgICAgICAgICAgICAgICAgd2hlcmUgdGhlIGVudGl0eSBlbmNvZGluZyBpcyBub3QgYXV0by1kZXRlY3RlZCAoZS5nLgotICAgICAqICAgICAgICAgICAgICAgICBpbnRlcm5hbCBwYXJhbWV0ZXIgZW50aXRpZXMpLgotICAgICAqIEBwYXJhbSBhdWdtZW50YXRpb25zIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydFBhcmFtZXRlckVudGl0eShTdHJpbmcgbmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxSZXNvdXJjZUlkZW50aWZpZXIgaWRlbnRpZmllciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgZW5jb2RpbmcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBOb3RpZmllcyBvZiB0aGUgcHJlc2VuY2Ugb2YgYSBUZXh0RGVjbCBsaW5lIGluIGFuIGVudGl0eS4gSWYgcHJlc2VudCwKLSAgICAgKiB0aGlzIG1ldGhvZCB3aWxsIGJlIGNhbGxlZCBpbW1lZGlhdGVseSBmb2xsb3dpbmcgdGhlIHN0YXJ0RW50aXR5IGNhbGwuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGlzIG1ldGhvZCBpcyBvbmx5IGNhbGxlZCBmb3IgZXh0ZXJuYWwKLSAgICAgKiBwYXJhbWV0ZXIgZW50aXRpZXMgcmVmZXJlbmNlZCBpbiB0aGUgRFRELgotICAgICAqCi0gICAgICogQHBhcmFtIHZlcnNpb24gIFRoZSBYTUwgdmVyc2lvbiwgb3IgbnVsbCBpZiBub3Qgc3BlY2lmaWVkLgotICAgICAqIEBwYXJhbSBlbmNvZGluZyBUaGUgSUFOQSBlbmNvZGluZyBuYW1lIG9mIHRoZSBlbnRpdHkuCi0gICAgICogQHBhcmFtIGF1Z21lbnRhdGlvbnMgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotLyoKLSAgICBwdWJsaWMgdm9pZCB0ZXh0RGVjbChTdHJpbmcgdmVyc2lvbiwgU3RyaW5nIGVuY29kaW5nLAotICAgICAgICAgICAgICAgICAgICAgICAgIEF1Z21lbnRhdGlvbnMgYXVnbWVudGF0aW9ucykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgfQotKi8KLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIG5vdGlmaWVzIHRoZSBlbmQgb2YgYSBwYXJhbWV0ZXIgZW50aXR5LiBQYXJhbWV0ZXIgZW50aXR5Ci0gICAgICogbmFtZXMgYmVnaW4gd2l0aCBhICclJyBjaGFyYWN0ZXIuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgcGFyYW1ldGVyIGVudGl0eS4KLSAgICAgKiBAcGFyYW0gYXVnbWVudGF0aW9ucyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kUGFyYW1ldGVyRW50aXR5KFN0cmluZyBuYW1lLCBBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoZSBzdGFydCBvZiB0aGUgRFREIGV4dGVybmFsIHN1YnNldC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBpZGVudGlmaWVyIFRoZSByZXNvdXJjZSBpZGVudGlmaWVyLgotICAgICAqIEBwYXJhbSBhdWdtZW50YXRpb25zCi0gICAgICogICAgICAgICAgICAgICAgICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqIEBleGNlcHRpb24gWE5JRXhjZXB0aW9uCi0gICAgICogICAgICAgICAgICAgICAgICAgVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RXh0ZXJuYWxTdWJzZXQoWE1MUmVzb3VyY2VJZGVudGlmaWVyIGlkZW50aWZpZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoZSBlbmQgb2YgdGhlIERURCBleHRlcm5hbCBzdWJzZXQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYXVnbWVudGF0aW9ucyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kRXh0ZXJuYWxTdWJzZXQoQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKQotICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBIGNvbW1lbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdGV4dCBUaGUgdGV4dCBpbiB0aGUgY29tbWVudC4KLSAgICAgKiBAcGFyYW0gYXVnbWVudGF0aW9ucyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgYXBwbGljYXRpb24gdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotLyoKLSAgICBwdWJsaWMgdm9pZCBjb21tZW50KFhNTFN0cmluZyB0ZXh0LCBBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotICAgIH0KLSovCi0KLSAgICAvKioKLSAgICAgKiBBIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24uIFByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb25zIGNvbnNpc3Qgb2YgYQotICAgICAqIHRhcmdldCBuYW1lIGFuZCwgb3B0aW9uYWxseSwgdGV4dCBkYXRhLiBUaGUgZGF0YSBpcyBvbmx5IG1lYW5pbmdmdWwKLSAgICAgKiB0byB0aGUgYXBwbGljYXRpb24uCi0gICAgICogPHA+Ci0gICAgICogVHlwaWNhbGx5LCBhIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24ncyBkYXRhIHdpbGwgY29udGFpbiBhIHNlcmllcwotICAgICAqIG9mIHBzZXVkby1hdHRyaWJ1dGVzLiBUaGVzZSBwc2V1ZG8tYXR0cmlidXRlcyBmb2xsb3cgdGhlIGZvcm0gb2YKLSAgICAgKiBlbGVtZW50IGF0dHJpYnV0ZXMgYnV0IGFyZSA8c3Ryb25nPm5vdDwvc3Ryb25nPiBwYXJzZWQgb3IgcHJlc2VudGVkCi0gICAgICogdG8gdGhlIGFwcGxpY2F0aW9uIGFzIGFueXRoaW5nIG90aGVyIHRoYW4gdGV4dC4gVGhlIGFwcGxpY2F0aW9uIGlzCi0gICAgICogcmVzcG9uc2libGUgZm9yIHBhcnNpbmcgdGhlIGRhdGEuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdGFyZ2V0IFRoZSB0YXJnZXQuCi0gICAgICogQHBhcmFtIGRhdGEgICBUaGUgZGF0YSBvciBudWxsIGlmIG5vbmUgc3BlY2lmaWVkLgotICAgICAqIEBwYXJhbSBhdWdtZW50YXRpb25zIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLS8qCi0gICAgcHVibGljIHZvaWQgcHJvY2Vzc2luZ0luc3RydWN0aW9uKFN0cmluZyB0YXJnZXQsIFhNTFN0cmluZyBkYXRhLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotICAgIH0KLSovCi0KLQotICAgIC8qKgotICAgICAqIEFuIGVsZW1lbnQgZGVjbGFyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSAgICAgICAgIFRoZSBuYW1lIG9mIHRoZSBlbGVtZW50LgotICAgICAqIEBwYXJhbSBjb250ZW50TW9kZWwgVGhlIGVsZW1lbnQgY29udGVudCBtb2RlbC4KLSAgICAgKiBAcGFyYW0gYXVnbWVudGF0aW9ucyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZWxlbWVudERlY2woU3RyaW5nIG5hbWUsIFN0cmluZyBjb250ZW50TW9kZWwsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKQotICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgc3RhcnQgb2YgYW4gYXR0cmlidXRlIGxpc3QuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZWxlbWVudE5hbWUgVGhlIG5hbWUgb2YgdGhlIGVsZW1lbnQgdGhhdCB0aGlzIGF0dHJpYnV0ZQotICAgICAqICAgICAgICAgICAgICAgICAgICBsaXN0IGlzIGFzc29jaWF0ZWQgd2l0aC4KLSAgICAgKiBAcGFyYW0gYXVnbWVudGF0aW9ucyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnRBdHRsaXN0KFN0cmluZyBlbGVtZW50TmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBbiBhdHRyaWJ1dGUgZGVjbGFyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZWxlbWVudE5hbWUgICBUaGUgbmFtZSBvZiB0aGUgZWxlbWVudCB0aGF0IHRoaXMgYXR0cmlidXRlCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgaXMgYXNzb2NpYXRlZCB3aXRoLgotICAgICAqIEBwYXJhbSBhdHRyaWJ1dGVOYW1lIFRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUuCi0gICAgICogQHBhcmFtIHR5cGUgICAgICAgICAgVGhlIGF0dHJpYnV0ZSB0eXBlLiBUaGlzIHZhbHVlIHdpbGwgYmUgb25lIG9mCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgdGhlIGZvbGxvd2luZzogIkNEQVRBIiwgIkVOVElUWSIsICJFTlRJVElFUyIsCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgIkVOVU1FUkFUSU9OIiwgIklEIiwgIklEUkVGIiwgIklEUkVGUyIsCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgIk5NVE9LRU4iLCAiTk1UT0tFTlMiLCBvciAiTk9UQVRJT04iLgotICAgICAqIEBwYXJhbSBlbnVtZXJhdGlvbiAgIElmIHRoZSB0eXBlIGhhcyB0aGUgdmFsdWUgIkVOVU1FUkFUSU9OIiBvcgotICAgICAqICAgICAgICAgICAgICAgICAgICAgICJOT1RBVElPTiIsIHRoaXMgYXJyYXkgaG9sZHMgdGhlIGFsbG93ZWQgYXR0cmlidXRlCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgdmFsdWVzOyBvdGhlcndpc2UsIHRoaXMgYXJyYXkgaXMgbnVsbC4KLSAgICAgKiBAcGFyYW0gZGVmYXVsdFR5cGUgICBUaGUgYXR0cmlidXRlIGRlZmF1bHQgdHlwZS4gVGhpcyB2YWx1ZSB3aWxsIGJlCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgb25lIG9mIHRoZSBmb2xsb3dpbmc6ICIjRklYRUQiLCAiI0lNUExJRUQiLAotICAgICAqICAgICAgICAgICAgICAgICAgICAgICIjUkVRVUlSRUQiLCBvciBudWxsLgotICAgICAqIEBwYXJhbSBkZWZhdWx0VmFsdWUgIFRoZSBhdHRyaWJ1dGUgZGVmYXVsdCB2YWx1ZSwgb3IgbnVsbCBpZiBubwotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQgdmFsdWUgaXMgc3BlY2lmaWVkLgotICAgICAqIEBwYXJhbSBub25Ob3JtYWxpemVkRGVmYXVsdFZhbHVlICBUaGUgYXR0cmlidXRlIGRlZmF1bHQgdmFsdWUgd2l0aCBubyBub3JtYWxpemF0aW9uCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgcGVyZm9ybWVkLCBvciBudWxsIGlmIG5vIGRlZmF1bHQgdmFsdWUgaXMgc3BlY2lmaWVkLgotICAgICAqIEBwYXJhbSBhdWdtZW50YXRpb25zIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBhdHRyaWJ1dGVEZWNsKFN0cmluZyBlbGVtZW50TmFtZSwgU3RyaW5nIGF0dHJpYnV0ZU5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdHlwZSwgU3RyaW5nW10gZW51bWVyYXRpb24sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgZGVmYXVsdFR5cGUsIFhNTFN0cmluZyBkZWZhdWx0VmFsdWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxTdHJpbmcgbm9uTm9ybWFsaXplZERlZmF1bHRWYWx1ZSwgQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKQotICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgZW5kIG9mIGFuIGF0dHJpYnV0ZSBsaXN0LgotICAgICAqCi0gICAgICogQHBhcmFtIGF1Z21lbnRhdGlvbnMgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZEF0dGxpc3QoQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBbiBpbnRlcm5hbCBlbnRpdHkgZGVjbGFyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgZW50aXR5LiBQYXJhbWV0ZXIgZW50aXR5IG5hbWVzIHN0YXJ0IHdpdGgKLSAgICAgKiAgICAgICAgICAgICAnJScsIHdoZXJlYXMgdGhlIG5hbWUgb2YgYSBnZW5lcmFsIGVudGl0eSBpcyBqdXN0IHRoZQotICAgICAqICAgICAgICAgICAgIGVudGl0eSBuYW1lLgotICAgICAqIEBwYXJhbSB0ZXh0IFRoZSB2YWx1ZSBvZiB0aGUgZW50aXR5LgotICAgICAqIEBwYXJhbSBub25Ob3JtYWxpemVkVGV4dCBUaGUgbm9uLW5vcm1hbGl6ZWQgdmFsdWUgb2YgdGhlIGVudGl0eS4gVGhpcwotICAgICAqICAgICAgICAgICAgIHZhbHVlIGNvbnRhaW5zIHRoZSBzYW1lIHNlcXVlbmNlIG9mIGNoYXJhY3RlcnMgdGhhdCB3YXMgaW4KLSAgICAgKiAgICAgICAgICAgICB0aGUgaW50ZXJuYWwgZW50aXR5IGRlY2xhcmF0aW9uLCB3aXRob3V0IGFueSBlbnRpdHkKLSAgICAgKiAgICAgICAgICAgICByZWZlcmVuY2VzIGV4cGFuZGVkLgotICAgICAqIEBwYXJhbSBhdWdtZW50YXRpb25zIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBpbnRlcm5hbEVudGl0eURlY2woU3RyaW5nIG5hbWUsIFhNTFN0cmluZyB0ZXh0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxTdHJpbmcgbm9uTm9ybWFsaXplZFRleHQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF1Z21lbnRhdGlvbnMgYXVnbWVudGF0aW9ucykKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQW4gZXh0ZXJuYWwgZW50aXR5IGRlY2xhcmF0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgICAgIFRoZSBuYW1lIG9mIHRoZSBlbnRpdHkuIFBhcmFtZXRlciBlbnRpdHkgbmFtZXMgc3RhcnQKLSAgICAgKiAgICAgICAgICAgICAgICAgd2l0aCAnJScsIHdoZXJlYXMgdGhlIG5hbWUgb2YgYSBnZW5lcmFsIGVudGl0eSBpcyBqdXN0Ci0gICAgICogICAgICAgICAgICAgICAgIHRoZSBlbnRpdHkgbmFtZS4KLSAgICAgKiBAcGFyYW0gaWRlbnRpZmllciAgICBBbiBvYmplY3QgY29udGFpbmluZyBhbGwgbG9jYXRpb24gaW5mb3JtYXRpb24KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBwZXJ0aW5lbnQgdG8gdGhpcyBleHRlcm5hbCBlbnRpdHkuCi0gICAgICogQHBhcmFtIGF1Z21lbnRhdGlvbnMgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGV4dGVybmFsRW50aXR5RGVjbChTdHJpbmcgbmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MUmVzb3VyY2VJZGVudGlmaWVyIGlkZW50aWZpZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF1Z21lbnRhdGlvbnMgYXVnbWVudGF0aW9ucykKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQW4gdW5wYXJzZWQgZW50aXR5IGRlY2xhcmF0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgICAgIFRoZSBuYW1lIG9mIHRoZSBlbnRpdHkuCi0gICAgICogQHBhcmFtIGlkZW50aWZpZXIgICAgQW4gb2JqZWN0IGNvbnRhaW5pbmcgYWxsIGxvY2F0aW9uIGluZm9ybWF0aW9uCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgcGVydGluZW50IHRvIHRoaXMgdW5wYXJzZWQgZW50aXR5IGRlY2xhcmF0aW9uLgotICAgICAqIEBwYXJhbSBub3RhdGlvbiBUaGUgbmFtZSBvZiB0aGUgbm90YXRpb24uCi0gICAgICogQHBhcmFtIGF1Z21lbnRhdGlvbnMgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHVucGFyc2VkRW50aXR5RGVjbChTdHJpbmcgbmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MUmVzb3VyY2VJZGVudGlmaWVyIGlkZW50aWZpZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBub3RhdGlvbiwgQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKQotICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBIG5vdGF0aW9uIGRlY2xhcmF0aW9uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSAgICAgVGhlIG5hbWUgb2YgdGhlIG5vdGF0aW9uLgotICAgICAqIEBwYXJhbSBpZGVudGlmaWVyICAgIEFuIG9iamVjdCBjb250YWluaW5nIGFsbCBsb2NhdGlvbiBpbmZvcm1hdGlvbgotICAgICAqICAgICAgICAgICAgICAgICAgICAgIHBlcnRpbmVudCB0byB0aGlzIG5vdGF0aW9uLgotICAgICAqIEBwYXJhbSBhdWdtZW50YXRpb25zIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBub3RhdGlvbkRlY2woU3RyaW5nIG5hbWUsIFhNTFJlc291cmNlSWRlbnRpZmllciBpZGVudGlmaWVyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoZSBzdGFydCBvZiBhIGNvbmRpdGlvbmFsIHNlY3Rpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdHlwZSBUaGUgdHlwZSBvZiB0aGUgY29uZGl0aW9uYWwgc2VjdGlvbi4gVGhpcyB2YWx1ZSB3aWxsCi0gICAgICogICAgICAgICAgICAgZWl0aGVyIGJlIENPTkRJVElPTkFMX0lOQ0xVREUgb3IgQ09ORElUSU9OQUxfSUdOT1JFLgotICAgICAqIEBwYXJhbSBhdWdtZW50YXRpb25zIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKgotICAgICAqIEBzZWUgI0NPTkRJVElPTkFMX0lOQ0xVREUKLSAgICAgKiBAc2VlICNDT05ESVRJT05BTF9JR05PUkUKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydENvbmRpdGlvbmFsKHNob3J0IHR5cGUsIEF1Z21lbnRhdGlvbnMgYXVnbWVudGF0aW9ucykKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ2hhcmFjdGVycyB3aXRoaW4gYW4gSUdOT1JFIGNvbmRpdGlvbmFsIHNlY3Rpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdGV4dCBUaGUgaWdub3JlZCB0ZXh0LgotICAgICAqIEBwYXJhbSBhdWdtZW50YXRpb25zIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBpZ25vcmVkQ2hhcmFjdGVycyhYTUxTdHJpbmcgdGV4dCwgQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKQotICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgZW5kIG9mIGEgY29uZGl0aW9uYWwgc2VjdGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBhdWdtZW50YXRpb25zIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbmRDb25kaXRpb25hbChBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoZSBlbmQgb2YgdGhlIERURC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBhdWdtZW50YXRpb25zIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbmREVEQoQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICB9Ci0KLQotICAgIC8vCi0gICAgLy8gWE1MRFREQ29udGVudE1vZGVsSGFuZGxlciBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFRoZSBzdGFydCBvZiBhIGNvbnRlbnQgbW9kZWwuIERlcGVuZGluZyBvbiB0aGUgdHlwZSBvZiB0aGUgY29udGVudAotICAgICAqIG1vZGVsLCBzcGVjaWZpYyBtZXRob2RzIG1heSBiZSBjYWxsZWQgYmV0d2VlbiB0aGUgY2FsbCB0byB0aGUKLSAgICAgKiBzdGFydENvbnRlbnRNb2RlbCBtZXRob2QgYW5kIHRoZSBjYWxsIHRvIHRoZSBlbmRDb250ZW50TW9kZWwgbWV0aG9kLgotICAgICAqCi0gICAgICogQHBhcmFtIGVsZW1lbnROYW1lIFRoZSBuYW1lIG9mIHRoZSBlbGVtZW50LgotICAgICAqIEBwYXJhbSBhdWdtZW50YXRpb25zIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydENvbnRlbnRNb2RlbChTdHJpbmcgZWxlbWVudE5hbWUsIEF1Z21lbnRhdGlvbnMgYXVnbWVudGF0aW9ucykKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQSBjb250ZW50IG1vZGVsIG9mIEFOWS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBhdWdtZW50YXRpb25zIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKgotICAgICAqIEBzZWUgI2VtcHR5Ci0gICAgICogQHNlZSAjc3RhcnRHcm91cAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGFueShBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgIH0KLQotICAgIC8qKgotICAgICAqIEEgY29udGVudCBtb2RlbCBvZiBFTVBUWS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKgotICAgICAqIEBwYXJhbSBhdWdtZW50YXRpb25zIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEBzZWUgI2FueQotICAgICAqIEBzZWUgI3N0YXJ0R3JvdXAKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbXB0eShBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgIH0KLQotICAgIC8qKgotICAgICAqIEEgc3RhcnQgb2YgZWl0aGVyIGEgbWl4ZWQgb3IgY2hpbGRyZW4gY29udGVudCBtb2RlbC4gQSBtaXhlZAotICAgICAqIGNvbnRlbnQgbW9kZWwgd2lsbCBpbW1lZGlhdGVseSBiZSBmb2xsb3dlZCBieSBhIGNhbGwgdG8gdGhlCi0gICAgICogPGNvZGU+cGNkYXRhKCk8L2NvZGU+IG1ldGhvZC4gQSBjaGlsZHJlbiBjb250ZW50IG1vZGVsIHdpbGwKLSAgICAgKiBjb250YWluIGFkZGl0aW9uYWwgZ3JvdXBzIGFuZC9vciBlbGVtZW50cy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBhdWdtZW50YXRpb25zIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKgotICAgICAqIEBzZWUgI2FueQotICAgICAqIEBzZWUgI2VtcHR5Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnRHcm91cChBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoZSBhcHBlYXJhbmNlIG9mICIjUENEQVRBIiB3aXRoaW4gYSBncm91cCBzaWduaWZ5aW5nIGEKLSAgICAgKiBtaXhlZCBjb250ZW50IG1vZGVsLiBUaGlzIG1ldGhvZCB3aWxsIGJlIHRoZSBmaXJzdCBjYWxsZWQKLSAgICAgKiBmb2xsb3dpbmcgdGhlIGNvbnRlbnQgbW9kZWwncyA8Y29kZT5zdGFydEdyb3VwKCk8L2NvZGU+LgotICAgICAqCi0gICAgICogQHBhcmFtIGF1Z21lbnRhdGlvbnMgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqCi0gICAgICogQHNlZSAjc3RhcnRHcm91cAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHBjZGF0YShBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgIH0KLQotICAgIC8qKgotICAgICAqIEEgcmVmZXJlbmNlZCBlbGVtZW50IGluIGEgbWl4ZWQgb3IgY2hpbGRyZW4gY29udGVudCBtb2RlbC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlbGVtZW50TmFtZSBUaGUgbmFtZSBvZiB0aGUgcmVmZXJlbmNlZCBlbGVtZW50LgotICAgICAqIEBwYXJhbSBhdWdtZW50YXRpb25zIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbGVtZW50KFN0cmluZyBlbGVtZW50TmFtZSwgQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKQotICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgc2VwYXJhdG9yIGJldHdlZW4gY2hvaWNlcyBvciBzZXF1ZW5jZXMgb2YgYSBtaXhlZCBvciBjaGlsZHJlbgotICAgICAqIGNvbnRlbnQgbW9kZWwuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc2VwYXJhdG9yIFRoZSB0eXBlIG9mIGNoaWxkcmVuIHNlcGFyYXRvci4KLSAgICAgKiBAcGFyYW0gYXVnbWVudGF0aW9ucyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICoKLSAgICAgKiBAc2VlICNTRVBBUkFUT1JfQ0hPSUNFCi0gICAgICogQHNlZSAjU0VQQVJBVE9SX1NFUVVFTkNFCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2VwYXJhdG9yKHNob3J0IHNlcGFyYXRvciwgQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKQotICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgb2NjdXJyZW5jZSBjb3VudCBmb3IgYSBjaGlsZCBpbiBhIGNoaWxkcmVuIGNvbnRlbnQgbW9kZWwgb3IKLSAgICAgKiBmb3IgdGhlIG1peGVkIGNvbnRlbnQgbW9kZWwgZ3JvdXAuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gb2NjdXJyZW5jZSBUaGUgb2NjdXJyZW5jZSBjb3VudCBmb3IgdGhlIGxhc3QgZWxlbWVudAotICAgICAqICAgICAgICAgICAgICAgICAgIG9yIGdyb3VwLgotICAgICAqIEBwYXJhbSBhdWdtZW50YXRpb25zIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKgotICAgICAqIEBzZWUgI09DQ1VSU19aRVJPX09SX09ORQotICAgICAqIEBzZWUgI09DQ1VSU19aRVJPX09SX01PUkUKLSAgICAgKiBAc2VlICNPQ0NVUlNfT05FX09SX01PUkUKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBvY2N1cnJlbmNlKHNob3J0IG9jY3VycmVuY2UsIEF1Z21lbnRhdGlvbnMgYXVnbWVudGF0aW9ucykKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhlIGVuZCBvZiBhIGdyb3VwIGZvciBtaXhlZCBvciBjaGlsZHJlbiBjb250ZW50IG1vZGVscy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBhdWdtZW50YXRpb25zIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbmRHcm91cChBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoZSBlbmQgb2YgYSBjb250ZW50IG1vZGVsLgotICAgICAqCi0gICAgICogQHBhcmFtIGF1Z21lbnRhdGlvbnMgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZENvbnRlbnRNb2RlbChBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgIH0KLQotICAgIHByaXZhdGUgWE1MRG9jdW1lbnRTb3VyY2UgZkRvY3VtZW50U291cmNlOwotCi0gICAgLyoqIFNldHMgdGhlIGRvY3VtZW50IHNvdXJjZS4gKi8KLSAgICBwdWJsaWMgdm9pZCBzZXREb2N1bWVudFNvdXJjZShYTUxEb2N1bWVudFNvdXJjZSBzb3VyY2UpIHsKLSAgICAgICAgZkRvY3VtZW50U291cmNlID0gc291cmNlOwotICAgIH0KLQotICAgIC8qKiBSZXR1cm5zIHRoZSBkb2N1bWVudCBzb3VyY2UuICovCi0gICAgcHVibGljIFhNTERvY3VtZW50U291cmNlIGdldERvY3VtZW50U291cmNlKCkgewotICAgICAgICByZXR1cm4gZkRvY3VtZW50U291cmNlOwotICAgIH0KLQotICAgIHByaXZhdGUgWE1MRFREU291cmNlIGZEVERTb3VyY2U7Ci0KLSAgICAvLyBzZXQgdGhlIHNvdXJjZSBvZiB0aGlzIGhhbmRsZXIKLSAgICBwdWJsaWMgdm9pZCBzZXREVERTb3VyY2UoWE1MRFREU291cmNlIHNvdXJjZSkgewotICAgICAgICBmRFREU291cmNlID0gc291cmNlOwotICAgIH0KLQotICAgIC8vIHJldHVybiB0aGUgc291cmNlIGZyb20gd2hpY2ggdGhpcyBoYW5kbGVyIGRlcml2ZXMgaXRzIGV2ZW50cwotICAgIHB1YmxpYyBYTUxEVERTb3VyY2UgZ2V0RFREU291cmNlKCkgewotICAgICAgICByZXR1cm4gZkRURFNvdXJjZTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIFhNTERURENvbnRlbnRNb2RlbFNvdXJjZSBmQ01Tb3VyY2U7Ci0KLSAgICAvLyBzZXQgY29udGVudCBtb2RlbCBzb3VyY2UKLSAgICBwdWJsaWMgdm9pZCBzZXREVERDb250ZW50TW9kZWxTb3VyY2UoWE1MRFREQ29udGVudE1vZGVsU291cmNlIHNvdXJjZSkgewotICAgICAgICBmQ01Tb3VyY2UgPSBzb3VyY2U7Ci0gICAgfQotCi0gICAgLy8gZ2V0IGNvbnRlbnQgbW9kZWwgc291cmNlCi0gICAgcHVibGljIFhNTERURENvbnRlbnRNb2RlbFNvdXJjZSBnZXREVERDb250ZW50TW9kZWxTb3VyY2UoKSB7Ci0gICAgICAgIHJldHVybiBmQ01Tb3VyY2U7Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL29wdGkvRWxlbWVudEltcGwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvb3B0aS9FbGVtZW50SW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyNGVlYmY3Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvb3B0aS9FbGVtZW50SW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjc0ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEsIDIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLm9wdGk7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5BdHRyOwotaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLk5hbWVkTm9kZU1hcDsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotCi0vKioKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIFJhaHVsIFNyaXZhc3RhdmEsIFN1biBNaWNyb3N5c3RlbXMgSW5jLgotICogQGF1dGhvciBTYW5keSBHYW8sIElCTQotICoKLSAqIEB2ZXJzaW9uICRJZDogRWxlbWVudEltcGwuamF2YSx2IDEuNyAyMDEwLTExLTAxIDA0OjQwOjAxIGpvZWh3IEV4cCAkCi0gKi8KLXB1YmxpYyBjbGFzcyBFbGVtZW50SW1wbCBleHRlbmRzIERlZmF1bHRFbGVtZW50IHsKLQotICAgIFNjaGVtYURPTSBzY2hlbWFET007Ci0gICAgQXR0cltdIGF0dHJzOwotICAgIGludCByb3c7Ci0gICAgaW50IGNvbDsKLSAgICBpbnQgcGFyZW50Um93OwotCi0gICAgaW50IGxpbmU7Ci0gICAgaW50IGNvbHVtbjsKLSAgICBpbnQgY2hhck9mZnNldDsKLSAgICBTdHJpbmcgZkFubm90YXRpb247Ci0gICAgU3RyaW5nIGZTeW50aGV0aWNBbm5vdGF0aW9uOwotCi0gICAgcHVibGljIEVsZW1lbnRJbXBsKGludCBsaW5lLCBpbnQgY29sdW1uLCBpbnQgb2Zmc2V0KSB7Ci0gICAgICAgIHJvdyA9IC0xOwotICAgICAgICBjb2wgPSAtMTsKLSAgICAgICAgcGFyZW50Um93ID0gLTE7Ci0gICAgICAgIG5vZGVUeXBlID0gTm9kZS5FTEVNRU5UX05PREU7Ci0KLSAgICAgICAgdGhpcy5saW5lID0gbGluZTsKLSAgICAgICAgdGhpcy5jb2x1bW4gPSBjb2x1bW47Ci0gICAgICAgIGNoYXJPZmZzZXQgPSBvZmZzZXQ7Ci0gICAgfQotCi0gICAgcHVibGljIEVsZW1lbnRJbXBsKGludCBsaW5lLCBpbnQgY29sdW1uKSB7Ci0gICAgICAgIHRoaXMobGluZSwgY29sdW1uLCAtMSk7Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgRWxlbWVudEltcGwoU3RyaW5nIHByZWZpeCwgU3RyaW5nIGxvY2FscGFydCwgU3RyaW5nIHJhd25hbWUsCi0gICAgICAgICAgICBTdHJpbmcgdXJpLCBpbnQgbGluZSwgaW50IGNvbHVtbiwgaW50IG9mZnNldCkgewotICAgICAgICBzdXBlcihwcmVmaXgsIGxvY2FscGFydCwgcmF3bmFtZSwgdXJpLCBOb2RlLkVMRU1FTlRfTk9ERSk7Ci0gICAgICAgIHJvdyA9IC0xOwotICAgICAgICBjb2wgPSAtMTsKLSAgICAgICAgcGFyZW50Um93ID0gLTE7Ci0KLSAgICAgICAgdGhpcy5saW5lID0gbGluZTsKLSAgICAgICAgdGhpcy5jb2x1bW4gPSBjb2x1bW47Ci0gICAgICAgIGNoYXJPZmZzZXQgPSBvZmZzZXQ7Ci0gICAgfQotCi0gICAgcHVibGljIEVsZW1lbnRJbXBsKFN0cmluZyBwcmVmaXgsIFN0cmluZyBsb2NhbHBhcnQsIFN0cmluZyByYXduYW1lLAotICAgICAgICAgICAgU3RyaW5nIHVyaSwgaW50IGxpbmUsIGludCBjb2x1bW4pIHsKLSAgICAgICAgdGhpcyhwcmVmaXgsIGxvY2FscGFydCwgcmF3bmFtZSwgdXJpLCBsaW5lLCBjb2x1bW4sIC0xKTsKLSAgICB9Ci0KLQotICAgIC8vCi0gICAgLy8gb3JnLnczYy5kb20uTm9kZSBtZXRob2RzCi0gICAgLy8KLQotICAgIHB1YmxpYyBEb2N1bWVudCBnZXRPd25lckRvY3VtZW50KCkgewotICAgICAgICByZXR1cm4gc2NoZW1hRE9NOwotICAgIH0KLQotCi0gICAgcHVibGljIE5vZGUgZ2V0UGFyZW50Tm9kZSgpIHsKLSAgICAgICAgcmV0dXJuIHNjaGVtYURPTS5yZWxhdGlvbnNbcm93XVswXTsKLSAgICB9Ci0KLQotICAgIHB1YmxpYyBib29sZWFuIGhhc0NoaWxkTm9kZXMoKSB7Ci0gICAgICAgIGlmIChwYXJlbnRSb3cgPT0gLTEpIHsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgTm9kZSBnZXRGaXJzdENoaWxkKCkgewotICAgICAgICBpZiAocGFyZW50Um93ID09IC0xKSB7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gc2NoZW1hRE9NLnJlbGF0aW9uc1twYXJlbnRSb3ddWzFdOwotICAgIH0KLQotCi0gICAgcHVibGljIE5vZGUgZ2V0TGFzdENoaWxkKCkgewotICAgICAgICBpZiAocGFyZW50Um93ID09IC0xKSB7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotICAgICAgICBpbnQgaT0xOwotICAgICAgICBmb3IgKDsgaTxzY2hlbWFET00ucmVsYXRpb25zW3BhcmVudFJvd10ubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgIGlmIChzY2hlbWFET00ucmVsYXRpb25zW3BhcmVudFJvd11baV0gPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJldHVybiBzY2hlbWFET00ucmVsYXRpb25zW3BhcmVudFJvd11baS0xXTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBpZiAoaSA9PTEpIHsKLSAgICAgICAgICAgIGkrKzsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gc2NoZW1hRE9NLnJlbGF0aW9uc1twYXJlbnRSb3ddW2ktMV07Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgTm9kZSBnZXRQcmV2aW91c1NpYmxpbmcoKSB7Ci0gICAgICAgIGlmIChjb2wgPT0gMSkgewotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHNjaGVtYURPTS5yZWxhdGlvbnNbcm93XVtjb2wtMV07Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgTm9kZSBnZXROZXh0U2libGluZygpIHsKLSAgICAgICAgaWYgKGNvbCA9PSBzY2hlbWFET00ucmVsYXRpb25zW3Jvd10ubGVuZ3RoLTEpIHsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBzY2hlbWFET00ucmVsYXRpb25zW3Jvd11bY29sKzFdOwotICAgIH0KLQotCi0gICAgcHVibGljIE5hbWVkTm9kZU1hcCBnZXRBdHRyaWJ1dGVzKCkgewotICAgICAgICByZXR1cm4gbmV3IE5hbWVkTm9kZU1hcEltcGwoYXR0cnMpOwotICAgIH0KLQotCi0gICAgcHVibGljIGJvb2xlYW4gaGFzQXR0cmlidXRlcygpIHsKLSAgICAgICAgcmV0dXJuIChhdHRycy5sZW5ndGggPT0gMCA/IGZhbHNlIDogdHJ1ZSk7Ci0gICAgfQotCi0KLQotICAgIC8vCi0gICAgLy8gb3JnLnczYy5kb20uRWxlbWVudCBtZXRob2RzCi0gICAgLy8KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFnTmFtZSgpIHsKLSAgICAgICAgcmV0dXJuIHJhd25hbWU7Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgU3RyaW5nIGdldEF0dHJpYnV0ZShTdHJpbmcgbmFtZSkgewotCi0gICAgICAgIGZvciAoaW50IGk9MDsgaTxhdHRycy5sZW5ndGg7IGkrKykgewotICAgICAgICAgICAgaWYgKGF0dHJzW2ldLmdldE5hbWUoKS5lcXVhbHMobmFtZSkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gYXR0cnNbaV0uZ2V0VmFsdWUoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gIiI7Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgQXR0ciBnZXRBdHRyaWJ1dGVOb2RlKFN0cmluZyBuYW1lKSB7Ci0gICAgICAgIGZvciAoaW50IGk9MDsgaTxhdHRycy5sZW5ndGg7IGkrKykgewotICAgICAgICAgICAgaWYgKGF0dHJzW2ldLmdldE5hbWUoKS5lcXVhbHMobmFtZSkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gYXR0cnNbaV07Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgU3RyaW5nIGdldEF0dHJpYnV0ZU5TKFN0cmluZyBuYW1lc3BhY2VVUkksIFN0cmluZyBsb2NhbE5hbWUpIHsKLSAgICAgICAgZm9yIChpbnQgaT0wOyBpPGF0dHJzLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICBpZiAoYXR0cnNbaV0uZ2V0TG9jYWxOYW1lKCkuZXF1YWxzKGxvY2FsTmFtZSkgJiYgbnNFcXVhbHMoYXR0cnNbaV0uZ2V0TmFtZXNwYWNlVVJJKCksIG5hbWVzcGFjZVVSSSkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gYXR0cnNbaV0uZ2V0VmFsdWUoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gIiI7Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgQXR0ciBnZXRBdHRyaWJ1dGVOb2RlTlMoU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIGxvY2FsTmFtZSkgewotICAgICAgICBmb3IgKGludCBpPTA7IGk8YXR0cnMubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgIGlmIChhdHRyc1tpXS5nZXROYW1lKCkuZXF1YWxzKGxvY2FsTmFtZSkgJiYgbnNFcXVhbHMoYXR0cnNbaV0uZ2V0TmFtZXNwYWNlVVJJKCksIG5hbWVzcGFjZVVSSSkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gYXR0cnNbaV07Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgYm9vbGVhbiBoYXNBdHRyaWJ1dGUoU3RyaW5nIG5hbWUpIHsKLSAgICAgICAgZm9yIChpbnQgaT0wOyBpPGF0dHJzLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICBpZiAoYXR0cnNbaV0uZ2V0TmFtZSgpLmVxdWFscyhuYW1lKSkgewotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLQotICAgIHB1YmxpYyBib29sZWFuIGhhc0F0dHJpYnV0ZU5TKFN0cmluZyBuYW1lc3BhY2VVUkksIFN0cmluZyBsb2NhbE5hbWUpIHsKLSAgICAgICAgZm9yIChpbnQgaT0wOyBpPGF0dHJzLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICBpZiAoYXR0cnNbaV0uZ2V0TmFtZSgpLmVxdWFscyhsb2NhbE5hbWUpICYmIG5zRXF1YWxzKGF0dHJzW2ldLmdldE5hbWVzcGFjZVVSSSgpLCBuYW1lc3BhY2VVUkkpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotCi0gICAgcHVibGljIHZvaWQgc2V0QXR0cmlidXRlKFN0cmluZyBuYW1lLCBTdHJpbmcgdmFsdWUpIHsKLSAgICAgICAgZm9yIChpbnQgaT0wOyBpPGF0dHJzLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICBpZiAoYXR0cnNbaV0uZ2V0TmFtZSgpLmVxdWFscyhuYW1lKSkgewotICAgICAgICAgICAgICAgIGF0dHJzW2ldLnNldFZhbHVlKHZhbHVlKTsKLSAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKiogUmV0dXJucyB0aGUgbGluZSBudW1iZXIuICovCi0gICAgcHVibGljIGludCBnZXRMaW5lTnVtYmVyKCkgewotICAgICAgICByZXR1cm4gbGluZTsKLSAgICB9Ci0KLSAgICAvKiogUmV0dXJucyB0aGUgY29sdW1uIG51bWJlci4gKi8KLSAgICBwdWJsaWMgaW50IGdldENvbHVtbk51bWJlcigpIHsKLSAgICAgICAgcmV0dXJuIGNvbHVtbjsKLSAgICB9Ci0KLSAgICAvKiogUmV0dXJucyB0aGUgY2hhcmFjdGVyIG9mZnNldC4gKi8KLSAgICBwdWJsaWMgaW50IGdldENoYXJhY3Rlck9mZnNldCgpIHsKLSAgICAgICAgcmV0dXJuIGNoYXJPZmZzZXQ7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRBbm5vdGF0aW9uKCkgewotICAgICAgICByZXR1cm4gZkFubm90YXRpb247Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRTeW50aGV0aWNBbm5vdGF0aW9uKCkgewotICAgICAgICByZXR1cm4gZlN5bnRoZXRpY0Fubm90YXRpb247Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29tcGFyZXMgdHdvIG5hbWVzcGFjZSBVUklzIHdpdGggYW4gZXh0cmEgY2FzZSBmb3IgbnVsbCBlbnRyaWVzCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBuc0VxdWFscyhTdHJpbmcgbnNVUklfMSwgU3RyaW5nIG5zVVJJXzIpIHsKLSAgICAgICAgaWYgKG5zVVJJXzEgPT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIChuc1VSSV8yID09IG51bGwpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIG5zVVJJXzEuZXF1YWxzKG5zVVJJXzIpOwotICAgICAgICB9Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL29wdGkvTmFtZWROb2RlTWFwSW1wbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9vcHRpL05hbWVkTm9kZU1hcEltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZDMzMjk5OS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL29wdGkvTmFtZWROb2RlTWFwSW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsODggKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMSwgMjAwMiwyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMub3B0aTsKLQotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci1pbXBvcnQgb3JnLnczYy5kb20uQXR0cjsKLWltcG9ydCBvcmcudzNjLmRvbS5OYW1lZE5vZGVNYXA7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5ET01FeGNlcHRpb247Ci0KLQotLyoqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBSYWh1bCBTcml2YXN0YXZhLCBTdW4gTWljcm9zeXN0ZW1zIEluYy4KLSAqCi0gKi8KLXB1YmxpYyBjbGFzcyBOYW1lZE5vZGVNYXBJbXBsIGltcGxlbWVudHMgTmFtZWROb2RlTWFwIHsKLQotICAgICAgICBBdHRyW10gYXR0cnM7Ci0KLSAgICAgICAgcHVibGljIE5hbWVkTm9kZU1hcEltcGwoQXR0cltdIGF0dHJzKSB7Ci0gICAgICAgICAgICAgICAgdGhpcy5hdHRycyA9IGF0dHJzOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIE5vZGUgZ2V0TmFtZWRJdGVtKFN0cmluZyBuYW1lKSB7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaT0wOyBpPGF0dHJzLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXR0cnNbaV0uZ2V0TmFtZSgpLmVxdWFscyhuYW1lKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYXR0cnNbaV07Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIE5vZGUgaXRlbShpbnQgaW5kZXgpIHsKLSAgICAgICAgICAgICAgICBpZiAoaW5kZXggPCAwICYmIGluZGV4ID4gZ2V0TGVuZ3RoKCkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICByZXR1cm4gYXR0cnNbaW5kZXhdOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIGludCBnZXRMZW5ndGgoKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGF0dHJzLmxlbmd0aDsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyBOb2RlIGdldE5hbWVkSXRlbU5TKFN0cmluZyBuYW1lc3BhY2VVUkksIFN0cmluZyBsb2NhbE5hbWUpIHsKLSAgICAgICAgICAgICAgICBmb3IgKGludCBpPTA7IGk8YXR0cnMubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhdHRyc1tpXS5nZXROYW1lKCkuZXF1YWxzKGxvY2FsTmFtZSkgJiYgYXR0cnNbaV0uZ2V0TmFtZXNwYWNlVVJJKCkuZXF1YWxzKG5hbWVzcGFjZVVSSSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGF0dHJzW2ldOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyBOb2RlIHNldE5hbWVkSXRlbU5TKE5vZGUgYXJnKSB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUiwgIk1ldGhvZCBub3Qgc3VwcG9ydGVkIik7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgTm9kZSBzZXROYW1lZEl0ZW0oTm9kZSBhcmcpIHRocm93cyBET01FeGNlcHRpb24gewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSLCAiTWV0aG9kIG5vdCBzdXBwb3J0ZWQiKTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyBOb2RlIHJlbW92ZU5hbWVkSXRlbShTdHJpbmcgbmFtZSkgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIsICJNZXRob2Qgbm90IHN1cHBvcnRlZCIpOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIE5vZGUgcmVtb3ZlTmFtZWRJdGVtTlMoU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIGxvY2FsTmFtZSkgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIsICJNZXRob2Qgbm90IHN1cHBvcnRlZCIpOwotICAgICAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL29wdGkvTm9kZUltcGwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvb3B0aS9Ob2RlSW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1NTYyYzlmLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvb3B0aS9Ob2RlSW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsODcgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMSwgMjAwMiwyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMub3B0aTsKLQotLyoqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBSYWh1bCBTcml2YXN0YXZhLCBTdW4gTWljcm9zeXN0ZW1zIEluYy4KLSAqCi0gKi8KLXB1YmxpYyBjbGFzcyBOb2RlSW1wbCBleHRlbmRzIERlZmF1bHROb2RlIHsKLQotICAgIFN0cmluZyBwcmVmaXg7Ci0gICAgU3RyaW5nIGxvY2FscGFydDsKLSAgICBTdHJpbmcgcmF3bmFtZTsKLSAgICBTdHJpbmcgdXJpOwotICAgIHNob3J0IG5vZGVUeXBlOwotICAgIGJvb2xlYW4gaGlkZGVuOwotCi0KLSAgICBwdWJsaWMgTm9kZUltcGwoKSB7Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgTm9kZUltcGwoU3RyaW5nIHByZWZpeCwgU3RyaW5nIGxvY2FscGFydCwgU3RyaW5nIHJhd25hbWUsIFN0cmluZyB1cmksIHNob3J0IG5vZGVUeXBlKSB7Ci0gICAgICAgIHRoaXMucHJlZml4ID0gcHJlZml4OwotICAgICAgICB0aGlzLmxvY2FscGFydCA9IGxvY2FscGFydDsKLSAgICAgICAgdGhpcy5yYXduYW1lID0gcmF3bmFtZTsKLSAgICAgICAgdGhpcy51cmkgPSB1cmk7Ci0gICAgICAgIHRoaXMubm9kZVR5cGUgPSBub2RlVHlwZTsKLSAgICB9Ci0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Tm9kZU5hbWUoKSB7Ci0gICAgICAgIHJldHVybiByYXduYW1lOwotICAgIH0KLQotCi0gICAgcHVibGljIFN0cmluZyBnZXROYW1lc3BhY2VVUkkoKSB7Ci0gICAgICAgIHJldHVybiB1cmk7Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgU3RyaW5nIGdldFByZWZpeCgpIHsKLSAgICAgICAgcmV0dXJuIHByZWZpeDsKLSAgICB9Ci0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TG9jYWxOYW1lKCkgewotICAgICAgICByZXR1cm4gbG9jYWxwYXJ0OwotICAgIH0KLQotCi0gICAgcHVibGljIHNob3J0IGdldE5vZGVUeXBlKCkgewotICAgICAgICByZXR1cm4gbm9kZVR5cGU7Ci0gICAgfQotCi0KLSAgICAvLyBvdGhlciBtZXRob2RzCi0KLSAgICBwdWJsaWMgdm9pZCBzZXRSZWFkT25seShib29sZWFuIGhpZGUsIGJvb2xlYW4gZGVlcCkgewotICAgICAgICBoaWRkZW4gPSBoaWRlOwotICAgIH0KLQotCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0UmVhZE9ubHkoKSB7Ci0gICAgICAgIHJldHVybiBoaWRkZW47Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9vcHRpL1NjaGVtYURPTS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9vcHRpL1NjaGVtYURPTS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0OGQ2ZjEyLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvb3B0aS9TY2hlbWFET00uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQ2MSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5vcHRpOwotCi1pbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKLWltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuWE1MU3ltYm9sczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5OYW1lc3BhY2VDb250ZXh0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlFOYW1lOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTEF0dHJpYnV0ZXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MU3RyaW5nOwotaW1wb3J0IG9yZy53M2MuZG9tLkF0dHI7Ci1pbXBvcnQgb3JnLnczYy5kb20uRE9NSW1wbGVtZW50YXRpb247Ci1pbXBvcnQgb3JnLnczYy5kb20uRWxlbWVudDsKLWltcG9ydCBvcmcudzNjLmRvbS5OYW1lZE5vZGVNYXA7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLQotLyoqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBSYWh1bCBTcml2YXN0YXZhLCBTdW4gTWljcm9zeXN0ZW1zIEluYy4KLSAqIEBhdXRob3IgU2FuZHkgR2FvLCBJQk0KLSAqCi0gKiBAdmVyc2lvbiAkSWQ6IFNjaGVtYURPTS5qYXZhLHYgMS43IDIwMTAtMTEtMDEgMDQ6NDA6MDEgam9laHcgRXhwICQKLSAqLwotcHVibGljIGNsYXNzIFNjaGVtYURPTSBleHRlbmRzIERlZmF1bHREb2N1bWVudCB7Ci0KLSAgICBzdGF0aWMgZmluYWwgaW50IHJlbGF0aW9uc1Jvd1Jlc2l6ZUZhY3RvciA9IDE1OwotICAgIHN0YXRpYyBmaW5hbCBpbnQgcmVsYXRpb25zQ29sUmVzaXplRmFjdG9yID0gMTA7Ci0KLSAgICBOb2RlSW1wbFtdW10gcmVsYXRpb25zOwotICAgIC8vIHBhcmVudCBtdXN0IGJlIGFuIGVsZW1lbnQgaW4gdGhpcyBzY2hlbWUKLSAgICBFbGVtZW50SW1wbCBwYXJlbnQ7Ci0gICAgaW50IGN1cnJMb2M7Ci0gICAgaW50IG5leHRGcmVlTG9jOwotICAgIGJvb2xlYW4gaGlkZGVuOwotICAgIGJvb2xlYW4gaW5DREFUQTsKLQotICAgIC8vIGZvciBhbm5vdGF0aW9uIHN1cHBvcnQ6Ci0gICAgcHJpdmF0ZSBTdHJpbmdCdWZmZXIgZkFubm90YXRpb25CdWZmZXIgPSBudWxsOwotCi0gICAgcHVibGljIFNjaGVtYURPTSgpIHsKLSAgICAgICAgcmVzZXQoKTsKLSAgICB9Ci0KLQotICAgIHB1YmxpYyBFbGVtZW50SW1wbCBzdGFydEVsZW1lbnQoUU5hbWUgZWxlbWVudCwgWE1MQXR0cmlidXRlcyBhdHRyaWJ1dGVzLAotICAgICAgICAgICAgaW50IGxpbmUsIGludCBjb2x1bW4sIGludCBvZmZzZXQpIHsKLSAgICAgICAgRWxlbWVudEltcGwgbm9kZSA9IG5ldyBFbGVtZW50SW1wbChsaW5lLCBjb2x1bW4sIG9mZnNldCk7Ci0gICAgICAgIHByb2Nlc3NFbGVtZW50KGVsZW1lbnQsIGF0dHJpYnV0ZXMsIG5vZGUpOwotICAgICAgICAvLyBub3cgdGhlIGN1cnJlbnQgbm9kZSBhZGRlZCwgYmVjb21lcyB0aGUgcGFyZW50Ci0gICAgICAgIHBhcmVudCA9IG5vZGU7Ci0gICAgICAgIHJldHVybiBub2RlOwotICAgIH0KLQotICAgIHB1YmxpYyBFbGVtZW50SW1wbCBlbXB0eUVsZW1lbnQoUU5hbWUgZWxlbWVudCwgWE1MQXR0cmlidXRlcyBhdHRyaWJ1dGVzLAotICAgICAgICAgICAgaW50IGxpbmUsIGludCBjb2x1bW4sIGludCBvZmZzZXQpIHsKLSAgICAgICAgRWxlbWVudEltcGwgbm9kZSA9IG5ldyBFbGVtZW50SW1wbChsaW5lLCBjb2x1bW4sIG9mZnNldCk7Ci0gICAgICAgIHByb2Nlc3NFbGVtZW50KGVsZW1lbnQsIGF0dHJpYnV0ZXMsIG5vZGUpOwotICAgICAgICByZXR1cm4gbm9kZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgRWxlbWVudEltcGwgc3RhcnRFbGVtZW50KFFOYW1lIGVsZW1lbnQsIFhNTEF0dHJpYnV0ZXMgYXR0cmlidXRlcywKLSAgICAgICAgICAgIGludCBsaW5lLCBpbnQgY29sdW1uKSB7Ci0gICAgICAgIHJldHVybiBzdGFydEVsZW1lbnQoZWxlbWVudCwgYXR0cmlidXRlcywgbGluZSwgY29sdW1uLCAtMSk7Ci0gICAgfQotCi0gICAgcHVibGljIEVsZW1lbnRJbXBsIGVtcHR5RWxlbWVudChRTmFtZSBlbGVtZW50LCBYTUxBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMsCi0gICAgICAgICAgICBpbnQgbGluZSwgaW50IGNvbHVtbikgewotICAgICAgICByZXR1cm4gZW1wdHlFbGVtZW50KGVsZW1lbnQsIGF0dHJpYnV0ZXMsIGxpbmUsIGNvbHVtbiwgLTEpOwotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBwcm9jZXNzRWxlbWVudChRTmFtZSBlbGVtZW50LCBYTUxBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMsIEVsZW1lbnRJbXBsIG5vZGUpIHsKLQotICAgICAgICAvLyBwb3B1bGF0ZSBub2RlCi0gICAgICAgIG5vZGUucHJlZml4ID0gZWxlbWVudC5wcmVmaXg7Ci0gICAgICAgIG5vZGUubG9jYWxwYXJ0ID0gZWxlbWVudC5sb2NhbHBhcnQ7Ci0gICAgICAgIG5vZGUucmF3bmFtZSA9IGVsZW1lbnQucmF3bmFtZTsKLSAgICAgICAgbm9kZS51cmkgPSBlbGVtZW50LnVyaTsKLSAgICAgICAgbm9kZS5zY2hlbWFET00gPSB0aGlzOwotCi0gICAgICAgIC8vIHNldCB0aGUgYXR0cmlidXRlcwotICAgICAgICBBdHRyW10gYXR0cnMgPSBuZXcgQXR0clthdHRyaWJ1dGVzLmdldExlbmd0aCgpXTsKLSAgICAgICAgZm9yIChpbnQgaT0wOyBpPGF0dHJpYnV0ZXMuZ2V0TGVuZ3RoKCk7IGkrKykgewotICAgICAgICAgICAgYXR0cnNbaV0gPSBuZXcgQXR0ckltcGwobm9kZSwKLSAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlcy5nZXRQcmVmaXgoaSksCi0gICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXMuZ2V0TG9jYWxOYW1lKGkpLAotICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzLmdldFFOYW1lKGkpLAotICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzLmdldFVSSShpKSwKLSAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlcy5nZXRWYWx1ZShpKSk7Ci0gICAgICAgIH0KLSAgICAgICAgbm9kZS5hdHRycyA9IGF0dHJzOwotCi0gICAgICAgIC8vIGNoZWNrIGlmIGFycmF5IG5lZWRzIHRvIGJlIHJlc2l6ZWQKLSAgICAgICAgaWYgKG5leHRGcmVlTG9jID09IHJlbGF0aW9ucy5sZW5ndGgpIHsKLSAgICAgICAgICAgIHJlc2l6ZVJlbGF0aW9ucygpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gc3RvcmUgdGhlIGN1cnJlbnQgcGFyZW50Ci0gICAgICAgIC8vaWYgKHJlbGF0aW9uc1tjdXJyTG9jXVswXSA9PSBudWxsIHx8IHJlbGF0aW9uc1tjdXJyTG9jXVswXSAhPSBwYXJlbnQpIHsKLSAgICAgICAgaWYgKHJlbGF0aW9uc1tjdXJyTG9jXVswXSAhPSBwYXJlbnQpIHsKLSAgICAgICAgICAgIHJlbGF0aW9uc1tuZXh0RnJlZUxvY11bMF0gPSBwYXJlbnQ7Ci0gICAgICAgICAgICBjdXJyTG9jID0gbmV4dEZyZWVMb2MrKzsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIGFkZCB0aGUgY3VycmVudCBub2RlIGFzIGNoaWxkIG9mIHBhcmVudAotICAgICAgICBib29sZWFuIGZvdW5kUGxhY2UgPSBmYWxzZTsKLSAgICAgICAgaW50IGkgPSAxOwotICAgICAgICBmb3IgKGkgPSAxOyBpPHJlbGF0aW9uc1tjdXJyTG9jXS5sZW5ndGg7IGkrKykgewotICAgICAgICAgICAgaWYgKHJlbGF0aW9uc1tjdXJyTG9jXVtpXSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZm91bmRQbGFjZSA9IHRydWU7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoIWZvdW5kUGxhY2UpIHsKLSAgICAgICAgICAgIHJlc2l6ZVJlbGF0aW9ucyhjdXJyTG9jKTsKLSAgICAgICAgfQotICAgICAgICByZWxhdGlvbnNbY3VyckxvY11baV0gPSBub2RlOwotCi0gICAgICAgIHBhcmVudC5wYXJlbnRSb3cgPSBjdXJyTG9jOwotICAgICAgICBub2RlLnJvdyA9IGN1cnJMb2M7Ci0gICAgICAgIG5vZGUuY29sID0gaTsKLSAgICB9Ci0KLQotICAgIHB1YmxpYyB2b2lkIGVuZEVsZW1lbnQoKSAgewotICAgICAgICAvLyB0aGUgcGFyZW50IG9mIGN1cnJlbnQgcGFyZW50IG5vZGUgYmVjb21lcyB0aGUgcGFyZW50Ci0gICAgICAgIC8vIGZvciB0aGUgbmV4dCBub2RlLgotICAgICAgICBjdXJyTG9jID0gcGFyZW50LnJvdzsKLSAgICAgICAgcGFyZW50ID0gKEVsZW1lbnRJbXBsKXJlbGF0aW9uc1tjdXJyTG9jXVswXTsKLSAgICB9Ci0KLSAgICAvLyBub3RlIHRoYXQgdGhpcyB3aWxsIG9ubHkgYmUgY2FsbGVkIHdpdGhpbiBhcHBpbmZvL2RvY3VtZW50YXRpb24KLSAgICB2b2lkIGNvbW1lbnQoWE1MU3RyaW5nIHRleHQpIHsKLSAgICAgICAgZkFubm90YXRpb25CdWZmZXIuYXBwZW5kKCI8IS0tIik7Ci0gICAgICAgIGlmICh0ZXh0Lmxlbmd0aCA+IDApIHsKLSAgICAgICAgICAgIGZBbm5vdGF0aW9uQnVmZmVyLmFwcGVuZCh0ZXh0LmNoLCB0ZXh0Lm9mZnNldCwgdGV4dC5sZW5ndGgpOwotICAgICAgICB9Ci0gICAgICAgIGZBbm5vdGF0aW9uQnVmZmVyLmFwcGVuZCgiLS0+Iik7Ci0gICAgfQotCi0gICAgLy8gbm90ZSB0aGF0IHRoaXMgd2lsbCBvbmx5IGJlIGNhbGxlZCB3aXRoaW4gYXBwaW5mby9kb2N1bWVudGF0aW9uCi0gICAgdm9pZCBwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oU3RyaW5nIHRhcmdldCwgWE1MU3RyaW5nIGRhdGEpIHsKLSAgICAgICAgZkFubm90YXRpb25CdWZmZXIuYXBwZW5kKCI8PyIpLmFwcGVuZCh0YXJnZXQpOwotICAgICAgICBpZiAoZGF0YS5sZW5ndGggPiAwKSB7Ci0gICAgICAgICAgICBmQW5ub3RhdGlvbkJ1ZmZlci5hcHBlbmQoJyAnKS5hcHBlbmQoZGF0YS5jaCwgZGF0YS5vZmZzZXQsIGRhdGEubGVuZ3RoKTsKLSAgICAgICAgfQotICAgICAgICBmQW5ub3RhdGlvbkJ1ZmZlci5hcHBlbmQoIj8+Iik7Ci0gICAgfQotCi0gICAgLy8gbm90ZSB0aGF0IHRoaXMgd2lsbCBvbmx5IGJlIGNhbGxlZCB3aXRoaW4gYXBwaW5mby9kb2N1bWVudGF0aW9uCi0gICAgdm9pZCBjaGFyYWN0ZXJzKFhNTFN0cmluZyB0ZXh0KSB7Ci0KLSAgICAgICAgLy8gZXNjYXBlIGNoYXJhY3RlcnMgaWYgbmVjZXNzYXJ5Ci0gICAgICAgIGlmICghaW5DREFUQSkgewotICAgICAgICAgICAgZmluYWwgU3RyaW5nQnVmZmVyIGFubm90YXRpb25CdWZmZXIgPSBmQW5ub3RhdGlvbkJ1ZmZlcjsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSB0ZXh0Lm9mZnNldDsgaSA8IHRleHQub2Zmc2V0K3RleHQubGVuZ3RoOyArK2kpIHsKLSAgICAgICAgICAgICAgICBjaGFyIGNoID0gdGV4dC5jaFtpXTsKLSAgICAgICAgICAgICAgICBpZiAoY2ggPT0gJyYnKSB7Ci0gICAgICAgICAgICAgICAgICAgIGFubm90YXRpb25CdWZmZXIuYXBwZW5kKCImYW1wOyIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIGlmIChjaCA9PSAnPCcpIHsKLSAgICAgICAgICAgICAgICAgICAgYW5ub3RhdGlvbkJ1ZmZlci5hcHBlbmQoIiZsdDsiKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLy8gY2hhcmFjdGVyIHNlcXVlbmNlICJdXT4iIGNhbm5vdCBhcHBlYXIgaW4gY29udGVudCwKLSAgICAgICAgICAgICAgICAvLyB0aGVyZWZvcmUgd2Ugc2hvdWxkIGVzY2FwZSAnPicuCi0gICAgICAgICAgICAgICAgZWxzZSBpZiAoY2ggPT0gJz4nKSB7Ci0gICAgICAgICAgICAgICAgICAgIGFubm90YXRpb25CdWZmZXIuYXBwZW5kKCImZ3Q7Iik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIC8vIElmIENSIGlzIHBhcnQgb2YgdGhlIGRvY3VtZW50J3MgY29udGVudCwgaXQKLSAgICAgICAgICAgICAgICAvLyBtdXN0IG5vdCBiZSBwcmludGVkIGFzIGEgbGl0ZXJhbCBvdGhlcndpc2UKLSAgICAgICAgICAgICAgICAvLyBpdCB3b3VsZCBiZSBub3JtYWxpemVkIHRvIExGIHdoZW4gdGhlIGRvY3VtZW50Ci0gICAgICAgICAgICAgICAgLy8gaXMgcmVwYXJzZWQuCi0gICAgICAgICAgICAgICAgZWxzZSBpZiAoY2ggPT0gJ1xyJykgewotICAgICAgICAgICAgICAgICAgICBhbm5vdGF0aW9uQnVmZmVyLmFwcGVuZCgiJiN4RDsiKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIGFubm90YXRpb25CdWZmZXIuYXBwZW5kKGNoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBmQW5ub3RhdGlvbkJ1ZmZlci5hcHBlbmQodGV4dC5jaCwgdGV4dC5vZmZzZXQsIHRleHQubGVuZ3RoKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8vIG5vdGUgdGhhdCB0aGlzIHdpbGwgb25seSBiZSBjYWxsZWQgd2l0aGluIGFwcGluZm8vZG9jdW1lbnRhdGlvbgotICAgIHZvaWQgY2hhcmFjdGVyc1JhdyhTdHJpbmcgdGV4dCkgewotICAgICAgICBmQW5ub3RhdGlvbkJ1ZmZlci5hcHBlbmQodGV4dCk7Ci0gICAgfQotCi0gICAgdm9pZCBlbmRBbm5vdGF0aW9uKFFOYW1lIGVsZW1OYW1lLCBFbGVtZW50SW1wbCBhbm5vdGF0aW9uKSB7Ci0gICAgICAgIGZBbm5vdGF0aW9uQnVmZmVyLmFwcGVuZCgiXG48LyIpLmFwcGVuZChlbGVtTmFtZS5yYXduYW1lKS5hcHBlbmQoIj4iKTsKLSAgICAgICAgYW5ub3RhdGlvbi5mQW5ub3RhdGlvbiA9IGZBbm5vdGF0aW9uQnVmZmVyLnRvU3RyaW5nKCk7Ci0gICAgICAgIC8vIGFwcGFyZW50bHksIHRoZXJlIGlzIG5vIHNlbnNpYmxlIHdheSBvZiByZXNldHRpbmcgdGhlc2UgdGhpbmdzCi0gICAgICAgIGZBbm5vdGF0aW9uQnVmZmVyID0gbnVsbDsKLSAgICB9Ci0KLSAgICB2b2lkIGVuZEFubm90YXRpb25FbGVtZW50KFFOYW1lIGVsZW1OYW1lKSB7Ci0gICAgICAgIGVuZEFubm90YXRpb25FbGVtZW50KGVsZW1OYW1lLnJhd25hbWUpOwotICAgIH0KLQotICAgIHZvaWQgZW5kQW5ub3RhdGlvbkVsZW1lbnQoU3RyaW5nIGVsZW1SYXdOYW1lKSB7Ci0gICAgICAgIGZBbm5vdGF0aW9uQnVmZmVyLmFwcGVuZCgiPC8iKS5hcHBlbmQoZWxlbVJhd05hbWUpLmFwcGVuZCgiPiIpOwotICAgIH0KLQotICAgIHZvaWQgZW5kU3ludGhldGljQW5ub3RhdGlvbkVsZW1lbnQoUU5hbWUgZWxlbU5hbWUsIGJvb2xlYW4gY29tcGxldGUpIHsKLSAgICAgICAgZW5kU3ludGhldGljQW5ub3RhdGlvbkVsZW1lbnQoZWxlbU5hbWUucmF3bmFtZSwgY29tcGxldGUpOwotICAgIH0KLQotICAgIHZvaWQgZW5kU3ludGhldGljQW5ub3RhdGlvbkVsZW1lbnQoU3RyaW5nIGVsZW1SYXdOYW1lLCBib29sZWFuIGNvbXBsZXRlKSB7Ci0gICAgICAgIGlmKGNvbXBsZXRlKSB7Ci0gICAgICAgICAgICBmQW5ub3RhdGlvbkJ1ZmZlci5hcHBlbmQoIlxuPC8iKS5hcHBlbmQoZWxlbVJhd05hbWUpLmFwcGVuZCgiPiIpOwotICAgICAgICAgICAgLy8gbm90ZSB0aGF0IHRoaXMgaXMgYWx3YXlzIGNhbGxlZCBhZnRlciBlbmRFbGVtZW50IG9uIDxhbm5vdGF0aW9uPidzCi0gICAgICAgICAgICAvLyBjaGlsZCBhbmQgYmVmb3JlIGVuZEVsZW1lbnQgb24gYW5ub3RhdGlvbi4KLSAgICAgICAgICAgIC8vIGhlbmNlLCB3ZSBtdXN0IG1ha2UgdGhpcyB0aGUgY2hpbGQgb2YgdGhlIGN1cnJlbnQKLSAgICAgICAgICAgIC8vIHBhcmVudCdzIG9ubHkgY2hpbGQuCi0gICAgICAgICAgICBwYXJlbnQuZlN5bnRoZXRpY0Fubm90YXRpb24gPSBmQW5ub3RhdGlvbkJ1ZmZlci50b1N0cmluZygpOwotCi0gICAgICAgICAgICAvLyBhcHBhcmVudGx5LCB0aGVyZSBpcyBubyBzZW5zaWJsZSB3YXkgb2YgcmVzZXR0aW5nCi0gICAgICAgICAgICAvLyB0aGVzZSB0aGluZ3MKLSAgICAgICAgICAgIGZBbm5vdGF0aW9uQnVmZmVyID0gbnVsbDsKLSAgICAgICAgfSBlbHNlICAgICAgLy9jYXB0dXJpbmcgY2hhcmFjdGVyIGNhbGxzCi0gICAgICAgICAgICBmQW5ub3RhdGlvbkJ1ZmZlci5hcHBlbmQoIjwvIikuYXBwZW5kKGVsZW1SYXdOYW1lKS5hcHBlbmQoIj4iKTsKLSAgICB9Ci0KLSAgICB2b2lkIHN0YXJ0QW5ub3RhdGlvbkNEQVRBKCkgewotICAgICAgICBpbkNEQVRBID0gdHJ1ZTsKLSAgICAgICAgZkFubm90YXRpb25CdWZmZXIuYXBwZW5kKCI8IVtDREFUQVsiKTsKLSAgICB9Ci0KLSAgICB2b2lkIGVuZEFubm90YXRpb25DREFUQSgpIHsKLSAgICAgICAgZkFubm90YXRpb25CdWZmZXIuYXBwZW5kKCJdXT4iKTsKLSAgICAgICAgaW5DREFUQSA9IGZhbHNlOwotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCByZXNpemVSZWxhdGlvbnMoKSB7Ci0gICAgICAgIE5vZGVJbXBsW11bXSB0ZW1wID0gbmV3IE5vZGVJbXBsW3JlbGF0aW9ucy5sZW5ndGgrcmVsYXRpb25zUm93UmVzaXplRmFjdG9yXVtdOwotICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHJlbGF0aW9ucywgMCwgdGVtcCwgMCwgcmVsYXRpb25zLmxlbmd0aCk7Ci0gICAgICAgIGZvciAoaW50IGkgPSByZWxhdGlvbnMubGVuZ3RoIDsgaSA8IHRlbXAubGVuZ3RoIDsgaSsrKSB7Ci0gICAgICAgICAgICB0ZW1wW2ldID0gbmV3IE5vZGVJbXBsW3JlbGF0aW9uc0NvbFJlc2l6ZUZhY3Rvcl07Ci0gICAgICAgIH0KLSAgICAgICAgcmVsYXRpb25zID0gdGVtcDsKLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgcmVzaXplUmVsYXRpb25zKGludCBpKSB7Ci0gICAgICAgIE5vZGVJbXBsW10gdGVtcCA9IG5ldyBOb2RlSW1wbFtyZWxhdGlvbnNbaV0ubGVuZ3RoK3JlbGF0aW9uc0NvbFJlc2l6ZUZhY3Rvcl07Ci0gICAgICAgIFN5c3RlbS5hcnJheWNvcHkocmVsYXRpb25zW2ldLCAwLCB0ZW1wLCAwLCByZWxhdGlvbnNbaV0ubGVuZ3RoKTsKLSAgICAgICAgcmVsYXRpb25zW2ldID0gdGVtcDsKLSAgICB9Ci0KLQotICAgIHB1YmxpYyB2b2lkIHJlc2V0KCkgewotCi0gICAgICAgIC8vIGhlbHAgb3V0IHRoZSBnYXJiYWdlIGNvbGxlY3RvcgotICAgICAgICBpZihyZWxhdGlvbnMgIT0gbnVsbCkKLSAgICAgICAgICAgIGZvcihpbnQgaT0wOyBpPHJlbGF0aW9ucy5sZW5ndGg7IGkrKykKLSAgICAgICAgICAgICAgICBmb3IoaW50IGo9MDsgajxyZWxhdGlvbnNbaV0ubGVuZ3RoOyBqKyspCi0gICAgICAgICAgICAgICAgICAgIHJlbGF0aW9uc1tpXVtqXSA9IG51bGw7Ci0gICAgICAgIHJlbGF0aW9ucyA9IG5ldyBOb2RlSW1wbFtyZWxhdGlvbnNSb3dSZXNpemVGYWN0b3JdW107Ci0gICAgICAgIHBhcmVudCA9IG5ldyBFbGVtZW50SW1wbCgwLCAwLCAwKTsKLSAgICAgICAgcGFyZW50LnJhd25hbWUgPSAiRE9DVU1FTlRfTk9ERSI7Ci0gICAgICAgIGN1cnJMb2MgPSAwOwotICAgICAgICBuZXh0RnJlZUxvYyA9IDE7Ci0gICAgICAgIGluQ0RBVEEgPSBmYWxzZTsKLSAgICAgICAgZm9yIChpbnQgaT0wOyBpPHJlbGF0aW9uc1Jvd1Jlc2l6ZUZhY3RvcjsgaSsrKSB7Ci0gICAgICAgICAgICByZWxhdGlvbnNbaV0gPSBuZXcgTm9kZUltcGxbcmVsYXRpb25zQ29sUmVzaXplRmFjdG9yXTsKLSAgICAgICAgfQotICAgICAgICByZWxhdGlvbnNbY3VyckxvY11bMF0gPSBwYXJlbnQ7Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgdm9pZCBwcmludERPTSgpIHsKLSAgICAgICAgLyoKLSAgICAgICAgIGZvciAoaW50IGk9MDsgaTxyZWxhdGlvbnMubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgIGlmIChyZWxhdGlvbnNbaV1bMF0gIT0gbnVsbCkgewotICAgICAgICAgZm9yIChpbnQgaj0wOyBqPHJlbGF0aW9uc1tpXS5sZW5ndGg7IGorKykgewotICAgICAgICAgaWYgKHJlbGF0aW9uc1tpXVtqXSAhPSBudWxsKSB7Ci0gICAgICAgICBTeXN0ZW0ub3V0LnByaW50KHJlbGF0aW9uc1tpXVtqXS5ub2RlVHlwZSsiLSIrcmVsYXRpb25zW2ldW2pdLnBhcmVudFJvdysiICAiKTsKLSAgICAgICAgIH0KLSAgICAgICAgIH0KLSAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiIik7Ci0gICAgICAgICB9Ci0gICAgICAgICB9Ci0gICAgICAgICAqLwotICAgICAgICAvL3RyYXZlcnNlKGdldERvY3VtZW50RWxlbWVudCgpLCAwKTsKLSAgICB9Ci0KLQotICAgIC8vIGRlYnVnIG1ldGhvZHMKLQotICAgIHB1YmxpYyBzdGF0aWMgdm9pZCB0cmF2ZXJzZShOb2RlIG5vZGUsIGludCBkZXB0aCkgewotICAgICAgICBpbmRlbnQoZGVwdGgpOwotICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCI8Iitub2RlLmdldE5vZGVOYW1lKCkpOwotCi0gICAgICAgIGlmIChub2RlLmhhc0F0dHJpYnV0ZXMoKSkgewotICAgICAgICAgICAgTmFtZWROb2RlTWFwIGF0dHJzID0gbm9kZS5nZXRBdHRyaWJ1dGVzKCk7Ci0gICAgICAgICAgICBmb3IgKGludCBpPTA7IGk8YXR0cnMuZ2V0TGVuZ3RoKCk7IGkrKykgewotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIiAgIisoKEF0dHIpYXR0cnMuaXRlbShpKSkuZ2V0TmFtZSgpKyI9XCIiKygoQXR0cilhdHRycy5pdGVtKGkpKS5nZXRWYWx1ZSgpKyJcIiIpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKG5vZGUuaGFzQ2hpbGROb2RlcygpKSB7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIj4iKTsKLSAgICAgICAgICAgIGRlcHRoKz00OwotICAgICAgICAgICAgZm9yIChOb2RlIGNoaWxkID0gbm9kZS5nZXRGaXJzdENoaWxkKCk7IGNoaWxkICE9IG51bGw7IGNoaWxkID0gY2hpbGQuZ2V0TmV4dFNpYmxpbmcoKSkgewotICAgICAgICAgICAgICAgIHRyYXZlcnNlKGNoaWxkLCBkZXB0aCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBkZXB0aC09NDsKLSAgICAgICAgICAgIGluZGVudChkZXB0aCk7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIjwvIitub2RlLmdldE5vZGVOYW1lKCkrIj4iKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiLz4iKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBpbmRlbnQoaW50IGFtb3VudCkgewotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGFtb3VudDsgaSsrKSB7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCcgJyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvLyBvcmcudzNjLmRvbSBtZXRob2RzCi0gICAgcHVibGljIEVsZW1lbnQgZ2V0RG9jdW1lbnRFbGVtZW50KCkgewotICAgICAgICAvLyB0aGlzIHJldHVybnMgYSBwYXJlbnQgbm9kZSwga25vd24gdG8gYmUgYW4gRWxlbWVudEltcGwKLSAgICAgICAgcmV0dXJuIChFbGVtZW50SW1wbClyZWxhdGlvbnNbMF1bMV07Ci0gICAgfQotCi0gICAgcHVibGljIERPTUltcGxlbWVudGF0aW9uIGdldEltcGxlbWVudGF0aW9uKCkgewotICAgICAgICByZXR1cm4gU2NoZW1hRE9NSW1wbGVtZW50YXRpb24uZ2V0RE9NSW1wbGVtZW50YXRpb24oKTsKLSAgICB9Ci0KLSAgICAvLyBjb21tZW5jZSB0aGUgc2VyaWFsaXphdGlvbiBvZiBhbiBhbm5vdGF0aW9uCi0gICAgdm9pZCBzdGFydEFubm90YXRpb24oUU5hbWUgZWxlbU5hbWUsIFhNTEF0dHJpYnV0ZXMgYXR0cmlidXRlcywKLSAgICAgICAgICAgIE5hbWVzcGFjZUNvbnRleHQgbmFtZXNwYWNlQ29udGV4dCkgewotICAgICAgICBzdGFydEFubm90YXRpb24oZWxlbU5hbWUucmF3bmFtZSwgYXR0cmlidXRlcywgbmFtZXNwYWNlQ29udGV4dCk7Ci0gICAgfQotICAgIHZvaWQgc3RhcnRBbm5vdGF0aW9uKFN0cmluZyBlbGVtUmF3TmFtZSwgWE1MQXR0cmlidXRlcyBhdHRyaWJ1dGVzLAotICAgICAgICAgICAgTmFtZXNwYWNlQ29udGV4dCBuYW1lc3BhY2VDb250ZXh0KSB7Ci0gICAgICAgIGlmKGZBbm5vdGF0aW9uQnVmZmVyID09IG51bGwpIGZBbm5vdGF0aW9uQnVmZmVyID0gbmV3IFN0cmluZ0J1ZmZlcigyNTYpOwotICAgICAgICBmQW5ub3RhdGlvbkJ1ZmZlci5hcHBlbmQoIjwiKS5hcHBlbmQoZWxlbVJhd05hbWUpLmFwcGVuZCgiICIpOwotCi0gICAgICAgIC8vIGF0dHJpYnV0ZXMgYXJlIGEgYml0IG9mIGEgcGFpbi4gIFRvIGdldCB0aGlzIHJpZ2h0LCB3ZSBoYXZlIHRvIGtlZXAgdHJhY2sKLSAgICAgICAgLy8gb2YgdGhlIG5hbWVzcGFjZXMgd2UndmUgc2VlbiBkZWNsYXJlZCwgdGhlbiBleGFtaW5lIHRoZSBuYW1lc3BhY2UgY29udGV4dAotICAgICAgICAvLyBmb3Igb3RoZXIgbmFtZXNwYWNlcyBzbyB0aGF0IHdlIGNhbiBhbHNvIGluY2x1ZGUgdGhlbS4KLSAgICAgICAgLy8gb3B0aW1pemVkIGZvciBzaW1wbGljaXR5IGFuZCB0aGUgY2FzZSB0aGF0IG5vdCBtYW55Ci0gICAgICAgIC8vIG5hbWVzcGFjZXMgYXJlIGRlY2xhcmVkIG9uIHRoaXMgYW5ub3RhdGlvbi4uLgotICAgICAgICBBcnJheUxpc3QgbmFtZXNwYWNlcyA9IG5ldyBBcnJheUxpc3QoKTsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhdHRyaWJ1dGVzLmdldExlbmd0aCgpOyArK2kpIHsKLSAgICAgICAgICAgIFN0cmluZyBhVmFsdWUgPSBhdHRyaWJ1dGVzLmdldFZhbHVlKGkpOwotICAgICAgICAgICAgU3RyaW5nIGFQcmVmaXggPSBhdHRyaWJ1dGVzLmdldFByZWZpeChpKTsKLSAgICAgICAgICAgIFN0cmluZyBhUU5hbWUgPSBhdHRyaWJ1dGVzLmdldFFOYW1lKGkpOwotICAgICAgICAgICAgLy8gaWYgaXQncyB4bWxuczoqIG9yIHhtbG5zLCBtdXN0IGJlIGEgbmFtZXNwYWNlIGRlY2wKLSAgICAgICAgICAgIGlmIChhUHJlZml4ID09IFhNTFN5bWJvbHMuUFJFRklYX1hNTE5TIHx8IGFRTmFtZSA9PSBYTUxTeW1ib2xzLlBSRUZJWF9YTUxOUykgewotICAgICAgICAgICAgICAgIG5hbWVzcGFjZXMuYWRkKGFQcmVmaXggPT0gWE1MU3ltYm9scy5QUkVGSVhfWE1MTlMgPwotICAgICAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlcy5nZXRMb2NhbE5hbWUoaSkgOiBYTUxTeW1ib2xzLkVNUFRZX1NUUklORyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmQW5ub3RhdGlvbkJ1ZmZlci5hcHBlbmQoYVFOYW1lKS5hcHBlbmQoIj1cIiIpLmFwcGVuZChwcm9jZXNzQXR0VmFsdWUoYVZhbHVlKSkuYXBwZW5kKCJcIiAiKTsKLSAgICAgICAgfQotICAgICAgICAvLyBub3cgd2UgaGF2ZSB0byBsb29rIHRocm91Z2ggY3VycmVudGx5IGluLXNjb3BlIG5hbWVzcGFjZXMgdG8gc2VlIHdoYXQKLSAgICAgICAgLy8gd2Fzbid0IGRlY2xhcmVkIGhlcmUKLSAgICAgICAgRW51bWVyYXRpb24gY3VyclByZWZpeGVzID0gbmFtZXNwYWNlQ29udGV4dC5nZXRBbGxQcmVmaXhlcygpOwotICAgICAgICB3aGlsZShjdXJyUHJlZml4ZXMuaGFzTW9yZUVsZW1lbnRzKCkpIHsKLSAgICAgICAgICAgIFN0cmluZyBwcmVmaXggPSAoU3RyaW5nKWN1cnJQcmVmaXhlcy5uZXh0RWxlbWVudCgpOwotICAgICAgICAgICAgU3RyaW5nIHVyaSA9IG5hbWVzcGFjZUNvbnRleHQuZ2V0VVJJKHByZWZpeCk7Ci0gICAgICAgICAgICBpZiAodXJpID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICB1cmkgPSBYTUxTeW1ib2xzLkVNUFRZX1NUUklORzsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmICghbmFtZXNwYWNlcy5jb250YWlucyhwcmVmaXgpKSB7Ci0gICAgICAgICAgICAgICAgLy8gaGF2ZSB0byBkZWNsYXJlIHRoaXMgb25lCi0gICAgICAgICAgICAgICAgaWYocHJlZml4ID09IFhNTFN5bWJvbHMuRU1QVFlfU1RSSU5HKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZBbm5vdGF0aW9uQnVmZmVyLmFwcGVuZCgieG1sbnMiKS5hcHBlbmQoIj1cIiIpLmFwcGVuZChwcm9jZXNzQXR0VmFsdWUodXJpKSkuYXBwZW5kKCJcIiAiKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIGZBbm5vdGF0aW9uQnVmZmVyLmFwcGVuZCgieG1sbnM6IikuYXBwZW5kKHByZWZpeCkuYXBwZW5kKCI9XCIiKS5hcHBlbmQocHJvY2Vzc0F0dFZhbHVlKHVyaSkpLmFwcGVuZCgiXCIgIik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGZBbm5vdGF0aW9uQnVmZmVyLmFwcGVuZCgiPlxuIik7Ci0gICAgfQotICAgIHZvaWQgc3RhcnRBbm5vdGF0aW9uRWxlbWVudChRTmFtZSBlbGVtTmFtZSwgWE1MQXR0cmlidXRlcyBhdHRyaWJ1dGVzKSB7Ci0gICAgICAgIHN0YXJ0QW5ub3RhdGlvbkVsZW1lbnQoZWxlbU5hbWUucmF3bmFtZSwgYXR0cmlidXRlcyk7Ci0gICAgfQotICAgIHZvaWQgc3RhcnRBbm5vdGF0aW9uRWxlbWVudChTdHJpbmcgZWxlbVJhd05hbWUsIFhNTEF0dHJpYnV0ZXMgYXR0cmlidXRlcykgewotICAgICAgICBmQW5ub3RhdGlvbkJ1ZmZlci5hcHBlbmQoIjwiKS5hcHBlbmQoZWxlbVJhd05hbWUpOwotICAgICAgICBmb3IoaW50IGk9MDsgaTxhdHRyaWJ1dGVzLmdldExlbmd0aCgpOyBpKyspIHsKLSAgICAgICAgICAgIFN0cmluZyBhVmFsdWUgPSBhdHRyaWJ1dGVzLmdldFZhbHVlKGkpOwotICAgICAgICAgICAgZkFubm90YXRpb25CdWZmZXIuYXBwZW5kKCIgIikuYXBwZW5kKGF0dHJpYnV0ZXMuZ2V0UU5hbWUoaSkpLmFwcGVuZCgiPVwiIikuYXBwZW5kKHByb2Nlc3NBdHRWYWx1ZShhVmFsdWUpKS5hcHBlbmQoIlwiIik7Ci0gICAgICAgIH0KLSAgICAgICAgZkFubm90YXRpb25CdWZmZXIuYXBwZW5kKCI+Iik7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIHByb2Nlc3NBdHRWYWx1ZShTdHJpbmcgb3JpZ2luYWwpIHsKLSAgICAgICAgZmluYWwgaW50IGxlbmd0aCA9IG9yaWdpbmFsLmxlbmd0aCgpOwotICAgICAgICAvLyBub3JtYWxseSwgbm90aGluZyB3aWxsIGhhcHBlbgotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7Ci0gICAgICAgICAgICBjaGFyIGN1cnJDaGFyID0gb3JpZ2luYWwuY2hhckF0KGkpOwotICAgICAgICAgICAgaWYgKGN1cnJDaGFyID09ICciJyB8fCBjdXJyQ2hhciA9PSAnPCcgfHwgY3VyckNoYXIgPT0gJyYnIHx8Ci0gICAgICAgICAgICAgICAgICAgIGN1cnJDaGFyID09IDB4MDkgfHwgY3VyckNoYXIgPT0gMHgwQSB8fCBjdXJyQ2hhciA9PSAweDBEKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGVzY2FwZUF0dFZhbHVlKG9yaWdpbmFsLCBpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gb3JpZ2luYWw7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGVzY2FwZUF0dFZhbHVlKFN0cmluZyBvcmlnaW5hbCwgaW50IGZyb20pIHsKLSAgICAgICAgaW50IGk7Ci0gICAgICAgIGZpbmFsIGludCBsZW5ndGggPSBvcmlnaW5hbC5sZW5ndGgoKTsKLSAgICAgICAgU3RyaW5nQnVmZmVyIG5ld1ZhbCA9IG5ldyBTdHJpbmdCdWZmZXIobGVuZ3RoKTsKLSAgICAgICAgbmV3VmFsLmFwcGVuZChvcmlnaW5hbC5zdWJzdHJpbmcoMCwgZnJvbSkpOwotICAgICAgICBmb3IgKGkgPSBmcm9tOyBpIDwgbGVuZ3RoOyArK2kpIHsKLSAgICAgICAgICAgIGNoYXIgY3VyckNoYXIgPSBvcmlnaW5hbC5jaGFyQXQoaSk7Ci0gICAgICAgICAgICBpZiAoY3VyckNoYXIgPT0gJyInKSB7Ci0gICAgICAgICAgICAgICAgbmV3VmFsLmFwcGVuZCgiJnF1b3Q7Iik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChjdXJyQ2hhciA9PSAnPCcpIHsKLSAgICAgICAgICAgICAgICBuZXdWYWwuYXBwZW5kKCImbHQ7Iik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChjdXJyQ2hhciA9PSAnJicpIHsKLSAgICAgICAgICAgICAgICBuZXdWYWwuYXBwZW5kKCImYW1wOyIpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gTXVzdCBlc2NhcGUgMHgwOSwgMHgwQSBhbmQgMHgwRCBpZiB0aGV5IGFwcGVhciBpbiBhdHRyaWJ1dGUKLSAgICAgICAgICAgIC8vIHZhbHVlIHNvIHRoYXQgdGhleSBtYXkgYmUgcm91bmQtdHJpcHBlZC4gVGhleSB3b3VsZCBvdGhlcndpc2UKLSAgICAgICAgICAgIC8vIGJlIHRyYW5zZm9ybWVkIHRvIGEgMHgyMCBkdXJpbmcgYXR0cmlidXRlIHZhbHVlIG5vcm1hbGl6YXRpb24uCi0gICAgICAgICAgICBlbHNlIGlmIChjdXJyQ2hhciA9PSAweDA5KSB7Ci0gICAgICAgICAgICAgICAgbmV3VmFsLmFwcGVuZCgiJiN4OTsiKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKGN1cnJDaGFyID09IDB4MEEpIHsKLSAgICAgICAgICAgICAgICBuZXdWYWwuYXBwZW5kKCImI3hBOyIpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoY3VyckNoYXIgPT0gMHgwRCkgewotICAgICAgICAgICAgICAgIG5ld1ZhbC5hcHBlbmQoIiYjeEQ7Iik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBuZXdWYWwuYXBwZW5kKGN1cnJDaGFyKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbmV3VmFsLnRvU3RyaW5nKCk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9vcHRpL1NjaGVtYURPTUltcGxlbWVudGF0aW9uLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL29wdGkvU2NoZW1hRE9NSW1wbGVtZW50YXRpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMTA1ZTYzNi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL29wdGkvU2NoZW1hRE9NSW1wbGVtZW50YXRpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDY3ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCi0gKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKLSAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KLSAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCi0gKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAotICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLm9wdGk7Ci1pbXBvcnQgb3JnLnczYy5kb20uRE9NRXhjZXB0aW9uOwotaW1wb3J0IG9yZy53M2MuZG9tLkRPTUltcGxlbWVudGF0aW9uOwotaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50VHlwZTsKLQotLyoqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQHZlcnNpb24gJElkOiBTY2hlbWFET01JbXBsZW1lbnRhdGlvbi5qYXZhLHYgMS4yIDIwMTAtMTAtMjYgMjM6MDE6MTggam9laHcgRXhwICQKLSAqLwotZmluYWwgY2xhc3MgU2NoZW1hRE9NSW1wbGVtZW50YXRpb24gaW1wbGVtZW50cyBET01JbXBsZW1lbnRhdGlvbiB7Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTY2hlbWFET01JbXBsZW1lbnRhdGlvbiBzaW5nbGV0b24gPSBuZXcgU2NoZW1hRE9NSW1wbGVtZW50YXRpb24oKTsKLQotICAgIC8qKiBOT04tRE9NOiBPYnRhaW4gYW5kIHJldHVybiB0aGUgc2luZ2xlIHNoYXJlZCBvYmplY3QgKi8KLSAgICBwdWJsaWMgc3RhdGljIERPTUltcGxlbWVudGF0aW9uIGdldERPTUltcGxlbWVudGF0aW9uKCkgewotICAgICAgICByZXR1cm4gc2luZ2xldG9uOwotICAgIH0KLQotICAgIHByaXZhdGUgU2NoZW1hRE9NSW1wbGVtZW50YXRpb24oKSB7fQotCi0gICAgcHVibGljIERvY3VtZW50IGNyZWF0ZURvY3VtZW50KFN0cmluZyBuYW1lc3BhY2VVUkksIFN0cmluZyBxdWFsaWZpZWROYW1lLCBEb2N1bWVudFR5cGUgZG9jdHlwZSkKLSAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb24gewotICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUiwgIk1ldGhvZCBub3Qgc3VwcG9ydGVkIik7Ci0gICAgfQotCi0gICAgcHVibGljIERvY3VtZW50VHlwZSBjcmVhdGVEb2N1bWVudFR5cGUoU3RyaW5nIHF1YWxpZmllZE5hbWUsIFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkKQotICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0gICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSLCAiTWV0aG9kIG5vdCBzdXBwb3J0ZWQiKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgT2JqZWN0IGdldEZlYXR1cmUoU3RyaW5nIGZlYXR1cmUsIFN0cmluZyB2ZXJzaW9uKSB7Ci0gICAgICAgIGlmIChzaW5nbGV0b24uaGFzRmVhdHVyZShmZWF0dXJlLCB2ZXJzaW9uKSkgewotICAgICAgICAgICAgcmV0dXJuIHNpbmdsZXRvbjsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBoYXNGZWF0dXJlKFN0cmluZyBmZWF0dXJlLCBTdHJpbmcgdmVyc2lvbikgewotICAgICAgICBmaW5hbCBib29sZWFuIGFueVZlcnNpb24gPSB2ZXJzaW9uID09IG51bGwgfHwgdmVyc2lvbi5sZW5ndGgoKSA9PSAwOwotICAgICAgICByZXR1cm4gKGZlYXR1cmUuZXF1YWxzSWdub3JlQ2FzZSgiQ29yZSIpIHx8IGZlYXR1cmUuZXF1YWxzSWdub3JlQ2FzZSgiWE1MIikpICYmCi0gICAgICAgICAgICAoYW55VmVyc2lvbiB8fCB2ZXJzaW9uLmVxdWFscygiMS4wIikgfHwgdmVyc2lvbi5lcXVhbHMoIjIuMCIpIHx8IHZlcnNpb24uZXF1YWxzKCIzLjAiKSk7Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL29wdGkvU2NoZW1hRE9NUGFyc2VyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL29wdGkvU2NoZW1hRE9NUGFyc2VyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGJlMjhjOGMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9vcHRpL1NjaGVtYURPTVBhcnNlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNjExICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLm9wdGk7Ci0KLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLkNvbnN0YW50czsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuWE1MRXJyb3JSZXBvcnRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMuU2NoZW1hU3ltYm9sczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMuWFNNZXNzYWdlRm9ybWF0dGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5YTUxBdHRyaWJ1dGVzSW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuWE1MQ2hhcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5BdWdtZW50YXRpb25zOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLk5hbWVzcGFjZUNvbnRleHQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuUU5hbWU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MQXR0cmlidXRlczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxMb2NhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTFN0cmluZzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTklFeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTEVudGl0eVJlc29sdmVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxJbnB1dFNvdXJjZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MUGFyc2VyQ29uZmlndXJhdGlvbjsKLWltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKLQotLyoqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBSYWh1bCBTcml2YXN0YXZhLCBTdW4gTWljcm9zeXN0ZW1zIEluYy4KLSAqIEBhdXRob3IgU2FuZHkgR2FvLCBJQk0KLSAqCi0gKiBAdmVyc2lvbiAkSWQ6IFNjaGVtYURPTVBhcnNlci5qYXZhLHYgMS44IDIwMTAtMTEtMDEgMDQ6NDA6MDEgam9laHcgRXhwICQKLSAqLwotcHVibGljIGNsYXNzIFNjaGVtYURPTVBhcnNlciBleHRlbmRzIERlZmF1bHRYTUxEb2N1bWVudEhhbmRsZXIgewotCi0gICAgLy8KLSAgICAvLyBEYXRhCi0gICAgLy8KLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBlcnJvciByZXBvcnRlci4gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJPUl9SRVBPUlRFUiA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLkVSUk9SX1JFUE9SVEVSX1BST1BFUlRZOwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogZ2VuZXJhdGUgc3ludGhldGljIGFubm90YXRpb25zLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEdFTkVSQVRFX1NZTlRIRVRJQ19BTk5PVEFUSU9OID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5HRU5FUkFURV9TWU5USEVUSUNfQU5OT1RBVElPTlNfRkVBVFVSRTsKLQotICAgIC8vIHRoZSBsb2NhdG9yIGNvbnRhaW5pbmcgbGluZS9jb2x1bW4gaW5mb3JtYXRpb24KLSAgICBwcm90ZWN0ZWQgWE1MTG9jYXRvciAgIGZMb2NhdG9yOwotCi0gICAgLy8gbmFtZXNwYWNlIGNvbnRleHQsIG5lZWRlZCBmb3IgcHJvZHVjaW5nCi0gICAgLy8gcmVwcmVzZW50YXRpb25zIG9mIGFubm90YXRpb25zCi0gICAgcHJvdGVjdGVkIE5hbWVzcGFjZUNvbnRleHQgZk5hbWVzcGFjZUNvbnRleHQgPSBudWxsOwotCi0gICAgU2NoZW1hRE9NIHNjaGVtYURPTTsKLQotICAgIFhNTFBhcnNlckNvbmZpZ3VyYXRpb24gY29uZmlnOwotCi0gICAgLy8KLSAgICAvLyBDb25zdHJ1Y3RvcnMKLSAgICAvLwotCi0gICAgLyoqIERlZmF1bHQgY29uc3RydWN0b3IuICovCi0gICAgcHVibGljIFNjaGVtYURPTVBhcnNlcihYTUxQYXJzZXJDb25maWd1cmF0aW9uIGNvbmZpZykgewotICAgICAgICB0aGlzLmNvbmZpZyA9IGNvbmZpZzsKLSAgICAgICAgY29uZmlnLnNldERvY3VtZW50SGFuZGxlcih0aGlzKTsKLSAgICAgICAgY29uZmlnLnNldERUREhhbmRsZXIodGhpcyk7Ci0gICAgICAgIGNvbmZpZy5zZXREVERDb250ZW50TW9kZWxIYW5kbGVyKHRoaXMpOwotICAgIH0KLQotICAgIC8vIFJlZmVyZW5jZSB0byB0aGUgY3VycmVudCBhbm5vdGF0aW9uIGVsZW1lbnQuCi0gICAgcHJpdmF0ZSBFbGVtZW50SW1wbCBmQ3VycmVudEFubm90YXRpb25FbGVtZW50OwotICAgIC8vIHdoZXJlIGFuIGFubm90YXRpb24gZWxlbWVudCBpdHNlbGYgYmVnaW5zCi0gICAgLy8gLTEgbWVhbnMgbm90IGluIGFuIGFubm90YXRpb24ncyBzY29wZQotICAgIHByaXZhdGUgaW50IGZBbm5vdGF0aW9uRGVwdGggPSAtMTsKLSAgICAvLyBXaGVyZSB4czphcHBpbmZvIG9yIHhzOmRvY3VtZW50YXRpb24gc3RhcnRzOwotICAgIC8vIC0xIG1lYW5zIG5vdCBpbiB0aGUgc2NvcGUgb2YgZWl0aGVyIG9mIHRoZSB0d28gZWxlbWVudHMuCi0gICAgcHJpdmF0ZSBpbnQgZklubmVyQW5ub3RhdGlvbkRlcHRoID0gLTE7Ci0gICAgLy8gVGhlIGN1cnJlbnQgZWxlbWVudCBkZXB0aAotICAgIHByaXZhdGUgaW50IGZEZXB0aCA9IC0xOwotICAgIC8vIFVzZSB0byByZXBvcnQgdGhlIGVycm9yIHdoZW4gY2hhcmFjdGVycyBhcmUgbm90IGFsbG93ZWQuCi0gICAgWE1MRXJyb3JSZXBvcnRlciBmRXJyb3JSZXBvcnRlcjsKLQotICAgIC8vIGZpZWxkcyBmb3IgZ2VuZXJhdGUtc3ludGhldGljIGFubm90YXRpb25zIGZlYXR1cmUKLSAgICBwcml2YXRlIGJvb2xlYW4gZkdlbmVyYXRlU3ludGhldGljQW5ub3RhdGlvbiA9IGZhbHNlOwotICAgIHByaXZhdGUgQm9vbGVhblN0YWNrIGZIYXNOb25TY2hlbWFBdHRyaWJ1dGVzID0gbmV3IEJvb2xlYW5TdGFjaygpOwotICAgIHByaXZhdGUgQm9vbGVhblN0YWNrIGZTYXdBbm5vdGF0aW9uID0gbmV3IEJvb2xlYW5TdGFjaygpOwotICAgIHByaXZhdGUgWE1MQXR0cmlidXRlcyBmRW1wdHlBdHRyID0gbmV3IFhNTEF0dHJpYnV0ZXNJbXBsKCk7Ci0KLSAgICAvLwotICAgIC8vIFhNTERvY3VtZW50SGFuZGxlciBtZXRob2RzCi0gICAgLy8KLQotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RG9jdW1lbnQoWE1MTG9jYXRvciBsb2NhdG9yLCBTdHJpbmcgZW5jb2RpbmcsCi0gICAgICAgICAgICBOYW1lc3BhY2VDb250ZXh0IG5hbWVzcGFjZUNvbnRleHQsIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgZkVycm9yUmVwb3J0ZXIgPSAoWE1MRXJyb3JSZXBvcnRlciljb25maWcuZ2V0UHJvcGVydHkoRVJST1JfUkVQT1JURVIpOwotICAgICAgICBmR2VuZXJhdGVTeW50aGV0aWNBbm5vdGF0aW9uID0gY29uZmlnLmdldEZlYXR1cmUoR0VORVJBVEVfU1lOVEhFVElDX0FOTk9UQVRJT04pOwotICAgICAgICBmSGFzTm9uU2NoZW1hQXR0cmlidXRlcy5jbGVhcigpOwotICAgICAgICBmU2F3QW5ub3RhdGlvbi5jbGVhcigpOwotICAgICAgICBzY2hlbWFET00gPSBuZXcgU2NoZW1hRE9NKCk7Ci0gICAgICAgIGZDdXJyZW50QW5ub3RhdGlvbkVsZW1lbnQgPSBudWxsOwotICAgICAgICBmQW5ub3RhdGlvbkRlcHRoID0gLTE7Ci0gICAgICAgIGZJbm5lckFubm90YXRpb25EZXB0aCA9IC0xOwotICAgICAgICBmRGVwdGggPSAtMTsKLSAgICAgICAgZkxvY2F0b3IgPSBsb2NhdG9yOwotICAgICAgICBmTmFtZXNwYWNlQ29udGV4dCA9IG5hbWVzcGFjZUNvbnRleHQ7Ci0gICAgICAgIHNjaGVtYURPTS5zZXREb2N1bWVudFVSSShsb2NhdG9yLmdldEV4cGFuZGVkU3lzdGVtSWQoKSk7Ci0gICAgfSAvLyBzdGFydERvY3VtZW50KFhNTExvY2F0b3IsU3RyaW5nLE5hbWVzcGFjZUNvbnRleHQsIEF1Z21lbnRhdGlvbnMpCi0KLSAgICAvKioKLSAgICAgKiBUaGUgZW5kIG9mIHRoZSBkb2N1bWVudC4KLSAgICAgKiBAcGFyYW0gYXVncyAgICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZERvY3VtZW50KEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIC8vIFRvIGRlYnVnIHRoZSBET00gY3JlYXRlZCB1bmNvbW1lbnQgdGhlIGxpbmUgYmVsb3cKLSAgICAgICAgLy8gc2NoZW1hRE9NLnByaW50RE9NKCk7Ci0gICAgfSAvLyBlbmREb2N1bWVudCgpCi0KLQotICAgIC8qKgotICAgICAqIEEgY29tbWVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSB0ZXh0ICAgVGhlIHRleHQgaW4gdGhlIGNvbW1lbnQuCi0gICAgICogQHBhcmFtIGF1Z3MgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIFhOSUV4Y2VwdGlvbgotICAgICAqICAgICAgICAgICAgICAgICAgIFRocm93biBieSBhcHBsaWNhdGlvbiB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY29tbWVudChYTUxTdHJpbmcgdGV4dCwgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgaWYoZkFubm90YXRpb25EZXB0aCA+IC0xKSB7Ci0gICAgICAgICAgICBzY2hlbWFET00uY29tbWVudCh0ZXh0KTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEEgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbi4gUHJvY2Vzc2luZyBpbnN0cnVjdGlvbnMgY29uc2lzdCBvZiBhCi0gICAgICogdGFyZ2V0IG5hbWUgYW5kLCBvcHRpb25hbGx5LCB0ZXh0IGRhdGEuIFRoZSBkYXRhIGlzIG9ubHkgbWVhbmluZ2Z1bAotICAgICAqIHRvIHRoZSBhcHBsaWNhdGlvbi4KLSAgICAgKiA8cD4KLSAgICAgKiBUeXBpY2FsbHksIGEgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbidzIGRhdGEgd2lsbCBjb250YWluIGEgc2VyaWVzCi0gICAgICogb2YgcHNldWRvLWF0dHJpYnV0ZXMuIFRoZXNlIHBzZXVkby1hdHRyaWJ1dGVzIGZvbGxvdyB0aGUgZm9ybSBvZgotICAgICAqIGVsZW1lbnQgYXR0cmlidXRlcyBidXQgYXJlIDxzdHJvbmc+bm90PC9zdHJvbmc+IHBhcnNlZCBvciBwcmVzZW50ZWQKLSAgICAgKiB0byB0aGUgYXBwbGljYXRpb24gYXMgYW55dGhpbmcgb3RoZXIgdGhhbiB0ZXh0LiBUaGUgYXBwbGljYXRpb24gaXMKLSAgICAgKiByZXNwb25zaWJsZSBmb3IgcGFyc2luZyB0aGUgZGF0YS4KLSAgICAgKgotICAgICAqIEBwYXJhbSB0YXJnZXQgVGhlIHRhcmdldC4KLSAgICAgKiBAcGFyYW0gZGF0YSAgIFRoZSBkYXRhIG9yIG51bGwgaWYgbm9uZSBzcGVjaWZpZWQuCi0gICAgICogQHBhcmFtIGF1Z3MgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIFhOSUV4Y2VwdGlvbgotICAgICAqICAgICAgICAgICAgICAgICAgIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oU3RyaW5nIHRhcmdldCwgWE1MU3RyaW5nIGRhdGEsIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKGZBbm5vdGF0aW9uRGVwdGggPiAtMSkgewotICAgICAgICAgICAgc2NoZW1hRE9NLnByb2Nlc3NpbmdJbnN0cnVjdGlvbih0YXJnZXQsIGRhdGEpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ2hhcmFjdGVyIGNvbnRlbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdGV4dCAgIFRoZSBjb250ZW50LgotICAgICAqIEBwYXJhbSBhdWdzICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBYTklFeGNlcHRpb24KLSAgICAgKiAgICAgICAgICAgICAgICAgICBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY2hhcmFjdGVycyhYTUxTdHJpbmcgdGV4dCwgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgLy8gd2hlbiBpdCdzIG5vdCB3aXRoaW4geHM6YXBwaW5mbyBvciB4czpkb2N1bWVudGF0aW9uCi0gICAgICAgIGlmIChmSW5uZXJBbm5vdGF0aW9uRGVwdGggPT0gLTEgKSB7Ci0gICAgICAgICAgICBmb3IgKGludCBpPXRleHQub2Zmc2V0OyBpPHRleHQub2Zmc2V0K3RleHQubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgICAgICAvLyBhbmQgdGhlcmUgaXMgYSBub24td2hpdGVzcGFjZSBjaGFyYWN0ZXIKLSAgICAgICAgICAgICAgICBpZiAoIVhNTENoYXIuaXNTcGFjZSh0ZXh0LmNoW2ldKSkgewotICAgICAgICAgICAgICAgICAgICAvLyB0aGUgc3RyaW5nIHdlIHNhdzogc3RhcnRpbmcgZnJvbSB0aGUgZmlyc3Qgbm9uLXdoaXRlc3BhY2UgY2hhcmFjdGVyLgotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdHh0ID0gbmV3IFN0cmluZyh0ZXh0LmNoLCBpLCB0ZXh0Lmxlbmd0aCt0ZXh0Lm9mZnNldC1pKTsKLSAgICAgICAgICAgICAgICAgICAgLy8gcmVwb3J0IGFuIGVycm9yCi0gICAgICAgICAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKGZMb2NhdG9yLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhTTWVzc2FnZUZvcm1hdHRlci5TQ0hFTUFfRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICJzNHMtZWx0LWNoYXJhY3RlciIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde3R4dH0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9FUlJPUik7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIGRvbid0IGNhbGwgc3VwZXIuY2hhcmFjdGVycygpIHdoZW4gaXQncyBub3Qgd2l0aGluIG9uZSBvZiB0aGUgMgotICAgICAgICAgICAgLy8gYW5ub3RhdGlvbiBlbGVtZW50czogdGhlIHRyYXZlcnNlcnMgaWdub3JlIHRoZW0gYW55d2F5LiBXZSBjYW4KLSAgICAgICAgICAgIC8vIHNhdmUgdGltZS9tZW1vcnkgY3JlYXRpbmcgdGhlIHRleHQgbm9kZXMuCi0gICAgICAgIH0KLSAgICAgICAgLy8gd2hlbiBpdCdzIHdpdGhpbiBlaXRoZXIgb2YgdGhlIDIgZWxlbWVudHMsIGNoYXJhY3RlcnMgYXJlIGFsbG93ZWQKLSAgICAgICAgLy8gYW5kIHdlIG5lZWQgdG8gc3RvcmUgdGhlbS4KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBzY2hlbWFET00uY2hhcmFjdGVycyh0ZXh0KTsKLSAgICAgICAgfQotCi0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBUaGUgc3RhcnQgb2YgYW4gZWxlbWVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlbGVtZW50ICAgIFRoZSBuYW1lIG9mIHRoZSBlbGVtZW50LgotICAgICAqIEBwYXJhbSBhdHRyaWJ1dGVzIFRoZSBlbGVtZW50IGF0dHJpYnV0ZXMuCi0gICAgICogQHBhcmFtIGF1Z3MgICAgICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBYTklFeGNlcHRpb24KLSAgICAgKiAgICAgICAgICAgICAgICAgICBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnRFbGVtZW50KFFOYW1lIGVsZW1lbnQsIFhNTEF0dHJpYnV0ZXMgYXR0cmlidXRlcywgQXVnbWVudGF0aW9ucyBhdWdzKQotICAgIHRocm93cyBYTklFeGNlcHRpb24gewotCi0gICAgICAgIGZEZXB0aCsrOwotICAgICAgICAvLyB3aGlsZSBpdCBpcyB0cnVlIHRoYXQgbm9uLXdoaXRlc3BhY2UgY2hhcmFjdGVyIGRhdGEKLSAgICAgICAgLy8gbWF5IG9ubHkgb2NjdXIgaW4gYXBwSW5mbyBvciBkb2N1bWVudGF0aW9uCi0gICAgICAgIC8vIGVsZW1lbnRzLCBpdCdzIGNlcnRhaW5seSBsZWdhbCBmb3IgY29tbWVudHMgYW5kIFBJJ3MgdG8KLSAgICAgICAgLy8gb2NjdXIgYXMgY2hpbGRyZW4gb2YgYW5ub3RhdGlvbjsgd2UgbmVlZAotICAgICAgICAvLyB0byBhY2NvdW50IGZvciB0aGVzZSBoZXJlLgotICAgICAgICBpZiAoZkFubm90YXRpb25EZXB0aCA9PSAtMSkgewotICAgICAgICAgICAgaWYgKGVsZW1lbnQudXJpID09IFNjaGVtYVN5bWJvbHMuVVJJX1NDSEVNQUZPUlNDSEVNQSAmJgotICAgICAgICAgICAgICAgICAgICBlbGVtZW50LmxvY2FscGFydCA9PSBTY2hlbWFTeW1ib2xzLkVMVF9BTk5PVEFUSU9OKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGZHZW5lcmF0ZVN5bnRoZXRpY0Fubm90YXRpb24pIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGZTYXdBbm5vdGF0aW9uLnNpemUoKSA+IDApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZTYXdBbm5vdGF0aW9uLnBvcCgpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGZTYXdBbm5vdGF0aW9uLnB1c2godHJ1ZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGZBbm5vdGF0aW9uRGVwdGggPSBmRGVwdGg7Ci0gICAgICAgICAgICAgICAgc2NoZW1hRE9NLnN0YXJ0QW5ub3RhdGlvbihlbGVtZW50LCBhdHRyaWJ1dGVzLCBmTmFtZXNwYWNlQ29udGV4dCk7Ci0gICAgICAgICAgICAgICAgZkN1cnJlbnRBbm5vdGF0aW9uRWxlbWVudCA9IHNjaGVtYURPTS5zdGFydEVsZW1lbnQoZWxlbWVudCwgYXR0cmlidXRlcywKLSAgICAgICAgICAgICAgICAgICAgICAgIGZMb2NhdG9yLmdldExpbmVOdW1iZXIoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgIGZMb2NhdG9yLmdldENvbHVtbk51bWJlcigpLAotICAgICAgICAgICAgICAgICAgICAgICAgZkxvY2F0b3IuZ2V0Q2hhcmFjdGVyT2Zmc2V0KCkpOwotICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKGVsZW1lbnQudXJpID09IFNjaGVtYVN5bWJvbHMuVVJJX1NDSEVNQUZPUlNDSEVNQSAmJiBmR2VuZXJhdGVTeW50aGV0aWNBbm5vdGF0aW9uKSB7Ci0gICAgICAgICAgICAgICAgZlNhd0Fubm90YXRpb24ucHVzaChmYWxzZSk7Ci0gICAgICAgICAgICAgICAgZkhhc05vblNjaGVtYUF0dHJpYnV0ZXMucHVzaChoYXNOb25TY2hlbWFBdHRyaWJ1dGVzKGVsZW1lbnQsIGF0dHJpYnV0ZXMpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChmRGVwdGggPT0gZkFubm90YXRpb25EZXB0aCArIDEpIHsKLSAgICAgICAgICAgIGZJbm5lckFubm90YXRpb25EZXB0aCA9IGZEZXB0aDsKLSAgICAgICAgICAgIHNjaGVtYURPTS5zdGFydEFubm90YXRpb25FbGVtZW50KGVsZW1lbnQsIGF0dHJpYnV0ZXMpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgc2NoZW1hRE9NLnN0YXJ0QW5ub3RhdGlvbkVsZW1lbnQoZWxlbWVudCwgYXR0cmlidXRlcyk7Ci0gICAgICAgICAgICAvLyBhdm9pZCBmYWxsaW5nIHRocm91Z2g7IGRvbid0IGNhbGwgc3RhcnRFbGVtZW50IGluIHRoaXMgY2FzZQotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0gICAgICAgIHNjaGVtYURPTS5zdGFydEVsZW1lbnQoZWxlbWVudCwgYXR0cmlidXRlcywKLSAgICAgICAgICAgICAgICBmTG9jYXRvci5nZXRMaW5lTnVtYmVyKCksCi0gICAgICAgICAgICAgICAgZkxvY2F0b3IuZ2V0Q29sdW1uTnVtYmVyKCksCi0gICAgICAgICAgICAgICAgZkxvY2F0b3IuZ2V0Q2hhcmFjdGVyT2Zmc2V0KCkpOwotCi0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBBbiBlbXB0eSBlbGVtZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIGVsZW1lbnQgICAgVGhlIG5hbWUgb2YgdGhlIGVsZW1lbnQuCi0gICAgICogQHBhcmFtIGF0dHJpYnV0ZXMgVGhlIGVsZW1lbnQgYXR0cmlidXRlcy4KLSAgICAgKiBAcGFyYW0gYXVncyAgICAgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIFhOSUV4Y2VwdGlvbgotICAgICAqICAgICAgICAgICAgICAgICAgIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbXB0eUVsZW1lbnQoUU5hbWUgZWxlbWVudCwgWE1MQXR0cmlidXRlcyBhdHRyaWJ1dGVzLCBBdWdtZW50YXRpb25zIGF1Z3MpCi0gICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgaWYgKGZHZW5lcmF0ZVN5bnRoZXRpY0Fubm90YXRpb24gJiYgZkFubm90YXRpb25EZXB0aCA9PSAtMSAmJgotICAgICAgICAgICAgICAgIGVsZW1lbnQudXJpID09IFNjaGVtYVN5bWJvbHMuVVJJX1NDSEVNQUZPUlNDSEVNQSAmJiBlbGVtZW50LmxvY2FscGFydCAhPSBTY2hlbWFTeW1ib2xzLkVMVF9BTk5PVEFUSU9OICYmIGhhc05vblNjaGVtYUF0dHJpYnV0ZXMoZWxlbWVudCwgYXR0cmlidXRlcykpIHsKLQotICAgICAgICAgICAgc2NoZW1hRE9NLnN0YXJ0RWxlbWVudChlbGVtZW50LCBhdHRyaWJ1dGVzLAotICAgICAgICAgICAgICAgICAgICBmTG9jYXRvci5nZXRMaW5lTnVtYmVyKCksCi0gICAgICAgICAgICAgICAgICAgIGZMb2NhdG9yLmdldENvbHVtbk51bWJlcigpLAotICAgICAgICAgICAgICAgICAgICBmTG9jYXRvci5nZXRDaGFyYWN0ZXJPZmZzZXQoKSk7Ci0KLSAgICAgICAgICAgIGF0dHJpYnV0ZXMucmVtb3ZlQWxsQXR0cmlidXRlcygpOwotICAgICAgICAgICAgU3RyaW5nIHNjaGVtYVByZWZpeCA9IGZOYW1lc3BhY2VDb250ZXh0LmdldFByZWZpeChTY2hlbWFTeW1ib2xzLlVSSV9TQ0hFTUFGT1JTQ0hFTUEpOwotICAgICAgICAgICAgZmluYWwgU3RyaW5nIGFublJhd05hbWUgPSAoc2NoZW1hUHJlZml4Lmxlbmd0aCgpID09IDApID8gU2NoZW1hU3ltYm9scy5FTFRfQU5OT1RBVElPTiA6IChzY2hlbWFQcmVmaXggKyAnOicgKyBTY2hlbWFTeW1ib2xzLkVMVF9BTk5PVEFUSU9OKTsKLSAgICAgICAgICAgIHNjaGVtYURPTS5zdGFydEFubm90YXRpb24oYW5uUmF3TmFtZSwgYXR0cmlidXRlcywgZk5hbWVzcGFjZUNvbnRleHQpOwotICAgICAgICAgICAgZmluYWwgU3RyaW5nIGVsZW1SYXdOYW1lID0gKHNjaGVtYVByZWZpeC5sZW5ndGgoKSA9PSAwKSA/IFNjaGVtYVN5bWJvbHMuRUxUX0RPQ1VNRU5UQVRJT04gOiAoc2NoZW1hUHJlZml4ICsgJzonICsgU2NoZW1hU3ltYm9scy5FTFRfRE9DVU1FTlRBVElPTik7Ci0gICAgICAgICAgICBzY2hlbWFET00uc3RhcnRBbm5vdGF0aW9uRWxlbWVudChlbGVtUmF3TmFtZSwgYXR0cmlidXRlcyk7Ci0gICAgICAgICAgICBzY2hlbWFET00uY2hhcmFjdGVyc1JhdygiU1lOVEhFVElDX0FOTk9UQVRJT04iKTsKLSAgICAgICAgICAgIHNjaGVtYURPTS5lbmRTeW50aGV0aWNBbm5vdGF0aW9uRWxlbWVudChlbGVtUmF3TmFtZSwgZmFsc2UpOwotICAgICAgICAgICAgc2NoZW1hRE9NLmVuZFN5bnRoZXRpY0Fubm90YXRpb25FbGVtZW50KGFublJhd05hbWUsIHRydWUpOwotCi0gICAgICAgICAgICBzY2hlbWFET00uZW5kRWxlbWVudCgpOwotCi0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLSAgICAgICAgLy8gdGhlIG9yZGVyIG9mIGV2ZW50cyB0aGF0IG9jY3VycyBoZXJlIGlzOgotICAgICAgICAvLyAgIHNjaGVtYURPTS5zdGFydEFubm90YXRpb24vc3RhcnRBbm5vdGF0aW9uRWxlbWVudCAoaWYgYXBwbGljYWJsZSkKLSAgICAgICAgLy8gICBzY2hlbWFET00uZW1wdHlFbGVtZW50ICAoYmFzaWNhbGx5IHRoZSBzYW1lIGFzIHN0YXJ0RWxlbWVudCB0aGVuIGVuZEVsZW1lbnQpCi0gICAgICAgIC8vICAgc2NoZW1hRE9NLmVuZEFubm90YXRpb25FbGVtZW50IChpZiBhcHBsaWNhYmxlKQotICAgICAgICAvLyB0aGUgb3JkZXIgb2YgZXZlbnRzIHRoYXQgd291bGQgb2NjdXIgaWYgdGhpcyB3YXMgPGVsZW1lbnQ+PC9lbGVtZW50PjoKLSAgICAgICAgLy8gICBzY2hlbWFET00uc3RhcnRBbm5vdGF0aW9uL3N0YXJ0QW5ub3RhdGlvbkVsZW1lbnQgKGlmIGFwcGxpY2FibGUpCi0gICAgICAgIC8vICAgc2NoZW1hRE9NLnN0YXJ0RWxlbWVudAotICAgICAgICAvLyAgIHNjaGVtYURPTS5lbmRBbm5vdGF0aW9uRWxlbWVudCAoaWYgYXBwbGljYWJsZSkKLSAgICAgICAgLy8gICBzY2hlbWFET00uZW5kRWxlbWVudEVsZW1lbnQKLSAgICAgICAgLy8gVGh1cywgd2UgY2FuIHNlZSB0aGF0IHRoZSBvcmRlciBvZiBldmVudHMgaXNuJ3QgdGhlIHNhbWUuICBIb3dldmVyLCBpdCBkb2Vzbid0Ci0gICAgICAgIC8vIHNlZW0gdG8gbWF0dGVyLiAgLS0gUEpNCi0gICAgICAgIGlmIChmQW5ub3RhdGlvbkRlcHRoID09IC0xKSB7Ci0gICAgICAgICAgICAvLyB0aGlzIGlzIG1lc3NlZCB1cCwgYnV0IGEgY2FzZSB0byBjb25zaWRlcjoKLSAgICAgICAgICAgIGlmIChlbGVtZW50LnVyaSA9PSBTY2hlbWFTeW1ib2xzLlVSSV9TQ0hFTUFGT1JTQ0hFTUEgJiYKLSAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5sb2NhbHBhcnQgPT0gU2NoZW1hU3ltYm9scy5FTFRfQU5OT1RBVElPTikgewotICAgICAgICAgICAgICAgIHNjaGVtYURPTS5zdGFydEFubm90YXRpb24oZWxlbWVudCwgYXR0cmlidXRlcywgZk5hbWVzcGFjZUNvbnRleHQpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgc2NoZW1hRE9NLnN0YXJ0QW5ub3RhdGlvbkVsZW1lbnQoZWxlbWVudCwgYXR0cmlidXRlcyk7Ci0gICAgICAgIH0KLQotICAgICAgICBFbGVtZW50SW1wbCBuZXdFbGVtID0gc2NoZW1hRE9NLmVtcHR5RWxlbWVudChlbGVtZW50LCBhdHRyaWJ1dGVzLAotICAgICAgICAgICAgICAgIGZMb2NhdG9yLmdldExpbmVOdW1iZXIoKSwKLSAgICAgICAgICAgICAgICBmTG9jYXRvci5nZXRDb2x1bW5OdW1iZXIoKSwKLSAgICAgICAgICAgICAgICBmTG9jYXRvci5nZXRDaGFyYWN0ZXJPZmZzZXQoKSk7Ci0KLSAgICAgICAgaWYgKGZBbm5vdGF0aW9uRGVwdGggPT0gLTEpIHsKLSAgICAgICAgICAgIC8vIHRoaXMgaXMgbWVzc2VkIHVwLCBidXQgYSBjYXNlIHRvIGNvbnNpZGVyOgotICAgICAgICAgICAgaWYgKGVsZW1lbnQudXJpID09IFNjaGVtYVN5bWJvbHMuVVJJX1NDSEVNQUZPUlNDSEVNQSAmJgotICAgICAgICAgICAgICAgICAgICBlbGVtZW50LmxvY2FscGFydCA9PSBTY2hlbWFTeW1ib2xzLkVMVF9BTk5PVEFUSU9OKSB7Ci0gICAgICAgICAgICAgICAgc2NoZW1hRE9NLmVuZEFubm90YXRpb24oZWxlbWVudCwgbmV3RWxlbSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBzY2hlbWFET00uZW5kQW5ub3RhdGlvbkVsZW1lbnQoZWxlbWVudCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFRoZSBlbmQgb2YgYW4gZWxlbWVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlbGVtZW50IFRoZSBuYW1lIG9mIHRoZSBlbGVtZW50LgotICAgICAqIEBwYXJhbSBhdWdzICAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKgotICAgICAqIEBleGNlcHRpb24gWE5JRXhjZXB0aW9uCi0gICAgICogICAgICAgICAgICAgICAgICAgVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZEVsZW1lbnQoUU5hbWUgZWxlbWVudCwgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLQotICAgICAgICAvLyB3aGVuIHdlIHJlYWNoIHRoZSBlbmRFbGVtZW50IG9mIHhzOmFwcGluZm8gb3IgeHM6ZG9jdW1lbnRhdGlvbiwKLSAgICAgICAgLy8gY2hhbmdlIGZJbm5lckFubm90YXRpb25EZXB0aCB0byAtMQotICAgICAgICBpZihmQW5ub3RhdGlvbkRlcHRoID4gLTEpIHsKLSAgICAgICAgICAgIGlmIChmSW5uZXJBbm5vdGF0aW9uRGVwdGggPT0gZkRlcHRoKSB7Ci0gICAgICAgICAgICAgICAgZklubmVyQW5ub3RhdGlvbkRlcHRoID0gLTE7Ci0gICAgICAgICAgICAgICAgc2NoZW1hRE9NLmVuZEFubm90YXRpb25FbGVtZW50KGVsZW1lbnQpOwotICAgICAgICAgICAgICAgIHNjaGVtYURPTS5lbmRFbGVtZW50KCk7Ci0gICAgICAgICAgICB9IGVsc2UgaWYgKGZBbm5vdGF0aW9uRGVwdGggPT0gZkRlcHRoKSB7Ci0gICAgICAgICAgICAgICAgZkFubm90YXRpb25EZXB0aCA9IC0xOwotICAgICAgICAgICAgICAgIHNjaGVtYURPTS5lbmRBbm5vdGF0aW9uKGVsZW1lbnQsIGZDdXJyZW50QW5ub3RhdGlvbkVsZW1lbnQpOwotICAgICAgICAgICAgICAgIHNjaGVtYURPTS5lbmRFbGVtZW50KCk7Ci0gICAgICAgICAgICB9IGVsc2UgeyAvLyBpbnNpZGUgYSBjaGlsZCBvZiBhbm5vdGF0aW9uCi0gICAgICAgICAgICAgICAgc2NoZW1hRE9NLmVuZEFubm90YXRpb25FbGVtZW50KGVsZW1lbnQpOwotICAgICAgICAgICAgfQotICAgICAgICB9IGVsc2UgeyAvLyBub3QgaW4gYW4gYW5ub3RhdGlvbiBhdCBhbGwKLSAgICAgICAgICAgIGlmKGVsZW1lbnQudXJpID09IFNjaGVtYVN5bWJvbHMuVVJJX1NDSEVNQUZPUlNDSEVNQSAmJiBmR2VuZXJhdGVTeW50aGV0aWNBbm5vdGF0aW9uKSB7Ci0gICAgICAgICAgICAgICAgYm9vbGVhbiB2YWx1ZSA9IGZIYXNOb25TY2hlbWFBdHRyaWJ1dGVzLnBvcCgpOwotICAgICAgICAgICAgICAgIGJvb2xlYW4gc2F3YW5uID0gZlNhd0Fubm90YXRpb24ucG9wKCk7Ci0gICAgICAgICAgICAgICAgaWYgKHZhbHVlICYmICFzYXdhbm4pIHsKLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHNjaGVtYVByZWZpeCA9IGZOYW1lc3BhY2VDb250ZXh0LmdldFByZWZpeChTY2hlbWFTeW1ib2xzLlVSSV9TQ0hFTUFGT1JTQ0hFTUEpOwotICAgICAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgYW5uUmF3TmFtZSA9IChzY2hlbWFQcmVmaXgubGVuZ3RoKCkgPT0gMCkgPyBTY2hlbWFTeW1ib2xzLkVMVF9BTk5PVEFUSU9OIDogKHNjaGVtYVByZWZpeCArICc6JyArIFNjaGVtYVN5bWJvbHMuRUxUX0FOTk9UQVRJT04pOwotICAgICAgICAgICAgICAgICAgICBzY2hlbWFET00uc3RhcnRBbm5vdGF0aW9uKGFublJhd05hbWUsIGZFbXB0eUF0dHIsIGZOYW1lc3BhY2VDb250ZXh0KTsKLSAgICAgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIGVsZW1SYXdOYW1lID0gKHNjaGVtYVByZWZpeC5sZW5ndGgoKSA9PSAwKSA/IFNjaGVtYVN5bWJvbHMuRUxUX0RPQ1VNRU5UQVRJT04gOiAoc2NoZW1hUHJlZml4ICsgJzonICsgU2NoZW1hU3ltYm9scy5FTFRfRE9DVU1FTlRBVElPTik7Ci0gICAgICAgICAgICAgICAgICAgIHNjaGVtYURPTS5zdGFydEFubm90YXRpb25FbGVtZW50KGVsZW1SYXdOYW1lLCBmRW1wdHlBdHRyKTsKLSAgICAgICAgICAgICAgICAgICAgc2NoZW1hRE9NLmNoYXJhY3RlcnNSYXcoIlNZTlRIRVRJQ19BTk5PVEFUSU9OIik7Ci0gICAgICAgICAgICAgICAgICAgIHNjaGVtYURPTS5lbmRTeW50aGV0aWNBbm5vdGF0aW9uRWxlbWVudChlbGVtUmF3TmFtZSwgZmFsc2UpOwotICAgICAgICAgICAgICAgICAgICBzY2hlbWFET00uZW5kU3ludGhldGljQW5ub3RhdGlvbkVsZW1lbnQoYW5uUmF3TmFtZSwgdHJ1ZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgc2NoZW1hRE9NLmVuZEVsZW1lbnQoKTsKLSAgICAgICAgfQotICAgICAgICBmRGVwdGgtLTsKLQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBwYXJhbSBhdHRyaWJ1dGVzCi0gICAgICogQHJldHVybgotICAgICAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBoYXNOb25TY2hlbWFBdHRyaWJ1dGVzKFFOYW1lIGVsZW1lbnQsIFhNTEF0dHJpYnV0ZXMgYXR0cmlidXRlcykgewotICAgICAgICBmaW5hbCBpbnQgbGVuZ3RoID0gYXR0cmlidXRlcy5nZXRMZW5ndGgoKTsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkgewotICAgICAgICAgICAgU3RyaW5nIHVyaSA9IGF0dHJpYnV0ZXMuZ2V0VVJJKGkpOwotICAgICAgICAgICAgaWYgKHVyaSAhPSBudWxsICYmIHVyaSAhPSBTY2hlbWFTeW1ib2xzLlVSSV9TQ0hFTUFGT1JTQ0hFTUEgJiYKLSAgICAgICAgICAgICAgICAgICAgdXJpICE9IE5hbWVzcGFjZUNvbnRleHQuWE1MTlNfVVJJICYmCi0gICAgICAgICAgICAgICAgICAgICEodXJpID09IE5hbWVzcGFjZUNvbnRleHQuWE1MX1VSSSAmJgotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXMuZ2V0UU5hbWUoaSkgPT0gU2NoZW1hU3ltYm9scy5BVFRfWE1MX0xBTkcgJiYgZWxlbWVudC5sb2NhbHBhcnQgPT0gU2NoZW1hU3ltYm9scy5FTFRfU0NIRU1BKSkgewotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJZ25vcmFibGUgd2hpdGVzcGFjZS4gRm9yIHRoaXMgbWV0aG9kIHRvIGJlIGNhbGxlZCwgdGhlIGRvY3VtZW50Ci0gICAgICogc291cmNlIG11c3QgaGF2ZSBzb21lIHdheSBvZiBkZXRlcm1pbmluZyB0aGF0IHRoZSB0ZXh0IGNvbnRhaW5pbmcKLSAgICAgKiBvbmx5IHdoaXRlc3BhY2UgY2hhcmFjdGVycyBzaG91bGQgYmUgY29uc2lkZXJlZCBpZ25vcmFibGUuIEZvcgotICAgICAqIGV4YW1wbGUsIHRoZSB2YWxpZGF0b3IgY2FuIGRldGVybWluZSBpZiBhIGxlbmd0aCBvZiB3aGl0ZXNwYWNlCi0gICAgICogY2hhcmFjdGVycyBpbiB0aGUgZG9jdW1lbnQgYXJlIGlnbm9yYWJsZSBiYXNlZCBvbiB0aGUgZWxlbWVudAotICAgICAqIGNvbnRlbnQgbW9kZWwuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdGV4dCAgIFRoZSBpZ25vcmFibGUgd2hpdGVzcGFjZS4KLSAgICAgKiBAcGFyYW0gYXVncyAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKgotICAgICAqIEBleGNlcHRpb24gWE5JRXhjZXB0aW9uCi0gICAgICogICAgICAgICAgICAgICAgICAgVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGlnbm9yYWJsZVdoaXRlc3BhY2UoWE1MU3RyaW5nIHRleHQsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIC8vIHVubGlrZWx5IHRvIGJlIGNhbGxlZCwgYnV0IHlvdSBuZXZlciBrbm93Li4uCi0gICAgICAgIGlmIChmQW5ub3RhdGlvbkRlcHRoICE9IC0xICkgewotICAgICAgICAgICAgc2NoZW1hRE9NLmNoYXJhY3RlcnModGV4dCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgc3RhcnQgb2YgYSBDREFUQSBzZWN0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIGF1Z3MgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIFhOSUV4Y2VwdGlvbgotICAgICAqICAgICAgICAgICAgICAgICAgIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydENEQVRBKEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIC8vIG9ubHkgZGVhbCB3aXRoIENEQVRBIGJvdW5kYXJpZXMgd2l0aGluIGFuIGFubm90YXRpb24uCi0gICAgICAgIGlmIChmQW5ub3RhdGlvbkRlcHRoICE9IC0xKSB7Ci0gICAgICAgICAgICBzY2hlbWFET00uc3RhcnRBbm5vdGF0aW9uQ0RBVEEoKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoZSBlbmQgb2YgYSBDREFUQSBzZWN0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIGF1Z3MgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIFhOSUV4Y2VwdGlvbgotICAgICAqICAgICAgICAgICAgICAgICAgIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbmRDREFUQShBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICAvLyBvbmx5IGRlYWwgd2l0aCBDREFUQSBib3VuZGFyaWVzIHdpdGhpbiBhbiBhbm5vdGF0aW9uLgotICAgICAgICBpZiAoZkFubm90YXRpb25EZXB0aCAhPSAtMSkgewotICAgICAgICAgICAgc2NoZW1hRE9NLmVuZEFubm90YXRpb25DREFUQSgpOwotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICAvLwotICAgIC8vIG90aGVyIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgRE9NIGRvY3VtZW50IG9iamVjdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgRG9jdW1lbnQgZ2V0RG9jdW1lbnQoKSB7Ci0gICAgICAgIHJldHVybiBzY2hlbWFET007Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRGVsZWdhdGVzIHRvIFNjaGVtYVBhcnNpbmdDb25maWcuc2V0RmVhdHVyZQotICAgICAqIEBwYXJhbSBmZWF0dXJlSWQKLSAgICAgKiBAcGFyYW0gc3RhdGUKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRGZWF0dXJlKFN0cmluZyBmZWF0dXJlSWQsIGJvb2xlYW4gc3RhdGUpewotICAgICAgICBjb25maWcuc2V0RmVhdHVyZShmZWF0dXJlSWQsIHN0YXRlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBEZWxlZ2F0ZXMgdG8gU2NoZW1hUGFyc2luZ0NvbmZpZy5nZXRGZWF0dXJlCi0gICAgICogQHBhcmFtIGZlYXR1cmVJZAotICAgICAqIEByZXR1cm4gYm9vbGVhbgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGdldEZlYXR1cmUoU3RyaW5nIGZlYXR1cmVJZCl7Ci0gICAgICAgIHJldHVybiBjb25maWcuZ2V0RmVhdHVyZShmZWF0dXJlSWQpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIERlbGVnYXRlcyB0byBTY2hlbWFQYXJzaW5nQ29uZmlnLnNldFByb3BlcnR5LgotICAgICAqIEBwYXJhbSBwcm9wZXJ0eUlkCi0gICAgICogQHBhcmFtIHZhbHVlCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0UHJvcGVydHkoU3RyaW5nIHByb3BlcnR5SWQsIE9iamVjdCB2YWx1ZSl7Ci0gICAgICAgIGNvbmZpZy5zZXRQcm9wZXJ0eShwcm9wZXJ0eUlkLCB2YWx1ZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRGVsZWdhdGVzIHRvIFNjaGVtYVBhcnNpbmdDb25maWcuZ2V0UHJvcGVydHkuCi0gICAgICogQHBhcmFtIHByb3BlcnR5SWQKLSAgICAgKiBAcmV0dXJuIE9iamVjdAotICAgICAqLwotICAgIHB1YmxpYyBPYmplY3QgZ2V0UHJvcGVydHkoU3RyaW5nIHByb3BlcnR5SWQpewotICAgICAgICByZXR1cm4gY29uZmlnLmdldFByb3BlcnR5KHByb3BlcnR5SWQpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIERlbGVnYXRlcyB0byBTY2hlbWFQYXJzaW5nQ29uZmlnLnNldEVudGl0eVJlc29sdmVyLgotICAgICAqIEBwYXJhbSBlciBYTUxFbnRpdHlSZXNvbHZlcgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEVudGl0eVJlc29sdmVyKFhNTEVudGl0eVJlc29sdmVyIGVyKSB7Ci0gICAgICAgIGNvbmZpZy5zZXRFbnRpdHlSZXNvbHZlcihlcik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRGVsZWdhdGVzIHBhcnNpbmcgdG8gU2NoZW1hUGFyc2luZ0NvbmZpZwotICAgICAqCi0gICAgICogQHBhcmFtIGlucHV0U291cmNlCi0gICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHBhcnNlKFhNTElucHV0U291cmNlIGlucHV0U291cmNlKSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgICAgICBjb25maWcucGFyc2UoaW5wdXRTb3VyY2UpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJlc2V0IFNjaGVtYVBhcnNpbmdDb25maWcKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCByZXNldCgpIHsKLSAgICAgICAgKChTY2hlbWFQYXJzaW5nQ29uZmlnKWNvbmZpZykucmVzZXQoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXNldE5vZGVQb29sIG9uIFNjaGVtYVBhcnNpbmdDb25maWcKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCByZXNldE5vZGVQb29sKCkgewotICAgICAgICAoKFNjaGVtYVBhcnNpbmdDb25maWcpY29uZmlnKS5yZXNldE5vZGVQb29sKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQSBzaW1wbGUgYm9vbGVhbiBiYXNlZCBzdGFjay4KLSAgICAgKgotICAgICAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBCb29sZWFuU3RhY2sgewotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIERhdGEKLSAgICAgICAgLy8KLQotICAgICAgICAvKiogU3RhY2sgZGVwdGguICovCi0gICAgICAgIHByaXZhdGUgaW50IGZEZXB0aDsKLQotICAgICAgICAvKiogU3RhY2sgZGF0YS4gKi8KLSAgICAgICAgcHJpdmF0ZSBib29sZWFuW10gZkRhdGE7Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gQ29uc3RydWN0b3IKLSAgICAgICAgLy8KLQotICAgICAgICBwdWJsaWMgQm9vbGVhblN0YWNrICgpIHt9Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gUHVibGljIG1ldGhvZHMKLSAgICAgICAgLy8KLQotICAgICAgICAvKiogUmV0dXJucyB0aGUgc2l6ZSBvZiB0aGUgc3RhY2suICovCi0gICAgICAgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKLSAgICAgICAgICAgIHJldHVybiBmRGVwdGg7Ci0gICAgICAgIH0KLQotICAgICAgICAvKiogUHVzaGVzIGEgdmFsdWUgb250byB0aGUgc3RhY2suICovCi0gICAgICAgIHB1YmxpYyB2b2lkIHB1c2goYm9vbGVhbiB2YWx1ZSkgewotICAgICAgICAgICAgZW5zdXJlQ2FwYWNpdHkoZkRlcHRoICsgMSk7Ci0gICAgICAgICAgICBmRGF0YVtmRGVwdGgrK10gPSB2YWx1ZTsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKiBQb3BzIGEgdmFsdWUgb2ZmIG9mIHRoZSBzdGFjay4gKi8KLSAgICAgICAgcHVibGljIGJvb2xlYW4gcG9wKCkgewotICAgICAgICAgICAgcmV0dXJuIGZEYXRhWy0tZkRlcHRoXTsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKiBDbGVhcnMgdGhlIHN0YWNrLiAqLwotICAgICAgICBwdWJsaWMgdm9pZCBjbGVhcigpIHsKLSAgICAgICAgICAgIGZEZXB0aCA9IDA7Ci0gICAgICAgIH0KLQotICAgICAgICAvLwotICAgICAgICAvLyBQcml2YXRlIG1ldGhvZHMKLSAgICAgICAgLy8KLQotICAgICAgICAvKiogRW5zdXJlcyBjYXBhY2l0eS4gKi8KLSAgICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUNhcGFjaXR5KGludCBzaXplKSB7Ci0gICAgICAgICAgICBpZiAoZkRhdGEgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZEYXRhID0gbmV3IGJvb2xlYW5bMzJdOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoZkRhdGEubGVuZ3RoIDw9IHNpemUpIHsKLSAgICAgICAgICAgICAgICBib29sZWFuW10gbmV3ZGF0YSA9IG5ldyBib29sZWFuW2ZEYXRhLmxlbmd0aCAqIDJdOwotICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZkRhdGEsIDAsIG5ld2RhdGEsIDAsIGZEYXRhLmxlbmd0aCk7Ci0gICAgICAgICAgICAgICAgZkRhdGEgPSBuZXdkYXRhOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9vcHRpL1NjaGVtYVBhcnNpbmdDb25maWcuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvb3B0aS9TY2hlbWFQYXJzaW5nQ29uZmlnLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGE5YjI1MWUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy9vcHRpL1NjaGVtYVBhcnNpbmdDb25maWcuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEwMzEgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMub3B0aTsKLQotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci1pbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5Db25zdGFudHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLlhNTDExRFREU2Nhbm5lckltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLlhNTDExTlNEb2N1bWVudFNjYW5uZXJJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5YTUxEVERTY2FubmVySW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuWE1MRW50aXR5SGFuZGxlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuWE1MRW50aXR5TWFuYWdlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuWE1MRXJyb3JSZXBvcnRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuWE1MTlNEb2N1bWVudFNjYW5uZXJJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5YTUxWZXJzaW9uRGV0ZWN0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LkRURERWRmFjdG9yeTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwubXNnLlhNTE1lc3NhZ2VGb3JtYXR0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnZhbGlkYXRpb24uVmFsaWRhdGlvbk1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlhTTWVzc2FnZUZvcm1hdHRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnBhcnNlcnMuQmFzaWNQYXJzZXJDb25maWd1cmF0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5GZWF0dXJlU3RhdGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlByb3BlcnR5U3RhdGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlN0YXR1czsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuU3ltYm9sVGFibGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MTG9jYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTklFeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuZ3JhbW1hcnMuWE1MR3JhbW1hclBvb2w7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTENvbXBvbmVudDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MQ29tcG9uZW50TWFuYWdlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MRFREU2Nhbm5lcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MRG9jdW1lbnRTY2FubmVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxJbnB1dFNvdXJjZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MUHVsbFBhcnNlckNvbmZpZ3VyYXRpb247Ci0KLS8qKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgUmFodWwgU3JpdmFzdGF2YSwgU3VuIE1pY3Jvc3lzdGVtcyBJbmMuCi0gKgotICogQHZlcnNpb24gJElkOiBTY2hlbWFQYXJzaW5nQ29uZmlnLmphdmEsdiAxLjggMjAxMC0xMS0wMSAwNDo0MDowMSBqb2VodyBFeHAgJAotICovCi1wdWJsaWMgY2xhc3MgU2NoZW1hUGFyc2luZ0NvbmZpZyBleHRlbmRzIEJhc2ljUGFyc2VyQ29uZmlndXJhdGlvbgotICAgIGltcGxlbWVudHMgWE1MUHVsbFBhcnNlckNvbmZpZ3VyYXRpb24gewotCi0gICAgLy8KLSAgICAvLyBDb25zdGFudHMKLSAgICAvLwotCi0gICAgcHJvdGVjdGVkIGZpbmFsIHN0YXRpYyBTdHJpbmcgWE1MMTFfREFUQVRZUEVfVkFMSURBVE9SX0ZBQ1RPUlkgPQotICAgICAgICAiY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LmR0ZC5YTUwxMURURERWRmFjdG9yeUltcGwiOwotCi0gICAgLy8gZmVhdHVyZSBpZGVudGlmaWVycwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogd2FybiBvbiBkdXBsaWNhdGUgYXR0cmlidXRlIGRlZmluaXRpb24uICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0FSTl9PTl9EVVBMSUNBVEVfQVRUREVGID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5XQVJOX09OX0RVUExJQ0FURV9BVFRERUZfRkVBVFVSRTsKLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IHdhcm4gb24gZHVwbGljYXRlIGVudGl0eSBkZWZpbml0aW9uLiAqLwotICAgIC8vICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBXQVJOX09OX0RVUExJQ0FURV9FTlRJVFlERUYgPSBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLldBUk5fT05fRFVQTElDQVRFX0VOVElUWURFRl9GRUFUVVJFOwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogd2FybiBvbiB1bmRlY2xhcmVkIGVsZW1lbnQgZGVmaW5pdGlvbi4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBXQVJOX09OX1VOREVDTEFSRURfRUxFTURFRiA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuV0FSTl9PTl9VTkRFQ0xBUkVEX0VMRU1ERUZfRkVBVFVSRTsKLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IGFsbG93IEphdmEgZW5jb2RpbmdzLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIEFMTE9XX0pBVkFfRU5DT0RJTkdTID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5BTExPV19KQVZBX0VOQ09ESU5HU19GRUFUVVJFOwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogY29udGludWUgYWZ0ZXIgZmF0YWwgZXJyb3IuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ09OVElOVUVfQUZURVJfRkFUQUxfRVJST1IgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLkNPTlRJTlVFX0FGVEVSX0ZBVEFMX0VSUk9SX0ZFQVRVUkU7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiBsb2FkIGV4dGVybmFsIERURC4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBMT0FEX0VYVEVSTkFMX0RURCA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuTE9BRF9FWFRFUk5BTF9EVERfRkVBVFVSRTsKLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IG5vdGlmeSBidWlsdC1pbiByZWZlcmVjZXMuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgTk9USUZZX0JVSUxUSU5fUkVGUyA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuTk9USUZZX0JVSUxUSU5fUkVGU19GRUFUVVJFOwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogbm90aWZ5IGNoYXJhY3RlciByZWZlcmVjZXMuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgTk9USUZZX0NIQVJfUkVGUyA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuTk9USUZZX0NIQVJfUkVGU19GRUFUVVJFOwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogZXhwb3NlIHNjaGVtYSBub3JtYWxpemVkIHZhbHVlICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgTk9STUFMSVpFX0RBVEEgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLlNDSEVNQV9OT1JNQUxJWkVEX1ZBTFVFOwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogc2VuZCBlbGVtZW50IGRlZmF1bHQgdmFsdWUgdmlhIGNoYXJhY3RlcnMoKSAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFNDSEVNQV9FTEVNRU5UX0RFRkFVTFQgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLlNDSEVNQV9FTEVNRU5UX0RFRkFVTFQ7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiBnZW5lcmF0ZSBzeW50aGV0aWMgYW5ub3RhdGlvbnMuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgR0VORVJBVEVfU1lOVEhFVElDX0FOTk9UQVRJT05TID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5HRU5FUkFURV9TWU5USEVUSUNfQU5OT1RBVElPTlNfRkVBVFVSRTsKLQotCi0gICAgLy8gcHJvcGVydHkgaWRlbnRpZmllcnMKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBlcnJvciByZXBvcnRlci4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJPUl9SRVBPUlRFUiA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLkVSUk9SX1JFUE9SVEVSX1BST1BFUlRZOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IGVudGl0eSBtYW5hZ2VyLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIEVOVElUWV9NQU5BR0VSID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuRU5USVRZX01BTkFHRVJfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllciBkb2N1bWVudCBzY2FubmVyOiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIERPQ1VNRU5UX1NDQU5ORVIgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5ET0NVTUVOVF9TQ0FOTkVSX1BST1BFUlRZOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IERURCBzY2FubmVyLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIERURF9TQ0FOTkVSID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuRFREX1NDQU5ORVJfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogZ3JhbW1hciBwb29sLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFhNTEdSQU1NQVJfUE9PTCA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLlhNTEdSQU1NQVJfUE9PTF9QUk9QRVJUWTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBEVEQgdmFsaWRhdG9yLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIERURF9WQUxJREFUT1IgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5EVERfVkFMSURBVE9SX1BST1BFUlRZOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IG5hbWVzcGFjZSBiaW5kZXIuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgTkFNRVNQQUNFX0JJTkRFUiA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLk5BTUVTUEFDRV9CSU5ERVJfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogZGF0YXR5cGUgdmFsaWRhdG9yIGZhY3RvcnkuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgREFUQVRZUEVfVkFMSURBVE9SX0ZBQ1RPUlkgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5EQVRBVFlQRV9WQUxJREFUT1JfRkFDVE9SWV9QUk9QRVJUWTsKLQotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFZBTElEQVRJT05fTUFOQUdFUiA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLlZBTElEQVRJT05fTUFOQUdFUl9QUk9QRVJUWTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBYTUwgU2NoZW1hIHZhbGlkYXRvci4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBTQ0hFTUFfVkFMSURBVE9SID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuU0NIRU1BX1ZBTElEQVRPUl9QUk9QRVJUWTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBsb2NhbGUuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgTE9DQUxFID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuTE9DQUxFX1BST1BFUlRZOwotCi0KLSAgICAvLyBkZWJ1Z2dpbmcKLQotICAgIC8qKiBTZXQgdG8gdHJ1ZSBhbmQgcmVjb21waWxlIHRvIHByaW50IGV4Y2VwdGlvbiBzdGFjayB0cmFjZS4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIFBSSU5UX0VYQ0VQVElPTl9TVEFDS19UUkFDRSA9IGZhbHNlOwotCi0gICAgLy8KLSAgICAvLyBEYXRhCi0gICAgLy8KLQotICAgIC8vCi0gICAgLy8gWE1MIDEuMCBjb21wb25lbnRzCi0gICAgLy8KLQotICAgIC8qKiBUaGUgWE1MIDEuMCBEYXRhdHlwZSB2YWxpZGF0b3IgZmFjdG9yeS4gKi8KLSAgICBwcm90ZWN0ZWQgZmluYWwgRFRERFZGYWN0b3J5IGZEYXRhdHlwZVZhbGlkYXRvckZhY3Rvcnk7Ci0KLSAgICAvKiogVGhlIFhNTCAxLjAgRG9jdW1lbnQgc2Nhbm5lci4gKi8KLSAgICBwcm90ZWN0ZWQgZmluYWwgWE1MTlNEb2N1bWVudFNjYW5uZXJJbXBsIGZOYW1lc3BhY2VTY2FubmVyOwotCi0gICAgLyoqIFRoZSBYTUwgMS4wIERURCBzY2FubmVyLiAqLwotICAgIHByb3RlY3RlZCBmaW5hbCBYTUxEVERTY2FubmVySW1wbCBmRFREU2Nhbm5lcjsKLQotICAgIC8vCi0gICAgLy8gWE1MIDEuMSBjb21wb25lbnRzCi0gICAgLy8KLQotICAgIC8qKiBUaGUgWE1MIDEuMSBEYXRhdHlwZSB2YWxpZGF0b3IgZmFjdG9yeS4gKi8KLSAgICBwcm90ZWN0ZWQgRFRERFZGYWN0b3J5IGZYTUwxMURhdGF0eXBlRmFjdG9yeSA9IG51bGw7Ci0KLSAgICAvKiogVGhlIFhNTCAxLjEgRG9jdW1lbnQgc2Nhbm5lci4gKi8KLSAgICBwcm90ZWN0ZWQgWE1MMTFOU0RvY3VtZW50U2Nhbm5lckltcGwgZlhNTDExTlNEb2NTY2FubmVyID0gbnVsbDsKLQotICAgIC8qKiBUaGUgWE1MIDEuMSBEVEQgc2Nhbm5lci4gKiovCi0gICAgcHJvdGVjdGVkIFhNTDExRFREU2Nhbm5lckltcGwgZlhNTDExRFREU2Nhbm5lciA9IG51bGw7Ci0KLSAgICAvLyBjb21tb24gY29tcG9uZW50cyAobm9uLWNvbmZpZ3VyYWJsZSkKLQotICAgIC8qKiBDdXJyZW50IERhdGF0eXBlIHZhbGlkYXRvciBmYWN0b3J5LiAqLwotICAgIHByb3RlY3RlZCBEVEREVkZhY3RvcnkgZkN1cnJlbnREVkZhY3Rvcnk7Ci0KLSAgICAvKiogQ3VycmVudCBzY2FubmVyICovCi0gICAgcHJvdGVjdGVkIFhNTERvY3VtZW50U2Nhbm5lciBmQ3VycmVudFNjYW5uZXI7Ci0KLSAgICAvKiogQ3VycmVudCBEVEQgc2Nhbm5lci4gKi8KLSAgICBwcm90ZWN0ZWQgWE1MRFREU2Nhbm5lciBmQ3VycmVudERURFNjYW5uZXI7Ci0KLSAgICAvKiogR3JhbW1hciBwb29sLiAqLwotICAgIHByb3RlY3RlZCBYTUxHcmFtbWFyUG9vbCBmR3JhbW1hclBvb2w7Ci0KLSAgICAvKiogWE1MIHZlcnNpb24gZGV0ZWN0b3IuICovCi0gICAgcHJvdGVjdGVkIGZpbmFsIFhNTFZlcnNpb25EZXRlY3RvciBmVmVyc2lvbkRldGVjdG9yOwotCi0gICAgLy8gY29tbW9uIGNvbXBvbmVudHMgKGNvbmZpZ3VyYWJsZSkKLQotICAgIC8qKiBFcnJvciByZXBvcnRlci4gKi8KLSAgICBwcm90ZWN0ZWQgZmluYWwgWE1MRXJyb3JSZXBvcnRlciBmRXJyb3JSZXBvcnRlcjsKLQotICAgIC8qKiBFbnRpdHkgbWFuYWdlci4gKi8KLSAgICBwcm90ZWN0ZWQgZmluYWwgWE1MRW50aXR5TWFuYWdlciBmRW50aXR5TWFuYWdlcjsKLQotICAgIC8qKiBJbnB1dCBTb3VyY2UgKi8KLSAgICBwcm90ZWN0ZWQgWE1MSW5wdXRTb3VyY2UgZklucHV0U291cmNlOwotCi0gICAgcHJvdGVjdGVkIGZpbmFsIFZhbGlkYXRpb25NYW5hZ2VyIGZWYWxpZGF0aW9uTWFuYWdlcjsKLSAgICAvLyBzdGF0ZQotCi0gICAgLyoqIExvY2F0b3IgKi8KLSAgICBwcm90ZWN0ZWQgWE1MTG9jYXRvciBmTG9jYXRvcjsKLQotICAgIC8qKgotICAgICAqIFRydWUgaWYgYSBwYXJzZSBpcyBpbiBwcm9ncmVzcy4gVGhpcyBzdGF0ZSBpcyBuZWVkZWQgYmVjYXVzZQotICAgICAqIHNvbWUgZmVhdHVyZXMvcHJvcGVydGllcyBjYW5ub3QgYmUgc2V0IHdoaWxlIHBhcnNpbmcgKGUuZy4KLSAgICAgKiB2YWxpZGF0aW9uIGFuZCBuYW1lc3BhY2VzKS4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBmUGFyc2VJblByb2dyZXNzID0gZmFsc2U7Ci0KLSAgICAvKioKLSAgICAgKiBmQ29uZmlnVXBkYXRlZCBpcyBzZXQgdG8gdHJ1ZSBpZiB0aGVyZSBoYXMgYmVlbiBhbnkgY2hhbmdlIHRvIHRoZSBjb25maWd1cmF0aW9uIHNldHRpbmdzLAotICAgICAqIGkuZSBhIGZlYXR1cmUgb3IgYSBwcm9wZXJ0eSB3YXMgY2hhbmdlZC4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBmQ29uZmlnVXBkYXRlZCA9IGZhbHNlOwotCi0gICAgLyoqIEZsYWcgaW5kaWNpYXRpbmcgd2hldGhlciBYTUwxMSBjb21wb25lbnRzIGhhdmUgYmVlbiBpbml0aWFsaXplZC4gKi8KLSAgICBwcml2YXRlIGJvb2xlYW4gZjExSW5pdGlhbGl6ZWQgPSBmYWxzZTsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKiBEZWZhdWx0IGNvbnN0cnVjdG9yLiAqLwotICAgIHB1YmxpYyBTY2hlbWFQYXJzaW5nQ29uZmlnKCkgewotICAgICAgICB0aGlzKG51bGwsIG51bGwsIG51bGwpOwotICAgIH0gLy8gPGluaXQ+KCkKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHMgYSBwYXJzZXIgY29uZmlndXJhdGlvbiB1c2luZyB0aGUgc3BlY2lmaWVkIHN5bWJvbCB0YWJsZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzeW1ib2xUYWJsZSBUaGUgc3ltYm9sIHRhYmxlIHRvIHVzZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgU2NoZW1hUGFyc2luZ0NvbmZpZyhTeW1ib2xUYWJsZSBzeW1ib2xUYWJsZSkgewotICAgICAgICB0aGlzKHN5bWJvbFRhYmxlLCBudWxsLCBudWxsKTsKLSAgICB9IC8vIDxpbml0PihTeW1ib2xUYWJsZSkKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHMgYSBwYXJzZXIgY29uZmlndXJhdGlvbiB1c2luZyB0aGUgc3BlY2lmaWVkIHN5bWJvbCB0YWJsZSBhbmQKLSAgICAgKiBncmFtbWFyIHBvb2wuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5SRVZJU0lUOjwvc3Ryb25nPgotICAgICAqIEdyYW1tYXIgcG9vbCB3aWxsIGJlIHVwZGF0ZWQgd2hlbiB0aGUgbmV3IHZhbGlkYXRpb24gZW5naW5lIGlzCi0gICAgICogaW1wbGVtZW50ZWQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc3ltYm9sVGFibGUgVGhlIHN5bWJvbCB0YWJsZSB0byB1c2UuCi0gICAgICogQHBhcmFtIGdyYW1tYXJQb29sIFRoZSBncmFtbWFyIHBvb2wgdG8gdXNlLgotICAgICAqLwotICAgIHB1YmxpYyBTY2hlbWFQYXJzaW5nQ29uZmlnKFN5bWJvbFRhYmxlIHN5bWJvbFRhYmxlLAotICAgICAgICAgICAgWE1MR3JhbW1hclBvb2wgZ3JhbW1hclBvb2wpIHsKLSAgICAgICAgdGhpcyhzeW1ib2xUYWJsZSwgZ3JhbW1hclBvb2wsIG51bGwpOwotICAgIH0gLy8gPGluaXQ+KFN5bWJvbFRhYmxlLFhNTEdyYW1tYXJQb29sKQotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0cyBhIHBhcnNlciBjb25maWd1cmF0aW9uIHVzaW5nIHRoZSBzcGVjaWZpZWQgc3ltYm9sIHRhYmxlLAotICAgICAqIGdyYW1tYXIgcG9vbCwgYW5kIHBhcmVudCBzZXR0aW5ncy4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPlJFVklTSVQ6PC9zdHJvbmc+Ci0gICAgICogR3JhbW1hciBwb29sIHdpbGwgYmUgdXBkYXRlZCB3aGVuIHRoZSBuZXcgdmFsaWRhdGlvbiBlbmdpbmUgaXMKLSAgICAgKiBpbXBsZW1lbnRlZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzeW1ib2xUYWJsZSAgICBUaGUgc3ltYm9sIHRhYmxlIHRvIHVzZS4KLSAgICAgKiBAcGFyYW0gZ3JhbW1hclBvb2wgICAgVGhlIGdyYW1tYXIgcG9vbCB0byB1c2UuCi0gICAgICogQHBhcmFtIHBhcmVudFNldHRpbmdzIFRoZSBwYXJlbnQgc2V0dGluZ3MuCi0gICAgICovCi0gICAgcHVibGljIFNjaGVtYVBhcnNpbmdDb25maWcoU3ltYm9sVGFibGUgc3ltYm9sVGFibGUsCi0gICAgICAgICAgICBYTUxHcmFtbWFyUG9vbCBncmFtbWFyUG9vbCwKLSAgICAgICAgICAgIFhNTENvbXBvbmVudE1hbmFnZXIgcGFyZW50U2V0dGluZ3MpIHsKLSAgICAgICAgc3VwZXIoc3ltYm9sVGFibGUsIHBhcmVudFNldHRpbmdzKTsKLQotICAgICAgICAvLyBhZGQgZGVmYXVsdCByZWNvZ25pemVkIGZlYXR1cmVzCi0gICAgICAgIGZpbmFsIFN0cmluZ1tdIHJlY29nbml6ZWRGZWF0dXJlcyA9IHsKLSAgICAgICAgICAgIFBBUlNFUl9TRVRUSU5HUywgV0FSTl9PTl9EVVBMSUNBVEVfQVRUREVGLCAgIFdBUk5fT05fVU5ERUNMQVJFRF9FTEVNREVGLAotICAgICAgICAgICAgQUxMT1dfSkFWQV9FTkNPRElOR1MsICAgICAgIENPTlRJTlVFX0FGVEVSX0ZBVEFMX0VSUk9SLAotICAgICAgICAgICAgTE9BRF9FWFRFUk5BTF9EVEQsICAgICAgICAgIE5PVElGWV9CVUlMVElOX1JFRlMsCi0gICAgICAgICAgICBOT1RJRllfQ0hBUl9SRUZTLCBHRU5FUkFURV9TWU5USEVUSUNfQU5OT1RBVElPTlMKLSAgICAgICAgfTsKLSAgICAgICAgYWRkUmVjb2duaXplZEZlYXR1cmVzKHJlY29nbml6ZWRGZWF0dXJlcyk7Ci0gICAgICAgIGZGZWF0dXJlcy5wdXQoUEFSU0VSX1NFVFRJTkdTLCBCb29sZWFuLlRSVUUpOwotICAgICAgICAvLyBzZXQgc3RhdGUgZm9yIGRlZmF1bHQgZmVhdHVyZXMKLSAgICAgICAgZkZlYXR1cmVzLnB1dChXQVJOX09OX0RVUExJQ0FURV9BVFRERUYsIEJvb2xlYW4uRkFMU0UpOwotICAgICAgICAvL3NldEZlYXR1cmUoV0FSTl9PTl9EVVBMSUNBVEVfRU5USVRZREVGLCBmYWxzZSk7Ci0gICAgICAgIGZGZWF0dXJlcy5wdXQoV0FSTl9PTl9VTkRFQ0xBUkVEX0VMRU1ERUYsIEJvb2xlYW4uRkFMU0UpOwotICAgICAgICBmRmVhdHVyZXMucHV0KEFMTE9XX0pBVkFfRU5DT0RJTkdTLCBCb29sZWFuLkZBTFNFKTsKLSAgICAgICAgZkZlYXR1cmVzLnB1dChDT05USU5VRV9BRlRFUl9GQVRBTF9FUlJPUiwgQm9vbGVhbi5GQUxTRSk7Ci0gICAgICAgIGZGZWF0dXJlcy5wdXQoTE9BRF9FWFRFUk5BTF9EVEQsIEJvb2xlYW4uVFJVRSk7Ci0gICAgICAgIGZGZWF0dXJlcy5wdXQoTk9USUZZX0JVSUxUSU5fUkVGUywgQm9vbGVhbi5GQUxTRSk7Ci0gICAgICAgIGZGZWF0dXJlcy5wdXQoTk9USUZZX0NIQVJfUkVGUywgQm9vbGVhbi5GQUxTRSk7Ci0gICAgICAgIGZGZWF0dXJlcy5wdXQoR0VORVJBVEVfU1lOVEhFVElDX0FOTk9UQVRJT05TLCBCb29sZWFuLkZBTFNFKTsKLQotICAgICAgICAvLyBhZGQgZGVmYXVsdCByZWNvZ25pemVkIHByb3BlcnRpZXMKLSAgICAgICAgZmluYWwgU3RyaW5nW10gcmVjb2duaXplZFByb3BlcnRpZXMgPSB7Ci0gICAgICAgICAgICBFUlJPUl9SRVBPUlRFUiwKLSAgICAgICAgICAgIEVOVElUWV9NQU5BR0VSLAotICAgICAgICAgICAgRE9DVU1FTlRfU0NBTk5FUiwKLSAgICAgICAgICAgIERURF9TQ0FOTkVSLAotICAgICAgICAgICAgRFREX1ZBTElEQVRPUiwKLSAgICAgICAgICAgIE5BTUVTUEFDRV9CSU5ERVIsCi0gICAgICAgICAgICBYTUxHUkFNTUFSX1BPT0wsCi0gICAgICAgICAgICBEQVRBVFlQRV9WQUxJREFUT1JfRkFDVE9SWSwKLSAgICAgICAgICAgIFZBTElEQVRJT05fTUFOQUdFUiwKLSAgICAgICAgICAgIEdFTkVSQVRFX1NZTlRIRVRJQ19BTk5PVEFUSU9OUywKLSAgICAgICAgICAgIExPQ0FMRQotICAgICAgICB9OwotICAgICAgICBhZGRSZWNvZ25pemVkUHJvcGVydGllcyhyZWNvZ25pemVkUHJvcGVydGllcyk7Ci0KLSAgICAgICAgZkdyYW1tYXJQb29sID0gZ3JhbW1hclBvb2w7Ci0gICAgICAgIGlmIChmR3JhbW1hclBvb2wgIT0gbnVsbCkgewotICAgICAgICAgICAgc2V0UHJvcGVydHkoWE1MR1JBTU1BUl9QT09MLCBmR3JhbW1hclBvb2wpOwotICAgICAgICB9Ci0KLSAgICAgICAgZkVudGl0eU1hbmFnZXIgPSBuZXcgWE1MRW50aXR5TWFuYWdlcigpOwotICAgICAgICBmUHJvcGVydGllcy5wdXQoRU5USVRZX01BTkFHRVIsIGZFbnRpdHlNYW5hZ2VyKTsKLSAgICAgICAgYWRkQ29tcG9uZW50KGZFbnRpdHlNYW5hZ2VyKTsKLQotICAgICAgICBmRXJyb3JSZXBvcnRlciA9IG5ldyBYTUxFcnJvclJlcG9ydGVyKCk7Ci0gICAgICAgIGZFcnJvclJlcG9ydGVyLnNldERvY3VtZW50TG9jYXRvcihmRW50aXR5TWFuYWdlci5nZXRFbnRpdHlTY2FubmVyKCkpOwotICAgICAgICBmUHJvcGVydGllcy5wdXQoRVJST1JfUkVQT1JURVIsIGZFcnJvclJlcG9ydGVyKTsKLSAgICAgICAgYWRkQ29tcG9uZW50KGZFcnJvclJlcG9ydGVyKTsKLQotICAgICAgICBmTmFtZXNwYWNlU2Nhbm5lciA9IG5ldyBYTUxOU0RvY3VtZW50U2Nhbm5lckltcGwoKTsKLSAgICAgICAgZlByb3BlcnRpZXMucHV0KERPQ1VNRU5UX1NDQU5ORVIsIGZOYW1lc3BhY2VTY2FubmVyKTsKLSAgICAgICAgYWRkUmVjb2duaXplZFBhcmFtc0FuZFNldERlZmF1bHRzKGZOYW1lc3BhY2VTY2FubmVyKTsKLQotICAgICAgICBmRFREU2Nhbm5lciA9IG5ldyBYTUxEVERTY2FubmVySW1wbCgpOwotICAgICAgICBmUHJvcGVydGllcy5wdXQoRFREX1NDQU5ORVIsIGZEVERTY2FubmVyKTsKLSAgICAgICAgYWRkUmVjb2duaXplZFBhcmFtc0FuZFNldERlZmF1bHRzKGZEVERTY2FubmVyKTsKLQotICAgICAgICBmRGF0YXR5cGVWYWxpZGF0b3JGYWN0b3J5ID0gRFRERFZGYWN0b3J5LmdldEluc3RhbmNlKCk7Ci0gICAgICAgIGZQcm9wZXJ0aWVzLnB1dChEQVRBVFlQRV9WQUxJREFUT1JfRkFDVE9SWSwKLSAgICAgICAgICAgICAgICBmRGF0YXR5cGVWYWxpZGF0b3JGYWN0b3J5KTsKLQotICAgICAgICBmVmFsaWRhdGlvbk1hbmFnZXIgPSBuZXcgVmFsaWRhdGlvbk1hbmFnZXIoKTsKLSAgICAgICAgZlByb3BlcnRpZXMucHV0KFZBTElEQVRJT05fTUFOQUdFUiwgZlZhbGlkYXRpb25NYW5hZ2VyKTsKLQotICAgICAgICBmVmVyc2lvbkRldGVjdG9yID0gbmV3IFhNTFZlcnNpb25EZXRlY3RvcigpOwotCi0gICAgICAgIC8vIGFkZCBtZXNzYWdlIGZvcm1hdHRlcnMKLSAgICAgICAgaWYgKGZFcnJvclJlcG9ydGVyLmdldE1lc3NhZ2VGb3JtYXR0ZXIoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOKSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBYTUxNZXNzYWdlRm9ybWF0dGVyIHhtZnQgPSBuZXcgWE1MTWVzc2FnZUZvcm1hdHRlcigpOwotICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucHV0TWVzc2FnZUZvcm1hdHRlcihYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sIHhtZnQpOwotICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucHV0TWVzc2FnZUZvcm1hdHRlcihYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTE5TX0RPTUFJTiwgeG1mdCk7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoZkVycm9yUmVwb3J0ZXIuZ2V0TWVzc2FnZUZvcm1hdHRlcihYU01lc3NhZ2VGb3JtYXR0ZXIuU0NIRU1BX0RPTUFJTikgPT0gbnVsbCkgewotICAgICAgICAgICAgWFNNZXNzYWdlRm9ybWF0dGVyIHhtZnQgPSBuZXcgWFNNZXNzYWdlRm9ybWF0dGVyKCk7Ci0gICAgICAgICAgICBmRXJyb3JSZXBvcnRlci5wdXRNZXNzYWdlRm9ybWF0dGVyKFhTTWVzc2FnZUZvcm1hdHRlci5TQ0hFTUFfRE9NQUlOLCB4bWZ0KTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIHNldCBsb2NhbGUKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIHNldExvY2FsZShMb2NhbGUuZ2V0RGVmYXVsdCgpKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoWE5JRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIC8vIGRvIG5vdGhpbmcKLSAgICAgICAgICAgIC8vIFJFVklTSVQ6IFdoYXQgaXMgdGhlIHJpZ2h0IHRoaW5nIHRvIGRvPyAtQWMKLSAgICAgICAgfQotCi0gICAgfSAvLyA8aW5pdD4oU3ltYm9sVGFibGUsWE1MR3JhbW1hclBvb2wpCi0KLSAgICAvLwotICAgIC8vIFB1YmxpYyBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIHN0YXRlIG9mIGEgZmVhdHVyZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBmZWF0dXJlSWQgVGhlIGZlYXR1cmUgaWRlbnRpZmllci4KLSAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGZlYXR1cmUgaXMgc3VwcG9ydGVkCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gVGhyb3duIGZvciBjb25maWd1cmF0aW9uIGVycm9yLgotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbiBnZW5lcmFsLCBjb21wb25lbnRzIHNob3VsZAotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbmx5IHRocm93IHRoaXMgZXhjZXB0aW9uIGlmCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0IGlzIDxzdHJvbmc+cmVhbGx5PC9zdHJvbmc+Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGEgY3JpdGljYWwgZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIEZlYXR1cmVTdGF0ZSBnZXRGZWF0dXJlU3RhdGUoU3RyaW5nIGZlYXR1cmVJZCkKLSAgICAgICAgdGhyb3dzIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gewotICAgICAgICAvLyBtYWtlIHRoaXMgZmVhdHVyZSBzcGVjaWFsCi0gICAgICAgIGlmIChmZWF0dXJlSWQuZXF1YWxzKFBBUlNFUl9TRVRUSU5HUykpIHsKLSAgICAgICAgICAgIHJldHVybiBGZWF0dXJlU3RhdGUuaXMoZkNvbmZpZ1VwZGF0ZWQpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBzdXBlci5nZXRGZWF0dXJlU3RhdGUoZmVhdHVyZUlkKTsKLQotICAgIH0gLy8gZ2V0RmVhdHVyZShTdHJpbmcpOmJvb2xlYW4KLQotICAgIC8qKgotICAgICAqIFNldCB0aGUgc3RhdGUgb2YgYSBmZWF0dXJlLgotICAgICAqCi0gICAgICogU2V0IHRoZSBzdGF0ZSBvZiBhbnkgZmVhdHVyZSBpbiBhIFNBWDIgcGFyc2VyLiAgVGhlIHBhcnNlcgotICAgICAqIG1pZ2h0IG5vdCByZWNvZ25pemUgdGhlIGZlYXR1cmUsIGFuZCBpZiBpdCBkb2VzIHJlY29nbml6ZQotICAgICAqIGl0LCBpdCBtaWdodCBub3QgYmUgYWJsZSB0byBmdWxmaWxsIHRoZSByZXF1ZXN0LgotICAgICAqCi0gICAgICogQHBhcmFtIGZlYXR1cmVJZCBUaGUgdW5pcXVlIGlkZW50aWZpZXIgKFVSSSkgb2YgdGhlIGZlYXR1cmUuCi0gICAgICogQHBhcmFtIHN0YXRlIFRoZSByZXF1ZXN0ZWQgc3RhdGUgb2YgdGhlIGZlYXR1cmUgKHRydWUgb3IgZmFsc2UpLgotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBJZiB0aGUKLSAgICAgKiAgICAgICAgICAgIHJlcXVlc3RlZCBmZWF0dXJlIGlzIG5vdCBrbm93bi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRGZWF0dXJlKFN0cmluZyBmZWF0dXJlSWQsIGJvb2xlYW4gc3RhdGUpCi0gICAgICAgIHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIHsKLQotICAgICAgICBmQ29uZmlnVXBkYXRlZCA9IHRydWU7Ci0KLSAgICAgICAgLy8gZm9yd2FyZCB0byBldmVyeSBYTUwgMS4wIGNvbXBvbmVudAotICAgICAgICBmTmFtZXNwYWNlU2Nhbm5lci5zZXRGZWF0dXJlKGZlYXR1cmVJZCwgc3RhdGUpOwotICAgICAgICBmRFREU2Nhbm5lci5zZXRGZWF0dXJlKGZlYXR1cmVJZCwgc3RhdGUpOwotCi0gICAgICAgIC8vIGZvcndhcmQgdG8gZXZlcnkgWE1MIDEuMSBjb21wb25lbnQKLSAgICAgICAgaWYgKGYxMUluaXRpYWxpemVkKSB7Ci0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIGZYTUwxMURURFNjYW5uZXIuc2V0RmVhdHVyZShmZWF0dXJlSWQsIHN0YXRlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIGlnbm9yZSB0aGUgZXhjZXB0aW9uLgotICAgICAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7fQotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICBmWE1MMTFOU0RvY1NjYW5uZXIuc2V0RmVhdHVyZShmZWF0dXJlSWQsIHN0YXRlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIGlnbm9yZSB0aGUgZXhjZXB0aW9uCi0gICAgICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGUpIHt9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBzYXZlIHN0YXRlIGlmIG5vb25lICJvYmplY3RzIgotICAgICAgICBzdXBlci5zZXRGZWF0dXJlKGZlYXR1cmVJZCwgc3RhdGUpOwotCi0gICAgfSAvLyBzZXRGZWF0dXJlKFN0cmluZyxib29sZWFuKQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgYSBwcm9wZXJ0eS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBwcm9wZXJ0eUlkIFRoZSBwcm9wZXJ0eSBpZGVudGlmaWVyLgotICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBwcm9wZXJ0eQotICAgICAqCi0gICAgICogQHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIFRocm93biBmb3IgY29uZmlndXJhdGlvbiBlcnJvci4KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW4gZ2VuZXJhbCwgY29tcG9uZW50cyBzaG91bGQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb25seSB0aHJvdyB0aGlzIGV4Y2VwdGlvbiBpZgotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdCBpcyA8c3Ryb25nPnJlYWxseTwvc3Ryb25nPgotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhIGNyaXRpY2FsIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyBQcm9wZXJ0eVN0YXRlIGdldFByb3BlcnR5U3RhdGUoU3RyaW5nIHByb3BlcnR5SWQpCi0gICAgICAgIHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKExPQ0FMRS5lcXVhbHMocHJvcGVydHlJZCkpIHsKLSAgICAgICAgICAgIHJldHVybiBQcm9wZXJ0eVN0YXRlLmlzKGdldExvY2FsZSgpKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gc3VwZXIuZ2V0UHJvcGVydHlTdGF0ZShwcm9wZXJ0eUlkKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBzZXRQcm9wZXJ0eQotICAgICAqCi0gICAgICogQHBhcmFtIHByb3BlcnR5SWQKLSAgICAgKiBAcGFyYW0gdmFsdWUKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRQcm9wZXJ0eShTdHJpbmcgcHJvcGVydHlJZCwgT2JqZWN0IHZhbHVlKQotICAgICAgICB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgZkNvbmZpZ1VwZGF0ZWQgPSB0cnVlOwotICAgICAgICBpZiAoTE9DQUxFLmVxdWFscyhwcm9wZXJ0eUlkKSkgewotICAgICAgICAgICAgc2V0TG9jYWxlKChMb2NhbGUpIHZhbHVlKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIGZvcndhcmQgdG8gZXZlcnkgWE1MIDEuMCBjb21wb25lbnQKLSAgICAgICAgZk5hbWVzcGFjZVNjYW5uZXIuc2V0UHJvcGVydHkocHJvcGVydHlJZCwgdmFsdWUpOwotICAgICAgICBmRFREU2Nhbm5lci5zZXRQcm9wZXJ0eShwcm9wZXJ0eUlkLCB2YWx1ZSk7Ci0KLSAgICAgICAgLy8gZm9yd2FyZCB0byBldmVyeSBYTUwgMS4xIGNvbXBvbmVudAotICAgICAgICBpZiAoZjExSW5pdGlhbGl6ZWQpIHsKLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgZlhNTDExRFREU2Nhbm5lci5zZXRQcm9wZXJ0eShwcm9wZXJ0eUlkLCB2YWx1ZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyBpZ25vcmUgdGhlIGV4Y2VwdGlvbi4KLSAgICAgICAgICAgIGNhdGNoIChFeGNlcHRpb24gZSkge30KLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgZlhNTDExTlNEb2NTY2FubmVyLnNldFByb3BlcnR5KHByb3BlcnR5SWQsIHZhbHVlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIGlnbm9yZSB0aGUgZXhjZXB0aW9uCi0gICAgICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGUpIHt9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBzdG9yZSB2YWx1ZSBpZiBub29uZSAib2JqZWN0cyIKLSAgICAgICAgc3VwZXIuc2V0UHJvcGVydHkocHJvcGVydHlJZCwgdmFsdWUpOwotCi0gICAgfSAvLyBzZXRQcm9wZXJ0eShTdHJpbmcsT2JqZWN0KQotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSBsb2NhbGUgdG8gdXNlIGZvciBtZXNzYWdlcy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBsb2NhbGUgVGhlIGxvY2FsZSBvYmplY3QgdG8gdXNlIGZvciBsb2NhbGl6YXRpb24gb2YgbWVzc2FnZXMuCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIFhOSUV4Y2VwdGlvbiBUaHJvd24gaWYgdGhlIHBhcnNlciBkb2VzIG5vdCBzdXBwb3J0IHRoZQotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIHNwZWNpZmllZCBsb2NhbGUuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0TG9jYWxlKExvY2FsZSBsb2NhbGUpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBzdXBlci5zZXRMb2NhbGUobG9jYWxlKTsKLSAgICAgICAgZkVycm9yUmVwb3J0ZXIuc2V0TG9jYWxlKGxvY2FsZSk7Ci0gICAgfSAvLyBzZXRMb2NhbGUoTG9jYWxlKQotCi0gICAgLy8KLSAgICAvLyBYTUxQdWxsUGFyc2VyQ29uZmlndXJhdGlvbiBtZXRob2RzCi0gICAgLy8KLQotICAgIC8vIHBhcnNpbmcKLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIGlucHV0IHNvdXJjZSBmb3IgdGhlIGRvY3VtZW50IHRvIHBhcnNlLgotICAgICAqCi0gICAgICogQHBhcmFtIGlucHV0U291cmNlIFRoZSBkb2N1bWVudCdzIGlucHV0IHNvdXJjZS4KLSAgICAgKgotICAgICAqIEBleGNlcHRpb24gWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBUaHJvd24gaWYgdGhlcmUgaXMgYQotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgY29uZmlndXJhdGlvbiBlcnJvciB3aGVuIGluaXRpYWxpemluZyB0aGUKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgIHBhcnNlci4KLSAgICAgKiBAZXhjZXB0aW9uIElPRXhjZXB0aW9uIFRocm93biBvbiBJL08gZXJyb3IuCi0gICAgICoKLSAgICAgKiBAc2VlICNwYXJzZShib29sZWFuKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldElucHV0U291cmNlKFhNTElucHV0U291cmNlIGlucHV0U291cmNlKQotICAgIHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy8gUkVWSVNJVDogdGhpcyBtZXRob2QgdXNlZCB0byByZXNldCBhbGwgdGhlIGNvbXBvbmVudHMgYW5kCi0gICAgICAgIC8vICAgICAgICAgIGNvbnN0cnVjdCB0aGUgcGlwZWxpbmUuIE5vdyByZXNldCgpIGlzIGNhbGxlZAotICAgICAgICAvLyAgICAgICAgICBpbiBwYXJzZSAoYm9vbGVhbikganVzdCBiZWZvcmUgd2UgcGFyc2UgdGhlIGRvY3VtZW50Ci0gICAgICAgIC8vICAgICAgICAgIFNob3VsZCB0aGlzIG1ldGhvZCBzdGlsbCB0aHJvdyBleGNlcHRpb25zLi4/Ci0KLSAgICAgICAgZklucHV0U291cmNlID0gaW5wdXRTb3VyY2U7Ci0KLSAgICB9IC8vIHNldElucHV0U291cmNlKFhNTElucHV0U291cmNlKQotCi0gICAgLyoqCi0gICAgICogUGFyc2VzIHRoZSBkb2N1bWVudCBpbiBhIHB1bGwgcGFyc2luZyBmYXNoaW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIGNvbXBsZXRlIFRydWUgaWYgdGhlIHB1bGwgcGFyc2VyIHNob3VsZCBwYXJzZSB0aGUKLSAgICAgKiAgICAgICAgICAgICAgICAgcmVtYWluaW5nIGRvY3VtZW50IGNvbXBsZXRlbHkuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRydWUgaWYgdGhlcmUgaXMgbW9yZSBkb2N1bWVudCB0byBwYXJzZS4KLSAgICAgKgotICAgICAqIEBleGNlcHRpb24gWE5JRXhjZXB0aW9uIEFueSBYTkkgZXhjZXB0aW9uLCBwb3NzaWJseSB3cmFwcGluZwotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIGFub3RoZXIgZXhjZXB0aW9uLgotICAgICAqIEBleGNlcHRpb24gSU9FeGNlcHRpb24gIEFuIElPIGV4Y2VwdGlvbiBmcm9tIHRoZSBwYXJzZXIsIHBvc3NpYmx5Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgZnJvbSBhIGJ5dGUgc3RyZWFtIG9yIGNoYXJhY3RlciBzdHJlYW0KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBzdXBwbGllZCBieSB0aGUgcGFyc2VyLgotICAgICAqCi0gICAgICogQHNlZSAjc2V0SW5wdXRTb3VyY2UKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBwYXJzZShib29sZWFuIGNvbXBsZXRlKSB0aHJvd3MgWE5JRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgIC8vCi0gICAgICAgIC8vIHJlc2V0IGFuZCBjb25maWd1cmUgcGlwZWxpbmUgYW5kIHNldCBJbnB1dFNvdXJjZS4KLSAgICAgICAgaWYgKGZJbnB1dFNvdXJjZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIGZWYWxpZGF0aW9uTWFuYWdlci5yZXNldCgpOwotICAgICAgICAgICAgICAgIGZWZXJzaW9uRGV0ZWN0b3IucmVzZXQodGhpcyk7Ci0gICAgICAgICAgICAgICAgcmVzZXQoKTsKLQotICAgICAgICAgICAgICAgIHNob3J0IHZlcnNpb24gPSBmVmVyc2lvbkRldGVjdG9yLmRldGVybWluZURvY1ZlcnNpb24oZklucHV0U291cmNlKTsKLSAgICAgICAgICAgICAgICAvLyBYTUwgMS4wCi0gICAgICAgICAgICAgICAgaWYgKHZlcnNpb24gPT0gQ29uc3RhbnRzLlhNTF9WRVJTSU9OXzFfMCkgewotICAgICAgICAgICAgICAgICAgICBjb25maWd1cmVQaXBlbGluZSgpOwotICAgICAgICAgICAgICAgICAgICByZXNldFhNTDEwKCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIC8vIFhNTCAxLjEKLSAgICAgICAgICAgICAgICBlbHNlIGlmICh2ZXJzaW9uID09IENvbnN0YW50cy5YTUxfVkVSU0lPTl8xXzEpIHsKLSAgICAgICAgICAgICAgICAgICAgaW5pdFhNTDExQ29tcG9uZW50cygpOwotICAgICAgICAgICAgICAgICAgICBjb25maWd1cmVYTUwxMVBpcGVsaW5lKCk7Ci0gICAgICAgICAgICAgICAgICAgIHJlc2V0WE1MMTEoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLy8gVW5yZWNvdmVyYWJsZSBlcnJvciByZXBvcnRlZCBkdXJpbmcgdmVyc2lvbiBkZXRlY3Rpb24KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgLy8gbWFyayBjb25maWd1cmF0aW9uIGFzIGZpeGVkCi0gICAgICAgICAgICAgICAgZkNvbmZpZ1VwZGF0ZWQgPSBmYWxzZTsKLQotICAgICAgICAgICAgICAgIC8vIHJlc2V0cyBhbmQgc2V0cyB0aGUgcGlwZWxpbmUuCi0gICAgICAgICAgICAgICAgZlZlcnNpb25EZXRlY3Rvci5zdGFydERvY3VtZW50UGFyc2luZygoWE1MRW50aXR5SGFuZGxlcikgZkN1cnJlbnRTY2FubmVyLCB2ZXJzaW9uKTsKLSAgICAgICAgICAgICAgICBmSW5wdXRTb3VyY2UgPSBudWxsOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2F0Y2ggKFhOSUV4Y2VwdGlvbiBleCkgewotICAgICAgICAgICAgICAgIGlmIChQUklOVF9FWENFUFRJT05fU1RBQ0tfVFJBQ0UpCi0gICAgICAgICAgICAgICAgICAgIGV4LnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgICAgICAgICAgIHRocm93IGV4OwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7Ci0gICAgICAgICAgICAgICAgaWYgKFBSSU5UX0VYQ0VQVElPTl9TVEFDS19UUkFDRSkKLSAgICAgICAgICAgICAgICAgICAgZXgucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgICAgICAgICAgdGhyb3cgZXg7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiBleCkgewotICAgICAgICAgICAgICAgIGlmIChQUklOVF9FWENFUFRJT05fU1RBQ0tfVFJBQ0UpCi0gICAgICAgICAgICAgICAgICAgIGV4LnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgICAgICAgICAgIHRocm93IGV4OwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkgewotICAgICAgICAgICAgICAgIGlmIChQUklOVF9FWENFUFRJT05fU1RBQ0tfVFJBQ0UpCi0gICAgICAgICAgICAgICAgICAgIGV4LnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgICAgICAgICAgIHRocm93IG5ldyBYTklFeGNlcHRpb24oZXgpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIHJldHVybiBmQ3VycmVudFNjYW5uZXIuc2NhbkRvY3VtZW50KGNvbXBsZXRlKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoWE5JRXhjZXB0aW9uIGV4KSB7Ci0gICAgICAgICAgICBpZiAoUFJJTlRfRVhDRVBUSU9OX1NUQUNLX1RSQUNFKQotICAgICAgICAgICAgICAgIGV4LnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgICAgICAgdGhyb3cgZXg7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7Ci0gICAgICAgICAgICBpZiAoUFJJTlRfRVhDRVBUSU9OX1NUQUNLX1RSQUNFKQotICAgICAgICAgICAgICAgIGV4LnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgICAgICAgdGhyb3cgZXg7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gZXgpIHsKLSAgICAgICAgICAgIGlmIChQUklOVF9FWENFUFRJT05fU1RBQ0tfVFJBQ0UpCi0gICAgICAgICAgICAgICAgZXgucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgICAgICB0aHJvdyBleDsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7Ci0gICAgICAgICAgICBpZiAoUFJJTlRfRVhDRVBUSU9OX1NUQUNLX1RSQUNFKQotICAgICAgICAgICAgICAgIGV4LnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgICAgICAgdGhyb3cgbmV3IFhOSUV4Y2VwdGlvbihleCk7Ci0gICAgICAgIH0KLQotICAgIH0gLy8gcGFyc2UoYm9vbGVhbik6Ym9vbGVhbgotCi0gICAgLyoqCi0gICAgICogSWYgdGhlIGFwcGxpY2F0aW9uIGRlY2lkZXMgdG8gdGVybWluYXRlIHBhcnNpbmcgYmVmb3JlIHRoZSB4bWwgZG9jdW1lbnQKLSAgICAgKiBpcyBmdWxseSBwYXJzZWQsIHRoZSBhcHBsaWNhdGlvbiBzaG91bGQgY2FsbCB0aGlzIG1ldGhvZCB0byBmcmVlIGFueQotICAgICAqIHJlc291cmNlIGFsbG9jYXRlZCBkdXJpbmcgcGFyc2luZy4gRm9yIGV4YW1wbGUsIGNsb3NlIGFsbCBvcGVuZWQgc3RyZWFtcy4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBjbGVhbnVwKCkgewotICAgICAgICBmRW50aXR5TWFuYWdlci5jbG9zZVJlYWRlcnMoKTsKLSAgICB9Ci0KLSAgICAvLwotICAgIC8vIFhNTFBhcnNlckNvbmZpZ3VyYXRpb24gbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBQYXJzZXMgdGhlIHNwZWNpZmllZCBpbnB1dCBzb3VyY2UuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc291cmNlIFRoZSBpbnB1dCBzb3VyY2UuCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIFhOSUV4Y2VwdGlvbiBUaHJvd3MgZXhjZXB0aW9uIG9uIFhOSSBlcnJvci4KLSAgICAgKiBAZXhjZXB0aW9uIGphdmEuaW8uSU9FeGNlcHRpb24gVGhyb3dzIGV4Y2VwdGlvbiBvbiBpL28gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcGFyc2UoWE1MSW5wdXRTb3VyY2Ugc291cmNlKSB0aHJvd3MgWE5JRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7Ci0KLSAgICAgICAgaWYgKGZQYXJzZUluUHJvZ3Jlc3MpIHsKLSAgICAgICAgICAgIC8vIFJFVklTSVQgLSBuZWVkIHRvIGFkZCBuZXcgZXJyb3IgbWVzc2FnZQotICAgICAgICAgICAgdGhyb3cgbmV3IFhOSUV4Y2VwdGlvbigiRldLMDA1IHBhcnNlIG1heSBub3QgYmUgY2FsbGVkIHdoaWxlIHBhcnNpbmcuIik7Ci0gICAgICAgIH0KLSAgICAgICAgZlBhcnNlSW5Qcm9ncmVzcyA9IHRydWU7Ci0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIHNldElucHV0U291cmNlKHNvdXJjZSk7Ci0gICAgICAgICAgICBwYXJzZSh0cnVlKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoWE5JRXhjZXB0aW9uIGV4KSB7Ci0gICAgICAgICAgICBpZiAoUFJJTlRfRVhDRVBUSU9OX1NUQUNLX1RSQUNFKQotICAgICAgICAgICAgICAgIGV4LnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgICAgICAgdGhyb3cgZXg7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7Ci0gICAgICAgICAgICBpZiAoUFJJTlRfRVhDRVBUSU9OX1NUQUNLX1RSQUNFKQotICAgICAgICAgICAgICAgIGV4LnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgICAgICAgdGhyb3cgZXg7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gZXgpIHsKLSAgICAgICAgICAgIGlmIChQUklOVF9FWENFUFRJT05fU1RBQ0tfVFJBQ0UpCi0gICAgICAgICAgICAgICAgZXgucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgICAgICB0aHJvdyBleDsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7Ci0gICAgICAgICAgICBpZiAoUFJJTlRfRVhDRVBUSU9OX1NUQUNLX1RSQUNFKQotICAgICAgICAgICAgICAgIGV4LnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgICAgICAgdGhyb3cgbmV3IFhOSUV4Y2VwdGlvbihleCk7Ci0gICAgICAgIH0KLSAgICAgICAgZmluYWxseSB7Ci0gICAgICAgICAgICBmUGFyc2VJblByb2dyZXNzID0gZmFsc2U7Ci0gICAgICAgICAgICAvLyBjbG9zZSBhbGwgc3RyZWFtcyBvcGVuZWQgYnkgeGVyY2VzCi0gICAgICAgICAgICB0aGlzLmNsZWFudXAoKTsKLSAgICAgICAgfQotCi0gICAgfSAvLyBwYXJzZShJbnB1dFNvdXJjZSkKLQotICAgIC8vCi0gICAgLy8gUHJvdGVjdGVkIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogUmVzZXQgYWxsIGNvbXBvbmVudHMgYmVmb3JlIHBhcnNpbmcuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gaWYgYW4gZXJyb3Igb2NjdXJzIGR1cmluZyBpbml0aWFsaXphdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCByZXNldCgpIHRocm93cyBYTklFeGNlcHRpb24gewotCi0gICAgICAgIC8vIGluaXRpYWxpemUgdGhlIGNvbW1vbiBjb21wb25lbnRzCi0gICAgICAgIHN1cGVyLnJlc2V0KCk7Ci0KLSAgICB9IC8vIHJlc2V0KCkKLQotICAgIC8qKiBDb25maWd1cmVzIHRoZSBYTUwgMS4wIHBpcGVsaW5lLiAqLwotICAgIHByb3RlY3RlZCB2b2lkIGNvbmZpZ3VyZVBpcGVsaW5lKCkgewotCi0gICAgICAgIGlmIChmQ3VycmVudERWRmFjdG9yeSAhPSBmRGF0YXR5cGVWYWxpZGF0b3JGYWN0b3J5KSB7Ci0gICAgICAgICAgICBmQ3VycmVudERWRmFjdG9yeSA9IGZEYXRhdHlwZVZhbGlkYXRvckZhY3Rvcnk7Ci0gICAgICAgICAgICAvLyB1c2UgWE1MIDEuMCBkYXRhdHlwZSBsaWJyYXJ5Ci0gICAgICAgICAgICBzZXRQcm9wZXJ0eShEQVRBVFlQRV9WQUxJREFUT1JfRkFDVE9SWSwgZkN1cnJlbnREVkZhY3RvcnkpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gc2V0dXAgZG9jdW1lbnQgcGlwZWxpbmUKLSAgICAgICAgaWYgKGZDdXJyZW50U2Nhbm5lciAhPSBmTmFtZXNwYWNlU2Nhbm5lcikgewotICAgICAgICAgICAgZkN1cnJlbnRTY2FubmVyID0gZk5hbWVzcGFjZVNjYW5uZXI7Ci0gICAgICAgICAgICBzZXRQcm9wZXJ0eShET0NVTUVOVF9TQ0FOTkVSLCBmQ3VycmVudFNjYW5uZXIpOwotICAgICAgICB9Ci0gICAgICAgIGZOYW1lc3BhY2VTY2FubmVyLnNldERvY3VtZW50SGFuZGxlcihmRG9jdW1lbnRIYW5kbGVyKTsKLSAgICAgICAgaWYgKGZEb2N1bWVudEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci5zZXREb2N1bWVudFNvdXJjZShmTmFtZXNwYWNlU2Nhbm5lcik7Ci0gICAgICAgIH0KLSAgICAgICAgZkxhc3RDb21wb25lbnQgPSBmTmFtZXNwYWNlU2Nhbm5lcjsKLQotICAgICAgICAvLyBzZXR1cCBkdGQgcGlwZWxpbmUKLSAgICAgICAgaWYgKGZDdXJyZW50RFREU2Nhbm5lciAhPSBmRFREU2Nhbm5lcikgewotICAgICAgICAgICAgZkN1cnJlbnREVERTY2FubmVyID0gZkRURFNjYW5uZXI7Ci0gICAgICAgICAgICBzZXRQcm9wZXJ0eShEVERfU0NBTk5FUiwgZkN1cnJlbnREVERTY2FubmVyKTsKLSAgICAgICAgfQotICAgICAgICBmRFREU2Nhbm5lci5zZXREVERIYW5kbGVyKGZEVERIYW5kbGVyKTsKLSAgICAgICAgaWYgKGZEVERIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZEVERIYW5kbGVyLnNldERURFNvdXJjZShmRFREU2Nhbm5lcik7Ci0gICAgICAgIH0KLSAgICAgICAgZkRURFNjYW5uZXIuc2V0RFREQ29udGVudE1vZGVsSGFuZGxlcihmRFREQ29udGVudE1vZGVsSGFuZGxlcik7Ci0gICAgICAgIGlmIChmRFREQ29udGVudE1vZGVsSGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmRFREQ29udGVudE1vZGVsSGFuZGxlci5zZXREVERDb250ZW50TW9kZWxTb3VyY2UoZkRURFNjYW5uZXIpOwotICAgICAgICB9Ci0KLSAgICB9IC8vIGNvbmZpZ3VyZVBpcGVsaW5lKCkKLQotICAgIC8qKiBDb25maWd1cmVzIHRoZSBYTUwgMS4xIHBpcGVsaW5lLiAqLwotICAgIHByb3RlY3RlZCB2b2lkIGNvbmZpZ3VyZVhNTDExUGlwZWxpbmUoKSB7Ci0KLSAgICAgICAgaWYgKGZDdXJyZW50RFZGYWN0b3J5ICE9IGZYTUwxMURhdGF0eXBlRmFjdG9yeSkgewotICAgICAgICAgICAgZkN1cnJlbnREVkZhY3RvcnkgPSBmWE1MMTFEYXRhdHlwZUZhY3Rvcnk7Ci0gICAgICAgICAgICAvLyB1c2UgWE1MIDEuMSBkYXRhdHlwZSBsaWJyYXJ5Ci0gICAgICAgICAgICBzZXRQcm9wZXJ0eShEQVRBVFlQRV9WQUxJREFUT1JfRkFDVE9SWSwgZkN1cnJlbnREVkZhY3RvcnkpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gc2V0dXAgZG9jdW1lbnQgcGlwZWxpbmUKLSAgICAgICAgaWYgKGZDdXJyZW50U2Nhbm5lciAhPSBmWE1MMTFOU0RvY1NjYW5uZXIpIHsKLSAgICAgICAgICAgIGZDdXJyZW50U2Nhbm5lciA9IGZYTUwxMU5TRG9jU2Nhbm5lcjsKLSAgICAgICAgICAgIHNldFByb3BlcnR5KERPQ1VNRU5UX1NDQU5ORVIsIGZDdXJyZW50U2Nhbm5lcik7Ci0gICAgICAgIH0KLSAgICAgICAgZlhNTDExTlNEb2NTY2FubmVyLnNldERvY3VtZW50SGFuZGxlcihmRG9jdW1lbnRIYW5kbGVyKTsKLSAgICAgICAgaWYgKGZEb2N1bWVudEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci5zZXREb2N1bWVudFNvdXJjZShmWE1MMTFOU0RvY1NjYW5uZXIpOwotICAgICAgICB9Ci0gICAgICAgIGZMYXN0Q29tcG9uZW50ID0gZlhNTDExTlNEb2NTY2FubmVyOwotCi0gICAgICAgIC8vIHNldHVwIGR0ZCBwaXBlbGluZQotICAgICAgICBpZiAoZkN1cnJlbnREVERTY2FubmVyICE9IGZYTUwxMURURFNjYW5uZXIpIHsKLSAgICAgICAgICAgIGZDdXJyZW50RFREU2Nhbm5lciA9IGZYTUwxMURURFNjYW5uZXI7Ci0gICAgICAgICAgICBzZXRQcm9wZXJ0eShEVERfU0NBTk5FUiwgZkN1cnJlbnREVERTY2FubmVyKTsKLSAgICAgICAgfQotICAgICAgICBmWE1MMTFEVERTY2FubmVyLnNldERUREhhbmRsZXIoZkRUREhhbmRsZXIpOwotICAgICAgICBpZiAoZkRUREhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkRUREhhbmRsZXIuc2V0RFREU291cmNlKGZYTUwxMURURFNjYW5uZXIpOwotICAgICAgICB9Ci0gICAgICAgIGZYTUwxMURURFNjYW5uZXIuc2V0RFREQ29udGVudE1vZGVsSGFuZGxlcihmRFREQ29udGVudE1vZGVsSGFuZGxlcik7Ci0gICAgICAgIGlmIChmRFREQ29udGVudE1vZGVsSGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmRFREQ29udGVudE1vZGVsSGFuZGxlci5zZXREVERDb250ZW50TW9kZWxTb3VyY2UoZlhNTDExRFREU2Nhbm5lcik7Ci0gICAgICAgIH0KLQotICAgIH0gLy8gY29uZmlndXJlWE1MMTFQaXBlbGluZSgpCi0KLSAgICAvLyBmZWF0dXJlcyBhbmQgcHJvcGVydGllcwotCi0gICAgLyoqCi0gICAgICogQ2hlY2sgYSBmZWF0dXJlLiBJZiBmZWF0dXJlIGlzIGtub3cgYW5kIHN1cHBvcnRlZCwgdGhpcyBtZXRob2Qgc2ltcGx5Ci0gICAgICogcmV0dXJucy4gT3RoZXJ3aXNlLCB0aGUgYXBwcm9wcmlhdGUgZXhjZXB0aW9uIGlzIHRocm93bi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBmZWF0dXJlSWQgVGhlIHVuaXF1ZSBpZGVudGlmaWVyIChVUkkpIG9mIHRoZSBmZWF0dXJlLgotICAgICAqCi0gICAgICogQHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIFRocm93biBmb3IgY29uZmlndXJhdGlvbiBlcnJvci4KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW4gZ2VuZXJhbCwgY29tcG9uZW50cyBzaG91bGQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb25seSB0aHJvdyB0aGlzIGV4Y2VwdGlvbiBpZgotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdCBpcyA8c3Ryb25nPnJlYWxseTwvc3Ryb25nPgotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhIGNyaXRpY2FsIGVycm9yLgotICAgICAqLwotICAgIHByb3RlY3RlZCBGZWF0dXJlU3RhdGUgY2hlY2tGZWF0dXJlKFN0cmluZyBmZWF0dXJlSWQpCi0gICAgICAgIHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIHsKLQotICAgICAgICAvLwotICAgICAgICAvLyBYZXJjZXMgRmVhdHVyZXMKLSAgICAgICAgLy8KLQotICAgICAgICBpZiAoZmVhdHVyZUlkLnN0YXJ0c1dpdGgoQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCkpIHsKLSAgICAgICAgICAgIGZpbmFsIGludCBzdWZmaXhMZW5ndGggPSBmZWF0dXJlSWQubGVuZ3RoKCkgLSBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYLmxlbmd0aCgpOwotCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgLy8gaHR0cDovL2FwYWNoZS5vcmcveG1sL2ZlYXR1cmVzL3ZhbGlkYXRpb24vZHluYW1pYwotICAgICAgICAgICAgLy8gICBBbGxvd3MgdGhlIHBhcnNlciB0byB2YWxpZGF0ZSBhIGRvY3VtZW50IG9ubHkgd2hlbiBpdAotICAgICAgICAgICAgLy8gICBjb250YWlucyBhIGdyYW1tYXIuIFZhbGlkYXRpb24gaXMgdHVybmVkIG9uL29mZiBiYXNlZAotICAgICAgICAgICAgLy8gICBvbiBlYWNoIGRvY3VtZW50IGluc3RhbmNlLCBhdXRvbWF0aWNhbGx5LgotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIGlmIChzdWZmaXhMZW5ndGggPT0gQ29uc3RhbnRzLkRZTkFNSUNfVkFMSURBVElPTl9GRUFUVVJFLmxlbmd0aCgpICYmCi0gICAgICAgICAgICAgICAgICAgIGZlYXR1cmVJZC5lbmRzV2l0aChDb25zdGFudHMuRFlOQU1JQ19WQUxJREFUSU9OX0ZFQVRVUkUpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIEZlYXR1cmVTdGF0ZS5SRUNPR05JWkVEOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIC8vIGh0dHA6Ly9hcGFjaGUub3JnL3htbC9mZWF0dXJlcy92YWxpZGF0aW9uL2RlZmF1bHQtYXR0cmlidXRlLXZhbHVlcwotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIGlmIChzdWZmaXhMZW5ndGggPT0gQ29uc3RhbnRzLkRFRkFVTFRfQVRUUklCVVRFX1ZBTFVFU19GRUFUVVJFLmxlbmd0aCgpICYmCi0gICAgICAgICAgICAgICAgICAgIGZlYXR1cmVJZC5lbmRzV2l0aChDb25zdGFudHMuREVGQVVMVF9BVFRSSUJVVEVfVkFMVUVTX0ZFQVRVUkUpKSB7Ci0gICAgICAgICAgICAgICAgLy8gUkVWSVNJVAotICAgICAgICAgICAgICAgIHJldHVybiBGZWF0dXJlU3RhdGUuTk9UX1NVUFBPUlRFRDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAvLyBodHRwOi8vYXBhY2hlLm9yZy94bWwvZmVhdHVyZXMvdmFsaWRhdGlvbi9kZWZhdWx0LWF0dHJpYnV0ZS12YWx1ZXMKLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICBpZiAoc3VmZml4TGVuZ3RoID09IENvbnN0YW50cy5WQUxJREFURV9DT05URU5UX01PREVMU19GRUFUVVJFLmxlbmd0aCgpICYmCi0gICAgICAgICAgICAgICAgICAgIGZlYXR1cmVJZC5lbmRzV2l0aChDb25zdGFudHMuVkFMSURBVEVfQ09OVEVOVF9NT0RFTFNfRkVBVFVSRSkpIHsKLSAgICAgICAgICAgICAgICAvLyBSRVZJU0lUCi0gICAgICAgICAgICAgICAgcmV0dXJuIEZlYXR1cmVTdGF0ZS5OT1RfU1VQUE9SVEVEOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIC8vIGh0dHA6Ly9hcGFjaGUub3JnL3htbC9mZWF0dXJlcy92YWxpZGF0aW9uL25vbnZhbGlkYXRpbmcvbG9hZC1kdGQtZ3JhbW1hcgotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIGlmIChzdWZmaXhMZW5ndGggPT0gQ29uc3RhbnRzLkxPQURfRFREX0dSQU1NQVJfRkVBVFVSRS5sZW5ndGgoKSAmJgotICAgICAgICAgICAgICAgICAgICBmZWF0dXJlSWQuZW5kc1dpdGgoQ29uc3RhbnRzLkxPQURfRFREX0dSQU1NQVJfRkVBVFVSRSkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gRmVhdHVyZVN0YXRlLlJFQ09HTklaRUQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLwotICAgICAgICAgICAgLy8gaHR0cDovL2FwYWNoZS5vcmcveG1sL2ZlYXR1cmVzL3ZhbGlkYXRpb24vbm9udmFsaWRhdGluZy9sb2FkLWV4dGVybmFsLWR0ZAotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIGlmIChzdWZmaXhMZW5ndGggPT0gQ29uc3RhbnRzLkxPQURfRVhURVJOQUxfRFREX0ZFQVRVUkUubGVuZ3RoKCkgJiYKLSAgICAgICAgICAgICAgICAgICAgZmVhdHVyZUlkLmVuZHNXaXRoKENvbnN0YW50cy5MT0FEX0VYVEVSTkFMX0RURF9GRUFUVVJFKSkgewotICAgICAgICAgICAgICAgIHJldHVybiBGZWF0dXJlU3RhdGUuUkVDT0dOSVpFRDsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIC8vIGh0dHA6Ly9hcGFjaGUub3JnL3htbC9mZWF0dXJlcy92YWxpZGF0aW9uL2RlZmF1bHQtYXR0cmlidXRlLXZhbHVlcwotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIGlmIChzdWZmaXhMZW5ndGggPT0gQ29uc3RhbnRzLlZBTElEQVRFX0RBVEFUWVBFU19GRUFUVVJFLmxlbmd0aCgpICYmCi0gICAgICAgICAgICAgICAgICAgIGZlYXR1cmVJZC5lbmRzV2l0aChDb25zdGFudHMuVkFMSURBVEVfREFUQVRZUEVTX0ZFQVRVUkUpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIEZlYXR1cmVTdGF0ZS5OT1RfU1VQUE9SVEVEOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gTm90IHJlY29nbml6ZWQKLSAgICAgICAgLy8KLQotICAgICAgICByZXR1cm4gc3VwZXIuY2hlY2tGZWF0dXJlKGZlYXR1cmVJZCk7Ci0KLSAgICB9IC8vIGNoZWNrRmVhdHVyZShTdHJpbmcpCi0KLSAgICAvKioKLSAgICAgKiBDaGVjayBhIHByb3BlcnR5LiBJZiB0aGUgcHJvcGVydHkgaXMga25vdyBhbmQgc3VwcG9ydGVkLCB0aGlzIG1ldGhvZAotICAgICAqIHNpbXBseSByZXR1cm5zLiBPdGhlcndpc2UsIHRoZSBhcHByb3ByaWF0ZSBleGNlcHRpb24gaXMgdGhyb3duLgotICAgICAqCi0gICAgICogQHBhcmFtIHByb3BlcnR5SWQgVGhlIHVuaXF1ZSBpZGVudGlmaWVyIChVUkkpIG9mIHRoZSBwcm9wZXJ0eQotICAgICAqICAgICAgICAgICAgICAgICAgIGJlaW5nIHNldC4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBUaHJvd24gZm9yIGNvbmZpZ3VyYXRpb24gZXJyb3IuCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluIGdlbmVyYWwsIGNvbXBvbmVudHMgc2hvdWxkCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9ubHkgdGhyb3cgdGhpcyBleGNlcHRpb24gaWYKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXQgaXMgPHN0cm9uZz5yZWFsbHk8L3N0cm9uZz4KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYSBjcml0aWNhbCBlcnJvci4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgUHJvcGVydHlTdGF0ZSBjaGVja1Byb3BlcnR5KFN0cmluZyBwcm9wZXJ0eUlkKQotICAgICAgICB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gWGVyY2VzIFByb3BlcnRpZXMKLSAgICAgICAgLy8KLQotICAgICAgICBpZiAocHJvcGVydHlJZC5zdGFydHNXaXRoKENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYKSkgewotICAgICAgICAgICAgZmluYWwgaW50IHN1ZmZpeExlbmd0aCA9IHByb3BlcnR5SWQubGVuZ3RoKCkgLSBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWC5sZW5ndGgoKTsKLQotICAgICAgICAgICAgaWYgKHN1ZmZpeExlbmd0aCA9PSBDb25zdGFudHMuRFREX1NDQU5ORVJfUFJPUEVSVFkubGVuZ3RoKCkgJiYKLSAgICAgICAgICAgICAgICAgICAgcHJvcGVydHlJZC5lbmRzV2l0aChDb25zdGFudHMuRFREX1NDQU5ORVJfUFJPUEVSVFkpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIFByb3BlcnR5U3RhdGUuUkVDT0dOSVpFRDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGlmIChwcm9wZXJ0eUlkLnN0YXJ0c1dpdGgoQ29uc3RhbnRzLkpBWFBfUFJPUEVSVFlfUFJFRklYKSkgewotICAgICAgICAgICAgZmluYWwgaW50IHN1ZmZpeExlbmd0aCA9IHByb3BlcnR5SWQubGVuZ3RoKCkgLSBDb25zdGFudHMuSkFYUF9QUk9QRVJUWV9QUkVGSVgubGVuZ3RoKCk7Ci0KLSAgICAgICAgICAgIGlmIChzdWZmaXhMZW5ndGggPT0gQ29uc3RhbnRzLlNDSEVNQV9TT1VSQ0UubGVuZ3RoKCkgJiYKLSAgICAgICAgICAgICAgICAgICAgcHJvcGVydHlJZC5lbmRzV2l0aChDb25zdGFudHMuU0NIRU1BX1NPVVJDRSkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gUHJvcGVydHlTdGF0ZS5SRUNPR05JWkVEOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gTm90IHJlY29nbml6ZWQKLSAgICAgICAgLy8KLQotICAgICAgICByZXR1cm4gc3VwZXIuY2hlY2tQcm9wZXJ0eShwcm9wZXJ0eUlkKTsKLQotICAgIH0gLy8gY2hlY2tQcm9wZXJ0eShTdHJpbmcpCi0KLSAgICAvKioKLSAgICAgKiBBZGRzIGFsbCBvZiB0aGUgY29tcG9uZW50J3MgcmVjb2duaXplZCBmZWF0dXJlcyBhbmQgcHJvcGVydGllcwotICAgICAqIHRvIHRoZSBsaXN0IG9mIGRlZmF1bHQgcmVjb2duaXplZCBmZWF0dXJlcyBhbmQgcHJvcGVydGllcywgYW5kCi0gICAgICogc2V0cyBkZWZhdWx0IHZhbHVlcyBvbiB0aGUgY29uZmlndXJhdGlvbiBmb3IgZmVhdHVyZXMgYW5kCi0gICAgICogcHJvcGVydGllcyB3aGljaCB3ZXJlIHByZXZpb3VzbHkgYWJzZW50IGZyb20gdGhlIGNvbmZpZ3VyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29tcG9uZW50IFRoZSBjb21wb25lbnQgd2hvc2UgcmVjb2duaXplZCBmZWF0dXJlcwotICAgICAqIGFuZCBwcm9wZXJ0aWVzIHdpbGwgYmUgYWRkZWQgdG8gdGhlIGNvbmZpZ3VyYXRpb24KLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgYWRkUmVjb2duaXplZFBhcmFtc0FuZFNldERlZmF1bHRzKFhNTENvbXBvbmVudCBjb21wb25lbnQpIHsKLQotICAgICAgICAvLyByZWdpc3RlciBjb21wb25lbnQncyByZWNvZ25pemVkIGZlYXR1cmVzCi0gICAgICAgIFN0cmluZ1tdIHJlY29nbml6ZWRGZWF0dXJlcyA9IGNvbXBvbmVudC5nZXRSZWNvZ25pemVkRmVhdHVyZXMoKTsKLSAgICAgICAgYWRkUmVjb2duaXplZEZlYXR1cmVzKHJlY29nbml6ZWRGZWF0dXJlcyk7Ci0KLSAgICAgICAgLy8gcmVnaXN0ZXIgY29tcG9uZW50J3MgcmVjb2duaXplZCBwcm9wZXJ0aWVzCi0gICAgICAgIFN0cmluZ1tdIHJlY29nbml6ZWRQcm9wZXJ0aWVzID0gY29tcG9uZW50LmdldFJlY29nbml6ZWRQcm9wZXJ0aWVzKCk7Ci0gICAgICAgIGFkZFJlY29nbml6ZWRQcm9wZXJ0aWVzKHJlY29nbml6ZWRQcm9wZXJ0aWVzKTsKLQotICAgICAgICAvLyBzZXQgZGVmYXVsdCB2YWx1ZXMKLSAgICAgICAgaWYgKHJlY29nbml6ZWRGZWF0dXJlcyAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlY29nbml6ZWRGZWF0dXJlcy5sZW5ndGg7ICsraSkgewotICAgICAgICAgICAgICAgIFN0cmluZyBmZWF0dXJlSWQgPSByZWNvZ25pemVkRmVhdHVyZXNbaV07Ci0gICAgICAgICAgICAgICAgQm9vbGVhbiBzdGF0ZSA9IGNvbXBvbmVudC5nZXRGZWF0dXJlRGVmYXVsdChmZWF0dXJlSWQpOwotICAgICAgICAgICAgICAgIGlmIChzdGF0ZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIERvIG5vdCBvdmVyd3JpdGUgdmFsdWVzIGFscmVhZHkgc2V0IG9uIHRoZSBjb25maWd1cmF0aW9uLgotICAgICAgICAgICAgICAgICAgICBpZiAoIWZGZWF0dXJlcy5jb250YWluc0tleShmZWF0dXJlSWQpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmRmVhdHVyZXMucHV0KGZlYXR1cmVJZCwgc3RhdGUpOwotICAgICAgICAgICAgICAgICAgICAgICAgLy8gRm9yIG5ld2x5IGFkZGVkIGNvbXBvbmVudHMgd2hvIHJlY29nbml6ZSB0aGlzIGZlYXR1cmUKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGJ1dCBkaWQgbm90IG9mZmVyIGEgZGVmYXVsdCB2YWx1ZSwgd2UgbmVlZCB0byBtYWtlCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBzdXJlIHRoZXNlIGNvbXBvbmVudHMgd2lsbCBnZXQgYW4gb3Bwb3J0dW5pdHkgdG8gcmVhZAotICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhlIHZhbHVlIGJlZm9yZSBwYXJzaW5nIGJlZ2lucy4KLSAgICAgICAgICAgICAgICAgICAgICAgIGZDb25maWdVcGRhdGVkID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBpZiAocmVjb2duaXplZFByb3BlcnRpZXMgIT0gbnVsbCkgewotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZWNvZ25pemVkUHJvcGVydGllcy5sZW5ndGg7ICsraSkgewotICAgICAgICAgICAgICAgIFN0cmluZyBwcm9wZXJ0eUlkID0gcmVjb2duaXplZFByb3BlcnRpZXNbaV07Ci0gICAgICAgICAgICAgICAgT2JqZWN0IHZhbHVlID0gY29tcG9uZW50LmdldFByb3BlcnR5RGVmYXVsdChwcm9wZXJ0eUlkKTsKLSAgICAgICAgICAgICAgICBpZiAodmFsdWUgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAvLyBEbyBub3Qgb3ZlcndyaXRlIHZhbHVlcyBhbHJlYWR5IHNldCBvbiB0aGUgY29uZmlndXJhdGlvbi4KLSAgICAgICAgICAgICAgICAgICAgaWYgKCFmUHJvcGVydGllcy5jb250YWluc0tleShwcm9wZXJ0eUlkKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgZlByb3BlcnRpZXMucHV0KHByb3BlcnR5SWQsIHZhbHVlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIEZvciBuZXdseSBhZGRlZCBjb21wb25lbnRzIHdobyByZWNvZ25pemUgdGhpcyBwcm9wZXJ0eQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gYnV0IGRpZCBub3Qgb2ZmZXIgYSBkZWZhdWx0IHZhbHVlLCB3ZSBuZWVkIHRvIG1ha2UKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIHN1cmUgdGhlc2UgY29tcG9uZW50cyB3aWxsIGdldCBhbiBvcHBvcnR1bml0eSB0byByZWFkCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGUgdmFsdWUgYmVmb3JlIHBhcnNpbmcgYmVnaW5zLgotICAgICAgICAgICAgICAgICAgICAgICAgZkNvbmZpZ1VwZGF0ZWQgPSB0cnVlOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmVzZXQgYWxsIFhNTCAxLjAgY29tcG9uZW50cyBiZWZvcmUgcGFyc2luZwotICAgICAqLwotICAgIHByb3RlY3RlZCBmaW5hbCB2b2lkIHJlc2V0WE1MMTAoKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgLy8gUmVzZXQgWE1MIDEuMCBjb21wb25lbnRzCi0gICAgICAgIGZOYW1lc3BhY2VTY2FubmVyLnJlc2V0KHRoaXMpOwotICAgICAgICBmRFREU2Nhbm5lci5yZXNldCh0aGlzKTsKLSAgICB9IC8vIHJlc2V0WE1MMTAoKQotCi0gICAgLyoqCi0gICAgICogUmVzZXQgYWxsIFhNTCAxLjEgY29tcG9uZW50cyBiZWZvcmUgcGFyc2luZwotICAgICAqLwotICAgIHByb3RlY3RlZCBmaW5hbCB2b2lkIHJlc2V0WE1MMTEoKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgLy8gUmVzZXQgWE1MIDEuMSBjb21wb25lbnRzCi0gICAgICAgIGZYTUwxMU5TRG9jU2Nhbm5lci5yZXNldCh0aGlzKTsKLSAgICAgICAgZlhNTDExRFREU2Nhbm5lci5yZXNldCh0aGlzKTsKLSAgICB9IC8vIHJlc2V0WE1MMTEoKQotCi0gICAgLy8KLSAgICAvLyBvdGhlciBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKiAqLwotICAgIHB1YmxpYyB2b2lkIHJlc2V0Tm9kZVBvb2woKSB7Ci0gICAgICAgIC8vIFJFVklTSVQ6IHRvIGltcGxlbWVudDogaW50cm9kdWNlIGEgbm9kZSBwb29sIHRvIHJldXNlIERUTSBub2Rlcy4KLSAgICAgICAgLy8gICAgICAgICAgcmVzZXQgdGhpcyBwb29sIGhlcmUuCi0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIGluaXRYTUwxMUNvbXBvbmVudHMoKSB7Ci0gICAgICAgIGlmICghZjExSW5pdGlhbGl6ZWQpIHsKLSAgICAgICAgICAgIC8vIGNyZWF0ZSBkYXRhdHlwZSBmYWN0b3J5Ci0gICAgICAgICAgICBmWE1MMTFEYXRhdHlwZUZhY3RvcnkgPSBEVEREVkZhY3RvcnkuZ2V0SW5zdGFuY2UoWE1MMTFfREFUQVRZUEVfVkFMSURBVE9SX0ZBQ1RPUlkpOwotCi0gICAgICAgICAgICAvLyBzZXR1cCBYTUwgMS4xIERURCBwaXBlbGluZQotICAgICAgICAgICAgZlhNTDExRFREU2Nhbm5lciA9IG5ldyBYTUwxMURURFNjYW5uZXJJbXBsKCk7Ci0gICAgICAgICAgICBhZGRSZWNvZ25pemVkUGFyYW1zQW5kU2V0RGVmYXVsdHMoZlhNTDExRFREU2Nhbm5lcik7Ci0KLSAgICAgICAgICAgIC8vIHNldHVwIFhNTCAxLjEuIGRvY3VtZW50IHBpcGVsaW5lIC0gbmFtZXNwYWNlIGF3YXJlCi0gICAgICAgICAgICBmWE1MMTFOU0RvY1NjYW5uZXIgPSBuZXcgWE1MMTFOU0RvY3VtZW50U2Nhbm5lckltcGwoKTsKLSAgICAgICAgICAgIGFkZFJlY29nbml6ZWRQYXJhbXNBbmRTZXREZWZhdWx0cyhmWE1MMTFOU0RvY1NjYW5uZXIpOwotCi0gICAgICAgICAgICBmMTFJbml0aWFsaXplZCA9IHRydWU7Ci0gICAgICAgIH0KLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL29wdGkvVGV4dEltcGwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvb3B0aS9UZXh0SW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzNDc2ZTY0Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvb3B0aS9UZXh0SW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTMwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLm9wdGk7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5ET01FeGNlcHRpb247Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLQotLyoqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBOZWlsIEdyYWhhbSwgSUJNCi0gKi8KLQotcHVibGljIGNsYXNzIFRleHRJbXBsIGV4dGVuZHMgRGVmYXVsdFRleHQgewotCi0gICAgLy8gRGF0YQotICAgIFN0cmluZyBmRGF0YSA9IG51bGw7Ci0gICAgU2NoZW1hRE9NIGZTY2hlbWFET00gPSBudWxsOwotICAgIGludCBmUm93OwotICAgIGludCBmQ29sOwotCi0gICAgcHVibGljIFRleHRJbXBsKFN0cmluZ0J1ZmZlciBzdHIsIFNjaGVtYURPTSBzRE9NLCBpbnQgcm93LCBpbnQgY29sKSB7Ci0gICAgICAgIGZEYXRhID0gc3RyLnRvU3RyaW5nKCk7Ci0gICAgICAgIGZTY2hlbWFET00gPSBzRE9NOwotICAgICAgICBmUm93ID0gcm93OwotICAgICAgICBmQ29sID0gY29sOwotICAgICAgICByYXduYW1lID0gcHJlZml4ID0gbG9jYWxwYXJ0ID0gdXJpID0gbnVsbDsKLSAgICAgICAgbm9kZVR5cGUgPSBOb2RlLlRFWFRfTk9ERTsKLSAgICB9Ci0KLSAgICAvLwotICAgIC8vIG9yZy53M2MuZG9tLk5vZGUgbWV0aG9kcwotICAgIC8vCi0KLSAgICBwdWJsaWMgTm9kZSBnZXRQYXJlbnROb2RlKCkgewotICAgICAgICByZXR1cm4gZlNjaGVtYURPTS5yZWxhdGlvbnNbZlJvd11bMF07Ci0gICAgfQotCi0gICAgcHVibGljIE5vZGUgZ2V0UHJldmlvdXNTaWJsaW5nKCkgewotICAgICAgICBpZiAoZkNvbCA9PSAxKSB7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZlNjaGVtYURPTS5yZWxhdGlvbnNbZlJvd11bZkNvbC0xXTsKLSAgICB9Ci0KLQotICAgIHB1YmxpYyBOb2RlIGdldE5leHRTaWJsaW5nKCkgewotICAgICAgICBpZiAoZkNvbCA9PSBmU2NoZW1hRE9NLnJlbGF0aW9uc1tmUm93XS5sZW5ndGgtMSkgewotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGZTY2hlbWFET00ucmVsYXRpb25zW2ZSb3ddW2ZDb2wrMV07Ci0gICAgfQotCi0gICAgLy8gQ2hhcmFjdGVyRGF0YSBtZXRob2RzCi0KLSAgICAvKioKLSAgICAgKiBUaGUgY2hhcmFjdGVyIGRhdGEgb2YgdGhlIG5vZGUgdGhhdCBpbXBsZW1lbnRzIHRoaXMgaW50ZXJmYWNlLiBUaGUgRE9NCi0gICAgICogaW1wbGVtZW50YXRpb24gbWF5IG5vdCBwdXQgYXJiaXRyYXJ5IGxpbWl0cyBvbiB0aGUgYW1vdW50IG9mIGRhdGEKLSAgICAgKiB0aGF0IG1heSBiZSBzdG9yZWQgaW4gYSA8Y29kZT5DaGFyYWN0ZXJEYXRhPC9jb2RlPiBub2RlLiBIb3dldmVyLAotICAgICAqIGltcGxlbWVudGF0aW9uIGxpbWl0cyBtYXkgbWVhbiB0aGF0IHRoZSBlbnRpcmV0eSBvZiBhIG5vZGUncyBkYXRhIG1heQotICAgICAqIG5vdCBmaXQgaW50byBhIHNpbmdsZSA8Y29kZT5ET01TdHJpbmc8L2NvZGU+LiBJbiBzdWNoIGNhc2VzLCB0aGUgdXNlcgotICAgICAqIG1heSBjYWxsIDxjb2RlPnN1YnN0cmluZ0RhdGE8L2NvZGU+IHRvIHJldHJpZXZlIHRoZSBkYXRhIGluCi0gICAgICogYXBwcm9wcmlhdGVseSBzaXplZCBwaWVjZXMuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIHdoZW4gdGhlIG5vZGUgaXMgcmVhZG9ubHkuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIERPTVNUUklOR19TSVpFX0VSUjogUmFpc2VkIHdoZW4gaXQgd291bGQgcmV0dXJuIG1vcmUgY2hhcmFjdGVycyB0aGFuCi0gICAgICogICBmaXQgaW4gYSA8Y29kZT5ET01TdHJpbmc8L2NvZGU+IHZhcmlhYmxlIG9uIHRoZSBpbXBsZW1lbnRhdGlvbgotICAgICAqICAgcGxhdGZvcm0uCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXREYXRhKCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKLSAgICAgICAgcmV0dXJuIGZEYXRhOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoZSBudW1iZXIgb2YgMTYtYml0IHVuaXRzIHRoYXQgYXJlIGF2YWlsYWJsZSB0aHJvdWdoIDxjb2RlPmRhdGE8L2NvZGU+Ci0gICAgICogYW5kIHRoZSA8Y29kZT5zdWJzdHJpbmdEYXRhPC9jb2RlPiBtZXRob2QgYmVsb3cuIFRoaXMgbWF5IGhhdmUgdGhlCi0gICAgICogdmFsdWUgemVybywgaS5lLiwgPGNvZGU+Q2hhcmFjdGVyRGF0YTwvY29kZT4gbm9kZXMgbWF5IGJlIGVtcHR5LgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0TGVuZ3RoKCkgewotICAgICAgICBpZihmRGF0YSA9PSBudWxsKSByZXR1cm4gMDsKLSAgICAgICAgcmV0dXJuIGZEYXRhLmxlbmd0aCgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEV4dHJhY3RzIGEgcmFuZ2Ugb2YgZGF0YSBmcm9tIHRoZSBub2RlLgotICAgICAqIEBwYXJhbSBvZmZzZXQgU3RhcnQgb2Zmc2V0IG9mIHN1YnN0cmluZyB0byBleHRyYWN0LgotICAgICAqIEBwYXJhbSBjb3VudCBUaGUgbnVtYmVyIG9mIDE2LWJpdCB1bml0cyB0byBleHRyYWN0LgotICAgICAqIEByZXR1cm4gVGhlIHNwZWNpZmllZCBzdWJzdHJpbmcuIElmIHRoZSBzdW0gb2YgPGNvZGU+b2Zmc2V0PC9jb2RlPiBhbmQKLSAgICAgKiAgIDxjb2RlPmNvdW50PC9jb2RlPiBleGNlZWRzIHRoZSA8Y29kZT5sZW5ndGg8L2NvZGU+LCB0aGVuIGFsbCAxNi1iaXQKLSAgICAgKiAgIHVuaXRzIHRvIHRoZSBlbmQgb2YgdGhlIGRhdGEgYXJlIHJldHVybmVkLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBJTkRFWF9TSVpFX0VSUjogUmFpc2VkIGlmIHRoZSBzcGVjaWZpZWQgPGNvZGU+b2Zmc2V0PC9jb2RlPiBpcwotICAgICAqICAgbmVnYXRpdmUgb3IgZ3JlYXRlciB0aGFuIHRoZSBudW1iZXIgb2YgMTYtYml0IHVuaXRzIGluCi0gICAgICogICA8Y29kZT5kYXRhPC9jb2RlPiwgb3IgaWYgdGhlIHNwZWNpZmllZCA8Y29kZT5jb3VudDwvY29kZT4gaXMKLSAgICAgKiAgIG5lZ2F0aXZlLgotICAgICAqICAgPGJyPkRPTVNUUklOR19TSVpFX0VSUjogUmFpc2VkIGlmIHRoZSBzcGVjaWZpZWQgcmFuZ2Ugb2YgdGV4dCBkb2VzCi0gICAgICogICBub3QgZml0IGludG8gYSA8Y29kZT5ET01TdHJpbmc8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgc3Vic3RyaW5nRGF0YShpbnQgb2Zmc2V0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgY291bnQpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb24gewotICAgICAgICBpZihmRGF0YSA9PSBudWxsKSByZXR1cm4gbnVsbDsKLSAgICAgICAgaWYoY291bnQgPCAwIHx8IG9mZnNldCA8IDAgfHwgb2Zmc2V0ID4gZkRhdGEubGVuZ3RoKCkpCi0gICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5JTkRFWF9TSVpFX0VSUiwgInBhcmFtZXRlciBlcnJvciIpOwotICAgICAgICBpZihvZmZzZXQrY291bnQgPj0gZkRhdGEubGVuZ3RoKCkpCi0gICAgICAgICAgICByZXR1cm4gZkRhdGEuc3Vic3RyaW5nKG9mZnNldCk7Ci0gICAgICAgIHJldHVybiBmRGF0YS5zdWJzdHJpbmcob2Zmc2V0LCBvZmZzZXQrY291bnQpOwotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy90cmF2ZXJzZXJzL1NjaGVtYUNvbnRlbnRIYW5kbGVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL3RyYXZlcnNlcnMvU2NoZW1hQ29udGVudEhhbmRsZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMWE3Y2ExNC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL3RyYXZlcnNlcnMvU2NoZW1hQ29udGVudEhhbmRsZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDM4MiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMudHJhdmVyc2VyczsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5vcHRpLlNjaGVtYURPTVBhcnNlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuTmFtZXNwYWNlU3VwcG9ydDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuU0FYTG9jYXRvcldyYXBwZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlN5bWJvbFRhYmxlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5YTUxBdHRyaWJ1dGVzSW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuWE1MU3ltYm9sczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5OYW1lc3BhY2VDb250ZXh0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlFOYW1lOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTFN0cmluZzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTklFeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTFBhcnNlRXhjZXB0aW9uOwotaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OwotaW1wb3J0IG9yZy54bWwuc2F4LkF0dHJpYnV0ZXM7Ci1pbXBvcnQgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguTG9jYXRvcjsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguaGVscGVycy5Mb2NhdG9ySW1wbDsKLQotLyoqCi0gKiA8cD5TY2hlbWFDb250ZW50SGFuZGxlciBjb252ZXJ0cyBTQVggZXZlbnRzIGludG8gWE5JCi0gKiBhbmQgcGFzc2VzIHRoZW0gZGlyZWN0bHkgdG8gdGhlIFNjaGVtYURPTVBhcnNlci48L3A+Ci0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgTWljaGFlbCBHbGF2YXNzZXZpY2gsIElCTQotICogQGF1dGhvciBKYWNrIFouIFdhbmcsIElCTQotICoKLSAqLwotZmluYWwgY2xhc3MgU2NoZW1hQ29udGVudEhhbmRsZXIgaW1wbGVtZW50cyBDb250ZW50SGFuZGxlciB7Ci0KLSAgICAvKiogU3ltYm9sIHRhYmxlICoqLwotICAgIHByaXZhdGUgU3ltYm9sVGFibGUgZlN5bWJvbFRhYmxlOwotCi0gICAgLyoqIFNjaGVtYURPTVBhcnNlciwgZXZlbnRzIHdpbGwgYmUgZGVsZWdhdGVkIHRvIFNjaGVtYURPTVBhcnNlciB0byBwYXNzICovCi0gICAgcHJpdmF0ZSBTY2hlbWFET01QYXJzZXIgZlNjaGVtYURPTVBhcnNlcjsKLQotICAgIC8qKiBYTUwgTG9jYXRvciB3cmFwcGVyIGZvciBTQVguICoqLwotICAgIHByaXZhdGUgZmluYWwgU0FYTG9jYXRvcldyYXBwZXIgZlNBWExvY2F0b3JXcmFwcGVyID0gbmV3IFNBWExvY2F0b3JXcmFwcGVyKCk7Ci0KLSAgICAvKiogVGhlIG5hbWVzcGFjZSBjb250ZXh0IG9mIHRoaXMgZG9jdW1lbnQ6IHN0b3JlcyBuYW1lc3BhY2VzIGluIHNjb3BlICovCi0gICAgcHJpdmF0ZSBOYW1lc3BhY2VTdXBwb3J0IGZOYW1lc3BhY2VDb250ZXh0ID0gbmV3IE5hbWVzcGFjZVN1cHBvcnQoKTsKLQotICAgIC8qKiBJbmRpY2F0ZSBpZiBwdXNoIE5hbWVzcGFjZUNvbnRlc3QgaXMgbmVlZGVkICovCi0gICAgcHJpdmF0ZSBib29sZWFuIGZOZWVkUHVzaE5TQ29udGV4dDsKLQotICAgIC8qKiBGbGFnIHVzZWQgdG8gdHJhY2sgd2hldGhlciBuYW1lc3BhY2UgZGVjbGFyYXRpb25zIGFyZSByZXBvcnRlZCBhcyBhdHRyaWJ1dGVzLiAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBmTmFtZXNwYWNlUHJlZml4ZXMgPSBmYWxzZTsKLQotICAgIC8qKiBGbGFnIHVzZWQgdG8gdHJhY2sgd2hldGhlciBYTUwgbmFtZXMgYW5kIE5hbWVzcGFjZSBVUklzIGhhdmUgYmVlbiBpbnRlcm5hbGl6ZWQuICovCi0gICAgcHJpdmF0ZSBib29sZWFuIGZTdHJpbmdzSW50ZXJuYWxpemVkID0gZmFsc2U7Ci0KLSAgICAvKiogRmllbGRzIGZvciBzdGFydCBlbGVtZW50LCBlbmQgZWxlbWVudCBhbmQgY2hhcmFjdGVycy4gKi8KLSAgICBwcml2YXRlIGZpbmFsIFFOYW1lIGZFbGVtZW50UU5hbWUgPSBuZXcgUU5hbWUoKTsKLSAgICBwcml2YXRlIGZpbmFsIFFOYW1lIGZBdHRyaWJ1dGVRTmFtZSA9IG5ldyBRTmFtZSgpOwotICAgIHByaXZhdGUgZmluYWwgWE1MQXR0cmlidXRlc0ltcGwgZkF0dHJpYnV0ZXMgPSBuZXcgWE1MQXR0cmlidXRlc0ltcGwoKTsKLSAgICBwcml2YXRlIGZpbmFsIFhNTFN0cmluZyBmVGVtcFN0cmluZyA9IG5ldyBYTUxTdHJpbmcoKTsKLQotICAgIC8qKgotICAgICAqIDxwPkNvbnN0cnVjdHMgYW4gU2NoZW1hQ29udGVudEhhbmRsZXIuPC9wPgotICAgICAqLwotICAgIHB1YmxpYyBTY2hlbWFDb250ZW50SGFuZGxlcigpIHt9Ci0KLSAgICAvKgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjc2V0RG9jdW1lbnRMb2NhdG9yKG9yZy54bWwuc2F4LkxvY2F0b3IpCi0gICAgICovCi0gICAgcHVibGljIERvY3VtZW50IGdldERvY3VtZW50KCkgewotICAgICAgICByZXR1cm4gZlNjaGVtYURPTVBhcnNlci5nZXREb2N1bWVudCgpOwotICAgIH0KLQotICAgIC8qCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNzZXREb2N1bWVudExvY2F0b3Iob3JnLnhtbC5zYXguTG9jYXRvcikKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXREb2N1bWVudExvY2F0b3IoTG9jYXRvciBsb2NhdG9yKSB7Ci0gICAgICAgIGZTQVhMb2NhdG9yV3JhcHBlci5zZXRMb2NhdG9yKGxvY2F0b3IpOwotICAgIH0KLQotICAgIC8qCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNzdGFydERvY3VtZW50KCkKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydERvY3VtZW50KCkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0gICAgICAgIGZOZWVkUHVzaE5TQ29udGV4dCA9IHRydWU7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBmU2NoZW1hRE9NUGFyc2VyLnN0YXJ0RG9jdW1lbnQoZlNBWExvY2F0b3JXcmFwcGVyLCBudWxsLCBmTmFtZXNwYWNlQ29udGV4dCwgbnVsbCk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKFhNTFBhcnNlRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIGNvbnZlcnRUb1NBWFBhcnNlRXhjZXB0aW9uKGUpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChYTklFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgY29udmVydFRvU0FYRXhjZXB0aW9uKGUpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI2VuZERvY3VtZW50KCkKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbmREb2N1bWVudCgpIHRocm93cyBTQVhFeGNlcHRpb24gewotICAgICAgICBmU0FYTG9jYXRvcldyYXBwZXIuc2V0TG9jYXRvcihudWxsKTsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGZTY2hlbWFET01QYXJzZXIuZW5kRG9jdW1lbnQobnVsbCk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKFhNTFBhcnNlRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIGNvbnZlcnRUb1NBWFBhcnNlRXhjZXB0aW9uKGUpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChYTklFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgY29udmVydFRvU0FYRXhjZXB0aW9uKGUpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI3N0YXJ0UHJlZml4TWFwcGluZyhqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0UHJlZml4TWFwcGluZyhTdHJpbmcgcHJlZml4LCBTdHJpbmcgdXJpKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKGZOZWVkUHVzaE5TQ29udGV4dCkgewotICAgICAgICAgICAgZk5lZWRQdXNoTlNDb250ZXh0ID0gZmFsc2U7Ci0gICAgICAgICAgICBmTmFtZXNwYWNlQ29udGV4dC5wdXNoQ29udGV4dCgpOwotICAgICAgICB9Ci0gICAgICAgIGlmICghZlN0cmluZ3NJbnRlcm5hbGl6ZWQpIHsKLSAgICAgICAgICAgIHByZWZpeCA9IChwcmVmaXggIT0gbnVsbCkgPyBmU3ltYm9sVGFibGUuYWRkU3ltYm9sKHByZWZpeCkgOiBYTUxTeW1ib2xzLkVNUFRZX1NUUklORzsKLSAgICAgICAgICAgIHVyaSA9ICh1cmkgIT0gbnVsbCAmJiB1cmkubGVuZ3RoKCkgPiAwKSA/IGZTeW1ib2xUYWJsZS5hZGRTeW1ib2wodXJpKSA6IG51bGw7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBpZiAocHJlZml4ID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBwcmVmaXggPSBYTUxTeW1ib2xzLkVNUFRZX1NUUklORzsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmICh1cmkgIT0gbnVsbCAmJiB1cmkubGVuZ3RoKCkgPT0gMCkgewotICAgICAgICAgICAgICAgIHVyaSA9IG51bGw7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZk5hbWVzcGFjZUNvbnRleHQuZGVjbGFyZVByZWZpeChwcmVmaXgsIHVyaSk7Ci0gICAgfQotCi0gICAgLyoKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI2VuZFByZWZpeE1hcHBpbmcoamF2YS5sYW5nLlN0cmluZykKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbmRQcmVmaXhNYXBwaW5nKFN0cmluZyBwcmVmaXgpIHRocm93cyBTQVhFeGNlcHRpb24gewotICAgICAgICAvLyBkbyBub3RoaW5nCi0gICAgfQotCi0gICAgLyoKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI3N0YXJ0RWxlbWVudChqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nLCBvcmcueG1sLnNheC5BdHRyaWJ1dGVzKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudChTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxOYW1lLCBTdHJpbmcgcU5hbWUsIEF0dHJpYnV0ZXMgYXR0cykgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChmTmVlZFB1c2hOU0NvbnRleHQpIHsKLSAgICAgICAgICAgIGZOYW1lc3BhY2VDb250ZXh0LnB1c2hDb250ZXh0KCk7Ci0gICAgICAgIH0KLSAgICAgICAgZk5lZWRQdXNoTlNDb250ZXh0ID0gdHJ1ZTsKLQotICAgICAgICAvLyBGaWxsIGVsZW1lbnQgUU5hbWUgYW5kIFhNTEF0dHJpYnV0ZXMKLSAgICAgICAgZmlsbFFOYW1lKGZFbGVtZW50UU5hbWUsIHVyaSwgbG9jYWxOYW1lLCBxTmFtZSk7Ci0gICAgICAgIGZpbGxYTUxBdHRyaWJ1dGVzKGF0dHMpOwotCi0gICAgICAgIC8vIEFkZCBuYW1lc3BhY2UgZGVjbGFyYXRpb25zIGlmIG5lY2Vzc2FyeQotICAgICAgICBpZiAoIWZOYW1lc3BhY2VQcmVmaXhlcykgewotICAgICAgICAgICAgZmluYWwgaW50IHByZWZpeENvdW50ID0gZk5hbWVzcGFjZUNvbnRleHQuZ2V0RGVjbGFyZWRQcmVmaXhDb3VudCgpOwotICAgICAgICAgICAgaWYgKHByZWZpeENvdW50ID4gMCkgewotICAgICAgICAgICAgICAgIGFkZE5hbWVzcGFjZURlY2xhcmF0aW9ucyhwcmVmaXhDb3VudCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICB0cnkgewotICAgICAgICAgICAgZlNjaGVtYURPTVBhcnNlci5zdGFydEVsZW1lbnQoZkVsZW1lbnRRTmFtZSwgZkF0dHJpYnV0ZXMsIG51bGwpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChYTUxQYXJzZUV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICBjb252ZXJ0VG9TQVhQYXJzZUV4Y2VwdGlvbihlKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoWE5JRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIGNvbnZlcnRUb1NBWEV4Y2VwdGlvbihlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNlbmRFbGVtZW50KGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kRWxlbWVudChTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxOYW1lLCBTdHJpbmcgcU5hbWUpIHRocm93cyBTQVhFeGNlcHRpb24gewotICAgICAgICBmaWxsUU5hbWUoZkVsZW1lbnRRTmFtZSwgdXJpLCBsb2NhbE5hbWUsIHFOYW1lKTsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGZTY2hlbWFET01QYXJzZXIuZW5kRWxlbWVudChmRWxlbWVudFFOYW1lLCBudWxsKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoWE1MUGFyc2VFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgY29udmVydFRvU0FYUGFyc2VFeGNlcHRpb24oZSk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKFhOSUV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICBjb252ZXJ0VG9TQVhFeGNlcHRpb24oZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZmluYWxseSB7Ci0gICAgICAgICAgICBmTmFtZXNwYWNlQ29udGV4dC5wb3BDb250ZXh0KCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjY2hhcmFjdGVycyhjaGFyW10sIGludCwgaW50KQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGNoYXJhY3RlcnMoY2hhcltdIGNoLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpIHRocm93cyBTQVhFeGNlcHRpb24gewotICAgICAgICB0cnkgewotICAgICAgICAgICAgZlRlbXBTdHJpbmcuc2V0VmFsdWVzKGNoLCBzdGFydCwgbGVuZ3RoKTsKLSAgICAgICAgICAgIGZTY2hlbWFET01QYXJzZXIuY2hhcmFjdGVycyhmVGVtcFN0cmluZywgbnVsbCk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKFhNTFBhcnNlRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIGNvbnZlcnRUb1NBWFBhcnNlRXhjZXB0aW9uKGUpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChYTklFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgY29udmVydFRvU0FYRXhjZXB0aW9uKGUpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI2lnbm9yYWJsZVdoaXRlc3BhY2UoY2hhcltdLCBpbnQsIGludCkKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBpZ25vcmFibGVXaGl0ZXNwYWNlKGNoYXJbXSBjaCwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGZUZW1wU3RyaW5nLnNldFZhbHVlcyhjaCwgc3RhcnQsIGxlbmd0aCk7Ci0gICAgICAgICAgICBmU2NoZW1hRE9NUGFyc2VyLmlnbm9yYWJsZVdoaXRlc3BhY2UoZlRlbXBTdHJpbmcsIG51bGwpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChYTUxQYXJzZUV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICBjb252ZXJ0VG9TQVhQYXJzZUV4Y2VwdGlvbihlKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoWE5JRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIGNvbnZlcnRUb1NBWEV4Y2VwdGlvbihlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZykKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oU3RyaW5nIHRhcmdldCwgU3RyaW5nIGRhdGEpIHRocm93cyBTQVhFeGNlcHRpb24gewotICAgICAgICB0cnkgewotICAgICAgICAgICAgZlRlbXBTdHJpbmcuc2V0VmFsdWVzKGRhdGEudG9DaGFyQXJyYXkoKSwgMCwgZGF0YS5sZW5ndGgoKSk7Ci0gICAgICAgICAgICBmU2NoZW1hRE9NUGFyc2VyLnByb2Nlc3NpbmdJbnN0cnVjdGlvbih0YXJnZXQsIGZUZW1wU3RyaW5nLCBudWxsKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoWE1MUGFyc2VFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgY29udmVydFRvU0FYUGFyc2VFeGNlcHRpb24oZSk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKFhOSUV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICBjb252ZXJ0VG9TQVhFeGNlcHRpb24oZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjc2tpcHBlZEVudGl0eShqYXZhLmxhbmcuU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNraXBwZWRFbnRpdHkoU3RyaW5nIGFyZykgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0gICAgICAgIC8vIGRvLW5vdGhpbmcKLSAgICB9Ci0KLSAgICAvKgotICAgICAqIE90aGVyIG1ldGhvZHMKLSAgICAgKi8KLQotICAgIHByaXZhdGUgdm9pZCBmaWxsUU5hbWUoUU5hbWUgdG9GaWxsLCBTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxwYXJ0LCBTdHJpbmcgcmF3bmFtZSkgewotICAgICAgICBpZiAoIWZTdHJpbmdzSW50ZXJuYWxpemVkKSB7Ci0gICAgICAgICAgICB1cmkgPSAodXJpICE9IG51bGwgJiYgdXJpLmxlbmd0aCgpID4gMCkgPyBmU3ltYm9sVGFibGUuYWRkU3ltYm9sKHVyaSkgOiBudWxsOwotICAgICAgICAgICAgbG9jYWxwYXJ0ID0gKGxvY2FscGFydCAhPSBudWxsKSA/IGZTeW1ib2xUYWJsZS5hZGRTeW1ib2wobG9jYWxwYXJ0KSA6IFhNTFN5bWJvbHMuRU1QVFlfU1RSSU5HOwotICAgICAgICAgICAgcmF3bmFtZSA9IChyYXduYW1lICE9IG51bGwpID8gZlN5bWJvbFRhYmxlLmFkZFN5bWJvbChyYXduYW1lKSA6IFhNTFN5bWJvbHMuRU1QVFlfU1RSSU5HOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgaWYgKHVyaSAhPSBudWxsICYmIHVyaS5sZW5ndGgoKSA9PSAwKSB7Ci0gICAgICAgICAgICAgICAgdXJpID0gbnVsbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChsb2NhbHBhcnQgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGxvY2FscGFydCA9IFhNTFN5bWJvbHMuRU1QVFlfU1RSSU5HOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKHJhd25hbWUgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJhd25hbWUgPSBYTUxTeW1ib2xzLkVNUFRZX1NUUklORzsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBTdHJpbmcgcHJlZml4ID0gWE1MU3ltYm9scy5FTVBUWV9TVFJJTkc7Ci0gICAgICAgIGludCBwcmVmaXhJZHggPSByYXduYW1lLmluZGV4T2YoJzonKTsKLSAgICAgICAgaWYgKHByZWZpeElkeCAhPSAtMSkgewotICAgICAgICAgICAgcHJlZml4ID0gZlN5bWJvbFRhYmxlLmFkZFN5bWJvbChyYXduYW1lLnN1YnN0cmluZygwLCBwcmVmaXhJZHgpKTsKLSAgICAgICAgICAgIC8vIGxvY2FsIHBhcnQgbWF5IGJlIGFuIGVtcHR5IHN0cmluZyBpZiB0aGlzIGlzIGEgbmFtZXNwYWNlIGRlY2xhcmF0aW9uCi0gICAgICAgICAgICBpZiAobG9jYWxwYXJ0ID09IFhNTFN5bWJvbHMuRU1QVFlfU1RSSU5HKSB7Ci0gICAgICAgICAgICAgICAgbG9jYWxwYXJ0ID0gZlN5bWJvbFRhYmxlLmFkZFN5bWJvbChyYXduYW1lLnN1YnN0cmluZyhwcmVmaXhJZHggKyAxKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgLy8gbG9jYWwgcGFydCBtYXkgYmUgYW4gZW1wdHkgc3RyaW5nIGlmIHRoaXMgaXMgYSBuYW1lc3BhY2UgZGVjbGFyYXRpb24KLSAgICAgICAgZWxzZSBpZiAobG9jYWxwYXJ0ID09IFhNTFN5bWJvbHMuRU1QVFlfU1RSSU5HKSB7Ci0gICAgICAgICAgICBsb2NhbHBhcnQgPSByYXduYW1lOwotICAgICAgICB9Ci0gICAgICAgIHRvRmlsbC5zZXRWYWx1ZXMocHJlZml4LCBsb2NhbHBhcnQsIHJhd25hbWUsIHVyaSk7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIGZpbGxYTUxBdHRyaWJ1dGVzKEF0dHJpYnV0ZXMgYXR0cykgewotICAgICAgICBmQXR0cmlidXRlcy5yZW1vdmVBbGxBdHRyaWJ1dGVzKCk7Ci0gICAgICAgIGZpbmFsIGludCBhdHRyQ291bnQgPSBhdHRzLmdldExlbmd0aCgpOwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGF0dHJDb3VudDsgKytpKSB7Ci0gICAgICAgICAgICBmaWxsUU5hbWUoZkF0dHJpYnV0ZVFOYW1lLCBhdHRzLmdldFVSSShpKSwgYXR0cy5nZXRMb2NhbE5hbWUoaSksIGF0dHMuZ2V0UU5hbWUoaSkpOwotICAgICAgICAgICAgU3RyaW5nIHR5cGUgPSBhdHRzLmdldFR5cGUoaSk7Ci0gICAgICAgICAgICBmQXR0cmlidXRlcy5hZGRBdHRyaWJ1dGVOUyhmQXR0cmlidXRlUU5hbWUsICh0eXBlICE9IG51bGwpID8gdHlwZSA6IFhNTFN5bWJvbHMuZkNEQVRBU3ltYm9sLCBhdHRzLmdldFZhbHVlKGkpKTsKLSAgICAgICAgICAgIGZBdHRyaWJ1dGVzLnNldFNwZWNpZmllZChpLCB0cnVlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBhZGROYW1lc3BhY2VEZWNsYXJhdGlvbnMoZmluYWwgaW50IHByZWZpeENvdW50KSB7Ci0gICAgICAgIFN0cmluZyBwcmVmaXggPSBudWxsOwotICAgICAgICBTdHJpbmcgbG9jYWxwYXJ0ID0gbnVsbDsKLSAgICAgICAgU3RyaW5nIHJhd25hbWUgPSBudWxsOwotICAgICAgICBTdHJpbmcgbnNQcmVmaXggPSBudWxsOwotICAgICAgICBTdHJpbmcgbnNVUkkgPSBudWxsOwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHByZWZpeENvdW50OyArK2kpIHsKLSAgICAgICAgICAgIG5zUHJlZml4ID0gZk5hbWVzcGFjZUNvbnRleHQuZ2V0RGVjbGFyZWRQcmVmaXhBdChpKTsKLSAgICAgICAgICAgIG5zVVJJID0gZk5hbWVzcGFjZUNvbnRleHQuZ2V0VVJJKG5zUHJlZml4KTsKLSAgICAgICAgICAgIGlmIChuc1ByZWZpeC5sZW5ndGgoKSA+IDApIHsKLSAgICAgICAgICAgICAgICBwcmVmaXggPSBYTUxTeW1ib2xzLlBSRUZJWF9YTUxOUzsKLSAgICAgICAgICAgICAgICBsb2NhbHBhcnQgPSBuc1ByZWZpeDsKLSAgICAgICAgICAgICAgICByYXduYW1lID0gZlN5bWJvbFRhYmxlLmFkZFN5bWJvbChwcmVmaXggKyAiOiIgKyBsb2NhbHBhcnQpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgcHJlZml4ID0gWE1MU3ltYm9scy5FTVBUWV9TVFJJTkc7Ci0gICAgICAgICAgICAgICAgbG9jYWxwYXJ0ID0gWE1MU3ltYm9scy5QUkVGSVhfWE1MTlM7Ci0gICAgICAgICAgICAgICAgcmF3bmFtZSA9IFhNTFN5bWJvbHMuUFJFRklYX1hNTE5TOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZkF0dHJpYnV0ZVFOYW1lLnNldFZhbHVlcyhwcmVmaXgsIGxvY2FscGFydCwgcmF3bmFtZSwgTmFtZXNwYWNlQ29udGV4dC5YTUxOU19VUkkpOwotICAgICAgICAgICAgZkF0dHJpYnV0ZXMuYWRkQXR0cmlidXRlKGZBdHRyaWJ1dGVRTmFtZSwgWE1MU3ltYm9scy5mQ0RBVEFTeW1ib2wsIG5zVVJJKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHJlc2V0KFNjaGVtYURPTVBhcnNlciBzY2hlbWFET01QYXJzZXIsIFN5bWJvbFRhYmxlIHN5bWJvbFRhYmxlLAotICAgICAgICAgICAgYm9vbGVhbiBuYW1lc3BhY2VQcmVmaXhlcywgYm9vbGVhbiBzdHJpbmdzSW50ZXJuYWxpemVkKSB7Ci0gICAgICAgIGZTY2hlbWFET01QYXJzZXIgPSBzY2hlbWFET01QYXJzZXI7Ci0gICAgICAgIGZTeW1ib2xUYWJsZSA9IHN5bWJvbFRhYmxlOwotICAgICAgICBmTmFtZXNwYWNlUHJlZml4ZXMgPSBuYW1lc3BhY2VQcmVmaXhlczsKLSAgICAgICAgZlN0cmluZ3NJbnRlcm5hbGl6ZWQgPSBzdHJpbmdzSW50ZXJuYWxpemVkOwotICAgIH0KLQotICAgIC8qCi0gICAgICogU3RhdGljIG1ldGhvZHMKLSAgICAgKi8KLQotICAgIHN0YXRpYyB2b2lkIGNvbnZlcnRUb1NBWFBhcnNlRXhjZXB0aW9uKFhNTFBhcnNlRXhjZXB0aW9uIGUpIHRocm93cyBTQVhFeGNlcHRpb24gewotICAgICAgICBFeGNlcHRpb24gZXggPSBlLmdldEV4Y2VwdGlvbigpOwotICAgICAgICBpZiAoZXggPT0gbnVsbCkgewotICAgICAgICAgICAgLy8gbXVzdCBiZSBhIHBhcnNlciBleGNlcHRpb247IG1pbmUgaXQgZm9yIGxvY2F0b3IgaW5mbyBhbmQgdGhyb3cKLSAgICAgICAgICAgIC8vIGEgU0FYUGFyc2VFeGNlcHRpb24KLSAgICAgICAgICAgIExvY2F0b3JJbXBsIGxvY2F0b3JJbXBsID0gbmV3IExvY2F0b3JJbXBsKCk7Ci0gICAgICAgICAgICBsb2NhdG9ySW1wbC5zZXRQdWJsaWNJZChlLmdldFB1YmxpY0lkKCkpOwotICAgICAgICAgICAgbG9jYXRvckltcGwuc2V0U3lzdGVtSWQoZS5nZXRFeHBhbmRlZFN5c3RlbUlkKCkpOwotICAgICAgICAgICAgbG9jYXRvckltcGwuc2V0TGluZU51bWJlcihlLmdldExpbmVOdW1iZXIoKSk7Ci0gICAgICAgICAgICBsb2NhdG9ySW1wbC5zZXRDb2x1bW5OdW1iZXIoZS5nZXRDb2x1bW5OdW1iZXIoKSk7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgU0FYUGFyc2VFeGNlcHRpb24oZS5nZXRNZXNzYWdlKCksIGxvY2F0b3JJbXBsKTsKLSAgICAgICAgfQotICAgICAgICBpZiAoZXggaW5zdGFuY2VvZiBTQVhFeGNlcHRpb24pIHsKLSAgICAgICAgICAgIC8vIHdoeSBkaWQgd2UgY3JlYXRlIGFuIFhNTFBhcnNlRXhjZXB0aW9uPwotICAgICAgICAgICAgdGhyb3cgKFNBWEV4Y2VwdGlvbikgZXg7Ci0gICAgICAgIH0KLSAgICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbihleCk7Ci0gICAgfQotCi0gICAgc3RhdGljIHZvaWQgY29udmVydFRvU0FYRXhjZXB0aW9uKFhOSUV4Y2VwdGlvbiBlKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICAgICAgRXhjZXB0aW9uIGV4ID0gZS5nZXRFeGNlcHRpb24oKTsKLSAgICAgICAgaWYgKGV4ID09IG51bGwpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oZS5nZXRNZXNzYWdlKCkpOwotICAgICAgICB9Ci0gICAgICAgIGlmIChleCBpbnN0YW5jZW9mIFNBWEV4Y2VwdGlvbikgewotICAgICAgICAgICAgdGhyb3cgKFNBWEV4Y2VwdGlvbikgZXg7Ci0gICAgICAgIH0KLSAgICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbihleCk7Ci0gICAgfQotCi19IC8vIFNjaGVtYUNvbnRlbnRIYW5kbGVyCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL3RyYXZlcnNlcnMvU3RBWFNjaGVtYVBhcnNlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy90cmF2ZXJzZXJzL1N0QVhTY2hlbWFQYXJzZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggM2Q3ZTNhZi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL3RyYXZlcnNlcnMvU3RBWFNjaGVtYVBhcnNlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDI1ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCi0gKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKLSAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KLSAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCi0gKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAotICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLnRyYXZlcnNlcnM7Ci0KLWltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwotaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKLQotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uWE1MRXZlbnRSZWFkZXI7Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5YTUxTdHJlYW1Db25zdGFudHM7Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5YTUxTdHJlYW1FeGNlcHRpb247Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5YTUxTdHJlYW1SZWFkZXI7Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5ldmVudHMuQXR0cmlidXRlOwotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uZXZlbnRzLkVuZEVsZW1lbnQ7Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5ldmVudHMuTmFtZXNwYWNlOwotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uZXZlbnRzLlByb2Nlc3NpbmdJbnN0cnVjdGlvbjsKLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLmV2ZW50cy5TdGFydEVsZW1lbnQ7Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5ldmVudHMuWE1MRXZlbnQ7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMub3B0aS5TY2hlbWFET01QYXJzZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLkpBWFBOYW1lc3BhY2VDb250ZXh0V3JhcHBlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuU3RBWExvY2F0aW9uV3JhcHBlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuU3ltYm9sVGFibGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlhNTEF0dHJpYnV0ZXNJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5YTUxTdHJpbmdCdWZmZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlhNTFN5bWJvbHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuTmFtZXNwYWNlQ29udGV4dDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5RTmFtZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxTdHJpbmc7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE5JRXhjZXB0aW9uOwotaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OwotCi0vKioKLSAqIDxwPlN0QVhTY2hlbWFQYXJzZXIgcmVhZHMgU3RBWCBldmVudHMsIGNvbnZlcnRzIHRoZW0gaW50byBYTkkgZXZlbnRzCi0gKiBhbmQgcGFzc2VzIHRoZW0gZGlyZWN0bHkgdG8gdGhlIFNjaGVtYURPTVBhcnNlci48L3A+Ci0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEB2ZXJzaW9uICRJZDogU3RBWFNjaGVtYVBhcnNlci5qYXZhLHYgMS4yIDIwMTAtMTAtMjYgMjM6MDE6MTIgam9laHcgRXhwICQKLSAqLwotZmluYWwgY2xhc3MgU3RBWFNjaGVtYVBhcnNlciB7Ci0KLSAgICAvKiogQ2h1bmsgc2l6ZSAoMTAyNCkuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IENIVU5LX1NJWkUgPSAoMSA8PCAxMCk7Ci0KLSAgICAvKiogQ2h1bmsgbWFzayAoQ0hVTktfU0laRSAtIDEpLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBDSFVOS19NQVNLID0gQ0hVTktfU0laRSAtIDE7Ci0KLSAgICAvKiogQXJyYXkgZm9yIGhvbGRpbmcgY2hhcmFjdGVyIGRhdGEuICoqLwotICAgIHByaXZhdGUgZmluYWwgY2hhciBbXSBmQ2hhckJ1ZmZlciA9IG5ldyBjaGFyW0NIVU5LX1NJWkVdOwotCi0gICAgLyoqIFN5bWJvbCB0YWJsZSAqKi8KLSAgICBwcml2YXRlIFN5bWJvbFRhYmxlIGZTeW1ib2xUYWJsZTsKLQotICAgIC8qKiBTY2hlbWFET01QYXJzZXIsIGV2ZW50cyB3aWxsIGJlIGRlbGVnYXRlZCB0byBTY2hlbWFET01QYXJzZXIgdG8gcGFzcyAqLwotICAgIHByaXZhdGUgU2NoZW1hRE9NUGFyc2VyIGZTY2hlbWFET01QYXJzZXI7Ci0KLSAgICAvKiogWE1MIExvY2F0b3Igd3JhcHBlciBmb3IgU0FYLiAqKi8KLSAgICBwcml2YXRlIGZpbmFsIFN0QVhMb2NhdGlvbldyYXBwZXIgZkxvY2F0aW9uV3JhcHBlciA9IG5ldyBTdEFYTG9jYXRpb25XcmFwcGVyKCk7Ci0KLSAgICAvKiogVGhlIG5hbWVzcGFjZSBjb250ZXh0IG9mIHRoaXMgZG9jdW1lbnQ6IHN0b3JlcyBuYW1lc3BhY2VzIGluIHNjb3BlICovCi0gICAgcHJpdmF0ZSBmaW5hbCBKQVhQTmFtZXNwYWNlQ29udGV4dFdyYXBwZXIgZk5hbWVzcGFjZUNvbnRleHQgPSBuZXcgSkFYUE5hbWVzcGFjZUNvbnRleHRXcmFwcGVyKGZTeW1ib2xUYWJsZSk7Ci0KLSAgICAvKiogRmllbGRzIGZvciBzdGFydCBlbGVtZW50LCBlbmQgZWxlbWVudCBhbmQgY2hhcmFjdGVycy4gKi8KLSAgICBwcml2YXRlIGZpbmFsIFFOYW1lIGZFbGVtZW50UU5hbWUgPSBuZXcgUU5hbWUoKTsKLSAgICBwcml2YXRlIGZpbmFsIFFOYW1lIGZBdHRyaWJ1dGVRTmFtZSA9IG5ldyBRTmFtZSgpOwotICAgIHByaXZhdGUgZmluYWwgWE1MQXR0cmlidXRlc0ltcGwgZkF0dHJpYnV0ZXMgPSBuZXcgWE1MQXR0cmlidXRlc0ltcGwoKTsKLSAgICBwcml2YXRlIGZpbmFsIFhNTFN0cmluZyBmVGVtcFN0cmluZyA9IG5ldyBYTUxTdHJpbmcoKTsKLSAgICBwcml2YXRlIGZpbmFsIEFycmF5TGlzdCBmRGVjbGFyZWRQcmVmaXhlcyA9IG5ldyBBcnJheUxpc3QoKTsKLSAgICBwcml2YXRlIGZpbmFsIFhNTFN0cmluZ0J1ZmZlciBmU3RyaW5nQnVmZmVyID0gbmV3IFhNTFN0cmluZ0J1ZmZlcigpOwotICAgIHByaXZhdGUgaW50IGZEZXB0aDsKLQotICAgIHB1YmxpYyBTdEFYU2NoZW1hUGFyc2VyKCkgewotICAgICAgICBmTmFtZXNwYWNlQ29udGV4dC5zZXREZWNsYXJlZFByZWZpeGVzKGZEZWNsYXJlZFByZWZpeGVzKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCByZXNldChTY2hlbWFET01QYXJzZXIgc2NoZW1hRE9NUGFyc2VyLCBTeW1ib2xUYWJsZSBzeW1ib2xUYWJsZSkgewotICAgICAgICBmU2NoZW1hRE9NUGFyc2VyID0gc2NoZW1hRE9NUGFyc2VyOwotICAgICAgICBmU3ltYm9sVGFibGUgPSBzeW1ib2xUYWJsZTsKLSAgICAgICAgZk5hbWVzcGFjZUNvbnRleHQuc2V0U3ltYm9sVGFibGUoZlN5bWJvbFRhYmxlKTsKLSAgICAgICAgZk5hbWVzcGFjZUNvbnRleHQucmVzZXQoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgRG9jdW1lbnQgZ2V0RG9jdW1lbnQoKSB7Ci0gICAgICAgIHJldHVybiBmU2NoZW1hRE9NUGFyc2VyLmdldERvY3VtZW50KCk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgcGFyc2UoWE1MRXZlbnRSZWFkZXIgaW5wdXQpIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24sIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIFhNTEV2ZW50IGN1cnJlbnRFdmVudCA9IGlucHV0LnBlZWsoKTsKLSAgICAgICAgaWYgKGN1cnJlbnRFdmVudCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpbnQgZXZlbnRUeXBlID0gY3VycmVudEV2ZW50LmdldEV2ZW50VHlwZSgpOwotICAgICAgICAgICAgaWYgKGV2ZW50VHlwZSAhPSBYTUxTdHJlYW1Db25zdGFudHMuU1RBUlRfRE9DVU1FTlQgJiYKLSAgICAgICAgICAgICAgICBldmVudFR5cGUgIT0gWE1MU3RyZWFtQ29uc3RhbnRzLlNUQVJUX0VMRU1FTlQpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWE1MU3RyZWFtRXhjZXB0aW9uKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmTG9jYXRpb25XcmFwcGVyLnNldExvY2F0aW9uKGN1cnJlbnRFdmVudC5nZXRMb2NhdGlvbigpKTsKLSAgICAgICAgICAgIGZTY2hlbWFET01QYXJzZXIuc3RhcnREb2N1bWVudChmTG9jYXRpb25XcmFwcGVyLCBudWxsLCBmTmFtZXNwYWNlQ29udGV4dCwgbnVsbCk7Ci0gICAgICAgICAgICBsb29wOiB3aGlsZSAoaW5wdXQuaGFzTmV4dCgpKSB7Ci0gICAgICAgICAgICAgICAgY3VycmVudEV2ZW50ID0gaW5wdXQubmV4dEV2ZW50KCk7Ci0gICAgICAgICAgICAgICAgZXZlbnRUeXBlID0gY3VycmVudEV2ZW50LmdldEV2ZW50VHlwZSgpOwotICAgICAgICAgICAgICAgIHN3aXRjaCAoZXZlbnRUeXBlKSB7Ci0gICAgICAgICAgICAgICAgY2FzZSBYTUxTdHJlYW1Db25zdGFudHMuU1RBUlRfRUxFTUVOVDoKLSAgICAgICAgICAgICAgICAgICAgKytmRGVwdGg7Ci0gICAgICAgICAgICAgICAgICAgIFN0YXJ0RWxlbWVudCBzdGFydCA9IGN1cnJlbnRFdmVudC5hc1N0YXJ0RWxlbWVudCgpOwotICAgICAgICAgICAgICAgICAgICBmaWxsUU5hbWUoZkVsZW1lbnRRTmFtZSwgc3RhcnQuZ2V0TmFtZSgpKTsKLSAgICAgICAgICAgICAgICAgICAgZkxvY2F0aW9uV3JhcHBlci5zZXRMb2NhdGlvbihzdGFydC5nZXRMb2NhdGlvbigpKTsKLSAgICAgICAgICAgICAgICAgICAgZk5hbWVzcGFjZUNvbnRleHQuc2V0TmFtZXNwYWNlQ29udGV4dChzdGFydC5nZXROYW1lc3BhY2VDb250ZXh0KCkpOwotICAgICAgICAgICAgICAgICAgICBmaWxsWE1MQXR0cmlidXRlcyhzdGFydCk7Ci0gICAgICAgICAgICAgICAgICAgIGZpbGxEZWNsYXJlZFByZWZpeGVzKHN0YXJ0KTsKLSAgICAgICAgICAgICAgICAgICAgYWRkTmFtZXNwYWNlRGVjbGFyYXRpb25zKCk7Ci0gICAgICAgICAgICAgICAgICAgIGZOYW1lc3BhY2VDb250ZXh0LnB1c2hDb250ZXh0KCk7Ci0gICAgICAgICAgICAgICAgICAgIGZTY2hlbWFET01QYXJzZXIuc3RhcnRFbGVtZW50KGZFbGVtZW50UU5hbWUsIGZBdHRyaWJ1dGVzLCBudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgY2FzZSBYTUxTdHJlYW1Db25zdGFudHMuRU5EX0VMRU1FTlQ6Ci0gICAgICAgICAgICAgICAgICAgIEVuZEVsZW1lbnQgZW5kID0gY3VycmVudEV2ZW50LmFzRW5kRWxlbWVudCgpOwotICAgICAgICAgICAgICAgICAgICBmaWxsUU5hbWUoZkVsZW1lbnRRTmFtZSwgZW5kLmdldE5hbWUoKSk7Ci0gICAgICAgICAgICAgICAgICAgIGZpbGxEZWNsYXJlZFByZWZpeGVzKGVuZCk7Ci0gICAgICAgICAgICAgICAgICAgIGZMb2NhdGlvbldyYXBwZXIuc2V0TG9jYXRpb24oZW5kLmdldExvY2F0aW9uKCkpOwotICAgICAgICAgICAgICAgICAgICBmU2NoZW1hRE9NUGFyc2VyLmVuZEVsZW1lbnQoZkVsZW1lbnRRTmFtZSwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgIGZOYW1lc3BhY2VDb250ZXh0LnBvcENvbnRleHQoKTsKLSAgICAgICAgICAgICAgICAgICAgLS1mRGVwdGg7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChmRGVwdGggPD0gMCkgewotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWsgbG9vcDsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICBjYXNlIFhNTFN0cmVhbUNvbnN0YW50cy5DSEFSQUNURVJTOgotICAgICAgICAgICAgICAgICAgICBzZW5kQ2hhcmFjdGVyc1RvU2NoZW1hUGFyc2VyKGN1cnJlbnRFdmVudC5hc0NoYXJhY3RlcnMoKS5nZXREYXRhKCksIGZhbHNlKTsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgY2FzZSBYTUxTdHJlYW1Db25zdGFudHMuU1BBQ0U6Ci0gICAgICAgICAgICAgICAgICAgIHNlbmRDaGFyYWN0ZXJzVG9TY2hlbWFQYXJzZXIoY3VycmVudEV2ZW50LmFzQ2hhcmFjdGVycygpLmdldERhdGEoKSwgdHJ1ZSk7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGNhc2UgWE1MU3RyZWFtQ29uc3RhbnRzLkNEQVRBOgotICAgICAgICAgICAgICAgICAgICBmU2NoZW1hRE9NUGFyc2VyLnN0YXJ0Q0RBVEEobnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgIHNlbmRDaGFyYWN0ZXJzVG9TY2hlbWFQYXJzZXIoY3VycmVudEV2ZW50LmFzQ2hhcmFjdGVycygpLmdldERhdGEoKSwgZmFsc2UpOwotICAgICAgICAgICAgICAgICAgICBmU2NoZW1hRE9NUGFyc2VyLmVuZENEQVRBKG51bGwpOwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICBjYXNlIFhNTFN0cmVhbUNvbnN0YW50cy5QUk9DRVNTSU5HX0lOU1RSVUNUSU9OOgotICAgICAgICAgICAgICAgICAgICBQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24gcGkgPSAoUHJvY2Vzc2luZ0luc3RydWN0aW9uKWN1cnJlbnRFdmVudDsKLSAgICAgICAgICAgICAgICAgICAgZmlsbFByb2Nlc3NpbmdJbnN0cnVjdGlvbihwaS5nZXREYXRhKCkpOwotICAgICAgICAgICAgICAgICAgICBmU2NoZW1hRE9NUGFyc2VyLnByb2Nlc3NpbmdJbnN0cnVjdGlvbihwaS5nZXRUYXJnZXQoKSwgZlRlbXBTdHJpbmcsIG51bGwpOwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICBjYXNlIFhNTFN0cmVhbUNvbnN0YW50cy5EVEQ6Ci0gICAgICAgICAgICAgICAgICAgIC8qIFRoZXJlIHNob3VsZG4ndCBiZSBhIERURCBpbiB0aGUgc2NoZW1hICovCi0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGNhc2UgWE1MU3RyZWFtQ29uc3RhbnRzLkVOVElUWV9SRUZFUkVOQ0U6Ci0gICAgICAgICAgICAgICAgICAgIC8qIE5vdCBuZWVkZWQgZm9yIHNjaGVtYXMgKi8KLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgY2FzZSBYTUxTdHJlYW1Db25zdGFudHMuQ09NTUVOVDoKLSAgICAgICAgICAgICAgICAgICAgLyogTm8gcG9pbnQgaW4gc2VuZGluZyBjb21tZW50cyAqLwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICBjYXNlIFhNTFN0cmVhbUNvbnN0YW50cy5TVEFSVF9ET0NVTUVOVDoKLSAgICAgICAgICAgICAgICAgICAgZkRlcHRoKys7Ci0gICAgICAgICAgICAgICAgICAgIC8qIFdlIGF1dG9tYXRpY2FsbHkgY2FsbCBzdGFydERvY3VtZW50IGJlZm9yZSB0aGUgbG9vcCAqLwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICBjYXNlIFhNTFN0cmVhbUNvbnN0YW50cy5FTkRfRE9DVU1FTlQ6Ci0gICAgICAgICAgICAgICAgICAgIC8qIFdlIGF1dG9tYXRpY2FsbHkgY2FsbCBlbmREb2N1bWVudCBhZnRlciB0aGUgbG9vcCAqLwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmTG9jYXRpb25XcmFwcGVyLnNldExvY2F0aW9uKG51bGwpOwotICAgICAgICAgICAgZk5hbWVzcGFjZUNvbnRleHQuc2V0TmFtZXNwYWNlQ29udGV4dChudWxsKTsKLSAgICAgICAgICAgIGZTY2hlbWFET01QYXJzZXIuZW5kRG9jdW1lbnQobnVsbCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBwYXJzZShYTUxTdHJlYW1SZWFkZXIgaW5wdXQpIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24sIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChpbnB1dC5oYXNOZXh0KCkpIHsKLSAgICAgICAgICAgIGludCBldmVudFR5cGUgPSBpbnB1dC5nZXRFdmVudFR5cGUoKTsKLSAgICAgICAgICAgIGlmIChldmVudFR5cGUgIT0gWE1MU3RyZWFtQ29uc3RhbnRzLlNUQVJUX0RPQ1VNRU5UICYmCi0gICAgICAgICAgICAgICAgZXZlbnRUeXBlICE9IFhNTFN0cmVhbUNvbnN0YW50cy5TVEFSVF9FTEVNRU5UKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFhNTFN0cmVhbUV4Y2VwdGlvbigpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZkxvY2F0aW9uV3JhcHBlci5zZXRMb2NhdGlvbihpbnB1dC5nZXRMb2NhdGlvbigpKTsKLSAgICAgICAgICAgIGZTY2hlbWFET01QYXJzZXIuc3RhcnREb2N1bWVudChmTG9jYXRpb25XcmFwcGVyLCBudWxsLCBmTmFtZXNwYWNlQ29udGV4dCwgbnVsbCk7Ci0gICAgICAgICAgICBib29sZWFuIGZpcnN0ID0gdHJ1ZTsKLSAgICAgICAgICAgIGxvb3A6IHdoaWxlIChpbnB1dC5oYXNOZXh0KCkpIHsKLSAgICAgICAgICAgICAgICBpZiAoIWZpcnN0KSB7Ci0gICAgICAgICAgICAgICAgICAgIGV2ZW50VHlwZSA9IGlucHV0Lm5leHQoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIGZpcnN0ID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHN3aXRjaCAoZXZlbnRUeXBlKSB7Ci0gICAgICAgICAgICAgICAgY2FzZSBYTUxTdHJlYW1Db25zdGFudHMuU1RBUlRfRUxFTUVOVDoKLSAgICAgICAgICAgICAgICAgICAgKytmRGVwdGg7Ci0gICAgICAgICAgICAgICAgICAgIGZMb2NhdGlvbldyYXBwZXIuc2V0TG9jYXRpb24oaW5wdXQuZ2V0TG9jYXRpb24oKSk7Ci0gICAgICAgICAgICAgICAgICAgIGZOYW1lc3BhY2VDb250ZXh0LnNldE5hbWVzcGFjZUNvbnRleHQoaW5wdXQuZ2V0TmFtZXNwYWNlQ29udGV4dCgpKTsKLSAgICAgICAgICAgICAgICAgICAgZmlsbFFOYW1lKGZFbGVtZW50UU5hbWUsIGlucHV0LmdldE5hbWVzcGFjZVVSSSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQuZ2V0TG9jYWxOYW1lKCksIGlucHV0LmdldFByZWZpeCgpKTsKLSAgICAgICAgICAgICAgICAgICAgZmlsbFhNTEF0dHJpYnV0ZXMoaW5wdXQpOwotICAgICAgICAgICAgICAgICAgICBmaWxsRGVjbGFyZWRQcmVmaXhlcyhpbnB1dCk7Ci0gICAgICAgICAgICAgICAgICAgIGFkZE5hbWVzcGFjZURlY2xhcmF0aW9ucygpOwotICAgICAgICAgICAgICAgICAgICBmTmFtZXNwYWNlQ29udGV4dC5wdXNoQ29udGV4dCgpOwotICAgICAgICAgICAgICAgICAgICBmU2NoZW1hRE9NUGFyc2VyLnN0YXJ0RWxlbWVudChmRWxlbWVudFFOYW1lLCBmQXR0cmlidXRlcywgbnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGNhc2UgWE1MU3RyZWFtQ29uc3RhbnRzLkVORF9FTEVNRU5UOgotICAgICAgICAgICAgICAgICAgICBmTG9jYXRpb25XcmFwcGVyLnNldExvY2F0aW9uKGlucHV0LmdldExvY2F0aW9uKCkpOwotICAgICAgICAgICAgICAgICAgICBmTmFtZXNwYWNlQ29udGV4dC5zZXROYW1lc3BhY2VDb250ZXh0KGlucHV0LmdldE5hbWVzcGFjZUNvbnRleHQoKSk7Ci0gICAgICAgICAgICAgICAgICAgIGZpbGxRTmFtZShmRWxlbWVudFFOYW1lLCBpbnB1dC5nZXROYW1lc3BhY2VVUkkoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0LmdldExvY2FsTmFtZSgpLCBpbnB1dC5nZXRQcmVmaXgoKSk7Ci0gICAgICAgICAgICAgICAgICAgIGZpbGxEZWNsYXJlZFByZWZpeGVzKGlucHV0KTsKLSAgICAgICAgICAgICAgICAgICAgZlNjaGVtYURPTVBhcnNlci5lbmRFbGVtZW50KGZFbGVtZW50UU5hbWUsIG51bGwpOwotICAgICAgICAgICAgICAgICAgICBmTmFtZXNwYWNlQ29udGV4dC5wb3BDb250ZXh0KCk7Ci0gICAgICAgICAgICAgICAgICAgIC0tZkRlcHRoOwotICAgICAgICAgICAgICAgICAgICBpZiAoZkRlcHRoIDw9IDApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrIGxvb3A7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgY2FzZSBYTUxTdHJlYW1Db25zdGFudHMuQ0hBUkFDVEVSUzoKLSAgICAgICAgICAgICAgICAgICAgZlRlbXBTdHJpbmcuc2V0VmFsdWVzKGlucHV0LmdldFRleHRDaGFyYWN0ZXJzKCksCi0gICAgICAgICAgICAgICAgICAgICAgICBpbnB1dC5nZXRUZXh0U3RhcnQoKSwgaW5wdXQuZ2V0VGV4dExlbmd0aCgpKTsKLSAgICAgICAgICAgICAgICAgICAgZlNjaGVtYURPTVBhcnNlci5jaGFyYWN0ZXJzKGZUZW1wU3RyaW5nLCBudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgY2FzZSBYTUxTdHJlYW1Db25zdGFudHMuU1BBQ0U6Ci0gICAgICAgICAgICAgICAgICAgIGZUZW1wU3RyaW5nLnNldFZhbHVlcyhpbnB1dC5nZXRUZXh0Q2hhcmFjdGVycygpLAotICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQuZ2V0VGV4dFN0YXJ0KCksIGlucHV0LmdldFRleHRMZW5ndGgoKSk7Ci0gICAgICAgICAgICAgICAgICAgIGZTY2hlbWFET01QYXJzZXIuaWdub3JhYmxlV2hpdGVzcGFjZShmVGVtcFN0cmluZywgbnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGNhc2UgWE1MU3RyZWFtQ29uc3RhbnRzLkNEQVRBOgotICAgICAgICAgICAgICAgICAgICBmU2NoZW1hRE9NUGFyc2VyLnN0YXJ0Q0RBVEEobnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgIGZUZW1wU3RyaW5nLnNldFZhbHVlcyhpbnB1dC5nZXRUZXh0Q2hhcmFjdGVycygpLAotICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQuZ2V0VGV4dFN0YXJ0KCksIGlucHV0LmdldFRleHRMZW5ndGgoKSk7Ci0gICAgICAgICAgICAgICAgICAgIGZTY2hlbWFET01QYXJzZXIuY2hhcmFjdGVycyhmVGVtcFN0cmluZywgbnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgIGZTY2hlbWFET01QYXJzZXIuZW5kQ0RBVEEobnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGNhc2UgWE1MU3RyZWFtQ29uc3RhbnRzLlBST0NFU1NJTkdfSU5TVFJVQ1RJT046Ci0gICAgICAgICAgICAgICAgICAgIGZpbGxQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oaW5wdXQuZ2V0UElEYXRhKCkpOwotICAgICAgICAgICAgICAgICAgICBmU2NoZW1hRE9NUGFyc2VyLnByb2Nlc3NpbmdJbnN0cnVjdGlvbihpbnB1dC5nZXRQSVRhcmdldCgpLCBmVGVtcFN0cmluZywgbnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGNhc2UgWE1MU3RyZWFtQ29uc3RhbnRzLkRURDoKLSAgICAgICAgICAgICAgICAgICAgLyogVGhlcmUgc2hvdWxkbid0IGJlIGEgRFREIGluIHRoZSBzY2hlbWEgKi8KLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgY2FzZSBYTUxTdHJlYW1Db25zdGFudHMuRU5USVRZX1JFRkVSRU5DRToKLSAgICAgICAgICAgICAgICAgICAgLyogTm90IG5lZWRlZCBmb3Igc2NoZW1hcyAqLwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICBjYXNlIFhNTFN0cmVhbUNvbnN0YW50cy5DT01NRU5UOgotICAgICAgICAgICAgICAgICAgICAvKiBObyBwb2ludCBpbiBzZW5kaW5nIGNvbW1lbnRzICovCi0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGNhc2UgWE1MU3RyZWFtQ29uc3RhbnRzLlNUQVJUX0RPQ1VNRU5UOgotICAgICAgICAgICAgICAgICAgICArK2ZEZXB0aDsKLSAgICAgICAgICAgICAgICAgICAgLyogV2UgYXV0b21hdGljYWxseSBjYWxsIHN0YXJ0RG9jdW1lbnQgYmVmb3JlIHRoZSBsb29wICovCi0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGNhc2UgWE1MU3RyZWFtQ29uc3RhbnRzLkVORF9ET0NVTUVOVDoKLSAgICAgICAgICAgICAgICAgICAgLyogV2UgYXV0b21hdGljYWxseSBjYWxsIGVuZERvY3VtZW50IGFmdGVyIHRoZSBsb29wICovCi0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGZMb2NhdGlvbldyYXBwZXIuc2V0TG9jYXRpb24obnVsbCk7Ci0gICAgICAgICAgICBmTmFtZXNwYWNlQ29udGV4dC5zZXROYW1lc3BhY2VDb250ZXh0KG51bGwpOwotICAgICAgICAgICAgZlNjaGVtYURPTVBhcnNlci5lbmREb2N1bWVudChudWxsKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKiBTZW5kIGNoYXJhY3RlcnMgdG8gdGhlIHZhbGlkYXRvciBpbiBDSFVOS19TSVpFIGNoYXJhY3RlciBjaHVua3MuICovCi0gICAgcHJpdmF0ZSB2b2lkIHNlbmRDaGFyYWN0ZXJzVG9TY2hlbWFQYXJzZXIoU3RyaW5nIHN0ciwgYm9vbGVhbiB3aGl0ZXNwYWNlKSB7Ci0gICAgICAgIGlmIChzdHIgIT0gbnVsbCkgewotICAgICAgICAgICAgZmluYWwgaW50IGxlbmd0aCA9IHN0ci5sZW5ndGgoKTsKLSAgICAgICAgICAgIGZpbmFsIGludCByZW1haW5kZXIgPSBsZW5ndGggJiBDSFVOS19NQVNLOwotICAgICAgICAgICAgaWYgKHJlbWFpbmRlciA+IDApIHsKLSAgICAgICAgICAgICAgICBzdHIuZ2V0Q2hhcnMoMCwgcmVtYWluZGVyLCBmQ2hhckJ1ZmZlciwgMCk7Ci0gICAgICAgICAgICAgICAgZlRlbXBTdHJpbmcuc2V0VmFsdWVzKGZDaGFyQnVmZmVyLCAwLCByZW1haW5kZXIpOwotICAgICAgICAgICAgICAgIGlmICh3aGl0ZXNwYWNlKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZTY2hlbWFET01QYXJzZXIuaWdub3JhYmxlV2hpdGVzcGFjZShmVGVtcFN0cmluZywgbnVsbCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICBmU2NoZW1hRE9NUGFyc2VyLmNoYXJhY3RlcnMoZlRlbXBTdHJpbmcsIG51bGwpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGludCBpID0gcmVtYWluZGVyOwotICAgICAgICAgICAgd2hpbGUgKGkgPCBsZW5ndGgpIHsKLSAgICAgICAgICAgICAgICBzdHIuZ2V0Q2hhcnMoaSwgaSArPSBDSFVOS19TSVpFLCBmQ2hhckJ1ZmZlciwgMCk7Ci0gICAgICAgICAgICAgICAgZlRlbXBTdHJpbmcuc2V0VmFsdWVzKGZDaGFyQnVmZmVyLCAwLCBDSFVOS19TSVpFKTsKLSAgICAgICAgICAgICAgICBpZiAod2hpdGVzcGFjZSkgewotICAgICAgICAgICAgICAgICAgICBmU2NoZW1hRE9NUGFyc2VyLmlnbm9yYWJsZVdoaXRlc3BhY2UoZlRlbXBTdHJpbmcsIG51bGwpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgZlNjaGVtYURPTVBhcnNlci5jaGFyYWN0ZXJzKGZUZW1wU3RyaW5nLCBudWxsKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvLyBwcm9jZXNzaW5nIGluc3RydWN0aW9ucyBtdXN0IGJlIHNlbnQgYWxsIGluIG9uZSBjaHVuawotICAgIHByaXZhdGUgdm9pZCBmaWxsUHJvY2Vzc2luZ0luc3RydWN0aW9uKFN0cmluZyBkYXRhKSB7Ci0gICAgICAgIGZpbmFsIGludCBkYXRhTGVuZ3RoID0gZGF0YS5sZW5ndGgoKTsKLSAgICAgICAgY2hhciBbXSBjaGFyQnVmZmVyID0gZkNoYXJCdWZmZXI7Ci0gICAgICAgIGlmIChjaGFyQnVmZmVyLmxlbmd0aCA8IGRhdGFMZW5ndGgpIHsKLSAgICAgICAgICAgIC8vIHRvQ2hhckFycmF5KCkgY3JlYXRlcyBhIG5ld2x5IGFsbG9jYXRlZCBhcnJheSwgc28gaXQncyBva2F5Ci0gICAgICAgICAgICAvLyB0byBrZWVwIGEgcmVmZXJlbmNlIHRvIGl0LgotICAgICAgICAgICAgY2hhckJ1ZmZlciA9IGRhdGEudG9DaGFyQXJyYXkoKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIGRhdGEuZ2V0Q2hhcnMoMCwgZGF0YUxlbmd0aCwgY2hhckJ1ZmZlciwgMCk7Ci0gICAgICAgIH0KLSAgICAgICAgZlRlbXBTdHJpbmcuc2V0VmFsdWVzKGNoYXJCdWZmZXIsIDAsIGRhdGFMZW5ndGgpOwotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBmaWxsWE1MQXR0cmlidXRlcyhTdGFydEVsZW1lbnQgZXZlbnQpIHsKLSAgICAgICAgZkF0dHJpYnV0ZXMucmVtb3ZlQWxsQXR0cmlidXRlcygpOwotICAgICAgICBmaW5hbCBJdGVyYXRvciBhdHRycyA9IGV2ZW50LmdldEF0dHJpYnV0ZXMoKTsKLSAgICAgICAgd2hpbGUgKGF0dHJzLmhhc05leHQoKSkgewotICAgICAgICAgICAgQXR0cmlidXRlIGF0dHIgPSAoQXR0cmlidXRlKSBhdHRycy5uZXh0KCk7Ci0gICAgICAgICAgICBmaWxsUU5hbWUoZkF0dHJpYnV0ZVFOYW1lLCBhdHRyLmdldE5hbWUoKSk7Ci0gICAgICAgICAgICBTdHJpbmcgdHlwZSA9IGF0dHIuZ2V0RFREVHlwZSgpOwotICAgICAgICAgICAgaW50IGlkeCA9IGZBdHRyaWJ1dGVzLmdldExlbmd0aCgpOwotICAgICAgICAgICAgZkF0dHJpYnV0ZXMuYWRkQXR0cmlidXRlTlMoZkF0dHJpYnV0ZVFOYW1lLAotICAgICAgICAgICAgICAgICAgICAodHlwZSAhPSBudWxsKSA/IHR5cGUgOiBYTUxTeW1ib2xzLmZDREFUQVN5bWJvbCwgYXR0ci5nZXRWYWx1ZSgpKTsKLSAgICAgICAgICAgIGZBdHRyaWJ1dGVzLnNldFNwZWNpZmllZChpZHgsIGF0dHIuaXNTcGVjaWZpZWQoKSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgZmlsbFhNTEF0dHJpYnV0ZXMoWE1MU3RyZWFtUmVhZGVyIGlucHV0KSB7Ci0gICAgICAgIGZBdHRyaWJ1dGVzLnJlbW92ZUFsbEF0dHJpYnV0ZXMoKTsKLSAgICAgICAgZmluYWwgaW50IGxlbiA9IGlucHV0LmdldEF0dHJpYnV0ZUNvdW50KCk7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuOyArK2kpIHsKLSAgICAgICAgICAgIGZpbGxRTmFtZShmQXR0cmlidXRlUU5hbWUsIGlucHV0LmdldEF0dHJpYnV0ZU5hbWVzcGFjZShpKSwKLSAgICAgICAgICAgICAgICBpbnB1dC5nZXRBdHRyaWJ1dGVMb2NhbE5hbWUoaSksIGlucHV0LmdldEF0dHJpYnV0ZVByZWZpeChpKSk7Ci0gICAgICAgICAgICBTdHJpbmcgdHlwZSA9IGlucHV0LmdldEF0dHJpYnV0ZVR5cGUoaSk7Ci0gICAgICAgICAgICBmQXR0cmlidXRlcy5hZGRBdHRyaWJ1dGVOUyhmQXR0cmlidXRlUU5hbWUsCi0gICAgICAgICAgICAgICAgICAgICh0eXBlICE9IG51bGwpID8gdHlwZSA6IFhNTFN5bWJvbHMuZkNEQVRBU3ltYm9sLCBpbnB1dC5nZXRBdHRyaWJ1dGVWYWx1ZShpKSk7Ci0gICAgICAgICAgICBmQXR0cmlidXRlcy5zZXRTcGVjaWZpZWQoaSwgaW5wdXQuaXNBdHRyaWJ1dGVTcGVjaWZpZWQoaSkpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIGFkZE5hbWVzcGFjZURlY2xhcmF0aW9ucygpIHsKLSAgICAgICAgU3RyaW5nIHByZWZpeCA9IG51bGw7Ci0gICAgICAgIFN0cmluZyBsb2NhbHBhcnQgPSBudWxsOwotICAgICAgICBTdHJpbmcgcmF3bmFtZSA9IG51bGw7Ci0gICAgICAgIFN0cmluZyBuc1ByZWZpeCA9IG51bGw7Ci0gICAgICAgIFN0cmluZyBuc1VSSSA9IG51bGw7Ci0KLSAgICAgICAgZmluYWwgSXRlcmF0b3IgaXRlciA9IGZEZWNsYXJlZFByZWZpeGVzLml0ZXJhdG9yKCk7Ci0gICAgICAgIHdoaWxlIChpdGVyLmhhc05leHQoKSkgewotICAgICAgICAgICAgbnNQcmVmaXggPSAoU3RyaW5nKSBpdGVyLm5leHQoKTsKLSAgICAgICAgICAgIG5zVVJJID0gZk5hbWVzcGFjZUNvbnRleHQuZ2V0VVJJKG5zUHJlZml4KTsKLSAgICAgICAgICAgIGlmIChuc1ByZWZpeC5sZW5ndGgoKSA+IDApIHsKLSAgICAgICAgICAgICAgICBwcmVmaXggPSBYTUxTeW1ib2xzLlBSRUZJWF9YTUxOUzsKLSAgICAgICAgICAgICAgICBsb2NhbHBhcnQgPSBuc1ByZWZpeDsKLSAgICAgICAgICAgICAgICBmU3RyaW5nQnVmZmVyLmNsZWFyKCk7Ci0gICAgICAgICAgICAgICAgZlN0cmluZ0J1ZmZlci5hcHBlbmQocHJlZml4KTsKLSAgICAgICAgICAgICAgICBmU3RyaW5nQnVmZmVyLmFwcGVuZCgnOicpOwotICAgICAgICAgICAgICAgIGZTdHJpbmdCdWZmZXIuYXBwZW5kKGxvY2FscGFydCk7Ci0gICAgICAgICAgICAgICAgcmF3bmFtZSA9IGZTeW1ib2xUYWJsZS5hZGRTeW1ib2woZlN0cmluZ0J1ZmZlci5jaCwgZlN0cmluZ0J1ZmZlci5vZmZzZXQsIGZTdHJpbmdCdWZmZXIubGVuZ3RoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIHByZWZpeCA9IFhNTFN5bWJvbHMuRU1QVFlfU1RSSU5HOwotICAgICAgICAgICAgICAgIGxvY2FscGFydCA9IFhNTFN5bWJvbHMuUFJFRklYX1hNTE5TOwotICAgICAgICAgICAgICAgIHJhd25hbWUgPSBYTUxTeW1ib2xzLlBSRUZJWF9YTUxOUzsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGZBdHRyaWJ1dGVRTmFtZS5zZXRWYWx1ZXMocHJlZml4LCBsb2NhbHBhcnQsIHJhd25hbWUsIE5hbWVzcGFjZUNvbnRleHQuWE1MTlNfVVJJKTsKLSAgICAgICAgICAgIGZBdHRyaWJ1dGVzLmFkZEF0dHJpYnV0ZShmQXR0cmlidXRlUU5hbWUsIFhNTFN5bWJvbHMuZkNEQVRBU3ltYm9sLAotICAgICAgICAgICAgICAgICAgICAobnNVUkkgIT0gbnVsbCkgPyBuc1VSSSA6IFhNTFN5bWJvbHMuRU1QVFlfU1RSSU5HKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKiBGaWxscyBpbiB0aGUgbGlzdCBvZiBkZWNsYXJlZCBwcmVmaXhlcy4gKi8KLSAgICBwcml2YXRlIHZvaWQgZmlsbERlY2xhcmVkUHJlZml4ZXMoU3RhcnRFbGVtZW50IGV2ZW50KSB7Ci0gICAgICAgIGZpbGxEZWNsYXJlZFByZWZpeGVzKGV2ZW50LmdldE5hbWVzcGFjZXMoKSk7Ci0gICAgfQotCi0gICAgLyoqIEZpbGxzIGluIHRoZSBsaXN0IG9mIGRlY2xhcmVkIHByZWZpeGVzLiAqLwotICAgIHByaXZhdGUgdm9pZCBmaWxsRGVjbGFyZWRQcmVmaXhlcyhFbmRFbGVtZW50IGV2ZW50KSB7Ci0gICAgICAgIGZpbGxEZWNsYXJlZFByZWZpeGVzKGV2ZW50LmdldE5hbWVzcGFjZXMoKSk7Ci0gICAgfQotCi0gICAgLyoqIEZpbGxzIGluIHRoZSBsaXN0IG9mIGRlY2xhcmVkIHByZWZpeGVzLiAqLwotICAgIHByaXZhdGUgdm9pZCBmaWxsRGVjbGFyZWRQcmVmaXhlcyhJdGVyYXRvciBuYW1lc3BhY2VzKSB7Ci0gICAgICAgIGZEZWNsYXJlZFByZWZpeGVzLmNsZWFyKCk7Ci0gICAgICAgIHdoaWxlIChuYW1lc3BhY2VzLmhhc05leHQoKSkgewotICAgICAgICAgICAgTmFtZXNwYWNlIG5zID0gKE5hbWVzcGFjZSkgbmFtZXNwYWNlcy5uZXh0KCk7Ci0gICAgICAgICAgICBTdHJpbmcgcHJlZml4ID0gbnMuZ2V0UHJlZml4KCk7Ci0gICAgICAgICAgICBmRGVjbGFyZWRQcmVmaXhlcy5hZGQocHJlZml4ICE9IG51bGwgPyBwcmVmaXggOiAiIik7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKiogRmlsbHMgaW4gdGhlIGxpc3Qgb2YgZGVjbGFyZWQgcHJlZml4ZXMuICovCi0gICAgcHJpdmF0ZSB2b2lkIGZpbGxEZWNsYXJlZFByZWZpeGVzKFhNTFN0cmVhbVJlYWRlciByZWFkZXIpIHsKLSAgICAgICAgZkRlY2xhcmVkUHJlZml4ZXMuY2xlYXIoKTsKLSAgICAgICAgZmluYWwgaW50IGxlbiA9IHJlYWRlci5nZXROYW1lc3BhY2VDb3VudCgpOwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbjsgKytpKSB7Ci0gICAgICAgICAgICBTdHJpbmcgcHJlZml4ID0gcmVhZGVyLmdldE5hbWVzcGFjZVByZWZpeChpKTsKLSAgICAgICAgICAgIGZEZWNsYXJlZFByZWZpeGVzLmFkZChwcmVmaXggIT0gbnVsbCA/IHByZWZpeCA6ICIiKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKiBGaWxscyBpbiBhIFFOYW1lIG9iamVjdC4gKi8KLSAgICBwcml2YXRlIHZvaWQgZmlsbFFOYW1lKFFOYW1lIHRvRmlsbCwgamF2YXgueG1sLm5hbWVzcGFjZS5RTmFtZSB0b0NvcHkpIHsKLSAgICAgICAgZmlsbFFOYW1lKHRvRmlsbCwgdG9Db3B5LmdldE5hbWVzcGFjZVVSSSgpLCB0b0NvcHkuZ2V0TG9jYWxQYXJ0KCksIHRvQ29weS5nZXRQcmVmaXgoKSk7Ci0gICAgfQotCi0gICAgLyoqIEZpbGxzIGluIGEgUU5hbWUgb2JqZWN0LiAqLwotICAgIGZpbmFsIHZvaWQgZmlsbFFOYW1lKFFOYW1lIHRvRmlsbCwgU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FscGFydCwgU3RyaW5nIHByZWZpeCkgewotICAgICAgICB1cmkgPSAodXJpICE9IG51bGwgJiYgdXJpLmxlbmd0aCgpID4gMCkgPyBmU3ltYm9sVGFibGUuYWRkU3ltYm9sKHVyaSkgOiBudWxsOwotICAgICAgICBsb2NhbHBhcnQgPSAobG9jYWxwYXJ0ICE9IG51bGwpID8gZlN5bWJvbFRhYmxlLmFkZFN5bWJvbChsb2NhbHBhcnQpIDogWE1MU3ltYm9scy5FTVBUWV9TVFJJTkc7Ci0gICAgICAgIHByZWZpeCA9IChwcmVmaXggIT0gbnVsbCAmJiBwcmVmaXgubGVuZ3RoKCkgPiAwKSA/IGZTeW1ib2xUYWJsZS5hZGRTeW1ib2wocHJlZml4KSA6IFhNTFN5bWJvbHMuRU1QVFlfU1RSSU5HOwotICAgICAgICBTdHJpbmcgcmF3ID0gbG9jYWxwYXJ0OwotICAgICAgICBpZiAocHJlZml4ICE9IFhNTFN5bWJvbHMuRU1QVFlfU1RSSU5HKSB7Ci0gICAgICAgICAgICBmU3RyaW5nQnVmZmVyLmNsZWFyKCk7Ci0gICAgICAgICAgICBmU3RyaW5nQnVmZmVyLmFwcGVuZChwcmVmaXgpOwotICAgICAgICAgICAgZlN0cmluZ0J1ZmZlci5hcHBlbmQoJzonKTsKLSAgICAgICAgICAgIGZTdHJpbmdCdWZmZXIuYXBwZW5kKGxvY2FscGFydCk7Ci0gICAgICAgICAgICByYXcgPSBmU3ltYm9sVGFibGUuYWRkU3ltYm9sKGZTdHJpbmdCdWZmZXIuY2gsIGZTdHJpbmdCdWZmZXIub2Zmc2V0LCBmU3RyaW5nQnVmZmVyLmxlbmd0aCk7Ci0gICAgICAgIH0KLSAgICAgICAgdG9GaWxsLnNldFZhbHVlcyhwcmVmaXgsIGxvY2FscGFydCwgcmF3LCB1cmkpOwotICAgIH0KLQotfSAvLyBTdEFYU2NoZW1hUGFyc2VyCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL3RyYXZlcnNlcnMvWFNBbm5vdGF0aW9uSW5mby5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy90cmF2ZXJzZXJzL1hTQW5ub3RhdGlvbkluZm8uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMWVjNzc0MS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL3RyYXZlcnNlcnMvWFNBbm5vdGF0aW9uSW5mby5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNzIgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy50cmF2ZXJzZXJzOwotCi1pbXBvcnQgb3JnLnczYy5kb20uRWxlbWVudDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMub3B0aS5FbGVtZW50SW1wbDsKLQotLyoqCi0gKiBPYmplY3RzIG9mIHRoaXMgY2xhc3MgY29udGFpbiB0aGUgdGV4dHVhbCByZXByZXNlbnRhdGlvbiBvZgotICogYW4gWE1MIHNjaGVtYSBhbm5vdGF0aW9uIGFzIHdlbGwgYXMgaW5mb3JtYXRpb24gb24gdGhlIGxvY2F0aW9uCi0gKiBvZiB0aGUgYW5ub3RhdGlvbiBpbiB0aGUgZG9jdW1lbnQgaXQgb3JpZ2luYXRlZCBmcm9tLgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIE1pY2hhZWwgR2xhdmFzc2V2aWNoLCBJQk0KLSAqLwotZmluYWwgY2xhc3MgWFNBbm5vdGF0aW9uSW5mbyB7Ci0KLSAgICAvKiogVGV4dHVhbCByZXByZXNlbnRhdGlvbiBvZiBhbm5vdGF0aW9uLiAqKi8KLSAgICBTdHJpbmcgZkFubm90YXRpb247Ci0KLSAgICAvKiogTGluZSBudW1iZXIgb2YgJmx0O2Fubm90YXRpb24mZ3Q7IGVsZW1lbnQuICoqLwotICAgIGludCBmTGluZTsKLQotICAgIC8qKiBDb2x1bW4gbnVtYmVyIG9mICZsdDthbm5vdGF0aW9uJmd0OyBlbGVtZW50LiAqKi8KLSAgICBpbnQgZkNvbHVtbjsKLQotICAgIC8qKiBDaGFyYWN0ZXIgb2Zmc2V0IG9mICZsdDthbm5vdGF0aW9uJmd0OyBlbGVtZW50LiAqKi8KLSAgICBpbnQgZkNoYXJPZmZzZXQ7Ci0KLSAgICAvKiogTmV4dCBhbm5vdGF0aW9uLiAqKi8KLSAgICBYU0Fubm90YXRpb25JbmZvIG5leHQ7Ci0KLSAgICBYU0Fubm90YXRpb25JbmZvKFN0cmluZyBhbm5vdGF0aW9uLCBpbnQgbGluZSwgaW50IGNvbHVtbiwgaW50IGNoYXJPZmZzZXQpIHsKLSAgICAgICAgZkFubm90YXRpb24gPSBhbm5vdGF0aW9uOwotICAgICAgICBmTGluZSA9IGxpbmU7Ci0gICAgICAgIGZDb2x1bW4gPSBjb2x1bW47Ci0gICAgICAgIGZDaGFyT2Zmc2V0ID0gY2hhck9mZnNldDsKLSAgICB9Ci0KLSAgICBYU0Fubm90YXRpb25JbmZvKFN0cmluZyBhbm5vdGF0aW9uLCBFbGVtZW50IGFubm90YXRpb25EZWNsKSB7Ci0gICAgICAgIGZBbm5vdGF0aW9uID0gYW5ub3RhdGlvbjsKLSAgICAgICAgaWYgKGFubm90YXRpb25EZWNsIGluc3RhbmNlb2YgRWxlbWVudEltcGwpIHsKLSAgICAgICAgICAgIGZpbmFsIEVsZW1lbnRJbXBsIGFubm90YXRpb25EZWNsSW1wbCA9IChFbGVtZW50SW1wbCkgYW5ub3RhdGlvbkRlY2w7Ci0gICAgICAgICAgICBmTGluZSA9IGFubm90YXRpb25EZWNsSW1wbC5nZXRMaW5lTnVtYmVyKCk7Ci0gICAgICAgICAgICBmQ29sdW1uID0gYW5ub3RhdGlvbkRlY2xJbXBsLmdldENvbHVtbk51bWJlcigpOwotICAgICAgICAgICAgZkNoYXJPZmZzZXQgPSBhbm5vdGF0aW9uRGVjbEltcGwuZ2V0Q2hhcmFjdGVyT2Zmc2V0KCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBmTGluZSA9IC0xOwotICAgICAgICAgICAgZkNvbHVtbiA9IC0xOwotICAgICAgICAgICAgZkNoYXJPZmZzZXQgPSAtMTsKLSAgICAgICAgfQotICAgIH0KLX0gLy8gWFNBbm5vdGF0aW9uSW5mbwpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy90cmF2ZXJzZXJzL1hTQXR0cmlidXRlQ2hlY2tlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy90cmF2ZXJzZXJzL1hTQXR0cmlidXRlQ2hlY2tlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1Njc3OTcxLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvdHJhdmVyc2Vycy9YU0F0dHJpYnV0ZUNoZWNrZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE4MjIgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAxNSwgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqLwotLyoKLSAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQotICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCi0gKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCi0gKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAotICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKLSAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy50cmF2ZXJzZXJzOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LkludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5YU1NpbXBsZVR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlNjaGVtYUdyYW1tYXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlNjaGVtYU5hbWVzcGFjZVN1cHBvcnQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlNjaGVtYVN5bWJvbHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlhTQXR0cmlidXRlRGVjbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMuWFNHcmFtbWFyQnVja2V0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5YU1dpbGRjYXJkRGVjbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMudXRpbC5YSW50OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy51dGlsLlhJbnRQb29sOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5ET01VdGlsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5TeW1ib2xUYWJsZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuWE1MQ2hhcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuWE1MU3ltYm9sczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWxzLlhNTFNlY3VyaXR5TWFuYWdlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5RTmFtZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTQ29uc3RhbnRzOwotaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwotaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKLWltcG9ydCBqYXZhLnV0aWwuTWFwOwotaW1wb3J0IGphdmEudXRpbC5TdHJpbmdUb2tlbml6ZXI7Ci1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLWltcG9ydCBvcmcudzNjLmRvbS5BdHRyOwotaW1wb3J0IG9yZy53M2MuZG9tLkVsZW1lbnQ7Ci0KLS8qKgotICogQ2xhc3MgPGNvZGU+WFNBdHRyaWJ1dGVDaGVjazwvY29kZT4gaXMgdXNlZCB0byBjaGVjayB0aGUgdmFsaWRpdHkgb2YgYXR0cmlidXRlcwotICogYXBwZWFyaW5nIGluIHRoZSBzY2hlbWEgZG9jdW1lbnQuIEl0Ci0gKiAtIHJlcG9ydHMgYW4gZXJyb3IgZm9yIGludmFsaWQgZWxlbWVudCAoaW52YWxpZCBuYW1lc3BhY2UsIGludmFsaWQgbmFtZSkKLSAqIC0gcmVwb3J0cyBhbiBlcnJvciBmb3IgaW52YWxpZCBhdHRyaWJ1dGUgKGludmFsaWQgbmFtZXNwYWNlLCBpbnZhbGlkIG5hbWUpCi0gKiAtIHJlcG9ydHMgYW4gZXJyb3IgZm9yIGludmFsaWQgYXR0cmlidXRlIHZhbHVlCi0gKiAtIHJldHVybiBjb21waWxlZCB2YWx1ZXMgZm9yIGF0dHJpdXRlIHZhbHVlcwotICogLSBwcm92aWRlIGRlZmF1bHQgdmFsdWUgZm9yIG1pc3Npbmcgb3B0aW9uYWwgYXR0cmlidXRlcwotICogLSBwcm92aWRlIGRlZmF1bHQgdmFsdWUgZm9yIGluY29ycmVjdCBhdHRyaWJ1dGUgdmFsdWVzCi0gKgotICogQnV0IGl0J3MgdGhlIGNhbGxlcidzIHJlc3BvbnNpYmlsaXR5IHRvIGNoZWNrIHdoZXRoZXIgYSByZXF1aXJlZCBhdHRyaWJ1dGUKLSAqIGlzIHByZXNlbnQuCi0gKgotICogVGhpbmdzIG5lZWQgcmV2aXNpdGluZzoKLSAqIC0gV2hldGhlciB0byByZXR1cm4gbm9uLXNjaGVtYSBhdHRyaWJ1dGVzL3ZhbHVlcwotICogLSBEbyB3ZSBuZWVkIHRvIHVwZGF0ZSBOYW1lc3BhY2VTY29wZSBhbmQgRXJyb3JSZXBvcnRlciB3aGVuIHJlc2V0KCk/Ci0gKiAtIFNob3VsZCBoYXZlIHRoZSBkYXRhdHlwZSB2YWxpZGF0b3JzIHJldHVybiBjb21waWxlZCB2YWx1ZQotICogLSB1c2Ugc3ltYm9sIHRhYmxlIGluc3RlYWQgb2YgbWFueSBtYXBzCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgU2FuZHkgR2FvLCBJQk0KLSAqIEB2ZXJzaW9uICRJZDogWFNBdHRyaWJ1dGVDaGVja2VyLmphdmEsdiAxLjEyIDIwMTAtMTEtMDEgMDQ6NDA6MDIgam9laHcgRXhwICQKLSAqLwotCi1wdWJsaWMgY2xhc3MgWFNBdHRyaWJ1dGVDaGVja2VyIHsKLQotICAgIC8vIFJFVklTSVQ6IG9ubHkgbG9jYWwgZWxlbWVudCBhbmQgYXR0cmlidXRlIGFyZSBkaWZmZXJlbnQgZnJvbSBvdGhlcnMuCi0gICAgLy8gICAgICAgICAgaXQncyBwb3NzaWJsZSB0byBoYXZlIGVpdGhlciBuYW1lIG9yIHJlZi4gYWxsIHRoZSBvdGhlcnMKLSAgICAvLyAgICAgICAgICBhcmUgb25seSBhbGxvd2VkIHRvIGhhdmUgb25lIG9mIG5hbWUgb3IgcmVmLCBvciBuZWl0aGVyIG9mIHRoZW0uCi0gICAgLy8gICAgICAgICAgd2UnZCBiZXR0ZXIgbW92ZSBzdWNoIGNoZWNraW5nIHRvIHRoZSB0cmF2ZXJzZXIuCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEVMRU1FTlRfTiA9ICJlbGVtZW50X24iOwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBFTEVNRU5UX1IgPSAiZWxlbWVudF9yIjsKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUUklCVVRFX04gPSAiYXR0cmlidXRlX24iOwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRSSUJVVEVfUiA9ICJhdHRyaWJ1dGVfciI7Ci0KLSAgICBwcml2YXRlIHN0YXRpYyAgICAgICBpbnQgQVRUSURYX0NPVU5UICAgICAgICAgICA9IDA7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQVRUSURYX0FCU1RSQUNUICAgICAgICA9IEFUVElEWF9DT1VOVCsrOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFUVElEWF9BRk9STURFRkFVTFQgICAgPSBBVFRJRFhfQ09VTlQrKzsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBVFRJRFhfQkFTRSAgICAgICAgICAgID0gQVRUSURYX0NPVU5UKys7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQVRUSURYX0JMT0NLICAgICAgICAgICA9IEFUVElEWF9DT1VOVCsrOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFUVElEWF9CTE9DS0RFRkFVTFQgICAgPSBBVFRJRFhfQ09VTlQrKzsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBVFRJRFhfREVGQVVMVCAgICAgICAgID0gQVRUSURYX0NPVU5UKys7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQVRUSURYX0VGT1JNREVGQVVMVCAgICA9IEFUVElEWF9DT1VOVCsrOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFUVElEWF9GSU5BTCAgICAgICAgICAgPSBBVFRJRFhfQ09VTlQrKzsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBVFRJRFhfRklOQUxERUZBVUxUICAgID0gQVRUSURYX0NPVU5UKys7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQVRUSURYX0ZJWEVEICAgICAgICAgICA9IEFUVElEWF9DT1VOVCsrOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFUVElEWF9GT1JNICAgICAgICAgICAgPSBBVFRJRFhfQ09VTlQrKzsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBVFRJRFhfSUQgICAgICAgICAgICAgID0gQVRUSURYX0NPVU5UKys7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQVRUSURYX0lURU1UWVBFICAgICAgICA9IEFUVElEWF9DT1VOVCsrOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFUVElEWF9NQVhPQ0NVUlMgICAgICAgPSBBVFRJRFhfQ09VTlQrKzsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBVFRJRFhfTUVNQkVSVFlQRVMgICAgID0gQVRUSURYX0NPVU5UKys7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQVRUSURYX01JTk9DQ1VSUyAgICAgICA9IEFUVElEWF9DT1VOVCsrOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFUVElEWF9NSVhFRCAgICAgICAgICAgPSBBVFRJRFhfQ09VTlQrKzsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBVFRJRFhfTkFNRSAgICAgICAgICAgID0gQVRUSURYX0NPVU5UKys7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQVRUSURYX05BTUVTUEFDRSAgICAgICA9IEFUVElEWF9DT1VOVCsrOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFUVElEWF9OQU1FU1BBQ0VfTElTVCAgPSBBVFRJRFhfQ09VTlQrKzsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBVFRJRFhfTklMTEFCTEUgICAgICAgID0gQVRUSURYX0NPVU5UKys7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQVRUSURYX05PTlNDSEVNQSAgICAgICA9IEFUVElEWF9DT1VOVCsrOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFUVElEWF9QUk9DRVNTQ09OVEVOVFMgPSBBVFRJRFhfQ09VTlQrKzsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBVFRJRFhfUFVCTElDICAgICAgICAgID0gQVRUSURYX0NPVU5UKys7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQVRUSURYX1JFRiAgICAgICAgICAgICA9IEFUVElEWF9DT1VOVCsrOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFUVElEWF9SRUZFUiAgICAgICAgICAgPSBBVFRJRFhfQ09VTlQrKzsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBVFRJRFhfU0NIRU1BTE9DQVRJT04gID0gQVRUSURYX0NPVU5UKys7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQVRUSURYX1NPVVJDRSAgICAgICAgICA9IEFUVElEWF9DT1VOVCsrOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFUVElEWF9TVUJTR1JPVVAgICAgICAgPSBBVFRJRFhfQ09VTlQrKzsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBVFRJRFhfU1lTVEVNICAgICAgICAgID0gQVRUSURYX0NPVU5UKys7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQVRUSURYX1RBUkdFVE5BTUVTUEFDRSA9IEFUVElEWF9DT1VOVCsrOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFUVElEWF9UWVBFICAgICAgICAgICAgPSBBVFRJRFhfQ09VTlQrKzsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBVFRJRFhfVVNFICAgICAgICAgICAgID0gQVRUSURYX0NPVU5UKys7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQVRUSURYX1ZBTFVFICAgICAgICAgICA9IEFUVElEWF9DT1VOVCsrOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFUVElEWF9FTlVNTlNERUNMUyAgICAgPSBBVFRJRFhfQ09VTlQrKzsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBVFRJRFhfVkVSU0lPTiAgICAgICAgID0gQVRUSURYX0NPVU5UKys7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQVRUSURYX1hNTF9MQU5HICAgICAgICA9IEFUVElEWF9DT1VOVCsrOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFUVElEWF9YUEFUSCAgICAgICAgICAgPSBBVFRJRFhfQ09VTlQrKzsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBVFRJRFhfRlJPTURFRkFVTFQgICAgID0gQVRUSURYX0NPVU5UKys7Ci0gICAgLy9wdWJsaWMgc3RhdGljIGZpbmFsIGludCBBVFRJRFhfT1RIRVJWQUxVRVMgICAgID0gQVRUSURYX0NPVU5UKys7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQVRUSURYX0lTUkVUVVJORUQgICAgICA9IEFUVElEWF9DT1VOVCsrOwotCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgWEludFBvb2wgZlhJbnRQb29sID0gbmV3IFhJbnRQb29sKCk7Ci0gICAgLy8gY29uc3RhbnRzIHRvIHJldHVybgotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFhJbnQgSU5UX1FVQUxJRklFRCAgICAgID0gZlhJbnRQb29sLmdldFhJbnQoU2NoZW1hU3ltYm9scy5GT1JNX1FVQUxJRklFRCk7Ci0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgWEludCBJTlRfVU5RVUFMSUZJRUQgICAgPSBmWEludFBvb2wuZ2V0WEludChTY2hlbWFTeW1ib2xzLkZPUk1fVU5RVUFMSUZJRUQpOwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFhJbnQgSU5UX0VNUFRZX1NFVCAgICAgID0gZlhJbnRQb29sLmdldFhJbnQoWFNDb25zdGFudHMuREVSSVZBVElPTl9OT05FKTsKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBYSW50IElOVF9BTllfU1RSSUNUICAgICA9IGZYSW50UG9vbC5nZXRYSW50KFhTV2lsZGNhcmREZWNsLlBDX1NUUklDVCk7Ci0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgWEludCBJTlRfQU5ZX0xBWCAgICAgICAgPSBmWEludFBvb2wuZ2V0WEludChYU1dpbGRjYXJkRGVjbC5QQ19MQVgpOwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFhJbnQgSU5UX0FOWV9TS0lQICAgICAgID0gZlhJbnRQb29sLmdldFhJbnQoWFNXaWxkY2FyZERlY2wuUENfU0tJUCk7Ci0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgWEludCBJTlRfQU5ZX0FOWSAgICAgICAgPSBmWEludFBvb2wuZ2V0WEludChYU1dpbGRjYXJkRGVjbC5OU0NPTlNUUkFJTlRfQU5ZKTsKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBYSW50IElOVF9BTllfTElTVCAgICAgICA9IGZYSW50UG9vbC5nZXRYSW50KFhTV2lsZGNhcmREZWNsLk5TQ09OU1RSQUlOVF9MSVNUKTsKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBYSW50IElOVF9BTllfTk9UICAgICAgICA9IGZYSW50UG9vbC5nZXRYSW50KFhTV2lsZGNhcmREZWNsLk5TQ09OU1RSQUlOVF9OT1QpOwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFhJbnQgSU5UX1VTRV9PUFRJT05BTCAgID0gZlhJbnRQb29sLmdldFhJbnQoU2NoZW1hU3ltYm9scy5VU0VfT1BUSU9OQUwpOwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFhJbnQgSU5UX1VTRV9SRVFVSVJFRCAgID0gZlhJbnRQb29sLmdldFhJbnQoU2NoZW1hU3ltYm9scy5VU0VfUkVRVUlSRUQpOwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFhJbnQgSU5UX1VTRV9QUk9ISUJJVEVEID0gZlhJbnRQb29sLmdldFhJbnQoU2NoZW1hU3ltYm9scy5VU0VfUFJPSElCSVRFRCk7Ci0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgWEludCBJTlRfV1NfUFJFU0VSVkUgICAgPSBmWEludFBvb2wuZ2V0WEludChYU1NpbXBsZVR5cGUuV1NfUFJFU0VSVkUpOwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFhJbnQgSU5UX1dTX1JFUExBQ0UgICAgID0gZlhJbnRQb29sLmdldFhJbnQoWFNTaW1wbGVUeXBlLldTX1JFUExBQ0UpOwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFhJbnQgSU5UX1dTX0NPTExBUFNFICAgID0gZlhJbnRQb29sLmdldFhJbnQoWFNTaW1wbGVUeXBlLldTX0NPTExBUFNFKTsKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBYSW50IElOVF9VTkJPVU5ERUQgICAgICA9IGZYSW50UG9vbC5nZXRYSW50KFNjaGVtYVN5bWJvbHMuT0NDVVJSRU5DRV9VTkJPVU5ERUQpOwotCi0gICAgLy8gdXNlZCB0byBzdG9yZSB0aGUgbWFwIGZyb20gZWxlbWVudCBuYW1lIHRvIGF0dHJpYnV0ZSBsaXN0Ci0gICAgLy8gZm9yIDE0IGdsb2JhbCBlbGVtZW50cwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIE1hcCBmRWxlQXR0cnNNYXBHID0gbmV3IEhhc2hNYXAoMjkpOwotICAgIC8vIGZvciAzOSBsb2NhbCBlbGVtZW1udHMKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBNYXAgZkVsZUF0dHJzTWFwTCA9IG5ldyBIYXNoTWFwKDc5KTsKLQotICAgIC8vIHVzZWQgdG8gaW5pdGlhbGl6ZSBmRWxlQXR0cnNNYXAKLSAgICAvLyBzdGVwIDE6IGFsbCBwb3NzaWJsZSBkYXRhIHR5cGVzCi0gICAgLy8gRFRfPz8/ID49IDAgOiB2YWxpZGF0ZSB1c2luZyBhIHZhbGlkYXRvciwgd2hpY2ggaXMgaW5pdGlhbGl6ZWQgc3RhdGljbHkKLSAgICAvLyBEVF8/Pz8gPCAgMCA6IHZhbGlkYXRlIGRpcmVjdGx5LCB3aGljaCBpcyBkb25lIGluICJ2YWxpZGF0ZSgpIgotCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBpbnQgRFRfQU5ZVVJJICAgICAgICAgICA9IDA7Ci0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBpbnQgRFRfSUQgICAgICAgICAgICAgICA9IDE7Ci0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBpbnQgRFRfUU5BTUUgICAgICAgICAgICA9IDI7Ci0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBpbnQgRFRfU1RSSU5HICAgICAgICAgICA9IDM7Ci0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBpbnQgRFRfVE9LRU4gICAgICAgICAgICA9IDQ7Ci0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBpbnQgRFRfTkNOQU1FICAgICAgICAgICA9IDU7Ci0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBpbnQgRFRfWFBBVEggICAgICAgICAgICA9IDY7Ci0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBpbnQgRFRfWFBBVEgxICAgICAgICAgICA9IDc7Ci0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBpbnQgRFRfTEFOR1VBR0UgICAgICAgICA9IDg7Ci0KLSAgICAvLyB1c2VkIHRvIHN0b3JlIGV4dHJhIGRhdGF0eXBlIHZhbGlkYXRvcnMKLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBEVF9DT1VOVCAgICAgICAgICAgID0gRFRfTEFOR1VBR0UgKyAxOwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFhTU2ltcGxlVHlwZVtdIGZFeHRyYURWcyA9IG5ldyBYU1NpbXBsZVR5cGVbRFRfQ09VTlRdOwotICAgIHN0YXRpYyB7Ci0gICAgICAgIC8vIHN0ZXAgNTogcmVnaXN0ZXIgYWxsIGRhdGF0eXBlIHZhbGlkYXRvcnMgZm9yIG5ldyB0eXBlcwotICAgICAgICBTY2hlbWFHcmFtbWFyIGdyYW1tYXIgPSBTY2hlbWFHcmFtbWFyLlNHX1NjaGVtYU5TOwotICAgICAgICAvLyBhbnlVUkkKLSAgICAgICAgZkV4dHJhRFZzW0RUX0FOWVVSSV0gPSAoWFNTaW1wbGVUeXBlKWdyYW1tYXIuZ2V0R2xvYmFsVHlwZURlY2woU2NoZW1hU3ltYm9scy5BVFRWQUxfQU5ZVVJJKTsKLSAgICAgICAgLy8gSUQKLSAgICAgICAgZkV4dHJhRFZzW0RUX0lEXSA9IChYU1NpbXBsZVR5cGUpZ3JhbW1hci5nZXRHbG9iYWxUeXBlRGVjbChTY2hlbWFTeW1ib2xzLkFUVFZBTF9JRCk7Ci0gICAgICAgIC8vIFFOYW1lCi0gICAgICAgIGZFeHRyYURWc1tEVF9RTkFNRV0gPSAoWFNTaW1wbGVUeXBlKWdyYW1tYXIuZ2V0R2xvYmFsVHlwZURlY2woU2NoZW1hU3ltYm9scy5BVFRWQUxfUU5BTUUpOwotICAgICAgICAvLyBzdHJpbmcKLSAgICAgICAgZkV4dHJhRFZzW0RUX1NUUklOR10gPSAoWFNTaW1wbGVUeXBlKWdyYW1tYXIuZ2V0R2xvYmFsVHlwZURlY2woU2NoZW1hU3ltYm9scy5BVFRWQUxfU1RSSU5HKTsKLSAgICAgICAgLy8gdG9rZW4KLSAgICAgICAgZkV4dHJhRFZzW0RUX1RPS0VOXSA9IChYU1NpbXBsZVR5cGUpZ3JhbW1hci5nZXRHbG9iYWxUeXBlRGVjbChTY2hlbWFTeW1ib2xzLkFUVFZBTF9UT0tFTik7Ci0gICAgICAgIC8vIE5DTmFtZQotICAgICAgICBmRXh0cmFEVnNbRFRfTkNOQU1FXSA9IChYU1NpbXBsZVR5cGUpZ3JhbW1hci5nZXRHbG9iYWxUeXBlRGVjbChTY2hlbWFTeW1ib2xzLkFUVFZBTF9OQ05BTUUpOwotICAgICAgICAvLyB4cGF0aCA9IGEgc3Vic2V0IG9mIFhQYXRoIGV4cHJlc3Npb24KLSAgICAgICAgZkV4dHJhRFZzW0RUX1hQQVRIXSA9IGZFeHRyYURWc1tEVF9TVFJJTkddOwotICAgICAgICAvLyB4cGF0aCA9IGEgc3Vic2V0IG9mIFhQYXRoIGV4cHJlc3Npb24KLSAgICAgICAgZkV4dHJhRFZzW0RUX1hQQVRIXSA9IGZFeHRyYURWc1tEVF9TVFJJTkddOwotICAgICAgICAvLyBsYW5ndWFnZQotICAgICAgICBmRXh0cmFEVnNbRFRfTEFOR1VBR0VdID0gKFhTU2ltcGxlVHlwZSlncmFtbWFyLmdldEdsb2JhbFR5cGVEZWNsKFNjaGVtYVN5bWJvbHMuQVRUVkFMX0xBTkdVQUdFKTsKLSAgICB9Ci0KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBEVF9CTE9DSyAgICAgICAgICAgID0gLTE7Ci0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBpbnQgRFRfQkxPQ0sxICAgICAgICAgICA9IC0yOwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgaW50IERUX0ZJTkFMICAgICAgICAgICAgPSAtMzsKLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBEVF9GSU5BTDEgICAgICAgICAgID0gLTQ7Ci0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBpbnQgRFRfRklOQUwyICAgICAgICAgICA9IC01OwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgaW50IERUX0ZPUk0gICAgICAgICAgICAgPSAtNjsKLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBEVF9NQVhPQ0NVUlMgICAgICAgID0gLTc7Ci0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBpbnQgRFRfTUFYT0NDVVJTMSAgICAgICA9IC04OwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgaW50IERUX01FTUJFUlRZUEVTICAgICAgPSAtOTsKLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBEVF9NSU5PQ0NVUlMxICAgICAgID0gLTEwOwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgaW50IERUX05BTUVTUEFDRSAgICAgICAgPSAtMTE7Ci0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBpbnQgRFRfUFJPQ0VTU0NPTlRFTlRTICA9IC0xMjsKLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBEVF9VU0UgICAgICAgICAgICAgID0gLTEzOwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgaW50IERUX1dISVRFU1BBQ0UgICAgICAgPSAtMTQ7Ci0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBpbnQgRFRfQk9PTEVBTiAgICAgICAgICA9IC0xNTsKLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBEVF9OT05ORUdJTlQgICAgICAgID0gLTE2OwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgaW50IERUX1BPU0lOVCAgICAgICAgICAgPSAtMTc7Ci0KLSAgICBzdGF0aWMgewotICAgICAgICAvLyBzdGVwIDI6IGFsbCBwb3NzaWJsZSBhdHRyaWJ1dGVzIGZvciBhbGwgZWxlbWVudHMKLSAgICAgICAgaW50IGF0dENvdW50ID0gMDsKLSAgICAgICAgaW50IEFUVF9BQlNUUkFDVF9EICAgICAgICAgID0gYXR0Q291bnQrKzsKLSAgICAgICAgaW50IEFUVF9BVFRSSUJVVEVfRkRfRCAgICAgID0gYXR0Q291bnQrKzsKLSAgICAgICAgaW50IEFUVF9CQVNFX1IgICAgICAgICAgICAgID0gYXR0Q291bnQrKzsKLSAgICAgICAgaW50IEFUVF9CQVNFX04gICAgICAgICAgICAgID0gYXR0Q291bnQrKzsKLSAgICAgICAgaW50IEFUVF9CTE9DS19OICAgICAgICAgICAgID0gYXR0Q291bnQrKzsKLSAgICAgICAgaW50IEFUVF9CTE9DSzFfTiAgICAgICAgICAgID0gYXR0Q291bnQrKzsKLSAgICAgICAgaW50IEFUVF9CTE9DS19EX0QgICAgICAgICAgID0gYXR0Q291bnQrKzsKLSAgICAgICAgaW50IEFUVF9ERUZBVUxUX04gICAgICAgICAgID0gYXR0Q291bnQrKzsKLSAgICAgICAgaW50IEFUVF9FTEVNRU5UX0ZEX0QgICAgICAgID0gYXR0Q291bnQrKzsKLSAgICAgICAgaW50IEFUVF9GSU5BTF9OICAgICAgICAgICAgID0gYXR0Q291bnQrKzsKLSAgICAgICAgaW50IEFUVF9GSU5BTDFfTiAgICAgICAgICAgID0gYXR0Q291bnQrKzsKLSAgICAgICAgaW50IEFUVF9GSU5BTF9EX0QgICAgICAgICAgID0gYXR0Q291bnQrKzsKLSAgICAgICAgaW50IEFUVF9GSVhFRF9OICAgICAgICAgICAgID0gYXR0Q291bnQrKzsKLSAgICAgICAgaW50IEFUVF9GSVhFRF9EICAgICAgICAgICAgID0gYXR0Q291bnQrKzsKLSAgICAgICAgaW50IEFUVF9GT1JNX04gICAgICAgICAgICAgID0gYXR0Q291bnQrKzsKLSAgICAgICAgaW50IEFUVF9JRF9OICAgICAgICAgICAgICAgID0gYXR0Q291bnQrKzsKLSAgICAgICAgaW50IEFUVF9JVEVNVFlQRV9OICAgICAgICAgID0gYXR0Q291bnQrKzsKLSAgICAgICAgaW50IEFUVF9NQVhPQ0NVUlNfRCAgICAgICAgID0gYXR0Q291bnQrKzsKLSAgICAgICAgaW50IEFUVF9NQVhPQ0NVUlMxX0QgICAgICAgID0gYXR0Q291bnQrKzsKLSAgICAgICAgaW50IEFUVF9NRU1CRVJfVF9OICAgICAgICAgID0gYXR0Q291bnQrKzsKLSAgICAgICAgaW50IEFUVF9NSU5PQ0NVUlNfRCAgICAgICAgID0gYXR0Q291bnQrKzsKLSAgICAgICAgaW50IEFUVF9NSU5PQ0NVUlMxX0QgICAgICAgID0gYXR0Q291bnQrKzsKLSAgICAgICAgaW50IEFUVF9NSVhFRF9EICAgICAgICAgICAgID0gYXR0Q291bnQrKzsKLSAgICAgICAgaW50IEFUVF9NSVhFRF9OICAgICAgICAgICAgID0gYXR0Q291bnQrKzsKLSAgICAgICAgaW50IEFUVF9OQU1FX1IgICAgICAgICAgICAgID0gYXR0Q291bnQrKzsKLSAgICAgICAgaW50IEFUVF9OQU1FU1BBQ0VfRCAgICAgICAgID0gYXR0Q291bnQrKzsKLSAgICAgICAgaW50IEFUVF9OQU1FU1BBQ0VfTiAgICAgICAgID0gYXR0Q291bnQrKzsKLSAgICAgICAgaW50IEFUVF9OSUxMQUJMRV9EICAgICAgICAgID0gYXR0Q291bnQrKzsKLSAgICAgICAgaW50IEFUVF9QUk9DRVNTX0NfRCAgICAgICAgID0gYXR0Q291bnQrKzsKLSAgICAgICAgaW50IEFUVF9QVUJMSUNfUiAgICAgICAgICAgID0gYXR0Q291bnQrKzsKLSAgICAgICAgaW50IEFUVF9SRUZfUiAgICAgICAgICAgICAgID0gYXR0Q291bnQrKzsKLSAgICAgICAgaW50IEFUVF9SRUZFUl9SICAgICAgICAgICAgID0gYXR0Q291bnQrKzsKLSAgICAgICAgaW50IEFUVF9TQ0hFTUFfTF9SICAgICAgICAgID0gYXR0Q291bnQrKzsKLSAgICAgICAgaW50IEFUVF9TQ0hFTUFfTF9OICAgICAgICAgID0gYXR0Q291bnQrKzsKLSAgICAgICAgaW50IEFUVF9TT1VSQ0VfTiAgICAgICAgICAgID0gYXR0Q291bnQrKzsKLSAgICAgICAgaW50IEFUVF9TVUJTVElUVVRJT05fR19OICAgID0gYXR0Q291bnQrKzsKLSAgICAgICAgaW50IEFUVF9TWVNURU1fTiAgICAgICAgICAgID0gYXR0Q291bnQrKzsKLSAgICAgICAgaW50IEFUVF9UQVJHRVRfTl9OICAgICAgICAgID0gYXR0Q291bnQrKzsKLSAgICAgICAgaW50IEFUVF9UWVBFX04gICAgICAgICAgICAgID0gYXR0Q291bnQrKzsKLSAgICAgICAgaW50IEFUVF9VU0VfRCAgICAgICAgICAgICAgID0gYXR0Q291bnQrKzsKLSAgICAgICAgaW50IEFUVF9WQUxVRV9OTklfTiAgICAgICAgID0gYXR0Q291bnQrKzsKLSAgICAgICAgaW50IEFUVF9WQUxVRV9QSV9OICAgICAgICAgID0gYXR0Q291bnQrKzsKLSAgICAgICAgaW50IEFUVF9WQUxVRV9TVFJfTiAgICAgICAgID0gYXR0Q291bnQrKzsKLSAgICAgICAgaW50IEFUVF9WQUxVRV9XU19OICAgICAgICAgID0gYXR0Q291bnQrKzsKLSAgICAgICAgaW50IEFUVF9WRVJTSU9OX04gICAgICAgICAgID0gYXR0Q291bnQrKzsKLSAgICAgICAgaW50IEFUVF9YTUxfTEFORyAgICAgICAgICAgID0gYXR0Q291bnQrKzsKLSAgICAgICAgaW50IEFUVF9YUEFUSF9SICAgICAgICAgICAgID0gYXR0Q291bnQrKzsKLSAgICAgICAgaW50IEFUVF9YUEFUSDFfUiAgICAgICAgICAgID0gYXR0Q291bnQrKzsKLQotICAgICAgICAvLyBzdGVwIDM6IHN0b3JlIGFsbCB0aGVzZSBhdHRyaWJ1dGVzIGluIGFuIGFycmF5Ci0gICAgICAgIE9uZUF0dHJbXSBhbGxBdHRycyA9IG5ldyBPbmVBdHRyW2F0dENvdW50XTsKLSAgICAgICAgYWxsQXR0cnNbQVRUX0FCU1RSQUNUX0RdICAgICAgICA9ICAgbmV3IE9uZUF0dHIoU2NoZW1hU3ltYm9scy5BVFRfQUJTVFJBQ1QsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERUX0JPT0xFQU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFUVElEWF9BQlNUUkFDVCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQm9vbGVhbi5GQUxTRSk7Ci0gICAgICAgIGFsbEF0dHJzW0FUVF9BVFRSSUJVVEVfRkRfRF0gICAgPSAgIG5ldyBPbmVBdHRyKFNjaGVtYVN5bWJvbHMuQVRUX0FUVFJJQlVURUZPUk1ERUZBVUxULAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEVF9GT1JNLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBVFRJRFhfQUZPUk1ERUZBVUxULAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlRfVU5RVUFMSUZJRUQpOwotICAgICAgICBhbGxBdHRyc1tBVFRfQkFTRV9SXSAgICAgICAgICAgID0gICBuZXcgT25lQXR0cihTY2hlbWFTeW1ib2xzLkFUVF9CQVNFLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEVF9RTkFNRSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVRUSURYX0JBU0UsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwpOwotICAgICAgICBhbGxBdHRyc1tBVFRfQkFTRV9OXSAgICAgICAgICAgID0gICBuZXcgT25lQXR0cihTY2hlbWFTeW1ib2xzLkFUVF9CQVNFLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEVF9RTkFNRSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVRUSURYX0JBU0UsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwpOwotICAgICAgICBhbGxBdHRyc1tBVFRfQkxPQ0tfTl0gICAgICAgICAgID0gICBuZXcgT25lQXR0cihTY2hlbWFTeW1ib2xzLkFUVF9CTE9DSywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFRfQkxPQ0ssCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFUVElEWF9CTE9DSywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCk7Ci0gICAgICAgIGFsbEF0dHJzW0FUVF9CTE9DSzFfTl0gICAgICAgICAgPSAgIG5ldyBPbmVBdHRyKFNjaGVtYVN5bWJvbHMuQVRUX0JMT0NLLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEVF9CTE9DSzEsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFUVElEWF9CTE9DSywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCk7Ci0gICAgICAgIGFsbEF0dHJzW0FUVF9CTE9DS19EX0RdICAgICAgICAgPSAgIG5ldyBPbmVBdHRyKFNjaGVtYVN5bWJvbHMuQVRUX0JMT0NLREVGQVVMVCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFRfQkxPQ0ssCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFUVElEWF9CTE9DS0RFRkFVTFQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVF9FTVBUWV9TRVQpOwotICAgICAgICBhbGxBdHRyc1tBVFRfREVGQVVMVF9OXSAgICAgICAgID0gICBuZXcgT25lQXR0cihTY2hlbWFTeW1ib2xzLkFUVF9ERUZBVUxULAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEVF9TVFJJTkcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFUVElEWF9ERUZBVUxULAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsKTsKLSAgICAgICAgYWxsQXR0cnNbQVRUX0VMRU1FTlRfRkRfRF0gICAgICA9ICAgbmV3IE9uZUF0dHIoU2NoZW1hU3ltYm9scy5BVFRfRUxFTUVOVEZPUk1ERUZBVUxULAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEVF9GT1JNLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBVFRJRFhfRUZPUk1ERUZBVUxULAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlRfVU5RVUFMSUZJRUQpOwotICAgICAgICBhbGxBdHRyc1tBVFRfRklOQUxfTl0gICAgICAgICAgID0gICBuZXcgT25lQXR0cihTY2hlbWFTeW1ib2xzLkFUVF9GSU5BTCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFRfRklOQUwsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFUVElEWF9GSU5BTCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCk7Ci0gICAgICAgIGFsbEF0dHJzW0FUVF9GSU5BTDFfTl0gICAgICAgICAgPSAgIG5ldyBPbmVBdHRyKFNjaGVtYVN5bWJvbHMuQVRUX0ZJTkFMLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEVF9GSU5BTDEsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFUVElEWF9GSU5BTCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCk7Ci0gICAgICAgIGFsbEF0dHJzW0FUVF9GSU5BTF9EX0RdICAgICAgICAgPSAgIG5ldyBPbmVBdHRyKFNjaGVtYVN5bWJvbHMuQVRUX0ZJTkFMREVGQVVMVCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFRfRklOQUwyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBVFRJRFhfRklOQUxERUZBVUxULAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlRfRU1QVFlfU0VUKTsKLSAgICAgICAgYWxsQXR0cnNbQVRUX0ZJWEVEX05dICAgICAgICAgICA9ICAgbmV3IE9uZUF0dHIoU2NoZW1hU3ltYm9scy5BVFRfRklYRUQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERUX1NUUklORywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVRUSURYX0ZJWEVELAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsKTsKLSAgICAgICAgYWxsQXR0cnNbQVRUX0ZJWEVEX0RdICAgICAgICAgICA9ICAgbmV3IE9uZUF0dHIoU2NoZW1hU3ltYm9scy5BVFRfRklYRUQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERUX0JPT0xFQU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFUVElEWF9GSVhFRCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQm9vbGVhbi5GQUxTRSk7Ci0gICAgICAgIGFsbEF0dHJzW0FUVF9GT1JNX05dICAgICAgICAgICAgPSAgIG5ldyBPbmVBdHRyKFNjaGVtYVN5bWJvbHMuQVRUX0ZPUk0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERUX0ZPUk0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFUVElEWF9GT1JNLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsKTsKLSAgICAgICAgYWxsQXR0cnNbQVRUX0lEX05dICAgICAgICAgICAgICA9ICAgbmV3IE9uZUF0dHIoU2NoZW1hU3ltYm9scy5BVFRfSUQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERUX0lELAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBVFRJRFhfSUQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwpOwotICAgICAgICBhbGxBdHRyc1tBVFRfSVRFTVRZUEVfTl0gICAgICAgID0gICBuZXcgT25lQXR0cihTY2hlbWFTeW1ib2xzLkFUVF9JVEVNVFlQRSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFRfUU5BTUUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFUVElEWF9JVEVNVFlQRSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCk7Ci0gICAgICAgIGFsbEF0dHJzW0FUVF9NQVhPQ0NVUlNfRF0gICAgICAgPSAgIG5ldyBPbmVBdHRyKFNjaGVtYVN5bWJvbHMuQVRUX01BWE9DQ1VSUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFRfTUFYT0NDVVJTLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBVFRJRFhfTUFYT0NDVVJTLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmWEludFBvb2wuZ2V0WEludCgxKSk7Ci0gICAgICAgIGFsbEF0dHJzW0FUVF9NQVhPQ0NVUlMxX0RdICAgICAgPSAgIG5ldyBPbmVBdHRyKFNjaGVtYVN5bWJvbHMuQVRUX01BWE9DQ1VSUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFRfTUFYT0NDVVJTMSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVRUSURYX01BWE9DQ1VSUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZlhJbnRQb29sLmdldFhJbnQoMSkpOwotICAgICAgICBhbGxBdHRyc1tBVFRfTUVNQkVSX1RfTl0gICAgICAgID0gICBuZXcgT25lQXR0cihTY2hlbWFTeW1ib2xzLkFUVF9NRU1CRVJUWVBFUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFRfTUVNQkVSVFlQRVMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFUVElEWF9NRU1CRVJUWVBFUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCk7Ci0gICAgICAgIGFsbEF0dHJzW0FUVF9NSU5PQ0NVUlNfRF0gICAgICAgPSAgIG5ldyBPbmVBdHRyKFNjaGVtYVN5bWJvbHMuQVRUX01JTk9DQ1VSUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFRfTk9OTkVHSU5ULAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBVFRJRFhfTUlOT0NDVVJTLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmWEludFBvb2wuZ2V0WEludCgxKSk7Ci0gICAgICAgIGFsbEF0dHJzW0FUVF9NSU5PQ0NVUlMxX0RdICAgICAgPSAgIG5ldyBPbmVBdHRyKFNjaGVtYVN5bWJvbHMuQVRUX01JTk9DQ1VSUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFRfTUlOT0NDVVJTMSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVRUSURYX01JTk9DQ1VSUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZlhJbnRQb29sLmdldFhJbnQoMSkpOwotICAgICAgICBhbGxBdHRyc1tBVFRfTUlYRURfRF0gICAgICAgICAgID0gICBuZXcgT25lQXR0cihTY2hlbWFTeW1ib2xzLkFUVF9NSVhFRCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFRfQk9PTEVBTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVRUSURYX01JWEVELAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCb29sZWFuLkZBTFNFKTsKLSAgICAgICAgYWxsQXR0cnNbQVRUX01JWEVEX05dICAgICAgICAgICA9ICAgbmV3IE9uZUF0dHIoU2NoZW1hU3ltYm9scy5BVFRfTUlYRUQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERUX0JPT0xFQU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFUVElEWF9NSVhFRCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCk7Ci0gICAgICAgIGFsbEF0dHJzW0FUVF9OQU1FX1JdICAgICAgICAgICAgPSAgIG5ldyBPbmVBdHRyKFNjaGVtYVN5bWJvbHMuQVRUX05BTUUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERUX05DTkFNRSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVRUSURYX05BTUUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwpOwotICAgICAgICBhbGxBdHRyc1tBVFRfTkFNRVNQQUNFX0RdICAgICAgID0gICBuZXcgT25lQXR0cihTY2hlbWFTeW1ib2xzLkFUVF9OQU1FU1BBQ0UsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERUX05BTUVTUEFDRSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVRUSURYX05BTUVTUEFDRSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UX0FOWV9BTlkpOwotICAgICAgICBhbGxBdHRyc1tBVFRfTkFNRVNQQUNFX05dICAgICAgID0gICBuZXcgT25lQXR0cihTY2hlbWFTeW1ib2xzLkFUVF9OQU1FU1BBQ0UsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERUX0FOWVVSSSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVRUSURYX05BTUVTUEFDRSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCk7Ci0gICAgICAgIGFsbEF0dHJzW0FUVF9OSUxMQUJMRV9EXSAgICAgICAgPSAgIG5ldyBPbmVBdHRyKFNjaGVtYVN5bWJvbHMuQVRUX05JTExBQkxFLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEVF9CT09MRUFOLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBVFRJRFhfTklMTEFCTEUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJvb2xlYW4uRkFMU0UpOwotICAgICAgICBhbGxBdHRyc1tBVFRfUFJPQ0VTU19DX0RdICAgICAgID0gICBuZXcgT25lQXR0cihTY2hlbWFTeW1ib2xzLkFUVF9QUk9DRVNTQ09OVEVOVFMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERUX1BST0NFU1NDT05URU5UUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVRUSURYX1BST0NFU1NDT05URU5UUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UX0FOWV9TVFJJQ1QpOwotICAgICAgICBhbGxBdHRyc1tBVFRfUFVCTElDX1JdICAgICAgICAgID0gICBuZXcgT25lQXR0cihTY2hlbWFTeW1ib2xzLkFUVF9QVUJMSUMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERUX1RPS0VOLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBVFRJRFhfUFVCTElDLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsKTsKLSAgICAgICAgYWxsQXR0cnNbQVRUX1JFRl9SXSAgICAgICAgICAgICA9ICAgbmV3IE9uZUF0dHIoU2NoZW1hU3ltYm9scy5BVFRfUkVGLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEVF9RTkFNRSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVRUSURYX1JFRiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCk7Ci0gICAgICAgIGFsbEF0dHJzW0FUVF9SRUZFUl9SXSAgICAgICAgICAgPSAgIG5ldyBPbmVBdHRyKFNjaGVtYVN5bWJvbHMuQVRUX1JFRkVSLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEVF9RTkFNRSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVRUSURYX1JFRkVSLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsKTsKLSAgICAgICAgYWxsQXR0cnNbQVRUX1NDSEVNQV9MX1JdICAgICAgICA9ICAgbmV3IE9uZUF0dHIoU2NoZW1hU3ltYm9scy5BVFRfU0NIRU1BTE9DQVRJT04sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERUX0FOWVVSSSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVRUSURYX1NDSEVNQUxPQ0FUSU9OLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsKTsKLSAgICAgICAgYWxsQXR0cnNbQVRUX1NDSEVNQV9MX05dICAgICAgICA9ICAgbmV3IE9uZUF0dHIoU2NoZW1hU3ltYm9scy5BVFRfU0NIRU1BTE9DQVRJT04sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERUX0FOWVVSSSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVRUSURYX1NDSEVNQUxPQ0FUSU9OLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsKTsKLSAgICAgICAgYWxsQXR0cnNbQVRUX1NPVVJDRV9OXSAgICAgICAgICA9ICAgbmV3IE9uZUF0dHIoU2NoZW1hU3ltYm9scy5BVFRfU09VUkNFLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEVF9BTllVUkksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFUVElEWF9TT1VSQ0UsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwpOwotICAgICAgICBhbGxBdHRyc1tBVFRfU1VCU1RJVFVUSU9OX0dfTl0gID0gICBuZXcgT25lQXR0cihTY2hlbWFTeW1ib2xzLkFUVF9TVUJTVElUVVRJT05HUk9VUCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFRfUU5BTUUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFUVElEWF9TVUJTR1JPVVAsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwpOwotICAgICAgICBhbGxBdHRyc1tBVFRfU1lTVEVNX05dICAgICAgICAgID0gICBuZXcgT25lQXR0cihTY2hlbWFTeW1ib2xzLkFUVF9TWVNURU0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERUX0FOWVVSSSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVRUSURYX1NZU1RFTSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCk7Ci0gICAgICAgIGFsbEF0dHJzW0FUVF9UQVJHRVRfTl9OXSAgICAgICAgPSAgIG5ldyBPbmVBdHRyKFNjaGVtYVN5bWJvbHMuQVRUX1RBUkdFVE5BTUVTUEFDRSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFRfQU5ZVVJJLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBVFRJRFhfVEFSR0VUTkFNRVNQQUNFLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsKTsKLSAgICAgICAgYWxsQXR0cnNbQVRUX1RZUEVfTl0gICAgICAgICAgICA9ICAgbmV3IE9uZUF0dHIoU2NoZW1hU3ltYm9scy5BVFRfVFlQRSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFRfUU5BTUUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFUVElEWF9UWVBFLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsKTsKLSAgICAgICAgYWxsQXR0cnNbQVRUX1VTRV9EXSAgICAgICAgICAgICA9ICAgbmV3IE9uZUF0dHIoU2NoZW1hU3ltYm9scy5BVFRfVVNFLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEVF9VU0UsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFUVElEWF9VU0UsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVF9VU0VfT1BUSU9OQUwpOwotICAgICAgICBhbGxBdHRyc1tBVFRfVkFMVUVfTk5JX05dICAgICAgID0gICBuZXcgT25lQXR0cihTY2hlbWFTeW1ib2xzLkFUVF9WQUxVRSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFRfTk9OTkVHSU5ULAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBVFRJRFhfVkFMVUUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwpOwotICAgICAgICBhbGxBdHRyc1tBVFRfVkFMVUVfUElfTl0gICAgICAgID0gICBuZXcgT25lQXR0cihTY2hlbWFTeW1ib2xzLkFUVF9WQUxVRSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFRfUE9TSU5ULAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBVFRJRFhfVkFMVUUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwpOwotICAgICAgICBhbGxBdHRyc1tBVFRfVkFMVUVfU1RSX05dICAgICAgID0gICBuZXcgT25lQXR0cihTY2hlbWFTeW1ib2xzLkFUVF9WQUxVRSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFRfU1RSSU5HLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBVFRJRFhfVkFMVUUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwpOwotICAgICAgICBhbGxBdHRyc1tBVFRfVkFMVUVfV1NfTl0gICAgICAgID0gICBuZXcgT25lQXR0cihTY2hlbWFTeW1ib2xzLkFUVF9WQUxVRSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFRfV0hJVEVTUEFDRSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVRUSURYX1ZBTFVFLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsKTsKLSAgICAgICAgYWxsQXR0cnNbQVRUX1ZFUlNJT05fTl0gICAgICAgICA9ICAgbmV3IE9uZUF0dHIoU2NoZW1hU3ltYm9scy5BVFRfVkVSU0lPTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFRfVE9LRU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFUVElEWF9WRVJTSU9OLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsKTsKLSAgICAgICAgYWxsQXR0cnNbQVRUX1hNTF9MQU5HXSAgICAgICAgICA9ICAgbmV3IE9uZUF0dHIoU2NoZW1hU3ltYm9scy5BVFRfWE1MX0xBTkcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERUX0xBTkdVQUdFLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBVFRJRFhfWE1MX0xBTkcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwpOwotICAgICAgICBhbGxBdHRyc1tBVFRfWFBBVEhfUl0gICAgICAgICAgID0gICBuZXcgT25lQXR0cihTY2hlbWFTeW1ib2xzLkFUVF9YUEFUSCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFRfWFBBVEgsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFUVElEWF9YUEFUSCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCk7Ci0gICAgICAgIGFsbEF0dHJzW0FUVF9YUEFUSDFfUl0gICAgICAgICAgPSAgIG5ldyBPbmVBdHRyKFNjaGVtYVN5bWJvbHMuQVRUX1hQQVRILAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEVF9YUEFUSDEsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFUVElEWF9YUEFUSCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCk7Ci0KLSAgICAgICAgLy8gc3RlcCA0OiBmb3IgZWFjaCBlbGVtZW50LCBtYWtlIGEgbGlzdCBvZiBwb3NzaWJsZSBhdHRyaWJ1dGVzCi0gICAgICAgIENvbnRhaW5lciBhdHRyTGlzdDsKLQotICAgICAgICAvLyBmb3IgZWxlbWVudCAiYXR0cmlidXRlIiAtIGdsb2JhbAotICAgICAgICBhdHRyTGlzdCA9IENvbnRhaW5lci5nZXRDb250YWluZXIoNSk7Ci0gICAgICAgIC8vIGRlZmF1bHQgPSBzdHJpbmcKLSAgICAgICAgYXR0ckxpc3QucHV0KFNjaGVtYVN5bWJvbHMuQVRUX0RFRkFVTFQsIGFsbEF0dHJzW0FUVF9ERUZBVUxUX05dKTsKLSAgICAgICAgLy8gZml4ZWQgPSBzdHJpbmcKLSAgICAgICAgYXR0ckxpc3QucHV0KFNjaGVtYVN5bWJvbHMuQVRUX0ZJWEVELCBhbGxBdHRyc1tBVFRfRklYRURfTl0pOwotICAgICAgICAvLyBpZCA9IElECi0gICAgICAgIGF0dHJMaXN0LnB1dChTY2hlbWFTeW1ib2xzLkFUVF9JRCwgYWxsQXR0cnNbQVRUX0lEX05dKTsKLSAgICAgICAgLy8gbmFtZSA9IE5DTmFtZQotICAgICAgICBhdHRyTGlzdC5wdXQoU2NoZW1hU3ltYm9scy5BVFRfTkFNRSwgYWxsQXR0cnNbQVRUX05BTUVfUl0pOwotICAgICAgICAvLyB0eXBlID0gUU5hbWUKLSAgICAgICAgYXR0ckxpc3QucHV0KFNjaGVtYVN5bWJvbHMuQVRUX1RZUEUsIGFsbEF0dHJzW0FUVF9UWVBFX05dKTsKLSAgICAgICAgZkVsZUF0dHJzTWFwRy5wdXQoU2NoZW1hU3ltYm9scy5FTFRfQVRUUklCVVRFLCBhdHRyTGlzdCk7Ci0KLSAgICAgICAgLy8gZm9yIGVsZW1lbnQgImF0dHJpYnV0ZSIgLSBsb2NhbCBuYW1lCi0gICAgICAgIGF0dHJMaXN0ID0gQ29udGFpbmVyLmdldENvbnRhaW5lcig3KTsKLSAgICAgICAgLy8gZGVmYXVsdCA9IHN0cmluZwotICAgICAgICBhdHRyTGlzdC5wdXQoU2NoZW1hU3ltYm9scy5BVFRfREVGQVVMVCwgYWxsQXR0cnNbQVRUX0RFRkFVTFRfTl0pOwotICAgICAgICAvLyBmaXhlZCA9IHN0cmluZwotICAgICAgICBhdHRyTGlzdC5wdXQoU2NoZW1hU3ltYm9scy5BVFRfRklYRUQsIGFsbEF0dHJzW0FUVF9GSVhFRF9OXSk7Ci0gICAgICAgIC8vIGZvcm0gPSAocXVhbGlmaWVkIHwgdW5xdWFsaWZpZWQpCi0gICAgICAgIGF0dHJMaXN0LnB1dChTY2hlbWFTeW1ib2xzLkFUVF9GT1JNLCBhbGxBdHRyc1tBVFRfRk9STV9OXSk7Ci0gICAgICAgIC8vIGlkID0gSUQKLSAgICAgICAgYXR0ckxpc3QucHV0KFNjaGVtYVN5bWJvbHMuQVRUX0lELCBhbGxBdHRyc1tBVFRfSURfTl0pOwotICAgICAgICAvLyBuYW1lID0gTkNOYW1lCi0gICAgICAgIGF0dHJMaXN0LnB1dChTY2hlbWFTeW1ib2xzLkFUVF9OQU1FLCBhbGxBdHRyc1tBVFRfTkFNRV9SXSk7Ci0gICAgICAgIC8vIHR5cGUgPSBRTmFtZQotICAgICAgICBhdHRyTGlzdC5wdXQoU2NoZW1hU3ltYm9scy5BVFRfVFlQRSwgYWxsQXR0cnNbQVRUX1RZUEVfTl0pOwotICAgICAgICAvLyB1c2UgPSAob3B0aW9uYWwgfCBwcm9oaWJpdGVkIHwgcmVxdWlyZWQpIDogb3B0aW9uYWwKLSAgICAgICAgYXR0ckxpc3QucHV0KFNjaGVtYVN5bWJvbHMuQVRUX1VTRSwgYWxsQXR0cnNbQVRUX1VTRV9EXSk7Ci0gICAgICAgIGZFbGVBdHRyc01hcEwucHV0KEFUVFJJQlVURV9OLCBhdHRyTGlzdCk7Ci0KLSAgICAgICAgLy8gZm9yIGVsZW1lbnQgImF0dHJpYnV0ZSIgLSBsb2NhbCByZWYKLSAgICAgICAgYXR0ckxpc3QgPSBDb250YWluZXIuZ2V0Q29udGFpbmVyKDUpOwotICAgICAgICAvLyBkZWZhdWx0ID0gc3RyaW5nCi0gICAgICAgIGF0dHJMaXN0LnB1dChTY2hlbWFTeW1ib2xzLkFUVF9ERUZBVUxULCBhbGxBdHRyc1tBVFRfREVGQVVMVF9OXSk7Ci0gICAgICAgIC8vIGZpeGVkID0gc3RyaW5nCi0gICAgICAgIGF0dHJMaXN0LnB1dChTY2hlbWFTeW1ib2xzLkFUVF9GSVhFRCwgYWxsQXR0cnNbQVRUX0ZJWEVEX05dKTsKLSAgICAgICAgLy8gaWQgPSBJRAotICAgICAgICBhdHRyTGlzdC5wdXQoU2NoZW1hU3ltYm9scy5BVFRfSUQsIGFsbEF0dHJzW0FUVF9JRF9OXSk7Ci0gICAgICAgIC8vIHJlZiA9IFFOYW1lCi0gICAgICAgIGF0dHJMaXN0LnB1dChTY2hlbWFTeW1ib2xzLkFUVF9SRUYsIGFsbEF0dHJzW0FUVF9SRUZfUl0pOwotICAgICAgICAvLyB1c2UgPSAob3B0aW9uYWwgfCBwcm9oaWJpdGVkIHwgcmVxdWlyZWQpIDogb3B0aW9uYWwKLSAgICAgICAgYXR0ckxpc3QucHV0KFNjaGVtYVN5bWJvbHMuQVRUX1VTRSwgYWxsQXR0cnNbQVRUX1VTRV9EXSk7Ci0gICAgICAgIGZFbGVBdHRyc01hcEwucHV0KEFUVFJJQlVURV9SLCBhdHRyTGlzdCk7Ci0KLSAgICAgICAgLy8gZm9yIGVsZW1lbnQgImVsZW1lbnQiIC0gZ2xvYmFsCi0gICAgICAgIGF0dHJMaXN0ID0gQ29udGFpbmVyLmdldENvbnRhaW5lcigxMCk7Ci0gICAgICAgIC8vIGFic3RyYWN0ID0gYm9vbGVhbiA6IGZhbHNlCi0gICAgICAgIGF0dHJMaXN0LnB1dChTY2hlbWFTeW1ib2xzLkFUVF9BQlNUUkFDVCwgYWxsQXR0cnNbQVRUX0FCU1RSQUNUX0RdKTsKLSAgICAgICAgLy8gYmxvY2sgPSAoI2FsbCB8IExpc3Qgb2YgKGV4dGVuc2lvbiB8IHJlc3RyaWN0aW9uIHwgc3Vic3RpdHV0aW9uKSkKLSAgICAgICAgYXR0ckxpc3QucHV0KFNjaGVtYVN5bWJvbHMuQVRUX0JMT0NLLCBhbGxBdHRyc1tBVFRfQkxPQ0tfTl0pOwotICAgICAgICAvLyBkZWZhdWx0ID0gc3RyaW5nCi0gICAgICAgIGF0dHJMaXN0LnB1dChTY2hlbWFTeW1ib2xzLkFUVF9ERUZBVUxULCBhbGxBdHRyc1tBVFRfREVGQVVMVF9OXSk7Ci0gICAgICAgIC8vIGZpbmFsID0gKCNhbGwgfCBMaXN0IG9mIChleHRlbnNpb24gfCByZXN0cmljdGlvbikpCi0gICAgICAgIGF0dHJMaXN0LnB1dChTY2hlbWFTeW1ib2xzLkFUVF9GSU5BTCwgYWxsQXR0cnNbQVRUX0ZJTkFMX05dKTsKLSAgICAgICAgLy8gZml4ZWQgPSBzdHJpbmcKLSAgICAgICAgYXR0ckxpc3QucHV0KFNjaGVtYVN5bWJvbHMuQVRUX0ZJWEVELCBhbGxBdHRyc1tBVFRfRklYRURfTl0pOwotICAgICAgICAvLyBpZCA9IElECi0gICAgICAgIGF0dHJMaXN0LnB1dChTY2hlbWFTeW1ib2xzLkFUVF9JRCwgYWxsQXR0cnNbQVRUX0lEX05dKTsKLSAgICAgICAgLy8gbmFtZSA9IE5DTmFtZQotICAgICAgICBhdHRyTGlzdC5wdXQoU2NoZW1hU3ltYm9scy5BVFRfTkFNRSwgYWxsQXR0cnNbQVRUX05BTUVfUl0pOwotICAgICAgICAvLyBuaWxsYWJsZSA9IGJvb2xlYW4gOiBmYWxzZQotICAgICAgICBhdHRyTGlzdC5wdXQoU2NoZW1hU3ltYm9scy5BVFRfTklMTEFCTEUsIGFsbEF0dHJzW0FUVF9OSUxMQUJMRV9EXSk7Ci0gICAgICAgIC8vIHN1YnN0aXR1dGlvbkdyb3VwID0gUU5hbWUKLSAgICAgICAgYXR0ckxpc3QucHV0KFNjaGVtYVN5bWJvbHMuQVRUX1NVQlNUSVRVVElPTkdST1VQLCBhbGxBdHRyc1tBVFRfU1VCU1RJVFVUSU9OX0dfTl0pOwotICAgICAgICAvLyB0eXBlID0gUU5hbWUKLSAgICAgICAgYXR0ckxpc3QucHV0KFNjaGVtYVN5bWJvbHMuQVRUX1RZUEUsIGFsbEF0dHJzW0FUVF9UWVBFX05dKTsKLSAgICAgICAgZkVsZUF0dHJzTWFwRy5wdXQoU2NoZW1hU3ltYm9scy5FTFRfRUxFTUVOVCwgYXR0ckxpc3QpOwotCi0gICAgICAgIC8vIGZvciBlbGVtZW50ICJlbGVtZW50IiAtIGxvY2FsIG5hbWUKLSAgICAgICAgYXR0ckxpc3QgPSBDb250YWluZXIuZ2V0Q29udGFpbmVyKDEwKTsKLSAgICAgICAgLy8gYmxvY2sgPSAoI2FsbCB8IExpc3Qgb2YgKGV4dGVuc2lvbiB8IHJlc3RyaWN0aW9uIHwgc3Vic3RpdHV0aW9uKSkKLSAgICAgICAgYXR0ckxpc3QucHV0KFNjaGVtYVN5bWJvbHMuQVRUX0JMT0NLLCBhbGxBdHRyc1tBVFRfQkxPQ0tfTl0pOwotICAgICAgICAvLyBkZWZhdWx0ID0gc3RyaW5nCi0gICAgICAgIGF0dHJMaXN0LnB1dChTY2hlbWFTeW1ib2xzLkFUVF9ERUZBVUxULCBhbGxBdHRyc1tBVFRfREVGQVVMVF9OXSk7Ci0gICAgICAgIC8vIGZpeGVkID0gc3RyaW5nCi0gICAgICAgIGF0dHJMaXN0LnB1dChTY2hlbWFTeW1ib2xzLkFUVF9GSVhFRCwgYWxsQXR0cnNbQVRUX0ZJWEVEX05dKTsKLSAgICAgICAgLy8gZm9ybSA9IChxdWFsaWZpZWQgfCB1bnF1YWxpZmllZCkKLSAgICAgICAgYXR0ckxpc3QucHV0KFNjaGVtYVN5bWJvbHMuQVRUX0ZPUk0sIGFsbEF0dHJzW0FUVF9GT1JNX05dKTsKLSAgICAgICAgLy8gaWQgPSBJRAotICAgICAgICBhdHRyTGlzdC5wdXQoU2NoZW1hU3ltYm9scy5BVFRfSUQsIGFsbEF0dHJzW0FUVF9JRF9OXSk7Ci0gICAgICAgIC8vIG1heE9jY3VycyA9IChub25OZWdhdGl2ZUludGVnZXIgfCB1bmJvdW5kZWQpICA6IDEKLSAgICAgICAgYXR0ckxpc3QucHV0KFNjaGVtYVN5bWJvbHMuQVRUX01BWE9DQ1VSUywgYWxsQXR0cnNbQVRUX01BWE9DQ1VSU19EXSk7Ci0gICAgICAgIC8vIG1pbk9jY3VycyA9IG5vbk5lZ2F0aXZlSW50ZWdlciA6IDEKLSAgICAgICAgYXR0ckxpc3QucHV0KFNjaGVtYVN5bWJvbHMuQVRUX01JTk9DQ1VSUywgYWxsQXR0cnNbQVRUX01JTk9DQ1VSU19EXSk7Ci0gICAgICAgIC8vIG5hbWUgPSBOQ05hbWUKLSAgICAgICAgYXR0ckxpc3QucHV0KFNjaGVtYVN5bWJvbHMuQVRUX05BTUUsIGFsbEF0dHJzW0FUVF9OQU1FX1JdKTsKLSAgICAgICAgLy8gbmlsbGFibGUgPSBib29sZWFuIDogZmFsc2UKLSAgICAgICAgYXR0ckxpc3QucHV0KFNjaGVtYVN5bWJvbHMuQVRUX05JTExBQkxFLCBhbGxBdHRyc1tBVFRfTklMTEFCTEVfRF0pOwotICAgICAgICAvLyB0eXBlID0gUU5hbWUKLSAgICAgICAgYXR0ckxpc3QucHV0KFNjaGVtYVN5bWJvbHMuQVRUX1RZUEUsIGFsbEF0dHJzW0FUVF9UWVBFX05dKTsKLSAgICAgICAgZkVsZUF0dHJzTWFwTC5wdXQoRUxFTUVOVF9OLCBhdHRyTGlzdCk7Ci0KLSAgICAgICAgLy8gZm9yIGVsZW1lbnQgImVsZW1lbnQiIC0gbG9jYWwgcmVmCi0gICAgICAgIGF0dHJMaXN0ID0gQ29udGFpbmVyLmdldENvbnRhaW5lcig0KTsKLSAgICAgICAgLy8gaWQgPSBJRAotICAgICAgICBhdHRyTGlzdC5wdXQoU2NoZW1hU3ltYm9scy5BVFRfSUQsIGFsbEF0dHJzW0FUVF9JRF9OXSk7Ci0gICAgICAgIC8vIG1heE9jY3VycyA9IChub25OZWdhdGl2ZUludGVnZXIgfCB1bmJvdW5kZWQpICA6IDEKLSAgICAgICAgYXR0ckxpc3QucHV0KFNjaGVtYVN5bWJvbHMuQVRUX01BWE9DQ1VSUywgYWxsQXR0cnNbQVRUX01BWE9DQ1VSU19EXSk7Ci0gICAgICAgIC8vIG1pbk9jY3VycyA9IG5vbk5lZ2F0aXZlSW50ZWdlciA6IDEKLSAgICAgICAgYXR0ckxpc3QucHV0KFNjaGVtYVN5bWJvbHMuQVRUX01JTk9DQ1VSUywgYWxsQXR0cnNbQVRUX01JTk9DQ1VSU19EXSk7Ci0gICAgICAgIC8vIHJlZiA9IFFOYW1lCi0gICAgICAgIGF0dHJMaXN0LnB1dChTY2hlbWFTeW1ib2xzLkFUVF9SRUYsIGFsbEF0dHJzW0FUVF9SRUZfUl0pOwotICAgICAgICBmRWxlQXR0cnNNYXBMLnB1dChFTEVNRU5UX1IsIGF0dHJMaXN0KTsKLQotICAgICAgICAvLyBmb3IgZWxlbWVudCAiY29tcGxleFR5cGUiIC0gZ2xvYmFsCi0gICAgICAgIGF0dHJMaXN0ID0gQ29udGFpbmVyLmdldENvbnRhaW5lcig2KTsKLSAgICAgICAgLy8gYWJzdHJhY3QgPSBib29sZWFuIDogZmFsc2UKLSAgICAgICAgYXR0ckxpc3QucHV0KFNjaGVtYVN5bWJvbHMuQVRUX0FCU1RSQUNULCBhbGxBdHRyc1tBVFRfQUJTVFJBQ1RfRF0pOwotICAgICAgICAvLyBibG9jayA9ICgjYWxsIHwgTGlzdCBvZiAoZXh0ZW5zaW9uIHwgcmVzdHJpY3Rpb24pKQotICAgICAgICBhdHRyTGlzdC5wdXQoU2NoZW1hU3ltYm9scy5BVFRfQkxPQ0ssIGFsbEF0dHJzW0FUVF9CTE9DSzFfTl0pOwotICAgICAgICAvLyBmaW5hbCA9ICgjYWxsIHwgTGlzdCBvZiAoZXh0ZW5zaW9uIHwgcmVzdHJpY3Rpb24pKQotICAgICAgICBhdHRyTGlzdC5wdXQoU2NoZW1hU3ltYm9scy5BVFRfRklOQUwsIGFsbEF0dHJzW0FUVF9GSU5BTF9OXSk7Ci0gICAgICAgIC8vIGlkID0gSUQKLSAgICAgICAgYXR0ckxpc3QucHV0KFNjaGVtYVN5bWJvbHMuQVRUX0lELCBhbGxBdHRyc1tBVFRfSURfTl0pOwotICAgICAgICAvLyBtaXhlZCA9IGJvb2xlYW4gOiBmYWxzZQotICAgICAgICBhdHRyTGlzdC5wdXQoU2NoZW1hU3ltYm9scy5BVFRfTUlYRUQsIGFsbEF0dHJzW0FUVF9NSVhFRF9EXSk7Ci0gICAgICAgIC8vIG5hbWUgPSBOQ05hbWUKLSAgICAgICAgYXR0ckxpc3QucHV0KFNjaGVtYVN5bWJvbHMuQVRUX05BTUUsIGFsbEF0dHJzW0FUVF9OQU1FX1JdKTsKLSAgICAgICAgZkVsZUF0dHJzTWFwRy5wdXQoU2NoZW1hU3ltYm9scy5FTFRfQ09NUExFWFRZUEUsIGF0dHJMaXN0KTsKLQotICAgICAgICAvLyBmb3IgZWxlbWVudCAibm90YXRpb24iIC0gZ2xvYmFsCi0gICAgICAgIGF0dHJMaXN0ID0gQ29udGFpbmVyLmdldENvbnRhaW5lcig0KTsKLSAgICAgICAgLy8gaWQgPSBJRAotICAgICAgICBhdHRyTGlzdC5wdXQoU2NoZW1hU3ltYm9scy5BVFRfSUQsIGFsbEF0dHJzW0FUVF9JRF9OXSk7Ci0gICAgICAgIC8vIG5hbWUgPSBOQ05hbWUKLSAgICAgICAgYXR0ckxpc3QucHV0KFNjaGVtYVN5bWJvbHMuQVRUX05BTUUsIGFsbEF0dHJzW0FUVF9OQU1FX1JdKTsKLSAgICAgICAgLy8gcHVibGljID0gQSBwdWJsaWMgaWRlbnRpZmllciwgcGVyIElTTyA4ODc5Ci0gICAgICAgIGF0dHJMaXN0LnB1dChTY2hlbWFTeW1ib2xzLkFUVF9QVUJMSUMsIGFsbEF0dHJzW0FUVF9QVUJMSUNfUl0pOwotICAgICAgICAvLyBzeXN0ZW0gPSBhbnlVUkkKLSAgICAgICAgYXR0ckxpc3QucHV0KFNjaGVtYVN5bWJvbHMuQVRUX1NZU1RFTSwgYWxsQXR0cnNbQVRUX1NZU1RFTV9OXSk7Ci0gICAgICAgIGZFbGVBdHRyc01hcEcucHV0KFNjaGVtYVN5bWJvbHMuRUxUX05PVEFUSU9OLCBhdHRyTGlzdCk7Ci0KLQotICAgICAgICAvLyBmb3IgZWxlbWVudCAiY29tcGxleFR5cGUiIC0gbG9jYWwKLSAgICAgICAgYXR0ckxpc3QgPSBDb250YWluZXIuZ2V0Q29udGFpbmVyKDIpOwotICAgICAgICAvLyBpZCA9IElECi0gICAgICAgIGF0dHJMaXN0LnB1dChTY2hlbWFTeW1ib2xzLkFUVF9JRCwgYWxsQXR0cnNbQVRUX0lEX05dKTsKLSAgICAgICAgLy8gbWl4ZWQgPSBib29sZWFuIDogZmFsc2UKLSAgICAgICAgYXR0ckxpc3QucHV0KFNjaGVtYVN5bWJvbHMuQVRUX01JWEVELCBhbGxBdHRyc1tBVFRfTUlYRURfRF0pOwotICAgICAgICBmRWxlQXR0cnNNYXBMLnB1dChTY2hlbWFTeW1ib2xzLkVMVF9DT01QTEVYVFlQRSwgYXR0ckxpc3QpOwotCi0gICAgICAgIC8vIGZvciBlbGVtZW50ICJzaW1wbGVDb250ZW50IiAtIGxvY2FsCi0gICAgICAgIGF0dHJMaXN0ID0gQ29udGFpbmVyLmdldENvbnRhaW5lcigxKTsKLSAgICAgICAgLy8gaWQgPSBJRAotICAgICAgICBhdHRyTGlzdC5wdXQoU2NoZW1hU3ltYm9scy5BVFRfSUQsIGFsbEF0dHJzW0FUVF9JRF9OXSk7Ci0gICAgICAgIGZFbGVBdHRyc01hcEwucHV0KFNjaGVtYVN5bWJvbHMuRUxUX1NJTVBMRUNPTlRFTlQsIGF0dHJMaXN0KTsKLQotICAgICAgICAvLyBmb3IgZWxlbWVudCAicmVzdHJpY3Rpb24iIC0gbG9jYWwKLSAgICAgICAgYXR0ckxpc3QgPSBDb250YWluZXIuZ2V0Q29udGFpbmVyKDIpOwotICAgICAgICAvLyBiYXNlID0gUU5hbWUKLSAgICAgICAgYXR0ckxpc3QucHV0KFNjaGVtYVN5bWJvbHMuQVRUX0JBU0UsIGFsbEF0dHJzW0FUVF9CQVNFX05dKTsKLSAgICAgICAgLy8gaWQgPSBJRAotICAgICAgICBhdHRyTGlzdC5wdXQoU2NoZW1hU3ltYm9scy5BVFRfSUQsIGFsbEF0dHJzW0FUVF9JRF9OXSk7Ci0gICAgICAgIGZFbGVBdHRyc01hcEwucHV0KFNjaGVtYVN5bWJvbHMuRUxUX1JFU1RSSUNUSU9OLCBhdHRyTGlzdCk7Ci0KLSAgICAgICAgLy8gZm9yIGVsZW1lbnQgImV4dGVuc2lvbiIgLSBsb2NhbAotICAgICAgICBhdHRyTGlzdCA9IENvbnRhaW5lci5nZXRDb250YWluZXIoMik7Ci0gICAgICAgIC8vIGJhc2UgPSBRTmFtZQotICAgICAgICBhdHRyTGlzdC5wdXQoU2NoZW1hU3ltYm9scy5BVFRfQkFTRSwgYWxsQXR0cnNbQVRUX0JBU0VfUl0pOwotICAgICAgICAvLyBpZCA9IElECi0gICAgICAgIGF0dHJMaXN0LnB1dChTY2hlbWFTeW1ib2xzLkFUVF9JRCwgYWxsQXR0cnNbQVRUX0lEX05dKTsKLSAgICAgICAgZkVsZUF0dHJzTWFwTC5wdXQoU2NoZW1hU3ltYm9scy5FTFRfRVhURU5TSU9OLCBhdHRyTGlzdCk7Ci0KLSAgICAgICAgLy8gZm9yIGVsZW1lbnQgImF0dHJpYnV0ZUdyb3VwIiAtIGxvY2FsIHJlZgotICAgICAgICBhdHRyTGlzdCA9IENvbnRhaW5lci5nZXRDb250YWluZXIoMik7Ci0gICAgICAgIC8vIGlkID0gSUQKLSAgICAgICAgYXR0ckxpc3QucHV0KFNjaGVtYVN5bWJvbHMuQVRUX0lELCBhbGxBdHRyc1tBVFRfSURfTl0pOwotICAgICAgICAvLyByZWYgPSBRTmFtZQotICAgICAgICBhdHRyTGlzdC5wdXQoU2NoZW1hU3ltYm9scy5BVFRfUkVGLCBhbGxBdHRyc1tBVFRfUkVGX1JdKTsKLSAgICAgICAgZkVsZUF0dHJzTWFwTC5wdXQoU2NoZW1hU3ltYm9scy5FTFRfQVRUUklCVVRFR1JPVVAsIGF0dHJMaXN0KTsKLQotICAgICAgICAvLyBmb3IgZWxlbWVudCAiYW55QXR0cmlidXRlIiAtIGxvY2FsCi0gICAgICAgIGF0dHJMaXN0ID0gQ29udGFpbmVyLmdldENvbnRhaW5lcigzKTsKLSAgICAgICAgLy8gaWQgPSBJRAotICAgICAgICBhdHRyTGlzdC5wdXQoU2NoZW1hU3ltYm9scy5BVFRfSUQsIGFsbEF0dHJzW0FUVF9JRF9OXSk7Ci0gICAgICAgIC8vIG5hbWVzcGFjZSA9ICgoIyNhbnkgfCAjI290aGVyKSB8IExpc3Qgb2YgKGFueVVSSSB8ICgjI3RhcmdldE5hbWVzcGFjZSB8ICMjbG9jYWwpKSApICA6ICMjYW55Ci0gICAgICAgIGF0dHJMaXN0LnB1dChTY2hlbWFTeW1ib2xzLkFUVF9OQU1FU1BBQ0UsIGFsbEF0dHJzW0FUVF9OQU1FU1BBQ0VfRF0pOwotICAgICAgICAvLyBwcm9jZXNzQ29udGVudHMgPSAobGF4IHwgc2tpcCB8IHN0cmljdCkgOiBzdHJpY3QKLSAgICAgICAgYXR0ckxpc3QucHV0KFNjaGVtYVN5bWJvbHMuQVRUX1BST0NFU1NDT05URU5UUywgYWxsQXR0cnNbQVRUX1BST0NFU1NfQ19EXSk7Ci0gICAgICAgIGZFbGVBdHRyc01hcEwucHV0KFNjaGVtYVN5bWJvbHMuRUxUX0FOWUFUVFJJQlVURSwgYXR0ckxpc3QpOwotCi0gICAgICAgIC8vIGZvciBlbGVtZW50ICJjb21wbGV4Q29udGVudCIgLSBsb2NhbAotICAgICAgICBhdHRyTGlzdCA9IENvbnRhaW5lci5nZXRDb250YWluZXIoMik7Ci0gICAgICAgIC8vIGlkID0gSUQKLSAgICAgICAgYXR0ckxpc3QucHV0KFNjaGVtYVN5bWJvbHMuQVRUX0lELCBhbGxBdHRyc1tBVFRfSURfTl0pOwotICAgICAgICAvLyBtaXhlZCA9IGJvb2xlYW4KLSAgICAgICAgYXR0ckxpc3QucHV0KFNjaGVtYVN5bWJvbHMuQVRUX01JWEVELCBhbGxBdHRyc1tBVFRfTUlYRURfTl0pOwotICAgICAgICBmRWxlQXR0cnNNYXBMLnB1dChTY2hlbWFTeW1ib2xzLkVMVF9DT01QTEVYQ09OVEVOVCwgYXR0ckxpc3QpOwotCi0gICAgICAgIC8vIGZvciBlbGVtZW50ICJhdHRyaWJ1dGVHcm91cCIgLSBnbG9iYWwKLSAgICAgICAgYXR0ckxpc3QgPSBDb250YWluZXIuZ2V0Q29udGFpbmVyKDIpOwotICAgICAgICAvLyBpZCA9IElECi0gICAgICAgIGF0dHJMaXN0LnB1dChTY2hlbWFTeW1ib2xzLkFUVF9JRCwgYWxsQXR0cnNbQVRUX0lEX05dKTsKLSAgICAgICAgLy8gbmFtZSA9IE5DTmFtZQotICAgICAgICBhdHRyTGlzdC5wdXQoU2NoZW1hU3ltYm9scy5BVFRfTkFNRSwgYWxsQXR0cnNbQVRUX05BTUVfUl0pOwotICAgICAgICBmRWxlQXR0cnNNYXBHLnB1dChTY2hlbWFTeW1ib2xzLkVMVF9BVFRSSUJVVEVHUk9VUCwgYXR0ckxpc3QpOwotCi0gICAgICAgIC8vIGZvciBlbGVtZW50ICJncm91cCIgLSBnbG9iYWwKLSAgICAgICAgYXR0ckxpc3QgPSBDb250YWluZXIuZ2V0Q29udGFpbmVyKDIpOwotICAgICAgICAvLyBpZCA9IElECi0gICAgICAgIGF0dHJMaXN0LnB1dChTY2hlbWFTeW1ib2xzLkFUVF9JRCwgYWxsQXR0cnNbQVRUX0lEX05dKTsKLSAgICAgICAgLy8gbmFtZSA9IE5DTmFtZQotICAgICAgICBhdHRyTGlzdC5wdXQoU2NoZW1hU3ltYm9scy5BVFRfTkFNRSwgYWxsQXR0cnNbQVRUX05BTUVfUl0pOwotICAgICAgICBmRWxlQXR0cnNNYXBHLnB1dChTY2hlbWFTeW1ib2xzLkVMVF9HUk9VUCwgYXR0ckxpc3QpOwotCi0gICAgICAgIC8vIGZvciBlbGVtZW50ICJncm91cCIgLSBsb2NhbCByZWYKLSAgICAgICAgYXR0ckxpc3QgPSBDb250YWluZXIuZ2V0Q29udGFpbmVyKDQpOwotICAgICAgICAvLyBpZCA9IElECi0gICAgICAgIGF0dHJMaXN0LnB1dChTY2hlbWFTeW1ib2xzLkFUVF9JRCwgYWxsQXR0cnNbQVRUX0lEX05dKTsKLSAgICAgICAgLy8gbWF4T2NjdXJzID0gKG5vbk5lZ2F0aXZlSW50ZWdlciB8IHVuYm91bmRlZCkgIDogMQotICAgICAgICBhdHRyTGlzdC5wdXQoU2NoZW1hU3ltYm9scy5BVFRfTUFYT0NDVVJTLCBhbGxBdHRyc1tBVFRfTUFYT0NDVVJTX0RdKTsKLSAgICAgICAgLy8gbWluT2NjdXJzID0gbm9uTmVnYXRpdmVJbnRlZ2VyIDogMQotICAgICAgICBhdHRyTGlzdC5wdXQoU2NoZW1hU3ltYm9scy5BVFRfTUlOT0NDVVJTLCBhbGxBdHRyc1tBVFRfTUlOT0NDVVJTX0RdKTsKLSAgICAgICAgLy8gcmVmID0gUU5hbWUKLSAgICAgICAgYXR0ckxpc3QucHV0KFNjaGVtYVN5bWJvbHMuQVRUX1JFRiwgYWxsQXR0cnNbQVRUX1JFRl9SXSk7Ci0gICAgICAgIGZFbGVBdHRyc01hcEwucHV0KFNjaGVtYVN5bWJvbHMuRUxUX0dST1VQLCBhdHRyTGlzdCk7Ci0KLSAgICAgICAgLy8gZm9yIGVsZW1lbnQgImFsbCIgLSBsb2NhbAotICAgICAgICBhdHRyTGlzdCA9IENvbnRhaW5lci5nZXRDb250YWluZXIoMyk7Ci0gICAgICAgIC8vIGlkID0gSUQKLSAgICAgICAgYXR0ckxpc3QucHV0KFNjaGVtYVN5bWJvbHMuQVRUX0lELCBhbGxBdHRyc1tBVFRfSURfTl0pOwotICAgICAgICAvLyBtYXhPY2N1cnMgPSAxIDogMQotICAgICAgICBhdHRyTGlzdC5wdXQoU2NoZW1hU3ltYm9scy5BVFRfTUFYT0NDVVJTLCBhbGxBdHRyc1tBVFRfTUFYT0NDVVJTMV9EXSk7Ci0gICAgICAgIC8vIG1pbk9jY3VycyA9ICgwIHwgMSkgOiAxCi0gICAgICAgIGF0dHJMaXN0LnB1dChTY2hlbWFTeW1ib2xzLkFUVF9NSU5PQ0NVUlMsIGFsbEF0dHJzW0FUVF9NSU5PQ0NVUlMxX0RdKTsKLSAgICAgICAgZkVsZUF0dHJzTWFwTC5wdXQoU2NoZW1hU3ltYm9scy5FTFRfQUxMLCBhdHRyTGlzdCk7Ci0KLSAgICAgICAgLy8gZm9yIGVsZW1lbnQgImNob2ljZSIgLSBsb2NhbAotICAgICAgICBhdHRyTGlzdCA9IENvbnRhaW5lci5nZXRDb250YWluZXIoMyk7Ci0gICAgICAgIC8vIGlkID0gSUQKLSAgICAgICAgYXR0ckxpc3QucHV0KFNjaGVtYVN5bWJvbHMuQVRUX0lELCBhbGxBdHRyc1tBVFRfSURfTl0pOwotICAgICAgICAvLyBtYXhPY2N1cnMgPSAobm9uTmVnYXRpdmVJbnRlZ2VyIHwgdW5ib3VuZGVkKSAgOiAxCi0gICAgICAgIGF0dHJMaXN0LnB1dChTY2hlbWFTeW1ib2xzLkFUVF9NQVhPQ0NVUlMsIGFsbEF0dHJzW0FUVF9NQVhPQ0NVUlNfRF0pOwotICAgICAgICAvLyBtaW5PY2N1cnMgPSBub25OZWdhdGl2ZUludGVnZXIgOiAxCi0gICAgICAgIGF0dHJMaXN0LnB1dChTY2hlbWFTeW1ib2xzLkFUVF9NSU5PQ0NVUlMsIGFsbEF0dHJzW0FUVF9NSU5PQ0NVUlNfRF0pOwotICAgICAgICBmRWxlQXR0cnNNYXBMLnB1dChTY2hlbWFTeW1ib2xzLkVMVF9DSE9JQ0UsIGF0dHJMaXN0KTsKLSAgICAgICAgLy8gZm9yIGVsZW1lbnQgInNlcXVlbmNlIiAtIGxvY2FsCi0gICAgICAgIGZFbGVBdHRyc01hcEwucHV0KFNjaGVtYVN5bWJvbHMuRUxUX1NFUVVFTkNFLCBhdHRyTGlzdCk7Ci0KLSAgICAgICAgLy8gZm9yIGVsZW1lbnQgImFueSIgLSBsb2NhbAotICAgICAgICBhdHRyTGlzdCA9IENvbnRhaW5lci5nZXRDb250YWluZXIoNSk7Ci0gICAgICAgIC8vIGlkID0gSUQKLSAgICAgICAgYXR0ckxpc3QucHV0KFNjaGVtYVN5bWJvbHMuQVRUX0lELCBhbGxBdHRyc1tBVFRfSURfTl0pOwotICAgICAgICAvLyBtYXhPY2N1cnMgPSAobm9uTmVnYXRpdmVJbnRlZ2VyIHwgdW5ib3VuZGVkKSAgOiAxCi0gICAgICAgIGF0dHJMaXN0LnB1dChTY2hlbWFTeW1ib2xzLkFUVF9NQVhPQ0NVUlMsIGFsbEF0dHJzW0FUVF9NQVhPQ0NVUlNfRF0pOwotICAgICAgICAvLyBtaW5PY2N1cnMgPSBub25OZWdhdGl2ZUludGVnZXIgOiAxCi0gICAgICAgIGF0dHJMaXN0LnB1dChTY2hlbWFTeW1ib2xzLkFUVF9NSU5PQ0NVUlMsIGFsbEF0dHJzW0FUVF9NSU5PQ0NVUlNfRF0pOwotICAgICAgICAvLyBuYW1lc3BhY2UgPSAoKCMjYW55IHwgIyNvdGhlcikgfCBMaXN0IG9mIChhbnlVUkkgfCAoIyN0YXJnZXROYW1lc3BhY2UgfCAjI2xvY2FsKSkgKSAgOiAjI2FueQotICAgICAgICBhdHRyTGlzdC5wdXQoU2NoZW1hU3ltYm9scy5BVFRfTkFNRVNQQUNFLCBhbGxBdHRyc1tBVFRfTkFNRVNQQUNFX0RdKTsKLSAgICAgICAgLy8gcHJvY2Vzc0NvbnRlbnRzID0gKGxheCB8IHNraXAgfCBzdHJpY3QpIDogc3RyaWN0Ci0gICAgICAgIGF0dHJMaXN0LnB1dChTY2hlbWFTeW1ib2xzLkFUVF9QUk9DRVNTQ09OVEVOVFMsIGFsbEF0dHJzW0FUVF9QUk9DRVNTX0NfRF0pOwotICAgICAgICBmRWxlQXR0cnNNYXBMLnB1dChTY2hlbWFTeW1ib2xzLkVMVF9BTlksIGF0dHJMaXN0KTsKLQotICAgICAgICAvLyBmb3IgZWxlbWVudCAidW5pcXVlIiAtIGxvY2FsCi0gICAgICAgIGF0dHJMaXN0ID0gQ29udGFpbmVyLmdldENvbnRhaW5lcigyKTsKLSAgICAgICAgLy8gaWQgPSBJRAotICAgICAgICBhdHRyTGlzdC5wdXQoU2NoZW1hU3ltYm9scy5BVFRfSUQsIGFsbEF0dHJzW0FUVF9JRF9OXSk7Ci0gICAgICAgIC8vIG5hbWUgPSBOQ05hbWUKLSAgICAgICAgYXR0ckxpc3QucHV0KFNjaGVtYVN5bWJvbHMuQVRUX05BTUUsIGFsbEF0dHJzW0FUVF9OQU1FX1JdKTsKLSAgICAgICAgZkVsZUF0dHJzTWFwTC5wdXQoU2NoZW1hU3ltYm9scy5FTFRfVU5JUVVFLCBhdHRyTGlzdCk7Ci0gICAgICAgIC8vIGZvciBlbGVtZW50ICJrZXkiIC0gbG9jYWwKLSAgICAgICAgZkVsZUF0dHJzTWFwTC5wdXQoU2NoZW1hU3ltYm9scy5FTFRfS0VZLCBhdHRyTGlzdCk7Ci0KLSAgICAgICAgLy8gZm9yIGVsZW1lbnQgImtleXJlZiIgLSBsb2NhbAotICAgICAgICBhdHRyTGlzdCA9IENvbnRhaW5lci5nZXRDb250YWluZXIoMyk7Ci0gICAgICAgIC8vIGlkID0gSUQKLSAgICAgICAgYXR0ckxpc3QucHV0KFNjaGVtYVN5bWJvbHMuQVRUX0lELCBhbGxBdHRyc1tBVFRfSURfTl0pOwotICAgICAgICAvLyBuYW1lID0gTkNOYW1lCi0gICAgICAgIGF0dHJMaXN0LnB1dChTY2hlbWFTeW1ib2xzLkFUVF9OQU1FLCBhbGxBdHRyc1tBVFRfTkFNRV9SXSk7Ci0gICAgICAgIC8vIHJlZmVyID0gUU5hbWUKLSAgICAgICAgYXR0ckxpc3QucHV0KFNjaGVtYVN5bWJvbHMuQVRUX1JFRkVSLCBhbGxBdHRyc1tBVFRfUkVGRVJfUl0pOwotICAgICAgICBmRWxlQXR0cnNNYXBMLnB1dChTY2hlbWFTeW1ib2xzLkVMVF9LRVlSRUYsIGF0dHJMaXN0KTsKLQotICAgICAgICAvLyBmb3IgZWxlbWVudCAic2VsZWN0b3IiIC0gbG9jYWwKLSAgICAgICAgYXR0ckxpc3QgPSBDb250YWluZXIuZ2V0Q29udGFpbmVyKDIpOwotICAgICAgICAvLyBpZCA9IElECi0gICAgICAgIGF0dHJMaXN0LnB1dChTY2hlbWFTeW1ib2xzLkFUVF9JRCwgYWxsQXR0cnNbQVRUX0lEX05dKTsKLSAgICAgICAgLy8geHBhdGggPSBhIHN1YnNldCBvZiBYUGF0aCBleHByZXNzaW9uCi0gICAgICAgIGF0dHJMaXN0LnB1dChTY2hlbWFTeW1ib2xzLkFUVF9YUEFUSCwgYWxsQXR0cnNbQVRUX1hQQVRIX1JdKTsKLSAgICAgICAgZkVsZUF0dHJzTWFwTC5wdXQoU2NoZW1hU3ltYm9scy5FTFRfU0VMRUNUT1IsIGF0dHJMaXN0KTsKLQotICAgICAgICAvLyBmb3IgZWxlbWVudCAiZmllbGQiIC0gbG9jYWwKLSAgICAgICAgYXR0ckxpc3QgPSBDb250YWluZXIuZ2V0Q29udGFpbmVyKDIpOwotICAgICAgICAvLyBpZCA9IElECi0gICAgICAgIGF0dHJMaXN0LnB1dChTY2hlbWFTeW1ib2xzLkFUVF9JRCwgYWxsQXR0cnNbQVRUX0lEX05dKTsKLSAgICAgICAgLy8geHBhdGggPSBhIHN1YnNldCBvZiBYUGF0aCBleHByZXNzaW9uCi0gICAgICAgIGF0dHJMaXN0LnB1dChTY2hlbWFTeW1ib2xzLkFUVF9YUEFUSCwgYWxsQXR0cnNbQVRUX1hQQVRIMV9SXSk7Ci0gICAgICAgIGZFbGVBdHRyc01hcEwucHV0KFNjaGVtYVN5bWJvbHMuRUxUX0ZJRUxELCBhdHRyTGlzdCk7Ci0KLSAgICAgICAgLy8gZm9yIGVsZW1lbnQgImFubm90YXRpb24iIC0gZ2xvYmFsCi0gICAgICAgIGF0dHJMaXN0ID0gQ29udGFpbmVyLmdldENvbnRhaW5lcigxKTsKLSAgICAgICAgLy8gaWQgPSBJRAotICAgICAgICBhdHRyTGlzdC5wdXQoU2NoZW1hU3ltYm9scy5BVFRfSUQsIGFsbEF0dHJzW0FUVF9JRF9OXSk7Ci0gICAgICAgIGZFbGVBdHRyc01hcEcucHV0KFNjaGVtYVN5bWJvbHMuRUxUX0FOTk9UQVRJT04sIGF0dHJMaXN0KTsKLSAgICAgICAgLy8gZm9yIGVsZW1lbnQgImFubm90YXRpb24iIC0gbG9jYWwKLSAgICAgICAgZkVsZUF0dHJzTWFwTC5wdXQoU2NoZW1hU3ltYm9scy5FTFRfQU5OT1RBVElPTiwgYXR0ckxpc3QpOwotCi0gICAgICAgIC8vIGZvciBlbGVtZW50ICJhcHBpbmZvIiAtIGxvY2FsCi0gICAgICAgIGF0dHJMaXN0ID0gQ29udGFpbmVyLmdldENvbnRhaW5lcigxKTsKLSAgICAgICAgLy8gc291cmNlID0gYW55VVJJCi0gICAgICAgIGF0dHJMaXN0LnB1dChTY2hlbWFTeW1ib2xzLkFUVF9TT1VSQ0UsIGFsbEF0dHJzW0FUVF9TT1VSQ0VfTl0pOwotICAgICAgICBmRWxlQXR0cnNNYXBHLnB1dChTY2hlbWFTeW1ib2xzLkVMVF9BUFBJTkZPLCBhdHRyTGlzdCk7Ci0gICAgICAgIGZFbGVBdHRyc01hcEwucHV0KFNjaGVtYVN5bWJvbHMuRUxUX0FQUElORk8sIGF0dHJMaXN0KTsKLQotICAgICAgICAvLyBmb3IgZWxlbWVudCAiZG9jdW1lbnRhdGlvbiIgLSBsb2NhbAotICAgICAgICBhdHRyTGlzdCA9IENvbnRhaW5lci5nZXRDb250YWluZXIoMik7Ci0gICAgICAgIC8vIHNvdXJjZSA9IGFueVVSSQotICAgICAgICBhdHRyTGlzdC5wdXQoU2NoZW1hU3ltYm9scy5BVFRfU09VUkNFLCBhbGxBdHRyc1tBVFRfU09VUkNFX05dKTsKLSAgICAgICAgLy8geG1sOmxhbmcgPSBsYW5ndWFnZQotICAgICAgICBhdHRyTGlzdC5wdXQoU2NoZW1hU3ltYm9scy5BVFRfWE1MX0xBTkcsIGFsbEF0dHJzW0FUVF9YTUxfTEFOR10pOwotICAgICAgICBmRWxlQXR0cnNNYXBHLnB1dChTY2hlbWFTeW1ib2xzLkVMVF9ET0NVTUVOVEFUSU9OLCBhdHRyTGlzdCk7Ci0gICAgICAgIGZFbGVBdHRyc01hcEwucHV0KFNjaGVtYVN5bWJvbHMuRUxUX0RPQ1VNRU5UQVRJT04sIGF0dHJMaXN0KTsKLQotICAgICAgICAvLyBmb3IgZWxlbWVudCAic2ltcGxlVHlwZSIgLSBnbG9iYWwKLSAgICAgICAgYXR0ckxpc3QgPSBDb250YWluZXIuZ2V0Q29udGFpbmVyKDMpOwotICAgICAgICAvLyBmaW5hbCA9ICgjYWxsIHwgTGlzdCBvZiAobGlzdCB8IHVuaW9uIHwgcmVzdHJpY3Rpb24pKQotICAgICAgICBhdHRyTGlzdC5wdXQoU2NoZW1hU3ltYm9scy5BVFRfRklOQUwsIGFsbEF0dHJzW0FUVF9GSU5BTDFfTl0pOwotICAgICAgICAvLyBpZCA9IElECi0gICAgICAgIGF0dHJMaXN0LnB1dChTY2hlbWFTeW1ib2xzLkFUVF9JRCwgYWxsQXR0cnNbQVRUX0lEX05dKTsKLSAgICAgICAgLy8gbmFtZSA9IE5DTmFtZQotICAgICAgICBhdHRyTGlzdC5wdXQoU2NoZW1hU3ltYm9scy5BVFRfTkFNRSwgYWxsQXR0cnNbQVRUX05BTUVfUl0pOwotICAgICAgICBmRWxlQXR0cnNNYXBHLnB1dChTY2hlbWFTeW1ib2xzLkVMVF9TSU1QTEVUWVBFLCBhdHRyTGlzdCk7Ci0KLSAgICAgICAgLy8gZm9yIGVsZW1lbnQgInNpbXBsZVR5cGUiIC0gbG9jYWwKLSAgICAgICAgYXR0ckxpc3QgPSBDb250YWluZXIuZ2V0Q29udGFpbmVyKDIpOwotICAgICAgICAvLyBmaW5hbCA9ICgjYWxsIHwgTGlzdCBvZiAobGlzdCB8IHVuaW9uIHwgcmVzdHJpY3Rpb24pKQotICAgICAgICBhdHRyTGlzdC5wdXQoU2NoZW1hU3ltYm9scy5BVFRfRklOQUwsIGFsbEF0dHJzW0FUVF9GSU5BTDFfTl0pOwotICAgICAgICAvLyBpZCA9IElECi0gICAgICAgIGF0dHJMaXN0LnB1dChTY2hlbWFTeW1ib2xzLkFUVF9JRCwgYWxsQXR0cnNbQVRUX0lEX05dKTsKLSAgICAgICAgZkVsZUF0dHJzTWFwTC5wdXQoU2NoZW1hU3ltYm9scy5FTFRfU0lNUExFVFlQRSwgYXR0ckxpc3QpOwotCi0gICAgICAgIC8vIGZvciBlbGVtZW50ICJyZXN0cmljdGlvbiIgLSBsb2NhbAotICAgICAgICAvLyBhbHJlYWR5IHJlZ2lzdGVyZWQgZm9yIGNvbXBsZXhUeXBlCi0KLSAgICAgICAgLy8gZm9yIGVsZW1lbnQgImxpc3QiIC0gbG9jYWwKLSAgICAgICAgYXR0ckxpc3QgPSBDb250YWluZXIuZ2V0Q29udGFpbmVyKDIpOwotICAgICAgICAvLyBpZCA9IElECi0gICAgICAgIGF0dHJMaXN0LnB1dChTY2hlbWFTeW1ib2xzLkFUVF9JRCwgYWxsQXR0cnNbQVRUX0lEX05dKTsKLSAgICAgICAgLy8gaXRlbVR5cGUgPSBRTmFtZQotICAgICAgICBhdHRyTGlzdC5wdXQoU2NoZW1hU3ltYm9scy5BVFRfSVRFTVRZUEUsIGFsbEF0dHJzW0FUVF9JVEVNVFlQRV9OXSk7Ci0gICAgICAgIGZFbGVBdHRyc01hcEwucHV0KFNjaGVtYVN5bWJvbHMuRUxUX0xJU1QsIGF0dHJMaXN0KTsKLQotICAgICAgICAvLyBmb3IgZWxlbWVudCAidW5pb24iIC0gbG9jYWwKLSAgICAgICAgYXR0ckxpc3QgPSBDb250YWluZXIuZ2V0Q29udGFpbmVyKDIpOwotICAgICAgICAvLyBpZCA9IElECi0gICAgICAgIGF0dHJMaXN0LnB1dChTY2hlbWFTeW1ib2xzLkFUVF9JRCwgYWxsQXR0cnNbQVRUX0lEX05dKTsKLSAgICAgICAgLy8gbWVtYmVyVHlwZXMgPSBMaXN0IG9mIFFOYW1lCi0gICAgICAgIGF0dHJMaXN0LnB1dChTY2hlbWFTeW1ib2xzLkFUVF9NRU1CRVJUWVBFUywgYWxsQXR0cnNbQVRUX01FTUJFUl9UX05dKTsKLSAgICAgICAgZkVsZUF0dHJzTWFwTC5wdXQoU2NoZW1hU3ltYm9scy5FTFRfVU5JT04sIGF0dHJMaXN0KTsKLQotICAgICAgICAvLyBmb3IgZWxlbWVudCAic2NoZW1hIiAtIGdsb2JhbAotICAgICAgICBhdHRyTGlzdCA9IENvbnRhaW5lci5nZXRDb250YWluZXIoOCk7Ci0gICAgICAgIC8vIGF0dHJpYnV0ZUZvcm1EZWZhdWx0ID0gKHF1YWxpZmllZCB8IHVucXVhbGlmaWVkKSA6IHVucXVhbGlmaWVkCi0gICAgICAgIGF0dHJMaXN0LnB1dChTY2hlbWFTeW1ib2xzLkFUVF9BVFRSSUJVVEVGT1JNREVGQVVMVCwgYWxsQXR0cnNbQVRUX0FUVFJJQlVURV9GRF9EXSk7Ci0gICAgICAgIC8vIGJsb2NrRGVmYXVsdCA9ICgjYWxsIHwgTGlzdCBvZiAoZXh0ZW5zaW9uIHwgcmVzdHJpY3Rpb24gfCBzdWJzdGl0dXRpb24pKSAgOiAnJwotICAgICAgICBhdHRyTGlzdC5wdXQoU2NoZW1hU3ltYm9scy5BVFRfQkxPQ0tERUZBVUxULCBhbGxBdHRyc1tBVFRfQkxPQ0tfRF9EXSk7Ci0gICAgICAgIC8vIGVsZW1lbnRGb3JtRGVmYXVsdCA9IChxdWFsaWZpZWQgfCB1bnF1YWxpZmllZCkgOiB1bnF1YWxpZmllZAotICAgICAgICBhdHRyTGlzdC5wdXQoU2NoZW1hU3ltYm9scy5BVFRfRUxFTUVOVEZPUk1ERUZBVUxULCBhbGxBdHRyc1tBVFRfRUxFTUVOVF9GRF9EXSk7Ci0gICAgICAgIC8vIGZpbmFsRGVmYXVsdCA9ICgjYWxsIHwgTGlzdCBvZiAoZXh0ZW5zaW9uIHwgcmVzdHJpY3Rpb24gfCBsaXN0IHwgdW5pb24pKSAgOiAnJwotICAgICAgICBhdHRyTGlzdC5wdXQoU2NoZW1hU3ltYm9scy5BVFRfRklOQUxERUZBVUxULCBhbGxBdHRyc1tBVFRfRklOQUxfRF9EXSk7Ci0gICAgICAgIC8vIGlkID0gSUQKLSAgICAgICAgYXR0ckxpc3QucHV0KFNjaGVtYVN5bWJvbHMuQVRUX0lELCBhbGxBdHRyc1tBVFRfSURfTl0pOwotICAgICAgICAvLyB0YXJnZXROYW1lc3BhY2UgPSBhbnlVUkkKLSAgICAgICAgYXR0ckxpc3QucHV0KFNjaGVtYVN5bWJvbHMuQVRUX1RBUkdFVE5BTUVTUEFDRSwgYWxsQXR0cnNbQVRUX1RBUkdFVF9OX05dKTsKLSAgICAgICAgLy8gdmVyc2lvbiA9IHRva2VuCi0gICAgICAgIGF0dHJMaXN0LnB1dChTY2hlbWFTeW1ib2xzLkFUVF9WRVJTSU9OLCBhbGxBdHRyc1tBVFRfVkVSU0lPTl9OXSk7Ci0gICAgICAgIC8vIHhtbDpsYW5nID0gbGFuZ3VhZ2UKLSAgICAgICAgYXR0ckxpc3QucHV0KFNjaGVtYVN5bWJvbHMuQVRUX1hNTF9MQU5HLCBhbGxBdHRyc1tBVFRfWE1MX0xBTkddKTsKLSAgICAgICAgZkVsZUF0dHJzTWFwRy5wdXQoU2NoZW1hU3ltYm9scy5FTFRfU0NIRU1BLCBhdHRyTGlzdCk7Ci0KLSAgICAgICAgLy8gZm9yIGVsZW1lbnQgImluY2x1ZGUiIC0gZ2xvYmFsCi0gICAgICAgIGF0dHJMaXN0ID0gQ29udGFpbmVyLmdldENvbnRhaW5lcigyKTsKLSAgICAgICAgLy8gaWQgPSBJRAotICAgICAgICBhdHRyTGlzdC5wdXQoU2NoZW1hU3ltYm9scy5BVFRfSUQsIGFsbEF0dHJzW0FUVF9JRF9OXSk7Ci0gICAgICAgIC8vIHNjaGVtYUxvY2F0aW9uID0gYW55VVJJCi0gICAgICAgIGF0dHJMaXN0LnB1dChTY2hlbWFTeW1ib2xzLkFUVF9TQ0hFTUFMT0NBVElPTiwgYWxsQXR0cnNbQVRUX1NDSEVNQV9MX1JdKTsKLSAgICAgICAgZkVsZUF0dHJzTWFwRy5wdXQoU2NoZW1hU3ltYm9scy5FTFRfSU5DTFVERSwgYXR0ckxpc3QpOwotICAgICAgICAvLyBmb3IgZWxlbWVudCAicmVkZWZpbmUiIC0gZ2xvYmFsCi0gICAgICAgIGZFbGVBdHRyc01hcEcucHV0KFNjaGVtYVN5bWJvbHMuRUxUX1JFREVGSU5FLCBhdHRyTGlzdCk7Ci0KLSAgICAgICAgLy8gZm9yIGVsZW1lbnQgImltcG9ydCIgLSBnbG9iYWwKLSAgICAgICAgYXR0ckxpc3QgPSBDb250YWluZXIuZ2V0Q29udGFpbmVyKDMpOwotICAgICAgICAvLyBpZCA9IElECi0gICAgICAgIGF0dHJMaXN0LnB1dChTY2hlbWFTeW1ib2xzLkFUVF9JRCwgYWxsQXR0cnNbQVRUX0lEX05dKTsKLSAgICAgICAgLy8gbmFtZXNwYWNlID0gYW55VVJJCi0gICAgICAgIGF0dHJMaXN0LnB1dChTY2hlbWFTeW1ib2xzLkFUVF9OQU1FU1BBQ0UsIGFsbEF0dHJzW0FUVF9OQU1FU1BBQ0VfTl0pOwotICAgICAgICAvLyBzY2hlbWFMb2NhdGlvbiA9IGFueVVSSQotICAgICAgICBhdHRyTGlzdC5wdXQoU2NoZW1hU3ltYm9scy5BVFRfU0NIRU1BTE9DQVRJT04sIGFsbEF0dHJzW0FUVF9TQ0hFTUFfTF9OXSk7Ci0gICAgICAgIGZFbGVBdHRyc01hcEcucHV0KFNjaGVtYVN5bWJvbHMuRUxUX0lNUE9SVCwgYXR0ckxpc3QpOwotCi0gICAgICAgIC8vIGZvciBlbGVtZW50ICJsZW5ndGgiIC0gbG9jYWwKLSAgICAgICAgYXR0ckxpc3QgPSBDb250YWluZXIuZ2V0Q29udGFpbmVyKDMpOwotICAgICAgICAvLyBpZCA9IElECi0gICAgICAgIGF0dHJMaXN0LnB1dChTY2hlbWFTeW1ib2xzLkFUVF9JRCwgYWxsQXR0cnNbQVRUX0lEX05dKTsKLSAgICAgICAgLy8gdmFsdWUgPSBub25OZWdhdGl2ZUludGVnZXIKLSAgICAgICAgYXR0ckxpc3QucHV0KFNjaGVtYVN5bWJvbHMuQVRUX1ZBTFVFLCBhbGxBdHRyc1tBVFRfVkFMVUVfTk5JX05dKTsKLSAgICAgICAgLy8gZml4ZWQgPSBib29sZWFuIDogZmFsc2UKLSAgICAgICAgYXR0ckxpc3QucHV0KFNjaGVtYVN5bWJvbHMuQVRUX0ZJWEVELCBhbGxBdHRyc1tBVFRfRklYRURfRF0pOwotICAgICAgICBmRWxlQXR0cnNNYXBMLnB1dChTY2hlbWFTeW1ib2xzLkVMVF9MRU5HVEgsIGF0dHJMaXN0KTsKLSAgICAgICAgLy8gZm9yIGVsZW1lbnQgIm1pbkxlbmd0aCIgLSBsb2NhbAotICAgICAgICBmRWxlQXR0cnNNYXBMLnB1dChTY2hlbWFTeW1ib2xzLkVMVF9NSU5MRU5HVEgsIGF0dHJMaXN0KTsKLSAgICAgICAgLy8gZm9yIGVsZW1lbnQgIm1heExlbmd0aCIgLSBsb2NhbAotICAgICAgICBmRWxlQXR0cnNNYXBMLnB1dChTY2hlbWFTeW1ib2xzLkVMVF9NQVhMRU5HVEgsIGF0dHJMaXN0KTsKLSAgICAgICAgLy8gZm9yIGVsZW1lbnQgImZyYWN0aW9uRGlnaXRzIiAtIGxvY2FsCi0gICAgICAgIGZFbGVBdHRyc01hcEwucHV0KFNjaGVtYVN5bWJvbHMuRUxUX0ZSQUNUSU9ORElHSVRTLCBhdHRyTGlzdCk7Ci0KLSAgICAgICAgLy8gZm9yIGVsZW1lbnQgInRvdGFsRGlnaXRzIiAtIGxvY2FsCi0gICAgICAgIGF0dHJMaXN0ID0gQ29udGFpbmVyLmdldENvbnRhaW5lcigzKTsKLSAgICAgICAgLy8gaWQgPSBJRAotICAgICAgICBhdHRyTGlzdC5wdXQoU2NoZW1hU3ltYm9scy5BVFRfSUQsIGFsbEF0dHJzW0FUVF9JRF9OXSk7Ci0gICAgICAgIC8vIHZhbHVlID0gcG9zaXRpdmVJbnRlZ2VyCi0gICAgICAgIGF0dHJMaXN0LnB1dChTY2hlbWFTeW1ib2xzLkFUVF9WQUxVRSwgYWxsQXR0cnNbQVRUX1ZBTFVFX1BJX05dKTsKLSAgICAgICAgLy8gZml4ZWQgPSBib29sZWFuIDogZmFsc2UKLSAgICAgICAgYXR0ckxpc3QucHV0KFNjaGVtYVN5bWJvbHMuQVRUX0ZJWEVELCBhbGxBdHRyc1tBVFRfRklYRURfRF0pOwotICAgICAgICBmRWxlQXR0cnNNYXBMLnB1dChTY2hlbWFTeW1ib2xzLkVMVF9UT1RBTERJR0lUUywgYXR0ckxpc3QpOwotCi0gICAgICAgIC8vIGZvciBlbGVtZW50ICJwYXR0ZXJuIiAtIGxvY2FsCi0gICAgICAgIGF0dHJMaXN0ID0gQ29udGFpbmVyLmdldENvbnRhaW5lcigyKTsKLSAgICAgICAgLy8gaWQgPSBJRAotICAgICAgICBhdHRyTGlzdC5wdXQoU2NoZW1hU3ltYm9scy5BVFRfSUQsIGFsbEF0dHJzW0FUVF9JRF9OXSk7Ci0gICAgICAgIC8vIHZhbHVlID0gc3RyaW5nCi0gICAgICAgIGF0dHJMaXN0LnB1dChTY2hlbWFTeW1ib2xzLkFUVF9WQUxVRSwgYWxsQXR0cnNbQVRUX1ZBTFVFX1NUUl9OXSk7Ci0gICAgICAgIGZFbGVBdHRyc01hcEwucHV0KFNjaGVtYVN5bWJvbHMuRUxUX1BBVFRFUk4sIGF0dHJMaXN0KTsKLQotICAgICAgICAvLyBmb3IgZWxlbWVudCAiZW51bWVyYXRpb24iIC0gbG9jYWwKLSAgICAgICAgYXR0ckxpc3QgPSBDb250YWluZXIuZ2V0Q29udGFpbmVyKDIpOwotICAgICAgICAvLyBpZCA9IElECi0gICAgICAgIGF0dHJMaXN0LnB1dChTY2hlbWFTeW1ib2xzLkFUVF9JRCwgYWxsQXR0cnNbQVRUX0lEX05dKTsKLSAgICAgICAgLy8gdmFsdWUgPSBhbnlTaW1wbGVUeXBlCi0gICAgICAgIGF0dHJMaXN0LnB1dChTY2hlbWFTeW1ib2xzLkFUVF9WQUxVRSwgYWxsQXR0cnNbQVRUX1ZBTFVFX1NUUl9OXSk7Ci0gICAgICAgIGZFbGVBdHRyc01hcEwucHV0KFNjaGVtYVN5bWJvbHMuRUxUX0VOVU1FUkFUSU9OLCBhdHRyTGlzdCk7Ci0KLSAgICAgICAgLy8gZm9yIGVsZW1lbnQgIndoaXRlU3BhY2UiIC0gbG9jYWwKLSAgICAgICAgYXR0ckxpc3QgPSBDb250YWluZXIuZ2V0Q29udGFpbmVyKDMpOwotICAgICAgICAvLyBpZCA9IElECi0gICAgICAgIGF0dHJMaXN0LnB1dChTY2hlbWFTeW1ib2xzLkFUVF9JRCwgYWxsQXR0cnNbQVRUX0lEX05dKTsKLSAgICAgICAgLy8gdmFsdWUgPSBwcmVzZXJ2ZSB8IHJlcGxhY2UgfCBjb2xsYXBzZQotICAgICAgICBhdHRyTGlzdC5wdXQoU2NoZW1hU3ltYm9scy5BVFRfVkFMVUUsIGFsbEF0dHJzW0FUVF9WQUxVRV9XU19OXSk7Ci0gICAgICAgIC8vIGZpeGVkID0gYm9vbGVhbiA6IGZhbHNlCi0gICAgICAgIGF0dHJMaXN0LnB1dChTY2hlbWFTeW1ib2xzLkFUVF9GSVhFRCwgYWxsQXR0cnNbQVRUX0ZJWEVEX0RdKTsKLSAgICAgICAgZkVsZUF0dHJzTWFwTC5wdXQoU2NoZW1hU3ltYm9scy5FTFRfV0hJVEVTUEFDRSwgYXR0ckxpc3QpOwotCi0gICAgICAgIC8vIGZvciBlbGVtZW50ICJtYXhJbmNsdXNpdmUiIC0gbG9jYWwKLSAgICAgICAgYXR0ckxpc3QgPSBDb250YWluZXIuZ2V0Q29udGFpbmVyKDMpOwotICAgICAgICAvLyBpZCA9IElECi0gICAgICAgIGF0dHJMaXN0LnB1dChTY2hlbWFTeW1ib2xzLkFUVF9JRCwgYWxsQXR0cnNbQVRUX0lEX05dKTsKLSAgICAgICAgLy8gdmFsdWUgPSBhbnlTaW1wbGVUeXBlCi0gICAgICAgIGF0dHJMaXN0LnB1dChTY2hlbWFTeW1ib2xzLkFUVF9WQUxVRSwgYWxsQXR0cnNbQVRUX1ZBTFVFX1NUUl9OXSk7Ci0gICAgICAgIC8vIGZpeGVkID0gYm9vbGVhbiA6IGZhbHNlCi0gICAgICAgIGF0dHJMaXN0LnB1dChTY2hlbWFTeW1ib2xzLkFUVF9GSVhFRCwgYWxsQXR0cnNbQVRUX0ZJWEVEX0RdKTsKLSAgICAgICAgZkVsZUF0dHJzTWFwTC5wdXQoU2NoZW1hU3ltYm9scy5FTFRfTUFYSU5DTFVTSVZFLCBhdHRyTGlzdCk7Ci0gICAgICAgIC8vIGZvciBlbGVtZW50ICJtYXhFeGNsdXNpdmUiIC0gbG9jYWwKLSAgICAgICAgZkVsZUF0dHJzTWFwTC5wdXQoU2NoZW1hU3ltYm9scy5FTFRfTUFYRVhDTFVTSVZFLCBhdHRyTGlzdCk7Ci0gICAgICAgIC8vIGZvciBlbGVtZW50ICJtaW5JbmNsdXNpdmUiIC0gbG9jYWwKLSAgICAgICAgZkVsZUF0dHJzTWFwTC5wdXQoU2NoZW1hU3ltYm9scy5FTFRfTUlOSU5DTFVTSVZFLCBhdHRyTGlzdCk7Ci0gICAgICAgIC8vIGZvciBlbGVtZW50ICJtaW5FeGNsdXNpdmUiIC0gbG9jYWwKLSAgICAgICAgZkVsZUF0dHJzTWFwTC5wdXQoU2NoZW1hU3ltYm9scy5FTFRfTUlORVhDTFVTSVZFLCBhdHRyTGlzdCk7Ci0gICAgfQotCi0gICAgLy8gdXNlZCB0byByZXNvbHZlciBuYW1lc3BhY2UgcHJlZml4ZXMKLSAgICBwcm90ZWN0ZWQgWFNESGFuZGxlciBmU2NoZW1hSGFuZGxlciA9IG51bGw7Ci0KLSAgICAvLyB1c2VkIHRvIHN0b3JlIHN5bWJvbHMuCi0gICAgcHJvdGVjdGVkIFN5bWJvbFRhYmxlIGZTeW1ib2xUYWJsZSA9IG51bGw7Ci0KLSAgICAvLyB1c2VkIHRvIHN0b3JlIHRoZSBtYXBwaW5nIGZyb20gcHJvY2Vzc2VkIGVsZW1lbnQgdG8gYXR0cmlidXRlcwotICAgIHByb3RlY3RlZCBNYXAgZk5vblNjaGVtYUF0dHJzID0gbmV3IEhhc2hNYXAoKTsKLQotICAgIC8vIHRlbXByb3J5IHZlY3RvciwgdXNlZCB0byBob2xkIHRoZSBuYW1lc3BhY2UgbGlzdAotICAgIHByb3RlY3RlZCBWZWN0b3IgZk5hbWVzcGFjZUxpc3QgPSBuZXcgVmVjdG9yKCk7Ci0KLSAgICAvLyB3aGV0aGVyIHRoaXMgYXR0cmlidXRlIGFwcGVhcmVkIGluIHRoZSBjdXJyZW50IGVsZW1lbnQKLSAgICBwcm90ZWN0ZWQgYm9vbGVhbltdIGZTZWVuID0gbmV3IGJvb2xlYW5bQVRUSURYX0NPVU5UXTsKLSAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuW10gZlNlZW5UZW1wID0gbmV3IGJvb2xlYW5bQVRUSURYX0NPVU5UXTsKLQotICAgIC8vIGNvbnN0cnVjdG9yLiBTZXRzIGZFcnJvclJlcHJvdGVyIGFuZCBnZXQgZGF0YXR5cGUgdmFsaWRhdG9ycwotICAgIHB1YmxpYyBYU0F0dHJpYnV0ZUNoZWNrZXIoWFNESGFuZGxlciBzY2hlbWFIYW5kbGVyKSB7Ci0gICAgICAgIGZTY2hlbWFIYW5kbGVyID0gc2NoZW1hSGFuZGxlcjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCByZXNldChTeW1ib2xUYWJsZSBzeW1ib2xUYWJsZSkgewotICAgICAgICBmU3ltYm9sVGFibGUgPSBzeW1ib2xUYWJsZTsKLSAgICAgICAgZk5vblNjaGVtYUF0dHJzLmNsZWFyKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ2hlY2sgd2hldGhlciB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgY29uZm9ybXMgdG8gdGhlIGF0dHJpYnV0ZXMgcmVzdHJpY3Rpb24KLSAgICAgKiBhbiBhcnJheSBvZiBhdHRyaWJ1dGUgdmFsdWVzIGlzIHJldHVybmVkLiB0aGUgY2FsbGVyIG11c3QgY2FsbAotICAgICAqIDxjb2RlPnJldHVybkF0dHJBcnJheTwvY29kZT4gdG8gcmV0dXJuIHRoYXQgYXJyYXkuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZWxlbWVudCAgICB3aGljaCBlbGVtZW50IHRvIGNoZWNrCi0gICAgICogQHBhcmFtIGlzR2xvYmFsICAgd2hldGhlciBhIGNoaWxkIG9mICZsdDtzY2hlbWEmZ3Q7IG9yICZsdDtyZWRlZmluZSZndDsKLSAgICAgKiBAcGFyYW0gc2NoZW1hRG9jICB0aGUgZG9jdW1lbnQgd2hlcmUgdGhlIGVsZW1lbnQgbGl2ZXMgaW4KLSAgICAgKiBAcmV0dXJuICAgICAgICAgICBhbiBhcnJheSBjb250YWluaW5nIGF0dHJpYnV0ZSB2YWx1ZXMKLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0W10gY2hlY2tBdHRyaWJ1dGVzKEVsZW1lbnQgZWxlbWVudCwgYm9vbGVhbiBpc0dsb2JhbCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhTRG9jdW1lbnRJbmZvIHNjaGVtYURvYykgewotICAgICAgICByZXR1cm4gY2hlY2tBdHRyaWJ1dGVzKGVsZW1lbnQsIGlzR2xvYmFsLCBzY2hlbWFEb2MsIGZhbHNlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDaGVjayB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBjb25mb3JtcyB0byB0aGUgYXR0cmlidXRlcyByZXN0cmljdGlvbgotICAgICAqIGFuIGFycmF5IG9mIGF0dHJpYnV0ZSB2YWx1ZXMgaXMgcmV0dXJuZWQuIHRoZSBjYWxsZXIgbXVzdCBjYWxsCi0gICAgICogPGNvZGU+cmV0dXJuQXR0ckFycmF5PC9jb2RlPiB0byByZXR1cm4gdGhhdCBhcnJheS4gVGhpcyBtZXRob2QgYWxzbyB0YWtlcwotICAgICAqIGFuIGV4dHJhIHBhcmFtZXRlcjogaWYgdGhlIGVsZW1lbnQgaXMgImVudW1lcmF0aW9uIiwgd2hldGhlciB0byBtYWtlIGEKLSAgICAgKiBjb3B5IG9mIHRoZSBuYW1lc3BhY2UgY29udGV4dCwgc28gdGhhdCB0aGUgdmFsdWUgY2FuIGJlIHJlc29sdmVkIGFzIGEKLSAgICAgKiBRTmFtZSBsYXRlci4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlbGVtZW50ICAgICAgd2hpY2ggZWxlbWVudCB0byBjaGVjawotICAgICAqIEBwYXJhbSBpc0dsb2JhbCAgICAgd2hldGhlciBhIGNoaWxkIG9mICZsdDtzY2hlbWEmZ3Q7IG9yICZsdDtyZWRlZmluZSZndDsKLSAgICAgKiBAcGFyYW0gc2NoZW1hRG9jICAgIHRoZSBkb2N1bWVudCB3aGVyZSB0aGUgZWxlbWVudCBsaXZlcyBpbgotICAgICAqIEBwYXJhbSBlbnVtQXNRTmFtZSAgd2hldGhlciB0byB0cmVhZCBlbnVtZXJhdGlvbiB2YWx1ZSBhcyBRTmFtZQotICAgICAqIEByZXR1cm4gICAgICAgICAgICAgYW4gYXJyYXkgY29udGFpbmluZyBhdHRyaWJ1dGUgdmFsdWVzCi0gICAgICovCi0gICAgcHVibGljIE9iamVjdFtdIGNoZWNrQXR0cmlidXRlcyhFbGVtZW50IGVsZW1lbnQsIGJvb2xlYW4gaXNHbG9iYWwsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYU0RvY3VtZW50SW5mbyBzY2hlbWFEb2MsIGJvb2xlYW4gZW51bUFzUU5hbWUpIHsKLSAgICAgICAgaWYgKGVsZW1lbnQgPT0gbnVsbCkKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotCi0gICAgICAgIC8vIGdldCBhbGwgYXR0cmlidXRlcwotICAgICAgICBBdHRyW10gYXR0cnMgPSBET01VdGlsLmdldEF0dHJzKGVsZW1lbnQpOwotCi0gICAgICAgIC8vIHVwZGF0ZSBOYW1lc3BhY2VTdXBwb3J0Ci0gICAgICAgIHJlc29sdmVOYW1lc3BhY2UoZWxlbWVudCwgYXR0cnMsIHNjaGVtYURvYy5mTmFtZXNwYWNlU3VwcG9ydCk7Ci0KLSAgICAgICAgU3RyaW5nIHVyaSA9IERPTVV0aWwuZ2V0TmFtZXNwYWNlVVJJKGVsZW1lbnQpOwotICAgICAgICBTdHJpbmcgZWxOYW1lID0gRE9NVXRpbC5nZXRMb2NhbE5hbWUoZWxlbWVudCk7Ci0KLSAgICAgICAgaWYgKCFTY2hlbWFTeW1ib2xzLlVSSV9TQ0hFTUFGT1JTQ0hFTUEuZXF1YWxzKHVyaSkpIHsKLSAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKCJzNHMtZWx0LXNjaGVtYS1ucyIsIG5ldyBPYmplY3RbXSB7ZWxOYW1lfSwgZWxlbWVudCk7Ci0gICAgICAgIH0KLQotICAgICAgICBNYXAgZWxlQXR0cnNNYXAgPSBmRWxlQXR0cnNNYXBHOwotICAgICAgICBTdHJpbmcgbG9va3VwTmFtZSA9IGVsTmFtZTsKLQotICAgICAgICAvLyBSRVZJU0lUOiBvbmx5IGxvY2FsIGVsZW1lbnQgYW5kIGF0dHJpYnV0ZSBhcmUgZGlmZmVyZW50IGZyb20gb3RoZXJzLgotICAgICAgICAvLyAgICAgICAgICBpdCdzIHBvc3NpYmxlIHRvIGhhdmUgZWl0aGVyIG5hbWUgb3IgcmVmLiBhbGwgdGhlIG90aGVycwotICAgICAgICAvLyAgICAgICAgICBhcmUgb25seSBhbGxvd2VkIHRvIGhhdmUgb25lIG9mIG5hbWUgb3IgcmVmLCBvciBuZWl0aGVyIG9mIHRoZW0uCi0gICAgICAgIC8vICAgICAgICAgIHdlJ2QgYmV0dGVyIG1vdmUgc3VjaCBjaGVja2luZyB0byB0aGUgdHJhdmVyc2VyLgotICAgICAgICBpZiAoIWlzR2xvYmFsKSB7Ci0gICAgICAgICAgICBlbGVBdHRyc01hcCA9IGZFbGVBdHRyc01hcEw7Ci0gICAgICAgICAgICBpZiAoZWxOYW1lLmVxdWFscyhTY2hlbWFTeW1ib2xzLkVMVF9FTEVNRU5UKSkgewotICAgICAgICAgICAgICAgIGlmIChET01VdGlsLmdldEF0dHIoZWxlbWVudCwgU2NoZW1hU3ltYm9scy5BVFRfUkVGKSAhPSBudWxsKQotICAgICAgICAgICAgICAgICAgICBsb29rdXBOYW1lID0gRUxFTUVOVF9SOwotICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgICAgbG9va3VwTmFtZSA9IEVMRU1FTlRfTjsKLSAgICAgICAgICAgIH0gZWxzZSBpZiAoZWxOYW1lLmVxdWFscyhTY2hlbWFTeW1ib2xzLkVMVF9BVFRSSUJVVEUpKSB7Ci0gICAgICAgICAgICAgICAgaWYgKERPTVV0aWwuZ2V0QXR0cihlbGVtZW50LCBTY2hlbWFTeW1ib2xzLkFUVF9SRUYpICE9IG51bGwpCi0gICAgICAgICAgICAgICAgICAgIGxvb2t1cE5hbWUgPSBBVFRSSUJVVEVfUjsKLSAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgIGxvb2t1cE5hbWUgPSBBVFRSSUJVVEVfTjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIGdldCBkZXNpcmVkIGF0dHJpYnV0ZSBsaXN0IG9mIHRoaXMgZWxlbWVudAotICAgICAgICBDb250YWluZXIgYXR0ckxpc3QgPSAoQ29udGFpbmVyKWVsZUF0dHJzTWFwLmdldChsb29rdXBOYW1lKTsKLSAgICAgICAgaWYgKGF0dHJMaXN0ID09IG51bGwpIHsKLSAgICAgICAgICAgIC8vIHNob3VsZCBuZXZlciBnZXRzIGhlcmUuCi0gICAgICAgICAgICAvLyB3aGVuIHRoaXMgbWV0aG9kIGlzIGNhbGxlZCwgdGhlIGNhbGwgYWxyZWFkeSBrbm93cyB0aGF0Ci0gICAgICAgICAgICAvLyB0aGUgZWxlbWVudCBjYW4gYXBwZWFyLgotICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IgKCJzNHMtZWx0LWludmFsaWQiLCBuZXcgT2JqZWN0W10ge2VsTmFtZX0sIGVsZW1lbnQpOwotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLQotICAgICAgICBPYmplY3RbXSBhdHRyVmFsdWVzID0gZ2V0QXZhaWxhYmxlQXJyYXkoKTsKLSAgICAgICAgbG9uZyBmcm9tRGVmYXVsdCA9IDA7Ci0KLSAgICAgICAgLy8gY2xlYXIgdGhlICJzZWVuIiBmbGFnLgotICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGZTZWVuVGVtcCwgMCwgZlNlZW4sIDAsIEFUVElEWF9DT1VOVCk7Ci0KLSAgICAgICAgLy8gdHJhdmVyc2UgYWxsIGF0dHJpYnV0ZXMKLSAgICAgICAgaW50IGxlbmd0aCA9IGF0dHJzLmxlbmd0aDsKLSAgICAgICAgQXR0ciBzYXR0ciA9IG51bGw7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgIHNhdHRyID0gYXR0cnNbaV07Ci0gICAgICAgICAgICAvLyBnZXQgdGhlIGF0dHJpYnV0ZSBuYW1lL3ZhbHVlCi0gICAgICAgICAgICAvL1N0cmluZyBhdHRyTmFtZSA9IERPTVV0aWwuZ2V0TG9jYWxOYW1lKHNhdHRyKTsKLSAgICAgICAgICAgIFN0cmluZyBhdHRyTmFtZSA9IHNhdHRyLmdldE5hbWUoKTsKLSAgICAgICAgICAgIFN0cmluZyBhdHRyVVJJID0gRE9NVXRpbC5nZXROYW1lc3BhY2VVUkkoc2F0dHIpOwotICAgICAgICAgICAgU3RyaW5nIGF0dHJWYWwgPSBET01VdGlsLmdldFZhbHVlKHNhdHRyKTsKLQotICAgICAgICAgICAgaWYgKGF0dHJOYW1lLnN0YXJ0c1dpdGgoInhtbCIpKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIGF0dHJQcmVmaXggPSBET01VdGlsLmdldFByZWZpeChzYXR0cik7Ci0gICAgICAgICAgICAgICAgLy8gd2UgZG9uJ3Qgd2FudCB0byBhZGQgbmFtZXNwYWNlIGRlY2xhcmF0aW9ucyB0byB0aGUgbm9uLXNjaGVtYSBhdHRyaWJ1dGVzCi0gICAgICAgICAgICAgICAgaWYgKCJ4bWxucyIuZXF1YWxzKGF0dHJQcmVmaXgpIHx8ICJ4bWxucyIuZXF1YWxzKGF0dHJOYW1lKSkgewotICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLy8gQm90aCA8c2NoZW1hPiBhbmQgPGRvY3VtZW50YXRpb24+IG1heSBoYXZlIGFuIHhtbDpsYW5nIGF0dHJpYnV0ZS4KLSAgICAgICAgICAgICAgICAvLyBTZXQgdGhlIFVSSSBmb3IgdGhpcyBhdHRyaWJ1dGUgdG8gbnVsbCBzbyB0aGF0IHdlIHByb2Nlc3MgaXQKLSAgICAgICAgICAgICAgICAvLyBsaWtlIGFueSBvdGhlciBzY2hlbWEgYXR0cmlidXRlLgotICAgICAgICAgICAgICAgIGVsc2UgaWYgKFNjaGVtYVN5bWJvbHMuQVRUX1hNTF9MQU5HLmVxdWFscyhhdHRyTmFtZSkgJiYKLSAgICAgICAgICAgICAgICAgICAgICAgIChTY2hlbWFTeW1ib2xzLkVMVF9TQ0hFTUEuZXF1YWxzKGVsTmFtZSkgfHwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU2NoZW1hU3ltYm9scy5FTFRfRE9DVU1FTlRBVElPTi5lcXVhbHMoZWxOYW1lKSkpIHsKLSAgICAgICAgICAgICAgICAgICAgYXR0clVSSSA9IG51bGw7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBmb3IgYXR0cmlidXRlcyB3aXRoIG5hbWVzcGFjZSBwcmVmaXgKLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICBpZiAoYXR0clVSSSAhPSBudWxsICYmIGF0dHJVUkkubGVuZ3RoKCkgIT0gMCkgewotICAgICAgICAgICAgICAgIC8vIGF0dHJpYnV0ZXMgd2l0aCBzY2hlbWEgbmFtZXNwYWNlIGFyZSBub3QgYWxsb3dlZAotICAgICAgICAgICAgICAgIC8vIGFuZCBub3QgYWxsb3dlZCBvbiAiZG9jdW1lbnQiIGFuZCAiYXBwSW5mbyIKLSAgICAgICAgICAgICAgICBpZiAoYXR0clVSSS5lcXVhbHMoU2NoZW1hU3ltYm9scy5VUklfU0NIRU1BRk9SU0NIRU1BKSkgewotICAgICAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvciAoInM0cy1hdHQtbm90LWFsbG93ZWQiLCBuZXcgT2JqZWN0W10ge2VsTmFtZSwgYXR0ck5hbWV9LCBlbGVtZW50KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmKGF0dHJWYWx1ZXNbQVRUSURYX05PTlNDSEVNQV0gPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhlc2UgYXJlIHVzdWFsbHkgc21hbGwKLSAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJWYWx1ZXNbQVRUSURYX05PTlNDSEVNQV0gPSBuZXcgVmVjdG9yKDQsMik7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgKChWZWN0b3IpYXR0clZhbHVlc1tBVFRJRFhfTk9OU0NIRU1BXSkuYWRkRWxlbWVudChhdHRyTmFtZSk7Ci0gICAgICAgICAgICAgICAgICAgICgoVmVjdG9yKWF0dHJWYWx1ZXNbQVRUSURYX05PTlNDSEVNQV0pLmFkZEVsZW1lbnQoYXR0clZhbCk7Ci0gICAgICAgICAgICAgICAgICAgIC8vIGZvciBhdHRyaWJ1dGVzIGZyb20gb3RoZXIgbmFtZXNwYWNlCi0gICAgICAgICAgICAgICAgICAgIC8vIHN0b3JlIHRoZW0gaW4gYSBsaXN0LCBhbmQgVFJZIHRvIHZhbGlkYXRlIHRoZW0gYWZ0ZXIKLSAgICAgICAgICAgICAgICAgICAgLy8gc2NoZW1hIHRyYXZlcnNhbCAoYmVjYXVzZSBpdCdzICJsYXgiKQotICAgICAgICAgICAgICAgICAgICAvL290aGVyVmFsdWVzLnB1dChhdHRyTmFtZSwgYXR0clZhbCk7Ci0gICAgICAgICAgICAgICAgICAgIC8vIFJFVklTSVQ6ICBhY3R1YWxseSB1c2UgdGhpcyBzb21lIGRheS4uLgotICAgICAgICAgICAgICAgICAgICAvLyBTdHJpbmcgYXR0clJOYW1lID0gYXR0clVSSSArICIsIiArIGF0dHJOYW1lOwotICAgICAgICAgICAgICAgICAgICAvLyBWZWN0b3IgdmFsdWVzID0gKFZlY3RvcilmTm9uU2NoZW1hQXR0cnMuZ2V0KGF0dHJSTmFtZSk7Ci0gICAgICAgICAgICAgICAgICAgIC8vIGlmICh2YWx1ZXMgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gdmFsdWVzID0gbmV3IFZlY3RvcigpOwotICAgICAgICAgICAgICAgICAgICAgICAgLy8gdmFsdWVzLmFkZEVsZW1lbnQoYXR0ck5hbWUpOwotICAgICAgICAgICAgICAgICAgICAgICAgLy8gdmFsdWVzLmFkZEVsZW1lbnQoZWxOYW1lKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIHZhbHVlcy5hZGRFbGVtZW50KGF0dHJWYWwpOwotICAgICAgICAgICAgICAgICAgICAgICAgLy8gZk5vblNjaGVtYUF0dHJzLnB1dChhdHRyUk5hbWUsIHZhbHVlcyk7Ci0gICAgICAgICAgICAgICAgICAgIC8vIH0KLSAgICAgICAgICAgICAgICAgICAgLy8gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyB2YWx1ZXMuYWRkRWxlbWVudChlbE5hbWUpOwotICAgICAgICAgICAgICAgICAgICAgICAgLy8gdmFsdWVzLmFkZEVsZW1lbnQoYXR0clZhbCk7Ci0gICAgICAgICAgICAgICAgICAgIC8vIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIGNoZWNrIHdoZXRoZXIgdGhpcyBhdHRyaWJ1dGUgaXMgYWxsb3dlZAotICAgICAgICAgICAgT25lQXR0ciBvbmVBdHRyID0gYXR0ckxpc3QuZ2V0KGF0dHJOYW1lKTsKLSAgICAgICAgICAgIGlmIChvbmVBdHRyID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvciAoInM0cy1hdHQtbm90LWFsbG93ZWQiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10ge2VsTmFtZSwgYXR0ck5hbWV9LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50KTsKLSAgICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gd2UndmUgc2VlbiB0aGlzIGF0dHJpYnV0ZQotICAgICAgICAgICAgZlNlZW5bb25lQXR0ci52YWx1ZUluZGV4XSA9IHRydWU7Ci0KLSAgICAgICAgICAgIC8vIGNoZWNrIHRoZSB2YWx1ZSBhZ2FpbnN0IHRoZSBkYXRhdHlwZQotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAvLyBubyBjaGVja2luZyBvbiBzdHJpbmcgbmVlZHMgdG8gYmUgZG9uZSBoZXJlLgotICAgICAgICAgICAgICAgIC8vIG5vIGNoZWNraW5nIG9uIHhwYXRoIG5lZWRzIHRvIGJlIGRvbmUgaGVyZS4KLSAgICAgICAgICAgICAgICAvLyB4cGF0aCB2YWx1ZXMgYXJlIHZhbGlkYXRlZCBpbiB4cGF0aCBwYXJzZXIKLSAgICAgICAgICAgICAgICBpZiAob25lQXR0ci5kdkluZGV4ID49IDApIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKG9uZUF0dHIuZHZJbmRleCAhPSBEVF9TVFJJTkcgJiYKLSAgICAgICAgICAgICAgICAgICAgICAgIG9uZUF0dHIuZHZJbmRleCAhPSBEVF9YUEFUSCAmJgotICAgICAgICAgICAgICAgICAgICAgICAgb25lQXR0ci5kdkluZGV4ICE9IERUX1hQQVRIMSkgewotICAgICAgICAgICAgICAgICAgICAgICAgWFNTaW1wbGVUeXBlIGR2ID0gZkV4dHJhRFZzW29uZUF0dHIuZHZJbmRleF07Ci0gICAgICAgICAgICAgICAgICAgICAgICBPYmplY3QgYXZhbHVlID0gZHYudmFsaWRhdGUoYXR0clZhbCwgc2NoZW1hRG9jLmZWYWxpZGF0aW9uQ29udGV4dCwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBrbHVkZ2UgdG8gaGFuZGxlIGNoYW1lbGVvbiBpbmNsdWRlcy9yZWRlZmluZXMuLi4KLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvbmVBdHRyLmR2SW5kZXggPT0gRFRfUU5BTUUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBRTmFtZSBxbmFtZSA9IChRTmFtZSlhdmFsdWU7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYocW5hbWUucHJlZml4ID09IFhNTFN5bWJvbHMuRU1QVFlfU1RSSU5HICYmIHFuYW1lLnVyaSA9PSBudWxsICYmIHNjaGVtYURvYy5mSXNDaGFtZWxlb25TY2hlbWEpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHFuYW1lLnVyaSA9IHNjaGVtYURvYy5mVGFyZ2V0TmFtZXNwYWNlOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgYXR0clZhbHVlc1tvbmVBdHRyLnZhbHVlSW5kZXhdID0gYXZhbHVlOwotICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgYXR0clZhbHVlc1tvbmVBdHRyLnZhbHVlSW5kZXhdID0gYXR0clZhbDsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgYXR0clZhbHVlc1tvbmVBdHRyLnZhbHVlSW5kZXhdID0gdmFsaWRhdGUoYXR0clZhbHVlcywgYXR0ck5hbWUsIGF0dHJWYWwsIG9uZUF0dHIuZHZJbmRleCwgc2NoZW1hRG9jKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9IGNhdGNoIChJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbiBpZGUpIHsKLSAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvciAoInM0cy1hdHQtaW52YWxpZC12YWx1ZSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7ZWxOYW1lLCBhdHRyTmFtZSwgaWRlLmdldE1lc3NhZ2UoKX0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQpOwotICAgICAgICAgICAgICAgIGlmIChvbmVBdHRyLmRmbHRWYWx1ZSAhPSBudWxsKQotICAgICAgICAgICAgICAgICAgICAvL2F0dHJWYWx1ZXMucHV0KGF0dHJOYW1lLCBvbmVBdHRyLmRmbHRWYWx1ZSk7Ci0gICAgICAgICAgICAgICAgICAgIGF0dHJWYWx1ZXNbb25lQXR0ci52YWx1ZUluZGV4XSA9IG9uZUF0dHIuZGZsdFZhbHVlOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBGb3IgImVudW1lcmF0aW9uIiwgYW5kIHR5cGUgaXMgcG9zc2libGUgdG8gYmUgYSBRTmFtZSwgd2UgbmVlZAotICAgICAgICAgICAgLy8gdG8gcmV0dXJuIG5hbWVzcGFjZSBjb250ZXh0IGZvciBsYXRlciBRTmFtZSByZXNvbHV0aW9uLgotICAgICAgICAgICAgaWYgKGVsTmFtZS5lcXVhbHMoU2NoZW1hU3ltYm9scy5FTFRfRU5VTUVSQVRJT04pICYmIGVudW1Bc1FOYW1lKSB7Ci0gICAgICAgICAgICAgICAgYXR0clZhbHVlc1tBVFRJRFhfRU5VTU5TREVDTFNdID0gbmV3IFNjaGVtYU5hbWVzcGFjZVN1cHBvcnQoc2NoZW1hRG9jLmZOYW1lc3BhY2VTdXBwb3J0KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIGFwcGx5IGRlZmF1bHQgdmFsdWVzCi0gICAgICAgIE9uZUF0dHJbXSByZXFBdHRycyA9IGF0dHJMaXN0LnZhbHVlczsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXFBdHRycy5sZW5ndGg7IGkrKykgewotICAgICAgICAgICAgT25lQXR0ciBvbmVBdHRyID0gcmVxQXR0cnNbaV07Ci0KLSAgICAgICAgICAgIC8vIGlmIHRoZSBhdHRyaWJ1dGUgZGlkbid0IGFwcHJlYXIsIGFuZAotICAgICAgICAgICAgLy8gaWYgdGhlIGF0dHJpYnV0ZSBpcyBvcHRpb25hbCB3aXRoIGRlZmF1bHQgdmFsdWUsIGFwcGx5IGl0Ci0gICAgICAgICAgICBpZiAob25lQXR0ci5kZmx0VmFsdWUgIT0gbnVsbCAmJiAhZlNlZW5bb25lQXR0ci52YWx1ZUluZGV4XSkgewotICAgICAgICAgICAgICAgIC8vYXR0clZhbHVlcy5wdXQob25lQXR0ci5uYW1lLCBvbmVBdHRyLmRmbHRWYWx1ZSk7Ci0gICAgICAgICAgICAgICAgYXR0clZhbHVlc1tvbmVBdHRyLnZhbHVlSW5kZXhdID0gb25lQXR0ci5kZmx0VmFsdWU7Ci0gICAgICAgICAgICAgICAgZnJvbURlZmF1bHQgfD0gKDE8PG9uZUF0dHIudmFsdWVJbmRleCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBhdHRyVmFsdWVzW0FUVElEWF9GUk9NREVGQVVMVF0gPSBuZXcgTG9uZyhmcm9tRGVmYXVsdCk7Ci0gICAgICAgIC8vYXR0clZhbHVlc1tBVFRJRFhfT1RIRVJWQUxVRVNdID0gb3RoZXJWYWx1ZXM7Ci0KLSAgICAgICAgLy8gQ2hlY2sgdGhhdCBtaW5PY2N1cnMgaXNuJ3QgZ3JlYXRlciB0aGFuIG1heE9jY3Vycy4KLSAgICAgICAgLy8gcC1wcm9wcy1jb3JyZWN0IDIuMQotICAgICAgICBpZiAoYXR0clZhbHVlc1tBVFRJRFhfTUFYT0NDVVJTXSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpbnQgbWluID0gKChYSW50KWF0dHJWYWx1ZXNbQVRUSURYX01JTk9DQ1VSU10pLmludFZhbHVlKCk7Ci0gICAgICAgICAgICBpbnQgbWF4ID0gKChYSW50KWF0dHJWYWx1ZXNbQVRUSURYX01BWE9DQ1VSU10pLmludFZhbHVlKCk7Ci0gICAgICAgICAgICBpZiAobWF4ICE9IFNjaGVtYVN5bWJvbHMuT0NDVVJSRU5DRV9VTkJPVU5ERUQpIHsKLQotICAgICAgICAgICAgICAgIC8vIG1heE9jY3VyTGltaXQgaXMgb25seSBjaGVjayBpbiBzZWN1cmUgbW9kZQotICAgICAgICAgICAgICAgIGlmIChmU2NoZW1hSGFuZGxlci5mU2VjdXJpdHlNYW5hZ2VyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGxvY2FsTmFtZSA9IGVsZW1lbnQuZ2V0TG9jYWxOYW1lKCk7Ci0KLSAgICAgICAgICAgICAgICAvLyBUaGUgbWF4T2NjdXJzIHJlc3RyaWN0aW9uIG5vIGxvbmdlciBhcHBsaWVzIHRvIGVsZW1lbnRzCi0gICAgICAgICAgICAgICAgICAgIC8vIGFuZCB3aWxkY2FyZHMgaW4gYSBzZXF1ZW5jZSBpbiB3aGljaCB0aGV5IGFyZSB0aGUgb25seQotICAgICAgICAgICAgICAgICAgICAvLyBwYXJ0aWNsZS4gVGhlc2UgYXJlIG5vdyB2YWxpZGF0ZWQgdXNpbmcgYSBjb25zdGFudAotICAgICAgICAgICAgICAgICAgICAvLyBzcGFjZSBhbGdvcml0aG0uIFRoZSByZXN0cmljdGlvbiBzdGlsbCBhcHBsaWVzIHRvIGFsbAotICAgICAgICAgICAgICAgICAgICAvLyBvdGhlciBjYXNlcy4KLQotICAgICAgICAgICAgICAgICAgICAvLyBEZXRlcm1pbmUgaWYgY29uc3RhbnQtc3BhY2UgYWxnb3JpdGhtIGNhbiBiZSBhcHBsaWVkCi0gICAgICAgICAgICAgICAgICAgIGZpbmFsIGJvb2xlYW4gb3B0aW1pemUgPQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIChsb2NhbE5hbWUuZXF1YWxzKCJlbGVtZW50IikgfHwgbG9jYWxOYW1lLmVxdWFscygiYW55IikpICYmCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGVsZW1lbnQuZ2V0TmV4dFNpYmxpbmcoKSA9PSBudWxsKSAmJgotICAgICAgICAgICAgICAgICAgICAgICAgICAgIChlbGVtZW50LmdldFByZXZpb3VzU2libGluZygpID09IG51bGwpICYmCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGVsZW1lbnQuZ2V0UGFyZW50Tm9kZSgpLmdldExvY2FsTmFtZSgpLmVxdWFscygic2VxdWVuY2UiKSk7Ci0KLSAgICAgICAgICAgICAgICAgICAgaWYgKCFvcHRpbWl6ZSkgewotICAgICAgICAgICAgICAgICAgICAvL1JldmlzaXQgOjogSU1PIHRoaXMgaXMgbm90IHJpZ2h0IHBsYWNlIHRvIGNoZWNrCi0gICAgICAgICAgICAgICAgICAgIC8vIG1heE9jY3VyTm9kZUxpbWl0LgotICAgICAgICAgICAgICAgICAgICBpbnQgbWF4T2NjdXJOb2RlTGltaXQgPSBmU2NoZW1hSGFuZGxlci5mU2VjdXJpdHlNYW5hZ2VyLmdldExpbWl0KFhNTFNlY3VyaXR5TWFuYWdlci5MaW1pdC5NQVhfT0NDVVJfTk9ERV9MSU1JVCk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChtYXggPiBtYXhPY2N1ck5vZGVMaW1pdCAmJiAhZlNjaGVtYUhhbmRsZXIuZlNlY3VyaXR5TWFuYWdlci5pc05vTGltaXQobWF4T2NjdXJOb2RlTGltaXQpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFGYXRhbEVycm9yKCJNYXhPY2N1ckxpbWl0IiwgbmV3IE9iamVjdFtdIHtuZXcgSW50ZWdlcihtYXhPY2N1ck5vZGVMaW1pdCl9LCBlbGVtZW50KTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gcmVzZXQgbWF4IHZhbHVlcyBpbiBjYXNlIHByb2Nlc3NpbmcgY29udGludWVzIG9uIGVycm9yCi0gICAgICAgICAgICAgICAgICAgICAgICBhdHRyVmFsdWVzW0FUVElEWF9NQVhPQ0NVUlNdID0gZlhJbnRQb29sLmdldFhJbnQobWF4T2NjdXJOb2RlTGltaXQpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9uZXcgSW50ZWdlcihtYXhPY2N1ck5vZGVMaW1pdCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBtYXggPSBtYXhPY2N1ck5vZGVMaW1pdDsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBpZiAobWluID4gbWF4KSB7Ci0gICAgICAgICAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yICgicC1wcm9wcy1jb3JyZWN0LjIuMSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10ge2VsTmFtZSwgYXR0clZhbHVlc1tBVFRJRFhfTUlOT0NDVVJTXSwgYXR0clZhbHVlc1tBVFRJRFhfTUFYT0NDVVJTXX0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50KTsKLSAgICAgICAgICAgICAgICAgICAgYXR0clZhbHVlc1tBVFRJRFhfTUlOT0NDVVJTXSA9IGF0dHJWYWx1ZXNbQVRUSURYX01BWE9DQ1VSU107Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIGF0dHJWYWx1ZXM7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBPYmplY3QgdmFsaWRhdGUoT2JqZWN0W10gYXR0clZhbHVlcywgU3RyaW5nIGF0dHIsIFN0cmluZyBpdmFsdWUsIGludCBkdkluZGV4LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhTRG9jdW1lbnRJbmZvIHNjaGVtYURvYykgdGhyb3dzIEludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKGl2YWx1ZSA9PSBudWxsKQotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0KLSAgICAgICAgLy8gVG8gdmFsaWRhdGUgdGhlc2UgdHlwZXMsIHdlIGRvbid0IGFjdHVhbGx5IG5lZWQgdG8gbm9ybWFsaXplIHRoZQotICAgICAgICAvLyBzdHJpbmdzLiBXZSBvbmx5IG5lZWQgdG8gcmVtb3ZlIHRoZSB3aGl0ZXNwYWNlIGZyb20gYm90aCBlbmRzLgotICAgICAgICAvLyBJbiBzb21lIHNwZWNpYWwgY2FzZXMgKGxpc3QgdHlwZXMpLCBTdHJpbmdUb2tlbml6ZXIgY2FuIGNvcnJlY3RseQotICAgICAgICAvLyBwcm9jZXNzIHRoZSB1bi1ub3JtYWxpemVkIHdoaXRlc3BhY2UuCi0KLSAgICAgICAgU3RyaW5nIHZhbHVlID0gWE1MQ2hhci50cmltKGl2YWx1ZSk7Ci0gICAgICAgIE9iamVjdCByZXRWYWx1ZSA9IG51bGw7Ci0gICAgICAgIFZlY3RvciBtZW1iZXJUeXBlOwotICAgICAgICBpbnQgY2hvaWNlOwotCi0gICAgICAgIHN3aXRjaCAoZHZJbmRleCkgewotICAgICAgICBjYXNlIERUX0JPT0xFQU46Ci0gICAgICAgICAgICBpZiAodmFsdWUuZXF1YWxzKFNjaGVtYVN5bWJvbHMuQVRUVkFMX0ZBTFNFKSB8fAotICAgICAgICAgICAgICAgIHZhbHVlLmVxdWFscyhTY2hlbWFTeW1ib2xzLkFUVFZBTF9GQUxTRV8wKSkgewotICAgICAgICAgICAgICAgIHJldFZhbHVlID0gQm9vbGVhbi5GQUxTRTsKLSAgICAgICAgICAgIH0gZWxzZSBpZiAodmFsdWUuZXF1YWxzKFNjaGVtYVN5bWJvbHMuQVRUVkFMX1RSVUUpIHx8Ci0gICAgICAgICAgICAgICAgICAgICAgIHZhbHVlLmVxdWFscyhTY2hlbWFTeW1ib2xzLkFUVFZBTF9UUlVFXzEpKSB7Ci0gICAgICAgICAgICAgICAgcmV0VmFsdWUgPSBCb29sZWFuLlRSVUU7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbigiY3ZjLWRhdGF0eXBlLXZhbGlkLjEuMi4xIiwgbmV3IE9iamVjdFtde3ZhbHVlLCAiYm9vbGVhbiJ9KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICBjYXNlIERUX05PTk5FR0lOVDoKLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgaWYgKHZhbHVlLmxlbmd0aCgpID4gMCAmJiB2YWx1ZS5jaGFyQXQoMCkgPT0gJysnKQotICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IHZhbHVlLnN1YnN0cmluZygxKTsKLSAgICAgICAgICAgICAgICByZXRWYWx1ZSA9IGZYSW50UG9vbC5nZXRYSW50KEludGVnZXIucGFyc2VJbnQodmFsdWUpKTsKLSAgICAgICAgICAgIH0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uKCJjdmMtZGF0YXR5cGUtdmFsaWQuMS4yLjEiLCBuZXcgT2JqZWN0W117dmFsdWUsICJub25OZWdhdGl2ZUludGVnZXIifSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoKChYSW50KXJldFZhbHVlKS5pbnRWYWx1ZSgpIDwgMCkKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24oImN2Yy1kYXRhdHlwZS12YWxpZC4xLjIuMSIsIG5ldyBPYmplY3RbXXt2YWx1ZSwgIm5vbk5lZ2F0aXZlSW50ZWdlciJ9KTsKLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICBjYXNlIERUX1BPU0lOVDoKLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgaWYgKHZhbHVlLmxlbmd0aCgpID4gMCAmJiB2YWx1ZS5jaGFyQXQoMCkgPT0gJysnKQotICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IHZhbHVlLnN1YnN0cmluZygxKTsKLSAgICAgICAgICAgICAgICByZXRWYWx1ZSA9IGZYSW50UG9vbC5nZXRYSW50KEludGVnZXIucGFyc2VJbnQodmFsdWUpKTsKLSAgICAgICAgICAgIH0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uKCJjdmMtZGF0YXR5cGUtdmFsaWQuMS4yLjEiLCBuZXcgT2JqZWN0W117dmFsdWUsICJwb3NpdGl2ZUludGVnZXIifSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoKChYSW50KXJldFZhbHVlKS5pbnRWYWx1ZSgpIDw9IDApCi0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uKCJjdmMtZGF0YXR5cGUtdmFsaWQuMS4yLjEiLCBuZXcgT2JqZWN0W117dmFsdWUsICJwb3NpdGl2ZUludGVnZXIifSk7Ci0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBEVF9CTE9DSzoKLSAgICAgICAgICAgIC8vIGJsb2NrID0gKCNhbGwgfCBMaXN0IG9mIChleHRlbnNpb24gfCByZXN0cmljdGlvbiB8IHN1YnN0aXR1dGlvbikpCi0gICAgICAgICAgICBjaG9pY2UgPSAwOwotICAgICAgICAgICAgaWYgKHZhbHVlLmVxdWFscyAoU2NoZW1hU3ltYm9scy5BVFRWQUxfUE9VTkRBTEwpKSB7Ci0gICAgICAgICAgICAgICAgY2hvaWNlID0gWFNDb25zdGFudHMuREVSSVZBVElPTl9TVUJTVElUVVRJT058WFNDb25zdGFudHMuREVSSVZBVElPTl9FWFRFTlNJT058Ci0gICAgICAgICAgICAgICAgICAgICAgICAgWFNDb25zdGFudHMuREVSSVZBVElPTl9SRVNUUklDVElPTjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIFN0cmluZ1Rva2VuaXplciB0ID0gbmV3IFN0cmluZ1Rva2VuaXplcih2YWx1ZSwgIiBcblx0XHIiKTsKLSAgICAgICAgICAgICAgICB3aGlsZSAodC5oYXNNb3JlVG9rZW5zKCkpIHsKLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHRva2VuID0gdC5uZXh0VG9rZW4gKCk7Ci0KLSAgICAgICAgICAgICAgICAgICAgaWYgKHRva2VuLmVxdWFscyAoU2NoZW1hU3ltYm9scy5BVFRWQUxfRVhURU5TSU9OKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgY2hvaWNlIHw9IFhTQ29uc3RhbnRzLkRFUklWQVRJT05fRVhURU5TSU9OOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHRva2VuLmVxdWFscyAoU2NoZW1hU3ltYm9scy5BVFRWQUxfUkVTVFJJQ1RJT04pKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBjaG9pY2UgfD0gWFNDb25zdGFudHMuREVSSVZBVElPTl9SRVNUUklDVElPTjsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICh0b2tlbi5lcXVhbHMgKFNjaGVtYVN5bWJvbHMuQVRUVkFMX1NVQlNUSVRVVElPTikpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGNob2ljZSB8PSBYU0NvbnN0YW50cy5ERVJJVkFUSU9OX1NVQlNUSVRVVElPTjsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbigiY3ZjLWRhdGF0eXBlLXZhbGlkLjEuMi4zIiwgbmV3IE9iamVjdFtde3ZhbHVlLCAiKCNhbGwgfCBMaXN0IG9mIChleHRlbnNpb24gfCByZXN0cmljdGlvbiB8IHN1YnN0aXR1dGlvbikpIn0pOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0VmFsdWUgPSBmWEludFBvb2wuZ2V0WEludChjaG9pY2UpOwotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgRFRfQkxPQ0sxOgotICAgICAgICBjYXNlIERUX0ZJTkFMOgotICAgICAgICAgICAgLy8gYmxvY2sgPSAoI2FsbCB8IExpc3Qgb2YgKGV4dGVuc2lvbiB8IHJlc3RyaWN0aW9uKSkKLSAgICAgICAgICAgIC8vIGZpbmFsID0gKCNhbGwgfCBMaXN0IG9mIChleHRlbnNpb24gfCByZXN0cmljdGlvbikpCi0gICAgICAgICAgICBjaG9pY2UgPSAwOwotICAgICAgICAgICAgaWYgKHZhbHVlLmVxdWFscyAoU2NoZW1hU3ltYm9scy5BVFRWQUxfUE9VTkRBTEwpKSB7Ci0gICAgICAgICAgICAgICAgLy9jaG9pY2UgPSBTY2hlbWFTeW1ib2xzLkVYVEVOU0lPTnxTY2hlbWFTeW1ib2xzLlJFU1RSSUNUSU9OOwotICAgICAgICAgICAgICAgIC8vIFJFVklTSVQ6IGlmICNhbGwsIHRoZW4gbWFrZSB0aGUgcmVzdWx0IHRoZSBjb21iaW5hdGlvbiBvZgotICAgICAgICAgICAgICAgIC8vICAgICAgICAgIGV2ZXJ5dGhpbmc6IHN1YnN0aXR1dGlvbi9leHRlcm5zaW9uL3Jlc3RyaWN0aW9uL2xpc3QvdW5pb24uCi0gICAgICAgICAgICAgICAgLy8gICAgICAgICAgd291bGQgdGhpcyBiZSBhIHByb2JsZW0/Ci0gICAgICAgICAgICAgICAgLy8gdGhlIHJlYXNvbiBkb2luZyBzbyBpcyB0aGF0IHdoZW4gZmluYWwvYmxvY2tGaW5hbCBvbiA8c2NoZW1hPgotICAgICAgICAgICAgICAgIC8vIGlzICNhbGwsIGl0J3Mgbm90IGFsd2F5cyB0aGUgc2FtZSBhcyB0aGUgY29uYmluYXRpb24gb2YgdGhvc2UKLSAgICAgICAgICAgICAgICAvLyB2YWx1ZXMgYWxsb3dlZCBieSBmaW5hbC9ibG9ja0ZpbmFsLgotICAgICAgICAgICAgICAgIC8vIGZvciBleGFtcGxlLCBmaW5hbERlZmF1bHQ9IiNhbGwiIGlzIG5vdCBhbHdheXMgdGhlIHNhbWUgYXMKLSAgICAgICAgICAgICAgICAvLyBmaW5hbERlZmF1bHQ9ImV4dGVuc2lvbiByZXN0cmljdGlvbiIuCi0gICAgICAgICAgICAgICAgLy8gaWYgZmluYWxEZWZhdWx0PSIjYWxsIiwgZmluYWwgb24gYW55IHNpbXBsZSB0eXBlIHdvdWxkIGJlCi0gICAgICAgICAgICAgICAgLy8gImV4dGVuc2lvbiByZXN0cmljdGlvbiBsaXN0IHVuaW9uIi4KLSAgICAgICAgICAgICAgICBjaG9pY2UgPSBYU0NvbnN0YW50cy5ERVJJVkFUSU9OX1NVQlNUSVRVVElPTnxYU0NvbnN0YW50cy5ERVJJVkFUSU9OX0VYVEVOU0lPTnwKLSAgICAgICAgICAgICAgICAgICAgICAgICBYU0NvbnN0YW50cy5ERVJJVkFUSU9OX1JFU1RSSUNUSU9OfFhTQ29uc3RhbnRzLkRFUklWQVRJT05fTElTVHwKLSAgICAgICAgICAgICAgICAgICAgICAgICBYU0NvbnN0YW50cy5ERVJJVkFUSU9OX1VOSU9OOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nVG9rZW5pemVyIHQgPSBuZXcgU3RyaW5nVG9rZW5pemVyKHZhbHVlLCAiIFxuXHRcciIpOwotICAgICAgICAgICAgICAgIHdoaWxlICh0Lmhhc01vcmVUb2tlbnMoKSkgewotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdG9rZW4gPSB0Lm5leHRUb2tlbiAoKTsKLQotICAgICAgICAgICAgICAgICAgICBpZiAodG9rZW4uZXF1YWxzIChTY2hlbWFTeW1ib2xzLkFUVFZBTF9FWFRFTlNJT04pKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBjaG9pY2UgfD0gWFNDb25zdGFudHMuREVSSVZBVElPTl9FWFRFTlNJT047Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAodG9rZW4uZXF1YWxzIChTY2hlbWFTeW1ib2xzLkFUVFZBTF9SRVNUUklDVElPTikpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGNob2ljZSB8PSBYU0NvbnN0YW50cy5ERVJJVkFUSU9OX1JFU1RSSUNUSU9OOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uKCJjdmMtZGF0YXR5cGUtdmFsaWQuMS4yLjMiLCBuZXcgT2JqZWN0W117dmFsdWUsICIoI2FsbCB8IExpc3Qgb2YgKGV4dGVuc2lvbiB8IHJlc3RyaWN0aW9uKSkifSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXRWYWx1ZSA9IGZYSW50UG9vbC5nZXRYSW50KGNob2ljZSk7Ci0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBEVF9GSU5BTDE6Ci0gICAgICAgICAgICAvLyBmaW5hbCA9ICgjYWxsIHwgTGlzdCBvZiAobGlzdCB8IHVuaW9uIHwgcmVzdHJpY3Rpb24pKQotICAgICAgICAgICAgY2hvaWNlID0gMDsKLSAgICAgICAgICAgIGlmICh2YWx1ZS5lcXVhbHMgKFNjaGVtYVN5bWJvbHMuQVRUVkFMX1BPVU5EQUxMKSkgewotICAgICAgICAgICAgICAgIC8vY2hvaWNlID0gU2NoZW1hU3ltYm9scy5SRVNUUklDVElPTnxTY2hlbWFTeW1ib2xzLkxJU1R8Ci0gICAgICAgICAgICAgICAgLy8gICAgICAgICBTY2hlbWFTeW1ib2xzLlVOSU9OOwotICAgICAgICAgICAgICAgIC8vIFJFVklTSVQ6IGlmICNhbGwsIHRoZW4gbWFrZSB0aGUgcmVzdWx0IHRoZSBjb21iaW5hdGlvbiBvZgotICAgICAgICAgICAgICAgIC8vICAgICAgICAgIGV2ZXJ5dGhpbmc6IHN1YnN0aXR1dGlvbi9leHRlcm5zaW9uL3Jlc3RyaWN0aW9uL2xpc3QvdW5pb24uCi0gICAgICAgICAgICAgICAgLy8gICAgICAgICAgd291bGQgdGhpcyBiZSBhIHByb2JsZW0/Ci0gICAgICAgICAgICAgICAgLy8gc2FtZSByZWFzb24gYXMgYWJvdmUgRFRfQkxPQ0sxL0RUX0ZJTkFMCi0gICAgICAgICAgICAgICAgY2hvaWNlID0gWFNDb25zdGFudHMuREVSSVZBVElPTl9TVUJTVElUVVRJT058WFNDb25zdGFudHMuREVSSVZBVElPTl9FWFRFTlNJT058Ci0gICAgICAgICAgICAgICAgICAgICAgICAgWFNDb25zdGFudHMuREVSSVZBVElPTl9SRVNUUklDVElPTnxYU0NvbnN0YW50cy5ERVJJVkFUSU9OX0xJU1R8Ci0gICAgICAgICAgICAgICAgICAgICAgICAgWFNDb25zdGFudHMuREVSSVZBVElPTl9VTklPTjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIFN0cmluZ1Rva2VuaXplciB0ID0gbmV3IFN0cmluZ1Rva2VuaXplcih2YWx1ZSwgIiBcblx0XHIiKTsKLSAgICAgICAgICAgICAgICB3aGlsZSAodC5oYXNNb3JlVG9rZW5zKCkpIHsKLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHRva2VuID0gdC5uZXh0VG9rZW4gKCk7Ci0KLSAgICAgICAgICAgICAgICAgICAgaWYgKHRva2VuLmVxdWFscyAoU2NoZW1hU3ltYm9scy5BVFRWQUxfTElTVCkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGNob2ljZSB8PSBYU0NvbnN0YW50cy5ERVJJVkFUSU9OX0xJU1Q7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAodG9rZW4uZXF1YWxzIChTY2hlbWFTeW1ib2xzLkFUVFZBTF9VTklPTikpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGNob2ljZSB8PSBYU0NvbnN0YW50cy5ERVJJVkFUSU9OX1VOSU9OOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHRva2VuLmVxdWFscyAoU2NoZW1hU3ltYm9scy5BVFRWQUxfUkVTVFJJQ1RJT04pKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBjaG9pY2UgfD0gWFNDb25zdGFudHMuREVSSVZBVElPTl9SRVNUUklDVElPTjsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbigiY3ZjLWRhdGF0eXBlLXZhbGlkLjEuMi4zIiwgbmV3IE9iamVjdFtde3ZhbHVlLCAiKCNhbGwgfCBMaXN0IG9mIChsaXN0IHwgdW5pb24gfCByZXN0cmljdGlvbikpIn0pOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0VmFsdWUgPSBmWEludFBvb2wuZ2V0WEludChjaG9pY2UpOwotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgRFRfRklOQUwyOgotICAgICAgICAgICAgLy8gZmluYWxEZWZhdWx0ID0gKCNhbGwgfCBMaXN0IG9mIChleHRlbnNpb24gfCByZXN0cmljdGlvbiB8IGxpc3QgfCB1bmlvbikpCi0gICAgICAgICAgICBjaG9pY2UgPSAwOwotICAgICAgICAgICAgaWYgKHZhbHVlLmVxdWFscyAoU2NoZW1hU3ltYm9scy5BVFRWQUxfUE9VTkRBTEwpKSB7Ci0gICAgICAgICAgICAgICAgLy9jaG9pY2UgPSBTY2hlbWFTeW1ib2xzLlJFU1RSSUNUSU9OfFNjaGVtYVN5bWJvbHMuTElTVHwKLSAgICAgICAgICAgICAgICAvLyAgICAgICAgIFNjaGVtYVN5bWJvbHMuVU5JT047Ci0gICAgICAgICAgICAgICAgLy8gUkVWSVNJVDogaWYgI2FsbCwgdGhlbiBtYWtlIHRoZSByZXN1bHQgdGhlIGNvbWJpbmF0aW9uIG9mCi0gICAgICAgICAgICAgICAgLy8gICAgICAgICAgZXZlcnl0aGluZzogc3Vic3RpdHV0aW9uL2V4dGVybnNpb24vcmVzdHJpY3Rpb24vbGlzdC91bmlvbi4KLSAgICAgICAgICAgICAgICAvLyAgICAgICAgICB3b3VsZCB0aGlzIGJlIGEgcHJvYmxlbT8KLSAgICAgICAgICAgICAgICAvLyBzYW1lIHJlYXNvbiBhcyBhYm92ZSBEVF9CTE9DSzEvRFRfRklOQUwKLSAgICAgICAgICAgICAgICBjaG9pY2UgPSBYU0NvbnN0YW50cy5ERVJJVkFUSU9OX1NVQlNUSVRVVElPTnxYU0NvbnN0YW50cy5ERVJJVkFUSU9OX0VYVEVOU0lPTnwKLSAgICAgICAgICAgICAgICAgICAgICAgICBYU0NvbnN0YW50cy5ERVJJVkFUSU9OX1JFU1RSSUNUSU9OfFhTQ29uc3RhbnRzLkRFUklWQVRJT05fTElTVHwKLSAgICAgICAgICAgICAgICAgICAgICAgICBYU0NvbnN0YW50cy5ERVJJVkFUSU9OX1VOSU9OOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nVG9rZW5pemVyIHQgPSBuZXcgU3RyaW5nVG9rZW5pemVyKHZhbHVlLCAiIFxuXHRcciIpOwotICAgICAgICAgICAgICAgIHdoaWxlICh0Lmhhc01vcmVUb2tlbnMoKSkgewotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdG9rZW4gPSB0Lm5leHRUb2tlbiAoKTsKLQotICAgICAgICAgICAgICAgICAgICBpZiAodG9rZW4uZXF1YWxzIChTY2hlbWFTeW1ib2xzLkFUVFZBTF9FWFRFTlNJT04pKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBjaG9pY2UgfD0gWFNDb25zdGFudHMuREVSSVZBVElPTl9FWFRFTlNJT047Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAodG9rZW4uZXF1YWxzIChTY2hlbWFTeW1ib2xzLkFUVFZBTF9SRVNUUklDVElPTikpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGNob2ljZSB8PSBYU0NvbnN0YW50cy5ERVJJVkFUSU9OX1JFU1RSSUNUSU9OOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHRva2VuLmVxdWFscyAoU2NoZW1hU3ltYm9scy5BVFRWQUxfTElTVCkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGNob2ljZSB8PSBYU0NvbnN0YW50cy5ERVJJVkFUSU9OX0xJU1Q7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAodG9rZW4uZXF1YWxzIChTY2hlbWFTeW1ib2xzLkFUVFZBTF9VTklPTikpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGNob2ljZSB8PSBYU0NvbnN0YW50cy5ERVJJVkFUSU9OX1VOSU9OOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uKCJjdmMtZGF0YXR5cGUtdmFsaWQuMS4yLjMiLCBuZXcgT2JqZWN0W117dmFsdWUsICIoI2FsbCB8IExpc3Qgb2YgKGV4dGVuc2lvbiB8IHJlc3RyaWN0aW9uIHwgbGlzdCB8IHVuaW9uKSkifSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXRWYWx1ZSA9IGZYSW50UG9vbC5nZXRYSW50KGNob2ljZSk7Ci0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBEVF9GT1JNOgotICAgICAgICAgICAgLy8gZm9ybSA9IChxdWFsaWZpZWQgfCB1bnF1YWxpZmllZCkKLSAgICAgICAgICAgIGlmICh2YWx1ZS5lcXVhbHMgKFNjaGVtYVN5bWJvbHMuQVRUVkFMX1FVQUxJRklFRCkpCi0gICAgICAgICAgICAgICAgcmV0VmFsdWUgPSBJTlRfUVVBTElGSUVEOwotICAgICAgICAgICAgZWxzZSBpZiAodmFsdWUuZXF1YWxzIChTY2hlbWFTeW1ib2xzLkFUVFZBTF9VTlFVQUxJRklFRCkpCi0gICAgICAgICAgICAgICAgcmV0VmFsdWUgPSBJTlRfVU5RVUFMSUZJRUQ7Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uKCJjdmMtZW51bWVyYXRpb24tdmFsaWQiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117dmFsdWUsICIocXVhbGlmaWVkIHwgdW5xdWFsaWZpZWQpIn0pOwotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgRFRfTUFYT0NDVVJTOgotICAgICAgICAgICAgLy8gbWF4T2NjdXJzID0gKG5vbk5lZ2F0aXZlSW50ZWdlciB8IHVuYm91bmRlZCkKLSAgICAgICAgICAgIGlmICh2YWx1ZS5lcXVhbHMoU2NoZW1hU3ltYm9scy5BVFRWQUxfVU5CT1VOREVEKSkgewotICAgICAgICAgICAgICAgIHJldFZhbHVlID0gSU5UX1VOQk9VTkRFRDsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgcmV0VmFsdWUgPSB2YWxpZGF0ZShhdHRyVmFsdWVzLCBhdHRyLCB2YWx1ZSwgRFRfTk9OTkVHSU5ULCBzY2hlbWFEb2MpOwotICAgICAgICAgICAgICAgIH0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbigiY3ZjLWRhdGF0eXBlLXZhbGlkLjEuMi4zIiwgbmV3IE9iamVjdFtde3ZhbHVlLCAiKG5vbk5lZ2F0aXZlSW50ZWdlciB8IHVuYm91bmRlZCkifSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgRFRfTUFYT0NDVVJTMToKLSAgICAgICAgICAgIC8vIG1heE9jY3VycyA9IDEKLSAgICAgICAgICAgIGlmICh2YWx1ZS5lcXVhbHMoIjEiKSkKLSAgICAgICAgICAgICAgICByZXRWYWx1ZSA9IGZYSW50UG9vbC5nZXRYSW50KDEpOwotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbigiY3ZjLWVudW1lcmF0aW9uLXZhbGlkIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde3ZhbHVlLCAiKDEpIn0pOwotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgRFRfTUVNQkVSVFlQRVM6Ci0gICAgICAgICAgICAvLyBtZW1iZXJUeXBlcyA9IExpc3Qgb2YgUU5hbWUKLSAgICAgICAgICAgIG1lbWJlclR5cGUgPSBuZXcgVmVjdG9yKCk7Ci0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIFN0cmluZ1Rva2VuaXplciB0ID0gbmV3IFN0cmluZ1Rva2VuaXplcih2YWx1ZSwgIiBcblx0XHIiKTsKLSAgICAgICAgICAgICAgICB3aGlsZSAodC5oYXNNb3JlVG9rZW5zKCkpIHsKLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHRva2VuID0gdC5uZXh0VG9rZW4gKCk7Ci0gICAgICAgICAgICAgICAgICAgIFFOYW1lIHFuYW1lID0gKFFOYW1lKWZFeHRyYURWc1tEVF9RTkFNRV0udmFsaWRhdGUodG9rZW4sIHNjaGVtYURvYy5mVmFsaWRhdGlvbkNvbnRleHQsIG51bGwpOwotICAgICAgICAgICAgICAgICAgICAvLyBrbHVkZ2UgdG8gaGFuZGxlIGNoYW1lbGVvbiBpbmNsdWRlcy9yZWRlZmluZXMuLi4KLSAgICAgICAgICAgICAgICAgICAgaWYocW5hbWUucHJlZml4ID09IFhNTFN5bWJvbHMuRU1QVFlfU1RSSU5HICYmIHFuYW1lLnVyaSA9PSBudWxsICYmIHNjaGVtYURvYy5mSXNDaGFtZWxlb25TY2hlbWEpCi0gICAgICAgICAgICAgICAgICAgICAgICBxbmFtZS51cmkgPSBzY2hlbWFEb2MuZlRhcmdldE5hbWVzcGFjZTsKLSAgICAgICAgICAgICAgICAgICAgbWVtYmVyVHlwZS5hZGRFbGVtZW50KHFuYW1lKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgcmV0VmFsdWUgPSBtZW1iZXJUeXBlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2F0Y2ggKEludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uIGlkZSkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbigiY3ZjLWRhdGF0eXBlLXZhbGlkLjEuMi4yIiwgbmV3IE9iamVjdFtde3ZhbHVlLCAiKExpc3Qgb2YgUU5hbWUpIn0pOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgRFRfTUlOT0NDVVJTMToKLSAgICAgICAgICAgIC8vIG1pbk9jY3VycyA9ICgwIHwgMSkKLSAgICAgICAgICAgIGlmICh2YWx1ZS5lcXVhbHMoIjAiKSkKLSAgICAgICAgICAgICAgICByZXRWYWx1ZSA9IGZYSW50UG9vbC5nZXRYSW50KDApOwotICAgICAgICAgICAgZWxzZSBpZiAodmFsdWUuZXF1YWxzKCIxIikpCi0gICAgICAgICAgICAgICAgcmV0VmFsdWUgPSBmWEludFBvb2wuZ2V0WEludCgxKTsKLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24oImN2Yy1lbnVtZXJhdGlvbi12YWxpZCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXt2YWx1ZSwgIigwIHwgMSkifSk7Ci0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBEVF9OQU1FU1BBQ0U6Ci0gICAgICAgICAgICAvLyBuYW1lc3BhY2UgPSAoKCMjYW55IHwgIyNvdGhlcikgfCBMaXN0IG9mIChhbnlVUkkgfCAoIyN0YXJnZXROYW1lc3BhY2UgfCAjI2xvY2FsKSkgKQotICAgICAgICAgICAgaWYgKHZhbHVlLmVxdWFscyhTY2hlbWFTeW1ib2xzLkFUVFZBTF9UV09QT1VOREFOWSkpIHsKLSAgICAgICAgICAgICAgICAvLyAjI2FueQotICAgICAgICAgICAgICAgIHJldFZhbHVlID0gSU5UX0FOWV9BTlk7Ci0gICAgICAgICAgICB9IGVsc2UgaWYgKHZhbHVlLmVxdWFscyhTY2hlbWFTeW1ib2xzLkFUVFZBTF9UV09QT1VORE9USEVSKSkgewotICAgICAgICAgICAgICAgIC8vICMjb3RoZXIKLSAgICAgICAgICAgICAgICByZXRWYWx1ZSA9IElOVF9BTllfTk9UOwotICAgICAgICAgICAgICAgIFN0cmluZ1tdIGxpc3QgPSBuZXcgU3RyaW5nWzJdOwotICAgICAgICAgICAgICAgIGxpc3RbMF0gPSBzY2hlbWFEb2MuZlRhcmdldE5hbWVzcGFjZTsKLSAgICAgICAgICAgICAgICBsaXN0WzFdID0gbnVsbDsKLSAgICAgICAgICAgICAgICBhdHRyVmFsdWVzW0FUVElEWF9OQU1FU1BBQ0VfTElTVF0gPSBsaXN0OwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAvLyBsaXN0Ci0gICAgICAgICAgICAgICAgcmV0VmFsdWUgPSBJTlRfQU5ZX0xJU1Q7Ci0KLSAgICAgICAgICAgICAgICBmTmFtZXNwYWNlTGlzdC5yZW1vdmVBbGxFbGVtZW50cygpOwotCi0gICAgICAgICAgICAgICAgLy8gdG9rZW5pemUKLSAgICAgICAgICAgICAgICBTdHJpbmdUb2tlbml6ZXIgdG9rZW5zID0gbmV3IFN0cmluZ1Rva2VuaXplcih2YWx1ZSwgIiBcblx0XHIiKTsKLSAgICAgICAgICAgICAgICBTdHJpbmcgdG9rZW47Ci0gICAgICAgICAgICAgICAgU3RyaW5nIHRlbXBOYW1lc3BhY2U7Ci0gICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHRva2Vucy5oYXNNb3JlVG9rZW5zKCkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHRva2VuID0gdG9rZW5zLm5leHRUb2tlbigpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRva2VuLmVxdWFscyhTY2hlbWFTeW1ib2xzLkFUVFZBTF9UV09QT1VORExPQ0FMKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXBOYW1lc3BhY2UgPSBudWxsOwotICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0b2tlbi5lcXVhbHMoU2NoZW1hU3ltYm9scy5BVFRWQUxfVFdPUE9VTkRUQVJHRVROUykpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wTmFtZXNwYWNlID0gc2NoZW1hRG9jLmZUYXJnZXROYW1lc3BhY2U7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHdlIGhhdmUgZm91bmQgbmFtZXNwYWNlIFVSSSBoZXJlCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbmVlZCB0byBhZGQgaXQgdG8gdGhlIHN5bWJvbCB0YWJsZQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZFeHRyYURWc1tEVF9BTllVUkldLnZhbGlkYXRlKHRva2VuLCBzY2hlbWFEb2MuZlZhbGlkYXRpb25Db250ZXh0LCBudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wTmFtZXNwYWNlID0gZlN5bWJvbFRhYmxlLmFkZFN5bWJvbCh0b2tlbik7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vY2hlY2sgZm9yIGR1cGxpY2F0ZSBuYW1lc3BhY2VzIGluIHRoZSBsaXN0Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWZOYW1lc3BhY2VMaXN0LmNvbnRhaW5zKHRlbXBOYW1lc3BhY2UpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZk5hbWVzcGFjZUxpc3QuYWRkRWxlbWVudCh0ZW1wTmFtZXNwYWNlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uIGlkZSkgewotICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24oImN2Yy1kYXRhdHlwZS12YWxpZC4xLjIuMyIsIG5ldyBPYmplY3RbXXt2YWx1ZSwgIigoIyNhbnkgfCAjI290aGVyKSB8IExpc3Qgb2YgKGFueVVSSSB8ICgjI3RhcmdldE5hbWVzcGFjZSB8ICMjbG9jYWwpKSApIn0pOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8vIGNvbnZlcnQgdGhlIHZlY3RvciB0byBhbiBhcnJheQotICAgICAgICAgICAgICAgIGludCBudW0gPSBmTmFtZXNwYWNlTGlzdC5zaXplKCk7Ci0gICAgICAgICAgICAgICAgU3RyaW5nW10gbGlzdCA9IG5ldyBTdHJpbmdbbnVtXTsKLSAgICAgICAgICAgICAgICBmTmFtZXNwYWNlTGlzdC5jb3B5SW50byhsaXN0KTsKLSAgICAgICAgICAgICAgICBhdHRyVmFsdWVzW0FUVElEWF9OQU1FU1BBQ0VfTElTVF0gPSBsaXN0OwotICAgICAgICAgICAgfQotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgRFRfUFJPQ0VTU0NPTlRFTlRTOgotICAgICAgICAgICAgLy8gcHJvY2Vzc0NvbnRlbnRzID0gKGxheCB8IHNraXAgfCBzdHJpY3QpCi0gICAgICAgICAgICBpZiAodmFsdWUuZXF1YWxzIChTY2hlbWFTeW1ib2xzLkFUVFZBTF9TVFJJQ1QpKQotICAgICAgICAgICAgICAgIHJldFZhbHVlID0gSU5UX0FOWV9TVFJJQ1Q7Ci0gICAgICAgICAgICBlbHNlIGlmICh2YWx1ZS5lcXVhbHMgKFNjaGVtYVN5bWJvbHMuQVRUVkFMX0xBWCkpCi0gICAgICAgICAgICAgICAgcmV0VmFsdWUgPSBJTlRfQU5ZX0xBWDsKLSAgICAgICAgICAgIGVsc2UgaWYgKHZhbHVlLmVxdWFscyAoU2NoZW1hU3ltYm9scy5BVFRWQUxfU0tJUCkpCi0gICAgICAgICAgICAgICAgcmV0VmFsdWUgPSBJTlRfQU5ZX1NLSVA7Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uKCJjdmMtZW51bWVyYXRpb24tdmFsaWQiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117dmFsdWUsICIobGF4IHwgc2tpcCB8IHN0cmljdCkifSk7Ci0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBEVF9VU0U6Ci0gICAgICAgICAgICAvLyB1c2UgPSAob3B0aW9uYWwgfCBwcm9oaWJpdGVkIHwgcmVxdWlyZWQpCi0gICAgICAgICAgICBpZiAodmFsdWUuZXF1YWxzIChTY2hlbWFTeW1ib2xzLkFUVFZBTF9PUFRJT05BTCkpCi0gICAgICAgICAgICAgICAgcmV0VmFsdWUgPSBJTlRfVVNFX09QVElPTkFMOwotICAgICAgICAgICAgZWxzZSBpZiAodmFsdWUuZXF1YWxzIChTY2hlbWFTeW1ib2xzLkFUVFZBTF9SRVFVSVJFRCkpCi0gICAgICAgICAgICAgICAgcmV0VmFsdWUgPSBJTlRfVVNFX1JFUVVJUkVEOwotICAgICAgICAgICAgZWxzZSBpZiAodmFsdWUuZXF1YWxzIChTY2hlbWFTeW1ib2xzLkFUVFZBTF9QUk9ISUJJVEVEKSkKLSAgICAgICAgICAgICAgICByZXRWYWx1ZSA9IElOVF9VU0VfUFJPSElCSVRFRDsKLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24oImN2Yy1lbnVtZXJhdGlvbi12YWxpZCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXt2YWx1ZSwgIihvcHRpb25hbCB8IHByb2hpYml0ZWQgfCByZXF1aXJlZCkifSk7Ci0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBEVF9XSElURVNQQUNFOgotICAgICAgICAgICAgLy8gdmFsdWUgPSBwcmVzZXJ2ZSB8IHJlcGxhY2UgfCBjb2xsYXBzZQotICAgICAgICAgICAgaWYgKHZhbHVlLmVxdWFscyAoU2NoZW1hU3ltYm9scy5BVFRWQUxfUFJFU0VSVkUpKQotICAgICAgICAgICAgICAgIHJldFZhbHVlID0gSU5UX1dTX1BSRVNFUlZFOwotICAgICAgICAgICAgZWxzZSBpZiAodmFsdWUuZXF1YWxzIChTY2hlbWFTeW1ib2xzLkFUVFZBTF9SRVBMQUNFKSkKLSAgICAgICAgICAgICAgICByZXRWYWx1ZSA9IElOVF9XU19SRVBMQUNFOwotICAgICAgICAgICAgZWxzZSBpZiAodmFsdWUuZXF1YWxzIChTY2hlbWFTeW1ib2xzLkFUVFZBTF9DT0xMQVBTRSkpCi0gICAgICAgICAgICAgICAgcmV0VmFsdWUgPSBJTlRfV1NfQ09MTEFQU0U7Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uKCJjdmMtZW51bWVyYXRpb24tdmFsaWQiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117dmFsdWUsICIocHJlc2VydmUgfCByZXBsYWNlIHwgY29sbGFwc2UpIn0pOwotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gcmV0VmFsdWU7Ci0gICAgfQotCi0gICAgdm9pZCByZXBvcnRTY2hlbWFGYXRhbEVycm9yIChTdHJpbmcga2V5LCBPYmplY3RbXSBhcmdzLCBFbGVtZW50IGVsZSkgewotICAgICAgICBmU2NoZW1hSGFuZGxlci5yZXBvcnRTY2hlbWFGYXRhbEVycm9yKGtleSwgYXJncywgZWxlKTsKLSAgICB9Ci0KLSAgICB2b2lkIHJlcG9ydFNjaGVtYUVycm9yIChTdHJpbmcga2V5LCBPYmplY3RbXSBhcmdzLCBFbGVtZW50IGVsZSkgewotICAgICAgICBmU2NoZW1hSGFuZGxlci5yZXBvcnRTY2hlbWFFcnJvcihrZXksIGFyZ3MsIGVsZSk7Ci0gICAgfQotCi0gICAgLy8gdmFsaWRhdGUgYXR0cml1YnRlcyBmcm9tIG5vbi1zY2hlbWEgbmFtZXNwYWNlcwotICAgIC8vIFJFVklTSVQ6IHdoeSB3ZSBzdG9yZSB0aGUgYXR0cmlidXRlcyBpbiB0aGlzIHdheT8gd2h5IG5vdCBqdXN0IGEgbGlzdAotICAgIC8vICAgICAgICAgIG9mIHN0cnVjdHVyZSB7ZWxlbWVudCBub2RlLCBhdHRyIG5hbWUvcW5hbWUsIGF0dHIgdmFsdWUpPwotICAgIC8vIFJFVklTSVQ6IHBhc3MgdGhlIHByb3BlciBlbGVtZW50IG5vZGUgdG8gcmVwb3J0U2NoZW1hRXJyb3IKLSAgICBwdWJsaWMgdm9pZCBjaGVja05vblNjaGVtYUF0dHJpYnV0ZXMoWFNHcmFtbWFyQnVja2V0IGdyYW1tYXJCdWNrZXQpIHsKLSAgICAgICAgLy8gZm9yIGFsbCBhdHRyaWJ1dGVzCi0gICAgICAgIEl0ZXJhdG9yIGVudHJpZXMgPSBmTm9uU2NoZW1hQXR0cnMuZW50cnlTZXQoKS5pdGVyYXRvcigpOwotICAgICAgICBYU0F0dHJpYnV0ZURlY2wgYXR0ckRlY2w7Ci0gICAgICAgIHdoaWxlIChlbnRyaWVzLmhhc05leHQoKSkgewotICAgICAgICAgICAgTWFwLkVudHJ5IGVudHJ5ID0gKE1hcC5FbnRyeSkgZW50cmllcy5uZXh0KCk7Ci0gICAgICAgICAgICAvLyBnZXQgbmFtZSwgdXJpLCBsb2NhbHBhcnQKLSAgICAgICAgICAgIFN0cmluZyBhdHRyUk5hbWUgPSAoU3RyaW5nKSBlbnRyeS5nZXRLZXkoKTsKLSAgICAgICAgICAgIFN0cmluZyBhdHRyVVJJID0gYXR0clJOYW1lLnN1YnN0cmluZygwLGF0dHJSTmFtZS5pbmRleE9mKCcsJykpOwotICAgICAgICAgICAgU3RyaW5nIGF0dHJMb2NhbCA9IGF0dHJSTmFtZS5zdWJzdHJpbmcoYXR0clJOYW1lLmluZGV4T2YoJywnKSsxKTsKLSAgICAgICAgICAgIC8vIGZpbmQgYXNzb2NpYXRlZCBncmFtbWFyCi0gICAgICAgICAgICBTY2hlbWFHcmFtbWFyIHNHcmFtbWFyID0gZ3JhbW1hckJ1Y2tldC5nZXRHcmFtbWFyKGF0dHJVUkkpOwotICAgICAgICAgICAgaWYgKHNHcmFtbWFyID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIGFuZCBnZXQgdGhlIGRhdGF0eXBlIHZhbGlkYXRvciwgaWYgdGhlcmUgaXMgb25lCi0gICAgICAgICAgICBhdHRyRGVjbCA9IHNHcmFtbWFyLmdldEdsb2JhbEF0dHJpYnV0ZURlY2woYXR0ckxvY2FsKTsKLSAgICAgICAgICAgIGlmIChhdHRyRGVjbCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBYU1NpbXBsZVR5cGUgZHYgPSAoWFNTaW1wbGVUeXBlKWF0dHJEZWNsLmdldFR5cGVEZWZpbml0aW9uKCk7Ci0gICAgICAgICAgICBpZiAoZHYgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBnZXQgYWxsIHZhbHVlcyBhcHBlYXJlZCB3aXRoIHRoaXMgYXR0cmlidXRlIG5hbWUKLSAgICAgICAgICAgIFZlY3RvciB2YWx1ZXMgPSAoVmVjdG9yKSBlbnRyeS5nZXRWYWx1ZSgpOwotICAgICAgICAgICAgU3RyaW5nIGVsTmFtZTsKLSAgICAgICAgICAgIFN0cmluZyBhdHRyTmFtZSA9IChTdHJpbmcpdmFsdWVzLmVsZW1lbnRBdCgwKTsKLSAgICAgICAgICAgIC8vIGZvciBlYWNoIG9mIHRoZSB2YWx1ZXMKLSAgICAgICAgICAgIGludCBjb3VudCA9IHZhbHVlcy5zaXplKCk7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMTsgaSA8IGNvdW50OyBpICs9IDIpIHsKLSAgICAgICAgICAgICAgICBlbE5hbWUgPSAoU3RyaW5nKXZhbHVlcy5lbGVtZW50QXQoaSk7Ci0gICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgLy8gYW5kIHZhbGlkYXRlIGl0IHVzaW5nIHRoZSBYU1NpbXBsZVR5cGUKLSAgICAgICAgICAgICAgICAgICAgLy8gUkVWSVNJVDogd2hhdCB3b3VsZCBiZSB0aGUgcHJvcGVyIHZhbGlkYXRpb24gY29udGV4dD8KLSAgICAgICAgICAgICAgICAgICAgLy8gICAgICAgICAgZ3Vlc3Mgd2UgbmVlZCB0byBzYXZlIHRoYXQgaW4gdGhlIHZlY3RvcnMgdG9vLgotICAgICAgICAgICAgICAgICAgICBkdi52YWxpZGF0ZSgoU3RyaW5nKXZhbHVlcy5lbGVtZW50QXQoaSsxKSwgbnVsbCwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgfSBjYXRjaChJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbiBpZGUpIHsKLSAgICAgICAgICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IgKCJzNHMtYXR0LWludmFsaWQtdmFsdWUiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHtlbE5hbWUsIGF0dHJOYW1lLCBpZGUuZ2V0TWVzc2FnZSgpfSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIC8vIG5vcm1hbGl6ZSB0aGUgc3RyaW5nIGFjY29yZGluZyB0byB0aGUgd2hpdGVTcGFjZSBmYWNldAotICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIG5vcm1hbGl6ZShTdHJpbmcgY29udGVudCwgc2hvcnQgd3MpIHsKLSAgICAgICAgaW50IGxlbiA9IGNvbnRlbnQgPT0gbnVsbCA/IDAgOiBjb250ZW50Lmxlbmd0aCgpOwotICAgICAgICBpZiAobGVuID09IDAgfHwgd3MgPT0gWFNTaW1wbGVUeXBlLldTX1BSRVNFUlZFKQotICAgICAgICAgICAgcmV0dXJuIGNvbnRlbnQ7Ci0KLSAgICAgICAgU3RyaW5nQnVmZmVyIHNiID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotICAgICAgICBpZiAod3MgPT0gWFNTaW1wbGVUeXBlLldTX1JFUExBQ0UpIHsKLSAgICAgICAgICAgIGNoYXIgY2g7Ci0gICAgICAgICAgICAvLyB3aGVuIGl0J3MgcmVwbGFjZSwganVzdCByZXBsYWNlICN4OSwgI3hhLCAjeGQgYnkgI3gyMAotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW47IGkrKykgewotICAgICAgICAgICAgICAgIGNoID0gY29udGVudC5jaGFyQXQoaSk7Ci0gICAgICAgICAgICAgICAgaWYgKGNoICE9IDB4OSAmJiBjaCAhPSAweGEgJiYgY2ggIT0gMHhkKQotICAgICAgICAgICAgICAgICAgICBzYi5hcHBlbmQoY2gpOwotICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgICAgc2IuYXBwZW5kKChjaGFyKTB4MjApOwotICAgICAgICAgICAgfQotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgY2hhciBjaDsKLSAgICAgICAgICAgIGludCBpOwotICAgICAgICAgICAgYm9vbGVhbiBpc0xlYWRpbmcgPSB0cnVlOwotICAgICAgICAgICAgLy8gd2hlbiBpdCdzIGNvbGxhcHNlCi0gICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKLSAgICAgICAgICAgICAgICBjaCA9IGNvbnRlbnQuY2hhckF0KGkpOwotICAgICAgICAgICAgICAgIC8vIGFwcGVuZCByZWFsIGNoYXJhY3RlcnMsIHNvIHdlIHBhc3NlZCBsZWFkaW5nIHdzCi0gICAgICAgICAgICAgICAgaWYgKGNoICE9IDB4OSAmJiBjaCAhPSAweGEgJiYgY2ggIT0gMHhkICYmIGNoICE9IDB4MjApIHsKLSAgICAgICAgICAgICAgICAgICAgc2IuYXBwZW5kKGNoKTsKLSAgICAgICAgICAgICAgICAgICAgaXNMZWFkaW5nID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAvLyBmb3Igd2hpdGVzcGFjZXMsIHdlIHNraXAgYWxsIGZvbGxvd2luZyB3cwotICAgICAgICAgICAgICAgICAgICBmb3IgKDsgaSA8IGxlbi0xOyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGNoID0gY29udGVudC5jaGFyQXQoaSsxKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjaCAhPSAweDkgJiYgY2ggIT0gMHhhICYmIGNoICE9IDB4ZCAmJiBjaCAhPSAweDIwKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIC8vIGlmIGl0J3Mgbm90IGEgbGVhZGluZyBvciB0YWlsaW5nIHdzLCB0aGVuIGFwcGVuZCBhIHNwYWNlCi0gICAgICAgICAgICAgICAgICAgIGlmIChpIDwgbGVuIC0gMSAmJiAhaXNMZWFkaW5nKQotICAgICAgICAgICAgICAgICAgICAgICAgc2IuYXBwZW5kKChjaGFyKTB4MjApOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBzYi50b1N0cmluZygpOwotICAgIH0KLQotICAgIC8vIHRoZSBmb2xsb3dpbmcgcGFydCBpbXBsZW1lbnRzIGFuIGF0dHJpYnV0ZS12YWx1ZS1hcnJheSBwb29sLgotICAgIC8vIHdoZW4gY2hlY2tBdHRyaWJ1dGUgaXMgY2FsbGVkLCBpdCBjYWxscyBnZXRBdmFpbGFibGVBcnJheSB0byBnZXQKLSAgICAvLyBhbiBhcnJheSBmcm9tIHRoZSBwb29sOyB3aGVuIHRoZSBjYWxsZXIgaXMgZG9uZSB3aXRoIHRoZSBhcnJheSwKLSAgICAvLyBpdCBjYWxscyByZXR1cm5BdHRyQXJyYXkgdG8gcmV0dXJuIHRoYXQgYXJyYXkgdG8gdGhlIHBvb2wuCi0KLSAgICAvLyBpbml0aWFsIHNpemUgb2YgdGhlIGFycmF5IHBvb2wuIDEwIGlzIGJpZyBlbm91Z2gKLSAgICBzdGF0aWMgZmluYWwgaW50IElOSVRfUE9PTF9TSVpFID0gMTA7Ci0gICAgLy8gdGhlIGluY3JlbWVudGFsIHNpemUgb2YgdGhlIGFycmF5IHBvb2wKLSAgICBzdGF0aWMgZmluYWwgaW50IElOQ19QT09MX1NJWkUgID0gMTA7Ci0gICAgLy8gdGhlIGFycmF5IHBvb2wKLSAgICBPYmplY3RbXVtdIGZBcnJheVBvb2wgPSBuZXcgT2JqZWN0W0lOSVRfUE9PTF9TSVpFXVtBVFRJRFhfQ09VTlRdOwotICAgIC8vIHVzZWQgdG8gY2xlYXIgdGhlIHJldHVybmVkIGFycmF5Ci0gICAgLy8gSSB0aGluayBTeXN0ZW0uYXJyYXlDb3B5IGlzIG1vcmUgZWZmaWNpZW50IHRoYW4gc2V0dGluZyAzNSBmaWVsZHMgdG8gbnVsbAotICAgIHByaXZhdGUgc3RhdGljIE9iamVjdFtdIGZUZW1wQXJyYXkgPSBuZXcgT2JqZWN0W0FUVElEWF9DT1VOVF07Ci0gICAgLy8gY3VycmVudCBwb3NpdGlvbiBvZiB0aGUgYXJyYXkgcG9vbCAoIyBvZiBhcnJheXMgbm90IHJldHVybmVkKQotICAgIGludCBmUG9vbFBvcyA9IDA7Ci0KLSAgICAvLyBnZXQgdGhlIG5leHQgYXZhaWxhYmxlIGFycmF5Ci0gICAgcHJvdGVjdGVkIE9iamVjdFtdIGdldEF2YWlsYWJsZUFycmF5KCkgewotICAgICAgICAvLyBpZiBubyBhcnJheSBsZWZ0IGluIHRoZSBwb29sLCBpbmNyZWFzZSB0aGUgcG9vbCBzaXplCi0gICAgICAgIGlmIChmQXJyYXlQb29sLmxlbmd0aCA9PSBmUG9vbFBvcykgewotICAgICAgICAgICAgLy8gaW5jcmVhc2Ugc2l6ZQotICAgICAgICAgICAgZkFycmF5UG9vbCA9IG5ldyBPYmplY3RbZlBvb2xQb3MrSU5DX1BPT0xfU0laRV1bXTsKLSAgICAgICAgICAgIC8vIGluaXRpYWxpemUgZWFjaCAqbmV3KiBhcnJheQotICAgICAgICAgICAgZm9yIChpbnQgaSA9IGZQb29sUG9zOyBpIDwgZkFycmF5UG9vbC5sZW5ndGg7IGkrKykKLSAgICAgICAgICAgICAgICBmQXJyYXlQb29sW2ldID0gbmV3IE9iamVjdFtBVFRJRFhfQ09VTlRdOwotICAgICAgICB9Ci0gICAgICAgIC8vIGdldCB0aGUgbmV4dCBhdmFpbGFibGUgb25lCi0gICAgICAgIE9iamVjdFtdIHJldEFycmF5ID0gZkFycmF5UG9vbFtmUG9vbFBvc107Ci0gICAgICAgIC8vIGNsZWFyIGl0IGZyb20gdGhlIHBvb2wuIHRoaXMgaXMgZm9yIEdDOiBpZiBhIGNhbGxlciBmb3JnZXQgdG8KLSAgICAgICAgLy8gcmV0dXJuIHRoZSBhcnJheSwgd2Ugd2FudCB0aGF0IGFycmF5IHRvIGJlIEdDZWQuCi0gICAgICAgIGZBcnJheVBvb2xbZlBvb2xQb3MrK10gPSBudWxsOwotICAgICAgICAvLyB0byBtYWtlIHN1cmUgdGhhdCBvbmUgYXJyYXkgaXMgbm90IHJldHVybmVkIHR3aWNlLCB3ZSB1c2UKLSAgICAgICAgLy8gdGhlIGxhc3QgZW50cnkgdG8gaW5kaWNhdGUgd2hldGhlciBhbiBhcnJheSBpcyBhbHJlYWR5IHJldHVybmVkCi0gICAgICAgIC8vIG5vdyBzZXQgaXQgdG8gZmFsc2UuCi0gICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZlRlbXBBcnJheSwgMCwgcmV0QXJyYXksIDAsIEFUVElEWF9DT1VOVC0xKTsKLSAgICAgICAgcmV0QXJyYXlbQVRUSURYX0lTUkVUVVJORURdID0gQm9vbGVhbi5GQUxTRTsKLQotICAgICAgICByZXR1cm4gcmV0QXJyYXk7Ci0gICAgfQotCi0gICAgLy8gcmV0dXJuIGFuIGFycmF5IGJhY2sgdG8gdGhlIHBvb2wKLSAgICBwdWJsaWMgdm9pZCByZXR1cm5BdHRyQXJyYXkoT2JqZWN0W10gYXR0ckFycmF5LCBYU0RvY3VtZW50SW5mbyBzY2hlbWFEb2MpIHsKLSAgICAgICAgLy8gcG9wIHRoZSBuYW1lc3BhY2UgY29udGV4dAotICAgICAgICBpZiAoc2NoZW1hRG9jICE9IG51bGwpCi0gICAgICAgICAgICBzY2hlbWFEb2MuZk5hbWVzcGFjZVN1cHBvcnQucG9wQ29udGV4dCgpOwotCi0gICAgICAgIC8vIGlmIDEuIHRoZSBwb29sIGlzIGZ1bGw7IDIuIHRoZSBhcnJheSBpcyBudWxsOwotICAgICAgICAvLyAzLiB0aGUgYXJyYXkgaXMgb2Ygd3Jvbmcgc2l6ZTsgNC4gdGhlIGFycmF5IGlzIGFscmVhZHkgcmV0dXJuZWQKLSAgICAgICAgLy8gdGhlbiB3ZSBjYW4ndCBhY2NlcHQgdGhpcyBhcnJheSB0byBiZSByZXR1cm5lZAotICAgICAgICBpZiAoZlBvb2xQb3MgPT0gMCB8fAotICAgICAgICAgICAgYXR0ckFycmF5ID09IG51bGwgfHwKLSAgICAgICAgICAgIGF0dHJBcnJheS5sZW5ndGggIT0gQVRUSURYX0NPVU5UIHx8Ci0gICAgICAgICAgICAoKEJvb2xlYW4pYXR0ckFycmF5W0FUVElEWF9JU1JFVFVSTkVEXSkuYm9vbGVhblZhbHVlKCkpIHsKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIG1hcmsgdGhpcyBhcnJheSBhcyByZXR1cm5lZAotICAgICAgICBhdHRyQXJyYXlbQVRUSURYX0lTUkVUVVJORURdID0gQm9vbGVhbi5UUlVFOwotICAgICAgICAvLyBiZXR0ZXIgY2xlYXIgbm9uc2NoZW1hIHZlY3RvcgotICAgICAgICBpZihhdHRyQXJyYXlbQVRUSURYX05PTlNDSEVNQV0gIT0gbnVsbCkKLSAgICAgICAgICAgICgoVmVjdG9yKWF0dHJBcnJheVtBVFRJRFhfTk9OU0NIRU1BXSkuY2xlYXIoKTsKLSAgICAgICAgLy8gYW5kIHB1dCBpdCBpbnRvIHRoZSBwb29sCi0gICAgICAgIGZBcnJheVBvb2xbLS1mUG9vbFBvc10gPSBhdHRyQXJyYXk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgcmVzb2x2ZU5hbWVzcGFjZShFbGVtZW50IGVsZW1lbnQsIEF0dHJbXSBhdHRycywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNjaGVtYU5hbWVzcGFjZVN1cHBvcnQgbnNTdXBwb3J0KSB7Ci0gICAgICAgIC8vIHB1c2ggdGhlIG5hbWVzcGFjZSBjb250ZXh0Ci0gICAgICAgIG5zU3VwcG9ydC5wdXNoQ29udGV4dCgpOwotCi0gICAgICAgIC8vIHNlYXJjaCBmb3IgbmV3IG5hbWVzcGFjZSBiaW5kaW5ncwotICAgICAgICBpbnQgbGVuZ3RoID0gYXR0cnMubGVuZ3RoOwotICAgICAgICBBdHRyIHNhdHRyID0gbnVsbDsKLSAgICAgICAgU3RyaW5nIHJhd25hbWUsIHByZWZpeCwgdXJpOwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICBzYXR0ciA9IGF0dHJzW2ldOwotICAgICAgICAgICAgcmF3bmFtZSA9IERPTVV0aWwuZ2V0TmFtZShzYXR0cik7Ci0gICAgICAgICAgICBwcmVmaXggPSBudWxsOwotICAgICAgICAgICAgaWYgKHJhd25hbWUuZXF1YWxzKFhNTFN5bWJvbHMuUFJFRklYX1hNTE5TKSkKLSAgICAgICAgICAgICAgICBwcmVmaXggPSBYTUxTeW1ib2xzLkVNUFRZX1NUUklORzsKLSAgICAgICAgICAgIGVsc2UgaWYgKHJhd25hbWUuc3RhcnRzV2l0aCgieG1sbnM6IikpCi0gICAgICAgICAgICAgICAgcHJlZml4ID0gZlN5bWJvbFRhYmxlLmFkZFN5bWJvbChET01VdGlsLmdldExvY2FsTmFtZShzYXR0cikpOwotICAgICAgICAgICAgaWYgKHByZWZpeCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgdXJpID0gZlN5bWJvbFRhYmxlLmFkZFN5bWJvbChET01VdGlsLmdldFZhbHVlKHNhdHRyKSk7Ci0gICAgICAgICAgICAgICAgbnNTdXBwb3J0LmRlY2xhcmVQcmVmaXgocHJlZml4LCB1cmkubGVuZ3RoKCkhPTAgPyB1cmkgOiBudWxsKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLX0KLQotY2xhc3MgT25lQXR0ciB7Ci0gICAgLy8gbmFtZSBvZiB0aGUgYXR0cmlidXRlCi0gICAgcHVibGljIFN0cmluZyBuYW1lOwotICAgIC8vIGluZGV4IG9mIHRoZSBkYXRhdHlwZSB2YWxpZGF0b3IKLSAgICBwdWJsaWMgaW50IGR2SW5kZXg7Ci0gICAgLy8gd2hldGhlciBpdCdzIG9wdGlvbmFsLCBhbmQgaGFzIGRlZmF1bHQgdmFsdWUKLSAgICBwdWJsaWMgaW50IHZhbHVlSW5kZXg7Ci0gICAgLy8gdGhlIGRlZmF1bHQgdmFsdWUgb2YgdGhpcyBhdHRyaWJ1dGUKLSAgICBwdWJsaWMgT2JqZWN0IGRmbHRWYWx1ZTsKLQotICAgIHB1YmxpYyBPbmVBdHRyKFN0cmluZyBuYW1lLCBpbnQgZHZJbmRleCwgaW50IHZhbHVlSW5kZXgsIE9iamVjdCBkZmx0VmFsdWUpIHsKLSAgICAgICAgdGhpcy5uYW1lID0gbmFtZTsKLSAgICAgICAgdGhpcy5kdkluZGV4ID0gZHZJbmRleDsKLSAgICAgICAgdGhpcy52YWx1ZUluZGV4ID0gdmFsdWVJbmRleDsKLSAgICAgICAgdGhpcy5kZmx0VmFsdWUgPSBkZmx0VmFsdWU7Ci0gICAgfQotfQotCi1hYnN0cmFjdCBjbGFzcyBDb250YWluZXIgewotICAgIHN0YXRpYyBmaW5hbCBpbnQgVEhSRVNIT0xEID0gNTsKLSAgICBzdGF0aWMgQ29udGFpbmVyIGdldENvbnRhaW5lcihpbnQgc2l6ZSkgewotICAgICAgICBpZiAoc2l6ZSA+IFRIUkVTSE9MRCkKLSAgICAgICAgICAgIHJldHVybiBuZXcgTGFyZ2VDb250YWluZXIoc2l6ZSk7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICAgIHJldHVybiBuZXcgU21hbGxDb250YWluZXIoc2l6ZSk7Ci0gICAgfQotICAgIGFic3RyYWN0IHZvaWQgcHV0KFN0cmluZyBrZXksIE9uZUF0dHIgdmFsdWUpOwotICAgIGFic3RyYWN0IE9uZUF0dHIgZ2V0KFN0cmluZyBrZXkpOwotCi0gICAgT25lQXR0cltdIHZhbHVlczsKLSAgICBpbnQgcG9zID0gMDsKLX0KLQotY2xhc3MgU21hbGxDb250YWluZXIgZXh0ZW5kcyBDb250YWluZXIgewotICAgIFN0cmluZ1tdIGtleXM7Ci0gICAgU21hbGxDb250YWluZXIoaW50IHNpemUpIHsKLSAgICAgICAga2V5cyA9IG5ldyBTdHJpbmdbc2l6ZV07Ci0gICAgICAgIHZhbHVlcyA9IG5ldyBPbmVBdHRyW3NpemVdOwotICAgIH0KLSAgICB2b2lkIHB1dChTdHJpbmcga2V5LCBPbmVBdHRyIHZhbHVlKSB7Ci0gICAgICAgIGtleXNbcG9zXSA9IGtleTsKLSAgICAgICAgdmFsdWVzW3BvcysrXSA9IHZhbHVlOwotICAgIH0KLSAgICBPbmVBdHRyIGdldChTdHJpbmcga2V5KSB7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcG9zOyBpKyspIHsKLSAgICAgICAgICAgIGlmIChrZXlzW2ldLmVxdWFscyhrZXkpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlc1tpXTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci19Ci0KLWNsYXNzIExhcmdlQ29udGFpbmVyIGV4dGVuZHMgQ29udGFpbmVyIHsKLSAgICBNYXAgaXRlbXM7Ci0gICAgTGFyZ2VDb250YWluZXIoaW50IHNpemUpIHsKLSAgICAgICAgaXRlbXMgPSBuZXcgSGFzaE1hcChzaXplKjIrMSk7Ci0gICAgICAgIHZhbHVlcyA9IG5ldyBPbmVBdHRyW3NpemVdOwotICAgIH0KLSAgICB2b2lkIHB1dChTdHJpbmcga2V5LCBPbmVBdHRyIHZhbHVlKSB7Ci0gICAgICAgIGl0ZW1zLnB1dChrZXksIHZhbHVlKTsKLSAgICAgICAgdmFsdWVzW3BvcysrXSA9IHZhbHVlOwotICAgIH0KLSAgICBPbmVBdHRyIGdldChTdHJpbmcga2V5KSB7Ci0gICAgICAgIE9uZUF0dHIgcmV0ID0gKE9uZUF0dHIpaXRlbXMuZ2V0KGtleSk7Ci0gICAgICAgIHJldHVybiByZXQ7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy90cmF2ZXJzZXJzL1hTREFic3RyYWN0SURDb25zdHJhaW50VHJhdmVyc2VyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL3RyYXZlcnNlcnMvWFNEQWJzdHJhY3RJRENvbnN0cmFpbnRUcmF2ZXJzZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYzY0NTUyMy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL3RyYXZlcnNlcnMvWFNEQWJzdHJhY3RJRENvbnN0cmFpbnRUcmF2ZXJzZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE5NCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy50cmF2ZXJzZXJzOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhwYXRoLlhQYXRoRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5TY2hlbWFTeW1ib2xzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5pZGVudGl0eS5GaWVsZDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMuaWRlbnRpdHkuSWRlbnRpdHlDb25zdHJhaW50OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5pZGVudGl0eS5TZWxlY3RvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuRE9NVXRpbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuWE1MQ2hhcjsKLWltcG9ydCBvcmcudzNjLmRvbS5FbGVtZW50OwotCi0vKioKLSAqIFRoaXMgY2xhc3MgY29udGFpbnMgY29kZSB0aGF0IGFsbCB0aHJlZSBJZGVudGl0eUNvbnN0cmFpbnQKLSAqIHRyYXZlcnNlcnMgKHRoZSBYU0RVbmlxdWVUcmF2ZXJzZXIsIFhTREtleVRyYXZlcnNlciBhbmQKLSAqIFhTREtleXJlZlRyYXZlcnNlcikgcmVseSB1cG9uLgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAdmVyc2lvbiAkSWQ6IFhTREFic3RyYWN0SURDb25zdHJhaW50VHJhdmVyc2VyLmphdmEsdiAxLjcgMjAxMC0xMS0wMSAwNDo0MDowMiBqb2VodyBFeHAgJAotICovCi1jbGFzcyBYU0RBYnN0cmFjdElEQ29uc3RyYWludFRyYXZlcnNlciBleHRlbmRzIFhTREFic3RyYWN0VHJhdmVyc2VyIHsKLQotICAgIHB1YmxpYyBYU0RBYnN0cmFjdElEQ29uc3RyYWludFRyYXZlcnNlciAoWFNESGFuZGxlciBoYW5kbGVyLAotICAgICAgICAgICAgWFNBdHRyaWJ1dGVDaGVja2VyIGdBdHRyQ2hlY2spIHsKLSAgICAgICAgc3VwZXIoaGFuZGxlciwgZ0F0dHJDaGVjayk7Ci0gICAgfQotCi0gICAgYm9vbGVhbiB0cmF2ZXJzZUlkZW50aXR5Q29uc3RyYWludChJZGVudGl0eUNvbnN0cmFpbnQgaWMsCi0gICAgICAgICAgICBFbGVtZW50IGljRWxlbSwgWFNEb2N1bWVudEluZm8gc2NoZW1hRG9jLCBPYmplY3QgW10gaWNFbGVtQXR0cnMpIHsKLQotICAgICAgICAvLyBHZW5lcmFsIEF0dHJpYnV0ZSBDaGVja2luZyB3aWxsIGhhdmUgYmVlbiBkb25lIG9uIGljRWxlbSBieSBjYWxsZXIKLQotICAgICAgICAvLyBjaGVjayBmb3IgPGFubm90YXRpb24+IGFuZCBnZXQgc2VsZWN0b3IKLSAgICAgICAgRWxlbWVudCBzRWxlbSA9IERPTVV0aWwuZ2V0Rmlyc3RDaGlsZEVsZW1lbnQoaWNFbGVtKTsKLSAgICAgICAgaWYoc0VsZW0gPT0gbnVsbCkgewotICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoInM0cy1lbHQtbXVzdC1tYXRjaC4yIiwKLSAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdeyJpZGVudGl0eSBjb25zdHJhaW50IiwgIihhbm5vdGF0aW9uPywgc2VsZWN0b3IsIGZpZWxkKykifSwKLSAgICAgICAgICAgICAgICAgICAgaWNFbGVtKTsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIEdlbmVyYWwgQXR0cmlidXRlIENoZWNraW5nIG9uIHNFbGVtCi0gICAgICAgIC8vIGZpcnN0IGNoaWxkIGNvdWxkIGJlIGFuIGFubm90YXRpb24KLSAgICAgICAgaWYgKERPTVV0aWwuZ2V0TG9jYWxOYW1lKHNFbGVtKS5lcXVhbHMoU2NoZW1hU3ltYm9scy5FTFRfQU5OT1RBVElPTikpIHsKLSAgICAgICAgICAgIGljLmFkZEFubm90YXRpb24odHJhdmVyc2VBbm5vdGF0aW9uRGVjbChzRWxlbSwgaWNFbGVtQXR0cnMsIGZhbHNlLCBzY2hlbWFEb2MpKTsKLSAgICAgICAgICAgIHNFbGVtID0gRE9NVXRpbC5nZXROZXh0U2libGluZ0VsZW1lbnQoc0VsZW0pOwotICAgICAgICAgICAgLy8gaWYgbm8gbW9yZSBjaGlsZHJlbiByZXBvcnQgYW4gZXJyb3IKLSAgICAgICAgICAgIGlmKHNFbGVtID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcigiczRzLWVsdC1tdXN0LW1hdGNoLjIiLCBuZXcgT2JqZWN0W117ImlkZW50aXR5IGNvbnN0cmFpbnQiLCAiKGFubm90YXRpb24/LCBzZWxlY3RvciwgZmllbGQrKSJ9LCBpY0VsZW0pOwotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIFN0cmluZyB0ZXh0ID0gRE9NVXRpbC5nZXRTeW50aGV0aWNBbm5vdGF0aW9uKGljRWxlbSk7Ci0gICAgICAgICAgICBpZiAodGV4dCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgaWMuYWRkQW5ub3RhdGlvbih0cmF2ZXJzZVN5bnRoZXRpY0Fubm90YXRpb24oaWNFbGVtLCB0ZXh0LCBpY0VsZW1BdHRycywgZmFsc2UsIHNjaGVtYURvYykpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gbXVzdCBiZSA8c2VsZWN0b3I+Ci0gICAgICAgIGlmKCFET01VdGlsLmdldExvY2FsTmFtZShzRWxlbSkuZXF1YWxzKFNjaGVtYVN5bWJvbHMuRUxUX1NFTEVDVE9SKSkgewotICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoInM0cy1lbHQtbXVzdC1tYXRjaC4xIiwgbmV3IE9iamVjdFtdeyJpZGVudGl0eSBjb25zdHJhaW50IiwgIihhbm5vdGF0aW9uPywgc2VsZWN0b3IsIGZpZWxkKykiLCBTY2hlbWFTeW1ib2xzLkVMVF9TRUxFQ1RPUn0sIHNFbGVtKTsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotICAgICAgICBPYmplY3QgW10gYXR0clZhbHVlcyA9IGZBdHRyQ2hlY2tlci5jaGVja0F0dHJpYnV0ZXMoc0VsZW0sIGZhbHNlLCBzY2hlbWFEb2MpOwotCi0gICAgICAgIC8vIG1ha2Ugc3VyZSA8c2VsZWN0b3I+J3MgY29udGVudCBpcyBmaW5lOgotICAgICAgICBFbGVtZW50IHNlbENoaWxkID0gRE9NVXRpbC5nZXRGaXJzdENoaWxkRWxlbWVudChzRWxlbSk7Ci0KLSAgICAgICAgaWYgKHNlbENoaWxkICE9bnVsbCkgewotICAgICAgICAgICAgLy8gdHJhdmVyc2UgYW5ub3RhdGlvbiBpZiBhbnkKLSAgICAgICAgICAgIGlmIChET01VdGlsLmdldExvY2FsTmFtZShzZWxDaGlsZCkuZXF1YWxzKFNjaGVtYVN5bWJvbHMuRUxUX0FOTk9UQVRJT04pKSB7Ci0gICAgICAgICAgICAgICAgaWMuYWRkQW5ub3RhdGlvbih0cmF2ZXJzZUFubm90YXRpb25EZWNsKHNlbENoaWxkLCBhdHRyVmFsdWVzLCBmYWxzZSwgc2NoZW1hRG9jKSk7Ci0gICAgICAgICAgICAgICAgc2VsQ2hpbGQgPSBET01VdGlsLmdldE5leHRTaWJsaW5nRWxlbWVudChzZWxDaGlsZCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcigiczRzLWVsdC1tdXN0LW1hdGNoLjEiLCBuZXcgT2JqZWN0W117U2NoZW1hU3ltYm9scy5FTFRfU0VMRUNUT1IsICIoYW5ub3RhdGlvbj8pIiwgRE9NVXRpbC5nZXRMb2NhbE5hbWUoc2VsQ2hpbGQpfSwgc2VsQ2hpbGQpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKHNlbENoaWxkICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcigiczRzLWVsdC1tdXN0LW1hdGNoLjEiLCBuZXcgT2JqZWN0IFtdIHtTY2hlbWFTeW1ib2xzLkVMVF9TRUxFQ1RPUiwgIihhbm5vdGF0aW9uPykiLCBET01VdGlsLmdldExvY2FsTmFtZShzZWxDaGlsZCl9LCBzZWxDaGlsZCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBTdHJpbmcgdGV4dCA9IERPTVV0aWwuZ2V0U3ludGhldGljQW5ub3RhdGlvbihzRWxlbSk7Ci0gICAgICAgICAgICBpZiAodGV4dCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgaWMuYWRkQW5ub3RhdGlvbih0cmF2ZXJzZVN5bnRoZXRpY0Fubm90YXRpb24oaWNFbGVtLCB0ZXh0LCBhdHRyVmFsdWVzLCBmYWxzZSwgc2NoZW1hRG9jKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBTdHJpbmcgc1RleHQgPSAoKFN0cmluZylhdHRyVmFsdWVzW1hTQXR0cmlidXRlQ2hlY2tlci5BVFRJRFhfWFBBVEhdKTsKLSAgICAgICAgaWYoc1RleHQgPT0gbnVsbCkgewotICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoInM0cy1hdHQtbXVzdC1hcHBlYXIiLCBuZXcgT2JqZWN0IFtdIHtTY2hlbWFTeW1ib2xzLkVMVF9TRUxFQ1RPUiwgU2NoZW1hU3ltYm9scy5BVFRfWFBBVEh9LCBzRWxlbSk7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLSAgICAgICAgc1RleHQgPSBYTUxDaGFyLnRyaW0oc1RleHQpOwotCi0gICAgICAgIFNlbGVjdG9yLlhQYXRoIHNYcGF0aCA9IG51bGw7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBzWHBhdGggPSBuZXcgU2VsZWN0b3IuWFBhdGgoc1RleHQsIGZTeW1ib2xUYWJsZSwKLSAgICAgICAgICAgICAgICAgICAgc2NoZW1hRG9jLmZOYW1lc3BhY2VTdXBwb3J0KTsKLSAgICAgICAgICAgIFNlbGVjdG9yIHNlbGVjdG9yID0gbmV3IFNlbGVjdG9yKHNYcGF0aCwgaWMpOwotICAgICAgICAgICAgaWMuc2V0U2VsZWN0b3Ioc2VsZWN0b3IpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChYUGF0aEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcihlLmdldEtleSgpLCBuZXcgT2JqZWN0W117c1RleHR9LCBzRWxlbSk7Ci0gICAgICAgICAgICAvLyBwdXQgYmFjayBhdHRyIHZhbHVlcy4uLgotICAgICAgICAgICAgZkF0dHJDaGVja2VyLnJldHVybkF0dHJBcnJheShhdHRyVmFsdWVzLCBzY2hlbWFEb2MpOwotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gcHV0IGJhY2sgYXR0ciB2YWx1ZXMuLi4KLSAgICAgICAgZkF0dHJDaGVja2VyLnJldHVybkF0dHJBcnJheShhdHRyVmFsdWVzLCBzY2hlbWFEb2MpOwotCi0gICAgICAgIC8vIGdldCBmaWVsZHMKLSAgICAgICAgRWxlbWVudCBmRWxlbSA9IERPTVV0aWwuZ2V0TmV4dFNpYmxpbmdFbGVtZW50KHNFbGVtKTsKLSAgICAgICAgaWYoZkVsZW0gPT0gbnVsbCkgewotICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoInM0cy1lbHQtbXVzdC1tYXRjaC4yIiwgbmV3IE9iamVjdFtdeyJpZGVudGl0eSBjb25zdHJhaW50IiwgIihhbm5vdGF0aW9uPywgc2VsZWN0b3IsIGZpZWxkKykifSwgc0VsZW0pOwotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0gICAgICAgIHdoaWxlIChmRWxlbSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpZighRE9NVXRpbC5nZXRMb2NhbE5hbWUoZkVsZW0pLmVxdWFscyhTY2hlbWFTeW1ib2xzLkVMVF9GSUVMRCkpIHsKLSAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcigiczRzLWVsdC1tdXN0LW1hdGNoLjEiLCBuZXcgT2JqZWN0W117ImlkZW50aXR5IGNvbnN0cmFpbnQiLCAiKGFubm90YXRpb24/LCBzZWxlY3RvciwgZmllbGQrKSIsIFNjaGVtYVN5bWJvbHMuRUxUX0ZJRUxEfSwgZkVsZW0pOwotICAgICAgICAgICAgICAgIGZFbGVtID0gRE9NVXRpbC5nZXROZXh0U2libGluZ0VsZW1lbnQoZkVsZW0pOwotICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBHZW5lcmFsIEF0dHJpYnV0ZSBDaGVja2luZwotICAgICAgICAgICAgYXR0clZhbHVlcyA9IGZBdHRyQ2hlY2tlci5jaGVja0F0dHJpYnV0ZXMoZkVsZW0sIGZhbHNlLCBzY2hlbWFEb2MpOwotCi0gICAgICAgICAgICAvLyBhbmQgbWFrZSBzdXJlIDxmaWVsZD4ncyBjb250ZW50IGlzIGZpbmU6Ci0gICAgICAgICAgICBFbGVtZW50IGZpZWxkQ2hpbGQgPSBET01VdGlsLmdldEZpcnN0Q2hpbGRFbGVtZW50KGZFbGVtKTsKLSAgICAgICAgICAgIGlmIChmaWVsZENoaWxkICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAvLyB0cmF2ZXJzZSBhbm5vdGF0aW9uCi0gICAgICAgICAgICAgICAgaWYgKERPTVV0aWwuZ2V0TG9jYWxOYW1lKGZpZWxkQ2hpbGQpLmVxdWFscyhTY2hlbWFTeW1ib2xzLkVMVF9BTk5PVEFUSU9OKSkgewotICAgICAgICAgICAgICAgICAgICBpYy5hZGRBbm5vdGF0aW9uKHRyYXZlcnNlQW5ub3RhdGlvbkRlY2woZmllbGRDaGlsZCwgYXR0clZhbHVlcywgZmFsc2UsIHNjaGVtYURvYykpOwotICAgICAgICAgICAgICAgICAgICBmaWVsZENoaWxkID0gRE9NVXRpbC5nZXROZXh0U2libGluZ0VsZW1lbnQoZmllbGRDaGlsZCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKGZpZWxkQ2hpbGQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKCJzNHMtZWx0LW11c3QtbWF0Y2guMSIsIG5ldyBPYmplY3QgW10ge1NjaGVtYVN5bWJvbHMuRUxUX0ZJRUxELCAiKGFubm90YXRpb24/KSIsIERPTVV0aWwuZ2V0TG9jYWxOYW1lKGZpZWxkQ2hpbGQpfSwgZmllbGRDaGlsZCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgdGV4dCA9IERPTVV0aWwuZ2V0U3ludGhldGljQW5ub3RhdGlvbihmRWxlbSk7Ci0gICAgICAgICAgICAgICAgaWYgKHRleHQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBpYy5hZGRBbm5vdGF0aW9uKHRyYXZlcnNlU3ludGhldGljQW5ub3RhdGlvbihpY0VsZW0sIHRleHQsIGF0dHJWYWx1ZXMsIGZhbHNlLCBzY2hlbWFEb2MpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBTdHJpbmcgZlRleHQgPSAoKFN0cmluZylhdHRyVmFsdWVzW1hTQXR0cmlidXRlQ2hlY2tlci5BVFRJRFhfWFBBVEhdKTsKLSAgICAgICAgICAgIGlmIChmVGV4dCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoInM0cy1hdHQtbXVzdC1hcHBlYXIiLCBuZXcgT2JqZWN0IFtdIHtTY2hlbWFTeW1ib2xzLkVMVF9GSUVMRCwgU2NoZW1hU3ltYm9scy5BVFRfWFBBVEh9LCBmRWxlbSk7Ci0gICAgICAgICAgICAgICAgZkF0dHJDaGVja2VyLnJldHVybkF0dHJBcnJheShhdHRyVmFsdWVzLCBzY2hlbWFEb2MpOwotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGZUZXh0ID0gWE1MQ2hhci50cmltKGZUZXh0KTsKLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgRmllbGQuWFBhdGggZlhwYXRoID0gbmV3IEZpZWxkLlhQYXRoKGZUZXh0LCBmU3ltYm9sVGFibGUsCi0gICAgICAgICAgICAgICAgICAgICAgICBzY2hlbWFEb2MuZk5hbWVzcGFjZVN1cHBvcnQpOwotICAgICAgICAgICAgICAgIEZpZWxkIGZpZWxkID0gbmV3IEZpZWxkKGZYcGF0aCwgaWMpOwotICAgICAgICAgICAgICAgIGljLmFkZEZpZWxkKGZpZWxkKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhdGNoIChYUGF0aEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoZS5nZXRLZXkoKSwgbmV3IE9iamVjdFtde2ZUZXh0fSwgZkVsZW0pOwotICAgICAgICAgICAgICAgIC8vIHB1dCBiYWNrIGF0dHIgdmFsdWVzLi4uCi0gICAgICAgICAgICAgICAgZkF0dHJDaGVja2VyLnJldHVybkF0dHJBcnJheShhdHRyVmFsdWVzLCBzY2hlbWFEb2MpOwotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGZFbGVtID0gRE9NVXRpbC5nZXROZXh0U2libGluZ0VsZW1lbnQoZkVsZW0pOwotICAgICAgICAgICAgLy8gcHV0IGJhY2sgYXR0ciB2YWx1ZXMuLi4KLSAgICAgICAgICAgIGZBdHRyQ2hlY2tlci5yZXR1cm5BdHRyQXJyYXkoYXR0clZhbHVlcywgc2NoZW1hRG9jKTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBpYy5nZXRGaWVsZENvdW50KCkgPiAwOwotICAgIH0gLy8gdHJhdmVyc2VJZGVudGl0eUNvbnN0cmFpbnQoSWRlbnRpdHlDb25zdHJhaW50LEVsZW1lbnQsIFhTRG9jdW1lbnRJbmZvKQotfSAvLyBYU0RBYnN0cmFjdElEQ29uc3RyYWludFRyYXZlcnNlcgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy90cmF2ZXJzZXJzL1hTREFic3RyYWN0UGFydGljbGVUcmF2ZXJzZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvdHJhdmVyc2Vycy9YU0RBYnN0cmFjdFBhcnRpY2xlVHJhdmVyc2VyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDM2NGE5NGEuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy90cmF2ZXJzZXJzL1hTREFic3RyYWN0UGFydGljbGVUcmF2ZXJzZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDM4NSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy50cmF2ZXJzZXJzOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlNjaGVtYUdyYW1tYXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlNjaGVtYVN5bWJvbHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlhTQW5ub3RhdGlvbkltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlhTTW9kZWxHcm91cEltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlhTUGFydGljbGVEZWNsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy51dGlsLlhJbnQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLnV0aWwuWFNPYmplY3RMaXN0SW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuRE9NVXRpbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTT2JqZWN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNPYmplY3RMaXN0OwotaW1wb3J0IG9yZy53M2MuZG9tLkVsZW1lbnQ7Ci0KLS8qKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgRWxlbmEgTGl0YW5pLCBJQk0KLSAqIEBhdXRob3IgU2FuZHkgR2FvLCBJQk0KLSAqIEB2ZXJzaW9uICRJZDogWFNEQWJzdHJhY3RQYXJ0aWNsZVRyYXZlcnNlci5qYXZhLHYgMS43IDIwMTAtMTEtMDEgMDQ6NDA6MDIgam9laHcgRXhwICQKLSAqLwotYWJzdHJhY3QgY2xhc3MgWFNEQWJzdHJhY3RQYXJ0aWNsZVRyYXZlcnNlciBleHRlbmRzIFhTREFic3RyYWN0VHJhdmVyc2VyIHsKLQotICAgIFhTREFic3RyYWN0UGFydGljbGVUcmF2ZXJzZXIgKFhTREhhbmRsZXIgaGFuZGxlciwKLSAgICAgICAgICAgIFhTQXR0cmlidXRlQ2hlY2tlciBnQXR0ckNoZWNrKSB7Ci0gICAgICAgIHN1cGVyKGhhbmRsZXIsIGdBdHRyQ2hlY2spOwotICAgIH0KLQotICAgIC8qKgotICAgICAqCi0gICAgICogVHJhdmVyc2UgdGhlICJBbGwiIGRlY2xhcmF0aW9uCi0gICAgICoKLSAgICAgKiAmbHQ7YWxsCi0gICAgICogICBpZCA9IElECi0gICAgICogICBtYXhPY2N1cnMgPSAxIDogMQotICAgICAqICAgbWluT2NjdXJzID0gKDAgfCAxKSA6IDEmZ3Q7Ci0gICAgICogICBDb250ZW50OiAoYW5ub3RhdGlvbj8gLCBlbGVtZW50KikKLSAgICAgKiAmbHQ7L2FsbCZndDsKLSAgICAgKiovCi0gICAgWFNQYXJ0aWNsZURlY2wgdHJhdmVyc2VBbGwoRWxlbWVudCBhbGxEZWNsLAotICAgICAgICAgICAgWFNEb2N1bWVudEluZm8gc2NoZW1hRG9jLAotICAgICAgICAgICAgU2NoZW1hR3JhbW1hciBncmFtbWFyLAotICAgICAgICAgICAgaW50IGFsbENvbnRleHRGbGFncywKLSAgICAgICAgICAgIFhTT2JqZWN0IHBhcmVudCkgewotCi0gICAgICAgIC8vIEdlbmVyYWwgQXR0cmlidXRlIENoZWNraW5nCi0KLSAgICAgICAgT2JqZWN0W10gYXR0clZhbHVlcyA9IGZBdHRyQ2hlY2tlci5jaGVja0F0dHJpYnV0ZXMoYWxsRGVjbCwgZmFsc2UsIHNjaGVtYURvYyk7Ci0KLSAgICAgICAgRWxlbWVudCBjaGlsZCA9IERPTVV0aWwuZ2V0Rmlyc3RDaGlsZEVsZW1lbnQoYWxsRGVjbCk7Ci0KLSAgICAgICAgWFNBbm5vdGF0aW9uSW1wbCBhbm5vdGF0aW9uID0gbnVsbDsKLSAgICAgICAgaWYgKGNoaWxkICE9bnVsbCAmJiBET01VdGlsLmdldExvY2FsTmFtZShjaGlsZCkuZXF1YWxzKFNjaGVtYVN5bWJvbHMuRUxUX0FOTk9UQVRJT04pKSB7Ci0gICAgICAgICAgICBhbm5vdGF0aW9uID0gdHJhdmVyc2VBbm5vdGF0aW9uRGVjbChjaGlsZCwgYXR0clZhbHVlcywgZmFsc2UsIHNjaGVtYURvYyk7Ci0gICAgICAgICAgICBjaGlsZCA9IERPTVV0aWwuZ2V0TmV4dFNpYmxpbmdFbGVtZW50KGNoaWxkKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIFN0cmluZyB0ZXh0ID0gRE9NVXRpbC5nZXRTeW50aGV0aWNBbm5vdGF0aW9uKGFsbERlY2wpOwotICAgICAgICAgICAgaWYgKHRleHQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGFubm90YXRpb24gPSB0cmF2ZXJzZVN5bnRoZXRpY0Fubm90YXRpb24oYWxsRGVjbCwgdGV4dCwgYXR0clZhbHVlcywgZmFsc2UsIHNjaGVtYURvYyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgU3RyaW5nIGNoaWxkTmFtZSA9IG51bGw7Ci0gICAgICAgIFhTUGFydGljbGVEZWNsIHBhcnRpY2xlOwotICAgICAgICBmUEFycmF5LnB1c2hDb250ZXh0KCk7Ci0KLSAgICAgICAgZm9yICg7IGNoaWxkICE9IG51bGw7IGNoaWxkID0gRE9NVXRpbC5nZXROZXh0U2libGluZ0VsZW1lbnQoY2hpbGQpKSB7Ci0KLSAgICAgICAgICAgIHBhcnRpY2xlID0gbnVsbDsKLSAgICAgICAgICAgIGNoaWxkTmFtZSA9IERPTVV0aWwuZ2V0TG9jYWxOYW1lKGNoaWxkKTsKLQotICAgICAgICAgICAgLy8gT25seSBlbGVtZW50cyBhcmUgYWxsb3dlZCBpbiA8YWxsPgotICAgICAgICAgICAgaWYgKGNoaWxkTmFtZS5lcXVhbHMoU2NoZW1hU3ltYm9scy5FTFRfRUxFTUVOVCkpIHsKLSAgICAgICAgICAgICAgICBwYXJ0aWNsZSA9IGZTY2hlbWFIYW5kbGVyLmZFbGVtZW50VHJhdmVyc2VyLnRyYXZlcnNlTG9jYWwoY2hpbGQsIHNjaGVtYURvYywgZ3JhbW1hciwgUFJPQ0VTU0lOR19BTExfRUwsIHBhcmVudCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBPYmplY3RbXSBhcmdzID0geyJhbGwiLCAiKGFubm90YXRpb24/LCBlbGVtZW50KikiLCBET01VdGlsLmdldExvY2FsTmFtZShjaGlsZCl9OwotICAgICAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKCJzNHMtZWx0LW11c3QtbWF0Y2guMSIsIGFyZ3MsIGNoaWxkKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKHBhcnRpY2xlICE9IG51bGwpCi0gICAgICAgICAgICAgICAgZlBBcnJheS5hZGRQYXJ0aWNsZShwYXJ0aWNsZSk7Ci0gICAgICAgIH0KLQotICAgICAgICBwYXJ0aWNsZSA9IG51bGw7Ci0gICAgICAgIFhJbnQgbWluQXR0ID0gKFhJbnQpYXR0clZhbHVlc1tYU0F0dHJpYnV0ZUNoZWNrZXIuQVRUSURYX01JTk9DQ1VSU107Ci0gICAgICAgIFhJbnQgbWF4QXR0ID0gKFhJbnQpYXR0clZhbHVlc1tYU0F0dHJpYnV0ZUNoZWNrZXIuQVRUSURYX01BWE9DQ1VSU107Ci0gICAgICAgIExvbmcgZGVmYXVsdFZhbHMgPSAoTG9uZylhdHRyVmFsdWVzW1hTQXR0cmlidXRlQ2hlY2tlci5BVFRJRFhfRlJPTURFRkFVTFRdOwotCi0gICAgICAgIFhTTW9kZWxHcm91cEltcGwgZ3JvdXAgPSBuZXcgWFNNb2RlbEdyb3VwSW1wbCgpOwotICAgICAgICBncm91cC5mQ29tcG9zaXRvciA9IFhTTW9kZWxHcm91cEltcGwuTU9ERUxHUk9VUF9BTEw7Ci0gICAgICAgIGdyb3VwLmZQYXJ0aWNsZUNvdW50ID0gZlBBcnJheS5nZXRQYXJ0aWNsZUNvdW50KCk7Ci0gICAgICAgIGdyb3VwLmZQYXJ0aWNsZXMgPSBmUEFycmF5LnBvcENvbnRleHQoKTsKLSAgICAgICAgWFNPYmplY3RMaXN0IGFubm90YXRpb25zOwotICAgICAgICBpZiAoYW5ub3RhdGlvbiAhPSBudWxsKSB7Ci0gICAgICAgICAgICBhbm5vdGF0aW9ucyA9IG5ldyBYU09iamVjdExpc3RJbXBsKCk7Ci0gICAgICAgICAgICAoKFhTT2JqZWN0TGlzdEltcGwpYW5ub3RhdGlvbnMpLmFkZFhTT2JqZWN0IChhbm5vdGF0aW9uKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIGFubm90YXRpb25zID0gWFNPYmplY3RMaXN0SW1wbC5FTVBUWV9MSVNUOwotICAgICAgICB9Ci0gICAgICAgIGdyb3VwLmZBbm5vdGF0aW9ucyA9IGFubm90YXRpb25zOwotICAgICAgICBwYXJ0aWNsZSA9IG5ldyBYU1BhcnRpY2xlRGVjbCgpOwotICAgICAgICBwYXJ0aWNsZS5mVHlwZSA9IFhTUGFydGljbGVEZWNsLlBBUlRJQ0xFX01PREVMR1JPVVA7Ci0gICAgICAgIHBhcnRpY2xlLmZNaW5PY2N1cnMgPSBtaW5BdHQuaW50VmFsdWUoKTsKLSAgICAgICAgcGFydGljbGUuZk1heE9jY3VycyA9IG1heEF0dC5pbnRWYWx1ZSgpOwotICAgICAgICBwYXJ0aWNsZS5mVmFsdWUgPSBncm91cDsKLSAgICAgICAgcGFydGljbGUuZkFubm90YXRpb25zID0gYW5ub3RhdGlvbnM7Ci0KLSAgICAgICAgcGFydGljbGUgPSBjaGVja09jY3VycmVuY2VzKHBhcnRpY2xlLAotICAgICAgICAgICAgICAgIFNjaGVtYVN5bWJvbHMuRUxUX0FMTCwKLSAgICAgICAgICAgICAgICAoRWxlbWVudClhbGxEZWNsLmdldFBhcmVudE5vZGUoKSwKLSAgICAgICAgICAgICAgICBhbGxDb250ZXh0RmxhZ3MsCi0gICAgICAgICAgICAgICAgZGVmYXVsdFZhbHMubG9uZ1ZhbHVlKCkpOwotICAgICAgICBmQXR0ckNoZWNrZXIucmV0dXJuQXR0ckFycmF5KGF0dHJWYWx1ZXMsIHNjaGVtYURvYyk7Ci0KLSAgICAgICAgcmV0dXJuIHBhcnRpY2xlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYXZlcnNlIHRoZSBTZXF1ZW5jZSBkZWNsYXJhdGlvbgotICAgICAqCi0gICAgICogPHNlcXVlbmNlCi0gICAgICogICBpZCA9IElECi0gICAgICogICBtYXhPY2N1cnMgPSBzdHJpbmcKLSAgICAgKiAgIG1pbk9jY3VycyA9IG5vbk5lZ2F0aXZlSW50ZWdlcj4KLSAgICAgKiAgIENvbnRlbnQ6IChhbm5vdGF0aW9uPyAsIChlbGVtZW50IHwgZ3JvdXAgfCBjaG9pY2UgfCBzZXF1ZW5jZSB8IGFueSkqKQotICAgICAqIDwvc2VxdWVuY2U+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gc2VxRGVjbAotICAgICAqIEBwYXJhbSBzY2hlbWFEb2MKLSAgICAgKiBAcGFyYW0gZ3JhbW1hcgotICAgICAqIEByZXR1cm4KLSAgICAgKi8KLSAgICBYU1BhcnRpY2xlRGVjbCB0cmF2ZXJzZVNlcXVlbmNlKEVsZW1lbnQgc2VxRGVjbCwKLSAgICAgICAgICAgIFhTRG9jdW1lbnRJbmZvIHNjaGVtYURvYywKLSAgICAgICAgICAgIFNjaGVtYUdyYW1tYXIgZ3JhbW1hciwKLSAgICAgICAgICAgIGludCBhbGxDb250ZXh0RmxhZ3MsCi0gICAgICAgICAgICBYU09iamVjdCBwYXJlbnQpIHsKLQotICAgICAgICByZXR1cm4gdHJhdmVyc2VTZXFDaG9pY2Uoc2VxRGVjbCwgc2NoZW1hRG9jLCBncmFtbWFyLCBhbGxDb250ZXh0RmxhZ3MsIGZhbHNlLCBwYXJlbnQpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYXZlcnNlIHRoZSBDaG9pY2UgZGVjbGFyYXRpb24KLSAgICAgKgotICAgICAqIDxjaG9pY2UKLSAgICAgKiAgIGlkID0gSUQKLSAgICAgKiAgIG1heE9jY3VycyA9IHN0cmluZwotICAgICAqICAgbWluT2NjdXJzID0gbm9uTmVnYXRpdmVJbnRlZ2VyPgotICAgICAqICAgQ29udGVudDogKGFubm90YXRpb24/ICwgKGVsZW1lbnQgfCBncm91cCB8IGNob2ljZSB8IHNlcXVlbmNlIHwgYW55KSopCi0gICAgICogPC9jaG9pY2U+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gY2hvaWNlRGVjbAotICAgICAqIEBwYXJhbSBzY2hlbWFEb2MKLSAgICAgKiBAcGFyYW0gZ3JhbW1hcgotICAgICAqIEByZXR1cm4KLSAgICAgKi8KLSAgICBYU1BhcnRpY2xlRGVjbCB0cmF2ZXJzZUNob2ljZShFbGVtZW50IGNob2ljZURlY2wsCi0gICAgICAgICAgICBYU0RvY3VtZW50SW5mbyBzY2hlbWFEb2MsCi0gICAgICAgICAgICBTY2hlbWFHcmFtbWFyIGdyYW1tYXIsCi0gICAgICAgICAgICBpbnQgYWxsQ29udGV4dEZsYWdzLAotICAgICAgICAgICAgWFNPYmplY3QgcGFyZW50KSB7Ci0KLSAgICAgICAgcmV0dXJuIHRyYXZlcnNlU2VxQ2hvaWNlIChjaG9pY2VEZWNsLCBzY2hlbWFEb2MsIGdyYW1tYXIsIGFsbENvbnRleHRGbGFncywgdHJ1ZSwgcGFyZW50KTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb21tb24gdHJhdmVyc2FsIGZvciA8Y2hvaWNlPiBhbmQgPHNlcXVlbmNlPgotICAgICAqCi0gICAgICogQHBhcmFtIGRlY2wKLSAgICAgKiBAcGFyYW0gc2NoZW1hRG9jCi0gICAgICogQHBhcmFtIGdyYW1tYXIKLSAgICAgKiBAcGFyYW0gY2hvaWNlICAgIElmIHRyYXZlcnNpbmcgPGNob2ljZT4gdGhpcyBwYXJhbWV0ZXIgaXMgdHJ1ZS4KLSAgICAgKiBAcmV0dXJuCi0gICAgICovCi0gICAgcHJpdmF0ZSBYU1BhcnRpY2xlRGVjbCB0cmF2ZXJzZVNlcUNob2ljZShFbGVtZW50IGRlY2wsCi0gICAgICAgICAgICBYU0RvY3VtZW50SW5mbyBzY2hlbWFEb2MsCi0gICAgICAgICAgICBTY2hlbWFHcmFtbWFyIGdyYW1tYXIsCi0gICAgICAgICAgICBpbnQgYWxsQ29udGV4dEZsYWdzLAotICAgICAgICAgICAgYm9vbGVhbiBjaG9pY2UsCi0gICAgICAgICAgICBYU09iamVjdCBwYXJlbnQpIHsKLQotICAgICAgICAvLyBHZW5lcmFsIEF0dHJpYnV0ZSBDaGVja2luZwotICAgICAgICBPYmplY3RbXSBhdHRyVmFsdWVzID0gZkF0dHJDaGVja2VyLmNoZWNrQXR0cmlidXRlcyhkZWNsLCBmYWxzZSwgc2NoZW1hRG9jKTsKLQotICAgICAgICBFbGVtZW50IGNoaWxkID0gRE9NVXRpbC5nZXRGaXJzdENoaWxkRWxlbWVudChkZWNsKTsKLSAgICAgICAgWFNBbm5vdGF0aW9uSW1wbCBhbm5vdGF0aW9uID0gbnVsbDsKLSAgICAgICAgaWYgKGNoaWxkICE9bnVsbCAmJiBET01VdGlsLmdldExvY2FsTmFtZShjaGlsZCkuZXF1YWxzKFNjaGVtYVN5bWJvbHMuRUxUX0FOTk9UQVRJT04pKSB7Ci0gICAgICAgICAgICBhbm5vdGF0aW9uID0gdHJhdmVyc2VBbm5vdGF0aW9uRGVjbChjaGlsZCwgYXR0clZhbHVlcywgZmFsc2UsIHNjaGVtYURvYyk7Ci0gICAgICAgICAgICBjaGlsZCA9IERPTVV0aWwuZ2V0TmV4dFNpYmxpbmdFbGVtZW50KGNoaWxkKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIFN0cmluZyB0ZXh0ID0gRE9NVXRpbC5nZXRTeW50aGV0aWNBbm5vdGF0aW9uKGRlY2wpOwotICAgICAgICAgICAgaWYgKHRleHQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGFubm90YXRpb24gPSB0cmF2ZXJzZVN5bnRoZXRpY0Fubm90YXRpb24oZGVjbCwgdGV4dCwgYXR0clZhbHVlcywgZmFsc2UsIHNjaGVtYURvYyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBTdHJpbmcgY2hpbGROYW1lID0gbnVsbDsKLSAgICAgICAgWFNQYXJ0aWNsZURlY2wgcGFydGljbGU7Ci0gICAgICAgIGZQQXJyYXkucHVzaENvbnRleHQoKTsKLQotICAgICAgICBmb3IgKDtjaGlsZCAhPSBudWxsO2NoaWxkID0gRE9NVXRpbC5nZXROZXh0U2libGluZ0VsZW1lbnQoY2hpbGQpKSB7Ci0KLSAgICAgICAgICAgIHBhcnRpY2xlID0gbnVsbDsKLQotICAgICAgICAgICAgY2hpbGROYW1lID0gRE9NVXRpbC5nZXRMb2NhbE5hbWUoY2hpbGQpOwotICAgICAgICAgICAgaWYgKGNoaWxkTmFtZS5lcXVhbHMoU2NoZW1hU3ltYm9scy5FTFRfRUxFTUVOVCkpIHsKLSAgICAgICAgICAgICAgICBwYXJ0aWNsZSA9IGZTY2hlbWFIYW5kbGVyLmZFbGVtZW50VHJhdmVyc2VyLnRyYXZlcnNlTG9jYWwoY2hpbGQsIHNjaGVtYURvYywgZ3JhbW1hciwgTk9UX0FMTF9DT05URVhULCBwYXJlbnQpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoY2hpbGROYW1lLmVxdWFscyhTY2hlbWFTeW1ib2xzLkVMVF9HUk9VUCkpIHsKLSAgICAgICAgICAgICAgICBwYXJ0aWNsZSA9IGZTY2hlbWFIYW5kbGVyLmZHcm91cFRyYXZlcnNlci50cmF2ZXJzZUxvY2FsKGNoaWxkLCBzY2hlbWFEb2MsIGdyYW1tYXIpOwotCi0gICAgICAgICAgICAgICAgLy8gQSBjb250ZW50IHR5cGUgb2YgYWxsIGNhbiBvbmx5IGFwcGVhcgotICAgICAgICAgICAgICAgIC8vIGFzIHRoZSBjb250ZW50IHR5cGUgb2YgYSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbi4KLSAgICAgICAgICAgICAgICBpZiAoaGFzQWxsQ29udGVudChwYXJ0aWNsZSkpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gZG9uJ3QgaW5zZXJ0IHRoZSAiYWxsIiBwYXJ0aWNsZSwgb3RoZXJ3aXNlIHdlIHdvbid0IGJlCi0gICAgICAgICAgICAgICAgICAgIC8vIGFibGUgdG8gY3JlYXRlIERGQSBmcm9tIHRoaXMgY29udGVudCBtb2RlbAotICAgICAgICAgICAgICAgICAgICBwYXJ0aWNsZSA9IG51bGw7Ci0gICAgICAgICAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKCJjb3MtYWxsLWxpbWl0ZWQuMS4yIiwgbnVsbCwgY2hpbGQpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoY2hpbGROYW1lLmVxdWFscyhTY2hlbWFTeW1ib2xzLkVMVF9DSE9JQ0UpKSB7Ci0gICAgICAgICAgICAgICAgcGFydGljbGUgPSB0cmF2ZXJzZUNob2ljZShjaGlsZCwgc2NoZW1hRG9jLCBncmFtbWFyLCBOT1RfQUxMX0NPTlRFWFQsIHBhcmVudCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChjaGlsZE5hbWUuZXF1YWxzKFNjaGVtYVN5bWJvbHMuRUxUX1NFUVVFTkNFKSkgewotICAgICAgICAgICAgICAgIHBhcnRpY2xlID0gdHJhdmVyc2VTZXF1ZW5jZShjaGlsZCwgc2NoZW1hRG9jLCBncmFtbWFyLCBOT1RfQUxMX0NPTlRFWFQsIHBhcmVudCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChjaGlsZE5hbWUuZXF1YWxzKFNjaGVtYVN5bWJvbHMuRUxUX0FOWSkpIHsKLSAgICAgICAgICAgICAgICBwYXJ0aWNsZSA9IGZTY2hlbWFIYW5kbGVyLmZXaWxkQ2FyZFRyYXZlcnNlci50cmF2ZXJzZUFueShjaGlsZCwgc2NoZW1hRG9jLCBncmFtbWFyKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIE9iamVjdCBbXSBhcmdzOwotICAgICAgICAgICAgICAgIGlmIChjaG9pY2UpIHsKLSAgICAgICAgICAgICAgICAgICAgYXJncyA9IG5ldyBPYmplY3RbXXsiY2hvaWNlIiwgIihhbm5vdGF0aW9uPywgKGVsZW1lbnQgfCBncm91cCB8IGNob2ljZSB8IHNlcXVlbmNlIHwgYW55KSopIiwgRE9NVXRpbC5nZXRMb2NhbE5hbWUoY2hpbGQpfTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIGFyZ3MgPSBuZXcgT2JqZWN0W117InNlcXVlbmNlIiwgIihhbm5vdGF0aW9uPywgKGVsZW1lbnQgfCBncm91cCB8IGNob2ljZSB8IHNlcXVlbmNlIHwgYW55KSopIiwgRE9NVXRpbC5nZXRMb2NhbE5hbWUoY2hpbGQpfTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoInM0cy1lbHQtbXVzdC1tYXRjaC4xIiwgYXJncywgY2hpbGQpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAocGFydGljbGUgIT0gbnVsbCkKLSAgICAgICAgICAgICAgICBmUEFycmF5LmFkZFBhcnRpY2xlKHBhcnRpY2xlKTsKLSAgICAgICAgfQotCi0gICAgICAgIHBhcnRpY2xlID0gbnVsbDsKLQotICAgICAgICBYSW50IG1pbkF0dCA9IChYSW50KWF0dHJWYWx1ZXNbWFNBdHRyaWJ1dGVDaGVja2VyLkFUVElEWF9NSU5PQ0NVUlNdOwotICAgICAgICBYSW50IG1heEF0dCA9IChYSW50KWF0dHJWYWx1ZXNbWFNBdHRyaWJ1dGVDaGVja2VyLkFUVElEWF9NQVhPQ0NVUlNdOwotICAgICAgICBMb25nIGRlZmF1bHRWYWxzID0gKExvbmcpYXR0clZhbHVlc1tYU0F0dHJpYnV0ZUNoZWNrZXIuQVRUSURYX0ZST01ERUZBVUxUXTsKLQotICAgICAgICBYU01vZGVsR3JvdXBJbXBsIGdyb3VwID0gbmV3IFhTTW9kZWxHcm91cEltcGwoKTsKLSAgICAgICAgZ3JvdXAuZkNvbXBvc2l0b3IgPSBjaG9pY2UgPyBYU01vZGVsR3JvdXBJbXBsLk1PREVMR1JPVVBfQ0hPSUNFIDogWFNNb2RlbEdyb3VwSW1wbC5NT0RFTEdST1VQX1NFUVVFTkNFOwotICAgICAgICBncm91cC5mUGFydGljbGVDb3VudCA9IGZQQXJyYXkuZ2V0UGFydGljbGVDb3VudCgpOwotICAgICAgICBncm91cC5mUGFydGljbGVzID0gZlBBcnJheS5wb3BDb250ZXh0KCk7Ci0gICAgICAgIFhTT2JqZWN0TGlzdCBhbm5vdGF0aW9uczsKLSAgICAgICAgaWYgKGFubm90YXRpb24gIT0gbnVsbCkgewotICAgICAgICAgICAgYW5ub3RhdGlvbnMgPSBuZXcgWFNPYmplY3RMaXN0SW1wbCgpOwotICAgICAgICAgICAgKChYU09iamVjdExpc3RJbXBsKWFubm90YXRpb25zKS5hZGRYU09iamVjdCAoYW5ub3RhdGlvbik7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBhbm5vdGF0aW9ucyA9IFhTT2JqZWN0TGlzdEltcGwuRU1QVFlfTElTVDsKLSAgICAgICAgfQotICAgICAgICBncm91cC5mQW5ub3RhdGlvbnMgPSBhbm5vdGF0aW9uczsKLSAgICAgICAgcGFydGljbGUgPSBuZXcgWFNQYXJ0aWNsZURlY2woKTsKLSAgICAgICAgcGFydGljbGUuZlR5cGUgPSBYU1BhcnRpY2xlRGVjbC5QQVJUSUNMRV9NT0RFTEdST1VQOwotICAgICAgICBwYXJ0aWNsZS5mTWluT2NjdXJzID0gbWluQXR0LmludFZhbHVlKCk7Ci0gICAgICAgIHBhcnRpY2xlLmZNYXhPY2N1cnMgPSBtYXhBdHQuaW50VmFsdWUoKTsKLSAgICAgICAgcGFydGljbGUuZlZhbHVlID0gZ3JvdXA7Ci0gICAgICAgIHBhcnRpY2xlLmZBbm5vdGF0aW9ucyA9IGFubm90YXRpb25zOwotCi0gICAgICAgIHBhcnRpY2xlID0gY2hlY2tPY2N1cnJlbmNlcyhwYXJ0aWNsZSwKLSAgICAgICAgICAgICAgICBjaG9pY2UgPyBTY2hlbWFTeW1ib2xzLkVMVF9DSE9JQ0UgOiBTY2hlbWFTeW1ib2xzLkVMVF9TRVFVRU5DRSwKLSAgICAgICAgICAgICAgICAgICAgICAgIChFbGVtZW50KWRlY2wuZ2V0UGFyZW50Tm9kZSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgYWxsQ29udGV4dEZsYWdzLAotICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdFZhbHMubG9uZ1ZhbHVlKCkpOwotICAgICAgICBmQXR0ckNoZWNrZXIucmV0dXJuQXR0ckFycmF5KGF0dHJWYWx1ZXMsIHNjaGVtYURvYyk7Ci0KLSAgICAgICAgcmV0dXJuIHBhcnRpY2xlOwotICAgIH0KLQotICAgIC8vIERldGVybWluZXMgd2hldGhlciBhIGNvbnRlbnQgc3BlYyB0cmVlIHJlcHJlc2VudHMgYW4gImFsbCIgY29udGVudCBtb2RlbAotICAgIHByb3RlY3RlZCBib29sZWFuIGhhc0FsbENvbnRlbnQoWFNQYXJ0aWNsZURlY2wgcGFydGljbGUpIHsKLSAgICAgICAgLy8gSWYgdGhlIGNvbnRlbnQgaXMgbm90IGVtcHR5LCBpcyB0aGUgdG9wIG5vZGUgQUxMPwotICAgICAgICBpZiAocGFydGljbGUgIT0gbnVsbCAmJiBwYXJ0aWNsZS5mVHlwZSA9PSBYU1BhcnRpY2xlRGVjbC5QQVJUSUNMRV9NT0RFTEdST1VQKSB7Ci0gICAgICAgICAgICByZXR1cm4gKChYU01vZGVsR3JvdXBJbXBsKXBhcnRpY2xlLmZWYWx1ZSkuZkNvbXBvc2l0b3IgPT0gWFNNb2RlbEdyb3VwSW1wbC5NT0RFTEdST1VQX0FMTDsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICAvLyB0aGUgaW5uZXIgY2xhc3M6IHVzZWQgdG8gc3RvcmUgcGFydGljbGVzIGZvciBtb2RlbCBncm91cHMKLSAgICAvLyB0byBhdm9pZCBjcmVhdGluZyBhIG5ldyBWZWN0b3IgaW4gZWFjaCBtb2RlbCBncm91cCwgb3Igd2hlbiB0cmF2ZXJzaW5nCi0gICAgLy8gZWFjaCBtb2RlbCBncm91cCwgd2UgdXNlIHRoaXMgb25lIGJpZyBhcnJheSB0byBzdG9yZSBhbGwgcGFydGljbGVzCi0gICAgLy8gZm9yIG1vZGVsIGdyb3Vwcy4gd2hlbiB0aGUgdHJhdmVyc2FsIGZpbmlzaGVzLCB0aGlzIGNsYXNzIHJldHVybnMgYW4KLSAgICAvLyBYU1BhcnRpY2xlRGVjbFtdIGNvbnRhaW5pbmcgYWxsIHBhcnRpY2xlcyBmb3IgdGhlIGN1cnJlbnQgbW9kZWwgZ3JvdXAuCi0gICAgLy8gaXQncyBwb3NzaWJsZSB0aGF0IHdlIG5lZWQgdG8gdHJhdmVyc2UgYW5vdGhlciBtb2RlbCBncm91cCB3aGlsZQotICAgIC8vIHRyYXZlcnNpbmcgb25lIChvbmUgaW5zaWRlIGFub3RoZXIgb25lOyByZWZlcnJpbmcgdG8gYSBnbG9iYWwgZ3JvdXAsCi0gICAgLy8gZXRjLiksIHNvIHdlIGhhdmUgcHVzaC9wb3MgY29udGV4dCBtZXRob2RzIHRvIHNhdmUgdGhlIHNhbWUgb2YgdGhlCi0gICAgLy8gY3VycmVudCB0cmF2ZXJzYWwgYmVmb3JlIHN0YXJ0aW5nIHRoZSB0cmF2ZXJzYWwgb2YgYW5vdGhlciBtb2RlbCBncm91cC4KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGNsYXNzIFBhcnRpY2xlQXJyYXkgewotICAgICAgICAvLyBiaWcgYXJyYXkgdG8gY29udGFpbiBhbGwgcGFydGljbGVzCi0gICAgICAgIFhTUGFydGljbGVEZWNsW10gZlBhcnRpY2xlcyA9IG5ldyBYU1BhcnRpY2xlRGVjbFsxMF07Ci0gICAgICAgIC8vIHRoZSBlbmRpbmcgcG9zaXRpb24gb2YgcGFydGljbGVzIGluIHRoZSBhcnJheSBmb3IgZWFjaCBjb250ZXh0Ci0gICAgICAgIC8vIGluZGV4IDAgaXMgcmVzZXJ2ZWQsIHdpdGggdmFsdWUgMC4gaW5kZXggMSBpcyB1c2VkIGZvciB0aGUgZmlzdAotICAgICAgICAvLyBjb250ZXh0LiBzbyB0aGF0IHRoZSBudW1iZXIgb2YgcGFydGljbGVzIGZvciBjb250ZXh0ICdpJyBjYW4gYmUKLSAgICAgICAgLy8gY29tcHV0ZWQgc2ltcGx5IGJ5IGZQb3NbaV0gLSBmUG9zW2ktMV0uCi0gICAgICAgIGludFtdIGZQb3MgPSBuZXcgaW50WzVdOwotICAgICAgICAvLyBudW1iZXIgb2YgY29udGV4dHMKLSAgICAgICAgaW50IGZDb250ZXh0Q291bnQgPSAwOwotCi0gICAgICAgIC8vIHN0YXJ0IGEgbmV3IGNvbnRleHQgKHN0YXJ0IHRyYXZlcnNpbmcgYSBuZXcgbW9kZWwgZ3JvdXApCi0gICAgICAgIHZvaWQgcHVzaENvbnRleHQoKSB7Ci0gICAgICAgICAgICBmQ29udGV4dENvdW50Kys7Ci0gICAgICAgICAgICAvLyByZXNpemUgcG9zaXRpb24gYXJyYXkgaWYgbmVjZXNzYXJ5Ci0gICAgICAgICAgICBpZiAoZkNvbnRleHRDb3VudCA9PSBmUG9zLmxlbmd0aCkgewotICAgICAgICAgICAgICAgIGludCBuZXdTaXplID0gZkNvbnRleHRDb3VudCAqIDI7Ci0gICAgICAgICAgICAgICAgaW50W10gbmV3QXJyYXkgPSBuZXcgaW50W25ld1NpemVdOwotICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZlBvcywgMCwgbmV3QXJyYXksIDAsIGZDb250ZXh0Q291bnQpOwotICAgICAgICAgICAgICAgIGZQb3MgPSBuZXdBcnJheTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIHRoZSBpbml0aWFsIGVuZGluZyBwb3NpdGlvbiBvZiB0aGUgY3VycmVudCBjb250ZXh0IGlzIHRoZQotICAgICAgICAgICAgLy8gZW5kaW5nIHBvc2l0aW9uIG9mIHRoZSBwcmV2aXNvdXMgY29udGV4dC4gd2hpY2ggbWVhbnMgdGhlcmUgaXMKLSAgICAgICAgICAgIC8vIG5vIHBhcnRpY2xlIGZvciB0aGUgY3VycmVudCBjb250ZXh0IHlldC4KLSAgICAgICAgICAgIGZQb3NbZkNvbnRleHRDb3VudF0gPSBmUG9zW2ZDb250ZXh0Q291bnQtMV07Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBnZXQgdGhlIG51bWJlciBvZiBwYXJ0aWNsZXMgb2YgdGhpcyBjb250ZXh0IChtb2RlbCBncm91cCkKLSAgICAgICAgaW50IGdldFBhcnRpY2xlQ291bnQoKSB7Ci0gICAgICAgICAgICByZXR1cm4gZlBvc1tmQ29udGV4dENvdW50XSAtIGZQb3NbZkNvbnRleHRDb3VudC0xXTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIGFkZCBhIHBhcnRpY2xlIHRvIHRoZSBjdXJyZW50IGNvbnRleHQKLSAgICAgICAgdm9pZCBhZGRQYXJ0aWNsZShYU1BhcnRpY2xlRGVjbCBwYXJ0aWNsZSkgewotICAgICAgICAgICAgLy8gcmVzaXplIHRoZSBwYXJ0aWNsZSBhcnJheSBpZiBuZWNlc3NhcnkKLSAgICAgICAgICAgIGlmIChmUG9zW2ZDb250ZXh0Q291bnRdID09IGZQYXJ0aWNsZXMubGVuZ3RoKSB7Ci0gICAgICAgICAgICAgICAgaW50IG5ld1NpemUgPSBmUG9zW2ZDb250ZXh0Q291bnRdICogMjsKLSAgICAgICAgICAgICAgICBYU1BhcnRpY2xlRGVjbFtdIG5ld0FycmF5ID0gbmV3IFhTUGFydGljbGVEZWNsW25ld1NpemVdOwotICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZlBhcnRpY2xlcywgMCwgbmV3QXJyYXksIDAsIGZQb3NbZkNvbnRleHRDb3VudF0pOwotICAgICAgICAgICAgICAgIGZQYXJ0aWNsZXMgPSBuZXdBcnJheTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGZQYXJ0aWNsZXNbZlBvc1tmQ29udGV4dENvdW50XSsrXSA9IHBhcnRpY2xlOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gZW5kIHRoZSBjdXJyZW50IGNvbnRleHQsIGFuZCByZXR1cm4gYW4gYXJyYXkgb2YgcGFydGljbGVzCi0gICAgICAgIFhTUGFydGljbGVEZWNsW10gcG9wQ29udGV4dCgpIHsKLSAgICAgICAgICAgIGludCBjb3VudCA9IGZQb3NbZkNvbnRleHRDb3VudF0gLSBmUG9zW2ZDb250ZXh0Q291bnQtMV07Ci0gICAgICAgICAgICBYU1BhcnRpY2xlRGVjbFtdIGFycmF5ID0gbnVsbDsKLSAgICAgICAgICAgIGlmIChjb3VudCAhPSAwKSB7Ci0gICAgICAgICAgICAgICAgYXJyYXkgPSBuZXcgWFNQYXJ0aWNsZURlY2xbY291bnRdOwotICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZlBhcnRpY2xlcywgZlBvc1tmQ29udGV4dENvdW50LTFdLCBhcnJheSwgMCwgY291bnQpOwotICAgICAgICAgICAgICAgIC8vIGNsZWFyIHRoZSBwYXJ0aWNsZSBhcnJheSwgdG8gcmVsZWFzZSBtZW1vcnkKLSAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gZlBvc1tmQ29udGV4dENvdW50LTFdOyBpIDwgZlBvc1tmQ29udGV4dENvdW50XTsgaSsrKQotICAgICAgICAgICAgICAgICAgICBmUGFydGljbGVzW2ldID0gbnVsbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGZDb250ZXh0Q291bnQtLTsKLSAgICAgICAgICAgIHJldHVybiBhcnJheTsKLSAgICAgICAgfQotCi0gICAgfQotCi0gICAgLy8gdGhlIGJpZyBwYXJ0aWNsZSBhcnJheSB0byBob2xkIGFsbCBwYXJ0aWNsZXMgaW4gbW9kZWwgZ3JvdXBzCi0gICAgUGFydGljbGVBcnJheSBmUEFycmF5ID0gbmV3IFBhcnRpY2xlQXJyYXkoKTsKLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvdHJhdmVyc2Vycy9YU0RBYnN0cmFjdFRyYXZlcnNlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy90cmF2ZXJzZXJzL1hTREFic3RyYWN0VHJhdmVyc2VyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGE1ZTk3ZjAuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy90cmF2ZXJzZXJzL1hTREFic3RyYWN0VHJhdmVyc2VyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4NTMgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMudHJhdmVyc2VyczsKLQotaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7Ci1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5JbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYuWFNGYWNldHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LlhTU2ltcGxlVHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwudmFsaWRhdGlvbi5WYWxpZGF0aW9uU3RhdGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlNjaGVtYUdyYW1tYXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlNjaGVtYVN5bWJvbHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlhTQW5ub3RhdGlvbkltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlhTQXR0cmlidXRlR3JvdXBEZWNsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5YU0F0dHJpYnV0ZVVzZUltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlhTQ29tcGxleFR5cGVEZWNsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5YU0VsZW1lbnREZWNsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5YU1BhcnRpY2xlRGVjbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMuWFNXaWxkY2FyZERlY2w7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLnV0aWwuWEludDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMudXRpbC5YU09iamVjdExpc3RJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5ET01VdGlsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5OYW1lc3BhY2VTdXBwb3J0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5TeW1ib2xUYWJsZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5RTmFtZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTQXR0cmlidXRlVXNlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNPYmplY3RMaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNUeXBlRGVmaW5pdGlvbjsKLWltcG9ydCBvcmcudzNjLmRvbS5FbGVtZW50OwotCi0vKioKLSAqIENsYXNzIDxjb2RlPlhTREFic3RyYWN0VHJhdmVyc2VyPC9jb2RlPiBzZXJ2ZXMgYXMgdGhlIGJhc2UgY2xhc3MgZm9yIGFsbAotICogb3RoZXIgPGNvZGU+WFNEPz8/VHJhdmVyc2VyPC9jb2RlPnMuIEl0IGhvbGRzIHRoZSBjb21tb24gZGF0YSBhbmQgcHJvdmlkZQotICogYSB1bmlmaWVkIHdheSB0byBpbml0aWFsaXplIHRoZXNlIGRhdGEuCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgRWxlbmEgTGl0YW5pLCBJQk0KLSAqIEBhdXRob3IgUmFodWwgU3JpdmFzdGF2YSwgU3VuIE1pY3Jvc3lzdGVtcyBJbmMuCi0gKiBAYXV0aG9yIE5lZXJhaiBCYWphaiwgU3VuIE1pY3Jvc3lzdGVtcyBJbmMuCi0gKgotICogQHZlcnNpb24gJElkOiBYU0RBYnN0cmFjdFRyYXZlcnNlci5qYXZhLHYgMS44IDIwMTAtMTEtMDEgMDQ6NDA6MDIgam9laHcgRXhwICQKLSAqLwotYWJzdHJhY3QgY2xhc3MgWFNEQWJzdHJhY3RUcmF2ZXJzZXIgewotCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgTk9fTkFNRSAgICAgID0gIihubyBuYW1lKSI7Ci0KLSAgICAvLyBGbGFncyBmb3IgY2hlY2tPY2N1cnJlbmNlcyB0byBpbmRpY2F0ZSBhbnkgc3BlY2lhbAotICAgIC8vIHJlc3RyaWN0aW9ucyBvbiBtaW5PY2N1cnMgYW5kIG1heE9jY3VycyByZWxhdGluZyB0byAiYWxsIi4KLSAgICAvLyAgICBOT1RfQUxMX0NPTlRFWFQgICAgLSBub3QgcHJvY2Vzc2luZyBhbiA8YWxsPgotICAgIC8vICAgIFBST0NFU1NJTkdfQUxMX0VMICAtIHByb2Nlc3NpbmcgYW4gPGVsZW1lbnQ+IGluIGFuIDxhbGw+Ci0gICAgLy8gICAgR1JPVVBfUkVGX1dJVEhfQUxMIC0gcHJvY2Vzc2luZyA8Z3JvdXA+IHJlZmVyZW5jZSB0aGF0IGNvbnRhaW5lZCA8YWxsPgotICAgIC8vICAgIENISUxEX09GX0dST1VQICAgICAtIHByb2Nlc3NpbmcgYSBjaGlsZCBvZiBhIG1vZGVsIGdyb3VwIGRlZmluaXRpb24KLSAgICAvLyAgICBQUk9DRVNTSU5HX0FMTF9HUCAgLSBwcm9jZXNzaW5nIGFuIDxhbGw+IGdyb3VwIGl0c2VsZgotCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBpbnQgTk9UX0FMTF9DT05URVhUICAgID0gMDsKLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBQUk9DRVNTSU5HX0FMTF9FTCAgPSAxOwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgaW50IEdST1VQX1JFRl9XSVRIX0FMTCA9IDI7Ci0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBpbnQgQ0hJTERfT0ZfR1JPVVAgICAgID0gNDsKLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBQUk9DRVNTSU5HX0FMTF9HUCAgPSA4OwotCi0gICAgLy9TaGFyZWQgZGF0YQotICAgIHByb3RlY3RlZCBYU0RIYW5kbGVyICAgICAgICAgICAgZlNjaGVtYUhhbmRsZXIgPSBudWxsOwotICAgIHByb3RlY3RlZCBTeW1ib2xUYWJsZSAgICAgICAgICAgZlN5bWJvbFRhYmxlID0gbnVsbDsKLSAgICBwcm90ZWN0ZWQgWFNBdHRyaWJ1dGVDaGVja2VyICAgIGZBdHRyQ2hlY2tlciA9IG51bGw7Ci0gICAgcHJvdGVjdGVkIGJvb2xlYW4gICAgICAgICAgICAgICBmVmFsaWRhdGVBbm5vdGF0aW9ucyA9IGZhbHNlOwotCi0gICAgLy8gdXNlZCB0byB2YWxpZGF0ZSBkZWZhdWx0L2ZpeGVkIGF0dHJpYnV0ZSB2YWx1ZXMKLSAgICBWYWxpZGF0aW9uU3RhdGUgZlZhbGlkYXRpb25TdGF0ZSA9IG5ldyBWYWxpZGF0aW9uU3RhdGUoKTsKLQotICAgIFhTREFic3RyYWN0VHJhdmVyc2VyIChYU0RIYW5kbGVyIGhhbmRsZXIsCi0gICAgICAgICAgICBYU0F0dHJpYnV0ZUNoZWNrZXIgYXR0ckNoZWNrZXIpIHsKLSAgICAgICAgZlNjaGVtYUhhbmRsZXIgPSBoYW5kbGVyOwotICAgICAgICBmQXR0ckNoZWNrZXIgPSBhdHRyQ2hlY2tlcjsKLSAgICB9Ci0KLSAgICB2b2lkIHJlc2V0KFN5bWJvbFRhYmxlIHN5bWJvbFRhYmxlLCBib29sZWFuIHZhbGlkYXRlQW5ub3RhdGlvbnMsIExvY2FsZSBsb2NhbGUpIHsKLSAgICAgICAgZlN5bWJvbFRhYmxlID0gc3ltYm9sVGFibGU7Ci0gICAgICAgIGZWYWxpZGF0ZUFubm90YXRpb25zID0gdmFsaWRhdGVBbm5vdGF0aW9uczsKLSAgICAgICAgZlZhbGlkYXRpb25TdGF0ZS5zZXRFeHRyYUNoZWNraW5nKGZhbHNlKTsKLSAgICAgICAgZlZhbGlkYXRpb25TdGF0ZS5zZXRTeW1ib2xUYWJsZShzeW1ib2xUYWJsZSk7Ci0gICAgICAgIGZWYWxpZGF0aW9uU3RhdGUuc2V0TG9jYWxlKGxvY2FsZSk7Ci0gICAgfQotCi0gICAgLy8gdHJhdmVyc2UgdGhlIGFubm90YXRpb24gZGVjbGFyYXRpb24KLSAgICAvLyBSRVZJU0lUOiBob3cgdG8gcGFzcyB0aGUgcGFyZW50QXR0cnM/IGFzIERPTSBhdHRyaWJ1dGVzPwotICAgIC8vICAgICAgICAgIGFzIG5hbWUvdmFsdWUgcGFpcnMgKHN0cmluZyk/IGluIHBhcnNlZCBmb3JtPwotICAgIC8vIEByZXR1cm4gWFNBbm5vdGF0aW9uSW1wbCBvYmplY3QKLSAgICBYU0Fubm90YXRpb25JbXBsIHRyYXZlcnNlQW5ub3RhdGlvbkRlY2woRWxlbWVudCBhbm5vdGF0aW9uRGVjbCwgT2JqZWN0W10gcGFyZW50QXR0cnMsCi0gICAgICAgICAgICBib29sZWFuIGlzR2xvYmFsLCBYU0RvY3VtZW50SW5mbyBzY2hlbWFEb2MpIHsKLSAgICAgICAgLy8gR2VuZXJhbCBBdHRyaWJ1dGUgQ2hlY2tpbmcKLSAgICAgICAgT2JqZWN0W10gYXR0clZhbHVlcyA9IGZBdHRyQ2hlY2tlci5jaGVja0F0dHJpYnV0ZXMoYW5ub3RhdGlvbkRlY2wsIGlzR2xvYmFsLCBzY2hlbWFEb2MpOwotICAgICAgICBmQXR0ckNoZWNrZXIucmV0dXJuQXR0ckFycmF5KGF0dHJWYWx1ZXMsIHNjaGVtYURvYyk7Ci0KLSAgICAgICAgU3RyaW5nIGNvbnRlbnRzID0gRE9NVXRpbC5nZXRBbm5vdGF0aW9uKGFubm90YXRpb25EZWNsKTsKLSAgICAgICAgRWxlbWVudCBjaGlsZCA9IERPTVV0aWwuZ2V0Rmlyc3RDaGlsZEVsZW1lbnQoYW5ub3RhdGlvbkRlY2wpOwotICAgICAgICBpZiAoY2hpbGQgIT0gbnVsbCkgewotICAgICAgICAgICAgZG8gewotICAgICAgICAgICAgICAgIFN0cmluZyBuYW1lID0gRE9NVXRpbC5nZXRMb2NhbE5hbWUoY2hpbGQpOwotCi0gICAgICAgICAgICAgICAgLy8gdGhlIG9ubHkgdmFsaWQgY2hpbGRyZW4gb2YgImFubm90YXRpb24iIGFyZQotICAgICAgICAgICAgICAgIC8vICJhcHBpbmZvIiBhbmQgImRvY3VtZW50YXRpb24iCi0gICAgICAgICAgICAgICAgaWYgKCEoKG5hbWUuZXF1YWxzKFNjaGVtYVN5bWJvbHMuRUxUX0FQUElORk8pKSB8fAotICAgICAgICAgICAgICAgICAgICAgICAgKG5hbWUuZXF1YWxzKFNjaGVtYVN5bWJvbHMuRUxUX0RPQ1VNRU5UQVRJT04pKSkpIHsKLSAgICAgICAgICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoInNyYy1hbm5vdGF0aW9uIiwgbmV3IE9iamVjdFtde25hbWV9LCBjaGlsZCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAvLyBHZW5lcmFsIEF0dHJpYnV0ZSBDaGVja2luZwotICAgICAgICAgICAgICAgICAgICAvLyBUaGVyZSBpcyBubyBkaWZmZXJlbmNlIGJldHdlZW4gZ2xvYmFsIG9yIGxvY2FsIGFwcGluZm8vZG9jdW1lbnRhdGlvbiwKLSAgICAgICAgICAgICAgICAgICAgLy8gc28gd2UgYXNzdW1lIGl0J3MgYWx3YXlzIGdsb2JhbC4KLSAgICAgICAgICAgICAgICAgICAgYXR0clZhbHVlcyA9IGZBdHRyQ2hlY2tlci5jaGVja0F0dHJpYnV0ZXMoY2hpbGQsIHRydWUsIHNjaGVtYURvYyk7Ci0gICAgICAgICAgICAgICAgICAgIGZBdHRyQ2hlY2tlci5yZXR1cm5BdHRyQXJyYXkoYXR0clZhbHVlcywgc2NoZW1hRG9jKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBjaGlsZCA9IERPTVV0aWwuZ2V0TmV4dFNpYmxpbmdFbGVtZW50KGNoaWxkKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHdoaWxlIChjaGlsZCAhPSBudWxsKTsKLSAgICAgICAgfQotICAgICAgICAvLyBpZiBjb250ZW50cyB3YXMgbnVsbCwgbXVzdCBoYXZlIGJlZW4gc29tZSBraW5kIG9mIGVycm9yOwotICAgICAgICAvLyBub3RoaW5nIHRvIGNvbnRyaWJ1dGUgdG8gUFNWSQotICAgICAgICBpZiAoY29udGVudHMgPT0gbnVsbCkgcmV0dXJuIG51bGw7Ci0KLSAgICAgICAgLy8gZmluZCB0aGUgZ3JhbW1hcjsgZlNjaGVtYUhhbmRsZXIgbXVzdCBiZSBrbm93biEKLSAgICAgICAgU2NoZW1hR3JhbW1hciBncmFtbWFyID0gZlNjaGVtYUhhbmRsZXIuZ2V0R3JhbW1hcihzY2hlbWFEb2MuZlRhcmdldE5hbWVzcGFjZSk7Ci0gICAgICAgIC8vIGZpc2ggb3V0IGxvY2FsIGF0dHJpYnV0ZXMgcGFzc2VkIGZyb20gcGFyZW50Ci0gICAgICAgIFZlY3RvciBhbm5vdGF0aW9uTG9jYWxBdHRycyA9IChWZWN0b3IpcGFyZW50QXR0cnNbWFNBdHRyaWJ1dGVDaGVja2VyLkFUVElEWF9OT05TQ0hFTUFdOwotICAgICAgICAvLyBvcHRpbWl6ZSBmb3IgY2FzZSB3aGVyZSB0aGVyZSBhcmUgbm8gbG9jYWwgYXR0cmlidXRlcwotICAgICAgICBpZihhbm5vdGF0aW9uTG9jYWxBdHRycyAhPSBudWxsICYmICFhbm5vdGF0aW9uTG9jYWxBdHRycy5pc0VtcHR5KCkpIHsKLSAgICAgICAgICAgIFN0cmluZ0J1ZmZlciBsb2NhbFN0ckJ1ZmZlciA9IG5ldyBTdHJpbmdCdWZmZXIoNjQpOwotICAgICAgICAgICAgbG9jYWxTdHJCdWZmZXIuYXBwZW5kKCIgIik7Ci0gICAgICAgICAgICAvLyBWZWN0b3Igc2hvdWxkIGNvbnRhaW4gcmF3bmFtZSB2YWx1ZSBwYWlycwotICAgICAgICAgICAgaW50IGkgPSAwOwotICAgICAgICAgICAgd2hpbGUgKGkgPCBhbm5vdGF0aW9uTG9jYWxBdHRycy5zaXplKCkpIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgcmF3bmFtZSA9IChTdHJpbmcpYW5ub3RhdGlvbkxvY2FsQXR0cnMuZWxlbWVudEF0KGkrKyk7Ci0gICAgICAgICAgICAgICAgaW50IGNvbG9uSW5kZXggPSByYXduYW1lLmluZGV4T2YoJzonKTsKLSAgICAgICAgICAgICAgICBTdHJpbmcgcHJlZml4LCBsb2NhbHBhcnQ7Ci0gICAgICAgICAgICAgICAgaWYgKGNvbG9uSW5kZXggPT0gLTEpIHsKLSAgICAgICAgICAgICAgICAgICAgcHJlZml4ID0gIiI7Ci0gICAgICAgICAgICAgICAgICAgIGxvY2FscGFydCA9IHJhd25hbWU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICBwcmVmaXggPSByYXduYW1lLnN1YnN0cmluZygwLGNvbG9uSW5kZXgpOwotICAgICAgICAgICAgICAgICAgICBsb2NhbHBhcnQgPSByYXduYW1lLnN1YnN0cmluZyhjb2xvbkluZGV4KzEpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBTdHJpbmcgdXJpID0gc2NoZW1hRG9jLmZOYW1lc3BhY2VTdXBwb3J0LmdldFVSSShmU3ltYm9sVGFibGUuYWRkU3ltYm9sKHByZWZpeCkpOwotICAgICAgICAgICAgICAgIGlmIChhbm5vdGF0aW9uRGVjbC5nZXRBdHRyaWJ1dGVOUyh1cmksIGxvY2FscGFydCkubGVuZ3RoKCkgIT0gMCkgewotICAgICAgICAgICAgICAgICAgICBpKys7IC8vIHNraXAgdGhlIG5leHQgdmFsdWUsIHRvbwotICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgbG9jYWxTdHJCdWZmZXIuYXBwZW5kKHJhd25hbWUpCi0gICAgICAgICAgICAgICAgLmFwcGVuZCgiPVwiIik7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIHZhbHVlID0gKFN0cmluZylhbm5vdGF0aW9uTG9jYWxBdHRycy5lbGVtZW50QXQoaSsrKTsKLSAgICAgICAgICAgICAgICAvLyBzZWFyY2ggZm9yIHBlc2t5ICJzIGFuZCA8cyB3aXRoaW4gYXR0ciB2YWx1ZToKLSAgICAgICAgICAgICAgICB2YWx1ZSA9IHByb2Nlc3NBdHRWYWx1ZSh2YWx1ZSk7Ci0gICAgICAgICAgICAgICAgbG9jYWxTdHJCdWZmZXIuYXBwZW5kKHZhbHVlKQotICAgICAgICAgICAgICAgIC5hcHBlbmQoIlwiICIpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gYW5kIG5vdyBzcGxpY2UgaXQgaW50byBwbGFjZTsgaW1tZWRpYXRlbHkgYWZ0ZXIgdGhlIGFubm90YXRpb24gdG9rZW4sIGZvciBzaW1wbGljaXR5J3Mgc2FrZQotICAgICAgICAgICAgU3RyaW5nQnVmZmVyIGNvbnRlbnRCdWZmZXIgPSBuZXcgU3RyaW5nQnVmZmVyKGNvbnRlbnRzLmxlbmd0aCgpICsgbG9jYWxTdHJCdWZmZXIubGVuZ3RoKCkpOwotICAgICAgICAgICAgaW50IGFubm90YXRpb25Ub2tlbkVuZCA9IGNvbnRlbnRzLmluZGV4T2YoU2NoZW1hU3ltYm9scy5FTFRfQU5OT1RBVElPTik7Ci0gICAgICAgICAgICAvLyBhbm5vdGF0aW9uIG11c3Qgb2NjdXIgc29tZXdoZXJlIG9yIHdlJ3JlIGluIGJpZyB0cm91YmxlLi4uCi0gICAgICAgICAgICBpZihhbm5vdGF0aW9uVG9rZW5FbmQgPT0gLTEpIHJldHVybiBudWxsOwotICAgICAgICAgICAgYW5ub3RhdGlvblRva2VuRW5kICs9IFNjaGVtYVN5bWJvbHMuRUxUX0FOTk9UQVRJT04ubGVuZ3RoKCk7Ci0gICAgICAgICAgICBjb250ZW50QnVmZmVyLmFwcGVuZChjb250ZW50cy5zdWJzdHJpbmcoMCxhbm5vdGF0aW9uVG9rZW5FbmQpKTsKLSAgICAgICAgICAgIGNvbnRlbnRCdWZmZXIuYXBwZW5kKGxvY2FsU3RyQnVmZmVyLnRvU3RyaW5nKCkpOwotICAgICAgICAgICAgY29udGVudEJ1ZmZlci5hcHBlbmQoY29udGVudHMuc3Vic3RyaW5nKGFubm90YXRpb25Ub2tlbkVuZCwgY29udGVudHMubGVuZ3RoKCkpKTsKLSAgICAgICAgICAgIGZpbmFsIFN0cmluZyBhbm5vdGF0aW9uID0gY29udGVudEJ1ZmZlci50b1N0cmluZygpOwotICAgICAgICAgICAgaWYgKGZWYWxpZGF0ZUFubm90YXRpb25zKSB7Ci0gICAgICAgICAgICAgICAgc2NoZW1hRG9jLmFkZEFubm90YXRpb24obmV3IFhTQW5ub3RhdGlvbkluZm8oYW5ub3RhdGlvbiwgYW5ub3RhdGlvbkRlY2wpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiBuZXcgWFNBbm5vdGF0aW9uSW1wbChhbm5vdGF0aW9uLCBncmFtbWFyKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIGlmIChmVmFsaWRhdGVBbm5vdGF0aW9ucykgewotICAgICAgICAgICAgICAgIHNjaGVtYURvYy5hZGRBbm5vdGF0aW9uKG5ldyBYU0Fubm90YXRpb25JbmZvKGNvbnRlbnRzLCBhbm5vdGF0aW9uRGVjbCkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIG5ldyBYU0Fubm90YXRpb25JbXBsKGNvbnRlbnRzLCBncmFtbWFyKTsKLSAgICAgICAgfQotCi0gICAgfQotCi0gICAgWFNBbm5vdGF0aW9uSW1wbCB0cmF2ZXJzZVN5bnRoZXRpY0Fubm90YXRpb24oRWxlbWVudCBhbm5vdGF0aW9uUGFyZW50LCBTdHJpbmcgaW5pdGlhbENvbnRlbnQsCi0gICAgICAgICAgICBPYmplY3RbXSBwYXJlbnRBdHRycywgYm9vbGVhbiBpc0dsb2JhbCwgWFNEb2N1bWVudEluZm8gc2NoZW1hRG9jKSB7Ci0KLSAgICAgICAgU3RyaW5nIGNvbnRlbnRzID0gaW5pdGlhbENvbnRlbnQ7Ci0KLSAgICAgICAgLy8gZmluZCB0aGUgZ3JhbW1hcjsgZlNjaGVtYUhhbmRsZXIgbXVzdCBiZSBrbm93biEKLSAgICAgICAgU2NoZW1hR3JhbW1hciBncmFtbWFyID0gZlNjaGVtYUhhbmRsZXIuZ2V0R3JhbW1hcihzY2hlbWFEb2MuZlRhcmdldE5hbWVzcGFjZSk7Ci0gICAgICAgIC8vIGZpc2ggb3V0IGxvY2FsIGF0dHJpYnV0ZXMgcGFzc2VkIGZyb20gcGFyZW50Ci0gICAgICAgIFZlY3RvciBhbm5vdGF0aW9uTG9jYWxBdHRycyA9IChWZWN0b3IpcGFyZW50QXR0cnNbWFNBdHRyaWJ1dGVDaGVja2VyLkFUVElEWF9OT05TQ0hFTUFdOwotICAgICAgICAvLyBvcHRpbWl6ZSBmb3IgY2FzZSB3aGVyZSB0aGVyZSBhcmUgbm8gbG9jYWwgYXR0cmlidXRlcwotICAgICAgICBpZiAoYW5ub3RhdGlvbkxvY2FsQXR0cnMgIT0gbnVsbCAmJiAhYW5ub3RhdGlvbkxvY2FsQXR0cnMuaXNFbXB0eSgpKSB7Ci0gICAgICAgICAgICBTdHJpbmdCdWZmZXIgbG9jYWxTdHJCdWZmZXIgPSBuZXcgU3RyaW5nQnVmZmVyKDY0KTsKLSAgICAgICAgICAgIGxvY2FsU3RyQnVmZmVyLmFwcGVuZCgiICIpOwotICAgICAgICAgICAgLy8gVmVjdG9yIHNob3VsZCBjb250YWluIHJhd25hbWUgdmFsdWUgcGFpcnMKLSAgICAgICAgICAgIGludCBpID0gMDsKLSAgICAgICAgICAgIHdoaWxlIChpIDwgYW5ub3RhdGlvbkxvY2FsQXR0cnMuc2l6ZSgpKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIHJhd25hbWUgPSAoU3RyaW5nKWFubm90YXRpb25Mb2NhbEF0dHJzLmVsZW1lbnRBdChpKyspOwotICAgICAgICAgICAgICAgIGludCBjb2xvbkluZGV4ID0gcmF3bmFtZS5pbmRleE9mKCc6Jyk7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIHByZWZpeCwgbG9jYWxwYXJ0OwotICAgICAgICAgICAgICAgIGlmIChjb2xvbkluZGV4ID09IC0xKSB7Ci0gICAgICAgICAgICAgICAgICAgIHByZWZpeCA9ICIiOwotICAgICAgICAgICAgICAgICAgICBsb2NhbHBhcnQgPSByYXduYW1lOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgcHJlZml4ID0gcmF3bmFtZS5zdWJzdHJpbmcoMCxjb2xvbkluZGV4KTsKLSAgICAgICAgICAgICAgICAgICAgbG9jYWxwYXJ0ID0gcmF3bmFtZS5zdWJzdHJpbmcoY29sb25JbmRleCsxKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgU3RyaW5nIHVyaSA9IHNjaGVtYURvYy5mTmFtZXNwYWNlU3VwcG9ydC5nZXRVUkkoZlN5bWJvbFRhYmxlLmFkZFN5bWJvbChwcmVmaXgpKTsKLSAgICAgICAgICAgICAgICBsb2NhbFN0ckJ1ZmZlci5hcHBlbmQocmF3bmFtZSkKLSAgICAgICAgICAgICAgICAuYXBwZW5kKCI9XCIiKTsKLSAgICAgICAgICAgICAgICBTdHJpbmcgdmFsdWUgPSAoU3RyaW5nKWFubm90YXRpb25Mb2NhbEF0dHJzLmVsZW1lbnRBdChpKyspOwotICAgICAgICAgICAgICAgIC8vIHNlYXJjaCBmb3IgcGVza3kgInMgYW5kIDxzIHdpdGhpbiBhdHRyIHZhbHVlOgotICAgICAgICAgICAgICAgIHZhbHVlID0gcHJvY2Vzc0F0dFZhbHVlKHZhbHVlKTsKLSAgICAgICAgICAgICAgICBsb2NhbFN0ckJ1ZmZlci5hcHBlbmQodmFsdWUpCi0gICAgICAgICAgICAgICAgLmFwcGVuZCgiXCIgIik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyBhbmQgbm93IHNwbGljZSBpdCBpbnRvIHBsYWNlOyBpbW1lZGlhdGVseSBhZnRlciB0aGUgYW5ub3RhdGlvbiB0b2tlbiwgZm9yIHNpbXBsaWNpdHkncyBzYWtlCi0gICAgICAgICAgICBTdHJpbmdCdWZmZXIgY29udGVudEJ1ZmZlciA9IG5ldyBTdHJpbmdCdWZmZXIoY29udGVudHMubGVuZ3RoKCkgKyBsb2NhbFN0ckJ1ZmZlci5sZW5ndGgoKSk7Ci0gICAgICAgICAgICBpbnQgYW5ub3RhdGlvblRva2VuRW5kID0gY29udGVudHMuaW5kZXhPZihTY2hlbWFTeW1ib2xzLkVMVF9BTk5PVEFUSU9OKTsKLSAgICAgICAgICAgIC8vIGFubm90YXRpb24gbXVzdCBvY2N1ciBzb21ld2hlcmUgb3Igd2UncmUgaW4gYmlnIHRyb3VibGUuLi4KLSAgICAgICAgICAgIGlmKGFubm90YXRpb25Ub2tlbkVuZCA9PSAtMSkgcmV0dXJuIG51bGw7Ci0gICAgICAgICAgICBhbm5vdGF0aW9uVG9rZW5FbmQgKz0gU2NoZW1hU3ltYm9scy5FTFRfQU5OT1RBVElPTi5sZW5ndGgoKTsKLSAgICAgICAgICAgIGNvbnRlbnRCdWZmZXIuYXBwZW5kKGNvbnRlbnRzLnN1YnN0cmluZygwLGFubm90YXRpb25Ub2tlbkVuZCkpOwotICAgICAgICAgICAgY29udGVudEJ1ZmZlci5hcHBlbmQobG9jYWxTdHJCdWZmZXIudG9TdHJpbmcoKSk7Ci0gICAgICAgICAgICBjb250ZW50QnVmZmVyLmFwcGVuZChjb250ZW50cy5zdWJzdHJpbmcoYW5ub3RhdGlvblRva2VuRW5kLCBjb250ZW50cy5sZW5ndGgoKSkpOwotICAgICAgICAgICAgZmluYWwgU3RyaW5nIGFubm90YXRpb24gPSBjb250ZW50QnVmZmVyLnRvU3RyaW5nKCk7Ci0gICAgICAgICAgICBpZiAoZlZhbGlkYXRlQW5ub3RhdGlvbnMpIHsKLSAgICAgICAgICAgICAgICBzY2hlbWFEb2MuYWRkQW5ub3RhdGlvbihuZXcgWFNBbm5vdGF0aW9uSW5mbyhhbm5vdGF0aW9uLCBhbm5vdGF0aW9uUGFyZW50KSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gbmV3IFhTQW5ub3RhdGlvbkltcGwoYW5ub3RhdGlvbiwgZ3JhbW1hcik7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBpZiAoZlZhbGlkYXRlQW5ub3RhdGlvbnMpIHsKLSAgICAgICAgICAgICAgICBzY2hlbWFEb2MuYWRkQW5ub3RhdGlvbihuZXcgWFNBbm5vdGF0aW9uSW5mbyhjb250ZW50cywgYW5ub3RhdGlvblBhcmVudCkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIG5ldyBYU0Fubm90YXRpb25JbXBsKGNvbnRlbnRzLCBncmFtbWFyKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8vIHRoZSBRTmFtZSBzaW1wbGUgdHlwZSB1c2VkIHRvIHJlc29sdmUgcW5hbWVzCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgWFNTaW1wbGVUeXBlIGZRTmFtZURWID0gKFhTU2ltcGxlVHlwZSlTY2hlbWFHcmFtbWFyLlNHX1NjaGVtYU5TLmdldEdsb2JhbFR5cGVEZWNsKFNjaGVtYVN5bWJvbHMuQVRUVkFMX1FOQU1FKTsKLSAgICAvLyBUZW1wIGRhdGEgc3RydWN0dXJlcyB0byBiZSByZS11c2VkIGluIHRyYXZlcnNpbmcgZmFjZXRzCi0gICAgcHJpdmF0ZSBTdHJpbmdCdWZmZXIgZlBhdHRlcm4gPSBuZXcgU3RyaW5nQnVmZmVyKCk7Ci0gICAgcHJpdmF0ZSBmaW5hbCBYU0ZhY2V0cyB4c0ZhY2V0cyA9IG5ldyBYU0ZhY2V0cygpOwotCi0gICAgc3RhdGljIGZpbmFsIGNsYXNzIEZhY2V0SW5mbyB7Ci0KLSAgICAgICAgZmluYWwgWFNGYWNldHMgZmFjZXRkYXRhOwotICAgICAgICBmaW5hbCBFbGVtZW50IG5vZGVBZnRlckZhY2V0czsKLSAgICAgICAgZmluYWwgc2hvcnQgZlByZXNlbnRGYWNldHM7Ci0gICAgICAgIGZpbmFsIHNob3J0IGZGaXhlZEZhY2V0czsKLQotICAgICAgICBGYWNldEluZm8oWFNGYWNldHMgZmFjZXRzLCBFbGVtZW50IG5vZGVBZnRlckZhY2V0cywgc2hvcnQgcHJlc2VudEZhY2V0cywgc2hvcnQgZml4ZWRGYWNldHMpIHsKLSAgICAgICAgICAgIGZhY2V0ZGF0YSA9IGZhY2V0czsKLSAgICAgICAgICAgIHRoaXMubm9kZUFmdGVyRmFjZXRzID0gbm9kZUFmdGVyRmFjZXRzOwotICAgICAgICAgICAgZlByZXNlbnRGYWNldHMgPSBwcmVzZW50RmFjZXRzOwotICAgICAgICAgICAgZkZpeGVkRmFjZXRzID0gZml4ZWRGYWNldHM7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBGYWNldEluZm8gdHJhdmVyc2VGYWNldHMoRWxlbWVudCBjb250ZW50LAotICAgICAgICAgICAgWFNTaW1wbGVUeXBlIGJhc2VWYWxpZGF0b3IsCi0gICAgICAgICAgICBYU0RvY3VtZW50SW5mbyBzY2hlbWFEb2MpIHsKLQotICAgICAgICBzaG9ydCBmYWNldHNQcmVzZW50ID0gMCA7Ci0gICAgICAgIHNob3J0IGZhY2V0c0ZpeGVkID0gMDsgLy8gZmFjZXRzIHRoYXQgaGF2ZSBmaXhlZD0idHJ1ZSIKLSAgICAgICAgU3RyaW5nIGZhY2V0OwotICAgICAgICBib29sZWFuIGhhc1FOYW1lID0gY29udGFpbnNRTmFtZShiYXNlVmFsaWRhdG9yKTsKLSAgICAgICAgVmVjdG9yIGVudW1EYXRhID0gbnVsbDsKLSAgICAgICAgWFNPYmplY3RMaXN0SW1wbCBlbnVtQW5ub3RhdGlvbnMgPSBudWxsOwotICAgICAgICBYU09iamVjdExpc3RJbXBsIHBhdHRlcm5Bbm5vdGF0aW9ucyA9IG51bGw7Ci0gICAgICAgIFZlY3RvciBlbnVtTlNEZWNscyA9IGhhc1FOYW1lID8gbmV3IFZlY3RvcigpIDogbnVsbDsKLSAgICAgICAgaW50IGN1cnJlbnRGYWNldCA9IDA7Ci0gICAgICAgIHhzRmFjZXRzLnJlc2V0KCk7Ci0gICAgICAgIHdoaWxlIChjb250ZW50ICE9IG51bGwpIHsKLSAgICAgICAgICAgIC8vIEdlbmVyYWwgQXR0cmlidXRlIENoZWNraW5nCi0gICAgICAgICAgICBPYmplY3RbXSBhdHRycyA9IG51bGw7Ci0gICAgICAgICAgICBmYWNldCA9IERPTVV0aWwuZ2V0TG9jYWxOYW1lKGNvbnRlbnQpOwotICAgICAgICAgICAgaWYgKGZhY2V0LmVxdWFscyhTY2hlbWFTeW1ib2xzLkVMVF9FTlVNRVJBVElPTikpIHsKLSAgICAgICAgICAgICAgICBhdHRycyA9IGZBdHRyQ2hlY2tlci5jaGVja0F0dHJpYnV0ZXMoY29udGVudCwgZmFsc2UsIHNjaGVtYURvYywgaGFzUU5hbWUpOwotICAgICAgICAgICAgICAgIFN0cmluZyBlbnVtVmFsID0gKFN0cmluZylhdHRyc1tYU0F0dHJpYnV0ZUNoZWNrZXIuQVRUSURYX1ZBTFVFXTsKLSAgICAgICAgICAgICAgICAvLyBUaGUgZmFjZXQgY2FuJ3QgYmUgdXNlZCBpZiB0aGUgdmFsdWUgaXMgbWlzc2luZy4gSWdub3JlCi0gICAgICAgICAgICAgICAgLy8gdGhpcyBmYWNldCBlbGVtZW50LgotICAgICAgICAgICAgICAgIGlmIChlbnVtVmFsID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoInM0cy1hdHQtbXVzdC1hcHBlYXIiLCBuZXcgT2JqZWN0W117U2NoZW1hU3ltYm9scy5FTFRfRU5VTUVSQVRJT04sIFNjaGVtYVN5bWJvbHMuQVRUX1ZBTFVFfSwgY29udGVudCk7Ci0gICAgICAgICAgICAgICAgICAgIGZBdHRyQ2hlY2tlci5yZXR1cm5BdHRyQXJyYXkgKGF0dHJzLCBzY2hlbWFEb2MpOwotICAgICAgICAgICAgICAgICAgICBjb250ZW50ID0gRE9NVXRpbC5nZXROZXh0U2libGluZ0VsZW1lbnQoY29udGVudCk7Ci0gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIE5hbWVzcGFjZVN1cHBvcnQgbnNEZWNscyA9IChOYW1lc3BhY2VTdXBwb3J0KWF0dHJzW1hTQXR0cmlidXRlQ2hlY2tlci5BVFRJRFhfRU5VTU5TREVDTFNdOwotCi0gICAgICAgICAgICAgICAgLy8gZm9yIE5PVEFUSU9OIHR5cGVzLCBuZWVkIHRvIGNoZWNrIHdoZXRoZXIgdGhlcmUgaXMgYSBub3RhdGlvbgotICAgICAgICAgICAgICAgIC8vIGRlY2xhcmVkIHdpdGggdGhlIHNhbWUgbmFtZSBhcyB0aGUgZW51bWVyYXRpb24gdmFsdWUuCi0gICAgICAgICAgICAgICAgaWYgKGJhc2VWYWxpZGF0b3IuZ2V0VmFyaWV0eSgpID09IFhTU2ltcGxlVHlwZS5WQVJJRVRZX0FUT01JQyAmJgotICAgICAgICAgICAgICAgICAgICAgICAgYmFzZVZhbGlkYXRvci5nZXRQcmltaXRpdmVLaW5kKCkgPT0gWFNTaW1wbGVUeXBlLlBSSU1JVElWRV9OT1RBVElPTikgewotICAgICAgICAgICAgICAgICAgICAvLyBuZWVkIHRvIHVzZSB0aGUgbmFtZXNwYWNlIGNvbnRleHQgcmV0dXJuZWQgZnJvbSBjaGVja0F0dHJpYnV0ZXMKLSAgICAgICAgICAgICAgICAgICAgc2NoZW1hRG9jLmZWYWxpZGF0aW9uQ29udGV4dC5zZXROYW1lc3BhY2VTdXBwb3J0KG5zRGVjbHMpOwotICAgICAgICAgICAgICAgICAgICBPYmplY3Qgbm90YXRpb24gPSBudWxsOwotICAgICAgICAgICAgICAgICAgICB0cnl7Ci0gICAgICAgICAgICAgICAgICAgICAgICBRTmFtZSB0ZW1wID0gKFFOYW1lKWZRTmFtZURWLnZhbGlkYXRlKGVudW1WYWwsIHNjaGVtYURvYy5mVmFsaWRhdGlvbkNvbnRleHQsIG51bGwpOwotICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHJ5IHRvIGdldCB0aGUgbm90YXRpb24gZGVjbC4gaWYgZmFpbGVkLCBnZXRHbG9iYWxEZWNsCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyByZXBvcnRzIGFuIGVycm9yLCBzbyB3ZSBkb24ndCBuZWVkIHRvIHJlcG9ydCBvbmUgYWdhaW4uCi0gICAgICAgICAgICAgICAgICAgICAgICBub3RhdGlvbiA9IGZTY2hlbWFIYW5kbGVyLmdldEdsb2JhbERlY2woc2NoZW1hRG9jLCBYU0RIYW5kbGVyLk5PVEFUSU9OX1RZUEUsIHRlbXAsIGNvbnRlbnQpOwotICAgICAgICAgICAgICAgICAgICB9Y2F0Y2goSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24gZXgpewotICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoZXguZ2V0S2V5KCksIGV4LmdldEFyZ3MoKSwgY29udGVudCk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgaWYgKG5vdGF0aW9uID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIEVpdGhlciB0aGUgUU5hbWUgdmFsdWUgaXMgaW52YWxpZCwgb3IgaXQgZG9lbnMndAotICAgICAgICAgICAgICAgICAgICAgICAgLy8gcmVzb2x2ZSB0byBhIG5vdGF0aW9uIGRlY2xhcmF0aW9uLgotICAgICAgICAgICAgICAgICAgICAgICAgLy8gSWdub3JlIHRoaXMgZmFjZXQsIHRvIGF2b2lkIGluc3RhbmNlIHZhbGlkYXRpb24gcHJvYmxlbXMKLSAgICAgICAgICAgICAgICAgICAgICAgIGZBdHRyQ2hlY2tlci5yZXR1cm5BdHRyQXJyYXkgKGF0dHJzLCBzY2hlbWFEb2MpOwotICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudCA9IERPTVV0aWwuZ2V0TmV4dFNpYmxpbmdFbGVtZW50KGNvbnRlbnQpOwotICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgLy8gcmVzdG9yZSB0byB0aGUgbm9ybWFsIG5hbWVzcGFjZSBjb250ZXh0Ci0gICAgICAgICAgICAgICAgICAgIHNjaGVtYURvYy5mVmFsaWRhdGlvbkNvbnRleHQuc2V0TmFtZXNwYWNlU3VwcG9ydChzY2hlbWFEb2MuZk5hbWVzcGFjZVN1cHBvcnQpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpZiAoZW51bURhdGEgPT0gbnVsbCl7Ci0gICAgICAgICAgICAgICAgICAgIGVudW1EYXRhID0gbmV3IFZlY3RvcigpOwotICAgICAgICAgICAgICAgICAgICBlbnVtQW5ub3RhdGlvbnMgPSBuZXcgWFNPYmplY3RMaXN0SW1wbCgpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbnVtRGF0YS5hZGRFbGVtZW50KGVudW1WYWwpOwotICAgICAgICAgICAgICAgIGVudW1Bbm5vdGF0aW9ucy5hZGRYU09iamVjdChudWxsKTsKLSAgICAgICAgICAgICAgICBpZiAoaGFzUU5hbWUpCi0gICAgICAgICAgICAgICAgICAgIGVudW1OU0RlY2xzLmFkZEVsZW1lbnQobnNEZWNscyk7Ci0gICAgICAgICAgICAgICAgRWxlbWVudCBjaGlsZCA9IERPTVV0aWwuZ2V0Rmlyc3RDaGlsZEVsZW1lbnQoIGNvbnRlbnQgKTsKLQotICAgICAgICAgICAgICAgIGlmIChjaGlsZCAhPSBudWxsICYmCi0gICAgICAgICAgICAgICAgICAgIERPTVV0aWwuZ2V0TG9jYWxOYW1lKGNoaWxkKS5lcXVhbHMoU2NoZW1hU3ltYm9scy5FTFRfQU5OT1RBVElPTikpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gdHJhdmVyc2UgYW5ub3RhdGlvbiBpZiBhbnkKLSAgICAgICAgICAgICAgICAgICAgZW51bUFubm90YXRpb25zLmFkZFhTT2JqZWN0KGVudW1Bbm5vdGF0aW9ucy5nZXRMZW5ndGgoKS0xLHRyYXZlcnNlQW5ub3RhdGlvbkRlY2woY2hpbGQsIGF0dHJzLCBmYWxzZSwgc2NoZW1hRG9jKSk7Ci0gICAgICAgICAgICAgICAgICAgIGNoaWxkID0gRE9NVXRpbC5nZXROZXh0U2libGluZ0VsZW1lbnQoY2hpbGQpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHRleHQgPSBET01VdGlsLmdldFN5bnRoZXRpY0Fubm90YXRpb24oY29udGVudCk7Ci0gICAgICAgICAgICAgICAgICAgIGlmICh0ZXh0ICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGVudW1Bbm5vdGF0aW9ucy5hZGRYU09iamVjdChlbnVtQW5ub3RhdGlvbnMuZ2V0TGVuZ3RoKCktMSwgdHJhdmVyc2VTeW50aGV0aWNBbm5vdGF0aW9uKGNvbnRlbnQsIHRleHQsIGF0dHJzLCBmYWxzZSwgc2NoZW1hRG9jKSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaWYgKGNoaWxkICE9bnVsbCkgewotICAgICAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcigiczRzLWVsdC1tdXN0LW1hdGNoLjEiLCBuZXcgT2JqZWN0W117ImVudW1lcmF0aW9uIiwgIihhbm5vdGF0aW9uPykiLCBET01VdGlsLmdldExvY2FsTmFtZShjaGlsZCl9LCBjaGlsZCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoZmFjZXQuZXF1YWxzKFNjaGVtYVN5bWJvbHMuRUxUX1BBVFRFUk4pKSB7Ci0gICAgICAgICAgICAgICAgZmFjZXRzUHJlc2VudCB8PSBYU1NpbXBsZVR5cGUuRkFDRVRfUEFUVEVSTjsKLSAgICAgICAgICAgICAgICBhdHRycyA9IGZBdHRyQ2hlY2tlci5jaGVja0F0dHJpYnV0ZXMoY29udGVudCwgZmFsc2UsIHNjaGVtYURvYyk7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIHBhdHRlcm5WYWwgPSAoU3RyaW5nKWF0dHJzW1hTQXR0cmlidXRlQ2hlY2tlci5BVFRJRFhfVkFMVUVdOwotICAgICAgICAgICAgICAgIC8vIFRoZSBmYWNldCBjYW4ndCBiZSB1c2VkIGlmIHRoZSB2YWx1ZSBpcyBtaXNzaW5nLiBJZ25vcmUKLSAgICAgICAgICAgICAgICAvLyB0aGlzIGZhY2V0IGVsZW1lbnQuCi0gICAgICAgICAgICAgICAgaWYgKHBhdHRlcm5WYWwgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcigiczRzLWF0dC1tdXN0LWFwcGVhciIsIG5ldyBPYmplY3RbXXtTY2hlbWFTeW1ib2xzLkVMVF9QQVRURVJOLCBTY2hlbWFTeW1ib2xzLkFUVF9WQUxVRX0sIGNvbnRlbnQpOwotICAgICAgICAgICAgICAgICAgICBmQXR0ckNoZWNrZXIucmV0dXJuQXR0ckFycmF5IChhdHRycywgc2NoZW1hRG9jKTsKLSAgICAgICAgICAgICAgICAgICAgY29udGVudCA9IERPTVV0aWwuZ2V0TmV4dFNpYmxpbmdFbGVtZW50KGNvbnRlbnQpOwotICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBpZiAoZlBhdHRlcm4ubGVuZ3RoKCkgPT0gMCkgewotICAgICAgICAgICAgICAgICAgICBmUGF0dGVybi5hcHBlbmQocGF0dGVyblZhbCk7Ci0gICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgICAgICAgICAgICAgICAgIC8vZGF0YXR5cGVzOiA1LjIuNCBwYXR0ZXJuOiBzcmMtbXVsdGlwbGUtcGF0dGVybgotICAgICAgICAgICAgICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICAgICAgICAgICAgICAgICAgZlBhdHRlcm4uYXBwZW5kKCJ8Iik7Ci0gICAgICAgICAgICAgICAgICAgIGZQYXR0ZXJuLmFwcGVuZChwYXR0ZXJuVmFsKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgRWxlbWVudCBjaGlsZCA9IERPTVV0aWwuZ2V0Rmlyc3RDaGlsZEVsZW1lbnQoIGNvbnRlbnQgKTsKLSAgICAgICAgICAgICAgICBpZiAoY2hpbGQgIT0gbnVsbCAmJgotICAgICAgICAgICAgICAgICAgICAgICAgRE9NVXRpbC5nZXRMb2NhbE5hbWUoY2hpbGQpLmVxdWFscyhTY2hlbWFTeW1ib2xzLkVMVF9BTk5PVEFUSU9OKSkgewotICAgICAgICAgICAgICAgICAgICAvLyB0cmF2ZXJzZSBhbm5vdGF0aW9uIGlmIGFueQotICAgICAgICAgICAgICAgICAgICBpZiAocGF0dGVybkFubm90YXRpb25zID09IG51bGwpewotICAgICAgICAgICAgICAgICAgICAgICAgcGF0dGVybkFubm90YXRpb25zID0gbmV3IFhTT2JqZWN0TGlzdEltcGwoKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBwYXR0ZXJuQW5ub3RhdGlvbnMuYWRkWFNPYmplY3QodHJhdmVyc2VBbm5vdGF0aW9uRGVjbChjaGlsZCwgYXR0cnMsIGZhbHNlLCBzY2hlbWFEb2MpKTsKLSAgICAgICAgICAgICAgICAgICAgY2hpbGQgPSBET01VdGlsLmdldE5leHRTaWJsaW5nRWxlbWVudChjaGlsZCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdGV4dCA9IERPTVV0aWwuZ2V0U3ludGhldGljQW5ub3RhdGlvbihjb250ZW50KTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKHRleHQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBhdHRlcm5Bbm5vdGF0aW9ucyA9PSBudWxsKXsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXR0ZXJuQW5ub3RhdGlvbnMgPSBuZXcgWFNPYmplY3RMaXN0SW1wbCgpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgcGF0dGVybkFubm90YXRpb25zLmFkZFhTT2JqZWN0KHRyYXZlcnNlU3ludGhldGljQW5ub3RhdGlvbihjb250ZW50LCB0ZXh0LCBhdHRycywgZmFsc2UsIHNjaGVtYURvYykpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGlmIChjaGlsZCAhPW51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoInM0cy1lbHQtbXVzdC1tYXRjaC4xIiwgbmV3IE9iamVjdFtdeyJwYXR0ZXJuIiwgIihhbm5vdGF0aW9uPykiLCBET01VdGlsLmdldExvY2FsTmFtZShjaGlsZCl9LCBjaGlsZCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgaWYgKGZhY2V0LmVxdWFscyhTY2hlbWFTeW1ib2xzLkVMVF9NSU5MRU5HVEgpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRGYWNldCA9IFhTU2ltcGxlVHlwZS5GQUNFVF9NSU5MRU5HVEg7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgaWYgKGZhY2V0LmVxdWFscyhTY2hlbWFTeW1ib2xzLkVMVF9NQVhMRU5HVEgpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRGYWNldCA9IFhTU2ltcGxlVHlwZS5GQUNFVF9NQVhMRU5HVEg7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgaWYgKGZhY2V0LmVxdWFscyhTY2hlbWFTeW1ib2xzLkVMVF9NQVhFWENMVVNJVkUpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRGYWNldCA9IFhTU2ltcGxlVHlwZS5GQUNFVF9NQVhFWENMVVNJVkU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgaWYgKGZhY2V0LmVxdWFscyhTY2hlbWFTeW1ib2xzLkVMVF9NQVhJTkNMVVNJVkUpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRGYWNldCA9IFhTU2ltcGxlVHlwZS5GQUNFVF9NQVhJTkNMVVNJVkU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgaWYgKGZhY2V0LmVxdWFscyhTY2hlbWFTeW1ib2xzLkVMVF9NSU5FWENMVVNJVkUpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRGYWNldCA9IFhTU2ltcGxlVHlwZS5GQUNFVF9NSU5FWENMVVNJVkU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgaWYgKGZhY2V0LmVxdWFscyhTY2hlbWFTeW1ib2xzLkVMVF9NSU5JTkNMVVNJVkUpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRGYWNldCA9IFhTU2ltcGxlVHlwZS5GQUNFVF9NSU5JTkNMVVNJVkU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgaWYgKGZhY2V0LmVxdWFscyhTY2hlbWFTeW1ib2xzLkVMVF9UT1RBTERJR0lUUykpIHsKLSAgICAgICAgICAgICAgICAgICAgY3VycmVudEZhY2V0ID0gWFNTaW1wbGVUeXBlLkZBQ0VUX1RPVEFMRElHSVRTOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIGlmIChmYWNldC5lcXVhbHMoU2NoZW1hU3ltYm9scy5FTFRfRlJBQ1RJT05ESUdJVFMpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRGYWNldCA9IFhTU2ltcGxlVHlwZS5GQUNFVF9GUkFDVElPTkRJR0lUUzsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSBpZiAoZmFjZXQuZXF1YWxzKFNjaGVtYVN5bWJvbHMuRUxUX1dISVRFU1BBQ0UpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRGYWNldCA9IFhTU2ltcGxlVHlwZS5GQUNFVF9XSElURVNQQUNFOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIGlmIChmYWNldC5lcXVhbHMoU2NoZW1hU3ltYm9scy5FTFRfTEVOR1RIKSkgewotICAgICAgICAgICAgICAgICAgICBjdXJyZW50RmFjZXQgPSBYU1NpbXBsZVR5cGUuRkFDRVRfTEVOR1RIOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7ICAgLy8gYSBub24tZmFjZXQKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBhdHRycyA9IGZBdHRyQ2hlY2tlci5jaGVja0F0dHJpYnV0ZXMoY29udGVudCwgZmFsc2UsIHNjaGVtYURvYyk7Ci0KLSAgICAgICAgICAgICAgICAvLyBjaGVjayBmb3IgZHVwbGljYXRlIGZhY2V0cwotICAgICAgICAgICAgICAgIGlmICgoZmFjZXRzUHJlc2VudCAmIGN1cnJlbnRGYWNldCkgIT0gMCkgewotICAgICAgICAgICAgICAgICAgICAvLyBJZ25vcmUgdGhpcyBmYWNldCwgdG8gYXZvaWQgY29ycnVwdGluZyB0aGUgcHJldmlvdXMgZmFjZXQKLSAgICAgICAgICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoInNyYy1zaW5nbGUtZmFjZXQtdmFsdWUiLCBuZXcgT2JqZWN0W117ZmFjZXR9LCBjb250ZW50KTsKLSAgICAgICAgICAgICAgICAgICAgZkF0dHJDaGVja2VyLnJldHVybkF0dHJBcnJheSAoYXR0cnMsIHNjaGVtYURvYyk7Ci0gICAgICAgICAgICAgICAgICAgIGNvbnRlbnQgPSBET01VdGlsLmdldE5leHRTaWJsaW5nRWxlbWVudChjb250ZW50KTsKLSAgICAgICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgLy8gVGhlIGZhY2V0IGNhbid0IGJlIHVzZWQgaWYgdGhlIHZhbHVlIGlzIG1pc3NpbmcuIElnbm9yZQotICAgICAgICAgICAgICAgIC8vIHRoaXMgZmFjZXQgZWxlbWVudC4KLSAgICAgICAgICAgICAgICBpZiAoYXR0cnNbWFNBdHRyaWJ1dGVDaGVja2VyLkFUVElEWF9WQUxVRV0gPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAvLyBSZXBvcnQgYW4gZXJyb3IgaWYgdGhlICJ2YWx1ZSIgYXR0cmlidXRlIGlzIG1pc3NpbmcuCi0gICAgICAgICAgICAgICAgICAgIC8vIElmIGl0J3Mgbm90IG1pc3NpbmcsIHRoZW4gaXRzIHZhbHVlIGlzIGludmFsaWQsIGFuZCBhbgotICAgICAgICAgICAgICAgICAgICAvLyBlcnJvciBzaG91bGQgaGF2ZSBhbHJlYWR5IGJlZW4gcmVwb3J0ZWQgYnkgdGhlCi0gICAgICAgICAgICAgICAgICAgIC8vIGF0dHJpYnV0ZSBjaGVja2VyLgotICAgICAgICAgICAgICAgICAgICBpZiAoY29udGVudC5nZXRBdHRyaWJ1dGVOb2RlTlMobnVsbCwgInZhbHVlIikgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoInM0cy1hdHQtbXVzdC1hcHBlYXIiLCBuZXcgT2JqZWN0W117Y29udGVudC5nZXRMb2NhbE5hbWUoKSwgU2NoZW1hU3ltYm9scy5BVFRfVkFMVUV9LCBjb250ZW50KTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBmQXR0ckNoZWNrZXIucmV0dXJuQXR0ckFycmF5IChhdHRycywgc2NoZW1hRG9jKTsKLSAgICAgICAgICAgICAgICAgICAgY29udGVudCA9IERPTVV0aWwuZ2V0TmV4dFNpYmxpbmdFbGVtZW50KGNvbnRlbnQpOwotICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBmYWNldHNQcmVzZW50IHw9IGN1cnJlbnRGYWNldDsKLSAgICAgICAgICAgICAgICAvLyBjaGVjayBmb3IgZml4ZWQgZmFjZXQKLSAgICAgICAgICAgICAgICBpZiAoKChCb29sZWFuKWF0dHJzW1hTQXR0cmlidXRlQ2hlY2tlci5BVFRJRFhfRklYRURdKS5ib29sZWFuVmFsdWUoKSkgewotICAgICAgICAgICAgICAgICAgICBmYWNldHNGaXhlZCB8PSBjdXJyZW50RmFjZXQ7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHN3aXRjaCAoY3VycmVudEZhY2V0KSB7Ci0gICAgICAgICAgICAgICAgY2FzZSBYU1NpbXBsZVR5cGUuRkFDRVRfTUlOTEVOR1RIOgotICAgICAgICAgICAgICAgICAgICB4c0ZhY2V0cy5taW5MZW5ndGggPSAoKFhJbnQpYXR0cnNbWFNBdHRyaWJ1dGVDaGVja2VyLkFUVElEWF9WQUxVRV0pLmludFZhbHVlKCk7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGNhc2UgWFNTaW1wbGVUeXBlLkZBQ0VUX01BWExFTkdUSDoKLSAgICAgICAgICAgICAgICAgICAgeHNGYWNldHMubWF4TGVuZ3RoID0gKChYSW50KWF0dHJzW1hTQXR0cmlidXRlQ2hlY2tlci5BVFRJRFhfVkFMVUVdKS5pbnRWYWx1ZSgpOwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICBjYXNlIFhTU2ltcGxlVHlwZS5GQUNFVF9NQVhFWENMVVNJVkU6Ci0gICAgICAgICAgICAgICAgICAgIHhzRmFjZXRzLm1heEV4Y2x1c2l2ZSA9IChTdHJpbmcpYXR0cnNbWFNBdHRyaWJ1dGVDaGVja2VyLkFUVElEWF9WQUxVRV07Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGNhc2UgWFNTaW1wbGVUeXBlLkZBQ0VUX01BWElOQ0xVU0lWRToKLSAgICAgICAgICAgICAgICAgICAgeHNGYWNldHMubWF4SW5jbHVzaXZlID0gKFN0cmluZylhdHRyc1tYU0F0dHJpYnV0ZUNoZWNrZXIuQVRUSURYX1ZBTFVFXTsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgY2FzZSBYU1NpbXBsZVR5cGUuRkFDRVRfTUlORVhDTFVTSVZFOgotICAgICAgICAgICAgICAgICAgICB4c0ZhY2V0cy5taW5FeGNsdXNpdmUgPSAoU3RyaW5nKWF0dHJzW1hTQXR0cmlidXRlQ2hlY2tlci5BVFRJRFhfVkFMVUVdOwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICBjYXNlIFhTU2ltcGxlVHlwZS5GQUNFVF9NSU5JTkNMVVNJVkU6Ci0gICAgICAgICAgICAgICAgICAgIHhzRmFjZXRzLm1pbkluY2x1c2l2ZSA9IChTdHJpbmcpYXR0cnNbWFNBdHRyaWJ1dGVDaGVja2VyLkFUVElEWF9WQUxVRV07Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGNhc2UgWFNTaW1wbGVUeXBlLkZBQ0VUX1RPVEFMRElHSVRTOgotICAgICAgICAgICAgICAgICAgICB4c0ZhY2V0cy50b3RhbERpZ2l0cyA9ICgoWEludClhdHRyc1tYU0F0dHJpYnV0ZUNoZWNrZXIuQVRUSURYX1ZBTFVFXSkuaW50VmFsdWUoKTsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgY2FzZSBYU1NpbXBsZVR5cGUuRkFDRVRfRlJBQ1RJT05ESUdJVFM6Ci0gICAgICAgICAgICAgICAgICAgIHhzRmFjZXRzLmZyYWN0aW9uRGlnaXRzID0gKChYSW50KWF0dHJzW1hTQXR0cmlidXRlQ2hlY2tlci5BVFRJRFhfVkFMVUVdKS5pbnRWYWx1ZSgpOwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICBjYXNlIFhTU2ltcGxlVHlwZS5GQUNFVF9XSElURVNQQUNFOgotICAgICAgICAgICAgICAgICAgICB4c0ZhY2V0cy53aGl0ZVNwYWNlID0gKChYSW50KWF0dHJzW1hTQXR0cmlidXRlQ2hlY2tlci5BVFRJRFhfVkFMVUVdKS5zaG9ydFZhbHVlKCk7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGNhc2UgWFNTaW1wbGVUeXBlLkZBQ0VUX0xFTkdUSDoKLSAgICAgICAgICAgICAgICAgICAgeHNGYWNldHMubGVuZ3RoID0gKChYSW50KWF0dHJzW1hTQXR0cmlidXRlQ2hlY2tlci5BVFRJRFhfVkFMVUVdKS5pbnRWYWx1ZSgpOwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBFbGVtZW50IGNoaWxkID0gRE9NVXRpbC5nZXRGaXJzdENoaWxkRWxlbWVudCggY29udGVudCApOwotICAgICAgICAgICAgICAgIFhTQW5ub3RhdGlvbkltcGwgYW5ub3RhdGlvbiA9IG51bGw7Ci0gICAgICAgICAgICAgICAgaWYgKGNoaWxkICE9IG51bGwgJiYKLSAgICAgICAgICAgICAgICAgICAgRE9NVXRpbC5nZXRMb2NhbE5hbWUoY2hpbGQpLmVxdWFscyhTY2hlbWFTeW1ib2xzLkVMVF9BTk5PVEFUSU9OKSkgewotICAgICAgICAgICAgICAgICAgICAvLyB0cmF2ZXJzZSBhbm5vdGF0aW9uIGlmIGFueQotICAgICAgICAgICAgICAgICAgICBhbm5vdGF0aW9uID0gdHJhdmVyc2VBbm5vdGF0aW9uRGVjbChjaGlsZCwgYXR0cnMsIGZhbHNlLCBzY2hlbWFEb2MpOwotICAgICAgICAgICAgICAgICAgICBjaGlsZCA9IERPTVV0aWwuZ2V0TmV4dFNpYmxpbmdFbGVtZW50KGNoaWxkKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIFN0cmluZyB0ZXh0ID0gRE9NVXRpbC5nZXRTeW50aGV0aWNBbm5vdGF0aW9uKGNvbnRlbnQpOwotICAgICAgICAgICAgICAgICAgICBpZiAodGV4dCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBhbm5vdGF0aW9uID0gdHJhdmVyc2VTeW50aGV0aWNBbm5vdGF0aW9uKGNvbnRlbnQsIHRleHQsIGF0dHJzLCBmYWxzZSwgc2NoZW1hRG9jKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHN3aXRjaCAoY3VycmVudEZhY2V0KSB7Ci0gICAgICAgICAgICAgICAgY2FzZSBYU1NpbXBsZVR5cGUuRkFDRVRfTUlOTEVOR1RIOgotICAgICAgICAgICAgICAgICAgICB4c0ZhY2V0cy5taW5MZW5ndGhBbm5vdGF0aW9uID0gYW5ub3RhdGlvbjsKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICBjYXNlIFhTU2ltcGxlVHlwZS5GQUNFVF9NQVhMRU5HVEg6Ci0gICAgICAgICAgICAgICAgICAgIHhzRmFjZXRzLm1heExlbmd0aEFubm90YXRpb24gPSBhbm5vdGF0aW9uOwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGNhc2UgWFNTaW1wbGVUeXBlLkZBQ0VUX01BWEVYQ0xVU0lWRToKLSAgICAgICAgICAgICAgICAgICAgeHNGYWNldHMubWF4RXhjbHVzaXZlQW5ub3RhdGlvbiA9IGFubm90YXRpb247Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgY2FzZSBYU1NpbXBsZVR5cGUuRkFDRVRfTUFYSU5DTFVTSVZFOgotICAgICAgICAgICAgICAgICAgICB4c0ZhY2V0cy5tYXhJbmNsdXNpdmVBbm5vdGF0aW9uID0gYW5ub3RhdGlvbjsKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICBjYXNlIFhTU2ltcGxlVHlwZS5GQUNFVF9NSU5FWENMVVNJVkU6Ci0gICAgICAgICAgICAgICAgICAgIHhzRmFjZXRzLm1pbkV4Y2x1c2l2ZUFubm90YXRpb24gPSBhbm5vdGF0aW9uOwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGNhc2UgWFNTaW1wbGVUeXBlLkZBQ0VUX01JTklOQ0xVU0lWRToKLSAgICAgICAgICAgICAgICAgICAgeHNGYWNldHMubWluSW5jbHVzaXZlQW5ub3RhdGlvbiA9IGFubm90YXRpb247Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgY2FzZSBYU1NpbXBsZVR5cGUuRkFDRVRfVE9UQUxESUdJVFM6Ci0gICAgICAgICAgICAgICAgICAgIHhzRmFjZXRzLnRvdGFsRGlnaXRzQW5ub3RhdGlvbiA9IGFubm90YXRpb247Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgY2FzZSBYU1NpbXBsZVR5cGUuRkFDRVRfRlJBQ1RJT05ESUdJVFM6Ci0gICAgICAgICAgICAgICAgICAgIHhzRmFjZXRzLmZyYWN0aW9uRGlnaXRzQW5ub3RhdGlvbiA9IGFubm90YXRpb247Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgY2FzZSBYU1NpbXBsZVR5cGUuRkFDRVRfV0hJVEVTUEFDRToKLSAgICAgICAgICAgICAgICAgICAgeHNGYWNldHMud2hpdGVTcGFjZUFubm90YXRpb24gPSBhbm5vdGF0aW9uOwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGNhc2UgWFNTaW1wbGVUeXBlLkZBQ0VUX0xFTkdUSDoKLSAgICAgICAgICAgICAgICAgICAgeHNGYWNldHMubGVuZ3RoQW5ub3RhdGlvbiA9IGFubm90YXRpb247Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGlmIChjaGlsZCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKCJzNHMtZWx0LW11c3QtbWF0Y2guMSIsIG5ldyBPYmplY3RbXXtmYWNldCwgIihhbm5vdGF0aW9uPykiLCBET01VdGlsLmdldExvY2FsTmFtZShjaGlsZCl9LCBjaGlsZCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZkF0dHJDaGVja2VyLnJldHVybkF0dHJBcnJheSAoYXR0cnMsIHNjaGVtYURvYyk7Ci0gICAgICAgICAgICBjb250ZW50ID0gRE9NVXRpbC5nZXROZXh0U2libGluZ0VsZW1lbnQoY29udGVudCk7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGVudW1EYXRhICE9bnVsbCkgewotICAgICAgICAgICAgZmFjZXRzUHJlc2VudCB8PSBYU1NpbXBsZVR5cGUuRkFDRVRfRU5VTUVSQVRJT047Ci0gICAgICAgICAgICB4c0ZhY2V0cy5lbnVtZXJhdGlvbiA9IGVudW1EYXRhOwotICAgICAgICAgICAgeHNGYWNldHMuZW51bU5TRGVjbHMgPSBlbnVtTlNEZWNsczsKLSAgICAgICAgICAgIHhzRmFjZXRzLmVudW1Bbm5vdGF0aW9ucyA9IGVudW1Bbm5vdGF0aW9uczsKLSAgICAgICAgfQotICAgICAgICBpZiAoKGZhY2V0c1ByZXNlbnQgJiBYU1NpbXBsZVR5cGUuRkFDRVRfUEFUVEVSTikgIT0gMCkgewotICAgICAgICAgICAgeHNGYWNldHMucGF0dGVybiA9IGZQYXR0ZXJuLnRvU3RyaW5nKCk7Ci0gICAgICAgICAgICB4c0ZhY2V0cy5wYXR0ZXJuQW5ub3RhdGlvbnMgPSBwYXR0ZXJuQW5ub3RhdGlvbnM7Ci0gICAgICAgIH0KLQotICAgICAgICBmUGF0dGVybi5zZXRMZW5ndGgoMCk7Ci0KLSAgICAgICAgcmV0dXJuIG5ldyBGYWNldEluZm8oeHNGYWNldHMsIGNvbnRlbnQsIGZhY2V0c1ByZXNlbnQsIGZhY2V0c0ZpeGVkKTsKLSAgICB9Ci0KLQotICAgIC8vIHJldHVybiB3aGV0aGVyIFFOYW1lL05PVEFUSU9OIGlzIHBhcnQgb2YgdGhlIGdpdmVuIHR5cGUKLSAgICBwcml2YXRlIGJvb2xlYW4gY29udGFpbnNRTmFtZShYU1NpbXBsZVR5cGUgdHlwZSkgewotICAgICAgICBpZiAodHlwZS5nZXRWYXJpZXR5KCkgPT0gWFNTaW1wbGVUeXBlLlZBUklFVFlfQVRPTUlDKSB7Ci0gICAgICAgICAgICBzaG9ydCBwcmltaXRpdmUgPSB0eXBlLmdldFByaW1pdGl2ZUtpbmQoKTsKLSAgICAgICAgICAgIHJldHVybiAocHJpbWl0aXZlID09IFhTU2ltcGxlVHlwZS5QUklNSVRJVkVfUU5BTUUgfHwKLSAgICAgICAgICAgICAgICAgICAgcHJpbWl0aXZlID09IFhTU2ltcGxlVHlwZS5QUklNSVRJVkVfTk9UQVRJT04pOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKHR5cGUuZ2V0VmFyaWV0eSgpID09IFhTU2ltcGxlVHlwZS5WQVJJRVRZX0xJU1QpIHsKLSAgICAgICAgICAgIHJldHVybiBjb250YWluc1FOYW1lKChYU1NpbXBsZVR5cGUpdHlwZS5nZXRJdGVtVHlwZSgpKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICh0eXBlLmdldFZhcmlldHkoKSA9PSBYU1NpbXBsZVR5cGUuVkFSSUVUWV9VTklPTikgewotICAgICAgICAgICAgWFNPYmplY3RMaXN0IG1lbWJlcnMgPSB0eXBlLmdldE1lbWJlclR5cGVzKCk7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1lbWJlcnMuZ2V0TGVuZ3RoKCk7IGkrKykgewotICAgICAgICAgICAgICAgIGlmIChjb250YWluc1FOYW1lKChYU1NpbXBsZVR5cGUpbWVtYmVycy5pdGVtKGkpKSkKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIC8vCi0gICAgLy8gVHJhdmVyc2UgYSBzZXQgb2YgYXR0cmlidXRlIGFuZCBhdHRyaWJ1dGUgZ3JvdXAgZWxlbWVudHMKLSAgICAvLyBOZWVkZWQgYnkgY29tcGxleFR5cGUgYW5kIGF0dHJpYnV0ZUdyb3VwIHRyYXZlcnNhbAotICAgIC8vIFRoaXMgbWV0aG9kIHdpbGwgcmV0dXJuIHRoZSBmaXJzdCBub24tYXR0cmlidXRlL2F0dHJncnAgZm91bmQKLSAgICAvLwotICAgIEVsZW1lbnQgdHJhdmVyc2VBdHRyc0FuZEF0dHJHcnBzKEVsZW1lbnQgZmlyc3RBdHRyLCBYU0F0dHJpYnV0ZUdyb3VwRGVjbCBhdHRyR3JwLAotICAgICAgICAgICAgWFNEb2N1bWVudEluZm8gc2NoZW1hRG9jLCBTY2hlbWFHcmFtbWFyIGdyYW1tYXIsCi0gICAgICAgICAgICBYU0NvbXBsZXhUeXBlRGVjbCBlbmNsb3NpbmdDVCkgewotCi0gICAgICAgIEVsZW1lbnQgY2hpbGQ9bnVsbDsKLSAgICAgICAgWFNBdHRyaWJ1dGVHcm91cERlY2wgdGVtcEF0dHJHcnAgPSBudWxsOwotICAgICAgICBYU0F0dHJpYnV0ZVVzZUltcGwgdGVtcEF0dHJVc2UgPSBudWxsOwotICAgICAgICBYU0F0dHJpYnV0ZVVzZSBvdGhlclVzZSA9IG51bGw7Ci0gICAgICAgIFN0cmluZyBjaGlsZE5hbWU7Ci0KLSAgICAgICAgZm9yIChjaGlsZD1maXJzdEF0dHI7IGNoaWxkIT1udWxsOyBjaGlsZD1ET01VdGlsLmdldE5leHRTaWJsaW5nRWxlbWVudChjaGlsZCkpIHsKLSAgICAgICAgICAgIGNoaWxkTmFtZSA9IERPTVV0aWwuZ2V0TG9jYWxOYW1lKGNoaWxkKTsKLSAgICAgICAgICAgIGlmIChjaGlsZE5hbWUuZXF1YWxzKFNjaGVtYVN5bWJvbHMuRUxUX0FUVFJJQlVURSkpIHsKLSAgICAgICAgICAgICAgICB0ZW1wQXR0clVzZSA9IGZTY2hlbWFIYW5kbGVyLmZBdHRyaWJ1dGVUcmF2ZXJzZXIudHJhdmVyc2VMb2NhbChjaGlsZCwKLSAgICAgICAgICAgICAgICAgICAgICAgIHNjaGVtYURvYywKLSAgICAgICAgICAgICAgICAgICAgICAgIGdyYW1tYXIsCi0gICAgICAgICAgICAgICAgICAgICAgICBlbmNsb3NpbmdDVCk7Ci0gICAgICAgICAgICAgICAgaWYgKHRlbXBBdHRyVXNlID09IG51bGwpIGNvbnRpbnVlOwotICAgICAgICAgICAgICAgIGlmICh0ZW1wQXR0clVzZS5mVXNlID09IFNjaGVtYVN5bWJvbHMuVVNFX1BST0hJQklURUQpIHsKLSAgICAgICAgICAgICAgICAgICAgYXR0ckdycC5hZGRBdHRyaWJ1dGVVc2UodGVtcEF0dHJVc2UpOwotICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgb3RoZXJVc2UgPSBhdHRyR3JwLmdldEF0dHJpYnV0ZVVzZU5vUHJvaGliaXRlZCgKLSAgICAgICAgICAgICAgICAgICAgICAgIHRlbXBBdHRyVXNlLmZBdHRyRGVjbC5nZXROYW1lc3BhY2UoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgIHRlbXBBdHRyVXNlLmZBdHRyRGVjbC5nZXROYW1lKCkpOwotICAgICAgICAgICAgICAgIGlmIChvdGhlclVzZT09bnVsbCkgewotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgaWROYW1lID0gYXR0ckdycC5hZGRBdHRyaWJ1dGVVc2UodGVtcEF0dHJVc2UpOwotICAgICAgICAgICAgICAgICAgICBpZiAoaWROYW1lICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBjb2RlID0gKGVuY2xvc2luZ0NUID09IG51bGwpID8gImFnLXByb3BzLWNvcnJlY3QuMyIgOiAiY3QtcHJvcHMtY29ycmVjdC41IjsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBuYW1lID0gKGVuY2xvc2luZ0NUID09IG51bGwpID8gYXR0ckdycC5mTmFtZSA6IGVuY2xvc2luZ0NULmdldE5hbWUoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKGNvZGUsIG5ldyBPYmplY3RbXXtuYW1lLCB0ZW1wQXR0clVzZS5mQXR0ckRlY2wuZ2V0TmFtZSgpLCBpZE5hbWV9LCBjaGlsZCk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSBpZiAob3RoZXJVc2UgIT0gdGVtcEF0dHJVc2UpIHsKLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGNvZGUgPSAoZW5jbG9zaW5nQ1QgPT0gbnVsbCkgPyAiYWctcHJvcHMtY29ycmVjdC4yIiA6ICJjdC1wcm9wcy1jb3JyZWN0LjQiOwotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbmFtZSA9IChlbmNsb3NpbmdDVCA9PSBudWxsKSA/IGF0dHJHcnAuZk5hbWUgOiBlbmNsb3NpbmdDVC5nZXROYW1lKCk7Ci0gICAgICAgICAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKGNvZGUsIG5ldyBPYmplY3RbXXtuYW1lLCB0ZW1wQXR0clVzZS5mQXR0ckRlY2wuZ2V0TmFtZSgpfSwgY2hpbGQpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKGNoaWxkTmFtZS5lcXVhbHMoU2NoZW1hU3ltYm9scy5FTFRfQVRUUklCVVRFR1JPVVApKSB7Ci0gICAgICAgICAgICAgICAgLy9SRVZJU0lUOiBkbyB3ZSBuZWVkIHRvIHNhdmUgc29tZSBzdGF0ZSBhdCB0aGlzIHBvaW50Pz8KLSAgICAgICAgICAgICAgICB0ZW1wQXR0ckdycCA9IGZTY2hlbWFIYW5kbGVyLmZBdHRyaWJ1dGVHcm91cFRyYXZlcnNlci50cmF2ZXJzZUxvY2FsKAotICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGQsIHNjaGVtYURvYywgZ3JhbW1hcik7Ci0gICAgICAgICAgICAgICAgaWYodGVtcEF0dHJHcnAgPT0gbnVsbCApIGNvbnRpbnVlOwotICAgICAgICAgICAgICAgIFhTT2JqZWN0TGlzdCBhdHRyVXNlUyA9IHRlbXBBdHRyR3JwLmdldEF0dHJpYnV0ZVVzZXMoKTsKLSAgICAgICAgICAgICAgICBYU0F0dHJpYnV0ZVVzZUltcGwgb25lQXR0clVzZTsKLSAgICAgICAgICAgICAgICBpbnQgYXR0ckNvdW50ID0gYXR0clVzZVMuZ2V0TGVuZ3RoKCk7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaT0wOyBpPGF0dHJDb3VudDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgICAgIG9uZUF0dHJVc2UgPSAoWFNBdHRyaWJ1dGVVc2VJbXBsKWF0dHJVc2VTLml0ZW0oaSk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChvbmVBdHRyVXNlLmZVc2UgPT0gU2NoZW1hU3ltYm9scy5VU0VfUFJPSElCSVRFRCkgewotICAgICAgICAgICAgICAgICAgICAgICAgYXR0ckdycC5hZGRBdHRyaWJ1dGVVc2Uob25lQXR0clVzZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBvdGhlclVzZSA9IGF0dHJHcnAuZ2V0QXR0cmlidXRlVXNlTm9Qcm9oaWJpdGVkKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uZUF0dHJVc2UuZkF0dHJEZWNsLmdldE5hbWVzcGFjZSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uZUF0dHJVc2UuZkF0dHJEZWNsLmdldE5hbWUoKSk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChvdGhlclVzZT09bnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGlkTmFtZSA9IGF0dHJHcnAuYWRkQXR0cmlidXRlVXNlKG9uZUF0dHJVc2UpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlkTmFtZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGNvZGUgPSAoZW5jbG9zaW5nQ1QgPT0gbnVsbCkgPyAiYWctcHJvcHMtY29ycmVjdC4zIiA6ICJjdC1wcm9wcy1jb3JyZWN0LjUiOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBuYW1lID0gKGVuY2xvc2luZ0NUID09IG51bGwpID8gYXR0ckdycC5mTmFtZSA6IGVuY2xvc2luZ0NULmdldE5hbWUoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcihjb2RlLCBuZXcgT2JqZWN0W117bmFtZSwgb25lQXR0clVzZS5mQXR0ckRlY2wuZ2V0TmFtZSgpLCBpZE5hbWV9LCBjaGlsZCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAob25lQXR0clVzZSAhPSBvdGhlclVzZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGNvZGUgPSAoZW5jbG9zaW5nQ1QgPT0gbnVsbCkgPyAiYWctcHJvcHMtY29ycmVjdC4yIiA6ICJjdC1wcm9wcy1jb3JyZWN0LjQiOwotICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG5hbWUgPSAoZW5jbG9zaW5nQ1QgPT0gbnVsbCkgPyBhdHRyR3JwLmZOYW1lIDogZW5jbG9zaW5nQ1QuZ2V0TmFtZSgpOwotICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoY29kZSwgbmV3IE9iamVjdFtde25hbWUsIG9uZUF0dHJVc2UuZkF0dHJEZWNsLmdldE5hbWUoKX0sIGNoaWxkKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIGlmICh0ZW1wQXR0ckdycC5mQXR0cmlidXRlV0MgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBpZiAoYXR0ckdycC5mQXR0cmlidXRlV0MgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgYXR0ckdycC5mQXR0cmlidXRlV0MgPSB0ZW1wQXR0ckdycC5mQXR0cmlidXRlV0M7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgLy8gcGVyZm9ybSBpbnRlcnNlY3Rpb24gb2YgYXR0cmlidXRlIHdpbGRjYXJkCi0gICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgYXR0ckdycC5mQXR0cmlidXRlV0MgPSBhdHRyR3JwLmZBdHRyaWJ1dGVXQy4KLSAgICAgICAgICAgICAgICAgICAgICAgIHBlcmZvcm1JbnRlcnNlY3Rpb25XaXRoKHRlbXBBdHRyR3JwLmZBdHRyaWJ1dGVXQywgYXR0ckdycC5mQXR0cmlidXRlV0MuZlByb2Nlc3NDb250ZW50cyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXR0ckdycC5mQXR0cmlidXRlV0MgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBjb2RlID0gKGVuY2xvc2luZ0NUID09IG51bGwpID8gInNyYy1hdHRyaWJ1dGVfZ3JvdXAuMiIgOiAic3JjLWN0LjQiOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBuYW1lID0gKGVuY2xvc2luZ0NUID09IG51bGwpID8gYXR0ckdycC5mTmFtZSA6IGVuY2xvc2luZ0NULmdldE5hbWUoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcihjb2RlLCBuZXcgT2JqZWN0W117bmFtZX0sIGNoaWxkKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgfSAvLyBmb3IKLQotICAgICAgICBpZiAoY2hpbGQgIT0gbnVsbCkgewotICAgICAgICAgICAgY2hpbGROYW1lID0gRE9NVXRpbC5nZXRMb2NhbE5hbWUoY2hpbGQpOwotICAgICAgICAgICAgaWYgKGNoaWxkTmFtZS5lcXVhbHMoU2NoZW1hU3ltYm9scy5FTFRfQU5ZQVRUUklCVVRFKSkgewotICAgICAgICAgICAgICAgIFhTV2lsZGNhcmREZWNsIHRlbXBBdHRyV0MgPSBmU2NoZW1hSGFuZGxlci5mV2lsZENhcmRUcmF2ZXJzZXIuCi0gICAgICAgICAgICAgICAgdHJhdmVyc2VBbnlBdHRyaWJ1dGUoY2hpbGQsIHNjaGVtYURvYywgZ3JhbW1hcik7Ci0gICAgICAgICAgICAgICAgaWYgKGF0dHJHcnAuZkF0dHJpYnV0ZVdDID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgYXR0ckdycC5mQXR0cmlidXRlV0MgPSB0ZW1wQXR0cldDOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvLyBwZXJmb3JtIGludGVyc2VjdGlvbiBvZiBhdHRyaWJ1dGUgd2lsZGNhcmQKLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgYXR0ckdycC5mQXR0cmlidXRlV0MgPSB0ZW1wQXR0cldDLgotICAgICAgICAgICAgICAgICAgICBwZXJmb3JtSW50ZXJzZWN0aW9uV2l0aChhdHRyR3JwLmZBdHRyaWJ1dGVXQywgdGVtcEF0dHJXQy5mUHJvY2Vzc0NvbnRlbnRzKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGF0dHJHcnAuZkF0dHJpYnV0ZVdDID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBjb2RlID0gKGVuY2xvc2luZ0NUID09IG51bGwpID8gInNyYy1hdHRyaWJ1dGVfZ3JvdXAuMiIgOiAic3JjLWN0LjQiOwotICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG5hbWUgPSAoZW5jbG9zaW5nQ1QgPT0gbnVsbCkgPyBhdHRyR3JwLmZOYW1lIDogZW5jbG9zaW5nQ1QuZ2V0TmFtZSgpOwotICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoY29kZSwgbmV3IE9iamVjdFtde25hbWV9LCBjaGlsZCk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgY2hpbGQgPSBET01VdGlsLmdldE5leHRTaWJsaW5nRWxlbWVudChjaGlsZCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBTdWNjZXNzCi0gICAgICAgIHJldHVybiBjaGlsZDsKLQotICAgIH0KLQotICAgIHZvaWQgcmVwb3J0U2NoZW1hRXJyb3IgKFN0cmluZyBrZXksIE9iamVjdFtdIGFyZ3MsIEVsZW1lbnQgZWxlKSB7Ci0gICAgICAgIGZTY2hlbWFIYW5kbGVyLnJlcG9ydFNjaGVtYUVycm9yKGtleSwgYXJncywgZWxlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBFbGVtZW50L0F0dHJpYnV0ZSB0cmF2ZXJzZXJzIGNhbGwgdGhpcyBtZXRob2QgdG8gY2hlY2sgd2hldGhlcgotICAgICAqIHRoZSB0eXBlIGlzIE5PVEFUSU9OIHdpdGhvdXQgZW51bWVyYXRpb24gZmFjZXQKLSAgICAgKi8KLSAgICB2b2lkIGNoZWNrTm90YXRpb25UeXBlKFN0cmluZyByZWZOYW1lLCBYU1R5cGVEZWZpbml0aW9uIHR5cGVEZWNsLCBFbGVtZW50IGVsZW0pIHsKLSAgICAgICAgaWYgKHR5cGVEZWNsLmdldFR5cGVDYXRlZ29yeSgpID09IFhTVHlwZURlZmluaXRpb24uU0lNUExFX1RZUEUgJiYKLSAgICAgICAgICAgICAgICAoKFhTU2ltcGxlVHlwZSl0eXBlRGVjbCkuZ2V0VmFyaWV0eSgpID09IFhTU2ltcGxlVHlwZS5WQVJJRVRZX0FUT01JQyAmJgotICAgICAgICAgICAgICAgICgoWFNTaW1wbGVUeXBlKXR5cGVEZWNsKS5nZXRQcmltaXRpdmVLaW5kKCkgPT0gWFNTaW1wbGVUeXBlLlBSSU1JVElWRV9OT1RBVElPTikgewotICAgICAgICAgICAgaWYgKCgoKFhTU2ltcGxlVHlwZSl0eXBlRGVjbCkuZ2V0RGVmaW5lZEZhY2V0cygpICYgWFNTaW1wbGVUeXBlLkZBQ0VUX0VOVU1FUkFUSU9OKSA9PSAwKSB7Ci0gICAgICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoImVudW1lcmF0aW9uLXJlcXVpcmVkLW5vdGF0aW9uIiwgbmV3IE9iamVjdFtde3R5cGVEZWNsLmdldE5hbWUoKSwgcmVmTmFtZSwgRE9NVXRpbC5nZXRMb2NhbE5hbWUoZWxlbSl9LCBlbGVtKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIC8vIENoZWNrcyBjb25zdHJhaW50cyBmb3IgbWluT2NjdXJzLCBtYXhPY2N1cnMKLSAgICBwcm90ZWN0ZWQgWFNQYXJ0aWNsZURlY2wgY2hlY2tPY2N1cnJlbmNlcyhYU1BhcnRpY2xlRGVjbCBwYXJ0aWNsZSwKLSAgICAgICAgICAgIFN0cmluZyBwYXJ0aWNsZU5hbWUsIEVsZW1lbnQgcGFyZW50LAotICAgICAgICAgICAgaW50IGFsbENvbnRleHRGbGFncywKLSAgICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHMpIHsKLQotICAgICAgICBpbnQgbWluID0gcGFydGljbGUuZk1pbk9jY3VyczsKLSAgICAgICAgaW50IG1heCA9IHBhcnRpY2xlLmZNYXhPY2N1cnM7Ci0gICAgICAgIGJvb2xlYW4gZGVmYXVsdE1pbiA9IChkZWZhdWx0VmFscyAmICgxIDw8IFhTQXR0cmlidXRlQ2hlY2tlci5BVFRJRFhfTUlOT0NDVVJTKSkgIT0gMDsKLSAgICAgICAgYm9vbGVhbiBkZWZhdWx0TWF4ID0gKGRlZmF1bHRWYWxzICYgKDEgPDwgWFNBdHRyaWJ1dGVDaGVja2VyLkFUVElEWF9NQVhPQ0NVUlMpKSAhPSAwOwotCi0gICAgICAgIGJvb2xlYW4gcHJvY2Vzc2luZ0FsbEVsID0gKChhbGxDb250ZXh0RmxhZ3MgJiBQUk9DRVNTSU5HX0FMTF9FTCkgIT0gMCk7Ci0gICAgICAgIGJvb2xlYW4gcHJvY2Vzc2luZ0FsbEdQID0gKChhbGxDb250ZXh0RmxhZ3MgJiBQUk9DRVNTSU5HX0FMTF9HUCkgIT0gMCk7Ci0gICAgICAgIGJvb2xlYW4gZ3JvdXBSZWZXaXRoQWxsID0gKChhbGxDb250ZXh0RmxhZ3MgJiBHUk9VUF9SRUZfV0lUSF9BTEwpICE9IDApOwotICAgICAgICBib29sZWFuIGlzR3JvdXBDaGlsZCAgICA9ICgoYWxsQ29udGV4dEZsYWdzICYgQ0hJTERfT0ZfR1JPVVApICE9IDApOwotCi0gICAgICAgIC8vIE5laXRoZXIgbWluT2NjdXJzIG5vciBtYXhPY2N1cnMgbWF5IGJlIHNwZWNpZmllZAotICAgICAgICAvLyBmb3IgdGhlIGNoaWxkIG9mIGEgbW9kZWwgZ3JvdXAgZGVmaW5pdGlvbi4KLSAgICAgICAgaWYgKGlzR3JvdXBDaGlsZCkgewotICAgICAgICAgICAgaWYgKCFkZWZhdWx0TWluKSB7Ci0gICAgICAgICAgICAgICAgT2JqZWN0W10gYXJncyA9IG5ldyBPYmplY3RbXXtwYXJ0aWNsZU5hbWUsICJtaW5PY2N1cnMifTsKLSAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcigiczRzLWF0dC1ub3QtYWxsb3dlZCIsIGFyZ3MsIHBhcmVudCk7Ci0gICAgICAgICAgICAgICAgbWluID0gMTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmICghZGVmYXVsdE1heCkgewotICAgICAgICAgICAgICAgIE9iamVjdFtdIGFyZ3MgPSBuZXcgT2JqZWN0W117cGFydGljbGVOYW1lLCAibWF4T2NjdXJzIn07Ci0gICAgICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoInM0cy1hdHQtbm90LWFsbG93ZWQiLCBhcmdzLCBwYXJlbnQpOwotICAgICAgICAgICAgICAgIG1heCA9IDE7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBJZiBtaW5PY2N1cnM9bWF4T2NjdXJzPTAsIG5vIGNvbXBvbmVudCBpcyBzcGVjaWZpZWQKLSAgICAgICAgaWYgKG1pbiA9PSAwICYmIG1heD09IDApIHsKLSAgICAgICAgICAgIHBhcnRpY2xlLmZUeXBlID0gWFNQYXJ0aWNsZURlY2wuUEFSVElDTEVfRU1QVFk7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIEZvciB0aGUgZWxlbWVudHMgcmVmZXJlbmNlZCBpbiBhbiA8YWxsPiwgbWluT2NjdXJzIGF0dHJpYnV0ZQotICAgICAgICAvLyBtdXN0IGJlIHplcm8gb3Igb25lLCBhbmQgbWF4T2NjdXJzIGF0dHJpYnV0ZSBtdXN0IGJlIG9uZS4KLSAgICAgICAgLy8gRm9yIGEgY29tcGxleCB0eXBlIGRlZmluaXRpb24gdGhhdCBjb250YWlucyBhbiA8YWxsPiBvciBhCi0gICAgICAgIC8vIHJlZmVyZW5jZSBhIDxncm91cD4gd2hvc2UgbW9kZWwgZ3JvdXAgaXMgYW4gYWxsIG1vZGVsIGdyb3VwLAotICAgICAgICAvLyBtaW5PY2N1cnMgYW5kIG1heE9jY3VycyBtdXN0IGJlIG9uZS4KLSAgICAgICAgaWYgKHByb2Nlc3NpbmdBbGxFbCkgewotICAgICAgICAgICAgaWYgKG1heCAhPSAxKSB7Ci0gICAgICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoImNvcy1hbGwtbGltaXRlZC4yIiwgbmV3IE9iamVjdFtdewotICAgICAgICAgICAgICAgICAgICAgICAgKG1heCA9PSBTY2hlbWFTeW1ib2xzLk9DQ1VSUkVOQ0VfVU5CT1VOREVEKSA/IFNjaGVtYVN5bWJvbHMuQVRUVkFMX1VOQk9VTkRFRCA6IEludGVnZXIudG9TdHJpbmcobWF4KSwKLSAgICAgICAgICAgICAgICAgICAgICAgICgoWFNFbGVtZW50RGVjbClwYXJ0aWNsZS5mVmFsdWUpLmdldE5hbWUoKX0sIHBhcmVudCk7Ci0gICAgICAgICAgICAgICAgbWF4ID0gMTsKLSAgICAgICAgICAgICAgICBpZiAobWluID4gMSkKLSAgICAgICAgICAgICAgICAgICAgbWluID0gMTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChwcm9jZXNzaW5nQWxsR1AgfHwgZ3JvdXBSZWZXaXRoQWxsKSB7Ci0gICAgICAgICAgICBpZiAobWF4ICE9IDEpIHsKLSAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcigiY29zLWFsbC1saW1pdGVkLjEuMiIsIG51bGwsIHBhcmVudCk7Ci0gICAgICAgICAgICAgICAgaWYgKG1pbiA+IDEpCi0gICAgICAgICAgICAgICAgICAgIG1pbiA9IDE7Ci0gICAgICAgICAgICAgICAgbWF4ID0gMTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHBhcnRpY2xlLmZNaW5PY2N1cnMgPSBtaW47Ci0gICAgICAgIHBhcnRpY2xlLmZNYXhPY2N1cnMgPSBtYXg7Ci0KLSAgICAgICAgcmV0dXJuIHBhcnRpY2xlOwotICAgIH0KLQotICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBwcm9jZXNzQXR0VmFsdWUoU3RyaW5nIG9yaWdpbmFsKSB7Ci0gICAgICAgIGZpbmFsIGludCBsZW5ndGggPSBvcmlnaW5hbC5sZW5ndGgoKTsKLSAgICAgICAgLy8gbm9ybWFsbHksIG5vdGhpbmcgd2lsbCBoYXBwZW4KLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkgewotICAgICAgICAgICAgY2hhciBjdXJyQ2hhciA9IG9yaWdpbmFsLmNoYXJBdChpKTsKLSAgICAgICAgICAgIGlmIChjdXJyQ2hhciA9PSAnIicgfHwgY3VyckNoYXIgPT0gJzwnIHx8IGN1cnJDaGFyID09ICcmJyB8fAotICAgICAgICAgICAgICAgICAgICBjdXJyQ2hhciA9PSAweDA5IHx8IGN1cnJDaGFyID09IDB4MEEgfHwgY3VyckNoYXIgPT0gMHgwRCkgewotICAgICAgICAgICAgICAgIHJldHVybiBlc2NhcGVBdHRWYWx1ZShvcmlnaW5hbCwgaSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG9yaWdpbmFsOwotICAgIH0KLQotICAgIC8vIHRoaXMgaXMgbm90IHRlcnJpYmx5IHBlcmZvcm1hbnQhCi0gICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGVzY2FwZUF0dFZhbHVlKFN0cmluZyBvcmlnaW5hbCwgaW50IGZyb20pIHsKLSAgICAgICAgaW50IGk7Ci0gICAgICAgIGZpbmFsIGludCBsZW5ndGggPSBvcmlnaW5hbC5sZW5ndGgoKTsKLSAgICAgICAgU3RyaW5nQnVmZmVyIG5ld1ZhbCA9IG5ldyBTdHJpbmdCdWZmZXIobGVuZ3RoKTsKLSAgICAgICAgbmV3VmFsLmFwcGVuZChvcmlnaW5hbC5zdWJzdHJpbmcoMCwgZnJvbSkpOwotICAgICAgICBmb3IgKGkgPSBmcm9tOyBpIDwgbGVuZ3RoOyArK2kpIHsKLSAgICAgICAgICAgIGNoYXIgY3VyckNoYXIgPSBvcmlnaW5hbC5jaGFyQXQoaSk7Ci0gICAgICAgICAgICBpZiAoY3VyckNoYXIgPT0gJyInKSB7Ci0gICAgICAgICAgICAgICAgbmV3VmFsLmFwcGVuZCgiJnF1b3Q7Iik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChjdXJyQ2hhciA9PSAnPCcpIHsKLSAgICAgICAgICAgICAgICBuZXdWYWwuYXBwZW5kKCImbHQ7Iik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChjdXJyQ2hhciA9PSAnJicpIHsKLSAgICAgICAgICAgICAgICBuZXdWYWwuYXBwZW5kKCImYW1wOyIpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gTXVzdCBlc2NhcGUgMHgwOSwgMHgwQSBhbmQgMHgwRCBpZiB0aGV5IGFwcGVhciBpbiBhdHRyaWJ1dGUKLSAgICAgICAgICAgIC8vIHZhbHVlIHNvIHRoYXQgdGhleSBtYXkgYmUgcm91bmQtdHJpcHBlZC4gVGhleSB3b3VsZCBvdGhlcndpc2UKLSAgICAgICAgICAgIC8vIGJlIHRyYW5zZm9ybWVkIHRvIGEgMHgyMCBkdXJpbmcgYXR0cmlidXRlIHZhbHVlIG5vcm1hbGl6YXRpb24uCi0gICAgICAgICAgICBlbHNlIGlmIChjdXJyQ2hhciA9PSAweDA5KSB7Ci0gICAgICAgICAgICAgICAgbmV3VmFsLmFwcGVuZCgiJiN4OTsiKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKGN1cnJDaGFyID09IDB4MEEpIHsKLSAgICAgICAgICAgICAgICBuZXdWYWwuYXBwZW5kKCImI3hBOyIpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoY3VyckNoYXIgPT0gMHgwRCkgewotICAgICAgICAgICAgICAgIG5ld1ZhbC5hcHBlbmQoIiYjeEQ7Iik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBuZXdWYWwuYXBwZW5kKGN1cnJDaGFyKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbmV3VmFsLnRvU3RyaW5nKCk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy90cmF2ZXJzZXJzL1hTREF0dHJpYnV0ZUdyb3VwVHJhdmVyc2VyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL3RyYXZlcnNlcnMvWFNEQXR0cmlidXRlR3JvdXBUcmF2ZXJzZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMGUxMjY3MC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL3RyYXZlcnNlcnMvWFNEQXR0cmlidXRlR3JvdXBUcmF2ZXJzZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIwOSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMudHJhdmVyc2VyczsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5TY2hlbWFHcmFtbWFyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5TY2hlbWFTeW1ib2xzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5YU0Fubm90YXRpb25JbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5YU0F0dHJpYnV0ZUdyb3VwRGVjbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMudXRpbC5YU09iamVjdExpc3RJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5ET01VdGlsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5YTUxTeW1ib2xzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlFOYW1lOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNPYmplY3RMaXN0OwotaW1wb3J0IG9yZy53M2MuZG9tLkVsZW1lbnQ7Ci0KLS8qKgotICogVGhlIGF0dHJpYnV0ZSBncm91cCBkZWZpbml0aW9uIHNjaGVtYSBjb21wb25lbnQgdHJhdmVyc2VyLgotICoKLSAqIDxhdHRyaWJ1dGVHcm91cAotICogICBpZCA9IElECi0gKiAgIG5hbWUgPSBOQ05hbWUKLSAqICAgcmVmID0gUU5hbWUKLSAqICAge2FueSBhdHRyaWJ1dGVzIHdpdGggbm9uLXNjaGVtYSBuYW1lc3BhY2UgLiAuIC59PgotICogICBDb250ZW50OiAoYW5ub3RhdGlvbj8sICgoYXR0cmlidXRlIHwgYXR0cmlidXRlR3JvdXApKiwgYW55QXR0cmlidXRlPykpCi0gKiA8L2F0dHJpYnV0ZUdyb3VwPgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIFJhaHVsIFNyaXZhc3RhdmEsIFN1biBNaWNyb3N5c3RlbXMgSW5jLgotICogQGF1dGhvciBTYW5keSBHYW8sIElCTQotICoKLSAqIEB2ZXJzaW9uICRJZDogWFNEQXR0cmlidXRlR3JvdXBUcmF2ZXJzZXIuamF2YSx2IDEuNyAyMDEwLTExLTAxIDA0OjQwOjAyIGpvZWh3IEV4cCAkCi0gKi8KLWNsYXNzIFhTREF0dHJpYnV0ZUdyb3VwVHJhdmVyc2VyIGV4dGVuZHMgWFNEQWJzdHJhY3RUcmF2ZXJzZXIgewotCi0gICAgWFNEQXR0cmlidXRlR3JvdXBUcmF2ZXJzZXIgKFhTREhhbmRsZXIgaGFuZGxlciwKLSAgICAgICAgICAgIFhTQXR0cmlidXRlQ2hlY2tlciBnQXR0ckNoZWNrKSB7Ci0KLSAgICAgICAgc3VwZXIoaGFuZGxlciwgZ0F0dHJDaGVjayk7Ci0gICAgfQotCi0KLSAgICBYU0F0dHJpYnV0ZUdyb3VwRGVjbCB0cmF2ZXJzZUxvY2FsKEVsZW1lbnQgZWxtTm9kZSwKLSAgICAgICAgICAgIFhTRG9jdW1lbnRJbmZvIHNjaGVtYURvYywKLSAgICAgICAgICAgIFNjaGVtYUdyYW1tYXIgZ3JhbW1hcikgewotCi0gICAgICAgIC8vIEdlbmVyYWwgQXR0cmlidXRlIENoZWNraW5nIGZvciBlbG1Ob2RlIGRlY2xhcmVkIGxvY2FsbHkKLSAgICAgICAgT2JqZWN0W10gYXR0clZhbHVlcyA9IGZBdHRyQ2hlY2tlci5jaGVja0F0dHJpYnV0ZXMoZWxtTm9kZSwgZmFsc2UsIHNjaGVtYURvYyk7Ci0KLSAgICAgICAgLy8gZ2V0IGF0dHJpYnV0ZQotICAgICAgICBRTmFtZSAgIHJlZkF0dHIgPSAoUU5hbWUpICAgYXR0clZhbHVlc1tYU0F0dHJpYnV0ZUNoZWNrZXIuQVRUSURYX1JFRl07Ci0KLSAgICAgICAgWFNBdHRyaWJ1dGVHcm91cERlY2wgYXR0ckdycCA9IG51bGw7Ci0KLSAgICAgICAgLy8gcmVmIHNob3VsZCBiZSBoZXJlLgotICAgICAgICBpZiAocmVmQXR0ciA9PSBudWxsKSB7Ci0gICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcigiczRzLWF0dC1tdXN0LWFwcGVhciIsIG5ldyBPYmplY3RbXXsiYXR0cmlidXRlR3JvdXAgKGxvY2FsKSIsICJyZWYifSwgZWxtTm9kZSk7Ci0gICAgICAgICAgICBmQXR0ckNoZWNrZXIucmV0dXJuQXR0ckFycmF5KGF0dHJWYWx1ZXMsIHNjaGVtYURvYyk7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIGdldCBnbG9iYWwgZGVjbAotICAgICAgICBhdHRyR3JwID0gKFhTQXR0cmlidXRlR3JvdXBEZWNsKWZTY2hlbWFIYW5kbGVyLmdldEdsb2JhbERlY2woc2NoZW1hRG9jLCBYU0RIYW5kbGVyLkFUVFJJQlVURUdST1VQX1RZUEUsIHJlZkF0dHIsIGVsbU5vZGUpOwotCi0gICAgICAgIC8vIG5vIGNoaWxkcmVuIGFyZSBhbGxvd2VkIGhlcmUgZXhjZXB0IGFubm90YXRpb24sIHdoaWNoIGlzIG9wdGlvbmFsLgotICAgICAgICBFbGVtZW50IGNoaWxkID0gRE9NVXRpbC5nZXRGaXJzdENoaWxkRWxlbWVudChlbG1Ob2RlKTsKLSAgICAgICAgaWYgKGNoaWxkICE9IG51bGwpIHsKLSAgICAgICAgICAgIFN0cmluZyBjaGlsZE5hbWUgPSBET01VdGlsLmdldExvY2FsTmFtZShjaGlsZCk7Ci0gICAgICAgICAgICBpZiAoY2hpbGROYW1lLmVxdWFscyhTY2hlbWFTeW1ib2xzLkVMVF9BTk5PVEFUSU9OKSkgewotICAgICAgICAgICAgICAgIHRyYXZlcnNlQW5ub3RhdGlvbkRlY2woY2hpbGQsIGF0dHJWYWx1ZXMsIGZhbHNlLCBzY2hlbWFEb2MpOwotICAgICAgICAgICAgICAgIGNoaWxkID0gRE9NVXRpbC5nZXROZXh0U2libGluZ0VsZW1lbnQoY2hpbGQpOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgdGV4dCA9IERPTVV0aWwuZ2V0U3ludGhldGljQW5ub3RhdGlvbihjaGlsZCk7Ci0gICAgICAgICAgICAgICAgaWYgKHRleHQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICB0cmF2ZXJzZVN5bnRoZXRpY0Fubm90YXRpb24oY2hpbGQsIHRleHQsIGF0dHJWYWx1ZXMsIGZhbHNlLCBzY2hlbWFEb2MpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKGNoaWxkICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBPYmplY3RbXSBhcmdzID0gbmV3IE9iamVjdCBbXSB7cmVmQXR0ci5yYXduYW1lLCAiKGFubm90YXRpb24/KSIsIERPTVV0aWwuZ2V0TG9jYWxOYW1lKGNoaWxkKX07Ci0gICAgICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoInM0cy1lbHQtbXVzdC1tYXRjaC4xIiwgYXJncywgY2hpbGQpOwotICAgICAgICAgICAgfQotICAgICAgICB9IC8vIGlmCi0KLSAgICAgICAgZkF0dHJDaGVja2VyLnJldHVybkF0dHJBcnJheShhdHRyVmFsdWVzLCBzY2hlbWFEb2MpOwotICAgICAgICByZXR1cm4gYXR0ckdycDsKLQotICAgIH0gLy8gdHJhdmVyc2VMb2NhbAotCi0gICAgWFNBdHRyaWJ1dGVHcm91cERlY2wgdHJhdmVyc2VHbG9iYWwoRWxlbWVudCBlbG1Ob2RlLAotICAgICAgICAgICAgWFNEb2N1bWVudEluZm8gc2NoZW1hRG9jLAotICAgICAgICAgICAgU2NoZW1hR3JhbW1hciBncmFtbWFyKSB7Ci0KLSAgICAgICAgWFNBdHRyaWJ1dGVHcm91cERlY2wgYXR0ckdycCA9IG5ldyBYU0F0dHJpYnV0ZUdyb3VwRGVjbCgpOwotCi0gICAgICAgIC8vIEdlbmVyYWwgQXR0cmlidXRlIENoZWNraW5nIGZvciBlbG1Ob2RlIGRlY2xhcmVkIGdsb2JhbGx5Ci0gICAgICAgIE9iamVjdFtdIGF0dHJWYWx1ZXMgPSBmQXR0ckNoZWNrZXIuY2hlY2tBdHRyaWJ1dGVzKGVsbU5vZGUsIHRydWUsIHNjaGVtYURvYyk7Ci0KLSAgICAgICAgU3RyaW5nICBuYW1lQXR0ciAgID0gKFN0cmluZykgYXR0clZhbHVlc1tYU0F0dHJpYnV0ZUNoZWNrZXIuQVRUSURYX05BTUVdOwotCi0gICAgICAgIC8vIGdsb2JhbCBkZWNsYXJhdGlvbiBtdXN0IGhhdmUgYSBuYW1lCi0gICAgICAgIGlmIChuYW1lQXR0ciA9PSBudWxsKSB7Ci0gICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcigiczRzLWF0dC1tdXN0LWFwcGVhciIsIG5ldyBPYmplY3RbXXsiYXR0cmlidXRlR3JvdXAgKGdsb2JhbCkiLCAibmFtZSJ9LCBlbG1Ob2RlKTsKLSAgICAgICAgICAgIG5hbWVBdHRyID0gTk9fTkFNRTsKLSAgICAgICAgfQotCi0gICAgICAgIGF0dHJHcnAuZk5hbWUgPSBuYW1lQXR0cjsKLSAgICAgICAgYXR0ckdycC5mVGFyZ2V0TmFtZXNwYWNlID0gc2NoZW1hRG9jLmZUYXJnZXROYW1lc3BhY2U7Ci0KLSAgICAgICAgLy8gY2hlY2sgdGhlIGNvbnRlbnQKLSAgICAgICAgRWxlbWVudCBjaGlsZCA9IERPTVV0aWwuZ2V0Rmlyc3RDaGlsZEVsZW1lbnQoZWxtTm9kZSk7Ci0gICAgICAgIFhTQW5ub3RhdGlvbkltcGwgYW5ub3RhdGlvbiA9IG51bGw7Ci0KLSAgICAgICAgaWYgKGNoaWxkIT1udWxsICYmIERPTVV0aWwuZ2V0TG9jYWxOYW1lKGNoaWxkKS5lcXVhbHMoU2NoZW1hU3ltYm9scy5FTFRfQU5OT1RBVElPTikpIHsKLSAgICAgICAgICAgIGFubm90YXRpb24gPSB0cmF2ZXJzZUFubm90YXRpb25EZWNsKGNoaWxkLCBhdHRyVmFsdWVzLCBmYWxzZSwgc2NoZW1hRG9jKTsKLSAgICAgICAgICAgIGNoaWxkID0gRE9NVXRpbC5nZXROZXh0U2libGluZ0VsZW1lbnQoY2hpbGQpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgU3RyaW5nIHRleHQgPSBET01VdGlsLmdldFN5bnRoZXRpY0Fubm90YXRpb24oZWxtTm9kZSk7Ci0gICAgICAgICAgICBpZiAodGV4dCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgYW5ub3RhdGlvbiA9IHRyYXZlcnNlU3ludGhldGljQW5ub3RhdGlvbihlbG1Ob2RlLCB0ZXh0LCBhdHRyVmFsdWVzLCBmYWxzZSwgc2NoZW1hRG9jKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIFRyYXZlcnNlIHRoZSBhdHRyaWJ1dGUgYW5kIGF0dHJpYnV0ZSBncm91cCBlbGVtZW50cyBhbmQgZmlsbCBpbiB0aGUKLSAgICAgICAgLy8gYXR0cmlidXRlR3JvdXAgc3RydWN0dXJlCi0KLSAgICAgICAgRWxlbWVudCBuZXh0Tm9kZSA9IHRyYXZlcnNlQXR0cnNBbmRBdHRyR3JwcyhjaGlsZCwgYXR0ckdycCwgc2NoZW1hRG9jLCBncmFtbWFyLCBudWxsKTsKLSAgICAgICAgaWYgKG5leHROb2RlIT1udWxsKSB7Ci0gICAgICAgICAgICAvLyBBbiBpbnZhbGlkIGVsZW1lbnQgd2FzIGZvdW5kLi4uCi0gICAgICAgICAgICBPYmplY3RbXSBhcmdzID0gbmV3IE9iamVjdCBbXSB7bmFtZUF0dHIsICIoYW5ub3RhdGlvbj8sICgoYXR0cmlidXRlIHwgYXR0cmlidXRlR3JvdXApKiwgYW55QXR0cmlidXRlPykpIiwgRE9NVXRpbC5nZXRMb2NhbE5hbWUobmV4dE5vZGUpfTsKLSAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKCJzNHMtZWx0LW11c3QtbWF0Y2guMSIsIGFyZ3MsIG5leHROb2RlKTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChuYW1lQXR0ci5lcXVhbHMoTk9fTkFNRSkpIHsKLSAgICAgICAgICAgIC8vIGlmIGEgZ2xvYmFsIGdyb3VwIGRvZXNuJ3QgaGF2ZSBhIG5hbWUsIHRoZW4gZG9uJ3QgYWRkIGl0LgotICAgICAgICAgICAgZkF0dHJDaGVja2VyLnJldHVybkF0dHJBcnJheShhdHRyVmFsdWVzLCBzY2hlbWFEb2MpOwotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBSZW1vdmUgcHJvaGliaXRlZCBhdHRyaWJ1dGVzIGZyb20gdGhlIHNldAotICAgICAgICBhdHRyR3JwLnJlbW92ZVByb2hpYml0ZWRBdHRycygpOwotCi0gICAgICAgIC8vIGNoZWNrIGZvciByZXN0cmljdGVkIHJlZGVmaW5lOgotICAgICAgICBYU0F0dHJpYnV0ZUdyb3VwRGVjbCByZWRlZmluZWRBdHRyR3JwID0gKFhTQXR0cmlidXRlR3JvdXBEZWNsKWZTY2hlbWFIYW5kbGVyLmdldEdycE9yQXR0ckdycFJlZGVmaW5lZEJ5UmVzdHJpY3Rpb24oCi0gICAgICAgICAgICAgICAgWFNESGFuZGxlci5BVFRSSUJVVEVHUk9VUF9UWVBFLAotICAgICAgICAgICAgICAgIG5ldyBRTmFtZShYTUxTeW1ib2xzLkVNUFRZX1NUUklORywgbmFtZUF0dHIsIG5hbWVBdHRyLCBzY2hlbWFEb2MuZlRhcmdldE5hbWVzcGFjZSksCi0gICAgICAgICAgICAgICAgc2NoZW1hRG9jLCBlbG1Ob2RlKTsKLSAgICAgICAgaWYocmVkZWZpbmVkQXR0ckdycCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBPYmplY3RbXSBlcnJBcmdzID0gYXR0ckdycC52YWxpZFJlc3RyaWN0aW9uT2YobmFtZUF0dHIsIHJlZGVmaW5lZEF0dHJHcnApOwotICAgICAgICAgICAgaWYgKGVyckFyZ3MgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKChTdHJpbmcpZXJyQXJnc1tlcnJBcmdzLmxlbmd0aC0xXSwgZXJyQXJncywgY2hpbGQpOwotICAgICAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKCJzcmMtcmVkZWZpbmUuNy4yLjIiLCBuZXcgT2JqZWN0IFtdIHtuYW1lQXR0ciwgZXJyQXJnc1tlcnJBcmdzLmxlbmd0aC0xXX0sIGNoaWxkKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIFhTT2JqZWN0TGlzdCBhbm5vdGF0aW9uczsKLSAgICAgICAgaWYgKGFubm90YXRpb24gIT0gbnVsbCkgewotICAgICAgICAgICAgYW5ub3RhdGlvbnMgPSBuZXcgWFNPYmplY3RMaXN0SW1wbCgpOwotICAgICAgICAgICAgKChYU09iamVjdExpc3RJbXBsKWFubm90YXRpb25zKS5hZGRYU09iamVjdCAoYW5ub3RhdGlvbik7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBhbm5vdGF0aW9ucyA9IFhTT2JqZWN0TGlzdEltcGwuRU1QVFlfTElTVDsKLSAgICAgICAgfQotCi0gICAgICAgIGF0dHJHcnAuZkFubm90YXRpb25zID0gYW5ub3RhdGlvbnM7Ci0KLSAgICAgICAgLy8gbWFrZSBhbiBlbnRyeSBpbiBnbG9iYWwgZGVjbGFyYXRpb25zLgotICAgICAgICBpZiAoZ3JhbW1hci5nZXRHbG9iYWxBdHRyaWJ1dGVHcm91cERlY2woYXR0ckdycC5mTmFtZSkgPT0gbnVsbCkgewotICAgICAgICAgICAgZ3JhbW1hci5hZGRHbG9iYWxBdHRyaWJ1dGVHcm91cERlY2woYXR0ckdycCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBhbHNvIGFkZCBpdCB0byBleHRlbmRlZCBtYXAKLSAgICAgICAgZmluYWwgU3RyaW5nIGxvYyA9IGZTY2hlbWFIYW5kbGVyLnNjaGVtYURvY3VtZW50MlN5c3RlbUlkKHNjaGVtYURvYyk7Ci0gICAgICAgIGZpbmFsIFhTQXR0cmlidXRlR3JvdXBEZWNsIGF0dHJHcnAyID0gZ3JhbW1hci5nZXRHbG9iYWxBdHRyaWJ1dGVHcm91cERlY2woYXR0ckdycC5mTmFtZSwgbG9jKTsKLSAgICAgICAgaWYgKGF0dHJHcnAyID09IG51bGwpIHsKLSAgICAgICAgICAgIGdyYW1tYXIuYWRkR2xvYmFsQXR0cmlidXRlR3JvdXBEZWNsKGF0dHJHcnAsIGxvYyk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBoYW5kbGUgZHVwbGljYXRlcwotICAgICAgICBpZiAoZlNjaGVtYUhhbmRsZXIuZlRvbGVyYXRlRHVwbGljYXRlcykgewotICAgICAgICAgICAgaWYgKGF0dHJHcnAyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBhdHRyR3JwID0gYXR0ckdycDI7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmU2NoZW1hSGFuZGxlci5hZGRHbG9iYWxBdHRyaWJ1dGVHcm91cERlY2woYXR0ckdycCk7Ci0gICAgICAgIH0KLQotICAgICAgICBmQXR0ckNoZWNrZXIucmV0dXJuQXR0ckFycmF5KGF0dHJWYWx1ZXMsIHNjaGVtYURvYyk7Ci0gICAgICAgIHJldHVybiBhdHRyR3JwOwotCi0gICAgfSAvLyB0cmF2ZXJzZUdsb2JhbAotCi19IC8vIFhTREF0dHJpYnV0ZUdyb3VwVHJhdmVyc2VyCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL3RyYXZlcnNlcnMvWFNEQXR0cmlidXRlVHJhdmVyc2VyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL3RyYXZlcnNlcnMvWFNEQXR0cmlidXRlVHJhdmVyc2VyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDBhYTBiMzIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy90cmF2ZXJzZXJzL1hTREF0dHJpYnV0ZVRyYXZlcnNlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDg4ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLnRyYXZlcnNlcnM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYuSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LlZhbGlkYXRlZEluZm87Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LlhTU2ltcGxlVHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMuU2NoZW1hR3JhbW1hcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMuU2NoZW1hU3ltYm9sczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMuWFNBbm5vdGF0aW9uSW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMuWFNBdHRyaWJ1dGVEZWNsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5YU0F0dHJpYnV0ZVVzZUltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlhTQ29tcGxleFR5cGVEZWNsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy51dGlsLlhJbnQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLnV0aWwuWFNPYmplY3RMaXN0SW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuRE9NVXRpbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuWE1MU3ltYm9sczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5RTmFtZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNPYmplY3RMaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNUeXBlRGVmaW5pdGlvbjsKLWltcG9ydCBvcmcudzNjLmRvbS5FbGVtZW50OwotCi0vKioKLSAqIFRoZSBhdHRyaWJ1dGUgZGVjbGFyYXRpb24gc2NoZW1hIGNvbXBvbmVudCB0cmF2ZXJzZXIuCi0gKgotICogPGF0dHJpYnV0ZQotICogICBkZWZhdWx0ID0gc3RyaW5nCi0gKiAgIGZpeGVkID0gc3RyaW5nCi0gKiAgIGZvcm0gPSAocXVhbGlmaWVkIHwgdW5xdWFsaWZpZWQpCi0gKiAgIGlkID0gSUQKLSAqICAgbmFtZSA9IE5DTmFtZQotICogICByZWYgPSBRTmFtZQotICogICB0eXBlID0gUU5hbWUKLSAqICAgdXNlID0gKG9wdGlvbmFsIHwgcHJvaGliaXRlZCB8IHJlcXVpcmVkKSA6IG9wdGlvbmFsCi0gKiAgIHthbnkgYXR0cmlidXRlcyB3aXRoIG5vbi1zY2hlbWEgbmFtZXNwYWNlIC4gLiAufT4KLSAqICAgQ29udGVudDogKGFubm90YXRpb24/LCAoc2ltcGxlVHlwZT8pKQotICogPC9hdHRyaWJ1dGU+Ci0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgU2FuZHkgR2FvLCBJQk0KLSAqIEBhdXRob3IgTmVlcmFqIEJhamFqLCBTdW4gTWljcm9zeXN0ZW1zLCBpbmMuCi0gKiBAdmVyc2lvbiAkSWQ6IFhTREF0dHJpYnV0ZVRyYXZlcnNlci5qYXZhLHYgMS43IDIwMTAtMTEtMDEgMDQ6NDA6MDIgam9laHcgRXhwICQKLSAqLwotY2xhc3MgWFNEQXR0cmlidXRlVHJhdmVyc2VyIGV4dGVuZHMgWFNEQWJzdHJhY3RUcmF2ZXJzZXIgewotCi0gICAgcHVibGljIFhTREF0dHJpYnV0ZVRyYXZlcnNlciAoWFNESGFuZGxlciBoYW5kbGVyLAotICAgICAgICAgICAgWFNBdHRyaWJ1dGVDaGVja2VyIGdBdHRyQ2hlY2spIHsKLSAgICAgICAgc3VwZXIoaGFuZGxlciwgZ0F0dHJDaGVjayk7Ci0gICAgfQotCi0gICAgcHJvdGVjdGVkIFhTQXR0cmlidXRlVXNlSW1wbCB0cmF2ZXJzZUxvY2FsKEVsZW1lbnQgYXR0ckRlY2wsCi0gICAgICAgICAgICBYU0RvY3VtZW50SW5mbyBzY2hlbWFEb2MsCi0gICAgICAgICAgICBTY2hlbWFHcmFtbWFyIGdyYW1tYXIsCi0gICAgICAgICAgICBYU0NvbXBsZXhUeXBlRGVjbCBlbmNsb3NpbmdDVCkgewotCi0gICAgICAgIC8vIEdlbmVyYWwgQXR0cmlidXRlIENoZWNraW5nCi0gICAgICAgIE9iamVjdFtdIGF0dHJWYWx1ZXMgPSBmQXR0ckNoZWNrZXIuY2hlY2tBdHRyaWJ1dGVzKGF0dHJEZWNsLCBmYWxzZSwgc2NoZW1hRG9jKTsKLQotICAgICAgICBTdHJpbmcgZGVmYXVsdEF0dCA9IChTdHJpbmcpIGF0dHJWYWx1ZXNbWFNBdHRyaWJ1dGVDaGVja2VyLkFUVElEWF9ERUZBVUxUXTsKLSAgICAgICAgU3RyaW5nIGZpeGVkQXR0ICAgPSAoU3RyaW5nKSBhdHRyVmFsdWVzW1hTQXR0cmlidXRlQ2hlY2tlci5BVFRJRFhfRklYRURdOwotICAgICAgICBTdHJpbmcgbmFtZUF0dCAgICA9IChTdHJpbmcpIGF0dHJWYWx1ZXNbWFNBdHRyaWJ1dGVDaGVja2VyLkFUVElEWF9OQU1FXTsKLSAgICAgICAgUU5hbWUgIHJlZkF0dCAgICAgPSAoUU5hbWUpICBhdHRyVmFsdWVzW1hTQXR0cmlidXRlQ2hlY2tlci5BVFRJRFhfUkVGXTsKLSAgICAgICAgWEludCAgIHVzZUF0dCAgICAgPSAoWEludCkgICBhdHRyVmFsdWVzW1hTQXR0cmlidXRlQ2hlY2tlci5BVFRJRFhfVVNFXTsKLQotICAgICAgICAvLyBnZXQgJ2F0dHJpYnV0ZSBkZWNsYXJhdGlvbicKLSAgICAgICAgWFNBdHRyaWJ1dGVEZWNsIGF0dHJpYnV0ZSA9IG51bGw7Ci0gICAgICAgIFhTQW5ub3RhdGlvbkltcGwgYW5ub3RhdGlvbiA9IG51bGw7Ci0gICAgICAgIGlmIChhdHRyRGVjbC5nZXRBdHRyaWJ1dGVOb2RlKFNjaGVtYVN5bWJvbHMuQVRUX1JFRikgIT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKHJlZkF0dCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgYXR0cmlidXRlID0gKFhTQXR0cmlidXRlRGVjbClmU2NoZW1hSGFuZGxlci5nZXRHbG9iYWxEZWNsKHNjaGVtYURvYywgWFNESGFuZGxlci5BVFRSSUJVVEVfVFlQRSwgcmVmQXR0LCBhdHRyRGVjbCk7Ci0KLSAgICAgICAgICAgICAgICBFbGVtZW50IGNoaWxkID0gRE9NVXRpbC5nZXRGaXJzdENoaWxkRWxlbWVudChhdHRyRGVjbCk7Ci0gICAgICAgICAgICAgICAgaWYgKGNoaWxkICE9IG51bGwgJiYgRE9NVXRpbC5nZXRMb2NhbE5hbWUoY2hpbGQpLmVxdWFscyhTY2hlbWFTeW1ib2xzLkVMVF9BTk5PVEFUSU9OKSkgewotICAgICAgICAgICAgICAgICAgICBhbm5vdGF0aW9uID0gdHJhdmVyc2VBbm5vdGF0aW9uRGVjbChjaGlsZCwgYXR0clZhbHVlcywgZmFsc2UsIHNjaGVtYURvYyk7Ci0gICAgICAgICAgICAgICAgICAgIGNoaWxkID0gRE9NVXRpbC5nZXROZXh0U2libGluZ0VsZW1lbnQoY2hpbGQpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHRleHQgPSBET01VdGlsLmdldFN5bnRoZXRpY0Fubm90YXRpb24oYXR0ckRlY2wpOwotICAgICAgICAgICAgICAgICAgICBpZiAodGV4dCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBhbm5vdGF0aW9uID0gdHJhdmVyc2VTeW50aGV0aWNBbm5vdGF0aW9uKGF0dHJEZWNsLCB0ZXh0LCBhdHRyVmFsdWVzLCBmYWxzZSwgc2NoZW1hRG9jKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIGlmIChjaGlsZCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKCJzcmMtYXR0cmlidXRlLjMuMiIsIG5ldyBPYmplY3RbXXtyZWZBdHQucmF3bmFtZX0sIGNoaWxkKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLy8gZm9yIGVycm9yIHJlcG9ydGluZwotICAgICAgICAgICAgICAgIG5hbWVBdHQgPSByZWZBdHQubG9jYWxwYXJ0OwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBhdHRyaWJ1dGUgPSBudWxsOwotICAgICAgICAgICAgfQotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgYXR0cmlidXRlID0gdHJhdmVyc2VOYW1lZEF0dHIoYXR0ckRlY2wsIGF0dHJWYWx1ZXMsIHNjaGVtYURvYywgZ3JhbW1hciwgZmFsc2UsIGVuY2xvc2luZ0NUKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIGdldCAndmFsdWUgY29uc3RyYWludCcKLSAgICAgICAgc2hvcnQgY29uc1R5cGUgPSBYU0NvbnN0YW50cy5WQ19OT05FOwotICAgICAgICBpZiAoZGVmYXVsdEF0dCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBjb25zVHlwZSA9IFhTQ29uc3RhbnRzLlZDX0RFRkFVTFQ7Ci0gICAgICAgIH0gZWxzZSBpZiAoZml4ZWRBdHQgIT0gbnVsbCkgewotICAgICAgICAgICAgY29uc1R5cGUgPSBYU0NvbnN0YW50cy5WQ19GSVhFRDsKLSAgICAgICAgICAgIGRlZmF1bHRBdHQgPSBmaXhlZEF0dDsKLSAgICAgICAgICAgIGZpeGVkQXR0ID0gbnVsbDsKLSAgICAgICAgfQotCi0gICAgICAgIFhTQXR0cmlidXRlVXNlSW1wbCBhdHRyVXNlID0gbnVsbDsKLSAgICAgICAgaWYgKGF0dHJpYnV0ZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAoZlNjaGVtYUhhbmRsZXIuZkRlY2xQb29sICE9bnVsbCkgewotICAgICAgICAgICAgICAgIGF0dHJVc2UgPSBmU2NoZW1hSGFuZGxlci5mRGVjbFBvb2wuZ2V0QXR0cmlidXRlVXNlKCk7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIGF0dHJVc2UgPSBuZXcgWFNBdHRyaWJ1dGVVc2VJbXBsKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBhdHRyVXNlLmZBdHRyRGVjbCA9IGF0dHJpYnV0ZTsKLSAgICAgICAgICAgIGF0dHJVc2UuZlVzZSA9IHVzZUF0dC5zaG9ydFZhbHVlKCk7Ci0gICAgICAgICAgICBhdHRyVXNlLmZDb25zdHJhaW50VHlwZSA9IGNvbnNUeXBlOwotICAgICAgICAgICAgaWYgKGRlZmF1bHRBdHQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGF0dHJVc2UuZkRlZmF1bHQgPSBuZXcgVmFsaWRhdGVkSW5mbygpOwotICAgICAgICAgICAgICAgIGF0dHJVc2UuZkRlZmF1bHQubm9ybWFsaXplZFZhbHVlID0gZGVmYXVsdEF0dDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIEdldCB0aGUgYW5ub3RhdGlvbiBhc3NvY2lhdGVkIHdpdGh0IHRoZSBsb2NhbCBhdHRyIGRlY2wKLSAgICAgICAgICAgIGlmIChhdHRyRGVjbC5nZXRBdHRyaWJ1dGVOb2RlKFNjaGVtYVN5bWJvbHMuQVRUX1JFRikgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGF0dHJVc2UuZkFubm90YXRpb25zID0gYXR0cmlidXRlLmdldEFubm90YXRpb25zKCk7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIFhTT2JqZWN0TGlzdCBhbm5vdGF0aW9uczsKLSAgICAgICAgICAgICAgICBpZiAoYW5ub3RhdGlvbiAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGFubm90YXRpb25zID0gbmV3IFhTT2JqZWN0TGlzdEltcGwoKTsKLSAgICAgICAgICAgICAgICAgICAgKChYU09iamVjdExpc3RJbXBsKSBhbm5vdGF0aW9ucykuYWRkWFNPYmplY3QoYW5ub3RhdGlvbik7Ci0gICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgYW5ub3RhdGlvbnMgPSBYU09iamVjdExpc3RJbXBsLkVNUFRZX0xJU1Q7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGF0dHJVc2UuZkFubm90YXRpb25zID0gYW5ub3RhdGlvbnM7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvL3NyYy1hdHRyaWJ1dGUKLQotICAgICAgICAvLyAxIGRlZmF1bHQgYW5kIGZpeGVkIG11c3Qgbm90IGJvdGggYmUgcHJlc2VudC4KLSAgICAgICAgaWYgKGRlZmF1bHRBdHQgIT0gbnVsbCAmJiBmaXhlZEF0dCAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcigic3JjLWF0dHJpYnV0ZS4xIiwgbmV3IE9iamVjdFtde25hbWVBdHR9LCBhdHRyRGVjbCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyAyIElmIGRlZmF1bHQgYW5kIHVzZSBhcmUgYm90aCBwcmVzZW50LCB1c2UgbXVzdCBoYXZlIHRoZSBhY3R1YWwgdmFsdWUgb3B0aW9uYWwuCi0gICAgICAgIGlmIChjb25zVHlwZSA9PSBYU0NvbnN0YW50cy5WQ19ERUZBVUxUICYmCi0gICAgICAgICAgICAgICAgdXNlQXR0ICE9IG51bGwgJiYgdXNlQXR0LmludFZhbHVlKCkgIT0gU2NoZW1hU3ltYm9scy5VU0VfT1BUSU9OQUwpIHsKLSAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKCJzcmMtYXR0cmlidXRlLjIiLCBuZXcgT2JqZWN0W117bmFtZUF0dH0sIGF0dHJEZWNsKTsKLSAgICAgICAgICAgIC8vIFJlY292ZXIgYnkgaG9ub3VyaW5nIHRoZSBkZWZhdWx0IHZhbHVlCi0gICAgICAgICAgICBhdHRyVXNlLmZVc2UgPSBTY2hlbWFTeW1ib2xzLlVTRV9PUFRJT05BTDsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIGEtcHJvcHMtY29ycmVjdAotCi0gICAgICAgIGlmIChkZWZhdWx0QXR0ICE9IG51bGwgJiYgYXR0clVzZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAvLyAyIGlmIHRoZXJlIGlzIGEge3ZhbHVlIGNvbnN0cmFpbnR9LCB0aGUgY2Fub25pY2FsIGxleGljYWwgcmVwcmVzZW50YXRpb24gb2YgaXRzIHZhbHVlIG11c3QgYmUgdmFsaWQgd2l0aCByZXNwZWN0IHRvIHRoZSB7dHlwZSBkZWZpbml0aW9ufSBhcyBkZWZpbmVkIGluIFN0cmluZyBWYWxpZCAoMy4xNC40KS4KLSAgICAgICAgICAgIGZWYWxpZGF0aW9uU3RhdGUuc2V0TmFtZXNwYWNlU3VwcG9ydChzY2hlbWFEb2MuZk5hbWVzcGFjZVN1cHBvcnQpOwotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICBjaGVja0RlZmF1bHRWYWxpZChhdHRyVXNlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhdGNoIChJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbiBpZGUpIHsKLSAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvciAoaWRlLmdldEtleSgpLCBpZGUuZ2V0QXJncygpLCBhdHRyRGVjbCk7Ci0gICAgICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IgKCJhLXByb3BzLWNvcnJlY3QuMiIsIG5ldyBPYmplY3RbXXtuYW1lQXR0LCBkZWZhdWx0QXR0fSwgYXR0ckRlY2wpOwotICAgICAgICAgICAgICAgIC8vIFJlY292ZXIgYnkgcmVtb3ZpbmcgdGhlIGRlZmF1bHQgdmFsdWUKLSAgICAgICAgICAgICAgICBhdHRyVXNlLmZEZWZhdWx0ID0gbnVsbDsKLSAgICAgICAgICAgICAgICBhdHRyVXNlLmZDb25zdHJhaW50VHlwZSA9IFhTQ29uc3RhbnRzLlZDX05PTkU7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIDMgSWYgdGhlIHt0eXBlIGRlZmluaXRpb259IGlzIG9yIGlzIGRlcml2ZWQgZnJvbSBJRCB0aGVuIHRoZXJlIG11c3Qgbm90IGJlIGEge3ZhbHVlIGNvbnN0cmFpbnR9LgotICAgICAgICAgICAgaWYgKCgoWFNTaW1wbGVUeXBlKWF0dHJpYnV0ZS5nZXRUeXBlRGVmaW5pdGlvbigpKS5pc0lEVHlwZSgpICkgewotICAgICAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yICgiYS1wcm9wcy1jb3JyZWN0LjMiLCBuZXcgT2JqZWN0W117bmFtZUF0dH0sIGF0dHJEZWNsKTsKLSAgICAgICAgICAgICAgICAvLyBSZWNvdmVyIGJ5IHJlbW92aW5nIHRoZSBkZWZhdWx0IHZhbHVlCi0gICAgICAgICAgICAgICAgYXR0clVzZS5mRGVmYXVsdCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgYXR0clVzZS5mQ29uc3RyYWludFR5cGUgPSBYU0NvbnN0YW50cy5WQ19OT05FOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBjaGVjayAzLjUuNiBjb25zdHJhaW50Ci0gICAgICAgICAgICAvLyBBdHRyaWJ1dGUgVXNlIENvcnJlY3QKLSAgICAgICAgICAgIC8vIDIgSWYgdGhlIHthdHRyaWJ1dGUgZGVjbGFyYXRpb259IGhhcyBhIGZpeGVkIHt2YWx1ZSBjb25zdHJhaW50fSwgdGhlbiBpZiB0aGUgYXR0cmlidXRlIHVzZSBpdHNlbGYgaGFzIGEge3ZhbHVlIGNvbnN0cmFpbnR9LCBpdCBtdXN0IGFsc28gYmUgZml4ZWQgYW5kIGl0cyB2YWx1ZSBtdXN0IG1hdGNoIHRoYXQgb2YgdGhlIHthdHRyaWJ1dGUgZGVjbGFyYXRpb259J3Mge3ZhbHVlIGNvbnN0cmFpbnR9LgotICAgICAgICAgICAgaWYgKGF0dHJVc2UuZkF0dHJEZWNsLmdldENvbnN0cmFpbnRUeXBlKCkgPT0gWFNDb25zdGFudHMuVkNfRklYRUQgJiYKLSAgICAgICAgICAgICAgICAgICAgYXR0clVzZS5mQ29uc3RyYWludFR5cGUgIT0gWFNDb25zdGFudHMuVkNfTk9ORSkgewotICAgICAgICAgICAgICAgIGlmIChhdHRyVXNlLmZDb25zdHJhaW50VHlwZSAhPSBYU0NvbnN0YW50cy5WQ19GSVhFRCB8fAotICAgICAgICAgICAgICAgICAgICAgICAgIWF0dHJVc2UuZkF0dHJEZWNsLmdldFZhbEluZm8oKS5hY3R1YWxWYWx1ZS5lcXVhbHMoYXR0clVzZS5mRGVmYXVsdC5hY3R1YWxWYWx1ZSkpIHsKLSAgICAgICAgICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IgKCJhdS1wcm9wcy1jb3JyZWN0LjIiLCBuZXcgT2JqZWN0W117bmFtZUF0dCwgYXR0clVzZS5mQXR0ckRlY2wuZ2V0VmFsSW5mbygpLnN0cmluZ1ZhbHVlKCl9LCBhdHRyRGVjbCk7Ci0gICAgICAgICAgICAgICAgICAgIC8vIFJlY292ZXIgYnkgdXNpbmcgdGhlIGRlY2wncyB7dmFsdWUgY29uc3RyYWludH0KLSAgICAgICAgICAgICAgICAgICAgYXR0clVzZS5mRGVmYXVsdCA9IGF0dHJVc2UuZkF0dHJEZWNsLmdldFZhbEluZm8oKTsKLSAgICAgICAgICAgICAgICAgICAgYXR0clVzZS5mQ29uc3RyYWludFR5cGUgPSBYU0NvbnN0YW50cy5WQ19GSVhFRDsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBmQXR0ckNoZWNrZXIucmV0dXJuQXR0ckFycmF5KGF0dHJWYWx1ZXMsIHNjaGVtYURvYyk7Ci0gICAgICAgIHJldHVybiBhdHRyVXNlOwotICAgIH0KLQotICAgIHByb3RlY3RlZCBYU0F0dHJpYnV0ZURlY2wgdHJhdmVyc2VHbG9iYWwoRWxlbWVudCBhdHRyRGVjbCwKLSAgICAgICAgICAgIFhTRG9jdW1lbnRJbmZvIHNjaGVtYURvYywKLSAgICAgICAgICAgIFNjaGVtYUdyYW1tYXIgZ3JhbW1hcikgewotCi0gICAgICAgIC8vIEdlbmVyYWwgQXR0cmlidXRlIENoZWNraW5nCi0gICAgICAgIE9iamVjdFtdIGF0dHJWYWx1ZXMgPSBmQXR0ckNoZWNrZXIuY2hlY2tBdHRyaWJ1dGVzKGF0dHJEZWNsLCB0cnVlLCBzY2hlbWFEb2MpOwotICAgICAgICBYU0F0dHJpYnV0ZURlY2wgYXR0cmlidXRlID0gdHJhdmVyc2VOYW1lZEF0dHIoYXR0ckRlY2wsIGF0dHJWYWx1ZXMsIHNjaGVtYURvYywgZ3JhbW1hciwgdHJ1ZSwgbnVsbCk7Ci0gICAgICAgIGZBdHRyQ2hlY2tlci5yZXR1cm5BdHRyQXJyYXkoYXR0clZhbHVlcywgc2NoZW1hRG9jKTsKLSAgICAgICAgcmV0dXJuIGF0dHJpYnV0ZTsKLQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYXZlcnNlIGEgZ2xvYmFsbHkgZGVjbGFyZWQgYXR0cmlidXRlLgotICAgICAqCi0gICAgICogQHBhcmFtICBhdHRyRGVjbAotICAgICAqIEBwYXJhbSAgYXR0clZhbHVlcwotICAgICAqIEBwYXJhbSAgc2NoZW1hRG9jCi0gICAgICogQHBhcmFtICBncmFtbWFyCi0gICAgICogQHBhcmFtICBpc0dsb2JhbAotICAgICAqIEByZXR1cm4gdGhlIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbiBpbmRleAotICAgICAqLwotICAgIFhTQXR0cmlidXRlRGVjbCB0cmF2ZXJzZU5hbWVkQXR0cihFbGVtZW50IGF0dHJEZWNsLAotICAgICAgICAgICAgT2JqZWN0W10gYXR0clZhbHVlcywKLSAgICAgICAgICAgIFhTRG9jdW1lbnRJbmZvIHNjaGVtYURvYywKLSAgICAgICAgICAgIFNjaGVtYUdyYW1tYXIgZ3JhbW1hciwKLSAgICAgICAgICAgIGJvb2xlYW4gaXNHbG9iYWwsCi0gICAgICAgICAgICBYU0NvbXBsZXhUeXBlRGVjbCBlbmNsb3NpbmdDVCkgewotCi0gICAgICAgIFN0cmluZyAgZGVmYXVsdEF0dCA9IChTdHJpbmcpIGF0dHJWYWx1ZXNbWFNBdHRyaWJ1dGVDaGVja2VyLkFUVElEWF9ERUZBVUxUXTsKLSAgICAgICAgU3RyaW5nICBmaXhlZEF0dCAgID0gKFN0cmluZykgYXR0clZhbHVlc1tYU0F0dHJpYnV0ZUNoZWNrZXIuQVRUSURYX0ZJWEVEXTsKLSAgICAgICAgWEludCAgICBmb3JtQXR0ICAgID0gKFhJbnQpICAgYXR0clZhbHVlc1tYU0F0dHJpYnV0ZUNoZWNrZXIuQVRUSURYX0ZPUk1dOwotICAgICAgICBTdHJpbmcgIG5hbWVBdHQgICAgPSAoU3RyaW5nKSBhdHRyVmFsdWVzW1hTQXR0cmlidXRlQ2hlY2tlci5BVFRJRFhfTkFNRV07Ci0gICAgICAgIFFOYW1lICAgdHlwZUF0dCAgICA9IChRTmFtZSkgIGF0dHJWYWx1ZXNbWFNBdHRyaWJ1dGVDaGVja2VyLkFUVElEWF9UWVBFXTsKLQotICAgICAgICAvLyBTdGVwIDE6IGdldCBkZWNsYXJhdGlvbiBpbmZvcm1hdGlvbgotICAgICAgICBYU0F0dHJpYnV0ZURlY2wgYXR0cmlidXRlID0gbnVsbDsKLSAgICAgICAgaWYgKGZTY2hlbWFIYW5kbGVyLmZEZWNsUG9vbCAhPW51bGwpIHsKLSAgICAgICAgICAgIGF0dHJpYnV0ZSA9IGZTY2hlbWFIYW5kbGVyLmZEZWNsUG9vbC5nZXRBdHRyaWJ1dGVEZWNsKCk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBhdHRyaWJ1dGUgPSBuZXcgWFNBdHRyaWJ1dGVEZWNsKCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBnZXQgJ25hbWUnCi0gICAgICAgIGlmIChuYW1lQXR0ICE9IG51bGwpCi0gICAgICAgICAgICBuYW1lQXR0ID0gZlN5bWJvbFRhYmxlLmFkZFN5bWJvbChuYW1lQXR0KTsKLQotICAgICAgICAvLyBnZXQgJ3RhcmdldCBuYW1lc3BhY2UnCi0gICAgICAgIFN0cmluZyB0bnNBdHQgPSBudWxsOwotICAgICAgICBYU0NvbXBsZXhUeXBlRGVjbCBlbmNsQ1QgPSBudWxsOwotICAgICAgICBzaG9ydCBzY29wZSA9IFhTQXR0cmlidXRlRGVjbC5TQ09QRV9BQlNFTlQ7Ci0gICAgICAgIGlmIChpc0dsb2JhbCkgewotICAgICAgICAgICAgdG5zQXR0ID0gc2NoZW1hRG9jLmZUYXJnZXROYW1lc3BhY2U7Ci0gICAgICAgICAgICBzY29wZSA9IFhTQXR0cmlidXRlRGVjbC5TQ09QRV9HTE9CQUw7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBpZiAoZW5jbG9zaW5nQ1QgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGVuY2xDVCA9IGVuY2xvc2luZ0NUOwotICAgICAgICAgICAgICAgIHNjb3BlID0gWFNBdHRyaWJ1dGVEZWNsLlNDT1BFX0xPQ0FMOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKGZvcm1BdHQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGlmIChmb3JtQXR0LmludFZhbHVlKCkgPT0gU2NoZW1hU3ltYm9scy5GT1JNX1FVQUxJRklFRCkKLSAgICAgICAgICAgICAgICAgICAgdG5zQXR0ID0gc2NoZW1hRG9jLmZUYXJnZXROYW1lc3BhY2U7Ci0gICAgICAgICAgICB9IGVsc2UgaWYgKHNjaGVtYURvYy5mQXJlTG9jYWxBdHRyaWJ1dGVzUXVhbGlmaWVkKSB7Ci0gICAgICAgICAgICAgICAgdG5zQXR0ID0gc2NoZW1hRG9jLmZUYXJnZXROYW1lc3BhY2U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgLy8gZ2V0ICd2YWx1ZSBjb25zdHJhaW50JwotICAgICAgICAvLyBmb3IgbG9jYWwgbmFtZWQgYXR0cmlidXRlLCB2YWx1ZSBjb25zdHJhaW50IGlzIGFic2VudAotICAgICAgICBWYWxpZGF0ZWRJbmZvIGF0dERlZmF1bHQgPSBudWxsOwotICAgICAgICBzaG9ydCBjb25zdHJhaW50VHlwZSA9IFhTQ29uc3RhbnRzLlZDX05PTkU7Ci0gICAgICAgIGlmIChpc0dsb2JhbCkgewotICAgICAgICAgICAgaWYgKGZpeGVkQXR0ICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBhdHREZWZhdWx0ID0gbmV3IFZhbGlkYXRlZEluZm8oKTsKLSAgICAgICAgICAgICAgICBhdHREZWZhdWx0Lm5vcm1hbGl6ZWRWYWx1ZSA9IGZpeGVkQXR0OwotICAgICAgICAgICAgICAgIGNvbnN0cmFpbnRUeXBlID0gWFNDb25zdGFudHMuVkNfRklYRUQ7Ci0gICAgICAgICAgICB9IGVsc2UgaWYgKGRlZmF1bHRBdHQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGF0dERlZmF1bHQgPSBuZXcgVmFsaWRhdGVkSW5mbygpOwotICAgICAgICAgICAgICAgIGF0dERlZmF1bHQubm9ybWFsaXplZFZhbHVlID0gZGVmYXVsdEF0dDsKLSAgICAgICAgICAgICAgICBjb25zdHJhaW50VHlwZSA9IFhTQ29uc3RhbnRzLlZDX0RFRkFVTFQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBnZXQgJ2Fubm90YXRpb24nCi0gICAgICAgIEVsZW1lbnQgY2hpbGQgPSBET01VdGlsLmdldEZpcnN0Q2hpbGRFbGVtZW50KGF0dHJEZWNsKTsKLSAgICAgICAgWFNBbm5vdGF0aW9uSW1wbCBhbm5vdGF0aW9uID0gbnVsbDsKLSAgICAgICAgaWYgKGNoaWxkICE9IG51bGwgJiYgRE9NVXRpbC5nZXRMb2NhbE5hbWUoY2hpbGQpLmVxdWFscyhTY2hlbWFTeW1ib2xzLkVMVF9BTk5PVEFUSU9OKSkgewotICAgICAgICAgICAgYW5ub3RhdGlvbiA9IHRyYXZlcnNlQW5ub3RhdGlvbkRlY2woY2hpbGQsIGF0dHJWYWx1ZXMsIGZhbHNlLCBzY2hlbWFEb2MpOwotICAgICAgICAgICAgY2hpbGQgPSBET01VdGlsLmdldE5leHRTaWJsaW5nRWxlbWVudChjaGlsZCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBTdHJpbmcgdGV4dCA9IERPTVV0aWwuZ2V0U3ludGhldGljQW5ub3RhdGlvbihhdHRyRGVjbCk7Ci0gICAgICAgICAgICBpZiAodGV4dCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgYW5ub3RhdGlvbiA9IHRyYXZlcnNlU3ludGhldGljQW5ub3RhdGlvbihhdHRyRGVjbCwgdGV4dCwgYXR0clZhbHVlcywgZmFsc2UsIHNjaGVtYURvYyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBnZXQgJ3R5cGUgZGVmaW5pdGlvbicKLSAgICAgICAgWFNTaW1wbGVUeXBlIGF0dHJUeXBlID0gbnVsbDsKLSAgICAgICAgYm9vbGVhbiBoYXZlQW5vblR5cGUgPSBmYWxzZTsKLQotICAgICAgICAvLyBIYW5kbGUgQW5vbnltb3VzIHR5cGUgaWYgdGhlcmUgaXMgb25lCi0gICAgICAgIGlmIChjaGlsZCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBTdHJpbmcgY2hpbGROYW1lID0gRE9NVXRpbC5nZXRMb2NhbE5hbWUoY2hpbGQpOwotCi0gICAgICAgICAgICBpZiAoY2hpbGROYW1lLmVxdWFscyhTY2hlbWFTeW1ib2xzLkVMVF9TSU1QTEVUWVBFKSkgewotICAgICAgICAgICAgICAgIGF0dHJUeXBlID0gZlNjaGVtYUhhbmRsZXIuZlNpbXBsZVR5cGVUcmF2ZXJzZXIudHJhdmVyc2VMb2NhbChjaGlsZCwgc2NoZW1hRG9jLCBncmFtbWFyKTsKLSAgICAgICAgICAgICAgICBoYXZlQW5vblR5cGUgPSB0cnVlOwotICAgICAgICAgICAgICAgIGNoaWxkID0gRE9NVXRpbC5nZXROZXh0U2libGluZ0VsZW1lbnQoY2hpbGQpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gSGFuZGxlIHR5cGUgYXR0cmlidXRlCi0gICAgICAgIGlmIChhdHRyVHlwZSA9PSBudWxsICYmIHR5cGVBdHQgIT0gbnVsbCkgewotICAgICAgICAgICAgWFNUeXBlRGVmaW5pdGlvbiB0eXBlID0gKFhTVHlwZURlZmluaXRpb24pZlNjaGVtYUhhbmRsZXIuZ2V0R2xvYmFsRGVjbChzY2hlbWFEb2MsIFhTREhhbmRsZXIuVFlQRURFQ0xfVFlQRSwgdHlwZUF0dCwgYXR0ckRlY2wpOwotICAgICAgICAgICAgaWYgKHR5cGUgIT0gbnVsbCAmJiB0eXBlLmdldFR5cGVDYXRlZ29yeSgpID09IFhTVHlwZURlZmluaXRpb24uU0lNUExFX1RZUEUpIHsKLSAgICAgICAgICAgICAgICBhdHRyVHlwZSA9IChYU1NpbXBsZVR5cGUpdHlwZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKCJzcmMtcmVzb2x2ZSIsIG5ldyBPYmplY3RbXXt0eXBlQXR0LnJhd25hbWUsICJzaW1wbGVUeXBlIGRlZmluaXRpb24ifSwgYXR0ckRlY2wpOwotICAgICAgICAgICAgICAgIGlmICh0eXBlID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZS5mVW5yZXNvbHZlZFR5cGVOYW1lID0gdHlwZUF0dDsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoYXR0clR5cGUgPT0gbnVsbCkgewotICAgICAgICAgICAgYXR0clR5cGUgPSBTY2hlbWFHcmFtbWFyLmZBbnlTaW1wbGVUeXBlOwotICAgICAgICB9Ci0KLSAgICAgICAgWFNPYmplY3RMaXN0IGFubm90YXRpb25zOwotICAgICAgICBpZiAoYW5ub3RhdGlvbiAhPSBudWxsKSB7Ci0gICAgICAgICAgICBhbm5vdGF0aW9ucyA9IG5ldyBYU09iamVjdExpc3RJbXBsKCk7Ci0gICAgICAgICAgICAoKFhTT2JqZWN0TGlzdEltcGwpYW5ub3RhdGlvbnMpLmFkZFhTT2JqZWN0KGFubm90YXRpb24pOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgYW5ub3RhdGlvbnMgPSBYU09iamVjdExpc3RJbXBsLkVNUFRZX0xJU1Q7Ci0gICAgICAgIH0KLSAgICAgICAgYXR0cmlidXRlLnNldFZhbHVlcyhuYW1lQXR0LCB0bnNBdHQsIGF0dHJUeXBlLCBjb25zdHJhaW50VHlwZSwgc2NvcGUsCi0gICAgICAgICAgICAgICAgYXR0RGVmYXVsdCwgZW5jbENULCBhbm5vdGF0aW9ucyk7Ci0KLSAgICAgICAgLy8gU3RlcCAzOiBjaGVjayBhZ2FpbnN0IHNjaGVtYSBmb3Igc2NoZW1hcwotCi0gICAgICAgIC8vIHJlcXVpcmVkIGF0dHJpYnV0ZXMKLSAgICAgICAgaWYgKG5hbWVBdHQgPT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKGlzR2xvYmFsKQotICAgICAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKCJzNHMtYXR0LW11c3QtYXBwZWFyIiwgbmV3IE9iamVjdFtde1NjaGVtYVN5bWJvbHMuRUxUX0FUVFJJQlVURSwgU2NoZW1hU3ltYm9scy5BVFRfTkFNRX0sIGF0dHJEZWNsKTsKLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcigic3JjLWF0dHJpYnV0ZS4zLjEiLCBudWxsLCBhdHRyRGVjbCk7Ci0gICAgICAgICAgICBuYW1lQXR0ID0gTk9fTkFNRTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIGVsZW1lbnQKLSAgICAgICAgaWYgKGNoaWxkICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKCJzNHMtZWx0LW11c3QtbWF0Y2guMSIsIG5ldyBPYmplY3RbXXtuYW1lQXR0LCAiKGFubm90YXRpb24/LCAoc2ltcGxlVHlwZT8pKSIsIERPTVV0aWwuZ2V0TG9jYWxOYW1lKGNoaWxkKX0sIGNoaWxkKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIFN0ZXAgNDogY2hlY2sgMy4yLjMgY29uc3RyYWludHMKLQotICAgICAgICAvLyBzcmMtYXR0cmlidXRlCi0KLSAgICAgICAgLy8gMSBkZWZhdWx0IGFuZCBmaXhlZCBtdXN0IG5vdCBib3RoIGJlIHByZXNlbnQuCi0gICAgICAgIGlmIChkZWZhdWx0QXR0ICE9IG51bGwgJiYgZml4ZWRBdHQgIT0gbnVsbCkgewotICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoInNyYy1hdHRyaWJ1dGUuMSIsIG5ldyBPYmplY3RbXXtuYW1lQXR0fSwgYXR0ckRlY2wpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gMiBJZiBkZWZhdWx0IGFuZCB1c2UgYXJlIGJvdGggcHJlc2VudCwgdXNlIG11c3QgaGF2ZSB0aGUgYWN0dWFsIHZhbHVlIG9wdGlvbmFsLgotICAgICAgICAvLyBUaGlzIGlzIGNoZWNrZWQgaW4gInRyYXZlcnNlIiBtZXRob2QKLQotICAgICAgICAvLyAzIElmIHRoZSBpdGVtJ3MgcGFyZW50IGlzIG5vdCA8c2NoZW1hPiwgdGhlbiBhbGwgb2YgdGhlIGZvbGxvd2luZyBtdXN0IGJlIHRydWU6Ci0gICAgICAgIC8vIDMuMSBPbmUgb2YgcmVmIG9yIG5hbWUgbXVzdCBiZSBwcmVzZW50LCBidXQgbm90IGJvdGguCi0gICAgICAgIC8vIFRoaXMgaXMgY2hlY2tlZCBpbiBYU0F0dHJpYnV0ZUNoZWNrZXIKLQotICAgICAgICAvLyAzLjIgSWYgcmVmIGlzIHByZXNlbnQsIHRoZW4gYWxsIG9mIDxzaW1wbGVUeXBlPiwgZm9ybSBhbmQgdHlwZSBtdXN0IGJlIGFic2VudC4KLSAgICAgICAgLy8gQXR0cmlidXRlcyBhcmUgY2hlY2tlZCBpbiBYU0F0dHJpYnV0ZUNoZWNrZXIsIGVsZW1lbnRzIGFyZSBjaGVja2VkIGluICJ0cmF2ZXJzZSIgbWV0aG9kCi0KLSAgICAgICAgLy8gNCB0eXBlIGFuZCA8c2ltcGxlVHlwZT4gbXVzdCBub3QgYm90aCBiZSBwcmVzZW50LgotICAgICAgICBpZiAoaGF2ZUFub25UeXBlICYmICh0eXBlQXR0ICE9IG51bGwpKSB7Ci0gICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvciggInNyYy1hdHRyaWJ1dGUuNCIsIG5ldyBPYmplY3RbXXtuYW1lQXR0fSwgYXR0ckRlY2wpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gU3RlcCA1OiBjaGVjayAzLjIuNiBjb25zdHJhaW50cwotICAgICAgICAvLyBjaGVjayBmb3IgTk9UQVRJT04gdHlwZQotICAgICAgICBjaGVja05vdGF0aW9uVHlwZShuYW1lQXR0LCBhdHRyVHlwZSwgYXR0ckRlY2wpOwotCi0gICAgICAgIC8vIGEtcHJvcHMtY29ycmVjdAotCi0gICAgICAgIC8vIDIgaWYgdGhlcmUgaXMgYSB7dmFsdWUgY29uc3RyYWludH0sIHRoZSBjYW5vbmljYWwgbGV4aWNhbCByZXByZXNlbnRhdGlvbiBvZiBpdHMgdmFsdWUgbXVzdCBiZSB2YWxpZCB3aXRoIHJlc3BlY3QgdG8gdGhlIHt0eXBlIGRlZmluaXRpb259IGFzIGRlZmluZWQgaW4gU3RyaW5nIFZhbGlkICgzLjE0LjQpLgotICAgICAgICBpZiAoYXR0RGVmYXVsdCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmVmFsaWRhdGlvblN0YXRlLnNldE5hbWVzcGFjZVN1cHBvcnQoc2NoZW1hRG9jLmZOYW1lc3BhY2VTdXBwb3J0KTsKLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgY2hlY2tEZWZhdWx0VmFsaWQoYXR0cmlidXRlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhdGNoIChJbnZhbGlkRGF0YXR5cGVWYWx1ZUV4Y2VwdGlvbiBpZGUpIHsKLSAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvciAoaWRlLmdldEtleSgpLCBpZGUuZ2V0QXJncygpLCBhdHRyRGVjbCk7Ci0gICAgICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IgKCJhLXByb3BzLWNvcnJlY3QuMiIsIG5ldyBPYmplY3RbXXtuYW1lQXR0LCBhdHREZWZhdWx0Lm5vcm1hbGl6ZWRWYWx1ZX0sIGF0dHJEZWNsKTsKLSAgICAgICAgICAgICAgICAvLyBSZWNvdmVyIGJ5IHJlbW92aW5nIHRoZSBkZWZhdWx0IHZhbHVlCi0gICAgICAgICAgICAgICAgYXR0RGVmYXVsdCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgY29uc3RyYWludFR5cGUgPSBYU0NvbnN0YW50cy5WQ19OT05FOwotICAgICAgICAgICAgICAgIGF0dHJpYnV0ZS5zZXRWYWx1ZXMobmFtZUF0dCwgdG5zQXR0LCBhdHRyVHlwZSwgY29uc3RyYWludFR5cGUsIHNjb3BlLAotICAgICAgICAgICAgICAgICAgICAgICAgYXR0RGVmYXVsdCwgZW5jbENULCBhbm5vdGF0aW9ucyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyAzIElmIHRoZSB7dHlwZSBkZWZpbml0aW9ufSBpcyBvciBpcyBkZXJpdmVkIGZyb20gSUQgdGhlbiB0aGVyZSBtdXN0IG5vdCBiZSBhIHt2YWx1ZSBjb25zdHJhaW50fS4KLSAgICAgICAgaWYgKGF0dERlZmF1bHQgIT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKGF0dHJUeXBlLmlzSURUeXBlKCkgKSB7Ci0gICAgICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IgKCJhLXByb3BzLWNvcnJlY3QuMyIsIG5ldyBPYmplY3RbXXtuYW1lQXR0fSwgYXR0ckRlY2wpOwotICAgICAgICAgICAgICAgIC8vIFJlY292ZXIgYnkgcmVtb3ZpbmcgdGhlIGRlZmF1bHQgdmFsdWUKLSAgICAgICAgICAgICAgICBhdHREZWZhdWx0ID0gbnVsbDsKLSAgICAgICAgICAgICAgICBjb25zdHJhaW50VHlwZSA9IFhTQ29uc3RhbnRzLlZDX05PTkU7Ci0gICAgICAgICAgICAgICAgYXR0cmlidXRlLnNldFZhbHVlcyhuYW1lQXR0LCB0bnNBdHQsIGF0dHJUeXBlLCBjb25zdHJhaW50VHlwZSwgc2NvcGUsCi0gICAgICAgICAgICAgICAgICAgICAgICBhdHREZWZhdWx0LCBlbmNsQ1QsIGFubm90YXRpb25zKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIG5vLXhtbG5zCi0KLSAgICAgICAgLy8gVGhlIHtuYW1lfSBvZiBhbiBhdHRyaWJ1dGUgZGVjbGFyYXRpb24gbXVzdCBub3QgbWF0Y2ggeG1sbnMuCi0gICAgICAgIGlmIChuYW1lQXR0ICE9IG51bGwgJiYgbmFtZUF0dC5lcXVhbHMoWE1MU3ltYm9scy5QUkVGSVhfWE1MTlMpKSB7Ci0gICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcigibm8teG1sbnMiLCBudWxsLCBhdHRyRGVjbCk7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIG5vLXhzaQotCi0gICAgICAgIC8vIFRoZSB7dGFyZ2V0IG5hbWVzcGFjZX0gb2YgYW4gYXR0cmlidXRlIGRlY2xhcmF0aW9uLCB3aGV0aGVyIGxvY2FsIG9yIHRvcC1sZXZlbCwgbXVzdCBub3QgbWF0Y2ggaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UgKHVubGVzcyBpdCBpcyBvbmUgb2YgdGhlIGZvdXIgYnVpbHQtaW4gZGVjbGFyYXRpb25zIGdpdmVuIGluIHRoZSBuZXh0IHNlY3Rpb24pLgotICAgICAgICBpZiAodG5zQXR0ICE9IG51bGwgJiYgdG5zQXR0LmVxdWFscyhTY2hlbWFTeW1ib2xzLlVSSV9YU0kpKSB7Ci0gICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcigibm8teHNpIiwgbmV3IE9iamVjdFtde1NjaGVtYVN5bWJvbHMuVVJJX1hTSX0sIGF0dHJEZWNsKTsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gQXR0cmlidXRlIHdpdGhvdXQgYSBuYW1lLiBSZXR1cm4gbnVsbC4KLSAgICAgICAgaWYgKG5hbWVBdHQuZXF1YWxzKE5PX05BTUUpKQotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0KLSAgICAgICAgLy8gU3RlcCAyOiByZWdpc3RlciBhdHRyaWJ1dGUgZGVjbCB0byB0aGUgZ3JhbW1hcgotICAgICAgICBpZiAoaXNHbG9iYWwpIHsKLSAgICAgICAgICAgIGlmIChncmFtbWFyLmdldEdsb2JhbEF0dHJpYnV0ZURlY2wobmFtZUF0dCkgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGdyYW1tYXIuYWRkR2xvYmFsQXR0cmlidXRlRGVjbChhdHRyaWJ1dGUpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBhbHNvIGFkZCBpdCB0byBleHRlbmRlZCBtYXAKLSAgICAgICAgICAgIGZpbmFsIFN0cmluZyBsb2MgPSBmU2NoZW1hSGFuZGxlci5zY2hlbWFEb2N1bWVudDJTeXN0ZW1JZChzY2hlbWFEb2MpOwotICAgICAgICAgICAgZmluYWwgWFNBdHRyaWJ1dGVEZWNsIGF0dHJpYnV0ZTIgPSBncmFtbWFyLmdldEdsb2JhbEF0dHJpYnV0ZURlY2wobmFtZUF0dCwgbG9jKTsKLSAgICAgICAgICAgIGlmIChhdHRyaWJ1dGUyICA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZ3JhbW1hci5hZGRHbG9iYWxBdHRyaWJ1dGVEZWNsKGF0dHJpYnV0ZSwgbG9jKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKGZTY2hlbWFIYW5kbGVyLmZUb2xlcmF0ZUR1cGxpY2F0ZXMpIHsKLSAgICAgICAgICAgICAgICBpZiAoYXR0cmlidXRlMiAgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGUgPSBhdHRyaWJ1dGUyOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBmU2NoZW1hSGFuZGxlci5hZGRHbG9iYWxBdHRyaWJ1dGVEZWNsKGF0dHJpYnV0ZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gYXR0cmlidXRlOwotICAgIH0KLQotICAgIC8vIHRocm93cyBhbiBlcnJvciBpZiB0aGUgY29uc3RyYWludCB2YWx1ZSBpcyBpbnZhbGlkIGZvciB0aGUgZ2l2ZW4gdHlwZQotICAgIHZvaWQgY2hlY2tEZWZhdWx0VmFsaWQoWFNBdHRyaWJ1dGVEZWNsIGF0dHJpYnV0ZSkgdGhyb3dzIEludmFsaWREYXRhdHlwZVZhbHVlRXhjZXB0aW9uIHsKLSAgICAgICAgLy8gdmFsaWRhdGUgdGhlIG9yaWdpbmFsIGxleGljYWwgcmVwLCBhbmQgc2V0IHRoZSBhY3R1YWwgdmFsdWUKLSAgICAgICAgKChYU1NpbXBsZVR5cGUpYXR0cmlidXRlLmdldFR5cGVEZWZpbml0aW9uKCkpLnZhbGlkYXRlKGF0dHJpYnV0ZS5nZXRWYWxJbmZvKCkubm9ybWFsaXplZFZhbHVlLCBmVmFsaWRhdGlvblN0YXRlLCBhdHRyaWJ1dGUuZ2V0VmFsSW5mbygpKTsKLSAgICAgICAgLy8gdmFsaWRhdGUgdGhlIGNhbm9uaWNhbCBsZXhpY2FsIHJlcAotICAgICAgICAoKFhTU2ltcGxlVHlwZSlhdHRyaWJ1dGUuZ2V0VHlwZURlZmluaXRpb24oKSkudmFsaWRhdGUoYXR0cmlidXRlLmdldFZhbEluZm8oKS5zdHJpbmdWYWx1ZSgpLCBmVmFsaWRhdGlvblN0YXRlLCBhdHRyaWJ1dGUuZ2V0VmFsSW5mbygpKTsKLSAgICB9Ci0KLSAgICAvLyB0aHJvd3MgYW4gZXJyb3IgaWYgdGhlIGNvbnN0cmFpbnQgdmFsdWUgaXMgaW52YWxpZCBmb3IgdGhlIGdpdmVuIHR5cGUKLSAgICB2b2lkIGNoZWNrRGVmYXVsdFZhbGlkKFhTQXR0cmlidXRlVXNlSW1wbCBhdHRyVXNlKSB0aHJvd3MgSW52YWxpZERhdGF0eXBlVmFsdWVFeGNlcHRpb24gewotICAgICAgICAvLyB2YWxpZGF0ZSB0aGUgb3JpZ2luYWwgbGV4aWNhbCByZXAsIGFuZCBzZXQgdGhlIGFjdHVhbCB2YWx1ZQotICAgICAgICAoKFhTU2ltcGxlVHlwZSlhdHRyVXNlLmZBdHRyRGVjbC5nZXRUeXBlRGVmaW5pdGlvbigpKS52YWxpZGF0ZShhdHRyVXNlLmZEZWZhdWx0Lm5vcm1hbGl6ZWRWYWx1ZSwgZlZhbGlkYXRpb25TdGF0ZSwgYXR0clVzZS5mRGVmYXVsdCk7Ci0gICAgICAgIC8vIHZhbGlkYXRlIHRoZSBjYW5vbmljYWwgbGV4aWNhbCByZXAKLSAgICAgICAgKChYU1NpbXBsZVR5cGUpYXR0clVzZS5mQXR0ckRlY2wuZ2V0VHlwZURlZmluaXRpb24oKSkudmFsaWRhdGUoYXR0clVzZS5mRGVmYXVsdC5zdHJpbmdWYWx1ZSgpLCBmVmFsaWRhdGlvblN0YXRlLCBhdHRyVXNlLmZEZWZhdWx0KTsKLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvdHJhdmVyc2Vycy9YU0RDb21wbGV4VHlwZVRyYXZlcnNlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy90cmF2ZXJzZXJzL1hTRENvbXBsZXhUeXBlVHJhdmVyc2VyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGNmYzk4YjguLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy90cmF2ZXJzZXJzL1hTRENvbXBsZXhUeXBlVHJhdmVyc2VyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMjU5ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy50cmF2ZXJzZXJzOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LkludmFsaWREYXRhdHlwZUZhY2V0RXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5TY2hlbWFEVkZhY3Rvcnk7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LlhTRmFjZXRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5YU1NpbXBsZVR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LnhzLlhTU2ltcGxlVHlwZURlY2w7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlNjaGVtYUdyYW1tYXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlNjaGVtYVN5bWJvbHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlhTQW5ub3RhdGlvbkltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlhTQXR0cmlidXRlR3JvdXBEZWNsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5YU0F0dHJpYnV0ZVVzZUltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlhTQ29tcGxleFR5cGVEZWNsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5YU0NvbnN0cmFpbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5YU01vZGVsR3JvdXBJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5YU1BhcnRpY2xlRGVjbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMuWFNXaWxkY2FyZERlY2w7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLnV0aWwuWEludDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMudXRpbC5YU09iamVjdExpc3RJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5ET01VdGlsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlFOYW1lOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNBdHRyaWJ1dGVVc2U7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU0NvbnN0YW50czsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTT2JqZWN0TGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTVHlwZURlZmluaXRpb247Ci1pbXBvcnQgb3JnLnczYy5kb20uRWxlbWVudDsKLQotLyoqCi0gKiBBIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uIHNjaGVtYSBjb21wb25lbnQgdHJhdmVyc2VyLgotICoKLSAqIDxjb21wbGV4VHlwZQotICogICBhYnN0cmFjdCA9IGJvb2xlYW4gOiBmYWxzZQotICogICBibG9jayA9ICgjYWxsIHwgTGlzdCBvZiAoZXh0ZW5zaW9uIHwgcmVzdHJpY3Rpb24pKQotICogICBmaW5hbCA9ICgjYWxsIHwgTGlzdCBvZiAoZXh0ZW5zaW9uIHwgcmVzdHJpY3Rpb24pKQotICogICBpZCA9IElECi0gKiAgIG1peGVkID0gYm9vbGVhbiA6IGZhbHNlCi0gKiAgIG5hbWUgPSBOQ05hbWUKLSAqICAge2FueSBhdHRyaWJ1dGVzIHdpdGggbm9uLXNjaGVtYSBuYW1lc3BhY2UgLiAuIC59PgotICogICBDb250ZW50OiAoYW5ub3RhdGlvbj8sIChzaW1wbGVDb250ZW50IHwgY29tcGxleENvbnRlbnQgfAotICogICAgICAgICAgICAoKGdyb3VwIHwgYWxsIHwgY2hvaWNlIHwgc2VxdWVuY2UpPywKLSAqICAgICAgICAgICAgKChhdHRyaWJ1dGUgfCBhdHRyaWJ1dGVHcm91cCkqLCBhbnlBdHRyaWJ1dGU/KSkpKQotICogPC9jb21wbGV4VHlwZT4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQHZlcnNpb24gJElkOiBYU0RDb21wbGV4VHlwZVRyYXZlcnNlci5qYXZhLHYgMS44IDIwMTAtMTEtMDEgMDQ6NDA6MDIgam9laHcgRXhwICQKLSAqLwotCi1jbGFzcyAgWFNEQ29tcGxleFR5cGVUcmF2ZXJzZXIgZXh0ZW5kcyBYU0RBYnN0cmFjdFBhcnRpY2xlVHJhdmVyc2VyIHsKLQotICAgIC8vIHNpemUgb2Ygc3RhY2sgdG8gaG9sZCBnbG9iYWxzOgotICAgIHByaXZhdGUgZmluYWwgc3RhdGljIGludCBHTE9CQUxfTlVNID0gMTE7Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBYU1BhcnRpY2xlRGVjbCBmRXJyb3JDb250ZW50ID0gbnVsbDsKLSAgICBwcml2YXRlIHN0YXRpYyBYU1dpbGRjYXJkRGVjbCBmRXJyb3JXaWxkY2FyZCA9IG51bGw7Ci0gICAgcHJpdmF0ZSBzdGF0aWMgWFNQYXJ0aWNsZURlY2wgZ2V0RXJyb3JDb250ZW50KCkgewotICAgICAgICBpZiAoZkVycm9yQ29udGVudCA9PSBudWxsKSB7Ci0gICAgICAgICAgICBYU1BhcnRpY2xlRGVjbCBwYXJ0aWNsZSA9IG5ldyBYU1BhcnRpY2xlRGVjbCgpOwotICAgICAgICAgICAgcGFydGljbGUuZlR5cGUgPSBYU1BhcnRpY2xlRGVjbC5QQVJUSUNMRV9XSUxEQ0FSRDsKLSAgICAgICAgICAgIHBhcnRpY2xlLmZWYWx1ZSA9IGdldEVycm9yV2lsZGNhcmQoKTsKLSAgICAgICAgICAgIHBhcnRpY2xlLmZNaW5PY2N1cnMgPSAwOwotICAgICAgICAgICAgcGFydGljbGUuZk1heE9jY3VycyA9IFNjaGVtYVN5bWJvbHMuT0NDVVJSRU5DRV9VTkJPVU5ERUQ7Ci0gICAgICAgICAgICBYU01vZGVsR3JvdXBJbXBsIGdyb3VwID0gbmV3IFhTTW9kZWxHcm91cEltcGwoKTsKLSAgICAgICAgICAgIGdyb3VwLmZDb21wb3NpdG9yID0gWFNNb2RlbEdyb3VwSW1wbC5NT0RFTEdST1VQX1NFUVVFTkNFOwotICAgICAgICAgICAgZ3JvdXAuZlBhcnRpY2xlQ291bnQgPSAxOwotICAgICAgICAgICAgZ3JvdXAuZlBhcnRpY2xlcyA9IG5ldyBYU1BhcnRpY2xlRGVjbFsxXTsKLSAgICAgICAgICAgIGdyb3VwLmZQYXJ0aWNsZXNbMF0gPSBwYXJ0aWNsZTsKLSAgICAgICAgICAgIFhTUGFydGljbGVEZWNsIGVycm9yQ29udGVudCA9IG5ldyBYU1BhcnRpY2xlRGVjbCgpOwotICAgICAgICAgICAgZXJyb3JDb250ZW50LmZUeXBlID0gWFNQYXJ0aWNsZURlY2wuUEFSVElDTEVfTU9ERUxHUk9VUDsKLSAgICAgICAgICAgIGVycm9yQ29udGVudC5mVmFsdWUgPSBncm91cDsKLSAgICAgICAgICAgIGZFcnJvckNvbnRlbnQgPSBlcnJvckNvbnRlbnQ7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGZFcnJvckNvbnRlbnQ7Ci0gICAgfQotICAgIHByaXZhdGUgc3RhdGljIFhTV2lsZGNhcmREZWNsIGdldEVycm9yV2lsZGNhcmQoKSB7Ci0gICAgICAgIGlmIChmRXJyb3JXaWxkY2FyZCA9PSBudWxsKSB7Ci0gICAgICAgICAgICBYU1dpbGRjYXJkRGVjbCB3aWxkY2FyZCA9IG5ldyBYU1dpbGRjYXJkRGVjbCgpOwotICAgICAgICAgICAgd2lsZGNhcmQuZlByb2Nlc3NDb250ZW50cyA9IFhTV2lsZGNhcmREZWNsLlBDX1NLSVA7Ci0gICAgICAgICAgICBmRXJyb3JXaWxkY2FyZCA9IHdpbGRjYXJkOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmRXJyb3JXaWxkY2FyZDsKLSAgICB9Ci0KLSAgICAvLyBnbG9iYWxzIGZvciBidWlsZGluZyBYU0NvbXBsZXhUeXBlRGVjbHMKLSAgICBwcml2YXRlIFN0cmluZyBmTmFtZSA9IG51bGw7Ci0gICAgcHJpdmF0ZSBTdHJpbmcgZlRhcmdldE5hbWVzcGFjZSA9IG51bGw7Ci0gICAgcHJpdmF0ZSBzaG9ydCBmRGVyaXZlZEJ5ID0gWFNDb25zdGFudHMuREVSSVZBVElPTl9SRVNUUklDVElPTjsKLSAgICBwcml2YXRlIHNob3J0IGZGaW5hbCA9IFhTQ29uc3RhbnRzLkRFUklWQVRJT05fTk9ORTsKLSAgICBwcml2YXRlIHNob3J0IGZCbG9jayA9IFhTQ29uc3RhbnRzLkRFUklWQVRJT05fTk9ORTsKLSAgICBwcml2YXRlIHNob3J0IGZDb250ZW50VHlwZSA9IFhTQ29tcGxleFR5cGVEZWNsLkNPTlRFTlRUWVBFX0VNUFRZOwotICAgIHByaXZhdGUgWFNUeXBlRGVmaW5pdGlvbiBmQmFzZVR5cGUgPSBudWxsOwotICAgIHByaXZhdGUgWFNBdHRyaWJ1dGVHcm91cERlY2wgZkF0dHJHcnAgPSBudWxsOwotICAgIHByaXZhdGUgWFNTaW1wbGVUeXBlIGZYU1NpbXBsZVR5cGUgPSBudWxsOwotICAgIHByaXZhdGUgWFNQYXJ0aWNsZURlY2wgZlBhcnRpY2xlID0gbnVsbDsKLSAgICBwcml2YXRlIGJvb2xlYW4gZklzQWJzdHJhY3QgPSBmYWxzZTsKLSAgICBwcml2YXRlIFhTQ29tcGxleFR5cGVEZWNsIGZDb21wbGV4VHlwZURlY2wgPSBudWxsOwotICAgIHByaXZhdGUgWFNBbm5vdGF0aW9uSW1wbCBbXSBmQW5ub3RhdGlvbnMgPSBudWxsOwotCi0gICAgLy8gb3VyIG93biBsaXR0bGUgc3RhY2sgdG8gcmV0YWluIHN0YXRlIHdoZW4gZ2V0R2xvYmFsRGVjbHMgaXMgY2FsbGVkOgotICAgIHByaXZhdGUgT2JqZWN0IFtdIGZHbG9iYWxTdG9yZSA9IG51bGw7Ci0gICAgcHJpdmF0ZSBpbnQgZkdsb2JhbFN0b3JlUG9zID0gMDsKLQotICAgIFhTRENvbXBsZXhUeXBlVHJhdmVyc2VyIChYU0RIYW5kbGVyIGhhbmRsZXIsCi0gICAgICAgICAgICBYU0F0dHJpYnV0ZUNoZWNrZXIgZ0F0dHJDaGVjaykgewotICAgICAgICBzdXBlcihoYW5kbGVyLCBnQXR0ckNoZWNrKTsKLSAgICB9Ci0KLQotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW4gREVCVUc9ZmFsc2U7Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBDb21wbGV4VHlwZVJlY292ZXJhYmxlRXJyb3IgZXh0ZW5kcyBFeGNlcHRpb24gewotCi0gICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDY4MDI3Mjk5MTIwOTExMzAzMzVMOwotCi0gICAgICAgIE9iamVjdFtdIGVycm9yU3Vic3RUZXh0PW51bGw7Ci0gICAgICAgIEVsZW1lbnQgIGVycm9yRWxlbSA9IG51bGw7Ci0gICAgICAgIENvbXBsZXhUeXBlUmVjb3ZlcmFibGVFcnJvcigpIHsKLSAgICAgICAgICAgIHN1cGVyKCk7Ci0gICAgICAgIH0KLSAgICAgICAgQ29tcGxleFR5cGVSZWNvdmVyYWJsZUVycm9yKFN0cmluZyBtc2dLZXksIE9iamVjdFtdIGFyZ3MsIEVsZW1lbnQgZSkgewotICAgICAgICAgICAgc3VwZXIobXNnS2V5KTsKLSAgICAgICAgICAgIGVycm9yU3Vic3RUZXh0PWFyZ3M7Ci0gICAgICAgICAgICBlcnJvckVsZW0gPSBlOwotICAgICAgICB9Ci0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmF2ZXJzZSBsb2NhbCBjb21wbGV4VHlwZSBkZWNsYXJhdGlvbnMKLSAgICAgKgotICAgICAqIEBwYXJhbSBFbGVtZW50Ci0gICAgICogQHBhcmFtIFhTRG9jdW1lbnRJbmZvCi0gICAgICogQHBhcmFtIFNjaGVtYUdyYW1tYXIKLSAgICAgKiBAcmV0dXJuIFhTQ29tcGxleFR5cGVEZWNsCi0gICAgICovCi0gICAgWFNDb21wbGV4VHlwZURlY2wgdHJhdmVyc2VMb2NhbChFbGVtZW50IGNvbXBsZXhUeXBlTm9kZSwKLSAgICAgICAgICAgIFhTRG9jdW1lbnRJbmZvIHNjaGVtYURvYywKLSAgICAgICAgICAgIFNjaGVtYUdyYW1tYXIgZ3JhbW1hcikgewotCi0KLSAgICAgICAgT2JqZWN0W10gYXR0clZhbHVlcyA9IGZBdHRyQ2hlY2tlci5jaGVja0F0dHJpYnV0ZXMoY29tcGxleFR5cGVOb2RlLCBmYWxzZSwKLSAgICAgICAgICAgICAgICBzY2hlbWFEb2MpOwotICAgICAgICBTdHJpbmcgY29tcGxleFR5cGVOYW1lID0gZ2VuQW5vblR5cGVOYW1lKGNvbXBsZXhUeXBlTm9kZSk7Ci0gICAgICAgIGNvbnRlbnRCYWNrdXAoKTsKLSAgICAgICAgWFNDb21wbGV4VHlwZURlY2wgdHlwZSA9IHRyYXZlcnNlQ29tcGxleFR5cGVEZWNsIChjb21wbGV4VHlwZU5vZGUsCi0gICAgICAgICAgICAgICAgY29tcGxleFR5cGVOYW1lLCBhdHRyVmFsdWVzLCBzY2hlbWFEb2MsIGdyYW1tYXIpOwotICAgICAgICBjb250ZW50UmVzdG9yZSgpOwotICAgICAgICAvLyBuZWVkIHRvIGFkZCB0aGUgdHlwZSB0byB0aGUgZ3JhbW1hciBmb3IgbGF0ZXIgY29uc3RyYWludCBjaGVja2luZwotICAgICAgICBncmFtbWFyLmFkZENvbXBsZXhUeXBlRGVjbCh0eXBlLCBmU2NoZW1hSGFuZGxlci5lbGVtZW50MkxvY2F0b3IoY29tcGxleFR5cGVOb2RlKSk7Ci0gICAgICAgIHR5cGUuc2V0SXNBbm9ueW1vdXMoKTsKLSAgICAgICAgZkF0dHJDaGVja2VyLnJldHVybkF0dHJBcnJheShhdHRyVmFsdWVzLCBzY2hlbWFEb2MpOwotCi0gICAgICAgIHJldHVybiB0eXBlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYXZlcnNlIGdsb2JhbCBjb21wbGV4VHlwZSBkZWNsYXJhdGlvbnMKLSAgICAgKgotICAgICAqIEBwYXJhbSBFbGVtZW50Ci0gICAgICogQHBhcmFtIFhTRG9jdW1lbnRJbmZvCi0gICAgICogQHBhcmFtIFNjaGVtYUdyYW1tYXIKLSAgICAgKiBAcmV0dXJuIFhTQ29tcGxleFR5cGVEZWNYU0NvbXBsZXhUeXBlRGVjbAotICAgICAqLwotICAgIFhTQ29tcGxleFR5cGVEZWNsIHRyYXZlcnNlR2xvYmFsIChFbGVtZW50IGNvbXBsZXhUeXBlTm9kZSwKLSAgICAgICAgICAgIFhTRG9jdW1lbnRJbmZvIHNjaGVtYURvYywKLSAgICAgICAgICAgIFNjaGVtYUdyYW1tYXIgZ3JhbW1hcikgewotCi0gICAgICAgIE9iamVjdFtdIGF0dHJWYWx1ZXMgPSBmQXR0ckNoZWNrZXIuY2hlY2tBdHRyaWJ1dGVzKGNvbXBsZXhUeXBlTm9kZSwgdHJ1ZSwKLSAgICAgICAgICAgICAgICBzY2hlbWFEb2MpOwotICAgICAgICBTdHJpbmcgY29tcGxleFR5cGVOYW1lID0gKFN0cmluZykgIGF0dHJWYWx1ZXNbWFNBdHRyaWJ1dGVDaGVja2VyLkFUVElEWF9OQU1FXTsKLSAgICAgICAgY29udGVudEJhY2t1cCgpOwotICAgICAgICBYU0NvbXBsZXhUeXBlRGVjbCB0eXBlID0gdHJhdmVyc2VDb21wbGV4VHlwZURlY2wgKGNvbXBsZXhUeXBlTm9kZSwKLSAgICAgICAgICAgICAgICBjb21wbGV4VHlwZU5hbWUsIGF0dHJWYWx1ZXMsIHNjaGVtYURvYywgZ3JhbW1hcik7Ci0gICAgICAgIGNvbnRlbnRSZXN0b3JlKCk7Ci0gICAgICAgIC8vIG5lZWQgdG8gYWRkIHRoZSB0eXBlIHRvIHRoZSBncmFtbWFyIGZvciBsYXRlciBjb25zdHJhaW50IGNoZWNraW5nCi0gICAgICAgIGdyYW1tYXIuYWRkQ29tcGxleFR5cGVEZWNsKHR5cGUsIGZTY2hlbWFIYW5kbGVyLmVsZW1lbnQyTG9jYXRvcihjb21wbGV4VHlwZU5vZGUpKTsKLQotICAgICAgICBpZiAoY29tcGxleFR5cGVOYW1lID09IG51bGwpIHsKLSAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKCJzNHMtYXR0LW11c3QtYXBwZWFyIiwgbmV3IE9iamVjdFtde1NjaGVtYVN5bWJvbHMuRUxUX0NPTVBMRVhUWVBFLCBTY2hlbWFTeW1ib2xzLkFUVF9OQU1FfSwgY29tcGxleFR5cGVOb2RlKTsKLSAgICAgICAgICAgIHR5cGUgPSBudWxsOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgaWYgKGdyYW1tYXIuZ2V0R2xvYmFsVHlwZURlY2wodHlwZS5nZXROYW1lKCkpID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBncmFtbWFyLmFkZEdsb2JhbENvbXBsZXhUeXBlRGVjbCh0eXBlKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gYWxzbyBhZGQgaXQgdG8gZXh0ZW5kZWQgbWFwCi0gICAgICAgICAgICBmaW5hbCBTdHJpbmcgbG9jID0gZlNjaGVtYUhhbmRsZXIuc2NoZW1hRG9jdW1lbnQyU3lzdGVtSWQoc2NoZW1hRG9jKTsKLSAgICAgICAgICAgIGZpbmFsIFhTVHlwZURlZmluaXRpb24gdHlwZTIgPSBncmFtbWFyLmdldEdsb2JhbFR5cGVEZWNsKHR5cGUuZ2V0TmFtZSgpLCBsb2MpOwotICAgICAgICAgICAgaWYgKHR5cGUyID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBncmFtbWFyLmFkZEdsb2JhbENvbXBsZXhUeXBlRGVjbCh0eXBlLCBsb2MpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBoYW5kbGUgZHVwbGljYXRlcwotICAgICAgICAgICAgaWYgKGZTY2hlbWFIYW5kbGVyLmZUb2xlcmF0ZUR1cGxpY2F0ZXMpIHsKLSAgICAgICAgICAgICAgICBpZiAodHlwZTIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBpZiAodHlwZTIgaW5zdGFuY2VvZiBYU0NvbXBsZXhUeXBlRGVjbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgdHlwZSA9IChYU0NvbXBsZXhUeXBlRGVjbCkgdHlwZTI7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZlNjaGVtYUhhbmRsZXIuYWRkR2xvYmFsVHlwZURlY2wodHlwZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBmQXR0ckNoZWNrZXIucmV0dXJuQXR0ckFycmF5KGF0dHJWYWx1ZXMsIHNjaGVtYURvYyk7Ci0KLSAgICAgICAgcmV0dXJuIHR5cGU7Ci0gICAgfQotCi0KLSAgICBwcml2YXRlIFhTQ29tcGxleFR5cGVEZWNsIHRyYXZlcnNlQ29tcGxleFR5cGVEZWNsKEVsZW1lbnQgY29tcGxleFR5cGVEZWNsLAotICAgICAgICAgICAgU3RyaW5nIGNvbXBsZXhUeXBlTmFtZSwKLSAgICAgICAgICAgIE9iamVjdFtdIGF0dHJWYWx1ZXMsCi0gICAgICAgICAgICBYU0RvY3VtZW50SW5mbyBzY2hlbWFEb2MsCi0gICAgICAgICAgICBTY2hlbWFHcmFtbWFyIGdyYW1tYXIpIHsKLQotICAgICAgICBmQ29tcGxleFR5cGVEZWNsID0gbmV3IFhTQ29tcGxleFR5cGVEZWNsKCk7Ci0gICAgICAgIGZBdHRyR3JwID0gbmV3IFhTQXR0cmlidXRlR3JvdXBEZWNsKCk7Ci0gICAgICAgIEJvb2xlYW4gYWJzdHJhY3RBdHQgID0gKEJvb2xlYW4pIGF0dHJWYWx1ZXNbWFNBdHRyaWJ1dGVDaGVja2VyLkFUVElEWF9BQlNUUkFDVF07Ci0gICAgICAgIFhJbnQgICAgYmxvY2tBdHQgICAgID0gKFhJbnQpICAgIGF0dHJWYWx1ZXNbWFNBdHRyaWJ1dGVDaGVja2VyLkFUVElEWF9CTE9DS107Ci0gICAgICAgIEJvb2xlYW4gbWl4ZWRBdHQgICAgID0gKEJvb2xlYW4pIGF0dHJWYWx1ZXNbWFNBdHRyaWJ1dGVDaGVja2VyLkFUVElEWF9NSVhFRF07Ci0gICAgICAgIFhJbnQgICAgZmluYWxBdHQgICAgID0gKFhJbnQpICAgIGF0dHJWYWx1ZXNbWFNBdHRyaWJ1dGVDaGVja2VyLkFUVElEWF9GSU5BTF07Ci0KLSAgICAgICAgZk5hbWUgPSBjb21wbGV4VHlwZU5hbWU7Ci0gICAgICAgIGZDb21wbGV4VHlwZURlY2wuc2V0TmFtZShmTmFtZSk7Ci0gICAgICAgIGZUYXJnZXROYW1lc3BhY2UgPSBzY2hlbWFEb2MuZlRhcmdldE5hbWVzcGFjZTsKLQotICAgICAgICBmQmxvY2sgPSBibG9ja0F0dCA9PSBudWxsID8gc2NoZW1hRG9jLmZCbG9ja0RlZmF1bHQgOiBibG9ja0F0dC5zaG9ydFZhbHVlKCk7Ci0gICAgICAgIGZGaW5hbCA9IGZpbmFsQXR0ID09IG51bGwgPyBzY2hlbWFEb2MuZkZpbmFsRGVmYXVsdCA6IGZpbmFsQXR0LnNob3J0VmFsdWUoKTsKLSAgICAgICAgLy9kaXNjYXJkIHZhbGlkIEJsb2NrL0ZpbmFsICdEZWZhdWx0JyB2YWx1ZXMgdGhhdCBhcmUgaW52YWxpZCBmb3IgQmxvY2svRmluYWwKLSAgICAgICAgZkJsb2NrICY9IChYU0NvbnN0YW50cy5ERVJJVkFUSU9OX0VYVEVOU0lPTiB8IFhTQ29uc3RhbnRzLkRFUklWQVRJT05fUkVTVFJJQ1RJT04pOwotICAgICAgICBmRmluYWwgJj0gKFhTQ29uc3RhbnRzLkRFUklWQVRJT05fRVhURU5TSU9OIHwgWFNDb25zdGFudHMuREVSSVZBVElPTl9SRVNUUklDVElPTik7Ci0KLSAgICAgICAgZklzQWJzdHJhY3QgPSAoYWJzdHJhY3RBdHQgIT0gbnVsbCAmJiBhYnN0cmFjdEF0dC5ib29sZWFuVmFsdWUoKSk7Ci0gICAgICAgIGZBbm5vdGF0aW9ucyA9IG51bGw7Ci0KLSAgICAgICAgRWxlbWVudCBjaGlsZCA9IG51bGw7Ci0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgICAgICAgICAgLy8gRmlyc3QsIGhhbmRsZSBhbnkgQU5OT1RBVElPTiBkZWNsYXJhdGlvbiBhbmQgZ2V0IG5leHQgY2hpbGQKLSAgICAgICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgICAgICAgICAgY2hpbGQgPSBET01VdGlsLmdldEZpcnN0Q2hpbGRFbGVtZW50KGNvbXBsZXhUeXBlRGVjbCk7Ci0gICAgICAgICAgICBpZihjaGlsZCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgaWYgKERPTVV0aWwuZ2V0TG9jYWxOYW1lKGNoaWxkKS5lcXVhbHMoU2NoZW1hU3ltYm9scy5FTFRfQU5OT1RBVElPTikpIHsKLSAgICAgICAgICAgICAgICAgICAgYWRkQW5ub3RhdGlvbih0cmF2ZXJzZUFubm90YXRpb25EZWNsKGNoaWxkLCBhdHRyVmFsdWVzLCBmYWxzZSwgc2NoZW1hRG9jKSk7Ci0gICAgICAgICAgICAgICAgICAgIGNoaWxkID0gRE9NVXRpbC5nZXROZXh0U2libGluZ0VsZW1lbnQoY2hpbGQpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHRleHQgPSBET01VdGlsLmdldFN5bnRoZXRpY0Fubm90YXRpb24oY29tcGxleFR5cGVEZWNsKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKHRleHQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgYWRkQW5ub3RhdGlvbih0cmF2ZXJzZVN5bnRoZXRpY0Fubm90YXRpb24oY29tcGxleFR5cGVEZWNsLCB0ZXh0LCBhdHRyVmFsdWVzLCBmYWxzZSwgc2NoZW1hRG9jKSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaWYgKGNoaWxkICE9bnVsbCAmJiBET01VdGlsLmdldExvY2FsTmFtZShjaGlsZCkuZXF1YWxzKFNjaGVtYVN5bWJvbHMuRUxUX0FOTk9UQVRJT04pKSB7Ci0gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBDb21wbGV4VHlwZVJlY292ZXJhYmxlRXJyb3IoInM0cy1lbHQtaW52YWxpZC1jb250ZW50LjEiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXtmTmFtZSxTY2hlbWFTeW1ib2xzLkVMVF9BTk5PVEFUSU9OfSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIHRleHQgPSBET01VdGlsLmdldFN5bnRoZXRpY0Fubm90YXRpb24oY29tcGxleFR5cGVEZWNsKTsKLSAgICAgICAgICAgICAgICBpZiAodGV4dCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGFkZEFubm90YXRpb24odHJhdmVyc2VTeW50aGV0aWNBbm5vdGF0aW9uKGNvbXBsZXhUeXBlRGVjbCwgdGV4dCwgYXR0clZhbHVlcywgZmFsc2UsIHNjaGVtYURvYykpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgICAgICAgICAgLy8gUHJvY2VzcyB0aGUgY29udGVudCBvZiB0aGUgY29tcGxleCB0eXBlIGRlZmluaXRpb24KLSAgICAgICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgICAgICAgICAgaWYgKGNoaWxkPT1udWxsKSB7Ci0gICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICAvLyBFTVBUWSBjb21wbGV4VHlwZSB3aXRoIGNvbXBsZXhDb250ZW50Ci0gICAgICAgICAgICAgICAgLy8KLQotICAgICAgICAgICAgICAgIC8vIHNldCB0aGUgYmFzZSB0byB0aGUgYW55VHlwZQotICAgICAgICAgICAgICAgIGZCYXNlVHlwZSA9IFNjaGVtYUdyYW1tYXIuZkFueVR5cGU7Ci0gICAgICAgICAgICAgICAgZkRlcml2ZWRCeSA9IFhTQ29uc3RhbnRzLkRFUklWQVRJT05fUkVTVFJJQ1RJT047Ci0gICAgICAgICAgICAgICAgcHJvY2Vzc0NvbXBsZXhDb250ZW50KGNoaWxkLCBtaXhlZEF0dC5ib29sZWFuVmFsdWUoKSwgZmFsc2UsCi0gICAgICAgICAgICAgICAgICAgICAgICBzY2hlbWFEb2MsIGdyYW1tYXIpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoRE9NVXRpbC5nZXRMb2NhbE5hbWUoY2hpbGQpLmVxdWFscwotICAgICAgICAgICAgICAgICAgICAoU2NoZW1hU3ltYm9scy5FTFRfU0lNUExFQ09OVEVOVCkpIHsKLSAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgIC8vIFNJTVBMRSBDT05URU5UCi0gICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICB0cmF2ZXJzZVNpbXBsZUNvbnRlbnQoY2hpbGQsIHNjaGVtYURvYywgZ3JhbW1hcik7Ci0gICAgICAgICAgICAgICAgRWxlbWVudCBlbGVtVG1wID0gRE9NVXRpbC5nZXROZXh0U2libGluZ0VsZW1lbnQoY2hpbGQpOwotICAgICAgICAgICAgICAgIGlmIChlbGVtVG1wICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHNpYmxpbmdOYW1lID0gRE9NVXRpbC5nZXRMb2NhbE5hbWUoZWxlbVRtcCk7Ci0gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBDb21wbGV4VHlwZVJlY292ZXJhYmxlRXJyb3IoInM0cy1lbHQtaW52YWxpZC1jb250ZW50LjEiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXtmTmFtZSxzaWJsaW5nTmFtZX0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbVRtcCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoRE9NVXRpbC5nZXRMb2NhbE5hbWUoY2hpbGQpLmVxdWFscwotICAgICAgICAgICAgICAgICAgICAoU2NoZW1hU3ltYm9scy5FTFRfQ09NUExFWENPTlRFTlQpKSB7Ci0gICAgICAgICAgICAgICAgdHJhdmVyc2VDb21wbGV4Q29udGVudChjaGlsZCwgbWl4ZWRBdHQuYm9vbGVhblZhbHVlKCksCi0gICAgICAgICAgICAgICAgICAgICAgICBzY2hlbWFEb2MsIGdyYW1tYXIpOwotICAgICAgICAgICAgICAgIEVsZW1lbnQgZWxlbVRtcCA9IERPTVV0aWwuZ2V0TmV4dFNpYmxpbmdFbGVtZW50KGNoaWxkKTsKLSAgICAgICAgICAgICAgICBpZiAoZWxlbVRtcCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIFN0cmluZyBzaWJsaW5nTmFtZSA9IERPTVV0aWwuZ2V0TG9jYWxOYW1lKGVsZW1UbXApOwotICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ29tcGxleFR5cGVSZWNvdmVyYWJsZUVycm9yKCJzNHMtZWx0LWludmFsaWQtY29udGVudC4xIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117Zk5hbWUsc2libGluZ05hbWV9LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1UbXApOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAgICAgLy8gV2UgbXVzdCBoYXZlIC4uLi4KLSAgICAgICAgICAgICAgICAvLyBHUk9VUCwgQUxMLCBTRVFVRU5DRSBvciBDSE9JQ0UsIGZvbGxvd2VkIGJ5IG9wdGlvbmFsIGF0dHJpYnV0ZXMKLSAgICAgICAgICAgICAgICAvLyBOb3RlIHRoYXQgaXQncyBwb3NzaWJsZSB0aGF0IG9ubHkgYXR0cmlidXRlcyBhcmUgc3BlY2lmaWVkLgotICAgICAgICAgICAgICAgIC8vCi0KLSAgICAgICAgICAgICAgICAvLyBzZXQgdGhlIGJhc2UgdG8gdGhlIGFueVR5cGUKLSAgICAgICAgICAgICAgICBmQmFzZVR5cGUgPSBTY2hlbWFHcmFtbWFyLmZBbnlUeXBlOwotICAgICAgICAgICAgICAgIGZEZXJpdmVkQnkgPSBYU0NvbnN0YW50cy5ERVJJVkFUSU9OX1JFU1RSSUNUSU9OOwotICAgICAgICAgICAgICAgIHByb2Nlc3NDb21wbGV4Q29udGVudChjaGlsZCwgbWl4ZWRBdHQuYm9vbGVhblZhbHVlKCksIGZhbHNlLAotICAgICAgICAgICAgICAgICAgICAgICAgc2NoZW1hRG9jLCBncmFtbWFyKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChDb21wbGV4VHlwZVJlY292ZXJhYmxlRXJyb3IgZSkgewotICAgICAgICAgICAgaGFuZGxlQ29tcGxleFR5cGVFcnJvcihlLmdldE1lc3NhZ2UoKSwgZS5lcnJvclN1YnN0VGV4dCwKLSAgICAgICAgICAgICAgICAgICAgZS5lcnJvckVsZW0pOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKERFQlVHKSB7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oZk5hbWUpOwotICAgICAgICB9Ci0gICAgICAgIGZDb21wbGV4VHlwZURlY2wuc2V0VmFsdWVzKGZOYW1lLCBmVGFyZ2V0TmFtZXNwYWNlLCBmQmFzZVR5cGUsCi0gICAgICAgICAgICAgICAgZkRlcml2ZWRCeSwgZkZpbmFsLCBmQmxvY2ssIGZDb250ZW50VHlwZSwgZklzQWJzdHJhY3QsCi0gICAgICAgICAgICAgICAgZkF0dHJHcnAsIGZYU1NpbXBsZVR5cGUsIGZQYXJ0aWNsZSwgbmV3IFhTT2JqZWN0TGlzdEltcGwoZkFubm90YXRpb25zLAotICAgICAgICAgICAgICAgICAgICAgICAgZkFubm90YXRpb25zID09IG51bGw/IDAgOiBmQW5ub3RhdGlvbnMubGVuZ3RoKSk7Ci0gICAgICAgIHJldHVybiBmQ29tcGxleFR5cGVEZWNsOwotICAgIH0KLQotCi0gICAgcHJpdmF0ZSB2b2lkIHRyYXZlcnNlU2ltcGxlQ29udGVudChFbGVtZW50IHNpbXBsZUNvbnRlbnRFbGVtZW50LAotICAgICAgICAgICAgWFNEb2N1bWVudEluZm8gc2NoZW1hRG9jLAotICAgICAgICAgICAgU2NoZW1hR3JhbW1hciBncmFtbWFyKQotICAgIHRocm93cyBDb21wbGV4VHlwZVJlY292ZXJhYmxlRXJyb3IgewotCi0KLSAgICAgICAgT2JqZWN0W10gc2ltcGxlQ29udGVudEF0dHJWYWx1ZXMgPSBmQXR0ckNoZWNrZXIuY2hlY2tBdHRyaWJ1dGVzKHNpbXBsZUNvbnRlbnRFbGVtZW50LCBmYWxzZSwKLSAgICAgICAgICAgICAgICBzY2hlbWFEb2MpOwotCi0gICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgICAgIC8vIFNldCBjb250ZW50IHR5cGUKLSAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICAgICAgZkNvbnRlbnRUeXBlID0gWFNDb21wbGV4VHlwZURlY2wuQ09OVEVOVFRZUEVfU0lNUExFOwotICAgICAgICBmUGFydGljbGUgPSBudWxsOwotCi0gICAgICAgIEVsZW1lbnQgc2ltcGxlQ29udGVudCA9IERPTVV0aWwuZ2V0Rmlyc3RDaGlsZEVsZW1lbnQoc2ltcGxlQ29udGVudEVsZW1lbnQpOwotICAgICAgICBpZiAoc2ltcGxlQ29udGVudCAhPSBudWxsICYmIERPTVV0aWwuZ2V0TG9jYWxOYW1lKHNpbXBsZUNvbnRlbnQpLmVxdWFscyhTY2hlbWFTeW1ib2xzLkVMVF9BTk5PVEFUSU9OKSkgewotICAgICAgICAgICAgYWRkQW5ub3RhdGlvbih0cmF2ZXJzZUFubm90YXRpb25EZWNsKHNpbXBsZUNvbnRlbnQsIHNpbXBsZUNvbnRlbnRBdHRyVmFsdWVzLCBmYWxzZSwgc2NoZW1hRG9jKSk7Ci0gICAgICAgICAgICBzaW1wbGVDb250ZW50ID0gRE9NVXRpbC5nZXROZXh0U2libGluZ0VsZW1lbnQoc2ltcGxlQ29udGVudCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBTdHJpbmcgdGV4dCA9IERPTVV0aWwuZ2V0U3ludGhldGljQW5ub3RhdGlvbihzaW1wbGVDb250ZW50RWxlbWVudCk7Ci0gICAgICAgICAgICBpZiAodGV4dCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgYWRkQW5ub3RhdGlvbih0cmF2ZXJzZVN5bnRoZXRpY0Fubm90YXRpb24oc2ltcGxlQ29udGVudEVsZW1lbnQsIHRleHQsIHNpbXBsZUNvbnRlbnRBdHRyVmFsdWVzLCBmYWxzZSwgc2NoZW1hRG9jKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBJZiB0aGVyZSBhcmUgbm8gY2hpbGRyZW4sIHJldHVybgotICAgICAgICBpZiAoc2ltcGxlQ29udGVudD09bnVsbCkgewotICAgICAgICAgICAgZkF0dHJDaGVja2VyLnJldHVybkF0dHJBcnJheShzaW1wbGVDb250ZW50QXR0clZhbHVlcywgc2NoZW1hRG9jKTsKLSAgICAgICAgICAgIHRocm93IG5ldyBDb21wbGV4VHlwZVJlY292ZXJhYmxlRXJyb3IoInM0cy1lbHQtaW52YWxpZC1jb250ZW50LjIiLAotICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117Zk5hbWUsU2NoZW1hU3ltYm9scy5FTFRfU0lNUExFQ09OVEVOVH0sCi0gICAgICAgICAgICAgICAgICAgIHNpbXBsZUNvbnRlbnRFbGVtZW50KTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgICAgIC8vIFRoZSBjb250ZW50IHNob3VsZCBiZSBlaXRoZXIgInJlc3RyaWN0aW9uIiBvciAiZXh0ZW5zaW9uIgotICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgICAgICBTdHJpbmcgc2ltcGxlQ29udGVudE5hbWUgPSBET01VdGlsLmdldExvY2FsTmFtZShzaW1wbGVDb250ZW50KTsKLSAgICAgICAgaWYgKHNpbXBsZUNvbnRlbnROYW1lLmVxdWFscyhTY2hlbWFTeW1ib2xzLkVMVF9SRVNUUklDVElPTikpCi0gICAgICAgICAgICBmRGVyaXZlZEJ5ID0gWFNDb25zdGFudHMuREVSSVZBVElPTl9SRVNUUklDVElPTjsKLSAgICAgICAgZWxzZSBpZiAoc2ltcGxlQ29udGVudE5hbWUuZXF1YWxzKFNjaGVtYVN5bWJvbHMuRUxUX0VYVEVOU0lPTikpCi0gICAgICAgICAgICBmRGVyaXZlZEJ5ID0gWFNDb25zdGFudHMuREVSSVZBVElPTl9FWFRFTlNJT047Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgZkF0dHJDaGVja2VyLnJldHVybkF0dHJBcnJheShzaW1wbGVDb250ZW50QXR0clZhbHVlcywgc2NoZW1hRG9jKTsKLSAgICAgICAgICAgIHRocm93IG5ldyBDb21wbGV4VHlwZVJlY292ZXJhYmxlRXJyb3IoInM0cy1lbHQtaW52YWxpZC1jb250ZW50LjEiLAotICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117Zk5hbWUsc2ltcGxlQ29udGVudE5hbWV9LAotICAgICAgICAgICAgICAgICAgICBzaW1wbGVDb250ZW50KTsKLSAgICAgICAgfQotICAgICAgICBFbGVtZW50IGVsZW1UbXAgPSBET01VdGlsLmdldE5leHRTaWJsaW5nRWxlbWVudChzaW1wbGVDb250ZW50KTsKLSAgICAgICAgaWYgKGVsZW1UbXAgIT0gbnVsbCkgewotICAgICAgICAgICAgZkF0dHJDaGVja2VyLnJldHVybkF0dHJBcnJheShzaW1wbGVDb250ZW50QXR0clZhbHVlcywgc2NoZW1hRG9jKTsKLSAgICAgICAgICAgIFN0cmluZyBzaWJsaW5nTmFtZSA9IERPTVV0aWwuZ2V0TG9jYWxOYW1lKGVsZW1UbXApOwotICAgICAgICAgICAgdGhyb3cgbmV3IENvbXBsZXhUeXBlUmVjb3ZlcmFibGVFcnJvcigiczRzLWVsdC1pbnZhbGlkLWNvbnRlbnQuMSIsCi0gICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXtmTmFtZSxzaWJsaW5nTmFtZX0sCi0gICAgICAgICAgICAgICAgICAgIGVsZW1UbXApOwotICAgICAgICB9Ci0KLSAgICAgICAgT2JqZWN0IFtdIGRlcml2YXRpb25UeXBlQXR0clZhbHVlcyA9IGZBdHRyQ2hlY2tlci5jaGVja0F0dHJpYnV0ZXMoc2ltcGxlQ29udGVudCwgZmFsc2UsCi0gICAgICAgICAgICAgICAgc2NoZW1hRG9jKTsKLSAgICAgICAgUU5hbWUgYmFzZVR5cGVOYW1lID0gKFFOYW1lKSAgZGVyaXZhdGlvblR5cGVBdHRyVmFsdWVzW1hTQXR0cmlidXRlQ2hlY2tlci5BVFRJRFhfQkFTRV07Ci0KLQotICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgICAgICAvLyBOZWVkIGEgYmFzZSB0eXBlLgotICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgICAgICBpZiAoYmFzZVR5cGVOYW1lPT1udWxsKSB7Ci0gICAgICAgICAgICBmQXR0ckNoZWNrZXIucmV0dXJuQXR0ckFycmF5KHNpbXBsZUNvbnRlbnRBdHRyVmFsdWVzLCBzY2hlbWFEb2MpOwotICAgICAgICAgICAgZkF0dHJDaGVja2VyLnJldHVybkF0dHJBcnJheShkZXJpdmF0aW9uVHlwZUF0dHJWYWx1ZXMsIHNjaGVtYURvYyk7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgQ29tcGxleFR5cGVSZWNvdmVyYWJsZUVycm9yKCJzNHMtYXR0LW11c3QtYXBwZWFyIiwKLSAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde3NpbXBsZUNvbnRlbnROYW1lLCAiYmFzZSJ9LCBzaW1wbGVDb250ZW50KTsKLSAgICAgICAgfQotCi0gICAgICAgIFhTVHlwZURlZmluaXRpb24gdHlwZSA9IChYU1R5cGVEZWZpbml0aW9uKWZTY2hlbWFIYW5kbGVyLmdldEdsb2JhbERlY2woc2NoZW1hRG9jLAotICAgICAgICAgICAgICAgIFhTREhhbmRsZXIuVFlQRURFQ0xfVFlQRSwgYmFzZVR5cGVOYW1lLAotICAgICAgICAgICAgICAgIHNpbXBsZUNvbnRlbnQpOwotICAgICAgICBpZiAodHlwZT09bnVsbCkgewotICAgICAgICAgICAgZkF0dHJDaGVja2VyLnJldHVybkF0dHJBcnJheShzaW1wbGVDb250ZW50QXR0clZhbHVlcywgc2NoZW1hRG9jKTsKLSAgICAgICAgICAgIGZBdHRyQ2hlY2tlci5yZXR1cm5BdHRyQXJyYXkoZGVyaXZhdGlvblR5cGVBdHRyVmFsdWVzLCBzY2hlbWFEb2MpOwotICAgICAgICAgICAgdGhyb3cgbmV3IENvbXBsZXhUeXBlUmVjb3ZlcmFibGVFcnJvcigpOwotICAgICAgICB9Ci0KLSAgICAgICAgZkJhc2VUeXBlID0gdHlwZTsKLQotICAgICAgICBYU1NpbXBsZVR5cGUgYmFzZVZhbGlkYXRvciA9IG51bGw7Ci0gICAgICAgIFhTQ29tcGxleFR5cGVEZWNsIGJhc2VDb21wbGV4VHlwZSA9IG51bGw7Ci0gICAgICAgIGludCBiYXNlRmluYWxTZXQgPSAwOwotCi0gICAgICAgIC8vIElmIHRoZSBiYXNlIHR5cGUgaXMgY29tcGxleCwgaXQgbXVzdCBoYXZlIHNpbXBsZUNvbnRlbnQKLSAgICAgICAgaWYgKCh0eXBlLmdldFR5cGVDYXRlZ29yeSgpID09IFhTVHlwZURlZmluaXRpb24uQ09NUExFWF9UWVBFKSkgewotCi0gICAgICAgICAgICBiYXNlQ29tcGxleFR5cGUgPSAoWFNDb21wbGV4VHlwZURlY2wpdHlwZTsKLSAgICAgICAgICAgIGJhc2VGaW5hbFNldCA9IGJhc2VDb21wbGV4VHlwZS5nZXRGaW5hbCgpOwotICAgICAgICAgICAgLy8gYmFzZSBpcyBhIENUIHdpdGggc2ltcGxlIGNvbnRlbnQgKGJvdGggcmVzdHJpY3Rpb24gYW5kIGV4dGVuc2lvbiBhcmUgT0spCi0gICAgICAgICAgICBpZiAoYmFzZUNvbXBsZXhUeXBlLmdldENvbnRlbnRUeXBlKCkgPT0gWFNDb21wbGV4VHlwZURlY2wuQ09OVEVOVFRZUEVfU0lNUExFKSB7Ci0gICAgICAgICAgICAgICAgYmFzZVZhbGlkYXRvciA9IChYU1NpbXBsZVR5cGUpYmFzZUNvbXBsZXhUeXBlLmdldFNpbXBsZVR5cGUoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIGJhc2UgaXMgYSBDVCB3aXRoIG1peGVkL2VtcHRpYWJsZSBjb250ZW50IChvbmx5IHJlc3RyaWN0aW9uIGlzIE9LKQotICAgICAgICAgICAgZWxzZSBpZiAoZkRlcml2ZWRCeSA9PSBYU0NvbnN0YW50cy5ERVJJVkFUSU9OX1JFU1RSSUNUSU9OICYmCi0gICAgICAgICAgICAgICAgICAgIGJhc2VDb21wbGV4VHlwZS5nZXRDb250ZW50VHlwZSgpID09IFhTQ29tcGxleFR5cGVEZWNsLkNPTlRFTlRUWVBFX01JWEVEICYmCi0gICAgICAgICAgICAgICAgICAgICgoWFNQYXJ0aWNsZURlY2wpYmFzZUNvbXBsZXhUeXBlLmdldFBhcnRpY2xlKCkpLmVtcHRpYWJsZSgpKSB7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBmQXR0ckNoZWNrZXIucmV0dXJuQXR0ckFycmF5KHNpbXBsZUNvbnRlbnRBdHRyVmFsdWVzLCBzY2hlbWFEb2MpOwotICAgICAgICAgICAgICAgIGZBdHRyQ2hlY2tlci5yZXR1cm5BdHRyQXJyYXkoZGVyaXZhdGlvblR5cGVBdHRyVmFsdWVzLCBzY2hlbWFEb2MpOwotICAgICAgICAgICAgICAgIHRocm93IG5ldyBDb21wbGV4VHlwZVJlY292ZXJhYmxlRXJyb3IoInNyYy1jdC4yLjEiLAotICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde2ZOYW1lLCBiYXNlQ29tcGxleFR5cGUuZ2V0TmFtZSgpfSwgc2ltcGxlQ29udGVudCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBiYXNlVmFsaWRhdG9yID0gKFhTU2ltcGxlVHlwZSl0eXBlOwotICAgICAgICAgICAgLy8gYmFzZSBpcyBhIFNUIChvbmx5IGV4dGVuc2lvbiBpcyBPSykKLSAgICAgICAgICAgIGlmIChmRGVyaXZlZEJ5ID09IFhTQ29uc3RhbnRzLkRFUklWQVRJT05fUkVTVFJJQ1RJT04pIHsKLSAgICAgICAgICAgICAgICBmQXR0ckNoZWNrZXIucmV0dXJuQXR0ckFycmF5KHNpbXBsZUNvbnRlbnRBdHRyVmFsdWVzLCBzY2hlbWFEb2MpOwotICAgICAgICAgICAgICAgIGZBdHRyQ2hlY2tlci5yZXR1cm5BdHRyQXJyYXkoZGVyaXZhdGlvblR5cGVBdHRyVmFsdWVzLCBzY2hlbWFEb2MpOwotICAgICAgICAgICAgICAgIHRocm93IG5ldyBDb21wbGV4VHlwZVJlY292ZXJhYmxlRXJyb3IoInNyYy1jdC4yLjEiLAotICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde2ZOYW1lLCBiYXNlVmFsaWRhdG9yLmdldE5hbWUoKX0sIHNpbXBsZUNvbnRlbnQpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgYmFzZUZpbmFsU2V0PWJhc2VWYWxpZGF0b3IuZ2V0RmluYWwoKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgICAgIC8vIENoZWNrIHRoYXQgdGhlIGJhc2UgcGVybWl0cyB0aGUgZGVyaXZhdGlvbgotICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgICAgICBpZiAoKGJhc2VGaW5hbFNldCAmIGZEZXJpdmVkQnkpIT0wKSB7Ci0gICAgICAgICAgICBmQXR0ckNoZWNrZXIucmV0dXJuQXR0ckFycmF5KHNpbXBsZUNvbnRlbnRBdHRyVmFsdWVzLCBzY2hlbWFEb2MpOwotICAgICAgICAgICAgZkF0dHJDaGVja2VyLnJldHVybkF0dHJBcnJheShkZXJpdmF0aW9uVHlwZUF0dHJWYWx1ZXMsIHNjaGVtYURvYyk7Ci0gICAgICAgICAgICBTdHJpbmcgZXJyb3JLZXkgPSAoZkRlcml2ZWRCeT09WFNDb25zdGFudHMuREVSSVZBVElPTl9FWFRFTlNJT04pID8KLSAgICAgICAgICAgICAgICAgICAgImNvcy1jdC1leHRlbmRzLjEuMSIgOiAiZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4xIjsKLSAgICAgICAgICAgIHRocm93IG5ldyBDb21wbGV4VHlwZVJlY292ZXJhYmxlRXJyb3IoZXJyb3JLZXksCi0gICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXtmTmFtZSwgZkJhc2VUeXBlLmdldE5hbWUoKX0sIHNpbXBsZUNvbnRlbnQpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICAgICAgLy8gU2tpcCBvdmVyIGFueSBwb3RlbnRpYWwgYW5ub3RhdGlvbnMKLSAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICAgICAgRWxlbWVudCBzY0VsZW1lbnQgPSBzaW1wbGVDb250ZW50OwotICAgICAgICBzaW1wbGVDb250ZW50ID0gRE9NVXRpbC5nZXRGaXJzdENoaWxkRWxlbWVudChzaW1wbGVDb250ZW50KTsKLSAgICAgICAgaWYgKHNpbXBsZUNvbnRlbnQgIT0gbnVsbCkgewotICAgICAgICAgICAgLy8gdHJhdmVyc2UgYW5ub3RhdGlvbiBpZiBhbnkKLQotICAgICAgICAgICAgaWYgKERPTVV0aWwuZ2V0TG9jYWxOYW1lKHNpbXBsZUNvbnRlbnQpLmVxdWFscyhTY2hlbWFTeW1ib2xzLkVMVF9BTk5PVEFUSU9OKSkgewotICAgICAgICAgICAgICAgIGFkZEFubm90YXRpb24odHJhdmVyc2VBbm5vdGF0aW9uRGVjbChzaW1wbGVDb250ZW50LCBkZXJpdmF0aW9uVHlwZUF0dHJWYWx1ZXMsIGZhbHNlLCBzY2hlbWFEb2MpKTsKLSAgICAgICAgICAgICAgICBzaW1wbGVDb250ZW50ID0gRE9NVXRpbC5nZXROZXh0U2libGluZ0VsZW1lbnQoc2ltcGxlQ29udGVudCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgdGV4dCA9IERPTVV0aWwuZ2V0U3ludGhldGljQW5ub3RhdGlvbihzY0VsZW1lbnQpOwotICAgICAgICAgICAgICAgIGlmICh0ZXh0ICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgYWRkQW5ub3RhdGlvbih0cmF2ZXJzZVN5bnRoZXRpY0Fubm90YXRpb24oc2NFbGVtZW50LCB0ZXh0LCBkZXJpdmF0aW9uVHlwZUF0dHJWYWx1ZXMsIGZhbHNlLCBzY2hlbWFEb2MpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmIChzaW1wbGVDb250ZW50ICE9bnVsbCAmJgotICAgICAgICAgICAgICAgICAgICBET01VdGlsLmdldExvY2FsTmFtZShzaW1wbGVDb250ZW50KS5lcXVhbHMoU2NoZW1hU3ltYm9scy5FTFRfQU5OT1RBVElPTikpewotICAgICAgICAgICAgICAgIGZBdHRyQ2hlY2tlci5yZXR1cm5BdHRyQXJyYXkoc2ltcGxlQ29udGVudEF0dHJWYWx1ZXMsIHNjaGVtYURvYyk7Ci0gICAgICAgICAgICAgICAgZkF0dHJDaGVja2VyLnJldHVybkF0dHJBcnJheShkZXJpdmF0aW9uVHlwZUF0dHJWYWx1ZXMsIHNjaGVtYURvYyk7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IENvbXBsZXhUeXBlUmVjb3ZlcmFibGVFcnJvcigiczRzLWVsdC1pbnZhbGlkLWNvbnRlbnQuMSIsCi0gICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117Zk5hbWUsU2NoZW1hU3ltYm9scy5FTFRfQU5OT1RBVElPTn0sCi0gICAgICAgICAgICAgICAgICAgICAgICBzaW1wbGVDb250ZW50KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIFN0cmluZyB0ZXh0ID0gRE9NVXRpbC5nZXRTeW50aGV0aWNBbm5vdGF0aW9uKHNjRWxlbWVudCk7Ci0gICAgICAgICAgICBpZiAodGV4dCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgYWRkQW5ub3RhdGlvbih0cmF2ZXJzZVN5bnRoZXRpY0Fubm90YXRpb24oc2NFbGVtZW50LCB0ZXh0LCBkZXJpdmF0aW9uVHlwZUF0dHJWYWx1ZXMsIGZhbHNlLCBzY2hlbWFEb2MpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgICAgIC8vIFByb2Nlc3MgYSBSRVNUUklDVElPTgotICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgICAgICBpZiAoZkRlcml2ZWRCeSA9PSBYU0NvbnN0YW50cy5ERVJJVkFUSU9OX1JFU1RSSUNUSU9OKSB7Ci0KLSAgICAgICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgICAgICAgICAvLyBUaGVyZSBtYXkgYmUgYSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uIGluIHRoZSByZXN0cmljdGlvbiBlbGVtZW50Ci0gICAgICAgICAgICAvLyBUaGUgZGF0YSB0eXBlIHZhbGlkYXRvciB3aWxsIGJlIGJhc2VkIG9uIGl0LCBpZiBzcGVjaWZpZWQKLSAgICAgICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgICAgICAgICBpZiAoc2ltcGxlQ29udGVudCAhPW51bGwgJiYKLSAgICAgICAgICAgICAgICAgICAgRE9NVXRpbC5nZXRMb2NhbE5hbWUoc2ltcGxlQ29udGVudCkuZXF1YWxzKFNjaGVtYVN5bWJvbHMuRUxUX1NJTVBMRVRZUEUgKSkgewotCi0gICAgICAgICAgICAgICAgWFNTaW1wbGVUeXBlIGR2ID0gZlNjaGVtYUhhbmRsZXIuZlNpbXBsZVR5cGVUcmF2ZXJzZXIudHJhdmVyc2VMb2NhbCgKLSAgICAgICAgICAgICAgICAgICAgICAgIHNpbXBsZUNvbnRlbnQsIHNjaGVtYURvYywgZ3JhbW1hcik7Ci0gICAgICAgICAgICAgICAgaWYgKGR2ID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgZkF0dHJDaGVja2VyLnJldHVybkF0dHJBcnJheShzaW1wbGVDb250ZW50QXR0clZhbHVlcywgc2NoZW1hRG9jKTsKLSAgICAgICAgICAgICAgICAgICAgZkF0dHJDaGVja2VyLnJldHVybkF0dHJBcnJheShkZXJpdmF0aW9uVHlwZUF0dHJWYWx1ZXMsIHNjaGVtYURvYyk7Ci0gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBDb21wbGV4VHlwZVJlY292ZXJhYmxlRXJyb3IoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLy9jaGVjayB0aGF0IHRoaXMgZGF0YXR5cGUgdmFsaWRhdG9yIGlzIHZhbGlkbHkgZGVyaXZlZCBmcm9tIHRoZSBiYXNlCi0gICAgICAgICAgICAgICAgLy9hY2NvcmRpbmcgdG8gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbiA1LjEuMi4xCi0KLSAgICAgICAgICAgICAgICBpZiAoYmFzZVZhbGlkYXRvciAhPSBudWxsICYmCi0gICAgICAgICAgICAgICAgICAgICAgICAhWFNDb25zdHJhaW50cy5jaGVja1NpbXBsZURlcml2YXRpb25PayhkdiwgYmFzZVZhbGlkYXRvciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmFzZVZhbGlkYXRvci5nZXRGaW5hbCgpKSkgewotICAgICAgICAgICAgICAgICAgICBmQXR0ckNoZWNrZXIucmV0dXJuQXR0ckFycmF5KHNpbXBsZUNvbnRlbnRBdHRyVmFsdWVzLCBzY2hlbWFEb2MpOwotICAgICAgICAgICAgICAgICAgICBmQXR0ckNoZWNrZXIucmV0dXJuQXR0ckFycmF5KGRlcml2YXRpb25UeXBlQXR0clZhbHVlcywgc2NoZW1hRG9jKTsKLSAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IENvbXBsZXhUeXBlUmVjb3ZlcmFibGVFcnJvcigiZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi41LjIuMi4xIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117Zk5hbWUsIGR2LmdldE5hbWUoKSwgYmFzZVZhbGlkYXRvci5nZXROYW1lKCl9LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpbXBsZUNvbnRlbnQpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBiYXNlVmFsaWRhdG9yID0gZHY7Ci0gICAgICAgICAgICAgICAgc2ltcGxlQ29udGVudCA9IERPTVV0aWwuZ2V0TmV4dFNpYmxpbmdFbGVtZW50KHNpbXBsZUNvbnRlbnQpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyB0aGlzIG9ubHkgaGFwcGVucyB3aGVuIHJlc3RyaWN0aW5nIGEgbWl4ZWQvZW1wdGlhYmxlIENUCi0gICAgICAgICAgICAvLyBidXQgdGhlcmUgaXMgbm8gPHNpbXBsZVR5cGU+LCB3aGljaCBpcyByZXF1aXJlZAotICAgICAgICAgICAgaWYgKGJhc2VWYWxpZGF0b3IgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZBdHRyQ2hlY2tlci5yZXR1cm5BdHRyQXJyYXkoc2ltcGxlQ29udGVudEF0dHJWYWx1ZXMsIHNjaGVtYURvYyk7Ci0gICAgICAgICAgICAgICAgZkF0dHJDaGVja2VyLnJldHVybkF0dHJBcnJheShkZXJpdmF0aW9uVHlwZUF0dHJWYWx1ZXMsIHNjaGVtYURvYyk7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IENvbXBsZXhUeXBlUmVjb3ZlcmFibGVFcnJvcigic3JjLWN0LjIuMiIsCi0gICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117Zk5hbWV9LCBzaW1wbGVDb250ZW50KTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICAgICAgICAgIC8vIFRyYXZlcnNlIGFueSBmYWNldHMKLSAgICAgICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgICAgICAgICBFbGVtZW50IGF0dHJOb2RlID0gbnVsbDsKLSAgICAgICAgICAgIFhTRmFjZXRzIGZhY2V0RGF0YSA9IG51bGw7Ci0gICAgICAgICAgICBzaG9ydCBwcmVzZW50RmFjZXRzID0gMCA7Ci0gICAgICAgICAgICBzaG9ydCBmaXhlZEZhY2V0cyA9IDAgOwotCi0gICAgICAgICAgICBpZiAoc2ltcGxlQ29udGVudCE9bnVsbCkgewotICAgICAgICAgICAgICAgIEZhY2V0SW5mbyBmaSA9IHRyYXZlcnNlRmFjZXRzKHNpbXBsZUNvbnRlbnQsIGJhc2VWYWxpZGF0b3IsIHNjaGVtYURvYyk7Ci0gICAgICAgICAgICAgICAgYXR0ck5vZGUgPSBmaS5ub2RlQWZ0ZXJGYWNldHM7Ci0gICAgICAgICAgICAgICAgZmFjZXREYXRhID0gZmkuZmFjZXRkYXRhOwotICAgICAgICAgICAgICAgIHByZXNlbnRGYWNldHMgPSBmaS5mUHJlc2VudEZhY2V0czsKLSAgICAgICAgICAgICAgICBmaXhlZEZhY2V0cyA9IGZpLmZGaXhlZEZhY2V0czsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgU3RyaW5nIG5hbWUgPSBnZW5Bbm9uVHlwZU5hbWUoc2ltcGxlQ29udGVudEVsZW1lbnQpOwotICAgICAgICAgICAgZlhTU2ltcGxlVHlwZSA9IGZTY2hlbWFIYW5kbGVyLmZEVkZhY3RvcnkuY3JlYXRlVHlwZVJlc3RyaWN0aW9uKG5hbWUsc2NoZW1hRG9jLmZUYXJnZXROYW1lc3BhY2UsKHNob3J0KTAsYmFzZVZhbGlkYXRvcixudWxsKTsKLSAgICAgICAgICAgIHRyeXsKLSAgICAgICAgICAgICAgICBmVmFsaWRhdGlvblN0YXRlLnNldE5hbWVzcGFjZVN1cHBvcnQoc2NoZW1hRG9jLmZOYW1lc3BhY2VTdXBwb3J0KTsKLSAgICAgICAgICAgICAgICBmWFNTaW1wbGVUeXBlLmFwcGx5RmFjZXRzKGZhY2V0RGF0YSwgcHJlc2VudEZhY2V0cywgZml4ZWRGYWNldHMsIGZWYWxpZGF0aW9uU3RhdGUpOwotICAgICAgICAgICAgfWNhdGNoKEludmFsaWREYXRhdHlwZUZhY2V0RXhjZXB0aW9uIGV4KXsKLSAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcihleC5nZXRLZXkoKSwgZXguZ2V0QXJncygpLCBzaW1wbGVDb250ZW50KTsKLSAgICAgICAgICAgICAgICAvLyBSZWNyZWF0ZSB0aGUgdHlwZSwgaWdub3JpbmcgdGhlIGZhY2V0cwotICAgICAgICAgICAgICAgIGZYU1NpbXBsZVR5cGUgPSBmU2NoZW1hSGFuZGxlci5mRFZGYWN0b3J5LmNyZWF0ZVR5cGVSZXN0cmljdGlvbihuYW1lLHNjaGVtYURvYy5mVGFyZ2V0TmFtZXNwYWNlLChzaG9ydCkwLGJhc2VWYWxpZGF0b3IsbnVsbCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoZlhTU2ltcGxlVHlwZSBpbnN0YW5jZW9mIFhTU2ltcGxlVHlwZURlY2wpIHsKLSAgICAgICAgICAgICAgICAoKFhTU2ltcGxlVHlwZURlY2wpZlhTU2ltcGxlVHlwZSkuc2V0QW5vbnltb3VzKHRydWUpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgICAgICAgICAgLy8gVHJhdmVyc2UgYW55IGF0dHJpYnV0ZXMKLSAgICAgICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgICAgICAgICBpZiAoYXR0ck5vZGUgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGlmICghaXNBdHRyT3JBdHRyR3JvdXAoYXR0ck5vZGUpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZBdHRyQ2hlY2tlci5yZXR1cm5BdHRyQXJyYXkoc2ltcGxlQ29udGVudEF0dHJWYWx1ZXMsIHNjaGVtYURvYyk7Ci0gICAgICAgICAgICAgICAgICAgIGZBdHRyQ2hlY2tlci5yZXR1cm5BdHRyQXJyYXkoZGVyaXZhdGlvblR5cGVBdHRyVmFsdWVzLCBzY2hlbWFEb2MpOwotICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ29tcGxleFR5cGVSZWNvdmVyYWJsZUVycm9yKCJzNHMtZWx0LWludmFsaWQtY29udGVudC4xIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117Zk5hbWUsRE9NVXRpbC5nZXRMb2NhbE5hbWUoYXR0ck5vZGUpfSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyTm9kZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIEVsZW1lbnQgbm9kZT10cmF2ZXJzZUF0dHJzQW5kQXR0ckdycHMoYXR0ck5vZGUsZkF0dHJHcnAsCi0gICAgICAgICAgICAgICAgICAgICAgICBzY2hlbWFEb2MsZ3JhbW1hcixmQ29tcGxleFR5cGVEZWNsKTsKLSAgICAgICAgICAgICAgICBpZiAobm9kZSE9bnVsbCkgewotICAgICAgICAgICAgICAgICAgICBmQXR0ckNoZWNrZXIucmV0dXJuQXR0ckFycmF5KHNpbXBsZUNvbnRlbnRBdHRyVmFsdWVzLCBzY2hlbWFEb2MpOwotICAgICAgICAgICAgICAgICAgICBmQXR0ckNoZWNrZXIucmV0dXJuQXR0ckFycmF5KGRlcml2YXRpb25UeXBlQXR0clZhbHVlcywgc2NoZW1hRG9jKTsKLSAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IENvbXBsZXhUeXBlUmVjb3ZlcmFibGVFcnJvcigiczRzLWVsdC1pbnZhbGlkLWNvbnRlbnQuMSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde2ZOYW1lLERPTVV0aWwuZ2V0TG9jYWxOYW1lKG5vZGUpfSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgbWVyZ2VBdHRyaWJ1dGVzKGJhc2VDb21wbGV4VHlwZS5nZXRBdHRyR3JwKCksIGZBdHRyR3JwLCBmTmFtZSwgZmFsc2UsIHNpbXBsZUNvbnRlbnRFbGVtZW50KTsKLSAgICAgICAgICAgIH0gY2F0Y2ggKENvbXBsZXhUeXBlUmVjb3ZlcmFibGVFcnJvciBlKSB7Ci0gICAgICAgICAgICAgICAgZkF0dHJDaGVja2VyLnJldHVybkF0dHJBcnJheShzaW1wbGVDb250ZW50QXR0clZhbHVlcywgc2NoZW1hRG9jKTsKLSAgICAgICAgICAgICAgICBmQXR0ckNoZWNrZXIucmV0dXJuQXR0ckFycmF5KGRlcml2YXRpb25UeXBlQXR0clZhbHVlcywgc2NoZW1hRG9jKTsKLSAgICAgICAgICAgICAgICB0aHJvdyBlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gUHJvaGliaXRlZCB1c2VzIG11c3QgYmUgcmVtb3ZlZCBhZnRlciBtZXJnZSBmb3IgUkVTVFJJQ1RJT04KLSAgICAgICAgICAgIGZBdHRyR3JwLnJlbW92ZVByb2hpYml0ZWRBdHRycygpOwotCi0gICAgICAgICAgICBPYmplY3RbXSBlcnJBcmdzPWZBdHRyR3JwLnZhbGlkUmVzdHJpY3Rpb25PZihmTmFtZSwgYmFzZUNvbXBsZXhUeXBlLmdldEF0dHJHcnAoKSk7Ci0gICAgICAgICAgICBpZiAoZXJyQXJncyAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZkF0dHJDaGVja2VyLnJldHVybkF0dHJBcnJheShzaW1wbGVDb250ZW50QXR0clZhbHVlcywgc2NoZW1hRG9jKTsKLSAgICAgICAgICAgICAgICBmQXR0ckNoZWNrZXIucmV0dXJuQXR0ckFycmF5KGRlcml2YXRpb25UeXBlQXR0clZhbHVlcywgc2NoZW1hRG9jKTsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ29tcGxleFR5cGVSZWNvdmVyYWJsZUVycm9yKChTdHJpbmcpZXJyQXJnc1tlcnJBcmdzLmxlbmd0aC0xXSwKLSAgICAgICAgICAgICAgICAgICAgICAgIGVyckFyZ3MsIGF0dHJOb2RlKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICB9Ci0gICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgICAgIC8vIFByb2Nlc3MgYSBFWFRFTlNJT04KLSAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBmWFNTaW1wbGVUeXBlID0gYmFzZVZhbGlkYXRvcjsKLSAgICAgICAgICAgIGlmIChzaW1wbGVDb250ZW50ICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgICAgICAgICAgICAgIC8vIFRyYXZlcnNlIGFueSBhdHRyaWJ1dGVzCi0gICAgICAgICAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICAgICAgICAgICAgICBFbGVtZW50IGF0dHJOb2RlID0gc2ltcGxlQ29udGVudDsKLSAgICAgICAgICAgICAgICBpZiAoIWlzQXR0ck9yQXR0ckdyb3VwKGF0dHJOb2RlKSkgewotICAgICAgICAgICAgICAgICAgICBmQXR0ckNoZWNrZXIucmV0dXJuQXR0ckFycmF5KHNpbXBsZUNvbnRlbnRBdHRyVmFsdWVzLCBzY2hlbWFEb2MpOwotICAgICAgICAgICAgICAgICAgICBmQXR0ckNoZWNrZXIucmV0dXJuQXR0ckFycmF5KGRlcml2YXRpb25UeXBlQXR0clZhbHVlcywgc2NoZW1hRG9jKTsKLSAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IENvbXBsZXhUeXBlUmVjb3ZlcmFibGVFcnJvcigiczRzLWVsdC1pbnZhbGlkLWNvbnRlbnQuMSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde2ZOYW1lLERPTVV0aWwuZ2V0TG9jYWxOYW1lKGF0dHJOb2RlKX0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0ck5vZGUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBFbGVtZW50IG5vZGU9dHJhdmVyc2VBdHRyc0FuZEF0dHJHcnBzKGF0dHJOb2RlLGZBdHRyR3JwLAotICAgICAgICAgICAgICAgICAgICAgICAgc2NoZW1hRG9jLGdyYW1tYXIsZkNvbXBsZXhUeXBlRGVjbCk7Ci0KLSAgICAgICAgICAgICAgICBpZiAobm9kZSE9bnVsbCkgewotICAgICAgICAgICAgICAgICAgICBmQXR0ckNoZWNrZXIucmV0dXJuQXR0ckFycmF5KHNpbXBsZUNvbnRlbnRBdHRyVmFsdWVzLCBzY2hlbWFEb2MpOwotICAgICAgICAgICAgICAgICAgICBmQXR0ckNoZWNrZXIucmV0dXJuQXR0ckFycmF5KGRlcml2YXRpb25UeXBlQXR0clZhbHVlcywgc2NoZW1hRG9jKTsKLSAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IENvbXBsZXhUeXBlUmVjb3ZlcmFibGVFcnJvcigiczRzLWVsdC1pbnZhbGlkLWNvbnRlbnQuMSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde2ZOYW1lLERPTVV0aWwuZ2V0TG9jYWxOYW1lKG5vZGUpfSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLy8gUmVtb3ZlIHByb2hpYml0ZWQgdXNlcy4gICBTaG91bGQgYmUgZG9uZSBwcmlvciB0byBhbnkgbWVyZ2UuCi0gICAgICAgICAgICAgICAgZkF0dHJHcnAucmVtb3ZlUHJvaGliaXRlZEF0dHJzKCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmIChiYXNlQ29tcGxleFR5cGUgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgIG1lcmdlQXR0cmlidXRlcyhiYXNlQ29tcGxleFR5cGUuZ2V0QXR0ckdycCgpLCBmQXR0ckdycCwgZk5hbWUsIHRydWUsIHNpbXBsZUNvbnRlbnRFbGVtZW50KTsKLSAgICAgICAgICAgICAgICB9IGNhdGNoIChDb21wbGV4VHlwZVJlY292ZXJhYmxlRXJyb3IgZSkgewotICAgICAgICAgICAgICAgICAgICBmQXR0ckNoZWNrZXIucmV0dXJuQXR0ckFycmF5KHNpbXBsZUNvbnRlbnRBdHRyVmFsdWVzLCBzY2hlbWFEb2MpOwotICAgICAgICAgICAgICAgICAgICBmQXR0ckNoZWNrZXIucmV0dXJuQXR0ckFycmF5KGRlcml2YXRpb25UeXBlQXR0clZhbHVlcywgc2NoZW1hRG9jKTsKLSAgICAgICAgICAgICAgICAgICAgdGhyb3cgZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgLy8gYW5kIGZpbmFsbHksIHNpbmNlIHdlJ3ZlIG5vdGhpbmcgbW9yZSB0byB0cmF2ZXJzZSwgd2UgY2FuCi0gICAgICAgIC8vIHJldHVybiB0aGUgYXR0cmlidXRlcyAoYW5kIHRoZXJlYnkgcmVzZXQgdGhlIG5hbWVzcGFjZSBzdXBwb3J0KQotICAgICAgICBmQXR0ckNoZWNrZXIucmV0dXJuQXR0ckFycmF5KHNpbXBsZUNvbnRlbnRBdHRyVmFsdWVzLCBzY2hlbWFEb2MpOwotICAgICAgICBmQXR0ckNoZWNrZXIucmV0dXJuQXR0ckFycmF5KGRlcml2YXRpb25UeXBlQXR0clZhbHVlcywgc2NoZW1hRG9jKTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgdHJhdmVyc2VDb21wbGV4Q29udGVudChFbGVtZW50IGNvbXBsZXhDb250ZW50RWxlbWVudCwKLSAgICAgICAgICAgIGJvb2xlYW4gbWl4ZWRPblR5cGUsIFhTRG9jdW1lbnRJbmZvIHNjaGVtYURvYywKLSAgICAgICAgICAgIFNjaGVtYUdyYW1tYXIgZ3JhbW1hcikKLSAgICB0aHJvd3MgQ29tcGxleFR5cGVSZWNvdmVyYWJsZUVycm9yIHsKLQotCi0gICAgICAgIE9iamVjdFtdIGNvbXBsZXhDb250ZW50QXR0clZhbHVlcyA9IGZBdHRyQ2hlY2tlci5jaGVja0F0dHJpYnV0ZXMoY29tcGxleENvbnRlbnRFbGVtZW50LCBmYWxzZSwKLSAgICAgICAgICAgICAgICBzY2hlbWFEb2MpOwotCi0KLSAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICAgICAgLy8gRGV0ZXJtaW5lIGlmIHRoaXMgaXMgbWl4ZWQgY29udGVudAotICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgICAgICBib29sZWFuIG1peGVkQ29udGVudCA9IG1peGVkT25UeXBlOwotICAgICAgICBCb29sZWFuIG1peGVkQXR0ICAgICA9IChCb29sZWFuKSBjb21wbGV4Q29udGVudEF0dHJWYWx1ZXNbWFNBdHRyaWJ1dGVDaGVja2VyLkFUVElEWF9NSVhFRF07Ci0gICAgICAgIGlmIChtaXhlZEF0dCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBtaXhlZENvbnRlbnQgPSBtaXhlZEF0dC5ib29sZWFuVmFsdWUoKTsKLSAgICAgICAgfQotCi0KLSAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICAgICAgLy8gU2luY2UgdGhlIHR5cGUgbXVzdCBoYXZlIGNvbXBsZXggY29udGVudCwgc2V0IHRoZSBzaW1wbGUgdHlwZSB2YWxpZGF0b3JzCi0gICAgICAgIC8vIHRvIG51bGwKLSAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICAgICAgZlhTU2ltcGxlVHlwZSA9IG51bGw7Ci0KLSAgICAgICAgRWxlbWVudCBjb21wbGV4Q29udGVudCA9IERPTVV0aWwuZ2V0Rmlyc3RDaGlsZEVsZW1lbnQoY29tcGxleENvbnRlbnRFbGVtZW50KTsKLSAgICAgICAgaWYgKGNvbXBsZXhDb250ZW50ICE9IG51bGwgJiYgRE9NVXRpbC5nZXRMb2NhbE5hbWUoY29tcGxleENvbnRlbnQpLmVxdWFscyhTY2hlbWFTeW1ib2xzLkVMVF9BTk5PVEFUSU9OKSkgewotICAgICAgICAgICAgYWRkQW5ub3RhdGlvbih0cmF2ZXJzZUFubm90YXRpb25EZWNsKGNvbXBsZXhDb250ZW50LCBjb21wbGV4Q29udGVudEF0dHJWYWx1ZXMsIGZhbHNlLCBzY2hlbWFEb2MpKTsKLSAgICAgICAgICAgIGNvbXBsZXhDb250ZW50ID0gRE9NVXRpbC5nZXROZXh0U2libGluZ0VsZW1lbnQoY29tcGxleENvbnRlbnQpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgU3RyaW5nIHRleHQgPSBET01VdGlsLmdldFN5bnRoZXRpY0Fubm90YXRpb24oY29tcGxleENvbnRlbnRFbGVtZW50KTsKLSAgICAgICAgICAgIGlmICh0ZXh0ICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBhZGRBbm5vdGF0aW9uKHRyYXZlcnNlU3ludGhldGljQW5ub3RhdGlvbihjb21wbGV4Q29udGVudEVsZW1lbnQsIHRleHQsIGNvbXBsZXhDb250ZW50QXR0clZhbHVlcywgZmFsc2UsIHNjaGVtYURvYykpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gSWYgdGhlcmUgYXJlIG5vIGNoaWxkcmVuLCByZXR1cm4KLSAgICAgICAgaWYgKGNvbXBsZXhDb250ZW50PT1udWxsKSB7Ci0gICAgICAgICAgICBmQXR0ckNoZWNrZXIucmV0dXJuQXR0ckFycmF5KGNvbXBsZXhDb250ZW50QXR0clZhbHVlcywgc2NoZW1hRG9jKTsKLSAgICAgICAgICAgIHRocm93IG5ldyBDb21wbGV4VHlwZVJlY292ZXJhYmxlRXJyb3IoInM0cy1lbHQtaW52YWxpZC1jb250ZW50LjIiLAotICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117Zk5hbWUsU2NoZW1hU3ltYm9scy5FTFRfQ09NUExFWENPTlRFTlR9LAotICAgICAgICAgICAgICAgICAgICBjb21wbGV4Q29udGVudEVsZW1lbnQpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICAgICAgLy8gVGhlIGNvbnRlbnQgc2hvdWxkIGJlIGVpdGhlciAicmVzdHJpY3Rpb24iIG9yICJleHRlbnNpb24iCi0gICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgICAgIFN0cmluZyBjb21wbGV4Q29udGVudE5hbWUgPSBET01VdGlsLmdldExvY2FsTmFtZShjb21wbGV4Q29udGVudCk7Ci0gICAgICAgIGlmIChjb21wbGV4Q29udGVudE5hbWUuZXF1YWxzKFNjaGVtYVN5bWJvbHMuRUxUX1JFU1RSSUNUSU9OKSkKLSAgICAgICAgICAgIGZEZXJpdmVkQnkgPSBYU0NvbnN0YW50cy5ERVJJVkFUSU9OX1JFU1RSSUNUSU9OOwotICAgICAgICBlbHNlIGlmIChjb21wbGV4Q29udGVudE5hbWUuZXF1YWxzKFNjaGVtYVN5bWJvbHMuRUxUX0VYVEVOU0lPTikpCi0gICAgICAgICAgICBmRGVyaXZlZEJ5ID0gWFNDb25zdGFudHMuREVSSVZBVElPTl9FWFRFTlNJT047Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgZkF0dHJDaGVja2VyLnJldHVybkF0dHJBcnJheShjb21wbGV4Q29udGVudEF0dHJWYWx1ZXMsIHNjaGVtYURvYyk7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgQ29tcGxleFR5cGVSZWNvdmVyYWJsZUVycm9yKCJzNHMtZWx0LWludmFsaWQtY29udGVudC4xIiwKLSAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde2ZOYW1lLCBjb21wbGV4Q29udGVudE5hbWV9LCBjb21wbGV4Q29udGVudCk7Ci0gICAgICAgIH0KLSAgICAgICAgRWxlbWVudCBlbGVtVG1wID0gRE9NVXRpbC5nZXROZXh0U2libGluZ0VsZW1lbnQoY29tcGxleENvbnRlbnQpOwotICAgICAgICBpZiAoZWxlbVRtcCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmQXR0ckNoZWNrZXIucmV0dXJuQXR0ckFycmF5KGNvbXBsZXhDb250ZW50QXR0clZhbHVlcywgc2NoZW1hRG9jKTsKLSAgICAgICAgICAgIFN0cmluZyBzaWJsaW5nTmFtZSA9IERPTVV0aWwuZ2V0TG9jYWxOYW1lKGVsZW1UbXApOwotICAgICAgICAgICAgdGhyb3cgbmV3IENvbXBsZXhUeXBlUmVjb3ZlcmFibGVFcnJvcigiczRzLWVsdC1pbnZhbGlkLWNvbnRlbnQuMSIsCi0gICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXtmTmFtZSwgc2libGluZ05hbWV9LCBlbGVtVG1wKTsKLSAgICAgICAgfQotCi0gICAgICAgIE9iamVjdFtdIGRlcml2YXRpb25UeXBlQXR0clZhbHVlcyA9IGZBdHRyQ2hlY2tlci5jaGVja0F0dHJpYnV0ZXMoY29tcGxleENvbnRlbnQsIGZhbHNlLAotICAgICAgICAgICAgICAgIHNjaGVtYURvYyk7Ci0gICAgICAgIFFOYW1lIGJhc2VUeXBlTmFtZSA9IChRTmFtZSkgIGRlcml2YXRpb25UeXBlQXR0clZhbHVlc1tYU0F0dHJpYnV0ZUNoZWNrZXIuQVRUSURYX0JBU0VdOwotCi0KLSAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICAgICAgLy8gTmVlZCBhIGJhc2UgdHlwZS4gIENoZWNrIHRoYXQgaXQncyBhIGNvbXBsZXggdHlwZQotICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgICAgICBpZiAoYmFzZVR5cGVOYW1lPT1udWxsKSB7Ci0gICAgICAgICAgICBmQXR0ckNoZWNrZXIucmV0dXJuQXR0ckFycmF5KGNvbXBsZXhDb250ZW50QXR0clZhbHVlcywgc2NoZW1hRG9jKTsKLSAgICAgICAgICAgIGZBdHRyQ2hlY2tlci5yZXR1cm5BdHRyQXJyYXkoZGVyaXZhdGlvblR5cGVBdHRyVmFsdWVzLCBzY2hlbWFEb2MpOwotICAgICAgICAgICAgdGhyb3cgbmV3IENvbXBsZXhUeXBlUmVjb3ZlcmFibGVFcnJvcigiczRzLWF0dC1tdXN0LWFwcGVhciIsCi0gICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXtjb21wbGV4Q29udGVudE5hbWUsICJiYXNlIn0sIGNvbXBsZXhDb250ZW50KTsKLSAgICAgICAgfQotCi0gICAgICAgIFhTVHlwZURlZmluaXRpb24gdHlwZSA9IChYU1R5cGVEZWZpbml0aW9uKWZTY2hlbWFIYW5kbGVyLmdldEdsb2JhbERlY2woc2NoZW1hRG9jLAotICAgICAgICAgICAgICAgIFhTREhhbmRsZXIuVFlQRURFQ0xfVFlQRSwKLSAgICAgICAgICAgICAgICBiYXNlVHlwZU5hbWUsCi0gICAgICAgICAgICAgICAgY29tcGxleENvbnRlbnQpOwotCi0gICAgICAgIGlmICh0eXBlPT1udWxsKSB7Ci0gICAgICAgICAgICBmQXR0ckNoZWNrZXIucmV0dXJuQXR0ckFycmF5KGNvbXBsZXhDb250ZW50QXR0clZhbHVlcywgc2NoZW1hRG9jKTsKLSAgICAgICAgICAgIGZBdHRyQ2hlY2tlci5yZXR1cm5BdHRyQXJyYXkoZGVyaXZhdGlvblR5cGVBdHRyVmFsdWVzLCBzY2hlbWFEb2MpOwotICAgICAgICAgICAgdGhyb3cgbmV3IENvbXBsZXhUeXBlUmVjb3ZlcmFibGVFcnJvcigpOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKCEgKHR5cGUgaW5zdGFuY2VvZiBYU0NvbXBsZXhUeXBlRGVjbCkpIHsKLSAgICAgICAgICAgIGZBdHRyQ2hlY2tlci5yZXR1cm5BdHRyQXJyYXkoY29tcGxleENvbnRlbnRBdHRyVmFsdWVzLCBzY2hlbWFEb2MpOwotICAgICAgICAgICAgZkF0dHJDaGVja2VyLnJldHVybkF0dHJBcnJheShkZXJpdmF0aW9uVHlwZUF0dHJWYWx1ZXMsIHNjaGVtYURvYyk7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgQ29tcGxleFR5cGVSZWNvdmVyYWJsZUVycm9yKCJzcmMtY3QuMSIsCi0gICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXtmTmFtZSwgdHlwZS5nZXROYW1lKCl9LCBjb21wbGV4Q29udGVudCk7Ci0gICAgICAgIH0KLSAgICAgICAgWFNDb21wbGV4VHlwZURlY2wgYmFzZVR5cGUgPSAoWFNDb21wbGV4VHlwZURlY2wpdHlwZTsKLSAgICAgICAgZkJhc2VUeXBlID0gYmFzZVR5cGU7Ci0KLSAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICAgICAgLy8gQ2hlY2sgdGhhdCB0aGUgYmFzZSBwZXJtaXRzIHRoZSBkZXJpdmF0aW9uCi0gICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgICAgIGlmICgoYmFzZVR5cGUuZ2V0RmluYWwoKSAmIGZEZXJpdmVkQnkpIT0wKSB7Ci0gICAgICAgICAgICBmQXR0ckNoZWNrZXIucmV0dXJuQXR0ckFycmF5KGNvbXBsZXhDb250ZW50QXR0clZhbHVlcywgc2NoZW1hRG9jKTsKLSAgICAgICAgICAgIGZBdHRyQ2hlY2tlci5yZXR1cm5BdHRyQXJyYXkoZGVyaXZhdGlvblR5cGVBdHRyVmFsdWVzLCBzY2hlbWFEb2MpOwotICAgICAgICAgICAgU3RyaW5nIGVycm9yS2V5ID0gKGZEZXJpdmVkQnk9PVhTQ29uc3RhbnRzLkRFUklWQVRJT05fRVhURU5TSU9OKSA/Ci0gICAgICAgICAgICAgICAgICAgICJjb3MtY3QtZXh0ZW5kcy4xLjEiIDogImRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMSI7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgQ29tcGxleFR5cGVSZWNvdmVyYWJsZUVycm9yKGVycm9yS2V5LAotICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117Zk5hbWUsIGZCYXNlVHlwZS5nZXROYW1lKCl9LCBjb21wbGV4Q29udGVudCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgICAgICAvLyBTa2lwIG92ZXIgYW55IHBvdGVudGlhbCBhbm5vdGF0aW9ucwotICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgICAgICBjb21wbGV4Q29udGVudCA9IERPTVV0aWwuZ2V0Rmlyc3RDaGlsZEVsZW1lbnQoY29tcGxleENvbnRlbnQpOwotCi0gICAgICAgIGlmIChjb21wbGV4Q29udGVudCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAvLyB0cmF2ZXJzZSBhbm5vdGF0aW9uIGlmIGFueQotICAgICAgICAgICAgaWYgKERPTVV0aWwuZ2V0TG9jYWxOYW1lKGNvbXBsZXhDb250ZW50KS5lcXVhbHMoU2NoZW1hU3ltYm9scy5FTFRfQU5OT1RBVElPTikpIHsKLSAgICAgICAgICAgICAgICBhZGRBbm5vdGF0aW9uKHRyYXZlcnNlQW5ub3RhdGlvbkRlY2woY29tcGxleENvbnRlbnQsIGRlcml2YXRpb25UeXBlQXR0clZhbHVlcywgZmFsc2UsIHNjaGVtYURvYykpOwotICAgICAgICAgICAgICAgIGNvbXBsZXhDb250ZW50ID0gRE9NVXRpbC5nZXROZXh0U2libGluZ0VsZW1lbnQoY29tcGxleENvbnRlbnQpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIHRleHQgPSBET01VdGlsLmdldFN5bnRoZXRpY0Fubm90YXRpb24oY29tcGxleENvbnRlbnQpOwotICAgICAgICAgICAgICAgIGlmICh0ZXh0ICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgYWRkQW5ub3RhdGlvbih0cmF2ZXJzZVN5bnRoZXRpY0Fubm90YXRpb24oY29tcGxleENvbnRlbnQsIHRleHQsIGRlcml2YXRpb25UeXBlQXR0clZhbHVlcywgZmFsc2UsIHNjaGVtYURvYykpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChjb21wbGV4Q29udGVudCAhPW51bGwgJiYKLSAgICAgICAgICAgICAgICAgICAgRE9NVXRpbC5nZXRMb2NhbE5hbWUoY29tcGxleENvbnRlbnQpLmVxdWFscyhTY2hlbWFTeW1ib2xzLkVMVF9BTk5PVEFUSU9OKSl7Ci0gICAgICAgICAgICAgICAgZkF0dHJDaGVja2VyLnJldHVybkF0dHJBcnJheShjb21wbGV4Q29udGVudEF0dHJWYWx1ZXMsIHNjaGVtYURvYyk7Ci0gICAgICAgICAgICAgICAgZkF0dHJDaGVja2VyLnJldHVybkF0dHJBcnJheShkZXJpdmF0aW9uVHlwZUF0dHJWYWx1ZXMsIHNjaGVtYURvYyk7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IENvbXBsZXhUeXBlUmVjb3ZlcmFibGVFcnJvcigiczRzLWVsdC1pbnZhbGlkLWNvbnRlbnQuMSIsCi0gICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117Zk5hbWUsU2NoZW1hU3ltYm9scy5FTFRfQU5OT1RBVElPTn0sIGNvbXBsZXhDb250ZW50KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIFN0cmluZyB0ZXh0ID0gRE9NVXRpbC5nZXRTeW50aGV0aWNBbm5vdGF0aW9uKGNvbXBsZXhDb250ZW50KTsKLSAgICAgICAgICAgIGlmICh0ZXh0ICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBhZGRBbm5vdGF0aW9uKHRyYXZlcnNlU3ludGhldGljQW5ub3RhdGlvbihjb21wbGV4Q29udGVudCwgdGV4dCwgZGVyaXZhdGlvblR5cGVBdHRyVmFsdWVzLCBmYWxzZSwgc2NoZW1hRG9jKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICAgICAgLy8gUHJvY2VzcyB0aGUgY29udGVudC4gIE5vdGU6ICBzaG91bGQgSSB0cnkgdG8gY2F0Y2ggYW55IGNvbXBsZXhUeXBlIGVycm9ycwotICAgICAgICAvLyBoZXJlIGluIG9yZGVyIHRvIHJldHVybiB0aGUgYXR0ciBhcnJheT8KLSAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIHByb2Nlc3NDb21wbGV4Q29udGVudChjb21wbGV4Q29udGVudCwgbWl4ZWRDb250ZW50LCB0cnVlLCBzY2hlbWFEb2MsCi0gICAgICAgICAgICAgICAgICAgIGdyYW1tYXIpOwotICAgICAgICB9IGNhdGNoIChDb21wbGV4VHlwZVJlY292ZXJhYmxlRXJyb3IgZSkgewotICAgICAgICAgICAgZkF0dHJDaGVja2VyLnJldHVybkF0dHJBcnJheShjb21wbGV4Q29udGVudEF0dHJWYWx1ZXMsIHNjaGVtYURvYyk7Ci0gICAgICAgICAgICBmQXR0ckNoZWNrZXIucmV0dXJuQXR0ckFycmF5KGRlcml2YXRpb25UeXBlQXR0clZhbHVlcywgc2NoZW1hRG9jKTsKLSAgICAgICAgICAgIHRocm93IGU7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgICAgICAvLyBDb21wb3NlIHRoZSBmaW5hbCBjb250ZW50IGFuZCBhdHRyaWJ1dGUgdXNlcwotICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgICAgICBYU1BhcnRpY2xlRGVjbCBiYXNlQ29udGVudCA9IChYU1BhcnRpY2xlRGVjbCliYXNlVHlwZS5nZXRQYXJ0aWNsZSgpOwotICAgICAgICBpZiAoZkRlcml2ZWRCeT09WFNDb25zdGFudHMuREVSSVZBVElPTl9SRVNUUklDVElPTikgewotCi0gICAgICAgICAgICAvLyBUaGlzIGlzIGFuIFJFU1RSSUNUSU9OCi0KLSAgICAgICAgICAgIC8vIE4uQi4gZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi41LjMgaXMgY2hlY2tlZCB1bmRlciBzY2hlbWEKLSAgICAgICAgICAgIC8vIGZ1bGwgY2hlY2tpbmcuICAgVGhhdCdzIGJlY2F1c2Ugd2UgbmVlZCB0byB3YWl0IHVudGlsIGxvY2FscyBhcmUKLSAgICAgICAgICAgIC8vIHRyYXZlcnNlZCBzbyB0aGF0IG9jY3VycmVuY2UgaW5mb3JtYXRpb24gaXMgY29ycmVjdC4KLQotCi0gICAgICAgICAgICBpZiAoZkNvbnRlbnRUeXBlID09IFhTQ29tcGxleFR5cGVEZWNsLkNPTlRFTlRUWVBFX01JWEVEICYmCi0gICAgICAgICAgICAgICAgICAgIGJhc2VUeXBlLmdldENvbnRlbnRUeXBlKCkgIT0gWFNDb21wbGV4VHlwZURlY2wuQ09OVEVOVFRZUEVfTUlYRUQpIHsKLSAgICAgICAgICAgICAgICBmQXR0ckNoZWNrZXIucmV0dXJuQXR0ckFycmF5KGNvbXBsZXhDb250ZW50QXR0clZhbHVlcywgc2NoZW1hRG9jKTsKLSAgICAgICAgICAgICAgICBmQXR0ckNoZWNrZXIucmV0dXJuQXR0ckFycmF5KGRlcml2YXRpb25UeXBlQXR0clZhbHVlcywgc2NoZW1hRG9jKTsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ29tcGxleFR5cGVSZWNvdmVyYWJsZUVycm9yKCJkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjUuNC4xLjIiLAotICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde2ZOYW1lLCBiYXNlVHlwZS5nZXROYW1lKCl9LAotICAgICAgICAgICAgICAgICAgICAgICAgY29tcGxleENvbnRlbnQpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIG1lcmdlQXR0cmlidXRlcyhiYXNlVHlwZS5nZXRBdHRyR3JwKCksIGZBdHRyR3JwLCBmTmFtZSwgZmFsc2UsIGNvbXBsZXhDb250ZW50KTsKLSAgICAgICAgICAgIH0gY2F0Y2ggKENvbXBsZXhUeXBlUmVjb3ZlcmFibGVFcnJvciBlKSB7Ci0gICAgICAgICAgICAgICAgZkF0dHJDaGVja2VyLnJldHVybkF0dHJBcnJheShjb21wbGV4Q29udGVudEF0dHJWYWx1ZXMsIHNjaGVtYURvYyk7Ci0gICAgICAgICAgICAgICAgZkF0dHJDaGVja2VyLnJldHVybkF0dHJBcnJheShkZXJpdmF0aW9uVHlwZUF0dHJWYWx1ZXMsIHNjaGVtYURvYyk7Ci0gICAgICAgICAgICAgICAgdGhyb3cgZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIFJlbW92ZSBwcm9oaWJpdGVkIHVzZXMuICAgTXVzdCBiZSBkb25lIGFmdGVyIG1lcmdlIGZvciBSRVNUUklDVElPTi4KLSAgICAgICAgICAgIGZBdHRyR3JwLnJlbW92ZVByb2hpYml0ZWRBdHRycygpOwotCi0gICAgICAgICAgICBpZiAoYmFzZVR5cGUgIT0gU2NoZW1hR3JhbW1hci5mQW55VHlwZSkgewotICAgICAgICAgICAgICAgIE9iamVjdFtdIGVyckFyZ3MgPSBmQXR0ckdycC52YWxpZFJlc3RyaWN0aW9uT2YoZk5hbWUsIGJhc2VUeXBlLmdldEF0dHJHcnAoKSk7Ci0gICAgICAgICAgICAgICAgaWYgKGVyckFyZ3MgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBmQXR0ckNoZWNrZXIucmV0dXJuQXR0ckFycmF5KGNvbXBsZXhDb250ZW50QXR0clZhbHVlcywgc2NoZW1hRG9jKTsKLSAgICAgICAgICAgICAgICAgICAgZkF0dHJDaGVja2VyLnJldHVybkF0dHJBcnJheShkZXJpdmF0aW9uVHlwZUF0dHJWYWx1ZXMsIHNjaGVtYURvYyk7Ci0gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBDb21wbGV4VHlwZVJlY292ZXJhYmxlRXJyb3IoKFN0cmluZyllcnJBcmdzW2VyckFyZ3MubGVuZ3RoLTFdLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVyckFyZ3MsIGNvbXBsZXhDb250ZW50KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0KLSAgICAgICAgICAgIC8vIFRoaXMgaXMgYW4gRVhURU5TSU9OCi0KLSAgICAgICAgICAgIC8vIENyZWF0ZSB0aGUgcGFydGljbGUKLSAgICAgICAgICAgIGlmIChmUGFydGljbGUgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZDb250ZW50VHlwZSA9IGJhc2VUeXBlLmdldENvbnRlbnRUeXBlKCk7Ci0gICAgICAgICAgICAgICAgZlhTU2ltcGxlVHlwZSA9IChYU1NpbXBsZVR5cGUpYmFzZVR5cGUuZ2V0U2ltcGxlVHlwZSgpOwotICAgICAgICAgICAgICAgIGZQYXJ0aWNsZSA9IGJhc2VDb250ZW50OwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoYmFzZVR5cGUuZ2V0Q29udGVudFR5cGUoKSA9PSBYU0NvbXBsZXhUeXBlRGVjbC5DT05URU5UVFlQRV9FTVBUWSkgewotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICAvLyBDaGVjayBpZiB0aGUgY29udGVudFR5cGUgb2YgdGhlIGJhc2UgaXMgY29uc2lzdGVudCB3aXRoIHRoZSBuZXcgdHlwZQotICAgICAgICAgICAgICAgIC8vIGNvcy1jdC1leHRlbmRzLjEuNC4zLjIKLSAgICAgICAgICAgICAgICBpZiAoZkNvbnRlbnRUeXBlID09IFhTQ29tcGxleFR5cGVEZWNsLkNPTlRFTlRUWVBFX0VMRU1FTlQgJiYKLSAgICAgICAgICAgICAgICAgICAgICAgIGJhc2VUeXBlLmdldENvbnRlbnRUeXBlKCkgIT0gWFNDb21wbGV4VHlwZURlY2wuQ09OVEVOVFRZUEVfRUxFTUVOVCkgewotICAgICAgICAgICAgICAgICAgICBmQXR0ckNoZWNrZXIucmV0dXJuQXR0ckFycmF5KGNvbXBsZXhDb250ZW50QXR0clZhbHVlcywgc2NoZW1hRG9jKTsKLSAgICAgICAgICAgICAgICAgICAgZkF0dHJDaGVja2VyLnJldHVybkF0dHJBcnJheShkZXJpdmF0aW9uVHlwZUF0dHJWYWx1ZXMsIHNjaGVtYURvYyk7Ci0gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBDb21wbGV4VHlwZVJlY292ZXJhYmxlRXJyb3IoImNvcy1jdC1leHRlbmRzLjEuNC4zLjIuMi4xLmEiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXtmTmFtZX0sIGNvbXBsZXhDb250ZW50KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSBpZiAoZkNvbnRlbnRUeXBlID09IFhTQ29tcGxleFR5cGVEZWNsLkNPTlRFTlRUWVBFX01JWEVEICYmCi0gICAgICAgICAgICAgICAgICAgICAgICBiYXNlVHlwZS5nZXRDb250ZW50VHlwZSgpICE9IFhTQ29tcGxleFR5cGVEZWNsLkNPTlRFTlRUWVBFX01JWEVEKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZBdHRyQ2hlY2tlci5yZXR1cm5BdHRyQXJyYXkoY29tcGxleENvbnRlbnRBdHRyVmFsdWVzLCBzY2hlbWFEb2MpOwotICAgICAgICAgICAgICAgICAgICBmQXR0ckNoZWNrZXIucmV0dXJuQXR0ckFycmF5KGRlcml2YXRpb25UeXBlQXR0clZhbHVlcywgc2NoZW1hRG9jKTsKLSAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IENvbXBsZXhUeXBlUmVjb3ZlcmFibGVFcnJvcigiY29zLWN0LWV4dGVuZHMuMS40LjMuMi4yLjEuYiIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde2ZOYW1lfSwgY29tcGxleENvbnRlbnQpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8vIGlmIHRoZSBjb250ZW50IG9mIGVpdGhlciB0eXBlIGlzIGFuICJhbGwiIG1vZGVsIGdyb3VwLCBlcnJvci4KLSAgICAgICAgICAgICAgICBpZiAoZlBhcnRpY2xlLmZUeXBlID09IFhTUGFydGljbGVEZWNsLlBBUlRJQ0xFX01PREVMR1JPVVAgJiYKLSAgICAgICAgICAgICAgICAgICAgICAgICgoWFNNb2RlbEdyb3VwSW1wbClmUGFydGljbGUuZlZhbHVlKS5mQ29tcG9zaXRvciA9PSBYU01vZGVsR3JvdXBJbXBsLk1PREVMR1JPVVBfQUxMIHx8Ci0gICAgICAgICAgICAgICAgICAgICAgICAoKFhTUGFydGljbGVEZWNsKWJhc2VUeXBlLmdldFBhcnRpY2xlKCkpLmZUeXBlID09IFhTUGFydGljbGVEZWNsLlBBUlRJQ0xFX01PREVMR1JPVVAgJiYKLSAgICAgICAgICAgICAgICAgICAgICAgICgoWFNNb2RlbEdyb3VwSW1wbCkoKChYU1BhcnRpY2xlRGVjbCliYXNlVHlwZS5nZXRQYXJ0aWNsZSgpKSkuZlZhbHVlKS5mQ29tcG9zaXRvciA9PSBYU01vZGVsR3JvdXBJbXBsLk1PREVMR1JPVVBfQUxMKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZBdHRyQ2hlY2tlci5yZXR1cm5BdHRyQXJyYXkoY29tcGxleENvbnRlbnRBdHRyVmFsdWVzLCBzY2hlbWFEb2MpOwotICAgICAgICAgICAgICAgICAgICBmQXR0ckNoZWNrZXIucmV0dXJuQXR0ckFycmF5KGRlcml2YXRpb25UeXBlQXR0clZhbHVlcywgc2NoZW1hRG9jKTsKLSAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IENvbXBsZXhUeXBlUmVjb3ZlcmFibGVFcnJvcigiY29zLWFsbC1saW1pdGVkLjEuMiIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde30sIGNvbXBsZXhDb250ZW50KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLy8gdGhlICJzZXF1ZW5jZSIgbW9kZWwgZ3JvdXAgdG8gY29udGFpbiBib3RoIHBhcnRpY2xlcwotICAgICAgICAgICAgICAgIFhTTW9kZWxHcm91cEltcGwgZ3JvdXAgPSBuZXcgWFNNb2RlbEdyb3VwSW1wbCgpOwotICAgICAgICAgICAgICAgIGdyb3VwLmZDb21wb3NpdG9yID0gWFNNb2RlbEdyb3VwSW1wbC5NT0RFTEdST1VQX1NFUVVFTkNFOwotICAgICAgICAgICAgICAgIGdyb3VwLmZQYXJ0aWNsZUNvdW50ID0gMjsKLSAgICAgICAgICAgICAgICBncm91cC5mUGFydGljbGVzID0gbmV3IFhTUGFydGljbGVEZWNsWzJdOwotICAgICAgICAgICAgICAgIGdyb3VwLmZQYXJ0aWNsZXNbMF0gPSAoWFNQYXJ0aWNsZURlY2wpYmFzZVR5cGUuZ2V0UGFydGljbGUoKTsKLSAgICAgICAgICAgICAgICBncm91cC5mUGFydGljbGVzWzFdID0gZlBhcnRpY2xlOwotICAgICAgICAgICAgICAgIGdyb3VwLmZBbm5vdGF0aW9ucyA9IFhTT2JqZWN0TGlzdEltcGwuRU1QVFlfTElTVDsKLSAgICAgICAgICAgICAgICAvLyB0aGUgcGFydGljbGUgdG8gY29udGFpbiB0aGUgYWJvdmUgc2VxdWVuY2UKLSAgICAgICAgICAgICAgICBYU1BhcnRpY2xlRGVjbCBwYXJ0aWNsZSA9IG5ldyBYU1BhcnRpY2xlRGVjbCgpOwotICAgICAgICAgICAgICAgIHBhcnRpY2xlLmZUeXBlID0gWFNQYXJ0aWNsZURlY2wuUEFSVElDTEVfTU9ERUxHUk9VUDsKLSAgICAgICAgICAgICAgICBwYXJ0aWNsZS5mVmFsdWUgPSBncm91cDsKLSAgICAgICAgICAgICAgICBwYXJ0aWNsZS5mQW5ub3RhdGlvbnMgPSBYU09iamVjdExpc3RJbXBsLkVNUFRZX0xJU1Q7Ci0KLSAgICAgICAgICAgICAgICBmUGFydGljbGUgPSBwYXJ0aWNsZTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gUmVtb3ZlIHByb2hpYml0ZWQgdXNlcy4gICBNdXN0IGJlIGRvbmUgYmVmb3JlIG1lcmdlIGZvciBFWFRFTlNJT04uCi0gICAgICAgICAgICBmQXR0ckdycC5yZW1vdmVQcm9oaWJpdGVkQXR0cnMoKTsKLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgbWVyZ2VBdHRyaWJ1dGVzKGJhc2VUeXBlLmdldEF0dHJHcnAoKSwgZkF0dHJHcnAsIGZOYW1lLCB0cnVlLCBjb21wbGV4Q29udGVudCk7Ci0gICAgICAgICAgICB9IGNhdGNoIChDb21wbGV4VHlwZVJlY292ZXJhYmxlRXJyb3IgZSkgewotICAgICAgICAgICAgICAgIGZBdHRyQ2hlY2tlci5yZXR1cm5BdHRyQXJyYXkoY29tcGxleENvbnRlbnRBdHRyVmFsdWVzLCBzY2hlbWFEb2MpOwotICAgICAgICAgICAgICAgIGZBdHRyQ2hlY2tlci5yZXR1cm5BdHRyQXJyYXkoZGVyaXZhdGlvblR5cGVBdHRyVmFsdWVzLCBzY2hlbWFEb2MpOwotICAgICAgICAgICAgICAgIHRocm93IGU7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIGFuZCAqZmluYWxseSogd2UgY2FuIGxlZ2l0aW1hdGVseSByZXR1cm4gdGhlIGF0dHJpYnV0ZXMhCi0gICAgICAgIGZBdHRyQ2hlY2tlci5yZXR1cm5BdHRyQXJyYXkoY29tcGxleENvbnRlbnRBdHRyVmFsdWVzLCBzY2hlbWFEb2MpOwotICAgICAgICBmQXR0ckNoZWNrZXIucmV0dXJuQXR0ckFycmF5KGRlcml2YXRpb25UeXBlQXR0clZhbHVlcywgc2NoZW1hRG9jKTsKLQotICAgIH0gLy8gZW5kIG9mIHRyYXZlcnNlQ29tcGxleENvbnRlbnQKLQotCi0gICAgLy8gVGhpcyBtZXRob2QgbWVyZ2VzIGF0dHJpYnV0ZSB1c2VzIGZyb20gdGhlIGJhc2UsIGludG8gdGhlIGRlcml2ZWQgc2V0LgotICAgIC8vIExNOiBtYXkgd2FudCB0byBtZXJnZSB3aXRoIGF0dHJpYnV0ZUdyb3VwIHByb2Nlc3NpbmcuCi0gICAgcHJpdmF0ZSB2b2lkIG1lcmdlQXR0cmlidXRlcyhYU0F0dHJpYnV0ZUdyb3VwRGVjbCBmcm9tQXR0ckdycCwKLSAgICAgICAgICAgIFhTQXR0cmlidXRlR3JvdXBEZWNsIHRvQXR0ckdycCwKLSAgICAgICAgICAgIFN0cmluZyB0eXBlTmFtZSwKLSAgICAgICAgICAgIGJvb2xlYW4gZXh0ZW5zaW9uLAotICAgICAgICAgICAgRWxlbWVudCBlbGVtKQotICAgIHRocm93cyBDb21wbGV4VHlwZVJlY292ZXJhYmxlRXJyb3IgewotCi0gICAgICAgIFhTT2JqZWN0TGlzdCBhdHRyVXNlUyA9IGZyb21BdHRyR3JwLmdldEF0dHJpYnV0ZVVzZXMoKTsKLSAgICAgICAgWFNBdHRyaWJ1dGVVc2VJbXBsIG9uZUF0dHJVc2UgPSBudWxsOwotICAgICAgICBpbnQgYXR0ckNvdW50ID0gYXR0clVzZVMuZ2V0TGVuZ3RoKCk7Ci0gICAgICAgIGZvciAoaW50IGk9MDsgaTxhdHRyQ291bnQ7IGkrKykgewotICAgICAgICAgICAgb25lQXR0clVzZSA9IChYU0F0dHJpYnV0ZVVzZUltcGwpYXR0clVzZVMuaXRlbShpKTsKLSAgICAgICAgICAgIFhTQXR0cmlidXRlVXNlIGV4aXN0aW5nQXR0clVzZSA9IHRvQXR0ckdycC5nZXRBdHRyaWJ1dGVVc2Uob25lQXR0clVzZS5mQXR0ckRlY2wuZ2V0TmFtZXNwYWNlKCksCi0gICAgICAgICAgICAgICAgICAgIG9uZUF0dHJVc2UuZkF0dHJEZWNsLmdldE5hbWUoKSk7Ci0gICAgICAgICAgICBpZiAoZXhpc3RpbmdBdHRyVXNlID09IG51bGwpIHsKLQotICAgICAgICAgICAgICAgIFN0cmluZyBpZE5hbWUgPSB0b0F0dHJHcnAuYWRkQXR0cmlidXRlVXNlKG9uZUF0dHJVc2UpOwotICAgICAgICAgICAgICAgIGlmIChpZE5hbWUgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ29tcGxleFR5cGVSZWNvdmVyYWJsZUVycm9yKCJjdC1wcm9wcy1jb3JyZWN0LjUiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXt0eXBlTmFtZSwgaWROYW1lLCBvbmVBdHRyVXNlLmZBdHRyRGVjbC5nZXROYW1lKCl9LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW0pOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKGV4aXN0aW5nQXR0clVzZSAhPSBvbmVBdHRyVXNlKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGV4dGVuc2lvbikgewotICAgICAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcigiY3QtcHJvcHMtY29ycmVjdC40IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117dHlwZU5hbWUsIG9uZUF0dHJVc2UuZkF0dHJEZWNsLmdldE5hbWUoKX0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbSk7Ci0gICAgICAgICAgICAgICAgICAgIC8vIFJlY292ZXIgYnkgdXNpbmcgdGhlIGF0dHJpYnV0ZSB1c2UgZnJvbSB0aGUgYmFzZSB0eXBlLAotICAgICAgICAgICAgICAgICAgICAvLyB0byBtYWtlIHRoZSByZXN1bHRpbmcgc2NoZW1hICJtb3JlIHZhbGlkIi4KLSAgICAgICAgICAgICAgICAgICAgdG9BdHRyR3JwLnJlcGxhY2VBdHRyaWJ1dGVVc2UoZXhpc3RpbmdBdHRyVXNlLCBvbmVBdHRyVXNlKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgLy8gRm9yIGV4dGVuc2lvbiwgdGhlIHdpbGRjYXJkIG11c3QgYmUgZm9ybWVkIGJ5IGRvaW5nIGEgdW5pb24gb2YgdGhlIHdpbGRjYXJkcwotICAgICAgICBpZiAoZXh0ZW5zaW9uKSB7Ci0gICAgICAgICAgICBpZiAodG9BdHRyR3JwLmZBdHRyaWJ1dGVXQz09bnVsbCkgewotICAgICAgICAgICAgICAgIHRvQXR0ckdycC5mQXR0cmlidXRlV0MgPSBmcm9tQXR0ckdycC5mQXR0cmlidXRlV0M7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChmcm9tQXR0ckdycC5mQXR0cmlidXRlV0MgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHRvQXR0ckdycC5mQXR0cmlidXRlV0MgPSB0b0F0dHJHcnAuZkF0dHJpYnV0ZVdDLnBlcmZvcm1VbmlvbldpdGgoZnJvbUF0dHJHcnAuZkF0dHJpYnV0ZVdDLCB0b0F0dHJHcnAuZkF0dHJpYnV0ZVdDLmZQcm9jZXNzQ29udGVudHMpOwotICAgICAgICAgICAgICAgIGlmICh0b0F0dHJHcnAuZkF0dHJpYnV0ZVdDID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gUkVWSVNJVDogWE1MIFNjaGVtYSAxLjAgMm5kIGVkaXRpb24gZG9lc24ndCBhY3R1YWxseSBzcGVjaWZ5IHRoaXMgY29uc3RyYWludC4gSXQncyBhIGJ1ZyBpbiB0aGUgc3BlYwotICAgICAgICAgICAgICAgICAgICAvLyB3aGljaCB3aWxsIGV2ZW50dWFsbHkgYmUgZml4ZWQuIFdlJ3JlIGp1c3QgZ3Vlc3Npbmcgd2hhdCB0aGUgZXJyb3IgY29kZSB3aWxsIGJlLiBJZiBpdCB0dXJucyBvdXQgdG8gYmUKLSAgICAgICAgICAgICAgICAgICAgLy8gc29tZXRoaW5nIGVsc2Ugd2UnbGwgbmVlZCB0byBjaGFuZ2UgaXQuIC0tIG1yZ2xhdmFzCi0gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBDb21wbGV4VHlwZVJlY292ZXJhYmxlRXJyb3IoInNyYy1jdC41IiwgbmV3IE9iamVjdFtde3R5cGVOYW1lfSwgZWxlbSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgcHJvY2Vzc0NvbXBsZXhDb250ZW50KEVsZW1lbnQgY29tcGxleENvbnRlbnRDaGlsZCwKLSAgICAgICAgICAgIGJvb2xlYW4gaXNNaXhlZCwgYm9vbGVhbiBpc0Rlcml2YXRpb24sCi0gICAgICAgICAgICBYU0RvY3VtZW50SW5mbyBzY2hlbWFEb2MsIFNjaGVtYUdyYW1tYXIgZ3JhbW1hcikKLSAgICB0aHJvd3MgQ29tcGxleFR5cGVSZWNvdmVyYWJsZUVycm9yIHsKLQotICAgICAgICBFbGVtZW50IGF0dHJOb2RlID0gbnVsbDsKLSAgICAgICAgWFNQYXJ0aWNsZURlY2wgcGFydGljbGUgPSBudWxsOwotCi0gICAgICAgIC8vIHdoZXRoZXIgdGhlcmUgaXMgYSBwYXJ0aWNsZSB3aXRoIGVtcHR5IG1vZGVsIGdyb3VwCi0gICAgICAgIGJvb2xlYW4gZW1wdHlQYXJ0aWNsZSA9IGZhbHNlOwotICAgICAgICBpZiAoY29tcGxleENvbnRlbnRDaGlsZCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgICAgICAgICAvLyBHUk9VUCwgQUxMLCBTRVFVRU5DRSBvciBDSE9JQ0UsIGZvbGxvd2VkIGJ5IGF0dHJpYnV0ZXMsIGlmIHNwZWNpZmllZC4KLSAgICAgICAgICAgIC8vIE5vdGUgdGhhdCBpdCdzIHBvc3NpYmxlIHRoYXQgb25seSBhdHRyaWJ1dGVzIGFyZSBzcGVjaWZpZWQuCi0gICAgICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0KLQotICAgICAgICAgICAgU3RyaW5nIGNoaWxkTmFtZSA9IERPTVV0aWwuZ2V0TG9jYWxOYW1lKGNvbXBsZXhDb250ZW50Q2hpbGQpOwotCi0gICAgICAgICAgICBpZiAoY2hpbGROYW1lLmVxdWFscyhTY2hlbWFTeW1ib2xzLkVMVF9HUk9VUCkpIHsKLQotICAgICAgICAgICAgICAgIHBhcnRpY2xlID0gZlNjaGVtYUhhbmRsZXIuZkdyb3VwVHJhdmVyc2VyLnRyYXZlcnNlTG9jYWwoY29tcGxleENvbnRlbnRDaGlsZCwKLSAgICAgICAgICAgICAgICAgICAgICAgIHNjaGVtYURvYywgZ3JhbW1hcik7Ci0gICAgICAgICAgICAgICAgYXR0ck5vZGUgPSBET01VdGlsLmdldE5leHRTaWJsaW5nRWxlbWVudChjb21wbGV4Q29udGVudENoaWxkKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKGNoaWxkTmFtZS5lcXVhbHMoU2NoZW1hU3ltYm9scy5FTFRfU0VRVUVOQ0UpKSB7Ci0gICAgICAgICAgICAgICAgcGFydGljbGUgPSB0cmF2ZXJzZVNlcXVlbmNlKGNvbXBsZXhDb250ZW50Q2hpbGQsc2NoZW1hRG9jLGdyYW1tYXIsCi0gICAgICAgICAgICAgICAgICAgICAgICBOT1RfQUxMX0NPTlRFWFQsZkNvbXBsZXhUeXBlRGVjbCk7Ci0gICAgICAgICAgICAgICAgaWYgKHBhcnRpY2xlICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgWFNNb2RlbEdyb3VwSW1wbCBncm91cCA9IChYU01vZGVsR3JvdXBJbXBsKXBhcnRpY2xlLmZWYWx1ZTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGdyb3VwLmZQYXJ0aWNsZUNvdW50ID09IDApCi0gICAgICAgICAgICAgICAgICAgICAgICBlbXB0eVBhcnRpY2xlID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgYXR0ck5vZGUgPSBET01VdGlsLmdldE5leHRTaWJsaW5nRWxlbWVudChjb21wbGV4Q29udGVudENoaWxkKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKGNoaWxkTmFtZS5lcXVhbHMoU2NoZW1hU3ltYm9scy5FTFRfQ0hPSUNFKSkgewotICAgICAgICAgICAgICAgIHBhcnRpY2xlID0gdHJhdmVyc2VDaG9pY2UoY29tcGxleENvbnRlbnRDaGlsZCxzY2hlbWFEb2MsZ3JhbW1hciwKLSAgICAgICAgICAgICAgICAgICAgICAgIE5PVF9BTExfQ09OVEVYVCxmQ29tcGxleFR5cGVEZWNsKTsKLSAgICAgICAgICAgICAgICBpZiAocGFydGljbGUgIT0gbnVsbCAmJiBwYXJ0aWNsZS5mTWluT2NjdXJzID09IDApIHsKLSAgICAgICAgICAgICAgICAgICAgWFNNb2RlbEdyb3VwSW1wbCBncm91cCA9IChYU01vZGVsR3JvdXBJbXBsKXBhcnRpY2xlLmZWYWx1ZTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGdyb3VwLmZQYXJ0aWNsZUNvdW50ID09IDApCi0gICAgICAgICAgICAgICAgICAgICAgICBlbXB0eVBhcnRpY2xlID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgYXR0ck5vZGUgPSBET01VdGlsLmdldE5leHRTaWJsaW5nRWxlbWVudChjb21wbGV4Q29udGVudENoaWxkKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKGNoaWxkTmFtZS5lcXVhbHMoU2NoZW1hU3ltYm9scy5FTFRfQUxMKSkgewotICAgICAgICAgICAgICAgIHBhcnRpY2xlID0gdHJhdmVyc2VBbGwoY29tcGxleENvbnRlbnRDaGlsZCxzY2hlbWFEb2MsZ3JhbW1hciwKLSAgICAgICAgICAgICAgICAgICAgICAgIFBST0NFU1NJTkdfQUxMX0dQLGZDb21wbGV4VHlwZURlY2wpOwotICAgICAgICAgICAgICAgIGlmIChwYXJ0aWNsZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIFhTTW9kZWxHcm91cEltcGwgZ3JvdXAgPSAoWFNNb2RlbEdyb3VwSW1wbClwYXJ0aWNsZS5mVmFsdWU7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChncm91cC5mUGFydGljbGVDb3VudCA9PSAwKQotICAgICAgICAgICAgICAgICAgICAgICAgZW1wdHlQYXJ0aWNsZSA9IHRydWU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGF0dHJOb2RlID0gRE9NVXRpbC5nZXROZXh0U2libGluZ0VsZW1lbnQoY29tcGxleENvbnRlbnRDaGlsZCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAvLyBTaG91bGQgYmUgYXR0cmlidXRlcyBoZXJlIC0gd2lsbCBjaGVjayBiZWxvdy4uLgotICAgICAgICAgICAgICAgIGF0dHJOb2RlID0gY29tcGxleENvbnRlbnRDaGlsZDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIGlmIHRoZSBwYXJ0aWNsZSBpcyBlbXB0eSBiZWNhdXNlIHRoZXJlIGlzIG5vIG5vbi1hbm5vdGF0aW9uIGNoaWRyZW4sCi0gICAgICAgIC8vIHdlIG5lZWQgdG8gbWFrZSB0aGUgcGFydGljbGUgaXRzZWxmIG51bGwgKHNvIHRoYXQgdGhlIGVmZmVjdGl2ZQotICAgICAgICAvLyBjb250ZW50IGlzIGVtcHR5KS4KLSAgICAgICAgaWYgKGVtcHR5UGFydGljbGUpIHsKLSAgICAgICAgICAgIC8vIGdldCB0aGUgZmlyc3QgY2hpbGQKLSAgICAgICAgICAgIEVsZW1lbnQgY2hpbGQgPSBET01VdGlsLmdldEZpcnN0Q2hpbGRFbGVtZW50KGNvbXBsZXhDb250ZW50Q2hpbGQpOwotICAgICAgICAgICAgLy8gaWYgaXQncyBhbm5vdGF0aW9uLCBnZXQgdGhlIG5leHQgb25lCi0gICAgICAgICAgICBpZiAoY2hpbGQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGlmIChET01VdGlsLmdldExvY2FsTmFtZShjaGlsZCkuZXF1YWxzKFNjaGVtYVN5bWJvbHMuRUxUX0FOTk9UQVRJT04pKSB7Ci0gICAgICAgICAgICAgICAgICAgIGNoaWxkID0gRE9NVXRpbC5nZXROZXh0U2libGluZ0VsZW1lbnQoY2hpbGQpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIGlmIHRoZXJlIGlzIG5vIChub24tYW5ub3RhdGlvbikgY2hpbGRyZW4sIG1hcmsgcGFydGljbGUgZW1wdHkKLSAgICAgICAgICAgIGlmIChjaGlsZCA9PSBudWxsKQotICAgICAgICAgICAgICAgIHBhcnRpY2xlID0gbnVsbDsKLSAgICAgICAgICAgIC8vIGNoaWxkICE9IG51bGwgbWVhbnMgd2UgbWlnaHQgaGF2ZSBzZWVuIGFuIGVsZW1lbnQgd2l0aAotICAgICAgICAgICAgLy8gbWluT2NjdXJzID09IG1heE9jY3VycyA9PSAwCi0gICAgICAgIH0KLQotICAgICAgICBpZiAocGFydGljbGUgPT0gbnVsbCAmJiBpc01peGVkKSB7Ci0gICAgICAgICAgICBwYXJ0aWNsZSA9IFhTQ29uc3RyYWludHMuZ2V0RW1wdHlTZXF1ZW5jZSgpOwotICAgICAgICB9Ci0gICAgICAgIGZQYXJ0aWNsZSA9IHBhcnRpY2xlOwotCi0gICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgICAgIC8vIFNldCB0aGUgY29udGVudCB0eXBlCi0gICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgICAgIGlmIChmUGFydGljbGUgPT0gbnVsbCkKLSAgICAgICAgICAgIGZDb250ZW50VHlwZSA9IFhTQ29tcGxleFR5cGVEZWNsLkNPTlRFTlRUWVBFX0VNUFRZOwotICAgICAgICBlbHNlIGlmIChpc01peGVkKQotICAgICAgICAgICAgZkNvbnRlbnRUeXBlID0gWFNDb21wbGV4VHlwZURlY2wuQ09OVEVOVFRZUEVfTUlYRUQ7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICAgIGZDb250ZW50VHlwZSA9IFhTQ29tcGxleFR5cGVEZWNsLkNPTlRFTlRUWVBFX0VMRU1FTlQ7Ci0KLQotICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgICAgIC8vIE5vdywgcHJvY2VzcyBhdHRyaWJ1dGVzCi0gICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICAgICAgaWYgKGF0dHJOb2RlICE9IG51bGwpIHsKLSAgICAgICAgICAgIGlmICghaXNBdHRyT3JBdHRyR3JvdXAoYXR0ck5vZGUpKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IENvbXBsZXhUeXBlUmVjb3ZlcmFibGVFcnJvcigiczRzLWVsdC1pbnZhbGlkLWNvbnRlbnQuMSIsCi0gICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117Zk5hbWUsRE9NVXRpbC5nZXRMb2NhbE5hbWUoYXR0ck5vZGUpfSwKLSAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJOb2RlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIEVsZW1lbnQgbm9kZSA9Ci0gICAgICAgICAgICAgICAgdHJhdmVyc2VBdHRyc0FuZEF0dHJHcnBzKGF0dHJOb2RlLGZBdHRyR3JwLHNjaGVtYURvYyxncmFtbWFyLGZDb21wbGV4VHlwZURlY2wpOwotICAgICAgICAgICAgaWYgKG5vZGUhPW51bGwpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ29tcGxleFR5cGVSZWNvdmVyYWJsZUVycm9yKCJzNHMtZWx0LWludmFsaWQtY29udGVudC4xIiwKLSAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXtmTmFtZSxET01VdGlsLmdldExvY2FsTmFtZShub2RlKX0sCi0gICAgICAgICAgICAgICAgICAgICAgICBub2RlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIE9ubHkgcmVtb3ZlIHByb2hpYml0ZWQgYXR0cmlidXRlIHVzZXMgaWYgdGhpcyBpc24ndCBhIGRlcml2ZWQgdHlwZQotICAgICAgICAgICAgLy8gRGVyaXZhdGlvbi1zcGVjaWZpYyBjb2RlIHdvcnJpZXMgYWJvdXQgdGhpcyBlbHNld2hlcmUKLSAgICAgICAgICAgIGlmICghaXNEZXJpdmF0aW9uKSB7Ci0gICAgICAgICAgICAgICAgZkF0dHJHcnAucmVtb3ZlUHJvaGliaXRlZEF0dHJzKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotCi0KLSAgICB9IC8vIGVuZCBwcm9jZXNzQ29tcGxleENvbnRlbnQKLQotCi0gICAgcHJpdmF0ZSBib29sZWFuIGlzQXR0ck9yQXR0ckdyb3VwKEVsZW1lbnQgZSkgewotICAgICAgICBTdHJpbmcgZWxlbWVudE5hbWUgPSBET01VdGlsLmdldExvY2FsTmFtZShlKTsKLQotICAgICAgICBpZiAoZWxlbWVudE5hbWUuZXF1YWxzKFNjaGVtYVN5bWJvbHMuRUxUX0FUVFJJQlVURSkgfHwKLSAgICAgICAgICAgICAgICBlbGVtZW50TmFtZS5lcXVhbHMoU2NoZW1hU3ltYm9scy5FTFRfQVRUUklCVVRFR1JPVVApIHx8Ci0gICAgICAgICAgICAgICAgZWxlbWVudE5hbWUuZXF1YWxzKFNjaGVtYVN5bWJvbHMuRUxUX0FOWUFUVFJJQlVURSkpCi0gICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgZWxzZQotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCB0cmF2ZXJzZVNpbXBsZUNvbnRlbnREZWNsKEVsZW1lbnQgc2ltcGxlQ29udGVudERlY2wpIHsKLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgdHJhdmVyc2VDb21wbGV4Q29udGVudERlY2woRWxlbWVudCBjb21wbGV4Q29udGVudERlY2wsCi0gICAgICAgICAgICBib29sZWFuIG1peGVkT25Db21wbGV4VHlwZURlY2wpIHsKLSAgICB9Ci0KLSAgICAvKgotICAgICAqIEdlbmVyYXRlIGEgbmFtZSBmb3IgYW4gYW5vbnltb3VzIHR5cGUKLSAgICAgKi8KLSAgICBwcml2YXRlIFN0cmluZyBnZW5Bbm9uVHlwZU5hbWUoRWxlbWVudCBjb21wbGV4VHlwZURlY2wpIHsKLQotICAgICAgICAvLyBHZW5lcmF0ZSBhIHVuaXF1ZSBuYW1lIGZvciB0aGUgYW5vbnltb3VzIHR5cGUgYnkgY29uY2F0ZW5hdGluZyB0b2dldGhlciB0aGUKLSAgICAgICAgLy8gbmFtZXMgb2YgcGFyZW50IG5vZGVzCi0gICAgICAgIC8vIFRoZSBuYW1lIGlzIHF1aXRlIGdvb2QgZm9yIGRlYnVnZ2luZy9lcnJvciBwdXJwb3NlcywgYnV0IHdlIG1heSB3YW50IHRvCi0gICAgICAgIC8vIHJldmlzaXQgaG93IHRoaXMgaXMgZG9uZSBmb3IgcGVyZm9ybWFuY2UgcmVhc29ucyAoTE0pLgotICAgICAgICBTdHJpbmdCdWZmZXIgdHlwZU5hbWUgPSBuZXcgU3RyaW5nQnVmZmVyKCIjQW5vblR5cGVfIik7Ci0gICAgICAgIEVsZW1lbnQgbm9kZSA9IERPTVV0aWwuZ2V0UGFyZW50KGNvbXBsZXhUeXBlRGVjbCk7Ci0gICAgICAgIHdoaWxlIChub2RlICE9IG51bGwgJiYgKG5vZGUgIT0gRE9NVXRpbC5nZXRSb290KERPTVV0aWwuZ2V0RG9jdW1lbnQobm9kZSkpKSkgewotICAgICAgICAgICAgdHlwZU5hbWUuYXBwZW5kKG5vZGUuZ2V0QXR0cmlidXRlKFNjaGVtYVN5bWJvbHMuQVRUX05BTUUpKTsKLSAgICAgICAgICAgIG5vZGUgPSBET01VdGlsLmdldFBhcmVudChub2RlKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gdHlwZU5hbWUudG9TdHJpbmcoKTsKLSAgICB9Ci0KLQotICAgIHByaXZhdGUgdm9pZCBoYW5kbGVDb21wbGV4VHlwZUVycm9yKFN0cmluZyBtZXNzYWdlSWQsT2JqZWN0W10gYXJncywKLSAgICAgICAgICAgIEVsZW1lbnQgZSkgewotCi0gICAgICAgIGlmIChtZXNzYWdlSWQhPW51bGwpIHsKLSAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKG1lc3NhZ2VJZCwgYXJncywgZSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLwotICAgICAgICAvLyAgTW9jayB1cCB0aGUgdHlwZUluZm8gc3RydWN0dXJlIHNvIHRoYXQgdGhlcmUgd29uJ3QgYmUgcHJvYmxlbXMgZHVyaW5nCi0gICAgICAgIC8vICB2YWxpZGF0aW9uCi0gICAgICAgIC8vCi0gICAgICAgIGZCYXNlVHlwZSA9IFNjaGVtYUdyYW1tYXIuZkFueVR5cGU7Ci0gICAgICAgIGZDb250ZW50VHlwZSA9IFhTQ29tcGxleFR5cGVEZWNsLkNPTlRFTlRUWVBFX01JWEVEOwotICAgICAgICBmWFNTaW1wbGVUeXBlID0gbnVsbDsKLSAgICAgICAgZlBhcnRpY2xlID0gZ2V0RXJyb3JDb250ZW50KCk7Ci0gICAgICAgIC8vIFJFVklTSVQ6IGRvIHdlIG5lZWQgdG8gcmVtb3ZlIGFsbCBhdHRyaWJ1dGUgdXNlcyBhbHJlYWR5IGFkZGVkIGludG8KLSAgICAgICAgLy8gdGhlIGF0dHJpYnV0ZSBncm91cD8gbWF5YmUgaXQncyBvayB0byBsZWF2ZSB0aGVtIHRoZXJlLiAtU0cKLSAgICAgICAgZkF0dHJHcnAuZkF0dHJpYnV0ZVdDID0gZ2V0RXJyb3JXaWxkY2FyZCgpOwotCi0gICAgICAgIHJldHVybjsKLQotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBjb250ZW50QmFja3VwKCkgewotICAgICAgICBpZihmR2xvYmFsU3RvcmUgPT0gbnVsbCkgewotICAgICAgICAgICAgZkdsb2JhbFN0b3JlID0gbmV3IE9iamVjdCBbR0xPQkFMX05VTV07Ci0gICAgICAgICAgICBmR2xvYmFsU3RvcmVQb3MgPSAwOwotICAgICAgICB9Ci0gICAgICAgIGlmKGZHbG9iYWxTdG9yZVBvcyA9PSBmR2xvYmFsU3RvcmUubGVuZ3RoKSB7Ci0gICAgICAgICAgICBPYmplY3QgW10gbmV3QXJyYXkgPSBuZXcgT2JqZWN0W2ZHbG9iYWxTdG9yZVBvcytHTE9CQUxfTlVNXTsKLSAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZkdsb2JhbFN0b3JlLCAwLCBuZXdBcnJheSwgMCwgZkdsb2JhbFN0b3JlUG9zKTsKLSAgICAgICAgICAgIGZHbG9iYWxTdG9yZSA9IG5ld0FycmF5OwotICAgICAgICB9Ci0gICAgICAgIGZHbG9iYWxTdG9yZVtmR2xvYmFsU3RvcmVQb3MrK10gPSBmQ29tcGxleFR5cGVEZWNsOwotICAgICAgICBmR2xvYmFsU3RvcmVbZkdsb2JhbFN0b3JlUG9zKytdID0gZklzQWJzdHJhY3Q/Qm9vbGVhbi5UUlVFOkJvb2xlYW4uRkFMU0U7Ci0gICAgICAgIGZHbG9iYWxTdG9yZVtmR2xvYmFsU3RvcmVQb3MrK10gPSBmTmFtZSA7Ci0gICAgICAgIGZHbG9iYWxTdG9yZVtmR2xvYmFsU3RvcmVQb3MrK10gPSBmVGFyZ2V0TmFtZXNwYWNlOwotICAgICAgICAvLyBsZXQncyBzYXZlIG91cnNlbHZlcyBhIGNvdXBsZSBvZiBvYmplY3RzLi4uCi0gICAgICAgIGZHbG9iYWxTdG9yZVtmR2xvYmFsU3RvcmVQb3MrK10gPSBuZXcgSW50ZWdlcigoZkRlcml2ZWRCeSA8PCAxNikgKyBmRmluYWwpOwotICAgICAgICBmR2xvYmFsU3RvcmVbZkdsb2JhbFN0b3JlUG9zKytdID0gbmV3IEludGVnZXIoKGZCbG9jayA8PCAxNikgKyBmQ29udGVudFR5cGUpOwotICAgICAgICBmR2xvYmFsU3RvcmVbZkdsb2JhbFN0b3JlUG9zKytdID0gZkJhc2VUeXBlOwotICAgICAgICBmR2xvYmFsU3RvcmVbZkdsb2JhbFN0b3JlUG9zKytdID0gZkF0dHJHcnA7Ci0gICAgICAgIGZHbG9iYWxTdG9yZVtmR2xvYmFsU3RvcmVQb3MrK10gPSBmUGFydGljbGU7Ci0gICAgICAgIGZHbG9iYWxTdG9yZVtmR2xvYmFsU3RvcmVQb3MrK10gPSBmWFNTaW1wbGVUeXBlOwotICAgICAgICBmR2xvYmFsU3RvcmVbZkdsb2JhbFN0b3JlUG9zKytdID0gZkFubm90YXRpb25zOwotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBjb250ZW50UmVzdG9yZSgpIHsKLSAgICAgICAgZkFubm90YXRpb25zID0gKFhTQW5ub3RhdGlvbkltcGwgW10pZkdsb2JhbFN0b3JlWy0tZkdsb2JhbFN0b3JlUG9zXTsKLSAgICAgICAgZlhTU2ltcGxlVHlwZSA9IChYU1NpbXBsZVR5cGUpZkdsb2JhbFN0b3JlWy0tZkdsb2JhbFN0b3JlUG9zXTsKLSAgICAgICAgZlBhcnRpY2xlID0gKFhTUGFydGljbGVEZWNsKWZHbG9iYWxTdG9yZVstLWZHbG9iYWxTdG9yZVBvc107Ci0gICAgICAgIGZBdHRyR3JwID0gKFhTQXR0cmlidXRlR3JvdXBEZWNsKWZHbG9iYWxTdG9yZVstLWZHbG9iYWxTdG9yZVBvc107Ci0gICAgICAgIGZCYXNlVHlwZSA9IChYU1R5cGVEZWZpbml0aW9uKWZHbG9iYWxTdG9yZVstLWZHbG9iYWxTdG9yZVBvc107Ci0gICAgICAgIGludCBpID0gKChJbnRlZ2VyKShmR2xvYmFsU3RvcmVbLS1mR2xvYmFsU3RvcmVQb3NdKSkuaW50VmFsdWUoKTsKLSAgICAgICAgZkJsb2NrID0gKHNob3J0KShpID4+IDE2KTsKLSAgICAgICAgZkNvbnRlbnRUeXBlID0gKHNob3J0KWk7Ci0gICAgICAgIGkgPSAoKEludGVnZXIpKGZHbG9iYWxTdG9yZVstLWZHbG9iYWxTdG9yZVBvc10pKS5pbnRWYWx1ZSgpOwotICAgICAgICBmRGVyaXZlZEJ5ID0gKHNob3J0KShpID4+IDE2KTsKLSAgICAgICAgZkZpbmFsID0gKHNob3J0KWk7Ci0gICAgICAgIGZUYXJnZXROYW1lc3BhY2UgPSAoU3RyaW5nKWZHbG9iYWxTdG9yZVstLWZHbG9iYWxTdG9yZVBvc107Ci0gICAgICAgIGZOYW1lID0gKFN0cmluZylmR2xvYmFsU3RvcmVbLS1mR2xvYmFsU3RvcmVQb3NdOwotICAgICAgICBmSXNBYnN0cmFjdCA9ICgoQm9vbGVhbilmR2xvYmFsU3RvcmVbLS1mR2xvYmFsU3RvcmVQb3NdKS5ib29sZWFuVmFsdWUoKTsKLSAgICAgICAgZkNvbXBsZXhUeXBlRGVjbCA9IChYU0NvbXBsZXhUeXBlRGVjbClmR2xvYmFsU3RvcmVbLS1mR2xvYmFsU3RvcmVQb3NdOwotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBhZGRBbm5vdGF0aW9uKFhTQW5ub3RhdGlvbkltcGwgYW5ub3RhdGlvbikgewotICAgICAgICBpZihhbm5vdGF0aW9uID09IG51bGwpCi0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIC8vIGl0IGlzbid0IHZlcnkgbGlrZWx5IHRoYXQgdGhlcmUgd2lsbCBiZSBtb3JlIHRoYW4gb25lIGFubm90YXRpb24KLSAgICAgICAgLy8gaW4gYSBjb21wbGV4VHlwZSBkZWNsLiAgVGhpcyBzYXZlcyB1cyBmcm9taGF2aW5nIHRvIHB1c2gvcG9wCi0gICAgICAgIC8vIG9uZSBtb3JlIG9iamVjdCBmcm9tIHRoZSBmR2xvYmFsU3RvcmUsIGFuZCB0aGF0J3MgYm91bmQKLSAgICAgICAgLy8gdG8gYmUgYSBzYXZpbmdzIGZvciBtb3N0IGFwcGxpY2F0aW9ucwotICAgICAgICBpZihmQW5ub3RhdGlvbnMgPT0gbnVsbCkgewotICAgICAgICAgICAgZkFubm90YXRpb25zID0gbmV3IFhTQW5ub3RhdGlvbkltcGxbMV07Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBYU0Fubm90YXRpb25JbXBsIFtdIHRlbXBBcnJheSA9IG5ldyBYU0Fubm90YXRpb25JbXBsW2ZBbm5vdGF0aW9ucy5sZW5ndGggKyAxXTsKLSAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZkFubm90YXRpb25zLCAwLCB0ZW1wQXJyYXksIDAsIGZBbm5vdGF0aW9ucy5sZW5ndGgpOwotICAgICAgICAgICAgZkFubm90YXRpb25zID0gdGVtcEFycmF5OwotICAgICAgICB9Ci0gICAgICAgIGZBbm5vdGF0aW9uc1tmQW5ub3RhdGlvbnMubGVuZ3RoLTFdID0gYW5ub3RhdGlvbjsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL3RyYXZlcnNlcnMvWFNERWxlbWVudFRyYXZlcnNlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy90cmF2ZXJzZXJzL1hTREVsZW1lbnRUcmF2ZXJzZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMGQ0ODA1OC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL3RyYXZlcnNlcnMvWFNERWxlbWVudFRyYXZlcnNlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTY1ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLnRyYXZlcnNlcnM7Ci0KLWltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LlZhbGlkYXRlZEluZm87Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LlhTU2ltcGxlVHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMuU2NoZW1hR3JhbW1hcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMuU2NoZW1hU3ltYm9sczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMuWFNBbm5vdGF0aW9uSW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMuWFNDb21wbGV4VHlwZURlY2w7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlhTQ29uc3RyYWludHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlhTRWxlbWVudERlY2w7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlhTUGFydGljbGVEZWNsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy51dGlsLlhJbnQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLnV0aWwuWFNPYmplY3RMaXN0SW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuRE9NVXRpbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuU3ltYm9sVGFibGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlhNTENoYXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuUU5hbWU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU0NvbnN0YW50czsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTT2JqZWN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNPYmplY3RMaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNUeXBlRGVmaW5pdGlvbjsKLWltcG9ydCBvcmcudzNjLmRvbS5BdHRyOwotaW1wb3J0IG9yZy53M2MuZG9tLkVsZW1lbnQ7Ci0KLS8qKgotICogVGhlIGVsZW1lbnQgZGVjbGFyYXRpb24gc2NoZW1hIGNvbXBvbmVudCB0cmF2ZXJzZXIuCi0gKiA8ZWxlbWVudAotICogICBhYnN0cmFjdCA9IGJvb2xlYW4gOiBmYWxzZQotICogICBibG9jayA9ICgjYWxsIHwgTGlzdCBvZiAoZXh0ZW5zaW9uIHwgcmVzdHJpY3Rpb24gfCBzdWJzdGl0dXRpb24pKQotICogICBkZWZhdWx0ID0gc3RyaW5nCi0gKiAgIGZpbmFsID0gKCNhbGwgfCBMaXN0IG9mIChleHRlbnNpb24gfCByZXN0cmljdGlvbikpCi0gKiAgIGZpeGVkID0gc3RyaW5nCi0gKiAgIGZvcm0gPSAocXVhbGlmaWVkIHwgdW5xdWFsaWZpZWQpCi0gKiAgIGlkID0gSUQKLSAqICAgbWF4T2NjdXJzID0gKG5vbk5lZ2F0aXZlSW50ZWdlciB8IHVuYm91bmRlZCkgIDogMQotICogICBtaW5PY2N1cnMgPSBub25OZWdhdGl2ZUludGVnZXIgOiAxCi0gKiAgIG5hbWUgPSBOQ05hbWUKLSAqICAgbmlsbGFibGUgPSBib29sZWFuIDogZmFsc2UKLSAqICAgcmVmID0gUU5hbWUKLSAqICAgc3Vic3RpdHV0aW9uR3JvdXAgPSBRTmFtZQotICogICB0eXBlID0gUU5hbWUKLSAqICAge2FueSBhdHRyaWJ1dGVzIHdpdGggbm9uLXNjaGVtYSBuYW1lc3BhY2UgLiAuIC59PgotICogICBDb250ZW50OiAoYW5ub3RhdGlvbj8sICgoc2ltcGxlVHlwZSB8IGNvbXBsZXhUeXBlKT8sICh1bmlxdWUgfCBrZXkgfCBrZXlyZWYpKikpCi0gKiA8L2VsZW1lbnQ+Ci0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgU2FuZHkgR2FvLCBJQk0KLSAqCi0gKiBAdmVyc2lvbiAkSWQ6IFhTREVsZW1lbnRUcmF2ZXJzZXIuamF2YSx2IDEuOSAyMDEwLTExLTAxIDA0OjQwOjAyIGpvZWh3IEV4cCAkCi0gKi8KLWNsYXNzIFhTREVsZW1lbnRUcmF2ZXJzZXIgZXh0ZW5kcyBYU0RBYnN0cmFjdFRyYXZlcnNlciB7Ci0KLSAgICBwcm90ZWN0ZWQgZmluYWwgWFNFbGVtZW50RGVjbCAgZlRlbXBFbGVtZW50RGVjbCAgPSBuZXcgWFNFbGVtZW50RGVjbCgpOwotCi0gICAgLy8gdGhpcyBjb250cm9scyB3aGF0IGhhcHBlbnMgd2hlbiBhIGxvY2FsIGVsZW1lbnQgaXMgZW5jb3VudGVyZWQuCi0gICAgLy8gV2UgbWF5IG5vdCBlbmNvdW50ZXIgYWxsIGxvY2FsIGVsZW1lbnRzIHdoZW4gZmlyc3QgcGFyc2luZy4KLSAgICBib29sZWFuIGZEZWZlclRyYXZlcnNpbmdMb2NhbEVsZW1lbnRzOwotCi0gICAgWFNERWxlbWVudFRyYXZlcnNlciAoWFNESGFuZGxlciBoYW5kbGVyLAotICAgICAgICAgICAgWFNBdHRyaWJ1dGVDaGVja2VyIGdBdHRyQ2hlY2spIHsKLSAgICAgICAgc3VwZXIoaGFuZGxlciwgZ0F0dHJDaGVjayk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhdmVyc2UgYSBsb2NhbGx5IGRlY2xhcmVkIGVsZW1lbnQgKG9yIGFuIGVsZW1lbnQgcmVmZXJlbmNlKS4KLSAgICAgKgotICAgICAqIFRvIGhhbmRsZSB0aGUgcmVjdXJzaXZlIGNhc2VzIGVmZmljaWVudGx5LCB3ZSBkZWxheSB0aGUgdHJhdmVyc2FsCi0gICAgICogYW5kIHJldHVybiBhbiBlbXB0eSBwYXJ0aWNsZSBub2RlLiBXZSdsbCBmaWxsIGluIHRoaXMgcGFydGljbGUgbm9kZQotICAgICAqIGxhdGVyIGFmdGVyIHdlJ3ZlIGRvbmUgd2l0aCBhbGwgdGhlIGdsb2JhbCBkZWNsYXJhdGlvbnMuCi0gICAgICogVGhpcyBtZXRob2QgY2F1c2VzIGEgbnVtYmVyIG9mIGRhdGEgc3RydWN0dXJlcyBpbiB0aGUgc2NoZW1hIGhhbmRsZXIgdG8gYmUgZmlsbGVkIGluLgotICAgICAqCi0gICAgICogQHBhcmFtICBlbG1EZWNsCi0gICAgICogQHBhcmFtICBzY2hlbWFEb2MKLSAgICAgKiBAcGFyYW0gIGdyYW1tYXIKLSAgICAgKiBAcmV0dXJuIHRoZSBwYXJ0aWNsZQotICAgICAqLwotICAgIFhTUGFydGljbGVEZWNsIHRyYXZlcnNlTG9jYWwoRWxlbWVudCBlbG1EZWNsLAotICAgICAgICAgICAgWFNEb2N1bWVudEluZm8gc2NoZW1hRG9jLAotICAgICAgICAgICAgU2NoZW1hR3JhbW1hciBncmFtbWFyLAotICAgICAgICAgICAgaW50IGFsbENvbnRleHRGbGFncywKLSAgICAgICAgICAgIFhTT2JqZWN0IHBhcmVudCkgewotCi0gICAgICAgIFhTUGFydGljbGVEZWNsIHBhcnRpY2xlID0gbnVsbDsKLSAgICAgICAgaWYgKGZTY2hlbWFIYW5kbGVyLmZEZWNsUG9vbCAhPW51bGwpIHsKLSAgICAgICAgICAgIHBhcnRpY2xlID0gZlNjaGVtYUhhbmRsZXIuZkRlY2xQb29sLmdldFBhcnRpY2xlRGVjbCgpOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgcGFydGljbGUgPSBuZXcgWFNQYXJ0aWNsZURlY2woKTsKLSAgICAgICAgfQotICAgICAgICBpZiAoZkRlZmVyVHJhdmVyc2luZ0xvY2FsRWxlbWVudHMpIHsKLSAgICAgICAgICAgIC8vIFRoZSBvbmx5IHRoaW5nIHdlIGNhcmUgYWJvdXQgbm93IGlzIHdoZXRoZXIgdGhpcyBlbGVtZW50IGhhcwotICAgICAgICAgICAgLy8gbWluT2NjdXJzPTAuIFRoaXMgYWZmZWN0cyAoaWYgdGhlIGVsZW1lbnQgYXBwZWFycyBpbiBhIGNvbXBsZXgKLSAgICAgICAgICAgIC8vIHR5cGUpIHdoZXRoZXIgYSB0eXBlIGhhcyBlbXB0aWFibGUgY29udGVudC4KLSAgICAgICAgICAgIHBhcnRpY2xlLmZUeXBlID0gWFNQYXJ0aWNsZURlY2wuUEFSVElDTEVfRUxFTUVOVDsKLSAgICAgICAgICAgIEF0dHIgYXR0ciA9IGVsbURlY2wuZ2V0QXR0cmlidXRlTm9kZShTY2hlbWFTeW1ib2xzLkFUVF9NSU5PQ0NVUlMpOwotICAgICAgICAgICAgaWYgKGF0dHIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIFN0cmluZyBtaW4gPSBhdHRyLmdldFZhbHVlKCk7Ci0gICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgaW50IG0gPSBJbnRlZ2VyLnBhcnNlSW50KFhNTENoYXIudHJpbShtaW4pKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKG0gPj0gMCkKLSAgICAgICAgICAgICAgICAgICAgICAgIHBhcnRpY2xlLmZNaW5PY2N1cnMgPSBtOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGV4KSB7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZlNjaGVtYUhhbmRsZXIuZmlsbEluTG9jYWxFbGVtSW5mbyhlbG1EZWNsLCBzY2hlbWFEb2MsIGFsbENvbnRleHRGbGFncywgcGFyZW50LCBwYXJ0aWNsZSk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICB0cmF2ZXJzZUxvY2FsKHBhcnRpY2xlLCBlbG1EZWNsLCBzY2hlbWFEb2MsIGdyYW1tYXIsIGFsbENvbnRleHRGbGFncywgcGFyZW50LCBudWxsKTsKLSAgICAgICAgICAgIC8vIElmIGl0J3MgYW4gZW1wdHkgcGFydGljbGUsIHJldHVybiBudWxsLgotICAgICAgICAgICAgaWYgKHBhcnRpY2xlLmZUeXBlID09IFhTUGFydGljbGVEZWNsLlBBUlRJQ0xFX0VNUFRZKQotICAgICAgICAgICAgICAgIHBhcnRpY2xlID0gbnVsbDsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBwYXJ0aWNsZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmF2ZXJzZSBhIGxvY2FsbHkgZGVjbGFyZWQgZWxlbWVudCAob3IgYW4gZWxlbWVudCByZWZlcmVuY2UpLgotICAgICAqCi0gICAgICogVGhpcyBpcyB0aGUgcmVhbCB0cmF2ZXJzYWwgbWV0aG9kLiBJdCdzIGNhbGxlZCBhZnRlciB3ZSd2ZSBkb25lIHdpdGgKLSAgICAgKiBhbGwgdGhlIGdsb2JhbCBkZWNsYXJhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gIGluZGV4Ci0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgdHJhdmVyc2VMb2NhbChYU1BhcnRpY2xlRGVjbCBwYXJ0aWNsZSwKLSAgICAgICAgICAgIEVsZW1lbnQgZWxtRGVjbCwKLSAgICAgICAgICAgIFhTRG9jdW1lbnRJbmZvIHNjaGVtYURvYywKLSAgICAgICAgICAgIFNjaGVtYUdyYW1tYXIgZ3JhbW1hciwKLSAgICAgICAgICAgIGludCBhbGxDb250ZXh0RmxhZ3MsCi0gICAgICAgICAgICBYU09iamVjdCBwYXJlbnQsCi0gICAgICAgICAgICBTdHJpbmdbXSBsb2NhbE5TRGVjbHMpIHsKLQotICAgICAgICBpZiAobG9jYWxOU0RlY2xzICE9IG51bGwpIHsKLSAgICAgICAgICAgIHNjaGVtYURvYy5mTmFtZXNwYWNlU3VwcG9ydC5zZXRFZmZlY3RpdmVDb250ZXh0KGxvY2FsTlNEZWNscyk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBHZW5lcmFsIEF0dHJpYnV0ZSBDaGVja2luZwotICAgICAgICBPYmplY3RbXSBhdHRyVmFsdWVzID0gZkF0dHJDaGVja2VyLmNoZWNrQXR0cmlidXRlcyhlbG1EZWNsLCBmYWxzZSwgc2NoZW1hRG9jKTsKLQotICAgICAgICBRTmFtZSByZWZBdHQgPSAoUU5hbWUpIGF0dHJWYWx1ZXNbWFNBdHRyaWJ1dGVDaGVja2VyLkFUVElEWF9SRUZdOwotICAgICAgICBYSW50ICBtaW5BdHQgPSAoWEludCkgIGF0dHJWYWx1ZXNbWFNBdHRyaWJ1dGVDaGVja2VyLkFUVElEWF9NSU5PQ0NVUlNdOwotICAgICAgICBYSW50ICBtYXhBdHQgPSAoWEludCkgIGF0dHJWYWx1ZXNbWFNBdHRyaWJ1dGVDaGVja2VyLkFUVElEWF9NQVhPQ0NVUlNdOwotCi0gICAgICAgIFhTRWxlbWVudERlY2wgZWxlbWVudCA9IG51bGw7Ci0gICAgICAgIFhTQW5ub3RhdGlvbkltcGwgYW5ub3RhdGlvbiA9IG51bGw7Ci0gICAgICAgIGlmIChlbG1EZWNsLmdldEF0dHJpYnV0ZU5vZGUoU2NoZW1hU3ltYm9scy5BVFRfUkVGKSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAocmVmQXR0ICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBlbGVtZW50ID0gKFhTRWxlbWVudERlY2wpZlNjaGVtYUhhbmRsZXIuZ2V0R2xvYmFsRGVjbChzY2hlbWFEb2MsIFhTREhhbmRsZXIuRUxFTUVOVF9UWVBFLCByZWZBdHQsIGVsbURlY2wpOwotCi0gICAgICAgICAgICAgICAgRWxlbWVudCBjaGlsZCA9IERPTVV0aWwuZ2V0Rmlyc3RDaGlsZEVsZW1lbnQoZWxtRGVjbCk7Ci0gICAgICAgICAgICAgICAgaWYgKGNoaWxkICE9IG51bGwgJiYgRE9NVXRpbC5nZXRMb2NhbE5hbWUoY2hpbGQpLmVxdWFscyhTY2hlbWFTeW1ib2xzLkVMVF9BTk5PVEFUSU9OKSkgewotICAgICAgICAgICAgICAgICAgICBhbm5vdGF0aW9uID0gdHJhdmVyc2VBbm5vdGF0aW9uRGVjbChjaGlsZCwgYXR0clZhbHVlcywgZmFsc2UsIHNjaGVtYURvYyk7Ci0gICAgICAgICAgICAgICAgICAgIGNoaWxkID0gRE9NVXRpbC5nZXROZXh0U2libGluZ0VsZW1lbnQoY2hpbGQpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHRleHQgPSBET01VdGlsLmdldFN5bnRoZXRpY0Fubm90YXRpb24oZWxtRGVjbCk7Ci0gICAgICAgICAgICAgICAgICAgIGlmICh0ZXh0ICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGFubm90YXRpb24gPSB0cmF2ZXJzZVN5bnRoZXRpY0Fubm90YXRpb24oZWxtRGVjbCwgdGV4dCwgYXR0clZhbHVlcywgZmFsc2UsIHNjaGVtYURvYyk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLy8gRWxlbWVudCBEZWNsYXJhdGlvbiBSZXByZXNlbnRhdGlvbiBPSwotICAgICAgICAgICAgICAgIC8vIDIgSWYgdGhlIGl0ZW0ncyBwYXJlbnQgaXMgbm90IDxzY2hlbWE+LCB0aGVuIGFsbCBvZiB0aGUgZm9sbG93aW5nIG11c3QgYmUgdHJ1ZToKLSAgICAgICAgICAgICAgICAvLyAyLjEgT25lIG9mIHJlZiBvciBuYW1lIG11c3QgYmUgcHJlc2VudCwgYnV0IG5vdCBib3RoLgotICAgICAgICAgICAgICAgIC8vIDIuMiBJZiByZWYgaXMgcHJlc2VudCwgdGhlbiBhbGwgb2YgPGNvbXBsZXhUeXBlPiwgPHNpbXBsZVR5cGU+LCA8a2V5PiwgPGtleXJlZj4sIDx1bmlxdWU+LCBuaWxsYWJsZSwgZGVmYXVsdCwgZml4ZWQsIGZvcm0sIGJsb2NrIGFuZCB0eXBlIG11c3QgYmUgYWJzZW50LCBpLmUuIG9ubHkgbWluT2NjdXJzLCBtYXhPY2N1cnMsIGlkIGFyZSBhbGxvd2VkIGluIGFkZGl0aW9uIHRvIHJlZiwgYWxvbmcgd2l0aCA8YW5ub3RhdGlvbj4uCi0gICAgICAgICAgICAgICAgaWYgKGNoaWxkICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoInNyYy1lbGVtZW50LjIuMiIsIG5ldyBPYmplY3RbXXtyZWZBdHQucmF3bmFtZSwgRE9NVXRpbC5nZXRMb2NhbE5hbWUoY2hpbGQpfSwgY2hpbGQpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgZWxlbWVudCA9IG51bGw7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBlbGVtZW50ID0gdHJhdmVyc2VOYW1lZEVsZW1lbnQoZWxtRGVjbCwgYXR0clZhbHVlcywgc2NoZW1hRG9jLCBncmFtbWFyLCBmYWxzZSwgcGFyZW50KTsKLSAgICAgICAgfQotCi0gICAgICAgIHBhcnRpY2xlLmZNaW5PY2N1cnMgPSBtaW5BdHQuaW50VmFsdWUoKTsKLSAgICAgICAgcGFydGljbGUuZk1heE9jY3VycyA9IG1heEF0dC5pbnRWYWx1ZSgpOwotICAgICAgICBpZiAoZWxlbWVudCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBwYXJ0aWNsZS5mVHlwZSA9IFhTUGFydGljbGVEZWNsLlBBUlRJQ0xFX0VMRU1FTlQ7Ci0gICAgICAgICAgICBwYXJ0aWNsZS5mVmFsdWUgPSBlbGVtZW50OwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgcGFydGljbGUuZlR5cGUgPSBYU1BhcnRpY2xlRGVjbC5QQVJUSUNMRV9FTVBUWTsKLSAgICAgICAgfQotICAgICAgICBpZiAocmVmQXR0ICE9IG51bGwpIHsKLSAgICAgICAgICAgIFhTT2JqZWN0TGlzdCBhbm5vdGF0aW9uczsKLSAgICAgICAgICAgIGlmIChhbm5vdGF0aW9uICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBhbm5vdGF0aW9ucyA9IG5ldyBYU09iamVjdExpc3RJbXBsKCk7Ci0gICAgICAgICAgICAgICAgKChYU09iamVjdExpc3RJbXBsKSBhbm5vdGF0aW9ucykuYWRkWFNPYmplY3QoYW5ub3RhdGlvbik7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIGFubm90YXRpb25zID0gWFNPYmplY3RMaXN0SW1wbC5FTVBUWV9MSVNUOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcGFydGljbGUuZkFubm90YXRpb25zID0gYW5ub3RhdGlvbnM7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBwYXJ0aWNsZS5mQW5ub3RhdGlvbnMgPSAoKGVsZW1lbnQgIT0gbnVsbCkgPyBlbGVtZW50LmZBbm5vdGF0aW9ucwotICAgICAgICAgICAgICAgICAgICA6IFhTT2JqZWN0TGlzdEltcGwuRU1QVFlfTElTVCk7Ci0gICAgICAgIH0KLSAgICAgICAgTG9uZyBkZWZhdWx0VmFscyA9IChMb25nKWF0dHJWYWx1ZXNbWFNBdHRyaWJ1dGVDaGVja2VyLkFUVElEWF9GUk9NREVGQVVMVF07Ci0gICAgICAgIGNoZWNrT2NjdXJyZW5jZXMocGFydGljbGUsIFNjaGVtYVN5bWJvbHMuRUxUX0VMRU1FTlQsCi0gICAgICAgICAgICAgICAgKEVsZW1lbnQpZWxtRGVjbC5nZXRQYXJlbnROb2RlKCksIGFsbENvbnRleHRGbGFncywKLSAgICAgICAgICAgICAgICBkZWZhdWx0VmFscy5sb25nVmFsdWUoKSk7Ci0KLSAgICAgICAgZkF0dHJDaGVja2VyLnJldHVybkF0dHJBcnJheShhdHRyVmFsdWVzLCBzY2hlbWFEb2MpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYXZlcnNlIGEgZ2xvYmFsbHkgZGVjbGFyZWQgZWxlbWVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSAgZWxtRGVjbAotICAgICAqIEBwYXJhbSAgc2NoZW1hRG9jCi0gICAgICogQHBhcmFtICBncmFtbWFyCi0gICAgICogQHJldHVybiB0aGUgZWxlbWVudCBkZWNsYXJhdGlvbgotICAgICAqLwotICAgIFhTRWxlbWVudERlY2wgdHJhdmVyc2VHbG9iYWwoRWxlbWVudCBlbG1EZWNsLAotICAgICAgICAgICAgWFNEb2N1bWVudEluZm8gc2NoZW1hRG9jLAotICAgICAgICAgICAgU2NoZW1hR3JhbW1hciBncmFtbWFyKSB7Ci0KLSAgICAgICAgLy8gR2VuZXJhbCBBdHRyaWJ1dGUgQ2hlY2tpbmcnCi0KLSAgICAgICAgT2JqZWN0W10gYXR0clZhbHVlcyA9IGZBdHRyQ2hlY2tlci5jaGVja0F0dHJpYnV0ZXMoZWxtRGVjbCwgdHJ1ZSwgc2NoZW1hRG9jKTsKLSAgICAgICAgWFNFbGVtZW50RGVjbCBlbGVtZW50ID0gdHJhdmVyc2VOYW1lZEVsZW1lbnQoZWxtRGVjbCwgYXR0clZhbHVlcywgc2NoZW1hRG9jLCBncmFtbWFyLCB0cnVlLCBudWxsKTsKLSAgICAgICAgZkF0dHJDaGVja2VyLnJldHVybkF0dHJBcnJheShhdHRyVmFsdWVzLCBzY2hlbWFEb2MpOwotICAgICAgICByZXR1cm4gZWxlbWVudDsKLQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYXZlcnNlIGEgZ2xvYmFsbHkgZGVjbGFyZWQgZWxlbWVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSAgZWxtRGVjbAotICAgICAqIEBwYXJhbSAgYXR0clZhbHVlcwotICAgICAqIEBwYXJhbSAgc2NoZW1hRG9jCi0gICAgICogQHBhcmFtICBncmFtbWFyCi0gICAgICogQHBhcmFtICBpc0dsb2JhbAotICAgICAqIEByZXR1cm4gdGhlIGVsZW1lbnQgZGVjbGFyYXRpb24KLSAgICAgKi8KLSAgICBYU0VsZW1lbnREZWNsIHRyYXZlcnNlTmFtZWRFbGVtZW50KEVsZW1lbnQgZWxtRGVjbCwKLSAgICAgICAgICAgIE9iamVjdFtdIGF0dHJWYWx1ZXMsCi0gICAgICAgICAgICBYU0RvY3VtZW50SW5mbyBzY2hlbWFEb2MsCi0gICAgICAgICAgICBTY2hlbWFHcmFtbWFyIGdyYW1tYXIsCi0gICAgICAgICAgICBib29sZWFuIGlzR2xvYmFsLAotICAgICAgICAgICAgWFNPYmplY3QgcGFyZW50KSB7Ci0KLSAgICAgICAgQm9vbGVhbiBhYnN0cmFjdEF0dCAgPSAoQm9vbGVhbikgYXR0clZhbHVlc1tYU0F0dHJpYnV0ZUNoZWNrZXIuQVRUSURYX0FCU1RSQUNUXTsKLSAgICAgICAgWEludCAgICBibG9ja0F0dCAgICAgPSAoWEludCkgICAgYXR0clZhbHVlc1tYU0F0dHJpYnV0ZUNoZWNrZXIuQVRUSURYX0JMT0NLXTsKLSAgICAgICAgU3RyaW5nICBkZWZhdWx0QXR0ICAgPSAoU3RyaW5nKSAgYXR0clZhbHVlc1tYU0F0dHJpYnV0ZUNoZWNrZXIuQVRUSURYX0RFRkFVTFRdOwotICAgICAgICBYSW50ICAgIGZpbmFsQXR0ICAgICA9IChYSW50KSAgICBhdHRyVmFsdWVzW1hTQXR0cmlidXRlQ2hlY2tlci5BVFRJRFhfRklOQUxdOwotICAgICAgICBTdHJpbmcgIGZpeGVkQXR0ICAgICA9IChTdHJpbmcpICBhdHRyVmFsdWVzW1hTQXR0cmlidXRlQ2hlY2tlci5BVFRJRFhfRklYRURdOwotICAgICAgICBYSW50ICAgIGZvcm1BdHQgICAgICA9IChYSW50KSAgICBhdHRyVmFsdWVzW1hTQXR0cmlidXRlQ2hlY2tlci5BVFRJRFhfRk9STV07Ci0gICAgICAgIFN0cmluZyAgbmFtZUF0dCAgICAgID0gKFN0cmluZykgIGF0dHJWYWx1ZXNbWFNBdHRyaWJ1dGVDaGVja2VyLkFUVElEWF9OQU1FXTsKLSAgICAgICAgQm9vbGVhbiBuaWxsYWJsZUF0dCAgPSAoQm9vbGVhbikgYXR0clZhbHVlc1tYU0F0dHJpYnV0ZUNoZWNrZXIuQVRUSURYX05JTExBQkxFXTsKLSAgICAgICAgUU5hbWUgICBzdWJHcm91cEF0dCAgPSAoUU5hbWUpICAgYXR0clZhbHVlc1tYU0F0dHJpYnV0ZUNoZWNrZXIuQVRUSURYX1NVQlNHUk9VUF07Ci0gICAgICAgIFFOYW1lICAgdHlwZUF0dCAgICAgID0gKFFOYW1lKSAgIGF0dHJWYWx1ZXNbWFNBdHRyaWJ1dGVDaGVja2VyLkFUVElEWF9UWVBFXTsKLQotICAgICAgICAvLyBTdGVwIDE6IGdldCBkZWNsYXJhdGlvbiBpbmZvcm1hdGlvbgotCi0gICAgICAgIFhTRWxlbWVudERlY2wgZWxlbWVudCA9IG51bGw7Ci0gICAgICAgIGlmIChmU2NoZW1hSGFuZGxlci5mRGVjbFBvb2wgIT1udWxsKSB7Ci0gICAgICAgICAgICBlbGVtZW50ID0gZlNjaGVtYUhhbmRsZXIuZkRlY2xQb29sLmdldEVsZW1lbnREZWNsKCk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBlbGVtZW50ID0gbmV3IFhTRWxlbWVudERlY2woKTsKLSAgICAgICAgfQotICAgICAgICAvLyBnZXQgJ25hbWUnCi0gICAgICAgIGlmIChuYW1lQXR0ICE9IG51bGwpCi0gICAgICAgICAgICBlbGVtZW50LmZOYW1lID0gZlN5bWJvbFRhYmxlLmFkZFN5bWJvbChuYW1lQXR0KTsKLQotICAgICAgICAvLyBnZXQgJ3RhcmdldCBuYW1lc3BhY2UnCi0gICAgICAgIGlmIChpc0dsb2JhbCkgewotICAgICAgICAgICAgZWxlbWVudC5mVGFyZ2V0TmFtZXNwYWNlID0gc2NoZW1hRG9jLmZUYXJnZXROYW1lc3BhY2U7Ci0gICAgICAgICAgICBlbGVtZW50LnNldElzR2xvYmFsKCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBpZiAocGFyZW50IGluc3RhbmNlb2YgWFNDb21wbGV4VHlwZURlY2wpCi0gICAgICAgICAgICAgICAgZWxlbWVudC5zZXRJc0xvY2FsKChYU0NvbXBsZXhUeXBlRGVjbClwYXJlbnQpOwotCi0gICAgICAgICAgICBpZiAoZm9ybUF0dCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGZvcm1BdHQuaW50VmFsdWUoKSA9PSBTY2hlbWFTeW1ib2xzLkZPUk1fUVVBTElGSUVEKQotICAgICAgICAgICAgICAgICAgICBlbGVtZW50LmZUYXJnZXROYW1lc3BhY2UgPSBzY2hlbWFEb2MuZlRhcmdldE5hbWVzcGFjZTsKLSAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuZlRhcmdldE5hbWVzcGFjZSA9IG51bGw7Ci0gICAgICAgICAgICB9IGVsc2UgaWYgKHNjaGVtYURvYy5mQXJlTG9jYWxFbGVtZW50c1F1YWxpZmllZCkgewotICAgICAgICAgICAgICAgIGVsZW1lbnQuZlRhcmdldE5hbWVzcGFjZSA9IHNjaGVtYURvYy5mVGFyZ2V0TmFtZXNwYWNlOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBlbGVtZW50LmZUYXJnZXROYW1lc3BhY2UgPSBudWxsOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gZ2V0ICdibG9jaycsICdmaW5hbCcsICduaWxsYWJsZScsICdhYnN0cmFjdCcKLSAgICAgICAgIGlmIChibG9ja0F0dCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgLy8gdXNlIGRlZmF1bHRzCi0gICAgICAgICAgICAgZWxlbWVudC5mQmxvY2sgPSBzY2hlbWFEb2MuZkJsb2NrRGVmYXVsdDsKLSAgICAgICAgICAgICAvLyBkaXNjYXJkIHZhbGlkIEJsb2NrICdEZWZhdWx0JyB2YWx1ZXMgdGhhdCBhcmUgaW52YWxpZCBmb3IgQmxvY2sKLSAgICAgICAgICAgICAvLyByZXNwZWN0ICNhbGwKLSAgICAgICAgICAgICBpZiAoZWxlbWVudC5mQmxvY2sgIT0gWFNDb25zdGFudHMuREVSSVZBVElPTl9BTEwpIHsKLSAgICAgICAgICAgICAgICAgZWxlbWVudC5mQmxvY2sgJj0gKFhTQ29uc3RhbnRzLkRFUklWQVRJT05fRVhURU5TSU9OIHwgWFNDb25zdGFudHMuREVSSVZBVElPTl9SRVNUUklDVElPTiB8IFhTQ29uc3RhbnRzLkRFUklWQVRJT05fU1VCU1RJVFVUSU9OKTsKLSAgICAgICAgICAgICB9Ci0gICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgIC8vIHVzZSBzcGVjaWZpZWQgdmFsdWVzCi0gICAgICAgICAgICAgZWxlbWVudC5mQmxvY2sgPSBibG9ja0F0dC5zaG9ydFZhbHVlKCk7Ci0gICAgICAgICAgICAgLy8gY2hlY2sgZm9yIHZhbGlkIHZhbHVlcwotICAgICAgICAgICAgIGlmICgoZWxlbWVudC5mQmxvY2sgIT0gWFNDb25zdGFudHMuREVSSVZBVElPTl9BTEwpCi0gICAgICAgICAgICAgICAgICYmCi0gICAgICAgICAgICAgICAgICgoZWxlbWVudC5mQmxvY2sgfCBYU0NvbnN0YW50cy5ERVJJVkFUSU9OX0VYVEVOU0lPTl9SRVNUUklDVElPTl9TVUJTVElUSU9OKQotICAgICAgICAgICAgICAgICAgICAgIT0gWFNDb25zdGFudHMuREVSSVZBVElPTl9FWFRFTlNJT05fUkVTVFJJQ1RJT05fU1VCU1RJVElPTikpIHsKLSAgICAgICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoCi0gICAgICAgICAgICAgICAgICAgICAgICAgInM0cy1hdHQtaW52YWxpZC12YWx1ZSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde2VsZW1lbnQuZk5hbWUsICJibG9jayIsICJtdXN0IGJlICgjYWxsIHwgTGlzdCBvZiAoZXh0ZW5zaW9uIHwgcmVzdHJpY3Rpb24gfCBzdWJzdGl0dXRpb24pKSJ9LAotICAgICAgICAgICAgICAgICAgICAgICAgIGVsbURlY2wpOwotICAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGVsZW1lbnQuZkZpbmFsID0gZmluYWxBdHQgPT0gbnVsbCA/IHNjaGVtYURvYy5mRmluYWxEZWZhdWx0IDogZmluYWxBdHQuc2hvcnRWYWx1ZSgpOwotICAgICAgICAvLyBkaXNjYXJkIHZhbGlkIEZpbmFsICdEZWZhdWx0JyB2YWx1ZXMgdGhhdCBhcmUgaW52YWxpZCBmb3IgRmluYWwKLSAgICAgICAgZWxlbWVudC5mRmluYWwgJj0gKFhTQ29uc3RhbnRzLkRFUklWQVRJT05fRVhURU5TSU9OIHwgWFNDb25zdGFudHMuREVSSVZBVElPTl9SRVNUUklDVElPTik7Ci0KLSAgICAgICAgaWYgKG5pbGxhYmxlQXR0LmJvb2xlYW5WYWx1ZSgpKQotICAgICAgICAgICAgZWxlbWVudC5zZXRJc05pbGxhYmxlKCk7Ci0gICAgICAgIGlmIChhYnN0cmFjdEF0dCAhPSBudWxsICYmIGFic3RyYWN0QXR0LmJvb2xlYW5WYWx1ZSgpKQotICAgICAgICAgICAgZWxlbWVudC5zZXRJc0Fic3RyYWN0KCk7Ci0KLSAgICAgICAgLy8gZ2V0ICd2YWx1ZSBjb25zdHJhaW50JwotICAgICAgICBpZiAoZml4ZWRBdHQgIT0gbnVsbCkgewotICAgICAgICAgICAgZWxlbWVudC5mRGVmYXVsdCA9IG5ldyBWYWxpZGF0ZWRJbmZvKCk7Ci0gICAgICAgICAgICBlbGVtZW50LmZEZWZhdWx0Lm5vcm1hbGl6ZWRWYWx1ZSA9IGZpeGVkQXR0OwotICAgICAgICAgICAgZWxlbWVudC5zZXRDb25zdHJhaW50VHlwZShYU0NvbnN0YW50cy5WQ19GSVhFRCk7Ci0gICAgICAgIH0gZWxzZSBpZiAoZGVmYXVsdEF0dCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBlbGVtZW50LmZEZWZhdWx0ID0gbmV3IFZhbGlkYXRlZEluZm8oKTsKLSAgICAgICAgICAgIGVsZW1lbnQuZkRlZmF1bHQubm9ybWFsaXplZFZhbHVlID0gZGVmYXVsdEF0dDsKLSAgICAgICAgICAgIGVsZW1lbnQuc2V0Q29uc3RyYWludFR5cGUoWFNDb25zdGFudHMuVkNfREVGQVVMVCk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBlbGVtZW50LnNldENvbnN0cmFpbnRUeXBlKFhTQ29uc3RhbnRzLlZDX05PTkUpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gZ2V0ICdzdWJzdGl0dXRpb25Hcm91cCBhZmZpbGlhdGlvbicKLSAgICAgICAgaWYgKHN1Ykdyb3VwQXR0ICE9IG51bGwpIHsKLSAgICAgICAgICAgIGVsZW1lbnQuZlN1Ykdyb3VwID0gKFhTRWxlbWVudERlY2wpZlNjaGVtYUhhbmRsZXIuZ2V0R2xvYmFsRGVjbChzY2hlbWFEb2MsIFhTREhhbmRsZXIuRUxFTUVOVF9UWVBFLCBzdWJHcm91cEF0dCwgZWxtRGVjbCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBnZXQgJ2Fubm90YXRpb24nCi0gICAgICAgIEVsZW1lbnQgY2hpbGQgPSBET01VdGlsLmdldEZpcnN0Q2hpbGRFbGVtZW50KGVsbURlY2wpOwotICAgICAgICBYU0Fubm90YXRpb25JbXBsIGFubm90YXRpb24gPSBudWxsOwotICAgICAgICBpZihjaGlsZCAhPSBudWxsICYmIERPTVV0aWwuZ2V0TG9jYWxOYW1lKGNoaWxkKS5lcXVhbHMoU2NoZW1hU3ltYm9scy5FTFRfQU5OT1RBVElPTikpIHsKLSAgICAgICAgICAgIGFubm90YXRpb24gPSB0cmF2ZXJzZUFubm90YXRpb25EZWNsKGNoaWxkLCBhdHRyVmFsdWVzLCBmYWxzZSwgc2NoZW1hRG9jKTsKLSAgICAgICAgICAgIGNoaWxkID0gRE9NVXRpbC5nZXROZXh0U2libGluZ0VsZW1lbnQoY2hpbGQpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgU3RyaW5nIHRleHQgPSBET01VdGlsLmdldFN5bnRoZXRpY0Fubm90YXRpb24oZWxtRGVjbCk7Ci0gICAgICAgICAgICBpZiAodGV4dCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgYW5ub3RhdGlvbiA9IHRyYXZlcnNlU3ludGhldGljQW5ub3RhdGlvbihlbG1EZWNsLCB0ZXh0LCBhdHRyVmFsdWVzLCBmYWxzZSwgc2NoZW1hRG9jKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIFhTT2JqZWN0TGlzdCBhbm5vdGF0aW9uczsKLSAgICAgICAgaWYgKGFubm90YXRpb24gIT0gbnVsbCkgewotICAgICAgICAgICAgYW5ub3RhdGlvbnMgPSBuZXcgWFNPYmplY3RMaXN0SW1wbCgpOwotICAgICAgICAgICAgKChYU09iamVjdExpc3RJbXBsKWFubm90YXRpb25zKS5hZGRYU09iamVjdCAoYW5ub3RhdGlvbik7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBhbm5vdGF0aW9ucyA9IFhTT2JqZWN0TGlzdEltcGwuRU1QVFlfTElTVDsKLSAgICAgICAgfQotICAgICAgICBlbGVtZW50LmZBbm5vdGF0aW9ucyA9IGFubm90YXRpb25zOwotCi0gICAgICAgIC8vIGdldCAndHlwZSBkZWZpbml0aW9uJwotICAgICAgICBYU1R5cGVEZWZpbml0aW9uIGVsZW1lbnRUeXBlID0gbnVsbDsKLSAgICAgICAgYm9vbGVhbiBoYXZlQW5vblR5cGUgPSBmYWxzZTsKLQotICAgICAgICAvLyBIYW5kbGUgQW5vbnltb3VzIHR5cGUgaWYgdGhlcmUgaXMgb25lCi0gICAgICAgIGlmIChjaGlsZCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBTdHJpbmcgY2hpbGROYW1lID0gRE9NVXRpbC5nZXRMb2NhbE5hbWUoY2hpbGQpOwotCi0gICAgICAgICAgICBpZiAoY2hpbGROYW1lLmVxdWFscyhTY2hlbWFTeW1ib2xzLkVMVF9DT01QTEVYVFlQRSkpIHsKLSAgICAgICAgICAgICAgICBlbGVtZW50VHlwZSA9IGZTY2hlbWFIYW5kbGVyLmZDb21wbGV4VHlwZVRyYXZlcnNlci50cmF2ZXJzZUxvY2FsKGNoaWxkLCBzY2hlbWFEb2MsIGdyYW1tYXIpOwotICAgICAgICAgICAgICAgIGhhdmVBbm9uVHlwZSA9IHRydWU7Ci0gICAgICAgICAgICAgICAgY2hpbGQgPSBET01VdGlsLmdldE5leHRTaWJsaW5nRWxlbWVudChjaGlsZCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChjaGlsZE5hbWUuZXF1YWxzKFNjaGVtYVN5bWJvbHMuRUxUX1NJTVBMRVRZUEUpKSB7Ci0gICAgICAgICAgICAgICAgZWxlbWVudFR5cGUgPSBmU2NoZW1hSGFuZGxlci5mU2ltcGxlVHlwZVRyYXZlcnNlci50cmF2ZXJzZUxvY2FsKGNoaWxkLCBzY2hlbWFEb2MsIGdyYW1tYXIpOwotICAgICAgICAgICAgICAgIGhhdmVBbm9uVHlwZSA9IHRydWU7Ci0gICAgICAgICAgICAgICAgY2hpbGQgPSBET01VdGlsLmdldE5leHRTaWJsaW5nRWxlbWVudChjaGlsZCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBIYW5kbGVyIHR5cGUgYXR0cmlidXRlCi0gICAgICAgIGlmIChlbGVtZW50VHlwZSA9PSBudWxsICYmIHR5cGVBdHQgIT0gbnVsbCkgewotICAgICAgICAgICAgZWxlbWVudFR5cGUgPSAoWFNUeXBlRGVmaW5pdGlvbilmU2NoZW1hSGFuZGxlci5nZXRHbG9iYWxEZWNsKHNjaGVtYURvYywgWFNESGFuZGxlci5UWVBFREVDTF9UWVBFLCB0eXBlQXR0LCBlbG1EZWNsKTsKLSAgICAgICAgICAgIGlmIChlbGVtZW50VHlwZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZWxlbWVudC5mVW5yZXNvbHZlZFR5cGVOYW1lID0gdHlwZUF0dDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIEdldCBpdCBmcm9tIHRoZSBzdWJzdGl0dXRpb25Hcm91cCBkZWNsYXJhdGlvbgotICAgICAgICBpZiAoZWxlbWVudFR5cGUgPT0gbnVsbCAmJiBlbGVtZW50LmZTdWJHcm91cCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBlbGVtZW50VHlwZSA9IGVsZW1lbnQuZlN1Ykdyb3VwLmZUeXBlOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKGVsZW1lbnRUeXBlID09IG51bGwpIHsKLSAgICAgICAgICAgIGVsZW1lbnRUeXBlID0gU2NoZW1hR3JhbW1hci5mQW55VHlwZTsKLSAgICAgICAgfQotCi0gICAgICAgIGVsZW1lbnQuZlR5cGUgPSBlbGVtZW50VHlwZTsKLQotICAgICAgICAvLyBnZXQgJ2lkZW50aXR5IGNvbnN0cmFpbnQnCi0KLSAgICAgICAgLy8gc2VlIGlmIHRoZXJlJ3Mgc29tZXRoaW5nIGhlcmU7IGl0IGhhZCBiZXR0ZXIgYmUga2V5LCBrZXlyZWYgb3IgdW5pcXVlLgotICAgICAgICBpZiAoY2hpbGQgIT0gbnVsbCkgewotICAgICAgICAgICAgU3RyaW5nIGNoaWxkTmFtZSA9IERPTVV0aWwuZ2V0TG9jYWxOYW1lKGNoaWxkKTsKLSAgICAgICAgICAgIHdoaWxlIChjaGlsZCAhPSBudWxsICYmCi0gICAgICAgICAgICAgICAgICAgIChjaGlsZE5hbWUuZXF1YWxzKFNjaGVtYVN5bWJvbHMuRUxUX0tFWSkgfHwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZE5hbWUuZXF1YWxzKFNjaGVtYVN5bWJvbHMuRUxUX0tFWVJFRikgfHwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZE5hbWUuZXF1YWxzKFNjaGVtYVN5bWJvbHMuRUxUX1VOSVFVRSkpKSB7Ci0KLSAgICAgICAgICAgICAgICBpZiAoY2hpbGROYW1lLmVxdWFscyhTY2hlbWFTeW1ib2xzLkVMVF9LRVkpIHx8Ci0gICAgICAgICAgICAgICAgICAgICAgICBjaGlsZE5hbWUuZXF1YWxzKFNjaGVtYVN5bWJvbHMuRUxUX1VOSVFVRSkpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gbmVlZCB0byBzZXQgPGtleT4vPHVuaXF1ZT4gdG8gaGlkZGVuIGJlZm9yZSB0cmF2ZXJzaW5nIGl0LAotICAgICAgICAgICAgICAgICAgICAvLyBiZWNhdXNlIGl0IGhhcyBnbG9iYWwgc2NvcGUKLSAgICAgICAgICAgICAgICAgICAgRE9NVXRpbC5zZXRIaWRkZW4oY2hpbGQsIGZTY2hlbWFIYW5kbGVyLmZIaWRkZW5Ob2Rlcyk7Ci0gICAgICAgICAgICAgICAgICAgIGZTY2hlbWFIYW5kbGVyLmZVbmlxdWVPcktleVRyYXZlcnNlci50cmF2ZXJzZShjaGlsZCwgZWxlbWVudCwgc2NoZW1hRG9jLCBncmFtbWFyKTsKLSAgICAgICAgICAgICAgICAgICAgaWYoRE9NVXRpbC5nZXRBdHRyVmFsdWUoY2hpbGQsIFNjaGVtYVN5bWJvbHMuQVRUX05BTUUpLmxlbmd0aCgpICE9IDAgKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmU2NoZW1hSGFuZGxlci5jaGVja0ZvckR1cGxpY2F0ZU5hbWVzKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoc2NoZW1hRG9jLmZUYXJnZXROYW1lc3BhY2UgPT0gbnVsbCkgPyAiLCIrRE9NVXRpbC5nZXRBdHRyVmFsdWUoY2hpbGQsIFNjaGVtYVN5bWJvbHMuQVRUX05BTUUpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBzY2hlbWFEb2MuZlRhcmdldE5hbWVzcGFjZSsiLCIrIERPTVV0aWwuZ2V0QXR0clZhbHVlKGNoaWxkLCBTY2hlbWFTeW1ib2xzLkFUVF9OQU1FKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmU2NoZW1hSGFuZGxlci5BVFRSSUJVVEVfVFlQRSwgZlNjaGVtYUhhbmRsZXIuZ2V0SURSZWdpc3RyeSgpLCBmU2NoZW1hSGFuZGxlci5nZXRJRFJlZ2lzdHJ5X3N1YigpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkLCBzY2hlbWFEb2MpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjaGlsZE5hbWUuZXF1YWxzKFNjaGVtYVN5bWJvbHMuRUxUX0tFWVJFRikpIHsKLSAgICAgICAgICAgICAgICAgICAgZlNjaGVtYUhhbmRsZXIuc3RvcmVLZXlSZWYoY2hpbGQsIHNjaGVtYURvYywgZWxlbWVudCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGNoaWxkID0gRE9NVXRpbC5nZXROZXh0U2libGluZ0VsZW1lbnQoY2hpbGQpOwotICAgICAgICAgICAgICAgIGlmIChjaGlsZCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGNoaWxkTmFtZSA9IERPTVV0aWwuZ2V0TG9jYWxOYW1lKGNoaWxkKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBTdGVwIDM6IGNoZWNrIGFnYWluc3Qgc2NoZW1hIGZvciBzY2hlbWFzCi0KLSAgICAgICAgLy8gcmVxdWlyZWQgYXR0cmlidXRlcwotICAgICAgICBpZiAobmFtZUF0dCA9PSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAoaXNHbG9iYWwpCi0gICAgICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoInM0cy1hdHQtbXVzdC1hcHBlYXIiLCBuZXcgT2JqZWN0W117U2NoZW1hU3ltYm9scy5FTFRfRUxFTUVOVCwgU2NoZW1hU3ltYm9scy5BVFRfTkFNRX0sIGVsbURlY2wpOwotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKCJzcmMtZWxlbWVudC4yLjEiLCBudWxsLCBlbG1EZWNsKTsKLSAgICAgICAgICAgIG5hbWVBdHQgPSBOT19OQU1FOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gZWxlbWVudAotICAgICAgICBpZiAoY2hpbGQgIT0gbnVsbCkgewotICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoInM0cy1lbHQtbXVzdC1tYXRjaC4xIiwgbmV3IE9iamVjdFtde25hbWVBdHQsICIoYW5ub3RhdGlvbj8sIChzaW1wbGVUeXBlIHwgY29tcGxleFR5cGUpPywgKHVuaXF1ZSB8IGtleSB8IGtleXJlZikqKSkiLCBET01VdGlsLmdldExvY2FsTmFtZShjaGlsZCl9LCBjaGlsZCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBTdGVwIDQ6IGNoZWNrIDMuMy4zIGNvbnN0cmFpbnRzCi0KLSAgICAgICAgLy8gc3JjLWVsZW1lbnQKLQotICAgICAgICAvLyAxIGRlZmF1bHQgYW5kIGZpeGVkIG11c3Qgbm90IGJvdGggYmUgcHJlc2VudC4KLSAgICAgICAgaWYgKGRlZmF1bHRBdHQgIT0gbnVsbCAmJiBmaXhlZEF0dCAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcigic3JjLWVsZW1lbnQuMSIsIG5ldyBPYmplY3RbXXtuYW1lQXR0fSwgZWxtRGVjbCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyAyIElmIHRoZSBpdGVtJ3MgcGFyZW50IGlzIG5vdCA8c2NoZW1hPiwgdGhlbiBhbGwgb2YgdGhlIGZvbGxvd2luZyBtdXN0IGJlIHRydWU6Ci0gICAgICAgIC8vIDIuMSBPbmUgb2YgcmVmIG9yIG5hbWUgbXVzdCBiZSBwcmVzZW50LCBidXQgbm90IGJvdGguCi0gICAgICAgIC8vIFRoaXMgaXMgY2hlY2tlZCBpbiBYU0F0dHJpYnV0ZUNoZWNrZXIKLQotICAgICAgICAvLyAyLjIgSWYgcmVmIGlzIHByZXNlbnQsIHRoZW4gYWxsIG9mIDxjb21wbGV4VHlwZT4sIDxzaW1wbGVUeXBlPiwgPGtleT4sIDxrZXlyZWY+LCA8dW5pcXVlPiwgbmlsbGFibGUsIGRlZmF1bHQsIGZpeGVkLCBmb3JtLCBibG9jayBhbmQgdHlwZSBtdXN0IGJlIGFic2VudCwgaS5lLiBvbmx5IG1pbk9jY3VycywgbWF4T2NjdXJzLCBpZCBhcmUgYWxsb3dlZCBpbiBhZGRpdGlvbiB0byByZWYsIGFsb25nIHdpdGggPGFubm90YXRpb24+LgotICAgICAgICAvLyBBdHRyaWJ1dGVzIGFyZSBjaGVja2VkIGluIFhTQXR0cmlidXRlQ2hlY2tlciwgZWxlbWVudHMgYXJlIGNoZWNrZWQgaW4gInRyYXZlcnNlIiBtZXRob2QKLQotICAgICAgICAvLyAzIHR5cGUgYW5kIGVpdGhlciA8c2ltcGxlVHlwZT4gb3IgPGNvbXBsZXhUeXBlPiBhcmUgbXV0dWFsbHkgZXhjbHVzaXZlLgotICAgICAgICBpZiAoaGF2ZUFub25UeXBlICYmICh0eXBlQXR0ICE9IG51bGwpKSB7Ci0gICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcigic3JjLWVsZW1lbnQuMyIsIG5ldyBPYmplY3RbXXtuYW1lQXR0fSwgZWxtRGVjbCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBTdGVwIDU6IGNoZWNrIDMuMy42IGNvbnN0cmFpbnRzCi0gICAgICAgIC8vIGNoZWNrIGZvciBOT1RBVElPTiB0eXBlCi0gICAgICAgIGNoZWNrTm90YXRpb25UeXBlKG5hbWVBdHQsIGVsZW1lbnRUeXBlLCBlbG1EZWNsKTsKLQotICAgICAgICAvLyBlLXByb3BzLWNvcnJlY3QKLQotICAgICAgICAvLyAyIElmIHRoZXJlIGlzIGEge3ZhbHVlIGNvbnN0cmFpbnR9LCB0aGUgY2Fub25pY2FsIGxleGljYWwgcmVwcmVzZW50YXRpb24gb2YgaXRzIHZhbHVlIG11c3QgYmUgdmFsaWQgd2l0aCByZXNwZWN0IHRvIHRoZSB7dHlwZSBkZWZpbml0aW9ufSBhcyBkZWZpbmVkIGluIEVsZW1lbnQgRGVmYXVsdCBWYWxpZCAoSW1tZWRpYXRlKSAoMy4zLjYpLgotICAgICAgICBpZiAoZWxlbWVudC5mRGVmYXVsdCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmVmFsaWRhdGlvblN0YXRlLnNldE5hbWVzcGFjZVN1cHBvcnQoc2NoZW1hRG9jLmZOYW1lc3BhY2VTdXBwb3J0KTsKLSAgICAgICAgICAgIGlmIChYU0NvbnN0cmFpbnRzLkVsZW1lbnREZWZhdWx0VmFsaWRJbW1lZGlhdGUoZWxlbWVudC5mVHlwZSwgZWxlbWVudC5mRGVmYXVsdC5ub3JtYWxpemVkVmFsdWUsIGZWYWxpZGF0aW9uU3RhdGUsIGVsZW1lbnQuZkRlZmF1bHQpID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvciAoImUtcHJvcHMtY29ycmVjdC4yIiwgbmV3IE9iamVjdFtde25hbWVBdHQsIGVsZW1lbnQuZkRlZmF1bHQubm9ybWFsaXplZFZhbHVlfSwgZWxtRGVjbCk7Ci0gICAgICAgICAgICAgICAgZWxlbWVudC5mRGVmYXVsdCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgZWxlbWVudC5zZXRDb25zdHJhaW50VHlwZShYU0NvbnN0YW50cy5WQ19OT05FKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIDQgSWYgdGhlcmUgaXMgYW4ge3N1YnN0aXR1dGlvbiBncm91cCBhZmZpbGlhdGlvbn0sIHRoZSB7dHlwZSBkZWZpbml0aW9ufSBvZiB0aGUgZWxlbWVudCBkZWNsYXJhdGlvbiBtdXN0IGJlIHZhbGlkbHkgZGVyaXZlZCBmcm9tIHRoZSB7dHlwZSBkZWZpbml0aW9ufSBvZiB0aGUge3N1YnN0aXR1dGlvbiBncm91cCBhZmZpbGlhdGlvbn0sIGdpdmVuIHRoZSB2YWx1ZSBvZiB0aGUge3N1YnN0aXR1dGlvbiBncm91cCBleGNsdXNpb25zfSBvZiB0aGUge3N1YnN0aXR1dGlvbiBncm91cCBhZmZpbGlhdGlvbn0sIGFzIGRlZmluZWQgaW4gVHlwZSBEZXJpdmF0aW9uIE9LIChDb21wbGV4KSAoMy40LjYpIChpZiB0aGUge3R5cGUgZGVmaW5pdGlvbn0gaXMgY29tcGxleCkgb3IgYXMgZGVmaW5lZCBpbiBUeXBlIERlcml2YXRpb24gT0sgKFNpbXBsZSkgKDMuMTQuNikgKGlmIHRoZSB7dHlwZSBkZWZpbml0aW9ufSBpcyBzaW1wbGUpLgotICAgICAgICBpZiAoZWxlbWVudC5mU3ViR3JvdXAgIT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKCFYU0NvbnN0cmFpbnRzLmNoZWNrVHlwZURlcml2YXRpb25PayhlbGVtZW50LmZUeXBlLCBlbGVtZW50LmZTdWJHcm91cC5mVHlwZSwgZWxlbWVudC5mU3ViR3JvdXAuZkZpbmFsKSkgewotICAgICAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yICgiZS1wcm9wcy1jb3JyZWN0LjQiLCBuZXcgT2JqZWN0W117bmFtZUF0dCwgc3ViR3JvdXBBdHQucHJlZml4KyI6IitzdWJHcm91cEF0dC5sb2NhbHBhcnR9LCBlbG1EZWNsKTsKLSAgICAgICAgICAgICAgICBlbGVtZW50LmZTdWJHcm91cCA9IG51bGw7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyA1IElmIHRoZSB7dHlwZSBkZWZpbml0aW9ufSBvciB7dHlwZSBkZWZpbml0aW9ufSdzIHtjb250ZW50IHR5cGV9IGlzIG9yIGlzIGRlcml2ZWQgZnJvbSBJRCB0aGVuIHRoZXJlIG11c3Qgbm90IGJlIGEge3ZhbHVlIGNvbnN0cmFpbnR9LgotICAgICAgICBpZiAoZWxlbWVudC5mRGVmYXVsdCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAoKGVsZW1lbnRUeXBlLmdldFR5cGVDYXRlZ29yeSgpID09IFhTVHlwZURlZmluaXRpb24uU0lNUExFX1RZUEUgJiYKLSAgICAgICAgICAgICAgICAgICAgKChYU1NpbXBsZVR5cGUpZWxlbWVudFR5cGUpLmlzSURUeXBlKCkpIHx8Ci0gICAgICAgICAgICAgICAgICAgIChlbGVtZW50VHlwZS5nZXRUeXBlQ2F0ZWdvcnkoKSA9PSBYU1R5cGVEZWZpbml0aW9uLkNPTVBMRVhfVFlQRSAmJgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoWFNDb21wbGV4VHlwZURlY2wpZWxlbWVudFR5cGUpLmNvbnRhaW5zVHlwZUlEKCkpKSB7Ci0gICAgICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IgKCJlLXByb3BzLWNvcnJlY3QuNSIsIG5ldyBPYmplY3RbXXtlbGVtZW50LmZOYW1lfSwgZWxtRGVjbCk7Ci0gICAgICAgICAgICAgICAgZWxlbWVudC5mRGVmYXVsdCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgZWxlbWVudC5zZXRDb25zdHJhaW50VHlwZShYU0NvbnN0YW50cy5WQ19OT05FKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIEVsZW1lbnQgd2l0aG91dCBhIG5hbWUuIFJldHVybiBudWxsLgotICAgICAgICBpZiAoZWxlbWVudC5mTmFtZSA9PSBudWxsKQotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0KLSAgICAgICAgLy8gU3RlcCA1OiByZWdpc3RlciB0aGUgZWxlbWVudCBkZWNsIHRvIHRoZSBncmFtbWFyCi0gICAgICAgIGlmIChpc0dsb2JhbCkgewotICAgICAgICAgICAgZ3JhbW1hci5hZGRHbG9iYWxFbGVtZW50RGVjbEFsbChlbGVtZW50KTsKLQotICAgICAgICAgICAgaWYgKGdyYW1tYXIuZ2V0R2xvYmFsRWxlbWVudERlY2woZWxlbWVudC5mTmFtZSkgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGdyYW1tYXIuYWRkR2xvYmFsRWxlbWVudERlY2woZWxlbWVudCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIHdlIGFsc28gYWRkIHRoZSBlbGVtZW50IHRvIHRoZSB0b2xlcmF0ZSBkdXBsaWNhdGVzIGxpc3QgYXMgd2VsbAotICAgICAgICAgICAgZmluYWwgU3RyaW5nIGxvYyA9IGZTY2hlbWFIYW5kbGVyLnNjaGVtYURvY3VtZW50MlN5c3RlbUlkKHNjaGVtYURvYyk7Ci0gICAgICAgICAgICBmaW5hbCBYU0VsZW1lbnREZWNsIGVsZW1lbnQyID0gZ3JhbW1hci5nZXRHbG9iYWxFbGVtZW50RGVjbChlbGVtZW50LmZOYW1lLCBsb2MpOwotICAgICAgICAgICAgaWYgKGVsZW1lbnQyID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBncmFtbWFyLmFkZEdsb2JhbEVsZW1lbnREZWNsKGVsZW1lbnQsIGxvYyk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIGlmIHdlIGFyZSB0b2xlcmF0aW5nIGR1cGxpY2F0ZXMsIGFuZCB3ZSBmb3VuZCBhIGR1cGxpY2F0ZSBkZWNsYXJhdGlvbgotICAgICAgICAgICAgLy8gdXNlIHRoZSBkdXBsaWNhdGUgb25lIGluc3RlYWQKLSAgICAgICAgICAgIGlmIChmU2NoZW1hSGFuZGxlci5mVG9sZXJhdGVEdXBsaWNhdGVzKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGVsZW1lbnQyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgZWxlbWVudCA9IGVsZW1lbnQyOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBmU2NoZW1hSGFuZGxlci5hZGRHbG9iYWxFbGVtZW50RGVjbChlbGVtZW50KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBlbGVtZW50OwotICAgIH0KLQotICAgIHZvaWQgcmVzZXQoU3ltYm9sVGFibGUgc3ltYm9sVGFibGUsIGJvb2xlYW4gdmFsaWRhdGVBbm5vdGF0aW9ucywgTG9jYWxlIGxvY2FsZSkgewotICAgICAgICBzdXBlci5yZXNldChzeW1ib2xUYWJsZSwgdmFsaWRhdGVBbm5vdGF0aW9ucywgbG9jYWxlKTsKLSAgICAgICAgZkRlZmVyVHJhdmVyc2luZ0xvY2FsRWxlbWVudHMgPSB0cnVlOwotICAgIH0gLy8gcmVzZXQoKQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL3RyYXZlcnNlcnMvWFNER3JvdXBUcmF2ZXJzZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvdHJhdmVyc2Vycy9YU0RHcm91cFRyYXZlcnNlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA5MTVmNDgyLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvdHJhdmVyc2Vycy9YU0RHcm91cFRyYXZlcnNlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjY5ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy50cmF2ZXJzZXJzOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlNjaGVtYUdyYW1tYXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlNjaGVtYVN5bWJvbHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlhTQW5ub3RhdGlvbkltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlhTQ29uc3RyYWludHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlhTR3JvdXBEZWNsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5YU01vZGVsR3JvdXBJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5YU1BhcnRpY2xlRGVjbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMudXRpbC5YSW50OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy51dGlsLlhTT2JqZWN0TGlzdEltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLkRPTVV0aWw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlhNTFN5bWJvbHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuUU5hbWU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU09iamVjdExpc3Q7Ci1pbXBvcnQgb3JnLnczYy5kb20uRWxlbWVudDsKLQotLyoqCi0gKiBUaGUgbW9kZWwgZ3JvdXAgc2NoZW1hIGNvbXBvbmVudCB0cmF2ZXJzZXIuCi0gKgotICogPGdyb3VwCi0gKiAgIG5hbWUgPSBOQ05hbWU+Ci0gKiAgIENvbnRlbnQ6IChhbm5vdGF0aW9uPywgKGFsbCB8IGNob2ljZSB8IHNlcXVlbmNlKSkKLSAqIDwvZ3JvdXA+Ci0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgUmFodWwgU3JpdmFzdGF2YSwgU3VuIE1pY3Jvc3lzdGVtcyBJbmMuCi0gKiBAYXV0aG9yIEVsZW5hIExpdGFuaSwgSUJNCi0gKiBAYXV0aG9yIExpc2EgTWFydGluLCAgSUJNCi0gKiBAdmVyc2lvbiAkSWQ6IFhTREdyb3VwVHJhdmVyc2VyLmphdmEsdiAxLjcgMjAxMC0xMS0wMSAwNDo0MDowMiBqb2VodyBFeHAgJAotICovCi1jbGFzcyAgWFNER3JvdXBUcmF2ZXJzZXIgZXh0ZW5kcyBYU0RBYnN0cmFjdFBhcnRpY2xlVHJhdmVyc2VyIHsKLQotICAgIFhTREdyb3VwVHJhdmVyc2VyIChYU0RIYW5kbGVyIGhhbmRsZXIsCi0gICAgICAgICAgICBYU0F0dHJpYnV0ZUNoZWNrZXIgZ0F0dHJDaGVjaykgewotCi0gICAgICAgIHN1cGVyKGhhbmRsZXIsIGdBdHRyQ2hlY2spOwotICAgIH0KLQotICAgIFhTUGFydGljbGVEZWNsIHRyYXZlcnNlTG9jYWwoRWxlbWVudCBlbG1Ob2RlLAotICAgICAgICAgICAgWFNEb2N1bWVudEluZm8gc2NoZW1hRG9jLAotICAgICAgICAgICAgU2NoZW1hR3JhbW1hciBncmFtbWFyKSB7Ci0KLSAgICAgICAgLy8gR2VuZXJhbCBBdHRyaWJ1dGUgQ2hlY2tpbmcgZm9yIGVsbU5vZGUgZGVjbGFyZWQgbG9jYWxseQotICAgICAgICBPYmplY3RbXSBhdHRyVmFsdWVzID0gZkF0dHJDaGVja2VyLmNoZWNrQXR0cmlidXRlcyhlbG1Ob2RlLCBmYWxzZSwKLSAgICAgICAgICAgICAgICBzY2hlbWFEb2MpOwotICAgICAgICBRTmFtZSByZWZBdHRyID0gKFFOYW1lKSBhdHRyVmFsdWVzW1hTQXR0cmlidXRlQ2hlY2tlci5BVFRJRFhfUkVGXTsKLSAgICAgICAgWEludCAgbWluQXR0ciA9IChYSW50KSAgYXR0clZhbHVlc1tYU0F0dHJpYnV0ZUNoZWNrZXIuQVRUSURYX01JTk9DQ1VSU107Ci0gICAgICAgIFhJbnQgIG1heEF0dHIgPSAoWEludCkgIGF0dHJWYWx1ZXNbWFNBdHRyaWJ1dGVDaGVja2VyLkFUVElEWF9NQVhPQ0NVUlNdOwotCi0gICAgICAgIFhTR3JvdXBEZWNsIGdyb3VwID0gbnVsbDsKLQotICAgICAgICAvLyByZWYgc2hvdWxkIGJlIGhlcmUuCi0gICAgICAgIGlmIChyZWZBdHRyID09IG51bGwpIHsKLSAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKCJzNHMtYXR0LW11c3QtYXBwZWFyIiwgbmV3IE9iamVjdFtdeyJncm91cCAobG9jYWwpIiwgInJlZiJ9LCBlbG1Ob2RlKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIC8vIGdldCBnbG9iYWwgZGVjbAotICAgICAgICAgICAgLy8gaW5kZXggaXMgYSBwYXJ0aWNsZSBpbmRleC4KLSAgICAgICAgICAgIGdyb3VwID0gKFhTR3JvdXBEZWNsKWZTY2hlbWFIYW5kbGVyLmdldEdsb2JhbERlY2woc2NoZW1hRG9jLCBYU0RIYW5kbGVyLkdST1VQX1RZUEUsIHJlZkF0dHIsIGVsbU5vZGUpOwotICAgICAgICB9Ci0KLSAgICAgICAgWFNBbm5vdGF0aW9uSW1wbCBhbm5vdGF0aW9uID0gbnVsbDsKLSAgICAgICAgLy8gbm8gY2hpbGRyZW4gb3RoZXIgdGhhbiAiYW5ub3RhdGlvbj8iIGFyZSBhbGxvd2VkCi0gICAgICAgIEVsZW1lbnQgY2hpbGQgPSBET01VdGlsLmdldEZpcnN0Q2hpbGRFbGVtZW50KGVsbU5vZGUpOwotICAgICAgICBpZiAoY2hpbGQgIT0gbnVsbCAmJiBET01VdGlsLmdldExvY2FsTmFtZShjaGlsZCkuZXF1YWxzKFNjaGVtYVN5bWJvbHMuRUxUX0FOTk9UQVRJT04pKSB7Ci0gICAgICAgICAgICBhbm5vdGF0aW9uID0gdHJhdmVyc2VBbm5vdGF0aW9uRGVjbChjaGlsZCwgYXR0clZhbHVlcywgZmFsc2UsIHNjaGVtYURvYyk7Ci0gICAgICAgICAgICBjaGlsZCA9IERPTVV0aWwuZ2V0TmV4dFNpYmxpbmdFbGVtZW50KGNoaWxkKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIFN0cmluZyB0ZXh0ID0gRE9NVXRpbC5nZXRTeW50aGV0aWNBbm5vdGF0aW9uKGVsbU5vZGUpOwotICAgICAgICAgICAgaWYgKHRleHQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGFubm90YXRpb24gPSB0cmF2ZXJzZVN5bnRoZXRpY0Fubm90YXRpb24oZWxtTm9kZSwgdGV4dCwgYXR0clZhbHVlcywgZmFsc2UsIHNjaGVtYURvYyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoY2hpbGQgIT0gbnVsbCkgewotICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoInM0cy1lbHQtbXVzdC1tYXRjaC4xIiwgbmV3IE9iamVjdFtdeyJncm91cCAobG9jYWwpIiwgIihhbm5vdGF0aW9uPykiLCBET01VdGlsLmdldExvY2FsTmFtZShlbG1Ob2RlKX0sIGVsbU5vZGUpOwotICAgICAgICB9Ci0KLSAgICAgICAgaW50IG1pbk9jY3VycyA9IG1pbkF0dHIuaW50VmFsdWUoKTsKLSAgICAgICAgaW50IG1heE9jY3VycyA9IG1heEF0dHIuaW50VmFsdWUoKTsKLQotICAgICAgICBYU1BhcnRpY2xlRGVjbCBwYXJ0aWNsZSA9IG51bGw7Ci0KLSAgICAgICAgLy8gbm90IGVtcHR5IGdyb3VwLCBub3QgZW1wdHkgcGFydGljbGUKLSAgICAgICAgaWYgKGdyb3VwICE9IG51bGwgJiYgZ3JvdXAuZk1vZGVsR3JvdXAgIT0gbnVsbCAmJgotICAgICAgICAgICAgICAgICEobWluT2NjdXJzID09IDAgJiYgbWF4T2NjdXJzID09IDApKSB7Ci0gICAgICAgICAgICAvLyBjcmVhdGUgYSBwYXJ0aWNsZSB0byBjb250YWluIHRoaXMgbW9kZWwgZ3JvdXAKLSAgICAgICAgICAgIGlmIChmU2NoZW1hSGFuZGxlci5mRGVjbFBvb2wgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHBhcnRpY2xlID0gZlNjaGVtYUhhbmRsZXIuZkRlY2xQb29sLmdldFBhcnRpY2xlRGVjbCgpOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBwYXJ0aWNsZSA9IG5ldyBYU1BhcnRpY2xlRGVjbCgpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcGFydGljbGUuZlR5cGUgPSBYU1BhcnRpY2xlRGVjbC5QQVJUSUNMRV9NT0RFTEdST1VQOwotICAgICAgICAgICAgcGFydGljbGUuZlZhbHVlID0gZ3JvdXAuZk1vZGVsR3JvdXA7Ci0gICAgICAgICAgICBwYXJ0aWNsZS5mTWluT2NjdXJzID0gbWluT2NjdXJzOwotICAgICAgICAgICAgcGFydGljbGUuZk1heE9jY3VycyA9IG1heE9jY3VyczsKLSAgICAgICAgICAgIGlmIChncm91cC5mTW9kZWxHcm91cC5mQ29tcG9zaXRvciA9PSBYU01vZGVsR3JvdXBJbXBsLk1PREVMR1JPVVBfQUxMKSB7Ci0gICAgICAgICAgICAgICAgTG9uZyBkZWZhdWx0VmFscyA9IChMb25nKWF0dHJWYWx1ZXNbWFNBdHRyaWJ1dGVDaGVja2VyLkFUVElEWF9GUk9NREVGQVVMVF07Ci0gICAgICAgICAgICAgICAgcGFydGljbGUgPSBjaGVja09jY3VycmVuY2VzKHBhcnRpY2xlLCBTY2hlbWFTeW1ib2xzLkVMVF9HUk9VUCwKLSAgICAgICAgICAgICAgICAgICAgICAgIChFbGVtZW50KWVsbU5vZGUuZ2V0UGFyZW50Tm9kZSgpLCBHUk9VUF9SRUZfV0lUSF9BTEwsCi0gICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0VmFscy5sb25nVmFsdWUoKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAocmVmQXR0ciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgWFNPYmplY3RMaXN0IGFubm90YXRpb25zOwotICAgICAgICAgICAgICAgIGlmIChhbm5vdGF0aW9uICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgYW5ub3RhdGlvbnMgPSBuZXcgWFNPYmplY3RMaXN0SW1wbCgpOwotICAgICAgICAgICAgICAgICAgICAoKFhTT2JqZWN0TGlzdEltcGwpIGFubm90YXRpb25zKS5hZGRYU09iamVjdChhbm5vdGF0aW9uKTsKLSAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICBhbm5vdGF0aW9ucyA9IFhTT2JqZWN0TGlzdEltcGwuRU1QVFlfTElTVDsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgcGFydGljbGUuZkFubm90YXRpb25zID0gYW5ub3RhdGlvbnM7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIHBhcnRpY2xlLmZBbm5vdGF0aW9ucyA9IGdyb3VwLmZBbm5vdGF0aW9uczsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGZBdHRyQ2hlY2tlci5yZXR1cm5BdHRyQXJyYXkoYXR0clZhbHVlcywgc2NoZW1hRG9jKTsKLQotICAgICAgICByZXR1cm4gcGFydGljbGU7Ci0KLSAgICB9IC8vIHRyYXZlcnNlTG9jYWwKLQotICAgIFhTR3JvdXBEZWNsIHRyYXZlcnNlR2xvYmFsKEVsZW1lbnQgZWxtTm9kZSwKLSAgICAgICAgICAgIFhTRG9jdW1lbnRJbmZvIHNjaGVtYURvYywKLSAgICAgICAgICAgIFNjaGVtYUdyYW1tYXIgZ3JhbW1hcikgewotCi0gICAgICAgIC8vIEdlbmVyYWwgQXR0cmlidXRlIENoZWNraW5nIGZvciBlbG1Ob2RlIGRlY2xhcmVkIGdsb2JhbGx5Ci0gICAgICAgIE9iamVjdFtdIGF0dHJWYWx1ZXMgPSBmQXR0ckNoZWNrZXIuY2hlY2tBdHRyaWJ1dGVzKGVsbU5vZGUsIHRydWUsCi0gICAgICAgICAgICAgICAgc2NoZW1hRG9jKTsKLSAgICAgICAgU3RyaW5nICBzdHJOYW1lQXR0ciA9IChTdHJpbmcpICBhdHRyVmFsdWVzW1hTQXR0cmlidXRlQ2hlY2tlci5BVFRJRFhfTkFNRV07Ci0KLSAgICAgICAgLy8gbXVzdCBoYXZlIGEgbmFtZQotICAgICAgICBpZiAoc3RyTmFtZUF0dHIgPT0gbnVsbCkgewotICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoInM0cy1hdHQtbXVzdC1hcHBlYXIiLCBuZXcgT2JqZWN0W117Imdyb3VwIChnbG9iYWwpIiwgIm5hbWUifSwgZWxtTm9kZSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBDcmVhdGUgdGhlIGdyb3VwIGRlZmkgdXAtZnJvbnQsIHNvIGl0IGNhbiBiZSBwYXNzZWQKLSAgICAgICAgLy8gdG8gdGhlIHRyYXZlcnNhbCBtZXRob2RzCi0gICAgICAgIFhTR3JvdXBEZWNsIGdyb3VwID0gbmV3IFhTR3JvdXBEZWNsKCk7Ci0gICAgICAgIFhTUGFydGljbGVEZWNsIHBhcnRpY2xlID0gbnVsbDsKLQotICAgICAgICAvLyBtdXN0IGhhdmUgYXQgbGVhc3Qgb25lIGNoaWxkCi0gICAgICAgIEVsZW1lbnQgbF9lbG1DaGlsZCA9IERPTVV0aWwuZ2V0Rmlyc3RDaGlsZEVsZW1lbnQoZWxtTm9kZSk7Ci0gICAgICAgIFhTQW5ub3RhdGlvbkltcGwgYW5ub3RhdGlvbiA9IG51bGw7Ci0gICAgICAgIGlmIChsX2VsbUNoaWxkID09IG51bGwpIHsKLSAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKCJzNHMtZWx0LW11c3QtbWF0Y2guMiIsCi0gICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXsiZ3JvdXAgKGdsb2JhbCkiLCAiKGFubm90YXRpb24/LCAoYWxsIHwgY2hvaWNlIHwgc2VxdWVuY2UpKSJ9LAotICAgICAgICAgICAgICAgICAgICBlbG1Ob2RlKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIFN0cmluZyBjaGlsZE5hbWUgPSBsX2VsbUNoaWxkLmdldExvY2FsTmFtZSgpOwotICAgICAgICAgICAgaWYgKGNoaWxkTmFtZS5lcXVhbHMoU2NoZW1hU3ltYm9scy5FTFRfQU5OT1RBVElPTikpIHsKLSAgICAgICAgICAgICAgICBhbm5vdGF0aW9uID0gdHJhdmVyc2VBbm5vdGF0aW9uRGVjbChsX2VsbUNoaWxkLCBhdHRyVmFsdWVzLCB0cnVlLCBzY2hlbWFEb2MpOwotICAgICAgICAgICAgICAgIGxfZWxtQ2hpbGQgPSBET01VdGlsLmdldE5leHRTaWJsaW5nRWxlbWVudChsX2VsbUNoaWxkKTsKLSAgICAgICAgICAgICAgICBpZiAobF9lbG1DaGlsZCAhPSBudWxsKQotICAgICAgICAgICAgICAgICAgICBjaGlsZE5hbWUgPSBsX2VsbUNoaWxkLmdldExvY2FsTmFtZSgpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIHRleHQgPSBET01VdGlsLmdldFN5bnRoZXRpY0Fubm90YXRpb24oZWxtTm9kZSk7Ci0gICAgICAgICAgICAgICAgaWYgKHRleHQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBhbm5vdGF0aW9uID0gdHJhdmVyc2VTeW50aGV0aWNBbm5vdGF0aW9uKGVsbU5vZGUsIHRleHQsIGF0dHJWYWx1ZXMsIGZhbHNlLCBzY2hlbWFEb2MpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKGxfZWxtQ2hpbGQgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKCJzNHMtZWx0LW11c3QtbWF0Y2guMiIsCi0gICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117Imdyb3VwIChnbG9iYWwpIiwgIihhbm5vdGF0aW9uPywgKGFsbCB8IGNob2ljZSB8IHNlcXVlbmNlKSkifSwKLSAgICAgICAgICAgICAgICAgICAgICAgIGVsbU5vZGUpOwotICAgICAgICAgICAgfSBlbHNlIGlmIChjaGlsZE5hbWUuZXF1YWxzKFNjaGVtYVN5bWJvbHMuRUxUX0FMTCkpIHsKLSAgICAgICAgICAgICAgICBwYXJ0aWNsZSA9IHRyYXZlcnNlQWxsKGxfZWxtQ2hpbGQsIHNjaGVtYURvYywgZ3JhbW1hciwgQ0hJTERfT0ZfR1JPVVAsIGdyb3VwKTsKLSAgICAgICAgICAgIH0gZWxzZSBpZiAoY2hpbGROYW1lLmVxdWFscyhTY2hlbWFTeW1ib2xzLkVMVF9DSE9JQ0UpKSB7Ci0gICAgICAgICAgICAgICAgcGFydGljbGUgPSB0cmF2ZXJzZUNob2ljZShsX2VsbUNoaWxkLCBzY2hlbWFEb2MsIGdyYW1tYXIsIENISUxEX09GX0dST1VQLCBncm91cCk7Ci0gICAgICAgICAgICB9IGVsc2UgaWYgKGNoaWxkTmFtZS5lcXVhbHMoU2NoZW1hU3ltYm9scy5FTFRfU0VRVUVOQ0UpKSB7Ci0gICAgICAgICAgICAgICAgcGFydGljbGUgPSB0cmF2ZXJzZVNlcXVlbmNlKGxfZWxtQ2hpbGQsIHNjaGVtYURvYywgZ3JhbW1hciwgQ0hJTERfT0ZfR1JPVVAsIGdyb3VwKTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoInM0cy1lbHQtbXVzdC1tYXRjaC4xIiwKLSAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXsiZ3JvdXAgKGdsb2JhbCkiLCAiKGFubm90YXRpb24/LCAoYWxsIHwgY2hvaWNlIHwgc2VxdWVuY2UpKSIsIERPTVV0aWwuZ2V0TG9jYWxOYW1lKGxfZWxtQ2hpbGQpfSwKLSAgICAgICAgICAgICAgICAgICAgICAgIGxfZWxtQ2hpbGQpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAobF9lbG1DaGlsZCAhPSBudWxsICYmCi0gICAgICAgICAgICAgICAgICAgIERPTVV0aWwuZ2V0TmV4dFNpYmxpbmdFbGVtZW50KGxfZWxtQ2hpbGQpICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcigiczRzLWVsdC1tdXN0LW1hdGNoLjEiLAotICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdeyJncm91cCAoZ2xvYmFsKSIsICIoYW5ub3RhdGlvbj8sIChhbGwgfCBjaG9pY2UgfCBzZXF1ZW5jZSkpIiwKLSAgICAgICAgICAgICAgICAgICAgICAgIERPTVV0aWwuZ2V0TG9jYWxOYW1lKERPTVV0aWwuZ2V0TmV4dFNpYmxpbmdFbGVtZW50KGxfZWxtQ2hpbGQpKX0sCi0gICAgICAgICAgICAgICAgICAgICAgICBET01VdGlsLmdldE5leHRTaWJsaW5nRWxlbWVudChsX2VsbUNoaWxkKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBhZGQgZ2xvYmFsIGdyb3VwIGRlY2xhcmF0aW9uIHRvIHRoZSBncmFtbWFyCi0gICAgICAgIGlmIChzdHJOYW1lQXR0ciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBncm91cC5mTmFtZSA9IHN0ck5hbWVBdHRyOwotICAgICAgICAgICAgZ3JvdXAuZlRhcmdldE5hbWVzcGFjZSA9IHNjaGVtYURvYy5mVGFyZ2V0TmFtZXNwYWNlOwotICAgICAgICAgICAgaWYgKHBhcnRpY2xlID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBwYXJ0aWNsZSA9IFhTQ29uc3RyYWludHMuZ2V0RW1wdHlTZXF1ZW5jZSgpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZ3JvdXAuZk1vZGVsR3JvdXAgPSAoWFNNb2RlbEdyb3VwSW1wbClwYXJ0aWNsZS5mVmFsdWU7Ci0gICAgICAgICAgICBYU09iamVjdExpc3QgYW5ub3RhdGlvbnM7Ci0gICAgICAgICAgICBpZiAoYW5ub3RhdGlvbiAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgYW5ub3RhdGlvbnMgPSBuZXcgWFNPYmplY3RMaXN0SW1wbCgpOwotICAgICAgICAgICAgICAgICgoWFNPYmplY3RMaXN0SW1wbCkgYW5ub3RhdGlvbnMpLmFkZFhTT2JqZWN0KGFubm90YXRpb24pOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBhbm5vdGF0aW9ucyA9IFhTT2JqZWN0TGlzdEltcGwuRU1QVFlfTElTVDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGdyb3VwLmZBbm5vdGF0aW9ucyA9IGFubm90YXRpb25zOwotICAgICAgICAgICAgLy8gQWRkIGdyb3VwIGRlY2xhcmF0aW9uIHRvIGdyYW1tYXIKLSAgICAgICAgICAgIGlmIChncmFtbWFyLmdldEdsb2JhbEdyb3VwRGVjbChncm91cC5mTmFtZSkgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGdyYW1tYXIuYWRkR2xvYmFsR3JvdXBEZWNsKGdyb3VwKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gYWxzbyBhZGQgaXQgdG8gZXh0ZW5kZWQgbWFwCi0gICAgICAgICAgICBmaW5hbCBTdHJpbmcgbG9jID0gZlNjaGVtYUhhbmRsZXIuc2NoZW1hRG9jdW1lbnQyU3lzdGVtSWQoc2NoZW1hRG9jKTsKLSAgICAgICAgICAgIGZpbmFsIFhTR3JvdXBEZWNsIGdyb3VwMiA9IGdyYW1tYXIuZ2V0R2xvYmFsR3JvdXBEZWNsKGdyb3VwLmZOYW1lLCBsb2MpOwotICAgICAgICAgICAgaWYgKGdyb3VwMiA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZ3JhbW1hci5hZGRHbG9iYWxHcm91cERlY2woZ3JvdXAsIGxvYyk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIGhhbmRsZSBkdXBsaWNhdGVzCi0gICAgICAgICAgICBpZiAoZlNjaGVtYUhhbmRsZXIuZlRvbGVyYXRlRHVwbGljYXRlcykgewotICAgICAgICAgICAgICAgIGlmIChncm91cDIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBncm91cCA9IGdyb3VwMjsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZlNjaGVtYUhhbmRsZXIuYWRkR2xvYmFsR3JvdXBEZWNsKGdyb3VwKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIC8vIG5hbWUgYXR0cmlidXRlIGlzIG5vdCB0aGVyZSwgZG9uJ3QgcmV0dXJuIHRoaXMgZ3JvdXAuCi0gICAgICAgICAgICBncm91cCA9IG51bGw7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoZ3JvdXAgIT0gbnVsbCkgewotICAgICAgICAgICAgLy8gc3RvcmUgZ3JvdXBzIHJlZGVmaW5lZCBieSByZXN0cmljdGlvbiBpbiB0aGUgZ3JhbW1hciBzbwotICAgICAgICAgICAgLy8gdGhhdCB3ZSBjYW4gZ2V0IGF0IHRoZW0gYXQgZnVsbC1zY2hlbWEtY2hlY2tpbmcgdGltZS4KLSAgICAgICAgICAgIE9iamVjdCByZWRlZmluZWRHcnAgPSBmU2NoZW1hSGFuZGxlci5nZXRHcnBPckF0dHJHcnBSZWRlZmluZWRCeVJlc3RyaWN0aW9uKFhTREhhbmRsZXIuR1JPVVBfVFlQRSwKLSAgICAgICAgICAgICAgICAgICAgbmV3IFFOYW1lKFhNTFN5bWJvbHMuRU1QVFlfU1RSSU5HLCBzdHJOYW1lQXR0ciwgc3RyTmFtZUF0dHIsIHNjaGVtYURvYy5mVGFyZ2V0TmFtZXNwYWNlKSwKLSAgICAgICAgICAgICAgICAgICAgc2NoZW1hRG9jLCBlbG1Ob2RlKTsKLSAgICAgICAgICAgIGlmIChyZWRlZmluZWRHcnAgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIC8vIHN0b3JlIGluIGdyYW1tYXIKLSAgICAgICAgICAgICAgICBncmFtbWFyLmFkZFJlZGVmaW5lZEdyb3VwRGVjbChncm91cCwgKFhTR3JvdXBEZWNsKXJlZGVmaW5lZEdycCwKLSAgICAgICAgICAgICAgICAgICAgICAgIGZTY2hlbWFIYW5kbGVyLmVsZW1lbnQyTG9jYXRvcihlbG1Ob2RlKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBmQXR0ckNoZWNrZXIucmV0dXJuQXR0ckFycmF5KGF0dHJWYWx1ZXMsIHNjaGVtYURvYyk7Ci0KLSAgICAgICAgcmV0dXJuIGdyb3VwOwotCi0gICAgfSAvLyB0cmF2ZXJzZUdsb2JhbAotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy90cmF2ZXJzZXJzL1hTREhhbmRsZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvdHJhdmVyc2Vycy9YU0RIYW5kbGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGUyOTU1NGQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy90cmF2ZXJzZXJzL1hTREhhbmRsZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQzMzYgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwNywgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqLwotLyoKLSAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQotICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCi0gKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCi0gKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAotICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKLSAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy50cmF2ZXJzZXJzOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLkNvbnN0YW50czsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuWE1MRW50aXR5TWFuYWdlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuWE1MRXJyb3JSZXBvcnRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYuU2NoZW1hRFZGYWN0b3J5OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi54cy5YU1NpbXBsZVR5cGVEZWNsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5TY2hlbWFHcmFtbWFyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5TY2hlbWFOYW1lc3BhY2VTdXBwb3J0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5TY2hlbWFTeW1ib2xzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5YTUxTY2hlbWFFeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlhNTFNjaGVtYUxvYWRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMuWFNBdHRyaWJ1dGVEZWNsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5YU0F0dHJpYnV0ZUdyb3VwRGVjbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMuWFNDb21wbGV4VHlwZURlY2w7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlhTRERlc2NyaXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5YU0RlY2xhcmF0aW9uUG9vbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMuWFNFbGVtZW50RGVjbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMuWFNHcmFtbWFyQnVja2V0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5YU0dyb3VwRGVjbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMuWFNNZXNzYWdlRm9ybWF0dGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5YU01vZGVsR3JvdXBJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5YU05vdGF0aW9uRGVjbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMuWFNQYXJ0aWNsZURlY2w7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLmlkZW50aXR5LklkZW50aXR5Q29uc3RyYWludDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMub3B0aS5FbGVtZW50SW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMub3B0aS5TY2hlbWFET01QYXJzZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLm9wdGkuU2NoZW1hUGFyc2luZ0NvbmZpZzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMudXRpbC5TaW1wbGVMb2NhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy51dGlsLlhTSW5wdXRTb3VyY2U7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5wYXJzZXJzLlNBWFBhcnNlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnBhcnNlcnMuWE1MMTFDb25maWd1cmF0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5ET01JbnB1dFNvdXJjZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuRE9NVXRpbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuRGVmYXVsdEVycm9ySGFuZGxlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuRXJyb3JIYW5kbGVyV3JhcHBlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuU0FYSW5wdXRTb3VyY2U7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlN0QVhJbnB1dFNvdXJjZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuU3RBWExvY2F0aW9uV3JhcHBlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuU3ltYm9sSGFzaDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuU3ltYm9sVGFibGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlVSSS5NYWxmb3JtZWRVUklFeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlhNTFN5bWJvbHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlscy5TZWN1cml0eVN1cHBvcnQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlscy5YTUxTZWN1cml0eU1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlscy5YTUxTZWN1cml0eVByb3BlcnR5TWFuYWdlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5RTmFtZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTklFeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuZ3JhbW1hcnMuR3JhbW1hcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5ncmFtbWFycy5YTUxHcmFtbWFyRGVzY3JpcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuZ3JhbW1hcnMuWE1MR3JhbW1hclBvb2w7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuZ3JhbW1hcnMuWE1MU2NoZW1hRGVzY3JpcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTENvbXBvbmVudE1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTEVudGl0eVJlc29sdmVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxFcnJvckhhbmRsZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTElucHV0U291cmNlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxQYXJzZUV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlN0cmluZ0xpc3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU0F0dHJpYnV0ZURlY2xhcmF0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNBdHRyaWJ1dGVHcm91cERlZmluaXRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU0F0dHJpYnV0ZVVzZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNFbGVtZW50RGVjbGFyYXRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU01vZGVsR3JvdXA7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU01vZGVsR3JvdXBEZWZpbml0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNOYW1lZE1hcDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTT2JqZWN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNPYmplY3RMaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNQYXJ0aWNsZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTU2ltcGxlVHlwZURlZmluaXRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU1Rlcm07Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU1R5cGVEZWZpbml0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuZGF0YXR5cGVzLk9iamVjdExpc3Q7Ci1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLlN0cmluZ1JlYWRlcjsKLWltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwotaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKLWltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwotaW1wb3J0IGphdmEudXRpbC5NYXA7Ci1pbXBvcnQgamF2YS51dGlsLlN0YWNrOwotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci1pbXBvcnQgamF2YXgueG1sLlhNTENvbnN0YW50czsKLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLlhNTEV2ZW50UmVhZGVyOwotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uWE1MU3RyZWFtRXhjZXB0aW9uOwotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uWE1MU3RyZWFtUmVhZGVyOwotaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLkVsZW1lbnQ7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhQYXJzZUV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5YTUxSZWFkZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguaGVscGVycy5YTUxSZWFkZXJGYWN0b3J5OwotCi0vKioKLSAqIFRoZSBwdXJwb3NlIG9mIHRoaXMgY2xhc3MgaXMgdG8gY28tb3JkaW5hdGUgdGhlIGNvbnN0cnVjdGlvbiBvZiBhCi0gKiBncmFtbWFyIG9iamVjdCBjb3JyZXNwb25kaW5nIHRvIGEgc2NoZW1hLiAgVG8gZG8gdGhpcywgaXQgbXVzdCBiZQotICogcHJlcGFyZWQgdG8gcGFyc2Ugc2V2ZXJhbCBzY2hlbWEgZG9jdW1lbnRzIChmb3IgaW5zdGFuY2UgaWYgdGhlCi0gKiBzY2hlbWEgZG9jdW1lbnQgb3JpZ2luYWxseSByZWZlcnJlZCB0byBjb250YWlucyA8aW5jbHVkZT4gb3IKLSAqIDxyZWRlZmluZWQ+IGluZm9ybWF0aW9uIGl0ZW1zKS4gIElmIGFueSBvZiB0aGUgc2NoZW1hcyBpbXBvcnRzIGEKLSAqIHNjaGVtYSwgb3RoZXIgZ3JhbW1hcnMgbWF5IGJlIGNvbnN0cnVjdGVkIGFzIGEgc2lkZS1lZmZlY3QuCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgTmVpbCBHcmFoYW0sIElCTQotICogQGF1dGhvciBQYXZhbmkgTXVrdGhpcHVkaSwgU3VuIE1pY3Jvc3lzdGVtcwotICoKLSAqIEB2ZXJzaW9uICRJZDogWFNESGFuZGxlci5qYXZhLHYgMS45IDIwMTAtMTEtMDEgMDQ6NDA6MDIgam9laHcgRXhwICQKLSAqLwotcHVibGljIGNsYXNzIFhTREhhbmRsZXIgewotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogdmFsaWRhdGlvbi4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBWQUxJREFUSU9OID0KLSAgICAgICAgQ29uc3RhbnRzLlNBWF9GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5WQUxJREFUSU9OX0ZFQVRVUkU7Ci0KLSAgICAvKiogZmVhdHVyZSBpZGVudGlmaWVyOiBYTUwgU2NoZW1hIHZhbGlkYXRpb24gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxTQ0hFTUFfVkFMSURBVElPTiA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuU0NIRU1BX1ZBTElEQVRJT05fRkVBVFVSRTsKLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6ICBhbGxvdyBqYXZhIGVuY29kaW5ncyAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIEFMTE9XX0pBVkFfRU5DT0RJTkdTID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5BTExPV19KQVZBX0VOQ09ESU5HU19GRUFUVVJFOwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogIGNvbnRpbnVlIGFmdGVyIGZhdGFsIGVycm9yICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ09OVElOVUVfQUZURVJfRkFUQUxfRVJST1IgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLkNPTlRJTlVFX0FGVEVSX0ZBVEFMX0VSUk9SX0ZFQVRVUkU7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiAgYWxsb3cgamF2YSBlbmNvZGluZ3MgKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBTVEFOREFSRF9VUklfQ09ORk9STUFOVF9GRUFUVVJFID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5TVEFOREFSRF9VUklfQ09ORk9STUFOVF9GRUFUVVJFOwotCi0gICAgLyoqIEZlYXR1cmU6IGRpc2FsbG93IGRvY3R5cGUqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIERJU0FMTE9XX0RPQ1RZUEUgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLkRJU0FMTE9XX0RPQ1RZUEVfREVDTF9GRUFUVVJFOwotCi0gICAgLyoqIEZlYXR1cmU6IGdlbmVyYXRlIHN5bnRoZXRpYyBhbm5vdGF0aW9ucyAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIEdFTkVSQVRFX1NZTlRIRVRJQ19BTk5PVEFUSU9OUyA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuR0VORVJBVEVfU1lOVEhFVElDX0FOTk9UQVRJT05TX0ZFQVRVUkU7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiB2YWxpZGF0ZSBhbm5vdGF0aW9ucy4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBWQUxJREFURV9BTk5PVEFUSU9OUyA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuVkFMSURBVEVfQU5OT1RBVElPTlNfRkVBVFVSRTsKLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IGhvbm91ciBhbGwgc2NoZW1hTG9jYXRpb25zICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgSE9OT1VSX0FMTF9TQ0hFTUFMT0NBVElPTlMgPQotICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5IT05PVVJfQUxMX1NDSEVNQUxPQ0FUSU9OU19GRUFUVVJFOwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogbmFtZXNwYWNlIGdyb3d0aCAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIE5BTUVTUEFDRV9HUk9XVEggPQotICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5OQU1FU1BBQ0VfR1JPV1RIX0ZFQVRVUkU7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiB0b2xlcmF0ZSBkdXBsaWNhdGVzICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgVE9MRVJBVEVfRFVQTElDQVRFUyA9Ci0gICAgICBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLlRPTEVSQVRFX0RVUExJQ0FURVNfRkVBVFVSRTsKLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IG5hbWVzcGFjZSBwcmVmaXhlcy4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgTkFNRVNQQUNFX1BSRUZJWEVTID0KLSAgICAgICAgQ29uc3RhbnRzLlNBWF9GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5OQU1FU1BBQ0VfUFJFRklYRVNfRkVBVFVSRTsKLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IHN0cmluZyBpbnRlcm5pbmcuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1RSSU5HX0lOVEVSTklORyA9Ci0gICAgICAgIENvbnN0YW50cy5TQVhfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuU1RSSU5HX0lOVEVSTklOR19GRUFUVVJFOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IGVycm9yIGhhbmRsZXIuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJST1JfSEFORExFUiA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLkVSUk9SX0hBTkRMRVJfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogSkFYUCBzY2hlbWEgc291cmNlLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIEpBWFBfU0NIRU1BX1NPVVJDRSA9Ci0gICAgICAgIENvbnN0YW50cy5KQVhQX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5TQ0hFTUFfU09VUkNFOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IGVudGl0eSByZXNvbHZlci4gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFTlRJVFlfUkVTT0xWRVIgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5FTlRJVFlfUkVTT0xWRVJfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogZW50aXR5IG1hbmFnZXIuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgRU5USVRZX01BTkFHRVIgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5FTlRJVFlfTUFOQUdFUl9QUk9QRVJUWTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBlcnJvciByZXBvcnRlci4gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJPUl9SRVBPUlRFUiA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLkVSUk9SX1JFUE9SVEVSX1BST1BFUlRZOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IGdyYW1tYXIgcG9vbC4gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxHUkFNTUFSX1BPT0wgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5YTUxHUkFNTUFSX1BPT0xfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogc3ltYm9sIHRhYmxlLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFNZTUJPTF9UQUJMRSA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLlNZTUJPTF9UQUJMRV9QUk9QRVJUWTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBzZWN1cml0eSBtYW5hZ2VyLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFNFQ1VSSVRZX01BTkFHRVIgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5TRUNVUklUWV9NQU5BR0VSX1BST1BFUlRZOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IGxvY2FsZS4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBMT0NBTEUgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5MT0NBTEVfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogU2VjdXJpdHkgcHJvcGVydHkgbWFuYWdlci4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MX1NFQ1VSSVRZX1BST1BFUlRZX01BTkFHRVIgPQotICAgICAgICBDb25zdGFudHMuWE1MX1NFQ1VSSVRZX1BST1BFUlRZX01BTkFHRVI7Ci0KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGJvb2xlYW4gREVCVUdfTk9ERV9QT09MID0gZmFsc2U7Ci0KLSAgICAvLyBEYXRhCi0KLSAgICAvLyBkaWZmZXJlbnQgc29ydHMgb2YgZGVjbGFyYXRpb25zOyBzaG91bGQgbWFrZSBsb29rdXAgYW5kCi0gICAgLy8gdHJhdmVyc2VyIGNhbGxpbmcgbW9yZSBlZmZpY2llbnQvbGVzcyBidWxreS4KLSAgICBmaW5hbCBzdGF0aWMgaW50IEFUVFJJQlVURV9UWVBFICAgICAgICAgID0gMTsKLSAgICBmaW5hbCBzdGF0aWMgaW50IEFUVFJJQlVURUdST1VQX1RZUEUgICAgID0gMjsKLSAgICBmaW5hbCBzdGF0aWMgaW50IEVMRU1FTlRfVFlQRSAgICAgICAgICAgID0gMzsKLSAgICBmaW5hbCBzdGF0aWMgaW50IEdST1VQX1RZUEUgICAgICAgICAgICAgID0gNDsKLSAgICBmaW5hbCBzdGF0aWMgaW50IElERU5USVRZQ09OU1RSQUlOVF9UWVBFID0gNTsKLSAgICBmaW5hbCBzdGF0aWMgaW50IE5PVEFUSU9OX1RZUEUgICAgICAgICAgID0gNjsKLSAgICBmaW5hbCBzdGF0aWMgaW50IFRZUEVERUNMX1RZUEUgICAgICAgICAgID0gNzsKLQotICAgIC8vIHRoaXMgc3RyaW5nIGdldHMgYXBwZW5kZWQgdG8gcmVkZWZpbmVkIG5hbWVzOyBpdCdzIHB1cnBvc2UgaXMgdG8gYmUKLSAgICAvLyBhcyB1bmxpa2VseSBhcyBwb3NzaWJsZSB0byBjYXVzZSBjb2xsaXNpb25zLgotICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgU3RyaW5nIFJFREVGX0lERU5USUZJRVIgPSAiX2ZuM2RrdGl6cmtuYzlwaSI7Ci0KLSAgICAvL3Byb3RlY3RlZCBkYXRhIHRoYXQgY2FuIGJlIGFjY2Vzc2libGUgYnkgYW55IHRyYXZlcnNlcgotCi0gICAgcHJvdGVjdGVkIFhTRGVjbGFyYXRpb25Qb29sIGZEZWNsUG9vbCA9IG51bGw7Ci0KLSAgICAvLyB0aGUgU2VjdXJpdHkgbWFuYWdlciBpbiBlZmZlY3QuCi0gICAgcHJvdGVjdGVkIFhNTFNlY3VyaXR5TWFuYWdlciBmU2VjdXJpdHlNYW5hZ2VyID0gbnVsbDsKLQotICAgIHByaXZhdGUgU3RyaW5nIGZBY2Nlc3NFeHRlcm5hbFNjaGVtYTsKLSAgICBwcml2YXRlIFN0cmluZyBmQWNjZXNzRXh0ZXJuYWxEVEQ7Ci0KLSAgICAvLyBUaGVzZSB0YWJsZXMgY29ycmVzcG9uZCB0byB0aGUgc3ltYm9sIHNwYWNlcyBkZWZpbmVkIGluIHRoZQotICAgIC8vIHNwZWMuCi0gICAgLy8gVGhleSBhcmUga2V5ZWQgd2l0aCBhIFFOYW1lICh0aGF0IGlzLCBTdHJpbmcoIlVSSSxsb2NhbHBhcnQpIGFuZAotICAgIC8vIHRoZWlyIHZhbHVlcyBhcmUgbm9kZXMgY29ycmVzcG9uZGluZyB0byB0aGUgZ2l2ZW4gbmFtZSdzIGRlY2wuCi0gICAgLy8gQnkgYXNraW5nIHRoZSBub2RlIGZvciBpdHMgb3duZXJEb2N1bWVudCBhbmQgbG9va2luZyBpbgotICAgIC8vIFhTRG9jdW1lbnRJbmZvUmVnaXN0cnkgd2UgY2FuIGVhc2lseSBnZXQgdGhlIGNvcnJlc3BvbmRpbmcKLSAgICAvLyBYU0RvY3VtZW50SW5mbyBvYmplY3QuCi0gICAgcHJpdmF0ZSBib29sZWFuIHJlZ2lzdHJ5RW1wdHkgPSB0cnVlOwotICAgIHByaXZhdGUgTWFwPFN0cmluZywgRWxlbWVudD4gZlVucGFyc2VkQXR0cmlidXRlUmVnaXN0cnkgPSBuZXcgSGFzaE1hcDw+KCk7Ci0gICAgcHJpdmF0ZSBNYXA8U3RyaW5nLCBFbGVtZW50PiBmVW5wYXJzZWRBdHRyaWJ1dGVHcm91cFJlZ2lzdHJ5ID0gIG5ldyBIYXNoTWFwPD4oKTsKLSAgICBwcml2YXRlIE1hcDxTdHJpbmcsIEVsZW1lbnQ+IGZVbnBhcnNlZEVsZW1lbnRSZWdpc3RyeSA9ICBuZXcgSGFzaE1hcDw+KCk7Ci0gICAgcHJpdmF0ZSBNYXA8U3RyaW5nLCBFbGVtZW50PiBmVW5wYXJzZWRHcm91cFJlZ2lzdHJ5ID0gIG5ldyBIYXNoTWFwPD4oKTsKLSAgICBwcml2YXRlIE1hcDxTdHJpbmcsIEVsZW1lbnQ+IGZVbnBhcnNlZElkZW50aXR5Q29uc3RyYWludFJlZ2lzdHJ5ID0gIG5ldyBIYXNoTWFwPD4oKTsKLSAgICBwcml2YXRlIE1hcDxTdHJpbmcsIEVsZW1lbnQ+IGZVbnBhcnNlZE5vdGF0aW9uUmVnaXN0cnkgPSAgbmV3IEhhc2hNYXA8PigpOwotICAgIHByaXZhdGUgTWFwPFN0cmluZywgRWxlbWVudD4gZlVucGFyc2VkVHlwZVJlZ2lzdHJ5ID0gIG5ldyBIYXNoTWFwPD4oKTsKLSAgICAvLyBDb21wZW5zYXRpb24gZm9yIHRoZSBhYm92ZSBtYXBzIHRvIGxvY2F0ZSBYU0RvY3VtZW50SW5mbywKLSAgICAvLyBTaW5jZSB3ZSBtYXkgdGFrZSBTY2hlbWEgRWxlbWVudCBkaXJlY3RseSwgc28gY2FuIG5vdCBnZXQgdGhlCi0gICAgLy8gY29ycmVzcG9uZGluZyBYU0RvY3VtZW50SW5mbyBvYmplY3QganVzdCB1c2luZyBhYm92ZSBtYXBzLgotICAgIHByaXZhdGUgTWFwPFN0cmluZywgWFNEb2N1bWVudEluZm8+IGZVbnBhcnNlZEF0dHJpYnV0ZVJlZ2lzdHJ5U3ViID0gIG5ldyBIYXNoTWFwPD4oKTsKLSAgICBwcml2YXRlIE1hcDxTdHJpbmcsIFhTRG9jdW1lbnRJbmZvPiBmVW5wYXJzZWRBdHRyaWJ1dGVHcm91cFJlZ2lzdHJ5U3ViID0gIG5ldyBIYXNoTWFwPD4oKTsKLSAgICBwcml2YXRlIE1hcDxTdHJpbmcsIFhTRG9jdW1lbnRJbmZvPiBmVW5wYXJzZWRFbGVtZW50UmVnaXN0cnlTdWIgPSAgbmV3IEhhc2hNYXA8PigpOwotICAgIHByaXZhdGUgTWFwPFN0cmluZywgWFNEb2N1bWVudEluZm8+IGZVbnBhcnNlZEdyb3VwUmVnaXN0cnlTdWIgPSAgbmV3IEhhc2hNYXA8PigpOwotICAgIHByaXZhdGUgTWFwPFN0cmluZywgWFNEb2N1bWVudEluZm8+IGZVbnBhcnNlZElkZW50aXR5Q29uc3RyYWludFJlZ2lzdHJ5U3ViID0gIG5ldyBIYXNoTWFwPD4oKTsKLSAgICBwcml2YXRlIE1hcDxTdHJpbmcsIFhTRG9jdW1lbnRJbmZvPiBmVW5wYXJzZWROb3RhdGlvblJlZ2lzdHJ5U3ViID0gIG5ldyBIYXNoTWFwPD4oKTsKLSAgICBwcml2YXRlIE1hcDxTdHJpbmcsIFhTRG9jdW1lbnRJbmZvPiBmVW5wYXJzZWRUeXBlUmVnaXN0cnlTdWIgPSAgbmV3IEhhc2hNYXA8PigpOwotCi0gICAgLy8gU3RvcmVzIFhTRG9jdW1lbnRJbmZvIChrZXllZCBieSBjb21wb25lbnQgbmFtZSksIHRvIGNoZWNrIGZvciBkdXBsaWNhdGUKLSAgICAvLyBjb21wb25lbnRzIGRlY2xhcmVkIHdpdGhpbiB0aGUgc2FtZSB4c2QgZG9jdW1lbnQKLSAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKLSAgICBwcml2YXRlIE1hcDxTdHJpbmcsIFhTRG9jdW1lbnRJbmZvPiBmVW5wYXJzZWRSZWdpc3RyaWVzRXh0W10gPSBuZXcgSGFzaE1hcFtdIHsKLSAgICAgICAgbnVsbCwKLSAgICAgICAgbnVsbCwgLy8gQVRUUklCVVRFX1RZUEUKLSAgICAgICAgbnVsbCwgLy8gQVRUUklCVVRFR1JPVVBfVFlQRQotICAgICAgICBudWxsLCAvLyBFTEVNRU5UX1RZUEUKLSAgICAgICAgbnVsbCwgLy8gR1JPVVBfVFlQRQotICAgICAgICBudWxsLCAvLyBJREVOVElUWUNPTlNUUkFJTlRfVFlQRQotICAgICAgICBudWxsLCAvLyBOT1RBVElPTl9UWVBFCi0gICAgICAgIG51bGwsIC8vIFRZUEVERUNMX1RZUEUKLSAgICB9OwotCi0gICAgLy8gdGhpcyBtYXAgaXMga2V5ZWQgb24gYnkgWFNEb2N1bWVudEluZm8gb2JqZWN0cy4gIEl0cyB2YWx1ZXMKLSAgICAvLyBhcmUgVmVjdG9ycyBjb250YWluaW5nIHRoZSBYU0RvY3VtZW50SW5mbyBvYmplY3RzIDxpbmNsdWRlPmQsCi0gICAgLy8gPGltcG9ydD5lZCBvciA8cmVkZWZpbmU+ZCBieSB0aGUga2V5IFhTRG9jdW1lbnRJbmZvLgotICAgIHByaXZhdGUgTWFwPFhTRG9jdW1lbnRJbmZvLCBWZWN0b3I8WFNEb2N1bWVudEluZm8+PiBmRGVwZW5kZW5jeU1hcCA9IG5ldyBIYXNoTWFwPD4oKTsKLQotICAgIC8vIHRoaXMgbWFwIGlzIGtleWVkIG9uIGJ5IGEgdGFyZ2V0IG5hbWVzcGFjZS4gIEl0cyB2YWx1ZXMKLSAgICAvLyBhcmUgVmVjdG9ycyBjb250YWluaW5nIG5hbWVzcGFjZXMgaW1wb3J0ZWQgYnkgc2NoZW1hIGRvY3VtZW50cwotICAgIC8vIHdpdGggdGhlIGtleSB0YXJnZXQgbmFtZXNwYWNlLgotICAgIC8vIGlmIGFuIGltcG9ydGVkIHNjaGVtYSBoYXMgYWJzZW50IG5hbWVzcGFjZSwgdGhlIHZhbHVlICJudWxsIiBpcyBzdG9yZWQuCi0gICAgcHJpdmF0ZSBNYXA8U3RyaW5nLCBWZWN0b3I+IGZJbXBvcnRNYXAgPSBuZXcgSGFzaE1hcDw+ICgpOwotCi0gICAgLy8gYWxsIG5hbWVzcGFjZXMgdGhhdCBpbXBvcnRzIG90aGVyIG5hbWVzcGFjZXMKLSAgICAvLyBpZiB0aGUgaW1wb3J0aW5nIHNjaGVtYSBoYXMgYWJzZW50IG5hbWVzcGFjZSwgZW1wdHkgc3RyaW5nIGlzIHN0b3JlZC4KLSAgICAvLyAoYmVjYXVzZSB0aGUga2V5IG9mIGEgbWFwIGNhbid0IGJlIG51bGwuKQotICAgIHByaXZhdGUgVmVjdG9yPFN0cmluZz4gZkFsbFROU3MgPSBuZXcgVmVjdG9yPD4oKTsKLQotICAgIC8vIHN0b3JlcyBpbnN0YW5jZSBkb2N1bWVudCBtYXBwaW5ncyBiZXR3ZWVuIG5hbWVzcGFjZXMgYW5kIHNjaGVtYSBoaW50cwotICAgIHByaXZhdGUgTWFwPFN0cmluZywgWE1MU2NoZW1hTG9hZGVyLkxvY2F0aW9uQXJyYXk+IGZMb2NhdGlvblBhaXJzID0gbnVsbDsKLQotICAgIC8vIFJlY29yZHMgd2hpY2ggbm9kZXMgYXJlIGhpZGRlbiB3aGVuIHRoZSBpbnB1dCBpcyBhIERPTUlucHV0U291cmNlLgotICAgIE1hcDxOb2RlLCBTdHJpbmc+IGZIaWRkZW5Ob2RlcyA9IG51bGw7Ci0KLSAgICAvLyBjb252ZW5pZW5jZSBtZXRob2RzCi0gICAgcHJpdmF0ZSBTdHJpbmcgbnVsbDJFbXB0eVN0cmluZyhTdHJpbmcgbnMpIHsKLSAgICAgICAgcmV0dXJuIG5zID09IG51bGwgPyBYTUxTeW1ib2xzLkVNUFRZX1NUUklORyA6IG5zOwotICAgIH0KLSAgICBwcml2YXRlIFN0cmluZyBlbXB0eVN0cmluZzJOdWxsKFN0cmluZyBucykgewotICAgICAgICByZXR1cm4gbnMgPT0gWE1MU3ltYm9scy5FTVBUWV9TVFJJTkcgPyBudWxsIDogbnM7Ci0gICAgfQotICAgIC8vIHVzZSBTY2hlbWEgRWxlbWVudCB0byBsb29rdXAgdGhlIFN5c3RlbUlkLgotICAgIHByaXZhdGUgU3RyaW5nIGRvYzJTeXN0ZW1JZChFbGVtZW50IGVsZSkgewotICAgICAgICBTdHJpbmcgZG9jdW1lbnRVUkkgPSBudWxsOwotICAgICAgICAvKioKLSAgICAgICAgICogUkVWSVNJVDogQ2FzdGluZyB1bnRpbCBET00gTGV2ZWwgMyBpbnRlcmZhY2VzIGFyZSBhdmFpbGFibGUuIC0tIG1yZ2xhdmFzCi0gICAgICAgICAqLwotICAgICAgICBpZihlbGUuZ2V0T3duZXJEb2N1bWVudCgpIGluc3RhbmNlb2YgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLm9wdGkuU2NoZW1hRE9NKXsKLSAgICAgICAgICAgIGRvY3VtZW50VVJJID0gKChjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMub3B0aS5TY2hlbWFET00pIGVsZS5nZXRPd25lckRvY3VtZW50KCkpLmdldERvY3VtZW50VVJJKCk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGRvY3VtZW50VVJJICE9IG51bGwgPyBkb2N1bWVudFVSSSA6IGZEb2MyU3lzdGVtSWQuZ2V0KGVsZSk7Ci0gICAgfQotCi0gICAgLy8gVGhpcyB2ZWN0b3Igc3RvcmVzIHN0cmluZ3Mgd2hpY2ggYXJlIGNvbWJpbmF0aW9ucyBvZiB0aGUKLSAgICAvLyBwdWJsaWNJZCBhbmQgc3lzdGVtSWQgb2YgdGhlIGlucHV0U291cmNlIGNvcnJlc3BvbmRpbmcgdG8gYQotICAgIC8vIHNjaGVtYSBkb2N1bWVudC4gIFRoaXMgY29tYmluYXRpb24gaXMgdXNlZCBzbyB0aGF0IHRoZSB1c2VyJ3MKLSAgICAvLyBFbnRpdHlSZXNvbHZlciBjYW4gcHJvdmlkZSBhIGNvbnNpc3RlbnQgd2F5IG9mIGlkZW50aWZ5aW5nIGEKLSAgICAvLyBzY2hlbWEgZG9jdW1lbnQgdGhhdCBpcyBpbmNsdWRlZCBpbiBtdWx0aXBsZSBvdGhlciBzY2hlbWFzLgotICAgIHByaXZhdGUgTWFwPFhTREtleSwgRWxlbWVudD4gZlRyYXZlcnNlZCA9IG5ldyBIYXNoTWFwPD4oKTsKLQotICAgIC8vIHRoaXMgbWFwIGNvbnRhaW5zIGEgbWFwcGluZyBmcm9tIFNjaGVtYSBFbGVtZW50IHRvIGl0cyBzeXN0ZW1JZAotICAgIC8vIHRoaXMgaXMgdXNlZnVsIHRvIHJlc29sdmUgYSB1cmkgcmVsYXRpdmUgdG8gdGhlIHJlZmVycmluZyBkb2N1bWVudAotICAgIHByaXZhdGUgTWFwPEVsZW1lbnQsIFN0cmluZz4gZkRvYzJTeXN0ZW1JZCA9IG5ldyBIYXNoTWFwPD4oKTsKLQotICAgIC8vIHRoZSBwcmltYXJ5IFhTRG9jdW1lbnRJbmZvIHdlIHdlcmUgY2FsbGVkIHRvIHBhcnNlCi0gICAgcHJpdmF0ZSBYU0RvY3VtZW50SW5mbyBmUm9vdCA9IG51bGw7Ci0KLSAgICAvLyBUaGlzIG1hcCdzIGpvYiBpcyB0byBhY3QgYXMgYSBsaW5rIGJldHdlZW4gdGhlIFNjaGVtYSBFbGVtZW50IGFuZCBpdHMKLSAgICAvLyBYU0RvY3VtZW50SW5mbyBvYmplY3QuCi0gICAgcHJpdmF0ZSBNYXAgZkRvYzJYU0RvY3VtZW50TWFwID0gbmV3IEhhc2hNYXAoKTsKLQotICAgIC8vIG1hcCBiZXR3ZWVuIDxyZWRlZmluZT4gZWxlbWVudHMgYW5kIHRoZSBYU0RvY3VtZW50SW5mbwotICAgIC8vIG9iamVjdHMgdGhhdCBjb3JyZXNwb25kIHRvIHRoZSBkb2N1bWVudHMgYmVpbmcgcmVkZWZpbmVkLgotICAgIHByaXZhdGUgTWFwIGZSZWRlZmluZTJYU0RNYXAgPSBudWxsOwotCi0gICAgLy8gbWFwIGJldHdlZW4gPHJlZGVmaW5lPiBlbGVtZW50cyBhbmQgdGhlIG5hbWVzcGFjZSBzdXBwb3J0Ci0gICAgcHJpdmF0ZSBNYXAgZlJlZGVmaW5lMk5TU3VwcG9ydCA9IG51bGw7Ci0KLSAgICAvLyB0aGVzZSBvYmplY3RzIHN0b3JlIGEgbWFwcGluZyBiZXR3ZWVuIHRoZSBuYW1lcyBvZiByZWRlZmluaW5nCi0gICAgLy8gZ3JvdXBzL2F0dHJpYnV0ZUdyb3VwcyBhbmQgdGhlIGdyb3Vwcy9BdHRyaWJ1dGVHcm91cHMgd2hpY2gKLSAgICAvLyB0aGV5IHJlZGVmaW5lIGJ5IHJlc3RyaWN0aW9uIChpbXBsaWNpdGx5KS4gIEl0IGlzIHVwIHRvIHRoZQotICAgIC8vIEdyb3VwIGFuZCBBdHRyaWJ1dGVHcm91cCB0cmF2ZXJzZXJzIHRvIGNoZWNrIHRoZXNlIHJlc3RyaWN0aW9ucyBmb3IKLSAgICAvLyB2YWxpZGl0eS4KLSAgICBwcml2YXRlIE1hcCBmUmVkZWZpbmVkUmVzdHJpY3RlZEF0dHJpYnV0ZUdyb3VwUmVnaXN0cnkgPSBuZXcgSGFzaE1hcCgpOwotICAgIHByaXZhdGUgTWFwIGZSZWRlZmluZWRSZXN0cmljdGVkR3JvdXBSZWdpc3RyeSA9IG5ldyBIYXNoTWFwKCk7Ci0KLSAgICAvLyBhIHZhcmlhYmxlIHN0b3Jpbmcgd2hldGhlciB0aGUgbGFzdCBzY2hlbWEgZG9jdW1lbnQKLSAgICAvLyBwcm9jZXNzZWQgKGJ5IGdldFNjaGVtYSkgd2FzIGEgZHVwbGljYXRlLgotICAgIHByaXZhdGUgYm9vbGVhbiBmTGFzdFNjaGVtYVdhc0R1cGxpY2F0ZTsKLQotICAgIC8vIHZhbGlkYXRlIGFubm90YXRpb25zIGZlYXR1cmUKLSAgICBwcml2YXRlIGJvb2xlYW4gZlZhbGlkYXRlQW5ub3RhdGlvbnMgPSBmYWxzZTsKLQotICAgIC8vaGFuZGxlIG11bHRpcGxlIGltcG9ydCBmZWF0dXJlCi0gICAgcHJpdmF0ZSBib29sZWFuIGZIb25vdXJBbGxTY2hlbWFMb2NhdGlvbnMgPSBmYWxzZTsKLQotICAgIC8vaGFuZGxlIG5hbWVzcGFjZSBncm93dGggZmVhdHVyZQotICAgIGJvb2xlYW4gZk5hbWVzcGFjZUdyb3d0aCA9IGZhbHNlOwotCi0gICAgLy8gaGFuZGxlIHRvbGVyYXRlIGR1cGxpY2F0ZXMgZmVhdHVyZQotICAgIGJvb2xlYW4gZlRvbGVyYXRlRHVwbGljYXRlcyA9IGZhbHNlOwotCi0gICAgLy8gdGhlIFhNTEVycm9yUmVwb3J0ZXIKLSAgICBwcml2YXRlIFhNTEVycm9yUmVwb3J0ZXIgZkVycm9yUmVwb3J0ZXI7Ci0KLSAgICAvLyB0aGUgWE1MRXJyb3JIYW5kbGVyCi0gICAgcHJpdmF0ZSBYTUxFcnJvckhhbmRsZXIgZkVycm9ySGFuZGxlcjsKLQotICAgIC8vIHRoZSBMb2NhbGUKLSAgICBwcml2YXRlIExvY2FsZSBmTG9jYWxlOwotCi0gICAgLy8gdGhlIFhNTEVudGl0eU1hbmFnZXIKLSAgICBwcml2YXRlIFhNTEVudGl0eVJlc29sdmVyIGZFbnRpdHlNYW5hZ2VyOwotCi0gICAgLy8gdGhlIFhTQXR0cmlidXRlQ2hlY2tlcgotICAgIHByaXZhdGUgWFNBdHRyaWJ1dGVDaGVja2VyIGZBdHRyaWJ1dGVDaGVja2VyOwotCi0gICAgLy8gdGhlIHN5bWJvbCB0YWJsZQotICAgIHByaXZhdGUgU3ltYm9sVGFibGUgZlN5bWJvbFRhYmxlOwotCi0gICAgLy8gdGhlIEdyYW1tYXJSZXNvbHZlcgotICAgIHByaXZhdGUgWFNHcmFtbWFyQnVja2V0IGZHcmFtbWFyQnVja2V0OwotCi0gICAgLy8gdGhlIEdyYW1tYXIgZGVzY3JpcHRpb24KLSAgICBwcml2YXRlIFhTRERlc2NyaXB0aW9uIGZTY2hlbWFHcmFtbWFyRGVzY3JpcHRpb247Ci0KLSAgICAvLyB0aGUgR3JhbW1hciBQb29sCi0gICAgcHJpdmF0ZSBYTUxHcmFtbWFyUG9vbCBmR3JhbW1hclBvb2w7Ci0KLSAgICAvLyB0aGUgc2VjdXJpdHkgcHJvcGVydHkgbWFuYWdlcgotICAgIHByaXZhdGUgWE1MU2VjdXJpdHlQcm9wZXJ0eU1hbmFnZXIgZlNlY3VyaXR5UHJvcGVydHlNZ3IgPSBudWxsOwotCi0gICAgLy8qKioqKioqKioqKiogVHJhdmVyc2VycyAqKioqKioqKioqCi0gICAgWFNEQXR0cmlidXRlR3JvdXBUcmF2ZXJzZXIgZkF0dHJpYnV0ZUdyb3VwVHJhdmVyc2VyOwotICAgIFhTREF0dHJpYnV0ZVRyYXZlcnNlciBmQXR0cmlidXRlVHJhdmVyc2VyOwotICAgIFhTRENvbXBsZXhUeXBlVHJhdmVyc2VyIGZDb21wbGV4VHlwZVRyYXZlcnNlcjsKLSAgICBYU0RFbGVtZW50VHJhdmVyc2VyIGZFbGVtZW50VHJhdmVyc2VyOwotICAgIFhTREdyb3VwVHJhdmVyc2VyIGZHcm91cFRyYXZlcnNlcjsKLSAgICBYU0RLZXlyZWZUcmF2ZXJzZXIgZktleXJlZlRyYXZlcnNlcjsKLSAgICBYU0ROb3RhdGlvblRyYXZlcnNlciBmTm90YXRpb25UcmF2ZXJzZXI7Ci0gICAgWFNEU2ltcGxlVHlwZVRyYXZlcnNlciBmU2ltcGxlVHlwZVRyYXZlcnNlcjsKLSAgICBYU0RVbmlxdWVPcktleVRyYXZlcnNlciBmVW5pcXVlT3JLZXlUcmF2ZXJzZXI7Ci0gICAgWFNEV2lsZGNhcmRUcmF2ZXJzZXIgZldpbGRDYXJkVHJhdmVyc2VyOwotCi0gICAgU2NoZW1hRFZGYWN0b3J5IGZEVkZhY3Rvcnk7Ci0gICAgU2NoZW1hRE9NUGFyc2VyIGZTY2hlbWFQYXJzZXI7Ci0gICAgU2NoZW1hQ29udGVudEhhbmRsZXIgZlhTQ29udGVudEhhbmRsZXI7Ci0gICAgU3RBWFNjaGVtYVBhcnNlciBmU3RBWFNjaGVtYVBhcnNlcjsKLSAgICBYTUwxMUNvbmZpZ3VyYXRpb24gZkFubm90YXRpb25WYWxpZGF0b3I7Ci0gICAgWFNBbm5vdGF0aW9uR3JhbW1hclBvb2wgZkdyYW1tYXJCdWNrZXRBZGFwdGVyOwotCi0gICAgLy8gdGhlc2UgZGF0YSBtZW1iZXJzIGFyZSBuZWVkZWQgZm9yIHRoZSBkZWZlcnJlZCB0cmF2ZXJzYWwKLSAgICAvLyBvZiBsb2NhbCBlbGVtZW50cy4KLQotICAgIC8vIHRoZSBpbml0aWFsIHNpemUgb2YgdGhlIGFycmF5IHRvIHN0b3JlIGRlZmVycmVkIGxvY2FsIGVsZW1lbnRzCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IElOSVRfU1RBQ0tfU0laRSA9IDMwOwotICAgIC8vIHRoZSBpbmNyZW1lbnRhbCBzaXplIG9mIHRoZSBhcnJheSB0byBzdG9yZSBkZWZlcnJlZCBsb2NhbCBlbGVtZW50cwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBJTkNfU1RBQ0tfU0laRSAgPSAxMDsKLSAgICAvLyBjdXJyZW50IHBvc2l0aW9uIG9mIHRoZSBhcnJheSAoIyBvZiBkZWZlcnJlZCBsb2NhbCBlbGVtZW50cykKLSAgICBwcml2YXRlIGludCBmTG9jYWxFbGVtU3RhY2tQb3MgPSAwOwotCi0gICAgcHJpdmF0ZSBYU1BhcnRpY2xlRGVjbFtdIGZQYXJ0aWNsZSA9IG5ldyBYU1BhcnRpY2xlRGVjbFtJTklUX1NUQUNLX1NJWkVdOwotICAgIHByaXZhdGUgRWxlbWVudFtdIGZMb2NhbEVsZW1lbnREZWNsID0gbmV3IEVsZW1lbnRbSU5JVF9TVEFDS19TSVpFXTsKLSAgICBwcml2YXRlIFhTRG9jdW1lbnRJbmZvW10gZkxvY2FsRWxlbWVudERlY2xfc2NoZW1hID0gbmV3IFhTRG9jdW1lbnRJbmZvW0lOSVRfU1RBQ0tfU0laRV07IC8vSkFDSwotICAgIHByaXZhdGUgaW50W10gZkFsbENvbnRleHQgPSBuZXcgaW50W0lOSVRfU1RBQ0tfU0laRV07Ci0gICAgcHJpdmF0ZSBYU09iamVjdFtdIGZQYXJlbnQgPSBuZXcgWFNPYmplY3RbSU5JVF9TVEFDS19TSVpFXTsKLSAgICBwcml2YXRlIFN0cmluZyBbXVtdIGZMb2NhbEVsZW1OYW1lc3BhY2VDb250ZXh0ID0gbmV3IFN0cmluZyBbSU5JVF9TVEFDS19TSVpFXVsxXTsKLQotICAgIC8vIHRoZXNlIGRhdGEgbWVtYmVycyBhcmUgbmVlZGVkIGZvciB0aGUgZGVmZXJyZWQgdHJhdmVyc2FsCi0gICAgLy8gb2Yga2V5cmVmcy4KLQotICAgIC8vIHRoZSBpbml0aWFsIHNpemUgb2YgdGhlIGFycmF5IHRvIHN0b3JlIGRlZmVycmVkIGtleXJlZnMKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgSU5JVF9LRVlSRUZfU1RBQ0sgPSAyOwotICAgIC8vIHRoZSBpbmNyZW1lbnRhbCBzaXplIG9mIHRoZSBhcnJheSB0byBzdG9yZSBkZWZlcnJlZCBrZXlyZWZzCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IElOQ19LRVlSRUZfU1RBQ0tfQU1PVU5UID0gMjsKLSAgICAvLyBjdXJyZW50IHBvc2l0aW9uIG9mIHRoZSBhcnJheSAoIyBvZiBkZWZlcnJlZCBrZXlyZWZzKQotICAgIHByaXZhdGUgaW50IGZLZXlyZWZTdGFja1BvcyA9IDA7Ci0KLSAgICBwcml2YXRlIEVsZW1lbnQgW10gZktleXJlZnMgPSBuZXcgRWxlbWVudFtJTklUX0tFWVJFRl9TVEFDS107Ci0gICAgcHJpdmF0ZSBYU0RvY3VtZW50SW5mbyBbXSBmS2V5cmVmc01hcFhTRG9jdW1lbnRJbmZvID0gbmV3IFhTRG9jdW1lbnRJbmZvW0lOSVRfS0VZUkVGX1NUQUNLXTsKLSAgICBwcml2YXRlIFhTRWxlbWVudERlY2wgW10gZktleXJlZkVsZW1zID0gbmV3IFhTRWxlbWVudERlY2wgW0lOSVRfS0VZUkVGX1NUQUNLXTsKLSAgICBwcml2YXRlIFN0cmluZyBbXVtdIGZLZXlyZWZOYW1lc3BhY2VDb250ZXh0ID0gbmV3IFN0cmluZ1tJTklUX0tFWVJFRl9TVEFDS11bMV07Ci0KLSAgICAvLyBnbG9iYWwgZGVjbHM6IG1hcCBmcm9tIGRlY2wgbmFtZSB0byBkZWNsIG9iamVjdAotICAgIFN5bWJvbEhhc2ggZkdsb2JhbEF0dHJEZWNscyA9IG5ldyBTeW1ib2xIYXNoKDEyKTsKLSAgICBTeW1ib2xIYXNoIGZHbG9iYWxBdHRyR3JwRGVjbHMgPSBuZXcgU3ltYm9sSGFzaCg1KTsKLSAgICBTeW1ib2xIYXNoIGZHbG9iYWxFbGVtRGVjbHMgPSBuZXcgU3ltYm9sSGFzaCgyNSk7Ci0gICAgU3ltYm9sSGFzaCBmR2xvYmFsR3JvdXBEZWNscyA9IG5ldyBTeW1ib2xIYXNoKDUpOwotICAgIFN5bWJvbEhhc2ggZkdsb2JhbE5vdGF0aW9uRGVjbHMgPSBuZXcgU3ltYm9sSGFzaCgxKTsKLSAgICBTeW1ib2xIYXNoIGZHbG9iYWxJRENvbnN0cmFpbnREZWNscyA9IG5ldyBTeW1ib2xIYXNoKDMpOwotICAgIFN5bWJvbEhhc2ggZkdsb2JhbFR5cGVEZWNscyA9IG5ldyBTeW1ib2xIYXNoKDI1KTsKLQotICAgIC8vIENvbnN0cnVjdG9ycwotICAgIHB1YmxpYyBYU0RIYW5kbGVyKCl7Ci0gICAgICAgIGZIaWRkZW5Ob2RlcyA9IG5ldyBIYXNoTWFwPD4oKTsKLSAgICAgICAgZlNjaGVtYVBhcnNlciA9IG5ldyBTY2hlbWFET01QYXJzZXIobmV3IFNjaGVtYVBhcnNpbmdDb25maWcoKSk7Ci0gICAgfQotCi0gICAgLy8gaXQgc2hvdWxkIGJlIHBvc3NpYmxlIHRvIHVzZSB0aGUgc2FtZSBYU0RIYW5kbGVyIHRvIHBhcnNlCi0gICAgLy8gbXVsdGlwbGUgc2NoZW1hIGRvY3VtZW50czsgdGhpcyB3aWxsIGFsbG93IG9uZSB0byBiZQotICAgIC8vIGNvbnN0cnVjdGVkLgotICAgIHB1YmxpYyBYU0RIYW5kbGVyIChYU0dyYW1tYXJCdWNrZXQgZ0J1Y2tldCkgewotICAgICAgICB0aGlzKCk7Ci0gICAgICAgIGZHcmFtbWFyQnVja2V0ID0gZ0J1Y2tldDsKLQotICAgICAgICAvLyBOb3RlOiBkb24ndCB1c2UgU2NoZW1hQ29uZmlndXJhdGlvbiBpbnRlcm5hbGx5Ci0gICAgICAgIC8vICAgICAgIHdlIHdpbGwgZ2V0IHN0YWNrIG92ZXJmbGF3IGJlY2F1c2UKLSAgICAgICAgLy8gICAgICAgWE1MU2NoZW1hVmFsaWRhdG9yIHdpbGwgYmUgaW5zdGFudGlhdGluZyBYU0RIYW5kbGVyLi4uCi0gICAgICAgIGZTY2hlbWFHcmFtbWFyRGVzY3JpcHRpb24gPSBuZXcgWFNERGVzY3JpcHRpb24oKTsKLSAgICB9IC8vIGVuZCBjb25zdHJ1Y3RvcgotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgaW5pdGlhdGVzIHRoZSBwYXJzZSBvZiBhIHNjaGVtYS4gIEl0IHdpbGwgbGlrZWx5IGJlCi0gICAgICogY2FsbGVkIGZyb20gdGhlIFZhbGlkYXRvciBhbmQgaXQgd2lsbCBtYWtlIHRoZQotICAgICAqIHJlc3VsdGluZyBncmFtbWFyIGF2YWlsYWJsZTsgaXQgcmV0dXJucyBhIHJlZmVyZW5jZSB0byB0aGlzIG9iamVjdCBqdXN0Ci0gICAgICogaW4gY2FzZS4gIEEgcmVzZXQoWE1MQ29tcG9uZW50TWFuYWdlcikgbXVzdCBiZSBjYWxsZWQgYmVmb3JlIHRoaXMgbWV0aG9kcyBpcyBjYWxsZWQuCi0gICAgICogQHBhcmFtIGlzCi0gICAgICogQHBhcmFtIGRlc2MKLSAgICAgKiBAcGFyYW0gbG9jYXRpb25QYWlycwotICAgICAqIEByZXR1cm4gdGhlIFNjaGVtYUdyYW1tYXIKLSAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0gICAgICovCi0gICAgcHVibGljIFNjaGVtYUdyYW1tYXIgcGFyc2VTY2hlbWEoWE1MSW5wdXRTb3VyY2UgaXMsIFhTRERlc2NyaXB0aW9uIGRlc2MsCi0gICAgICAgICAgICBNYXA8U3RyaW5nLCBYTUxTY2hlbWFMb2FkZXIuTG9jYXRpb25BcnJheT4gbG9jYXRpb25QYWlycykKLSAgICB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgICAgICBmTG9jYXRpb25QYWlycyA9IGxvY2F0aW9uUGFpcnM7Ci0gICAgICAgIGZTY2hlbWFQYXJzZXIucmVzZXROb2RlUG9vbCgpOwotICAgICAgICBTY2hlbWFHcmFtbWFyIGdyYW1tYXIgPSBudWxsOwotICAgICAgICBTdHJpbmcgc2NoZW1hTmFtZXNwYWNlICA9IG51bGw7Ci0gICAgICAgIHNob3J0IHJlZmVyVHlwZSA9IGRlc2MuZ2V0Q29udGV4dFR5cGUoKTsKLQotICAgICAgICAvLyBpZiBsb2FkaW5nIHVzaW5nIEpBWFAgc2NoZW1hU291cmNlIHByb3BlcnR5LCBvciB1c2luZyBncmFtbWFyIGNhY2hpbmcgbG9hZEdyYW1tYXIKLSAgICAgICAgLy8gdGhlIGRlc2MudGFyZ2V0TmFtZXNwYWNlIGlzIGFsd2F5cyBudWxsLgotICAgICAgICAvLyBUaGVyZWZvcmUgd2Ugc2hvdWxkIG5vdCBhdHRlbXB0IHRvIGZpbmQgb3V0IGlmCi0gICAgICAgIC8vIHRoZSBzY2hlbWEgaXMgYWxyZWFkeSBpbiB0aGUgYnVja2V0LCBzaW5jZSBpbiB0aGUgY2FzZSB3ZSBoYXZlCi0gICAgICAgIC8vIG5vIG5hbWVzcGFjZSBzY2hlbWEgaW4gdGhlIGJ1Y2tldCwgZmluZEdyYW1tYXIgd2lsbCBhbHdheXMgcmV0dXJuIHRoZQotICAgICAgICAvLyBubyBuYW1lc3BhY2Ugc2NoZW1hLgotICAgICAgICBpZiAocmVmZXJUeXBlICE9IFhTRERlc2NyaXB0aW9uLkNPTlRFWFRfUFJFUEFSU0UpewotICAgICAgICAgICAgLy8gZmlyc3QgdHJ5IHRvIGZpbmQgaXQgaW4gdGhlIGJ1Y2tldC9wb29sLCByZXR1cm4gaWYgb25lIGlzIGZvdW5kCi0gICAgICAgICAgICBpZiAoZkhvbm91ckFsbFNjaGVtYUxvY2F0aW9ucyAmJiByZWZlclR5cGUgPT0gWFNERGVzY3JpcHRpb24uQ09OVEVYVF9JTVBPUlQgJiYgaXNFeGlzdGluZ0dyYW1tYXIoZGVzYywgZk5hbWVzcGFjZUdyb3d0aCkpIHsKLSAgICAgICAgICAgICAgICBncmFtbWFyID0gZkdyYW1tYXJCdWNrZXQuZ2V0R3JhbW1hcihkZXNjLmdldFRhcmdldE5hbWVzcGFjZSgpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIGdyYW1tYXIgPSBmaW5kR3JhbW1hcihkZXNjLCBmTmFtZXNwYWNlR3Jvd3RoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChncmFtbWFyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBpZiAoIWZOYW1lc3BhY2VHcm93dGgpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGdyYW1tYXI7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGdyYW1tYXIuZ2V0RG9jdW1lbnRMb2NhdGlvbnMoKS5jb250YWlucyhYTUxFbnRpdHlNYW5hZ2VyLmV4cGFuZFN5c3RlbUlkKGlzLmdldFN5c3RlbUlkKCksIGlzLmdldEJhc2VTeXN0ZW1JZCgpLCBmYWxzZSkpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGdyYW1tYXI7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgY2F0Y2ggKE1hbGZvcm1lZFVSSUV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvL1JFVklTSVQ6IHJldHVybiB0aGUgZ3JhbW1hcj8KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgc2NoZW1hTmFtZXNwYWNlID0gZGVzYy5nZXRUYXJnZXROYW1lc3BhY2UoKTsKLSAgICAgICAgICAgIC8vIGhhbmRsZSBlbXB0eSBzdHJpbmcgVVJJIGFzIG51bGwKLSAgICAgICAgICAgIGlmIChzY2hlbWFOYW1lc3BhY2UgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHNjaGVtYU5hbWVzcGFjZSA9IGZTeW1ib2xUYWJsZS5hZGRTeW1ib2woc2NoZW1hTmFtZXNwYWNlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIGJlZm9yZSBwYXJzaW5nIGEgc2NoZW1hLCBuZWVkIHRvIGNsZWFyIHJlZ2lzdHJpZXMgYXNzb2NpYXRlZCB3aXRoCi0gICAgICAgIC8vIHBhcnNpbmcgc2NoZW1hcwotICAgICAgICBwcmVwYXJlRm9yUGFyc2UoKTsKLQotICAgICAgICBFbGVtZW50IHNjaGVtYVJvb3QgPSBudWxsOwotICAgICAgICAvLyBmaXJzdCBwaGFzZTogIGNvbnN0cnVjdCB0cmVlcy4KLSAgICAgICAgaWYgKGlzIGluc3RhbmNlb2YgRE9NSW5wdXRTb3VyY2UpIHsKLSAgICAgICAgICAgIHNjaGVtYVJvb3QgPSBnZXRTY2hlbWFEb2N1bWVudChzY2hlbWFOYW1lc3BhY2UsIChET01JbnB1dFNvdXJjZSkgaXMsCi0gICAgICAgICAgICAgICAgICAgIHJlZmVyVHlwZSA9PSBYU0REZXNjcmlwdGlvbi5DT05URVhUX1BSRVBBUlNFLAotICAgICAgICAgICAgICAgICAgICByZWZlclR5cGUsIG51bGwpOwotICAgICAgICB9IC8vIERPTUlucHV0U291cmNlCi0gICAgICAgIGVsc2UgaWYgKGlzIGluc3RhbmNlb2YgU0FYSW5wdXRTb3VyY2UpIHsKLSAgICAgICAgICAgICAgICBzY2hlbWFSb290ID0gZ2V0U2NoZW1hRG9jdW1lbnQoc2NoZW1hTmFtZXNwYWNlLCAoU0FYSW5wdXRTb3VyY2UpIGlzLAotICAgICAgICAgICAgICAgICAgICByZWZlclR5cGUgPT0gWFNERGVzY3JpcHRpb24uQ09OVEVYVF9QUkVQQVJTRSwKLSAgICAgICAgICAgICAgICAgICAgcmVmZXJUeXBlLCBudWxsKTsKLSAgICAgICAgfSAvLyBTQVhJbnB1dFNvdXJjZQotICAgICAgICBlbHNlIGlmIChpcyBpbnN0YW5jZW9mIFN0QVhJbnB1dFNvdXJjZSkgewotICAgICAgICAgICAgc2NoZW1hUm9vdCA9IGdldFNjaGVtYURvY3VtZW50KHNjaGVtYU5hbWVzcGFjZSwgKFN0QVhJbnB1dFNvdXJjZSkgaXMsCi0gICAgICAgICAgICAgICAgICAgIHJlZmVyVHlwZSA9PSBYU0REZXNjcmlwdGlvbi5DT05URVhUX1BSRVBBUlNFLAotICAgICAgICAgICAgICAgICAgICByZWZlclR5cGUsIG51bGwpOwotICAgICAgICB9IC8vIFN0QVhJbnB1dFNvdXJjZQotICAgICAgICBlbHNlIGlmIChpcyBpbnN0YW5jZW9mIFhTSW5wdXRTb3VyY2UpIHsKLSAgICAgICAgICAgIHNjaGVtYVJvb3QgPSBnZXRTY2hlbWFEb2N1bWVudCgoWFNJbnB1dFNvdXJjZSkgaXMsIGRlc2MpOwotICAgICAgICB9IC8vIFhTSW5wdXRTb3VyY2UKLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgc2NoZW1hUm9vdCA9IGdldFNjaGVtYURvY3VtZW50KHNjaGVtYU5hbWVzcGFjZSwgaXMsCi0gICAgICAgICAgICAgICAgICByZWZlclR5cGUgPT0gWFNERGVzY3JpcHRpb24uQ09OVEVYVF9QUkVQQVJTRSwKLSAgICAgICAgICAgICAgICAgIHJlZmVyVHlwZSwgbnVsbCk7Ci0KLSAgICAgICAgfSAvL2lzIGluc3RhbmNlb2YgWE1MSW5wdXRTb3VyY2UKLQotICAgICAgICBpZiAoc2NoZW1hUm9vdCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAvLyBzb21ldGhpbmcgd2VudCB3cm9uZyByaWdodCBvZmYgdGhlIGhvcAotICAgICAgICAgICAgaWYgKGlzIGluc3RhbmNlb2YgWFNJbnB1dFNvdXJjZSkgewotICAgICAgICAgICAgICAgIHJldHVybiBmR3JhbW1hckJ1Y2tldC5nZXRHcmFtbWFyKGRlc2MuZ2V0VGFyZ2V0TmFtZXNwYWNlKCkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIGdyYW1tYXI7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAocmVmZXJUeXBlID09IFhTRERlc2NyaXB0aW9uLkNPTlRFWFRfUFJFUEFSU0UpIHsKLSAgICAgICAgICAgICAgICBFbGVtZW50IHNjaGVtYUVsZW0gPSBzY2hlbWFSb290OwotICAgICAgICAgICAgc2NoZW1hTmFtZXNwYWNlID0gRE9NVXRpbC5nZXRBdHRyVmFsdWUoc2NoZW1hRWxlbSwgU2NoZW1hU3ltYm9scy5BVFRfVEFSR0VUTkFNRVNQQUNFKTsKLSAgICAgICAgICAgIGlmKHNjaGVtYU5hbWVzcGFjZSAhPSBudWxsICYmIHNjaGVtYU5hbWVzcGFjZS5sZW5ndGgoKSA+IDApIHsKLSAgICAgICAgICAgICAgICAvLyBTaW5jZSBub3cgd2UndmUgZGlzY292ZXJlZCBhIG5hbWVzcGFjZSwgd2UgbmVlZCB0byB1cGRhdGUgeHNkIGtleQotICAgICAgICAgICAgICAgIC8vIGFuZCBzdG9yZSB0aGlzIHNjaGVtYSBpbiB0cmF2ZXJzZWQgc2NoZW1hcyBidWNrZXQKLSAgICAgICAgICAgICAgICBzY2hlbWFOYW1lc3BhY2UgPSBmU3ltYm9sVGFibGUuYWRkU3ltYm9sKHNjaGVtYU5hbWVzcGFjZSk7Ci0gICAgICAgICAgICAgICAgZGVzYy5zZXRUYXJnZXROYW1lc3BhY2Uoc2NoZW1hTmFtZXNwYWNlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIHNjaGVtYU5hbWVzcGFjZSA9IG51bGw7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBncmFtbWFyID0gZmluZEdyYW1tYXIoZGVzYywgZk5hbWVzcGFjZUdyb3d0aCk7Ci0gICAgICAgICAgICBTdHJpbmcgc2NoZW1hSWQgPSBYTUxFbnRpdHlNYW5hZ2VyLmV4cGFuZFN5c3RlbUlkKGlzLmdldFN5c3RlbUlkKCksIGlzLmdldEJhc2VTeXN0ZW1JZCgpLCBmYWxzZSk7Ci0gICAgICAgICAgICBpZiAoZ3JhbW1hciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgLy8gV2hlbiBuYW1lc3BhY2UgZ3Jvd3RoIGlzIGVuYWJsZWQgYW5kIGEgbnVsbCBsb2NhdGlvbiBpcyBwcm92aWRlZCB3ZSBjYW5ub3QgdGVsbAotICAgICAgICAgICAgICAgIC8vIHdoZXRoZXIgd2UndmUgbG9hZGVkIHRoaXMgc2NoZW1hIGRvY3VtZW50IGJlZm9yZSBzbyB3ZSBtdXN0IGFzc3VtZSB0aGF0IHdlIGhhdmVuJ3QuCi0gICAgICAgICAgICAgICAgaWYgKCFmTmFtZXNwYWNlR3Jvd3RoIHx8IChzY2hlbWFJZCAhPSBudWxsICYmIGdyYW1tYXIuZ2V0RG9jdW1lbnRMb2NhdGlvbnMoKS5jb250YWlucyhzY2hlbWFJZCkpKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBncmFtbWFyOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgWFNES2V5IGtleSA9IG5ldyBYU0RLZXkoc2NoZW1hSWQsIHJlZmVyVHlwZSwgc2NoZW1hTmFtZXNwYWNlKTsKLSAgICAgICAgICAgIGZUcmF2ZXJzZWQucHV0KGtleSwgc2NoZW1hUm9vdCk7Ci0gICAgICAgICAgICBpZiAoc2NoZW1hSWQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZEb2MyU3lzdGVtSWQucHV0KHNjaGVtYVJvb3QsIHNjaGVtYUlkKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIGJlZm9yZSBjb25zdHJ1Y3RpbmcgdHJlZXMgYW5kIHRyYXZlcnNpbmcgYSBzY2hlbWEsIG5lZWQgdG8gcmVzZXQKLSAgICAgICAgLy8gYWxsIHRyYXZlcnNlcnMgYW5kIGNsZWFyIGFsbCByZWdpc3RyaWVzCi0gICAgICAgIHByZXBhcmVGb3JUcmF2ZXJzZSgpOwotCi0gICAgICAgIGZSb290ID0gY29uc3RydWN0VHJlZXMoc2NoZW1hUm9vdCwgaXMuZ2V0U3lzdGVtSWQoKSwgZGVzYywgZ3JhbW1hciAhPSBudWxsKTsKLSAgICAgICAgaWYgKGZSb290ID09IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gc2Vjb25kIHBoYXNlOiAgZmlsbCBnbG9iYWwgcmVnaXN0cmllcy4KLSAgICAgICAgYnVpbGRHbG9iYWxOYW1lUmVnaXN0cmllcygpOwotCi0gICAgICAgIC8vIHRoaXJkIHBoYXNlOiAgY2FsbCB0cmF2ZXJzZXJzCi0gICAgICAgIEFycmF5TGlzdCBhbm5vdGF0aW9uSW5mbyA9IGZWYWxpZGF0ZUFubm90YXRpb25zID8gbmV3IEFycmF5TGlzdCgpIDogbnVsbDsKLSAgICAgICAgdHJhdmVyc2VTY2hlbWFzKGFubm90YXRpb25JbmZvKTsKLQotICAgICAgICAvLyBmb3VydGggcGhhc2U6IGhhbmRsZSBsb2NhbCBlbGVtZW50IGRlY2xzCi0gICAgICAgIHRyYXZlcnNlTG9jYWxFbGVtZW50cygpOwotCi0gICAgICAgIC8vIGZpZnRoIHBoYXNlOiAgaGFuZGxlIEtleXJlZnMKLSAgICAgICAgcmVzb2x2ZUtleVJlZnMoKTsKLQotICAgICAgICAvLyBzaXh0aCBwaGFzZTogIHZhbGlkYXRlIGF0dHJpYnV0ZSBvZiBub24tc2NoZW1hIG5hbWVzcGFjZXMKLSAgICAgICAgLy8gUkVWSVNJVDogc2tpcCB0aGlzIGZvciBub3cuIHdlIHJlYWxseSBkb24ndCB3YW50IHRvIGRvIGl0LgotICAgICAgICAvL2ZBdHRyaWJ1dGVDaGVja2VyLmNoZWNrTm9uU2NoZW1hQXR0cmlidXRlcyhmR3JhbW1hckJ1Y2tldCk7Ci0KLSAgICAgICAgLy8gc2V2ZW50aCBwaGFzZTogIHN0b3JlIGltcG9ydGVkIGdyYW1tYXJzCi0gICAgICAgIC8vIGZvciBhbGwgZ3JhbW1hcnMgd2l0aCA8aW1wb3J0PnMKLSAgICAgICAgZm9yIChpbnQgaSA9IGZBbGxUTlNzLnNpemUoKSAtIDE7IGkgPj0gMDsgaS0tKSB7Ci0gICAgICAgICAgICAvLyBnZXQgaXRzIHRhcmdldCBuYW1lc3BhY2UKLSAgICAgICAgICAgIFN0cmluZyB0bnMgPSBmQWxsVE5Tcy5lbGVtZW50QXQoaSk7Ci0gICAgICAgICAgICAvLyBnZXQgYWxsIG5hbWVzcGFjZXMgaXQgaW1wb3J0cwotICAgICAgICAgICAgVmVjdG9yIGlucyA9IChWZWN0b3IpZkltcG9ydE1hcC5nZXQodG5zKTsKLSAgICAgICAgICAgIC8vIGdldCB0aGUgZ3JhbW1hcgotICAgICAgICAgICAgU2NoZW1hR3JhbW1hciBzZyA9IGZHcmFtbWFyQnVja2V0LmdldEdyYW1tYXIoZW1wdHlTdHJpbmcyTnVsbCh0bnMpKTsKLSAgICAgICAgICAgIGlmIChzZyA9PSBudWxsKQotICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgU2NoZW1hR3JhbW1hciBpc2c7Ci0gICAgICAgICAgICAvLyBmb3IgaW1wb3J0ZWQgbmFtZXNwYWNlCi0gICAgICAgICAgICBpbnQgY291bnQgPSAwOwotICAgICAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBpbnMuc2l6ZSgpOyBqKyspIHsKLSAgICAgICAgICAgICAgICAvLyBnZXQgaW1wb3J0ZWQgZ3JhbW1hcgotICAgICAgICAgICAgICAgIGlzZyA9IGZHcmFtbWFyQnVja2V0LmdldEdyYW1tYXIoKFN0cmluZylpbnMuZWxlbWVudEF0KGopKTsKLSAgICAgICAgICAgICAgICAvLyByZXVzZSB0aGUgc2FtZSB2ZWN0b3IKLSAgICAgICAgICAgICAgICBpZiAoaXNnICE9IG51bGwpCi0gICAgICAgICAgICAgICAgICAgIGlucy5zZXRFbGVtZW50QXQoaXNnLCBjb3VudCsrKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlucy5zZXRTaXplKGNvdW50KTsKLSAgICAgICAgICAgIC8vIHNldCB0aGUgaW1wb3J0ZWQgZ3JhbW1hcnMKLSAgICAgICAgICAgIHNnLnNldEltcG9ydGVkR3JhbW1hcnMoaW5zKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKiB2YWxpZGF0ZSBhbm5vdGF0aW9ucyAqKi8KLSAgICAgICAgaWYgKGZWYWxpZGF0ZUFubm90YXRpb25zICYmIGFubm90YXRpb25JbmZvLnNpemUoKSA+IDApIHsKLSAgICAgICAgICAgIHZhbGlkYXRlQW5ub3RhdGlvbnMoYW5ub3RhdGlvbkluZm8pOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gYW5kIHJldHVybi4KLSAgICAgICAgcmV0dXJuIGZHcmFtbWFyQnVja2V0LmdldEdyYW1tYXIoZlJvb3QuZlRhcmdldE5hbWVzcGFjZSk7Ci0gICAgfSAvLyBlbmQgcGFyc2VTY2hlbWEKLQotICAgIHByaXZhdGUgdm9pZCB2YWxpZGF0ZUFubm90YXRpb25zKEFycmF5TGlzdCBhbm5vdGF0aW9uSW5mbykgewotICAgICAgICBpZiAoZkFubm90YXRpb25WYWxpZGF0b3IgPT0gbnVsbCkgewotICAgICAgICAgICAgY3JlYXRlQW5ub3RhdGlvblZhbGlkYXRvcigpOwotICAgICAgICB9Ci0gICAgICAgIGZpbmFsIGludCBzaXplID0gYW5ub3RhdGlvbkluZm8uc2l6ZSgpOwotICAgICAgICBmaW5hbCBYTUxJbnB1dFNvdXJjZSBzcmMgPSBuZXcgWE1MSW5wdXRTb3VyY2UobnVsbCwgbnVsbCwgbnVsbCk7Ci0gICAgICAgIGZHcmFtbWFyQnVja2V0QWRhcHRlci5yZWZyZXNoR3JhbW1hcnMoZkdyYW1tYXJCdWNrZXQpOwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkgKz0gMikgewotICAgICAgICAgICAgc3JjLnNldFN5c3RlbUlkKChTdHJpbmcpIGFubm90YXRpb25JbmZvLmdldChpKSk7Ci0gICAgICAgICAgICBYU0Fubm90YXRpb25JbmZvIGFubm90YXRpb24gPSAoWFNBbm5vdGF0aW9uSW5mbykgYW5ub3RhdGlvbkluZm8uZ2V0KGkrMSk7Ci0gICAgICAgICAgICB3aGlsZSAoYW5ub3RhdGlvbiAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgc3JjLnNldENoYXJhY3RlclN0cmVhbShuZXcgU3RyaW5nUmVhZGVyKGFubm90YXRpb24uZkFubm90YXRpb24pKTsKLSAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICBmQW5ub3RhdGlvblZhbGlkYXRvci5wYXJzZShzcmMpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBjYXRjaCAoSU9FeGNlcHRpb24gZXhjKSB7fQotICAgICAgICAgICAgICAgIGFubm90YXRpb24gPSBhbm5vdGF0aW9uLm5leHQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgY3JlYXRlQW5ub3RhdGlvblZhbGlkYXRvcigpIHsKLSAgICAgICAgZkFubm90YXRpb25WYWxpZGF0b3IgPSBuZXcgWE1MMTFDb25maWd1cmF0aW9uKCk7Ci0gICAgICAgIGZHcmFtbWFyQnVja2V0QWRhcHRlciA9IG5ldyBYU0Fubm90YXRpb25HcmFtbWFyUG9vbCgpOwotICAgICAgICBmQW5ub3RhdGlvblZhbGlkYXRvci5zZXRGZWF0dXJlKFZBTElEQVRJT04sIHRydWUpOwotICAgICAgICBmQW5ub3RhdGlvblZhbGlkYXRvci5zZXRGZWF0dXJlKFhNTFNDSEVNQV9WQUxJREFUSU9OLCB0cnVlKTsKLSAgICAgICAgZkFubm90YXRpb25WYWxpZGF0b3Iuc2V0UHJvcGVydHkoWE1MR1JBTU1BUl9QT09MLCBmR3JhbW1hckJ1Y2tldEFkYXB0ZXIpOwotICAgICAgICAvKiogc2V0IHNlY3VyaXR5IG1hbmFnZXIgYW5kIFhNTCBTZWN1cml0eSBQcm9wZXJ0eSBNYW5hZ2VyICoqLwotICAgICAgICBmQW5ub3RhdGlvblZhbGlkYXRvci5zZXRQcm9wZXJ0eShTRUNVUklUWV9NQU5BR0VSLCAoZlNlY3VyaXR5TWFuYWdlciAhPSBudWxsKSA/IGZTZWN1cml0eU1hbmFnZXIgOiBuZXcgWE1MU2VjdXJpdHlNYW5hZ2VyKHRydWUpKTsKLSAgICAgICAgZkFubm90YXRpb25WYWxpZGF0b3Iuc2V0UHJvcGVydHkoWE1MX1NFQ1VSSVRZX1BST1BFUlRZX01BTkFHRVIsIGZTZWN1cml0eVByb3BlcnR5TWdyKTsKLSAgICAgICAgLyoqIFNldCBlcnJvciBoYW5kbGVyLiAqKi8KLSAgICAgICAgZkFubm90YXRpb25WYWxpZGF0b3Iuc2V0UHJvcGVydHkoRVJST1JfSEFORExFUiwgKGZFcnJvckhhbmRsZXIgIT0gbnVsbCkgPyBmRXJyb3JIYW5kbGVyIDogbmV3IERlZmF1bHRFcnJvckhhbmRsZXIoKSk7Ci0gICAgICAgIC8qKiBTZXQgbG9jYWxlLiAqKi8KLSAgICAgICAgZkFubm90YXRpb25WYWxpZGF0b3Iuc2V0UHJvcGVydHkoTE9DQUxFLCBmTG9jYWxlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBQdWxsIHRoZSBncmFtbWFyIG91dCBvZiB0aGUgYnVja2V0IHNpbXBseSB1c2luZwotICAgICAqIGl0cyBUTlMgYXMgYSBrZXkKLSAgICAgKi8KLSAgICBTY2hlbWFHcmFtbWFyIGdldEdyYW1tYXIoU3RyaW5nIHRucykgewotICAgICAgICByZXR1cm4gZkdyYW1tYXJCdWNrZXQuZ2V0R3JhbW1hcih0bnMpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEZpcnN0IHRyeSB0byBmaW5kIGEgZ3JhbW1hciBpbiB0aGUgYnVja2V0LCBpZiBmYWlsZWQsIGNvbnN1bHQgdGhlCi0gICAgICogZ3JhbW1hciBwb29sLiBJZiBhIGdyYW1tYXIgaXMgZm91bmQgaW4gdGhlIHBvb2wsIHRoZW4gYWRkIGl0IChhbmQgYWxsCi0gICAgICogaW1wb3J0ZWQgb25lcykgaW50byB0aGUgYnVja2V0LgotICAgICAqLwotICAgIHByb3RlY3RlZCBTY2hlbWFHcmFtbWFyIGZpbmRHcmFtbWFyKFhTRERlc2NyaXB0aW9uIGRlc2MsIGJvb2xlYW4gaWdub3JlQ29uZmxpY3QpIHsKLSAgICAgICAgU2NoZW1hR3JhbW1hciBzZyA9IGZHcmFtbWFyQnVja2V0LmdldEdyYW1tYXIoZGVzYy5nZXRUYXJnZXROYW1lc3BhY2UoKSk7Ci0gICAgICAgIGlmIChzZyA9PSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAoZkdyYW1tYXJQb29sICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBzZyA9IChTY2hlbWFHcmFtbWFyKWZHcmFtbWFyUG9vbC5yZXRyaWV2ZUdyYW1tYXIoZGVzYyk7Ci0gICAgICAgICAgICAgICAgaWYgKHNnICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gcHV0IHRoaXMgZ3JhbW1hciBpbnRvIHRoZSBidWNrZXQsIGFsb25nIHdpdGggZ3JhbW1hcnMKLSAgICAgICAgICAgICAgICAgICAgLy8gaW1wb3J0ZWQgYnkgaXQgKGRpcmVjdGx5IG9yIGluZGlyZWN0bHkpCi0gICAgICAgICAgICAgICAgICAgIGlmICghZkdyYW1tYXJCdWNrZXQucHV0R3JhbW1hcihzZywgdHJ1ZSwgaWdub3JlQ29uZmxpY3QpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBSRVZJU0lUOiBhIGNvbmZsaWN0IGJldHdlZW4gbmV3IGdyYW1tYXIocykgYW5kIGdyYW1tYXJzCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBpbiB0aGUgYnVja2V0LiBXaGF0IHRvIGRvPyBBIHdhcm5pbmc/IEFuIGV4Y2VwdGlvbj8KLSAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydFNjaGVtYVdhcm5pbmcoIkdyYW1tYXJDb25mbGljdCIsIG51bGwsIG51bGwpOwotICAgICAgICAgICAgICAgICAgICAgICAgc2cgPSBudWxsOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBzZzsKLSAgICB9Ci0KLSAgICAvLyBtYXkgd2lzaCB0byBoYXZlIHNldHRlciBtZXRob2RzIGZvciBFcnJvckhhbmRsZXIsCi0gICAgLy8gRW50aXR5UmVzb2x2ZXIuLi4KLQotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZ1tdW10gTlNfRVJST1JfQ09ERVMgPSB7Ci0gICAgICAgICAgICB7InNyYy1pbmNsdWRlLjIuMSIsICJzcmMtaW5jbHVkZS4yLjEifSwKLSAgICAgICAgICAgIHsic3JjLXJlZGVmaW5lLjMuMSIsICJzcmMtcmVkZWZpbmUuMy4xIn0sCi0gICAgICAgICAgICB7InNyYy1pbXBvcnQuMy4xIiwgInNyYy1pbXBvcnQuMy4yIn0sCi0gICAgICAgICAgICBudWxsLAotICAgICAgICAgICAgeyJUYXJnZXROYW1lc3BhY2UuMSIsICJUYXJnZXROYW1lc3BhY2UuMiJ9LAotICAgICAgICAgICAgeyJUYXJnZXROYW1lc3BhY2UuMSIsICJUYXJnZXROYW1lc3BhY2UuMiJ9LAotICAgICAgICAgICAgeyJUYXJnZXROYW1lc3BhY2UuMSIsICJUYXJnZXROYW1lc3BhY2UuMiJ9LAotICAgICAgICAgICAgeyJUYXJnZXROYW1lc3BhY2UuMSIsICJUYXJnZXROYW1lc3BhY2UuMiJ9Ci0gICAgfTsKLQotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZ1tdIEVMRV9FUlJPUl9DT0RFUyA9IHsKLSAgICAgICAgICAgICJzcmMtaW5jbHVkZS4xIiwgInNyYy1yZWRlZmluZS4yIiwgInNyYy1pbXBvcnQuMiIsICJzY2hlbWFfcmVmZXJlbmNlLjQiLAotICAgICAgICAgICAgInNjaGVtYV9yZWZlcmVuY2UuNCIsICJzY2hlbWFfcmVmZXJlbmNlLjQiLCAic2NoZW1hX3JlZmVyZW5jZS40IiwgInNjaGVtYV9yZWZlcmVuY2UuNCIKLSAgICB9OwotCi0gICAgLy8gVGhpcyBtZXRob2QgZG9lcyBzZXZlcmFsIHRoaW5nczoKLSAgICAvLyBJdCBjb25zdHJ1Y3RzIGFuIGluc3RhbmNlIG9mIGFuIFhTRG9jdW1lbnRJbmZvIG9iamVjdCB1c2luZyB0aGUKLSAgICAvLyBzY2hlbWFSb290IG5vZGUuICBUaGVuLCBmb3IgZWFjaCA8aW5jbHVkZT4sCi0gICAgLy8gPHJlZGVmaW5lPiwgYW5kIDxpbXBvcnQ+IGNoaWxkcmVuLCBpdCBhdHRlbXB0cyB0byByZXNvbHZlIHRoZQotICAgIC8vIHJlcXVlc3RlZCBzY2hlbWEgZG9jdW1lbnQsIGluaXRpYXRlcyBhIERPTSBwYXJzZSwgYW5kIGNhbGxzCi0gICAgLy8gaXRzZWxmIHJlY3Vyc2l2ZWx5IG9uIHRoYXQgZG9jdW1lbnQncyByb290LiAgSXQgYWxzbyByZWNvcmRzIGluCi0gICAgLy8gdGhlIERlcGVuZGVuY3lNYXAgb2JqZWN0IHdoYXQgWFNEb2N1bWVudEluZm8gb2JqZWN0cyBpdHMgWFNEb2N1bWVudEluZm8KLSAgICAvLyBkZXBlbmRzIG9uLgotICAgIC8vIEl0IGFsc28gbWFrZXMgc3VyZSB0aGUgdGFyZ2V0TmFtZXNwYWNlIG9mIHRoZSBzY2hlbWEgaXQgd2FzCi0gICAgLy8gY2FsbGVkIHRvIHBhcnNlIGlzIGNvcnJlY3QuCi0gICAgcHJvdGVjdGVkIFhTRG9jdW1lbnRJbmZvIGNvbnN0cnVjdFRyZWVzKEVsZW1lbnQgc2NoZW1hUm9vdCwgU3RyaW5nIGxvY2F0aW9uSGludCwgWFNERGVzY3JpcHRpb24gZGVzYywgYm9vbGVhbiBuc0NvbGxpc2lvbikgewotICAgICAgICBpZiAoc2NoZW1hUm9vdCA9PSBudWxsKSByZXR1cm4gbnVsbDsKLSAgICAgICAgU3RyaW5nIGNhbGxlclROUyA9IGRlc2MuZ2V0VGFyZ2V0TmFtZXNwYWNlKCk7Ci0gICAgICAgIHNob3J0IHJlZmVyVHlwZSA9IGRlc2MuZ2V0Q29udGV4dFR5cGUoKTsKLQotICAgICAgICBYU0RvY3VtZW50SW5mbyBjdXJyU2NoZW1hSW5mbyA9IG51bGw7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAvLyBub3RlIHRoYXQgYXR0cmlidXRlcyBhcmUgZnJlZWQgYXQgZW5kIG9mIHRyYXZlcnNlU2NoZW1hcygpCi0gICAgICAgICAgICBjdXJyU2NoZW1hSW5mbyA9IG5ldyBYU0RvY3VtZW50SW5mbyhzY2hlbWFSb290LCBmQXR0cmlidXRlQ2hlY2tlciwgZlN5bWJvbFRhYmxlKTsKLSAgICAgICAgfSBjYXRjaCAoWE1MU2NoZW1hRXhjZXB0aW9uIHNlKSB7Ci0gICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcihFTEVfRVJST1JfQ09ERVNbcmVmZXJUeXBlXSwKLSAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde2xvY2F0aW9uSGludH0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2hlbWFSb290KTsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgICAgIC8vIHRhcmdldE5hbWVzcGFjZT0iIiBpcyBub3QgdmFsaWQsIGlzc3VlIGEgd2FybmluZywgYW5kIGlnbm9yZSBpdAotICAgICAgICBpZiAoY3VyclNjaGVtYUluZm8uZlRhcmdldE5hbWVzcGFjZSAhPSBudWxsICYmCi0gICAgICAgICAgICAgICAgY3VyclNjaGVtYUluZm8uZlRhcmdldE5hbWVzcGFjZS5sZW5ndGgoKSA9PSAwKSB7Ci0gICAgICAgICAgICByZXBvcnRTY2hlbWFXYXJuaW5nKCJFbXB0eVRhcmdldE5hbWVzcGFjZSIsCi0gICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXtsb2NhdGlvbkhpbnR9LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjaGVtYVJvb3QpOwotICAgICAgICAgICAgY3VyclNjaGVtYUluZm8uZlRhcmdldE5hbWVzcGFjZSA9IG51bGw7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoY2FsbGVyVE5TICE9IG51bGwpIHsKLSAgICAgICAgICAgIC8vIHRoZSBzZWNvbmQgaW5kZXggdG8gdGhlIE5TX0VSUk9SX0NPREVTIGFycmF5Ci0gICAgICAgICAgICAvLyBpZiB0aGUgY2FsbGVyL2V4cGVjdGVkIE5TIGlzIG5vdCBhYnNlbnQsIHdlIHVzZSB0aGUgZmlyc3QgY29sdW1uCi0gICAgICAgICAgICBpbnQgc2Vjb25kSWR4ID0gMDsKLSAgICAgICAgICAgIC8vIGZvciBpbmNsdWRlIGFuZCByZWRlZmluZQotICAgICAgICAgICAgaWYgKHJlZmVyVHlwZSA9PSBYU0REZXNjcmlwdGlvbi5DT05URVhUX0lOQ0xVREUgfHwKLSAgICAgICAgICAgICAgICAgICAgcmVmZXJUeXBlID09IFhTRERlc2NyaXB0aW9uLkNPTlRFWFRfUkVERUZJTkUpIHsKLSAgICAgICAgICAgICAgICAvLyBpZiB0aGUgcmVmZXJyZWQgZG9jdW1lbnQgaGFzIG5vIHRhcmdldE5hbWVzcGFjZSwKLSAgICAgICAgICAgICAgICAvLyBpdCdzIGEgY2hhbWVsZW9uIHNjaGVtYQotICAgICAgICAgICAgICAgIGlmIChjdXJyU2NoZW1hSW5mby5mVGFyZ2V0TmFtZXNwYWNlID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgY3VyclNjaGVtYUluZm8uZlRhcmdldE5hbWVzcGFjZSA9IGNhbGxlclROUzsKLSAgICAgICAgICAgICAgICAgICAgY3VyclNjaGVtYUluZm8uZklzQ2hhbWVsZW9uU2NoZW1hID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLy8gaWYgdGhlIHJlZmVycmVkIGRvY3VtZW50IGhhcyBhIHRhcmdldCBuYW1lc3BhY2UgZGlmZmVyaW5nCi0gICAgICAgICAgICAgICAgLy8gZnJvbSB0aGUgY2FsbGVyLCBpdCdzIGFuIGVycm9yCi0gICAgICAgICAgICAgICAgZWxzZSBpZiAoY2FsbGVyVE5TICE9IGN1cnJTY2hlbWFJbmZvLmZUYXJnZXROYW1lc3BhY2UpIHsKLSAgICAgICAgICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoTlNfRVJST1JfQ09ERVNbcmVmZXJUeXBlXVtzZWNvbmRJZHhdLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3QgW10ge2NhbGxlclROUywgY3VyclNjaGVtYUluZm8uZlRhcmdldE5hbWVzcGFjZX0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjaGVtYVJvb3QpOwotICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyBmb3IgaW5zdGFuY2UgYW5kIGltcG9ydCwgdGhlIHR3byBOUydzIG11c3QgYmUgdGhlIHNhbWUKLSAgICAgICAgICAgIGVsc2UgaWYgKHJlZmVyVHlwZSAhPSBYU0REZXNjcmlwdGlvbi5DT05URVhUX1BSRVBBUlNFICYmIGNhbGxlclROUyAhPSBjdXJyU2NoZW1hSW5mby5mVGFyZ2V0TmFtZXNwYWNlKSB7Ci0gICAgICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoTlNfRVJST1JfQ09ERVNbcmVmZXJUeXBlXVtzZWNvbmRJZHhdLAotICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdCBbXSB7Y2FsbGVyVE5TLCBjdXJyU2NoZW1hSW5mby5mVGFyZ2V0TmFtZXNwYWNlfSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjaGVtYVJvb3QpOwotICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIC8vIG5vdyB0aGVyZSBpcyBubyBjYWxsZXIvZXhwZWN0ZWQgTlMsIGl0J3MgYW4gZXJyb3IgZm9yIHRoZSByZWZlcnJlZAotICAgICAgICAvLyBkb2N1bWVudCB0byBoYXZlIGEgdGFyZ2V0IG5hbWVzcGFjZSwgdW5sZXNzIHdlIGFyZSBwcmVwYXJzaW5nIGEgc2NoZW1hCi0gICAgICAgIGVsc2UgaWYgKGN1cnJTY2hlbWFJbmZvLmZUYXJnZXROYW1lc3BhY2UgIT0gbnVsbCkgewotICAgICAgICAgICAgLy8gc2V0IHRoZSB0YXJnZXQgbmFtZXNwYWNlIG9mIHRoZSBkZXNjcmlwdGlvbgotICAgICAgICAgICAgaWYgKHJlZmVyVHlwZSA9PSBYU0REZXNjcmlwdGlvbi5DT05URVhUX1BSRVBBUlNFKSB7Ci0gICAgICAgICAgICAgICAgZGVzYy5zZXRUYXJnZXROYW1lc3BhY2UoY3VyclNjaGVtYUluZm8uZlRhcmdldE5hbWVzcGFjZSk7Ci0gICAgICAgICAgICAgICAgY2FsbGVyVE5TID0gY3VyclNjaGVtYUluZm8uZlRhcmdldE5hbWVzcGFjZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIC8vIHRoZSBzZWNvbmQgaW5kZXggdG8gdGhlIE5TX0VSUk9SX0NPREVTIGFycmF5Ci0gICAgICAgICAgICAgICAgLy8gaWYgdGhlIGNhbGxlci9leHBlY3RlZCBOUyBpcyBhYnNlbnQsIHdlIHVzZSB0aGUgc2Vjb25kIGNvbHVtbgotICAgICAgICAgICAgICAgIGludCBzZWNvbmRJZHggPSAxOwotICAgICAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKE5TX0VSUk9SX0NPREVTW3JlZmVyVHlwZV1bc2Vjb25kSWR4XSwKLSAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3QgW10ge2NhbGxlclROUywgY3VyclNjaGVtYUluZm8uZlRhcmdldE5hbWVzcGFjZX0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2hlbWFSb290KTsKLSAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICAvLyB0aGUgb3RoZXIgY2FzZXMgKGNhbGxlclROUyA9PSBjdXJyU2NoZW1hSW5mby5mVGFyZ2V0TmFtZXNwY2UgPT0gbnVsbCkKLSAgICAgICAgLy8gYXJlIHZhbGlkCi0KLSAgICAgICAgLy8gYSBzY2hlbWEgZG9jdW1lbnQgY2FuIGFsd2F5cyBhY2Nlc3MgaXQncyBvd24gdGFyZ2V0IG5hbWVzcGFjZQotICAgICAgICBjdXJyU2NoZW1hSW5mby5hZGRBbGxvd2VkTlMoY3VyclNjaGVtYUluZm8uZlRhcmdldE5hbWVzcGFjZSk7Ci0KLSAgICAgICAgU2NoZW1hR3JhbW1hciBzZyA9IG51bGw7Ci0KLSAgICAgICAgLy8gd2UgaGF2ZSBhIG5hbWVzcGFjZSBjb2xsaXNpb24KLSAgICAgICAgaWYgKG5zQ29sbGlzaW9uKSB7Ci0gICAgICAgICAgICBTY2hlbWFHcmFtbWFyIHNnMiA9IGZHcmFtbWFyQnVja2V0LmdldEdyYW1tYXIoY3VyclNjaGVtYUluZm8uZlRhcmdldE5hbWVzcGFjZSk7Ci0gICAgICAgICAgICBpZiAoc2cyLmlzSW1tdXRhYmxlKCkpIHsKLSAgICAgICAgICAgICAgICBzZyA9IG5ldyBTY2hlbWFHcmFtbWFyKHNnMik7Ci0gICAgICAgICAgICAgICAgZkdyYW1tYXJCdWNrZXQucHV0R3JhbW1hcihzZyk7Ci0gICAgICAgICAgICAgICAgLy8gdXBkYXRlIGFsbCB0aGUgZ3JhbW1hcnMgaW4gdGhlIGJ1Y2tldCB0byBwb2ludCB0byB0aGUgbmV3IGdyYW1tYXIuCi0gICAgICAgICAgICAgICAgdXBkYXRlSW1wb3J0TGlzdFdpdGgoc2cpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgc2cgPSBzZzI7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIHVwZGF0ZSBpbXBvcnQgbGlzdCBvZiB0aGUgbmV3IGdyYW1tYXIKLSAgICAgICAgICAgIHVwZGF0ZUltcG9ydExpc3RGb3Ioc2cpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKHJlZmVyVHlwZSA9PSBYU0REZXNjcmlwdGlvbi5DT05URVhUX0lOQ0xVREUgfHwKLSAgICAgICAgICAgICAgICByZWZlclR5cGUgPT0gWFNERGVzY3JpcHRpb24uQ09OVEVYVF9SRURFRklORSkgewotICAgICAgICAgICAgc2cgPSBmR3JhbW1hckJ1Y2tldC5nZXRHcmFtbWFyKGN1cnJTY2hlbWFJbmZvLmZUYXJnZXROYW1lc3BhY2UpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYoZkhvbm91ckFsbFNjaGVtYUxvY2F0aW9ucyAmJiByZWZlclR5cGUgPT0gWFNERGVzY3JpcHRpb24uQ09OVEVYVF9JTVBPUlQpIHsKLSAgICAgICAgICAgIHNnID0gZmluZEdyYW1tYXIoZGVzYywgZmFsc2UpOwotICAgICAgICAgICAgaWYoc2cgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHNnID0gbmV3IFNjaGVtYUdyYW1tYXIoY3VyclNjaGVtYUluZm8uZlRhcmdldE5hbWVzcGFjZSwgZGVzYy5tYWtlQ2xvbmUoKSwgZlN5bWJvbFRhYmxlKTsKLSAgICAgICAgICAgICAgICBmR3JhbW1hckJ1Y2tldC5wdXRHcmFtbWFyKHNnKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHNnID0gbmV3IFNjaGVtYUdyYW1tYXIoY3VyclNjaGVtYUluZm8uZlRhcmdldE5hbWVzcGFjZSwgZGVzYy5tYWtlQ2xvbmUoKSwgZlN5bWJvbFRhYmxlKTsKLSAgICAgICAgICAgIGZHcmFtbWFyQnVja2V0LnB1dEdyYW1tYXIoc2cpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gc3RvcmUgdGhlIGRvY3VtZW50IGFuZCBpdHMgbG9jYXRpb24KLSAgICAgICAgLy8gUkVWSVNJVDogZG9uJ3QgZXhwb3NlIHRoZSBET00gdHJlZQotICAgICAgICBzZy5hZGREb2N1bWVudChudWxsLCBmRG9jMlN5c3RlbUlkLmdldChjdXJyU2NoZW1hSW5mby5mU2NoZW1hRWxlbWVudCkpOwotCi0gICAgICAgIGZEb2MyWFNEb2N1bWVudE1hcC5wdXQoc2NoZW1hUm9vdCwgY3VyclNjaGVtYUluZm8pOwotICAgICAgICBWZWN0b3I8WFNEb2N1bWVudEluZm8+IGRlcGVuZGVuY2llcyA9IG5ldyBWZWN0b3I8PigpOwotICAgICAgICBFbGVtZW50IHJvb3ROb2RlID0gc2NoZW1hUm9vdDsKLQotICAgICAgICBFbGVtZW50IG5ld1NjaGVtYVJvb3QgPSBudWxsOwotICAgICAgICBmb3IgKEVsZW1lbnQgY2hpbGQgPSBET01VdGlsLmdldEZpcnN0Q2hpbGRFbGVtZW50KHJvb3ROb2RlKTsKLSAgICAgICAgY2hpbGQgIT0gbnVsbDsKLSAgICAgICAgY2hpbGQgPSBET01VdGlsLmdldE5leHRTaWJsaW5nRWxlbWVudChjaGlsZCkpIHsKLSAgICAgICAgICAgIFN0cmluZyBzY2hlbWFOYW1lc3BhY2U9bnVsbDsKLSAgICAgICAgICAgIFN0cmluZyBzY2hlbWFIaW50PW51bGw7Ci0gICAgICAgICAgICBTdHJpbmcgbG9jYWxOYW1lID0gRE9NVXRpbC5nZXRMb2NhbE5hbWUoY2hpbGQpOwotCi0gICAgICAgICAgICBzaG9ydCByZWZUeXBlID0gLTE7Ci0gICAgICAgICAgICBib29sZWFuIGltcG9ydENvbGxpc2lvbiA9IGZhbHNlOwotCi0gICAgICAgICAgICBpZiAobG9jYWxOYW1lLmVxdWFscyhTY2hlbWFTeW1ib2xzLkVMVF9BTk5PVEFUSU9OKSkKLSAgICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgIGVsc2UgaWYgKGxvY2FsTmFtZS5lcXVhbHMoU2NoZW1hU3ltYm9scy5FTFRfSU1QT1JUKSkgewotICAgICAgICAgICAgICAgIHJlZlR5cGUgPSBYU0REZXNjcmlwdGlvbi5DT05URVhUX0lNUE9SVDsKLSAgICAgICAgICAgICAgICAvLyBoYXZlIHRvIGhhbmRsZSBzb21lIHZhbGlkYXRpb24gaGVyZSB0b28hCi0gICAgICAgICAgICAgICAgLy8gY2FsbCBYU0F0dHJpYnV0ZUNoZWNrZXIgdG8gZmlsbCBpbiBhdHRycwotICAgICAgICAgICAgICAgIE9iamVjdFtdIGltcG9ydEF0dHJzID0gZkF0dHJpYnV0ZUNoZWNrZXIuY2hlY2tBdHRyaWJ1dGVzKGNoaWxkLCB0cnVlLCBjdXJyU2NoZW1hSW5mbyk7Ci0gICAgICAgICAgICAgICAgc2NoZW1hSGludCA9IChTdHJpbmcpaW1wb3J0QXR0cnNbWFNBdHRyaWJ1dGVDaGVja2VyLkFUVElEWF9TQ0hFTUFMT0NBVElPTl07Ci0gICAgICAgICAgICAgICAgc2NoZW1hTmFtZXNwYWNlID0gKFN0cmluZylpbXBvcnRBdHRyc1tYU0F0dHJpYnV0ZUNoZWNrZXIuQVRUSURYX05BTUVTUEFDRV07Ci0gICAgICAgICAgICAgICAgaWYgKHNjaGVtYU5hbWVzcGFjZSAhPSBudWxsKQotICAgICAgICAgICAgICAgICAgICBzY2hlbWFOYW1lc3BhY2UgPSBmU3ltYm9sVGFibGUuYWRkU3ltYm9sKHNjaGVtYU5hbWVzcGFjZSk7Ci0KLSAgICAgICAgICAgICAgICAvLyBjaGVjayBjb250ZW50cyBhbmQgcHJvY2VzcyBvcHRpb25hbCBhbm5vdGF0aW9ucwotICAgICAgICAgICAgICAgIEVsZW1lbnQgaW1wb3J0Q2hpbGQgPSBET01VdGlsLmdldEZpcnN0Q2hpbGRFbGVtZW50KGNoaWxkKTsKLSAgICAgICAgICAgICAgICBpZihpbXBvcnRDaGlsZCAhPSBudWxsICkgewotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgaW1wb3J0Q29tcG9uZW50VHlwZSA9IERPTVV0aWwuZ2V0TG9jYWxOYW1lKGltcG9ydENoaWxkKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGltcG9ydENvbXBvbmVudFR5cGUuZXF1YWxzKFNjaGVtYVN5bWJvbHMuRUxUX0FOTk9UQVRJT04pKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBwcm9tb3RpbmcgYW5ub3RhdGlvbnMgdG8gcGFyZW50IGNvbXBvbmVudAotICAgICAgICAgICAgICAgICAgICAgICAgc2cuYWRkQW5ub3RhdGlvbigKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkVsZW1lbnRUcmF2ZXJzZXIudHJhdmVyc2VBbm5vdGF0aW9uRGVjbChpbXBvcnRDaGlsZCwgaW1wb3J0QXR0cnMsIHRydWUsIGN1cnJTY2hlbWFJbmZvKSk7Ci0gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcigiczRzLWVsdC1tdXN0LW1hdGNoLjEiLCBuZXcgT2JqZWN0IFtdIHtsb2NhbE5hbWUsICJhbm5vdGF0aW9uPyIsIGltcG9ydENvbXBvbmVudFR5cGV9LCBjaGlsZCk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgaWYoRE9NVXRpbC5nZXROZXh0U2libGluZ0VsZW1lbnQoaW1wb3J0Q2hpbGQpICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKCJzNHMtZWx0LW11c3QtbWF0Y2guMSIsIG5ldyBPYmplY3QgW10ge2xvY2FsTmFtZSwgImFubm90YXRpb24/IiwgRE9NVXRpbC5nZXRMb2NhbE5hbWUoRE9NVXRpbC5nZXROZXh0U2libGluZ0VsZW1lbnQoaW1wb3J0Q2hpbGQpKX0sIGNoaWxkKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHRleHQgPSBET01VdGlsLmdldFN5bnRoZXRpY0Fubm90YXRpb24oY2hpbGQpOwotICAgICAgICAgICAgICAgICAgICBpZiAodGV4dCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzZy5hZGRBbm5vdGF0aW9uKGZFbGVtZW50VHJhdmVyc2VyLnRyYXZlcnNlU3ludGhldGljQW5ub3RhdGlvbihjaGlsZCwgdGV4dCwgaW1wb3J0QXR0cnMsIHRydWUsIGN1cnJTY2hlbWFJbmZvKSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZkF0dHJpYnV0ZUNoZWNrZXIucmV0dXJuQXR0ckFycmF5KGltcG9ydEF0dHJzLCBjdXJyU2NoZW1hSW5mbyk7Ci0KLSAgICAgICAgICAgICAgICAvLyBhIGRvY3VtZW50IGNhbid0IGltcG9ydCBhbm90aGVyIGRvY3VtZW50IHdpdGggdGhlIHNhbWUgbmFtZXNwYWNlCi0gICAgICAgICAgICAgICAgaWYgKHNjaGVtYU5hbWVzcGFjZSA9PSBjdXJyU2NoZW1hSW5mby5mVGFyZ2V0TmFtZXNwYWNlKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKHNjaGVtYU5hbWVzcGFjZSAhPSBudWxsID8KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAic3JjLWltcG9ydC4xLjEiIDogInNyYy1pbXBvcnQuMS4yIiwgbmV3IE9iamVjdCBbXSB7c2NoZW1hTmFtZXNwYWNlfSwgY2hpbGQpOwotICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyBpZiB0aGlzIG5hbWVzcGFjZSBoYXMgbm90IGJlZW4gaW1wb3J0ZWQgYnkgdGhpcyBkb2N1bWVudCwKLSAgICAgICAgICAgICAgICAvLyAgdGhlbiBpbXBvcnQgaWYgbXVsdGlwbGUgaW1wb3J0cyBzdXBwb3J0IGlzIGVuYWJsZWQuCi0gICAgICAgICAgICAgICAgaWYoY3VyclNjaGVtYUluZm8uaXNBbGxvd2VkTlMoc2NoZW1hTmFtZXNwYWNlKSkgewotICAgICAgICAgICAgICAgICAgICBpZighZkhvbm91ckFsbFNjaGVtYUxvY2F0aW9ucyAmJiAhZk5hbWVzcGFjZUdyb3d0aCkKLSAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlICB7Ci0gICAgICAgICAgICAgICAgICAgIGN1cnJTY2hlbWFJbmZvLmFkZEFsbG93ZWROUyhzY2hlbWFOYW1lc3BhY2UpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvLyBhbHNvIHJlY29yZCB0aGUgZmFjdCB0aGF0IG9uZSBuYW1lc3BhY2UgaW1wb3J0cyBhbm90aGVyIG9uZQotICAgICAgICAgICAgICAgIC8vIGNvbnZlcnQgbnVsbCB0byAiIgotICAgICAgICAgICAgICAgIFN0cmluZyB0bnMgPSBudWxsMkVtcHR5U3RyaW5nKGN1cnJTY2hlbWFJbmZvLmZUYXJnZXROYW1lc3BhY2UpOwotICAgICAgICAgICAgICAgIC8vIGdldCBhbGwgbmFtZXNwYWNlcyBpbXBvcnRlZCBieSB0aGlzIG9uZQotICAgICAgICAgICAgICAgIFZlY3RvciBpbnMgPSAoVmVjdG9yKWZJbXBvcnRNYXAuZ2V0KHRucyk7Ci0gICAgICAgICAgICAgICAgLy8gaWYgbm8gbmFtZXNwYWNlIHdhcyBpbXBvcnRlZCwgY3JlYXRlIG5ldyBWZWN0b3IKLSAgICAgICAgICAgICAgICBpZiAoaW5zID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gcmVjb3JkIHRoYXQgdGhpcyBvbmUgaW1wb3J0cyBvdGhlcihzKQotICAgICAgICAgICAgICAgICAgICBmQWxsVE5Tcy5hZGRFbGVtZW50KHRucyk7Ci0gICAgICAgICAgICAgICAgICAgIGlucyA9IG5ldyBWZWN0b3IoKTsKLSAgICAgICAgICAgICAgICAgICAgZkltcG9ydE1hcC5wdXQodG5zLCBpbnMpOwotICAgICAgICAgICAgICAgICAgICBpbnMuYWRkRWxlbWVudChzY2hlbWFOYW1lc3BhY2UpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIGlmICghaW5zLmNvbnRhaW5zKHNjaGVtYU5hbWVzcGFjZSkpewotICAgICAgICAgICAgICAgICAgICBpbnMuYWRkRWxlbWVudChzY2hlbWFOYW1lc3BhY2UpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIGZTY2hlbWFHcmFtbWFyRGVzY3JpcHRpb24ucmVzZXQoKTsKLSAgICAgICAgICAgICAgICBmU2NoZW1hR3JhbW1hckRlc2NyaXB0aW9uLnNldENvbnRleHRUeXBlKFhTRERlc2NyaXB0aW9uLkNPTlRFWFRfSU1QT1JUKTsKLSAgICAgICAgICAgICAgICBmU2NoZW1hR3JhbW1hckRlc2NyaXB0aW9uLnNldEJhc2VTeXN0ZW1JZChkb2MyU3lzdGVtSWQoc2NoZW1hUm9vdCkpOwotICAgICAgICAgICAgICAgIGZTY2hlbWFHcmFtbWFyRGVzY3JpcHRpb24uc2V0TGl0ZXJhbFN5c3RlbUlkKHNjaGVtYUhpbnQpOwotICAgICAgICAgICAgICAgIGZTY2hlbWFHcmFtbWFyRGVzY3JpcHRpb24uc2V0TG9jYXRpb25IaW50cyhuZXcgU3RyaW5nW117c2NoZW1hSGludH0pOwotICAgICAgICAgICAgICAgIGZTY2hlbWFHcmFtbWFyRGVzY3JpcHRpb24uc2V0VGFyZ2V0TmFtZXNwYWNlKHNjaGVtYU5hbWVzcGFjZSk7Ci0KLSAgICAgICAgICAgICAgICAvLyBpZiBhIGdyYW1tYXIgd2l0aCB0aGUgc2FtZSBuYW1lc3BhY2UgYW5kIGxvY2F0aW9uIGV4aXN0cyAob3IgYmVpbmcKLSAgICAgICAgICAgICAgICAvLyBidWlsdCksIGlnbm9yZSB0aGlzIG9uZSAoZG9uJ3QgdHJhdmVyc2UgaXQpLgotICAgICAgICAgICAgICAgIFNjaGVtYUdyYW1tYXIgaXNnID0gZmluZEdyYW1tYXIoZlNjaGVtYUdyYW1tYXJEZXNjcmlwdGlvbiwgZk5hbWVzcGFjZUdyb3d0aCk7Ci0gICAgICAgICAgICAgICAgaWYgKGlzZyAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChmTmFtZXNwYWNlR3Jvd3RoKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc2cuZ2V0RG9jdW1lbnRMb2NhdGlvbnMoKS5jb250YWlucyhYTUxFbnRpdHlNYW5hZ2VyLmV4cGFuZFN5c3RlbUlkKHNjaGVtYUhpbnQsIGZTY2hlbWFHcmFtbWFyRGVzY3JpcHRpb24uZ2V0QmFzZVN5c3RlbUlkKCksIGZhbHNlKSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbXBvcnRDb2xsaXNpb24gPSB0cnVlOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGNhdGNoIChNYWxmb3JtZWRVUklFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKCFmSG9ub3VyQWxsU2NoZW1hTG9jYXRpb25zIHx8IGlzRXhpc3RpbmdHcmFtbWFyKGZTY2hlbWFHcmFtbWFyRGVzY3JpcHRpb24sIGZhbHNlKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLy9pZiAoKCFmSG9ub3VyQWxsU2NoZW1hTG9jYXRpb25zICYmIGZpbmRHcmFtbWFyKGZTY2hlbWFHcmFtbWFyRGVzY3JpcHRpb24pICE9IG51bGwpIHx8IGlzRXhpc3RpbmdHcmFtbWFyKGZTY2hlbWFHcmFtbWFyRGVzY3JpcHRpb24pKQotICAgICAgICAgICAgICAgIC8vICAgIGNvbnRpbnVlOwotCi0gICAgICAgICAgICAgICAgLy8gSWYgImZpbmRHcmFtbWFyIiByZXR1cm5zIGEgZ3JhbW1hciwgdGhlbiB0aGlzIGlzIG5vdCB0aGUKLSAgICAgICAgICAgICAgICAvLyB0aGUgZmlyc3QgdGltZSB3ZSBzZWUgYSBsb2NhdGlvbiBmb3IgYSBnaXZlbiBuYW1lc3BhY2UuCi0gICAgICAgICAgICAgICAgLy8gRG9uJ3QgY29uc3VsdCB0aGUgbG9jYXRpb24gcGFpciBtYXAgaW4gdGhpcyBjYXNlLAotICAgICAgICAgICAgICAgIC8vIG90aGVyd2lzZSB0aGUgbG9jYXRpb24gd2lsbCBiZSBpZ25vcmVkIGJlY2F1c2UgaXQnbGwgZ2V0Ci0gICAgICAgICAgICAgICAgLy8gcmVzb2x2ZWQgdG8gdGhlIHNhbWUgbG9jYXRpb24gYXMgdGhlIGZpcnN0IGhpbnQuCi0gICAgICAgICAgICAgICAgbmV3U2NoZW1hUm9vdCA9IHJlc29sdmVTY2hlbWEoZlNjaGVtYUdyYW1tYXJEZXNjcmlwdGlvbiwgZmFsc2UsIGNoaWxkLCBpc2cgPT0gbnVsbCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmICgobG9jYWxOYW1lLmVxdWFscyhTY2hlbWFTeW1ib2xzLkVMVF9JTkNMVURFKSkgfHwKLSAgICAgICAgICAgICAgICAgICAgKGxvY2FsTmFtZS5lcXVhbHMoU2NoZW1hU3ltYm9scy5FTFRfUkVERUZJTkUpKSkgewotICAgICAgICAgICAgICAgIC8vIHZhbGlkYXRpb24gZm9yIHJlZGVmaW5lL2luY2x1ZGUgd2lsbCBiZSB0aGUgc2FtZSBoZXJlOyBqdXN0Ci0gICAgICAgICAgICAgICAgLy8gbWFrZSBzdXJlIFROUyBpcyByaWdodCAoZG9uJ3QgY2FyZSBhYm91dCByZWRlZiBjb250ZW50cwotICAgICAgICAgICAgICAgIC8vIHlldCkuCi0gICAgICAgICAgICAgICAgT2JqZWN0W10gaW5jbHVkZUF0dHJzID0gZkF0dHJpYnV0ZUNoZWNrZXIuY2hlY2tBdHRyaWJ1dGVzKGNoaWxkLCB0cnVlLCBjdXJyU2NoZW1hSW5mbyk7Ci0gICAgICAgICAgICAgICAgc2NoZW1hSGludCA9IChTdHJpbmcpaW5jbHVkZUF0dHJzW1hTQXR0cmlidXRlQ2hlY2tlci5BVFRJRFhfU0NIRU1BTE9DQVRJT05dOwotICAgICAgICAgICAgICAgIC8vIHN0b3JlIHRoZSBuYW1lc3BhY2UgZGVjbHMgb2YgdGhlIHJlZGVmaW5lIGVsZW1lbnQKLSAgICAgICAgICAgICAgICBpZiAobG9jYWxOYW1lLmVxdWFscyhTY2hlbWFTeW1ib2xzLkVMVF9SRURFRklORSkpIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGZSZWRlZmluZTJOU1N1cHBvcnQgPT0gbnVsbCkgZlJlZGVmaW5lMk5TU3VwcG9ydCA9IG5ldyBIYXNoTWFwKCk7Ci0gICAgICAgICAgICAgICAgICAgIGZSZWRlZmluZTJOU1N1cHBvcnQucHV0KGNoaWxkLCBuZXcgU2NoZW1hTmFtZXNwYWNlU3VwcG9ydChjdXJyU2NoZW1hSW5mby5mTmFtZXNwYWNlU3VwcG9ydCkpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8vIGNoZWNrIGFubm90YXRpb25zLiAgTXVzdCBkbyB0aGlzIGhlcmUgdG8gYXZvaWQgaGF2aW5nIHRvCi0gICAgICAgICAgICAgICAgLy8gcmUtcGFyc2UgYXR0cmlidXRlcyBsYXRlcgotICAgICAgICAgICAgICAgIGlmKGxvY2FsTmFtZS5lcXVhbHMoU2NoZW1hU3ltYm9scy5FTFRfSU5DTFVERSkpIHsKLSAgICAgICAgICAgICAgICAgICAgRWxlbWVudCBpbmNsdWRlQ2hpbGQgPSBET01VdGlsLmdldEZpcnN0Q2hpbGRFbGVtZW50KGNoaWxkKTsKLSAgICAgICAgICAgICAgICAgICAgaWYoaW5jbHVkZUNoaWxkICE9IG51bGwgKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgaW5jbHVkZUNvbXBvbmVudFR5cGUgPSBET01VdGlsLmdldExvY2FsTmFtZShpbmNsdWRlQ2hpbGQpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGluY2x1ZGVDb21wb25lbnRUeXBlLmVxdWFscyhTY2hlbWFTeW1ib2xzLkVMVF9BTk5PVEFUSU9OKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHByb21vdGluZyBhbm5vdGF0aW9ucyB0byBwYXJlbnQgY29tcG9uZW50Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2cuYWRkQW5ub3RhdGlvbigKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZFbGVtZW50VHJhdmVyc2VyLnRyYXZlcnNlQW5ub3RhdGlvbkRlY2woaW5jbHVkZUNoaWxkLCBpbmNsdWRlQXR0cnMsIHRydWUsIGN1cnJTY2hlbWFJbmZvKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKCJzNHMtZWx0LW11c3QtbWF0Y2guMSIsIG5ldyBPYmplY3QgW10ge2xvY2FsTmFtZSwgImFubm90YXRpb24/IiwgaW5jbHVkZUNvbXBvbmVudFR5cGV9LCBjaGlsZCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZihET01VdGlsLmdldE5leHRTaWJsaW5nRWxlbWVudChpbmNsdWRlQ2hpbGQpICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcigiczRzLWVsdC1tdXN0LW1hdGNoLjEiLCBuZXcgT2JqZWN0IFtdIHtsb2NhbE5hbWUsICJhbm5vdGF0aW9uPyIsIERPTVV0aWwuZ2V0TG9jYWxOYW1lKERPTVV0aWwuZ2V0TmV4dFNpYmxpbmdFbGVtZW50KGluY2x1ZGVDaGlsZCkpfSwgY2hpbGQpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHRleHQgPSBET01VdGlsLmdldFN5bnRoZXRpY0Fubm90YXRpb24oY2hpbGQpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRleHQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNnLmFkZEFubm90YXRpb24oZkVsZW1lbnRUcmF2ZXJzZXIudHJhdmVyc2VTeW50aGV0aWNBbm5vdGF0aW9uKGNoaWxkLCB0ZXh0LCBpbmNsdWRlQXR0cnMsIHRydWUsIGN1cnJTY2hlbWFJbmZvKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIGZvciAoRWxlbWVudCByZWRlZmluZWRDaGlsZCA9IERPTVV0aWwuZ2V0Rmlyc3RDaGlsZEVsZW1lbnQoY2hpbGQpOwotICAgICAgICAgICAgICAgICAgICByZWRlZmluZWRDaGlsZCAhPSBudWxsOwotICAgICAgICAgICAgICAgICAgICByZWRlZmluZWRDaGlsZCA9IERPTVV0aWwuZ2V0TmV4dFNpYmxpbmdFbGVtZW50KHJlZGVmaW5lZENoaWxkKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHJlZGVmaW5lZENvbXBvbmVudFR5cGUgPSBET01VdGlsLmdldExvY2FsTmFtZShyZWRlZmluZWRDaGlsZCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVkZWZpbmVkQ29tcG9uZW50VHlwZS5lcXVhbHMoU2NoZW1hU3ltYm9scy5FTFRfQU5OT1RBVElPTikpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBwcm9tb3RpbmcgYW5ub3RhdGlvbnMgdG8gcGFyZW50IGNvbXBvbmVudAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNnLmFkZEFubm90YXRpb24oCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmRWxlbWVudFRyYXZlcnNlci50cmF2ZXJzZUFubm90YXRpb25EZWNsKHJlZGVmaW5lZENoaWxkLCBpbmNsdWRlQXR0cnMsIHRydWUsIGN1cnJTY2hlbWFJbmZvKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgRE9NVXRpbC5zZXRIaWRkZW4ocmVkZWZpbmVkQ2hpbGQsIGZIaWRkZW5Ob2Rlcyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdGV4dCA9IERPTVV0aWwuZ2V0U3ludGhldGljQW5ub3RhdGlvbihjaGlsZCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRleHQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZy5hZGRBbm5vdGF0aW9uKGZFbGVtZW50VHJhdmVyc2VyLnRyYXZlcnNlU3ludGhldGljQW5ub3RhdGlvbihjaGlsZCwgdGV4dCwgaW5jbHVkZUF0dHJzLCB0cnVlLCBjdXJyU2NoZW1hSW5mbykpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNhdGNoIGFsbCBvdGhlciBjb250ZW50IGVycm9ycyBsYXRlcgotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGZBdHRyaWJ1dGVDaGVja2VyLnJldHVybkF0dHJBcnJheShpbmNsdWRlQXR0cnMsIGN1cnJTY2hlbWFJbmZvKTsKLSAgICAgICAgICAgICAgICAvLyBzY2hlbWFMb2NhdGlvbiBpcyByZXF1aXJlZCBvbiA8aW5jbHVkZT4gYW5kIDxyZWRlZmluZT4KLSAgICAgICAgICAgICAgICBpZiAoc2NoZW1hSGludCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKCJzNHMtYXR0LW11c3QtYXBwZWFyIiwgbmV3IE9iamVjdCBbXSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIjxpbmNsdWRlPiBvciA8cmVkZWZpbmU+IiwgInNjaGVtYUxvY2F0aW9uIn0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGQpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvLyBwYXNzIHRoZSBzeXN0ZW1JZCBvZiB0aGUgY3VycmVudCBkb2N1bWVudCBhcyB0aGUgYmFzZSBzeXN0ZW1JZAotICAgICAgICAgICAgICAgIGJvb2xlYW4gbXVzdFJlc29sdmUgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICByZWZUeXBlID0gWFNERGVzY3JpcHRpb24uQ09OVEVYVF9JTkNMVURFOwotICAgICAgICAgICAgICAgIGlmKGxvY2FsTmFtZS5lcXVhbHMoU2NoZW1hU3ltYm9scy5FTFRfUkVERUZJTkUpKSB7Ci0gICAgICAgICAgICAgICAgICAgIG11c3RSZXNvbHZlID0gbm9uQW5ub3RhdGlvbkNvbnRlbnQoY2hpbGQpOwotICAgICAgICAgICAgICAgICAgICByZWZUeXBlID0gWFNERGVzY3JpcHRpb24uQ09OVEVYVF9SRURFRklORTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZlNjaGVtYUdyYW1tYXJEZXNjcmlwdGlvbi5yZXNldCgpOwotICAgICAgICAgICAgICAgIGZTY2hlbWFHcmFtbWFyRGVzY3JpcHRpb24uc2V0Q29udGV4dFR5cGUocmVmVHlwZSk7Ci0gICAgICAgICAgICAgICAgZlNjaGVtYUdyYW1tYXJEZXNjcmlwdGlvbi5zZXRCYXNlU3lzdGVtSWQoZG9jMlN5c3RlbUlkKHNjaGVtYVJvb3QpKTsKLSAgICAgICAgICAgICAgICBmU2NoZW1hR3JhbW1hckRlc2NyaXB0aW9uLnNldExvY2F0aW9uSGludHMobmV3IFN0cmluZ1tde3NjaGVtYUhpbnR9KTsKLSAgICAgICAgICAgICAgICBmU2NoZW1hR3JhbW1hckRlc2NyaXB0aW9uLnNldFRhcmdldE5hbWVzcGFjZShjYWxsZXJUTlMpOwotCi0gICAgICAgICAgICAgICAgYm9vbGVhbiBhbHJlYWR5VHJhdmVyc2VkID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgWE1MSW5wdXRTb3VyY2Ugc2NoZW1hU291cmNlID0gcmVzb2x2ZVNjaGVtYVNvdXJjZShmU2NoZW1hR3JhbW1hckRlc2NyaXB0aW9uLCBtdXN0UmVzb2x2ZSwgY2hpbGQsIHRydWUpOwotICAgICAgICAgICAgICAgIGlmIChmTmFtZXNwYWNlR3Jvd3RoICYmIHJlZlR5cGUgPT0gWFNERGVzY3JpcHRpb24uQ09OVEVYVF9JTkNMVURFKSB7Ci0gICAgICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgc2NoZW1hSWQgPSBYTUxFbnRpdHlNYW5hZ2VyLmV4cGFuZFN5c3RlbUlkKHNjaGVtYVNvdXJjZS5nZXRTeXN0ZW1JZCgpLCBzY2hlbWFTb3VyY2UuZ2V0QmFzZVN5c3RlbUlkKCksIGZhbHNlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGFscmVhZHlUcmF2ZXJzZWQgPSBzZy5nZXREb2N1bWVudExvY2F0aW9ucygpLmNvbnRhaW5zKHNjaGVtYUlkKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBjYXRjaChNYWxmb3JtZWRVUklFeGNlcHRpb24gZSkgewotCi0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBpZiAoIWFscmVhZHlUcmF2ZXJzZWQpIHsKLSAgICAgICAgICAgICAgICAgICAgbmV3U2NoZW1hUm9vdCA9IHJlc29sdmVTY2hlbWEoc2NoZW1hU291cmNlLCBmU2NoZW1hR3JhbW1hckRlc2NyaXB0aW9uLCBtdXN0UmVzb2x2ZSwgY2hpbGQpOwotICAgICAgICAgICAgICAgICAgICBzY2hlbWFOYW1lc3BhY2UgPSBjdXJyU2NoZW1hSW5mby5mVGFyZ2V0TmFtZXNwYWNlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgZkxhc3RTY2hlbWFXYXNEdXBsaWNhdGUgPSB0cnVlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIC8vIG5vIG1vcmUgcG9zc2liaWxpdHkgb2Ygc2NoZW1hIHJlZmVyZW5jZXMgaW4gd2VsbC1mb3JtZWQKLSAgICAgICAgICAgICAgICAvLyBzY2hlbWEuLi4KLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gSWYgdGhlIHNjaGVtYSBpcyBkdXBsaWNhdGUsIHdlIG5lZWRuJ3QgY2FsbCBjb25zdHJ1Y3RUcmVlcygpIGFnYWluLgotICAgICAgICAgICAgLy8gVG8gaGFuZGxlIG11dHVhbCA8aW5jbHVkZT5zCi0gICAgICAgICAgICBYU0RvY3VtZW50SW5mbyBuZXdTY2hlbWFJbmZvID0gbnVsbDsKLSAgICAgICAgICAgIGlmIChmTGFzdFNjaGVtYVdhc0R1cGxpY2F0ZSkgewotICAgICAgICAgICAgICAgIG5ld1NjaGVtYUluZm8gPSBuZXdTY2hlbWFSb290ID09IG51bGwgPyBudWxsIDogKFhTRG9jdW1lbnRJbmZvKWZEb2MyWFNEb2N1bWVudE1hcC5nZXQobmV3U2NoZW1hUm9vdCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBuZXdTY2hlbWFJbmZvID0gY29uc3RydWN0VHJlZXMobmV3U2NoZW1hUm9vdCwgc2NoZW1hSGludCwgZlNjaGVtYUdyYW1tYXJEZXNjcmlwdGlvbiwgaW1wb3J0Q29sbGlzaW9uKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKGxvY2FsTmFtZS5lcXVhbHMoU2NoZW1hU3ltYm9scy5FTFRfUkVERUZJTkUpICYmCi0gICAgICAgICAgICAgICAgICAgIG5ld1NjaGVtYUluZm8gIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIC8vIG11c3QgcmVjb3JkIHdoaWNoIHNjaGVtYSB3ZSdyZSByZWRlZmluaW5nIHNvIHRoYXQgd2UgY2FuCi0gICAgICAgICAgICAgICAgLy8gcmVuYW1lIHRoZSByaWdodCB0aGluZ3MgbGF0ZXIhCi0gICAgICAgICAgICAgICAgaWYgKGZSZWRlZmluZTJYU0RNYXAgPT0gbnVsbCkgZlJlZGVmaW5lMlhTRE1hcCA9IG5ldyBIYXNoTWFwKCk7Ci0gICAgICAgICAgICAgICAgZlJlZGVmaW5lMlhTRE1hcC5wdXQoY2hpbGQsIG5ld1NjaGVtYUluZm8pOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKG5ld1NjaGVtYVJvb3QgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGlmIChuZXdTY2hlbWFJbmZvICE9IG51bGwpCi0gICAgICAgICAgICAgICAgICAgIGRlcGVuZGVuY2llcy5hZGRFbGVtZW50KG5ld1NjaGVtYUluZm8pOwotICAgICAgICAgICAgICAgIG5ld1NjaGVtYVJvb3QgPSBudWxsOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgZkRlcGVuZGVuY3lNYXAucHV0KGN1cnJTY2hlbWFJbmZvLCBkZXBlbmRlbmNpZXMpOwotICAgICAgICByZXR1cm4gY3VyclNjaGVtYUluZm87Ci0gICAgfSAvLyBlbmQgY29uc3RydWN0VHJlZXMKLQotICAgIHByaXZhdGUgYm9vbGVhbiBpc0V4aXN0aW5nR3JhbW1hcihYU0REZXNjcmlwdGlvbiBkZXNjLCBib29sZWFuIGlnbm9yZUNvbmZsaWN0KSB7Ci0gICAgICAgIFNjaGVtYUdyYW1tYXIgc2cgPSBmR3JhbW1hckJ1Y2tldC5nZXRHcmFtbWFyKGRlc2MuZ2V0VGFyZ2V0TmFtZXNwYWNlKCkpOwotICAgICAgICBpZiAoc2cgPT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIGZpbmRHcmFtbWFyKGRlc2MsIGlnbm9yZUNvbmZsaWN0KSAhPSBudWxsOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKHNnLmlzSW1tdXRhYmxlKCkpIHsKLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICByZXR1cm4gc2cuZ2V0RG9jdW1lbnRMb2NhdGlvbnMoKS5jb250YWlucyhYTUxFbnRpdHlNYW5hZ2VyLmV4cGFuZFN5c3RlbUlkKGRlc2MuZ2V0TGl0ZXJhbFN5c3RlbUlkKCksIGRlc2MuZ2V0QmFzZVN5c3RlbUlkKCksIGZhbHNlKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXRjaCAoTWFsZm9ybWVkVVJJRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBOYW1lc3BhY2UgZ3Jvd3RoCi0gICAgICoKLSAgICAgKiBHbyB0aHJvdWdoIHRoZSBpbXBvcnQgbGlzdCBvZiBhIGdpdmVuIGdyYW1tYXIgYW5kIGZvciBlYWNoIGltcG9ydGVkCi0gICAgICogZ3JhbW1hciwgY2hlY2sgdG8gc2VlIGlmIHRoZSBncmFtbWFyIGJ1Y2tldCBoYXMgYSBuZXdlciB2ZXJzaW9uLgotICAgICAqIElmIGEgbmV3IGluc3RhbmNlIGlzIGZvdW5kLCB3ZSB1cGRhdGUgdGhlIGltcG9ydCBsaXN0IHdpdGggdGhlCi0gICAgICogbmV3ZXIgdmVyc2lvbi4KLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgdXBkYXRlSW1wb3J0TGlzdEZvcihTY2hlbWFHcmFtbWFyIGdyYW1tYXIpIHsKLSAgICAgICAgVmVjdG9yIGltcG9ydGVkR3JhbW1hcnMgPSBncmFtbWFyLmdldEltcG9ydGVkR3JhbW1hcnMoKTsKLSAgICAgICAgaWYgKGltcG9ydGVkR3JhbW1hcnMgIT0gbnVsbCkgewotICAgICAgICAgICAgZm9yIChpbnQgaT0wOyBpPGltcG9ydGVkR3JhbW1hcnMuc2l6ZSgpOyBpKyspIHsKLSAgICAgICAgICAgICAgICBTY2hlbWFHcmFtbWFyIGlzZzEgPSAoU2NoZW1hR3JhbW1hcikgaW1wb3J0ZWRHcmFtbWFycy5lbGVtZW50QXQoaSk7Ci0gICAgICAgICAgICAgICAgU2NoZW1hR3JhbW1hciBpc2cyID0gZkdyYW1tYXJCdWNrZXQuZ2V0R3JhbW1hcihpc2cxLmdldFRhcmdldE5hbWVzcGFjZSgpKTsKLSAgICAgICAgICAgICAgICBpZiAoaXNnMiAhPSBudWxsICYmIGlzZzEgIT0gaXNnMikgewotICAgICAgICAgICAgICAgICAgICBpbXBvcnRlZEdyYW1tYXJzLnNldChpLCBpc2cyKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBOYW1lc3BhY2UgZ3Jvd3RoCi0gICAgICoKLSAgICAgKiBHbyB0aHJvdXRoIHRoZSBncmFtbWFyIGJ1Y2tldCwgYW5kIGZvciBlYWNoIGdyYW1tYXIgaW4gdGhlIGJ1Y2tldAotICAgICAqIGNoZWNrIHRoZSBpbXBvcnQgbGlzdC4gSWYgdGhlcmUgZXhpc3RzIGEgZ3JhbW1hciBpbiBpbXBvcnQgbGlzdAotICAgICAqIHRoYXQgaGFzIHRoZSBzYW1lIG5hbWVzcGFjZSBhcyBuZXdHcmFtbWFyLCBidXQgYSBkaWZmZXJlbnQgaW5zdGFuY2UsCi0gICAgICogdGhlbiB1cGRhdGUgdGhlIGltcG9ydCBsaXN0IGFuZCByZXBsYWNlIHRoZSBvbGQgZ3JhbW1hciBpbnN0YW5jZSB3aXRoCi0gICAgICogdGhlIG5ldyBvbmUKLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgdXBkYXRlSW1wb3J0TGlzdFdpdGgoU2NoZW1hR3JhbW1hciBuZXdHcmFtbWFyKSB7Ci0gICAgICAgIFNjaGVtYUdyYW1tYXJbXSBzY2hlbWFHcmFtbWFycyA9IGZHcmFtbWFyQnVja2V0LmdldEdyYW1tYXJzKCk7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc2NoZW1hR3JhbW1hcnMubGVuZ3RoOyArK2kpIHsKLSAgICAgICAgICAgIFNjaGVtYUdyYW1tYXIgc2cgPSBzY2hlbWFHcmFtbWFyc1tpXTsKLSAgICAgICAgICAgIGlmIChzZyAhPSBuZXdHcmFtbWFyKSB7Ci0gICAgICAgICAgICAgICAgVmVjdG9yIGltcG9ydGVkR3JhbW1hcnMgPSBzZy5nZXRJbXBvcnRlZEdyYW1tYXJzKCk7Ci0gICAgICAgICAgICAgICAgaWYgKGltcG9ydGVkR3JhbW1hcnMgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBqPTA7IGo8aW1wb3J0ZWRHcmFtbWFycy5zaXplKCk7IGorKykgewotICAgICAgICAgICAgICAgICAgICAgICAgU2NoZW1hR3JhbW1hciBpc2cgPSAoU2NoZW1hR3JhbW1hcikgaW1wb3J0ZWRHcmFtbWFycy5lbGVtZW50QXQoaik7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAobnVsbDJFbXB0eVN0cmluZyhpc2cuZ2V0VGFyZ2V0TmFtZXNwYWNlKCkpLmVxdWFscyhudWxsMkVtcHR5U3RyaW5nKG5ld0dyYW1tYXIuZ2V0VGFyZ2V0TmFtZXNwYWNlKCkpKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc2cgIT0gbmV3R3JhbW1hcikgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbXBvcnRlZEdyYW1tYXJzLnNldChqLCBuZXdHcmFtbWFyKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvLyBUaGlzIG1ldGhvZCBidWlsZHMgcmVnaXN0cmllcyBmb3IgYWxsIGdsb2JhbGx5LXJlZmVyZW5jZWFibGUKLSAgICAvLyBuYW1lcy4gIEEgcmVnaXN0cnkgd2lsbCBiZSBidWlsdCBmb3IgZWFjaCBzeW1ib2wgc3BhY2UgZGVmaW5lZAotICAgIC8vIGJ5IHRoZSBzcGVjLiAgSXQgaXMgYWxzbyB0aGlzIG1ldGhvZCdzIGpvYiB0byByZW5hbWUgcmVkZWZpbmVkCi0gICAgLy8gY29tcG9uZW50cywgYW5kIHRvIHJlY29yZCB3aGljaCBjb21wb25lbnRzIHJlZGVmaW5lIG90aGVycyAoc28KLSAgICAvLyB0aGF0IGltcGxpY2l0IHJlZGVmaW5pdGlvbnMgb2YgZ3JvdXBzIGFuZCBhdHRyaWJ1dGVHcm91cHMgY2FuIGJlIGhhbmRsZWQpLgotICAgIHByb3RlY3RlZCB2b2lkIGJ1aWxkR2xvYmFsTmFtZVJlZ2lzdHJpZXMoKSB7Ci0KLSAgICAgICAgcmVnaXN0cnlFbXB0eSA9IGZhbHNlOwotICAgICAgICAvLyBTdGFydGluZyB3aXRoIGZSb290LCB3ZSBleGFtaW5lIGVhY2ggY2hpbGQgb2YgdGhlIHNjaGVtYQotICAgICAgICAvLyBlbGVtZW50LiAgU2tpcHBpbmcgYWxsIGltcG9ydHMgYW5kIGluY2x1ZGVzLCB3ZSByZWNvcmQgdGhlIG5hbWVzCi0gICAgICAgIC8vIG9mIGFsbCBvdGhlciBnbG9iYWwgY29tcG9uZW50cyAoYW5kIGNoaWxkcmVuIG9mIDxyZWRlZmluZT4pLiAgV2UKLSAgICAgICAgLy8gYWxzbyBwdXQgPHJlZGVmaW5lPiBuYW1lcyBpbiBhIHJlZ2lzdHJ5IHRoYXQgd2UgbG9vayB0aHJvdWdoIGluCi0gICAgICAgIC8vIGNhc2Ugc29tZXRoaW5nIG5lZWRzIHJlbmFtaW5nLiAgT25jZSB3ZSdyZSBkb25lIHdpdGggYSBzY2hlbWEgd2UKLSAgICAgICAgLy8gc2V0IGl0cyBEb2N1bWVudCBub2RlIHRvIGhpZGRlbiBzbyB0aGF0IHdlIGRvbid0IHRyeSB0byB0cmF2ZXJzZQotICAgICAgICAvLyBpdCBhZ2FpbjsgdGhlbiB3ZSBsb29rIHRvIGl0cyBEZXBlbmRlbmN5IG1hcCBlbnRyeS4gIFdlIGtlZXAgYQotICAgICAgICAvLyBzdGFjayBvZiBzY2hlbWFzIHRoYXQgd2UgaGF2ZW4ndCB5ZXQgZmluaXNoZWQgcHJvY2Vzc2luZzsgdGhpcwotICAgICAgICAvLyBpcyBhIGRlcHRoLWZpcnN0IHRyYXZlcnNhbC4KLQotICAgICAgICBTdGFjayBzY2hlbWFzVG9Qcm9jZXNzID0gbmV3IFN0YWNrKCk7Ci0gICAgICAgIHNjaGVtYXNUb1Byb2Nlc3MucHVzaChmUm9vdCk7Ci0KLSAgICAgICAgd2hpbGUgKCFzY2hlbWFzVG9Qcm9jZXNzLmVtcHR5KCkpIHsKLSAgICAgICAgICAgIFhTRG9jdW1lbnRJbmZvIGN1cnJTY2hlbWFEb2MgPQotICAgICAgICAgICAgICAgIChYU0RvY3VtZW50SW5mbylzY2hlbWFzVG9Qcm9jZXNzLnBvcCgpOwotICAgICAgICAgICAgRWxlbWVudCBjdXJyRG9jID0gY3VyclNjaGVtYURvYy5mU2NoZW1hRWxlbWVudDsKLSAgICAgICAgICAgIGlmKERPTVV0aWwuaXNIaWRkZW4oY3VyckRvYywgZkhpZGRlbk5vZGVzKSl7Ci0gICAgICAgICAgICAgICAgLy8gbXVzdCBoYXZlIHByb2Nlc3NlZCB0aGlzIGFscmVhZHkhCi0gICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIEVsZW1lbnQgY3VyclJvb3QgPSBjdXJyRG9jOwotICAgICAgICAgICAgLy8gcHJvY2VzcyB0aGlzIHNjaGVtYSdzIGdsb2JhbCBkZWNscwotICAgICAgICAgICAgYm9vbGVhbiBkZXBlbmRlbmNpZXNDYW5PY2N1ciA9IHRydWU7Ci0gICAgICAgICAgICBmb3IgKEVsZW1lbnQgZ2xvYmFsQ29tcCA9Ci0gICAgICAgICAgICAgICAgRE9NVXRpbC5nZXRGaXJzdENoaWxkRWxlbWVudChjdXJyUm9vdCk7Ci0gICAgICAgICAgICBnbG9iYWxDb21wICE9IG51bGw7Ci0gICAgICAgICAgICBnbG9iYWxDb21wID0gRE9NVXRpbC5nZXROZXh0U2libGluZ0VsZW1lbnQoZ2xvYmFsQ29tcCkpIHsKLSAgICAgICAgICAgICAgICAvLyB0aGlzIGxvb3AgbWFrZXMgc3VyZSB0aGUgPHNjaGVtYT4gZWxlbWVudCBvcmRlcmluZyBpcwotICAgICAgICAgICAgICAgIC8vIGFsc28gdmFsaWQuCi0gICAgICAgICAgICAgICAgaWYgKERPTVV0aWwuZ2V0TG9jYWxOYW1lKGdsb2JhbENvbXApLmVxdWFscyhTY2hlbWFTeW1ib2xzLkVMVF9BTk5PVEFUSU9OKSkgewotICAgICAgICAgICAgICAgICAgICAvL3NraXAgaXQ7IHRyYXZlcnNlIGl0IGxhdGVyCi0gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIGlmIChET01VdGlsLmdldExvY2FsTmFtZShnbG9iYWxDb21wKS5lcXVhbHMoU2NoZW1hU3ltYm9scy5FTFRfSU5DTFVERSkgfHwKLSAgICAgICAgICAgICAgICAgICAgICAgIERPTVV0aWwuZ2V0TG9jYWxOYW1lKGdsb2JhbENvbXApLmVxdWFscyhTY2hlbWFTeW1ib2xzLkVMVF9JTVBPUlQpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmICghZGVwZW5kZW5jaWVzQ2FuT2NjdXIpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKCJzNHMtZWx0LWludmFsaWQtY29udGVudC4zIiwgbmV3IE9iamVjdCBbXSB7RE9NVXRpbC5nZXRMb2NhbE5hbWUoZ2xvYmFsQ29tcCl9LCBnbG9iYWxDb21wKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBET01VdGlsLnNldEhpZGRlbihnbG9iYWxDb21wLCBmSGlkZGVuTm9kZXMpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIGlmIChET01VdGlsLmdldExvY2FsTmFtZShnbG9iYWxDb21wKS5lcXVhbHMoU2NoZW1hU3ltYm9scy5FTFRfUkVERUZJTkUpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmICghZGVwZW5kZW5jaWVzQ2FuT2NjdXIpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKCJzNHMtZWx0LWludmFsaWQtY29udGVudC4zIiwgbmV3IE9iamVjdCBbXSB7RE9NVXRpbC5nZXRMb2NhbE5hbWUoZ2xvYmFsQ29tcCl9LCBnbG9iYWxDb21wKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBmb3IgKEVsZW1lbnQgcmVkZWZpbmVDb21wID0gRE9NVXRpbC5nZXRGaXJzdENoaWxkRWxlbWVudChnbG9iYWxDb21wKTsKLSAgICAgICAgICAgICAgICAgICAgcmVkZWZpbmVDb21wICE9IG51bGw7Ci0gICAgICAgICAgICAgICAgICAgIHJlZGVmaW5lQ29tcCA9IERPTVV0aWwuZ2V0TmV4dFNpYmxpbmdFbGVtZW50KHJlZGVmaW5lQ29tcCkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBsTmFtZSA9IERPTVV0aWwuZ2V0QXR0clZhbHVlKHJlZGVmaW5lQ29tcCwgU2NoZW1hU3ltYm9scy5BVFRfTkFNRSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAobE5hbWUubGVuZ3RoKCkgPT0gMCkgLy8gYW4gZXJyb3Igd2UnbGwgY2F0Y2ggbGF0ZXIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBxTmFtZSA9IGN1cnJTY2hlbWFEb2MuZlRhcmdldE5hbWVzcGFjZSA9PSBudWxsID8KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiwiK2xOYW1lOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VyclNjaGVtYURvYy5mVGFyZ2V0TmFtZXNwYWNlICsiLCIrbE5hbWU7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgY29tcG9uZW50VHlwZSA9IERPTVV0aWwuZ2V0TG9jYWxOYW1lKHJlZGVmaW5lQ29tcCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29tcG9uZW50VHlwZS5lcXVhbHMoU2NoZW1hU3ltYm9scy5FTFRfQVRUUklCVVRFR1JPVVApKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tGb3JEdXBsaWNhdGVOYW1lcyhxTmFtZSwgQVRUUklCVVRFR1JPVVBfVFlQRSwgZlVucGFyc2VkQXR0cmlidXRlR3JvdXBSZWdpc3RyeSwgZlVucGFyc2VkQXR0cmlidXRlR3JvdXBSZWdpc3RyeVN1YiwgcmVkZWZpbmVDb21wLCBjdXJyU2NoZW1hRG9jKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGUgY2hlY2sgd2lsbCBoYXZlIGNoYW5nZWQgb3VyIG5hbWU7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHRhcmdldExOYW1lID0gRE9NVXRpbC5nZXRBdHRyVmFsdWUocmVkZWZpbmVDb21wLCBTY2hlbWFTeW1ib2xzLkFUVF9OQU1FKStSRURFRl9JREVOVElGSUVSOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFuZCBhbGwgd2UgbmVlZCB0byBkbyBpcyBlcnJvci1jaGVjaytyZW5hbWUgb3VyIGtraWRzOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbmFtZVJlZGVmaW5pbmdDb21wb25lbnRzKGN1cnJTY2hlbWFEb2MsIHJlZGVmaW5lQ29tcCwgU2NoZW1hU3ltYm9scy5FTFRfQVRUUklCVVRFR1JPVVAsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsTmFtZSwgdGFyZ2V0TE5hbWUpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoKGNvbXBvbmVudFR5cGUuZXF1YWxzKFNjaGVtYVN5bWJvbHMuRUxUX0NPTVBMRVhUWVBFKSkgfHwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNvbXBvbmVudFR5cGUuZXF1YWxzKFNjaGVtYVN5bWJvbHMuRUxUX1NJTVBMRVRZUEUpKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoZWNrRm9yRHVwbGljYXRlTmFtZXMocU5hbWUsIFRZUEVERUNMX1RZUEUsIGZVbnBhcnNlZFR5cGVSZWdpc3RyeSwgZlVucGFyc2VkVHlwZVJlZ2lzdHJ5U3ViLCByZWRlZmluZUNvbXAsIGN1cnJTY2hlbWFEb2MpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoZSBjaGVjayB3aWxsIGhhdmUgY2hhbmdlZCBvdXIgbmFtZTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdGFyZ2V0TE5hbWUgPSBET01VdGlsLmdldEF0dHJWYWx1ZShyZWRlZmluZUNvbXAsIFNjaGVtYVN5bWJvbHMuQVRUX05BTUUpICsgUkVERUZfSURFTlRJRklFUjsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBhbmQgYWxsIHdlIG5lZWQgdG8gZG8gaXMgZXJyb3ItY2hlY2srcmVuYW1lIG91ciBra2lkczoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29tcG9uZW50VHlwZS5lcXVhbHMoU2NoZW1hU3ltYm9scy5FTFRfQ09NUExFWFRZUEUpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbmFtZVJlZGVmaW5pbmdDb21wb25lbnRzKGN1cnJTY2hlbWFEb2MsIHJlZGVmaW5lQ29tcCwgU2NoZW1hU3ltYm9scy5FTFRfQ09NUExFWFRZUEUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbE5hbWUsIHRhcmdldExOYW1lKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7IC8vIG11c3QgYmUgc2ltcGxlVHlwZQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZW5hbWVSZWRlZmluaW5nQ29tcG9uZW50cyhjdXJyU2NoZW1hRG9jLCByZWRlZmluZUNvbXAsIFNjaGVtYVN5bWJvbHMuRUxUX1NJTVBMRVRZUEUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbE5hbWUsIHRhcmdldExOYW1lKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChjb21wb25lbnRUeXBlLmVxdWFscyhTY2hlbWFTeW1ib2xzLkVMVF9HUk9VUCkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGVja0ZvckR1cGxpY2F0ZU5hbWVzKHFOYW1lLCBHUk9VUF9UWVBFLCBmVW5wYXJzZWRHcm91cFJlZ2lzdHJ5LCBmVW5wYXJzZWRHcm91cFJlZ2lzdHJ5U3ViLCByZWRlZmluZUNvbXAsIGN1cnJTY2hlbWFEb2MpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoZSBjaGVjayB3aWxsIGhhdmUgY2hhbmdlZCBvdXIgbmFtZTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdGFyZ2V0TE5hbWUgPSBET01VdGlsLmdldEF0dHJWYWx1ZShyZWRlZmluZUNvbXAsIFNjaGVtYVN5bWJvbHMuQVRUX05BTUUpK1JFREVGX0lERU5USUZJRVI7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYW5kIGFsbCB3ZSBuZWVkIHRvIGRvIGlzIGVycm9yLWNoZWNrK3JlbmFtZSBvdXIga2lkczoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICByZW5hbWVSZWRlZmluaW5nQ29tcG9uZW50cyhjdXJyU2NoZW1hRG9jLCByZWRlZmluZUNvbXAsIFNjaGVtYVN5bWJvbHMuRUxUX0dST1VQLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbE5hbWUsIHRhcmdldExOYW1lKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfSAvLyBlbmQgbWFyY2ggdGhyb3VnaCA8cmVkZWZpbmU+IGNoaWxkcmVuCi0gICAgICAgICAgICAgICAgICAgIC8vIGFuZCBub3cgc2V0IGFzIHRyYXZlcnNlZAotICAgICAgICAgICAgICAgICAgICAvL0RPTVV0aWwuc2V0SGlkZGVuKGdsb2JhbENvbXApOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgZGVwZW5kZW5jaWVzQ2FuT2NjdXIgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGxOYW1lID0gRE9NVXRpbC5nZXRBdHRyVmFsdWUoZ2xvYmFsQ29tcCwgU2NoZW1hU3ltYm9scy5BVFRfTkFNRSk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChsTmFtZS5sZW5ndGgoKSA9PSAwKSAvLyBhbiBlcnJvciB3ZSdsbCBjYXRjaCBsYXRlcgotICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICAgICAgICAgIFN0cmluZyBxTmFtZSA9IGN1cnJTY2hlbWFEb2MuZlRhcmdldE5hbWVzcGFjZSA9PSBudWxsPwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICIsIitsTmFtZToKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VyclNjaGVtYURvYy5mVGFyZ2V0TmFtZXNwYWNlICsiLCIrbE5hbWU7Ci0gICAgICAgICAgICAgICAgICAgIFN0cmluZyBjb21wb25lbnRUeXBlID0gRE9NVXRpbC5nZXRMb2NhbE5hbWUoZ2xvYmFsQ29tcCk7Ci0KLSAgICAgICAgICAgICAgICAgICAgaWYgKGNvbXBvbmVudFR5cGUuZXF1YWxzKFNjaGVtYVN5bWJvbHMuRUxUX0FUVFJJQlVURSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGNoZWNrRm9yRHVwbGljYXRlTmFtZXMocU5hbWUsIEFUVFJJQlVURV9UWVBFLCBmVW5wYXJzZWRBdHRyaWJ1dGVSZWdpc3RyeSwgZlVucGFyc2VkQXR0cmlidXRlUmVnaXN0cnlTdWIsIGdsb2JhbENvbXAsIGN1cnJTY2hlbWFEb2MpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGNvbXBvbmVudFR5cGUuZXF1YWxzKFNjaGVtYVN5bWJvbHMuRUxUX0FUVFJJQlVURUdST1VQKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tGb3JEdXBsaWNhdGVOYW1lcyhxTmFtZSwgQVRUUklCVVRFR1JPVVBfVFlQRSwgZlVucGFyc2VkQXR0cmlidXRlR3JvdXBSZWdpc3RyeSwgZlVucGFyc2VkQXR0cmlidXRlR3JvdXBSZWdpc3RyeVN1YiwgZ2xvYmFsQ29tcCwgY3VyclNjaGVtYURvYyk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoKGNvbXBvbmVudFR5cGUuZXF1YWxzKFNjaGVtYVN5bWJvbHMuRUxUX0NPTVBMRVhUWVBFKSkgfHwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY29tcG9uZW50VHlwZS5lcXVhbHMoU2NoZW1hU3ltYm9scy5FTFRfU0lNUExFVFlQRSkpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBjaGVja0ZvckR1cGxpY2F0ZU5hbWVzKHFOYW1lLCBUWVBFREVDTF9UWVBFLCBmVW5wYXJzZWRUeXBlUmVnaXN0cnksIGZVbnBhcnNlZFR5cGVSZWdpc3RyeVN1YiwgZ2xvYmFsQ29tcCwgY3VyclNjaGVtYURvYyk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoY29tcG9uZW50VHlwZS5lcXVhbHMoU2NoZW1hU3ltYm9scy5FTFRfRUxFTUVOVCkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGNoZWNrRm9yRHVwbGljYXRlTmFtZXMocU5hbWUsIEVMRU1FTlRfVFlQRSwgZlVucGFyc2VkRWxlbWVudFJlZ2lzdHJ5LCBmVW5wYXJzZWRFbGVtZW50UmVnaXN0cnlTdWIsIGdsb2JhbENvbXAsIGN1cnJTY2hlbWFEb2MpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGNvbXBvbmVudFR5cGUuZXF1YWxzKFNjaGVtYVN5bWJvbHMuRUxUX0dST1VQKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tGb3JEdXBsaWNhdGVOYW1lcyhxTmFtZSwgR1JPVVBfVFlQRSwgZlVucGFyc2VkR3JvdXBSZWdpc3RyeSwgZlVucGFyc2VkR3JvdXBSZWdpc3RyeVN1YiwgZ2xvYmFsQ29tcCwgY3VyclNjaGVtYURvYyk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoY29tcG9uZW50VHlwZS5lcXVhbHMoU2NoZW1hU3ltYm9scy5FTFRfTk9UQVRJT04pKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBjaGVja0ZvckR1cGxpY2F0ZU5hbWVzKHFOYW1lLCBOT1RBVElPTl9UWVBFLCBmVW5wYXJzZWROb3RhdGlvblJlZ2lzdHJ5LCBmVW5wYXJzZWROb3RhdGlvblJlZ2lzdHJ5U3ViLCBnbG9iYWxDb21wLCBjdXJyU2NoZW1hRG9jKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0gLy8gZW5kIGZvcgotCi0gICAgICAgICAgICAvLyBub3cgd2UncmUgZG9uZSB3aXRoIHRoaXMgb25lIQotICAgICAgICAgICAgRE9NVXRpbC5zZXRIaWRkZW4oY3VyckRvYywgZkhpZGRlbk5vZGVzKTsKLSAgICAgICAgICAgIC8vIG5vdyBhZGQgdGhlIHNjaGVtYXMgdGhpcyBndXkgZGVwZW5kcyBvbgotICAgICAgICAgICAgVmVjdG9yPFhTRG9jdW1lbnRJbmZvPiBjdXJyU2NoZW1hRGVwZW5kcyA9IGZEZXBlbmRlbmN5TWFwLmdldChjdXJyU2NoZW1hRG9jKTsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY3VyclNjaGVtYURlcGVuZHMuc2l6ZSgpOyBpKyspIHsKLSAgICAgICAgICAgICAgICBzY2hlbWFzVG9Qcm9jZXNzLnB1c2goY3VyclNjaGVtYURlcGVuZHMuZWxlbWVudEF0KGkpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSAvLyB3aGlsZQotCi0gICAgfSAvLyBlbmQgYnVpbGRHbG9iYWxOYW1lUmVnaXN0cmllcwotCi0gICAgLy8gQmVnaW5uaW5nIGF0IHRoZSBmaXJzdCBzY2hlbWEgcHJvY2Vzc2luZyB3YXMgcmVxdWVzdGVkIGZvcgotICAgIC8vIChmUm9vdCksIHRoaXMgbWV0aG9kCi0gICAgLy8gZXhhbWluZXMgZWFjaCBjaGlsZCAoZ2xvYmFsIHNjaGVtYSBpbmZvcm1hdGlvbiBpdGVtKSBvZiBlYWNoCi0gICAgLy8gc2NoZW1hIGRvY3VtZW50IChhbmQgb2YgZWFjaCA8cmVkZWZpbmU+IGVsZW1lbnQpCi0gICAgLy8gY29ycmVzcG9uZGluZyB0byBhbiBYU0RvY3VtZW50SW5mbyBvYmplY3QuICBJZiB0aGUKLSAgICAvLyByZWFkT25seSBmaWVsZCBvbiB0aGF0IG5vZGUgaGFzIG5vdCBiZWVuIHNldCwgaXQgY2FsbHMgYW4KLSAgICAvLyBhcHByb3ByaWF0ZSB0cmF2ZXJzZXIgdG8gdHJhdmVyc2UgaXQuICBPbmNlIGFsbCBnbG9iYWwgZGVjbHMgaW4KLSAgICAvLyBhbiBYU0RvY3VtZW50SW5mbyBvYmplY3QgaGF2ZSBiZWVuIHRyYXZlcnNlZCwgaXQgbWFya3MgdGhhdCBvYmplY3QKLSAgICAvLyBhcyB0cmF2ZXJzZWQgKG9yIGhpZGRlbikgaW4gb3JkZXIgdG8gYXZvaWQgaW5maW5pdGUgbG9vcHMuICBJdCBjb21wbGV0ZXMKLSAgICAvLyB3aGVuIGl0IGhhcyB2aXNpdGVkIGFsbCBYU0RvY3VtZW50SW5mbyBvYmplY3RzIGluIHRoZQotICAgIC8vIERlcGVuZGVuY3lNYXAgYW5kIG1hcmtlZCB0aGVtIGFzIHRyYXZlcnNlZC4KLSAgICBwcm90ZWN0ZWQgdm9pZCB0cmF2ZXJzZVNjaGVtYXMoQXJyYXlMaXN0IGFubm90YXRpb25JbmZvKSB7Ci0gICAgICAgIC8vIHRoZSBwcm9jZXNzIGhlcmUgaXMgdmVyeSBzaW1pbGFyIHRvIHRoYXQgaW4KLSAgICAgICAgLy8gYnVpbGRHbG9iYWxSZWdpc3RyaWVzLCBleGNlcHQgd2UgY2FuJ3Qgc2V0IG91ciBzY2hlbWFzIGFzCi0gICAgICAgIC8vIGhpZGRlbiBmb3IgYSBzZWNvbmQgdGltZTsgc28gbWFrZSB0aGVtIGFsbCB2aXNpYmxlIGFnYWluCi0gICAgICAgIC8vIGZpcnN0IQotICAgICAgICBzZXRTY2hlbWFzVmlzaWJsZShmUm9vdCk7Ci0gICAgICAgIFN0YWNrIHNjaGVtYXNUb1Byb2Nlc3MgPSBuZXcgU3RhY2soKTsKLSAgICAgICAgc2NoZW1hc1RvUHJvY2Vzcy5wdXNoKGZSb290KTsKLSAgICAgICAgd2hpbGUgKCFzY2hlbWFzVG9Qcm9jZXNzLmVtcHR5KCkpIHsKLSAgICAgICAgICAgIFhTRG9jdW1lbnRJbmZvIGN1cnJTY2hlbWFEb2MgPQotICAgICAgICAgICAgICAgIChYU0RvY3VtZW50SW5mbylzY2hlbWFzVG9Qcm9jZXNzLnBvcCgpOwotICAgICAgICAgICAgRWxlbWVudCBjdXJyRG9jID0gY3VyclNjaGVtYURvYy5mU2NoZW1hRWxlbWVudDsKLQotICAgICAgICAgICAgU2NoZW1hR3JhbW1hciBjdXJyU0cgPSBmR3JhbW1hckJ1Y2tldC5nZXRHcmFtbWFyKGN1cnJTY2hlbWFEb2MuZlRhcmdldE5hbWVzcGFjZSk7Ci0KLSAgICAgICAgICAgIGlmKERPTVV0aWwuaXNIaWRkZW4oY3VyckRvYywgZkhpZGRlbk5vZGVzKSkgewotICAgICAgICAgICAgICAgIC8vIG11c3QgaGF2ZSBwcm9jZXNzZWQgdGhpcyBhbHJlYWR5IQotICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgRWxlbWVudCBjdXJyUm9vdCA9IGN1cnJEb2M7Ci0gICAgICAgICAgICBib29sZWFuIHNhd0Fubm90YXRpb24gPSBmYWxzZTsKLSAgICAgICAgICAgIC8vIHRyYXZlcnNlIHRoaXMgc2NoZW1hJ3MgZ2xvYmFsIGRlY2xzCi0gICAgICAgICAgICBmb3IgKEVsZW1lbnQgZ2xvYmFsQ29tcCA9Ci0gICAgICAgICAgICAgICAgRE9NVXRpbC5nZXRGaXJzdFZpc2libGVDaGlsZEVsZW1lbnQoY3VyclJvb3QsIGZIaWRkZW5Ob2Rlcyk7Ci0gICAgICAgICAgICBnbG9iYWxDb21wICE9IG51bGw7Ci0gICAgICAgICAgICBnbG9iYWxDb21wID0gRE9NVXRpbC5nZXROZXh0VmlzaWJsZVNpYmxpbmdFbGVtZW50KGdsb2JhbENvbXAsIGZIaWRkZW5Ob2RlcykpIHsKLSAgICAgICAgICAgICAgICBET01VdGlsLnNldEhpZGRlbihnbG9iYWxDb21wLCBmSGlkZGVuTm9kZXMpOwotICAgICAgICAgICAgICAgIFN0cmluZyBjb21wb25lbnRUeXBlID0gRE9NVXRpbC5nZXRMb2NhbE5hbWUoZ2xvYmFsQ29tcCk7Ci0gICAgICAgICAgICAgICAgLy8gaW5jbHVkZXMgYW5kIGltcG9ydHMgd2lsbCBub3Qgc2hvdyB1cCBoZXJlIQotICAgICAgICAgICAgICAgIGlmIChET01VdGlsLmdldExvY2FsTmFtZShnbG9iYWxDb21wKS5lcXVhbHMoU2NoZW1hU3ltYm9scy5FTFRfUkVERUZJTkUpKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIHVzZSB0aGUgbmFtZXNwYWNlIGRlY2xzIGZvciB0aGUgcmVkZWZpbmUsIGluc3RlYWQgb2YgZm9yIHRoZSBwYXJlbnQgPHNjaGVtYT4KLSAgICAgICAgICAgICAgICAgICAgY3VyclNjaGVtYURvYy5iYWNrdXBOU1N1cHBvcnQoKGZSZWRlZmluZTJOU1N1cHBvcnQhPW51bGwpPyhTY2hlbWFOYW1lc3BhY2VTdXBwb3J0KWZSZWRlZmluZTJOU1N1cHBvcnQuZ2V0KGdsb2JhbENvbXApOm51bGwpOwotICAgICAgICAgICAgICAgICAgICBmb3IgKEVsZW1lbnQgcmVkZWZpbmVkQ29tcCA9IERPTVV0aWwuZ2V0Rmlyc3RWaXNpYmxlQ2hpbGRFbGVtZW50KGdsb2JhbENvbXAsIGZIaWRkZW5Ob2Rlcyk7Ci0gICAgICAgICAgICAgICAgICAgIHJlZGVmaW5lZENvbXAgIT0gbnVsbDsKLSAgICAgICAgICAgICAgICAgICAgcmVkZWZpbmVkQ29tcCA9IERPTVV0aWwuZ2V0TmV4dFZpc2libGVTaWJsaW5nRWxlbWVudChyZWRlZmluZWRDb21wLCBmSGlkZGVuTm9kZXMpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcmVkZWZpbmVkQ29tcG9uZW50VHlwZSA9IERPTVV0aWwuZ2V0TG9jYWxOYW1lKHJlZGVmaW5lZENvbXApOwotICAgICAgICAgICAgICAgICAgICAgICAgRE9NVXRpbC5zZXRIaWRkZW4ocmVkZWZpbmVkQ29tcCwgZkhpZGRlbk5vZGVzKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZWRlZmluZWRDb21wb25lbnRUeXBlLmVxdWFscyhTY2hlbWFTeW1ib2xzLkVMVF9BVFRSSUJVVEVHUk9VUCkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmQXR0cmlidXRlR3JvdXBUcmF2ZXJzZXIudHJhdmVyc2VHbG9iYWwocmVkZWZpbmVkQ29tcCwgY3VyclNjaGVtYURvYywgY3VyclNHKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHJlZGVmaW5lZENvbXBvbmVudFR5cGUuZXF1YWxzKFNjaGVtYVN5bWJvbHMuRUxUX0NPTVBMRVhUWVBFKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZDb21wbGV4VHlwZVRyYXZlcnNlci50cmF2ZXJzZUdsb2JhbChyZWRlZmluZWRDb21wLCBjdXJyU2NoZW1hRG9jLCBjdXJyU0cpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAocmVkZWZpbmVkQ29tcG9uZW50VHlwZS5lcXVhbHMoU2NoZW1hU3ltYm9scy5FTFRfR1JPVVApKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZkdyb3VwVHJhdmVyc2VyLnRyYXZlcnNlR2xvYmFsKHJlZGVmaW5lZENvbXAsIGN1cnJTY2hlbWFEb2MsIGN1cnJTRyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChyZWRlZmluZWRDb21wb25lbnRUeXBlLmVxdWFscyhTY2hlbWFTeW1ib2xzLkVMVF9TSU1QTEVUWVBFKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZTaW1wbGVUeXBlVHJhdmVyc2VyLnRyYXZlcnNlR2xvYmFsKHJlZGVmaW5lZENvbXAsIGN1cnJTY2hlbWFEb2MsIGN1cnJTRyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBhbm5vdGF0aW9ucyB3aWxsIGhhdmUgYmVlbiBwcm9jZXNzZWQgYWxyZWFkeTsgdGhpcyBpcyBub3cKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIHVubmVjZXNzYXJ5Ci0gICAgICAgICAgICAgICAgICAgICAgICAvL2Vsc2UgaWYgKHJlZGVmaW5lZENvbXBvbmVudFR5cGUuZXF1YWxzKFNjaGVtYVN5bWJvbHMuRUxUX0FOTk9UQVRJT04pKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyAgICBmRWxlbWVudFRyYXZlcnNlci50cmF2ZXJzZUFubm90YXRpb25EZWNsKHJlZGVmaW5lZENvbXAsIG51bGwsIHRydWUsIGN1cnJTY2hlbWFEb2MpOwotICAgICAgICAgICAgICAgICAgICAgICAgLy99Ci0gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcigiczRzLWVsdC1tdXN0LW1hdGNoLjEiLCBuZXcgT2JqZWN0IFtdIHtET01VdGlsLmdldExvY2FsTmFtZShnbG9iYWxDb21wKSwgIihhbm5vdGF0aW9uIHwgKHNpbXBsZVR5cGUgfCBjb21wbGV4VHlwZSB8IGdyb3VwIHwgYXR0cmlidXRlR3JvdXApKSoiLCByZWRlZmluZWRDb21wb25lbnRUeXBlfSwgcmVkZWZpbmVkQ29tcCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0gLy8gZW5kIG1hcmNoIHRocm91Z2ggPHJlZGVmaW5lPiBjaGlsZHJlbgotICAgICAgICAgICAgICAgICAgICBjdXJyU2NoZW1hRG9jLnJlc3RvcmVOU1N1cHBvcnQoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSBpZiAoY29tcG9uZW50VHlwZS5lcXVhbHMoU2NoZW1hU3ltYm9scy5FTFRfQVRUUklCVVRFKSkgewotICAgICAgICAgICAgICAgICAgICBmQXR0cmlidXRlVHJhdmVyc2VyLnRyYXZlcnNlR2xvYmFsKGdsb2JhbENvbXAsIGN1cnJTY2hlbWFEb2MsIGN1cnJTRyk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgaWYgKGNvbXBvbmVudFR5cGUuZXF1YWxzKFNjaGVtYVN5bWJvbHMuRUxUX0FUVFJJQlVURUdST1VQKSkgewotICAgICAgICAgICAgICAgICAgICBmQXR0cmlidXRlR3JvdXBUcmF2ZXJzZXIudHJhdmVyc2VHbG9iYWwoZ2xvYmFsQ29tcCwgY3VyclNjaGVtYURvYywgY3VyclNHKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSBpZiAoY29tcG9uZW50VHlwZS5lcXVhbHMoU2NoZW1hU3ltYm9scy5FTFRfQ09NUExFWFRZUEUpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZDb21wbGV4VHlwZVRyYXZlcnNlci50cmF2ZXJzZUdsb2JhbChnbG9iYWxDb21wLCBjdXJyU2NoZW1hRG9jLCBjdXJyU0cpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIGlmIChjb21wb25lbnRUeXBlLmVxdWFscyhTY2hlbWFTeW1ib2xzLkVMVF9FTEVNRU5UKSkgewotICAgICAgICAgICAgICAgICAgICBmRWxlbWVudFRyYXZlcnNlci50cmF2ZXJzZUdsb2JhbChnbG9iYWxDb21wLCBjdXJyU2NoZW1hRG9jLCBjdXJyU0cpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIGlmIChjb21wb25lbnRUeXBlLmVxdWFscyhTY2hlbWFTeW1ib2xzLkVMVF9HUk9VUCkpIHsKLSAgICAgICAgICAgICAgICAgICAgZkdyb3VwVHJhdmVyc2VyLnRyYXZlcnNlR2xvYmFsKGdsb2JhbENvbXAsIGN1cnJTY2hlbWFEb2MsIGN1cnJTRyk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgaWYgKGNvbXBvbmVudFR5cGUuZXF1YWxzKFNjaGVtYVN5bWJvbHMuRUxUX05PVEFUSU9OKSkgewotICAgICAgICAgICAgICAgICAgICBmTm90YXRpb25UcmF2ZXJzZXIudHJhdmVyc2UoZ2xvYmFsQ29tcCwgY3VyclNjaGVtYURvYywgY3VyclNHKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSBpZiAoY29tcG9uZW50VHlwZS5lcXVhbHMoU2NoZW1hU3ltYm9scy5FTFRfU0lNUExFVFlQRSkpIHsKLSAgICAgICAgICAgICAgICAgICAgZlNpbXBsZVR5cGVUcmF2ZXJzZXIudHJhdmVyc2VHbG9iYWwoZ2xvYmFsQ29tcCwgY3VyclNjaGVtYURvYywgY3VyclNHKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSBpZiAoY29tcG9uZW50VHlwZS5lcXVhbHMoU2NoZW1hU3ltYm9scy5FTFRfQU5OT1RBVElPTikpIHsKLSAgICAgICAgICAgICAgICAgICAgY3VyclNHLmFkZEFubm90YXRpb24oZkVsZW1lbnRUcmF2ZXJzZXIudHJhdmVyc2VBbm5vdGF0aW9uRGVjbChnbG9iYWxDb21wLCBjdXJyU2NoZW1hRG9jLmdldFNjaGVtYUF0dHJzKCksIHRydWUsIGN1cnJTY2hlbWFEb2MpKTsKLSAgICAgICAgICAgICAgICAgICAgc2F3QW5ub3RhdGlvbiA9IHRydWU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcigiczRzLWVsdC1pbnZhbGlkLWNvbnRlbnQuMSIsIG5ldyBPYmplY3QgW10ge1NjaGVtYVN5bWJvbHMuRUxUX1NDSEVNQSwgRE9NVXRpbC5nZXRMb2NhbE5hbWUoZ2xvYmFsQ29tcCl9LCBnbG9iYWxDb21wKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9IC8vIGVuZCBmb3IKLQotICAgICAgICAgICAgaWYgKCFzYXdBbm5vdGF0aW9uKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIHRleHQgPSBET01VdGlsLmdldFN5bnRoZXRpY0Fubm90YXRpb24oY3VyclJvb3QpOwotICAgICAgICAgICAgICAgIGlmICh0ZXh0ICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgY3VyclNHLmFkZEFubm90YXRpb24oZkVsZW1lbnRUcmF2ZXJzZXIudHJhdmVyc2VTeW50aGV0aWNBbm5vdGF0aW9uKGN1cnJSb290LCB0ZXh0LCBjdXJyU2NoZW1hRG9jLmdldFNjaGVtYUF0dHJzKCksIHRydWUsIGN1cnJTY2hlbWFEb2MpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8qKiBDb2xsZWN0IGFubm90YXRpb24gaW5mb3JtYXRpb24gZm9yIHZhbGlkYXRpb24uICoqLwotICAgICAgICAgICAgaWYgKGFubm90YXRpb25JbmZvICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBYU0Fubm90YXRpb25JbmZvIGluZm8gPSBjdXJyU2NoZW1hRG9jLmdldEFubm90YXRpb25zKCk7Ci0gICAgICAgICAgICAgICAgLyoqIE9ubHkgYWRkIGFubm90YXRpb25zIHRvIHRoZSBsaXN0IGlmIHRoZXJlIHdlcmUgYW55IGluIHRoaXMgZG9jdW1lbnQuICoqLwotICAgICAgICAgICAgICAgIGlmIChpbmZvICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgYW5ub3RhdGlvbkluZm8uYWRkKGRvYzJTeXN0ZW1JZChjdXJyRG9jKSk7Ci0gICAgICAgICAgICAgICAgICAgIGFubm90YXRpb25JbmZvLmFkZChpbmZvKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyBub3cgd2UncmUgZG9uZSB3aXRoIHRoaXMgb25lIQotICAgICAgICAgICAgY3VyclNjaGVtYURvYy5yZXR1cm5TY2hlbWFBdHRycygpOwotICAgICAgICAgICAgRE9NVXRpbC5zZXRIaWRkZW4oY3VyckRvYywgZkhpZGRlbk5vZGVzKTsKLQotICAgICAgICAgICAgLy8gbm93IGFkZCB0aGUgc2NoZW1hcyB0aGlzIGd1eSBkZXBlbmRzIG9uCi0gICAgICAgICAgICBWZWN0b3I8WFNEb2N1bWVudEluZm8+IGN1cnJTY2hlbWFEZXBlbmRzID0gZkRlcGVuZGVuY3lNYXAuZ2V0KGN1cnJTY2hlbWFEb2MpOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjdXJyU2NoZW1hRGVwZW5kcy5zaXplKCk7IGkrKykgewotICAgICAgICAgICAgICAgIHNjaGVtYXNUb1Byb2Nlc3MucHVzaChjdXJyU2NoZW1hRGVwZW5kcy5lbGVtZW50QXQoaSkpOwotICAgICAgICAgICAgfQotICAgICAgICB9IC8vIHdoaWxlCi0gICAgfSAvLyBlbmQgdHJhdmVyc2VTY2hlbWFzCi0KLSAgICAvLyBzdG9yZSB3aGV0aGVyIHdlIGhhdmUgcmVwb3J0ZWQgYW4gZXJyb3IgYWJvdXQgdGhhdCBubyBncmFtbWFyCi0gICAgLy8gaXMgZm91bmQgZm9yIHRoZSBnaXZlbiBuYW1lc3BhY2UgdXJpCi0gICAgcHJpdmF0ZSBWZWN0b3IgZlJlcG9ydGVkVE5TID0gbnVsbDsKLSAgICAvLyBjaGVjayB3aGV0aGVyIHdlIG5lZWQgdG8gcmVwb3J0IGFuIGVycm9yIGFnYWluc3QgdGhlIGdpdmVuIHVyaS4KLSAgICAvLyBpZiB3ZSBoYXZlIHJlcG9ydGVkIGFuIGVycm9yLCB0aGVuIHdlIGRvbid0IG5lZWQgdG8gcmVwb3J0IGFnYWluOwotICAgIC8vIG90aGVyd2lzZSB3ZSByZXBvcnRlZCB0aGUgZXJyb3IsIGFuZCByZW1lbWJlciB0aGlzIGZhY3QuCi0gICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIG5lZWRSZXBvcnRUTlNFcnJvcihTdHJpbmcgdXJpKSB7Ci0gICAgICAgIGlmIChmUmVwb3J0ZWRUTlMgPT0gbnVsbCkKLSAgICAgICAgICAgIGZSZXBvcnRlZFROUyA9IG5ldyBWZWN0b3IoKTsKLSAgICAgICAgZWxzZSBpZiAoZlJlcG9ydGVkVE5TLmNvbnRhaW5zKHVyaSkpCi0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIGZSZXBvcnRlZFROUy5hZGRFbGVtZW50KHVyaSk7Ci0gICAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZ1tdIENPTVBfVFlQRSA9IHsKLSAgICAgICAgICAgIG51bGwsICAgICAgICAgICAgICAgLy8gaW5kZXggMAotICAgICAgICAgICAgImF0dHJpYnV0ZSBkZWNsYXJhdGlvbiIsCi0gICAgICAgICAgICAiYXR0cmlidXRlIGdyb3VwIiwKLSAgICAgICAgICAgICJlbGVtZW50IGRlY2xhcmF0aW9uIiwKLSAgICAgICAgICAgICJncm91cCIsCi0gICAgICAgICAgICAiaWRlbnRpdHkgY29uc3RyYWludCIsCi0gICAgICAgICAgICAibm90YXRpb24iLAotICAgICAgICAgICAgInR5cGUgZGVmaW5pdGlvbiIsCi0gICAgfTsKLQotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZ1tdIENJUkNVTEFSX0NPREVTID0gewotICAgICAgICAgICAgIkludGVybmFsLUVycm9yIiwKLSAgICAgICAgICAgICJJbnRlcm5hbC1FcnJvciIsCi0gICAgICAgICAgICAic3JjLWF0dHJpYnV0ZV9ncm91cC4zIiwKLSAgICAgICAgICAgICJlLXByb3BzLWNvcnJlY3QuNiIsCi0gICAgICAgICAgICAibWctcHJvcHMtY29ycmVjdC4yIiwKLSAgICAgICAgICAgICJJbnRlcm5hbC1FcnJvciIsCi0gICAgICAgICAgICAiSW50ZXJuYWwtRXJyb3IiLAotICAgICAgICAgICAgInN0LXByb3BzLWNvcnJlY3QuMiIsICAgICAgIC8vb3IgY3QtcHJvcHMtY29ycmVjdC4zCi0gICAgfTsKLQotICAgIC8vIGFkZCBhIGdsb2JhbCBhdHRyaWJ1dGUgZGVjbCBmcm9tIGEgY3VycmVudCBzY2hlbWEgbG9hZCAob25seSBpZiBubyBleGlzdGluZyBkZWNsIGlzIGZvdW5kKQotICAgIHZvaWQgYWRkR2xvYmFsQXR0cmlidXRlRGVjbChYU0F0dHJpYnV0ZURlY2wgZGVjbCkgewotICAgICAgICBmaW5hbCBTdHJpbmcgbmFtZXNwYWNlID0gZGVjbC5nZXROYW1lc3BhY2UoKTsKLSAgICAgICAgZmluYWwgU3RyaW5nIGRlY2xLZXkgPSAobmFtZXNwYWNlID09IG51bGwgfHwgbmFtZXNwYWNlLmxlbmd0aCgpID09IDApCi0gICAgICAgICAgICA/ICIsIiArIGRlY2wuZ2V0TmFtZSgpIDogbmFtZXNwYWNlICsgIiwiICsgZGVjbC5nZXROYW1lKCk7Ci0KLSAgICAgICAgaWYgKGZHbG9iYWxBdHRyRGVjbHMuZ2V0KGRlY2xLZXkpID09IG51bGwpIHsKLSAgICAgICAgICAgIGZHbG9iYWxBdHRyRGVjbHMucHV0KGRlY2xLZXksIGRlY2wpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLy8gYWRkIGEgZ2xvYmFsIGF0dHJpYnV0ZSBncm91cCBkZWNsIGZyb20gYSBjdXJyZW50IHNjaGVtYSBsb2FkIChvbmx5IGlmIG5vIGV4aXN0aW5nIGRlY2wgaXMgZm91bmQpCi0gICAgdm9pZCBhZGRHbG9iYWxBdHRyaWJ1dGVHcm91cERlY2woWFNBdHRyaWJ1dGVHcm91cERlY2wgZGVjbCkgewotICAgICAgICBmaW5hbCBTdHJpbmcgbmFtZXNwYWNlID0gZGVjbC5nZXROYW1lc3BhY2UoKTsKLSAgICAgICAgZmluYWwgU3RyaW5nIGRlY2xLZXkgPSAobmFtZXNwYWNlID09IG51bGwgfHwgbmFtZXNwYWNlLmxlbmd0aCgpID09IDApCi0gICAgICAgICAgICA/ICIsIiArIGRlY2wuZ2V0TmFtZSgpIDogbmFtZXNwYWNlICsgIiwiICsgZGVjbC5nZXROYW1lKCk7Ci0KLSAgICAgICAgaWYgKGZHbG9iYWxBdHRyR3JwRGVjbHMuZ2V0KGRlY2xLZXkpID09IG51bGwpIHsKLSAgICAgICAgICAgIGZHbG9iYWxBdHRyR3JwRGVjbHMucHV0KGRlY2xLZXksIGRlY2wpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLy8gYWRkIGEgZ2xvYmFsIGVsZW1lbnQgZGVjbCBmcm9tIGEgY3VycmVudCBzY2hlbWEgbG9hZCAob25seSBpZiBubyBleGlzdGluZyBkZWNsIGlzIGZvdW5kKQotICAgIHZvaWQgYWRkR2xvYmFsRWxlbWVudERlY2woWFNFbGVtZW50RGVjbCBkZWNsKSB7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBuYW1lc3BhY2UgPSBkZWNsLmdldE5hbWVzcGFjZSgpOwotICAgICAgICBmaW5hbCBTdHJpbmcgZGVjbEtleSA9IChuYW1lc3BhY2UgPT0gbnVsbCB8fCBuYW1lc3BhY2UubGVuZ3RoKCkgPT0gMCkKLSAgICAgICAgICAgID8gIiwiICsgZGVjbC5nZXROYW1lKCkgOiBuYW1lc3BhY2UgKyAiLCIgKyBkZWNsLmdldE5hbWUoKTsKLQotICAgICAgICBpZiAoZkdsb2JhbEVsZW1EZWNscy5nZXQoZGVjbEtleSkgPT0gbnVsbCkgewotICAgICAgICAgICAgZkdsb2JhbEVsZW1EZWNscy5wdXQoZGVjbEtleSwgZGVjbCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvLyBhZGQgYSBnbG9iYWwgZ3JvdXAgZGVjbCBmcm9tIGEgY3VycmVudCBzY2hlbWEgbG9hZCAob25seSBpZiBubyBleGlzdGluZyBkZWNsIGlzIGZvdW5kKQotICAgIHZvaWQgYWRkR2xvYmFsR3JvdXBEZWNsKFhTR3JvdXBEZWNsIGRlY2wpIHsKLSAgICAgICAgZmluYWwgU3RyaW5nIG5hbWVzcGFjZSA9IGRlY2wuZ2V0TmFtZXNwYWNlKCk7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBkZWNsS2V5ID0gKG5hbWVzcGFjZSA9PSBudWxsIHx8IG5hbWVzcGFjZS5sZW5ndGgoKSA9PSAwKQotICAgICAgICAgICAgPyAiLCIgKyBkZWNsLmdldE5hbWUoKSA6IG5hbWVzcGFjZSArICIsIiArIGRlY2wuZ2V0TmFtZSgpOwotCi0gICAgICAgIGlmIChmR2xvYmFsR3JvdXBEZWNscy5nZXQoZGVjbEtleSkgPT0gbnVsbCkgewotICAgICAgICAgICAgZkdsb2JhbEdyb3VwRGVjbHMucHV0KGRlY2xLZXksIGRlY2wpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLy8gYWRkIGEgZ2xvYmFsIG5vdGF0aW9uIGRlY2wgZnJvbSBhIGN1cnJlbnQgc2NoZW1hIGxvYWQgKG9ubHkgaWYgbm8gZXhpc3RpbmcgZGVjbCBpcyBmb3VuZCkKLSAgICB2b2lkIGFkZEdsb2JhbE5vdGF0aW9uRGVjbChYU05vdGF0aW9uRGVjbCBkZWNsKSB7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBuYW1lc3BhY2UgPSBkZWNsLmdldE5hbWVzcGFjZSgpOwotICAgICAgICBmaW5hbCBTdHJpbmcgZGVjbEtleSA9IChuYW1lc3BhY2UgPT0gbnVsbCB8fCBuYW1lc3BhY2UubGVuZ3RoKCkgPT0gMCkKLSAgICAgICAgICAgID8gIiwiICsgZGVjbC5nZXROYW1lKCkgOiBuYW1lc3BhY2UgKyAiLCIgKyBkZWNsLmdldE5hbWUoKTsKLQotICAgICAgICBpZiAoZkdsb2JhbE5vdGF0aW9uRGVjbHMuZ2V0KGRlY2xLZXkpID09IG51bGwpIHsKLSAgICAgICAgICAgIGZHbG9iYWxOb3RhdGlvbkRlY2xzLnB1dChkZWNsS2V5LCBkZWNsKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8vIGFkZCBhIGdsb2JhbCB0eXBlIGRlY2wgZnJvbSBhIGN1cnJlbnQgc2NoZW1hIGxvYWQgKG9ubHkgaWYgbm8gZXhpc3RpbmcgZGVjbCBpcyBmb3VuZCkKLSAgICB2b2lkIGFkZEdsb2JhbFR5cGVEZWNsKFhTVHlwZURlZmluaXRpb24gZGVjbCkgewotICAgICAgICBmaW5hbCBTdHJpbmcgbmFtZXNwYWNlID0gZGVjbC5nZXROYW1lc3BhY2UoKTsKLSAgICAgICAgZmluYWwgU3RyaW5nIGRlY2xLZXkgPSAobmFtZXNwYWNlID09IG51bGwgfHwgbmFtZXNwYWNlLmxlbmd0aCgpID09IDApCi0gICAgICAgICAgICA/ICIsIiArIGRlY2wuZ2V0TmFtZSgpIDogbmFtZXNwYWNlICsgIiwiICsgZGVjbC5nZXROYW1lKCk7Ci0KLSAgICAgICAgaWYgKGZHbG9iYWxUeXBlRGVjbHMuZ2V0KGRlY2xLZXkpID09IG51bGwpIHsKLSAgICAgICAgICAgIGZHbG9iYWxUeXBlRGVjbHMucHV0KGRlY2xLZXksIGRlY2wpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLy8gYWRkIGEgaWRlbnRpdHkgY29uc3RyYWludCBkZWNsIGZyb20gYSBjdXJyZW50IHNjaGVtYSBsb2FkIChvbmx5IGlmIG5vIGV4aXN0aW5nIGRlY2wgaXMgZm91bmQpCi0gICAgdm9pZCBhZGRJRENvbnN0cmFpbnREZWNsKElkZW50aXR5Q29uc3RyYWludCBkZWNsKSB7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBuYW1lc3BhY2UgPSBkZWNsLmdldE5hbWVzcGFjZSgpOwotICAgICAgICBmaW5hbCBTdHJpbmcgZGVjbEtleSA9IChuYW1lc3BhY2UgPT0gbnVsbCB8fCBuYW1lc3BhY2UubGVuZ3RoKCkgPT0gMCkKLSAgICAgICAgICAgID8gIiwiICsgZGVjbC5nZXRJZGVudGl0eUNvbnN0cmFpbnROYW1lKCkgOiBuYW1lc3BhY2UgKyAiLCIgKyBkZWNsLmdldElkZW50aXR5Q29uc3RyYWludE5hbWUoKTsKLQotICAgICAgICBpZiAoZkdsb2JhbElEQ29uc3RyYWludERlY2xzLmdldChkZWNsS2V5KSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBmR2xvYmFsSURDb25zdHJhaW50RGVjbHMucHV0KGRlY2xLZXksIGRlY2wpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBYU0F0dHJpYnV0ZURlY2wgZ2V0R2xvYmFsQXR0cmlidXRlRGVjbChTdHJpbmcgZGVjbEtleSkgewotICAgICAgICByZXR1cm4gKFhTQXR0cmlidXRlRGVjbClmR2xvYmFsQXR0ckRlY2xzLmdldChkZWNsS2V5KTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIFhTQXR0cmlidXRlR3JvdXBEZWNsIGdldEdsb2JhbEF0dHJpYnV0ZUdyb3VwRGVjbChTdHJpbmcgZGVjbEtleSkgewotICAgICAgICByZXR1cm4gKFhTQXR0cmlidXRlR3JvdXBEZWNsKWZHbG9iYWxBdHRyR3JwRGVjbHMuZ2V0KGRlY2xLZXkpOwotICAgIH0KLQotICAgIHByaXZhdGUgWFNFbGVtZW50RGVjbCBnZXRHbG9iYWxFbGVtZW50RGVjbChTdHJpbmcgZGVjbEtleSkgewotICAgICAgICByZXR1cm4gKFhTRWxlbWVudERlY2wpZkdsb2JhbEVsZW1EZWNscy5nZXQoZGVjbEtleSk7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBYU0dyb3VwRGVjbCBnZXRHbG9iYWxHcm91cERlY2woU3RyaW5nIGRlY2xLZXkpIHsKLSAgICAgICAgcmV0dXJuIChYU0dyb3VwRGVjbClmR2xvYmFsR3JvdXBEZWNscy5nZXQoZGVjbEtleSk7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBYU05vdGF0aW9uRGVjbCBnZXRHbG9iYWxOb3RhdGlvbkRlY2woU3RyaW5nIGRlY2xLZXkpIHsKLSAgICAgICAgcmV0dXJuIChYU05vdGF0aW9uRGVjbClmR2xvYmFsTm90YXRpb25EZWNscy5nZXQoZGVjbEtleSk7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBYU1R5cGVEZWZpbml0aW9uIGdldEdsb2JhbFR5cGVEZWNsKFN0cmluZyBkZWNsS2V5KSB7Ci0gICAgICAgIHJldHVybiAoWFNUeXBlRGVmaW5pdGlvbilmR2xvYmFsVHlwZURlY2xzLmdldChkZWNsS2V5KTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIElkZW50aXR5Q29uc3RyYWludCBnZXRJRENvbnN0cmFpbnREZWNsKFN0cmluZyBkZWNsS2V5KSB7Ci0gICAgICAgIHJldHVybiAoSWRlbnRpdHlDb25zdHJhaW50KWZHbG9iYWxJRENvbnN0cmFpbnREZWNscy5nZXQoZGVjbEtleSk7Ci0gICAgfQotCi0gICAgLy8gc2luY2UgaXQgaXMgZm9yYmlkZGVuIGZvciB0cmF2ZXJzZXJzIHRvIHRhbGsgdG8gZWFjaCBvdGhlcgotICAgIC8vIGRpcmVjdGx5IChleGNlcHQgd2VuIGEgdHJhdmVyc2VyIGVuY291bnRlcnMgYSBsb2NhbCBkZWNsYXJhdGlvbiksCi0gICAgLy8gdGhpcyBwcm92aWRlcyBhIGdlbmVyaWMgbWVhbnMgZm9yIGEgdHJhdmVyc2VyIHRvIGNhbGwKLSAgICAvLyBmb3IgdGhlIHRyYXZlcnNhbCBvZiBzb21lIGRlY2xhcmF0aW9uLiAgQW4gWFNEb2N1bWVudEluZm8gaXMKLSAgICAvLyByZXF1aXJlZCBiZWNhdXNlIHRoZSBYU0RvY3VtZW50SW5mbyB0aGF0IHRoZSB0cmF2ZXJzZXIgaXMgdHJhdmVyc2luZwotICAgIC8vIG1heSBiZWFyIG5vIHJlbGF0aW9uIHRvIHRoZSBvbmUgdGhlIGhhbmRsZXIgaXMgb3BlcmF0aW5nIG9uLgotICAgIC8vIFRoaXMgbWV0aG9kIHdpbGw6Ci0gICAgLy8gMS4gIFNlZSBpZiBhIGdsb2JhbCBkZWZpbml0aW9uIG1hdGNoaW5nIGRlY2xUb1RyYXZlcnNlIGV4aXN0czsKLSAgICAvLyAyLiBpZiBzbywgZGV0ZXJtaW5lIGlmIHRoZXJlIGlzIGEgcGF0aCBmcm9tIGN1cnJTY2hlbWEgdG8gdGhlCi0gICAgLy8gc2NoZW1hIGRvY3VtZW50IHdoZXJlIGRlY2xUb1RyYXZlcnNlIGxpdmVzIChpLmUuLCBkbyBhIGxvb2t1cAotICAgIC8vIGluIERlcGVuZGVuY3lNYXApOwotICAgIC8vIDMuIGRlcGVuZGluZyBvbiBkZWNsVHlwZSAod2hpY2ggd2lsbCBiZSByZWxldmFudCB0byBzdGVwIDEgYXMKLSAgICAvLyB3ZWxsKSwgY2FsbCB0aGUgYXBwcm9wcmlhdGUgdHJhdmVyc2VyIHdpdGggdGhlIGFwcHJvcHJpYXRlCi0gICAgLy8gWFNEb2N1bWVudEluZm8gb2JqZWN0LgotICAgIC8vIFRoaXMgbWV0aG9kIHJldHVybnMgd2hhdGV2ZXIgdGhlIHRyYXZlcnNlciBpdCBjYWxsZWQgcmV0dXJuZWQ7Ci0gICAgLy8gdGhpcyB3aWxsIGJlIGFuIE9iamVjdCBvZiBzb21lIGtpbmQKLSAgICAvLyB0aGF0IGxpdmVzIGluIHRoZSBHcmFtbWFyLgotICAgIHByb3RlY3RlZCBPYmplY3QgZ2V0R2xvYmFsRGVjbChYU0RvY3VtZW50SW5mbyBjdXJyU2NoZW1hLAotICAgICAgICAgICAgaW50IGRlY2xUeXBlLAotICAgICAgICAgICAgUU5hbWUgZGVjbFRvVHJhdmVyc2UsCi0gICAgICAgICAgICBFbGVtZW50IGVsbU5vZGUpIHsKLQotICAgICAgICBpZiAoREVCVUdfTk9ERV9QT09MKSB7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlRSQVZFUlNFX0dMOiAiK2RlY2xUb1RyYXZlcnNlLnRvU3RyaW5nKCkpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gZnJvbSB0aGUgc2NoZW1hIHNwZWMsIGFsbCBidWlsdC1pbiB0eXBlcyBhcmUgcHJlc2VudCBpbiBhbGwgc2NoZW1hcywKLSAgICAgICAgLy8gc28gaWYgdGhlIHJlcXVlc3RlZCBjb21wb25lbnQgaXMgYSB0eXBlLCBhbmQgY291bGQgYmUgZm91bmQgaW4gdGhlCi0gICAgICAgIC8vIGRlZmF1bHQgc2NoZW1hIGdyYW1tYXIsIHdlIHNob3VsZCByZXR1cm4gdGhhdCB0eXBlLgotICAgICAgICAvLyBvdGhlcndpc2UgKHNpbmNlIHdlIHdvdWxkIHN1cHBvcnQgdXNlci1kZWZpbmVkIHNjaGVtYSBncmFtbWFyKSB3ZSdsbAotICAgICAgICAvLyB1c2UgdGhlIG5vcm1hbCB3YXkgdG8gZ2V0IHRoZSBkZWNsCi0gICAgICAgIGlmIChkZWNsVG9UcmF2ZXJzZS51cmkgIT0gbnVsbCAmJgotICAgICAgICAgICAgICAgIGRlY2xUb1RyYXZlcnNlLnVyaSA9PSBTY2hlbWFTeW1ib2xzLlVSSV9TQ0hFTUFGT1JTQ0hFTUEpIHsKLSAgICAgICAgICAgIGlmIChkZWNsVHlwZSA9PSBUWVBFREVDTF9UWVBFKSB7Ci0gICAgICAgICAgICAgICAgT2JqZWN0IHJldE9iaiA9IFNjaGVtYUdyYW1tYXIuU0dfU2NoZW1hTlMuZ2V0R2xvYmFsVHlwZURlY2woZGVjbFRvVHJhdmVyc2UubG9jYWxwYXJ0KTsKLSAgICAgICAgICAgICAgICBpZiAocmV0T2JqICE9IG51bGwpCi0gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXRPYmo7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBub3cgY2hlY2sgd2hldGhlciB0aGlzIGRvY3VtZW50IGNhbiBhY2Nlc3MgdGhlIHJlcXVzdGVkIG5hbWVzcGFjZQotICAgICAgICBpZiAoIWN1cnJTY2hlbWEuaXNBbGxvd2VkTlMoZGVjbFRvVHJhdmVyc2UudXJpKSkgewotICAgICAgICAgICAgLy8gY2Fubm90IGdldCB0byB0aGlzIHNjaGVtYSBmcm9tIHRoZSBvbmUgY29udGFpbmluZyB0aGUgcmVxdWVzdGluZyBkZWNsCi0gICAgICAgICAgICBpZiAoY3VyclNjaGVtYS5uZWVkUmVwb3J0VE5TRXJyb3IoZGVjbFRvVHJhdmVyc2UudXJpKSkgewotICAgICAgICAgICAgICAgIFN0cmluZyBjb2RlID0gZGVjbFRvVHJhdmVyc2UudXJpID09IG51bGwgPyAic3JjLXJlc29sdmUuNC4xIiA6ICJzcmMtcmVzb2x2ZS40LjIiOwotICAgICAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKGNvZGUsIG5ldyBPYmplY3RbXXtmRG9jMlN5c3RlbUlkLmdldChjdXJyU2NoZW1hLmZTY2hlbWFFbGVtZW50KSwgZGVjbFRvVHJhdmVyc2UudXJpLCBkZWNsVG9UcmF2ZXJzZS5yYXduYW1lfSwgZWxtTm9kZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyBSZWNvdmVyIGFuZCBjb250aW51ZSB0byBsb29rIGZvciB0aGUgY29tcG9uZW50LgotICAgICAgICAgICAgLy8gcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBjaGVjayB3aGV0aGVyIHRoZXJlIGlzIGdyYW1tYXIgZm9yIHRoZSByZXF1ZXN0ZWQgbmFtZXNwYWNlCi0gICAgICAgIFNjaGVtYUdyYW1tYXIgc0dyYW1tYXIgPSBmR3JhbW1hckJ1Y2tldC5nZXRHcmFtbWFyKGRlY2xUb1RyYXZlcnNlLnVyaSk7Ci0gICAgICAgIGlmIChzR3JhbW1hciA9PSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAobmVlZFJlcG9ydFROU0Vycm9yKGRlY2xUb1RyYXZlcnNlLnVyaSkpCi0gICAgICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoInNyYy1yZXNvbHZlIiwgbmV3IE9iamVjdFtde2RlY2xUb1RyYXZlcnNlLnJhd25hbWUsIENPTVBfVFlQRVtkZWNsVHlwZV19LCBlbG1Ob2RlKTsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gaWYgdGhlcmUgaXMgc3VjaCBncmFtbWFyLCBjaGVjayB3aGV0aGVyIHRoZSByZXF1ZXN0ZWQgY29tcG9uZW50IGlzIGluIHRoZSBncmFtbWFyCi0gICAgICAgIE9iamVjdCByZXRPYmogPSBnZXRHbG9iYWxEZWNsRnJvbUdyYW1tYXIoc0dyYW1tYXIsIGRlY2xUeXBlLCBkZWNsVG9UcmF2ZXJzZS5sb2NhbHBhcnQpOwotICAgICAgICBTdHJpbmcgZGVjbEtleSA9IGRlY2xUb1RyYXZlcnNlLnVyaSA9PSBudWxsPyAiLCIrZGVjbFRvVHJhdmVyc2UubG9jYWxwYXJ0OgotICAgICAgICAgICAgZGVjbFRvVHJhdmVyc2UudXJpKyIsIitkZWNsVG9UcmF2ZXJzZS5sb2NhbHBhcnQ7Ci0KLSAgICAgICAgLy8gaWYgdGhlIGNvbXBvbmVudCBpcyBwYXJzZWQsIHJldHVybiBpdAotICAgICAgICBpZiAoIWZUb2xlcmF0ZUR1cGxpY2F0ZXMpIHsKLSAgICAgICAgICAgIGlmIChyZXRPYmogIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJldHVybiByZXRPYmo7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBPYmplY3QgcmV0T2JqMiA9IGdldEdsb2JhbERlY2woZGVjbEtleSwgZGVjbFR5cGUpOwotICAgICAgICAgICAgaWYgKHJldE9iajIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJldHVybiByZXRPYmoyOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgWFNEb2N1bWVudEluZm8gc2NoZW1hV2l0aERlY2wgPSBudWxsOwotICAgICAgICBFbGVtZW50IGRlY2wgPSBudWxsOwotICAgICAgICBYU0RvY3VtZW50SW5mbyBkZWNsRG9jID0gbnVsbDsKLQotICAgICAgICAvLyB0aGUgY29tcG9uZW50IGlzIG5vdCBwYXJzZWQsIHRyeSB0byBmaW5kIGEgRE9NIGVsZW1lbnQgZm9yIGl0Ci0gICAgICAgIHN3aXRjaCAoZGVjbFR5cGUpIHsKLSAgICAgICAgY2FzZSBBVFRSSUJVVEVfVFlQRSA6Ci0gICAgICAgICAgICBkZWNsID0gZ2V0RWxlbWVudEZyb21NYXAoZlVucGFyc2VkQXR0cmlidXRlUmVnaXN0cnksIGRlY2xLZXkpOwotICAgICAgICAgICAgZGVjbERvYyA9IGdldERvY0luZm9Gcm9tTWFwKGZVbnBhcnNlZEF0dHJpYnV0ZVJlZ2lzdHJ5U3ViLCBkZWNsS2V5KTsKLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICBjYXNlIEFUVFJJQlVURUdST1VQX1RZUEUgOgotICAgICAgICAgICAgZGVjbCA9IGdldEVsZW1lbnRGcm9tTWFwKGZVbnBhcnNlZEF0dHJpYnV0ZUdyb3VwUmVnaXN0cnksIGRlY2xLZXkpOwotICAgICAgICAgICAgZGVjbERvYyA9IGdldERvY0luZm9Gcm9tTWFwKGZVbnBhcnNlZEF0dHJpYnV0ZUdyb3VwUmVnaXN0cnlTdWIsIGRlY2xLZXkpOwotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgRUxFTUVOVF9UWVBFIDoKLSAgICAgICAgICAgIGRlY2wgPSBnZXRFbGVtZW50RnJvbU1hcChmVW5wYXJzZWRFbGVtZW50UmVnaXN0cnksIGRlY2xLZXkpOwotICAgICAgICAgICAgZGVjbERvYyA9IGdldERvY0luZm9Gcm9tTWFwKGZVbnBhcnNlZEVsZW1lbnRSZWdpc3RyeVN1YiwgZGVjbEtleSk7Ci0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBHUk9VUF9UWVBFIDoKLSAgICAgICAgICAgIGRlY2wgPSBnZXRFbGVtZW50RnJvbU1hcChmVW5wYXJzZWRHcm91cFJlZ2lzdHJ5LCBkZWNsS2V5KTsKLSAgICAgICAgICAgIGRlY2xEb2MgPSBnZXREb2NJbmZvRnJvbU1hcChmVW5wYXJzZWRHcm91cFJlZ2lzdHJ5U3ViLCBkZWNsS2V5KTsKLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICBjYXNlIElERU5USVRZQ09OU1RSQUlOVF9UWVBFIDoKLSAgICAgICAgICAgIGRlY2wgPSBnZXRFbGVtZW50RnJvbU1hcChmVW5wYXJzZWRJZGVudGl0eUNvbnN0cmFpbnRSZWdpc3RyeSwgZGVjbEtleSk7Ci0gICAgICAgICAgICBkZWNsRG9jID0gZ2V0RG9jSW5mb0Zyb21NYXAoZlVucGFyc2VkSWRlbnRpdHlDb25zdHJhaW50UmVnaXN0cnlTdWIsIGRlY2xLZXkpOwotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgTk9UQVRJT05fVFlQRSA6Ci0gICAgICAgICAgICBkZWNsID0gZ2V0RWxlbWVudEZyb21NYXAoZlVucGFyc2VkTm90YXRpb25SZWdpc3RyeSwgZGVjbEtleSk7Ci0gICAgICAgICAgICBkZWNsRG9jID0gZ2V0RG9jSW5mb0Zyb21NYXAoZlVucGFyc2VkTm90YXRpb25SZWdpc3RyeVN1YiwgZGVjbEtleSk7Ci0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBUWVBFREVDTF9UWVBFIDoKLSAgICAgICAgICAgIGRlY2wgPSBnZXRFbGVtZW50RnJvbU1hcChmVW5wYXJzZWRUeXBlUmVnaXN0cnksIGRlY2xLZXkpOwotICAgICAgICAgICAgZGVjbERvYyA9IGdldERvY0luZm9Gcm9tTWFwKGZVbnBhcnNlZFR5cGVSZWdpc3RyeVN1YiwgZGVjbEtleSk7Ci0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgZGVmYXVsdDoKLSAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKCJJbnRlcm5hbC1FcnJvciIsIG5ldyBPYmplY3QgW10geyJYU0RIYW5kbGVyIGFza2VkIHRvIGxvY2F0ZSBjb21wb25lbnQgb2YgdHlwZSAiICsgZGVjbFR5cGUgKyAiOyBpdCBkb2VzIG5vdCByZWNvZ25pemUgdGhpcyB0eXBlISJ9LCBlbG1Ob2RlKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIG5vIERPTSBlbGVtZW50IGZvdW5kLCBzbyB0aGUgY29tcG9uZW50IGNhbid0IGJlIGxvY2F0ZWQKLSAgICAgICAgaWYgKGRlY2wgPT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKHJldE9iaiA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoInNyYy1yZXNvbHZlIiwgbmV3IE9iamVjdFtde2RlY2xUb1RyYXZlcnNlLnJhd25hbWUsIENPTVBfVFlQRVtkZWNsVHlwZV19LCBlbG1Ob2RlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiByZXRPYmo7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBnZXQgdGhlIHNjaGVtYSBkb2MgY29udGFpbmluZyB0aGUgY29tcG9uZW50IHRvIGJlIHBhcnNlZAotICAgICAgICAvLyBpdCBzaG91bGQgYWx3YXlzIHJldHVybiBub24tbnVsbCB2YWx1ZSwgYnV0IHNpbmNlIG51bGwtY2hlY2tpbmcKLSAgICAgICAgLy8gY29tZXMgZm9yIGZyZWUsIGxldCdzIGJlIHNhZmUgYW5kIGNoZWNrIGFnYWluCi0gICAgICAgIHNjaGVtYVdpdGhEZWNsID0gZmluZFhTRG9jdW1lbnRGb3JEZWNsKGN1cnJTY2hlbWEsIGRlY2wsIGRlY2xEb2MpOwotICAgICAgICBpZiAoc2NoZW1hV2l0aERlY2wgPT0gbnVsbCkgewotICAgICAgICAgICAgLy8gY2Fubm90IGdldCB0byB0aGlzIHNjaGVtYSBmcm9tIHRoZSBvbmUgY29udGFpbmluZyB0aGUgcmVxdWVzdGluZyBkZWNsCi0gICAgICAgICAgICBpZiAocmV0T2JqID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgY29kZSA9IGRlY2xUb1RyYXZlcnNlLnVyaSA9PSBudWxsID8gInNyYy1yZXNvbHZlLjQuMSIgOiAic3JjLXJlc29sdmUuNC4yIjsKLSAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcihjb2RlLCBuZXcgT2JqZWN0W117ZkRvYzJTeXN0ZW1JZC5nZXQoY3VyclNjaGVtYS5mU2NoZW1hRWxlbWVudCksIGRlY2xUb1RyYXZlcnNlLnVyaSwgZGVjbFRvVHJhdmVyc2UucmF3bmFtZX0sIGVsbU5vZGUpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIHJldE9iajsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIGEgY29tcG9uZW50IGlzIGhpZGRlbiwgbWVhbmluZyBlaXRoZXIgaXQncyB0cmF2ZXJzZWQsIG9yIGJlaW5nIHRyYXZlcnNlZC4KLSAgICAgICAgLy8gYnV0IHdlIGRpZG4ndCBmaW5kIGl0IGluIHRoZSBncmFtbWFyLCBzbyBpdCdzIHRoZSBsYXR0ZXIgY2FzZSwgYW5kCi0gICAgICAgIC8vIGEgY2lyY3VsYXIgcmVmZXJlbmNlLiBlcnJvciEKLSAgICAgICAgaWYgKERPTVV0aWwuaXNIaWRkZW4oZGVjbCwgZkhpZGRlbk5vZGVzKSkgewotICAgICAgICAgICAgaWYgKHJldE9iaiA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIGNvZGUgPSBDSVJDVUxBUl9DT0RFU1tkZWNsVHlwZV07Ci0gICAgICAgICAgICAgICAgaWYgKGRlY2xUeXBlID09IFRZUEVERUNMX1RZUEUpIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKFNjaGVtYVN5bWJvbHMuRUxUX0NPTVBMRVhUWVBFLmVxdWFscyhET01VdGlsLmdldExvY2FsTmFtZShkZWNsKSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGNvZGUgPSAiY3QtcHJvcHMtY29ycmVjdC4zIjsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvLyBkZWNsIG11c3Qgbm90IGJlIG51bGwgaWYgd2UncmUgaGVyZS4uLgotICAgICAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKGNvZGUsIG5ldyBPYmplY3QgW10ge2RlY2xUb1RyYXZlcnNlLnByZWZpeCsiOiIrZGVjbFRvVHJhdmVyc2UubG9jYWxwYXJ0fSwgZWxtTm9kZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gcmV0T2JqOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIHRyYXZlcnNlR2xvYmFsRGVjbChkZWNsVHlwZSwgZGVjbCwgc2NoZW1hV2l0aERlY2wsIHNHcmFtbWFyKTsKLSAgICB9IC8vIGdldEdsb2JhbERlY2woWFNEb2N1bWVudEluZm8sIGludCwgUU5hbWUpOiAgT2JqZWN0Ci0KLSAgICAvLyBJZiB3ZSBhcmUgdG9sZXJhdGluZyBkdXBsaWNhdGUgZGVjbGFyYXRpb25zIGFuZCBhbGxvd2luZyBuYW1lc3BhY2UgZ3Jvd3RoCi0gICAgLy8gdXNlIHRoZSBkZWNsYXJhdGlvbiBmcm9tIHRoZSBjdXJyZW50IHNjaGVtYSBsb2FkIChpZiBpdCBleGlzdHMpCi0gICAgcHJvdGVjdGVkIE9iamVjdCBnZXRHbG9iYWxEZWNsKFN0cmluZyBkZWNsS2V5LCBpbnQgZGVjbFR5cGUpIHsKLSAgICAgICAgT2JqZWN0IHJldE9iaiA9IG51bGw7Ci0KLSAgICAgICAgc3dpdGNoIChkZWNsVHlwZSkgewotICAgICAgICBjYXNlIEFUVFJJQlVURV9UWVBFIDoKLSAgICAgICAgICAgIHJldE9iaiA9IGdldEdsb2JhbEF0dHJpYnV0ZURlY2woZGVjbEtleSk7Ci0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBBVFRSSUJVVEVHUk9VUF9UWVBFIDoKLSAgICAgICAgICAgIHJldE9iaiA9IGdldEdsb2JhbEF0dHJpYnV0ZUdyb3VwRGVjbChkZWNsS2V5KTsKLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICBjYXNlIEVMRU1FTlRfVFlQRSA6Ci0gICAgICAgICAgICByZXRPYmogPSBnZXRHbG9iYWxFbGVtZW50RGVjbChkZWNsS2V5KTsKLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICBjYXNlIEdST1VQX1RZUEUgOgotICAgICAgICAgICAgcmV0T2JqID0gZ2V0R2xvYmFsR3JvdXBEZWNsKGRlY2xLZXkpOwotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgSURFTlRJVFlDT05TVFJBSU5UX1RZUEUgOgotICAgICAgICAgICAgcmV0T2JqID0gZ2V0SURDb25zdHJhaW50RGVjbChkZWNsS2V5KTsKLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICBjYXNlIE5PVEFUSU9OX1RZUEUgOgotICAgICAgICAgICAgcmV0T2JqID0gZ2V0R2xvYmFsTm90YXRpb25EZWNsKGRlY2xLZXkpOwotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgVFlQRURFQ0xfVFlQRSA6Ci0gICAgICAgICAgICByZXRPYmogPSBnZXRHbG9iYWxUeXBlRGVjbChkZWNsS2V5KTsKLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIHJldE9iajsKLSAgICB9Ci0KLSAgICBwcm90ZWN0ZWQgT2JqZWN0IGdldEdsb2JhbERlY2xGcm9tR3JhbW1hcihTY2hlbWFHcmFtbWFyIHNHcmFtbWFyLCBpbnQgZGVjbFR5cGUsIFN0cmluZyBsb2NhbHBhcnQpIHsKLSAgICAgICAgT2JqZWN0IHJldE9iaiA9IG51bGw7Ci0KLSAgICAgICAgc3dpdGNoIChkZWNsVHlwZSkgewotICAgICAgICBjYXNlIEFUVFJJQlVURV9UWVBFIDoKLSAgICAgICAgICAgIHJldE9iaiA9IHNHcmFtbWFyLmdldEdsb2JhbEF0dHJpYnV0ZURlY2wobG9jYWxwYXJ0KTsKLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICBjYXNlIEFUVFJJQlVURUdST1VQX1RZUEUgOgotICAgICAgICAgICAgcmV0T2JqID0gc0dyYW1tYXIuZ2V0R2xvYmFsQXR0cmlidXRlR3JvdXBEZWNsKGxvY2FscGFydCk7Ci0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBFTEVNRU5UX1RZUEUgOgotICAgICAgICAgICAgcmV0T2JqID0gc0dyYW1tYXIuZ2V0R2xvYmFsRWxlbWVudERlY2wobG9jYWxwYXJ0KTsKLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICBjYXNlIEdST1VQX1RZUEUgOgotICAgICAgICAgICAgcmV0T2JqID0gc0dyYW1tYXIuZ2V0R2xvYmFsR3JvdXBEZWNsKGxvY2FscGFydCk7Ci0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBJREVOVElUWUNPTlNUUkFJTlRfVFlQRSA6Ci0gICAgICAgICAgICByZXRPYmogPSBzR3JhbW1hci5nZXRJRENvbnN0cmFpbnREZWNsKGxvY2FscGFydCk7Ci0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBOT1RBVElPTl9UWVBFIDoKLSAgICAgICAgICAgIHJldE9iaiA9IHNHcmFtbWFyLmdldEdsb2JhbE5vdGF0aW9uRGVjbChsb2NhbHBhcnQpOwotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgVFlQRURFQ0xfVFlQRSA6Ci0gICAgICAgICAgICByZXRPYmogPSBzR3JhbW1hci5nZXRHbG9iYWxUeXBlRGVjbChsb2NhbHBhcnQpOwotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gcmV0T2JqOwotICAgIH0KLQotICAgIHByb3RlY3RlZCBPYmplY3QgZ2V0R2xvYmFsRGVjbEZyb21HcmFtbWFyKFNjaGVtYUdyYW1tYXIgc0dyYW1tYXIsIGludCBkZWNsVHlwZSwgU3RyaW5nIGxvY2FscGFydCwgU3RyaW5nIHNjaGVtYUxvYykgewotICAgICAgICBPYmplY3QgcmV0T2JqID0gbnVsbDsKLQotICAgICAgICBzd2l0Y2ggKGRlY2xUeXBlKSB7Ci0gICAgICAgIGNhc2UgQVRUUklCVVRFX1RZUEUgOgotICAgICAgICAgICAgcmV0T2JqID0gc0dyYW1tYXIuZ2V0R2xvYmFsQXR0cmlidXRlRGVjbChsb2NhbHBhcnQsIHNjaGVtYUxvYyk7Ci0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBBVFRSSUJVVEVHUk9VUF9UWVBFIDoKLSAgICAgICAgICAgIHJldE9iaiA9IHNHcmFtbWFyLmdldEdsb2JhbEF0dHJpYnV0ZUdyb3VwRGVjbChsb2NhbHBhcnQsIHNjaGVtYUxvYyk7Ci0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBFTEVNRU5UX1RZUEUgOgotICAgICAgICAgICAgcmV0T2JqID0gc0dyYW1tYXIuZ2V0R2xvYmFsRWxlbWVudERlY2wobG9jYWxwYXJ0LCBzY2hlbWFMb2MpOwotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgR1JPVVBfVFlQRSA6Ci0gICAgICAgICAgICByZXRPYmogPSBzR3JhbW1hci5nZXRHbG9iYWxHcm91cERlY2wobG9jYWxwYXJ0LCBzY2hlbWFMb2MpOwotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgSURFTlRJVFlDT05TVFJBSU5UX1RZUEUgOgotICAgICAgICAgICAgcmV0T2JqID0gc0dyYW1tYXIuZ2V0SURDb25zdHJhaW50RGVjbChsb2NhbHBhcnQsIHNjaGVtYUxvYyk7Ci0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBOT1RBVElPTl9UWVBFIDoKLSAgICAgICAgICAgIHJldE9iaiA9IHNHcmFtbWFyLmdldEdsb2JhbE5vdGF0aW9uRGVjbChsb2NhbHBhcnQsIHNjaGVtYUxvYyk7Ci0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBUWVBFREVDTF9UWVBFIDoKLSAgICAgICAgICAgIHJldE9iaiA9IHNHcmFtbWFyLmdldEdsb2JhbFR5cGVEZWNsKGxvY2FscGFydCwgc2NoZW1hTG9jKTsKLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIHJldE9iajsKLSAgICB9Ci0KLSAgICBwcm90ZWN0ZWQgT2JqZWN0IHRyYXZlcnNlR2xvYmFsRGVjbChpbnQgZGVjbFR5cGUsIEVsZW1lbnQgZGVjbCwgWFNEb2N1bWVudEluZm8gc2NoZW1hRG9jLCBTY2hlbWFHcmFtbWFyIGdyYW1tYXIpIHsKLSAgICAgICAgT2JqZWN0IHJldE9iaiA9IG51bGw7Ci0KLSAgICAgICAgRE9NVXRpbC5zZXRIaWRkZW4oZGVjbCwgZkhpZGRlbk5vZGVzKTsKLSAgICAgICAgU2NoZW1hTmFtZXNwYWNlU3VwcG9ydCBuc1N1cHBvcnQgPSBudWxsOwotICAgICAgICAvLyBpZiB0aGUgcGFyZW50IGlzIDxyZWRlZmluZT4gdXNlIHRoZSBuYW1lc3BhY2UgZGVsY3MgZm9yIGl0LgotICAgICAgICBFbGVtZW50IHBhcmVudCA9IERPTVV0aWwuZ2V0UGFyZW50KGRlY2wpOwotICAgICAgICBpZiAoRE9NVXRpbC5nZXRMb2NhbE5hbWUocGFyZW50KS5lcXVhbHMoU2NoZW1hU3ltYm9scy5FTFRfUkVERUZJTkUpKQotICAgICAgICAgICAgbnNTdXBwb3J0ID0gKGZSZWRlZmluZTJOU1N1cHBvcnQhPW51bGwpPyhTY2hlbWFOYW1lc3BhY2VTdXBwb3J0KWZSZWRlZmluZTJOU1N1cHBvcnQuZ2V0KHBhcmVudCk6bnVsbDsKLSAgICAgICAgLy8gYmFjayB1cCB0aGUgY3VycmVudCBTY2hlbWFOYW1lc3BhY2VTdXBwb3J0LCBiZWNhdXNlIHdlIG5lZWQgdG8gcHJvdmlkZQotICAgICAgICAvLyBhIGZyZXNoIG9uZSB0byB0aGUgdHJhdmVyc2VHbG9iYWwgbWV0aG9kcy4KLSAgICAgICAgc2NoZW1hRG9jLmJhY2t1cE5TU3VwcG9ydChuc1N1cHBvcnQpOwotCi0gICAgICAgIC8vIHRyYXZlcnNlIHRoZSByZWZlcmVuY2VkIGdsb2JhbCBjb21wb25lbnQKLSAgICAgICAgc3dpdGNoIChkZWNsVHlwZSkgewotICAgICAgICBjYXNlIFRZUEVERUNMX1RZUEUgOgotICAgICAgICAgICAgaWYgKERPTVV0aWwuZ2V0TG9jYWxOYW1lKGRlY2wpLmVxdWFscyhTY2hlbWFTeW1ib2xzLkVMVF9DT01QTEVYVFlQRSkpIHsKLSAgICAgICAgICAgICAgICByZXRPYmogPSBmQ29tcGxleFR5cGVUcmF2ZXJzZXIudHJhdmVyc2VHbG9iYWwoZGVjbCwgc2NoZW1hRG9jLCBncmFtbWFyKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIHJldE9iaiA9IGZTaW1wbGVUeXBlVHJhdmVyc2VyLnRyYXZlcnNlR2xvYmFsKGRlY2wsIHNjaGVtYURvYywgZ3JhbW1hcik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBBVFRSSUJVVEVfVFlQRSA6Ci0gICAgICAgICAgICByZXRPYmogPSBmQXR0cmlidXRlVHJhdmVyc2VyLnRyYXZlcnNlR2xvYmFsKGRlY2wsIHNjaGVtYURvYywgZ3JhbW1hcik7Ci0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBFTEVNRU5UX1RZUEUgOgotICAgICAgICAgICAgcmV0T2JqID0gZkVsZW1lbnRUcmF2ZXJzZXIudHJhdmVyc2VHbG9iYWwoZGVjbCwgc2NoZW1hRG9jLCBncmFtbWFyKTsKLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICBjYXNlIEFUVFJJQlVURUdST1VQX1RZUEUgOgotICAgICAgICAgICAgcmV0T2JqID0gZkF0dHJpYnV0ZUdyb3VwVHJhdmVyc2VyLnRyYXZlcnNlR2xvYmFsKGRlY2wsIHNjaGVtYURvYywgZ3JhbW1hcik7Ci0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBHUk9VUF9UWVBFIDoKLSAgICAgICAgICAgIHJldE9iaiA9IGZHcm91cFRyYXZlcnNlci50cmF2ZXJzZUdsb2JhbChkZWNsLCBzY2hlbWFEb2MsIGdyYW1tYXIpOwotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgTk9UQVRJT05fVFlQRSA6Ci0gICAgICAgICAgICByZXRPYmogPSBmTm90YXRpb25UcmF2ZXJzZXIudHJhdmVyc2UoZGVjbCwgc2NoZW1hRG9jLCBncmFtbWFyKTsKLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICBjYXNlIElERU5USVRZQ09OU1RSQUlOVF9UWVBFIDoKLSAgICAgICAgICAgIC8vIGlkZW50aXR5IGNvbnN0cmFpbnRzIHNob3VsZCBoYXZlIGJlZW4gcGFyc2VkIGFscmVhZHkuLi4KLSAgICAgICAgICAgIC8vIHdlIHNob3VsZCBuZXZlciBnZXQgaGVyZQotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyByZXN0b3JlIHRoZSBwcmV2aW91cyBTY2hlbWFOYW1lc3BhY2VTdXBwb3J0LCBzbyB0aGF0IHRoZSBjYWxsZXIgY2FuIGdldAotICAgICAgICAvLyBwcm9wZXIgbmFtZXNwYWNlIGJpbmRpbmcuCi0gICAgICAgIHNjaGVtYURvYy5yZXN0b3JlTlNTdXBwb3J0KCk7Ci0KLSAgICAgICAgcmV0dXJuIHJldE9iajsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIHNjaGVtYURvY3VtZW50MlN5c3RlbUlkKFhTRG9jdW1lbnRJbmZvIHNjaGVtYURvYykgewotICAgICAgICByZXR1cm4gZkRvYzJTeXN0ZW1JZC5nZXQoc2NoZW1hRG9jLmZTY2hlbWFFbGVtZW50KTsKLSAgICB9Ci0KLSAgICAvLyBUaGlzIG1ldGhvZCBkZXRlcm1pbmVzIHdoZXRoZXIgdGhlcmUgaXMgYSBncm91cAotICAgIC8vIChhdHRyaWJ1dGVHcm91cCkgd2hpY2ggdGhlIGdpdmVuIG9uZSBoYXMgcmVkZWZpbmVkIGJ5Ci0gICAgLy8gcmVzdHJpY3Rpb24uICBJZiBzbywgaXQgcmV0dXJucyBpdDsgZWxzZSBpdCByZXR1cm5zIG51bGwuCi0gICAgLy8gQHBhcmFtIHR5cGU6ICB3aGV0aGVyIHdoYXQncyBiZWVuIHJlZGVmaW5lZCBpcyBhbgotICAgIC8vIGF0dHJpYnV0ZUdyb3VwIG9yIGEgZ3JvdXA7Ci0gICAgLy8gQHBhcmFtIG5hbWU6ICB0aGUgUU5hbWUgb2YgdGhlIGNvbXBvbmVudCBkb2luZyB0aGUgcmVkZWZpbmluZy4KLSAgICAvLyBAcGFyYW0gY3VyclNjaGVtYTogIHNjaGVtYSBkb2MgaW4gd2hpY2ggdGhlIHJlZGVmaW5pbmcgY29tcG9uZW50IGxpdmVzLgotICAgIC8vIEByZXR1cm46ICBPYmplY3QgcmVwcmVzZW50aW5nIGRlY2wgcmVkZWZpbmVkIGlmIHByZXNlbnQsIG51bGwKLSAgICAvLyBvdGhlcndpc2UuCi0gICAgT2JqZWN0IGdldEdycE9yQXR0ckdycFJlZGVmaW5lZEJ5UmVzdHJpY3Rpb24oaW50IHR5cGUsIFFOYW1lIG5hbWUsIFhTRG9jdW1lbnRJbmZvIGN1cnJTY2hlbWEsIEVsZW1lbnQgZWxtTm9kZSkgewotICAgICAgICBTdHJpbmcgcmVhbE5hbWUgPSBuYW1lLnVyaSAhPSBudWxsP25hbWUudXJpKyIsIituYW1lLmxvY2FscGFydDoKLSAgICAgICAgICAgICIsIituYW1lLmxvY2FscGFydDsKLSAgICAgICAgU3RyaW5nIG5hbWVUb0ZpbmQgPSBudWxsOwotICAgICAgICBzd2l0Y2ggKHR5cGUpIHsKLSAgICAgICAgY2FzZSBBVFRSSUJVVEVHUk9VUF9UWVBFOgotICAgICAgICAgICAgbmFtZVRvRmluZCA9IChTdHJpbmcpZlJlZGVmaW5lZFJlc3RyaWN0ZWRBdHRyaWJ1dGVHcm91cFJlZ2lzdHJ5LmdldChyZWFsTmFtZSk7Ci0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBHUk9VUF9UWVBFOgotICAgICAgICAgICAgbmFtZVRvRmluZCA9IChTdHJpbmcpZlJlZGVmaW5lZFJlc3RyaWN0ZWRHcm91cFJlZ2lzdHJ5LmdldChyZWFsTmFtZSk7Ci0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgZGVmYXVsdDoKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgICAgIGlmIChuYW1lVG9GaW5kID09IG51bGwpIHJldHVybiBudWxsOwotICAgICAgICBpbnQgY29tbWFQb3MgPSBuYW1lVG9GaW5kLmluZGV4T2YoIiwiKTsKLSAgICAgICAgUU5hbWUgcU5hbWVUb0ZpbmQgPSBuZXcgUU5hbWUoWE1MU3ltYm9scy5FTVBUWV9TVFJJTkcsIG5hbWVUb0ZpbmQuc3Vic3RyaW5nKGNvbW1hUG9zKzEpLAotICAgICAgICAgICAgICAgIG5hbWVUb0ZpbmQuc3Vic3RyaW5nKGNvbW1hUG9zKSwgKGNvbW1hUG9zID09IDApPyBudWxsIDogbmFtZVRvRmluZC5zdWJzdHJpbmcoMCwgY29tbWFQb3MpKTsKLSAgICAgICAgT2JqZWN0IHJldE9iaiA9IGdldEdsb2JhbERlY2woY3VyclNjaGVtYSwgdHlwZSwgcU5hbWVUb0ZpbmQsIGVsbU5vZGUpOwotICAgICAgICBpZihyZXRPYmogPT0gbnVsbCkgewotICAgICAgICAgICAgc3dpdGNoICh0eXBlKSB7Ci0gICAgICAgICAgICBjYXNlIEFUVFJJQlVURUdST1VQX1RZUEU6Ci0gICAgICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoInNyYy1yZWRlZmluZS43LjIuMSIsIG5ldyBPYmplY3QgW117bmFtZS5sb2NhbHBhcnR9LCBlbG1Ob2RlKTsKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIGNhc2UgR1JPVVBfVFlQRToKLSAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcigic3JjLXJlZGVmaW5lLjYuMi4xIiwgbmV3IE9iamVjdCBbXXtuYW1lLmxvY2FscGFydH0sIGVsbU5vZGUpOwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHJldE9iajsKLSAgICB9IC8vIGdldEdycE9yQXR0ckdycFJlZGVmaW5lZEJ5UmVzdHJpY3Rpb24oaW50LCBRTmFtZSwgWFNEb2N1bWVudEluZm8pOiAgT2JqZWN0Ci0KLSAgICAvLyBTaW5jZSBJRCBjb25zdHJhaW50cyBjYW4gb2NjdXIgaW4gbG9jYWwgZWxlbWVudHMsIHVubGVzcyB3ZQotICAgIC8vIHdpc2ggdG8gY29tcGxldGVseSB0cmF2ZXJzZSBhbGwgb3VyIERPTSB0cmVlcyBsb29raW5nIGZvciBJRAotICAgIC8vIGNvbnN0cmFpbnRzIHdoaWxlIHdlJ3JlIGJ1aWxkaW5nIG91ciBnbG9iYWwgbmFtZSByZWdpc3RyaWVzLAotICAgIC8vIHdoaWNoIHNlZW1zIHRlcnJpYmx5IGluZWZmaWNpZW50LCB3ZSBuZWVkIHRvIHJlc29sdmUga2V5cmVmcwotICAgIC8vIGFmdGVyIGFsbCBwYXJzaW5nIGlzIGNvbXBsZXRlLiAgVGhpcyB3ZSBjYW4gc2ltcGx5IGRvIGJ5IHJ1bm5pbmcgdGhyb3VnaAotICAgIC8vIGZJZGVudGl0eUNvbnN0cmFpbnRSZWdpc3RyeSBhbmQgY2FsbGluZyB0cmF2ZXJzZUtleVJlZiBvbiBhbGwKLSAgICAvLyBvZiB0aGUgS2V5UmVmIG5vZGVzLiAgVGhpcyB1bmZvcnR1bmF0ZWx5IHJlbW92ZXMgdGhpcyBrbm93bGVkZ2UKLSAgICAvLyBmcm9tIHRoZSBlbGVtZW50VHJhdmVyc2VyIGNsYXNzICh3aGljaCBtdXN0IGlnbm9yZSBrZXlyZWZzKSwKLSAgICAvLyBidXQgdGhlcmUgc2VlbXMgdG8gYmUgbm8gZWZmaWNpZW50IHdheSBhcm91bmQgdGhpcy4uLgotICAgIHByb3RlY3RlZCB2b2lkIHJlc29sdmVLZXlSZWZzKCkgewotICAgICAgICBmb3IgKGludCBpPTA7IGk8ZktleXJlZlN0YWNrUG9zOyBpKyspIHsKLSAgICAgICAgICAgIFhTRG9jdW1lbnRJbmZvIGtleXJlZlNjaGVtYURvYyA9IGZLZXlyZWZzTWFwWFNEb2N1bWVudEluZm9baV07Ci0gICAgICAgICAgICBrZXlyZWZTY2hlbWFEb2MuZk5hbWVzcGFjZVN1cHBvcnQubWFrZUdsb2JhbCgpOwotICAgICAgICAgICAga2V5cmVmU2NoZW1hRG9jLmZOYW1lc3BhY2VTdXBwb3J0LnNldEVmZmVjdGl2ZUNvbnRleHQoIGZLZXlyZWZOYW1lc3BhY2VDb250ZXh0W2ldICk7Ci0gICAgICAgICAgICBTY2hlbWFHcmFtbWFyIGtleXJlZkdyYW1tYXIgPSBmR3JhbW1hckJ1Y2tldC5nZXRHcmFtbWFyKGtleXJlZlNjaGVtYURvYy5mVGFyZ2V0TmFtZXNwYWNlKTsKLSAgICAgICAgICAgIC8vIG5lZWQgdG8gc2V0IDxrZXlyZWY+IHRvIGhpZGRlbiBiZWZvcmUgdHJhdmVyc2luZyBpdCwKLSAgICAgICAgICAgIC8vIGJlY2F1c2UgaXQgaGFzIGdsb2JhbCBzY29wZQotICAgICAgICAgICAgICAgIERPTVV0aWwuc2V0SGlkZGVuKGZLZXlyZWZzW2ldLCBmSGlkZGVuTm9kZXMpOwotICAgICAgICAgICAgZktleXJlZlRyYXZlcnNlci50cmF2ZXJzZShmS2V5cmVmc1tpXSwgZktleXJlZkVsZW1zW2ldLCBrZXlyZWZTY2hlbWFEb2MsIGtleXJlZkdyYW1tYXIpOwotICAgICAgICB9Ci0gICAgfSAvLyBlbmQgcmVzb2x2ZUtleVJlZnMKLQotICAgIC8vIGFuIGFjY2Vzc29yIG1ldGhvZC4gIEp1c3QgbWFrZXMgc3VyZSBjYWxsZXJzCi0gICAgLy8gd2hvIHdhbnQgdGhlIElkZW50aXR5IGNvbnN0cmFpbnQgcmVnaXN0cnkgdmFndWVseSBrbm93IHdoYXQgdGhleSdyZSBhYm91dC4KLSAgICBwcm90ZWN0ZWQgTWFwIGdldElEUmVnaXN0cnkoKSB7Ci0gICAgICAgIHJldHVybiBmVW5wYXJzZWRJZGVudGl0eUNvbnN0cmFpbnRSZWdpc3RyeTsKLSAgICB9Ci0gICAgLy8gYW4gYWNjZXNzb3IgbWV0aG9kLgotICAgIHByb3RlY3RlZCBNYXAgZ2V0SURSZWdpc3RyeV9zdWIoKSB7Ci0gICAgICAgIHJldHVybiBmVW5wYXJzZWRJZGVudGl0eUNvbnN0cmFpbnRSZWdpc3RyeVN1YjsKLSAgICB9Ci0KLQotCi0gICAgLy8gVGhpcyBtZXRob2Qgc3F1aXJyZWxzIGF3YXkgPGtleXJlZj4gZGVjbGFyYXRpb25zLS1hbG9uZyB3aXRoIHRoZSBlbGVtZW50Ci0gICAgLy8gZGVjbHMgYW5kIG5hbWVzcGFjZSBiaW5kaW5ncyB0aGV5IG1pZ2h0IGZpbmQgaGFuZHkuCi0gICAgcHJvdGVjdGVkIHZvaWQgc3RvcmVLZXlSZWYgKEVsZW1lbnQga2V5cmVmVG9TdG9yZSwgWFNEb2N1bWVudEluZm8gc2NoZW1hRG9jLAotICAgICAgICAgICAgWFNFbGVtZW50RGVjbCBjdXJyRWxlbURlY2wpIHsKLSAgICAgICAgU3RyaW5nIGtleXJlZk5hbWUgPSBET01VdGlsLmdldEF0dHJWYWx1ZShrZXlyZWZUb1N0b3JlLCBTY2hlbWFTeW1ib2xzLkFUVF9OQU1FKTsKLSAgICAgICAgaWYgKGtleXJlZk5hbWUubGVuZ3RoKCkgIT0gMCkgewotICAgICAgICAgICAgU3RyaW5nIGtleXJlZlFOYW1lID0gc2NoZW1hRG9jLmZUYXJnZXROYW1lc3BhY2UgPT0gbnVsbD8KLSAgICAgICAgICAgICAgICAgICAgIiwiICsga2V5cmVmTmFtZTogc2NoZW1hRG9jLmZUYXJnZXROYW1lc3BhY2UrIiwiK2tleXJlZk5hbWU7Ci0gICAgICAgICAgICBjaGVja0ZvckR1cGxpY2F0ZU5hbWVzKGtleXJlZlFOYW1lLCBJREVOVElUWUNPTlNUUkFJTlRfVFlQRSwgZlVucGFyc2VkSWRlbnRpdHlDb25zdHJhaW50UmVnaXN0cnksIGZVbnBhcnNlZElkZW50aXR5Q29uc3RyYWludFJlZ2lzdHJ5U3ViLCBrZXlyZWZUb1N0b3JlLCBzY2hlbWFEb2MpOwotICAgICAgICB9Ci0gICAgICAgIC8vIG5vdyBzZXQgdXAgYWxsIHRoZSByZWdpc3RyaWVzIHdlJ2xsIG5lZWQuLi4KLQotICAgICAgICAvLyBjaGVjayBhcnJheSBzaXplcwotICAgICAgICBpZiAoZktleXJlZlN0YWNrUG9zID09IGZLZXlyZWZzLmxlbmd0aCkgewotICAgICAgICAgICAgRWxlbWVudCBbXSBlbGVtQXJyYXkgPSBuZXcgRWxlbWVudCBbZktleXJlZlN0YWNrUG9zICsgSU5DX0tFWVJFRl9TVEFDS19BTU9VTlRdOwotICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShmS2V5cmVmcywgMCwgZWxlbUFycmF5LCAwLCBmS2V5cmVmU3RhY2tQb3MpOwotICAgICAgICAgICAgZktleXJlZnMgPSBlbGVtQXJyYXk7Ci0gICAgICAgICAgICBYU0VsZW1lbnREZWNsIFtdIGRlY2xBcnJheSA9IG5ldyBYU0VsZW1lbnREZWNsIFtmS2V5cmVmU3RhY2tQb3MgKyBJTkNfS0VZUkVGX1NUQUNLX0FNT1VOVF07Ci0gICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGZLZXlyZWZFbGVtcywgMCwgZGVjbEFycmF5LCAwLCBmS2V5cmVmU3RhY2tQb3MpOwotICAgICAgICAgICAgZktleXJlZkVsZW1zID0gZGVjbEFycmF5OwotICAgICAgICAgICAgU3RyaW5nW11bXSBzdHJpbmdBcnJheSA9IG5ldyBTdHJpbmcgW2ZLZXlyZWZTdGFja1BvcyArIElOQ19LRVlSRUZfU1RBQ0tfQU1PVU5UXVtdOwotICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShmS2V5cmVmTmFtZXNwYWNlQ29udGV4dCwgMCwgc3RyaW5nQXJyYXksIDAsIGZLZXlyZWZTdGFja1Bvcyk7Ci0gICAgICAgICAgICBmS2V5cmVmTmFtZXNwYWNlQ29udGV4dCA9IHN0cmluZ0FycmF5OwotCi0gICAgICAgICAgICBYU0RvY3VtZW50SW5mbyBbXSB4c0RvY3VtZW50SW5mbyA9IG5ldyBYU0RvY3VtZW50SW5mbyBbZktleXJlZlN0YWNrUG9zICsgSU5DX0tFWVJFRl9TVEFDS19BTU9VTlRdOwotICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShmS2V5cmVmc01hcFhTRG9jdW1lbnRJbmZvLCAwLCB4c0RvY3VtZW50SW5mbywgMCwgZktleXJlZlN0YWNrUG9zKTsKLSAgICAgICAgICAgIGZLZXlyZWZzTWFwWFNEb2N1bWVudEluZm8gPSB4c0RvY3VtZW50SW5mbzsKLQotICAgICAgICB9Ci0gICAgICAgIGZLZXlyZWZzW2ZLZXlyZWZTdGFja1Bvc10gPSBrZXlyZWZUb1N0b3JlOwotICAgICAgICBmS2V5cmVmRWxlbXNbZktleXJlZlN0YWNrUG9zXSA9IGN1cnJFbGVtRGVjbDsKLSAgICAgICAgZktleXJlZk5hbWVzcGFjZUNvbnRleHRbZktleXJlZlN0YWNrUG9zXSA9IHNjaGVtYURvYy5mTmFtZXNwYWNlU3VwcG9ydC5nZXRFZmZlY3RpdmVMb2NhbENvbnRleHQoKTsKLQotICAgICAgICBmS2V5cmVmc01hcFhTRG9jdW1lbnRJbmZvW2ZLZXlyZWZTdGFja1BvcysrXSA9IHNjaGVtYURvYzsKLSAgICB9IC8vIHN0b3JlS2V5cmVmIChFbGVtZW50LCBYU0RvY3VtZW50SW5mbywgWFNFbGVtZW50RGVjbCk6IHZvaWQKLQotCi0gICAgLyoqCi0gICAgICogcmVzb2x2ZVNjaGVtYSBtZXRob2QgaXMgcmVzcG9uc2libGUgZm9yIHJlc29sdmluZyBsb2NhdGlvbiBvZiB0aGUgc2NoZW1hICh1c2luZyBYTUxFbnRpdHlSZXNvbHZlciksCi0gICAgICogYW5kIGlmIGl0IHdhcyBzdWNjZWZ1bGx5IHJlc29sdmVkIGdldHRpbmcgdGhlIHNjaGVtYSBEb2N1bWVudC4KLSAgICAgKiBAcGFyYW0gZGVzYwotICAgICAqIEBwYXJhbSBtdXN0UmVzb2x2ZQotICAgICAqIEBwYXJhbSByZWZlckVsZW1lbnQKLSAgICAgKiBAcmV0dXJuIEEgc2NoZW1hIEVsZW1lbnQgb3IgbnVsbC4KLSAgICAgKi8KLSAgICBwcml2YXRlIEVsZW1lbnQgcmVzb2x2ZVNjaGVtYShYU0REZXNjcmlwdGlvbiBkZXNjLCBib29sZWFuIG11c3RSZXNvbHZlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVsZW1lbnQgcmVmZXJFbGVtZW50LCBib29sZWFuIHVzZVBhaXJzKSB7Ci0gICAgICAgIFhNTElucHV0U291cmNlIHNjaGVtYVNvdXJjZSA9IG51bGw7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBNYXA8U3RyaW5nLCBYTUxTY2hlbWFMb2FkZXIuTG9jYXRpb25BcnJheT4gcGFpcnMgPSB1c2VQYWlycyA/IGZMb2NhdGlvblBhaXJzIDogQ29sbGVjdGlvbnMuZW1wdHlNYXAoKTsKLSAgICAgICAgICAgIHNjaGVtYVNvdXJjZSA9IFhNTFNjaGVtYUxvYWRlci5yZXNvbHZlRG9jdW1lbnQoZGVzYywgcGFpcnMsIGZFbnRpdHlNYW5hZ2VyKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKLSAgICAgICAgICAgIGlmIChtdXN0UmVzb2x2ZSkgewotICAgICAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKCJzY2hlbWFfcmVmZXJlbmNlLjQiLAotICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde2Rlc2MuZ2V0TG9jYXRpb25IaW50cygpWzBdfSwKLSAgICAgICAgICAgICAgICAgICAgICAgIHJlZmVyRWxlbWVudCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFXYXJuaW5nKCJzY2hlbWFfcmVmZXJlbmNlLjQiLAotICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde2Rlc2MuZ2V0TG9jYXRpb25IaW50cygpWzBdfSwKLSAgICAgICAgICAgICAgICAgICAgICAgIHJlZmVyRWxlbWVudCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKHNjaGVtYVNvdXJjZSBpbnN0YW5jZW9mIERPTUlucHV0U291cmNlKSB7Ci0gICAgICAgICAgICByZXR1cm4gZ2V0U2NoZW1hRG9jdW1lbnQoZGVzYy5nZXRUYXJnZXROYW1lc3BhY2UoKSwgKERPTUlucHV0U291cmNlKSBzY2hlbWFTb3VyY2UsIG11c3RSZXNvbHZlLCBkZXNjLmdldENvbnRleHRUeXBlKCksIHJlZmVyRWxlbWVudCk7Ci0gICAgICAgIH0gLy8gRE9NSW5wdXRTb3VyY2UKLSAgICAgICAgZWxzZSBpZiAoc2NoZW1hU291cmNlIGluc3RhbmNlb2YgU0FYSW5wdXRTb3VyY2UpIHsKLSAgICAgICAgICAgIHJldHVybiBnZXRTY2hlbWFEb2N1bWVudChkZXNjLmdldFRhcmdldE5hbWVzcGFjZSgpLCAoU0FYSW5wdXRTb3VyY2UpIHNjaGVtYVNvdXJjZSwgbXVzdFJlc29sdmUsIGRlc2MuZ2V0Q29udGV4dFR5cGUoKSwgcmVmZXJFbGVtZW50KTsKLSAgICAgICAgfSAvLyBTQVhJbnB1dFNvdXJjZQotICAgICAgICBlbHNlIGlmIChzY2hlbWFTb3VyY2UgaW5zdGFuY2VvZiBTdEFYSW5wdXRTb3VyY2UpIHsKLSAgICAgICAgICAgIHJldHVybiBnZXRTY2hlbWFEb2N1bWVudChkZXNjLmdldFRhcmdldE5hbWVzcGFjZSgpLCAoU3RBWElucHV0U291cmNlKSBzY2hlbWFTb3VyY2UsIG11c3RSZXNvbHZlLCBkZXNjLmdldENvbnRleHRUeXBlKCksIHJlZmVyRWxlbWVudCk7Ci0gICAgICAgIH0gLy8gU3RBWElucHV0U291cmNlCi0gICAgICAgIGVsc2UgaWYgKHNjaGVtYVNvdXJjZSBpbnN0YW5jZW9mIFhTSW5wdXRTb3VyY2UpIHsKLSAgICAgICAgICAgIHJldHVybiBnZXRTY2hlbWFEb2N1bWVudCgoWFNJbnB1dFNvdXJjZSkgc2NoZW1hU291cmNlLCBkZXNjKTsKLSAgICAgICAgfSAvLyBYU0lucHV0U291cmNlCi0gICAgICAgIHJldHVybiBnZXRTY2hlbWFEb2N1bWVudChkZXNjLmdldFRhcmdldE5hbWVzcGFjZSgpLCBzY2hlbWFTb3VyY2UsIG11c3RSZXNvbHZlLCBkZXNjLmdldENvbnRleHRUeXBlKCksIHJlZmVyRWxlbWVudCk7Ci0gICAgfSAvLyBnZXRTY2hlbWEoU3RyaW5nLCBTdHJpbmcsIFN0cmluZywgYm9vbGVhbiwgc2hvcnQpOiAgRG9jdW1lbnQKLQotICAgIHByaXZhdGUgRWxlbWVudCByZXNvbHZlU2NoZW1hKFhNTElucHV0U291cmNlIHNjaGVtYVNvdXJjZSwgWFNERGVzY3JpcHRpb24gZGVzYywKLSAgICAgICAgICAgIGJvb2xlYW4gbXVzdFJlc29sdmUsIEVsZW1lbnQgcmVmZXJFbGVtZW50KSB7Ci0KLSAgICAgICAgaWYgKHNjaGVtYVNvdXJjZSBpbnN0YW5jZW9mIERPTUlucHV0U291cmNlKSB7Ci0gICAgICAgICAgICByZXR1cm4gZ2V0U2NoZW1hRG9jdW1lbnQoZGVzYy5nZXRUYXJnZXROYW1lc3BhY2UoKSwgKERPTUlucHV0U291cmNlKSBzY2hlbWFTb3VyY2UsIG11c3RSZXNvbHZlLCBkZXNjLmdldENvbnRleHRUeXBlKCksIHJlZmVyRWxlbWVudCk7Ci0gICAgICAgIH0gLy8gRE9NSW5wdXRTb3VyY2UKLSAgICAgICAgZWxzZSBpZiAoc2NoZW1hU291cmNlIGluc3RhbmNlb2YgU0FYSW5wdXRTb3VyY2UpIHsKLSAgICAgICAgICAgIHJldHVybiBnZXRTY2hlbWFEb2N1bWVudChkZXNjLmdldFRhcmdldE5hbWVzcGFjZSgpLCAoU0FYSW5wdXRTb3VyY2UpIHNjaGVtYVNvdXJjZSwgbXVzdFJlc29sdmUsIGRlc2MuZ2V0Q29udGV4dFR5cGUoKSwgcmVmZXJFbGVtZW50KTsKLSAgICAgICAgfSAvLyBTQVhJbnB1dFNvdXJjZQotICAgICAgICBlbHNlIGlmIChzY2hlbWFTb3VyY2UgaW5zdGFuY2VvZiBTdEFYSW5wdXRTb3VyY2UpIHsKLSAgICAgICAgICAgIHJldHVybiBnZXRTY2hlbWFEb2N1bWVudChkZXNjLmdldFRhcmdldE5hbWVzcGFjZSgpLCAoU3RBWElucHV0U291cmNlKSBzY2hlbWFTb3VyY2UsIG11c3RSZXNvbHZlLCBkZXNjLmdldENvbnRleHRUeXBlKCksIHJlZmVyRWxlbWVudCk7Ci0gICAgICAgIH0gLy8gU3RBWElucHV0U291cmNlCi0gICAgICAgIGVsc2UgaWYgKHNjaGVtYVNvdXJjZSBpbnN0YW5jZW9mIFhTSW5wdXRTb3VyY2UpIHsKLSAgICAgICAgICAgIHJldHVybiBnZXRTY2hlbWFEb2N1bWVudCgoWFNJbnB1dFNvdXJjZSkgc2NoZW1hU291cmNlLCBkZXNjKTsKLSAgICAgICAgfSAvLyBYU0lucHV0U291cmNlCi0gICAgICAgIHJldHVybiBnZXRTY2hlbWFEb2N1bWVudChkZXNjLmdldFRhcmdldE5hbWVzcGFjZSgpLCBzY2hlbWFTb3VyY2UsIG11c3RSZXNvbHZlLCBkZXNjLmdldENvbnRleHRUeXBlKCksIHJlZmVyRWxlbWVudCk7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBYTUxJbnB1dFNvdXJjZSByZXNvbHZlU2NoZW1hU291cmNlKFhTRERlc2NyaXB0aW9uIGRlc2MsIGJvb2xlYW4gbXVzdFJlc29sdmUsCi0gICAgICAgICAgICBFbGVtZW50IHJlZmVyRWxlbWVudCwgYm9vbGVhbiB1c2VQYWlycykgewotCi0gICAgICAgIFhNTElucHV0U291cmNlIHNjaGVtYVNvdXJjZSA9IG51bGw7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBNYXA8U3RyaW5nLCBYTUxTY2hlbWFMb2FkZXIuTG9jYXRpb25BcnJheT4gcGFpcnMgPSB1c2VQYWlycyA/IGZMb2NhdGlvblBhaXJzIDogQ29sbGVjdGlvbnMuZW1wdHlNYXAoKTsKLSAgICAgICAgICAgIHNjaGVtYVNvdXJjZSA9IFhNTFNjaGVtYUxvYWRlci5yZXNvbHZlRG9jdW1lbnQoZGVzYywgcGFpcnMsIGZFbnRpdHlNYW5hZ2VyKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKLSAgICAgICAgICAgIGlmIChtdXN0UmVzb2x2ZSkgewotICAgICAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKCJzY2hlbWFfcmVmZXJlbmNlLjQiLAotICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde2Rlc2MuZ2V0TG9jYXRpb25IaW50cygpWzBdfSwKLSAgICAgICAgICAgICAgICAgICAgICAgIHJlZmVyRWxlbWVudCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFXYXJuaW5nKCJzY2hlbWFfcmVmZXJlbmNlLjQiLAotICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde2Rlc2MuZ2V0TG9jYXRpb25IaW50cygpWzBdfSwKLSAgICAgICAgICAgICAgICAgICAgICAgIHJlZmVyRWxlbWVudCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gc2NoZW1hU291cmNlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIGdldFNjaGVtYURvY3VtZW50IG1ldGhvZCB1c2VzIFhNTElucHV0U291cmNlIHRvIHBhcnNlIGEgc2NoZW1hIGRvY3VtZW50LgotICAgICAqIEBwYXJhbSBzY2hlbWFOYW1lc3BhY2UKLSAgICAgKiBAcGFyYW0gc2NoZW1hU291cmNlCi0gICAgICogQHBhcmFtIG11c3RSZXNvbHZlCi0gICAgICogQHBhcmFtIHJlZmVyVHlwZQotICAgICAqIEBwYXJhbSByZWZlckVsZW1lbnQKLSAgICAgKiBAcmV0dXJuIEEgc2NoZW1hIEVsZW1lbnQuCi0gICAgICovCi0gICAgcHJpdmF0ZSBFbGVtZW50IGdldFNjaGVtYURvY3VtZW50KFN0cmluZyBzY2hlbWFOYW1lc3BhY2UsIFhNTElucHV0U291cmNlIHNjaGVtYVNvdXJjZSwKLSAgICAgICAgICAgIGJvb2xlYW4gbXVzdFJlc29sdmUsIHNob3J0IHJlZmVyVHlwZSwgRWxlbWVudCByZWZlckVsZW1lbnQpIHsKLQotICAgICAgICBib29sZWFuIGhhc0lucHV0ID0gdHJ1ZTsKLSAgICAgICAgSU9FeGNlcHRpb24gZXhjZXB0aW9uID0gbnVsbDsKLSAgICAgICAgLy8gY29udGVudHMgb2YgdGhpcyBtZXRob2Qgd2lsbCBkZXBlbmQgb24gdGhlIHN5c3RlbSB3ZSBhZG9wdCBmb3IgZW50aXR5IHJlc29sdXRpb24tLWkuZS4sIFhNTEVudGl0eUhhbmRsZXIsIEVudGl0eUhhbmRsZXIsIGV0Yy4KLSAgICAgICAgRWxlbWVudCBzY2hlbWFFbGVtZW50ID0gbnVsbDsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIC8vIHdoZW4gdGhlIHN5c3RlbSBpZCBhbmQgYnl0ZSBzdHJlYW0gYW5kIGNoYXJhY3RlciBzdHJlYW0KLSAgICAgICAgICAgIC8vIG9mIHRoZSBpbnB1dCBzb3VyY2UgYXJlIGFsbCBudWxsLCBpdCdzCi0gICAgICAgICAgICAvLyBpbXBvc3NpYmxlIHRvIGZpbmQgdGhlIHNjaGVtYSBkb2N1bWVudC4gc28gd2Ugc2tpcCBpbgotICAgICAgICAgICAgLy8gdGhpcyBjYXNlLiBvdGhlcndpc2Ugd2UnbGwgcmVjZWl2ZSBzb21lIE5QRSBvcgotICAgICAgICAgICAgLy8gZmlsZSBub3QgZm91bmQgZXJyb3JzLiBidXQgc2NoZW1hSGludD09IiIgaXMgcGVyZmVjdGx5Ci0gICAgICAgICAgICAvLyBsZWdhbCBmb3IgaW1wb3J0LgotICAgICAgICAgICAgaWYgKHNjaGVtYVNvdXJjZSAhPSBudWxsICYmCi0gICAgICAgICAgICAgICAgICAgIChzY2hlbWFTb3VyY2UuZ2V0U3lzdGVtSWQoKSAhPSBudWxsIHx8Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NoZW1hU291cmNlLmdldEJ5dGVTdHJlYW0oKSAhPSBudWxsIHx8Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NoZW1hU291cmNlLmdldENoYXJhY3RlclN0cmVhbSgpICE9IG51bGwpKSB7Ci0KLSAgICAgICAgICAgICAgICAvLyBXaGVuIHRoZSBzeXN0ZW0gaWQgb2YgdGhlIGlucHV0IHNvdXJjZSBpcyB1c2VkLCBmaXJzdCB0cnkgdG8KLSAgICAgICAgICAgICAgICAvLyBleHBhbmQgaXQsIGFuZCBjaGVjayB3aGV0aGVyIHRoZSBzYW1lIGRvY3VtZW50IGhhcyBiZWVuCi0gICAgICAgICAgICAgICAgLy8gcGFyc2VkIGJlZm9yZS4gSWYgc28sIHJldHVybiB0aGUgZG9jdW1lbnQgY29ycmVzcG9uZGluZyB0bwotICAgICAgICAgICAgICAgIC8vIHRoYXQgc3lzdGVtIGlkLgotICAgICAgICAgICAgICAgIFhTREtleSBrZXkgPSBudWxsOwotICAgICAgICAgICAgICAgIFN0cmluZyBzY2hlbWFJZCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgaWYgKHJlZmVyVHlwZSAhPSBYU0REZXNjcmlwdGlvbi5DT05URVhUX1BSRVBBUlNFKXsKLSAgICAgICAgICAgICAgICAgICAgc2NoZW1hSWQgPSBYTUxFbnRpdHlNYW5hZ2VyLmV4cGFuZFN5c3RlbUlkKHNjaGVtYVNvdXJjZS5nZXRTeXN0ZW1JZCgpLCBzY2hlbWFTb3VyY2UuZ2V0QmFzZVN5c3RlbUlkKCksIGZhbHNlKTsKLSAgICAgICAgICAgICAgICAgICAga2V5ID0gbmV3IFhTREtleShzY2hlbWFJZCwgcmVmZXJUeXBlLCBzY2hlbWFOYW1lc3BhY2UpOwotICAgICAgICAgICAgICAgICAgICBpZigoc2NoZW1hRWxlbWVudCA9IGZUcmF2ZXJzZWQuZ2V0KGtleSkpICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZMYXN0U2NoZW1hV2FzRHVwbGljYXRlID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzY2hlbWFFbGVtZW50OwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGlmIChyZWZlclR5cGUgPT0gWFNERGVzY3JpcHRpb24uQ09OVEVYVF9JTVBPUlQgfHwgcmVmZXJUeXBlID09IFhTRERlc2NyaXB0aW9uLkNPTlRFWFRfSU5DTFVERQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IHJlZmVyVHlwZSA9PSBYU0REZXNjcmlwdGlvbi5DT05URVhUX1JFREVGSU5FKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgYWNjZXNzRXJyb3IgPSBTZWN1cml0eVN1cHBvcnQuY2hlY2tBY2Nlc3Moc2NoZW1hSWQsIGZBY2Nlc3NFeHRlcm5hbFNjaGVtYSwgQ29uc3RhbnRzLkFDQ0VTU19FWFRFUk5BTF9BTEwpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFjY2Vzc0Vycm9yICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFGYXRhbEVycm9yKCJzY2hlbWFfcmVmZXJlbmNlLmFjY2VzcyIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBTZWN1cml0eVN1cHBvcnQuc2FuaXRpemVQYXRoKHNjaGVtYUlkKSwgYWNjZXNzRXJyb3IgfSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZmVyRWxlbWVudCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBmU2NoZW1hUGFyc2VyLnBhcnNlKHNjaGVtYVNvdXJjZSk7Ci0gICAgICAgICAgICAgICAgRG9jdW1lbnQgc2NoZW1hRG9jdW1lbnQgPSBmU2NoZW1hUGFyc2VyLmdldERvY3VtZW50KCk7Ci0gICAgICAgICAgICAgICAgc2NoZW1hRWxlbWVudCA9IHNjaGVtYURvY3VtZW50ICE9IG51bGwgPyBET01VdGlsLmdldFJvb3Qoc2NoZW1hRG9jdW1lbnQpIDogbnVsbDsKLSAgICAgICAgICAgICAgICByZXR1cm4gZ2V0U2NoZW1hRG9jdW1lbnQwKGtleSwgc2NoZW1hSWQsIHNjaGVtYUVsZW1lbnQpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgaGFzSW5wdXQgPSBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKLSAgICAgICAgICAgIGV4Y2VwdGlvbiA9IGV4OwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBnZXRTY2hlbWFEb2N1bWVudDEobXVzdFJlc29sdmUsIGhhc0lucHV0LCBzY2hlbWFTb3VyY2UsIHJlZmVyRWxlbWVudCwgZXhjZXB0aW9uKTsKLSAgICB9IC8vIGdldFNjaGVtYURvY3VtZW50KFN0cmluZywgWE1MSW5wdXRTb3VyY2UsIGJvb2xlYW4sIHNob3J0LCBFbGVtZW50KTogRWxlbWVudAotCi0gICAgLyoqCi0gICAgICogZ2V0U2NoZW1hRG9jdW1lbnQgbWV0aG9kIHVzZXMgU0FYSW5wdXRTb3VyY2UgdG8gcGFyc2UgYSBzY2hlbWEgZG9jdW1lbnQuCi0gICAgICogQHBhcmFtIHNjaGVtYU5hbWVzcGFjZQotICAgICAqIEBwYXJhbSBzY2hlbWFTb3VyY2UKLSAgICAgKiBAcGFyYW0gbXVzdFJlc29sdmUKLSAgICAgKiBAcGFyYW0gcmVmZXJUeXBlCi0gICAgICogQHBhcmFtIHJlZmVyRWxlbWVudAotICAgICAqIEByZXR1cm4gQSBzY2hlbWEgRWxlbWVudC4KLSAgICAgKi8KLSAgICBwcml2YXRlIEVsZW1lbnQgZ2V0U2NoZW1hRG9jdW1lbnQoU3RyaW5nIHNjaGVtYU5hbWVzcGFjZSwgU0FYSW5wdXRTb3VyY2Ugc2NoZW1hU291cmNlLAotICAgICAgICAgICAgYm9vbGVhbiBtdXN0UmVzb2x2ZSwgc2hvcnQgcmVmZXJUeXBlLCBFbGVtZW50IHJlZmVyRWxlbWVudCkgewotICAgICAgICBYTUxSZWFkZXIgcGFyc2VyID0gc2NoZW1hU291cmNlLmdldFhNTFJlYWRlcigpOwotICAgICAgICBJbnB1dFNvdXJjZSBpbnB1dFNvdXJjZSA9IHNjaGVtYVNvdXJjZS5nZXRJbnB1dFNvdXJjZSgpOwotICAgICAgICBib29sZWFuIGhhc0lucHV0ID0gdHJ1ZTsKLSAgICAgICAgSU9FeGNlcHRpb24gZXhjZXB0aW9uID0gbnVsbDsKLSAgICAgICAgRWxlbWVudCBzY2hlbWFFbGVtZW50ID0gbnVsbDsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGlmIChpbnB1dFNvdXJjZSAhPSBudWxsICYmCi0gICAgICAgICAgICAgICAgICAgIChpbnB1dFNvdXJjZS5nZXRTeXN0ZW1JZCgpICE9IG51bGwgfHwKLSAgICAgICAgICAgICAgICAgICAgIGlucHV0U291cmNlLmdldEJ5dGVTdHJlYW0oKSAhPSBudWxsIHx8Ci0gICAgICAgICAgICAgICAgICAgICBpbnB1dFNvdXJjZS5nZXRDaGFyYWN0ZXJTdHJlYW0oKSAhPSBudWxsKSkgewotCi0gICAgICAgICAgICAgICAgLy8gY2hlY2sgd2hldGhlciB0aGUgc2FtZSBkb2N1bWVudCBoYXMgYmVlbiBwYXJzZWQgYmVmb3JlLgotICAgICAgICAgICAgICAgIC8vIElmIHNvLCByZXR1cm4gdGhlIGRvY3VtZW50IGNvcnJlc3BvbmRpbmcgdG8gdGhhdCBzeXN0ZW0gaWQuCi0gICAgICAgICAgICAgICAgWFNES2V5IGtleSA9IG51bGw7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIHNjaGVtYUlkID0gbnVsbDsKLSAgICAgICAgICAgICAgICBpZiAocmVmZXJUeXBlICE9IFhTRERlc2NyaXB0aW9uLkNPTlRFWFRfUFJFUEFSU0UpIHsKLSAgICAgICAgICAgICAgICAgICAgc2NoZW1hSWQgPSBYTUxFbnRpdHlNYW5hZ2VyLmV4cGFuZFN5c3RlbUlkKGlucHV0U291cmNlLmdldFN5c3RlbUlkKCksIHNjaGVtYVNvdXJjZS5nZXRCYXNlU3lzdGVtSWQoKSwgZmFsc2UpOwotICAgICAgICAgICAgICAgICAgICBrZXkgPSBuZXcgWFNES2V5KHNjaGVtYUlkLCByZWZlclR5cGUsIHNjaGVtYU5hbWVzcGFjZSk7Ci0gICAgICAgICAgICAgICAgICAgIGlmICgoc2NoZW1hRWxlbWVudCA9IGZUcmF2ZXJzZWQuZ2V0KGtleSkpICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZMYXN0U2NoZW1hV2FzRHVwbGljYXRlID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzY2hlbWFFbGVtZW50OwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgYm9vbGVhbiBuYW1lc3BhY2VQcmVmaXhlcyA9IGZhbHNlOwotICAgICAgICAgICAgICAgIGlmIChwYXJzZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXNwYWNlUHJlZml4ZXMgPSBwYXJzZXIuZ2V0RmVhdHVyZShOQU1FU1BBQ0VfUFJFRklYRVMpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGNhdGNoIChTQVhFeGNlcHRpb24gc2UpIHt9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2VyID0gWE1MUmVhZGVyRmFjdG9yeS5jcmVhdGVYTUxSZWFkZXIoKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAvLyBJZiBzb21ldGhpbmcgd2VudCB3cm9uZyB3aXRoIHRoZSBmYWN0b3J5Ci0gICAgICAgICAgICAgICAgICAgIC8vIGp1c3QgdXNlIG91ciBvd24gU0FYIHBhcnNlci4KLSAgICAgICAgICAgICAgICAgICAgY2F0Y2ggKFNBWEV4Y2VwdGlvbiBzZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2VyID0gbmV3IFNBWFBhcnNlcigpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBwYXJzZXIuc2V0RmVhdHVyZShOQU1FU1BBQ0VfUFJFRklYRVMsIHRydWUpOwotICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXNwYWNlUHJlZml4ZXMgPSB0cnVlOwotICAgICAgICAgICAgICAgICAgICAgICAgLy8gSWYgdGhpcyBpcyBhIFhlcmNlcyBTQVggcGFyc2VyIHNldCB0aGUgc2VjdXJpdHkgbWFuYWdlciBpZiB0aGVyZSBpcyBvbmUKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYXJzZXIgaW5zdGFuY2VvZiBTQVhQYXJzZXIpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZlNlY3VyaXR5TWFuYWdlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcnNlci5zZXRQcm9wZXJ0eShTRUNVUklUWV9NQU5BR0VSLCBmU2VjdXJpdHlNYW5hZ2VyKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgY2F0Y2ggKFNBWEV4Y2VwdGlvbiBzZSkge30KLQotICAgICAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2VyLnNldFByb3BlcnR5KFhNTENvbnN0YW50cy5BQ0NFU1NfRVhURVJOQUxfRFRELCBmQWNjZXNzRXh0ZXJuYWxEVEQpOwotICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIGV4YykgewotICAgICAgICAgICAgICAgICAgICAgICAgWE1MU2VjdXJpdHlNYW5hZ2VyLnByaW50V2FybmluZyhwYXJzZXIuZ2V0Q2xhc3MoKS5nZXROYW1lKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTENvbnN0YW50cy5BQ0NFU1NfRVhURVJOQUxfRFRELCBleGMpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIC8vIElmIFhNTCBuYW1lcyBhbmQgTmFtZXNwYWNlIFVSSXMgYXJlIGFscmVhZHkgaW50ZXJuYWxpemVkIHdlCi0gICAgICAgICAgICAgICAgLy8gY2FuIGF2b2lkIHJ1bm5pbmcgdGhlbSB0aHJvdWdoIHRoZSBTeW1ib2xUYWJsZS4KLSAgICAgICAgICAgICAgICBib29sZWFuIHN0cmluZ3NJbnRlcm5hbGl6ZWQgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICBzdHJpbmdzSW50ZXJuYWxpemVkID0gcGFyc2VyLmdldEZlYXR1cmUoU1RSSU5HX0lOVEVSTklORyk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGNhdGNoIChTQVhFeGNlcHRpb24gZXhjKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIFRoZSBmZWF0dXJlIGlzbid0IHJlY29nbml6ZWQgb3IgZ2V0dGluZyBpdCBpcyBub3Qgc3VwcG9ydGVkLgotICAgICAgICAgICAgICAgICAgICAvLyBJbiBlaXRoZXIgY2FzZSwgYXNzdW1lIHRoYXQgc3RyaW5ncyBhcmUgbm90IGludGVybmFsaXplZC4KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaWYgKGZYU0NvbnRlbnRIYW5kbGVyID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgZlhTQ29udGVudEhhbmRsZXIgPSBuZXcgU2NoZW1hQ29udGVudEhhbmRsZXIoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZlhTQ29udGVudEhhbmRsZXIucmVzZXQoZlNjaGVtYVBhcnNlciwgZlN5bWJvbFRhYmxlLAotICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXNwYWNlUHJlZml4ZXMsIHN0cmluZ3NJbnRlcm5hbGl6ZWQpOwotICAgICAgICAgICAgICAgIHBhcnNlci5zZXRDb250ZW50SGFuZGxlcihmWFNDb250ZW50SGFuZGxlcik7Ci0gICAgICAgICAgICAgICAgcGFyc2VyLnNldEVycm9ySGFuZGxlcihmRXJyb3JSZXBvcnRlci5nZXRTQVhFcnJvckhhbmRsZXIoKSk7Ci0KLSAgICAgICAgICAgICAgICBwYXJzZXIucGFyc2UoaW5wdXRTb3VyY2UpOwotICAgICAgICAgICAgICAgIC8vIERpc2Nvbm5lY3QgdGhlIHNjaGVtYSBsb2FkZXIgYW5kIG90aGVyIG9iamVjdHMgZnJvbSB0aGUgWE1MUmVhZGVyCi0gICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgcGFyc2VyLnNldENvbnRlbnRIYW5kbGVyKG51bGwpOwotICAgICAgICAgICAgICAgICAgICBwYXJzZXIuc2V0RXJyb3JIYW5kbGVyKG51bGwpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvLyBJZ25vcmUgYW55IGV4Y2VwdGlvbnMgdGhyb3duIGJ5IHRoZSBYTUxSZWFkZXIuIE9sZCB2ZXJzaW9ucyBvZiBTQVgKLSAgICAgICAgICAgICAgICAvLyByZXF1aXJlZCBhbiBYTUxSZWFkZXIgdG8gdGhyb3cgYSBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiBhbiBhdHRlbXB0Ci0gICAgICAgICAgICAgICAgLy8gdG8gc2V0IGEgaGFuZGxlciB0byBudWxsIHdhcyBtYWRlLgotICAgICAgICAgICAgICAgIGNhdGNoIChFeGNlcHRpb24gZSkge30KLQotICAgICAgICAgICAgICAgIERvY3VtZW50IHNjaGVtYURvY3VtZW50ID0gZlhTQ29udGVudEhhbmRsZXIuZ2V0RG9jdW1lbnQoKTsKLSAgICAgICAgICAgICAgICBzY2hlbWFFbGVtZW50ID0gc2NoZW1hRG9jdW1lbnQgIT0gbnVsbCA/IERPTVV0aWwuZ2V0Um9vdChzY2hlbWFEb2N1bWVudCkgOiBudWxsOwotICAgICAgICAgICAgICAgIHJldHVybiBnZXRTY2hlbWFEb2N1bWVudDAoa2V5LCBzY2hlbWFJZCwgc2NoZW1hRWxlbWVudCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBoYXNJbnB1dCA9IGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChTQVhQYXJzZUV4Y2VwdGlvbiBzcGUpIHsKLSAgICAgICAgICAgIHRocm93IFNBWDJYTklVdGlsLmNyZWF0ZVhNTFBhcnNlRXhjZXB0aW9uMChzcGUpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChTQVhFeGNlcHRpb24gc2UpIHsKLSAgICAgICAgICAgIHRocm93IFNBWDJYTklVdGlsLmNyZWF0ZVhOSUV4Y2VwdGlvbjAoc2UpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChJT0V4Y2VwdGlvbiBpb2UpIHsKLSAgICAgICAgICAgIGV4Y2VwdGlvbiA9IGlvZTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZ2V0U2NoZW1hRG9jdW1lbnQxKG11c3RSZXNvbHZlLCBoYXNJbnB1dCwgc2NoZW1hU291cmNlLCByZWZlckVsZW1lbnQsIGV4Y2VwdGlvbik7Ci0gICAgfSAvLyBnZXRTY2hlbWFEb2N1bWVudChTdHJpbmcsIFNBWElucHV0U291cmNlLCBib29sZWFuLCBzaG9ydCwgRWxlbWVudCk6IEVsZW1lbnQKLQotICAgIC8qKgotICAgICAqIGdldFNjaGVtYURvY3VtZW50IG1ldGhvZCB1c2VzIERPTUlucHV0U291cmNlIHRvIHBhcnNlIGEgc2NoZW1hIGRvY3VtZW50LgotICAgICAqIEBwYXJhbSBzY2hlbWFOYW1lc3BhY2UKLSAgICAgKiBAcGFyYW0gc2NoZW1hU291cmNlCi0gICAgICogQHBhcmFtIG11c3RSZXNvbHZlCi0gICAgICogQHBhcmFtIHJlZmVyVHlwZQotICAgICAqIEBwYXJhbSByZWZlckVsZW1lbnQKLSAgICAgKiBAcmV0dXJuIEEgc2NoZW1hIEVsZW1lbnQuCi0gICAgICovCi0gICAgcHJpdmF0ZSBFbGVtZW50IGdldFNjaGVtYURvY3VtZW50KFN0cmluZyBzY2hlbWFOYW1lc3BhY2UsIERPTUlucHV0U291cmNlIHNjaGVtYVNvdXJjZSwKLSAgICAgICAgICAgIGJvb2xlYW4gbXVzdFJlc29sdmUsIHNob3J0IHJlZmVyVHlwZSwgRWxlbWVudCByZWZlckVsZW1lbnQpIHsKLSAgICAgICAgYm9vbGVhbiBoYXNJbnB1dCA9IHRydWU7Ci0gICAgICAgIElPRXhjZXB0aW9uIGV4Y2VwdGlvbiA9IG51bGw7Ci0gICAgICAgIEVsZW1lbnQgc2NoZW1hRWxlbWVudCA9IG51bGw7Ci0gICAgICAgIEVsZW1lbnQgc2NoZW1hUm9vdEVsZW1lbnQgPSBudWxsOwotCi0gICAgICAgIGZpbmFsIE5vZGUgbm9kZSA9IHNjaGVtYVNvdXJjZS5nZXROb2RlKCk7Ci0gICAgICAgIHNob3J0IG5vZGVUeXBlID0gLTE7Ci0gICAgICAgIGlmIChub2RlICE9IG51bGwpIHsKLSAgICAgICAgICAgIG5vZGVUeXBlID0gbm9kZS5nZXROb2RlVHlwZSgpOwotICAgICAgICAgICAgaWYgKG5vZGVUeXBlID09IE5vZGUuRE9DVU1FTlRfTk9ERSkgewotICAgICAgICAgICAgICAgIHNjaGVtYVJvb3RFbGVtZW50ID0gRE9NVXRpbC5nZXRSb290KChEb2N1bWVudCkgbm9kZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChub2RlVHlwZSA9PSBOb2RlLkVMRU1FTlRfTk9ERSkgewotICAgICAgICAgICAgICAgIHNjaGVtYVJvb3RFbGVtZW50ID0gKEVsZW1lbnQpIG5vZGU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICB0cnkgewotICAgICAgICAgICAgaWYgKHNjaGVtYVJvb3RFbGVtZW50ICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAvLyBjaGVjayB3aGV0aGVyIHRoZSBzYW1lIGRvY3VtZW50IGhhcyBiZWVuIHBhcnNlZCBiZWZvcmUuCi0gICAgICAgICAgICAgICAgLy8gSWYgc28sIHJldHVybiB0aGUgZG9jdW1lbnQgY29ycmVzcG9uZGluZyB0byB0aGF0IHN5c3RlbSBpZC4KLSAgICAgICAgICAgICAgICBYU0RLZXkga2V5ID0gbnVsbDsKLSAgICAgICAgICAgICAgICBTdHJpbmcgc2NoZW1hSWQgPSBudWxsOwotICAgICAgICAgICAgICAgIGlmIChyZWZlclR5cGUgIT0gWFNERGVzY3JpcHRpb24uQ09OVEVYVF9QUkVQQVJTRSkgewotICAgICAgICAgICAgICAgICAgICBzY2hlbWFJZCA9IFhNTEVudGl0eU1hbmFnZXIuZXhwYW5kU3lzdGVtSWQoc2NoZW1hU291cmNlLmdldFN5c3RlbUlkKCksIHNjaGVtYVNvdXJjZS5nZXRCYXNlU3lzdGVtSWQoKSwgZmFsc2UpOwotICAgICAgICAgICAgICAgICAgICBib29sZWFuIGlzRG9jdW1lbnQgPSAobm9kZVR5cGUgPT0gTm9kZS5ET0NVTUVOVF9OT0RFKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKCFpc0RvY3VtZW50KSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBOb2RlIHBhcmVudCA9IHNjaGVtYVJvb3RFbGVtZW50LmdldFBhcmVudE5vZGUoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYXJlbnQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzRG9jdW1lbnQgPSAocGFyZW50LmdldE5vZGVUeXBlKCkgPT0gTm9kZS5ET0NVTUVOVF9OT0RFKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBpZiAoaXNEb2N1bWVudCkgewotICAgICAgICAgICAgICAgICAgICAgICAga2V5ID0gbmV3IFhTREtleShzY2hlbWFJZCwgcmVmZXJUeXBlLCBzY2hlbWFOYW1lc3BhY2UpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChzY2hlbWFFbGVtZW50ID0gZlRyYXZlcnNlZC5nZXQoa2V5KSkgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZMYXN0U2NoZW1hV2FzRHVwbGljYXRlID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2NoZW1hRWxlbWVudDsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIHNjaGVtYUVsZW1lbnQgPSBzY2hlbWFSb290RWxlbWVudDsKLSAgICAgICAgICAgICAgICByZXR1cm4gZ2V0U2NoZW1hRG9jdW1lbnQwKGtleSwgc2NoZW1hSWQsIHNjaGVtYUVsZW1lbnQpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgaGFzSW5wdXQgPSBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoSU9FeGNlcHRpb24gaW9lKSB7Ci0gICAgICAgICAgICBleGNlcHRpb24gPSBpb2U7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGdldFNjaGVtYURvY3VtZW50MShtdXN0UmVzb2x2ZSwgaGFzSW5wdXQsIHNjaGVtYVNvdXJjZSwgcmVmZXJFbGVtZW50LCBleGNlcHRpb24pOwotICAgIH0gLy8gZ2V0U2NoZW1hRG9jdW1lbnQoU3RyaW5nLCBET01JbnB1dFNvdXJjZSwgYm9vbGVhbiwgc2hvcnQsIEVsZW1lbnQpOiBFbGVtZW50Ci0KLSAgICAvKioKLSAgICAgKiBnZXRTY2hlbWFEb2N1bWVudCBtZXRob2QgdXNlcyBTdEFYSW5wdXRTb3VyY2UgdG8gcGFyc2UgYSBzY2hlbWEgZG9jdW1lbnQuCi0gICAgICogQHBhcmFtIHNjaGVtYU5hbWVzcGFjZQotICAgICAqIEBwYXJhbSBzY2hlbWFTb3VyY2UKLSAgICAgKiBAcGFyYW0gbXVzdFJlc29sdmUKLSAgICAgKiBAcGFyYW0gcmVmZXJUeXBlCi0gICAgICogQHBhcmFtIHJlZmVyRWxlbWVudAotICAgICAqIEByZXR1cm4gQSBzY2hlbWEgRWxlbWVudC4KLSAgICAgKi8KLSAgICBwcml2YXRlIEVsZW1lbnQgZ2V0U2NoZW1hRG9jdW1lbnQoU3RyaW5nIHNjaGVtYU5hbWVzcGFjZSwgU3RBWElucHV0U291cmNlIHNjaGVtYVNvdXJjZSwKLSAgICAgICAgICAgIGJvb2xlYW4gbXVzdFJlc29sdmUsIHNob3J0IHJlZmVyVHlwZSwgRWxlbWVudCByZWZlckVsZW1lbnQpIHsKLSAgICAgICAgSU9FeGNlcHRpb24gZXhjZXB0aW9uID0gbnVsbDsKLSAgICAgICAgRWxlbWVudCBzY2hlbWFFbGVtZW50ID0gbnVsbDsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGZpbmFsIGJvb2xlYW4gY29uc3VtZVJlbWFpbmluZ0NvbnRlbnQgPSBzY2hlbWFTb3VyY2Uuc2hvdWxkQ29uc3VtZVJlbWFpbmluZ0NvbnRlbnQoKTsKLSAgICAgICAgICAgIGZpbmFsIFhNTFN0cmVhbVJlYWRlciBzdHJlYW1SZWFkZXIgPSBzY2hlbWFTb3VyY2UuZ2V0WE1MU3RyZWFtUmVhZGVyKCk7Ci0gICAgICAgICAgICBmaW5hbCBYTUxFdmVudFJlYWRlciBldmVudFJlYWRlciA9IHNjaGVtYVNvdXJjZS5nZXRYTUxFdmVudFJlYWRlcigpOwotCi0gICAgICAgICAgICAvLyBjaGVjayB3aGV0aGVyIHRoZSBzYW1lIGRvY3VtZW50IGhhcyBiZWVuIHBhcnNlZCBiZWZvcmUuCi0gICAgICAgICAgICAvLyBJZiBzbywgcmV0dXJuIHRoZSBkb2N1bWVudCBjb3JyZXNwb25kaW5nIHRvIHRoYXQgc3lzdGVtIGlkLgotICAgICAgICAgICAgWFNES2V5IGtleSA9IG51bGw7Ci0gICAgICAgICAgICBTdHJpbmcgc2NoZW1hSWQgPSBudWxsOwotICAgICAgICAgICAgaWYgKHJlZmVyVHlwZSAhPSBYU0REZXNjcmlwdGlvbi5DT05URVhUX1BSRVBBUlNFKSB7Ci0gICAgICAgICAgICAgICAgc2NoZW1hSWQgPSBYTUxFbnRpdHlNYW5hZ2VyLmV4cGFuZFN5c3RlbUlkKHNjaGVtYVNvdXJjZS5nZXRTeXN0ZW1JZCgpLCBzY2hlbWFTb3VyY2UuZ2V0QmFzZVN5c3RlbUlkKCksIGZhbHNlKTsKLSAgICAgICAgICAgICAgICBib29sZWFuIGlzRG9jdW1lbnQgPSBjb25zdW1lUmVtYWluaW5nQ29udGVudDsKLSAgICAgICAgICAgICAgICBpZiAoIWlzRG9jdW1lbnQpIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKHN0cmVhbVJlYWRlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpc0RvY3VtZW50ID0gKHN0cmVhbVJlYWRlci5nZXRFdmVudFR5cGUoKSA9PSBYTUxTdHJlYW1SZWFkZXIuU1RBUlRfRE9DVU1FTlQpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgaXNEb2N1bWVudCA9IGV2ZW50UmVhZGVyLnBlZWsoKS5pc1N0YXJ0RG9jdW1lbnQoKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpZiAoaXNEb2N1bWVudCkgewotICAgICAgICAgICAgICAgICAgICBrZXkgPSBuZXcgWFNES2V5KHNjaGVtYUlkLCByZWZlclR5cGUsIHNjaGVtYU5hbWVzcGFjZSk7Ci0gICAgICAgICAgICAgICAgICAgIGlmICgoc2NoZW1hRWxlbWVudCA9IGZUcmF2ZXJzZWQuZ2V0KGtleSkpICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZMYXN0U2NoZW1hV2FzRHVwbGljYXRlID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzY2hlbWFFbGVtZW50OwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAoZlN0QVhTY2hlbWFQYXJzZXIgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZTdEFYU2NoZW1hUGFyc2VyID0gbmV3IFN0QVhTY2hlbWFQYXJzZXIoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGZTdEFYU2NoZW1hUGFyc2VyLnJlc2V0KGZTY2hlbWFQYXJzZXIsIGZTeW1ib2xUYWJsZSk7Ci0KLSAgICAgICAgICAgIGlmIChzdHJlYW1SZWFkZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZTdEFYU2NoZW1hUGFyc2VyLnBhcnNlKHN0cmVhbVJlYWRlcik7Ci0gICAgICAgICAgICAgICAgaWYgKGNvbnN1bWVSZW1haW5pbmdDb250ZW50KSB7Ci0gICAgICAgICAgICAgICAgICAgIHdoaWxlIChzdHJlYW1SZWFkZXIuaGFzTmV4dCgpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1SZWFkZXIubmV4dCgpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgZlN0QVhTY2hlbWFQYXJzZXIucGFyc2UoZXZlbnRSZWFkZXIpOwotICAgICAgICAgICAgICAgIGlmIChjb25zdW1lUmVtYWluaW5nQ29udGVudCkgewotICAgICAgICAgICAgICAgICAgICB3aGlsZSAoZXZlbnRSZWFkZXIuaGFzTmV4dCgpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBldmVudFJlYWRlci5uZXh0RXZlbnQoKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIERvY3VtZW50IHNjaGVtYURvY3VtZW50ID0gZlN0QVhTY2hlbWFQYXJzZXIuZ2V0RG9jdW1lbnQoKTsKLSAgICAgICAgICAgIHNjaGVtYUVsZW1lbnQgPSBzY2hlbWFEb2N1bWVudCAhPSBudWxsID8gRE9NVXRpbC5nZXRSb290KHNjaGVtYURvY3VtZW50KSA6IG51bGw7Ci0gICAgICAgICAgICByZXR1cm4gZ2V0U2NoZW1hRG9jdW1lbnQwKGtleSwgc2NoZW1hSWQsIHNjaGVtYUVsZW1lbnQpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChYTUxTdHJlYW1FeGNlcHRpb24gZSkgewotICAgICAgICAgICAgU3RBWExvY2F0aW9uV3JhcHBlciBzbHcgPSBuZXcgU3RBWExvY2F0aW9uV3JhcHBlcigpOwotICAgICAgICAgICAgc2x3LnNldExvY2F0aW9uKGUuZ2V0TG9jYXRpb24oKSk7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWE1MUGFyc2VFeGNlcHRpb24oc2x3LCBlLmdldE1lc3NhZ2UoKSwgZSk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIGV4Y2VwdGlvbiA9IGU7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGdldFNjaGVtYURvY3VtZW50MShtdXN0UmVzb2x2ZSwgdHJ1ZSwgc2NoZW1hU291cmNlLCByZWZlckVsZW1lbnQsIGV4Y2VwdGlvbik7Ci0gICAgfSAvLyBnZXRTY2hlbWFEb2N1bWVudChTdHJpbmcsIFN0QVhJbnB1dFNvdXJjZSwgYm9vbGVhbiwgc2hvcnQsIEVsZW1lbnQpOiBFbGVtZW50Ci0KLSAgICAvKioKLSAgICAgKiBDb2RlIHNoYXJlZCBiZXR3ZWVuIHRoZSB2YXJpb3VzIGdldFNjaGVtYURvY3VtZW50KCkgbWV0aG9kcyB3aGljaAotICAgICAqIHN0b3JlcyBtYXBwaW5nIGluZm9ybWF0aW9uIGZvciB0aGUgZG9jdW1lbnQuCi0gICAgICovCi0gICAgcHJpdmF0ZSBFbGVtZW50IGdldFNjaGVtYURvY3VtZW50MChYU0RLZXkga2V5LCBTdHJpbmcgc2NoZW1hSWQsIEVsZW1lbnQgc2NoZW1hRWxlbWVudCkgewotICAgICAgICAvLyBub3cgd2UgbmVlZCB0byBzdG9yZSB0aGUgbWFwcGluZyBpbmZvcm1hdGlvbiBmcm9tIHN5c3RlbSBpZAotICAgICAgICAvLyB0byB0aGUgZG9jdW1lbnQuIGFsc28gZnJvbSB0aGUgZG9jdW1lbnQgdG8gdGhlIHN5c3RlbSBpZC4KLSAgICAgICAgaWYgKGtleSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmVHJhdmVyc2VkLnB1dChrZXksIHNjaGVtYUVsZW1lbnQpOwotICAgICAgICB9Ci0gICAgICAgIGlmIChzY2hlbWFJZCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmRG9jMlN5c3RlbUlkLnB1dChzY2hlbWFFbGVtZW50LCBzY2hlbWFJZCk7Ci0gICAgICAgIH0KLSAgICAgICAgZkxhc3RTY2hlbWFXYXNEdXBsaWNhdGUgPSBmYWxzZTsKLSAgICAgICAgcmV0dXJuIHNjaGVtYUVsZW1lbnQ7Ci0gICAgfSAvLyBnZXRTY2hlbWFEb2N1bWVudDAoWFNES2V5LCBTdHJpbmcsIEVsZW1lbnQpOiBFbGVtZW50Ci0KLSAgICAvKioKLSAgICAgKiBFcnJvciBoYW5kbGluZyBjb2RlIHNoYXJlZCBiZXR3ZWVuIHRoZSB2YXJpb3VzIGdldFNjaGVtYURvY3VtZW50KCkgbWV0aG9kcy4KLSAgICAgKi8KLSAgICBwcml2YXRlIEVsZW1lbnQgZ2V0U2NoZW1hRG9jdW1lbnQxKGJvb2xlYW4gbXVzdFJlc29sdmUsIGJvb2xlYW4gaGFzSW5wdXQsCi0gICAgICAgICAgICBYTUxJbnB1dFNvdXJjZSBzY2hlbWFTb3VyY2UsIEVsZW1lbnQgcmVmZXJFbGVtZW50LCBJT0V4Y2VwdGlvbiBpb2UpIHsKLSAgICAgICAgLy8gZWl0aGVyIGFuIGVycm9yIG9jY3VyZWQgKGV4Y2VwdGlvbiksIG9yIGVtcHR5IGlucHV0IHNvdXJjZSB3YXMKLSAgICAgICAgLy8gcmV0dXJuZWQsIHdlIG5lZWQgdG8gcmVwb3J0IGFuIGVycm9yIG9yIGEgd2FybmluZwotICAgICAgICBpZiAobXVzdFJlc29sdmUpIHsKLSAgICAgICAgICAgIGlmIChoYXNJbnB1dCkgewotICAgICAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKCJzY2hlbWFfcmVmZXJlbmNlLjQiLAotICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde3NjaGVtYVNvdXJjZS5nZXRTeXN0ZW1JZCgpfSwKLSAgICAgICAgICAgICAgICAgICAgICAgIHJlZmVyRWxlbWVudCwgaW9lKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKCJzY2hlbWFfcmVmZXJlbmNlLjQiLAotICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde3NjaGVtYVNvdXJjZSA9PSBudWxsID8gIiIgOiBzY2hlbWFTb3VyY2UuZ2V0U3lzdGVtSWQoKX0sCi0gICAgICAgICAgICAgICAgICAgICAgICByZWZlckVsZW1lbnQsIGlvZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoaGFzSW5wdXQpIHsKLSAgICAgICAgICAgIHJlcG9ydFNjaGVtYVdhcm5pbmcoInNjaGVtYV9yZWZlcmVuY2UuNCIsCi0gICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXtzY2hlbWFTb3VyY2UuZ2V0U3lzdGVtSWQoKX0sCi0gICAgICAgICAgICAgICAgICAgIHJlZmVyRWxlbWVudCwgaW9lKTsKLSAgICAgICAgfQotCi0gICAgICAgIGZMYXN0U2NoZW1hV2FzRHVwbGljYXRlID0gZmFsc2U7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0gLy8gZ2V0U2NoZW1hRG9jdW1lbnQxKGJvb2xlYW4sIGJvb2xlYW4sIFhNTElucHV0U291cmNlLCBFbGVtZW50KTogRWxlbWVudAotCi0gICAgLyoqCi0gICAgICogZ2V0U2NoZW1hRG9jdW1lbnQgbWV0aG9kIHVzZXMgWE1MSW5wdXRTb3VyY2UgdG8gcGFyc2UgYSBzY2hlbWEgZG9jdW1lbnQuCi0gICAgICogQHBhcmFtIHNjaGVtYU5hbWVzcGFjZQotICAgICAqIEBwYXJhbSBzY2hlbWFTb3VyY2UKLSAgICAgKiBAcGFyYW0gbXVzdFJlc29sdmUKLSAgICAgKiBAcGFyYW0gcmVmZXJUeXBlCi0gICAgICogQHBhcmFtIHJlZmVyRWxlbWVudAotICAgICAqIEByZXR1cm4gQSBzY2hlbWEgRWxlbWVudC4KLSAgICAgKi8KLSAgICBwcml2YXRlIEVsZW1lbnQgZ2V0U2NoZW1hRG9jdW1lbnQoWFNJbnB1dFNvdXJjZSBzY2hlbWFTb3VyY2UsIFhTRERlc2NyaXB0aW9uIGRlc2MpIHsKLQotICAgICAgICBTY2hlbWFHcmFtbWFyW10gZ3JhbW1hcnMgPSBzY2hlbWFTb3VyY2UuZ2V0R3JhbW1hcnMoKTsKLSAgICAgICAgc2hvcnQgcmVmZXJUeXBlID0gZGVzYy5nZXRDb250ZXh0VHlwZSgpOwotCi0gICAgICAgIGlmIChncmFtbWFycyAhPSBudWxsICYmIGdyYW1tYXJzLmxlbmd0aCA+IDApIHsKLSAgICAgICAgICAgIFZlY3RvciBleHBhbmRlZEdyYW1tYXJzID0gZXhwYW5kR3JhbW1hcnMoZ3JhbW1hcnMpOwotICAgICAgICAgICAgLy8gY2hlY2sgZm9yIGV4aXN0aW5nIGdyYW1tYXJzIGluIG91ciBidWNrZXQKLSAgICAgICAgICAgIC8vIGFuZCBpZiB0aGVyZSBleGlzdCBhbnksIGFuZCBuYW1lc3BhY2UgZ3Jvd3RoIGlzCi0gICAgICAgICAgICAvLyBub3QgZW5hYmxlZCAtIHdlIGRvIG5vdGhpbmcKLSAgICAgICAgICAgIGlmIChmTmFtZXNwYWNlR3Jvd3RoIHx8ICFleGlzdGluZ0dyYW1tYXJzKGV4cGFuZGVkR3JhbW1hcnMpKSB7Ci0gICAgICAgICAgICAgICAgYWRkR3JhbW1hcnMoZXhwYW5kZWRHcmFtbWFycyk7Ci0gICAgICAgICAgICAgICAgaWYgKHJlZmVyVHlwZSA9PSBYU0REZXNjcmlwdGlvbi5DT05URVhUX1BSRVBBUlNFKSB7Ci0gICAgICAgICAgICAgICAgICAgIGRlc2Muc2V0VGFyZ2V0TmFtZXNwYWNlKGdyYW1tYXJzWzBdLmdldFRhcmdldE5hbWVzcGFjZSgpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBYU09iamVjdFtdIGNvbXBvbmVudHMgPSBzY2hlbWFTb3VyY2UuZ2V0Q29tcG9uZW50cygpOwotICAgICAgICAgICAgaWYgKGNvbXBvbmVudHMgIT0gbnVsbCAmJiBjb21wb25lbnRzLmxlbmd0aCA+IDApIHsKLSAgICAgICAgICAgICAgICBNYXA8U3RyaW5nLCBWZWN0b3I+IGltcG9ydERlcGVuZGVuY2llcyA9IG5ldyBIYXNoTWFwKCk7Ci0gICAgICAgICAgICAgICAgVmVjdG9yIGV4cGFuZGVkQ29tcG9uZW50cyA9IGV4cGFuZENvbXBvbmVudHMoY29tcG9uZW50cywgaW1wb3J0RGVwZW5kZW5jaWVzKTsKLSAgICAgICAgICAgICAgICBpZiAoZk5hbWVzcGFjZUdyb3d0aCB8fCBjYW5BZGRDb21wb25lbnRzKGV4cGFuZGVkQ29tcG9uZW50cykpIHsKLSAgICAgICAgICAgICAgICAgICAgYWRkR2xvYmFsQ29tcG9uZW50cyhleHBhbmRlZENvbXBvbmVudHMsIGltcG9ydERlcGVuZGVuY2llcyk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChyZWZlclR5cGUgPT0gWFNERGVzY3JpcHRpb24uQ09OVEVYVF9QUkVQQVJTRSkgewotICAgICAgICAgICAgICAgICAgICAgICAgZGVzYy5zZXRUYXJnZXROYW1lc3BhY2UoY29tcG9uZW50c1swXS5nZXROYW1lc3BhY2UoKSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfSAvLyBnZXRTY2hlbWFEb2N1bWVudChTdHJpbmcsIFhTSW5wdXRTb3VyY2UsIGJvb2xlYW4sIHNob3J0LCBFbGVtZW50KTogRWxlbWVudAotCi0gICAgcHJpdmF0ZSBWZWN0b3IgZXhwYW5kR3JhbW1hcnMoU2NoZW1hR3JhbW1hcltdIGdyYW1tYXJzKSB7Ci0gICAgICAgIFZlY3RvciBjdXJyR3JhbW1hcnMgPSBuZXcgVmVjdG9yKCk7Ci0KLSAgICAgICAgZm9yIChpbnQgaT0wOyBpPGdyYW1tYXJzLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICBpZiAoIWN1cnJHcmFtbWFycy5jb250YWlucyhncmFtbWFyc1tpXSkpIHsKLSAgICAgICAgICAgICAgICBjdXJyR3JhbW1hcnMuYWRkKGdyYW1tYXJzW2ldKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIGZvciBhbGwgKHJlY3Vyc2l2ZWx5KSBpbXBvcnRlZCBncmFtbWFycwotICAgICAgICBTY2hlbWFHcmFtbWFyIHNnMSwgc2cyOwotICAgICAgICBWZWN0b3IgZ3M7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY3VyckdyYW1tYXJzLnNpemUoKTsgaSsrKSB7Ci0gICAgICAgICAgICAvLyBnZXQgdGhlIGdyYW1tYXIKLSAgICAgICAgICAgIHNnMSA9IChTY2hlbWFHcmFtbWFyKWN1cnJHcmFtbWFycy5lbGVtZW50QXQoaSk7Ci0gICAgICAgICAgICAvLyB3ZSBuZWVkIHRvIGFkZCBncmFtbWFycyBpbXBvcnRlZCBieSBzZzEgdG9vCi0gICAgICAgICAgICBncyA9IHNnMS5nZXRJbXBvcnRlZEdyYW1tYXJzKCk7Ci0gICAgICAgICAgICAvLyBmb3IgYWxsIGdyYW1tYXJzIGltcG9ydGVkIGJ5IHNnMiwgYnV0IG5vdCBpbiB0aGUgdmVjdG9yCi0gICAgICAgICAgICAvLyB3ZSBhZGQgdGhlbSB0byB0aGUgdmVjdG9yCi0gICAgICAgICAgICBpZiAoZ3MgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBmb3IgKGludCBqID0gZ3Muc2l6ZSgpIC0gMTsgaiA+PSAwOyBqLS0pIHsKLSAgICAgICAgICAgICAgICBzZzIgPSAoU2NoZW1hR3JhbW1hcilncy5lbGVtZW50QXQoaik7Ci0gICAgICAgICAgICAgICAgaWYgKCFjdXJyR3JhbW1hcnMuY29udGFpbnMoc2cyKSkgewotICAgICAgICAgICAgICAgICAgICBjdXJyR3JhbW1hcnMuYWRkRWxlbWVudChzZzIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBjdXJyR3JhbW1hcnM7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBib29sZWFuIGV4aXN0aW5nR3JhbW1hcnMoVmVjdG9yIGdyYW1tYXJzKSB7Ci0gICAgICAgIGludCBsZW5ndGggPSBncmFtbWFycy5zaXplKCk7Ci0gICAgICAgIGZpbmFsIFhTRERlc2NyaXB0aW9uIGRlc2MgPSBuZXcgWFNERGVzY3JpcHRpb24oKTsKLQotICAgICAgICBmb3IgKGludCBpPTA7IGkgPCBsZW5ndGg7IGkrKykgewotICAgICAgICAgICAgZmluYWwgU2NoZW1hR3JhbW1hciBzZzEgPSAoU2NoZW1hR3JhbW1hcilncmFtbWFycy5lbGVtZW50QXQoaSk7Ci0gICAgICAgICAgICBkZXNjLnNldE5hbWVzcGFjZShzZzEuZ2V0VGFyZ2V0TmFtZXNwYWNlKCkpOwotCi0gICAgICAgICAgICBmaW5hbCBTY2hlbWFHcmFtbWFyIHNnMiA9IGZpbmRHcmFtbWFyKGRlc2MsIGZhbHNlKTsKLSAgICAgICAgICAgIGlmIChzZzIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIHByaXZhdGUgYm9vbGVhbiBjYW5BZGRDb21wb25lbnRzKFZlY3RvciBjb21wb25lbnRzKSB7Ci0gICAgICAgIGZpbmFsIGludCBzaXplID0gY29tcG9uZW50cy5zaXplKCk7Ci0gICAgICAgIGZpbmFsIFhTRERlc2NyaXB0aW9uIGRlc2MgPSBuZXcgWFNERGVzY3JpcHRpb24oKTsKLSAgICAgICAgZm9yIChpbnQgaT0wOyBpPHNpemU7IGkrKykgewotICAgICAgICAgICAgWFNPYmplY3QgY29tcG9uZW50ID0gKFhTT2JqZWN0KSBjb21wb25lbnRzLmVsZW1lbnRBdChpKTsKLSAgICAgICAgICAgIGlmICghY2FuQWRkQ29tcG9uZW50KGNvbXBvbmVudCwgZGVzYykpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBib29sZWFuIGNhbkFkZENvbXBvbmVudChYU09iamVjdCBjb21wb25lbnQsIFhTRERlc2NyaXB0aW9uIGRlc2MpIHsKLSAgICAgICAgZGVzYy5zZXROYW1lc3BhY2UoY29tcG9uZW50LmdldE5hbWVzcGFjZSgpKTsKLQotICAgICAgICBmaW5hbCBTY2hlbWFHcmFtbWFyIHNnID0gZmluZEdyYW1tYXIoZGVzYywgZmFsc2UpOwotICAgICAgICBpZiAoc2cgPT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoc2cuaXNJbW11dGFibGUoKSkgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0KLSAgICAgICAgc2hvcnQgY29tcG9uZW50VHlwZSA9IGNvbXBvbmVudC5nZXRUeXBlKCk7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBuYW1lID0gY29tcG9uZW50LmdldE5hbWUoKTsKLQotICAgICAgICBzd2l0Y2ggKGNvbXBvbmVudFR5cGUpIHsKLSAgICAgICAgY2FzZSBYU0NvbnN0YW50cy5UWVBFX0RFRklOSVRJT04gOgotICAgICAgICAgICAgaWYgKHNnLmdldEdsb2JhbFR5cGVEZWNsKG5hbWUpID09IGNvbXBvbmVudCkgewotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgWFNDb25zdGFudHMuQVRUUklCVVRFX0RFQ0xBUkFUSU9OIDoKLSAgICAgICAgICAgIGlmIChzZy5nZXRHbG9iYWxBdHRyaWJ1dGVEZWNsKG5hbWUpID09IGNvbXBvbmVudCkgewotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgWFNDb25zdGFudHMuQVRUUklCVVRFX0dST1VQIDoKLSAgICAgICAgICAgIGlmIChzZy5nZXRHbG9iYWxBdHRyaWJ1dGVEZWNsKG5hbWUpID09IGNvbXBvbmVudCkgewotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgWFNDb25zdGFudHMuRUxFTUVOVF9ERUNMQVJBVElPTiA6Ci0gICAgICAgICAgICBpZiAoc2cuZ2V0R2xvYmFsRWxlbWVudERlY2wobmFtZSkgPT0gY29tcG9uZW50KSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBYU0NvbnN0YW50cy5NT0RFTF9HUk9VUF9ERUZJTklUSU9OIDoKLSAgICAgICAgICAgIGlmIChzZy5nZXRHbG9iYWxHcm91cERlY2wobmFtZSkgPT0gY29tcG9uZW50KSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBYU0NvbnN0YW50cy5OT1RBVElPTl9ERUNMQVJBVElPTiA6Ci0gICAgICAgICAgICBpZiAoc2cuZ2V0R2xvYmFsTm90YXRpb25EZWNsKG5hbWUpID09IGNvbXBvbmVudCkgewotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgWFNDb25zdGFudHMuSURFTlRJVFlfQ09OU1RSQUlOVCA6Ci0gICAgICAgIGNhc2UgWFNDb25zdGFudHMuQVRUUklCVVRFX1VTRSA6Ci0gICAgICAgIGRlZmF1bHQgOgotICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBhZGRHcmFtbWFycyhWZWN0b3IgZ3JhbW1hcnMpIHsKLSAgICAgICAgaW50IGxlbmd0aCA9IGdyYW1tYXJzLnNpemUoKTsKLSAgICAgICAgWFNERGVzY3JpcHRpb24gZGVzYyA9IG5ldyBYU0REZXNjcmlwdGlvbigpOwotCi0gICAgICAgIGZvciAoaW50IGk9MDsgaSA8IGxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICBmaW5hbCBTY2hlbWFHcmFtbWFyIHNnMSA9IChTY2hlbWFHcmFtbWFyKWdyYW1tYXJzLmVsZW1lbnRBdChpKTsKLSAgICAgICAgICAgIGRlc2Muc2V0TmFtZXNwYWNlKHNnMS5nZXRUYXJnZXROYW1lc3BhY2UoKSk7Ci0KLSAgICAgICAgICAgIGZpbmFsIFNjaGVtYUdyYW1tYXIgc2cyID0gZmluZEdyYW1tYXIoZGVzYywgZk5hbWVzcGFjZUdyb3d0aCk7Ci0gICAgICAgICAgICBpZiAoc2cxICE9IHNnMikgewotICAgICAgICAgICAgICAgIGFkZEdyYW1tYXJDb21wb25lbnRzKHNnMSwgc2cyKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBhZGRHcmFtbWFyQ29tcG9uZW50cyhTY2hlbWFHcmFtbWFyIHNyY0dyYW1tYXIsIFNjaGVtYUdyYW1tYXIgZHN0R3JhbW1hcikgewotICAgICAgICBpZiAoZHN0R3JhbW1hciA9PSBudWxsKSB7Ci0gICAgICAgICAgICBjcmVhdGVHcmFtbWFyRnJvbShzcmNHcmFtbWFyKTsKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotCi0gICAgICAgIFNjaGVtYUdyYW1tYXIgdG1wR3JhbW1hciA9IGRzdEdyYW1tYXI7Ci0gICAgICAgIGlmICh0bXBHcmFtbWFyLmlzSW1tdXRhYmxlKCkpIHsKLSAgICAgICAgICAgIHRtcEdyYW1tYXIgPSBjcmVhdGVHcmFtbWFyRnJvbShkc3RHcmFtbWFyKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIGFkZCBhbnkgbmV3IGxvY2F0aW9ucwotICAgICAgICBhZGROZXdHcmFtbWFyTG9jYXRpb25zKHNyY0dyYW1tYXIsIHRtcEdyYW1tYXIpOwotCi0gICAgICAgIC8vIGFkZCBhbnkgbmV3IGltcG9ydGVkIGdyYW1tYXJzCi0gICAgICAgIGFkZE5ld0ltcG9ydGVkR3JhbW1hcnMoc3JjR3JhbW1hciwgdG1wR3JhbW1hcik7Ci0KLSAgICAgICAgLy8gYWRkIGFueSBuZXcgZ2xvYmFsIGNvbXBvbmVudHMKLSAgICAgICAgYWRkTmV3R3JhbW1hckNvbXBvbmVudHMoc3JjR3JhbW1hciwgdG1wR3JhbW1hcik7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBTY2hlbWFHcmFtbWFyIGNyZWF0ZUdyYW1tYXJGcm9tKFNjaGVtYUdyYW1tYXIgZ3JhbW1hcikgewotICAgICAgICBTY2hlbWFHcmFtbWFyIG5ld0dyYW1tYXIgPSBuZXcgU2NoZW1hR3JhbW1hcihncmFtbWFyKTsKLSAgICAgICAgZkdyYW1tYXJCdWNrZXQucHV0R3JhbW1hcihuZXdHcmFtbWFyKTsKLSAgICAgICAgLy8gdXBkYXRlIGFsbCB0aGUgZ3JhbW1hcnMgaW4gdGhlIGJ1Y2tldCB0byBwb2ludCB0byB0aGUgbmV3IGdyYW1tYXIuCi0gICAgICAgIHVwZGF0ZUltcG9ydExpc3RXaXRoKG5ld0dyYW1tYXIpOwotICAgICAgICAvLyB1cGRhdGUgaW1wb3J0IGxpc3Qgb2YgdGhlIG5ldyBncmFtbWFyCi0gICAgICAgIHVwZGF0ZUltcG9ydExpc3RGb3IobmV3R3JhbW1hcik7Ci0gICAgICAgIHJldHVybiBuZXdHcmFtbWFyOwotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBhZGROZXdHcmFtbWFyTG9jYXRpb25zKFNjaGVtYUdyYW1tYXIgc3JjR3JhbW1hciwgU2NoZW1hR3JhbW1hciBkc3RHcmFtbWFyKSB7Ci0gICAgICAgIGZpbmFsIFN0cmluZ0xpc3QgbG9jYXRpb25zID0gc3JjR3JhbW1hci5nZXREb2N1bWVudExvY2F0aW9ucygpOwotICAgICAgICBmaW5hbCBpbnQgbG9jU2l6ZSA9IGxvY2F0aW9ucy5zaXplKCk7Ci0gICAgICAgIGZpbmFsIFN0cmluZ0xpc3QgbG9jYXRpb25zMiA9IGRzdEdyYW1tYXIuZ2V0RG9jdW1lbnRMb2NhdGlvbnMoKTsKLQotICAgICAgICBmb3IgKGludCBpPTA7IGk8bG9jU2l6ZTsgaSsrKSB7Ci0gICAgICAgICAgICBTdHJpbmcgbG9jID0gbG9jYXRpb25zLml0ZW0oaSk7Ci0gICAgICAgICAgICBpZiAoIWxvY2F0aW9uczIuY29udGFpbnMobG9jKSkgewotICAgICAgICAgICAgICAgIGRzdEdyYW1tYXIuYWRkRG9jdW1lbnQobnVsbCwgbG9jKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBhZGROZXdJbXBvcnRlZEdyYW1tYXJzKFNjaGVtYUdyYW1tYXIgc3JjR3JhbW1hciwgU2NoZW1hR3JhbW1hciBkc3RHcmFtbWFyKSB7Ci0gICAgICAgIGZpbmFsIFZlY3RvciBpZ3MxID0gc3JjR3JhbW1hci5nZXRJbXBvcnRlZEdyYW1tYXJzKCk7Ci0gICAgICAgIGlmIChpZ3MxICE9IG51bGwpIHsKLSAgICAgICAgICAgIFZlY3RvciBpZ3MyID0gZHN0R3JhbW1hci5nZXRJbXBvcnRlZEdyYW1tYXJzKCk7Ci0KLSAgICAgICAgICAgIGlmIChpZ3MyID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBpZ3MyID0gKChWZWN0b3IpIGlnczEuY2xvbmUoKSk7Ci0gICAgICAgICAgICAgICAgZHN0R3JhbW1hci5zZXRJbXBvcnRlZEdyYW1tYXJzKGlnczIpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgdXBkYXRlSW1wb3J0TGlzdChpZ3MxLCBpZ3MyKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCB1cGRhdGVJbXBvcnRMaXN0KFZlY3RvciBpbXBvcnRlZFNyYywgVmVjdG9yIGltcG9ydGVkRHN0KQotICAgIHsKLSAgICAgICAgZmluYWwgaW50IHNpemUgPSBpbXBvcnRlZFNyYy5zaXplKCk7Ci0KLSAgICAgICAgZm9yIChpbnQgaT0wOyBpPHNpemU7IGkrKykgewotICAgICAgICAgICAgZmluYWwgU2NoZW1hR3JhbW1hciBzZyA9IChTY2hlbWFHcmFtbWFyKSBpbXBvcnRlZFNyYy5lbGVtZW50QXQoaSk7Ci0gICAgICAgICAgICBpZiAoIWNvbnRhaW5lZEltcG9ydGVkR3JhbW1hcihpbXBvcnRlZERzdCwgc2cpKSB7Ci0gICAgICAgICAgICAgICAgaW1wb3J0ZWREc3QuYWRkKHNnKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBhZGROZXdHcmFtbWFyQ29tcG9uZW50cyhTY2hlbWFHcmFtbWFyIHNyY0dyYW1tYXIsIFNjaGVtYUdyYW1tYXIgZHN0R3JhbW1hcikgewotICAgICAgICBkc3RHcmFtbWFyLnJlc2V0Q29tcG9uZW50cygpOwotICAgICAgICBhZGRHbG9iYWxFbGVtZW50RGVjbHMoc3JjR3JhbW1hciwgZHN0R3JhbW1hcik7Ci0gICAgICAgIGFkZEdsb2JhbEF0dHJpYnV0ZURlY2xzKHNyY0dyYW1tYXIsIGRzdEdyYW1tYXIpOwotICAgICAgICBhZGRHbG9iYWxBdHRyaWJ1dGVHcm91cERlY2xzKHNyY0dyYW1tYXIsIGRzdEdyYW1tYXIpOwotICAgICAgICBhZGRHbG9iYWxHcm91cERlY2xzKHNyY0dyYW1tYXIsIGRzdEdyYW1tYXIpOwotICAgICAgICBhZGRHbG9iYWxUeXBlRGVjbHMoc3JjR3JhbW1hciwgZHN0R3JhbW1hcik7Ci0gICAgICAgIGFkZEdsb2JhbE5vdGF0aW9uRGVjbHMoc3JjR3JhbW1hciwgZHN0R3JhbW1hcik7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIGFkZEdsb2JhbEVsZW1lbnREZWNscyhTY2hlbWFHcmFtbWFyIHNyY0dyYW1tYXIsIFNjaGVtYUdyYW1tYXIgZHN0R3JhbW1hcikgewotICAgICAgICBYU05hbWVkTWFwIGNvbXBvbmVudHMgPSBzcmNHcmFtbWFyLmdldENvbXBvbmVudHMoWFNDb25zdGFudHMuRUxFTUVOVF9ERUNMQVJBVElPTik7Ci0gICAgICAgIGludCBsZW4gPSBjb21wb25lbnRzLmdldExlbmd0aCgpOwotICAgICAgICBYU0VsZW1lbnREZWNsIHNyY0RlY2wsIGRzdERlY2w7Ci0KLSAgICAgICAgLy8gYWRkIGdsb2JhbCBjb21wb25lbnRzCi0gICAgICAgIGZvciAoaW50IGk9MDsgaTxsZW47IGkrKykgewotICAgICAgICAgICAgc3JjRGVjbCA9IChYU0VsZW1lbnREZWNsKSBjb21wb25lbnRzLml0ZW0oaSk7Ci0gICAgICAgICAgICBkc3REZWNsID0gZHN0R3JhbW1hci5nZXRHbG9iYWxFbGVtZW50RGVjbChzcmNEZWNsLmdldE5hbWUoKSk7Ci0gICAgICAgICAgICBpZiAoZHN0RGVjbCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZHN0R3JhbW1hci5hZGRHbG9iYWxFbGVtZW50RGVjbChzcmNEZWNsKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKGRzdERlY2wgIT0gc3JjRGVjbCl7Ci0gICAgICAgICAgICAgICAgLy8gVE9ETzogaWYgbm90IHRvbGVyYXRpbmcgZHVwbGljYXRlLCBnZW5lcmF0ZSBhbiBlcnJvciBtZXNzYWdlCi0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBhZGQgYW55IGV4dGVuZGVkIChkdXBsaWNhdGUpIGdsb2JhbCBjb21wb25lbnRzCi0gICAgICAgIE9iamVjdExpc3QgY29tcG9uZW50c0V4dCA9IHNyY0dyYW1tYXIuZ2V0Q29tcG9uZW50c0V4dChYU0NvbnN0YW50cy5FTEVNRU5UX0RFQ0xBUkFUSU9OKTsKLSAgICAgICAgbGVuID0gY29tcG9uZW50c0V4dC5nZXRMZW5ndGgoKTsKLQotICAgICAgICBmb3IgKGludCBpPTA7IGk8bGVuOyBpKz0gMikgewotICAgICAgICAgICAgZmluYWwgU3RyaW5nIGtleSA9IChTdHJpbmcpIGNvbXBvbmVudHNFeHQuaXRlbShpKTsKLSAgICAgICAgICAgIGZpbmFsIGludCBpbmRleCA9IGtleS5pbmRleE9mKCcsJyk7Ci0gICAgICAgICAgICBmaW5hbCBTdHJpbmcgbG9jYXRpb24gPSBrZXkuc3Vic3RyaW5nKDAsIGluZGV4KTsKLSAgICAgICAgICAgIGZpbmFsIFN0cmluZyBuYW1lID0ga2V5LnN1YnN0cmluZyhpbmRleCArIDEsIGtleS5sZW5ndGgoKSk7Ci0KLSAgICAgICAgICAgIHNyY0RlY2wgPSAoWFNFbGVtZW50RGVjbCljb21wb25lbnRzRXh0Lml0ZW0oaSsxKTsKLSAgICAgICAgICAgIGRzdERlY2wgPSBkc3RHcmFtbWFyLmdldEdsb2JhbEVsZW1lbnREZWNsKG5hbWUsIGxvY2F0aW9uKTsKLSAgICAgICAgICAgIGlmICggZHN0RGVjbCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZHN0R3JhbW1hci5hZGRHbG9iYWxFbGVtZW50RGVjbChzcmNEZWNsLCBsb2NhdGlvbik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChkc3REZWNsICE9IHNyY0RlY2wpewotICAgICAgICAgICAgICAgIC8vIFRPRE86IGlmIG5vdCB0b2xlcmF0aW5nIGR1cGxpY2F0ZSwgZ2VuZXJhdGUgYW4gZXJyb3IgbWVzc2FnZQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIGFkZEdsb2JhbEF0dHJpYnV0ZURlY2xzKFNjaGVtYUdyYW1tYXIgc3JjR3JhbW1hciwgU2NoZW1hR3JhbW1hciBkc3RHcmFtbWFyKSB7Ci0gICAgICAgIFhTTmFtZWRNYXAgY29tcG9uZW50cyA9IHNyY0dyYW1tYXIuZ2V0Q29tcG9uZW50cyhYU0NvbnN0YW50cy5BVFRSSUJVVEVfREVDTEFSQVRJT04pOwotICAgICAgICBpbnQgbGVuID0gY29tcG9uZW50cy5nZXRMZW5ndGgoKTsKLSAgICAgICAgWFNBdHRyaWJ1dGVEZWNsIHNyY0RlY2wsIGRzdERlY2w7Ci0KLSAgICAgICAgLy8gYWRkIGdsb2JhbCBjb21wb25lbnRzCi0gICAgICAgIGZvciAoaW50IGk9MDsgaTxsZW47IGkrKykgewotICAgICAgICAgICAgc3JjRGVjbCA9IChYU0F0dHJpYnV0ZURlY2wpIGNvbXBvbmVudHMuaXRlbShpKTsKLSAgICAgICAgICAgIGRzdERlY2wgPSBkc3RHcmFtbWFyLmdldEdsb2JhbEF0dHJpYnV0ZURlY2woc3JjRGVjbC5nZXROYW1lKCkpOwotICAgICAgICAgICAgaWYgKGRzdERlY2wgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGRzdEdyYW1tYXIuYWRkR2xvYmFsQXR0cmlidXRlRGVjbChzcmNEZWNsKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKGRzdERlY2wgIT0gc3JjRGVjbCAmJiAhZlRvbGVyYXRlRHVwbGljYXRlcykgewotICAgICAgICAgICAgICAgIHJlcG9ydFNoYXJpbmdFcnJvcihzcmNEZWNsLmdldE5hbWVzcGFjZSgpLCBzcmNEZWNsLmdldE5hbWUoKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBhZGQgYW55IGV4dGVuZGVkIChkdXBsaWNhdGUpIGdsb2JhbCBjb21wb25lbnRzCi0gICAgICAgIE9iamVjdExpc3QgY29tcG9uZW50c0V4dCA9IHNyY0dyYW1tYXIuZ2V0Q29tcG9uZW50c0V4dChYU0NvbnN0YW50cy5BVFRSSUJVVEVfREVDTEFSQVRJT04pOwotICAgICAgICBsZW4gPSBjb21wb25lbnRzRXh0LmdldExlbmd0aCgpOwotCi0gICAgICAgIGZvciAoaW50IGk9MDsgaTxsZW47IGkrPSAyKSB7Ci0gICAgICAgICAgICBmaW5hbCBTdHJpbmcga2V5ID0gKFN0cmluZykgY29tcG9uZW50c0V4dC5pdGVtKGkpOwotICAgICAgICAgICAgZmluYWwgaW50IGluZGV4ID0ga2V5LmluZGV4T2YoJywnKTsKLSAgICAgICAgICAgIGZpbmFsIFN0cmluZyBsb2NhdGlvbiA9IGtleS5zdWJzdHJpbmcoMCwgaW5kZXgpOwotICAgICAgICAgICAgZmluYWwgU3RyaW5nIG5hbWUgPSBrZXkuc3Vic3RyaW5nKGluZGV4ICsgMSwga2V5Lmxlbmd0aCgpKTsKLQotICAgICAgICAgICAgc3JjRGVjbCA9IChYU0F0dHJpYnV0ZURlY2wpY29tcG9uZW50c0V4dC5pdGVtKGkrMSk7Ci0gICAgICAgICAgICBkc3REZWNsID0gZHN0R3JhbW1hci5nZXRHbG9iYWxBdHRyaWJ1dGVEZWNsKG5hbWUsIGxvY2F0aW9uKTsKLSAgICAgICAgICAgIGlmIChkc3REZWNsID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBkc3RHcmFtbWFyLmFkZEdsb2JhbEF0dHJpYnV0ZURlY2woc3JjRGVjbCwgbG9jYXRpb24pOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gUkVWSVNJVCAtIGRvIHdlIHJlcG9ydCBhbiBlcnJvcj8KLSAgICAgICAgICAgIGVsc2UgaWYgKGRzdERlY2wgIT0gc3JjRGVjbCkgewotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIGFkZEdsb2JhbEF0dHJpYnV0ZUdyb3VwRGVjbHMoU2NoZW1hR3JhbW1hciBzcmNHcmFtbWFyLCBTY2hlbWFHcmFtbWFyIGRzdEdyYW1tYXIpIHsKLSAgICAgICAgWFNOYW1lZE1hcCBjb21wb25lbnRzID0gc3JjR3JhbW1hci5nZXRDb21wb25lbnRzKFhTQ29uc3RhbnRzLkFUVFJJQlVURV9HUk9VUCk7Ci0gICAgICAgIGludCBsZW4gPSBjb21wb25lbnRzLmdldExlbmd0aCgpOwotICAgICAgICBYU0F0dHJpYnV0ZUdyb3VwRGVjbCBzcmNEZWNsLCBkc3REZWNsOwotCi0gICAgICAgIC8vIGFkZCBnbG9iYWwgY29tcG9uZW50cwotICAgICAgICBmb3IgKGludCBpPTA7IGk8bGVuOyBpKyspIHsKLSAgICAgICAgICAgIHNyY0RlY2wgPSAoWFNBdHRyaWJ1dGVHcm91cERlY2wpIGNvbXBvbmVudHMuaXRlbShpKTsKLSAgICAgICAgICAgIGRzdERlY2wgPSBkc3RHcmFtbWFyLmdldEdsb2JhbEF0dHJpYnV0ZUdyb3VwRGVjbChzcmNEZWNsLmdldE5hbWUoKSk7Ci0gICAgICAgICAgICBpZiAoZHN0RGVjbCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZHN0R3JhbW1hci5hZGRHbG9iYWxBdHRyaWJ1dGVHcm91cERlY2woc3JjRGVjbCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChkc3REZWNsICE9IHNyY0RlY2wgJiYgIWZUb2xlcmF0ZUR1cGxpY2F0ZXMpIHsKLSAgICAgICAgICAgICAgICByZXBvcnRTaGFyaW5nRXJyb3Ioc3JjRGVjbC5nZXROYW1lc3BhY2UoKSwgc3JjRGVjbC5nZXROYW1lKCkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gYWRkIGFueSBleHRlbmRlZCAoZHVwbGljYXRlKSBnbG9iYWwgY29tcG9uZW50cwotICAgICAgICBPYmplY3RMaXN0IGNvbXBvbmVudHNFeHQgPSBzcmNHcmFtbWFyLmdldENvbXBvbmVudHNFeHQoWFNDb25zdGFudHMuQVRUUklCVVRFX0dST1VQKTsKLSAgICAgICAgbGVuID0gY29tcG9uZW50c0V4dC5nZXRMZW5ndGgoKTsKLQotICAgICAgICBmb3IgKGludCBpPTA7IGk8bGVuOyBpKz0gMikgewotICAgICAgICAgICAgZmluYWwgU3RyaW5nIGtleSA9IChTdHJpbmcpIGNvbXBvbmVudHNFeHQuaXRlbShpKTsKLSAgICAgICAgICAgIGZpbmFsIGludCBpbmRleCA9IGtleS5pbmRleE9mKCcsJyk7Ci0gICAgICAgICAgICBmaW5hbCBTdHJpbmcgbG9jYXRpb24gPSBrZXkuc3Vic3RyaW5nKDAsIGluZGV4KTsKLSAgICAgICAgICAgIGZpbmFsIFN0cmluZyBuYW1lID0ga2V5LnN1YnN0cmluZyhpbmRleCArIDEsIGtleS5sZW5ndGgoKSk7Ci0KLSAgICAgICAgICAgIHNyY0RlY2wgPSAoWFNBdHRyaWJ1dGVHcm91cERlY2wpY29tcG9uZW50c0V4dC5pdGVtKGkrMSk7Ci0gICAgICAgICAgICBkc3REZWNsID0gZHN0R3JhbW1hci5nZXRHbG9iYWxBdHRyaWJ1dGVHcm91cERlY2wobmFtZSwgbG9jYXRpb24pOwotICAgICAgICAgICAgaWYgKGRzdERlY2wgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGRzdEdyYW1tYXIuYWRkR2xvYmFsQXR0cmlidXRlR3JvdXBEZWNsKHNyY0RlY2wsIGxvY2F0aW9uKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIFJFVklTSVQgLSBkbyB3ZSByZXBvcnQgYW4gZXJyb3I/Ci0gICAgICAgICAgICBlbHNlIGlmIChkc3REZWNsICE9IHNyY0RlY2wpIHsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBhZGRHbG9iYWxOb3RhdGlvbkRlY2xzKFNjaGVtYUdyYW1tYXIgc3JjR3JhbW1hciwgU2NoZW1hR3JhbW1hciBkc3RHcmFtbWFyKSB7Ci0gICAgICAgIFhTTmFtZWRNYXAgY29tcG9uZW50cyA9IHNyY0dyYW1tYXIuZ2V0Q29tcG9uZW50cyhYU0NvbnN0YW50cy5OT1RBVElPTl9ERUNMQVJBVElPTik7Ci0gICAgICAgIGludCBsZW4gPSBjb21wb25lbnRzLmdldExlbmd0aCgpOwotICAgICAgICBYU05vdGF0aW9uRGVjbCBzcmNEZWNsLCBkc3REZWNsOwotCi0gICAgICAgIC8vIGFkZCBnbG9iYWwgY29tcG9uZW50cwotICAgICAgICBmb3IgKGludCBpPTA7IGk8bGVuOyBpKyspIHsKLSAgICAgICAgICAgIHNyY0RlY2wgPSAoWFNOb3RhdGlvbkRlY2wpIGNvbXBvbmVudHMuaXRlbShpKTsKLSAgICAgICAgICAgIGRzdERlY2wgPSBkc3RHcmFtbWFyLmdldEdsb2JhbE5vdGF0aW9uRGVjbChzcmNEZWNsLmdldE5hbWUoKSk7Ci0gICAgICAgICAgICBpZiAoZHN0RGVjbCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZHN0R3JhbW1hci5hZGRHbG9iYWxOb3RhdGlvbkRlY2woc3JjRGVjbCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChkc3REZWNsICE9IHNyY0RlY2wgJiYgIWZUb2xlcmF0ZUR1cGxpY2F0ZXMpIHsKLSAgICAgICAgICAgICAgICByZXBvcnRTaGFyaW5nRXJyb3Ioc3JjRGVjbC5nZXROYW1lc3BhY2UoKSwgc3JjRGVjbC5nZXROYW1lKCkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gYWRkIGFueSBleHRlbmRlZCAoZHVwbGljYXRlKSBnbG9iYWwgY29tcG9uZW50cwotICAgICAgICBPYmplY3RMaXN0IGNvbXBvbmVudHNFeHQgPSBzcmNHcmFtbWFyLmdldENvbXBvbmVudHNFeHQoWFNDb25zdGFudHMuTk9UQVRJT05fREVDTEFSQVRJT04pOwotICAgICAgICBsZW4gPSBjb21wb25lbnRzRXh0LmdldExlbmd0aCgpOwotCi0gICAgICAgIGZvciAoaW50IGk9MDsgaTxsZW47IGkrPSAyKSB7Ci0gICAgICAgICAgICBmaW5hbCBTdHJpbmcga2V5ID0gKFN0cmluZykgY29tcG9uZW50c0V4dC5pdGVtKGkpOwotICAgICAgICAgICAgZmluYWwgaW50IGluZGV4ID0ga2V5LmluZGV4T2YoJywnKTsKLSAgICAgICAgICAgIGZpbmFsIFN0cmluZyBsb2NhdGlvbiA9IGtleS5zdWJzdHJpbmcoMCwgaW5kZXgpOwotICAgICAgICAgICAgZmluYWwgU3RyaW5nIG5hbWUgPSBrZXkuc3Vic3RyaW5nKGluZGV4ICsgMSwga2V5Lmxlbmd0aCgpKTsKLQotICAgICAgICAgICAgc3JjRGVjbCA9IChYU05vdGF0aW9uRGVjbCljb21wb25lbnRzRXh0Lml0ZW0oaSsxKTsKLSAgICAgICAgICAgIGRzdERlY2wgPSBkc3RHcmFtbWFyLmdldEdsb2JhbE5vdGF0aW9uRGVjbChuYW1lLCBsb2NhdGlvbik7Ci0gICAgICAgICAgICBpZiAoZHN0RGVjbCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZHN0R3JhbW1hci5hZGRHbG9iYWxOb3RhdGlvbkRlY2woc3JjRGVjbCwgbG9jYXRpb24pOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gUkVWSVNJVCAtIGRvIHdlIHJlcG9ydCBhbiBlcnJvcj8KLSAgICAgICAgICAgIGVsc2UgaWYgKGRzdERlY2wgIT0gc3JjRGVjbCkgewotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIGFkZEdsb2JhbEdyb3VwRGVjbHMoU2NoZW1hR3JhbW1hciBzcmNHcmFtbWFyLCBTY2hlbWFHcmFtbWFyIGRzdEdyYW1tYXIpIHsKLSAgICAgICAgWFNOYW1lZE1hcCBjb21wb25lbnRzID0gc3JjR3JhbW1hci5nZXRDb21wb25lbnRzKFhTQ29uc3RhbnRzLk1PREVMX0dST1VQX0RFRklOSVRJT04pOwotICAgICAgICBpbnQgbGVuID0gY29tcG9uZW50cy5nZXRMZW5ndGgoKTsKLSAgICAgICAgWFNHcm91cERlY2wgc3JjRGVjbCwgZHN0RGVjbDsKLQotICAgICAgICAvLyBhZGQgZ2xvYmFsIGNvbXBvbmVudHMKLSAgICAgICAgZm9yIChpbnQgaT0wOyBpPGxlbjsgaSsrKSB7Ci0gICAgICAgICAgICBzcmNEZWNsID0gKFhTR3JvdXBEZWNsKSBjb21wb25lbnRzLml0ZW0oaSk7Ci0gICAgICAgICAgICBkc3REZWNsID0gZHN0R3JhbW1hci5nZXRHbG9iYWxHcm91cERlY2woc3JjRGVjbC5nZXROYW1lKCkpOwotICAgICAgICAgICAgaWYgKGRzdERlY2wgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGRzdEdyYW1tYXIuYWRkR2xvYmFsR3JvdXBEZWNsKHNyY0RlY2wpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoc3JjRGVjbCAhPSBkc3REZWNsICYmICFmVG9sZXJhdGVEdXBsaWNhdGVzKSB7Ci0gICAgICAgICAgICAgICAgcmVwb3J0U2hhcmluZ0Vycm9yKHNyY0RlY2wuZ2V0TmFtZXNwYWNlKCksIHNyY0RlY2wuZ2V0TmFtZSgpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIGFkZCBhbnkgZXh0ZW5kZWQgKGR1cGxpY2F0ZSkgZ2xvYmFsIGNvbXBvbmVudHMKLSAgICAgICAgT2JqZWN0TGlzdCBjb21wb25lbnRzRXh0ID0gc3JjR3JhbW1hci5nZXRDb21wb25lbnRzRXh0KFhTQ29uc3RhbnRzLk1PREVMX0dST1VQX0RFRklOSVRJT04pOwotICAgICAgICBsZW4gPSBjb21wb25lbnRzRXh0LmdldExlbmd0aCgpOwotCi0gICAgICAgIGZvciAoaW50IGk9MDsgaTxsZW47IGkrPSAyKSB7Ci0gICAgICAgICAgICBmaW5hbCBTdHJpbmcga2V5ID0gKFN0cmluZykgY29tcG9uZW50c0V4dC5pdGVtKGkpOwotICAgICAgICAgICAgZmluYWwgaW50IGluZGV4ID0ga2V5LmluZGV4T2YoJywnKTsKLSAgICAgICAgICAgIGZpbmFsIFN0cmluZyBsb2NhdGlvbiA9IGtleS5zdWJzdHJpbmcoMCwgaW5kZXgpOwotICAgICAgICAgICAgZmluYWwgU3RyaW5nIG5hbWUgPSBrZXkuc3Vic3RyaW5nKGluZGV4ICsgMSwga2V5Lmxlbmd0aCgpKTsKLQotICAgICAgICAgICAgc3JjRGVjbCA9IChYU0dyb3VwRGVjbCljb21wb25lbnRzRXh0Lml0ZW0oaSsxKTsKLSAgICAgICAgICAgIGRzdERlY2wgPSBkc3RHcmFtbWFyLmdldEdsb2JhbEdyb3VwRGVjbChuYW1lLCBsb2NhdGlvbik7Ci0gICAgICAgICAgICBpZiAoZHN0RGVjbCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZHN0R3JhbW1hci5hZGRHbG9iYWxHcm91cERlY2woc3JjRGVjbCwgbG9jYXRpb24pOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gUkVWSVNUIC0gZG8gd2UgcmVwb3J0IGFuIGVycm9yPwotICAgICAgICAgICAgZWxzZSBpZiAoZHN0RGVjbCAhPSBzcmNEZWNsKSB7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgYWRkR2xvYmFsVHlwZURlY2xzKFNjaGVtYUdyYW1tYXIgc3JjR3JhbW1hciwgU2NoZW1hR3JhbW1hciBkc3RHcmFtbWFyKSB7Ci0gICAgICAgIFhTTmFtZWRNYXAgY29tcG9uZW50cyA9IHNyY0dyYW1tYXIuZ2V0Q29tcG9uZW50cyhYU0NvbnN0YW50cy5UWVBFX0RFRklOSVRJT04pOwotICAgICAgICBpbnQgbGVuID0gY29tcG9uZW50cy5nZXRMZW5ndGgoKTsKLSAgICAgICAgWFNUeXBlRGVmaW5pdGlvbiBzcmNEZWNsLCBkc3REZWNsOwotCi0gICAgICAgIC8vIGFkZCBnbG9iYWwgY29tcG9uZW50cwotICAgICAgICBmb3IgKGludCBpPTA7IGk8bGVuOyBpKyspIHsKLSAgICAgICAgICAgIHNyY0RlY2wgPSAoWFNUeXBlRGVmaW5pdGlvbikgY29tcG9uZW50cy5pdGVtKGkpOwotICAgICAgICAgICAgZHN0RGVjbCA9IGRzdEdyYW1tYXIuZ2V0R2xvYmFsVHlwZURlY2woc3JjRGVjbC5nZXROYW1lKCkpOwotICAgICAgICAgICAgaWYgKGRzdERlY2wgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGRzdEdyYW1tYXIuYWRkR2xvYmFsVHlwZURlY2woc3JjRGVjbCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChkc3REZWNsICE9IHNyY0RlY2wgJiYgIWZUb2xlcmF0ZUR1cGxpY2F0ZXMpIHsKLSAgICAgICAgICAgICAgICByZXBvcnRTaGFyaW5nRXJyb3Ioc3JjRGVjbC5nZXROYW1lc3BhY2UoKSwgc3JjRGVjbC5nZXROYW1lKCkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gYWRkIGFueSBleHRlbmRlZCAoZHVwbGljYXRlKSBnbG9iYWwgY29tcG9uZW50cwotICAgICAgICBPYmplY3RMaXN0IGNvbXBvbmVudHNFeHQgPSBzcmNHcmFtbWFyLmdldENvbXBvbmVudHNFeHQoWFNDb25zdGFudHMuVFlQRV9ERUZJTklUSU9OKTsKLSAgICAgICAgbGVuID0gY29tcG9uZW50c0V4dC5nZXRMZW5ndGgoKTsKLQotICAgICAgICBmb3IgKGludCBpPTA7IGk8bGVuOyBpKz0gMikgewotICAgICAgICAgICAgZmluYWwgU3RyaW5nIGtleSA9IChTdHJpbmcpIGNvbXBvbmVudHNFeHQuaXRlbShpKTsKLSAgICAgICAgICAgIGZpbmFsIGludCBpbmRleCA9IGtleS5pbmRleE9mKCcsJyk7Ci0gICAgICAgICAgICBmaW5hbCBTdHJpbmcgbG9jYXRpb24gPSBrZXkuc3Vic3RyaW5nKDAsIGluZGV4KTsKLSAgICAgICAgICAgIGZpbmFsIFN0cmluZyBuYW1lID0ga2V5LnN1YnN0cmluZyhpbmRleCArIDEsIGtleS5sZW5ndGgoKSk7Ci0KLSAgICAgICAgICAgIHNyY0RlY2wgPSAoWFNUeXBlRGVmaW5pdGlvbiljb21wb25lbnRzRXh0Lml0ZW0oaSsxKTsKLSAgICAgICAgICAgIGRzdERlY2wgPSBkc3RHcmFtbWFyLmdldEdsb2JhbFR5cGVEZWNsKG5hbWUsIGxvY2F0aW9uKTsKLSAgICAgICAgICAgIGlmIChkc3REZWNsID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBkc3RHcmFtbWFyLmFkZEdsb2JhbFR5cGVEZWNsKHNyY0RlY2wsIGxvY2F0aW9uKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIFJFVklTSVQgLSBkbyB3ZSByZXBvcnQgYW4gZXJyb3I/Ci0gICAgICAgICAgICBlbHNlIGlmIChkc3REZWNsICE9IHNyY0RlY2wpIHsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIHByaXZhdGUgVmVjdG9yIGV4cGFuZENvbXBvbmVudHMoWFNPYmplY3RbXSBjb21wb25lbnRzLCBNYXA8U3RyaW5nLCBWZWN0b3I+IGRlcGVuZGVuY2llcykgewotICAgICAgICBWZWN0b3IgbmV3Q29tcG9uZW50cyA9IG5ldyBWZWN0b3IoKTsKLQotICAgICAgICBmb3IgKGludCBpPTA7IGk8Y29tcG9uZW50cy5sZW5ndGg7IGkrKykgewotICAgICAgICAgICAgaWYgKCFuZXdDb21wb25lbnRzLmNvbnRhaW5zKGNvbXBvbmVudHNbaV0pKSB7Ci0gICAgICAgICAgICAgICAgbmV3Q29tcG9uZW50cy5hZGQoY29tcG9uZW50c1tpXSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBmb3IgKGludCBpPTA7IGk8bmV3Q29tcG9uZW50cy5zaXplKCk7IGkrKykgewotICAgICAgICAgICAgZmluYWwgWFNPYmplY3QgY29tcG9uZW50ID0gKFhTT2JqZWN0KSBuZXdDb21wb25lbnRzLmVsZW1lbnRBdChpKTsKLSAgICAgICAgICAgIGV4cGFuZFJlbGF0ZWRDb21wb25lbnRzKGNvbXBvbmVudCwgbmV3Q29tcG9uZW50cywgZGVwZW5kZW5jaWVzKTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBuZXdDb21wb25lbnRzOwotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBleHBhbmRSZWxhdGVkQ29tcG9uZW50cyhYU09iamVjdCBjb21wb25lbnQsIFZlY3RvciBjb21wb25lbnRMaXN0LCBNYXA8U3RyaW5nLCBWZWN0b3I+IGRlcGVuZGVuY2llcykgewotICAgICAgICBzaG9ydCBjb21wb25lbnRUeXBlID0gY29tcG9uZW50LmdldFR5cGUoKTsKLSAgICAgICAgc3dpdGNoIChjb21wb25lbnRUeXBlKSB7Ci0gICAgICAgIGNhc2UgWFNDb25zdGFudHMuVFlQRV9ERUZJTklUSU9OIDoKLSAgICAgICAgICAgIGV4cGFuZFJlbGF0ZWRUeXBlQ29tcG9uZW50cygoWFNUeXBlRGVmaW5pdGlvbikgY29tcG9uZW50LCBjb21wb25lbnRMaXN0LCBjb21wb25lbnQuZ2V0TmFtZXNwYWNlKCksIGRlcGVuZGVuY2llcyk7Ci0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBYU0NvbnN0YW50cy5BVFRSSUJVVEVfREVDTEFSQVRJT04gOgotICAgICAgICAgICAgZXhwYW5kUmVsYXRlZEF0dHJpYnV0ZUNvbXBvbmVudHMoKFhTQXR0cmlidXRlRGVjbGFyYXRpb24pIGNvbXBvbmVudCwgY29tcG9uZW50TGlzdCwgY29tcG9uZW50LmdldE5hbWVzcGFjZSgpLCBkZXBlbmRlbmNpZXMpOwotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgWFNDb25zdGFudHMuQVRUUklCVVRFX0dST1VQIDoKLSAgICAgICAgICAgIGV4cGFuZFJlbGF0ZWRBdHRyaWJ1dGVHcm91cENvbXBvbmVudHMoKFhTQXR0cmlidXRlR3JvdXBEZWZpbml0aW9uKSBjb21wb25lbnQsIGNvbXBvbmVudExpc3QsIGNvbXBvbmVudC5nZXROYW1lc3BhY2UoKSwgZGVwZW5kZW5jaWVzKTsKLSAgICAgICAgY2FzZSBYU0NvbnN0YW50cy5FTEVNRU5UX0RFQ0xBUkFUSU9OIDoKLSAgICAgICAgICAgIGV4cGFuZFJlbGF0ZWRFbGVtZW50Q29tcG9uZW50cygoWFNFbGVtZW50RGVjbGFyYXRpb24pIGNvbXBvbmVudCwgY29tcG9uZW50TGlzdCwgY29tcG9uZW50LmdldE5hbWVzcGFjZSgpLCBkZXBlbmRlbmNpZXMpOwotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgWFNDb25zdGFudHMuTU9ERUxfR1JPVVBfREVGSU5JVElPTiA6Ci0gICAgICAgICAgICBleHBhbmRSZWxhdGVkTW9kZWxHcm91cERlZmluaXRpb25Db21wb25lbnRzKChYU01vZGVsR3JvdXBEZWZpbml0aW9uKSBjb21wb25lbnQsIGNvbXBvbmVudExpc3QsIGNvbXBvbmVudC5nZXROYW1lc3BhY2UoKSwgZGVwZW5kZW5jaWVzKTsKLSAgICAgICAgY2FzZSBYU0NvbnN0YW50cy5BVFRSSUJVVEVfVVNFIDoKLSAgICAgICAgICAgIC8vZXhwYW5kUmVsYXRlZEF0dHJpYnV0ZVVzZUNvbXBvbmVudHMoKFhTQXR0cmlidXRlVXNlKWNvbXBvbmVudCwgY29tcG9uZW50TGlzdCwgZGVwZW5kZW5jaWVzKTsKLSAgICAgICAgY2FzZSBYU0NvbnN0YW50cy5OT1RBVElPTl9ERUNMQVJBVElPTiA6Ci0gICAgICAgIGNhc2UgWFNDb25zdGFudHMuSURFTlRJVFlfQ09OU1RSQUlOVCA6Ci0gICAgICAgIGRlZmF1bHQgOgotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgZXhwYW5kUmVsYXRlZEF0dHJpYnV0ZUNvbXBvbmVudHMoWFNBdHRyaWJ1dGVEZWNsYXJhdGlvbiBkZWNsLCBWZWN0b3IgY29tcG9uZW50TGlzdCwgU3RyaW5nIG5hbWVzcGFjZSwgTWFwPFN0cmluZywgVmVjdG9yPiBkZXBlbmRlbmNpZXMpIHsKLSAgICAgICAgYWRkUmVsYXRlZFR5cGUoZGVjbC5nZXRUeXBlRGVmaW5pdGlvbigpLCBjb21wb25lbnRMaXN0LCBuYW1lc3BhY2UsIGRlcGVuZGVuY2llcyk7Ci0KLSAgICAgICAgLypmaW5hbCBYU0NvbXBsZXhUeXBlRGVmaW5pdGlvbiBlbmNsb3NpbmdUeXBlID0gZGVjbC5nZXRFbmNsb3NpbmdDVERlZmluaXRpb24oKTsKLSAgICAgICAgaWYgKGVuY2xvc2luZ1R5cGUgIT0gbnVsbCkgewotICAgICAgICAgICAgYWRkUmVsYXRlZFR5cGUoZW5jbG9zaW5nVHlwZSwgY29tcG9uZW50TGlzdCwgbmFtZXNwYWNlLCBkZXBlbmRlbmNpZXMpOwotICAgICAgICB9Ki8KLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgZXhwYW5kUmVsYXRlZEVsZW1lbnRDb21wb25lbnRzKFhTRWxlbWVudERlY2xhcmF0aW9uIGRlY2wsIFZlY3RvciBjb21wb25lbnRMaXN0LCBTdHJpbmcgbmFtZXNwYWNlLCBNYXA8U3RyaW5nLCBWZWN0b3I+IGRlcGVuZGVuY2llcykgewotICAgICAgICBhZGRSZWxhdGVkVHlwZShkZWNsLmdldFR5cGVEZWZpbml0aW9uKCksIGNvbXBvbmVudExpc3QsIG5hbWVzcGFjZSwgZGVwZW5kZW5jaWVzKTsKLQotICAgICAgICAvKmZpbmFsIFhTVHlwZURlZmluaXRpb24gZW5jbG9zaW5nVHlwZSA9IGRlY2wuZ2V0RW5jbG9zaW5nQ1REZWZpbml0aW9uKCk7Ci0gICAgICAgIGlmIChlbmNsb3NpbmdUeXBlICE9IG51bGwpIHsKLSAgICAgICAgICAgIGFkZFJlbGF0ZWRUeXBlKGVuY2xvc2luZ1R5cGUsIGNvbXBvbmVudExpc3QsIG5hbWVzcGFjZSwgZGVwZW5kZW5jaWVzKTsKLSAgICAgICAgfSovCi0KLSAgICAgICAgZmluYWwgWFNFbGVtZW50RGVjbGFyYXRpb24gc3ViRWxlbURlY2wgPSBkZWNsLmdldFN1YnN0aXR1dGlvbkdyb3VwQWZmaWxpYXRpb24oKTsKLSAgICAgICAgaWYgKHN1YkVsZW1EZWNsICE9IG51bGwpIHsKLSAgICAgICAgICAgIGFkZFJlbGF0ZWRFbGVtZW50KHN1YkVsZW1EZWNsLCBjb21wb25lbnRMaXN0LCBuYW1lc3BhY2UsIGRlcGVuZGVuY2llcyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgZXhwYW5kUmVsYXRlZFR5cGVDb21wb25lbnRzKFhTVHlwZURlZmluaXRpb24gdHlwZSwgVmVjdG9yIGNvbXBvbmVudExpc3QsIFN0cmluZyBuYW1lc3BhY2UsIE1hcDxTdHJpbmcsIFZlY3Rvcj4gZGVwZW5kZW5jaWVzKSB7Ci0gICAgICAgIGlmICh0eXBlIGluc3RhbmNlb2YgWFNDb21wbGV4VHlwZURlY2wpIHsKLSAgICAgICAgICAgIGV4cGFuZFJlbGF0ZWRDb21wbGV4VHlwZUNvbXBvbmVudHMoKFhTQ29tcGxleFR5cGVEZWNsKSB0eXBlLCBjb21wb25lbnRMaXN0LCBuYW1lc3BhY2UsIGRlcGVuZGVuY2llcyk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAodHlwZSBpbnN0YW5jZW9mIFhTU2ltcGxlVHlwZURlY2wpIHsKLSAgICAgICAgICAgIGV4cGFuZFJlbGF0ZWRTaW1wbGVUeXBlQ29tcG9uZW50cygoWFNTaW1wbGVUeXBlRGVmaW5pdGlvbikgdHlwZSwgY29tcG9uZW50TGlzdCwgbmFtZXNwYWNlLCBkZXBlbmRlbmNpZXMpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIGV4cGFuZFJlbGF0ZWRNb2RlbEdyb3VwRGVmaW5pdGlvbkNvbXBvbmVudHMoWFNNb2RlbEdyb3VwRGVmaW5pdGlvbiBtb2RlbEdyb3VwRGVmLCBWZWN0b3IgY29tcG9uZW50TGlzdCwKLSAgICAgICAgICAgIFN0cmluZyBuYW1lc3BhY2UsIE1hcDxTdHJpbmcsIFZlY3Rvcj4gZGVwZW5kZW5jaWVzKSB7Ci0gICAgICAgIGV4cGFuZFJlbGF0ZWRNb2RlbEdyb3VwQ29tcG9uZW50cyhtb2RlbEdyb3VwRGVmLmdldE1vZGVsR3JvdXAoKSwgY29tcG9uZW50TGlzdCwgbmFtZXNwYWNlLCBkZXBlbmRlbmNpZXMpOwotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBleHBhbmRSZWxhdGVkQXR0cmlidXRlR3JvdXBDb21wb25lbnRzKFhTQXR0cmlidXRlR3JvdXBEZWZpbml0aW9uIGF0dHJHcm91cCwgVmVjdG9yIGNvbXBvbmVudExpc3QKLSAgICAgICAgICAgICwgU3RyaW5nIG5hbWVzcGFjZSwgTWFwPFN0cmluZywgVmVjdG9yPiBkZXBlbmRlbmNpZXMpIHsKLSAgICAgICAgZXhwYW5kUmVsYXRlZEF0dHJpYnV0ZVVzZXNDb21wb25lbnRzKGF0dHJHcm91cC5nZXRBdHRyaWJ1dGVVc2VzKCksIGNvbXBvbmVudExpc3QsIG5hbWVzcGFjZSwgZGVwZW5kZW5jaWVzKTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgZXhwYW5kUmVsYXRlZENvbXBsZXhUeXBlQ29tcG9uZW50cyhYU0NvbXBsZXhUeXBlRGVjbCB0eXBlLCBWZWN0b3IgY29tcG9uZW50TGlzdCwgU3RyaW5nIG5hbWVzcGFjZSwgTWFwPFN0cmluZywgVmVjdG9yPiBkZXBlbmRlbmNpZXMpIHsKLSAgICAgICAgYWRkUmVsYXRlZFR5cGUodHlwZS5nZXRCYXNlVHlwZSgpLCBjb21wb25lbnRMaXN0LCBuYW1lc3BhY2UsIGRlcGVuZGVuY2llcyk7Ci0gICAgICAgIGV4cGFuZFJlbGF0ZWRBdHRyaWJ1dGVVc2VzQ29tcG9uZW50cyh0eXBlLmdldEF0dHJpYnV0ZVVzZXMoKSwgY29tcG9uZW50TGlzdCwgbmFtZXNwYWNlLCBkZXBlbmRlbmNpZXMpOwotICAgICAgICBmaW5hbCBYU1BhcnRpY2xlIHBhcnRpY2xlID0gdHlwZS5nZXRQYXJ0aWNsZSgpOwotICAgICAgICBpZiAocGFydGljbGUgIT0gbnVsbCkgewotICAgICAgICAgICAgZXhwYW5kUmVsYXRlZFBhcnRpY2xlQ29tcG9uZW50cyhwYXJ0aWNsZSwgY29tcG9uZW50TGlzdCwgbmFtZXNwYWNlLCBkZXBlbmRlbmNpZXMpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIGV4cGFuZFJlbGF0ZWRTaW1wbGVUeXBlQ29tcG9uZW50cyhYU1NpbXBsZVR5cGVEZWZpbml0aW9uIHR5cGUsIFZlY3RvciBjb21wb25lbnRMaXN0LCBTdHJpbmcgbmFtZXNwYWNlLCBNYXA8U3RyaW5nLCBWZWN0b3I+IGRlcGVuZGVuY2llcykgewotICAgICAgICBmaW5hbCBYU1R5cGVEZWZpbml0aW9uIGJhc2VUeXBlID0gdHlwZS5nZXRCYXNlVHlwZSgpOwotICAgICAgICBpZiAoYmFzZVR5cGUgIT0gbnVsbCkgewotICAgICAgICAgICAgYWRkUmVsYXRlZFR5cGUoYmFzZVR5cGUsIGNvbXBvbmVudExpc3QsIG5hbWVzcGFjZSwgZGVwZW5kZW5jaWVzKTsKLSAgICAgICAgfQotCi0gICAgICAgIGZpbmFsIFhTVHlwZURlZmluaXRpb24gaXRlbVR5cGUgPSB0eXBlLmdldEl0ZW1UeXBlKCk7Ci0gICAgICAgIGlmIChpdGVtVHlwZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBhZGRSZWxhdGVkVHlwZShpdGVtVHlwZSwgY29tcG9uZW50TGlzdCwgbmFtZXNwYWNlLCBkZXBlbmRlbmNpZXMpOwotICAgICAgICB9Ci0KLSAgICAgICAgZmluYWwgWFNUeXBlRGVmaW5pdGlvbiBwcmltaXRpdmVUeXBlID0gdHlwZS5nZXRQcmltaXRpdmVUeXBlKCk7Ci0gICAgICAgIGlmIChwcmltaXRpdmVUeXBlICE9IG51bGwpIHsKLSAgICAgICAgICAgIGFkZFJlbGF0ZWRUeXBlKHByaW1pdGl2ZVR5cGUsIGNvbXBvbmVudExpc3QsIG5hbWVzcGFjZSwgZGVwZW5kZW5jaWVzKTsKLSAgICAgICAgfQotCi0gICAgICAgIGZpbmFsIFhTT2JqZWN0TGlzdCBtZW1iZXJUeXBlcyA9IHR5cGUuZ2V0TWVtYmVyVHlwZXMoKTsKLSAgICAgICAgaWYgKG1lbWJlclR5cGVzLnNpemUoKSA+IDApIHsKLSAgICAgICAgICAgIGZvciAoaW50IGk9MDsgaTxtZW1iZXJUeXBlcy5zaXplKCk7IGkrKykgewotICAgICAgICAgICAgICAgIGFkZFJlbGF0ZWRUeXBlKChYU1R5cGVEZWZpbml0aW9uKW1lbWJlclR5cGVzLml0ZW0oaSksIGNvbXBvbmVudExpc3QsIG5hbWVzcGFjZSwgZGVwZW5kZW5jaWVzKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBleHBhbmRSZWxhdGVkQXR0cmlidXRlVXNlc0NvbXBvbmVudHMoWFNPYmplY3RMaXN0IGF0dHJVc2VzLCBWZWN0b3IgY29tcG9uZW50TGlzdCwKLSAgICAgICAgICAgIFN0cmluZyBuYW1lc3BhY2UsIE1hcDxTdHJpbmcsIFZlY3Rvcj4gZGVwZW5kZW5jaWVzKSB7Ci0gICAgICAgIGZpbmFsIGludCBhdHRyVXNlU2l6ZSA9IChhdHRyVXNlcyA9PSBudWxsKSA/IDAgOiBhdHRyVXNlcy5zaXplKCk7Ci0gICAgICAgIGZvciAoaW50IGk9MDsgaTxhdHRyVXNlU2l6ZTsgaSsrKSB7Ci0gICAgICAgICAgICBleHBhbmRSZWxhdGVkQXR0cmlidXRlVXNlQ29tcG9uZW50cygoWFNBdHRyaWJ1dGVVc2UpYXR0clVzZXMuaXRlbShpKSwgY29tcG9uZW50TGlzdCwgbmFtZXNwYWNlLCBkZXBlbmRlbmNpZXMpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIGV4cGFuZFJlbGF0ZWRBdHRyaWJ1dGVVc2VDb21wb25lbnRzKFhTQXR0cmlidXRlVXNlIGNvbXBvbmVudCwgVmVjdG9yIGNvbXBvbmVudExpc3QsCi0gICAgICAgICAgICBTdHJpbmcgbmFtZXNwYWNlLCBNYXA8U3RyaW5nLCBWZWN0b3I+IGRlcGVuZGVuY2llcykgewotICAgICAgICBhZGRSZWxhdGVkQXR0cmlidXRlKGNvbXBvbmVudC5nZXRBdHRyRGVjbGFyYXRpb24oKSwgY29tcG9uZW50TGlzdCwgbmFtZXNwYWNlLCBkZXBlbmRlbmNpZXMpOwotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBleHBhbmRSZWxhdGVkUGFydGljbGVDb21wb25lbnRzKFhTUGFydGljbGUgY29tcG9uZW50LCBWZWN0b3IgY29tcG9uZW50TGlzdCwKLSAgICAgICAgICAgIFN0cmluZyBuYW1lc3BhY2UsIE1hcDxTdHJpbmcsIFZlY3Rvcj4gZGVwZW5kZW5jaWVzKSB7Ci0gICAgICAgIFhTVGVybSB0ZXJtID0gY29tcG9uZW50LmdldFRlcm0oKTsKLSAgICAgICAgc3dpdGNoICh0ZXJtLmdldFR5cGUoKSkgewotICAgICAgICBjYXNlIFhTQ29uc3RhbnRzLkVMRU1FTlRfREVDTEFSQVRJT04gOgotICAgICAgICAgICAgYWRkUmVsYXRlZEVsZW1lbnQoKFhTRWxlbWVudERlY2xhcmF0aW9uKSB0ZXJtLCBjb21wb25lbnRMaXN0LCBuYW1lc3BhY2UsIGRlcGVuZGVuY2llcyk7Ci0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBYU0NvbnN0YW50cy5NT0RFTF9HUk9VUCA6Ci0gICAgICAgICAgICBleHBhbmRSZWxhdGVkTW9kZWxHcm91cENvbXBvbmVudHMoKFhTTW9kZWxHcm91cCkgdGVybSwgY29tcG9uZW50TGlzdCwgbmFtZXNwYWNlLCBkZXBlbmRlbmNpZXMpOwotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGRlZmF1bHQ6Ci0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBleHBhbmRSZWxhdGVkTW9kZWxHcm91cENvbXBvbmVudHMoWFNNb2RlbEdyb3VwIG1vZGVsR3JvdXAsIFZlY3RvciBjb21wb25lbnRMaXN0LAotICAgICAgICAgICAgU3RyaW5nIG5hbWVzcGFjZSwgTWFwPFN0cmluZywgVmVjdG9yPiBkZXBlbmRlbmNpZXMpIHsKLSAgICAgICAgWFNPYmplY3RMaXN0IHBhcnRpY2xlcyA9IG1vZGVsR3JvdXAuZ2V0UGFydGljbGVzKCk7Ci0gICAgICAgIGZpbmFsIGludCBsZW5ndGggPSAocGFydGljbGVzID09IG51bGwpID8gMCA6IHBhcnRpY2xlcy5nZXRMZW5ndGgoKTsKLSAgICAgICAgZm9yIChpbnQgaT0wOyBpPGxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICBleHBhbmRSZWxhdGVkUGFydGljbGVDb21wb25lbnRzKChYU1BhcnRpY2xlKXBhcnRpY2xlcy5pdGVtKGkpLCBjb21wb25lbnRMaXN0LCBuYW1lc3BhY2UsIGRlcGVuZGVuY2llcyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgYWRkUmVsYXRlZFR5cGUoWFNUeXBlRGVmaW5pdGlvbiB0eXBlLCBWZWN0b3IgY29tcG9uZW50TGlzdCwgU3RyaW5nIG5hbWVzcGFjZSwgTWFwPFN0cmluZywgVmVjdG9yPiBkZXBlbmRlbmNpZXMpIHsKLSAgICAgICAgaWYgKCF0eXBlLmdldEFub255bW91cygpKSB7Ci0gICAgICAgICAgICBpZiAoIXR5cGUuZ2V0TmFtZXNwYWNlKCkuZXF1YWxzKFNjaGVtYVN5bWJvbHMuVVJJX1NDSEVNQUZPUlNDSEVNQSkpIHsgLy9SRVZJU0lUIC0gZG8gd2UgdXNlID09IGluc3RlYWQKLSAgICAgICAgICAgICAgICBpZiAoIWNvbXBvbmVudExpc3QuY29udGFpbnModHlwZSkpIHsKLSAgICAgICAgICAgICAgICAgICAgZmluYWwgVmVjdG9yIGltcG9ydGVkTmFtZXNwYWNlcyA9IGZpbmREZXBlbmRlbnROYW1lc3BhY2VzKG5hbWVzcGFjZSwgZGVwZW5kZW5jaWVzKTsKLSAgICAgICAgICAgICAgICAgICAgYWRkTmFtZXNwYWNlRGVwZW5kZW5jeShuYW1lc3BhY2UsIHR5cGUuZ2V0TmFtZXNwYWNlKCksIGltcG9ydGVkTmFtZXNwYWNlcyk7Ci0gICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudExpc3QuYWRkKHR5cGUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIGV4cGFuZFJlbGF0ZWRUeXBlQ29tcG9uZW50cyh0eXBlLCBjb21wb25lbnRMaXN0LCBuYW1lc3BhY2UsIGRlcGVuZGVuY2llcyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgYWRkUmVsYXRlZEVsZW1lbnQoWFNFbGVtZW50RGVjbGFyYXRpb24gZGVjbCwgVmVjdG9yIGNvbXBvbmVudExpc3QsIFN0cmluZyBuYW1lc3BhY2UsIE1hcDxTdHJpbmcsIFZlY3Rvcj4gZGVwZW5kZW5jaWVzKSB7Ci0gICAgICAgIGlmIChkZWNsLmdldFNjb3BlKCkgPT0gWFNDb25zdGFudHMuU0NPUEVfR0xPQkFMKSB7Ci0gICAgICAgICAgICBpZiAoIWNvbXBvbmVudExpc3QuY29udGFpbnMoZGVjbCkpIHsKLSAgICAgICAgICAgICAgICBWZWN0b3IgaW1wb3J0ZWROYW1lc3BhY2VzID0gZmluZERlcGVuZGVudE5hbWVzcGFjZXMobmFtZXNwYWNlLCBkZXBlbmRlbmNpZXMpOwotICAgICAgICAgICAgICAgIGFkZE5hbWVzcGFjZURlcGVuZGVuY3kobmFtZXNwYWNlLCBkZWNsLmdldE5hbWVzcGFjZSgpLCBpbXBvcnRlZE5hbWVzcGFjZXMpOwotICAgICAgICAgICAgICAgIGNvbXBvbmVudExpc3QuYWRkKGRlY2wpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgZXhwYW5kUmVsYXRlZEVsZW1lbnRDb21wb25lbnRzKGRlY2wsIGNvbXBvbmVudExpc3QsIG5hbWVzcGFjZSwgZGVwZW5kZW5jaWVzKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBhZGRSZWxhdGVkQXR0cmlidXRlKFhTQXR0cmlidXRlRGVjbGFyYXRpb24gZGVjbCwgVmVjdG9yIGNvbXBvbmVudExpc3QsIFN0cmluZyBuYW1lc3BhY2UsIE1hcDxTdHJpbmcsIFZlY3Rvcj4gZGVwZW5kZW5jaWVzKSB7Ci0gICAgICAgIGlmIChkZWNsLmdldFNjb3BlKCkgPT0gWFNDb25zdGFudHMuU0NPUEVfR0xPQkFMKSB7Ci0gICAgICAgICAgICBpZiAoIWNvbXBvbmVudExpc3QuY29udGFpbnMoZGVjbCkpIHsKLSAgICAgICAgICAgICAgICBWZWN0b3IgaW1wb3J0ZWROYW1lc3BhY2VzID0gZmluZERlcGVuZGVudE5hbWVzcGFjZXMobmFtZXNwYWNlLCBkZXBlbmRlbmNpZXMpOwotICAgICAgICAgICAgICAgIGFkZE5hbWVzcGFjZURlcGVuZGVuY3kobmFtZXNwYWNlLCBkZWNsLmdldE5hbWVzcGFjZSgpLCBpbXBvcnRlZE5hbWVzcGFjZXMpOwotICAgICAgICAgICAgICAgIGNvbXBvbmVudExpc3QuYWRkKGRlY2wpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgZXhwYW5kUmVsYXRlZEF0dHJpYnV0ZUNvbXBvbmVudHMoZGVjbCwgY29tcG9uZW50TGlzdCwgbmFtZXNwYWNlLCBkZXBlbmRlbmNpZXMpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIGFkZEdsb2JhbENvbXBvbmVudHMoVmVjdG9yIGNvbXBvbmVudHMsIE1hcDxTdHJpbmcsIFZlY3Rvcj4gaW1wb3J0RGVwZW5kZW5jaWVzKSB7Ci0gICAgICAgIGZpbmFsIFhTRERlc2NyaXB0aW9uIGRlc2MgPSBuZXcgWFNERGVzY3JpcHRpb24oKTsKLSAgICAgICAgZmluYWwgaW50IHNpemUgPSBjb21wb25lbnRzLnNpemUoKTsKLQotICAgICAgICBmb3IgKGludCBpPTA7IGk8c2l6ZTsgaSsrKSB7Ci0gICAgICAgICAgICBhZGRHbG9iYWxDb21wb25lbnQoKFhTT2JqZWN0KSBjb21wb25lbnRzLmVsZW1lbnRBdChpKSwgZGVzYyk7Ci0gICAgICAgIH0KLSAgICAgICAgdXBkYXRlSW1wb3J0RGVwZW5kZW5jaWVzKGltcG9ydERlcGVuZGVuY2llcyk7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIGFkZEdsb2JhbENvbXBvbmVudChYU09iamVjdCBjb21wb25lbnQsIFhTRERlc2NyaXB0aW9uIGRlc2MpIHsKLSAgICAgICAgZmluYWwgU3RyaW5nIG5hbWVzcGFjZSA9IGNvbXBvbmVudC5nZXROYW1lc3BhY2UoKTsKLQotICAgICAgICBkZXNjLnNldE5hbWVzcGFjZShuYW1lc3BhY2UpOwotICAgICAgICBmaW5hbCBTY2hlbWFHcmFtbWFyIHNnID0gZ2V0U2NoZW1hR3JhbW1hcihkZXNjKTsKLQotICAgICAgICBzaG9ydCBjb21wb25lbnRUeXBlID0gY29tcG9uZW50LmdldFR5cGUoKTsKLSAgICAgICAgZmluYWwgU3RyaW5nIG5hbWUgPSBjb21wb25lbnQuZ2V0TmFtZSgpOwotCi0gICAgICAgIHN3aXRjaCAoY29tcG9uZW50VHlwZSkgewotICAgICAgICBjYXNlIFhTQ29uc3RhbnRzLlRZUEVfREVGSU5JVElPTiA6Ci0gICAgICAgICAgICBpZiAoISgoWFNUeXBlRGVmaW5pdGlvbikgY29tcG9uZW50KS5nZXRBbm9ueW1vdXMoKSkgewotICAgICAgICAgICAgICAgIGlmIChzZy5nZXRHbG9iYWxUeXBlRGVjbChuYW1lKSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIHNnLmFkZEdsb2JhbFR5cGVEZWNsKChYU1R5cGVEZWZpbml0aW9uKSBjb21wb25lbnQpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvLyBzdG9yZSB0aGUgZGVjbGFyYXRpb24gaW4gdGhlIGV4dGVuZGVkIG1hcCwgdXNpbmcgYW4gZW1wdHkgbG9jYXRpb24KLSAgICAgICAgICAgICAgICBpZiAoc2cuZ2V0R2xvYmFsVHlwZURlY2wobmFtZSwgIiIpID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgc2cuYWRkR2xvYmFsVHlwZURlY2woKFhTVHlwZURlZmluaXRpb24pIGNvbXBvbmVudCwgIiIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICBjYXNlIFhTQ29uc3RhbnRzLkFUVFJJQlVURV9ERUNMQVJBVElPTiA6Ci0gICAgICAgICAgICBpZiAoKChYU0F0dHJpYnV0ZURlY2wpIGNvbXBvbmVudCkuZ2V0U2NvcGUoKSA9PSBYU0F0dHJpYnV0ZURlY2wuU0NPUEVfR0xPQkFMKSB7Ci0gICAgICAgICAgICAgICAgaWYgKHNnLmdldEdsb2JhbEF0dHJpYnV0ZURlY2wobmFtZSkgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBzZy5hZGRHbG9iYWxBdHRyaWJ1dGVEZWNsKChYU0F0dHJpYnV0ZURlY2wpIGNvbXBvbmVudCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIC8vIHN0b3JlIHRoZSBkZWNsYXJhdGlvbiBpbiB0aGUgZXh0ZW5kZWQgbWFwLCB1c2luZyBhbiBlbXB0eSBsb2NhdGlvbgotICAgICAgICAgICAgICAgIGlmIChzZy5nZXRHbG9iYWxBdHRyaWJ1dGVEZWNsKG5hbWUsICIiKSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIHNnLmFkZEdsb2JhbEF0dHJpYnV0ZURlY2woKFhTQXR0cmlidXRlRGVjbCkgY29tcG9uZW50LCAiIik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgWFNDb25zdGFudHMuQVRUUklCVVRFX0dST1VQIDoKLSAgICAgICAgICAgIGlmIChzZy5nZXRHbG9iYWxBdHRyaWJ1dGVEZWNsKG5hbWUpID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBzZy5hZGRHbG9iYWxBdHRyaWJ1dGVHcm91cERlY2woKFhTQXR0cmlidXRlR3JvdXBEZWNsKSBjb21wb25lbnQpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gc3RvcmUgdGhlIGRlY2xhcmF0aW9uIGluIHRoZSBleHRlbmRlZCBtYXAsIHVzaW5nIGFuIGVtcHR5IGxvY2F0aW9uCi0gICAgICAgICAgICBpZiAoc2cuZ2V0R2xvYmFsQXR0cmlidXRlRGVjbChuYW1lLCAiIikgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHNnLmFkZEdsb2JhbEF0dHJpYnV0ZUdyb3VwRGVjbCgoWFNBdHRyaWJ1dGVHcm91cERlY2wpIGNvbXBvbmVudCwgIiIpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgWFNDb25zdGFudHMuRUxFTUVOVF9ERUNMQVJBVElPTiA6Ci0gICAgICAgICAgICBpZiAoKChYU0VsZW1lbnREZWNsKSBjb21wb25lbnQpLmdldFNjb3BlKCkgPT0gWFNFbGVtZW50RGVjbC5TQ09QRV9HTE9CQUwpIHsKLSAgICAgICAgICAgICAgICBzZy5hZGRHbG9iYWxFbGVtZW50RGVjbEFsbCgoWFNFbGVtZW50RGVjbCkgY29tcG9uZW50KTsKLQotICAgICAgICAgICAgICAgIGlmIChzZy5nZXRHbG9iYWxFbGVtZW50RGVjbChuYW1lKSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIHNnLmFkZEdsb2JhbEVsZW1lbnREZWNsKChYU0VsZW1lbnREZWNsKSBjb21wb25lbnQpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvLyBzdG9yZSB0aGUgZGVjbGFyYXRpb24gaW4gdGhlIGV4dGVuZGVkIG1hcCwgdXNpbmcgYW4gZW1wdHkgbG9jYXRpb24KLSAgICAgICAgICAgICAgICBpZiAoc2cuZ2V0R2xvYmFsRWxlbWVudERlY2wobmFtZSwgIiIpID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgc2cuYWRkR2xvYmFsRWxlbWVudERlY2woKFhTRWxlbWVudERlY2wpIGNvbXBvbmVudCwgIiIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICBjYXNlIFhTQ29uc3RhbnRzLk1PREVMX0dST1VQX0RFRklOSVRJT04gOgotICAgICAgICAgICAgaWYgKHNnLmdldEdsb2JhbEdyb3VwRGVjbChuYW1lKSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgc2cuYWRkR2xvYmFsR3JvdXBEZWNsKChYU0dyb3VwRGVjbCkgY29tcG9uZW50KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIHN0b3JlIHRoZSBkZWNsYXJhdGlvbiBpbiB0aGUgZXh0ZW5kZWQgbWFwLCB1c2luZyBhbiBlbXB0eSBsb2NhdGlvbgotICAgICAgICAgICAgaWYgKHNnLmdldEdsb2JhbEdyb3VwRGVjbChuYW1lLCAiIikgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHNnLmFkZEdsb2JhbEdyb3VwRGVjbCgoWFNHcm91cERlY2wpIGNvbXBvbmVudCwgIiIpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgWFNDb25zdGFudHMuTk9UQVRJT05fREVDTEFSQVRJT04gOgotICAgICAgICAgICAgaWYgKHNnLmdldEdsb2JhbE5vdGF0aW9uRGVjbChuYW1lKSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgc2cuYWRkR2xvYmFsTm90YXRpb25EZWNsKChYU05vdGF0aW9uRGVjbCkgY29tcG9uZW50KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIHN0b3JlIHRoZSBkZWNsYXJhdGlvbiBpbiB0aGUgZXh0ZW5kZWQgbWFwLCB1c2luZyBhbiBlbXB0eSBsb2NhdGlvbgotICAgICAgICAgICAgaWYgKHNnLmdldEdsb2JhbE5vdGF0aW9uRGVjbChuYW1lLCAiIikgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHNnLmFkZEdsb2JhbE5vdGF0aW9uRGVjbCgoWFNOb3RhdGlvbkRlY2wpIGNvbXBvbmVudCwgIiIpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgWFNDb25zdGFudHMuSURFTlRJVFlfQ09OU1RSQUlOVCA6Ci0gICAgICAgIGNhc2UgWFNDb25zdGFudHMuQVRUUklCVVRFX1VTRSA6Ci0gICAgICAgIGRlZmF1bHQgOgotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgdXBkYXRlSW1wb3J0RGVwZW5kZW5jaWVzKE1hcDxTdHJpbmcsIFZlY3Rvcj4gdGFibGUpIHsKLSAgICAgICAgaWYgKHRhYmxlID09IG51bGwpIHJldHVybjsKLSAgICAgICAgU3RyaW5nIG5hbWVzcGFjZTsKLSAgICAgICAgVmVjdG9yIGltcG9ydExpc3Q7Ci0KLSAgICAgICAgZm9yKE1hcC5FbnRyeTxTdHJpbmcsIFZlY3Rvcj4gZW50cnkgOiB0YWJsZS5lbnRyeVNldCgpKXsKLSAgICAgICAgICAgIG5hbWVzcGFjZSA9IGVudHJ5LmdldEtleSgpOwotICAgICAgICAgICAgaW1wb3J0TGlzdCA9IGVudHJ5LmdldFZhbHVlKCk7Ci0gICAgICAgICAgICBpZiAoaW1wb3J0TGlzdC5zaXplKCkgPiAwKSB7Ci0gICAgICAgICAgICAgICAgZXhwYW5kSW1wb3J0TGlzdChuYW1lc3BhY2UsIGltcG9ydExpc3QpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIGV4cGFuZEltcG9ydExpc3QoU3RyaW5nIG5hbWVzcGFjZSwgVmVjdG9yIG5hbWVzcGFjZUxpc3QpIHsKLSAgICAgICAgU2NoZW1hR3JhbW1hciBzZyA9IGZHcmFtbWFyQnVja2V0LmdldEdyYW1tYXIobmFtZXNwYWNlKTsKLSAgICAgICAgLy8gc2hvdWxkbid0IGJlIG51bGwKLSAgICAgICAgaWYgKHNnICE9IG51bGwpIHsKLSAgICAgICAgICAgIFZlY3RvciBpc2dzID0gc2cuZ2V0SW1wb3J0ZWRHcmFtbWFycygpOwotICAgICAgICAgICAgaWYgKGlzZ3MgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGlzZ3MgPSBuZXcgVmVjdG9yKCk7Ci0gICAgICAgICAgICAgICAgYWRkSW1wb3J0TGlzdChzZywgaXNncywgbmFtZXNwYWNlTGlzdCk7Ci0gICAgICAgICAgICAgICAgc2cuc2V0SW1wb3J0ZWRHcmFtbWFycyhpc2dzKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIHVwZGF0ZUltcG9ydExpc3Qoc2csIGlzZ3MsIG5hbWVzcGFjZUxpc3QpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIGFkZEltcG9ydExpc3QoU2NoZW1hR3JhbW1hciBzZywgVmVjdG9yIGltcG9ydGVkR3JhbW1hcnMsIFZlY3RvciBuYW1lc3BhY2VMaXN0KSB7Ci0gICAgICAgIGZpbmFsIGludCBzaXplID0gbmFtZXNwYWNlTGlzdC5zaXplKCk7Ci0gICAgICAgIFNjaGVtYUdyYW1tYXIgaXNnOwotCi0gICAgICAgIGZvciAoaW50IGk9MDsgaTxzaXplOyBpKyspIHsKLSAgICAgICAgICAgIGlzZyA9IGZHcmFtbWFyQnVja2V0LmdldEdyYW1tYXIoKFN0cmluZyluYW1lc3BhY2VMaXN0LmVsZW1lbnRBdChpKSk7Ci0gICAgICAgICAgICBpZiAoaXNnICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBpbXBvcnRlZEdyYW1tYXJzLmFkZChpc2cpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgLy9SRVZJU1Q6IHJlcG9ydCBhbiBlcnJvciBtZXNzYWdlCi0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgdXBkYXRlSW1wb3J0TGlzdChTY2hlbWFHcmFtbWFyIHNnLCBWZWN0b3IgaW1wb3J0ZWRHcmFtbWFycywgVmVjdG9yIG5hbWVzcGFjZUxpc3QpIHsKLSAgICAgICAgZmluYWwgaW50IHNpemUgPSBuYW1lc3BhY2VMaXN0LnNpemUoKTsKLSAgICAgICAgU2NoZW1hR3JhbW1hciBpc2c7Ci0KLSAgICAgICAgZm9yIChpbnQgaT0wOyBpPHNpemU7IGkrKykgewotICAgICAgICAgICAgaXNnID0gZkdyYW1tYXJCdWNrZXQuZ2V0R3JhbW1hcigoU3RyaW5nKW5hbWVzcGFjZUxpc3QuZWxlbWVudEF0KGkpKTsKLSAgICAgICAgICAgIGlmIChpc2cgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGlmICghY29udGFpbmVkSW1wb3J0ZWRHcmFtbWFyKGltcG9ydGVkR3JhbW1hcnMsIGlzZykpIHsKLSAgICAgICAgICAgICAgICAgICAgaW1wb3J0ZWRHcmFtbWFycy5hZGQoaXNnKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAvL1JFVklTVDogcmVwb3J0IGFuIGVycm9yIG1lc3NhZ2UKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIHByaXZhdGUgYm9vbGVhbiBjb250YWluZWRJbXBvcnRlZEdyYW1tYXIoVmVjdG9yIGltcG9ydGVkR3JhbW1hciwgU2NoZW1hR3JhbW1hciBncmFtbWFyKSB7Ci0gICAgICAgIGZpbmFsIGludCBzaXplID0gaW1wb3J0ZWRHcmFtbWFyLnNpemUoKTsKLSAgICAgICAgU2NoZW1hR3JhbW1hciBzZzsKLQotICAgICAgICBmb3IgKGludCBpPTA7IGk8c2l6ZTsgaSsrKSB7Ci0gICAgICAgICAgICBzZyA9IChTY2hlbWFHcmFtbWFyKSBpbXBvcnRlZEdyYW1tYXIuZWxlbWVudEF0KGkpOwotICAgICAgICAgICAgaWYgKG51bGwyRW1wdHlTdHJpbmcoc2cuZ2V0VGFyZ2V0TmFtZXNwYWNlKCkpLmVxdWFscyhudWxsMkVtcHR5U3RyaW5nKGdyYW1tYXIuZ2V0VGFyZ2V0TmFtZXNwYWNlKCkpKSkgewotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICAvLyBOT1RFOiBhbHdheXMgYXNzdW1pbmcgdGhhdCBmTmFtZXNwYWNlR3Jvd3RoIGlzIGVuYWJsZWQKLSAgICAvLyAgICAgICBvdGhlcndpc2UgdGhlIGdyYW1tYXIgc2hvdWxkIGhhdmUgZXhpc3RlZAotICAgIHByaXZhdGUgU2NoZW1hR3JhbW1hciBnZXRTY2hlbWFHcmFtbWFyKFhTRERlc2NyaXB0aW9uIGRlc2MpIHsKLSAgICAgICAgU2NoZW1hR3JhbW1hciBzZyA9IGZpbmRHcmFtbWFyKGRlc2MsIGZOYW1lc3BhY2VHcm93dGgpOwotCi0gICAgICAgIGlmIChzZyA9PSBudWxsKSB7Ci0gICAgICAgICAgICBzZyA9IG5ldyBTY2hlbWFHcmFtbWFyKGRlc2MuZ2V0TmFtZXNwYWNlKCksIGRlc2MubWFrZUNsb25lKCksIGZTeW1ib2xUYWJsZSk7Ci0gICAgICAgICAgICBmR3JhbW1hckJ1Y2tldC5wdXRHcmFtbWFyKHNnKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChzZy5pc0ltbXV0YWJsZSgpKXsKLSAgICAgICAgICAgIHNnID0gY3JlYXRlR3JhbW1hckZyb20oc2cpOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIHNnOwotICAgIH0KLQotICAgIHByaXZhdGUgVmVjdG9yIGZpbmREZXBlbmRlbnROYW1lc3BhY2VzKFN0cmluZyBuYW1lc3BhY2UsIE1hcCB0YWJsZSkgewotICAgICAgICBmaW5hbCBTdHJpbmcgbnMgPSBudWxsMkVtcHR5U3RyaW5nKG5hbWVzcGFjZSk7Ci0gICAgICAgIFZlY3RvciBuYW1lc3BhY2VMaXN0ID0gKFZlY3RvcikgZ2V0RnJvbU1hcCh0YWJsZSwgbnMpOwotCi0gICAgICAgIGlmIChuYW1lc3BhY2VMaXN0ID09IG51bGwpIHsKLSAgICAgICAgICAgIG5hbWVzcGFjZUxpc3QgPSBuZXcgVmVjdG9yKCk7Ci0gICAgICAgICAgICB0YWJsZS5wdXQobnMsIG5hbWVzcGFjZUxpc3QpOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIG5hbWVzcGFjZUxpc3Q7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIGFkZE5hbWVzcGFjZURlcGVuZGVuY3koU3RyaW5nIG5hbWVzcGFjZTEsIFN0cmluZyBuYW1lc3BhY2UyLCBWZWN0b3IgbGlzdCkgewotICAgICAgICBmaW5hbCBTdHJpbmcgbnMxID0gbnVsbDJFbXB0eVN0cmluZyhuYW1lc3BhY2UxKTsKLSAgICAgICAgZmluYWwgU3RyaW5nIG5zMiA9IG51bGwyRW1wdHlTdHJpbmcobmFtZXNwYWNlMik7Ci0gICAgICAgIGlmICghbnMxLmVxdWFscyhuczIpKSB7Ci0gICAgICAgICAgICBpZiAoIWxpc3QuY29udGFpbnMobnMyKSkgewotICAgICAgICAgICAgICAgIGxpc3QuYWRkKG5zMik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgcmVwb3J0U2hhcmluZ0Vycm9yKFN0cmluZyBuYW1lc3BhY2UsIFN0cmluZyBuYW1lKSB7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBxTmFtZSA9IChuYW1lc3BhY2UgPT0gbnVsbCkKLSAgICAgICAgICAgID8gIiwiICsgbmFtZSA6IG5hbWVzcGFjZSArICIsIiArIG5hbWU7Ci0KLSAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoInNjaC1wcm9wcy1jb3JyZWN0LjIiLCBuZXcgT2JqZWN0IFtdIHtxTmFtZX0sIG51bGwpOwotICAgIH0KLQotICAgIC8vIGluaXRpYWxpemUgYWxsIHRoZSB0cmF2ZXJzZXJzLgotICAgIC8vIHRoaXMgc2hvdWxkIG9ubHkgbmVlZCB0byBiZSBjYWxsZWQgb25jZSBkdXJpbmcgdGhlIGNvbnN0cnVjdGlvbgotICAgIC8vIG9mIHRoaXMgb2JqZWN0OyBpdCBjcmVhdGVzIHRoZSB0cmF2ZXJzZXJzIHRoYXQgd2lsbCBiZSB1c2VkIHRvCi0KLSAgICAvLyBjb25zdHJ1Y3Qgc2NoZW1hR3JhbW1hcnMuCi0gICAgcHJpdmF0ZSB2b2lkIGNyZWF0ZVRyYXZlcnNlcnMoKSB7Ci0gICAgICAgIGZBdHRyaWJ1dGVDaGVja2VyID0gbmV3IFhTQXR0cmlidXRlQ2hlY2tlcih0aGlzKTsKLSAgICAgICAgZkF0dHJpYnV0ZUdyb3VwVHJhdmVyc2VyID0gbmV3IFhTREF0dHJpYnV0ZUdyb3VwVHJhdmVyc2VyKHRoaXMsIGZBdHRyaWJ1dGVDaGVja2VyKTsKLSAgICAgICAgZkF0dHJpYnV0ZVRyYXZlcnNlciA9IG5ldyBYU0RBdHRyaWJ1dGVUcmF2ZXJzZXIodGhpcywgZkF0dHJpYnV0ZUNoZWNrZXIpOwotICAgICAgICBmQ29tcGxleFR5cGVUcmF2ZXJzZXIgPSBuZXcgWFNEQ29tcGxleFR5cGVUcmF2ZXJzZXIodGhpcywgZkF0dHJpYnV0ZUNoZWNrZXIpOwotICAgICAgICBmRWxlbWVudFRyYXZlcnNlciA9IG5ldyBYU0RFbGVtZW50VHJhdmVyc2VyKHRoaXMsIGZBdHRyaWJ1dGVDaGVja2VyKTsKLSAgICAgICAgZkdyb3VwVHJhdmVyc2VyID0gbmV3IFhTREdyb3VwVHJhdmVyc2VyKHRoaXMsIGZBdHRyaWJ1dGVDaGVja2VyKTsKLSAgICAgICAgZktleXJlZlRyYXZlcnNlciA9IG5ldyBYU0RLZXlyZWZUcmF2ZXJzZXIodGhpcywgZkF0dHJpYnV0ZUNoZWNrZXIpOwotICAgICAgICBmTm90YXRpb25UcmF2ZXJzZXIgPSBuZXcgWFNETm90YXRpb25UcmF2ZXJzZXIodGhpcywgZkF0dHJpYnV0ZUNoZWNrZXIpOwotICAgICAgICBmU2ltcGxlVHlwZVRyYXZlcnNlciA9IG5ldyBYU0RTaW1wbGVUeXBlVHJhdmVyc2VyKHRoaXMsIGZBdHRyaWJ1dGVDaGVja2VyKTsKLSAgICAgICAgZlVuaXF1ZU9yS2V5VHJhdmVyc2VyID0gbmV3IFhTRFVuaXF1ZU9yS2V5VHJhdmVyc2VyKHRoaXMsIGZBdHRyaWJ1dGVDaGVja2VyKTsKLSAgICAgICAgZldpbGRDYXJkVHJhdmVyc2VyID0gbmV3IFhTRFdpbGRjYXJkVHJhdmVyc2VyKHRoaXMsIGZBdHRyaWJ1dGVDaGVja2VyKTsKLSAgICB9IC8vIGNyZWF0ZVRyYXZlcnNlcnMoKQotCi0gICAgLy8gYmVmb3JlIHBhcnNpbmcgYSBzY2hlbWEsIG5lZWQgdG8gY2xlYXIgcmVnaXN0cmllcyBhc3NvY2lhdGVkIHdpdGgKLSAgICAvLyBwYXJzaW5nIHNjaGVtYXMKLSAgICB2b2lkIHByZXBhcmVGb3JQYXJzZSgpIHsKLSAgICAgICAgZlRyYXZlcnNlZC5jbGVhcigpOwotICAgICAgICBmRG9jMlN5c3RlbUlkLmNsZWFyKCk7Ci0gICAgICAgIGZIaWRkZW5Ob2Rlcy5jbGVhcigpOwotICAgICAgICBmTGFzdFNjaGVtYVdhc0R1cGxpY2F0ZSA9IGZhbHNlOwotICAgIH0KLQotICAgIC8vIGJlZm9yZSB0cmF2ZXJzaW5nIGEgc2NoZW1hJ3MgcGFyc2UgdHJlZSwgbmVlZCB0byByZXNldCBhbGwgdHJhdmVyc2VycyBhbmQKLSAgICAvLyBjbGVhciBhbGwgcmVnaXN0cmllcwotICAgIHZvaWQgcHJlcGFyZUZvclRyYXZlcnNlKCkgewotICAgICAgICBpZiAoIXJlZ2lzdHJ5RW1wdHkpIHsKLSAgICAgICAgZlVucGFyc2VkQXR0cmlidXRlUmVnaXN0cnkuY2xlYXIoKTsKLSAgICAgICAgZlVucGFyc2VkQXR0cmlidXRlR3JvdXBSZWdpc3RyeS5jbGVhcigpOwotICAgICAgICBmVW5wYXJzZWRFbGVtZW50UmVnaXN0cnkuY2xlYXIoKTsKLSAgICAgICAgZlVucGFyc2VkR3JvdXBSZWdpc3RyeS5jbGVhcigpOwotICAgICAgICBmVW5wYXJzZWRJZGVudGl0eUNvbnN0cmFpbnRSZWdpc3RyeS5jbGVhcigpOwotICAgICAgICBmVW5wYXJzZWROb3RhdGlvblJlZ2lzdHJ5LmNsZWFyKCk7Ci0gICAgICAgIGZVbnBhcnNlZFR5cGVSZWdpc3RyeS5jbGVhcigpOwotCi0gICAgICAgIGZVbnBhcnNlZEF0dHJpYnV0ZVJlZ2lzdHJ5U3ViLmNsZWFyKCk7Ci0gICAgICAgIGZVbnBhcnNlZEF0dHJpYnV0ZUdyb3VwUmVnaXN0cnlTdWIuY2xlYXIoKTsKLSAgICAgICAgZlVucGFyc2VkRWxlbWVudFJlZ2lzdHJ5U3ViLmNsZWFyKCk7Ci0gICAgICAgIGZVbnBhcnNlZEdyb3VwUmVnaXN0cnlTdWIuY2xlYXIoKTsKLSAgICAgICAgZlVucGFyc2VkSWRlbnRpdHlDb25zdHJhaW50UmVnaXN0cnlTdWIuY2xlYXIoKTsKLSAgICAgICAgZlVucGFyc2VkTm90YXRpb25SZWdpc3RyeVN1Yi5jbGVhcigpOwotICAgICAgICBmVW5wYXJzZWRUeXBlUmVnaXN0cnlTdWIuY2xlYXIoKTsKLSAgICAgICAgfQotCi0gICAgICAgIGZvciAoaW50IGk9MTsgaTw9IFRZUEVERUNMX1RZUEU7IGkrKykgewotICAgICAgICAgICAgaWYgKGZVbnBhcnNlZFJlZ2lzdHJpZXNFeHRbaV0gIT0gbnVsbCkKLSAgICAgICAgICAgICAgICBmVW5wYXJzZWRSZWdpc3RyaWVzRXh0W2ldLmNsZWFyKCk7Ci0gICAgICAgIH0KLQotICAgICAgICBmRGVwZW5kZW5jeU1hcC5jbGVhcigpOwotICAgICAgICBmRG9jMlhTRG9jdW1lbnRNYXAuY2xlYXIoKTsKLSAgICAgICAgaWYgKGZSZWRlZmluZTJYU0RNYXAgIT0gbnVsbCkgZlJlZGVmaW5lMlhTRE1hcC5jbGVhcigpOwotICAgICAgICBpZiAoZlJlZGVmaW5lMk5TU3VwcG9ydCAhPSBudWxsKSBmUmVkZWZpbmUyTlNTdXBwb3J0LmNsZWFyKCk7Ci0gICAgICAgIGZBbGxUTlNzLnJlbW92ZUFsbEVsZW1lbnRzKCk7Ci0gICAgICAgIGZJbXBvcnRNYXAuY2xlYXIoKTsKLSAgICAgICAgZlJvb3QgPSBudWxsOwotCi0gICAgICAgIC8vIGNsZWFyIGxvY2FsIGVsZW1lbnQgc3RhY2sKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmTG9jYWxFbGVtU3RhY2tQb3M7IGkrKykgewotICAgICAgICAgICAgZlBhcnRpY2xlW2ldID0gbnVsbDsKLSAgICAgICAgICAgIGZMb2NhbEVsZW1lbnREZWNsW2ldID0gbnVsbDsKLSAgICAgICAgICAgIGZMb2NhbEVsZW1lbnREZWNsX3NjaGVtYVtpXSA9IG51bGw7Ci0gICAgICAgICAgICBmTG9jYWxFbGVtTmFtZXNwYWNlQ29udGV4dFtpXSA9IG51bGw7Ci0gICAgICAgIH0KLSAgICAgICAgZkxvY2FsRWxlbVN0YWNrUG9zID0gMDsKLQotICAgICAgICAvLyBhbmQgZG8gc2FtZSBmb3Iga2V5cmVmcy4KLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmS2V5cmVmU3RhY2tQb3M7IGkrKykgewotICAgICAgICAgICAgZktleXJlZnNbaV0gPSBudWxsOwotICAgICAgICAgICAgZktleXJlZkVsZW1zW2ldID0gbnVsbDsKLSAgICAgICAgICAgIGZLZXlyZWZOYW1lc3BhY2VDb250ZXh0W2ldID0gbnVsbDsKLSAgICAgICAgICAgIGZLZXlyZWZzTWFwWFNEb2N1bWVudEluZm9baV0gPSBudWxsOwotICAgICAgICB9Ci0gICAgICAgIGZLZXlyZWZTdGFja1BvcyA9IDA7Ci0KLSAgICAgICAgLy8gY3JlYXRlIHRyYXZlcnNlcnMgaWYgbmVjZXNzYXJ5Ci0gICAgICAgIGlmIChmQXR0cmlidXRlQ2hlY2tlciA9PSBudWxsKSB7Ci0gICAgICAgICAgICBjcmVhdGVUcmF2ZXJzZXJzKCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyByZXNldCB0cmF2ZXJzZXJzCi0gICAgICAgIExvY2FsZSBsb2NhbGUgPSBmRXJyb3JSZXBvcnRlci5nZXRMb2NhbGUoKTsKLSAgICAgICAgZkF0dHJpYnV0ZUNoZWNrZXIucmVzZXQoZlN5bWJvbFRhYmxlKTsKLSAgICAgICAgZkF0dHJpYnV0ZUdyb3VwVHJhdmVyc2VyLnJlc2V0KGZTeW1ib2xUYWJsZSwgZlZhbGlkYXRlQW5ub3RhdGlvbnMsIGxvY2FsZSk7Ci0gICAgICAgIGZBdHRyaWJ1dGVUcmF2ZXJzZXIucmVzZXQoZlN5bWJvbFRhYmxlLCBmVmFsaWRhdGVBbm5vdGF0aW9ucywgbG9jYWxlKTsKLSAgICAgICAgZkNvbXBsZXhUeXBlVHJhdmVyc2VyLnJlc2V0KGZTeW1ib2xUYWJsZSwgZlZhbGlkYXRlQW5ub3RhdGlvbnMsIGxvY2FsZSk7Ci0gICAgICAgIGZFbGVtZW50VHJhdmVyc2VyLnJlc2V0KGZTeW1ib2xUYWJsZSwgZlZhbGlkYXRlQW5ub3RhdGlvbnMsIGxvY2FsZSk7Ci0gICAgICAgIGZHcm91cFRyYXZlcnNlci5yZXNldChmU3ltYm9sVGFibGUsIGZWYWxpZGF0ZUFubm90YXRpb25zLCBsb2NhbGUpOwotICAgICAgICBmS2V5cmVmVHJhdmVyc2VyLnJlc2V0KGZTeW1ib2xUYWJsZSwgZlZhbGlkYXRlQW5ub3RhdGlvbnMsIGxvY2FsZSk7Ci0gICAgICAgIGZOb3RhdGlvblRyYXZlcnNlci5yZXNldChmU3ltYm9sVGFibGUsIGZWYWxpZGF0ZUFubm90YXRpb25zLCBsb2NhbGUpOwotICAgICAgICBmU2ltcGxlVHlwZVRyYXZlcnNlci5yZXNldChmU3ltYm9sVGFibGUsIGZWYWxpZGF0ZUFubm90YXRpb25zLCBsb2NhbGUpOwotICAgICAgICBmVW5pcXVlT3JLZXlUcmF2ZXJzZXIucmVzZXQoZlN5bWJvbFRhYmxlLCBmVmFsaWRhdGVBbm5vdGF0aW9ucywgbG9jYWxlKTsKLSAgICAgICAgZldpbGRDYXJkVHJhdmVyc2VyLnJlc2V0KGZTeW1ib2xUYWJsZSwgZlZhbGlkYXRlQW5ub3RhdGlvbnMsIGxvY2FsZSk7Ci0KLSAgICAgICAgZlJlZGVmaW5lZFJlc3RyaWN0ZWRBdHRyaWJ1dGVHcm91cFJlZ2lzdHJ5LmNsZWFyKCk7Ci0gICAgICAgIGZSZWRlZmluZWRSZXN0cmljdGVkR3JvdXBSZWdpc3RyeS5jbGVhcigpOwotCi0gICAgICAgIGZHbG9iYWxBdHRyRGVjbHMuY2xlYXIoKTsKLSAgICAgICAgZkdsb2JhbEF0dHJHcnBEZWNscy5jbGVhcigpOwotICAgICAgICBmR2xvYmFsRWxlbURlY2xzLmNsZWFyKCk7Ci0gICAgICAgIGZHbG9iYWxHcm91cERlY2xzLmNsZWFyKCk7Ci0gICAgICAgIGZHbG9iYWxOb3RhdGlvbkRlY2xzLmNsZWFyKCk7Ci0gICAgICAgIGZHbG9iYWxJRENvbnN0cmFpbnREZWNscy5jbGVhcigpOwotICAgICAgICBmR2xvYmFsVHlwZURlY2xzLmNsZWFyKCk7Ci0gICAgfQotICAgIHB1YmxpYyB2b2lkIHNldERlY2xQb29sIChYU0RlY2xhcmF0aW9uUG9vbCBkZWNsUG9vbCl7Ci0gICAgICAgIGZEZWNsUG9vbCA9IGRlY2xQb29sOwotICAgIH0KLSAgICBwdWJsaWMgdm9pZCBzZXREVkZhY3RvcnkoU2NoZW1hRFZGYWN0b3J5IGR2RmFjdG9yeSl7Ci0gICAgICAgIGZEVkZhY3RvcnkgPSBkdkZhY3Rvcnk7Ci0gICAgfQotICAgIHB1YmxpYyBTY2hlbWFEVkZhY3RvcnkgZ2V0RFZGYWN0b3J5KCl7Ci0gICAgICAgIHJldHVybiBmRFZGYWN0b3J5OwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHJlc2V0KFhNTENvbXBvbmVudE1hbmFnZXIgY29tcG9uZW50TWFuYWdlcikgewotCi0gICAgICAgIC8vIHNldCBzeW1ib2wgdGFibGUKLSAgICAgICAgZlN5bWJvbFRhYmxlID0gKFN5bWJvbFRhYmxlKSBjb21wb25lbnRNYW5hZ2VyLmdldFByb3BlcnR5KFNZTUJPTF9UQUJMRSk7Ci0KLSAgICAgICAgLy8gc2V0IHNlY3VyaXR5IG1hbmFnZXIKLSAgICAgICAgZlNlY3VyaXR5TWFuYWdlciA9IChYTUxTZWN1cml0eU1hbmFnZXIpIGNvbXBvbmVudE1hbmFnZXIuZ2V0UHJvcGVydHkoU0VDVVJJVFlfTUFOQUdFUiwgbnVsbCk7Ci0KLSAgICAgICAgLy9zZXQgZW50aXR5IG1hbmFnZXIKLSAgICAgICAgZkVudGl0eU1hbmFnZXIgPSAoWE1MRW50aXR5UmVzb2x2ZXIpIGNvbXBvbmVudE1hbmFnZXIuZ2V0UHJvcGVydHkoRU5USVRZX01BTkFHRVIpOwotCi0gICAgICAgIC8vc2V0IGVudGl0eSByZXNvbHZlcgotICAgICAgICBYTUxFbnRpdHlSZXNvbHZlciBlciA9IChYTUxFbnRpdHlSZXNvbHZlciljb21wb25lbnRNYW5hZ2VyLmdldFByb3BlcnR5KEVOVElUWV9SRVNPTFZFUik7Ci0gICAgICAgIGlmIChlciAhPSBudWxsKQotICAgICAgICAgICAgZlNjaGVtYVBhcnNlci5zZXRFbnRpdHlSZXNvbHZlcihlcik7Ci0KLSAgICAgICAgLy8gc2V0IGVycm9yIHJlcG9ydGVyCi0gICAgICAgIGZFcnJvclJlcG9ydGVyID0gKFhNTEVycm9yUmVwb3J0ZXIpIGNvbXBvbmVudE1hbmFnZXIuZ2V0UHJvcGVydHkoRVJST1JfUkVQT1JURVIpOwotICAgICAgICBmRXJyb3JIYW5kbGVyID0gZkVycm9yUmVwb3J0ZXIuZ2V0RXJyb3JIYW5kbGVyKCk7Ci0gICAgICAgIGZMb2NhbGUgPSBmRXJyb3JSZXBvcnRlci5nZXRMb2NhbGUoKTsKLQotICAgICAgICBmVmFsaWRhdGVBbm5vdGF0aW9ucyA9IGNvbXBvbmVudE1hbmFnZXIuZ2V0RmVhdHVyZShWQUxJREFURV9BTk5PVEFUSU9OUywgZmFsc2UpOwotICAgICAgICBmSG9ub3VyQWxsU2NoZW1hTG9jYXRpb25zID0gY29tcG9uZW50TWFuYWdlci5nZXRGZWF0dXJlKEhPTk9VUl9BTExfU0NIRU1BTE9DQVRJT05TLCBmYWxzZSk7Ci0gICAgICAgIGZOYW1lc3BhY2VHcm93dGggPSBjb21wb25lbnRNYW5hZ2VyLmdldEZlYXR1cmUoTkFNRVNQQUNFX0dST1dUSCwgZmFsc2UpOwotICAgICAgICBmVG9sZXJhdGVEdXBsaWNhdGVzID0gY29tcG9uZW50TWFuYWdlci5nZXRGZWF0dXJlKFRPTEVSQVRFX0RVUExJQ0FURVMsIGZhbHNlKTsKLQotICAgICAgICB0cnkgewotICAgICAgICAgICAgLy8gU2V0dGluZyBhIHBhcnNlciBwcm9wZXJ0eSBjYW4gYmUgbXVjaCBtb3JlIGV4cGVuc2l2ZQotICAgICAgICAgICAgLy8gdGhhbiBjaGVja2luZyBpdHMgdmFsdWUuICBEb24ndCBzZXQgdGhlIEVSUk9SX0hBTkRMRVIKLSAgICAgICAgICAgIC8vIG9yIExPQ0FMRSBwcm9wZXJ0aWVzIHVubGVzcyB0aGV5J3ZlIGFjdHVhbGx5IGNoYW5nZWQuCi0gICAgICAgICAgICBpZiAoZkVycm9ySGFuZGxlciAhPSBmU2NoZW1hUGFyc2VyLmdldFByb3BlcnR5KEVSUk9SX0hBTkRMRVIpKSB7Ci0gICAgICAgICAgICAgICAgZlNjaGVtYVBhcnNlci5zZXRQcm9wZXJ0eShFUlJPUl9IQU5ETEVSLCAoZkVycm9ySGFuZGxlciAhPSBudWxsKSA/IGZFcnJvckhhbmRsZXIgOiBuZXcgRGVmYXVsdEVycm9ySGFuZGxlcigpKTsKLSAgICAgICAgICAgICAgICBpZiAoZkFubm90YXRpb25WYWxpZGF0b3IgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBmQW5ub3RhdGlvblZhbGlkYXRvci5zZXRQcm9wZXJ0eShFUlJPUl9IQU5ETEVSLCAoZkVycm9ySGFuZGxlciAhPSBudWxsKSA/IGZFcnJvckhhbmRsZXIgOiBuZXcgRGVmYXVsdEVycm9ySGFuZGxlcigpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoZkxvY2FsZSAhPSBmU2NoZW1hUGFyc2VyLmdldFByb3BlcnR5KExPQ0FMRSkpIHsKLSAgICAgICAgICAgICAgICBmU2NoZW1hUGFyc2VyLnNldFByb3BlcnR5KExPQ0FMRSwgZkxvY2FsZSk7Ci0gICAgICAgICAgICAgICAgaWYgKGZBbm5vdGF0aW9uVmFsaWRhdG9yICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgZkFubm90YXRpb25WYWxpZGF0b3Iuc2V0UHJvcGVydHkoTE9DQUxFLCBmTG9jYWxlKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gZSkge30KLQotICAgICAgICB0cnkgewotICAgICAgICAgICAgZlNjaGVtYVBhcnNlci5zZXRGZWF0dXJlKENPTlRJTlVFX0FGVEVSX0ZBVEFMX0VSUk9SLCBmRXJyb3JSZXBvcnRlci5nZXRGZWF0dXJlKENPTlRJTlVFX0FGVEVSX0ZBVEFMX0VSUk9SKSk7Ci0gICAgICAgIH0gY2F0Y2ggKFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gZSkge30KLQotICAgICAgICB0cnkgewotICAgICAgICAgICAgaWYgKGNvbXBvbmVudE1hbmFnZXIuZ2V0RmVhdHVyZShBTExPV19KQVZBX0VOQ09ESU5HUywgZmFsc2UpKSB7Ci0gICAgICAgICAgICAgICAgZlNjaGVtYVBhcnNlci5zZXRGZWF0dXJlKEFMTE9XX0pBVkFfRU5DT0RJTkdTLCB0cnVlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSBjYXRjaCAoWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBlKSB7fQotCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBpZiAoY29tcG9uZW50TWFuYWdlci5nZXRGZWF0dXJlKFNUQU5EQVJEX1VSSV9DT05GT1JNQU5UX0ZFQVRVUkUsIGZhbHNlKSkgewotICAgICAgICAgICAgICAgIGZTY2hlbWFQYXJzZXIuc2V0RmVhdHVyZShTVEFOREFSRF9VUklfQ09ORk9STUFOVF9GRUFUVVJFLCB0cnVlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSBjYXRjaCAoWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBlKSB7fQotCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBmR3JhbW1hclBvb2wgPSAoWE1MR3JhbW1hclBvb2wpIGNvbXBvbmVudE1hbmFnZXIuZ2V0UHJvcGVydHkoWE1MR1JBTU1BUl9QT09MKTsKLSAgICAgICAgfSBjYXRjaCAoWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICBmR3JhbW1hclBvb2wgPSBudWxsOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gc2VjdXJpdHkgZmVhdHVyZXMKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGlmIChjb21wb25lbnRNYW5hZ2VyLmdldEZlYXR1cmUoRElTQUxMT1dfRE9DVFlQRSwgZmFsc2UpKSB7Ci0gICAgICAgICAgICAgICAgZlNjaGVtYVBhcnNlci5zZXRGZWF0dXJlKERJU0FMTE9XX0RPQ1RZUEUsIHRydWUpOwotICAgICAgICAgICAgfQotICAgICAgICB9IGNhdGNoIChYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIGUpIHt9Ci0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGlmIChmU2VjdXJpdHlNYW5hZ2VyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmU2NoZW1hUGFyc2VyLnNldFByb3BlcnR5KFNFQ1VSSVRZX01BTkFHRVIsIGZTZWN1cml0eU1hbmFnZXIpOwotICAgICAgICAgICAgfQotICAgICAgICB9IGNhdGNoIChYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIGUpIHt9Ci0KLSAgICAgICAgZlNlY3VyaXR5UHJvcGVydHlNZ3IgPSAoWE1MU2VjdXJpdHlQcm9wZXJ0eU1hbmFnZXIpIGNvbXBvbmVudE1hbmFnZXIuZ2V0UHJvcGVydHkoWE1MX1NFQ1VSSVRZX1BST1BFUlRZX01BTkFHRVIpOwotCi0gICAgICAgIC8vUGFzc2luZyBvbiB0aGUgc2V0dGluZyB0byB0aGUgcGFyc2VyCi0gICAgICAgIGZTY2hlbWFQYXJzZXIuc2V0UHJvcGVydHkoWE1MX1NFQ1VSSVRZX1BST1BFUlRZX01BTkFHRVIsIGZTZWN1cml0eVByb3BlcnR5TWdyKTsKLQotICAgICAgICBmQWNjZXNzRXh0ZXJuYWxEVEQgPSBmU2VjdXJpdHlQcm9wZXJ0eU1nci5nZXRWYWx1ZShYTUxTZWN1cml0eVByb3BlcnR5TWFuYWdlci5Qcm9wZXJ0eS5BQ0NFU1NfRVhURVJOQUxfRFREKTsKLSAgICAgICAgZkFjY2Vzc0V4dGVybmFsU2NoZW1hID0gZlNlY3VyaXR5UHJvcGVydHlNZ3IuZ2V0VmFsdWUoWE1MU2VjdXJpdHlQcm9wZXJ0eU1hbmFnZXIuUHJvcGVydHkuQUNDRVNTX0VYVEVSTkFMX1NDSEVNQSk7Ci0KLSAgICB9IC8vIHJlc2V0KFhNTENvbXBvbmVudE1hbmFnZXIpCi0KLQotICAgIC8qKgotICAgICAqIFRyYXZlcnNlIGFsbCB0aGUgZGVmZXJyZWQgbG9jYWwgZWxlbWVudHMuIFRoaXMgbWV0aG9kIHNob3VsZCBiZSBjYWxsZWQKLSAgICAgKiBieSB0cmF2ZXJzZVNjaGVtYXMgYWZ0ZXIgd2UndmUgZG9uZSB3aXRoIGFsbCB0aGUgZ2xvYmFsIGRlY2xhcmF0aW9ucy4KLSAgICAgKi8KLSAgICB2b2lkIHRyYXZlcnNlTG9jYWxFbGVtZW50cygpIHsKLSAgICAgICAgZkVsZW1lbnRUcmF2ZXJzZXIuZkRlZmVyVHJhdmVyc2luZ0xvY2FsRWxlbWVudHMgPSBmYWxzZTsKLQotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZMb2NhbEVsZW1TdGFja1BvczsgaSsrKSB7Ci0gICAgICAgICAgICBFbGVtZW50IGN1cnJFbGVtID0gZkxvY2FsRWxlbWVudERlY2xbaV07Ci0gICAgICAgICAgICAvL1hTRG9jdW1lbnRJbmZvIGN1cnJTY2hlbWEgPSAoWFNEb2N1bWVudEluZm8pZkRvYzJYU0RvY3VtZW50TWFwLmdldChET01VdGlsLmdldERvY3VtZW50KGN1cnJFbGVtKSk7Ci0gICAgICAgICAgICAvL1hTRG9jdW1lbnRJbmZvIGN1cnJTY2hlbWEgPSAoWFNEb2N1bWVudEluZm8pZkRvYzJYU0RvY3VtZW50TWFwLmdldChET01VdGlsLmdldFJvb3QoRE9NVXRpbC5nZXREb2N1bWVudChjdXJyRWxlbSkpKTsKLSAgICAgICAgICAgIFhTRG9jdW1lbnRJbmZvIGN1cnJTY2hlbWEgPSBmTG9jYWxFbGVtZW50RGVjbF9zY2hlbWFbaV07Ci0gICAgICAgICAgICBTY2hlbWFHcmFtbWFyIGN1cnJHcmFtbWFyID0gZkdyYW1tYXJCdWNrZXQuZ2V0R3JhbW1hcihjdXJyU2NoZW1hLmZUYXJnZXROYW1lc3BhY2UpOwotICAgICAgICAgICAgZkVsZW1lbnRUcmF2ZXJzZXIudHJhdmVyc2VMb2NhbCAoZlBhcnRpY2xlW2ldLCBjdXJyRWxlbSwgY3VyclNjaGVtYSwgY3VyckdyYW1tYXIsIGZBbGxDb250ZXh0W2ldLCBmUGFyZW50W2ldLCBmTG9jYWxFbGVtTmFtZXNwYWNlQ29udGV4dFtpXSk7Ci0gICAgICAgICAgICAvLyBJZiBpdCdzIGFuIGVtcHR5IHBhcnRpY2xlLCByZW1vdmUgaXQgZnJvbSB0aGUgY29udGFpbmluZyBjb21wb25lbnQuCi0gICAgICAgICAgICBpZiAoZlBhcnRpY2xlW2ldLmZUeXBlID09IFhTUGFydGljbGVEZWNsLlBBUlRJQ0xFX0VNUFRZKSB7Ci0gICAgICAgICAgICAgICAgWFNNb2RlbEdyb3VwSW1wbCBncm91cCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgaWYgKGZQYXJlbnRbaV0gaW5zdGFuY2VvZiBYU0NvbXBsZXhUeXBlRGVjbCkgewotICAgICAgICAgICAgICAgICAgICBYU1BhcnRpY2xlIHAgPSAoKFhTQ29tcGxleFR5cGVEZWNsKWZQYXJlbnRbaV0pLmdldFBhcnRpY2xlKCk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChwICE9IG51bGwpCi0gICAgICAgICAgICAgICAgICAgICAgICBncm91cCA9IChYU01vZGVsR3JvdXBJbXBsKXAuZ2V0VGVybSgpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgZ3JvdXAgPSAoKFhTR3JvdXBEZWNsKWZQYXJlbnRbaV0pLmZNb2RlbEdyb3VwOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpZiAoZ3JvdXAgIT0gbnVsbCkKLSAgICAgICAgICAgICAgICAgICAgcmVtb3ZlUGFydGljbGUoZ3JvdXAsIGZQYXJ0aWNsZVtpXSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwcml2YXRlIGJvb2xlYW4gcmVtb3ZlUGFydGljbGUoWFNNb2RlbEdyb3VwSW1wbCBncm91cCwgWFNQYXJ0aWNsZURlY2wgcGFydGljbGUpIHsKLSAgICAgICAgWFNQYXJ0aWNsZURlY2wgbWVtYmVyOwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGdyb3VwLmZQYXJ0aWNsZUNvdW50OyBpKyspIHsKLSAgICAgICAgICAgIG1lbWJlciA9IGdyb3VwLmZQYXJ0aWNsZXNbaV07Ci0gICAgICAgICAgICBpZiAobWVtYmVyID09IHBhcnRpY2xlKSB7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaiA9IGk7IGogPCBncm91cC5mUGFydGljbGVDb3VudC0xOyBqKyspCi0gICAgICAgICAgICAgICAgICAgIGdyb3VwLmZQYXJ0aWNsZXNbal0gPSBncm91cC5mUGFydGljbGVzW2orMV07Ci0gICAgICAgICAgICAgICAgZ3JvdXAuZlBhcnRpY2xlQ291bnQtLTsKLSAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChtZW1iZXIuZlR5cGUgPT0gWFNQYXJ0aWNsZURlY2wuUEFSVElDTEVfTU9ERUxHUk9VUCkgewotICAgICAgICAgICAgICAgIGlmIChyZW1vdmVQYXJ0aWNsZSgoWFNNb2RlbEdyb3VwSW1wbCltZW1iZXIuZlZhbHVlLCBwYXJ0aWNsZSkpCi0gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICAvLyB0aGUgcHVycG9zZSBvZiB0aGlzIG1ldGhvZCBpcyB0byBrZWVwIHVwLXRvLWRhdGUgc3RydWN0dXJlcwotICAgIC8vIHdlJ2xsIG5lZWQgZm9yIHRoZSBmZWZlcnJlZCB0cmF2ZXJzYWwgb2YgbG9jYWwgZWxlbWVudHMuCi0gICAgdm9pZCBmaWxsSW5Mb2NhbEVsZW1JbmZvKEVsZW1lbnQgZWxtRGVjbCwKLSAgICAgICAgICAgIFhTRG9jdW1lbnRJbmZvIHNjaGVtYURvYywKLSAgICAgICAgICAgIGludCBhbGxDb250ZXh0RmxhZ3MsCi0gICAgICAgICAgICBYU09iamVjdCBwYXJlbnQsCi0gICAgICAgICAgICBYU1BhcnRpY2xlRGVjbCBwYXJ0aWNsZSkgewotCi0gICAgICAgIC8vIGlmIHRoZSBzdGFjayBpcyBmdWxsLCBpbmNyZWFzZSB0aGUgc2l6ZQotICAgICAgICBpZiAoZlBhcnRpY2xlLmxlbmd0aCA9PSBmTG9jYWxFbGVtU3RhY2tQb3MpIHsKLSAgICAgICAgICAgIC8vIGluY3JlYXNlIHNpemUKLSAgICAgICAgICAgIFhTUGFydGljbGVEZWNsW10gbmV3U3RhY2tQID0gbmV3IFhTUGFydGljbGVEZWNsW2ZMb2NhbEVsZW1TdGFja1BvcytJTkNfU1RBQ0tfU0laRV07Ci0gICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGZQYXJ0aWNsZSwgMCwgbmV3U3RhY2tQLCAwLCBmTG9jYWxFbGVtU3RhY2tQb3MpOwotICAgICAgICAgICAgZlBhcnRpY2xlID0gbmV3U3RhY2tQOwotICAgICAgICAgICAgRWxlbWVudFtdIG5ld1N0YWNrRSA9IG5ldyBFbGVtZW50W2ZMb2NhbEVsZW1TdGFja1BvcytJTkNfU1RBQ0tfU0laRV07Ci0gICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGZMb2NhbEVsZW1lbnREZWNsLCAwLCBuZXdTdGFja0UsIDAsIGZMb2NhbEVsZW1TdGFja1Bvcyk7Ci0gICAgICAgICAgICBmTG9jYWxFbGVtZW50RGVjbCA9IG5ld1N0YWNrRTsKLSAgICAgICAgICAgIFhTRG9jdW1lbnRJbmZvIFtdIG5ld1N0YWNrRV9zY2hlbWEgPSBuZXcgWFNEb2N1bWVudEluZm9bZkxvY2FsRWxlbVN0YWNrUG9zK0lOQ19TVEFDS19TSVpFXTsKLSAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZkxvY2FsRWxlbWVudERlY2xfc2NoZW1hLCAwLCBuZXdTdGFja0Vfc2NoZW1hLCAwLCBmTG9jYWxFbGVtU3RhY2tQb3MpOwotICAgICAgICAgICAgZkxvY2FsRWxlbWVudERlY2xfc2NoZW1hID0gbmV3U3RhY2tFX3NjaGVtYTsKLSAgICAgICAgICAgIGludFtdIG5ld1N0YWNrSSA9IG5ldyBpbnRbZkxvY2FsRWxlbVN0YWNrUG9zK0lOQ19TVEFDS19TSVpFXTsKLSAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZkFsbENvbnRleHQsIDAsIG5ld1N0YWNrSSwgMCwgZkxvY2FsRWxlbVN0YWNrUG9zKTsKLSAgICAgICAgICAgIGZBbGxDb250ZXh0ID0gbmV3U3RhY2tJOwotICAgICAgICAgICAgWFNPYmplY3RbXSBuZXdTdGFja0MgPSBuZXcgWFNPYmplY3RbZkxvY2FsRWxlbVN0YWNrUG9zK0lOQ19TVEFDS19TSVpFXTsKLSAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZlBhcmVudCwgMCwgbmV3U3RhY2tDLCAwLCBmTG9jYWxFbGVtU3RhY2tQb3MpOwotICAgICAgICAgICAgZlBhcmVudCA9IG5ld1N0YWNrQzsKLSAgICAgICAgICAgIFN0cmluZyBbXVtdIG5ld1N0YWNrTiA9IG5ldyBTdHJpbmcgW2ZMb2NhbEVsZW1TdGFja1BvcytJTkNfU1RBQ0tfU0laRV1bXTsKLSAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZkxvY2FsRWxlbU5hbWVzcGFjZUNvbnRleHQsIDAsIG5ld1N0YWNrTiwgMCwgZkxvY2FsRWxlbVN0YWNrUG9zKTsKLSAgICAgICAgICAgIGZMb2NhbEVsZW1OYW1lc3BhY2VDb250ZXh0ID0gbmV3U3RhY2tOOwotICAgICAgICB9Ci0KLSAgICAgICAgZlBhcnRpY2xlW2ZMb2NhbEVsZW1TdGFja1Bvc10gPSBwYXJ0aWNsZTsKLSAgICAgICAgZkxvY2FsRWxlbWVudERlY2xbZkxvY2FsRWxlbVN0YWNrUG9zXSA9IGVsbURlY2w7Ci0gICAgICAgIGZMb2NhbEVsZW1lbnREZWNsX3NjaGVtYVtmTG9jYWxFbGVtU3RhY2tQb3NdID0gc2NoZW1hRG9jOwotICAgICAgICBmQWxsQ29udGV4dFtmTG9jYWxFbGVtU3RhY2tQb3NdID0gYWxsQ29udGV4dEZsYWdzOwotICAgICAgICBmUGFyZW50W2ZMb2NhbEVsZW1TdGFja1Bvc10gPSBwYXJlbnQ7Ci0gICAgICAgIGZMb2NhbEVsZW1OYW1lc3BhY2VDb250ZXh0W2ZMb2NhbEVsZW1TdGFja1BvcysrXSA9IHNjaGVtYURvYy5mTmFtZXNwYWNlU3VwcG9ydC5nZXRFZmZlY3RpdmVMb2NhbENvbnRleHQoKTsKLSAgICB9IC8vIGVuZCBmaWxsSW5Mb2NhbEVsZW1JbmZvKC4uLikKLQotICAgIC8qKiBUaGlzIG1ldGhvZCBtYWtlcyBzdXJlIHRoYXQKLSAgICAgKiBpZiB0aGlzIGNvbXBvbmVudCBpcyBiZWluZyByZWRlZmluZWQgdGhhdCBpdCBsaXZlcyBpbiB0aGUKLSAgICAgKiByaWdodCBzY2hlbWEuICBJdCB0aGVuIHJlbmFtZXMgdGhlIGNvbXBvbmVudCBjb3JyZWN0bHkuICBJZiBpdAotICAgICAqIGRldGVjdHMgYSBjb2xsaXNpb24tLWEgZHVwbGljYXRlIGRlZmluaXRpb24tLXRoZW4gaXQgY29tcGxhaW5zLgotICAgICAqIE5vdGUgdGhhdCByZWRlZmluZXMgbXVzdCBiZSBoYW5kbGVkIGNhcmVmdWxseTogIGlmIHRoZXJlCi0gICAgICogaXMgYSBjb2xsaXNpb24sIGl0IG1heSBiZSBiZWNhdXNlIHdlJ3JlIHJlZGVmaW5pbmcgc29tZXRoaW5nIHdlIGtub3cgYWJvdXQKLSAgICAgKiBvciBiZWNhdXNlIHdlJ3ZlIGZvdW5kIHRoZSB0aGluZyB3ZSdyZSByZWRlZmluaW5nLgotICAgICAqLwotICAgIHZvaWQgY2hlY2tGb3JEdXBsaWNhdGVOYW1lcyhTdHJpbmcgcU5hbWUsIGludCBkZWNsVHlwZSwKLSAgICAgICAgICAgIE1hcDxTdHJpbmcsRWxlbWVudD4gcmVnaXN0cnksIE1hcDxTdHJpbmcsWFNEb2N1bWVudEluZm8+IHJlZ2lzdHJ5X3N1YiwgRWxlbWVudCBjdXJyQ29tcCwKLSAgICAgICAgICAgIFhTRG9jdW1lbnRJbmZvIGN1cnJTY2hlbWEpIHsKLSAgICAgICAgT2JqZWN0IG9iakVsZW0gPSBudWxsOwotICAgICAgICAvLyBSRVZJU0lUOiAgd2hlbiB3ZSBhZGQgZGVyaXZhdGlvbiBjaGVja2luZywgd2UnbGwgaGF2ZSB0byBtYWtlCi0gICAgICAgIC8vIHN1cmUgdGhhdCBJRCBjb25zdHJhaW50IGNvbGxpc2lvbnMgZG9uJ3QgbmVjZXNzYXJpbHkgcmVzdWx0IGluIGVycm9yIG1lc3NhZ2VzLgotICAgICAgICBpZiAoKG9iakVsZW0gPSByZWdpc3RyeS5nZXQocU5hbWUpKSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAvLyBuZWVkIHRvIGNoZWNrIHdoZXRoZXIgd2UgaGF2ZSBhIGdsb2JhbCBkZWNsYXJhdGlvbiBpbiB0aGUgY29ycmVzcG9uZGluZwotICAgICAgICAgICAgLy8gZ3JhbW1hcgotICAgICAgICAgICAgaWYgKGZOYW1lc3BhY2VHcm93dGggJiYgIWZUb2xlcmF0ZUR1cGxpY2F0ZXMpIHsKLSAgICAgICAgICAgICAgICBjaGVja0ZvckR1cGxpY2F0ZU5hbWVzKHFOYW1lLCBkZWNsVHlwZSwgY3VyckNvbXApOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8ganVzdCBhZGQgaXQgaW4hCi0gICAgICAgICAgICByZWdpc3RyeS5wdXQocU5hbWUsIGN1cnJDb21wKTsKLSAgICAgICAgICAgIHJlZ2lzdHJ5X3N1Yi5wdXQocU5hbWUsIGN1cnJTY2hlbWEpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgRWxlbWVudCBjb2xsaWRpbmdFbGVtID0gKEVsZW1lbnQpb2JqRWxlbTsKLSAgICAgICAgICAgIFhTRG9jdW1lbnRJbmZvIGNvbGxpZGluZ0VsZW1TY2hlbWEgPSAoWFNEb2N1bWVudEluZm8pcmVnaXN0cnlfc3ViLmdldChxTmFtZSk7Ci0gICAgICAgICAgICBpZiAoY29sbGlkaW5nRWxlbSA9PSBjdXJyQ29tcCkgcmV0dXJuOwotICAgICAgICAgICAgRWxlbWVudCBlbGVtUGFyZW50ID0gbnVsbDsKLSAgICAgICAgICAgIFhTRG9jdW1lbnRJbmZvIHJlZGVmaW5lZFNjaGVtYSA9IG51bGw7Ci0gICAgICAgICAgICAvLyBjYXNlIHdoZXJlIHdlJ3ZlIGNvbGxpZGVkIHdpdGggYSByZWRlZmluaW5nIGVsZW1lbnQKLSAgICAgICAgICAgIC8vICh0aGUgcGFyZW50IG9mIHRoZSBjb2xsaWRpbmcgZWxlbWVudCBpcyBhIHJlZGVmaW5lKQotICAgICAgICAgICAgYm9vbGVhbiBjb2xsaWRlZFdpdGhSZWRlZmluZSA9IHRydWU7Ci0gICAgICAgICAgICBpZiAoKERPTVV0aWwuZ2V0TG9jYWxOYW1lKChlbGVtUGFyZW50ID0gRE9NVXRpbC5nZXRQYXJlbnQoY29sbGlkaW5nRWxlbSkpKS5lcXVhbHMoU2NoZW1hU3ltYm9scy5FTFRfUkVERUZJTkUpKSkgewotICAgICAgICAgICAgICAgIHJlZGVmaW5lZFNjaGVtYSA9IChmUmVkZWZpbmUyWFNETWFwICE9IG51bGwpPyhYU0RvY3VtZW50SW5mbykgKGZSZWRlZmluZTJYU0RNYXAuZ2V0KGVsZW1QYXJlbnQpKTogbnVsbDsKLSAgICAgICAgICAgICAgICAvLyBjYXNlIHdoZXJlIHdlJ3JlIGEgcmVkZWZpbmluZyBlbGVtZW50LgotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoKERPTVV0aWwuZ2V0TG9jYWxOYW1lKERPTVV0aWwuZ2V0UGFyZW50KGN1cnJDb21wKSkuZXF1YWxzKFNjaGVtYVN5bWJvbHMuRUxUX1JFREVGSU5FKSkpIHsKLSAgICAgICAgICAgICAgICByZWRlZmluZWRTY2hlbWEgPSBjb2xsaWRpbmdFbGVtU2NoZW1hOwotICAgICAgICAgICAgICAgIGNvbGxpZGVkV2l0aFJlZGVmaW5lID0gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAocmVkZWZpbmVkU2NoZW1hICE9IG51bGwpIHsgLy9yZWRlZmluaXRpb24gaW52b2x2ZWQgc29tZWhvdwotICAgICAgICAgICAgICAgIC8vIElmIGJvdGggY29tcG9uZW50cyBiZWxvbmcgdG8gdGhlIHNhbWUgZG9jdW1lbnQgdGhlbgotICAgICAgICAgICAgICAgIC8vIHJlcG9ydCBhbiBlcnJvciBhbmQgcmV0dXJuLgotICAgICAgICAgICAgICAgIGlmKGNvbGxpZGluZ0VsZW1TY2hlbWEgPT0gY3VyclNjaGVtYSl7Ci0gICAgICAgICAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKCJzY2gtcHJvcHMtY29ycmVjdC4yIiwgbmV3IE9iamVjdFtde3FOYW1lfSwgY3VyckNvbXApOwotICAgICAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgU3RyaW5nIG5ld05hbWUgPSBxTmFtZS5zdWJzdHJpbmcocU5hbWUubGFzdEluZGV4T2YoJywnKSsxKStSRURFRl9JREVOVElGSUVSOwotICAgICAgICAgICAgICAgIGlmIChyZWRlZmluZWRTY2hlbWEgPT0gY3VyclNjaGVtYSkgeyAvLyBvYmplY3QgY29tcC4gb2theSBoZXJlCi0gICAgICAgICAgICAgICAgICAgIC8vIG5vdyBoYXZlIHRvIGRvIHNvbWUgcmVuYW1pbmcuLi4KLSAgICAgICAgICAgICAgICAgICAgY3VyckNvbXAuc2V0QXR0cmlidXRlKFNjaGVtYVN5bWJvbHMuQVRUX05BTUUsIG5ld05hbWUpOwotICAgICAgICAgICAgICAgICAgICBpZiAoY3VyclNjaGVtYS5mVGFyZ2V0TmFtZXNwYWNlID09IG51bGwpewotICAgICAgICAgICAgICAgICAgICAgICAgcmVnaXN0cnkucHV0KCIsIituZXdOYW1lLCBjdXJyQ29tcCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZWdpc3RyeV9zdWIucHV0KCIsIituZXdOYW1lLCBjdXJyU2NoZW1hKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlewotICAgICAgICAgICAgICAgICAgICAgICAgcmVnaXN0cnkucHV0KGN1cnJTY2hlbWEuZlRhcmdldE5hbWVzcGFjZSsiLCIrbmV3TmFtZSwgY3VyckNvbXApOwotICAgICAgICAgICAgICAgICAgICAgICAgcmVnaXN0cnlfc3ViLnB1dChjdXJyU2NoZW1hLmZUYXJnZXROYW1lc3BhY2UrIiwiK25ld05hbWUsIGN1cnJTY2hlbWEpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIC8vIGFuZCB0YWtlIGNhcmUgb2YgbmVzdGVkIHJlZGVmaW5lcyBieSBjYWxsaW5nIHJlY3Vyc2l2ZWx5OgotICAgICAgICAgICAgICAgICAgICBpZiAoY3VyclNjaGVtYS5mVGFyZ2V0TmFtZXNwYWNlID09IG51bGwpCi0gICAgICAgICAgICAgICAgICAgICAgICBjaGVja0ZvckR1cGxpY2F0ZU5hbWVzKCIsIituZXdOYW1lLCBkZWNsVHlwZSwgcmVnaXN0cnksIHJlZ2lzdHJ5X3N1YiwgY3VyckNvbXAsIGN1cnJTY2hlbWEpOwotICAgICAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgICAgICBjaGVja0ZvckR1cGxpY2F0ZU5hbWVzKGN1cnJTY2hlbWEuZlRhcmdldE5hbWVzcGFjZSsiLCIrbmV3TmFtZSwgZGVjbFR5cGUsIHJlZ2lzdHJ5LCByZWdpc3RyeV9zdWIsIGN1cnJDb21wLCBjdXJyU2NoZW1hKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSB7IC8vIHdlIG1heSBiZSByZWRlZmluaW5nIHRoZSB3cm9uZyBzY2hlbWEKLSAgICAgICAgICAgICAgICAgICAgaWYgKGNvbGxpZGVkV2l0aFJlZGVmaW5lKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY3VyclNjaGVtYS5mVGFyZ2V0TmFtZXNwYWNlID09IG51bGwpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tGb3JEdXBsaWNhdGVOYW1lcygiLCIrbmV3TmFtZSwgZGVjbFR5cGUsIHJlZ2lzdHJ5LCByZWdpc3RyeV9zdWIsIGN1cnJDb21wLCBjdXJyU2NoZW1hKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGVja0ZvckR1cGxpY2F0ZU5hbWVzKGN1cnJTY2hlbWEuZlRhcmdldE5hbWVzcGFjZSsiLCIrbmV3TmFtZSwgZGVjbFR5cGUsIHJlZ2lzdHJ5LCByZWdpc3RyeV9zdWIsIGN1cnJDb21wLCBjdXJyU2NoZW1hKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGVycm9yIHRoYXQgcmVkZWZpbmVkIGVsZW1lbnQgaW4gd3Jvbmcgc2NoZW1hCi0gICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcigic2NoLXByb3BzLWNvcnJlY3QuMiIsIG5ldyBPYmplY3QgW10ge3FOYW1lfSwgY3VyckNvbXApOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgLy8gd2UndmUganVzdCBnb3QgYSBmbGF0LW91dCBjb2xsaXNpb24gKHdlIHRvbGVyYXRlIGR1cGxpY2F0ZQotICAgICAgICAgICAgICAgIC8vIGRlY2xhcmF0aW9ucywgb25seSBpZiB0aGV5IGFyZSBkZWZpbmVkIGluIGRpZmZlcmVudCBzY2hlbWEKLSAgICAgICAgICAgICAgICAvLyBkb2N1bWVudHMpCi0gICAgICAgICAgICAgICAgaWYgKCFmVG9sZXJhdGVEdXBsaWNhdGVzKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKCJzY2gtcHJvcHMtY29ycmVjdC4yIiwgbmV3IE9iamVjdCBbXXtxTmFtZX0sIGN1cnJDb21wKTsKLSAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGZVbnBhcnNlZFJlZ2lzdHJpZXNFeHRbZGVjbFR5cGVdICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGZVbnBhcnNlZFJlZ2lzdHJpZXNFeHRbZGVjbFR5cGVdLmdldChxTmFtZSkgPT0gY3VyclNjaGVtYSkgewotICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoInNjaC1wcm9wcy1jb3JyZWN0LjIiLCBuZXcgT2JqZWN0IFtde3FOYW1lfSwgY3VyckNvbXApOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gc3RvcmUgdGhlIGxhc3Rlc3QgY3VycmVudCBkb2N1bWVudCBpbmZvCi0gICAgICAgIGlmIChmVG9sZXJhdGVEdXBsaWNhdGVzKSB7Ci0gICAgICAgICAgICBpZiAoZlVucGFyc2VkUmVnaXN0cmllc0V4dFtkZWNsVHlwZV0gPT0gbnVsbCkKLSAgICAgICAgICAgICAgICBmVW5wYXJzZWRSZWdpc3RyaWVzRXh0W2RlY2xUeXBlXSA9IG5ldyBIYXNoTWFwKCk7Ci0gICAgICAgICAgICBmVW5wYXJzZWRSZWdpc3RyaWVzRXh0W2RlY2xUeXBlXS5wdXQocU5hbWUsIGN1cnJTY2hlbWEpOwotICAgICAgICB9Ci0KLSAgICB9IC8vIGNoZWNrRm9yRHVwbGljYXRlTmFtZXMoU3RyaW5nLCBNYXAsIEVsZW1lbnQsIFhTRG9jdW1lbnRJbmZvKTp2b2lkCi0KLSAgICB2b2lkIGNoZWNrRm9yRHVwbGljYXRlTmFtZXMoU3RyaW5nIHFOYW1lLCBpbnQgZGVjbFR5cGUsIEVsZW1lbnQgY3VyckNvbXApIHsKLSAgICAgICAgaW50IG5hbWVzcGFjZUVuZCA9IHFOYW1lLmluZGV4T2YoJywnKTsKLSAgICAgICAgU3RyaW5nIG5hbWVzcGFjZSA9IHFOYW1lLnN1YnN0cmluZygwLCBuYW1lc3BhY2VFbmQpOwotICAgICAgICBTY2hlbWFHcmFtbWFyIGdyYW1tYXIgPSBmR3JhbW1hckJ1Y2tldC5nZXRHcmFtbWFyKGVtcHR5U3RyaW5nMk51bGwobmFtZXNwYWNlKSk7Ci0KLSAgICAgICAgaWYgKGdyYW1tYXIgIT0gbnVsbCkgewotICAgICAgICAgICAgT2JqZWN0IG9iaiA9IGdldEdsb2JhbERlY2xGcm9tR3JhbW1hcihncmFtbWFyLCBkZWNsVHlwZSwgcU5hbWUuc3Vic3RyaW5nKG5hbWVzcGFjZUVuZCArIDEpKTsKLSAgICAgICAgICAgIGlmIChvYmogIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKCJzY2gtcHJvcHMtY29ycmVjdC4yIiwgbmV3IE9iamVjdCBbXXtxTmFtZX0sIGN1cnJDb21wKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIC8vIHRoZSBwdXJwb3NlIG9mIHRoaXMgbWV0aG9kIGlzIHRvIHRha2UgdGhlIGNvbXBvbmVudCBvZiB0aGUKLSAgICAvLyBzcGVjaWZpZWQgdHlwZSBhbmQgcmVuYW1lIHJlZmVyZW5jZXMgdG8gaXRzZWxmIHNvIHRoYXQgdGhleQotICAgIC8vIHJlZmVyIHRvIHRoZSBvYmplY3QgYmVpbmcgcmVkZWZpbmVkLiAgSXQgdGFrZXMgc3BlY2lhbCBjYXJlIG9mCi0gICAgLy8gPGdyb3VwPnMgYW5kIDxhdHRyaWJ1dGVHcm91cD5zIHRvIGVuc3VyZSB0aGF0IGluZm9ybWF0aW9uCi0gICAgLy8gcmVsYXRpbmcgdG8gaW1wbGljaXQgcmVzdHJpY3Rpb25zIGlzIHByZXNlcnZlZCBmb3IgdGhvc2UKLSAgICAvLyB0cmF2ZXJzZXJzLgotICAgIHByaXZhdGUgdm9pZCByZW5hbWVSZWRlZmluaW5nQ29tcG9uZW50cyhYU0RvY3VtZW50SW5mbyBjdXJyU2NoZW1hLAotICAgICAgICAgICAgRWxlbWVudCBjaGlsZCwgU3RyaW5nIGNvbXBvbmVudFR5cGUsCi0gICAgICAgICAgICBTdHJpbmcgb2xkTmFtZSwgU3RyaW5nIG5ld05hbWUpIHsKLSAgICAgICAgaWYgKGNvbXBvbmVudFR5cGUuZXF1YWxzKFNjaGVtYVN5bWJvbHMuRUxUX1NJTVBMRVRZUEUpKSB7Ci0gICAgICAgICAgICBFbGVtZW50IGdyYW5kS2lkID0gRE9NVXRpbC5nZXRGaXJzdENoaWxkRWxlbWVudChjaGlsZCk7Ci0gICAgICAgICAgICBpZiAoZ3JhbmRLaWQgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKCJzcmMtcmVkZWZpbmUuNS5hLmEiLCBudWxsLCBjaGlsZCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgZ3JhbmRLaWROYW1lID0gRE9NVXRpbC5nZXRMb2NhbE5hbWUoZ3JhbmRLaWQpOwotICAgICAgICAgICAgICAgIGlmIChncmFuZEtpZE5hbWUuZXF1YWxzKFNjaGVtYVN5bWJvbHMuRUxUX0FOTk9UQVRJT04pKSB7Ci0gICAgICAgICAgICAgICAgICAgIGdyYW5kS2lkID0gRE9NVXRpbC5nZXROZXh0U2libGluZ0VsZW1lbnQoZ3JhbmRLaWQpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpZiAoZ3JhbmRLaWQgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcigic3JjLXJlZGVmaW5lLjUuYS5hIiwgbnVsbCwgY2hpbGQpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgZ3JhbmRLaWROYW1lID0gRE9NVXRpbC5nZXRMb2NhbE5hbWUoZ3JhbmRLaWQpOwotICAgICAgICAgICAgICAgICAgICBpZiAoIWdyYW5kS2lkTmFtZS5lcXVhbHMoU2NoZW1hU3ltYm9scy5FTFRfUkVTVFJJQ1RJT04pKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcigic3JjLXJlZGVmaW5lLjUuYS5iIiwgbmV3IE9iamVjdFtde2dyYW5kS2lkTmFtZX0sIGNoaWxkKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIE9iamVjdFtdIGF0dHJzID0gZkF0dHJpYnV0ZUNoZWNrZXIuY2hlY2tBdHRyaWJ1dGVzKGdyYW5kS2lkLCBmYWxzZSwgY3VyclNjaGVtYSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBRTmFtZSBkZXJpdmVkQmFzZSA9IChRTmFtZSlhdHRyc1tYU0F0dHJpYnV0ZUNoZWNrZXIuQVRUSURYX0JBU0VdOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRlcml2ZWRCYXNlID09IG51bGwgfHwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVyaXZlZEJhc2UudXJpICE9IGN1cnJTY2hlbWEuZlRhcmdldE5hbWVzcGFjZSB8fAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAhZGVyaXZlZEJhc2UubG9jYWxwYXJ0LmVxdWFscyhvbGROYW1lKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKCJzcmMtcmVkZWZpbmUuNS5hLmMiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde2dyYW5kS2lkTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjdXJyU2NoZW1hLmZUYXJnZXROYW1lc3BhY2U9PW51bGw/IiI6Y3VyclNjaGVtYS5mVGFyZ2V0TmFtZXNwYWNlKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiLCIgKyBvbGROYW1lfSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG5vdyB3ZSBoYXZlIHRvIGRvIHRoZSByZW5hbWluZy4uLgotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkZXJpdmVkQmFzZS5wcmVmaXggIT0gbnVsbCAmJiBkZXJpdmVkQmFzZS5wcmVmaXgubGVuZ3RoKCkgPiAwKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncmFuZEtpZC5zZXRBdHRyaWJ1dGUoIFNjaGVtYVN5bWJvbHMuQVRUX0JBU0UsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVyaXZlZEJhc2UucHJlZml4ICsgIjoiICsgbmV3TmFtZSApOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JhbmRLaWQuc2V0QXR0cmlidXRlKCBTY2hlbWFTeW1ib2xzLkFUVF9CQVNFLCBuZXdOYW1lICk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBmQXR0cmlidXRlQ2hlY2tlci5yZXR1cm5BdHRyQXJyYXkoYXR0cnMsIGN1cnJTY2hlbWEpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKGNvbXBvbmVudFR5cGUuZXF1YWxzKFNjaGVtYVN5bWJvbHMuRUxUX0NPTVBMRVhUWVBFKSkgewotICAgICAgICAgICAgRWxlbWVudCBncmFuZEtpZCA9IERPTVV0aWwuZ2V0Rmlyc3RDaGlsZEVsZW1lbnQoY2hpbGQpOwotICAgICAgICAgICAgaWYgKGdyYW5kS2lkID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcigic3JjLXJlZGVmaW5lLjUuYi5hIiwgbnVsbCwgY2hpbGQpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgaWYgKERPTVV0aWwuZ2V0TG9jYWxOYW1lKGdyYW5kS2lkKS5lcXVhbHMoU2NoZW1hU3ltYm9scy5FTFRfQU5OT1RBVElPTikpIHsKLSAgICAgICAgICAgICAgICAgICAgZ3JhbmRLaWQgPSBET01VdGlsLmdldE5leHRTaWJsaW5nRWxlbWVudChncmFuZEtpZCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGlmIChncmFuZEtpZCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKCJzcmMtcmVkZWZpbmUuNS5iLmEiLCBudWxsLCBjaGlsZCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAvLyBoYXZlIHRvIGdvIG9uZSBtb3JlIGxldmVsIGRvd247IGxldCBhbm90aGVyIHBhc3Mgd29ycnkgd2hldGhlciBjb21wbGV4VHlwZSBpcyB2YWxpZC4KLSAgICAgICAgICAgICAgICAgICAgRWxlbWVudCBncmVhdEdyYW5kS2lkID0gRE9NVXRpbC5nZXRGaXJzdENoaWxkRWxlbWVudChncmFuZEtpZCk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChncmVhdEdyYW5kS2lkID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKCJzcmMtcmVkZWZpbmUuNS5iLmIiLCBudWxsLCBncmFuZEtpZCk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgZ3JlYXRHcmFuZEtpZE5hbWUgPSBET01VdGlsLmdldExvY2FsTmFtZShncmVhdEdyYW5kS2lkKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChncmVhdEdyYW5kS2lkTmFtZS5lcXVhbHMoU2NoZW1hU3ltYm9scy5FTFRfQU5OT1RBVElPTikpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBncmVhdEdyYW5kS2lkID0gRE9NVXRpbC5nZXROZXh0U2libGluZ0VsZW1lbnQoZ3JlYXRHcmFuZEtpZCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZ3JlYXRHcmFuZEtpZCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoInNyYy1yZWRlZmluZS41LmIuYiIsIG51bGwsIGdyYW5kS2lkKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyZWF0R3JhbmRLaWROYW1lID0gRE9NVXRpbC5nZXRMb2NhbE5hbWUoZ3JlYXRHcmFuZEtpZCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFncmVhdEdyYW5kS2lkTmFtZS5lcXVhbHMoU2NoZW1hU3ltYm9scy5FTFRfUkVTVFJJQ1RJT04pICYmCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAhZ3JlYXRHcmFuZEtpZE5hbWUuZXF1YWxzKFNjaGVtYVN5bWJvbHMuRUxUX0VYVEVOU0lPTikpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoInNyYy1yZWRlZmluZS41LmIuYyIsIG5ldyBPYmplY3RbXXtncmVhdEdyYW5kS2lkTmFtZX0sIGdyZWF0R3JhbmRLaWQpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT2JqZWN0W10gYXR0cnMgPSBmQXR0cmlidXRlQ2hlY2tlci5jaGVja0F0dHJpYnV0ZXMoZ3JlYXRHcmFuZEtpZCwgZmFsc2UsIGN1cnJTY2hlbWEpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBRTmFtZSBkZXJpdmVkQmFzZSA9IChRTmFtZSlhdHRyc1tYU0F0dHJpYnV0ZUNoZWNrZXIuQVRUSURYX0JBU0VdOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGVyaXZlZEJhc2UgPT0gbnVsbCB8fAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlcml2ZWRCYXNlLnVyaSAhPSBjdXJyU2NoZW1hLmZUYXJnZXROYW1lc3BhY2UgfHwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAhZGVyaXZlZEJhc2UubG9jYWxwYXJ0LmVxdWFscyhvbGROYW1lKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoInNyYy1yZWRlZmluZS41LmIuZCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXtncmVhdEdyYW5kS2lkTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGN1cnJTY2hlbWEuZlRhcmdldE5hbWVzcGFjZT09bnVsbD8iIjpjdXJyU2NoZW1hLmZUYXJnZXROYW1lc3BhY2UpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiwiICsgb2xkTmFtZX0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyZWF0R3JhbmRLaWQpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbm93IHdlIGhhdmUgdG8gZG8gdGhlIHJlbmFtaW5nLi4uCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGVyaXZlZEJhc2UucHJlZml4ICE9IG51bGwgJiYgZGVyaXZlZEJhc2UucHJlZml4Lmxlbmd0aCgpID4gMCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncmVhdEdyYW5kS2lkLnNldEF0dHJpYnV0ZSggU2NoZW1hU3ltYm9scy5BVFRfQkFTRSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlcml2ZWRCYXNlLnByZWZpeCArICI6IiArIG5ld05hbWUgKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncmVhdEdyYW5kS2lkLnNldEF0dHJpYnV0ZSggU2NoZW1hU3ltYm9scy5BVFRfQkFTRSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld05hbWUgKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoY29tcG9uZW50VHlwZS5lcXVhbHMoU2NoZW1hU3ltYm9scy5FTFRfQVRUUklCVVRFR1JPVVApKSB7Ci0gICAgICAgICAgICBTdHJpbmcgcHJvY2Vzc2VkQmFzZU5hbWUgPSAoY3VyclNjaGVtYS5mVGFyZ2V0TmFtZXNwYWNlID09IG51bGwpPwotICAgICAgICAgICAgICAgICAgICAiLCIrb2xkTmFtZTpjdXJyU2NoZW1hLmZUYXJnZXROYW1lc3BhY2UrIiwiK29sZE5hbWU7Ci0gICAgICAgICAgICBpbnQgYXR0R3JvdXBSZWZzQ291bnQgPSBjaGFuZ2VSZWRlZmluZUdyb3VwKHByb2Nlc3NlZEJhc2VOYW1lLCBjb21wb25lbnRUeXBlLCBuZXdOYW1lLCBjaGlsZCwgY3VyclNjaGVtYSk7Ci0gICAgICAgICAgICBpZiAoYXR0R3JvdXBSZWZzQ291bnQgPiAxKSB7Ci0gICAgICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoInNyYy1yZWRlZmluZS43LjEiLCBuZXcgT2JqZWN0IFtde25ldyBJbnRlZ2VyKGF0dEdyb3VwUmVmc0NvdW50KX0sIGNoaWxkKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKGF0dEdyb3VwUmVmc0NvdW50ID09IDEpIHsKLSAgICAgICAgICAgICAgICAvLyAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICBpZiAoY3VyclNjaGVtYS5mVGFyZ2V0TmFtZXNwYWNlID09IG51bGwpCi0gICAgICAgICAgICAgICAgICAgIGZSZWRlZmluZWRSZXN0cmljdGVkQXR0cmlidXRlR3JvdXBSZWdpc3RyeS5wdXQocHJvY2Vzc2VkQmFzZU5hbWUsICIsIituZXdOYW1lKTsKLSAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgIGZSZWRlZmluZWRSZXN0cmljdGVkQXR0cmlidXRlR3JvdXBSZWdpc3RyeS5wdXQocHJvY2Vzc2VkQmFzZU5hbWUsIGN1cnJTY2hlbWEuZlRhcmdldE5hbWVzcGFjZSsiLCIrbmV3TmFtZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoY29tcG9uZW50VHlwZS5lcXVhbHMoU2NoZW1hU3ltYm9scy5FTFRfR1JPVVApKSB7Ci0gICAgICAgICAgICBTdHJpbmcgcHJvY2Vzc2VkQmFzZU5hbWUgPSAoY3VyclNjaGVtYS5mVGFyZ2V0TmFtZXNwYWNlID09IG51bGwpPwotICAgICAgICAgICAgICAgICAgICAiLCIrb2xkTmFtZTpjdXJyU2NoZW1hLmZUYXJnZXROYW1lc3BhY2UrIiwiK29sZE5hbWU7Ci0gICAgICAgICAgICBpbnQgZ3JvdXBSZWZzQ291bnQgPSBjaGFuZ2VSZWRlZmluZUdyb3VwKHByb2Nlc3NlZEJhc2VOYW1lLCBjb21wb25lbnRUeXBlLCBuZXdOYW1lLCBjaGlsZCwgY3VyclNjaGVtYSk7Ci0gICAgICAgICAgICBpZiAoZ3JvdXBSZWZzQ291bnQgPiAxKSB7Ci0gICAgICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoInNyYy1yZWRlZmluZS42LjEuMSIsIG5ldyBPYmplY3QgW117bmV3IEludGVnZXIoZ3JvdXBSZWZzQ291bnQpfSwgY2hpbGQpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoZ3JvdXBSZWZzQ291bnQgPT0gMSkgewotICAgICAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgaWYgKGN1cnJTY2hlbWEuZlRhcmdldE5hbWVzcGFjZSA9PSBudWxsKQotICAgICAgICAgICAgICAgICAgICBmUmVkZWZpbmVkUmVzdHJpY3RlZEdyb3VwUmVnaXN0cnkucHV0KHByb2Nlc3NlZEJhc2VOYW1lLCAiLCIrbmV3TmFtZSk7Ci0gICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICBmUmVkZWZpbmVkUmVzdHJpY3RlZEdyb3VwUmVnaXN0cnkucHV0KHByb2Nlc3NlZEJhc2VOYW1lLCBjdXJyU2NoZW1hLmZUYXJnZXROYW1lc3BhY2UrIiwiK25ld05hbWUpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoIkludGVybmFsLUVycm9yIiwgbmV3IE9iamVjdCBbXSB7ImNvdWxkIG5vdCBoYW5kbGUgdGhpcyBwYXJ0aWN1bGFyIDxyZWRlZmluZT47IHBsZWFzZSBzdWJtaXQgeW91ciBzY2hlbWFzIGFuZCBpbnN0YW5jZSBkb2N1bWVudCBpbiBhIGJ1ZyByZXBvcnQhIn0sIGNoaWxkKTsKLSAgICAgICAgfQotICAgICAgICAvLyBpZiB3ZSBnZXQgaGVyZSB0aGVuIHdlIG11c3QgaGF2ZSByZXBvcnRlZCBhbiBlcnJvciBhbmQgZmFpbGVkIHNvbWV3aGVyZS4uLgotICAgICAgICAvLyAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0gLy8gcmVuYW1lUmVkZWZpbmluZ0NvbXBvbmVudHMoWFNEb2N1bWVudEluZm8sIEVsZW1lbnQsIFN0cmluZywgU3RyaW5nLCBTdHJpbmcpOnZvaWQKLQotICAgIC8vIHRoaXMgbWV0aG9kIHRha2VzIGEgbmFtZSBvZiB0aGUgZm9ybSBhOmIsIGRldGVybWluZXMgdGhlIFVSSSBtYXBwZWQKLSAgICAvLyB0byBieSBhIGluIHRoZSBjdXJyZW50IFNjaGVtYU5hbWVzcGFjZVN1cHBvcnQgb2JqZWN0LCBhbmQgcmV0dXJucyB0aGlzCi0gICAgLy8gaW5mb3JtYXRpb24gaW4gdGhlIGZvcm0gKG5zVVJJLGIpIHN1aXRhYmxlIGZvciBsb29rdXBzIGluIHRoZSBnbG9iYWwKLSAgICAvLyBkZWNsIG1hcHMuCi0gICAgLy8gUkVWSVNJVDogc2hvdWxkIGhhdmUgaXQgcmV0dXJuIFFOYW1lLCBpbnN0ZWFkIG9mIFN0cmluZy4gdGhpcyB3b3VsZAotICAgIC8vICAgICAgICAgIHNhdmUgbG90cyBvZiBzdHJpbmcgY29uY2F0ZW5hdGlvbiB0aW1lLiB3ZSBjYW4gdXNlCi0gICAgLy8gICAgICAgICAgUU5hbWUjZXF1YWxzKCkgdG8gY29tcGFyZSB0d28gUU5hbWVzLCBhbmQgdXNlIFFOYW1lIGRpcmVjdGx5Ci0gICAgLy8gICAgICAgICAgYXMgYSBrZXkgdG8gdGhlIFN5bWJvbEhhc2guCi0gICAgLy8gICAgICAgICAgQW5kIHdoZW4gdGhlIERWJ3MgYXJlIHJlYWR5IHRvIHJldHVybiBjb21waWxlZCB2YWx1ZXMgZnJvbQotICAgIC8vICAgICAgICAgIHZhbGlkYXRlKCkgbWV0aG9kLCB3ZSBzaG91bGQganVzdCBjYWxsIFFOYW1lRFYudmFsaWRhdGUoKQotICAgIC8vICAgICAgICAgIGluIHRoaXMgbWV0aG9kLgotICAgIHByaXZhdGUgU3RyaW5nIGZpbmRRTmFtZShTdHJpbmcgbmFtZSwgWFNEb2N1bWVudEluZm8gc2NoZW1hRG9jKSB7Ci0gICAgICAgIFNjaGVtYU5hbWVzcGFjZVN1cHBvcnQgY3Vyck5TTWFwID0gc2NoZW1hRG9jLmZOYW1lc3BhY2VTdXBwb3J0OwotICAgICAgICBpbnQgY29sb25QdHIgPSBuYW1lLmluZGV4T2YoJzonKTsKLSAgICAgICAgU3RyaW5nIHByZWZpeCA9IFhNTFN5bWJvbHMuRU1QVFlfU1RSSU5HOwotICAgICAgICBpZiAoY29sb25QdHIgPiAwKQotICAgICAgICAgICAgcHJlZml4ID0gbmFtZS5zdWJzdHJpbmcoMCwgY29sb25QdHIpOwotICAgICAgICBTdHJpbmcgdXJpID0gY3Vyck5TTWFwLmdldFVSSShmU3ltYm9sVGFibGUuYWRkU3ltYm9sKHByZWZpeCkpOwotICAgICAgICBTdHJpbmcgbG9jYWxwYXJ0ID0gKGNvbG9uUHRyID09IDApP25hbWU6bmFtZS5zdWJzdHJpbmcoY29sb25QdHIrMSk7Ci0gICAgICAgIGlmIChwcmVmaXggPT0gWE1MU3ltYm9scy5FTVBUWV9TVFJJTkcgJiYgdXJpID09IG51bGwgJiYgc2NoZW1hRG9jLmZJc0NoYW1lbGVvblNjaGVtYSkKLSAgICAgICAgICAgIHVyaSA9IHNjaGVtYURvYy5mVGFyZ2V0TmFtZXNwYWNlOwotICAgICAgICBpZiAodXJpID09IG51bGwpCi0gICAgICAgICAgICByZXR1cm4gIiwiK2xvY2FscGFydDsKLSAgICAgICAgcmV0dXJuIHVyaSsiLCIrbG9jYWxwYXJ0OwotICAgIH0gLy8gZmluZFFOYW1lKFN0cmluZywgWFNEb2N1bWVudEluZm8pOiAgU3RyaW5nCi0KLSAgICAvLyBUaGlzIGZ1bmN0aW9uIGxvb2tzIGFtb25nIHRoZSBjaGlsZHJlbiBvZiBjdXJyIGZvciBhbiBlbGVtZW50IG9mIHR5cGUgZWxlbWVudFNvdWdodC4KLSAgICAvLyBJZiBpdCBmaW5kcyBvbmUsIGl0IGV2YWx1YXRlcyB3aGV0aGVyIGl0cyByZWYgYXR0cmlidXRlIGNvbnRhaW5zIGEgcmVmZXJlbmNlCi0gICAgLy8gdG8gb3JpZ2luYWxRTmFtZS4gIElmIGl0IGRvZXMsIGl0IHJldHVybnMgMSArIHRoZSB2YWx1ZSByZXR1cm5lZCBieQotICAgIC8vIGNhbGxzIHRvIGl0c2VsZiBvbiBhbGwgb3RoZXIgY2hpbGRyZW4uICBJbiBhbGwgb3RoZXIgY2FzZXMgaXQgcmV0dXJucyAwIHBsdXMKLSAgICAvLyB0aGUgc3VtIG9mIHRoZSB2YWx1ZXMgcmV0dXJuZWQgYnkgY2FsbHMgdG8gaXRzZWxmIG9uIGN1cnIncyBjaGlsZHJlbi4KLSAgICAvLyBJdCBhbHNvIHJlc2V0cyB0aGUgdmFsdWUgb2YgcmVmIHNvIHRoYXQgaXQgd2lsbCByZWZlciB0byB0aGUgcmVuYW1lZCB0eXBlIGZyb20gdGhlIHNjaGVtYQotICAgIC8vIGJlaW5nIHJlZGVmaW5lZC4KLSAgICBwcml2YXRlIGludCBjaGFuZ2VSZWRlZmluZUdyb3VwKFN0cmluZyBvcmlnaW5hbFFOYW1lLCBTdHJpbmcgZWxlbWVudFNvdWdodCwKLSAgICAgICAgICAgIFN0cmluZyBuZXdOYW1lLCBFbGVtZW50IGN1cnIsIFhTRG9jdW1lbnRJbmZvIHNjaGVtYURvYykgewotICAgICAgICBpbnQgcmVzdWx0ID0gMDsKLSAgICAgICAgZm9yIChFbGVtZW50IGNoaWxkID0gRE9NVXRpbC5nZXRGaXJzdENoaWxkRWxlbWVudChjdXJyKTsKLSAgICAgICAgY2hpbGQgIT0gbnVsbDsgY2hpbGQgPSBET01VdGlsLmdldE5leHRTaWJsaW5nRWxlbWVudChjaGlsZCkpIHsKLSAgICAgICAgICAgIFN0cmluZyBuYW1lID0gRE9NVXRpbC5nZXRMb2NhbE5hbWUoY2hpbGQpOwotICAgICAgICAgICAgaWYgKCFuYW1lLmVxdWFscyhlbGVtZW50U291Z2h0KSkKLSAgICAgICAgICAgICAgICByZXN1bHQgKz0gY2hhbmdlUmVkZWZpbmVHcm91cChvcmlnaW5hbFFOYW1lLCBlbGVtZW50U291Z2h0LCBuZXdOYW1lLCBjaGlsZCwgc2NoZW1hRG9jKTsKLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIFN0cmluZyByZWYgPSBjaGlsZC5nZXRBdHRyaWJ1dGUoIFNjaGVtYVN5bWJvbHMuQVRUX1JFRiApOwotICAgICAgICAgICAgICAgIGlmIChyZWYubGVuZ3RoKCkgIT0gMCkgewotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcHJvY2Vzc2VkUmVmID0gZmluZFFOYW1lKHJlZiwgc2NoZW1hRG9jKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKG9yaWdpbmFsUU5hbWUuZXF1YWxzKHByb2Nlc3NlZFJlZikpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBwcmVmaXggPSBYTUxTeW1ib2xzLkVNUFRZX1NUUklORzsKLSAgICAgICAgICAgICAgICAgICAgICAgIGludCBjb2xvbnB0ciA9IHJlZi5pbmRleE9mKCI6Iik7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29sb25wdHIgPiAwKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJlZml4ID0gcmVmLnN1YnN0cmluZygwLGNvbG9ucHRyKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZC5zZXRBdHRyaWJ1dGUoU2NoZW1hU3ltYm9scy5BVFRfUkVGLCBwcmVmaXggKyAiOiIgKyBuZXdOYW1lKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZC5zZXRBdHRyaWJ1dGUoU2NoZW1hU3ltYm9scy5BVFRfUkVGLCBuZXdOYW1lKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCsrOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVsZW1lbnRTb3VnaHQuZXF1YWxzKFNjaGVtYVN5bWJvbHMuRUxUX0dST1VQKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBtaW5PY2N1cnMgPSBjaGlsZC5nZXRBdHRyaWJ1dGUoIFNjaGVtYVN5bWJvbHMuQVRUX01JTk9DQ1VSUyApOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBtYXhPY2N1cnMgPSBjaGlsZC5nZXRBdHRyaWJ1dGUoIFNjaGVtYVN5bWJvbHMuQVRUX01BWE9DQ1VSUyApOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghKChtYXhPY2N1cnMubGVuZ3RoKCkgPT0gMCB8fCBtYXhPY2N1cnMuZXF1YWxzKCIxIikpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiAobWluT2NjdXJzLmxlbmd0aCgpID09IDAgfHwgbWluT2NjdXJzLmVxdWFscygiMSIpKSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoInNyYy1yZWRlZmluZS42LjEuMiIsIG5ldyBPYmplY3QgW10ge3JlZn0sIGNoaWxkKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9IC8vIGlmIHJlZiB3YXMgbnVsbCBzb21lIG90aGVyIHN0YWdlIG9mIHByb2Nlc3Npbmcgd2lsbCBmbGFnIHRoZSBlcnJvcgotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiByZXN1bHQ7Ci0gICAgfSAvLyBjaGFuZ2VSZWRlZmluZUdyb3VwCi0KLSAgICAvLyB0aGlzIG1ldGhvZCByZXR1cm5zIHRoZSBYU0RvY3VtZW50SW5mbyBvYmplY3QgdGhhdCBjb250YWlucyB0aGUKLSAgICAvLyBjb21wb25lbnQgY29ycmVzcG9uZGluZyB0byBkZWNsLiAgSWYgY29tcG9uZW50cyBmcm9tIHRoaXMKLSAgICAvLyBkb2N1bWVudCBjYW5ub3QgYmUgcmVmZXJyZWQgdG8gZnJvbSB0aG9zZSBvZiBjdXJyU2NoZW1hLCB0aGlzCi0gICAgLy8gbWV0aG9kIHJldHVybnMgbnVsbDsgaXQncyB1cCB0byB0aGUgY2FsbGVyIHRvIHRocm93IGFuIGVycm9yLgotICAgIC8vIEBwYXJhbTogIGN1cnJTY2hlbWE6ICB0aGUgWFNEb2N1bWVudEluZm8gb2JqZWN0IGNvbnRhaW5pbmcgdGhlCi0gICAgLy8gZGVjbCByZWYnaW5nIHVzLgotICAgIC8vIEBwYXJhbTogIGRlY2w6ICB0aGUgZGVjbGFyYXRpb24gYmVpbmcgcmVmJ2QuCi0gICAgLy8gdGhpcyBtZXRob2QgaXMgc3VwZXJmaWNpYWwgbm93LiAtLS1KYWNrCi0gICAgcHJpdmF0ZSBYU0RvY3VtZW50SW5mbyBmaW5kWFNEb2N1bWVudEZvckRlY2woWFNEb2N1bWVudEluZm8gY3VyclNjaGVtYSwKLSAgICAgICAgICAgIEVsZW1lbnQgZGVjbCwgWFNEb2N1bWVudEluZm8gZGVjbF9Eb2MpIHsKLQotICAgICAgICBpZiAoREVCVUdfTk9ERV9QT09MKSB7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkRPQ1VNRU5UIE5TOiIrIGN1cnJTY2hlbWEuZlRhcmdldE5hbWVzcGFjZSsiIGhhc2hjb2RlOiIrICgoT2JqZWN0KWN1cnJTY2hlbWEuZlNjaGVtYUVsZW1lbnQpLmhhc2hDb2RlKCkpOwotICAgICAgICB9Ci0gICAgICAgIE9iamVjdCB0ZW1wID0gZGVjbF9Eb2M7Ci0gICAgICAgIGlmICh0ZW1wID09IG51bGwpIHsKLSAgICAgICAgICAgIC8vIHNvbWV0aGluZyB3ZW50IGJhZGx5IHdyb25nOyB3ZSBkb24ndCBrbm93IHRoaXMgZG9jPwotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLSAgICAgICAgWFNEb2N1bWVudEluZm8gZGVjbERvY0luZm8gPSAoWFNEb2N1bWVudEluZm8pdGVtcDsKLSAgICAgICAgcmV0dXJuIGRlY2xEb2NJbmZvOwotICAgICAgICAvKioqKioqKioqCi0gICAgICAgICBMb2dpYyBoZXJlIGlzIHVubmVjZXNzYXJ5IGFmdGVyIHNjaGVtYSBXRydzIHJlY2VudCBkZWNpc2lvbiB0byBhbGxvdwotICAgICAgICAgc2NoZW1hIGNvbXBvbmVudHMgZnJvbSBvbmUgZG9jdW1lbnQgdG8gcmVmZXIgdG8gY29tcG9uZW50cyBvZiBhbnkgb3RoZXIsCi0gICAgICAgICBzbyBsb25nIGFzIHRoZXJlJ3Mgc29tZSBpbmNsdWRlL2ltcG9ydC9yZWRlZmluZSBwYXRoIGFtb25nc3QgdGhlbS4KLSAgICAgICAgIElmIHRoZXkgcnZlciByZXZlcnNlIHRoaXMgZGVjaXNpb24gdGhlIGNvZGUncyByaWdodCBoZXJlIHRob3VnaC4uLiAgLSBuZWlsZwotICAgICAgICAgLy8gbm93IGxvb2sgaW4gZkRlcGVuZGVuY3lNYXAgdG8gc2VlIGlmIHRoaXMgaXMgcmVhY2hhYmxlCi0gICAgICAgICAgaWYoKGZEZXBlbmRlbmN5TWFwLmdldChjdXJyU2NoZW1hKSkuY29udGFpbnMoZGVjbERvY0luZm8pKSB7Ci0gICAgICAgICAgcmV0dXJuIGRlY2xEb2NJbmZvOwotICAgICAgICAgIH0KLSAgICAgICAgICAvLyBvYnZpb3VzbHkgdGhlIHJlcXVlc3RpbmcgZG9jIGRpZG4ndCBpbmNsdWRlLCByZWRlZmluZSBvcgotICAgICAgICAgICAvLyBpbXBvcnQgdGhlIG9uZSBjb250YWluaW5nIGRlY2wuLi4KLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICAgICAgKioqKioqKioqKi8KLSAgICB9IC8vIGZpbmRYU0RvY3VtZW50Rm9yRGVjbChYU0RvY3VtZW50SW5mbywgRWxlbWVudCk6ICBYU0RvY3VtZW50SW5mbwotCi0gICAgLy8gcmV0dXJucyB3aGV0aGVyIG1vcmUgdGhhbiA8YW5ub3RhdGlvbj5zIG9jY3VyIGluIGNoaWxkcmVuIG9mIGVsZW0KLSAgICBwcml2YXRlIGJvb2xlYW4gbm9uQW5ub3RhdGlvbkNvbnRlbnQoRWxlbWVudCBlbGVtKSB7Ci0gICAgICAgIGZvcihFbGVtZW50IGNoaWxkID0gRE9NVXRpbC5nZXRGaXJzdENoaWxkRWxlbWVudChlbGVtKTsgY2hpbGQgIT0gbnVsbDsgY2hpbGQgPSBET01VdGlsLmdldE5leHRTaWJsaW5nRWxlbWVudChjaGlsZCkpIHsKLSAgICAgICAgICAgIGlmKCEoRE9NVXRpbC5nZXRMb2NhbE5hbWUoY2hpbGQpLmVxdWFscyhTY2hlbWFTeW1ib2xzLkVMVF9BTk5PVEFUSU9OKSkpIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9IC8vIG5vbkFubm90YXRpb25Db250ZW50KEVsZW1lbnQpOiAgYm9vbGVhbgotCi0gICAgcHJpdmF0ZSB2b2lkIHNldFNjaGVtYXNWaXNpYmxlKFhTRG9jdW1lbnRJbmZvIHN0YXJ0U2NoZW1hKSB7Ci0gICAgICAgIGlmIChET01VdGlsLmlzSGlkZGVuKHN0YXJ0U2NoZW1hLmZTY2hlbWFFbGVtZW50LCBmSGlkZGVuTm9kZXMpKSB7Ci0gICAgICAgICAgICAvLyBtYWtlIGl0IHZpc2libGUKLSAgICAgICAgICAgIERPTVV0aWwuc2V0VmlzaWJsZShzdGFydFNjaGVtYS5mU2NoZW1hRWxlbWVudCwgZkhpZGRlbk5vZGVzKTsKLSAgICAgICAgICAgIFZlY3RvcjxYU0RvY3VtZW50SW5mbz4gZGVwZW5kaW5nU2NoZW1hcyA9IGZEZXBlbmRlbmN5TWFwLmdldChzdGFydFNjaGVtYSk7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGRlcGVuZGluZ1NjaGVtYXMuc2l6ZSgpOyBpKyspIHsKLSAgICAgICAgICAgICAgICBzZXRTY2hlbWFzVmlzaWJsZShkZXBlbmRpbmdTY2hlbWFzLmVsZW1lbnRBdChpKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgLy8gaWYgaXQncyB2aXNpYmxlIGFscmVhZHkgdGhhbiBzbyBtdXN0IGJlIGl0cyBjaGlsZHJlbgotICAgIH0gLy8gc2V0U2NoZW1hc1Zpc2libGUoWFNEb2N1bWVudEluZm8pOiB2b2lkCi0KLSAgICBwcml2YXRlIFNpbXBsZUxvY2F0b3IgeGwgPSBuZXcgU2ltcGxlTG9jYXRvcigpOwotCi0gICAgLyoqCi0gICAgICogRXh0cmFjdCBsb2NhdGlvbiBpbmZvcm1hdGlvbiBmcm9tIGFuIEVsZW1lbnQgbm9kZSwgYW5kIGNyZWF0ZSBhCi0gICAgICogbmV3IFNpbXBsZUxvY2F0b3Igb2JqZWN0IGZyb20gc3VjaCBpbmZvcm1hdGlvbi4gUmV0dXJuaW5nIG51bGwgbWVhbnMKLSAgICAgKiBubyBpbmZvcm1hdGlvbiBjYW4gYmUgcmV0cmlldmVkIGZyb20gdGhlIGVsZW1lbnQuCi0gICAgICovCi0gICAgcHVibGljIFNpbXBsZUxvY2F0b3IgZWxlbWVudDJMb2NhdG9yKEVsZW1lbnQgZSkgewotICAgICAgICBpZiAoISggZSBpbnN0YW5jZW9mIEVsZW1lbnRJbXBsKSkKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotCi0gICAgICAgIFNpbXBsZUxvY2F0b3IgbCA9IG5ldyBTaW1wbGVMb2NhdG9yKCk7Ci0gICAgICAgIHJldHVybiBlbGVtZW50MkxvY2F0b3IoZSwgbCkgPyBsIDogbnVsbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBFeHRyYWN0IGxvY2F0aW9uIGluZm9ybWF0aW9uIGZyb20gYW4gRWxlbWVudCBub2RlLCBzdG9yZSBzdWNoCi0gICAgICogaW5mb3JtYXRpb24gaW4gdGhlIHBhc3NlZC1pbiBTaW1wbGVMb2NhdG9yIG9iamVjdCwgdGhlbiByZXR1cm4KLSAgICAgKiB0cnVlLiBSZXR1cm5pbmcgZmFsc2UgbWVhbnMgY2FuJ3QgZXh0cmFjdCBvciBzdG9yZSBzdWNoIGluZm9ybWF0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGVsZW1lbnQyTG9jYXRvcihFbGVtZW50IGUsIFNpbXBsZUxvY2F0b3IgbCkgewotICAgICAgICBpZiAobCA9PSBudWxsKQotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICBpZiAoZSBpbnN0YW5jZW9mIEVsZW1lbnRJbXBsKSB7Ci0gICAgICAgICAgICBFbGVtZW50SW1wbCBlbGUgPSAoRWxlbWVudEltcGwpZTsKLSAgICAgICAgICAgIC8vIGdldCBzeXN0ZW0gaWQgZnJvbSBkb2N1bWVudCBvYmplY3QKLSAgICAgICAgICAgIERvY3VtZW50IGRvYyA9IGVsZS5nZXRPd25lckRvY3VtZW50KCk7Ci0gICAgICAgICAgICBTdHJpbmcgc2lkID0gZkRvYzJTeXN0ZW1JZC5nZXQoRE9NVXRpbC5nZXRSb290KGRvYykpOwotICAgICAgICAgICAgLy8gbGluZS9jb2x1bW4gbnVtYmVycyBhcmUgc3RvcmVkIGluIHRoZSBlbGVtZW50IG5vZGUKLSAgICAgICAgICAgIGludCBsaW5lID0gZWxlLmdldExpbmVOdW1iZXIoKTsKLSAgICAgICAgICAgIGludCBjb2x1bW4gPSBlbGUuZ2V0Q29sdW1uTnVtYmVyKCk7Ci0gICAgICAgICAgICBsLnNldFZhbHVlcyhzaWQsIHNpZCwgbGluZSwgY29sdW1uLCBlbGUuZ2V0Q2hhcmFjdGVyT2Zmc2V0KCkpOwotICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIHByaXZhdGUgRWxlbWVudCBnZXRFbGVtZW50RnJvbU1hcChNYXA8U3RyaW5nLCBFbGVtZW50PiByZWdpc3RyeSwgU3RyaW5nIGRlY2xLZXkpIHsKLSAgICAgICAgaWYgKHJlZ2lzdHJ5ID09IG51bGwpIHJldHVybiBudWxsOwotICAgICAgICByZXR1cm4gcmVnaXN0cnkuZ2V0KGRlY2xLZXkpOwotICAgIH0KLQotICAgIHByaXZhdGUgWFNEb2N1bWVudEluZm8gZ2V0RG9jSW5mb0Zyb21NYXAoTWFwPFN0cmluZywgWFNEb2N1bWVudEluZm8+IHJlZ2lzdHJ5LCBTdHJpbmcgZGVjbEtleSkgewotICAgICAgICBpZiAocmVnaXN0cnkgPT0gbnVsbCkgcmV0dXJuIG51bGw7Ci0gICAgICAgIHJldHVybiByZWdpc3RyeS5nZXQoZGVjbEtleSk7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBPYmplY3QgZ2V0RnJvbU1hcChNYXAgcmVnaXN0cnksIFN0cmluZyBrZXkpIHsKLSAgICAgICAgaWYgKHJlZ2lzdHJ5ID09IG51bGwpIHJldHVybiBudWxsOwotICAgICAgICByZXR1cm4gcmVnaXN0cnkuZ2V0KGtleSk7Ci0gICAgfQotCi0gICAgdm9pZCByZXBvcnRTY2hlbWFGYXRhbEVycm9yKFN0cmluZyBrZXksIE9iamVjdFtdIGFyZ3MsIEVsZW1lbnQgZWxlKSB7Ci0gICAgICAgIHJlcG9ydFNjaGVtYUVycihrZXksIGFyZ3MsIGVsZSwgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9GQVRBTF9FUlJPUiwgbnVsbCk7Ci0gICAgfQotCi0gICAgdm9pZCByZXBvcnRTY2hlbWFFcnJvcihTdHJpbmcga2V5LCBPYmplY3RbXSBhcmdzLCBFbGVtZW50IGVsZSkgewotICAgICAgICByZXBvcnRTY2hlbWFFcnIoa2V5LCBhcmdzLCBlbGUsIFhNTEVycm9yUmVwb3J0ZXIuU0VWRVJJVFlfRVJST1IsIG51bGwpOwotICAgIH0KLQotICAgIHZvaWQgcmVwb3J0U2NoZW1hRXJyb3IoU3RyaW5nIGtleSwgT2JqZWN0W10gYXJncywgRWxlbWVudCBlbGUsIEV4Y2VwdGlvbiBleGNlcHRpb24pIHsKLSAgICAgICAgcmVwb3J0U2NoZW1hRXJyKGtleSwgYXJncywgZWxlLCBYTUxFcnJvclJlcG9ydGVyLlNFVkVSSVRZX0VSUk9SLCBleGNlcHRpb24pOwotICAgIH0KLQotICAgIHZvaWQgcmVwb3J0U2NoZW1hV2FybmluZyhTdHJpbmcga2V5LCBPYmplY3RbXSBhcmdzLCBFbGVtZW50IGVsZSkgewotICAgICAgICByZXBvcnRTY2hlbWFFcnIoa2V5LCBhcmdzLCBlbGUsIFhNTEVycm9yUmVwb3J0ZXIuU0VWRVJJVFlfV0FSTklORywgbnVsbCk7Ci0gICAgfQotCi0gICAgdm9pZCByZXBvcnRTY2hlbWFXYXJuaW5nKFN0cmluZyBrZXksIE9iamVjdFtdIGFyZ3MsIEVsZW1lbnQgZWxlLCBFeGNlcHRpb24gZXhjZXB0aW9uKSB7Ci0gICAgICAgIHJlcG9ydFNjaGVtYUVycihrZXksIGFyZ3MsIGVsZSwgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9XQVJOSU5HLCBleGNlcHRpb24pOwotICAgIH0KLQotICAgIHZvaWQgcmVwb3J0U2NoZW1hRXJyKFN0cmluZyBrZXksIE9iamVjdFtdIGFyZ3MsIEVsZW1lbnQgZWxlLCBzaG9ydCB0eXBlLCBFeGNlcHRpb24gZXhjZXB0aW9uKSB7Ci0gICAgICAgIGlmIChlbGVtZW50MkxvY2F0b3IoZWxlLCB4bCkpIHsKLSAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKHhsLCBYU01lc3NhZ2VGb3JtYXR0ZXIuU0NIRU1BX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAga2V5LCBhcmdzLCB0eXBlLCBleGNlcHRpb24pOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IoWFNNZXNzYWdlRm9ybWF0dGVyLlNDSEVNQV9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgIGtleSwgYXJncywgdHlwZSwgZXhjZXB0aW9uKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdyYW1tYXIgcG9vbCB1c2VkIGZvciB2YWxpZGF0aW5nIGFubm90YXRpb25zLiBUaGlzIHdpbGwgcmV0dXJuIGFsbCBvZiB0aGUKLSAgICAgKiBncmFtbWFycyBmcm9tIHRoZSBncmFtbWFyIGJ1Y2tldC4gSXQgd2lsbCBhbHNvIHJldHVybiBhbiBvYmplY3QgZm9yIHRoZQotICAgICAqIHNjaGVtYSBmb3Igc2NoZW1hcyB3aGljaCB3aWxsIGNvbnRhaW4gYXQgbGVhc3QgdGhlIHJlbGV2YW50IGRlY2xhcmF0aW9ucwotICAgICAqIGZvciBhbm5vdGF0aW9ucy4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBYU0Fubm90YXRpb25HcmFtbWFyUG9vbCBpbXBsZW1lbnRzIFhNTEdyYW1tYXJQb29sIHsKLQotICAgICAgICBwcml2YXRlIFhTR3JhbW1hckJ1Y2tldCBmR3JhbW1hckJ1Y2tldDsKLSAgICAgICAgcHJpdmF0ZSBHcmFtbWFyIFtdIGZJbml0aWFsR3JhbW1hclNldDsKLQotICAgICAgICBwdWJsaWMgR3JhbW1hcltdIHJldHJpZXZlSW5pdGlhbEdyYW1tYXJTZXQoU3RyaW5nIGdyYW1tYXJUeXBlKSB7Ci0gICAgICAgICAgICBpZiAoZ3JhbW1hclR5cGUgPT0gWE1MR3JhbW1hckRlc2NyaXB0aW9uLlhNTF9TQ0hFTUEpIHsKLSAgICAgICAgICAgICAgICBpZiAoZkluaXRpYWxHcmFtbWFyU2V0ID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGZHcmFtbWFyQnVja2V0ID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZJbml0aWFsR3JhbW1hclNldCA9IG5ldyBHcmFtbWFyIFtdIHtTY2hlbWFHcmFtbWFyLlNjaGVtYTRBbm5vdGF0aW9ucy5JTlNUQU5DRX07Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTY2hlbWFHcmFtbWFyIFtdIHNjaGVtYUdyYW1tYXJzID0gZkdyYW1tYXJCdWNrZXQuZ2V0R3JhbW1hcnMoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8qKgotICAgICAgICAgICAgICAgICAgICAgICAgICogSWYgdGhlIGdyYW1tYXIgYnVja2V0IGFscmVhZHkgY29udGFpbnMgdGhlIHNjaGVtYSBmb3Igc2NoZW1hcwotICAgICAgICAgICAgICAgICAgICAgICAgICogdGhlbiB3ZSBhbHJlYWR5IGhhdmUgdGhlIGRlZmluaXRpb25zIGZvciB0aGUgcGFydHMgcmVsZXZhbnQKLSAgICAgICAgICAgICAgICAgICAgICAgICAqIHRvIGFubm90YXRpb25zLgotICAgICAgICAgICAgICAgICAgICAgICAgICovCi0gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNjaGVtYUdyYW1tYXJzLmxlbmd0aDsgKytpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKFNjaGVtYVN5bWJvbHMuVVJJX1NDSEVNQUZPUlNDSEVNQS5lcXVhbHMoc2NoZW1hR3JhbW1hcnNbaV0uZ2V0VGFyZ2V0TmFtZXNwYWNlKCkpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZJbml0aWFsR3JhbW1hclNldCA9IHNjaGVtYUdyYW1tYXJzOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZkluaXRpYWxHcmFtbWFyU2V0OwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIEdyYW1tYXIgW10gZ3JhbW1hcnMgPSBuZXcgR3JhbW1hcltzY2hlbWFHcmFtbWFycy5sZW5ndGggKyAxXTsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoc2NoZW1hR3JhbW1hcnMsIDAsIGdyYW1tYXJzLCAwLCBzY2hlbWFHcmFtbWFycy5sZW5ndGgpOwotICAgICAgICAgICAgICAgICAgICAgICAgZ3JhbW1hcnNbZ3JhbW1hcnMubGVuZ3RoIC0gMV0gPSBTY2hlbWFHcmFtbWFyLlNjaGVtYTRBbm5vdGF0aW9ucy5JTlNUQU5DRTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZJbml0aWFsR3JhbW1hclNldCA9IGdyYW1tYXJzOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHJldHVybiBmSW5pdGlhbEdyYW1tYXJTZXQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gbmV3IEdyYW1tYXJbMF07Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCBjYWNoZUdyYW1tYXJzKFN0cmluZyBncmFtbWFyVHlwZSwgR3JhbW1hcltdIGdyYW1tYXJzKSB7Ci0KLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyBHcmFtbWFyIHJldHJpZXZlR3JhbW1hcihYTUxHcmFtbWFyRGVzY3JpcHRpb24gZGVzYykgewotICAgICAgICAgICAgaWYgKGRlc2MuZ2V0R3JhbW1hclR5cGUoKSA9PSBYTUxHcmFtbWFyRGVzY3JpcHRpb24uWE1MX1NDSEVNQSkgewotICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyB0bnMgPSAoKFhNTFNjaGVtYURlc2NyaXB0aW9uKSBkZXNjKS5nZXRUYXJnZXROYW1lc3BhY2UoKTsKLSAgICAgICAgICAgICAgICBpZiAoZkdyYW1tYXJCdWNrZXQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBHcmFtbWFyIGdyYW1tYXIgPSBmR3JhbW1hckJ1Y2tldC5nZXRHcmFtbWFyKHRucyk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChncmFtbWFyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBncmFtbWFyOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGlmIChTY2hlbWFTeW1ib2xzLlVSSV9TQ0hFTUFGT1JTQ0hFTUEuZXF1YWxzKHRucykpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFNjaGVtYUdyYW1tYXIuU2NoZW1hNEFubm90YXRpb25zLklOU1RBTkNFOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIHZvaWQgcmVmcmVzaEdyYW1tYXJzKFhTR3JhbW1hckJ1Y2tldCBnQnVja2V0KSB7Ci0gICAgICAgICAgICBmR3JhbW1hckJ1Y2tldCA9IGdCdWNrZXQ7Ci0gICAgICAgICAgICBmSW5pdGlhbEdyYW1tYXJTZXQgPSBudWxsOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIHZvaWQgbG9ja1Bvb2woKSB7fQotCi0gICAgICAgIHB1YmxpYyB2b2lkIHVubG9ja1Bvb2woKSB7fQotCi0gICAgICAgIHB1YmxpYyB2b2lkIGNsZWFyKCkge30KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiB1c2VkIHRvIGlkZW50aWZ5IGEgcmVmZXJlbmNlIHRvIGEgc2NoZW1hIGRvY3VtZW50Ci0gICAgICogaWYgdGhlIHNhbWUgZG9jdW1lbnQgaXMgcmVmZXJlbmNlZCB0d2ljZSB3aXRoIHRoZSBzYW1lIGtleSwgdGhlbgotICAgICAqIHdlIG9ubHkgbmVlZCB0byBwYXJzZSBpdCBvbmNlLgotICAgICAqCi0gICAgICogV2hlbiAyIFhTREtleSdzIGFyZSBjb21wYXJlZCwgdGhlIGZvbGxvd2luZyB0YWJsZSBjYW4gYmUgdXNlZCB0bwotICAgICAqIGRldGVybWluZSB3aGV0aGVyIHRoZXkgYXJlIGVxdWFsOgotICAgICAqICAgICAgaW5jICAgICByZWQgICAgIGltcCAgICAgcHJlICAgICBpbnMKLSAgICAgKiBpbmMgIE4vTCAgICAgID8gICAgICBOL0wgICAgIE4vTCAgICAgTi9MCi0gICAgICogcmVkICAgPyAgICAgIE4vTCAgICAgID8gICAgICAgPyAgICAgICA/Ci0gICAgICogaW1wICBOL0wgICAgICA/ICAgICAgTi9QICAgICBOL1AgICAgIE4vUAotICAgICAqIHByZSAgTi9MICAgICAgPyAgICAgIE4vUCAgICAgTi9QICAgICBOL1AKLSAgICAgKiBpbnMgIE4vTCAgICAgID8gICAgICBOL1AgICAgIE4vUCAgICAgTi9QCi0gICAgICoKLSAgICAgKiBXaGVyZTogTi9MOiBkdXBsaWNhdGUgd2hlbiB0aGV5IGhhdmUgdGhlIHNhbWUgbmFtZXNwYWNlIGFuZCBsb2NhdGlvbi4KLSAgICAgKiAgICAgICAgID8gOiBub3QgY2xlYXIgZnJvbSB0aGUgc3BlYy4KLSAgICAgKiAgICAgICAgICAgICBSRVZJU0lUOiB0byBzaW1wbGlmeSB0aGUgcHJvY2VzcywgYWxzbyBjb25zaWRlcmluZwotICAgICAqICAgICAgICAgICAgIGl0J3MgdmVyeSByYXJlLCB3ZSB0cmVhdCB0aGVtIGFzIG5vdCBkdXBsaWNhdGUuCi0gICAgICogICAgICAgIE4vUDogbm90IHBvc3NpYmxlLiBpbXAvcHJlL2lucyBhcmUgcmVmZXJlbmNlZCBieSBuYW1lc3BhY2UuCi0gICAgICogICAgICAgICAgICAgd2hlbiB0aGUgZmlyc3QgdGltZSB3ZSBlbmNvdW50ZXIgYSBzY2hlbWEgZG9jdW1lbnQgZm9yIGEKLSAgICAgKiAgICAgICAgICAgICBuYW1lc3BhY2UsIHdlIGNyZWF0ZSBhIGdyYW1tYXIgYW5kIHN0b3JlIGl0IGluIHRoZSBncmFtbWFyCi0gICAgICogICAgICAgICAgICAgYnVja2V0LiB3aGVuIHdlIHNlZSBhbm90aGVyIHJlZmVyZW5jZSB0byB0aGUgc2FtZSBuYW1lc3BhY2UsCi0gICAgICogICAgICAgICAgICAgd2UgZmlyc3QgY2hlY2sgd2hldGhlciBhIGdyYW1tYXIgd2l0aCB0aGUgc2FtZSBuYW1lc3BhY2UgaXMKLSAgICAgKiAgICAgICAgICAgICBhbHJlYWR5IGluIHRoZSBidWNrZXQsIHdoaWNoIGlzIHRydWUgaW4gdGhpcyBjYXNlLCBzbyB3ZQotICAgICAqICAgICAgICAgICAgIHdvbid0IGNyZWF0ZSBhbm90aGVyIFhTREtleS4KLSAgICAgKgotICAgICAqIENvbmNsdXNpb24gZnJvbSB0aGUgdGFibGU6IHR3byBYU0RLZXkncyBhcmUgZHVwbGljYXRlIG9ubHkgd2hlbiBhbGwgb2YKLSAgICAgKiB0aGUgZm9sbG93aW5nIGFyZSB0cnVlOgotICAgICAqIDEuIFRoZXkgYXJlIGJvdGggInJlZGVmaW5lIiwgb3IgbmVpdGhlciBpcyAicmVkZWZpbmUiOwotICAgICAqIDIuIFRoZXkgaGF2ZSB0aGUgc2FtZSBuYW1lc3BhY2U7Ci0gICAgICogMy4gVGhleSBoYXZlIHRoZSBzYW1lIG5vbi1udWxsIGxvY2F0aW9uLgotICAgICAqCi0gICAgICogQWJvdXQgMzogaWYgbmVpdGhlciBoYXMgYSBub24tbnVsbCBsb2NhdGlvbiwgdGhlbiBpdCdzIHRoZSBjYXNlIHdoZXJlCi0gICAgICogMiBpbnB1dCBzdHJlYW1zIGFyZSBwcm92aWRlZCwgYnV0IG5vIHN5c3RlbSBJRCBpcyBwcm92aWRlZC4gV2UgY2FuJ3QgdGVsbAotICAgICAqIHdoZXRoZXIgdGhlIDIgc3RyZWFtcyBoYXZlIHRoZSBzYW1lIGNvbnRlbnQsIHNvIHdlIHRyZWF0IHRoZW0gYXMgbm90Ci0gICAgICogZHVwbGljYXRlLgotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIFhTREtleSB7Ci0gICAgICAgIFN0cmluZyBzeXN0ZW1JZDsKLSAgICAgICAgc2hvcnQgIHJlZmVyVHlwZTsKLSAgICAgICAgLy8gZm9yIGluY2x1ZS9yZWRlZmluZSwgdGhpcyBpcyB0aGUgZW5jbG9zaW5nIG5hbWVzcGFjZQotICAgICAgICAvLyBmb3IgaW1wb3J0L3ByZXBhcnNlL2luc3RhbmNlLCB0aGlzIGlzIHRoZSB0YXJnZXQgbmFtZXNwYWNlCi0gICAgICAgIFN0cmluZyByZWZlck5TOwotCi0gICAgICAgIFhTREtleShTdHJpbmcgc3lzdGVtSWQsIHNob3J0IHJlZmVyVHlwZSwgU3RyaW5nIHJlZmVyTlMpIHsKLSAgICAgICAgICAgIHRoaXMuc3lzdGVtSWQgPSBzeXN0ZW1JZDsKLSAgICAgICAgICAgIHRoaXMucmVmZXJUeXBlID0gcmVmZXJUeXBlOwotICAgICAgICAgICAgdGhpcy5yZWZlck5TID0gcmVmZXJOUzsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7Ci0gICAgICAgICAgICAvLyBhY2NvcmRpbmcgdG8gdGhlIGRlc2NyaXB0aW9uIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhpcyBjbGFzcywKLSAgICAgICAgICAgIC8vIHdlIHVzZSB0aGUgaGFzaGNvZGUgb2YgdGhlIG5hbWVzcGFjZSBhcyB0aGUgaGFzaGNvZSBvZiB0aGlzIGtleS4KLSAgICAgICAgICAgIHJldHVybiByZWZlck5TID09IG51bGwgPyAwIDogcmVmZXJOUy5oYXNoQ29kZSgpOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmopIHsKLSAgICAgICAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIFhTREtleSkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBYU0RLZXkga2V5ID0gKFhTREtleSlvYmo7Ci0KLSAgICAgICAgICAgIC8vIGNvbmRpdGlvbiAxOiBib3RoIGFyZSByZWRlZmluZQotICAgICAgICAgICAgLyoqIGlmIChyZWZlclR5cGUgPT0gWFNERGVzY3JpcHRpb24uQ09OVEVYVF9SRURFRklORSB8fAotICAgICAgICAgICAgICAgICAgICBrZXkucmVmZXJUeXBlID09IFhTRERlc2NyaXB0aW9uLkNPTlRFWFRfUkVERUZJTkUpIHsKLSAgICAgICAgICAgICAgICBpZiAocmVmZXJUeXBlICE9IGtleS5yZWZlclR5cGUpCi0gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIH0qKi8KLQotICAgICAgICAgICAgLy8gY29uZGl0aW9uIDI6IHNhbWUgbmFtZXNwYWNlCi0gICAgICAgICAgICBpZiAocmVmZXJOUyAhPSBrZXkucmVmZXJOUykKLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0KLSAgICAgICAgICAgIC8vIGNvbmRpdGlvbiAzOiBzYW1lIG5vbi1udWxsIGxvY2F0aW9uCi0gICAgICAgICAgICBpZiAoc3lzdGVtSWQgPT0gbnVsbCB8fCAhc3lzdGVtSWQuZXF1YWxzKGtleS5zeXN0ZW1JZCkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgU0FYMlhOSVV0aWwgZXh0ZW5kcyBFcnJvckhhbmRsZXJXcmFwcGVyIHsKLSAgICAgICAgcHVibGljIHN0YXRpYyBYTUxQYXJzZUV4Y2VwdGlvbiBjcmVhdGVYTUxQYXJzZUV4Y2VwdGlvbjAoU0FYUGFyc2VFeGNlcHRpb24gZXhjZXB0aW9uKSB7Ci0gICAgICAgICAgICByZXR1cm4gY3JlYXRlWE1MUGFyc2VFeGNlcHRpb24oZXhjZXB0aW9uKTsKLSAgICAgICAgfQotICAgICAgICBwdWJsaWMgc3RhdGljIFhOSUV4Y2VwdGlvbiBjcmVhdGVYTklFeGNlcHRpb24wKFNBWEV4Y2VwdGlvbiBleGNlcHRpb24pIHsKLSAgICAgICAgICAgIHJldHVybiBjcmVhdGVYTklFeGNlcHRpb24oZXhjZXB0aW9uKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBwYXJhbSBzdGF0ZQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEdlbmVyYXRlU3ludGhldGljQW5ub3RhdGlvbnMoYm9vbGVhbiBzdGF0ZSkgewotICAgICAgICBmU2NoZW1hUGFyc2VyLnNldEZlYXR1cmUoR0VORVJBVEVfU1lOVEhFVElDX0FOTk9UQVRJT05TLCBzdGF0ZSk7Ci0gICAgfQotCi19IC8vIFhTREhhbmRsZXIKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvdHJhdmVyc2Vycy9YU0RLZXlyZWZUcmF2ZXJzZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvdHJhdmVyc2Vycy9YU0RLZXlyZWZUcmF2ZXJzZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDdkMTYwZS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL3RyYXZlcnNlcnMvWFNES2V5cmVmVHJhdmVyc2VyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMjUgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMSwgMjAwMiwyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMudHJhdmVyc2VyczsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5TY2hlbWFHcmFtbWFyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5TY2hlbWFTeW1ib2xzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5YU0VsZW1lbnREZWNsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5pZGVudGl0eS5JZGVudGl0eUNvbnN0cmFpbnQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLmlkZW50aXR5LktleVJlZjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMuaWRlbnRpdHkuVW5pcXVlT3JLZXk7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuUU5hbWU7Ci1pbXBvcnQgb3JnLnczYy5kb20uRWxlbWVudDsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGNvbnRhaW5zIGNvZGUgdGhhdCBpcyB1c2VkIHRvIHRyYXZlcnNlIDxrZXlyZWY+cy4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBOZWlsIEdyYWhhbSwgSUJNCi0gKiBAdmVyc2lvbiAkSWQ6IFhTREtleXJlZlRyYXZlcnNlci5qYXZhLHYgMS43IDIwMTAtMTEtMDEgMDQ6NDA6MDIgam9laHcgRXhwICQKLSAqLwotY2xhc3MgWFNES2V5cmVmVHJhdmVyc2VyIGV4dGVuZHMgWFNEQWJzdHJhY3RJRENvbnN0cmFpbnRUcmF2ZXJzZXIgewotCi0gICAgcHVibGljIFhTREtleXJlZlRyYXZlcnNlciAoWFNESGFuZGxlciBoYW5kbGVyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhTQXR0cmlidXRlQ2hlY2tlciBnQXR0ckNoZWNrKSB7Ci0gICAgICAgIHN1cGVyKGhhbmRsZXIsIGdBdHRyQ2hlY2spOwotICAgIH0KLQotICAgIHZvaWQgdHJhdmVyc2UoRWxlbWVudCBrckVsZW0sIFhTRWxlbWVudERlY2wgZWxlbWVudCwKLSAgICAgICAgICAgIFhTRG9jdW1lbnRJbmZvIHNjaGVtYURvYywgU2NoZW1hR3JhbW1hciBncmFtbWFyKSB7Ci0KLSAgICAgICAgLy8gR2VuZXJhbCBBdHRyaWJ1dGUgQ2hlY2tpbmcKLSAgICAgICAgT2JqZWN0W10gYXR0clZhbHVlcyA9IGZBdHRyQ2hlY2tlci5jaGVja0F0dHJpYnV0ZXMoa3JFbGVtLCBmYWxzZSwgc2NoZW1hRG9jKTsKLQotICAgICAgICAvLyBjcmVhdGUgaWRlbnRpdHkgY29uc3RyYWludAotICAgICAgICBTdHJpbmcga3JOYW1lID0gKFN0cmluZylhdHRyVmFsdWVzW1hTQXR0cmlidXRlQ2hlY2tlci5BVFRJRFhfTkFNRV07Ci0gICAgICAgIGlmKGtyTmFtZSA9PSBudWxsKXsKLSAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKCJzNHMtYXR0LW11c3QtYXBwZWFyIiwgbmV3IE9iamVjdCBbXSB7U2NoZW1hU3ltYm9scy5FTFRfS0VZUkVGICwgU2NoZW1hU3ltYm9scy5BVFRfTkFNRSB9LCBrckVsZW0pOwotICAgICAgICAgICAgLy9yZXR1cm4gdGhpcyBhcnJheSBiYWNrIHRvIHBvb2wKLSAgICAgICAgICAgIGZBdHRyQ2hlY2tlci5yZXR1cm5BdHRyQXJyYXkoYXR0clZhbHVlcywgc2NoZW1hRG9jKTsKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotICAgICAgICBRTmFtZSBrTmFtZSA9IChRTmFtZSlhdHRyVmFsdWVzW1hTQXR0cmlidXRlQ2hlY2tlci5BVFRJRFhfUkVGRVJdOwotICAgICAgICBpZihrTmFtZSA9PSBudWxsKXsKLSAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKCJzNHMtYXR0LW11c3QtYXBwZWFyIiwgbmV3IE9iamVjdCBbXSB7U2NoZW1hU3ltYm9scy5FTFRfS0VZUkVGICwgU2NoZW1hU3ltYm9scy5BVFRfUkVGRVIgfSwga3JFbGVtKTsKLSAgICAgICAgICAgIC8vcmV0dXJuIHRoaXMgYXJyYXkgYmFjayB0byBwb29sCi0gICAgICAgICAgICBmQXR0ckNoZWNrZXIucmV0dXJuQXR0ckFycmF5KGF0dHJWYWx1ZXMsIHNjaGVtYURvYyk7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLQotICAgICAgICBVbmlxdWVPcktleSBrZXkgPSBudWxsOwotICAgICAgICBJZGVudGl0eUNvbnN0cmFpbnQgcmV0ID0gKElkZW50aXR5Q29uc3RyYWludClmU2NoZW1hSGFuZGxlci5nZXRHbG9iYWxEZWNsKHNjaGVtYURvYywgWFNESGFuZGxlci5JREVOVElUWUNPTlNUUkFJTlRfVFlQRSwga05hbWUsIGtyRWxlbSk7Ci0gICAgICAgIC8vIGlmIHJldCA9PSBudWxsLCB3ZSd2ZSBhbHJlYWR5IHJlcG9ydGVkIGFuIGVycm9yIGluIGdldEdsb2JhbERlY2wKLSAgICAgICAgLy8gd2UgcmVwb3J0IGFuIGVycm9yIG9ubHkgd2hlbiByZXQgIT0gbnVsbCwgYW5kIHRoZSByZXR1cm4gdHlwZSBrZXlyZWYKLSAgICAgICAgaWYgKHJldCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAocmV0LmdldENhdGVnb3J5KCkgPT0gSWRlbnRpdHlDb25zdHJhaW50LklDX0tFWSB8fAotICAgICAgICAgICAgICAgIHJldC5nZXRDYXRlZ29yeSgpID09IElkZW50aXR5Q29uc3RyYWludC5JQ19VTklRVUUpIHsKLSAgICAgICAgICAgICAgICBrZXkgPSAoVW5pcXVlT3JLZXkpcmV0OwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcigic3JjLXJlc29sdmUiLCBuZXcgT2JqZWN0W117a05hbWUucmF3bmFtZSwgImlkZW50aXR5IGNvbnN0cmFpbnQga2V5L3VuaXF1ZSJ9LCBrckVsZW0pOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgaWYoa2V5ID09IG51bGwpIHsKLSAgICAgICAgICAgIGZBdHRyQ2hlY2tlci5yZXR1cm5BdHRyQXJyYXkoYXR0clZhbHVlcywgc2NoZW1hRG9jKTsKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotCi0gICAgICAgIEtleVJlZiBrZXlSZWYgPSBuZXcgS2V5UmVmKHNjaGVtYURvYy5mVGFyZ2V0TmFtZXNwYWNlLCBrck5hbWUsIGVsZW1lbnQuZk5hbWUsIGtleSk7Ci0KLSAgICAgICAgLy8gSWYgZXJyb3JzIG9jY3VycmVkIGluIHRyYXZlcnNpbmcgdGhlIGlkZW50aXR5IGNvbnN0cmFpbnQsIHRoZW4gZG9uJ3QKLSAgICAgICAgLy8gYWRkIGl0IHRvIHRoZSBzY2hlbWEsIHRvIGF2b2lkIGVycm9ycyB3aGVuIHByb2Nlc3NpbmcgdGhlIGluc3RhbmNlLgotICAgICAgICBpZiAodHJhdmVyc2VJZGVudGl0eUNvbnN0cmFpbnQoa2V5UmVmLCBrckVsZW0sIHNjaGVtYURvYywgYXR0clZhbHVlcykpIHsKLSAgICAgICAgICAgIC8vU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OiBJZGVudGl0eS1jb25zdHJhaW50IERlZmluaXRpb24gUHJvcGVydGllcyBDb3JyZWN0Ci0gICAgICAgICAgICAvLzIgSWYgdGhlIHtpZGVudGl0eS1jb25zdHJhaW50IGNhdGVnb3J5fSBpcyBrZXlyZWYsIHRoZSBjYXJkaW5hbGl0eSBvZiB0aGUge2ZpZWxkc30gbXVzdCBlcXVhbCB0aGF0IG9mIHRoZSB7ZmllbGRzfSBvZiB0aGUge3JlZmVyZW5jZWQga2V5fS4KLSAgICAgICAgICAgIGlmKGtleS5nZXRGaWVsZENvdW50KCkgIT0ga2V5UmVmLmdldEZpZWxkQ291bnQoKSkgewotICAgICAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKCJjLXByb3BzLWNvcnJlY3QuMiIgLCBuZXcgT2JqZWN0IFtdIHtrck5hbWUsa2V5LmdldElkZW50aXR5Q29uc3RyYWludE5hbWUoKX0sIGtyRWxlbSk7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIC8vIGFkZCBrZXkgcmVmZXJlbmNlIHRvIGVsZW1lbnQgZGVjbAotICAgICAgICAgICAgICAgIC8vIGFuZCBzdHVmZiB0aGlzIGluIHRoZSBncmFtbWFyCi0gICAgICAgICAgICAgICAgaWYgKGdyYW1tYXIuZ2V0SURDb25zdHJhaW50RGVjbChrZXlSZWYuZ2V0SWRlbnRpdHlDb25zdHJhaW50TmFtZSgpKSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGdyYW1tYXIuYWRkSURDb25zdHJhaW50RGVjbChlbGVtZW50LCBrZXlSZWYpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8vIGFsc28gYWRkIGl0IHRvIGV4dGVuZGVkIG1hcAotICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBsb2MgPSBmU2NoZW1hSGFuZGxlci5zY2hlbWFEb2N1bWVudDJTeXN0ZW1JZChzY2hlbWFEb2MpOwotICAgICAgICAgICAgICAgIGZpbmFsIElkZW50aXR5Q29uc3RyYWludCBpZGMgPSBncmFtbWFyLmdldElEQ29uc3RyYWludERlY2woa2V5UmVmLmdldElkZW50aXR5Q29uc3RyYWludE5hbWUoKSwgbG9jKTsKLSAgICAgICAgICAgICAgICBpZiAoaWRjICA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGdyYW1tYXIuYWRkSURDb25zdHJhaW50RGVjbChlbGVtZW50LCBrZXlSZWYsIGxvYyk7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgLy8gaGFuZGxlIGR1cGxpY2F0ZXMKLSAgICAgICAgICAgICAgICBpZiAoZlNjaGVtYUhhbmRsZXIuZlRvbGVyYXRlRHVwbGljYXRlcykgewotICAgICAgICAgICAgICAgICAgICBpZiAoaWRjICAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaWRjIGluc3RhbmNlb2YgS2V5UmVmKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5UmVmID0gKEtleVJlZikgaWRjOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGZTY2hlbWFIYW5kbGVyLmFkZElEQ29uc3RyYWludERlY2woa2V5UmVmKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBhbmQgcHV0IGJhY2sgYXR0cmlidXRlcwotICAgICAgICBmQXR0ckNoZWNrZXIucmV0dXJuQXR0ckFycmF5KGF0dHJWYWx1ZXMsIHNjaGVtYURvYyk7Ci0gICAgfSAvLyB0cmF2ZXJzZShFbGVtZW50LGludCxYU0RvY3VtZW50SW5mbywgU2NoZW1hR3JhbW1hcikKLX0gLy8gWFNES2V5cmVmVHJhdmVyc2VyCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL3RyYXZlcnNlcnMvWFNETm90YXRpb25UcmF2ZXJzZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvdHJhdmVyc2Vycy9YU0ROb3RhdGlvblRyYXZlcnNlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4NDZjOWI5Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvdHJhdmVyc2Vycy9YU0ROb3RhdGlvblRyYXZlcnNlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTM0ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLnRyYXZlcnNlcnM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMuU2NoZW1hR3JhbW1hcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMuU2NoZW1hU3ltYm9sczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMuWFNBbm5vdGF0aW9uSW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMuWFNOb3RhdGlvbkRlY2w7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLnV0aWwuWFNPYmplY3RMaXN0SW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuRE9NVXRpbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTT2JqZWN0TGlzdDsKLWltcG9ydCBvcmcudzNjLmRvbS5FbGVtZW50OwotCi0vKioKLSAqIFRoZSBub3RhdGlvbiBkZWNsYXJhdGlvbiBzY2hlbWEgY29tcG9uZW50IHRyYXZlcnNlci4KLSAqCi0gKiA8bm90YXRpb24KLSAqICAgaWQgPSBJRAotICogICBuYW1lID0gTkNOYW1lCi0gKiAgIHB1YmxpYyA9IGFueVVSSQotICogICBzeXN0ZW0gPSBhbnlVUkkKLSAqICAge2FueSBhdHRyaWJ1dGVzIHdpdGggbm9uLXNjaGVtYSBuYW1lc3BhY2UgLiAuIC59PgotICogICBDb250ZW50OiAoYW5ub3RhdGlvbj8pCi0gKiA8L25vdGF0aW9uPgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIFJhaHVsIFNyaXZhc3RhdmEsIFN1biBNaWNyb3N5c3RlbXMgSW5jLgotICogQGF1dGhvciBFbGVuYSBMaXRhbmksIElCTQotICogQHZlcnNpb24gJElkOiBYU0ROb3RhdGlvblRyYXZlcnNlci5qYXZhLHYgMS43IDIwMTAtMTEtMDEgMDQ6NDA6MDIgam9laHcgRXhwICQKLSAqLwotY2xhc3MgIFhTRE5vdGF0aW9uVHJhdmVyc2VyIGV4dGVuZHMgWFNEQWJzdHJhY3RUcmF2ZXJzZXIgewotCi0gICAgWFNETm90YXRpb25UcmF2ZXJzZXIgKFhTREhhbmRsZXIgaGFuZGxlciwKLSAgICAgICAgICAgIFhTQXR0cmlidXRlQ2hlY2tlciBnQXR0ckNoZWNrKSB7Ci0gICAgICAgIHN1cGVyKGhhbmRsZXIsIGdBdHRyQ2hlY2spOwotICAgIH0KLQotICAgIFhTTm90YXRpb25EZWNsIHRyYXZlcnNlKEVsZW1lbnQgZWxtTm9kZSwKLSAgICAgICAgICAgIFhTRG9jdW1lbnRJbmZvIHNjaGVtYURvYywKLSAgICAgICAgICAgIFNjaGVtYUdyYW1tYXIgZ3JhbW1hcikgewotCi0gICAgICAgIC8vIEdlbmVyYWwgQXR0cmlidXRlIENoZWNraW5nIGZvciBlbG1Ob2RlCi0gICAgICAgIE9iamVjdFtdIGF0dHJWYWx1ZXMgPSBmQXR0ckNoZWNrZXIuY2hlY2tBdHRyaWJ1dGVzKGVsbU5vZGUsIHRydWUsIHNjaGVtYURvYyk7Ci0gICAgICAgIC8vZ2V0IGF0dHJpYnV0ZXMKLSAgICAgICAgU3RyaW5nICBuYW1lQXR0ciAgID0gKFN0cmluZykgYXR0clZhbHVlc1tYU0F0dHJpYnV0ZUNoZWNrZXIuQVRUSURYX05BTUVdOwotCi0gICAgICAgIFN0cmluZyAgcHVibGljQXR0ciA9IChTdHJpbmcpIGF0dHJWYWx1ZXNbWFNBdHRyaWJ1dGVDaGVja2VyLkFUVElEWF9QVUJMSUNdOwotICAgICAgICBTdHJpbmcgIHN5c3RlbUF0dHIgPSAoU3RyaW5nKSBhdHRyVmFsdWVzW1hTQXR0cmlidXRlQ2hlY2tlci5BVFRJRFhfU1lTVEVNXTsKLSAgICAgICAgaWYgKG5hbWVBdHRyID09IG51bGwpIHsKLSAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKCJzNHMtYXR0LW11c3QtYXBwZWFyIiwgbmV3IE9iamVjdFtde1NjaGVtYVN5bWJvbHMuRUxUX05PVEFUSU9OLCBTY2hlbWFTeW1ib2xzLkFUVF9OQU1FfSwgZWxtTm9kZSk7Ci0gICAgICAgICAgICBmQXR0ckNoZWNrZXIucmV0dXJuQXR0ckFycmF5KGF0dHJWYWx1ZXMsIHNjaGVtYURvYyk7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChzeXN0ZW1BdHRyID09IG51bGwgJiYgcHVibGljQXR0ciA9PSBudWxsKSB7Ci0gICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcigiUHVibGljU3lzdGVtT25Ob3RhdGlvbiIsIG51bGwsIGVsbU5vZGUpOwotICAgICAgICAgICAgcHVibGljQXR0ciA9ICJtaXNzaW5nIjsKLSAgICAgICAgfQotCi0gICAgICAgIFhTTm90YXRpb25EZWNsIG5vdGF0aW9uID0gbmV3IFhTTm90YXRpb25EZWNsKCk7Ci0gICAgICAgIG5vdGF0aW9uLmZOYW1lID0gbmFtZUF0dHI7Ci0gICAgICAgIG5vdGF0aW9uLmZUYXJnZXROYW1lc3BhY2UgPSBzY2hlbWFEb2MuZlRhcmdldE5hbWVzcGFjZTsKLSAgICAgICAgbm90YXRpb24uZlB1YmxpY0lkID0gcHVibGljQXR0cjsKLSAgICAgICAgbm90YXRpb24uZlN5c3RlbUlkID0gc3lzdGVtQXR0cjsKLQotICAgICAgICAvL2NoZWNrIGNvbnRlbnQKLSAgICAgICAgRWxlbWVudCBjb250ZW50ID0gRE9NVXRpbC5nZXRGaXJzdENoaWxkRWxlbWVudChlbG1Ob2RlKTsKLSAgICAgICAgWFNBbm5vdGF0aW9uSW1wbCBhbm5vdGF0aW9uID0gbnVsbDsKLQotICAgICAgICBpZiAoY29udGVudCAhPSBudWxsICYmIERPTVV0aWwuZ2V0TG9jYWxOYW1lKGNvbnRlbnQpLmVxdWFscyhTY2hlbWFTeW1ib2xzLkVMVF9BTk5PVEFUSU9OKSkgewotICAgICAgICAgICAgYW5ub3RhdGlvbiA9IHRyYXZlcnNlQW5ub3RhdGlvbkRlY2woY29udGVudCwgYXR0clZhbHVlcywgZmFsc2UsIHNjaGVtYURvYyk7Ci0gICAgICAgICAgICBjb250ZW50ID0gRE9NVXRpbC5nZXROZXh0U2libGluZ0VsZW1lbnQoY29udGVudCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBTdHJpbmcgdGV4dCA9IERPTVV0aWwuZ2V0U3ludGhldGljQW5ub3RhdGlvbihlbG1Ob2RlKTsKLSAgICAgICAgICAgIGlmICh0ZXh0ICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBhbm5vdGF0aW9uID0gdHJhdmVyc2VTeW50aGV0aWNBbm5vdGF0aW9uKGVsbU5vZGUsIHRleHQsIGF0dHJWYWx1ZXMsIGZhbHNlLCBzY2hlbWFEb2MpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIFhTT2JqZWN0TGlzdCBhbm5vdGF0aW9uczsKLSAgICAgICAgaWYgKGFubm90YXRpb24gIT0gbnVsbCkgewotICAgICAgICAgICAgYW5ub3RhdGlvbnMgPSBuZXcgWFNPYmplY3RMaXN0SW1wbCgpOwotICAgICAgICAgICAgKChYU09iamVjdExpc3RJbXBsKSBhbm5vdGF0aW9ucykuYWRkWFNPYmplY3QoYW5ub3RhdGlvbik7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBhbm5vdGF0aW9ucyA9IFhTT2JqZWN0TGlzdEltcGwuRU1QVFlfTElTVDsKLSAgICAgICAgfQotICAgICAgICBub3RhdGlvbi5mQW5ub3RhdGlvbnMgPSBhbm5vdGF0aW9uczsKLSAgICAgICAgaWYgKGNvbnRlbnQhPW51bGwpewotICAgICAgICAgICAgT2JqZWN0W10gYXJncyA9IG5ldyBPYmplY3QgW10ge1NjaGVtYVN5bWJvbHMuRUxUX05PVEFUSU9OLCAiKGFubm90YXRpb24/KSIsIERPTVV0aWwuZ2V0TG9jYWxOYW1lKGNvbnRlbnQpfTsKLSAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKCJzNHMtZWx0LW11c3QtbWF0Y2guMSIsIGFyZ3MsIGNvbnRlbnQpOwotCi0gICAgICAgIH0KLSAgICAgICAgaWYgKGdyYW1tYXIuZ2V0R2xvYmFsTm90YXRpb25EZWNsKG5vdGF0aW9uLmZOYW1lKSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBncmFtbWFyLmFkZEdsb2JhbE5vdGF0aW9uRGVjbChub3RhdGlvbik7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBhbHNvIGFkZCBpdCB0byBleHRlbmRlZCBtYXAKLSAgICAgICAgZmluYWwgU3RyaW5nIGxvYyA9IGZTY2hlbWFIYW5kbGVyLnNjaGVtYURvY3VtZW50MlN5c3RlbUlkKHNjaGVtYURvYyk7Ci0gICAgICAgIGZpbmFsIFhTTm90YXRpb25EZWNsIG5vdGF0aW9uMiA9IGdyYW1tYXIuZ2V0R2xvYmFsTm90YXRpb25EZWNsKG5vdGF0aW9uLmZOYW1lLCBsb2MpOwotICAgICAgICBpZiAobm90YXRpb24yID09IG51bGwpIHsKLSAgICAgICAgICAgIGdyYW1tYXIuYWRkR2xvYmFsTm90YXRpb25EZWNsKG5vdGF0aW9uLCBsb2MpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gaGFuZGxlIGR1cGxpY2F0ZXMKLSAgICAgICAgaWYgKGZTY2hlbWFIYW5kbGVyLmZUb2xlcmF0ZUR1cGxpY2F0ZXMpIHsKLSAgICAgICAgICAgIGlmIChub3RhdGlvbjIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIG5vdGF0aW9uID0gbm90YXRpb24yOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZlNjaGVtYUhhbmRsZXIuYWRkR2xvYmFsTm90YXRpb25EZWNsKG5vdGF0aW9uKTsKLSAgICAgICAgfQotICAgICAgICBmQXR0ckNoZWNrZXIucmV0dXJuQXR0ckFycmF5KGF0dHJWYWx1ZXMsIHNjaGVtYURvYyk7Ci0KLSAgICAgICAgcmV0dXJuIG5vdGF0aW9uOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvdHJhdmVyc2Vycy9YU0RTaW1wbGVUeXBlVHJhdmVyc2VyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL3RyYXZlcnNlcnMvWFNEU2ltcGxlVHlwZVRyYXZlcnNlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzNTU4ODFlLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvdHJhdmVyc2Vycy9YU0RTaW1wbGVUeXBlVHJhdmVyc2VyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw1MjIgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMudHJhdmVyc2VyczsKLQotaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7Ci1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5JbnZhbGlkRGF0YXR5cGVGYWNldEV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYuU2NoZW1hRFZGYWN0b3J5OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5YU1NpbXBsZVR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LnhzLlNjaGVtYURWRmFjdG9yeUltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LnhzLlhTU2ltcGxlVHlwZURlY2w7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlNjaGVtYUdyYW1tYXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlNjaGVtYVN5bWJvbHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlhTQW5ub3RhdGlvbkltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLnV0aWwuWEludDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMudXRpbC5YU09iamVjdExpc3RJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5ET01VdGlsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlFOYW1lOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNDb25zdGFudHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU09iamVjdExpc3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU1R5cGVEZWZpbml0aW9uOwotaW1wb3J0IG9yZy53M2MuZG9tLkVsZW1lbnQ7Ci0KLS8qKgotICogVGhlIHNpbXBsZSB0eXBlIGRlZmluaXRpb24gc2NoZW1hIGNvbXBvbmVudCB0cmF2ZXJzZXIuCi0gKgotICogPHNpbXBsZVR5cGUKLSAqICAgZmluYWwgPSAoI2FsbCB8IChsaXN0IHwgdW5pb24gfCByZXN0cmljdGlvbikpCi0gKiAgIGlkID0gSUQKLSAqICAgbmFtZSA9IE5DTmFtZQotICogICB7YW55IGF0dHJpYnV0ZXMgd2l0aCBub24tc2NoZW1hIG5hbWVzcGFjZSAuIC4gLn0+Ci0gKiAgIENvbnRlbnQ6IChhbm5vdGF0aW9uPywgKHJlc3RyaWN0aW9uIHwgbGlzdCB8IHVuaW9uKSkKLSAqIDwvc2ltcGxlVHlwZT4KLSAqCi0gKiA8cmVzdHJpY3Rpb24KLSAqICAgYmFzZSA9IFFOYW1lCi0gKiAgIGlkID0gSUQKLSAqICAge2FueSBhdHRyaWJ1dGVzIHdpdGggbm9uLXNjaGVtYSBuYW1lc3BhY2UgLiAuIC59PgotICogICBDb250ZW50OiAoYW5ub3RhdGlvbj8sIChzaW1wbGVUeXBlPywgKG1pbkV4Y2x1c2l2ZSB8IG1pbkluY2x1c2l2ZSB8IG1heEV4Y2x1c2l2ZSB8IG1heEluY2x1c2l2ZSB8IHRvdGFsRGlnaXRzIHwgZnJhY3Rpb25EaWdpdHMgfCBsZW5ndGggfCBtaW5MZW5ndGggfCBtYXhMZW5ndGggfCBlbnVtZXJhdGlvbiB8IHdoaXRlU3BhY2UgfCBwYXR0ZXJuKSopKQotICogPC9yZXN0cmljdGlvbj4KLSAqCi0gKiA8bGlzdAotICogICBpZCA9IElECi0gKiAgIGl0ZW1UeXBlID0gUU5hbWUKLSAqICAge2FueSBhdHRyaWJ1dGVzIHdpdGggbm9uLXNjaGVtYSBuYW1lc3BhY2UgLiAuIC59PgotICogICBDb250ZW50OiAoYW5ub3RhdGlvbj8sIChzaW1wbGVUeXBlPykpCi0gKiA8L2xpc3Q+Ci0gKgotICogPHVuaW9uCi0gKiAgIGlkID0gSUQKLSAqICAgbWVtYmVyVHlwZXMgPSBMaXN0IG9mIFFOYW1lCi0gKiAgIHthbnkgYXR0cmlidXRlcyB3aXRoIG5vbi1zY2hlbWEgbmFtZXNwYWNlIC4gLiAufT4KLSAqICAgQ29udGVudDogKGFubm90YXRpb24/LCAoc2ltcGxlVHlwZSopKQotICogPC91bmlvbj4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBFbGVuYSBMaXRhbmksIElCTQotICogQGF1dGhvciBOZWVyYWogQmFqYWosIFN1biBNaWNyb3N5c3RlbXMsIEluYy4KLSAqIEBhdXRob3IgU2FuZHkgR2FvLCBJQk0KLSAqCi0gKiBAdmVyc2lvbiAkSWQ6IFhTRFNpbXBsZVR5cGVUcmF2ZXJzZXIuamF2YSx2IDEuNyAyMDEwLTExLTAxIDA0OjQwOjAyIGpvZWh3IEV4cCAkCi0gKi8KLWNsYXNzIFhTRFNpbXBsZVR5cGVUcmF2ZXJzZXIgZXh0ZW5kcyBYU0RBYnN0cmFjdFRyYXZlcnNlciB7Ci0KLSAgICAvLyB3aGV0aGVyIHRoZSB0eXBlIGJlaW5nIHBhcnNlZCBpcyBhIFM0UyBidWlsdC1pbiB0eXBlLgotICAgIHByaXZhdGUgYm9vbGVhbiBmSXNCdWlsdEluID0gZmFsc2U7Ci0KLSAgICBYU0RTaW1wbGVUeXBlVHJhdmVyc2VyIChYU0RIYW5kbGVyIGhhbmRsZXIsCi0gICAgICAgICAgICBYU0F0dHJpYnV0ZUNoZWNrZXIgZ0F0dHJDaGVjaykgewotICAgICAgICBzdXBlcihoYW5kbGVyLCBnQXR0ckNoZWNrKTsKLSAgICB9Ci0KLSAgICAvL3JldHVybiBxdWFsaWZpZWQgbmFtZSBvZiBzaW1wbGVUeXBlIG9yIGVtcHR5IHN0cmluZyBpZiBlcnJvciBvY2N1cmVkCi0gICAgWFNTaW1wbGVUeXBlIHRyYXZlcnNlR2xvYmFsKEVsZW1lbnQgZWxtTm9kZSwKLSAgICAgICAgICAgIFhTRG9jdW1lbnRJbmZvIHNjaGVtYURvYywKLSAgICAgICAgICAgIFNjaGVtYUdyYW1tYXIgZ3JhbW1hcikgewotCi0gICAgICAgIC8vIEdlbmVyYWwgQXR0cmlidXRlIENoZWNraW5nCi0gICAgICAgIE9iamVjdFtdIGF0dHJWYWx1ZXMgPSBmQXR0ckNoZWNrZXIuY2hlY2tBdHRyaWJ1dGVzKGVsbU5vZGUsIHRydWUsIHNjaGVtYURvYyk7Ci0gICAgICAgIFN0cmluZyBuYW1lQXR0ID0gKFN0cmluZylhdHRyVmFsdWVzW1hTQXR0cmlidXRlQ2hlY2tlci5BVFRJRFhfTkFNRV07Ci0gICAgICAgIGlmIChuYW1lQXR0ID09IG51bGwpIHsKLSAgICAgICAgICAgIGF0dHJWYWx1ZXNbWFNBdHRyaWJ1dGVDaGVja2VyLkFUVElEWF9OQU1FXSA9IE5PX05BTUU7Ci0gICAgICAgIH0KLSAgICAgICAgWFNTaW1wbGVUeXBlIHR5cGUgPSB0cmF2ZXJzZVNpbXBsZVR5cGVEZWNsKGVsbU5vZGUsIGF0dHJWYWx1ZXMsIHNjaGVtYURvYywgZ3JhbW1hcik7Ci0gICAgICAgIGZBdHRyQ2hlY2tlci5yZXR1cm5BdHRyQXJyYXkoYXR0clZhbHVlcywgc2NoZW1hRG9jKTsKLQotICAgICAgICAvLyBpZiBpdCdzIGEgZ2xvYmFsIHR5cGUgd2l0aG91dCBhIG5hbWUsIHJldHVybiBudWxsCi0gICAgICAgIGlmIChuYW1lQXR0ID09IG51bGwpIHsKLSAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKCJzNHMtYXR0LW11c3QtYXBwZWFyIiwgbmV3IE9iamVjdFtde1NjaGVtYVN5bWJvbHMuRUxUX1NJTVBMRVRZUEUsIFNjaGVtYVN5bWJvbHMuQVRUX05BTUV9LCBlbG1Ob2RlKTsKLSAgICAgICAgICAgIHR5cGUgPSBudWxsOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gZG9uJ3QgYWRkIGdsb2JhbCBjb21wb25lbnRzIHdpdGhvdXQgbmFtZSB0byB0aGUgZ3JhbW1hcgotICAgICAgICBpZiAodHlwZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAoZ3JhbW1hci5nZXRHbG9iYWxUeXBlRGVjbCh0eXBlLmdldE5hbWUoKSkgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGdyYW1tYXIuYWRkR2xvYmFsU2ltcGxlVHlwZURlY2wodHlwZSk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIGFsc28gYWRkIGl0IHRvIGV4dGVuZGVkIG1hcAotICAgICAgICAgICAgZmluYWwgU3RyaW5nIGxvYyA9IGZTY2hlbWFIYW5kbGVyLnNjaGVtYURvY3VtZW50MlN5c3RlbUlkKHNjaGVtYURvYyk7Ci0gICAgICAgICAgICBmaW5hbCBYU1R5cGVEZWZpbml0aW9uIHR5cGUyID0gZ3JhbW1hci5nZXRHbG9iYWxUeXBlRGVjbCh0eXBlLmdldE5hbWUoKSwgbG9jKTsKLSAgICAgICAgICAgIGlmICh0eXBlMiA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZ3JhbW1hci5hZGRHbG9iYWxTaW1wbGVUeXBlRGVjbCh0eXBlLCBsb2MpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBoYW5kbGUgZHVwbGljYXRlcwotICAgICAgICAgICAgaWYgKGZTY2hlbWFIYW5kbGVyLmZUb2xlcmF0ZUR1cGxpY2F0ZXMpIHsKLSAgICAgICAgICAgICAgICBpZiAodHlwZTIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBpZiAodHlwZTIgaW5zdGFuY2VvZiBYU1NpbXBsZVR5cGUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUgPSAoWFNTaW1wbGVUeXBlKSB0eXBlMjsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBmU2NoZW1hSGFuZGxlci5hZGRHbG9iYWxUeXBlRGVjbCh0eXBlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiB0eXBlOwotICAgIH0KLQotICAgIFhTU2ltcGxlVHlwZSB0cmF2ZXJzZUxvY2FsKEVsZW1lbnQgZWxtTm9kZSwKLSAgICAgICAgICAgIFhTRG9jdW1lbnRJbmZvIHNjaGVtYURvYywKLSAgICAgICAgICAgIFNjaGVtYUdyYW1tYXIgZ3JhbW1hcikgewotCi0gICAgICAgIC8vIEdlbmVyYWwgQXR0cmlidXRlIENoZWNraW5nCi0gICAgICAgIE9iamVjdFtdIGF0dHJWYWx1ZXMgPSBmQXR0ckNoZWNrZXIuY2hlY2tBdHRyaWJ1dGVzKGVsbU5vZGUsIGZhbHNlLCBzY2hlbWFEb2MpOwotICAgICAgICBTdHJpbmcgbmFtZSA9IGdlbkFub25UeXBlTmFtZShlbG1Ob2RlKTsKLSAgICAgICAgWFNTaW1wbGVUeXBlIHR5cGUgPSBnZXRTaW1wbGVUeXBlIChuYW1lLCBlbG1Ob2RlLCBhdHRyVmFsdWVzLCBzY2hlbWFEb2MsIGdyYW1tYXIpOwotICAgICAgICBpZiAodHlwZSBpbnN0YW5jZW9mIFhTU2ltcGxlVHlwZURlY2wpIHsKLSAgICAgICAgICAgICgoWFNTaW1wbGVUeXBlRGVjbCl0eXBlKS5zZXRBbm9ueW1vdXModHJ1ZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZkF0dHJDaGVja2VyLnJldHVybkF0dHJBcnJheShhdHRyVmFsdWVzLCBzY2hlbWFEb2MpOwotCi0gICAgICAgIHJldHVybiB0eXBlOwotICAgIH0KLQotICAgIHByaXZhdGUgWFNTaW1wbGVUeXBlIHRyYXZlcnNlU2ltcGxlVHlwZURlY2woRWxlbWVudCBzaW1wbGVUeXBlRGVjbCwKLSAgICAgICAgICAgIE9iamVjdFtdIGF0dHJWYWx1ZXMsCi0gICAgICAgICAgICBYU0RvY3VtZW50SW5mbyBzY2hlbWFEb2MsCi0gICAgICAgICAgICBTY2hlbWFHcmFtbWFyIGdyYW1tYXIpIHsKLQotICAgICAgICAvLyBnZXQgbmFtZSBhbmQgZmluYWwgdmFsdWVzCi0gICAgICAgIFN0cmluZyBuYW1lID0gKFN0cmluZylhdHRyVmFsdWVzW1hTQXR0cmlidXRlQ2hlY2tlci5BVFRJRFhfTkFNRV07Ci0gICAgICAgIHJldHVybiBnZXRTaW1wbGVUeXBlKG5hbWUsIHNpbXBsZVR5cGVEZWNsLCBhdHRyVmFsdWVzLCBzY2hlbWFEb2MsIGdyYW1tYXIpOwotICAgIH0KLQotICAgIC8qCi0gICAgICogR2VuZXJhdGUgYSBuYW1lIGZvciBhbiBhbm9ueW1vdXMgdHlwZQotICAgICAqLwotICAgIHByaXZhdGUgU3RyaW5nIGdlbkFub25UeXBlTmFtZShFbGVtZW50IHNpbXBsZVR5cGVEZWNsKSB7Ci0KLSAgICAgICAgLy8gR2VuZXJhdGUgYSB1bmlxdWUgbmFtZSBmb3IgdGhlIGFub255bW91cyB0eXBlIGJ5IGNvbmNhdGVuYXRpbmcgdG9nZXRoZXIgdGhlCi0gICAgICAgIC8vIG5hbWVzIG9mIHBhcmVudCBub2RlcwotICAgICAgICAvLyBUaGUgbmFtZSBpcyBxdWl0ZSBnb29kIGZvciBkZWJ1Z2dpbmcvZXJyb3IgcHVycG9zZXMsIGJ1dCB3ZSBtYXkgd2FudCB0bwotICAgICAgICAvLyByZXZpc2l0IGhvdyB0aGlzIGlzIGRvbmUgZm9yIHBlcmZvcm1hbmNlIHJlYXNvbnMgKExNKS4KLSAgICAgICAgU3RyaW5nQnVmZmVyIHR5cGVOYW1lID0gbmV3IFN0cmluZ0J1ZmZlcigiI0Fub25UeXBlXyIpOwotICAgICAgICBFbGVtZW50IG5vZGUgPSBET01VdGlsLmdldFBhcmVudChzaW1wbGVUeXBlRGVjbCk7Ci0gICAgICAgIHdoaWxlIChub2RlICE9IG51bGwgJiYgKG5vZGUgIT0gRE9NVXRpbC5nZXRSb290KERPTVV0aWwuZ2V0RG9jdW1lbnQobm9kZSkpKSkgewotICAgICAgICAgICAgdHlwZU5hbWUuYXBwZW5kKG5vZGUuZ2V0QXR0cmlidXRlKFNjaGVtYVN5bWJvbHMuQVRUX05BTUUpKTsKLSAgICAgICAgICAgIG5vZGUgPSBET01VdGlsLmdldFBhcmVudChub2RlKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gdHlwZU5hbWUudG9TdHJpbmcoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAcGFyYW0gbmFtZQotICAgICAqIEBwYXJhbSBzaW1wbGVUeXBlRGVjbAotICAgICAqIEBwYXJhbSBhdHRyVmFsdWVzCi0gICAgICogQHBhcmFtIHNjaGVtYURvYwotICAgICAqIEBwYXJhbSBncmFtbWFyCi0gICAgICogQHJldHVybgotICAgICAqLwotICAgIHByaXZhdGUgWFNTaW1wbGVUeXBlIGdldFNpbXBsZVR5cGUoU3RyaW5nIG5hbWUsIEVsZW1lbnQgc2ltcGxlVHlwZURlY2wsIE9iamVjdFtdIGF0dHJWYWx1ZXMsIFhTRG9jdW1lbnRJbmZvIHNjaGVtYURvYywgU2NoZW1hR3JhbW1hciBncmFtbWFyKSB7Ci0gICAgICAgIFhJbnQgZmluYWxBdHRyID0gKFhJbnQpYXR0clZhbHVlc1tYU0F0dHJpYnV0ZUNoZWNrZXIuQVRUSURYX0ZJTkFMXTsKLSAgICAgICAgaW50IGZpbmFsUHJvcGVydHkgPSBmaW5hbEF0dHIgPT0gbnVsbCA/IHNjaGVtYURvYy5mRmluYWxEZWZhdWx0IDogZmluYWxBdHRyLmludFZhbHVlKCk7Ci0gICAgICAgIC8vIGFubm90YXRpb24/LChsaXN0fHJlc3RyaWN0aW9ufHVuaW9uKQotICAgICAgICBFbGVtZW50IGNoaWxkID0gRE9NVXRpbC5nZXRGaXJzdENoaWxkRWxlbWVudChzaW1wbGVUeXBlRGVjbCk7Ci0gICAgICAgIFhTQW5ub3RhdGlvbkltcGwgW10gYW5ub3RhdGlvbnMgPSBudWxsOwotICAgICAgICBpZiAoY2hpbGQgIT0gbnVsbCAmJiBET01VdGlsLmdldExvY2FsTmFtZShjaGlsZCkuZXF1YWxzKFNjaGVtYVN5bWJvbHMuRUxUX0FOTk9UQVRJT04pKSB7Ci0gICAgICAgICAgICBYU0Fubm90YXRpb25JbXBsIGFubm90YXRpb24gPSB0cmF2ZXJzZUFubm90YXRpb25EZWNsKGNoaWxkLCBhdHRyVmFsdWVzLCBmYWxzZSwgc2NoZW1hRG9jKTsKLSAgICAgICAgICAgIGlmIChhbm5vdGF0aW9uICE9IG51bGwpCi0gICAgICAgICAgICAgICAgYW5ub3RhdGlvbnMgPSBuZXcgWFNBbm5vdGF0aW9uSW1wbCBbXSB7YW5ub3RhdGlvbn07Ci0gICAgICAgICAgICBjaGlsZCA9IERPTVV0aWwuZ2V0TmV4dFNpYmxpbmdFbGVtZW50KGNoaWxkKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIFN0cmluZyB0ZXh0ID0gRE9NVXRpbC5nZXRTeW50aGV0aWNBbm5vdGF0aW9uKHNpbXBsZVR5cGVEZWNsKTsKLSAgICAgICAgICAgIGlmICh0ZXh0ICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBYU0Fubm90YXRpb25JbXBsIGFubm90YXRpb24gPSB0cmF2ZXJzZVN5bnRoZXRpY0Fubm90YXRpb24oc2ltcGxlVHlwZURlY2wsIHRleHQsIGF0dHJWYWx1ZXMsIGZhbHNlLCBzY2hlbWFEb2MpOwotICAgICAgICAgICAgICAgIGFubm90YXRpb25zID0gbmV3IFhTQW5ub3RhdGlvbkltcGxbXSB7YW5ub3RhdGlvbn07Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgLy8gKGxpc3R8cmVzdHJpY3Rpb258dW5pb24pCi0gICAgICAgIGlmIChjaGlsZCA9PSBudWxsKSB7Ci0gICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcigiczRzLWVsdC1tdXN0LW1hdGNoLjIiLCBuZXcgT2JqZWN0W117U2NoZW1hU3ltYm9scy5FTFRfU0lNUExFVFlQRSwgIihhbm5vdGF0aW9uPywgKHJlc3RyaWN0aW9uIHwgbGlzdCB8IHVuaW9uKSkifSwgc2ltcGxlVHlwZURlY2wpOwotICAgICAgICAgICAgcmV0dXJuIGVycm9yVHlwZShuYW1lLCBzY2hlbWFEb2MuZlRhcmdldE5hbWVzcGFjZSwgWFNDb25zdGFudHMuREVSSVZBVElPTl9SRVNUUklDVElPTik7Ci0gICAgICAgIH0KLSAgICAgICAgLy8gZGVyaXZhdGlvbiB0eXBlOiByZXN0cmljdGlvbi9saXN0L3VuaW9uCi0gICAgICAgIFN0cmluZyB2YXJpZXR5UHJvcGVydHkgPSBET01VdGlsLmdldExvY2FsTmFtZShjaGlsZCk7Ci0gICAgICAgIHNob3J0IHJlZlR5cGUgPSBYU0NvbnN0YW50cy5ERVJJVkFUSU9OX1JFU1RSSUNUSU9OOwotICAgICAgICBib29sZWFuIHJlc3RyaWN0aW9uID0gZmFsc2UsIGxpc3QgPSBmYWxzZSwgdW5pb24gPSBmYWxzZTsKLSAgICAgICAgaWYgKHZhcmlldHlQcm9wZXJ0eS5lcXVhbHMoU2NoZW1hU3ltYm9scy5FTFRfUkVTVFJJQ1RJT04pKSB7Ci0gICAgICAgICAgICByZWZUeXBlID0gWFNDb25zdGFudHMuREVSSVZBVElPTl9SRVNUUklDVElPTjsKLSAgICAgICAgICAgIHJlc3RyaWN0aW9uID0gdHJ1ZTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICh2YXJpZXR5UHJvcGVydHkuZXF1YWxzKFNjaGVtYVN5bWJvbHMuRUxUX0xJU1QpKSB7Ci0gICAgICAgICAgICByZWZUeXBlID0gWFNDb25zdGFudHMuREVSSVZBVElPTl9MSVNUOwotICAgICAgICAgICAgbGlzdCA9IHRydWU7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAodmFyaWV0eVByb3BlcnR5LmVxdWFscyhTY2hlbWFTeW1ib2xzLkVMVF9VTklPTikpIHsKLSAgICAgICAgICAgIHJlZlR5cGUgPSBYU0NvbnN0YW50cy5ERVJJVkFUSU9OX1VOSU9OOwotICAgICAgICAgICAgdW5pb24gPSB0cnVlOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoInM0cy1lbHQtbXVzdC1tYXRjaC4xIiwgbmV3IE9iamVjdFtde1NjaGVtYVN5bWJvbHMuRUxUX1NJTVBMRVRZUEUsICIoYW5ub3RhdGlvbj8sIChyZXN0cmljdGlvbiB8IGxpc3QgfCB1bmlvbikpIiwgdmFyaWV0eVByb3BlcnR5fSwgc2ltcGxlVHlwZURlY2wpOwotICAgICAgICAgICAgcmV0dXJuIGVycm9yVHlwZShuYW1lLCBzY2hlbWFEb2MuZlRhcmdldE5hbWVzcGFjZSwgWFNDb25zdGFudHMuREVSSVZBVElPTl9SRVNUUklDVElPTik7Ci0gICAgICAgIH0KLSAgICAgICAgLy8gbm90aGluZyBzaG91bGQgZm9sbG93IHRoaXMgZWxlbWVudAotICAgICAgICBFbGVtZW50IG5leHRDaGlsZCA9IERPTVV0aWwuZ2V0TmV4dFNpYmxpbmdFbGVtZW50KGNoaWxkKTsKLSAgICAgICAgaWYgKG5leHRDaGlsZCAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcigiczRzLWVsdC1tdXN0LW1hdGNoLjEiLCBuZXcgT2JqZWN0W117U2NoZW1hU3ltYm9scy5FTFRfU0lNUExFVFlQRSwgIihhbm5vdGF0aW9uPywgKHJlc3RyaWN0aW9uIHwgbGlzdCB8IHVuaW9uKSkiLCBET01VdGlsLmdldExvY2FsTmFtZShuZXh0Q2hpbGQpfSwgbmV4dENoaWxkKTsKLSAgICAgICAgfQotICAgICAgICAvLyBHZW5lcmFsIEF0dHJpYnV0ZSBDaGVja2luZzogZ2V0IGJhc2UvaXRlbS9tZW1iZXIgdHlwZXMKLSAgICAgICAgT2JqZWN0W10gY29udGVudEF0dHJzID0gZkF0dHJDaGVja2VyLmNoZWNrQXR0cmlidXRlcyhjaGlsZCwgZmFsc2UsIHNjaGVtYURvYyk7Ci0gICAgICAgIFFOYW1lIGJhc2VUeXBlTmFtZSA9IChRTmFtZSljb250ZW50QXR0cnNbcmVzdHJpY3Rpb24gPwotICAgICAgICAgICAgICAgIFhTQXR0cmlidXRlQ2hlY2tlci5BVFRJRFhfQkFTRSA6Ci0gICAgICAgICAgICAgICAgICAgIFhTQXR0cmlidXRlQ2hlY2tlci5BVFRJRFhfSVRFTVRZUEVdOwotICAgICAgICBWZWN0b3IgbWVtYmVyVHlwZXMgPSAoVmVjdG9yKWNvbnRlbnRBdHRyc1tYU0F0dHJpYnV0ZUNoZWNrZXIuQVRUSURYX01FTUJFUlRZUEVTXTsKLSAgICAgICAgLy9jb250ZW50ID0ge2Fubm90YXRpb24/LHNpbXBsZVR5cGU/Li4ufQotICAgICAgICBFbGVtZW50IGNvbnRlbnQgPSBET01VdGlsLmdldEZpcnN0Q2hpbGRFbGVtZW50KGNoaWxkKTsKLSAgICAgICAgLy9jaGVjayBjb250ZW50IChhbm5vdGF0aW9uPywgLi4uKQotICAgICAgICBpZiAoY29udGVudCAhPSBudWxsICYmIERPTVV0aWwuZ2V0TG9jYWxOYW1lKGNvbnRlbnQpLmVxdWFscyhTY2hlbWFTeW1ib2xzLkVMVF9BTk5PVEFUSU9OKSkgewotICAgICAgICAgICAgWFNBbm5vdGF0aW9uSW1wbCBhbm5vdGF0aW9uID0gdHJhdmVyc2VBbm5vdGF0aW9uRGVjbChjb250ZW50LCBjb250ZW50QXR0cnMsIGZhbHNlLCBzY2hlbWFEb2MpOwotICAgICAgICAgICAgaWYgKGFubm90YXRpb24gIT0gbnVsbCApIHsKLSAgICAgICAgICAgICAgICBpZihhbm5vdGF0aW9ucyA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGFubm90YXRpb25zID0gbmV3IFhTQW5ub3RhdGlvbkltcGwgW10ge2Fubm90YXRpb259OwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgWFNBbm5vdGF0aW9uSW1wbCBbXSB0ZW1wQXJyYXkgPSBuZXcgWFNBbm5vdGF0aW9uSW1wbFsyXTsKLSAgICAgICAgICAgICAgICAgICAgdGVtcEFycmF5WzBdID0gYW5ub3RhdGlvbnNbMF07Ci0gICAgICAgICAgICAgICAgICAgIGFubm90YXRpb25zID0gdGVtcEFycmF5OwotICAgICAgICAgICAgICAgICAgICBhbm5vdGF0aW9uc1sxXSA9IGFubm90YXRpb247Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgY29udGVudCA9IERPTVV0aWwuZ2V0TmV4dFNpYmxpbmdFbGVtZW50KGNvbnRlbnQpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgU3RyaW5nIHRleHQgPSBET01VdGlsLmdldFN5bnRoZXRpY0Fubm90YXRpb24oY2hpbGQpOwotICAgICAgICAgICAgaWYgKHRleHQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIFhTQW5ub3RhdGlvbkltcGwgYW5ub3RhdGlvbiA9IHRyYXZlcnNlU3ludGhldGljQW5ub3RhdGlvbihjaGlsZCwgdGV4dCwgY29udGVudEF0dHJzLCBmYWxzZSwgc2NoZW1hRG9jKTsKLSAgICAgICAgICAgICAgICBpZiAoYW5ub3RhdGlvbnMgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBhbm5vdGF0aW9ucyA9IG5ldyBYU0Fubm90YXRpb25JbXBsIFtdIHthbm5vdGF0aW9ufTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIFhTQW5ub3RhdGlvbkltcGwgW10gdGVtcEFycmF5ID0gbmV3IFhTQW5ub3RhdGlvbkltcGxbMl07Ci0gICAgICAgICAgICAgICAgICAgIHRlbXBBcnJheVswXSA9IGFubm90YXRpb25zWzBdOwotICAgICAgICAgICAgICAgICAgICBhbm5vdGF0aW9ucyA9IHRlbXBBcnJheTsKLSAgICAgICAgICAgICAgICAgICAgYW5ub3RhdGlvbnNbMV0gPSBhbm5vdGF0aW9uOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICAvLyBnZXQgYmFzZSB0eXBlIGZyb20gImJhc2UiIGF0dHJpYnV0ZQotICAgICAgICBYU1NpbXBsZVR5cGUgYmFzZVZhbGlkYXRvciA9IG51bGw7Ci0gICAgICAgIGlmICgocmVzdHJpY3Rpb24gfHwgbGlzdCkgJiYgYmFzZVR5cGVOYW1lICE9IG51bGwpIHsKLSAgICAgICAgICAgIGJhc2VWYWxpZGF0b3IgPSBmaW5kRFRWYWxpZGF0b3IoY2hpbGQsIG5hbWUsIGJhc2VUeXBlTmFtZSwgcmVmVHlwZSwgc2NoZW1hRG9jKTsKLSAgICAgICAgICAgIC8vIGlmIGl0cyB0aGUgYnVpbHQtaW4gdHlwZSwgcmV0dXJuIG51bGwgZnJvbSBoZXJlCi0gICAgICAgICAgICBpZiAoYmFzZVZhbGlkYXRvciA9PSBudWxsICYmIGZJc0J1aWx0SW4pIHsKLSAgICAgICAgICAgICAgICBmSXNCdWlsdEluID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgLy8gZ2V0IHR5cGVzIGZyb20gIm1lbWJlclR5cGVzIiBhdHRyaWJ1dGUKLSAgICAgICAgQXJyYXlMaXN0IGRUVmFsaWRhdG9ycyA9IG51bGw7Ci0gICAgICAgIFhTU2ltcGxlVHlwZSBkdiA9IG51bGw7Ci0gICAgICAgIFhTT2JqZWN0TGlzdCBkdnM7Ci0gICAgICAgIGlmICh1bmlvbiAmJiBtZW1iZXJUeXBlcyAhPSBudWxsICYmIG1lbWJlclR5cGVzLnNpemUoKSA+IDApIHsKLSAgICAgICAgICAgIGludCBzaXplID0gbWVtYmVyVHlwZXMuc2l6ZSgpOwotICAgICAgICAgICAgZFRWYWxpZGF0b3JzID0gbmV3IEFycmF5TGlzdChzaXplKTsKLSAgICAgICAgICAgIC8vIGZvciBlYWNoIHFuYW1lIGluIHRoZSBsaXN0Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewotICAgICAgICAgICAgICAgIC8vIGdldCB0aGUgdHlwZSBkZWNsCi0gICAgICAgICAgICAgICAgZHYgPSBmaW5kRFRWYWxpZGF0b3IoY2hpbGQsIG5hbWUsIChRTmFtZSltZW1iZXJUeXBlcy5lbGVtZW50QXQoaSksCi0gICAgICAgICAgICAgICAgICAgICAgICBYU0NvbnN0YW50cy5ERVJJVkFUSU9OX1VOSU9OLCBzY2hlbWFEb2MpOwotICAgICAgICAgICAgICAgIGlmIChkdiAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIGlmIGl0J3MgYSB1bmlvbiwgZXhwYW5kIGl0Ci0gICAgICAgICAgICAgICAgICAgIGlmIChkdi5nZXRWYXJpZXR5KCkgPT0gWFNTaW1wbGVUeXBlLlZBUklFVFlfVU5JT04pIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGR2cyA9IGR2LmdldE1lbWJlclR5cGVzKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IGR2cy5nZXRMZW5ndGgoKTsgaisrKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRUVmFsaWRhdG9ycy5hZGQoZHZzLml0ZW0oaikpOwotICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgZFRWYWxpZGF0b3JzLmFkZChkdik7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBjaGVjayBpZiB0aGVyZSBpcyBhIGNoaWxkICJzaW1wbGVUeXBlIgotICAgICAgICBpZiAoY29udGVudCAhPSBudWxsICYmIERPTVV0aWwuZ2V0TG9jYWxOYW1lKGNvbnRlbnQpLmVxdWFscyhTY2hlbWFTeW1ib2xzLkVMVF9TSU1QTEVUWVBFKSkgewotICAgICAgICAgICAgaWYgKHJlc3RyaWN0aW9uIHx8IGxpc3QpIHsKLSAgICAgICAgICAgICAgICAvLyBpdCdzIGFuIGVycm9yIGZvciBib3RoICJiYXNlIiBhbmQgInNpbXBsZVR5cGUiIHRvIGFwcGVhcgotICAgICAgICAgICAgICAgIGlmIChiYXNlVHlwZU5hbWUgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcihsaXN0ID8gInNyYy1zaW1wbGUtdHlwZS4zLmEiIDogInNyYy1zaW1wbGUtdHlwZS4yLmEiLCBudWxsLCBjb250ZW50KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaWYgKGJhc2VWYWxpZGF0b3IgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAvLyB0cmF2ZXJzZSB0aGlzIGNoaWxkIHRvIGdldCB0aGUgYmFzZSB0eXBlCi0gICAgICAgICAgICAgICAgICAgIGJhc2VWYWxpZGF0b3IgPSB0cmF2ZXJzZUxvY2FsKGNvbnRlbnQsIHNjaGVtYURvYywgZ3JhbW1hcik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIC8vIGdldCB0aGUgbmV4dCBlbGVtZW50Ci0gICAgICAgICAgICAgICAgY29udGVudCA9IERPTVV0aWwuZ2V0TmV4dFNpYmxpbmdFbGVtZW50KGNvbnRlbnQpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAodW5pb24pIHsKLSAgICAgICAgICAgICAgICBpZiAoZFRWYWxpZGF0b3JzID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgZFRWYWxpZGF0b3JzID0gbmV3IEFycmF5TGlzdCgyKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZG8gewotICAgICAgICAgICAgICAgICAgICAvLyB0cmF2ZXJzZSB0aGlzIGNoaWxkIHRvIGdldCB0aGUgbWVtYmVyIHR5cGUKLSAgICAgICAgICAgICAgICAgICAgZHYgPSB0cmF2ZXJzZUxvY2FsKGNvbnRlbnQsIHNjaGVtYURvYywgZ3JhbW1hcik7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChkdiAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBpZiBpdCdzIGEgdW5pb24sIGV4cGFuZCBpdAotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGR2LmdldFZhcmlldHkoKSA9PSBYU1NpbXBsZVR5cGUuVkFSSUVUWV9VTklPTikgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR2cyA9IGR2LmdldE1lbWJlclR5cGVzKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBkdnMuZ2V0TGVuZ3RoKCk7IGorKykgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkVFZhbGlkYXRvcnMuYWRkKGR2cy5pdGVtKGopKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBkVFZhbGlkYXRvcnMuYWRkKGR2KTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAvLyBnZXQgdGhlIG5leHQgZWxlbWVudAotICAgICAgICAgICAgICAgICAgICBjb250ZW50ID0gRE9NVXRpbC5nZXROZXh0U2libGluZ0VsZW1lbnQoY29udGVudCk7Ci0gICAgICAgICAgICAgICAgfSB3aGlsZSAoY29udGVudCAhPSBudWxsICYmIERPTVV0aWwuZ2V0TG9jYWxOYW1lKGNvbnRlbnQpLmVxdWFscyhTY2hlbWFTeW1ib2xzLkVMVF9TSU1QTEVUWVBFKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoKHJlc3RyaWN0aW9uIHx8IGxpc3QpICYmIGJhc2VUeXBlTmFtZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAvLyBpdCdzIGFuIGVycm9yIGlmIG5laXRoZXIgImJhc2UvaXRlbVR5cGUiIG5vciAic2ltcGxlVHlwZSIgYXBwZWFycwotICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IobGlzdCA/ICJzcmMtc2ltcGxlLXR5cGUuMy5iIiA6ICJzcmMtc2ltcGxlLXR5cGUuMi5iIiwgbnVsbCwgY2hpbGQpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKHVuaW9uICYmIChtZW1iZXJUeXBlcyA9PSBudWxsIHx8IG1lbWJlclR5cGVzLnNpemUoKSA9PSAwKSkgewotICAgICAgICAgICAgLy8gaXQncyBhbiBlcnJvciBpZiAibWVtYmVyVHlwZXMiIGlzIGVtcHR5IGFuZCBubyAic2ltcGxlVHlwZSIgYXBwZWFycwotICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoInNyYy11bmlvbi1tZW1iZXJUeXBlcy1vci1zaW1wbGVUeXBlcyIsIG51bGwsIGNoaWxkKTsKLSAgICAgICAgfQotICAgICAgICAvLyBlcnJvciBmaW5kaW5nICJiYXNlIiBvciBlcnJvciB0cmF2ZXJzaW5nICJzaW1wbGVUeXBlIi4KLSAgICAgICAgLy8gZG9uJ3QgbmVlZCB0byByZXBvcnQgYW4gZXJyb3IsIHNpbmNlIHNvbWUgZXJyb3IgaGFzIGJlZW4gcmVwb3J0ZWQuCi0gICAgICAgIGlmICgocmVzdHJpY3Rpb24gfHwgbGlzdCkgJiYgYmFzZVZhbGlkYXRvciA9PSBudWxsKSB7Ci0gICAgICAgICAgICBmQXR0ckNoZWNrZXIucmV0dXJuQXR0ckFycmF5KGNvbnRlbnRBdHRycywgc2NoZW1hRG9jKTsKLSAgICAgICAgICAgIHJldHVybiBlcnJvclR5cGUobmFtZSwgc2NoZW1hRG9jLmZUYXJnZXROYW1lc3BhY2UsCi0gICAgICAgICAgICAgICAgICAgIHJlc3RyaWN0aW9uID8gWFNDb25zdGFudHMuREVSSVZBVElPTl9SRVNUUklDVElPTiA6IFhTQ29uc3RhbnRzLkRFUklWQVRJT05fTElTVCk7Ci0gICAgICAgIH0KLSAgICAgICAgLy8gZXJyb3IgZmluZGluZyAibWVtYmVyVHlwZXMiIG9yIGVycm9yIHRyYXZlcnNpbmcgInNpbXBsZVR5cGUiLgotICAgICAgICAvLyBkb24ndCBuZWVkIHRvIHJlcG9ydCBhbiBlcnJvciwgc2luY2Ugc29tZSBlcnJvciBoYXMgYmVlbiByZXBvcnRlZC4KLSAgICAgICAgaWYgKHVuaW9uICYmIChkVFZhbGlkYXRvcnMgPT0gbnVsbCB8fCBkVFZhbGlkYXRvcnMuc2l6ZSgpID09IDApKSB7Ci0gICAgICAgICAgICBmQXR0ckNoZWNrZXIucmV0dXJuQXR0ckFycmF5KGNvbnRlbnRBdHRycywgc2NoZW1hRG9jKTsKLSAgICAgICAgICAgIHJldHVybiBlcnJvclR5cGUobmFtZSwgc2NoZW1hRG9jLmZUYXJnZXROYW1lc3BhY2UsCi0gICAgICAgICAgICAgICAgICAgIFhTQ29uc3RhbnRzLkRFUklWQVRJT05fVU5JT04pOwotICAgICAgICB9Ci0gICAgICAgIC8vIGl0ZW0gdHlwZSBvZiBsaXN0IHR5cGVzIGNhbid0IGhhdmUgbGlzdCBjb250ZW50Ci0gICAgICAgIGlmIChsaXN0ICYmIGlzTGlzdERhdGF0eXBlKGJhc2VWYWxpZGF0b3IpKSB7Ci0gICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcigiY29zLXN0LXJlc3RyaWN0cy4yLjEiLCBuZXcgT2JqZWN0W117bmFtZSwgYmFzZVZhbGlkYXRvci5nZXROYW1lKCl9LCBjaGlsZCk7Ci0gICAgICAgICAgICBmQXR0ckNoZWNrZXIucmV0dXJuQXR0ckFycmF5KGNvbnRlbnRBdHRycywgc2NoZW1hRG9jKTsKLSAgICAgICAgICAgIHJldHVybiBlcnJvclR5cGUobmFtZSwgc2NoZW1hRG9jLmZUYXJnZXROYW1lc3BhY2UsCi0gICAgICAgICAgICAgICAgICAgIFhTQ29uc3RhbnRzLkRFUklWQVRJT05fTElTVCk7Ci0gICAgICAgIH0KLSAgICAgICAgLy8gY3JlYXRlIHRoZSBzaW1wbGUgdHlwZSBiYXNlZCBvbiB0aGUgImJhc2UiIHR5cGUKLSAgICAgICAgWFNTaW1wbGVUeXBlIG5ld0RlY2wgPSBudWxsOwotICAgICAgICBpZiAocmVzdHJpY3Rpb24pIHsKLSAgICAgICAgICAgIG5ld0RlY2wgPSBmU2NoZW1hSGFuZGxlci5mRFZGYWN0b3J5LmNyZWF0ZVR5cGVSZXN0cmljdGlvbihuYW1lLCBzY2hlbWFEb2MuZlRhcmdldE5hbWVzcGFjZSwgKHNob3J0KWZpbmFsUHJvcGVydHksIGJhc2VWYWxpZGF0b3IsCi0gICAgICAgICAgICAgICAgICAgIGFubm90YXRpb25zID09IG51bGw/IG51bGwgOiBuZXcgWFNPYmplY3RMaXN0SW1wbChhbm5vdGF0aW9ucywgYW5ub3RhdGlvbnMubGVuZ3RoKSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAobGlzdCkgewotICAgICAgICAgICAgbmV3RGVjbCA9IGZTY2hlbWFIYW5kbGVyLmZEVkZhY3RvcnkuY3JlYXRlVHlwZUxpc3QobmFtZSwgc2NoZW1hRG9jLmZUYXJnZXROYW1lc3BhY2UsIChzaG9ydClmaW5hbFByb3BlcnR5LCBiYXNlVmFsaWRhdG9yLAotICAgICAgICAgICAgICAgICAgICBhbm5vdGF0aW9ucyA9PSBudWxsPyBudWxsIDogbmV3IFhTT2JqZWN0TGlzdEltcGwoYW5ub3RhdGlvbnMsIGFubm90YXRpb25zLmxlbmd0aCkpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKHVuaW9uKSB7Ci0gICAgICAgICAgICBYU1NpbXBsZVR5cGVbXSBtZW1iZXJEZWNscyA9IChYU1NpbXBsZVR5cGVbXSkgZFRWYWxpZGF0b3JzLnRvQXJyYXkobmV3IFhTU2ltcGxlVHlwZVtkVFZhbGlkYXRvcnMuc2l6ZSgpXSk7Ci0gICAgICAgICAgICBuZXdEZWNsID0gZlNjaGVtYUhhbmRsZXIuZkRWRmFjdG9yeS5jcmVhdGVUeXBlVW5pb24obmFtZSwgc2NoZW1hRG9jLmZUYXJnZXROYW1lc3BhY2UsIChzaG9ydClmaW5hbFByb3BlcnR5LCBtZW1iZXJEZWNscywKLSAgICAgICAgICAgICAgICAgICAgYW5ub3RhdGlvbnMgPT0gbnVsbD8gbnVsbCA6IG5ldyBYU09iamVjdExpc3RJbXBsKGFubm90YXRpb25zLCBhbm5vdGF0aW9ucy5sZW5ndGgpKTsKLSAgICAgICAgfQotICAgICAgICAvLyBub3cgdHJhdmVyc2UgZmFjZXRzLCBpZiBpdCdzIGRlcml2ZWQgYnkgcmVzdHJpY3Rpb24KLSAgICAgICAgaWYgKHJlc3RyaWN0aW9uICYmIGNvbnRlbnQgIT0gbnVsbCkgewotICAgICAgICAgICAgRmFjZXRJbmZvIGZpID0gdHJhdmVyc2VGYWNldHMoY29udGVudCwgYmFzZVZhbGlkYXRvciwgc2NoZW1hRG9jKTsKLSAgICAgICAgICAgIGNvbnRlbnQgPSBmaS5ub2RlQWZ0ZXJGYWNldHM7Ci0KLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgZlZhbGlkYXRpb25TdGF0ZS5zZXROYW1lc3BhY2VTdXBwb3J0KHNjaGVtYURvYy5mTmFtZXNwYWNlU3VwcG9ydCk7Ci0gICAgICAgICAgICAgICAgbmV3RGVjbC5hcHBseUZhY2V0cyhmaS5mYWNldGRhdGEsIGZpLmZQcmVzZW50RmFjZXRzLCBmaS5mRml4ZWRGYWNldHMsIGZWYWxpZGF0aW9uU3RhdGUpOwotICAgICAgICAgICAgfSBjYXRjaCAoSW52YWxpZERhdGF0eXBlRmFjZXRFeGNlcHRpb24gZXgpIHsKLSAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcihleC5nZXRLZXkoKSwgZXguZ2V0QXJncygpLCBjaGlsZCk7Ci0gICAgICAgICAgICAgICAgLy8gUmVjcmVhdGUgdGhlIHR5cGUsIGlnbm9yaW5nIHRoZSBmYWNldHMKLSAgICAgICAgICAgICAgICBuZXdEZWNsID0gZlNjaGVtYUhhbmRsZXIuZkRWRmFjdG9yeS5jcmVhdGVUeXBlUmVzdHJpY3Rpb24obmFtZSwgc2NoZW1hRG9jLmZUYXJnZXROYW1lc3BhY2UsIChzaG9ydClmaW5hbFByb3BlcnR5LCBiYXNlVmFsaWRhdG9yLAotICAgICAgICAgICAgICAgICAgICAgICAgYW5ub3RhdGlvbnMgPT0gbnVsbD8gbnVsbCA6IG5ldyBYU09iamVjdExpc3RJbXBsKGFubm90YXRpb25zLCBhbm5vdGF0aW9ucy5sZW5ndGgpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICAvLyBubyBlbGVtZW50IHNob3VsZCBhcHBlYXIgYWZ0ZXIgdGhpcyBwb2ludAotICAgICAgICBpZiAoY29udGVudCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAocmVzdHJpY3Rpb24pIHsKLSAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcigiczRzLWVsdC1tdXN0LW1hdGNoLjEiLCBuZXcgT2JqZWN0W117U2NoZW1hU3ltYm9scy5FTFRfUkVTVFJJQ1RJT04sICIoYW5ub3RhdGlvbj8sIChzaW1wbGVUeXBlPywgKG1pbkV4Y2x1c2l2ZSB8IG1pbkluY2x1c2l2ZSB8IG1heEV4Y2x1c2l2ZSB8IG1heEluY2x1c2l2ZSB8IHRvdGFsRGlnaXRzIHwgZnJhY3Rpb25EaWdpdHMgfCBsZW5ndGggfCBtaW5MZW5ndGggfCBtYXhMZW5ndGggfCBlbnVtZXJhdGlvbiB8IHdoaXRlU3BhY2UgfCBwYXR0ZXJuKSopKSIsIERPTVV0aWwuZ2V0TG9jYWxOYW1lKGNvbnRlbnQpfSwgY29udGVudCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChsaXN0KSB7Ci0gICAgICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoInM0cy1lbHQtbXVzdC1tYXRjaC4xIiwgbmV3IE9iamVjdFtde1NjaGVtYVN5bWJvbHMuRUxUX0xJU1QsICIoYW5ub3RhdGlvbj8sIChzaW1wbGVUeXBlPykpIiwgRE9NVXRpbC5nZXRMb2NhbE5hbWUoY29udGVudCl9LCBjb250ZW50KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKHVuaW9uKSB7Ci0gICAgICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoInM0cy1lbHQtbXVzdC1tYXRjaC4xIiwgbmV3IE9iamVjdFtde1NjaGVtYVN5bWJvbHMuRUxUX1VOSU9OLCAiKGFubm90YXRpb24/LCAoc2ltcGxlVHlwZSopKSIsIERPTVV0aWwuZ2V0TG9jYWxOYW1lKGNvbnRlbnQpfSwgY29udGVudCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZkF0dHJDaGVja2VyLnJldHVybkF0dHJBcnJheShjb250ZW50QXR0cnMsIHNjaGVtYURvYyk7Ci0gICAgICAgIC8vIHJldHVybiB0aGUgbmV3IHR5cGUKLSAgICAgICAgcmV0dXJuIG5ld0RlY2w7Ci0gICAgfQotCi0gICAgLy9AcGFyYW06IGVsbSAtIHRvcCBlbGVtZW50Ci0gICAgLy9AcGFyYW06IGJhc2VUeXBlU3RyIC0gdHlwZSAoYmFzZS9pdGVtVHlwZS9tZW1iZXJUeXBlcykKLSAgICAvL0BwYXJhbTogYmFzZVJlZkNvbnRleHQ6ICB3aGV0aGVyIHRoZSBjYWxsZXIgaXMgdXNpbmcgdGhpcyB0eXBlIGFzIGEgYmFzZSBmb3IgcmVzdHJpY3Rpb24sIHVuaW9uIG9yIGxpc3QKLSAgICAvL3JldHVybiBYU1NpbXBsZVR5cGUgYXZhaWxhYmxlIGZvciB0aGUgYmFzZVR5cGVTdHIsIG51bGwgaWYgbm90IGZvdW5kIG9yIGRpc2FsbG93ZWQuCi0gICAgLy8gYWxzbyB0aHJvd3MgYW4gZXJyb3IgaWYgdGhlIGJhc2UgdHlwZSB3b24ndCBhbGxvdyBpdHNlbGYgdG8gYmUgdXNlZCBpbiB0aGlzIGNvbnRleHQuCi0gICAgLy8gUkVWSVNJVDogY2FuIHRoaXMgY29kZSBiZSByZS11c2VkPwotICAgIHByaXZhdGUgWFNTaW1wbGVUeXBlIGZpbmREVFZhbGlkYXRvcihFbGVtZW50IGVsbSwgU3RyaW5nIHJlZk5hbWUsCi0gICAgICAgICAgICBRTmFtZSBiYXNlVHlwZVN0ciwgc2hvcnQgYmFzZVJlZkNvbnRleHQsCi0gICAgICAgICAgICBYU0RvY3VtZW50SW5mbyBzY2hlbWFEb2MpIHsKLSAgICAgICAgaWYgKGJhc2VUeXBlU3RyID09IG51bGwpCi0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLQotICAgICAgICBYU1R5cGVEZWZpbml0aW9uIGJhc2VUeXBlID0gKFhTVHlwZURlZmluaXRpb24pZlNjaGVtYUhhbmRsZXIuZ2V0R2xvYmFsRGVjbChzY2hlbWFEb2MsIFhTREhhbmRsZXIuVFlQRURFQ0xfVFlQRSwgYmFzZVR5cGVTdHIsIGVsbSk7Ci0gICAgICAgIGlmIChiYXNlVHlwZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotICAgICAgICBpZiAoYmFzZVR5cGUuZ2V0VHlwZUNhdGVnb3J5KCkgIT0gWFNUeXBlRGVmaW5pdGlvbi5TSU1QTEVfVFlQRSkgewotICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoImNvcy1zdC1yZXN0cmljdHMuMS4xIiwgbmV3IE9iamVjdFtde2Jhc2VUeXBlU3RyLnJhd25hbWUsIHJlZk5hbWV9LCBlbG0pOwotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBpZiBpdCdzIGEgY29tcGxleCB0eXBlLCBvciBpZiBpdHMgcmVzdHJpY3Rpb24gb2YgYW55U2ltcGxlVHlwZQotICAgICAgICBpZiAoYmFzZVR5cGUgPT0gU2NoZW1hR3JhbW1hci5mQW55U2ltcGxlVHlwZSAmJgotICAgICAgICAgICAgYmFzZVJlZkNvbnRleHQgPT0gWFNDb25zdGFudHMuREVSSVZBVElPTl9SRVNUUklDVElPTikgewotICAgICAgICAgICAgLy8gaWYgdGhlIGJhc2UgdHlwZSBpcyBhbnlTaW1wbGVUeXBlIGFuZCB0aGUgY3VycmVudCB0eXBlIGlzCi0gICAgICAgICAgICAvLyBhIFM0UyBidWlsdC1pbiB0eXBlLCByZXR1cm4gbnVsbC4gKG5vdCBhbiBlcnJvcikuCi0gICAgICAgICAgICBpZiAoY2hlY2tCdWlsdEluKHJlZk5hbWUsIHNjaGVtYURvYy5mVGFyZ2V0TmFtZXNwYWNlKSkgewotICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoImNvcy1zdC1yZXN0cmljdHMuMS4xIiwgbmV3IE9iamVjdFtde2Jhc2VUeXBlU3RyLnJhd25hbWUsIHJlZk5hbWV9LCBlbG0pOwotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoKGJhc2VUeXBlLmdldEZpbmFsKCkgJiBiYXNlUmVmQ29udGV4dCkgIT0gMCkgewotICAgICAgICAgICAgaWYgKGJhc2VSZWZDb250ZXh0ID09IFhTQ29uc3RhbnRzLkRFUklWQVRJT05fUkVTVFJJQ1RJT04pIHsKLSAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcigic3QtcHJvcHMtY29ycmVjdC4zIiwgbmV3IE9iamVjdFtde3JlZk5hbWUsIGJhc2VUeXBlU3RyLnJhd25hbWV9LCBlbG0pOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoYmFzZVJlZkNvbnRleHQgPT0gWFNDb25zdGFudHMuREVSSVZBVElPTl9MSVNUKSB7Ci0gICAgICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoImNvcy1zdC1yZXN0cmljdHMuMi4zLjEuMSIsIG5ldyBPYmplY3RbXXtiYXNlVHlwZVN0ci5yYXduYW1lLCByZWZOYW1lfSwgZWxtKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKGJhc2VSZWZDb250ZXh0ID09IFhTQ29uc3RhbnRzLkRFUklWQVRJT05fVU5JT04pIHsKLSAgICAgICAgICAgICAgICByZXBvcnRTY2hlbWFFcnJvcigiY29zLXN0LXJlc3RyaWN0cy4zLjMuMS4xIiwgbmV3IE9iamVjdFtde2Jhc2VUeXBlU3RyLnJhd25hbWUsIHJlZk5hbWV9LCBlbG0pOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gKFhTU2ltcGxlVHlwZSliYXNlVHlwZTsKLSAgICB9Ci0KLSAgICAvLyBjaGVjayB3aGV0aGUgdGhlIHR5cGUgZGVub3RlZCBieSB0aGUgbmFtZSBhbmQgbmFtZXNwYWNlIGlzIGEgUzRTCi0gICAgLy8gYnVpbHQtaW4gdHlwZS4gdXBkYXRlIGZJc0J1aWx0SW4gYXQgdGhlIHNhbWUgdGltZS4KLSAgICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gY2hlY2tCdWlsdEluKFN0cmluZyBuYW1lLCBTdHJpbmcgbmFtZXNwYWNlKSB7Ci0gICAgICAgIGlmIChuYW1lc3BhY2UgIT0gU2NoZW1hU3ltYm9scy5VUklfU0NIRU1BRk9SU0NIRU1BKQotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICBpZiAoU2NoZW1hR3JhbW1hci5TR19TY2hlbWFOUy5nZXRHbG9iYWxUeXBlRGVjbChuYW1lKSAhPSBudWxsKQotICAgICAgICAgICAgZklzQnVpbHRJbiA9IHRydWU7Ci0gICAgICAgIHJldHVybiBmSXNCdWlsdEluOwotICAgIH0KLQotICAgIC8vIGZpbmQgaWYgYSBkYXRhdHlwZSB2YWxpZGF0b3IgaXMgYSBsaXN0IG9yIGhhcyBsaXN0IGRhdGF0eXBlIG1lbWJlci4KLSAgICBwcml2YXRlIGJvb2xlYW4gaXNMaXN0RGF0YXR5cGUoWFNTaW1wbGVUeXBlIHZhbGlkYXRvcikgewotICAgICAgICBpZiAodmFsaWRhdG9yLmdldFZhcmlldHkoKSA9PSBYU1NpbXBsZVR5cGUuVkFSSUVUWV9MSVNUKQotICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0KLSAgICAgICAgaWYgKHZhbGlkYXRvci5nZXRWYXJpZXR5KCkgPT0gWFNTaW1wbGVUeXBlLlZBUklFVFlfVU5JT04pIHsKLSAgICAgICAgICAgIFhTT2JqZWN0TGlzdCB0ZW1wID0gdmFsaWRhdG9yLmdldE1lbWJlclR5cGVzKCk7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHRlbXAuZ2V0TGVuZ3RoKCk7IGkrKykgewotICAgICAgICAgICAgICAgIGlmICgoKFhTU2ltcGxlVHlwZSl0ZW1wLml0ZW0oaSkpLmdldFZhcmlldHkoKSA9PSBYU1NpbXBsZVR5cGUuVkFSSUVUWV9MSVNUKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ly9pc0xpc3REYXRhdHlwZShYU1NpbXBsZVR5cGVEZWNsKTpib29sZWFuCi0KLSAgICBwcml2YXRlIFhTU2ltcGxlVHlwZSBlcnJvclR5cGUoU3RyaW5nIG5hbWUsIFN0cmluZyBuYW1lc3BhY2UsIHNob3J0IHJlZlR5cGUpIHsKLSAgICAgICAgWFNTaW1wbGVUeXBlIHN0cmluZ1R5cGUgPSAoWFNTaW1wbGVUeXBlKVNjaGVtYUdyYW1tYXIuU0dfU2NoZW1hTlMuZ2V0VHlwZURlZmluaXRpb24oInN0cmluZyIpOwotICAgICAgICBzd2l0Y2ggKHJlZlR5cGUpIHsKLSAgICAgICAgY2FzZSBYU0NvbnN0YW50cy5ERVJJVkFUSU9OX1JFU1RSSUNUSU9OOgotICAgICAgICAgICAgcmV0dXJuIGZTY2hlbWFIYW5kbGVyLmZEVkZhY3RvcnkuY3JlYXRlVHlwZVJlc3RyaWN0aW9uKG5hbWUsIG5hbWVzcGFjZSwgKHNob3J0KTAsCi0gICAgICAgICAgICAgICAgICAgIHN0cmluZ1R5cGUsIG51bGwpOwotICAgICAgICBjYXNlIFhTQ29uc3RhbnRzLkRFUklWQVRJT05fTElTVDoKLSAgICAgICAgICAgIHJldHVybiBmU2NoZW1hSGFuZGxlci5mRFZGYWN0b3J5LmNyZWF0ZVR5cGVMaXN0KG5hbWUsIG5hbWVzcGFjZSwgKHNob3J0KTAsCi0gICAgICAgICAgICAgICAgICAgIHN0cmluZ1R5cGUsIG51bGwpOwotICAgICAgICBjYXNlIFhTQ29uc3RhbnRzLkRFUklWQVRJT05fVU5JT046Ci0gICAgICAgICAgICByZXR1cm4gZlNjaGVtYUhhbmRsZXIuZkRWRmFjdG9yeS5jcmVhdGVUeXBlVW5pb24obmFtZSwgbmFtZXNwYWNlLCAoc2hvcnQpMCwKLSAgICAgICAgICAgICAgICAgICAgbmV3IFhTU2ltcGxlVHlwZVtde3N0cmluZ1R5cGV9LCBudWxsKTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotfS8vY2xhc3MgWFNEU2ltcGxlVHlwZVRyYXZlcnNlcgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy90cmF2ZXJzZXJzL1hTRFVuaXF1ZU9yS2V5VHJhdmVyc2VyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL3RyYXZlcnNlcnMvWFNEVW5pcXVlT3JLZXlUcmF2ZXJzZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDU0ZGQ5ZC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL3RyYXZlcnNlcnMvWFNEVW5pcXVlT3JLZXlUcmF2ZXJzZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEwMiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLCAyMDAyLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy50cmF2ZXJzZXJzOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlNjaGVtYUdyYW1tYXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlNjaGVtYVN5bWJvbHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlhTRWxlbWVudERlY2w7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLmlkZW50aXR5LklkZW50aXR5Q29uc3RyYWludDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMuaWRlbnRpdHkuVW5pcXVlT3JLZXk7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLkRPTVV0aWw7Ci1pbXBvcnQgb3JnLnczYy5kb20uRWxlbWVudDsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGNvbnRhaW5zIGNvZGUgdGhhdCBpcyB1c2VkIHRvIHRyYXZlcnNlIGJvdGggPGtleT5zIGFuZAotICogPHVuaXF1ZT5zLgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIE5laWwgR3JhaGFtLCBJQk0KLSAqIEB2ZXJzaW9uICRJZDogWFNEVW5pcXVlT3JLZXlUcmF2ZXJzZXIuamF2YSx2IDEuNyAyMDEwLTExLTAxIDA0OjQwOjAyIGpvZWh3IEV4cCAkCi0gKi8KLWNsYXNzIFhTRFVuaXF1ZU9yS2V5VHJhdmVyc2VyIGV4dGVuZHMgWFNEQWJzdHJhY3RJRENvbnN0cmFpbnRUcmF2ZXJzZXIgewotCi0gICAgcHVibGljIFhTRFVuaXF1ZU9yS2V5VHJhdmVyc2VyIChYU0RIYW5kbGVyIGhhbmRsZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWFNBdHRyaWJ1dGVDaGVja2VyIGdBdHRyQ2hlY2spIHsKLSAgICAgICAgc3VwZXIoaGFuZGxlciwgZ0F0dHJDaGVjayk7Ci0gICAgfQotCi0KLSAgICB2b2lkIHRyYXZlcnNlKEVsZW1lbnQgdUVsZW0sIFhTRWxlbWVudERlY2wgZWxlbWVudCwKLSAgICAgICAgICAgIFhTRG9jdW1lbnRJbmZvIHNjaGVtYURvYywgU2NoZW1hR3JhbW1hciBncmFtbWFyKSB7Ci0KLSAgICAgICAgLy8gR2VuZXJhbCBBdHRyaWJ1dGUgQ2hlY2tpbmcKLSAgICAgICAgT2JqZWN0W10gYXR0clZhbHVlcyA9IGZBdHRyQ2hlY2tlci5jaGVja0F0dHJpYnV0ZXModUVsZW0sIGZhbHNlLCBzY2hlbWFEb2MpOwotCi0gICAgICAgIC8vIGNyZWF0ZSBpZGVudGl0eSBjb25zdHJhaW50Ci0gICAgICAgIFN0cmluZyB1TmFtZSA9IChTdHJpbmcpYXR0clZhbHVlc1tYU0F0dHJpYnV0ZUNoZWNrZXIuQVRUSURYX05BTUVdOwotCi0gICAgICAgIGlmKHVOYW1lID09IG51bGwpewotICAgICAgICAgICAgcmVwb3J0U2NoZW1hRXJyb3IoInM0cy1hdHQtbXVzdC1hcHBlYXIiLCBuZXcgT2JqZWN0IFtdIHtET01VdGlsLmdldExvY2FsTmFtZSh1RWxlbSkgLCBTY2hlbWFTeW1ib2xzLkFUVF9OQU1FIH0sIHVFbGVtKTsKLSAgICAgICAgICAgIC8vcmV0dXJuIHRoaXMgYXJyYXkgYmFjayB0byBwb29sCi0gICAgICAgICAgICBmQXR0ckNoZWNrZXIucmV0dXJuQXR0ckFycmF5KGF0dHJWYWx1ZXMsIHNjaGVtYURvYyk7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLQotICAgICAgICBVbmlxdWVPcktleSB1bmlxdWVPcktleSA9IG51bGw7Ci0gICAgICAgIGlmKERPTVV0aWwuZ2V0TG9jYWxOYW1lKHVFbGVtKS5lcXVhbHMoU2NoZW1hU3ltYm9scy5FTFRfVU5JUVVFKSkgewotICAgICAgICAgICAgdW5pcXVlT3JLZXkgPSBuZXcgVW5pcXVlT3JLZXkoc2NoZW1hRG9jLmZUYXJnZXROYW1lc3BhY2UsIHVOYW1lLCBlbGVtZW50LmZOYW1lLCBJZGVudGl0eUNvbnN0cmFpbnQuSUNfVU5JUVVFKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIHVuaXF1ZU9yS2V5ID0gbmV3IFVuaXF1ZU9yS2V5KHNjaGVtYURvYy5mVGFyZ2V0TmFtZXNwYWNlLCB1TmFtZSwgZWxlbWVudC5mTmFtZSwgSWRlbnRpdHlDb25zdHJhaW50LklDX0tFWSk7Ci0gICAgICAgIH0KLSAgICAgICAgLy8gaXQncyBYU0RFbGVtZW50VHJhdmVyc2VyJ3Mgam9iIHRvIGVuc3VyZSB0aGF0IHRoZXJlJ3Mgbm8KLSAgICAgICAgLy8gZHVwbGljYXRpb24gKG9yIGlmIHRoZXJlIGlzIHRoYXQgcmVzdHJpY3Rpb24gaXMgaW52b2x2ZWQKLSAgICAgICAgLy8gYW5kIHRoZXJlJ3MgaWRlbnRpdHkpLgotCi0gICAgICAgIC8vIElmIGVycm9ycyBvY2N1cnJlZCBpbiB0cmF2ZXJzaW5nIHRoZSBpZGVudGl0eSBjb25zdHJhaW50LCB0aGVuIGRvbid0Ci0gICAgICAgIC8vIGFkZCBpdCB0byB0aGUgc2NoZW1hLCB0byBhdm9pZCBlcnJvcnMgd2hlbiBwcm9jZXNzaW5nIHRoZSBpbnN0YW5jZS4KLSAgICAgICAgaWYgKHRyYXZlcnNlSWRlbnRpdHlDb25zdHJhaW50KHVuaXF1ZU9yS2V5LCB1RWxlbSwgc2NoZW1hRG9jLCBhdHRyVmFsdWVzKSkgewotICAgICAgICAgICAgLy8gYW5kIHN0dWZmIHRoaXMgaW4gdGhlIGdyYW1tYXIKLSAgICAgICAgICAgIGlmIChncmFtbWFyLmdldElEQ29uc3RyYWludERlY2wodW5pcXVlT3JLZXkuZ2V0SWRlbnRpdHlDb25zdHJhaW50TmFtZSgpKSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZ3JhbW1hci5hZGRJRENvbnN0cmFpbnREZWNsKGVsZW1lbnQsIHVuaXF1ZU9yS2V5KTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgZmluYWwgU3RyaW5nIGxvYyA9IGZTY2hlbWFIYW5kbGVyLnNjaGVtYURvY3VtZW50MlN5c3RlbUlkKHNjaGVtYURvYyk7Ci0gICAgICAgICAgICBmaW5hbCBJZGVudGl0eUNvbnN0cmFpbnQgaWRjID0gZ3JhbW1hci5nZXRJRENvbnN0cmFpbnREZWNsKHVuaXF1ZU9yS2V5LmdldElkZW50aXR5Q29uc3RyYWludE5hbWUoKSwgbG9jKTsKLSAgICAgICAgICAgIGlmIChpZGMgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGdyYW1tYXIuYWRkSURDb25zdHJhaW50RGVjbChlbGVtZW50LCB1bmlxdWVPcktleSwgbG9jKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gaGFuZGxlIGR1cGxpY2F0ZXMKLSAgICAgICAgICAgIGlmIChmU2NoZW1hSGFuZGxlci5mVG9sZXJhdGVEdXBsaWNhdGVzKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGlkYyAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChpZGMgaW5zdGFuY2VvZiBVbmlxdWVPcktleSkgewotICAgICAgICAgICAgICAgICAgICAgICAgdW5pcXVlT3JLZXkgPSAoVW5pcXVlT3JLZXkpIHVuaXF1ZU9yS2V5OwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGZTY2hlbWFIYW5kbGVyLmFkZElEQ29uc3RyYWludERlY2wodW5pcXVlT3JLZXkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gYW5kIGZpeCB1cCBhdHRyaWJ1dGVDaGVja2VyCi0gICAgICAgIGZBdHRyQ2hlY2tlci5yZXR1cm5BdHRyQXJyYXkoYXR0clZhbHVlcywgc2NoZW1hRG9jKTsKLSAgICB9IC8vIHRyYXZlcnNlKEVsZW1lbnQsWFNERWxlbWVudERlY2wsWFNEb2N1bWVudEluZm8sIFNjaGVtYUdyYW1tYXIpCi19IC8vIFhTRFVuaXF1ZU9yS2V5VHJhdmVyc2VyCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL3RyYXZlcnNlcnMvWFNEV2lsZGNhcmRUcmF2ZXJzZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvdHJhdmVyc2Vycy9YU0RXaWxkY2FyZFRyYXZlcnNlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2MGJmYjU0Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvdHJhdmVyc2Vycy9YU0RXaWxkY2FyZFRyYXZlcnNlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjAyICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLnRyYXZlcnNlcnM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMuU2NoZW1hR3JhbW1hcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMuU2NoZW1hU3ltYm9sczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMuWFNBbm5vdGF0aW9uSW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMuWFNQYXJ0aWNsZURlY2w7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlhTV2lsZGNhcmREZWNsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy51dGlsLlhJbnQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLnV0aWwuWFNPYmplY3RMaXN0SW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuRE9NVXRpbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTT2JqZWN0TGlzdDsKLWltcG9ydCBvcmcudzNjLmRvbS5FbGVtZW50OwotCi0vKioKLSAqIFRoZSB3aWxkY2FyZCBzY2hlbWEgY29tcG9uZW50IHRyYXZlcnNlci4KLSAqCi0gKiAmbHQ7YW55Ci0gKiAgIGlkID0gSUQKLSAqICAgbWF4T2NjdXJzID0gKG5vbk5lZ2F0aXZlSW50ZWdlciB8IHVuYm91bmRlZCkgIDogMQotICogICBtaW5PY2N1cnMgPSBub25OZWdhdGl2ZUludGVnZXIgOiAxCi0gKiAgIG5hbWVzcGFjZSA9ICgoIyNhbnkgfCAjI290aGVyKSB8IExpc3Qgb2YgKGFueVVSSSB8ICgjI3RhcmdldE5hbWVzcGFjZSB8ICMjbG9jYWwpKSApICA6ICMjYW55Ci0gKiAgIHByb2Nlc3NDb250ZW50cyA9IChsYXggfCBza2lwIHwgc3RyaWN0KSA6IHN0cmljdAotICogICB7YW55IGF0dHJpYnV0ZXMgd2l0aCBub24tc2NoZW1hIG5hbWVzcGFjZSAuIC4gLn0mZ3Q7Ci0gKiAgIENvbnRlbnQ6IChhbm5vdGF0aW9uPykKLSAqICZsdDsvYW55Jmd0OwotICoKLSAqICZsdDthbnlBdHRyaWJ1dGUKLSAqICAgaWQgPSBJRAotICogICBuYW1lc3BhY2UgPSAoKCMjYW55IHwgIyNvdGhlcikgfCBMaXN0IG9mIChhbnlVUkkgfCAoIyN0YXJnZXROYW1lc3BhY2UgfCAjI2xvY2FsKSkgKSAgOiAjI2FueQotICogICBwcm9jZXNzQ29udGVudHMgPSAobGF4IHwgc2tpcCB8IHN0cmljdCkgOiBzdHJpY3QKLSAqICAge2FueSBhdHRyaWJ1dGVzIHdpdGggbm9uLXNjaGVtYSBuYW1lc3BhY2UgLiAuIC59Jmd0OwotICogICBDb250ZW50OiAoYW5ub3RhdGlvbj8pCi0gKiAmbHQ7L2FueUF0dHJpYnV0ZSZndDsKLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBSYWh1bCBTcml2YXN0YXZhLCBTdW4gTWljcm9zeXN0ZW1zIEluYy4KLSAqIEBhdXRob3IgU2FuZHkgR2FvLCBJQk0KLSAqCi0gKiBAdmVyc2lvbiAkSWQ6IFhTRFdpbGRjYXJkVHJhdmVyc2VyLmphdmEsdiAxLjcgMjAxMC0xMS0wMSAwNDo0MDowMiBqb2VodyBFeHAgJAotICovCi1jbGFzcyBYU0RXaWxkY2FyZFRyYXZlcnNlciBleHRlbmRzIFhTREFic3RyYWN0VHJhdmVyc2VyIHsKLQotICAgIC8qKgotICAgICAqIGNvbnN0cnVjdG9yCi0gICAgICoKLSAgICAgKiBAcGFyYW0gIGhhbmRsZXIKLSAgICAgKiBAcGFyYW0gIGVycm9yUmVwb3J0ZXIKLSAgICAgKiBAcGFyYW0gIGdBdHRyQ2hlY2sKLSAgICAgKi8KLSAgICBYU0RXaWxkY2FyZFRyYXZlcnNlciAoWFNESGFuZGxlciBoYW5kbGVyLAotICAgICAgICAgICAgWFNBdHRyaWJ1dGVDaGVja2VyIGdBdHRyQ2hlY2spIHsKLSAgICAgICAgc3VwZXIoaGFuZGxlciwgZ0F0dHJDaGVjayk7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBUcmF2ZXJzZSAmbHQ7YW55Jmd0OwotICAgICAqCi0gICAgICogQHBhcmFtICBlbG1Ob2RlCi0gICAgICogQHBhcmFtICBzY2hlbWFEb2MKLSAgICAgKiBAcGFyYW0gIGdyYW1tYXIKLSAgICAgKiBAcmV0dXJuIHRoZSB3aWxkY2FyZCBub2RlIGluZGV4Ci0gICAgICovCi0gICAgWFNQYXJ0aWNsZURlY2wgdHJhdmVyc2VBbnkoRWxlbWVudCBlbG1Ob2RlLAotICAgICAgICAgICAgWFNEb2N1bWVudEluZm8gc2NoZW1hRG9jLAotICAgICAgICAgICAgU2NoZW1hR3JhbW1hciBncmFtbWFyKSB7Ci0KLSAgICAgICAgLy8gR2VuZXJhbCBBdHRyaWJ1dGUgQ2hlY2tpbmcgZm9yIGVsbU5vZGUKLSAgICAgICAgT2JqZWN0W10gYXR0clZhbHVlcyA9IGZBdHRyQ2hlY2tlci5jaGVja0F0dHJpYnV0ZXMoZWxtTm9kZSwgZmFsc2UsIHNjaGVtYURvYyk7Ci0gICAgICAgIFhTV2lsZGNhcmREZWNsIHdpbGRjYXJkID0gdHJhdmVyc2VXaWxkY2FyZERlY2woZWxtTm9kZSwgYXR0clZhbHVlcywgc2NoZW1hRG9jLCBncmFtbWFyKTsKLQotICAgICAgICAvLyBmb3IgPGFueT4sIG5lZWQgdG8gY3JlYXRlIGEgbmV3IHBhcnRpY2xlIHRvIHJlZmxlY3QgdGhlIG1pbi9tYXggdmFsdWVzCi0gICAgICAgIFhTUGFydGljbGVEZWNsIHBhcnRpY2xlID0gbnVsbDsKLSAgICAgICAgaWYgKHdpbGRjYXJkICE9IG51bGwpIHsKLSAgICAgICAgICAgIGludCBtaW4gPSAoKFhJbnQpYXR0clZhbHVlc1tYU0F0dHJpYnV0ZUNoZWNrZXIuQVRUSURYX01JTk9DQ1VSU10pLmludFZhbHVlKCk7Ci0gICAgICAgICAgICBpbnQgbWF4ID0gKChYSW50KWF0dHJWYWx1ZXNbWFNBdHRyaWJ1dGVDaGVja2VyLkFUVElEWF9NQVhPQ0NVUlNdKS5pbnRWYWx1ZSgpOwotICAgICAgICAgICAgaWYgKG1heCAhPSAwKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGZTY2hlbWFIYW5kbGVyLmZEZWNsUG9vbCAhPW51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgcGFydGljbGUgPSBmU2NoZW1hSGFuZGxlci5mRGVjbFBvb2wuZ2V0UGFydGljbGVEZWNsKCk7Ci0gICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgcGFydGljbGUgPSBuZXcgWFNQYXJ0aWNsZURlY2woKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgcGFydGljbGUuZlR5cGUgPSBYU1BhcnRpY2xlRGVjbC5QQVJUSUNMRV9XSUxEQ0FSRDsKLSAgICAgICAgICAgICAgICBwYXJ0aWNsZS5mVmFsdWUgPSB3aWxkY2FyZDsKLSAgICAgICAgICAgICAgICBwYXJ0aWNsZS5mTWluT2NjdXJzID0gbWluOwotICAgICAgICAgICAgICAgIHBhcnRpY2xlLmZNYXhPY2N1cnMgPSBtYXg7Ci0gICAgICAgICAgICAgICAgcGFydGljbGUuZkFubm90YXRpb25zID0gd2lsZGNhcmQuZkFubm90YXRpb25zOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgZkF0dHJDaGVja2VyLnJldHVybkF0dHJBcnJheShhdHRyVmFsdWVzLCBzY2hlbWFEb2MpOwotCi0gICAgICAgIHJldHVybiBwYXJ0aWNsZTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFRyYXZlcnNlICZsdDthbnlBdHRyaWJ1dGUmZ3Q7Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gIGVsbU5vZGUKLSAgICAgKiBAcGFyYW0gIHNjaGVtYURvYwotICAgICAqIEBwYXJhbSAgZ3JhbW1hcgotICAgICAqIEByZXR1cm4gdGhlIHdpbGRjYXJkIG5vZGUgaW5kZXgKLSAgICAgKi8KLSAgICBYU1dpbGRjYXJkRGVjbCB0cmF2ZXJzZUFueUF0dHJpYnV0ZShFbGVtZW50IGVsbU5vZGUsCi0gICAgICAgICAgICBYU0RvY3VtZW50SW5mbyBzY2hlbWFEb2MsCi0gICAgICAgICAgICBTY2hlbWFHcmFtbWFyIGdyYW1tYXIpIHsKLQotICAgICAgICAvLyBHZW5lcmFsIEF0dHJpYnV0ZSBDaGVja2luZyBmb3IgZWxtTm9kZQotICAgICAgICBPYmplY3RbXSBhdHRyVmFsdWVzID0gZkF0dHJDaGVja2VyLmNoZWNrQXR0cmlidXRlcyhlbG1Ob2RlLCBmYWxzZSwgc2NoZW1hRG9jKTsKLSAgICAgICAgWFNXaWxkY2FyZERlY2wgd2lsZGNhcmQgPSB0cmF2ZXJzZVdpbGRjYXJkRGVjbChlbG1Ob2RlLCBhdHRyVmFsdWVzLCBzY2hlbWFEb2MsIGdyYW1tYXIpOwotICAgICAgICBmQXR0ckNoZWNrZXIucmV0dXJuQXR0ckFycmF5KGF0dHJWYWx1ZXMsIHNjaGVtYURvYyk7Ci0KLSAgICAgICAgcmV0dXJuIHdpbGRjYXJkOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICoKLSAgICAgKiBAcGFyYW0gIGVsbU5vZGUKLSAgICAgKiBAcGFyYW0gIGF0dHJWYWx1ZXMKLSAgICAgKiBAcGFyYW0gIHNjaGVtYURvYwotICAgICAqIEBwYXJhbSAgZ3JhbW1hcgotICAgICAqIEByZXR1cm4gdGhlIHdpbGRjYXJkIG5vZGUgaW5kZXgKLSAgICAgKi8KLSAgICBYU1dpbGRjYXJkRGVjbCB0cmF2ZXJzZVdpbGRjYXJkRGVjbChFbGVtZW50IGVsbU5vZGUsCi0gICAgICAgICAgICBPYmplY3RbXSBhdHRyVmFsdWVzLAotICAgICAgICAgICAgWFNEb2N1bWVudEluZm8gc2NoZW1hRG9jLAotICAgICAgICAgICAgU2NoZW1hR3JhbW1hciBncmFtbWFyKSB7Ci0KLSAgICAgICAgLy9nZXQgYWxsIGF0dHJpYnV0ZXMKLSAgICAgICAgWFNXaWxkY2FyZERlY2wgd2lsZGNhcmQgPSBuZXcgWFNXaWxkY2FyZERlY2woKTsKLSAgICAgICAgLy8gbmFtZXNwYWNlIHR5cGUKLSAgICAgICAgWEludCBuYW1lc3BhY2VUeXBlQXR0ciA9IChYSW50KSBhdHRyVmFsdWVzW1hTQXR0cmlidXRlQ2hlY2tlci5BVFRJRFhfTkFNRVNQQUNFXTsKLSAgICAgICAgd2lsZGNhcmQuZlR5cGUgPSBuYW1lc3BhY2VUeXBlQXR0ci5zaG9ydFZhbHVlKCk7Ci0gICAgICAgIC8vIG5hbWVzcGFjZSBsaXN0Ci0gICAgICAgIHdpbGRjYXJkLmZOYW1lc3BhY2VMaXN0ID0gKFN0cmluZ1tdKWF0dHJWYWx1ZXNbWFNBdHRyaWJ1dGVDaGVja2VyLkFUVElEWF9OQU1FU1BBQ0VfTElTVF07Ci0gICAgICAgIC8vIHByb2Nlc3MgY29udGVudHMKLSAgICAgICAgWEludCBwcm9jZXNzQ29udGVudHNBdHRyID0gKFhJbnQpIGF0dHJWYWx1ZXNbWFNBdHRyaWJ1dGVDaGVja2VyLkFUVElEWF9QUk9DRVNTQ09OVEVOVFNdOwotICAgICAgICB3aWxkY2FyZC5mUHJvY2Vzc0NvbnRlbnRzID0gcHJvY2Vzc0NvbnRlbnRzQXR0ci5zaG9ydFZhbHVlKCk7Ci0KLSAgICAgICAgLy9jaGVjayBjb250ZW50Ci0gICAgICAgIEVsZW1lbnQgY2hpbGQgPSBET01VdGlsLmdldEZpcnN0Q2hpbGRFbGVtZW50KGVsbU5vZGUpOwotICAgICAgICBYU0Fubm90YXRpb25JbXBsIGFubm90YXRpb24gPSBudWxsOwotICAgICAgICBpZiAoY2hpbGQgIT0gbnVsbCkKLSAgICAgICAgewotICAgICAgICAgICAgaWYgKERPTVV0aWwuZ2V0TG9jYWxOYW1lKGNoaWxkKS5lcXVhbHMoU2NoZW1hU3ltYm9scy5FTFRfQU5OT1RBVElPTikpIHsKLSAgICAgICAgICAgICAgICBhbm5vdGF0aW9uID0gdHJhdmVyc2VBbm5vdGF0aW9uRGVjbChjaGlsZCwgYXR0clZhbHVlcywgZmFsc2UsIHNjaGVtYURvYyk7Ci0gICAgICAgICAgICAgICAgY2hpbGQgPSBET01VdGlsLmdldE5leHRTaWJsaW5nRWxlbWVudChjaGlsZCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgdGV4dCA9IERPTVV0aWwuZ2V0U3ludGhldGljQW5ub3RhdGlvbihlbG1Ob2RlKTsKLSAgICAgICAgICAgICAgICBpZiAodGV4dCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGFubm90YXRpb24gPSB0cmF2ZXJzZVN5bnRoZXRpY0Fubm90YXRpb24oZWxtTm9kZSwgdGV4dCwgYXR0clZhbHVlcywgZmFsc2UsIHNjaGVtYURvYyk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAoY2hpbGQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJlcG9ydFNjaGVtYUVycm9yKCJzNHMtZWx0LW11c3QtbWF0Y2guMSIsIG5ldyBPYmplY3RbXXsid2lsZGNhcmQiLCAiKGFubm90YXRpb24/KSIsIERPTVV0aWwuZ2V0TG9jYWxOYW1lKGNoaWxkKX0sIGVsbU5vZGUpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgU3RyaW5nIHRleHQgPSBET01VdGlsLmdldFN5bnRoZXRpY0Fubm90YXRpb24oZWxtTm9kZSk7Ci0gICAgICAgICAgICBpZiAodGV4dCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgYW5ub3RhdGlvbiA9IHRyYXZlcnNlU3ludGhldGljQW5ub3RhdGlvbihlbG1Ob2RlLCB0ZXh0LCBhdHRyVmFsdWVzLCBmYWxzZSwgc2NoZW1hRG9jKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBYU09iamVjdExpc3QgYW5ub3RhdGlvbnM7Ci0gICAgICAgIGlmIChhbm5vdGF0aW9uICE9IG51bGwpIHsKLSAgICAgICAgICAgIGFubm90YXRpb25zID0gbmV3IFhTT2JqZWN0TGlzdEltcGwoKTsKLSAgICAgICAgICAgICgoWFNPYmplY3RMaXN0SW1wbCkgYW5ub3RhdGlvbnMpLmFkZFhTT2JqZWN0KGFubm90YXRpb24pOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgYW5ub3RhdGlvbnMgPSBYU09iamVjdExpc3RJbXBsLkVNUFRZX0xJU1Q7Ci0gICAgICAgIH0KLSAgICAgICAgd2lsZGNhcmQuZkFubm90YXRpb25zID0gYW5ub3RhdGlvbnM7Ci0KLSAgICAgICAgcmV0dXJuIHdpbGRjYXJkOwotCi0gICAgfSAvLyB0cmF2ZXJzZVdpbGRjYXJkRGVjbAotCi19IC8vIFhTRFdpbGRjYXJkVHJhdmVyc2VyCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL3RyYXZlcnNlcnMvWFNEb2N1bWVudEluZm8uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvdHJhdmVyc2Vycy9YU0RvY3VtZW50SW5mby5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiNzU2MzlmLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvdHJhdmVyc2Vycy9YU0RvY3VtZW50SW5mby5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjUyICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLnRyYXZlcnNlcnM7Ci0KLWltcG9ydCBqYXZhLnV0aWwuU3RhY2s7Ci1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC52YWxpZGF0aW9uLlZhbGlkYXRpb25TdGF0ZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMuU2NoZW1hTmFtZXNwYWNlU3VwcG9ydDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMuU2NoZW1hU3ltYm9sczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMuWE1MU2NoZW1hRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy51dGlsLlhJbnQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlN5bWJvbFRhYmxlOwotaW1wb3J0IG9yZy53M2MuZG9tLkVsZW1lbnQ7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcudzNjLmRvbS5BdHRyOwotaW1wb3J0IG9yZy53M2MuZG9tLk5hbWVkTm9kZU1hcDsKLQotLyoqCi0gKiBPYmplY3RzIG9mIHRoaXMgY2xhc3MgaG9sZCBhbGwgaW5mb3JtYXRpb24gcGVjdWxhciB0byBhCi0gKiBwYXJ0aWN1bGFyIFhNTCBTY2hlbWEgZG9jdW1lbnQuICBUaGlzIGlzIG5lZWRlZCBiZWNhdXNlCi0gKiBuYW1lc3BhY2UgYmluZGluZ3MgYW5kIG90aGVyIHNldHRpbmdzIG9uIHRoZSA8c2NoZW1hLz4gZWxlbWVudAotICogYWZmZWN0IHRoZSBjb250ZW50cyBvZiB0aGF0IHNjaGVtYSBkb2N1bWVudCBhbG9uZS4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBOZWlsIEdyYWhhbSwgSUJNCi0gKiBAdmVyc2lvbiAkSWQ6IFhTRG9jdW1lbnRJbmZvLmphdmEsdiAxLjUgMjAwNy8xMC8xNSAyMjoyNzo0OCBzcGVyaWNhcyBFeHAgJAotICovCi1jbGFzcyBYU0RvY3VtZW50SW5mbyB7Ci0KLSAgICAvLyBEYXRhCi0gICAgcHJvdGVjdGVkIFNjaGVtYU5hbWVzcGFjZVN1cHBvcnQgZk5hbWVzcGFjZVN1cHBvcnQ7Ci0gICAgcHJvdGVjdGVkIFNjaGVtYU5hbWVzcGFjZVN1cHBvcnQgZk5hbWVzcGFjZVN1cHBvcnRSb290OwotICAgIHByb3RlY3RlZCBTdGFjayBTY2hlbWFOYW1lc3BhY2VTdXBwb3J0U3RhY2sgPSBuZXcgU3RhY2soKTsKLQotICAgIC8vIHNjaGVtYSdzIGF0dHJpYnV0ZUZvcm1EZWZhdWx0Ci0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZkFyZUxvY2FsQXR0cmlidXRlc1F1YWxpZmllZDsKLQotICAgIC8vIGVsZW1lbnRGb3JtRGVmYXVsdAotICAgIHByb3RlY3RlZCBib29sZWFuIGZBcmVMb2NhbEVsZW1lbnRzUXVhbGlmaWVkOwotCi0gICAgLy8gW2Jsb2NrIHwgZmluYWxdRGVmYXVsdAotICAgIHByb3RlY3RlZCBzaG9ydCBmQmxvY2tEZWZhdWx0OwotICAgIHByb3RlY3RlZCBzaG9ydCBmRmluYWxEZWZhdWx0OwotCi0gICAgLy8gdGFyZ2V0TmFtZXNwYWNlCi0gICAgU3RyaW5nIGZUYXJnZXROYW1lc3BhY2U7Ci0KLSAgICAvLyByZXByZXNlbnRzIHdoZXRoZXIgdGhpcyBpcyBhIGNoYW1lbGVvbiBzY2hlbWEgKGkuZS4sIHdoZXRoZXIgaXRzIFROUyBpcyBuYXR1cmFsIG9yIGNvbWVzIGZyb20gd2l0aG91dCkKLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBmSXNDaGFtZWxlb25TY2hlbWE7Ci0KLSAgICAvLyB0aGUgcm9vdCBvZiB0aGUgc2NoZW1hIERvY3VtZW50IHRyZWUgaXRzZWxmCi0gICAgcHJvdGVjdGVkIEVsZW1lbnQgZlNjaGVtYUVsZW1lbnQ7Ci0KLSAgICAvLyBhbGwgbmFtZXNwYWNlcyB0aGF0IHRoaXMgZG9jdW1lbnQgY2FuIHJlZmVyIHRvCi0gICAgVmVjdG9yIGZJbXBvcnRlZE5TID0gbmV3IFZlY3RvcigpOwotCi0gICAgcHJvdGVjdGVkIFZhbGlkYXRpb25TdGF0ZSBmVmFsaWRhdGlvbkNvbnRleHQgPSBuZXcgVmFsaWRhdGlvblN0YXRlKCk7Ci0KLSAgICBTeW1ib2xUYWJsZSBmU3ltYm9sVGFibGUgPSBudWxsOwotCi0gICAgLy8gYXR0cmlidXRlIGNoZWNrZXIgdG8gd2hpY2ggd2UnbGwgcmV0dXJuIHRoZSBhdHRyaWJ1dGVzCi0gICAgLy8gb25jZSB3ZSd2ZSBiZWVuIHRvbGQgdGhhdCB3ZSdyZSBkb25lIHdpdGggdGhlbQotICAgIHByb3RlY3RlZCBYU0F0dHJpYnV0ZUNoZWNrZXIgZkF0dHJDaGVja2VyOwotCi0gICAgLy8gYXJyYXkgb2Ygb2JqZWN0cyBvbiB0aGUgc2NoZW1hJ3Mgcm9vdCBlbGVtZW50LiAgVGhpcyBpcyBudWxsCi0gICAgLy8gb25jZSByZXR1cm5TY2hlbWFBdHRycyBoYXMgYmVlbiBjYWxsZWQuCi0gICAgcHJvdGVjdGVkIE9iamVjdCBbXSBmU2NoZW1hQXR0cnM7Ci0KLSAgICAvLyBsaXN0IG9mIGFubm90YXRpb25zIGNvbnRhaW5lZCBpbiB0aGUgc2NoZW1hIGRvY3VtZW50LiBUaGlzIGlzIG51bGwKLSAgICAvLyBvbmNlIHJlbW92ZUFubm90YXRpb25zIGhhcyBiZWVuIGNhbGxlZC4KLSAgICBwcm90ZWN0ZWQgWFNBbm5vdGF0aW9uSW5mbyBmQW5ub3RhdGlvbnMgPSBudWxsOwotCi0gICAgLy8gbm90ZSB0aGF0IHRoZSBjYWxsZXIgbXVzdCBlbnN1cmUgdG8gY2FsbCByZXR1cm5TY2hlbWFBdHRycygpCi0gICAgLy8gdG8gYXZvaWQgbWVtb3J5IGxlYWtzIQotICAgIFhTRG9jdW1lbnRJbmZvIChFbGVtZW50IHNjaGVtYVJvb3QsIFhTQXR0cmlidXRlQ2hlY2tlciBhdHRyQ2hlY2tlciwgU3ltYm9sVGFibGUgc3ltYm9sVGFibGUpCi0gICAgICAgICAgICAgICAgICAgIHRocm93cyBYTUxTY2hlbWFFeGNlcHRpb24gewotICAgICAgICBmU2NoZW1hRWxlbWVudCA9IHNjaGVtYVJvb3Q7Ci0gICAgICAgIGluaXROYW1lc3BhY2VTdXBwb3J0KHNjaGVtYVJvb3QpOwotICAgICAgICBmSXNDaGFtZWxlb25TY2hlbWEgPSBmYWxzZTsKLQotICAgICAgICBmU3ltYm9sVGFibGUgPSBzeW1ib2xUYWJsZTsKLSAgICAgICAgZkF0dHJDaGVja2VyID0gYXR0ckNoZWNrZXI7Ci0KLSAgICAgICAgaWYgKHNjaGVtYVJvb3QgIT0gbnVsbCkgewotICAgICAgICAgICAgRWxlbWVudCByb290ID0gc2NoZW1hUm9vdDsKLSAgICAgICAgICAgIGZTY2hlbWFBdHRycyA9IGF0dHJDaGVja2VyLmNoZWNrQXR0cmlidXRlcyhyb290LCB0cnVlLCB0aGlzKTsKLSAgICAgICAgICAgIC8vIHNjaGVtYUF0dHJzID09IG51bGwgbWVhbnMgaXQncyBub3QgYW4gPHhzZDpzY2hlbWE+IGVsZW1lbnQKLSAgICAgICAgICAgIC8vIHRocm93IGFuIGV4Y2VwdGlvbiwgYnV0IHdlIGRvbid0IGtub3cgdGhlIGRvY3VtZW50IHN5c3RlbUlkLAotICAgICAgICAgICAgLy8gc28gd2UgbGVhdmUgdGhhdCB0byB0aGUgY2FsbGVyLgotICAgICAgICAgICAgaWYgKGZTY2hlbWFBdHRycyA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFhNTFNjaGVtYUV4Y2VwdGlvbihudWxsLCBudWxsKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGZBcmVMb2NhbEF0dHJpYnV0ZXNRdWFsaWZpZWQgPQotICAgICAgICAgICAgICAgICgoWEludClmU2NoZW1hQXR0cnNbWFNBdHRyaWJ1dGVDaGVja2VyLkFUVElEWF9BRk9STURFRkFVTFRdKS5pbnRWYWx1ZSgpID09IFNjaGVtYVN5bWJvbHMuRk9STV9RVUFMSUZJRUQ7Ci0gICAgICAgICAgICBmQXJlTG9jYWxFbGVtZW50c1F1YWxpZmllZCA9Ci0gICAgICAgICAgICAgICAgKChYSW50KWZTY2hlbWFBdHRyc1tYU0F0dHJpYnV0ZUNoZWNrZXIuQVRUSURYX0VGT1JNREVGQVVMVF0pLmludFZhbHVlKCkgPT0gU2NoZW1hU3ltYm9scy5GT1JNX1FVQUxJRklFRDsKLSAgICAgICAgICAgIGZCbG9ja0RlZmF1bHQgPQotICAgICAgICAgICAgICAgICgoWEludClmU2NoZW1hQXR0cnNbWFNBdHRyaWJ1dGVDaGVja2VyLkFUVElEWF9CTE9DS0RFRkFVTFRdKS5zaG9ydFZhbHVlKCk7Ci0gICAgICAgICAgICBmRmluYWxEZWZhdWx0ID0KLSAgICAgICAgICAgICAgICAoKFhJbnQpZlNjaGVtYUF0dHJzW1hTQXR0cmlidXRlQ2hlY2tlci5BVFRJRFhfRklOQUxERUZBVUxUXSkuc2hvcnRWYWx1ZSgpOwotICAgICAgICAgICAgZlRhcmdldE5hbWVzcGFjZSA9Ci0gICAgICAgICAgICAgICAgKFN0cmluZylmU2NoZW1hQXR0cnNbWFNBdHRyaWJ1dGVDaGVja2VyLkFUVElEWF9UQVJHRVROQU1FU1BBQ0VdOwotICAgICAgICAgICAgaWYgKGZUYXJnZXROYW1lc3BhY2UgIT0gbnVsbCkKLSAgICAgICAgICAgICAgICBmVGFyZ2V0TmFtZXNwYWNlID0gc3ltYm9sVGFibGUuYWRkU3ltYm9sKGZUYXJnZXROYW1lc3BhY2UpOwotCi0gICAgICAgICAgICBmTmFtZXNwYWNlU3VwcG9ydFJvb3QgPSBuZXcgU2NoZW1hTmFtZXNwYWNlU3VwcG9ydChmTmFtZXNwYWNlU3VwcG9ydCk7Ci0KLSAgICAgICAgICAgIC8vc2V0IG5hbWVzcGFjZSBzdXBwb3J0Ci0gICAgICAgICAgICBmVmFsaWRhdGlvbkNvbnRleHQuc2V0TmFtZXNwYWNlU3VwcG9ydChmTmFtZXNwYWNlU3VwcG9ydCk7Ci0gICAgICAgICAgICBmVmFsaWRhdGlvbkNvbnRleHQuc2V0U3ltYm9sVGFibGUoc3ltYm9sVGFibGUpOwotICAgICAgICAgICAgLy8gcGFzcyBudWxsIGFzIHRoZSBzY2hlbWEgZG9jdW1lbnQsIHNvIHRoYXQgdGhlIG5hbWVzcGFjZQotICAgICAgICAgICAgLy8gY29udGV4dCBpcyBub3QgcG9wcGVkLgotCi0gICAgICAgICAgICAvLyBkb24ndCByZXR1cm4gdGhlIGF0dHJpYnV0ZSBhcnJheSB5ZXQhCi0gICAgICAgICAgICAvL2F0dHJDaGVja2VyLnJldHVybkF0dHJBcnJheShzY2hlbWFBdHRycywgbnVsbCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJbml0aWFsaXplIG5hbWVzcGFjZSBzdXBwb3J0IGJ5IGNvbGxlY3RpbmcgYWxsIG9mIHRoZSBuYW1lc3BhY2UKLSAgICAgKiBkZWNsYXJhdGlvbnMgaW4gdGhlIHJvb3QncyBhbmNlc3RvcnMuIFRoaXMgaXMgbmVjZXNzYXJ5IHRvCi0gICAgICogc3VwcG9ydCBzY2hlbWFzIGZyYWdtZW50cywgaS5lLiBzY2hlbWFzIGVtYmVkZGVkIGluIG90aGVyCi0gICAgICogZG9jdW1lbnRzLiBTZWUsCi0gICAgICoKLSAgICAgKiBodHRwczovL2pheHAuZGV2LmphdmEubmV0L2lzc3Vlcy9zaG93X2J1Zy5jZ2k/aWQ9NDMKLSAgICAgKgotICAgICAqIFJlcXVpcmVzIHRoZSBET00gdG8gYmUgY3JlYXRlZCB3aXRoIG5hbWVzcGFjZSBzdXBwb3J0IGVuYWJsZWQuCi0gICAgICovCi0gICAgcHJpdmF0ZSB2b2lkIGluaXROYW1lc3BhY2VTdXBwb3J0KEVsZW1lbnQgc2NoZW1hUm9vdCkgewotICAgICAgICBmTmFtZXNwYWNlU3VwcG9ydCA9IG5ldyBTY2hlbWFOYW1lc3BhY2VTdXBwb3J0KCk7Ci0gICAgICAgIGZOYW1lc3BhY2VTdXBwb3J0LnJlc2V0KCk7Ci0KLSAgICAgICAgTm9kZSBwYXJlbnQgPSBzY2hlbWFSb290LmdldFBhcmVudE5vZGUoKTsKLSAgICAgICAgd2hpbGUgKHBhcmVudCAhPSBudWxsICYmIHBhcmVudC5nZXROb2RlVHlwZSgpID09IE5vZGUuRUxFTUVOVF9OT0RFCi0gICAgICAgICAgICAgICAgJiYgIXBhcmVudC5nZXROb2RlTmFtZSgpLmVxdWFscygiRE9DVU1FTlRfTk9ERSIpKQotICAgICAgICB7Ci0gICAgICAgICAgICBFbGVtZW50IGVwYXJlbnQgPSAoRWxlbWVudCkgcGFyZW50OwotICAgICAgICAgICAgTmFtZWROb2RlTWFwIG1hcCA9IGVwYXJlbnQuZ2V0QXR0cmlidXRlcygpOwotICAgICAgICAgICAgaW50IGxlbmd0aCA9IChtYXAgIT0gbnVsbCkgPyBtYXAuZ2V0TGVuZ3RoKCkgOiAwOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykgewotICAgICAgICAgICAgICAgIEF0dHIgYXR0ciA9IChBdHRyKSBtYXAuaXRlbShpKTsKLSAgICAgICAgICAgICAgICBTdHJpbmcgdXJpID0gYXR0ci5nZXROYW1lc3BhY2VVUkkoKTsKLQotICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIGF0dHJpYnV0ZSBpcyBhbiBucyBkZWNsIC0tIHJlcXVpcmVzIG5zIHN1cHBvcnQKLSAgICAgICAgICAgICAgICBpZiAodXJpICE9IG51bGwgJiYgdXJpLmVxdWFscygiaHR0cDovL3d3dy53My5vcmcvMjAwMC94bWxucy8iKSkgewotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcHJlZml4ID0gYXR0ci5nZXRMb2NhbE5hbWUoKS5pbnRlcm4oKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKHByZWZpeCA9PSAieG1sbnMiKSBwcmVmaXggPSAiIjsKLSAgICAgICAgICAgICAgICAgICAgLy8gRGVjbGFyZSBwcmVmaXggaWYgbm90IHNldCAtLSBtb3ZpbmcgdXB3YXJkcwotICAgICAgICAgICAgICAgICAgICBpZiAoZk5hbWVzcGFjZVN1cHBvcnQuZ2V0VVJJKHByZWZpeCkgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgZk5hbWVzcGFjZVN1cHBvcnQuZGVjbGFyZVByZWZpeChwcmVmaXgsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHIuZ2V0VmFsdWUoKS5pbnRlcm4oKSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBwYXJlbnQgPSBwYXJlbnQuZ2V0UGFyZW50Tm9kZSgpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLy8gYmFja3VwIHRoZSBjdXJyZW50IG5zIHN1cHBvcnQsIGFuZCB1c2UgdGhlIG9uZSBwYXNzZWQtaW4uCi0gICAgLy8gaWYgbm8gbnMgc3VwcG9ydCBpcyBwYXNzZWQtaW4sIHVzZSB0aGUgb25lIGZvciA8c2NoZW1hPiBlbGVtZW50Ci0gICAgdm9pZCBiYWNrdXBOU1N1cHBvcnQoU2NoZW1hTmFtZXNwYWNlU3VwcG9ydCBuc1N1cHBvcnQpIHsKLSAgICAgICAgU2NoZW1hTmFtZXNwYWNlU3VwcG9ydFN0YWNrLnB1c2goZk5hbWVzcGFjZVN1cHBvcnQpOwotICAgICAgICBpZiAobnNTdXBwb3J0ID09IG51bGwpCi0gICAgICAgICAgICBuc1N1cHBvcnQgPSBmTmFtZXNwYWNlU3VwcG9ydFJvb3Q7Ci0gICAgICAgIGZOYW1lc3BhY2VTdXBwb3J0ID0gbmV3IFNjaGVtYU5hbWVzcGFjZVN1cHBvcnQobnNTdXBwb3J0KTsKLQotICAgICAgICBmVmFsaWRhdGlvbkNvbnRleHQuc2V0TmFtZXNwYWNlU3VwcG9ydChmTmFtZXNwYWNlU3VwcG9ydCk7Ci0gICAgfQotCi0gICAgdm9pZCByZXN0b3JlTlNTdXBwb3J0KCkgewotICAgICAgICBmTmFtZXNwYWNlU3VwcG9ydCA9IChTY2hlbWFOYW1lc3BhY2VTdXBwb3J0KVNjaGVtYU5hbWVzcGFjZVN1cHBvcnRTdGFjay5wb3AoKTsKLSAgICAgICAgZlZhbGlkYXRpb25Db250ZXh0LnNldE5hbWVzcGFjZVN1cHBvcnQoZk5hbWVzcGFjZVN1cHBvcnQpOwotICAgIH0KLQotICAgIC8vIHNvbWUgT2JqZWN0IG1ldGhvZHMKLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgICAgICByZXR1cm4gZlRhcmdldE5hbWVzcGFjZSA9PSBudWxsPyJubyB0YXJnZXROYW1zcGFjZSI6InRhcmdldE5hbWVzcGFjZSBpcyAiICsgZlRhcmdldE5hbWVzcGFjZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBhZGRBbGxvd2VkTlMoU3RyaW5nIG5hbWVzcGFjZSkgewotICAgICAgICBmSW1wb3J0ZWROUy5hZGRFbGVtZW50KG5hbWVzcGFjZSA9PSBudWxsID8gIiIgOiBuYW1lc3BhY2UpOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGlzQWxsb3dlZE5TKFN0cmluZyBuYW1lc3BhY2UpIHsKLSAgICAgICAgcmV0dXJuIGZJbXBvcnRlZE5TLmNvbnRhaW5zKG5hbWVzcGFjZSA9PSBudWxsID8gIiIgOiBuYW1lc3BhY2UpOwotICAgIH0KLQotICAgIC8vIHN0b3JlIHdoZXRoZXIgd2UgaGF2ZSByZXBvcnRlZCBhbiBlcnJvciBhYm91dCB0aGF0IHRoaXMgZG9jdW1lbnQKLSAgICAvLyBjYW4ndCBhY2Nlc3MgY29tcG9uZW50cyBmcm9tIHRoZSBnaXZlbiBuYW1lc3BhY2UKLSAgICBwcml2YXRlIFZlY3RvciBmUmVwb3J0ZWRUTlMgPSBudWxsOwotICAgIC8vIGNoZWNrIHdoZXRoZXIgd2UgbmVlZCB0byByZXBvcnQgYW4gZXJyb3IgYWdhaW5zdCB0aGUgZ2l2ZW4gdXJpLgotICAgIC8vIGlmIHdlIGhhdmUgcmVwb3J0ZWQgYW4gZXJyb3IsIHRoZW4gd2UgZG9uJ3QgbmVlZCB0byByZXBvcnQgYWdhaW47Ci0gICAgLy8gb3RoZXJ3aXNlIHdlIHJlcG9ydGVkIHRoZSBlcnJvciwgYW5kIHJlbWVtYmVyIHRoaXMgZmFjdC4KLSAgICBmaW5hbCBib29sZWFuIG5lZWRSZXBvcnRUTlNFcnJvcihTdHJpbmcgdXJpKSB7Ci0gICAgICAgIGlmIChmUmVwb3J0ZWRUTlMgPT0gbnVsbCkKLSAgICAgICAgICAgIGZSZXBvcnRlZFROUyA9IG5ldyBWZWN0b3IoKTsKLSAgICAgICAgZWxzZSBpZiAoZlJlcG9ydGVkVE5TLmNvbnRhaW5zKHVyaSkpCi0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIGZSZXBvcnRlZFROUy5hZGRFbGVtZW50KHVyaSk7Ci0gICAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotICAgIC8vIHJldHVybiB0aGUgYXR0cmlidXRlcyBvbiB0aGUgc2NoZW1hIGVsZW1lbnQgaXRzZWxmOgotICAgIE9iamVjdCBbXSBnZXRTY2hlbWFBdHRycyAoKSB7Ci0gICAgICAgIHJldHVybiBmU2NoZW1hQXR0cnM7Ci0gICAgfQotCi0gICAgLy8gZGVhbGxvY2F0ZSB0aGUgc3RvcmFnZSBzZXQgYXNpZGUgZm9yIHRoZSBzY2hlbWEgZWxlbWVudCdzCi0gICAgLy8gYXR0cmlidXRlcwotICAgIHZvaWQgcmV0dXJuU2NoZW1hQXR0cnMgKCkgewotICAgICAgICBmQXR0ckNoZWNrZXIucmV0dXJuQXR0ckFycmF5IChmU2NoZW1hQXR0cnMsIG51bGwpOwotICAgICAgICBmU2NoZW1hQXR0cnMgPSBudWxsOwotICAgIH0KLQotICAgIC8vIGFkZHMgYW4gYW5ub3RhdGlvbiB0byB0aGUgbGlzdCBvZiBhbm5vdGF0aW9ucwotICAgIHZvaWQgYWRkQW5ub3RhdGlvbihYU0Fubm90YXRpb25JbmZvIGluZm8pIHsKLSAgICAgICAgaW5mby5uZXh0ID0gZkFubm90YXRpb25zOwotICAgICAgICBmQW5ub3RhdGlvbnMgPSBpbmZvOwotICAgIH0KLQotICAgIC8vIHJldHVybnMgdGhlIGxpc3Qgb2YgYW5ub3RhdGlvbnMgY29uYXRpbmVkIGluIHRoZQotICAgIC8vIHNjaGVtYSBkb2N1bWVudCBvciBudWxsIGlmIHRoZSBkb2N1bWVudCBjb250YWluZWQgbm8gYW5ub3RhdGlvbnMuCi0gICAgWFNBbm5vdGF0aW9uSW5mbyBnZXRBbm5vdGF0aW9ucygpIHsKLSAgICAgICAgcmV0dXJuIGZBbm5vdGF0aW9uczsKLSAgICB9Ci0KLSAgICAvLyByZW1vdmVzIHJlZmVyZW5jZSB0byBhbm5vdGF0aW9uIGxpc3QKLSAgICB2b2lkIHJlbW92ZUFubm90YXRpb25zKCkgewotICAgICAgICBmQW5ub3RhdGlvbnMgPSBudWxsOwotICAgIH0KLQotfSAvLyBYU0RvY3VtZW50SW5mbwpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy91dGlsL0xTSW5wdXRMaXN0SW1wbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy91dGlsL0xTSW5wdXRMaXN0SW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjOGE5MzI5Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvdXRpbC9MU0lucHV0TGlzdEltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEyNiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQotICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCi0gKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCi0gKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAotICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKLSAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy51dGlsOwotCi1pbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuQXJyYXk7Ci1pbXBvcnQgamF2YS51dGlsLkFic3RyYWN0TGlzdDsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuTFNJbnB1dExpc3Q7Ci1pbXBvcnQgb3JnLnczYy5kb20ubHMuTFNJbnB1dDsKLQotLyoqCi0gKiBDb250YWlucyBhIGxpc3Qgb2YgTFNJbnB1dHMuCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgTWljaGFlbCBHbGF2YXNzZXZpY2gsIElCTQotICoKLSAqIEB2ZXJzaW9uICRJZDogTFNJbnB1dExpc3RJbXBsLmphdmEsdiAxLjIgMjAxMC0xMC0yNiAyMzowMTowNCBqb2VodyBFeHAgJAotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgTFNJbnB1dExpc3RJbXBsIGV4dGVuZHMgQWJzdHJhY3RMaXN0IGltcGxlbWVudHMgTFNJbnB1dExpc3QgewotCi0gICAgLyoqCi0gICAgICogQW4gaW1tdXRhYmxlIGVtcHR5IGxpc3QuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBMU0lucHV0TGlzdEltcGwgRU1QVFlfTElTVCA9IG5ldyBMU0lucHV0TGlzdEltcGwobmV3IExTSW5wdXRbMF0sIDApOwotCi0gICAgLy8gVGhlIGFycmF5IHRvIGhvbGQgYWxsIGRhdGEKLSAgICBwcml2YXRlIGZpbmFsIExTSW5wdXRbXSBmQXJyYXk7Ci0gICAgLy8gTnVtYmVyIG9mIGVsZW1lbnRzIGluIHRoaXMgbGlzdAotICAgIHByaXZhdGUgZmluYWwgaW50IGZMZW5ndGg7Ci0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3QgYW4gTFNJbnB1dExpc3QgaW1wbGVtZW50YXRpb24KLSAgICAgKgotICAgICAqIEBwYXJhbSBhcnJheSAgICAgdGhlIGRhdGEgYXJyYXkKLSAgICAgKiBAcGFyYW0gbGVuZ3RoICAgIHRoZSBudW1iZXIgb2YgZWxlbWVudHMKLSAgICAgKi8KLSAgICBwdWJsaWMgTFNJbnB1dExpc3RJbXBsKExTSW5wdXRbXSBhcnJheSwgaW50IGxlbmd0aCkgewotICAgICAgICBmQXJyYXkgPSBhcnJheTsKLSAgICAgICAgZkxlbmd0aCA9IGxlbmd0aDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgbnVtYmVyIG9mIDxjb2RlPkxTSW5wdXQ8L2NvZGU+cyBpbiB0aGUgbGlzdC4gVGhlIHJhbmdlIG9mIHZhbGlkCi0gICAgICogY2hpbGQgb2JqZWN0IGluZGljZXMgaXMgMCB0byA8Y29kZT5sZW5ndGgtMTwvY29kZT4gaW5jbHVzaXZlLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0TGVuZ3RoKCkgewotICAgICAgICByZXR1cm4gZkxlbmd0aDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSA8Y29kZT5pbmRleDwvY29kZT50aCBpdGVtIGluIHRoZSBjb2xsZWN0aW9uIG9yCi0gICAgICogPGNvZGU+bnVsbDwvY29kZT4gaWYgPGNvZGU+aW5kZXg8L2NvZGU+IGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0bwotICAgICAqIHRoZSBudW1iZXIgb2Ygb2JqZWN0cyBpbiB0aGUgbGlzdC4gVGhlIGluZGV4IHN0YXJ0cyBhdCAwLgotICAgICAqIEBwYXJhbSBpbmRleCAgaW5kZXggaW50byB0aGUgY29sbGVjdGlvbi4KLSAgICAgKiBAcmV0dXJuICBUaGUgPGNvZGU+TFNJbnB1dDwvY29kZT4gYXQgdGhlIDxjb2RlPmluZGV4PC9jb2RlPnRoCi0gICAgICogICBwb3NpdGlvbiBpbiB0aGUgPGNvZGU+TFNJbnB1dExpc3Q8L2NvZGU+LCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZgotICAgICAqICAgdGhlIGluZGV4IHNwZWNpZmllZCBpcyBub3QgdmFsaWQuCi0gICAgICovCi0gICAgcHVibGljIExTSW5wdXQgaXRlbShpbnQgaW5kZXgpIHsKLSAgICAgICAgaWYgKGluZGV4IDwgMCB8fCBpbmRleCA+PSBmTGVuZ3RoKSB7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZkFycmF5W2luZGV4XTsKLSAgICB9Ci0KLSAgICAvKgotICAgICAqIExpc3QgbWV0aG9kcwotICAgICAqLwotCi0gICAgcHVibGljIE9iamVjdCBnZXQoaW50IGluZGV4KSB7Ci0gICAgICAgIGlmIChpbmRleCA+PSAwICYmIGluZGV4IDwgZkxlbmd0aCkgewotICAgICAgICAgICAgcmV0dXJuIGZBcnJheVtpbmRleF07Ci0gICAgICAgIH0KLSAgICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oIkluZGV4OiAiICsgaW5kZXgpOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKLSAgICAgICAgcmV0dXJuIGdldExlbmd0aCgpOwotICAgIH0KLQotICAgIHB1YmxpYyBPYmplY3RbXSB0b0FycmF5KCkgewotICAgICAgICBPYmplY3RbXSBhID0gbmV3IE9iamVjdFtmTGVuZ3RoXTsKLSAgICAgICAgdG9BcnJheTAoYSk7Ci0gICAgICAgIHJldHVybiBhOwotICAgIH0KLQotICAgIHB1YmxpYyBPYmplY3RbXSB0b0FycmF5KE9iamVjdFtdIGEpIHsKLSAgICAgICAgaWYgKGEubGVuZ3RoIDwgZkxlbmd0aCkgewotICAgICAgICAgICAgQ2xhc3MgYXJyYXlDbGFzcyA9IGEuZ2V0Q2xhc3MoKTsKLSAgICAgICAgICAgIENsYXNzIGNvbXBvbmVudFR5cGUgPSBhcnJheUNsYXNzLmdldENvbXBvbmVudFR5cGUoKTsKLSAgICAgICAgICAgIGEgPSAoT2JqZWN0W10pIEFycmF5Lm5ld0luc3RhbmNlKGNvbXBvbmVudFR5cGUsIGZMZW5ndGgpOwotICAgICAgICB9Ci0gICAgICAgIHRvQXJyYXkwKGEpOwotICAgICAgICBpZiAoYS5sZW5ndGggPiBmTGVuZ3RoKSB7Ci0gICAgICAgICAgICBhW2ZMZW5ndGhdID0gbnVsbDsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gYTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgdG9BcnJheTAoT2JqZWN0W10gYSkgewotICAgICAgICBpZiAoZkxlbmd0aCA+IDApIHsKLSAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZkFycmF5LCAwLCBhLCAwLCBmTGVuZ3RoKTsKLSAgICAgICAgfQotICAgIH0KLQotfSAvLyBMU0lucHV0TGlzdEltcGwKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvdXRpbC9PYmplY3RMaXN0SW1wbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy91dGlsL09iamVjdExpc3RJbXBsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDlmMGExOTYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy91dGlsL09iamVjdExpc3RJbXBsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMTkgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKLSAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAotICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgotICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKLSAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCi0gKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMudXRpbDsKLQotaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkFycmF5OwotaW1wb3J0IGphdmEudXRpbC5BYnN0cmFjdExpc3Q7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLmRhdGF0eXBlcy5PYmplY3RMaXN0OwotCi0vKioKLSAqIENvbnRhaW5zIGEgbGlzdCBvZiBPYmplY3RzLgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAdmVyc2lvbiAkSWQ6IE9iamVjdExpc3RJbXBsLmphdmEsdiAxLjIgMjAxMC0xMC0yNiAyMzowMTowNCBqb2VodyBFeHAgJAotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgT2JqZWN0TGlzdEltcGwgZXh0ZW5kcyBBYnN0cmFjdExpc3QgaW1wbGVtZW50cyBPYmplY3RMaXN0IHsKLQotICAgIC8qKgotICAgICAqIEFuIGltbXV0YWJsZSBlbXB0eSBsaXN0LgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgT2JqZWN0TGlzdEltcGwgRU1QVFlfTElTVCA9IG5ldyBPYmplY3RMaXN0SW1wbChuZXcgT2JqZWN0WzBdLCAwKTsKLQotICAgIC8vIFRoZSBhcnJheSB0byBob2xkIGFsbCBkYXRhCi0gICAgcHJpdmF0ZSBmaW5hbCBPYmplY3RbXSBmQXJyYXk7Ci0KLSAgICAvLyBOdW1iZXIgb2YgZWxlbWVudHMgaW4gdGhpcyBsaXN0Ci0gICAgcHJpdmF0ZSBmaW5hbCBpbnQgZkxlbmd0aDsKLQotICAgIHB1YmxpYyBPYmplY3RMaXN0SW1wbChPYmplY3RbXSBhcnJheSwgaW50IGxlbmd0aCkgewotICAgICAgICBmQXJyYXkgPSBhcnJheTsKLSAgICAgICAgZkxlbmd0aCA9IGxlbmd0aDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldExlbmd0aCgpIHsKLSAgICAgICAgcmV0dXJuIGZMZW5ndGg7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gY29udGFpbnMoT2JqZWN0IGl0ZW0pIHsKLSAgICAgICAgaWYgKGl0ZW0gPT0gbnVsbCkgewotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmTGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgICAgICBpZiAoZkFycmF5W2ldID09IG51bGwpCi0gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmTGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgICAgICBpZiAoaXRlbS5lcXVhbHMoZkFycmF5W2ldKSkKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIHB1YmxpYyBPYmplY3QgaXRlbShpbnQgaW5kZXgpIHsKLSAgICAgICAgaWYgKGluZGV4IDwgMCB8fCBpbmRleCA+PSBmTGVuZ3RoKSB7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZkFycmF5W2luZGV4XTsKLSAgICB9Ci0KLSAgICAvKgotICAgICAqIExpc3QgbWV0aG9kcwotICAgICAqLwotICAgIHB1YmxpYyBPYmplY3QgZ2V0KGludCBpbmRleCkgewotICAgICAgICBpZiAoaW5kZXggPj0gMCAmJiBpbmRleCA8IGZMZW5ndGgpIHsKLSAgICAgICAgICAgIHJldHVybiBmQXJyYXlbaW5kZXhdOwotICAgICAgICB9Ci0gICAgICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCJJbmRleDogIiArIGluZGV4KTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IHNpemUoKSB7Ci0gICAgICAgIHJldHVybiBnZXRMZW5ndGgoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgT2JqZWN0W10gdG9BcnJheSgpIHsKLSAgICAgICAgT2JqZWN0W10gYSA9IG5ldyBPYmplY3RbZkxlbmd0aF07Ci0gICAgICAgIHRvQXJyYXkwKGEpOwotICAgICAgICByZXR1cm4gYTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgT2JqZWN0W10gdG9BcnJheShPYmplY3RbXSBhKSB7Ci0gICAgICAgIGlmIChhLmxlbmd0aCA8IGZMZW5ndGgpIHsKLSAgICAgICAgICAgIENsYXNzIGFycmF5Q2xhc3MgPSBhLmdldENsYXNzKCk7Ci0gICAgICAgICAgICBDbGFzcyBjb21wb25lbnRUeXBlID0gYXJyYXlDbGFzcy5nZXRDb21wb25lbnRUeXBlKCk7Ci0gICAgICAgICAgICBhID0gKE9iamVjdFtdKSBBcnJheS5uZXdJbnN0YW5jZShjb21wb25lbnRUeXBlLCBmTGVuZ3RoKTsKLSAgICAgICAgfQotICAgICAgICB0b0FycmF5MChhKTsKLSAgICAgICAgaWYgKGEubGVuZ3RoID4gZkxlbmd0aCkgewotICAgICAgICAgICAgYVtmTGVuZ3RoXSA9IG51bGw7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGE7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIHRvQXJyYXkwKE9iamVjdFtdIGEpIHsKLSAgICAgICAgaWYgKGZMZW5ndGggPiAwKSB7Ci0gICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGZBcnJheSwgMCwgYSwgMCwgZkxlbmd0aCk7Ci0gICAgICAgIH0KLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL3V0aWwvU2hvcnRMaXN0SW1wbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy91dGlsL1Nob3J0TGlzdEltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOWEzYmEzOC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL3V0aWwvU2hvcnRMaXN0SW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTI0ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDIsMjAwMy0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMudXRpbDsKLQotaW1wb3J0IGphdmEudXRpbC5BYnN0cmFjdExpc3Q7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlNob3J0TGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTRXhjZXB0aW9uOwotCi0vKioKLSAqIENvbnRhaW50cyBhIGxpc3Qgb2YgT2JqZWN0J3MuCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgU2FuZHkgR2FvLCBJQk0KLSAqCi0gKiBAdmVyc2lvbiAkSWQ6IFNob3J0TGlzdEltcGwuamF2YSx2IDEuNyAyMDEwLTExLTAxIDA0OjQwOjA2IGpvZWh3IEV4cCAkCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBTaG9ydExpc3RJbXBsIGV4dGVuZHMgQWJzdHJhY3RMaXN0IGltcGxlbWVudHMgU2hvcnRMaXN0IHsKLQotICAgIC8qKgotICAgICAqIEFuIGltbXV0YWJsZSBlbXB0eSBsaXN0LgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU2hvcnRMaXN0SW1wbCBFTVBUWV9MSVNUID0gbmV3IFNob3J0TGlzdEltcGwobmV3IHNob3J0WzBdLCAwKTsKLQotICAgIC8vIFRoZSBhcnJheSB0byBob2xkIGFsbCBkYXRhCi0gICAgcHJpdmF0ZSBmaW5hbCBzaG9ydFtdIGZBcnJheTsKLSAgICAvLyBOdW1iZXIgb2YgZWxlbWVudHMgaW4gdGhpcyBsaXN0Ci0gICAgcHJpdmF0ZSBmaW5hbCBpbnQgZkxlbmd0aDsKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdCBhbiBYU09iamVjdExpc3QgaW1wbGVtZW50YXRpb24KLSAgICAgKgotICAgICAqIEBwYXJhbSBhcnJheSAgICAgdGhlIGRhdGEgYXJyYXkKLSAgICAgKiBAcGFyYW0gbGVuZ3RoICAgIHRoZSBudW1iZXIgb2YgZWxlbWVudHMKLSAgICAgKi8KLSAgICBwdWJsaWMgU2hvcnRMaXN0SW1wbChzaG9ydFtdIGFycmF5LCBpbnQgbGVuZ3RoKSB7Ci0gICAgICAgIGZBcnJheSA9IGFycmF5OwotICAgICAgICBmTGVuZ3RoID0gbGVuZ3RoOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoZSBudW1iZXIgb2YgPGNvZGU+T2JqZWN0czwvY29kZT4gaW4gdGhlIGxpc3QuIFRoZSByYW5nZSBvZiB2YWxpZAotICAgICAqIGNoaWxkIG5vZGUgaW5kaWNlcyBpcyAwIHRvIDxjb2RlPmxlbmd0aC0xPC9jb2RlPiBpbmNsdXNpdmUuCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRMZW5ndGgoKSB7Ci0gICAgICAgIHJldHVybiBmTGVuZ3RoOwotICAgIH0KLQotICAgIC8qKgotICAgICAqICBDaGVja3MgaWYgdGhlIDxjb2RlPnVuc2lnbmVkIHNob3J0PC9jb2RlPiA8Y29kZT5pdGVtPC9jb2RlPiBpcyBhCi0gICAgICogbWVtYmVyIG9mIHRoaXMgbGlzdC4KLSAgICAgKiBAcGFyYW0gaXRlbSAgPGNvZGU+dW5zaWduZWQgc2hvcnQ8L2NvZGU+IHdob3NlIHByZXNlbmNlIGluIHRoaXMgbGlzdAotICAgICAqICAgaXMgdG8gYmUgdGVzdGVkLgotICAgICAqIEByZXR1cm4gIFRydWUgaWYgdGhpcyBsaXN0IGNvbnRhaW5zIHRoZSA8Y29kZT51bnNpZ25lZCBzaG9ydDwvY29kZT4KLSAgICAgKiAgIDxjb2RlPml0ZW08L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKHNob3J0IGl0ZW0pIHsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmTGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgIGlmIChmQXJyYXlbaV0gPT0gaXRlbSkgewotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgc2hvcnQgaXRlbShpbnQgaW5kZXgpIHRocm93cyBYU0V4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChpbmRleCA8IDAgfHwgaW5kZXggPj0gZkxlbmd0aCkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFhTRXhjZXB0aW9uKFhTRXhjZXB0aW9uLklOREVYX1NJWkVfRVJSLCBudWxsKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZkFycmF5W2luZGV4XTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaikgewotICAgICAgICBpZiAob2JqID09IG51bGwgfHwgIShvYmogaW5zdGFuY2VvZiBTaG9ydExpc3QpKSB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLSAgICAgICAgU2hvcnRMaXN0IHJocyA9IChTaG9ydExpc3Qpb2JqOwotCi0gICAgICAgIGlmIChmTGVuZ3RoICE9IHJocy5nZXRMZW5ndGgoKSkgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0gICAgICAgIGZvciAoaW50IGkgPSAwO2kgPCBmTGVuZ3RoOyArK2kpIHsKLSAgICAgICAgICAgIGlmIChmQXJyYXlbaV0gIT0gcmhzLml0ZW0oaSkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotCi0gICAgLyoKLSAgICAgKiBMaXN0IG1ldGhvZHMKLSAgICAgKi8KLQotICAgIHB1YmxpYyBPYmplY3QgZ2V0KGludCBpbmRleCkgewotICAgICAgICBpZiAoaW5kZXggPj0gMCAmJiBpbmRleCA8IGZMZW5ndGgpIHsKLSAgICAgICAgICAgIHJldHVybiBuZXcgU2hvcnQoZkFycmF5W2luZGV4XSk7Ci0gICAgICAgIH0KLSAgICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oIkluZGV4OiAiICsgaW5kZXgpOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKLSAgICAgICAgcmV0dXJuIGdldExlbmd0aCgpOwotICAgIH0KLQotfSAvLyBjbGFzcyBTaG9ydExpc3RJbXBsCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL3V0aWwvU2ltcGxlTG9jYXRvci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy91dGlsL1NpbXBsZUxvY2F0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYTM4NDA1ZS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL3V0aWwvU2ltcGxlTG9jYXRvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTQ3ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDIsIDIwMDMsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLnV0aWw7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxMb2NhdG9yOwotCi0vKioKLSAqIEFuIFhNTExvY2F0b3IgaW1wbGVtZW50YXRpb24gdXNlZCBmb3Igc2NoZW1hIGVycm9yIHJlcG9ydGluZy4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBTYW5keSBHYW8sIElCTQotICovCi1wdWJsaWMgY2xhc3MgU2ltcGxlTG9jYXRvciBpbXBsZW1lbnRzIFhNTExvY2F0b3IgewotCi0gICAgU3RyaW5nIGxzaWQsIGVzaWQ7Ci0gICAgaW50IGxpbmUsIGNvbHVtbjsKLSAgICBpbnQgY2hhck9mZnNldDsKLQotICAgIHB1YmxpYyBTaW1wbGVMb2NhdG9yKCkgewotICAgIH0KLQotICAgIHB1YmxpYyBTaW1wbGVMb2NhdG9yKFN0cmluZyBsc2lkLCBTdHJpbmcgZXNpZCwgaW50IGxpbmUsIGludCBjb2x1bW4pIHsKLSAgICAgICAgdGhpcyhsc2lkLCBlc2lkLCBsaW5lLCBjb2x1bW4sIC0xKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRWYWx1ZXMoU3RyaW5nIGxzaWQsIFN0cmluZyBlc2lkLCBpbnQgbGluZSwgaW50IGNvbHVtbikgewotICAgICAgICBzZXRWYWx1ZXMobHNpZCwgZXNpZCwgbGluZSwgY29sdW1uLCAtMSk7Ci0gICAgfQotCi0gICAgcHVibGljIFNpbXBsZUxvY2F0b3IoU3RyaW5nIGxzaWQsIFN0cmluZyBlc2lkLCBpbnQgbGluZSwgaW50IGNvbHVtbiwgaW50IG9mZnNldCkgewotICAgICAgICB0aGlzLmxpbmUgPSBsaW5lOwotICAgICAgICB0aGlzLmNvbHVtbiA9IGNvbHVtbjsKLSAgICAgICAgdGhpcy5sc2lkID0gbHNpZDsKLSAgICAgICAgdGhpcy5lc2lkID0gZXNpZDsKLSAgICAgICAgY2hhck9mZnNldCA9IG9mZnNldDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRWYWx1ZXMoU3RyaW5nIGxzaWQsIFN0cmluZyBlc2lkLCBpbnQgbGluZSwgaW50IGNvbHVtbiwgaW50IG9mZnNldCkgewotICAgICAgICB0aGlzLmxpbmUgPSBsaW5lOwotICAgICAgICB0aGlzLmNvbHVtbiA9IGNvbHVtbjsKLSAgICAgICAgdGhpcy5sc2lkID0gbHNpZDsKLSAgICAgICAgdGhpcy5lc2lkID0gZXNpZDsKLSAgICAgICAgY2hhck9mZnNldCA9IG9mZnNldDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldExpbmVOdW1iZXIoKSB7Ci0gICAgICAgIHJldHVybiBsaW5lOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgZ2V0Q29sdW1uTnVtYmVyKCkgewotICAgICAgICByZXR1cm4gY29sdW1uOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgZ2V0Q2hhcmFjdGVyT2Zmc2V0KCkgewotICAgICAgICByZXR1cm4gY2hhck9mZnNldDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldFB1YmxpY0lkKCkgewotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldEV4cGFuZGVkU3lzdGVtSWQoKSB7Ci0gICAgICAgIHJldHVybiBlc2lkOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TGl0ZXJhbFN5c3RlbUlkKCkgewotICAgICAgICByZXR1cm4gbHNpZDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldEJhc2VTeXN0ZW1JZCgpIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotICAgIC8qKgotICAgICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MTG9jYXRvciNzZXRDb2x1bW5OdW1iZXIoaW50KQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldENvbHVtbk51bWJlcihpbnQgY29sKSB7Ci0gICAgICAgIHRoaXMuY29sdW1uID0gY29sOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MTG9jYXRvciNzZXRMaW5lTnVtYmVyKGludCkKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRMaW5lTnVtYmVyKGludCBsaW5lKSB7Ci0gICAgICAgIHRoaXMubGluZSA9IGxpbmU7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0Q2hhcmFjdGVyT2Zmc2V0KGludCBvZmZzZXQpIHsKLSAgICAgICAgY2hhck9mZnNldCA9IG9mZnNldDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTFJlc291cmNlSWRlbnRpZmllciNzZXRCYXNlU3lzdGVtSWQoU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEJhc2VTeXN0ZW1JZChTdHJpbmcgc3lzdGVtSWQpIHt9Ci0KLSAgICAvKioKLSAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTFJlc291cmNlSWRlbnRpZmllciNzZXRFeHBhbmRlZFN5c3RlbUlkKFN0cmluZykKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRFeHBhbmRlZFN5c3RlbUlkKFN0cmluZyBzeXN0ZW1JZCkgewotICAgICAgICBlc2lkID0gc3lzdGVtSWQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxSZXNvdXJjZUlkZW50aWZpZXIjc2V0TGl0ZXJhbFN5c3RlbUlkKFN0cmluZykKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRMaXRlcmFsU3lzdGVtSWQoU3RyaW5nIHN5c3RlbUlkKSB7Ci0gICAgICAgIGxzaWQgPSBzeXN0ZW1JZDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTFJlc291cmNlSWRlbnRpZmllciNzZXRQdWJsaWNJZChTdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0UHVibGljSWQoU3RyaW5nIHB1YmxpY0lkKSB7fQotCi0gICAgLyoqIFJldHVybnMgdGhlIGVuY29kaW5nIG9mIHRoZSBjdXJyZW50IGVudGl0eS4KLSAgICAgKiBTaW5jZSB0aGVzZSBsb2NhdG9ycyBhcmUgdXNlZCBpbiB0aGUgY29uc3RydWN0aW9uIG9mCi0gICAgICogWE1MUGFyc2VFeGNlcHRpb25zLCB3aGljaCBrbm93IG5vdGhpbmcgYWJvdXQgZW5jb2RpbmdzLCB0aGVyZSBpcwotICAgICAqIG5vIHBvaW50IGluIGhhdmluZyB0aGlzIG9iamVjdCBkZWFsIGludGVsbGlnZW50bHkKLSAgICAgKiB3aXRoIGVuY29kaW5nIGluZm9ybWF0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0RW5jb2RpbmcoKSB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0WE1MVmVyc2lvbigpIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy91dGlsL1N0cmluZ0xpc3RJbXBsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL3V0aWwvU3RyaW5nTGlzdEltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNWYyMjYyOC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL3V0aWwvU3RyaW5nTGlzdEltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE2NiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAyLDIwMDMtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLnV0aWw7Ci0KLWltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5BcnJheTsKLWltcG9ydCBqYXZhLnV0aWwuQWJzdHJhY3RMaXN0OwotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlN0cmluZ0xpc3Q7Ci0KLS8qKgotICogQ29udGFpbnRzIGEgbGlzdCBvZiBPYmplY3Qncy4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBTYW5keSBHYW8sIElCTQotICoKLSAqIEB2ZXJzaW9uICRJZDogU3RyaW5nTGlzdEltcGwuamF2YSx2IDEuNyAyMDEwLTExLTAxIDA0OjQwOjA2IGpvZWh3IEV4cCAkCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBTdHJpbmdMaXN0SW1wbCBleHRlbmRzIEFic3RyYWN0TGlzdCBpbXBsZW1lbnRzIFN0cmluZ0xpc3QgewotCi0gICAgLyoqCi0gICAgICogQW4gaW1tdXRhYmxlIGVtcHR5IGxpc3QuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmdMaXN0SW1wbCBFTVBUWV9MSVNUID0gbmV3IFN0cmluZ0xpc3RJbXBsKG5ldyBTdHJpbmdbMF0sIDApOwotCi0gICAgLy8gVGhlIGFycmF5IHRvIGhvbGQgYWxsIGRhdGEKLSAgICBwcml2YXRlIGZpbmFsIFN0cmluZ1tdIGZBcnJheTsKLSAgICAvLyBOdW1iZXIgb2YgZWxlbWVudHMgaW4gdGhpcyBsaXN0Ci0gICAgcHJpdmF0ZSBmaW5hbCBpbnQgZkxlbmd0aDsKLQotICAgIC8vIFJFVklTSVQ6IHRoaXMgaXMgdGVtcCBzb2x1dGlvbi4gSW4gZ2VuZXJhbCB3ZSBuZWVkIHRvIHVzZSB0aGlzIGNsYXNzCi0gICAgLy8gICAgICAgICAgaW5zdGVhZCBvZiB0aGUgVmVjdG9yLgotICAgIHByaXZhdGUgZmluYWwgVmVjdG9yIGZWZWN0b3I7Ci0KLSAgICBwdWJsaWMgU3RyaW5nTGlzdEltcGwoVmVjdG9yIHYpIHsKLSAgICAgICAgZlZlY3RvciA9IHY7Ci0gICAgICAgIGZMZW5ndGggPSAodiA9PSBudWxsKSA/IDAgOiB2LnNpemUoKTsKLSAgICAgICAgZkFycmF5ID0gbnVsbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3QgYW4gWFNPYmplY3RMaXN0IGltcGxlbWVudGF0aW9uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYXJyYXkgICAgIHRoZSBkYXRhIGFycmF5Ci0gICAgICogQHBhcmFtIGxlbmd0aCAgICB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZ0xpc3RJbXBsKFN0cmluZ1tdIGFycmF5LCBpbnQgbGVuZ3RoKSB7Ci0gICAgICAgIGZBcnJheSA9IGFycmF5OwotICAgICAgICBmTGVuZ3RoID0gbGVuZ3RoOwotICAgICAgICBmVmVjdG9yID0gbnVsbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgbnVtYmVyIG9mIDxjb2RlPk9iamVjdHM8L2NvZGU+IGluIHRoZSBsaXN0LiBUaGUgcmFuZ2Ugb2YgdmFsaWQKLSAgICAgKiBjaGlsZCBub2RlIGluZGljZXMgaXMgMCB0byA8Y29kZT5sZW5ndGgtMTwvY29kZT4gaW5jbHVzaXZlLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0TGVuZ3RoKCkgewotICAgICAgICByZXR1cm4gZkxlbmd0aDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiAgQ2hlY2tzIGlmIHRoZSA8Y29kZT5HZW5lcmljU3RyaW5nPC9jb2RlPiA8Y29kZT5pdGVtPC9jb2RlPiBpcyBhIG1lbWJlcgotICAgICAqIG9mIHRoaXMgbGlzdC4KLSAgICAgKiBAcGFyYW0gaXRlbSAgPGNvZGU+R2VuZXJpY1N0cmluZzwvY29kZT4gd2hvc2UgcHJlc2VuY2UgaW4gdGhpcyBsaXN0IGlzCi0gICAgICogICB0byBiZSB0ZXN0ZWQuCi0gICAgICogQHJldHVybiAgVHJ1ZSBpZiB0aGlzIGxpc3QgY29udGFpbnMgdGhlIDxjb2RlPkdlbmVyaWNTdHJpbmc8L2NvZGU+Ci0gICAgICogICA8Y29kZT5pdGVtPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBjb250YWlucyhTdHJpbmcgaXRlbSkgewotICAgICAgICBpZiAoZlZlY3RvciAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gZlZlY3Rvci5jb250YWlucyhpdGVtKTsKLSAgICAgICAgfQotICAgICAgICBpZiAoaXRlbSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZMZW5ndGg7IGkrKykgewotICAgICAgICAgICAgICAgIGlmIChmQXJyYXlbaV0gPT0gbnVsbCkKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZMZW5ndGg7IGkrKykgewotICAgICAgICAgICAgICAgIGlmIChpdGVtLmVxdWFscyhmQXJyYXlbaV0pKQotICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBpdGVtKGludCBpbmRleCkgewotICAgICAgICBpZiAoaW5kZXggPCAwIHx8IGluZGV4ID49IGZMZW5ndGgpIHsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgICAgIGlmIChmVmVjdG9yICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiAoU3RyaW5nKWZWZWN0b3IuZWxlbWVudEF0KGluZGV4KTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZkFycmF5W2luZGV4XTsKLSAgICB9Ci0KLSAgICAvKgotICAgICAqIExpc3QgbWV0aG9kcwotICAgICAqLwotCi0gICAgcHVibGljIE9iamVjdCBnZXQoaW50IGluZGV4KSB7Ci0gICAgICAgIGlmIChpbmRleCA+PSAwICYmIGluZGV4IDwgZkxlbmd0aCkgewotICAgICAgICAgICAgaWYgKGZWZWN0b3IgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJldHVybiBmVmVjdG9yLmVsZW1lbnRBdChpbmRleCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gZkFycmF5W2luZGV4XTsKLSAgICAgICAgfQotICAgICAgICB0aHJvdyBuZXcgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigiSW5kZXg6ICIgKyBpbmRleCk7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBzaXplKCkgewotICAgICAgICByZXR1cm4gZ2V0TGVuZ3RoKCk7Ci0gICAgfQotCi0gICAgcHVibGljIE9iamVjdFtdIHRvQXJyYXkoKSB7Ci0gICAgICAgIGlmIChmVmVjdG9yICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBmVmVjdG9yLnRvQXJyYXkoKTsKLSAgICAgICAgfQotICAgICAgICBPYmplY3RbXSBhID0gbmV3IE9iamVjdFtmTGVuZ3RoXTsKLSAgICAgICAgdG9BcnJheTAoYSk7Ci0gICAgICAgIHJldHVybiBhOwotICAgIH0KLQotICAgIHB1YmxpYyBPYmplY3RbXSB0b0FycmF5KE9iamVjdFtdIGEpIHsKLSAgICAgICAgaWYgKGZWZWN0b3IgIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIGZWZWN0b3IudG9BcnJheShhKTsKLSAgICAgICAgfQotICAgICAgICBpZiAoYS5sZW5ndGggPCBmTGVuZ3RoKSB7Ci0gICAgICAgICAgICBDbGFzcyBhcnJheUNsYXNzID0gYS5nZXRDbGFzcygpOwotICAgICAgICAgICAgQ2xhc3MgY29tcG9uZW50VHlwZSA9IGFycmF5Q2xhc3MuZ2V0Q29tcG9uZW50VHlwZSgpOwotICAgICAgICAgICAgYSA9IChPYmplY3RbXSkgQXJyYXkubmV3SW5zdGFuY2UoY29tcG9uZW50VHlwZSwgZkxlbmd0aCk7Ci0gICAgICAgIH0KLSAgICAgICAgdG9BcnJheTAoYSk7Ci0gICAgICAgIGlmIChhLmxlbmd0aCA+IGZMZW5ndGgpIHsKLSAgICAgICAgICAgIGFbZkxlbmd0aF0gPSBudWxsOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBhOwotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCB0b0FycmF5MChPYmplY3RbXSBhKSB7Ci0gICAgICAgIGlmIChmTGVuZ3RoID4gMCkgewotICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShmQXJyYXksIDAsIGEsIDAsIGZMZW5ndGgpOwotICAgICAgICB9Ci0gICAgfQotCi19IC8vIGNsYXNzIFN0cmluZ0xpc3RJbXBsCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL3V0aWwvWEludC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy91dGlsL1hJbnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNjhhYTYzYy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL3V0aWwvWEludC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTIgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMSwgMjAwMiwyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMudXRpbDsKLQotLyoqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBIZW5yeSBab25nYXJvLCBJQk0KLSAqLwotCi1wdWJsaWMgZmluYWwgY2xhc3MgWEludCB7Ci0KLSAgICBwcml2YXRlIGludCBmVmFsdWU7Ci0KLSAgICBYSW50KGludCB2YWx1ZSkgewotICAgICAgICBmVmFsdWUgPSB2YWx1ZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgZmluYWwgaW50IGludFZhbHVlKCkgewotICAgICAgICByZXR1cm4gZlZhbHVlOwotICAgIH0KLQotICAgIHB1YmxpYyBmaW5hbCBzaG9ydCBzaG9ydFZhbHVlKCkgewotICAgICAgICByZXR1cm4gKHNob3J0KWZWYWx1ZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBlcXVhbHMoWEludCBjb21wYXJlVmFsKSB7Ci0gICAgICAgIHJldHVybiAodGhpcy5mVmFsdWUgPT0gY29tcGFyZVZhbC5mVmFsdWUpOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0gICAgICAgIHJldHVybiBJbnRlZ2VyLnRvU3RyaW5nKGZWYWx1ZSk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy91dGlsL1hJbnRQb29sLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL3V0aWwvWEludFBvb2wuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggODIxZjM5OS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL3V0aWwvWEludFBvb2wuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQzICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEsIDIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLnV0aWw7Ci0KLS8qKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgSGVucnkgWm9uZ2FybywgSUJNCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBYSW50UG9vbCB7Ci0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgc2hvcnQgUE9PTF9TSVpFID0gMTA7Ci0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgWEludFtdIGZYSW50UG9vbCA9IG5ldyBYSW50W1BPT0xfU0laRV07Ci0KLSAgICBzdGF0aWMgewotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IFBPT0xfU0laRTsgaSsrKQotICAgICAgICAgICAgZlhJbnRQb29sW2ldID0gbmV3IFhJbnQoaSk7Ci0gICAgfQotCi0gICAgcHVibGljIGZpbmFsIFhJbnQgZ2V0WEludChpbnQgdmFsdWUpIHsKLSAgICAgICAgaWYgKHZhbHVlID49IDAgJiYgdmFsdWUgPCBmWEludFBvb2wubGVuZ3RoKQotICAgICAgICAgICAgcmV0dXJuIGZYSW50UG9vbFt2YWx1ZV07Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICAgIHJldHVybiBuZXcgWEludCh2YWx1ZSk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy91dGlsL1hTR3JhbW1hclBvb2wuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvdXRpbC9YU0dyYW1tYXJQb29sLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDNmODNlODMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy91dGlsL1hTR3JhbW1hclBvb2wuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDc0ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDMsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLnV0aWw7Ci0KLWltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLkNvbnN0YW50czsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMuU2NoZW1hR3JhbW1hcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMuWFNNb2RlbEltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlhNTEdyYW1tYXJQb29sSW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5ncmFtbWFycy5YTUxHcmFtbWFyRGVzY3JpcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU01vZGVsOwotCi0KLS8qKgotICogQWRkIGEgbWV0aG9kIHRoYXQgcmV0dXJuIGFuIDxjb2RlPlhTTW9kZWw8L2NvZGU+IHRoYXQgcmVwcmVzZW50cyBjb21wb25lbnRzIGluCi0gKiB0aGUgc2NoZW1hIGdyYW1tYXJzIGluIHRoaXMgcG9vbCBpbXBsZW1lbnRhdGlvbi4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQHZlcnNpb24gJElkOiBYU0dyYW1tYXJQb29sLmphdmEsdiAxLjcgMjAxMC0xMS0wMSAwNDo0MDowNiBqb2VodyBFeHAgJAotICovCi1wdWJsaWMgY2xhc3MgWFNHcmFtbWFyUG9vbCBleHRlbmRzIFhNTEdyYW1tYXJQb29sSW1wbCB7Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gYW4gPGNvZGU+WFNNb2RlbDwvY29kZT4gdGhhdCByZXByZXNlbnRzIGNvbXBvbmVudHMgaW4KLSAgICAgKiB0aGUgc2NoZW1hIGdyYW1tYXJzIGluIHRoaXMgcG9vbCBpbXBsZW1lbnRhdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gIGFuIDxjb2RlPlhTTW9kZWw8L2NvZGU+IHJlcHJlc2VudGluZyB0aGlzIHNjaGVtYSBncmFtbWFyCi0gICAgICovCi0gICAgcHVibGljIFhTTW9kZWwgdG9YU01vZGVsKCkgewotICAgICAgICByZXR1cm4gdG9YU01vZGVsKENvbnN0YW50cy5TQ0hFTUFfVkVSU0lPTl8xXzApOwotICAgIH0KLQotICAgIHB1YmxpYyBYU01vZGVsIHRvWFNNb2RlbChzaG9ydCBzY2hlbWFWZXJzaW9uKSB7Ci0gICAgICAgIEFycmF5TGlzdCBsaXN0ID0gbmV3IEFycmF5TGlzdCgpOwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZHcmFtbWFycy5sZW5ndGg7IGkrKykgewotICAgICAgICAgICAgZm9yIChFbnRyeSBlbnRyeSA9IGZHcmFtbWFyc1tpXSA7IGVudHJ5ICE9IG51bGwgOyBlbnRyeSA9IGVudHJ5Lm5leHQpIHsKLSAgICAgICAgICAgICAgICBpZiAoZW50cnkuZGVzYy5nZXRHcmFtbWFyVHlwZSgpLmVxdWFscyhYTUxHcmFtbWFyRGVzY3JpcHRpb24uWE1MX1NDSEVNQSkpIHsKLSAgICAgICAgICAgICAgICAgICAgbGlzdC5hZGQoZW50cnkuZ3JhbW1hcik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGludCBzaXplID0gbGlzdC5zaXplKCk7Ci0gICAgICAgIGlmIChzaXplID09IDApIHsKLSAgICAgICAgICAgIHJldHVybiB0b1hTTW9kZWwobmV3IFNjaGVtYUdyYW1tYXJbMF0sIHNjaGVtYVZlcnNpb24pOwotICAgICAgICB9Ci0gICAgICAgIFNjaGVtYUdyYW1tYXJbXSBncyA9IChTY2hlbWFHcmFtbWFyW10pbGlzdC50b0FycmF5KG5ldyBTY2hlbWFHcmFtbWFyW3NpemVdKTsKLSAgICAgICAgcmV0dXJuIHRvWFNNb2RlbChncywgc2NoZW1hVmVyc2lvbik7Ci0gICAgfQotCi0gICAgcHJvdGVjdGVkIFhTTW9kZWwgdG9YU01vZGVsKFNjaGVtYUdyYW1tYXJbXSBncmFtbWFycywgc2hvcnQgc2NoZW1hVmVyc2lvbikgewotICAgICAgICByZXR1cm4gbmV3IFhTTW9kZWxJbXBsKGdyYW1tYXJzLCBzY2hlbWFWZXJzaW9uKTsKLSAgICB9Ci0KLX0gLy8gY2xhc3MgWFNHcmFtbWFyUG9vbApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy91dGlsL1hTSW5wdXRTb3VyY2UuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2ltcGwveHMvdXRpbC9YU0lucHV0U291cmNlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDRjYTExNGIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy91dGlsL1hTSW5wdXRTb3VyY2UuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDY2ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCi0gKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKLSAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KLSAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCi0gKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAotICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLnV0aWw7Ci0KLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5TY2hlbWFHcmFtbWFyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxJbnB1dFNvdXJjZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTT2JqZWN0OwotCi0vKioKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAdmVyc2lvbiAkSWQ6IFhTSW5wdXRTb3VyY2UuamF2YSx2IDEuMiAyMDEwLTEwLTI2IDIzOjAxOjA1IGpvZWh3IEV4cCAkCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBYU0lucHV0U291cmNlIGV4dGVuZHMgWE1MSW5wdXRTb3VyY2UgewotCi0gICAgcHJpdmF0ZSBTY2hlbWFHcmFtbWFyW10gZkdyYW1tYXJzOwotICAgIHByaXZhdGUgWFNPYmplY3RbXSBmQ29tcG9uZW50czsKLQotICAgIHB1YmxpYyBYU0lucHV0U291cmNlKFNjaGVtYUdyYW1tYXJbXSBncmFtbWFycykgewotICAgICAgICBzdXBlcihudWxsLCBudWxsLCBudWxsKTsKLSAgICAgICAgZkdyYW1tYXJzID0gZ3JhbW1hcnM7Ci0gICAgICAgIGZDb21wb25lbnRzID0gbnVsbDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgWFNJbnB1dFNvdXJjZShYU09iamVjdFtdIGNvbXBvbmVudCkgewotICAgICAgICBzdXBlcihudWxsLCBudWxsLCBudWxsKTsKLSAgICAgICAgZkdyYW1tYXJzID0gbnVsbDsKLSAgICAgICAgZkNvbXBvbmVudHMgPSBjb21wb25lbnQ7Ci0gICAgfQotCi0gICAgcHVibGljIFNjaGVtYUdyYW1tYXJbXSBnZXRHcmFtbWFycygpIHsKLSAgICAgICAgcmV0dXJuIGZHcmFtbWFyczsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRHcmFtbWFycyhTY2hlbWFHcmFtbWFyW10gZ3JhbW1hcnMpIHsKLSAgICAgICAgZkdyYW1tYXJzID0gZ3JhbW1hcnM7Ci0gICAgfQotCi0gICAgcHVibGljIFhTT2JqZWN0W10gZ2V0Q29tcG9uZW50cygpIHsKLSAgICAgICAgcmV0dXJuIGZDb21wb25lbnRzOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldENvbXBvbmVudHMoWFNPYmplY3RbXSBjb21wb25lbnRzKSB7Ci0gICAgICAgIGZDb21wb25lbnRzID0gY29tcG9uZW50czsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL3V0aWwvWFNOYW1lZE1hcDRUeXBlcy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy91dGlsL1hTTmFtZWRNYXA0VHlwZXMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNjNmNmY0Ny4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL3V0aWwvWFNOYW1lZE1hcDRUeXBlcy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTQ0ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLnV0aWw7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuU3ltYm9sSGFzaDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTT2JqZWN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNUeXBlRGVmaW5pdGlvbjsKLQotCi0vKioKLSAqIENvbnRhaW50cyB0aGUgbWFwIGJldHdlZW4gcW5hbWVzIGFuZCBYU09iamVjdCdzLgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKiBAYXV0aG9yIFNhbmR5IEdhbywgSUJNCi0gKgotICogQHZlcnNpb24gJElkOiBYU05hbWVkTWFwNFR5cGVzLmphdmEsdiAxLjcgMjAxMC0xMS0wMSAwNDo0MDowNiBqb2VodyBFeHAgJAotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgWFNOYW1lZE1hcDRUeXBlcyBleHRlbmRzIFhTTmFtZWRNYXBJbXBsIHsKLQotICAgIC8vIHRoZSB0eXBlIG9mIGNvbXBvbmVudCBzdG9yZWQgaGVyZTogY29tcGxleCBvciBzaW1wbGUgdHlwZQotICAgIHByaXZhdGUgZmluYWwgc2hvcnQgZlR5cGU7Ci0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3QgYW4gWFNOYW1lZE1hcCBpbXBsZW1lbnRhdGlvbiBmb3Igb25lIG5hbWVzcGFjZQotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWVzcGFjZSB0aGUgbmFtZXNwYWNlIHRvIHdoaWNoIHRoZSBjb21wb25lbnRzIGJlbG9uZwotICAgICAqIEBwYXJhbSBtYXAgICAgICAgdGhlIG1hcCBmcm9tIGxvY2FsIG5hbWVzIHRvIGNvbXBvbmVudHMKLSAgICAgKiBAcGFyYW0gdHlwZSAgICAgIHRoZSB0eXBlIG9mIGNvbXBvbmVudHMKLSAgICAgKi8KLSAgICBwdWJsaWMgWFNOYW1lZE1hcDRUeXBlcyhTdHJpbmcgbmFtZXNwYWNlLCBTeW1ib2xIYXNoIG1hcCwgc2hvcnQgdHlwZSkgewotICAgICAgICBzdXBlcihuYW1lc3BhY2UsIG1hcCk7Ci0gICAgICAgIGZUeXBlID0gdHlwZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3QgYW4gWFNOYW1lZE1hcCBpbXBsZW1lbnRhdGlvbiBmb3IgYSBsaXN0IG9mIG5hbWVzcGFjZXMKLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lc3BhY2VzIHRoZSBuYW1lc3BhY2VzIHRvIHdoaWNoIHRoZSBjb21wb25lbnRzIGJlbG9uZwotICAgICAqIEBwYXJhbSBtYXBzICAgICAgIHRoZSBtYXBzIGZyb20gbG9jYWwgbmFtZXMgdG8gY29tcG9uZW50cwotICAgICAqIEBwYXJhbSBudW0gICAgICAgIHRoZSBudW1iZXIgb2YgbmFtZXNwYWNlcwotICAgICAqIEBwYXJhbSB0eXBlICAgICAgdGhlIHR5cGUgb2YgY29tcG9uZW50cwotICAgICAqLwotICAgIHB1YmxpYyBYU05hbWVkTWFwNFR5cGVzKFN0cmluZ1tdIG5hbWVzcGFjZXMsIFN5bWJvbEhhc2hbXSBtYXBzLCBpbnQgbnVtLCBzaG9ydCB0eXBlKSB7Ci0gICAgICAgIHN1cGVyKG5hbWVzcGFjZXMsIG1hcHMsIG51bSk7Ci0gICAgICAgIGZUeXBlID0gdHlwZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgbnVtYmVyIG9mIDxjb2RlPlhTT2JqZWN0czwvY29kZT4gaW4gdGhlIDxjb2RlPlhTT2JqZWN0TGlzdDwvY29kZT4uIFRoZQotICAgICAqIHJhbmdlIG9mIHZhbGlkIGNoaWxkIG5vZGUgaW5kaWNlcyBpcyAwIHRvIDxjb2RlPmxlbmd0aC0xPC9jb2RlPgotICAgICAqIGluY2x1c2l2ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3luY2hyb25pemVkIGludCBnZXRMZW5ndGgoKSB7Ci0gICAgICAgIGlmIChmTGVuZ3RoID09IC0xKSB7Ci0gICAgICAgICAgICAvLyBmaXJzdCBnZXQgdGhlIG51bWJlciBvZiBjb21wb25lbnRzIGZvciBhbGwgdHlwZXMKLSAgICAgICAgICAgIGludCBsZW5ndGggPSAwOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmTlNOdW07IGkrKykgewotICAgICAgICAgICAgICAgIGxlbmd0aCArPSBmTWFwc1tpXS5nZXRMZW5ndGgoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIHRoZW4gY29weSBhbGwgdHlwZXMgdG8gYW4gdGVtcG9yYXJ5IGFycmF5Ci0gICAgICAgICAgICBpbnQgcG9zID0gMDsKLSAgICAgICAgICAgIFhTT2JqZWN0W10gYXJyYXkgPSBuZXcgWFNPYmplY3RbbGVuZ3RoXTsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZk5TTnVtOyBpKyspIHsKLSAgICAgICAgICAgICAgICBwb3MgKz0gZk1hcHNbaV0uZ2V0VmFsdWVzKGFycmF5LCBwb3MpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gdGhlbiBjb3B5IGVpdGhlciBzaW1wbGUgb3IgY29tcGxleCB0eXBlcyB0byBmQXJyYXksCi0gICAgICAgICAgICAvLyBkZXBlbmRpbmcgb24gd2hpY2gga2luZCBpcyByZXF1aXJlZAotICAgICAgICAgICAgZkxlbmd0aCA9IDA7Ci0gICAgICAgICAgICBmQXJyYXkgPSBuZXcgWFNPYmplY3RbbGVuZ3RoXTsKLSAgICAgICAgICAgIFhTVHlwZURlZmluaXRpb24gdHlwZTsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgICAgICB0eXBlID0gKFhTVHlwZURlZmluaXRpb24pYXJyYXlbaV07Ci0gICAgICAgICAgICAgICAgaWYgKHR5cGUuZ2V0VHlwZUNhdGVnb3J5KCkgPT0gZlR5cGUpIHsKLSAgICAgICAgICAgICAgICAgICAgZkFycmF5W2ZMZW5ndGgrK10gPSB0eXBlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZkxlbmd0aDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXRyaWV2ZXMgYW4gPGNvZGU+WFNPYmplY3Q8L2NvZGU+IHNwZWNpZmllZCBieSBsb2NhbCBuYW1lIGFuZCBuYW1lc3BhY2UKLSAgICAgKiBVUkkuCi0gICAgICogQHBhcmFtIG5hbWVzcGFjZSBUaGUgbmFtZXNwYWNlIFVSSSBvZiB0aGUgPGNvZGU+WFNPYmplY3Q8L2NvZGU+IHRvCi0gICAgICogICByZXRyaWV2ZS4KLSAgICAgKiBAcGFyYW0gbG9jYWxOYW1lIFRoZSBsb2NhbCBuYW1lIG9mIHRoZSA8Y29kZT5YU09iamVjdDwvY29kZT4gdG8gcmV0cmlldmUuCi0gICAgICogQHJldHVybiBBIDxjb2RlPlhTT2JqZWN0PC9jb2RlPiAob2YgYW55IHR5cGUpIHdpdGggdGhlIHNwZWNpZmllZCBsb2NhbAotICAgICAqICAgbmFtZSBhbmQgbmFtZXNwYWNlIFVSSSwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhleSBkbyBub3QKLSAgICAgKiAgIGlkZW50aWZ5IGFueSA8Y29kZT5YU09iamVjdDwvY29kZT4gaW4gdGhpcyBtYXAuCi0gICAgICovCi0gICAgcHVibGljIFhTT2JqZWN0IGl0ZW1CeU5hbWUoU3RyaW5nIG5hbWVzcGFjZSwgU3RyaW5nIGxvY2FsTmFtZSkgewotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZOU051bTsgaSsrKSB7Ci0gICAgICAgICAgICBpZiAoaXNFcXVhbChuYW1lc3BhY2UsIGZOYW1lc3BhY2VzW2ldKSkgewotICAgICAgICAgICAgICAgIFhTVHlwZURlZmluaXRpb24gdHlwZSA9IChYU1R5cGVEZWZpbml0aW9uKWZNYXBzW2ldLmdldChsb2NhbE5hbWUpOwotICAgICAgICAgICAgICAgIC8vIG9ubHkgcmV0dXJuIGl0IGlmIGl0IG1hdGNoZXMgdGhlIHJlcXVpcmVkIHR5cGUKLSAgICAgICAgICAgICAgICBpZiAodHlwZSAhPSBudWxsICYmIHR5cGUuZ2V0VHlwZUNhdGVnb3J5KCkgPT0gZlR5cGUpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHR5cGU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIDxjb2RlPmluZGV4PC9jb2RlPnRoIGl0ZW0gaW4gdGhlIG1hcC4gVGhlIGluZGV4IHN0YXJ0cyBhdAotICAgICAqIDAuIElmIDxjb2RlPmluZGV4PC9jb2RlPiBpcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gdGhlIG51bWJlciBvZgotICAgICAqIG5vZGVzIGluIHRoZSBsaXN0LCB0aGlzIHJldHVybnMgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICogQHBhcmFtIGluZGV4IFRoZSBwb3NpdGlvbiBpbiB0aGUgbWFwIGZyb20gd2hpY2ggdGhlIGl0ZW0gaXMgdG8gYmUKLSAgICAgKiAgIHJldHJpZXZlZC4KLSAgICAgKiBAcmV0dXJuIFRoZSA8Y29kZT5YU09iamVjdDwvY29kZT4gYXQgdGhlIDxjb2RlPmluZGV4PC9jb2RlPnRoIHBvc2l0aW9uCi0gICAgICogICBpbiB0aGUgPGNvZGU+WFNOYW1lZE1hcDwvY29kZT4sIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoYXQgaXMKLSAgICAgKiAgIG5vdCBhIHZhbGlkIGluZGV4LgotICAgICAqLwotICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgWFNPYmplY3QgaXRlbShpbnQgaW5kZXgpIHsKLSAgICAgICAgaWYgKGZBcnJheSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBnZXRMZW5ndGgoKTsKLSAgICAgICAgfQotICAgICAgICBpZiAoaW5kZXggPCAwIHx8IGluZGV4ID49IGZMZW5ndGgpIHsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmQXJyYXlbaW5kZXhdOwotICAgIH0KLQotfSAvLyBjbGFzcyBYU05hbWVkTWFwSW1wbApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy91dGlsL1hTTmFtZWRNYXBJbXBsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL3V0aWwvWFNOYW1lZE1hcEltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMTc0MDY1Ni4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL3V0aWwvWFNOYW1lZE1hcEltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDMwMiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAyLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy51dGlsOwotCi1pbXBvcnQgamF2YS51dGlsLkFic3RyYWN0TWFwOwotaW1wb3J0IGphdmEudXRpbC5BYnN0cmFjdFNldDsKLWltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7Ci1pbXBvcnQgamF2YS51dGlsLk1hcDsKLWltcG9ydCBqYXZhLnV0aWwuTm9TdWNoRWxlbWVudEV4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuU2V0OwotCi1pbXBvcnQgamF2YXgueG1sLlhNTENvbnN0YW50czsKLWltcG9ydCBqYXZheC54bWwubmFtZXNwYWNlLlFOYW1lOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlN5bWJvbEhhc2g7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU05hbWVkTWFwOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNPYmplY3Q7Ci0KLS8qKgotICogQ29udGFpbnRzIHRoZSBtYXAgYmV0d2VlbiBxbmFtZXMgYW5kIFhTT2JqZWN0J3MuCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEBhdXRob3IgU2FuZHkgR2FvLCBJQk0KLSAqCi0gKiBAdmVyc2lvbiAkSWQ6IFhTTmFtZWRNYXBJbXBsLmphdmEsdiAxLjcgMjAxMC0xMS0wMSAwNDo0MDowNiBqb2VodyBFeHAgJAotICovCi1wdWJsaWMgY2xhc3MgWFNOYW1lZE1hcEltcGwgZXh0ZW5kcyBBYnN0cmFjdE1hcCBpbXBsZW1lbnRzIFhTTmFtZWRNYXAgewotCi0gICAgLyoqCi0gICAgICogQW4gaW1tdXRhYmxlIGVtcHR5IG1hcC4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFhTTmFtZWRNYXBJbXBsIEVNUFRZX01BUCA9IG5ldyBYU05hbWVkTWFwSW1wbChuZXcgWFNPYmplY3RbMF0sIDApOwotCi0gICAgLy8gY29tcG9uZW50cyBvZiB0aGVzZSBuYW1lc3BhY2VzIGFyZSBzdG9yZWQgaW4gdGhpcyBtYXAKLSAgICBmaW5hbCBTdHJpbmdbXSBmTmFtZXNwYWNlczsKLSAgICAvLyBudW1iZXIgb2YgbmFtZXNwYWNlcwotICAgIGZpbmFsIGludCBmTlNOdW07Ci0gICAgLy8gZWFjaCBlbnRyeSBjb250YWlucyBjb21wb25lbnRzIGluIG9uZSBuYW1lc3BhY2UKLSAgICBmaW5hbCBTeW1ib2xIYXNoW10gZk1hcHM7Ci0gICAgLy8gc3RvcmUgYWxsIGNvbXBvbmVudHMgZnJvbSBhbGwgbmFtZXNwYWNlLgotICAgIC8vIHVzZWQgd2hlbiB0aGlzIG1hcCBpcyBhY2Nlc3NlZCBhcyBhIGxpc3QuCi0gICAgWFNPYmplY3RbXSBmQXJyYXkgPSBudWxsOwotICAgIC8vIHN0b3JlIHRoZSBudW1iZXIgb2YgY29tcG9uZW50cy4KLSAgICAvLyB1c2VkIHdoZW4gdGhpcyBtYXAgaXMgYWNjZXNzZWQgYXMgYSBsaXN0LgotICAgIGludCBmTGVuZ3RoID0gLTE7Ci0gICAgLy8gU2V0IG9mIE1hcC5FbnRyeTxRTmFtZSxYU09iamVjdD4gZm9yIHRoZSBqYXZhLnV0aWwuTWFwIG1ldGhvZHMKLSAgICBwcml2YXRlIFNldCBmRW50cnlTZXQgPSBudWxsOwotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0IGFuIFhTTmFtZWRNYXAgaW1wbGVtZW50YXRpb24gZm9yIG9uZSBuYW1lc3BhY2UKLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lc3BhY2UgdGhlIG5hbWVzcGFjZSB0byB3aGljaCB0aGUgY29tcG9uZW50cyBiZWxvbmcKLSAgICAgKiBAcGFyYW0gbWFwICAgICAgIHRoZSBtYXAgZnJvbSBsb2NhbCBuYW1lcyB0byBjb21wb25lbnRzCi0gICAgICovCi0gICAgcHVibGljIFhTTmFtZWRNYXBJbXBsKFN0cmluZyBuYW1lc3BhY2UsIFN5bWJvbEhhc2ggbWFwKSB7Ci0gICAgICAgIGZOYW1lc3BhY2VzID0gbmV3IFN0cmluZ1tdIHtuYW1lc3BhY2V9OwotICAgICAgICBmTWFwcyA9IG5ldyBTeW1ib2xIYXNoW10ge21hcH07Ci0gICAgICAgIGZOU051bSA9IDE7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0IGFuIFhTTmFtZWRNYXAgaW1wbGVtZW50YXRpb24gZm9yIGEgbGlzdCBvZiBuYW1lc3BhY2VzCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZXNwYWNlcyB0aGUgbmFtZXNwYWNlcyB0byB3aGljaCB0aGUgY29tcG9uZW50cyBiZWxvbmcKLSAgICAgKiBAcGFyYW0gbWFwcyAgICAgICB0aGUgbWFwcyBmcm9tIGxvY2FsIG5hbWVzIHRvIGNvbXBvbmVudHMKLSAgICAgKiBAcGFyYW0gbnVtICAgICAgICB0aGUgbnVtYmVyIG9mIG5hbWVzcGFjZXMKLSAgICAgKi8KLSAgICBwdWJsaWMgWFNOYW1lZE1hcEltcGwoU3RyaW5nW10gbmFtZXNwYWNlcywgU3ltYm9sSGFzaFtdIG1hcHMsIGludCBudW0pIHsKLSAgICAgICAgZk5hbWVzcGFjZXMgPSBuYW1lc3BhY2VzOwotICAgICAgICBmTWFwcyA9IG1hcHM7Ci0gICAgICAgIGZOU051bSA9IG51bTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3QgYW4gWFNOYW1lZE1hcCBpbXBsZW1lbnRhdGlvbiBvbmUgbmFtZXNwYWNlIGZyb20gYW4gYXJyYXkKLSAgICAgKgotICAgICAqIEBwYXJhbSBhcnJheSAgICAgY29udGFpbmluZyBhbGwgY29tcG9uZW50cwotICAgICAqIEBwYXJhbSBsZW5ndGggICAgbnVtYmVyIG9mIGNvbXBvbmVudHMKLSAgICAgKi8KLSAgICBwdWJsaWMgWFNOYW1lZE1hcEltcGwoWFNPYmplY3RbXSBhcnJheSwgaW50IGxlbmd0aCkgewotICAgICAgICBpZiAobGVuZ3RoID09IDApIHsKLSAgICAgICAgICAgIGZOYW1lc3BhY2VzID0gbnVsbDsKLSAgICAgICAgICAgIGZNYXBzID0gbnVsbDsKLSAgICAgICAgICAgIGZOU051bSA9IDA7Ci0gICAgICAgICAgICBmQXJyYXkgPSBhcnJheTsKLSAgICAgICAgICAgIGZMZW5ndGggPSAwOwotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0gICAgICAgIC8vIGJlY2F1c2UgYWxsIGNvbXBvbmVudHMgYXJlIGZyb20gdGhlIHNhbWUgdGFyZ2V0IG5hbWVzYXBjZSwKLSAgICAgICAgLy8gZ2V0IHRoZSBuYW1lc3BhY2UgZnJvbSB0aGUgZmlyc3Qgb25lLgotICAgICAgICBmTmFtZXNwYWNlcyA9IG5ldyBTdHJpbmdbXXthcnJheVswXS5nZXROYW1lc3BhY2UoKX07Ci0gICAgICAgIGZNYXBzID0gbnVsbDsKLSAgICAgICAgZk5TTnVtID0gMTsKLSAgICAgICAgLy8gY29weSBlbGVtZW50cyB0byB0aGUgVmVjdG9yCi0gICAgICAgIGZBcnJheSA9IGFycmF5OwotICAgICAgICBmTGVuZ3RoID0gbGVuZ3RoOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoZSBudW1iZXIgb2YgPGNvZGU+WFNPYmplY3RzPC9jb2RlPiBpbiB0aGUgPGNvZGU+WFNPYmplY3RMaXN0PC9jb2RlPi4KLSAgICAgKiBUaGUgcmFuZ2Ugb2YgdmFsaWQgY2hpbGQgb2JqZWN0IGluZGljZXMgaXMgMCB0byA8Y29kZT5sZW5ndGgtMTwvY29kZT4KLSAgICAgKiBpbmNsdXNpdmUuCi0gICAgICovCi0gICAgcHVibGljIHN5bmNocm9uaXplZCBpbnQgZ2V0TGVuZ3RoKCkgewotICAgICAgICBpZiAoZkxlbmd0aCA9PSAtMSkgewotICAgICAgICAgICAgZkxlbmd0aCA9IDA7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZOU051bTsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgZkxlbmd0aCArPSBmTWFwc1tpXS5nZXRMZW5ndGgoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZkxlbmd0aDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXRyaWV2ZXMgYW4gPGNvZGU+WFNPYmplY3Q8L2NvZGU+IHNwZWNpZmllZCBieSBsb2NhbCBuYW1lIGFuZAotICAgICAqIG5hbWVzcGFjZSBVUkkuCi0gICAgICogPGJyPlBlciBYTUwgTmFtZXNwYWNlcywgYXBwbGljYXRpb25zIG11c3QgdXNlIHRoZSB2YWx1ZSA8Y29kZT5udWxsPC9jb2RlPiBhcyB0aGUKLSAgICAgKiA8Y29kZT5uYW1lc3BhY2U8L2NvZGU+IHBhcmFtZXRlciBmb3IgbWV0aG9kcyBpZiB0aGV5IHdpc2ggdG8gc3BlY2lmeQotICAgICAqIG5vIG5hbWVzcGFjZS4KLSAgICAgKiBAcGFyYW0gbmFtZXNwYWNlIFRoZSBuYW1lc3BhY2UgVVJJIG9mIHRoZSA8Y29kZT5YU09iamVjdDwvY29kZT4gdG8KLSAgICAgKiAgIHJldHJpZXZlLCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGUgPGNvZGU+WFNPYmplY3Q8L2NvZGU+IGhhcyBubwotICAgICAqICAgbmFtZXNwYWNlLgotICAgICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGxvY2FsIG5hbWUgb2YgdGhlIDxjb2RlPlhTT2JqZWN0PC9jb2RlPiB0bwotICAgICAqICAgcmV0cmlldmUuCi0gICAgICogQHJldHVybiBBIDxjb2RlPlhTT2JqZWN0PC9jb2RlPiAob2YgYW55IHR5cGUpIHdpdGggdGhlIHNwZWNpZmllZCBsb2NhbAotICAgICAqICAgbmFtZSBhbmQgbmFtZXNwYWNlIFVSSSwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhleSBkbyBub3QKLSAgICAgKiAgIGlkZW50aWZ5IGFueSBvYmplY3QgaW4gdGhpcyBtYXAuCi0gICAgICovCi0gICAgcHVibGljIFhTT2JqZWN0IGl0ZW1CeU5hbWUoU3RyaW5nIG5hbWVzcGFjZSwgU3RyaW5nIGxvY2FsTmFtZSkgewotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZOU051bTsgaSsrKSB7Ci0gICAgICAgICAgICBpZiAoaXNFcXVhbChuYW1lc3BhY2UsIGZOYW1lc3BhY2VzW2ldKSkgewotICAgICAgICAgICAgICAgIC8vIHdoZW4gdGhpcyBtYXAgaXMgY3JlYXRlZCBmcm9tIFN5bWJvbEhhc2gncwotICAgICAgICAgICAgICAgIC8vIGdldCB0aGUgY29tcG9uZW50IGZyb20gU3ltYm9sSGFzaAotICAgICAgICAgICAgICAgIGlmIChmTWFwcyAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiAoWFNPYmplY3QpZk1hcHNbaV0uZ2V0KGxvY2FsTmFtZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIC8vIE90aGVyd2lzZSAoaXQncyBjcmVhdGVkIGZyb20gYW4gYXJyYXkpCi0gICAgICAgICAgICAgICAgLy8gZ28gdGhyb3VnaCB0aGUgYXJyYXkgdG8gZmluZCBhIG1hdGNoaW5nIG5hbWUKLSAgICAgICAgICAgICAgICBYU09iamVjdCByZXQ7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBmTGVuZ3RoOyBqKyspIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0ID0gZkFycmF5W2pdOwotICAgICAgICAgICAgICAgICAgICBpZiAocmV0LmdldE5hbWUoKS5lcXVhbHMobG9jYWxOYW1lKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJldDsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSA8Y29kZT5pbmRleDwvY29kZT50aCBpdGVtIGluIHRoZSBjb2xsZWN0aW9uIG9yCi0gICAgICogPGNvZGU+bnVsbDwvY29kZT4gaWYgPGNvZGU+aW5kZXg8L2NvZGU+IGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0bwotICAgICAqIHRoZSBudW1iZXIgb2Ygb2JqZWN0cyBpbiB0aGUgbGlzdC4gVGhlIGluZGV4IHN0YXJ0cyBhdCAwLgotICAgICAqIEBwYXJhbSBpbmRleCAgaW5kZXggaW50byB0aGUgY29sbGVjdGlvbi4KLSAgICAgKiBAcmV0dXJuICBUaGUgPGNvZGU+WFNPYmplY3Q8L2NvZGU+IGF0IHRoZSA8Y29kZT5pbmRleDwvY29kZT50aAotICAgICAqICAgcG9zaXRpb24gaW4gdGhlIDxjb2RlPlhTT2JqZWN0TGlzdDwvY29kZT4sIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmCi0gICAgICogICB0aGUgaW5kZXggc3BlY2lmaWVkIGlzIG5vdCB2YWxpZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3luY2hyb25pemVkIFhTT2JqZWN0IGl0ZW0oaW50IGluZGV4KSB7Ci0gICAgICAgIGlmIChmQXJyYXkgPT0gbnVsbCkgewotICAgICAgICAgICAgLy8gY2FsY3VsYXRlIHRoZSB0b3RhbCBudW1iZXIgb2YgZWxlbWVudHMKLSAgICAgICAgICAgIGdldExlbmd0aCgpOwotICAgICAgICAgICAgZkFycmF5ID0gbmV3IFhTT2JqZWN0W2ZMZW5ndGhdOwotICAgICAgICAgICAgaW50IHBvcyA9IDA7Ci0gICAgICAgICAgICAvLyBnZXQgY29tcG9uZW50cyBmcm9tIGFsbCBTeW1ib2xIYXNoZXMKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZk5TTnVtOyBpKyspIHsKLSAgICAgICAgICAgICAgICBwb3MgKz0gZk1hcHNbaV0uZ2V0VmFsdWVzKGZBcnJheSwgcG9zKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBpZiAoaW5kZXggPCAwIHx8IGluZGV4ID49IGZMZW5ndGgpIHsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmQXJyYXlbaW5kZXhdOwotICAgIH0KLQotICAgIHN0YXRpYyBib29sZWFuIGlzRXF1YWwoU3RyaW5nIG9uZSwgU3RyaW5nIHR3bykgewotICAgICAgICByZXR1cm4gKG9uZSAhPSBudWxsKSA/IG9uZS5lcXVhbHModHdvKSA6ICh0d28gPT0gbnVsbCk7Ci0gICAgfQotCi0gICAgLyoKLSAgICAgKiBqYXZhLnV0aWwuTWFwIG1ldGhvZHMKLSAgICAgKi8KLQotICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zS2V5KE9iamVjdCBrZXkpIHsKLSAgICAgICAgcmV0dXJuIChnZXQoa2V5KSAhPSBudWxsKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgT2JqZWN0IGdldChPYmplY3Qga2V5KSB7Ci0gICAgICAgIGlmIChrZXkgaW5zdGFuY2VvZiBRTmFtZSkgewotICAgICAgICAgICAgZmluYWwgUU5hbWUgbmFtZSA9IChRTmFtZSkga2V5OwotICAgICAgICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSA9IG5hbWUuZ2V0TmFtZXNwYWNlVVJJKCk7Ci0gICAgICAgICAgICBpZiAoWE1MQ29uc3RhbnRzLk5VTExfTlNfVVJJLmVxdWFscyhuYW1lc3BhY2VVUkkpKSB7Ci0gICAgICAgICAgICAgICAgbmFtZXNwYWNlVVJJID0gbnVsbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIFN0cmluZyBsb2NhbFBhcnQgPSBuYW1lLmdldExvY2FsUGFydCgpOwotICAgICAgICAgICAgcmV0dXJuIGl0ZW1CeU5hbWUobmFtZXNwYWNlVVJJLCBsb2NhbFBhcnQpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKLSAgICAgICAgcmV0dXJuIGdldExlbmd0aCgpOwotICAgIH0KLQotICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgU2V0IGVudHJ5U2V0KCkgewotICAgICAgICAvLyBEZWZlciBjcmVhdGlvbiBvZiB0aGUgZW50cnkgc2V0IHVudGlsIGl0IGlzIGFjdHVhbGx5IG5lZWRlZC4KLSAgICAgICAgaWYgKGZFbnRyeVNldCA9PSBudWxsKSB7Ci0gICAgICAgICAgICBmaW5hbCBpbnQgbGVuZ3RoID0gZ2V0TGVuZ3RoKCk7Ci0gICAgICAgICAgICBmaW5hbCBYU05hbWVkTWFwRW50cnlbXSBlbnRyaWVzID0gbmV3IFhTTmFtZWRNYXBFbnRyeVtsZW5ndGhdOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkgewotICAgICAgICAgICAgICAgIFhTT2JqZWN0IHhzbyA9IGl0ZW0oaSk7Ci0gICAgICAgICAgICAgICAgZW50cmllc1tpXSA9IG5ldyBYU05hbWVkTWFwRW50cnkobmV3IFFOYW1lKHhzby5nZXROYW1lc3BhY2UoKSwgeHNvLmdldE5hbWUoKSksIHhzbyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyBDcmVhdGUgYSB2aWV3IG9mIHRoaXMgaW1tdXRhYmxlIG1hcC4KLSAgICAgICAgICAgIGZFbnRyeVNldCA9IG5ldyBBYnN0cmFjdFNldCgpIHsKLSAgICAgICAgICAgICAgICBwdWJsaWMgSXRlcmF0b3IgaXRlcmF0b3IoKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgSXRlcmF0b3IoKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBwcml2YXRlIGludCBpbmRleCA9IDA7Ci0gICAgICAgICAgICAgICAgICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNOZXh0KCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoaW5kZXggPCBsZW5ndGgpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgcHVibGljIE9iamVjdCBuZXh0KCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbmRleCA8IGxlbmd0aCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZW50cmllc1tpbmRleCsrXTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIHJlbW92ZSgpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgcHVibGljIGludCBzaXplKCkgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gbGVuZ3RoOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH07Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGZFbnRyeVNldDsKLSAgICB9Ci0KLSAgICAvKiogQW4gZW50cnkgaW4gdGhlIFhTTmFtZWRNYXAuICoqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIFhTTmFtZWRNYXBFbnRyeSBpbXBsZW1lbnRzIE1hcC5FbnRyeSB7Ci0gICAgICAgIHByaXZhdGUgZmluYWwgUU5hbWUga2V5OwotICAgICAgICBwcml2YXRlIGZpbmFsIFhTT2JqZWN0IHZhbHVlOwotICAgICAgICBwdWJsaWMgWFNOYW1lZE1hcEVudHJ5KFFOYW1lIGtleSwgWFNPYmplY3QgdmFsdWUpIHsKLSAgICAgICAgICAgIHRoaXMua2V5ID0ga2V5OwotICAgICAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOwotICAgICAgICB9Ci0gICAgICAgIHB1YmxpYyBPYmplY3QgZ2V0S2V5KCkgewotICAgICAgICAgICAgcmV0dXJuIGtleTsKLSAgICAgICAgfQotICAgICAgICBwdWJsaWMgT2JqZWN0IGdldFZhbHVlKCkgewotICAgICAgICAgICAgcmV0dXJuIHZhbHVlOwotICAgICAgICB9Ci0gICAgICAgIHB1YmxpYyBPYmplY3Qgc2V0VmFsdWUoT2JqZWN0IHZhbHVlKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKLSAgICAgICAgfQotICAgICAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG8pIHsKLSAgICAgICAgICAgIGlmIChvIGluc3RhbmNlb2YgTWFwLkVudHJ5KSB7Ci0gICAgICAgICAgICAgICAgTWFwLkVudHJ5IGUgPSAoTWFwLkVudHJ5KSBvOwotICAgICAgICAgICAgICAgIE9iamVjdCBvdGhlcktleSA9IGUuZ2V0S2V5KCk7Ci0gICAgICAgICAgICAgICAgT2JqZWN0IG90aGVyVmFsdWUgPSBlLmdldFZhbHVlKCk7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIChrZXkgPT0gbnVsbCA/IG90aGVyS2V5ID09IG51bGwgOiBrZXkuZXF1YWxzKG90aGVyS2V5KSkgJiYKLSAgICAgICAgICAgICAgICAgICAgKHZhbHVlID09IG51bGwgPyBvdGhlclZhbHVlID09IG51bGwgOiB2YWx1ZS5lcXVhbHMob3RoZXJWYWx1ZSkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0gICAgICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7Ci0gICAgICAgICAgICByZXR1cm4gKGtleSA9PSBudWxsID8gMCA6IGtleS5oYXNoQ29kZSgpKQotICAgICAgICAgICAgICAgIF4gKHZhbHVlID09IG51bGwgPyAwIDogdmFsdWUuaGFzaENvZGUoKSk7Ci0gICAgICAgIH0KLSAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKLSAgICAgICAgICAgIFN0cmluZ0J1ZmZlciBidWZmZXIgPSBuZXcgU3RyaW5nQnVmZmVyKCk7Ci0gICAgICAgICAgICBidWZmZXIuYXBwZW5kKFN0cmluZy52YWx1ZU9mKGtleSkpOwotICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgnPScpOwotICAgICAgICAgICAgYnVmZmVyLmFwcGVuZChTdHJpbmcudmFsdWVPZih2YWx1ZSkpOwotICAgICAgICAgICAgcmV0dXJuIGJ1ZmZlci50b1N0cmluZygpOwotICAgICAgICB9Ci0gICAgfQotCi19IC8vIGNsYXNzIFhTTmFtZWRNYXBJbXBsCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL3V0aWwvWFNPYmplY3RMaXN0SW1wbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvaW1wbC94cy91dGlsL1hTT2JqZWN0TGlzdEltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYjVlMGRlMi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9pbXBsL3hzL3V0aWwvWFNPYmplY3RMaXN0SW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjY3ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDIsMjAwMy0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMudXRpbDsKLQotaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkFycmF5OwotaW1wb3J0IGphdmEudXRpbC5BYnN0cmFjdExpc3Q7Ci1pbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOwotaW1wb3J0IGphdmEudXRpbC5MaXN0SXRlcmF0b3I7Ci1pbXBvcnQgamF2YS51dGlsLk5vU3VjaEVsZW1lbnRFeGNlcHRpb247Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTT2JqZWN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNPYmplY3RMaXN0OwotCi0vKioKLSAqIENvbnRhaW50cyBhIGxpc3Qgb2YgWFNPYmplY3Qncy4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQGF1dGhvciBTYW5keSBHYW8sIElCTQotICoKLSAqIEB2ZXJzaW9uICRJZDogWFNPYmplY3RMaXN0SW1wbC5qYXZhLHYgMS43IDIwMTAtMTEtMDEgMDQ6NDA6MDYgam9laHcgRXhwICQKLSAqLwotcHVibGljIGNsYXNzIFhTT2JqZWN0TGlzdEltcGwgZXh0ZW5kcyBBYnN0cmFjdExpc3QgaW1wbGVtZW50cyBYU09iamVjdExpc3QgewotCi0gICAgLyoqCi0gICAgICogQW4gaW1tdXRhYmxlIGVtcHR5IGxpc3QuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBYU09iamVjdExpc3RJbXBsIEVNUFRZX0xJU1QgPSBuZXcgWFNPYmplY3RMaXN0SW1wbChuZXcgWFNPYmplY3RbMF0sIDApOwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIExpc3RJdGVyYXRvciBFTVBUWV9JVEVSQVRPUiA9IG5ldyBMaXN0SXRlcmF0b3IoKSB7Ci0gICAgICAgIHB1YmxpYyBib29sZWFuIGhhc05leHQoKSB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLSAgICAgICAgcHVibGljIE9iamVjdCBuZXh0KCkgewotICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oKTsKLSAgICAgICAgfQotICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNQcmV2aW91cygpIHsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotICAgICAgICBwdWJsaWMgT2JqZWN0IHByZXZpb3VzKCkgewotICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oKTsKLSAgICAgICAgfQotICAgICAgICBwdWJsaWMgaW50IG5leHRJbmRleCgpIHsKLSAgICAgICAgICAgIHJldHVybiAwOwotICAgICAgICB9Ci0gICAgICAgIHB1YmxpYyBpbnQgcHJldmlvdXNJbmRleCgpIHsKLSAgICAgICAgICAgIHJldHVybiAtMTsKLSAgICAgICAgfQotICAgICAgICBwdWJsaWMgdm9pZCByZW1vdmUoKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKLSAgICAgICAgfQotICAgICAgICBwdWJsaWMgdm9pZCBzZXQoT2JqZWN0IG9iamVjdCkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7Ci0gICAgICAgIH0KLSAgICAgICAgcHVibGljIHZvaWQgYWRkKE9iamVjdCBvYmplY3QpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOwotICAgICAgICB9Ci0gICAgfTsKLQotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBERUZBVUxUX1NJWkUgPSA0OwotCi0gICAgLy8gVGhlIGFycmF5IHRvIGhvbGQgYWxsIGRhdGEKLSAgICBwcml2YXRlIFhTT2JqZWN0W10gZkFycmF5ID0gbnVsbDsKLSAgICAvLyBOdW1iZXIgb2YgZWxlbWVudHMgaW4gdGhpcyBsaXN0Ci0gICAgcHJpdmF0ZSBpbnQgZkxlbmd0aCA9IDA7Ci0KLSAgICBwdWJsaWMgWFNPYmplY3RMaXN0SW1wbCgpIHsKLSAgICAgICAgZkFycmF5ID0gbmV3IFhTT2JqZWN0W0RFRkFVTFRfU0laRV07Ci0gICAgICAgIGZMZW5ndGggPSAwOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdCBhbiBYU09iamVjdExpc3QgaW1wbGVtZW50YXRpb24KLSAgICAgKgotICAgICAqIEBwYXJhbSBhcnJheSAgICAgdGhlIGRhdGEgYXJyYXkKLSAgICAgKiBAcGFyYW0gbGVuZ3RoICAgIHRoZSBudW1iZXIgb2YgZWxlbWVudHMKLSAgICAgKi8KLSAgICBwdWJsaWMgWFNPYmplY3RMaXN0SW1wbChYU09iamVjdFtdIGFycmF5LCBpbnQgbGVuZ3RoKSB7Ci0gICAgICAgIGZBcnJheSA9IGFycmF5OwotICAgICAgICBmTGVuZ3RoID0gbGVuZ3RoOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoZSBudW1iZXIgb2YgPGNvZGU+WFNPYmplY3RzPC9jb2RlPiBpbiB0aGUgbGlzdC4gVGhlIHJhbmdlIG9mIHZhbGlkCi0gICAgICogY2hpbGQgbm9kZSBpbmRpY2VzIGlzIDAgdG8gPGNvZGU+bGVuZ3RoLTE8L2NvZGU+IGluY2x1c2l2ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldExlbmd0aCgpIHsKLSAgICAgICAgcmV0dXJuIGZMZW5ndGg7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgPGNvZGU+aW5kZXg8L2NvZGU+dGggaXRlbSBpbiB0aGUgY29sbGVjdGlvbi4gVGhlIGluZGV4Ci0gICAgICogc3RhcnRzIGF0IDAuIElmIDxjb2RlPmluZGV4PC9jb2RlPiBpcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gdGhlCi0gICAgICogbnVtYmVyIG9mIG5vZGVzIGluIHRoZSBsaXN0LCB0aGlzIHJldHVybnMgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICogQHBhcmFtIGluZGV4IGluZGV4IGludG8gdGhlIGNvbGxlY3Rpb24uCi0gICAgICogQHJldHVybiBUaGUgWFNPYmplY3QgYXQgdGhlIDxjb2RlPmluZGV4PC9jb2RlPnRoIHBvc2l0aW9uIGluIHRoZQotICAgICAqICAgPGNvZGU+WFNPYmplY3RMaXN0PC9jb2RlPiwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhhdCBpcyBub3QgYQotICAgICAqICAgdmFsaWQgaW5kZXguCi0gICAgICovCi0gICAgcHVibGljIFhTT2JqZWN0IGl0ZW0oaW50IGluZGV4KSB7Ci0gICAgICAgIGlmIChpbmRleCA8IDAgfHwgaW5kZXggPj0gZkxlbmd0aCkgewotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGZBcnJheVtpbmRleF07Ci0gICAgfQotCi0gICAgLy8gY2xlYXIgdGhpcyBvYmplY3QKLSAgICBwdWJsaWMgdm9pZCBjbGVhclhTT2JqZWN0TGlzdCgpIHsKLSAgICAgICAgZm9yIChpbnQgaT0wOyBpPGZMZW5ndGg7IGkrKykgewotICAgICAgICAgICAgZkFycmF5W2ldID0gbnVsbDsKLSAgICAgICAgfQotICAgICAgICBmQXJyYXkgPSBudWxsOwotICAgICAgICBmTGVuZ3RoID0gMDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBhZGRYU09iamVjdChYU09iamVjdCBvYmplY3QpIHsKLSAgICAgICBpZiAoZkxlbmd0aCA9PSBmQXJyYXkubGVuZ3RoKSB7Ci0gICAgICAgICAgIFhTT2JqZWN0W10gdGVtcCA9IG5ldyBYU09iamVjdFtmTGVuZ3RoICsgNF07Ci0gICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZkFycmF5LCAwLCB0ZW1wLCAwLCBmTGVuZ3RoKTsKLSAgICAgICAgICAgZkFycmF5ID0gdGVtcDsKLSAgICAgICB9Ci0gICAgICAgZkFycmF5W2ZMZW5ndGgrK10gPSBvYmplY3Q7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgYWRkWFNPYmplY3QoaW50IGluZGV4LCBYU09iamVjdCBvYmplY3QpIHsKLSAgICAgICAgZkFycmF5W2luZGV4XSA9IG9iamVjdDsKLSAgICB9Ci0KLSAgICAvKgotICAgICAqIExpc3QgbWV0aG9kcwotICAgICAqLwotCi0gICAgcHVibGljIGJvb2xlYW4gY29udGFpbnMoT2JqZWN0IHZhbHVlKSB7Ci0gICAgICAgIHJldHVybiAodmFsdWUgPT0gbnVsbCkgPyBjb250YWluc051bGwoKSA6IGNvbnRhaW5zT2JqZWN0KHZhbHVlKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgT2JqZWN0IGdldChpbnQgaW5kZXgpIHsKLSAgICAgICAgaWYgKGluZGV4ID49IDAgJiYgaW5kZXggPCBmTGVuZ3RoKSB7Ci0gICAgICAgICAgICByZXR1cm4gZkFycmF5W2luZGV4XTsKLSAgICAgICAgfQotICAgICAgICB0aHJvdyBuZXcgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigiSW5kZXg6ICIgKyBpbmRleCk7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBzaXplKCkgewotICAgICAgICByZXR1cm4gZ2V0TGVuZ3RoKCk7Ci0gICAgfQotCi0gICAgcHVibGljIEl0ZXJhdG9yIGl0ZXJhdG9yKCkgewotICAgICAgICByZXR1cm4gbGlzdEl0ZXJhdG9yMCgwKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgTGlzdEl0ZXJhdG9yIGxpc3RJdGVyYXRvcigpIHsKLSAgICAgICAgcmV0dXJuIGxpc3RJdGVyYXRvcjAoMCk7Ci0gICAgfQotCi0gICAgcHVibGljIExpc3RJdGVyYXRvciBsaXN0SXRlcmF0b3IoaW50IGluZGV4KSB7Ci0gICAgICAgIGlmIChpbmRleCA+PSAwICYmIGluZGV4IDwgZkxlbmd0aCkgewotICAgICAgICAgICAgcmV0dXJuIGxpc3RJdGVyYXRvcjAoaW5kZXgpOwotICAgICAgICB9Ci0gICAgICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCJJbmRleDogIiArIGluZGV4KTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIExpc3RJdGVyYXRvciBsaXN0SXRlcmF0b3IwKGludCBpbmRleCkgewotICAgICAgICByZXR1cm4gZkxlbmd0aCA9PSAwID8gRU1QVFlfSVRFUkFUT1IgOiBuZXcgWFNPYmplY3RMaXN0SXRlcmF0b3IoaW5kZXgpOwotICAgIH0KLQotICAgIHByaXZhdGUgYm9vbGVhbiBjb250YWluc09iamVjdChPYmplY3QgdmFsdWUpIHsKLSAgICAgICAgZm9yIChpbnQgaSA9IGZMZW5ndGggLSAxOyBpID49IDA7IC0taSkgewotICAgICAgICAgICAgaWYgKHZhbHVlLmVxdWFscyhmQXJyYXlbaV0pKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIHByaXZhdGUgYm9vbGVhbiBjb250YWluc051bGwoKSB7Ci0gICAgICAgIGZvciAoaW50IGkgPSBmTGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHsKLSAgICAgICAgICAgIGlmIChmQXJyYXlbaV0gPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgT2JqZWN0W10gdG9BcnJheSgpIHsKLSAgICAgICAgT2JqZWN0W10gYSA9IG5ldyBPYmplY3RbZkxlbmd0aF07Ci0gICAgICAgIHRvQXJyYXkwKGEpOwotICAgICAgICByZXR1cm4gYTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgT2JqZWN0W10gdG9BcnJheShPYmplY3RbXSBhKSB7Ci0gICAgICAgIGlmIChhLmxlbmd0aCA8IGZMZW5ndGgpIHsKLSAgICAgICAgICAgIENsYXNzIGFycmF5Q2xhc3MgPSBhLmdldENsYXNzKCk7Ci0gICAgICAgICAgICBDbGFzcyBjb21wb25lbnRUeXBlID0gYXJyYXlDbGFzcy5nZXRDb21wb25lbnRUeXBlKCk7Ci0gICAgICAgICAgICBhID0gKE9iamVjdFtdKSBBcnJheS5uZXdJbnN0YW5jZShjb21wb25lbnRUeXBlLCBmTGVuZ3RoKTsKLSAgICAgICAgfQotICAgICAgICB0b0FycmF5MChhKTsKLSAgICAgICAgaWYgKGEubGVuZ3RoID4gZkxlbmd0aCkgewotICAgICAgICAgICAgYVtmTGVuZ3RoXSA9IG51bGw7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGE7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIHRvQXJyYXkwKE9iamVjdFtdIGEpIHsKLSAgICAgICAgaWYgKGZMZW5ndGggPiAwKSB7Ci0gICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGZBcnJheSwgMCwgYSwgMCwgZkxlbmd0aCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwcml2YXRlIGZpbmFsIGNsYXNzIFhTT2JqZWN0TGlzdEl0ZXJhdG9yIGltcGxlbWVudHMgTGlzdEl0ZXJhdG9yIHsKLSAgICAgICAgcHJpdmF0ZSBpbnQgaW5kZXg7Ci0gICAgICAgIHB1YmxpYyBYU09iamVjdExpc3RJdGVyYXRvcihpbnQgaW5kZXgpIHsKLSAgICAgICAgICAgIHRoaXMuaW5kZXggPSBpbmRleDsKLSAgICAgICAgfQotICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNOZXh0KCkgewotICAgICAgICAgICAgcmV0dXJuIChpbmRleCA8IGZMZW5ndGgpOwotICAgICAgICB9Ci0gICAgICAgIHB1YmxpYyBPYmplY3QgbmV4dCgpIHsKLSAgICAgICAgICAgIGlmIChpbmRleCA8IGZMZW5ndGgpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZkFycmF5W2luZGV4KytdOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oKTsKLSAgICAgICAgfQotICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNQcmV2aW91cygpIHsKLSAgICAgICAgICAgIHJldHVybiAoaW5kZXggPiAwKTsKLSAgICAgICAgfQotICAgICAgICBwdWJsaWMgT2JqZWN0IHByZXZpb3VzKCkgewotICAgICAgICAgICAgaWYgKGluZGV4ID4gMCkgewotICAgICAgICAgICAgICAgIHJldHVybiBmQXJyYXlbLS1pbmRleF07Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbigpOwotICAgICAgICB9Ci0gICAgICAgIHB1YmxpYyBpbnQgbmV4dEluZGV4KCkgewotICAgICAgICAgICAgcmV0dXJuIGluZGV4OwotICAgICAgICB9Ci0gICAgICAgIHB1YmxpYyBpbnQgcHJldmlvdXNJbmRleCgpIHsKLSAgICAgICAgICAgIHJldHVybiBpbmRleCAtIDE7Ci0gICAgICAgIH0KLSAgICAgICAgcHVibGljIHZvaWQgcmVtb3ZlKCkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7Ci0gICAgICAgIH0KLSAgICAgICAgcHVibGljIHZvaWQgc2V0KE9iamVjdCBvKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKLSAgICAgICAgfQotICAgICAgICBwdWJsaWMgdm9pZCBhZGQoT2JqZWN0IG8pIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOwotICAgICAgICB9Ci0gICAgfQotCi19IC8vIGNsYXNzIFhTT2JqZWN0TGlzdEltcGwKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2pheHAvRGVmYXVsdFZhbGlkYXRpb25FcnJvckhhbmRsZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2pheHAvRGVmYXVsdFZhbGlkYXRpb25FcnJvckhhbmRsZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMGM4ZDBhOC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9qYXhwL0RlZmF1bHRWYWxpZGF0aW9uRXJyb3JIYW5kbGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw2MiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAwLTIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5qYXhwOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlNBWE1lc3NhZ2VGb3JtYXR0ZXI7Ci1pbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguaGVscGVycy5EZWZhdWx0SGFuZGxlcjsKLQotLyoqCi0gKi8KLQotY2xhc3MgRGVmYXVsdFZhbGlkYXRpb25FcnJvckhhbmRsZXIgZXh0ZW5kcyBEZWZhdWx0SGFuZGxlciB7Ci0gICAgc3RhdGljIHByaXZhdGUgaW50IEVSUk9SX0NPVU5UX0xJTUlUID0gMTA7Ci0gICAgcHJpdmF0ZSBpbnQgZXJyb3JDb3VudCA9IDA7Ci0gICAgcHJpdmF0ZSBMb2NhbGUgbG9jYWxlID0gTG9jYWxlLmdldERlZmF1bHQoKTsKLQotICAgIHB1YmxpYyBEZWZhdWx0VmFsaWRhdGlvbkVycm9ySGFuZGxlcihMb2NhbGUgbG9jYWxlKSB7Ci0gICAgICAgIHRoaXMubG9jYWxlID0gbG9jYWxlOwotICAgIH0KLQotICAgIC8vIFhYWCBGaXggbWVzc2FnZSBpMThuCi0gICAgcHVibGljIHZvaWQgZXJyb3IoU0FYUGFyc2VFeGNlcHRpb24gZSkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChlcnJvckNvdW50ID49IEVSUk9SX0NPVU5UX0xJTUlUKSB7Ci0gICAgICAgICAgICAvLyBJZ25vcmUgYWxsIGVycm9ycyBhZnRlciByZWFjaGluZyB0aGUgbGltaXQKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfSBlbHNlIGlmIChlcnJvckNvdW50ID09IDApIHsKLSAgICAgICAgICAgIC8vIFByaW50IGEgd2FybmluZyBiZWZvcmUgdGhlIGZpcnN0IGVycm9yCi0gICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oU0FYTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKGxvY2FsZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICJlcnJvckhhbmRsZXJOb3RTZXQiLCBuZXcgT2JqZWN0IFtdIHtlcnJvckNvdW50fSkpOwotICAgICAgICB9Ci0KLSAgICAgICAgU3RyaW5nIHN5c3RlbUlkID0gZS5nZXRTeXN0ZW1JZCgpOwotICAgICAgICBpZiAoc3lzdGVtSWQgPT0gbnVsbCkgewotICAgICAgICAgICAgc3lzdGVtSWQgPSAibnVsbCI7Ci0gICAgICAgIH0KLSAgICAgICAgU3RyaW5nIG1lc3NhZ2UgPSAiRXJyb3I6IFVSST0iICsgc3lzdGVtSWQgKwotICAgICAgICAgICAgIiBMaW5lPSIgKyBlLmdldExpbmVOdW1iZXIoKSArCi0gICAgICAgICAgICAiOiAiICsgZS5nZXRNZXNzYWdlKCk7Ci0gICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbihtZXNzYWdlKTsKLSAgICAgICAgZXJyb3JDb3VudCsrOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2pheHAvRG9jdW1lbnRCdWlsZGVyRmFjdG9yeUltcGwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2pheHAvRG9jdW1lbnRCdWlsZGVyRmFjdG9yeUltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZmQ5Mjk4Zi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9qYXhwL0RvY3VtZW50QnVpbGRlckZhY3RvcnlJbXBsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMjIgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqLwotLyoKLSAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQotICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCi0gKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCi0gKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAotICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKLSAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuamF4cDsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwucGFyc2Vycy5ET01QYXJzZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlNBWE1lc3NhZ2VGb3JtYXR0ZXI7Ci1pbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7Ci1pbXBvcnQgamF2YS51dGlsLk1hcDsKLWltcG9ydCBqYXZheC54bWwuWE1MQ29uc3RhbnRzOwotaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlcjsKLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5OwotaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLlBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci1pbXBvcnQgamF2YXgueG1sLnZhbGlkYXRpb24uU2NoZW1hOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbjsKLQotLyoqCi0gKiBAYXV0aG9yIFJhaml2IE1vcmRhbmkKLSAqIEBhdXRob3IgRWR3aW4gR29laQotICogQHZlcnNpb24gJElkOiBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5SW1wbC5qYXZhLHYgMS44IDIwMTAtMTEtMDEgMDQ6NDA6MDYgam9laHcgRXhwICQKLSAqLwotcHVibGljIGNsYXNzIERvY3VtZW50QnVpbGRlckZhY3RvcnlJbXBsIGV4dGVuZHMgRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB7Ci0gICAgLyoqIFRoZXNlIGFyZSBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGF0dHJpYnV0ZXMgbm90IERPTSBhdHRyaWJ1dGVzICovCi0gICAgcHJpdmF0ZSBNYXA8U3RyaW5nLCBPYmplY3Q+IGF0dHJpYnV0ZXM7Ci0gICAgcHJpdmF0ZSBNYXA8U3RyaW5nLCBCb29sZWFuPiBmZWF0dXJlczsKLSAgICBwcml2YXRlIFNjaGVtYSBncmFtbWFyOwotICAgIHByaXZhdGUgYm9vbGVhbiBpc1hJbmNsdWRlQXdhcmU7Ci0KLSAgICAvKioKLSAgICAgKiBTdGF0ZSBvZiB0aGUgc2VjdXJlIHByb2Nlc3NpbmcgZmVhdHVyZSwgaW5pdGlhbGx5IDxjb2RlPmZhbHNlPC9jb2RlPgotICAgICAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBmU2VjdXJlUHJvY2VzcyA9IHRydWU7Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIGEge0BsaW5rIGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlcn0KLSAgICAgKiB1c2luZyB0aGUgY3VycmVudGx5IGNvbmZpZ3VyZWQgcGFyYW1ldGVycy4KLSAgICAgKi8KLSAgICBwdWJsaWMgRG9jdW1lbnRCdWlsZGVyIG5ld0RvY3VtZW50QnVpbGRlcigpCi0gICAgICAgIHRocm93cyBQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uCi0gICAgewotICAgICAgICAvKiogQ2hlY2sgdGhhdCBpZiBhIFNjaGVtYSBoYXMgYmVlbiBzcGVjaWZpZWQgdGhhdCBuZWl0aGVyIG9mIHRoZSBzY2hlbWEgcHJvcGVydGllcyBoYXZlIGJlZW4gc2V0LiAqLwotICAgICAgICBpZiAoZ3JhbW1hciAhPSBudWxsICYmIGF0dHJpYnV0ZXMgIT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKGF0dHJpYnV0ZXMuY29udGFpbnNLZXkoSkFYUENvbnN0YW50cy5KQVhQX1NDSEVNQV9MQU5HVUFHRSkpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgICAgIFNBWE1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShudWxsLAotICAgICAgICAgICAgICAgICAgICAgICAgInNjaGVtYS1hbHJlYWR5LXNwZWNpZmllZCIsIG5ldyBPYmplY3RbXSB7SkFYUENvbnN0YW50cy5KQVhQX1NDSEVNQV9MQU5HVUFHRX0pKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKGF0dHJpYnV0ZXMuY29udGFpbnNLZXkoSkFYUENvbnN0YW50cy5KQVhQX1NDSEVNQV9TT1VSQ0UpKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgICAgICBTQVhNZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UobnVsbCwKLSAgICAgICAgICAgICAgICAgICAgICAgICJzY2hlbWEtYWxyZWFkeS1zcGVjaWZpZWQiLCBuZXcgT2JqZWN0W10ge0pBWFBDb25zdGFudHMuSkFYUF9TQ0hFTUFfU09VUkNFfSkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIHJldHVybiBuZXcgRG9jdW1lbnRCdWlsZGVySW1wbCh0aGlzLCBhdHRyaWJ1dGVzLCBmZWF0dXJlcywgZlNlY3VyZVByb2Nlc3MpOwotICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gc2UpIHsKLSAgICAgICAgICAgIC8vIEhhbmRsZXMgYm90aCBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24sIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24KLSAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uKHNlLmdldE1lc3NhZ2UoKSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBbGxvd3MgdGhlIHVzZXIgdG8gc2V0IHNwZWNpZmljIGF0dHJpYnV0ZXMgb24gdGhlIHVuZGVybHlpbmcKLSAgICAgKiBpbXBsZW1lbnRhdGlvbi4KLSAgICAgKiBAcGFyYW0gbmFtZSAgICBuYW1lIG9mIGF0dHJpYnV0ZQotICAgICAqIEBwYXJhbSB2YWx1ZSAgIG51bGwgbWVhbnMgdG8gcmVtb3ZlIGF0dHJpYnV0ZQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEF0dHJpYnV0ZShTdHJpbmcgbmFtZSwgT2JqZWN0IHZhbHVlKQotICAgICAgICB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCi0gICAgewotICAgICAgICAvLyBUaGlzIGhhbmRsZXMgcmVtb3ZhbCBvZiBhdHRyaWJ1dGVzCi0gICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAoYXR0cmlidXRlcyAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgYXR0cmlidXRlcy5yZW1vdmUobmFtZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyBVbnJlY29nbml6ZWQgYXR0cmlidXRlcyBkbyBub3QgY2F1c2UgYW4gZXhjZXB0aW9uCi0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBUaGlzIGlzIHVnbHkuICBXZSBoYXZlIHRvIGNvbGxlY3QgdGhlIGF0dHJpYnV0ZXMgYW5kIHRoZW4KLSAgICAgICAgLy8gbGF0ZXIgY3JlYXRlIGEgRG9jdW1lbnRCdWlsZGVySW1wbCB0byB2ZXJpZnkgdGhlIGF0dHJpYnV0ZXMuCi0KLSAgICAgICAgLy8gQ3JlYXRlIHRoZSBNYXAgaWYgbm9uZSBleGlzdGVkIGJlZm9yZQotICAgICAgICBpZiAoYXR0cmlidXRlcyA9PSBudWxsKSB7Ci0gICAgICAgICAgICBhdHRyaWJ1dGVzID0gbmV3IEhhc2hNYXA8PigpOwotICAgICAgICB9Ci0KLSAgICAgICAgYXR0cmlidXRlcy5wdXQobmFtZSwgdmFsdWUpOwotCi0gICAgICAgIC8vIFRlc3QgdGhlIGF0dHJpYnV0ZSBuYW1lIGJ5IHBvc3NpYmx5IHRocm93aW5nIGFuIGV4Y2VwdGlvbgotICAgICAgICB0cnkgewotICAgICAgICAgICAgbmV3IERvY3VtZW50QnVpbGRlckltcGwodGhpcywgYXR0cmlidXRlcywgZmVhdHVyZXMpOwotICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgYXR0cmlidXRlcy5yZW1vdmUobmFtZSk7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKGUuZ2V0TWVzc2FnZSgpKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEFsbG93cyB0aGUgdXNlciB0byByZXRyaWV2ZSBzcGVjaWZpYyBhdHRyaWJ1dGVzIG9uIHRoZSB1bmRlcmx5aW5nCi0gICAgICogaW1wbGVtZW50YXRpb24uCi0gICAgICovCi0gICAgcHVibGljIE9iamVjdCBnZXRBdHRyaWJ1dGUoU3RyaW5nIG5hbWUpCi0gICAgICAgIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIC8vIFNlZSBpZiBpdCdzIGluIHRoZSBhdHRyaWJ1dGVzIE1hcAotICAgICAgICBpZiAoYXR0cmlidXRlcyAhPSBudWxsKSB7Ci0gICAgICAgICAgICBPYmplY3QgdmFsID0gYXR0cmlidXRlcy5nZXQobmFtZSk7Ci0gICAgICAgICAgICBpZiAodmFsICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gdmFsOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgRE9NUGFyc2VyIGRvbVBhcnNlciA9IG51bGw7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAvLyBXZSBjcmVhdGUgYSBkdW1teSBEb2N1bWVudEJ1aWxkZXJJbXBsIGluIGNhc2UgdGhlIGF0dHJpYnV0ZQotICAgICAgICAgICAgLy8gbmFtZSBpcyBub3Qgb25lIHRoYXQgaXMgaW4gdGhlIGF0dHJpYnV0ZXMgbWFwLgotICAgICAgICAgICAgZG9tUGFyc2VyID0KLSAgICAgICAgICAgICAgICBuZXcgRG9jdW1lbnRCdWlsZGVySW1wbCh0aGlzLCBhdHRyaWJ1dGVzLCBmZWF0dXJlcykuZ2V0RE9NUGFyc2VyKCk7Ci0gICAgICAgICAgICByZXR1cm4gZG9tUGFyc2VyLmdldFByb3BlcnR5KG5hbWUpOwotICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gc2UxKSB7Ci0gICAgICAgICAgICAvLyBhc3NlcnQobmFtZSBpcyBub3QgcmVjb2duaXplZCBvciBub3Qgc3VwcG9ydGVkKSwgdHJ5IGZlYXR1cmUKLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgYm9vbGVhbiByZXN1bHQgPSBkb21QYXJzZXIuZ2V0RmVhdHVyZShuYW1lKTsKLSAgICAgICAgICAgICAgICAvLyBNdXN0IGhhdmUgYmVlbiBhIGZlYXR1cmUKLSAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0ID8gQm9vbGVhbi5UUlVFIDogQm9vbGVhbi5GQUxTRTsKLSAgICAgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBzZTIpIHsKLSAgICAgICAgICAgICAgICAvLyBOb3QgYSBwcm9wZXJ0eSBvciBhIGZlYXR1cmUKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKHNlMS5nZXRNZXNzYWdlKCkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIFNjaGVtYSBnZXRTY2hlbWEoKSB7Ci0gICAgICAgIHJldHVybiBncmFtbWFyOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldFNjaGVtYShTY2hlbWEgZ3JhbW1hcikgewotICAgICAgICB0aGlzLmdyYW1tYXIgPSBncmFtbWFyOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGlzWEluY2x1ZGVBd2FyZSgpIHsKLSAgICAgICAgcmV0dXJuIHRoaXMuaXNYSW5jbHVkZUF3YXJlOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldFhJbmNsdWRlQXdhcmUoYm9vbGVhbiBzdGF0ZSkgewotICAgICAgICB0aGlzLmlzWEluY2x1ZGVBd2FyZSA9IHN0YXRlOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGdldEZlYXR1cmUoU3RyaW5nIG5hbWUpCi0gICAgICAgIHRocm93cyBQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKG5hbWUuZXF1YWxzKFhNTENvbnN0YW50cy5GRUFUVVJFX1NFQ1VSRV9QUk9DRVNTSU5HKSkgewotICAgICAgICAgICAgcmV0dXJuIGZTZWN1cmVQcm9jZXNzOwotICAgICAgICB9Ci0gICAgICAgIC8vIFNlZSBpZiBpdCdzIGluIHRoZSBmZWF0dXJlcyBtYXAKLSAgICAgICAgaWYgKGZlYXR1cmVzICE9IG51bGwpIHsKLSAgICAgICAgICAgIEJvb2xlYW4gdmFsID0gZmVhdHVyZXMuZ2V0KG5hbWUpOwotICAgICAgICAgICAgaWYgKHZhbCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHZhbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICB0cnkgewotICAgICAgICAgICAgRE9NUGFyc2VyIGRvbVBhcnNlciA9IG5ldyBEb2N1bWVudEJ1aWxkZXJJbXBsKHRoaXMsIGF0dHJpYnV0ZXMsIGZlYXR1cmVzKS5nZXRET01QYXJzZXIoKTsKLSAgICAgICAgICAgIHJldHVybiBkb21QYXJzZXIuZ2V0RmVhdHVyZShuYW1lKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uKGUuZ2V0TWVzc2FnZSgpKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldEZlYXR1cmUoU3RyaW5nIG5hbWUsIGJvb2xlYW4gdmFsdWUpCi0gICAgICAgIHRocm93cyBQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKGZlYXR1cmVzID09IG51bGwpIHsKLSAgICAgICAgICAgIGZlYXR1cmVzID0gbmV3IEhhc2hNYXA8PigpOwotICAgICAgICB9Ci0gICAgICAgIC8vIElmIHRoaXMgaXMgdGhlIHNlY3VyZSBwcm9jZXNzaW5nIGZlYXR1cmUsIHNhdmUgaXQgdGhlbiByZXR1cm4uCi0gICAgICAgIGlmIChuYW1lLmVxdWFscyhYTUxDb25zdGFudHMuRkVBVFVSRV9TRUNVUkVfUFJPQ0VTU0lORykpIHsKLSAgICAgICAgICAgIGlmIChTeXN0ZW0uZ2V0U2VjdXJpdHlNYW5hZ2VyKCkgIT0gbnVsbCAmJiAoIXZhbHVlKSkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICAgICAgU0FYTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKG51bGwsCi0gICAgICAgICAgICAgICAgICAgICAgICAiamF4cC1zZWN1cmVwcm9jZXNzaW5nLWZlYXR1cmUiLCBudWxsKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmU2VjdXJlUHJvY2VzcyA9IHZhbHVlOwotICAgICAgICAgICAgZmVhdHVyZXMucHV0KG5hbWUsIHZhbHVlID8gQm9vbGVhbi5UUlVFIDogQm9vbGVhbi5GQUxTRSk7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLQotICAgICAgICBmZWF0dXJlcy5wdXQobmFtZSwgdmFsdWUgPyBCb29sZWFuLlRSVUUgOiBCb29sZWFuLkZBTFNFKTsKLSAgICAgICAgLy8gVGVzdCB0aGUgZmVhdHVyZSBieSBwb3NzaWJseSB0aHJvd2luZyBTQVggZXhjZXB0aW9ucwotICAgICAgICB0cnkgewotICAgICAgICAgICAgbmV3IERvY3VtZW50QnVpbGRlckltcGwodGhpcywgYXR0cmlidXRlcywgZmVhdHVyZXMpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgZmVhdHVyZXMucmVtb3ZlKG5hbWUpOwotICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24oZS5nZXRNZXNzYWdlKCkpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIGZlYXR1cmVzLnJlbW92ZShuYW1lKTsKLSAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uKGUuZ2V0TWVzc2FnZSgpKTsKLSAgICAgICAgfQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2pheHAvRG9jdW1lbnRCdWlsZGVySW1wbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvamF4cC9Eb2N1bWVudEJ1aWxkZXJJbXBsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGI1MjM4NjYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvamF4cC9Eb2N1bWVudEJ1aWxkZXJJbXBsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0MTMgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwNywgMjAxNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqLwotLyoKLSAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQotICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCi0gKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCi0gKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAotICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKLSAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuamF4cDsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tLkRPTUltcGxlbWVudGF0aW9uSW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbS5ET01NZXNzYWdlRm9ybWF0dGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5Db25zdGFudHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnZhbGlkYXRpb24uVmFsaWRhdGlvbk1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlhNTFNjaGVtYVZhbGlkYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmpheHAudmFsaWRhdGlvbi5YU0dyYW1tYXJQb29sQ29udGFpbmVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwucGFyc2Vycy5ET01QYXJzZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlscy5YTUxTZWN1cml0eU1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlscy5YTUxTZWN1cml0eVByb3BlcnR5TWFuYWdlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWxzLlhNTFNlY3VyaXR5UHJvcGVydHlNYW5hZ2VyLlByb3BlcnR5OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbHMuWE1MU2VjdXJpdHlQcm9wZXJ0eU1hbmFnZXIuU3RhdGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MRG9jdW1lbnRIYW5kbGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxDb21wb25lbnQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTENvbXBvbmVudE1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTERvY3VtZW50U291cmNlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxQYXJzZXJDb25maWd1cmF0aW9uOwotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci1pbXBvcnQgamF2YS51dGlsLk1hcDsKLWltcG9ydCBqYXZheC54bWwuWE1MQ29uc3RhbnRzOwotaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlcjsKLWltcG9ydCBqYXZheC54bWwudmFsaWRhdGlvbi5TY2hlbWE7Ci1pbXBvcnQgb3JnLnczYy5kb20uRE9NSW1wbGVtZW50YXRpb247Ci1pbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7Ci1pbXBvcnQgb3JnLnhtbC5zYXguRW50aXR5UmVzb2x2ZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguRXJyb3JIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LklucHV0U291cmNlOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbjsKLQotLyoqCi0gKiBAYXV0aG9yIFJhaml2IE1vcmRhbmkKLSAqIEBhdXRob3IgRWR3aW4gR29laQotICogQHZlcnNpb24gJElkOiBEb2N1bWVudEJ1aWxkZXJJbXBsLmphdmEsdiAxLjggMjAxMC0xMS0wMSAwNDo0MDowNiBqb2VodyBFeHAgJAotICovCi1wdWJsaWMgY2xhc3MgRG9jdW1lbnRCdWlsZGVySW1wbCBleHRlbmRzIERvY3VtZW50QnVpbGRlcgotICAgICAgICBpbXBsZW1lbnRzIEpBWFBDb25zdGFudHMKLXsKLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiBuYW1lc3BhY2VzLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBOQU1FU1BBQ0VTX0ZFQVRVUkUgPQotICAgICAgICBDb25zdGFudHMuU0FYX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLk5BTUVTUEFDRVNfRkVBVFVSRTsKLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IGluY2x1ZGUgaWdub3JhYmxlIHdoaXRlIHNwYWNlLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBJTkNMVURFX0lHTk9SQUJMRV9XSElURVNQQUNFID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5JTkNMVURFX0lHTk9SQUJMRV9XSElURVNQQUNFOwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogY3JlYXRlIGVudGlyeSByZWYgbm9kZXMgZmVhdHVyZS4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ1JFQVRFX0VOVElUWV9SRUZfTk9ERVNfRkVBVFVSRSA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuQ1JFQVRFX0VOVElUWV9SRUZfTk9ERVNfRkVBVFVSRTsKLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IGluY2x1ZGUgY29tbWVudHMgZmVhdHVyZS4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgSU5DTFVERV9DT01NRU5UU19GRUFUVVJFID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5JTkNMVURFX0NPTU1FTlRTX0ZFQVRVUkU7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiBjcmVhdGUgY2RhdGEgbm9kZXMgZmVhdHVyZS4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ1JFQVRFX0NEQVRBX05PREVTX0ZFQVRVUkUgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLkNSRUFURV9DREFUQV9OT0RFU19GRUFUVVJFOwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogWEluY2x1ZGUgcHJvY2Vzc2luZyAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBYSU5DTFVERV9GRUFUVVJFID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5YSU5DTFVERV9GRUFUVVJFOwotCi0gICAgLyoqIGZlYXR1cmUgaWRlbnRpZmllcjogWE1MIFNjaGVtYSB2YWxpZGF0aW9uICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFhNTFNDSEVNQV9WQUxJREFUSU9OX0ZFQVRVUkUgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLlNDSEVNQV9WQUxJREFUSU9OX0ZFQVRVUkU7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiB2YWxpZGF0aW9uICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFZBTElEQVRJT05fRkVBVFVSRSA9Ci0gICAgICAgIENvbnN0YW50cy5TQVhfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuVkFMSURBVElPTl9GRUFUVVJFOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IHNlY3VyaXR5IG1hbmFnZXIuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFNFQ1VSSVRZX01BTkFHRVIgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5TRUNVUklUWV9NQU5BR0VSX1BST1BFUlRZOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IFNlY3VyaXR5IHByb3BlcnR5IG1hbmFnZXIuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFhNTF9TRUNVUklUWV9QUk9QRVJUWV9NQU5BR0VSID0KLSAgICAgICAgICAgIENvbnN0YW50cy5YTUxfU0VDVVJJVFlfUFJPUEVSVFlfTUFOQUdFUjsKLQotICAgIC8qKiBwcm9wZXJ0eSBpZGVudGlmaWVyOiBhY2Nlc3MgZXh0ZXJuYWwgZHRkLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEFDQ0VTU19FWFRFUk5BTF9EVEQgPSBYTUxDb25zdGFudHMuQUNDRVNTX0VYVEVSTkFMX0RURDsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBhY2Nlc3MgdG8gZXh0ZXJuYWwgc2NoZW1hICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQUNDRVNTX0VYVEVSTkFMX1NDSEVNQSA9IFhNTENvbnN0YW50cy5BQ0NFU1NfRVhURVJOQUxfU0NIRU1BOwotCi0KLSAgICBwcml2YXRlIGZpbmFsIERPTVBhcnNlciBkb21QYXJzZXI7Ci0gICAgcHJpdmF0ZSBmaW5hbCBTY2hlbWEgZ3JhbW1hcjsKLQotICAgIHByaXZhdGUgZmluYWwgWE1MQ29tcG9uZW50IGZTY2hlbWFWYWxpZGF0b3I7Ci0gICAgcHJpdmF0ZSBmaW5hbCBYTUxDb21wb25lbnRNYW5hZ2VyIGZTY2hlbWFWYWxpZGF0b3JDb21wb25lbnRNYW5hZ2VyOwotICAgIHByaXZhdGUgZmluYWwgVmFsaWRhdGlvbk1hbmFnZXIgZlNjaGVtYVZhbGlkYXRpb25NYW5hZ2VyOwotICAgIHByaXZhdGUgZmluYWwgVW5wYXJzZWRFbnRpdHlIYW5kbGVyIGZVbnBhcnNlZEVudGl0eUhhbmRsZXI7Ci0KLSAgICAvKiogSW5pdGlhbCBFcnJvckhhbmRsZXIgKi8KLSAgICBwcml2YXRlIGZpbmFsIEVycm9ySGFuZGxlciBmSW5pdEVycm9ySGFuZGxlcjsKLQotICAgIC8qKiBJbml0aWFsIEVudGl0eVJlc29sdmVyICovCi0gICAgcHJpdmF0ZSBmaW5hbCBFbnRpdHlSZXNvbHZlciBmSW5pdEVudGl0eVJlc29sdmVyOwotCi0gICAgcHJpdmF0ZSBYTUxTZWN1cml0eU1hbmFnZXIgZlNlY3VyaXR5TWFuYWdlcjsKLSAgICBwcml2YXRlIFhNTFNlY3VyaXR5UHJvcGVydHlNYW5hZ2VyIGZTZWN1cml0eVByb3BlcnR5TWdyOwotCi0gICAgRG9jdW1lbnRCdWlsZGVySW1wbChEb2N1bWVudEJ1aWxkZXJGYWN0b3J5SW1wbCBkYmYsIE1hcDxTdHJpbmcsIE9iamVjdD4gZGJmQXR0cnMsCi0gICAgICAgICAgICBNYXA8U3RyaW5nLCBCb29sZWFuPiBmZWF0dXJlcykKLSAgICAgICAgdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiB7Ci0gICAgICAgIHRoaXMoZGJmLCBkYmZBdHRycywgZmVhdHVyZXMsIGZhbHNlKTsKLSAgICB9Ci0KLSAgICBEb2N1bWVudEJ1aWxkZXJJbXBsKERvY3VtZW50QnVpbGRlckZhY3RvcnlJbXBsIGRiZiwgTWFwPFN0cmluZywgT2JqZWN0PiBkYmZBdHRycywKLSAgICAgICAgICAgIE1hcDxTdHJpbmcsIEJvb2xlYW4+IGZlYXR1cmVzLCBib29sZWFuIHNlY3VyZVByb2Nlc3NpbmcpCi0gICAgICAgIHRocm93cyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uLCBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGRvbVBhcnNlciA9IG5ldyBET01QYXJzZXIoKTsKLQotICAgICAgICAvLyBJZiB2YWxpZGF0aW5nLCBwcm92aWRlIGEgZGVmYXVsdCBFcnJvckhhbmRsZXIgdGhhdCBwcmludHMKLSAgICAgICAgLy8gdmFsaWRhdGlvbiBlcnJvcnMgd2l0aCBhIHdhcm5pbmcgdGVsbGluZyB0aGUgdXNlciB0byBzZXQgYW4KLSAgICAgICAgLy8gRXJyb3JIYW5kbGVyCi0gICAgICAgIGlmIChkYmYuaXNWYWxpZGF0aW5nKCkpIHsKLSAgICAgICAgICAgIGZJbml0RXJyb3JIYW5kbGVyID0gbmV3IERlZmF1bHRWYWxpZGF0aW9uRXJyb3JIYW5kbGVyKGRvbVBhcnNlci5nZXRYTUxQYXJzZXJDb25maWd1cmF0aW9uKCkuZ2V0TG9jYWxlKCkpOwotICAgICAgICAgICAgc2V0RXJyb3JIYW5kbGVyKGZJbml0RXJyb3JIYW5kbGVyKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIGZJbml0RXJyb3JIYW5kbGVyID0gZG9tUGFyc2VyLmdldEVycm9ySGFuZGxlcigpOwotICAgICAgICB9Ci0KLSAgICAgICAgZG9tUGFyc2VyLnNldEZlYXR1cmUoVkFMSURBVElPTl9GRUFUVVJFLCBkYmYuaXNWYWxpZGF0aW5nKCkpOwotCi0gICAgICAgIC8vICJuYW1lc3BhY2VBd2FyZSIgPT0gU0FYIE5hbWVzcGFjZXMgZmVhdHVyZQotICAgICAgICBkb21QYXJzZXIuc2V0RmVhdHVyZShOQU1FU1BBQ0VTX0ZFQVRVUkUsIGRiZi5pc05hbWVzcGFjZUF3YXJlKCkpOwotCi0gICAgICAgIC8vIFNldCB2YXJpb3VzIHBhcmFtZXRlcnMgb2J0YWluZWQgZnJvbSBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5Ci0gICAgICAgIGRvbVBhcnNlci5zZXRGZWF0dXJlKElOQ0xVREVfSUdOT1JBQkxFX1dISVRFU1BBQ0UsCi0gICAgICAgICAgICAgICAgIWRiZi5pc0lnbm9yaW5nRWxlbWVudENvbnRlbnRXaGl0ZXNwYWNlKCkpOwotICAgICAgICBkb21QYXJzZXIuc2V0RmVhdHVyZShDUkVBVEVfRU5USVRZX1JFRl9OT0RFU19GRUFUVVJFLAotICAgICAgICAgICAgICAgICFkYmYuaXNFeHBhbmRFbnRpdHlSZWZlcmVuY2VzKCkpOwotICAgICAgICBkb21QYXJzZXIuc2V0RmVhdHVyZShJTkNMVURFX0NPTU1FTlRTX0ZFQVRVUkUsCi0gICAgICAgICAgICAgICAgIWRiZi5pc0lnbm9yaW5nQ29tbWVudHMoKSk7Ci0gICAgICAgIGRvbVBhcnNlci5zZXRGZWF0dXJlKENSRUFURV9DREFUQV9OT0RFU19GRUFUVVJFLAotICAgICAgICAgICAgICAgICFkYmYuaXNDb2FsZXNjaW5nKCkpOwotCi0gICAgICAgIC8vIEF2b2lkIHNldHRpbmcgdGhlIFhJbmNsdWRlIHByb2Nlc3NpbmcgZmVhdHVyZSBpZiB0aGUgdmFsdWUgaXMgZmFsc2UuCi0gICAgICAgIC8vIFRoaXMgd2lsbCBrZWVwIHRoZSBjb25maWd1cmF0aW9uIGZyb20gdGhyb3dpbmcgYW4gZXhjZXB0aW9uIGlmIGl0Ci0gICAgICAgIC8vIGRvZXMgbm90IHN1cHBvcnQgWEluY2x1ZGUuCi0gICAgICAgIGlmIChkYmYuaXNYSW5jbHVkZUF3YXJlKCkpIHsKLSAgICAgICAgICAgIGRvbVBhcnNlci5zZXRGZWF0dXJlKFhJTkNMVURFX0ZFQVRVUkUsIHRydWUpOwotICAgICAgICB9Ci0KLSAgICAgICAgZlNlY3VyaXR5UHJvcGVydHlNZ3IgPSBuZXcgWE1MU2VjdXJpdHlQcm9wZXJ0eU1hbmFnZXIoKTsKLSAgICAgICAgZG9tUGFyc2VyLnNldFByb3BlcnR5KFhNTF9TRUNVUklUWV9QUk9QRVJUWV9NQU5BR0VSLCBmU2VjdXJpdHlQcm9wZXJ0eU1ncik7Ci0KLSAgICAgICAgZlNlY3VyaXR5TWFuYWdlciA9IG5ldyBYTUxTZWN1cml0eU1hbmFnZXIoc2VjdXJlUHJvY2Vzc2luZyk7Ci0gICAgICAgIGRvbVBhcnNlci5zZXRQcm9wZXJ0eShTRUNVUklUWV9NQU5BR0VSLCBmU2VjdXJpdHlNYW5hZ2VyKTsKLQotICAgICAgICBpZiAoc2VjdXJlUHJvY2Vzc2luZykgewotICAgICAgICAgICAgLyoqCi0gICAgICAgICAgICAgKiBJZiBzZWN1cmUgcHJvY2Vzc2luZyBpcyBleHBsaWNpdGx5IHNldCBvbiB0aGUgZmFjdG9yeSwgdGhlCi0gICAgICAgICAgICAgKiBhY2Nlc3MgcHJvcGVydGllcyB3aWxsIGJlIHNldCB1bmxlc3MgdGhlIGNvcnJlc3BvbmRpbmcKLSAgICAgICAgICAgICAqIFN5c3RlbSBQcm9wZXJ0aWVzIG9yIGpheHAucHJvcGVydGllcyBhcmUgc2V0Ci0gICAgICAgICAgICAgKi8KLSAgICAgICAgICAgIGlmIChmZWF0dXJlcyAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgQm9vbGVhbiB0ZW1wID0gZmVhdHVyZXMuZ2V0KFhNTENvbnN0YW50cy5GRUFUVVJFX1NFQ1VSRV9QUk9DRVNTSU5HKTsKLSAgICAgICAgICAgICAgICBpZiAodGVtcCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmICh0ZW1wICYmIENvbnN0YW50cy5JU19KREs4X09SX0FCT1ZFKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmU2VjdXJpdHlQcm9wZXJ0eU1nci5zZXRWYWx1ZShQcm9wZXJ0eS5BQ0NFU1NfRVhURVJOQUxfRFRELAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdGF0ZS5GU1AsIENvbnN0YW50cy5FWFRFUk5BTF9BQ0NFU1NfREVGQVVMVF9GU1ApOwotICAgICAgICAgICAgICAgICAgICAgICAgZlNlY3VyaXR5UHJvcGVydHlNZ3Iuc2V0VmFsdWUoUHJvcGVydHkuQUNDRVNTX0VYVEVSTkFMX1NDSEVNQSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RhdGUuRlNQLCBDb25zdGFudHMuRVhURVJOQUxfQUNDRVNTX0RFRkFVTFRfRlNQKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHRoaXMuZ3JhbW1hciA9IGRiZi5nZXRTY2hlbWEoKTsKLSAgICAgICAgaWYgKGdyYW1tYXIgIT0gbnVsbCkgewotICAgICAgICAgICAgWE1MUGFyc2VyQ29uZmlndXJhdGlvbiBjb25maWcgPSBkb21QYXJzZXIuZ2V0WE1MUGFyc2VyQ29uZmlndXJhdGlvbigpOwotICAgICAgICAgICAgWE1MQ29tcG9uZW50IHZhbGlkYXRvckNvbXBvbmVudCA9IG51bGw7Ci0gICAgICAgICAgICAvKiogRm9yIFhlcmNlcyBncmFtbWFycywgdXNlIGJ1aWx0LWluIHNjaGVtYSB2YWxpZGF0b3IuICoqLwotICAgICAgICAgICAgaWYgKGdyYW1tYXIgaW5zdGFuY2VvZiBYU0dyYW1tYXJQb29sQ29udGFpbmVyKSB7Ci0gICAgICAgICAgICAgICAgdmFsaWRhdG9yQ29tcG9uZW50ID0gbmV3IFhNTFNjaGVtYVZhbGlkYXRvcigpOwotICAgICAgICAgICAgICAgIGZTY2hlbWFWYWxpZGF0aW9uTWFuYWdlciA9IG5ldyBWYWxpZGF0aW9uTWFuYWdlcigpOwotICAgICAgICAgICAgICAgIGZVbnBhcnNlZEVudGl0eUhhbmRsZXIgPSBuZXcgVW5wYXJzZWRFbnRpdHlIYW5kbGVyKGZTY2hlbWFWYWxpZGF0aW9uTWFuYWdlcik7Ci0gICAgICAgICAgICAgICAgY29uZmlnLnNldERUREhhbmRsZXIoZlVucGFyc2VkRW50aXR5SGFuZGxlcik7Ci0gICAgICAgICAgICAgICAgZlVucGFyc2VkRW50aXR5SGFuZGxlci5zZXREVERIYW5kbGVyKGRvbVBhcnNlcik7Ci0gICAgICAgICAgICAgICAgZG9tUGFyc2VyLnNldERURFNvdXJjZShmVW5wYXJzZWRFbnRpdHlIYW5kbGVyKTsKLSAgICAgICAgICAgICAgICBmU2NoZW1hVmFsaWRhdG9yQ29tcG9uZW50TWFuYWdlciA9IG5ldyBTY2hlbWFWYWxpZGF0b3JDb25maWd1cmF0aW9uKGNvbmZpZywKLSAgICAgICAgICAgICAgICAgICAgICAgIChYU0dyYW1tYXJQb29sQ29udGFpbmVyKSBncmFtbWFyLCBmU2NoZW1hVmFsaWRhdGlvbk1hbmFnZXIpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLyoqIEZvciB0aGlyZCBwYXJ0eSBncmFtbWFycywgdXNlIHRoZSBKQVhQIHZhbGlkYXRvciBjb21wb25lbnQuICoqLwotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgdmFsaWRhdG9yQ29tcG9uZW50ID0gbmV3IEpBWFBWYWxpZGF0b3JDb21wb25lbnQoZ3JhbW1hci5uZXdWYWxpZGF0b3JIYW5kbGVyKCkpOwotICAgICAgICAgICAgICAgIGZTY2hlbWFWYWxpZGF0aW9uTWFuYWdlciA9IG51bGw7Ci0gICAgICAgICAgICAgICAgZlVucGFyc2VkRW50aXR5SGFuZGxlciA9IG51bGw7Ci0gICAgICAgICAgICAgICAgZlNjaGVtYVZhbGlkYXRvckNvbXBvbmVudE1hbmFnZXIgPSBjb25maWc7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjb25maWcuYWRkUmVjb2duaXplZEZlYXR1cmVzKHZhbGlkYXRvckNvbXBvbmVudC5nZXRSZWNvZ25pemVkRmVhdHVyZXMoKSk7Ci0gICAgICAgICAgICBjb25maWcuYWRkUmVjb2duaXplZFByb3BlcnRpZXModmFsaWRhdG9yQ29tcG9uZW50LmdldFJlY29nbml6ZWRQcm9wZXJ0aWVzKCkpOwotICAgICAgICAgICAgc2V0RmVhdHVyZXMoZmVhdHVyZXMpOyAgICAgIC8vIE11c3Qgc2V0IGJlZm9yZSBjYWxsaW5nIHNldERvY3VtZW50SGFuZGxlcigpCi0gICAgICAgICAgICBjb25maWcuc2V0RG9jdW1lbnRIYW5kbGVyKChYTUxEb2N1bWVudEhhbmRsZXIpIHZhbGlkYXRvckNvbXBvbmVudCk7Ci0gICAgICAgICAgICAoKFhNTERvY3VtZW50U291cmNlKXZhbGlkYXRvckNvbXBvbmVudCkuc2V0RG9jdW1lbnRIYW5kbGVyKGRvbVBhcnNlcik7Ci0gICAgICAgICAgICBkb21QYXJzZXIuc2V0RG9jdW1lbnRTb3VyY2UoKFhNTERvY3VtZW50U291cmNlKSB2YWxpZGF0b3JDb21wb25lbnQpOwotICAgICAgICAgICAgZlNjaGVtYVZhbGlkYXRvciA9IHZhbGlkYXRvckNvbXBvbmVudDsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIGZTY2hlbWFWYWxpZGF0aW9uTWFuYWdlciA9IG51bGw7Ci0gICAgICAgICAgICBmVW5wYXJzZWRFbnRpdHlIYW5kbGVyID0gbnVsbDsKLSAgICAgICAgICAgIGZTY2hlbWFWYWxpZGF0b3JDb21wb25lbnRNYW5hZ2VyID0gbnVsbDsKLSAgICAgICAgICAgIGZTY2hlbWFWYWxpZGF0b3IgPSBudWxsOwotICAgICAgICAgICAgc2V0RmVhdHVyZXMoZmVhdHVyZXMpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy9zZXRBdHRyaWJ1dGUgb3ZlcnJpZGUgdGhvc2UgdGhhdCBtYXkgYmUgc2V0IGJ5IG90aGVyIG1lYW5zCi0gICAgICAgIHNldERvY3VtZW50QnVpbGRlckZhY3RvcnlBdHRyaWJ1dGVzKGRiZkF0dHJzKTsKLQotICAgICAgICAvLyBJbml0aWFsIEVudGl0eVJlc29sdmVyCi0gICAgICAgIGZJbml0RW50aXR5UmVzb2x2ZXIgPSBkb21QYXJzZXIuZ2V0RW50aXR5UmVzb2x2ZXIoKTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgc2V0RmVhdHVyZXMoIE1hcDxTdHJpbmcsIEJvb2xlYW4+IGZlYXR1cmVzKQotICAgICAgICB0aHJvd3MgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uLCBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKGZlYXR1cmVzICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZvciAoTWFwLkVudHJ5PFN0cmluZywgQm9vbGVhbj4gZW50cnkgOiBmZWF0dXJlcy5lbnRyeVNldCgpKSB7Ci0gICAgICAgICAgICAgICAgZG9tUGFyc2VyLnNldEZlYXR1cmUoZW50cnkuZ2V0S2V5KCksIGVudHJ5LmdldFZhbHVlKCkpOwotICAgICAgICB9Ci0gICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldCBhbnkgRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBhdHRyaWJ1dGVzIG9mIG91ciB1bmRlcmx5aW5nIERPTVBhcnNlcgotICAgICAqCi0gICAgICogTm90ZTogY29kZSBkb2VzIG5vdCBoYW5kbGUgcG9zc2libGUgY29uZmxpY3RzIGJldHdlZW4gRE9NUGFyc2VyCi0gICAgICogYXR0cmlidXRlIG5hbWVzIGFuZCBKQVhQIHNwZWNpZmljIGF0dHJpYnV0ZSBuYW1lcywKLSAgICAgKiBlZy4gRG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5zZXRWYWxpZGF0aW5nKCkKLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgc2V0RG9jdW1lbnRCdWlsZGVyRmFjdG9yeUF0dHJpYnV0ZXMoIE1hcDxTdHJpbmcsIE9iamVjdD4gZGJmQXR0cnMpCi0gICAgICAgIHRocm93cyBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24sIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGlmIChkYmZBdHRycyA9PSBudWxsKSB7Ci0gICAgICAgICAgICAvLyBOb3RoaW5nIHRvIGRvCi0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLQotICAgICAgICBmb3IgKE1hcC5FbnRyeTxTdHJpbmcsIE9iamVjdD4gZW50cnkgOiBkYmZBdHRycy5lbnRyeVNldCgpKSB7Ci0gICAgICAgICAgICBTdHJpbmcgbmFtZSA9IGVudHJ5LmdldEtleSgpOwotICAgICAgICAgICAgT2JqZWN0IHZhbCA9IGVudHJ5LmdldFZhbHVlKCk7Ci0gICAgICAgICAgICBpZiAodmFsIGluc3RhbmNlb2YgQm9vbGVhbikgewotICAgICAgICAgICAgICAgIC8vIEFzc3VtZSBmZWF0dXJlCi0gICAgICAgICAgICAgICAgZG9tUGFyc2VyLnNldEZlYXR1cmUobmFtZSwgKEJvb2xlYW4pdmFsKTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgLy8gQXNzdW1lIHByb3BlcnR5Ci0gICAgICAgICAgICAgICAgaWYgKEpBWFBfU0NIRU1BX0xBTkdVQUdFLmVxdWFscyhuYW1lKSkgewotICAgICAgICAgICAgICAgICAgICAvLyBKQVhQIDEuMiBzdXBwb3J0Ci0gICAgICAgICAgICAgICAgICAgIC8vTm9uZSBvZiB0aGUgcHJvcGVydGllcyB3aWxsIHRha2UgZWZmZWN0IHRpbGwgdGhlIHNldFZhbGlkYXRpbmcodHJ1ZSkgaGFzIGJlZW4gY2FsbGVkCi0gICAgICAgICAgICAgICAgICAgIGlmICggVzNDX1hNTF9TQ0hFTUEuZXF1YWxzKHZhbCkgKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiggaXNWYWxpZGF0aW5nKCkgKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9tUGFyc2VyLnNldEZlYXR1cmUoWE1MU0NIRU1BX1ZBTElEQVRJT05fRkVBVFVSRSwgdHJ1ZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhpcyBzaG91bGQgYWxsb3cgdXMgbm90IHRvIGVtaXQgRFREIGVycm9ycywgYXMgZXhwZWN0ZWQgYnkgdGhlCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc3BlYyB3aGVuIHNjaGVtYSB2YWxpZGF0aW9uIGlzIGVuYWJsZWQKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb21QYXJzZXIuc2V0UHJvcGVydHkoSkFYUF9TQ0hFTUFfTEFOR1VBR0UsIFczQ19YTUxfU0NIRU1BKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgfSBlbHNlIGlmKEpBWFBfU0NIRU1BX1NPVVJDRS5lcXVhbHMobmFtZSkpewotICAgICAgICAgICAgICAgICAgICBpZiggaXNWYWxpZGF0aW5nKCkgKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdmFsdWU9KFN0cmluZylkYmZBdHRycy5nZXQoSkFYUF9TQ0hFTUFfTEFOR1VBR0UpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYodmFsdWUgIT1udWxsICYmIFczQ19YTUxfU0NIRU1BLmVxdWFscyh2YWx1ZSkpewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvbVBhcnNlci5zZXRQcm9wZXJ0eShuYW1lLCB2YWwpOwotICAgICAgICAgICAgICAgICAgICAgICAgfWVsc2V7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImpheHAtb3JkZXItbm90LXN1cHBvcnRlZCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7SkFYUF9TQ0hFTUFfTEFOR1VBR0UsIEpBWFBfU0NIRU1BX1NPVVJDRX0pKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAvL2NoZWNrIGlmIHRoZSBwcm9wZXJ0eSBpcyBtYW5hZ2VkIGJ5IHNlY3VyaXR5IG1hbmFnZXIKLSAgICAgICAgICAgICAgICAgICAgIGlmIChmU2VjdXJpdHlNYW5hZ2VyID09IG51bGwgfHwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIWZTZWN1cml0eU1hbmFnZXIuc2V0TGltaXQobmFtZSwgWE1MU2VjdXJpdHlNYW5hZ2VyLlN0YXRlLkFQSVBST1BFUlRZLCB2YWwpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgLy9jaGVjayBpZiB0aGUgcHJvcGVydHkgaXMgbWFuYWdlZCBieSBzZWN1cml0eSBwcm9wZXJ0eSBtYW5hZ2VyCi0gICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZTZWN1cml0eVByb3BlcnR5TWdyID09IG51bGwgfHwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICFmU2VjdXJpdHlQcm9wZXJ0eU1nci5zZXRWYWx1ZShuYW1lLCBYTUxTZWN1cml0eVByb3BlcnR5TWFuYWdlci5TdGF0ZS5BUElQUk9QRVJUWSwgdmFsKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2ZhbGwgYmFjayB0byB0aGUgZXhpc3RpbmcgcHJvcGVydHkgbWFuYWdlcgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb21QYXJzZXIuc2V0UHJvcGVydHkobmFtZSwgdmFsKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBOb24tcHJlZmVycmVkOiB1c2UgdGhlIGdldERPTUltcGxlbWVudGF0aW9uKCkgbWV0aG9kIGluc3RlYWQgb2YgdGhpcwotICAgICAqIG9uZSB0byBnZXQgYSBET00gTGV2ZWwgMiBET01JbXBsZW1lbnRhdGlvbiBvYmplY3QgYW5kIHRoZW4gdXNlIERPTQotICAgICAqIExldmVsIDIgbWV0aG9kcyB0byBjcmVhdGUgYSBET00gRG9jdW1lbnQgb2JqZWN0LgotICAgICAqLwotICAgIHB1YmxpYyBEb2N1bWVudCBuZXdEb2N1bWVudCgpIHsKLSAgICAgICAgcmV0dXJuIG5ldyBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbS5Eb2N1bWVudEltcGwoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgRE9NSW1wbGVtZW50YXRpb24gZ2V0RE9NSW1wbGVtZW50YXRpb24oKSB7Ci0gICAgICAgIHJldHVybiBET01JbXBsZW1lbnRhdGlvbkltcGwuZ2V0RE9NSW1wbGVtZW50YXRpb24oKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgRG9jdW1lbnQgcGFyc2UoSW5wdXRTb3VyY2UgaXMpIHRocm93cyBTQVhFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKGlzID09IG51bGwpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAiamF4cC1udWxsLWlucHV0LXNvdXJjZSIsIG51bGwpKTsKLSAgICAgICAgfQotICAgICAgICBpZiAoZlNjaGVtYVZhbGlkYXRvciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAoZlNjaGVtYVZhbGlkYXRpb25NYW5hZ2VyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmU2NoZW1hVmFsaWRhdGlvbk1hbmFnZXIucmVzZXQoKTsKLSAgICAgICAgICAgICAgICBmVW5wYXJzZWRFbnRpdHlIYW5kbGVyLnJlc2V0KCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXNldFNjaGVtYVZhbGlkYXRvcigpOwotICAgICAgICB9Ci0gICAgICAgIGRvbVBhcnNlci5wYXJzZShpcyk7Ci0gICAgICAgIERvY3VtZW50IGRvYyA9IGRvbVBhcnNlci5nZXREb2N1bWVudCgpOwotICAgICAgICBkb21QYXJzZXIuZHJvcERvY3VtZW50UmVmZXJlbmNlcygpOwotICAgICAgICByZXR1cm4gZG9jOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGlzTmFtZXNwYWNlQXdhcmUoKSB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICByZXR1cm4gZG9tUGFyc2VyLmdldEZlYXR1cmUoTkFNRVNQQUNFU19GRUFUVVJFKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoU0FYRXhjZXB0aW9uIHgpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oeC5nZXRNZXNzYWdlKCkpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gaXNWYWxpZGF0aW5nKCkgewotICAgICAgICB0cnkgewotICAgICAgICAgICAgcmV0dXJuIGRvbVBhcnNlci5nZXRGZWF0dXJlKFZBTElEQVRJT05fRkVBVFVSRSk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKFNBWEV4Y2VwdGlvbiB4KSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKHguZ2V0TWVzc2FnZSgpKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldHMgdGhlIFhJbmNsdWRlIHByb2Nlc3NpbmcgbW9kZSBmb3IgdGhpcyBwYXJzZXIKLSAgICAgKiBAcmV0dXJuIHRoZSBzdGF0ZSBvZiBYSW5jbHVkZSBwcm9jZXNzaW5nIG1vZGUKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc1hJbmNsdWRlQXdhcmUoKSB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICByZXR1cm4gZG9tUGFyc2VyLmdldEZlYXR1cmUoWElOQ0xVREVfRkVBVFVSRSk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKFNBWEV4Y2VwdGlvbiBleGMpIHsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldEVudGl0eVJlc29sdmVyKEVudGl0eVJlc29sdmVyIGVyKSB7Ci0gICAgICAgIGRvbVBhcnNlci5zZXRFbnRpdHlSZXNvbHZlcihlcik7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0RXJyb3JIYW5kbGVyKEVycm9ySGFuZGxlciBlaCkgewotICAgICAgICBkb21QYXJzZXIuc2V0RXJyb3JIYW5kbGVyKGVoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU2NoZW1hIGdldFNjaGVtYSgpIHsKLSAgICAgICAgcmV0dXJuIGdyYW1tYXI7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgcmVzZXQoKSB7Ci0gICAgICAgIC8qKiBSZXN0b3JlIHRoZSBpbml0aWFsIGVycm9yIGhhbmRsZXIuICoqLwotICAgICAgICBpZiAoZG9tUGFyc2VyLmdldEVycm9ySGFuZGxlcigpICE9IGZJbml0RXJyb3JIYW5kbGVyKSB7Ci0gICAgICAgICAgICBkb21QYXJzZXIuc2V0RXJyb3JIYW5kbGVyKGZJbml0RXJyb3JIYW5kbGVyKTsKLSAgICAgICAgfQotICAgICAgICAvKiogUmVzdG9yZSB0aGUgaW5pdGlhbCBlbnRpdHkgcmVzb2x2ZXIuICoqLwotICAgICAgICBpZiAoZG9tUGFyc2VyLmdldEVudGl0eVJlc29sdmVyKCkgIT0gZkluaXRFbnRpdHlSZXNvbHZlcikgewotICAgICAgICAgICAgZG9tUGFyc2VyLnNldEVudGl0eVJlc29sdmVyKGZJbml0RW50aXR5UmVzb2x2ZXIpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLy8gcGFja2FnZSBwcml2YXRlCi0gICAgRE9NUGFyc2VyIGdldERPTVBhcnNlcigpIHsKLSAgICAgICAgcmV0dXJuIGRvbVBhcnNlcjsKLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgcmVzZXRTY2hlbWFWYWxpZGF0b3IoKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGZTY2hlbWFWYWxpZGF0b3IucmVzZXQoZlNjaGVtYVZhbGlkYXRvckNvbXBvbmVudE1hbmFnZXIpOwotICAgICAgICB9Ci0gICAgICAgIC8vIFRoaXMgc2hvdWxkIG5ldmVyIGJlIHRocm93biBmcm9tIHRoZSBzY2hlbWEgdmFsaWRhdG9yLgotICAgICAgICBjYXRjaCAoWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKGUpOwotICAgICAgICB9Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvamF4cC9KQVhQQ29uc3RhbnRzLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9qYXhwL0pBWFBDb25zdGFudHMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNWYyYzU2My4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9qYXhwL0pBWFBDb25zdGFudHMuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQxICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDAtMjAwMiwyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuamF4cDsKLQotLyoqCi0gKiBUaGlzIGludGVyZmFjZSBob2xkcyBKQVhQIGNvbnN0YW50IHByb3BlcnR5L2F0dHJpYnV0ZSBuYW1lcyBhbmQgdmFsdWVzLgotICogU2luY2UgSkFYUCAxLjIgaXMgYSBtYWludGVuYW5jZSByZWxlYXNlIG9mIEpBWFAgMS4xLCBubyBwdWJsaWMKLSAqIHNpZ25hdHVyZXMgYXJlIGFsbG93ZWQgc28gdGhlc2UgdmFsdWVzIGNhbm5vdCBiZSBleHBvc2VkIGluIHRoZQotICogamF2YXgueG1sLnBhcnNlcnMgcGFja2FnZS4gIE9uY2UgZXF1aXZhbGVudCBjb25zdGFudHMgaGF2ZSBiZWVuIGRlZmluZWQKLSAqIGluIGZ1dHVyZSBKQVhQIHNwZWMgdmVyc2lvbnMsIHRoaXMgaW50ZXJmYWNlIGNhbiBiZSByZW1vdmVkLgotICoKLSAqIEBhdXRob3IgRWR3aW4gR29laQotICovCi1wdWJsaWMgaW50ZXJmYWNlIEpBWFBDb25zdGFudHMgewotICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgSkFYUF9TQ0hFTUFfTEFOR1VBR0UgPQotICAgICAgICAiaHR0cDovL2phdmEuc3VuLmNvbS94bWwvamF4cC9wcm9wZXJ0aWVzL3NjaGVtYUxhbmd1YWdlIjsKLSAgICBzdGF0aWMgZmluYWwgU3RyaW5nIFczQ19YTUxfU0NIRU1BID0KLSAgICAgICAgImh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hIjsKLQotICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgSkFYUF9TQ0hFTUFfU09VUkNFID0KLSAgICAgICAgImh0dHA6Ly9qYXZhLnN1bi5jb20veG1sL2pheHAvcHJvcGVydGllcy9zY2hlbWFTb3VyY2UiOwotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvamF4cC9KQVhQVmFsaWRhdG9yQ29tcG9uZW50LmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9qYXhwL0pBWFBWYWxpZGF0b3JDb21wb25lbnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZDQ0NzU3NC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9qYXhwL0pBWFBWYWxpZGF0b3JDb21wb25lbnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDU5OSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmpheHA7Ci0KLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotCi1pbXBvcnQgamF2YXgueG1sLnZhbGlkYXRpb24uVHlwZUluZm9Qcm92aWRlcjsKLWltcG9ydCBqYXZheC54bWwudmFsaWRhdGlvbi5WYWxpZGF0b3JIYW5kbGVyOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5kb20uRE9NSW5wdXRJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5Db25zdGFudHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLlhNTEVycm9yUmVwb3J0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLm9wdGkuRGVmYXVsdFhNTERvY3VtZW50SGFuZGxlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuQXR0cmlidXRlc1Byb3h5OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5BdWdtZW50YXRpb25zSW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuRXJyb3JIYW5kbGVyUHJveHk7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLkVycm9ySGFuZGxlcldyYXBwZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLkxvY2F0b3JQcm94eTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuU3ltYm9sVGFibGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlhNTFJlc291cmNlSWRlbnRpZmllckltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuQXVnbWVudGF0aW9uczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5OYW1lc3BhY2VDb250ZXh0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlFOYW1lOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTEF0dHJpYnV0ZXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MRG9jdW1lbnRIYW5kbGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTExvY2F0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MU3RyaW5nOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhOSUV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MQ29tcG9uZW50OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxDb21wb25lbnRNYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxFbnRpdHlSZXNvbHZlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MRXJyb3JIYW5kbGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxJbnB1dFNvdXJjZTsKLWltcG9ydCBvcmcudzNjLmRvbS5UeXBlSW5mbzsKLWltcG9ydCBvcmcudzNjLmRvbS5scy5MU0lucHV0OwotaW1wb3J0IG9yZy53M2MuZG9tLmxzLkxTUmVzb3VyY2VSZXNvbHZlcjsKLWltcG9ydCBvcmcueG1sLnNheC5BdHRyaWJ1dGVzOwotaW1wb3J0IG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LkVycm9ySGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguaGVscGVycy5EZWZhdWx0SGFuZGxlcjsKLQotLyoqCi0gKiBSdW5zIGV2ZW50cyB0aHJvdWdoIGEge0BsaW5rIGphdmF4LnhtbC52YWxpZGF0aW9uLlZhbGlkYXRvckhhbmRsZXJ9Ci0gKiBhbmQgcGVyZm9ybXMgdmFsaWRhdGlvbi9pbmZvc2V0LWF1Z21lbnRhdGlvbiBieSBhbiBleHRlcm5hbCB2YWxpZGF0b3IuCi0gKgotICogPHA+Ci0gKiBUaGlzIGNvbXBvbmVudCBzZXRzIHVwIHRoZSBwaXBlbGluZSBhcyBmb2xsb3dzOgotICoKLSAqIDwhLS0gdGhpcyBwaWN0dXJlIG1heSBsb29rIHRlcmliYmxlIG9uIHlvdXIgSURFIGJ1dCBpdCBpcyBjb3JyZWN0LiAtLT4KLSAqIDxwcmU+Ci0gKiAgICAgICAgICAgICBfXyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfXwotICogICAgICAgICAgICAvICB8PT0+IFhOSTJTQVggLS0+IFZhbGlkYXRvciAtLT4gU0FYMlhOSSA9PT58Ci0gKiAgICAgICAgICAgLyAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKLSAqICAgICAgID09PnwgVGVlfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBuZXh0Ci0gKiAgICAgICAgICAgXCAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgIGNvbXBvbmVudAotICogICAgICAgICAgICBcICB8PT09PT09PT09PT09b3RoZXIgWE5JIGV2ZW50cz09PT09PT09PT09PT58Ci0gKiAgICAgICAgICAgICB+fiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB+fgotICogPC9wcmU+Ci0gKiA8cD4KLSAqIG9ubHkgdGhvc2UgZXZlbnRzIHRoYXQgbmVlZCB0byBnbyB0aHJvdWdoIFZhbGlkYXRvciB3aWxsIGdvIHRoZSAxc3Qgcm91dGUsCi0gKiBhbmQgb3RoZXIgZXZlbnRzIGdvIHRoZSAybmQgZGlyZWN0IHJvdXRlLgotICoKLSAqIEBhdXRob3IgS29oc3VrZSBLYXdhZ3VjaGkgKGtvaHN1a2Uua2F3YWd1Y2hpQHN1bi5jb20pCi0gKi8KLWZpbmFsIGNsYXNzIEpBWFBWYWxpZGF0b3JDb21wb25lbnQKLSAgICBleHRlbmRzIFRlZVhNTERvY3VtZW50RmlsdGVySW1wbCBpbXBsZW1lbnRzIFhNTENvbXBvbmVudCB7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogZW50aXR5IG1hbmFnZXIuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEVOVElUWV9NQU5BR0VSID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuRU5USVRZX01BTkFHRVJfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogZXJyb3IgcmVwb3J0ZXIuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUk9SX1JFUE9SVEVSID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuRVJST1JfUkVQT1JURVJfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogc3ltYm9sIHRhYmxlLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBTWU1CT0xfVEFCTEUgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5TWU1CT0xfVEFCTEVfUFJPUEVSVFk7Ci0KLSAgICAvLyBwaXBlbGluZSBwYXJ0cwotICAgIHByaXZhdGUgZmluYWwgVmFsaWRhdG9ySGFuZGxlciB2YWxpZGF0b3I7Ci0gICAgcHJpdmF0ZSBmaW5hbCBYTkkyU0FYIHhuaTJzYXggPSBuZXcgWE5JMlNBWCgpOwotICAgIHByaXZhdGUgZmluYWwgU0FYMlhOSSBzYXgyeG5pID0gbmV3IFNBWDJYTkkoKTsKLQotICAgIC8vIG5ldmVyIGJlIG51bGwKLSAgICBwcml2YXRlIGZpbmFsIFR5cGVJbmZvUHJvdmlkZXIgdHlwZUluZm9Qcm92aWRlcjsKLQotICAgIC8qKgotICAgICAqIFVzZWQgdG8gc3RvcmUgdGhlIHtAbGluayBBdWdtZW50YXRpb25zfSBhc3NvY2lhdGVkIHdpdGggdGhlCi0gICAgICogY3VycmVudCBldmVudCwgc28gdGhhdCB3ZSBjYW4gcGljayBpdCB1cCBhZ2FpbgotICAgICAqIHdoZW4gdGhlIGV2ZW50IGlzIGZvcndhcmRlZCBieSB0aGUge0BsaW5rIFZhbGlkYXRvckhhbmRsZXJ9LgotICAgICAqCi0gICAgICogVUdMWSBIQUNLLgotICAgICAqLwotICAgIHByaXZhdGUgQXVnbWVudGF0aW9ucyBmQ3VycmVudEF1ZzsKLQotICAgIC8qKgotICAgICAqIHtAbGluayBYTUxBdHRyaWJ1dGVzfSB2ZXJzaW9uIG9mIHtAbGluayAjZkN1cnJlbnRBdWd9LgotICAgICAqLwotICAgIHByaXZhdGUgWE1MQXR0cmlidXRlcyBmQ3VycmVudEF0dHJpYnV0ZXM7Ci0KLSAgICAvLyBjb21wb25lbnRzIG9idGFpbmVkIGZyb20gYSBtYW5hZ2VyIC8gcHJvcGVydHkKLQotICAgIHByaXZhdGUgU3ltYm9sVGFibGUgZlN5bWJvbFRhYmxlOwotICAgIHByaXZhdGUgWE1MRXJyb3JSZXBvcnRlciBmRXJyb3JSZXBvcnRlcjsKLSAgICBwcml2YXRlIFhNTEVudGl0eVJlc29sdmVyIGZFbnRpdHlSZXNvbHZlcjsKLQotICAgIC8qKgotICAgICAqIEBwYXJhbSB2YWxpZGF0b3JIYW5kbGVyIG1heSBub3QgYmUgbnVsbC4KLSAgICAgKi8KLSAgICBwdWJsaWMgSkFYUFZhbGlkYXRvckNvbXBvbmVudCggVmFsaWRhdG9ySGFuZGxlciB2YWxpZGF0b3JIYW5kbGVyICkgewotICAgICAgICB0aGlzLnZhbGlkYXRvciA9IHZhbGlkYXRvckhhbmRsZXI7Ci0gICAgICAgIFR5cGVJbmZvUHJvdmlkZXIgdGlwID0gdmFsaWRhdG9ySGFuZGxlci5nZXRUeXBlSW5mb1Byb3ZpZGVyKCk7Ci0gICAgICAgIGlmKHRpcD09bnVsbCkgICB0aXAgPSBub0luZm9Qcm92aWRlcjsKLSAgICAgICAgdGhpcy50eXBlSW5mb1Byb3ZpZGVyID0gdGlwOwotCi0gICAgICAgIC8vIGNvbmZpZ3VyZSB3aXJpbmcgYmV0d2VlbiBpbnRlcm5hbCBjb21wb25lbnRzLgotICAgICAgICB4bmkyc2F4LnNldENvbnRlbnRIYW5kbGVyKHZhbGlkYXRvcik7Ci0gICAgICAgIHZhbGlkYXRvci5zZXRDb250ZW50SGFuZGxlcihzYXgyeG5pKTsKLSAgICAgICAgdGhpcy5zZXRTaWRlKHhuaTJzYXgpOwotCi0gICAgICAgIC8vIGNvbmZpZ3VyZSB2YWxpZGF0b3Igd2l0aCBwcm9wZXIgRW50aXR5UmVzb2x2ZXIvRXJyb3JIYW5kbGVyLgotICAgICAgICB2YWxpZGF0b3Iuc2V0RXJyb3JIYW5kbGVyKG5ldyBFcnJvckhhbmRsZXJQcm94eSgpIHsKLSAgICAgICAgICAgIHByb3RlY3RlZCBYTUxFcnJvckhhbmRsZXIgZ2V0RXJyb3JIYW5kbGVyKCkgewotICAgICAgICAgICAgICAgIFhNTEVycm9ySGFuZGxlciBoYW5kbGVyID0gZkVycm9yUmVwb3J0ZXIuZ2V0RXJyb3JIYW5kbGVyKCk7Ci0gICAgICAgICAgICAgICAgaWYoaGFuZGxlciE9bnVsbCkgICByZXR1cm4gaGFuZGxlcjsKLSAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEVycm9ySGFuZGxlcldyYXBwZXIoRHJhY29uaWFuRXJyb3JIYW5kbGVyLmdldEluc3RhbmNlKCkpOwotICAgICAgICAgICAgfQotICAgICAgICB9KTsKLSAgICAgICAgdmFsaWRhdG9yLnNldFJlc291cmNlUmVzb2x2ZXIobmV3IExTUmVzb3VyY2VSZXNvbHZlcigpIHsKLSAgICAgICAgICAgIHB1YmxpYyBMU0lucHV0IHJlc29sdmVSZXNvdXJjZShTdHJpbmcgdHlwZSxTdHJpbmcgbnMsIFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkLCBTdHJpbmcgYmFzZVVyaSkgewotICAgICAgICAgICAgICAgIGlmKGZFbnRpdHlSZXNvbHZlcj09bnVsbCkgICByZXR1cm4gbnVsbDsKLSAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICBYTUxJbnB1dFNvdXJjZSBpcyA9IGZFbnRpdHlSZXNvbHZlci5yZXNvbHZlRW50aXR5KAotICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFhNTFJlc291cmNlSWRlbnRpZmllckltcGwocHVibGljSWQsc3lzdGVtSWQsYmFzZVVyaSxudWxsKSk7Ci0gICAgICAgICAgICAgICAgICAgIGlmKGlzPT1udWxsKSAgICByZXR1cm4gbnVsbDsKLQotICAgICAgICAgICAgICAgICAgICBMU0lucHV0IGRpID0gbmV3IERPTUlucHV0SW1wbCgpOwotICAgICAgICAgICAgICAgICAgICBkaS5zZXRCYXNlVVJJKGlzLmdldEJhc2VTeXN0ZW1JZCgpKTsKLSAgICAgICAgICAgICAgICAgICAgZGkuc2V0Qnl0ZVN0cmVhbShpcy5nZXRCeXRlU3RyZWFtKCkpOwotICAgICAgICAgICAgICAgICAgICBkaS5zZXRDaGFyYWN0ZXJTdHJlYW0oaXMuZ2V0Q2hhcmFjdGVyU3RyZWFtKCkpOwotICAgICAgICAgICAgICAgICAgICBkaS5zZXRFbmNvZGluZyhpcy5nZXRFbmNvZGluZygpKTsKLSAgICAgICAgICAgICAgICAgICAgZGkuc2V0UHVibGljSWQoaXMuZ2V0UHVibGljSWQoKSk7Ci0gICAgICAgICAgICAgICAgICAgIGRpLnNldFN5c3RlbUlkKGlzLmdldFN5c3RlbUlkKCkpOwotCi0gICAgICAgICAgICAgICAgICAgIHJldHVybiBkaTsKLSAgICAgICAgICAgICAgICB9IGNhdGNoKCBJT0V4Y2VwdGlvbiBlICkgewotICAgICAgICAgICAgICAgICAgICAvLyBlcm9ycyB0aHJvd24gYnkgdGhlIGNhbGxiYWNrIGlzIG5vdCBzdXBwb3NlZCB0byBiZQotICAgICAgICAgICAgICAgICAgICAvLyByZXBvcnRlZCB0byB1c2Vycy4KLSAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFhOSUV4Y2VwdGlvbihlKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0pOwotICAgIH0KLQotCi0gICAgcHVibGljIHZvaWQgc3RhcnRFbGVtZW50KFFOYW1lIGVsZW1lbnQsIFhNTEF0dHJpYnV0ZXMgYXR0cmlidXRlcywgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgZkN1cnJlbnRBdHRyaWJ1dGVzID0gYXR0cmlidXRlczsKLSAgICAgICAgZkN1cnJlbnRBdWcgPSBhdWdzOwotICAgICAgICB4bmkyc2F4LnN0YXJ0RWxlbWVudChlbGVtZW50LGF0dHJpYnV0ZXMsbnVsbCk7Ci0gICAgICAgIGZDdXJyZW50QXR0cmlidXRlcyA9IG51bGw7IC8vIG1vc3RseSB0byBtYWtlIGl0IGVhc3kgdG8gZmluZCBhbnkgYnVnLgotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGVuZEVsZW1lbnQoUU5hbWUgZWxlbWVudCwgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgZkN1cnJlbnRBdWcgPSBhdWdzOwotICAgICAgICB4bmkyc2F4LmVuZEVsZW1lbnQoZWxlbWVudCxudWxsKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBlbXB0eUVsZW1lbnQoUU5hbWUgZWxlbWVudCwgWE1MQXR0cmlidXRlcyBhdHRyaWJ1dGVzLCBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBzdGFydEVsZW1lbnQoZWxlbWVudCxhdHRyaWJ1dGVzLGF1Z3MpOwotICAgICAgICBlbmRFbGVtZW50KGVsZW1lbnQsYXVncyk7Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgdm9pZCBjaGFyYWN0ZXJzKFhNTFN0cmluZyB0ZXh0LCBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICAvLyBzaW5jZSBhIHZhbGlkYXRvciBtYXkgY2hhbmdlIHRoZSBjb250ZW50cywKLSAgICAgICAgLy8gbGV0IHRoaXMgb25lIGdvIHRocm91Z2ggYSB2YWxpZGF0b3IKLSAgICAgICAgZkN1cnJlbnRBdWcgPSBhdWdzOwotICAgICAgICB4bmkyc2F4LmNoYXJhY3RlcnModGV4dCxudWxsKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBpZ25vcmFibGVXaGl0ZXNwYWNlKFhNTFN0cmluZyB0ZXh0LCBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICAvLyBzaW5jZSBhIHZhbGlkYXRvciBtYXkgY2hhbmdlIHRoZSBjb250ZW50cywKLSAgICAgICAgLy8gbGV0IHRoaXMgb25lIGdvIHRocm91Z2ggYSB2YWxpZGF0b3IKLSAgICAgICAgZkN1cnJlbnRBdWcgPSBhdWdzOwotICAgICAgICB4bmkyc2F4Lmlnbm9yYWJsZVdoaXRlc3BhY2UodGV4dCxudWxsKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCByZXNldChYTUxDb21wb25lbnRNYW5hZ2VyIGNvbXBvbmVudE1hbmFnZXIpIHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIHsKLSAgICAgICAgLy8gb2J0YWluIHJlZmVyZW5jZXMgZnJvbSB0aGUgbWFuYWdlcgotICAgICAgICBmU3ltYm9sVGFibGUgPSAoU3ltYm9sVGFibGUpY29tcG9uZW50TWFuYWdlci5nZXRQcm9wZXJ0eShTWU1CT0xfVEFCTEUpOwotICAgICAgICBmRXJyb3JSZXBvcnRlciA9IChYTUxFcnJvclJlcG9ydGVyKWNvbXBvbmVudE1hbmFnZXIuZ2V0UHJvcGVydHkoRVJST1JfUkVQT1JURVIpOwotICAgICAgICB0cnkgewotICAgICAgICAgICAgZkVudGl0eVJlc29sdmVyID0gKFhNTEVudGl0eVJlc29sdmVyKSBjb21wb25lbnRNYW5hZ2VyLmdldFByb3BlcnR5KEVOVElUWV9NQU5BR0VSKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICBmRW50aXR5UmVzb2x2ZXIgPSBudWxsOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICoKLSAgICAgKiBVc2VzIHtAbGluayBEZWZhdWx0SGFuZGxlcn0gYXMgYSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIG9mCi0gICAgICoge0BsaW5rIENvbnRlbnRIYW5kbGVyfS4KLSAgICAgKgotICAgICAqIDxwPgotICAgICAqIFdlIG9ubHkgZm9yd2FyZCBjZXJ0YWluIGV2ZW50cyBmcm9tIGEge0BsaW5rIFZhbGlkYXRvckhhbmRsZXJ9LgotICAgICAqIE90aGVyIGV2ZW50cyBzaG91bGQgZ28gInRoZSAybmQgZGlyZWN0IHJvdXRlIi4KLSAgICAgKi8KLSAgICBwcml2YXRlIGZpbmFsIGNsYXNzIFNBWDJYTkkgZXh0ZW5kcyBEZWZhdWx0SGFuZGxlciB7Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIHtAbGluayBBdWdtZW50YXRpb25zfSB0byBzZW5kIGFsb25nIHdpdGggZXZlbnRzLgotICAgICAgICAgKiBXZSByZXVzZSBvbmUgb2JqZWN0IGZvciBlZmZpY2llbmN5LgotICAgICAgICAgKi8KLSAgICAgICAgcHJpdmF0ZSBmaW5hbCBBdWdtZW50YXRpb25zIGZBdWdtZW50YXRpb25zID0gbmV3IEF1Z21lbnRhdGlvbnNJbXBsKCk7Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIHtAbGluayBRTmFtZX0gdG8gc2VuZCBhbG9uZyBldmVudHMuCi0gICAgICAgICAqIHdlIHJldXNlIG9uZSBRTmFtZSBmb3IgZWZmaWNpZW5jeS4KLSAgICAgICAgICovCi0gICAgICAgIHByaXZhdGUgZmluYWwgUU5hbWUgZlFOYW1lID0gbmV3IFFOYW1lKCk7Ci0KLSAgICAgICAgcHVibGljIHZvaWQgY2hhcmFjdGVycyhjaGFyW10gY2gsIGludCBzdGFydCwgaW50IGxlbikgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIGhhbmRsZXIoKS5jaGFyYWN0ZXJzKG5ldyBYTUxTdHJpbmcoY2gsc3RhcnQsbGVuKSxhdWcoKSk7Ci0gICAgICAgICAgICB9IGNhdGNoKCBYTklFeGNlcHRpb24gZSApIHsKLSAgICAgICAgICAgICAgICB0aHJvdyB0b1NBWEV4Y2VwdGlvbihlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyB2b2lkIGlnbm9yYWJsZVdoaXRlc3BhY2UoY2hhcltdIGNoLCBpbnQgc3RhcnQsIGludCBsZW4pIHRocm93cyBTQVhFeGNlcHRpb24gewotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICBoYW5kbGVyKCkuaWdub3JhYmxlV2hpdGVzcGFjZShuZXcgWE1MU3RyaW5nKGNoLHN0YXJ0LGxlbiksYXVnKCkpOwotICAgICAgICAgICAgfSBjYXRjaCggWE5JRXhjZXB0aW9uIGUgKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgdG9TQVhFeGNlcHRpb24oZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSwgU3RyaW5nIHFuYW1lLCBBdHRyaWJ1dGVzIGF0dHMpIHRocm93cyBTQVhFeGNlcHRpb24gewotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICB1cGRhdGVBdHRyaWJ1dGVzKGF0dHMpOwotICAgICAgICAgICAgICAgIGhhbmRsZXIoKS5zdGFydEVsZW1lbnQodG9RTmFtZSh1cmksbG9jYWxOYW1lLHFuYW1lKSwgZkN1cnJlbnRBdHRyaWJ1dGVzLCBlbGVtZW50QXVnKCkpOwotICAgICAgICAgICAgfSBjYXRjaCggWE5JRXhjZXB0aW9uIGUgKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgdG9TQVhFeGNlcHRpb24oZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCBlbmRFbGVtZW50KFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUsIFN0cmluZyBxbmFtZSkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIGhhbmRsZXIoKS5lbmRFbGVtZW50KHRvUU5hbWUodXJpLGxvY2FsTmFtZSxxbmFtZSksYXVnKCkpOwotICAgICAgICAgICAgfSBjYXRjaCggWE5JRXhjZXB0aW9uIGUgKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgdG9TQVhFeGNlcHRpb24oZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBwcml2YXRlIEF1Z21lbnRhdGlvbnMgZWxlbWVudEF1ZygpIHsKLSAgICAgICAgICAgIEF1Z21lbnRhdGlvbnMgYXVnID0gYXVnKCk7Ci0gICAgICAgICAgICAvKiogYXVnLnB1dEl0ZW0oQ29uc3RhbnRzLlRZUEVJTkZPLHR5cGVJbmZvUHJvdmlkZXIuZ2V0RWxlbWVudFR5cGVJbmZvKCkpOyAqKi8KLSAgICAgICAgICAgIHJldHVybiBhdWc7Ci0gICAgICAgIH0KLQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBHZXRzIHRoZSB7QGxpbmsgQXVnbWVudGF0aW9uc30gdGhhdCBzaG91bGQgYmUgYXNzb2NpYXRlZCB3aXRoCi0gICAgICAgICAqIHRoZSBjdXJyZW50IGV2ZW50LgotICAgICAgICAgKi8KLSAgICAgICAgcHJpdmF0ZSBBdWdtZW50YXRpb25zIGF1ZygpIHsKLSAgICAgICAgICAgIGlmKCBmQ3VycmVudEF1ZyE9bnVsbCApIHsKLSAgICAgICAgICAgICAgICBBdWdtZW50YXRpb25zIHIgPSBmQ3VycmVudEF1ZzsKLSAgICAgICAgICAgICAgICBmQ3VycmVudEF1ZyA9IG51bGw7IC8vIHdlICJjb25zdW1lZCIgdGhpcyBhdWdtZW50YXRpb24uCi0gICAgICAgICAgICAgICAgcmV0dXJuIHI7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmQXVnbWVudGF0aW9ucy5yZW1vdmVBbGxJdGVtcygpOwotICAgICAgICAgICAgcmV0dXJuIGZBdWdtZW50YXRpb25zOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIEdldCB0aGUgaGFuZGxlciB0byB3aGljaCB3ZSBzaG91bGQgc2VuZCBldmVudHMuCi0gICAgICAgICAqLwotICAgICAgICBwcml2YXRlIFhNTERvY3VtZW50SGFuZGxlciBoYW5kbGVyKCkgewotICAgICAgICAgICAgcmV0dXJuIEpBWFBWYWxpZGF0b3JDb21wb25lbnQudGhpcy5nZXREb2N1bWVudEhhbmRsZXIoKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBDb252ZXJ0cyB0aGUge0BsaW5rIFhOSUV4Y2VwdGlvbn0gcmVjZWl2ZWQgZnJvbSBhIGRvd25zdHJlYW0KLSAgICAgICAgICogY29tcG9uZW50IHRvIGEge0BsaW5rIFNBWEV4Y2VwdGlvbn0uCi0gICAgICAgICAqLwotICAgICAgICBwcml2YXRlIFNBWEV4Y2VwdGlvbiB0b1NBWEV4Y2VwdGlvbiggWE5JRXhjZXB0aW9uIHhlICkgewotICAgICAgICAgICAgRXhjZXB0aW9uIGUgPSB4ZS5nZXRFeGNlcHRpb24oKTsKLSAgICAgICAgICAgIGlmKCBlPT1udWxsICkgICBlID0geGU7Ci0gICAgICAgICAgICBpZiggZSBpbnN0YW5jZW9mIFNBWEV4Y2VwdGlvbiApICByZXR1cm4gKFNBWEV4Y2VwdGlvbillOwotICAgICAgICAgICAgcmV0dXJuIG5ldyBTQVhFeGNlcHRpb24oZSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogQ3JlYXRlcyBhIHByb3BlciB7QGxpbmsgUU5hbWV9IG9iamVjdCBmcm9tIDMgcGFydHMuCi0gICAgICAgICAqIDxwPgotICAgICAgICAgKiBUaGlzIG1ldGhvZCBkb2VzIHRoZSBzeW1ib2xpemF0aW9uLgotICAgICAgICAgKi8KLSAgICAgICAgcHJpdmF0ZSBRTmFtZSB0b1FOYW1lKCBTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxOYW1lLCBTdHJpbmcgcW5hbWUgKSB7Ci0gICAgICAgICAgICBTdHJpbmcgcHJlZml4ID0gbnVsbDsKLSAgICAgICAgICAgIGludCBpZHggPSBxbmFtZS5pbmRleE9mKCc6Jyk7Ci0gICAgICAgICAgICBpZiggaWR4PjAgKQotICAgICAgICAgICAgICAgIHByZWZpeCA9IHN5bWJvbGl6ZShxbmFtZS5zdWJzdHJpbmcoMCxpZHgpKTsKLQotICAgICAgICAgICAgbG9jYWxOYW1lID0gc3ltYm9saXplKGxvY2FsTmFtZSk7Ci0gICAgICAgICAgICBxbmFtZSA9IHN5bWJvbGl6ZShxbmFtZSk7Ci0gICAgICAgICAgICB1cmkgPSBzeW1ib2xpemUodXJpKTsKLQotICAgICAgICAgICAgLy8gbm90aWZ5IGhhbmRsZXJzCi0gICAgICAgICAgICBmUU5hbWUuc2V0VmFsdWVzKHByZWZpeCwgbG9jYWxOYW1lLCBxbmFtZSwgdXJpKTsKLSAgICAgICAgICAgIHJldHVybiBmUU5hbWU7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb252ZXJ0cyB7QGxpbmsgWE5JfSBldmVudHMgdG8ge0BsaW5rIENvbnRlbnRIYW5kbGVyfSBldmVudHMuCi0gICAgICoKLSAgICAgKiA8cD4KLSAgICAgKiBEZXJpdmluZyBmcm9tIHtAbGluayBEZWZhdWx0WE1MRG9jdW1lbnRIYW5kbGVyfQotICAgICAqIHRvIHJldXNlIGl0cyBkZWZhdWx0IHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxEb2N1bWVudEhhbmRsZXJ9Ci0gICAgICogaW1wbGVtZW50YXRpb24uCi0gICAgICoKLSAgICAgKiBAYXV0aG9yIEtvaHN1a2UgS2F3YWd1Y2hpIChrb2hzdWtlLmthd2FndWNoaUBzdW4uY29tKQotICAgICAqLwotICAgIHByaXZhdGUgZmluYWwgY2xhc3MgWE5JMlNBWCBleHRlbmRzIERlZmF1bHRYTUxEb2N1bWVudEhhbmRsZXIgewotCi0gICAgICAgIHByaXZhdGUgQ29udGVudEhhbmRsZXIgZkNvbnRlbnRIYW5kbGVyOwotCi0gICAgICAgIHByaXZhdGUgU3RyaW5nIGZWZXJzaW9uOwotCi0gICAgICAgIC8qKiBOYW1lc3BhY2UgY29udGV4dCAqLwotICAgICAgICBwcm90ZWN0ZWQgTmFtZXNwYWNlQ29udGV4dCBmTmFtZXNwYWNlQ29udGV4dDsKLQotICAgICAgICAvKioKLSAgICAgICAgICogRm9yIGVmZmljaWVuY3ksIHdlIHJldXNlIG9uZSBpbnN0YW5jZS4KLSAgICAgICAgICovCi0gICAgICAgIHByaXZhdGUgZmluYWwgQXR0cmlidXRlc1Byb3h5IGZBdHRyaWJ1dGVzUHJveHkgPSBuZXcgQXR0cmlidXRlc1Byb3h5KG51bGwpOwotCi0gICAgICAgIHB1YmxpYyB2b2lkIHNldENvbnRlbnRIYW5kbGVyKCBDb250ZW50SGFuZGxlciBoYW5kbGVyICkgewotICAgICAgICAgICAgdGhpcy5mQ29udGVudEhhbmRsZXIgPSBoYW5kbGVyOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIENvbnRlbnRIYW5kbGVyIGdldENvbnRlbnRIYW5kbGVyKCkgewotICAgICAgICAgICAgcmV0dXJuIGZDb250ZW50SGFuZGxlcjsKLSAgICAgICAgfQotCi0KLSAgICAgICAgcHVibGljIHZvaWQgeG1sRGVjbChTdHJpbmcgdmVyc2lvbiwgU3RyaW5nIGVuY29kaW5nLCBTdHJpbmcgc3RhbmRhbG9uZSwgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgICAgIHRoaXMuZlZlcnNpb24gPSB2ZXJzaW9uOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIHZvaWQgc3RhcnREb2N1bWVudChYTUxMb2NhdG9yIGxvY2F0b3IsIFN0cmluZyBlbmNvZGluZywgTmFtZXNwYWNlQ29udGV4dCBuYW1lc3BhY2VDb250ZXh0LCBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICAgICAgZk5hbWVzcGFjZUNvbnRleHQgPSBuYW1lc3BhY2VDb250ZXh0OwotICAgICAgICAgICAgZkNvbnRlbnRIYW5kbGVyLnNldERvY3VtZW50TG9jYXRvcihuZXcgTG9jYXRvclByb3h5KGxvY2F0b3IpKTsKLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgZkNvbnRlbnRIYW5kbGVyLnN0YXJ0RG9jdW1lbnQoKTsKLSAgICAgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFhOSUV4Y2VwdGlvbihlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyB2b2lkIGVuZERvY3VtZW50KEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIGZDb250ZW50SGFuZGxlci5lbmREb2N1bWVudCgpOwotICAgICAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWE5JRXhjZXB0aW9uKGUpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIHZvaWQgcHJvY2Vzc2luZ0luc3RydWN0aW9uKFN0cmluZyB0YXJnZXQsIFhNTFN0cmluZyBkYXRhLCBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICBmQ29udGVudEhhbmRsZXIucHJvY2Vzc2luZ0luc3RydWN0aW9uKHRhcmdldCxkYXRhLnRvU3RyaW5nKCkpOwotICAgICAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWE5JRXhjZXB0aW9uKGUpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIHZvaWQgc3RhcnRFbGVtZW50KFFOYW1lIGVsZW1lbnQsIFhNTEF0dHJpYnV0ZXMgYXR0cmlidXRlcywgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgLy8gc3RhcnQgbmFtZXNwYWNlIHByZWZpeCBtYXBwaW5ncwotICAgICAgICAgICAgICAgIGludCBjb3VudCA9IGZOYW1lc3BhY2VDb250ZXh0LmdldERlY2xhcmVkUHJlZml4Q291bnQoKTsKLSAgICAgICAgICAgICAgICBpZiAoY291bnQgPiAwKSB7Ci0gICAgICAgICAgICAgICAgICAgIFN0cmluZyBwcmVmaXggPSBudWxsOwotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdXJpID0gbnVsbDsKLSAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBwcmVmaXggPSBmTmFtZXNwYWNlQ29udGV4dC5nZXREZWNsYXJlZFByZWZpeEF0KGkpOwotICAgICAgICAgICAgICAgICAgICAgICAgdXJpID0gZk5hbWVzcGFjZUNvbnRleHQuZ2V0VVJJKHByZWZpeCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmQ29udGVudEhhbmRsZXIuc3RhcnRQcmVmaXhNYXBwaW5nKHByZWZpeCwgKHVyaSA9PSBudWxsKT8iIjp1cmkpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgU3RyaW5nIHVyaSA9IGVsZW1lbnQudXJpICE9IG51bGwgPyBlbGVtZW50LnVyaSA6ICIiOwotICAgICAgICAgICAgICAgIFN0cmluZyBsb2NhbHBhcnQgPSBlbGVtZW50LmxvY2FscGFydDsKLSAgICAgICAgICAgICAgICBmQXR0cmlidXRlc1Byb3h5LnNldEF0dHJpYnV0ZXMoYXR0cmlidXRlcyk7Ci0gICAgICAgICAgICAgICAgZkNvbnRlbnRIYW5kbGVyLnN0YXJ0RWxlbWVudCh1cmksIGxvY2FscGFydCwgZWxlbWVudC5yYXduYW1lLCBmQXR0cmlidXRlc1Byb3h5KTsKLSAgICAgICAgICAgIH0gY2F0Y2goIFNBWEV4Y2VwdGlvbiBlICkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBYTklFeGNlcHRpb24oZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCBlbmRFbGVtZW50KFFOYW1lIGVsZW1lbnQsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIFN0cmluZyB1cmkgPSBlbGVtZW50LnVyaSAhPSBudWxsID8gZWxlbWVudC51cmkgOiAiIjsKLSAgICAgICAgICAgICAgICBTdHJpbmcgbG9jYWxwYXJ0ID0gZWxlbWVudC5sb2NhbHBhcnQ7Ci0gICAgICAgICAgICAgICAgZkNvbnRlbnRIYW5kbGVyLmVuZEVsZW1lbnQodXJpLCBsb2NhbHBhcnQsIGVsZW1lbnQucmF3bmFtZSk7Ci0KLSAgICAgICAgICAgICAgICAvLyBzZW5kIGVuZFByZWZpeE1hcHBpbmcgZXZlbnRzCi0gICAgICAgICAgICAgICAgaW50IGNvdW50ID0gZk5hbWVzcGFjZUNvbnRleHQuZ2V0RGVjbGFyZWRQcmVmaXhDb3VudCgpOwotICAgICAgICAgICAgICAgIGlmIChjb3VudCA+IDApIHsKLSAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmQ29udGVudEhhbmRsZXIuZW5kUHJlZml4TWFwcGluZyhmTmFtZXNwYWNlQ29udGV4dC5nZXREZWNsYXJlZFByZWZpeEF0KGkpKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0gY2F0Y2goIFNBWEV4Y2VwdGlvbiBlICkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBYTklFeGNlcHRpb24oZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCBlbXB0eUVsZW1lbnQoUU5hbWUgZWxlbWVudCwgWE1MQXR0cmlidXRlcyBhdHRyaWJ1dGVzLCBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICAgICAgc3RhcnRFbGVtZW50KGVsZW1lbnQsYXR0cmlidXRlcyxhdWdzKTsKLSAgICAgICAgICAgIGVuZEVsZW1lbnQoZWxlbWVudCxhdWdzKTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyB2b2lkIGNoYXJhY3RlcnMoWE1MU3RyaW5nIHRleHQsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIGZDb250ZW50SGFuZGxlci5jaGFyYWN0ZXJzKHRleHQuY2gsdGV4dC5vZmZzZXQsdGV4dC5sZW5ndGgpOwotICAgICAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWE5JRXhjZXB0aW9uKGUpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIHZvaWQgaWdub3JhYmxlV2hpdGVzcGFjZShYTUxTdHJpbmcgdGV4dCwgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgZkNvbnRlbnRIYW5kbGVyLmlnbm9yYWJsZVdoaXRlc3BhY2UodGV4dC5jaCx0ZXh0Lm9mZnNldCx0ZXh0Lmxlbmd0aCk7Ci0gICAgICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBYTklFeGNlcHRpb24oZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBEcmFjb25pYW5FcnJvckhhbmRsZXIgaW1wbGVtZW50cyBFcnJvckhhbmRsZXIgewotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBTaW5nbGV0b24gaW5zdGFuY2UuCi0gICAgICAgICAqLwotICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBEcmFjb25pYW5FcnJvckhhbmRsZXIgRVJST1JfSEFORExFUl9JTlNUQU5DRQotICAgICAgICAgICAgPSBuZXcgRHJhY29uaWFuRXJyb3JIYW5kbGVyKCk7Ci0KLSAgICAgICAgcHJpdmF0ZSBEcmFjb25pYW5FcnJvckhhbmRsZXIoKSB7fQotCi0gICAgICAgIC8qKiBSZXR1cm5zIHRoZSBvbmUgYW5kIG9ubHkgaW5zdGFuY2Ugb2YgdGhpcyBlcnJvciBoYW5kbGVyLiAqLwotICAgICAgICBwdWJsaWMgc3RhdGljIERyYWNvbmlhbkVycm9ySGFuZGxlciBnZXRJbnN0YW5jZSgpIHsKLSAgICAgICAgICAgIHJldHVybiBFUlJPUl9IQU5ETEVSX0lOU1RBTkNFOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqIFdhcm5pbmc6IElnbm9yZS4gKi8KLSAgICAgICAgcHVibGljIHZvaWQgd2FybmluZyhTQVhQYXJzZUV4Y2VwdGlvbiBlKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICAgICAgICAgIC8vIG5vb3AKLSAgICAgICAgfQotCi0gICAgICAgIC8qKiBFcnJvcjogVGhyb3dzIGJhY2sgU0FYUGFyc2VFeGNlcHRpb24uICovCi0gICAgICAgIHB1YmxpYyB2b2lkIGVycm9yKFNBWFBhcnNlRXhjZXB0aW9uIGUpIHRocm93cyBTQVhFeGNlcHRpb24gewotICAgICAgICAgICAgdGhyb3cgZTsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKiBGYXRhbCBFcnJvcjogVGhyb3dzIGJhY2sgU0FYUGFyc2VFeGNlcHRpb24uICovCi0gICAgICAgIHB1YmxpYyB2b2lkIGZhdGFsRXJyb3IoU0FYUGFyc2VFeGNlcHRpb24gZSkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICB0aHJvdyBlOwotICAgICAgICB9Ci0KLSAgICB9IC8vIERyYWNvbmlhbkVycm9ySGFuZGxlcgotCi0KLSAgICAvKioKLSAgICAgKiBDb21wYXJlcyB0aGUgZ2l2ZW4ge0BsaW5rIEF0dHJpYnV0ZXN9IHdpdGgge0BsaW5rICNmQ3VycmVudEF0dHJpYnV0ZXN9Ci0gICAgICogYW5kIHVwZGF0ZSB0aGUgbGF0dGVyIGFjY29yZGluZ2x5LgotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCB1cGRhdGVBdHRyaWJ1dGVzKCBBdHRyaWJ1dGVzIGF0dHMgKSB7Ci0gICAgICAgIGludCBsZW4gPSBhdHRzLmdldExlbmd0aCgpOwotICAgICAgICBmb3IoIGludCBpPTA7IGk8bGVuOyBpKysgKSB7Ci0gICAgICAgICAgICBTdHJpbmcgYXFuID0gYXR0cy5nZXRRTmFtZShpKTsKLSAgICAgICAgICAgIGludCBqID0gZkN1cnJlbnRBdHRyaWJ1dGVzLmdldEluZGV4KGFxbik7Ci0gICAgICAgICAgICBTdHJpbmcgYXYgPSBhdHRzLmdldFZhbHVlKGkpOwotICAgICAgICAgICAgaWYoaj09LTEpIHsKLSAgICAgICAgICAgICAgICAvLyBuZXdseSBhZGRlZCBhdHRyaWJ1dGUuIGFkZCB0byB0aGUgY3VycmVudCBhdHRyaWJ1dGUgbGlzdC4KLQotICAgICAgICAgICAgICAgIFN0cmluZyBwcmVmaXg7Ci0gICAgICAgICAgICAgICAgaW50IGlkeCA9IGFxbi5pbmRleE9mKCc6Jyk7Ci0gICAgICAgICAgICAgICAgaWYoIGlkeDwwICkgewotICAgICAgICAgICAgICAgICAgICBwcmVmaXggPSBudWxsOwotICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIHByZWZpeCA9IHN5bWJvbGl6ZShhcW4uc3Vic3RyaW5nKDAsaWR4KSk7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgaiA9IGZDdXJyZW50QXR0cmlidXRlcy5hZGRBdHRyaWJ1dGUoCi0gICAgICAgICAgICAgICAgICAgIG5ldyBRTmFtZSgKLSAgICAgICAgICAgICAgICAgICAgICAgIHByZWZpeCwKLSAgICAgICAgICAgICAgICAgICAgICAgIHN5bWJvbGl6ZShhdHRzLmdldExvY2FsTmFtZShpKSksCi0gICAgICAgICAgICAgICAgICAgICAgICBzeW1ib2xpemUoYXFuKSwKLSAgICAgICAgICAgICAgICAgICAgICAgIHN5bWJvbGl6ZShhdHRzLmdldFVSSShpKSkpLAotICAgICAgICAgICAgICAgICAgICBhdHRzLmdldFR5cGUoaSksYXYpOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAvLyB0aGUgYXR0cmlidXRlIGlzIHByZXNlbnQuCi0gICAgICAgICAgICAgICAgaWYoICFhdi5lcXVhbHMoZkN1cnJlbnRBdHRyaWJ1dGVzLmdldFZhbHVlKGopKSApIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gYnV0IHRoZSB2YWx1ZSB3YXMgY2hhbmdlZC4KLSAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRBdHRyaWJ1dGVzLnNldFZhbHVlKGosYXYpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLyoqIEF1Z21lbnRhdGlvbnMgYXVncyA9IGZDdXJyZW50QXR0cmlidXRlcy5nZXRBdWdtZW50YXRpb25zKGopOwotICAgICAgICAgICAgYXVncy5wdXRJdGVtKCBDb25zdGFudHMuVFlQRUlORk8sCi0gICAgICAgICAgICAgICAgdHlwZUluZm9Qcm92aWRlci5nZXRBdHRyaWJ1dGVUeXBlSW5mbyhpKSApOwotICAgICAgICAgICAgYXVncy5wdXRJdGVtKCBDb25zdGFudHMuSURfQVRUUklCVVRFLAotICAgICAgICAgICAgICAgIHR5cGVJbmZvUHJvdmlkZXIuaXNJZEF0dHJpYnV0ZShpKT9Cb29sZWFuLlRSVUU6Qm9vbGVhbi5GQUxTRSApOyAqKi8KLSAgICAgICAgfQotICAgIH0KLQotICAgIHByaXZhdGUgU3RyaW5nIHN5bWJvbGl6ZSggU3RyaW5nIHMgKSB7Ci0gICAgICAgIHJldHVybiBmU3ltYm9sVGFibGUuYWRkU3ltYm9sKHMpOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICoge0BsaW5rIFR5cGVJbmZvUHJvdmlkZXJ9IHRoYXQgcmV0dXJucyBubyBpbmZvLgotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFR5cGVJbmZvUHJvdmlkZXIgbm9JbmZvUHJvdmlkZXIgPSBuZXcgVHlwZUluZm9Qcm92aWRlcigpIHsKLSAgICAgICAgcHVibGljIFR5cGVJbmZvIGdldEVsZW1lbnRUeXBlSW5mbygpIHsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgICAgIHB1YmxpYyBUeXBlSW5mbyBnZXRBdHRyaWJ1dGVUeXBlSW5mbyhpbnQgaW5kZXgpIHsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgICAgIHB1YmxpYyBUeXBlSW5mbyBnZXRBdHRyaWJ1dGVUeXBlSW5mbyhTdHJpbmcgYXR0cmlidXRlUU5hbWUpIHsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgICAgIHB1YmxpYyBUeXBlSW5mbyBnZXRBdHRyaWJ1dGVUeXBlSW5mbyhTdHJpbmcgYXR0cmlidXRlVXJpLCBTdHJpbmcgYXR0cmlidXRlTG9jYWxOYW1lKSB7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc0lkQXR0cmlidXRlKGludCBpbmRleCkgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0gICAgICAgIHB1YmxpYyBib29sZWFuIGlzU3BlY2lmaWVkKGludCBpbmRleCkgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0gICAgfTsKLQotICAgIC8vCi0gICAgLy8KLSAgICAvLyBYTUxDb21wb25lbnQgaW1wbGVtZW50YXRpb24uCi0gICAgLy8KLSAgICAvLwotCi0gICAgLy8gbm8gcHJvcGVydHkvZmVhdHVyZSBzdXBwb3J0ZWQKLSAgICBwdWJsaWMgU3RyaW5nW10gZ2V0UmVjb2duaXplZEZlYXR1cmVzKCkgewotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRGZWF0dXJlKFN0cmluZyBmZWF0dXJlSWQsIGJvb2xlYW4gc3RhdGUpIHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIHsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nW10gZ2V0UmVjb2duaXplZFByb3BlcnRpZXMoKSB7Ci0gICAgICAgIHJldHVybiBuZXcgU3RyaW5nW117RU5USVRZX01BTkFHRVIsIEVSUk9SX1JFUE9SVEVSLCBTWU1CT0xfVEFCTEV9OwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldFByb3BlcnR5KFN0cmluZyBwcm9wZXJ0eUlkLCBPYmplY3QgdmFsdWUpIHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIHsKLSAgICB9Ci0KLSAgICBwdWJsaWMgQm9vbGVhbiBnZXRGZWF0dXJlRGVmYXVsdChTdHJpbmcgZmVhdHVyZUlkKSB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIHB1YmxpYyBPYmplY3QgZ2V0UHJvcGVydHlEZWZhdWx0KFN0cmluZyBwcm9wZXJ0eUlkKSB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvamF4cC9TQVhQYXJzZXJGYWN0b3J5SW1wbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvamF4cC9TQVhQYXJzZXJGYWN0b3J5SW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1NTU5MzEwLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2pheHAvU0FYUGFyc2VyRmFjdG9yeUltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIxMiArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDE1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICovCi0vKgotICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCi0gKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKLSAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KLSAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCi0gKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAotICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5qYXhwOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLkNvbnN0YW50czsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuU0FYTWVzc2FnZUZvcm1hdHRlcjsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKLWltcG9ydCBqYXZhLnV0aWwuTWFwOwotaW1wb3J0IGphdmF4LnhtbC5YTUxDb25zdGFudHM7Ci1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXI7Ci1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyRmFjdG9yeTsKLWltcG9ydCBqYXZheC54bWwudmFsaWRhdGlvbi5TY2hlbWE7Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uOwotCi0vKioKLSAqIFRoaXMgaXMgdGhlIGltcGxlbWVudGF0aW9uIHNwZWNpZmljIGNsYXNzIGZvciB0aGUKLSAqIDxjb2RlPmphdmF4LnhtbC5wYXJzZXJzLlNBWFBhcnNlckZhY3Rvcnk8L2NvZGU+LiBUaGlzIGlzIHRoZSBwbGF0Zm9ybQotICogZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBmb3IgdGhlIHBsYXRmb3JtLgotICoKLSAqIEBhdXRob3IgUmFqaXYgTW9yZGFuaQotICogQGF1dGhvciBFZHdpbiBHb2VpCi0gKgotICogQHZlcnNpb24gJElkOiBTQVhQYXJzZXJGYWN0b3J5SW1wbC5qYXZhLHYgMS45IDIwMTAtMTEtMDEgMDQ6NDA6MDYgam9laHcgRXhwICQKLSAqLwotcHVibGljIGNsYXNzIFNBWFBhcnNlckZhY3RvcnlJbXBsIGV4dGVuZHMgU0FYUGFyc2VyRmFjdG9yeSB7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiB2YWxpZGF0aW9uLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBWQUxJREFUSU9OX0ZFQVRVUkUgPQotICAgICAgICBDb25zdGFudHMuU0FYX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLlZBTElEQVRJT05fRkVBVFVSRTsKLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IG5hbWVzcGFjZXMuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIE5BTUVTUEFDRVNfRkVBVFVSRSA9Ci0gICAgICAgIENvbnN0YW50cy5TQVhfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuTkFNRVNQQUNFU19GRUFUVVJFOwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogWEluY2x1ZGUgcHJvY2Vzc2luZyAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBYSU5DTFVERV9GRUFUVVJFID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5YSU5DTFVERV9GRUFUVVJFOwotCi0gICAgcHJpdmF0ZSBNYXA8U3RyaW5nLCBCb29sZWFuPiBmZWF0dXJlczsKLSAgICBwcml2YXRlIFNjaGVtYSBncmFtbWFyOwotICAgIHByaXZhdGUgYm9vbGVhbiBpc1hJbmNsdWRlQXdhcmU7Ci0KLSAgICAvKioKLSAgICAgKiBTdGF0ZSBvZiB0aGUgc2VjdXJlIHByb2Nlc3NpbmcgZmVhdHVyZSwgaW5pdGlhbGx5IDxjb2RlPmZhbHNlPC9jb2RlPgotICAgICAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBmU2VjdXJlUHJvY2VzcyA9IHRydWU7Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIDxjb2RlPlNBWFBhcnNlcjwvY29kZT4gdXNpbmcgdGhlIGN1cnJlbnRseQotICAgICAqIGNvbmZpZ3VyZWQgZmFjdG9yeSBwYXJhbWV0ZXJzLgotICAgICAqIEByZXR1cm4gamF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyCi0gICAgICovCi0gICAgcHVibGljIFNBWFBhcnNlciBuZXdTQVhQYXJzZXIoKQotICAgICAgICB0aHJvd3MgUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgU0FYUGFyc2VyIHNheFBhcnNlckltcGw7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBzYXhQYXJzZXJJbXBsID0gbmV3IFNBWFBhcnNlckltcGwodGhpcywgZmVhdHVyZXMsIGZTZWN1cmVQcm9jZXNzKTsKLSAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIHNlKSB7Ci0gICAgICAgICAgICAvLyBUcmFuc2xhdGUgdG8gUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbgotICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24oc2UuZ2V0TWVzc2FnZSgpKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gc2F4UGFyc2VySW1wbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb21tb24gY29kZSBmb3IgdHJhbnNsYXRpbmcgZXhjZXB0aW9ucwotICAgICAqLwotICAgIHByaXZhdGUgU0FYUGFyc2VySW1wbCBuZXdTQVhQYXJzZXJJbXBsKCkKLSAgICAgICAgdGhyb3dzIFBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24sIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sCi0gICAgICAgIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgU0FYUGFyc2VySW1wbCBzYXhQYXJzZXJJbXBsOwotICAgICAgICB0cnkgewotICAgICAgICAgICAgc2F4UGFyc2VySW1wbCA9IG5ldyBTQVhQYXJzZXJJbXBsKHRoaXMsIGZlYXR1cmVzKTsKLSAgICAgICAgfSBjYXRjaCAoU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIHRocm93IGU7Ci0gICAgICAgIH0gY2F0Y2ggKFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgdGhyb3cgZTsKLSAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIHNlKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbihzZS5nZXRNZXNzYWdlKCkpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBzYXhQYXJzZXJJbXBsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIHBhcnRpY3VsYXIgZmVhdHVyZSBpbiB0aGUgdW5kZXJseWluZyBpbXBsZW1lbnRhdGlvbiBvZgotICAgICAqIG9yZy54bWwuc2F4LlhNTFJlYWRlci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRGZWF0dXJlKFN0cmluZyBuYW1lLCBib29sZWFuIHZhbHVlKQotICAgICAgICB0aHJvd3MgUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiwgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiwKLSAgICAgICAgICAgICAgICBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gewotICAgICAgICBpZiAobmFtZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKLSAgICAgICAgfQotICAgICAgICAvLyBJZiB0aGlzIGlzIHRoZSBzZWN1cmUgcHJvY2Vzc2luZyBmZWF0dXJlLCBzYXZlIGl0IHRoZW4gcmV0dXJuLgotICAgICAgICBpZiAobmFtZS5lcXVhbHMoWE1MQ29uc3RhbnRzLkZFQVRVUkVfU0VDVVJFX1BST0NFU1NJTkcpKSB7Ci0gICAgICAgICAgICBpZiAoU3lzdGVtLmdldFNlY3VyaXR5TWFuYWdlcigpICE9IG51bGwgJiYgKCF2YWx1ZSkpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgICAgIFNBWE1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShudWxsLAotICAgICAgICAgICAgICAgICAgICAgICAgImpheHAtc2VjdXJlcHJvY2Vzc2luZy1mZWF0dXJlIiwgbnVsbCkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZlNlY3VyZVByb2Nlc3MgPSB2YWx1ZTsKLSAgICAgICAgICAgIHB1dEluRmVhdHVyZXMobmFtZSwgdmFsdWUpOwotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gWFhYIFRoaXMgaXMgdWdseS4gIFdlIGhhdmUgdG8gY29sbGVjdCB0aGUgZmVhdHVyZXMgYW5kIHRoZW4KLSAgICAgICAgLy8gbGF0ZXIgY3JlYXRlIGFuIFhNTFJlYWRlciB0byB2ZXJpZnkgdGhlIGZlYXR1cmVzLgotICAgICAgICBwdXRJbkZlYXR1cmVzKG5hbWUsIHZhbHVlKTsKLSAgICAgICAgLy8gVGVzdCB0aGUgZmVhdHVyZSBieSBwb3NzaWJseSB0aHJvd2luZyBTQVggZXhjZXB0aW9ucwotICAgICAgICB0cnkgewotICAgICAgICAgICAgbmV3U0FYUGFyc2VySW1wbCgpOwotICAgICAgICB9IGNhdGNoIChTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgZmVhdHVyZXMucmVtb3ZlKG5hbWUpOwotICAgICAgICAgICAgdGhyb3cgZTsKLSAgICAgICAgfSBjYXRjaCAoU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICBmZWF0dXJlcy5yZW1vdmUobmFtZSk7Ci0gICAgICAgICAgICB0aHJvdyBlOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogcmV0dXJucyB0aGUgcGFydGljdWxhciBwcm9wZXJ0eSByZXF1ZXN0ZWQgZm9yIGluIHRoZSB1bmRlcmx5aW5nCi0gICAgICogaW1wbGVtZW50YXRpb24gb2Ygb3JnLnhtbC5zYXguWE1MUmVhZGVyLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGdldEZlYXR1cmUoU3RyaW5nIG5hbWUpCi0gICAgICAgIHRocm93cyBQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uLCBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uLAotICAgICAgICAgICAgICAgIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChuYW1lID09IG51bGwpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwotICAgICAgICB9Ci0gICAgICAgIGlmIChuYW1lLmVxdWFscyhYTUxDb25zdGFudHMuRkVBVFVSRV9TRUNVUkVfUFJPQ0VTU0lORykpIHsKLSAgICAgICAgICAgIHJldHVybiBmU2VjdXJlUHJvY2VzczsKLSAgICAgICAgfQotICAgICAgICAvLyBDaGVjayBmb3IgdmFsaWQgbmFtZSBieSBjcmVhdGluZyBhIGR1bW15IFhNTFJlYWRlciB0byBnZXQKLSAgICAgICAgLy8gZmVhdHVyZSB2YWx1ZQotICAgICAgICByZXR1cm4gbmV3U0FYUGFyc2VySW1wbCgpLmdldFhNTFJlYWRlcigpLmdldEZlYXR1cmUobmFtZSk7Ci0gICAgfQotCi0gICAgcHVibGljIFNjaGVtYSBnZXRTY2hlbWEoKSB7Ci0gICAgICAgIHJldHVybiBncmFtbWFyOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldFNjaGVtYShTY2hlbWEgZ3JhbW1hcikgewotICAgICAgICB0aGlzLmdyYW1tYXIgPSBncmFtbWFyOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGlzWEluY2x1ZGVBd2FyZSgpIHsKLSAgICAgICAgcmV0dXJuIGdldEZyb21GZWF0dXJlcyhYSU5DTFVERV9GRUFUVVJFKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRYSW5jbHVkZUF3YXJlKGJvb2xlYW4gc3RhdGUpIHsKLSAgICAgICAgcHV0SW5GZWF0dXJlcyhYSU5DTFVERV9GRUFUVVJFLCBzdGF0ZSk7Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgdm9pZCBzZXRWYWxpZGF0aW5nKGJvb2xlYW4gdmFsaWRhdGluZykgewotICAgICAgICBwdXRJbkZlYXR1cmVzKFZBTElEQVRJT05fRkVBVFVSRSwgdmFsaWRhdGluZyk7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gaXNWYWxpZGF0aW5nKCkgewotICAgICAgICAgcmV0dXJuIGdldEZyb21GZWF0dXJlcyhWQUxJREFUSU9OX0ZFQVRVUkUpOwotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBwdXRJbkZlYXR1cmVzKFN0cmluZyBuYW1lLCBib29sZWFuIHZhbHVlKXsKLSAgICAgICAgIGlmIChmZWF0dXJlcyA9PSBudWxsKSB7Ci0gICAgICAgICAgICBmZWF0dXJlcyA9IG5ldyBIYXNoTWFwPD4oKTsKLSAgICAgICAgfQotICAgICAgICBmZWF0dXJlcy5wdXQobmFtZSwgdmFsdWUgPyBCb29sZWFuLlRSVUUgOiBCb29sZWFuLkZBTFNFKTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIGJvb2xlYW4gZ2V0RnJvbUZlYXR1cmVzKFN0cmluZyBuYW1lKXsKLSAgICAgICAgIGlmIChmZWF0dXJlcyA9PSBudWxsKXsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgIH0KLSAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgIEJvb2xlYW4gdmFsdWUgPSBmZWF0dXJlcy5nZXQobmFtZSk7Ci0gICAgICAgICAgICAgcmV0dXJuICh2YWx1ZSA9PSBudWxsKSA/IGZhbHNlIDogdmFsdWU7Ci0gICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gaXNOYW1lc3BhY2VBd2FyZSgpIHsKLSAgICAgICAgcmV0dXJuIGdldEZyb21GZWF0dXJlcyhOQU1FU1BBQ0VTX0ZFQVRVUkUpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldE5hbWVzcGFjZUF3YXJlKGJvb2xlYW4gYXdhcmVuZXNzKSB7Ci0gICAgICAgcHV0SW5GZWF0dXJlcyhOQU1FU1BBQ0VTX0ZFQVRVUkUsIGF3YXJlbmVzcyk7Ci0gICAgfQotCi0gfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvamF4cC9TQVhQYXJzZXJJbXBsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9qYXhwL1NBWFBhcnNlckltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMTlmODJkNS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9qYXhwL1NBWFBhcnNlckltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDczOCArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDEwLCAyMDE1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICovCi0vKgotICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCi0gKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKLSAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KLSAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCi0gKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAotICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5qYXhwOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLkNvbnN0YW50czsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwudmFsaWRhdGlvbi5WYWxpZGF0aW9uTWFuYWdlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMuWE1MU2NoZW1hVmFsaWRhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuamF4cC52YWxpZGF0aW9uLlhTR3JhbW1hclBvb2xDb250YWluZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlNBWE1lc3NhZ2VGb3JtYXR0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlN0YXR1czsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWxzLlhNTFNlY3VyaXR5TWFuYWdlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWxzLlhNTFNlY3VyaXR5UHJvcGVydHlNYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTERvY3VtZW50SGFuZGxlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MQ29tcG9uZW50OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxDb21wb25lbnRNYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxEb2N1bWVudFNvdXJjZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MUGFyc2VyQ29uZmlndXJhdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLkF0dHJpYnV0ZVBTVkk7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5FbGVtZW50UFNWSTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlBTVklQcm92aWRlcjsKLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwotaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKLWltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwotaW1wb3J0IGphdmEudXRpbC5NYXA7Ci1pbXBvcnQgamF2YXgueG1sLlhNTENvbnN0YW50czsKLWltcG9ydCBqYXZheC54bWwudmFsaWRhdGlvbi5TY2hlbWE7Ci1pbXBvcnQgb3JnLnhtbC5zYXguRW50aXR5UmVzb2x2ZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguRXJyb3JIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LkhhbmRsZXJCYXNlOwotaW1wb3J0IG9yZy54bWwuc2F4LklucHV0U291cmNlOwotaW1wb3J0IG9yZy54bWwuc2F4LlBhcnNlcjsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguWE1MUmVhZGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LmhlbHBlcnMuRGVmYXVsdEhhbmRsZXI7Ci0KLS8qKgotICogVGhpcyBpcyB0aGUgaW1wbGVtZW50YXRpb24gc3BlY2lmaWMgY2xhc3MgZm9yIHRoZQotICogPGNvZGU+amF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyPC9jb2RlPi4KLSAqCi0gKiBAYXV0aG9yIFJhaml2IE1vcmRhbmkKLSAqIEBhdXRob3IgRWR3aW4gR29laQotICoKLSAqIEB2ZXJzaW9uICRJZDogU0FYUGFyc2VySW1wbC5qYXZhLHYgMS43IDIwMTAtMTEtMDEgMDQ6NDA6MDYgam9laHcgRXhwICQKLSAqLwotcHVibGljIGNsYXNzIFNBWFBhcnNlckltcGwgZXh0ZW5kcyBqYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXIKLSAgICBpbXBsZW1lbnRzIEpBWFBDb25zdGFudHMsIFBTVklQcm92aWRlciB7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiBuYW1lc3BhY2VzLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBOQU1FU1BBQ0VTX0ZFQVRVUkUgPQotICAgICAgICBDb25zdGFudHMuU0FYX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLk5BTUVTUEFDRVNfRkVBVFVSRTsKLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IG5hbWVzcGFjZSBwcmVmaXhlcy4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgTkFNRVNQQUNFX1BSRUZJWEVTX0ZFQVRVUkUgPQotICAgICAgICBDb25zdGFudHMuU0FYX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLk5BTUVTUEFDRV9QUkVGSVhFU19GRUFUVVJFOwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogdmFsaWRhdGlvbi4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgVkFMSURBVElPTl9GRUFUVVJFID0KLSAgICAgICAgQ29uc3RhbnRzLlNBWF9GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5WQUxJREFUSU9OX0ZFQVRVUkU7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiBYTUwgU2NoZW1hIHZhbGlkYXRpb24gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MU0NIRU1BX1ZBTElEQVRJT05fRkVBVFVSRSA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuU0NIRU1BX1ZBTElEQVRJT05fRkVBVFVSRTsKLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IFhJbmNsdWRlIHByb2Nlc3NpbmcgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgWElOQ0xVREVfRkVBVFVSRSA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuWElOQ0xVREVfRkVBVFVSRTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBzZWN1cml0eSBtYW5hZ2VyLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBTRUNVUklUWV9NQU5BR0VSID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuU0VDVVJJVFlfTUFOQUdFUl9QUk9QRVJUWTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBTZWN1cml0eSBwcm9wZXJ0eSBtYW5hZ2VyLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxfU0VDVVJJVFlfUFJPUEVSVFlfTUFOQUdFUiA9Ci0gICAgICAgICAgICBDb25zdGFudHMuWE1MX1NFQ1VSSVRZX1BST1BFUlRZX01BTkFHRVI7Ci0KLSAgICBwcml2YXRlIGZpbmFsIEpBWFBTQVhQYXJzZXIgeG1sUmVhZGVyOwotICAgIHByaXZhdGUgU3RyaW5nIHNjaGVtYUxhbmd1YWdlID0gbnVsbDsgICAgIC8vIG51bGwgbWVhbnMgRFRECi0gICAgcHJpdmF0ZSBmaW5hbCBTY2hlbWEgZ3JhbW1hcjsKLQotICAgIHByaXZhdGUgZmluYWwgWE1MQ29tcG9uZW50IGZTY2hlbWFWYWxpZGF0b3I7Ci0gICAgcHJpdmF0ZSBmaW5hbCBYTUxDb21wb25lbnRNYW5hZ2VyIGZTY2hlbWFWYWxpZGF0b3JDb21wb25lbnRNYW5hZ2VyOwotICAgIHByaXZhdGUgZmluYWwgVmFsaWRhdGlvbk1hbmFnZXIgZlNjaGVtYVZhbGlkYXRpb25NYW5hZ2VyOwotICAgIHByaXZhdGUgZmluYWwgVW5wYXJzZWRFbnRpdHlIYW5kbGVyIGZVbnBhcnNlZEVudGl0eUhhbmRsZXI7Ci0KLSAgICAvKiogSW5pdGlhbCBFcnJvckhhbmRsZXIgKi8KLSAgICBwcml2YXRlIGZpbmFsIEVycm9ySGFuZGxlciBmSW5pdEVycm9ySGFuZGxlcjsKLQotICAgIC8qKiBJbml0aWFsIEVudGl0eVJlc29sdmVyICovCi0gICAgcHJpdmF0ZSBmaW5hbCBFbnRpdHlSZXNvbHZlciBmSW5pdEVudGl0eVJlc29sdmVyOwotCi0gICAgcHJpdmF0ZSBmaW5hbCBYTUxTZWN1cml0eU1hbmFnZXIgZlNlY3VyaXR5TWFuYWdlcjsKLSAgICBwcml2YXRlIGZpbmFsIFhNTFNlY3VyaXR5UHJvcGVydHlNYW5hZ2VyIGZTZWN1cml0eVByb3BlcnR5TWdyOwotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlIGEgU0FYIHBhcnNlciB3aXRoIHRoZSBhc3NvY2lhdGVkIGZlYXR1cmVzCi0gICAgICogQHBhcmFtIGZlYXR1cmVzIE1hcCBvZiBTQVggZmVhdHVyZXMsIG1heSBiZSBudWxsCi0gICAgICovCi0gICAgU0FYUGFyc2VySW1wbChTQVhQYXJzZXJGYWN0b3J5SW1wbCBzcGYsIE1hcDxTdHJpbmcsIEJvb2xlYW4+IGZlYXR1cmVzKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICAgICAgdGhpcyhzcGYsIGZlYXR1cmVzLCBmYWxzZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlIGEgU0FYIHBhcnNlciB3aXRoIHRoZSBhc3NvY2lhdGVkIGZlYXR1cmVzCi0gICAgICogQHBhcmFtIGZlYXR1cmVzIE1hcCBvZiBTQVggZmVhdHVyZXMsIG1heSBiZSBudWxsCi0gICAgICovCi0gICAgU0FYUGFyc2VySW1wbChTQVhQYXJzZXJGYWN0b3J5SW1wbCBzcGYsIE1hcDxTdHJpbmcsIEJvb2xlYW4+IGZlYXR1cmVzLCBib29sZWFuIHNlY3VyZVByb2Nlc3NpbmcpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGZTZWN1cml0eU1hbmFnZXIgPSBuZXcgWE1MU2VjdXJpdHlNYW5hZ2VyKHNlY3VyZVByb2Nlc3NpbmcpOwotICAgICAgICBmU2VjdXJpdHlQcm9wZXJ0eU1nciA9IG5ldyBYTUxTZWN1cml0eVByb3BlcnR5TWFuYWdlcigpOwotICAgICAgICAvLyBJbnN0YW50aWF0ZSBhIFNBWFBhcnNlciBkaXJlY3RseSBhbmQgbm90IHRocm91Z2ggU0FYIHNvIHRoYXQgd2UgdXNlIHRoZSByaWdodCBDbGFzc0xvYWRlcgotICAgICAgICB4bWxSZWFkZXIgPSBuZXcgSkFYUFNBWFBhcnNlcih0aGlzLCBmU2VjdXJpdHlQcm9wZXJ0eU1nciwgZlNlY3VyaXR5TWFuYWdlcik7Ci0KLSAgICAgICAgLy8gSkFYUCAibmFtZXNwYWNlQXdhcmUiID09IFNBWCBOYW1lc3BhY2VzIGZlYXR1cmUKLSAgICAgICAgLy8gTm90ZTogdGhlcmUgaXMgYSBjb21wYXRpYmlsaXR5IHByb2JsZW0gaGVyZSB3aXRoIGRlZmF1bHQgdmFsdWVzOgotICAgICAgICAvLyBKQVhQIGRlZmF1bHQgaXMgZmFsc2Ugd2hpbGUgU0FYIDIgZGVmYXVsdCBpcyB0cnVlIQotICAgICAgICB4bWxSZWFkZXIuc2V0RmVhdHVyZTAoTkFNRVNQQUNFU19GRUFUVVJFLCBzcGYuaXNOYW1lc3BhY2VBd2FyZSgpKTsKLQotICAgICAgICAvLyBTQVggIm5hbWVzcGFjZXMiIGFuZCAibmFtZXNwYWNlLXByZWZpeGVzIiBmZWF0dXJlcyBzaG91bGQgbm90Ci0gICAgICAgIC8vIGJvdGggYmUgZmFsc2UuICBXZSBtYWtlIHRoZW0gb3Bwb3NpdGUgZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkKLSAgICAgICAgLy8gc2luY2UgSkFYUCAxLjAgYXBwcyBtYXkgd2FudCB0byByZWNlaXZlIHhtbG5zKiBhdHRyaWJ1dGVzLgotICAgICAgICB4bWxSZWFkZXIuc2V0RmVhdHVyZTAoTkFNRVNQQUNFX1BSRUZJWEVTX0ZFQVRVUkUsICFzcGYuaXNOYW1lc3BhY2VBd2FyZSgpKTsKLQotICAgICAgICAvLyBBdm9pZCBzZXR0aW5nIHRoZSBYSW5jbHVkZSBwcm9jZXNzaW5nIGZlYXR1cmUgaWYgdGhlIHZhbHVlIGlzIGZhbHNlLgotICAgICAgICAvLyBUaGlzIHdpbGwga2VlcCB0aGUgY29uZmlndXJhdGlvbiBmcm9tIHRocm93aW5nIGFuIGV4Y2VwdGlvbiBpZiBpdAotICAgICAgICAvLyBkb2VzIG5vdCBzdXBwb3J0IFhJbmNsdWRlLgotICAgICAgICBpZiAoc3BmLmlzWEluY2x1ZGVBd2FyZSgpKSB7Ci0gICAgICAgICAgICB4bWxSZWFkZXIuc2V0RmVhdHVyZTAoWElOQ0xVREVfRkVBVFVSRSwgdHJ1ZSk7Ci0gICAgICAgIH0KLQotICAgICAgICB4bWxSZWFkZXIuc2V0UHJvcGVydHkwKFhNTF9TRUNVUklUWV9QUk9QRVJUWV9NQU5BR0VSLCBmU2VjdXJpdHlQcm9wZXJ0eU1ncik7Ci0KLSAgICAgICAgeG1sUmVhZGVyLnNldFByb3BlcnR5MChTRUNVUklUWV9NQU5BR0VSLCBmU2VjdXJpdHlNYW5hZ2VyKTsKLQotICAgICAgICBpZiAoc2VjdXJlUHJvY2Vzc2luZykgewotICAgICAgICAgICAgLyoqCi0gICAgICAgICAgICAgKiBCeSBkZWZhdWx0LCBzZWN1cmUgcHJvY2Vzc2luZyBpcyBzZXQsIG5vIGV4dGVybmFsIGFjY2VzcyBpcyBhbGxvd2VkLgotICAgICAgICAgICAgICogSG93ZXZlciwgd2UgbmVlZCB0byBjaGVjayBpZiBpdCBpcyBhY3RpdmVseSBzZXQgb24gdGhlIGZhY3Rvcnkgc2luY2Ugd2UKLSAgICAgICAgICAgICAqIGFsbG93IHRoZSB1c2Ugb2YgdGhlIFN5c3RlbSBQcm9wZXJ0eSBvciBqYXhwLnByb3BlcnRpZXMgdG8gb3ZlcnJpZGUKLSAgICAgICAgICAgICAqIHRoZSBkZWZhdWx0IHZhbHVlCi0gICAgICAgICAgICAgKi8KLSAgICAgICAgICAgIGlmIChmZWF0dXJlcyAhPSBudWxsKSB7Ci0KLSAgICAgICAgICAgICAgICBCb29sZWFuIHRlbXAgPSBmZWF0dXJlcy5nZXQoWE1MQ29uc3RhbnRzLkZFQVRVUkVfU0VDVVJFX1BST0NFU1NJTkcpOwotICAgICAgICAgICAgICAgIGlmICh0ZW1wICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKHRlbXAgJiYgQ29uc3RhbnRzLklTX0pESzhfT1JfQUJPVkUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZTZWN1cml0eVByb3BlcnR5TWdyLnNldFZhbHVlKFhNTFNlY3VyaXR5UHJvcGVydHlNYW5hZ2VyLlByb3BlcnR5LkFDQ0VTU19FWFRFUk5BTF9EVEQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTFNlY3VyaXR5UHJvcGVydHlNYW5hZ2VyLlN0YXRlLkZTUCwgQ29uc3RhbnRzLkVYVEVSTkFMX0FDQ0VTU19ERUZBVUxUX0ZTUCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmU2VjdXJpdHlQcm9wZXJ0eU1nci5zZXRWYWx1ZShYTUxTZWN1cml0eVByb3BlcnR5TWFuYWdlci5Qcm9wZXJ0eS5BQ0NFU1NfRVhURVJOQUxfU0NIRU1BLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxTZWN1cml0eVByb3BlcnR5TWFuYWdlci5TdGF0ZS5GU1AsIENvbnN0YW50cy5FWFRFUk5BTF9BQ0NFU1NfREVGQVVMVF9GU1ApOwotCi0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBTZXQgYXBwbGljYXRpb24ncyBmZWF0dXJlcywgZm9sbG93ZWQgYnkgdmFsaWRhdGlvbiBmZWF0dXJlcy4KLSAgICAgICAgc2V0RmVhdHVyZXMoZmVhdHVyZXMpOwotCi0gICAgICAgIC8vIElmIHZhbGlkYXRpbmcsIHByb3ZpZGUgYSBkZWZhdWx0IEVycm9ySGFuZGxlciB0aGF0IHByaW50cwotICAgICAgICAvLyB2YWxpZGF0aW9uIGVycm9ycyB3aXRoIGEgd2FybmluZyB0ZWxsaW5nIHRoZSB1c2VyIHRvIHNldCBhbgotICAgICAgICAvLyBFcnJvckhhbmRsZXIuCi0gICAgICAgIGlmIChzcGYuaXNWYWxpZGF0aW5nKCkpIHsKLSAgICAgICAgICAgIGZJbml0RXJyb3JIYW5kbGVyID0gbmV3IERlZmF1bHRWYWxpZGF0aW9uRXJyb3JIYW5kbGVyKHhtbFJlYWRlci5nZXRMb2NhbGUoKSk7Ci0gICAgICAgICAgICB4bWxSZWFkZXIuc2V0RXJyb3JIYW5kbGVyKGZJbml0RXJyb3JIYW5kbGVyKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIGZJbml0RXJyb3JIYW5kbGVyID0geG1sUmVhZGVyLmdldEVycm9ySGFuZGxlcigpOwotICAgICAgICB9Ci0gICAgICAgIHhtbFJlYWRlci5zZXRGZWF0dXJlMChWQUxJREFUSU9OX0ZFQVRVUkUsIHNwZi5pc1ZhbGlkYXRpbmcoKSk7Ci0KLSAgICAgICAgLy8gR2V0IHRoZSBTY2hlbWEgb2JqZWN0IGZyb20gdGhlIGZhY3RvcnkKLSAgICAgICAgdGhpcy5ncmFtbWFyID0gc3BmLmdldFNjaGVtYSgpOwotICAgICAgICBpZiAoZ3JhbW1hciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBYTUxQYXJzZXJDb25maWd1cmF0aW9uIGNvbmZpZyA9IHhtbFJlYWRlci5nZXRYTUxQYXJzZXJDb25maWd1cmF0aW9uKCk7Ci0gICAgICAgICAgICBYTUxDb21wb25lbnQgdmFsaWRhdG9yQ29tcG9uZW50ID0gbnVsbDsKLSAgICAgICAgICAgIC8qKiBGb3IgWGVyY2VzIGdyYW1tYXJzLCB1c2UgYnVpbHQtaW4gc2NoZW1hIHZhbGlkYXRvci4gKiovCi0gICAgICAgICAgICBpZiAoZ3JhbW1hciBpbnN0YW5jZW9mIFhTR3JhbW1hclBvb2xDb250YWluZXIpIHsKLSAgICAgICAgICAgICAgICB2YWxpZGF0b3JDb21wb25lbnQgPSBuZXcgWE1MU2NoZW1hVmFsaWRhdG9yKCk7Ci0gICAgICAgICAgICAgICAgZlNjaGVtYVZhbGlkYXRpb25NYW5hZ2VyID0gbmV3IFZhbGlkYXRpb25NYW5hZ2VyKCk7Ci0gICAgICAgICAgICAgICAgZlVucGFyc2VkRW50aXR5SGFuZGxlciA9IG5ldyBVbnBhcnNlZEVudGl0eUhhbmRsZXIoZlNjaGVtYVZhbGlkYXRpb25NYW5hZ2VyKTsKLSAgICAgICAgICAgICAgICBjb25maWcuc2V0RFRESGFuZGxlcihmVW5wYXJzZWRFbnRpdHlIYW5kbGVyKTsKLSAgICAgICAgICAgICAgICBmVW5wYXJzZWRFbnRpdHlIYW5kbGVyLnNldERUREhhbmRsZXIoeG1sUmVhZGVyKTsKLSAgICAgICAgICAgICAgICB4bWxSZWFkZXIuc2V0RFREU291cmNlKGZVbnBhcnNlZEVudGl0eUhhbmRsZXIpOwotICAgICAgICAgICAgICAgIGZTY2hlbWFWYWxpZGF0b3JDb21wb25lbnRNYW5hZ2VyID0gbmV3IFNjaGVtYVZhbGlkYXRvckNvbmZpZ3VyYXRpb24oY29uZmlnLAotICAgICAgICAgICAgICAgICAgICAgICAgKFhTR3JhbW1hclBvb2xDb250YWluZXIpIGdyYW1tYXIsIGZTY2hlbWFWYWxpZGF0aW9uTWFuYWdlcik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvKiogRm9yIHRoaXJkIHBhcnR5IGdyYW1tYXJzLCB1c2UgdGhlIEpBWFAgdmFsaWRhdG9yIGNvbXBvbmVudC4gKiovCi0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICB2YWxpZGF0b3JDb21wb25lbnQgPSBuZXcgSkFYUFZhbGlkYXRvckNvbXBvbmVudChncmFtbWFyLm5ld1ZhbGlkYXRvckhhbmRsZXIoKSk7Ci0gICAgICAgICAgICAgICAgZlNjaGVtYVZhbGlkYXRpb25NYW5hZ2VyID0gbnVsbDsKLSAgICAgICAgICAgICAgICBmVW5wYXJzZWRFbnRpdHlIYW5kbGVyID0gbnVsbDsKLSAgICAgICAgICAgICAgICBmU2NoZW1hVmFsaWRhdG9yQ29tcG9uZW50TWFuYWdlciA9IGNvbmZpZzsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNvbmZpZy5hZGRSZWNvZ25pemVkRmVhdHVyZXModmFsaWRhdG9yQ29tcG9uZW50LmdldFJlY29nbml6ZWRGZWF0dXJlcygpKTsKLSAgICAgICAgICAgIGNvbmZpZy5hZGRSZWNvZ25pemVkUHJvcGVydGllcyh2YWxpZGF0b3JDb21wb25lbnQuZ2V0UmVjb2duaXplZFByb3BlcnRpZXMoKSk7Ci0gICAgICAgICAgICBjb25maWcuc2V0RG9jdW1lbnRIYW5kbGVyKChYTUxEb2N1bWVudEhhbmRsZXIpIHZhbGlkYXRvckNvbXBvbmVudCk7Ci0gICAgICAgICAgICAoKFhNTERvY3VtZW50U291cmNlKXZhbGlkYXRvckNvbXBvbmVudCkuc2V0RG9jdW1lbnRIYW5kbGVyKHhtbFJlYWRlcik7Ci0gICAgICAgICAgICB4bWxSZWFkZXIuc2V0RG9jdW1lbnRTb3VyY2UoKFhNTERvY3VtZW50U291cmNlKSB2YWxpZGF0b3JDb21wb25lbnQpOwotICAgICAgICAgICAgZlNjaGVtYVZhbGlkYXRvciA9IHZhbGlkYXRvckNvbXBvbmVudDsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIGZTY2hlbWFWYWxpZGF0aW9uTWFuYWdlciA9IG51bGw7Ci0gICAgICAgICAgICBmVW5wYXJzZWRFbnRpdHlIYW5kbGVyID0gbnVsbDsKLSAgICAgICAgICAgIGZTY2hlbWFWYWxpZGF0b3JDb21wb25lbnRNYW5hZ2VyID0gbnVsbDsKLSAgICAgICAgICAgIGZTY2hlbWFWYWxpZGF0b3IgPSBudWxsOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gSW5pdGlhbCBFbnRpdHlSZXNvbHZlcgotICAgICAgICBmSW5pdEVudGl0eVJlc29sdmVyID0geG1sUmVhZGVyLmdldEVudGl0eVJlc29sdmVyKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0IGFueSBmZWF0dXJlcyBvZiBvdXIgWE1MUmVhZGVyIGJhc2VkIG9uIGFueSBmZWF0dXJlcyBzZXQgb24gdGhlCi0gICAgICogU0FYUGFyc2VyRmFjdG9yeS4KLSAgICAgKgotICAgICAqIFhYWCBEb2VzIG5vdCBoYW5kbGUgcG9zc2libGUgY29uZmxpY3RzIGJldHdlZW4gU0FYIGZlYXR1cmUgbmFtZXMgYW5kCi0gICAgICogSkFYUCBzcGVjaWZpYyBmZWF0dXJlIG5hbWVzLCBlZy4gU0FYUGFyc2VyRmFjdG9yeS5pc1ZhbGlkYXRpbmcoKQotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCBzZXRGZWF0dXJlcyhNYXA8U3RyaW5nLCBCb29sZWFuPiBmZWF0dXJlcykKLSAgICAgICAgdGhyb3dzIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiwgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChmZWF0dXJlcyAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmb3IgKE1hcC5FbnRyeTxTdHJpbmcsIEJvb2xlYW4+IGVudHJ5IDogZmVhdHVyZXMuZW50cnlTZXQoKSkgewotICAgICAgICAgICAgICAgIHhtbFJlYWRlci5zZXRGZWF0dXJlMChlbnRyeS5nZXRLZXkoKSwgZW50cnkuZ2V0VmFsdWUoKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgUGFyc2VyIGdldFBhcnNlcigpIHRocm93cyBTQVhFeGNlcHRpb24gewotICAgICAgICAvLyBYZXJjZXMyIEFic3RyYWN0U0FYUGFyc2VyIGltcGxlbWVudHMgU0FYMSBQYXJzZXIKLSAgICAgICAgLy8gYXNzZXJ0KHhtbFJlYWRlciBpbnN0YW5jZW9mIFBhcnNlcik7Ci0gICAgICAgIHJldHVybiAoUGFyc2VyKSB4bWxSZWFkZXI7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgWE1MUmVhZGVyIHRoYXQgaXMgZW5jYXBzdWxhdGVkIGJ5IHRoZSBpbXBsZW1lbnRhdGlvbiBvZgotICAgICAqIHRoaXMgY2xhc3MuCi0gICAgICovCi0gICAgcHVibGljIFhNTFJlYWRlciBnZXRYTUxSZWFkZXIoKSB7Ci0gICAgICAgIHJldHVybiB4bWxSZWFkZXI7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gaXNOYW1lc3BhY2VBd2FyZSgpIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIHJldHVybiB4bWxSZWFkZXIuZ2V0RmVhdHVyZShOQU1FU1BBQ0VTX0ZFQVRVUkUpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChTQVhFeGNlcHRpb24geCkgewotICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbih4LmdldE1lc3NhZ2UoKSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBpc1ZhbGlkYXRpbmcoKSB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICByZXR1cm4geG1sUmVhZGVyLmdldEZlYXR1cmUoVkFMSURBVElPTl9GRUFUVVJFKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoU0FYRXhjZXB0aW9uIHgpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oeC5nZXRNZXNzYWdlKCkpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0cyB0aGUgWEluY2x1ZGUgcHJvY2Vzc2luZyBtb2RlIGZvciB0aGlzIHBhcnNlcgotICAgICAqIEByZXR1cm4gdGhlIHN0YXRlIG9mIFhJbmNsdWRlIHByb2Nlc3NpbmcgbW9kZQotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzWEluY2x1ZGVBd2FyZSgpIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIHJldHVybiB4bWxSZWFkZXIuZ2V0RmVhdHVyZShYSU5DTFVERV9GRUFUVVJFKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoU0FYRXhjZXB0aW9uIGV4YykgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0cyB0aGUgcGFydGljdWxhciBwcm9wZXJ0eSBpbiB0aGUgdW5kZXJseWluZyBpbXBsZW1lbnRhdGlvbiBvZgotICAgICAqIG9yZy54bWwuc2F4LlhNTFJlYWRlci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRQcm9wZXJ0eShTdHJpbmcgbmFtZSwgT2JqZWN0IHZhbHVlKQotICAgICAgICB0aHJvd3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiwgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIHsKLSAgICAgICAgeG1sUmVhZGVyLnNldFByb3BlcnR5KG5hbWUsIHZhbHVlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiByZXR1cm5zIHRoZSBwYXJ0aWN1bGFyIHByb3BlcnR5IHJlcXVlc3RlZCBmb3IgaW4gdGhlIHVuZGVybHlpbmcKLSAgICAgKiBpbXBsZW1lbnRhdGlvbiBvZiBvcmcueG1sLnNheC5YTUxSZWFkZXIuCi0gICAgICovCi0gICAgcHVibGljIE9iamVjdCBnZXRQcm9wZXJ0eShTdHJpbmcgbmFtZSkKLSAgICAgICAgdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiB7Ci0gICAgICAgIHJldHVybiB4bWxSZWFkZXIuZ2V0UHJvcGVydHkobmFtZSk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgcGFyc2UoSW5wdXRTb3VyY2UgaXMsIERlZmF1bHRIYW5kbGVyIGRoKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChpcyA9PSBudWxsKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGRoICE9IG51bGwpIHsKLSAgICAgICAgICAgIHhtbFJlYWRlci5zZXRDb250ZW50SGFuZGxlcihkaCk7Ci0gICAgICAgICAgICB4bWxSZWFkZXIuc2V0RW50aXR5UmVzb2x2ZXIoZGgpOwotICAgICAgICAgICAgeG1sUmVhZGVyLnNldEVycm9ySGFuZGxlcihkaCk7Ci0gICAgICAgICAgICB4bWxSZWFkZXIuc2V0RFRESGFuZGxlcihkaCk7Ci0gICAgICAgICAgICB4bWxSZWFkZXIuc2V0RG9jdW1lbnRIYW5kbGVyKG51bGwpOwotICAgICAgICB9Ci0gICAgICAgIHhtbFJlYWRlci5wYXJzZShpcyk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgcGFyc2UoSW5wdXRTb3VyY2UgaXMsIEhhbmRsZXJCYXNlIGhiKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChpcyA9PSBudWxsKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGhiICE9IG51bGwpIHsKLSAgICAgICAgICAgIHhtbFJlYWRlci5zZXREb2N1bWVudEhhbmRsZXIoaGIpOwotICAgICAgICAgICAgeG1sUmVhZGVyLnNldEVudGl0eVJlc29sdmVyKGhiKTsKLSAgICAgICAgICAgIHhtbFJlYWRlci5zZXRFcnJvckhhbmRsZXIoaGIpOwotICAgICAgICAgICAgeG1sUmVhZGVyLnNldERUREhhbmRsZXIoaGIpOwotICAgICAgICAgICAgeG1sUmVhZGVyLnNldENvbnRlbnRIYW5kbGVyKG51bGwpOwotICAgICAgICB9Ci0gICAgICAgIHhtbFJlYWRlci5wYXJzZShpcyk7Ci0gICAgfQotCi0gICAgcHVibGljIFNjaGVtYSBnZXRTY2hlbWEoKSB7Ci0gICAgICAgIHJldHVybiBncmFtbWFyOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHJlc2V0KCkgewotICAgICAgICB0cnkgewotICAgICAgICAgICAgLyoqIFJlc3RvcmUgaW5pdGlhbCB2YWx1ZXMgb2YgZmVhdHVyZXMgYW5kIHByb3BlcnRpZXMuICoqLwotICAgICAgICAgICAgeG1sUmVhZGVyLnJlc3RvcmVJbml0U3RhdGUoKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoU0FYRXhjZXB0aW9uIGV4YykgewotICAgICAgICAgICAgLy8gVGhpcyBzaG91bGQgbmV2ZXIgaGFwcGVuLiBXZSBvbmx5IHN0b3JlIHJlY29nbml6ZWQKLSAgICAgICAgICAgIC8vIGZlYXR1cmVzIGFuZCBwcm9wZXJ0aWVzIGluIHRoZSBoYXNoIG1hcHMuIEZvciBub3cKLSAgICAgICAgICAgIC8vIGp1c3QgaWdub3JlIGl0LgotICAgICAgICB9Ci0gICAgICAgIC8qKiBSZXN0b3JlIHZhcmlvdXMgaGFuZGxlcnMuICoqLwotICAgICAgICB4bWxSZWFkZXIuc2V0Q29udGVudEhhbmRsZXIobnVsbCk7Ci0gICAgICAgIHhtbFJlYWRlci5zZXREVERIYW5kbGVyKG51bGwpOwotICAgICAgICBpZiAoeG1sUmVhZGVyLmdldEVycm9ySGFuZGxlcigpICE9IGZJbml0RXJyb3JIYW5kbGVyKSB7Ci0gICAgICAgICAgICB4bWxSZWFkZXIuc2V0RXJyb3JIYW5kbGVyKGZJbml0RXJyb3JIYW5kbGVyKTsKLSAgICAgICAgfQotICAgICAgICBpZiAoeG1sUmVhZGVyLmdldEVudGl0eVJlc29sdmVyKCkgIT0gZkluaXRFbnRpdHlSZXNvbHZlcikgewotICAgICAgICAgICAgeG1sUmVhZGVyLnNldEVudGl0eVJlc29sdmVyKGZJbml0RW50aXR5UmVzb2x2ZXIpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoKLSAgICAgKiBQU1ZJUHJvdmlkZXIgbWV0aG9kcwotICAgICAqLwotCi0gICAgcHVibGljIEVsZW1lbnRQU1ZJIGdldEVsZW1lbnRQU1ZJKCkgewotICAgICAgICByZXR1cm4gKChQU1ZJUHJvdmlkZXIpeG1sUmVhZGVyKS5nZXRFbGVtZW50UFNWSSgpOwotICAgIH0KLQotICAgIHB1YmxpYyBBdHRyaWJ1dGVQU1ZJIGdldEF0dHJpYnV0ZVBTVkkoaW50IGluZGV4KSB7Ci0gICAgICAgIHJldHVybiAoKFBTVklQcm92aWRlcil4bWxSZWFkZXIpLmdldEF0dHJpYnV0ZVBTVkkoaW5kZXgpOwotICAgIH0KLQotICAgIHB1YmxpYyBBdHRyaWJ1dGVQU1ZJIGdldEF0dHJpYnV0ZVBTVklCeU5hbWUoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsbmFtZSkgewotICAgICAgICByZXR1cm4gKChQU1ZJUHJvdmlkZXIpeG1sUmVhZGVyKS5nZXRBdHRyaWJ1dGVQU1ZJQnlOYW1lKHVyaSwgbG9jYWxuYW1lKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBFeHRlbnNpb24gb2YgU0FYUGFyc2VyLiBUaGlzIGNsYXNzIHRyYWNrcyBjaGFuZ2VzIHRvCi0gICAgICogZmVhdHVyZXMgYW5kIHByb3BlcnRpZXMgdG8gYWxsb3cgdGhlIHBhcnNlciB0byBiZSByZXNldCB0bwotICAgICAqIGl0cyBpbml0aWFsIHN0YXRlLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgSkFYUFNBWFBhcnNlciBleHRlbmRzIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwucGFyc2Vycy5TQVhQYXJzZXIgewotCi0gICAgICAgIHByaXZhdGUgZmluYWwgSGFzaE1hcCBmSW5pdEZlYXR1cmVzID0gbmV3IEhhc2hNYXAoKTsKLSAgICAgICAgcHJpdmF0ZSBmaW5hbCBIYXNoTWFwIGZJbml0UHJvcGVydGllcyA9IG5ldyBIYXNoTWFwKCk7Ci0gICAgICAgIHByaXZhdGUgZmluYWwgU0FYUGFyc2VySW1wbCBmU0FYUGFyc2VyOwotICAgICAgICBwcml2YXRlIFhNTFNlY3VyaXR5TWFuYWdlciBmU2VjdXJpdHlNYW5hZ2VyOwotICAgICAgICBwcml2YXRlIFhNTFNlY3VyaXR5UHJvcGVydHlNYW5hZ2VyIGZTZWN1cml0eVByb3BlcnR5TWdyOwotCi0KLSAgICAgICAgcHVibGljIEpBWFBTQVhQYXJzZXIoKSB7Ci0gICAgICAgICAgICB0aGlzKG51bGwsIG51bGwsIG51bGwpOwotICAgICAgICB9Ci0KLSAgICAgICAgSkFYUFNBWFBhcnNlcihTQVhQYXJzZXJJbXBsIHNheFBhcnNlciwgWE1MU2VjdXJpdHlQcm9wZXJ0eU1hbmFnZXIgc2VjdXJpdHlQcm9wZXJ0eU1nciwKLSAgICAgICAgICAgICAgICBYTUxTZWN1cml0eU1hbmFnZXIgc2VjdXJpdHlNYW5hZ2VyKSB7Ci0gICAgICAgICAgICBzdXBlcigpOwotICAgICAgICAgICAgZlNBWFBhcnNlciA9IHNheFBhcnNlcjsKLSAgICAgICAgICAgIGZTZWN1cml0eU1hbmFnZXIgPSBzZWN1cml0eU1hbmFnZXI7Ci0gICAgICAgICAgICBmU2VjdXJpdHlQcm9wZXJ0eU1nciA9IHNlY3VyaXR5UHJvcGVydHlNZ3I7Ci0gICAgICAgICAgICAvKioKLSAgICAgICAgICAgICAqIFRoaXMgY2xhc3MgbWF5IGJlIHVzZWQgZGlyZWN0bHkuIFNvIGluaXRpYWxpemUgdGhlIHNlY3VyaXR5IG1hbmFnZXIgaWYKLSAgICAgICAgICAgICAqIGl0IGlzIG51bGwuCi0gICAgICAgICAgICAgKi8KLSAgICAgICAgICAgIGlmIChmU2VjdXJpdHlNYW5hZ2VyID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmU2VjdXJpdHlNYW5hZ2VyID0gbmV3IFhNTFNlY3VyaXR5TWFuYWdlcih0cnVlKTsKLSAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICBzdXBlci5zZXRQcm9wZXJ0eShTRUNVUklUWV9NQU5BR0VSLCBmU2VjdXJpdHlNYW5hZ2VyKTsKLSAgICAgICAgICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgIFNBWE1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShmQ29uZmlndXJhdGlvbi5nZXRMb2NhbGUoKSwKLSAgICAgICAgICAgICAgICAgICAgInByb3BlcnR5LW5vdC1yZWNvZ25pemVkIiwgbmV3IE9iamVjdCBbXSB7U0VDVVJJVFlfTUFOQUdFUn0pLCBlKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoZlNlY3VyaXR5UHJvcGVydHlNZ3IgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZTZWN1cml0eVByb3BlcnR5TWdyID0gbmV3IFhNTFNlY3VyaXR5UHJvcGVydHlNYW5hZ2VyKCk7Ci0gICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgc3VwZXIuc2V0UHJvcGVydHkoWE1MX1NFQ1VSSVRZX1BST1BFUlRZX01BTkFHRVIsIGZTZWN1cml0eVByb3BlcnR5TWdyKTsKLSAgICAgICAgICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgIFNBWE1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShmQ29uZmlndXJhdGlvbi5nZXRMb2NhbGUoKSwKLSAgICAgICAgICAgICAgICAgICAgInByb3BlcnR5LW5vdC1yZWNvZ25pemVkIiwgbmV3IE9iamVjdCBbXSB7U0VDVVJJVFlfTUFOQUdFUn0pLCBlKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogT3ZlcnJpZGUgU0FYUGFyc2VyJ3Mgc2V0RmVhdHVyZSBtZXRob2QgdG8gdHJhY2sgdGhlIGluaXRpYWwgc3RhdGUKLSAgICAgICAgICogb2YgZmVhdHVyZXMuIFRoaXMga2VlcHMgdXMgZnJvbSBhZmZlY3RpbmcgdGhlIHBlcmZvcm1hbmNlIG9mIHRoZQotICAgICAgICAgKiBTQVhQYXJzZXIgd2hlbiBpdCBpcyBjcmVhdGVkIHdpdGggWE1MUmVhZGVyRmFjdG9yeS4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBzZXRGZWF0dXJlKFN0cmluZyBuYW1lLCBib29sZWFuIHZhbHVlKQotICAgICAgICAgICAgdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICBpZiAobmFtZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgLy8gVE9ETzogQWRkIGxvY2FsaXplZCBlcnJvciBtZXNzYWdlLgotICAgICAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKG5hbWUuZXF1YWxzKFhNTENvbnN0YW50cy5GRUFUVVJFX1NFQ1VSRV9QUk9DRVNTSU5HKSkgewotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgIGZTZWN1cml0eU1hbmFnZXIuc2V0U2VjdXJlUHJvY2Vzc2luZyh2YWx1ZSk7Ci0gICAgICAgICAgICAgICAgICAgIHNldFByb3BlcnR5KFNFQ1VSSVRZX01BTkFHRVIsIGZTZWN1cml0eU1hbmFnZXIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBjYXRjaCAoU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiBleGMpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gSWYgdGhlIHByb3BlcnR5IGlzIG5vdCBzdXBwb3J0ZWQKLSAgICAgICAgICAgICAgICAgICAgLy8gcmUtdGhyb3cgdGhlIGV4Y2VwdGlvbiBpZiB0aGUgdmFsdWUgaXMgdHJ1ZS4KLSAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBleGM7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgY2F0Y2ggKFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBleGMpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gSWYgdGhlIHByb3BlcnR5IGlzIG5vdCBzdXBwb3J0ZWQKLSAgICAgICAgICAgICAgICAgICAgLy8gcmUtdGhyb3cgdGhlIGV4Y2VwdGlvbiBpZiB0aGUgdmFsdWUgaXMgdHJ1ZS4KLSAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBleGM7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKCFmSW5pdEZlYXR1cmVzLmNvbnRhaW5zS2V5KG5hbWUpKSB7Ci0gICAgICAgICAgICAgICAgYm9vbGVhbiBjdXJyZW50ID0gc3VwZXIuZ2V0RmVhdHVyZShuYW1lKTsKLSAgICAgICAgICAgICAgICBmSW5pdEZlYXR1cmVzLnB1dChuYW1lLCBjdXJyZW50ID8gQm9vbGVhbi5UUlVFIDogQm9vbGVhbi5GQUxTRSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvKiogRm9yd2FyZCBmZWF0dXJlIHRvIHRoZSBzY2hlbWEgdmFsaWRhdG9yIGlmIHRoZXJlIGlzIG9uZS4gKiovCi0gICAgICAgICAgICBpZiAoZlNBWFBhcnNlciAhPSBudWxsICYmIGZTQVhQYXJzZXIuZlNjaGVtYVZhbGlkYXRvciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgc2V0U2NoZW1hVmFsaWRhdG9yRmVhdHVyZShuYW1lLCB2YWx1ZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBzdXBlci5zZXRGZWF0dXJlKG5hbWUsIHZhbHVlKTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgYm9vbGVhbiBnZXRGZWF0dXJlKFN0cmluZyBuYW1lKQotICAgICAgICAgICAgdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICBpZiAobmFtZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgLy8gVE9ETzogQWRkIGxvY2FsaXplZCBlcnJvciBtZXNzYWdlLgotICAgICAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKG5hbWUuZXF1YWxzKFhNTENvbnN0YW50cy5GRUFUVVJFX1NFQ1VSRV9QUk9DRVNTSU5HKSkgewotICAgICAgICAgICAgICAgIHJldHVybiBmU2VjdXJpdHlNYW5hZ2VyLmlzU2VjdXJlUHJvY2Vzc2luZygpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmdldEZlYXR1cmUobmFtZSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogT3ZlcnJpZGUgU0FYUGFyc2VyJ3Mgc2V0UHJvcGVydHkgbWV0aG9kIHRvIHRyYWNrIHRoZSBpbml0aWFsIHN0YXRlCi0gICAgICAgICAqIG9mIHByb3BlcnRpZXMuIFRoaXMga2VlcHMgdXMgZnJvbSBhZmZlY3RpbmcgdGhlIHBlcmZvcm1hbmNlIG9mIHRoZQotICAgICAgICAgKiBTQVhQYXJzZXIgd2hlbiBpdCBpcyBjcmVhdGVkIHdpdGggWE1MUmVhZGVyRmFjdG9yeS4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBzZXRQcm9wZXJ0eShTdHJpbmcgbmFtZSwgT2JqZWN0IHZhbHVlKQotICAgICAgICAgICAgdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICBpZiAobmFtZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgLy8gVE9ETzogQWRkIGxvY2FsaXplZCBlcnJvciBtZXNzYWdlLgotICAgICAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKGZTQVhQYXJzZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIC8vIEpBWFAgMS4yIHN1cHBvcnQKLSAgICAgICAgICAgICAgICBpZiAoSkFYUF9TQ0hFTUFfTEFOR1VBR0UuZXF1YWxzKG5hbWUpKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIFRoZSBzcGVjIHNheXMgaWYgYSBzY2hlbWEgaXMgZ2l2ZW4gdmlhIFNBWFBhcnNlckZhY3RvcnkKLSAgICAgICAgICAgICAgICAgICAgLy8gdGhlIEpBWFAgMS4yIHByb3BlcnRpZXMgc2hvdWxkbid0IGJlIGFsbG93ZWQuCi0gICAgICAgICAgICAgICAgICAgIGlmIChmU0FYUGFyc2VyLmdyYW1tYXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU0FYTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKGZDb25maWd1cmF0aW9uLmdldExvY2FsZSgpLCAic2NoZW1hLWFscmVhZHktc3BlY2lmaWVkIiwgbmV3IE9iamVjdFtdIHtuYW1lfSkpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGlmICggVzNDX1hNTF9TQ0hFTUEuZXF1YWxzKHZhbHVlKSApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vTm9uZSBvZiB0aGUgcHJvcGVydGllcyB3aWxsIHRha2UgZWZmZWN0IHRpbGwgdGhlIHNldFZhbGlkYXRpbmcodHJ1ZSkgaGFzIGJlZW4gY2FsbGVkCi0gICAgICAgICAgICAgICAgICAgICAgICBpZiggZlNBWFBhcnNlci5pc1ZhbGlkYXRpbmcoKSApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmU0FYUGFyc2VyLnNjaGVtYUxhbmd1YWdlID0gVzNDX1hNTF9TQ0hFTUE7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0RmVhdHVyZShYTUxTQ0hFTUFfVkFMSURBVElPTl9GRUFUVVJFLCB0cnVlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGlzIHdpbGwgYWxsb3cgdGhlIHBhcnNlciBub3QgdG8gZW1pdCBEVEQtcmVsYXRlZAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGVycm9ycywgYXMgdGhlIHNwZWMgZGVtYW5kcwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghZkluaXRQcm9wZXJ0aWVzLmNvbnRhaW5zS2V5KEpBWFBfU0NIRU1BX0xBTkdVQUdFKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmSW5pdFByb3BlcnRpZXMucHV0KEpBWFBfU0NIRU1BX0xBTkdVQUdFLCBzdXBlci5nZXRQcm9wZXJ0eShKQVhQX1NDSEVNQV9MQU5HVUFHRSkpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdXBlci5zZXRQcm9wZXJ0eShKQVhQX1NDSEVNQV9MQU5HVUFHRSwgVzNDX1hNTF9TQ0hFTUEpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAodmFsdWUgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgZlNBWFBhcnNlci5zY2hlbWFMYW5ndWFnZSA9IG51bGw7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzZXRGZWF0dXJlKFhNTFNDSEVNQV9WQUxJREFUSU9OX0ZFQVRVUkUsIGZhbHNlKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJFVklTSVQ6IEl0IHdvdWxkIGJlIG5pY2UgaWYgd2UgY291bGQgZm9ybWF0IHRoaXMgbWVzc2FnZQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gdXNpbmcgYSB1c2VyIHNwZWNpZmllZCBsb2NhbGUgYXMgd2UgZG8gaW4gdGhlIHVuZGVybHlpbmcKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIFhNTFJlYWRlciAtLSBtcmdsYXZhcwotICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBTQVhNZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoZkNvbmZpZ3VyYXRpb24uZ2V0TG9jYWxlKCksICJzY2hlbWEtbm90LXN1cHBvcnRlZCIsIG51bGwpKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgaWYgKEpBWFBfU0NIRU1BX1NPVVJDRS5lcXVhbHMobmFtZSkpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gVGhlIHNwZWMgc2F5cyBpZiBhIHNjaGVtYSBpcyBnaXZlbiB2aWEgU0FYUGFyc2VyRmFjdG9yeQotICAgICAgICAgICAgICAgICAgICAvLyB0aGUgSkFYUCAxLjIgcHJvcGVydGllcyBzaG91bGRuJ3QgYmUgYWxsb3dlZC4KLSAgICAgICAgICAgICAgICAgICAgaWYgKGZTQVhQYXJzZXIuZ3JhbW1hciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTQVhNZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoZkNvbmZpZ3VyYXRpb24uZ2V0TG9jYWxlKCksICJzY2hlbWEtYWxyZWFkeS1zcGVjaWZpZWQiLCBuZXcgT2JqZWN0W10ge25hbWV9KSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHZhbCA9IChTdHJpbmcpZ2V0UHJvcGVydHkoSkFYUF9TQ0hFTUFfTEFOR1VBR0UpOwotICAgICAgICAgICAgICAgICAgICBpZiAoIHZhbCAhPSBudWxsICYmIFczQ19YTUxfU0NIRU1BLmVxdWFscyh2YWwpICkgewotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFmSW5pdFByb3BlcnRpZXMuY29udGFpbnNLZXkoSkFYUF9TQ0hFTUFfU09VUkNFKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZJbml0UHJvcGVydGllcy5wdXQoSkFYUF9TQ0hFTUFfU09VUkNFLCBzdXBlci5nZXRQcm9wZXJ0eShKQVhQX1NDSEVNQV9TT1VSQ0UpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIHN1cGVyLnNldFByb3BlcnR5KG5hbWUsIHZhbHVlKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgU0FYTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKGZDb25maWd1cmF0aW9uLmdldExvY2FsZSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICJqYXhwLW9yZGVyLW5vdC1zdXBwb3J0ZWQiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7SkFYUF9TQ0hFTUFfTEFOR1VBR0UsIEpBWFBfU0NIRU1BX1NPVVJDRX0pKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgLyoqIEZvcndhcmQgcHJvcGVydHkgdG8gdGhlIHNjaGVtYSB2YWxpZGF0b3IgaWYgdGhlcmUgaXMgb25lLiAqKi8KLSAgICAgICAgICAgIGlmIChmU0FYUGFyc2VyICE9IG51bGwgJiYgZlNBWFBhcnNlci5mU2NoZW1hVmFsaWRhdG9yICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBzZXRTY2hlbWFWYWxpZGF0b3JQcm9wZXJ0eShuYW1lLCB2YWx1ZSk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vY2hlY2sgaWYgdGhlIHByb3BlcnR5IGlzIG1hbmFnZWQgYnkgc2VjdXJpdHkgbWFuYWdlcgotICAgICAgICAgICAgaWYgKGZTZWN1cml0eU1hbmFnZXIgPT0gbnVsbCB8fAotICAgICAgICAgICAgICAgICAgICAhZlNlY3VyaXR5TWFuYWdlci5zZXRMaW1pdChuYW1lLCBYTUxTZWN1cml0eU1hbmFnZXIuU3RhdGUuQVBJUFJPUEVSVFksIHZhbHVlKSkgewotICAgICAgICAgICAgICAgIC8vY2hlY2sgaWYgdGhlIHByb3BlcnR5IGlzIG1hbmFnZWQgYnkgc2VjdXJpdHkgcHJvcGVydHkgbWFuYWdlcgotICAgICAgICAgICAgICAgIGlmIChmU2VjdXJpdHlQcm9wZXJ0eU1nciA9PSBudWxsIHx8Ci0gICAgICAgICAgICAgICAgICAgICAgICAhZlNlY3VyaXR5UHJvcGVydHlNZ3Iuc2V0VmFsdWUobmFtZSwgWE1MU2VjdXJpdHlQcm9wZXJ0eU1hbmFnZXIuU3RhdGUuQVBJUFJPUEVSVFksIHZhbHVlKSkgewotICAgICAgICAgICAgICAgICAgICAvL2ZhbGwgYmFjayB0byB0aGUgZXhpc3RpbmcgcHJvcGVydHkgbWFuYWdlcgotICAgICAgICAgICAgICAgICAgICBpZiAoIWZJbml0UHJvcGVydGllcy5jb250YWluc0tleShuYW1lKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgZkluaXRQcm9wZXJ0aWVzLnB1dChuYW1lLCBzdXBlci5nZXRQcm9wZXJ0eShuYW1lKSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgc3VwZXIuc2V0UHJvcGVydHkobmFtZSwgdmFsdWUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIHN5bmNocm9uaXplZCBPYmplY3QgZ2V0UHJvcGVydHkoU3RyaW5nIG5hbWUpCi0gICAgICAgICAgICB0aHJvd3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiwgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIHsKLSAgICAgICAgICAgIGlmIChuYW1lID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAvLyBUT0RPOiBBZGQgbG9jYWxpemVkIGVycm9yIG1lc3NhZ2UuCi0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoZlNBWFBhcnNlciAhPSBudWxsICYmIEpBWFBfU0NIRU1BX0xBTkdVQUdFLmVxdWFscyhuYW1lKSkgewotICAgICAgICAgICAgICAgIC8vIEpBWFAgMS4yIHN1cHBvcnQKLSAgICAgICAgICAgICAgICByZXR1cm4gZlNBWFBhcnNlci5zY2hlbWFMYW5ndWFnZTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLyoqIENoZWNrIHRvIHNlZSBpZiB0aGUgcHJvcGVydHkgaXMgbWFuYWdlZCBieSB0aGUgc2VjdXJpdHkgbWFuYWdlciAqKi8KLSAgICAgICAgICAgIFN0cmluZyBwcm9wZXJ0eVZhbHVlID0gKGZTZWN1cml0eU1hbmFnZXIgIT0gbnVsbCkgPwotICAgICAgICAgICAgICAgICAgICBmU2VjdXJpdHlNYW5hZ2VyLmdldExpbWl0QXNTdHJpbmcobmFtZSkgOiBudWxsOwotICAgICAgICAgICAgaWYgKHByb3BlcnR5VmFsdWUgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJldHVybiBwcm9wZXJ0eVZhbHVlOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBwcm9wZXJ0eVZhbHVlID0gKGZTZWN1cml0eVByb3BlcnR5TWdyICE9IG51bGwpID8KLSAgICAgICAgICAgICAgICAgICAgZlNlY3VyaXR5UHJvcGVydHlNZ3IuZ2V0VmFsdWUobmFtZSkgOiBudWxsOwotICAgICAgICAgICAgICAgIGlmIChwcm9wZXJ0eVZhbHVlICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHByb3BlcnR5VmFsdWU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICByZXR1cm4gc3VwZXIuZ2V0UHJvcGVydHkobmFtZSk7Ci0gICAgICAgIH0KLQotICAgICAgICBzeW5jaHJvbml6ZWQgdm9pZCByZXN0b3JlSW5pdFN0YXRlKCkKLSAgICAgICAgICAgIHRocm93cyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uLCBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gewotICAgICAgICAgICAgSXRlcmF0b3IgaXRlcjsKLSAgICAgICAgICAgIGlmICghZkluaXRGZWF0dXJlcy5pc0VtcHR5KCkpIHsKLSAgICAgICAgICAgICAgICBpdGVyID0gZkluaXRGZWF0dXJlcy5lbnRyeVNldCgpLml0ZXJhdG9yKCk7Ci0gICAgICAgICAgICAgICAgd2hpbGUgKGl0ZXIuaGFzTmV4dCgpKSB7Ci0gICAgICAgICAgICAgICAgICAgIE1hcC5FbnRyeSBlbnRyeSA9IChNYXAuRW50cnkpIGl0ZXIubmV4dCgpOwotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbmFtZSA9IChTdHJpbmcpIGVudHJ5LmdldEtleSgpOwotICAgICAgICAgICAgICAgICAgICBib29sZWFuIHZhbHVlID0gKChCb29sZWFuKSBlbnRyeS5nZXRWYWx1ZSgpKS5ib29sZWFuVmFsdWUoKTsKLSAgICAgICAgICAgICAgICAgICAgc3VwZXIuc2V0RmVhdHVyZShuYW1lLCB2YWx1ZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGZJbml0RmVhdHVyZXMuY2xlYXIoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmICghZkluaXRQcm9wZXJ0aWVzLmlzRW1wdHkoKSkgewotICAgICAgICAgICAgICAgIGl0ZXIgPSBmSW5pdFByb3BlcnRpZXMuZW50cnlTZXQoKS5pdGVyYXRvcigpOwotICAgICAgICAgICAgICAgIHdoaWxlIChpdGVyLmhhc05leHQoKSkgewotICAgICAgICAgICAgICAgICAgICBNYXAuRW50cnkgZW50cnkgPSAoTWFwLkVudHJ5KSBpdGVyLm5leHQoKTsKLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG5hbWUgPSAoU3RyaW5nKSBlbnRyeS5nZXRLZXkoKTsKLSAgICAgICAgICAgICAgICAgICAgT2JqZWN0IHZhbHVlID0gZW50cnkuZ2V0VmFsdWUoKTsKLSAgICAgICAgICAgICAgICAgICAgc3VwZXIuc2V0UHJvcGVydHkobmFtZSwgdmFsdWUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBmSW5pdFByb3BlcnRpZXMuY2xlYXIoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyB2b2lkIHBhcnNlKElucHV0U291cmNlIGlucHV0U291cmNlKQotICAgICAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewotICAgICAgICAgICAgaWYgKGZTQVhQYXJzZXIgIT0gbnVsbCAmJiBmU0FYUGFyc2VyLmZTY2hlbWFWYWxpZGF0b3IgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGlmIChmU0FYUGFyc2VyLmZTY2hlbWFWYWxpZGF0aW9uTWFuYWdlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZTQVhQYXJzZXIuZlNjaGVtYVZhbGlkYXRpb25NYW5hZ2VyLnJlc2V0KCk7Ci0gICAgICAgICAgICAgICAgICAgIGZTQVhQYXJzZXIuZlVucGFyc2VkRW50aXR5SGFuZGxlci5yZXNldCgpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICByZXNldFNjaGVtYVZhbGlkYXRvcigpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgc3VwZXIucGFyc2UoaW5wdXRTb3VyY2UpOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIHZvaWQgcGFyc2UoU3RyaW5nIHN5c3RlbUlkKQotICAgICAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewotICAgICAgICAgICAgaWYgKGZTQVhQYXJzZXIgIT0gbnVsbCAmJiBmU0FYUGFyc2VyLmZTY2hlbWFWYWxpZGF0b3IgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGlmIChmU0FYUGFyc2VyLmZTY2hlbWFWYWxpZGF0aW9uTWFuYWdlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZTQVhQYXJzZXIuZlNjaGVtYVZhbGlkYXRpb25NYW5hZ2VyLnJlc2V0KCk7Ci0gICAgICAgICAgICAgICAgICAgIGZTQVhQYXJzZXIuZlVucGFyc2VkRW50aXR5SGFuZGxlci5yZXNldCgpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICByZXNldFNjaGVtYVZhbGlkYXRvcigpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgc3VwZXIucGFyc2Uoc3lzdGVtSWQpOwotICAgICAgICB9Ci0KLSAgICAgICAgWE1MUGFyc2VyQ29uZmlndXJhdGlvbiBnZXRYTUxQYXJzZXJDb25maWd1cmF0aW9uKCkgewotICAgICAgICAgICAgcmV0dXJuIGZDb25maWd1cmF0aW9uOwotICAgICAgICB9Ci0KLSAgICAgICAgdm9pZCBzZXRGZWF0dXJlMChTdHJpbmcgbmFtZSwgYm9vbGVhbiB2YWx1ZSkKLSAgICAgICAgICAgIHRocm93cyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uLCBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gewotICAgICAgICAgICAgc3VwZXIuc2V0RmVhdHVyZShuYW1lLCB2YWx1ZSk7Ci0gICAgICAgIH0KLQotICAgICAgICBib29sZWFuIGdldEZlYXR1cmUwKFN0cmluZyBuYW1lKQotICAgICAgICAgICAgdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICByZXR1cm4gc3VwZXIuZ2V0RmVhdHVyZShuYW1lKTsKLSAgICAgICAgfQotCi0gICAgICAgIHZvaWQgc2V0UHJvcGVydHkwKFN0cmluZyBuYW1lLCBPYmplY3QgdmFsdWUpCi0gICAgICAgICAgICB0aHJvd3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiwgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIHsKLSAgICAgICAgICAgIHN1cGVyLnNldFByb3BlcnR5KG5hbWUsIHZhbHVlKTsKLSAgICAgICAgfQotCi0gICAgICAgIE9iamVjdCBnZXRQcm9wZXJ0eTAoU3RyaW5nIG5hbWUpCi0gICAgICAgICAgICB0aHJvd3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiwgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIHsKLSAgICAgICAgICAgIHJldHVybiBzdXBlci5nZXRQcm9wZXJ0eShuYW1lKTsKLSAgICAgICAgfQotCi0gICAgICAgIExvY2FsZSBnZXRMb2NhbGUoKSB7Ci0gICAgICAgICAgICByZXR1cm4gZkNvbmZpZ3VyYXRpb24uZ2V0TG9jYWxlKCk7Ci0gICAgICAgIH0KLQotICAgICAgICBwcml2YXRlIHZvaWQgc2V0U2NoZW1hVmFsaWRhdG9yRmVhdHVyZShTdHJpbmcgbmFtZSwgYm9vbGVhbiB2YWx1ZSkKLSAgICAgICAgICAgIHRocm93cyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uLCBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gewotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICBmU0FYUGFyc2VyLmZTY2hlbWFWYWxpZGF0b3Iuc2V0RmVhdHVyZShuYW1lLCB2YWx1ZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyBUaGlzIHNob3VsZCBuZXZlciBiZSB0aHJvd24gZnJvbSB0aGUgc2NoZW1hIHZhbGlkYXRvci4KLSAgICAgICAgICAgIGNhdGNoIChYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgaWRlbnRpZmllciA9IGUuZ2V0SWRlbnRpZmllcigpOwotICAgICAgICAgICAgICAgIGlmIChlLmdldFR5cGUoKSA9PSBTdGF0dXMuTk9UX1JFQ09HTklaRUQpIHsKLSAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgICAgICBTQVhNZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoZkNvbmZpZ3VyYXRpb24uZ2V0TG9jYWxlKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAiZmVhdHVyZS1ub3QtcmVjb2duaXplZCIsIG5ldyBPYmplY3QgW10ge2lkZW50aWZpZXJ9KSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICAgICAgU0FYTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKGZDb25maWd1cmF0aW9uLmdldExvY2FsZSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgImZlYXR1cmUtbm90LXN1cHBvcnRlZCIsIG5ldyBPYmplY3QgW10ge2lkZW50aWZpZXJ9KSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgcHJpdmF0ZSB2b2lkIHNldFNjaGVtYVZhbGlkYXRvclByb3BlcnR5KFN0cmluZyBuYW1lLCBPYmplY3QgdmFsdWUpCi0gICAgICAgICAgICB0aHJvd3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiwgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIHsKLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgZlNBWFBhcnNlci5mU2NoZW1hVmFsaWRhdG9yLnNldFByb3BlcnR5KG5hbWUsIHZhbHVlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIFRoaXMgc2hvdWxkIG5ldmVyIGJlIHRocm93biBmcm9tIHRoZSBzY2hlbWEgdmFsaWRhdG9yLgotICAgICAgICAgICAgY2F0Y2ggKFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgIFN0cmluZyBpZGVudGlmaWVyID0gZS5nZXRJZGVudGlmaWVyKCk7Ci0gICAgICAgICAgICAgICAgaWYgKGUuZ2V0VHlwZSgpID09IFN0YXR1cy5OT1RfUkVDT0dOSVpFRCkgewotICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgICAgIFNBWE1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShmQ29uZmlndXJhdGlvbi5nZXRMb2NhbGUoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICJwcm9wZXJ0eS1ub3QtcmVjb2duaXplZCIsIG5ldyBPYmplY3QgW10ge2lkZW50aWZpZXJ9KSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICAgICAgU0FYTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKGZDb25maWd1cmF0aW9uLmdldExvY2FsZSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgInByb3BlcnR5LW5vdC1zdXBwb3J0ZWQiLCBuZXcgT2JqZWN0IFtdIHtpZGVudGlmaWVyfSkpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHByaXZhdGUgdm9pZCByZXNldFNjaGVtYVZhbGlkYXRvcigpIHRocm93cyBTQVhFeGNlcHRpb24gewotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICBmU0FYUGFyc2VyLmZTY2hlbWFWYWxpZGF0b3IucmVzZXQoZlNBWFBhcnNlci5mU2NoZW1hVmFsaWRhdG9yQ29tcG9uZW50TWFuYWdlcik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyBUaGlzIHNob3VsZCBuZXZlciBiZSB0aHJvd24gZnJvbSB0aGUgc2NoZW1hIHZhbGlkYXRvci4KLSAgICAgICAgICAgIGNhdGNoIChYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKGUpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvamF4cC9TY2hlbWFWYWxpZGF0b3JDb25maWd1cmF0aW9uLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9qYXhwL1NjaGVtYVZhbGlkYXRvckNvbmZpZ3VyYXRpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOWVmODBiZS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9qYXhwL1NjaGVtYVZhbGlkYXRvckNvbmZpZ3VyYXRpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE5MiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmpheHA7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5YTUxFcnJvclJlcG9ydGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC52YWxpZGF0aW9uLlZhbGlkYXRpb25NYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5YU01lc3NhZ2VGb3JtYXR0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5qYXhwLnZhbGlkYXRpb24uWFNHcmFtbWFyUG9vbENvbnRhaW5lcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuRmVhdHVyZVN0YXRlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5Qcm9wZXJ0eVN0YXRlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLmdyYW1tYXJzLlhNTEdyYW1tYXJQb29sOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxDb21wb25lbnRNYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uOwotCi0vKioKLSAqIDxwPlBhcnNlciBjb25maWd1cmF0aW9uIGZvciBYZXJjZXMnIFhNTFNjaGVtYVZhbGlkYXRvci48L3A+Ci0gKgotICogQHZlcnNpb24gJElkOiBTY2hlbWFWYWxpZGF0b3JDb25maWd1cmF0aW9uLmphdmEsdiAxLjUgMjAxMC0xMS0wMSAwNDo0MDowNiBqb2VodyBFeHAgJAotICovCi1maW5hbCBjbGFzcyBTY2hlbWFWYWxpZGF0b3JDb25maWd1cmF0aW9uIGltcGxlbWVudHMgWE1MQ29tcG9uZW50TWFuYWdlciB7Ci0KLSAgICAvLyBmZWF0dXJlIGlkZW50aWZpZXJzCi0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiBzY2hlbWEgdmFsaWRhdGlvbi4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgU0NIRU1BX1ZBTElEQVRJT04gPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLlNDSEVNQV9WQUxJREFUSU9OX0ZFQVRVUkU7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiB2YWxpZGF0aW9uLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBWQUxJREFUSU9OID0KLSAgICAgICAgQ29uc3RhbnRzLlNBWF9GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5WQUxJREFUSU9OX0ZFQVRVUkU7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiB1c2UgZ3JhbW1hciBwb29sIG9ubHkuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFVTRV9HUkFNTUFSX1BPT0xfT05MWSA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuVVNFX0dSQU1NQVJfUE9PTF9PTkxZX0ZFQVRVUkU7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiBwYXJzZXIgc2V0dGluZ3MuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFBBUlNFUl9TRVRUSU5HUyA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuUEFSU0VSX1NFVFRJTkdTOwotCi0gICAgLy8gcHJvcGVydHkgaWRlbnRpZmllcnMKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBlcnJvciByZXBvcnRlci4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJST1JfUkVQT1JURVIgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5FUlJPUl9SRVBPUlRFUl9QUk9QRVJUWTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiB2YWxpZGF0aW9uIG1hbmFnZXIuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFZBTElEQVRJT05fTUFOQUdFUiA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLlZBTElEQVRJT05fTUFOQUdFUl9QUk9QRVJUWTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBncmFtbWFyIHBvb2wuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFhNTEdSQU1NQVJfUE9PTCA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLlhNTEdSQU1NQVJfUE9PTF9QUk9QRVJUWTsKLQotICAgIC8vCi0gICAgLy8gRGF0YQotICAgIC8vCi0KLSAgICAvKiogUGFyZW50IGNvbXBvbmVudCBtYW5hZ2VyLiAqKi8KLSAgICBwcml2YXRlIGZpbmFsIFhNTENvbXBvbmVudE1hbmFnZXIgZlBhcmVudENvbXBvbmVudE1hbmFnZXI7Ci0KLSAgICAvKiogVGhlIFNjaGVtYSdzIGdyYW1tYXIgcG9vbC4gKiovCi0gICAgcHJpdmF0ZSBmaW5hbCBYTUxHcmFtbWFyUG9vbCBmR3JhbW1hclBvb2w7Ci0KLSAgICAvKioKLSAgICAgKiBUcmFja3Mgd2hldGhlciB0aGUgdmFsaWRhdG9yIHNob3VsZCB1c2UgY29tcG9uZW50cyBmcm9tCi0gICAgICogdGhlIGdyYW1tYXIgcG9vbCB0byB0aGUgZXhjbHVzaW9uIG9mIGFsbCBvdGhlcnMuCi0gICAgICovCi0gICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIGZVc2VHcmFtbWFyUG9vbE9ubHk7Ci0KLSAgICAvKiogVmFsaWRhdGlvbiBtYW5hZ2VyLiAqLwotICAgIHByaXZhdGUgZmluYWwgVmFsaWRhdGlvbk1hbmFnZXIgZlZhbGlkYXRpb25NYW5hZ2VyOwotCi0gICAgcHVibGljIFNjaGVtYVZhbGlkYXRvckNvbmZpZ3VyYXRpb24oWE1MQ29tcG9uZW50TWFuYWdlciBwYXJlbnRNYW5hZ2VyLAotICAgICAgICAgICAgWFNHcmFtbWFyUG9vbENvbnRhaW5lciBncmFtbWFyQ29udGFpbmVyLCBWYWxpZGF0aW9uTWFuYWdlciB2YWxpZGF0aW9uTWFuYWdlcikgewotICAgICAgICBmUGFyZW50Q29tcG9uZW50TWFuYWdlciA9IHBhcmVudE1hbmFnZXI7Ci0gICAgICAgIGZHcmFtbWFyUG9vbCA9IGdyYW1tYXJDb250YWluZXIuZ2V0R3JhbW1hclBvb2woKTsKLSAgICAgICAgZlVzZUdyYW1tYXJQb29sT25seSA9IGdyYW1tYXJDb250YWluZXIuaXNGdWxseUNvbXBvc2VkKCk7Ci0gICAgICAgIGZWYWxpZGF0aW9uTWFuYWdlciA9IHZhbGlkYXRpb25NYW5hZ2VyOwotICAgICAgICAvLyBhZGQgc2NoZW1hIG1lc3NhZ2UgZm9ybWF0dGVyIHRvIGVycm9yIHJlcG9ydGVyCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBYTUxFcnJvclJlcG9ydGVyIGVycm9yUmVwb3J0ZXIgPSAoWE1MRXJyb3JSZXBvcnRlcikgZlBhcmVudENvbXBvbmVudE1hbmFnZXIuZ2V0UHJvcGVydHkoRVJST1JfUkVQT1JURVIpOwotICAgICAgICAgICAgaWYgKGVycm9yUmVwb3J0ZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGVycm9yUmVwb3J0ZXIucHV0TWVzc2FnZUZvcm1hdHRlcihYU01lc3NhZ2VGb3JtYXR0ZXIuU0NIRU1BX0RPTUFJTiwgbmV3IFhTTWVzc2FnZUZvcm1hdHRlcigpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICAvLyBJZ25vcmUgZXhjZXB0aW9uLgotICAgICAgICBjYXRjaCAoWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBleGMpIHt9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgc3RhdGUgb2YgYSBmZWF0dXJlLgotICAgICAqCi0gICAgICogQHBhcmFtIGZlYXR1cmVJZCBUaGUgZmVhdHVyZSBpZGVudGlmaWVyLgotICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgZmVhdHVyZSBpcyBzdXBwb3J0ZWQKLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBUaHJvd24gZm9yIGNvbmZpZ3VyYXRpb24gZXJyb3IuCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluIGdlbmVyYWwsIGNvbXBvbmVudHMgc2hvdWxkCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9ubHkgdGhyb3cgdGhpcyBleGNlcHRpb24gaWYKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXQgaXMgPHN0cm9uZz5yZWFsbHk8L3N0cm9uZz4KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYSBjcml0aWNhbCBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXRGZWF0dXJlKFN0cmluZyBmZWF0dXJlSWQpCi0gICAgICAgICAgICB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiB7Ci0gICAgICAgIEZlYXR1cmVTdGF0ZSBzdGF0ZSA9IGdldEZlYXR1cmVTdGF0ZShmZWF0dXJlSWQpOwotICAgICAgICBpZiAoc3RhdGUuaXNFeGNlcHRpb25hbCgpKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbihzdGF0ZS5zdGF0dXMsIGZlYXR1cmVJZCk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHN0YXRlLnN0YXRlOwotICAgIH0KLQotICAgIHB1YmxpYyBGZWF0dXJlU3RhdGUgZ2V0RmVhdHVyZVN0YXRlKFN0cmluZyBmZWF0dXJlSWQpIHsKLSAgICAgICAgaWYgKFBBUlNFUl9TRVRUSU5HUy5lcXVhbHMoZmVhdHVyZUlkKSkgewotICAgICAgICAgICAgcmV0dXJuIGZQYXJlbnRDb21wb25lbnRNYW5hZ2VyLmdldEZlYXR1cmVTdGF0ZShmZWF0dXJlSWQpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKFZBTElEQVRJT04uZXF1YWxzKGZlYXR1cmVJZCkgfHwgU0NIRU1BX1ZBTElEQVRJT04uZXF1YWxzKGZlYXR1cmVJZCkpIHsKLSAgICAgICAgICAgIHJldHVybiBGZWF0dXJlU3RhdGUuaXModHJ1ZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoVVNFX0dSQU1NQVJfUE9PTF9PTkxZLmVxdWFscyhmZWF0dXJlSWQpKSB7Ci0gICAgICAgICAgICByZXR1cm4gRmVhdHVyZVN0YXRlLmlzKGZVc2VHcmFtbWFyUG9vbE9ubHkpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmUGFyZW50Q29tcG9uZW50TWFuYWdlci5nZXRGZWF0dXJlU3RhdGUoZmVhdHVyZUlkKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgUHJvcGVydHlTdGF0ZSBnZXRQcm9wZXJ0eVN0YXRlKFN0cmluZyBwcm9wZXJ0eUlkKSB7Ci0gICAgICAgIGlmIChYTUxHUkFNTUFSX1BPT0wuZXF1YWxzKHByb3BlcnR5SWQpKSB7Ci0gICAgICAgICAgICByZXR1cm4gUHJvcGVydHlTdGF0ZS5pcyhmR3JhbW1hclBvb2wpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKFZBTElEQVRJT05fTUFOQUdFUi5lcXVhbHMocHJvcGVydHlJZCkpIHsKLSAgICAgICAgICAgIHJldHVybiBQcm9wZXJ0eVN0YXRlLmlzKGZWYWxpZGF0aW9uTWFuYWdlcik7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGZQYXJlbnRDb21wb25lbnRNYW5hZ2VyLmdldFByb3BlcnR5U3RhdGUocHJvcGVydHlJZCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgYSBwcm9wZXJ0eS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBwcm9wZXJ0eUlkIFRoZSBwcm9wZXJ0eSBpZGVudGlmaWVyLgotICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBwcm9wZXJ0eQotICAgICAqCi0gICAgICogQHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIFRocm93biBmb3IgY29uZmlndXJhdGlvbiBlcnJvci4KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW4gZ2VuZXJhbCwgY29tcG9uZW50cyBzaG91bGQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb25seSB0aHJvdyB0aGlzIGV4Y2VwdGlvbiBpZgotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdCBpcyA8c3Ryb25nPnJlYWxseTwvc3Ryb25nPgotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhIGNyaXRpY2FsIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyBPYmplY3QgZ2V0UHJvcGVydHkoU3RyaW5nIHByb3BlcnR5SWQpCi0gICAgICAgICAgICB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiB7Ci0gICAgICAgIFByb3BlcnR5U3RhdGUgc3RhdGUgPSBnZXRQcm9wZXJ0eVN0YXRlKHByb3BlcnR5SWQpOwotICAgICAgICBpZiAoc3RhdGUuaXNFeGNlcHRpb25hbCgpKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbihzdGF0ZS5zdGF0dXMsIHByb3BlcnR5SWQpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBzdGF0ZS5zdGF0ZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXRGZWF0dXJlKFN0cmluZyBmZWF0dXJlSWQsIGJvb2xlYW4gZGVmYXVsdFZhbHVlKSB7Ci0gICAgICAgIEZlYXR1cmVTdGF0ZSBzdGF0ZSA9IGdldEZlYXR1cmVTdGF0ZShmZWF0dXJlSWQpOwotICAgICAgICBpZiAoc3RhdGUuaXNFeGNlcHRpb25hbCgpKSB7Ci0gICAgICAgICAgICByZXR1cm4gZGVmYXVsdFZhbHVlOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBzdGF0ZS5zdGF0ZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgT2JqZWN0IGdldFByb3BlcnR5KFN0cmluZyBwcm9wZXJ0eUlkLCBPYmplY3QgZGVmYXVsdFZhbHVlKSB7Ci0gICAgICAgIFByb3BlcnR5U3RhdGUgc3RhdGUgPSBnZXRQcm9wZXJ0eVN0YXRlKHByb3BlcnR5SWQpOwotICAgICAgICBpZiAoc3RhdGUuaXNFeGNlcHRpb25hbCgpKSB7Ci0gICAgICAgICAgICByZXR1cm4gZGVmYXVsdFZhbHVlOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBzdGF0ZS5zdGF0ZTsKLSAgICB9Ci0KLQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9qYXhwL1RlZVhNTERvY3VtZW50RmlsdGVySW1wbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvamF4cC9UZWVYTUxEb2N1bWVudEZpbHRlckltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNjk2NzE3YS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9qYXhwL1RlZVhNTERvY3VtZW50RmlsdGVySW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTc2ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuamF4cDsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLkF1Z21lbnRhdGlvbnM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuTmFtZXNwYWNlQ29udGV4dDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5RTmFtZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxBdHRyaWJ1dGVzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTERvY3VtZW50SGFuZGxlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxMb2NhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTFJlc291cmNlSWRlbnRpZmllcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxTdHJpbmc7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE5JRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxEb2N1bWVudEZpbHRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MRG9jdW1lbnRTb3VyY2U7Ci0KLS8qKgotICogPHA+WE1MRG9jdW1lbnRIYW5kbGVyIHdoaWNoIGZvcmtzIHRoZSBwaXBlbGluZSB0byB0d28gb3RoZXIgY29tcG9uZW50cy48L3A+Ci0gKgotICogQGF1dGhvciBLb2hzdWtlIEthd2FndWNoaSAoa29oc3VrZS5rYXdhZ3VjaGlAc3VuLmNvbSkKLSAqLwotY2xhc3MgVGVlWE1MRG9jdW1lbnRGaWx0ZXJJbXBsIGltcGxlbWVudHMgWE1MRG9jdW1lbnRGaWx0ZXIgewotCi0gICAgLyoqCi0gICAgICogVGhlIG5leHQgY29tcG9uZW50IGluIHRoZSBwaXBlbGluZSB3aG8gcmVjZWl2ZXMgdGhlIGV2ZW50LgotICAgICAqIFRoaXMgY29tcG9uZW50IHJlY2VpdmVzIGV2ZW50cyBhZnRlciB0aGUgInNpZGUiIGhhbmRsZXIKLSAgICAgKiByZWNlaXZlcyB0aGVtLgotICAgICAqLwotICAgIHByaXZhdGUgWE1MRG9jdW1lbnRIYW5kbGVyIG5leHQ7Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgY29tcG9uZW50IHdobyBpbnRlcmNlcHRzIGV2ZW50cy4KLSAgICAgKi8KLSAgICBwcml2YXRlIFhNTERvY3VtZW50SGFuZGxlciBzaWRlOwotCi0gICAgLyoqCi0gICAgICogVGhlIHNvdXJjZSBvZiB0aGUgZXZlbnQuCi0gICAgICovCi0gICAgcHJpdmF0ZSBYTUxEb2N1bWVudFNvdXJjZSBzb3VyY2U7Ci0KLSAgICBwdWJsaWMgWE1MRG9jdW1lbnRIYW5kbGVyIGdldFNpZGUoKSB7Ci0gICAgICAgIHJldHVybiBzaWRlOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldFNpZGUoWE1MRG9jdW1lbnRIYW5kbGVyIHNpZGUpIHsKLSAgICAgICAgdGhpcy5zaWRlID0gc2lkZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgWE1MRG9jdW1lbnRTb3VyY2UgZ2V0RG9jdW1lbnRTb3VyY2UoKSB7Ci0gICAgICAgIHJldHVybiBzb3VyY2U7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0RG9jdW1lbnRTb3VyY2UoWE1MRG9jdW1lbnRTb3VyY2Ugc291cmNlKSB7Ci0gICAgICAgIHRoaXMuc291cmNlID0gc291cmNlOwotICAgIH0KLQotICAgIHB1YmxpYyBYTUxEb2N1bWVudEhhbmRsZXIgZ2V0RG9jdW1lbnRIYW5kbGVyKCkgewotICAgICAgICByZXR1cm4gbmV4dDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXREb2N1bWVudEhhbmRsZXIoWE1MRG9jdW1lbnRIYW5kbGVyIGhhbmRsZXIpIHsKLSAgICAgICAgbmV4dCA9IGhhbmRsZXI7Ci0gICAgfQotCi0gICAgLy8KLSAgICAvLwotICAgIC8vICBYTUxEb2N1bWVudEhhbmRsZXIgaW1wbGVtZW50YXRpb24KLSAgICAvLwotICAgIC8vCi0KLSAgICBwdWJsaWMgdm9pZCBjaGFyYWN0ZXJzKFhNTFN0cmluZyB0ZXh0LCBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBzaWRlLmNoYXJhY3RlcnModGV4dCwgYXVncyk7Ci0gICAgICAgIG5leHQuY2hhcmFjdGVycyh0ZXh0LCBhdWdzKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBjb21tZW50KFhNTFN0cmluZyB0ZXh0LCBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBzaWRlLmNvbW1lbnQodGV4dCwgYXVncyk7Ci0gICAgICAgIG5leHQuY29tbWVudCh0ZXh0LCBhdWdzKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBkb2N0eXBlRGVjbChTdHJpbmcgcm9vdEVsZW1lbnQsIFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkLCBBdWdtZW50YXRpb25zIGF1Z3MpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBzaWRlLmRvY3R5cGVEZWNsKHJvb3RFbGVtZW50LCBwdWJsaWNJZCwgc3lzdGVtSWQsIGF1Z3MpOwotICAgICAgICBuZXh0LmRvY3R5cGVEZWNsKHJvb3RFbGVtZW50LCBwdWJsaWNJZCwgc3lzdGVtSWQsIGF1Z3MpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGVtcHR5RWxlbWVudChRTmFtZSBlbGVtZW50LCBYTUxBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIHNpZGUuZW1wdHlFbGVtZW50KGVsZW1lbnQsIGF0dHJpYnV0ZXMsIGF1Z3MpOwotICAgICAgICBuZXh0LmVtcHR5RWxlbWVudChlbGVtZW50LCBhdHRyaWJ1dGVzLCBhdWdzKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBlbmRDREFUQShBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBzaWRlLmVuZENEQVRBKGF1Z3MpOwotICAgICAgICBuZXh0LmVuZENEQVRBKGF1Z3MpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGVuZERvY3VtZW50KEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIHNpZGUuZW5kRG9jdW1lbnQoYXVncyk7Ci0gICAgICAgIG5leHQuZW5kRG9jdW1lbnQoYXVncyk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgZW5kRWxlbWVudChRTmFtZSBlbGVtZW50LCBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBzaWRlLmVuZEVsZW1lbnQoZWxlbWVudCwgYXVncyk7Ci0gICAgICAgIG5leHQuZW5kRWxlbWVudChlbGVtZW50LCBhdWdzKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBlbmRHZW5lcmFsRW50aXR5KFN0cmluZyBuYW1lLCBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBzaWRlLmVuZEdlbmVyYWxFbnRpdHkobmFtZSwgYXVncyk7Ci0gICAgICAgIG5leHQuZW5kR2VuZXJhbEVudGl0eShuYW1lLCBhdWdzKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBpZ25vcmFibGVXaGl0ZXNwYWNlKFhNTFN0cmluZyB0ZXh0LCBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBzaWRlLmlnbm9yYWJsZVdoaXRlc3BhY2UodGV4dCwgYXVncyk7Ci0gICAgICAgIG5leHQuaWdub3JhYmxlV2hpdGVzcGFjZSh0ZXh0LCBhdWdzKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oU3RyaW5nIHRhcmdldCwgWE1MU3RyaW5nIGRhdGEsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIHNpZGUucHJvY2Vzc2luZ0luc3RydWN0aW9uKHRhcmdldCwgZGF0YSwgYXVncyk7Ci0gICAgICAgIG5leHQucHJvY2Vzc2luZ0luc3RydWN0aW9uKHRhcmdldCwgZGF0YSwgYXVncyk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc3RhcnRDREFUQShBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBzaWRlLnN0YXJ0Q0RBVEEoYXVncyk7Ci0gICAgICAgIG5leHQuc3RhcnRDREFUQShhdWdzKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzdGFydERvY3VtZW50KAotICAgICAgICAgICAgWE1MTG9jYXRvciBsb2NhdG9yLAotICAgICAgICAgICAgU3RyaW5nIGVuY29kaW5nLAotICAgICAgICAgICAgTmFtZXNwYWNlQ29udGV4dCBuYW1lc3BhY2VDb250ZXh0LAotICAgICAgICAgICAgQXVnbWVudGF0aW9ucyBhdWdzKQotICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgc2lkZS5zdGFydERvY3VtZW50KGxvY2F0b3IsIGVuY29kaW5nLCBuYW1lc3BhY2VDb250ZXh0LCBhdWdzKTsKLSAgICAgICAgbmV4dC5zdGFydERvY3VtZW50KGxvY2F0b3IsIGVuY29kaW5nLCBuYW1lc3BhY2VDb250ZXh0LCBhdWdzKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQoUU5hbWUgZWxlbWVudCwgWE1MQXR0cmlidXRlcyBhdHRyaWJ1dGVzLCBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBzaWRlLnN0YXJ0RWxlbWVudChlbGVtZW50LCBhdHRyaWJ1dGVzLCBhdWdzKTsKLSAgICAgICAgbmV4dC5zdGFydEVsZW1lbnQoZWxlbWVudCwgYXR0cmlidXRlcywgYXVncyk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc3RhcnRHZW5lcmFsRW50aXR5KFN0cmluZyBuYW1lLCBYTUxSZXNvdXJjZUlkZW50aWZpZXIgaWRlbnRpZmllciwgU3RyaW5nIGVuY29kaW5nLCBBdWdtZW50YXRpb25zIGF1Z3MpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBzaWRlLnN0YXJ0R2VuZXJhbEVudGl0eShuYW1lLCBpZGVudGlmaWVyLCBlbmNvZGluZywgYXVncyk7Ci0gICAgICAgIG5leHQuc3RhcnRHZW5lcmFsRW50aXR5KG5hbWUsIGlkZW50aWZpZXIsIGVuY29kaW5nLCBhdWdzKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCB0ZXh0RGVjbChTdHJpbmcgdmVyc2lvbiwgU3RyaW5nIGVuY29kaW5nLCBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBzaWRlLnRleHREZWNsKHZlcnNpb24sIGVuY29kaW5nLCBhdWdzKTsKLSAgICAgICAgbmV4dC50ZXh0RGVjbCh2ZXJzaW9uLCBlbmNvZGluZywgYXVncyk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgeG1sRGVjbChTdHJpbmcgdmVyc2lvbiwgU3RyaW5nIGVuY29kaW5nLCBTdHJpbmcgc3RhbmRhbG9uZSwgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgc2lkZS54bWxEZWNsKHZlcnNpb24sIGVuY29kaW5nLCBzdGFuZGFsb25lLCBhdWdzKTsKLSAgICAgICAgbmV4dC54bWxEZWNsKHZlcnNpb24sIGVuY29kaW5nLCBzdGFuZGFsb25lLCBhdWdzKTsKLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2pheHAvVW5wYXJzZWRFbnRpdHlIYW5kbGVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9qYXhwL1VucGFyc2VkRW50aXR5SGFuZGxlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1NzE0ZGEzLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2pheHAvVW5wYXJzZWRFbnRpdHlIYW5kbGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyNjIgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5qYXhwOwotCi1pbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwudmFsaWRhdGlvbi5FbnRpdHlTdGF0ZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwudmFsaWRhdGlvbi5WYWxpZGF0aW9uTWFuYWdlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5BdWdtZW50YXRpb25zOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTERUREhhbmRsZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MTG9jYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxSZXNvdXJjZUlkZW50aWZpZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MU3RyaW5nOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhOSUV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MRFRERmlsdGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxEVERTb3VyY2U7Ci0KLS8qKgotICogPHA+VGhpcyBmaWx0ZXIgcmVjb3JkcyB3aGljaCB1bnBhcnNlZCBlbnRpdGllcyBoYXZlIGJlZW4KLSAqIGRlY2xhcmVkIGluIHRoZSBEVEQgYW5kIHByb3ZpZGVzIHRoaXMgaW5mb3JtYXRpb24gdG8gYSBWYWxpZGF0aW9uTWFuYWdlci4KLSAqIEV2ZW50cyBhcmUgZm9yd2FyZGVkIHRvIHRoZSByZWdpc3RlcmVkIFhNTERUREhhbmRsZXIgd2l0aG91dCBtb2RpZmljYXRpb24uPC9wPgotICoKLSAqIEBhdXRob3IgTWljaGFlbCBHbGF2YXNzZXZpY2gsIElCTQotICogQHZlcnNpb24gJElkOiBVbnBhcnNlZEVudGl0eUhhbmRsZXIuamF2YSx2IDEuNiAyMDEwLTExLTAxIDA0OjQwOjA3IGpvZWh3IEV4cCAkCi0gKi8KLWZpbmFsIGNsYXNzIFVucGFyc2VkRW50aXR5SGFuZGxlciBpbXBsZW1lbnRzIFhNTERUREZpbHRlciwgRW50aXR5U3RhdGUgewotCi0gICAgLyoqIERURCBzb3VyY2UgYW5kIGhhbmRsZXIuICoqLwotICAgIHByaXZhdGUgWE1MRFREU291cmNlIGZEVERTb3VyY2U7Ci0gICAgcHJpdmF0ZSBYTUxEVERIYW5kbGVyIGZEVERIYW5kbGVyOwotCi0gICAgLyoqIFZhbGlkYXRpb24gbWFuYWdlci4gKi8KLSAgICBwcml2YXRlIGZpbmFsIFZhbGlkYXRpb25NYW5hZ2VyIGZWYWxpZGF0aW9uTWFuYWdlcjsKLQotICAgIC8qKiBNYXAgZm9yIHRyYWNraW5nIHVucGFyc2VkIGVudGl0aWVzLiAqLwotICAgIHByaXZhdGUgSGFzaE1hcCBmVW5wYXJzZWRFbnRpdGllcyA9IG51bGw7Ci0KLSAgICBVbnBhcnNlZEVudGl0eUhhbmRsZXIoVmFsaWRhdGlvbk1hbmFnZXIgbWFuYWdlcikgewotICAgICAgICBmVmFsaWRhdGlvbk1hbmFnZXIgPSBtYW5hZ2VyOwotICAgIH0KLQotICAgIC8qCi0gICAgICogWE1MRFRESGFuZGxlciBtZXRob2RzCi0gICAgICovCi0KLSAgICBwdWJsaWMgdm9pZCBzdGFydERURChYTUxMb2NhdG9yIGxvY2F0b3IsIEF1Z21lbnRhdGlvbnMgYXVnbWVudGF0aW9ucykKLSAgICAgICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBmVmFsaWRhdGlvbk1hbmFnZXIuc2V0RW50aXR5U3RhdGUodGhpcyk7Ci0gICAgICAgIGlmIChmRFRESGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmRFRESGFuZGxlci5zdGFydERURChsb2NhdG9yLCBhdWdtZW50YXRpb25zKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHN0YXJ0UGFyYW1ldGVyRW50aXR5KFN0cmluZyBuYW1lLAotICAgICAgICAgICAgWE1MUmVzb3VyY2VJZGVudGlmaWVyIGlkZW50aWZpZXIsIFN0cmluZyBlbmNvZGluZywKLSAgICAgICAgICAgIEF1Z21lbnRhdGlvbnMgYXVnbWVudGF0aW9ucykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChmRFRESGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmRFRESGFuZGxlci5zdGFydFBhcmFtZXRlckVudGl0eShuYW1lLCBpZGVudGlmaWVyLCBlbmNvZGluZywgYXVnbWVudGF0aW9ucyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCB0ZXh0RGVjbChTdHJpbmcgdmVyc2lvbiwgU3RyaW5nIGVuY29kaW5nLAotICAgICAgICAgICAgQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKGZEVERIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZEVERIYW5kbGVyLnRleHREZWNsKHZlcnNpb24sIGVuY29kaW5nLCBhdWdtZW50YXRpb25zKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGVuZFBhcmFtZXRlckVudGl0eShTdHJpbmcgbmFtZSwgQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKQotICAgICAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChmRFRESGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmRFRESGFuZGxlci5lbmRQYXJhbWV0ZXJFbnRpdHkobmFtZSwgYXVnbWVudGF0aW9ucyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzdGFydEV4dGVybmFsU3Vic2V0KFhNTFJlc291cmNlSWRlbnRpZmllciBpZGVudGlmaWVyLAotICAgICAgICAgICAgQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKGZEVERIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZEVERIYW5kbGVyLnN0YXJ0RXh0ZXJuYWxTdWJzZXQoaWRlbnRpZmllciwgYXVnbWVudGF0aW9ucyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBlbmRFeHRlcm5hbFN1YnNldChBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpCi0gICAgICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKGZEVERIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZEVERIYW5kbGVyLmVuZEV4dGVybmFsU3Vic2V0KGF1Z21lbnRhdGlvbnMpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgY29tbWVudChYTUxTdHJpbmcgdGV4dCwgQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKQotICAgICAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChmRFRESGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmRFRESGFuZGxlci5jb21tZW50KHRleHQsIGF1Z21lbnRhdGlvbnMpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgcHJvY2Vzc2luZ0luc3RydWN0aW9uKFN0cmluZyB0YXJnZXQsIFhNTFN0cmluZyBkYXRhLAotICAgICAgICAgICAgQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKGZEVERIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZEVERIYW5kbGVyLnByb2Nlc3NpbmdJbnN0cnVjdGlvbih0YXJnZXQsIGRhdGEsIGF1Z21lbnRhdGlvbnMpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgZWxlbWVudERlY2woU3RyaW5nIG5hbWUsIFN0cmluZyBjb250ZW50TW9kZWwsCi0gICAgICAgICAgICBBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBpZiAoZkRUREhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkRUREhhbmRsZXIuZWxlbWVudERlY2wobmFtZSwgY29udGVudE1vZGVsLCBhdWdtZW50YXRpb25zKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHN0YXJ0QXR0bGlzdChTdHJpbmcgZWxlbWVudE5hbWUsIEF1Z21lbnRhdGlvbnMgYXVnbWVudGF0aW9ucykKLSAgICAgICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBpZiAoZkRUREhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkRUREhhbmRsZXIuc3RhcnRBdHRsaXN0KGVsZW1lbnROYW1lLCBhdWdtZW50YXRpb25zKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGF0dHJpYnV0ZURlY2woU3RyaW5nIGVsZW1lbnROYW1lLCBTdHJpbmcgYXR0cmlidXRlTmFtZSwKLSAgICAgICAgICAgIFN0cmluZyB0eXBlLCBTdHJpbmdbXSBlbnVtZXJhdGlvbiwgU3RyaW5nIGRlZmF1bHRUeXBlLAotICAgICAgICAgICAgWE1MU3RyaW5nIGRlZmF1bHRWYWx1ZSwgWE1MU3RyaW5nIG5vbk5vcm1hbGl6ZWREZWZhdWx0VmFsdWUsCi0gICAgICAgICAgICBBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBpZiAoZkRUREhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkRUREhhbmRsZXIuYXR0cmlidXRlRGVjbChlbGVtZW50TmFtZSwgYXR0cmlidXRlTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgdHlwZSwgZW51bWVyYXRpb24sIGRlZmF1bHRUeXBlLAotICAgICAgICAgICAgICAgICAgICBkZWZhdWx0VmFsdWUsIG5vbk5vcm1hbGl6ZWREZWZhdWx0VmFsdWUsCi0gICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgZW5kQXR0bGlzdChBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBpZiAoZkRUREhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkRUREhhbmRsZXIuZW5kQXR0bGlzdChhdWdtZW50YXRpb25zKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGludGVybmFsRW50aXR5RGVjbChTdHJpbmcgbmFtZSwgWE1MU3RyaW5nIHRleHQsCi0gICAgICAgICAgICBYTUxTdHJpbmcgbm9uTm9ybWFsaXplZFRleHQsIEF1Z21lbnRhdGlvbnMgYXVnbWVudGF0aW9ucykKLSAgICAgICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBpZiAoZkRUREhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkRUREhhbmRsZXIuaW50ZXJuYWxFbnRpdHlEZWNsKG5hbWUsIHRleHQsCi0gICAgICAgICAgICAgICAgICAgIG5vbk5vcm1hbGl6ZWRUZXh0LCBhdWdtZW50YXRpb25zKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGV4dGVybmFsRW50aXR5RGVjbChTdHJpbmcgbmFtZSwKLSAgICAgICAgICAgIFhNTFJlc291cmNlSWRlbnRpZmllciBpZGVudGlmaWVyLCBBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpCi0gICAgICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKGZEVERIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZEVERIYW5kbGVyLmV4dGVybmFsRW50aXR5RGVjbChuYW1lLCBpZGVudGlmaWVyLCBhdWdtZW50YXRpb25zKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHVucGFyc2VkRW50aXR5RGVjbChTdHJpbmcgbmFtZSwKLSAgICAgICAgICAgIFhNTFJlc291cmNlSWRlbnRpZmllciBpZGVudGlmaWVyLCBTdHJpbmcgbm90YXRpb24sCi0gICAgICAgICAgICBBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBpZiAoZlVucGFyc2VkRW50aXRpZXMgPT0gbnVsbCkgewotICAgICAgICAgICAgZlVucGFyc2VkRW50aXRpZXMgPSBuZXcgSGFzaE1hcCgpOwotICAgICAgICB9Ci0gICAgICAgIGZVbnBhcnNlZEVudGl0aWVzLnB1dChuYW1lLCBuYW1lKTsKLSAgICAgICAgaWYgKGZEVERIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZEVERIYW5kbGVyLnVucGFyc2VkRW50aXR5RGVjbChuYW1lLCBpZGVudGlmaWVyLCBub3RhdGlvbiwgYXVnbWVudGF0aW9ucyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBub3RhdGlvbkRlY2woU3RyaW5nIG5hbWUsIFhNTFJlc291cmNlSWRlbnRpZmllciBpZGVudGlmaWVyLAotICAgICAgICAgICAgQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKGZEVERIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZEVERIYW5kbGVyLm5vdGF0aW9uRGVjbChuYW1lLCBpZGVudGlmaWVyLCBhdWdtZW50YXRpb25zKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHN0YXJ0Q29uZGl0aW9uYWwoc2hvcnQgdHlwZSwgQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKQotICAgICAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChmRFRESGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmRFRESGFuZGxlci5zdGFydENvbmRpdGlvbmFsKHR5cGUsIGF1Z21lbnRhdGlvbnMpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgaWdub3JlZENoYXJhY3RlcnMoWE1MU3RyaW5nIHRleHQsIEF1Z21lbnRhdGlvbnMgYXVnbWVudGF0aW9ucykKLSAgICAgICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBpZiAoZkRUREhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkRUREhhbmRsZXIuaWdub3JlZENoYXJhY3RlcnModGV4dCwgYXVnbWVudGF0aW9ucyk7Ci0gICAgICAgIH0KLQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGVuZENvbmRpdGlvbmFsKEF1Z21lbnRhdGlvbnMgYXVnbWVudGF0aW9ucykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChmRFRESGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmRFRESGFuZGxlci5lbmRDb25kaXRpb25hbChhdWdtZW50YXRpb25zKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGVuZERURChBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBpZiAoZkRUREhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkRUREhhbmRsZXIuZW5kRFREKGF1Z21lbnRhdGlvbnMpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0RFREU291cmNlKFhNTERURFNvdXJjZSBzb3VyY2UpIHsKLSAgICAgICAgZkRURFNvdXJjZSA9IHNvdXJjZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgWE1MRFREU291cmNlIGdldERURFNvdXJjZSgpIHsKLSAgICAgICAgcmV0dXJuIGZEVERTb3VyY2U7Ci0gICAgfQotCi0gICAgLyoKLSAgICAgKiBYTUxEVERTb3VyY2UgbWV0aG9kcwotICAgICAqLwotCi0gICAgcHVibGljIHZvaWQgc2V0RFRESGFuZGxlcihYTUxEVERIYW5kbGVyIGhhbmRsZXIpIHsKLSAgICAgICAgZkRUREhhbmRsZXIgPSBoYW5kbGVyOwotICAgIH0KLQotICAgIHB1YmxpYyBYTUxEVERIYW5kbGVyIGdldERUREhhbmRsZXIoKSB7Ci0gICAgICAgIHJldHVybiBmRFRESGFuZGxlcjsKLSAgICB9Ci0KLSAgICAvKgotICAgICAqIEVudGl0eVN0YXRlIG1ldGhvZHMKLSAgICAgKi8KLQotICAgIHB1YmxpYyBib29sZWFuIGlzRW50aXR5RGVjbGFyZWQoU3RyaW5nIG5hbWUpIHsKLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGlzRW50aXR5VW5wYXJzZWQoU3RyaW5nIG5hbWUpIHsKLSAgICAgICAgaWYgKGZVbnBhcnNlZEVudGl0aWVzICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBmVW5wYXJzZWRFbnRpdGllcy5jb250YWluc0tleShuYW1lKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgLyoKLSAgICAgKiBPdGhlciBtZXRob2RzCi0gICAgICovCi0KLSAgICBwdWJsaWMgdm9pZCByZXNldCgpIHsKLSAgICAgICAgaWYgKGZVbnBhcnNlZEVudGl0aWVzICE9IG51bGwgJiYgIWZVbnBhcnNlZEVudGl0aWVzLmlzRW1wdHkoKSkgewotICAgICAgICAgICAgLy8gc2hvdWxkIG9ubHkgY2xlYXIgdGhpcyBpZiB0aGUgbGFzdCBkb2N1bWVudCBjb250YWluZWQgdW5wYXJzZWQgZW50aXRpZXMKLSAgICAgICAgICAgIGZVbnBhcnNlZEVudGl0aWVzLmNsZWFyKCk7Ci0gICAgICAgIH0KLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9qYXhwL2RhdGF0eXBlL0RhdGF0eXBlRmFjdG9yeUltcGwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2pheHAvZGF0YXR5cGUvRGF0YXR5cGVGYWN0b3J5SW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1OTQ5N2E0Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2pheHAvZGF0YXR5cGUvRGF0YXR5cGVGYWN0b3J5SW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNjUyICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuamF4cC5kYXRhdHlwZTsKLQotaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOwotaW1wb3J0IGphdmEubWF0aC5CaWdEZWNpbWFsOwotaW1wb3J0IGphdmEudXRpbC5HcmVnb3JpYW5DYWxlbmRhcjsKLQotaW1wb3J0IGphdmF4LnhtbC5kYXRhdHlwZS5EYXRhdHlwZUNvbnN0YW50czsKLWltcG9ydCBqYXZheC54bWwuZGF0YXR5cGUuRGF0YXR5cGVGYWN0b3J5OwotaW1wb3J0IGphdmF4LnhtbC5kYXRhdHlwZS5EdXJhdGlvbjsKLWltcG9ydCBqYXZheC54bWwuZGF0YXR5cGUuWE1MR3JlZ29yaWFuQ2FsZW5kYXI7Ci0KLS8qKgotICogPHA+RmFjdG9yeSB0aGF0IGNyZWF0ZXMgbmV3IDxjb2RlPmphdmF4LnhtbC5kYXRhdHlwZTwvY29kZT4gPGNvZGU+T2JqZWN0PC9jb2RlPnMgdGhhdCBtYXAgWE1MIHRvL2Zyb20gSmF2YSA8Y29kZT5PYmplY3Q8L2NvZGU+cy48L3A+Ci0gKgotICogPHAgaWQ9IkRhdGF0eXBlRmFjdG9yeS5uZXdJbnN0YW5jZSI+e0BsaW5rICNuZXdJbnN0YW5jZSgpfSBpcyB1c2VkIHRvIGNyZWF0ZSBhIG5ldyA8Y29kZT5EYXRhdHlwZUZhY3Rvcnk8L2NvZGU+LgotICogVGhlIGZvbGxvd2luZyBpbXBsZW1lbnRhdGlvbiByZXNvbHV0aW9uIG1lY2hhbmlzbXMgYXJlIHVzZWQgaW4gdGhlIGZvbGxvd2luZyBvcmRlcjo8L3A+Ci0gKiA8b2w+Ci0gKiAgICA8bGk+Ci0gKiAgICAgIElmIHRoZSBzeXN0ZW0gcHJvcGVydHkgc3BlY2lmaWVkIGJ5IHtAbGluayAjREFUQVRZUEVGQUNUT1JZX1BST1BFUlRZfSwgIjxjb2RlPmphdmF4LnhtbC5kYXRhdHlwZS5EYXRhdHlwZUZhY3Rvcnk8L2NvZGU+IiwKLSAqICAgICAgZXhpc3RzLCBhIGNsYXNzIHdpdGggdGhlIG5hbWUgb2YgdGhlIHByb3BlcnR5J3MgdmFsdWUgaXMgaW5zdGFudGlhdGVkLgotICogICAgICBBbnkgRXhjZXB0aW9uIHRocm93biBkdXJpbmcgdGhlIGluc3RhbnRpYXRpb24gcHJvY2VzcyBpcyB3cmFwcGVkIGFzIGEge0BsaW5rIERhdGF0eXBlQ29uZmlndXJhdGlvbkV4Y2VwdGlvbn0uCi0gKiAgICA8L2xpPgotICogICAgPGxpPgotICogICAgICBJZiB0aGUgZmlsZSAke0pBVkFfSE9NRX0vbGliL2pheHAucHJvcGVydGllcyBleGlzdHMsIGl0IGlzIGxvYWRlZCBpbiBhIHtAbGluayBqYXZhLnV0aWwuUHJvcGVydGllc30gPGNvZGU+T2JqZWN0PC9jb2RlPi4KLSAqICAgICAgVGhlIDxjb2RlPlByb3BlcnRpZXM8L2NvZGU+IDxjb2RlPk9iamVjdCA8L2NvZGU+IGlzIHRoZW4gcXVlcmllZCBmb3IgdGhlIHByb3BlcnR5IGFzIGRvY3VtZW50ZWQgaW4gdGhlIHByaW9yIHN0ZXAKLSAqICAgICAgYW5kIHByb2Nlc3NlZCBhcyBkb2N1bWVudGVkIGluIHRoZSBwcmlvciBzdGVwLgotICogICAgPC9saT4KLSAqICAgIDxsaT4KLSAqICAgICAgVGhlIHNlcnZpY2VzIHJlc29sdXRpb24gbWVjaGFuaXNtIGlzIHVzZWQsIGUuZy4gPGNvZGU+TUVUQS1JTkYvc2VydmljZXMvamF2YS54bWwuZGF0YXR5cGUuRGF0YXR5cGVGYWN0b3J5PC9jb2RlPi4KLSAqICAgICAgQW55IEV4Y2VwdGlvbiB0aHJvd24gZHVyaW5nIHRoZSBpbnN0YW50aWF0aW9uIHByb2Nlc3MgaXMgd3JhcHBlZCBhcyBhIHtAbGluayBEYXRhdHlwZUNvbmZpZ3VyYXRpb25FeGNlcHRpb259LgotICogICAgPC9saT4KLSAqICAgIDxsaT4KLSAqICAgICAgVGhlIGZpbmFsIG1lY2hhbmlzbSBpcyB0byBhdHRlbXB0IHRvIGluc3RhbnRpYXRlIHRoZSA8Y29kZT5DbGFzczwvY29kZT4gc3BlY2lmaWVkIGJ5Ci0gKiAgICAgIHtAbGluayAjREFUQVRZUEVGQUNUT1JZX0lNUExFTUVOVEFUSU9OX0NMQVNTfSwgIjxjb2RlPmphdmF4LnhtbC5kYXRhdHlwZS5EYXRhdHlwZUZhY3RvcnlJbXBsPC9jb2RlPiIuCi0gKiAgICAgIEFueSBFeGNlcHRpb24gdGhyb3duIGR1cmluZyB0aGUgaW5zdGFudGlhdGlvbiBwcm9jZXNzIGlzIHdyYXBwZWQgYXMgYSB7QGxpbmsgRGF0YXR5cGVDb25maWd1cmF0aW9uRXhjZXB0aW9ufS4KLSAqICAgIDwvbGk+Ci0gKiA8L29sPgotICoKLSAqIEBhdXRob3IgPGEgaHJlZj0ibWFpbHRvOkpvc2VwaC5GaWFsbGlAU3VuLkNPTSI+Sm9zZXBoIEZpYWxsaTwvYT4KLSAqIEBhdXRob3IgPGEgaHJlZj0ibWFpbHRvOkplZmYuU3V0dG9yQFN1bi5jb20iPkplZmYgU3V0dG9yPC9hPgotICogQHZlcnNpb24gJElkOiBEYXRhdHlwZUZhY3RvcnlJbXBsLmphdmEsdiAxLjYgMjAxMC8wNS8xOSAwNTowMjo1NSBqb2VodyBFeHAgJAotICovCi1wdWJsaWMgY2xhc3MgRGF0YXR5cGVGYWN0b3J5SW1wbAotICAgICAgICBleHRlbmRzIERhdGF0eXBlRmFjdG9yeSB7Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIDxwPlB1YmxpYyBjb25zdHJ1Y3RvciBpcyBlbXB0eS4uPC9wPgotICAgICAgICAgKgotICAgICAgICAgKiA8cD5Vc2Uge0BsaW5rIERhdGF0eXBlRmFjdG9yeSNuZXdJbnN0YW5jZSgpfSB0byBjcmVhdGUgYSA8Y29kZT5EYXRhdHlwZUZhY3Rvcnk8L2NvZGU+LjwvcD4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBEYXRhdHlwZUZhY3RvcnlJbXBsKCkgewotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIDxwPk9idGFpbiBhIG5ldyBpbnN0YW5jZSBvZiBhIDxjb2RlPkR1cmF0aW9uPC9jb2RlPgotICAgICAgICAgKiBzcGVjaWZ5aW5nIHRoZSA8Y29kZT5EdXJhdGlvbjwvY29kZT4gYXMgaXRzIHN0cmluZyByZXByZXNlbnRhdGlvbiwgIlBuWW5NbkRUbkhuTW5TIiwKLSAgICAgICAgICogYXMgZGVmaW5lZCBpbiBYTUwgU2NoZW1hIDEuMCBzZWN0aW9uIDMuMi42LjEuPC9wPgotICAgICAgICAgKgotICAgICAgICAgKiA8cD5YTUwgU2NoZW1hIFBhcnQgMjogRGF0YXR5cGVzLCAzLjIuNiBkdXJhdGlvbiwgZGVmaW5lcyA8Y29kZT5kdXJhdGlvbjwvY29kZT4gYXM6PC9wPgotICAgICAgICAgKiA8YmxvY2txdW90ZT4KLSAgICAgICAgICogZHVyYXRpb24gcmVwcmVzZW50cyBhIGR1cmF0aW9uIG9mIHRpbWUuCi0gICAgICAgICAqIFRoZSB2YWx1ZSBzcGFjZSBvZiBkdXJhdGlvbiBpcyBhIHNpeC1kaW1lbnNpb25hbCBzcGFjZSB3aGVyZSB0aGUgY29vcmRpbmF0ZXMgZGVzaWduYXRlIHRoZQotICAgICAgICAgKiBHcmVnb3JpYW4geWVhciwgbW9udGgsIGRheSwgaG91ciwgbWludXRlLCBhbmQgc2Vjb25kIGNvbXBvbmVudHMgZGVmaW5lZCBpbiBTZWN0aW9uIDUuNS4zLjIgb2YgW0lTTyA4NjAxXSwgcmVzcGVjdGl2ZWx5LgotICAgICAgICAgKiBUaGVzZSBjb21wb25lbnRzIGFyZSBvcmRlcmVkIGluIHRoZWlyIHNpZ25pZmljYW5jZSBieSB0aGVpciBvcmRlciBvZiBhcHBlYXJhbmNlIGkuZS4gYXMKLSAgICAgICAgICogeWVhciwgbW9udGgsIGRheSwgaG91ciwgbWludXRlLCBhbmQgc2Vjb25kLgotICAgICAgICAgKiA8L2Jsb2NrcXVvdGU+Ci0gICAgICogPHA+QWxsIHNpeCB2YWx1ZXMgYXJlIHNldCBhbmQgYXZhaWxhYmUgZnJvbSB0aGUgY3JlYXRlZCB7QGxpbmsgRHVyYXRpb259PC9wPgotICAgICAgICAgKgotICAgICAqIDxwPlRoZSBYTUwgU2NoZW1hIHNwZWNpZmljYXRpb24gc3RhdGVzIHRoYXQgdmFsdWVzIGNhbiBiZSBvZiBhbiBhcmJpdHJhcnkgc2l6ZS4KLSAgICAgKiBJbXBsZW1lbnRhdGlvbnMgbWF5IGNob3NlIG5vdCB0byBvciBiZSBpbmNhcGFibGUgb2Ygc3VwcG9ydGluZyBhcmJpdHJhcmlseSBsYXJnZSBhbmQvb3Igc21hbGwgdmFsdWVzLgotICAgICAqIEFuIHtAbGluayBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbn0gd2lsbCBiZSB0aHJvd24gd2l0aCBhIG1lc3NhZ2UgaW5kaWNhdGluZyBpbXBsZW1lbnRhdGlvbiBsaW1pdHMKLSAgICAgKiBpZiBpbXBsZW1lbnRhdGlvbiBjYXBhY2l0aWVzIGFyZSBleGNlZWRlZC48L3A+Ci0gICAgICoKLSAgICAgICAgICogQHBhcmFtIGxleGljYWxSZXByZXNlbnRhdGlvbiA8Y29kZT5TdHJpbmc8L2NvZGU+IHJlcHJlc2VudGF0aW9uIG9mIGEgPGNvZGU+RHVyYXRpb248L2NvZGU+LgotICAgICAgICAgKgotICAgICAgICAgKiBAcmV0dXJuIE5ldyA8Y29kZT5EdXJhdGlvbjwvY29kZT4gY3JlYXRlZCBmcm9tIHBhcnNpbmcgdGhlIDxjb2RlPmxleGljYWxSZXByZXNlbnRhdGlvbjwvY29kZT4uCi0gICAgICAgICAqCi0gICAgICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIElmIDxjb2RlPmxleGljYWxSZXByZXNlbnRhdGlvbjwvY29kZT4gaXMgbm90IGEgdmFsaWQgcmVwcmVzZW50YXRpb24gb2YgYSA8Y29kZT5EdXJhdGlvbjwvY29kZT4uCi0gICAgICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gSWYgaW1wbGVtZW50YXRpb24gY2Fubm90IHN1cHBvcnQgcmVxdWVzdGVkIHZhbHVlcy4KLSAgICAgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiA8Y29kZT5sZXhpY2FsUmVwcmVzZW50YXRpb248L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIER1cmF0aW9uIG5ld0R1cmF0aW9uKGZpbmFsIFN0cmluZyBsZXhpY2FsUmVwcmVzZW50YXRpb24pIHsKLQotICAgICAgICAgICAgICAgIHJldHVybiBuZXcgRHVyYXRpb25JbXBsKGxleGljYWxSZXByZXNlbnRhdGlvbik7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogPHA+T2J0YWluIGEgbmV3IGluc3RhbmNlIG9mIGEgPGNvZGU+RHVyYXRpb248L2NvZGU+Ci0gICAgICAgICAqIHNwZWNpZnlpbmcgdGhlIDxjb2RlPkR1cmF0aW9uPC9jb2RlPiBhcyBtaWxsaXNlY29uZHMuPC9wPgotICAgICAgICAgKgotICAgICAgICAgKiA8cD5YTUwgU2NoZW1hIFBhcnQgMjogRGF0YXR5cGVzLCAzLjIuNiBkdXJhdGlvbiwgZGVmaW5lcyA8Y29kZT5kdXJhdGlvbjwvY29kZT4gYXM6PC9wPgotICAgICAgICAgKiA8YmxvY2txdW90ZT4KLSAgICAgICAgICogZHVyYXRpb24gcmVwcmVzZW50cyBhIGR1cmF0aW9uIG9mIHRpbWUuCi0gICAgICAgICAqIFRoZSB2YWx1ZSBzcGFjZSBvZiBkdXJhdGlvbiBpcyBhIHNpeC1kaW1lbnNpb25hbCBzcGFjZSB3aGVyZSB0aGUgY29vcmRpbmF0ZXMgZGVzaWduYXRlIHRoZQotICAgICAgICAgKiBHcmVnb3JpYW4geWVhciwgbW9udGgsIGRheSwgaG91ciwgbWludXRlLCBhbmQgc2Vjb25kIGNvbXBvbmVudHMgZGVmaW5lZCBpbiBTZWN0aW9uIDUuNS4zLjIgb2YgW0lTTyA4NjAxXSwgcmVzcGVjdGl2ZWx5LgotICAgICAgICAgKiBUaGVzZSBjb21wb25lbnRzIGFyZSBvcmRlcmVkIGluIHRoZWlyIHNpZ25pZmljYW5jZSBieSB0aGVpciBvcmRlciBvZiBhcHBlYXJhbmNlIGkuZS4gYXMKLSAgICAgICAgICogeWVhciwgbW9udGgsIGRheSwgaG91ciwgbWludXRlLCBhbmQgc2Vjb25kLgotICAgICAgICAgKiA8L2Jsb2NrcXVvdGU+Ci0gICAgICogPHA+QWxsIHNpeCB2YWx1ZXMgYXJlIHNldCBieSBjb21wdXRpbmcgdGhlaXIgdmFsdWVzIGZyb20gdGhlIHNwZWNpZmllZCBtaWxsaXNlY29uZHMKLSAgICAgKiBhbmQgYXJlIGF2YWlsYWJlIHVzaW5nIHRoZSA8Y29kZT5nZXQ8L2NvZGU+IG1ldGhvZHMgb2YgIHRoZSBjcmVhdGVkIHtAbGluayBEdXJhdGlvbn0uCi0gICAgICogVGhlIHZhbHVlcyBjb25mb3JtIHRvIGFuZCBhcmUgZGVmaW5lZCBieTo8L3A+Ci0gICAgICogPHVsPgotICAgICAqICAgPGxpPklTTyA4NjAxOjIwMDAoRSkgU2VjdGlvbiA1LjUuMy4yIEFsdGVybmF0aXZlIGZvcm1hdDwvbGk+Ci0gICAgICogICA8bGk+PGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveG1sc2NoZW1hLTIvI2lzb2Zvcm1hdHMiPgotICAgICAqICAgICBXM0MgWE1MIFNjaGVtYSAxLjAgUGFydCAyLCBBcHBlbmRpeCBELCBJU08gODYwMSBEYXRlIGFuZCBUaW1lIEZvcm1hdHM8L2E+Ci0gICAgICogICA8L2xpPgotICAgICAqICAgPGxpPntAbGluayBYTUxHcmVnb3JpYW5DYWxlbmRhcn0gIERhdGUvVGltZSBEYXRhdHlwZSBGaWVsZCBNYXBwaW5nIEJldHdlZW4gWE1MIFNjaGVtYSAxLjAgYW5kIEphdmEgUmVwcmVzZW50YXRpb248L2xpPgotICAgICAqIDwvdWw+Ci0gICAgICAgICAqCi0gICAgICAgICAqIDxwPlRoZSBkZWZhdWx0IHN0YXJ0IGluc3RhbmNlIGlzIGRlZmluZWQgYnkge0BsaW5rIEdyZWdvcmlhbkNhbGVuZGFyfSdzIHVzZSBvZiB0aGUgc3RhcnQgb2YgdGhlIGVwb2NoOiBpLmUuLAotICAgICAgICAgKiB7QGxpbmsgamF2YS51dGlsLkNhbGVuZGFyI1lFQVJ9ID0gMTk3MCwKLSAgICAgICAgICoge0BsaW5rIGphdmEudXRpbC5DYWxlbmRhciNNT05USH0gPSB7QGxpbmsgamF2YS51dGlsLkNhbGVuZGFyI0pBTlVBUll9LAotICAgICAgICAgKiB7QGxpbmsgamF2YS51dGlsLkNhbGVuZGFyI0RBVEV9ID0gMSwgZXRjLgotICAgICAgICAgKiBUaGlzIGlzIGltcG9ydGFudCBhcyB0aGVyZSBhcmUgdmFyaWF0aW9ucyBpbiB0aGUgR3JlZ29yaWFuIENhbGVuZGFyLAotICAgICAgICAgKiBlLmcuIGxlYXAgeWVhcnMgaGF2ZSBkaWZmZXJlbnQgZGF5cyBpbiB0aGUgbW9udGggPSB7QGxpbmsgamF2YS51dGlsLkNhbGVuZGFyI0ZFQlJVQVJZfQotICAgICAgICAgKiBzbyB0aGUgcmVzdWx0IG9mIHtAbGluayBEdXJhdGlvbiNnZXRNb250aHMoKX0gYW5kIHtAbGluayBEdXJhdGlvbiNnZXREYXlzKCl9IGNhbiBiZSBpbmZsdWVuY2VkLjwvcD4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIGR1cmF0aW9uSW5NaWxsaXNlY29uZHMgRHVyYXRpb24gaW4gbWlsbGlzZWNvbmRzIHRvIGNyZWF0ZS4KLSAgICAgICAgICoKLSAgICAgICAgICogQHJldHVybiBOZXcgPGNvZGU+RHVyYXRpb248L2NvZGU+IHJlcHJlc2VudGluZyA8Y29kZT5kdXJhdGlvbkluTWlsbGlzZWNvbmRzPC9jb2RlPi4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBEdXJhdGlvbiBuZXdEdXJhdGlvbihmaW5hbCBsb25nIGR1cmF0aW9uSW5NaWxsaXNlY29uZHMpIHsKLQotICAgICAgICAgICAgICAgIHJldHVybiBuZXcgRHVyYXRpb25JbXBsKGR1cmF0aW9uSW5NaWxsaXNlY29uZHMpOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIDxwPk9idGFpbiBhIG5ldyBpbnN0YW5jZSBvZiBhIDxjb2RlPkR1cmF0aW9uPC9jb2RlPgotICAgICAgICAgKiBzcGVjaWZ5aW5nIHRoZSA8Y29kZT5EdXJhdGlvbjwvY29kZT4gYXMgaXNQb3NpdGl2ZSwgeWVhcnMsIG1vbnRocywgZGF5cywgaG91cnMsIG1pbnV0ZXMsIHNlY29uZHMuPC9wPgotICAgICAgICAgKgotICAgICAqIDxwPlRoZSBYTUwgU2NoZW1hIHNwZWNpZmljYXRpb24gc3RhdGVzIHRoYXQgdmFsdWVzIGNhbiBiZSBvZiBhbiBhcmJpdHJhcnkgc2l6ZS4KLSAgICAgKiBJbXBsZW1lbnRhdGlvbnMgbWF5IGNob3NlIG5vdCB0byBvciBiZSBpbmNhcGFibGUgb2Ygc3VwcG9ydGluZyBhcmJpdHJhcmlseSBsYXJnZSBhbmQvb3Igc21hbGwgdmFsdWVzLgotICAgICAqIEFuIHtAbGluayBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbn0gd2lsbCBiZSB0aHJvd24gd2l0aCBhIG1lc3NhZ2UgaW5kaWNhdGluZyBpbXBsZW1lbnRhdGlvbiBsaW1pdHMKLSAgICAgKiBpZiBpbXBsZW1lbnRhdGlvbiBjYXBhY2l0aWVzIGFyZSBleGNlZWRlZC48L3A+Ci0gICAgICoKLSAgICAgICAgICogQHBhcmFtIGlzUG9zaXRpdmUgU2V0IHRvIDxjb2RlPmZhbHNlPC9jb2RlPiB0byBjcmVhdGUgYSBuZWdhdGl2ZSBkdXJhdGlvbi4gV2hlbiB0aGUgbGVuZ3RoCi0gICAgICAgICAqICAgb2YgdGhlIGR1cmF0aW9uIGlzIHplcm8sIHRoaXMgcGFyYW1ldGVyIHdpbGwgYmUgaWdub3JlZC4KLSAgICAgICAgICogQHBhcmFtIHllYXJzIG9mIHRoaXMgPGNvZGU+RHVyYXRpb248L2NvZGU+Ci0gICAgICAgICAqIEBwYXJhbSBtb250aHMgb2YgdGhpcyA8Y29kZT5EdXJhdGlvbjwvY29kZT4KLSAgICAgICAgICogQHBhcmFtIGRheXMgb2YgdGhpcyA8Y29kZT5EdXJhdGlvbjwvY29kZT4KLSAgICAgICAgICogQHBhcmFtIGhvdXJzIG9mIHRoaXMgPGNvZGU+RHVyYXRpb248L2NvZGU+Ci0gICAgICAgICAqIEBwYXJhbSBtaW51dGVzIG9mIHRoaXMgPGNvZGU+RHVyYXRpb248L2NvZGU+Ci0gICAgICAgICAqIEBwYXJhbSBzZWNvbmRzIG9mIHRoaXMgPGNvZGU+RHVyYXRpb248L2NvZGU+Ci0gICAgICAgICAqCi0gICAgICAgICAqIEByZXR1cm4gTmV3IDxjb2RlPkR1cmF0aW9uPC9jb2RlPiBjcmVhdGVkIGZyb20gdGhlIHNwZWNpZmllZCB2YWx1ZXMuCi0gICAgICAgICAqCi0gICAgICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIElmIHZhbHVlcyBhcmUgbm90IGEgdmFsaWQgcmVwcmVzZW50YXRpb24gb2YgYSA8Y29kZT5EdXJhdGlvbjwvY29kZT4uCi0gICAgICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gSWYgaW1wbGVtZW50YXRpb24gY2Fubm90IHN1cHBvcnQgcmVxdWVzdGVkIHZhbHVlcy4KLSAgICAgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBJZiBhbnkgdmFsdWVzIGFyZSA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICAgICAgICoKLSAgICAgICAgICogQHNlZSAjbmV3RHVyYXRpb24oYm9vbGVhbiBpc1Bvc2l0aXZlLCBCaWdJbnRlZ2VyIHllYXJzLCBCaWdJbnRlZ2VyIG1vbnRocywgQmlnSW50ZWdlciBkYXlzLAotICAgICAgICAgKiAgIEJpZ0ludGVnZXIgaG91cnMsIEJpZ0ludGVnZXIgbWludXRlcywgQmlnRGVjaW1hbCBzZWNvbmRzKQotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIER1cmF0aW9uIG5ld0R1cmF0aW9uKAotICAgICAgICAgICAgICAgIGZpbmFsIGJvb2xlYW4gaXNQb3NpdGl2ZSwKLSAgICAgICAgICAgICAgICBmaW5hbCBCaWdJbnRlZ2VyIHllYXJzLAotICAgICAgICAgICAgICAgIGZpbmFsIEJpZ0ludGVnZXIgbW9udGhzLAotICAgICAgICAgICAgICAgIGZpbmFsIEJpZ0ludGVnZXIgZGF5cywKLSAgICAgICAgICAgICAgICBmaW5hbCBCaWdJbnRlZ2VyIGhvdXJzLAotICAgICAgICAgICAgICAgIGZpbmFsIEJpZ0ludGVnZXIgbWludXRlcywKLSAgICAgICAgICAgICAgICBmaW5hbCBCaWdEZWNpbWFsIHNlY29uZHMpIHsKLQotICAgICAgICAgICAgICAgIHJldHVybiBuZXcgRHVyYXRpb25JbXBsKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc1Bvc2l0aXZlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ZWFycywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9udGhzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXlzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBob3VycywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWludXRlcywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vjb25kcwotICAgICAgICAgICAgICAgICAgICAgICAgKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgIC8qKgotICAgICAgICAgKiA8cD5DcmVhdGUgYSA8Y29kZT5EdXJhdGlvbjwvY29kZT4gb2YgdHlwZSA8Y29kZT54ZHQ6eWVhck1vbnRoRHVyYXRpb248L2NvZGU+IHVzaW5nIHRoZSBzcGVjaWZpZWQKLSAgICAgICAgICogPGNvZGU+eWVhcjwvY29kZT4gYW5kIDxjb2RlPm1vbnRoPC9jb2RlPiBhcyBkZWZpbmVkIGluCi0gICAgICAgICAqIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hwYXRoLWRhdGFtb2RlbCN5ZWFyTW9udGhEdXJhdGlvbiI+Ci0gICAgICAgICAqICAgWFF1ZXJ5IDEuMCBhbmQgWFBhdGggMi4wIERhdGEgTW9kZWwsIHhkdDp5ZWFyTW9udGhEdXJhdGlvbjwvYT4uPC9wPgotICAgICAgICAgKgotICAgICAqIDxwPlRoZSBYTUwgU2NoZW1hIHNwZWNpZmljYXRpb24gc3RhdGVzIHRoYXQgdmFsdWVzIGNhbiBiZSBvZiBhbiBhcmJpdHJhcnkgc2l6ZS4KLSAgICAgKiBJbXBsZW1lbnRhdGlvbnMgbWF5IGNob3NlIG5vdCB0byBvciBiZSBpbmNhcGFibGUgb2Ygc3VwcG9ydGluZyBhcmJpdHJhcmlseSBsYXJnZSBhbmQvb3Igc21hbGwgdmFsdWVzLgotICAgICAqIEFuIHtAbGluayBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbn0gd2lsbCBiZSB0aHJvd24gd2l0aCBhIG1lc3NhZ2UgaW5kaWNhdGluZyBpbXBsZW1lbnRhdGlvbiBsaW1pdHMKLSAgICAgKiBpZiBpbXBsZW1lbnRhdGlvbiBjYXBhY2l0aWVzIGFyZSBleGNlZWRlZC48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5BIDxjb2RlPm51bGw8L2NvZGU+IHZhbHVlIGluZGljYXRlcyB0aGF0IGZpZWxkIGlzIG5vdCBzZXQuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGlzUG9zaXRpdmUgU2V0IHRvIDxjb2RlPmZhbHNlPC9jb2RlPiB0byBjcmVhdGUgYSBuZWdhdGl2ZSBkdXJhdGlvbi4gV2hlbiB0aGUgbGVuZ3RoCi0gICAgICogICBvZiB0aGUgZHVyYXRpb24gaXMgemVybywgdGhpcyBwYXJhbWV0ZXIgd2lsbCBiZSBpZ25vcmVkLgotICAgICAgICAgKiBAcGFyYW0geWVhciBZZWFyIG9mIDxjb2RlPkR1cmF0aW9uPC9jb2RlPi4KLSAgICAgICAgICogQHBhcmFtIG1vbnRoIE1vbnRoIG9mIDxjb2RlPkR1cmF0aW9uPC9jb2RlPi4KLSAgICAgICAgICoKLSAgICAgICAgICogQHJldHVybiBOZXcgPGNvZGU+RHVyYXRpb248L2NvZGU+IGNyZWF0ZWQgdXNpbmcgdGhlIHNwZWNpZmllZCA8Y29kZT55ZWFyPC9jb2RlPiBhbmQgPGNvZGU+bW9udGg8L2NvZGU+LgotICAgICAgICAgKgotICAgICAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBJZiB0aGUgdmFsdWVzIGFyZSBub3QgYSB2YWxpZCByZXByZXNlbnRhdGlvbiBvZiBhCi0gICAgICAgICAqIDxjb2RlPkR1cmF0aW9uPC9jb2RlPjogaWYgYWxsIG9mIHRoZSBmaWVsZHMgKHllYXIsIG1vbnRoKSBhcmUgbnVsbCBvcgotICAgICAgICAgKiBpZiBhbnkgb2YgdGhlIGZpZWxkcyBpcyBuZWdhdGl2ZS4KLSAgICAgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBJZiBpbXBsZW1lbnRhdGlvbiBjYW5ub3Qgc3VwcG9ydCByZXF1ZXN0ZWQgdmFsdWVzLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIER1cmF0aW9uIG5ld0R1cmF0aW9uWWVhck1vbnRoKAotICAgICAgICAgICAgICAgIGZpbmFsIGJvb2xlYW4gaXNQb3NpdGl2ZSwKLSAgICAgICAgICAgICAgICBmaW5hbCBCaWdJbnRlZ2VyIHllYXIsCi0gICAgICAgICAgICAgICAgZmluYWwgQmlnSW50ZWdlciBtb250aCkgewotCi0gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBEdXJhdGlvblllYXJNb250aEltcGwoCi0gICAgICAgICAgICAgICAgICAgICAgICAgaXNQb3NpdGl2ZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICB5ZWFyLAotICAgICAgICAgICAgICAgICAgICAgICAgIG1vbnRoCi0gICAgICAgICAgICAgICAgICk7Ci0KLSAgICAgICAgfQotICAgICAgICAvKioKLSAgICAgICAgICogPHA+Q3JlYXRlIGEgPGNvZGU+RHVyYXRpb248L2NvZGU+IG9mIHR5cGUgPGNvZGU+eGR0OnllYXJNb250aER1cmF0aW9uPC9jb2RlPiB1c2luZyB0aGUgc3BlY2lmaWVkCi0gICAgICAgICAqIDxjb2RlPnllYXI8L2NvZGU+IGFuZCA8Y29kZT5tb250aDwvY29kZT4gYXMgZGVmaW5lZCBpbgotICAgICAgICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aC1kYXRhbW9kZWwjeWVhck1vbnRoRHVyYXRpb24iPgotICAgICAgICAgKiAgIFhRdWVyeSAxLjAgYW5kIFhQYXRoIDIuMCBEYXRhIE1vZGVsLCB4ZHQ6eWVhck1vbnRoRHVyYXRpb248L2E+LjwvcD4KLSAgICAgICAgICoKLSAgICAgKiA8cD5BIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNGSUVMRF9VTkRFRklORUR9IHZhbHVlIGluZGljYXRlcyB0aGF0IGZpZWxkIGlzIG5vdCBzZXQuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGlzUG9zaXRpdmUgU2V0IHRvIDxjb2RlPmZhbHNlPC9jb2RlPiB0byBjcmVhdGUgYSBuZWdhdGl2ZSBkdXJhdGlvbi4gV2hlbiB0aGUgbGVuZ3RoCi0gICAgICogICBvZiB0aGUgZHVyYXRpb24gaXMgemVybywgdGhpcyBwYXJhbWV0ZXIgd2lsbCBiZSBpZ25vcmVkLgotICAgICAgICAgKiBAcGFyYW0geWVhciBZZWFyIG9mIDxjb2RlPkR1cmF0aW9uPC9jb2RlPi4KLSAgICAgICAgICogQHBhcmFtIG1vbnRoIE1vbnRoIG9mIDxjb2RlPkR1cmF0aW9uPC9jb2RlPi4KLSAgICAgICAgICoKLSAgICAgICAgICogQHJldHVybiBOZXcgPGNvZGU+RHVyYXRpb248L2NvZGU+IGNyZWF0ZWQgdXNpbmcgdGhlIHNwZWNpZmllZCA8Y29kZT55ZWFyPC9jb2RlPiBhbmQgPGNvZGU+bW9udGg8L2NvZGU+LgotICAgICAgICAgKgotICAgICAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBJZiB0aGUgdmFsdWVzIGFyZSBub3QgYSB2YWxpZCByZXByZXNlbnRhdGlvbiBvZiBhCi0gICAgICAgICAqIDxjb2RlPkR1cmF0aW9uPC9jb2RlPjogaWYgYW55IG9mIHRoZSBmaWVsZHMgKHllYXIsIG1vbnRoKSBpcyBuZWdhdGl2ZS4KLSAgICAgICAgICovCi0gICAgQE92ZXJyaWRlCi0gICAgICAgIHB1YmxpYyBEdXJhdGlvbiBuZXdEdXJhdGlvblllYXJNb250aCgKLSAgICAgICAgICAgICAgICBmaW5hbCBib29sZWFuIGlzUG9zaXRpdmUsCi0gICAgICAgICAgICAgICAgZmluYWwgaW50IHllYXIsCi0gICAgICAgICAgICAgICAgZmluYWwgaW50IG1vbnRoKSB7Ci0KLSAgICAgICAgICAgICAgICByZXR1cm4gbmV3IER1cmF0aW9uWWVhck1vbnRoSW1wbCgKLSAgICAgICAgICAgICAgICAgICAgICAgIGlzUG9zaXRpdmUsCi0gICAgICAgICAgICAgICAgICAgICAgICB5ZWFyLAotICAgICAgICAgICAgICAgICAgICAgICAgbW9udGgpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogPHA+Q3JlYXRlIGEgPGNvZGU+RHVyYXRpb248L2NvZGU+IG9mIHR5cGUgPGNvZGU+eGR0OnllYXJNb250aER1cmF0aW9uPC9jb2RlPiBieSBwYXJzaW5nIGl0cyA8Y29kZT5TdHJpbmc8L2NvZGU+IHJlcHJlc2VudGF0aW9uLAotICAgICAgICAgKiAiPGVtPlBuWW5NPC9lbT4iLCA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aC1kYXRhbW9kZWwjeWVhck1vbnRoRHVyYXRpb24iPgotICAgICAgICAgKiAgIFhRdWVyeSAxLjAgYW5kIFhQYXRoIDIuMCBEYXRhIE1vZGVsLCB4ZHQ6eWVhck1vbnRoRHVyYXRpb248L2E+LjwvcD4KLSAgICAgICAgICoKLSAgICAgICAgICogPHA+VGhlIGRhdGF0eXBlIDxjb2RlPnhkdDp5ZWFyTW9udGhEdXJhdGlvbjwvY29kZT4gaXMgYSBzdWJ0eXBlIG9mIDxjb2RlPnhzOmR1cmF0aW9uPC9jb2RlPgotICAgICAgICAgKiB3aG9zZSBsZXhpY2FsIHJlcHJlc2VudGF0aW9uIGNvbnRhaW5zIG9ubHkgeWVhciBhbmQgbW9udGggY29tcG9uZW50cy4KLSAgICAgICAgICogVGhpcyBkYXRhdHlwZSByZXNpZGVzIGluIHRoZSBuYW1lc3BhY2Uge0BsaW5rIGphdmF4LnhtbC5YTUxDb25zdGFudHMjVzNDX1hQQVRIX0RBVEFUWVBFX05TX1VSSX0uPC9wPgotICAgICAgICAgKgotICAgICAqIDxwPkJvdGggdmFsdWVzIGFyZSBzZXQgYW5kIGF2YWlsYWJlIGZyb20gdGhlIGNyZWF0ZWQge0BsaW5rIER1cmF0aW9ufTwvcD4KLSAgICAgICAgICoKLSAgICAgKiA8cD5UaGUgWE1MIFNjaGVtYSBzcGVjaWZpY2F0aW9uIHN0YXRlcyB0aGF0IHZhbHVlcyBjYW4gYmUgb2YgYW4gYXJiaXRyYXJ5IHNpemUuCi0gICAgICogSW1wbGVtZW50YXRpb25zIG1heSBjaG9zZSBub3QgdG8gb3IgYmUgaW5jYXBhYmxlIG9mIHN1cHBvcnRpbmcgYXJiaXRyYXJpbHkgbGFyZ2UgYW5kL29yIHNtYWxsIHZhbHVlcy4KLSAgICAgKiBBbiB7QGxpbmsgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb259IHdpbGwgYmUgdGhyb3duIHdpdGggYSBtZXNzYWdlIGluZGljYXRpbmcgaW1wbGVtZW50YXRpb24gbGltaXRzCi0gICAgICogaWYgaW1wbGVtZW50YXRpb24gY2FwYWNpdGllcyBhcmUgZXhjZWVkZWQuPC9wPgotICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBsZXhpY2FsUmVwcmVzZW50YXRpb24gTGV4aWNhbCByZXByZXNlbnRhdGlvbiBvZiBhIGR1cmF0aW9uLgotICAgICAgICAgKgotICAgICAgICAgKiBAcmV0dXJuIE5ldyA8Y29kZT5EdXJhdGlvbjwvY29kZT4gY3JlYXRlZCB1c2luZyB0aGUgc3BlY2lmaWVkIDxjb2RlPmxleGljYWxSZXByZXNlbnRhdGlvbjwvY29kZT4uCi0gICAgICAgICAqCi0gICAgICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIElmIDxjb2RlPmxleGljYWxSZXByZXNlbnRhdGlvbjwvY29kZT4gaXMgbm90IGEgdmFsaWQgcmVwcmVzZW50YXRpb24gb2YgYSA8Y29kZT5EdXJhdGlvbjwvY29kZT4gZXhwcmVzc2VkIG9ubHkgaW4gdGVybXMgb2YgeWVhcnMgYW5kIG1vbnRocy4KLSAgICAgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBJZiBpbXBsZW1lbnRhdGlvbiBjYW5ub3Qgc3VwcG9ydCByZXF1ZXN0ZWQgdmFsdWVzLgotICAgICAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIElmIDxjb2RlPmxleGljYWxSZXByZXNlbnRhdGlvbjwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgRHVyYXRpb24gbmV3RHVyYXRpb25ZZWFyTW9udGgoCi0gICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIGxleGljYWxSZXByZXNlbnRhdGlvbikgewotCi0gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBEdXJhdGlvblllYXJNb250aEltcGwobGV4aWNhbFJlcHJlc2VudGF0aW9uKTsKLQotICAgICAgICB9Ci0gICAgICAgIC8qKgotICAgICAgICAgKiA8cD5DcmVhdGUgYSA8Y29kZT5EdXJhdGlvbjwvY29kZT4gb2YgdHlwZSA8Y29kZT54ZHQ6eWVhck1vbnRoRHVyYXRpb248L2NvZGU+IHVzaW5nIHRoZSBzcGVjaWZpZWQgbWlsbGlzZWNvbmRzIGFzIGRlZmluZWQgaW4KLSAgICAgICAgICogPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGgtZGF0YW1vZGVsI3llYXJNb250aER1cmF0aW9uIj4KLSAgICAgICAgICogICBYUXVlcnkgMS4wIGFuZCBYUGF0aCAyLjAgRGF0YSBNb2RlbCwgeGR0OnllYXJNb250aER1cmF0aW9uPC9hPi48L3A+Ci0gICAgICAgICAqCi0gICAgICAgICAqIDxwPlRoZSBkYXRhdHlwZSA8Y29kZT54ZHQ6eWVhck1vbnRoRHVyYXRpb248L2NvZGU+IGlzIGEgc3VidHlwZSBvZiA8Y29kZT54czpkdXJhdGlvbjwvY29kZT4KLSAgICAgICAgICogd2hvc2UgbGV4aWNhbCByZXByZXNlbnRhdGlvbiBjb250YWlucyBvbmx5IHllYXIgYW5kIG1vbnRoIGNvbXBvbmVudHMuCi0gICAgICAgICAqIFRoaXMgZGF0YXR5cGUgcmVzaWRlcyBpbiB0aGUgbmFtZXNwYWNlIHtAbGluayBqYXZheC54bWwuWE1MQ29uc3RhbnRzI1czQ19YUEFUSF9EQVRBVFlQRV9OU19VUkl9LjwvcD4KLSAgICAgICAgICoKLSAgICAgKiA8cD5Cb3RoIHZhbHVlcyBhcmUgc2V0IGJ5IGNvbXB1dGluZyB0aGVpciB2YWx1ZXMgZnJvbSB0aGUgc3BlY2lmaWVkIG1pbGxpc2Vjb25kcwotICAgICAqIGFuZCBhcmUgYXZhaWxhYmUgdXNpbmcgdGhlIDxjb2RlPmdldDwvY29kZT4gbWV0aG9kcyBvZiAgdGhlIGNyZWF0ZWQge0BsaW5rIER1cmF0aW9ufS4KLSAgICAgKiBUaGUgdmFsdWVzIGNvbmZvcm0gdG8gYW5kIGFyZSBkZWZpbmVkIGJ5OjwvcD4KLSAgICAgKiA8dWw+Ci0gICAgICogICA8bGk+SVNPIDg2MDE6MjAwMChFKSBTZWN0aW9uIDUuNS4zLjIgQWx0ZXJuYXRpdmUgZm9ybWF0PC9saT4KLSAgICAgKiAgIDxsaT48YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94bWxzY2hlbWEtMi8jaXNvZm9ybWF0cyI+Ci0gICAgICogICAgIFczQyBYTUwgU2NoZW1hIDEuMCBQYXJ0IDIsIEFwcGVuZGl4IEQsIElTTyA4NjAxIERhdGUgYW5kIFRpbWUgRm9ybWF0czwvYT4KLSAgICAgKiAgIDwvbGk+Ci0gICAgICogICA8bGk+e0BsaW5rIFhNTEdyZWdvcmlhbkNhbGVuZGFyfSAgRGF0ZS9UaW1lIERhdGF0eXBlIEZpZWxkIE1hcHBpbmcgQmV0d2VlbiBYTUwgU2NoZW1hIDEuMCBhbmQgSmF2YSBSZXByZXNlbnRhdGlvbjwvbGk+Ci0gICAgICogPC91bD4KLSAgICAgKgotICAgICAgICAgKiA8cD5UaGUgZGVmYXVsdCBzdGFydCBpbnN0YW5jZSBpcyBkZWZpbmVkIGJ5IHtAbGluayBHcmVnb3JpYW5DYWxlbmRhcn0ncyB1c2Ugb2YgdGhlIHN0YXJ0IG9mIHRoZSBlcG9jaDogaS5lLiwKLSAgICAgICAgICoge0BsaW5rIGphdmEudXRpbC5DYWxlbmRhciNZRUFSfSA9IDE5NzAsCi0gICAgICAgICAqIHtAbGluayBqYXZhLnV0aWwuQ2FsZW5kYXIjTU9OVEh9ID0ge0BsaW5rIGphdmEudXRpbC5DYWxlbmRhciNKQU5VQVJZfSwKLSAgICAgICAgICoge0BsaW5rIGphdmEudXRpbC5DYWxlbmRhciNEQVRFfSA9IDEsIGV0Yy4KLSAgICAgICAgICogVGhpcyBpcyBpbXBvcnRhbnQgYXMgdGhlcmUgYXJlIHZhcmlhdGlvbnMgaW4gdGhlIEdyZWdvcmlhbiBDYWxlbmRhciwKLSAgICAgICAgICogZS5nLiBsZWFwIHllYXJzIGhhdmUgZGlmZmVyZW50IGRheXMgaW4gdGhlIG1vbnRoID0ge0BsaW5rIGphdmEudXRpbC5DYWxlbmRhciNGRUJSVUFSWX0KLSAgICAgICAgICogc28gdGhlIHJlc3VsdCBvZiB7QGxpbmsgRHVyYXRpb24jZ2V0TW9udGhzKCl9IGNhbiBiZSBpbmZsdWVuY2VkLjwvcD4KLSAgICAgICAgICoKLSAgICAgKiA8cD5BbnkgcmVtYWluaW5nIG1pbGxpc2Vjb25kcyBhZnRlciBkZXRlcm1pbmluZyB0aGUgeWVhciBhbmQgbW9udGggYXJlIGRpc2NhcmRlZC48L3A+Ci0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBkdXJhdGlvbkluTWlsbGlzZWNvbmRzIE1pbGxpc2Vjb25kcyBvZiA8Y29kZT5EdXJhdGlvbjwvY29kZT4gdG8gY3JlYXRlLgotICAgICAgICAgKgotICAgICAgICAgKiBAcmV0dXJuIE5ldyA8Y29kZT5EdXJhdGlvbjwvY29kZT4gY3JlYXRlZCB1c2luZyB0aGUgc3BlY2lmaWVkIDxjb2RlPmR1cmF0aW9uSW5NaWxsaXNlY29uZHM8L2NvZGU+LgotICAgICAgICAgKi8KLSAgICBwdWJsaWMgRHVyYXRpb24gbmV3RHVyYXRpb25ZZWFyTW9udGgoCi0gICAgICAgICAgICBmaW5hbCBsb25nIGR1cmF0aW9uSW5NaWxsaXNlY29uZHMpIHsKLQotICAgICAgICByZXR1cm4gbmV3IER1cmF0aW9uWWVhck1vbnRoSW1wbChkdXJhdGlvbkluTWlsbGlzZWNvbmRzKTsKLSAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIDxwPkNyZWF0ZSBhIDxjb2RlPkR1cmF0aW9uPC9jb2RlPiBvZiB0eXBlIDxjb2RlPnhkdDpkYXlUaW1lRHVyYXRpb248L2NvZGU+IGJ5IHBhcnNpbmcgaXRzIDxjb2RlPlN0cmluZzwvY29kZT4gcmVwcmVzZW50YXRpb24sCi0gICAgICAgICAqICI8ZW0+UG5EVG5Ibk1uUzwvZW0+IiwgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGgtZGF0YW1vZGVsI2RheVRpbWVEdXJhdGlvbiI+Ci0gICAgICAgICAqICAgWFF1ZXJ5IDEuMCBhbmQgWFBhdGggMi4wIERhdGEgTW9kZWwsIHhkdDpkYXlUaW1lRHVyYXRpb248L2E+LjwvcD4KLSAgICAgICAgICoKLSAgICAgICAgICogPHA+VGhlIGRhdGF0eXBlIDxjb2RlPnhkdDpkYXlUaW1lRHVyYXRpb248L2NvZGU+IGlzIGEgc3VidHlwZSBvZiA8Y29kZT54czpkdXJhdGlvbjwvY29kZT4KLSAgICAgICAgICogd2hvc2UgbGV4aWNhbCByZXByZXNlbnRhdGlvbiBjb250YWlucyBvbmx5IGRheSwgaG91ciwgbWludXRlLCBhbmQgc2Vjb25kIGNvbXBvbmVudHMuCi0gICAgICAgICAqIFRoaXMgZGF0YXR5cGUgcmVzaWRlcyBpbiB0aGUgbmFtZXNwYWNlIDxjb2RlPmh0dHA6Ly93d3cudzMub3JnLzIwMDMvMTEveHBhdGgtZGF0YXR5cGVzPC9jb2RlPi48L3A+Ci0gICAgICAgICAqCi0gICAgICogPHA+QWxsIGZvdXIgdmFsdWVzIGFyZSBzZXQgYW5kIGF2YWlsYWJlIGZyb20gdGhlIGNyZWF0ZWQge0BsaW5rIER1cmF0aW9ufTwvcD4KLSAgICAgICAgICoKLSAgICAgKiA8cD5UaGUgWE1MIFNjaGVtYSBzcGVjaWZpY2F0aW9uIHN0YXRlcyB0aGF0IHZhbHVlcyBjYW4gYmUgb2YgYW4gYXJiaXRyYXJ5IHNpemUuCi0gICAgICogSW1wbGVtZW50YXRpb25zIG1heSBjaG9zZSBub3QgdG8gb3IgYmUgaW5jYXBhYmxlIG9mIHN1cHBvcnRpbmcgYXJiaXRyYXJpbHkgbGFyZ2UgYW5kL29yIHNtYWxsIHZhbHVlcy4KLSAgICAgKiBBbiB7QGxpbmsgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb259IHdpbGwgYmUgdGhyb3duIHdpdGggYSBtZXNzYWdlIGluZGljYXRpbmcgaW1wbGVtZW50YXRpb24gbGltaXRzCi0gICAgICogaWYgaW1wbGVtZW50YXRpb24gY2FwYWNpdGllcyBhcmUgZXhjZWVkZWQuPC9wPgotICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBsZXhpY2FsUmVwcmVzZW50YXRpb24gTGV4aWNhbCByZXByZXNlbnRhdGlvbiBvZiBhIGR1cmF0aW9uLgotICAgICAgICAgKgotICAgICAgICAgKiBAcmV0dXJuIE5ldyA8Y29kZT5EdXJhdGlvbjwvY29kZT4gY3JlYXRlZCB1c2luZyB0aGUgc3BlY2lmaWVkIDxjb2RlPmxleGljYWxSZXByZXNlbnRhdGlvbjwvY29kZT4uCi0gICAgICAgICAqCi0gICAgICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIElmIDxjb2RlPmxleGljYWxSZXByZXNlbnRhdGlvbjwvY29kZT4gaXMgbm90IGEgdmFsaWQgcmVwcmVzZW50YXRpb24gb2YgYSA8Y29kZT5EdXJhdGlvbjwvY29kZT4gZXhwcmVzc2VkIG9ubHkgaW4gdGVybXMgb2YgZGF5cyBhbmQgdGltZS4KLSAgICAgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBJZiBpbXBsZW1lbnRhdGlvbiBjYW5ub3Qgc3VwcG9ydCByZXF1ZXN0ZWQgdmFsdWVzLgotICAgICAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIElmIDxjb2RlPmxleGljYWxSZXByZXNlbnRhdGlvbjwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgRHVyYXRpb24gbmV3RHVyYXRpb25EYXlUaW1lKGZpbmFsIFN0cmluZyBsZXhpY2FsUmVwcmVzZW50YXRpb24pIHsKLSAgICAgICAgICAgIC8vIGxleGljYWxSZXByZXNlbnRhdGlvbiBtdXN0IGJlIG5vbi1udWxsCi0gICAgICAgICAgICBpZiAobGV4aWNhbFJlcHJlc2VudGF0aW9uID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgICJUcnlpbmcgdG8gY3JlYXRlIGFuIHhkdDpkYXlUaW1lRHVyYXRpb24gd2l0aCBhbiBpbnZhbGlkIgotICAgICAgICAgICAgICAgICAgICArICIgbGV4aWNhbCByZXByZXNlbnRhdGlvbiBvZiBcIm51bGxcIiIpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICByZXR1cm4gbmV3IER1cmF0aW9uRGF5VGltZUltcGwobGV4aWNhbFJlcHJlc2VudGF0aW9uKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiA8cD5DcmVhdGUgYSA8Y29kZT5EdXJhdGlvbjwvY29kZT4gb2YgdHlwZSA8Y29kZT54ZHQ6ZGF5VGltZUR1cmF0aW9uPC9jb2RlPiB1c2luZyB0aGUgc3BlY2lmaWVkIG1pbGxpc2Vjb25kcyBhcyBkZWZpbmVkIGluCi0gICAgICAgICAqIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hwYXRoLWRhdGFtb2RlbCNkYXlUaW1lRHVyYXRpb24iPgotICAgICAgICAgKiAgIFhRdWVyeSAxLjAgYW5kIFhQYXRoIDIuMCBEYXRhIE1vZGVsLCB4ZHQ6ZGF5VGltZUR1cmF0aW9uPC9hPi48L3A+Ci0gICAgICAgICAqCi0gICAgICAgICAqIDxwPlRoZSBkYXRhdHlwZSA8Y29kZT54ZHQ6ZGF5VGltZUR1cmF0aW9uPC9jb2RlPiBpcyBhIHN1YnR5cGUgb2YgPGNvZGU+eHM6ZHVyYXRpb248L2NvZGU+Ci0gICAgICAgICAqIHdob3NlIGxleGljYWwgcmVwcmVzZW50YXRpb24gY29udGFpbnMgb25seSBkYXksIGhvdXIsIG1pbnV0ZSwgYW5kIHNlY29uZCBjb21wb25lbnRzLgotICAgICAgICAgKiBUaGlzIGRhdGF0eXBlIHJlc2lkZXMgaW4gdGhlIG5hbWVzcGFjZSA8Y29kZT5odHRwOi8vd3d3LnczLm9yZy8yMDAzLzExL3hwYXRoLWRhdGF0eXBlczwvY29kZT4uPC9wPgotICAgICAgICAgKgotICAgICAqIDxwPkFsbCBmb3VyIHZhbHVlcyBhcmUgc2V0IGJ5IGNvbXB1dGluZyB0aGVpciB2YWx1ZXMgZnJvbSB0aGUgc3BlY2lmaWVkIG1pbGxpc2Vjb25kcwotICAgICAqIGFuZCBhcmUgYXZhaWxhYmUgdXNpbmcgdGhlIDxjb2RlPmdldDwvY29kZT4gbWV0aG9kcyBvZiAgdGhlIGNyZWF0ZWQge0BsaW5rIER1cmF0aW9ufS4KLSAgICAgKiBUaGUgdmFsdWVzIGNvbmZvcm0gdG8gYW5kIGFyZSBkZWZpbmVkIGJ5OjwvcD4KLSAgICAgKiA8dWw+Ci0gICAgICogICA8bGk+SVNPIDg2MDE6MjAwMChFKSBTZWN0aW9uIDUuNS4zLjIgQWx0ZXJuYXRpdmUgZm9ybWF0PC9saT4KLSAgICAgKiAgIDxsaT48YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94bWxzY2hlbWEtMi8jaXNvZm9ybWF0cyI+Ci0gICAgICogICAgIFczQyBYTUwgU2NoZW1hIDEuMCBQYXJ0IDIsIEFwcGVuZGl4IEQsIElTTyA4NjAxIERhdGUgYW5kIFRpbWUgRm9ybWF0czwvYT4KLSAgICAgKiAgIDwvbGk+Ci0gICAgICogICA8bGk+e0BsaW5rIFhNTEdyZWdvcmlhbkNhbGVuZGFyfSAgRGF0ZS9UaW1lIERhdGF0eXBlIEZpZWxkIE1hcHBpbmcgQmV0d2VlbiBYTUwgU2NoZW1hIDEuMCBhbmQgSmF2YSBSZXByZXNlbnRhdGlvbjwvbGk+Ci0gICAgICogPC91bD4KLSAgICAgICAgICoKLSAgICAgICAgICogPHA+VGhlIGRlZmF1bHQgc3RhcnQgaW5zdGFuY2UgaXMgZGVmaW5lZCBieSB7QGxpbmsgR3JlZ29yaWFuQ2FsZW5kYXJ9J3MgdXNlIG9mIHRoZSBzdGFydCBvZiB0aGUgZXBvY2g6IGkuZS4sCi0gICAgICAgICAqIHtAbGluayBqYXZhLnV0aWwuQ2FsZW5kYXIjWUVBUn0gPSAxOTcwLAotICAgICAgICAgKiB7QGxpbmsgamF2YS51dGlsLkNhbGVuZGFyI01PTlRIfSA9IHtAbGluayBqYXZhLnV0aWwuQ2FsZW5kYXIjSkFOVUFSWX0sCi0gICAgICAgICAqIHtAbGluayBqYXZhLnV0aWwuQ2FsZW5kYXIjREFURX0gPSAxLCBldGMuCi0gICAgICAgICAqIFRoaXMgaXMgaW1wb3J0YW50IGFzIHRoZXJlIGFyZSB2YXJpYXRpb25zIGluIHRoZSBHcmVnb3JpYW4gQ2FsZW5kYXIsCi0gICAgICAgICAqIGUuZy4gbGVhcCB5ZWFycyBoYXZlIGRpZmZlcmVudCBkYXlzIGluIHRoZSBtb250aCA9IHtAbGluayBqYXZhLnV0aWwuQ2FsZW5kYXIjRkVCUlVBUll9Ci0gICAgICAgICAqIHNvIHRoZSByZXN1bHQgb2Yge0BsaW5rIER1cmF0aW9uI2dldERheXMoKX0gY2FuIGJlIGluZmx1ZW5jZWQuPC9wPgotICAgICAgICAgKgotICAgICAqIDxwPkFueSByZW1haW5pbmcgbWlsbGlzZWNvbmRzIGFmdGVyIGRldGVybWluaW5nIHRoZSBkYXksIGhvdXIsIG1pbnV0ZSBhbmQgc2Vjb25kIGFyZSBkaXNjYXJkZWQuPC9wPgotICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBkdXJhdGlvbkluTWlsbGlzZWNvbmRzIE1pbGxpc2Vjb25kcyBvZiA8Y29kZT5EdXJhdGlvbjwvY29kZT4gdG8gY3JlYXRlLgotICAgICAgICAgKgotICAgICAgICAgKiBAcmV0dXJuIE5ldyA8Y29kZT5EdXJhdGlvbjwvY29kZT4gY3JlYXRlZCB3aXRoIHRoZSBzcGVjaWZpZWQgPGNvZGU+ZHVyYXRpb25Jbk1pbGxpc2Vjb25kczwvY29kZT4uCi0gICAgICAgICAqCi0gICAgICAgICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGgtZGF0YW1vZGVsI2RheVRpbWVEdXJhdGlvbiI+Ci0gICAgICAgICAqICAgWFF1ZXJ5IDEuMCBhbmQgWFBhdGggMi4wIERhdGEgTW9kZWwsIHhkdDpkYXlUaW1lRHVyYXRpb248L2E+Ci0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgRHVyYXRpb24gbmV3RHVyYXRpb25EYXlUaW1lKGZpbmFsIGxvbmcgZHVyYXRpb25Jbk1pbGxpc2Vjb25kcykgewotCi0gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBEdXJhdGlvbkRheVRpbWVJbXBsKGR1cmF0aW9uSW5NaWxsaXNlY29uZHMpOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIDxwPkNyZWF0ZSBhIDxjb2RlPkR1cmF0aW9uPC9jb2RlPiBvZiB0eXBlIDxjb2RlPnhkdDpkYXlUaW1lRHVyYXRpb248L2NvZGU+IHVzaW5nIHRoZSBzcGVjaWZpZWQKLSAgICAgICAgICogPGNvZGU+ZGF5PC9jb2RlPiwgPGNvZGU+aG91cjwvY29kZT4sIDxjb2RlPm1pbnV0ZTwvY29kZT4gYW5kIDxjb2RlPnNlY29uZDwvY29kZT4gYXMgZGVmaW5lZCBpbgotICAgICAgICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aC1kYXRhbW9kZWwjZGF5VGltZUR1cmF0aW9uIj4KLSAgICAgICAgICogICBYUXVlcnkgMS4wIGFuZCBYUGF0aCAyLjAgRGF0YSBNb2RlbCwgeGR0OmRheVRpbWVEdXJhdGlvbjwvYT4uPC9wPgotICAgICAgICAgKgotICAgICAgICAgKiA8cD5UaGUgZGF0YXR5cGUgPGNvZGU+eGR0OmRheVRpbWVEdXJhdGlvbjwvY29kZT4gaXMgYSBzdWJ0eXBlIG9mIDxjb2RlPnhzOmR1cmF0aW9uPC9jb2RlPgotICAgICAgICAgKiB3aG9zZSBsZXhpY2FsIHJlcHJlc2VudGF0aW9uIGNvbnRhaW5zIG9ubHkgZGF5LCBob3VyLCBtaW51dGUsIGFuZCBzZWNvbmQgY29tcG9uZW50cy4KLSAgICAgICAgICogVGhpcyBkYXRhdHlwZSByZXNpZGVzIGluIHRoZSBuYW1lc3BhY2UgPGNvZGU+aHR0cDovL3d3dy53My5vcmcvMjAwMy8xMS94cGF0aC1kYXRhdHlwZXM8L2NvZGU+LjwvcD4KLSAgICAgICAgICoKLSAgICAgKiA8cD5UaGUgWE1MIFNjaGVtYSBzcGVjaWZpY2F0aW9uIHN0YXRlcyB0aGF0IHZhbHVlcyBjYW4gYmUgb2YgYW4gYXJiaXRyYXJ5IHNpemUuCi0gICAgICogSW1wbGVtZW50YXRpb25zIG1heSBjaG9zZSBub3QgdG8gb3IgYmUgaW5jYXBhYmxlIG9mIHN1cHBvcnRpbmcgYXJiaXRyYXJpbHkgbGFyZ2UgYW5kL29yIHNtYWxsIHZhbHVlcy4KLSAgICAgKiBBbiB7QGxpbmsgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb259IHdpbGwgYmUgdGhyb3duIHdpdGggYSBtZXNzYWdlIGluZGljYXRpbmcgaW1wbGVtZW50YXRpb24gbGltaXRzCi0gICAgICogaWYgaW1wbGVtZW50YXRpb24gY2FwYWNpdGllcyBhcmUgZXhjZWVkZWQuPC9wPgotICAgICAqCi0gICAgICogPHA+QSA8Y29kZT5udWxsPC9jb2RlPiB2YWx1ZSBpbmRpY2F0ZXMgdGhhdCBmaWVsZCBpcyBub3Qgc2V0LjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBpc1Bvc2l0aXZlIFNldCB0byA8Y29kZT5mYWxzZTwvY29kZT4gdG8gY3JlYXRlIGEgbmVnYXRpdmUgZHVyYXRpb24uIFdoZW4gdGhlIGxlbmd0aAotICAgICAqICAgb2YgdGhlIGR1cmF0aW9uIGlzIHplcm8sIHRoaXMgcGFyYW1ldGVyIHdpbGwgYmUgaWdub3JlZC4KLSAgICAgICAgICogQHBhcmFtIGRheSBEYXkgb2YgPGNvZGU+RHVyYXRpb248L2NvZGU+LgotICAgICAgICAgKiBAcGFyYW0gaG91ciBIb3VyIG9mIDxjb2RlPkR1cmF0aW9uPC9jb2RlPi4KLSAgICAgICAgICogQHBhcmFtIG1pbnV0ZSBNaW51dGUgb2YgPGNvZGU+RHVyYXRpb248L2NvZGU+LgotICAgICAgICAgKiBAcGFyYW0gc2Vjb25kIFNlY29uZCBvZiA8Y29kZT5EdXJhdGlvbjwvY29kZT4uCi0gICAgICAgICAqCi0gICAgICAgICAqIEByZXR1cm4gTmV3IDxjb2RlPkR1cmF0aW9uPC9jb2RlPiBjcmVhdGVkIHdpdGggdGhlIHNwZWNpZmllZCA8Y29kZT5kYXk8L2NvZGU+LCA8Y29kZT5ob3VyPC9jb2RlPiwgPGNvZGU+bWludXRlPC9jb2RlPgotICAgICAgICAgKiBhbmQgPGNvZGU+c2Vjb25kPC9jb2RlPi4KLSAgICAgICAgICoKLSAgICAgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gSWYgdGhlIHZhbHVlcyBhcmUgbm90IGEgdmFsaWQgcmVwcmVzZW50YXRpb24gb2YgYQotICAgICAgICAgKiA8Y29kZT5EdXJhdGlvbjwvY29kZT46IGlmIGFsbCB0aGUgZmllbGRzIChkYXksIGhvdXIsIC4uLikgYXJlIG51bGwgb3IKLSAgICAgICAgICogaWYgYW55IG9mIHRoZSBmaWVsZHMgaXMgbmVnYXRpdmUuCi0gICAgICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gSWYgaW1wbGVtZW50YXRpb24gY2Fubm90IHN1cHBvcnQgcmVxdWVzdGVkIHZhbHVlcy4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBEdXJhdGlvbiBuZXdEdXJhdGlvbkRheVRpbWUoCi0gICAgICAgICAgICAgICAgZmluYWwgYm9vbGVhbiBpc1Bvc2l0aXZlLAotICAgICAgICAgICAgICAgIGZpbmFsIEJpZ0ludGVnZXIgZGF5LAotICAgICAgICAgICAgICAgIGZpbmFsIEJpZ0ludGVnZXIgaG91ciwKLSAgICAgICAgICAgICAgICBmaW5hbCBCaWdJbnRlZ2VyIG1pbnV0ZSwKLSAgICAgICAgICAgICAgICBmaW5hbCBCaWdJbnRlZ2VyIHNlY29uZCkgewotCi0gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBEdXJhdGlvbkRheVRpbWVJbXBsKAotICAgICAgICAgICAgICAgICAgICAgICAgaXNQb3NpdGl2ZSwKLSAgICAgICAgICAgICAgICAgICAgICAgIGRheSwKLSAgICAgICAgICAgICAgICAgICAgICAgIGhvdXIsCi0gICAgICAgICAgICAgICAgICAgICAgICBtaW51dGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAoc2Vjb25kICE9IG51bGwpPyBuZXcgQmlnRGVjaW1hbChzZWNvbmQpOm51bGwKLSAgICAgICAgICAgICAgICApOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIDxwPkNyZWF0ZSBhIDxjb2RlPkR1cmF0aW9uPC9jb2RlPiBvZiB0eXBlIDxjb2RlPnhkdDpkYXlUaW1lRHVyYXRpb248L2NvZGU+IHVzaW5nIHRoZSBzcGVjaWZpZWQKLSAgICAgICAgICogPGNvZGU+ZGF5PC9jb2RlPiwgPGNvZGU+aG91cjwvY29kZT4sIDxjb2RlPm1pbnV0ZTwvY29kZT4gYW5kIDxjb2RlPnNlY29uZDwvY29kZT4gYXMgZGVmaW5lZCBpbgotICAgICAgICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aC1kYXRhbW9kZWwjZGF5VGltZUR1cmF0aW9uIj4KLSAgICAgICAgICogICBYUXVlcnkgMS4wIGFuZCBYUGF0aCAyLjAgRGF0YSBNb2RlbCwgeGR0OmRheVRpbWVEdXJhdGlvbjwvYT4uPC9wPgotICAgICAgICAgKgotICAgICAgICAgKiA8cD5UaGUgZGF0YXR5cGUgPGNvZGU+eGR0OmRheVRpbWVEdXJhdGlvbjwvY29kZT4gaXMgYSBzdWJ0eXBlIG9mIDxjb2RlPnhzOmR1cmF0aW9uPC9jb2RlPgotICAgICAgICAgKiB3aG9zZSBsZXhpY2FsIHJlcHJlc2VudGF0aW9uIGNvbnRhaW5zIG9ubHkgZGF5LCBob3VyLCBtaW51dGUsIGFuZCBzZWNvbmQgY29tcG9uZW50cy4KLSAgICAgICAgICogVGhpcyBkYXRhdHlwZSByZXNpZGVzIGluIHRoZSBuYW1lc3BhY2UgPGNvZGU+aHR0cDovL3d3dy53My5vcmcvMjAwMy8xMS94cGF0aC1kYXRhdHlwZXM8L2NvZGU+LjwvcD4KLSAgICAgICAgICoKLSAgICAgKiA8cD5BIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNGSUVMRF9VTkRFRklORUR9IHZhbHVlIGluZGljYXRlcyB0aGF0IGZpZWxkIGlzIG5vdCBzZXQuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGlzUG9zaXRpdmUgU2V0IHRvIDxjb2RlPmZhbHNlPC9jb2RlPiB0byBjcmVhdGUgYSBuZWdhdGl2ZSBkdXJhdGlvbi4gV2hlbiB0aGUgbGVuZ3RoCi0gICAgICogICBvZiB0aGUgZHVyYXRpb24gaXMgemVybywgdGhpcyBwYXJhbWV0ZXIgd2lsbCBiZSBpZ25vcmVkLgotICAgICAgICAgKiBAcGFyYW0gZGF5IERheSBvZiA8Y29kZT5EdXJhdGlvbjwvY29kZT4uCi0gICAgICAgICAqIEBwYXJhbSBob3VyIEhvdXIgb2YgPGNvZGU+RHVyYXRpb248L2NvZGU+LgotICAgICAgICAgKiBAcGFyYW0gbWludXRlIE1pbnV0ZSBvZiA8Y29kZT5EdXJhdGlvbjwvY29kZT4uCi0gICAgICAgICAqIEBwYXJhbSBzZWNvbmQgU2Vjb25kIG9mIDxjb2RlPkR1cmF0aW9uPC9jb2RlPi4KLSAgICAgICAgICoKLSAgICAgICAgICogQHJldHVybiBOZXcgPGNvZGU+RHVyYXRpb248L2NvZGU+IGNyZWF0ZWQgd2l0aCB0aGUgc3BlY2lmaWVkIDxjb2RlPmRheTwvY29kZT4sIDxjb2RlPmhvdXI8L2NvZGU+LCA8Y29kZT5taW51dGU8L2NvZGU+Ci0gICAgICAgICAqIGFuZCA8Y29kZT5zZWNvbmQ8L2NvZGU+LgotICAgICAgICAgKgotICAgICAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBJZiB0aGUgdmFsdWVzIGFyZSBub3QgYSB2YWxpZCByZXByZXNlbnRhdGlvbiBvZiBhCi0gICAgICAgICAqIDxjb2RlPkR1cmF0aW9uPC9jb2RlPjogaWYgYW55IG9mIHRoZSBmaWVsZHMgKGRheSwgaG91ciwgLi4uKSBpcyBuZWdhdGl2ZS4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBEdXJhdGlvbiBuZXdEdXJhdGlvbkRheVRpbWUoCi0gICAgICAgICAgICAgICAgZmluYWwgYm9vbGVhbiBpc1Bvc2l0aXZlLAotICAgICAgICAgICAgICAgIGZpbmFsIGludCBkYXksCi0gICAgICAgICAgICAgICAgZmluYWwgaW50IGhvdXIsCi0gICAgICAgICAgICAgICAgZmluYWwgaW50IG1pbnV0ZSwKLSAgICAgICAgICAgICAgICBmaW5hbCBpbnQgc2Vjb25kKSB7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgRHVyYXRpb25EYXlUaW1lSW1wbCgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNQb3NpdGl2ZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF5LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBob3VyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW51dGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlY29uZAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogPHA+Q3JlYXRlIGEgbmV3IGluc3RhbmNlIG9mIGFuIDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPi48L3A+Ci0gICAgICAgICAqCi0gICAgICogPHA+QWxsIGRhdGUvdGltZSBkYXRhdHlwZSBmaWVsZHMgc2V0IHRvIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNGSUVMRF9VTkRFRklORUR9IG9yIG51bGwuPC9wPgotICAgICAqCi0gICAgICogQHJldHVybiBOZXcgPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IHdpdGggYWxsIGRhdGUvdGltZSBkYXRhdHlwZSBmaWVsZHMgc2V0IHRvCi0gICAgICogICB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjRklFTERfVU5ERUZJTkVEfSBvciBudWxsLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIFhNTEdyZWdvcmlhbkNhbGVuZGFyIG5ld1hNTEdyZWdvcmlhbkNhbGVuZGFyKCkgewotCi0gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBYTUxHcmVnb3JpYW5DYWxlbmRhckltcGwoKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiA8cD5DcmVhdGUgYSBuZXcgWE1MR3JlZ29yaWFuQ2FsZW5kYXIgYnkgcGFyc2luZyB0aGUgU3RyaW5nIGFzIGEgbGV4aWNhbCByZXByZXNlbnRhdGlvbi48L3A+Ci0gICAgICAgICAqCi0gICAgICogPHA+UGFyc2luZyB0aGUgbGV4aWNhbCBzdHJpbmcgcmVwcmVzZW50YXRpb24gaXMgZGVmaW5lZCBpbgotICAgICAqIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3htbHNjaGVtYS0yLyNkYXRlVGltZS1vcmRlciI+WE1MIFNjaGVtYSAxLjAgUGFydCAyLCBTZWN0aW9uIDMuMi5bNy0xNF0uMSwKLSAgICAgKiA8ZW0+TGV4aWNhbCBSZXByZXNlbnRhdGlvbjwvZW0+LjwvYT48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5UaGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG1heSBub3QgaGF2ZSBhbnkgbGVhZGluZyBhbmQgdHJhaWxpbmcgd2hpdGVzcGFjZXMuPC9wPgotICAgICAqCi0gICAgICogPHA+VGhlIHBhcnNpbmcgaXMgZG9uZSBmaWVsZCBieSBmaWVsZCBzbyB0aGF0Ci0gICAgICogdGhlIGZvbGxvd2luZyBob2xkcyBmb3IgYW55IGxleGljYWxseSBjb3JyZWN0IFN0cmluZyB4OjwvcD4KLSAgICAgKiA8cHJlPgotICAgICAqIG5ld1hNTEdyZWdvcmlhbkNhbGVuZGFyKHgpLnRvWE1MRm9ybWF0KCkuZXF1YWxzKHgpCi0gICAgICogPC9wcmU+Ci0gICAgICogPHA+RXhjZXB0IGZvciB0aGUgbm90ZWQgbGV4aWNhbC9jYW5vbmljYWwgcmVwcmVzZW50YXRpb24gbWlzbWF0Y2hlcwotICAgICAqIGxpc3RlZCBpbiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzA1L3htbHNjaGVtYS1lcnJhdGEjZTItNDUiPgotICAgICAqIFhNTCBTY2hlbWEgMS4wIGVycmF0YSwgU2VjdGlvbiAzLjIuNy4yPC9hPi48L3A+Ci0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBsZXhpY2FsUmVwcmVzZW50YXRpb24gTGV4aWNhbCByZXByZXNlbnRhdGlvbiBvZiBvbmUgdGhlIGVpZ2h0IFhNTCBTY2hlbWEgZGF0ZS90aW1lIGRhdGF0eXBlcy4KLSAgICAgICAgICoKLSAgICAgICAgICogQHJldHVybiA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gY3JlYXRlZCBmcm9tIHRoZSA8Y29kZT5sZXhpY2FsUmVwcmVzZW50YXRpb248L2NvZGU+LgotICAgICAgICAgKgotICAgICAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBJZiB0aGUgPGNvZGU+bGV4aWNhbFJlcHJlc2VudGF0aW9uPC9jb2RlPiBpcyBub3QgYSB2YWxpZCA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4uCi0gICAgICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gSWYgPGNvZGU+bGV4aWNhbFJlcHJlc2VudGF0aW9uPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBYTUxHcmVnb3JpYW5DYWxlbmRhciBuZXdYTUxHcmVnb3JpYW5DYWxlbmRhcihmaW5hbCBTdHJpbmcgbGV4aWNhbFJlcHJlc2VudGF0aW9uKSB7Ci0KLSAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFhNTEdyZWdvcmlhbkNhbGVuZGFySW1wbChsZXhpY2FsUmVwcmVzZW50YXRpb24pOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIDxwPkNyZWF0ZSBhbiA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gZnJvbSBhIHtAbGluayBHcmVnb3JpYW5DYWxlbmRhcn0uPC9wPgotICAgICAgICAgKgotICAgICAgICAgKiA8dGFibGUgYm9yZGVyPSIyIiBydWxlcz0iYWxsIiBjZWxscGFkZGluZz0iMiI+Ci0gICAgICAgICAqICAgPHRoZWFkPgotICAgICAgICAgKiAgICAgPHRyPgotICAgICAgICAgKiAgICAgICA8dGggYWxpZ249ImNlbnRlciIgY29sc3Bhbj0iMiI+Ci0gICAgICAgICAqICAgICAgICAgIEZpZWxkIGJ5IEZpZWxkIENvbnZlcnNpb24gZnJvbQotICAgICAgICAgKiAgICAgICAgICB7QGxpbmsgR3JlZ29yaWFuQ2FsZW5kYXJ9IHRvIGFuIHtAbGluayBYTUxHcmVnb3JpYW5DYWxlbmRhcn0KLSAgICAgICAgICogICAgICAgPC90aD4KLSAgICAgICAgICogICAgIDwvdHI+Ci0gICAgICAgICAqICAgICA8dHI+Ci0gICAgICAgICAqICAgICAgICA8dGg+PGNvZGU+amF2YS51dGlsLkdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiBmaWVsZDwvdGg+Ci0gICAgICAgICAqICAgICAgICA8dGg+PGNvZGU+amF2YXgueG1sLmRhdGF0eXBlLlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiBmaWVsZDwvdGg+Ci0gICAgICAgICAqICAgICA8L3RyPgotICAgICAgICAgKiAgIDwvdGhlYWQ+Ci0gICAgICAgICAqICAgPHRib2R5PgotICAgICAgICAgKiAgICAgPHRyPgotICAgICAgICAgKiAgICAgICA8dGQ+PGNvZGU+RVJBID09IEdyZWdvcmlhbkNhbGVuZGFyLkJDID8gLVlFQVIgOiBZRUFSPC9jb2RlPjwvdGQ+Ci0gICAgICAgICAqICAgICAgIDx0ZD57QGxpbmsgWE1MR3JlZ29yaWFuQ2FsZW5kYXIjc2V0WWVhcihpbnQgeWVhcil9PC90ZD4KLSAgICAgICAgICogICAgIDwvdHI+Ci0gICAgICAgICAqICAgICA8dHI+Ci0gICAgICAgICAqICAgICAgIDx0ZD48Y29kZT5NT05USCArIDE8L2NvZGU+PC90ZD4KLSAgICAgICAgICogICAgICAgPHRkPntAbGluayBYTUxHcmVnb3JpYW5DYWxlbmRhciNzZXRNb250aChpbnQgbW9udGgpfTwvdGQ+Ci0gICAgICAgICAqICAgICA8L3RyPgotICAgICAgICAgKiAgICAgPHRyPgotICAgICAgICAgKiAgICAgICA8dGQ+PGNvZGU+REFZX09GX01PTlRIPC9jb2RlPjwvdGQ+Ci0gICAgICAgICAqICAgICAgIDx0ZD57QGxpbmsgWE1MR3JlZ29yaWFuQ2FsZW5kYXIjc2V0RGF5KGludCBkYXkpfTwvdGQ+Ci0gICAgICAgICAqICAgICA8L3RyPgotICAgICAgICAgKiAgICAgPHRyPgotICAgICAgICAgKiAgICAgICA8dGQ+PGNvZGU+SE9VUl9PRl9EQVksIE1JTlVURSwgU0VDT05ELCBNSUxMSVNFQ09ORDwvY29kZT48L3RkPgotICAgICAgICAgKiAgICAgICA8dGQ+e0BsaW5rIFhNTEdyZWdvcmlhbkNhbGVuZGFyI3NldFRpbWUoaW50IGhvdXIsIGludCBtaW51dGUsIGludCBzZWNvbmQsIEJpZ0RlY2ltYWwgZnJhY3Rpb25hbCl9PC90ZD4KLSAgICAgICAgICogICAgIDwvdHI+Ci0gICAgICAgICAqICAgICA8dHI+Ci0gICAgICAgICAqICAgICAgIDx0ZD4KLSAgICAgICAgICogICAgICAgICA8Y29kZT4oWk9ORV9PRkZTRVQgKyBEU1RfT0ZGU0VUKSAvICg2MCoxMDAwKTwvY29kZT48YnIvPgotICAgICAgICAgKiAgICAgICAgIDxlbT4oaW4gbWludXRlcyk8L2VtPgotICAgICAgICAgKiAgICAgICA8L3RkPgotICAgICAgICAgKiAgICAgICA8dGQ+e0BsaW5rIFhNTEdyZWdvcmlhbkNhbGVuZGFyI3NldFRpbWV6b25lKGludCBvZmZzZXQpfTxzdXA+PGVtPio8L2VtPjwvc3VwPgotICAgICAgICAgKiAgICAgICA8L3RkPgotICAgICAgICAgKiAgICAgPC90cj4KLSAgICAgICAgICogICA8L3Rib2R5PgotICAgICAgICAgKiA8L3RhYmxlPgotICAgICAgICAgKiA8cD48ZW0+KjwvZW0+Y29udmVyc2lvbiBsb3NzIG9mIGluZm9ybWF0aW9uLiBJdCBpcyBub3QgcG9zc2libGUgdG8gcmVwcmVzZW50Ci0gICAgICAgICAqIGEgPGNvZGU+amF2YS51dGlsLkdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiBkYXlsaWdodCBzYXZpbmdzIHRpbWV6b25lIGlkIGluIHRoZQotICAgICAgICAgKiBYTUwgU2NoZW1hIDEuMCBkYXRlL3RpbWUgZGF0YXR5cGUgcmVwcmVzZW50YXRpb24uPC9wPgotICAgICAgICAgKgotICAgICAgICAgKiA8cD5UbyBjb21wdXRlIHRoZSByZXR1cm4gdmFsdWUncyA8Y29kZT5UaW1lWm9uZTwvY29kZT4gZmllbGQsCi0gICAgICAgICAqIDx1bD4KLSAgICAgICAgICogPGxpPndoZW4gPGNvZGU+dGhpcy5nZXRUaW1lem9uZSgpICE9IEZJRUxEX1VOREVGSU5FRDwvY29kZT4sCi0gICAgICAgICAqIGNyZWF0ZSBhIDxjb2RlPmphdmEudXRpbC5UaW1lWm9uZTwvY29kZT4gd2l0aCBhIGN1c3RvbSB0aW1lem9uZSBpZAotICAgICAgICAgKiB1c2luZyB0aGUgPGNvZGU+dGhpcy5nZXRUaW1lem9uZSgpPC9jb2RlPi48L2xpPgotICAgICAgICAgKiA8bGk+ZWxzZSB1c2UgdGhlIDxjb2RlPkdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiBkZWZhdWx0IHRpbWV6b25lIHZhbHVlCi0gICAgICAgICAqIGZvciB0aGUgaG9zdCBpcyBkZWZpbmVkIGFzIHNwZWNpZmllZCBieQotICAgICAgICAgKiA8Y29kZT5qYXZhLnV0aWwuVGltZVpvbmUuZ2V0RGVmYXVsdCgpPC9jb2RlPi48L2xpPjwvcD4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIGNhbCA8Y29kZT5qYXZhLnV0aWwuR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IHVzZWQgdG8gY3JlYXRlIDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPgotICAgICAgICAgKgotICAgICAgICAgKiBAcmV0dXJuIDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiBjcmVhdGVkIGZyb20gPGNvZGU+amF2YS51dGlsLkdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPgotICAgICAgICAgKgotICAgICAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIElmIDxjb2RlPmNhbDwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgWE1MR3JlZ29yaWFuQ2FsZW5kYXIgbmV3WE1MR3JlZ29yaWFuQ2FsZW5kYXIoZmluYWwgR3JlZ29yaWFuQ2FsZW5kYXIgY2FsKSB7Ci0KLSAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFhNTEdyZWdvcmlhbkNhbGVuZGFySW1wbChjYWwpOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIDxwPkNvbnN0cnVjdG9yIGFsbG93aW5nIGZvciBjb21wbGV0ZSB2YWx1ZSBzcGFjZXMgYWxsb3dlZCBieQotICAgICAgICAgKiBXM0MgWE1MIFNjaGVtYSAxLjAgcmVjb21tZW5kYXRpb24gZm9yIHhzZDpkYXRlVGltZSBhbmQgcmVsYXRlZAotICAgICAgICAgKiBidWlsdGluIGRhdGF0eXBlcy4gTm90ZSB0aGF0IDxjb2RlPnllYXI8L2NvZGU+IHBhcmFtZXRlciBzdXBwb3J0cwotICAgICAgICAgKiBhcmJpdHJhcmlseSBsYXJnZSBudW1iZXJzIGFuZCBmcmFjdGlvbmFsU2Vjb25kIGhhcyBpbmZpbml0ZQotICAgICAgICAgKiBwcmVjaXNpb24uPC9wPgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0geWVhciBvZiA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gdG8gYmUgY3JlYXRlZC4KLSAgICAgICAgICogQHBhcmFtIG1vbnRoIG9mIDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiB0byBiZSBjcmVhdGVkLgotICAgICAgICAgKiBAcGFyYW0gZGF5IG9mIDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiB0byBiZSBjcmVhdGVkLgotICAgICAgICAgKiBAcGFyYW0gaG91ciBvZiA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gdG8gYmUgY3JlYXRlZC4KLSAgICAgICAgICogQHBhcmFtIG1pbnV0ZSBvZiA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gdG8gYmUgY3JlYXRlZC4KLSAgICAgICAgICogQHBhcmFtIHNlY29uZCBvZiA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gdG8gYmUgY3JlYXRlZC4KLSAgICAgICAgICogQHBhcmFtIGZyYWN0aW9uYWxTZWNvbmQgb2YgPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IHRvIGJlIGNyZWF0ZWQuCi0gICAgICAgICAqIEBwYXJhbSB0aW1lem9uZSBvZiA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gdG8gYmUgY3JlYXRlZC4KLSAgICAgICAgICoKLSAgICAgICAgICogQHJldHVybiA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gY3JlYXRlZCBmcm9tIHNwZWNpZmllZCB2YWx1ZXMuCi0gICAgICAgICAqCi0gICAgICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIElmIGFueSBpbmRpdmlkdWFsIHBhcmFtZXRlcidzIHZhbHVlIGlzIG91dHNpZGUgdGhlIG1heGltdW0gdmFsdWUgY29uc3RyYWludCBmb3IgdGhlIGZpZWxkCi0gICAgICAgICAqICAgYXMgZGV0ZXJtaW5lZCBieSB0aGUgRGF0ZS9UaW1lIERhdGEgTWFwcGluZyB0YWJsZSBpbiB7QGxpbmsgWE1MR3JlZ29yaWFuQ2FsZW5kYXJ9Ci0gICAgICAgICAqICAgb3IgaWYgdGhlIGNvbXBvc2l0ZSB2YWx1ZXMgY29uc3RpdHV0ZSBhbiBpbnZhbGlkIDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiBpbnN0YW5jZQotICAgICAgICAgKiAgIGFzIGRldGVybWluZWQgYnkge0BsaW5rIFhNTEdyZWdvcmlhbkNhbGVuZGFyI2lzVmFsaWQoKX0uCi0gICAgICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gSWYgYW55IHBhcmFtZXRlcnMgYXJlIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAgICAgKgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIFhNTEdyZWdvcmlhbkNhbGVuZGFyIG5ld1hNTEdyZWdvcmlhbkNhbGVuZGFyKAotICAgICAgICAgICAgICAgIGZpbmFsIEJpZ0ludGVnZXIgeWVhciwKLSAgICAgICAgICAgICAgICBmaW5hbCBpbnQgbW9udGgsCi0gICAgICAgICAgICAgICAgZmluYWwgaW50IGRheSwKLSAgICAgICAgICAgICAgICBmaW5hbCBpbnQgaG91ciwKLSAgICAgICAgICAgICAgICBmaW5hbCBpbnQgbWludXRlLAotICAgICAgICAgICAgICAgIGZpbmFsIGludCBzZWNvbmQsCi0gICAgICAgICAgICAgICAgZmluYWwgQmlnRGVjaW1hbCBmcmFjdGlvbmFsU2Vjb25kLAotICAgICAgICAgICAgICAgIGZpbmFsIGludCB0aW1lem9uZSkgewotCi0gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBYTUxHcmVnb3JpYW5DYWxlbmRhckltcGwoCi0gICAgICAgICAgICAgICAgICAgICAgICB5ZWFyLAotICAgICAgICAgICAgICAgICAgICAgICAgbW9udGgsCi0gICAgICAgICAgICAgICAgICAgICAgICBkYXksCi0gICAgICAgICAgICAgICAgICAgICAgICBob3VyLAotICAgICAgICAgICAgICAgICAgICAgICAgbWludXRlLAotICAgICAgICAgICAgICAgICAgICAgICAgc2Vjb25kLAotICAgICAgICAgICAgICAgICAgICAgICAgZnJhY3Rpb25hbFNlY29uZCwKLSAgICAgICAgICAgICAgICAgICAgICAgIHRpbWV6b25lCi0gICAgICAgICAgICAgICAgKTsKLSAgICAgICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvamF4cC9kYXRhdHlwZS9EdXJhdGlvbkRheVRpbWVJbXBsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9qYXhwL2RhdGF0eXBlL0R1cmF0aW9uRGF5VGltZUltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOWU1Y2FmZC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9qYXhwL2RhdGF0eXBlL0R1cmF0aW9uRGF5VGltZUltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE5NiArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogQ29weXJpZ2h0IChjKSAyMDA5IGJ5IE9yYWNsZSBDb3Jwb3JhdGlvbi4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuamF4cC5kYXRhdHlwZTsKLQotCi1pbXBvcnQgamF2YS5tYXRoLkJpZ0ludGVnZXI7Ci1pbXBvcnQgamF2YS5tYXRoLkJpZ0RlY2ltYWw7Ci1pbXBvcnQgamF2YXgueG1sLmRhdGF0eXBlLkRhdGF0eXBlQ29uc3RhbnRzOwotCi0vKioKLSAqIDxwPlJlcHJlc2VudCBhIHN1YnR5cGUgPGNvZGU+eGR0OmRheVRpbWVEdXJhdGlvbjwvY29kZT4gb2YgYSA8Y29kZT5EdXJhdGlvbjwvY29kZT4KLSAqIGFzIHNwZWNpZmllZCBpbiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aC1kYXRhbW9kZWwjZGF5VGltZUR1cmF0aW9uIj4KLSAqICAgWFF1ZXJ5IDEuMCBhbmQgWFBhdGggMi4wIERhdGEgTW9kZWwsIHhkdDpkYXlUaW1lRHVyYXRpb248L2E+LjwvcD4KLSAqCi0gKgotICogPHA+VGhlIER1cmF0aW9uWWVhck1vbnRoIG9iamVjdCByZXByZXNlbnRzIGEgcGVyaW9kIG9mIEdyZWdvcmlhbiB0aW1lLAotICogd2l0aCBhIGxleGljYWwgcmVwcmVzZW50YXRpb24sICI8ZW0+UG5EVG5Ibk1uUzwvZW0+IiB0aGF0IGNvbnRhaW5zIG9ubHkgeWVhciBhbmQgbW9udGggY29tcG9uZW50cy4KLSAqIDwvcD4KLSAqCi0gKgotICogQGF1dGhvciA8YSBocmVmPSJtYWlsdG86VmlrcmFtLkFyb3NrYXJAU3VuLkNPTSI+VmlrcmFtIEFyb3NrYXI8L2E+Ci0gKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzpIdWl6aGUud2FuZ0BvcmFjbGUuY29tIj5Kb2UgV2FuZzwvYT4KLSAqIEB2ZXJzaW9uICRSZXZpc2lvbjogMS4yICQsICREYXRlOiAyMDEwLzA1LzE5IDIzOjIwOjA2ICQKLQotICogQHNlZSBYTUxHcmVnb3JpYW5DYWxlbmRhciNhZGQoRHVyYXRpb24pCi0gKi8KLQotY2xhc3MgRHVyYXRpb25EYXlUaW1lSW1wbAotICAgICAgICBleHRlbmRzIER1cmF0aW9uSW1wbCB7Ci0KLSAgICBwdWJsaWMgRHVyYXRpb25EYXlUaW1lSW1wbCgKLSAgICAgICAgYm9vbGVhbiBpc1Bvc2l0aXZlLAotICAgICAgICBCaWdJbnRlZ2VyIGRheXMsCi0gICAgICAgIEJpZ0ludGVnZXIgaG91cnMsCi0gICAgICAgIEJpZ0ludGVnZXIgbWludXRlcywKLSAgICAgICAgQmlnRGVjaW1hbCBzZWNvbmRzKSB7Ci0KLSAgICAgICAgc3VwZXIoaXNQb3NpdGl2ZSwgbnVsbCwgbnVsbCwgZGF5cywgaG91cnMsIG1pbnV0ZXMsIHNlY29uZHMpOwotICAgICAgICBjb252ZXJ0VG9DYW5vbmljYWxEYXlUaW1lKCk7Ci0gICAgfQotCi0gICAgcHVibGljIER1cmF0aW9uRGF5VGltZUltcGwoCi0gICAgICAgIGJvb2xlYW4gaXNQb3NpdGl2ZSwKLSAgICAgICAgaW50IGRheXMsCi0gICAgICAgIGludCBob3VycywKLSAgICAgICAgaW50IG1pbnV0ZXMsCi0gICAgICAgIGludCBzZWNvbmRzKSB7Ci0KLSAgICAgICAgdGhpcygKLSAgICAgICAgICAgIGlzUG9zaXRpdmUsCi0gICAgICAgICAgICB3cmFwKGRheXMpLAotICAgICAgICAgICAgd3JhcChob3VycyksCi0gICAgICAgICAgICB3cmFwKG1pbnV0ZXMpLAotICAgICAgICAgICAgKHNlY29uZHMgIT0gRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVEID8gbmV3IEJpZ0RlY2ltYWwoU3RyaW5nLnZhbHVlT2Yoc2Vjb25kcykpIDogbnVsbCkpOwotICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogPHA+Q29uc3RydWN0IGEgPGNvZGU+RHVyYXRpb248L2NvZGU+IG9mIHR5cGUgPGNvZGU+eGR0OmRheVRpbWVEdXJhdGlvbjwvY29kZT4gYnkgcGFyc2luZyBpdHMgPGNvZGU+U3RyaW5nPC9jb2RlPiByZXByZXNlbnRhdGlvbiwKLSAgICAgICAgICogIjxlbT5QbkRUbkhuTW5TPC9lbT4iLCA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aC1kYXRhbW9kZWwjZGF5VGltZUR1cmF0aW9uIj4KLSAgICAgICAgICogICBYUXVlcnkgMS4wIGFuZCBYUGF0aCAyLjAgRGF0YSBNb2RlbCwgeGR0OmRheVRpbWVEdXJhdGlvbjwvYT4uPC9wPgotICAgICAgICAgKgotICAgICAgICAgKiA8cD5UaGUgZGF0YXR5cGUgPGNvZGU+eGR0OmRheVRpbWVEdXJhdGlvbjwvY29kZT4gaXMgYSBzdWJ0eXBlIG9mIDxjb2RlPnhzOmR1cmF0aW9uPC9jb2RlPgotICAgICAgICAgKiB3aG9zZSBsZXhpY2FsIHJlcHJlc2VudGF0aW9uIGNvbnRhaW5zIG9ubHkgZGF5LCBob3VyLCBtaW51dGUsIGFuZCBzZWNvbmQgY29tcG9uZW50cy4KLSAgICAgICAgICogVGhpcyBkYXRhdHlwZSByZXNpZGVzIGluIHRoZSBuYW1lc3BhY2UgPGNvZGU+aHR0cDovL3d3dy53My5vcmcvMjAwMy8xMS94cGF0aC1kYXRhdHlwZXM8L2NvZGU+LjwvcD4KLSAgICAgICAgICoKLSAgICAgKiA8cD5BbGwgZm91ciB2YWx1ZXMgYXJlIHNldCBhbmQgYXZhaWxhYmUgZnJvbSB0aGUgY3JlYXRlZCB7QGxpbmsgRHVyYXRpb259PC9wPgotICAgICAgICAgKgotICAgICAqIDxwPlRoZSBYTUwgU2NoZW1hIHNwZWNpZmljYXRpb24gc3RhdGVzIHRoYXQgdmFsdWVzIGNhbiBiZSBvZiBhbiBhcmJpdHJhcnkgc2l6ZS4KLSAgICAgKiBJbXBsZW1lbnRhdGlvbnMgbWF5IGNob3NlIG5vdCB0byBvciBiZSBpbmNhcGFibGUgb2Ygc3VwcG9ydGluZyBhcmJpdHJhcmlseSBsYXJnZSBhbmQvb3Igc21hbGwgdmFsdWVzLgotICAgICAqIEFuIHtAbGluayBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbn0gd2lsbCBiZSB0aHJvd24gd2l0aCBhIG1lc3NhZ2UgaW5kaWNhdGluZyBpbXBsZW1lbnRhdGlvbiBsaW1pdHMKLSAgICAgKiBpZiBpbXBsZW1lbnRhdGlvbiBjYXBhY2l0aWVzIGFyZSBleGNlZWRlZC48L3A+Ci0gICAgICoKLSAgICAgICAgICogQHBhcmFtIGxleGljYWxSZXByZXNlbnRhdGlvbiBMZXhpY2FsIHJlcHJlc2VudGF0aW9uIG9mIGEgZHVyYXRpb24uCi0gICAgICAgICAqCi0gICAgICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIElmIDxjb2RlPmxleGljYWxSZXByZXNlbnRhdGlvbjwvY29kZT4gaXMgbm90IGEgdmFsaWQgcmVwcmVzZW50YXRpb24gb2YgYSA8Y29kZT5EdXJhdGlvbjwvY29kZT4gZXhwcmVzc2VkIG9ubHkgaW4gdGVybXMgb2YgZGF5cyBhbmQgdGltZS4KLSAgICAgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBJZiBpbXBsZW1lbnRhdGlvbiBjYW5ub3Qgc3VwcG9ydCByZXF1ZXN0ZWQgdmFsdWVzLgotICAgICAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIElmIDxjb2RlPmxleGljYWxSZXByZXNlbnRhdGlvbjwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICAgICAqLwotICAgIHByb3RlY3RlZCBEdXJhdGlvbkRheVRpbWVJbXBsKFN0cmluZyBsZXhpY2FsUmVwcmVzZW50YXRpb24pIHsKLSAgICAgICAgc3VwZXIobGV4aWNhbFJlcHJlc2VudGF0aW9uKTsKLQotICAgICAgICBpZiAoZ2V0WWVhcnMoKSA+IDAgfHwgZ2V0TW9udGhzKCkgPiAwKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICAiVHJ5aW5nIHRvIGNyZWF0ZSBhbiB4ZHQ6ZGF5VGltZUR1cmF0aW9uIHdpdGggYW4gaW52YWxpZCIKLSAgICAgICAgICAgICAgICAgICAgKyAiIGxleGljYWwgcmVwcmVzZW50YXRpb24gb2YgXCIiICsgbGV4aWNhbFJlcHJlc2VudGF0aW9uCi0gICAgICAgICAgICAgICAgICAgICsgIlwiLCBkYXRhIG1vZGVsIHJlcXVpcmVzIGEgZm9ybWF0IFBuRFRuSG5NblMuIik7Ci0gICAgICAgIH0KLQotICAgICAgICBjb252ZXJ0VG9DYW5vbmljYWxEYXlUaW1lKCk7Ci0gICAgfQotICAgICAgICAvKioKLSAgICAgICAgICogPHA+Q3JlYXRlIGEgPGNvZGU+RHVyYXRpb248L2NvZGU+IG9mIHR5cGUgPGNvZGU+eGR0OmRheVRpbWVEdXJhdGlvbjwvY29kZT4gdXNpbmcgdGhlIHNwZWNpZmllZCBtaWxsaXNlY29uZHMgYXMgZGVmaW5lZCBpbgotICAgICAgICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aC1kYXRhbW9kZWwjZGF5VGltZUR1cmF0aW9uIj4KLSAgICAgICAgICogICBYUXVlcnkgMS4wIGFuZCBYUGF0aCAyLjAgRGF0YSBNb2RlbCwgeGR0OmRheVRpbWVEdXJhdGlvbjwvYT4uPC9wPgotICAgICAgICAgKgotICAgICAgICAgKiA8cD5UaGUgZGF0YXR5cGUgPGNvZGU+eGR0OmRheVRpbWVEdXJhdGlvbjwvY29kZT4gaXMgYSBzdWJ0eXBlIG9mIDxjb2RlPnhzOmR1cmF0aW9uPC9jb2RlPgotICAgICAgICAgKiB3aG9zZSBsZXhpY2FsIHJlcHJlc2VudGF0aW9uIGNvbnRhaW5zIG9ubHkgZGF5LCBob3VyLCBtaW51dGUsIGFuZCBzZWNvbmQgY29tcG9uZW50cy4KLSAgICAgICAgICogVGhpcyBkYXRhdHlwZSByZXNpZGVzIGluIHRoZSBuYW1lc3BhY2UgPGNvZGU+aHR0cDovL3d3dy53My5vcmcvMjAwMy8xMS94cGF0aC1kYXRhdHlwZXM8L2NvZGU+LjwvcD4KLSAgICAgICAgICoKLSAgICAgKiA8cD5BbGwgZm91ciB2YWx1ZXMgYXJlIHNldCBieSBjb21wdXRpbmcgdGhlaXIgdmFsdWVzIGZyb20gdGhlIHNwZWNpZmllZCBtaWxsaXNlY29uZHMKLSAgICAgKiBhbmQgYXJlIGF2YWlsYWJlIHVzaW5nIHRoZSA8Y29kZT5nZXQ8L2NvZGU+IG1ldGhvZHMgb2YgIHRoZSBjcmVhdGVkIHtAbGluayBEdXJhdGlvbn0uCi0gICAgICogVGhlIHZhbHVlcyBjb25mb3JtIHRvIGFuZCBhcmUgZGVmaW5lZCBieTo8L3A+Ci0gICAgICogPHVsPgotICAgICAqICAgPGxpPklTTyA4NjAxOjIwMDAoRSkgU2VjdGlvbiA1LjUuMy4yIEFsdGVybmF0aXZlIGZvcm1hdDwvbGk+Ci0gICAgICogICA8bGk+PGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveG1sc2NoZW1hLTIvI2lzb2Zvcm1hdHMiPgotICAgICAqICAgICBXM0MgWE1MIFNjaGVtYSAxLjAgUGFydCAyLCBBcHBlbmRpeCBELCBJU08gODYwMSBEYXRlIGFuZCBUaW1lIEZvcm1hdHM8L2E+Ci0gICAgICogICA8L2xpPgotICAgICAqICAgPGxpPntAbGluayBYTUxHcmVnb3JpYW5DYWxlbmRhcn0gIERhdGUvVGltZSBEYXRhdHlwZSBGaWVsZCBNYXBwaW5nIEJldHdlZW4gWE1MIFNjaGVtYSAxLjAgYW5kIEphdmEgUmVwcmVzZW50YXRpb248L2xpPgotICAgICAqIDwvdWw+Ci0gICAgICAgICAqCi0gICAgICAgICAqIDxwPlRoZSBkZWZhdWx0IHN0YXJ0IGluc3RhbmNlIGlzIGRlZmluZWQgYnkge0BsaW5rIEdyZWdvcmlhbkNhbGVuZGFyfSdzIHVzZSBvZiB0aGUgc3RhcnQgb2YgdGhlIGVwb2NoOiBpLmUuLAotICAgICAgICAgKiB7QGxpbmsgamF2YS51dGlsLkNhbGVuZGFyI1lFQVJ9ID0gMTk3MCwKLSAgICAgICAgICoge0BsaW5rIGphdmEudXRpbC5DYWxlbmRhciNNT05USH0gPSB7QGxpbmsgamF2YS51dGlsLkNhbGVuZGFyI0pBTlVBUll9LAotICAgICAgICAgKiB7QGxpbmsgamF2YS51dGlsLkNhbGVuZGFyI0RBVEV9ID0gMSwgZXRjLgotICAgICAgICAgKiBUaGlzIGlzIGltcG9ydGFudCBhcyB0aGVyZSBhcmUgdmFyaWF0aW9ucyBpbiB0aGUgR3JlZ29yaWFuIENhbGVuZGFyLAotICAgICAgICAgKiBlLmcuIGxlYXAgeWVhcnMgaGF2ZSBkaWZmZXJlbnQgZGF5cyBpbiB0aGUgbW9udGggPSB7QGxpbmsgamF2YS51dGlsLkNhbGVuZGFyI0ZFQlJVQVJZfQotICAgICAgICAgKiBzbyB0aGUgcmVzdWx0IG9mIHtAbGluayBEdXJhdGlvbiNnZXREYXlzKCl9IGNhbiBiZSBpbmZsdWVuY2VkLjwvcD4KLSAgICAgICAgICoKLSAgICAgKiA8cD5BbnkgcmVtYWluaW5nIG1pbGxpc2Vjb25kcyBhZnRlciBkZXRlcm1pbmluZyB0aGUgZGF5LCBob3VyLCBtaW51dGUgYW5kIHNlY29uZCBhcmUgZGlzY2FyZGVkLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBkdXJhdGlvbkluTWlsbGlzZWNvbmRzIE1pbGxpc2Vjb25kcyBvZiA8Y29kZT5EdXJhdGlvbjwvY29kZT4gdG8gY3JlYXRlLgotICAgICAqCi0gICAgICogQHJldHVybiBOZXcgPGNvZGU+RHVyYXRpb248L2NvZGU+IGNyZWF0ZWQgd2l0aCB0aGUgc3BlY2lmaWVkIDxjb2RlPmR1cmF0aW9uSW5NaWxsaXNlY29uZHM8L2NvZGU+LgotICAgICAqCi0gICAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aC1kYXRhbW9kZWwjZGF5VGltZUR1cmF0aW9uIj4KLSAgICAgKiAgIFhRdWVyeSAxLjAgYW5kIFhQYXRoIDIuMCBEYXRhIE1vZGVsLCB4ZHQ6ZGF5VGltZUR1cmF0aW9uPC9hPgotICAgICAqLwotICAgIHByb3RlY3RlZCBEdXJhdGlvbkRheVRpbWVJbXBsKGZpbmFsIGxvbmcgZHVyYXRpb25Jbk1pbGxpc2Vjb25kcykgewotICAgICAgICAgICAgc3VwZXIoZHVyYXRpb25Jbk1pbGxpc2Vjb25kcyk7Ci0gICAgICAgICAgICBjb252ZXJ0VG9DYW5vbmljYWxEYXlUaW1lKCk7Ci0gICAgICAgICAgICAvLyBvbmx5IGRheSwgaG91ciwgbWludXRlLCBhbmQgc2Vjb25kIHNob3VsZCBoYXZlIHZhbHVlcwotICAgICAgICAgICAgeWVhcnMgPSBudWxsOwotICAgICAgICAgICAgbW9udGhzID0gbnVsbDsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFRoZSB2YWx1ZSBzcGFjZSBvZiB4czpkYXlUaW1lRHVyYXRpb24gaXMgdGhlIHNldCBvZiBmcmFjdGlvbmFsIHNlY29uZCB2YWx1ZXMuCi0gICAgICogQHJldHVybiBmcmFjdGlvbmFsIHNlY29uZCB2YWx1ZXMKLSAgICAgKi8KLSAgICBwdWJsaWMgZmxvYXQgZ2V0VmFsdWUoKSB7Ci0gICAgICAgIGZsb2F0IHNlYyA9IChzZWNvbmRzPT1udWxsKT8wOnNlY29uZHMuZmxvYXRWYWx1ZSgpOwotICAgICAgICByZXR1cm4gKCgoKChnZXREYXlzKCkgKiAyNCkgKwotICAgICAgICAgICAgICAgICAgICBnZXRIb3VycygpKSAqIDYwKSArCi0gICAgICAgICAgICAgICAgICAgIGdldE1pbnV0ZXMoKSkqNjApICsKLSAgICAgICAgICAgICAgICAgICAgc2VjOwotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBjb252ZXJ0VG9DYW5vbmljYWxEYXlUaW1lKCkgewotCi0gICAgICAgIHdoaWxlIChnZXRTZWNvbmRzKCkgPj0gNjApCi0gICAgICAgIHsKLSAgICAgICAgICAgIHNlY29uZHMgPSBzZWNvbmRzLnN1YnRyYWN0KEJpZ0RlY2ltYWwudmFsdWVPZig2MCkpOwotICAgICAgICAgICAgbWludXRlcyA9IEJpZ0ludGVnZXIudmFsdWVPZigobG9uZykgZ2V0TWludXRlcygpKS5hZGQoQmlnSW50ZWdlci5PTkUpOwotICAgICAgICB9Ci0KLSAgICAgICAgd2hpbGUgKGdldE1pbnV0ZXMoKSA+PSA2MCkKLSAgICAgICAgewotICAgICAgICAgICAgbWludXRlcyA9IG1pbnV0ZXMuc3VidHJhY3QoQmlnSW50ZWdlci52YWx1ZU9mKDYwKSk7Ci0gICAgICAgICAgICBob3VycyA9IEJpZ0ludGVnZXIudmFsdWVPZigobG9uZykgZ2V0SG91cnMoKSkuYWRkKEJpZ0ludGVnZXIuT05FKTsKLSAgICAgICAgfQotCi0gICAgICAgIHdoaWxlIChnZXRIb3VycygpID49IDI0KQotICAgICAgICB7Ci0gICAgICAgICAgICBob3VycyA9IGhvdXJzLnN1YnRyYWN0KEJpZ0ludGVnZXIudmFsdWVPZigyNCkpOwotICAgICAgICAgICAgZGF5cyA9IEJpZ0ludGVnZXIudmFsdWVPZigobG9uZykgZ2V0RGF5cygpKS5hZGQoQmlnSW50ZWdlci5PTkUpOwotICAgICAgICB9Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9qYXhwL2RhdGF0eXBlL0R1cmF0aW9uSW1wbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvamF4cC9kYXRhdHlwZS9EdXJhdGlvbkltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNGU0ZjdkNC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9qYXhwL2RhdGF0eXBlL0R1cmF0aW9uSW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjAyMCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmpheHAuZGF0YXR5cGU7Ci0KLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotaW1wb3J0IGphdmEuaW8uT2JqZWN0U3RyZWFtRXhjZXB0aW9uOwotaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOwotaW1wb3J0IGphdmEubWF0aC5CaWdEZWNpbWFsOwotaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOwotaW1wb3J0IGphdmEudXRpbC5DYWxlbmRhcjsKLWltcG9ydCBqYXZhLnV0aWwuRGF0ZTsKLWltcG9ydCBqYXZhLnV0aWwuR3JlZ29yaWFuQ2FsZW5kYXI7Ci1pbXBvcnQgamF2YS51dGlsLlRpbWVab25lOwotCi1pbXBvcnQgamF2YXgueG1sLmRhdGF0eXBlLkRhdGF0eXBlQ29uc3RhbnRzOwotaW1wb3J0IGphdmF4LnhtbC5kYXRhdHlwZS5EdXJhdGlvbjsKLWltcG9ydCBqYXZheC54bWwuZGF0YXR5cGUuWE1MR3JlZ29yaWFuQ2FsZW5kYXI7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuRGF0YXR5cGVNZXNzYWdlRm9ybWF0dGVyOwotCi0vKioKLSAqIDxwPkltbXV0YWJsZSByZXByZXNlbnRhdGlvbiBvZiBhIHRpbWUgc3BhbiBhcyBkZWZpbmVkIGluCi0gKiB0aGUgVzNDIFhNTCBTY2hlbWEgMS4wIHNwZWNpZmljYXRpb24uPC9wPgotICoKLSAqIDxwPkEgRHVyYXRpb24gb2JqZWN0IHJlcHJlc2VudHMgYSBwZXJpb2Qgb2YgR3JlZ29yaWFuIHRpbWUsCi0gKiB3aGljaCBjb25zaXN0cyBvZiBzaXggZmllbGRzICh5ZWFycywgbW9udGhzLCBkYXlzLCBob3VycywKLSAqIG1pbnV0ZXMsIGFuZCBzZWNvbmRzKSBwbHVzIGEgc2lnbiAoKy8tKSBmaWVsZC48L3A+Ci0gKgotICogPHA+VGhlIGZpcnN0IGZpdmUgZmllbGRzIGhhdmUgbm9uLW5lZ2F0aXZlICg+PTApIGludGVnZXJzIG9yIG51bGwKLSAqICh3aGljaCByZXByZXNlbnRzIHRoYXQgdGhlIGZpZWxkIGlzIG5vdCBzZXQpLAotICogYW5kIHRoZSBzZWNvbmRzIGZpZWxkIGhhcyBhIG5vbi1uZWdhdGl2ZSBkZWNpbWFsIG9yIG51bGwuCi0gKiBBIG5lZ2F0aXZlIHNpZ24gaW5kaWNhdGVzIGEgbmVnYXRpdmUgZHVyYXRpb24uPC9wPgotICoKLSAqIDxwPlRoaXMgY2xhc3MgcHJvdmlkZXMgYSBudW1iZXIgb2YgbWV0aG9kcyB0aGF0IG1ha2UgaXQgZWFzeQotICogdG8gdXNlIGZvciB0aGUgZHVyYXRpb24gZGF0YXR5cGUgb2YgWE1MIFNjaGVtYSAxLjAgd2l0aAotICogdGhlIGVycmF0YS48L3A+Ci0gKgotICogPGgyPk9yZGVyIHJlbGF0aW9uc2hpcDwvaDI+Ci0gKiA8cD5EdXJhdGlvbiBvYmplY3RzIG9ubHkgaGF2ZSBwYXJ0aWFsIG9yZGVyLCB3aGVyZSB0d28gdmFsdWVzIEEgYW5kIEIKLSAqIG1heWJlIGVpdGhlcjo8L3A+Ci0gKiA8b2w+Ci0gKiAgPGxpPkEmbHQ7QiAoQSBpcyBzaG9ydGVyIHRoYW4gQikKLSAqICA8bGk+QSZndDtCIChBIGlzIGxvbmdlciB0aGFuIEIpCi0gKiAgPGxpPkE9PUIgICAoQSBhbmQgQiBhcmUgb2YgdGhlIHNhbWUgZHVyYXRpb24pCi0gKiAgPGxpPkEmbHQ7PkIgKENvbXBhcmlzb24gYmV0d2VlbiBBIGFuZCBCIGlzIGluZGV0ZXJtaW5hdGUpCi0gKiA8L29sPgotICogPHA+Rm9yIGV4YW1wbGUsIDMwIGRheXMgY2Fubm90IGJlIG1lYW5pbmdmdWxseSBjb21wYXJlZCB0byBvbmUgbW9udGguCi0gKiBUaGUge0BsaW5rICNjb21wYXJlKER1cmF0aW9uKX0gbWV0aG9kIGltcGxlbWVudHMgdGhpcwotICogcmVsYXRpb25zaGlwLjwvcD4KLSAqCi0gKiA8cD5TZWUgdGhlIHtAbGluayAjaXNMb25nZXJUaGFuKER1cmF0aW9uKX0gbWV0aG9kIGZvciBkZXRhaWxzIGFib3V0Ci0gKiB0aGUgb3JkZXIgcmVsYXRpb25zaGlwIGFtb25nIHtAbGluayBEdXJhdGlvbn0gb2JqZWN0cy48L3A+Ci0gKgotICoKLSAqCi0gKiA8aDI+T3BlcmF0aW9ucyBvdmVyIER1cmF0aW9uPC9oMj4KLSAqIDxwPlRoaXMgY2xhc3MgcHJvdmlkZXMgYSBzZXQgb2YgYmFzaWMgYXJpdGhtZXRpYyBvcGVyYXRpb25zLCBzdWNoCi0gKiBhcyBhZGRpdGlvbiwgc3VidHJhY3Rpb24gYW5kIG11bHRpcGxpY2F0aW9uLgotICogQmVjYXVzZSBkdXJhdGlvbnMgZG9uJ3QgaGF2ZSB0b3RhbCBvcmRlciwgYW4gb3BlcmF0aW9uIGNvdWxkCi0gKiBmYWlsIGZvciBzb21lIGNvbWJpbmF0aW9ucyBvZiBvcGVyYXRpb25zLiBGb3IgZXhhbXBsZSwgeW91IGNhbm5vdAotICogc3VidHJhY3QgMTUgZGF5cyBmcm9tIDEgbW9udGguIFNlZSB0aGUgamF2YWRvYyBvZiB0aG9zZSBtZXRob2RzCi0gKiBmb3IgZGV0YWlsZWQgY29uZGl0aW9ucyB3aGVyZSB0aGlzIGNvdWxkIGhhcHBlbi48L3A+Ci0gKgotICogPHA+QWxzbywgZGl2aXNpb24gb2YgYSBkdXJhdGlvbiBieSBhIG51bWJlciBpcyBub3QgcHJvdmlkZWQgYmVjYXVzZQotICogdGhlIHtAbGluayBEdXJhdGlvbn0gY2xhc3MgY2FuIG9ubHkgZGVhbCB3aXRoIGZpbml0ZSBwcmVjaXNpb24KLSAqIGRlY2ltYWwgbnVtYmVycy4gRm9yIGV4YW1wbGUsIG9uZSBjYW5ub3QgcmVwcmVzZW50IDEgc2VjIGRpdmlkZWQgYnkgMy48L3A+Ci0gKgotICogPHA+SG93ZXZlciwgeW91IGNvdWxkIHN1YnN0aXR1dGUgYSBkaXZpc2lvbiBieSAzIHdpdGggbXVsdGlwbHlpbmcKLSAqIGJ5IG51bWJlcnMgc3VjaCBhcyAwLjMgb3IgMC4zMzMuPC9wPgotICoKLSAqCi0gKgotICogPGgyPlJhbmdlIG9mIGFsbG93ZWQgdmFsdWVzPC9oMj4KLSAqIDxwPgotICogQmVjYXVzZSBzb21lIG9wZXJhdGlvbnMgb2Yge0BsaW5rIER1cmF0aW9ufSByZWx5IG9uIHtAbGluayBDYWxlbmRhcn0KLSAqIGV2ZW4gdGhvdWdoIHtAbGluayBEdXJhdGlvbn0gY2FuIGhvbGQgdmVyeSBsYXJnZSBvciB2ZXJ5IHNtYWxsIHZhbHVlcywKLSAqIHNvbWUgb2YgdGhlIG1ldGhvZHMgbWF5IG5vdCB3b3JrIGNvcnJlY3RseSBvbiBzdWNoIHtAbGluayBEdXJhdGlvbn1zLgotICogVGhlIGltcGFjdGVkIG1ldGhvZHMgZG9jdW1lbnQgdGhlaXIgZGVwZW5kZW5jeSBvbiB7QGxpbmsgQ2FsZW5kYXJ9LgotICoKLSAqCi0gKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzpLb2hzdWtlLkthd2FndWNoaUBTdW4uY29tIj5Lb2hzdWtlIEthd2FndWNoaTwvYT4KLSAqIEBhdXRob3IgPGEgaHJlZj0ibWFpbHRvOkpvc2VwaC5GaWFsbGlAU3VuLmNvbSI+Sm9zZXBoIEZpYWxsaTwvYT4KLSAqIEB2ZXJzaW9uICRSZXZpc2lvbjogMS44ICQsICREYXRlOiAyMDEwLzA1LzE5IDIzOjIwOjA2ICQKLQotICogQHNlZSBYTUxHcmVnb3JpYW5DYWxlbmRhciNhZGQoRHVyYXRpb24pCi0gKi8KLWNsYXNzIER1cmF0aW9uSW1wbAotICAgICAgICBleHRlbmRzIER1cmF0aW9uCi0gICAgICAgIGltcGxlbWVudHMgU2VyaWFsaXphYmxlIHsKLQotICAgIC8qKgotICAgICAqIDxwPk51bWJlciBvZiBGaWVsZHMuPC9wPgotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBGSUVMRF9OVU0gPSA2OwotCi0gICAgLyoqCi0gICAgICogPHA+SW50ZXJuYWwgYXJyYXkgb2YgdmFsdWUgRmllbGRzLjwvcD4KLSAgICAgKi8KLSAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRGF0YXR5cGVDb25zdGFudHMuRmllbGRbXSBGSUVMRFMgPSBuZXcgRGF0YXR5cGVDb25zdGFudHMuRmllbGRbXXsKLSAgICAgICAgICAgICAgICAgICAgICAgIERhdGF0eXBlQ29uc3RhbnRzLllFQVJTLAotICAgICAgICAgICAgICAgICAgICAgICAgRGF0YXR5cGVDb25zdGFudHMuTU9OVEhTLAotICAgICAgICAgICAgICAgICAgICAgICAgRGF0YXR5cGVDb25zdGFudHMuREFZUywKLSAgICAgICAgICAgICAgICAgICAgICAgIERhdGF0eXBlQ29uc3RhbnRzLkhPVVJTLAotICAgICAgICAgICAgICAgICAgICAgICAgRGF0YXR5cGVDb25zdGFudHMuTUlOVVRFUywKLSAgICAgICAgICAgICAgICAgICAgICAgIERhdGF0eXBlQ29uc3RhbnRzLlNFQ09ORFMKLSAgICAgICAgICAgICAgICB9OwotCi0gICAgICAgICAgICAgICAgLyoqCi0gICAgICAgICAgICAgICAgICogPHA+SW50ZXJuYWwgYXJyYXkgb2YgdmFsdWUgRmllbGQgaWRzLjwvcD4KLSAgICAgICAgICAgICAgICAgKi8KLSAgICAgICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnRbXSBGSUVMRF9JRFMgPSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERhdGF0eXBlQ29uc3RhbnRzLllFQVJTLmdldElkKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERhdGF0eXBlQ29uc3RhbnRzLk1PTlRIUy5nZXRJZCgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEYXRhdHlwZUNvbnN0YW50cy5EQVlTLmdldElkKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERhdGF0eXBlQ29uc3RhbnRzLkhPVVJTLmdldElkKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERhdGF0eXBlQ29uc3RhbnRzLk1JTlVURVMuZ2V0SWQoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGF0YXR5cGVDb25zdGFudHMuU0VDT05EUy5nZXRJZCgpCi0gICAgICAgICAgICAgICAgICAgICAgICB9OwotCi0gICAgLyoqCi0gICAgICogVGltZVpvbmUgZm9yIEdNVC4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBUaW1lWm9uZSBHTVQgPSBUaW1lWm9uZS5nZXRUaW1lWm9uZSgiR01UIik7Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIDxwPkJpZ0RlY2ltYWwgdmFsdWUgb2YgMC48L3A+Ci0gICAgICAgICAqLwotICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBCaWdEZWNpbWFsIFpFUk8gPSBCaWdEZWNpbWFsLnZhbHVlT2YoKGxvbmcpIDApOwotCi0gICAgLyoqCi0gICAgICogPHA+SW5kaWNhdGVzIHRoZSBzaWduLiAtMSwgMCBvciAxIGlmIHRoZSBkdXJhdGlvbiBpcyBuZWdhdGl2ZSwKLSAgICAgKiB6ZXJvLCBvciBwb3NpdGl2ZS48L3A+Ci0gICAgICovCi0gICAgcHJvdGVjdGVkIGludCBzaWdudW07Ci0KLSAgICAvKioKLSAgICAgKiA8cD5ZZWFycyBvZiB0aGlzIDxjb2RlPkR1cmF0aW9uPC9jb2RlPi48L3A+Ci0gICAgICovCi0gICAgLyoqCi0gICAgICogVGhlc2Ugd2VyZSBmaW5hbCBzaW5jZSBEdXJhdGlvbiBpcyBpbW11dGFibGUuIEJ1dCBuZXcgc3ViY2xhc3NlcyBuZWVkCi0gICAgICogdG8gYmUgYWJsZSB0byBzZXQgYWZ0ZXIgY29udmVyc2lvbi4gSXQgd29uJ3QgYnJlYWsgdGhlIGltbXV0YWJsZSBuYXR1cmUKLSAgICAgKiBvZiB0aGVtIHNpbmNlIHRoZXJlJ3Mgbm8gb3RoZXIgd2F5IHRvIHNldCBuZXcgdmFsdWVzIHRvIHRoZW0KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgQmlnSW50ZWdlciB5ZWFyczsKLQotICAgIC8qKgotICAgICAqIDxwPk1vbnRocyBvZiB0aGlzIDxjb2RlPkR1cmF0aW9uPC9jb2RlPi48L3A+Ci0gICAgICovCi0gICAgcHJvdGVjdGVkIEJpZ0ludGVnZXIgbW9udGhzOwotCi0gICAgLyoqCi0gICAgICogPHA+RGF5cyBvZiB0aGlzIDxjb2RlPkR1cmF0aW9uPC9jb2RlPi48L3A+Ci0gICAgICovCi0gICAgcHJvdGVjdGVkIEJpZ0ludGVnZXIgZGF5czsKLQotICAgIC8qKgotICAgICAqIDxwPkhvdXJzIG9mIHRoaXMgPGNvZGU+RHVyYXRpb248L2NvZGU+LjwvcD4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgQmlnSW50ZWdlciBob3VyczsKLQotICAgIC8qKgotICAgICAqIDxwPk1pbnV0ZXMgb2YgdGhpcyA8Y29kZT5EdXJhdGlvbjwvY29kZT4uPC9wPgotICAgICAqLwotICAgIHByb3RlY3RlZCBCaWdJbnRlZ2VyIG1pbnV0ZXM7Ci0KLSAgICAvKioKLSAgICAgKiA8cD5TZWNvbmRzIG9mIHRoaXMgPGNvZGU+RHVyYXRpb248L2NvZGU+LjwvcD4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgQmlnRGVjaW1hbCBzZWNvbmRzOwotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBSZXR1cm5zIHRoZSBzaWduIG9mIHRoaXMgZHVyYXRpb24gaW4gLTEsMCwgb3IgMS4KLSAgICAgICAgICoKLSAgICAgICAgICogQHJldHVybgotICAgICAgICAgKiAgICAgIC0xIGlmIHRoaXMgZHVyYXRpb24gaXMgbmVnYXRpdmUsIDAgaWYgdGhlIGR1cmF0aW9uIGlzIHplcm8sCi0gICAgICAgICAqICAgICAgYW5kIDEgaWYgdGhlIGR1cmF0aW9uIGlzIHBvc3RpdmUuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgaW50IGdldFNpZ24oKSB7Ci0KLSAgICAgICAgICAgICAgICByZXR1cm4gc2lnbnVtOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFRPRE86IEphdmFkb2MKLSAgICAgICAgICogQHBhcmFtIGlzUG9zaXRpdmUgU2lnbi4KLSAgICAgICAgICoKLSAgICAgICAgICogQHJldHVybiAxIGlmIHBvc2l0aXZlLCBlbHNlIC0xLgotICAgICAgICAgKi8KLSAgICBwcm90ZWN0ZWQgaW50IGNhbGNTaWdudW0oYm9vbGVhbiBpc1Bvc2l0aXZlKSB7Ci0gICAgICAgIGlmICgoeWVhcnMgPT0gbnVsbCB8fCB5ZWFycy5zaWdudW0oKSA9PSAwKQotICAgICAgICAgICAgJiYgKG1vbnRocyA9PSBudWxsIHx8IG1vbnRocy5zaWdudW0oKSA9PSAwKQotICAgICAgICAgICAgJiYgKGRheXMgPT0gbnVsbCB8fCBkYXlzLnNpZ251bSgpID09IDApCi0gICAgICAgICAgICAmJiAoaG91cnMgPT0gbnVsbCB8fCBob3Vycy5zaWdudW0oKSA9PSAwKQotICAgICAgICAgICAgJiYgKG1pbnV0ZXMgPT0gbnVsbCB8fCBtaW51dGVzLnNpZ251bSgpID09IDApCi0gICAgICAgICAgICAmJiAoc2Vjb25kcyA9PSBudWxsIHx8IHNlY29uZHMuc2lnbnVtKCkgPT0gMCkpIHsKLSAgICAgICAgICAgIHJldHVybiAwOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAoaXNQb3NpdGl2ZSkgewotICAgICAgICAgICAgICAgIHJldHVybiAxOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gLTE7Ci0gICAgICAgICAgICB9Ci0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5Db25zdHJ1Y3RzIGEgbmV3IER1cmF0aW9uIG9iamVjdCBieSBzcGVjaWZ5aW5nIGVhY2ggZmllbGQgaW5kaXZpZHVhbGx5LjwvcD4KLSAgICAgKgotICAgICAqIDxwPkFsbCB0aGUgcGFyYW1ldGVycyBhcmUgb3B0aW9uYWwgYXMgbG9uZyBhcyBhdCBsZWFzdCBvbmUgZmllbGQgaXMgcHJlc2VudC4KLSAgICAgKiBJZiBzcGVjaWZpZWQsIHBhcmFtZXRlcnMgaGF2ZSB0byBiZSB6ZXJvIG9yIHBvc2l0aXZlLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBpc1Bvc2l0aXZlIFNldCB0byA8Y29kZT5mYWxzZTwvY29kZT4gdG8gY3JlYXRlIGEgbmVnYXRpdmUgZHVyYXRpb24uIFdoZW4gdGhlIGxlbmd0aAotICAgICAqICAgb2YgdGhlIGR1cmF0aW9uIGlzIHplcm8sIHRoaXMgcGFyYW1ldGVyIHdpbGwgYmUgaWdub3JlZC4KLSAgICAgKiBAcGFyYW0geWVhcnMgb2YgdGhpcyA8Y29kZT5EdXJhdGlvbjwvY29kZT4KLSAgICAgKiBAcGFyYW0gbW9udGhzIG9mIHRoaXMgPGNvZGU+RHVyYXRpb248L2NvZGU+Ci0gICAgICogQHBhcmFtIGRheXMgb2YgdGhpcyA8Y29kZT5EdXJhdGlvbjwvY29kZT4KLSAgICAgKiBAcGFyYW0gaG91cnMgb2YgdGhpcyA8Y29kZT5EdXJhdGlvbjwvY29kZT4KLSAgICAgKiBAcGFyYW0gbWludXRlcyBvZiB0aGlzIDxjb2RlPkR1cmF0aW9uPC9jb2RlPgotICAgICAqIEBwYXJhbSBzZWNvbmRzIG9mIHRoaXMgPGNvZGU+RHVyYXRpb248L2NvZGU+Ci0gICAgICoKLSAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgotICAgICAqICAgIElmIHllYXJzLCBtb250aHMsIGRheXMsIGhvdXJzLCBtaW51dGVzIGFuZAotICAgICAqICAgIHNlY29uZHMgcGFyYW1ldGVycyBhcmUgYWxsIDxjb2RlPm51bGw8L2NvZGU+LiBPciBpZiBhbnkKLSAgICAgKiAgICBvZiB0aG9zZSBwYXJhbWV0ZXJzIGFyZSBuZWdhdGl2ZS4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgRHVyYXRpb25JbXBsKAotICAgICAgICBib29sZWFuIGlzUG9zaXRpdmUsCi0gICAgICAgIEJpZ0ludGVnZXIgeWVhcnMsCi0gICAgICAgIEJpZ0ludGVnZXIgbW9udGhzLAotICAgICAgICBCaWdJbnRlZ2VyIGRheXMsCi0gICAgICAgIEJpZ0ludGVnZXIgaG91cnMsCi0gICAgICAgIEJpZ0ludGVnZXIgbWludXRlcywKLSAgICAgICAgQmlnRGVjaW1hbCBzZWNvbmRzKSB7Ci0KLSAgICAgICAgdGhpcy55ZWFycyA9IHllYXJzOwotICAgICAgICB0aGlzLm1vbnRocyA9IG1vbnRoczsKLSAgICAgICAgdGhpcy5kYXlzID0gZGF5czsKLSAgICAgICAgdGhpcy5ob3VycyA9IGhvdXJzOwotICAgICAgICB0aGlzLm1pbnV0ZXMgPSBtaW51dGVzOwotICAgICAgICB0aGlzLnNlY29uZHMgPSBzZWNvbmRzOwotCi0gICAgICAgIHRoaXMuc2lnbnVtID0gY2FsY1NpZ251bShpc1Bvc2l0aXZlKTsKLQotICAgICAgICAvLyBzYW5pdHkgY2hlY2sKLSAgICAgICAgaWYgKHllYXJzID09IG51bGwKLSAgICAgICAgICAgICYmIG1vbnRocyA9PSBudWxsCi0gICAgICAgICAgICAmJiBkYXlzID09IG51bGwKLSAgICAgICAgICAgICYmIGhvdXJzID09IG51bGwKLSAgICAgICAgICAgICYmIG1pbnV0ZXMgPT0gbnVsbAotICAgICAgICAgICAgJiYgc2Vjb25kcyA9PSBudWxsKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAotICAgICAgICAgICAgLy8iYWxsIHRoZSBmaWVsZHMgYXJlIG51bGwiCi0gICAgICAgICAgICBEYXRhdHlwZU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShudWxsLCAiQWxsRmllbGRzTnVsbCIsIG51bGwpCi0gICAgICAgICAgICApOwotICAgICAgICB9Ci0gICAgICAgIHRlc3ROb25OZWdhdGl2ZSh5ZWFycywgRGF0YXR5cGVDb25zdGFudHMuWUVBUlMpOwotICAgICAgICB0ZXN0Tm9uTmVnYXRpdmUobW9udGhzLCBEYXRhdHlwZUNvbnN0YW50cy5NT05USFMpOwotICAgICAgICB0ZXN0Tm9uTmVnYXRpdmUoZGF5cywgRGF0YXR5cGVDb25zdGFudHMuREFZUyk7Ci0gICAgICAgIHRlc3ROb25OZWdhdGl2ZShob3VycywgRGF0YXR5cGVDb25zdGFudHMuSE9VUlMpOwotICAgICAgICB0ZXN0Tm9uTmVnYXRpdmUobWludXRlcywgRGF0YXR5cGVDb25zdGFudHMuTUlOVVRFUyk7Ci0gICAgICAgIHRlc3ROb25OZWdhdGl2ZShzZWNvbmRzLCBEYXRhdHlwZUNvbnN0YW50cy5TRUNPTkRTKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5NYWtlcyBzdXJlIHRoYXQgdGhlIGdpdmVuIG51bWJlciBpcyBub24tbmVnYXRpdmUuIElmIGl0IGlzIG5vdCwKLSAgICAgKiB0aHJvdyB7QGxpbmsgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9ufS48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gbiBOdW1iZXIgdG8gdGVzdC4KLSAgICAgKiBAcGFyYW0gZiBGaWVsZCB0byB0ZXN0LgotICAgICAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgdm9pZCB0ZXN0Tm9uTmVnYXRpdmUoQmlnSW50ZWdlciBuLCBEYXRhdHlwZUNvbnN0YW50cy5GaWVsZCBmKSB7Ci0gICAgICAgIGlmIChuICE9IG51bGwgJiYgbi5zaWdudW0oKSA8IDApIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgRGF0YXR5cGVNZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UobnVsbCwgIk5lZ2F0aXZlRmllbGQiLCBuZXcgT2JqZWN0W117Zi50b1N0cmluZygpfSkKLSAgICAgICAgICAgICk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5NYWtlcyBzdXJlIHRoYXQgdGhlIGdpdmVuIG51bWJlciBpcyBub24tbmVnYXRpdmUuIElmIGl0IGlzIG5vdCwKLSAgICAgKiB0aHJvdyB7QGxpbmsgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9ufS48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gbiBOdW1iZXIgdG8gdGVzdC4KLSAgICAgKiBAcGFyYW0gZiBGaWVsZCB0byB0ZXN0LgotICAgICAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgdm9pZCB0ZXN0Tm9uTmVnYXRpdmUoQmlnRGVjaW1hbCBuLCBEYXRhdHlwZUNvbnN0YW50cy5GaWVsZCBmKSB7Ci0gICAgICAgIGlmIChuICE9IG51bGwgJiYgbi5zaWdudW0oKSA8IDApIHsKLQotICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICBEYXRhdHlwZU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShudWxsLCAiTmVnYXRpdmVGaWVsZCIsIG5ldyBPYmplY3RbXXtmLnRvU3RyaW5nKCl9KQotICAgICAgICAgICAgKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPkNvbnN0cnVjdHMgYSBuZXcgRHVyYXRpb24gb2JqZWN0IGJ5IHNwZWNpZnlpbmcgZWFjaCBmaWVsZAotICAgICAqIGluZGl2aWR1YWxseS48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5UaGlzIG1ldGhvZCBpcyBmdW5jdGlvbmFsbHkgZXF1aXZhbGVudCB0bwotICAgICAqIGludm9raW5nIGFub3RoZXIgY29uc3RydWN0b3IgYnkgd3JhcHBpbmcKLSAgICAgKiBhbGwgbm9uLXplcm8gcGFyYW1ldGVycyBpbnRvIHtAbGluayBCaWdJbnRlZ2VyfSBhbmQge0BsaW5rIEJpZ0RlY2ltYWx9LgotICAgICAqIFplcm8gdmFsdWUgb2YgaW50IHBhcmFtZXRlciBpcyBlcXVpdmFsZW50IG9mIG51bGwgdmFsdWUgb2YKLSAgICAgKiB0aGUgY29ycmVzcG9uZGluZyBmaWVsZC48L3A+Ci0gICAgICoKLSAgICAgKiBAc2VlICNEdXJhdGlvbkltcGwoYm9vbGVhbiwgQmlnSW50ZWdlciwgQmlnSW50ZWdlciwgQmlnSW50ZWdlciwgQmlnSW50ZWdlciwKLSAgICAgKiAgIEJpZ0ludGVnZXIsIEJpZ0RlY2ltYWwpCi0gICAgICovCi0gICAgcHJvdGVjdGVkIER1cmF0aW9uSW1wbCgKLSAgICAgICAgZmluYWwgYm9vbGVhbiBpc1Bvc2l0aXZlLAotICAgICAgICBmaW5hbCBpbnQgeWVhcnMsCi0gICAgICAgIGZpbmFsIGludCBtb250aHMsCi0gICAgICAgIGZpbmFsIGludCBkYXlzLAotICAgICAgICBmaW5hbCBpbnQgaG91cnMsCi0gICAgICAgIGZpbmFsIGludCBtaW51dGVzLAotICAgICAgICBmaW5hbCBpbnQgc2Vjb25kcykgewotICAgICAgICB0aGlzKAotICAgICAgICAgICAgaXNQb3NpdGl2ZSwKLSAgICAgICAgICAgIHdyYXAoeWVhcnMpLAotICAgICAgICAgICAgd3JhcChtb250aHMpLAotICAgICAgICAgICAgd3JhcChkYXlzKSwKLSAgICAgICAgICAgIHdyYXAoaG91cnMpLAotICAgICAgICAgICAgd3JhcChtaW51dGVzKSwKLSAgICAgICAgICAgIHNlY29uZHMgIT0gRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVEID8gbmV3IEJpZ0RlY2ltYWwoU3RyaW5nLnZhbHVlT2Yoc2Vjb25kcykpIDogbnVsbCk7Ci0gICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBUT0RPOiBKYXZhZG9jCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBpIGludCB0byBjb252ZXJ0IHRvIEJpZ0ludGVnZXIuCi0gICAgICAgICAqCi0gICAgICAgICAqIEByZXR1cm4gQmlnSW50ZWdlciByZXByZXNlbnRhdGlvbiBvZiBpbnQuCi0gICAgICAgICAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgQmlnSW50ZWdlciB3cmFwKGZpbmFsIGludCBpKSB7Ci0KLSAgICAgICAgLy8gZmllbGQgbWF5IG5vdCBiZSBzZXQKLSAgICAgICAgaWYgKGkgPT0gRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVEKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBpbnQgLT4gQmlnSW50ZWdlcgotICAgICAgICByZXR1cm4gbmV3IEJpZ0ludGVnZXIoU3RyaW5nLnZhbHVlT2YoaSkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPkNvbnN0cnVjdHMgYSBuZXcgRHVyYXRpb24gb2JqZWN0IGJ5IHNwZWNpZnlpbmcgdGhlIGR1cmF0aW9uCi0gICAgICogaW4gbWlsbGlzZWNvbmRzLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBkdXJhdGlvbkluTWlsbGlTZWNvbmRzCi0gICAgICogICAgICBUaGUgbGVuZ3RoIG9mIHRoZSBkdXJhdGlvbiBpbiBtaWxsaXNlY29uZHMuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIER1cmF0aW9uSW1wbChmaW5hbCBsb25nIGR1cmF0aW9uSW5NaWxsaVNlY29uZHMpIHsKLQotICAgICAgICBsb25nIGwgPSBkdXJhdGlvbkluTWlsbGlTZWNvbmRzOwotCi0gICAgICAgIGlmIChsID4gMCkgewotICAgICAgICAgICAgc2lnbnVtID0gMTsKLSAgICAgICAgfSBlbHNlIGlmIChsIDwgMCkgewotICAgICAgICAgICAgc2lnbnVtID0gLTE7Ci0gICAgICAgICAgICBpZiAobCA9PSAweDgwMDAwMDAwMDAwMDAwMDBMKSB7Ci0gICAgICAgICAgICAgICAgLy8gbmVnYXRpbmcgMHg4MDAwMDAwMDAwMDAwMDAwTCBjYXVzZXMgYW4gb3ZlcmZsb3cKLSAgICAgICAgICAgICAgICBsKys7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBsICo9IC0xOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgc2lnbnVtID0gMDsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIGxldCBHcmVnb3JpYW5DYWxlbmRhciBkbyB0aGUgaGVhdnkgbGlmdGluZwotICAgICAgICBHcmVnb3JpYW5DYWxlbmRhciBncmVnb3JpYW5DYWxlbmRhciA9IG5ldyBHcmVnb3JpYW5DYWxlbmRhcihHTVQpOwotCi0gICAgICAgIC8vIGR1cmF0aW9uIGlzIHRoZSBvZmZzZXQgZnJvbSB0aGUgRXBvY2gKLSAgICAgICAgZ3JlZ29yaWFuQ2FsZW5kYXIuc2V0VGltZUluTWlsbGlzKGwpOwotCi0gICAgICAgIC8vIG5vdyBmaW5kIG91dCBob3cgbXVjaCBlYWNoIGZpZWxkIGhhcyBjaGFuZ2VkCi0gICAgICAgIGxvbmcgaW50MmxvbmcgPSAwTDsKLQotICAgICAgICAvLyB5ZWFycwotICAgICAgICBpbnQybG9uZyA9IGdyZWdvcmlhbkNhbGVuZGFyLmdldChDYWxlbmRhci5ZRUFSKSAtIDE5NzA7Ci0gICAgICAgIHRoaXMueWVhcnMgPSBCaWdJbnRlZ2VyLnZhbHVlT2YoaW50MmxvbmcpOwotCi0gICAgICAgIC8vIG1vbnRocwotICAgICAgICBpbnQybG9uZyA9IGdyZWdvcmlhbkNhbGVuZGFyLmdldChDYWxlbmRhci5NT05USCk7Ci0gICAgICAgIHRoaXMubW9udGhzID0gQmlnSW50ZWdlci52YWx1ZU9mKGludDJsb25nKTsKLQotICAgICAgICAvLyBkYXlzCi0gICAgICAgIGludDJsb25nID0gZ3JlZ29yaWFuQ2FsZW5kYXIuZ2V0KENhbGVuZGFyLkRBWV9PRl9NT05USCkgLSAxOwotICAgICAgICB0aGlzLmRheXMgPSBCaWdJbnRlZ2VyLnZhbHVlT2YoaW50MmxvbmcpOwotCi0gICAgICAgIC8vIGhvdXJzCi0gICAgICAgIGludDJsb25nID0gZ3JlZ29yaWFuQ2FsZW5kYXIuZ2V0KENhbGVuZGFyLkhPVVJfT0ZfREFZKTsKLSAgICAgICAgdGhpcy5ob3VycyA9IEJpZ0ludGVnZXIudmFsdWVPZihpbnQybG9uZyk7Ci0KLSAgICAgICAgLy8gbWludXRlcwotICAgICAgICBpbnQybG9uZyA9IGdyZWdvcmlhbkNhbGVuZGFyLmdldChDYWxlbmRhci5NSU5VVEUpOwotICAgICAgICB0aGlzLm1pbnV0ZXMgPSBCaWdJbnRlZ2VyLnZhbHVlT2YoaW50MmxvbmcpOwotCi0gICAgICAgIC8vIHNlY29uZHMgJiBtaWxsaXNlY29uZHMKLSAgICAgICAgaW50MmxvbmcgPSAoZ3JlZ29yaWFuQ2FsZW5kYXIuZ2V0KENhbGVuZGFyLlNFQ09ORCkgKiAxMDAwKQotICAgICAgICAgICAgICAgICAgICArIGdyZWdvcmlhbkNhbGVuZGFyLmdldChDYWxlbmRhci5NSUxMSVNFQ09ORCk7Ci0gICAgICAgIHRoaXMuc2Vjb25kcyA9IEJpZ0RlY2ltYWwudmFsdWVPZihpbnQybG9uZywgMyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0cyBhIG5ldyBEdXJhdGlvbiBvYmplY3QgYnkKLSAgICAgKiBwYXJzaW5nIGl0cyBzdHJpbmcgcmVwcmVzZW50YXRpb24KLSAgICAgKiAiUG5Zbk1uRFRuSG5NblMiIGFzIGRlZmluZWQgaW4gWE1MIFNjaGVtYSAxLjAgc2VjdGlvbiAzLjIuNi4xLgotICAgICAqCi0gICAgICogPHA+Ci0gICAgICogVGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBtYXkgbm90IGhhdmUgYW55IGxlYWRpbmcKLSAgICAgKiBhbmQgdHJhaWxpbmcgd2hpdGVzcGFjZXMuCi0gICAgICoKLSAgICAgKiA8cD4KLSAgICAgKiBGb3IgZXhhbXBsZSwgdGhpcyBtZXRob2QgcGFyc2VzIHN0cmluZ3MgbGlrZQotICAgICAqICJQMUQiICgxIGRheSksICItUFQxMDBTIiAoLTEwMCBzZWMuKSwgIlAxRFQxMkgiICgxIGRheXMgYW5kIDEyIGhvdXJzKS4KLSAgICAgKgotICAgICAqIDxwPgotICAgICAqIFRoZSBwYXJzaW5nIGlzIGRvbmUgZmllbGQgYnkgZmllbGQgc28gdGhhdAotICAgICAqIHRoZSBmb2xsb3dpbmcgaG9sZHMgZm9yIGFueSBsZXhpY2FsbHkgY29ycmVjdCBzdHJpbmcgeDoKLSAgICAgKiA8cHJlPgotICAgICAqIG5ldyBEdXJhdGlvbih4KS50b1N0cmluZygpLmVxdWFscyh4KQotICAgICAqIDwvcHJlPgotICAgICAqCi0gICAgICogUmV0dXJucyBhIG5vbi1udWxsIHZhbGlkIGR1cmF0aW9uIG9iamVjdCB0aGF0IGhvbGRzIHRoZSB2YWx1ZQotICAgICAqIGluZGljYXRlZCBieSB0aGUgbGV4aWNhbFJlcHJlc2VudGF0aW9uIHBhcmFtZXRlci4KLSAgICAgKgotICAgICAqIEBwYXJhbSBsZXhpY2FsUmVwcmVzZW50YXRpb24KLSAgICAgKiAgICAgIExleGljYWwgcmVwcmVzZW50YXRpb24gb2YgYSBkdXJhdGlvbi4KLSAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgotICAgICAqICAgICAgSWYgdGhlIGdpdmVuIHN0cmluZyBkb2VzIG5vdCBjb25mb3JtIHRvIHRoZSBhZm9yZW1lbnRpb25lZAotICAgICAqICAgICAgc3BlY2lmaWNhdGlvbi4KLSAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCi0gICAgICogICAgICBJZiB0aGUgZ2l2ZW4gc3RyaW5nIGlzIG51bGwuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIER1cmF0aW9uSW1wbChTdHJpbmcgbGV4aWNhbFJlcHJlc2VudGF0aW9uKQotICAgICAgICB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHsKLSAgICAgICAgLy8gb25seSBpZiBJIGNvdWxkIHVzZSB0aGUgSkRLMS40IHJlZ3VsYXIgZXhwcmVzc2lvbiAuLi4uCi0KLSAgICAgICAgZmluYWwgU3RyaW5nIHMgPSBsZXhpY2FsUmVwcmVzZW50YXRpb247Ci0gICAgICAgIGJvb2xlYW4gcG9zaXRpdmU7Ci0gICAgICAgIGludFtdIGlkeCA9IG5ldyBpbnRbMV07Ci0gICAgICAgIGludCBsZW5ndGggPSBzLmxlbmd0aCgpOwotICAgICAgICBib29sZWFuIHRpbWVSZXF1aXJlZCA9IGZhbHNlOwotCi0gICAgICAgIGlmIChsZXhpY2FsUmVwcmVzZW50YXRpb24gPT0gbnVsbCkgewotICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7Ci0gICAgICAgIH0KLQotICAgICAgICBpZHhbMF0gPSAwOwotICAgICAgICBpZiAobGVuZ3RoICE9IGlkeFswXSAmJiBzLmNoYXJBdChpZHhbMF0pID09ICctJykgewotICAgICAgICAgICAgaWR4WzBdKys7Ci0gICAgICAgICAgICBwb3NpdGl2ZSA9IGZhbHNlOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgcG9zaXRpdmUgPSB0cnVlOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKGxlbmd0aCAhPSBpZHhbMF0gJiYgcy5jaGFyQXQoaWR4WzBdKyspICE9ICdQJykgewotICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihzKTsgLy8saWR4WzBdLTEpOwotICAgICAgICB9Ci0KLQotICAgICAgICAvLyBwaGFzZSAxOiBjaG9wIHRoZSBzdHJpbmcgaW50byBjaHVua3MKLSAgICAgICAgLy8gKHdoZXJlIGEgY2h1bmsgaXMgJzxudW1iZXI+PGEgc3ltYm9sPicKLSAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgICAgICBpbnQgZGF0ZUxlbiA9IDA7Ci0gICAgICAgIFN0cmluZ1tdIGRhdGVQYXJ0cyA9IG5ldyBTdHJpbmdbM107Ci0gICAgICAgIGludFtdIGRhdGVQYXJ0c0luZGV4ID0gbmV3IGludFszXTsKLSAgICAgICAgd2hpbGUgKGxlbmd0aCAhPSBpZHhbMF0KLSAgICAgICAgICAgICYmIGlzRGlnaXQocy5jaGFyQXQoaWR4WzBdKSkKLSAgICAgICAgICAgICYmIGRhdGVMZW4gPCAzKSB7Ci0gICAgICAgICAgICBkYXRlUGFydHNJbmRleFtkYXRlTGVuXSA9IGlkeFswXTsKLSAgICAgICAgICAgIGRhdGVQYXJ0c1tkYXRlTGVuKytdID0gcGFyc2VQaWVjZShzLCBpZHgpOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKGxlbmd0aCAhPSBpZHhbMF0pIHsKLSAgICAgICAgICAgIGlmIChzLmNoYXJBdChpZHhbMF0rKykgPT0gJ1QnKSB7Ci0gICAgICAgICAgICAgICAgdGltZVJlcXVpcmVkID0gdHJ1ZTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihzKTsgLy8gLGlkeFswXS0xKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGludCB0aW1lTGVuID0gMDsKLSAgICAgICAgU3RyaW5nW10gdGltZVBhcnRzID0gbmV3IFN0cmluZ1szXTsKLSAgICAgICAgaW50W10gdGltZVBhcnRzSW5kZXggPSBuZXcgaW50WzNdOwotICAgICAgICB3aGlsZSAobGVuZ3RoICE9IGlkeFswXQotICAgICAgICAgICAgJiYgaXNEaWdpdE9yUGVyaW9kKHMuY2hhckF0KGlkeFswXSkpCi0gICAgICAgICAgICAmJiB0aW1lTGVuIDwgMykgewotICAgICAgICAgICAgdGltZVBhcnRzSW5kZXhbdGltZUxlbl0gPSBpZHhbMF07Ci0gICAgICAgICAgICB0aW1lUGFydHNbdGltZUxlbisrXSA9IHBhcnNlUGllY2UocywgaWR4KTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmICh0aW1lUmVxdWlyZWQgJiYgdGltZUxlbiA9PSAwKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKHMpOyAvLyAsaWR4WzBdKTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChsZW5ndGggIT0gaWR4WzBdKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKHMpOyAvLyAsaWR4WzBdKTsKLSAgICAgICAgfQotICAgICAgICBpZiAoZGF0ZUxlbiA9PSAwICYmIHRpbWVMZW4gPT0gMCkgewotICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihzKTsgLy8gLGlkeFswXSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBwaGFzZSAyOiBjaGVjayB0aGUgb3JkZXJpbmcgb2YgY2h1bmtzCi0gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICAgICAgb3JnYW5pemVQYXJ0cyhzLCBkYXRlUGFydHMsIGRhdGVQYXJ0c0luZGV4LCBkYXRlTGVuLCAiWU1EIik7Ci0gICAgICAgIG9yZ2FuaXplUGFydHMocywgdGltZVBhcnRzLCB0aW1lUGFydHNJbmRleCwgdGltZUxlbiwgIkhNUyIpOwotCi0gICAgICAgIC8vIHBhcnNlIGludG8gbnVtYmVycwotICAgICAgICB5ZWFycyA9IHBhcnNlQmlnSW50ZWdlcihzLCBkYXRlUGFydHNbMF0sIGRhdGVQYXJ0c0luZGV4WzBdKTsKLSAgICAgICAgbW9udGhzID0gcGFyc2VCaWdJbnRlZ2VyKHMsIGRhdGVQYXJ0c1sxXSwgZGF0ZVBhcnRzSW5kZXhbMV0pOwotICAgICAgICBkYXlzID0gcGFyc2VCaWdJbnRlZ2VyKHMsIGRhdGVQYXJ0c1syXSwgZGF0ZVBhcnRzSW5kZXhbMl0pOwotICAgICAgICBob3VycyA9IHBhcnNlQmlnSW50ZWdlcihzLCB0aW1lUGFydHNbMF0sIHRpbWVQYXJ0c0luZGV4WzBdKTsKLSAgICAgICAgbWludXRlcyA9IHBhcnNlQmlnSW50ZWdlcihzLCB0aW1lUGFydHNbMV0sIHRpbWVQYXJ0c0luZGV4WzFdKTsKLSAgICAgICAgc2Vjb25kcyA9IHBhcnNlQmlnRGVjaW1hbChzLCB0aW1lUGFydHNbMl0sIHRpbWVQYXJ0c0luZGV4WzJdKTsKLSAgICAgICAgc2lnbnVtID0gY2FsY1NpZ251bShwb3NpdGl2ZSk7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBUT0RPOiBKYXZhZG9jCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY2ggY2hhciB0byB0ZXN0LgotICAgICAqCi0gICAgICogQHJldHVybiB0cnVlIGlmIGNoIGlzIGEgZGlnaXQsIGVsc2UgZmFsc2UuCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBpc0RpZ2l0KGNoYXIgY2gpIHsKLSAgICAgICAgcmV0dXJuICcwJyA8PSBjaCAmJiBjaCA8PSAnOSc7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVE9ETzogSmF2YWRvYwotICAgICAqCi0gICAgICogQHBhcmFtIGNoIHRvIHRlc3QuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRydWUgaWYgY2ggaXMgYSBkaWdpdCBvciBhIHBlcmlvZCwgZWxzZSBmYWxzZS4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGlzRGlnaXRPclBlcmlvZChjaGFyIGNoKSB7Ci0gICAgICAgIHJldHVybiBpc0RpZ2l0KGNoKSB8fCBjaCA9PSAnLic7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVE9ETzogSmF2YWRvYwotICAgICAqCi0gICAgICogQHBhcmFtIHdob2xlIFN0cmluZyB0byBwYXJzZS4KLSAgICAgKiBAcGFyYW0gaWR4IFRPRE86ID8/PwotICAgICAqCi0gICAgICogQHJldHVybiBSZXN1bHQgb2YgcGFyc2luZy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIElmIHdob2xlIGNhbm5vdCBiZSBwYXJzZWQuCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIHBhcnNlUGllY2UoU3RyaW5nIHdob2xlLCBpbnRbXSBpZHgpCi0gICAgICAgIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gewotICAgICAgICBpbnQgc3RhcnQgPSBpZHhbMF07Ci0gICAgICAgIHdoaWxlIChpZHhbMF0gPCB3aG9sZS5sZW5ndGgoKQotICAgICAgICAgICAgJiYgaXNEaWdpdE9yUGVyaW9kKHdob2xlLmNoYXJBdChpZHhbMF0pKSkgewotICAgICAgICAgICAgaWR4WzBdKys7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIGlmIChpZHhbMF0gPT0gd2hvbGUubGVuZ3RoKCkpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24od2hvbGUpOyAvLyAsaWR4WzBdKTsKLSAgICAgICAgfQotCi0gICAgICAgIGlkeFswXSsrOwotCi0gICAgICAgIHJldHVybiB3aG9sZS5zdWJzdHJpbmcoc3RhcnQsIGlkeFswXSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVE9ETzogSmF2YWRvYy4KLSAgICAgKgotICAgICAqIEBwYXJhbSB3aG9sZSBUT0RPOiA/Pz8KLSAgICAgKiBAcGFyYW0gcGFydHMgVE9ETzogPz8/Ci0gICAgICogQHBhcmFtIHBhcnRzSW5kZXggVE9ETzogPz8/Ci0gICAgICogQHBhcmFtIGxlbiBUT0RPOiA/Pz8KLSAgICAgKiBAcGFyYW0gdG9rZW5zIFRPRE86ID8/PwotICAgICAqCi0gICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gVE9ETzogPz8/Ci0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBvcmdhbml6ZVBhcnRzKAotICAgICAgICBTdHJpbmcgd2hvbGUsCi0gICAgICAgIFN0cmluZ1tdIHBhcnRzLAotICAgICAgICBpbnRbXSBwYXJ0c0luZGV4LAotICAgICAgICBpbnQgbGVuLAotICAgICAgICBTdHJpbmcgdG9rZW5zKQotICAgICAgICB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHsKLQotICAgICAgICBpbnQgaWR4ID0gdG9rZW5zLmxlbmd0aCgpOwotICAgICAgICBmb3IgKGludCBpID0gbGVuIC0gMTsgaSA+PSAwOyBpLS0pIHsKLSAgICAgICAgICAgIGludCBuaWR4ID0KLSAgICAgICAgICAgICAgICB0b2tlbnMubGFzdEluZGV4T2YoCi0gICAgICAgICAgICAgICAgICAgIHBhcnRzW2ldLmNoYXJBdChwYXJ0c1tpXS5sZW5ndGgoKSAtIDEpLAotICAgICAgICAgICAgICAgICAgICBpZHggLSAxKTsKLSAgICAgICAgICAgIGlmIChuaWR4ID09IC0xKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbih3aG9sZSk7Ci0gICAgICAgICAgICAgICAgLy8gLHBhcnRzSW5kZXhbaV0rcGFydHNbaV0ubGVuZ3RoKCktMSk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGZvciAoaW50IGogPSBuaWR4ICsgMTsgaiA8IGlkeDsgaisrKSB7Ci0gICAgICAgICAgICAgICAgcGFydHNbal0gPSBudWxsOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWR4ID0gbmlkeDsKLSAgICAgICAgICAgIHBhcnRzW2lkeF0gPSBwYXJ0c1tpXTsKLSAgICAgICAgICAgIHBhcnRzSW5kZXhbaWR4XSA9IHBhcnRzSW5kZXhbaV07Ci0gICAgICAgIH0KLSAgICAgICAgZm9yIChpZHgtLTsgaWR4ID49IDA7IGlkeC0tKSB7Ci0gICAgICAgICAgICBwYXJ0c1tpZHhdID0gbnVsbDsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRPRE86IEphdmFkb2MKLSAgICAgKgotICAgICAqIEBwYXJhbSB3aG9sZSBUT0RPOiA/Pz8uCi0gICAgICogQHBhcmFtIHBhcnQgVE9ETzogPz8/LgotICAgICAqIEBwYXJhbSBpbmRleCBUT0RPOiA/Pz8uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRPRE86ID8/Py4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIFRPRE86ID8/Py4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBCaWdJbnRlZ2VyIHBhcnNlQmlnSW50ZWdlcigKLSAgICAgICAgU3RyaW5nIHdob2xlLAotICAgICAgICBTdHJpbmcgcGFydCwKLSAgICAgICAgaW50IGluZGV4KQotICAgICAgICB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKHBhcnQgPT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLSAgICAgICAgcGFydCA9IHBhcnQuc3Vic3RyaW5nKDAsIHBhcnQubGVuZ3RoKCkgLSAxKTsKLSAgICAgICAgLy8gICAgICAgIHRyeSB7Ci0gICAgICAgIHJldHVybiBuZXcgQmlnSW50ZWdlcihwYXJ0KTsKLSAgICAgICAgLy8gICAgICAgIH0gY2F0Y2goIE51bWJlckZvcm1hdEV4Y2VwdGlvbiBlICkgewotICAgICAgICAvLyAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZUV4Y2VwdGlvbiggd2hvbGUsIGluZGV4ICk7Ci0gICAgICAgIC8vICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVE9ETzogSmF2YWRvYy4KLSAgICAgKgotICAgICAqIEBwYXJhbSB3aG9sZSBUT0RPOiA/Pz8uCi0gICAgICogQHBhcmFtIHBhcnQgVE9ETzogPz8/LgotICAgICAqIEBwYXJhbSBpbmRleCBUT0RPOiA/Pz8uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRPRE86ID8/Py4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIFRPRE86ID8/Py4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBCaWdEZWNpbWFsIHBhcnNlQmlnRGVjaW1hbCgKLSAgICAgICAgU3RyaW5nIHdob2xlLAotICAgICAgICBTdHJpbmcgcGFydCwKLSAgICAgICAgaW50IGluZGV4KQotICAgICAgICB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKHBhcnQgPT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLSAgICAgICAgcGFydCA9IHBhcnQuc3Vic3RyaW5nKDAsIHBhcnQubGVuZ3RoKCkgLSAxKTsKLSAgICAgICAgLy8gTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGlzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgotICAgICAgICAvLyAgICAgICAgdHJ5IHsKLSAgICAgICAgcmV0dXJuIG5ldyBCaWdEZWNpbWFsKHBhcnQpOwotICAgICAgICAvLyAgICAgICAgfSBjYXRjaCggTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGUgKSB7Ci0gICAgICAgIC8vICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlRXhjZXB0aW9uKCB3aG9sZSwgaW5kZXggKTsKLSAgICAgICAgLy8gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5Gb3VyIGNvbnN0YW50cyBkZWZpbmVkIGZvciB0aGUgY29tcGFyaXNvbiBvZiBkdXJhdGlvbnMuPC9wPgotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFhNTEdyZWdvcmlhbkNhbGVuZGFyW10gVEVTVF9QT0lOVFMgPSBuZXcgWE1MR3JlZ29yaWFuQ2FsZW5kYXJbXSB7Ci0gICAgICAgIFhNTEdyZWdvcmlhbkNhbGVuZGFySW1wbC5wYXJzZSgiMTY5Ni0wOS0wMVQwMDowMDowMFoiKSwKLSAgICAgICAgWE1MR3JlZ29yaWFuQ2FsZW5kYXJJbXBsLnBhcnNlKCIxNjk3LTAyLTAxVDAwOjAwOjAwWiIpLAotICAgICAgICBYTUxHcmVnb3JpYW5DYWxlbmRhckltcGwucGFyc2UoIjE5MDMtMDMtMDFUMDA6MDA6MDBaIiksCi0gICAgICAgIFhNTEdyZWdvcmlhbkNhbGVuZGFySW1wbC5wYXJzZSgiMTkwMy0wNy0wMVQwMDowMDowMFoiKQotICAgIH07Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIDxwPlBhcnRpYWwgb3JkZXIgcmVsYXRpb24gY29tcGFyaXNvbiB3aXRoIHRoaXMgPGNvZGU+RHVyYXRpb248L2NvZGU+IGluc3RhbmNlLjwvcD4KLSAgICAgICAgICoKLSAgICAgICAgICogPHA+Q29tcGFyaXNvbiByZXN1bHQgbXVzdCBiZSBpbiBhY2NvcmRhbmNlIHdpdGgKLSAgICAgICAgICogPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveG1sc2NoZW1hLTIvI2R1cmF0aW9uLW9yZGVyIj5XM0MgWE1MIFNjaGVtYSAxLjAgUGFydCAyLCBTZWN0aW9uIDMuMi43LjYuMiwKLSAgICAgICAgICogPGk+T3JkZXIgcmVsYXRpb24gb24gZHVyYXRpb248L2k+PC9hPi48L3A+Ci0gICAgICAgICAqCi0gICAgICAgICAqIDxwPlJldHVybjo8L3A+Ci0gICAgICAgICAqIDx1bD4KLSAgICAgICAgICogICA8bGk+e0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0xFU1NFUn0gaWYgdGhpcyA8Y29kZT5EdXJhdGlvbjwvY29kZT4gaXMgc2hvcnRlciB0aGFuIDxjb2RlPmR1cmF0aW9uPC9jb2RlPiBwYXJhbWV0ZXI8L2xpPgotICAgICAgICAgKiAgIDxsaT57QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjRVFVQUx9IGlmIHRoaXMgPGNvZGU+RHVyYXRpb248L2NvZGU+IGlzIGVxdWFsIHRvIDxjb2RlPmR1cmF0aW9uPC9jb2RlPiBwYXJhbWV0ZXI8L2xpPgotICAgICAgICAgKiAgIDxsaT57QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjR1JFQVRFUn0gaWYgdGhpcyA8Y29kZT5EdXJhdGlvbjwvY29kZT4gaXMgbG9uZ2VyIHRoYW4gPGNvZGU+ZHVyYXRpb248L2NvZGU+IHBhcmFtZXRlcjwvbGk+Ci0gICAgICAgICAqICAgPGxpPntAbGluayBEYXRhdHlwZUNvbnN0YW50cyNJTkRFVEVSTUlOQVRFfSBpZiBhIGNvbmNsdXNpdmUgcGFydGlhbCBvcmRlciByZWxhdGlvbiBjYW5ub3QgYmUgZGV0ZXJtaW5lZDwvbGk+Ci0gICAgICAgICAqIDwvdWw+Ci0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBkdXJhdGlvbiB0byBjb21wYXJlCi0gICAgICAgICAqCi0gICAgICAgICAqIEByZXR1cm4gdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIDxjb2RlPnRoaXM8L2NvZGU+IDxjb2RlPkR1cmF0aW9uPC9jb2RlPmFuZCA8Y29kZT5kdXJhdGlvbjwvY29kZT4gcGFyYW1ldGVyIGFzCi0gICAgICAgICAqICAge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0xFU1NFUn0sIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNFUVVBTH0sIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNHUkVBVEVSfQotICAgICAgICAgKiAgIG9yIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNJTkRFVEVSTUlOQVRFfS4KLSAgICAgICAgICoKLSAgICAgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBJZiB0aGUgdW5kZXJseWluZyBpbXBsZW1lbnRhdGlvbgotICAgICAgICAgKiAgIGNhbm5vdCByZWFzb25hYmx5IHByb2Nlc3MgdGhlIHJlcXVlc3QsIGUuZy4gVzNDIFhNTCBTY2hlbWEgYWxsb3dzIGZvcgotICAgICAgICAgKiAgIGFyYml0cmFyaWx5IGxhcmdlL3NtYWxsL3ByZWNpc2UgdmFsdWVzLCB0aGUgcmVxdWVzdCBtYXkgYmUgYmV5b25kIHRoZQotICAgICAgICAgKiAgIGltcGxlbWVudGF0aW9ucyBjYXBhYmlsaXR5LgotICAgICAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIDxjb2RlPmR1cmF0aW9uPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICAgICAgICoKLSAgICAgICAgICogQHNlZSAjaXNTaG9ydGVyVGhhbihEdXJhdGlvbikKLSAgICAgICAgICogQHNlZSAjaXNMb25nZXJUaGFuKER1cmF0aW9uKQotICAgICAgICAgKi8KLSAgICBwdWJsaWMgaW50IGNvbXBhcmUoRHVyYXRpb24gcmhzKSB7Ci0KLSAgICAgICAgQmlnSW50ZWdlciBtYXhpbnRBc0JpZ0ludGVnZXIgPSBCaWdJbnRlZ2VyLnZhbHVlT2YoKGxvbmcpIEludGVnZXIuTUFYX1ZBTFVFKTsKLSAgICAgICAgQmlnSW50ZWdlciBtaW5pbnRBc0JpZ0ludGVnZXIgPSBCaWdJbnRlZ2VyLnZhbHVlT2YoKGxvbmcpIEludGVnZXIuTUlOX1ZBTFVFKTsKLQotICAgICAgICAvLyBjaGVjayBmb3IgZmllbGRzIHRoYXQgYXJlIHRvbyBsYXJnZSBpbiB0aGlzIER1cmF0aW9uCi0gICAgICAgIGlmICh5ZWFycyAhPSBudWxsICYmIHllYXJzLmNvbXBhcmVUbyhtYXhpbnRBc0JpZ0ludGVnZXIpID09IDEpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgICAgIERhdGF0eXBlTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKG51bGwsICJUb29MYXJnZSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde3RoaXMuZ2V0Q2xhc3MoKS5nZXROYW1lKCkgKyAiI2NvbXBhcmUoRHVyYXRpb24gZHVyYXRpb24pIiArIERhdGF0eXBlQ29uc3RhbnRzLllFQVJTLnRvU3RyaW5nKCksIHllYXJzLnRvU3RyaW5nKCl9KQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vdGhpcy5nZXRDbGFzcygpLmdldE5hbWUoKSArICIjY29tcGFyZShEdXJhdGlvbiBkdXJhdGlvbikiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLysgIiB5ZWFycyB0b28gbGFyZ2UgdG8gYmUgc3VwcG9ydGVkIGJ5IHRoaXMgaW1wbGVtZW50YXRpb24gIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8rIHllYXJzLnRvU3RyaW5nKCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApOwotICAgICAgICB9Ci0gICAgICAgIGlmIChtb250aHMgIT0gbnVsbCAmJiBtb250aHMuY29tcGFyZVRvKG1heGludEFzQmlnSW50ZWdlcikgPT0gMSkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgICAgIERhdGF0eXBlTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKG51bGwsICJUb29MYXJnZSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde3RoaXMuZ2V0Q2xhc3MoKS5nZXROYW1lKCkgKyAiI2NvbXBhcmUoRHVyYXRpb24gZHVyYXRpb24pIiArIERhdGF0eXBlQ29uc3RhbnRzLk1PTlRIUy50b1N0cmluZygpLCBtb250aHMudG9TdHJpbmcoKX0pCi0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3RoaXMuZ2V0Q2xhc3MoKS5nZXROYW1lKCkgKyAiI2NvbXBhcmUoRHVyYXRpb24gZHVyYXRpb24pIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8rICIgbW9udGhzIHRvbyBsYXJnZSB0byBiZSBzdXBwb3J0ZWQgYnkgdGhpcyBpbXBsZW1lbnRhdGlvbiAiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLysgbW9udGhzLnRvU3RyaW5nKCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApOwotICAgICAgICB9Ci0gICAgICAgIGlmIChkYXlzICE9IG51bGwgJiYgZGF5cy5jb21wYXJlVG8obWF4aW50QXNCaWdJbnRlZ2VyKSA9PSAxKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICAgICAgRGF0YXR5cGVNZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UobnVsbCwgIlRvb0xhcmdlIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117dGhpcy5nZXRDbGFzcygpLmdldE5hbWUoKSArICIjY29tcGFyZShEdXJhdGlvbiBkdXJhdGlvbikiICsgRGF0YXR5cGVDb25zdGFudHMuREFZUy50b1N0cmluZygpLCBkYXlzLnRvU3RyaW5nKCl9KQotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy90aGlzLmdldENsYXNzKCkuZ2V0TmFtZSgpICsgIiNjb21wYXJlKER1cmF0aW9uIGR1cmF0aW9uKSIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vKyAiIGRheXMgdG9vIGxhcmdlIHRvIGJlIHN1cHBvcnRlZCBieSB0aGlzIGltcGxlbWVudGF0aW9uICIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vKyBkYXlzLnRvU3RyaW5nKCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApOwotICAgICAgICB9Ci0gICAgICAgIGlmIChob3VycyAhPSBudWxsICYmIGhvdXJzLmNvbXBhcmVUbyhtYXhpbnRBc0JpZ0ludGVnZXIpID09IDEpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgICAgICBEYXRhdHlwZU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShudWxsLCAiVG9vTGFyZ2UiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXt0aGlzLmdldENsYXNzKCkuZ2V0TmFtZSgpICsgIiNjb21wYXJlKER1cmF0aW9uIGR1cmF0aW9uKSIgKyBEYXRhdHlwZUNvbnN0YW50cy5IT1VSUy50b1N0cmluZygpLCBob3Vycy50b1N0cmluZygpfSkKLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vdGhpcy5nZXRDbGFzcygpLmdldE5hbWUoKSArICIjY29tcGFyZShEdXJhdGlvbiBkdXJhdGlvbikiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLysgIiBob3VycyB0b28gbGFyZ2UgdG8gYmUgc3VwcG9ydGVkIGJ5IHRoaXMgaW1wbGVtZW50YXRpb24gIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8rIGhvdXJzLnRvU3RyaW5nKCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApOwotICAgICAgICB9Ci0gICAgICAgIGlmIChtaW51dGVzICE9IG51bGwgJiYgbWludXRlcy5jb21wYXJlVG8obWF4aW50QXNCaWdJbnRlZ2VyKSA9PSAxKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICAgICAgRGF0YXR5cGVNZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UobnVsbCwgIlRvb0xhcmdlIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117dGhpcy5nZXRDbGFzcygpLmdldE5hbWUoKSArICIjY29tcGFyZShEdXJhdGlvbiBkdXJhdGlvbikiICsgRGF0YXR5cGVDb25zdGFudHMuTUlOVVRFUy50b1N0cmluZygpLCBtaW51dGVzLnRvU3RyaW5nKCl9KQotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy90aGlzLmdldENsYXNzKCkuZ2V0TmFtZSgpICsgIiNjb21wYXJlKER1cmF0aW9uIGR1cmF0aW9uKSIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vKyAiIG1pbnV0ZXMgdG9vIGxhcmdlIHRvIGJlIHN1cHBvcnRlZCBieSB0aGlzIGltcGxlbWVudGF0aW9uICIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vKyBtaW51dGVzLnRvU3RyaW5nKCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApOwotICAgICAgICB9Ci0gICAgICAgIGlmIChzZWNvbmRzICE9IG51bGwgJiYgc2Vjb25kcy50b0JpZ0ludGVnZXIoKS5jb21wYXJlVG8obWF4aW50QXNCaWdJbnRlZ2VyKSA9PSAxKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICAgICAgRGF0YXR5cGVNZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UobnVsbCwgIlRvb0xhcmdlIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117dGhpcy5nZXRDbGFzcygpLmdldE5hbWUoKSArICIjY29tcGFyZShEdXJhdGlvbiBkdXJhdGlvbikiICsgRGF0YXR5cGVDb25zdGFudHMuU0VDT05EUy50b1N0cmluZygpLCBzZWNvbmRzLnRvU3RyaW5nKCl9KQotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy90aGlzLmdldENsYXNzKCkuZ2V0TmFtZSgpICsgIiNjb21wYXJlKER1cmF0aW9uIGR1cmF0aW9uKSIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vKyAiIHNlY29uZHMgdG9vIGxhcmdlIHRvIGJlIHN1cHBvcnRlZCBieSB0aGlzIGltcGxlbWVudGF0aW9uICIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vKyBzZWNvbmRzLnRvU3RyaW5nKCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gY2hlY2sgZm9yIGZpZWxkcyB0aGF0IGFyZSB0b28gbGFyZ2UgaW4gcmhzIER1cmF0aW9uCi0gICAgICAgIEJpZ0ludGVnZXIgcmhzWWVhcnMgPSAoQmlnSW50ZWdlcikgcmhzLmdldEZpZWxkKERhdGF0eXBlQ29uc3RhbnRzLllFQVJTKTsKLSAgICAgICAgaWYgKHJoc1llYXJzICE9IG51bGwgJiYgcmhzWWVhcnMuY29tcGFyZVRvKG1heGludEFzQmlnSW50ZWdlcikgPT0gMSkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgICAgIERhdGF0eXBlTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKG51bGwsICJUb29MYXJnZSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde3RoaXMuZ2V0Q2xhc3MoKS5nZXROYW1lKCkgKyAiI2NvbXBhcmUoRHVyYXRpb24gZHVyYXRpb24pIiArIERhdGF0eXBlQ29uc3RhbnRzLllFQVJTLnRvU3RyaW5nKCksIHJoc1llYXJzLnRvU3RyaW5nKCl9KQotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy90aGlzLmdldENsYXNzKCkuZ2V0TmFtZSgpICsgIiNjb21wYXJlKER1cmF0aW9uIGR1cmF0aW9uKSIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vKyAiIHllYXJzIHRvbyBsYXJnZSB0byBiZSBzdXBwb3J0ZWQgYnkgdGhpcyBpbXBsZW1lbnRhdGlvbiAiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLysgcmhzWWVhcnMudG9TdHJpbmcoKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7Ci0gICAgICAgIH0KLSAgICAgICAgQmlnSW50ZWdlciByaHNNb250aHMgPSAoQmlnSW50ZWdlcikgcmhzLmdldEZpZWxkKERhdGF0eXBlQ29uc3RhbnRzLk1PTlRIUyk7Ci0gICAgICAgIGlmIChyaHNNb250aHMgIT0gbnVsbCAmJiByaHNNb250aHMuY29tcGFyZVRvKG1heGludEFzQmlnSW50ZWdlcikgPT0gMSkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgICAgIERhdGF0eXBlTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKG51bGwsICJUb29MYXJnZSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde3RoaXMuZ2V0Q2xhc3MoKS5nZXROYW1lKCkgKyAiI2NvbXBhcmUoRHVyYXRpb24gZHVyYXRpb24pIiArIERhdGF0eXBlQ29uc3RhbnRzLk1PTlRIUy50b1N0cmluZygpLCByaHNNb250aHMudG9TdHJpbmcoKX0pCi0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3RoaXMuZ2V0Q2xhc3MoKS5nZXROYW1lKCkgKyAiI2NvbXBhcmUoRHVyYXRpb24gZHVyYXRpb24pIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8rICIgbW9udGhzIHRvbyBsYXJnZSB0byBiZSBzdXBwb3J0ZWQgYnkgdGhpcyBpbXBsZW1lbnRhdGlvbiAiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLysgcmhzTW9udGhzLnRvU3RyaW5nKCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApOwotICAgICAgICB9Ci0gICAgICAgIEJpZ0ludGVnZXIgcmhzRGF5cyA9IChCaWdJbnRlZ2VyKSByaHMuZ2V0RmllbGQoRGF0YXR5cGVDb25zdGFudHMuREFZUyk7Ci0gICAgICAgIGlmIChyaHNEYXlzICE9IG51bGwgJiYgcmhzRGF5cy5jb21wYXJlVG8obWF4aW50QXNCaWdJbnRlZ2VyKSA9PSAxKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICAgICAgRGF0YXR5cGVNZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UobnVsbCwgIlRvb0xhcmdlIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117dGhpcy5nZXRDbGFzcygpLmdldE5hbWUoKSArICIjY29tcGFyZShEdXJhdGlvbiBkdXJhdGlvbikiICsgRGF0YXR5cGVDb25zdGFudHMuREFZUy50b1N0cmluZygpLCByaHNEYXlzLnRvU3RyaW5nKCl9KQotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy90aGlzLmdldENsYXNzKCkuZ2V0TmFtZSgpICsgIiNjb21wYXJlKER1cmF0aW9uIGR1cmF0aW9uKSIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vKyAiIGRheXMgdG9vIGxhcmdlIHRvIGJlIHN1cHBvcnRlZCBieSB0aGlzIGltcGxlbWVudGF0aW9uICIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vKyByaHNEYXlzLnRvU3RyaW5nKCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApOwotICAgICAgICB9Ci0gICAgICAgIEJpZ0ludGVnZXIgcmhzSG91cnMgPSAoQmlnSW50ZWdlcikgcmhzLmdldEZpZWxkKERhdGF0eXBlQ29uc3RhbnRzLkhPVVJTKTsKLSAgICAgICAgaWYgKHJoc0hvdXJzICE9IG51bGwgJiYgcmhzSG91cnMuY29tcGFyZVRvKG1heGludEFzQmlnSW50ZWdlcikgPT0gMSkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgICAgIERhdGF0eXBlTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKG51bGwsICJUb29MYXJnZSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde3RoaXMuZ2V0Q2xhc3MoKS5nZXROYW1lKCkgKyAiI2NvbXBhcmUoRHVyYXRpb24gZHVyYXRpb24pIiArIERhdGF0eXBlQ29uc3RhbnRzLkhPVVJTLnRvU3RyaW5nKCksIHJoc0hvdXJzLnRvU3RyaW5nKCl9KQotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy90aGlzLmdldENsYXNzKCkuZ2V0TmFtZSgpICsgIiNjb21wYXJlKER1cmF0aW9uIGR1cmF0aW9uKSIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vKyAiIGhvdXJzIHRvbyBsYXJnZSB0byBiZSBzdXBwb3J0ZWQgYnkgdGhpcyBpbXBsZW1lbnRhdGlvbiAiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLysgcmhzSG91cnMudG9TdHJpbmcoKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7Ci0gICAgICAgIH0KLSAgICAgICAgQmlnSW50ZWdlciByaHNNaW51dGVzID0gKEJpZ0ludGVnZXIpIHJocy5nZXRGaWVsZChEYXRhdHlwZUNvbnN0YW50cy5NSU5VVEVTKTsKLSAgICAgICAgaWYgKHJoc01pbnV0ZXMgIT0gbnVsbCAmJiByaHNNaW51dGVzLmNvbXBhcmVUbyhtYXhpbnRBc0JpZ0ludGVnZXIpID09IDEpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgICAgICBEYXRhdHlwZU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShudWxsLCAiVG9vTGFyZ2UiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXt0aGlzLmdldENsYXNzKCkuZ2V0TmFtZSgpICsgIiNjb21wYXJlKER1cmF0aW9uIGR1cmF0aW9uKSIgKyBEYXRhdHlwZUNvbnN0YW50cy5NSU5VVEVTLnRvU3RyaW5nKCksIHJoc01pbnV0ZXMudG9TdHJpbmcoKX0pCi0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3RoaXMuZ2V0Q2xhc3MoKS5nZXROYW1lKCkgKyAiI2NvbXBhcmUoRHVyYXRpb24gZHVyYXRpb24pIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8rICIgbWludXRlcyB0b28gbGFyZ2UgdG8gYmUgc3VwcG9ydGVkIGJ5IHRoaXMgaW1wbGVtZW50YXRpb24gIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8rIHJoc01pbnV0ZXMudG9TdHJpbmcoKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7Ci0gICAgICAgIH0KLSAgICAgICAgQmlnRGVjaW1hbCByaHNTZWNvbmRzQXNCaWdEZWNpbWFsID0gKEJpZ0RlY2ltYWwpIHJocy5nZXRGaWVsZChEYXRhdHlwZUNvbnN0YW50cy5TRUNPTkRTKTsKLSAgICAgICAgQmlnSW50ZWdlciByaHNTZWNvbmRzID0gbnVsbDsKLSAgICAgICAgaWYgKCByaHNTZWNvbmRzQXNCaWdEZWNpbWFsICE9IG51bGwgKSB7Ci0gICAgICAgICAgICAgICAgcmhzU2Vjb25kcyA9ICByaHNTZWNvbmRzQXNCaWdEZWNpbWFsLnRvQmlnSW50ZWdlcigpOwotICAgICAgICB9Ci0gICAgICAgIGlmIChyaHNTZWNvbmRzICE9IG51bGwgJiYgcmhzU2Vjb25kcy5jb21wYXJlVG8obWF4aW50QXNCaWdJbnRlZ2VyKSA9PSAxKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICAgICAgRGF0YXR5cGVNZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UobnVsbCwgIlRvb0xhcmdlIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117dGhpcy5nZXRDbGFzcygpLmdldE5hbWUoKSArICIjY29tcGFyZShEdXJhdGlvbiBkdXJhdGlvbikiICsgRGF0YXR5cGVDb25zdGFudHMuU0VDT05EUy50b1N0cmluZygpLCByaHNTZWNvbmRzLnRvU3RyaW5nKCl9KQotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy90aGlzLmdldENsYXNzKCkuZ2V0TmFtZSgpICsgIiNjb21wYXJlKER1cmF0aW9uIGR1cmF0aW9uKSIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vKyAiIHNlY29uZHMgdG9vIGxhcmdlIHRvIGJlIHN1cHBvcnRlZCBieSB0aGlzIGltcGxlbWVudGF0aW9uICIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vKyByaHNTZWNvbmRzLnRvU3RyaW5nKCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gdHVybiB0aGlzIER1cmF0aW9uIGludG8gYSBHcmVnb3JpYW5DYWxlbmRhcgotICAgICAgICBHcmVnb3JpYW5DYWxlbmRhciBsaHNDYWxlbmRhciA9IG5ldyBHcmVnb3JpYW5DYWxlbmRhcigKLSAgICAgICAgICAgICAgICAgICAgICAgIDE5NzAsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDApOwotICAgICAgICAgICAgICAgIGxoc0NhbGVuZGFyLmFkZChHcmVnb3JpYW5DYWxlbmRhci5ZRUFSLCBnZXRZZWFycygpICogZ2V0U2lnbigpKTsKLSAgICAgICAgICAgICAgICBsaHNDYWxlbmRhci5hZGQoR3JlZ29yaWFuQ2FsZW5kYXIuTU9OVEgsIGdldE1vbnRocygpICogZ2V0U2lnbigpKTsKLSAgICAgICAgICAgICAgICBsaHNDYWxlbmRhci5hZGQoR3JlZ29yaWFuQ2FsZW5kYXIuREFZX09GX1lFQVIsIGdldERheXMoKSAqIGdldFNpZ24oKSk7Ci0gICAgICAgICAgICAgICAgbGhzQ2FsZW5kYXIuYWRkKEdyZWdvcmlhbkNhbGVuZGFyLkhPVVJfT0ZfREFZLCBnZXRIb3VycygpICogZ2V0U2lnbigpKTsKLSAgICAgICAgICAgICAgICBsaHNDYWxlbmRhci5hZGQoR3JlZ29yaWFuQ2FsZW5kYXIuTUlOVVRFLCBnZXRNaW51dGVzKCkgKiBnZXRTaWduKCkpOwotICAgICAgICAgICAgICAgIGxoc0NhbGVuZGFyLmFkZChHcmVnb3JpYW5DYWxlbmRhci5TRUNPTkQsIGdldFNlY29uZHMoKSAqIGdldFNpZ24oKSk7Ci0KLSAgICAgICAgICAgICAgICAvLyB0dXJuIGNvbXBhcmUgRHVyYXRpb24gaW50byBhIEdyZWdvcmlhbkNhbGVuZGFyCi0gICAgICAgIEdyZWdvcmlhbkNhbGVuZGFyIHJoc0NhbGVuZGFyID0gbmV3IEdyZWdvcmlhbkNhbGVuZGFyKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxOTcwLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwKTsKLSAgICAgICAgICAgICAgICByaHNDYWxlbmRhci5hZGQoR3JlZ29yaWFuQ2FsZW5kYXIuWUVBUiwgcmhzLmdldFllYXJzKCkgKiByaHMuZ2V0U2lnbigpKTsKLSAgICAgICAgICAgICAgICByaHNDYWxlbmRhci5hZGQoR3JlZ29yaWFuQ2FsZW5kYXIuTU9OVEgsIHJocy5nZXRNb250aHMoKSAqIHJocy5nZXRTaWduKCkpOwotICAgICAgICAgICAgICAgIHJoc0NhbGVuZGFyLmFkZChHcmVnb3JpYW5DYWxlbmRhci5EQVlfT0ZfWUVBUiwgcmhzLmdldERheXMoKSAqIHJocy5nZXRTaWduKCkpOwotICAgICAgICAgICAgICAgIHJoc0NhbGVuZGFyLmFkZChHcmVnb3JpYW5DYWxlbmRhci5IT1VSX09GX0RBWSwgcmhzLmdldEhvdXJzKCkgKiByaHMuZ2V0U2lnbigpKTsKLSAgICAgICAgICAgICAgICByaHNDYWxlbmRhci5hZGQoR3JlZ29yaWFuQ2FsZW5kYXIuTUlOVVRFLCByaHMuZ2V0TWludXRlcygpICogcmhzLmdldFNpZ24oKSk7Ci0gICAgICAgICAgICAgICAgcmhzQ2FsZW5kYXIuYWRkKEdyZWdvcmlhbkNhbGVuZGFyLlNFQ09ORCwgcmhzLmdldFNlY29uZHMoKSAqIHJocy5nZXRTaWduKCkpOwotCi0KLSAgICAgICAgICAgICAgICBpZiAobGhzQ2FsZW5kYXIuZXF1YWxzKHJoc0NhbGVuZGFyKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIERhdGF0eXBlQ29uc3RhbnRzLkVRVUFMOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIHJldHVybiBjb21wYXJlRGF0ZXModGhpcywgcmhzKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb21wYXJlcyAyIGdpdmVuIGR1cmF0aW9ucy4gKHJlZmVyIHRvIFczQyBTY2hlbWEgRGF0YXR5cGVzICIzLjIuNiBkdXJhdGlvbiIpCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZHVyYXRpb24xICBVbm5vcm1hbGl6ZWQgZHVyYXRpb24KLSAgICAgKiBAcGFyYW0gZHVyYXRpb24yICBVbm5vcm1hbGl6ZWQgZHVyYXRpb24KLSAgICAgKiBAcmV0dXJuIElOREVURVJNSU5BVEUgaWYgdGhlIG9yZGVyIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGRhdGUxIGFuZCBkYXRlMiBpcyBpbmRldGVybWluYXRlLgotICAgICAqIEVRVUFMIGlmIHRoZSBvcmRlciByZWxhdGlvbiBiZXR3ZWVuIGRhdGUxIGFuZCBkYXRlMiBpcyBFUVVBTC4KLSAgICAgKiBJZiB0aGUgc3RyaWN0IHBhcmFtZXRlciBpcyB0cnVlLCByZXR1cm4gTEVTU19USEFOIGlmIGRhdGUxIGlzIGxlc3MgdGhhbiBkYXRlMiBhbmQKLSAgICAgKiByZXR1cm4gR1JFQVRFUl9USEFOIGlmIGRhdGUxIGlzIGdyZWF0ZXIgdGhhbiBkYXRlMi4KLSAgICAgKiBJZiB0aGUgc3RyaWN0IHBhcmFtZXRlciBpcyBmYWxzZSwgcmV0dXJuIExFU1NfVEhBTiBpZiBkYXRlMSBpcyBsZXNzIHRoYW4gT1IgZXF1YWwgdG8gZGF0ZTIgYW5kCi0gICAgICogcmV0dXJuIEdSRUFURVJfVEhBTiBpZiBkYXRlMSBpcyBncmVhdGVyIHRoYW4gT1IgZXF1YWwgdG8gZGF0ZTIKLSAgICAgKi8KLSAgICBwcml2YXRlIGludCBjb21wYXJlRGF0ZXMoRHVyYXRpb24gZHVyYXRpb24xLCBEdXJhdGlvbiBkdXJhdGlvbjIpIHsKLQotICAgICAgICBpbnQgcmVzdWx0QSA9IERhdGF0eXBlQ29uc3RhbnRzLklOREVURVJNSU5BVEU7Ci0gICAgICAgIGludCByZXN1bHRCID0gRGF0YXR5cGVDb25zdGFudHMuSU5ERVRFUk1JTkFURTsKLQotICAgICAgICBYTUxHcmVnb3JpYW5DYWxlbmRhciB0ZW1wQSA9IChYTUxHcmVnb3JpYW5DYWxlbmRhcilURVNUX1BPSU5UU1swXS5jbG9uZSgpOwotICAgICAgICBYTUxHcmVnb3JpYW5DYWxlbmRhciB0ZW1wQiA9IChYTUxHcmVnb3JpYW5DYWxlbmRhcilURVNUX1BPSU5UU1swXS5jbG9uZSgpOwotCi0gICAgICAgIC8vbG9uZyBjb21wYXJpc29uIGFsZ29yaXRobSBpcyByZXF1aXJlZAotICAgICAgICB0ZW1wQS5hZGQoZHVyYXRpb24xKTsKLSAgICAgICAgdGVtcEIuYWRkKGR1cmF0aW9uMik7Ci0gICAgICAgIHJlc3VsdEEgPSAgdGVtcEEuY29tcGFyZSh0ZW1wQik7Ci0gICAgICAgIGlmICggcmVzdWx0QSA9PSBEYXRhdHlwZUNvbnN0YW50cy5JTkRFVEVSTUlOQVRFICkgewotICAgICAgICAgICAgcmV0dXJuIERhdGF0eXBlQ29uc3RhbnRzLklOREVURVJNSU5BVEU7Ci0gICAgICAgIH0KLQotICAgICAgICB0ZW1wQSA9IChYTUxHcmVnb3JpYW5DYWxlbmRhcilURVNUX1BPSU5UU1sxXS5jbG9uZSgpOwotICAgICAgICB0ZW1wQiA9IChYTUxHcmVnb3JpYW5DYWxlbmRhcilURVNUX1BPSU5UU1sxXS5jbG9uZSgpOwotCi0gICAgICAgIHRlbXBBLmFkZChkdXJhdGlvbjEpOwotICAgICAgICB0ZW1wQi5hZGQoZHVyYXRpb24yKTsKLSAgICAgICAgcmVzdWx0QiA9IHRlbXBBLmNvbXBhcmUodGVtcEIpOwotICAgICAgICByZXN1bHRBID0gY29tcGFyZVJlc3VsdHMocmVzdWx0QSwgcmVzdWx0Qik7Ci0gICAgICAgIGlmIChyZXN1bHRBID09IERhdGF0eXBlQ29uc3RhbnRzLklOREVURVJNSU5BVEUpIHsKLSAgICAgICAgICAgIHJldHVybiBEYXRhdHlwZUNvbnN0YW50cy5JTkRFVEVSTUlOQVRFOwotICAgICAgICB9Ci0KLSAgICAgICAgdGVtcEEgPSAoWE1MR3JlZ29yaWFuQ2FsZW5kYXIpVEVTVF9QT0lOVFNbMl0uY2xvbmUoKTsKLSAgICAgICAgdGVtcEIgPSAoWE1MR3JlZ29yaWFuQ2FsZW5kYXIpVEVTVF9QT0lOVFNbMl0uY2xvbmUoKTsKLQotICAgICAgICB0ZW1wQS5hZGQoZHVyYXRpb24xKTsKLSAgICAgICAgdGVtcEIuYWRkKGR1cmF0aW9uMik7Ci0gICAgICAgIHJlc3VsdEIgPSB0ZW1wQS5jb21wYXJlKHRlbXBCKTsKLSAgICAgICAgcmVzdWx0QSA9IGNvbXBhcmVSZXN1bHRzKHJlc3VsdEEsIHJlc3VsdEIpOwotICAgICAgICBpZiAocmVzdWx0QSA9PSBEYXRhdHlwZUNvbnN0YW50cy5JTkRFVEVSTUlOQVRFKSB7Ci0gICAgICAgICAgICByZXR1cm4gRGF0YXR5cGVDb25zdGFudHMuSU5ERVRFUk1JTkFURTsKLSAgICAgICAgfQotCi0gICAgICAgIHRlbXBBID0gKFhNTEdyZWdvcmlhbkNhbGVuZGFyKVRFU1RfUE9JTlRTWzNdLmNsb25lKCk7Ci0gICAgICAgIHRlbXBCID0gKFhNTEdyZWdvcmlhbkNhbGVuZGFyKVRFU1RfUE9JTlRTWzNdLmNsb25lKCk7Ci0KLSAgICAgICAgdGVtcEEuYWRkKGR1cmF0aW9uMSk7Ci0gICAgICAgIHRlbXBCLmFkZChkdXJhdGlvbjIpOwotICAgICAgICByZXN1bHRCID0gdGVtcEEuY29tcGFyZSh0ZW1wQik7Ci0gICAgICAgIHJlc3VsdEEgPSBjb21wYXJlUmVzdWx0cyhyZXN1bHRBLCByZXN1bHRCKTsKLQotICAgICAgICByZXR1cm4gcmVzdWx0QTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIGludCBjb21wYXJlUmVzdWx0cyhpbnQgcmVzdWx0QSwgaW50IHJlc3VsdEIpewotCi0gICAgICBpZiAoIHJlc3VsdEIgPT0gRGF0YXR5cGVDb25zdGFudHMuSU5ERVRFUk1JTkFURSApIHsKLSAgICAgICAgICAgIHJldHVybiBEYXRhdHlwZUNvbnN0YW50cy5JTkRFVEVSTUlOQVRFOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKCByZXN1bHRBIT1yZXN1bHRCKSB7Ci0gICAgICAgICAgICByZXR1cm4gRGF0YXR5cGVDb25zdGFudHMuSU5ERVRFUk1JTkFURTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gcmVzdWx0QTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGEgaGFzaCBjb2RlIGNvbnNpc3RlbnQgd2l0aCB0aGUgZGVmaW5pdGlvbiBvZiB0aGUgZXF1YWxzIG1ldGhvZC4KLSAgICAgKgotICAgICAqIEBzZWUgT2JqZWN0I2hhc2hDb2RlKCkKLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewotICAgICAgICAvLyBjb21wb25lbnQgd2lzZSBoYXNoIGlzIG5vdCBjb3JyZWN0IGJlY2F1c2UgMWRheSA9IDI0aG91cnMKLSAgICAgICAgQ2FsZW5kYXIgY2FsID0gVEVTVF9QT0lOVFNbMF0udG9HcmVnb3JpYW5DYWxlbmRhcigpOwotICAgICAgICB0aGlzLmFkZFRvKGNhbCk7Ci0gICAgICAgIHJldHVybiAoaW50KSBnZXRDYWxlbmRhclRpbWVJbk1pbGxpcyhjYWwpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBkdXJhdGlvbiBvYmplY3QuCi0gICAgICoKLSAgICAgKiA8cD4KLSAgICAgKiBUaGUgcmVzdWx0IGlzIGZvcm1hdHRlciBhY2NvcmRpbmcgdG8gdGhlIFhNTCBTY2hlbWEgMS4wCi0gICAgICogc3BlYyBhbmQgY2FuIGJlIGFsd2F5cyBwYXJzZWQgYmFjayBsYXRlciBpbnRvIHRoZQotICAgICAqIGVxdWl2YWxlbnQgZHVyYXRpb24gb2JqZWN0IGJ5Ci0gICAgICogdGhlIHtAbGluayAjRHVyYXRpb25JbXBsKFN0cmluZyl9IGNvbnN0cnVjdG9yLgotICAgICAqCi0gICAgICogPHA+Ci0gICAgICogRm9ybWFsbHksIHRoZSBmb2xsb3dpbmcgaG9sZHMgZm9yIGFueSB7QGxpbmsgRHVyYXRpb259Ci0gICAgICogb2JqZWN0IHguCi0gICAgICogPHByZT4KLSAgICAgKiBuZXcgRHVyYXRpb24oeC50b1N0cmluZygpKS5lcXVhbHMoeCkKLSAgICAgKiA8L3ByZT4KLSAgICAgKgotICAgICAqIEByZXR1cm4KLSAgICAgKiAgICAgIEFsd2F5cyByZXR1cm4gYSBub24tbnVsbCB2YWxpZCBTdHJpbmcgb2JqZWN0LgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0gICAgICAgIFN0cmluZ0J1ZmZlciBidWYgPSBuZXcgU3RyaW5nQnVmZmVyKCk7Ci0gICAgICAgIGlmIChzaWdudW0gPCAwKSB7Ci0gICAgICAgICAgICBidWYuYXBwZW5kKCctJyk7Ci0gICAgICAgIH0KLSAgICAgICAgYnVmLmFwcGVuZCgnUCcpOwotCi0gICAgICAgIGlmICh5ZWFycyAhPSBudWxsKSB7Ci0gICAgICAgICAgICBidWYuYXBwZW5kKHllYXJzICsgIlkiKTsKLSAgICAgICAgfQotICAgICAgICBpZiAobW9udGhzICE9IG51bGwpIHsKLSAgICAgICAgICAgIGJ1Zi5hcHBlbmQobW9udGhzICsgIk0iKTsKLSAgICAgICAgfQotICAgICAgICBpZiAoZGF5cyAhPSBudWxsKSB7Ci0gICAgICAgICAgICBidWYuYXBwZW5kKGRheXMgKyAiRCIpOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKGhvdXJzICE9IG51bGwgfHwgbWludXRlcyAhPSBudWxsIHx8IHNlY29uZHMgIT0gbnVsbCkgewotICAgICAgICAgICAgYnVmLmFwcGVuZCgnVCcpOwotICAgICAgICAgICAgaWYgKGhvdXJzICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBidWYuYXBwZW5kKGhvdXJzICsgIkgiKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChtaW51dGVzICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBidWYuYXBwZW5kKG1pbnV0ZXMgKyAiTSIpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKHNlY29uZHMgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQodG9TdHJpbmcoc2Vjb25kcykgKyAiUyIpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIGJ1Zi50b1N0cmluZygpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPlR1cm5zIHtAbGluayBCaWdEZWNpbWFsfSB0byBhIHN0cmluZyByZXByZXNlbnRhdGlvbi48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5EdWUgdG8gYSBiZWhhdmlvciBjaGFuZ2UgaW4gdGhlIHtAbGluayBCaWdEZWNpbWFsI3RvU3RyaW5nKCl9Ci0gICAgICogbWV0aG9kIGluIEpESzEuNSwgdGhpcyBoYWQgdG8gYmUgaW1wbGVtZW50ZWQgaGVyZS48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gYmQgPGNvZGU+QmlnRGVjaW1hbDwvY29kZT4gdG8gZm9ybWF0IGFzIGEgPGNvZGU+U3RyaW5nPC9jb2RlPgotICAgICAqCi0gICAgICogQHJldHVybiAgPGNvZGU+U3RyaW5nPC9jb2RlPiByZXByZXNlbnRhdGlvbiBvZiA8Y29kZT5CaWdEZWNpbWFsPC9jb2RlPgotICAgICAqLwotICAgIHByaXZhdGUgU3RyaW5nIHRvU3RyaW5nKEJpZ0RlY2ltYWwgYmQpIHsKLSAgICAgICAgU3RyaW5nIGludFN0cmluZyA9IGJkLnVuc2NhbGVkVmFsdWUoKS50b1N0cmluZygpOwotICAgICAgICBpbnQgc2NhbGUgPSBiZC5zY2FsZSgpOwotCi0gICAgICAgIGlmIChzY2FsZSA9PSAwKSB7Ci0gICAgICAgICAgICByZXR1cm4gaW50U3RyaW5nOwotICAgICAgICB9Ci0KLSAgICAgICAgLyogSW5zZXJ0IGRlY2ltYWwgcG9pbnQgKi8KLSAgICAgICAgU3RyaW5nQnVmZmVyIGJ1ZjsKLSAgICAgICAgaW50IGluc2VydGlvblBvaW50ID0gaW50U3RyaW5nLmxlbmd0aCgpIC0gc2NhbGU7Ci0gICAgICAgIGlmIChpbnNlcnRpb25Qb2ludCA9PSAwKSB7IC8qIFBvaW50IGdvZXMgcmlnaHQgYmVmb3JlIGludFZhbCAqLwotICAgICAgICAgICAgcmV0dXJuICIwLiIgKyBpbnRTdHJpbmc7Ci0gICAgICAgIH0gZWxzZSBpZiAoaW5zZXJ0aW9uUG9pbnQgPiAwKSB7IC8qIFBvaW50IGdvZXMgaW5zaWRlIGludFZhbCAqLwotICAgICAgICAgICAgYnVmID0gbmV3IFN0cmluZ0J1ZmZlcihpbnRTdHJpbmcpOwotICAgICAgICAgICAgYnVmLmluc2VydChpbnNlcnRpb25Qb2ludCwgJy4nKTsKLSAgICAgICAgfSBlbHNlIHsgLyogV2UgbXVzdCBpbnNlcnQgemVyb3MgYmV0d2VlbiBwb2ludCBhbmQgaW50VmFsICovCi0gICAgICAgICAgICBidWYgPSBuZXcgU3RyaW5nQnVmZmVyKDMgLSBpbnNlcnRpb25Qb2ludCArIGludFN0cmluZy5sZW5ndGgoKSk7Ci0gICAgICAgICAgICBidWYuYXBwZW5kKCIwLiIpOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAtaW5zZXJ0aW9uUG9pbnQ7IGkrKykgewotICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoJzAnKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGJ1Zi5hcHBlbmQoaW50U3RyaW5nKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gYnVmLnRvU3RyaW5nKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ2hlY2tzIGlmIGEgZmllbGQgaXMgc2V0LgotICAgICAqCi0gICAgICogQSBmaWVsZCBvZiBhIGR1cmF0aW9uIG9iamVjdCBtYXkgb3IgbWF5IG5vdCBiZSBwcmVzZW50LgotICAgICAqIFRoaXMgbWV0aG9kIGNhbiBiZSB1c2VkIHRvIHRlc3QgaWYgYSBmaWVsZCBpcyBwcmVzZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIGZpZWxkCi0gICAgICogICAgICBvbmUgb2YgdGhlIHNpeCBGaWVsZCBjb25zdGFudHMgKFlFQVJTLE1PTlRIUyxEQVlTLEhPVVJTLAotICAgICAqICAgICAgTUlOVVRFUywgb3IgU0VDT05EUy4pCi0gICAgICogQHJldHVybgotICAgICAqICAgICAgdHJ1ZSBpZiB0aGUgZmllbGQgaXMgcHJlc2VudC4gZmFsc2UgaWYgbm90LgotICAgICAqCi0gICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgotICAgICAqICAgICAgSWYgdGhlIGZpZWxkIHBhcmFtZXRlciBpcyBudWxsLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzU2V0KERhdGF0eXBlQ29uc3RhbnRzLkZpZWxkIGZpZWxkKSB7Ci0KLSAgICAgICAgaWYgKGZpZWxkID09IG51bGwpIHsKLSAgICAgICAgICAgIFN0cmluZyBtZXRob2ROYW1lID0gImphdmF4LnhtbC5kYXRhdHlwZS5EdXJhdGlvbiIgKyAiI2lzU2V0KERhdGF0eXBlQ29uc3RhbnRzLkZpZWxkIGZpZWxkKSIgOwotICAgICAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAvLyJjYW5ub3QgYmUgY2FsbGVkIHdpdGggZmllbGQgPT0gbnVsbCIKLSAgICAgICAgICAgICAgICBEYXRhdHlwZU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShudWxsLCAiRmllbGRDYW5ub3RCZU51bGwiLCBuZXcgT2JqZWN0W117bWV0aG9kTmFtZX0pCi0gICAgICAgICAgICAgICAgKTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChmaWVsZCA9PSBEYXRhdHlwZUNvbnN0YW50cy5ZRUFSUykgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHllYXJzICE9IG51bGw7Ci0gICAgICAgIH0KLQotICAgICAgICAgICAgICAgIGlmIChmaWVsZCA9PSBEYXRhdHlwZUNvbnN0YW50cy5NT05USFMpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBtb250aHMgIT0gbnVsbDsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBpZiAoZmllbGQgPT0gRGF0YXR5cGVDb25zdGFudHMuREFZUykgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRheXMgIT0gbnVsbDsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBpZiAoZmllbGQgPT0gRGF0YXR5cGVDb25zdGFudHMuSE9VUlMpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBob3VycyAhPSBudWxsOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIGlmIChmaWVsZCA9PSBEYXRhdHlwZUNvbnN0YW50cy5NSU5VVEVTKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbWludXRlcyAhPSBudWxsOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIGlmIChmaWVsZCA9PSBEYXRhdHlwZUNvbnN0YW50cy5TRUNPTkRTKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2Vjb25kcyAhPSBudWxsOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgU3RyaW5nIG1ldGhvZE5hbWUgPSAiamF2YXgueG1sLmRhdGF0eXBlLkR1cmF0aW9uIiArICIjaXNTZXQoRGF0YXR5cGVDb25zdGFudHMuRmllbGQgZmllbGQpIjsKLQotICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAotICAgICAgICAgICAgRGF0YXR5cGVNZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UobnVsbCwiVW5rbm93bkZpZWxkIiwgbmV3IE9iamVjdFtde21ldGhvZE5hbWUsIGZpZWxkLnRvU3RyaW5nKCl9KQotICAgICAgICAgICAgICAgICk7Ci0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXRzIHRoZSB2YWx1ZSBvZiBhIGZpZWxkLgotICAgICAqCi0gICAgICogRmllbGRzIG9mIGEgZHVyYXRpb24gb2JqZWN0IG1heSBjb250YWluIGFyYml0cmFyeSBsYXJnZSB2YWx1ZS4KLSAgICAgKiBUaGVyZWZvcmUgdGhpcyBtZXRob2QgaXMgZGVzaWduZWQgdG8gcmV0dXJuIGEge0BsaW5rIE51bWJlcn0gb2JqZWN0LgotICAgICAqCi0gICAgICogSW4gY2FzZSBvZiBZRUFSUywgTU9OVEhTLCBEQVlTLCBIT1VSUywgYW5kIE1JTlVURVMsIHRoZSByZXR1cm5lZAotICAgICAqIG51bWJlciB3aWxsIGJlIGEgbm9uLW5lZ2F0aXZlIGludGVnZXIuIEluIGNhc2Ugb2Ygc2Vjb25kcywKLSAgICAgKiB0aGUgcmV0dXJuZWQgbnVtYmVyIG1heSBiZSBhIG5vbi1uZWdhdGl2ZSBkZWNpbWFsIHZhbHVlLgotICAgICAqCi0gICAgICogQHBhcmFtIGZpZWxkCi0gICAgICogICAgICBvbmUgb2YgdGhlIHNpeCBGaWVsZCBjb25zdGFudHMgKFlFQVJTLE1PTlRIUyxEQVlTLEhPVVJTLAotICAgICAqICAgICAgTUlOVVRFUywgb3IgU0VDT05EUy4pCi0gICAgICogQHJldHVybgotICAgICAqICAgICAgSWYgdGhlIHNwZWNpZmllZCBmaWVsZCBpcyBwcmVzZW50LCB0aGlzIG1ldGhvZCByZXR1cm5zCi0gICAgICogICAgICBhIG5vbi1udWxsIG5vbi1uZWdhdGl2ZSB7QGxpbmsgTnVtYmVyfSBvYmplY3QgdGhhdAotICAgICAqICAgICAgcmVwcmVzZW50cyBpdHMgdmFsdWUuIElmIGl0IGlzIG5vdCBwcmVzZW50LCByZXR1cm4gbnVsbC4KLSAgICAgKiAgICAgIEZvciBZRUFSUywgTU9OVEhTLCBEQVlTLCBIT1VSUywgYW5kIE1JTlVURVMsIHRoaXMgbWV0aG9kCi0gICAgICogICAgICByZXR1cm5zIGEge0BsaW5rIEJpZ0ludGVnZXJ9IG9iamVjdC4gRm9yIFNFQ09ORFMsIHRoaXMKLSAgICAgKiAgICAgIG1ldGhvZCByZXR1cm5zIGEge0BsaW5rIEJpZ0RlY2ltYWx9LgotICAgICAqCi0gICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgotICAgICAqICAgICAgSWYgdGhlIGZpZWxkIHBhcmFtZXRlciBpcyBudWxsLgotICAgICAqLwotICAgIHB1YmxpYyBOdW1iZXIgZ2V0RmllbGQoRGF0YXR5cGVDb25zdGFudHMuRmllbGQgZmllbGQpIHsKLQotICAgICAgICAgICAgICAgIGlmIChmaWVsZCA9PSBudWxsKSB7Ci0gICAgICAgICAgICBTdHJpbmcgbWV0aG9kTmFtZSA9ICJqYXZheC54bWwuZGF0YXR5cGUuRHVyYXRpb24iICsgIiNpc1NldChEYXRhdHlwZUNvbnN0YW50cy5GaWVsZCBmaWVsZCkgIiA7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICBEYXRhdHlwZU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShudWxsLCJGaWVsZENhbm5vdEJlTnVsbCIsIG5ldyBPYmplY3RbXXttZXRob2ROYW1lfSkKLSAgICAgICAgICAgICAgICApOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIGlmIChmaWVsZCA9PSBEYXRhdHlwZUNvbnN0YW50cy5ZRUFSUykgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHllYXJzOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIGlmIChmaWVsZCA9PSBEYXRhdHlwZUNvbnN0YW50cy5NT05USFMpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBtb250aHM7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgaWYgKGZpZWxkID09IERhdGF0eXBlQ29uc3RhbnRzLkRBWVMpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBkYXlzOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIGlmIChmaWVsZCA9PSBEYXRhdHlwZUNvbnN0YW50cy5IT1VSUykgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGhvdXJzOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIGlmIChmaWVsZCA9PSBEYXRhdHlwZUNvbnN0YW50cy5NSU5VVEVTKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbWludXRlczsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBpZiAoZmllbGQgPT0gRGF0YXR5cGVDb25zdGFudHMuU0VDT05EUykgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNlY29uZHM7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIC8qKgotICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgICAgICAiamF2YXgueG1sLmRhdGF0eXBlLkR1cmF0aW9uIgotICAgICAgICAgICAgICAgICAgICAgICAgKyAiIyhnZXRTZXQoRGF0YXR5cGVDb25zdGFudHMuRmllbGQgZmllbGQpIGNhbGxlZCB3aXRoIGFuIHVua25vd24gZmllbGQ6ICIKLSAgICAgICAgICAgICAgICAgICAgICAgICsgZmllbGQudG9TdHJpbmcoKQotICAgICAgICAgICAgICAgICk7Ci0gICAgICAgICovCi0gICAgICAgIFN0cmluZyBtZXRob2ROYW1lID0gImphdmF4LnhtbC5kYXRhdHlwZS5EdXJhdGlvbiIgKyAiIyhnZXRTZXQoRGF0YXR5cGVDb25zdGFudHMuRmllbGQgZmllbGQpIjsKLQotICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAotICAgICAgICAgICAgRGF0YXR5cGVNZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UobnVsbCwiVW5rbm93bkZpZWxkIiwgbmV3IE9iamVjdFtde21ldGhvZE5hbWUsIGZpZWxkLnRvU3RyaW5nKCl9KQotICAgICAgICAgICAgICAgICk7Ci0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBPYnRhaW5zIHRoZSB2YWx1ZSBvZiB0aGUgWUVBUlMgZmllbGQgYXMgYW4gaW50ZWdlciB2YWx1ZSwKLSAgICAgKiBvciAwIGlmIG5vdCBwcmVzZW50LgotICAgICAqCi0gICAgICogPHA+Ci0gICAgICogVGhpcyBtZXRob2QgaXMgYSBjb252ZW5pZW5jZSBtZXRob2QgYXJvdW5kIHRoZQotICAgICAqIHtAbGluayAjZ2V0RmllbGQoRGF0YXR5cGVDb25zdGFudHMuRmllbGQpfSBtZXRob2QuCi0gICAgICoKLSAgICAgKiA8cD4KLSAgICAgKiBOb3RlIHRoYXQgc2luY2UgdGhpcyBtZXRob2QgcmV0dXJucyA8dHQ+aW50PC90dD4sIHRoaXMKLSAgICAgKiBtZXRob2Qgd2lsbCByZXR1cm4gYW4gaW5jb3JyZWN0IHZhbHVlIGZvciB7QGxpbmsgRHVyYXRpb259cwotICAgICAqIHdpdGggdGhlIHllYXIgZmllbGQgdGhhdCBnb2VzIGJleW9uZCB0aGUgcmFuZ2Ugb2YgPHR0PmludDwvdHQ+LgotICAgICAqIFVzZSA8Y29kZT5nZXRGaWVsZChZRUFSUyk8L2NvZGU+IHRvIGF2b2lkIHBvc3NpYmxlIGxvc3Mgb2YgcHJlY2lzaW9uLjwvcD4KLSAgICAgKgotICAgICAqIEByZXR1cm4KLSAgICAgKiAgICAgIElmIHRoZSBZRUFSUyBmaWVsZCBpcyBwcmVzZW50LCByZXR1cm4KLSAgICAgKiAgICAgIGl0cyB2YWx1ZSBhcyBhbiBpbnRlZ2VyIGJ5IHVzaW5nIHRoZSB7QGxpbmsgTnVtYmVyI2ludFZhbHVlKCl9Ci0gICAgICogICAgICBtZXRob2QuIElmIHRoZSBZRUFSUyBmaWVsZCBpcyBub3QgcHJlc2VudCwgcmV0dXJuIDAuCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRZZWFycygpIHsKLSAgICAgICAgcmV0dXJuIGdldEludChEYXRhdHlwZUNvbnN0YW50cy5ZRUFSUyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogT2J0YWlucyB0aGUgdmFsdWUgb2YgdGhlIE1PTlRIUyBmaWVsZCBhcyBhbiBpbnRlZ2VyIHZhbHVlLAotICAgICAqIG9yIDAgaWYgbm90IHByZXNlbnQuCi0gICAgICoKLSAgICAgKiBUaGlzIG1ldGhvZCB3b3JrcyBqdXN0IGxpa2Uge0BsaW5rICNnZXRZZWFycygpfSBleGNlcHQKLSAgICAgKiB0aGF0IHRoaXMgbWV0aG9kIHdvcmtzIG9uIHRoZSBNT05USFMgZmllbGQuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIE1vbnRocyBvZiB0aGlzIDxjb2RlPkR1cmF0aW9uPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldE1vbnRocygpIHsKLSAgICAgICAgcmV0dXJuIGdldEludChEYXRhdHlwZUNvbnN0YW50cy5NT05USFMpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIE9idGFpbnMgdGhlIHZhbHVlIG9mIHRoZSBEQVlTIGZpZWxkIGFzIGFuIGludGVnZXIgdmFsdWUsCi0gICAgICogb3IgMCBpZiBub3QgcHJlc2VudC4KLSAgICAgKgotICAgICAqIFRoaXMgbWV0aG9kIHdvcmtzIGp1c3QgbGlrZSB7QGxpbmsgI2dldFllYXJzKCl9IGV4Y2VwdAotICAgICAqIHRoYXQgdGhpcyBtZXRob2Qgd29ya3Mgb24gdGhlIERBWVMgZmllbGQuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIERheXMgb2YgdGhpcyA8Y29kZT5EdXJhdGlvbjwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXREYXlzKCkgewotICAgICAgICByZXR1cm4gZ2V0SW50KERhdGF0eXBlQ29uc3RhbnRzLkRBWVMpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIE9idGFpbnMgdGhlIHZhbHVlIG9mIHRoZSBIT1VSUyBmaWVsZCBhcyBhbiBpbnRlZ2VyIHZhbHVlLAotICAgICAqIG9yIDAgaWYgbm90IHByZXNlbnQuCi0gICAgICoKLSAgICAgKiBUaGlzIG1ldGhvZCB3b3JrcyBqdXN0IGxpa2Uge0BsaW5rICNnZXRZZWFycygpfSBleGNlcHQKLSAgICAgKiB0aGF0IHRoaXMgbWV0aG9kIHdvcmtzIG9uIHRoZSBIT1VSUyBmaWVsZC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gSG91cnMgb2YgdGhpcyA8Y29kZT5EdXJhdGlvbjwvY29kZT4uCi0gICAgICoKLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldEhvdXJzKCkgewotICAgICAgICByZXR1cm4gZ2V0SW50KERhdGF0eXBlQ29uc3RhbnRzLkhPVVJTKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBPYnRhaW5zIHRoZSB2YWx1ZSBvZiB0aGUgTUlOVVRFUyBmaWVsZCBhcyBhbiBpbnRlZ2VyIHZhbHVlLAotICAgICAqIG9yIDAgaWYgbm90IHByZXNlbnQuCi0gICAgICoKLSAgICAgKiBUaGlzIG1ldGhvZCB3b3JrcyBqdXN0IGxpa2Uge0BsaW5rICNnZXRZZWFycygpfSBleGNlcHQKLSAgICAgKiB0aGF0IHRoaXMgbWV0aG9kIHdvcmtzIG9uIHRoZSBNSU5VVEVTIGZpZWxkLgotICAgICAqCi0gICAgICogQHJldHVybiBNaW51dGVzIG9mIHRoaXMgPGNvZGU+RHVyYXRpb248L2NvZGU+LgotICAgICAqCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRNaW51dGVzKCkgewotICAgICAgICByZXR1cm4gZ2V0SW50KERhdGF0eXBlQ29uc3RhbnRzLk1JTlVURVMpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIE9idGFpbnMgdGhlIHZhbHVlIG9mIHRoZSBTRUNPTkRTIGZpZWxkIGFzIGFuIGludGVnZXIgdmFsdWUsCi0gICAgICogb3IgMCBpZiBub3QgcHJlc2VudC4KLSAgICAgKgotICAgICAqIFRoaXMgbWV0aG9kIHdvcmtzIGp1c3QgbGlrZSB7QGxpbmsgI2dldFllYXJzKCl9IGV4Y2VwdAotICAgICAqIHRoYXQgdGhpcyBtZXRob2Qgd29ya3Mgb24gdGhlIFNFQ09ORFMgZmllbGQuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHNlY29uZHMgaW4gdGhlIGludGVnZXIgdmFsdWUuIFRoZSBmcmFjdGlvbiBvZiBzZWNvbmRzCi0gICAgICogICB3aWxsIGJlIGRpc2NhcmRlZCAoZm9yIGV4YW1wbGUsIGlmIHRoZSBhY3R1YWwgdmFsdWUgaXMgMi41LAotICAgICAqICAgdGhpcyBtZXRob2QgcmV0dXJucyAyKQotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0U2Vjb25kcygpIHsKLSAgICAgICAgcmV0dXJuIGdldEludChEYXRhdHlwZUNvbnN0YW50cy5TRUNPTkRTKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5SZXR1cm4gdGhlIHJlcXVlc3RlZCBmaWVsZCB2YWx1ZSBhcyBhbiBpbnQuPC9wPgotICAgICAqCi0gICAgICogPHA+SWYgZmllbGQgaXMgbm90IHNldCwgaS5lLiA9PSBudWxsLCAwIGlzIHJldHVybmVkLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBmaWVsZCBUbyBnZXQgdmFsdWUgZm9yLgotICAgICAqCi0gICAgICogQHJldHVybiBpbnQgdmFsdWUgb2YgZmllbGQgb3IgMCBpZiBmaWVsZCBpcyBub3Qgc2V0LgotICAgICAqLwotICAgIHByaXZhdGUgaW50IGdldEludChEYXRhdHlwZUNvbnN0YW50cy5GaWVsZCBmaWVsZCkgewotICAgICAgICBOdW1iZXIgbiA9IGdldEZpZWxkKGZpZWxkKTsKLSAgICAgICAgaWYgKG4gPT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIDA7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gbi5pbnRWYWx1ZSgpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+UmV0dXJucyB0aGUgbGVuZ3RoIG9mIHRoZSBkdXJhdGlvbiBpbiBtaWxsaS1zZWNvbmRzLjwvcD4KLSAgICAgKgotICAgICAqIDxwPklmIHRoZSBzZWNvbmRzIGZpZWxkIGNhcnJpZXMgbW9yZSBkaWdpdHMgdGhhbiBtaWxsaS1zZWNvbmQgb3JkZXIsCi0gICAgICogdGhvc2Ugd2lsbCBiZSBzaW1wbHkgZGlzY2FyZGVkIChvciBpbiBvdGhlciB3b3Jkcywgcm91bmRlZCB0byB6ZXJvLikKLSAgICAgKiBGb3IgZXhhbXBsZSwgZm9yIGFueSBDYWxlbmRhciB2YWx1ZSA8Y29kZT54PGNvZGU+LDwvcD4KLSAgICAgKiA8cHJlPgotICAgICAqIDxjb2RlPm5ldyBEdXJhdGlvbigiUFQxMC4wMDA5OVMiKS5nZXRUaW1lSW5NaWxscyh4KSA9PSAxMDAwMDwvY29kZT4uCi0gICAgICogPGNvZGU+bmV3IER1cmF0aW9uKCItUFQxMC4wMDA5OVMiKS5nZXRUaW1lSW5NaWxscyh4KSA9PSAtMTAwMDA8L2NvZGU+LgotICAgICAqIDwvcHJlPgotICAgICAqCi0gICAgICogPHA+Ci0gICAgICogTm90ZSB0aGF0IHRoaXMgbWV0aG9kIHVzZXMgdGhlIHtAbGluayAjYWRkVG8oQ2FsZW5kYXIpfSBtZXRob2QsCi0gICAgICogd2hpY2ggbWF5IHdvcmsgaW5jb3JlY3RseSB3aXRoIHtAbGluayBEdXJhdGlvbn0gb2JqZWN0cyB3aXRoCi0gICAgICogdmVyeSBsYXJnZSB2YWx1ZXMgaW4gaXRzIGZpZWxkcy4gU2VlIHRoZSB7QGxpbmsgI2FkZFRvKENhbGVuZGFyKX0KLSAgICAgKiBtZXRob2QgZm9yIGRldGFpbHMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc3RhcnRJbnN0YW50Ci0gICAgICogICAgICBUaGUgbGVuZ3RoIG9mIGEgbW9udGgveWVhciB2YXJpZXMuIFRoZSA8Y29kZT5zdGFydEluc3RhbnQ8L2NvZGU+IGlzCi0gICAgICogICAgICB1c2VkIHRvIGRpc2FtYmlndWF0ZSB0aGlzIHZhcmlhbmNlLiBTcGVjaWZpY2FsbHksIHRoaXMgbWV0aG9kCi0gICAgICogICAgICByZXR1cm5zIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gPGNvZGU+c3RhcnRJbnN0YW50PC9jb2RlPiBhbmQKLSAgICAgKiAgICAgIDxjb2RlPnN0YXJ0SW5zdGFudCtkdXJhdGlvbjwvY29kZT4KLSAgICAgKgotICAgICAqIEByZXR1cm4gbWlsbGlzZWNvbmRzIGJldHdlZW4gPGNvZGU+c3RhcnRJbnN0YW50PC9jb2RlPiBhbmQKLSAgICAgKiAgIDxjb2RlPnN0YXJ0SW5zdGFudDwvY29kZT4gcGx1cyB0aGlzIDxjb2RlPkR1cmF0aW9uPC9jb2RlPgotICAgICAqCi0gICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiA8Y29kZT5zdGFydEluc3RhbnQ8L2NvZGU+IHBhcmFtZXRlcgotICAgICAqIGlzIG51bGwuCi0gICAgICoKLSAgICAgKi8KLSAgICBwdWJsaWMgbG9uZyBnZXRUaW1lSW5NaWxsaXMoZmluYWwgQ2FsZW5kYXIgc3RhcnRJbnN0YW50KSB7Ci0gICAgICAgIENhbGVuZGFyIGNhbCA9IChDYWxlbmRhcikgc3RhcnRJbnN0YW50LmNsb25lKCk7Ci0gICAgICAgIGFkZFRvKGNhbCk7Ci0gICAgICAgIHJldHVybiBnZXRDYWxlbmRhclRpbWVJbk1pbGxpcyhjYWwpCi0gICAgICAgICAgICAgICAgICAgIC0gZ2V0Q2FsZW5kYXJUaW1lSW5NaWxsaXMoc3RhcnRJbnN0YW50KTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5SZXR1cm5zIHRoZSBsZW5ndGggb2YgdGhlIGR1cmF0aW9uIGluIG1pbGxpLXNlY29uZHMuPC9wPgotICAgICAqCi0gICAgICogPHA+SWYgdGhlIHNlY29uZHMgZmllbGQgY2FycmllcyBtb3JlIGRpZ2l0cyB0aGFuIG1pbGxpLXNlY29uZCBvcmRlciwKLSAgICAgKiB0aG9zZSB3aWxsIGJlIHNpbXBseSBkaXNjYXJkZWQgKG9yIGluIG90aGVyIHdvcmRzLCByb3VuZGVkIHRvIHplcm8uKQotICAgICAqIEZvciBleGFtcGxlLCBmb3IgYW55IDxjb2RlPkRhdGU8L2NvZGU+IHZhbHVlIDxjb2RlPng8Y29kZT4sPC9wPgotICAgICAqIDxwcmU+Ci0gICAgICogPGNvZGU+bmV3IER1cmF0aW9uKCJQVDEwLjAwMDk5UyIpLmdldFRpbWVJbk1pbGxzKHgpID09IDEwMDAwPC9jb2RlPi4KLSAgICAgKiA8Y29kZT5uZXcgRHVyYXRpb24oIi1QVDEwLjAwMDk5UyIpLmdldFRpbWVJbk1pbGxzKHgpID09IC0xMDAwMDwvY29kZT4uCi0gICAgICogPC9wcmU+Ci0gICAgICoKLSAgICAgKiA8cD4KLSAgICAgKiBOb3RlIHRoYXQgdGhpcyBtZXRob2QgdXNlcyB0aGUge0BsaW5rICNhZGRUbyhEYXRlKX0gbWV0aG9kLAotICAgICAqIHdoaWNoIG1heSB3b3JrIGluY29yZWN0bHkgd2l0aCB7QGxpbmsgRHVyYXRpb259IG9iamVjdHMgd2l0aAotICAgICAqIHZlcnkgbGFyZ2UgdmFsdWVzIGluIGl0cyBmaWVsZHMuIFNlZSB0aGUge0BsaW5rICNhZGRUbyhEYXRlKX0KLSAgICAgKiBtZXRob2QgZm9yIGRldGFpbHMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc3RhcnRJbnN0YW50Ci0gICAgICogICAgICBUaGUgbGVuZ3RoIG9mIGEgbW9udGgveWVhciB2YXJpZXMuIFRoZSA8Y29kZT5zdGFydEluc3RhbnQ8L2NvZGU+IGlzCi0gICAgICogICAgICB1c2VkIHRvIGRpc2FtYmlndWF0ZSB0aGlzIHZhcmlhbmNlLiBTcGVjaWZpY2FsbHksIHRoaXMgbWV0aG9kCi0gICAgICogICAgICByZXR1cm5zIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gPGNvZGU+c3RhcnRJbnN0YW50PC9jb2RlPiBhbmQKLSAgICAgKiAgICAgIDxjb2RlPnN0YXJ0SW5zdGFudCtkdXJhdGlvbjwvY29kZT4uCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCi0gICAgICogICAgICBJZiB0aGUgc3RhcnRJbnN0YW50IHBhcmFtZXRlciBpcyBudWxsLgotICAgICAqCi0gICAgICogQHJldHVybiBtaWxsaXNlY29uZHMgYmV0d2VlbiA8Y29kZT5zdGFydEluc3RhbnQ8L2NvZGU+IGFuZAotICAgICAqICAgPGNvZGU+c3RhcnRJbnN0YW50PC9jb2RlPiBwbHVzIHRoaXMgPGNvZGU+RHVyYXRpb248L2NvZGU+Ci0gICAgICoKLSAgICAgKiBAc2VlICNnZXRUaW1lSW5NaWxsaXMoQ2FsZW5kYXIpCi0gICAgICovCi0gICAgcHVibGljIGxvbmcgZ2V0VGltZUluTWlsbGlzKGZpbmFsIERhdGUgc3RhcnRJbnN0YW50KSB7Ci0gICAgICAgIENhbGVuZGFyIGNhbCA9IG5ldyBHcmVnb3JpYW5DYWxlbmRhcigpOwotICAgICAgICBjYWwuc2V0VGltZShzdGFydEluc3RhbnQpOwotICAgICAgICB0aGlzLmFkZFRvKGNhbCk7Ci0gICAgICAgIHJldHVybiBnZXRDYWxlbmRhclRpbWVJbk1pbGxpcyhjYWwpIC0gc3RhcnRJbnN0YW50LmdldFRpbWUoKTsKLSAgICB9Ci0KLS8vICAgIC8qKgotLy8gICAgICogUmV0dXJucyBhbiBlcXVpdmFsZW50IGJ1dCAibm9ybWFsaXplZCIgZHVyYXRpb24gdmFsdWUuCi0vLyAgICAgKgotLy8gICAgICogSW50dWl0aXZlbHksIHRoZSBub3JtYWxpemF0aW9uIG1vdmVzIFlFQVJTIGludG8KLS8vICAgICAqIE1PTlRIUyAoYnkgeDEyKSBhbmQgbW92ZXMgREFZUywgSE9VUlMsIGFuZCBNSU5VVEVTIGZpZWxkcwotLy8gICAgICogaW50byBTRUNPTkRTIChieSB4ODY0MDAsIHgzNjAwLCBhbmQgeDYwIHJlc3BlY3RpdmVseS4pCi0vLyAgICAgKgotLy8gICAgICoKLS8vICAgICAqIEZvcm1hbGx5LCB0aGlzIG1ldGhvZCBzYXRpc2ZpZXMgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgotLy8gICAgICogPHVsPgotLy8gICAgICogIDxsaT54Lm5vcm1hbGl6ZSgpLmVxdWFscyh4KQotLy8gICAgICogIDxsaT4heC5ub3JtYWxpemUoKS5pc1NldChEdXJhdGlvbi5ZRUFSUykKLS8vICAgICAqICA8bGk+IXgubm9ybWFsaXplKCkuaXNTZXQoRHVyYXRpb24uREFZUykKLS8vICAgICAqICA8bGk+IXgubm9ybWFsaXplKCkuaXNTZXQoRHVyYXRpb24uSE9VUlMpCi0vLyAgICAgKiAgPGxpPiF4Lm5vcm1hbGl6ZSgpLmlzU2V0KER1cmF0aW9uLk1JTlVURVMpCi0vLyAgICAgKiA8L3VsPgotLy8gICAgICoKLS8vICAgICAqIEByZXR1cm4KLS8vICAgICAqICAgICAgYWx3YXlzIHJldHVybiBhIG5vbi1udWxsIHZhbGlkIHZhbHVlLgotLy8gICAgICovCi0vLyAgICBwdWJsaWMgRHVyYXRpb24gbm9ybWFsaXplKCkgewotLy8gICAgICAgIHJldHVybiBudWxsOwotLy8gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+Q29udmVydHMgdGhlIHllYXJzIGFuZCBtb250aHMgZmllbGRzIGludG8gdGhlIGRheXMgZmllbGQKLSAgICAgKiBieSB1c2luZyBhIHNwZWNpZmljIHRpbWUgaW5zdGFudCBhcyB0aGUgcmVmZXJlbmNlIHBvaW50LjwvcD4KLSAgICAgKgotICAgICAqIDxwPkZvciBleGFtcGxlLCBkdXJhdGlvbiBvZiBvbmUgbW9udGggbm9ybWFsaXplcyB0byAzMSBkYXlzCi0gICAgICogZ2l2ZW4gdGhlIHN0YXJ0IHRpbWUgaW5zdGFuY2UgIkp1bHkgOHRoIDIwMDMsIDE3OjQwOjMyIi48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5Gb3JtYWxseSwgdGhlIGNvbXB1dGF0aW9uIGlzIGRvbmUgYXMgZm9sbG93czo8L3A+Ci0gICAgICogPG9sPgotICAgICAqICA8bGk+VGhlIGdpdmVuIENhbGVuZGFyIG9iamVjdCBpcyBjbG9uZWQuCi0gICAgICogIDxsaT5UaGUgeWVhcnMsIG1vbnRocyBhbmQgZGF5cyBmaWVsZHMgd2lsbCBiZSBhZGRlZCB0bwotICAgICAqICAgICAgdGhlIHtAbGluayBDYWxlbmRhcn0gb2JqZWN0Ci0gICAgICogICAgICBieSB1c2luZyB0aGUge0BsaW5rIENhbGVuZGFyI2FkZChpbnQsaW50KX0gbWV0aG9kLgotICAgICAqICA8bGk+VGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0d28gQ2FsZW5kYXJzIGFyZSBjb21wdXRlZCBpbiB0ZXJtcyBvZiBkYXlzLgotICAgICAqICA8bGk+VGhlIGNvbXB1dGVkIGRheXMsIGFsb25nIHdpdGggdGhlIGhvdXJzLCBtaW51dGVzIGFuZCBzZWNvbmRzCi0gICAgICogICAgICBmaWVsZHMgb2YgdGhpcyBkdXJhdGlvbiBvYmplY3QgaXMgdXNlZCB0byBjb25zdHJ1Y3QgYSBuZXcKLSAgICAgKiAgICAgIER1cmF0aW9uIG9iamVjdC4KLSAgICAgKiA8L29sPgotICAgICAqCi0gICAgICogPHA+Tm90ZSB0aGF0IHNpbmNlIHRoZSBDYWxlbmRhciBjbGFzcyB1c2VzIDxjb2RlPmludDwvY29kZT4gdG8KLSAgICAgKiBob2xkIHRoZSB2YWx1ZSBvZiB5ZWFyIGFuZCBtb250aCwgdGhpcyBtZXRob2QgbWF5IHByb2R1Y2UKLSAgICAgKiBhbiB1bmV4cGVjdGVkIHJlc3VsdCBpZiB0aGlzIGR1cmF0aW9uIG9iamVjdCBob2xkcwotICAgICAqIGEgdmVyeSBsYXJnZSB2YWx1ZSBpbiB0aGUgeWVhcnMgb3IgbW9udGhzIGZpZWxkcy48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gc3RhcnRUaW1lSW5zdGFudCA8Y29kZT5DYWxlbmRhcjwvY29kZT4gcmVmZXJlbmNlIHBvaW50LgotICAgICAqCi0gICAgICogQHJldHVybiA8Y29kZT5EdXJhdGlvbjwvY29kZT4gb2YgeWVhcnMgYW5kIG1vbnRocyBvZiB0aGlzIDxjb2RlPkR1cmF0aW9uPC9jb2RlPiBhcyBkYXlzLgotICAgICAqCi0gICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBJZiB0aGUgc3RhcnRUaW1lSW5zdGFudCBwYXJhbWV0ZXIgaXMgbnVsbC4KLSAgICAgKi8KLSAgICBwdWJsaWMgRHVyYXRpb24gbm9ybWFsaXplV2l0aChDYWxlbmRhciBzdGFydFRpbWVJbnN0YW50KSB7Ci0KLSAgICAgICAgQ2FsZW5kYXIgYyA9IChDYWxlbmRhcikgc3RhcnRUaW1lSW5zdGFudC5jbG9uZSgpOwotCi0gICAgICAgIC8vIHVzaW5nIGludCBtYXkgY2F1c2Ugb3ZlcmZsb3csIGJ1dAotICAgICAgICAvLyBDYWxlbmRhciBpbnRlcm5hbGx5IHRyZWF0cyB2YWx1ZSBhcyBpbnQgYW55d2F5cy4KLSAgICAgICAgYy5hZGQoQ2FsZW5kYXIuWUVBUiwgZ2V0WWVhcnMoKSAqIHNpZ251bSk7Ci0gICAgICAgIGMuYWRkKENhbGVuZGFyLk1PTlRILCBnZXRNb250aHMoKSAqIHNpZ251bSk7Ci0gICAgICAgIGMuYWRkKENhbGVuZGFyLkRBWV9PRl9NT05USCwgZ2V0RGF5cygpICogc2lnbnVtKTsKLQotICAgICAgICAvLyBvYnRhaW4gdGhlIGRpZmZlcmVuY2UgaW4gdGVybXMgb2YgZGF5cwotICAgICAgICBsb25nIGRpZmYgPSBnZXRDYWxlbmRhclRpbWVJbk1pbGxpcyhjKSAtIGdldENhbGVuZGFyVGltZUluTWlsbGlzKHN0YXJ0VGltZUluc3RhbnQpOwotICAgICAgICBpbnQgZGF5cyA9IChpbnQpIChkaWZmIC8gKDEwMDBMICogNjBMICogNjBMICogMjRMKSk7Ci0KLSAgICAgICAgcmV0dXJuIG5ldyBEdXJhdGlvbkltcGwoCi0gICAgICAgICAgICBkYXlzID49IDAsCi0gICAgICAgICAgICBudWxsLAotICAgICAgICAgICAgbnVsbCwKLSAgICAgICAgICAgIHdyYXAoTWF0aC5hYnMoZGF5cykpLAotICAgICAgICAgICAgKEJpZ0ludGVnZXIpIGdldEZpZWxkKERhdGF0eXBlQ29uc3RhbnRzLkhPVVJTKSwKLSAgICAgICAgICAgIChCaWdJbnRlZ2VyKSBnZXRGaWVsZChEYXRhdHlwZUNvbnN0YW50cy5NSU5VVEVTKSwKLSAgICAgICAgICAgIChCaWdEZWNpbWFsKSBnZXRGaWVsZChEYXRhdHlwZUNvbnN0YW50cy5TRUNPTkRTKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+Q29tcHV0ZXMgYSBuZXcgZHVyYXRpb24gd2hvc2UgdmFsdWUgaXMgPGNvZGU+ZmFjdG9yPC9jb2RlPiB0aW1lcwotICAgICAqIGxvbmdlciB0aGFuIHRoZSB2YWx1ZSBvZiB0aGlzIGR1cmF0aW9uLjwvcD4KLSAgICAgKgotICAgICAqIDxwPlRoaXMgbWV0aG9kIGlzIHByb3ZpZGVkIGZvciB0aGUgY29udmVuaWVuY2UuCi0gICAgICogSXQgaXMgZnVuY3Rpb25hbGx5IGVxdWl2YWxlbnQgdG8gdGhlIGZvbGxvd2luZyBjb2RlOjwvcD4KLSAgICAgKiA8cHJlPgotICAgICAqIG11bHRpcGx5KG5ldyBCaWdEZWNpbWFsKFN0cmluZy52YWx1ZU9mKGZhY3RvcikpKQotICAgICAqIDwvcHJlPgotICAgICAqCi0gICAgICogQHBhcmFtIGZhY3RvciBGYWN0b3IgdGltZXMgbG9uZ2VyIG9mIG5ldyA8Y29kZT5EdXJhdGlvbjwvY29kZT4gdG8gY3JlYXRlLgotICAgICAqCi0gICAgICogQHJldHVybiBOZXcgPGNvZGU+RHVyYXRpb248L2NvZGU+IHRoYXQgaXMgPGNvZGU+ZmFjdG9yPC9jb2RlPnRpbWVzIGxvbmdlciB0aGFuIHRoaXMgPGNvZGU+RHVyYXRpb248L2NvZGU+LgotICAgICAqCi0gICAgICogQHNlZSAjbXVsdGlwbHkoQmlnRGVjaW1hbCkKLSAgICAgKi8KLSAgICBwdWJsaWMgRHVyYXRpb24gbXVsdGlwbHkoaW50IGZhY3RvcikgewotICAgICAgICByZXR1cm4gbXVsdGlwbHkoQmlnRGVjaW1hbC52YWx1ZU9mKGZhY3RvcikpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbXB1dGVzIGEgbmV3IGR1cmF0aW9uIHdob3NlIHZhbHVlIGlzIDxjb2RlPmZhY3RvcjwvY29kZT4gdGltZXMKLSAgICAgKiBsb25nZXIgdGhhbiB0aGUgdmFsdWUgb2YgdGhpcyBkdXJhdGlvbi4KLSAgICAgKgotICAgICAqIDxwPgotICAgICAqIEZvciBleGFtcGxlLAotICAgICAqIDxwcmU+Ci0gICAgICogIlAxTSIgKDEgbW9udGgpICogIjEyIiA9ICJQMTJNIiAoMTIgbW9udGhzKQotICAgICAqICJQVDFNIiAoMSBtaW4pICogIjAuMyIgPSAiUFQxOFMiICgxOCBzZWNvbmRzKQotICAgICAqICJQMU0iICgxIG1vbnRoKSAqICIxLjUiID0gSWxsZWdhbFN0YXRlRXhjZXB0aW9uCi0gICAgICogPC9wcmU+Ci0gICAgICoKLSAgICAgKiA8cD4KLSAgICAgKiBTaW5jZSB0aGUge0BsaW5rIER1cmF0aW9ufSBjbGFzcyBpcyBpbW11dGFibGUsIHRoaXMgbWV0aG9kCi0gICAgICogZG9lc24ndCBjaGFuZ2UgdGhlIHZhbHVlIG9mIHRoaXMgb2JqZWN0LiBJdCBzaW1wbHkgY29tcHV0ZXMKLSAgICAgKiBhIG5ldyBEdXJhdGlvbiBvYmplY3QgYW5kIHJldHVybnMgaXQuCi0gICAgICoKLSAgICAgKiA8cD4KLSAgICAgKiBUaGUgb3BlcmF0aW9uIHdpbGwgYmUgcGVyZm9ybWVkIGZpZWxkIGJ5IGZpZWxkIHdpdGggdGhlIHByZWNpc2lvbgotICAgICAqIG9mIHtAbGluayBCaWdEZWNpbWFsfS4gU2luY2UgYWxsIHRoZSBmaWVsZHMgZXhjZXB0IHNlY29uZHMgYXJlCi0gICAgICogcmVzdHJpY3RlZCB0byBob2xkIGludGVnZXJzLAotICAgICAqIGFueSBmcmFjdGlvbiBwcm9kdWNlZCBieSB0aGUgY29tcHV0YXRpb24gd2lsbCBiZQotICAgICAqIGNhcnJpZWQgZG93biB0b3dhcmQgdGhlIG5leHQgbG93ZXIgdW5pdC4gRm9yIGV4YW1wbGUsCi0gICAgICogaWYgeW91IG11bHRpcGx5ICJQMUQiICgxIGRheSkgd2l0aCAiMC41IiwgdGhlbiBpdCB3aWxsIGJlIDAuNSBkYXksCi0gICAgICogd2hpY2ggd2lsbCBiZSBjYXJyaWVkIGRvd24gdG8gIlBUMTJIIiAoMTIgaG91cnMpLgotICAgICAqIFdoZW4gZnJhY3Rpb25zIG9mIG1vbnRoIGNhbm5vdCBiZSBtZWFuaW5nZnVsbHkgY2FycmllZCBkb3duCi0gICAgICogdG8gZGF5cywgb3IgeWVhciB0byBtb250aHMsIHRoaXMgd2lsbCBjYXVzZSBhbgotICAgICAqIHtAbGluayBJbGxlZ2FsU3RhdGVFeGNlcHRpb259IHRvIGJlIHRocm93bi4KLSAgICAgKiBGb3IgZXhhbXBsZSBpZiB5b3UgbXVsdGlwbGUgb25lIG1vbnRoIGJ5IDAuNS48L3A+Ci0gICAgICoKLSAgICAgKiA8cD4KLSAgICAgKiBUbyBhdm9pZCB7QGxpbmsgSWxsZWdhbFN0YXRlRXhjZXB0aW9ufSwgdXNlCi0gICAgICogdGhlIHtAbGluayAjbm9ybWFsaXplV2l0aChDYWxlbmRhcil9IG1ldGhvZCB0byByZW1vdmUgdGhlIHllYXJzCi0gICAgICogYW5kIG1vbnRocyBmaWVsZHMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZmFjdG9yIHRvIG11bHRpcGx5IGJ5Ci0gICAgICoKLSAgICAgKiBAcmV0dXJuCi0gICAgICogICAgICByZXR1cm5zIGEgbm9uLW51bGwgdmFsaWQge0BsaW5rIER1cmF0aW9ufSBvYmplY3QKLSAgICAgKgotICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIG9wZXJhdGlvbiBwcm9kdWNlcyBmcmFjdGlvbiBpbgotICAgICAqIHRoZSBtb250aHMgZmllbGQuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSA8Y29kZT5mYWN0b3I8L2NvZGU+IHBhcmFtZXRlciBpcwotICAgICAqIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAqCi0gICAgICovCi0gICAgcHVibGljIER1cmF0aW9uIG11bHRpcGx5KEJpZ0RlY2ltYWwgZmFjdG9yKSB7Ci0gICAgICAgIEJpZ0RlY2ltYWwgY2FycnkgPSBaRVJPOwotICAgICAgICBpbnQgZmFjdG9yU2lnbiA9IGZhY3Rvci5zaWdudW0oKTsKLSAgICAgICAgZmFjdG9yID0gZmFjdG9yLmFicygpOwotCi0gICAgICAgIEJpZ0RlY2ltYWxbXSBidWYgPSBuZXcgQmlnRGVjaW1hbFs2XTsKLQotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDU7IGkrKykgewotICAgICAgICAgICAgQmlnRGVjaW1hbCBiZCA9IGdldEZpZWxkQXNCaWdEZWNpbWFsKEZJRUxEU1tpXSk7Ci0gICAgICAgICAgICBiZCA9IGJkLm11bHRpcGx5KGZhY3RvcikuYWRkKGNhcnJ5KTsKLQotICAgICAgICAgICAgYnVmW2ldID0gYmQuc2V0U2NhbGUoMCwgQmlnRGVjaW1hbC5ST1VORF9ET1dOKTsKLQotICAgICAgICAgICAgYmQgPSBiZC5zdWJ0cmFjdChidWZbaV0pOwotICAgICAgICAgICAgaWYgKGkgPT0gMSkgewotICAgICAgICAgICAgICAgIGlmIChiZC5zaWdudW0oKSAhPSAwKSB7Ci0gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oKTsgLy8gaWxsZWdhbCBjYXJyeS1kb3duCi0gICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgY2FycnkgPSBaRVJPOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgY2FycnkgPSBiZC5tdWx0aXBseShGQUNUT1JTW2ldKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGlmIChzZWNvbmRzICE9IG51bGwpIHsKLSAgICAgICAgICAgIGJ1Zls1XSA9IHNlY29uZHMubXVsdGlwbHkoZmFjdG9yKS5hZGQoY2FycnkpOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgYnVmWzVdID0gY2Fycnk7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gbmV3IER1cmF0aW9uSW1wbCgKLSAgICAgICAgICAgIHRoaXMuc2lnbnVtICogZmFjdG9yU2lnbiA+PSAwLAotICAgICAgICAgICAgdG9CaWdJbnRlZ2VyKGJ1ZlswXSwgbnVsbCA9PSB5ZWFycyksCi0gICAgICAgICAgICB0b0JpZ0ludGVnZXIoYnVmWzFdLCBudWxsID09IG1vbnRocyksCi0gICAgICAgICAgICB0b0JpZ0ludGVnZXIoYnVmWzJdLCBudWxsID09IGRheXMpLAotICAgICAgICAgICAgdG9CaWdJbnRlZ2VyKGJ1ZlszXSwgbnVsbCA9PSBob3VycyksCi0gICAgICAgICAgICB0b0JpZ0ludGVnZXIoYnVmWzRdLCBudWxsID09IG1pbnV0ZXMpLAotICAgICAgICAgICAgKGJ1Zls1XS5zaWdudW0oKSA9PSAwICYmIHNlY29uZHMgPT0gbnVsbCkgPyBudWxsIDogYnVmWzVdKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5HZXRzIHRoZSB2YWx1ZSBvZiB0aGUgZmllbGQgYXMgYSB7QGxpbmsgQmlnRGVjaW1hbH0uPC9wPgotICAgICAqCi0gICAgICogPHA+SWYgdGhlIGZpZWxkIGlzIHVuc2V0LCByZXR1cm4gMC48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gZiBGaWVsZCB0byBnZXQgdmFsdWUgZm9yLgotICAgICAqCi0gICAgICogQHJldHVybiAgbm9uLW51bGwgdmFsaWQge0BsaW5rIEJpZ0RlY2ltYWx9LgotICAgICAqLwotICAgIHByaXZhdGUgQmlnRGVjaW1hbCBnZXRGaWVsZEFzQmlnRGVjaW1hbChEYXRhdHlwZUNvbnN0YW50cy5GaWVsZCBmKSB7Ci0gICAgICAgIGlmIChmID09IERhdGF0eXBlQ29uc3RhbnRzLlNFQ09ORFMpIHsKLSAgICAgICAgICAgIGlmIChzZWNvbmRzICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gc2Vjb25kczsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIFpFUk87Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBCaWdJbnRlZ2VyIGJpID0gKEJpZ0ludGVnZXIpIGdldEZpZWxkKGYpOwotICAgICAgICAgICAgaWYgKGJpID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gWkVSTzsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBCaWdEZWNpbWFsKGJpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPkJpZ0ludGVnZXIgdmFsdWUgb2YgQmlnRGVjaW1hbCB2YWx1ZS48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gdmFsdWUgVmFsdWUgdG8gY29udmVydC4KLSAgICAgKiBAcGFyYW0gY2FuQmVOdWxsIENhbiByZXR1cm5lZCB2YWx1ZSBiZSBudWxsPwotICAgICAqCi0gICAgICogQHJldHVybiBCaWdJbnRlZ2VyIHZhbHVlIG9mIEJpZ0RlY2ltYWwsIHBvc3NpYmx5IG51bGwuCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgQmlnSW50ZWdlciB0b0JpZ0ludGVnZXIoCi0gICAgICAgIEJpZ0RlY2ltYWwgdmFsdWUsCi0gICAgICAgIGJvb2xlYW4gY2FuQmVOdWxsKSB7Ci0gICAgICAgIGlmIChjYW5CZU51bGwgJiYgdmFsdWUuc2lnbnVtKCkgPT0gMCkgewotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gdmFsdWUudW5zY2FsZWRWYWx1ZSgpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogMSB1bml0IG9mIEZJRUxEU1tpXSBpcyBlcXVpdmFsZW50IHRvIDxjb2RlPkZBQ1RPUlNbaV08L2NvZGU+IHVuaXQgb2YKLSAgICAgKiBGSUVMRFNbaSsxXS4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBCaWdEZWNpbWFsW10gRkFDVE9SUyA9IG5ldyBCaWdEZWNpbWFsW117Ci0gICAgICAgIEJpZ0RlY2ltYWwudmFsdWVPZigxMiksCi0gICAgICAgIG51bGwvKnVuZGVmaW5lZCovLAotICAgICAgICBCaWdEZWNpbWFsLnZhbHVlT2YoMjQpLAotICAgICAgICBCaWdEZWNpbWFsLnZhbHVlT2YoNjApLAotICAgICAgICBCaWdEZWNpbWFsLnZhbHVlT2YoNjApCi0gICAgfTsKLQotICAgIC8qKgotICAgICAqIDxwPkNvbXB1dGVzIGEgbmV3IGR1cmF0aW9uIHdob3NlIHZhbHVlIGlzIDxjb2RlPnRoaXMrcmhzPC9jb2RlPi48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5Gb3IgZXhhbXBsZSw8L3A+Ci0gICAgICogPHByZT4KLSAgICAgKiAiMSBkYXkiICsgIi0zIGRheXMiID0gIi0yIGRheXMiCi0gICAgICogIjEgeWVhciIgKyAiMSBkYXkiID0gIjEgeWVhciBhbmQgMSBkYXkiCi0gICAgICogIi0oMSBob3VyLDUwIG1pbnV0ZXMpIiArICItMjAgbWludXRlcyIgPSAiLSgxIGhvdXJzLDcwIG1pbnV0ZXMpIgotICAgICAqICIxNSBob3VycyIgKyAiLTMgZGF5cyIgPSAiLSgyIGRheXMsOSBob3VycykiCi0gICAgICogIjEgeWVhciIgKyAiLTEgZGF5IiA9IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgotICAgICAqIDwvcHJlPgotICAgICAqCi0gICAgICogPHA+U2luY2UgdGhlcmUncyBubyB3YXkgdG8gbWVhbmluZ2Z1bGx5IHN1YnRyYWN0IDEgZGF5IGZyb20gMSBtb250aCwKLSAgICAgKiB0aGVyZSBhcmUgY2FzZXMgd2hlcmUgdGhlIG9wZXJhdGlvbiBmYWlscyBpbgotICAgICAqIHtAbGluayBJbGxlZ2FsU3RhdGVFeGNlcHRpb259LjwvcD4KLSAgICAgKgotICAgICAqIDxwPgotICAgICAqIEZvcm1hbGx5LCB0aGUgY29tcHV0YXRpb24gaXMgZGVmaW5lZCBhcyBmb2xsb3dzLjwvcD4KLSAgICAgKiA8cD4KLSAgICAgKiBGaXJzdGx5LCB3ZSBjYW4gYXNzdW1lIHRoYXQgdHdvIHtAbGluayBEdXJhdGlvbn1zIHRvIGJlIGFkZGVkCi0gICAgICogYXJlIGJvdGggcG9zaXRpdmUgd2l0aG91dCBsb3NpbmcgZ2VuZXJhbGl0eSAoaS5lLiwKLSAgICAgKiA8Y29kZT4oLVgpK1k9WS1YPC9jb2RlPiwgPGNvZGU+WCsoLVkpPVgtWTwvY29kZT4sCi0gICAgICogPGNvZGU+KC1YKSsoLVkpPS0oWCtZKTwvY29kZT4pCi0gICAgICoKLSAgICAgKiA8cD4KLSAgICAgKiBBZGRpdGlvbiBvZiB0d28gcG9zaXRpdmUge0BsaW5rIER1cmF0aW9ufXMgYXJlIHNpbXBseSBkZWZpbmVkIGFzCi0gICAgICogZmllbGQgYnkgZmllbGQgYWRkaXRpb24gd2hlcmUgbWlzc2luZyBmaWVsZHMgYXJlIHRyZWF0ZWQgYXMgMC4KLSAgICAgKiA8cD4KLSAgICAgKiBBIGZpZWxkIG9mIHRoZSByZXN1bHRpbmcge0BsaW5rIER1cmF0aW9ufSB3aWxsIGJlIHVuc2V0IGlmIGFuZAotICAgICAqIG9ubHkgaWYgcmVzcGVjdGl2ZSBmaWVsZHMgb2YgdHdvIGlucHV0IHtAbGluayBEdXJhdGlvbn1zIGFyZSB1bnNldC4KLSAgICAgKiA8cD4KLSAgICAgKiBOb3RlIHRoYXQgPGNvZGU+bGhzLmFkZChyaHMpPC9jb2RlPiB3aWxsIGJlIGFsd2F5cyBzdWNjZXNzZnVsIGlmCi0gICAgICogPGNvZGU+bGhzLnNpZ251bSgpKnJocy5zaWdudW0oKSE9LTE8L2NvZGU+IG9yIGJvdGggb2YgdGhlbSBhcmUKLSAgICAgKiBub3JtYWxpemVkLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSByaHMgPGNvZGU+RHVyYXRpb248L2NvZGU+IHRvIGFkZCB0byB0aGlzIDxjb2RlPkR1cmF0aW9uPC9jb2RlPgotICAgICAqCi0gICAgICogQHJldHVybgotICAgICAqICAgICAgbm9uLW51bGwgdmFsaWQgRHVyYXRpb24gb2JqZWN0LgotICAgICAqCi0gICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgotICAgICAqICAgICAgSWYgdGhlIHJocyBwYXJhbWV0ZXIgaXMgbnVsbC4KLSAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgotICAgICAqICAgICAgSWYgdHdvIGR1cmF0aW9ucyBjYW5ub3QgYmUgbWVhbmluZ2Z1bGx5IGFkZGVkLiBGb3IKLSAgICAgKiAgICAgIGV4YW1wbGUsIGFkZGluZyBuZWdhdGl2ZSBvbmUgZGF5IHRvIG9uZSBtb250aCBjYXVzZXMKLSAgICAgKiAgICAgIHRoaXMgZXhjZXB0aW9uLgotICAgICAqCi0gICAgICoKLSAgICAgKiBAc2VlICNzdWJ0cmFjdChEdXJhdGlvbikKLSAgICAgKi8KLSAgICBwdWJsaWMgRHVyYXRpb24gYWRkKGZpbmFsIER1cmF0aW9uIHJocykgewotICAgICAgICBEdXJhdGlvbiBsaHMgPSB0aGlzOwotICAgICAgICBCaWdEZWNpbWFsW10gYnVmID0gbmV3IEJpZ0RlY2ltYWxbNl07Ci0KLSAgICAgICAgYnVmWzBdID0gc2FuaXRpemUoKEJpZ0ludGVnZXIpIGxocy5nZXRGaWVsZChEYXRhdHlwZUNvbnN0YW50cy5ZRUFSUyksCi0gICAgICAgICAgICAgICAgbGhzLmdldFNpZ24oKSkuYWRkKHNhbml0aXplKChCaWdJbnRlZ2VyKSByaHMuZ2V0RmllbGQoRGF0YXR5cGVDb25zdGFudHMuWUVBUlMpLCAgcmhzLmdldFNpZ24oKSkpOwotICAgICAgICBidWZbMV0gPSBzYW5pdGl6ZSgoQmlnSW50ZWdlcikgbGhzLmdldEZpZWxkKERhdGF0eXBlQ29uc3RhbnRzLk1PTlRIUyksCi0gICAgICAgICAgICAgICAgbGhzLmdldFNpZ24oKSkuYWRkKHNhbml0aXplKChCaWdJbnRlZ2VyKSByaHMuZ2V0RmllbGQoRGF0YXR5cGVDb25zdGFudHMuTU9OVEhTKSwgcmhzLmdldFNpZ24oKSkpOwotICAgICAgICBidWZbMl0gPSBzYW5pdGl6ZSgoQmlnSW50ZWdlcikgbGhzLmdldEZpZWxkKERhdGF0eXBlQ29uc3RhbnRzLkRBWVMpLAotICAgICAgICAgICAgICAgIGxocy5nZXRTaWduKCkpLmFkZChzYW5pdGl6ZSgoQmlnSW50ZWdlcikgcmhzLmdldEZpZWxkKERhdGF0eXBlQ29uc3RhbnRzLkRBWVMpLCAgIHJocy5nZXRTaWduKCkpKTsKLSAgICAgICAgYnVmWzNdID0gc2FuaXRpemUoKEJpZ0ludGVnZXIpIGxocy5nZXRGaWVsZChEYXRhdHlwZUNvbnN0YW50cy5IT1VSUyksCi0gICAgICAgICAgICAgICAgbGhzLmdldFNpZ24oKSkuYWRkKHNhbml0aXplKChCaWdJbnRlZ2VyKSByaHMuZ2V0RmllbGQoRGF0YXR5cGVDb25zdGFudHMuSE9VUlMpLCAgcmhzLmdldFNpZ24oKSkpOwotICAgICAgICBidWZbNF0gPSBzYW5pdGl6ZSgoQmlnSW50ZWdlcikgbGhzLmdldEZpZWxkKERhdGF0eXBlQ29uc3RhbnRzLk1JTlVURVMpLAotICAgICAgICAgICAgICAgIGxocy5nZXRTaWduKCkpLmFkZChzYW5pdGl6ZSgoQmlnSW50ZWdlcikgcmhzLmdldEZpZWxkKERhdGF0eXBlQ29uc3RhbnRzLk1JTlVURVMpLCByaHMuZ2V0U2lnbigpKSk7Ci0gICAgICAgIGJ1Zls1XSA9IHNhbml0aXplKChCaWdEZWNpbWFsKSBsaHMuZ2V0RmllbGQoRGF0YXR5cGVDb25zdGFudHMuU0VDT05EUyksCi0gICAgICAgICAgICAgICAgbGhzLmdldFNpZ24oKSkuYWRkKHNhbml0aXplKChCaWdEZWNpbWFsKSByaHMuZ2V0RmllbGQoRGF0YXR5cGVDb25zdGFudHMuU0VDT05EUyksIHJocy5nZXRTaWduKCkpKTsKLQotICAgICAgICAvLyBhbGlnbiBzaWduCi0gICAgICAgIGFsaWduU2lnbnMoYnVmLCAwLCAyKTsgLy8gWSxNCi0gICAgICAgIGFsaWduU2lnbnMoYnVmLCAyLCA2KTsgLy8gRCxoLG0scwotCi0gICAgICAgIC8vIG1ha2Ugc3VyZSB0aGF0IHRoZSBzaWduIGJpdCBpcyBjb25zaXN0ZW50IGFjcm9zcyBhbGwgNiBmaWVsZHMuCi0gICAgICAgIGludCBzID0gMDsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCA2OyBpKyspIHsKLSAgICAgICAgICAgIGlmIChzICogYnVmW2ldLnNpZ251bSgpIDwgMCkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChzID09IDApIHsKLSAgICAgICAgICAgICAgICBzID0gYnVmW2ldLnNpZ251bSgpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIG5ldyBEdXJhdGlvbkltcGwoCi0gICAgICAgICAgICBzID49IDAsCi0gICAgICAgICAgICB0b0JpZ0ludGVnZXIoc2FuaXRpemUoYnVmWzBdLCBzKSwKLSAgICAgICAgICAgICAgICBsaHMuZ2V0RmllbGQoRGF0YXR5cGVDb25zdGFudHMuWUVBUlMpID09IG51bGwgJiYgcmhzLmdldEZpZWxkKERhdGF0eXBlQ29uc3RhbnRzLllFQVJTKSA9PSBudWxsKSwKLSAgICAgICAgICAgIHRvQmlnSW50ZWdlcihzYW5pdGl6ZShidWZbMV0sIHMpLAotICAgICAgICAgICAgICAgIGxocy5nZXRGaWVsZChEYXRhdHlwZUNvbnN0YW50cy5NT05USFMpID09IG51bGwgJiYgcmhzLmdldEZpZWxkKERhdGF0eXBlQ29uc3RhbnRzLk1PTlRIUykgPT0gbnVsbCksCi0gICAgICAgICAgICB0b0JpZ0ludGVnZXIoc2FuaXRpemUoYnVmWzJdLCBzKSwKLSAgICAgICAgICAgICAgICBsaHMuZ2V0RmllbGQoRGF0YXR5cGVDb25zdGFudHMuREFZUykgPT0gbnVsbCAmJiByaHMuZ2V0RmllbGQoRGF0YXR5cGVDb25zdGFudHMuREFZUykgPT0gbnVsbCksCi0gICAgICAgICAgICB0b0JpZ0ludGVnZXIoc2FuaXRpemUoYnVmWzNdLCBzKSwKLSAgICAgICAgICAgICAgICBsaHMuZ2V0RmllbGQoRGF0YXR5cGVDb25zdGFudHMuSE9VUlMpID09IG51bGwgJiYgcmhzLmdldEZpZWxkKERhdGF0eXBlQ29uc3RhbnRzLkhPVVJTKSA9PSBudWxsKSwKLSAgICAgICAgICAgIHRvQmlnSW50ZWdlcihzYW5pdGl6ZShidWZbNF0sIHMpLAotICAgICAgICAgICAgICAgIGxocy5nZXRGaWVsZChEYXRhdHlwZUNvbnN0YW50cy5NSU5VVEVTKSA9PSBudWxsICYmIHJocy5nZXRGaWVsZChEYXRhdHlwZUNvbnN0YW50cy5NSU5VVEVTKSA9PSBudWxsKSwKLSAgICAgICAgICAgICAoYnVmWzVdLnNpZ251bSgpID09IDAKLSAgICAgICAgICAgICAmJiBsaHMuZ2V0RmllbGQoRGF0YXR5cGVDb25zdGFudHMuU0VDT05EUykgPT0gbnVsbAotICAgICAgICAgICAgICYmIHJocy5nZXRGaWVsZChEYXRhdHlwZUNvbnN0YW50cy5TRUNPTkRTKSA9PSBudWxsKSA/IG51bGwgOiBzYW5pdGl6ZShidWZbNV0sIHMpKTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGFsaWduU2lnbnMoQmlnRGVjaW1hbFtdIGJ1ZiwgaW50IHN0YXJ0LCBpbnQgZW5kKSB7Ci0gICAgICAgIC8vIGFsaWduIHNpZ24KLSAgICAgICAgYm9vbGVhbiB0b3VjaGVkOwotCi0gICAgICAgIGRvIHsgLy8gcmVwZWF0IHVudGlsIGFsbCB0aGUgc2lnbiBiaXRzIGJlY29tZSBjb25zaXN0ZW50Ci0gICAgICAgICAgICB0b3VjaGVkID0gZmFsc2U7Ci0gICAgICAgICAgICBpbnQgcyA9IDA7IC8vIHNpZ24gb2YgdGhlIGxlZnQgZmllbGRzCi0KLSAgICAgICAgICAgIGZvciAoaW50IGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgaWYgKHMgKiBidWZbaV0uc2lnbnVtKCkgPCAwKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIHRoaXMgZmllbGQgaGFzIGRpZmZlcmVudCBzaWduIHRoYW4gaXRzIGxlZnQgZmllbGQuCi0gICAgICAgICAgICAgICAgICAgIHRvdWNoZWQgPSB0cnVlOwotCi0gICAgICAgICAgICAgICAgICAgIC8vIGNvbXB1dGUgdGhlIG51bWJlciBvZiB1bml0IHRoYXQgbmVlZHMgdG8gYmUgYm9ycm93ZWQuCi0gICAgICAgICAgICAgICAgICAgIEJpZ0RlY2ltYWwgYm9ycm93ID0KLSAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZltpXS5hYnMoKS5kaXZpZGUoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgRkFDVE9SU1tpIC0gMV0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgQmlnRGVjaW1hbC5ST1VORF9VUCk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChidWZbaV0uc2lnbnVtKCkgPiAwKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBib3Jyb3cgPSBib3Jyb3cubmVnYXRlKCk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAvLyB1cGRhdGUgdmFsdWVzCi0gICAgICAgICAgICAgICAgICAgIGJ1ZltpIC0gMV0gPSBidWZbaSAtIDFdLnN1YnRyYWN0KGJvcnJvdyk7Ci0gICAgICAgICAgICAgICAgICAgIGJ1ZltpXSA9IGJ1ZltpXS5hZGQoYm9ycm93Lm11bHRpcGx5KEZBQ1RPUlNbaSAtIDFdKSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGlmIChidWZbaV0uc2lnbnVtKCkgIT0gMCkgewotICAgICAgICAgICAgICAgICAgICBzID0gYnVmW2ldLnNpZ251bSgpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfSB3aGlsZSAodG91Y2hlZCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29tcHV0ZSA8Y29kZT52YWx1ZSpzaWdudW08L2NvZGU+IHdoZXJlIHZhbHVlPT1udWxsIGlzIHRyZWF0ZWQgYXMKLSAgICAgKiB2YWx1ZT09MC4KLSAgICAgKiBAcGFyYW0gdmFsdWUgVmFsdWUgdG8gc2FuaXRpemUuCi0gICAgICogQHBhcmFtIHNpZ251bSAwIHRvIHNhbml0aXplIHRvIDAsID4gMCB0byBzYW5pdGl6ZSB0byA8Y29kZT52YWx1ZTwvY29kZT4sIDwgMCB0byBzYW5pdGl6ZSB0byBuZWdhdGl2ZSA8Y29kZT52YWx1ZTwvY29kZT4uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIG5vbi1udWxsIHtAbGluayBCaWdEZWNpbWFsfS4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBCaWdEZWNpbWFsIHNhbml0aXplKEJpZ0ludGVnZXIgdmFsdWUsIGludCBzaWdudW0pIHsKLSAgICAgICAgaWYgKHNpZ251bSA9PSAwIHx8IHZhbHVlID09IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBaRVJPOwotICAgICAgICB9Ci0gICAgICAgIGlmIChzaWdudW0gPiAwKSB7Ci0gICAgICAgICAgICByZXR1cm4gbmV3IEJpZ0RlY2ltYWwodmFsdWUpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBuZXcgQmlnRGVjaW1hbCh2YWx1ZS5uZWdhdGUoKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+Q29tcHV0ZSA8Y29kZT52YWx1ZSpzaWdudW08L2NvZGU+IHdoZXJlIDxjb2RlPnZhbHVlPT1udWxsPC9jb2RlPiBpcyB0cmVhdGVkIGFzIDxjb2RlPnZhbHVlPT0wPC9jb2RlPjwvcD4uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdmFsdWUgVmFsdWUgdG8gc2FuaXRpemUuCi0gICAgICogQHBhcmFtIHNpZ251bSAwIHRvIHNhbml0aXplIHRvIDAsID4gMCB0byBzYW5pdGl6ZSB0byA8Y29kZT52YWx1ZTwvY29kZT4sIDwgMCB0byBzYW5pdGl6ZSB0byBuZWdhdGl2ZSA8Y29kZT52YWx1ZTwvY29kZT4uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIG5vbi1udWxsIHtAbGluayBCaWdEZWNpbWFsfS4KLSAgICAgKi8KLSAgICBzdGF0aWMgQmlnRGVjaW1hbCBzYW5pdGl6ZShCaWdEZWNpbWFsIHZhbHVlLCBpbnQgc2lnbnVtKSB7Ci0gICAgICAgIGlmIChzaWdudW0gPT0gMCB8fCB2YWx1ZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gWkVSTzsKLSAgICAgICAgfQotICAgICAgICBpZiAoc2lnbnVtID4gMCkgewotICAgICAgICAgICAgcmV0dXJuIHZhbHVlOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiB2YWx1ZS5uZWdhdGUoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5Db21wdXRlcyBhIG5ldyBkdXJhdGlvbiB3aG9zZSB2YWx1ZSBpcyA8Y29kZT50aGlzLXJoczwvY29kZT4uPC9wPgotICAgICAqCi0gICAgICogPHA+Rm9yIGV4YW1wbGU6PC9wPgotICAgICAqIDxwcmU+Ci0gICAgICogIjEgZGF5IiAtICItMyBkYXlzIiA9ICI0IGRheXMiCi0gICAgICogIjEgeWVhciIgLSAiMSBkYXkiID0gSWxsZWdhbFN0YXRlRXhjZXB0aW9uCi0gICAgICogIi0oMSBob3VyLDUwIG1pbnV0ZXMpIiAtICItMjAgbWludXRlcyIgPSAiLSgxaG91cnMsMzAgbWludXRlcykiCi0gICAgICogIjE1IGhvdXJzIiAtICItMyBkYXlzIiA9ICIzIGRheXMgYW5kIDE1IGhvdXJzIgotICAgICAqICIxIHllYXIiIC0gIi0xIGRheSIgPSAiMSB5ZWFyIGFuZCAxIGRheSIKLSAgICAgKiA8L3ByZT4KLSAgICAgKgotICAgICAqIDxwPlNpbmNlIHRoZXJlJ3Mgbm8gd2F5IHRvIG1lYW5pbmdmdWxseSBzdWJ0cmFjdCAxIGRheSBmcm9tIDEgbW9udGgsCi0gICAgICogdGhlcmUgYXJlIGNhc2VzIHdoZXJlIHRoZSBvcGVyYXRpb24gZmFpbHMgaW4ge0BsaW5rIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbn0uPC9wPgotICAgICAqCi0gICAgICogPHA+Rm9ybWFsbHkgdGhlIGNvbXB1dGF0aW9uIGlzIGRlZmluZWQgYXMgZm9sbG93cy4KLSAgICAgKiBGaXJzdCwgd2UgY2FuIGFzc3VtZSB0aGF0IHR3byB7QGxpbmsgRHVyYXRpb259cyBhcmUgYm90aCBwb3NpdGl2ZQotICAgICAqIHdpdGhvdXQgbG9zaW5nIGdlbmVyYWxpdHkuICAoaS5lLiwKLSAgICAgKiA8Y29kZT4oLVgpLVk9LShYK1kpPC9jb2RlPiwgPGNvZGU+WC0oLVkpPVgrWTwvY29kZT4sCi0gICAgICogPGNvZGU+KC1YKS0oLVkpPS0oWC1ZKTwvY29kZT4pPC9wPgotICAgICAqCi0gICAgICogPHA+VGhlbiB0d28gZHVyYXRpb25zIGFyZSBzdWJ0cmFjdGVkIGZpZWxkIGJ5IGZpZWxkLgotICAgICAqIElmIHRoZSBzaWduIG9mIGFueSBub24temVybyBmaWVsZCA8dHQ+RjwvdHQ+IGlzIGRpZmZlcmVudCBmcm9tCi0gICAgICogdGhlIHNpZ24gb2YgdGhlIG1vc3Qgc2lnbmlmaWNhbnQgZmllbGQsCi0gICAgICogMSAoaWYgPHR0PkY8L3R0PiBpcyBuZWdhdGl2ZSkgb3IgLTEgKG90aGVyd2lzZSkKLSAgICAgKiB3aWxsIGJlIGJvcnJvd2VkIGZyb20gdGhlIG5leHQgYmlnZ2VyIHVuaXQgb2YgPHR0PkY8L3R0Pi48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5UaGlzIHByb2Nlc3MgaXMgcmVwZWF0ZWQgdW50aWwgYWxsIHRoZSBub24temVybyBmaWVsZHMgaGF2ZQotICAgICAqIHRoZSBzYW1lIHNpZ24uPC9wPgotICAgICAqCi0gICAgICogPHA+SWYgYSBib3Jyb3cgb2NjdXJzIGluIHRoZSBkYXlzIGZpZWxkIChpbiBvdGhlciB3b3JkcywgaWYKLSAgICAgKiB0aGUgY29tcHV0YXRpb24gbmVlZHMgdG8gYm9ycm93IDEgb3IgLTEgbW9udGggdG8gY29tcGVuc2F0ZQotICAgICAqIGRheXMpLCB0aGVuIHRoZSBjb21wdXRhdGlvbiBmYWlscyBieSB0aHJvd2luZyBhbgotICAgICAqIHtAbGluayBJbGxlZ2FsU3RhdGVFeGNlcHRpb259LjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSByaHMgPGNvZGU+RHVyYXRpb248L2NvZGU+IHRvIHN1YnN0cmFjdCBmcm9tIHRoaXMgPGNvZGU+RHVyYXRpb248L2NvZGU+LgotICAgICAqCi0gICAgICogQHJldHVybiBOZXcgPGNvZGU+RHVyYXRpb248L2NvZGU+IGNyZWF0ZWQgZnJvbSBzdWJ0cmFjdGluZyA8Y29kZT5yaHM8L2NvZGU+IGZyb20gdGhpcyA8Y29kZT5EdXJhdGlvbjwvY29kZT4uCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgotICAgICAqICAgICAgSWYgdHdvIGR1cmF0aW9ucyBjYW5ub3QgYmUgbWVhbmluZ2Z1bGx5IHN1YnRyYWN0ZWQuIEZvcgotICAgICAqICAgICAgZXhhbXBsZSwgc3VidHJhY3Rpbmcgb25lIGRheSBmcm9tIG9uZSBtb250aCBjYXVzZXMKLSAgICAgKiAgICAgIHRoaXMgZXhjZXB0aW9uLgotICAgICAqCi0gICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgotICAgICAqICAgICAgSWYgdGhlIHJocyBwYXJhbWV0ZXIgaXMgbnVsbC4KLSAgICAgKgotICAgICAqIEBzZWUgI2FkZChEdXJhdGlvbikKLSAgICAgKi8KLSAgICBwdWJsaWMgRHVyYXRpb24gc3VidHJhY3QoZmluYWwgRHVyYXRpb24gcmhzKSB7Ci0gICAgICAgIHJldHVybiBhZGQocmhzLm5lZ2F0ZSgpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGEgbmV3IHtAbGluayBEdXJhdGlvbn0gb2JqZWN0IHdob3NlCi0gICAgICogdmFsdWUgaXMgPGNvZGU+LXRoaXM8L2NvZGU+LgotICAgICAqCi0gICAgICogPHA+Ci0gICAgICogU2luY2UgdGhlIHtAbGluayBEdXJhdGlvbn0gY2xhc3MgaXMgaW1tdXRhYmxlLCB0aGlzIG1ldGhvZAotICAgICAqIGRvZXNuJ3QgY2hhbmdlIHRoZSB2YWx1ZSBvZiB0aGlzIG9iamVjdC4gSXQgc2ltcGx5IGNvbXB1dGVzCi0gICAgICogYSBuZXcgRHVyYXRpb24gb2JqZWN0IGFuZCByZXR1cm5zIGl0LgotICAgICAqCi0gICAgICogQHJldHVybgotICAgICAqICAgICAgYWx3YXlzIHJldHVybiBhIG5vbi1udWxsIHZhbGlkIHtAbGluayBEdXJhdGlvbn0gb2JqZWN0LgotICAgICAqLwotICAgIHB1YmxpYyBEdXJhdGlvbiBuZWdhdGUoKSB7Ci0gICAgICAgIHJldHVybiBuZXcgRHVyYXRpb25JbXBsKAotICAgICAgICAgICAgc2lnbnVtIDw9IDAsCi0gICAgICAgICAgICB5ZWFycywKLSAgICAgICAgICAgIG1vbnRocywKLSAgICAgICAgICAgIGRheXMsCi0gICAgICAgICAgICBob3VycywKLSAgICAgICAgICAgIG1pbnV0ZXMsCi0gICAgICAgICAgICBzZWNvbmRzKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBzaWduIG9mIHRoaXMgZHVyYXRpb24gaW4gLTEsMCwgb3IgMS4KLSAgICAgKgotICAgICAqIEByZXR1cm4KLSAgICAgKiAgICAgIC0xIGlmIHRoaXMgZHVyYXRpb24gaXMgbmVnYXRpdmUsIDAgaWYgdGhlIGR1cmF0aW9uIGlzIHplcm8sCi0gICAgICogICAgICBhbmQgMSBpZiB0aGUgZHVyYXRpb24gaXMgcG9zdGl2ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IHNpZ251bSgpIHsKLSAgICAgICAgcmV0dXJuIHNpZ251bTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIEFkZHMgdGhpcyBkdXJhdGlvbiB0byBhIHtAbGluayBDYWxlbmRhcn0gb2JqZWN0LgotICAgICAqCi0gICAgICogPHA+Ci0gICAgICogQ2FsbHMge0BsaW5rIGphdmEudXRpbC5DYWxlbmRhciNhZGQoaW50LGludCl9IGluIHRoZQotICAgICAqIG9yZGVyIG9mIFlFQVJTLCBNT05USFMsIERBWVMsIEhPVVJTLCBNSU5VVEVTLCBTRUNPTkRTLCBhbmQgTUlMTElTRUNPTkRTCi0gICAgICogaWYgdGhvc2UgZmllbGRzIGFyZSBwcmVzZW50LiBCZWNhdXNlIHRoZSB7QGxpbmsgQ2FsZW5kYXJ9IGNsYXNzCi0gICAgICogdXNlcyBpbnQgdG8gaG9sZCB2YWx1ZXMsIHRoZXJlIGFyZSBjYXNlcyB3aGVyZSB0aGlzIG1ldGhvZAotICAgICAqIHdvbid0IHdvcmsgY29ycmVjdGx5IChmb3IgZXhhbXBsZSBpZiB2YWx1ZXMgb2YgZmllbGRzCi0gICAgICogZXhjZWVkIHRoZSByYW5nZSBvZiBpbnQuKQotICAgICAqIDwvcD4KLSAgICAgKgotICAgICAqIDxwPgotICAgICAqIEFsc28sIHNpbmNlIHRoaXMgZHVyYXRpb24gY2xhc3MgaXMgYSBHcmVnb3JpYW4gZHVyYXRpb24sIHRoaXMKLSAgICAgKiBtZXRob2Qgd2lsbCBub3Qgd29yayBjb3JyZWN0bHkgaWYgdGhlIGdpdmVuIHtAbGluayBDYWxlbmRhcn0KLSAgICAgKiBvYmplY3QgaXMgYmFzZWQgb24gc29tZSBvdGhlciBjYWxlbmRhciBzeXN0ZW1zLgotICAgICAqIDwvcD4KLSAgICAgKgotICAgICAqIDxwPgotICAgICAqIEFueSBmcmFjdGlvbmFsIHBhcnRzIG9mIHRoaXMge0BsaW5rIER1cmF0aW9ufSBvYmplY3QKLSAgICAgKiBiZXlvbmQgbWlsbGlzZWNvbmRzIHdpbGwgYmUgc2ltcGx5IGlnbm9yZWQuIEZvciBleGFtcGxlLCBpZgotICAgICAqIHRoaXMgZHVyYXRpb24gaXMgIlAxLjIzNDU2UyIsIHRoZW4gMSBpcyBhZGRlZCB0byBTRUNPTkRTLAotICAgICAqIDIzNCBpcyBhZGRlZCB0byBNSUxMSVNFQ09ORFMsIGFuZCB0aGUgcmVzdCB3aWxsIGJlIHVudXNlZC4KLSAgICAgKiA8L3A+Ci0gICAgICoKLSAgICAgKiA8cD4KLSAgICAgKiBOb3RlIHRoYXQgYmVjYXVzZSB7QGxpbmsgQ2FsZW5kYXIjYWRkKGludCwgaW50KX0gaXMgdXNpbmcKLSAgICAgKiA8dHQ+aW50PC90dD4sIHtAbGluayBEdXJhdGlvbn0gd2l0aCB2YWx1ZXMgYmV5b25kIHRoZQotICAgICAqIHJhbmdlIG9mIDx0dD5pbnQ8L3R0PiBpbiBpdHMgZmllbGRzCi0gICAgICogd2lsbCBjYXVzZSBvdmVyZmxvdy91bmRlcmZsb3cgdG8gdGhlIGdpdmVuIHtAbGluayBDYWxlbmRhcn0uCi0gICAgICoge0BsaW5rIFhNTEdyZWdvcmlhbkNhbGVuZGFyI2FkZChEdXJhdGlvbil9IHByb3ZpZGVzIHRoZSBzYW1lCi0gICAgICogYmFzaWMgb3BlcmF0aW9uIGFzIHRoaXMgbWV0aG9kIHdoaWxlIGF2b2lkaW5nCi0gICAgICogdGhlIG92ZXJmbG93L3VuZGVyZmxvdyBpc3N1ZXMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY2FsZW5kYXIKLSAgICAgKiAgICAgIEEgY2FsZW5kYXIgb2JqZWN0IHdob3NlIHZhbHVlIHdpbGwgYmUgbW9kaWZpZWQuCi0gICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgotICAgICAqICAgICAgaWYgdGhlIGNhbGVuZGFyIHBhcmFtZXRlciBpcyBudWxsLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGFkZFRvKENhbGVuZGFyIGNhbGVuZGFyKSB7Ci0gICAgICAgIGNhbGVuZGFyLmFkZChDYWxlbmRhci5ZRUFSLCBnZXRZZWFycygpICogc2lnbnVtKTsKLSAgICAgICAgY2FsZW5kYXIuYWRkKENhbGVuZGFyLk1PTlRILCBnZXRNb250aHMoKSAqIHNpZ251bSk7Ci0gICAgICAgIGNhbGVuZGFyLmFkZChDYWxlbmRhci5EQVlfT0ZfTU9OVEgsIGdldERheXMoKSAqIHNpZ251bSk7Ci0gICAgICAgIGNhbGVuZGFyLmFkZChDYWxlbmRhci5IT1VSLCBnZXRIb3VycygpICogc2lnbnVtKTsKLSAgICAgICAgY2FsZW5kYXIuYWRkKENhbGVuZGFyLk1JTlVURSwgZ2V0TWludXRlcygpICogc2lnbnVtKTsKLSAgICAgICAgY2FsZW5kYXIuYWRkKENhbGVuZGFyLlNFQ09ORCwgZ2V0U2Vjb25kcygpICogc2lnbnVtKTsKLQotICAgICAgICBpZiAoc2Vjb25kcyAhPSBudWxsKSB7Ci0gICAgICAgICAgICBCaWdEZWNpbWFsIGZyYWN0aW9uID0KLSAgICAgICAgICAgICAgICBzZWNvbmRzLnN1YnRyYWN0KHNlY29uZHMuc2V0U2NhbGUoMCwgQmlnRGVjaW1hbC5ST1VORF9ET1dOKSk7Ci0gICAgICAgICAgICBpbnQgbWlsbGlzZWMgPSBmcmFjdGlvbi5tb3ZlUG9pbnRSaWdodCgzKS5pbnRWYWx1ZSgpOwotICAgICAgICAgICAgY2FsZW5kYXIuYWRkKENhbGVuZGFyLk1JTExJU0VDT05ELCBtaWxsaXNlYyAqIHNpZ251bSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBZGRzIHRoaXMgZHVyYXRpb24gdG8gYSB7QGxpbmsgRGF0ZX0gb2JqZWN0LgotICAgICAqCi0gICAgICogPHA+Ci0gICAgICogVGhlIGdpdmVuIGRhdGUgaXMgZmlyc3QgY29udmVydGVkIGludG8KLSAgICAgKiBhIHtAbGluayBqYXZhLnV0aWwuR3JlZ29yaWFuQ2FsZW5kYXJ9LCB0aGVuIHRoZSBkdXJhdGlvbgotICAgICAqIGlzIGFkZGVkIGV4YWN0bHkgbGlrZSB0aGUge0BsaW5rICNhZGRUbyhDYWxlbmRhcil9IG1ldGhvZC4KLSAgICAgKgotICAgICAqIDxwPgotICAgICAqIFRoZSB1cGRhdGVkIHRpbWUgaW5zdGFudCBpcyB0aGVuIGNvbnZlcnRlZCBiYWNrIGludG8gYQotICAgICAqIHtAbGluayBEYXRlfSBvYmplY3QgYW5kIHVzZWQgdG8gdXBkYXRlIHRoZSBnaXZlbiB7QGxpbmsgRGF0ZX0gb2JqZWN0LgotICAgICAqCi0gICAgICogPHA+Ci0gICAgICogVGhpcyBzb21ld2hhdCByZWR1bmRhbnQgY29tcHV0YXRpb24gaXMgbmVjZXNzYXJ5IHRvIHVuYW1iaWd1b3VzbHkKLSAgICAgKiBkZXRlcm1pbmUgdGhlIGR1cmF0aW9uIG9mIG1vbnRocyBhbmQgeWVhcnMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZGF0ZQotICAgICAqICAgICAgQSBkYXRlIG9iamVjdCB3aG9zZSB2YWx1ZSB3aWxsIGJlIG1vZGlmaWVkLgotICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KLSAgICAgKiAgICAgIGlmIHRoZSBkYXRlIHBhcmFtZXRlciBpcyBudWxsLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGFkZFRvKERhdGUgZGF0ZSkgewotICAgICAgICBDYWxlbmRhciBjYWwgPSBuZXcgR3JlZ29yaWFuQ2FsZW5kYXIoKTsKLSAgICAgICAgY2FsLnNldFRpbWUoZGF0ZSk7IC8vIHRoaXMgd2lsbCB0aHJvdyBOUEUgaWYgZGF0ZT09bnVsbAotICAgICAgICB0aGlzLmFkZFRvKGNhbCk7Ci0gICAgICAgIGRhdGUuc2V0VGltZShnZXRDYWxlbmRhclRpbWVJbk1pbGxpcyhjYWwpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5TdHJlYW0gVW5pcXVlIElkZW50aWZpZXIuPC9wPgotICAgICAqCi0gICAgICogPHA+VE9ETzogU2VyaWFsaXphdGlvbiBzaG91bGQgdXNlIHRoZSBYTUwgc3RyaW5nIHJlcHJlc2VudGF0aW9uIGFzCi0gICAgICogdGhlIHNlcmlhbGl6YXRpb24gZm9ybWF0IHRvIGVuc3VyZSBmdXR1cmUgY29tcGF0aWJpbGl0eS48L3A+Ci0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMUw7Ci0KLSAgICAvKioKLSAgICAgKiBXcml0ZXMge0BsaW5rIER1cmF0aW9ufSBhcyBhIGxleGljYWwgcmVwcmVzZW50YXRpb24KLSAgICAgKiBmb3IgbWF4aW11bSBmdXR1cmUgY29tcGF0aWJpbGl0eS4KLSAgICAgKgotICAgICAqIEByZXR1cm4KLSAgICAgKiAgICAgIEFuIG9iamVjdCB0aGF0IGVuY2Fwc3VsYXRlcyB0aGUgc3RyaW5nCi0gICAgICogICAgICByZXR1cm5lZCBieSA8Y29kZT50aGlzLnRvU3RyaW5nKCk8L2NvZGU+LgotICAgICAqLwotICAgIHByaXZhdGUgT2JqZWN0IHdyaXRlUmVwbGFjZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgIHJldHVybiBuZXcgRHVyYXRpb25TdHJlYW0odGhpcy50b1N0cmluZygpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXByZXNlbnRhdGlvbiBvZiB7QGxpbmsgRHVyYXRpb259IGluIHRoZSBvYmplY3Qgc3RyZWFtLgotICAgICAqCi0gICAgICogQGF1dGhvciBLb2hzdWtlIEthd2FndWNoaSAoa29oc3VrZS5rYXdhZ3VjaGlAc3VuLmNvbSkKLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBEdXJhdGlvblN0cmVhbSBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZSB7Ci0gICAgICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIGxleGljYWw7Ci0KLSAgICAgICAgcHJpdmF0ZSBEdXJhdGlvblN0cmVhbShTdHJpbmcgX2xleGljYWwpIHsKLSAgICAgICAgICAgIHRoaXMubGV4aWNhbCA9IF9sZXhpY2FsOwotICAgICAgICB9Ci0KLSAgICAgICAgcHJpdmF0ZSBPYmplY3QgcmVhZFJlc29sdmUoKSB0aHJvd3MgT2JqZWN0U3RyZWFtRXhjZXB0aW9uIHsKLSAgICAgICAgICAgIC8vICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIHJldHVybiBuZXcgRHVyYXRpb25JbXBsKGxleGljYWwpOwotICAgICAgICAgICAgLy8gICAgICAgICAgICB9IGNhdGNoKCBQYXJzZUV4Y2VwdGlvbiBlICkgewotICAgICAgICAgICAgLy8gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFN0cmVhbUNvcnJ1cHRlZEV4Y2VwdGlvbigidW5hYmxlIHRvIHBhcnNlICIrbGV4aWNhbCsiIGFzIGR1cmF0aW9uIik7Ci0gICAgICAgICAgICAvLyAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDFMOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENhbGxzIHRoZSB7QGxpbmsgQ2FsZW5kYXIjZ2V0VGltZUluTWlsbGlzfSBtZXRob2QuCi0gICAgICogUHJpb3IgdG8gSkRLMS40LCB0aGlzIG1ldGhvZCB3YXMgcHJvdGVjdGVkIGFuZCB0aGVyZWZvcmUKLSAgICAgKiBjYW5ub3QgYmUgaW52b2tlZCBkaXJlY3RseS4KLSAgICAgKgotICAgICAqIEluIGZ1dHVyZSwgdGhpcyBzaG91bGQgYmUgcmVwbGFjZWQgYnkKLSAgICAgKiA8Y29kZT5jYWwuZ2V0VGltZUluTWlsbGlzKCk8L2NvZGU+Ci0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgbG9uZyBnZXRDYWxlbmRhclRpbWVJbk1pbGxpcyhDYWxlbmRhciBjYWwpIHsKLSAgICAgICAgcmV0dXJuIGNhbC5nZXRUaW1lKCkuZ2V0VGltZSgpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2pheHAvZGF0YXR5cGUvRHVyYXRpb25ZZWFyTW9udGhJbXBsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9qYXhwL2RhdGF0eXBlL0R1cmF0aW9uWWVhck1vbnRoSW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhYmY4YzUzLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2pheHAvZGF0YXR5cGUvRHVyYXRpb25ZZWFyTW9udGhJbXBsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMDAgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAxMCwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmpheHAuZGF0YXR5cGU7Ci0KLWltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKLWltcG9ydCBqYXZheC54bWwuZGF0YXR5cGUuRGF0YXR5cGVDb25zdGFudHM7Ci0KLQotLyoqCi0gKiA8cD5SZXByZXNlbnQgYSBzdWJ0eXBlIDxjb2RlPnhkdDp5ZWFyTW9udGhEdXJhdGlvbjwvY29kZT4gb2YgYSA8Y29kZT5EdXJhdGlvbjwvY29kZT4KLSAqIGFzIHNwZWNpZmllZCBpbiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aC1kYXRhbW9kZWwjeWVhck1vbnRoRHVyYXRpb24iPgotICogICBYUXVlcnkgMS4wIGFuZCBYUGF0aCAyLjAgRGF0YSBNb2RlbCwgeGR0OnllYXJNb250aER1cmF0aW9uPC9hPi48L3A+Ci0gKgotICoKLSAqIDxwPlRoZSBEdXJhdGlvblllYXJNb250aCBvYmplY3QgcmVwcmVzZW50cyBhIHBlcmlvZCBvZiBHcmVnb3JpYW4gdGltZSwKLSAqIHdpdGggYSBsZXhpY2FsIHJlcHJlc2VudGF0aW9uLCAiPGVtPlBuWW5NPC9lbT4iIHRoYXQgY29udGFpbnMgb25seSB5ZWFyIGFuZCBtb250aCBjb21wb25lbnRzLgotICogPC9wPgotICoKLSAqCi0gKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzpWaWtyYW0uQXJvc2thckBTdW4uQ09NIj5WaWtyYW0gQXJvc2thcjwvYT4KLSAqIEBhdXRob3IgPGEgaHJlZj0ibWFpbHRvOkh1aXpoZS53YW5nQG9yYWNsZS5jb20iPkpvZSBXYW5nPC9hPgotICogQHZlcnNpb24gJFJldmlzaW9uOiAxLjEgJCwgJERhdGU6IDIwMTAvMDUvMTkgMDU6MDI6NTUgJAotCi0gKiBAc2VlIFhNTEdyZWdvcmlhbkNhbGVuZGFyI2FkZChEdXJhdGlvbikKLSAqLwotCi1jbGFzcyBEdXJhdGlvblllYXJNb250aEltcGwKLSAgICAgICAgZXh0ZW5kcyBEdXJhdGlvbkltcGwgewotCi0KLSAgICAvKioKLSAgICAgKiA8cD5Db25zdHJ1Y3RzIGEgbmV3IER1cmF0aW9uIG9iamVjdCBieSBzcGVjaWZ5aW5nIGVhY2ggZmllbGQgaW5kaXZpZHVhbGx5LjwvcD4KLSAgICAgKgotICAgICAqIDxwPkFsbCB0aGUgcGFyYW1ldGVycyBhcmUgb3B0aW9uYWwgYXMgbG9uZyBhcyBhdCBsZWFzdCBvbmUgZmllbGQgaXMgcHJlc2VudC4KLSAgICAgKiBJZiBzcGVjaWZpZWQsIHBhcmFtZXRlcnMgaGF2ZSB0byBiZSB6ZXJvIG9yIHBvc2l0aXZlLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBpc1Bvc2l0aXZlIFNldCB0byA8Y29kZT5mYWxzZTwvY29kZT4gdG8gY3JlYXRlIGEgbmVnYXRpdmUgZHVyYXRpb24uIFdoZW4gdGhlIGxlbmd0aAotICAgICAqICAgb2YgdGhlIGR1cmF0aW9uIGlzIHplcm8sIHRoaXMgcGFyYW1ldGVyIHdpbGwgYmUgaWdub3JlZC4KLSAgICAgKiBAcGFyYW0geWVhcnMgb2YgdGhpcyA8Y29kZT5EdXJhdGlvbjwvY29kZT4KLSAgICAgKiBAcGFyYW0gbW9udGhzIG9mIHRoaXMgPGNvZGU+RHVyYXRpb248L2NvZGU+Ci0gICAgICoKLSAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgotICAgICAqICAgIElmIHllYXJzLCBtb250aHMgcGFyYW1ldGVycyBhcmUgYWxsIDxjb2RlPm51bGw8L2NvZGU+LiBPciBpZiBhbnkKLSAgICAgKiAgICBvZiB0aG9zZSBwYXJhbWV0ZXJzIGFyZSBuZWdhdGl2ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgRHVyYXRpb25ZZWFyTW9udGhJbXBsKAotICAgICAgICBib29sZWFuIGlzUG9zaXRpdmUsCi0gICAgICAgIEJpZ0ludGVnZXIgeWVhcnMsCi0gICAgICAgIEJpZ0ludGVnZXIgbW9udGhzKSB7Ci0KLSAgICAgICAgc3VwZXIoaXNQb3NpdGl2ZSwgeWVhcnMsIG1vbnRocywgbnVsbCwgbnVsbCwgbnVsbCwgbnVsbCk7Ci0gICAgICAgIGNvbnZlcnRUb0Nhbm9uaWNhbFllYXJNb250aCgpOwotICAgIH0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIDxwPkNvbnN0cnVjdCBhIDxjb2RlPkR1cmF0aW9uPC9jb2RlPiBvZiB0eXBlIDxjb2RlPnhkdDp5ZWFyTW9udGhEdXJhdGlvbjwvY29kZT4gdXNpbmcgdGhlIHNwZWNpZmllZAotICAgICAgICAgKiA8Y29kZT55ZWFyPC9jb2RlPiBhbmQgPGNvZGU+bW9udGg8L2NvZGU+IGFzIGRlZmluZWQgaW4KLSAgICAgICAgICogPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGgtZGF0YW1vZGVsI3llYXJNb250aER1cmF0aW9uIj4KLSAgICAgICAgICogICBYUXVlcnkgMS4wIGFuZCBYUGF0aCAyLjAgRGF0YSBNb2RlbCwgeGR0OnllYXJNb250aER1cmF0aW9uPC9hPi48L3A+Ci0gICAgICAgICAqCi0gICAgICogPHA+QSB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjRklFTERfVU5ERUZJTkVEfSB2YWx1ZSBpbmRpY2F0ZXMgdGhhdCBmaWVsZCBpcyBub3Qgc2V0LjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBpc1Bvc2l0aXZlIFNldCB0byA8Y29kZT5mYWxzZTwvY29kZT4gdG8gY3JlYXRlIGEgbmVnYXRpdmUgZHVyYXRpb24uIFdoZW4gdGhlIGxlbmd0aAotICAgICAqICAgb2YgdGhlIGR1cmF0aW9uIGlzIHplcm8sIHRoaXMgcGFyYW1ldGVyIHdpbGwgYmUgaWdub3JlZC4KLSAgICAgICAgICogQHBhcmFtIHllYXIgWWVhciBvZiA8Y29kZT5EdXJhdGlvbjwvY29kZT4uCi0gICAgICAgICAqIEBwYXJhbSBtb250aCBNb250aCBvZiA8Y29kZT5EdXJhdGlvbjwvY29kZT4uCi0gICAgICAgICAqCi0gICAgICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIElmIHRoZSB2YWx1ZXMgYXJlIG5vdCBhIHZhbGlkIHJlcHJlc2VudGF0aW9uIG9mIGEKLSAgICAgICAgICogPGNvZGU+RHVyYXRpb248L2NvZGU+OiBpZiBhbnkgb2YgdGhlIGZpZWxkcyAoeWVhciwgbW9udGgpIGlzIG5lZ2F0aXZlLgotICAgICAgICAgKi8KLSAgICBwcm90ZWN0ZWQgRHVyYXRpb25ZZWFyTW9udGhJbXBsKAotICAgICAgICBmaW5hbCBib29sZWFuIGlzUG9zaXRpdmUsCi0gICAgICAgIGZpbmFsIGludCB5ZWFycywKLSAgICAgICAgZmluYWwgaW50IG1vbnRocykgewotCi0gICAgICAgIHRoaXMoaXNQb3NpdGl2ZSwKLSAgICAgICAgICAgIHdyYXAoeWVhcnMpLAotICAgICAgICAgICAgd3JhcChtb250aHMpKTsKLQotCi0gICAgfQotCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIDxwPkNvbnN0cnVjdCBhIDxjb2RlPkR1cmF0aW9uPC9jb2RlPiBvZiB0eXBlIDxjb2RlPnhkdDp5ZWFyTW9udGhEdXJhdGlvbjwvY29kZT4gdXNpbmcgdGhlIHNwZWNpZmllZCBtaWxsaXNlY29uZHMgYXMgZGVmaW5lZCBpbgotICAgICAgICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aC1kYXRhbW9kZWwjeWVhck1vbnRoRHVyYXRpb24iPgotICAgICAgICAgKiAgIFhRdWVyeSAxLjAgYW5kIFhQYXRoIDIuMCBEYXRhIE1vZGVsLCB4ZHQ6eWVhck1vbnRoRHVyYXRpb248L2E+LjwvcD4KLSAgICAgICAgICoKLSAgICAgICAgICogPHA+VGhlIGRhdGF0eXBlIDxjb2RlPnhkdDp5ZWFyTW9udGhEdXJhdGlvbjwvY29kZT4gaXMgYSBzdWJ0eXBlIG9mIDxjb2RlPnhzOmR1cmF0aW9uPC9jb2RlPgotICAgICAgICAgKiB3aG9zZSBsZXhpY2FsIHJlcHJlc2VudGF0aW9uIGNvbnRhaW5zIG9ubHkgeWVhciBhbmQgbW9udGggY29tcG9uZW50cy4KLSAgICAgICAgICogVGhpcyBkYXRhdHlwZSByZXNpZGVzIGluIHRoZSBuYW1lc3BhY2Uge0BsaW5rIGphdmF4LnhtbC5YTUxDb25zdGFudHMjVzNDX1hQQVRIX0RBVEFUWVBFX05TX1VSSX0uPC9wPgotICAgICAgICAgKgotICAgICAqIDxwPkJvdGggdmFsdWVzIGFyZSBzZXQgYnkgY29tcHV0aW5nIHRoZWlyIHZhbHVlcyBmcm9tIHRoZSBzcGVjaWZpZWQgbWlsbGlzZWNvbmRzCi0gICAgICogYW5kIGFyZSBhdmFpbGFiZSB1c2luZyB0aGUgPGNvZGU+Z2V0PC9jb2RlPiBtZXRob2RzIG9mICB0aGUgY3JlYXRlZCB7QGxpbmsgRHVyYXRpb259LgotICAgICAqIFRoZSB2YWx1ZXMgY29uZm9ybSB0byBhbmQgYXJlIGRlZmluZWQgYnk6PC9wPgotICAgICAqIDx1bD4KLSAgICAgKiAgIDxsaT5JU08gODYwMToyMDAwKEUpIFNlY3Rpb24gNS41LjMuMiBBbHRlcm5hdGl2ZSBmb3JtYXQ8L2xpPgotICAgICAqICAgPGxpPjxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3htbHNjaGVtYS0yLyNpc29mb3JtYXRzIj4KLSAgICAgKiAgICAgVzNDIFhNTCBTY2hlbWEgMS4wIFBhcnQgMiwgQXBwZW5kaXggRCwgSVNPIDg2MDEgRGF0ZSBhbmQgVGltZSBGb3JtYXRzPC9hPgotICAgICAqICAgPC9saT4KLSAgICAgKiAgIDxsaT57QGxpbmsgWE1MR3JlZ29yaWFuQ2FsZW5kYXJ9ICBEYXRlL1RpbWUgRGF0YXR5cGUgRmllbGQgTWFwcGluZyBCZXR3ZWVuIFhNTCBTY2hlbWEgMS4wIGFuZCBKYXZhIFJlcHJlc2VudGF0aW9uPC9saT4KLSAgICAgKiA8L3VsPgotICAgICAqCi0gICAgICAgICAqIDxwPlRoZSBkZWZhdWx0IHN0YXJ0IGluc3RhbmNlIGlzIGRlZmluZWQgYnkge0BsaW5rIEdyZWdvcmlhbkNhbGVuZGFyfSdzIHVzZSBvZiB0aGUgc3RhcnQgb2YgdGhlIGVwb2NoOiBpLmUuLAotICAgICAgICAgKiB7QGxpbmsgamF2YS51dGlsLkNhbGVuZGFyI1lFQVJ9ID0gMTk3MCwKLSAgICAgICAgICoge0BsaW5rIGphdmEudXRpbC5DYWxlbmRhciNNT05USH0gPSB7QGxpbmsgamF2YS51dGlsLkNhbGVuZGFyI0pBTlVBUll9LAotICAgICAgICAgKiB7QGxpbmsgamF2YS51dGlsLkNhbGVuZGFyI0RBVEV9ID0gMSwgZXRjLgotICAgICAgICAgKiBUaGlzIGlzIGltcG9ydGFudCBhcyB0aGVyZSBhcmUgdmFyaWF0aW9ucyBpbiB0aGUgR3JlZ29yaWFuIENhbGVuZGFyLAotICAgICAgICAgKiBlLmcuIGxlYXAgeWVhcnMgaGF2ZSBkaWZmZXJlbnQgZGF5cyBpbiB0aGUgbW9udGggPSB7QGxpbmsgamF2YS51dGlsLkNhbGVuZGFyI0ZFQlJVQVJZfQotICAgICAgICAgKiBzbyB0aGUgcmVzdWx0IG9mIHtAbGluayBEdXJhdGlvbiNnZXRNb250aHMoKX0gY2FuIGJlIGluZmx1ZW5jZWQuPC9wPgotICAgICAgICAgKgotICAgICAqIDxwPkFueSByZW1haW5pbmcgbWlsbGlzZWNvbmRzIGFmdGVyIGRldGVybWluaW5nIHRoZSB5ZWFyIGFuZCBtb250aCBhcmUgZGlzY2FyZGVkLjwvcD4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIGR1cmF0aW9uSW5NaWxsaXNlY29uZHMgTWlsbGlzZWNvbmRzIG9mIDxjb2RlPkR1cmF0aW9uPC9jb2RlPiB0byBjcmVhdGUuCi0gICAgICAgICAqLwotICAgIHByb3RlY3RlZCBEdXJhdGlvblllYXJNb250aEltcGwobG9uZyBkdXJhdGlvbkluTWlsbGlzZWNvbmRzKSB7Ci0KLSAgICAgICAgc3VwZXIoZHVyYXRpb25Jbk1pbGxpc2Vjb25kcyk7Ci0gICAgICAgIGNvbnZlcnRUb0Nhbm9uaWNhbFllYXJNb250aCgpOwotICAgICAgICAvL0FueSByZW1haW5pbmcgbWlsbGlzZWNvbmRzIGFmdGVyIGRldGVybWluaW5nIHRoZSB5ZWFyIGFuZCBtb250aCBhcmUgZGlzY2FyZGVkLgotICAgICAgICBkYXlzID0gbnVsbDsKLSAgICAgICAgaG91cnMgPSBudWxsOwotICAgICAgICBtaW51dGVzID0gbnVsbDsKLSAgICAgICAgc2Vjb25kcyA9IG51bGw7Ci0gICAgICAgIHNpZ251bSA9IGNhbGNTaWdudW0oKHNpZ251bTwwKT9mYWxzZTp0cnVlKTsKLSAgICB9Ci0KLQotICAgICAgICAvKioKLSAgICAgICAgICogPHA+Q29uc3RydWN0IGEgPGNvZGU+RHVyYXRpb248L2NvZGU+IG9mIHR5cGUgPGNvZGU+eGR0OnllYXJNb250aER1cmF0aW9uPC9jb2RlPiBieSBwYXJzaW5nIGl0cyA8Y29kZT5TdHJpbmc8L2NvZGU+IHJlcHJlc2VudGF0aW9uLAotICAgICAgICAgKiAiPGVtPlBuWW5NPC9lbT4iLCA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aC1kYXRhbW9kZWwjeWVhck1vbnRoRHVyYXRpb24iPgotICAgICAgICAgKiAgIFhRdWVyeSAxLjAgYW5kIFhQYXRoIDIuMCBEYXRhIE1vZGVsLCB4ZHQ6eWVhck1vbnRoRHVyYXRpb248L2E+LjwvcD4KLSAgICAgICAgICoKLSAgICAgICAgICogPHA+VGhlIGRhdGF0eXBlIDxjb2RlPnhkdDp5ZWFyTW9udGhEdXJhdGlvbjwvY29kZT4gaXMgYSBzdWJ0eXBlIG9mIDxjb2RlPnhzOmR1cmF0aW9uPC9jb2RlPgotICAgICAgICAgKiB3aG9zZSBsZXhpY2FsIHJlcHJlc2VudGF0aW9uIGNvbnRhaW5zIG9ubHkgeWVhciBhbmQgbW9udGggY29tcG9uZW50cy4KLSAgICAgICAgICogVGhpcyBkYXRhdHlwZSByZXNpZGVzIGluIHRoZSBuYW1lc3BhY2Uge0BsaW5rIGphdmF4LnhtbC5YTUxDb25zdGFudHMjVzNDX1hQQVRIX0RBVEFUWVBFX05TX1VSSX0uPC9wPgotICAgICAgICAgKgotICAgICAqIDxwPkJvdGggdmFsdWVzIGFyZSBzZXQgYW5kIGF2YWlsYWJlIGZyb20gdGhlIGNyZWF0ZWQge0BsaW5rIER1cmF0aW9ufTwvcD4KLSAgICAgICAgICoKLSAgICAgKiA8cD5UaGUgWE1MIFNjaGVtYSBzcGVjaWZpY2F0aW9uIHN0YXRlcyB0aGF0IHZhbHVlcyBjYW4gYmUgb2YgYW4gYXJiaXRyYXJ5IHNpemUuCi0gICAgICogSW1wbGVtZW50YXRpb25zIG1heSBjaG9zZSBub3QgdG8gb3IgYmUgaW5jYXBhYmxlIG9mIHN1cHBvcnRpbmcgYXJiaXRyYXJpbHkgbGFyZ2UgYW5kL29yIHNtYWxsIHZhbHVlcy4KLSAgICAgKiBBbiB7QGxpbmsgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb259IHdpbGwgYmUgdGhyb3duIHdpdGggYSBtZXNzYWdlIGluZGljYXRpbmcgaW1wbGVtZW50YXRpb24gbGltaXRzCi0gICAgICogaWYgaW1wbGVtZW50YXRpb24gY2FwYWNpdGllcyBhcmUgZXhjZWVkZWQuPC9wPgotICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBsZXhpY2FsUmVwcmVzZW50YXRpb24gTGV4aWNhbCByZXByZXNlbnRhdGlvbiBvZiBhIGR1cmF0aW9uLgotICAgICAgICAgKgotICAgICAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBJZiA8Y29kZT5sZXhpY2FsUmVwcmVzZW50YXRpb248L2NvZGU+IGlzIG5vdCBhIHZhbGlkIHJlcHJlc2VudGF0aW9uIG9mIGEgPGNvZGU+RHVyYXRpb248L2NvZGU+IGV4cHJlc3NlZCBvbmx5IGluIHRlcm1zIG9mIHllYXJzIGFuZCBtb250aHMuCi0gICAgICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gSWYgaW1wbGVtZW50YXRpb24gY2Fubm90IHN1cHBvcnQgcmVxdWVzdGVkIHZhbHVlcy4KLSAgICAgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBJZiA8Y29kZT5sZXhpY2FsUmVwcmVzZW50YXRpb248L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAgICAgKi8KLSAgICBwcm90ZWN0ZWQgRHVyYXRpb25ZZWFyTW9udGhJbXBsKFN0cmluZyBsZXhpY2FsUmVwcmVzZW50YXRpb24pIHsKLSAgICAgICAgc3VwZXIobGV4aWNhbFJlcHJlc2VudGF0aW9uKTsKLSAgICAgICAgaWYgKGdldERheXMoKSA+IDAgfHwgZ2V0SG91cnMoKSA+IDAKLSAgICAgICAgICAgICAgICB8fCBnZXRNaW51dGVzKCkgPiAwIHx8IGdldFNlY29uZHMoKSA+IDApIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgICJUcnlpbmcgdG8gY3JlYXRlIGFuIHhkdDp5ZWFyTW9udGhEdXJhdGlvbiB3aXRoIGFuIGludmFsaWQiCi0gICAgICAgICAgICAgICAgICAgICsgIiBsZXhpY2FsIHJlcHJlc2VudGF0aW9uIG9mIFwiIiArIGxleGljYWxSZXByZXNlbnRhdGlvbgotICAgICAgICAgICAgICAgICAgICArICJcIiwgZGF0YSBtb2RlbCByZXF1aXJlcyBQblluTS4iKTsKLSAgICAgICAgfQotICAgICAgICBjb252ZXJ0VG9DYW5vbmljYWxZZWFyTW9udGgoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgdmFsdWUgc3BhY2Ugb2YgeHM6eWVhck1vbnRoRHVyYXRpb24gaXMgdGhlIHNldCBvZiB4czppbnRlZ2VyIG1vbnRoIHZhbHVlcy4KLSAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSBvZiB5ZWFyTW9udGhEdXJhdGlvbgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0VmFsdWUoKSB7Ci0gICAgICAgIHJldHVybiBnZXRZZWFycygpICogMTIgKyBnZXRNb250aHMoKTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgY29udmVydFRvQ2Fub25pY2FsWWVhck1vbnRoKCkgewotICAgICAgICB3aGlsZSAoZ2V0TW9udGhzKCkgPj0gMTIpCi0gICAgICAgIHsKLSAgICAgICAgICAgIG1vbnRocyA9IG1vbnRocy5zdWJ0cmFjdChCaWdJbnRlZ2VyLnZhbHVlT2YoMTIpKTsKLSAgICAgICAgICAgIHllYXJzID0gQmlnSW50ZWdlci52YWx1ZU9mKChsb25nKSBnZXRZZWFycygpKS5hZGQoQmlnSW50ZWdlci5PTkUpOwotICAgICAgICB9Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvamF4cC9kYXRhdHlwZS9YTUxHcmVnb3JpYW5DYWxlbmRhckltcGwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2pheHAvZGF0YXR5cGUvWE1MR3JlZ29yaWFuQ2FsZW5kYXJJbXBsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDg0NTQzZWMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvamF4cC9kYXRhdHlwZS9YTUxHcmVnb3JpYW5DYWxlbmRhckltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDMwOTMgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwNCwgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmpheHAuZGF0YXR5cGU7Ci0KLWltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKLWltcG9ydCBqYXZhLm1hdGguQmlnRGVjaW1hbDsKLWltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKLWltcG9ydCBqYXZhLnV0aWwuVGltZVpvbmU7Ci1pbXBvcnQgamF2YS51dGlsLkNhbGVuZGFyOwotaW1wb3J0IGphdmEudXRpbC5HcmVnb3JpYW5DYWxlbmRhcjsKLWltcG9ydCBqYXZhLnV0aWwuRGF0ZTsKLWltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwotCi1pbXBvcnQgamF2YXgueG1sLmRhdGF0eXBlLkRhdGF0eXBlQ29uc3RhbnRzOwotaW1wb3J0IGphdmF4LnhtbC5kYXRhdHlwZS5EdXJhdGlvbjsKLWltcG9ydCBqYXZheC54bWwuZGF0YXR5cGUuWE1MR3JlZ29yaWFuQ2FsZW5kYXI7Ci1pbXBvcnQgamF2YXgueG1sLm5hbWVzcGFjZS5RTmFtZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuRGF0YXR5cGVNZXNzYWdlRm9ybWF0dGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbHMuU2VjdXJpdHlTdXBwb3J0OwotCi0vKioKLSAqIDxwPlJlcHJlc2VudGF0aW9uIGZvciBXM0MgWE1MIFNjaGVtYSAxLjAgZGF0ZS90aW1lIGRhdGF0eXBlcy4KLSAqIFNwZWNpZmljYWxseSwgdGhlc2UgZGF0ZS90aW1lIGRhdGF0eXBlcyBhcmUKLSAqIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNEQVRFVElNRSBkYXRlVGltZX0sCi0gKiB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjVElNRSB0aW1lfSwKLSAqIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNEQVRFIGRhdGV9LAotICoge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0dZRUFSTU9OVEggZ1llYXJNb250aH0sCi0gKiB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjR01PTlRIREFZIGdNb250aERheX0sCi0gKiB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjR1lFQVIgZ1llYXJ9LAotICoge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0dNT05USCBnTW9udGh9IGFuZAotICoge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0dEQVkgZ0RheX0KLSAqIGRlZmluZWQgaW4gdGhlIFhNTCBOYW1lc3BhY2UKLSAqIDxjb2RlPiJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYSI8L2NvZGU+LgotICogVGhlc2UgZGF0YXR5cGVzIGFyZSBub3JtYXRpdmVseSBkZWZpbmVkIGluCi0gKiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94bWxzY2hlbWEtMi8jZGF0ZVRpbWUiPlczQyBYTUwgU2NoZW1hIDEuMCBQYXJ0IDIsIFNlY3Rpb24gMy4yLjctMTQ8L2E+LjwvcD4KLSAqCi0gKiA8cD5UaGUgdGFibGUgYmVsb3cgZGVmaW5lcyB0aGUgbWFwcGluZyBiZXR3ZWVuIFhNTCBTY2hlbWEgMS4wCi0gKiBkYXRlL3RpbWUgZGF0YXR5cGUgZmllbGRzIGFuZCB0aGlzIGNsYXNzJyBmaWVsZHMuIEl0IGFsc28gc3VtbWFyaXplcwotICogdGhlIHZhbHVlIGNvbnN0cmFpbnRzIGZvciB0aGUgZGF0ZSBhbmQgdGltZSBmaWVsZHMgZGVmaW5lZCBpbgotICogPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveG1sc2NoZW1hLTIvI2lzb2Zvcm1hdHMiPlczQyBYTUwgU2NoZW1hIDEuMCBQYXJ0IDIsIEFwcGVuZGl4IEQsCi0gKiA8aT5JU08gODYwMSBEYXRlIGFuZCBUaW1lIEZvcm1hdHM8L2k+PC9hPi48L3A+Ci0gKgotICogPGEgbmFtZT0iZGF0ZXRpbWVmaWVsZHNtYXBwaW5nIi8+Ci0gKiA8dGFibGUgYm9yZGVyPSIyIiBydWxlcz0iYWxsIiBjZWxscGFkZGluZz0iMiI+Ci0gKiAgIDx0aGVhZD4KLSAqICAgICA8dHI+Ci0gKiAgICAgICA8dGggYWxpZ249ImNlbnRlciIgY29sc3Bhbj0iMyI+Ci0gKiAgICAgICAgIERhdGUvdGltZSBkYXRhdHlwZSBmaWVsZCBtYXBwaW5nIGJldHdlZW4gWE1MIFNjaGVtYSAxLjAgYW5kIEphdmEgcmVwcmVzZW50YXRpb24KLSAqICAgICAgIDwvdGg+Ci0gKiAgICAgPC90cj4KLSAqICAgPC90aGVhZD4KLSAqICAgPHRib2R5PgotICogICAgIDx0cj4KLSAqICAgICAgIDx0aD5YTUwgU2NoZW1hIDEuMDxici8+Ci0gKiAgICAgICAgICAgZGF0YXR5cGU8YnIvPgotICogICAgICAgICAgICBmaWVsZDwvdGg+Ci0gKiAgICAgICA8dGg+UmVsYXRlZDxici8+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8YnIvPkFjY2Vzc29yKHMpPC90aD4KLSAqICAgICAgIDx0aD5WYWx1ZSBSYW5nZTwvdGg+Ci0gKiAgICAgPC90cj4KLSAqICAgICA8YSBuYW1lPSJkYXRldGltZWZpZWxkLXllYXIiLz4KLSAqICAgICA8dHI+Ci0gKiAgICAgICA8dGQ+IHllYXIgPC90ZD4KLSAqICAgICAgIDx0ZD4ge0BsaW5rICNnZXRZZWFyKCl9ICsge0BsaW5rICNnZXRFb24oKX0gb3I8YnIvPgotICogICAgICAgICAgICB7QGxpbmsgI2dldEVvbkFuZFllYXJ9Ci0gKiAgICAgICA8L3RkPgotICogICAgICAgPHRkPiA8Y29kZT5nZXRZZWFyKCk8L2NvZGU+IGlzIGEgdmFsdWUgYmV0d2VlbiAtKDEwXjktMSkgdG8gKDEwXjkpLTEKLSAqICAgICAgICAgICAgb3Ige0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0ZJRUxEX1VOREVGSU5FRH0uPGJyLz4KLSAqICAgICAgICAgICAge0BsaW5rICNnZXRFb24oKX0gaXMgaGlnaCBvcmRlciB5ZWFyIHZhbHVlIGluIGJpbGxpb24gb2YgeWVhcnMuPGJyLz4KLSAqICAgICAgICAgICAgPGNvZGU+Z2V0RW9uKCk8L2NvZGU+IGhhcyB2YWx1ZXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICgxMF45KSBvciBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gLSgxMF45KS4KLSAqICAgICAgICAgICAgQSB2YWx1ZSBvZiBudWxsIGluZGljYXRlcyBmaWVsZCBpcyB1bmRlZmluZWQuPC9icj4KLSAqICAgICAgICAgICAgR2l2ZW4gdGhhdCA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzA1L3htbHNjaGVtYS1lcnJhdGEjZTItNjMiPlhNTCBTY2hlbWEgMS4wIGVycmF0YTwvYT4gc3RhdGVzIHRoYXQgdGhlIHllYXIgemVybwotICogICAgICAgICAgICB3aWxsIGJlIGEgdmFsaWQgbGV4aWNhbCB2YWx1ZSBpbiBhIGZ1dHVyZSB2ZXJzaW9uIG9mIFhNTCBTY2hlbWEsCi0gKiAgICAgICAgICAgIHRoaXMgY2xhc3MgYWxsb3dzIHRoZSB5ZWFyIGZpZWxkIHRvIGJlIHNldCB0byB6ZXJvLiBPdGhlcndpc2UsCi0gKiAgICAgICAgICAgIHRoZSB5ZWFyIGZpZWxkIHZhbHVlIGlzIGhhbmRsZWQgZXhhY3RseSBhcyBkZXNjcmliZWQKLSAqICAgICAgICAgICAgaW4gdGhlIGVycmF0YSBhbmQgW0lTTy04NjAxLTE5ODhdLiBOb3RlIHRoYXQgVzNDIFhNTCBTY2hlbWEgMS4wCi0gKiAgICAgICAgICAgIHZhbGlkYXRpb24gZG9lcyBub3QgYWxsb3cgZm9yIHRoZSB5ZWFyIGZpZWxkIHRvIGhhdmUgYSB2YWx1ZSBvZiB6ZXJvLgotICogICAgICAgICAgICA8L3RkPgotICogICAgIDwvdHI+Ci0gKiAgICAgPGEgbmFtZT0iZGF0ZXRpbWVmaWVsZC1tb250aCIvPgotICogICAgIDx0cj4KLSAqICAgICAgIDx0ZD4gbW9udGggPC90ZD4KLSAqICAgICAgIDx0ZD4ge0BsaW5rICNnZXRNb250aCgpfSA8L3RkPgotICogICAgICAgPHRkPiAxIHRvIDEyIG9yIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNGSUVMRF9VTkRFRklORUR9IDwvdGQ+Ci0gKiAgICAgPC90cj4KLSAqICAgICA8YSBuYW1lPSJkYXRldGltZWZpZWxkLWRheSIvPgotICogICAgIDx0cj4KLSAqICAgICAgIDx0ZD4gZGF5IDwvdGQ+Ci0gKiAgICAgICA8dGQ+IHtAbGluayAjZ2V0RGF5KCl9IDwvdGQ+Ci0gKiAgICAgICA8dGQ+IEluZGVwZW5kZW50IG9mIG1vbnRoLCBtYXggcmFuZ2UgaXMgMSB0byAzMSBvciB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjRklFTERfVU5ERUZJTkVEfS48YnIvPgotICogICAgICAgICAgICBUaGUgbm9ybWF0aXZlIHZhbHVlIGNvbnN0cmFpbnQgc3RhdGVkIHJlbGF0aXZlIHRvIG1vbnRoCi0gKiAgICAgICAgICAgIGZpZWxkJ3MgdmFsdWUgaXMgaW4gPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveG1sc2NoZW1hLTIvI2lzb2Zvcm1hdHMiPlczQyBYTUwgU2NoZW1hIDEuMCBQYXJ0IDIsIEFwcGVuZGl4IEQ8L2E+LgotICogICAgICAgPC90ZD4KLSAqICAgICA8L3RyPgotICogICAgIDxhIG5hbWU9ImRhdGV0aW1lZmllbGQtaG91ciIvPgotICogICAgIDx0cj4KLSAqICAgICAgIDx0ZD4gaG91ciA8L3RkPgotICogICAgICAgPHRkPiB7QGxpbmsgI2dldEhvdXIoKX0gPC90ZD4KLSAqICAgICAgIDx0ZD4KLSAqICAgICAgICAgMCB0byAyMyBvciB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjRklFTERfVU5ERUZJTkVEfS4KLSAqICAgICAgICAgQW4gaG91ciB2YWx1ZSBvZiAyNCBpcyBhbGxvd2VkIHRvIGJlIHNldCBpbiB0aGUgbGV4aWNhbCBzcGFjZSBwcm92aWRlZCB0aGUgbWludXRlIGFuZCBzZWNvbmQKLSAqICAgICAgICAgZmllbGQgdmFsdWVzIGFyZSB6ZXJvLiBIb3dldmVyLCBhbiBob3VyIHZhbHVlIG9mIDI0IGlzIG5vdCBhbGxvd2VkIGluIHZhbHVlIHNwYWNlIGFuZCB3aWxsIGJlCi0gKiAgICAgICAgIHRyYW5zZm9ybWVkIHRvIHJlcHJlc2VudCB0aGUgdmFsdWUgb2YgdGhlIGZpcnN0IGluc3RhbmNlIG9mIHRoZSBmb2xsb3dpbmcgZGF5IGFzIHBlcgotICogICAgICAgICA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94bWxzY2hlbWEtMi8jYnVpbHQtaW4tcHJpbWl0aXZlLWRhdGF0eXBlcyI+Ci0gKiAgICAgICAgIFhNTCBTY2hlbWEgUGFydCAyOiBEYXRhdHlwZXMgU2Vjb25kIEVkaXRpb24sIDMuMiBQcmltaXRpdmUgZGF0YXR5cGVzPC9hPi4KLSAqICAgICAgIDwvdGQ+Ci0gKiAgICAgPC90cj4KLSAqICAgICA8YSBuYW1lPSJkYXRldGltZWZpZWxkLW1pbnV0ZSIvPgotICogICAgIDx0cj4KLSAqICAgICAgIDx0ZD4gbWludXRlIDwvdGQ+Ci0gKiAgICAgICA8dGQ+IHtAbGluayAjZ2V0TWludXRlKCl9IDwvdGQ+Ci0gKiAgICAgICA8dGQ+IDAgdG8gNTkgb3Ige0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0ZJRUxEX1VOREVGSU5FRH0gPC90ZD4KLSAqICAgICA8L3RyPgotICogICAgIDxhIG5hbWU9ImRhdGV0aW1lZmllbGQtc2Vjb25kIi8+Ci0gKiAgICAgPHRyPgotICogICAgICAgPHRkPnNlY29uZDwvdGQ+Ci0gKiAgICAgICA8dGQ+Ci0gKiAgICAgICAgIHtAbGluayAjZ2V0U2Vjb25kKCl9ICsge0BsaW5rICNnZXRNaWxsaXNlY29uZCgpfS8xMDAwIG9yPGJyLz4KLSAqICAgICAgICAge0BsaW5rICNnZXRTZWNvbmQoKX0gKyB7QGxpbmsgI2dldEZyYWN0aW9uYWxTZWNvbmQoKX0KLSAqICAgICAgIDwvdGQ+Ci0gKiAgICAgICA8dGQ+Ci0gKiAgICAgICAgIHtAbGluayAjZ2V0U2Vjb25kKCl9IGZyb20gMCB0byA2MCBvciB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjRklFTERfVU5ERUZJTkVEfS48YnIvPgotICogICAgICAgICA8aT4oTm90ZTogNjAgb25seSBhbGxvd2FibGUgZm9yIGxlYXAgc2Vjb25kLik8L2k+PGJyLz4KLSAqICAgICAgICAge0BsaW5rICNnZXRGcmFjdGlvbmFsU2Vjb25kKCl9IGFsbG93cyBmb3IgaW5maW5pdGUgcHJlY2lzaW9uIG92ZXIgdGhlIHJhbmdlIGZyb20gMC4wIHRvIDEuMCB3aGVuCi0gKiAgICAgICAgIHRoZSB7QGxpbmsgI2dldFNlY29uZCgpfSBpcyBkZWZpbmVkLjxici8+Ci0gKiAgICAgICAgIDxjb2RlPkZyYWN0aW9uYWxTZWNvbmQ8L2NvZGU+IGlzIG9wdGlvbmFsIGFuZCBoYXMgYSB2YWx1ZSBvZiA8Y29kZT5udWxsPC9jb2RlPiB3aGVuIGl0IGlzIHVuZGVmaW5lZC48YnIgLz4KLSAqICAgICAgICAgICAge0BsaW5rICNnZXRNaWxsaXNlY29uZCgpfSBpcyB0aGUgY29udmVuaWVuY2UKLSAqICAgICAgICAgICAgbWlsbGlzZWNvbmQgcHJlY2lzaW9uIG9mIHZhbHVlIG9mIHtAbGluayAjZ2V0RnJhY3Rpb25hbFNlY29uZCgpfS4KLSAqICAgICAgIDwvdGQ+Ci0gKiAgICAgPC90cj4KLSAqICAgICA8dHIgaWQ9ImRhdGV0aW1lZmllbGQtdGltZXpvbmUiPgotICogICAgICAgPHRkPiB0aW1lem9uZSA8L3RkPgotICogICAgICAgPHRkPiB7QGxpbmsgI2dldFRpbWV6b25lKCl9IDwvdGQ+Ci0gKiAgICAgICA8dGQ+IE51bWJlciBvZiBtaW51dGVzIG9yIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNGSUVMRF9VTkRFRklORUR9LgotICogICAgICAgICBWYWx1ZSByYW5nZSBmcm9tIC0xNCBob3VycyAoLTE0ICogNjAgbWludXRlcykgdG8gMTQgaG91cnMgKDE0ICogNjAgbWludXRlcykuCi0gKiAgICAgICA8L3RkPgotICogICAgIDwvdHI+Ci0gKiAgIDwvdGJvZHk+Ci0gKiAgPC90YWJsZT4KLSAqCi0gKiA8cD5BbGwgbWF4aW11bSB2YWx1ZSBzcGFjZSBjb25zdHJhaW50cyBsaXN0ZWQgZm9yIHRoZSBmaWVsZHMgaW4gdGhlIHRhYmxlCi0gKiBhYm92ZSBhcmUgY2hlY2tlZCBieSBmYWN0b3J5IG1ldGhvZHMsIHNldHRlciBtZXRob2RzIGFuZCBwYXJzZSBtZXRob2RzIG9mCi0gKiB0aGlzIGNsYXNzLiA8Y29kZT5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb248L2NvZGU+IGlzIHRocm93biB3aGVuCi0gKiBwYXJhbWV0ZXIncyB2YWx1ZSBpcyBvdXRzaWRlIHRoZSBtYXhpbXVtIHZhbHVlIGNvbnN0cmFpbnQgZm9yIHRoZSBmaWVsZC4KLSAqIFZhbGlkYXRpb24gY2hlY2tzLCBmb3IgZXhhbXBsZSwgd2hldGhlciBkYXlzIGluIG1vbnRoIHNob3VsZCBiZQotICogbGltaXRlZCB0byAyOSwgMzAgb3IgMzEgZGF5cywgdGhhdCBhcmUgZGVwZW5kZW50IG9uIHRoZSB2YWx1ZXMgb2Ygb3RoZXIKLSAqIGZpZWxkcyBhcmUgbm90IGNoZWNrZWQgYnkgdGhlc2UgbWV0aG9kcy4KLSAqIDwvcD4KLSAqCi0gKiA8cD5UaGUgZm9sbG93aW5nIG9wZXJhdGlvbnMgYXJlIGRlZmluZWQgZm9yIHRoaXMgY2xhc3M6Ci0gKiA8dWw+Ci0gKiAgIDxsaT5mYWN0b3J5IG1ldGhvZHMgdG8gY3JlYXRlIGluc3RhbmNlczwvbGk+Ci0gKiAgIDxsaT5hY2Nlc3NvcnMvbXV0YXRvcnMgZm9yIGluZGVwZW5kZW50IGRhdGUvdGltZSBmaWVsZHM8L2xpPgotICogICA8bGk+Y29udmVyc2lvbiBiZXR3ZWVuIHRoaXMgY2xhc3MgYW5kIFczQyBYTUwgU2NoZW1hIDEuMCBsZXhpY2FsIHJlcHJlc2VudGF0aW9uPC9saT4KLSAqICAgPGxpPmNvbnZlcnNpb24gYmV0d2VlbiB0aGlzIGNsYXNzIGFuZCA8Y29kZT5qYXZhLnV0aWwuR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+PC9saT4KLSAqICAgPGxpPnBhcnRpYWwgb3JkZXIgcmVsYXRpb24gY29tcGFyYXRvciBtZXRob2QsIHtAbGluayAjY29tcGFyZShYTUxHcmVnb3JpYW5DYWxlbmRhcil9PC9saT4KLSAqICAgPGxpPntAbGluayAjZXF1YWxzKE9iamVjdCl9IGRlZmluZWQgcmVsYXRpdmUgdG8ge0BsaW5rICNjb21wYXJlKFhNTEdyZWdvcmlhbkNhbGVuZGFyKX0uPC9saT4KLSAqICAgPGxpPiBhZGRpdGlvbiBvcGVyYXRpb24gd2l0aCB7QGxpbmsgamF2YXgueG1sLmRhdGF0eXBlLkR1cmF0aW9ufS4KLSAqIGluc3RhbmNlIGFzIGRlZmluZWQgaW4gPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveG1sc2NoZW1hLTIvI2FkZGluZy1kdXJhdGlvbnMtdG8tZGF0ZVRpbWVzIj4KLSAqIFczQyBYTUwgU2NoZW1hIDEuMCBQYXJ0IDIsIEFwcGVuZGl4IEUsIDxpPkFkZGluZyBkdXJhdGlvbnMgdG8gZGF0ZVRpbWVzPC9pPjwvYT4uPC9saT4KLSAqIDwvdWw+Ci0gKiA8L3A+Ci0gKgotICogQGF1dGhvciA8YSBocmVmPSJtYWlsdG86S29oc3VrZS5LYXdhZ3VjaGlAU3VuLmNvbSI+S29oc3VrZSBLYXdhZ3VjaGk8L2E+Ci0gKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzpKb3NlcGguRmlhbGxpQFN1bi5jb20iPkpvc2VwaCBGaWFsbGk8L2E+Ci0gKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzpTdW5pdGhhLlJlZGR5QFN1bi5jb20iPlN1bml0aGEgUmVkZHk8L2E+Ci0gKiBAdmVyc2lvbiAkUmV2aXNpb246IDEuMTQgJCwgJERhdGU6IDIwMTAtMTEtMTAgMDc6NDE6NDEgJAotICogQHNlZSBqYXZheC54bWwuZGF0YXR5cGUuRHVyYXRpb24KLSAqIEBzaW5jZSAxLjUKLSAqLwotCi1wdWJsaWMgY2xhc3MgWE1MR3JlZ29yaWFuQ2FsZW5kYXJJbXBsCi0gICAgICAgIGV4dGVuZHMgWE1MR3JlZ29yaWFuQ2FsZW5kYXIKLSAgICAgICAgaW1wbGVtZW50cyBTZXJpYWxpemFibGUsIENsb25lYWJsZSB7Ci0KLSAgICAvKioKLSAgICAgKiA8cD5Fb24gb2YgdGhpcyA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4uPC9wPgotICAgICAqLwotICAgIHByaXZhdGUgQmlnSW50ZWdlciBlb24gPSBudWxsOwotCi0gICAgLyoqCi0gICAgICogPHA+WWVhciBvZiB0aGlzIDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPi48L3A+Ci0gICAgICovCi0gICAgcHJpdmF0ZSBpbnQgeWVhciA9IERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRDsKLQotICAgIC8qKgotICAgICAqIDxwPk1vbnRoIG9mIHRoaXMgPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+LjwvcD4KLSAgICAgKi8KLSAgICBwcml2YXRlIGludCBtb250aCA9IERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRDsKLQotICAgIC8qKgotICAgICAqIDxwPkRheSBvZiB0aGlzIDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPi48L3A+Ci0gICAgICovCi0gICAgcHJpdmF0ZSBpbnQgZGF5ID0gRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVEOwotCi0gICAgLyoqCi0gICAgICogPHA+VGltZXpvbmUgb2YgdGhpcyA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gaW4gbWludXRlcy48L3A+Ci0gICAgICovCi0gICAgcHJpdmF0ZSBpbnQgdGltZXpvbmUgPSBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQ7Ci0KLSAgICAvKioKLSAgICAgKiA8cD5Ib3VyIG9mIHRoaXMgPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+LjwvcD4KLSAgICAgKi8KLSAgICBwcml2YXRlIGludCBob3VyID0gRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVEOwotCi0gICAgLyoqCi0gICAgICogPHA+TWludXRlIG9mIHRoaXMgPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+LjwvcD4KLSAgICAgKi8KLSAgICBwcml2YXRlIGludCBtaW51dGUgPSBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQ7Ci0KLSAgICAvKioKLSAgICAgKiA8cD5TZWNvbmQgb2YgdGhpcyA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4uPC9wPgotICAgICAqLwotICAgIHByaXZhdGUgaW50IHNlY29uZCA9IERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCA7Ci0KLSAgICAvKioKLSAgICAgKiA8cD5GcmFjdGlvbmFsIHNlY29uZCBvZiB0aGlzIDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPi48L3A+Ci0gICAgICovCi0gICAgcHJpdmF0ZSBCaWdEZWNpbWFsIGZyYWN0aW9uYWxTZWNvbmQgPSBudWxsOwotCi0gICAgLyoqCi0gICAgICogPHA+Q29uc3RhbnQgdG8gcmVwcmVzZW50IGEgYmlsbGlvbi48L3A+Ci0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQmlnSW50ZWdlciBCSUxMSU9OID0gbmV3IEJpZ0ludGVnZXIoIjEwMDAwMDAwMDAiKTsKLQotICAgIC8qKgotICAgICAqICAgPHA+T2J0YWluIGEgcHVyZSBHcmVnb3JpYW4gQ2FsZW5kYXIgYnkgY2FsbGluZwotICAgICAqICAgR3JlZ29yaWFuQ2FsZW5kYXIuc2V0Q2hhbmdlKFBVUkVfR1JFR09SSUFOX0NIQU5HRSkuIDwvcD4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBEYXRlIFBVUkVfR1JFR09SSUFOX0NIQU5HRSA9Ci0gICAgICAgIG5ldyBEYXRlKExvbmcuTUlOX1ZBTFVFKTsKLQotICAgIC8qKgotICAgICAqIFllYXIgaW5kZXggZm9yIE1JTl8gYW5kIE1BWF9GSUVMRF9WQUxVRVMuCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFlFQVIgICA9IDA7Ci0KLSAgICAvKioKLSAgICAgKiBNb250aCBpbmRleCBmb3IgTUlOXyBhbmQgTUFYX0ZJRUxEX1ZBTFVFUy4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTU9OVEggID0gMTsKLQotICAgIC8qKgotICAgICAqIERheSBpbmRleCBmb3IgTUlOXyBhbmQgTUFYX0ZJRUxEX1ZBTFVFUy4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgREFZICAgID0gMjsKLQotICAgIC8qKgotICAgICAqIEhvdXIgaW5kZXggZm9yIE1JTl8gYW5kIE1BWF9GSUVMRF9WQUxVRVMuCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEhPVVIgICA9IDM7Ci0KLSAgICAvKioKLSAgICAgKiBNaW51dGUgaW5kZXggZm9yIE1JTl8gYW5kIE1BWF9GSUVMRF9WQUxVRVMuCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE1JTlVURSA9IDQ7Ci0KLSAgICAvKioKLSAgICAgKiBTZWNvbmQgaW5kZXggZm9yIE1JTl8gYW5kIE1BWF9GSUVMRF9WQUxVRVMuCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFNFQ09ORCA9IDU7Ci0KLSAgICAvKioKLSAgICAgKiBTZWNvbmQgaW5kZXggZm9yIE1JTl8gYW5kIE1BWF9GSUVMRF9WQUxVRVMuCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE1JTExJU0VDT05EID0gNjsKLQotICAgIC8qKgotICAgICAqIFRpbWV6b25lIGluZGV4IGZvciBNSU5fIGFuZCBNQVhfRklFTERfVkFMVUVTCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFRJTUVaT05FID0gNzsKLQotCi0gICAgLyoqCi0gICAgICogZmllbGQgbmFtZXMgaW5kZXhlZCBieSBZRUFSLi5USU1FWk9ORS4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRklFTERfTkFNRVtdID0gewotICAgICAgICAiWWVhciIsCi0gICAgICAgICJNb250aCIsCi0gICAgICAgICJEYXkiLAotICAgICAgICAiSG91ciIsCi0gICAgICAgICJNaW51dGUiLAotICAgICAgICAiU2Vjb25kIiwKLSAgICAgICAgIk1pbGxpc2Vjb25kIiwKLSAgICAgICAgIlRpbWV6b25lIgotICAgIH07Ci0KLSAgICAvKioKLSAgICAgKiA8cD5TdHJlYW0gVW5pcXVlIElkZW50aWZpZXIuPC9wPgotICAgICAqCi0gICAgICogPHA+VE9ETzogU2VyaWFsaXphdGlvbiBzaG91bGQgdXNlIHRoZSBYTUwgc3RyaW5nIHJlcHJlc2VudGF0aW9uIGFzCi0gICAgICogdGhlIHNlcmlhbGl6YXRpb24gZm9ybWF0IHRvIGVuc3VyZSBmdXR1cmUgY29tcGF0aWJpbGl0eS48L3A+Ci0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMUw7Ci0KLSAgICAvKioKLSAgICAgKiA8cD5Vc2UgYXMgYSB0ZW1wbGF0ZSBmb3IgZGVmYXVsdCBmaWVsZCB2YWx1ZXMgd2hlbgotICAgICAqIGNvbnZlcnRpbmcgdG8gYSB7QGxpbmsgR3JlZ29yaWFuQ2FsZW5kYXJ9LCBzZXQgdG8gYSBsZWFwCi0gICAgICogeWVhciBkYXRlIG9mIEphbnVhcnkgMSwgMDQwMCBhdCBtaWRuaWdodC48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5GaWVsZHMgdGhhdCBhcmUgb3B0aW9uYWwgZm9yIGFuIDxjb2RlPnhzZDpkYXRlVGltZTwvY29kZT4gaW5zdGFuY2VzIGFyZSBkZWZhdWx0ZWQgdG8gbm90IGJlaW5nIHNldCB0byBhbnkgdmFsdWUuCi0gICAgICogPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IGZpZWxkcyBtaWxsaXNlY29uZCwgZnJhY3Rpb25hbCBzZWNvbmQgYW5kIHRpbWV6b25lIHJldHVybiB0aGUgdmFsdWUgaW5kaWNhdGluZwotICAgICAqIHRoYXQgdGhlIGZpZWxkIGlzIG5vdCBzZXQsIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNGSUVMRF9VTkRFRklORUR9IGZvciBtaWxsaXNlY29uZCBhbmQgdGltZXpvbmUKLSAgICAgKiBhbmQgPGNvZGU+bnVsbDwvY29kZT4gZm9yIGZyYWN0aW9uYWwgc2Vjb25kLjwvcD4KLSAgICAgKgotICAgICAqIEBzZWUgI3RvR3JlZ29yaWFuQ2FsZW5kYXIoVGltZVpvbmUsIExvY2FsZSwgWE1MR3JlZ29yaWFuQ2FsZW5kYXIpCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBYTUxHcmVnb3JpYW5DYWxlbmRhciBMRUFQX1lFQVJfREVGQVVMVCA9Ci0gICAgICAgICAgICAgICAgY3JlYXRlRGF0ZVRpbWUoCi0gICAgICAgICAgICAgICAgICAgICAgICA0MDAsICAvL3llYXIKLSAgICAgICAgICAgICAgICBEYXRhdHlwZUNvbnN0YW50cy5KQU5VQVJZLCAgLy9tb250aAotICAgICAgICAgICAgICAgICAgICAgICAgMSwgIC8vIGRheQotICAgICAgICAgICAgICAgICAgICAwLCAgLy8gaG91cgotICAgICAgICAgICAgICAgICAgICAwLCAgLy8gbWludXRlCi0gICAgICAgICAgICAgICAgICAgIDAsICAvLyBzZWNvbmQKLSAgICAgICAgICAgICAgICAgICAgRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVELCAgLy8gbWlsbGlzZWNvbmRzCi0gICAgICAgICAgICAgICAgICAgIERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCAvLyB0aW1lem9uZQotICAgICAgICAgICAgICAgICk7Ci0KLSAgICAvLyBDb25zdHJ1Y3RvcnMKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHMgYSBuZXcgWE1MR3JlZ29yaWFuQ2FsZW5kYXIgb2JqZWN0LgotICAgICAqCi0gICAgICogU3RyaW5nIHBhcnNpbmcgZG9jdW1lbnRlZCBieSB7QGxpbmsgI3BhcnNlKFN0cmluZyl9LgotICAgICAqCi0gICAgICogUmV0dXJucyBhIG5vbi1udWxsIHZhbGlkIFhNTEdyZWdvcmlhbkNhbGVuZGFyIG9iamVjdCB0aGF0IGhvbGRzIHRoZQotICAgICAqIHZhbHVlIGluZGljYXRlZCBieSB0aGUgbGV4aWNhbFJlcHJlc2VudGF0aW9uIHBhcmFtZXRlci4KLSAgICAgKgotICAgICAqIEBwYXJhbSBsZXhpY2FsUmVwcmVzZW50YXRpb24KLSAgICAgKiAgICAgIExleGljYWwgcmVwcmVzZW50YXRpb24gb2Ygb25lIHRoZSBlaWdodAotICAgICAqICAgICAgWE1MIFNjaGVtYSBkYXRlL3RpbWUgZGF0YXR5cGVzLgotICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCi0gICAgICogICAgICBJZiB0aGUgZ2l2ZW4gc3RyaW5nIGRvZXMgbm90IGNvbmZvcm0gYXMgZG9jdW1lbnRlZCBpbgotICAgICAqICAgICAge0BsaW5rICNwYXJzZShTdHJpbmcpfS4KLSAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCi0gICAgICogICAgICBJZiB0aGUgZ2l2ZW4gc3RyaW5nIGlzIG51bGwuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIFhNTEdyZWdvcmlhbkNhbGVuZGFySW1wbChTdHJpbmcgbGV4aWNhbFJlcHJlc2VudGF0aW9uKQotICAgICAgICAgICAgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy8gY29tcHV0ZSBmb3JtYXQgc3RyaW5nIGZvciB0aGlzIGxleGljYWwgcmVwcmVzZW50YXRpb24uCi0gICAgICAgIFN0cmluZyBmb3JtYXQgPSBudWxsOwotICAgICAgICBTdHJpbmcgbGV4UmVwID0gbGV4aWNhbFJlcHJlc2VudGF0aW9uOwotICAgICAgICBmaW5hbCBpbnQgTk9UX0ZPVU5EID0gLTE7Ci0gICAgICAgIGludCBsZXhSZXBMZW5ndGggPSBsZXhSZXAubGVuZ3RoKCk7Ci0KLSAgICAgICAgLy8gY3VycmVudCBwYXJzZXIgbmVlZHMgYSBmb3JtYXQgc3RyaW5nLAotICAgICAgICAvLyB1c2UgZm9sbG93aW5nIGhldXJpc3RpY3MgdG8gZmlndXJlIG91dCB3aGF0IHhtbCBzY2hlbWEgZGF0ZS90aW1lCi0gICAgICAgIC8vIGRhdGF0eXBlIHRoaXMgbGV4aWNhbCBzdHJpbmcgY291bGQgcmVwcmVzZW50LgotICAgICAgICAvLyBGaXggNDk3MTYxMjogaW52YWxpZCBTQ0NTIG1hY3JvIHN1YnN0aXR1dGlvbiBpbiBkYXRhIHN0cmluZywKLSAgICAgICAgLy8gICBubyAle2FscGhhfSUgdG8gYXZvaWQgU0NDUyBtYWNvIHN1YnN0aXR1dGlvbgotICAgICAgICBpZiAobGV4UmVwLmluZGV4T2YoJ1QnKSAhPSBOT1RfRk9VTkQpIHsKLSAgICAgICAgICAgIC8vIGZvdW5kIERhdGUgVGltZSBzZXBhcmF0ZXIsIG11c3QgYmUgeHNkOkRhdGVUaW1lCi0gICAgICAgICAgICBmb3JtYXQgPSAiJVktJU0tJURUJWg6JW06JXMiICsgIiV6IjsKLSAgICAgICAgfSBlbHNlIGlmIChsZXhSZXBMZW5ndGggPj0gMyAmJiBsZXhSZXAuY2hhckF0KDIpID09ICc6JykgewotICAgICAgICAgICAgLy8gZm91bmQgIjoiLCBtdXN0IGJlIHhzZDpUaW1lCi0gICAgICAgICAgICBmb3JtYXQgPSAiJWg6JW06JXMiICsgIiV6IjsKLSAgICAgICAgfSBlbHNlIGlmIChsZXhSZXAuc3RhcnRzV2l0aCgiLS0iKSkgewotICAgICAgICAgICAgLy8gY2hlY2sgZm9yIGdEYXkgfHwgZ01vbnRoIHx8IGdNb250aERheQotICAgICAgICAgICAgaWYgKGxleFJlcExlbmd0aCA+PSAzICYmIGxleFJlcC5jaGFyQXQoMikgPT0gJy0nKSB7Ci0gICAgICAgICAgICAgICAgLy8gZ0RheSwgLS0tREQoej8pCi0gICAgICAgICAgICAgICAgZm9ybWF0ID0gIi0tLSVEIiArICIleiI7Ci0gICAgICAgICAgICB9IGVsc2UgaWYgKGxleFJlcExlbmd0aCA9PSA0ICAgICAvLyAtLU1NCi0gICAgICAgICAgICAgICAgICAgIHx8IGxleFJlcExlbmd0aCA9PSA1ICAgICAvLyAtLU1NWgotICAgICAgICAgICAgICAgICAgICB8fCBsZXhSZXBMZW5ndGggPT0gMTApIHsgLy8gLS1NTVNISDpNTQotICAgICAgICAgICAgICAgIC8vIGdNb250aCwgLS1NTSh6PyksCi0gICAgICAgICAgICAgICAgLy8gcGVyIFhNTCBTY2hlbWEgRXJyYXRhLCB1c2VkIHRvIGJlIC0tTU0tLSh6PykKLSAgICAgICAgICAgICAgICBmb3JtYXQgPSAiLS0lTSIgKyAiJXoiOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAvLyBnTW9udGhEYXksIC0tTU0tREQoej8pLCAob3IgaW52YWxpZCBsZXhpY2FsUmVwcmVzZW50YXRpb24pCi0gICAgICAgICAgICAgICAgLy8gbGVuZ3RoIHNob3VsZCBiZToKLSAgICAgICAgICAgICAgICAvLyAgNzogLS1NTS1ERAotICAgICAgICAgICAgICAgIC8vICA4OiAtLU1NLUREWgotICAgICAgICAgICAgICAgIC8vIDEzOiAtLU1NLUREU0hIOk1NCi0gICAgICAgICAgICAgICAgZm9ybWF0ID0gIi0tJU0tJUQiICsgIiV6IjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIC8vIGNoZWNrIGZvciBEYXRlIHx8IEdZZWFyIHwgR1llYXJNb250aAotICAgICAgICAgICAgaW50IGNvdW50U2VwYXJhdG9yID0gMDsKLQotICAgICAgICAgICAgLy8gc3RhcnQgYXQgaW5kZXggMSB0byBza2lwIHBvdGVudGlhbCBuZWdhdGl2ZSBzaWduIGZvciB5ZWFyLgotCi0KLSAgICAgICAgICAgIGludCB0aW1lem9uZU9mZnNldCA9IGxleFJlcC5pbmRleE9mKCc6Jyk7Ci0gICAgICAgICAgICBpZiAodGltZXpvbmVPZmZzZXQgIT0gTk9UX0ZPVU5EKSB7Ci0KLSAgICAgICAgICAgICAgICAvLyBmb3VuZCB0aW1lem9uZSwgc3RyaXAgaXQgb2ZmIGZvciBkaXN0aW5ndWlzaGluZwotICAgICAgICAgICAgICAgIC8vIGJldHdlZW4gRGF0ZSwgR1llYXIgYW5kIEdZZWFyTW9udGggc28gcG9zc2libGUKLSAgICAgICAgICAgICAgICAvLyBuZWdhdGl2ZSBzaWduIGluIHRpbWV6b25lIGlzIG5vdCBtaXN0YWtlbiBhcwotICAgICAgICAgICAgICAgIC8vIGEgc2VwYXJhdG9yLgotICAgICAgICAgICAgICAgIGxleFJlcExlbmd0aCAtPSA2OwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBmb3IgKGludCBpID0gMTsgaSA8IGxleFJlcExlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGxleFJlcC5jaGFyQXQoaSkgPT0gJy0nKSB7Ci0gICAgICAgICAgICAgICAgICAgIGNvdW50U2VwYXJhdG9yKys7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKGNvdW50U2VwYXJhdG9yID09IDApIHsKLSAgICAgICAgICAgICAgICAvLyBHWWVhcgotICAgICAgICAgICAgICAgIGZvcm1hdCA9ICIlWSIgKyAiJXoiOwotICAgICAgICAgICAgfSBlbHNlIGlmIChjb3VudFNlcGFyYXRvciA9PSAxKSB7Ci0gICAgICAgICAgICAgICAgLy8gR1llYXJNb250aAotICAgICAgICAgICAgICAgIGZvcm1hdCA9ICIlWS0lTSIgKyAiJXoiOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAvLyBEYXRlIG9yIGludmFsaWQgbGV4aWNhbFJlcHJlc2VudGF0aW9uCi0gICAgICAgICAgICAgICAgLy8gRml4IDQ5NzE2MTI6IGludmFsaWQgU0NDUyBtYWNybyBzdWJzdGl0dXRpb24gaW4gZGF0YSBzdHJpbmcKLSAgICAgICAgICAgICAgICBmb3JtYXQgPSAiJVktJU0tJUQiICsgIiV6IjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBQYXJzZXIgcCA9IG5ldyBQYXJzZXIoZm9ybWF0LCBsZXhSZXApOwotICAgICAgICBwLnBhcnNlKCk7Ci0KLSAgICAgICAgLy8gY2hlY2sgZm9yIHZhbGlkaXR5Ci0gICAgICAgIGlmICghaXNWYWxpZCgpKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICBEYXRhdHlwZU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShudWxsLCAiSW52YWxpZFhHQ1JlcHJlc2VudGF0aW9uIiwgbmV3IE9iamVjdFtde2xleGljYWxSZXByZXNlbnRhdGlvbn0pCi0gICAgICAgICAgICAgICAgICAgIC8vIlwiIiArIGxleGljYWxSZXByZXNlbnRhdGlvbiArICJcIiBpcyBub3QgYSB2YWxpZCByZXByZXNlbnRhdGlvbiBvZiBhbiBYTUwgR3JlZ29yaWFuIENhbGVuZGFyIHZhbHVlLiIKLSAgICAgICAgICAgICk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5DcmVhdGUgYW4gaW5zdGFuY2Ugd2l0aCBhbGwgZGF0ZS90aW1lIGRhdGF0eXBlIGZpZWxkcyBzZXQgdG8KLSAgICAgKiB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjRklFTERfVU5ERUZJTkVEfSBvciBudWxsIHJlc3BlY3RpdmVseS48L3A+Ci0gICAgICovCi0gICAgcHVibGljIFhNTEdyZWdvcmlhbkNhbGVuZGFySW1wbCgpIHsKLQotICAgICAgICAvLyBmaWVsZCBpbml0aWFsaXplcnMgYWxyZWFkeSBkbyB0aGUgY29ycmVjdCBpbml0aWFsaXphdGlvbi4KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5Qcml2YXRlIGNvbnN0cnVjdG9yIGFsbG93aW5nIGZvciBjb21wbGV0ZSB2YWx1ZSBzcGFjZXMgYWxsb3dlZCBieQotICAgICAqIFczQyBYTUwgU2NoZW1hIDEuMCByZWNvbW1lbmRhdGlvbiBmb3IgeHNkOmRhdGVUaW1lIGFuZCByZWxhdGVkCi0gICAgICogYnVpbHRpbiBkYXRhdHlwZXMuIE5vdGUgdGhhdCA8Y29kZT55ZWFyPC9jb2RlPiBwYXJhbWV0ZXIgc3VwcG9ydHMKLSAgICAgKiBhcmJpdHJhcmlseSBsYXJnZSBudW1iZXJzIGFuZCBmcmFjdGlvbmFsU2Vjb25kIGhhcyBpbmZpbml0ZQotICAgICAqIHByZWNpc2lvbi48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0geWVhciBvZiA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gdG8gYmUgY3JlYXRlZC4KLSAgICAgKiBAcGFyYW0gbW9udGggb2YgPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IHRvIGJlIGNyZWF0ZWQuCi0gICAgICogQHBhcmFtIGRheSBvZiA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gdG8gYmUgY3JlYXRlZC4KLSAgICAgKiBAcGFyYW0gaG91ciBvZiA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gdG8gYmUgY3JlYXRlZC4KLSAgICAgKiBAcGFyYW0gbWludXRlIG9mIDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiB0byBiZSBjcmVhdGVkLgotICAgICAqIEBwYXJhbSBzZWNvbmQgb2YgPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IHRvIGJlIGNyZWF0ZWQuCi0gICAgICogQHBhcmFtIGZyYWN0aW9uYWxTZWNvbmQgb2YgPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IHRvIGJlIGNyZWF0ZWQuCi0gICAgICogQHBhcmFtIHRpbWV6b25lIG9mIDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiB0byBiZSBjcmVhdGVkLgotICAgICAqCi0gICAgICovCi0gICAgcHJvdGVjdGVkIFhNTEdyZWdvcmlhbkNhbGVuZGFySW1wbCgKLSAgICAgICAgQmlnSW50ZWdlciB5ZWFyLAotICAgICAgICBpbnQgbW9udGgsCi0gICAgICAgIGludCBkYXksCi0gICAgICAgIGludCBob3VyLAotICAgICAgICBpbnQgbWludXRlLAotICAgICAgICBpbnQgc2Vjb25kLAotICAgICAgICBCaWdEZWNpbWFsIGZyYWN0aW9uYWxTZWNvbmQsCi0gICAgICAgIGludCB0aW1lem9uZSkgewotCi0gICAgICAgICAgICAgICAgc2V0WWVhcih5ZWFyKTsKLSAgICAgICAgc2V0TW9udGgobW9udGgpOwotICAgICAgICBzZXREYXkoZGF5KTsKLSAgICAgICAgc2V0VGltZShob3VyLCBtaW51dGUsIHNlY29uZCwgZnJhY3Rpb25hbFNlY29uZCk7Ci0gICAgICAgICAgICAgICAgc2V0VGltZXpvbmUodGltZXpvbmUpOwotCi0gICAgICAgICAgICAgICAgLy8gY2hlY2sgZm9yIHZhbGlkaXR5Ci0gICAgICAgICAgICAgICAgaWYgKCFpc1ZhbGlkKCkpIHsKLQotICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICBEYXRhdHlwZU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShudWxsLAotICAgICAgICAgICAgICAgICAgICAiSW52YWxpZFhHQ1ZhbHVlLWZyYWN0aW9uYWwiLAotICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyB5ZWFyLCBuZXcgSW50ZWdlcihtb250aCksIG5ldyBJbnRlZ2VyKGRheSksCi0gICAgICAgICAgICAgICAgICAgIG5ldyBJbnRlZ2VyKGhvdXIpLCBuZXcgSW50ZWdlcihtaW51dGUpLCBuZXcgSW50ZWdlcihzZWNvbmQpLAotICAgICAgICAgICAgICAgICAgICBmcmFjdGlvbmFsU2Vjb25kLCBuZXcgSW50ZWdlcih0aW1lem9uZSl9KQotICAgICAgICAgICAgICAgICAgICAgICAgKTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgLyoqCi0gICAgICAgICAgICAgICAgU3RyaW5nIHllYXJTdHJpbmcgPSAibnVsbCI7Ci0gICAgICAgICAgICAgICAgaWYgKHllYXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICB5ZWFyU3RyaW5nID0geWVhci50b1N0cmluZygpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBTdHJpbmcgZnJhY3Rpb25hbFNlY29uZFN0cmluZyA9ICJudWxsIjsKLSAgICAgICAgICAgICAgICBpZiAoZnJhY3Rpb25hbFNlY29uZCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZyYWN0aW9uYWxTZWNvbmRTdHJpbmcgPSBmcmFjdGlvbmFsU2Vjb25kLnRvU3RyaW5nKCk7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgInllYXIgPSAiICsgeWVhclN0cmluZwotICAgICAgICAgICAgICAgICAgICArICIsIG1vbnRoID0gIiArIG1vbnRoCi0gICAgICAgICAgICAgICAgICAgICsgIiwgZGF5ID0gIiArIGRheQotICAgICAgICAgICAgICAgICAgICArICIsIGhvdXIgPSAiICsgaG91cgotICAgICAgICAgICAgICAgICAgICArICIsIG1pbnV0ZSA9ICIgKyBtaW51dGUKLSAgICAgICAgICAgICAgICAgICAgKyAiLCBzZWNvbmQgPSAiICsgc2Vjb25kCi0gICAgICAgICAgICAgICAgICAgICsgIiwgZnJhY3Rpb25hbFNlY29uZCA9ICIgKyBmcmFjdGlvbmFsU2Vjb25kU3RyaW5nCi0gICAgICAgICAgICAgICAgICAgICsgIiwgdGltZXpvbmUgPSAiICsgdGltZXpvbmUKLSAgICAgICAgICAgICAgICAgICAgKyAiLCBpcyBub3QgYSB2YWxpZCByZXByZXNlbnRhdGlvbiBvZiBhbiBYTUwgR3JlZ29yaWFuIENhbGVuZGFyIHZhbHVlLiIKLSAgICAgICAgICAgICAgICApOwotICAgICAgICAgICAgICAgICovCi0KLSAgICAgICAgICAgICAgICB9Ci0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5Qcml2YXRlIGNvbnN0cnVjdG9yIG9mIHZhbHVlIHNwYWNlcyB0aGF0IGEKLSAgICAgKiA8Y29kZT5qYXZhLnV0aWwuR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IGluc3RhbmNlIHdvdWxkIG5lZWQgdG8gY29udmVydCB0byBhbgotICAgICAqIDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiBpbnN0YW5jZS48L3A+Ci0gICAgICoKLSAgICAgKiA8cD48Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhciBlb248L2NvZGU+IGFuZAotICAgICAqIDxjb2RlPmZyYWN0aW9uYWxTZWNvbmQ8L2NvZGU+IGFyZSBzZXQgdG8gPGNvZGU+bnVsbDwvY29kZT48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0geWVhciBvZiA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gdG8gYmUgY3JlYXRlZC4KLSAgICAgKiBAcGFyYW0gbW9udGggb2YgPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IHRvIGJlIGNyZWF0ZWQuCi0gICAgICogQHBhcmFtIGRheSBvZiA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gdG8gYmUgY3JlYXRlZC4KLSAgICAgKiBAcGFyYW0gaG91ciBvZiA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gdG8gYmUgY3JlYXRlZC4KLSAgICAgKiBAcGFyYW0gbWludXRlIG9mIDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiB0byBiZSBjcmVhdGVkLgotICAgICAqIEBwYXJhbSBzZWNvbmQgb2YgPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IHRvIGJlIGNyZWF0ZWQuCi0gICAgICogQHBhcmFtIG1pbGxpc2Vjb25kIG9mIDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiB0byBiZSBjcmVhdGVkLgotICAgICAqIEBwYXJhbSB0aW1lem9uZSBvZiA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gdG8gYmUgY3JlYXRlZC4KLSAgICAgKi8KLSAgICBwcml2YXRlIFhNTEdyZWdvcmlhbkNhbGVuZGFySW1wbCgKLSAgICAgICAgaW50IHllYXIsCi0gICAgICAgIGludCBtb250aCwKLSAgICAgICAgaW50IGRheSwKLSAgICAgICAgaW50IGhvdXIsCi0gICAgICAgIGludCBtaW51dGUsCi0gICAgICAgIGludCBzZWNvbmQsCi0gICAgICAgICAgICAgICAgaW50IG1pbGxpc2Vjb25kLAotICAgICAgICBpbnQgdGltZXpvbmUpIHsKLQotICAgICAgICAgICAgICAgIHNldFllYXIoeWVhcik7Ci0gICAgICAgIHNldE1vbnRoKG1vbnRoKTsKLSAgICAgICAgc2V0RGF5KGRheSk7Ci0gICAgICAgIHNldFRpbWUoaG91ciwgbWludXRlLCBzZWNvbmQpOwotICAgICAgICAgICAgICAgIHNldFRpbWV6b25lKHRpbWV6b25lKTsKLSAgICAgICAgICAgICAgICBzZXRNaWxsaXNlY29uZChtaWxsaXNlY29uZCk7Ci0KLSAgICAgICAgICAgICAgICBpZiAoIWlzVmFsaWQoKSkgewotCi0gICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAotICAgICAgICAgICAgICAgIERhdGF0eXBlTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKG51bGwsCi0gICAgICAgICAgICAgICAgIkludmFsaWRYR0NWYWx1ZS1taWxsaSIsCi0gICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgbmV3IEludGVnZXIoeWVhciksIG5ldyBJbnRlZ2VyKG1vbnRoKSwgbmV3IEludGVnZXIoZGF5KSwKLSAgICAgICAgICAgICAgICBuZXcgSW50ZWdlcihob3VyKSwgbmV3IEludGVnZXIobWludXRlKSwgbmV3IEludGVnZXIoc2Vjb25kKSwKLSAgICAgICAgICAgICAgICBuZXcgSW50ZWdlcihtaWxsaXNlY29uZCksIG5ldyBJbnRlZ2VyKHRpbWV6b25lKX0pCi0gICAgICAgICAgICAgICAgICAgICAgICApOwotICAgICAgICAgICAgICAgIC8qCi0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgInllYXIgPSAiICsgeWVhcgotICAgICAgICAgICAgICAgICAgICArICIsIG1vbnRoID0gIiArIG1vbnRoCi0gICAgICAgICAgICAgICAgICAgICsgIiwgZGF5ID0gIiArIGRheQotICAgICAgICAgICAgICAgICAgICArICIsIGhvdXIgPSAiICsgaG91cgotICAgICAgICAgICAgICAgICAgICArICIsIG1pbnV0ZSA9ICIgKyBtaW51dGUKLSAgICAgICAgICAgICAgICAgICAgKyAiLCBzZWNvbmQgPSAiICsgc2Vjb25kCi0gICAgICAgICAgICAgICAgICAgICsgIiwgbWlsbGlzZWNvbmQgPSAiICsgbWlsbGlzZWNvbmQKLSAgICAgICAgICAgICAgICAgICAgKyAiLCB0aW1lem9uZSA9ICIgKyB0aW1lem9uZQotICAgICAgICAgICAgICAgICAgICArICIsIGlzIG5vdCBhIHZhbGlkIHJlcHJlc2VudGF0aW9uIG9mIGFuIFhNTCBHcmVnb3JpYW4gQ2FsZW5kYXIgdmFsdWUuIgotICAgICAgICAgICAgICAgICAgICApOwotICAgICAgICAgICAgICAgICAqLwotCi0gICAgICAgICAgICAgICAgfQotICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogPHA+Q29udmVydCBhIDxjb2RlPmphdmEudXRpbC5HcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gdG8gWE1MIFNjaGVtYSAxLjAKLSAgICAgICAgICogcmVwcmVzZW50YXRpb24uPC9wPgotICAgICAgICAgKgotICAgICAgICAgKiA8dGFibGUgYm9yZGVyPSIyIiBydWxlcz0iYWxsIiBjZWxscGFkZGluZz0iMiI+Ci0gICAgICAgICAqICAgPHRoZWFkPgotICAgICAgICAgKiAgICAgPHRyPgotICAgICAgICAgKiAgICAgICA8dGggYWxpZ249ImNlbnRlciIgY29sc3Bhbj0iMiI+Ci0gICAgICAgICAqICAgICAgICAgIEZpZWxkIGJ5IEZpZWxkIENvbnZlcnNpb24gZnJvbQotICAgICAgICAgKiAgICAgICAgICA8Y29kZT5qYXZhLnV0aWwuR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IHRvIHRoaXMgY2xhc3MKLSAgICAgICAgICogICAgICAgPC90aD4KLSAgICAgICAgICogICAgIDwvdHI+Ci0gICAgICAgICAqICAgPC90aGVhZD4KLSAgICAgICAgICogICA8dGJvZHk+Ci0gICAgICAgICAqICAgICA8dHI+Ci0gICAgICAgICAqICAgICAgICA8dGg+PGNvZGU+amF2YXgueG1sLmRhdGF0eXBlLlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiBmaWVsZDwvdGg+Ci0gICAgICAgICAqICAgICAgICA8dGg+PGNvZGU+amF2YS51dGlsLkdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiBmaWVsZDwvdGg+Ci0gICAgICAgICAqICAgICA8L3RyPgotICAgICAgICAgKiAgICAgPHRyPgotICAgICAgICAgKiAgICAgICA8dGg+e0BsaW5rICNzZXRZZWFyKGludCl9PC90aD4KLSAgICAgICAgICogICAgICAgPHRoPjxjb2RlPkVSQSA9PSBHcmVnb3JpYW5DYWxlbmRhci5CQyA/IC1ZRUFSIDogWUVBUjwvY29kZT48L3RoPgotICAgICAgICAgKiAgICAgPC90cj4KLSAgICAgICAgICogICAgIDx0cj4KLSAgICAgICAgICogICAgICAgPHRoPntAbGluayAjc2V0TW9udGgoaW50KX08L3RoPgotICAgICAgICAgKiAgICAgICA8dGg+PGNvZGU+TU9OVEggKyAxPC9jb2RlPjwvdGg+Ci0gICAgICAgICAqICAgICA8L3RyPgotICAgICAgICAgKiAgICAgPHRyPgotICAgICAgICAgKiAgICAgICA8dGg+e0BsaW5rICNzZXREYXkoaW50KX08L3RoPgotICAgICAgICAgKiAgICAgICA8dGg+PGNvZGU+REFZX09GX01PTlRIPC9jb2RlPjwvdGg+Ci0gICAgICAgICAqICAgICA8L3RyPgotICAgICAgICAgKiAgICAgPHRyPgotICAgICAgICAgKiAgICAgICA8dGg+e0BsaW5rICNzZXRUaW1lKGludCxpbnQsaW50LCBCaWdEZWNpbWFsKX08L3RoPgotICAgICAgICAgKiAgICAgICA8dGg+PGNvZGU+SE9VUl9PRl9EQVksIE1JTlVURSwgU0VDT05ELCBNSUxMSVNFQ09ORDwvY29kZT48L3RoPgotICAgICAgICAgKiAgICAgPC90cj4KLSAgICAgICAgICogICAgIDx0cj4KLSAgICAgICAgICogICAgICAgPHRoPntAbGluayAjc2V0VGltZXpvbmUoaW50KX08aT4qPC9pPjwvdGg+Ci0gICAgICAgICAqICAgICAgIDx0aD48Y29kZT4oWk9ORV9PRkZTRVQgKyBEU1RfT0ZGU0VUKSAvICg2MCoxMDAwKTwvY29kZT48YnIvPgotICAgICAgICAgKiAgICAgICA8aT4oaW4gbWludXRlcyk8L2k+Ci0gICAgICAgICAqICAgICAgIDwvdGg+Ci0gICAgICAgICAqICAgICA8L3RyPgotICAgICAgICAgKiAgIDwvdGJvZHk+Ci0gICAgICAgICAqIDwvdGFibGU+Ci0gICAgICAgICAqIDxwPjxpPio8L2k+Y29udmVyc2lvbiBsb3NzIG9mIGluZm9ybWF0aW9uLiBJdCBpcyBub3QgcG9zc2libGUgdG8gcmVwcmVzZW50Ci0gICAgICAgICAqIGEgPGNvZGU+amF2YS51dGlsLkdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiBkYXlsaWdodCBzYXZpbmdzIHRpbWV6b25lIGlkIGluIHRoZQotICAgICAgICAgKiBYTUwgU2NoZW1hIDEuMCBkYXRlL3RpbWUgZGF0YXR5cGUgcmVwcmVzZW50YXRpb24uPC9wPgotICAgICAgICAgKgotICAgICAgICAgKiA8cD5UbyBjb21wdXRlIHRoZSByZXR1cm4gdmFsdWUncyA8Y29kZT5UaW1lWm9uZTwvY29kZT4gZmllbGQsCi0gICAgICAgICAqIDx1bD4KLSAgICAgICAgICogPGxpPndoZW4gPGNvZGU+dGhpcy5nZXRUaW1lem9uZSgpICE9IERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRDwvY29kZT4sCi0gICAgICAgICAqIGNyZWF0ZSBhIDxjb2RlPmphdmEudXRpbC5UaW1lWm9uZTwvY29kZT4gd2l0aCBhIGN1c3RvbSB0aW1lem9uZSBpZAotICAgICAgICAgKiB1c2luZyB0aGUgPGNvZGU+dGhpcy5nZXRUaW1lem9uZSgpPC9jb2RlPi48L2xpPgotICAgICAgICAgKiA8bGk+ZWxzZSB1c2UgdGhlIDxjb2RlPkdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiBkZWZhdWx0IHRpbWV6b25lIHZhbHVlCi0gICAgICAgICAqIGZvciB0aGUgaG9zdCBpcyBkZWZpbmVkIGFzIHNwZWNpZmllZCBieQotICAgICAgICAgKiA8Y29kZT5qYXZhLnV0aWwuVGltZVpvbmUuZ2V0RGVmYXVsdCgpPC9jb2RlPi48L2xpPjwvcD4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIGNhbCA8Y29kZT5qYXZhLnV0aWwuR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IHVzZWQgdG8gY3JlYXRlIDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPgotICAgICAgICAgKi8KLSAgICBwdWJsaWMgWE1MR3JlZ29yaWFuQ2FsZW5kYXJJbXBsKEdyZWdvcmlhbkNhbGVuZGFyIGNhbCkgewotCi0gICAgICAgIGludCB5ZWFyID0gY2FsLmdldChDYWxlbmRhci5ZRUFSKTsKLSAgICAgICAgaWYgKGNhbC5nZXQoQ2FsZW5kYXIuRVJBKSA9PSBHcmVnb3JpYW5DYWxlbmRhci5CQykgewotICAgICAgICAgICAgeWVhciA9IC15ZWFyOwotICAgICAgICB9Ci0gICAgICAgIHRoaXMuc2V0WWVhcih5ZWFyKTsKLQotICAgICAgICAvLyBDYWxlbmRhci5NT05USCBpcyB6ZXJvIGJhc2VkLCBYU0QgRGF0ZSBkYXRhdHlwZSdzIG1vbnRoIGZpZWxkIHN0YXJ0cwotICAgICAgICAvLyB3aXRoIEpBTlVBUlkgYXMgMS4KLSAgICAgICAgdGhpcy5zZXRNb250aChjYWwuZ2V0KENhbGVuZGFyLk1PTlRIKSArIDEpOwotICAgICAgICB0aGlzLnNldERheShjYWwuZ2V0KENhbGVuZGFyLkRBWV9PRl9NT05USCkpOwotICAgICAgICB0aGlzLnNldFRpbWUoCi0gICAgICAgICAgICAgICAgY2FsLmdldChDYWxlbmRhci5IT1VSX09GX0RBWSksCi0gICAgICAgICAgICAgICAgY2FsLmdldChDYWxlbmRhci5NSU5VVEUpLAotICAgICAgICAgICAgICAgIGNhbC5nZXQoQ2FsZW5kYXIuU0VDT05EKSwKLSAgICAgICAgICAgICAgICBjYWwuZ2V0KENhbGVuZGFyLk1JTExJU0VDT05EKSk7Ci0KLSAgICAgICAgLy8gQ2FsZW5kYXIgWk9ORV9PRkZTRVQgYW5kIERTVF9PRkZTRVQgZmllbGRzIGFyZSBpbiBtaWxsaXNlY29uZHMuCi0gICAgICAgIGludCBvZmZzZXRJbk1pbnV0ZXMgPSAoY2FsLmdldChDYWxlbmRhci5aT05FX09GRlNFVCkgKyBjYWwuZ2V0KENhbGVuZGFyLkRTVF9PRkZTRVQpKSAvICg2MCAqIDEwMDApOwotICAgICAgICB0aGlzLnNldFRpbWV6b25lKG9mZnNldEluTWludXRlcyk7Ci0gICAgfQotCi0gICAgLy8gRmFjdG9yaWVzCi0KLSAgICAvKioKLSAgICAgKiA8cD5DcmVhdGUgYSBKYXZhIHJlcHJlc2VudGF0aW9uIG9mIFhNTCBTY2hlbWEgYnVpbHRpbiBkYXRhdHlwZSA8Y29kZT5kYXRlVGltZTwvY29kZT4uCi0gICAgICogQWxsIHBvc3NpYmxlIGZpZWxkcyBhcmUgc3BlY2lmaWVkIGZvciB0aGlzIGZhY3RvcnkgbWV0aG9kLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSB5ZWFyIHJlcHJlc2VudHMgYm90aCBoaWdoLW9yZGVyIGVvbnMgYW5kIGxvdy1vcmRlciB5ZWFyLgotICAgICAqIEBwYXJhbSBtb250aCBvZiA8Y29kZT5kYXRlVGltZTwvY29kZT4KLSAgICAgKiBAcGFyYW0gZGF5IG9mIDxjb2RlPmRhdGVUaW1lPC9jb2RlPgotICAgICAqIEBwYXJhbSBob3VycyBvZiA8Y29kZT5kYXRlVGltZTwvY29kZT4KLSAgICAgKiBAcGFyYW0gbWludXRlcyBvZiA8Y29kZT5kYXRlVGltZTwvY29kZT4KLSAgICAgKiBAcGFyYW0gc2Vjb25kcyBvZiA8Y29kZT5kYXRlVGltZTwvY29kZT4KLSAgICAgKiBAcGFyYW0gZnJhY3Rpb25hbFNlY29uZCB2YWx1ZSBvZiBudWxsIGluZGljYXRlcyBvcHRpb25hbCBmaWVsZCBpcyBhYnNlbnQuCi0gICAgICogQHBhcmFtIHRpbWV6b25lIG9mZnNldCBpbiBtaW51dGVzLiB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjRklFTERfVU5ERUZJTkVEfSBpbmRpY2F0ZXMgb3B0aW9uYWwgZmllbGQgaXMgbm90IHNldC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IGNyZWF0ZWQgZnJvbSBwYXJhbWV0ZXIgdmFsdWVzLgotICAgICAqCi0gICAgICogQHNlZSBEYXRhdHlwZUNvbnN0YW50cyNGSUVMRF9VTkRFRklORUQKLSAgICAgKgotICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIGFueSBwYXJhbWV0ZXIgaXMgb3V0c2lkZSB2YWx1ZQotICAgICAqIGNvbnN0cmFpbnRzIGZvciB0aGUgZmllbGQgYXMgc3BlY2lmaWVkIGluCi0gICAgICogPGEgaHJlZj0iI2RhdGV0aW1lZmllbGRtYXBwaW5nIj5kYXRlL3RpbWUgZmllbGQgbWFwcGluZyB0YWJsZTwvYT4uCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBYTUxHcmVnb3JpYW5DYWxlbmRhciBjcmVhdGVEYXRlVGltZSgKLSAgICAgICAgQmlnSW50ZWdlciB5ZWFyLAotICAgICAgICBpbnQgbW9udGgsCi0gICAgICAgIGludCBkYXksCi0gICAgICAgIGludCBob3VycywKLSAgICAgICAgaW50IG1pbnV0ZXMsCi0gICAgICAgIGludCBzZWNvbmRzLAotICAgICAgICBCaWdEZWNpbWFsIGZyYWN0aW9uYWxTZWNvbmQsCi0gICAgICAgIGludCB0aW1lem9uZSkgewotCi0gICAgICAgIHJldHVybiBuZXcgWE1MR3JlZ29yaWFuQ2FsZW5kYXJJbXBsKAotICAgICAgICAgICAgeWVhciwKLSAgICAgICAgICAgIG1vbnRoLAotICAgICAgICAgICAgZGF5LAotICAgICAgICAgICAgaG91cnMsCi0gICAgICAgICAgICBtaW51dGVzLAotICAgICAgICAgICAgc2Vjb25kcywKLSAgICAgICAgICAgIGZyYWN0aW9uYWxTZWNvbmQsCi0gICAgICAgICAgICB0aW1lem9uZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+Q3JlYXRlIGEgSmF2YSBpbnN0YW5jZSBvZiBYTUwgU2NoZW1hIGJ1aWx0aW4gZGF0YXR5cGUgZGF0ZVRpbWUuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIHllYXIgcmVwcmVzZW50cyBib3RoIGhpZ2gtb3JkZXIgZW9ucyBhbmQgbG93LW9yZGVyIHllYXIuCi0gICAgICogQHBhcmFtIG1vbnRoIG9mIDxjb2RlPmRhdGVUaW1lPC9jb2RlPgotICAgICAqIEBwYXJhbSBkYXkgb2YgPGNvZGU+ZGF0ZVRpbWU8L2NvZGU+Ci0gICAgICogQHBhcmFtIGhvdXIgb2YgPGNvZGU+ZGF0ZVRpbWU8L2NvZGU+Ci0gICAgICogQHBhcmFtIG1pbnV0ZSBvZiA8Y29kZT5kYXRlVGltZTwvY29kZT4KLSAgICAgKiBAcGFyYW0gc2Vjb25kIG9mIDxjb2RlPmRhdGVUaW1lPC9jb2RlPgotICAgICAqCi0gICAgICogQHJldHVybiA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gY3JlYXRlZCBmcm9tIHBhcmFtZXRlciB2YWx1ZXMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiBhbnkgcGFyYW1ldGVyIGlzIG91dHNpZGUgdmFsdWUgY29uc3RyYWludHMgZm9yIHRoZSBmaWVsZCBhcyBzcGVjaWZpZWQgaW4KLSAgICAgKiAgIDxhIGhyZWY9IiNkYXRldGltZWZpZWxkbWFwcGluZyI+ZGF0ZS90aW1lIGZpZWxkIG1hcHBpbmcgdGFibGU8L2E+LgotICAgICAqCi0gICAgICogQHNlZSBEYXRhdHlwZUNvbnN0YW50cyNGSUVMRF9VTkRFRklORUQKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFhNTEdyZWdvcmlhbkNhbGVuZGFyIGNyZWF0ZURhdGVUaW1lKAotICAgICAgICBpbnQgeWVhciwKLSAgICAgICAgaW50IG1vbnRoLAotICAgICAgICBpbnQgZGF5LAotICAgICAgICBpbnQgaG91ciwKLSAgICAgICAgaW50IG1pbnV0ZSwKLSAgICAgICAgaW50IHNlY29uZCkgewotCi0gICAgICAgIHJldHVybiBuZXcgWE1MR3JlZ29yaWFuQ2FsZW5kYXJJbXBsKAotICAgICAgICAgICAgeWVhciwKLSAgICAgICAgICAgIG1vbnRoLAotICAgICAgICAgICAgZGF5LAotICAgICAgICAgICAgaG91ciwKLSAgICAgICAgICAgIG1pbnV0ZSwKLSAgICAgICAgICAgIHNlY29uZCwKLSAgICAgICAgICAgIERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCwgIC8vbWlsbGlzZWNvbmQKLSAgICAgICAgICAgICAgICBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQgLy90aW1lem9uZQotICAgICAgICApOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPkNyZWF0ZSBhIEphdmEgcmVwcmVzZW50YXRpb24gb2YgWE1MIFNjaGVtYSBidWlsdGluIGRhdGF0eXBlIDxjb2RlPmRhdGVUaW1lPC9jb2RlPi4KLSAgICAgKiBBbGwgcG9zc2libGUgZmllbGRzIGFyZSBzcGVjaWZpZWQgZm9yIHRoaXMgZmFjdG9yeSBtZXRob2QuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIHllYXIgcmVwcmVzZW50cyBsb3ctb3JkZXIgeWVhci4KLSAgICAgKiBAcGFyYW0gbW9udGggb2YgPGNvZGU+ZGF0ZVRpbWU8L2NvZGU+Ci0gICAgICogQHBhcmFtIGRheSBvZiA8Y29kZT5kYXRlVGltZTwvY29kZT4KLSAgICAgKiBAcGFyYW0gaG91cnMgb2YgPGNvZGU+ZGF0ZVRpbWU8L2NvZGU+Ci0gICAgICogQHBhcmFtIG1pbnV0ZXMgb2YgPGNvZGU+ZGF0ZVRpbWU8L2NvZGU+Ci0gICAgICogQHBhcmFtIHNlY29uZHMgb2YgPGNvZGU+ZGF0ZVRpbWU8L2NvZGU+Ci0gICAgICogQHBhcmFtIG1pbGxpc2Vjb25kcyBvZiA8Y29kZT5kYXRlVGltZTwvY29kZT4uIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNGSUVMRF9VTkRFRklORUR9IGluZGljYXRlcyBvcHRpb25hbCBmaWVsZCBpcyBub3Qgc2V0LgotICAgICAqIEBwYXJhbSB0aW1lem9uZSBvZmZzZXQgaW4gbWludXRlcy4ge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0ZJRUxEX1VOREVGSU5FRH0gaW5kaWNhdGVzIG9wdGlvbmFsIGZpZWxkIGlzIG5vdCBzZXQuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiBjcmVhdGVkIGZyb20gcGFyYW1ldGVyIHZhbHVlcy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIGFueSBwYXJhbWV0ZXIgaXMgb3V0c2lkZSB2YWx1ZSBjb25zdHJhaW50cyBmb3IgdGhlIGZpZWxkIGFzIHNwZWNpZmllZCBpbgotICAgICAqICAgPGEgaHJlZj0iI2RhdGV0aW1lZmllbGRtYXBwaW5nIj5kYXRlL3RpbWUgZmllbGQgbWFwcGluZyB0YWJsZTwvYT4uCi0gICAgICoKLSAgICAgKiBAc2VlIERhdGF0eXBlQ29uc3RhbnRzI0ZJRUxEX1VOREVGSU5FRAotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgWE1MR3JlZ29yaWFuQ2FsZW5kYXIgY3JlYXRlRGF0ZVRpbWUoCi0gICAgICAgIGludCB5ZWFyLAotICAgICAgICBpbnQgbW9udGgsCi0gICAgICAgIGludCBkYXksCi0gICAgICAgIGludCBob3VycywKLSAgICAgICAgaW50IG1pbnV0ZXMsCi0gICAgICAgIGludCBzZWNvbmRzLAotICAgICAgICBpbnQgbWlsbGlzZWNvbmRzLAotICAgICAgICBpbnQgdGltZXpvbmUpIHsKLQotICAgICAgICByZXR1cm4gbmV3IFhNTEdyZWdvcmlhbkNhbGVuZGFySW1wbCgKLSAgICAgICAgICAgIHllYXIsCi0gICAgICAgICAgICBtb250aCwKLSAgICAgICAgICAgIGRheSwKLSAgICAgICAgICAgIGhvdXJzLAotICAgICAgICAgICAgbWludXRlcywKLSAgICAgICAgICAgIHNlY29uZHMsCi0gICAgICAgICAgICBtaWxsaXNlY29uZHMsCi0gICAgICAgICAgICB0aW1lem9uZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+Q3JlYXRlIGEgSmF2YSByZXByZXNlbnRhdGlvbiBvZiBYTUwgU2NoZW1hIGJ1aWx0aW4gZGF0YXR5cGUgPGNvZGU+ZGF0ZTwvY29kZT4gb3IgPGNvZGU+Zyo8L2NvZGU+LjwvcD4KLSAgICAgKgotICAgICAqIDxwPkZvciBleGFtcGxlLCBhbiBpbnN0YW5jZSBvZiA8Y29kZT5nWWVhcjwvY29kZT4gY2FuIGJlIGNyZWF0ZWQgaW52b2tpbmcgdGhpcyBmYWN0b3J5Ci0gICAgICogd2l0aCA8Y29kZT5tb250aDwvY29kZT4gYW5kIDxjb2RlPmRheTwvY29kZT4gcGFyYW1ldGVycyBzZXQgdG8KLSAgICAgKiB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjRklFTERfVU5ERUZJTkVEfS48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0geWVhciBvZiA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gdG8gYmUgY3JlYXRlZC4KLSAgICAgKiBAcGFyYW0gbW9udGggb2YgPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IHRvIGJlIGNyZWF0ZWQuCi0gICAgICogQHBhcmFtIGRheSBvZiA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gdG8gYmUgY3JlYXRlZC4KLSAgICAgKiBAcGFyYW0gdGltZXpvbmUgb2Zmc2V0IGluIG1pbnV0ZXMuIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNGSUVMRF9VTkRFRklORUR9IGluZGljYXRlcyBvcHRpb25hbCBmaWVsZCBpcyBub3Qgc2V0LgotICAgICAqCi0gICAgICogQHJldHVybiA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gY3JlYXRlZCBmcm9tIHBhcmFtZXRlciB2YWx1ZXMuCi0gICAgICoKLSAgICAgKiBAc2VlIERhdGF0eXBlQ29uc3RhbnRzI0ZJRUxEX1VOREVGSU5FRAotICAgICAqCi0gICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgYW55IHBhcmFtZXRlciBpcyBvdXRzaWRlIHZhbHVlCi0gICAgICogY29uc3RyYWludHMgZm9yIHRoZSBmaWVsZCBhcyBzcGVjaWZpZWQgaW4KLSAgICAgKiA8YSBocmVmPSIjZGF0ZXRpbWVmaWVsZG1hcHBpbmciPmRhdGUvdGltZSBmaWVsZCBtYXBwaW5nIHRhYmxlPC9hPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFhNTEdyZWdvcmlhbkNhbGVuZGFyIGNyZWF0ZURhdGUoCi0gICAgICAgIGludCB5ZWFyLAotICAgICAgICBpbnQgbW9udGgsCi0gICAgICAgIGludCBkYXksCi0gICAgICAgIGludCB0aW1lem9uZSkgewotCi0gICAgICAgIHJldHVybiBuZXcgWE1MR3JlZ29yaWFuQ2FsZW5kYXJJbXBsKAotICAgICAgICAgICAgeWVhciwKLSAgICAgICAgICAgIG1vbnRoLAotICAgICAgICAgICAgZGF5LAotICAgICAgICAgICAgRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVELCAvLyBob3VyCi0gICAgICAgICAgICBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQsIC8vIG1pbnV0ZQotICAgICAgICAgICAgRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVELCAvLyBzZWNvbmQKLSAgICAgICAgICAgICAgICBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQsIC8vIG1pbGxpc2Vjb25kCi0gICAgICAgICAgICB0aW1lem9uZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlIGEgSmF2YSBpbnN0YW5jZSBvZiBYTUwgU2NoZW1hIGJ1aWx0aW4gZGF0YXR5cGUgPGNvZGU+dGltZTwvY29kZT4uCi0gICAgICogQHBhcmFtIGhvdXJzIG51bWJlciBvZiBob3VycwotICAgICAqIEBwYXJhbSBtaW51dGVzIG51bWJlciBvZiBtaW51dGVzCi0gICAgICogQHBhcmFtIHNlY29uZHMgbnVtYmVyIG9mIHNlY29uZHMKLSAgICAgKiBAcGFyYW0gdGltZXpvbmUgb2Zmc2V0IGluIG1pbnV0ZXMuIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNGSUVMRF9VTkRFRklORUR9IGluZGljYXRlcyBvcHRpb25hbCBmaWVsZCBpcyBub3Qgc2V0LgotICAgICAqCi0gICAgICogQHJldHVybiA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gY3JlYXRlZCBmcm9tIHBhcmFtZXRlciB2YWx1ZXMuCi0gICAgICoKLSAgICAgKiBAc2VlIERhdGF0eXBlQ29uc3RhbnRzI0ZJRUxEX1VOREVGSU5FRAotICAgICAqCi0gICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgYW55IHBhcmFtZXRlciBpcyBvdXRzaWRlIHZhbHVlCi0gICAgICogY29uc3RyYWludHMgZm9yIHRoZSBmaWVsZCBhcyBzcGVjaWZpZWQgaW4KLSAgICAgKiA8YSBocmVmPSIjZGF0ZXRpbWVmaWVsZG1hcHBpbmciPmRhdGUvdGltZSBmaWVsZCBtYXBwaW5nIHRhYmxlPC9hPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFhNTEdyZWdvcmlhbkNhbGVuZGFyIGNyZWF0ZVRpbWUoCi0gICAgICAgIGludCBob3VycywKLSAgICAgICAgaW50IG1pbnV0ZXMsCi0gICAgICAgIGludCBzZWNvbmRzLAotICAgICAgICAgICAgICAgIGludCB0aW1lem9uZSkgewotCi0gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBYTUxHcmVnb3JpYW5DYWxlbmRhckltcGwoCi0gICAgICAgICAgICAgICAgICAgICAgICBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQsIC8vIFllYXIKLSAgICAgICAgICAgICAgICAgICAgICAgIERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCwgLy8gTW9udGgKLSAgICAgICAgICAgICAgICAgICAgICAgIERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCwgLy8gRGF5Ci0gICAgICAgICAgICAgICAgICAgICAgICBob3VycywKLSAgICAgICAgICAgICAgICAgICAgICAgIG1pbnV0ZXMsCi0gICAgICAgICAgICAgICAgICAgICAgICBzZWNvbmRzLAotICAgICAgICAgICAgICAgICAgICAgICAgRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVELCAvL01pbGxpc2Vjb25kCi0gICAgICAgICAgICAgICAgICAgICAgICB0aW1lem9uZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+Q3JlYXRlIGEgSmF2YSBpbnN0YW5jZSBvZiBYTUwgU2NoZW1hIGJ1aWx0aW4gZGF0YXR5cGUgdGltZS48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gaG91cnMgbnVtYmVyIG9mIGhvdXJzCi0gICAgICogQHBhcmFtIG1pbnV0ZXMgbnVtYmVyIG9mIG1pbnV0ZXMKLSAgICAgKiBAcGFyYW0gc2Vjb25kcyBudW1iZXIgb2Ygc2Vjb25kcwotICAgICAqIEBwYXJhbSBmcmFjdGlvbmFsU2Vjb25kIHZhbHVlIG9mIDxjb2RlPm51bGw8L2NvZGU+IGluZGljYXRlcyB0aGF0IHRoaXMgb3B0aW9uYWwgZmllbGQgaXMgbm90IHNldC4KLSAgICAgKiBAcGFyYW0gdGltZXpvbmUgb2Zmc2V0IGluIG1pbnV0ZXMuIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNGSUVMRF9VTkRFRklORUR9IGluZGljYXRlcyBvcHRpb25hbCBmaWVsZCBpcyBub3Qgc2V0LgotICAgICAqCi0gICAgICogQHJldHVybiA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gY3JlYXRlZCBmcm9tIHBhcmFtZXRlciB2YWx1ZXMuCi0gICAgICoKLSAgICAgKiBAc2VlIERhdGF0eXBlQ29uc3RhbnRzI0ZJRUxEX1VOREVGSU5FRAotICAgICAqCi0gICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgYW55IHBhcmFtZXRlciBpcyBvdXRzaWRlIHZhbHVlCi0gICAgICogY29uc3RyYWludHMgZm9yIHRoZSBmaWVsZCBhcyBzcGVjaWZpZWQgaW4KLSAgICAgKiA8YSBocmVmPSIjZGF0ZXRpbWVmaWVsZG1hcHBpbmciPmRhdGUvdGltZSBmaWVsZCBtYXBwaW5nIHRhYmxlPC9hPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFhNTEdyZWdvcmlhbkNhbGVuZGFyIGNyZWF0ZVRpbWUoCi0gICAgICAgIGludCBob3VycywKLSAgICAgICAgaW50IG1pbnV0ZXMsCi0gICAgICAgIGludCBzZWNvbmRzLAotICAgICAgICBCaWdEZWNpbWFsIGZyYWN0aW9uYWxTZWNvbmQsCi0gICAgICAgIGludCB0aW1lem9uZSkgewotCi0gICAgICAgIHJldHVybiBuZXcgWE1MR3JlZ29yaWFuQ2FsZW5kYXJJbXBsKAotICAgICAgICAgICAgbnVsbCwgICAgICAgICAgICAvLyBZZWFyCi0gICAgICAgICAgICBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQsIC8vIG1vbnRoCi0gICAgICAgICAgICBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQsIC8vIGRheQotICAgICAgICAgICAgaG91cnMsCi0gICAgICAgICAgICBtaW51dGVzLAotICAgICAgICAgICAgc2Vjb25kcywKLSAgICAgICAgICAgIGZyYWN0aW9uYWxTZWNvbmQsCi0gICAgICAgICAgICB0aW1lem9uZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+Q3JlYXRlIGEgSmF2YSBpbnN0YW5jZSBvZiBYTUwgU2NoZW1hIGJ1aWx0aW4gZGF0YXR5cGUgdGltZS48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gaG91cnMgbnVtYmVyIG9mIGhvdXJzCi0gICAgICogQHBhcmFtIG1pbnV0ZXMgbnVtYmVyIG9mIG1pbnV0ZXMKLSAgICAgKiBAcGFyYW0gc2Vjb25kcyBudW1iZXIgb2Ygc2Vjb25kcwotICAgICAqIEBwYXJhbSBtaWxsaXNlY29uZHMgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcwotICAgICAqIEBwYXJhbSB0aW1lem9uZSBvZmZzZXQgaW4gbWludXRlcy4ge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0ZJRUxEX1VOREVGSU5FRH0gaW5kaWNhdGVzIG9wdGlvbmFsIGZpZWxkIGlzIG5vdCBzZXQuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiBjcmVhdGVkIGZyb20gcGFyYW1ldGVyIHZhbHVlcy4KLSAgICAgKgotICAgICAqIEBzZWUgRGF0YXR5cGVDb25zdGFudHMjRklFTERfVU5ERUZJTkVECi0gICAgICoKLSAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiBhbnkgcGFyYW1ldGVyIGlzIG91dHNpZGUgdmFsdWUKLSAgICAgKiBjb25zdHJhaW50cyBmb3IgdGhlIGZpZWxkIGFzIHNwZWNpZmllZCBpbgotICAgICAqIDxhIGhyZWY9IiNkYXRldGltZWZpZWxkbWFwcGluZyI+ZGF0ZS90aW1lIGZpZWxkIG1hcHBpbmcgdGFibGU8L2E+LgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgWE1MR3JlZ29yaWFuQ2FsZW5kYXIgY3JlYXRlVGltZSgKLSAgICAgICAgaW50IGhvdXJzLAotICAgICAgICBpbnQgbWludXRlcywKLSAgICAgICAgaW50IHNlY29uZHMsCi0gICAgICAgIGludCBtaWxsaXNlY29uZHMsCi0gICAgICAgIGludCB0aW1lem9uZSkgewotCi0gICAgICAgIHJldHVybiBuZXcgWE1MR3JlZ29yaWFuQ2FsZW5kYXJJbXBsKAotICAgICAgICAgICAgICAgIERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCwgLy8geWVhcgotICAgICAgICAgICAgICAgIERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCwgLy8gbW9udGgKLSAgICAgICAgICAgICAgICBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQsIC8vIGRheQotICAgICAgICAgICAgICAgIGhvdXJzLAotICAgICAgICAgICAgICAgIG1pbnV0ZXMsCi0gICAgICAgICAgICAgICAgc2Vjb25kcywKLSAgICAgICAgICAgICAgICBtaWxsaXNlY29uZHMsCi0gICAgICAgICAgICAgICAgdGltZXpvbmUpOwotICAgIH0KLQotICAgIC8vIEFjY2Vzc29ycwotCi0gICAgLyoqCi0gICAgICogPHA+UmV0dXJuIGhpZ2ggb3JkZXIgY29tcG9uZW50IGZvciBYTUwgU2NoZW1hIDEuMCBkYXRlVGltZSBkYXRhdHlwZSBmaWVsZCBmb3IKLSAgICAgKiA8Y29kZT55ZWFyPC9jb2RlPi4KLSAgICAgKiA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGlzIG9wdGlvbmFsIHBhcnQgb2YgdGhlIHllYXIgZmllbGQgaXMgbm90IGRlZmluZWQuPC9wPgotICAgICAqCi0gICAgICogPHA+VmFsdWUgY29uc3RyYWludHMgZm9yIHRoaXMgdmFsdWUgYXJlIHN1bW1hcml6ZWQgaW4KLSAgICAgKiA8YSBocmVmPSIjZGF0ZXRpbWVmaWVsZC15ZWFyIj55ZWFyIGZpZWxkIG9mIGRhdGUvdGltZSBmaWVsZCBtYXBwaW5nIHRhYmxlPC9hPi48L3A+Ci0gICAgICogQHJldHVybiBlb24gb2YgdGhpcyA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4uIFRoZSB2YWx1ZQotICAgICAqIHJldHVybmVkIGlzIGFuIGludGVnZXIgbXVsdGlwbGUgb2YgMTBeOS4KLSAgICAgKgotICAgICAqIEBzZWUgI2dldFllYXIoKQotICAgICAqIEBzZWUgI2dldEVvbkFuZFllYXIoKQotICAgICAqLwotICAgIHB1YmxpYyBCaWdJbnRlZ2VyIGdldEVvbigpIHsKLSAgICAgICAgICAgcmV0dXJuIGVvbjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5SZXR1cm4gbG93IG9yZGVyIGNvbXBvbmVudCBmb3IgWE1MIFNjaGVtYSAxLjAgZGF0ZVRpbWUgZGF0YXR5cGUgZmllbGQgZm9yCi0gICAgICogPGNvZGU+eWVhcjwvY29kZT4gb3Ige0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0ZJRUxEX1VOREVGSU5FRH0uPC9wPgotICAgICAqCi0gICAgICogPHA+VmFsdWUgY29uc3RyYWludHMgZm9yIHRoaXMgdmFsdWUgYXJlIHN1bW1hcml6ZWQgaW4KLSAgICAgKiA8YSBocmVmPSIjZGF0ZXRpbWVmaWVsZC15ZWFyIj55ZWFyIGZpZWxkIG9mIGRhdGUvdGltZSBmaWVsZCBtYXBwaW5nIHRhYmxlPC9hPi48L3A+Ci0gICAgICoKLSAgICAgKiBAcmV0dXJuIHllYXIgIG9mIHRoaXMgPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+LgotICAgICAqCi0gICAgICogQHNlZSAjZ2V0RW9uKCkKLSAgICAgKiBAc2VlICNnZXRFb25BbmRZZWFyKCkKLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldFllYXIoKSB7Ci0gICAgICAgICAgIHJldHVybiB5ZWFyOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPlJldHVybiBYTUwgU2NoZW1hIDEuMCBkYXRlVGltZSBkYXRhdHlwZSBmaWVsZCBmb3IKLSAgICAgKiA8Y29kZT55ZWFyPC9jb2RlPi48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5WYWx1ZSBjb25zdHJhaW50cyBmb3IgdGhpcyB2YWx1ZSBhcmUgc3VtbWFyaXplZCBpbgotICAgICAqIDxhIGhyZWY9IiNkYXRldGltZWZpZWxkLXllYXIiPnllYXIgZmllbGQgb2YgZGF0ZS90aW1lIGZpZWxkIG1hcHBpbmcgdGFibGU8L2E+LjwvcD4KLSAgICAgKgotICAgICAqIEByZXR1cm4gc3VtIG9mIDxjb2RlPmVvbjwvY29kZT4gYW5kIDxjb2RlPkJpZ0ludGVnZXIudmFsdWVPZih5ZWFyKTwvY29kZT4KLSAgICAgKiB3aGVuIGJvdGggZmllbGRzIGFyZSBkZWZpbmVkLiBXaGVuIG9ubHkgPGNvZGU+eWVhcjwvY29kZT4gaXMgZGVmaW5lZCwKLSAgICAgKiByZXR1cm4gaXQuIFdoZW4gYm90aCA8Y29kZT5lb248L2NvZGU+IGFuZCA8Y29kZT55ZWFyPC9jb2RlPiBhcmUgbm90Ci0gICAgICogZGVmaW5lZCwgcmV0dXJuIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAqCi0gICAgICogQHNlZSAjZ2V0RW9uKCkKLSAgICAgKiBAc2VlICNnZXRZZWFyKCkKLSAgICAgKi8KLSAgICBwdWJsaWMgQmlnSW50ZWdlciBnZXRFb25BbmRZZWFyKCkgewotCi0gICAgICAgICAgICAgICAgLy8gYm90aCBhcmUgZGVmaW5lZAotICAgICAgICAgICAgICAgIGlmICh5ZWFyICE9IERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRAotICAgICAgICAgICAgICAgICAgICAgICAgJiYgZW9uICE9IG51bGwpIHsKLQotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVvbi5hZGQoQmlnSW50ZWdlci52YWx1ZU9mKChsb25nKSB5ZWFyKSk7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgLy8gb25seSB5ZWFyIGlzIGRlZmluZWQKLSAgICAgICAgICAgICAgICBpZiAoeWVhciAhPSBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQKLSAgICAgICAgICAgICAgICAgICAgICAgICYmIGVvbiA9PSBudWxsKSB7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBCaWdJbnRlZ2VyLnZhbHVlT2YoKGxvbmcpIHllYXIpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAvLyBuZWl0aGVyIGFyZSBkZWZpbmVkCi0gICAgICAgIC8vIG9yIG9ubHkgZW9uIGlzIGRlZmluZWQgd2hpY2ggaXMgbm90IHZhbGlkIHdpdGhvdXQgYSB5ZWFyCi0gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+UmV0dXJuIG51bWJlciBvZiBtb250aCBvciB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjRklFTERfVU5ERUZJTkVEfS48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5WYWx1ZSBjb25zdHJhaW50cyBmb3IgdGhpcyB2YWx1ZSBhcmUgc3VtbWFyaXplZCBpbgotICAgICAqIDxhIGhyZWY9IiNkYXRldGltZWZpZWxkLW1vbnRoIj5tb250aCBmaWVsZCBvZiBkYXRlL3RpbWUgZmllbGQgbWFwcGluZyB0YWJsZTwvYT4uPC9wPgotICAgICAqCi0gICAgICogQHJldHVybiB5ZWFyICBvZiB0aGlzIDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPi4KLSAgICAgKgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0TW9udGgoKSB7Ci0gICAgICAgIHJldHVybiBtb250aDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gZGF5IGluIG1vbnRoIG9yIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNGSUVMRF9VTkRFRklORUR9LjwvcD4KLSAgICAgKgotICAgICAqIDxwPlZhbHVlIGNvbnN0cmFpbnRzIGZvciB0aGlzIHZhbHVlIGFyZSBzdW1tYXJpemVkIGluCi0gICAgICogPGEgaHJlZj0iI2RhdGV0aW1lZmllbGQtZGF5Ij5kYXkgZmllbGQgb2YgZGF0ZS90aW1lIGZpZWxkIG1hcHBpbmcgdGFibGU8L2E+LjwvcD4KLSAgICAgKgotICAgICAqIEBzZWUgI3NldERheShpbnQpCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXREYXkoKSB7Ci0gICAgICAgIHJldHVybiBkYXk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRpbWV6b25lIG9mZnNldCBpbiBtaW51dGVzIG9yCi0gICAgICoge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0ZJRUxEX1VOREVGSU5FRH0gaWYgdGhpcyBvcHRpb25hbCBmaWVsZCBpcyBub3QgZGVmaW5lZC4KLSAgICAgKgotICAgICAqIDxwPlZhbHVlIGNvbnN0cmFpbnRzIGZvciB0aGlzIHZhbHVlIGFyZSBzdW1tYXJpemVkIGluCi0gICAgICogPGEgaHJlZj0iI2RhdGV0aW1lZmllbGQtdGltZXpvbmUiPnRpbWV6b25lIGZpZWxkIG9mIGRhdGUvdGltZSBmaWVsZCBtYXBwaW5nIHRhYmxlPC9hPi48L3A+Ci0gICAgICoKLSAgICAgKiBAc2VlICNzZXRUaW1lem9uZShpbnQpCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRUaW1lem9uZSgpIHsKLSAgICAgICAgcmV0dXJuIHRpbWV6b25lOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybiBob3VycyBvciB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjRklFTERfVU5ERUZJTkVEfS4KLSAgICAgKiBSZXR1cm5zIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNGSUVMRF9VTkRFRklORUR9IGlmIHRoaXMgZmllbGQgaXMgbm90IGRlZmluZWQuCi0gICAgICoKLSAgICAgKiA8cD5WYWx1ZSBjb25zdHJhaW50cyBmb3IgdGhpcyB2YWx1ZSBhcmUgc3VtbWFyaXplZCBpbgotICAgICAqIDxhIGhyZWY9IiNkYXRldGltZWZpZWxkLWhvdXIiPmhvdXIgZmllbGQgb2YgZGF0ZS90aW1lIGZpZWxkIG1hcHBpbmcgdGFibGU8L2E+LjwvcD4KLSAgICAgKiBAc2VlICNzZXRUaW1lKGludCwgaW50LCBpbnQpCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRIb3VyKCkgewotICAgICAgICByZXR1cm4gaG91cjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gbWludXRlcyBvciB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjRklFTERfVU5ERUZJTkVEfS48XHA+Ci0gICAgICogUmV0dXJucyB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjRklFTERfVU5ERUZJTkVEfSBpZiB0aGlzIGZpZWxkIGlzIG5vdCBkZWZpbmVkLgotICAgICAqCi0gICAgICogPHA+VmFsdWUgY29uc3RyYWludHMgZm9yIHRoaXMgdmFsdWUgYXJlIHN1bW1hcml6ZWQgaW4KLSAgICAgKiA8YSBocmVmPSIjZGF0ZXRpbWVmaWVsZC1taW51dGUiPm1pbnV0ZSBmaWVsZCBvZiBkYXRlL3RpbWUgZmllbGQgbWFwcGluZyB0YWJsZTwvYT4uPC9wPgotICAgICAqIEBzZWUgI3NldFRpbWUoaW50LCBpbnQsIGludCkKLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldE1pbnV0ZSgpIHsKLSAgICAgICAgcmV0dXJuIG1pbnV0ZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5SZXR1cm4gc2Vjb25kcyBvciB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjRklFTERfVU5ERUZJTkVEfS48XHA+Ci0gICAgICoKLSAgICAgKiA8cD5SZXR1cm5zIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNGSUVMRF9VTkRFRklORUR9IGlmIHRoaXMgZmllbGQgaXMgbm90IGRlZmluZWQuCi0gICAgICogV2hlbiB0aGlzIGZpZWxkIGlzIG5vdCBkZWZpbmVkLCB0aGUgb3B0aW9uYWwgeHM6ZGF0ZVRpbWUKLSAgICAgKiBmcmFjdGlvbmFsIHNlY29uZHMgZmllbGQsIHJlcHJlc2VudGVkIGJ5Ci0gICAgICoge0BsaW5rICNnZXRGcmFjdGlvbmFsU2Vjb25kKCl9IGFuZCB7QGxpbmsgI2dldE1pbGxpc2Vjb25kKCl9LAotICAgICAqIG11c3Qgbm90IGJlIGRlZmluZWQuPC9wPgotICAgICAqCi0gICAgICogPHA+VmFsdWUgY29uc3RyYWludHMgZm9yIHRoaXMgdmFsdWUgYXJlIHN1bW1hcml6ZWQgaW4KLSAgICAgKiA8YSBocmVmPSIjZGF0ZXRpbWVmaWVsZC1zZWNvbmQiPnNlY29uZCBmaWVsZCBvZiBkYXRlL3RpbWUgZmllbGQgbWFwcGluZyB0YWJsZTwvYT4uPC9wPgotICAgICAqCi0gICAgICogQHJldHVybiBTZWNvbmQgIG9mIHRoaXMgPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+LgotICAgICAqCi0gICAgICogQHNlZSAjZ2V0RnJhY3Rpb25hbFNlY29uZCgpCi0gICAgICogQHNlZSAjZ2V0TWlsbGlzZWNvbmQoKQotICAgICAqIEBzZWUgI3NldFRpbWUoaW50LCBpbnQsIGludCkKLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldFNlY29uZCgpIHsKLSAgICAgICAgICAgcmV0dXJuIHNlY29uZDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAcmV0dXJuIHJlc3VsdCBvZiBhZGRpbmcgc2Vjb25kIGFuZCBmcmFjdGlvbmFsIHNlY29uZCBmaWVsZAotICAgICAqLwotICAgIHByaXZhdGUgQmlnRGVjaW1hbCBnZXRTZWNvbmRzKCkgewotICAgICAgICBpZiAoc2Vjb25kID09IERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCkgewotICAgICAgICAgICAgcmV0dXJuIERFQ0lNQUxfWkVSTzsKLSAgICAgICAgfQotICAgICAgICBCaWdEZWNpbWFsIHJlc3VsdCA9IEJpZ0RlY2ltYWwudmFsdWVPZigobG9uZykgc2Vjb25kKTsKLSAgICAgICAgaWYgKGZyYWN0aW9uYWxTZWNvbmQgIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIHJlc3VsdC5hZGQoZnJhY3Rpb25hbFNlY29uZCk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gcmVzdWx0OwotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiA8cD5SZXR1cm4gbWlsbGlzZWNvbmQgcHJlY2lzaW9uIG9mIHtAbGluayAjZ2V0RnJhY3Rpb25hbFNlY29uZCgpfS48XHA+Ci0gICAgICoKLSAgICAgKiA8cD5UaGlzIG1ldGhvZCByZXByZXNlbnRzIGEgY29udmVuaWVuY2UgYWNjZXNzb3IgdG8gaW5maW5pdGUKLSAgICAgKiBwcmVjaXNpb24gZnJhY3Rpb25hbCBzZWNvbmQgdmFsdWUgcmV0dXJuZWQgYnkKLSAgICAgKiB7QGxpbmsgI2dldEZyYWN0aW9uYWxTZWNvbmQoKX0uIFRoZSByZXR1cm5lZCB2YWx1ZSBpcyB0aGUgcm91bmRlZAotICAgICAqIGRvd24gdG8gbWlsbGlzZWNvbmRzIHZhbHVlIG9mCi0gICAgICoge0BsaW5rICNnZXRGcmFjdGlvbmFsU2Vjb25kKCl9LiBXaGVuIHtAbGluayAjZ2V0RnJhY3Rpb25hbFNlY29uZCgpfQotICAgICAqIHJldHVybnMgPGNvZGU+bnVsbDwvY29kZT4sIHRoaXMgbWV0aG9kIG11c3QgcmV0dXJuCi0gICAgICoge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0ZJRUxEX1VOREVGSU5FRH0uPC9wPgotICAgICAqCi0gICAgICogPHA+VmFsdWUgY29uc3RyYWludHMgZm9yIHRoaXMgdmFsdWUgYXJlIHN1bW1hcml6ZWQgaW4KLSAgICAgKiA8YSBocmVmPSIjZGF0ZXRpbWVmaWVsZC1zZWNvbmQiPnNlY29uZCBmaWVsZCBvZiBkYXRlL3RpbWUgZmllbGQgbWFwcGluZyB0YWJsZTwvYT4uPC9wPgotICAgICAqCi0gICAgICogQHJldHVybiBNaWxsaXNlY29uZCAgb2YgdGhpcyA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4uCi0gICAgICoKLSAgICAgKiBAc2VlICNnZXRGcmFjdGlvbmFsU2Vjb25kKCkKLSAgICAgKiBAc2VlICNzZXRUaW1lKGludCwgaW50LCBpbnQpCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRNaWxsaXNlY29uZCgpIHsKLSAgICAgICAgaWYgKGZyYWN0aW9uYWxTZWNvbmQgPT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRDsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIC8vIFRPRE86IE5vbi1vcHRpbWFsIHNvbHV0aW9uIGZvciBub3cuCi0gICAgICAgICAgICAvLyBFZmZpY2llbnQgaW1wbGVtZW50YXRpb24gd291bGQgb25seSBzdG9yZSBhcyBCaWdEZWNpbWFsCi0gICAgICAgICAgICAvLyB3aGVuIG5lZWRlZCBhbmQgbWlsbGlzZWNvbmQgb3RoZXJ3aXNlLgotICAgICAgICAgICAgcmV0dXJuIGZyYWN0aW9uYWxTZWNvbmQubW92ZVBvaW50UmlnaHQoMykuaW50VmFsdWUoKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPlJldHVybiBmcmFjdGlvbmFsIHNlY29uZHMuPC9wPgotICAgICAqCi0gICAgICogPHA+PGNvZGU+bnVsbDwvY29kZT4gaXMgcmV0dXJuZWQgd2hlbiB0aGlzIG9wdGlvbmFsIGZpZWxkIGlzIG5vdCBkZWZpbmVkLjwvcD4KLSAgICAgKgotICAgICAqIDxwPlZhbHVlIGNvbnN0cmFpbnRzIGFyZSBkZXRhaWxlZCBpbgotICAgICAqIDxhIGhyZWY9IiNkYXRldGltZWZpZWxkLXNlY29uZCI+c2Vjb25kIGZpZWxkIG9mIGRhdGUvdGltZSBmaWVsZCBtYXBwaW5nIHRhYmxlPC9hPi48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5UaGlzIG9wdGlvbmFsIGZpZWxkIGNhbiBvbmx5IGhhdmUgYSBkZWZpbmVkIHZhbHVlIHdoZW4gdGhlCi0gICAgICogeHM6ZGF0ZVRpbWUgc2Vjb25kIGZpZWxkLCByZXByZXNlbnRlZCBieSAoe0BsaW5rICNnZXRTZWNvbmQoKX0sCi0gICAgICogZG9lcyBub3QgcmV0dXJuIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNGSUVMRF9VTkRFRklORUR9KS48L3A+Ci0gICAgICoKLSAgICAgKiBAcmV0dXJuIGZyYWN0aW9uYWwgc2Vjb25kcyAgb2YgdGhpcyA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4uCi0gICAgICoKLSAgICAgKiBAc2VlICNnZXRTZWNvbmQoKQotICAgICAqIEBzZWUgI3NldFRpbWUoaW50LCBpbnQsIGludCwgQmlnRGVjaW1hbCkKLSAgICAgKi8KLSAgICBwdWJsaWMgQmlnRGVjaW1hbCBnZXRGcmFjdGlvbmFsU2Vjb25kKCkgewotICAgICAgICAgICByZXR1cm4gZnJhY3Rpb25hbFNlY29uZDsKLSAgICB9Ci0KLSAgICAvLyBzZXR0ZXJzCi0KLSAgICAvKioKLSAgICAgKiA8cD5TZXQgbG93IGFuZCBoaWdoIG9yZGVyIGNvbXBvbmVudCBvZiBYU0QgPGNvZGU+ZGF0ZVRpbWU8L2NvZGU+IHllYXIgZmllbGQuPC9wPgotICAgICAqCi0gICAgICogPHA+VW5zZXQgdGhpcyBmaWVsZCBieSBpbnZva2luZyB0aGUgc2V0dGVyIHdpdGggYSBwYXJhbWV0ZXIgdmFsdWUgb2YgPGNvZGU+bnVsbDwvY29kZT4uPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIHllYXIgdmFsdWUgY29uc3RyYWludHMgc3VtbWFyaXplZCBpbiA8YSBocmVmPSIjZGF0ZXRpbWVmaWVsZC15ZWFyIj55ZWFyIGZpZWxkIG9mIGRhdGUvdGltZSBmaWVsZCBtYXBwaW5nIHRhYmxlPC9hPi4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIDxjb2RlPnllYXI8L2NvZGU+IHBhcmFtZXRlciBpcwotICAgICAqIG91dHNpZGUgdmFsdWUgY29uc3RyYWludHMgZm9yIHRoZSBmaWVsZCBhcyBzcGVjaWZpZWQgaW4KLSAgICAgKiA8YSBocmVmPSIjZGF0ZXRpbWVmaWVsZG1hcHBpbmciPmRhdGUvdGltZSBmaWVsZCBtYXBwaW5nIHRhYmxlPC9hPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRZZWFyKEJpZ0ludGVnZXIgeWVhcikgewotICAgICAgICBpZiAoeWVhciA9PSBudWxsKSB7Ci0gICAgICAgICAgICB0aGlzLmVvbiA9IG51bGw7Ci0gICAgICAgICAgICB0aGlzLnllYXIgPSBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQ7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBCaWdJbnRlZ2VyIHRlbXAgPSB5ZWFyLnJlbWFpbmRlcihCSUxMSU9OKTsKLSAgICAgICAgICAgIHRoaXMueWVhciA9IHRlbXAuaW50VmFsdWUoKTsKLSAgICAgICAgICAgIHNldEVvbih5ZWFyLnN1YnRyYWN0KHRlbXApKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPlNldCB5ZWFyIG9mIFhTRCA8Y29kZT5kYXRlVGltZTwvY29kZT4geWVhciBmaWVsZC48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5VbnNldCB0aGlzIGZpZWxkIGJ5IGludm9raW5nIHRoZSBzZXR0ZXIgd2l0aCBhIHBhcmFtZXRlciB2YWx1ZSBvZgotICAgICAqIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNGSUVMRF9VTkRFRklORUR9LjwvcD4KLSAgICAgKgotICAgICAqIDxwPk5vdGU6IGlmIHRoZSBhYnNvbHV0ZSB2YWx1ZSBvZiB0aGUgPGNvZGU+eWVhcjwvY29kZT4gcGFyYW1ldGVyCi0gICAgICogaXMgbGVzcyB0aGFuIDEwXjksIHRoZSBlb24gY29tcG9uZW50IG9mIHRoZSBYU0QgeWVhciBmaWVsZCBpcyBzZXQgdG8KLSAgICAgKiA8Y29kZT5udWxsPC9jb2RlPiBieSB0aGlzIG1ldGhvZC48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0geWVhciB2YWx1ZSBjb25zdHJhaW50cyBhcmUgc3VtbWFyaXplZCBpbiA8YSBocmVmPSIjZGF0ZXRpbWVmaWVsZC15ZWFyIj55ZWFyIGZpZWxkIG9mIGRhdGUvdGltZSBmaWVsZCBtYXBwaW5nIHRhYmxlPC9hPi4KLSAgICAgKiAgIElmIHllYXIgaXMge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0ZJRUxEX1VOREVGSU5FRH0sIHRoZW4gZW9uIGlzIHNldCB0byA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRZZWFyKGludCB5ZWFyKSB7Ci0gICAgICAgIGlmICh5ZWFyID09IERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCkgewotICAgICAgICAgICAgdGhpcy55ZWFyID0gRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVEOwotICAgICAgICAgICAgdGhpcy5lb24gPSBudWxsOwotICAgICAgICB9IGVsc2UgaWYgKE1hdGguYWJzKHllYXIpIDwgQklMTElPTi5pbnRWYWx1ZSgpKSB7Ci0gICAgICAgICAgICB0aGlzLnllYXIgPSB5ZWFyOwotICAgICAgICAgICAgdGhpcy5lb24gPSBudWxsOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgQmlnSW50ZWdlciB0aGVZZWFyID0gQmlnSW50ZWdlci52YWx1ZU9mKChsb25nKSB5ZWFyKTsKLSAgICAgICAgICAgIEJpZ0ludGVnZXIgcmVtYWluZGVyID0gdGhlWWVhci5yZW1haW5kZXIoQklMTElPTik7Ci0gICAgICAgICAgICB0aGlzLnllYXIgPSByZW1haW5kZXIuaW50VmFsdWUoKTsKLSAgICAgICAgICAgIHNldEVvbih0aGVZZWFyLnN1YnRyYWN0KHJlbWFpbmRlcikpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+U2V0IGhpZ2ggb3JkZXIgcGFydCBvZiBYU0QgPGNvZGU+ZGF0ZVRpbWU8L2NvZGU+IHllYXIgZmllbGQuPC9wPgotICAgICAqCi0gICAgICogPHA+VW5zZXQgdGhpcyBmaWVsZCBieSBpbnZva2luZyB0aGUgc2V0dGVyIHdpdGggYSBwYXJhbWV0ZXIgdmFsdWUgb2YKLSAgICAgKiA8Y29kZT5udWxsPC9jb2RlPi48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gZW9uIHZhbHVlIGNvbnN0cmFpbnRzIHN1bW1hcml6ZWQgaW4gPGEgaHJlZj0iI2RhdGV0aW1lZmllbGQteWVhciI+eWVhciBmaWVsZCBvZiBkYXRlL3RpbWUgZmllbGQgbWFwcGluZyB0YWJsZTwvYT4uCi0gICAgICovCi0gICAgcHJpdmF0ZSB2b2lkIHNldEVvbihCaWdJbnRlZ2VyIGVvbikgewotICAgICAgICBpZiAoZW9uICE9IG51bGwgJiYgZW9uLmNvbXBhcmVUbyhCaWdJbnRlZ2VyLlpFUk8pID09IDApIHsKLSAgICAgICAgICAgIC8vIFRyZWF0IFpFUk8gYXMgZmllbGQgYmVpbmcgdW5kZWZpbmVkLgotICAgICAgICAgICAgdGhpcy5lb24gPSBudWxsOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgdGhpcy5lb24gPSBlb247Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5TZXQgbW9udGguPC9wPgotICAgICAqCi0gICAgICogPHA+VW5zZXQgdGhpcyBmaWVsZCBieSBpbnZva2luZyB0aGUgc2V0dGVyIHdpdGggYSBwYXJhbWV0ZXIgdmFsdWUgb2Yge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0ZJRUxEX1VOREVGSU5FRH0uPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIG1vbnRoIHZhbHVlIGNvbnN0cmFpbnRzIHN1bW1hcml6ZWQgaW4gPGEgaHJlZj0iI2RhdGV0aW1lZmllbGQtbW9udGgiPm1vbnRoIGZpZWxkIG9mIGRhdGUvdGltZSBmaWVsZCBtYXBwaW5nIHRhYmxlPC9hPi4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIDxjb2RlPm1vbnRoPC9jb2RlPiBwYXJhbWV0ZXIgaXMKLSAgICAgKiBvdXRzaWRlIHZhbHVlIGNvbnN0cmFpbnRzIGZvciB0aGUgZmllbGQgYXMgc3BlY2lmaWVkIGluCi0gICAgICogPGEgaHJlZj0iI2RhdGV0aW1lZmllbGRtYXBwaW5nIj5kYXRlL3RpbWUgZmllbGQgbWFwcGluZyB0YWJsZTwvYT4uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0TW9udGgoaW50IG1vbnRoKSB7Ci0gICAgICAgIGlmKG1vbnRoPERhdGF0eXBlQ29uc3RhbnRzLkpBTlVBUlkgfHwgRGF0YXR5cGVDb25zdGFudHMuREVDRU1CRVI8bW9udGgpCi0gICAgICAgICAgICBpZihtb250aCE9RGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVEKQotICAgICAgICAgICAgICAgIGludmFsaWRGaWVsZFZhbHVlKE1PTlRILCBtb250aCk7Ci0gICAgICAgIHRoaXMubW9udGggPSBtb250aDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5TZXQgZGF5cyBpbiBtb250aC48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5VbnNldCB0aGlzIGZpZWxkIGJ5IGludm9raW5nIHRoZSBzZXR0ZXIgd2l0aCBhIHBhcmFtZXRlciB2YWx1ZSBvZiB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjRklFTERfVU5ERUZJTkVEfS48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gZGF5IHZhbHVlIGNvbnN0cmFpbnRzIHN1bW1hcml6ZWQgaW4gPGEgaHJlZj0iI2RhdGV0aW1lZmllbGQtZGF5Ij5kYXkgZmllbGQgb2YgZGF0ZS90aW1lIGZpZWxkIG1hcHBpbmcgdGFibGU8L2E+LgotICAgICAqCi0gICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgPGNvZGU+ZGF5PC9jb2RlPiBwYXJhbWV0ZXIgaXMKLSAgICAgKiBvdXRzaWRlIHZhbHVlIGNvbnN0cmFpbnRzIGZvciB0aGUgZmllbGQgYXMgc3BlY2lmaWVkIGluCi0gICAgICogPGEgaHJlZj0iI2RhdGV0aW1lZmllbGRtYXBwaW5nIj5kYXRlL3RpbWUgZmllbGQgbWFwcGluZyB0YWJsZTwvYT4uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RGF5KGludCBkYXkpIHsKLSAgICAgICAgaWYoZGF5PDEgfHwgMzE8ZGF5KQotICAgICAgICAgICAgaWYoZGF5IT1EYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQpCi0gICAgICAgICAgICAgICAgaW52YWxpZEZpZWxkVmFsdWUoREFZLGRheSk7Ci0gICAgICAgIHRoaXMuZGF5ID0gZGF5OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPlNldCB0aGUgbnVtYmVyIG9mIG1pbnV0ZXMgaW4gdGhlIHRpbWV6b25lIG9mZnNldC48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5VbnNldCB0aGlzIGZpZWxkIGJ5IGludm9raW5nIHRoZSBzZXR0ZXIgd2l0aCBhIHBhcmFtZXRlciB2YWx1ZSBvZiB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjRklFTERfVU5ERUZJTkVEfS48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gb2Zmc2V0IHZhbHVlIGNvbnN0cmFpbnRzIHN1bW1hcml6ZWQgaW4gPGEgaHJlZj0iI2RhdGV0aW1lZmllbGQtdGltZXpvbmUiPgotICAgICAqICAgdGltZXpvbmUgZmllbGQgb2YgZGF0ZS90aW1lIGZpZWxkIG1hcHBpbmcgdGFibGU8L2E+LgotICAgICAqCi0gICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgPGNvZGU+b2Zmc2V0PC9jb2RlPiBwYXJhbWV0ZXIgaXMKLSAgICAgKiBvdXRzaWRlIHZhbHVlIGNvbnN0cmFpbnRzIGZvciB0aGUgZmllbGQgYXMgc3BlY2lmaWVkIGluCi0gICAgICogPGEgaHJlZj0iI2RhdGV0aW1lZmllbGRtYXBwaW5nIj5kYXRlL3RpbWUgZmllbGQgbWFwcGluZyB0YWJsZTwvYT4uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0VGltZXpvbmUoaW50IG9mZnNldCkgewotICAgICAgICAgICAgaWYob2Zmc2V0PC0xNCo2MCB8fCAxNCo2MDxvZmZzZXQpCi0gICAgICAgICAgICBpZihvZmZzZXQhPURhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCkKLSAgICAgICAgICAgICAgICBpbnZhbGlkRmllbGRWYWx1ZShUSU1FWk9ORSxvZmZzZXQpOwotICAgICAgICB0aGlzLnRpbWV6b25lID0gb2Zmc2V0OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPlNldCB0aW1lIGFzIG9uZSB1bml0LjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBob3VyIHZhbHVlIGNvbnN0cmFpbnRzIGFyZSBzdW1tYXJpemVkIGluCi0gICAgICogPGEgaHJlZj0iI2RhdGV0aW1lZmllbGQtaG91ciI+aG91ciBmaWVsZCBvZiBkYXRlL3RpbWUgZmllbGQgbWFwcGluZyB0YWJsZTwvYT4uCi0gICAgICogQHBhcmFtIG1pbnV0ZSB2YWx1ZSBjb25zdHJhaW50cyBhcmUgc3VtbWFyaXplZCBpbgotICAgICAqIDxhIGhyZWY9IiNkYXRldGltZWZpZWxkLW1pbnV0ZSI+bWludXRlIGZpZWxkIG9mIGRhdGUvdGltZSBmaWVsZCBtYXBwaW5nIHRhYmxlPC9hPi4KLSAgICAgKiBAcGFyYW0gc2Vjb25kIHZhbHVlIGNvbnN0cmFpbnRzIGFyZSBzdW1tYXJpemVkIGluCi0gICAgICogPGEgaHJlZj0iI2RhdGV0aW1lZmllbGQtc2Vjb25kIj5zZWNvbmQgZmllbGQgb2YgZGF0ZS90aW1lIGZpZWxkIG1hcHBpbmcgdGFibGU8L2E+LgotICAgICAqCi0gICAgICogQHNlZSAjc2V0VGltZShpbnQsIGludCwgaW50LCBCaWdEZWNpbWFsKQotICAgICAqCi0gICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgYW55IHBhcmFtZXRlciBpcwotICAgICAqIG91dHNpZGUgdmFsdWUgY29uc3RyYWludHMgZm9yIHRoZSBmaWVsZCBhcyBzcGVjaWZpZWQgaW4KLSAgICAgKiA8YSBocmVmPSIjZGF0ZXRpbWVmaWVsZG1hcHBpbmciPmRhdGUvdGltZSBmaWVsZCBtYXBwaW5nIHRhYmxlPC9hPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRUaW1lKGludCBob3VyLCBpbnQgbWludXRlLCBpbnQgc2Vjb25kKSB7Ci0gICAgICAgIHNldFRpbWUoaG91ciwgbWludXRlLCBzZWNvbmQsIG51bGwpOwotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBpbnZhbGlkRmllbGRWYWx1ZShpbnQgZmllbGQsIGludCB2YWx1ZSkgewotICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAotICAgICAgICAgICAgRGF0YXR5cGVNZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UobnVsbCwgIkludmFsaWRGaWVsZFZhbHVlIiwKLSAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117IG5ldyBJbnRlZ2VyKHZhbHVlKSwgRklFTERfTkFNRVtmaWVsZF19KQotICAgICAgICApOwotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCB0ZXN0SG91cigpIHsKLQotICAgICAgICAvLyBodHRwOi8vd3d3LnczLm9yZy8yMDAxLzA1L3htbHNjaGVtYS1lcnJhdGEjZTItNDUKLSAgICAgICAgaWYgKGdldEhvdXIoKSA9PSAyNCkgewotICAgICAgICAgICAgaWYgKGdldE1pbnV0ZSgpICE9IDAKLSAgICAgICAgICAgICAgICAgICAgfHwgZ2V0U2Vjb25kKCkgIT0gMCkgewotICAgICAgICAgICAgICAgIGludmFsaWRGaWVsZFZhbHVlKEhPVVIsIGdldEhvdXIoKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyB3aGlsZSAwLTI0IGlzIGFjY2VwdGFibGUgaW4gdGhlIGxleGljYWwgc3BhY2UsIDI0IGlzIG5vdCB2YWxpZCBpbiB2YWx1ZSBzcGFjZQotICAgICAgICAgICAgLy8gVzNDIFhNTCBTY2hlbWEgUGFydCAyLCBTZWN0aW9uIDMuMi43LjEKLSAgICAgICAgICAgIHNldEhvdXIoMCwgZmFsc2UpOwotICAgICAgICAgICAgYWRkKG5ldyBEdXJhdGlvbkltcGwodHJ1ZSwgMCwgMCwgMSwgMCwgMCwgMCkpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0SG91cihpbnQgaG91cikgewotCi0gICAgICAgIHNldEhvdXIoaG91ciwgdHJ1ZSk7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIHNldEhvdXIoaW50IGhvdXIsIGJvb2xlYW4gdmFsaWRhdGUpIHsKLQotICAgICAgICBpZiAoaG91ciA8IDAgfHwgaG91ciA+IDI0KSB7Ci0gICAgICAgICAgICBpZiAoaG91ciAhPSBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQpIHsKLSAgICAgICAgICAgICAgICBpbnZhbGlkRmllbGRWYWx1ZShIT1VSLCBob3VyKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHRoaXMuaG91ciA9IGhvdXI7Ci0KLSAgICAgICAgaWYgKHZhbGlkYXRlKSB7Ci0gICAgICAgICAgICB0ZXN0SG91cigpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0TWludXRlKGludCBtaW51dGUpIHsKLSAgICAgICAgaWYobWludXRlPDAgfHwgNTk8bWludXRlKQotICAgICAgICAgICAgaWYobWludXRlIT1EYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQpCi0gICAgICAgICAgICAgICAgaW52YWxpZEZpZWxkVmFsdWUoTUlOVVRFLCBtaW51dGUpOwotICAgICAgICB0aGlzLm1pbnV0ZSA9IG1pbnV0ZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRTZWNvbmQoaW50IHNlY29uZCkgewotICAgICAgICBpZihzZWNvbmQ8MCB8fCA2MDxzZWNvbmQpICAgLy8gbGVhcCBzZWNvbmQgYWxsb3dzIGZvciA2MAotICAgICAgICAgICAgaWYoc2Vjb25kIT1EYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQpCi0gICAgICAgICAgICAgICAgaW52YWxpZEZpZWxkVmFsdWUoU0VDT05ELCBzZWNvbmQpOwotICAgICAgICB0aGlzLnNlY29uZCAgPSBzZWNvbmQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+U2V0IHRpbWUgYXMgb25lIHVuaXQsIGluY2x1ZGluZyB0aGUgb3B0aW9uYWwgaW5maW5pdGUgcHJlY2lzb24KLSAgICAgKiBmcmFjdGlvbmFsIHNlY29uZHMuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGhvdXIgdmFsdWUgY29uc3RyYWludHMgYXJlIHN1bW1hcml6ZWQgaW4KLSAgICAgKiA8YSBocmVmPSIjZGF0ZXRpbWVmaWVsZC1ob3VyIj5ob3VyIGZpZWxkIG9mIGRhdGUvdGltZSBmaWVsZCBtYXBwaW5nIHRhYmxlPC9hPi4KLSAgICAgKiBAcGFyYW0gbWludXRlIHZhbHVlIGNvbnN0cmFpbnRzIGFyZSBzdW1tYXJpemVkIGluCi0gICAgICogPGEgaHJlZj0iI2RhdGV0aW1lZmllbGQtbWludXRlIj5taW51dGUgZmllbGQgb2YgZGF0ZS90aW1lIGZpZWxkIG1hcHBpbmcgdGFibGU8L2E+LgotICAgICAqIEBwYXJhbSBzZWNvbmQgdmFsdWUgY29uc3RyYWludHMgYXJlIHN1bW1hcml6ZWQgaW4KLSAgICAgKiA8YSBocmVmPSIjZGF0ZXRpbWVmaWVsZC1zZWNvbmQiPnNlY29uZCBmaWVsZCBvZiBkYXRlL3RpbWUgZmllbGQgbWFwcGluZyB0YWJsZTwvYT4uCi0gICAgICogQHBhcmFtIGZyYWN0aW9uYWwgdmFsdWUgb2YgPGNvZGU+bnVsbDwvY29kZT4gaW5kaWNhdGVzIHRoaXMgb3B0aW9uYWwKLSAgICAgKiAgICAgICAgICAgICAgICAgICBmaWVsZCBpcyBub3Qgc2V0LgotICAgICAqCi0gICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgYW55IHBhcmFtZXRlciBpcwotICAgICAqIG91dHNpZGUgdmFsdWUgY29uc3RyYWludHMgZm9yIHRoZSBmaWVsZCBhcyBzcGVjaWZpZWQgaW4KLSAgICAgKiA8YSBocmVmPSIjZGF0ZXRpbWVmaWVsZG1hcHBpbmciPmRhdGUvdGltZSBmaWVsZCBtYXBwaW5nIHRhYmxlPC9hPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRUaW1lKAotICAgICAgICAgICAgaW50IGhvdXIsCi0gICAgICAgICAgICBpbnQgbWludXRlLAotICAgICAgICAgICAgaW50IHNlY29uZCwKLSAgICAgICAgICAgIEJpZ0RlY2ltYWwgZnJhY3Rpb25hbCkgewotCi0gICAgICAgIHNldEhvdXIoaG91ciwgZmFsc2UpOwotCi0gICAgICAgIHNldE1pbnV0ZShtaW51dGUpOwotICAgICAgICBpZiAoc2Vjb25kICE9IDYwKSB7Ci0gICAgICAgICAgICBzZXRTZWNvbmQoc2Vjb25kKTsKLSAgICAgICAgfSBlbHNlIGlmICgoaG91ciA9PSAyMyAmJiBtaW51dGUgPT0gNTkpIHx8IChob3VyID09IDAgJiYgbWludXRlID09IDApKSB7Ci0gICAgICAgICAgICBzZXRTZWNvbmQoc2Vjb25kKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIGludmFsaWRGaWVsZFZhbHVlKFNFQ09ORCwgc2Vjb25kKTsKLSAgICAgICAgfQotCi0gICAgICAgIHNldEZyYWN0aW9uYWxTZWNvbmQoZnJhY3Rpb25hbCk7Ci0KLSAgICAgICAgLy8gbXVzdCB0ZXN0IGhvdXIgYWZ0ZXIgc2V0dGluZyBzZWNvbmRzCi0gICAgICAgIHRlc3RIb3VyKCk7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiA8cD5TZXQgdGltZSBhcyBvbmUgdW5pdCwgaW5jbHVkaW5nIG9wdGlvbmFsIG1pbGxpc2Vjb25kcy48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gaG91ciB2YWx1ZSBjb25zdHJhaW50cyBhcmUgc3VtbWFyaXplZCBpbgotICAgICAqIDxhIGhyZWY9IiNkYXRldGltZWZpZWxkLWhvdXIiPmhvdXIgZmllbGQgb2YgZGF0ZS90aW1lIGZpZWxkIG1hcHBpbmcgdGFibGU8L2E+LgotICAgICAqIEBwYXJhbSBtaW51dGUgdmFsdWUgY29uc3RyYWludHMgYXJlIHN1bW1hcml6ZWQgaW4KLSAgICAgKiA8YSBocmVmPSIjZGF0ZXRpbWVmaWVsZC1taW51dGUiPm1pbnV0ZSBmaWVsZCBvZiBkYXRlL3RpbWUgZmllbGQgbWFwcGluZyB0YWJsZTwvYT4uCi0gICAgICogQHBhcmFtIHNlY29uZCB2YWx1ZSBjb25zdHJhaW50cyBhcmUgc3VtbWFyaXplZCBpbgotICAgICAqIDxhIGhyZWY9IiNkYXRldGltZWZpZWxkLXNlY29uZCI+c2Vjb25kIGZpZWxkIG9mIGRhdGUvdGltZSBmaWVsZCBtYXBwaW5nIHRhYmxlPC9hPi4KLSAgICAgKiBAcGFyYW0gbWlsbGlzZWNvbmQgdmFsdWUgb2Yge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0ZJRUxEX1VOREVGSU5FRH0gaW5kaWNhdGVzIHRoaXMKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgb3B0aW9uYWwgZmllbGQgaXMgbm90IHNldC4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIGFueSBwYXJhbWV0ZXIgaXMKLSAgICAgKiBvdXRzaWRlIHZhbHVlIGNvbnN0cmFpbnRzIGZvciB0aGUgZmllbGQgYXMgc3BlY2lmaWVkIGluCi0gICAgICogPGEgaHJlZj0iI2RhdGV0aW1lZmllbGRtYXBwaW5nIj5kYXRlL3RpbWUgZmllbGQgbWFwcGluZyB0YWJsZTwvYT4uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0VGltZShpbnQgaG91ciwgaW50IG1pbnV0ZSwgaW50IHNlY29uZCwgaW50IG1pbGxpc2Vjb25kKSB7Ci0KLSAgICAgICAgc2V0SG91cihob3VyLCBmYWxzZSk7Ci0KLSAgICAgICAgc2V0TWludXRlKG1pbnV0ZSk7Ci0gICAgICAgIGlmIChzZWNvbmQgIT0gNjApIHsKLSAgICAgICAgICAgIHNldFNlY29uZChzZWNvbmQpOwotICAgICAgICB9IGVsc2UgaWYgKChob3VyID09IDIzICYmIG1pbnV0ZSA9PSA1OSkgfHwgKGhvdXIgPT0gMCAmJiBtaW51dGUgPT0gMCkpIHsKLSAgICAgICAgICAgIHNldFNlY29uZChzZWNvbmQpOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgaW52YWxpZEZpZWxkVmFsdWUoU0VDT05ELCBzZWNvbmQpOwotICAgICAgICB9Ci0gICAgICAgIHNldE1pbGxpc2Vjb25kKG1pbGxpc2Vjb25kKTsKLQotICAgICAgICAvLyBtdXN0IHRlc3QgaG91ciBhZnRlciBzZXR0aW5nIHNlY29uZHMKLSAgICAgICAgdGVzdEhvdXIoKTsKLSAgICB9Ci0KLSAgICAvLyBjb21wYXJpc29ucwotICAgIC8qKgotICAgICAqIDxwPkNvbXBhcmUgdHdvIGluc3RhbmNlcyBvZiBXM0MgWE1MIFNjaGVtYSAxLjAgZGF0ZS90aW1lIGRhdGF0eXBlcwotICAgICAqIGFjY29yZGluZyB0byBwYXJ0aWFsIG9yZGVyIHJlbGF0aW9uIGRlZmluZWQgaW4KLSAgICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94bWxzY2hlbWEtMi8jZGF0ZVRpbWUtb3JkZXIiPlczQyBYTUwgU2NoZW1hIDEuMCBQYXJ0IDIsIFNlY3Rpb24gMy4yLjcuMywKLSAgICAgKiA8aT5PcmRlciByZWxhdGlvbiBvbiBkYXRlVGltZTwvaT48L2E+LjwvcD4KLSAgICAgKgotICAgICAqIDxwPjxjb2RlPnhzZDpkYXRlVGltZTwvY29kZT4gZGF0YXR5cGUgZmllbGQgbWFwcGluZyB0byBhY2Nlc3NvcnMgb2YKLSAgICAgKiB0aGlzIGNsYXNzIGFyZSBkZWZpbmVkIGluCi0gICAgICogPGEgaHJlZj0iI2RhdGV0aW1lZmllbGRtYXBwaW5nIj5kYXRlL3RpbWUgZmllbGQgbWFwcGluZyB0YWJsZTwvYT4uPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIHJocyBpbnN0YW5jZSBvZiA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gdG8gY29tcGFyZQotICAgICAqCi0gICAgICogQHJldHVybiB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gPGNvZGU+bGhzPC9jb2RlPiBhbmQgPGNvZGU+cmhzPC9jb2RlPiBhcwotICAgICAqICAge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0xFU1NFUn0sCi0gICAgICogICB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjRVFVQUx9LAotICAgICAqICAge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0dSRUFURVJ9IG9yCi0gICAgICogICB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjSU5ERVRFUk1JTkFURX0uCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIDxjb2RlPmxoczwvY29kZT4gb3IgPGNvZGU+cmhzPC9jb2RlPgotICAgICAqIHBhcmFtZXRlcnMgYXJlIG51bGwuCi0gICAgICovCi0gICAgcHVibGljIGludCBjb21wYXJlKFhNTEdyZWdvcmlhbkNhbGVuZGFyIHJocykgewotCi0gICAgICAgIFhNTEdyZWdvcmlhbkNhbGVuZGFyIGxocyA9IHRoaXM7Ci0KLSAgICAgICAgaW50IHJlc3VsdCA9IERhdGF0eXBlQ29uc3RhbnRzLklOREVURVJNSU5BVEU7Ci0gICAgICAgIFhNTEdyZWdvcmlhbkNhbGVuZGFySW1wbCBQID0gKFhNTEdyZWdvcmlhbkNhbGVuZGFySW1wbCkgbGhzOwotICAgICAgICBYTUxHcmVnb3JpYW5DYWxlbmRhckltcGwgUSA9IChYTUxHcmVnb3JpYW5DYWxlbmRhckltcGwpIHJoczsKLQotICAgICAgICBpZiAoUC5nZXRUaW1lem9uZSgpID09IFEuZ2V0VGltZXpvbmUoKSkgewotICAgICAgICAgICAgLy8gT3B0aW1pemF0aW9uOgotICAgICAgICAgICAgLy8gYm90aCBpbnN0YW5jZXMgYXJlIGluIHNhbWUgdGltZXpvbmUgb3IKLSAgICAgICAgICAgIC8vIGJvdGggYXJlIEZJRUxEX1VOREVGSU5FRC4KLSAgICAgICAgICAgIC8vIEF2b2lkIGNvc3RseSBub3JtYWxpemF0aW9uIG9mIHRpbWV6b25lIHRvICdaJyB0aW1lLgotICAgICAgICAgICAgcmV0dXJuIGludGVybmFsQ29tcGFyZShQLCBRKTsKLQotICAgICAgICB9IGVsc2UgaWYgKFAuZ2V0VGltZXpvbmUoKSAhPSBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQgJiYKLSAgICAgICAgICAgICAgICBRLmdldFRpbWV6b25lKCkgIT0gRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVEKSB7Ci0KLSAgICAgICAgICAgIC8vIEJvdGggaW5zdGFuY2VzIGhhdmUgZGlmZmVyZW50IHRpbWV6b25lcy4KLSAgICAgICAgICAgIC8vIE5vcm1hbGl6ZSB0byBVVEMgdGltZSBhbmQgY29tcGFyZS4KLSAgICAgICAgICAgIFAgPSAoWE1MR3JlZ29yaWFuQ2FsZW5kYXJJbXBsKSBQLm5vcm1hbGl6ZSgpOwotICAgICAgICAgICAgUSA9IChYTUxHcmVnb3JpYW5DYWxlbmRhckltcGwpIFEubm9ybWFsaXplKCk7Ci0gICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxDb21wYXJlKFAsIFEpOwotICAgICAgICB9IGVsc2UgaWYgKFAuZ2V0VGltZXpvbmUoKSAhPSBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQpIHsKLQotICAgICAgICAgICAgaWYgKFAuZ2V0VGltZXpvbmUoKSAhPSAwKSB7Ci0gICAgICAgICAgICAgICAgUCA9IChYTUxHcmVnb3JpYW5DYWxlbmRhckltcGwpIFAubm9ybWFsaXplKCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIEMuIHN0ZXAgMQotICAgICAgICAgICAgWE1MR3JlZ29yaWFuQ2FsZW5kYXIgTWluUSA9IFEubm9ybWFsaXplVG9UaW1lem9uZShEYXRhdHlwZUNvbnN0YW50cy5NSU5fVElNRVpPTkVfT0ZGU0VUKTsKLSAgICAgICAgICAgIHJlc3VsdCA9IGludGVybmFsQ29tcGFyZShQLCBNaW5RKTsKLSAgICAgICAgICAgIGlmIChyZXN1bHQgPT0gRGF0YXR5cGVDb25zdGFudHMuTEVTU0VSKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gQy4gc3RlcCAyCi0gICAgICAgICAgICBYTUxHcmVnb3JpYW5DYWxlbmRhciBNYXhRID0gUS5ub3JtYWxpemVUb1RpbWV6b25lKERhdGF0eXBlQ29uc3RhbnRzLk1BWF9USU1FWk9ORV9PRkZTRVQpOwotICAgICAgICAgICAgcmVzdWx0ID0gaW50ZXJuYWxDb21wYXJlKFAsIE1heFEpOwotICAgICAgICAgICAgaWYgKHJlc3VsdCA9PSBEYXRhdHlwZUNvbnN0YW50cy5HUkVBVEVSKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgLy8gQy4gc3RlcCAzCi0gICAgICAgICAgICAgICAgcmV0dXJuIERhdGF0eXBlQ29uc3RhbnRzLklOREVURVJNSU5BVEU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gZWxzZSB7IC8vIFEuZ2V0VGltZXpvbmUoKSAhPSBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQKLSAgICAgICAgICAgIC8vIFAgaGFzIG5vIHRpbWV6b25lIGFuZCBRIGRvZXMuCi0gICAgICAgICAgICBpZiAoUS5nZXRUaW1lem9uZSgpICE9IDApIHsKLSAgICAgICAgICAgICAgICBRID0gKFhNTEdyZWdvcmlhbkNhbGVuZGFySW1wbCkgUS5ub3JtYWxpemVUb1RpbWV6b25lKFEuZ2V0VGltZXpvbmUoKSk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIEQuIHN0ZXAgMQotICAgICAgICAgICAgWE1MR3JlZ29yaWFuQ2FsZW5kYXIgTWF4UCA9IFAubm9ybWFsaXplVG9UaW1lem9uZShEYXRhdHlwZUNvbnN0YW50cy5NQVhfVElNRVpPTkVfT0ZGU0VUKTsKLSAgICAgICAgICAgIHJlc3VsdCA9IGludGVybmFsQ29tcGFyZShNYXhQLCBRKTsKLSAgICAgICAgICAgIGlmIChyZXN1bHQgPT0gRGF0YXR5cGVDb25zdGFudHMuTEVTU0VSKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gRC4gc3RlcCAyCi0gICAgICAgICAgICBYTUxHcmVnb3JpYW5DYWxlbmRhciBNaW5QID0gUC5ub3JtYWxpemVUb1RpbWV6b25lKERhdGF0eXBlQ29uc3RhbnRzLk1JTl9USU1FWk9ORV9PRkZTRVQpOwotICAgICAgICAgICAgcmVzdWx0ID0gaW50ZXJuYWxDb21wYXJlKE1pblAsIFEpOwotICAgICAgICAgICAgaWYgKHJlc3VsdCA9PSBEYXRhdHlwZUNvbnN0YW50cy5HUkVBVEVSKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgLy8gRC4gc3RlcCAzCi0gICAgICAgICAgICAgICAgcmV0dXJuIERhdGF0eXBlQ29uc3RhbnRzLklOREVURVJNSU5BVEU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5Ob3JtYWxpemUgdGhpcyBpbnN0YW5jZSB0byBVVEMuPC9wPgotICAgICAqCi0gICAgICogPHA+MjAwMC0wMy0wNFQyMzowMDowMCswMzowMCBub3JtYWxpemVzIHRvIDIwMDAtMDMtMDRUMjA6MDA6MDBaPC9wPgotICAgICAqIDxwPkltcGxlbWVudHMgVzNDIFhNTCBTY2hlbWEgUGFydCAyLCBTZWN0aW9uIDMuMi43LjMgKEEpLjwvcD4KLSAgICAgKi8KLSAgICBwdWJsaWMgWE1MR3JlZ29yaWFuQ2FsZW5kYXIgbm9ybWFsaXplKCkgewotCi0gICAgICAgIFhNTEdyZWdvcmlhbkNhbGVuZGFyIG5vcm1hbGl6ZWQgPSBub3JtYWxpemVUb1RpbWV6b25lKHRpbWV6b25lKTsKLQotICAgICAgICAvLyBpZiB0aW1lem9uZSB3YXMgdW5kZWZpbmVkLCBsZWF2ZSBpdCB1bmRlZmluZWQKLSAgICAgICAgaWYgKGdldFRpbWV6b25lKCkgPT0gRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVEKSB7Ci0gICAgICAgICAgICBub3JtYWxpemVkLnNldFRpbWV6b25lKERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBpZiBtaWxsaXNlY29uZHMgd2FzIHVuZGVmaW5lZCwgbGVhdmUgaXQgdW5kZWZpbmVkCi0gICAgICAgIGlmIChnZXRNaWxsaXNlY29uZCgpID09IERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCkgewotICAgICAgICAgICAgbm9ybWFsaXplZC5zZXRNaWxsaXNlY29uZChEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQpOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIG5vcm1hbGl6ZWQ7Ci0gICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiA8cD5Ob3JtYWxpemUgdGhpcyBpbnN0YW5jZSB0byBVVEMuPC9wPgotICAgICAgICAgKgotICAgICAgICAgKiA8cD4yMDAwLTAzLTA0VDIzOjAwOjAwKzAzOjAwIG5vcm1hbGl6ZXMgdG8gMjAwMC0wMy0wNFQyMDowMDowMFo8L3A+Ci0gICAgICAgICAqIDxwPkltcGxlbWVudHMgVzNDIFhNTCBTY2hlbWEgUGFydCAyLCBTZWN0aW9uIDMuMi43LjMgKEEpLjwvcD4KLSAgICAgICAgICovCi0gICAgcHJpdmF0ZSBYTUxHcmVnb3JpYW5DYWxlbmRhciBub3JtYWxpemVUb1RpbWV6b25lKGludCB0aW1lem9uZSkgewotCi0gICAgICAgIGludCBtaW51dGVzID0gdGltZXpvbmU7Ci0gICAgICAgIFhNTEdyZWdvcmlhbkNhbGVuZGFyIHJlc3VsdCA9IChYTUxHcmVnb3JpYW5DYWxlbmRhcikgdGhpcy5jbG9uZSgpOwotCi0gICAgICAgIC8vIG5vcm1hbGl6aW5nIHRvIFVUQyB0aW1lIG5lZ2F0ZXMgdGhlIHRpbWV6b25lIG9mZnNldCBiZWZvcmUKLSAgICAgICAgLy8gYWRkaXRpb24uCi0gICAgICAgIG1pbnV0ZXMgPSAtbWludXRlczsKLSAgICAgICAgRHVyYXRpb24gZCA9IG5ldyBEdXJhdGlvbkltcGwobWludXRlcyA+PSAwLCAvLyBpc1Bvc2l0aXZlCi0gICAgICAgICAgICAgICAgMCwgLy95ZWFycwotICAgICAgICAgICAgICAgIDAsIC8vbW9udGhzCi0gICAgICAgICAgICAgICAgMCwgLy9kYXlzCi0gICAgICAgICAgICAgICAgMCwgLy9ob3VycwotICAgICAgICAgICAgICAgIG1pbnV0ZXMgPCAwID8gLW1pbnV0ZXMgOiBtaW51dGVzLCAvLyBhYnNvbHV0ZQotICAgICAgICAgICAgICAgIDAgIC8vc2Vjb25kcwotICAgICAgICApOwotICAgICAgICByZXN1bHQuYWRkKGQpOwotCi0gICAgICAgIC8vIHNldCB0byB6dWx1IFVUQyB0aW1lLgotICAgICAgICByZXN1bHQuc2V0VGltZXpvbmUoMCk7Ci0gICAgICAgIHJldHVybiByZXN1bHQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICoKLSAgICAgKiAgPHA+SW1wbGVtZW50cyBTdGVwIEIgZnJvbSBodHRwOi8vd3d3LnczLm9yZy9UUi94bWxzY2hlbWEtMi8jZGF0ZVRpbWUtb3JkZXIgPC9wPgotICAgICAqIEBwYXJhbSBQIGNhbGVuZGFyIGluc3RhbmNlIHdpdGggbm9ybWFsaXplZCB0aW1lem9uZSBvZmZzZXQgb3IKLSAgICAgKiAgICAgICAgICBoYXZpbmcgc2FtZSB0aW1lem9uZSBhcyBRCi0gICAgICogQHBhcmFtIFEgY2FsZW5kYXIgaW5zdGFuY2Ugd2l0aCBub3JtYWxpemVkIHRpbWV6b25lIG9mZnNldCBvcgotICAgICAqICAgICAgICAgIGhhdmluZyBzYW1lIHRpbWV6b25lIGFzIFAKLSAgICAgKgotICAgICAqIEByZXR1cm4gcmVzdWx0IG9mIGNvbXBhcmluZyBQIGFuZCBRLCB2YWx1ZSBvZgotICAgICAqICAge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0VRVUFMfSwKLSAgICAgKiAgIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNMRVNTRVJ9LAotICAgICAqICAge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0dSRUFURVJ9IG9yCi0gICAgICogICB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjSU5ERVRFUk1JTkFURX0uCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgaW50IGludGVybmFsQ29tcGFyZShYTUxHcmVnb3JpYW5DYWxlbmRhciBQLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MR3JlZ29yaWFuQ2FsZW5kYXIgUSkgewotCi0gICAgICAgIGludCByZXN1bHQ7Ci0KLSAgICAgICAgLy8gY29tcGFyZSBZZWFyLgotICAgICAgICBpZiAoUC5nZXRFb24oKSA9PSBRLmdldEVvbigpKSB7Ci0KLSAgICAgICAgICAgIC8vIEVvbiBmaWVsZCBpcyBvbmx5IGVxdWFsIHdoZW4gbnVsbC4KLSAgICAgICAgICAgIC8vIG9wdGltaXplZCBjYXNlIGZvciBjb21wYXJpbmcgeWVhciBub3QgcmVxdWlyaW5nIGVvbiBmaWVsZC4KLSAgICAgICAgICAgIHJlc3VsdCA9IGNvbXBhcmVGaWVsZChQLmdldFllYXIoKSwgUS5nZXRZZWFyKCkpOwotICAgICAgICAgICAgaWYgKHJlc3VsdCAhPSBEYXRhdHlwZUNvbnN0YW50cy5FUVVBTCkgewotICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICByZXN1bHQgPSBjb21wYXJlRmllbGQoUC5nZXRFb25BbmRZZWFyKCksIFEuZ2V0RW9uQW5kWWVhcigpKTsKLSAgICAgICAgICAgIGlmIChyZXN1bHQgIT0gRGF0YXR5cGVDb25zdGFudHMuRVFVQUwpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0OwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgcmVzdWx0ID0gY29tcGFyZUZpZWxkKFAuZ2V0TW9udGgoKSwgUS5nZXRNb250aCgpKTsKLSAgICAgICAgaWYgKHJlc3VsdCAhPSBEYXRhdHlwZUNvbnN0YW50cy5FUVVBTCkgewotICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKLSAgICAgICAgfQotCi0gICAgICAgIHJlc3VsdCA9IGNvbXBhcmVGaWVsZChQLmdldERheSgpLCBRLmdldERheSgpKTsKLSAgICAgICAgaWYgKHJlc3VsdCAhPSBEYXRhdHlwZUNvbnN0YW50cy5FUVVBTCkgewotICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKLSAgICAgICAgfQotCi0gICAgICAgIHJlc3VsdCA9IGNvbXBhcmVGaWVsZChQLmdldEhvdXIoKSwgUS5nZXRIb3VyKCkpOwotICAgICAgICBpZiAocmVzdWx0ICE9IERhdGF0eXBlQ29uc3RhbnRzLkVRVUFMKSB7Ci0gICAgICAgICAgICByZXR1cm4gcmVzdWx0OwotICAgICAgICB9Ci0KLSAgICAgICAgcmVzdWx0ID0gY29tcGFyZUZpZWxkKFAuZ2V0TWludXRlKCksIFEuZ2V0TWludXRlKCkpOwotICAgICAgICBpZiAocmVzdWx0ICE9IERhdGF0eXBlQ29uc3RhbnRzLkVRVUFMKSB7Ci0gICAgICAgICAgICByZXR1cm4gcmVzdWx0OwotICAgICAgICB9Ci0gICAgICAgIHJlc3VsdCA9IGNvbXBhcmVGaWVsZChQLmdldFNlY29uZCgpLCBRLmdldFNlY29uZCgpKTsKLSAgICAgICAgaWYgKHJlc3VsdCAhPSBEYXRhdHlwZUNvbnN0YW50cy5FUVVBTCkgewotICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKLSAgICAgICAgfQotCi0gICAgICAgIHJlc3VsdCA9IGNvbXBhcmVGaWVsZChQLmdldEZyYWN0aW9uYWxTZWNvbmQoKSwgUS5nZXRGcmFjdGlvbmFsU2Vjb25kKCkpOwotICAgICAgICByZXR1cm4gcmVzdWx0OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPkltcGxlbWVudCBTdGVwIEIgZnJvbQotICAgICAqIGh0dHA6Ly93d3cudzMub3JnL1RSL3htbHNjaGVtYS0yLyNkYXRlVGltZS1vcmRlci48L3A+Ci0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgaW50IGNvbXBhcmVGaWVsZChpbnQgUGZpZWxkLCBpbnQgUWZpZWxkKSB7Ci0gICAgICAgIGlmIChQZmllbGQgPT0gUWZpZWxkKSB7Ci0KLSAgICAgICAgICAgIC8vZmllbGRzIGFyZSBlaXRoZXIgZXF1YWwgaW4gdmFsdWUgb3IgYm90aCB1bmRlZmluZWQuCi0gICAgICAgICAgICAvLyBTdGVwIEIuIDEuMSBBTkQgb3B0aW1pemVkIHJlc3VsdCBvZiBwZXJmb3JtaW5nIDEuMS0xLjQuCi0gICAgICAgICAgICByZXR1cm4gRGF0YXR5cGVDb25zdGFudHMuRVFVQUw7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBpZiAoUGZpZWxkID09IERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCB8fCBRZmllbGQgPT0gRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVEKSB7Ci0gICAgICAgICAgICAgICAgLy8gU3RlcCBCLiAxLjIKLSAgICAgICAgICAgICAgICByZXR1cm4gRGF0YXR5cGVDb25zdGFudHMuSU5ERVRFUk1JTkFURTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgLy8gU3RlcCBCLiAxLjMtNC4KLSAgICAgICAgICAgICAgICByZXR1cm4gKFBmaWVsZCA8IFFmaWVsZCA/IERhdGF0eXBlQ29uc3RhbnRzLkxFU1NFUiA6IERhdGF0eXBlQ29uc3RhbnRzLkdSRUFURVIpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBzdGF0aWMgaW50IGNvbXBhcmVGaWVsZChCaWdJbnRlZ2VyIFBmaWVsZCwgQmlnSW50ZWdlciBRZmllbGQpIHsKLSAgICAgICAgaWYgKFBmaWVsZCA9PSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gKFFmaWVsZCA9PSBudWxsID8gRGF0YXR5cGVDb25zdGFudHMuRVFVQUwgOiBEYXRhdHlwZUNvbnN0YW50cy5JTkRFVEVSTUlOQVRFKTsKLSAgICAgICAgfQotICAgICAgICBpZiAoUWZpZWxkID09IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBEYXRhdHlwZUNvbnN0YW50cy5JTkRFVEVSTUlOQVRFOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBQZmllbGQuY29tcGFyZVRvKFFmaWVsZCk7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBzdGF0aWMgaW50IGNvbXBhcmVGaWVsZChCaWdEZWNpbWFsIFBmaWVsZCwgQmlnRGVjaW1hbCBRZmllbGQpIHsKLSAgICAgICAgLy8gb3B0aW1pemF0aW9uLiBlc3BlY2lhbGx5IHdoZW4gYm90aCBhcmd1bWVudHMgYXJlIG51bGwuCi0gICAgICAgIGlmIChQZmllbGQgPT0gUWZpZWxkKSB7Ci0gICAgICAgICAgICByZXR1cm4gRGF0YXR5cGVDb25zdGFudHMuRVFVQUw7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoUGZpZWxkID09IG51bGwpIHsKLSAgICAgICAgICAgIFBmaWVsZCA9IERFQ0lNQUxfWkVSTzsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChRZmllbGQgPT0gbnVsbCkgewotICAgICAgICAgICAgUWZpZWxkID0gREVDSU1BTF9aRVJPOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIFBmaWVsZC5jb21wYXJlVG8oUWZpZWxkKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5JbmRpY2F0ZXMgd2hldGhlciBwYXJhbWV0ZXIgPGNvZGU+b2JqPC9jb2RlPiBpcyAiZXF1YWwgdG8iIHRoaXMgb25lLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBvYmogdG8gY29tcGFyZS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gPGNvZGU+dHJ1ZTwvY29kZT4gd2hlbiA8Y29kZT5jb21wYXJlKHRoaXMsKFhNTEdyZWdvcmlhbkNhbGVuZGFyKW9iaikgPT0gRVFVQUwuPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaikgewotCi0gICAgICAgIGlmIChvYmogPT0gbnVsbCB8fCAhKG9iaiBpbnN0YW5jZW9mIFhNTEdyZWdvcmlhbkNhbGVuZGFyKSkgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBjb21wYXJlKChYTUxHcmVnb3JpYW5DYWxlbmRhcikgb2JqKSA9PSBEYXRhdHlwZUNvbnN0YW50cy5FUVVBTDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5SZXR1cm5zIGEgaGFzaCBjb2RlIGNvbnNpc3RlbnQgd2l0aCB0aGUgZGVmaW5pdGlvbiBvZiB0aGUgZXF1YWxzIG1ldGhvZC48L3A+Ci0gICAgICoKLSAgICAgKiBAcmV0dXJuIGhhc2ggY29kZSBvZiB0aGlzIG9iamVjdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewotCi0gICAgICAgIC8vIEZvbGxvd2luZyB0d28gZGF0ZXMgY29tcGFyZSB0byBFUVVBTFMgc2luY2UgaW4gZGlmZmVyZW50IHRpbWV6b25lcy4KLSAgICAgICAgLy8gMjAwMC0wMS0xNVQxMjowMDowMC0wNTowMCA9PSAyMDAwLTAxLTE1VDEzOjAwOjAwLTA0OjAwCi0gICAgICAgIC8vCi0gICAgICAgIC8vIE11c3QgZW5zdXJlIGJvdGggaW5zdGFuY2VzIGdlbmVyYXRlIHNhbWUgaGFzaGNvZGUgYnkgbm9ybWFsaXppbmcKLSAgICAgICAgLy8gdGhpcyB0byBVVEMgdGltZXpvbmUuCi0gICAgICAgIGludCB0aW1lem9uZSA9IGdldFRpbWV6b25lKCk7Ci0gICAgICAgIGlmICh0aW1lem9uZSA9PSBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQpIHsKLSAgICAgICAgICAgIHRpbWV6b25lID0gMDsKLSAgICAgICAgfQotICAgICAgICBYTUxHcmVnb3JpYW5DYWxlbmRhciBnYyA9IHRoaXM7Ci0gICAgICAgIGlmICh0aW1lem9uZSAhPSAwKSB7Ci0gICAgICAgICAgICBnYyA9IHRoaXMubm9ybWFsaXplVG9UaW1lem9uZShnZXRUaW1lem9uZSgpKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZ2MuZ2V0WWVhcigpICsgZ2MuZ2V0TW9udGgoKSArIGdjLmdldERheSgpICsKLSAgICAgICAgICAgICAgICBnYy5nZXRIb3VyKCkgKyBnYy5nZXRNaW51dGUoKSArIGdjLmdldFNlY29uZCgpOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogPHA+Q29uc3RydWN0cyBhIG5ldyBYTUxHcmVnb3JpYW5DYWxlbmRhciBvYmplY3QgYnkKLSAgICAgKiBwYXJzaW5nIGl0cyBsZXhpY2FsIHN0cmluZyByZXByZXNlbnRhdGlvbiBhcyBkZWZpbmVkIGluCi0gICAgICogPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveG1sc2NoZW1hLTIvI2RhdGVUaW1lLW9yZGVyIj5YTUwgU2NoZW1hIDEuMCBQYXJ0IDIsIFNlY3Rpb24gMy4yLls3LTE0XS4xLAotICAgICAqIDxpPkxleGljYWwgUmVwcmVzZW50YXRpb248L2k+LjwvYT48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5UaGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG1heSBub3QgaGF2ZSBhbnkgbGVhZGluZyBhbmQgdHJhaWxpbmcgd2hpdGVzcGFjZXMuPC9wPgotICAgICAqCi0gICAgICogPHA+VGhlIHBhcnNpbmcgaXMgZG9uZSBmaWVsZCBieSBmaWVsZCBzbyB0aGF0Ci0gICAgICogdGhlIGZvbGxvd2luZyBob2xkcyBmb3IgYW55IGxleGljYWxseSBjb3JyZWN0IHN0cmluZyB4OjwvcD4KLSAgICAgKiA8cHJlPgotICAgICAqIG5ldyBYTUxHcmVnb3JpYW5DYWxlbmRhcih4KS50b1hNTEZvcm1hdCgpLmVxdWFscyh4KQotICAgICAqIDwvcHJlPgotICAgICAqIEV4Y2VwdCBmb3IgdGhlIG5vdGVkIGxleGljYWwvY2Fub25pY2FsIHJlcHJlc2VudGF0aW9uIG1pc21hdGNoZXMKLSAgICAgKiBsaXN0ZWQgaW4gPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8wNS94bWxzY2hlbWEtZXJyYXRhI2UyLTQ1Ij4KLSAgICAgKiBYTUwgU2NoZW1hIDEuMCBlcnJhdGEsIFNlY3Rpb24gMy4yLjcuMjwvYT4uCi0gICAgICoKLSAgICAgKiA8cD5SZXR1cm5zIGEgbm9uLW51bGwgdmFsaWQgWE1MR3JlZ29yaWFuQ2FsZW5kYXIgb2JqZWN0IHRoYXQgaG9sZHMgdGhlIHZhbHVlCi0gICAgICogaW5kaWNhdGVkIGJ5IHRoZSBsZXhpY2FsUmVwcmVzZW50YXRpb24gcGFyYW1ldGVyLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBsZXhpY2FsUmVwcmVzZW50YXRpb24gTGV4aWNhbCByZXByZXNlbnRhdGlvbiBvZiBvbmUgdGhlIDggWE1MIFNjaGVtYSBjYWxlbmRhciBkYXRhdHlwZXMuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiBjcmVhdGVkIGZyb20gcGFyc2luZyA8Y29kZT5sZXhpY2FsUmVwcmVzZW50YXRpb248L2NvZGU+IHBhcmFtZXRlci4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCi0gICAgICogICAgICBJZiB0aGUgZ2l2ZW4gc3RyaW5nIGRvZXMgbm90IGNvbmZvcm0gdG8gdGhlIGFmb3JlbWVudGlvbmVkCi0gICAgICogICAgICBzcGVjaWZpY2F0aW9uLgotICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KLSAgICAgKiAgICAgIElmIHRoZSBnaXZlbiBzdHJpbmcgaXMgbnVsbC4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFhNTEdyZWdvcmlhbkNhbGVuZGFyIHBhcnNlKFN0cmluZyBsZXhpY2FsUmVwcmVzZW50YXRpb24pIHsKLQotICAgICAgICAgICAgICAgIHJldHVybiBuZXcgWE1MR3JlZ29yaWFuQ2FsZW5kYXJJbXBsKGxleGljYWxSZXByZXNlbnRhdGlvbik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+UmV0dXJuIHRoZSBsZXhpY2FsIHJlcHJlc2VudGF0aW9uIG9mIDxjb2RlPnRoaXM8L2NvZGU+IGluc3RhbmNlLgotICAgICAqIFRoZSBmb3JtYXQgaXMgc3BlY2lmaWVkIGluCi0gICAgICogPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveG1sc2NoZW1hLTIvI2RhdGVUaW1lLW9yZGVyIj5YTUwgU2NoZW1hIDEuMCBQYXJ0IDIsIFNlY3Rpb24gMy4yLls3LTE0XS4xLAotICAgICAqIDxpPkxleGljYWwgUmVwcmVzZW50YXRpb248L2k+Ii48L2E+PC9wPgotICAgICAqCi0gICAgICogPHA+U3BlY2lmaWMgdGFyZ2V0IGxleGljYWwgcmVwcmVzZW50YXRpb24gZm9ybWF0IGlzIGRldGVybWluZWQgYnkKLSAgICAgKiB7QGxpbmsgI2dldFhNTFNjaGVtYVR5cGUoKX0uPC9wPgotICAgICAqCi0gICAgICogQHJldHVybiBYTUwsIGFzIDxjb2RlPlN0cmluZzwvY29kZT4sIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+Ci0gICAgICoKLSAgICAgKiBAdGhyb3dzIGphdmEubGFuZy5JbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhlIGNvbWJpbmF0aW9uIG9mIHNldCBmaWVsZHMKLSAgICAgKiAgICBkb2VzIG5vdCBtYXRjaCBvbmUgb2YgdGhlIGVpZ2h0IGRlZmluZWQgWE1MIFNjaGVtYSBidWlsdGluIGRhdGUvdGltZSBkYXRhdHlwZXMuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyB0b1hNTEZvcm1hdCgpIHsKLQotICAgICAgICBRTmFtZSB0eXBla2luZCA9IGdldFhNTFNjaGVtYVR5cGUoKTsKLQotICAgICAgICBTdHJpbmcgZm9ybWF0U3RyaW5nID0gbnVsbDsKLSAgICAgICAgLy8gRml4IDQ5NzE2MTI6IGludmFsaWQgU0NDUyBtYWNybyBzdWJzdGl0dXRpb24gaW4gZGF0YSBzdHJpbmcKLSAgICAgICAgLy8gICBubyAle2FscGhhfSUgdG8gYXZvaWQgU0NDUyBtYWNybyBzdWJzdGl0dXRpb24KLSAgICAgICAgaWYgKHR5cGVraW5kID09IERhdGF0eXBlQ29uc3RhbnRzLkRBVEVUSU1FKSB7Ci0gICAgICAgICAgICBmb3JtYXRTdHJpbmcgPSAiJVktJU0tJURUJWg6JW06JXMiICsgIiV6IjsKLSAgICAgICAgfSBlbHNlIGlmICh0eXBla2luZCA9PSBEYXRhdHlwZUNvbnN0YW50cy5EQVRFKSB7Ci0gICAgICAgICAgICBmb3JtYXRTdHJpbmcgPSAiJVktJU0tJUQiICsgIiV6IjsKLSAgICAgICAgfSBlbHNlIGlmICh0eXBla2luZCA9PSBEYXRhdHlwZUNvbnN0YW50cy5USU1FKSB7Ci0gICAgICAgICAgICBmb3JtYXRTdHJpbmcgPSAiJWg6JW06JXMiICsgIiV6IjsKLSAgICAgICAgfSBlbHNlIGlmICh0eXBla2luZCA9PSBEYXRhdHlwZUNvbnN0YW50cy5HTU9OVEgpIHsKLSAgICAgICAgICAgIGZvcm1hdFN0cmluZyA9ICItLSVNIiArICIleiI7Ci0gICAgICAgIH0gZWxzZSBpZiAodHlwZWtpbmQgPT0gRGF0YXR5cGVDb25zdGFudHMuR0RBWSkgewotICAgICAgICAgICAgZm9ybWF0U3RyaW5nID0gIi0tLSVEIiArICIleiI7Ci0gICAgICAgIH0gZWxzZSBpZiAodHlwZWtpbmQgPT0gRGF0YXR5cGVDb25zdGFudHMuR1lFQVIpIHsKLSAgICAgICAgICAgIGZvcm1hdFN0cmluZyA9ICIlWSIgKyAiJXoiOwotICAgICAgICB9IGVsc2UgaWYgKHR5cGVraW5kID09IERhdGF0eXBlQ29uc3RhbnRzLkdZRUFSTU9OVEgpIHsKLSAgICAgICAgICAgIGZvcm1hdFN0cmluZyA9ICIlWS0lTSIgKyAiJXoiOwotICAgICAgICB9IGVsc2UgaWYgKHR5cGVraW5kID09IERhdGF0eXBlQ29uc3RhbnRzLkdNT05USERBWSkgewotICAgICAgICAgICAgZm9ybWF0U3RyaW5nID0gIi0tJU0tJUQiICsgIiV6IjsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZm9ybWF0KGZvcm1hdFN0cmluZyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+UmV0dXJuIHRoZSBuYW1lIG9mIHRoZSBYTUwgU2NoZW1hIGRhdGUvdGltZSB0eXBlIHRoYXQgdGhpcyBpbnN0YW5jZQotICAgICAqIG1hcHMgdG8uIFR5cGUgaXMgY29tcHV0ZWQgYmFzZWQgb24gZmllbGRzIHRoYXQgYXJlIHNldC48L3A+Ci0gICAgICoKLSAgICAgKiA8dGFibGUgYm9yZGVyPSIyIiBydWxlcz0iYWxsIiBjZWxscGFkZGluZz0iMiI+Ci0gICAgICogICA8dGhlYWQ+Ci0gICAgICogICAgIDx0cj4KLSAgICAgKiAgICAgICA8dGggYWxpZ249ImNlbnRlciIgY29sc3Bhbj0iNyI+Ci0gICAgICogICAgICAgICBSZXF1aXJlZCBmaWVsZHMgZm9yIFhNTCBTY2hlbWEgMS4wIERhdGUvVGltZSBEYXRhdHlwZXMuPGJyLz4KLSAgICAgKiAgICAgICAgIDxpPih0aW1lem9uZSBpcyBvcHRpb25hbCBmb3IgYWxsIGRhdGUvdGltZSBkYXRhdHlwZXMpPC9pPgotICAgICAqICAgICAgIDwvdGg+Ci0gICAgICogICAgIDwvdHI+Ci0gICAgICogICA8L3RoZWFkPgotICAgICAqICAgPHRib2R5PgotICAgICAqICAgICA8dHI+Ci0gICAgICogICAgICAgPHRkPkRhdGF0eXBlPC90ZD4KLSAgICAgKiAgICAgICA8dGQ+eWVhcjwvdGQ+Ci0gICAgICogICAgICAgPHRkPm1vbnRoPC90ZD4KLSAgICAgKiAgICAgICA8dGQ+ZGF5PC90ZD4KLSAgICAgKiAgICAgICA8dGQ+aG91cjwvdGQ+Ci0gICAgICogICAgICAgPHRkPm1pbnV0ZTwvdGQ+Ci0gICAgICogICAgICAgPHRkPnNlY29uZDwvdGQ+Ci0gICAgICogICAgIDwvdHI+Ci0gICAgICogICAgIDx0cj4KLSAgICAgKiAgICAgICA8dGQ+e0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0RBVEVUSU1FfTwvdGQ+Ci0gICAgICogICAgICAgPHRkPlg8L3RkPgotICAgICAqICAgICAgIDx0ZD5YPC90ZD4KLSAgICAgKiAgICAgICA8dGQ+WDwvdGQ+Ci0gICAgICogICAgICAgPHRkPlg8L3RkPgotICAgICAqICAgICAgIDx0ZD5YPC90ZD4KLSAgICAgKiAgICAgICA8dGQ+WDwvdGQ+Ci0gICAgICogICAgIDwvdHI+Ci0gICAgICogICAgIDx0cj4KLSAgICAgKiAgICAgICA8dGQ+e0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0RBVEV9PC90ZD4KLSAgICAgKiAgICAgICA8dGQ+WDwvdGQ+Ci0gICAgICogICAgICAgPHRkPlg8L3RkPgotICAgICAqICAgICAgIDx0ZD5YPC90ZD4KLSAgICAgKiAgICAgICA8dGQ+PC90ZD4KLSAgICAgKiAgICAgICA8dGQ+PC90ZD4KLSAgICAgKiAgICAgICA8dGQ+PC90ZD4KLSAgICAgKiAgICAgPC90cj4KLSAgICAgKiAgICAgPHRyPgotICAgICAqICAgICAgIDx0ZD57QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjVElNRX08L3RkPgotICAgICAqICAgICAgIDx0ZD48L3RkPgotICAgICAqICAgICAgIDx0ZD48L3RkPgotICAgICAqICAgICAgIDx0ZD48L3RkPgotICAgICAqICAgICAgIDx0ZD5YPC90ZD4KLSAgICAgKiAgICAgICA8dGQ+WDwvdGQ+Ci0gICAgICogICAgICAgPHRkPlg8L3RkPgotICAgICAqICAgICA8L3RyPgotICAgICAqICAgICA8dHI+Ci0gICAgICogICAgICAgPHRkPntAbGluayBEYXRhdHlwZUNvbnN0YW50cyNHWUVBUk1PTlRIfTwvdGQ+Ci0gICAgICogICAgICAgPHRkPlg8L3RkPgotICAgICAqICAgICAgIDx0ZD5YPC90ZD4KLSAgICAgKiAgICAgICA8dGQ+PC90ZD4KLSAgICAgKiAgICAgICA8dGQ+PC90ZD4KLSAgICAgKiAgICAgICA8dGQ+PC90ZD4KLSAgICAgKiAgICAgICA8dGQ+PC90ZD4KLSAgICAgKiAgICAgPC90cj4KLSAgICAgKiAgICAgPHRyPgotICAgICAqICAgICAgIDx0ZD57QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjR01PTlRIREFZfTwvdGQ+Ci0gICAgICogICAgICAgPHRkPjwvdGQ+Ci0gICAgICogICAgICAgPHRkPlg8L3RkPgotICAgICAqICAgICAgIDx0ZD5YPC90ZD4KLSAgICAgKiAgICAgICA8dGQ+PC90ZD4KLSAgICAgKiAgICAgICA8dGQ+PC90ZD4KLSAgICAgKiAgICAgICA8dGQ+PC90ZD4KLSAgICAgKiAgICAgPC90cj4KLSAgICAgKiAgICAgPHRyPgotICAgICAqICAgICAgIDx0ZD57QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjR1lFQVJ9PC90ZD4KLSAgICAgKiAgICAgICA8dGQ+WDwvdGQ+Ci0gICAgICogICAgICAgPHRkPjwvdGQ+Ci0gICAgICogICAgICAgPHRkPjwvdGQ+Ci0gICAgICogICAgICAgPHRkPjwvdGQ+Ci0gICAgICogICAgICAgPHRkPjwvdGQ+Ci0gICAgICogICAgICAgPHRkPjwvdGQ+Ci0gICAgICogICAgIDwvdHI+Ci0gICAgICogICAgIDx0cj4KLSAgICAgKiAgICAgICA8dGQ+e0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0dNT05USH08L3RkPgotICAgICAqICAgICAgIDx0ZD48L3RkPgotICAgICAqICAgICAgIDx0ZD5YPC90ZD4KLSAgICAgKiAgICAgICA8dGQ+PC90ZD4KLSAgICAgKiAgICAgICA8dGQ+PC90ZD4KLSAgICAgKiAgICAgICA8dGQ+PC90ZD4KLSAgICAgKiAgICAgICA8dGQ+PC90ZD4KLSAgICAgKiAgICAgPC90cj4KLSAgICAgKiAgICAgPHRyPgotICAgICAqICAgICAgIDx0ZD57QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjR0RBWX08L3RkPgotICAgICAqICAgICAgIDx0ZD48L3RkPgotICAgICAqICAgICAgIDx0ZD48L3RkPgotICAgICAqICAgICAgIDx0ZD5YPC90ZD4KLSAgICAgKiAgICAgICA8dGQ+PC90ZD4KLSAgICAgKiAgICAgICA8dGQ+PC90ZD4KLSAgICAgKiAgICAgICA8dGQ+PC90ZD4KLSAgICAgKiAgICAgPC90cj4KLSAgICAgKiAgIDwvdGJvZHk+Ci0gICAgICogPC90YWJsZT4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgamF2YS5sYW5nLklsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGUgY29tYmluYXRpb24gb2Ygc2V0IGZpZWxkcwotICAgICAqICAgIGRvZXMgbm90IG1hdGNoIG9uZSBvZiB0aGUgZWlnaHQgZGVmaW5lZCBYTUwgU2NoZW1hIGJ1aWx0aW4KLSAgICAgKiAgICBkYXRlL3RpbWUgZGF0YXR5cGVzLgotICAgICAqIEByZXR1cm4gT25lIG9mIHRoZSBmb2xsb3dpbmcgY2xhc3MgY29uc3RhbnRzOgotICAgICAqICAge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0RBVEVUSU1FfSwKLSAgICAgKiAgIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNUSU1FfSwKLSAgICAgKiAgIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNEQVRFfSwKLSAgICAgKiAgIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNHWUVBUk1PTlRIfSwKLSAgICAgKiAgIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNHTU9OVEhEQVl9LAotICAgICAqICAge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0dZRUFSfSwKLSAgICAgKiAgIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNHTU9OVEh9IG9yCi0gICAgICogICB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjR0RBWX0uCi0gICAgICovCi0gICAgcHVibGljIFFOYW1lIGdldFhNTFNjaGVtYVR5cGUoKSB7Ci0KLSAgICAgICAgaW50IG1hc2sgPQotICAgICAgICAgICAgKHllYXIgIT0gRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVEID8gICAweDIwIDogMCApfAotICAgICAgICAgICAgKG1vbnRoICE9IERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCA/ICAweDEwIDogMCApfAotICAgICAgICAgICAgKGRheSAhPSBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQgPyAgICAweDA4IDogMCApfAotICAgICAgICAgICAgKGhvdXIgIT0gRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVEID8gICAweDA0IDogMCApfAotICAgICAgICAgICAgKG1pbnV0ZSAhPSBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQgPyAweDAyIDogMCApfAotICAgICAgICAgICAgKHNlY29uZCAhPSBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQgPyAweDAxIDogMCApOwotCi0gICAgICAgIHN3aXRjaChtYXNrKSB7Ci0gICAgICAgIGNhc2UgMHgzRjoKLSAgICAgICAgICAgICAgICByZXR1cm4gRGF0YXR5cGVDb25zdGFudHMuREFURVRJTUU7Ci0gICAgICAgIGNhc2UgMHgzODoKLSAgICAgICAgICAgICAgICByZXR1cm4gRGF0YXR5cGVDb25zdGFudHMuREFURTsKLSAgICAgICAgY2FzZSAweDA3OgotICAgICAgICAgICAgICAgIHJldHVybiBEYXRhdHlwZUNvbnN0YW50cy5USU1FOwotICAgICAgICBjYXNlIDB4MzA6Ci0gICAgICAgICAgICAgICAgcmV0dXJuIERhdGF0eXBlQ29uc3RhbnRzLkdZRUFSTU9OVEg7Ci0gICAgICAgIGNhc2UgMHgxODoKLSAgICAgICAgICAgICAgICByZXR1cm4gRGF0YXR5cGVDb25zdGFudHMuR01PTlRIREFZOwotICAgICAgICBjYXNlIDB4MjA6Ci0gICAgICAgICAgICAgICAgcmV0dXJuIERhdGF0eXBlQ29uc3RhbnRzLkdZRUFSOwotICAgICAgICBjYXNlIDB4MTA6Ci0gICAgICAgICAgICAgICAgcmV0dXJuIERhdGF0eXBlQ29uc3RhbnRzLkdNT05USDsKLSAgICAgICAgY2FzZSAweDA4OgotICAgICAgICAgICAgICAgIHJldHVybiBEYXRhdHlwZUNvbnN0YW50cy5HREFZOwotICAgICAgICBkZWZhdWx0OgotICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICB0aGlzLmdldENsYXNzKCkuZ2V0TmFtZSgpCi0gICAgICAgICAgICAgICAgKyAiI2dldFhNTFNjaGVtYVR5cGUoKSA6IgotICAgICAgICAgICAgICAgICsgRGF0YXR5cGVNZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UobnVsbCwgIkludmFsaWRYR0NGaWVsZHMiLCBudWxsKQotICAgICAgICAgICAgKTsKLSAgICAgICAgfQotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogVmFsaWRhdGUgaW5zdGFuY2UgYnkgPGNvZGU+Z2V0WE1MU2NoZW1hVHlwZSgpPC9jb2RlPiBjb25zdHJhaW50cy4KLSAgICAgKiBAcmV0dXJuIHRydWUgaWYgZGF0YSB2YWx1ZXMgYXJlIHZhbGlkLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzVmFsaWQoKSB7Ci0gICAgICAgIC8vIHNpbmNlIHNldHRlcnMgZG8gbm90IGFsbG93IGZvciBpbnZhbGlkIHZhbHVlcywKLSAgICAgICAgLy8gKGV4Y2VwdCBmb3IgZXhjZXB0aW9uYWwgY2FzZSBvZiB5ZWFyIGZpZWxkIG9mIHplcm8pLAotICAgICAgICAvLyBubyBuZWVkIHRvIGNoZWNrIGZvciBhbnl0aGluZyBleGNlcHQgZm9yIGNvbnN0cmFpbnRzCi0gICAgICAgIC8vIGJldHdlZW4gZmllbGRzLgotCi0gICAgICAgIC8vY2hlY2sgaWYgZGF5cyBpbiBtb250aCBpcyB2YWxpZC4gQ2FuIGJlIGRlcGVuZGVudCBvbiBsZWFwIHllYXIuCi0gICAgICAgIGlmIChnZXRNb250aCgpID09IERhdGF0eXBlQ29uc3RhbnRzLkZFQlJVQVJZKSB7Ci0gICAgICAgICAgICAvLyB5ZWFycyBjb3VsZCBub3QgYmUgc2V0Ci0gICAgICAgICAgICBpbnQgbWF4RGF5cyA9IDI5OwotCi0gICAgICAgICAgICBpZiAoZW9uID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBpZih5ZWFyIT1EYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQpCi0gICAgICAgICAgICAgICAgICAgIG1heERheXMgPSBtYXhpbXVtRGF5SW5Nb250aEZvcih5ZWFyLGdldE1vbnRoKCkpOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyIHllYXJzID0gZ2V0RW9uQW5kWWVhcigpOwotICAgICAgICAgICAgICAgIGlmICh5ZWFycyAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIG1heERheXMgPSBtYXhpbXVtRGF5SW5Nb250aEZvcihnZXRFb25BbmRZZWFyKCksIERhdGF0eXBlQ29uc3RhbnRzLkZFQlJVQVJZKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoZ2V0RGF5KCkgPiBtYXhEYXlzKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gaHR0cDovL3d3dy53My5vcmcvMjAwMS8wNS94bWxzY2hlbWEtZXJyYXRhI2UyLTQ1Ci0gICAgICAgIGlmIChnZXRIb3VyKCkgPT0gMjQpIHsKLSAgICAgICAgICAgIGlmKGdldE1pbnV0ZSgpICE9IDApIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICB9IGVsc2UgaWYgKGdldFNlY29uZCgpICE9IDApIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBYTUwgU2NoZW1hIDEuMCBzcGVjaWZpY2F0aW9uIGRlZmluZXMgeWVhciB2YWx1ZSBvZiB6ZXJvIGFzCi0gICAgICAgIC8vIGludmFsaWQuIEFsbG93IHRoaXMgY2xhc3MgdG8gc2V0IHllYXIgZmllbGQgdG8gemVybwotICAgICAgICAvLyBzaW5jZSBYTUwgU2NoZW1hIDEuMCBlcnJhdGEgc3RhdGVzIHRoYXQgbGV4aWNhbCB6ZXJvIHdpbGwKLSAgICAgICAgLy8gYmUgYWxsb3dlZCBpbiBuZXh0IHZlcnNpb24gYW5kIHRyZWF0ZWQgYXMgMSBCLkMuRS4KLSAgICAgICAgaWYgKGVvbiA9PSBudWxsKSB7Ci0gICAgICAgICAgICAvLyBvcHRpbWl6ZSBjaGVjay4KLSAgICAgICAgICAgIGlmICh5ZWFyID09IDApIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBCaWdJbnRlZ2VyIHllYXJGaWVsZCA9IGdldEVvbkFuZFllYXIoKTsKLSAgICAgICAgICAgIGlmICh5ZWFyRmllbGQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGludCByZXN1bHQgPSBjb21wYXJlRmllbGQoeWVhckZpZWxkLCBCaWdJbnRlZ2VyLlpFUk8pOwotICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgPT0gRGF0YXR5cGVDb25zdGFudHMuRVFVQUwpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5BZGQgPGNvZGU+ZHVyYXRpb248L2NvZGU+IHRvIHRoaXMgaW5zdGFuY2UuPFxwPgotICAgICAqCi0gICAgICogPHA+VGhlIGNvbXB1dGF0aW9uIGlzIHNwZWNpZmllZCBpbgotICAgICAqIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3htbHNjaGVtYS0yLyNhZGRpbmctZHVyYXRpb25zLXRvLWRhdGVUaW1lcyI+WE1MIFNjaGVtYSAxLjAgUGFydCAyLCBBcHBlbmRpeCBFLAotICAgICAqIDxpPkFkZGluZyBkdXJhdGlvbnMgdG8gZGF0ZVRpbWVzPC9pPj48L2E+LgotICAgICAqIDxhIGhyZWY9IiNkYXRldGltZWZpZWxkc21hcHBpbmciPmRhdGUvdGltZSBmaWVsZCBtYXBwaW5nIHRhYmxlPC9hPgotICAgICAqIGRlZmluZXMgdGhlIG1hcHBpbmcgZnJvbSBYTUwgU2NoZW1hIDEuMCA8Y29kZT5kYXRlVGltZTwvY29kZT4gZmllbGRzCi0gICAgICogdG8gdGhpcyBjbGFzcycgcmVwcmVzZW50YXRpb24gb2YgdGhvc2UgZmllbGRzLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBkdXJhdGlvbiBEdXJhdGlvbiB0byBhZGQgdG8gdGhpcyA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4uCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uICB3aGVuIDxjb2RlPmR1cmF0aW9uPC9jb2RlPiBwYXJhbWV0ZXIgaXMgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgYWRkKER1cmF0aW9uIGR1cmF0aW9uKSB7Ci0KLSAgICAgICAgLyoKLSAgICAgICAgICAgKiBFeHRyYWN0ZWQgZnJvbQotICAgICAgICAgICAqIGh0dHA6Ly93d3cudzMub3JnL1RSL3htbHNjaGVtYS0yLyNhZGRpbmctZHVyYXRpb25zLXRvLWRhdGVUaW1lcwotICAgICAgICAgICAqIHRvIGVuc3VyZSBpbXBsZW1lbnRlZCBwcm9wZXJseS4gU2VlIHNwZWMgZm9yIGRlZmluaXRpb25zIG9mIG1ldGhvZHMKLSAgICAgICAgICAgKiB1c2VkIGluIGFsZ29yaXRobS4KLSAgICAgICAgICAgKgotICAgICAgICAgICAqIEdpdmVuIGEgZGF0ZVRpbWUgUyBhbmQgYSBkdXJhdGlvbiBELCBzcGVjaWZpZXMgaG93IHRvIGNvbXB1dGUgYQotICAgICAgICAgICAqIGRhdGVUaW1lIEUgd2hlcmUgRSBpcyB0aGUgZW5kIG9mIHRoZSB0aW1lIHBlcmlvZCB3aXRoIHN0YXJ0IFMgYW5kCi0gICAgICAgICAgICogZHVyYXRpb24gRCBpLmUuIEUgPSBTICsgRC4KLSAgICAgICAgICAgKgotICAgICAgICAgICAqIFRoZSBmb2xsb3dpbmcgaXMgdGhlIHByZWNpc2Ugc3BlY2lmaWNhdGlvbi4KLSAgICAgICAgICAgKiBUaGVzZSBzdGVwcyBtdXN0IGJlIGZvbGxvd2VkIGluIHRoZSBzYW1lIG9yZGVyLgotICAgICAgICAgICAqIElmIGEgZmllbGQgaW4gRCBpcyBub3Qgc3BlY2lmaWVkLCBpdCBpcyB0cmVhdGVkIGFzIGlmIGl0IHdlcmUgemVyby4KLSAgICAgICAgICAgKiBJZiBhIGZpZWxkIGluIFMgaXMgbm90IHNwZWNpZmllZCwgaXQgaXMgdHJlYXRlZCBpbiB0aGUgY2FsY3VsYXRpb24KLSAgICAgICAgICAgKiBhcyBpZiBpdCB3ZXJlIHRoZSBtaW5pbXVtIGFsbG93ZWQgdmFsdWUgaW4gdGhhdCBmaWVsZCwgaG93ZXZlciwKLSAgICAgICAgICAgKiBhZnRlciB0aGUgY2FsY3VsYXRpb24gaXMgY29uY2x1ZGVkLCB0aGUgY29ycmVzcG9uZGluZyBmaWVsZCBpbgotICAgICAgICAgICAqIEUgaXMgcmVtb3ZlZCAoc2V0IHRvIHVuc3BlY2lmaWVkKS4KLSAgICAgICAgICAgKgotICAgICAgICAgICAqIE1vbnRocyAobWF5IGJlIG1vZGlmaWVkIGFkZGl0aW9uYWxseSBiZWxvdykKLSAgICAgICAgICAgICAgICogIHRlbXAgOj0gU1ttb250aF0gKyBEW21vbnRoXQotICAgICAgICAgICAgICAgKiAgRVttb250aF0gOj0gbW9kdWxvKHRlbXAsIDEsIDEzKQotICAgICAgICAgICAgICAgKiAgY2FycnkgOj0gZlF1b3RpZW50KHRlbXAsIDEsIDEzKQotICAgICAgICAgICAqLwotCi0gICAgICAgIGJvb2xlYW4gZmllbGRVbmRlZmluZWRbXSA9IHsKLSAgICAgICAgICAgICAgICBmYWxzZSwKLSAgICAgICAgICAgICAgICBmYWxzZSwKLSAgICAgICAgICAgICAgICBmYWxzZSwKLSAgICAgICAgICAgICAgICBmYWxzZSwKLSAgICAgICAgICAgICAgICBmYWxzZSwKLSAgICAgICAgICAgICAgICBmYWxzZQotICAgICAgICB9OwotCi0gICAgICAgIGludCBzaWdudW0gPSBkdXJhdGlvbi5nZXRTaWduKCk7Ci0KLSAgICAgICAgaW50IHN0YXJ0TW9udGggPSBnZXRNb250aCgpOwotICAgICAgICBpZiAoc3RhcnRNb250aCA9PSBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQpIHsKLSAgICAgICAgICAgIHN0YXJ0TW9udGggPSBEYXRhdHlwZUNvbnN0YW50cy5KQU5VQVJZOwotICAgICAgICAgICAgZmllbGRVbmRlZmluZWRbTU9OVEhdID0gdHJ1ZTsKLSAgICAgICAgfQotCi0gICAgICAgIEJpZ0ludGVnZXIgZE1vbnRocyA9IHNhbml0aXplKGR1cmF0aW9uLmdldEZpZWxkKERhdGF0eXBlQ29uc3RhbnRzLk1PTlRIUyksIHNpZ251bSk7Ci0gICAgICAgIEJpZ0ludGVnZXIgdGVtcCA9IEJpZ0ludGVnZXIudmFsdWVPZigobG9uZykgc3RhcnRNb250aCkuYWRkKGRNb250aHMpOwotICAgICAgICBzZXRNb250aCh0ZW1wLnN1YnRyYWN0KEJpZ0ludGVnZXIuT05FKS5tb2QoVFdFTFZFKS5pbnRWYWx1ZSgpICsgMSk7Ci0gICAgICAgIEJpZ0ludGVnZXIgY2FycnkgPQotICAgICAgICAgICAgICAgIG5ldyBCaWdEZWNpbWFsKHRlbXAuc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpKS5kaXZpZGUobmV3IEJpZ0RlY2ltYWwoVFdFTFZFKSwgQmlnRGVjaW1hbC5ST1VORF9GTE9PUikudG9CaWdJbnRlZ2VyKCk7Ci0KLSAgICAgICAgLyogWWVhcnMgKG1heSBiZSBtb2RpZmllZCBhZGRpdGlvbmFsbHkgYmVsb3cpCi0gICAgICAgICAgICAqICBFW3llYXJdIDo9IFNbeWVhcl0gKyBEW3llYXJdICsgY2FycnkKLSAgICAgICAgICAgICovCi0gICAgICAgIEJpZ0ludGVnZXIgc3RhcnRZZWFyID0gZ2V0RW9uQW5kWWVhcigpOwotICAgICAgICBpZiAoc3RhcnRZZWFyID09IG51bGwpIHsKLSAgICAgICAgICAgIGZpZWxkVW5kZWZpbmVkW1lFQVJdID0gdHJ1ZTsKLSAgICAgICAgICAgIHN0YXJ0WWVhciA9IEJpZ0ludGVnZXIuWkVSTzsKLSAgICAgICAgfQotICAgICAgICBCaWdJbnRlZ2VyIGRZZWFycyA9IHNhbml0aXplKGR1cmF0aW9uLmdldEZpZWxkKERhdGF0eXBlQ29uc3RhbnRzLllFQVJTKSwgc2lnbnVtKTsKLSAgICAgICAgQmlnSW50ZWdlciBlbmRZZWFyID0gc3RhcnRZZWFyLmFkZChkWWVhcnMpLmFkZChjYXJyeSk7Ci0gICAgICAgIHNldFllYXIoZW5kWWVhcik7Ci0KLSAgICAgICAgLyogWm9uZQotICAgICAgICAgICAgICAgKiAgRVt6b25lXSA6PSBTW3pvbmVdCi0gICAgICAgICAgICoKLSAgICAgICAgICAgKiBuby1vcCBzaW5jZSBhZGRpbmcgdG8gdGhpcywgbm90IHRvIGEgbmV3IGVuZCBwb2ludC4KLSAgICAgICAgICAgKi8KLQotICAgICAgICAvKiBTZWNvbmRzCi0gICAgICAgICAgICAqICB0ZW1wIDo9IFNbc2Vjb25kXSArIERbc2Vjb25kXQotICAgICAgICAgICAgKiAgRVtzZWNvbmRdIDo9IG1vZHVsbyh0ZW1wLCA2MCkKLSAgICAgICAgICAgICogIGNhcnJ5IDo9IGZRdW90aWVudCh0ZW1wLCA2MCkKLSAgICAgICAgICAgICovCi0gICAgICAgIEJpZ0RlY2ltYWwgc3RhcnRTZWNvbmRzOwotICAgICAgICBpZiAoZ2V0U2Vjb25kKCkgPT0gRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVEKSB7Ci0gICAgICAgICAgICBmaWVsZFVuZGVmaW5lZFtTRUNPTkRdID0gdHJ1ZTsKLSAgICAgICAgICAgIHN0YXJ0U2Vjb25kcyA9IERFQ0lNQUxfWkVSTzsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIC8vIHNlY29uZHMgKyBmcmFjdGlvbmFsU2Vjb25kcwotICAgICAgICAgICAgc3RhcnRTZWNvbmRzID0gZ2V0U2Vjb25kcygpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gRHVyYXRpb24gc2Vjb25kcyBpcyBTRUNPTkRTICsgRlJBQ1RJT05BTFNFQ09ORFMuCi0gICAgICAgIEJpZ0RlY2ltYWwgZFNlY29uZHMgPSBEdXJhdGlvbkltcGwuc2FuaXRpemUoKEJpZ0RlY2ltYWwpIGR1cmF0aW9uLmdldEZpZWxkKERhdGF0eXBlQ29uc3RhbnRzLlNFQ09ORFMpLCBzaWdudW0pOwotICAgICAgICBCaWdEZWNpbWFsIHRlbXBCRCA9IHN0YXJ0U2Vjb25kcy5hZGQoZFNlY29uZHMpOwotICAgICAgICBCaWdEZWNpbWFsIGZRdW90aWVudCA9Ci0gICAgICAgICAgICAgICAgbmV3IEJpZ0RlY2ltYWwobmV3IEJpZ0RlY2ltYWwodGVtcEJELnRvQmlnSW50ZWdlcigpKS5kaXZpZGUoREVDSU1BTF9TSVhUWSwgQmlnRGVjaW1hbC5ST1VORF9GTE9PUikudG9CaWdJbnRlZ2VyKCkpOwotICAgICAgICBCaWdEZWNpbWFsIGVuZFNlY29uZHMgPSB0ZW1wQkQuc3VidHJhY3QoZlF1b3RpZW50Lm11bHRpcGx5KERFQ0lNQUxfU0lYVFkpKTsKLQotICAgICAgICBjYXJyeSA9IGZRdW90aWVudC50b0JpZ0ludGVnZXIoKTsKLSAgICAgICAgc2V0U2Vjb25kKGVuZFNlY29uZHMuaW50VmFsdWUoKSk7Ci0gICAgICAgIEJpZ0RlY2ltYWwgdGVtcEZyYWNTZWNvbmRzID0gZW5kU2Vjb25kcy5zdWJ0cmFjdChuZXcgQmlnRGVjaW1hbChCaWdJbnRlZ2VyLnZhbHVlT2YoKGxvbmcpIGdldFNlY29uZCgpKSkpOwotICAgICAgICBpZiAodGVtcEZyYWNTZWNvbmRzLmNvbXBhcmVUbyhERUNJTUFMX1pFUk8pIDwgMCkgewotICAgICAgICAgICAgc2V0RnJhY3Rpb25hbFNlY29uZChERUNJTUFMX09ORS5hZGQodGVtcEZyYWNTZWNvbmRzKSk7Ci0gICAgICAgICAgICBpZiAoZ2V0U2Vjb25kKCkgPT0gMCkgewotICAgICAgICAgICAgICAgIHNldFNlY29uZCg1OSk7Ci0gICAgICAgICAgICAgICAgY2FycnkgPSBjYXJyeS5zdWJ0cmFjdChCaWdJbnRlZ2VyLk9ORSk7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIHNldFNlY29uZChnZXRTZWNvbmQoKSAtIDEpOwotICAgICAgICAgICAgfQotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgc2V0RnJhY3Rpb25hbFNlY29uZCh0ZW1wRnJhY1NlY29uZHMpOwotICAgICAgICB9Ci0KLSAgICAgICAgLyogTWludXRlcwotICAgICAgICAgICAgICAgKiAgdGVtcCA6PSBTW21pbnV0ZV0gKyBEW21pbnV0ZV0gKyBjYXJyeQotICAgICAgICAgICAgICAgKiAgRVttaW51dGVdIDo9IG1vZHVsbyh0ZW1wLCA2MCkKLSAgICAgICAgICAgICAgICogIGNhcnJ5IDo9IGZRdW90aWVudCh0ZW1wLCA2MCkKLSAgICAgICAgICAgKi8KLSAgICAgICAgaW50IHN0YXJ0TWludXRlcyA9IGdldE1pbnV0ZSgpOwotICAgICAgICBpZiAoc3RhcnRNaW51dGVzID09IERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCkgewotICAgICAgICAgICAgZmllbGRVbmRlZmluZWRbTUlOVVRFXSA9IHRydWU7Ci0gICAgICAgICAgICBzdGFydE1pbnV0ZXMgPSAwOwotICAgICAgICB9Ci0gICAgICAgIEJpZ0ludGVnZXIgZE1pbnV0ZXMgPSBzYW5pdGl6ZShkdXJhdGlvbi5nZXRGaWVsZChEYXRhdHlwZUNvbnN0YW50cy5NSU5VVEVTKSwgc2lnbnVtKTsKLQotICAgICAgICB0ZW1wID0gQmlnSW50ZWdlci52YWx1ZU9mKHN0YXJ0TWludXRlcykuYWRkKGRNaW51dGVzKS5hZGQoY2FycnkpOwotICAgICAgICBzZXRNaW51dGUodGVtcC5tb2QoU0lYVFkpLmludFZhbHVlKCkpOwotICAgICAgICBjYXJyeSA9IG5ldyBCaWdEZWNpbWFsKHRlbXApLmRpdmlkZShERUNJTUFMX1NJWFRZLCBCaWdEZWNpbWFsLlJPVU5EX0ZMT09SKS50b0JpZ0ludGVnZXIoKTsKLQotICAgICAgICAvKiBIb3VycwotICAgICAgICAgICAgICAgKiAgdGVtcCA6PSBTW2hvdXJdICsgRFtob3VyXSArIGNhcnJ5Ci0gICAgICAgICAgICAgICAqICBFW2hvdXJdIDo9IG1vZHVsbyh0ZW1wLCAyNCkKLSAgICAgICAgICAgICAgICogIGNhcnJ5IDo9IGZRdW90aWVudCh0ZW1wLCAyNCkKLSAgICAgICAgICAgKi8KLSAgICAgICAgaW50IHN0YXJ0SG91cnMgPSBnZXRIb3VyKCk7Ci0gICAgICAgIGlmIChzdGFydEhvdXJzID09IERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCkgewotICAgICAgICAgICAgZmllbGRVbmRlZmluZWRbSE9VUl0gPSB0cnVlOwotICAgICAgICAgICAgc3RhcnRIb3VycyA9IDA7Ci0gICAgICAgIH0KLSAgICAgICAgQmlnSW50ZWdlciBkSG91cnMgPSBzYW5pdGl6ZShkdXJhdGlvbi5nZXRGaWVsZChEYXRhdHlwZUNvbnN0YW50cy5IT1VSUyksIHNpZ251bSk7Ci0KLSAgICAgICAgdGVtcCA9IEJpZ0ludGVnZXIudmFsdWVPZihzdGFydEhvdXJzKS5hZGQoZEhvdXJzKS5hZGQoY2FycnkpOwotICAgICAgICBzZXRIb3VyKHRlbXAubW9kKFRXRU5UWV9GT1VSKS5pbnRWYWx1ZSgpLCBmYWxzZSk7Ci0gICAgICAgIGNhcnJ5ID0gbmV3IEJpZ0RlY2ltYWwodGVtcCkuZGl2aWRlKG5ldyBCaWdEZWNpbWFsKFRXRU5UWV9GT1VSKSwgQmlnRGVjaW1hbC5ST1VORF9GTE9PUikudG9CaWdJbnRlZ2VyKCk7Ci0KLSAgICAgICAgLyogRGF5cwotICAgICAgICAgICAqICBpZiBTW2RheV0gPiBtYXhpbXVtRGF5SW5Nb250aEZvcihFW3llYXJdLCBFW21vbnRoXSkKLSAgICAgICAgICAgKiAgICAgICArIHRlbXBEYXlzIDo9IG1heGltdW1EYXlJbk1vbnRoRm9yKEVbeWVhcl0sIEVbbW9udGhdKQotICAgICAgICAgICAqICBlbHNlIGlmIFNbZGF5XSA8IDEKLSAgICAgICAgICAgKiAgICAgICArIHRlbXBEYXlzIDo9IDEKLSAgICAgICAgICAgKiAgZWxzZQotICAgICAgICAgICAqICAgICAgICsgdGVtcERheXMgOj0gU1tkYXldCi0gICAgICAgICAgICogIEVbZGF5XSA6PSB0ZW1wRGF5cyArIERbZGF5XSArIGNhcnJ5Ci0gICAgICAgICAgICogIFNUQVJUIExPT1AKLSAgICAgICAgICAgKiAgICAgICArIElGIEVbZGF5XSA8IDEKLSAgICAgICAgICAgKiAgICAgICAgICAgICAjIEVbZGF5XSA6PSBFW2RheV0gKwotICAgICAgICAgICAgKiAgICAgICAgICAgICAgICAgbWF4aW11bURheUluTW9udGhGb3IoRVt5ZWFyXSwgRVttb250aF0gLSAxKQotICAgICAgICAgICAqICAgICAgICAgICAgICMgY2FycnkgOj0gLTEKLSAgICAgICAgICAgKiAgICAgICArIEVMU0UgSUYgRVtkYXldID4gbWF4aW11bURheUluTW9udGhGb3IoRVt5ZWFyXSwgRVttb250aF0pCi0gICAgICAgICAgICogICAgICAgICAgICAgIyBFW2RheV0gOj0KLSAgICAgICAgICAgICogICAgICAgICAgICAgICAgICAgIEVbZGF5XSAtIG1heGltdW1EYXlJbk1vbnRoRm9yKEVbeWVhcl0sIEVbbW9udGhdKQotICAgICAgICAgICAqICAgICAgICAgICAgICMgY2FycnkgOj0gMQotICAgICAgICAgICAqICAgICAgICsgRUxTRSBFWElUIExPT1AKLSAgICAgICAgICAgKiAgICAgICArIHRlbXAgOj0gRVttb250aF0gKyBjYXJyeQotICAgICAgICAgICAqICAgICAgICsgRVttb250aF0gOj0gbW9kdWxvKHRlbXAsIDEsIDEzKQotICAgICAgICAgICAqICAgICAgICsgRVt5ZWFyXSA6PSBFW3llYXJdICsgZlF1b3RpZW50KHRlbXAsIDEsIDEzKQotICAgICAgICAgICAqICAgICAgICsgR09UTyBTVEFSVCBMT09QCi0gICAgICAgICAgICovCi0gICAgICAgIEJpZ0ludGVnZXIgdGVtcERheXM7Ci0gICAgICAgIGludCBzdGFydERheSA9IGdldERheSgpOwotICAgICAgICBpZiAoc3RhcnREYXkgPT0gRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVEKSB7Ci0gICAgICAgICAgICBmaWVsZFVuZGVmaW5lZFtEQVldID0gdHJ1ZTsKLSAgICAgICAgICAgIHN0YXJ0RGF5ID0gMTsKLSAgICAgICAgfQotICAgICAgICBCaWdJbnRlZ2VyIGREYXlzID0gc2FuaXRpemUoZHVyYXRpb24uZ2V0RmllbGQoRGF0YXR5cGVDb25zdGFudHMuREFZUyksIHNpZ251bSk7Ci0gICAgICAgIGludCBtYXhEYXlJbk1vbnRoID0gbWF4aW11bURheUluTW9udGhGb3IoZ2V0RW9uQW5kWWVhcigpLCBnZXRNb250aCgpKTsKLSAgICAgICAgaWYgKHN0YXJ0RGF5ID4gbWF4RGF5SW5Nb250aCkgewotICAgICAgICAgICAgdGVtcERheXMgPSBCaWdJbnRlZ2VyLnZhbHVlT2YobWF4RGF5SW5Nb250aCk7Ci0gICAgICAgIH0gZWxzZSBpZiAoc3RhcnREYXkgPCAxKSB7Ci0gICAgICAgICAgICB0ZW1wRGF5cyA9IEJpZ0ludGVnZXIuT05FOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgdGVtcERheXMgPSBCaWdJbnRlZ2VyLnZhbHVlT2Yoc3RhcnREYXkpOwotICAgICAgICB9Ci0gICAgICAgIEJpZ0ludGVnZXIgZW5kRGF5cyA9IHRlbXBEYXlzLmFkZChkRGF5cykuYWRkKGNhcnJ5KTsKLSAgICAgICAgaW50IG1vbnRoQ2Fycnk7Ci0gICAgICAgIGludCBpbnRUZW1wOwotICAgICAgICB3aGlsZSAodHJ1ZSkgewotICAgICAgICAgICAgaWYgKGVuZERheXMuY29tcGFyZVRvKEJpZ0ludGVnZXIuT05FKSA8IDApIHsKLSAgICAgICAgICAgICAgICAvLyBjYWxjdWxhdGUgZGF5cyBpbiBwcmV2aW91cyBtb250aCwgd2F0Y2ggZm9yIG1vbnRoIHJvbGwgb3ZlcgotICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIgbWRpbWYgPSBudWxsOwotICAgICAgICAgICAgICAgIGlmIChtb250aCA+PSAyKSB7Ci0gICAgICAgICAgICAgICAgICAgIG1kaW1mID0gQmlnSW50ZWdlci52YWx1ZU9mKG1heGltdW1EYXlJbk1vbnRoRm9yKGdldEVvbkFuZFllYXIoKSwgZ2V0TW9udGgoKSAtIDEpKTsKLSAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAvLyByb2xsIG92ZXIgdG8gRGVjZW1iZXIgb2YgcHJldmlvdXMgeWVhcgotICAgICAgICAgICAgICAgICAgICBtZGltZiA9IEJpZ0ludGVnZXIudmFsdWVPZihtYXhpbXVtRGF5SW5Nb250aEZvcihnZXRFb25BbmRZZWFyKCkuc3VidHJhY3QoQmlnSW50ZWdlci52YWx1ZU9mKChsb25nKSAxKSksIDEyKSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVuZERheXMgPSBlbmREYXlzLmFkZChtZGltZik7Ci0gICAgICAgICAgICAgICAgbW9udGhDYXJyeSA9IC0xOwotICAgICAgICAgICAgfSBlbHNlIGlmIChlbmREYXlzLmNvbXBhcmVUbyhCaWdJbnRlZ2VyLnZhbHVlT2YobWF4aW11bURheUluTW9udGhGb3IoZ2V0RW9uQW5kWWVhcigpLCBnZXRNb250aCgpKSkpID4gMCkgewotICAgICAgICAgICAgICAgIGVuZERheXMgPSBlbmREYXlzLmFkZChCaWdJbnRlZ2VyLnZhbHVlT2YoLW1heGltdW1EYXlJbk1vbnRoRm9yKGdldEVvbkFuZFllYXIoKSwgZ2V0TW9udGgoKSkpKTsKLSAgICAgICAgICAgICAgICBtb250aENhcnJ5ID0gMTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGludFRlbXAgPSBnZXRNb250aCgpICsgbW9udGhDYXJyeTsKLSAgICAgICAgICAgIGludCBlbmRNb250aCA9IChpbnRUZW1wIC0gMSkgJSAoMTMgLSAxKTsKLSAgICAgICAgICAgIGludCBxdW90aWVudDsKLSAgICAgICAgICAgIGlmIChlbmRNb250aCA8IDApIHsKLSAgICAgICAgICAgICAgICBlbmRNb250aCA9ICgxMyAtIDEpICsgZW5kTW9udGggKyAxOwotICAgICAgICAgICAgICAgIHF1b3RpZW50ID0gbmV3IEJpZ0RlY2ltYWwoaW50VGVtcCAtIDEpLmRpdmlkZShuZXcgQmlnRGVjaW1hbChUV0VMVkUpLCBCaWdEZWNpbWFsLlJPVU5EX1VQKS5pbnRWYWx1ZSgpOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBxdW90aWVudCA9IChpbnRUZW1wIC0gMSkgLyAoMTMgLSAxKTsKLSAgICAgICAgICAgICAgICBlbmRNb250aCArPSAxOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgc2V0TW9udGgoZW5kTW9udGgpOwotICAgICAgICAgICAgaWYgKHF1b3RpZW50ICE9IDApIHsKLSAgICAgICAgICAgICAgICBzZXRZZWFyKGdldEVvbkFuZFllYXIoKS5hZGQoQmlnSW50ZWdlci52YWx1ZU9mKHF1b3RpZW50KSkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHNldERheShlbmREYXlzLmludFZhbHVlKCkpOwotCi0gICAgICAgIC8vIHNldCBmaWVsZHMgdGhhdCB3aGVyZSB1bmRlZmluZWQgYmVmb3JlIHRoaXMgYWRkaXRpb24sIGJhY2sgdG8gdW5kZWZpbmVkLgotICAgICAgICBmb3IgKGludCBpID0gWUVBUjsgaSA8PSBTRUNPTkQ7IGkrKykgewotICAgICAgICAgICAgaWYgKGZpZWxkVW5kZWZpbmVkW2ldKSB7Ci0gICAgICAgICAgICAgICAgc3dpdGNoIChpKSB7Ci0gICAgICAgICAgICAgICAgY2FzZSBZRUFSOgotICAgICAgICAgICAgICAgICAgICBzZXRZZWFyKERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCk7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGNhc2UgTU9OVEg6Ci0gICAgICAgICAgICAgICAgICAgIHNldE1vbnRoKERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCk7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGNhc2UgREFZOgotICAgICAgICAgICAgICAgICAgICBzZXREYXkoRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVEKTsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgY2FzZSBIT1VSOgotICAgICAgICAgICAgICAgICAgICBzZXRIb3VyKERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCwgZmFsc2UpOwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICBjYXNlIE1JTlVURToKLSAgICAgICAgICAgICAgICAgICAgc2V0TWludXRlKERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCk7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGNhc2UgU0VDT05EOgotICAgICAgICAgICAgICAgICAgICBzZXRTZWNvbmQoRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVEKTsKLSAgICAgICAgICAgICAgICAgICAgc2V0RnJhY3Rpb25hbFNlY29uZChudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQmlnSW50ZWdlciBGT1VSID0gQmlnSW50ZWdlci52YWx1ZU9mKDQpOwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEJpZ0ludGVnZXIgSFVORFJFRCA9IEJpZ0ludGVnZXIudmFsdWVPZigxMDApOwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEJpZ0ludGVnZXIgRk9VUl9IVU5EUkVEID0gQmlnSW50ZWdlci52YWx1ZU9mKDQwMCk7Ci0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQmlnSW50ZWdlciBTSVhUWSA9IEJpZ0ludGVnZXIudmFsdWVPZig2MCk7Ci0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQmlnSW50ZWdlciBUV0VOVFlfRk9VUiA9IEJpZ0ludGVnZXIudmFsdWVPZigyNCk7Ci0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQmlnSW50ZWdlciBUV0VMVkUgPSBCaWdJbnRlZ2VyLnZhbHVlT2YoMTIpOwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEJpZ0RlY2ltYWwgREVDSU1BTF9aRVJPID0gbmV3IEJpZ0RlY2ltYWwoIjAiKTsKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBCaWdEZWNpbWFsIERFQ0lNQUxfT05FID0gbmV3IEJpZ0RlY2ltYWwoIjEiKTsKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBCaWdEZWNpbWFsIERFQ0lNQUxfU0lYVFkgPSBuZXcgQmlnRGVjaW1hbCgiNjAiKTsKLQotCi0gICAgcHJpdmF0ZSBzdGF0aWMgaW50IGRheXNJbk1vbnRoW10gPSB7IDAsICAvLyBYTUwgU2NoZW1hIG1vbnRocyBzdGFydCBhdCAxLgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMzEsIDI4LCAzMSwgMzAsIDMxLCAzMCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDMxLCAzMSwgMzAsIDMxLCAzMCwgMzF9OwotCi0gICAgcHJpdmF0ZSBzdGF0aWMgaW50IG1heGltdW1EYXlJbk1vbnRoRm9yKEJpZ0ludGVnZXIgeWVhciwgaW50IG1vbnRoKSB7Ci0gICAgICAgIGlmIChtb250aCAhPSBEYXRhdHlwZUNvbnN0YW50cy5GRUJSVUFSWSkgewotICAgICAgICAgICAgcmV0dXJuIGRheXNJbk1vbnRoW21vbnRoXTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIGlmICh5ZWFyLm1vZChGT1VSX0hVTkRSRUQpLmVxdWFscyhCaWdJbnRlZ2VyLlpFUk8pIHx8Ci0gICAgICAgICAgICAgICAgICAgICgheWVhci5tb2QoSFVORFJFRCkuZXF1YWxzKEJpZ0ludGVnZXIuWkVSTykgJiYKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ZWFyLm1vZChGT1VSKS5lcXVhbHMoQmlnSW50ZWdlci5aRVJPKSkpIHsKLSAgICAgICAgICAgICAgICAvLyBpcyBhIGxlYXAgeWVhci4KLSAgICAgICAgICAgICAgICByZXR1cm4gMjk7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIHJldHVybiBkYXlzSW5Nb250aFttb250aF07Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBpbnQgbWF4aW11bURheUluTW9udGhGb3IoaW50IHllYXIsIGludCBtb250aCkgewotICAgICAgICBpZiAobW9udGggIT0gRGF0YXR5cGVDb25zdGFudHMuRkVCUlVBUlkpIHsKLSAgICAgICAgICAgIHJldHVybiBkYXlzSW5Nb250aFttb250aF07Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBpZiAoKCh5ZWFyICUgNDAwKSA9PSAwKSB8fAotICAgICAgICAgICAgICAgICAgICAoKCh5ZWFyICUgMTAwKSAhPSAwKSAmJiAoKHllYXIgJSA0KSA9PSAwKSkpIHsKLSAgICAgICAgICAgICAgICAvLyBpcyBhIGxlYXAgeWVhci4KLSAgICAgICAgICAgICAgICByZXR1cm4gMjk7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIHJldHVybiBkYXlzSW5Nb250aFtEYXRhdHlwZUNvbnN0YW50cy5GRUJSVUFSWV07Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5Db252ZXJ0IDxjb2RlPnRoaXM8L2NvZGU+IHRvIDxjb2RlPmphdmEudXRpbC5HcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4uPC9wPgotICAgICAqCi0gICAgICogPHA+V2hlbiA8Y29kZT50aGlzPC9jb2RlPiBpbnN0YW5jZSBoYXMgYW4gdW5kZWZpbmVkIGZpZWxkLCB0aGlzCi0gICAgICogY29udmVyc2lvbiByZWxpZXMgb24gdGhlIDxjb2RlPmphdmEudXRpbC5HcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gZGVmYXVsdAotICAgICAqIGZvciBpdHMgY29ycmVzcG9uZGluZyBmaWVsZC4gQSBub3RhYmxlIGRpZmZlcmVuY2UgYmV0d2VlbgotICAgICAqIFhNTCBTY2hlbWEgMS4wIGRhdGUvdGltZSBkYXRhdHlwZXMgYW5kIDxjb2RlPmphdmEudXRpbC5HcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4KLSAgICAgKiBpcyB0aGF0IFRpbWV6b25lIHZhbHVlIGlzIG9wdGlvbmFsIGZvciBkYXRlL3RpbWUgZGF0YXR5cGVzIGFuZCBpdCBpcwotICAgICAqIGEgcmVxdWlyZWQgZmllbGQgZm9yIDxjb2RlPmphdmEudXRpbC5HcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4uIFNlZSBqYXZhZG9jCi0gICAgICogZm9yIDxjb2RlPmphdmEudXRpbC5UaW1lWm9uZS5nZXREZWZhdWx0KCk8L2NvZGU+IG9uIGhvdyB0aGUgZGVmYXVsdAotICAgICAqIGlzIGRldGVybWluZWQuIFRvIGV4cGxpY2l0bHkgc3BlY2lmeSB0aGUgPGNvZGU+VGltZVpvbmU8L2NvZGU+Ci0gICAgICogaW5zdGFuY2UsIHNlZQotICAgICAqIHtAbGluayAjdG9HcmVnb3JpYW5DYWxlbmRhcihUaW1lWm9uZSwgTG9jYWxlLCBYTUxHcmVnb3JpYW5DYWxlbmRhcil9LjwvcD4KLSAgICAgKgotICAgICAqIDx0YWJsZSBib3JkZXI9IjIiIHJ1bGVzPSJhbGwiIGNlbGxwYWRkaW5nPSIyIj4KLSAgICAgKiAgIDx0aGVhZD4KLSAgICAgKiAgICAgPHRyPgotICAgICAqICAgICAgIDx0aCBhbGlnbj0iY2VudGVyIiBjb2xzcGFuPSIyIj4KLSAgICAgKiAgICAgICAgICBGaWVsZCBieSBGaWVsZCBDb252ZXJzaW9uIGZyb20gdGhpcyBjbGFzcyB0bwotICAgICAqICAgICAgICAgIDxjb2RlPmphdmEudXRpbC5HcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4KLSAgICAgKiAgICAgICA8L3RoPgotICAgICAqICAgICA8L3RyPgotICAgICAqICAgPC90aGVhZD4KLSAgICAgKiAgIDx0Ym9keT4KLSAgICAgKiAgICAgPHRyPgotICAgICAqICAgICAgICA8dGg+PGNvZGU+amF2YS51dGlsLkdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiBmaWVsZDwvdGg+Ci0gICAgICogICAgICAgIDx0aD48Y29kZT5qYXZheC54bWwuZGF0YXR5cGUuWE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IGZpZWxkPC90aD4KLSAgICAgKiAgICAgPC90cj4KLSAgICAgKiAgICAgPHRyPgotICAgICAqICAgICAgIDx0aD48Y29kZT5FUkE8L2NvZGU+PC90aD4KLSAgICAgKiAgICAgICA8dGg+e0BsaW5rICNnZXRFb25BbmRZZWFyKCl9PGNvZGU+LnNpZ251bSgpIDwgMCA/IEdyZWdvcmlhbkNhbGVuZGFyLkJDIDogR3JlZ29yaWFuQ2FsZW5kYXIuQUQ8L2NvZGU+PC90aD4KLSAgICAgKiAgICAgPC90cj4KLSAgICAgKiAgICAgPHRyPgotICAgICAqICAgICAgIDx0aD48Y29kZT5ZRUFSPC9jb2RlPjwvdGg+Ci0gICAgICogICAgICAgPHRoPntAbGluayAjZ2V0RW9uQW5kWWVhcigpfTxjb2RlPi5hYnMoKS5pbnRWYWx1ZSgpPC9jb2RlPjxpPio8L2k+PC90aD4KLSAgICAgKiAgICAgPC90cj4KLSAgICAgKiAgICAgPHRyPgotICAgICAqICAgICAgIDx0aD48Y29kZT5NT05USDwvY29kZT48L3RoPgotICAgICAqICAgICAgIDx0aD57QGxpbmsgI2dldE1vbnRoKCl9PGNvZGU+IC0gMTwvY29kZT48L3RoPgotICAgICAqICAgICA8L3RyPgotICAgICAqICAgICA8dHI+Ci0gICAgICogICAgICAgPHRoPjxjb2RlPkRBWV9PRl9NT05USDwvY29kZT48L3RoPgotICAgICAqICAgICAgIDx0aD57QGxpbmsgI2dldERheSgpfTwvdGg+Ci0gICAgICogICAgIDwvdHI+Ci0gICAgICogICAgIDx0cj4KLSAgICAgKiAgICAgICA8dGg+PGNvZGU+QU1fUE08L2NvZGU+PC90aD4KLSAgICAgKiAgICAgICA8dGg+e0BsaW5rICNnZXRIb3VyKCl9IDwgMTIgOiBDYWxlbmRhci5BTSA6IENhbGVuZGFyLlBNPC90aD4KLSAgICAgKiAgICAgPC90cj4KLSAgICAgKiAgICAgPHRyPgotICAgICAqICAgICAgIDx0aD48Y29kZT5IT1VSX09GX0RBWTwvY29kZT48L3RoPgotICAgICAqICAgICAgIDx0aD57QGxpbmsgI2dldEhvdXIoKX08L3RoPgotICAgICAqICAgICA8L3RyPgotICAgICAqICAgICA8dHI+Ci0gICAgICogICAgICAgPHRoPjxjb2RlPk1JTlVURTwvY29kZT48L3RoPgotICAgICAqICAgICAgIDx0aD57QGxpbmsgI2dldE1pbnV0ZSgpfTwvdGg+Ci0gICAgICogICAgIDwvdHI+Ci0gICAgICogICAgIDx0cj4KLSAgICAgKiAgICAgICA8dGg+PGNvZGU+U0VDT05EPC9jb2RlPjwvdGg+Ci0gICAgICogICAgICAgPHRoPntAbGluayAjZ2V0U2Vjb25kKCl9PC90aD4KLSAgICAgKiAgICAgPC90cj4KLSAgICAgKiAgICAgPHRyPgotICAgICAqICAgICAgIDx0aD48Y29kZT5NSUxMSVNFQ09ORDwvY29kZT48L3RoPgotICAgICAqICAgICAgIDx0aD5nZXQgbWlsbGlzZWNvbmQgb3JkZXIgZnJvbSB7QGxpbmsgI2dldEZyYWN0aW9uYWxTZWNvbmQoKX08aT4qPC9pPiA8L3RoPgotICAgICAqICAgICA8L3RyPgotICAgICAqICAgICA8dHI+Ci0gICAgICogICAgICAgPHRoPjxjb2RlPkdyZWdvcmlhbkNhbGVuZGFyLnNldFRpbWVab25lKFRpbWVab25lKTwvY29kZT48L3RoPgotICAgICAqICAgICAgIDx0aD57QGxpbmsgI2dldFRpbWV6b25lKCl9IGZvcm1hdHRlZCBpbnRvIEN1c3RvbSB0aW1lem9uZSBpZDwvdGg+Ci0gICAgICogICAgIDwvdHI+Ci0gICAgICogICA8L3Rib2R5PgotICAgICAqIDwvdGFibGU+Ci0gICAgICogPGk+KjwvaT4gZGVzaWduYXRlcyBwb3NzaWJsZSBsb3NzIG9mIHByZWNpc2lvbiBkdXJpbmcgdGhlIGNvbnZlcnNpb24gZHVlCi0gICAgICogdG8gc291cmNlIGRhdGF0eXBlIGhhdmluZyBoaWdlciBwcmVjaXNvbiB0aGFuIHRhcmdldCBkYXRhdHlwZS4KLSAgICAgKgotICAgICAqIDxwPlRvIGVuc3VyZSBjb25zaXN0ZW5jeSBpbiBjb252ZXJzaW9uIGltcGxlbWVudGF0aW9ucywgdGhlIG5ldwotICAgICAqIDxjb2RlPkdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiBzaG91bGQgYmUgaW5zdGFudGlhdGVkIGluIGZvbGxvd2luZwotICAgICAqIG1hbm5lci4KLSAgICAgKiA8dWw+Ci0gICAgICogICA8bGk+VXNpbmcgPGNvZGU+dGltZVpvbmU8L2NvZGU+IHZhbHVlIGFzIGRlZmluZWQgYWJvdmUsIGNyZWF0ZSBhIG5ldwotICAgICAqIDxjb2RlPmphdmEudXRpbC5HcmVnb3JpYW5DYWxlbmRhcih0aW1lWm9uZSxMb2NhbGUuZ2V0RGVmYXVsdCgpKTwvY29kZT4uCi0gICAgICogICA8L2xpPgotICAgICAqICAgPGxpPkluaXRpYWxpemUgYWxsIEdyZWdvcmlhbkNhbGVuZGFyIGZpZWxkcyBieSBjYWxsaW5nIHsoQGxpbmsgR2Vnb3JpYW5DYWxlbmRhciNjbGVhcigpfS48L2xpPgotICAgICAqICAgPGxpPk9idGFpbiBhIHB1cmUgR3JlZ29yaWFuIENhbGVuZGFyIGJ5IGludm9raW5nCi0gICAgICogICA8Y29kZT5HcmVnb3JpYW5DYWxlbmRhci5zZXRHcmVnb3JpYW5DaGFuZ2UoCi0gICAgICogICBuZXcgRGF0ZShMb25nLk1JTl9WQUxVRSkpPC9jb2RlPi48L2xpPgotICAgICAqICAgPGxpPkl0cyBmaWVsZHMgRVJBLCBZRUFSLCBNT05USCwgREFZX09GX01PTlRILCBIT1VSX09GX0RBWSwKLSAgICAgKiAgICAgICBNSU5VVEUsIFNFQ09ORCBhbmQgTUlMTElTRUNPTkQgYXJlIHNldCB1c2luZyB0aGUgbWV0aG9kCi0gICAgICogICAgICAgPGNvZGU+Q2FsZW5kYXIuc2V0KGludCxpbnQpPC9jb2RlPjwvbGk+Ci0gICAgICogPC91bD4KLSAgICAgKiA8L3A+Ci0gICAgICoKLSAgICAgKiBAc2VlICN0b0dyZWdvcmlhbkNhbGVuZGFyKGphdmEudXRpbC5UaW1lWm9uZSwgamF2YS51dGlsLkxvY2FsZSwgWE1MR3JlZ29yaWFuQ2FsZW5kYXIpCi0gICAgICovCi0gICAgcHVibGljIGphdmEudXRpbC5HcmVnb3JpYW5DYWxlbmRhciB0b0dyZWdvcmlhbkNhbGVuZGFyKCkgewotCi0gICAgICAgIEdyZWdvcmlhbkNhbGVuZGFyIHJlc3VsdCA9IG51bGw7Ci0gICAgICAgIGZpbmFsIGludCBERUZBVUxUX1RJTUVaT05FX09GRlNFVCA9IERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRDsKLSAgICAgICAgVGltZVpvbmUgdHogPSBnZXRUaW1lWm9uZShERUZBVUxUX1RJTUVaT05FX09GRlNFVCk7Ci0gICAgICAgIC8qKiBVc2UgdGhlIGZvbGxvd2luZyBpbnN0ZWFkIGZvciBKREs3IG9ubHk6Ci0gICAgICAgICAqIExvY2FsZSBsb2NhbGUgPSBMb2NhbGUuZ2V0RGVmYXVsdChMb2NhbGUuQ2F0ZWdvcnkuRk9STUFUKTsKLSAgICAgICAgICovCi0gICAgICAgIExvY2FsZSBsb2NhbGUgPSBnZXREZWZhdWx0TG9jYWxlKCk7Ci0KLSAgICAgICAgcmVzdWx0ID0gbmV3IEdyZWdvcmlhbkNhbGVuZGFyKHR6LCBsb2NhbGUpOwotICAgICAgICByZXN1bHQuY2xlYXIoKTsKLSAgICAgICAgcmVzdWx0LnNldEdyZWdvcmlhbkNoYW5nZShQVVJFX0dSRUdPUklBTl9DSEFOR0UpOwotCi0gICAgICAgIC8vIGlmIHllYXIoIGFuZCBlb24pIGFyZSB1bmRlZmluZWQsIGxlYXZlIGRlZmF1bHQgQ2FsZW5kYXIgdmFsdWVzCi0gICAgICAgIEJpZ0ludGVnZXIgeWVhciA9IGdldEVvbkFuZFllYXIoKTsKLSAgICAgICAgaWYgKHllYXIgIT0gbnVsbCkgewotICAgICAgICAgICAgcmVzdWx0LnNldChDYWxlbmRhci5FUkEsIHllYXIuc2lnbnVtKCkgPT0gLTEgPyBHcmVnb3JpYW5DYWxlbmRhci5CQyA6IEdyZWdvcmlhbkNhbGVuZGFyLkFEKTsKLSAgICAgICAgICAgIHJlc3VsdC5zZXQoQ2FsZW5kYXIuWUVBUiwgeWVhci5hYnMoKS5pbnRWYWx1ZSgpKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIG9ubHkgc2V0IG1vbnRoIGlmIGl0IGlzIHNldAotICAgICAgICBpZiAobW9udGggIT0gRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVEKSB7Ci0gICAgICAgICAgICAvLyBDYWxlbmRhci5NT05USCBpcyB6ZXJvIGJhc2VkIHdoaWxlIFhNTEdyZWdvcmlhbkNhbGVuZGFyIG1vbnRoIGZpZWxkIGlzIG5vdC4KLSAgICAgICAgICAgIHJlc3VsdC5zZXQoQ2FsZW5kYXIuTU9OVEgsIG1vbnRoIC0gMSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBvbmx5IHNldCBkYXkgaWYgaXQgaXMgc2V0Ci0gICAgICAgIGlmIChkYXkgIT0gRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVEKSB7Ci0gICAgICAgICAgICByZXN1bHQuc2V0KENhbGVuZGFyLkRBWV9PRl9NT05USCwgZGF5KTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIG9ubHkgc2V0IGhvdXIgaWYgaXQgaXMgc2V0Ci0gICAgICAgIGlmIChob3VyICE9IERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCkgewotICAgICAgICAgICAgcmVzdWx0LnNldChDYWxlbmRhci5IT1VSX09GX0RBWSwgaG91cik7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBvbmx5IHNldCBtaW51dGUgaWYgaXQgaXMgc2V0Ci0gICAgICAgIGlmIChtaW51dGUgIT0gRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVEKSB7Ci0gICAgICAgICAgICByZXN1bHQuc2V0KENhbGVuZGFyLk1JTlVURSwgbWludXRlKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIG9ubHkgc2V0IHNlY29uZCBpZiBpdCBpcyBzZXQKLSAgICAgICAgaWYgKHNlY29uZCAhPSBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQpIHsKLSAgICAgICAgICAgIHJlc3VsdC5zZXQoQ2FsZW5kYXIuU0VDT05ELCBzZWNvbmQpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gb25seSBzZXQgbWlsbGlzZW5kIGlmIGl0IGlzIHNldAotICAgICAgICBpZiAoZnJhY3Rpb25hbFNlY29uZCAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXN1bHQuc2V0KENhbGVuZGFyLk1JTExJU0VDT05ELCBnZXRNaWxsaXNlY29uZCgpKTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiByZXN1bHQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIGRlZmF1bHQgbG9jYWxlCi0gICAgICovCi0gICAgcHJpdmF0ZSBMb2NhbGUgZ2V0RGVmYXVsdExvY2FsZSgpIHsKLQotICAgICAgICBTdHJpbmcgbGFuZyA9IFNlY3VyaXR5U3VwcG9ydC5nZXRTeXN0ZW1Qcm9wZXJ0eSgidXNlci5sYW5ndWFnZS5mb3JtYXQiKTsKLSAgICAgICAgU3RyaW5nIGNvdW50cnkgPSBTZWN1cml0eVN1cHBvcnQuZ2V0U3lzdGVtUHJvcGVydHkoInVzZXIuY291bnRyeS5mb3JtYXQiKTsKLSAgICAgICAgU3RyaW5nIHZhcmlhbnQgPSBTZWN1cml0eVN1cHBvcnQuZ2V0U3lzdGVtUHJvcGVydHkoInVzZXIudmFyaWFudC5mb3JtYXQiKTsKLSAgICAgICAgTG9jYWxlIGxvY2FsZSA9IG51bGw7Ci0gICAgICAgIGlmIChsYW5nICE9IG51bGwpIHsKLSAgICAgICAgICAgIGlmIChjb3VudHJ5ICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBpZiAodmFyaWFudCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGxvY2FsZSA9IG5ldyBMb2NhbGUobGFuZywgY291bnRyeSwgdmFyaWFudCk7Ci0gICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgbG9jYWxlID0gbmV3IExvY2FsZShsYW5nLCBjb3VudHJ5KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIGxvY2FsZSA9IG5ldyBMb2NhbGUobGFuZyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGxvY2FsZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBsb2NhbGUgPSBMb2NhbGUuZ2V0RGVmYXVsdCgpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBsb2NhbGU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+Q29udmVydCA8Y29kZT50aGlzPC9jb2RlPiBhbG9uZyB3aXRoIHByb3ZpZGVkIHBhcmFtZXRlcnMKLSAgICAgKiB0byA8Y29kZT5qYXZhLnV0aWwuR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IGluc3RhbmNlLjwvcD4KLSAgICAgKgotICAgICAqIDxwPiBTaW5jZSBYTUwgU2NoZW1hIDEuMCBkYXRlL3RpbWUgZGF0ZXR5cGVzIGhhcyBubyBjb25jZXB0IG9mCi0gICAgICogdGltZXpvbmUgaWRzIG9yIGRheWxpZ2h0IHNhdmluZ3MgdGltZXpvbmUgaWRzLCB0aGlzIGNvbnZlcnNpb24gb3BlcmF0aW9uCi0gICAgICogYWxsb3dzIHRoZSB1c2VyIHRvIGV4cGxpY2l0bHkgc3BlY2lmeSBvbmUgd2l0aAotICAgICAqIDxjb2RlPnRpbWV6b25lPC9jb2RlPiBwYXJhbWV0ZXIuPC9wPgotICAgICAqCi0gICAgICogPHA+VG8gY29tcHV0ZSB0aGUgcmV0dXJuIHZhbHVlJ3MgPGNvZGU+VGltZVpvbmU8L2NvZGU+IGZpZWxkLAotICAgICAqIDx1bD4KLSAgICAgKiA8bGk+d2hlbiBwYXJhbWV0ZXIgPGNvZGU+dGltZVpvbmU8L2NvZGU+IGlzIG5vbi1udWxsLAotICAgICAqIGl0IGlzIHRoZSB0aW1lem9uZSBmaWVsZC48L2xpPgotICAgICAqIDxsaT5lbHNlIHdoZW4gPGNvZGU+dGhpcy5nZXRUaW1lem9uZSgpICE9IERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRDwvY29kZT4sCi0gICAgICogY3JlYXRlIGEgPGNvZGU+amF2YS51dGlsLlRpbWVab25lPC9jb2RlPiB3aXRoIGEgY3VzdG9tIHRpbWV6b25lIGlkCi0gICAgICogdXNpbmcgdGhlIDxjb2RlPnRoaXMuZ2V0VGltZXpvbmUoKTwvY29kZT4uPC9saT4KLSAgICAgKiA8bGk+ZWxzZSB3aGVuIDxjb2RlPmRlZmF1bHRzLmdldFRpbWV6b25lKCkgIT0gRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVEPC9jb2RlPiwKLSAgICAgKiBjcmVhdGUgYSA8Y29kZT5qYXZhLnV0aWwuVGltZVpvbmU8L2NvZGU+IHdpdGggYSBjdXN0b20gdGltZXpvbmUgaWQKLSAgICAgKiB1c2luZyA8Y29kZT5kZWZhdWx0cy5nZXRUaW1lem9uZSgpPC9jb2RlPi48L2xpPgotICAgICAqIDxsaT5lbHNlIHVzZSB0aGUgPGNvZGU+R3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IGRlZmF1bHQgdGltZXpvbmUgdmFsdWUKLSAgICAgKiBmb3IgdGhlIGhvc3QgaXMgZGVmaW5lZGFzIHNwZWNpZmllZCBieQotICAgICAqIDxjb2RlPmphdmEudXRpbC5UaW1lWm9uZS5nZXREZWZhdWx0KCk8L2NvZGU+LjwvbGk+PC9wPgotICAgICAqCi0gICAgICogPHA+VG8gZW5zdXJlIGNvbnNpc3RlbmN5IGluIGNvbnZlcnNpb24gaW1wbGVtZW50YXRpb25zLCB0aGUgbmV3Ci0gICAgICogPGNvZGU+R3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IHNob3VsZCBiZSBpbnN0YW50aWF0ZWQgaW4gZm9sbG93aW5nCi0gICAgICogbWFubmVyLgotICAgICAqIDx1bD4KLSAgICAgKiAgIDxsaT5DcmVhdGUgYSBuZXcgPGNvZGU+amF2YS51dGlsLkdyZWdvcmlhbkNhbGVuZGFyKFRpbWVab25lLAotICAgICAqICAgICAgIExvY2FsZSk8L2NvZGU+IHdpdGggVGltZVpvbmUgc2V0IGFzIHNwZWNpZmllZCBhYm92ZSBhbmQgdGhlCi0gICAgICogICAgICAgPGNvZGU+TG9jYWxlPC9jb2RlPiBwYXJhbWV0ZXIuCi0gICAgICogICA8L2xpPgotICAgICAqICAgPGxpPkluaXRpYWxpemUgYWxsIEdyZWdvcmlhbkNhbGVuZGFyIGZpZWxkcyBieSBjYWxsaW5nIHsoQGxpbmsgR2Vnb3JpYW5DYWxlbmRhciNjbGVhcigpfS48L2xpPgotICAgICAqICAgPGxpPk9idGFpbiBhIHB1cmUgR3JlZ29yaWFuIENhbGVuZGFyIGJ5IGludm9raW5nCi0gICAgICogICA8Y29kZT5HcmVnb3JpYW5DYWxlbmRhci5zZXRHcmVnb3JpYW5DaGFuZ2UoCi0gICAgICogICBuZXcgRGF0ZShMb25nLk1JTl9WQUxVRSkpPC9jb2RlPi48L2xpPgotICAgICAqICAgPGxpPkl0cyBmaWVsZHMgRVJBLCBZRUFSLCBNT05USCwgREFZX09GX01PTlRILCBIT1VSX09GX0RBWSwKLSAgICAgKiAgICAgICBNSU5VVEUsIFNFQ09ORCBhbmQgTUlMTElTRUNPTkQgYXJlIHNldCB1c2luZyB0aGUgbWV0aG9kCi0gICAgICogICAgICAgPGNvZGU+Q2FsZW5kYXIuc2V0KGludCxpbnQpPC9jb2RlPjwvbGk+Ci0gICAgICogPC91bD4KLSAgICAgKgotICAgICAqIEBwYXJhbSB0aW1lem9uZSBwcm92aWRlIFRpbWV6b25lLiA8Y29kZT5udWxsPC9jb2RlPiBpcyBhIGxlZ2FsIHZhbHVlLgotICAgICAqIEBwYXJhbSBhTG9jYWxlICBwcm92aWRlIGV4cGxpY2l0IExvY2FsZS4gVXNlIGRlZmF1bHQgR3JlZ29yaWFuQ2FsZW5kYXIgbG9jYWxlIGlmCi0gICAgICogICAgICAgICAgICAgICAgIHZhbHVlIGlzIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAqIEBwYXJhbSBkZWZhdWx0cyBwcm92aWRlIGRlZmF1bHQgZmllbGQgdmFsdWVzIHRvIHVzZSB3aGVuIGNvcnJlc3BvbmRpbmcKLSAgICAgKiAgICAgICAgICAgICAgICAgZmllbGQgZm9yIHRoaXMgaW5zdGFuY2UgaXMgRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVEIG9yIG51bGwuCi0gICAgICogICAgICAgICAgICAgICAgIElmIDxjb2RlPmRlZmF1bHRzPC9jb2RlPmlzIDxjb2RlPm51bGw8L2NvZGU+IG9yIGEgZmllbGQKLSAgICAgKiAgICAgICAgICAgICAgICAgd2l0aGluIHRoZSBzcGVjaWZpZWQgPGNvZGU+ZGVmYXVsdHM8L2NvZGU+IGlzIHVuZGVmaW5lZCwKLSAgICAgKiAgICAgICAgICAgICAgICAganVzdCB1c2UgPGNvZGU+amF2YS51dGlsLkdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiBkZWZhdWx0cy4KLSAgICAgKiBAcmV0dXJuIGEgamF2YS51dGlsLkdyZWdvcmlhbkNhbGVuZGFyIGNvbnZlcnNpb24gb2YgdGhpcyBpbnN0YW5jZS4KLSAgICAgKgotICAgICAqIEBzZWUgI0xFQVBfWUVBUl9ERUZBVUxUCi0gICAgICovCi0gICAgcHVibGljIEdyZWdvcmlhbkNhbGVuZGFyIHRvR3JlZ29yaWFuQ2FsZW5kYXIoVGltZVpvbmUgdGltZXpvbmUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTG9jYWxlIGFMb2NhbGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MR3JlZ29yaWFuQ2FsZW5kYXIgZGVmYXVsdHMpIHsKLSAgICAgICAgR3JlZ29yaWFuQ2FsZW5kYXIgcmVzdWx0ID0gbnVsbDsKLSAgICAgICAgVGltZVpvbmUgdHogPSB0aW1lem9uZTsKLSAgICAgICAgaWYgKHR6ID09IG51bGwpIHsKLSAgICAgICAgICAgIGludCBkZWZhdWx0Wm9uZW9mZnNldCA9IERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRDsKLSAgICAgICAgICAgIGlmIChkZWZhdWx0cyAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZGVmYXVsdFpvbmVvZmZzZXQgPSBkZWZhdWx0cy5nZXRUaW1lem9uZSgpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgdHogPSBnZXRUaW1lWm9uZShkZWZhdWx0Wm9uZW9mZnNldCk7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGFMb2NhbGUgPT0gbnVsbCkgewotICAgICAgICAgICAgYUxvY2FsZSA9IExvY2FsZS5nZXREZWZhdWx0KCk7Ci0gICAgICAgIH0KLSAgICAgICAgcmVzdWx0ID0gbmV3IEdyZWdvcmlhbkNhbGVuZGFyKHR6LCBhTG9jYWxlKTsKLSAgICAgICAgcmVzdWx0LmNsZWFyKCk7Ci0gICAgICAgIHJlc3VsdC5zZXRHcmVnb3JpYW5DaGFuZ2UoUFVSRV9HUkVHT1JJQU5fQ0hBTkdFKTsKLQotICAgICAgICAvLyBpZiB5ZWFyKCBhbmQgZW9uKSBhcmUgdW5kZWZpbmVkLCBsZWF2ZSBkZWZhdWx0IENhbGVuZGFyIHZhbHVlcwotICAgICAgICBCaWdJbnRlZ2VyIHllYXIgPSBnZXRFb25BbmRZZWFyKCk7Ci0gICAgICAgIGlmICh5ZWFyICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJlc3VsdC5zZXQoQ2FsZW5kYXIuRVJBLCB5ZWFyLnNpZ251bSgpID09IC0xID8gR3JlZ29yaWFuQ2FsZW5kYXIuQkMgOiBHcmVnb3JpYW5DYWxlbmRhci5BRCk7Ci0gICAgICAgICAgICByZXN1bHQuc2V0KENhbGVuZGFyLllFQVIsIHllYXIuYWJzKCkuaW50VmFsdWUoKSk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAvLyB1c2UgZGVmYXVsdCBpZiBzZXQKLSAgICAgICAgICAgIEJpZ0ludGVnZXIgZGVmYXVsdFllYXIgPSAoZGVmYXVsdHMgIT0gbnVsbCkgPyBkZWZhdWx0cy5nZXRFb25BbmRZZWFyKCkgOiBudWxsOwotICAgICAgICAgICAgaWYgKGRlZmF1bHRZZWFyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICByZXN1bHQuc2V0KENhbGVuZGFyLkVSQSwgZGVmYXVsdFllYXIuc2lnbnVtKCkgPT0gLTEgPyBHcmVnb3JpYW5DYWxlbmRhci5CQyA6IEdyZWdvcmlhbkNhbGVuZGFyLkFEKTsKLSAgICAgICAgICAgICAgICByZXN1bHQuc2V0KENhbGVuZGFyLllFQVIsIGRlZmF1bHRZZWFyLmFicygpLmludFZhbHVlKCkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gb25seSBzZXQgbW9udGggaWYgaXQgaXMgc2V0Ci0gICAgICAgIGlmIChtb250aCAhPSBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQpIHsKLSAgICAgICAgICAgIC8vIENhbGVuZGFyLk1PTlRIIGlzIHplcm8gYmFzZWQgd2hpbGUgWE1MR3JlZ29yaWFuQ2FsZW5kYXIgbW9udGggZmllbGQgaXMgbm90LgotICAgICAgICAgICAgcmVzdWx0LnNldChDYWxlbmRhci5NT05USCwgbW9udGggLSAxKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIC8vIHVzZSBkZWZhdWx0IGlmIHNldAotICAgICAgICAgICAgaW50IGRlZmF1bHRNb250aCA9IChkZWZhdWx0cyAhPSBudWxsKSA/IGRlZmF1bHRzLmdldE1vbnRoKCkgOiBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQ7Ci0gICAgICAgICAgICBpZiAoZGVmYXVsdE1vbnRoICE9IERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCkgewotICAgICAgICAgICAgICAgIC8vIENhbGVuZGFyLk1PTlRIIGlzIHplcm8gYmFzZWQgd2hpbGUgWE1MR3JlZ29yaWFuQ2FsZW5kYXIgbW9udGggZmllbGQgaXMgbm90LgotICAgICAgICAgICAgICAgIHJlc3VsdC5zZXQoQ2FsZW5kYXIuTU9OVEgsIGRlZmF1bHRNb250aCAtIDEpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gb25seSBzZXQgZGF5IGlmIGl0IGlzIHNldAotICAgICAgICBpZiAoZGF5ICE9IERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCkgewotICAgICAgICAgICAgcmVzdWx0LnNldChDYWxlbmRhci5EQVlfT0ZfTU9OVEgsIGRheSk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAvLyB1c2UgZGVmYXVsdCBpZiBzZXQKLSAgICAgICAgICAgIGludCBkZWZhdWx0RGF5ID0gKGRlZmF1bHRzICE9IG51bGwpID8gZGVmYXVsdHMuZ2V0RGF5KCkgOiBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQ7Ci0gICAgICAgICAgICBpZiAoZGVmYXVsdERheSAhPSBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQpIHsKLSAgICAgICAgICAgICAgICByZXN1bHQuc2V0KENhbGVuZGFyLkRBWV9PRl9NT05USCwgZGVmYXVsdERheSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBvbmx5IHNldCBob3VyIGlmIGl0IGlzIHNldAotICAgICAgICBpZiAoaG91ciAhPSBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQpIHsKLSAgICAgICAgICAgIHJlc3VsdC5zZXQoQ2FsZW5kYXIuSE9VUl9PRl9EQVksIGhvdXIpOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgLy8gdXNlIGRlZmF1bHQgaWYgc2V0Ci0gICAgICAgICAgICBpbnQgZGVmYXVsdEhvdXIgPSAoZGVmYXVsdHMgIT0gbnVsbCkgPyBkZWZhdWx0cy5nZXRIb3VyKCkgOiBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQ7Ci0gICAgICAgICAgICBpZiAoZGVmYXVsdEhvdXIgIT0gRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVEKSB7Ci0gICAgICAgICAgICAgICAgcmVzdWx0LnNldChDYWxlbmRhci5IT1VSX09GX0RBWSwgZGVmYXVsdEhvdXIpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gb25seSBzZXQgbWludXRlIGlmIGl0IGlzIHNldAotICAgICAgICBpZiAobWludXRlICE9IERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCkgewotICAgICAgICAgICAgcmVzdWx0LnNldChDYWxlbmRhci5NSU5VVEUsIG1pbnV0ZSk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAvLyB1c2UgZGVmYXVsdCBpZiBzZXQKLSAgICAgICAgICAgIGludCBkZWZhdWx0TWludXRlID0gKGRlZmF1bHRzICE9IG51bGwpID8gZGVmYXVsdHMuZ2V0TWludXRlKCkgOiBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQ7Ci0gICAgICAgICAgICBpZiAoZGVmYXVsdE1pbnV0ZSAhPSBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQpIHsKLSAgICAgICAgICAgICAgICByZXN1bHQuc2V0KENhbGVuZGFyLk1JTlVURSwgZGVmYXVsdE1pbnV0ZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBvbmx5IHNldCBzZWNvbmQgaWYgaXQgaXMgc2V0Ci0gICAgICAgIGlmIChzZWNvbmQgIT0gRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVEKSB7Ci0gICAgICAgICAgICByZXN1bHQuc2V0KENhbGVuZGFyLlNFQ09ORCwgc2Vjb25kKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIC8vIHVzZSBkZWZhdWx0IGlmIHNldAotICAgICAgICAgICAgaW50IGRlZmF1bHRTZWNvbmQgPSAoZGVmYXVsdHMgIT0gbnVsbCkgPyBkZWZhdWx0cy5nZXRTZWNvbmQoKSA6IERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRDsKLSAgICAgICAgICAgIGlmIChkZWZhdWx0U2Vjb25kICE9IERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCkgewotICAgICAgICAgICAgICAgIHJlc3VsdC5zZXQoQ2FsZW5kYXIuU0VDT05ELCBkZWZhdWx0U2Vjb25kKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIG9ubHkgc2V0IG1pbGxpc2VuZCBpZiBpdCBpcyBzZXQKLSAgICAgICAgaWYgKGZyYWN0aW9uYWxTZWNvbmQgIT0gbnVsbCkgewotICAgICAgICAgICAgcmVzdWx0LnNldChDYWxlbmRhci5NSUxMSVNFQ09ORCwgZ2V0TWlsbGlzZWNvbmQoKSk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAvLyB1c2UgZGVmYXVsdCBpZiBzZXQKLSAgICAgICAgICAgIEJpZ0RlY2ltYWwgZGVmYXVsdEZyYWN0aW9uYWxTZWNvbmQgPSAoZGVmYXVsdHMgIT0gbnVsbCkgPyBkZWZhdWx0cy5nZXRGcmFjdGlvbmFsU2Vjb25kKCkgOiBudWxsOwotICAgICAgICAgICAgaWYgKGRlZmF1bHRGcmFjdGlvbmFsU2Vjb25kICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICByZXN1bHQuc2V0KENhbGVuZGFyLk1JTExJU0VDT05ELCBkZWZhdWx0cy5nZXRNaWxsaXNlY29uZCgpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiByZXN1bHQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+UmV0dXJucyBhIDxjb2RlPmphdmEudXRpbC5UaW1lWm9uZTwvY29kZT4gZm9yIHRoaXMgY2xhc3MuPC9wPgotICAgICAqCi0gICAgICogPHA+SWYgdGltZXpvbmUgZmllbGQgaXMgZGVmaW5lZCBmb3IgdGhpcyBpbnN0YW5jZSwKLSAgICAgKiByZXR1cm5zIFRpbWVab25lIGluaXRpYWxpemVkIHdpdGggY3VzdG9tIHRpbWV6b25lIGlkCi0gICAgICogb2Ygem9uZW9mZnNldC4gSWYgdGltZXpvbmUgZmllbGQgaXMgdW5kZWZpbmVkLAotICAgICAqIHRyeSB0aGUgZGVmYXVsdFpvbmVvZmZzZXQgdGhhdCB3YXMgcGFzc2VkIGluLgotICAgICAqIElmIGRlZmF1bHRab25lb2Zmc2V0IGlzIERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCwgcmV0dXJuCi0gICAgICogZGVmYXVsdCB0aW1lem9uZSBmb3IgdGhpcyBob3N0LgotICAgICAqIChTYW1lIGRlZmF1bHQgYXMgamF2YS51dGlsLkdyZWdvcmlhbkNhbGVuZGFyKS48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gZGVmYXVsdFpvbmVvZmZzZXQgZGVmYXVsdCB6b25lb2Zmc2V0IGlmIHRoaXMgem9uZW9mZnNldCBpcwotICAgICAqIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNGSUVMRF9VTkRFRklORUR9LgotICAgICAqCi0gICAgICogQHJldHVybiBUaW1lWm9uZSBmb3IgdGhpcy4KLSAgICAgKi8KLSAgICBwdWJsaWMgVGltZVpvbmUgZ2V0VGltZVpvbmUoaW50IGRlZmF1bHRab25lb2Zmc2V0KSB7Ci0gICAgICAgIFRpbWVab25lIHJlc3VsdCA9IG51bGw7Ci0gICAgICAgIGludCB6b25lb2Zmc2V0ID0gZ2V0VGltZXpvbmUoKTsKLQotICAgICAgICBpZiAoem9uZW9mZnNldCA9PSBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQpIHsKLSAgICAgICAgICAgIHpvbmVvZmZzZXQgPSBkZWZhdWx0Wm9uZW9mZnNldDsKLSAgICAgICAgfQotICAgICAgICBpZiAoem9uZW9mZnNldCA9PSBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQpIHsKLSAgICAgICAgICAgIHJlc3VsdCA9IFRpbWVab25lLmdldERlZmF1bHQoKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIC8vIHpvbmVvZmZzZXQgaXMgaW4gbWludXRlcy4gQ29udmVydCB0byBjdXN0b20gdGltZXpvbmUgaWQgZm9ybWF0LgotICAgICAgICAgICAgY2hhciBzaWduID0gem9uZW9mZnNldCA8IDAgPyAnLScgOiAnKyc7Ci0gICAgICAgICAgICBpZiAoc2lnbiA9PSAnLScpIHsKLSAgICAgICAgICAgICAgICB6b25lb2Zmc2V0ID0gLXpvbmVvZmZzZXQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpbnQgaG91ciA9IHpvbmVvZmZzZXQgLyA2MDsKLSAgICAgICAgICAgIGludCBtaW51dGVzID0gem9uZW9mZnNldCAtIChob3VyICogNjApOwotCi0gICAgICAgICAgICAvLyBKYXZhZG9jIGZvciBqYXZhLnV0aWwuVGltZVpvbmUgZG9jdW1lbnRzIG1heCBsZW5ndGgKLSAgICAgICAgICAgIC8vIGZvciBjdXN0b21UaW1lem9uZUlkIGlzIDggd2hlbiBvcHRpb25hbCAnOicgaXMgbm90IHVzZWQuCi0gICAgICAgICAgICAvLyBGb3JtYXQgaXMKLSAgICAgICAgICAgIC8vICJHTVQiICgnLSd8JycrJykgKGRpZ2l0IGRpZ2l0PykgKGRpZ2l0IGRpZ2l0KT8KLSAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgICAgIGhvdXIgICAgICAgICAgbWludXRlcwotICAgICAgICAgICAgU3RyaW5nQnVmZmVyIGN1c3RvbVRpbWV6b25lSWQgPSBuZXcgU3RyaW5nQnVmZmVyKDgpOwotICAgICAgICAgICAgY3VzdG9tVGltZXpvbmVJZC5hcHBlbmQoIkdNVCIpOwotICAgICAgICAgICAgY3VzdG9tVGltZXpvbmVJZC5hcHBlbmQoc2lnbik7Ci0gICAgICAgICAgICBjdXN0b21UaW1lem9uZUlkLmFwcGVuZChob3VyKTsKLSAgICAgICAgICAgIGlmIChtaW51dGVzICE9IDApIHsKLSAgICAgICAgICAgICAgICBpZiAobWludXRlcyA8IDEwKSB7Ci0gICAgICAgICAgICAgICAgICAgIGN1c3RvbVRpbWV6b25lSWQuYXBwZW5kKCcwJyk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGN1c3RvbVRpbWV6b25lSWQuYXBwZW5kKG1pbnV0ZXMpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmVzdWx0ID0gVGltZVpvbmUuZ2V0VGltZVpvbmUoY3VzdG9tVGltZXpvbmVJZC50b1N0cmluZygpKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gcmVzdWx0OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPkNyZWF0ZXMgYW5kIHJldHVybnMgYSBjb3B5IG9mIHRoaXMgb2JqZWN0LjwvcD4KLSAgICAgKgotICAgICAqIEByZXR1cm4gY29weSBvZiB0aGlzIDxjb2RlPk9iamVjdDwvY29kZT4KLSAgICAgKi8KLSAgIHB1YmxpYyBPYmplY3QgY2xvbmUoKSB7Ci0gICAgICAgIC8vIEJvdGggdGhpcy5lb24gYW5kIHRoaXMuZnJhY3Rpb25hbFNlY29uZCBhcmUgaW5zdGFuY2VzCi0gICAgICAgIC8vIG9mIGltbXV0YWJsZSBjbGFzc2VzLCBzbyB0aGV5IGRvIG5vdCBuZWVkIHRvIGJlIGNsb25lZC4KLSAgICAgICByZXR1cm4gbmV3IFhNTEdyZWdvcmlhbkNhbGVuZGFySW1wbChnZXRFb25BbmRZZWFyKCksCi0gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm1vbnRoLCB0aGlzLmRheSwKLSAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaG91ciwgdGhpcy5taW51dGUsIHRoaXMuc2Vjb25kLAotICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5mcmFjdGlvbmFsU2Vjb25kLAotICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy50aW1lem9uZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+VW5zZXQgYWxsIGZpZWxkcyB0byB1bmRlZmluZWQuPC9wPgotICAgICAqCi0gICAgICogPHA+U2V0IGFsbCBpbnQgZmllbGRzIHRvIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNGSUVMRF9VTkRFRklORUR9IGFuZCByZWZlcmVuY2UgZmllbGRzCi0gICAgICogdG8gbnVsbC48L3A+Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgY2xlYXIoKSB7Ci0gICAgICAgIGVvbiA9IG51bGw7Ci0gICAgICAgIHllYXIgPSBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQ7Ci0gICAgICAgIG1vbnRoID0gRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVEOwotICAgICAgICBkYXkgPSBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQ7Ci0gICAgICAgIHRpbWV6b25lID0gRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVEOyAgLy8gaW4gbWludXRlcwotICAgICAgICBob3VyID0gRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVEOwotICAgICAgICBtaW51dGUgPSBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQ7Ci0gICAgICAgIHNlY29uZCA9IERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRDsKLSAgICAgICAgZnJhY3Rpb25hbFNlY29uZCA9IG51bGw7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0TWlsbGlzZWNvbmQoaW50IG1pbGxpc2Vjb25kKSB7Ci0gICAgICAgIGlmIChtaWxsaXNlY29uZCA9PSBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQpIHsKLSAgICAgICAgICAgIGZyYWN0aW9uYWxTZWNvbmQgPSBudWxsOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgaWYobWlsbGlzZWNvbmQ8MCB8fCA5OTk8bWlsbGlzZWNvbmQpCi0gICAgICAgICAgICAgICAgaWYobWlsbGlzZWNvbmQhPURhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCkKLSAgICAgICAgICAgICAgICAgICAgaW52YWxpZEZpZWxkVmFsdWUoTUlMTElTRUNPTkQsIG1pbGxpc2Vjb25kKTsKLSAgICAgICAgICAgIGZyYWN0aW9uYWxTZWNvbmQgPSBuZXcgQmlnRGVjaW1hbCgobG9uZykgbWlsbGlzZWNvbmQpLm1vdmVQb2ludExlZnQoMyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRGcmFjdGlvbmFsU2Vjb25kKEJpZ0RlY2ltYWwgZnJhY3Rpb25hbCkgewotICAgICAgICBpZiAoZnJhY3Rpb25hbCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAoKGZyYWN0aW9uYWwuY29tcGFyZVRvKERFQ0lNQUxfWkVSTykgPCAwKSB8fAotICAgICAgICAgICAgICAgICAgICAoZnJhY3Rpb25hbC5jb21wYXJlVG8oREVDSU1BTF9PTkUpID4gMCkpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKERhdGF0eXBlTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKG51bGwsCi0gICAgICAgICAgICAgICAgICAgICAgICAiSW52YWxpZEZyYWN0aW9uYWwiLCBuZXcgT2JqZWN0W117ZnJhY3Rpb25hbH0pKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICB0aGlzLmZyYWN0aW9uYWxTZWNvbmQgPSBmcmFjdGlvbmFsOwotICAgIH0KLQotICAgIHByaXZhdGUgZmluYWwgY2xhc3MgUGFyc2VyIHsKLSAgICAgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgZm9ybWF0OwotICAgICAgICBwcml2YXRlIGZpbmFsIFN0cmluZyB2YWx1ZTsKLQotICAgICAgICBwcml2YXRlIGZpbmFsIGludCBmbGVuOwotICAgICAgICBwcml2YXRlIGZpbmFsIGludCB2bGVuOwotCi0gICAgICAgIHByaXZhdGUgaW50IGZpZHg7Ci0gICAgICAgIHByaXZhdGUgaW50IHZpZHg7Ci0KLSAgICAgICAgcHJpdmF0ZSBQYXJzZXIoU3RyaW5nIGZvcm1hdCwgU3RyaW5nIHZhbHVlKSB7Ci0gICAgICAgICAgICB0aGlzLmZvcm1hdCA9IGZvcm1hdDsKLSAgICAgICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKLSAgICAgICAgICAgIHRoaXMuZmxlbiA9IGZvcm1hdC5sZW5ndGgoKTsKLSAgICAgICAgICAgIHRoaXMudmxlbiA9IHZhbHVlLmxlbmd0aCgpOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIDxwPlBhcnNlIGEgZm9ybWF0ZWQgPGNvZGU+U3RyaW5nPC9jb2RlPiBpbnRvIGFuIDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPi48L3A+Ci0gICAgICAgICAqCi0gICAgICAgICAqIDxwPklmIDxjb2RlPlN0cmluZzwvY29kZT4gaXMgbm90IGZvcm1hdGVkIGFzIGEgbGVnYWwgPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IHZhbHVlLAotICAgICAgICAgKiBhbiA8Y29kZT5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb248L2NvZGU+IGlzIHRocm93bi48L3A+Ci0gICAgICAgICAqCi0gICAgICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIElmIDxjb2RlPlN0cmluZzwvY29kZT4gaXMgbm90IGZvcm1hdGVkIGFzIGEgbGVnYWwgPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IHZhbHVlLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIHZvaWQgcGFyc2UoKSB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHsKLSAgICAgICAgICAgIHdoaWxlIChmaWR4IDwgZmxlbikgewotICAgICAgICAgICAgICAgIGNoYXIgZmNoID0gZm9ybWF0LmNoYXJBdChmaWR4KyspOwotCi0gICAgICAgICAgICAgICAgaWYgKGZjaCAhPSAnJScpIHsgLy8gbm90IGEgbWV0YSBjaGFyYWN0ZXIKLSAgICAgICAgICAgICAgICAgICAgc2tpcChmY2gpOwotICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyBzZWVuIG1ldGEgY2hhcmFjdGVyLiB3ZSBkb24ndCBkbyBlcnJvciBjaGVjayBhZ2FpbnN0IHRoZSBmb3JtYXQKLSAgICAgICAgICAgICAgICBzd2l0Y2ggKGZvcm1hdC5jaGFyQXQoZmlkeCsrKSkgewotICAgICAgICAgICAgICAgICAgICBjYXNlICdZJyA6IC8vIHllYXIKLSAgICAgICAgICAgICAgICAgICAgICAgIHBhcnNlQW5kU2V0WWVhcig0KTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgICAgICAgICAgICAgIGNhc2UgJ00nIDogLy8gbW9udGgKLSAgICAgICAgICAgICAgICAgICAgICAgIHNldE1vbnRoKHBhcnNlSW50KDIsIDIpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgICAgICAgICAgICAgIGNhc2UgJ0QnIDogLy8gZGF5cwotICAgICAgICAgICAgICAgICAgICAgICAgc2V0RGF5KHBhcnNlSW50KDIsIDIpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgICAgICAgICAgICAgIGNhc2UgJ2gnIDogLy8gaG91cnMKLSAgICAgICAgICAgICAgICAgICAgICAgIHNldEhvdXIocGFyc2VJbnQoMiwgMiksIGZhbHNlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgICAgICAgICAgICAgIGNhc2UgJ20nIDogLy8gbWludXRlcwotICAgICAgICAgICAgICAgICAgICAgICAgc2V0TWludXRlKHBhcnNlSW50KDIsIDIpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgICAgICAgICAgICAgIGNhc2UgJ3MnIDogLy8gcGFyc2Ugc2Vjb25kcy4KLSAgICAgICAgICAgICAgICAgICAgICAgIHNldFNlY29uZChwYXJzZUludCgyLCAyKSk7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwZWVrKCkgPT0gJy4nKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0RnJhY3Rpb25hbFNlY29uZChwYXJzZUJpZ0RlY2ltYWwoKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLQotICAgICAgICAgICAgICAgICAgICBjYXNlICd6JyA6IC8vIHRpbWUgem9uZS4gbWlzc2luZywgJ1onLCBvciBbKy1dbm46bm4KLSAgICAgICAgICAgICAgICAgICAgICAgIGNoYXIgdmNoID0gcGVlaygpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHZjaCA9PSAnWicpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWR4Kys7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0VGltZXpvbmUoMCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHZjaCA9PSAnKycgfHwgdmNoID09ICctJykgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZHgrKzsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaCA9IHBhcnNlSW50KDIsIDIpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNraXAoJzonKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbSA9IHBhcnNlSW50KDIsIDIpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldFRpbWV6b25lKChoICogNjAgKyBtKSAqICh2Y2ggPT0gJysnID8gMSA6IC0xKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQgOgotICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWxsZWdhbCBtZXRhIGNoYXJhY3Rlci4gaW1wb3NzaWJsZS4KLSAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAodmlkeCAhPSB2bGVuKSB7Ci0gICAgICAgICAgICAgICAgLy8gc29tZSB0b2tlbnMgYXJlIGxlZnQgaW4gdGhlIGlucHV0Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbih2YWx1ZSk7IC8vLHZpZHgpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgdGVzdEhvdXIoKTsKLSAgICAgICAgfQotCi0gICAgICAgIHByaXZhdGUgY2hhciBwZWVrKCkgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICBpZiAodmlkeCA9PSB2bGVuKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIChjaGFyKSAtMTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiB2YWx1ZS5jaGFyQXQodmlkeCk7Ci0gICAgICAgIH0KLQotICAgICAgICBwcml2YXRlIGNoYXIgcmVhZCgpIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gewotICAgICAgICAgICAgaWYgKHZpZHggPT0gdmxlbikgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24odmFsdWUpOyAvLyx2aWR4KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiB2YWx1ZS5jaGFyQXQodmlkeCsrKTsKLSAgICAgICAgfQotCi0gICAgICAgIHByaXZhdGUgdm9pZCBza2lwKGNoYXIgY2gpIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gewotICAgICAgICAgICAgaWYgKHJlYWQoKSAhPSBjaCkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24odmFsdWUpOyAvLyx2aWR4LTEpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgcHJpdmF0ZSBpbnQgcGFyc2VJbnQoaW50IG1pbkRpZ2l0cywgaW50IG1heERpZ2l0cykKLSAgICAgICAgICAgIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gewotCi0gICAgICAgICAgICBpbnQgbiA9IDA7Ci0gICAgICAgICAgICBjaGFyIGNoOwotICAgICAgICAgICAgaW50IHZzdGFydCA9IHZpZHg7Ci0gICAgICAgICAgICB3aGlsZSAoaXNEaWdpdChjaD1wZWVrKCkpICYmICh2aWR4IC0gdnN0YXJ0KSA8PSBtYXhEaWdpdHMpIHsKLSAgICAgICAgICAgICAgICB2aWR4Kys7Ci0gICAgICAgICAgICAgICAgbiA9IG4qMTAgKyBjaC0nMCc7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoKHZpZHggLSB2c3RhcnQpIDwgbWluRGlnaXRzKSB7Ci0gICAgICAgICAgICAgICAgLy8gd2UgYXJlIGV4cGVjdGluZyBtb3JlIGRpZ2l0cwotICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24odmFsdWUpOyAvLyx2aWR4KTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgcmV0dXJuIG47Ci0gICAgICAgIH0KLQotICAgICAgICBwcml2YXRlIHZvaWQgcGFyc2VBbmRTZXRZZWFyKGludCBtaW5EaWdpdHMpCi0gICAgICAgICAgICAgICAgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICBpbnQgdnN0YXJ0ID0gdmlkeDsKLSAgICAgICAgICAgIGludCBuID0gMDsKLSAgICAgICAgICAgIGJvb2xlYW4gbmVnID0gZmFsc2U7Ci0KLSAgICAgICAgICAgIC8vIHNraXAgbGVhZGluZyBuZWdhdGl2ZSwgaWYgaXQgZXhpc3RzCi0gICAgICAgICAgICBpZiAocGVlaygpID09ICctJykgewotICAgICAgICAgICAgICAgIHZpZHgrKzsKLSAgICAgICAgICAgICAgICBuZWcgPSB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgd2hpbGUodHJ1ZSkgewotICAgICAgICAgICAgICAgIGNoYXIgY2ggPSBwZWVrKCk7Ci0gICAgICAgICAgICAgICAgaWYoIWlzRGlnaXQoY2gpKQotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICB2aWR4Kys7Ci0gICAgICAgICAgICAgICAgbiA9IG4qMTAgKyBjaC0nMCc7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmICgodmlkeCAtIHZzdGFydCkgPCBtaW5EaWdpdHMpIHsKLSAgICAgICAgICAgICAgICAvLyB3ZSBhcmUgZXhwZWN0aW5nIG1vcmUgZGlnaXRzCi0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbih2YWx1ZSk7IC8vLHZpZHgpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZih2aWR4LXZzdGFydDw3KSB7Ci0gICAgICAgICAgICAgICAgLy8gZGVmaW5pdGVseSBpbnQgb25seS4gSSBkb24ndCBrbm93IHRoZSBleGFjdCAjIG9mIGRpZ2l0cyB0aGF0IGNhbiBiZSBpbiBpbnQsCi0gICAgICAgICAgICAgICAgLy8gYnV0IGFzIGxvbmcgYXMgd2UgY2FuIGNhdGNoICgwLTk5OTkpIHJhbmdlLCB0aGF0IHNob3VsZCBiZSBlbm91Z2guCi0gICAgICAgICAgICAgICAgaWYobmVnKSAgICAgbiA9IC1uOwotICAgICAgICAgICAgICAgIHllYXIgPSBuOwotICAgICAgICAgICAgICAgIGVvbiA9IG51bGw7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIHNldFllYXIobmV3IEJpZ0ludGVnZXIodmFsdWUuc3Vic3RyaW5nKHZzdGFydCwgdmlkeCkpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHByaXZhdGUgQmlnRGVjaW1hbCBwYXJzZUJpZ0RlY2ltYWwoKQotICAgICAgICAgICAgICAgIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gewotICAgICAgICAgICAgaW50IHZzdGFydCA9IHZpZHg7Ci0KLSAgICAgICAgICAgIGlmIChwZWVrKCkgPT0gJy4nKSB7Ci0gICAgICAgICAgICAgICAgdmlkeCsrOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKHZhbHVlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHdoaWxlIChpc0RpZ2l0KHBlZWsoKSkpIHsKLSAgICAgICAgICAgICAgICB2aWR4Kys7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gbmV3IEJpZ0RlY2ltYWwodmFsdWUuc3Vic3RyaW5nKHZzdGFydCwgdmlkeCkpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBpc0RpZ2l0KGNoYXIgY2gpIHsKLSAgICAgICAgcmV0dXJuICcwJyA8PSBjaCAmJiBjaCA8PSAnOSc7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUHJpbnRzIHRoaXMgb2JqZWN0IGFjY29yZGluZyB0byB0aGUgZm9ybWF0IHNwZWNpZmljYXRpb24uCi0gICAgICoKLSAgICAgKiA8cD4KLSAgICAgKiBJIHdyb3RlIGEgY3VzdG9tIGZvcm1hdCBtZXRob2QgZm9yIGEgcGFydGljdWxhciBmb3JtYXQgc3RyaW5nIHRvCi0gICAgICogc2VlIGlmIGl0IGltcHJvdmVzIHRoZSBwZXJmb3JtYW5jZSwgYnV0IGl0IGRpZG4ndC4gU28gdGhpcyBpbnRlcnByZXRpbmcKLSAgICAgKiBhcHByb2FjaCBpc24ndCB0b28gYmFkLgotICAgICAqCi0gICAgICogPHA+Ci0gICAgICogU3RyaW5nQnVmZmVyIC0+IFN0cmluZ0J1aWxkZXIgY2hhbmdlIGhhZCBhIHZlcnkgdmlzaWJsZSBpbXBhY3QuCi0gICAgICogSXQgYWxtb3N0IGN1dCB0aGUgZXhlY3V0aW9uIHRpbWUgdG8gaGFsZiwgYnV0IHVuZm9ydHVuYXRlbHkgd2UgY2FuJ3QgdXNlIGl0Ci0gICAgICogYmVjYXVzZSB3ZSBuZWVkIHRvIHJ1biBvbiBKREsgMS4zCi0gICAgICovCi0gICAgcHJpdmF0ZSBTdHJpbmcgZm9ybWF0KCBTdHJpbmcgZm9ybWF0ICkgewotICAgICAgICBjaGFyW10gYnVmID0gbmV3IGNoYXJbMzJdOwotICAgICAgICBpbnQgYnVmUHRyID0gMDsKLQotICAgICAgICBpbnQgZmlkeD0wLGZsZW49Zm9ybWF0Lmxlbmd0aCgpOwotCi0gICAgICAgIHdoaWxlKGZpZHg8ZmxlbikgewotICAgICAgICAgICAgY2hhciBmY2ggPSBmb3JtYXQuY2hhckF0KGZpZHgrKyk7Ci0gICAgICAgICAgICBpZihmY2ghPSclJykgey8vIG5vdCBhIG1ldGEgY2hhcgotICAgICAgICAgICAgICAgIGJ1ZltidWZQdHIrK10gPSBmY2g7Ci0gICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIHN3aXRjaChmb3JtYXQuY2hhckF0KGZpZHgrKykpIHsKLSAgICAgICAgICAgIGNhc2UgJ1knOgotICAgICAgICAgICAgICAgIGlmKGVvbj09bnVsbCkgewotICAgICAgICAgICAgICAgICAgICAvLyBvcHRpbWl6ZWQgcGF0aAotICAgICAgICAgICAgICAgICAgICBpbnQgeSA9IGdldFllYXIoKTsKLSAgICAgICAgICAgICAgICAgICAgaWYoeTwwKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBidWZbYnVmUHRyKytdID0gJy0nOwotICAgICAgICAgICAgICAgICAgICAgICAgeSA9IC15OwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGJ1ZlB0ciA9IHByaW50NE51bWJlcihidWYsYnVmUHRyLHkpOwotICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIFN0cmluZyBzID0gZ2V0RW9uQW5kWWVhcigpLnRvU3RyaW5nKCk7Ci0gICAgICAgICAgICAgICAgICAgIC8vIHJlYWxsb2NhdGUgdGhlIGJ1ZmZlciBub3cgc28gdGhhdCBpdCBoYXMgZW5vdWdoIHNwYWNlCi0gICAgICAgICAgICAgICAgICAgIGNoYXJbXSBuID0gbmV3IGNoYXJbYnVmLmxlbmd0aCtzLmxlbmd0aCgpXTsKLSAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShidWYsMCxuLDAsYnVmUHRyKTsKLSAgICAgICAgICAgICAgICAgICAgYnVmID0gbjsKLSAgICAgICAgICAgICAgICAgICAgZm9yKGludCBpPXMubGVuZ3RoKCk7aTw0O2krKykKLSAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZltidWZQdHIrK10gPSAnMCc7Ci0gICAgICAgICAgICAgICAgICAgIHMuZ2V0Q2hhcnMoMCxzLmxlbmd0aCgpLGJ1ZixidWZQdHIpOwotICAgICAgICAgICAgICAgICAgICBidWZQdHIgKz0gcy5sZW5ndGgoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICBjYXNlICdNJzoKLSAgICAgICAgICAgICAgICBidWZQdHIgPSBwcmludDJOdW1iZXIoYnVmLGJ1ZlB0cixnZXRNb250aCgpKTsKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIGNhc2UgJ0QnOgotICAgICAgICAgICAgICAgIGJ1ZlB0ciA9IHByaW50Mk51bWJlcihidWYsYnVmUHRyLGdldERheSgpKTsKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIGNhc2UgJ2gnOgotICAgICAgICAgICAgICAgIGJ1ZlB0ciA9IHByaW50Mk51bWJlcihidWYsYnVmUHRyLGdldEhvdXIoKSk7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICBjYXNlICdtJzoKLSAgICAgICAgICAgICAgICBidWZQdHIgPSBwcmludDJOdW1iZXIoYnVmLGJ1ZlB0cixnZXRNaW51dGUoKSk7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICBjYXNlICdzJzoKLSAgICAgICAgICAgICAgICBidWZQdHIgPSBwcmludDJOdW1iZXIoYnVmLGJ1ZlB0cixnZXRTZWNvbmQoKSk7Ci0gICAgICAgICAgICAgICAgaWYgKGdldEZyYWN0aW9uYWxTZWNvbmQoKSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIE5vdGU6IHRvUGxhaW5TdHJpbmcoKSBpc24ndCBhdmFpbGFibGUgYmVmb3JlIEphdmEgMS41Ci0gICAgICAgICAgICAgICAgICAgIFN0cmluZyBmcmFjID0gZ2V0RnJhY3Rpb25hbFNlY29uZCgpLnRvU3RyaW5nKCk7Ci0KLSAgICAgICAgICAgICAgICAgICAgaW50IHBvcyA9IGZyYWMuaW5kZXhPZigiRS0iKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKHBvcyA+PSAwKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgemVyb3MgPSBmcmFjLnN1YnN0cmluZyhwb3MrMik7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmcmFjID0gZnJhYy5zdWJzdHJpbmcoMCxwb3MpOwotICAgICAgICAgICAgICAgICAgICAgICAgcG9zID0gZnJhYy5pbmRleE9mKCIuIik7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAocG9zID49IDApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcmFjID0gZnJhYy5zdWJzdHJpbmcoMCxwb3MpICsgZnJhYy5zdWJzdHJpbmcocG9zKzEpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgaW50IGNvdW50ID0gSW50ZWdlci5wYXJzZUludCh6ZXJvcyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY291bnQgPCA0MCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyYWMgPSAiMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAiLnN1YnN0cmluZygwLGNvdW50LTEpICsgZnJhYzsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZG8gaXQgdGhlIGhhcmQgd2F5Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGNvdW50ID4gMSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcmFjID0gIjAiICsgZnJhYzsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY291bnQtLTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBmcmFjID0gIjAuIiArIGZyYWM7Ci0gICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAvLyByZWFsbG9jYXRlIHRoZSBidWZmZXIgbm93IHNvIHRoYXQgaXQgaGFzIGVub3VnaCBzcGFjZQotICAgICAgICAgICAgICAgICAgICBjaGFyW10gbiA9IG5ldyBjaGFyW2J1Zi5sZW5ndGgrZnJhYy5sZW5ndGgoKV07Ci0gICAgICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYnVmLDAsbiwwLGJ1ZlB0cik7Ci0gICAgICAgICAgICAgICAgICAgIGJ1ZiA9IG47Ci0gICAgICAgICAgICAgICAgICAgIC8vc2tpcCBsZWFkaW5nIHplcm8uCi0gICAgICAgICAgICAgICAgICAgIGZyYWMuZ2V0Q2hhcnMoMSwgZnJhYy5sZW5ndGgoKSwgYnVmLCBidWZQdHIpOwotICAgICAgICAgICAgICAgICAgICBidWZQdHIgKz0gZnJhYy5sZW5ndGgoKS0xOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIGNhc2UgJ3onOgotICAgICAgICAgICAgICAgIGludCBvZmZzZXQgPSBnZXRUaW1lem9uZSgpOwotICAgICAgICAgICAgICAgIGlmIChvZmZzZXQgPT0gMCkgewotICAgICAgICAgICAgICAgICAgICBidWZbYnVmUHRyKytdID0gJ1onOwotICAgICAgICAgICAgICAgIH0gZWxzZQotICAgICAgICAgICAgICAgIGlmIChvZmZzZXQgIT0gRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVEKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBidWZbYnVmUHRyKytdID0gJy0nOwotICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0ICo9IC0xOwotICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgYnVmW2J1ZlB0cisrXSA9ICcrJzsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBidWZQdHIgPSBwcmludDJOdW1iZXIoYnVmLCBidWZQdHIsIG9mZnNldCAvIDYwKTsKLSAgICAgICAgICAgICAgICAgICAgYnVmW2J1ZlB0cisrXSA9ICc6JzsKLSAgICAgICAgICAgICAgICAgICAgYnVmUHRyID0gcHJpbnQyTnVtYmVyKGJ1ZiwgYnVmUHRyLCBvZmZzZXQgJSA2MCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgZGVmYXVsdDoKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcigpOyAgLy8gaW1wb3NzaWJsZQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIG5ldyBTdHJpbmcoYnVmLDAsYnVmUHRyKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBQcmludHMgYW4gaW50IGFzIHR3byBkaWdpdHMgaW50byB0aGUgYnVmZmVyLgotICAgICAqCi0gICAgICogQHBhcmFtIG51bWJlcgotICAgICAqICAgICAgTnVtYmVyIHRvIGJlIHByaW50ZWQuIE11c3QgYmUgcG9zaXRpdmUuCi0gICAgICovCi0gICAgcHJpdmF0ZSBpbnQgcHJpbnQyTnVtYmVyKCBjaGFyW10gb3V0LCBpbnQgYnVmcHRyLCBpbnQgbnVtYmVyICkgewotICAgICAgICBvdXRbYnVmcHRyKytdID0gKGNoYXIpICgnMCcrKG51bWJlci8xMCkpOwotICAgICAgICBvdXRbYnVmcHRyKytdID0gKGNoYXIpICgnMCcrKG51bWJlciUxMCkpOwotICAgICAgICByZXR1cm4gYnVmcHRyOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFByaW50cyBhbiBpbnQgYXMgZm91ciBkaWdpdHMgaW50byB0aGUgYnVmZmVyLgotICAgICAqCi0gICAgICogQHBhcmFtIG51bWJlcgotICAgICAqICAgICAgTnVtYmVyIHRvIGJlIHByaW50ZWQuIE11c3QgYmUgcG9zaXRpdmUuCi0gICAgICovCi0gICAgcHJpdmF0ZSBpbnQgcHJpbnQ0TnVtYmVyKCBjaGFyW10gb3V0LCBpbnQgYnVmcHRyLCBpbnQgbnVtYmVyICkgewotICAgICAgICBvdXRbYnVmcHRyKzNdID0gKGNoYXIpICgnMCcrKG51bWJlciUxMCkpOwotICAgICAgICBudW1iZXIgLz0gMTA7Ci0gICAgICAgIG91dFtidWZwdHIrMl0gPSAoY2hhcikgKCcwJysobnVtYmVyJTEwKSk7Ci0gICAgICAgIG51bWJlciAvPSAxMDsKLSAgICAgICAgb3V0W2J1ZnB0cisxXSA9IChjaGFyKSAoJzAnKyhudW1iZXIlMTApKTsKLSAgICAgICAgbnVtYmVyIC89IDEwOwotICAgICAgICBvdXRbYnVmcHRyICBdID0gKGNoYXIpICgnMCcrKG51bWJlciUxMCkpOwotICAgICAgICByZXR1cm4gYnVmcHRyKzQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29tcHV0ZSA8Y29kZT52YWx1ZSpzaWdudW08L2NvZGU+IHdoZXJlIHZhbHVlPT1udWxsIGlzIHRyZWF0ZWQgYXMKLSAgICAgKiB2YWx1ZT09MC4KLSAgICAgKiBAcmV0dXJuIG5vbi1udWxsIHtAbGluayBCaWdJbnRlZ2VyfS4KLSAgICAgKi8KLSAgICBzdGF0aWMgQmlnSW50ZWdlciBzYW5pdGl6ZShOdW1iZXIgdmFsdWUsIGludCBzaWdudW0pIHsKLSAgICAgICAgaWYgKHNpZ251bSA9PSAwIHx8IHZhbHVlID09IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBCaWdJbnRlZ2VyLlpFUk87Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIChzaWdudW0gPCAgMCk/ICgoQmlnSW50ZWdlcil2YWx1ZSkubmVnYXRlKCkgOiAoQmlnSW50ZWdlcil2YWx1ZTsKLSAgICB9Ci0KLSAgICAvKiogPHA+PGNvZGU+cmVzZXQoKTwvY29kZT4gaXMgZGVzaWduZWQgdG8gYWxsb3cgdGhlIHJldXNlIG9mIGV4aXN0aW5nCi0gICAgICogPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+cyB0aHVzIHNhdmluZyByZXNvdXJjZXMgYXNzb2NpYXRlZAotICAgICAqICB3aXRoIHRoZSBjcmVhdGlvbiBvZiBuZXcgPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+cy48L3A+Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgcmVzZXQoKSB7Ci0gICAgICAgIC8vUEVORElORyA6IEltcGxlbWVudGF0aW9uIG9mIHJlc2V0IG1ldGhvZAotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2pheHAvZGF0YXR5cGUvamF2YXgueG1sLmRhdGF0eXBlLkRhdGF0eXBlRmFjdG9yeSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2pheHAvZGF0YXR5cGUvamF2YXgueG1sLmRhdGF0eXBlLkRhdGF0eXBlRmFjdG9yeQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNGE1YzI4Mi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9qYXhwL2RhdGF0eXBlL2phdmF4LnhtbC5kYXRhdHlwZS5EYXRhdHlwZUZhY3RvcnkKKysrIC9kZXYvbnVsbApAQCAtMSArMCwwIEBACi1jb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmpheHAuZGF0YXR5cGUuRGF0YXR5cGVGYWN0b3J5SW1wbApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvamF4cC9qYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvamF4cC9qYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5CmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkYzM5NDQwLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2pheHAvamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyRmFjdG9yeQorKysgL2Rldi9udWxsCkBAIC0xICswLDAgQEAKLWNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuamF4cC5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5SW1wbApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvamF4cC9qYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXJGYWN0b3J5IGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvamF4cC9qYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXJGYWN0b3J5CmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjZDg0MDY5Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2pheHAvamF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyRmFjdG9yeQorKysgL2Rldi9udWxsCkBAIC0xICswLDAgQEAKLWNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuamF4cC5TQVhQYXJzZXJGYWN0b3J5SW1wbApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvamF4cC92YWxpZGF0aW9uL0Fic3RyYWN0WE1MU2NoZW1hLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9qYXhwL3ZhbGlkYXRpb24vQWJzdHJhY3RYTUxTY2hlbWEuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMjVlMTNhNy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9qYXhwL3ZhbGlkYXRpb24vQWJzdHJhY3RYTUxTY2hlbWEuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEwOSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmpheHAudmFsaWRhdGlvbjsKLQotaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwotCi1pbXBvcnQgamF2YXgueG1sLnZhbGlkYXRpb24uU2NoZW1hOwotaW1wb3J0IGphdmF4LnhtbC52YWxpZGF0aW9uLlZhbGlkYXRvcjsKLWltcG9ydCBqYXZheC54bWwudmFsaWRhdGlvbi5WYWxpZGF0b3JIYW5kbGVyOwotCi0vKioKLSAqIDxwPkFic3RyYWN0IGltcGxlbWVudGF0aW9uIG9mIFNjaGVtYSBmb3IgVzNDIFhNTCBTY2hlbWFzLjwvcD4KLSAqCi0gKiBAYXV0aG9yIE1pY2hhZWwgR2xhdmFzc2V2aWNoLCBJQk0KLSAqIEB2ZXJzaW9uICRJZDogQWJzdHJhY3RYTUxTY2hlbWEuamF2YSx2IDEuNiAyMDEwLTExLTAxIDA0OjQwOjA3IGpvZWh3IEV4cCAkCi0gKi8KLWFic3RyYWN0IGNsYXNzIEFic3RyYWN0WE1MU2NoZW1hIGV4dGVuZHMgU2NoZW1hIGltcGxlbWVudHMKLSAgICAgICAgWFNHcmFtbWFyUG9vbENvbnRhaW5lciB7Ci0KLSAgICAvKioKLSAgICAgKiBNYXAgY29udGFpbmluZyB0aGUgaW5pdGlhbCB2YWx1ZXMgb2YgZmVhdHVyZXMgZm9yCi0gICAgICogdmFsaWRhdG9ycyBjcmVhdGVkIHVzaW5nIHRoaXMgZ3JhbW1hciBwb29sIGNvbnRhaW5lci4KLSAgICAgKi8KLSAgICBwcml2YXRlIGZpbmFsIEhhc2hNYXAgZkZlYXR1cmVzOwotCi0gICAgLyoqCi0gICAgICogTWFwIGNvbnRhaW5pbmcgdGhlIGluaXRpYWwgdmFsdWVzIG9mIHByb3BlcnRpZXMgZm9yCi0gICAgICogdmFsaWRhdG9ycyBjcmVhdGVkIHVzaW5nIHRoaXMgZ3JhbW1hciBwb29sIGNvbnRhaW5lci4KLSAgICAgKi8KLSAgICBwcml2YXRlIGZpbmFsIEhhc2hNYXAgZlByb3BlcnRpZXM7Ci0KLSAgICBwdWJsaWMgQWJzdHJhY3RYTUxTY2hlbWEoKSB7Ci0gICAgICAgIGZGZWF0dXJlcyA9IG5ldyBIYXNoTWFwKCk7Ci0gICAgICAgIGZQcm9wZXJ0aWVzID0gbmV3IEhhc2hNYXAoKTsKLSAgICB9Ci0KLSAgICAvKgotICAgICAqIFNjaGVtYSBtZXRob2RzCi0gICAgICovCi0KLSAgICAvKgotICAgICAqIEBzZWUgamF2YXgueG1sLnZhbGlkYXRpb24uU2NoZW1hI25ld1ZhbGlkYXRvcigpCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIFZhbGlkYXRvciBuZXdWYWxpZGF0b3IoKSB7Ci0gICAgICAgIHJldHVybiBuZXcgVmFsaWRhdG9ySW1wbCh0aGlzKTsKLSAgICB9Ci0KLSAgICAvKgotICAgICAqIEBzZWUgamF2YXgueG1sLnZhbGlkYXRpb24uU2NoZW1hI25ld1ZhbGlkYXRvckhhbmRsZXIoKQotICAgICAqLwotICAgIHB1YmxpYyBmaW5hbCBWYWxpZGF0b3JIYW5kbGVyIG5ld1ZhbGlkYXRvckhhbmRsZXIoKSB7Ci0gICAgICAgIHJldHVybiBuZXcgVmFsaWRhdG9ySGFuZGxlckltcGwodGhpcyk7Ci0gICAgfQotCi0gICAgLyoKLSAgICAgKiBYU0dyYW1tYXJQb29sQ29udGFpbmVyIG1ldGhvZHMKLSAgICAgKi8KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIGluaXRpYWwgdmFsdWUgb2YgYSBmZWF0dXJlIGZvciB2YWxpZGF0b3JzIGNyZWF0ZWQKLSAgICAgKiB1c2luZyB0aGlzIGdyYW1tYXIgcG9vbCBjb250YWluZXIgb3IgbnVsbCBpZiB0aGUgdmFsaWRhdG9ycwotICAgICAqIHNob3VsZCB1c2UgdGhlIGRlZmF1bHQgdmFsdWUuCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIEJvb2xlYW4gZ2V0RmVhdHVyZShTdHJpbmcgZmVhdHVyZUlkKSB7Ci0gICAgICAgIHJldHVybiAoQm9vbGVhbikgZkZlYXR1cmVzLmdldChmZWF0dXJlSWQpOwotICAgIH0KLQotICAgIC8qCi0gICAgICogU2V0IGEgZmVhdHVyZSBvbiB0aGUgc2NoZW1hCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIHZvaWQgc2V0RmVhdHVyZShTdHJpbmcgZmVhdHVyZUlkLCBib29sZWFuIHN0YXRlKSB7Ci0gICAgICAgIGZGZWF0dXJlcy5wdXQoZmVhdHVyZUlkLCBzdGF0ZSA/IEJvb2xlYW4uVFJVRSA6IEJvb2xlYW4uRkFMU0UpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIGluaXRpYWwgdmFsdWUgb2YgYSBwcm9wZXJ0eSBmb3IgdmFsaWRhdG9ycyBjcmVhdGVkCi0gICAgICogdXNpbmcgdGhpcyBncmFtbWFyIHBvb2wgY29udGFpbmVyIG9yIG51bGwgaWYgdGhlIHZhbGlkYXRvcnMKLSAgICAgKiBzaG91bGQgdXNlIHRoZSBkZWZhdWx0IHZhbHVlLgotICAgICAqLwotICAgIHB1YmxpYyBmaW5hbCBPYmplY3QgZ2V0UHJvcGVydHkoU3RyaW5nIHByb3BlcnR5SWQpIHsKLSAgICAgICAgcmV0dXJuIGZQcm9wZXJ0aWVzLmdldChwcm9wZXJ0eUlkKTsKLSAgICB9Ci0KLSAgICAvKgotICAgICAqIFNldCBhIHByb3BlcnR5IG9uIHRoZSBzY2hlbWEKLSAgICAgKi8KLSAgICBwdWJsaWMgZmluYWwgdm9pZCBzZXRQcm9wZXJ0eShTdHJpbmcgcHJvcGVydHlJZCwgT2JqZWN0IHN0YXRlKSB7Ci0gICAgICAgIGZQcm9wZXJ0aWVzLnB1dChwcm9wZXJ0eUlkLCBzdGF0ZSk7Ci0gICAgfQotCi19IC8vIEFic3RyYWN0WE1MU2NoZW1hCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9qYXhwL3ZhbGlkYXRpb24vRE9NRG9jdW1lbnRIYW5kbGVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9qYXhwL3ZhbGlkYXRpb24vRE9NRG9jdW1lbnRIYW5kbGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDlmNTE0YTkuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvamF4cC92YWxpZGF0aW9uL0RPTURvY3VtZW50SGFuZGxlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsODkgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5qYXhwLnZhbGlkYXRpb247Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLmRvbS5ET01SZXN1bHQ7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxEb2N1bWVudEhhbmRsZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE5JRXhjZXB0aW9uOwotCi1pbXBvcnQgb3JnLnczYy5kb20uQ0RBVEFTZWN0aW9uOwotaW1wb3J0IG9yZy53M2MuZG9tLkNvbW1lbnQ7Ci1pbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnRUeXBlOwotaW1wb3J0IG9yZy53M2MuZG9tLlByb2Nlc3NpbmdJbnN0cnVjdGlvbjsKLWltcG9ydCBvcmcudzNjLmRvbS5UZXh0OwotCi0vKioKLSAqIDxwPkFuIGV4dGVuc2lvbiB0byBYTUxEb2N1bWVudEhhbmRsZXIgZm9yIGJ1aWxkaW5nIERPTSBzdHJ1Y3R1cmVzLjwvcD4KLSAqCi0gKiBAYXV0aG9yIE1pY2hhZWwgR2xhdmFzc2V2aWNoLCBJQk0KLSAqLwotaW50ZXJmYWNlIERPTURvY3VtZW50SGFuZGxlciBleHRlbmRzIFhNTERvY3VtZW50SGFuZGxlciB7Ci0KLSAgICAvKioKLSAgICAgKiA8cD5TZXRzIHRoZSA8Y29kZT5ET01SZXN1bHQ8L2NvZGU+IG9iamVjdCB3aGljaAotICAgICAqIHJlY2VpdmVzIHRoZSBjb25zdHJ1Y3RlZCBET00gbm9kZXMuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIHJlc3VsdCB0aGUgb2JqZWN0IHdoaWNoIHJlY2VpdmVzIHRoZSBjb25zdHJ1Y3RlZCBET00gbm9kZXMKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRET01SZXN1bHQoRE9NUmVzdWx0IHJlc3VsdCk7Ci0KLSAgICAvKioKLSAgICAgKiBBIGRvY3VtZW50IHR5cGUgZGVjbGFyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbm9kZSBhIERvY3VtZW50VHlwZSBub2RlCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZG9jdHlwZURlY2woRG9jdW1lbnRUeXBlIG5vZGUpIHRocm93cyBYTklFeGNlcHRpb247Ci0KLSAgICBwdWJsaWMgdm9pZCBjaGFyYWN0ZXJzKFRleHQgbm9kZSkgdGhyb3dzIFhOSUV4Y2VwdGlvbjsKLQotICAgIHB1YmxpYyB2b2lkIGNkYXRhKENEQVRBU2VjdGlvbiBub2RlKSB0aHJvd3MgWE5JRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogQSBjb21tZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIG5vZGUgYSBDb21tZW50IG5vZGUKLSAgICAgKgotICAgICAqIEBleGNlcHRpb24gWE5JRXhjZXB0aW9uIFRocm93biBieSBhcHBsaWNhdGlvbiB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY29tbWVudChDb21tZW50IG5vZGUpIHRocm93cyBYTklFeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBBIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24uIFByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb25zIGNvbnNpc3Qgb2YgYQotICAgICAqIHRhcmdldCBuYW1lIGFuZCwgb3B0aW9uYWxseSwgdGV4dCBkYXRhLiBUaGUgZGF0YSBpcyBvbmx5IG1lYW5pbmdmdWwKLSAgICAgKiB0byB0aGUgYXBwbGljYXRpb24uCi0gICAgICogPHA+Ci0gICAgICogVHlwaWNhbGx5LCBhIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24ncyBkYXRhIHdpbGwgY29udGFpbiBhIHNlcmllcwotICAgICAqIG9mIHBzZXVkby1hdHRyaWJ1dGVzLiBUaGVzZSBwc2V1ZG8tYXR0cmlidXRlcyBmb2xsb3cgdGhlIGZvcm0gb2YKLSAgICAgKiBlbGVtZW50IGF0dHJpYnV0ZXMgYnV0IGFyZSA8c3Ryb25nPm5vdDwvc3Ryb25nPiBwYXJzZWQgb3IgcHJlc2VudGVkCi0gICAgICogdG8gdGhlIGFwcGxpY2F0aW9uIGFzIGFueXRoaW5nIG90aGVyIHRoYW4gdGV4dC4gVGhlIGFwcGxpY2F0aW9uIGlzCi0gICAgICogcmVzcG9uc2libGUgZm9yIHBhcnNpbmcgdGhlIGRhdGEuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbm9kZSBhIFByb2Nlc3NpbmdJbnN0cnVjdGlvbiBub2RlCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcHJvY2Vzc2luZ0luc3RydWN0aW9uKFByb2Nlc3NpbmdJbnN0cnVjdGlvbiBub2RlKSB0aHJvd3MgWE5JRXhjZXB0aW9uOwotCi0gICAgcHVibGljIHZvaWQgc2V0SWdub3JpbmdDaGFyYWN0ZXJzKGJvb2xlYW4gaWdub3JlKTsKLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2pheHAvdmFsaWRhdGlvbi9ET01SZXN1bHRBdWdtZW50b3IuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2pheHAvdmFsaWRhdGlvbi9ET01SZXN1bHRBdWdtZW50b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDZkNzVlYi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9qYXhwL3ZhbGlkYXRpb24vRE9NUmVzdWx0QXVnbWVudG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyNTggKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5qYXhwLnZhbGlkYXRpb247Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLmRvbS5ET01SZXN1bHQ7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbS5BdHRySW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbS5Db3JlRG9jdW1lbnRJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tLkVsZW1lbnRJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tLkVsZW1lbnROU0ltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5kb20uUFNWSUF0dHJOU0ltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5kb20uUFNWSURvY3VtZW50SW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbS5QU1ZJRWxlbWVudE5TSW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5YU1NpbXBsZVR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuQXVnbWVudGF0aW9uczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5OYW1lc3BhY2VDb250ZXh0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlFOYW1lOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTEF0dHJpYnV0ZXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MTG9jYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxSZXNvdXJjZUlkZW50aWZpZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MU3RyaW5nOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhOSUV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MRG9jdW1lbnRTb3VyY2U7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5BdHRyaWJ1dGVQU1ZJOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuRWxlbWVudFBTVkk7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5YU1R5cGVEZWZpbml0aW9uOwotaW1wb3J0IG9yZy53M2MuZG9tLkNEQVRBU2VjdGlvbjsKLWltcG9ydCBvcmcudzNjLmRvbS5Db21tZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50VHlwZTsKLWltcG9ydCBvcmcudzNjLmRvbS5FbGVtZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLk5hbWVkTm9kZU1hcDsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotaW1wb3J0IG9yZy53M2MuZG9tLlByb2Nlc3NpbmdJbnN0cnVjdGlvbjsKLWltcG9ydCBvcmcudzNjLmRvbS5UZXh0OwotCi0vKioKLSAqIDxwPkRPTSByZXN1bHQgYXVnbWVudG9yLjwvcD4KLSAqCi0gKiBAYXV0aG9yIE1pY2hhZWwgR2xhdmFzc2V2aWNoLCBJQk0KLSAqLwotZmluYWwgY2xhc3MgRE9NUmVzdWx0QXVnbWVudG9yIGltcGxlbWVudHMgRE9NRG9jdW1lbnRIYW5kbGVyIHsKLQotICAgIC8vCi0gICAgLy8gRGF0YQotICAgIC8vCi0KLSAgICBwcml2YXRlIERPTVZhbGlkYXRvckhlbHBlciBmRE9NVmFsaWRhdG9ySGVscGVyOwotCi0gICAgcHJpdmF0ZSBEb2N1bWVudCBmRG9jdW1lbnQ7Ci0gICAgcHJpdmF0ZSBDb3JlRG9jdW1lbnRJbXBsIGZEb2N1bWVudEltcGw7Ci0gICAgcHJpdmF0ZSBib29sZWFuIGZTdG9yZVBTVkk7Ci0KLSAgICBwcml2YXRlIGJvb2xlYW4gZklnbm9yZUNoYXJzOwotCi0gICAgcHJpdmF0ZSBmaW5hbCBRTmFtZSBmQXR0cmlidXRlUU5hbWUgPSBuZXcgUU5hbWUoKTsKLQotICAgIHB1YmxpYyBET01SZXN1bHRBdWdtZW50b3IoRE9NVmFsaWRhdG9ySGVscGVyIGhlbHBlcikgewotICAgICAgICBmRE9NVmFsaWRhdG9ySGVscGVyID0gaGVscGVyOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldERPTVJlc3VsdChET01SZXN1bHQgcmVzdWx0KSB7Ci0gICAgICAgIGZJZ25vcmVDaGFycyA9IGZhbHNlOwotICAgICAgICBpZiAocmVzdWx0ICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZpbmFsIE5vZGUgdGFyZ2V0ID0gcmVzdWx0LmdldE5vZGUoKTsKLSAgICAgICAgICAgIGZEb2N1bWVudCA9ICh0YXJnZXQuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLkRPQ1VNRU5UX05PREUpID8gKERvY3VtZW50KSB0YXJnZXQgOiB0YXJnZXQuZ2V0T3duZXJEb2N1bWVudCgpOwotICAgICAgICAgICAgZkRvY3VtZW50SW1wbCA9IChmRG9jdW1lbnQgaW5zdGFuY2VvZiBDb3JlRG9jdW1lbnRJbXBsKSA/IChDb3JlRG9jdW1lbnRJbXBsKSBmRG9jdW1lbnQgOiBudWxsOwotICAgICAgICAgICAgZlN0b3JlUFNWSSA9IChmRG9jdW1lbnQgaW5zdGFuY2VvZiBQU1ZJRG9jdW1lbnRJbXBsKTsKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotICAgICAgICBmRG9jdW1lbnQgPSBudWxsOwotICAgICAgICBmRG9jdW1lbnRJbXBsID0gbnVsbDsKLSAgICAgICAgZlN0b3JlUFNWSSA9IGZhbHNlOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGRvY3R5cGVEZWNsKERvY3VtZW50VHlwZSBub2RlKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHt9Ci0KLSAgICBwdWJsaWMgdm9pZCBjaGFyYWN0ZXJzKFRleHQgbm9kZSkgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7fQotCi0gICAgcHVibGljIHZvaWQgY2RhdGEoQ0RBVEFTZWN0aW9uIG5vZGUpIHRocm93cyBYTklFeGNlcHRpb24ge30KLQotICAgIHB1YmxpYyB2b2lkIGNvbW1lbnQoQ29tbWVudCBub2RlKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHt9Ci0KLSAgICBwdWJsaWMgdm9pZCBwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oUHJvY2Vzc2luZ0luc3RydWN0aW9uIG5vZGUpCi0gICAgICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHt9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRJZ25vcmluZ0NoYXJhY3RlcnMoYm9vbGVhbiBpZ25vcmUpIHsKLSAgICAgICAgZklnbm9yZUNoYXJzID0gaWdub3JlOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RG9jdW1lbnQoWE1MTG9jYXRvciBsb2NhdG9yLCBTdHJpbmcgZW5jb2RpbmcsCi0gICAgICAgICAgICBOYW1lc3BhY2VDb250ZXh0IG5hbWVzcGFjZUNvbnRleHQsIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICAgICAgICAgIHRocm93cyBYTklFeGNlcHRpb24ge30KLQotICAgIHB1YmxpYyB2b2lkIHhtbERlY2woU3RyaW5nIHZlcnNpb24sIFN0cmluZyBlbmNvZGluZywgU3RyaW5nIHN0YW5kYWxvbmUsCi0gICAgICAgICAgICBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24ge30KLQotICAgIHB1YmxpYyB2b2lkIGRvY3R5cGVEZWNsKFN0cmluZyByb290RWxlbWVudCwgU3RyaW5nIHB1YmxpY0lkLAotICAgICAgICAgICAgU3RyaW5nIHN5c3RlbUlkLCBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24ge30KLQotICAgIHB1YmxpYyB2b2lkIGNvbW1lbnQoWE1MU3RyaW5nIHRleHQsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7fQotCi0gICAgcHVibGljIHZvaWQgcHJvY2Vzc2luZ0luc3RydWN0aW9uKFN0cmluZyB0YXJnZXQsIFhNTFN0cmluZyBkYXRhLAotICAgICAgICAgICAgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHt9Ci0KLSAgICBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQoUU5hbWUgZWxlbWVudCwgWE1MQXR0cmlidXRlcyBhdHRyaWJ1dGVzLAotICAgICAgICAgICAgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgZmluYWwgRWxlbWVudCBjdXJyZW50RWxlbWVudCA9IChFbGVtZW50KSBmRE9NVmFsaWRhdG9ySGVscGVyLmdldEN1cnJlbnRFbGVtZW50KCk7Ci0gICAgICAgIGZpbmFsIE5hbWVkTm9kZU1hcCBhdHRyTWFwID0gY3VycmVudEVsZW1lbnQuZ2V0QXR0cmlidXRlcygpOwotCi0gICAgICAgIGZpbmFsIGludCBvbGRMZW5ndGggPSBhdHRyTWFwLmdldExlbmd0aCgpOwotICAgICAgICAvLyBJZiBpdCdzIGEgWGVyY2VzIERPTSBzdG9yZSB0eXBlIGluZm9ybWF0aW9uIGZvciBhdHRyaWJ1dGVzLCBzZXQgaWRuZXNzLCBldGMuLgotICAgICAgICBpZiAoZkRvY3VtZW50SW1wbCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBBdHRySW1wbCBhdHRyOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBvbGRMZW5ndGg7ICsraSkgewotICAgICAgICAgICAgICAgIGF0dHIgPSAoQXR0ckltcGwpIGF0dHJNYXAuaXRlbShpKTsKLQotICAgICAgICAgICAgICAgIC8vIHdyaXRlIHR5cGUgaW5mb3JtYXRpb24gdG8gdGhpcyBhdHRyaWJ1dGUKLSAgICAgICAgICAgICAgICBBdHRyaWJ1dGVQU1ZJIGF0dHJQU1ZJID0gKEF0dHJpYnV0ZVBTVkkpIGF0dHJpYnV0ZXMuZ2V0QXVnbWVudGF0aW9ucyhpKS5nZXRJdGVtIChDb25zdGFudHMuQVRUUklCVVRFX1BTVkkpOwotICAgICAgICAgICAgICAgIGlmIChhdHRyUFNWSSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChwcm9jZXNzQXR0cmlidXRlUFNWSShhdHRyLCBhdHRyUFNWSSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICgoRWxlbWVudEltcGwpIGN1cnJlbnRFbGVtZW50KS5zZXRJZEF0dHJpYnV0ZU5vZGUgKGF0dHIsIHRydWUpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgZmluYWwgaW50IG5ld0xlbmd0aCA9IGF0dHJpYnV0ZXMuZ2V0TGVuZ3RoKCk7Ci0gICAgICAgIC8vIEFkZCBkZWZhdWx0L2ZpeGVkIGF0dHJpYnV0ZXMKLSAgICAgICAgaWYgKG5ld0xlbmd0aCA+IG9sZExlbmd0aCkgewotICAgICAgICAgICAgaWYgKGZEb2N1bWVudEltcGwgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSBvbGRMZW5ndGg7IGkgPCBuZXdMZW5ndGg7ICsraSkgewotICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzLmdldE5hbWUoaSwgZkF0dHJpYnV0ZVFOYW1lKTsKLSAgICAgICAgICAgICAgICAgICAgY3VycmVudEVsZW1lbnQuc2V0QXR0cmlidXRlTlMoZkF0dHJpYnV0ZVFOYW1lLnVyaSwgZkF0dHJpYnV0ZVFOYW1lLnJhd25hbWUsIGF0dHJpYnV0ZXMuZ2V0VmFsdWUoaSkpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIElmIGl0J3MgYSBYZXJjZXMgRE9NIHN0b3JlIHR5cGUgaW5mb3JtYXRpb24gZm9yIGF0dHJpYnV0ZXMsIHNldCBpZG5lc3MsIGV0Yy4uCi0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gb2xkTGVuZ3RoOyBpIDwgbmV3TGVuZ3RoOyArK2kpIHsKLSAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlcy5nZXROYW1lKGksIGZBdHRyaWJ1dGVRTmFtZSk7Ci0gICAgICAgICAgICAgICAgICAgIEF0dHJJbXBsIGF0dHIgPSAoQXR0ckltcGwpIGZEb2N1bWVudEltcGwuY3JlYXRlQXR0cmlidXRlTlMoZkF0dHJpYnV0ZVFOYW1lLnVyaSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmQXR0cmlidXRlUU5hbWUucmF3bmFtZSwgZkF0dHJpYnV0ZVFOYW1lLmxvY2FscGFydCk7Ci0gICAgICAgICAgICAgICAgICAgIGF0dHIuc2V0VmFsdWUoYXR0cmlidXRlcy5nZXRWYWx1ZShpKSk7Ci0KLSAgICAgICAgICAgICAgICAgICAgLy8gd3JpdGUgdHlwZSBpbmZvcm1hdGlvbiB0byB0aGlzIGF0dHJpYnV0ZQotICAgICAgICAgICAgICAgICAgICBBdHRyaWJ1dGVQU1ZJIGF0dHJQU1ZJID0gKEF0dHJpYnV0ZVBTVkkpIGF0dHJpYnV0ZXMuZ2V0QXVnbWVudGF0aW9ucyhpKS5nZXRJdGVtIChDb25zdGFudHMuQVRUUklCVVRFX1BTVkkpOwotICAgICAgICAgICAgICAgICAgICBpZiAoYXR0clBTVkkgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHByb2Nlc3NBdHRyaWJ1dGVQU1ZJKGF0dHIsIGF0dHJQU1ZJKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoRWxlbWVudEltcGwpIGN1cnJlbnRFbGVtZW50KS5zZXRJZEF0dHJpYnV0ZU5vZGUgKGF0dHIsIHRydWUpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGF0dHIuc2V0U3BlY2lmaWVkKGZhbHNlKTsKLSAgICAgICAgICAgICAgICAgICAgY3VycmVudEVsZW1lbnQuc2V0QXR0cmlidXRlTm9kZShhdHRyKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBlbXB0eUVsZW1lbnQoUU5hbWUgZWxlbWVudCwgWE1MQXR0cmlidXRlcyBhdHRyaWJ1dGVzLAotICAgICAgICAgICAgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgc3RhcnRFbGVtZW50KGVsZW1lbnQsIGF0dHJpYnV0ZXMsIGF1Z3MpOwotICAgICAgICBlbmRFbGVtZW50KGVsZW1lbnQsIGF1Z3MpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHN0YXJ0R2VuZXJhbEVudGl0eShTdHJpbmcgbmFtZSwKLSAgICAgICAgICAgIFhNTFJlc291cmNlSWRlbnRpZmllciBpZGVudGlmaWVyLCBTdHJpbmcgZW5jb2RpbmcsCi0gICAgICAgICAgICBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24ge30KLQotICAgIHB1YmxpYyB2b2lkIHRleHREZWNsKFN0cmluZyB2ZXJzaW9uLCBTdHJpbmcgZW5jb2RpbmcsIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICAgICAgICAgIHRocm93cyBYTklFeGNlcHRpb24ge30KLQotICAgIHB1YmxpYyB2b2lkIGVuZEdlbmVyYWxFbnRpdHkoU3RyaW5nIG5hbWUsIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICAgICAgICAgIHRocm93cyBYTklFeGNlcHRpb24ge30KLQotICAgIHB1YmxpYyB2b2lkIGNoYXJhY3RlcnMoWE1MU3RyaW5nIHRleHQsIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICAgICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBpZiAoIWZJZ25vcmVDaGFycykgewotICAgICAgICAgICAgZmluYWwgRWxlbWVudCBjdXJyZW50RWxlbWVudCA9IChFbGVtZW50KSBmRE9NVmFsaWRhdG9ySGVscGVyLmdldEN1cnJlbnRFbGVtZW50KCk7Ci0gICAgICAgICAgICBjdXJyZW50RWxlbWVudC5hcHBlbmRDaGlsZChmRG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUodGV4dC50b1N0cmluZygpKSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBpZ25vcmFibGVXaGl0ZXNwYWNlKFhNTFN0cmluZyB0ZXh0LCBBdWdtZW50YXRpb25zIGF1Z3MpCi0gICAgICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgY2hhcmFjdGVycyh0ZXh0LCBhdWdzKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBlbmRFbGVtZW50KFFOYW1lIGVsZW1lbnQsIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICAgICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBmaW5hbCBOb2RlIGN1cnJlbnRFbGVtZW50ID0gZkRPTVZhbGlkYXRvckhlbHBlci5nZXRDdXJyZW50RWxlbWVudCgpOwotICAgICAgICAvLyBXcml0ZSB0eXBlIGluZm9ybWF0aW9uIHRvIHRoaXMgZWxlbWVudAotICAgICAgICBpZiAoYXVncyAhPSBudWxsICYmIGZEb2N1bWVudEltcGwgIT0gbnVsbCkgewotICAgICAgICAgICAgRWxlbWVudFBTVkkgZWxlbWVudFBTVkkgPSAoRWxlbWVudFBTVkkpYXVncy5nZXRJdGVtKENvbnN0YW50cy5FTEVNRU5UX1BTVkkpOwotICAgICAgICAgICAgaWYgKGVsZW1lbnRQU1ZJICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBpZiAoZlN0b3JlUFNWSSkgewotICAgICAgICAgICAgICAgICAgICAoKFBTVklFbGVtZW50TlNJbXBsKSBjdXJyZW50RWxlbWVudCkuc2V0UFNWSShlbGVtZW50UFNWSSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIFhTVHlwZURlZmluaXRpb24gdHlwZSA9IGVsZW1lbnRQU1ZJLmdldE1lbWJlclR5cGVEZWZpbml0aW9uKCk7Ci0gICAgICAgICAgICAgICAgaWYgKHR5cGUgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICB0eXBlID0gZWxlbWVudFBTVkkuZ2V0VHlwZURlZmluaXRpb24oKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgKChFbGVtZW50TlNJbXBsKSBjdXJyZW50RWxlbWVudCkuc2V0VHlwZSh0eXBlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHN0YXJ0Q0RBVEEoQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHt9Ci0KLSAgICBwdWJsaWMgdm9pZCBlbmRDREFUQShBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24ge30KLQotICAgIHB1YmxpYyB2b2lkIGVuZERvY3VtZW50KEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7fQotCi0gICAgcHVibGljIHZvaWQgc2V0RG9jdW1lbnRTb3VyY2UoWE1MRG9jdW1lbnRTb3VyY2Ugc291cmNlKSB7fQotCi0gICAgcHVibGljIFhNTERvY3VtZW50U291cmNlIGdldERvY3VtZW50U291cmNlKCkgewotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICAvKiogUmV0dXJucyB3aGV0aGVyIHRoZSBnaXZlbiBhdHRyaWJ1dGUgaXMgYW4gSUQgdHlwZS4gKiovCi0gICAgcHJpdmF0ZSBib29sZWFuIHByb2Nlc3NBdHRyaWJ1dGVQU1ZJKEF0dHJJbXBsIGF0dHIsIEF0dHJpYnV0ZVBTVkkgYXR0clBTVkkpIHsKLSAgICAgICAgaWYgKGZTdG9yZVBTVkkpIHsKLSAgICAgICAgICAgICgoUFNWSUF0dHJOU0ltcGwpIGF0dHIpLnNldFBTVkkgKGF0dHJQU1ZJKTsKLSAgICAgICAgfQotICAgICAgICBPYmplY3QgdHlwZSA9IGF0dHJQU1ZJLmdldE1lbWJlclR5cGVEZWZpbml0aW9uICgpOwotICAgICAgICBpZiAodHlwZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICB0eXBlID0gYXR0clBTVkkuZ2V0VHlwZURlZmluaXRpb24gKCk7Ci0gICAgICAgICAgICBpZiAodHlwZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgYXR0ci5zZXRUeXBlKHR5cGUpOwotICAgICAgICAgICAgICAgIHJldHVybiAoKFhTU2ltcGxlVHlwZSkgdHlwZSkuaXNJRFR5cGUoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIGF0dHIuc2V0VHlwZSh0eXBlKTsKLSAgICAgICAgICAgIHJldHVybiAoKFhTU2ltcGxlVHlwZSkgdHlwZSkuaXNJRFR5cGUoKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi19IC8vIERPTVJlc3VsdEF1Z21lbnRvcgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvamF4cC92YWxpZGF0aW9uL0RPTVJlc3VsdEJ1aWxkZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2pheHAvdmFsaWRhdGlvbi9ET01SZXN1bHRCdWlsZGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGY3OGYxZjQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvamF4cC92YWxpZGF0aW9uL0RPTVJlc3VsdEJ1aWxkZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDM3MyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmpheHAudmFsaWRhdGlvbjsKLQotaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLmRvbS5ET01SZXN1bHQ7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbS5BdHRySW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbS5Db3JlRG9jdW1lbnRJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tLkRPTU1lc3NhZ2VGb3JtYXR0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5kb20uRG9jdW1lbnRUeXBlSW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbS5FbGVtZW50SW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbS5FbGVtZW50TlNJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tLkVudGl0eUltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5kb20uTm90YXRpb25JbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tLlBTVklBdHRyTlNJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tLlBTVklEb2N1bWVudEltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5kb20uUFNWSUVsZW1lbnROU0ltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLkNvbnN0YW50czsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYuWFNTaW1wbGVUeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLkF1Z21lbnRhdGlvbnM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuTmFtZXNwYWNlQ29udGV4dDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5RTmFtZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxBdHRyaWJ1dGVzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTExvY2F0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MUmVzb3VyY2VJZGVudGlmaWVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTFN0cmluZzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTklFeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTERvY3VtZW50U291cmNlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuQXR0cmlidXRlUFNWSTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLkVsZW1lbnRQU1ZJOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNUeXBlRGVmaW5pdGlvbjsKLQotaW1wb3J0IG9yZy53M2MuZG9tLkNEQVRBU2VjdGlvbjsKLWltcG9ydCBvcmcudzNjLmRvbS5Db21tZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50VHlwZTsKLWltcG9ydCBvcmcudzNjLmRvbS5FbGVtZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLkVudGl0eTsKLWltcG9ydCBvcmcudzNjLmRvbS5OYW1lZE5vZGVNYXA7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob3RhdGlvbjsKLWltcG9ydCBvcmcudzNjLmRvbS5Qcm9jZXNzaW5nSW5zdHJ1Y3Rpb247Ci1pbXBvcnQgb3JnLnczYy5kb20uVGV4dDsKLQotCi0vKioKLSAqIDxwPkRPTSByZXN1bHQgYnVpbGRlci48L3A+Ci0gKgotICogQGF1dGhvciBNaWNoYWVsIEdsYXZhc3NldmljaCwgSUJNCi0gKi8KLWZpbmFsIGNsYXNzIERPTVJlc3VsdEJ1aWxkZXIgaW1wbGVtZW50cyBET01Eb2N1bWVudEhhbmRsZXIgewotCi0gICAgLyoqIFRhYmxlIGZvciBxdWljayBjaGVjayBvZiBjaGlsZCBpbnNlcnRpb24uICovCi0gICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgaW50W10ga2lkT0s7Ci0KLSAgICBzdGF0aWMgewotICAgICAgICBraWRPSyA9IG5ldyBpbnRbMTNdOwotICAgICAgICBraWRPS1tOb2RlLkRPQ1VNRU5UX05PREVdID0KLSAgICAgICAgICAgIDEgPDwgTm9kZS5FTEVNRU5UX05PREUgfCAxIDw8IE5vZGUuUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFIHwKLSAgICAgICAgICAgIDEgPDwgTm9kZS5DT01NRU5UX05PREUgfCAxIDw8IE5vZGUuRE9DVU1FTlRfVFlQRV9OT0RFOwotICAgICAgICBraWRPS1tOb2RlLkRPQ1VNRU5UX0ZSQUdNRU5UX05PREVdID0KLSAgICAgICAga2lkT0tbTm9kZS5FTlRJVFlfTk9ERV0gPQotICAgICAgICBraWRPS1tOb2RlLkVOVElUWV9SRUZFUkVOQ0VfTk9ERV0gPQotICAgICAgICBraWRPS1tOb2RlLkVMRU1FTlRfTk9ERV0gPQotICAgICAgICAgICAgMSA8PCBOb2RlLkVMRU1FTlRfTk9ERSB8IDEgPDwgTm9kZS5QUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREUgfAotICAgICAgICAgICAgMSA8PCBOb2RlLkNPTU1FTlRfTk9ERSB8IDEgPDwgTm9kZS5URVhUX05PREUgfAotICAgICAgICAgICAgMSA8PCBOb2RlLkNEQVRBX1NFQ1RJT05fTk9ERSB8IDEgPDwgTm9kZS5FTlRJVFlfUkVGRVJFTkNFX05PREUgOwotICAgICAgICBraWRPS1tOb2RlLkFUVFJJQlVURV9OT0RFXSA9IDEgPDwgTm9kZS5URVhUX05PREUgfCAxIDw8IE5vZGUuRU5USVRZX1JFRkVSRU5DRV9OT0RFOwotICAgICAgICBraWRPS1tOb2RlLkRPQ1VNRU5UX1RZUEVfTk9ERV0gPSAwOwotICAgICAgICBraWRPS1tOb2RlLlBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERV0gPSAwOwotICAgICAgICBraWRPS1tOb2RlLkNPTU1FTlRfTk9ERV0gPSAwOwotICAgICAgICBraWRPS1tOb2RlLlRFWFRfTk9ERV0gPSAwOwotICAgICAgICBraWRPS1tOb2RlLkNEQVRBX1NFQ1RJT05fTk9ERV0gPSAwOwotICAgICAgICBraWRPS1tOb2RlLk5PVEFUSU9OX05PREVdID0gMDsKLSAgICB9IC8vIHN0YXRpYwotCi0gICAgLy8KLSAgICAvLyBEYXRhCi0gICAgLy8KLQotICAgIHByaXZhdGUgRG9jdW1lbnQgZkRvY3VtZW50OwotICAgIHByaXZhdGUgQ29yZURvY3VtZW50SW1wbCBmRG9jdW1lbnRJbXBsOwotICAgIHByaXZhdGUgYm9vbGVhbiBmU3RvcmVQU1ZJOwotCi0gICAgcHJpdmF0ZSBOb2RlIGZUYXJnZXQ7Ci0gICAgcHJpdmF0ZSBOb2RlIGZOZXh0U2libGluZzsKLQotICAgIHByaXZhdGUgTm9kZSBmQ3VycmVudE5vZGU7Ci0gICAgcHJpdmF0ZSBOb2RlIGZGcmFnbWVudFJvb3Q7Ci0KLSAgICBwcml2YXRlIGZpbmFsIEFycmF5TGlzdCBmVGFyZ2V0Q2hpbGRyZW4gPSBuZXcgQXJyYXlMaXN0KCk7Ci0KLSAgICBwcml2YXRlIGJvb2xlYW4gZklnbm9yZUNoYXJzOwotCi0gICAgcHJpdmF0ZSBmaW5hbCBRTmFtZSBmQXR0cmlidXRlUU5hbWUgPSBuZXcgUU5hbWUoKTsKLQotICAgIHB1YmxpYyBET01SZXN1bHRCdWlsZGVyKCkge30KLQotICAgIC8qCi0gICAgICogRE9NRG9jdW1lbnRIYW5kbGVyIG1ldGhvZHMKLSAgICAgKi8KLQotICAgIHB1YmxpYyB2b2lkIHNldERPTVJlc3VsdChET01SZXN1bHQgcmVzdWx0KSB7Ci0gICAgICAgIGZDdXJyZW50Tm9kZSA9IG51bGw7Ci0gICAgICAgIGZGcmFnbWVudFJvb3QgPSBudWxsOwotICAgICAgICBmSWdub3JlQ2hhcnMgPSBmYWxzZTsKLSAgICAgICAgZlRhcmdldENoaWxkcmVuLmNsZWFyKCk7Ci0gICAgICAgIGlmIChyZXN1bHQgIT0gbnVsbCkgewotICAgICAgICAgICAgZlRhcmdldCA9IHJlc3VsdC5nZXROb2RlKCk7Ci0gICAgICAgICAgICBmTmV4dFNpYmxpbmcgPSByZXN1bHQuZ2V0TmV4dFNpYmxpbmcoKTsKLSAgICAgICAgICAgIGZEb2N1bWVudCA9IChmVGFyZ2V0LmdldE5vZGVUeXBlKCkgPT0gTm9kZS5ET0NVTUVOVF9OT0RFKSA/IChEb2N1bWVudCkgZlRhcmdldCA6IGZUYXJnZXQuZ2V0T3duZXJEb2N1bWVudCgpOwotICAgICAgICAgICAgZkRvY3VtZW50SW1wbCA9IChmRG9jdW1lbnQgaW5zdGFuY2VvZiBDb3JlRG9jdW1lbnRJbXBsKSA/IChDb3JlRG9jdW1lbnRJbXBsKSBmRG9jdW1lbnQgOiBudWxsOwotICAgICAgICAgICAgZlN0b3JlUFNWSSA9IChmRG9jdW1lbnQgaW5zdGFuY2VvZiBQU1ZJRG9jdW1lbnRJbXBsKTsKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotICAgICAgICBmVGFyZ2V0ID0gbnVsbDsKLSAgICAgICAgZk5leHRTaWJsaW5nID0gbnVsbDsKLSAgICAgICAgZkRvY3VtZW50ID0gbnVsbDsKLSAgICAgICAgZkRvY3VtZW50SW1wbCA9IG51bGw7Ci0gICAgICAgIGZTdG9yZVBTVkkgPSBmYWxzZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBkb2N0eXBlRGVjbChEb2N1bWVudFR5cGUgbm9kZSkgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIC8qKiBDcmVhdGUgbmV3IERvY3VtZW50VHlwZSBub2RlIGZvciB0aGUgdGFyZ2V0LiAqLwotICAgICAgICBpZiAoZkRvY3VtZW50SW1wbCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBEb2N1bWVudFR5cGUgZG9jVHlwZSA9IGZEb2N1bWVudEltcGwuY3JlYXRlRG9jdW1lbnRUeXBlKG5vZGUuZ2V0TmFtZSgpLCBub2RlLmdldFB1YmxpY0lkKCksIG5vZGUuZ2V0U3lzdGVtSWQoKSk7Ci0gICAgICAgICAgICBmaW5hbCBTdHJpbmcgaW50ZXJuYWxTdWJzZXQgPSBub2RlLmdldEludGVybmFsU3Vic2V0KCk7Ci0gICAgICAgICAgICAvKiogQ29weSBpbnRlcm5hbCBzdWJzZXQuICovCi0gICAgICAgICAgICBpZiAoaW50ZXJuYWxTdWJzZXQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICgoRG9jdW1lbnRUeXBlSW1wbCkgZG9jVHlwZSkuc2V0SW50ZXJuYWxTdWJzZXQoaW50ZXJuYWxTdWJzZXQpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLyoqIENvcHkgZW50aXRpZXMuICovCi0gICAgICAgICAgICBOYW1lZE5vZGVNYXAgb2xkTWFwID0gbm9kZS5nZXRFbnRpdGllcygpOwotICAgICAgICAgICAgTmFtZWROb2RlTWFwIG5ld01hcCA9IGRvY1R5cGUuZ2V0RW50aXRpZXMoKTsKLSAgICAgICAgICAgIGludCBsZW5ndGggPSBvbGRNYXAuZ2V0TGVuZ3RoKCk7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7Ci0gICAgICAgICAgICAgICAgRW50aXR5IG9sZEVudGl0eSA9IChFbnRpdHkpIG9sZE1hcC5pdGVtKGkpOwotICAgICAgICAgICAgICAgIEVudGl0eUltcGwgbmV3RW50aXR5ID0gKEVudGl0eUltcGwpIGZEb2N1bWVudEltcGwuY3JlYXRlRW50aXR5KG9sZEVudGl0eS5nZXROb2RlTmFtZSgpKTsKLSAgICAgICAgICAgICAgICBuZXdFbnRpdHkuc2V0UHVibGljSWQob2xkRW50aXR5LmdldFB1YmxpY0lkKCkpOwotICAgICAgICAgICAgICAgIG5ld0VudGl0eS5zZXRTeXN0ZW1JZChvbGRFbnRpdHkuZ2V0U3lzdGVtSWQoKSk7Ci0gICAgICAgICAgICAgICAgbmV3RW50aXR5LnNldE5vdGF0aW9uTmFtZShvbGRFbnRpdHkuZ2V0Tm90YXRpb25OYW1lKCkpOwotICAgICAgICAgICAgICAgIG5ld01hcC5zZXROYW1lZEl0ZW0obmV3RW50aXR5KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8qKiBDb3B5IG5vdGF0aW9ucy4gKi8KLSAgICAgICAgICAgIG9sZE1hcCA9IG5vZGUuZ2V0Tm90YXRpb25zKCk7Ci0gICAgICAgICAgICBuZXdNYXAgPSBkb2NUeXBlLmdldE5vdGF0aW9ucygpOwotICAgICAgICAgICAgbGVuZ3RoID0gb2xkTWFwLmdldExlbmd0aCgpOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkgewotICAgICAgICAgICAgICAgIE5vdGF0aW9uIG9sZE5vdGF0aW9uID0gKE5vdGF0aW9uKSBvbGRNYXAuaXRlbShpKTsKLSAgICAgICAgICAgICAgICBOb3RhdGlvbkltcGwgbmV3Tm90YXRpb24gPSAoTm90YXRpb25JbXBsKSBmRG9jdW1lbnRJbXBsLmNyZWF0ZU5vdGF0aW9uKG9sZE5vdGF0aW9uLmdldE5vZGVOYW1lKCkpOwotICAgICAgICAgICAgICAgIG5ld05vdGF0aW9uLnNldFB1YmxpY0lkKG9sZE5vdGF0aW9uLmdldFB1YmxpY0lkKCkpOwotICAgICAgICAgICAgICAgIG5ld05vdGF0aW9uLnNldFN5c3RlbUlkKG9sZE5vdGF0aW9uLmdldFN5c3RlbUlkKCkpOwotICAgICAgICAgICAgICAgIG5ld01hcC5zZXROYW1lZEl0ZW0obmV3Tm90YXRpb24pOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgYXBwZW5kKGRvY1R5cGUpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgY2hhcmFjdGVycyhUZXh0IG5vZGUpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICAvKiogQ3JlYXRlIG5ldyBUZXh0IG5vZGUgZm9yIHRoZSB0YXJnZXQuICovCi0gICAgICAgIGFwcGVuZChmRG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUobm9kZS5nZXROb2RlVmFsdWUoKSkpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGNkYXRhKENEQVRBU2VjdGlvbiBub2RlKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgLyoqIENyZWF0ZSBuZXcgQ0RBVEFTZWN0aW9uIG5vZGUgZm9yIHRoZSB0YXJnZXQuICovCi0gICAgICAgIGFwcGVuZChmRG9jdW1lbnQuY3JlYXRlQ0RBVEFTZWN0aW9uKG5vZGUuZ2V0Tm9kZVZhbHVlKCkpKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBjb21tZW50KENvbW1lbnQgbm9kZSkgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIC8qKiBDcmVhdGUgbmV3IENvbW1lbnQgbm9kZSBmb3IgdGhlIHRhcmdldC4gKi8KLSAgICAgICAgYXBwZW5kKGZEb2N1bWVudC5jcmVhdGVDb21tZW50KG5vZGUuZ2V0Tm9kZVZhbHVlKCkpKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oUHJvY2Vzc2luZ0luc3RydWN0aW9uIG5vZGUpCi0gICAgICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgLyoqIENyZWF0ZSBuZXcgUHJvY2Vzc2luZ0luc3RydWN0aW9uIG5vZGUgZm9yIHRoZSB0YXJnZXQuICovCi0gICAgICAgIGFwcGVuZChmRG9jdW1lbnQuY3JlYXRlUHJvY2Vzc2luZ0luc3RydWN0aW9uKG5vZGUuZ2V0VGFyZ2V0KCksIG5vZGUuZ2V0RGF0YSgpKSk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0SWdub3JpbmdDaGFyYWN0ZXJzKGJvb2xlYW4gaWdub3JlKSB7Ci0gICAgICAgIGZJZ25vcmVDaGFycyA9IGlnbm9yZTsKLSAgICB9Ci0KLSAgICAvKgotICAgICAqIFhNTERvY3VtZW50SGFuZGxlciBtZXRob2RzCi0gICAgICovCi0KLSAgICBwdWJsaWMgdm9pZCBzdGFydERvY3VtZW50KFhNTExvY2F0b3IgbG9jYXRvciwgU3RyaW5nIGVuY29kaW5nLAotICAgICAgICAgICAgTmFtZXNwYWNlQ29udGV4dCBuYW1lc3BhY2VDb250ZXh0LCBBdWdtZW50YXRpb25zIGF1Z3MpCi0gICAgICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHt9Ci0KLSAgICBwdWJsaWMgdm9pZCB4bWxEZWNsKFN0cmluZyB2ZXJzaW9uLCBTdHJpbmcgZW5jb2RpbmcsIFN0cmluZyBzdGFuZGFsb25lLAotICAgICAgICAgICAgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHt9Ci0KLSAgICBwdWJsaWMgdm9pZCBkb2N0eXBlRGVjbChTdHJpbmcgcm9vdEVsZW1lbnQsIFN0cmluZyBwdWJsaWNJZCwKLSAgICAgICAgICAgIFN0cmluZyBzeXN0ZW1JZCwgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHt9Ci0KLSAgICBwdWJsaWMgdm9pZCBjb21tZW50KFhNTFN0cmluZyB0ZXh0LCBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24ge30KLQotICAgIHB1YmxpYyB2b2lkIHByb2Nlc3NpbmdJbnN0cnVjdGlvbihTdHJpbmcgdGFyZ2V0LCBYTUxTdHJpbmcgZGF0YSwKLSAgICAgICAgICAgIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7fQotCi0gICAgcHVibGljIHZvaWQgc3RhcnRFbGVtZW50KFFOYW1lIGVsZW1lbnQsIFhNTEF0dHJpYnV0ZXMgYXR0cmlidXRlcywKLSAgICAgICAgICAgIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIEVsZW1lbnQgZWxlbTsKLSAgICAgICAgaW50IGF0dHJDb3VudCA9IGF0dHJpYnV0ZXMuZ2V0TGVuZ3RoKCk7Ci0gICAgICAgIGlmIChmRG9jdW1lbnRJbXBsID09IG51bGwpIHsKLSAgICAgICAgICAgIGVsZW0gPSBmRG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKGVsZW1lbnQudXJpLCBlbGVtZW50LnJhd25hbWUpOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhdHRyQ291bnQ7ICsraSkgewotICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXMuZ2V0TmFtZShpLCBmQXR0cmlidXRlUU5hbWUpOwotICAgICAgICAgICAgICAgIGVsZW0uc2V0QXR0cmlidXRlTlMoZkF0dHJpYnV0ZVFOYW1lLnVyaSwgZkF0dHJpYnV0ZVFOYW1lLnJhd25hbWUsIGF0dHJpYnV0ZXMuZ2V0VmFsdWUoaSkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIC8vIElmIGl0J3MgYSBYZXJjZXMgRE9NIHN0b3JlIHR5cGUgaW5mb3JtYXRpb24gZm9yIGF0dHJpYnV0ZXMsIHNldCBpZG5lc3MsIGV0Yy4uCi0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgZWxlbSA9IGZEb2N1bWVudEltcGwuY3JlYXRlRWxlbWVudE5TKGVsZW1lbnQudXJpLCBlbGVtZW50LnJhd25hbWUsIGVsZW1lbnQubG9jYWxwYXJ0KTsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYXR0ckNvdW50OyArK2kpIHsKLSAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzLmdldE5hbWUoaSwgZkF0dHJpYnV0ZVFOYW1lKTsKLSAgICAgICAgICAgICAgICBBdHRySW1wbCBhdHRyID0gKEF0dHJJbXBsKSBmRG9jdW1lbnRJbXBsLmNyZWF0ZUF0dHJpYnV0ZU5TKGZBdHRyaWJ1dGVRTmFtZS51cmksCi0gICAgICAgICAgICAgICAgICAgICAgICBmQXR0cmlidXRlUU5hbWUucmF3bmFtZSwgZkF0dHJpYnV0ZVFOYW1lLmxvY2FscGFydCk7Ci0gICAgICAgICAgICAgICAgYXR0ci5zZXRWYWx1ZShhdHRyaWJ1dGVzLmdldFZhbHVlKGkpKTsKLQotICAgICAgICAgICAgICAgIC8vIHdyaXRlIHR5cGUgaW5mb3JtYXRpb24gdG8gdGhpcyBhdHRyaWJ1dGUKLSAgICAgICAgICAgICAgICBBdHRyaWJ1dGVQU1ZJIGF0dHJQU1ZJID0gKEF0dHJpYnV0ZVBTVkkpIGF0dHJpYnV0ZXMuZ2V0QXVnbWVudGF0aW9ucyhpKS5nZXRJdGVtIChDb25zdGFudHMuQVRUUklCVVRFX1BTVkkpOwotICAgICAgICAgICAgICAgIGlmIChhdHRyUFNWSSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChmU3RvcmVQU1ZJKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAoKFBTVklBdHRyTlNJbXBsKSBhdHRyKS5zZXRQU1ZJKGF0dHJQU1ZJKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBPYmplY3QgdHlwZSA9IGF0dHJQU1ZJLmdldE1lbWJlclR5cGVEZWZpbml0aW9uKCk7Ci0gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUgPSBhdHRyUFNWSS5nZXRUeXBlRGVmaW5pdGlvbigpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGUgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHIuc2V0VHlwZSAodHlwZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCgoWFNTaW1wbGVUeXBlKSB0eXBlKS5pc0lEVHlwZSgpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoRWxlbWVudEltcGwpIGVsZW0pLnNldElkQXR0cmlidXRlTm9kZSAoYXR0ciwgdHJ1ZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgYXR0ci5zZXRUeXBlICh0eXBlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoKFhTU2ltcGxlVHlwZSkgdHlwZSkuaXNJRFR5cGUoKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoRWxlbWVudEltcGwpIGVsZW0pLnNldElkQXR0cmlidXRlTm9kZSAoYXR0ciwgdHJ1ZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgYXR0ci5zZXRTcGVjaWZpZWQoYXR0cmlidXRlcy5pc1NwZWNpZmllZChpKSk7Ci0gICAgICAgICAgICAgICAgZWxlbS5zZXRBdHRyaWJ1dGVOb2RlKGF0dHIpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGFwcGVuZChlbGVtKTsKLSAgICAgICAgZkN1cnJlbnROb2RlID0gZWxlbTsKLSAgICAgICAgaWYgKGZGcmFnbWVudFJvb3QgPT0gbnVsbCkgewotICAgICAgICAgICAgZkZyYWdtZW50Um9vdCA9IGVsZW07Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBlbXB0eUVsZW1lbnQoUU5hbWUgZWxlbWVudCwgWE1MQXR0cmlidXRlcyBhdHRyaWJ1dGVzLAotICAgICAgICAgICAgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgc3RhcnRFbGVtZW50KGVsZW1lbnQsIGF0dHJpYnV0ZXMsIGF1Z3MpOwotICAgICAgICBlbmRFbGVtZW50KGVsZW1lbnQsIGF1Z3MpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHN0YXJ0R2VuZXJhbEVudGl0eShTdHJpbmcgbmFtZSwKLSAgICAgICAgICAgIFhNTFJlc291cmNlSWRlbnRpZmllciBpZGVudGlmaWVyLCBTdHJpbmcgZW5jb2RpbmcsCi0gICAgICAgICAgICBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24ge30KLQotICAgIHB1YmxpYyB2b2lkIHRleHREZWNsKFN0cmluZyB2ZXJzaW9uLCBTdHJpbmcgZW5jb2RpbmcsIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICAgICAgICAgIHRocm93cyBYTklFeGNlcHRpb24ge30KLQotICAgIHB1YmxpYyB2b2lkIGVuZEdlbmVyYWxFbnRpdHkoU3RyaW5nIG5hbWUsIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICAgICAgICAgIHRocm93cyBYTklFeGNlcHRpb24ge30KLQotICAgIHB1YmxpYyB2b2lkIGNoYXJhY3RlcnMoWE1MU3RyaW5nIHRleHQsIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICAgICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBpZiAoIWZJZ25vcmVDaGFycykgewotICAgICAgICAgICAgYXBwZW5kKGZEb2N1bWVudC5jcmVhdGVUZXh0Tm9kZSh0ZXh0LnRvU3RyaW5nKCkpKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGlnbm9yYWJsZVdoaXRlc3BhY2UoWE1MU3RyaW5nIHRleHQsIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICAgICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBjaGFyYWN0ZXJzKHRleHQsIGF1Z3MpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGVuZEVsZW1lbnQoUU5hbWUgZWxlbWVudCwgQXVnbWVudGF0aW9ucyBhdWdzKQotICAgICAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIC8vIHdyaXRlIHR5cGUgaW5mb3JtYXRpb24gdG8gdGhpcyBlbGVtZW50Ci0gICAgICAgIGlmIChhdWdzICE9IG51bGwgJiYgZkRvY3VtZW50SW1wbCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBFbGVtZW50UFNWSSBlbGVtZW50UFNWSSA9IChFbGVtZW50UFNWSSlhdWdzLmdldEl0ZW0oQ29uc3RhbnRzLkVMRU1FTlRfUFNWSSk7Ci0gICAgICAgICAgICBpZiAoZWxlbWVudFBTVkkgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGlmIChmU3RvcmVQU1ZJKSB7Ci0gICAgICAgICAgICAgICAgICAgICgoUFNWSUVsZW1lbnROU0ltcGwpZkN1cnJlbnROb2RlKS5zZXRQU1ZJKGVsZW1lbnRQU1ZJKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgWFNUeXBlRGVmaW5pdGlvbiB0eXBlID0gZWxlbWVudFBTVkkuZ2V0TWVtYmVyVHlwZURlZmluaXRpb24oKTsKLSAgICAgICAgICAgICAgICBpZiAodHlwZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIHR5cGUgPSBlbGVtZW50UFNWSS5nZXRUeXBlRGVmaW5pdGlvbigpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAoKEVsZW1lbnROU0ltcGwpZkN1cnJlbnROb2RlKS5zZXRUeXBlKHR5cGUpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gYWRqdXN0IGN1cnJlbnQgbm9kZSByZWZlcmVuY2UKLSAgICAgICAgaWYgKGZDdXJyZW50Tm9kZSA9PSBmRnJhZ21lbnRSb290KSB7Ci0gICAgICAgICAgICBmQ3VycmVudE5vZGUgPSBudWxsOwotICAgICAgICAgICAgZkZyYWdtZW50Um9vdCA9IG51bGw7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLSAgICAgICAgZkN1cnJlbnROb2RlID0gZkN1cnJlbnROb2RlLmdldFBhcmVudE5vZGUoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzdGFydENEQVRBKEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7fQotCi0gICAgcHVibGljIHZvaWQgZW5kQ0RBVEEoQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHt9Ci0KLSAgICBwdWJsaWMgdm9pZCBlbmREb2N1bWVudChBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBmaW5hbCBpbnQgbGVuZ3RoID0gZlRhcmdldENoaWxkcmVuLnNpemUoKTsKLSAgICAgICAgaWYgKGZOZXh0U2libGluZyA9PSBudWxsKSB7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7Ci0gICAgICAgICAgICAgICAgZlRhcmdldC5hcHBlbmRDaGlsZCgoTm9kZSkgZlRhcmdldENoaWxkcmVuLmdldChpKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7Ci0gICAgICAgICAgICAgICAgZlRhcmdldC5pbnNlcnRCZWZvcmUoKE5vZGUpIGZUYXJnZXRDaGlsZHJlbi5nZXQoaSksIGZOZXh0U2libGluZyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXREb2N1bWVudFNvdXJjZShYTUxEb2N1bWVudFNvdXJjZSBzb3VyY2UpIHt9Ci0KLSAgICBwdWJsaWMgWE1MRG9jdW1lbnRTb3VyY2UgZ2V0RG9jdW1lbnRTb3VyY2UoKSB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qCi0gICAgICogT3RoZXIgbWV0aG9kcwotICAgICAqLwotCi0gICAgcHJpdmF0ZSB2b2lkIGFwcGVuZChOb2RlIG5vZGUpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBpZiAoZkN1cnJlbnROb2RlICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZDdXJyZW50Tm9kZS5hcHBlbmRDaGlsZChub2RlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIC8qKiBDaGVjayBpZiB0aGlzIG5vZGUgY2FuIGJlIGF0dGFjaGVkIHRvIHRoZSB0YXJnZXQuICovCi0gICAgICAgICAgICBpZiAoKGtpZE9LW2ZUYXJnZXQuZ2V0Tm9kZVR5cGUoKV0gJiAoMSA8PCBub2RlLmdldE5vZGVUeXBlKCkpKSA9PSAwKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIG1zZyA9IERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sICJISUVSQVJDSFlfUkVRVUVTVF9FUlIiLCBudWxsKTsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWE5JRXhjZXB0aW9uKG1zZyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmVGFyZ2V0Q2hpbGRyZW4uYWRkKG5vZGUpOwotICAgICAgICB9Ci0gICAgfQotCi19IC8vIERPTVJlc3VsdEJ1aWxkZXIKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2pheHAvdmFsaWRhdGlvbi9ET01WYWxpZGF0b3JIZWxwZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2pheHAvdmFsaWRhdGlvbi9ET01WYWxpZGF0b3JIZWxwZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNGM2OWU3MC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9qYXhwL3ZhbGlkYXRpb24vRE9NVmFsaWRhdG9ySGVscGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw2MTMgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5qYXhwLnZhbGlkYXRpb247Ci0KLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKLQotaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlcjsKLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5OwotaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLlBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5SZXN1bHQ7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2U7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5kb20uRE9NUmVzdWx0OwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uZG9tLkRPTVNvdXJjZTsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5Db25zdGFudHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLlhNTEVycm9yUmVwb3J0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnZhbGlkYXRpb24uRW50aXR5U3RhdGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnZhbGlkYXRpb24uVmFsaWRhdGlvbk1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlhNTFNjaGVtYVZhbGlkYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMudXRpbC5TaW1wbGVMb2NhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuamF4cC5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5SW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuTmFtZXNwYWNlU3VwcG9ydDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuU3ltYm9sVGFibGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlhNTEF0dHJpYnV0ZXNJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5YTUxTeW1ib2xzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLk5hbWVzcGFjZUNvbnRleHQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuUU5hbWU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MU3RyaW5nOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhOSUV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MUGFyc2VFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnczYy5kb20uQXR0cjsKLWltcG9ydCBvcmcudzNjLmRvbS5DREFUQVNlY3Rpb247Ci1pbXBvcnQgb3JnLnczYy5kb20uQ29tbWVudDsKLWltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKLWltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudFR5cGU7Ci1pbXBvcnQgb3JnLnczYy5kb20uRW50aXR5OwotaW1wb3J0IG9yZy53M2MuZG9tLk5hbWVkTm9kZU1hcDsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotaW1wb3J0IG9yZy53M2MuZG9tLlByb2Nlc3NpbmdJbnN0cnVjdGlvbjsKLWltcG9ydCBvcmcudzNjLmRvbS5UZXh0OwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKLQotLyoqCi0gKiA8cD5BIHZhbGlkYXRvciBoZWxwZXIgZm9yIDxjb2RlPkRPTVNvdXJjZTwvY29kZT5zLjwvcD4KLSAqCi0gKiBAYXV0aG9yIE1pY2hhZWwgR2xhdmFzc2V2aWNoLCBJQk0KLSAqIEB2ZXJzaW9uICRJZDogRE9NVmFsaWRhdG9ySGVscGVyLmphdmEsdiAxLjkgMjAxMC0xMS0wMSAwNDo0MDowOCBqb2VodyBFeHAgJAotICovCi1maW5hbCBjbGFzcyBET01WYWxpZGF0b3JIZWxwZXIgaW1wbGVtZW50cyBWYWxpZGF0b3JIZWxwZXIsIEVudGl0eVN0YXRlIHsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RhbnRzCi0gICAgLy8KLQotICAgIC8qKiBDaHVuayBzaXplICgxMDI0KS4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQ0hVTktfU0laRSA9ICgxIDw8IDEwKTsKLQotICAgIC8qKiBDaHVuayBtYXNrIChDSFVOS19TSVpFIC0gMSkuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IENIVU5LX01BU0sgPSBDSFVOS19TSVpFIC0gMTsKLQotICAgIC8vIHByb3BlcnR5IGlkZW50aWZpZXJzCi0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogZXJyb3IgcmVwb3J0ZXIuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUk9SX1JFUE9SVEVSID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuRVJST1JfUkVQT1JURVJfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogbmFtZXNwYWNlIGNvbnRleHQuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIE5BTUVTUEFDRV9DT05URVhUID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuTkFNRVNQQUNFX0NPTlRFWFRfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogWE1MIFNjaGVtYSB2YWxpZGF0b3IuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFNDSEVNQV9WQUxJREFUT1IgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5TQ0hFTUFfVkFMSURBVE9SX1BST1BFUlRZOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IHN5bWJvbCB0YWJsZS4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1lNQk9MX1RBQkxFID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuU1lNQk9MX1RBQkxFX1BST1BFUlRZOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IHZhbGlkYXRpb24gbWFuYWdlci4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgVkFMSURBVElPTl9NQU5BR0VSID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuVkFMSURBVElPTl9NQU5BR0VSX1BST1BFUlRZOwotCi0gICAgLy8KLSAgICAvLyBEYXRhCi0gICAgLy8KLQotICAgIC8qKiBFcnJvciByZXBvcnRlci4gKi8KLSAgICBwcml2YXRlIFhNTEVycm9yUmVwb3J0ZXIgZkVycm9yUmVwb3J0ZXI7Ci0KLSAgICAvKiogVGhlIG5hbWVzcGFjZSBjb250ZXh0IG9mIHRoaXMgZG9jdW1lbnQ6IHN0b3JlcyBuYW1lc3BhY2VzIGluIHNjb3BlLiAqKi8KLSAgICBwcml2YXRlIE5hbWVzcGFjZVN1cHBvcnQgZk5hbWVzcGFjZUNvbnRleHQ7Ci0KLSAgICAvKiogVGhlIG5hbWVzcGFjZSBjb250ZXh0IG9mIHRoZSBET01Tb3VyY2UsIGluY2x1ZGVzIGNvbnRleHQgZnJvbSBhbmNlc3RvciBub2Rlcy4gKiovCi0gICAgcHJpdmF0ZSBET01OYW1lc3BhY2VDb250ZXh0IGZET01OYW1lc3BhY2VDb250ZXh0ID0gbmV3IERPTU5hbWVzcGFjZUNvbnRleHQoKTsKLQotICAgIC8qKiBTY2hlbWEgdmFsaWRhdG9yLiAqKi8KLSAgICBwcml2YXRlIFhNTFNjaGVtYVZhbGlkYXRvciBmU2NoZW1hVmFsaWRhdG9yOwotCi0gICAgLyoqIFN5bWJvbCB0YWJsZSAqKi8KLSAgICBwcml2YXRlIFN5bWJvbFRhYmxlIGZTeW1ib2xUYWJsZTsKLQotICAgIC8qKiBWYWxpZGF0aW9uIG1hbmFnZXIuICoqLwotICAgIHByaXZhdGUgVmFsaWRhdGlvbk1hbmFnZXIgZlZhbGlkYXRpb25NYW5hZ2VyOwotCi0gICAgLyoqIENvbXBvbmVudCBtYW5hZ2VyLiAqKi8KLSAgICBwcml2YXRlIFhNTFNjaGVtYVZhbGlkYXRvckNvbXBvbmVudE1hbmFnZXIgZkNvbXBvbmVudE1hbmFnZXI7Ci0KLSAgICAvKiogU2ltcGxlIExvY2F0b3IuICoqLwotICAgIHByaXZhdGUgZmluYWwgU2ltcGxlTG9jYXRvciBmWE1MTG9jYXRvciA9IG5ldyBTaW1wbGVMb2NhdG9yKG51bGwsIG51bGwsIC0xLCAtMSwgLTEpOwotCi0gICAgLyoqIERPTSBkb2N1bWVudCBoYW5kbGVyLiAqKi8KLSAgICBwcml2YXRlIERPTURvY3VtZW50SGFuZGxlciBmRE9NVmFsaWRhdG9ySGFuZGxlcjsKLQotICAgIC8qKiBET00gcmVzdWx0IGF1Z21lbnRvci4gKiovCi0gICAgcHJpdmF0ZSBmaW5hbCBET01SZXN1bHRBdWdtZW50b3IgZkRPTVJlc3VsdEF1Z21lbnRvciA9IG5ldyBET01SZXN1bHRBdWdtZW50b3IodGhpcyk7Ci0KLSAgICAvKiogRE9NIHJlc3VsdCBidWlsZGVyLiAqKi8KLSAgICBwcml2YXRlIGZpbmFsIERPTVJlc3VsdEJ1aWxkZXIgZkRPTVJlc3VsdEJ1aWxkZXIgPSBuZXcgRE9NUmVzdWx0QnVpbGRlcigpOwotCi0gICAgLyoqIE1hcCBmb3IgdHJhY2tpbmcgdW5wYXJzZWQgZW50aXRpZXMuICoqLwotICAgIHByaXZhdGUgTmFtZWROb2RlTWFwIGZFbnRpdGllcyA9IG51bGw7Ci0KLSAgICAvKiogQXJyYXkgZm9yIGhvbGRpbmcgY2hhcmFjdGVyIGRhdGEuICoqLwotICAgIHByaXZhdGUgY2hhciBbXSBmQ2hhckJ1ZmZlciA9IG5ldyBjaGFyW0NIVU5LX1NJWkVdOwotCi0gICAgLyoqIFJvb3Qgbm9kZS4gKiovCi0gICAgcHJpdmF0ZSBOb2RlIGZSb290OwotCi0gICAgLyoqIEN1cnJlbnQgZWxlbWVudC4gKiovCi0gICAgcHJpdmF0ZSBOb2RlIGZDdXJyZW50RWxlbWVudDsKLQotICAgIC8qKiBGaWVsZHMgZm9yIHN0YXJ0IGVsZW1lbnQsIGVuZCBlbGVtZW50IGFuZCBjaGFyYWN0ZXJzLiAqKi8KLSAgICBmaW5hbCBRTmFtZSBmRWxlbWVudFFOYW1lID0gbmV3IFFOYW1lKCk7Ci0gICAgZmluYWwgUU5hbWUgZkF0dHJpYnV0ZVFOYW1lID0gbmV3IFFOYW1lKCk7Ci0gICAgZmluYWwgWE1MQXR0cmlidXRlc0ltcGwgZkF0dHJpYnV0ZXMgPSBuZXcgWE1MQXR0cmlidXRlc0ltcGwoKTsKLSAgICBmaW5hbCBYTUxTdHJpbmcgZlRlbXBTdHJpbmcgPSBuZXcgWE1MU3RyaW5nKCk7Ci0KLSAgICBwdWJsaWMgRE9NVmFsaWRhdG9ySGVscGVyKFhNTFNjaGVtYVZhbGlkYXRvckNvbXBvbmVudE1hbmFnZXIgY29tcG9uZW50TWFuYWdlcikgewotICAgICAgICBmQ29tcG9uZW50TWFuYWdlciA9IGNvbXBvbmVudE1hbmFnZXI7Ci0gICAgICAgIGZFcnJvclJlcG9ydGVyID0gKFhNTEVycm9yUmVwb3J0ZXIpIGZDb21wb25lbnRNYW5hZ2VyLmdldFByb3BlcnR5KEVSUk9SX1JFUE9SVEVSKTsKLSAgICAgICAgZk5hbWVzcGFjZUNvbnRleHQgPSAoTmFtZXNwYWNlU3VwcG9ydCkgZkNvbXBvbmVudE1hbmFnZXIuZ2V0UHJvcGVydHkoTkFNRVNQQUNFX0NPTlRFWFQpOwotICAgICAgICBmU2NoZW1hVmFsaWRhdG9yID0gKFhNTFNjaGVtYVZhbGlkYXRvcikgZkNvbXBvbmVudE1hbmFnZXIuZ2V0UHJvcGVydHkoU0NIRU1BX1ZBTElEQVRPUik7Ci0gICAgICAgIGZTeW1ib2xUYWJsZSA9IChTeW1ib2xUYWJsZSkgZkNvbXBvbmVudE1hbmFnZXIuZ2V0UHJvcGVydHkoU1lNQk9MX1RBQkxFKTsKLSAgICAgICAgZlZhbGlkYXRpb25NYW5hZ2VyID0gKFZhbGlkYXRpb25NYW5hZ2VyKSBmQ29tcG9uZW50TWFuYWdlci5nZXRQcm9wZXJ0eShWQUxJREFUSU9OX01BTkFHRVIpOwotICAgIH0KLQotICAgIC8qCi0gICAgICogVmFsaWRhdG9ySGVscGVyIG1ldGhvZHMKLSAgICAgKi8KLQotICAgIHB1YmxpYyB2b2lkIHZhbGlkYXRlKFNvdXJjZSBzb3VyY2UsIFJlc3VsdCByZXN1bHQpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIERPTVJlc3VsdCB8fCByZXN1bHQgPT0gbnVsbCkgewotICAgICAgICAgICAgZmluYWwgRE9NU291cmNlIGRvbVNvdXJjZSA9IChET01Tb3VyY2UpIHNvdXJjZTsKLSAgICAgICAgICAgIGZpbmFsIERPTVJlc3VsdCBkb21SZXN1bHQgPSAoRE9NUmVzdWx0KSByZXN1bHQ7Ci0gICAgICAgICAgICBOb2RlIG5vZGUgPSBkb21Tb3VyY2UuZ2V0Tm9kZSgpOwotICAgICAgICAgICAgZlJvb3QgPSBub2RlOwotICAgICAgICAgICAgaWYgKG5vZGUgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZDb21wb25lbnRNYW5hZ2VyLnJlc2V0KCk7Ci0gICAgICAgICAgICAgICAgZlZhbGlkYXRpb25NYW5hZ2VyLnNldEVudGl0eVN0YXRlKHRoaXMpOwotICAgICAgICAgICAgICAgIGZET01OYW1lc3BhY2VDb250ZXh0LnJlc2V0KCk7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIHN5c3RlbUlkID0gZG9tU291cmNlLmdldFN5c3RlbUlkKCk7Ci0gICAgICAgICAgICAgICAgZlhNTExvY2F0b3Iuc2V0TGl0ZXJhbFN5c3RlbUlkKHN5c3RlbUlkKTsKLSAgICAgICAgICAgICAgICBmWE1MTG9jYXRvci5zZXRFeHBhbmRlZFN5c3RlbUlkKHN5c3RlbUlkKTsKLSAgICAgICAgICAgICAgICBmRXJyb3JSZXBvcnRlci5zZXREb2N1bWVudExvY2F0b3IoZlhNTExvY2F0b3IpOwotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIHJlZ2FyZGxlc3Mgb2Ygd2hhdCB0eXBlIG9mIG5vZGUgdGhpcyBpcywgZmlyZSBzdGFydCBhbmQgZW5kIGRvY3VtZW50IGV2ZW50cwotICAgICAgICAgICAgICAgICAgICBzZXR1cEVudGl0eU1hcCgobm9kZS5nZXROb2RlVHlwZSgpID09IE5vZGUuRE9DVU1FTlRfTk9ERSkgPyAoRG9jdW1lbnQpIG5vZGUgOiBub2RlLmdldE93bmVyRG9jdW1lbnQoKSk7Ci0gICAgICAgICAgICAgICAgICAgIHNldHVwRE9NUmVzdWx0SGFuZGxlcihkb21Tb3VyY2UsIGRvbVJlc3VsdCk7Ci0gICAgICAgICAgICAgICAgICAgIGZTY2hlbWFWYWxpZGF0b3Iuc3RhcnREb2N1bWVudChmWE1MTG9jYXRvciwgbnVsbCwgZkRPTU5hbWVzcGFjZUNvbnRleHQsIG51bGwpOwotICAgICAgICAgICAgICAgICAgICB2YWxpZGF0ZShub2RlKTsKLSAgICAgICAgICAgICAgICAgICAgZlNjaGVtYVZhbGlkYXRvci5lbmREb2N1bWVudChudWxsKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgY2F0Y2ggKFhNTFBhcnNlRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICAgICAgdGhyb3cgVXRpbC50b1NBWFBhcnNlRXhjZXB0aW9uKGUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBjYXRjaCAoWE5JRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICAgICAgdGhyb3cgVXRpbC50b1NBWEV4Y2VwdGlvbihlKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZmluYWxseSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIFJlbGVhc2UgcmVmZXJlbmNlcyB0byBhcHBsaWNhdGlvbiBvYmplY3RzCi0gICAgICAgICAgICAgICAgICAgIGZSb290ID0gbnVsbDsKLSAgICAgICAgICAgICAgICAgICAgLy9mQ3VycmVudEVsZW1lbnQgPSBudWxsOyAtLSBrZWVwIHRoZSByZWZlcmVuY2UgdG8gc3VwcG9ydCBjdXJyZW50LWVsZW1lbnQtbm9kZSBwcm9wZXJ0eQotICAgICAgICAgICAgICAgICAgICBmRW50aXRpZXMgPSBudWxsOwotICAgICAgICAgICAgICAgICAgICBpZiAoZkRPTVZhbGlkYXRvckhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgZkRPTVZhbGlkYXRvckhhbmRsZXIuc2V0RE9NUmVzdWx0KG51bGwpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0gICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oSkFYUFZhbGlkYXRpb25NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoZkNvbXBvbmVudE1hbmFnZXIuZ2V0TG9jYWxlKCksCi0gICAgICAgICAgICAgICAgIlNvdXJjZVJlc3VsdE1pc21hdGNoIiwKLSAgICAgICAgICAgICAgICBuZXcgT2JqZWN0IFtdIHtzb3VyY2UuZ2V0Q2xhc3MoKS5nZXROYW1lKCksIHJlc3VsdC5nZXRDbGFzcygpLmdldE5hbWUoKX0pKTsKLSAgICB9Ci0KLSAgICAvKgotICAgICAqIEVudGl0eVN0YXRlIG1ldGhvZHMKLSAgICAgKi8KLQotICAgIHB1YmxpYyBib29sZWFuIGlzRW50aXR5RGVjbGFyZWQoU3RyaW5nIG5hbWUpIHsKLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGlzRW50aXR5VW5wYXJzZWQoU3RyaW5nIG5hbWUpIHsKLSAgICAgICAgaWYgKGZFbnRpdGllcyAhPSBudWxsKSB7Ci0gICAgICAgICAgICBFbnRpdHkgZW50aXR5ID0gKEVudGl0eSkgZkVudGl0aWVzLmdldE5hbWVkSXRlbShuYW1lKTsKLSAgICAgICAgICAgIGlmIChlbnRpdHkgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJldHVybiAoZW50aXR5LmdldE5vdGF0aW9uTmFtZSgpICE9IG51bGwpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICAvKgotICAgICAqIE90aGVyIG1ldGhvZHMKLSAgICAgKi8KLQotICAgIC8qKiBUcmF2ZXJzZSB0aGUgRE9NIGFuZCBmaXJlIGV2ZW50cyB0byB0aGUgc2NoZW1hIHZhbGlkYXRvci4gKi8KLSAgICBwcml2YXRlIHZvaWQgdmFsaWRhdGUoTm9kZSBub2RlKSB7Ci0gICAgICAgIGZpbmFsIE5vZGUgdG9wID0gbm9kZTsKLSAgICAgICAgLy8gUGVyZm9ybXMgYSBub24tcmVjdXJzaXZlIHRyYXZlcnNhbCBvZiB0aGUgRE9NLiBUaGlzCi0gICAgICAgIC8vIHdpbGwgYXZvaWQgYSBzdGFjayBvdmVyZmxvdyBmb3IgRE9NcyB3aXRoIGhpZ2ggZGVwdGguCi0gICAgICAgIHdoaWxlIChub2RlICE9IG51bGwpIHsKLSAgICAgICAgICAgIGJlZ2luTm9kZShub2RlKTsKLSAgICAgICAgICAgIE5vZGUgbmV4dCA9IG5vZGUuZ2V0Rmlyc3RDaGlsZCgpOwotICAgICAgICAgICAgd2hpbGUgKG5leHQgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZpbmlzaE5vZGUobm9kZSk7Ci0gICAgICAgICAgICAgICAgaWYgKHRvcCA9PSBub2RlKSB7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBuZXh0ID0gbm9kZS5nZXROZXh0U2libGluZygpOwotICAgICAgICAgICAgICAgIGlmIChuZXh0ID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgbm9kZSA9IG5vZGUuZ2V0UGFyZW50Tm9kZSgpOwotICAgICAgICAgICAgICAgICAgICBpZiAobm9kZSA9PSBudWxsIHx8IHRvcCA9PSBub2RlKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAobm9kZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluaXNoTm9kZShub2RlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIG5leHQgPSBudWxsOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBub2RlID0gbmV4dDsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKiBEbyBwcm9jZXNzaW5nIGZvciB0aGUgc3RhcnQgb2YgYSBub2RlLiAqLwotICAgIHByaXZhdGUgdm9pZCBiZWdpbk5vZGUoTm9kZSBub2RlKSB7Ci0gICAgICAgIHN3aXRjaCAobm9kZS5nZXROb2RlVHlwZSgpKSB7Ci0gICAgICAgICAgICBjYXNlIE5vZGUuRUxFTUVOVF9OT0RFOgotICAgICAgICAgICAgICAgIGZDdXJyZW50RWxlbWVudCA9IG5vZGU7Ci0gICAgICAgICAgICAgICAgLy8gcHVzaCBuYW1lc3BhY2UgY29udGV4dAotICAgICAgICAgICAgICAgIGZOYW1lc3BhY2VDb250ZXh0LnB1c2hDb250ZXh0KCk7Ci0gICAgICAgICAgICAgICAgLy8gc3RhcnQgZWxlbWVudAotICAgICAgICAgICAgICAgIGZpbGxRTmFtZShmRWxlbWVudFFOYW1lLCBub2RlKTsKLSAgICAgICAgICAgICAgICBwcm9jZXNzQXR0cmlidXRlcyhub2RlLmdldEF0dHJpYnV0ZXMoKSk7Ci0gICAgICAgICAgICAgICAgZlNjaGVtYVZhbGlkYXRvci5zdGFydEVsZW1lbnQoZkVsZW1lbnRRTmFtZSwgZkF0dHJpYnV0ZXMsIG51bGwpOwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgY2FzZSBOb2RlLlRFWFRfTk9ERToKLSAgICAgICAgICAgICAgICBpZiAoZkRPTVZhbGlkYXRvckhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBmRE9NVmFsaWRhdG9ySGFuZGxlci5zZXRJZ25vcmluZ0NoYXJhY3RlcnModHJ1ZSk7Ci0gICAgICAgICAgICAgICAgICAgIHNlbmRDaGFyYWN0ZXJzVG9WYWxpZGF0b3Iobm9kZS5nZXROb2RlVmFsdWUoKSk7Ci0gICAgICAgICAgICAgICAgICAgIGZET01WYWxpZGF0b3JIYW5kbGVyLnNldElnbm9yaW5nQ2hhcmFjdGVycyhmYWxzZSk7Ci0gICAgICAgICAgICAgICAgICAgIGZET01WYWxpZGF0b3JIYW5kbGVyLmNoYXJhY3RlcnMoKFRleHQpIG5vZGUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgc2VuZENoYXJhY3RlcnNUb1ZhbGlkYXRvcihub2RlLmdldE5vZGVWYWx1ZSgpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICBjYXNlIE5vZGUuQ0RBVEFfU0VDVElPTl9OT0RFOgotICAgICAgICAgICAgICAgIGlmIChmRE9NVmFsaWRhdG9ySGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZET01WYWxpZGF0b3JIYW5kbGVyLnNldElnbm9yaW5nQ2hhcmFjdGVycyh0cnVlKTsKLSAgICAgICAgICAgICAgICAgICAgZlNjaGVtYVZhbGlkYXRvci5zdGFydENEQVRBKG51bGwpOwotICAgICAgICAgICAgICAgICAgICBzZW5kQ2hhcmFjdGVyc1RvVmFsaWRhdG9yKG5vZGUuZ2V0Tm9kZVZhbHVlKCkpOwotICAgICAgICAgICAgICAgICAgICBmU2NoZW1hVmFsaWRhdG9yLmVuZENEQVRBKG51bGwpOwotICAgICAgICAgICAgICAgICAgICBmRE9NVmFsaWRhdG9ySGFuZGxlci5zZXRJZ25vcmluZ0NoYXJhY3RlcnMoZmFsc2UpOwotICAgICAgICAgICAgICAgICAgICBmRE9NVmFsaWRhdG9ySGFuZGxlci5jZGF0YSgoQ0RBVEFTZWN0aW9uKSBub2RlKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIGZTY2hlbWFWYWxpZGF0b3Iuc3RhcnRDREFUQShudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgc2VuZENoYXJhY3RlcnNUb1ZhbGlkYXRvcihub2RlLmdldE5vZGVWYWx1ZSgpKTsKLSAgICAgICAgICAgICAgICAgICAgZlNjaGVtYVZhbGlkYXRvci5lbmRDREFUQShudWxsKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICBjYXNlIE5vZGUuUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFOgotICAgICAgICAgICAgICAgIC8qKgotICAgICAgICAgICAgICAgICAqIFRoZSB2YWxpZGF0b3IgZG9lcyBub3RoaW5nIHdpdGggcHJvY2Vzc2luZyBpbnN0cnVjdGlvbnMgc28gYnlwYXNzIGl0LgotICAgICAgICAgICAgICAgICAqIFNlbmQgdGhlIFByb2Nlc3NpbmdJbnN0cnVjdGlvbiBub2RlIGRpcmVjdGx5IHRvIHRoZSByZXN1bHQgYnVpbGRlci4KLSAgICAgICAgICAgICAgICAgKi8KLSAgICAgICAgICAgICAgICBpZiAoZkRPTVZhbGlkYXRvckhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBmRE9NVmFsaWRhdG9ySGFuZGxlci5wcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oKFByb2Nlc3NpbmdJbnN0cnVjdGlvbikgbm9kZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgY2FzZSBOb2RlLkNPTU1FTlRfTk9ERToKLSAgICAgICAgICAgICAgICAvKioKLSAgICAgICAgICAgICAgICAgKiBUaGUgdmFsaWRhdG9yIGRvZXMgbm90aGluZyB3aXRoIGNvbW1lbnRzIHNvIGJ5cGFzcyBpdC4KLSAgICAgICAgICAgICAgICAgKiBTZW5kIHRoZSBDb21tZW50IG5vZGUgZGlyZWN0bHkgdG8gdGhlIHJlc3VsdCBidWlsZGVyLgotICAgICAgICAgICAgICAgICAqLwotICAgICAgICAgICAgICAgIGlmIChmRE9NVmFsaWRhdG9ySGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZET01WYWxpZGF0b3JIYW5kbGVyLmNvbW1lbnQoKENvbW1lbnQpIG5vZGUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIGNhc2UgTm9kZS5ET0NVTUVOVF9UWVBFX05PREU6Ci0gICAgICAgICAgICAgICAgLyoqCi0gICAgICAgICAgICAgICAgICogU2VuZCB0aGUgRG9jdW1lbnRUeXBlIG5vZGUgZGlyZWN0bHkgdG8gdGhlIHJlc3VsdCBidWlsZGVyLgotICAgICAgICAgICAgICAgICAqLwotICAgICAgICAgICAgICAgIGlmIChmRE9NVmFsaWRhdG9ySGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZET01WYWxpZGF0b3JIYW5kbGVyLmRvY3R5cGVEZWNsKChEb2N1bWVudFR5cGUpIG5vZGUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIGRlZmF1bHQ6IC8vIElnbm9yZSBvdGhlciBub2RlIHR5cGVzLgotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqIERvIHByb2Nlc3NpbmcgZm9yIHRoZSBlbmQgb2YgYSBub2RlLiAqLwotICAgIHByaXZhdGUgdm9pZCBmaW5pc2hOb2RlKE5vZGUgbm9kZSkgewotICAgICAgICBpZiAobm9kZS5nZXROb2RlVHlwZSgpID09IE5vZGUuRUxFTUVOVF9OT0RFKSB7Ci0gICAgICAgICAgICBmQ3VycmVudEVsZW1lbnQgPSBub2RlOwotICAgICAgICAgICAgLy8gZW5kIGVsZW1lbnQKLSAgICAgICAgICAgIGZpbGxRTmFtZShmRWxlbWVudFFOYW1lLCBub2RlKTsKLSAgICAgICAgICAgIGZTY2hlbWFWYWxpZGF0b3IuZW5kRWxlbWVudChmRWxlbWVudFFOYW1lLCBudWxsKTsKLSAgICAgICAgICAgIC8vIHBvcCBuYW1lc3BhY2UgY29udGV4dAotICAgICAgICAgICAgZk5hbWVzcGFjZUNvbnRleHQucG9wQ29udGV4dCgpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRXh0cmFjdHMgTmFtZWROb2RlTWFwIG9mIGVudGl0aWVzLiBXZSBuZWVkIHRoaXMgdG8gdmFsaWRhdGUKLSAgICAgKiBlbGVtZW50cyBhbmQgYXR0cmlidXRlcyBvZiB0eXBlIHhzOkVOVElUWSwgeHM6RU5USVRJRVMgb3IKLSAgICAgKiB0eXBlcyBkZXJ2aWVkIGZyb20gdGhlbS4KLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgc2V0dXBFbnRpdHlNYXAoRG9jdW1lbnQgZG9jKSB7Ci0gICAgICAgIGlmIChkb2MgIT0gbnVsbCkgewotICAgICAgICAgICAgRG9jdW1lbnRUeXBlIGRvY1R5cGUgPSBkb2MuZ2V0RG9jdHlwZSgpOwotICAgICAgICAgICAgaWYgKGRvY1R5cGUgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZFbnRpdGllcyA9IGRvY1R5cGUuZ2V0RW50aXRpZXMoKTsKLSAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZkVudGl0aWVzID0gbnVsbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXRzIHVwIGhhbmRsZXIgZm9yIDxjb2RlPkRPTVJlc3VsdDwvY29kZT4uCi0gICAgICovCi0gICAgcHJpdmF0ZSB2b2lkIHNldHVwRE9NUmVzdWx0SGFuZGxlcihET01Tb3VyY2Ugc291cmNlLCBET01SZXN1bHQgcmVzdWx0KSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICAgICAgLy8gSWYgdGhlcmUncyBubyBET01SZXN1bHQsIHVuc2V0IHRoZSB2YWxpZGF0b3IgaGFuZGxlcgotICAgICAgICBpZiAocmVzdWx0ID09IG51bGwpIHsKLSAgICAgICAgICAgIGZET01WYWxpZGF0b3JIYW5kbGVyID0gbnVsbDsKLSAgICAgICAgICAgIGZTY2hlbWFWYWxpZGF0b3Iuc2V0RG9jdW1lbnRIYW5kbGVyKG51bGwpOwotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0gICAgICAgIGZpbmFsIE5vZGUgbm9kZVJlc3VsdCA9IHJlc3VsdC5nZXROb2RlKCk7Ci0gICAgICAgIC8vIElmIHRoZSBzb3VyY2Ugbm9kZSBhbmQgcmVzdWx0IG5vZGUgYXJlIHRoZSBzYW1lIHVzZSB0aGUgRE9NUmVzdWx0QXVnbWVudG9yLgotICAgICAgICAvLyBPdGhlcndpc2UgdXNlIHRoZSBET01SZXN1bHRCdWlsZGVyLgotICAgICAgICBpZiAoc291cmNlLmdldE5vZGUoKSA9PSBub2RlUmVzdWx0KSB7Ci0gICAgICAgICAgICBmRE9NVmFsaWRhdG9ySGFuZGxlciA9IGZET01SZXN1bHRBdWdtZW50b3I7Ci0gICAgICAgICAgICBmRE9NUmVzdWx0QXVnbWVudG9yLnNldERPTVJlc3VsdChyZXN1bHQpOwotICAgICAgICAgICAgZlNjaGVtYVZhbGlkYXRvci5zZXREb2N1bWVudEhhbmRsZXIoZkRPTVJlc3VsdEF1Z21lbnRvcik7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKHJlc3VsdC5nZXROb2RlKCkgPT0gbnVsbCkgewotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkgPSBmQ29tcG9uZW50TWFuYWdlci5nZXRGZWF0dXJlKENvbnN0YW50cy5PUkFDTEVfRkVBVFVSRV9TRVJWSUNFX01FQ0hBTklTTSkgPwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5uZXdJbnN0YW5jZSgpIDogbmV3IERvY3VtZW50QnVpbGRlckZhY3RvcnlJbXBsKCk7Ci0gICAgICAgICAgICAgICAgZmFjdG9yeS5zZXROYW1lc3BhY2VBd2FyZSh0cnVlKTsKLSAgICAgICAgICAgICAgICBEb2N1bWVudEJ1aWxkZXIgYnVpbGRlciA9IGZhY3RvcnkubmV3RG9jdW1lbnRCdWlsZGVyKCk7Ci0gICAgICAgICAgICAgICAgcmVzdWx0LnNldE5vZGUoYnVpbGRlci5uZXdEb2N1bWVudCgpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhdGNoIChQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKGUpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGZET01WYWxpZGF0b3JIYW5kbGVyID0gZkRPTVJlc3VsdEJ1aWxkZXI7Ci0gICAgICAgIGZET01SZXN1bHRCdWlsZGVyLnNldERPTVJlc3VsdChyZXN1bHQpOwotICAgICAgICBmU2NoZW1hVmFsaWRhdG9yLnNldERvY3VtZW50SGFuZGxlcihmRE9NUmVzdWx0QnVpbGRlcik7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIGZpbGxRTmFtZShRTmFtZSB0b0ZpbGwsIE5vZGUgbm9kZSkgewotICAgICAgICBmaW5hbCBTdHJpbmcgcHJlZml4ID0gbm9kZS5nZXRQcmVmaXgoKTsKLSAgICAgICAgZmluYWwgU3RyaW5nIGxvY2FsTmFtZSA9IG5vZGUuZ2V0TG9jYWxOYW1lKCk7Ci0gICAgICAgIGZpbmFsIFN0cmluZyByYXdOYW1lID0gbm9kZS5nZXROb2RlTmFtZSgpOwotICAgICAgICBmaW5hbCBTdHJpbmcgbmFtZXNwYWNlID0gbm9kZS5nZXROYW1lc3BhY2VVUkkoKTsKLQotICAgICAgICB0b0ZpbGwudXJpID0gKG5hbWVzcGFjZSAhPSBudWxsICYmIG5hbWVzcGFjZS5sZW5ndGgoKSA+IDApID8gZlN5bWJvbFRhYmxlLmFkZFN5bWJvbChuYW1lc3BhY2UpIDogbnVsbDsKLSAgICAgICAgdG9GaWxsLnJhd25hbWUgPSAocmF3TmFtZSAhPSBudWxsKSA/IGZTeW1ib2xUYWJsZS5hZGRTeW1ib2wocmF3TmFtZSkgOiBYTUxTeW1ib2xzLkVNUFRZX1NUUklORzsKLQotICAgICAgICAvLyBJcyB0aGlzIGEgRE9NIGxldmVsMSBkb2N1bWVudD8KLSAgICAgICAgaWYgKGxvY2FsTmFtZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBpbnQgayA9IHJhd05hbWUuaW5kZXhPZignOicpOwotICAgICAgICAgICAgaWYgKGsgPiAwKSB7Ci0gICAgICAgICAgICAgICAgdG9GaWxsLnByZWZpeCA9IGZTeW1ib2xUYWJsZS5hZGRTeW1ib2wocmF3TmFtZS5zdWJzdHJpbmcoMCwgaykpOwotICAgICAgICAgICAgICAgIHRvRmlsbC5sb2NhbHBhcnQgPSBmU3ltYm9sVGFibGUuYWRkU3ltYm9sKHJhd05hbWUuc3Vic3RyaW5nKGsgKyAxKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICB0b0ZpbGwucHJlZml4ID0gWE1MU3ltYm9scy5FTVBUWV9TVFJJTkc7Ci0gICAgICAgICAgICAgICAgdG9GaWxsLmxvY2FscGFydCA9IHRvRmlsbC5yYXduYW1lOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgdG9GaWxsLnByZWZpeCA9IChwcmVmaXggIT0gbnVsbCkgPyBmU3ltYm9sVGFibGUuYWRkU3ltYm9sKHByZWZpeCkgOiBYTUxTeW1ib2xzLkVNUFRZX1NUUklORzsKLSAgICAgICAgICAgIHRvRmlsbC5sb2NhbHBhcnQgPSAobG9jYWxOYW1lICE9IG51bGwpID8gZlN5bWJvbFRhYmxlLmFkZFN5bWJvbChsb2NhbE5hbWUpIDogWE1MU3ltYm9scy5FTVBUWV9TVFJJTkc7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgcHJvY2Vzc0F0dHJpYnV0ZXMoTmFtZWROb2RlTWFwIGF0dHJNYXApIHsKLSAgICAgICAgZmluYWwgaW50IGF0dHJDb3VudCA9IGF0dHJNYXAuZ2V0TGVuZ3RoKCk7Ci0gICAgICAgIGZBdHRyaWJ1dGVzLnJlbW92ZUFsbEF0dHJpYnV0ZXMoKTsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhdHRyQ291bnQ7ICsraSkgewotICAgICAgICAgICAgQXR0ciBhdHRyID0gKEF0dHIpIGF0dHJNYXAuaXRlbShpKTsKLSAgICAgICAgICAgIFN0cmluZyB2YWx1ZSA9IGF0dHIuZ2V0VmFsdWUoKTsKLSAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgdmFsdWUgPSBYTUxTeW1ib2xzLkVNUFRZX1NUUklORzsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGZpbGxRTmFtZShmQXR0cmlidXRlUU5hbWUsIGF0dHIpOwotICAgICAgICAgICAgLy8gUkVWSVNJVDogQXNzdW1pbmcgYWxsIGF0dHJpYnV0ZXMgYXJlIG9mIHR5cGUgQ0RBVEEuIFRoZSBhY3R1YWwgdHlwZSBtYXkgbm90IG1hdHRlci4gLS0gbXJnbGF2YXMKLSAgICAgICAgICAgIGZBdHRyaWJ1dGVzLmFkZEF0dHJpYnV0ZU5TKGZBdHRyaWJ1dGVRTmFtZSwgWE1MU3ltYm9scy5mQ0RBVEFTeW1ib2wsIHZhbHVlKTsKLSAgICAgICAgICAgIGZBdHRyaWJ1dGVzLnNldFNwZWNpZmllZChpLCBhdHRyLmdldFNwZWNpZmllZCgpKTsKLSAgICAgICAgICAgIC8vIFJFVklTSVQ6IFNob3VsZCB3ZSBiZSBsb29raW5nIGF0IG5vbi1uYW1lc3BhY2UgYXR0cmlidXRlcwotICAgICAgICAgICAgLy8gZm9yIGFkZGl0aW9uYWwgbWFwcGluZ3M/IFNob3VsZCB3ZSBkZXRlY3QgaWxsZWdhbCBuYW1lc3BhY2UKLSAgICAgICAgICAgIC8vIGRlY2xhcmF0aW9ucyBhbmQgZXhjbHVkZSB0aGVtIGZyb20gdGhlIGNvbnRleHQ/IC0tIG1yZ2xhdmFzCi0gICAgICAgICAgICBpZiAoZkF0dHJpYnV0ZVFOYW1lLnVyaSA9PSBOYW1lc3BhY2VDb250ZXh0LlhNTE5TX1VSSSkgewotICAgICAgICAgICAgICAgIC8vIHByb2Nlc3MgbmFtZXNwYWNlIGF0dHJpYnV0ZQotICAgICAgICAgICAgICAgIGlmIChmQXR0cmlidXRlUU5hbWUucHJlZml4ID09IFhNTFN5bWJvbHMuUFJFRklYX1hNTE5TKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZOYW1lc3BhY2VDb250ZXh0LmRlY2xhcmVQcmVmaXgoZkF0dHJpYnV0ZVFOYW1lLmxvY2FscGFydCwgdmFsdWUubGVuZ3RoKCkgIT0gMCA/IGZTeW1ib2xUYWJsZS5hZGRTeW1ib2wodmFsdWUpIDogbnVsbCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICBmTmFtZXNwYWNlQ29udGV4dC5kZWNsYXJlUHJlZml4KFhNTFN5bWJvbHMuRU1QVFlfU1RSSU5HLCB2YWx1ZS5sZW5ndGgoKSAhPSAwID8gZlN5bWJvbFRhYmxlLmFkZFN5bWJvbCh2YWx1ZSkgOiBudWxsKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgc2VuZENoYXJhY3RlcnNUb1ZhbGlkYXRvcihTdHJpbmcgc3RyKSB7Ci0gICAgICAgIGlmIChzdHIgIT0gbnVsbCkgewotICAgICAgICAgICAgZmluYWwgaW50IGxlbmd0aCA9IHN0ci5sZW5ndGgoKTsKLSAgICAgICAgICAgIGZpbmFsIGludCByZW1haW5kZXIgPSBsZW5ndGggJiBDSFVOS19NQVNLOwotICAgICAgICAgICAgaWYgKHJlbWFpbmRlciA+IDApIHsKLSAgICAgICAgICAgICAgICBzdHIuZ2V0Q2hhcnMoMCwgcmVtYWluZGVyLCBmQ2hhckJ1ZmZlciwgMCk7Ci0gICAgICAgICAgICAgICAgZlRlbXBTdHJpbmcuc2V0VmFsdWVzKGZDaGFyQnVmZmVyLCAwLCByZW1haW5kZXIpOwotICAgICAgICAgICAgICAgIGZTY2hlbWFWYWxpZGF0b3IuY2hhcmFjdGVycyhmVGVtcFN0cmluZywgbnVsbCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpbnQgaSA9IHJlbWFpbmRlcjsKLSAgICAgICAgICAgIHdoaWxlIChpIDwgbGVuZ3RoKSB7Ci0gICAgICAgICAgICAgICAgc3RyLmdldENoYXJzKGksIGkgKz0gQ0hVTktfU0laRSwgZkNoYXJCdWZmZXIsIDApOwotICAgICAgICAgICAgICAgIGZUZW1wU3RyaW5nLnNldFZhbHVlcyhmQ2hhckJ1ZmZlciwgMCwgQ0hVTktfU0laRSk7Ci0gICAgICAgICAgICAgICAgZlNjaGVtYVZhbGlkYXRvci5jaGFyYWN0ZXJzKGZUZW1wU3RyaW5nLCBudWxsKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIE5vZGUgZ2V0Q3VycmVudEVsZW1lbnQoKSB7Ci0gICAgICAgIHJldHVybiBmQ3VycmVudEVsZW1lbnQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogTmFtZXNwYWNlQ29udGV4dCBmb3IgdGhlIERPTVNvdXJjZSwgaW5jbHVkZXMgY29udGV4dCBmb3IgYW5jZXN0b3Igbm9kZXMuCi0gICAgICovCi0gICAgZmluYWwgY2xhc3MgRE9NTmFtZXNwYWNlQ29udGV4dCBpbXBsZW1lbnRzIE5hbWVzcGFjZUNvbnRleHQgewotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIERhdGEKLSAgICAgICAgLy8KLQotICAgICAgICAvKioKLSAgICAgICAgICogTmFtZXNwYWNlIGJpbmRpbmcgaW5mb3JtYXRpb24uIFRoaXMgYXJyYXkgaXMgY29tcG9zZWQgb2YgYQotICAgICAgICAgKiBzZXJpZXMgb2YgdHVwbGVzIGNvbnRhaW5pbmcgdGhlIG5hbWVzcGFjZSBiaW5kaW5nIGluZm9ybWF0aW9uOgotICAgICAgICAgKiAmbHQ7cHJlZml4LCB1cmkmZ3Q7LgotICAgICAgICAgKi8KLSAgICAgICAgcHJvdGVjdGVkIFN0cmluZ1tdIGZOYW1lc3BhY2UgPSBuZXcgU3RyaW5nWzE2ICogMl07Ci0KLSAgICAgICAgLyoqIFRoZSBzaXplIG9mIHRoZSBuYW1lc3BhY2UgaW5mb3JtYXRpb24gYXJyYXkuICovCi0gICAgICAgIHByb3RlY3RlZCBpbnQgZk5hbWVzcGFjZVNpemUgPSAwOwotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBGbGFnIGluZGljYXRpbmcgd2hldGhlciB0aGUgbmFtZXNwYWNlIGNvbnRleHQKLSAgICAgICAgICogaGFzIGJlZW4gZnJvbSB0aGUgcm9vdCBub2RlJ3MgYW5jZXN0b3JzLgotICAgICAgICAgKi8KLSAgICAgICAgcHJvdGVjdGVkIGJvb2xlYW4gZkRPTUNvbnRleHRCdWlsdCA9IGZhbHNlOwotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIE1ldGhvZHMKLSAgICAgICAgLy8KLQotICAgICAgICBwdWJsaWMgdm9pZCBwdXNoQ29udGV4dCgpIHsKLSAgICAgICAgICAgIGZOYW1lc3BhY2VDb250ZXh0LnB1c2hDb250ZXh0KCk7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCBwb3BDb250ZXh0KCkgewotICAgICAgICAgICAgZk5hbWVzcGFjZUNvbnRleHQucG9wQ29udGV4dCgpOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIGJvb2xlYW4gZGVjbGFyZVByZWZpeChTdHJpbmcgcHJlZml4LCBTdHJpbmcgdXJpKSB7Ci0gICAgICAgICAgICByZXR1cm4gZk5hbWVzcGFjZUNvbnRleHQuZGVjbGFyZVByZWZpeChwcmVmaXgsIHVyaSk7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFVSSShTdHJpbmcgcHJlZml4KSB7Ci0gICAgICAgICAgICBTdHJpbmcgdXJpID0gZk5hbWVzcGFjZUNvbnRleHQuZ2V0VVJJKHByZWZpeCk7Ci0gICAgICAgICAgICBpZiAodXJpID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBpZiAoIWZET01Db250ZXh0QnVpbHQpIHsKLSAgICAgICAgICAgICAgICAgICAgZmlsbE5hbWVzcGFjZUNvbnRleHQoKTsKLSAgICAgICAgICAgICAgICAgICAgZkRPTUNvbnRleHRCdWlsdCA9IHRydWU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGlmIChmTmFtZXNwYWNlU2l6ZSA+IDAgJiYKLSAgICAgICAgICAgICAgICAgICAgIWZOYW1lc3BhY2VDb250ZXh0LmNvbnRhaW5zUHJlZml4KHByZWZpeCkpIHsKLSAgICAgICAgICAgICAgICAgICAgdXJpID0gZ2V0VVJJMChwcmVmaXgpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiB1cmk7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFByZWZpeChTdHJpbmcgdXJpKSB7Ci0gICAgICAgICAgICByZXR1cm4gZk5hbWVzcGFjZUNvbnRleHQuZ2V0UHJlZml4KHVyaSk7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgaW50IGdldERlY2xhcmVkUHJlZml4Q291bnQoKSB7Ci0gICAgICAgICAgICByZXR1cm4gZk5hbWVzcGFjZUNvbnRleHQuZ2V0RGVjbGFyZWRQcmVmaXhDb3VudCgpOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIFN0cmluZyBnZXREZWNsYXJlZFByZWZpeEF0KGludCBpbmRleCkgewotICAgICAgICAgICAgcmV0dXJuIGZOYW1lc3BhY2VDb250ZXh0LmdldERlY2xhcmVkUHJlZml4QXQoaW5kZXgpOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIEVudW1lcmF0aW9uIGdldEFsbFByZWZpeGVzKCkgewotICAgICAgICAgICAgcmV0dXJuIGZOYW1lc3BhY2VDb250ZXh0LmdldEFsbFByZWZpeGVzKCk7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCByZXNldCgpIHsKLSAgICAgICAgICAgIGZET01Db250ZXh0QnVpbHQgPSBmYWxzZTsKLSAgICAgICAgICAgIGZOYW1lc3BhY2VTaXplID0gMDsKLSAgICAgICAgfQotCi0gICAgICAgIHByaXZhdGUgdm9pZCBmaWxsTmFtZXNwYWNlQ29udGV4dCgpIHsKLSAgICAgICAgICAgIGlmIChmUm9vdCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgTm9kZSBjdXJyZW50Tm9kZSA9IGZSb290LmdldFBhcmVudE5vZGUoKTsKLSAgICAgICAgICAgICAgICB3aGlsZSAoY3VycmVudE5vZGUgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBpZiAoTm9kZS5FTEVNRU5UX05PREUgPT0gY3VycmVudE5vZGUuZ2V0Tm9kZVR5cGUoKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXMgPSBjdXJyZW50Tm9kZS5nZXRBdHRyaWJ1dGVzKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgYXR0ckNvdW50ID0gYXR0cmlidXRlcy5nZXRMZW5ndGgoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYXR0ckNvdW50OyArK2kpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdHRyIGF0dHIgPSAoQXR0cikgYXR0cmlidXRlcy5pdGVtKGkpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyB2YWx1ZSA9IGF0dHIuZ2V0VmFsdWUoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IFhNTFN5bWJvbHMuRU1QVFlfU1RSSU5HOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxsUU5hbWUoZkF0dHJpYnV0ZVFOYW1lLCBhdHRyKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBSRVZJU0lUOiBTaG91bGQgd2UgYmUgbG9va2luZyBhdCBub24tbmFtZXNwYWNlIGF0dHJpYnV0ZXMKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBmb3IgYWRkaXRpb25hbCBtYXBwaW5ncz8gU2hvdWxkIHdlIGRldGVjdCBpbGxlZ2FsIG5hbWVzcGFjZQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGRlY2xhcmF0aW9ucyBhbmQgZXhjbHVkZSB0aGVtIGZyb20gdGhlIGNvbnRleHQ/IC0tIG1yZ2xhdmFzCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZBdHRyaWJ1dGVRTmFtZS51cmkgPT0gTmFtZXNwYWNlQ29udGV4dC5YTUxOU19VUkkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcHJvY2VzcyBuYW1lc3BhY2UgYXR0cmlidXRlCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmQXR0cmlidXRlUU5hbWUucHJlZml4ID09IFhNTFN5bWJvbHMuUFJFRklYX1hNTE5TKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWNsYXJlUHJlZml4MChmQXR0cmlidXRlUU5hbWUubG9jYWxwYXJ0LCB2YWx1ZS5sZW5ndGgoKSAhPSAwID8gZlN5bWJvbFRhYmxlLmFkZFN5bWJvbCh2YWx1ZSkgOiBudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlY2xhcmVQcmVmaXgwKFhNTFN5bWJvbHMuRU1QVFlfU1RSSU5HLCB2YWx1ZS5sZW5ndGgoKSAhPSAwID8gZlN5bWJvbFRhYmxlLmFkZFN5bWJvbCh2YWx1ZSkgOiBudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGN1cnJlbnROb2RlID0gY3VycmVudE5vZGUuZ2V0UGFyZW50Tm9kZSgpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHByaXZhdGUgdm9pZCBkZWNsYXJlUHJlZml4MChTdHJpbmcgcHJlZml4LCBTdHJpbmcgdXJpKSB7Ci0gICAgICAgICAgICAvLyByZXNpemUgYXJyYXksIGlmIG5lZWRlZAotICAgICAgICAgICAgaWYgKGZOYW1lc3BhY2VTaXplID09IGZOYW1lc3BhY2UubGVuZ3RoKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nW10gbmFtZXNwYWNlYXJyYXkgPSBuZXcgU3RyaW5nW2ZOYW1lc3BhY2VTaXplICogMl07Ci0gICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShmTmFtZXNwYWNlLCAwLCBuYW1lc3BhY2VhcnJheSwgMCwgZk5hbWVzcGFjZVNpemUpOwotICAgICAgICAgICAgICAgIGZOYW1lc3BhY2UgPSBuYW1lc3BhY2VhcnJheTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gYmluZCBwcmVmaXggdG8gdXJpIGluIGN1cnJlbnQgY29udGV4dAotICAgICAgICAgICAgZk5hbWVzcGFjZVtmTmFtZXNwYWNlU2l6ZSsrXSA9IHByZWZpeDsKLSAgICAgICAgICAgIGZOYW1lc3BhY2VbZk5hbWVzcGFjZVNpemUrK10gPSB1cmk7Ci0gICAgICAgIH0KLQotICAgICAgICBwcml2YXRlIFN0cmluZyBnZXRVUkkwKFN0cmluZyBwcmVmaXgpIHsKLSAgICAgICAgICAgIC8vIGZpbmQgcHJlZml4IGluIHRoZSBET00gY29udGV4dAotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmTmFtZXNwYWNlU2l6ZTsgaSArPSAyKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGZOYW1lc3BhY2VbaV0gPT0gcHJlZml4KSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBmTmFtZXNwYWNlW2kgKyAxXTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyBwcmVmaXggbm90IGZvdW5kCi0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotICAgIH0KLQotfSAvLyBET01WYWxpZGF0b3JIZWxwZXIKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2pheHAvdmFsaWRhdGlvbi9EcmFjb25pYW5FcnJvckhhbmRsZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2pheHAvdmFsaWRhdGlvbi9EcmFjb25pYW5FcnJvckhhbmRsZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMTcxYTRiNS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9qYXhwL3ZhbGlkYXRpb24vRHJhY29uaWFuRXJyb3JIYW5kbGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw2MiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmpheHAudmFsaWRhdGlvbjsKLQotaW1wb3J0IG9yZy54bWwuc2F4LkVycm9ySGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb247Ci0KLS8qKgotICoge0BsaW5rIEVycm9ySGFuZGxlcn0gdGhhdCB0aHJvd3MgYWxsIGVycm9ycyBhbmQgZmF0YWwgZXJyb3JzLgotICoKLSAqIEBhdXRob3IgS29oc3VrZSBLYXdhZ3VjaGkgKGtvaHN1a2Uua2F3YWd1Y2hpQHN1bi5jb20pCi0gKi8KLWZpbmFsIGNsYXNzIERyYWNvbmlhbkVycm9ySGFuZGxlciBpbXBsZW1lbnRzIEVycm9ySGFuZGxlciB7Ci0KLSAgICAvKioKLSAgICAgKiBTaW5nbGV0b24gaW5zdGFuY2UuCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRHJhY29uaWFuRXJyb3JIYW5kbGVyIEVSUk9SX0hBTkRMRVJfSU5TVEFOQ0UKLSAgICAgICAgPSBuZXcgRHJhY29uaWFuRXJyb3JIYW5kbGVyKCk7Ci0KLSAgICBwcml2YXRlIERyYWNvbmlhbkVycm9ySGFuZGxlcigpIHt9Ci0KLSAgICAvKiogUmV0dXJucyB0aGUgb25lIGFuZCBvbmx5IGluc3RhbmNlIG9mIHRoaXMgZXJyb3IgaGFuZGxlci4gKi8KLSAgICBwdWJsaWMgc3RhdGljIERyYWNvbmlhbkVycm9ySGFuZGxlciBnZXRJbnN0YW5jZSgpIHsKLSAgICAgICAgcmV0dXJuIEVSUk9SX0hBTkRMRVJfSU5TVEFOQ0U7Ci0gICAgfQotCi0gICAgLyoqIFdhcm5pbmc6IElnbm9yZS4gKi8KLSAgICBwdWJsaWMgdm9pZCB3YXJuaW5nKFNBWFBhcnNlRXhjZXB0aW9uIGUpIHRocm93cyBTQVhFeGNlcHRpb24gewotICAgICAgICAvLyBub29wCi0gICAgfQotCi0gICAgLyoqIEVycm9yOiBUaHJvd3MgYmFjayBTQVhQYXJzZUV4Y2VwdGlvbi4gKi8KLSAgICBwdWJsaWMgdm9pZCBlcnJvcihTQVhQYXJzZUV4Y2VwdGlvbiBlKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICAgICAgdGhyb3cgZTsKLSAgICB9Ci0KLSAgICAvKiogRmF0YWwgRXJyb3I6IFRocm93cyBiYWNrIFNBWFBhcnNlRXhjZXB0aW9uLiAqLwotICAgIHB1YmxpYyB2b2lkIGZhdGFsRXJyb3IoU0FYUGFyc2VFeGNlcHRpb24gZSkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0gICAgICAgIHRocm93IGU7Ci0gICAgfQotCi19IC8vIERyYWNvbmlhbkVycm9ySGFuZGxlcgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvamF4cC92YWxpZGF0aW9uL0VtcHR5WE1MU2NoZW1hLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9qYXhwL3ZhbGlkYXRpb24vRW1wdHlYTUxTY2hlbWEuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZWNhMDBlOC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9qYXhwL3ZhbGlkYXRpb24vRW1wdHlYTUxTY2hlbWEuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDczICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuamF4cC52YWxpZGF0aW9uOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuZ3JhbW1hcnMuR3JhbW1hcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5ncmFtbWFycy5YTUxHcmFtbWFyRGVzY3JpcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuZ3JhbW1hcnMuWE1MR3JhbW1hclBvb2w7Ci0KLS8qKgotICogPHA+SW1wbGVtZW50YXRpb24gb2YgU2NoZW1hIGZvciBXM0MgWE1MIFNjaGVtYXMKLSAqIHdoaWNoIGNvbnRhaW5zIG5vIHNjaGVtYSBjb21wb25lbnRzLjwvcD4KLSAqCi0gKiBAYXV0aG9yIE1pY2hhZWwgR2xhdmFzc2V2aWNoLCBJQk0KLSAqIEB2ZXJzaW9uICRJZDogRW1wdHlYTUxTY2hlbWEuamF2YSx2IDEuNiAyMDEwLTExLTAxIDA0OjQwOjA4IGpvZWh3IEV4cCAkCi0gKi8KLWZpbmFsIGNsYXNzIEVtcHR5WE1MU2NoZW1hIGV4dGVuZHMgQWJzdHJhY3RYTUxTY2hlbWEgaW1wbGVtZW50cyBYTUxHcmFtbWFyUG9vbCB7Ci0KLSAgICAvKiogWmVybyBsZW5ndGggZ3JhbW1hciBhcnJheS4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBHcmFtbWFyIFtdIFpFUk9fTEVOR1RIX0dSQU1NQVJfQVJSQVkgPSBuZXcgR3JhbW1hciBbMF07Ci0KLSAgICBwdWJsaWMgRW1wdHlYTUxTY2hlbWEoKSB7fQotCi0gICAgLyoKLSAgICAgKiBYTUxHcmFtbWFyUG9vbCBtZXRob2RzCi0gICAgICovCi0KLSAgICBwdWJsaWMgR3JhbW1hcltdIHJldHJpZXZlSW5pdGlhbEdyYW1tYXJTZXQoU3RyaW5nIGdyYW1tYXJUeXBlKSB7Ci0gICAgICAgIHJldHVybiBaRVJPX0xFTkdUSF9HUkFNTUFSX0FSUkFZOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGNhY2hlR3JhbW1hcnMoU3RyaW5nIGdyYW1tYXJUeXBlLCBHcmFtbWFyW10gZ3JhbW1hcnMpIHt9Ci0KLSAgICBwdWJsaWMgR3JhbW1hciByZXRyaWV2ZUdyYW1tYXIoWE1MR3JhbW1hckRlc2NyaXB0aW9uIGRlc2MpIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgbG9ja1Bvb2woKSB7fQotCi0gICAgcHVibGljIHZvaWQgdW5sb2NrUG9vbCgpIHt9Ci0KLSAgICBwdWJsaWMgdm9pZCBjbGVhcigpIHt9Ci0KLSAgICAvKgotICAgICAqIFhTR3JhbW1hclBvb2xDb250YWluZXIgbWV0aG9kcwotICAgICAqLwotCi0gICAgcHVibGljIFhNTEdyYW1tYXJQb29sIGdldEdyYW1tYXJQb29sKCkgewotICAgICAgICByZXR1cm4gdGhpczsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0Z1bGx5Q29tcG9zZWQoKSB7Ci0gICAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotfSAvLyBFbXB0eVhNTFNjaGVtYQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvamF4cC92YWxpZGF0aW9uL0Vycm9ySGFuZGxlckFkYXB0b3IuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2pheHAvdmFsaWRhdGlvbi9FcnJvckhhbmRsZXJBZGFwdG9yLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDEyNGJjYmMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvamF4cC92YWxpZGF0aW9uL0Vycm9ySGFuZGxlckFkYXB0b3IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEyMiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAwLTIwMDIgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYZXJjZXMiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIEludGVybmF0aW9uYWwKLSAqIEJ1c2luZXNzIE1hY2hpbmVzLCBJbmMuLCBodHRwOi8vd3d3LmFwYWNoZS5vcmcuICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5qYXhwLnZhbGlkYXRpb247Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MRXJyb3JIYW5kbGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxQYXJzZUV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5FcnJvckhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotCi0vKioKLSAqIFJlY2VpdmVzIGVycm9ycyB0aHJvdWdoIFhlcmNlcyB7QGxpbmsgWE1MRXJyb3JIYW5kbGVyfQotICogYW5kIHBhc3MgdGhlbSBkb3duIHRvIFNBWCB7QGxpbmsgRXJyb3JIYW5kbGVyfS4KLSAqCi0gKiBAYXV0aG9yCi0gKiAgICAgS29oc3VrZSBLYXdhZ3VjaGkgKGtvaHN1a2Uua2F3YWd1Y2hpQHN1bi5jb20pCi0gKi8KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBFcnJvckhhbmRsZXJBZGFwdG9yIGltcGxlbWVudHMgWE1MRXJyb3JIYW5kbGVyCi17Ci0gICAgLyoqIHNldCB0byB0cnVlIGlmIHRoZXJlIHdhcyBhbnkgZXJyb3IuICovCi0gICAgcHJpdmF0ZSBib29sZWFuIGhhZEVycm9yID0gZmFsc2U7Ci0KLSAgICAvKioKLSAgICAgKiByZXR1cm5zIGlmIHRoZXJlIHdhcyBhbiBlcnJvciBzaW5jZSB0aGUgbGFzdCBpbnZvY2F0aW9uIG9mCi0gICAgICogdGhlIHJlc2V0RXJyb3IgbWV0aG9kLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGhhZEVycm9yKCkgeyByZXR1cm4gaGFkRXJyb3I7IH0KLSAgICAvKiogcmVzZXRzIHRoZSBlcnJvciBmbGFnLiAqLwotICAgIHB1YmxpYyB2b2lkIHJlc2V0KCkgeyBoYWRFcnJvciA9IGZhbHNlOyB9Ci0KLSAgICAvKioKLSAgICAgKiBJbXBsZW1lbnRlZCBieSB0aGUgZGVyaXZlZCBjbGFzcyB0byByZXR1cm4gdGhlIGFjdHVhbAotICAgICAqIHtAbGluayBFcnJvckhhbmRsZXJ9IHRvIHdoaWNoIGVycm9ycyBhcmUgc2VudC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gYWx3YXlzIHJldHVybiBub24tbnVsbCB2YWxpZCBvYmplY3QuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGFic3RyYWN0IEVycm9ySGFuZGxlciBnZXRFcnJvckhhbmRsZXIoKTsKLQotICAgIHB1YmxpYyB2b2lkIGZhdGFsRXJyb3IoIFN0cmluZyBkb21haW4sIFN0cmluZyBrZXksIFhNTFBhcnNlRXhjZXB0aW9uIGUgKSB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBoYWRFcnJvciA9IHRydWU7Ci0gICAgICAgICAgICBnZXRFcnJvckhhbmRsZXIoKS5mYXRhbEVycm9yKCBVdGlsLnRvU0FYUGFyc2VFeGNlcHRpb24oZSkgKTsKLSAgICAgICAgfSBjYXRjaCggU0FYRXhjZXB0aW9uIHNlICkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFdyYXBwZWRTQVhFeGNlcHRpb24oc2UpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgZXJyb3IoIFN0cmluZyBkb21haW4sIFN0cmluZyBrZXksIFhNTFBhcnNlRXhjZXB0aW9uIGUgKSB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBoYWRFcnJvciA9IHRydWU7Ci0gICAgICAgICAgICBnZXRFcnJvckhhbmRsZXIoKS5lcnJvciggVXRpbC50b1NBWFBhcnNlRXhjZXB0aW9uKGUpICk7Ci0gICAgICAgIH0gY2F0Y2goIFNBWEV4Y2VwdGlvbiBzZSApIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBXcmFwcGVkU0FYRXhjZXB0aW9uKHNlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHdhcm5pbmcoIFN0cmluZyBkb21haW4sIFN0cmluZyBrZXksIFhNTFBhcnNlRXhjZXB0aW9uIGUgKSB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBnZXRFcnJvckhhbmRsZXIoKS53YXJuaW5nKCBVdGlsLnRvU0FYUGFyc2VFeGNlcHRpb24oZSkgKTsKLSAgICAgICAgfSBjYXRjaCggU0FYRXhjZXB0aW9uIHNlICkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFdyYXBwZWRTQVhFeGNlcHRpb24oc2UpOwotICAgICAgICB9Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9qYXhwL3ZhbGlkYXRpb24vSkFYUFZhbGlkYXRpb25NZXNzYWdlRm9ybWF0dGVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9qYXhwL3ZhbGlkYXRpb24vSkFYUFZhbGlkYXRpb25NZXNzYWdlRm9ybWF0dGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDVjNTEwNTMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvamF4cC92YWxpZGF0aW9uL0pBWFBWYWxpZGF0aW9uTWVzc2FnZUZvcm1hdHRlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTAyICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuamF4cC52YWxpZGF0aW9uOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlscy5TZWN1cml0eVN1cHBvcnQ7Ci1pbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKLWltcG9ydCBqYXZhLnV0aWwuTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uOwotaW1wb3J0IGphdmEudXRpbC5SZXNvdXJjZUJ1bmRsZTsKLQotLyoqCi0gKiA8cD5Vc2VkIHRvIGZvcm1hdCBKQVhQIFZhbGlkYXRpb24gQVBJIGVycm9yIG1lc3NhZ2VzIHVzaW5nIGEgc3BlY2lmaWVkIGxvY2FsZS48L3A+Ci0gKgotICogQGF1dGhvciBNaWNoYWVsIEdsYXZhc3NldmljaCwgSUJNCi0gKiBAdmVyc2lvbiAkSWQ6IEpBWFBWYWxpZGF0aW9uTWVzc2FnZUZvcm1hdHRlci5qYXZhLHYgMS41IDIwMTAtMTEtMDEgMDQ6NDA6MDggam9laHcgRXhwICQKLSAqLwotZmluYWwgY2xhc3MgSkFYUFZhbGlkYXRpb25NZXNzYWdlRm9ybWF0dGVyIHsKLQotICAgIC8qKgotICAgICAqIEZvcm1hdHMgYSBtZXNzYWdlIHdpdGggdGhlIHNwZWNpZmllZCBhcmd1bWVudHMgdXNpbmcgdGhlIGdpdmVuCi0gICAgICogbG9jYWxlIGluZm9ybWF0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIGxvY2FsZSAgICBUaGUgbG9jYWxlIG9mIHRoZSBtZXNzYWdlLgotICAgICAqIEBwYXJhbSBrZXkgICAgICAgVGhlIG1lc3NhZ2Uga2V5LgotICAgICAqIEBwYXJhbSBhcmd1bWVudHMgVGhlIG1lc3NhZ2UgcmVwbGFjZW1lbnQgdGV4dCBhcmd1bWVudHMuIFRoZSBvcmRlcgotICAgICAqICAgICAgICAgICAgICAgICAgb2YgdGhlIGFyZ3VtZW50cyBtdXN0IG1hdGNoIHRoYXQgb2YgdGhlIHBsYWNlaG9sZGVycwotICAgICAqICAgICAgICAgICAgICAgICAgaW4gdGhlIGFjdHVhbCBtZXNzYWdlLgotICAgICAqCi0gICAgICogQHJldHVybiAgICAgICAgICB0aGUgZm9ybWF0dGVkIG1lc3NhZ2UuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGhlIG1lc3NhZ2Ugd2l0aCB0aGUKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGVjaWZpZWQga2V5IGNhbm5vdCBiZSBmb3VuZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBmb3JtYXRNZXNzYWdlKExvY2FsZSBsb2NhbGUsCi0gICAgICAgIFN0cmluZyBrZXksIE9iamVjdFtdIGFyZ3VtZW50cykKLSAgICAgICAgdGhyb3dzIE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgUmVzb3VyY2VCdW5kbGUgcmVzb3VyY2VCdW5kbGUgPSBudWxsOwotICAgICAgICBpZiAobG9jYWxlICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJlc291cmNlQnVuZGxlID0KLSAgICAgICAgICAgICAgICBTZWN1cml0eVN1cHBvcnQuZ2V0UmVzb3VyY2VCdW5kbGUoImNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5tc2cuSkFYUFZhbGlkYXRpb25NZXNzYWdlcyIsIGxvY2FsZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICByZXNvdXJjZUJ1bmRsZSA9Ci0gICAgICAgICAgICAgICAgU2VjdXJpdHlTdXBwb3J0LmdldFJlc291cmNlQnVuZGxlKCJjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwubXNnLkpBWFBWYWxpZGF0aW9uTWVzc2FnZXMiKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIGZvcm1hdCBtZXNzYWdlCi0gICAgICAgIFN0cmluZyBtc2c7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBtc2cgPSByZXNvdXJjZUJ1bmRsZS5nZXRTdHJpbmcoa2V5KTsKLSAgICAgICAgICAgIGlmIChhcmd1bWVudHMgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgIG1zZyA9IGphdmEudGV4dC5NZXNzYWdlRm9ybWF0LmZvcm1hdChtc2csIGFyZ3VtZW50cyk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgICAgICBtc2cgPSByZXNvdXJjZUJ1bmRsZS5nZXRTdHJpbmcoIkZvcm1hdEZhaWxlZCIpOwotICAgICAgICAgICAgICAgICAgICBtc2cgKz0gIiAiICsgcmVzb3VyY2VCdW5kbGUuZ2V0U3RyaW5nKGtleSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gZXJyb3IKLSAgICAgICAgY2F0Y2ggKE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICBtc2cgPSByZXNvdXJjZUJ1bmRsZS5nZXRTdHJpbmcoIkJhZE1lc3NhZ2VLZXkiKTsKLSAgICAgICAgICAgIHRocm93IG5ldyBNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24oa2V5LCBtc2csIGtleSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBubyBtZXNzYWdlCi0gICAgICAgIGlmIChtc2cgPT0gbnVsbCkgewotICAgICAgICAgICAgbXNnID0ga2V5OwotICAgICAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAwKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nQnVmZmVyIHN0ciA9IG5ldyBTdHJpbmdCdWZmZXIobXNnKTsKLSAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKCc/Jyk7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGkgPiAwKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKCcmJyk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgc3RyLmFwcGVuZChTdHJpbmcudmFsdWVPZihhcmd1bWVudHNbaV0pKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG1zZzsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9qYXhwL3ZhbGlkYXRpb24vUmVhZE9ubHlHcmFtbWFyUG9vbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvamF4cC92YWxpZGF0aW9uL1JlYWRPbmx5R3JhbW1hclBvb2wuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZjE3N2ExMS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9qYXhwL3ZhbGlkYXRpb24vUmVhZE9ubHlHcmFtbWFyUG9vbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNjUgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5qYXhwLnZhbGlkYXRpb247Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5ncmFtbWFycy5HcmFtbWFyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLmdyYW1tYXJzLlhNTEdyYW1tYXJEZXNjcmlwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5ncmFtbWFycy5YTUxHcmFtbWFyUG9vbDsKLQotLyoqCi0gKiA8cD5GaWx0ZXIge0BsaW5rIFhNTEdyYW1tYXJQb29sfSB0aGF0IGV4cG9zZXMgYQotICogcmVhZC1vbmx5IHZpZXcgb2YgdGhlIHVuZGVybHlpbmcgcG9vbC48L3A+Ci0gKgotICogQGF1dGhvciBLb2hzdWtlIEthd2FndWNoaSAoa29oc3VrZS5rYXdhZ3VjaGlAc3VuLmNvbSkKLSAqLwotZmluYWwgY2xhc3MgUmVhZE9ubHlHcmFtbWFyUG9vbCBpbXBsZW1lbnRzIFhNTEdyYW1tYXJQb29sIHsKLQotICAgIHByaXZhdGUgZmluYWwgWE1MR3JhbW1hclBvb2wgY29yZTsKLQotICAgIHB1YmxpYyBSZWFkT25seUdyYW1tYXJQb29sKCBYTUxHcmFtbWFyUG9vbCBwb29sICkgewotICAgICAgICB0aGlzLmNvcmUgPSBwb29sOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGNhY2hlR3JhbW1hcnMoU3RyaW5nIGdyYW1tYXJUeXBlLCBHcmFtbWFyW10gZ3JhbW1hcnMpIHsKLSAgICAgICAgLy8gbm9vcC4gZG9uJ3QgbGV0IGNhY2hpbmcgdG8gaGFwcGVuCi0gICAgfQotCi0gICAgcHVibGljIHZvaWQgY2xlYXIoKSB7Ci0gICAgICAgIC8vIG5vb3AuIGNhY2hlIGlzIHJlYWQtb25seS4KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBsb2NrUG9vbCgpIHsKLSAgICAgICAgLy8gbm9vcC4gdGhpcyBwb29sIGlzIGFsd2F5cyByZWFkLW9ubHkKLSAgICB9Ci0KLSAgICBwdWJsaWMgR3JhbW1hciByZXRyaWV2ZUdyYW1tYXIoWE1MR3JhbW1hckRlc2NyaXB0aW9uIGRlc2MpIHsKLSAgICAgICAgcmV0dXJuIGNvcmUucmV0cmlldmVHcmFtbWFyKGRlc2MpOwotICAgIH0KLQotICAgIHB1YmxpYyBHcmFtbWFyW10gcmV0cmlldmVJbml0aWFsR3JhbW1hclNldChTdHJpbmcgZ3JhbW1hclR5cGUpIHsKLSAgICAgICAgcmV0dXJuIGNvcmUucmV0cmlldmVJbml0aWFsR3JhbW1hclNldChncmFtbWFyVHlwZSk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgdW5sb2NrUG9vbCgpIHsKLSAgICAgICAgLy8gbm9vcC4gdGhpcyBwb29sIGlzIGFsd2F5cyByZWFkLW9ubHkuCi0gICAgfQotCi19IC8vIFJlYWRPbmx5R3JhbW1hclBvb2wKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2pheHAvdmFsaWRhdGlvbi9TaW1wbGVYTUxTY2hlbWEuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2pheHAvdmFsaWRhdGlvbi9TaW1wbGVYTUxTY2hlbWEuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOWI3YjY3ZC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9qYXhwL3ZhbGlkYXRpb24vU2ltcGxlWE1MU2NoZW1hLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4MSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmpheHAudmFsaWRhdGlvbjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLmdyYW1tYXJzLkdyYW1tYXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuZ3JhbW1hcnMuWE1MR3JhbW1hckRlc2NyaXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLmdyYW1tYXJzLlhNTEdyYW1tYXJQb29sOwotCi0vKioKLSAqIDxwPkltcGxlbWVudGF0aW9uIG9mIFNjaGVtYSBmb3IgVzNDIFhNTCBTY2hlbWFzIHdoaWNoCi0gKiBjb250YWlucyBzY2hlbWEgY29tcG9uZW50cyBmcm9tIG9uZSB0YXJnZXQgbmFtZXNwYWNlLjwvcD4KLSAqCi0gKiBAYXV0aG9yIE1pY2hhZWwgR2xhdmFzc2V2aWNoLCBJQk0KLSAqLwotZmluYWwgY2xhc3MgU2ltcGxlWE1MU2NoZW1hIGV4dGVuZHMgQWJzdHJhY3RYTUxTY2hlbWEgaW1wbGVtZW50cyBYTUxHcmFtbWFyUG9vbCB7Ci0KLSAgICAvKiogWmVybyBsZW5ndGggZ3JhbW1hciBhcnJheS4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBHcmFtbWFyIFtdIFpFUk9fTEVOR1RIX0dSQU1NQVJfQVJSQVkgPSBuZXcgR3JhbW1hciBbMF07Ci0KLSAgICBwcml2YXRlIEdyYW1tYXIgZkdyYW1tYXI7Ci0gICAgcHJpdmF0ZSBHcmFtbWFyW10gZkdyYW1tYXJzOwotICAgIHByaXZhdGUgWE1MR3JhbW1hckRlc2NyaXB0aW9uIGZHcmFtbWFyRGVzY3JpcHRpb247Ci0KLSAgICBwdWJsaWMgU2ltcGxlWE1MU2NoZW1hKEdyYW1tYXIgZ3JhbW1hcikgewotICAgICAgICBmR3JhbW1hciA9IGdyYW1tYXI7Ci0gICAgICAgIGZHcmFtbWFycyA9IG5ldyBHcmFtbWFyW10ge2dyYW1tYXJ9OwotICAgICAgICBmR3JhbW1hckRlc2NyaXB0aW9uID0gZ3JhbW1hci5nZXRHcmFtbWFyRGVzY3JpcHRpb24oKTsKLSAgICB9Ci0KLSAgICAvKgotICAgICAqIFhNTEdyYW1tYXJQb29sIG1ldGhvZHMKLSAgICAgKi8KLQotICAgIHB1YmxpYyBHcmFtbWFyW10gcmV0cmlldmVJbml0aWFsR3JhbW1hclNldChTdHJpbmcgZ3JhbW1hclR5cGUpIHsKLSAgICAgICAgcmV0dXJuIFhNTEdyYW1tYXJEZXNjcmlwdGlvbi5YTUxfU0NIRU1BLmVxdWFscyhncmFtbWFyVHlwZSkgPwotICAgICAgICAgICAgICAgIChHcmFtbWFyW10pIGZHcmFtbWFycy5jbG9uZSgpIDogWkVST19MRU5HVEhfR1JBTU1BUl9BUlJBWTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBjYWNoZUdyYW1tYXJzKFN0cmluZyBncmFtbWFyVHlwZSwgR3JhbW1hcltdIGdyYW1tYXJzKSB7fQotCi0gICAgcHVibGljIEdyYW1tYXIgcmV0cmlldmVHcmFtbWFyKFhNTEdyYW1tYXJEZXNjcmlwdGlvbiBkZXNjKSB7Ci0gICAgICAgIHJldHVybiBmR3JhbW1hckRlc2NyaXB0aW9uLmVxdWFscyhkZXNjKSA/IGZHcmFtbWFyIDogbnVsbDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBsb2NrUG9vbCgpIHt9Ci0KLSAgICBwdWJsaWMgdm9pZCB1bmxvY2tQb29sKCkge30KLQotICAgIHB1YmxpYyB2b2lkIGNsZWFyKCkge30KLQotICAgIC8qCi0gICAgICogWFNHcmFtbWFyUG9vbENvbnRhaW5lciBtZXRob2RzCi0gICAgICovCi0KLSAgICBwdWJsaWMgWE1MR3JhbW1hclBvb2wgZ2V0R3JhbW1hclBvb2woKSB7Ci0gICAgICAgIHJldHVybiB0aGlzOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGlzRnVsbHlDb21wb3NlZCgpIHsKLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotCi19IC8vIFNpbXBsZVhNTFNjaGVtYQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvamF4cC92YWxpZGF0aW9uL1NvZnRSZWZlcmVuY2VHcmFtbWFyUG9vbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvamF4cC92YWxpZGF0aW9uL1NvZnRSZWZlcmVuY2VHcmFtbWFyUG9vbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyZWViNTUzLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2pheHAvdmFsaWRhdGlvbi9Tb2Z0UmVmZXJlbmNlR3JhbW1hclBvb2wuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQzNSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmpheHAudmFsaWRhdGlvbjsKLQotaW1wb3J0IGphdmEubGFuZy5yZWYuUmVmZXJlbmNlOwotaW1wb3J0IGphdmEubGFuZy5yZWYuUmVmZXJlbmNlUXVldWU7Ci1pbXBvcnQgamF2YS5sYW5nLnJlZi5Tb2Z0UmVmZXJlbmNlOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuZ3JhbW1hcnMuR3JhbW1hcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5ncmFtbWFycy5YTUxHcmFtbWFyRGVzY3JpcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuZ3JhbW1hcnMuWE1MU2NoZW1hRGVzY3JpcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuZ3JhbW1hcnMuWE1MR3JhbW1hclBvb2w7Ci0KLS8qKgotICogPHA+VGhpcyBncmFtbWFyIHBvb2wgaXMgYSBtZW1vcnkgc2Vuc2l0aXZlIGNhY2hlLiBUaGUgZ3JhbW1hcnMKLSAqIHN0b3JlZCBpbiB0aGUgcG9vbCBhcmUgc29mdGx5IHJlYWNoYWJsZSBhbmQgbWF5IGJlIGNsZWFyZWQgYnkKLSAqIHRoZSBnYXJiYWdlIGNvbGxlY3RvciBpbiByZXNwb25zZSB0byBtZW1vcnkgZGVtYW5kLiBFcXVhbGl0eQotICogb2YgPGNvZGU+WE1MU2NoZW1hRGVzY3JpcHRpb248L2NvZGU+cyBpcyBkZXRlcm1pbmVkIHVzaW5nIGJvdGgKLSAqIHRoZSB0YXJnZXQgbmFtZXNwYWNlIGZvciB0aGUgc2NoZW1hIGFuZCBzY2hlbWEgbG9jYXRpb24uPC9wPgotICoKLSAqIEBhdXRob3IgTWljaGFlbCBHbGF2YXNzZXZpY2gsIElCTQotICovCi1maW5hbCBjbGFzcyBTb2Z0UmVmZXJlbmNlR3JhbW1hclBvb2wgaW1wbGVtZW50cyBYTUxHcmFtbWFyUG9vbCB7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0YW50cwotICAgIC8vCi0KLSAgICAvKiogRGVmYXVsdCBzaXplLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgaW50IFRBQkxFX1NJWkUgPSAxMTsKLQotICAgIC8qKiBaZXJvIGxlbmd0aCBncmFtbWFyIGFycmF5LiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgR3JhbW1hciBbXSBaRVJPX0xFTkdUSF9HUkFNTUFSX0FSUkFZID0gbmV3IEdyYW1tYXIgWzBdOwotCi0gICAgLy8KLSAgICAvLyBEYXRhCi0gICAgLy8KLQotICAgIC8qKiBHcmFtbWFycy4gKi8KLSAgICBwcm90ZWN0ZWQgRW50cnkgW10gZkdyYW1tYXJzID0gbnVsbDsKLQotICAgIC8qKiBGbGFnIGluZGljYXRpbmcgd2hldGhlciB0aGlzIHBvb2wgaXMgbG9ja2VkICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZlBvb2xJc0xvY2tlZDsKLQotICAgIC8qKiBUaGUgbnVtYmVyIG9mIGdyYW1tYXJzIGluIHRoZSBwb29sICovCi0gICAgcHJvdGVjdGVkIGludCBmR3JhbW1hckNvdW50ID0gMDsKLQotICAgIC8qKiBSZWZlcmVuY2UgcXVldWUgZm9yIGNsZWFyZWQgZ3JhbW1hciByZWZlcmVuY2VzICovCi0gICAgcHJvdGVjdGVkIGZpbmFsIFJlZmVyZW5jZVF1ZXVlIGZSZWZlcmVuY2VRdWV1ZSA9IG5ldyBSZWZlcmVuY2VRdWV1ZSgpOwotCi0gICAgLy8KLSAgICAvLyBDb25zdHJ1Y3RvcnMKLSAgICAvLwotCi0gICAgLyoqIENvbnN0cnVjdHMgYSBncmFtbWFyIHBvb2wgd2l0aCBhIGRlZmF1bHQgbnVtYmVyIG9mIGJ1Y2tldHMuICovCi0gICAgcHVibGljIFNvZnRSZWZlcmVuY2VHcmFtbWFyUG9vbCgpIHsKLSAgICAgICAgZkdyYW1tYXJzID0gbmV3IEVudHJ5W1RBQkxFX1NJWkVdOwotICAgICAgICBmUG9vbElzTG9ja2VkID0gZmFsc2U7Ci0gICAgfSAvLyA8aW5pdD4oKQotCi0gICAgLyoqIENvbnN0cnVjdHMgYSBncmFtbWFyIHBvb2wgd2l0aCBhIHNwZWNpZmllZCBudW1iZXIgb2YgYnVja2V0cy4gKi8KLSAgICBwdWJsaWMgU29mdFJlZmVyZW5jZUdyYW1tYXJQb29sKGludCBpbml0aWFsQ2FwYWNpdHkpIHsKLSAgICAgICAgZkdyYW1tYXJzID0gbmV3IEVudHJ5W2luaXRpYWxDYXBhY2l0eV07Ci0gICAgICAgIGZQb29sSXNMb2NrZWQgPSBmYWxzZTsKLSAgICB9Ci0KLSAgICAvLwotICAgIC8vIFhNTEdyYW1tYXJQb29sIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyogPHA+IFJldHJpZXZlIHRoZSBpbml0aWFsIGtub3duIHNldCBvZiBncmFtbWFycy4gVGhpcyBtZXRob2QgaXMKLSAgICAgKiBjYWxsZWQgYnkgYSB2YWxpZGF0b3IgYmVmb3JlIHRoZSB2YWxpZGF0aW9uIHN0YXJ0cy4gVGhlIGFwcGxpY2F0aW9uCi0gICAgICogY2FuIHByb3ZpZGUgYW4gaW5pdGlhbCBzZXQgb2YgZ3JhbW1hcnMgYXZhaWxhYmxlIHRvIHRoZSBjdXJyZW50Ci0gICAgICogdmFsaWRhdGlvbiBhdHRlbXB0LiA8L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gZ3JhbW1hclR5cGUgVGhlIHR5cGUgb2YgdGhlIGdyYW1tYXIsIGZyb20gdGhlCi0gICAgICogICAgICAgICAgICAgICAgICAgIDxjb2RlPmNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLmdyYW1tYXJzLlhNTEdyYW1tYXJEZXNjcmlwdGlvbjwvY29kZT4KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgaW50ZXJmYWNlLgotICAgICAqIEByZXR1cm4gICAgICAgICAgICBUaGUgc2V0IG9mIGdyYW1tYXJzIHRoZSB2YWxpZGF0b3IgbWF5IHB1dCBpbiBpdHMgImJ1Y2tldCIKLSAgICAgKi8KLSAgICBwdWJsaWMgR3JhbW1hciBbXSByZXRyaWV2ZUluaXRpYWxHcmFtbWFyU2V0IChTdHJpbmcgZ3JhbW1hclR5cGUpIHsKLSAgICAgICAgc3luY2hyb25pemVkIChmR3JhbW1hcnMpIHsKLSAgICAgICAgICAgIGNsZWFuKCk7Ci0gICAgICAgICAgICAvLyBSZXR1cm4gbm8gZ3JhbW1hcnMuIFRoaXMgYWxsb3dzIHRoZSBnYXJiYWdlIGNvbGxlY3RvciB0byBzaWZ0Ci0gICAgICAgICAgICAvLyBvdXQgZ3JhbW1hcnMgd2hpY2ggYXJlIG5vdCBpbiB1c2Ugd2hlbiBtZW1vcnkgZGVtYW5kIGlzIGhpZ2guCi0gICAgICAgICAgICAvLyBJdCBhbHNvIGFsbG93cyB0aGUgcG9vbCB0byByZXR1cm4gdGhlICJyaWdodCIgc2NoZW1hIGdyYW1tYXIKLSAgICAgICAgICAgIC8vIGJhc2VkIG9uIHNjaGVtYSBsb2NhdGlvbnMuCi0gICAgICAgICAgICByZXR1cm4gWkVST19MRU5HVEhfR1JBTU1BUl9BUlJBWTsKLSAgICAgICAgfQotICAgIH0gLy8gcmV0cmlldmVJbml0aWFsR3JhbW1hclNldCAoU3RyaW5nKTogR3JhbW1hcltdCi0KLSAgICAvKiA8cD4gUmV0dXJuIHRoZSBmaW5hbCBzZXQgb2YgZ3JhbW1hcnMgdGhhdCB0aGUgdmFsaWRhdG9yIGVuZGVkIHVwCi0gICAgICogd2l0aC4gVGhpcyBtZXRob2QgaXMgY2FsbGVkIGFmdGVyIHRoZSB2YWxpZGF0aW9uIGZpbmlzaGVzLiBUaGUKLSAgICAgKiBhcHBsaWNhdGlvbiBtYXkgdGhlbiBjaG9vc2UgdG8gY2FjaGUgc29tZSBvZiB0aGUgcmV0dXJuZWQgZ3JhbW1hcnMuPC9wPgotICAgICAqIDxwPkluIHRoaXMgaW1wbGVtZW50YXRpb24sIHdlIG1ha2Ugb3VyIGNob2ljZSBiYXNlZCBvbiB3aGV0aGVyIHRoaXMgb2JqZWN0Ci0gICAgICogaXMgImxvY2tlZCItLXRoYXQgaXMsIHdoZXRoZXIgdGhlIGFwcGxpY2F0aW9uIGhhcyBpbnN0cnVjdGVkCi0gICAgICogdXMgbm90IHRvIGFjY2VwdCBhbnkgbmV3IGdyYW1tYXJzLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBncmFtbWFyVHlwZSBUaGUgdHlwZSBvZiB0aGUgZ3JhbW1hcnMgYmVpbmcgcmV0dXJuZWQ7Ci0gICAgICogQHBhcmFtIGdyYW1tYXJzICAgIEFuIGFycmF5IGNvbnRhaW5pbmcgdGhlIHNldCBvZiBncmFtbWFycyBiZWluZwotICAgICAqICAgICAgICAgICAgICAgICAgICByZXR1cm5lZDsgb3JkZXIgaXMgbm90IHNpZ25pZmljYW50LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGNhY2hlR3JhbW1hcnMoU3RyaW5nIGdyYW1tYXJUeXBlLCBHcmFtbWFyW10gZ3JhbW1hcnMpIHsKLSAgICAgICAgaWYgKCFmUG9vbElzTG9ja2VkKSB7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGdyYW1tYXJzLmxlbmd0aDsgKytpKSB7Ci0gICAgICAgICAgICAgICAgcHV0R3JhbW1hcihncmFtbWFyc1tpXSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9IC8vIGNhY2hlR3JhbW1hcnMoU3RyaW5nLCBHcmFtbWFyW10pOwotCi0gICAgLyogPHA+IFRoaXMgbWV0aG9kIHJlcXVlc3RzIHRoYXQgdGhlIGFwcGxpY2F0aW9uIHJldHJpZXZlIGEgZ3JhbW1hcgotICAgICAqIGNvcnJlc3BvbmRpbmcgdG8gdGhlIGdpdmVuIEdyYW1tYXJJZGVudGlmaWVyIGZyb20gaXRzIGNhY2hlLgotICAgICAqIElmIGl0IGNhbm5vdCBkbyBzbyBpdCBtdXN0IHJldHVybiBudWxsOyB0aGUgcGFyc2VyIHdpbGwgdGhlbgotICAgICAqIGNhbGwgdGhlIEVudGl0eVJlc29sdmVyLiA8L3A+Ci0gICAgICogPHN0cm9uZz5BbiBhcHBsaWNhdGlvbiBtdXN0IG5vdCBjYWxsIGl0cyBFbnRpdHlSZXNvbHZlciBpdHNlbGYKLSAgICAgKiBmcm9tIHRoaXMgbWV0aG9kOyB0aGlzIG1heSByZXN1bHQgaW4gaW5maW5pdGUgcmVjdXJzaW9ucy48L3N0cm9uZz4KLSAgICAgKgotICAgICAqIFRoaXMgaW1wbGVtZW50YXRpb24gY2hvb3NlcyB0byB1c2UgdGhlIHJvb3QgZWxlbWVudCBuYW1lIHRvIGlkZW50aWZ5IGEgRFREIGdyYW1tYXIKLSAgICAgKiBhbmQgdGhlIHRhcmdldCBuYW1lc3BhY2UgdG8gaWRlbnRpZnkgYSBTY2hlbWEgZ3JhbW1hci4KLSAgICAgKgotICAgICAqIEBwYXJhbSBkZXNjIFRoZSBkZXNjcmlwdGlvbiBvZiB0aGUgR3JhbW1hciBiZWluZyByZXF1ZXN0ZWQuCi0gICAgICogQHJldHVybiAgICAgVGhlIEdyYW1tYXIgY29ycmVzcG9uZGluZyB0byB0aGlzIGRlc2NyaXB0aW9uIG9yIG51bGwgaWYKLSAgICAgKiAgICAgICAgICAgICBubyBzdWNoIEdyYW1tYXIgaXMga25vd24uCi0gICAgICovCi0gICAgcHVibGljIEdyYW1tYXIgcmV0cmlldmVHcmFtbWFyKFhNTEdyYW1tYXJEZXNjcmlwdGlvbiBkZXNjKSB7Ci0gICAgICAgIHJldHVybiBnZXRHcmFtbWFyKGRlc2MpOwotICAgIH0gLy8gcmV0cmlldmVHcmFtbWFyKFhNTEdyYW1tYXJEZXNjcmlwdGlvbik6ICBHcmFtbWFyCi0KLSAgICAvLwotICAgIC8vIFB1YmxpYyBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFB1dHMgdGhlIHNwZWNpZmllZCBncmFtbWFyIGludG8gdGhlIGdyYW1tYXIgcG9vbCBhbmQgYXNzb2NpYXRlcyBpdCB0bwotICAgICAqIGl0cyByb290IGVsZW1lbnQgbmFtZSBvciBpdHMgdGFyZ2V0IG5hbWVzcGFjZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBncmFtbWFyIFRoZSBHcmFtbWFyLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHB1dEdyYW1tYXIoR3JhbW1hciBncmFtbWFyKSB7Ci0gICAgICAgIGlmICghZlBvb2xJc0xvY2tlZCkgewotICAgICAgICAgICAgc3luY2hyb25pemVkIChmR3JhbW1hcnMpIHsKLSAgICAgICAgICAgICAgICBjbGVhbigpOwotICAgICAgICAgICAgICAgIFhNTEdyYW1tYXJEZXNjcmlwdGlvbiBkZXNjID0gZ3JhbW1hci5nZXRHcmFtbWFyRGVzY3JpcHRpb24oKTsKLSAgICAgICAgICAgICAgICBpbnQgaGFzaCA9IGhhc2hDb2RlKGRlc2MpOwotICAgICAgICAgICAgICAgIGludCBpbmRleCA9IChoYXNoICYgMHg3RkZGRkZGRikgJSBmR3JhbW1hcnMubGVuZ3RoOwotICAgICAgICAgICAgICAgIGZvciAoRW50cnkgZW50cnkgPSBmR3JhbW1hcnNbaW5kZXhdOyBlbnRyeSAhPSBudWxsOyBlbnRyeSA9IGVudHJ5Lm5leHQpIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGVudHJ5Lmhhc2ggPT0gaGFzaCAmJiBlcXVhbHMoZW50cnkuZGVzYywgZGVzYykpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlbnRyeS5ncmFtbWFyLmdldCgpICE9IGdyYW1tYXIpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbnRyeS5ncmFtbWFyID0gbmV3IFNvZnRHcmFtbWFyUmVmZXJlbmNlKGVudHJ5LCBncmFtbWFyLCBmUmVmZXJlbmNlUXVldWUpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIC8vIGNyZWF0ZSBhIG5ldyBlbnRyeQotICAgICAgICAgICAgICAgIEVudHJ5IGVudHJ5ID0gbmV3IEVudHJ5KGhhc2gsIGluZGV4LCBkZXNjLCBncmFtbWFyLCBmR3JhbW1hcnNbaW5kZXhdLCBmUmVmZXJlbmNlUXVldWUpOwotICAgICAgICAgICAgICAgIGZHcmFtbWFyc1tpbmRleF0gPSBlbnRyeTsKLSAgICAgICAgICAgICAgICBmR3JhbW1hckNvdW50Kys7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9IC8vIHB1dEdyYW1tYXIoR3JhbW1hcikKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIGdyYW1tYXIgYXNzb2NpYXRlZCB0byB0aGUgc3BlY2lmaWVkIGdyYW1tYXIgZGVzY3JpcHRpb24uCi0gICAgICogQ3VycmVudGx5LCB0aGUgcm9vdCBlbGVtZW50IG5hbWUgaXMgdXNlZCBhcyB0aGUga2V5IGZvciBEVEQgZ3JhbW1hcnMKLSAgICAgKiBhbmQgdGhlIHRhcmdldCBuYW1lc3BhY2UgIGlzIHVzZWQgYXMgdGhlIGtleSBmb3IgU2NoZW1hIGdyYW1tYXJzLgotICAgICAqCi0gICAgICogQHBhcmFtIGRlc2MgVGhlIEdyYW1tYXIgRGVzY3JpcHRpb24uCi0gICAgICovCi0gICAgcHVibGljIEdyYW1tYXIgZ2V0R3JhbW1hcihYTUxHcmFtbWFyRGVzY3JpcHRpb24gZGVzYykgewotICAgICAgICBzeW5jaHJvbml6ZWQgKGZHcmFtbWFycykgewotICAgICAgICAgICAgY2xlYW4oKTsKLSAgICAgICAgICAgIGludCBoYXNoID0gaGFzaENvZGUoZGVzYyk7Ci0gICAgICAgICAgICBpbnQgaW5kZXggPSAoaGFzaCAmIDB4N0ZGRkZGRkYpICUgZkdyYW1tYXJzLmxlbmd0aDsKLSAgICAgICAgICAgIGZvciAoRW50cnkgZW50cnkgPSBmR3JhbW1hcnNbaW5kZXhdOyBlbnRyeSAhPSBudWxsOyBlbnRyeSA9IGVudHJ5Lm5leHQpIHsKLSAgICAgICAgICAgICAgICBHcmFtbWFyIHRlbXBHcmFtbWFyID0gKEdyYW1tYXIpIGVudHJ5LmdyYW1tYXIuZ2V0KCk7Ci0gICAgICAgICAgICAgICAgLyoqIElmIHRoZSBzb2Z0IHJlZmVyZW5jZSBoYXMgYmVlbiBjbGVhcmVkLCByZW1vdmUgdGhpcyBlbnRyeSBmcm9tIHRoZSBwb29sLiAqLwotICAgICAgICAgICAgICAgIGlmICh0ZW1wR3JhbW1hciA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJlbW92ZUVudHJ5KGVudHJ5KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSBpZiAoKGVudHJ5Lmhhc2ggPT0gaGFzaCkgJiYgZXF1YWxzKGVudHJ5LmRlc2MsIGRlc2MpKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiB0ZW1wR3JhbW1hcjsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotICAgIH0gLy8gZ2V0R3JhbW1hcihYTUxHcmFtbWFyRGVzY3JpcHRpb24pOkdyYW1tYXIKLQotICAgIC8qKgotICAgICAqIFJlbW92ZXMgdGhlIGdyYW1tYXIgYXNzb2NpYXRlZCB0byB0aGUgc3BlY2lmaWVkIGdyYW1tYXIgZGVzY3JpcHRpb24gZnJvbSB0aGUKLSAgICAgKiBncmFtbWFyIHBvb2wgYW5kIHJldHVybnMgdGhlIHJlbW92ZWQgZ3JhbW1hci4gQ3VycmVudGx5LCB0aGUgcm9vdCBlbGVtZW50IG5hbWUKLSAgICAgKiBpcyB1c2VkIGFzIHRoZSBrZXkgZm9yIERURCBncmFtbWFycyBhbmQgdGhlIHRhcmdldCBuYW1lc3BhY2UgIGlzIHVzZWQKLSAgICAgKiBhcyB0aGUga2V5IGZvciBTY2hlbWEgZ3JhbW1hcnMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZGVzYyBUaGUgR3JhbW1hciBEZXNjcmlwdGlvbi4KLSAgICAgKiBAcmV0dXJuICAgICBUaGUgcmVtb3ZlZCBncmFtbWFyLgotICAgICAqLwotICAgIHB1YmxpYyBHcmFtbWFyIHJlbW92ZUdyYW1tYXIoWE1MR3JhbW1hckRlc2NyaXB0aW9uIGRlc2MpIHsKLSAgICAgICAgc3luY2hyb25pemVkIChmR3JhbW1hcnMpIHsKLSAgICAgICAgICAgIGNsZWFuKCk7Ci0gICAgICAgICAgICBpbnQgaGFzaCA9IGhhc2hDb2RlKGRlc2MpOwotICAgICAgICAgICAgaW50IGluZGV4ID0gKGhhc2ggJiAweDdGRkZGRkZGKSAlIGZHcmFtbWFycy5sZW5ndGg7Ci0gICAgICAgICAgICBmb3IgKEVudHJ5IGVudHJ5ID0gZkdyYW1tYXJzW2luZGV4XTsgZW50cnkgIT0gbnVsbDsgZW50cnkgPSBlbnRyeS5uZXh0KSB7Ci0gICAgICAgICAgICAgICAgaWYgKChlbnRyeS5oYXNoID09IGhhc2gpICYmIGVxdWFscyhlbnRyeS5kZXNjLCBkZXNjKSkgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVtb3ZlRW50cnkoZW50cnkpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgfSAvLyByZW1vdmVHcmFtbWFyKFhNTEdyYW1tYXJEZXNjcmlwdGlvbik6R3JhbW1hcgotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBncmFtbWFyIHBvb2wgY29udGFpbnMgYSBncmFtbWFyIGFzc29jaWF0ZWQKLSAgICAgKiB0byB0aGUgc3BlY2lmaWVkIGdyYW1tYXIgZGVzY3JpcHRpb24uIEN1cnJlbnRseSwgdGhlIHJvb3QgZWxlbWVudCBuYW1lCi0gICAgICogaXMgdXNlZCBhcyB0aGUga2V5IGZvciBEVEQgZ3JhbW1hcnMgYW5kIHRoZSB0YXJnZXQgbmFtZXNwYWNlICBpcyB1c2VkCi0gICAgICogYXMgdGhlIGtleSBmb3IgU2NoZW1hIGdyYW1tYXJzLgotICAgICAqCi0gICAgICogQHBhcmFtIGRlc2MgVGhlIEdyYW1tYXIgRGVzY3JpcHRpb24uCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNHcmFtbWFyKFhNTEdyYW1tYXJEZXNjcmlwdGlvbiBkZXNjKSB7Ci0gICAgICAgIHN5bmNocm9uaXplZCAoZkdyYW1tYXJzKSB7Ci0gICAgICAgICAgICBjbGVhbigpOwotICAgICAgICAgICAgaW50IGhhc2ggPSBoYXNoQ29kZShkZXNjKTsKLSAgICAgICAgICAgIGludCBpbmRleCA9IChoYXNoICYgMHg3RkZGRkZGRikgJSBmR3JhbW1hcnMubGVuZ3RoOwotICAgICAgICAgICAgZm9yIChFbnRyeSBlbnRyeSA9IGZHcmFtbWFyc1tpbmRleF07IGVudHJ5ICE9IG51bGwgOyBlbnRyeSA9IGVudHJ5Lm5leHQpIHsKLSAgICAgICAgICAgICAgICBHcmFtbWFyIHRlbXBHcmFtbWFyID0gKEdyYW1tYXIpIGVudHJ5LmdyYW1tYXIuZ2V0KCk7Ci0gICAgICAgICAgICAgICAgLyoqIElmIHRoZSBzb2Z0IHJlZmVyZW5jZSBoYXMgYmVlbiBjbGVhcmVkLCByZW1vdmUgdGhpcyBlbnRyeSBmcm9tIHRoZSBwb29sLiAqLwotICAgICAgICAgICAgICAgIGlmICh0ZW1wR3JhbW1hciA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJlbW92ZUVudHJ5KGVudHJ5KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSBpZiAoKGVudHJ5Lmhhc2ggPT0gaGFzaCkgJiYgZXF1YWxzKGVudHJ5LmRlc2MsIGRlc2MpKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotICAgIH0gLy8gY29udGFpbnNHcmFtbWFyKFhNTEdyYW1tYXJEZXNjcmlwdGlvbik6Ym9vbGVhbgotCi0gICAgLyogPHA+IFNldHMgdGhpcyBncmFtbWFyIHBvb2wgdG8gYSAibG9ja2VkIiBzdGF0ZS0taS5lLiwKLSAgICAgKiBubyBuZXcgZ3JhbW1hcnMgd2lsbCBiZSBhZGRlZCB1bnRpbCBpdCBpcyAidW5sb2NrZWQiLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGxvY2tQb29sKCkgewotICAgICAgICBmUG9vbElzTG9ja2VkID0gdHJ1ZTsKLSAgICB9IC8vIGxvY2tQb29sKCkKLQotICAgIC8qIDxwPiBTZXRzIHRoaXMgZ3JhbW1hciBwb29sIHRvIGFuICJ1bmxvY2tlZCIgc3RhdGUtLWkuZS4sCi0gICAgICogbmV3IGdyYW1tYXJzIHdpbGwgYmUgYWRkZWQgd2hlbiBwdXRHcmFtbWFyIG9yIGNhY2hlR3JhbW1hcnMKLSAgICAgKiBhcmUgY2FsbGVkLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHVubG9ja1Bvb2woKSB7Ci0gICAgICAgIGZQb29sSXNMb2NrZWQgPSBmYWxzZTsKLSAgICB9IC8vIHVubG9ja1Bvb2woKQotCi0gICAgLyoKLSAgICAgKiA8cD5UaGlzIG1ldGhvZCBjbGVhcnMgdGhlIHBvb2wtaS5lLiwgcmVtb3ZlcyByZWZlcmVuY2VzCi0gICAgICogdG8gYWxsIHRoZSBncmFtbWFycyBpbiBpdC48L3A+Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgY2xlYXIoKSB7Ci0gICAgICAgIGZvciAoaW50IGk9MDsgaTxmR3JhbW1hcnMubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgIGlmKGZHcmFtbWFyc1tpXSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZkdyYW1tYXJzW2ldLmNsZWFyKCk7Ci0gICAgICAgICAgICAgICAgZkdyYW1tYXJzW2ldID0gbnVsbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBmR3JhbW1hckNvdW50ID0gMDsKLSAgICB9IC8vIGNsZWFyKCkKLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIGNoZWNrcyB3aGV0aGVyIHR3byBncmFtbWFycyBhcmUgdGhlIHNhbWUuIEN1cnJlbnRseSwgd2UgY29tcGFyZQotICAgICAqIHRoZSByb290IGVsZW1lbnQgbmFtZXMgZm9yIERURCBncmFtbWFycyBhbmQgdGhlIHRhcmdldCBuYW1lc3BhY2VzIGZvciBTY2hlbWEgZ3JhbW1hcnMuCi0gICAgICogVGhlIGFwcGxpY2F0aW9uIGNhbiBvdmVycmlkZSB0aGlzIGJlaGF2aW91ciBhbmQgYWRkIGl0cyBvd24gbG9naWMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZGVzYzEgVGhlIGdyYW1tYXIgZGVzY3JpcHRpb24KLSAgICAgKiBAcGFyYW0gZGVzYzIgVGhlIGdyYW1tYXIgZGVzY3JpcHRpb24gb2YgdGhlIGdyYW1tYXIgdG8gYmUgY29tcGFyZWQgdG8KLSAgICAgKiBAcmV0dXJuICAgICAgVHJ1ZSBpZiB0aGUgZ3JhbW1hcnMgYXJlIGVxdWFsLCBvdGhlcndpc2UgZmFsc2UKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoWE1MR3JhbW1hckRlc2NyaXB0aW9uIGRlc2MxLCBYTUxHcmFtbWFyRGVzY3JpcHRpb24gZGVzYzIpIHsKLSAgICAgICAgaWYgKGRlc2MxIGluc3RhbmNlb2YgWE1MU2NoZW1hRGVzY3JpcHRpb24pIHsKLSAgICAgICAgICAgIGlmICghKGRlc2MyIGluc3RhbmNlb2YgWE1MU2NoZW1hRGVzY3JpcHRpb24pKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZmluYWwgWE1MU2NoZW1hRGVzY3JpcHRpb24gc2QxID0gKFhNTFNjaGVtYURlc2NyaXB0aW9uKSBkZXNjMTsKLSAgICAgICAgICAgIGZpbmFsIFhNTFNjaGVtYURlc2NyaXB0aW9uIHNkMiA9IChYTUxTY2hlbWFEZXNjcmlwdGlvbikgZGVzYzI7Ci0gICAgICAgICAgICBmaW5hbCBTdHJpbmcgdGFyZ2V0TmFtZXNwYWNlID0gc2QxLmdldFRhcmdldE5hbWVzcGFjZSgpOwotICAgICAgICAgICAgaWYgKHRhcmdldE5hbWVzcGFjZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgaWYgKCF0YXJnZXROYW1lc3BhY2UuZXF1YWxzKHNkMi5nZXRUYXJnZXROYW1lc3BhY2UoKSkpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKHNkMi5nZXRUYXJnZXROYW1lc3BhY2UoKSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gVGhlIEpBWFAgMS4zIHNwZWMgc2F5cyB0aGF0IHRoZSBpbXBsZW1lbnRhdGlvbiBjYW4gYXNzdW1lIHRoYXQKLSAgICAgICAgICAgIC8vIGlmIHR3byBzY2hlbWEgbG9jYXRpb24gaGludHMgYXJlIHRoZSBzYW1lIHRoZXkgYWx3YXlzIHJlc29sdmUKLSAgICAgICAgICAgIC8vIHRvIHRoZSBzYW1lIGRvY3VtZW50LiBJbiB0aGUgZGVmYXVsdCBncmFtbWFyIHBvb2wgaW1wbGVtZW50YXRpb24KLSAgICAgICAgICAgIC8vIHdlIG9ubHkgbG9vayBhdCB0aGUgdGFyZ2V0IG5hbWVzcGFjZXMuIEhlcmUgd2UgYWxzbyBjb21wYXJlCi0gICAgICAgICAgICAvLyBsb2NhdGlvbiBoaW50cy4KLSAgICAgICAgICAgIGZpbmFsIFN0cmluZyBleHBhbmRlZFN5c3RlbUlkID0gc2QxLmdldEV4cGFuZGVkU3lzdGVtSWQoKTsKLSAgICAgICAgICAgIGlmIChleHBhbmRlZFN5c3RlbUlkICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBpZiAoIWV4cGFuZGVkU3lzdGVtSWQuZXF1YWxzKHNkMi5nZXRFeHBhbmRlZFN5c3RlbUlkKCkpKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChzZDIuZ2V0RXhwYW5kZWRTeXN0ZW1JZCgpICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZGVzYzEuZXF1YWxzKGRlc2MyKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBoYXNoIGNvZGUgdmFsdWUgZm9yIHRoZSBnaXZlbiBncmFtbWFyIGRlc2NyaXB0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIGRlc2MgVGhlIGdyYW1tYXIgZGVzY3JpcHRpb24KLSAgICAgKiBAcmV0dXJuICAgICBUaGUgaGFzaCBjb2RlIHZhbHVlCi0gICAgICovCi0gICAgcHVibGljIGludCBoYXNoQ29kZShYTUxHcmFtbWFyRGVzY3JpcHRpb24gZGVzYykgewotICAgICAgICBpZiAoZGVzYyBpbnN0YW5jZW9mIFhNTFNjaGVtYURlc2NyaXB0aW9uKSB7Ci0gICAgICAgICAgICBmaW5hbCBYTUxTY2hlbWFEZXNjcmlwdGlvbiBzZCA9IChYTUxTY2hlbWFEZXNjcmlwdGlvbikgZGVzYzsKLSAgICAgICAgICAgIGZpbmFsIFN0cmluZyB0YXJnZXROYW1lc3BhY2UgPSBzZC5nZXRUYXJnZXROYW1lc3BhY2UoKTsKLSAgICAgICAgICAgIGZpbmFsIFN0cmluZyBleHBhbmRlZFN5c3RlbUlkID0gc2QuZ2V0RXhwYW5kZWRTeXN0ZW1JZCgpOwotICAgICAgICAgICAgaW50IGhhc2ggPSAodGFyZ2V0TmFtZXNwYWNlICE9IG51bGwpID8gdGFyZ2V0TmFtZXNwYWNlLmhhc2hDb2RlKCkgOiAwOwotICAgICAgICAgICAgaGFzaCBePSAoZXhwYW5kZWRTeXN0ZW1JZCAhPSBudWxsKSA/IGV4cGFuZGVkU3lzdGVtSWQuaGFzaENvZGUoKSA6IDA7Ci0gICAgICAgICAgICByZXR1cm4gaGFzaDsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZGVzYy5oYXNoQ29kZSgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJlbW92ZXMgdGhlIGdpdmVuIGVudHJ5IGZyb20gdGhlIHBvb2wKLSAgICAgKgotICAgICAqIEBwYXJhbSBlbnRyeSB0aGUgZW50cnkgdG8gcmVtb3ZlCi0gICAgICogQHJldHVybiBUaGUgZ3JhbW1hciBhdHRhY2hlZCB0byB0aGlzIGVudHJ5Ci0gICAgICovCi0gICAgcHJpdmF0ZSBHcmFtbWFyIHJlbW92ZUVudHJ5KEVudHJ5IGVudHJ5KSB7Ci0gICAgICAgIGlmIChlbnRyeS5wcmV2ICE9IG51bGwpIHsKLSAgICAgICAgICAgIGVudHJ5LnByZXYubmV4dCA9IGVudHJ5Lm5leHQ7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBmR3JhbW1hcnNbZW50cnkuYnVja2V0XSA9IGVudHJ5Lm5leHQ7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGVudHJ5Lm5leHQgIT0gbnVsbCkgewotICAgICAgICAgICAgZW50cnkubmV4dC5wcmV2ID0gZW50cnkucHJldjsKLSAgICAgICAgfQotICAgICAgICAtLWZHcmFtbWFyQ291bnQ7Ci0gICAgICAgIGVudHJ5LmdyYW1tYXIuZW50cnkgPSBudWxsOwotICAgICAgICByZXR1cm4gKEdyYW1tYXIpIGVudHJ5LmdyYW1tYXIuZ2V0KCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmVtb3ZlcyBzdGFsZSBlbnRyaWVzIGZyb20gdGhlIHBvb2wuCi0gICAgICovCi0gICAgcHJpdmF0ZSB2b2lkIGNsZWFuKCkgewotICAgICAgICBSZWZlcmVuY2UgcmVmID0gZlJlZmVyZW5jZVF1ZXVlLnBvbGwoKTsKLSAgICAgICAgd2hpbGUgKHJlZiAhPSBudWxsKSB7Ci0gICAgICAgICAgICBFbnRyeSBlbnRyeSA9ICgoU29mdEdyYW1tYXJSZWZlcmVuY2UpIHJlZikuZW50cnk7Ci0gICAgICAgICAgICBpZiAoZW50cnkgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJlbW92ZUVudHJ5KGVudHJ5KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJlZiA9IGZSZWZlcmVuY2VRdWV1ZS5wb2xsKCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIGNsYXNzIGlzIGEgZ3JhbW1hciBwb29sIGVudHJ5LiBFYWNoIGVudHJ5IGFjdHMgYXMgYSBub2RlCi0gICAgICogaW4gYSBkb3VibHkgbGlua2VkIGxpc3QuCi0gICAgICovCi0gICAgc3RhdGljIGZpbmFsIGNsYXNzIEVudHJ5IHsKLQotICAgICAgICBwdWJsaWMgaW50IGhhc2g7Ci0gICAgICAgIHB1YmxpYyBpbnQgYnVja2V0OwotICAgICAgICBwdWJsaWMgRW50cnkgcHJldjsKLSAgICAgICAgcHVibGljIEVudHJ5IG5leHQ7Ci0gICAgICAgIHB1YmxpYyBYTUxHcmFtbWFyRGVzY3JpcHRpb24gZGVzYzsKLSAgICAgICAgcHVibGljIFNvZnRHcmFtbWFyUmVmZXJlbmNlIGdyYW1tYXI7Ci0KLSAgICAgICAgcHJvdGVjdGVkIEVudHJ5KGludCBoYXNoLCBpbnQgYnVja2V0LCBYTUxHcmFtbWFyRGVzY3JpcHRpb24gZGVzYywgR3JhbW1hciBncmFtbWFyLCBFbnRyeSBuZXh0LCBSZWZlcmVuY2VRdWV1ZSBxdWV1ZSkgewotICAgICAgICAgICAgdGhpcy5oYXNoID0gaGFzaDsKLSAgICAgICAgICAgIHRoaXMuYnVja2V0ID0gYnVja2V0OwotICAgICAgICAgICAgdGhpcy5wcmV2ID0gbnVsbDsKLSAgICAgICAgICAgIHRoaXMubmV4dCA9IG5leHQ7Ci0gICAgICAgICAgICBpZiAobmV4dCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgbmV4dC5wcmV2ID0gdGhpczsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHRoaXMuZGVzYyA9IGRlc2M7Ci0gICAgICAgICAgICB0aGlzLmdyYW1tYXIgPSBuZXcgU29mdEdyYW1tYXJSZWZlcmVuY2UodGhpcywgZ3JhbW1hciwgcXVldWUpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gY2xlYXIgdGhpcyBlbnRyeTsgdXNlZnVsIHRvIHByb21vdGUgZ2FyYmFnZSBjb2xsZWN0aW9uCi0gICAgICAgIC8vIHNpbmNlIHJlZHVjZXMgcmVmZXJlbmNlIGNvdW50IG9mIG9iamVjdHMgdG8gYmUgZGVzdHJveWVkCi0gICAgICAgIHByb3RlY3RlZCB2b2lkIGNsZWFyICgpIHsKLSAgICAgICAgICAgIGRlc2MgPSBudWxsOwotICAgICAgICAgICAgZ3JhbW1hciA9IG51bGw7Ci0gICAgICAgICAgICBpZihuZXh0ICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBuZXh0LmNsZWFyKCk7Ci0gICAgICAgICAgICAgICAgbmV4dCA9IG51bGw7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gLy8gY2xlYXIoKQotCi0gICAgfSAvLyBjbGFzcyBFbnRyeQotCi0gICAgLyoqCi0gICAgICogVGhpcyBjbGFzcyBzdG9yZXMgYSBzb2Z0IHJlZmVyZW5jZSB0byBhIGdyYW1tYXIgb2JqZWN0LiBJdCBrZWVwcyBhIHJlZmVyZW5jZQotICAgICAqIHRvIGl0cyBhc3NvY2lhdGVkIGVudHJ5LCBzbyB0aGF0IGl0IGNhbiBiZSBlYXNpbHkgcmVtb3ZlZCBmcm9tIHRoZSBwb29sLgotICAgICAqLwotICAgIHN0YXRpYyBmaW5hbCBjbGFzcyBTb2Z0R3JhbW1hclJlZmVyZW5jZSBleHRlbmRzIFNvZnRSZWZlcmVuY2UgewotCi0gICAgICAgIHB1YmxpYyBFbnRyeSBlbnRyeTsKLQotICAgICAgICBwcm90ZWN0ZWQgU29mdEdyYW1tYXJSZWZlcmVuY2UoRW50cnkgZW50cnksIEdyYW1tYXIgZ3JhbW1hciwgUmVmZXJlbmNlUXVldWUgcXVldWUpIHsKLSAgICAgICAgICAgIHN1cGVyKGdyYW1tYXIsIHF1ZXVlKTsKLSAgICAgICAgICAgIHRoaXMuZW50cnkgPSBlbnRyeTsKLSAgICAgICAgfQotCi0gICAgfSAvLyBjbGFzcyBTb2Z0R3JhbW1hclJlZmVyZW5jZQotCi19IC8vIGNsYXNzIFNvZnRSZWZlcmVuY2VHcmFtbWFyUG9vbApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvamF4cC92YWxpZGF0aW9uL1N0QVhWYWxpZGF0b3JIZWxwZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2pheHAvdmFsaWRhdGlvbi9TdEFYVmFsaWRhdG9ySGVscGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDE2YjFjOTcuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvamF4cC92YWxpZGF0aW9uL1N0QVhWYWxpZGF0b3JIZWxwZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExOSArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDEzLCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuamF4cC52YWxpZGF0aW9uOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLkNvbnN0YW50czsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWxzLlhNTFNlY3VyaXR5TWFuYWdlcjsKLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5SZXN1bHQ7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2U7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lcjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJGYWN0b3J5OwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlNBWFJlc3VsdDsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnNheC5TQVhUcmFuc2Zvcm1lckZhY3Rvcnk7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zYXguVHJhbnNmb3JtZXJIYW5kbGVyOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc3RheC5TdEFYUmVzdWx0OwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc3RheC5TdEFYU291cmNlOwotCi1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotCi0vKioKLSAqIDxwPkEgdmFsaWRhdG9yIGhlbHBlciBmb3IgPGNvZGU+U3RBWFNvdXJjZTwvY29kZT5zLjwvcD4KLSAqCi0gKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzpTdW5pdGhhLlJlZGR5QFN1bi5jb20iPlN1bml0aGEgUmVkZHk8L2E+Ci0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBTdEFYVmFsaWRhdG9ySGVscGVyIGltcGxlbWVudHMgVmFsaWRhdG9ySGVscGVyIHsKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgREVGQVVMVF9UUkFOU0ZPUk1FUl9JTVBMID0gImNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy50cmF4LlRyYW5zZm9ybWVyRmFjdG9yeUltcGwiOwotCi0gICAgLyoqIENvbXBvbmVudCBtYW5hZ2VyLiAqKi8KLSAgICBwcml2YXRlIFhNTFNjaGVtYVZhbGlkYXRvckNvbXBvbmVudE1hbmFnZXIgZkNvbXBvbmVudE1hbmFnZXI7Ci0KLSAgICBwcml2YXRlIFRyYW5zZm9ybWVyIGlkZW50aXR5VHJhbnNmb3JtZXIxID0gbnVsbDsKLSAgICBwcml2YXRlIFRyYW5zZm9ybWVySGFuZGxlciBpZGVudGl0eVRyYW5zZm9ybWVyMiA9IG51bGw7Ci0gICAgcHJpdmF0ZSBWYWxpZGF0b3JIYW5kbGVySW1wbCBoYW5kbGVyID0gbnVsbDsKLQotICAgIC8qKiBDcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIFN0YXhWYWxpZGF0b3JIZWxwZXIgKi8KLSAgICBwdWJsaWMgU3RBWFZhbGlkYXRvckhlbHBlcihYTUxTY2hlbWFWYWxpZGF0b3JDb21wb25lbnRNYW5hZ2VyIGNvbXBvbmVudE1hbmFnZXIpIHsKLSAgICAgICAgZkNvbXBvbmVudE1hbmFnZXIgPSBjb21wb25lbnRNYW5hZ2VyOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHZhbGlkYXRlKFNvdXJjZSBzb3VyY2UsIFJlc3VsdCByZXN1bHQpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKLQotICAgICAgICBpZiAocmVzdWx0ID09IG51bGwgfHwgcmVzdWx0IGluc3RhbmNlb2YgU3RBWFJlc3VsdCkgewotCi0gICAgICAgICAgICBpZiggaWRlbnRpdHlUcmFuc2Zvcm1lcjE9PW51bGwgKSB7Ci0gICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgU0FYVHJhbnNmb3JtZXJGYWN0b3J5IHRmID0gZkNvbXBvbmVudE1hbmFnZXIuZ2V0RmVhdHVyZShDb25zdGFudHMuT1JBQ0xFX0ZFQVRVUkVfU0VSVklDRV9NRUNIQU5JU00pID8KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChTQVhUcmFuc2Zvcm1lckZhY3RvcnkpU0FYVHJhbnNmb3JtZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogKFNBWFRyYW5zZm9ybWVyRmFjdG9yeSkgVHJhbnNmb3JtZXJGYWN0b3J5Lm5ld0luc3RhbmNlKERFRkFVTFRfVFJBTlNGT1JNRVJfSU1QTCwgU3RBWFZhbGlkYXRvckhlbHBlci5jbGFzcy5nZXRDbGFzc0xvYWRlcigpKTsKLSAgICAgICAgICAgICAgICAgICAgWE1MU2VjdXJpdHlNYW5hZ2VyIHNlY3VyaXR5TWFuYWdlciA9IChYTUxTZWN1cml0eU1hbmFnZXIpZkNvbXBvbmVudE1hbmFnZXIuZ2V0UHJvcGVydHkoQ29uc3RhbnRzLlNFQ1VSSVRZX01BTkFHRVIpOwotICAgICAgICAgICAgICAgICAgICBpZiAoc2VjdXJpdHlNYW5hZ2VyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoWE1MU2VjdXJpdHlNYW5hZ2VyLkxpbWl0IGxpbWl0IDogWE1MU2VjdXJpdHlNYW5hZ2VyLkxpbWl0LnZhbHVlcygpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNlY3VyaXR5TWFuYWdlci5pc1NldChsaW1pdC5vcmRpbmFsKCkpKXsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGYuc2V0QXR0cmlidXRlKGxpbWl0LmFwaVByb3BlcnR5KCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VjdXJpdHlNYW5hZ2VyLmdldExpbWl0VmFsdWVBc1N0cmluZyhsaW1pdCkpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZWN1cml0eU1hbmFnZXIucHJpbnRFbnRpdHlDb3VudEluZm8oKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRmLnNldEF0dHJpYnV0ZShDb25zdGFudHMuSkRLX0VOVElUWV9DT1VOVF9JTkZPLCAieWVzIik7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICBpZGVudGl0eVRyYW5zZm9ybWVyMSA9IHRmLm5ld1RyYW5zZm9ybWVyKCk7Ci0gICAgICAgICAgICAgICAgICAgIGlkZW50aXR5VHJhbnNmb3JtZXIyID0gdGYubmV3VHJhbnNmb3JtZXJIYW5kbGVyKCk7Ci0gICAgICAgICAgICAgICAgfSBjYXRjaCAoVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gdGhpcyBpcyBpbXBvc3NpYmxlLCBidXQgYWdhaW4gYmV0dGVyIHNhZmUgdGhhbiBzb3JyeQotICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yKGUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaGFuZGxlciA9IG5ldyBWYWxpZGF0b3JIYW5kbGVySW1wbChmQ29tcG9uZW50TWFuYWdlcik7Ci0gICAgICAgICAgICBpZiggcmVzdWx0IT1udWxsICkgewotICAgICAgICAgICAgICAgIGhhbmRsZXIuc2V0Q29udGVudEhhbmRsZXIoaWRlbnRpdHlUcmFuc2Zvcm1lcjIpOwotICAgICAgICAgICAgICAgIGlkZW50aXR5VHJhbnNmb3JtZXIyLnNldFJlc3VsdChyZXN1bHQpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIGlkZW50aXR5VHJhbnNmb3JtZXIxLnRyYW5zZm9ybSggc291cmNlLCBuZXcgU0FYUmVzdWx0KGhhbmRsZXIpICk7Ci0gICAgICAgICAgICB9IGNhdGNoIChUcmFuc2Zvcm1lckV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgaWYoIGUuZ2V0RXhjZXB0aW9uKCkgaW5zdGFuY2VvZiBTQVhFeGNlcHRpb24gKQotICAgICAgICAgICAgICAgICAgICB0aHJvdyAoU0FYRXhjZXB0aW9uKWUuZ2V0RXhjZXB0aW9uKCk7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbihlKTsKLSAgICAgICAgICAgIH0gZmluYWxseSB7Ci0gICAgICAgICAgICAgICAgaGFuZGxlci5zZXRDb250ZW50SGFuZGxlcihudWxsKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKEpBWFBWYWxpZGF0aW9uTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKGZDb21wb25lbnRNYW5hZ2VyLmdldExvY2FsZSgpLAotICAgICAgICAgICAgICAgICJTb3VyY2VSZXN1bHRNaXNtYXRjaCIsCi0gICAgICAgICAgICAgICAgbmV3IE9iamVjdCBbXSB7c291cmNlLmdldENsYXNzKCkuZ2V0TmFtZSgpLCByZXN1bHQuZ2V0Q2xhc3MoKS5nZXROYW1lKCl9KSk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvamF4cC92YWxpZGF0aW9uL1N0cmVhbVZhbGlkYXRvckhlbHBlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvamF4cC92YWxpZGF0aW9uL1N0cmVhbVZhbGlkYXRvckhlbHBlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkNmMwNGZkLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2pheHAvdmFsaWRhdGlvbi9TdHJlYW1WYWxpZGF0b3JIZWxwZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE5OCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmpheHAudmFsaWRhdGlvbjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5Db25zdGFudHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLlhNTEVycm9yUmVwb3J0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLm1zZy5YTUxNZXNzYWdlRm9ybWF0dGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwucGFyc2Vycy5YTUwxMUNvbmZpZ3VyYXRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlscy5YTUxTZWN1cml0eU1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE5JRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxJbnB1dFNvdXJjZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MUGFyc2VFeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTFBhcnNlckNvbmZpZ3VyYXRpb247Ci1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmxhbmcucmVmLlNvZnRSZWZlcmVuY2U7Ci1pbXBvcnQgamF2YXgueG1sLlhNTENvbnN0YW50czsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlJlc3VsdDsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlNvdXJjZTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRmFjdG9yeTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvcjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnNheC5TQVhUcmFuc2Zvcm1lckZhY3Rvcnk7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zYXguVHJhbnNmb3JtZXJIYW5kbGVyOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc3RyZWFtLlN0cmVhbVJlc3VsdDsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbS5TdHJlYW1Tb3VyY2U7Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotCi0vKioKLSAqIDxwPkEgdmFsaWRhdG9yIGhlbHBlciBmb3IgPGNvZGU+U3RyZWFtU291cmNlPC9jb2RlPnMuPC9wPgotICoKLSAqIEBhdXRob3IgTWljaGFlbCBHbGF2YXNzZXZpY2gsIElCTQotICogQGF1dGhvciA8YSBocmVmPSJtYWlsdG86U3VuaXRoYS5SZWRkeUBTdW4uY29tIj5TdW5pdGhhIFJlZGR5PC9hPgotICogQHZlcnNpb24gJElkOiBTdHJlYW1WYWxpZGF0b3JIZWxwZXIuamF2YSx2IDEuNyAyMDEwLTExLTAxIDA0OjQwOjA4IGpvZWh3IEV4cCAkCi0gKi8KLWZpbmFsIGNsYXNzIFN0cmVhbVZhbGlkYXRvckhlbHBlciBpbXBsZW1lbnRzIFZhbGlkYXRvckhlbHBlciB7Ci0KLSAgICAvLyBmZWF0dXJlIGlkZW50aWZpZXJzCi0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiBwYXJzZXIgc2V0dGluZ3MuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFBBUlNFUl9TRVRUSU5HUyA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuUEFSU0VSX1NFVFRJTkdTOwotCi0gICAgLy8gcHJvcGVydHkgaWRlbnRpZmllcnMKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBlbnRpdHkgcmVzb2x2ZXIuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEVOVElUWV9SRVNPTFZFUiA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLkVOVElUWV9SRVNPTFZFUl9QUk9QRVJUWTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBlcnJvciBoYW5kbGVyLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJPUl9IQU5ETEVSID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuRVJST1JfSEFORExFUl9QUk9QRVJUWTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBlcnJvciByZXBvcnRlci4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJST1JfUkVQT1JURVIgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5FUlJPUl9SRVBPUlRFUl9QUk9QRVJUWTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBYTUwgU2NoZW1hIHZhbGlkYXRvci4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgU0NIRU1BX1ZBTElEQVRPUiA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLlNDSEVNQV9WQUxJREFUT1JfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogc3ltYm9sIHRhYmxlLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBTWU1CT0xfVEFCTEUgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5TWU1CT0xfVEFCTEVfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogdmFsaWRhdGlvbiBtYW5hZ2VyLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBWQUxJREFUSU9OX01BTkFHRVIgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5WQUxJREFUSU9OX01BTkFHRVJfUFJPUEVSVFk7Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgREVGQVVMVF9UUkFOU0ZPUk1FUl9JTVBMID0gImNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy50cmF4LlRyYW5zZm9ybWVyRmFjdG9yeUltcGwiOwotCi0gICAgLyoqIFByb3BlcnR5IGlkOiBzZWN1cml0eSBtYW5hZ2VyLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBTRUNVUklUWV9NQU5BR0VSID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuU0VDVVJJVFlfTUFOQUdFUl9QUk9QRVJUWTsKLQotICAgIC8vCi0gICAgLy8gRGF0YQotICAgIC8vCi0KLSAgICAvKiogU29mdFJlZmVyZW5jZSB0byBwYXJzZXIgY29uZmlndXJhdGlvbi4gKiovCi0gICAgcHJpdmF0ZSBTb2Z0UmVmZXJlbmNlIGZDb25maWd1cmF0aW9uID0gbmV3IFNvZnRSZWZlcmVuY2UobnVsbCk7Ci0KLSAgICAvKiogU2NoZW1hIHZhbGlkYXRvci4gKiovCi0gICAgcHJpdmF0ZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMuWE1MU2NoZW1hVmFsaWRhdG9yIGZTY2hlbWFWYWxpZGF0b3I7Ci0KLSAgICAvKiogQ29tcG9uZW50IG1hbmFnZXIuICoqLwotICAgIHByaXZhdGUgWE1MU2NoZW1hVmFsaWRhdG9yQ29tcG9uZW50TWFuYWdlciBmQ29tcG9uZW50TWFuYWdlcjsKLQotICAgIHByaXZhdGUgVmFsaWRhdG9ySGFuZGxlckltcGwgaGFuZGxlciA9IG51bGw7Ci0KLSAgICBwdWJsaWMgU3RyZWFtVmFsaWRhdG9ySGVscGVyKFhNTFNjaGVtYVZhbGlkYXRvckNvbXBvbmVudE1hbmFnZXIgY29tcG9uZW50TWFuYWdlcikgewotICAgICAgICBmQ29tcG9uZW50TWFuYWdlciA9IGNvbXBvbmVudE1hbmFnZXI7Ci0gICAgICAgIGZTY2hlbWFWYWxpZGF0b3IgPSAoY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlhNTFNjaGVtYVZhbGlkYXRvcikgZkNvbXBvbmVudE1hbmFnZXIuZ2V0UHJvcGVydHkoU0NIRU1BX1ZBTElEQVRPUik7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgdmFsaWRhdGUoU291cmNlIHNvdXJjZSwgUmVzdWx0IHJlc3VsdCkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewotICAgICAgICBpZiAocmVzdWx0ID09IG51bGwgfHwgcmVzdWx0IGluc3RhbmNlb2YgU3RyZWFtUmVzdWx0KSB7Ci0gICAgICAgICAgICBmaW5hbCBTdHJlYW1Tb3VyY2Ugc3RyZWFtU291cmNlID0gKFN0cmVhbVNvdXJjZSkgc291cmNlOwotICAgICAgICAgICAgVHJhbnNmb3JtZXJIYW5kbGVyIGlkZW50aXR5VHJhbnNmb3JtZXJIYW5kbGVyIDsKLQotICAgICAgICAgICAgaWYoIHJlc3VsdCE9bnVsbCApIHsKLSAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICBTQVhUcmFuc2Zvcm1lckZhY3RvcnkgdGYgPSBmQ29tcG9uZW50TWFuYWdlci5nZXRGZWF0dXJlKENvbnN0YW50cy5PUkFDTEVfRkVBVFVSRV9TRVJWSUNFX01FQ0hBTklTTSkgPwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFNBWFRyYW5zZm9ybWVyRmFjdG9yeSlTQVhUcmFuc2Zvcm1lckZhY3RvcnkubmV3SW5zdGFuY2UoKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAoU0FYVHJhbnNmb3JtZXJGYWN0b3J5KSBUcmFuc2Zvcm1lckZhY3RvcnkubmV3SW5zdGFuY2UoREVGQVVMVF9UUkFOU0ZPUk1FUl9JTVBMLCBTdHJlYW1WYWxpZGF0b3JIZWxwZXIuY2xhc3MuZ2V0Q2xhc3NMb2FkZXIoKSk7Ci0gICAgICAgICAgICAgICAgICAgIGlkZW50aXR5VHJhbnNmb3JtZXJIYW5kbGVyID0gdGYubmV3VHJhbnNmb3JtZXJIYW5kbGVyKCk7Ci0gICAgICAgICAgICAgICAgfSBjYXRjaCAoVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvcihlKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBoYW5kbGVyID0gbmV3IFZhbGlkYXRvckhhbmRsZXJJbXBsKGZDb21wb25lbnRNYW5hZ2VyKTsKLSAgICAgICAgICAgICAgICBoYW5kbGVyLnNldENvbnRlbnRIYW5kbGVyKGlkZW50aXR5VHJhbnNmb3JtZXJIYW5kbGVyKTsKLSAgICAgICAgICAgICAgICBpZGVudGl0eVRyYW5zZm9ybWVySGFuZGxlci5zZXRSZXN1bHQocmVzdWx0KTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgWE1MSW5wdXRTb3VyY2UgaW5wdXQgPSBuZXcgWE1MSW5wdXRTb3VyY2Uoc3RyZWFtU291cmNlLmdldFB1YmxpY0lkKCksIHN0cmVhbVNvdXJjZS5nZXRTeXN0ZW1JZCgpLCBudWxsKTsKLSAgICAgICAgICAgIGlucHV0LnNldEJ5dGVTdHJlYW0oc3RyZWFtU291cmNlLmdldElucHV0U3RyZWFtKCkpOwotICAgICAgICAgICAgaW5wdXQuc2V0Q2hhcmFjdGVyU3RyZWFtKHN0cmVhbVNvdXJjZS5nZXRSZWFkZXIoKSk7Ci0KLSAgICAgICAgICAgIC8vIEdldHMgdGhlIHBhcnNlciBjb25maWd1cmF0aW9uLiBXZSdsbCBjcmVhdGUgYW5kIGluaXRpYWxpemUgYSBuZXcgb25lLCBpZiB3ZQotICAgICAgICAgICAgLy8gaGF2ZW4ndCBjcmVhdGVkIG9uZSBiZWZvcmUgb3IgaWYgdGhlIHByZXZpb3VzIG9uZSB3YXMgZ2FyYmFnZSBjb2xsZWN0ZWQuCi0gICAgICAgICAgICBYTUxQYXJzZXJDb25maWd1cmF0aW9uIGNvbmZpZyA9IChYTUxQYXJzZXJDb25maWd1cmF0aW9uKSBmQ29uZmlndXJhdGlvbi5nZXQoKTsKLSAgICAgICAgICAgIGlmIChjb25maWcgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGNvbmZpZyA9IGluaXRpYWxpemUoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIElmIHNldHRpbmdzIGhhdmUgY2hhbmdlZCBvbiB0aGUgY29tcG9uZW50IG1hbmFnZXIsIHJlZnJlc2ggdGhlIGVycm9yIGhhbmRsZXIgYW5kIGVudGl0eSByZXNvbHZlci4KLSAgICAgICAgICAgIGVsc2UgaWYgKGZDb21wb25lbnRNYW5hZ2VyLmdldEZlYXR1cmUoUEFSU0VSX1NFVFRJTkdTKSkgewotICAgICAgICAgICAgICAgIGNvbmZpZy5zZXRQcm9wZXJ0eShFTlRJVFlfUkVTT0xWRVIsIGZDb21wb25lbnRNYW5hZ2VyLmdldFByb3BlcnR5KEVOVElUWV9SRVNPTFZFUikpOwotICAgICAgICAgICAgICAgIGNvbmZpZy5zZXRQcm9wZXJ0eShFUlJPUl9IQU5ETEVSLCBmQ29tcG9uZW50TWFuYWdlci5nZXRQcm9wZXJ0eShFUlJPUl9IQU5ETEVSKSk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIHByZXBhcmUgZm9yIHBhcnNlCi0gICAgICAgICAgICBmQ29tcG9uZW50TWFuYWdlci5yZXNldCgpOwotICAgICAgICAgICAgZlNjaGVtYVZhbGlkYXRvci5zZXREb2N1bWVudEhhbmRsZXIoaGFuZGxlcik7Ci0KLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgY29uZmlnLnBhcnNlKGlucHV0KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhdGNoIChYTUxQYXJzZUV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgVXRpbC50b1NBWFBhcnNlRXhjZXB0aW9uKGUpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2F0Y2ggKFhOSUV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgVXRpbC50b1NBWEV4Y2VwdGlvbihlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKEpBWFBWYWxpZGF0aW9uTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKGZDb21wb25lbnRNYW5hZ2VyLmdldExvY2FsZSgpLAotICAgICAgICAgICAgICAgICJTb3VyY2VSZXN1bHRNaXNtYXRjaCIsCi0gICAgICAgICAgICAgICAgbmV3IE9iamVjdCBbXSB7c291cmNlLmdldENsYXNzKCkuZ2V0TmFtZSgpLCByZXN1bHQuZ2V0Q2xhc3MoKS5nZXROYW1lKCl9KSk7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBYTUxQYXJzZXJDb25maWd1cmF0aW9uIGluaXRpYWxpemUoKSB7Ci0gICAgICAgIFhNTDExQ29uZmlndXJhdGlvbiBjb25maWcgPSBuZXcgWE1MMTFDb25maWd1cmF0aW9uKCk7Ci0gICAgICAgIGlmIChmQ29tcG9uZW50TWFuYWdlci5nZXRGZWF0dXJlKFhNTENvbnN0YW50cy5GRUFUVVJFX1NFQ1VSRV9QUk9DRVNTSU5HKSkgewotICAgICAgICAgICAgY29uZmlnLnNldFByb3BlcnR5KFNFQ1VSSVRZX01BTkFHRVIsIG5ldyBYTUxTZWN1cml0eU1hbmFnZXIoKSk7Ci0gICAgICAgIH0KLSAgICAgICAgY29uZmlnLnNldFByb3BlcnR5KEVOVElUWV9SRVNPTFZFUiwgZkNvbXBvbmVudE1hbmFnZXIuZ2V0UHJvcGVydHkoRU5USVRZX1JFU09MVkVSKSk7Ci0gICAgICAgIGNvbmZpZy5zZXRQcm9wZXJ0eShFUlJPUl9IQU5ETEVSLCBmQ29tcG9uZW50TWFuYWdlci5nZXRQcm9wZXJ0eShFUlJPUl9IQU5ETEVSKSk7Ci0gICAgICAgIFhNTEVycm9yUmVwb3J0ZXIgZXJyb3JSZXBvcnRlciA9IChYTUxFcnJvclJlcG9ydGVyKSBmQ29tcG9uZW50TWFuYWdlci5nZXRQcm9wZXJ0eShFUlJPUl9SRVBPUlRFUik7Ci0gICAgICAgIGNvbmZpZy5zZXRQcm9wZXJ0eShFUlJPUl9SRVBPUlRFUiwgZXJyb3JSZXBvcnRlcik7Ci0gICAgICAgIC8vIGFkZCBtZXNzYWdlIGZvcm1hdHRlcnMKLSAgICAgICAgaWYgKGVycm9yUmVwb3J0ZXIuZ2V0TWVzc2FnZUZvcm1hdHRlcihYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4pID09IG51bGwpIHsKLSAgICAgICAgICAgIFhNTE1lc3NhZ2VGb3JtYXR0ZXIgeG1mdCA9IG5ldyBYTUxNZXNzYWdlRm9ybWF0dGVyKCk7Ci0gICAgICAgICAgICBlcnJvclJlcG9ydGVyLnB1dE1lc3NhZ2VGb3JtYXR0ZXIoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLCB4bWZ0KTsKLSAgICAgICAgICAgIGVycm9yUmVwb3J0ZXIucHV0TWVzc2FnZUZvcm1hdHRlcihYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTE5TX0RPTUFJTiwgeG1mdCk7Ci0gICAgICAgIH0KLSAgICAgICAgY29uZmlnLnNldFByb3BlcnR5KFNZTUJPTF9UQUJMRSwgZkNvbXBvbmVudE1hbmFnZXIuZ2V0UHJvcGVydHkoU1lNQk9MX1RBQkxFKSk7Ci0gICAgICAgIGNvbmZpZy5zZXRQcm9wZXJ0eShWQUxJREFUSU9OX01BTkFHRVIsIGZDb21wb25lbnRNYW5hZ2VyLmdldFByb3BlcnR5KFZBTElEQVRJT05fTUFOQUdFUikpOwotICAgICAgICBjb25maWcuc2V0RG9jdW1lbnRIYW5kbGVyKGZTY2hlbWFWYWxpZGF0b3IpOwotICAgICAgICBjb25maWcuc2V0RFRESGFuZGxlcihudWxsKTsKLSAgICAgICAgY29uZmlnLnNldERURENvbnRlbnRNb2RlbEhhbmRsZXIobnVsbCk7Ci0gICAgICAgIGNvbmZpZy5zZXRQcm9wZXJ0eShDb25zdGFudHMuWE1MX1NFQ1VSSVRZX1BST1BFUlRZX01BTkFHRVIsCi0gICAgICAgICAgICAgICAgZkNvbXBvbmVudE1hbmFnZXIuZ2V0UHJvcGVydHkoQ29uc3RhbnRzLlhNTF9TRUNVUklUWV9QUk9QRVJUWV9NQU5BR0VSKSk7Ci0gICAgICAgIGNvbmZpZy5zZXRQcm9wZXJ0eShDb25zdGFudHMuU0VDVVJJVFlfTUFOQUdFUiwKLSAgICAgICAgICAgICAgICBmQ29tcG9uZW50TWFuYWdlci5nZXRQcm9wZXJ0eShDb25zdGFudHMuU0VDVVJJVFlfTUFOQUdFUikpOwotICAgICAgICBmQ29uZmlndXJhdGlvbiA9IG5ldyBTb2Z0UmVmZXJlbmNlKGNvbmZpZyk7Ci0gICAgICAgIHJldHVybiBjb25maWc7Ci0gICAgfQotCi19IC8vIFN0cmVhbVZhbGlkYXRvckhlbHBlcgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvamF4cC92YWxpZGF0aW9uL1V0aWwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2pheHAvdmFsaWRhdGlvbi9VdGlsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDUwNzZlNjAuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvamF4cC92YWxpZGF0aW9uL1V0aWwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDc3ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuamF4cC52YWxpZGF0aW9uOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zdHJlYW0uU3RyZWFtU291cmNlOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE5JRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxJbnB1dFNvdXJjZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MUGFyc2VFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWFBhcnNlRXhjZXB0aW9uOwotCi0vKioKLSAqIDxwPlN0YXRpYyB1dGlsaXR5IG1ldGhvZHMgZm9yIHRoZSBWYWxpZGF0aW9uIEFQSSBpbXBsZW1lbnRhdGlvbi48L3A+Ci0gKgotICogQGF1dGhvciBLb2hzdWtlIEthd2FndWNoaSAoa29oc3VrZS5rYXdhZ3VjaGlAc3VuLmNvbSkKLSAqLwotZmluYWwgY2xhc3MgVXRpbCB7Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGVzIGEgcHJvcGVyIHtAbGluayBYTUxJbnB1dFNvdXJjZX0gZnJvbSBhIHtAbGluayBTdHJlYW1Tb3VyY2V9LgotICAgICAqCi0gICAgICogQHJldHVybiBhbHdheXMgcmV0dXJuIG5vbi1udWxsIHZhbGlkIG9iamVjdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFhNTElucHV0U291cmNlIHRvWE1MSW5wdXRTb3VyY2UoIFN0cmVhbVNvdXJjZSBpbiApIHsKLSAgICAgICAgaWYoIGluLmdldFJlYWRlcigpIT1udWxsICkKLSAgICAgICAgICAgIHJldHVybiBuZXcgWE1MSW5wdXRTb3VyY2UoCi0gICAgICAgICAgICBpbi5nZXRQdWJsaWNJZCgpLCBpbi5nZXRTeXN0ZW1JZCgpLCBpbi5nZXRTeXN0ZW1JZCgpLAotICAgICAgICAgICAgaW4uZ2V0UmVhZGVyKCksIG51bGwgKTsKLSAgICAgICAgaWYoIGluLmdldElucHV0U3RyZWFtKCkhPW51bGwgKQotICAgICAgICAgICAgcmV0dXJuIG5ldyBYTUxJbnB1dFNvdXJjZSgKLSAgICAgICAgICAgIGluLmdldFB1YmxpY0lkKCksIGluLmdldFN5c3RlbUlkKCksIGluLmdldFN5c3RlbUlkKCksCi0gICAgICAgICAgICBpbi5nZXRJbnB1dFN0cmVhbSgpLCBudWxsICk7Ci0KLSAgICAgICAgcmV0dXJuIG5ldyBYTUxJbnB1dFNvdXJjZSgKLSAgICAgICAgaW4uZ2V0UHVibGljSWQoKSwgaW4uZ2V0U3lzdGVtSWQoKSwgaW4uZ2V0U3lzdGVtSWQoKSApOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJlY29uc3RydWN0cyB7QGxpbmsgU0FYRXhjZXB0aW9ufSBmcm9tIFhOSUV4Y2VwdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFNBWEV4Y2VwdGlvbiB0b1NBWEV4Y2VwdGlvbihYTklFeGNlcHRpb24gZSkgewotICAgICAgICBpZihlIGluc3RhbmNlb2YgWE1MUGFyc2VFeGNlcHRpb24pCi0gICAgICAgICAgICByZXR1cm4gdG9TQVhQYXJzZUV4Y2VwdGlvbigoWE1MUGFyc2VFeGNlcHRpb24pZSk7Ci0gICAgICAgIGlmKCBlLmdldEV4Y2VwdGlvbigpIGluc3RhbmNlb2YgU0FYRXhjZXB0aW9uICkKLSAgICAgICAgICAgIHJldHVybiAoU0FYRXhjZXB0aW9uKWUuZ2V0RXhjZXB0aW9uKCk7Ci0gICAgICAgIHJldHVybiBuZXcgU0FYRXhjZXB0aW9uKGUuZ2V0TWVzc2FnZSgpLGUuZ2V0RXhjZXB0aW9uKCkpOwotICAgIH0KLQotICAgIHB1YmxpYyBzdGF0aWMgU0FYUGFyc2VFeGNlcHRpb24gdG9TQVhQYXJzZUV4Y2VwdGlvbiggWE1MUGFyc2VFeGNlcHRpb24gZSApIHsKLSAgICAgICAgaWYoIGUuZ2V0RXhjZXB0aW9uKCkgaW5zdGFuY2VvZiBTQVhQYXJzZUV4Y2VwdGlvbiApCi0gICAgICAgICAgICByZXR1cm4gKFNBWFBhcnNlRXhjZXB0aW9uKWUuZ2V0RXhjZXB0aW9uKCk7Ci0gICAgICAgIHJldHVybiBuZXcgU0FYUGFyc2VFeGNlcHRpb24oIGUuZ2V0TWVzc2FnZSgpLAotICAgICAgICBlLmdldFB1YmxpY0lkKCksIGUuZ2V0RXhwYW5kZWRTeXN0ZW1JZCgpLAotICAgICAgICBlLmdldExpbmVOdW1iZXIoKSwgZS5nZXRDb2x1bW5OdW1iZXIoKSwKLSAgICAgICAgZS5nZXRFeGNlcHRpb24oKSApOwotICAgIH0KLQotfSAvLyBVdGlsCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9qYXhwL3ZhbGlkYXRpb24vVmFsaWRhdG9ySGFuZGxlckltcGwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2pheHAvdmFsaWRhdGlvbi9WYWxpZGF0b3JIYW5kbGVySW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyYTYyNDA1Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2pheHAvdmFsaWRhdGlvbi9WYWxpZGF0b3JIYW5kbGVySW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTA4NyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmpheHAudmFsaWRhdGlvbjsKLQotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci1pbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKLWltcG9ydCBqYXZhLmlvLlJlYWRlcjsKLWltcG9ydCBqYXZhLmlvLlN0cmluZ1JlYWRlcjsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKLQotaW1wb3J0IGphdmF4LnhtbC5YTUxDb25zdGFudHM7Ci1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvcjsKLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXJGYWN0b3J5OwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uUmVzdWx0OwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uU291cmNlOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlNBWFJlc3VsdDsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnNheC5TQVhTb3VyY2U7Ci1pbXBvcnQgamF2YXgueG1sLnZhbGlkYXRpb24uVHlwZUluZm9Qcm92aWRlcjsKLWltcG9ydCBqYXZheC54bWwudmFsaWRhdGlvbi5WYWxpZGF0b3JIYW5kbGVyOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLkNvbnN0YW50czsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuWE1MRW50aXR5TWFuYWdlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuWE1MRXJyb3JSZXBvcnRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYuWFNTaW1wbGVUeXBlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC52YWxpZGF0aW9uLkVudGl0eVN0YXRlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC52YWxpZGF0aW9uLlZhbGlkYXRpb25NYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5YTUxTY2hlbWFWYWxpZGF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5qYXhwLlNBWFBhcnNlckZhY3RvcnlJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5BdHRyaWJ1dGVzUHJveHk7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlNBWExvY2F0b3JXcmFwcGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5TQVhNZXNzYWdlRm9ybWF0dGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5TdGF0dXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlN5bWJvbFRhYmxlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5VUkk7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlhNTEF0dHJpYnV0ZXNJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5YTUxTeW1ib2xzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbHMuWE1MU2VjdXJpdHlQcm9wZXJ0eU1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlscy5YTUxTZWN1cml0eU1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuQXVnbWVudGF0aW9uczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5OYW1lc3BhY2VDb250ZXh0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlFOYW1lOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTEF0dHJpYnV0ZXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MRG9jdW1lbnRIYW5kbGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTExvY2F0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MUmVzb3VyY2VJZGVudGlmaWVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTFN0cmluZzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTklFeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTERvY3VtZW50U291cmNlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxQYXJzZUV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLkF0dHJpYnV0ZVBTVkk7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5FbGVtZW50UFNWSTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLkl0ZW1QU1ZJOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuUFNWSVByb3ZpZGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNUeXBlRGVmaW5pdGlvbjsKLWltcG9ydCBvcmcudzNjLmRvbS5UeXBlSW5mbzsKLWltcG9ydCBvcmcudzNjLmRvbS5scy5MU0lucHV0OwotaW1wb3J0IG9yZy53M2MuZG9tLmxzLkxTUmVzb3VyY2VSZXNvbHZlcjsKLWltcG9ydCBvcmcueG1sLnNheC5BdHRyaWJ1dGVzOwotaW1wb3J0IG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LkRUREhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguRXJyb3JIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LklucHV0U291cmNlOwotaW1wb3J0IG9yZy54bWwuc2F4LkxvY2F0b3I7Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LlhNTFJlYWRlcjsKLWltcG9ydCBvcmcueG1sLnNheC5leHQuQXR0cmlidXRlczI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguZXh0LkVudGl0eVJlc29sdmVyMjsKLQotLyoqCi0gKiA8cD5JbXBsZW1lbnRhdGlvbiBvZiBWYWxpZGF0b3JIYW5kbGVyIGZvciBXM0MgWE1MIFNjaGVtYXMgYW5kCi0gKiBhbHNvIGEgdmFsaWRhdG9yIGhlbHBlciBmb3IgPGNvZGU+U0FYU291cmNlPC9jb2RlPnMuPC9wPgotICoKLSAqIEBhdXRob3IgS29oc3VrZSBLYXdhZ3VjaGkgKGtvaHN1a2Uua2F3YWd1Y2hpQHN1bi5jb20pCi0gKiBAYXV0aG9yIE1pY2hhZWwgR2xhdmFzc2V2aWNoLCBJQk0KLSAqCi0gKiBAdmVyc2lvbiAkSWQ6IFZhbGlkYXRvckhhbmRsZXJJbXBsLmphdmEsdiAxLjEwIDIwMTAtMTEtMDEgMDQ6NDA6MDggam9laHcgRXhwICQKLSAqLwotZmluYWwgY2xhc3MgVmFsaWRhdG9ySGFuZGxlckltcGwgZXh0ZW5kcyBWYWxpZGF0b3JIYW5kbGVyIGltcGxlbWVudHMKLSAgICBEVERIYW5kbGVyLCBFbnRpdHlTdGF0ZSwgUFNWSVByb3ZpZGVyLCBWYWxpZGF0b3JIZWxwZXIsIFhNTERvY3VtZW50SGFuZGxlciB7Ci0KLSAgICAvLyBmZWF0dXJlIGlkZW50aWZpZXJzCi0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiBuYW1lc3BhY2UgcHJlZml4ZXMuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIE5BTUVTUEFDRV9QUkVGSVhFUyA9Ci0gICAgICAgIENvbnN0YW50cy5TQVhfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuTkFNRVNQQUNFX1BSRUZJWEVTX0ZFQVRVUkU7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiBzdHJpbmcgaW50ZXJuaW5nLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFNUUklOR19JTlRFUk5JTkcgPQotICAgICAgICBDb25zdGFudHMuU0FYX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLlNUUklOR19JTlRFUk5JTkdfRkVBVFVSRTsKLQotICAgIC8vIHByb3BlcnR5IGlkZW50aWZpZXJzCi0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogZXJyb3IgcmVwb3J0ZXIuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUk9SX1JFUE9SVEVSID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuRVJST1JfUkVQT1JURVJfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogbmFtZXNwYWNlIGNvbnRleHQuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIE5BTUVTUEFDRV9DT05URVhUID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuTkFNRVNQQUNFX0NPTlRFWFRfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogWE1MIFNjaGVtYSB2YWxpZGF0b3IuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFNDSEVNQV9WQUxJREFUT1IgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5TQ0hFTUFfVkFMSURBVE9SX1BST1BFUlRZOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IHNlY3VyaXR5IG1hbmFnZXIuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFNFQ1VSSVRZX01BTkFHRVIgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5TRUNVUklUWV9NQU5BR0VSX1BST1BFUlRZOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IHN5bWJvbCB0YWJsZS4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1lNQk9MX1RBQkxFID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuU1lNQk9MX1RBQkxFX1BST1BFUlRZOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IHZhbGlkYXRpb24gbWFuYWdlci4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgVkFMSURBVElPTl9NQU5BR0VSID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuVkFMSURBVElPTl9NQU5BR0VSX1BST1BFUlRZOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IFNlY3VyaXR5IHByb3BlcnR5IG1hbmFnZXIuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFhNTF9TRUNVUklUWV9QUk9QRVJUWV9NQU5BR0VSID0KLSAgICAgICAgICAgIENvbnN0YW50cy5YTUxfU0VDVVJJVFlfUFJPUEVSVFlfTUFOQUdFUjsKLQotICAgIC8vCi0gICAgLy8gRGF0YQotICAgIC8vCi0KLSAgICAvKiogRXJyb3IgcmVwb3J0ZXIuICovCi0gICAgcHJpdmF0ZSBYTUxFcnJvclJlcG9ydGVyIGZFcnJvclJlcG9ydGVyOwotCi0gICAgLyoqIFRoZSBuYW1lc3BhY2UgY29udGV4dCBvZiB0aGlzIGRvY3VtZW50OiBzdG9yZXMgbmFtZXNwYWNlcyBpbiBzY29wZSAqLwotICAgIHByaXZhdGUgTmFtZXNwYWNlQ29udGV4dCBmTmFtZXNwYWNlQ29udGV4dDsKLQotICAgIC8qKiBTY2hlbWEgdmFsaWRhdG9yLiAqKi8KLSAgICBwcml2YXRlIFhNTFNjaGVtYVZhbGlkYXRvciBmU2NoZW1hVmFsaWRhdG9yOwotCi0gICAgLyoqIFN5bWJvbCB0YWJsZSAqKi8KLSAgICBwcml2YXRlIFN5bWJvbFRhYmxlIGZTeW1ib2xUYWJsZTsKLQotICAgIC8qKiBWYWxpZGF0aW9uIG1hbmFnZXIuICovCi0gICAgcHJpdmF0ZSBWYWxpZGF0aW9uTWFuYWdlciBmVmFsaWRhdGlvbk1hbmFnZXI7Ci0KLSAgICAvKiogQ29tcG9uZW50IG1hbmFnZXIuICoqLwotICAgIHByaXZhdGUgWE1MU2NoZW1hVmFsaWRhdG9yQ29tcG9uZW50TWFuYWdlciBmQ29tcG9uZW50TWFuYWdlcjsKLQotICAgIC8qKiBYTUwgTG9jYXRvciB3cmFwcGVyIGZvciBTQVguICoqLwotICAgIHByaXZhdGUgZmluYWwgU0FYTG9jYXRvcldyYXBwZXIgZlNBWExvY2F0b3JXcmFwcGVyID0gbmV3IFNBWExvY2F0b3JXcmFwcGVyKCk7Ci0KLSAgICAvKiogRmxhZyB1c2VkIHRvIHRyYWNrIHdoZXRoZXIgdGhlIG5hbWVzcGFjZSBjb250ZXh0IG5lZWRzIHRvIGJlIHB1c2hlZC4gKi8KLSAgICBwcml2YXRlIGJvb2xlYW4gZk5lZWRQdXNoTlNDb250ZXh0ID0gdHJ1ZTsKLQotICAgIC8qKiBNYXAgZm9yIHRyYWNraW5nIHVucGFyc2VkIGVudGl0aWVzLiAqLwotICAgIHByaXZhdGUgSGFzaE1hcCBmVW5wYXJzZWRFbnRpdGllcyA9IG51bGw7Ci0KLSAgICAvKiogRmxhZyB1c2VkIHRvIHRyYWNrIHdoZXRoZXIgWE1MIG5hbWVzIGFuZCBOYW1lc3BhY2UgVVJJcyBoYXZlIGJlZW4gaW50ZXJuYWxpemVkLiAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBmU3RyaW5nc0ludGVybmFsaXplZCA9IGZhbHNlOwotCi0gICAgLyoqIEZpZWxkcyBmb3Igc3RhcnQgZWxlbWVudCwgZW5kIGVsZW1lbnQgYW5kIGNoYXJhY3RlcnMuICovCi0gICAgcHJpdmF0ZSBmaW5hbCBRTmFtZSBmRWxlbWVudFFOYW1lID0gbmV3IFFOYW1lKCk7Ci0gICAgcHJpdmF0ZSBmaW5hbCBRTmFtZSBmQXR0cmlidXRlUU5hbWUgPSBuZXcgUU5hbWUoKTsKLSAgICBwcml2YXRlIGZpbmFsIFhNTEF0dHJpYnV0ZXNJbXBsIGZBdHRyaWJ1dGVzID0gbmV3IFhNTEF0dHJpYnV0ZXNJbXBsKCk7Ci0gICAgcHJpdmF0ZSBmaW5hbCBBdHRyaWJ1dGVzUHJveHkgZkF0dHJBZGFwdGVyID0gbmV3IEF0dHJpYnV0ZXNQcm94eShmQXR0cmlidXRlcyk7Ci0gICAgcHJpdmF0ZSBmaW5hbCBYTUxTdHJpbmcgZlRlbXBTdHJpbmcgPSBuZXcgWE1MU3RyaW5nKCk7Ci0KLSAgICAvLwotICAgIC8vIFVzZXIgT2JqZWN0cwotICAgIC8vCi0KLSAgICBwcml2YXRlIENvbnRlbnRIYW5kbGVyIGZDb250ZW50SGFuZGxlciA9IG51bGw7Ci0KLSAgICAvKgotICAgICAqIENvbnN0cnVjdG9ycwotICAgICAqLwotCi0gICAgcHVibGljIFZhbGlkYXRvckhhbmRsZXJJbXBsKFhTR3JhbW1hclBvb2xDb250YWluZXIgZ3JhbW1hckNvbnRhaW5lcikgewotICAgICAgICB0aGlzKG5ldyBYTUxTY2hlbWFWYWxpZGF0b3JDb21wb25lbnRNYW5hZ2VyKGdyYW1tYXJDb250YWluZXIpKTsKLSAgICAgICAgZkNvbXBvbmVudE1hbmFnZXIuYWRkUmVjb2duaXplZEZlYXR1cmVzKG5ldyBTdHJpbmcgW10ge05BTUVTUEFDRV9QUkVGSVhFU30pOwotICAgICAgICBmQ29tcG9uZW50TWFuYWdlci5zZXRGZWF0dXJlKE5BTUVTUEFDRV9QUkVGSVhFUywgZmFsc2UpOwotICAgICAgICBzZXRFcnJvckhhbmRsZXIobnVsbCk7Ci0gICAgICAgIHNldFJlc291cmNlUmVzb2x2ZXIobnVsbCk7Ci0gICAgfQotCi0gICAgcHVibGljIFZhbGlkYXRvckhhbmRsZXJJbXBsKFhNTFNjaGVtYVZhbGlkYXRvckNvbXBvbmVudE1hbmFnZXIgY29tcG9uZW50TWFuYWdlcikgewotICAgICAgICBmQ29tcG9uZW50TWFuYWdlciA9IGNvbXBvbmVudE1hbmFnZXI7Ci0gICAgICAgIGZFcnJvclJlcG9ydGVyID0gKFhNTEVycm9yUmVwb3J0ZXIpIGZDb21wb25lbnRNYW5hZ2VyLmdldFByb3BlcnR5KEVSUk9SX1JFUE9SVEVSKTsKLSAgICAgICAgZk5hbWVzcGFjZUNvbnRleHQgPSAoTmFtZXNwYWNlQ29udGV4dCkgZkNvbXBvbmVudE1hbmFnZXIuZ2V0UHJvcGVydHkoTkFNRVNQQUNFX0NPTlRFWFQpOwotICAgICAgICBmU2NoZW1hVmFsaWRhdG9yID0gKFhNTFNjaGVtYVZhbGlkYXRvcikgZkNvbXBvbmVudE1hbmFnZXIuZ2V0UHJvcGVydHkoU0NIRU1BX1ZBTElEQVRPUik7Ci0gICAgICAgIGZTeW1ib2xUYWJsZSA9IChTeW1ib2xUYWJsZSkgZkNvbXBvbmVudE1hbmFnZXIuZ2V0UHJvcGVydHkoU1lNQk9MX1RBQkxFKTsKLSAgICAgICAgZlZhbGlkYXRpb25NYW5hZ2VyID0gKFZhbGlkYXRpb25NYW5hZ2VyKSBmQ29tcG9uZW50TWFuYWdlci5nZXRQcm9wZXJ0eShWQUxJREFUSU9OX01BTkFHRVIpOwotICAgIH0KLQotICAgIC8qCi0gICAgICogVmFsaWRhdG9ySGFuZGxlciBtZXRob2RzCi0gICAgICovCi0KLSAgICBwdWJsaWMgdm9pZCBzZXRDb250ZW50SGFuZGxlcihDb250ZW50SGFuZGxlciByZWNlaXZlcikgewotICAgICAgICBmQ29udGVudEhhbmRsZXIgPSByZWNlaXZlcjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgQ29udGVudEhhbmRsZXIgZ2V0Q29udGVudEhhbmRsZXIoKSB7Ci0gICAgICAgIHJldHVybiBmQ29udGVudEhhbmRsZXI7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0RXJyb3JIYW5kbGVyKEVycm9ySGFuZGxlciBlcnJvckhhbmRsZXIpIHsKLSAgICAgICAgZkNvbXBvbmVudE1hbmFnZXIuc2V0RXJyb3JIYW5kbGVyKGVycm9ySGFuZGxlcik7Ci0gICAgfQotCi0gICAgcHVibGljIEVycm9ySGFuZGxlciBnZXRFcnJvckhhbmRsZXIoKSB7Ci0gICAgICAgIHJldHVybiBmQ29tcG9uZW50TWFuYWdlci5nZXRFcnJvckhhbmRsZXIoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRSZXNvdXJjZVJlc29sdmVyKExTUmVzb3VyY2VSZXNvbHZlciByZXNvdXJjZVJlc29sdmVyKSB7Ci0gICAgICAgIGZDb21wb25lbnRNYW5hZ2VyLnNldFJlc291cmNlUmVzb2x2ZXIocmVzb3VyY2VSZXNvbHZlcik7Ci0gICAgfQotCi0gICAgcHVibGljIExTUmVzb3VyY2VSZXNvbHZlciBnZXRSZXNvdXJjZVJlc29sdmVyKCkgewotICAgICAgICByZXR1cm4gZkNvbXBvbmVudE1hbmFnZXIuZ2V0UmVzb3VyY2VSZXNvbHZlcigpOwotICAgIH0KLQotICAgIHB1YmxpYyBUeXBlSW5mb1Byb3ZpZGVyIGdldFR5cGVJbmZvUHJvdmlkZXIoKSB7Ci0gICAgICAgIHJldHVybiBmVHlwZUluZm9Qcm92aWRlcjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXRGZWF0dXJlKFN0cmluZyBuYW1lKQotICAgICAgICB0aHJvd3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiwgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKG5hbWUgPT0gbnVsbCkgewotICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7Ci0gICAgICAgIH0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIHJldHVybiBmQ29tcG9uZW50TWFuYWdlci5nZXRGZWF0dXJlKG5hbWUpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIGZpbmFsIFN0cmluZyBpZGVudGlmaWVyID0gZS5nZXRJZGVudGlmaWVyKCk7Ci0gICAgICAgICAgICBmaW5hbCBTdHJpbmcga2V5ID0gZS5nZXRUeXBlKCkgPT0gU3RhdHVzLk5PVF9SRUNPR05JWkVEID8KLSAgICAgICAgICAgICAgICAgICAgImZlYXR1cmUtbm90LXJlY29nbml6ZWQiIDogImZlYXR1cmUtbm90LXN1cHBvcnRlZCI7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgU0FYTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKGZDb21wb25lbnRNYW5hZ2VyLmdldExvY2FsZSgpLAotICAgICAgICAgICAgICAgICAgICBrZXksIG5ldyBPYmplY3QgW10ge2lkZW50aWZpZXJ9KSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRGZWF0dXJlKFN0cmluZyBuYW1lLCBib29sZWFuIHZhbHVlKQotICAgICAgICB0aHJvd3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiwgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKG5hbWUgPT0gbnVsbCkgewotICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7Ci0gICAgICAgIH0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGZDb21wb25lbnRNYW5hZ2VyLnNldEZlYXR1cmUobmFtZSwgdmFsdWUpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIGZpbmFsIFN0cmluZyBpZGVudGlmaWVyID0gZS5nZXRJZGVudGlmaWVyKCk7Ci0gICAgICAgICAgICBmaW5hbCBTdHJpbmcga2V5OwotICAgICAgICAgICAgaWYgKGUuZ2V0VHlwZSgpID09IFN0YXR1cy5OT1RfQUxMT1dFRCkgewotICAgICAgICAgICAgICAgIC8vZm9yIG5vdywgdGhlIGlkZW50aWZpZXIgY2FuIG9ubHkgYmUgKFhNTENvbnN0YW50cy5GRUFUVVJFX1NFQ1VSRV9QUk9DRVNTSU5HKQotICAgICAgICAgICAgICAgIHRocm93IG5ldyBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgIFNBWE1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShmQ29tcG9uZW50TWFuYWdlci5nZXRMb2NhbGUoKSwKLSAgICAgICAgICAgICAgICAgICAgImpheHAtc2VjdXJlcHJvY2Vzc2luZy1mZWF0dXJlIiwgbnVsbCkpOwotICAgICAgICAgICAgfSBlbHNlIGlmIChlLmdldFR5cGUoKSA9PSBTdGF0dXMuTk9UX1JFQ09HTklaRUQpIHsKLSAgICAgICAgICAgICAgICBrZXkgPSAiZmVhdHVyZS1ub3QtcmVjb2duaXplZCI7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIGtleSA9ICJmZWF0dXJlLW5vdC1zdXBwb3J0ZWQiOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgdGhyb3cgbmV3IFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgIFNBWE1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShmQ29tcG9uZW50TWFuYWdlci5nZXRMb2NhbGUoKSwKLSAgICAgICAgICAgICAgICAgICAga2V5LCBuZXcgT2JqZWN0IFtdIHtpZGVudGlmaWVyfSkpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIE9iamVjdCBnZXRQcm9wZXJ0eShTdHJpbmcgbmFtZSkKLSAgICAgICAgdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChuYW1lID09IG51bGwpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwotICAgICAgICB9Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICByZXR1cm4gZkNvbXBvbmVudE1hbmFnZXIuZ2V0UHJvcGVydHkobmFtZSk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gZSkgewotICAgICAgICAgICAgZmluYWwgU3RyaW5nIGlkZW50aWZpZXIgPSBlLmdldElkZW50aWZpZXIoKTsKLSAgICAgICAgICAgIGZpbmFsIFN0cmluZyBrZXkgPSBlLmdldFR5cGUoKSA9PSBTdGF0dXMuTk9UX1JFQ09HTklaRUQgPwotICAgICAgICAgICAgICAgICAgICAicHJvcGVydHktbm90LXJlY29nbml6ZWQiIDogInByb3BlcnR5LW5vdC1zdXBwb3J0ZWQiOwotICAgICAgICAgICAgdGhyb3cgbmV3IFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgIFNBWE1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShmQ29tcG9uZW50TWFuYWdlci5nZXRMb2NhbGUoKSwKLSAgICAgICAgICAgICAgICAgICAga2V5LCBuZXcgT2JqZWN0IFtdIHtpZGVudGlmaWVyfSkpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0UHJvcGVydHkoU3RyaW5nIG5hbWUsIE9iamVjdCBvYmplY3QpCi0gICAgICAgIHRocm93cyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uLCBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gewotICAgICAgICBpZiAobmFtZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKLSAgICAgICAgfQotICAgICAgICB0cnkgewotICAgICAgICAgICAgZkNvbXBvbmVudE1hbmFnZXIuc2V0UHJvcGVydHkobmFtZSwgb2JqZWN0KTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICBmaW5hbCBTdHJpbmcgaWRlbnRpZmllciA9IGUuZ2V0SWRlbnRpZmllcigpOwotICAgICAgICAgICAgZmluYWwgU3RyaW5nIGtleSA9IGUuZ2V0VHlwZSgpID09IFN0YXR1cy5OT1RfUkVDT0dOSVpFRCA/Ci0gICAgICAgICAgICAgICAgICAgICJwcm9wZXJ0eS1ub3QtcmVjb2duaXplZCIgOiAicHJvcGVydHktbm90LXN1cHBvcnRlZCI7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgU0FYTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKGZDb21wb25lbnRNYW5hZ2VyLmdldExvY2FsZSgpLAotICAgICAgICAgICAgICAgICAgICBrZXksIG5ldyBPYmplY3QgW10ge2lkZW50aWZpZXJ9KSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKgotICAgICAqIEVudGl0eVN0YXRlIG1ldGhvZHMKLSAgICAgKi8KLQotICAgIHB1YmxpYyBib29sZWFuIGlzRW50aXR5RGVjbGFyZWQoU3RyaW5nIG5hbWUpIHsKLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGlzRW50aXR5VW5wYXJzZWQoU3RyaW5nIG5hbWUpIHsKLSAgICAgICAgaWYgKGZVbnBhcnNlZEVudGl0aWVzICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBmVW5wYXJzZWRFbnRpdGllcy5jb250YWluc0tleShuYW1lKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgLyoKLSAgICAgKiBYTUxEb2N1bWVudEhhbmRsZXIgbWV0aG9kcwotICAgICAqLwotCi0gICAgcHVibGljIHZvaWQgc3RhcnREb2N1bWVudChYTUxMb2NhdG9yIGxvY2F0b3IsIFN0cmluZyBlbmNvZGluZywKLSAgICAgICAgICAgIE5hbWVzcGFjZUNvbnRleHQgbmFtZXNwYWNlQ29udGV4dCwgQXVnbWVudGF0aW9ucyBhdWdzKQotICAgICAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChmQ29udGVudEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICBmQ29udGVudEhhbmRsZXIuc3RhcnREb2N1bWVudCgpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFhOSUV4Y2VwdGlvbihlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHhtbERlY2woU3RyaW5nIHZlcnNpb24sIFN0cmluZyBlbmNvZGluZywgU3RyaW5nIHN0YW5kYWxvbmUsCi0gICAgICAgICAgICBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24ge30KLQotICAgIHB1YmxpYyB2b2lkIGRvY3R5cGVEZWNsKFN0cmluZyByb290RWxlbWVudCwgU3RyaW5nIHB1YmxpY0lkLAotICAgICAgICAgICAgU3RyaW5nIHN5c3RlbUlkLCBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24ge30KLQotICAgIHB1YmxpYyB2b2lkIGNvbW1lbnQoWE1MU3RyaW5nIHRleHQsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7fQotCi0gICAgcHVibGljIHZvaWQgcHJvY2Vzc2luZ0luc3RydWN0aW9uKFN0cmluZyB0YXJnZXQsIFhNTFN0cmluZyBkYXRhLAotICAgICAgICAgICAgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKGZDb250ZW50SGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIGZDb250ZW50SGFuZGxlci5wcm9jZXNzaW5nSW5zdHJ1Y3Rpb24odGFyZ2V0LCBkYXRhLnRvU3RyaW5nKCkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFhOSUV4Y2VwdGlvbihlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudChRTmFtZSBlbGVtZW50LCBYTUxBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMsCi0gICAgICAgICAgICBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBpZiAoZkNvbnRlbnRIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgZlR5cGVJbmZvUHJvdmlkZXIuYmVnaW5TdGFydEVsZW1lbnQoYXVncywgYXR0cmlidXRlcyk7Ci0gICAgICAgICAgICAgICAgZkNvbnRlbnRIYW5kbGVyLnN0YXJ0RWxlbWVudCgoZWxlbWVudC51cmkgIT0gbnVsbCkgPyBlbGVtZW50LnVyaSA6IFhNTFN5bWJvbHMuRU1QVFlfU1RSSU5HLAotICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5sb2NhbHBhcnQsIGVsZW1lbnQucmF3bmFtZSwgZkF0dHJBZGFwdGVyKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhdGNoIChTQVhFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBYTklFeGNlcHRpb24oZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmaW5hbGx5IHsKLSAgICAgICAgICAgICAgICBmVHlwZUluZm9Qcm92aWRlci5maW5pc2hTdGFydEVsZW1lbnQoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGVtcHR5RWxlbWVudChRTmFtZSBlbGVtZW50LCBYTUxBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMsCi0gICAgICAgICAgICBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICAvKiogU3BsaXQgZW1wdHkgZWxlbWVudCBldmVudC4gKiovCi0gICAgICAgIHN0YXJ0RWxlbWVudChlbGVtZW50LCBhdHRyaWJ1dGVzLCBhdWdzKTsKLSAgICAgICAgZW5kRWxlbWVudChlbGVtZW50LCBhdWdzKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzdGFydEdlbmVyYWxFbnRpdHkoU3RyaW5nIG5hbWUsCi0gICAgICAgICAgICBYTUxSZXNvdXJjZUlkZW50aWZpZXIgaWRlbnRpZmllciwgU3RyaW5nIGVuY29kaW5nLAotICAgICAgICAgICAgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHt9Ci0KLSAgICBwdWJsaWMgdm9pZCB0ZXh0RGVjbChTdHJpbmcgdmVyc2lvbiwgU3RyaW5nIGVuY29kaW5nLCBBdWdtZW50YXRpb25zIGF1Z3MpCi0gICAgICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHt9Ci0KLSAgICBwdWJsaWMgdm9pZCBlbmRHZW5lcmFsRW50aXR5KFN0cmluZyBuYW1lLCBBdWdtZW50YXRpb25zIGF1Z3MpCi0gICAgICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHt9Ci0KLSAgICBwdWJsaWMgdm9pZCBjaGFyYWN0ZXJzKFhNTFN0cmluZyB0ZXh0LCBBdWdtZW50YXRpb25zIGF1Z3MpCi0gICAgICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKGZDb250ZW50SGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAvLyBpZiB0aGUgdHlwZSBpcyB1bmlvbiBpdCBpcyBwb3NzaWJsZSB0aGF0IHdlIHJlY2VpdmUKLSAgICAgICAgICAgIC8vIGEgY2hhcmFjdGVyIGNhbGwgd2l0aCBlbXB0eSBkYXRhCi0gICAgICAgICAgICBpZiAodGV4dC5sZW5ndGggPT0gMCkgewotICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgZkNvbnRlbnRIYW5kbGVyLmNoYXJhY3RlcnModGV4dC5jaCwgdGV4dC5vZmZzZXQsIHRleHQubGVuZ3RoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhdGNoIChTQVhFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBYTklFeGNlcHRpb24oZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBpZ25vcmFibGVXaGl0ZXNwYWNlKFhNTFN0cmluZyB0ZXh0LCBBdWdtZW50YXRpb25zIGF1Z3MpCi0gICAgICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKGZDb250ZW50SGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIGZDb250ZW50SGFuZGxlci5pZ25vcmFibGVXaGl0ZXNwYWNlKHRleHQuY2gsIHRleHQub2Zmc2V0LCB0ZXh0Lmxlbmd0aCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWE5JRXhjZXB0aW9uKGUpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgZW5kRWxlbWVudChRTmFtZSBlbGVtZW50LCBBdWdtZW50YXRpb25zIGF1Z3MpCi0gICAgICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKGZDb250ZW50SGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIGZUeXBlSW5mb1Byb3ZpZGVyLmJlZ2luRW5kRWxlbWVudChhdWdzKTsKLSAgICAgICAgICAgICAgICBmQ29udGVudEhhbmRsZXIuZW5kRWxlbWVudCgoZWxlbWVudC51cmkgIT0gbnVsbCkgPyBlbGVtZW50LnVyaSA6IFhNTFN5bWJvbHMuRU1QVFlfU1RSSU5HLAotICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5sb2NhbHBhcnQsIGVsZW1lbnQucmF3bmFtZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWE5JRXhjZXB0aW9uKGUpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZmluYWxseSB7Ci0gICAgICAgICAgICAgICAgZlR5cGVJbmZvUHJvdmlkZXIuZmluaXNoRW5kRWxlbWVudCgpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc3RhcnRDREFUQShBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24ge30KLQotICAgIHB1YmxpYyB2b2lkIGVuZENEQVRBKEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7fQotCi0gICAgcHVibGljIHZvaWQgZW5kRG9jdW1lbnQoQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKGZDb250ZW50SGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIGZDb250ZW50SGFuZGxlci5lbmREb2N1bWVudCgpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFhOSUV4Y2VwdGlvbihlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIC8vIE5PLU9QCi0gICAgcHVibGljIHZvaWQgc2V0RG9jdW1lbnRTb3VyY2UoWE1MRG9jdW1lbnRTb3VyY2Ugc291cmNlKSB7fQotCi0gICAgcHVibGljIFhNTERvY3VtZW50U291cmNlIGdldERvY3VtZW50U291cmNlKCkgewotICAgICAgICByZXR1cm4gZlNjaGVtYVZhbGlkYXRvcjsKLSAgICB9Ci0KLSAgICAvKgotICAgICAqIENvbnRlbnRIYW5kbGVyIG1ldGhvZHMKLSAgICAgKi8KLQotICAgIHB1YmxpYyB2b2lkIHNldERvY3VtZW50TG9jYXRvcihMb2NhdG9yIGxvY2F0b3IpIHsKLSAgICAgICAgZlNBWExvY2F0b3JXcmFwcGVyLnNldExvY2F0b3IobG9jYXRvcik7Ci0gICAgICAgIGlmIChmQ29udGVudEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkNvbnRlbnRIYW5kbGVyLnNldERvY3VtZW50TG9jYXRvcihsb2NhdG9yKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RG9jdW1lbnQoKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICAgICAgZkNvbXBvbmVudE1hbmFnZXIucmVzZXQoKTsKLSAgICAgICAgZlNjaGVtYVZhbGlkYXRvci5zZXREb2N1bWVudEhhbmRsZXIodGhpcyk7Ci0gICAgICAgIGZWYWxpZGF0aW9uTWFuYWdlci5zZXRFbnRpdHlTdGF0ZSh0aGlzKTsKLSAgICAgICAgZlR5cGVJbmZvUHJvdmlkZXIuZmluaXNoU3RhcnRFbGVtZW50KCk7IC8vIGNsZWFucyB1cCBUeXBlSW5mb1Byb3ZpZGVyCi0gICAgICAgIGZOZWVkUHVzaE5TQ29udGV4dCA9IHRydWU7Ci0gICAgICAgIGlmIChmVW5wYXJzZWRFbnRpdGllcyAhPSBudWxsICYmICFmVW5wYXJzZWRFbnRpdGllcy5pc0VtcHR5KCkpIHsKLSAgICAgICAgICAgIC8vIHNob3VsZCBvbmx5IGNsZWFyIHRoaXMgaWYgdGhlIGxhc3QgZG9jdW1lbnQgY29udGFpbmVkIHVucGFyc2VkIGVudGl0aWVzCi0gICAgICAgICAgICBmVW5wYXJzZWRFbnRpdGllcy5jbGVhcigpOwotICAgICAgICB9Ci0gICAgICAgIGZFcnJvclJlcG9ydGVyLnNldERvY3VtZW50TG9jYXRvcihmU0FYTG9jYXRvcldyYXBwZXIpOwotICAgICAgICB0cnkgewotICAgICAgICAgICAgZlNjaGVtYVZhbGlkYXRvci5zdGFydERvY3VtZW50KGZTQVhMb2NhdG9yV3JhcHBlciwgZlNBWExvY2F0b3JXcmFwcGVyLmdldEVuY29kaW5nKCksIGZOYW1lc3BhY2VDb250ZXh0LCBudWxsKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoWE1MUGFyc2VFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgdGhyb3cgVXRpbC50b1NBWFBhcnNlRXhjZXB0aW9uKGUpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChYTklFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgdGhyb3cgVXRpbC50b1NBWEV4Y2VwdGlvbihlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGVuZERvY3VtZW50KCkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0gICAgICAgIGZTQVhMb2NhdG9yV3JhcHBlci5zZXRMb2NhdG9yKG51bGwpOwotICAgICAgICB0cnkgewotICAgICAgICAgICAgZlNjaGVtYVZhbGlkYXRvci5lbmREb2N1bWVudChudWxsKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoWE1MUGFyc2VFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgdGhyb3cgVXRpbC50b1NBWFBhcnNlRXhjZXB0aW9uKGUpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChYTklFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgdGhyb3cgVXRpbC50b1NBWEV4Y2VwdGlvbihlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHN0YXJ0UHJlZml4TWFwcGluZyhTdHJpbmcgcHJlZml4LCBTdHJpbmcgdXJpKQotICAgICAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0gICAgICAgIFN0cmluZyBwcmVmaXhTeW1ib2w7Ci0gICAgICAgIFN0cmluZyB1cmlTeW1ib2w7Ci0gICAgICAgIGlmICghZlN0cmluZ3NJbnRlcm5hbGl6ZWQpIHsKLSAgICAgICAgICAgIHByZWZpeFN5bWJvbCA9IChwcmVmaXggIT0gbnVsbCkgPyBmU3ltYm9sVGFibGUuYWRkU3ltYm9sKHByZWZpeCkgOiBYTUxTeW1ib2xzLkVNUFRZX1NUUklORzsKLSAgICAgICAgICAgIHVyaVN5bWJvbCA9ICh1cmkgIT0gbnVsbCAmJiB1cmkubGVuZ3RoKCkgPiAwKSA/IGZTeW1ib2xUYWJsZS5hZGRTeW1ib2wodXJpKSA6IG51bGw7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBwcmVmaXhTeW1ib2wgPSAocHJlZml4ICE9IG51bGwpID8gcHJlZml4IDogWE1MU3ltYm9scy5FTVBUWV9TVFJJTkc7Ci0gICAgICAgICAgICB1cmlTeW1ib2wgPSAodXJpICE9IG51bGwgJiYgdXJpLmxlbmd0aCgpID4gMCkgPyB1cmkgOiBudWxsOwotICAgICAgICB9Ci0gICAgICAgIGlmIChmTmVlZFB1c2hOU0NvbnRleHQpIHsKLSAgICAgICAgICAgIGZOZWVkUHVzaE5TQ29udGV4dCA9IGZhbHNlOwotICAgICAgICAgICAgZk5hbWVzcGFjZUNvbnRleHQucHVzaENvbnRleHQoKTsKLSAgICAgICAgfQotICAgICAgICBmTmFtZXNwYWNlQ29udGV4dC5kZWNsYXJlUHJlZml4KHByZWZpeFN5bWJvbCwgdXJpU3ltYm9sKTsKLSAgICAgICAgaWYgKGZDb250ZW50SGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmQ29udGVudEhhbmRsZXIuc3RhcnRQcmVmaXhNYXBwaW5nKHByZWZpeCwgdXJpKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGVuZFByZWZpeE1hcHBpbmcoU3RyaW5nIHByZWZpeCkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChmQ29udGVudEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkNvbnRlbnRIYW5kbGVyLmVuZFByZWZpeE1hcHBpbmcocHJlZml4KTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudChTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxOYW1lLCBTdHJpbmcgcU5hbWUsCi0gICAgICAgICAgICBBdHRyaWJ1dGVzIGF0dHMpIHRocm93cyBTQVhFeGNlcHRpb24gewotICAgICAgICBpZiAoZk5lZWRQdXNoTlNDb250ZXh0KSB7Ci0gICAgICAgICAgICBmTmFtZXNwYWNlQ29udGV4dC5wdXNoQ29udGV4dCgpOwotICAgICAgICB9Ci0gICAgICAgIGZOZWVkUHVzaE5TQ29udGV4dCA9IHRydWU7Ci0KLSAgICAgICAgLy8gRmlsbCBlbGVtZW50IFFOYW1lCi0gICAgICAgIGZpbGxRTmFtZShmRWxlbWVudFFOYW1lLCB1cmksIGxvY2FsTmFtZSwgcU5hbWUpOwotCi0gICAgICAgIC8vIEZpbGwgWE1MQXR0cmlidXRlcwotICAgICAgICBpZiAoYXR0cyBpbnN0YW5jZW9mIEF0dHJpYnV0ZXMyKSB7Ci0gICAgICAgICAgICBmaWxsWE1MQXR0cmlidXRlczIoKEF0dHJpYnV0ZXMyKSBhdHRzKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIGZpbGxYTUxBdHRyaWJ1dGVzKGF0dHMpOwotICAgICAgICB9Ci0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGZTY2hlbWFWYWxpZGF0b3Iuc3RhcnRFbGVtZW50KGZFbGVtZW50UU5hbWUsIGZBdHRyaWJ1dGVzLCBudWxsKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoWE1MUGFyc2VFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgdGhyb3cgVXRpbC50b1NBWFBhcnNlRXhjZXB0aW9uKGUpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChYTklFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgdGhyb3cgVXRpbC50b1NBWEV4Y2VwdGlvbihlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGVuZEVsZW1lbnQoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSwgU3RyaW5nIHFOYW1lKQotICAgICAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0gICAgICAgIGZpbGxRTmFtZShmRWxlbWVudFFOYW1lLCB1cmksIGxvY2FsTmFtZSwgcU5hbWUpOwotICAgICAgICB0cnkgewotICAgICAgICAgICAgZlNjaGVtYVZhbGlkYXRvci5lbmRFbGVtZW50KGZFbGVtZW50UU5hbWUsIG51bGwpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChYTUxQYXJzZUV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICB0aHJvdyBVdGlsLnRvU0FYUGFyc2VFeGNlcHRpb24oZSk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKFhOSUV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICB0aHJvdyBVdGlsLnRvU0FYRXhjZXB0aW9uKGUpOwotICAgICAgICB9Ci0gICAgICAgIGZpbmFsbHkgewotICAgICAgICAgICAgZk5hbWVzcGFjZUNvbnRleHQucG9wQ29udGV4dCgpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgY2hhcmFjdGVycyhjaGFyW10gY2gsIGludCBzdGFydCwgaW50IGxlbmd0aCkKLSAgICAgICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24gewotICAgICAgICB0cnkgewotICAgICAgICAgICAgZlRlbXBTdHJpbmcuc2V0VmFsdWVzKGNoLCBzdGFydCwgbGVuZ3RoKTsKLSAgICAgICAgICAgIGZTY2hlbWFWYWxpZGF0b3IuY2hhcmFjdGVycyhmVGVtcFN0cmluZywgbnVsbCk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKFhNTFBhcnNlRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIHRocm93IFV0aWwudG9TQVhQYXJzZUV4Y2VwdGlvbihlKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoWE5JRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIHRocm93IFV0aWwudG9TQVhFeGNlcHRpb24oZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBpZ25vcmFibGVXaGl0ZXNwYWNlKGNoYXJbXSBjaCwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKQotICAgICAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBmVGVtcFN0cmluZy5zZXRWYWx1ZXMoY2gsIHN0YXJ0LCBsZW5ndGgpOwotICAgICAgICAgICAgZlNjaGVtYVZhbGlkYXRvci5pZ25vcmFibGVXaGl0ZXNwYWNlKGZUZW1wU3RyaW5nLCBudWxsKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoWE1MUGFyc2VFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgdGhyb3cgVXRpbC50b1NBWFBhcnNlRXhjZXB0aW9uKGUpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChYTklFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgdGhyb3cgVXRpbC50b1NBWEV4Y2VwdGlvbihlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHByb2Nlc3NpbmdJbnN0cnVjdGlvbihTdHJpbmcgdGFyZ2V0LCBTdHJpbmcgZGF0YSkKLSAgICAgICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24gewotICAgICAgICAvKioKLSAgICAgICAgICogUHJvY2Vzc2luZyBpbnN0cnVjdGlvbnMgZG8gbm90IHBhcnRpY2lwYXRlIGluIHNjaGVtYSB2YWxpZGF0aW9uLAotICAgICAgICAgKiBzbyBqdXN0IGZvcndhcmQgdGhlIGV2ZW50IHRvIHRoZSBhcHBsaWNhdGlvbidzIGNvbnRlbnQKLSAgICAgICAgICogaGFuZGxlci4KLSAgICAgICAgICovCi0gICAgICAgIGlmIChmQ29udGVudEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkNvbnRlbnRIYW5kbGVyLnByb2Nlc3NpbmdJbnN0cnVjdGlvbih0YXJnZXQsIGRhdGEpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2tpcHBlZEVudGl0eShTdHJpbmcgbmFtZSkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0gICAgICAgIC8vIHRoZXJlIHNlZW1zIHRvIGJlIG5vIGNvcnJlc3BvbmRpbmcgbWV0aG9kIG9uIFhNTERvY3VtZW50RmlsdGVyLgotICAgICAgICAvLyBqdXN0IHBhc3MgaXQgZG93biB0byB0aGUgb3V0cHV0LCBpZiBhbnkuCi0gICAgICAgIGlmIChmQ29udGVudEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkNvbnRlbnRIYW5kbGVyLnNraXBwZWRFbnRpdHkobmFtZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKgotICAgICAqIERUREhhbmRsZXIgbWV0aG9kcwotICAgICAqLwotCi0gICAgcHVibGljIHZvaWQgbm90YXRpb25EZWNsKFN0cmluZyBuYW1lLCBTdHJpbmcgcHVibGljSWQsCi0gICAgICAgICAgICBTdHJpbmcgc3lzdGVtSWQpIHRocm93cyBTQVhFeGNlcHRpb24ge30KLQotICAgIHB1YmxpYyB2b2lkIHVucGFyc2VkRW50aXR5RGVjbChTdHJpbmcgbmFtZSwgU3RyaW5nIHB1YmxpY0lkLAotICAgICAgICAgICAgU3RyaW5nIHN5c3RlbUlkLCBTdHJpbmcgbm90YXRpb25OYW1lKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKGZVbnBhcnNlZEVudGl0aWVzID09IG51bGwpIHsKLSAgICAgICAgICAgIGZVbnBhcnNlZEVudGl0aWVzID0gbmV3IEhhc2hNYXAoKTsKLSAgICAgICAgfQotICAgICAgICBmVW5wYXJzZWRFbnRpdGllcy5wdXQobmFtZSwgbmFtZSk7Ci0gICAgfQotCi0gICAgLyoKLSAgICAgKiBWYWxpZGF0b3JIZWxwZXIgbWV0aG9kcwotICAgICAqLwotCi0gICAgcHVibGljIHZvaWQgdmFsaWRhdGUoU291cmNlIHNvdXJjZSwgUmVzdWx0IHJlc3VsdCkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewotICAgICAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgU0FYUmVzdWx0IHx8IHJlc3VsdCA9PSBudWxsKSB7Ci0gICAgICAgICAgICBmaW5hbCBTQVhTb3VyY2Ugc2F4U291cmNlID0gKFNBWFNvdXJjZSkgc291cmNlOwotICAgICAgICAgICAgZmluYWwgU0FYUmVzdWx0IHNheFJlc3VsdCA9IChTQVhSZXN1bHQpIHJlc3VsdDsKLQotICAgICAgICAgICAgaWYgKHJlc3VsdCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgc2V0Q29udGVudEhhbmRsZXIoc2F4UmVzdWx0LmdldEhhbmRsZXIoKSk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgWE1MUmVhZGVyIHJlYWRlciA9IHNheFNvdXJjZS5nZXRYTUxSZWFkZXIoKTsKLSAgICAgICAgICAgICAgICBpZiggcmVhZGVyPT1udWxsICkgewotICAgICAgICAgICAgICAgICAgICAvLyBjcmVhdGUgb25lIG5vdwotICAgICAgICAgICAgICAgICAgICBTQVhQYXJzZXJGYWN0b3J5IHNwZiA9IGZDb21wb25lbnRNYW5hZ2VyLmdldEZlYXR1cmUoQ29uc3RhbnRzLk9SQUNMRV9GRUFUVVJFX1NFUlZJQ0VfTUVDSEFOSVNNKSA/Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTQVhQYXJzZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCkgOiBuZXcgU0FYUGFyc2VyRmFjdG9yeUltcGwoKTsKLSAgICAgICAgICAgICAgICAgICAgc3BmLnNldE5hbWVzcGFjZUF3YXJlKHRydWUpOwotICAgICAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICAgICAgc3BmLnNldEZlYXR1cmUoWE1MQ29uc3RhbnRzLkZFQVRVUkVfU0VDVVJFX1BST0NFU1NJTkcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZDb21wb25lbnRNYW5hZ2VyLmdldEZlYXR1cmUoWE1MQ29uc3RhbnRzLkZFQVRVUkVfU0VDVVJFX1BST0NFU1NJTkcpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJlYWRlciA9IHNwZi5uZXdTQVhQYXJzZXIoKS5nZXRYTUxSZWFkZXIoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIElmIHRoaXMgaXMgYSBYZXJjZXMgU0FYIHBhcnNlciwgc2V0IHRoZSBzZWN1cml0eSBtYW5hZ2VyIGlmIHRoZXJlIGlzIG9uZQotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlYWRlciBpbnN0YW5jZW9mIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwucGFyc2Vycy5TQVhQYXJzZXIpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTFNlY3VyaXR5TWFuYWdlciBzZWN1cml0eU1hbmFnZXIgPSAoWE1MU2VjdXJpdHlNYW5hZ2VyKSBmQ29tcG9uZW50TWFuYWdlci5nZXRQcm9wZXJ0eShTRUNVUklUWV9NQU5BR0VSKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZWN1cml0eU1hbmFnZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlYWRlci5zZXRQcm9wZXJ0eShTRUNVUklUWV9NQU5BR0VSLCBzZWN1cml0eU1hbmFnZXIpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJZ25vcmUgdGhlIGV4Y2VwdGlvbiBpZiB0aGUgc2VjdXJpdHkgbWFuYWdlciBjYW5ub3QgYmUgc2V0LgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhdGNoIChTQVhFeGNlcHRpb24gZXhjKSB7fQotICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxTZWN1cml0eVByb3BlcnR5TWFuYWdlciBzcG0gPSAoWE1MU2VjdXJpdHlQcm9wZXJ0eU1hbmFnZXIpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmQ29tcG9uZW50TWFuYWdlci5nZXRQcm9wZXJ0eShYTUxfU0VDVVJJVFlfUFJPUEVSVFlfTUFOQUdFUik7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhZGVyLnNldFByb3BlcnR5KFhNTENvbnN0YW50cy5BQ0NFU1NfRVhURVJOQUxfRFRELAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BtLmdldFZhbHVlKFhNTFNlY3VyaXR5UHJvcGVydHlNYW5hZ2VyLlByb3BlcnR5LkFDQ0VTU19FWFRFUk5BTF9EVEQpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBleGMpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxTZWN1cml0eU1hbmFnZXIucHJpbnRXYXJuaW5nKHJlYWRlci5nZXRDbGFzcygpLmdldE5hbWUoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTENvbnN0YW50cy5BQ0NFU1NfRVhURVJOQUxfRFRELCBleGMpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9IGNhdGNoKCBFeGNlcHRpb24gZSApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoaXMgaXMgaW1wb3NzaWJsZSwgYnV0IGJldHRlciBzYWZlIHRoYW4gc29ycnkKLSAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yKGUpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgLy8gSWYgWE1MIG5hbWVzIGFuZCBOYW1lc3BhY2UgVVJJcyBhcmUgYWxyZWFkeSBpbnRlcm5hbGl6ZWQgd2UKLSAgICAgICAgICAgICAgICAvLyBjYW4gYXZvaWQgcnVubmluZyB0aGVtIHRocm91Z2ggdGhlIFN5bWJvbFRhYmxlLgotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgIGZTdHJpbmdzSW50ZXJuYWxpemVkID0gcmVhZGVyLmdldEZlYXR1cmUoU1RSSU5HX0lOVEVSTklORyk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGNhdGNoIChTQVhFeGNlcHRpb24gZXhjKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIFRoZSBmZWF0dXJlIGlzbid0IHJlY29nbml6ZWQgb3IgZ2V0dGluZyBpdCBpcyBub3Qgc3VwcG9ydGVkLgotICAgICAgICAgICAgICAgICAgICAvLyBJbiBlaXRoZXIgY2FzZSwgYXNzdW1lIHRoYXQgc3RyaW5ncyBhcmUgbm90IGludGVybmFsaXplZC4KLSAgICAgICAgICAgICAgICAgICAgZlN0cmluZ3NJbnRlcm5hbGl6ZWQgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBFcnJvckhhbmRsZXIgZXJyb3JIYW5kbGVyID0gZkNvbXBvbmVudE1hbmFnZXIuZ2V0RXJyb3JIYW5kbGVyKCk7Ci0gICAgICAgICAgICAgICAgcmVhZGVyLnNldEVycm9ySGFuZGxlcihlcnJvckhhbmRsZXIgIT0gbnVsbCA/IGVycm9ySGFuZGxlciA6IERyYWNvbmlhbkVycm9ySGFuZGxlci5nZXRJbnN0YW5jZSgpKTsKLSAgICAgICAgICAgICAgICByZWFkZXIuc2V0RW50aXR5UmVzb2x2ZXIoZlJlc29sdXRpb25Gb3J3YXJkZXIpOwotICAgICAgICAgICAgICAgIGZSZXNvbHV0aW9uRm9yd2FyZGVyLnNldEVudGl0eVJlc29sdmVyKGZDb21wb25lbnRNYW5hZ2VyLmdldFJlc291cmNlUmVzb2x2ZXIoKSk7Ci0gICAgICAgICAgICAgICAgcmVhZGVyLnNldENvbnRlbnRIYW5kbGVyKHRoaXMpOwotICAgICAgICAgICAgICAgIHJlYWRlci5zZXREVERIYW5kbGVyKHRoaXMpOwotCi0gICAgICAgICAgICAgICAgSW5wdXRTb3VyY2UgaXMgPSBzYXhTb3VyY2UuZ2V0SW5wdXRTb3VyY2UoKTsKLSAgICAgICAgICAgICAgICByZWFkZXIucGFyc2UoaXMpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZmluYWxseSB7Ci0gICAgICAgICAgICAgICAgLy8gcmVsZWFzZSB0aGUgcmVmZXJlbmNlIHRvIHVzZXIncyBoYW5kbGVyIEFTQVAKLSAgICAgICAgICAgICAgICBzZXRDb250ZW50SGFuZGxlcihudWxsKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKEpBWFBWYWxpZGF0aW9uTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKGZDb21wb25lbnRNYW5hZ2VyLmdldExvY2FsZSgpLAotICAgICAgICAgICAgICAgICJTb3VyY2VSZXN1bHRNaXNtYXRjaCIsCi0gICAgICAgICAgICAgICAgbmV3IE9iamVjdCBbXSB7c291cmNlLmdldENsYXNzKCkuZ2V0TmFtZSgpLCByZXN1bHQuZ2V0Q2xhc3MoKS5nZXROYW1lKCl9KSk7Ci0gICAgfQotCi0gICAgLyoKLSAgICAgKiBQU1ZJUHJvdmlkZXIgbWV0aG9kcwotICAgICAqLwotCi0gICAgcHVibGljIEVsZW1lbnRQU1ZJIGdldEVsZW1lbnRQU1ZJKCkgewotICAgICAgICByZXR1cm4gZlR5cGVJbmZvUHJvdmlkZXIuZ2V0RWxlbWVudFBTVkkoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgQXR0cmlidXRlUFNWSSBnZXRBdHRyaWJ1dGVQU1ZJKGludCBpbmRleCkgewotICAgICAgICByZXR1cm4gZlR5cGVJbmZvUHJvdmlkZXIuZ2V0QXR0cmlidXRlUFNWSShpbmRleCk7Ci0gICAgfQotCi0gICAgcHVibGljIEF0dHJpYnV0ZVBTVkkgZ2V0QXR0cmlidXRlUFNWSUJ5TmFtZShTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxuYW1lKSB7Ci0gICAgICAgIHJldHVybiBmVHlwZUluZm9Qcm92aWRlci5nZXRBdHRyaWJ1dGVQU1ZJQnlOYW1lKHVyaSwgbG9jYWxuYW1lKTsKLSAgICB9Ci0KLSAgICAvLwotICAgIC8vCi0gICAgLy8gaGVscGVyIG1ldGhvZHMKLSAgICAvLwotICAgIC8vCi0KLSAgICAvKiogRmlsbHMgaW4gYSBRTmFtZSBvYmplY3QuICovCi0gICAgcHJpdmF0ZSB2b2lkIGZpbGxRTmFtZShRTmFtZSB0b0ZpbGwsIFN0cmluZyB1cmksIFN0cmluZyBsb2NhbHBhcnQsIFN0cmluZyByYXcpIHsKLSAgICAgICAgaWYgKCFmU3RyaW5nc0ludGVybmFsaXplZCkgewotICAgICAgICAgICAgdXJpID0gKHVyaSAhPSBudWxsICYmIHVyaS5sZW5ndGgoKSA+IDApID8gZlN5bWJvbFRhYmxlLmFkZFN5bWJvbCh1cmkpIDogbnVsbDsKLSAgICAgICAgICAgIGxvY2FscGFydCA9IChsb2NhbHBhcnQgIT0gbnVsbCkgPyBmU3ltYm9sVGFibGUuYWRkU3ltYm9sKGxvY2FscGFydCkgOiBYTUxTeW1ib2xzLkVNUFRZX1NUUklORzsKLSAgICAgICAgICAgIHJhdyA9IChyYXcgIT0gbnVsbCkgPyBmU3ltYm9sVGFibGUuYWRkU3ltYm9sKHJhdykgOiBYTUxTeW1ib2xzLkVNUFRZX1NUUklORzsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIGlmICh1cmkgIT0gbnVsbCAmJiB1cmkubGVuZ3RoKCkgPT0gMCkgewotICAgICAgICAgICAgICAgIHVyaSA9IG51bGw7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAobG9jYWxwYXJ0ID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBsb2NhbHBhcnQgPSBYTUxTeW1ib2xzLkVNUFRZX1NUUklORzsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChyYXcgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJhdyA9IFhNTFN5bWJvbHMuRU1QVFlfU1RSSU5HOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIFN0cmluZyBwcmVmaXggPSBYTUxTeW1ib2xzLkVNUFRZX1NUUklORzsKLSAgICAgICAgaW50IHByZWZpeElkeCA9IHJhdy5pbmRleE9mKCc6Jyk7Ci0gICAgICAgIGlmIChwcmVmaXhJZHggIT0gLTEpIHsKLSAgICAgICAgICAgIHByZWZpeCA9IGZTeW1ib2xUYWJsZS5hZGRTeW1ib2wocmF3LnN1YnN0cmluZygwLCBwcmVmaXhJZHgpKTsKLSAgICAgICAgfQotICAgICAgICB0b0ZpbGwuc2V0VmFsdWVzKHByZWZpeCwgbG9jYWxwYXJ0LCByYXcsIHVyaSk7Ci0gICAgfQotCi0gICAgLyoqIEZpbGxzIGluIHRoZSBYTUxBdHRyaWJ1dGVzIG9iamVjdC4gKi8KLSAgICBwcml2YXRlIHZvaWQgZmlsbFhNTEF0dHJpYnV0ZXMoQXR0cmlidXRlcyBhdHQpIHsKLSAgICAgICAgZkF0dHJpYnV0ZXMucmVtb3ZlQWxsQXR0cmlidXRlcygpOwotICAgICAgICBmaW5hbCBpbnQgbGVuID0gYXR0LmdldExlbmd0aCgpOwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbjsgKytpKSB7Ci0gICAgICAgICAgICBmaWxsWE1MQXR0cmlidXRlKGF0dCwgaSk7Ci0gICAgICAgICAgICBmQXR0cmlidXRlcy5zZXRTcGVjaWZpZWQoaSwgdHJ1ZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKiogRmlsbHMgaW4gdGhlIFhNTEF0dHJpYnV0ZXMgb2JqZWN0LiAqLwotICAgIHByaXZhdGUgdm9pZCBmaWxsWE1MQXR0cmlidXRlczIoQXR0cmlidXRlczIgYXR0KSB7Ci0gICAgICAgIGZBdHRyaWJ1dGVzLnJlbW92ZUFsbEF0dHJpYnV0ZXMoKTsKLSAgICAgICAgZmluYWwgaW50IGxlbiA9IGF0dC5nZXRMZW5ndGgoKTsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW47ICsraSkgewotICAgICAgICAgICAgZmlsbFhNTEF0dHJpYnV0ZShhdHQsIGkpOwotICAgICAgICAgICAgZkF0dHJpYnV0ZXMuc2V0U3BlY2lmaWVkKGksIGF0dC5pc1NwZWNpZmllZChpKSk7Ci0gICAgICAgICAgICBpZiAoYXR0LmlzRGVjbGFyZWQoaSkpIHsKLSAgICAgICAgICAgICAgICBmQXR0cmlidXRlcy5nZXRBdWdtZW50YXRpb25zKGkpLnB1dEl0ZW0oQ29uc3RhbnRzLkFUVFJJQlVURV9ERUNMQVJFRCwgQm9vbGVhbi5UUlVFKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKiBBZGRzIGFuIGF0dHJpYnV0ZSB0byB0aGUgWE1MQXR0cmlidXRlcyBvYmplY3QuICovCi0gICAgcHJpdmF0ZSB2b2lkIGZpbGxYTUxBdHRyaWJ1dGUoQXR0cmlidXRlcyBhdHQsIGludCBpbmRleCkgewotICAgICAgICBmaWxsUU5hbWUoZkF0dHJpYnV0ZVFOYW1lLCBhdHQuZ2V0VVJJKGluZGV4KSwgYXR0LmdldExvY2FsTmFtZShpbmRleCksIGF0dC5nZXRRTmFtZShpbmRleCkpOwotICAgICAgICBTdHJpbmcgdHlwZSA9IGF0dC5nZXRUeXBlKGluZGV4KTsKLSAgICAgICAgZkF0dHJpYnV0ZXMuYWRkQXR0cmlidXRlTlMoZkF0dHJpYnV0ZVFOYW1lLCAodHlwZSAhPSBudWxsKSA/IHR5cGUgOiBYTUxTeW1ib2xzLmZDREFUQVN5bWJvbCwgYXR0LmdldFZhbHVlKGluZGV4KSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICoge0BsaW5rIFR5cGVJbmZvUHJvdmlkZXJ9IGltcGxlbWVudGF0aW9uLgotICAgICAqCi0gICAgICogUkVWSVNJVDogSSdtIG5vdCBzdXJlIGlmIHRoaXMgY29kZSBzaG91bGQgYmVsb25nIGhlcmUuCi0gICAgICovCi0gICAgcHJpdmF0ZSBmaW5hbCBYTUxTY2hlbWFUeXBlSW5mb1Byb3ZpZGVyIGZUeXBlSW5mb1Byb3ZpZGVyID0gbmV3IFhNTFNjaGVtYVR5cGVJbmZvUHJvdmlkZXIoKTsKLSAgICBwcml2YXRlIGNsYXNzIFhNTFNjaGVtYVR5cGVJbmZvUHJvdmlkZXIgZXh0ZW5kcyBUeXBlSW5mb1Byb3ZpZGVyIHsKLQotICAgICAgICAvKiogRWxlbWVudCBhdWdtZW50YXRpb25zOiBjb250YWlucyBFbGVtZW50UFNWSS4gKiovCi0gICAgICAgIHByaXZhdGUgQXVnbWVudGF0aW9ucyBmRWxlbWVudEF1Z3M7Ci0KLSAgICAgICAgLyoqIEF0dHJpYnV0ZXM6IGF1Z21lbnRhdGlvbnMgZm9yIGVhY2ggYXR0cmlidXRlIGNvbnRhaW4gQXR0cmlidXRlUFNWSS4gKiovCi0gICAgICAgIHByaXZhdGUgWE1MQXR0cmlidXRlcyBmQXR0cmlidXRlczsKLQotICAgICAgICAvKiogSW4gc3RhcnQgZWxlbWVudC4gKiovCi0gICAgICAgIHByaXZhdGUgYm9vbGVhbiBmSW5TdGFydEVsZW1lbnQgPSBmYWxzZTsKLQotICAgICAgICAvKiogSW4gZW5kIGVsZW1lbnQuICoqLwotICAgICAgICBwcml2YXRlIGJvb2xlYW4gZkluRW5kRWxlbWVudCA9IGZhbHNlOwotCi0gICAgICAgIC8qKiBJbml0aWFsaXplcyB0aGUgVHlwZUluZm9Qcm92aWRlciB3aXRoIHR5cGUgaW5mb3JtYXRpb24gZm9yIHRoZSBjdXJyZW50IGVsZW1lbnQuICoqLwotICAgICAgICB2b2lkIGJlZ2luU3RhcnRFbGVtZW50KEF1Z21lbnRhdGlvbnMgZWxlbWVudEF1Z3MsIFhNTEF0dHJpYnV0ZXMgYXR0cmlidXRlcykgewotICAgICAgICAgICAgZkluU3RhcnRFbGVtZW50ID0gdHJ1ZTsKLSAgICAgICAgICAgIGZFbGVtZW50QXVncyA9IGVsZW1lbnRBdWdzOwotICAgICAgICAgICAgZkF0dHJpYnV0ZXMgPSBhdHRyaWJ1dGVzOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqIENsZWFudXAgYXQgdGhlIGVuZCBvZiBzdGFydCBlbGVtZW50LiAqKi8KLSAgICAgICAgdm9pZCBmaW5pc2hTdGFydEVsZW1lbnQoKSB7Ci0gICAgICAgICAgICBmSW5TdGFydEVsZW1lbnQgPSBmYWxzZTsKLSAgICAgICAgICAgIGZFbGVtZW50QXVncyA9IG51bGw7Ci0gICAgICAgICAgICBmQXR0cmlidXRlcyA9IG51bGw7Ci0gICAgICAgIH0KLQotICAgICAgICAvKiogSW5pdGlhbGl6ZXMgdGhlIFR5cGVJbmZvUHJvdmlkZXIgd2l0aCB0eXBlIGluZm9ybWF0aW9uIGZvciB0aGUgY3VycmVudCBlbGVtZW50LiAqKi8KLSAgICAgICAgdm9pZCBiZWdpbkVuZEVsZW1lbnQoQXVnbWVudGF0aW9ucyBlbGVtZW50QXVncykgewotICAgICAgICAgICAgZkluRW5kRWxlbWVudCA9IHRydWU7Ci0gICAgICAgICAgICBmRWxlbWVudEF1Z3MgPSBlbGVtZW50QXVnczsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKiBDbGVhbnVwIGF0IHRoZSBlbmQgb2YgZW5kIGVsZW1lbnQuICoqLwotICAgICAgICB2b2lkIGZpbmlzaEVuZEVsZW1lbnQoKSB7Ci0gICAgICAgICAgICBmSW5FbmRFbGVtZW50ID0gZmFsc2U7Ci0gICAgICAgICAgICBmRWxlbWVudEF1Z3MgPSBudWxsOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFRocm93cyBhIHtAbGluayBJbGxlZ2FsU3RhdGVFeGNlcHRpb259IGlmIHdlIGFyZSBub3QgaW4KLSAgICAgICAgICogdGhlIHN0YXJ0RWxlbWVudCBjYWxsYmFjay4gdGhlIEpBWFAgQVBJIHJlcXVpcmVzIHRoaXMKLSAgICAgICAgICogZm9yIG1vc3Qgb2YgdGhlIHB1YmxpYyBtZXRob2RzLgotICAgICAgICAgKi8KLSAgICAgICAgcHJpdmF0ZSB2b2lkIGNoZWNrU3RhdGUoYm9vbGVhbiBmb3JFbGVtZW50SW5mbykgewotICAgICAgICAgICAgaWYgKCEgKGZJblN0YXJ0RWxlbWVudCB8fCAoZkluRW5kRWxlbWVudCAmJiBmb3JFbGVtZW50SW5mbykpKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbihKQVhQVmFsaWRhdGlvbk1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShmQ29tcG9uZW50TWFuYWdlci5nZXRMb2NhbGUoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICJUeXBlSW5mb1Byb3ZpZGVySWxsZWdhbFN0YXRlIiwgbnVsbCkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIFR5cGVJbmZvIGdldEF0dHJpYnV0ZVR5cGVJbmZvKGludCBpbmRleCkgewotICAgICAgICAgICAgY2hlY2tTdGF0ZShmYWxzZSk7Ci0gICAgICAgICAgICByZXR1cm4gZ2V0QXR0cmlidXRlVHlwZShpbmRleCk7Ci0gICAgICAgIH0KLQotICAgICAgICBwcml2YXRlIFR5cGVJbmZvIGdldEF0dHJpYnV0ZVR5cGUoIGludCBpbmRleCApIHsKLSAgICAgICAgICAgIGNoZWNrU3RhdGUoZmFsc2UpOwotICAgICAgICAgICAgaWYoIGluZGV4PDAgfHwgZkF0dHJpYnV0ZXMuZ2V0TGVuZ3RoKCk8PWluZGV4ICkKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihJbnRlZ2VyLnRvU3RyaW5nKGluZGV4KSk7Ci0gICAgICAgICAgICBBdWdtZW50YXRpb25zIGF1Z3MgPSBmQXR0cmlidXRlcy5nZXRBdWdtZW50YXRpb25zKGluZGV4KTsKLSAgICAgICAgICAgIGlmIChhdWdzID09IG51bGwpIHJldHVybiBudWxsOwotICAgICAgICAgICAgQXR0cmlidXRlUFNWSSBwc3ZpID0gKEF0dHJpYnV0ZVBTVkkpYXVncy5nZXRJdGVtKENvbnN0YW50cy5BVFRSSUJVVEVfUFNWSSk7Ci0gICAgICAgICAgICByZXR1cm4gZ2V0VHlwZUluZm9Gcm9tUFNWSShwc3ZpKTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyBUeXBlSW5mbyBnZXRBdHRyaWJ1dGVUeXBlSW5mbyhTdHJpbmcgYXR0cmlidXRlVXJpLCBTdHJpbmcgYXR0cmlidXRlTG9jYWxOYW1lKSB7Ci0gICAgICAgICAgICBjaGVja1N0YXRlKGZhbHNlKTsKLSAgICAgICAgICAgIHJldHVybiBnZXRBdHRyaWJ1dGVUeXBlSW5mbyhmQXR0cmlidXRlcy5nZXRJbmRleChhdHRyaWJ1dGVVcmksYXR0cmlidXRlTG9jYWxOYW1lKSk7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgVHlwZUluZm8gZ2V0QXR0cmlidXRlVHlwZUluZm8oU3RyaW5nIGF0dHJpYnV0ZVFOYW1lKSB7Ci0gICAgICAgICAgICBjaGVja1N0YXRlKGZhbHNlKTsKLSAgICAgICAgICAgIHJldHVybiBnZXRBdHRyaWJ1dGVUeXBlSW5mbyhmQXR0cmlidXRlcy5nZXRJbmRleChhdHRyaWJ1dGVRTmFtZSkpOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIFR5cGVJbmZvIGdldEVsZW1lbnRUeXBlSW5mbygpIHsKLSAgICAgICAgICAgIGNoZWNrU3RhdGUodHJ1ZSk7Ci0gICAgICAgICAgICBpZiAoZkVsZW1lbnRBdWdzID09IG51bGwpIHJldHVybiBudWxsOwotICAgICAgICAgICAgRWxlbWVudFBTVkkgcHN2aSA9IChFbGVtZW50UFNWSSlmRWxlbWVudEF1Z3MuZ2V0SXRlbShDb25zdGFudHMuRUxFTUVOVF9QU1ZJKTsKLSAgICAgICAgICAgIHJldHVybiBnZXRUeXBlSW5mb0Zyb21QU1ZJKHBzdmkpOwotICAgICAgICB9Ci0KLSAgICAgICAgcHJpdmF0ZSBUeXBlSW5mbyBnZXRUeXBlSW5mb0Zyb21QU1ZJKCBJdGVtUFNWSSBwc3ZpICkgewotICAgICAgICAgICAgaWYocHN2aT09bnVsbCkgIHJldHVybiBudWxsOwotCi0gICAgICAgICAgICAvLyBUT0RPOiBtYWtlIHN1cmUgaWYgdGhpcyBpcyBjb3JyZWN0LgotICAgICAgICAgICAgLy8gVE9ETzogc2luY2UgdGhlIG51bWJlciBvZiB0eXBlcyBpbiBhIHNjaGVtYSBpcyBxdWl0ZSBsaW1pdGVkLAotICAgICAgICAgICAgLy8gVHlwZUluZm9JbXBsIHNob3VsZCBiZSBwb29sZWQuIEV2ZW4gYmV0dGVyLCBpdCBzaG91bGQgYmUgYSBwYXJ0Ci0gICAgICAgICAgICAvLyBvZiB0aGUgZWxlbWVudCBkZWNsLgotICAgICAgICAgICAgaWYoIHBzdmkuZ2V0VmFsaWRpdHkoKT09IEVsZW1lbnRQU1ZJLlZBTElESVRZX1ZBTElEICkgewotICAgICAgICAgICAgICAgIFhTVHlwZURlZmluaXRpb24gdCA9IHBzdmkuZ2V0TWVtYmVyVHlwZURlZmluaXRpb24oKTsKLSAgICAgICAgICAgICAgICBpZiAodCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiAodCBpbnN0YW5jZW9mIFR5cGVJbmZvKSA/IChUeXBlSW5mbykgdCA6IG51bGw7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBYU1R5cGVEZWZpbml0aW9uIHQgPSBwc3ZpLmdldFR5cGVEZWZpbml0aW9uKCk7Ci0gICAgICAgICAgICAvLyBUT0RPOiBjYW4gdCBiZSBudWxsPwotICAgICAgICAgICAgaWYgKHQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJldHVybiAodCBpbnN0YW5jZW9mIFR5cGVJbmZvKSA/IChUeXBlSW5mbykgdCA6IG51bGw7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyBib29sZWFuIGlzSWRBdHRyaWJ1dGUoaW50IGluZGV4KSB7Ci0gICAgICAgICAgICBjaGVja1N0YXRlKGZhbHNlKTsKLSAgICAgICAgICAgIFhTU2ltcGxlVHlwZSB0eXBlID0gKFhTU2ltcGxlVHlwZSlnZXRBdHRyaWJ1dGVUeXBlKGluZGV4KTsKLSAgICAgICAgICAgIGlmKHR5cGU9PW51bGwpICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICByZXR1cm4gdHlwZS5pc0lEVHlwZSgpOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIGJvb2xlYW4gaXNTcGVjaWZpZWQoaW50IGluZGV4KSB7Ci0gICAgICAgICAgICBjaGVja1N0YXRlKGZhbHNlKTsKLSAgICAgICAgICAgIHJldHVybiBmQXR0cmlidXRlcy5pc1NwZWNpZmllZChpbmRleCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvKgotICAgICAgICAgKiBPdGhlciBtZXRob2RzCi0gICAgICAgICAqLwotCi0gICAgICAgIC8vIFBTVklQcm92aWRlciBzdXBwb3J0Ci0gICAgICAgIEVsZW1lbnRQU1ZJIGdldEVsZW1lbnRQU1ZJKCkgewotICAgICAgICAgICAgcmV0dXJuIChmRWxlbWVudEF1Z3MgIT0gbnVsbCkgPyAoRWxlbWVudFBTVkkpIGZFbGVtZW50QXVncy5nZXRJdGVtKENvbnN0YW50cy5FTEVNRU5UX1BTVkkpIDogbnVsbDsKLSAgICAgICAgfQotCi0gICAgICAgIEF0dHJpYnV0ZVBTVkkgZ2V0QXR0cmlidXRlUFNWSShpbnQgaW5kZXgpIHsKLSAgICAgICAgICAgIGlmIChmQXR0cmlidXRlcyAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgQXVnbWVudGF0aW9ucyBhdWdzID0gZkF0dHJpYnV0ZXMuZ2V0QXVnbWVudGF0aW9ucyhpbmRleCk7Ci0gICAgICAgICAgICAgICAgaWYgKGF1Z3MgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gKEF0dHJpYnV0ZVBTVkkpIGF1Z3MuZ2V0SXRlbShDb25zdGFudHMuQVRUUklCVVRFX1BTVkkpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0KLSAgICAgICAgQXR0cmlidXRlUFNWSSBnZXRBdHRyaWJ1dGVQU1ZJQnlOYW1lKFN0cmluZyB1cmksIFN0cmluZyBsb2NhbG5hbWUpIHsKLSAgICAgICAgICAgIGlmIChmQXR0cmlidXRlcyAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgQXVnbWVudGF0aW9ucyBhdWdzID0gZkF0dHJpYnV0ZXMuZ2V0QXVnbWVudGF0aW9ucyh1cmksIGxvY2FsbmFtZSk7Ci0gICAgICAgICAgICAgICAgaWYgKGF1Z3MgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gKEF0dHJpYnV0ZVBTVkkpIGF1Z3MuZ2V0SXRlbShDb25zdGFudHMuQVRUUklCVVRFX1BTVkkpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqIFNBWCBhZGFwdGVyIGZvciBhbiBMU1Jlc291cmNlUmVzb2x2ZXIuICovCi0gICAgcHJpdmF0ZSBmaW5hbCBSZXNvbHV0aW9uRm9yd2FyZGVyIGZSZXNvbHV0aW9uRm9yd2FyZGVyID0gbmV3IFJlc29sdXRpb25Gb3J3YXJkZXIobnVsbCk7Ci0gICAgc3RhdGljIGZpbmFsIGNsYXNzIFJlc29sdXRpb25Gb3J3YXJkZXIKLSAgICAgICAgaW1wbGVtZW50cyBFbnRpdHlSZXNvbHZlcjIgewotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIERhdGEKLSAgICAgICAgLy8KLQotICAgICAgICAvKiogWE1MIDEuMCB0eXBlIGNvbnN0YW50IGFjY29yZGluZyB0byBET00gTDMgTFMgUkVDIHNwZWMgImh0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLURPTS1MZXZlbC0zLUxTLTIwMDQwNDA3LyIgKi8KLSAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFhNTF9UWVBFID0gImh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy14bWwiOwotCi0gICAgICAgIC8qKiBUaGUgRE9NIGVudGl0eSByZXNvbHZlci4gKi8KLSAgICAgICAgcHJvdGVjdGVkIExTUmVzb3VyY2VSZXNvbHZlciBmRW50aXR5UmVzb2x2ZXI7Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gQ29uc3RydWN0b3JzCi0gICAgICAgIC8vCi0KLSAgICAgICAgLyoqIERlZmF1bHQgY29uc3RydWN0b3IuICovCi0gICAgICAgIHB1YmxpYyBSZXNvbHV0aW9uRm9yd2FyZGVyKCkge30KLQotICAgICAgICAvKiogV3JhcHMgdGhlIHNwZWNpZmllZCBET00gZW50aXR5IHJlc29sdmVyLiAqLwotICAgICAgICBwdWJsaWMgUmVzb2x1dGlvbkZvcndhcmRlcihMU1Jlc291cmNlUmVzb2x2ZXIgZW50aXR5UmVzb2x2ZXIpIHsKLSAgICAgICAgICAgIHNldEVudGl0eVJlc29sdmVyKGVudGl0eVJlc29sdmVyKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIFB1YmxpYyBtZXRob2RzCi0gICAgICAgIC8vCi0KLSAgICAgICAgLyoqIFNldHMgdGhlIERPTSBlbnRpdHkgcmVzb2x2ZXIuICovCi0gICAgICAgIHB1YmxpYyB2b2lkIHNldEVudGl0eVJlc29sdmVyKExTUmVzb3VyY2VSZXNvbHZlciBlbnRpdHlSZXNvbHZlcikgewotICAgICAgICAgICAgZkVudGl0eVJlc29sdmVyID0gZW50aXR5UmVzb2x2ZXI7Ci0gICAgICAgIH0gLy8gc2V0RW50aXR5UmVzb2x2ZXIoTFNSZXNvdXJjZVJlc29sdmVyKQotCi0gICAgICAgIC8qKiBSZXR1cm5zIHRoZSBET00gZW50aXR5IHJlc29sdmVyLiAqLwotICAgICAgICBwdWJsaWMgTFNSZXNvdXJjZVJlc29sdmVyIGdldEVudGl0eVJlc29sdmVyKCkgewotICAgICAgICAgICAgcmV0dXJuIGZFbnRpdHlSZXNvbHZlcjsKLSAgICAgICAgfSAvLyBnZXRFbnRpdHlSZXNvbHZlcigpOkxTUmVzb3VyY2VSZXNvbHZlcgotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBBbHdheXMgcmV0dXJucyA8Y29kZT5udWxsPC9jb2RlPi4gQW4gTFNSZXNvdXJjZVJlc29sdmVyIGhhcyBubyBjb3JyZXNwb25kaW5nIG1ldGhvZC4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBJbnB1dFNvdXJjZSBnZXRFeHRlcm5hbFN1YnNldChTdHJpbmcgbmFtZSwgU3RyaW5nIGJhc2VVUkkpCi0gICAgICAgICAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogUmVzb2x2ZXMgdGhlIGdpdmVuIHJlc291cmNlIGFuZCBhZGFwdHMgdGhlIDxjb2RlPkxTSW5wdXQ8L2NvZGU+Ci0gICAgICAgICAqIHJldHVybmVkIGludG8gYW4gPGNvZGU+SW5wdXRTb3VyY2U8L2NvZGU+LgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIElucHV0U291cmNlIHJlc29sdmVFbnRpdHkoU3RyaW5nIG5hbWUsIFN0cmluZyBwdWJsaWNJZCwKLSAgICAgICAgICAgICAgICBTdHJpbmcgYmFzZVVSSSwgU3RyaW5nIHN5c3RlbUlkKSB0aHJvd3MgU0FYRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgICAgICBpZiAoZkVudGl0eVJlc29sdmVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBMU0lucHV0IGxzSW5wdXQgPSBmRW50aXR5UmVzb2x2ZXIucmVzb2x2ZVJlc291cmNlKFhNTF9UWVBFLCBudWxsLCBwdWJsaWNJZCwgc3lzdGVtSWQsIGJhc2VVUkkpOwotICAgICAgICAgICAgICAgIGlmIChsc0lucHV0ICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIHB1YklkID0gbHNJbnB1dC5nZXRQdWJsaWNJZCgpOwotICAgICAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgc3lzSWQgPSBsc0lucHV0LmdldFN5c3RlbUlkKCk7Ci0gICAgICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBiYXNlU3lzdGVtSWQgPSBsc0lucHV0LmdldEJhc2VVUkkoKTsKLSAgICAgICAgICAgICAgICAgICAgZmluYWwgUmVhZGVyIGNoYXJTdHJlYW0gPSBsc0lucHV0LmdldENoYXJhY3RlclN0cmVhbSgpOwotICAgICAgICAgICAgICAgICAgICBmaW5hbCBJbnB1dFN0cmVhbSBieXRlU3RyZWFtID0gbHNJbnB1dC5nZXRCeXRlU3RyZWFtKCk7Ci0gICAgICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBkYXRhID0gbHNJbnB1dC5nZXRTdHJpbmdEYXRhKCk7Ci0gICAgICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBlbmNvZGluZyA9IGxzSW5wdXQuZ2V0RW5jb2RpbmcoKTsKLQotICAgICAgICAgICAgICAgICAgICAvKioKLSAgICAgICAgICAgICAgICAgICAgICogQW4gTFNQYXJzZXIgbG9va3MgYXQgaW5wdXRzIHNwZWNpZmllZCBpbiBMU0lucHV0IGluCi0gICAgICAgICAgICAgICAgICAgICAqIHRoZSBmb2xsb3dpbmcgb3JkZXI6IGNoYXJhY3RlclN0cmVhbSwgYnl0ZVN0cmVhbSwKLSAgICAgICAgICAgICAgICAgICAgICogc3RyaW5nRGF0YSwgc3lzdGVtSWQsIHB1YmxpY0lkLiBGb3IgY29uc2lzdGVuY3kKLSAgICAgICAgICAgICAgICAgICAgICogd2l0aCB0aGUgRE9NIExldmVsIDMgTG9hZCBhbmQgU2F2ZSBSZWNvbW1lbmRhdGlvbgotICAgICAgICAgICAgICAgICAgICAgKiB1c2UgdGhlIHNhbWUgbG9va3VwIG9yZGVyIGhlcmUuCi0gICAgICAgICAgICAgICAgICAgICAqLwotICAgICAgICAgICAgICAgICAgICBJbnB1dFNvdXJjZSBpbnB1dFNvdXJjZSA9IG5ldyBJbnB1dFNvdXJjZSgpOwotICAgICAgICAgICAgICAgICAgICBpbnB1dFNvdXJjZS5zZXRQdWJsaWNJZChwdWJJZCk7Ci0gICAgICAgICAgICAgICAgICAgIGlucHV0U291cmNlLnNldFN5c3RlbUlkKChiYXNlU3lzdGVtSWQgIT0gbnVsbCkgPyByZXNvbHZlU3lzdGVtSWQoc3lzdGVtSWQsIGJhc2VTeXN0ZW1JZCkgOiBzeXN0ZW1JZCk7Ci0KLSAgICAgICAgICAgICAgICAgICAgaWYgKGNoYXJTdHJlYW0gIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXRTb3VyY2Uuc2V0Q2hhcmFjdGVyU3RyZWFtKGNoYXJTdHJlYW0pOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGJ5dGVTdHJlYW0gIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXRTb3VyY2Uuc2V0Qnl0ZVN0cmVhbShieXRlU3RyZWFtKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChkYXRhICE9IG51bGwgJiYgZGF0YS5sZW5ndGgoKSAhPSAwKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpbnB1dFNvdXJjZS5zZXRDaGFyYWN0ZXJTdHJlYW0obmV3IFN0cmluZ1JlYWRlcihkYXRhKSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgaW5wdXRTb3VyY2Uuc2V0RW5jb2RpbmcoZW5jb2RpbmcpOwotICAgICAgICAgICAgICAgICAgICByZXR1cm4gaW5wdXRTb3VyY2U7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLQotICAgICAgICAvKiogRGVsZWdhdGVzIHRvIEVudGl0eVJlc29sdmVyMi5yZXNvbHZlRW50aXR5KFN0cmluZywgU3RyaW5nLCBTdHJpbmcsIFN0cmluZykuICovCi0gICAgICAgIHB1YmxpYyBJbnB1dFNvdXJjZSByZXNvbHZlRW50aXR5KFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkKQotICAgICAgICAgICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKLSAgICAgICAgICAgIHJldHVybiByZXNvbHZlRW50aXR5KG51bGwsIHB1YmxpY0lkLCBudWxsLCBzeXN0ZW1JZCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvKiogUmVzb2x2ZXMgYSBzeXN0ZW0gaWRlbnRpZmllciBhZ2FpbnN0IGEgYmFzZSBVUkkuICovCi0gICAgICAgIHByaXZhdGUgU3RyaW5nIHJlc29sdmVTeXN0ZW1JZChTdHJpbmcgc3lzdGVtSWQsIFN0cmluZyBiYXNlVVJJKSB7Ci0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIHJldHVybiBYTUxFbnRpdHlNYW5hZ2VyLmV4cGFuZFN5c3RlbUlkKHN5c3RlbUlkLCBiYXNlVVJJLCBmYWxzZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyBJbiB0aGUgZXZlbnQgdGhhdCByZXNvbHV0aW9uIGZhaWxlZCBhZ2FpbnN0IHRoZQotICAgICAgICAgICAgLy8gYmFzZSBVUkksIGp1c3QgcmV0dXJuIHRoZSBzeXN0ZW0gaWQgYXMgaXMuIFRoZXJlJ3Mgbm90Ci0gICAgICAgICAgICAvLyBtdWNoIGVsc2Ugd2UgY2FuIGRvLgotICAgICAgICAgICAgY2F0Y2ggKFVSSS5NYWxmb3JtZWRVUklFeGNlcHRpb24gZXgpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gc3lzdGVtSWQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9qYXhwL3ZhbGlkYXRpb24vVmFsaWRhdG9ySGVscGVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9qYXhwL3ZhbGlkYXRpb24vVmFsaWRhdG9ySGVscGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGFhYzNjNmQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvamF4cC92YWxpZGF0aW9uL1ZhbGlkYXRvckhlbHBlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDAgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5qYXhwLnZhbGlkYXRpb247Ci0KLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5SZXN1bHQ7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2U7Ci0KLWltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci0KLS8qKgotICogPHA+SW5zdGFuY2VzIG9mIFZhbGlkYXRvckhlbHBlciBhcmUgYWJsZSB0byB2YWxpZGF0ZQotICogc3BlY2lmaWMgc291cmNlIGFuZCByZXN1bHQgdHlwZXMuPC9wPgotICoKLSAqIEBhdXRob3IgTWljaGFlbCBHbGF2YXNzZXZpY2gsIElCTQotICovCi1pbnRlcmZhY2UgVmFsaWRhdG9ySGVscGVyIHsKLQotICAgIHB1YmxpYyB2b2lkIHZhbGlkYXRlKFNvdXJjZSBzb3VyY2UsIFJlc3VsdCByZXN1bHQpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24sIElPRXhjZXB0aW9uOwotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvamF4cC92YWxpZGF0aW9uL1ZhbGlkYXRvckltcGwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2pheHAvdmFsaWRhdGlvbi9WYWxpZGF0b3JJbXBsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGYwZDE4ZGQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvamF4cC92YWxpZGF0aW9uL1ZhbGlkYXRvckltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI4MSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmpheHAudmFsaWRhdGlvbjsKLQotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci0KLWltcG9ydCBqYXZheC54bWwuWE1MQ29uc3RhbnRzOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uUmVzdWx0OwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uU291cmNlOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uZG9tLkRPTVNvdXJjZTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnNheC5TQVhTb3VyY2U7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zdGF4LlN0QVhSZXN1bHQ7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zdGF4LlN0QVhTb3VyY2U7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zdHJlYW0uU3RyZWFtU291cmNlOwotaW1wb3J0IGphdmF4LnhtbC52YWxpZGF0aW9uLlZhbGlkYXRvcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5Db25zdGFudHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlNBWE1lc3NhZ2VGb3JtYXR0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlN0YXR1czsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLkF0dHJpYnV0ZVBTVkk7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5FbGVtZW50UFNWSTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlBTVklQcm92aWRlcjsKLWltcG9ydCBvcmcudzNjLmRvbS5scy5MU1Jlc291cmNlUmVzb2x2ZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguRXJyb3JIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbjsKLQotLyoqCi0gKiA8cD5JbXBsZW1lbnRhdGlvbiBvZiBWYWxpZGF0b3IgZm9yIFczQyBYTUwgU2NoZW1hcy48L3A+Ci0gKgotICogQGF1dGhvciA8YSBocmVmPSJtYWlsdG86S29oc3VrZS5LYXdhZ3VjaGlAU3VuLmNvbSI+S29oc3VrZSBLYXdhZ3VjaGk8L2E+Ci0gKiBAYXV0aG9yIE1pY2hhZWwgR2xhdmFzc2V2aWNoLCBJQk0KLSAqIEBhdXRob3IgPGEgaHJlZj0ibWFpbHRvOlN1bml0aGEuUmVkZHlAU3VuLmNvbSI+U3VuaXRoYSBSZWRkeTwvYT4KLSAqIEB2ZXJzaW9uICRJZDogVmFsaWRhdG9ySW1wbC5qYXZhLHYgMS4xMCAyMDEwLTExLTAxIDA0OjQwOjA4IGpvZWh3IEV4cCAkCi0gKi8KLWZpbmFsIGNsYXNzIFZhbGlkYXRvckltcGwgZXh0ZW5kcyBWYWxpZGF0b3IgaW1wbGVtZW50cyBQU1ZJUHJvdmlkZXIgewotCi0gICAgLy8KLSAgICAvLyBEYXRhCi0gICAgLy8KLQotICAgIC8qKiBDb21wb25lbnQgbWFuYWdlci4gKiovCi0gICAgcHJpdmF0ZSBYTUxTY2hlbWFWYWxpZGF0b3JDb21wb25lbnRNYW5hZ2VyIGZDb21wb25lbnRNYW5hZ2VyOwotCi0gICAgLyoqIFNBWCB2YWxpZGF0b3IgaGVscGVyLiAqKi8KLSAgICBwcml2YXRlIFZhbGlkYXRvckhhbmRsZXJJbXBsIGZTQVhWYWxpZGF0b3JIZWxwZXI7Ci0KLSAgICAvKiogRE9NIHZhbGlkYXRvciBoZWxwZXIuICoqLwotICAgIHByaXZhdGUgRE9NVmFsaWRhdG9ySGVscGVyIGZET01WYWxpZGF0b3JIZWxwZXI7Ci0KLSAgICAvKiogU3RyZWFtIHZhbGlkYXRvciBoZWxwZXIuICoqLwotICAgIHByaXZhdGUgU3RyZWFtVmFsaWRhdG9ySGVscGVyIGZTdHJlYW1WYWxpZGF0b3JIZWxwZXI7Ci0KLSAgICAvKiogU3RBWCB2YWxpZGF0b3IgaGVscGVyLiAqKi8KLSAgICBwcml2YXRlIFN0QVhWYWxpZGF0b3JIZWxwZXIgZlN0YXhWYWxpZGF0b3JIZWxwZXI7Ci0KLSAgICAvKiogRmxhZyBmb3IgdHJhY2tpbmcgd2hldGhlciBmZWF0dXJlcy9wcm9wZXJ0aWVzIGNoYW5nZWQgc2luY2UgbGFzdCByZXNldC4gKi8KLSAgICBwcml2YXRlIGJvb2xlYW4gZkNvbmZpZ3VyYXRpb25DaGFuZ2VkID0gZmFsc2U7Ci0KLSAgICAvKiogRmxhZyBmb3IgdHJhY2tpbmcgd2hldGhlciB0aGUgZXJyb3IgaGFuZGxlciBjaGFuZ2VkIHNpbmNlIGxhc3QgcmVzZXQuICovCi0gICAgcHJpdmF0ZSBib29sZWFuIGZFcnJvckhhbmRsZXJDaGFuZ2VkID0gZmFsc2U7Ci0KLSAgICAvKiogRmxhZyBmb3IgdHJhY2tpbmcgd2hldGhlciB0aGUgcmVzb3VyY2UgcmVzb2x2ZXIgY2hhbmdlZCBzaW5jZSBsYXN0IHJlc2V0LiAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBmUmVzb3VyY2VSZXNvbHZlckNoYW5nZWQgPSBmYWxzZTsKLQotICAgIC8qKiBTdXBwb3J0IGN1cnJlbnQtZWxlbWVudC1ub2RlIHByb3BlcnR5ICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIENVUlJFTlRfRUxFTUVOVF9OT0RFID0gQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuQ1VSUkVOVF9FTEVNRU5UX05PREVfUFJPUEVSVFk7Ci0KLSAgICBwdWJsaWMgVmFsaWRhdG9ySW1wbChYU0dyYW1tYXJQb29sQ29udGFpbmVyIGdyYW1tYXJDb250YWluZXIpIHsKLSAgICAgICAgZkNvbXBvbmVudE1hbmFnZXIgPSBuZXcgWE1MU2NoZW1hVmFsaWRhdG9yQ29tcG9uZW50TWFuYWdlcihncmFtbWFyQ29udGFpbmVyKTsKLSAgICAgICAgc2V0RXJyb3JIYW5kbGVyKG51bGwpOwotICAgICAgICBzZXRSZXNvdXJjZVJlc29sdmVyKG51bGwpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHZhbGlkYXRlKFNvdXJjZSBzb3VyY2UsIFJlc3VsdCByZXN1bHQpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKHNvdXJjZSBpbnN0YW5jZW9mIFNBWFNvdXJjZSkgewotICAgICAgICAgICAgLy8gSGFuZCBvZmYgdG8gU0FYIHZhbGlkYXRvciBoZWxwZXIuCi0gICAgICAgICAgICBpZiAoZlNBWFZhbGlkYXRvckhlbHBlciA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZlNBWFZhbGlkYXRvckhlbHBlciA9IG5ldyBWYWxpZGF0b3JIYW5kbGVySW1wbChmQ29tcG9uZW50TWFuYWdlcik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmU0FYVmFsaWRhdG9ySGVscGVyLnZhbGlkYXRlKHNvdXJjZSwgcmVzdWx0KTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChzb3VyY2UgaW5zdGFuY2VvZiBET01Tb3VyY2UpIHsKLSAgICAgICAgICAgIC8vIEhhbmQgb2ZmIHRvIERPTSB2YWxpZGF0b3IgaGVscGVyLgotICAgICAgICAgICAgaWYgKGZET01WYWxpZGF0b3JIZWxwZXIgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZET01WYWxpZGF0b3JIZWxwZXIgPSBuZXcgRE9NVmFsaWRhdG9ySGVscGVyKGZDb21wb25lbnRNYW5hZ2VyKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGZET01WYWxpZGF0b3JIZWxwZXIudmFsaWRhdGUoc291cmNlLCByZXN1bHQpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKHNvdXJjZSBpbnN0YW5jZW9mIFN0cmVhbVNvdXJjZSkgewotICAgICAgICAgICAgLy8gSGFuZCBvZmYgdG8gc3RyZWFtIHZhbGlkYXRvciBoZWxwZXIuCi0gICAgICAgICAgICBpZiAoZlN0cmVhbVZhbGlkYXRvckhlbHBlciA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZlN0cmVhbVZhbGlkYXRvckhlbHBlciA9IG5ldyBTdHJlYW1WYWxpZGF0b3JIZWxwZXIoZkNvbXBvbmVudE1hbmFnZXIpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZlN0cmVhbVZhbGlkYXRvckhlbHBlci52YWxpZGF0ZShzb3VyY2UsIHJlc3VsdCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoc291cmNlIGluc3RhbmNlb2YgU3RBWFNvdXJjZSkgewotICAgICAgICAgICAgLy8gSGFuZCBvZmYgdG8gc3RheCB2YWxpZGF0b3IgaGVscGVyLgotICAgICAgICAgICAgaWYgKGZTdGF4VmFsaWRhdG9ySGVscGVyID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmU3RheFZhbGlkYXRvckhlbHBlciA9IG5ldyBTdEFYVmFsaWRhdG9ySGVscGVyKGZDb21wb25lbnRNYW5hZ2VyKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGZTdGF4VmFsaWRhdG9ySGVscGVyLnZhbGlkYXRlKHNvdXJjZSwgcmVzdWx0KTsKLSAgICAgICAgfQotICAgICAgICAvLyBTb3VyY2UgcGFyYW1ldGVyIGNhbm5vdCBiZSBudWxsLgotICAgICAgICBlbHNlIGlmIChzb3VyY2UgPT0gbnVsbCkgewotICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKEpBWFBWYWxpZGF0aW9uTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKGZDb21wb25lbnRNYW5hZ2VyLmdldExvY2FsZSgpLAotICAgICAgICAgICAgICAgICAgICAiU291cmNlUGFyYW1ldGVyTnVsbCIsIG51bGwpKTsKLSAgICAgICAgfQotICAgICAgICAvLyBTb3VyY2UgcGFyYW1ldGVyIG11c3QgYmUgYSBTQVhTb3VyY2UsIERPTVNvdXJjZSBvciBTdHJlYW1Tb3VyY2UKLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKEpBWFBWYWxpZGF0aW9uTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKGZDb21wb25lbnRNYW5hZ2VyLmdldExvY2FsZSgpLAotICAgICAgICAgICAgICAgICAgICAiU291cmNlTm90QWNjZXB0ZWQiLCBuZXcgT2JqZWN0IFtdIHtzb3VyY2UuZ2V0Q2xhc3MoKS5nZXROYW1lKCl9KSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRFcnJvckhhbmRsZXIoRXJyb3JIYW5kbGVyIGVycm9ySGFuZGxlcikgewotICAgICAgICBmRXJyb3JIYW5kbGVyQ2hhbmdlZCA9IChlcnJvckhhbmRsZXIgIT0gbnVsbCk7Ci0gICAgICAgIGZDb21wb25lbnRNYW5hZ2VyLnNldEVycm9ySGFuZGxlcihlcnJvckhhbmRsZXIpOwotICAgIH0KLQotICAgIHB1YmxpYyBFcnJvckhhbmRsZXIgZ2V0RXJyb3JIYW5kbGVyKCkgewotICAgICAgICByZXR1cm4gZkNvbXBvbmVudE1hbmFnZXIuZ2V0RXJyb3JIYW5kbGVyKCk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0UmVzb3VyY2VSZXNvbHZlcihMU1Jlc291cmNlUmVzb2x2ZXIgcmVzb3VyY2VSZXNvbHZlcikgewotICAgICAgICBmUmVzb3VyY2VSZXNvbHZlckNoYW5nZWQgPSAocmVzb3VyY2VSZXNvbHZlciAhPSBudWxsKTsKLSAgICAgICAgZkNvbXBvbmVudE1hbmFnZXIuc2V0UmVzb3VyY2VSZXNvbHZlcihyZXNvdXJjZVJlc29sdmVyKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgTFNSZXNvdXJjZVJlc29sdmVyIGdldFJlc291cmNlUmVzb2x2ZXIoKSB7Ci0gICAgICAgIHJldHVybiBmQ29tcG9uZW50TWFuYWdlci5nZXRSZXNvdXJjZVJlc29sdmVyKCk7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0RmVhdHVyZShTdHJpbmcgbmFtZSkKLSAgICAgICAgdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChuYW1lID09IG51bGwpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwotICAgICAgICB9Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICByZXR1cm4gZkNvbXBvbmVudE1hbmFnZXIuZ2V0RmVhdHVyZShuYW1lKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICBmaW5hbCBTdHJpbmcgaWRlbnRpZmllciA9IGUuZ2V0SWRlbnRpZmllcigpOwotICAgICAgICAgICAgZmluYWwgU3RyaW5nIGtleSA9IGUuZ2V0VHlwZSgpID09IFN0YXR1cy5OT1RfUkVDT0dOSVpFRCA/Ci0gICAgICAgICAgICAgICAgICAgICJmZWF0dXJlLW5vdC1yZWNvZ25pemVkIiA6ICJmZWF0dXJlLW5vdC1zdXBwb3J0ZWQiOwotICAgICAgICAgICAgdGhyb3cgbmV3IFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgIFNBWE1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShmQ29tcG9uZW50TWFuYWdlci5nZXRMb2NhbGUoKSwKLSAgICAgICAgICAgICAgICAgICAga2V5LCBuZXcgT2JqZWN0IFtdIHtpZGVudGlmaWVyfSkpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0RmVhdHVyZShTdHJpbmcgbmFtZSwgYm9vbGVhbiB2YWx1ZSkKLSAgICAgICAgdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChuYW1lID09IG51bGwpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwotICAgICAgICB9Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBmQ29tcG9uZW50TWFuYWdlci5zZXRGZWF0dXJlKG5hbWUsIHZhbHVlKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICBmaW5hbCBTdHJpbmcgaWRlbnRpZmllciA9IGUuZ2V0SWRlbnRpZmllcigpOwotICAgICAgICAgICAgZmluYWwgU3RyaW5nIGtleTsKLSAgICAgICAgICAgIGlmIChlLmdldFR5cGUoKSA9PSBTdGF0dXMuTk9UX0FMTE9XRUQpIHsKLSAgICAgICAgICAgICAgICAvL2ZvciBub3csIHRoZSBpZGVudGlmaWVyIGNhbiBvbmx5IGJlIChYTUxDb25zdGFudHMuRkVBVFVSRV9TRUNVUkVfUFJPQ0VTU0lORykKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICBTQVhNZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoZkNvbXBvbmVudE1hbmFnZXIuZ2V0TG9jYWxlKCksCi0gICAgICAgICAgICAgICAgICAgICJqYXhwLXNlY3VyZXByb2Nlc3NpbmctZmVhdHVyZSIsIG51bGwpKTsKLSAgICAgICAgICAgIH0gZWxzZSBpZiAoZS5nZXRUeXBlKCkgPT0gU3RhdHVzLk5PVF9SRUNPR05JWkVEKSB7Ci0gICAgICAgICAgICAgICAga2V5ID0gImZlYXR1cmUtbm90LXJlY29nbml6ZWQiOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBrZXkgPSAiZmVhdHVyZS1ub3Qtc3VwcG9ydGVkIjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHRocm93IG5ldyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICBTQVhNZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoZkNvbXBvbmVudE1hbmFnZXIuZ2V0TG9jYWxlKCksCi0gICAgICAgICAgICAgICAgICAgIGtleSwgbmV3IE9iamVjdCBbXSB7aWRlbnRpZmllcn0pKTsKLSAgICAgICAgfQotICAgICAgICBmQ29uZmlndXJhdGlvbkNoYW5nZWQgPSB0cnVlOwotICAgIH0KLQotICAgIHB1YmxpYyBPYmplY3QgZ2V0UHJvcGVydHkoU3RyaW5nIG5hbWUpCi0gICAgICAgIHRocm93cyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uLCBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gewotICAgICAgICBpZiAobmFtZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKLSAgICAgICAgfQotICAgICAgICAvL1N1cHBvcnQgY3VycmVudC1lbGVtZW50LW5vZGU7IHJldHVybiBjdXJyZW50IG5vZGUgaWYgRE9NU291cmNlIGlzIHVzZWQuCi0gICAgICAgIGlmIChDVVJSRU5UX0VMRU1FTlRfTk9ERS5lcXVhbHMobmFtZSkpIHsKLSAgICAgICAgICAgIHJldHVybiAoZkRPTVZhbGlkYXRvckhlbHBlciAhPSBudWxsKSA/IGZET01WYWxpZGF0b3JIZWxwZXIuZ2V0Q3VycmVudEVsZW1lbnQoKSA6IG51bGw7Ci0gICAgICAgIH0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIHJldHVybiBmQ29tcG9uZW50TWFuYWdlci5nZXRQcm9wZXJ0eShuYW1lKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICBmaW5hbCBTdHJpbmcgaWRlbnRpZmllciA9IGUuZ2V0SWRlbnRpZmllcigpOwotICAgICAgICAgICAgZmluYWwgU3RyaW5nIGtleSA9IGUuZ2V0VHlwZSgpID09IFN0YXR1cy5OT1RfUkVDT0dOSVpFRCA/Ci0gICAgICAgICAgICAgICAgICAgICJwcm9wZXJ0eS1ub3QtcmVjb2duaXplZCIgOiAicHJvcGVydHktbm90LXN1cHBvcnRlZCI7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgU0FYTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKGZDb21wb25lbnRNYW5hZ2VyLmdldExvY2FsZSgpLAotICAgICAgICAgICAgICAgICAgICBrZXksIG5ldyBPYmplY3QgW10ge2lkZW50aWZpZXJ9KSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRQcm9wZXJ0eShTdHJpbmcgbmFtZSwgT2JqZWN0IG9iamVjdCkKLSAgICAgICAgdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChuYW1lID09IG51bGwpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwotICAgICAgICB9Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBmQ29tcG9uZW50TWFuYWdlci5zZXRQcm9wZXJ0eShuYW1lLCBvYmplY3QpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIGZpbmFsIFN0cmluZyBpZGVudGlmaWVyID0gZS5nZXRJZGVudGlmaWVyKCk7Ci0gICAgICAgICAgICBmaW5hbCBTdHJpbmcga2V5ID0gZS5nZXRUeXBlKCkgPT0gU3RhdHVzLk5PVF9SRUNPR05JWkVEID8KLSAgICAgICAgICAgICAgICAgICAgInByb3BlcnR5LW5vdC1yZWNvZ25pemVkIiA6ICJwcm9wZXJ0eS1ub3Qtc3VwcG9ydGVkIjsKLSAgICAgICAgICAgIHRocm93IG5ldyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICBTQVhNZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoZkNvbXBvbmVudE1hbmFnZXIuZ2V0TG9jYWxlKCksCi0gICAgICAgICAgICAgICAgICAgIGtleSwgbmV3IE9iamVjdCBbXSB7aWRlbnRpZmllcn0pKTsKLSAgICAgICAgfQotICAgICAgICBmQ29uZmlndXJhdGlvbkNoYW5nZWQgPSB0cnVlOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHJlc2V0KCkgewotICAgICAgICAvLyBhdm9pZCByZXNldHRpbmcgZmVhdHVyZXMgYW5kIHByb3BlcnRpZXMgaWYgdGhlIHN0YXRlIHRoZSB2YWxpZGF0b3IKLSAgICAgICAgLy8gaXMgY3VycmVudGx5IGluLCBpcyB0aGUgc2FtZSBhcyBpdCB3aWxsIGJlIGFmdGVyIHJlc2V0LgotICAgICAgICBpZiAoZkNvbmZpZ3VyYXRpb25DaGFuZ2VkKSB7Ci0gICAgICAgICAgICBmQ29tcG9uZW50TWFuYWdlci5yZXN0b3JlSW5pdGlhbFN0YXRlKCk7Ci0gICAgICAgICAgICBzZXRFcnJvckhhbmRsZXIobnVsbCk7Ci0gICAgICAgICAgICBzZXRSZXNvdXJjZVJlc29sdmVyKG51bGwpOwotICAgICAgICAgICAgZkNvbmZpZ3VyYXRpb25DaGFuZ2VkID0gZmFsc2U7Ci0gICAgICAgICAgICBmRXJyb3JIYW5kbGVyQ2hhbmdlZCA9IGZhbHNlOwotICAgICAgICAgICAgZlJlc291cmNlUmVzb2x2ZXJDaGFuZ2VkID0gZmFsc2U7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBpZiAoZkVycm9ySGFuZGxlckNoYW5nZWQpIHsKLSAgICAgICAgICAgICAgICBzZXRFcnJvckhhbmRsZXIobnVsbCk7Ci0gICAgICAgICAgICAgICAgZkVycm9ySGFuZGxlckNoYW5nZWQgPSBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChmUmVzb3VyY2VSZXNvbHZlckNoYW5nZWQpIHsKLSAgICAgICAgICAgICAgICBzZXRSZXNvdXJjZVJlc29sdmVyKG51bGwpOwotICAgICAgICAgICAgICAgIGZSZXNvdXJjZVJlc29sdmVyQ2hhbmdlZCA9IGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoKLSAgICAgKiBQU1ZJUHJvdmlkZXIgbWV0aG9kcwotICAgICAqLwotCi0gICAgcHVibGljIEVsZW1lbnRQU1ZJIGdldEVsZW1lbnRQU1ZJKCkgewotICAgICAgICByZXR1cm4gKGZTQVhWYWxpZGF0b3JIZWxwZXIgIT0gbnVsbCkgPyBmU0FYVmFsaWRhdG9ySGVscGVyLmdldEVsZW1lbnRQU1ZJKCkgOiBudWxsOwotICAgIH0KLQotICAgIHB1YmxpYyBBdHRyaWJ1dGVQU1ZJIGdldEF0dHJpYnV0ZVBTVkkoaW50IGluZGV4KSB7Ci0gICAgICAgIHJldHVybiAoZlNBWFZhbGlkYXRvckhlbHBlciAhPSBudWxsKSA/IGZTQVhWYWxpZGF0b3JIZWxwZXIuZ2V0QXR0cmlidXRlUFNWSShpbmRleCkgOiBudWxsOwotICAgIH0KLQotICAgIHB1YmxpYyBBdHRyaWJ1dGVQU1ZJIGdldEF0dHJpYnV0ZVBTVklCeU5hbWUoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsbmFtZSkgewotICAgICAgICByZXR1cm4gKGZTQVhWYWxpZGF0b3JIZWxwZXIgIT0gbnVsbCkgPyBmU0FYVmFsaWRhdG9ySGVscGVyLmdldEF0dHJpYnV0ZVBTVklCeU5hbWUodXJpLCBsb2NhbG5hbWUpIDogbnVsbDsKLSAgICB9Ci0KLX0gLy8gVmFsaWRhdG9ySW1wbApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvamF4cC92YWxpZGF0aW9uL1dlYWtSZWZlcmVuY2VYTUxTY2hlbWEuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2pheHAvdmFsaWRhdGlvbi9XZWFrUmVmZXJlbmNlWE1MU2NoZW1hLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDgzOTljOWYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvamF4cC92YWxpZGF0aW9uL1dlYWtSZWZlcmVuY2VYTUxTY2hlbWEuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDYyICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuamF4cC52YWxpZGF0aW9uOwotCi1pbXBvcnQgamF2YS5sYW5nLnJlZi5XZWFrUmVmZXJlbmNlOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuZ3JhbW1hcnMuWE1MR3JhbW1hclBvb2w7Ci0KLS8qKgotICogPHA+QW4gaW1wbGVtZW50YXRpb24gb2YgU2NoZW1hIGZvciBXM0MgWE1MIFNjaGVtYXMKLSAqIHRoYXQga2VlcHMgYSB3ZWFrIHJlZmVyZW5jZSB0byBpdHMgZ3JhbW1hciBwb29sLiBJZgotICogbm8gdmFsaWRhdG9ycyBjdXJyZW50bHkgaGF2ZSBhIHJlZmVyZW5jZSB0byB0aGUKLSAqIGdyYW1tYXIgcG9vbCwgdGhlIGdhcmJhZ2UgY29sbGVjdG9yIGlzIGZyZWUgdG8gcmVjbGFpbQotICogaXRzIG1lbW9yeS48L3A+Ci0gKgotICogQGF1dGhvciBNaWNoYWVsIEdsYXZhc3NldmljaCwgSUJNCi0gKi8KLWZpbmFsIGNsYXNzIFdlYWtSZWZlcmVuY2VYTUxTY2hlbWEgZXh0ZW5kcyBBYnN0cmFjdFhNTFNjaGVtYSB7Ci0KLSAgICAvKiogV2VhayByZWZlcmVuY2UgdG8gZ3JhbW1hciBwb29sLiAqLwotICAgIHByaXZhdGUgV2Vha1JlZmVyZW5jZSBmR3JhbW1hclBvb2wgPSBuZXcgV2Vha1JlZmVyZW5jZShudWxsKTsKLQotICAgIHB1YmxpYyBXZWFrUmVmZXJlbmNlWE1MU2NoZW1hKCkge30KLQotICAgIC8qCi0gICAgICogWFNHcmFtbWFyUG9vbENvbnRhaW5lciBtZXRob2RzCi0gICAgICovCi0KLSAgICBwdWJsaWMgc3luY2hyb25pemVkIFhNTEdyYW1tYXJQb29sIGdldEdyYW1tYXJQb29sKCkgewotICAgICAgICBYTUxHcmFtbWFyUG9vbCBncmFtbWFyUG9vbCA9IChYTUxHcmFtbWFyUG9vbCkgZkdyYW1tYXJQb29sLmdldCgpOwotICAgICAgICAvLyBJZiB0aGVyZSdzIG5vIGdyYW1tYXIgcG9vbCB0aGVuIGVpdGhlciB3ZSBoYXZlbid0IGNyZWF0ZWQgb25lCi0gICAgICAgIC8vIHlldCBvciB0aGUgZ2FyYmFnZSBjb2xsZWN0b3IgaGFzIGFscmVhZHkgY2xlYW5lZCBvdXQgdGhlIHByZXZpb3VzIG9uZS4KLSAgICAgICAgaWYgKGdyYW1tYXJQb29sID09IG51bGwpIHsKLSAgICAgICAgICAgIGdyYW1tYXJQb29sID0gbmV3IFNvZnRSZWZlcmVuY2VHcmFtbWFyUG9vbCgpOwotICAgICAgICAgICAgZkdyYW1tYXJQb29sID0gbmV3IFdlYWtSZWZlcmVuY2UoZ3JhbW1hclBvb2wpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBncmFtbWFyUG9vbDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0Z1bGx5Q29tcG9zZWQoKSB7Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLX0gLy8gV2Vha1JlZmVyZW5jZVhNTFNjaGVtYQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvamF4cC92YWxpZGF0aW9uL1dyYXBwZWRTQVhFeGNlcHRpb24uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2pheHAvdmFsaWRhdGlvbi9XcmFwcGVkU0FYRXhjZXB0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDEwNjExN2MuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvamF4cC92YWxpZGF0aW9uL1dyYXBwZWRTQVhFeGNlcHRpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDg3ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDAtMjAwMiBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhlcmNlcyIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgSW50ZXJuYXRpb25hbAotICogQnVzaW5lc3MgTWFjaGluZXMsIEluYy4sIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmpheHAudmFsaWRhdGlvbjsKLQotaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKLQotLyoqCi0gKiBXcmFwcyB7QGxpbmsgU0FYRXhjZXB0aW9ufSBhbmQgbWFrZSBpdCBhbiB1bmNoZWNrZWQgZXhjZXB0aW9uLgotICogPHA+Ci0gKiBYZXJjZXMgWE5JIGRvZXNuJ3QgYWxsb3cge0BsaW5rIFNBWEV4Y2VwdGlvbn0gdG8gYmUgdGhyb3duLgotICogU28gd2hlbiB0aGUgdXNlci1zdXBwbGllZCBlcnJvciBoYW5kbGVyIHRocm93cyBpdCwKLSAqIGl0IG5lZWRzIHRvIGJlIHR1bm5lbGVkIHRocm91Z2ggWGVyY2VzLgotICoKLSAqIDxwPgotICogSXQgaXMgYSBidWcgaWYgdGhpcyBleGNlcHRpb24gImxlYWtzIiB0byB0aGUgYXBwbGljYXRpb24uCi0gKgotICogRklYTUU6IHVzZSBYTklFeGNlcHRpb24gZm9yIHRoaXMgcHVycG9zZS4gSXQncyBhbHJlYWR5IGRvaW5nIHRoaXMKLSAqIGtpbmQgb2YgU0FYRXhjZXB0aW9uIHR1bm5lbGluZy4KLSAqCi0gKiBAYXV0aG9yCi0gKiAgICAgS29oc3VrZSBLYXdhZ3VjaGkgKGtvaHN1a2Uua2F3YWd1Y2hpQHN1bi5jb20pCi0gKi8KLXB1YmxpYyBjbGFzcyBXcmFwcGVkU0FYRXhjZXB0aW9uIGV4dGVuZHMgUnVudGltZUV4Y2VwdGlvbiB7Ci0gICAgcHVibGljIGZpbmFsIFNBWEV4Y2VwdGlvbiBleGNlcHRpb247Ci0KLSAgICBXcmFwcGVkU0FYRXhjZXB0aW9uKCBTQVhFeGNlcHRpb24gZSApIHsKLSAgICAgICAgdGhpcy5leGNlcHRpb24gPSBlOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2pheHAvdmFsaWRhdGlvbi9YTUxTY2hlbWEuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2pheHAvdmFsaWRhdGlvbi9YTUxTY2hlbWEuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDcwMDg2YS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9qYXhwL3ZhbGlkYXRpb24vWE1MU2NoZW1hLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw2NiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmpheHAudmFsaWRhdGlvbjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLmdyYW1tYXJzLlhNTEdyYW1tYXJQb29sOwotCi0vKioKLSAqIDxwPkltcGxlbWVudGF0aW9uIG9mIFNjaGVtYSBmb3IgVzNDIFhNTCBTY2hlbWFzLjwvcD4KLSAqCi0gKiBAYXV0aG9yIE1pY2hhZWwgR2xhdmFzc2V2aWNoLCBJQk0KLSAqLwotZmluYWwgY2xhc3MgWE1MU2NoZW1hIGV4dGVuZHMgQWJzdHJhY3RYTUxTY2hlbWEgewotCi0gICAgLyoqIFRoZSBncmFtbWFyIHBvb2wgaXMgaW1tdXRhYmxlICovCi0gICAgcHJpdmF0ZSBmaW5hbCBYTUxHcmFtbWFyUG9vbCBmR3JhbW1hclBvb2w7Ci0KLSAgICAvKiogQ29uc3RydWN0b3IgKi8KLSAgICBwdWJsaWMgWE1MU2NoZW1hKFhNTEdyYW1tYXJQb29sIGdyYW1tYXJQb29sKSB7Ci0gICAgICAgIGZHcmFtbWFyUG9vbCA9IGdyYW1tYXJQb29sOwotICAgIH0KLQotICAgIC8qCi0gICAgICogWFNHcmFtbWFyUG9vbENvbnRhaW5lciBtZXRob2RzCi0gICAgICovCi0KLSAgICAvKioKLSAgICAgKiA8cD5SZXR1cm5zIHRoZSBncmFtbWFyIHBvb2wgY29udGFpbmVkIGluc2lkZSB0aGUgY29udGFpbmVyLjwvcD4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdGhlIGdyYW1tYXIgcG9vbCBjb250YWluZWQgaW5zaWRlIHRoZSBjb250YWluZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgWE1MR3JhbW1hclBvb2wgZ2V0R3JhbW1hclBvb2woKSB7Ci0gICAgICAgIHJldHVybiBmR3JhbW1hclBvb2w7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+UmV0dXJucyB3aGV0aGVyIHRoZSBzY2hlbWEgY29tcG9uZW50cyBjb250YWluZWQgaW4gdGhpcyBvYmplY3QKLSAgICAgKiBjYW4gYmUgY29uc2lkZXJlZCB0byBiZSBhIGZ1bGx5IGNvbXBvc2VkIHNjaGVtYSBhbmQgc2hvdWxkIGJlCi0gICAgICogdXNlZCB0byBleGNsdXNpb24gb2Ygb3RoZXIgc2NoZW1hIGNvbXBvbmVudHMgd2hpY2ggbWF5IGJlCi0gICAgICogcHJlc2VudCBlbHNld2hlcmUuPC9wPgotICAgICAqCi0gICAgICogQHJldHVybiB3aGV0aGVyIHRoZSBzY2hlbWEgY29tcG9uZW50cyBjb250YWluZWQgaW4gdGhpcyBvYmplY3QKLSAgICAgKiBjYW4gYmUgY29uc2lkZXJlZCB0byBiZSBhIGZ1bGx5IGNvbXBvc2VkIHNjaGVtYQotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzRnVsbHlDb21wb3NlZCgpIHsKLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotCi19IC8vIFhNTFNjaGVtYQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvamF4cC92YWxpZGF0aW9uL1hNTFNjaGVtYUZhY3RvcnkuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2pheHAvdmFsaWRhdGlvbi9YTUxTY2hlbWFGYWN0b3J5LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDRlNTcxNzAuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvamF4cC92YWxpZGF0aW9uL1hNTFNjaGVtYUZhY3RvcnkuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDU0NyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmpheHAudmFsaWRhdGlvbjsKLQotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci1pbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKLWltcG9ydCBqYXZhLmlvLlJlYWRlcjsKLQotaW1wb3J0IGphdmF4LnhtbC5YTUxDb25zdGFudHM7Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5YTUxFdmVudFJlYWRlcjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlNvdXJjZTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLmRvbS5ET01Tb3VyY2U7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zYXguU0FYU291cmNlOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc3RheC5TdEFYU291cmNlOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc3RyZWFtLlN0cmVhbVNvdXJjZTsKLWltcG9ydCBqYXZheC54bWwudmFsaWRhdGlvbi5TY2hlbWE7Ci1pbXBvcnQgamF2YXgueG1sLnZhbGlkYXRpb24uU2NoZW1hRmFjdG9yeTsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5Db25zdGFudHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlhNTFNjaGVtYUxvYWRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuRE9NRW50aXR5UmVzb2x2ZXJXcmFwcGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5ET01JbnB1dFNvdXJjZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuRXJyb3JIYW5kbGVyV3JhcHBlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuU0FYSW5wdXRTb3VyY2U7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlNBWE1lc3NhZ2VGb3JtYXR0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlN0QVhJbnB1dFNvdXJjZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuU3RhdHVzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5YTUxHcmFtbWFyUG9vbEltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlscy5YTUxTZWN1cml0eU1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlscy5YTUxTZWN1cml0eVByb3BlcnR5TWFuYWdlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTklFeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuZ3JhbW1hcnMuR3JhbW1hcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5ncmFtbWFycy5YTUxHcmFtbWFyRGVzY3JpcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuZ3JhbW1hcnMuWE1MR3JhbW1hclBvb2w7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTElucHV0U291cmNlOwotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci1pbXBvcnQgb3JnLnczYy5kb20ubHMuTFNSZXNvdXJjZVJlc29sdmVyOwotaW1wb3J0IG9yZy54bWwuc2F4LkVycm9ySGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb247Ci0KLS8qKgotICoge0BsaW5rIFNjaGVtYUZhY3Rvcnl9IGZvciBYTUwgU2NoZW1hLgotICoKLSAqIEBhdXRob3IgS29oc3VrZSBLYXdhZ3VjaGkgKGtvaHN1a2Uua2F3YWd1Y2hpQHN1bi5jb20pCi0gKiBAdmVyc2lvbiAkSWQ6IFhNTFNjaGVtYUZhY3RvcnkuamF2YSx2IDEuMTEgMjAxMC0xMS0wMSAwNDo0MDowOCBqb2VodyBFeHAgJAotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgWE1MU2NoZW1hRmFjdG9yeSBleHRlbmRzIFNjaGVtYUZhY3RvcnkgewotCi0gICAgLy8gcHJvcGVydHkgaWRlbnRpZmllcnMKLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IHNjaGVtYSBmdWxsIGNoZWNraW5nLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBTQ0hFTUFfRlVMTF9DSEVDS0lORyA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuU0NIRU1BX0ZVTExfQ0hFQ0tJTkc7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogZ3JhbW1hciBwb29sLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxHUkFNTUFSX1BPT0wgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5YTUxHUkFNTUFSX1BPT0xfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogWE1MU2VjdXJpdHlNYW5hZ2VyLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBTRUNVUklUWV9NQU5BR0VSID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuU0VDVVJJVFlfTUFOQUdFUl9QUk9QRVJUWTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBTZWN1cml0eSBwcm9wZXJ0eSBtYW5hZ2VyLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxfU0VDVVJJVFlfUFJPUEVSVFlfTUFOQUdFUiA9Ci0gICAgICAgICAgICBDb25zdGFudHMuWE1MX1NFQ1VSSVRZX1BST1BFUlRZX01BTkFHRVI7Ci0KLQotICAgIC8vCi0gICAgLy8gRGF0YQotICAgIC8vCi0KLSAgICAvKiogVGhlIFhNTFNjaGVtYUxvYWRlciAqLwotICAgIHByaXZhdGUgZmluYWwgWE1MU2NoZW1hTG9hZGVyIGZYTUxTY2hlbWFMb2FkZXIgPSBuZXcgWE1MU2NoZW1hTG9hZGVyKCk7Ci0KLSAgICAvKiogVXNlci1zcGVjaWZpZWQgRXJyb3JIYW5kbGVyOyBjYW4gYmUgbnVsbC4gKi8KLSAgICBwcml2YXRlIEVycm9ySGFuZGxlciBmRXJyb3JIYW5kbGVyOwotCi0gICAgLyoqIFRoZSBMU1Jlc3JvdWNlUmVzb2x2ZXIgKi8KLSAgICBwcml2YXRlIExTUmVzb3VyY2VSZXNvbHZlciBmTFNSZXNvdXJjZVJlc29sdmVyOwotCi0gICAgLyoqIFRoZSBET01FbnRpdHlSZXNvbHZlcldyYXBwZXIgKi8KLSAgICBwcml2YXRlIGZpbmFsIERPTUVudGl0eVJlc29sdmVyV3JhcHBlciBmRE9NRW50aXR5UmVzb2x2ZXJXcmFwcGVyOwotCi0gICAgLyoqIFRoZSBFcnJvckhhbmRsZXJXcmFwcGVyICovCi0gICAgcHJpdmF0ZSBFcnJvckhhbmRsZXJXcmFwcGVyIGZFcnJvckhhbmRsZXJXcmFwcGVyOwotCi0gICAgLyoqIFRoZSBTZWN1cml0eU1hbmFnZXIuICovCi0gICAgcHJpdmF0ZSBYTUxTZWN1cml0eU1hbmFnZXIgZlNlY3VyaXR5TWFuYWdlcjsKLQotICAgIC8qKiBUaGUgU2VjdXJpdHkgcHJvcGVydHkgbWFuYWdlci4gKi8KLSAgICBwcml2YXRlIFhNTFNlY3VyaXR5UHJvcGVydHlNYW5hZ2VyIGZTZWN1cml0eVByb3BlcnR5TWdyOwotCi0gICAgLyoqIFRoZSBjb250YWluZXIgZm9yIHRoZSByZWFsIGdyYW1tYXIgcG9vbC4gKi8KLSAgICBwcml2YXRlIFhNTEdyYW1tYXJQb29sV3JhcHBlciBmWE1MR3JhbW1hclBvb2xXcmFwcGVyOwotCi0gICAgLyoqCi0gICAgICogSW5kaWNhdGVzIHdoZXRoZXIgaW1wbGVtZW50YXRpb24gcGFydHMgc2hvdWxkIHVzZQotICAgICAqICAgc2VydmljZSBsb2FkZXIgKG9yIHNpbWlsYXIpLgotICAgICAqIE5vdGUgdGhlIGRlZmF1bHQgdmFsdWUgKGZhbHNlKSBpcyB0aGUgc2FmZSBvcHRpb24uLgotICAgICAqLwotICAgIHByaXZhdGUgZmluYWwgYm9vbGVhbiBmVXNlU2VydmljZXNNZWNoYW5pc207Ci0KLQotICAgIHB1YmxpYyBYTUxTY2hlbWFGYWN0b3J5KCkgewotICAgICAgICB0aGlzKHRydWUpOwotICAgIH0KLSAgICBwdWJsaWMgc3RhdGljIFhNTFNjaGVtYUZhY3RvcnkgbmV3WE1MU2NoZW1hRmFjdG9yeU5vU2VydmljZUxvYWRlcigpIHsKLSAgICAgICAgcmV0dXJuIG5ldyBYTUxTY2hlbWFGYWN0b3J5KGZhbHNlKTsKLSAgICB9Ci0gICAgcHJpdmF0ZSBYTUxTY2hlbWFGYWN0b3J5KGJvb2xlYW4gdXNlU2VydmljZXNNZWNoYW5pc20pIHsKLSAgICAgICAgZlVzZVNlcnZpY2VzTWVjaGFuaXNtID0gdXNlU2VydmljZXNNZWNoYW5pc207Ci0gICAgICAgIGZFcnJvckhhbmRsZXJXcmFwcGVyID0gbmV3IEVycm9ySGFuZGxlcldyYXBwZXIoRHJhY29uaWFuRXJyb3JIYW5kbGVyLmdldEluc3RhbmNlKCkpOwotICAgICAgICBmRE9NRW50aXR5UmVzb2x2ZXJXcmFwcGVyID0gbmV3IERPTUVudGl0eVJlc29sdmVyV3JhcHBlcigpOwotICAgICAgICBmWE1MR3JhbW1hclBvb2xXcmFwcGVyID0gbmV3IFhNTEdyYW1tYXJQb29sV3JhcHBlcigpOwotICAgICAgICBmWE1MU2NoZW1hTG9hZGVyLnNldEZlYXR1cmUoU0NIRU1BX0ZVTExfQ0hFQ0tJTkcsIHRydWUpOwotICAgICAgICBmWE1MU2NoZW1hTG9hZGVyLnNldFByb3BlcnR5KFhNTEdSQU1NQVJfUE9PTCwgZlhNTEdyYW1tYXJQb29sV3JhcHBlcik7Ci0gICAgICAgIGZYTUxTY2hlbWFMb2FkZXIuc2V0RW50aXR5UmVzb2x2ZXIoZkRPTUVudGl0eVJlc29sdmVyV3JhcHBlcik7Ci0gICAgICAgIGZYTUxTY2hlbWFMb2FkZXIuc2V0RXJyb3JIYW5kbGVyKGZFcnJvckhhbmRsZXJXcmFwcGVyKTsKLQotICAgICAgICAvLyBFbmFibGUgc2VjdXJlIHByb2Nlc3NpbmcgZmVhdHVyZSBieSBkZWZhdWx0Ci0gICAgICAgIGZTZWN1cml0eU1hbmFnZXIgPSBuZXcgWE1MU2VjdXJpdHlNYW5hZ2VyKHRydWUpOwotICAgICAgICBmWE1MU2NoZW1hTG9hZGVyLnNldFByb3BlcnR5KFNFQ1VSSVRZX01BTkFHRVIsIGZTZWN1cml0eU1hbmFnZXIpOwotCi0gICAgICAgIGZTZWN1cml0eVByb3BlcnR5TWdyID0gbmV3IFhNTFNlY3VyaXR5UHJvcGVydHlNYW5hZ2VyKCk7Ci0gICAgICAgIGZYTUxTY2hlbWFMb2FkZXIuc2V0UHJvcGVydHkoWE1MX1NFQ1VSSVRZX1BST1BFUlRZX01BTkFHRVIsCi0gICAgICAgICAgICAgICAgZlNlY3VyaXR5UHJvcGVydHlNZ3IpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPklzIHNwZWNpZmllZCBzY2hlbWEgc3VwcG9ydGVkIGJ5IHRoaXMgPGNvZGU+U2NoZW1hRmFjdG9yeTwvY29kZT4/PC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIHNjaGVtYUxhbmd1YWdlIFNwZWNpZmllcyB0aGUgc2NoZW1hIGxhbmd1YWdlIHdoaWNoIHRoZSByZXR1cm5lZCA8Y29kZT5TY2hlbWFGYWN0b3J5PC9jb2RlPiB3aWxsIHVuZGVyc3RhbmQuCi0gICAgICogICAgPGNvZGU+c2NoZW1hTGFuZ3VhZ2U8L2NvZGU+IG11c3Qgc3BlY2lmeSBhIDxhIGhyZWY9IiNzY2hlbWFMYW5ndWFnZSI+dmFsaWQ8L2E+IHNjaGVtYSBsYW5ndWFnZS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gPGNvZGU+dHJ1ZTwvY29kZT4gaWYgPGNvZGU+U2NoZW1hRmFjdG9yeTwvY29kZT4gc3VwcG9ydHMgPGNvZGU+c2NoZW1hTGFuZ3VhZ2U8L2NvZGU+LCBlbHNlIDxjb2RlPmZhbHNlPC9jb2RlPi4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gSWYgPGNvZGU+c2NoZW1hTGFuZ3VhZ2U8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIElmIDxjb2RlPnNjaGVtYUxhbmd1YWdlLmxlbmd0aCgpID09IDA8L2NvZGU+Ci0gICAgICogICBvciA8Y29kZT5zY2hlbWFMYW5ndWFnZTwvY29kZT4gZG9lcyBub3Qgc3BlY2lmeSBhIDxhIGhyZWY9IiNzY2hlbWFMYW5ndWFnZSI+dmFsaWQ8L2E+IHNjaGVtYSBsYW5ndWFnZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc1NjaGVtYUxhbmd1YWdlU3VwcG9ydGVkKFN0cmluZyBzY2hlbWFMYW5ndWFnZSkgewotICAgICAgICBpZiAoc2NoZW1hTGFuZ3VhZ2UgPT0gbnVsbCkgewotICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKEpBWFBWYWxpZGF0aW9uTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKGZYTUxTY2hlbWFMb2FkZXIuZ2V0TG9jYWxlKCksCi0gICAgICAgICAgICAgICAgICAgICJTY2hlbWFMYW5ndWFnZU51bGwiLCBudWxsKSk7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKHNjaGVtYUxhbmd1YWdlLmxlbmd0aCgpID09IDApIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oSkFYUFZhbGlkYXRpb25NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoZlhNTFNjaGVtYUxvYWRlci5nZXRMb2NhbGUoKSwKLSAgICAgICAgICAgICAgICAgICAgIlNjaGVtYUxhbmd1YWdlTGVuZ3RoWmVybyIsIG51bGwpKTsKLSAgICAgICAgfQotICAgICAgICAvLyBvbmx5IFczQyBYTUwgU2NoZW1hIDEuMCBpcyBzdXBwb3J0ZWQKLSAgICAgICAgcmV0dXJuIHNjaGVtYUxhbmd1YWdlLmVxdWFscyhYTUxDb25zdGFudHMuVzNDX1hNTF9TQ0hFTUFfTlNfVVJJKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgTFNSZXNvdXJjZVJlc29sdmVyIGdldFJlc291cmNlUmVzb2x2ZXIoKSB7Ci0gICAgICAgIHJldHVybiBmTFNSZXNvdXJjZVJlc29sdmVyOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldFJlc291cmNlUmVzb2x2ZXIoTFNSZXNvdXJjZVJlc29sdmVyIHJlc291cmNlUmVzb2x2ZXIpIHsKLSAgICAgICAgZkxTUmVzb3VyY2VSZXNvbHZlciA9IHJlc291cmNlUmVzb2x2ZXI7Ci0gICAgICAgIGZET01FbnRpdHlSZXNvbHZlcldyYXBwZXIuc2V0RW50aXR5UmVzb2x2ZXIocmVzb3VyY2VSZXNvbHZlcik7Ci0gICAgICAgIGZYTUxTY2hlbWFMb2FkZXIuc2V0RW50aXR5UmVzb2x2ZXIoZkRPTUVudGl0eVJlc29sdmVyV3JhcHBlcik7Ci0gICAgfQotCi0gICAgcHVibGljIEVycm9ySGFuZGxlciBnZXRFcnJvckhhbmRsZXIoKSB7Ci0gICAgICAgIHJldHVybiBmRXJyb3JIYW5kbGVyOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldEVycm9ySGFuZGxlcihFcnJvckhhbmRsZXIgZXJyb3JIYW5kbGVyKSB7Ci0gICAgICAgIGZFcnJvckhhbmRsZXIgPSBlcnJvckhhbmRsZXI7Ci0gICAgICAgIGZFcnJvckhhbmRsZXJXcmFwcGVyLnNldEVycm9ySGFuZGxlcihlcnJvckhhbmRsZXIgIT0gbnVsbCA/IGVycm9ySGFuZGxlciA6IERyYWNvbmlhbkVycm9ySGFuZGxlci5nZXRJbnN0YW5jZSgpKTsKLSAgICAgICAgZlhNTFNjaGVtYUxvYWRlci5zZXRFcnJvckhhbmRsZXIoZkVycm9ySGFuZGxlcldyYXBwZXIpOwotICAgIH0KLQotICAgIHB1YmxpYyBTY2hlbWEgbmV3U2NoZW1hKCBTb3VyY2VbXSBzY2hlbWFzICkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy8gdGhpcyB3aWxsIGxldCB0aGUgbG9hZGVyIHN0b3JlIHBhcnNlZCBHcmFtbWFycyBpbnRvIHRoZSBwb29sLgotICAgICAgICBYTUxHcmFtbWFyUG9vbEltcGxFeHRlbnNpb24gcG9vbCA9IG5ldyBYTUxHcmFtbWFyUG9vbEltcGxFeHRlbnNpb24oKTsKLSAgICAgICAgZlhNTEdyYW1tYXJQb29sV3JhcHBlci5zZXRHcmFtbWFyUG9vbChwb29sKTsKLQotICAgICAgICBYTUxJbnB1dFNvdXJjZVtdIHhtbElucHV0U291cmNlcyA9IG5ldyBYTUxJbnB1dFNvdXJjZVtzY2hlbWFzLmxlbmd0aF07Ci0gICAgICAgIElucHV0U3RyZWFtIGlucHV0U3RyZWFtOwotICAgICAgICBSZWFkZXIgcmVhZGVyOwotICAgICAgICBmb3IoIGludCBpPTA7IGk8c2NoZW1hcy5sZW5ndGg7IGkrKyApIHsKLSAgICAgICAgICAgIFNvdXJjZSBzb3VyY2UgPSBzY2hlbWFzW2ldOwotICAgICAgICAgICAgaWYgKHNvdXJjZSBpbnN0YW5jZW9mIFN0cmVhbVNvdXJjZSkgewotICAgICAgICAgICAgICAgIFN0cmVhbVNvdXJjZSBzdHJlYW1Tb3VyY2UgPSAoU3RyZWFtU291cmNlKSBzb3VyY2U7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIHB1YmxpY0lkID0gc3RyZWFtU291cmNlLmdldFB1YmxpY0lkKCk7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIHN5c3RlbUlkID0gc3RyZWFtU291cmNlLmdldFN5c3RlbUlkKCk7Ci0gICAgICAgICAgICAgICAgaW5wdXRTdHJlYW0gPSBzdHJlYW1Tb3VyY2UuZ2V0SW5wdXRTdHJlYW0oKTsKLSAgICAgICAgICAgICAgICByZWFkZXIgPSBzdHJlYW1Tb3VyY2UuZ2V0UmVhZGVyKCk7Ci0gICAgICAgICAgICAgICAgeG1sSW5wdXRTb3VyY2VzW2ldID0gbmV3IFhNTElucHV0U291cmNlKHB1YmxpY0lkLCBzeXN0ZW1JZCwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgeG1sSW5wdXRTb3VyY2VzW2ldLnNldEJ5dGVTdHJlYW0oaW5wdXRTdHJlYW0pOwotICAgICAgICAgICAgICAgIHhtbElucHV0U291cmNlc1tpXS5zZXRDaGFyYWN0ZXJTdHJlYW0ocmVhZGVyKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKHNvdXJjZSBpbnN0YW5jZW9mIFNBWFNvdXJjZSkgewotICAgICAgICAgICAgICAgIFNBWFNvdXJjZSBzYXhTb3VyY2UgPSAoU0FYU291cmNlKSBzb3VyY2U7Ci0gICAgICAgICAgICAgICAgSW5wdXRTb3VyY2UgaW5wdXRTb3VyY2UgPSBzYXhTb3VyY2UuZ2V0SW5wdXRTb3VyY2UoKTsKLSAgICAgICAgICAgICAgICBpZiAoaW5wdXRTb3VyY2UgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKEpBWFBWYWxpZGF0aW9uTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKGZYTUxTY2hlbWFMb2FkZXIuZ2V0TG9jYWxlKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNBWFNvdXJjZU51bGxJbnB1dFNvdXJjZSIsIG51bGwpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgeG1sSW5wdXRTb3VyY2VzW2ldID0gbmV3IFNBWElucHV0U291cmNlKHNheFNvdXJjZS5nZXRYTUxSZWFkZXIoKSwgaW5wdXRTb3VyY2UpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoc291cmNlIGluc3RhbmNlb2YgRE9NU291cmNlKSB7Ci0gICAgICAgICAgICAgICAgRE9NU291cmNlIGRvbVNvdXJjZSA9IChET01Tb3VyY2UpIHNvdXJjZTsKLSAgICAgICAgICAgICAgICBOb2RlIG5vZGUgPSBkb21Tb3VyY2UuZ2V0Tm9kZSgpOwotICAgICAgICAgICAgICAgIFN0cmluZyBzeXN0ZW1JRCA9IGRvbVNvdXJjZS5nZXRTeXN0ZW1JZCgpOwotICAgICAgICAgICAgICAgIHhtbElucHV0U291cmNlc1tpXSA9IG5ldyBET01JbnB1dFNvdXJjZShub2RlLCBzeXN0ZW1JRCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAgZWxzZSBpZiAoc291cmNlIGluc3RhbmNlb2YgU3RBWFNvdXJjZSkgewotICAgICAgICAgICAgICAgIFN0QVhTb3VyY2Ugc3RheFNvdXJjZSA9IChTdEFYU291cmNlKSBzb3VyY2U7Ci0gICAgICAgICAgICAgICAgWE1MRXZlbnRSZWFkZXIgZXZlbnRSZWFkZXIgPSBzdGF4U291cmNlLmdldFhNTEV2ZW50UmVhZGVyKCk7Ci0gICAgICAgICAgICAgICAgaWYgKGV2ZW50UmVhZGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgeG1sSW5wdXRTb3VyY2VzW2ldID0gbmV3IFN0QVhJbnB1dFNvdXJjZShldmVudFJlYWRlcik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICB4bWxJbnB1dFNvdXJjZXNbaV0gPSBuZXcgU3RBWElucHV0U291cmNlKHN0YXhTb3VyY2UuZ2V0WE1MU3RyZWFtUmVhZGVyKCkpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKHNvdXJjZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKEpBWFBWYWxpZGF0aW9uTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKGZYTUxTY2hlbWFMb2FkZXIuZ2V0TG9jYWxlKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAiU2NoZW1hU291cmNlQXJyYXlNZW1iZXJOdWxsIiwgbnVsbCkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihKQVhQVmFsaWRhdGlvbk1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShmWE1MU2NoZW1hTG9hZGVyLmdldExvY2FsZSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgIlNjaGVtYUZhY3RvcnlTb3VyY2VVbnJlY29nbml6ZWQiLAotICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdCBbXSB7c291cmNlLmdldENsYXNzKCkuZ2V0TmFtZSgpfSkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGZYTUxTY2hlbWFMb2FkZXIubG9hZEdyYW1tYXIoeG1sSW5wdXRTb3VyY2VzKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoWE5JRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIC8vIHRoaXMgc2hvdWxkIGhhdmUgYmVlbiByZXBvcnRlZCB0byB1c2VycyBhbHJlYWR5LgotICAgICAgICAgICAgdGhyb3cgVXRpbC50b1NBWEV4Y2VwdGlvbihlKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewotICAgICAgICAgICAgLy8gdGhpcyBoYXNuJ3QgYmVlbiByZXBvcnRlZCwgc28gZG8gc28gbm93LgotICAgICAgICAgICAgU0FYUGFyc2VFeGNlcHRpb24gc2UgPSBuZXcgU0FYUGFyc2VFeGNlcHRpb24oZS5nZXRNZXNzYWdlKCksbnVsbCxlKTsKLSAgICAgICAgICAgIGZFcnJvckhhbmRsZXIuZXJyb3Ioc2UpOwotICAgICAgICAgICAgdGhyb3cgc2U7IC8vIGFuZCB3ZSBtdXN0IHRocm93IGl0LgotICAgICAgICB9Ci0KLSAgICAgICAgLy8gQ2xlYXIgcmVmZXJlbmNlIHRvIGdyYW1tYXIgcG9vbC4KLSAgICAgICAgZlhNTEdyYW1tYXJQb29sV3JhcHBlci5zZXRHcmFtbWFyUG9vbChudWxsKTsKLQotICAgICAgICAvLyBTZWxlY3QgU2NoZW1hIGltcGxlbWVudGF0aW9uIGJhc2VkIG9uIGdyYW1tYXIgY291bnQuCi0gICAgICAgIGZpbmFsIGludCBncmFtbWFyQ291bnQgPSBwb29sLmdldEdyYW1tYXJDb3VudCgpOwotICAgICAgICBBYnN0cmFjdFhNTFNjaGVtYSBzY2hlbWEgPSBudWxsOwotICAgICAgICBpZiAoZ3JhbW1hckNvdW50ID4gMSkgewotICAgICAgICAgICAgc2NoZW1hID0gbmV3IFhNTFNjaGVtYShuZXcgUmVhZE9ubHlHcmFtbWFyUG9vbChwb29sKSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoZ3JhbW1hckNvdW50ID09IDEpIHsKLSAgICAgICAgICAgIEdyYW1tYXJbXSBncmFtbWFycyA9IHBvb2wucmV0cmlldmVJbml0aWFsR3JhbW1hclNldChYTUxHcmFtbWFyRGVzY3JpcHRpb24uWE1MX1NDSEVNQSk7Ci0gICAgICAgICAgICBzY2hlbWEgPSBuZXcgU2ltcGxlWE1MU2NoZW1hKGdyYW1tYXJzWzBdKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHNjaGVtYSA9IG5ldyBFbXB0eVhNTFNjaGVtYSgpOwotICAgICAgICB9Ci0gICAgICAgIHByb3BhZ2F0ZUZlYXR1cmVzKHNjaGVtYSk7Ci0gICAgICAgIHByb3BhZ2F0ZVByb3BlcnRpZXMoc2NoZW1hKTsKLSAgICAgICAgcmV0dXJuIHNjaGVtYTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU2NoZW1hIG5ld1NjaGVtYSgpIHRocm93cyBTQVhFeGNlcHRpb24gewotICAgICAgICAvLyBVc2UgYSBTY2hlbWEgdGhhdCB1c2VzIHRoZSBzeXN0ZW0gaWQgYXMgdGhlIGVxdWFsaXR5IHNvdXJjZS4KLSAgICAgICAgQWJzdHJhY3RYTUxTY2hlbWEgc2NoZW1hID0gbmV3IFdlYWtSZWZlcmVuY2VYTUxTY2hlbWEoKTsKLSAgICAgICAgcHJvcGFnYXRlRmVhdHVyZXMoc2NoZW1hKTsKLSAgICAgICAgcHJvcGFnYXRlUHJvcGVydGllcyhzY2hlbWEpOwotICAgICAgICByZXR1cm4gc2NoZW1hOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGdldEZlYXR1cmUoU3RyaW5nIG5hbWUpCi0gICAgICAgIHRocm93cyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uLCBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gewotICAgICAgICBpZiAobmFtZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oSkFYUFZhbGlkYXRpb25NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoZlhNTFNjaGVtYUxvYWRlci5nZXRMb2NhbGUoKSwKLSAgICAgICAgICAgICAgICAgICAgIkZlYXR1cmVOYW1lTnVsbCIsIG51bGwpKTsKLSAgICAgICAgfQotICAgICAgICBpZiAobmFtZS5lcXVhbHMoWE1MQ29uc3RhbnRzLkZFQVRVUkVfU0VDVVJFX1BST0NFU1NJTkcpKSB7Ci0gICAgICAgICAgICByZXR1cm4gKGZTZWN1cml0eU1hbmFnZXIgIT0gbnVsbCAmJiBmU2VjdXJpdHlNYW5hZ2VyLmlzU2VjdXJlUHJvY2Vzc2luZygpKTsKLSAgICAgICAgfQotICAgICAgICB0cnkgewotICAgICAgICAgICAgcmV0dXJuIGZYTUxTY2hlbWFMb2FkZXIuZ2V0RmVhdHVyZShuYW1lKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICBTdHJpbmcgaWRlbnRpZmllciA9IGUuZ2V0SWRlbnRpZmllcigpOwotICAgICAgICAgICAgaWYgKGUuZ2V0VHlwZSgpID09IFN0YXR1cy5OT1RfUkVDT0dOSVpFRCkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICAgICAgU0FYTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKGZYTUxTY2hlbWFMb2FkZXIuZ2V0TG9jYWxlKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAiZmVhdHVyZS1ub3QtcmVjb2duaXplZCIsIG5ldyBPYmplY3QgW10ge2lkZW50aWZpZXJ9KSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICAgICAgU0FYTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKGZYTUxTY2hlbWFMb2FkZXIuZ2V0TG9jYWxlKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAiZmVhdHVyZS1ub3Qtc3VwcG9ydGVkIiwgbmV3IE9iamVjdCBbXSB7aWRlbnRpZmllcn0pKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyBPYmplY3QgZ2V0UHJvcGVydHkoU3RyaW5nIG5hbWUpCi0gICAgICAgIHRocm93cyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uLCBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gewotICAgICAgICBpZiAobmFtZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oSkFYUFZhbGlkYXRpb25NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoZlhNTFNjaGVtYUxvYWRlci5nZXRMb2NhbGUoKSwKLSAgICAgICAgICAgICAgICAgICAgIlByb3BlcnlOYW1lTnVsbCIsIG51bGwpKTsKLSAgICAgICAgfQotICAgICAgICBpZiAobmFtZS5lcXVhbHMoU0VDVVJJVFlfTUFOQUdFUikpIHsKLSAgICAgICAgICAgIHJldHVybiBmU2VjdXJpdHlNYW5hZ2VyOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzKFhNTEdSQU1NQVJfUE9PTCkpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgIFNBWE1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShmWE1MU2NoZW1hTG9hZGVyLmdldExvY2FsZSgpLAotICAgICAgICAgICAgICAgICAgICAicHJvcGVydHktbm90LXN1cHBvcnRlZCIsIG5ldyBPYmplY3QgW10ge25hbWV9KSk7Ci0gICAgICAgIH0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIHJldHVybiBmWE1MU2NoZW1hTG9hZGVyLmdldFByb3BlcnR5KG5hbWUpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIFN0cmluZyBpZGVudGlmaWVyID0gZS5nZXRJZGVudGlmaWVyKCk7Ci0gICAgICAgICAgICBpZiAoZS5nZXRUeXBlKCkgPT0gU3RhdHVzLk5PVF9SRUNPR05JWkVEKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgICAgICBTQVhNZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoZlhNTFNjaGVtYUxvYWRlci5nZXRMb2NhbGUoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICJwcm9wZXJ0eS1ub3QtcmVjb2duaXplZCIsIG5ldyBPYmplY3QgW10ge2lkZW50aWZpZXJ9KSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICAgICAgU0FYTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKGZYTUxTY2hlbWFMb2FkZXIuZ2V0TG9jYWxlKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAicHJvcGVydHktbm90LXN1cHBvcnRlZCIsIG5ldyBPYmplY3QgW10ge2lkZW50aWZpZXJ9KSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRGZWF0dXJlKFN0cmluZyBuYW1lLCBib29sZWFuIHZhbHVlKQotICAgICAgICB0aHJvd3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiwgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKG5hbWUgPT0gbnVsbCkgewotICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKEpBWFBWYWxpZGF0aW9uTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKGZYTUxTY2hlbWFMb2FkZXIuZ2V0TG9jYWxlKCksCi0gICAgICAgICAgICAgICAgICAgICJGZWF0dXJlTmFtZU51bGwiLCBudWxsKSk7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKG5hbWUuZXF1YWxzKFhNTENvbnN0YW50cy5GRUFUVVJFX1NFQ1VSRV9QUk9DRVNTSU5HKSkgewotICAgICAgICAgICAgaWYgKFN5c3RlbS5nZXRTZWN1cml0eU1hbmFnZXIoKSAhPSBudWxsICYmICghdmFsdWUpKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgICAgIFNBWE1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShudWxsLAotICAgICAgICAgICAgICAgICAgICAgICAgImpheHAtc2VjdXJlcHJvY2Vzc2luZy1mZWF0dXJlIiwgbnVsbCkpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBmU2VjdXJpdHlNYW5hZ2VyLnNldFNlY3VyZVByb2Nlc3NpbmcodmFsdWUpOwotICAgICAgICAgICAgaWYgKHZhbHVlKSB7Ci0gICAgICAgICAgICAgICAgaWYgKENvbnN0YW50cy5JU19KREs4X09SX0FCT1ZFKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZTZWN1cml0eVByb3BlcnR5TWdyLnNldFZhbHVlKFhNTFNlY3VyaXR5UHJvcGVydHlNYW5hZ2VyLlByb3BlcnR5LkFDQ0VTU19FWFRFUk5BTF9EVEQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MU2VjdXJpdHlQcm9wZXJ0eU1hbmFnZXIuU3RhdGUuRlNQLCBDb25zdGFudHMuRVhURVJOQUxfQUNDRVNTX0RFRkFVTFRfRlNQKTsKLSAgICAgICAgICAgICAgICAgICAgZlNlY3VyaXR5UHJvcGVydHlNZ3Iuc2V0VmFsdWUoWE1MU2VjdXJpdHlQcm9wZXJ0eU1hbmFnZXIuUHJvcGVydHkuQUNDRVNTX0VYVEVSTkFMX1NDSEVNQSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxTZWN1cml0eVByb3BlcnR5TWFuYWdlci5TdGF0ZS5GU1AsIENvbnN0YW50cy5FWFRFUk5BTF9BQ0NFU1NfREVGQVVMVF9GU1ApOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgZlhNTFNjaGVtYUxvYWRlci5zZXRQcm9wZXJ0eShTRUNVUklUWV9NQU5BR0VSLCBmU2VjdXJpdHlNYW5hZ2VyKTsKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfSBlbHNlIGlmIChuYW1lLmVxdWFscyhDb25zdGFudHMuT1JBQ0xFX0ZFQVRVUkVfU0VSVklDRV9NRUNIQU5JU00pKSB7Ci0gICAgICAgICAgICAvL2luIHNlY3VyZSBtb2RlLCBsZXQgX3VzZVNlcnZpY2VzTWVjaGFuaXNtIGJlIGRldGVybWluZWQgYnkgdGhlIGNvbnN0cnVjdG9yCi0gICAgICAgICAgICBpZiAoU3lzdGVtLmdldFNlY3VyaXR5TWFuYWdlcigpICE9IG51bGwpCi0gICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBmWE1MU2NoZW1hTG9hZGVyLnNldEZlYXR1cmUobmFtZSwgdmFsdWUpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIFN0cmluZyBpZGVudGlmaWVyID0gZS5nZXRJZGVudGlmaWVyKCk7Ci0gICAgICAgICAgICBpZiAoZS5nZXRUeXBlKCkgPT0gU3RhdHVzLk5PVF9SRUNPR05JWkVEKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgICAgICBTQVhNZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoZlhNTFNjaGVtYUxvYWRlci5nZXRMb2NhbGUoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICJmZWF0dXJlLW5vdC1yZWNvZ25pemVkIiwgbmV3IE9iamVjdCBbXSB7aWRlbnRpZmllcn0pKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgICAgICBTQVhNZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoZlhNTFNjaGVtYUxvYWRlci5nZXRMb2NhbGUoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICJmZWF0dXJlLW5vdC1zdXBwb3J0ZWQiLCBuZXcgT2JqZWN0IFtdIHtpZGVudGlmaWVyfSkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0UHJvcGVydHkoU3RyaW5nIG5hbWUsIE9iamVjdCBvYmplY3QpCi0gICAgICAgIHRocm93cyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uLCBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gewotICAgICAgICBpZiAobmFtZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oSkFYUFZhbGlkYXRpb25NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoZlhNTFNjaGVtYUxvYWRlci5nZXRMb2NhbGUoKSwKLSAgICAgICAgICAgICAgICAgICAgIlByb3BlcnlOYW1lTnVsbCIsIG51bGwpKTsKLSAgICAgICAgfQotICAgICAgICBpZiAobmFtZS5lcXVhbHMoU0VDVVJJVFlfTUFOQUdFUikpIHsKLSAgICAgICAgICAgIGZTZWN1cml0eU1hbmFnZXIgPSBYTUxTZWN1cml0eU1hbmFnZXIuY29udmVydChvYmplY3QsIGZTZWN1cml0eU1hbmFnZXIpOwotICAgICAgICAgICAgZlhNTFNjaGVtYUxvYWRlci5zZXRQcm9wZXJ0eShTRUNVUklUWV9NQU5BR0VSLCBmU2VjdXJpdHlNYW5hZ2VyKTsKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfSBlbHNlIGlmIChuYW1lLmVxdWFscyhDb25zdGFudHMuWE1MX1NFQ1VSSVRZX1BST1BFUlRZX01BTkFHRVIpKSB7Ci0gICAgICAgICAgICBpZiAob2JqZWN0ID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmU2VjdXJpdHlQcm9wZXJ0eU1nciA9IG5ldyBYTUxTZWN1cml0eVByb3BlcnR5TWFuYWdlcigpOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBmU2VjdXJpdHlQcm9wZXJ0eU1nciA9IChYTUxTZWN1cml0eVByb3BlcnR5TWFuYWdlcilvYmplY3Q7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmWE1MU2NoZW1hTG9hZGVyLnNldFByb3BlcnR5KENvbnN0YW50cy5YTUxfU0VDVVJJVFlfUFJPUEVSVFlfTUFOQUdFUiwgZlNlY3VyaXR5UHJvcGVydHlNZ3IpOwotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzKFhNTEdSQU1NQVJfUE9PTCkpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgIFNBWE1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShmWE1MU2NoZW1hTG9hZGVyLmdldExvY2FsZSgpLAotICAgICAgICAgICAgICAgICAgICAicHJvcGVydHktbm90LXN1cHBvcnRlZCIsIG5ldyBPYmplY3QgW10ge25hbWV9KSk7Ci0gICAgICAgIH0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIC8vY2hlY2sgaWYgdGhlIHByb3BlcnR5IGlzIG1hbmFnZWQgYnkgc2VjdXJpdHkgbWFuYWdlcgotICAgICAgICAgICAgaWYgKGZTZWN1cml0eU1hbmFnZXIgPT0gbnVsbCB8fAotICAgICAgICAgICAgICAgICAgICAhZlNlY3VyaXR5TWFuYWdlci5zZXRMaW1pdChuYW1lLCBYTUxTZWN1cml0eU1hbmFnZXIuU3RhdGUuQVBJUFJPUEVSVFksIG9iamVjdCkpIHsKLSAgICAgICAgICAgICAgICAvL2NoZWNrIGlmIHRoZSBwcm9wZXJ0eSBpcyBtYW5hZ2VkIGJ5IHNlY3VyaXR5IHByb3BlcnR5IG1hbmFnZXIKLSAgICAgICAgICAgICAgICBpZiAoZlNlY3VyaXR5UHJvcGVydHlNZ3IgPT0gbnVsbCB8fAotICAgICAgICAgICAgICAgICAgICAgICAgIWZTZWN1cml0eVByb3BlcnR5TWdyLnNldFZhbHVlKG5hbWUsIFhNTFNlY3VyaXR5UHJvcGVydHlNYW5hZ2VyLlN0YXRlLkFQSVBST1BFUlRZLCBvYmplY3QpKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vZmFsbCBiYWNrIHRvIHRoZSBleGlzdGluZyBwcm9wZXJ0eSBtYW5hZ2VyCi0gICAgICAgICAgICAgICAgICAgIGZYTUxTY2hlbWFMb2FkZXIuc2V0UHJvcGVydHkobmFtZSwgb2JqZWN0KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gZSkgewotICAgICAgICAgICAgU3RyaW5nIGlkZW50aWZpZXIgPSBlLmdldElkZW50aWZpZXIoKTsKLSAgICAgICAgICAgIGlmIChlLmdldFR5cGUoKSA9PSBTdGF0dXMuTk9UX1JFQ09HTklaRUQpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgICAgIFNBWE1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShmWE1MU2NoZW1hTG9hZGVyLmdldExvY2FsZSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgInByb3BlcnR5LW5vdC1yZWNvZ25pemVkIiwgbmV3IE9iamVjdCBbXSB7aWRlbnRpZmllcn0pKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgICAgICBTQVhNZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoZlhNTFNjaGVtYUxvYWRlci5nZXRMb2NhbGUoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICJwcm9wZXJ0eS1ub3Qtc3VwcG9ydGVkIiwgbmV3IE9iamVjdCBbXSB7aWRlbnRpZmllcn0pKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBwcm9wYWdhdGVGZWF0dXJlcyhBYnN0cmFjdFhNTFNjaGVtYSBzY2hlbWEpIHsKLSAgICAgICAgc2NoZW1hLnNldEZlYXR1cmUoWE1MQ29uc3RhbnRzLkZFQVRVUkVfU0VDVVJFX1BST0NFU1NJTkcsCi0gICAgICAgICAgICAgICAgKGZTZWN1cml0eU1hbmFnZXIgIT0gbnVsbCAmJiBmU2VjdXJpdHlNYW5hZ2VyLmlzU2VjdXJlUHJvY2Vzc2luZygpKSk7Ci0gICAgICAgIHNjaGVtYS5zZXRGZWF0dXJlKENvbnN0YW50cy5PUkFDTEVfRkVBVFVSRV9TRVJWSUNFX01FQ0hBTklTTSwgZlVzZVNlcnZpY2VzTWVjaGFuaXNtKTsKLSAgICAgICAgU3RyaW5nW10gZmVhdHVyZXMgPSBmWE1MU2NoZW1hTG9hZGVyLmdldFJlY29nbml6ZWRGZWF0dXJlcygpOwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZlYXR1cmVzLmxlbmd0aDsgKytpKSB7Ci0gICAgICAgICAgICBib29sZWFuIHN0YXRlID0gZlhNTFNjaGVtYUxvYWRlci5nZXRGZWF0dXJlKGZlYXR1cmVzW2ldKTsKLSAgICAgICAgICAgIHNjaGVtYS5zZXRGZWF0dXJlKGZlYXR1cmVzW2ldLCBzdGF0ZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgcHJvcGFnYXRlUHJvcGVydGllcyhBYnN0cmFjdFhNTFNjaGVtYSBzY2hlbWEpIHsKLSAgICAgICAgU3RyaW5nW10gcHJvcGVydGllcyA9IGZYTUxTY2hlbWFMb2FkZXIuZ2V0UmVjb2duaXplZFByb3BlcnRpZXMoKTsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwcm9wZXJ0aWVzLmxlbmd0aDsgKytpKSB7Ci0gICAgICAgICAgICBPYmplY3Qgc3RhdGUgPSBmWE1MU2NoZW1hTG9hZGVyLmdldFByb3BlcnR5KHByb3BlcnRpZXNbaV0pOwotICAgICAgICAgICAgc2NoZW1hLnNldFByb3BlcnR5KHByb3BlcnRpZXNbaV0sIHN0YXRlKTsKLSAgICAgICAgfQotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogRXh0ZW5zaW9uIG9mIFhNTEdyYW1tYXJQb29sSW1wbCB3aGljaCBleHBvc2VzIHRoZSBudW1iZXIgb2YKLSAgICAgKiBncmFtbWFycyBzdG9yZWQgaW4gdGhlIGdyYW1tYXIgcG9vbC4KLSAgICAgKi8KLSAgICBzdGF0aWMgY2xhc3MgWE1MR3JhbW1hclBvb2xJbXBsRXh0ZW5zaW9uIGV4dGVuZHMgWE1MR3JhbW1hclBvb2xJbXBsIHsKLQotICAgICAgICAvKiogQ29uc3RydWN0cyBhIGdyYW1tYXIgcG9vbCB3aXRoIGEgZGVmYXVsdCBudW1iZXIgb2YgYnVja2V0cy4gKi8KLSAgICAgICAgcHVibGljIFhNTEdyYW1tYXJQb29sSW1wbEV4dGVuc2lvbigpIHsKLSAgICAgICAgICAgIHN1cGVyKCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvKiogQ29uc3RydWN0cyBhIGdyYW1tYXIgcG9vbCB3aXRoIGEgc3BlY2lmaWVkIG51bWJlciBvZiBidWNrZXRzLiAqLwotICAgICAgICBwdWJsaWMgWE1MR3JhbW1hclBvb2xJbXBsRXh0ZW5zaW9uKGludCBpbml0aWFsQ2FwYWNpdHkpIHsKLSAgICAgICAgICAgIHN1cGVyKGluaXRpYWxDYXBhY2l0eSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvKiogUmV0dXJucyB0aGUgbnVtYmVyIG9mIGdyYW1tYXJzIGNvbnRhaW5lZCBpbiB0aGlzIHBvb2wuICovCi0gICAgICAgIGludCBnZXRHcmFtbWFyQ291bnQoKSB7Ci0gICAgICAgICAgICByZXR1cm4gZkdyYW1tYXJDb3VudDsKLSAgICAgICAgfQotCi0gICAgfSAvLyBYTUxTY2hlbWFGYWN0b3J5LlhNTEdyYW1tYXJQb29sSW1wbEV4dGVuc2lvbgotCi0gICAgLyoqCi0gICAgICogQSBncmFtbWFyIHBvb2wgd2hpY2ggd3JhcHMgYW5vdGhlci4KLSAgICAgKi8KLSAgICBzdGF0aWMgY2xhc3MgWE1MR3JhbW1hclBvb2xXcmFwcGVyIGltcGxlbWVudHMgWE1MR3JhbW1hclBvb2wgewotCi0gICAgICAgIHByaXZhdGUgWE1MR3JhbW1hclBvb2wgZkdyYW1tYXJQb29sOwotCi0gICAgICAgIC8qCi0gICAgICAgICAqIFhNTEdyYW1tYXJQb29sIG1ldGhvZHMKLSAgICAgICAgICovCi0KLSAgICAgICAgcHVibGljIEdyYW1tYXJbXSByZXRyaWV2ZUluaXRpYWxHcmFtbWFyU2V0KFN0cmluZyBncmFtbWFyVHlwZSkgewotICAgICAgICAgICAgcmV0dXJuIGZHcmFtbWFyUG9vbC5yZXRyaWV2ZUluaXRpYWxHcmFtbWFyU2V0KGdyYW1tYXJUeXBlKTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyB2b2lkIGNhY2hlR3JhbW1hcnMoU3RyaW5nIGdyYW1tYXJUeXBlLCBHcmFtbWFyW10gZ3JhbW1hcnMpIHsKLSAgICAgICAgICAgIGZHcmFtbWFyUG9vbC5jYWNoZUdyYW1tYXJzKGdyYW1tYXJUeXBlLCBncmFtbWFycyk7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgR3JhbW1hciByZXRyaWV2ZUdyYW1tYXIoWE1MR3JhbW1hckRlc2NyaXB0aW9uIGRlc2MpIHsKLSAgICAgICAgICAgIHJldHVybiBmR3JhbW1hclBvb2wucmV0cmlldmVHcmFtbWFyKGRlc2MpOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIHZvaWQgbG9ja1Bvb2woKSB7Ci0gICAgICAgICAgICBmR3JhbW1hclBvb2wubG9ja1Bvb2woKTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyB2b2lkIHVubG9ja1Bvb2woKSB7Ci0gICAgICAgICAgICBmR3JhbW1hclBvb2wudW5sb2NrUG9vbCgpOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIHZvaWQgY2xlYXIoKSB7Ci0gICAgICAgICAgICBmR3JhbW1hclBvb2wuY2xlYXIoKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8qCi0gICAgICAgICAqIE90aGVyIG1ldGhvZHMKLSAgICAgICAgICovCi0KLSAgICAgICAgdm9pZCBzZXRHcmFtbWFyUG9vbChYTUxHcmFtbWFyUG9vbCBncmFtbWFyUG9vbCkgewotICAgICAgICAgICAgZkdyYW1tYXJQb29sID0gZ3JhbW1hclBvb2w7Ci0gICAgICAgIH0KLQotICAgICAgICBYTUxHcmFtbWFyUG9vbCBnZXRHcmFtbWFyUG9vbCgpIHsKLSAgICAgICAgICAgIHJldHVybiBmR3JhbW1hclBvb2w7Ci0gICAgICAgIH0KLQotICAgIH0gLy8gWE1MU2NoZW1hRmFjdG9yeS5YTUxHcmFtbWFyUG9vbFdyYXBwZXIKLQotfSAvLyBYTUxTY2hlbWFGYWN0b3J5CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9qYXhwL3ZhbGlkYXRpb24vWE1MU2NoZW1hVmFsaWRhdG9yQ29tcG9uZW50TWFuYWdlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvamF4cC92YWxpZGF0aW9uL1hNTFNjaGVtYVZhbGlkYXRvckNvbXBvbmVudE1hbmFnZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZGNiYmFiZC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9qYXhwL3ZhbGlkYXRpb24vWE1MU2NoZW1hVmFsaWRhdG9yQ29tcG9uZW50TWFuYWdlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTYxICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuamF4cC52YWxpZGF0aW9uOwotCi1pbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7Ci1pbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKLWltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7Ci1pbXBvcnQgamF2YS51dGlsLk1hcDsKLQotaW1wb3J0IGphdmF4LnhtbC5YTUxDb25zdGFudHM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5YTUxFbnRpdHlNYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5YTUxFcnJvclJlcG9ydGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC52YWxpZGF0aW9uLlZhbGlkYXRpb25NYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5YTUxTY2hlbWFWYWxpZGF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlhTTWVzc2FnZUZvcm1hdHRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuRE9NRW50aXR5UmVzb2x2ZXJXcmFwcGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5FcnJvckhhbmRsZXJXcmFwcGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5GZWF0dXJlU3RhdGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLk5hbWVzcGFjZVN1cHBvcnQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlBhcnNlckNvbmZpZ3VyYXRpb25TZXR0aW5nczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuUHJvcGVydHlTdGF0ZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuU3RhdHVzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5TeW1ib2xUYWJsZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWxzLlhNTFNlY3VyaXR5UHJvcGVydHlNYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbHMuWE1MU2VjdXJpdHlNYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLk5hbWVzcGFjZUNvbnRleHQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE5JRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxDb21wb25lbnQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTENvbXBvbmVudE1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci1pbXBvcnQgb3JnLnczYy5kb20ubHMuTFNSZXNvdXJjZVJlc29sdmVyOwotaW1wb3J0IG9yZy54bWwuc2F4LkVycm9ySGFuZGxlcjsKLQotLyoqCi0gKiA8cD5BbiBpbXBsZW1lbnRhdGlvbiBvZiBYTUxDb21wb25lbnRNYW5hZ2VyIGZvciBhIHNjaGVtYSB2YWxpZGF0b3IuPC9wPgotICoKLSAqIEBhdXRob3IgTWljaGFlbCBHbGF2YXNzZXZpY2gsIElCTQotICogQHZlcnNpb24gJElkOiBYTUxTY2hlbWFWYWxpZGF0b3JDb21wb25lbnRNYW5hZ2VyLmphdmEsdiAxLjkgMjAxMC0xMS0wMSAwNDo0MDowOCBqb2VodyBFeHAgJAotICovCi1maW5hbCBjbGFzcyBYTUxTY2hlbWFWYWxpZGF0b3JDb21wb25lbnRNYW5hZ2VyIGV4dGVuZHMgUGFyc2VyQ29uZmlndXJhdGlvblNldHRpbmdzIGltcGxlbWVudHMKLSAgICAgICAgWE1MQ29tcG9uZW50TWFuYWdlciB7Ci0KLSAgICAvLyBmZWF0dXJlIGlkZW50aWZpZXJzCi0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiBzY2hlbWEgdmFsaWRhdGlvbi4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgU0NIRU1BX1ZBTElEQVRJT04gPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLlNDSEVNQV9WQUxJREFUSU9OX0ZFQVRVUkU7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiB2YWxpZGF0aW9uLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBWQUxJREFUSU9OID0KLSAgICAgICAgQ29uc3RhbnRzLlNBWF9GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5WQUxJREFUSU9OX0ZFQVRVUkU7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiBzZW5kIGVsZW1lbnQgZGVmYXVsdCB2YWx1ZSB2aWEgY2hhcmFjdGVycygpICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFNDSEVNQV9FTEVNRU5UX0RFRkFVTFQgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLlNDSEVNQV9FTEVNRU5UX0RFRkFVTFQ7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiB1c2UgZ3JhbW1hciBwb29sIG9ubHkuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFVTRV9HUkFNTUFSX1BPT0xfT05MWSA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuVVNFX0dSQU1NQVJfUE9PTF9PTkxZX0ZFQVRVUkU7Ci0KLSAgICAvLyBwcm9wZXJ0eSBpZGVudGlmaWVycwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IGVudGl0eSBtYW5hZ2VyLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBFTlRJVFlfTUFOQUdFUiA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLkVOVElUWV9NQU5BR0VSX1BST1BFUlRZOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IGVudGl0eSByZXNvbHZlci4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRU5USVRZX1JFU09MVkVSID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuRU5USVRZX1JFU09MVkVSX1BST1BFUlRZOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IGVycm9yIGhhbmRsZXIuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUk9SX0hBTkRMRVIgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5FUlJPUl9IQU5ETEVSX1BST1BFUlRZOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IGVycm9yIHJlcG9ydGVyLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJPUl9SRVBPUlRFUiA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLkVSUk9SX1JFUE9SVEVSX1BST1BFUlRZOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IG5hbWVzcGFjZSBjb250ZXh0LiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBOQU1FU1BBQ0VfQ09OVEVYVCA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLk5BTUVTUEFDRV9DT05URVhUX1BST1BFUlRZOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IFhNTCBTY2hlbWEgdmFsaWRhdG9yLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBTQ0hFTUFfVkFMSURBVE9SID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuU0NIRU1BX1ZBTElEQVRPUl9QUk9QRVJUWTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBzZWN1cml0eSBtYW5hZ2VyLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBTRUNVUklUWV9NQU5BR0VSID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuU0VDVVJJVFlfTUFOQUdFUl9QUk9QRVJUWTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBzZWN1cml0eSBwcm9wZXJ0eSBtYW5hZ2VyLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxfU0VDVVJJVFlfUFJPUEVSVFlfTUFOQUdFUiA9Ci0gICAgICAgICAgICBDb25zdGFudHMuWE1MX1NFQ1VSSVRZX1BST1BFUlRZX01BTkFHRVI7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogc3ltYm9sIHRhYmxlLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBTWU1CT0xfVEFCTEUgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5TWU1CT0xfVEFCTEVfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogdmFsaWRhdGlvbiBtYW5hZ2VyLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBWQUxJREFUSU9OX01BTkFHRVIgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5WQUxJREFUSU9OX01BTkFHRVJfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogZ3JhbW1hciBwb29sLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxHUkFNTUFSX1BPT0wgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5YTUxHUkFNTUFSX1BPT0xfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogbG9jYWxlLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBMT0NBTEUgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5MT0NBTEVfUFJPUEVSVFk7Ci0KLSAgICAvLwotICAgIC8vIERhdGEKLSAgICAvLwotICAgIC8qKgotICAgICAqIDxwPlN0YXRlIG9mIHNlY3VyZSBtb2RlLjwvcD4KLSAgICAgKi8KLSAgICBwcml2YXRlIGJvb2xlYW4gX2lzU2VjdXJlTW9kZSA9IGZhbHNlOwotCi0gICAgLyoqCi0gICAgICogZkNvbmZpZ1VwZGF0ZWQgaXMgc2V0IHRvIHRydWUgaWYgdGhlcmUgaGFzIGJlZW4gYW55IGNoYW5nZSB0byB0aGUgY29uZmlndXJhdGlvbiBzZXR0aW5ncywKLSAgICAgKiBpLmUgYSBmZWF0dXJlIG9yIGEgcHJvcGVydHkgd2FzIGNoYW5nZWQuCi0gICAgICovCi0gICAgcHJpdmF0ZSBib29sZWFuIGZDb25maWdVcGRhdGVkID0gdHJ1ZTsKLQotICAgIC8qKgotICAgICAqIFRyYWNrcyB3aGV0aGVyIHRoZSB2YWxpZGF0b3Igc2hvdWxkIHVzZSBjb21wb25lbnRzIGZyb20KLSAgICAgKiB0aGUgZ3JhbW1hciBwb29sIHRvIHRoZSBleGNsdXNpb24gb2YgYWxsIG90aGVycy4KLSAgICAgKi8KLSAgICBwcml2YXRlIGJvb2xlYW4gZlVzZUdyYW1tYXJQb29sT25seTsKLQotICAgIC8qKiBMb29rdXAgbWFwIGZvciBjb21wb25lbnRzIHJlcXVpcmVkIGZvciB2YWxpZGF0aW9uLiAqKi8KLSAgICBwcml2YXRlIGZpbmFsIEhhc2hNYXAgZkNvbXBvbmVudHMgPSBuZXcgSGFzaE1hcCgpOwotCi0gICAgLy8KLSAgICAvLyBDb21wb25lbnRzCi0gICAgLy8KLQotICAgIC8qKiBFbnRpdHkgbWFuYWdlci4gKi8KLSAgICBwcml2YXRlIFhNTEVudGl0eU1hbmFnZXIgZkVudGl0eU1hbmFnZXI7Ci0KLSAgICAvKiogRXJyb3IgcmVwb3J0ZXIuICovCi0gICAgcHJpdmF0ZSBYTUxFcnJvclJlcG9ydGVyIGZFcnJvclJlcG9ydGVyOwotCi0gICAgLyoqIE5hbWVzcGFjZSBjb250ZXh0LiAqLwotICAgIHByaXZhdGUgTmFtZXNwYWNlQ29udGV4dCBmTmFtZXNwYWNlQ29udGV4dDsKLQotICAgIC8qKiBYTUwgU2NoZW1hIHZhbGlkYXRvci4gKi8KLSAgICBwcml2YXRlIFhNTFNjaGVtYVZhbGlkYXRvciBmU2NoZW1hVmFsaWRhdG9yOwotCi0gICAgLyoqIFZhbGlkYXRpb24gbWFuYWdlci4gKi8KLSAgICBwcml2YXRlIFZhbGlkYXRpb25NYW5hZ2VyIGZWYWxpZGF0aW9uTWFuYWdlcjsKLQotICAgIC8vCi0gICAgLy8gQ29uZmlndXJhdGlvbgotICAgIC8vCi0KLSAgICAvKiogU3RvcmVzIGluaXRpYWwgZmVhdHVyZSB2YWx1ZXMgZm9yIHZhbGlkYXRvciByZXNldC4gKi8KLSAgICBwcml2YXRlIGZpbmFsIEhhc2hNYXAgZkluaXRGZWF0dXJlcyA9IG5ldyBIYXNoTWFwKCk7Ci0KLSAgICAvKiogU3RvcmVzIGluaXRpYWwgcHJvcGVydHkgdmFsdWVzIGZvciB2YWxpZGF0b3IgcmVzZXQuICovCi0gICAgcHJpdmF0ZSBmaW5hbCBIYXNoTWFwIGZJbml0UHJvcGVydGllcyA9IG5ldyBIYXNoTWFwKCk7Ci0KLSAgICAvKiogU3RvcmVzIHRoZSBpbml0aWFsIHNlY3VyaXR5IG1hbmFnZXIuICovCi0gICAgcHJpdmF0ZSBYTUxTZWN1cml0eU1hbmFnZXIgZkluaXRTZWN1cml0eU1hbmFnZXI7Ci0KLSAgICAvKiogU3RvcmVzIHRoZSBpbml0aWFsIHNlY3VyaXR5IHByb3BlcnR5IG1hbmFnZXIuICovCi0gICAgcHJpdmF0ZSBmaW5hbCBYTUxTZWN1cml0eVByb3BlcnR5TWFuYWdlciBmU2VjdXJpdHlQcm9wZXJ0eU1ncjsKLQotICAgIC8vCi0gICAgLy8gVXNlciBPYmplY3RzCi0gICAgLy8KLQotICAgIC8qKiBBcHBsaWNhdGlvbidzIEVycm9ySGFuZGxlci4gKiovCi0gICAgcHJpdmF0ZSBFcnJvckhhbmRsZXIgZkVycm9ySGFuZGxlciA9IG51bGw7Ci0KLSAgICAvKiogQXBwbGljYXRpb24ncyBMU1Jlc291cmNlUmVzb2x2ZXIuICovCi0gICAgcHJpdmF0ZSBMU1Jlc291cmNlUmVzb2x2ZXIgZlJlc291cmNlUmVzb2x2ZXIgPSBudWxsOwotCi0gICAgLyoqIExvY2FsZSBjaG9zZW4gYnkgdGhlIGFwcGxpY2F0aW9uLiAqLwotICAgIHByaXZhdGUgTG9jYWxlIGZMb2NhbGUgPSBudWxsOwotCi0gICAgLyoqIENvbnN0cnVjdHMgYSBjb21wb25lbnQgbWFuYWdlciBzdWl0YWJsZSBmb3IgWGVyY2VzJyBzY2hlbWEgdmFsaWRhdG9yLiAqLwotICAgIHB1YmxpYyBYTUxTY2hlbWFWYWxpZGF0b3JDb21wb25lbnRNYW5hZ2VyKFhTR3JhbW1hclBvb2xDb250YWluZXIgZ3JhbW1hckNvbnRhaW5lcikgewotICAgICAgICAvLyBzZXR1cCBjb21wb25lbnRzCi0gICAgICAgIGZFbnRpdHlNYW5hZ2VyID0gbmV3IFhNTEVudGl0eU1hbmFnZXIoKTsKLSAgICAgICAgZkNvbXBvbmVudHMucHV0KEVOVElUWV9NQU5BR0VSLCBmRW50aXR5TWFuYWdlcik7Ci0KLSAgICAgICAgZkVycm9yUmVwb3J0ZXIgPSBuZXcgWE1MRXJyb3JSZXBvcnRlcigpOwotICAgICAgICBmQ29tcG9uZW50cy5wdXQoRVJST1JfUkVQT1JURVIsIGZFcnJvclJlcG9ydGVyKTsKLQotICAgICAgICBmTmFtZXNwYWNlQ29udGV4dCA9IG5ldyBOYW1lc3BhY2VTdXBwb3J0KCk7Ci0gICAgICAgIGZDb21wb25lbnRzLnB1dChOQU1FU1BBQ0VfQ09OVEVYVCwgZk5hbWVzcGFjZUNvbnRleHQpOwotCi0gICAgICAgIGZTY2hlbWFWYWxpZGF0b3IgPSBuZXcgWE1MU2NoZW1hVmFsaWRhdG9yKCk7Ci0gICAgICAgIGZDb21wb25lbnRzLnB1dChTQ0hFTUFfVkFMSURBVE9SLCBmU2NoZW1hVmFsaWRhdG9yKTsKLQotICAgICAgICBmVmFsaWRhdGlvbk1hbmFnZXIgPSBuZXcgVmFsaWRhdGlvbk1hbmFnZXIoKTsKLSAgICAgICAgZkNvbXBvbmVudHMucHV0KFZBTElEQVRJT05fTUFOQUdFUiwgZlZhbGlkYXRpb25NYW5hZ2VyKTsKLQotICAgICAgICAvLyBzZXR1cCBvdGhlciBwcm9wZXJ0aWVzCi0gICAgICAgIGZDb21wb25lbnRzLnB1dChFTlRJVFlfUkVTT0xWRVIsIG51bGwpOwotICAgICAgICBmQ29tcG9uZW50cy5wdXQoRVJST1JfSEFORExFUiwgbnVsbCk7Ci0KLSAgICAgICAgZkNvbXBvbmVudHMucHV0KFNZTUJPTF9UQUJMRSwgbmV3IFN5bWJvbFRhYmxlKCkpOwotCi0gICAgICAgIC8vIHNldHVwIGdyYW1tYXIgcG9vbAotICAgICAgICBmQ29tcG9uZW50cy5wdXQoWE1MR1JBTU1BUl9QT09MLCBncmFtbWFyQ29udGFpbmVyLmdldEdyYW1tYXJQb29sKCkpOwotICAgICAgICBmVXNlR3JhbW1hclBvb2xPbmx5ID0gZ3JhbW1hckNvbnRhaW5lci5pc0Z1bGx5Q29tcG9zZWQoKTsKLQotICAgICAgICAvLyBhZGQgc2NoZW1hIG1lc3NhZ2UgZm9ybWF0dGVyIHRvIGVycm9yIHJlcG9ydGVyCi0gICAgICAgIGZFcnJvclJlcG9ydGVyLnB1dE1lc3NhZ2VGb3JtYXR0ZXIoWFNNZXNzYWdlRm9ybWF0dGVyLlNDSEVNQV9ET01BSU4sIG5ldyBYU01lc3NhZ2VGb3JtYXR0ZXIoKSk7Ci0KLSAgICAgICAgLy8gYWRkIGFsbCByZWNvZ25pemVkIGZlYXR1cmVzIGFuZCBwcm9wZXJ0aWVzIGFuZCBhcHBseSB0aGVpciBkZWZhdWx0cwotICAgICAgICBhZGRSZWNvZ25pemVkUGFyYW1zQW5kU2V0RGVmYXVsdHMoZkVudGl0eU1hbmFnZXIsIGdyYW1tYXJDb250YWluZXIpOwotICAgICAgICBhZGRSZWNvZ25pemVkUGFyYW1zQW5kU2V0RGVmYXVsdHMoZkVycm9yUmVwb3J0ZXIsIGdyYW1tYXJDb250YWluZXIpOwotICAgICAgICBhZGRSZWNvZ25pemVkUGFyYW1zQW5kU2V0RGVmYXVsdHMoZlNjaGVtYVZhbGlkYXRvciwgZ3JhbW1hckNvbnRhaW5lcik7Ci0KLSAgICAgICAgYm9vbGVhbiBzZWN1cmVQcm9jZXNzaW5nID0gZ3JhbW1hckNvbnRhaW5lci5nZXRGZWF0dXJlKFhNTENvbnN0YW50cy5GRUFUVVJFX1NFQ1VSRV9QUk9DRVNTSU5HKTsKLSAgICAgICAgaWYgKFN5c3RlbS5nZXRTZWN1cml0eU1hbmFnZXIoKSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBfaXNTZWN1cmVNb2RlID0gdHJ1ZTsKLSAgICAgICAgICAgIHNlY3VyZVByb2Nlc3NpbmcgPSB0cnVlOwotICAgICAgICB9Ci0KLSAgICAgICAgZkluaXRTZWN1cml0eU1hbmFnZXIgPSAoWE1MU2VjdXJpdHlNYW5hZ2VyKQotICAgICAgICAgICAgICAgIGdyYW1tYXJDb250YWluZXIuZ2V0UHJvcGVydHkoU0VDVVJJVFlfTUFOQUdFUik7Ci0gICAgICAgIGlmIChmSW5pdFNlY3VyaXR5TWFuYWdlciAhPSBudWxsICkgewotICAgICAgICAgICAgZkluaXRTZWN1cml0eU1hbmFnZXIuc2V0U2VjdXJlUHJvY2Vzc2luZyhzZWN1cmVQcm9jZXNzaW5nKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIGZJbml0U2VjdXJpdHlNYW5hZ2VyID0gbmV3IFhNTFNlY3VyaXR5TWFuYWdlcihzZWN1cmVQcm9jZXNzaW5nKTsKLSAgICAgICAgfQotCi0gICAgICAgIHNldFByb3BlcnR5KFNFQ1VSSVRZX01BTkFHRVIsIGZJbml0U2VjdXJpdHlNYW5hZ2VyKTsKLQotICAgICAgICAvL3Bhc3Mgb24gcHJvcGVydGllcyBzZXQgb24gU2NoZW1hRmFjdG9yeQotICAgICAgICBmU2VjdXJpdHlQcm9wZXJ0eU1nciA9IChYTUxTZWN1cml0eVByb3BlcnR5TWFuYWdlcikKLSAgICAgICAgICAgICAgICBncmFtbWFyQ29udGFpbmVyLmdldFByb3BlcnR5KENvbnN0YW50cy5YTUxfU0VDVVJJVFlfUFJPUEVSVFlfTUFOQUdFUik7Ci0gICAgICAgIHNldFByb3BlcnR5KFhNTF9TRUNVUklUWV9QUk9QRVJUWV9NQU5BR0VSLCBmU2VjdXJpdHlQcm9wZXJ0eU1ncik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgc3RhdGUgb2YgYSBmZWF0dXJlLgotICAgICAqCi0gICAgICogQHBhcmFtIGZlYXR1cmVJZCBUaGUgZmVhdHVyZSBpZGVudGlmaWVyLgotICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgZmVhdHVyZSBpcyBzdXBwb3J0ZWQKLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBUaHJvd24gZm9yIGNvbmZpZ3VyYXRpb24gZXJyb3IuCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluIGdlbmVyYWwsIGNvbXBvbmVudHMgc2hvdWxkCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9ubHkgdGhyb3cgdGhpcyBleGNlcHRpb24gaWYKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXQgaXMgPHN0cm9uZz5yZWFsbHk8L3N0cm9uZz4KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYSBjcml0aWNhbCBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgRmVhdHVyZVN0YXRlIGdldEZlYXR1cmVTdGF0ZShTdHJpbmcgZmVhdHVyZUlkKQotICAgICAgICAgICAgdGhyb3dzIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gewotICAgICAgICBpZiAoUEFSU0VSX1NFVFRJTkdTLmVxdWFscyhmZWF0dXJlSWQpKSB7Ci0gICAgICAgICAgICByZXR1cm4gRmVhdHVyZVN0YXRlLmlzKGZDb25maWdVcGRhdGVkKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChWQUxJREFUSU9OLmVxdWFscyhmZWF0dXJlSWQpIHx8IFNDSEVNQV9WQUxJREFUSU9OLmVxdWFscyhmZWF0dXJlSWQpKSB7Ci0gICAgICAgICAgICByZXR1cm4gRmVhdHVyZVN0YXRlLmlzKHRydWUpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKFVTRV9HUkFNTUFSX1BPT0xfT05MWS5lcXVhbHMoZmVhdHVyZUlkKSkgewotICAgICAgICAgICAgcmV0dXJuIEZlYXR1cmVTdGF0ZS5pcyhmVXNlR3JhbW1hclBvb2xPbmx5KTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChYTUxDb25zdGFudHMuRkVBVFVSRV9TRUNVUkVfUFJPQ0VTU0lORy5lcXVhbHMoZmVhdHVyZUlkKSkgewotICAgICAgICAgICAgcmV0dXJuIEZlYXR1cmVTdGF0ZS5pcyhmSW5pdFNlY3VyaXR5TWFuYWdlci5pc1NlY3VyZVByb2Nlc3NpbmcoKSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoU0NIRU1BX0VMRU1FTlRfREVGQVVMVC5lcXVhbHMoZmVhdHVyZUlkKSkgewotICAgICAgICAgICAgcmV0dXJuIEZlYXR1cmVTdGF0ZS5pcyh0cnVlKTsgLy9wcmUtY29uZGl0aW9uOiBWQUxJREFUSU9OIGFuZCBTQ0hFTUFfVkFMSURBVElPTiBhcmUgYWx3YXlzIHRydWUKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gc3VwZXIuZ2V0RmVhdHVyZVN0YXRlKGZlYXR1cmVJZCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSBzdGF0ZSBvZiBhIGZlYXR1cmUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZmVhdHVyZUlkIFRoZSB1bmlxdWUgaWRlbnRpZmllciAoVVJJKSBvZiB0aGUgZmVhdHVyZS4KLSAgICAgKiBAcGFyYW0gc3RhdGUgVGhlIHJlcXVlc3RlZCBzdGF0ZSBvZiB0aGUgZmVhdHVyZSAodHJ1ZSBvciBmYWxzZSkuCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gSWYgdGhlIHJlcXVlc3RlZCBmZWF0dXJlIGlzIG5vdCBrbm93bi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRGZWF0dXJlKFN0cmluZyBmZWF0dXJlSWQsIGJvb2xlYW4gdmFsdWUpIHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKFBBUlNFUl9TRVRUSU5HUy5lcXVhbHMoZmVhdHVyZUlkKSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24oU3RhdHVzLk5PVF9TVVBQT1JURUQsIGZlYXR1cmVJZCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAodmFsdWUgPT0gZmFsc2UgJiYgKFZBTElEQVRJT04uZXF1YWxzKGZlYXR1cmVJZCkgfHwgU0NIRU1BX1ZBTElEQVRJT04uZXF1YWxzKGZlYXR1cmVJZCkpKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbihTdGF0dXMuTk9UX1NVUFBPUlRFRCwgZmVhdHVyZUlkKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChVU0VfR1JBTU1BUl9QT09MX09OTFkuZXF1YWxzKGZlYXR1cmVJZCkgJiYgdmFsdWUgIT0gZlVzZUdyYW1tYXJQb29sT25seSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24oU3RhdHVzLk5PVF9TVVBQT1JURUQsIGZlYXR1cmVJZCk7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKFhNTENvbnN0YW50cy5GRUFUVVJFX1NFQ1VSRV9QUk9DRVNTSU5HLmVxdWFscyhmZWF0dXJlSWQpKSB7Ci0gICAgICAgICAgICBpZiAoX2lzU2VjdXJlTW9kZSAmJiAhdmFsdWUpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbihTdGF0dXMuTk9UX0FMTE9XRUQsIFhNTENvbnN0YW50cy5GRUFUVVJFX1NFQ1VSRV9QUk9DRVNTSU5HKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgZkluaXRTZWN1cml0eU1hbmFnZXIuc2V0U2VjdXJlUHJvY2Vzc2luZyh2YWx1ZSk7Ci0gICAgICAgICAgICBzZXRQcm9wZXJ0eShTRUNVUklUWV9NQU5BR0VSLCBmSW5pdFNlY3VyaXR5TWFuYWdlcik7Ci0KLSAgICAgICAgICAgIGlmICh2YWx1ZSAmJiBDb25zdGFudHMuSVNfSkRLOF9PUl9BQk9WRSkgewotICAgICAgICAgICAgICAgIGZTZWN1cml0eVByb3BlcnR5TWdyLnNldFZhbHVlKFhNTFNlY3VyaXR5UHJvcGVydHlNYW5hZ2VyLlByb3BlcnR5LkFDQ0VTU19FWFRFUk5BTF9EVEQsCi0gICAgICAgICAgICAgICAgICAgICAgICBYTUxTZWN1cml0eVByb3BlcnR5TWFuYWdlci5TdGF0ZS5GU1AsIENvbnN0YW50cy5FWFRFUk5BTF9BQ0NFU1NfREVGQVVMVF9GU1ApOwotICAgICAgICAgICAgICAgIGZTZWN1cml0eVByb3BlcnR5TWdyLnNldFZhbHVlKFhNTFNlY3VyaXR5UHJvcGVydHlNYW5hZ2VyLlByb3BlcnR5LkFDQ0VTU19FWFRFUk5BTF9TQ0hFTUEsCi0gICAgICAgICAgICAgICAgICAgICAgICBYTUxTZWN1cml0eVByb3BlcnR5TWFuYWdlci5TdGF0ZS5GU1AsIENvbnN0YW50cy5FWFRFUk5BTF9BQ0NFU1NfREVGQVVMVF9GU1ApOwotICAgICAgICAgICAgICAgIHNldFByb3BlcnR5KFhNTF9TRUNVUklUWV9QUk9QRVJUWV9NQU5BR0VSLCBmU2VjdXJpdHlQcm9wZXJ0eU1ncik7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotICAgICAgICBmQ29uZmlnVXBkYXRlZCA9IHRydWU7Ci0gICAgICAgIGZFbnRpdHlNYW5hZ2VyLnNldEZlYXR1cmUoZmVhdHVyZUlkLCB2YWx1ZSk7Ci0gICAgICAgIGZFcnJvclJlcG9ydGVyLnNldEZlYXR1cmUoZmVhdHVyZUlkLCB2YWx1ZSk7Ci0gICAgICAgIGZTY2hlbWFWYWxpZGF0b3Iuc2V0RmVhdHVyZShmZWF0dXJlSWQsIHZhbHVlKTsKLSAgICAgICAgaWYgKCFmSW5pdEZlYXR1cmVzLmNvbnRhaW5zS2V5KGZlYXR1cmVJZCkpIHsKLSAgICAgICAgICAgIGJvb2xlYW4gY3VycmVudCA9IHN1cGVyLmdldEZlYXR1cmUoZmVhdHVyZUlkKTsKLSAgICAgICAgICAgIGZJbml0RmVhdHVyZXMucHV0KGZlYXR1cmVJZCwgY3VycmVudCA/IEJvb2xlYW4uVFJVRSA6IEJvb2xlYW4uRkFMU0UpOwotICAgICAgICB9Ci0gICAgICAgIHN1cGVyLnNldEZlYXR1cmUoZmVhdHVyZUlkLCB2YWx1ZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgYSBwcm9wZXJ0eS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBwcm9wZXJ0eUlkIFRoZSBwcm9wZXJ0eSBpZGVudGlmaWVyLgotICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBwcm9wZXJ0eQotICAgICAqCi0gICAgICogQHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIFRocm93biBmb3IgY29uZmlndXJhdGlvbiBlcnJvci4KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW4gZ2VuZXJhbCwgY29tcG9uZW50cyBzaG91bGQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb25seSB0aHJvdyB0aGlzIGV4Y2VwdGlvbiBpZgotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdCBpcyA8c3Ryb25nPnJlYWxseTwvc3Ryb25nPgotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhIGNyaXRpY2FsIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyBQcm9wZXJ0eVN0YXRlIGdldFByb3BlcnR5U3RhdGUoU3RyaW5nIHByb3BlcnR5SWQpCi0gICAgICAgICAgICB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChMT0NBTEUuZXF1YWxzKHByb3BlcnR5SWQpKSB7Ci0gICAgICAgICAgICByZXR1cm4gUHJvcGVydHlTdGF0ZS5pcyhnZXRMb2NhbGUoKSk7Ci0gICAgICAgIH0KLSAgICAgICAgZmluYWwgT2JqZWN0IGNvbXBvbmVudCA9IGZDb21wb25lbnRzLmdldChwcm9wZXJ0eUlkKTsKLSAgICAgICAgaWYgKGNvbXBvbmVudCAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gUHJvcGVydHlTdGF0ZS5pcyhjb21wb25lbnQpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKGZDb21wb25lbnRzLmNvbnRhaW5zS2V5KHByb3BlcnR5SWQpKSB7Ci0gICAgICAgICAgICByZXR1cm4gUHJvcGVydHlTdGF0ZS5pcyhudWxsKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gc3VwZXIuZ2V0UHJvcGVydHlTdGF0ZShwcm9wZXJ0eUlkKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSBzdGF0ZSBvZiBhIHByb3BlcnR5LgotICAgICAqCi0gICAgICogQHBhcmFtIHByb3BlcnR5SWQgVGhlIHVuaXF1ZSBpZGVudGlmaWVyIChVUkkpIG9mIHRoZSBwcm9wZXJ0eS4KLSAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcXVlc3RlZCBzdGF0ZSBvZiB0aGUgcHJvcGVydHkuCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gSWYgdGhlIHJlcXVlc3RlZCBwcm9wZXJ0eSBpcyBub3Qga25vd24uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0UHJvcGVydHkoU3RyaW5nIHByb3BlcnR5SWQsIE9iamVjdCB2YWx1ZSkgdGhyb3dzIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gewotICAgICAgICBpZiAoIEVOVElUWV9NQU5BR0VSLmVxdWFscyhwcm9wZXJ0eUlkKSB8fCBFUlJPUl9SRVBPUlRFUi5lcXVhbHMocHJvcGVydHlJZCkgfHwKLSAgICAgICAgICAgICBOQU1FU1BBQ0VfQ09OVEVYVC5lcXVhbHMocHJvcGVydHlJZCkgfHwgU0NIRU1BX1ZBTElEQVRPUi5lcXVhbHMocHJvcGVydHlJZCkgfHwKLSAgICAgICAgICAgICBTWU1CT0xfVEFCTEUuZXF1YWxzKHByb3BlcnR5SWQpIHx8IFZBTElEQVRJT05fTUFOQUdFUi5lcXVhbHMocHJvcGVydHlJZCkgfHwKLSAgICAgICAgICAgICBYTUxHUkFNTUFSX1BPT0wuZXF1YWxzKHByb3BlcnR5SWQpKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbihTdGF0dXMuTk9UX1NVUFBPUlRFRCwgcHJvcGVydHlJZCk7Ci0gICAgICAgIH0KLSAgICAgICAgZkNvbmZpZ1VwZGF0ZWQgPSB0cnVlOwotICAgICAgICBmRW50aXR5TWFuYWdlci5zZXRQcm9wZXJ0eShwcm9wZXJ0eUlkLCB2YWx1ZSk7Ci0gICAgICAgIGZFcnJvclJlcG9ydGVyLnNldFByb3BlcnR5KHByb3BlcnR5SWQsIHZhbHVlKTsKLSAgICAgICAgZlNjaGVtYVZhbGlkYXRvci5zZXRQcm9wZXJ0eShwcm9wZXJ0eUlkLCB2YWx1ZSk7Ci0gICAgICAgIGlmIChFTlRJVFlfUkVTT0xWRVIuZXF1YWxzKHByb3BlcnR5SWQpIHx8IEVSUk9SX0hBTkRMRVIuZXF1YWxzKHByb3BlcnR5SWQpIHx8Ci0gICAgICAgICAgICAgICAgU0VDVVJJVFlfTUFOQUdFUi5lcXVhbHMocHJvcGVydHlJZCkpIHsKLSAgICAgICAgICAgIGZDb21wb25lbnRzLnB1dChwcm9wZXJ0eUlkLCB2YWx1ZSk7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoTE9DQUxFLmVxdWFscyhwcm9wZXJ0eUlkKSkgewotICAgICAgICAgICAgc2V0TG9jYWxlKChMb2NhbGUpIHZhbHVlKTsKLSAgICAgICAgICAgIGZDb21wb25lbnRzLnB1dChwcm9wZXJ0eUlkLCB2YWx1ZSk7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLSAgICAgICAgLy9jaGVjayBpZiB0aGUgcHJvcGVydHkgaXMgbWFuYWdlZCBieSBzZWN1cml0eSBtYW5hZ2VyCi0gICAgICAgIGlmIChmSW5pdFNlY3VyaXR5TWFuYWdlciA9PSBudWxsIHx8Ci0gICAgICAgICAgICAgICAgIWZJbml0U2VjdXJpdHlNYW5hZ2VyLnNldExpbWl0KHByb3BlcnR5SWQsIFhNTFNlY3VyaXR5TWFuYWdlci5TdGF0ZS5BUElQUk9QRVJUWSwgdmFsdWUpKSB7Ci0gICAgICAgICAgICAvL2NoZWNrIGlmIHRoZSBwcm9wZXJ0eSBpcyBtYW5hZ2VkIGJ5IHNlY3VyaXR5IHByb3BlcnR5IG1hbmFnZXIKLSAgICAgICAgICAgIGlmIChmU2VjdXJpdHlQcm9wZXJ0eU1nciA9PSBudWxsIHx8Ci0gICAgICAgICAgICAgICAgICAgICFmU2VjdXJpdHlQcm9wZXJ0eU1nci5zZXRWYWx1ZShwcm9wZXJ0eUlkLCBYTUxTZWN1cml0eVByb3BlcnR5TWFuYWdlci5TdGF0ZS5BUElQUk9QRVJUWSwgdmFsdWUpKSB7Ci0gICAgICAgICAgICAgICAgLy9mYWxsIGJhY2sgdG8gdGhlIGV4aXN0aW5nIHByb3BlcnR5IG1hbmFnZXIKLSAgICAgICAgICAgICAgICBpZiAoIWZJbml0UHJvcGVydGllcy5jb250YWluc0tleShwcm9wZXJ0eUlkKSkgewotICAgICAgICAgICAgICAgICAgICBmSW5pdFByb3BlcnRpZXMucHV0KHByb3BlcnR5SWQsIHN1cGVyLmdldFByb3BlcnR5KHByb3BlcnR5SWQpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgc3VwZXIuc2V0UHJvcGVydHkocHJvcGVydHlJZCwgdmFsdWUpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQWRkcyBhbGwgb2YgdGhlIGNvbXBvbmVudCdzIHJlY29nbml6ZWQgZmVhdHVyZXMgYW5kIHByb3BlcnRpZXMKLSAgICAgKiB0byB0aGUgbGlzdCBvZiBkZWZhdWx0IHJlY29nbml6ZWQgZmVhdHVyZXMgYW5kIHByb3BlcnRpZXMsIGFuZAotICAgICAqIHNldHMgZGVmYXVsdCB2YWx1ZXMgb24gdGhlIGNvbmZpZ3VyYXRpb24gZm9yIGZlYXR1cmVzIGFuZAotICAgICAqIHByb3BlcnRpZXMgd2hpY2ggd2VyZSBwcmV2aW91c2x5IGFic2VudCBmcm9tIHRoZSBjb25maWd1cmF0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIGNvbXBvbmVudCBUaGUgY29tcG9uZW50IHdob3NlIHJlY29nbml6ZWQgZmVhdHVyZXMKLSAgICAgKiBhbmQgcHJvcGVydGllcyB3aWxsIGJlIGFkZGVkIHRvIHRoZSBjb25maWd1cmF0aW9uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgYWRkUmVjb2duaXplZFBhcmFtc0FuZFNldERlZmF1bHRzKFhNTENvbXBvbmVudCBjb21wb25lbnQsIFhTR3JhbW1hclBvb2xDb250YWluZXIgZ3JhbW1hckNvbnRhaW5lcikgewotCi0gICAgICAgIC8vIHJlZ2lzdGVyIGNvbXBvbmVudCdzIHJlY29nbml6ZWQgZmVhdHVyZXMKLSAgICAgICAgZmluYWwgU3RyaW5nW10gcmVjb2duaXplZEZlYXR1cmVzID0gY29tcG9uZW50LmdldFJlY29nbml6ZWRGZWF0dXJlcygpOwotICAgICAgICBhZGRSZWNvZ25pemVkRmVhdHVyZXMocmVjb2duaXplZEZlYXR1cmVzKTsKLQotICAgICAgICAvLyByZWdpc3RlciBjb21wb25lbnQncyByZWNvZ25pemVkIHByb3BlcnRpZXMKLSAgICAgICAgZmluYWwgU3RyaW5nW10gcmVjb2duaXplZFByb3BlcnRpZXMgPSBjb21wb25lbnQuZ2V0UmVjb2duaXplZFByb3BlcnRpZXMoKTsKLSAgICAgICAgYWRkUmVjb2duaXplZFByb3BlcnRpZXMocmVjb2duaXplZFByb3BlcnRpZXMpOwotCi0gICAgICAgIC8vIHNldCBkZWZhdWx0IHZhbHVlcwotICAgICAgICBzZXRGZWF0dXJlRGVmYXVsdHMoY29tcG9uZW50LCByZWNvZ25pemVkRmVhdHVyZXMsIGdyYW1tYXJDb250YWluZXIpOwotICAgICAgICBzZXRQcm9wZXJ0eURlZmF1bHRzKGNvbXBvbmVudCwgcmVjb2duaXplZFByb3BlcnRpZXMpOwotICAgIH0KLQotICAgIC8qKiBDYWxscyByZXNldCBvbiBlYWNoIG9mIHRoZSBjb21wb25lbnRzIG93bmVkIGJ5IHRoaXMgY29tcG9uZW50IG1hbmFnZXIuICoqLwotICAgIHB1YmxpYyB2b2lkIHJlc2V0KCkgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIGZOYW1lc3BhY2VDb250ZXh0LnJlc2V0KCk7Ci0gICAgICAgIGZWYWxpZGF0aW9uTWFuYWdlci5yZXNldCgpOwotICAgICAgICBmRW50aXR5TWFuYWdlci5yZXNldCh0aGlzKTsKLSAgICAgICAgZkVycm9yUmVwb3J0ZXIucmVzZXQodGhpcyk7Ci0gICAgICAgIGZTY2hlbWFWYWxpZGF0b3IucmVzZXQodGhpcyk7Ci0gICAgICAgIC8vIE1hcmsgY29uZmlndXJhdGlvbiBhcyBmaXhlZC4KLSAgICAgICAgZkNvbmZpZ1VwZGF0ZWQgPSBmYWxzZTsKLSAgICB9Ci0KLSAgICB2b2lkIHNldEVycm9ySGFuZGxlcihFcnJvckhhbmRsZXIgZXJyb3JIYW5kbGVyKSB7Ci0gICAgICAgIGZFcnJvckhhbmRsZXIgPSBlcnJvckhhbmRsZXI7Ci0gICAgICAgIHNldFByb3BlcnR5KEVSUk9SX0hBTkRMRVIsIChlcnJvckhhbmRsZXIgIT0gbnVsbCkgPyBuZXcgRXJyb3JIYW5kbGVyV3JhcHBlcihlcnJvckhhbmRsZXIpIDoKLSAgICAgICAgICAgICAgICBuZXcgRXJyb3JIYW5kbGVyV3JhcHBlcihEcmFjb25pYW5FcnJvckhhbmRsZXIuZ2V0SW5zdGFuY2UoKSkpOwotICAgIH0KLQotICAgIEVycm9ySGFuZGxlciBnZXRFcnJvckhhbmRsZXIoKSB7Ci0gICAgICAgIHJldHVybiBmRXJyb3JIYW5kbGVyOwotICAgIH0KLQotICAgIHZvaWQgc2V0UmVzb3VyY2VSZXNvbHZlcihMU1Jlc291cmNlUmVzb2x2ZXIgcmVzb3VyY2VSZXNvbHZlcikgewotICAgICAgICBmUmVzb3VyY2VSZXNvbHZlciA9IHJlc291cmNlUmVzb2x2ZXI7Ci0gICAgICAgIHNldFByb3BlcnR5KEVOVElUWV9SRVNPTFZFUiwgbmV3IERPTUVudGl0eVJlc29sdmVyV3JhcHBlcihyZXNvdXJjZVJlc29sdmVyKSk7Ci0gICAgfQotCi0gICAgTFNSZXNvdXJjZVJlc29sdmVyIGdldFJlc291cmNlUmVzb2x2ZXIoKSB7Ci0gICAgICAgIHJldHVybiBmUmVzb3VyY2VSZXNvbHZlcjsKLSAgICB9Ci0KLSAgICB2b2lkIHNldExvY2FsZShMb2NhbGUgbG9jYWxlKSB7Ci0gICAgICAgIGZMb2NhbGUgPSBsb2NhbGU7Ci0gICAgICAgIGZFcnJvclJlcG9ydGVyLnNldExvY2FsZShsb2NhbGUpOwotICAgIH0KLQotICAgIExvY2FsZSBnZXRMb2NhbGUoKSB7Ci0gICAgICAgIHJldHVybiBmTG9jYWxlOwotICAgIH0KLQotICAgIC8qKiBDbGVhbnMgb3V0IGNvbmZpZ3VyYXRpb24sIHJlc3RvcmluZyBpdCB0byBpdHMgaW5pdGlhbCBzdGF0ZS4gKi8KLSAgICB2b2lkIHJlc3RvcmVJbml0aWFsU3RhdGUoKSB7Ci0gICAgICAgIGZDb25maWdVcGRhdGVkID0gdHJ1ZTsKLQotICAgICAgICAvLyBSZW1vdmUgZXJyb3IgcmVzb2x2ZXIgYW5kIGVycm9yIGhhbmRsZXIKLSAgICAgICAgZkNvbXBvbmVudHMucHV0KEVOVElUWV9SRVNPTFZFUiwgbnVsbCk7Ci0gICAgICAgIGZDb21wb25lbnRzLnB1dChFUlJPUl9IQU5ETEVSLCBudWxsKTsKLQotICAgICAgICAvLyBTZXQgdGhlIExvY2FsZSBiYWNrIHRvIG51bGwuCi0gICAgICAgIHNldExvY2FsZShudWxsKTsKLSAgICAgICAgZkNvbXBvbmVudHMucHV0KExPQ0FMRSwgbnVsbCk7Ci0KLSAgICAgICAgLy8gUmVzdG9yZSBpbml0aWFsIHNlY3VyaXR5IG1hbmFnZXIKLSAgICAgICAgZkNvbXBvbmVudHMucHV0KFNFQ1VSSVRZX01BTkFHRVIsIGZJbml0U2VjdXJpdHlNYW5hZ2VyKTsKLQotICAgICAgICAvLyBTZXQgdGhlIExvY2FsZSBiYWNrIHRvIG51bGwuCi0gICAgICAgIHNldExvY2FsZShudWxsKTsKLSAgICAgICAgZkNvbXBvbmVudHMucHV0KExPQ0FMRSwgbnVsbCk7Ci0KLSAgICAgICAgLy8gUmVzZXQgZmVhdHVyZSBhbmQgcHJvcGVydHkgdmFsdWVzIHRvIHRoZWlyIGluaXRpYWwgdmFsdWVzCi0gICAgICAgIGlmICghZkluaXRGZWF0dXJlcy5pc0VtcHR5KCkpIHsKLSAgICAgICAgICAgIEl0ZXJhdG9yIGl0ZXIgPSBmSW5pdEZlYXR1cmVzLmVudHJ5U2V0KCkuaXRlcmF0b3IoKTsKLSAgICAgICAgICAgIHdoaWxlIChpdGVyLmhhc05leHQoKSkgewotICAgICAgICAgICAgICAgIE1hcC5FbnRyeSBlbnRyeSA9IChNYXAuRW50cnkpIGl0ZXIubmV4dCgpOwotICAgICAgICAgICAgICAgIFN0cmluZyBuYW1lID0gKFN0cmluZykgZW50cnkuZ2V0S2V5KCk7Ci0gICAgICAgICAgICAgICAgYm9vbGVhbiB2YWx1ZSA9ICgoQm9vbGVhbikgZW50cnkuZ2V0VmFsdWUoKSkuYm9vbGVhblZhbHVlKCk7Ci0gICAgICAgICAgICAgICAgc3VwZXIuc2V0RmVhdHVyZShuYW1lLCB2YWx1ZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmSW5pdEZlYXR1cmVzLmNsZWFyKCk7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKCFmSW5pdFByb3BlcnRpZXMuaXNFbXB0eSgpKSB7Ci0gICAgICAgICAgICBJdGVyYXRvciBpdGVyID0gZkluaXRQcm9wZXJ0aWVzLmVudHJ5U2V0KCkuaXRlcmF0b3IoKTsKLSAgICAgICAgICAgIHdoaWxlIChpdGVyLmhhc05leHQoKSkgewotICAgICAgICAgICAgICAgIE1hcC5FbnRyeSBlbnRyeSA9IChNYXAuRW50cnkpIGl0ZXIubmV4dCgpOwotICAgICAgICAgICAgICAgIFN0cmluZyBuYW1lID0gKFN0cmluZykgZW50cnkuZ2V0S2V5KCk7Ci0gICAgICAgICAgICAgICAgT2JqZWN0IHZhbHVlID0gZW50cnkuZ2V0VmFsdWUoKTsKLSAgICAgICAgICAgICAgICBzdXBlci5zZXRQcm9wZXJ0eShuYW1lLCB2YWx1ZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmSW5pdFByb3BlcnRpZXMuY2xlYXIoKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKiBTZXRzIGZlYXR1cmUgZGVmYXVsdHMgZm9yIHRoZSBnaXZlbiBjb21wb25lbnQgb24gdGhpcyBjb25maWd1cmF0aW9uLiAqLwotICAgIHByaXZhdGUgdm9pZCBzZXRGZWF0dXJlRGVmYXVsdHMoZmluYWwgWE1MQ29tcG9uZW50IGNvbXBvbmVudCwKLSAgICAgICAgICAgIGZpbmFsIFN0cmluZyBbXSByZWNvZ25pemVkRmVhdHVyZXMsIFhTR3JhbW1hclBvb2xDb250YWluZXIgZ3JhbW1hckNvbnRhaW5lcikgewotICAgICAgICBpZiAocmVjb2duaXplZEZlYXR1cmVzICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVjb2duaXplZEZlYXR1cmVzLmxlbmd0aDsgKytpKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIGZlYXR1cmVJZCA9IHJlY29nbml6ZWRGZWF0dXJlc1tpXTsKLSAgICAgICAgICAgICAgICBCb29sZWFuIHN0YXRlID0gZ3JhbW1hckNvbnRhaW5lci5nZXRGZWF0dXJlKGZlYXR1cmVJZCk7Ci0gICAgICAgICAgICAgICAgaWYgKHN0YXRlID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgc3RhdGUgPSBjb21wb25lbnQuZ2V0RmVhdHVyZURlZmF1bHQoZmVhdHVyZUlkKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaWYgKHN0YXRlICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gRG8gbm90IG92ZXJ3cml0ZSB2YWx1ZXMgYWxyZWFkeSBzZXQgb24gdGhlIGNvbmZpZ3VyYXRpb24uCi0gICAgICAgICAgICAgICAgICAgIGlmICghZkZlYXR1cmVzLmNvbnRhaW5zS2V5KGZlYXR1cmVJZCkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZGZWF0dXJlcy5wdXQoZmVhdHVyZUlkLCBzdGF0ZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBGb3IgbmV3bHkgYWRkZWQgY29tcG9uZW50cyB3aG8gcmVjb2duaXplIHRoaXMgZmVhdHVyZQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gYnV0IGRpZCBub3Qgb2ZmZXIgYSBkZWZhdWx0IHZhbHVlLCB3ZSBuZWVkIHRvIG1ha2UKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIHN1cmUgdGhlc2UgY29tcG9uZW50cyB3aWxsIGdldCBhbiBvcHBvcnR1bml0eSB0byByZWFkCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGUgdmFsdWUgYmVmb3JlIHBhcnNpbmcgYmVnaW5zLgotICAgICAgICAgICAgICAgICAgICAgICAgZkNvbmZpZ1VwZGF0ZWQgPSB0cnVlOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqIFNldHMgcHJvcGVydHkgZGVmYXVsdHMgZm9yIHRoZSBnaXZlbiBjb21wb25lbnQgb24gdGhpcyBjb25maWd1cmF0aW9uLiAqLwotICAgIHByaXZhdGUgdm9pZCBzZXRQcm9wZXJ0eURlZmF1bHRzKGZpbmFsIFhNTENvbXBvbmVudCBjb21wb25lbnQsIGZpbmFsIFN0cmluZyBbXSByZWNvZ25pemVkUHJvcGVydGllcykgewotICAgICAgICBpZiAocmVjb2duaXplZFByb3BlcnRpZXMgIT0gbnVsbCkgewotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZWNvZ25pemVkUHJvcGVydGllcy5sZW5ndGg7ICsraSkgewotICAgICAgICAgICAgICAgIFN0cmluZyBwcm9wZXJ0eUlkID0gcmVjb2duaXplZFByb3BlcnRpZXNbaV07Ci0gICAgICAgICAgICAgICAgT2JqZWN0IHZhbHVlID0gY29tcG9uZW50LmdldFByb3BlcnR5RGVmYXVsdChwcm9wZXJ0eUlkKTsKLSAgICAgICAgICAgICAgICBpZiAodmFsdWUgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAvLyBEbyBub3Qgb3ZlcndyaXRlIHZhbHVlcyBhbHJlYWR5IHNldCBvbiB0aGUgY29uZmlndXJhdGlvbi4KLSAgICAgICAgICAgICAgICAgICAgaWYgKCFmUHJvcGVydGllcy5jb250YWluc0tleShwcm9wZXJ0eUlkKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgZlByb3BlcnRpZXMucHV0KHByb3BlcnR5SWQsIHZhbHVlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIEZvciBuZXdseSBhZGRlZCBjb21wb25lbnRzIHdobyByZWNvZ25pemUgdGhpcyBwcm9wZXJ0eQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gYnV0IGRpZCBub3Qgb2ZmZXIgYSBkZWZhdWx0IHZhbHVlLCB3ZSBuZWVkIHRvIG1ha2UKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIHN1cmUgdGhlc2UgY29tcG9uZW50cyB3aWxsIGdldCBhbiBvcHBvcnR1bml0eSB0byByZWFkCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGUgdmFsdWUgYmVmb3JlIHBhcnNpbmcgYmVnaW5zLgotICAgICAgICAgICAgICAgICAgICAgICAgZkNvbmZpZ1VwZGF0ZWQgPSB0cnVlOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi19IC8vIFhNTFNjaGVtYVZhbGlkYXRvckNvbXBvbmVudE1hbmFnZXIKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2pheHAvdmFsaWRhdGlvbi9YU0dyYW1tYXJQb29sQ29udGFpbmVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9qYXhwL3ZhbGlkYXRpb24vWFNHcmFtbWFyUG9vbENvbnRhaW5lci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3OWVmNTU5Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL2pheHAvdmFsaWRhdGlvbi9YU0dyYW1tYXJQb29sQ29udGFpbmVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3NSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmpheHAudmFsaWRhdGlvbjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLmdyYW1tYXJzLlhNTEdyYW1tYXJQb29sOwotCi0vKioKLSAqIDxwPkEgY29udGFpbmVyIGZvciBncmFtbWFyIHBvb2xzIHdoaWNoIG9ubHkgY29udGFpbiBzY2hlbWEgZ3JhbW1hcnMuPC9wPgotICoKLSAqIEBhdXRob3IgTWljaGFlbCBHbGF2YXNzZXZpY2gsIElCTQotICogQHZlcnNpb24gJElkOiBYU0dyYW1tYXJQb29sQ29udGFpbmVyLmphdmEsdiAxLjYgMjAxMC0xMS0wMSAwNDo0MDowOCBqb2VodyBFeHAgJAotICovCi1wdWJsaWMgaW50ZXJmYWNlIFhTR3JhbW1hclBvb2xDb250YWluZXIgewotCi0gICAgLyoqCi0gICAgICogPHA+UmV0dXJucyB0aGUgZ3JhbW1hciBwb29sIGNvbnRhaW5lZCBpbnNpZGUgdGhlIGNvbnRhaW5lci48L3A+Ci0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRoZSBncmFtbWFyIHBvb2wgY29udGFpbmVkIGluc2lkZSB0aGUgY29udGFpbmVyCi0gICAgICovCi0gICAgcHVibGljIFhNTEdyYW1tYXJQb29sIGdldEdyYW1tYXJQb29sKCk7Ci0KLSAgICAvKioKLSAgICAgKiA8cD5SZXR1cm5zIHdoZXRoZXIgdGhlIHNjaGVtYSBjb21wb25lbnRzIGNvbnRhaW5lZCBpbiB0aGlzIG9iamVjdAotICAgICAqIGNhbiBiZSBjb25zaWRlcmVkIHRvIGJlIGEgZnVsbHkgY29tcG9zZWQgc2NoZW1hIGFuZCBzaG91bGQgYmUKLSAgICAgKiB1c2VkIHRvIHRoZSBleGNsdXNpb24gb2Ygb3RoZXIgc2NoZW1hIGNvbXBvbmVudHMgd2hpY2ggbWF5IGJlCi0gICAgICogcHJlc2VudCBlbHNld2hlcmUuPC9wPgotICAgICAqCi0gICAgICogQHJldHVybiB3aGV0aGVyIHRoZSBzY2hlbWEgY29tcG9uZW50cyBjb250YWluZWQgaW4gdGhpcyBvYmplY3QKLSAgICAgKiBjYW4gYmUgY29uc2lkZXJlZCB0byBiZSBhIGZ1bGx5IGNvbXBvc2VkIHNjaGVtYQotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzRnVsbHlDb21wb3NlZCgpOwotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgaW5pdGlhbCB2YWx1ZSBvZiBhIGZlYXR1cmUgZm9yIHZhbGlkYXRvcnMgY3JlYXRlZAotICAgICAqIHVzaW5nIHRoaXMgZ3JhbW1hciBwb29sIGNvbnRhaW5lciBvciBudWxsIGlmIHRoZSB2YWxpZGF0b3JzCi0gICAgICogc2hvdWxkIHVzZSB0aGUgZGVmYXVsdCB2YWx1ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgQm9vbGVhbiBnZXRGZWF0dXJlKFN0cmluZyBmZWF0dXJlSWQpOwotCi0gICAgLyoKLSAgICAgKiBTZXQgYSBmZWF0dXJlIG9uIHRoZSBzY2hlbWEKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRGZWF0dXJlKFN0cmluZyBmZWF0dXJlSWQsIGJvb2xlYW4gc3RhdGUpOwotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgaW5pdGlhbCB2YWx1ZSBvZiBhIHByb3BlcnR5IGZvciB2YWxpZGF0b3JzIGNyZWF0ZWQKLSAgICAgKiB1c2luZyB0aGlzIGdyYW1tYXIgcG9vbCBjb250YWluZXIgb3IgbnVsbCBpZiB0aGUgdmFsaWRhdG9ycwotICAgICAqIHNob3VsZCB1c2UgdGhlIGRlZmF1bHQgdmFsdWUuCi0gICAgICovCi0gICAgcHVibGljIE9iamVjdCBnZXRQcm9wZXJ0eShTdHJpbmcgcHJvcGVydHlJZCk7Ci0KLSAgICAvKgotICAgICAqIFNldCBhIHByb3BlcnR5IG9uIHRoZSBzY2hlbWEKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRQcm9wZXJ0eShTdHJpbmcgcHJvcGVydHlJZCwgT2JqZWN0IHN0YXRlKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvamF4cC92YWxpZGF0aW9uL2phdmF4LnhtbC52YWxpZGF0aW9uLlNjaGVtYUZhY3RvcnkgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9qYXhwL3ZhbGlkYXRpb24vamF2YXgueG1sLnZhbGlkYXRpb24uU2NoZW1hRmFjdG9yeQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNTFkMzNhNi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9qYXhwL3ZhbGlkYXRpb24vamF2YXgueG1sLnZhbGlkYXRpb24uU2NoZW1hRmFjdG9yeQorKysgL2Rldi9udWxsCkBAIC0xICswLDAgQEAKLWNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuamF4cC52YWxpZGF0aW9uLlhNTFNjaGVtYUZhY3RvcnkKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3BhcnNlcnMvQWJzdHJhY3RET01QYXJzZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3BhcnNlcnMvQWJzdHJhY3RET01QYXJzZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggODhlYTk1MS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9wYXJzZXJzL0Fic3RyYWN0RE9NUGFyc2VyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyNjU3ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5wYXJzZXJzOwotCi1pbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKLWltcG9ydCBqYXZhLnV0aWwuU3RhY2s7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbS5BdHRySW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbS5Db3JlRG9jdW1lbnRJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tLkRPTUVycm9ySW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbS5ET01NZXNzYWdlRm9ybWF0dGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tLkRlZmVycmVkRG9jdW1lbnRJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tLkRvY3VtZW50SW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbS5Eb2N1bWVudFR5cGVJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tLkVsZW1lbnREZWZpbml0aW9uSW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbS5FbGVtZW50SW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbS5FbGVtZW50TlNJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tLkVudGl0eUltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5kb20uRW50aXR5UmVmZXJlbmNlSW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbS5Ob2RlSW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbS5Ob3RhdGlvbkltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5kb20uUFNWSUF0dHJOU0ltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5kb20uUFNWSURvY3VtZW50SW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbS5QU1ZJRWxlbWVudE5TSW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbS5UZXh0SW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5YU1NpbXBsZVR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLkRPTUVycm9ySGFuZGxlcldyYXBwZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuQXVnbWVudGF0aW9uczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5OYW1lc3BhY2VDb250ZXh0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlFOYW1lOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTEF0dHJpYnV0ZXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MTG9jYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxSZXNvdXJjZUlkZW50aWZpZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MU3RyaW5nOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhOSUV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MUGFyc2VyQ29uZmlndXJhdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLkF0dHJpYnV0ZVBTVkk7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5FbGVtZW50UFNWSTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTVHlwZURlZmluaXRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlscy5PYmplY3RGYWN0b3J5OwotaW1wb3J0IG9yZy53M2MuZG9tLkF0dHI7Ci1pbXBvcnQgb3JnLnczYy5kb20uQ0RBVEFTZWN0aW9uOwotaW1wb3J0IG9yZy53M2MuZG9tLkNvbW1lbnQ7Ci1pbXBvcnQgb3JnLnczYy5kb20uRE9NRXJyb3I7Ci1pbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7Ci1pbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnRUeXBlOwotaW1wb3J0IG9yZy53M2MuZG9tLkVsZW1lbnQ7Ci1pbXBvcnQgb3JnLnczYy5kb20uRW50aXR5UmVmZXJlbmNlOwotaW1wb3J0IG9yZy53M2MuZG9tLk5hbWVkTm9kZU1hcDsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGVMaXN0OwotaW1wb3J0IG9yZy53M2MuZG9tLlByb2Nlc3NpbmdJbnN0cnVjdGlvbjsKLWltcG9ydCBvcmcudzNjLmRvbS5UZXh0OwotaW1wb3J0IG9yZy53M2MuZG9tLmxzLkxTUGFyc2VyRmlsdGVyOwotaW1wb3J0IG9yZy53M2MuZG9tLnRyYXZlcnNhbC5Ob2RlRmlsdGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKLQotLyoqCi0gKiBUaGlzIGlzIHRoZSBiYXNlIGNsYXNzIG9mIGFsbCBET00gcGFyc2Vycy4gSXQgaW1wbGVtZW50cyB0aGUgWE5JCi0gKiBjYWxsYmFjayBtZXRob2RzIHRvIGNyZWF0ZSB0aGUgRE9NIHRyZWUuIEFmdGVyIGEgc3VjY2Vzc2Z1bCBwYXJzZSBvZgotICogYW4gWE1MIGRvY3VtZW50LCB0aGUgRE9NIERvY3VtZW50IG9iamVjdCBjYW4gYmUgcXVlcmllZCB1c2luZyB0aGUKLSAqIDxjb2RlPmdldERvY3VtZW50PC9jb2RlPiBtZXRob2QuIFRoZSBhY3R1YWwgcGlwZWxpbmUgaXMgZGVmaW5lZCBpbgotICogcGFyc2VyIGNvbmZpZ3VyYXRpb24uCi0gKgotICogQGF1dGhvciBBcm5hdWQgTGUgSG9ycywgSUJNCi0gKiBAYXV0aG9yIEFuZHkgQ2xhcmssIElCTQotICogQGF1dGhvciBFbGVuYSBMaXRhbmksIElCTQotICoKLSAqIEB2ZXJzaW9uICRJZDogQWJzdHJhY3RET01QYXJzZXIuamF2YSx2IDEuMTAgMjAxMC0xMS0wMSAwNDo0MDowOSBqb2VodyBFeHAgJAotICovCi1wdWJsaWMgY2xhc3MgQWJzdHJhY3RET01QYXJzZXIgZXh0ZW5kcyBBYnN0cmFjdFhNTERvY3VtZW50UGFyc2VyIHsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RhbnRzCi0gICAgLy8KLQotICAgIC8vIGZlYXR1cmUgaWRzCi0KLSAgICAvKiogRmVhdHVyZSBpZDogbmFtZXNwYWNlLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIE5BTUVTUEFDRVMgPQotICAgIENvbnN0YW50cy5TQVhfRkVBVFVSRV9QUkVGSVgrQ29uc3RhbnRzLk5BTUVTUEFDRVNfRkVBVFVSRTsKLQotICAgIC8qKiBGZWF0dXJlIGlkOiBjcmVhdGUgZW50aXR5IHJlZiBub2Rlcy4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBDUkVBVEVfRU5USVRZX1JFRl9OT0RFUyA9Ci0gICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5DUkVBVEVfRU5USVRZX1JFRl9OT0RFU19GRUFUVVJFOwotCi0gICAgLyoqIEZlYXR1cmUgaWQ6IGluY2x1ZGUgY29tbWVudHMuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgSU5DTFVERV9DT01NRU5UU19GRUFUVVJFID0KLSAgICBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLklOQ0xVREVfQ09NTUVOVFNfRkVBVFVSRTsKLQotICAgIC8qKiBGZWF0dXJlIGlkOiBjcmVhdGUgY2RhdGEgbm9kZXMuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ1JFQVRFX0NEQVRBX05PREVTX0ZFQVRVUkUgPQotICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuQ1JFQVRFX0NEQVRBX05PREVTX0ZFQVRVUkU7Ci0KLSAgICAvKiogRmVhdHVyZSBpZDogaW5jbHVkZSBpZ25vcmFibGUgd2hpdGVzcGFjZS4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBJTkNMVURFX0lHTk9SQUJMRV9XSElURVNQQUNFID0KLSAgICBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLklOQ0xVREVfSUdOT1JBQkxFX1dISVRFU1BBQ0U7Ci0KLSAgICAvKiogRmVhdHVyZSBpZDogZGVmZXIgbm9kZSBleHBhbnNpb24uICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgREVGRVJfTk9ERV9FWFBBTlNJT04gPQotICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuREVGRVJfTk9ERV9FWFBBTlNJT05fRkVBVFVSRTsKLQotCi0gICAgLyoqIFJlY29nbml6ZWQgZmVhdHVyZXMuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nW10gUkVDT0dOSVpFRF9GRUFUVVJFUyA9IHsKLSAgICAgICAgTkFNRVNQQUNFUywKLSAgICAgICAgQ1JFQVRFX0VOVElUWV9SRUZfTk9ERVMsCi0gICAgICAgIElOQ0xVREVfQ09NTUVOVFNfRkVBVFVSRSwKLSAgICAgICAgQ1JFQVRFX0NEQVRBX05PREVTX0ZFQVRVUkUsCi0gICAgICAgIElOQ0xVREVfSUdOT1JBQkxFX1dISVRFU1BBQ0UsCi0gICAgICAgIERFRkVSX05PREVfRVhQQU5TSU9OCi0gICAgfTsKLQotICAgIC8vIHByb3BlcnR5IGlkcwotCi0gICAgLyoqIFByb3BlcnR5IGlkOiBkb2N1bWVudCBjbGFzcyBuYW1lLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIERPQ1VNRU5UX0NMQVNTX05BTUUgPQotICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLkRPQ1VNRU5UX0NMQVNTX05BTUVfUFJPUEVSVFk7Ci0KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyAgQ1VSUkVOVF9FTEVNRU5UX05PREU9Ci0gICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuQ1VSUkVOVF9FTEVNRU5UX05PREVfUFJPUEVSVFk7Ci0KLSAgICAvLyBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBHUkFNTUFSX1BPT0wgPQotICAgIC8vIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLlhNTEdSQU1NQVJfUE9PTF9QUk9QRVJUWTsKLQotICAgIC8qKiBSZWNvZ25pemVkIHByb3BlcnRpZXMuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nW10gUkVDT0dOSVpFRF9QUk9QRVJUSUVTID0gewotICAgICAgICBET0NVTUVOVF9DTEFTU19OQU1FLAotICAgICAgICBDVVJSRU5UX0VMRU1FTlRfTk9ERSwKLSAgICB9OwotCi0gICAgLy8gb3RoZXIKLQotICAgIC8qKiBEZWZhdWx0IGRvY3VtZW50IGNsYXNzIG5hbWUuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgREVGQVVMVF9ET0NVTUVOVF9DTEFTU19OQU1FID0KLSAgICAiY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5kb20uRG9jdW1lbnRJbXBsIjsKLQotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIENPUkVfRE9DVU1FTlRfQ0xBU1NfTkFNRSA9Ci0gICAgImNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tLkNvcmVEb2N1bWVudEltcGwiOwotCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgUFNWSV9ET0NVTUVOVF9DTEFTU19OQU1FID0KLSAgICAiY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5kb20uUFNWSURvY3VtZW50SW1wbCI7Ci0KLSAgICAvKioKLSAgICAgKiBJZiB0aGUgdXNlciBzdG9wcyB0aGUgcHJvY2VzcywgdGhpcyBleGNlcHRpb24gd2lsbCBiZSB0aHJvd24uCi0gICAgICovCi0gICAgc3RhdGljIGZpbmFsIGNsYXNzIEFib3J0IGV4dGVuZHMgUnVudGltZUV4Y2VwdGlvbiB7Ci0gICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDE2ODc4NDg5OTQ5NzY4MDg0OTBMOwotICAgICAgICBzdGF0aWMgZmluYWwgQWJvcnQgSU5TVEFOQ0UgPSBuZXcgQWJvcnQoKTsKLSAgICAgICAgcHJpdmF0ZSBBYm9ydCgpIHt9Ci0gICAgICAgIHB1YmxpYyBUaHJvd2FibGUgZmlsbEluU3RhY2tUcmFjZSgpIHsKLSAgICAgICAgICAgIHJldHVybiB0aGlzOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLy8gZGVidWdnaW5nCi0KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIERFQlVHX0VWRU5UUyA9IGZhbHNlOwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW4gREVCVUdfQkFTRVVSSSA9IGZhbHNlOwotCi0gICAgLy8KLSAgICAvLyBEYXRhCi0gICAgLy8KLQotICAgIC8qKiBET00gTDMgZXJyb3IgaGFuZGxlciAqLwotICAgIHByb3RlY3RlZCBET01FcnJvckhhbmRsZXJXcmFwcGVyIGZFcnJvckhhbmRsZXIgPSBudWxsOwotCi0gICAgLyoqIFRydWUgaWYgaW5zaWRlIERURC4gKi8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBmSW5EVEQ7Ci0KLSAgICAvLyBmZWF0dXJlcwotCi0gICAgLyoqIENyZWF0ZSBlbnRpdHkgcmVmZXJlbmNlIG5vZGVzLiAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIGZDcmVhdGVFbnRpdHlSZWZOb2RlczsKLQotICAgIC8qKiBJbmNsdWRlIGlnbm9yYWJsZSB3aGl0ZXNwYWNlLiAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIGZJbmNsdWRlSWdub3JhYmxlV2hpdGVzcGFjZTsKLQotICAgIC8qKiBJbmNsdWRlIENvbW1lbnRzLiAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIGZJbmNsdWRlQ29tbWVudHM7Ci0KLSAgICAvKiogQ3JlYXRlIGNkYXRhIG5vZGVzLiAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIGZDcmVhdGVDREFUQU5vZGVzOwotCi0gICAgLy8gZG9tIGluZm9ybWF0aW9uCi0KLSAgICAvKiogVGhlIGRvY3VtZW50LiAqLwotICAgIHByb3RlY3RlZCBEb2N1bWVudCBmRG9jdW1lbnQ7Ci0KLSAgICAvKiogVGhlIGRlZmF1bHQgWGVyY2VzIGRvY3VtZW50IGltcGxlbWVudGF0aW9uLCBpZiB1c2VkLiAqLwotICAgIHByb3RlY3RlZCBDb3JlRG9jdW1lbnRJbXBsIGZEb2N1bWVudEltcGw7Ci0KLSAgICAvKiogV2hldGhlciB0byBzdG9yZSBQU1ZJIGluZm9ybWF0aW9uIGluIERPTSB0cmVlLiAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIGZTdG9yZVBTVkk7Ci0KLSAgICAvKiogVGhlIGRvY3VtZW50IGNsYXNzIG5hbWUgdG8gdXNlLiAqLwotICAgIHByb3RlY3RlZCBTdHJpbmcgIGZEb2N1bWVudENsYXNzTmFtZTsKLQotICAgIC8qKiBUaGUgZG9jdW1lbnQgdHlwZSBub2RlLiAqLwotICAgIHByb3RlY3RlZCBEb2N1bWVudFR5cGUgZkRvY3VtZW50VHlwZTsKLQotICAgIC8qKiBDdXJyZW50IG5vZGUuICovCi0gICAgcHJvdGVjdGVkIE5vZGUgZkN1cnJlbnROb2RlOwotICAgIHByb3RlY3RlZCBDREFUQVNlY3Rpb24gZkN1cnJlbnRDREFUQVNlY3Rpb247Ci0gICAgcHJvdGVjdGVkIEVudGl0eUltcGwgZkN1cnJlbnRFbnRpdHlEZWNsOwotICAgIHByb3RlY3RlZCBpbnQgZkRlZmVycmVkRW50aXR5RGVjbDsKLQotICAgIC8qKiBDaGFyYWN0ZXIgYnVmZmVyICovCi0gICAgcHJvdGVjdGVkIGZpbmFsIFN0cmluZ0J1aWxkZXIgZlN0cmluZ0J1aWxkZXIgPSBuZXcgU3RyaW5nQnVpbGRlciAoNTApOwotCi0gICAgLy8gaW50ZXJuYWwgc3Vic2V0Ci0KLSAgICAvKiogSW50ZXJuYWwgc3Vic2V0IGJ1ZmZlci4gKi8KLSAgICBwcm90ZWN0ZWQgU3RyaW5nQnVpbGRlciBmSW50ZXJuYWxTdWJzZXQ7Ci0KLSAgICAvLyBkZWZlcnJlZCBleHBhbnNpb24gZGF0YQotCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gICAgICAgICAgICAgIGZEZWZlck5vZGVFeHBhbnNpb247Ci0gICAgcHJvdGVjdGVkIGJvb2xlYW4gICAgICAgICAgICAgIGZOYW1lc3BhY2VBd2FyZTsKLSAgICBwcm90ZWN0ZWQgRGVmZXJyZWREb2N1bWVudEltcGwgZkRlZmVycmVkRG9jdW1lbnRJbXBsOwotICAgIHByb3RlY3RlZCBpbnQgICAgICAgICAgICAgICAgICBmRG9jdW1lbnRJbmRleDsKLSAgICBwcm90ZWN0ZWQgaW50ICAgICAgICAgICAgICAgICAgZkRvY3VtZW50VHlwZUluZGV4OwotICAgIHByb3RlY3RlZCBpbnQgICAgICAgICAgICAgICAgICBmQ3VycmVudE5vZGVJbmRleDsKLSAgICBwcm90ZWN0ZWQgaW50ICAgICAgICAgICAgICAgICAgZkN1cnJlbnRDREFUQVNlY3Rpb25JbmRleDsKLQotICAgIC8vIHN0YXRlCi0KLSAgICAvKiogVHJ1ZSBpZiBpbnNpZGUgRFREIGV4dGVybmFsIHN1YnNldC4gKi8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBmSW5EVERFeHRlcm5hbFN1YnNldDsKLQotICAgIC8qKiBSb290IGVsZW1lbnQgbm9kZS4gKi8KLSAgICBwcm90ZWN0ZWQgTm9kZSBmUm9vdDsKLQotICAgIC8qKiBUcnVlIGlmIGluc2lkZSBDREFUQSBzZWN0aW9uLiAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIGZJbkNEQVRBU2VjdGlvbjsKLQotICAgIC8qKiBUcnVlIGlmIHNhdyB0aGUgZmlyc3QgY2h1bmsgb2YgY2hhcmFjdGVycyovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZkZpcnN0Q2h1bmsgPSBmYWxzZTsKLQotCi0gICAgLyoqIExTUGFyc2VyRmlsdGVyOiBzcGVjaWZpZXMgdGhhdCBlbGVtZW50IHdpdGggZ2l2ZW4gUU5BTUUgYW5kIGFsbCBpdHMgY2hpbGRyZW4KLSAgICAgKiBtdXN0IGJlIHJlamVjdGVkICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZkZpbHRlclJlamVjdCA9IGZhbHNlOwotCi0gICAgLy8gZGF0YQotCi0gICAgLyoqIEJhc2UgdXJpIHN0YWNrKi8KLSAgICBwcm90ZWN0ZWQgZmluYWwgU3RhY2sgZkJhc2VVUklTdGFjayA9IG5ldyBTdGFjayAoKTsKLQotICAgIC8qKiBMU1BhcnNlckZpbHRlcjogdHJhY2tzIHRoZSBlbGVtZW50IGRlcHRoIHdpdGhpbiBhIHJlamVjdGVkIHN1YnRyZWUuICovCi0gICAgcHJvdGVjdGVkIGludCBmUmVqZWN0ZWRFbGVtZW50RGVwdGggPSAwOwotCi0gICAgLyoqIExTUGFyc2VyRmlsdGVyOiBzdG9yZSBkZXB0aCBvZiBza2lwcGVkIGVsZW1lbnRzICovCi0gICAgcHJvdGVjdGVkIFN0YWNrIGZTa2lwcGVkRWxlbVN0YWNrID0gbnVsbDsKLQotICAgIC8qKiBMU1BhcnNlckZpbHRlcjogdHJ1ZSBpZiBpbnNpZGUgZW50aXR5IHJlZmVyZW5jZSAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIGZJbkVudGl0eVJlZiA9IGZhbHNlOwotCi0gICAgLyoqIEF0dHJpYnV0ZSBRTmFtZS4gKi8KLSAgICBwcml2YXRlIGZpbmFsIFFOYW1lIGZBdHRyUU5hbWUgPSBuZXcgUU5hbWUoKTsKLQotICAgIC8qKiBEb2N1bWVudCBsb2NhdG9yLiAqLwotICAgIHByaXZhdGUgWE1MTG9jYXRvciBmTG9jYXRvcjsKLQotICAgIC8vIGhhbmRsZXJzCi0KLSAgICBwcm90ZWN0ZWQgTFNQYXJzZXJGaWx0ZXIgZkRPTUZpbHRlciA9IG51bGw7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0cnVjdG9ycwotICAgIC8vCi0KLSAgICAvKiogRGVmYXVsdCBjb25zdHJ1Y3Rvci4gKi8KLSAgICBwcm90ZWN0ZWQgQWJzdHJhY3RET01QYXJzZXIgKFhNTFBhcnNlckNvbmZpZ3VyYXRpb24gY29uZmlnKSB7Ci0KLSAgICAgICAgc3VwZXIgKGNvbmZpZyk7Ci0KLQotICAgICAgICAvLyBhZGQgcmVjb2duaXplZCBmZWF0dXJlcwotICAgICAgICBmQ29uZmlndXJhdGlvbi5hZGRSZWNvZ25pemVkRmVhdHVyZXMgKFJFQ09HTklaRURfRkVBVFVSRVMpOwotCi0gICAgICAgIC8vIHNldCBkZWZhdWx0IHZhbHVlcwotICAgICAgICBmQ29uZmlndXJhdGlvbi5zZXRGZWF0dXJlIChDUkVBVEVfRU5USVRZX1JFRl9OT0RFUywgdHJ1ZSk7Ci0gICAgICAgIGZDb25maWd1cmF0aW9uLnNldEZlYXR1cmUgKElOQ0xVREVfSUdOT1JBQkxFX1dISVRFU1BBQ0UsIHRydWUpOwotICAgICAgICBmQ29uZmlndXJhdGlvbi5zZXRGZWF0dXJlIChERUZFUl9OT0RFX0VYUEFOU0lPTiwgdHJ1ZSk7Ci0gICAgICAgIGZDb25maWd1cmF0aW9uLnNldEZlYXR1cmUgKElOQ0xVREVfQ09NTUVOVFNfRkVBVFVSRSwgdHJ1ZSk7Ci0gICAgICAgIGZDb25maWd1cmF0aW9uLnNldEZlYXR1cmUgKENSRUFURV9DREFUQV9OT0RFU19GRUFUVVJFLCB0cnVlKTsKLQotICAgICAgICAvLyBhZGQgcmVjb2duaXplZCBwcm9wZXJ0aWVzCi0gICAgICAgIGZDb25maWd1cmF0aW9uLmFkZFJlY29nbml6ZWRQcm9wZXJ0aWVzIChSRUNPR05JWkVEX1BST1BFUlRJRVMpOwotCi0gICAgICAgIC8vIHNldCBkZWZhdWx0IHZhbHVlcwotICAgICAgICBmQ29uZmlndXJhdGlvbi5zZXRQcm9wZXJ0eSAoRE9DVU1FTlRfQ0xBU1NfTkFNRSwKLSAgICAgICAgREVGQVVMVF9ET0NVTUVOVF9DTEFTU19OQU1FKTsKLQotICAgIH0gLy8gPGluaXQ+KFhNTFBhcnNlckNvbmZpZ3VyYXRpb24pCi0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCByZXRyaWV2ZXMgdGhlIG5hbWUgb2YgY3VycmVudCBkb2N1bWVudCBjbGFzcy4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgU3RyaW5nIGdldERvY3VtZW50Q2xhc3NOYW1lICgpIHsKLSAgICAgICAgcmV0dXJuIGZEb2N1bWVudENsYXNzTmFtZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBhbGxvd3MgdGhlIHByb2dyYW1tZXIgdG8gZGVjaWRlIHdoaWNoIGRvY3VtZW50Ci0gICAgICogZmFjdG9yeSB0byB1c2Ugd2hlbiBjb25zdHJ1Y3RpbmcgdGhlIERPTSB0cmVlLiBIb3dldmVyLCBkb2luZwotICAgICAqIHNvIHdpbGwgbG9zZSB0aGUgZnVuY3Rpb25hbGl0eSBvZiB0aGUgZGVmYXVsdCBmYWN0b3J5LiBBbHNvLAotICAgICAqIGEgZG9jdW1lbnQgY2xhc3Mgb3RoZXIgdGhhbiB0aGUgZGVmYXVsdCB3aWxsIGxvc2UgdGhlIGFiaWxpdHkKLSAgICAgKiB0byBkZWZlciBub2RlIGV4cGFuc2lvbiBvbiB0aGUgRE9NIHRyZWUgcHJvZHVjZWQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZG9jdW1lbnRDbGFzc05hbWUgVGhlIGZ1bGx5IHF1YWxpZmllZCBjbGFzcyBuYW1lIG9mIHRoZQotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGRvY3VtZW50IGZhY3RvcnkgdG8gdXNlIHdoZW4gY29uc3RydWN0aW5nCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgdGhlIERPTSB0cmVlLgotICAgICAqCi0gICAgICogQHNlZSAjZ2V0RG9jdW1lbnRDbGFzc05hbWUKLSAgICAgKiBAc2VlICNERUZBVUxUX0RPQ1VNRU5UX0NMQVNTX05BTUUKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCBzZXREb2N1bWVudENsYXNzTmFtZSAoU3RyaW5nIGRvY3VtZW50Q2xhc3NOYW1lKSB7Ci0KLSAgICAgICAgLy8gbm9ybWFsaXplIGNsYXNzIG5hbWUKLSAgICAgICAgaWYgKGRvY3VtZW50Q2xhc3NOYW1lID09IG51bGwpIHsKLSAgICAgICAgICAgIGRvY3VtZW50Q2xhc3NOYW1lID0gREVGQVVMVF9ET0NVTUVOVF9DTEFTU19OQU1FOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKCFkb2N1bWVudENsYXNzTmFtZS5lcXVhbHMoREVGQVVMVF9ET0NVTUVOVF9DTEFTU19OQU1FKSAmJgotICAgICAgICAgICAgIWRvY3VtZW50Q2xhc3NOYW1lLmVxdWFscyhQU1ZJX0RPQ1VNRU5UX0NMQVNTX05BTUUpKSB7Ci0gICAgICAgICAgICAvLyB2ZXJpZnkgdGhhdCB0aGlzIGNsYXNzIGV4aXN0cyBhbmQgaXMgb2YgdGhlIHJpZ2h0IHR5cGUKLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgQ2xhc3MgX2NsYXNzID0gT2JqZWN0RmFjdG9yeS5maW5kUHJvdmlkZXJDbGFzcyAoZG9jdW1lbnRDbGFzc05hbWUsIHRydWUpOwotICAgICAgICAgICAgICAgIC8vaWYgKCFfY2xhc3MuaXNBc3NpZ25hYmxlRnJvbShEb2N1bWVudC5jbGFzcykpIHsKLSAgICAgICAgICAgICAgICBpZiAoIURvY3VtZW50LmNsYXNzLmlzQXNzaWduYWJsZUZyb20gKF9jbGFzcykpIHsKLSAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiAoCi0gICAgICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoCi0gICAgICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAiSW52YWxpZERvY3VtZW50Q2xhc3NOYW1lIiwgbmV3IE9iamVjdCBbXSB7ZG9jdW1lbnRDbGFzc05hbWV9KSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gKAotICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoCi0gICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgIk1pc3NpbmdEb2N1bWVudENsYXNzTmFtZSIsIG5ldyBPYmplY3QgW10ge2RvY3VtZW50Q2xhc3NOYW1lfSkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gc2V0IGRvY3VtZW50IGNsYXNzIG5hbWUKLSAgICAgICAgZkRvY3VtZW50Q2xhc3NOYW1lID0gZG9jdW1lbnRDbGFzc05hbWU7Ci0gICAgICAgIGlmICghZG9jdW1lbnRDbGFzc05hbWUuZXF1YWxzIChERUZBVUxUX0RPQ1VNRU5UX0NMQVNTX05BTUUpKSB7Ci0gICAgICAgICAgICBmRGVmZXJOb2RlRXhwYW5zaW9uID0gZmFsc2U7Ci0gICAgICAgIH0KLQotICAgIH0gLy8gc2V0RG9jdW1lbnRDbGFzc05hbWUoU3RyaW5nKQotCi0gICAgLy8KLSAgICAvLyBQdWJsaWMgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKiogUmV0dXJucyB0aGUgRE9NIGRvY3VtZW50IG9iamVjdC4gKi8KLSAgICBwdWJsaWMgRG9jdW1lbnQgZ2V0RG9jdW1lbnQgKCkgewotICAgICAgICByZXR1cm4gZkRvY3VtZW50OwotICAgIH0gLy8gZ2V0RG9jdW1lbnQoKTpEb2N1bWVudAotCi0gICAgLyoqCi0gICAgICogRHJvcHMgYWxsIHJlZmVyZW5jZXMgdG8gdGhlIGxhc3QgRE9NIHdoaWNoIHdhcyBidWlsdCBieSB0aGlzIHBhcnNlci4KLSAgICAgKi8KLSAgICBwdWJsaWMgZmluYWwgdm9pZCBkcm9wRG9jdW1lbnRSZWZlcmVuY2VzKCkgewotICAgICAgICBmRG9jdW1lbnQgPSBudWxsOwotICAgICAgICBmRG9jdW1lbnRJbXBsID0gbnVsbDsKLSAgICAgICAgZkRlZmVycmVkRG9jdW1lbnRJbXBsID0gbnVsbDsKLSAgICAgICAgZkRvY3VtZW50VHlwZSA9IG51bGw7Ci0gICAgICAgIGZDdXJyZW50Tm9kZSA9IG51bGw7Ci0gICAgICAgIGZDdXJyZW50Q0RBVEFTZWN0aW9uID0gbnVsbDsKLSAgICAgICAgZkN1cnJlbnRFbnRpdHlEZWNsID0gbnVsbDsKLSAgICAgICAgZlJvb3QgPSBudWxsOwotICAgIH0gLy8gZHJvcERvY3VtZW50UmVmZXJlbmNlcygpCi0KLSAgICAvLwotICAgIC8vIFhNTERvY3VtZW50UGFyc2VyIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogUmVzZXRzIHRoZSBwYXJzZXIgc3RhdGUuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBUaHJvd24gb24gaW5pdGlhbGl6YXRpb24gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcmVzZXQgKCkgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIHN1cGVyLnJlc2V0ICgpOwotCi0KLSAgICAgICAgLy8gZ2V0IGZlYXR1cmUgc3RhdGUKLSAgICAgICAgZkNyZWF0ZUVudGl0eVJlZk5vZGVzID0KLSAgICAgICAgZkNvbmZpZ3VyYXRpb24uZ2V0RmVhdHVyZSAoQ1JFQVRFX0VOVElUWV9SRUZfTk9ERVMpOwotCi0gICAgICAgIGZJbmNsdWRlSWdub3JhYmxlV2hpdGVzcGFjZSA9Ci0gICAgICAgIGZDb25maWd1cmF0aW9uLmdldEZlYXR1cmUgKElOQ0xVREVfSUdOT1JBQkxFX1dISVRFU1BBQ0UpOwotCi0gICAgICAgIGZEZWZlck5vZGVFeHBhbnNpb24gPQotICAgICAgICBmQ29uZmlndXJhdGlvbi5nZXRGZWF0dXJlIChERUZFUl9OT0RFX0VYUEFOU0lPTik7Ci0KLSAgICAgICAgZk5hbWVzcGFjZUF3YXJlID0gZkNvbmZpZ3VyYXRpb24uZ2V0RmVhdHVyZSAoTkFNRVNQQUNFUyk7Ci0KLSAgICAgICAgZkluY2x1ZGVDb21tZW50cyA9IGZDb25maWd1cmF0aW9uLmdldEZlYXR1cmUgKElOQ0xVREVfQ09NTUVOVFNfRkVBVFVSRSk7Ci0KLSAgICAgICAgZkNyZWF0ZUNEQVRBTm9kZXMgPSBmQ29uZmlndXJhdGlvbi5nZXRGZWF0dXJlIChDUkVBVEVfQ0RBVEFfTk9ERVNfRkVBVFVSRSk7Ci0KLSAgICAgICAgLy8gZ2V0IHByb3BlcnR5Ci0gICAgICAgIHNldERvY3VtZW50Q2xhc3NOYW1lICgoU3RyaW5nKQotICAgICAgICBmQ29uZmlndXJhdGlvbi5nZXRQcm9wZXJ0eSAoRE9DVU1FTlRfQ0xBU1NfTkFNRSkpOwotCi0gICAgICAgIC8vIHJlc2V0IGRvbSBpbmZvcm1hdGlvbgotICAgICAgICBmRG9jdW1lbnQgPSBudWxsOwotICAgICAgICBmRG9jdW1lbnRJbXBsID0gbnVsbDsKLSAgICAgICAgZlN0b3JlUFNWSSA9IGZhbHNlOwotICAgICAgICBmRG9jdW1lbnRUeXBlID0gbnVsbDsKLSAgICAgICAgZkRvY3VtZW50VHlwZUluZGV4ID0gLTE7Ci0gICAgICAgIGZEZWZlcnJlZERvY3VtZW50SW1wbCA9IG51bGw7Ci0gICAgICAgIGZDdXJyZW50Tm9kZSA9IG51bGw7Ci0KLSAgICAgICAgLy8gcmVzZXQgc3RyaW5nIGJ1ZmZlcgotICAgICAgICBmU3RyaW5nQnVpbGRlci5zZXRMZW5ndGggKDApOwotCi0gICAgICAgIC8vIHJlc2V0IHN0YXRlIGluZm9ybWF0aW9uCi0gICAgICAgIGZSb290ID0gbnVsbDsKLSAgICAgICAgZkluRFREID0gZmFsc2U7Ci0gICAgICAgIGZJbkRUREV4dGVybmFsU3Vic2V0ID0gZmFsc2U7Ci0gICAgICAgIGZJbkNEQVRBU2VjdGlvbiA9IGZhbHNlOwotICAgICAgICBmRmlyc3RDaHVuayA9IGZhbHNlOwotICAgICAgICBmQ3VycmVudENEQVRBU2VjdGlvbiA9IG51bGw7Ci0gICAgICAgIGZDdXJyZW50Q0RBVEFTZWN0aW9uSW5kZXggPSAtMTsKLQotICAgICAgICBmQmFzZVVSSVN0YWNrLnJlbW92ZUFsbEVsZW1lbnRzICgpOwotCi0KLSAgICB9IC8vIHJlc2V0KCkKLQotICAgIC8qKgotICAgICAqIFNldCB0aGUgbG9jYWxlIHRvIHVzZSBmb3IgbWVzc2FnZXMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbG9jYWxlIFRoZSBsb2NhbGUgb2JqZWN0IHRvIHVzZSBmb3IgbG9jYWxpemF0aW9uIG9mIG1lc3NhZ2VzLgotICAgICAqCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0TG9jYWxlIChMb2NhbGUgbG9jYWxlKSB7Ci0gICAgICAgIGZDb25maWd1cmF0aW9uLnNldExvY2FsZSAobG9jYWxlKTsKLQotICAgIH0gLy8gc2V0TG9jYWxlKExvY2FsZSkKLQotICAgIC8vCi0gICAgLy8gWE1MRG9jdW1lbnRIYW5kbGVyIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2Qgbm90aWZpZXMgdGhlIHN0YXJ0IG9mIGEgZ2VuZXJhbCBlbnRpdHkuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGlzIG1ldGhvZCBpcyBub3QgY2FsbGVkIGZvciBlbnRpdHkgcmVmZXJlbmNlcwotICAgICAqIGFwcGVhcmluZyBhcyBwYXJ0IG9mIGF0dHJpYnV0ZSB2YWx1ZXMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSAgICAgVGhlIG5hbWUgb2YgdGhlIGdlbmVyYWwgZW50aXR5LgotICAgICAqIEBwYXJhbSBpZGVudGlmaWVyIFRoZSByZXNvdXJjZSBpZGVudGlmaWVyLgotICAgICAqIEBwYXJhbSBlbmNvZGluZyBUaGUgYXV0by1kZXRlY3RlZCBJQU5BIGVuY29kaW5nIG5hbWUgb2YgdGhlIGVudGl0eQotICAgICAqICAgICAgICAgICAgICAgICBzdHJlYW0uIFRoaXMgdmFsdWUgd2lsbCBiZSBudWxsIGluIHRob3NlIHNpdHVhdGlvbnMKLSAgICAgKiAgICAgICAgICAgICAgICAgd2hlcmUgdGhlIGVudGl0eSBlbmNvZGluZyBpcyBub3QgYXV0by1kZXRlY3RlZCAoZS5nLgotICAgICAqICAgICAgICAgICAgICAgICBpbnRlcm5hbCBlbnRpdGllcyBvciBhIGRvY3VtZW50IGVudGl0eSB0aGF0IGlzCi0gICAgICogICAgICAgICAgICAgICAgIHBhcnNlZCBmcm9tIGEgamF2YS5pby5SZWFkZXIpLgotICAgICAqIEBwYXJhbSBhdWdzICAgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnRHZW5lcmFsRW50aXR5IChTdHJpbmcgbmFtZSwKLSAgICBYTUxSZXNvdXJjZUlkZW50aWZpZXIgaWRlbnRpZmllciwKLSAgICBTdHJpbmcgZW5jb2RpbmcsIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKERFQlVHX0VWRU5UUykgewotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuICgiPT0+c3RhcnRHZW5lcmFsRW50aXR5ICgiK25hbWUrIikiKTsKLSAgICAgICAgICAgIGlmIChERUJVR19CQVNFVVJJKSB7Ci0gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuICgiICAgZXhwYW5kZWRTeXN0ZW1JZCggKipiYXNlVVJJKTogIitpZGVudGlmaWVyLmdldEV4cGFuZGVkU3lzdGVtSWQgKCkpOwotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbiAoIiAgIGJhc2VVUkk6IisgaWRlbnRpZmllci5nZXRCYXNlU3lzdGVtSWQgKCkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gQWx3YXlzIGNyZWF0ZSBlbnRpdHkgcmVmZXJlbmNlIG5vZGVzIHRvIGJlIGFibGUgdG8gcmVjcmVhdGUKLSAgICAgICAgLy8gZW50aXR5IGFzIGEgcGFydCBvZiBkb2N0eXBlCi0gICAgICAgIGlmICghZkRlZmVyTm9kZUV4cGFuc2lvbikgewotICAgICAgICAgICAgaWYgKGZGaWx0ZXJSZWplY3QpIHsKLSAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBzZXRDaGFyYWN0ZXJEYXRhICh0cnVlKTsKLSAgICAgICAgICAgIEVudGl0eVJlZmVyZW5jZSBlciA9IGZEb2N1bWVudC5jcmVhdGVFbnRpdHlSZWZlcmVuY2UgKG5hbWUpOwotICAgICAgICAgICAgaWYgKGZEb2N1bWVudEltcGwgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIC8vIFJFVklTSVQ6IGJhc2VVUkkvYWN0dWFsRW5jb2RpbmcKLSAgICAgICAgICAgICAgICAvLyAgICAgICAgIHJlbW92ZSBkZXBlbmRlbmN5IG9uIG91ciBpbXBsZW1lbnRhdGlvbiB3aGVuIERPTSBMMyBpcyBSRUMKLSAgICAgICAgICAgICAgICAvLwotCi0gICAgICAgICAgICAgICAgRW50aXR5UmVmZXJlbmNlSW1wbCBlckltcGwgPShFbnRpdHlSZWZlcmVuY2VJbXBsKWVyOwotCi0gICAgICAgICAgICAgICAgLy8gc2V0IGJhc2UgdXJpCi0gICAgICAgICAgICAgICAgZXJJbXBsLnNldEJhc2VVUkkgKGlkZW50aWZpZXIuZ2V0RXhwYW5kZWRTeXN0ZW1JZCAoKSk7Ci0gICAgICAgICAgICAgICAgaWYgKGZEb2N1bWVudFR5cGUgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAvLyBzZXQgYWN0dWFsIGVuY29kaW5nCi0gICAgICAgICAgICAgICAgICAgIE5hbWVkTm9kZU1hcCBlbnRpdGllcyA9IGZEb2N1bWVudFR5cGUuZ2V0RW50aXRpZXMgKCk7Ci0gICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5RGVjbCA9IChFbnRpdHlJbXBsKSBlbnRpdGllcy5nZXROYW1lZEl0ZW0gKG5hbWUpOwotICAgICAgICAgICAgICAgICAgICBpZiAoZkN1cnJlbnRFbnRpdHlEZWNsICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5RGVjbC5zZXRJbnB1dEVuY29kaW5nIChlbmNvZGluZyk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvLyB3ZSBkb24ndCBuZWVkIHN5bmNocm9uaXphdGlvbiBub3csIGJlY2F1c2UgZW50aXR5IHJlZiB3aWxsIGJlCi0gICAgICAgICAgICAgICAgLy8gZXhwYW5kZWQgYW55d2F5LiBTeW5jaCBvbmx5IG5lZWRlZCB3aGVuIHVzZXIgY3JlYXRlcyBlbnRpdHlSZWYgbm9kZQotICAgICAgICAgICAgICAgIGVySW1wbC5uZWVkc1N5bmNDaGlsZHJlbiAoZmFsc2UpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZkluRW50aXR5UmVmID0gdHJ1ZTsKLSAgICAgICAgICAgIGZDdXJyZW50Tm9kZS5hcHBlbmRDaGlsZCAoZXIpOwotICAgICAgICAgICAgZkN1cnJlbnROb2RlID0gZXI7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0KLSAgICAgICAgICAgIGludCBlciA9Ci0gICAgICAgICAgICBmRGVmZXJyZWREb2N1bWVudEltcGwuY3JlYXRlRGVmZXJyZWRFbnRpdHlSZWZlcmVuY2UgKG5hbWUsIGlkZW50aWZpZXIuZ2V0RXhwYW5kZWRTeXN0ZW1JZCAoKSk7Ci0gICAgICAgICAgICBpZiAoZkRvY3VtZW50VHlwZUluZGV4ICE9IC0xKSB7Ci0gICAgICAgICAgICAgICAgLy8gZmluZCBjb3JyZXNwb25kaW5nIEVudGl0eSBkZWNsCi0gICAgICAgICAgICAgICAgaW50IG5vZGUgPSBmRGVmZXJyZWREb2N1bWVudEltcGwuZ2V0TGFzdENoaWxkIChmRG9jdW1lbnRUeXBlSW5kZXgsIGZhbHNlKTsKLSAgICAgICAgICAgICAgICB3aGlsZSAobm9kZSAhPSAtMSkgewotICAgICAgICAgICAgICAgICAgICBzaG9ydCBub2RlVHlwZSA9IGZEZWZlcnJlZERvY3VtZW50SW1wbC5nZXROb2RlVHlwZSAobm9kZSwgZmFsc2UpOwotICAgICAgICAgICAgICAgICAgICBpZiAobm9kZVR5cGUgPT0gTm9kZS5FTlRJVFlfTk9ERSkgewotICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG5vZGVOYW1lID0KLSAgICAgICAgICAgICAgICAgICAgICAgIGZEZWZlcnJlZERvY3VtZW50SW1wbC5nZXROb2RlTmFtZSAobm9kZSwgZmFsc2UpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5vZGVOYW1lLmVxdWFscyAobmFtZSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmRGVmZXJyZWRFbnRpdHlEZWNsID0gbm9kZTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmRGVmZXJyZWREb2N1bWVudEltcGwuc2V0SW5wdXRFbmNvZGluZyAobm9kZSwgZW5jb2RpbmcpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIG5vZGUgPSBmRGVmZXJyZWREb2N1bWVudEltcGwuZ2V0UmVhbFByZXZTaWJsaW5nIChub2RlLCBmYWxzZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZkRlZmVycmVkRG9jdW1lbnRJbXBsLmFwcGVuZENoaWxkIChmQ3VycmVudE5vZGVJbmRleCwgZXIpOwotICAgICAgICAgICAgZkN1cnJlbnROb2RlSW5kZXggPSBlcjsKLSAgICAgICAgfQotCi0gICAgfSAvLyBzdGFydEdlbmVyYWxFbnRpdHkoU3RyaW5nLFhNTFJlc291cmNlSWRlbnRpZmllciwgQXVnbWVudGF0aW9ucykKLQotICAgIC8qKgotICAgICAqIE5vdGlmaWVzIG9mIHRoZSBwcmVzZW5jZSBvZiBhIFRleHREZWNsIGxpbmUgaW4gYW4gZW50aXR5LiBJZiBwcmVzZW50LAotICAgICAqIHRoaXMgbWV0aG9kIHdpbGwgYmUgY2FsbGVkIGltbWVkaWF0ZWx5IGZvbGxvd2luZyB0aGUgc3RhcnRFbnRpdHkgY2FsbC4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoaXMgbWV0aG9kIHdpbGwgbmV2ZXIgYmUgY2FsbGVkIGZvciB0aGUKLSAgICAgKiBkb2N1bWVudCBlbnRpdHk7IGl0IGlzIG9ubHkgY2FsbGVkIGZvciBleHRlcm5hbCBnZW5lcmFsIGVudGl0aWVzCi0gICAgICogcmVmZXJlbmNlZCBpbiBkb2N1bWVudCBjb250ZW50LgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gVGhpcyBtZXRob2QgaXMgbm90IGNhbGxlZCBmb3IgZW50aXR5IHJlZmVyZW5jZXMKLSAgICAgKiBhcHBlYXJpbmcgYXMgcGFydCBvZiBhdHRyaWJ1dGUgdmFsdWVzLgotICAgICAqCi0gICAgICogQHBhcmFtIHZlcnNpb24gIFRoZSBYTUwgdmVyc2lvbiwgb3IgbnVsbCBpZiBub3Qgc3BlY2lmaWVkLgotICAgICAqIEBwYXJhbSBlbmNvZGluZyBUaGUgSUFOQSBlbmNvZGluZyBuYW1lIG9mIHRoZSBlbnRpdHkuCi0gICAgICogQHBhcmFtIGF1Z3MgICAgICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRleHREZWNsIChTdHJpbmcgdmVyc2lvbiwgU3RyaW5nIGVuY29kaW5nLCBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBpZiAoZkluRFREKXsKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotICAgICAgICBpZiAoIWZEZWZlck5vZGVFeHBhbnNpb24pIHsKLSAgICAgICAgICAgIGlmIChmQ3VycmVudEVudGl0eURlY2wgIT0gbnVsbCAmJiAhZkZpbHRlclJlamVjdCkgewotICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5RGVjbC5zZXRYbWxFbmNvZGluZyAoZW5jb2RpbmcpOwotICAgICAgICAgICAgICAgIGlmICh2ZXJzaW9uICE9IG51bGwpCi0gICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5RGVjbC5zZXRYbWxWZXJzaW9uICh2ZXJzaW9uKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIGlmIChmRGVmZXJyZWRFbnRpdHlEZWNsICE9LTEpIHsKLSAgICAgICAgICAgICAgICBmRGVmZXJyZWREb2N1bWVudEltcGwuc2V0RW50aXR5SW5mbyAoZkRlZmVycmVkRW50aXR5RGVjbCwgdmVyc2lvbiwgZW5jb2RpbmcpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfSAvLyB0ZXh0RGVjbChTdHJpbmcsU3RyaW5nKQotCi0gICAgLyoqCi0gICAgICogQSBjb21tZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIHRleHQgVGhlIHRleHQgaW4gdGhlIGNvbW1lbnQuCi0gICAgICogQHBhcmFtIGF1Z3MgICAgICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGFwcGxpY2F0aW9uIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBjb21tZW50IChYTUxTdHJpbmcgdGV4dCwgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKGZJbkRURCkgewotICAgICAgICAgICAgaWYgKGZJbnRlcm5hbFN1YnNldCAhPSBudWxsICYmICFmSW5EVERFeHRlcm5hbFN1YnNldCkgewotICAgICAgICAgICAgICAgIGZJbnRlcm5hbFN1YnNldC5hcHBlbmQgKCI8IS0tIik7Ci0gICAgICAgICAgICAgICAgaWYgKHRleHQubGVuZ3RoID4gMCkgewotICAgICAgICAgICAgICAgICAgICBmSW50ZXJuYWxTdWJzZXQuYXBwZW5kICh0ZXh0LmNoLCB0ZXh0Lm9mZnNldCwgdGV4dC5sZW5ndGgpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBmSW50ZXJuYWxTdWJzZXQuYXBwZW5kICgiLS0+Iik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKCFmSW5jbHVkZUNvbW1lbnRzIHx8IGZGaWx0ZXJSZWplY3QpIHsKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotICAgICAgICBpZiAoIWZEZWZlck5vZGVFeHBhbnNpb24pIHsKLSAgICAgICAgICAgIENvbW1lbnQgY29tbWVudCA9IGZEb2N1bWVudC5jcmVhdGVDb21tZW50ICh0ZXh0LnRvU3RyaW5nICgpKTsKLQotICAgICAgICAgICAgc2V0Q2hhcmFjdGVyRGF0YSAoZmFsc2UpOwotICAgICAgICAgICAgZkN1cnJlbnROb2RlLmFwcGVuZENoaWxkIChjb21tZW50KTsKLSAgICAgICAgICAgIGlmIChmRE9NRmlsdGVyICE9bnVsbCAmJiAhZkluRW50aXR5UmVmICYmCi0gICAgICAgICAgICAoZkRPTUZpbHRlci5nZXRXaGF0VG9TaG93ICgpICYgTm9kZUZpbHRlci5TSE9XX0NPTU1FTlQpIT0gMCkgewotICAgICAgICAgICAgICAgIHNob3J0IGNvZGUgPSBmRE9NRmlsdGVyLmFjY2VwdE5vZGUgKGNvbW1lbnQpOwotICAgICAgICAgICAgICAgIHN3aXRjaCAoY29kZSkgewotICAgICAgICAgICAgICAgICAgICBjYXNlIExTUGFyc2VyRmlsdGVyLkZJTFRFUl9JTlRFUlJVUFQ6ewotICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgQWJvcnQuSU5TVEFOQ0U7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgY2FzZSBMU1BhcnNlckZpbHRlci5GSUxURVJfUkVKRUNUOnsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJFVklTSVQ6IHRoZSBjb25zdGFudCBGSUxURVJfUkVKRUNUIHNob3VsZCBiZSBjaGFuZ2VkIHdoZW4gbmV3Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBET00gTFMgc3BlY3MgZ2V0cyBwdWJsaXNoZWQKLQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gZmFsbCB0aHJvdWdoIHRvIFNLSVAgc2luY2UgY29tbWVudCBoYXMgbm8gY2hpbGRyZW4uCi0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgY2FzZSBMU1BhcnNlckZpbHRlci5GSUxURVJfU0tJUDogewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gUkVWSVNJVDogdGhlIGNvbnN0YW50IEZJTFRFUl9TS0lQIHNob3VsZCBiZSBjaGFuZ2VkIHdoZW4gbmV3Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBET00gTFMgc3BlY3MgZ2V0cyBwdWJsaXNoZWQKLSAgICAgICAgICAgICAgICAgICAgICAgIGZDdXJyZW50Tm9kZS5yZW1vdmVDaGlsZCAoY29tbWVudCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBtYWtlIHN1cmUgd2UgZG9uJ3QgbG9vc2UgY2hhcnMgaWYgbmV4dCBldmVudCBpcyBjaGFyYWN0ZXJzKCkKLSAgICAgICAgICAgICAgICAgICAgICAgIGZGaXJzdENodW5rID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFjY2VwdCBub2RlCi0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIGludCBjb21tZW50ID0KLSAgICAgICAgICAgIGZEZWZlcnJlZERvY3VtZW50SW1wbC5jcmVhdGVEZWZlcnJlZENvbW1lbnQgKHRleHQudG9TdHJpbmcgKCkpOwotICAgICAgICAgICAgZkRlZmVycmVkRG9jdW1lbnRJbXBsLmFwcGVuZENoaWxkIChmQ3VycmVudE5vZGVJbmRleCwgY29tbWVudCk7Ci0gICAgICAgIH0KLQotICAgIH0gLy8gY29tbWVudChYTUxTdHJpbmcpCi0KLSAgICAvKioKLSAgICAgKiBBIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24uIFByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb25zIGNvbnNpc3Qgb2YgYQotICAgICAqIHRhcmdldCBuYW1lIGFuZCwgb3B0aW9uYWxseSwgdGV4dCBkYXRhLiBUaGUgZGF0YSBpcyBvbmx5IG1lYW5pbmdmdWwKLSAgICAgKiB0byB0aGUgYXBwbGljYXRpb24uCi0gICAgICogPHA+Ci0gICAgICogVHlwaWNhbGx5LCBhIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24ncyBkYXRhIHdpbGwgY29udGFpbiBhIHNlcmllcwotICAgICAqIG9mIHBzZXVkby1hdHRyaWJ1dGVzLiBUaGVzZSBwc2V1ZG8tYXR0cmlidXRlcyBmb2xsb3cgdGhlIGZvcm0gb2YKLSAgICAgKiBlbGVtZW50IGF0dHJpYnV0ZXMgYnV0IGFyZSA8c3Ryb25nPm5vdDwvc3Ryb25nPiBwYXJzZWQgb3IgcHJlc2VudGVkCi0gICAgICogdG8gdGhlIGFwcGxpY2F0aW9uIGFzIGFueXRoaW5nIG90aGVyIHRoYW4gdGV4dC4gVGhlIGFwcGxpY2F0aW9uIGlzCi0gICAgICogcmVzcG9uc2libGUgZm9yIHBhcnNpbmcgdGhlIGRhdGEuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdGFyZ2V0IFRoZSB0YXJnZXQuCi0gICAgICogQHBhcmFtIGRhdGEgICBUaGUgZGF0YSBvciBudWxsIGlmIG5vbmUgc3BlY2lmaWVkLgotICAgICAqIEBwYXJhbSBhdWdzICAgICAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24gKFN0cmluZyB0YXJnZXQsIFhNTFN0cmluZyBkYXRhLCBBdWdtZW50YXRpb25zIGF1Z3MpCi0gICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgaWYgKGZJbkRURCkgewotICAgICAgICAgICAgaWYgKGZJbnRlcm5hbFN1YnNldCAhPSBudWxsICYmICFmSW5EVERFeHRlcm5hbFN1YnNldCkgewotICAgICAgICAgICAgICAgIGZJbnRlcm5hbFN1YnNldC5hcHBlbmQgKCI8PyIpOwotICAgICAgICAgICAgICAgIGZJbnRlcm5hbFN1YnNldC5hcHBlbmQgKHRhcmdldCk7Ci0gICAgICAgICAgICAgICAgaWYgKGRhdGEubGVuZ3RoID4gMCkgewotICAgICAgICAgICAgICAgICAgICBmSW50ZXJuYWxTdWJzZXQuYXBwZW5kICgnICcpLmFwcGVuZCAoZGF0YS5jaCwgZGF0YS5vZmZzZXQsIGRhdGEubGVuZ3RoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZkludGVybmFsU3Vic2V0LmFwcGVuZCAoIj8+Iik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoREVCVUdfRVZFTlRTKSB7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4gKCI9PT5wcm9jZXNzaW5nSW5zdHJ1Y3Rpb24gKCIrdGFyZ2V0KyIpIik7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKCFmRGVmZXJOb2RlRXhwYW5zaW9uKSB7Ci0gICAgICAgICAgICBpZiAoZkZpbHRlclJlamVjdCkgewotICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIFByb2Nlc3NpbmdJbnN0cnVjdGlvbiBwaSA9Ci0gICAgICAgICAgICBmRG9jdW1lbnQuY3JlYXRlUHJvY2Vzc2luZ0luc3RydWN0aW9uICh0YXJnZXQsIGRhdGEudG9TdHJpbmcgKCkpOwotCi0KLSAgICAgICAgICAgIHNldENoYXJhY3RlckRhdGEgKGZhbHNlKTsKLSAgICAgICAgICAgIGZDdXJyZW50Tm9kZS5hcHBlbmRDaGlsZCAocGkpOwotICAgICAgICAgICAgaWYgKGZET01GaWx0ZXIgIT1udWxsICYmICFmSW5FbnRpdHlSZWYgJiYKLSAgICAgICAgICAgIChmRE9NRmlsdGVyLmdldFdoYXRUb1Nob3cgKCkgJiBOb2RlRmlsdGVyLlNIT1dfUFJPQ0VTU0lOR19JTlNUUlVDVElPTikhPSAwKSB7Ci0gICAgICAgICAgICAgICAgc2hvcnQgY29kZSA9IGZET01GaWx0ZXIuYWNjZXB0Tm9kZSAocGkpOwotICAgICAgICAgICAgICAgIHN3aXRjaCAoY29kZSkgewotICAgICAgICAgICAgICAgICAgICBjYXNlIExTUGFyc2VyRmlsdGVyLkZJTFRFUl9JTlRFUlJVUFQ6ewotICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgQWJvcnQuSU5TVEFOQ0U7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgY2FzZSBMU1BhcnNlckZpbHRlci5GSUxURVJfUkVKRUNUOnsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZhbGwgdGhyb3VnaCB0byBTS0lQIHNpbmNlIFBJIGhhcyBubyBjaGlsZHJlbi4KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBjYXNlIExTUGFyc2VyRmlsdGVyLkZJTFRFUl9TS0lQOiB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmQ3VycmVudE5vZGUucmVtb3ZlQ2hpbGQgKHBpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZGaXJzdENodW5rIG11c3QgYmUgc2V0IHRvIHRydWUgc28gdGhhdCBkYXRhCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyB3b24ndCBiZSBsb3N0IGluIHRoZSBjYXNlIHdoZXJlIHRoZSBjaGlsZCBiZWZvcmUgUEkgaXMKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGEgdGV4dCBub2RlIGFuZCB0aGUgbmV4dCBldmVudCBpcyBjaGFyYWN0ZXJzLgotICAgICAgICAgICAgICAgICAgICAgICAgZkZpcnN0Q2h1bmsgPSB0cnVlOwotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIGludCBwaSA9IGZEZWZlcnJlZERvY3VtZW50SW1wbC4KLSAgICAgICAgICAgIGNyZWF0ZURlZmVycmVkUHJvY2Vzc2luZ0luc3RydWN0aW9uICh0YXJnZXQsIGRhdGEudG9TdHJpbmcgKCkpOwotICAgICAgICAgICAgZkRlZmVycmVkRG9jdW1lbnRJbXBsLmFwcGVuZENoaWxkIChmQ3VycmVudE5vZGVJbmRleCwgcGkpOwotICAgICAgICB9Ci0KLSAgICB9IC8vIHByb2Nlc3NpbmdJbnN0cnVjdGlvbihTdHJpbmcsWE1MU3RyaW5nKQotCi0gICAgLyoqCi0gICAgICogVGhlIHN0YXJ0IG9mIHRoZSBkb2N1bWVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBsb2NhdG9yIFRoZSBzeXN0ZW0gaWRlbnRpZmllciBvZiB0aGUgZW50aXR5IGlmIHRoZSBlbnRpdHkKLSAgICAgKiAgICAgICAgICAgICAgICAgaXMgZXh0ZXJuYWwsIG51bGwgb3RoZXJ3aXNlLgotICAgICAqIEBwYXJhbSBlbmNvZGluZyBUaGUgYXV0by1kZXRlY3RlZCBJQU5BIGVuY29kaW5nIG5hbWUgb2YgdGhlIGVudGl0eQotICAgICAqICAgICAgICAgICAgICAgICBzdHJlYW0uIFRoaXMgdmFsdWUgd2lsbCBiZSBudWxsIGluIHRob3NlIHNpdHVhdGlvbnMKLSAgICAgKiAgICAgICAgICAgICAgICAgd2hlcmUgdGhlIGVudGl0eSBlbmNvZGluZyBpcyBub3QgYXV0by1kZXRlY3RlZCAoZS5nLgotICAgICAqICAgICAgICAgICAgICAgICBpbnRlcm5hbCBlbnRpdGllcyBvciBhIGRvY3VtZW50IGVudGl0eSB0aGF0IGlzCi0gICAgICogICAgICAgICAgICAgICAgIHBhcnNlZCBmcm9tIGEgamF2YS5pby5SZWFkZXIpLgotICAgICAqIEBwYXJhbSBuYW1lc3BhY2VDb250ZXh0Ci0gICAgICogICAgICAgICAgICAgICAgIFRoZSBuYW1lc3BhY2UgY29udGV4dCBpbiBlZmZlY3QgYXQgdGhlCi0gICAgICogICAgICAgICAgICAgICAgIHN0YXJ0IG9mIHRoaXMgZG9jdW1lbnQuCi0gICAgICogICAgICAgICAgICAgICAgIFRoaXMgb2JqZWN0IHJlcHJlc2VudHMgdGhlIGN1cnJlbnQgY29udGV4dC4KLSAgICAgKiAgICAgICAgICAgICAgICAgSW1wbGVtZW50b3JzIG9mIHRoaXMgY2xhc3MgYXJlIHJlc3BvbnNpYmxlCi0gICAgICogICAgICAgICAgICAgICAgIGZvciBjb3B5aW5nIHRoZSBuYW1lc3BhY2UgYmluZGluZ3MgZnJvbSB0aGUKLSAgICAgKiAgICAgICAgICAgICAgICAgdGhlIGN1cnJlbnQgY29udGV4dCAoYW5kIGl0cyBwYXJlbnQgY29udGV4dHMpCi0gICAgICogICAgICAgICAgICAgICAgIGlmIHRoYXQgaW5mb3JtYXRpb24gaXMgaW1wb3J0YW50LgotICAgICAqIEBwYXJhbSBhdWdzICAgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnREb2N1bWVudCAoWE1MTG9jYXRvciBsb2NhdG9yLCBTdHJpbmcgZW5jb2RpbmcsCi0gICAgTmFtZXNwYWNlQ29udGV4dCBuYW1lc3BhY2VDb250ZXh0LCBBdWdtZW50YXRpb25zIGF1Z3MpCi0gICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgZkxvY2F0b3IgPSBsb2NhdG9yOwotICAgICAgICBpZiAoIWZEZWZlck5vZGVFeHBhbnNpb24pIHsKLSAgICAgICAgICAgIGlmIChmRG9jdW1lbnRDbGFzc05hbWUuZXF1YWxzIChERUZBVUxUX0RPQ1VNRU5UX0NMQVNTX05BTUUpKSB7Ci0gICAgICAgICAgICAgICAgZkRvY3VtZW50ID0gbmV3IERvY3VtZW50SW1wbCAoKTsKLSAgICAgICAgICAgICAgICBmRG9jdW1lbnRJbXBsID0gKENvcmVEb2N1bWVudEltcGwpZkRvY3VtZW50OwotICAgICAgICAgICAgICAgIC8vIFJFVklTSVQ6IHdoZW4gRE9NIExldmVsIDMgaXMgUkVDIHJlbHkgb24gRG9jdW1lbnQuc3VwcG9ydAotICAgICAgICAgICAgICAgIC8vICAgICAgICAgIGluc3RlYWQgb2Ygc3BlY2lmaWMgY2xhc3MKLSAgICAgICAgICAgICAgICAvLyBzZXQgRE9NIGVycm9yIGNoZWNraW5nIG9mZgotICAgICAgICAgICAgICAgIGZEb2N1bWVudEltcGwuc2V0U3RyaWN0RXJyb3JDaGVja2luZyAoZmFsc2UpOwotICAgICAgICAgICAgICAgIC8vIHNldCBhY3R1YWwgZW5jb2RpbmcKLSAgICAgICAgICAgICAgICBmRG9jdW1lbnRJbXBsLnNldElucHV0RW5jb2RpbmcgKGVuY29kaW5nKTsKLSAgICAgICAgICAgICAgICAvLyBzZXQgZG9jdW1lbnRVUkkKLSAgICAgICAgICAgICAgICBmRG9jdW1lbnRJbXBsLnNldERvY3VtZW50VVJJIChsb2NhdG9yLmdldEV4cGFuZGVkU3lzdGVtSWQgKCkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoZkRvY3VtZW50Q2xhc3NOYW1lLmVxdWFscyAoUFNWSV9ET0NVTUVOVF9DTEFTU19OQU1FKSkgewotICAgICAgICAgICAgICAgIGZEb2N1bWVudCA9IG5ldyBQU1ZJRG9jdW1lbnRJbXBsKCk7Ci0gICAgICAgICAgICAgICAgZkRvY3VtZW50SW1wbCA9IChDb3JlRG9jdW1lbnRJbXBsKWZEb2N1bWVudDsKLSAgICAgICAgICAgICAgICBmU3RvcmVQU1ZJID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAvLyBSRVZJU0lUOiB3aGVuIERPTSBMZXZlbCAzIGlzIFJFQyByZWx5IG9uIERvY3VtZW50LnN1cHBvcnQKLSAgICAgICAgICAgICAgICAvLyAgICAgICAgICBpbnN0ZWFkIG9mIHNwZWNpZmljIGNsYXNzCi0gICAgICAgICAgICAgICAgLy8gc2V0IERPTSBlcnJvciBjaGVja2luZyBvZmYKLSAgICAgICAgICAgICAgICBmRG9jdW1lbnRJbXBsLnNldFN0cmljdEVycm9yQ2hlY2tpbmcgKGZhbHNlKTsKLSAgICAgICAgICAgICAgICAvLyBzZXQgYWN0dWFsIGVuY29kaW5nCi0gICAgICAgICAgICAgICAgZkRvY3VtZW50SW1wbC5zZXRJbnB1dEVuY29kaW5nIChlbmNvZGluZyk7Ci0gICAgICAgICAgICAgICAgLy8gc2V0IGRvY3VtZW50VVJJCi0gICAgICAgICAgICAgICAgZkRvY3VtZW50SW1wbC5zZXREb2N1bWVudFVSSSAobG9jYXRvci5nZXRFeHBhbmRlZFN5c3RlbUlkICgpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIC8vIHVzZSBzcGVjaWZpZWQgZG9jdW1lbnQgY2xhc3MKLSAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICBDbGFzcyBkb2N1bWVudENsYXNzID0gT2JqZWN0RmFjdG9yeS5maW5kUHJvdmlkZXJDbGFzcyAoZkRvY3VtZW50Q2xhc3NOYW1lLCB0cnVlKTsKLSAgICAgICAgICAgICAgICAgICAgZkRvY3VtZW50ID0gKERvY3VtZW50KWRvY3VtZW50Q2xhc3MubmV3SW5zdGFuY2UgKCk7Ci0KLSAgICAgICAgICAgICAgICAgICAgLy8gaWYgc3ViY2xhc3Mgb2Ygb3VyIG93biBjbGFzcyB0aGF0J3MgY29vbCB0b28KLSAgICAgICAgICAgICAgICAgICAgQ2xhc3MgZGVmYXVsdERvY0NsYXNzID0KLSAgICAgICAgICAgICAgICAgICAgT2JqZWN0RmFjdG9yeS5maW5kUHJvdmlkZXJDbGFzcyAoQ09SRV9ET0NVTUVOVF9DTEFTU19OQU1FLCB0cnVlKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGRlZmF1bHREb2NDbGFzcy5pc0Fzc2lnbmFibGVGcm9tIChkb2N1bWVudENsYXNzKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgZkRvY3VtZW50SW1wbCA9IChDb3JlRG9jdW1lbnRJbXBsKWZEb2N1bWVudDsKLQotICAgICAgICAgICAgICAgICAgICAgICAgQ2xhc3MgcHN2aURvY0NsYXNzID0gT2JqZWN0RmFjdG9yeS5maW5kUHJvdmlkZXJDbGFzcyAoUFNWSV9ET0NVTUVOVF9DTEFTU19OQU1FLCB0cnVlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwc3ZpRG9jQ2xhc3MuaXNBc3NpZ25hYmxlRnJvbSAoZG9jdW1lbnRDbGFzcykpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmU3RvcmVQU1ZJID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gUkVWSVNJVDogd2hlbiBET00gTGV2ZWwgMyBpcyBSRUMgcmVseSBvbgotICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgICAgICAgRG9jdW1lbnQuc3VwcG9ydCBpbnN0ZWFkIG9mIHNwZWNpZmljIGNsYXNzCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBzZXQgRE9NIGVycm9yIGNoZWNraW5nIG9mZgotICAgICAgICAgICAgICAgICAgICAgICAgZkRvY3VtZW50SW1wbC5zZXRTdHJpY3RFcnJvckNoZWNraW5nIChmYWxzZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBzZXQgYWN0dWFsIGVuY29kaW5nCi0gICAgICAgICAgICAgICAgICAgICAgICBmRG9jdW1lbnRJbXBsLnNldElucHV0RW5jb2RpbmcgKGVuY29kaW5nKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNldCBkb2N1bWVudFVSSQotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxvY2F0b3IgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZEb2N1bWVudEltcGwuc2V0RG9jdW1lbnRVUkkgKGxvY2F0b3IuZ2V0RXhwYW5kZWRTeXN0ZW1JZCAoKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgICAgICAvLyB3b24ndCBoYXBwZW4gd2UgYWxyZWFkeSBjaGVja2VkIHRoYXQgZWFybGllcgotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24gKAotICAgICAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKAotICAgICAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgIkNhbm5vdENyZWF0ZURvY3VtZW50Q2xhc3MiLAotICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdCBbXSB7ZkRvY3VtZW50Q2xhc3NOYW1lfSkpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGZDdXJyZW50Tm9kZSA9IGZEb2N1bWVudDsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIGZEZWZlcnJlZERvY3VtZW50SW1wbCA9IG5ldyBEZWZlcnJlZERvY3VtZW50SW1wbCAoZk5hbWVzcGFjZUF3YXJlKTsKLSAgICAgICAgICAgIGZEb2N1bWVudCA9IGZEZWZlcnJlZERvY3VtZW50SW1wbDsKLSAgICAgICAgICAgIGZEb2N1bWVudEluZGV4ID0gZkRlZmVycmVkRG9jdW1lbnRJbXBsLmNyZWF0ZURlZmVycmVkRG9jdW1lbnQgKCk7Ci0gICAgICAgICAgICAvLyBSRVZJU0lUOiBzdHJpY3QgZXJyb3IgY2hlY2tpbmcgaXMgbm90IGltcGxlbWVudGVkIGluIGRlZmVycmVkIGRvbS4KLSAgICAgICAgICAgIC8vICAgICAgICAgIERvY3VtZW50LnN1cHBvcnQgaW5zdGVhZCBvZiBzcGVjaWZpYyBjbGFzcwotCi0gICAgICAgICAgICAvLyBzZXQgYWN0dWFsIGVuY29kaW5nCi0gICAgICAgICAgICBmRGVmZXJyZWREb2N1bWVudEltcGwuc2V0SW5wdXRFbmNvZGluZyAoZW5jb2RpbmcpOwotICAgICAgICAgICAgLy8gc2V0IGRvY3VtZW50VVJJCi0gICAgICAgICAgICBmRGVmZXJyZWREb2N1bWVudEltcGwuc2V0RG9jdW1lbnRVUkkgKGxvY2F0b3IuZ2V0RXhwYW5kZWRTeXN0ZW1JZCAoKSk7Ci0gICAgICAgICAgICBmQ3VycmVudE5vZGVJbmRleCA9IGZEb2N1bWVudEluZGV4OwotCi0gICAgICAgIH0KLQotICAgIH0gLy8gc3RhcnREb2N1bWVudChTdHJpbmcsU3RyaW5nKQotCi0gICAgLyoqCi0gICAgICogTm90aWZpZXMgb2YgdGhlIHByZXNlbmNlIG9mIGFuIFhNTERlY2wgbGluZSBpbiB0aGUgZG9jdW1lbnQuIElmCi0gICAgICogcHJlc2VudCwgdGhpcyBtZXRob2Qgd2lsbCBiZSBjYWxsZWQgaW1tZWRpYXRlbHkgZm9sbG93aW5nIHRoZQotICAgICAqIHN0YXJ0RG9jdW1lbnQgY2FsbC4KLSAgICAgKgotICAgICAqIEBwYXJhbSB2ZXJzaW9uICAgIFRoZSBYTUwgdmVyc2lvbi4KLSAgICAgKiBAcGFyYW0gZW5jb2RpbmcgICBUaGUgSUFOQSBlbmNvZGluZyBuYW1lIG9mIHRoZSBkb2N1bWVudCwgb3IgbnVsbCBpZgotICAgICAqICAgICAgICAgICAgICAgICAgIG5vdCBzcGVjaWZpZWQuCi0gICAgICogQHBhcmFtIHN0YW5kYWxvbmUgVGhlIHN0YW5kYWxvbmUgdmFsdWUsIG9yIG51bGwgaWYgbm90IHNwZWNpZmllZC4KLSAgICAgKiBAcGFyYW0gYXVncyAgICAgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgeG1sRGVjbCAoU3RyaW5nIHZlcnNpb24sIFN0cmluZyBlbmNvZGluZywgU3RyaW5nIHN0YW5kYWxvbmUsCi0gICAgQXVnbWVudGF0aW9ucyBhdWdzKQotICAgIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBpZiAoIWZEZWZlck5vZGVFeHBhbnNpb24pIHsKLSAgICAgICAgICAgIC8vIFJFVklTSVQ6IHdoZW4gRE9NIExldmVsIDMgaXMgUkVDIHJlbHkgb24gRG9jdW1lbnQuc3VwcG9ydAotICAgICAgICAgICAgLy8gICAgICAgICAgaW5zdGVhZCBvZiBzcGVjaWZpYyBjbGFzcwotICAgICAgICAgICAgaWYgKGZEb2N1bWVudEltcGwgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGlmICh2ZXJzaW9uICE9IG51bGwpCi0gICAgICAgICAgICAgICAgICAgIGZEb2N1bWVudEltcGwuc2V0WG1sVmVyc2lvbiAodmVyc2lvbik7Ci0gICAgICAgICAgICAgICAgZkRvY3VtZW50SW1wbC5zZXRYbWxFbmNvZGluZyAoZW5jb2RpbmcpOwotICAgICAgICAgICAgICAgIGZEb2N1bWVudEltcGwuc2V0WG1sU3RhbmRhbG9uZSAoInllcyIuZXF1YWxzIChzdGFuZGFsb25lKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBpZiAodmVyc2lvbiAhPSBudWxsKQotICAgICAgICAgICAgICAgIGZEZWZlcnJlZERvY3VtZW50SW1wbC5zZXRYbWxWZXJzaW9uICh2ZXJzaW9uKTsKLSAgICAgICAgICAgIGZEZWZlcnJlZERvY3VtZW50SW1wbC5zZXRYbWxFbmNvZGluZyAoZW5jb2RpbmcpOwotICAgICAgICAgICAgZkRlZmVycmVkRG9jdW1lbnRJbXBsLnNldFhtbFN0YW5kYWxvbmUgKCJ5ZXMiLmVxdWFscyAoc3RhbmRhbG9uZSkpOwotICAgICAgICB9Ci0gICAgfSAvLyB4bWxEZWNsKFN0cmluZyxTdHJpbmcsU3RyaW5nKQotCi0gICAgLyoqCi0gICAgICogTm90aWZpZXMgb2YgdGhlIHByZXNlbmNlIG9mIHRoZSBET0NUWVBFIGxpbmUgaW4gdGhlIGRvY3VtZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIHJvb3RFbGVtZW50IFRoZSBuYW1lIG9mIHRoZSByb290IGVsZW1lbnQuCi0gICAgICogQHBhcmFtIHB1YmxpY0lkICAgIFRoZSBwdWJsaWMgaWRlbnRpZmllciBpZiBhbiBleHRlcm5hbCBEVEQgb3IgbnVsbAotICAgICAqICAgICAgICAgICAgICAgICAgICBpZiB0aGUgZXh0ZXJuYWwgRFREIGlzIHNwZWNpZmllZCB1c2luZyBTWVNURU0uCi0gICAgICogQHBhcmFtIHN5c3RlbUlkICAgIFRoZSBzeXN0ZW0gaWRlbnRpZmllciBpZiBhbiBleHRlcm5hbCBEVEQsIG51bGwKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgb3RoZXJ3aXNlLgotICAgICAqIEBwYXJhbSBhdWdzICAgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZG9jdHlwZURlY2wgKFN0cmluZyByb290RWxlbWVudCwKLSAgICBTdHJpbmcgcHVibGljSWQsIFN0cmluZyBzeXN0ZW1JZCwgQXVnbWVudGF0aW9ucyBhdWdzKQotICAgIHRocm93cyBYTklFeGNlcHRpb24gewotCi0gICAgICAgIGlmICghZkRlZmVyTm9kZUV4cGFuc2lvbikgewotICAgICAgICAgICAgaWYgKGZEb2N1bWVudEltcGwgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZEb2N1bWVudFR5cGUgPSBmRG9jdW1lbnRJbXBsLmNyZWF0ZURvY3VtZW50VHlwZSAoCi0gICAgICAgICAgICAgICAgcm9vdEVsZW1lbnQsIHB1YmxpY0lkLCBzeXN0ZW1JZCk7Ci0gICAgICAgICAgICAgICAgZkN1cnJlbnROb2RlLmFwcGVuZENoaWxkIChmRG9jdW1lbnRUeXBlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIGZEb2N1bWVudFR5cGVJbmRleCA9IGZEZWZlcnJlZERvY3VtZW50SW1wbC4KLSAgICAgICAgICAgIGNyZWF0ZURlZmVycmVkRG9jdW1lbnRUeXBlIChyb290RWxlbWVudCwgcHVibGljSWQsIHN5c3RlbUlkKTsKLSAgICAgICAgICAgIGZEZWZlcnJlZERvY3VtZW50SW1wbC5hcHBlbmRDaGlsZCAoZkN1cnJlbnROb2RlSW5kZXgsIGZEb2N1bWVudFR5cGVJbmRleCk7Ci0gICAgICAgIH0KLQotICAgIH0gLy8gZG9jdHlwZURlY2woU3RyaW5nLFN0cmluZyxTdHJpbmcpCi0KLSAgICAvKioKLSAgICAgKiBUaGUgc3RhcnQgb2YgYW4gZWxlbWVudC4gSWYgdGhlIGRvY3VtZW50IHNwZWNpZmllcyB0aGUgc3RhcnQgZWxlbWVudAotICAgICAqIGJ5IHVzaW5nIGFuIGVtcHR5IHRhZywgdGhlbiB0aGUgc3RhcnRFbGVtZW50IG1ldGhvZCB3aWxsIGltbWVkaWF0ZWx5Ci0gICAgICogYmUgZm9sbG93ZWQgYnkgdGhlIGVuZEVsZW1lbnQgbWV0aG9kLCB3aXRoIG5vIGludGVydmVuaW5nIG1ldGhvZHMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZWxlbWVudCAgICBUaGUgbmFtZSBvZiB0aGUgZWxlbWVudC4KLSAgICAgKiBAcGFyYW0gYXR0cmlidXRlcyBUaGUgZWxlbWVudCBhdHRyaWJ1dGVzLgotICAgICAqIEBwYXJhbSBhdWdzICAgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnRFbGVtZW50IChRTmFtZSBlbGVtZW50LCBYTUxBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMsIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKERFQlVHX0VWRU5UUykgewotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuICgiPT0+c3RhcnRFbGVtZW50ICgiK2VsZW1lbnQucmF3bmFtZSsiKSIpOwotICAgICAgICB9Ci0gICAgICAgIGlmICghZkRlZmVyTm9kZUV4cGFuc2lvbikgewotICAgICAgICAgICAgaWYgKGZGaWx0ZXJSZWplY3QpIHsKLSAgICAgICAgICAgICAgICArK2ZSZWplY3RlZEVsZW1lbnREZXB0aDsKLSAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBFbGVtZW50IGVsID0gY3JlYXRlRWxlbWVudE5vZGUgKGVsZW1lbnQpOwotICAgICAgICAgICAgaW50IGF0dHJDb3VudCA9IGF0dHJpYnV0ZXMuZ2V0TGVuZ3RoICgpOwotICAgICAgICAgICAgYm9vbGVhbiBzZWVuU2NoZW1hRGVmYXVsdCA9IGZhbHNlOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhdHRyQ291bnQ7IGkrKykgewotICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXMuZ2V0TmFtZSAoaSwgZkF0dHJRTmFtZSk7Ci0gICAgICAgICAgICAgICAgQXR0ciBhdHRyID0gY3JlYXRlQXR0ck5vZGUgKGZBdHRyUU5hbWUpOwotCi0gICAgICAgICAgICAgICAgU3RyaW5nIGF0dHJWYWx1ZSA9IGF0dHJpYnV0ZXMuZ2V0VmFsdWUgKGkpOwotCi0gICAgICAgICAgICAgICAgQXR0cmlidXRlUFNWSSBhdHRyUFNWSSA9KEF0dHJpYnV0ZVBTVkkpIGF0dHJpYnV0ZXMuZ2V0QXVnbWVudGF0aW9ucyAoaSkuZ2V0SXRlbSAoQ29uc3RhbnRzLkFUVFJJQlVURV9QU1ZJKTsKLSAgICAgICAgICAgICAgICBpZiAoZlN0b3JlUFNWSSAmJiBhdHRyUFNWSSAhPSBudWxsKXsKLSAgICAgICAgICAgICAgICAgICAgKChQU1ZJQXR0ck5TSW1wbCkgYXR0cikuc2V0UFNWSSAoYXR0clBTVkkpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIGF0dHIuc2V0VmFsdWUgKGF0dHJWYWx1ZSk7Ci0gICAgICAgICAgICAgICAgYm9vbGVhbiBzcGVjaWZpZWQgPSBhdHRyaWJ1dGVzLmlzU3BlY2lmaWVkKGkpOwotICAgICAgICAgICAgICAgIC8vIFRha2Ugc3BlY2lhbCBjYXJlIG9mIHNjaGVtYSBkZWZhdWx0ZWQgYXR0cmlidXRlcy4gQ2FsbGluZyB0aGUKLSAgICAgICAgICAgICAgICAvLyBub24tbmFtZXNwYWNlIGF3YXJlIHNldEF0dHJpYnV0ZU5vZGUoKSBtZXRob2QgY291bGQgb3ZlcndyaXRlCi0gICAgICAgICAgICAgICAgLy8gYW5vdGhlciBhdHRyaWJ1dGUgd2l0aCB0aGUgc2FtZSBsb2NhbCBuYW1lLgotICAgICAgICAgICAgICAgIGlmICghc3BlY2lmaWVkICYmIChzZWVuU2NoZW1hRGVmYXVsdCB8fCAoZkF0dHJRTmFtZS51cmkgIT0gbnVsbCAmJgotICAgICAgICAgICAgICAgICAgICBmQXR0clFOYW1lLnVyaSAhPSBOYW1lc3BhY2VDb250ZXh0LlhNTE5TX1VSSSAmJiBmQXR0clFOYW1lLnByZWZpeCA9PSBudWxsKSkpIHsKLSAgICAgICAgICAgICAgICAgICAgZWwuc2V0QXR0cmlidXRlTm9kZU5TKGF0dHIpOwotICAgICAgICAgICAgICAgICAgICBzZWVuU2NoZW1hRGVmYXVsdCA9IHRydWU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICBlbC5zZXRBdHRyaWJ1dGVOb2RlKGF0dHIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvLyBOT1RFOiBUaGUgc3BlY2lmaWVkIHZhbHVlIE1VU1QgYmUgc2V0IGFmdGVyIHlvdSBzZXQKLSAgICAgICAgICAgICAgICAvLyAgICAgICB0aGUgbm9kZSB2YWx1ZSBiZWNhdXNlIHRoYXQgdHVybnMgdGhlICJzcGVjaWZpZWQiCi0gICAgICAgICAgICAgICAgLy8gICAgICAgZmxhZyB0byAidHJ1ZSIgd2hpY2ggbWF5IG92ZXJ3cml0ZSBhICJmYWxzZSIKLSAgICAgICAgICAgICAgICAvLyAgICAgICB2YWx1ZSBmcm9tIHRoZSBhdHRyaWJ1dGUgbGlzdC4gLUFjCi0gICAgICAgICAgICAgICAgaWYgKGZEb2N1bWVudEltcGwgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBBdHRySW1wbCBhdHRySW1wbCA9IChBdHRySW1wbCkgYXR0cjsKLSAgICAgICAgICAgICAgICAgICAgT2JqZWN0IHR5cGUgPSBudWxsOwotICAgICAgICAgICAgICAgICAgICBib29sZWFuIGlkID0gZmFsc2U7Ci0KLSAgICAgICAgICAgICAgICAgICAgLy8gUkVWSVNJVDogY3VycmVudGx5IGl0IGlzIHBvc3NpYmxlIHRoYXQgc29tZW9uZSB0dXJucyBvZmYKLSAgICAgICAgICAgICAgICAgICAgLy8gbmFtZXNwYWNlcyBhbmQgdHVybnMgb24geG1sIHNjaGVtYSB2YWxpZGF0aW9uCi0gICAgICAgICAgICAgICAgICAgIC8vIFRvIGF2b2lkIGNsYXNzY2FzdCBleGNlcHRpb24gaW4gQXR0ckltcGwgY2hlY2sgZm9yIG5hbWVzcGFjZXMKLSAgICAgICAgICAgICAgICAgICAgLy8gaG93ZXZlciB0aGUgY29ycmVjdCBzb2x1dGlvbiBzaG91bGQgcHJvYmFibHkgZGlzYWxsb3cgc2V0dGluZwotICAgICAgICAgICAgICAgICAgICAvLyBuYW1lc3BhY2VzIHRvIGZhbHNlIHdoZW4gc2NoZW1hIHByb2Nlc3NpbmcgaXMgdHVybmVkIG9uLgotICAgICAgICAgICAgICAgICAgICBpZiAoYXR0clBTVkkgIT0gbnVsbCAmJiBmTmFtZXNwYWNlQXdhcmUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIFhNTCBTY2hlbWEKLSAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUgPSBhdHRyUFNWSS5nZXRNZW1iZXJUeXBlRGVmaW5pdGlvbiAoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlID0gYXR0clBTVkkuZ2V0VHlwZURlZmluaXRpb24gKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGUgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZCA9ICgoWFNTaW1wbGVUeXBlKSB0eXBlKS5pc0lEVHlwZSAoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0ckltcGwuc2V0VHlwZSAodHlwZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWQgPSAoKFhTU2ltcGxlVHlwZSkgdHlwZSkuaXNJRFR5cGUgKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0ckltcGwuc2V0VHlwZSAodHlwZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBEVEQKLSAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gaXNEZWNsYXJlZCA9IEJvb2xlYW4uVFJVRS5lcXVhbHMgKGF0dHJpYnV0ZXMuZ2V0QXVnbWVudGF0aW9ucyAoaSkuZ2V0SXRlbSAoQ29uc3RhbnRzLkFUVFJJQlVURV9ERUNMQVJFRCkpOwotICAgICAgICAgICAgICAgICAgICAgICAgLy8gRm9yIERPTSBMZXZlbCAzIFR5cGVJbmZvLCB0aGUgdHlwZSBuYW1lIG11c3QKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGJlIG51bGwgaWYgdGhpcyBhdHRyaWJ1dGUgaGFzIG5vdCBiZWVuIGRlY2xhcmVkCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBpbiB0aGUgRFRELgotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzRGVjbGFyZWQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlID0gYXR0cmlidXRlcy5nZXRUeXBlIChpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZCA9ICJJRCIuZXF1YWxzICh0eXBlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJJbXBsLnNldFR5cGUgKHR5cGUpOwotICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgaWYgKGlkKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAoKEVsZW1lbnRJbXBsKSBlbCkuc2V0SWRBdHRyaWJ1dGVOb2RlIChhdHRyLCB0cnVlKTsKLSAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgIGF0dHJJbXBsLnNldFNwZWNpZmllZCAoc3BlY2lmaWVkKTsKLSAgICAgICAgICAgICAgICAgICAgLy8gUkVWSVNJVDogSGFuZGxlIGVudGl0aWVzIGluIGF0dHJpYnV0ZSB2YWx1ZS4KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBzZXRDaGFyYWN0ZXJEYXRhIChmYWxzZSk7Ci0KLSAgICAgICAgICAgIGlmIChhdWdzICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBFbGVtZW50UFNWSSBlbGVtZW50UFNWSSA9IChFbGVtZW50UFNWSSlhdWdzLmdldEl0ZW0gKENvbnN0YW50cy5FTEVNRU5UX1BTVkkpOwotICAgICAgICAgICAgICAgIGlmIChlbGVtZW50UFNWSSAhPSBudWxsICYmIGZOYW1lc3BhY2VBd2FyZSkgewotICAgICAgICAgICAgICAgICAgICBYU1R5cGVEZWZpbml0aW9uIHR5cGUgPSBlbGVtZW50UFNWSS5nZXRNZW1iZXJUeXBlRGVmaW5pdGlvbiAoKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGUgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgdHlwZSA9IGVsZW1lbnRQU1ZJLmdldFR5cGVEZWZpbml0aW9uICgpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICgoRWxlbWVudE5TSW1wbCllbCkuc2V0VHlwZSAodHlwZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0KLSAgICAgICAgICAgIC8vIGZpbHRlciBub2RlcwotICAgICAgICAgICAgaWYgKGZET01GaWx0ZXIgIT0gbnVsbCAmJiAhZkluRW50aXR5UmVmKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGZSb290ID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gZmlsbCB2YWx1ZSBvZiB0aGUgcm9vdCBlbGVtZW50Ci0gICAgICAgICAgICAgICAgICAgIGZSb290ID0gZWw7Ci0gICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgc2hvcnQgY29kZSA9IGZET01GaWx0ZXIuc3RhcnRFbGVtZW50KGVsKTsKLSAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChjb2RlKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIExTUGFyc2VyRmlsdGVyLkZJTFRFUl9JTlRFUlJVUFQgOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgQWJvcnQuSU5TVEFOQ0U7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBMU1BhcnNlckZpbHRlci5GSUxURVJfUkVKRUNUIDoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZGaWx0ZXJSZWplY3QgPSB0cnVlOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmUmVqZWN0ZWRFbGVtZW50RGVwdGggPSAwOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBMU1BhcnNlckZpbHRlci5GSUxURVJfU0tJUCA6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBtYWtlIHN1cmUgdGhhdCBpZiBhbnkgY2hhciBkYXRhIGlzIGF2YWlsYWJsZQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGUgZkZpcnN0Q2h1bmsgaXMgdHJ1ZSwgc28gdGhhdCBpZiB0aGUgbmV4dCBldmVudAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpcyBjaGFyYWN0ZXJzKCksIGFuZCB0aGUgbGFzdCBub2RlIGlzIHRleHQsIHdlIHdpbGwgY29weQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGUgdmFsdWUgYWxyZWFkeSBpbiB0aGUgdGV4dCBub2RlIHRvIGZTdHJpbmdCdWZmZXIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gKG5vdCB0byBsb3NlIGl0KS4KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkZpcnN0Q2h1bmsgPSB0cnVlOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmU2tpcHBlZEVsZW1TdGFjay5wdXNoKEJvb2xlYW4uVFJVRSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0IDoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghZlNraXBwZWRFbGVtU3RhY2suaXNFbXB0eSgpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmU2tpcHBlZEVsZW1TdGFjay5wdXNoKEJvb2xlYW4uRkFMU0UpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZkN1cnJlbnROb2RlLmFwcGVuZENoaWxkIChlbCk7Ci0gICAgICAgICAgICBmQ3VycmVudE5vZGUgPSBlbDsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIGludCBlbCA9IGZEZWZlcnJlZERvY3VtZW50SW1wbC5jcmVhdGVEZWZlcnJlZEVsZW1lbnQgKGZOYW1lc3BhY2VBd2FyZSA/Ci0gICAgICAgICAgICAgICAgICAgIGVsZW1lbnQudXJpIDogbnVsbCwgZWxlbWVudC5yYXduYW1lKTsKLSAgICAgICAgICAgIE9iamVjdCB0eXBlID0gbnVsbDsKLSAgICAgICAgICAgIGludCBhdHRyQ291bnQgPSBhdHRyaWJ1dGVzLmdldExlbmd0aCAoKTsKLSAgICAgICAgICAgIC8vIE5lZWQgdG8gbG9vcCBpbiByZXZlcnNlIG9yZGVyIHNvIHRoYXQgdGhlIGF0dHJpYnV0ZXMKLSAgICAgICAgICAgIC8vIGFyZSBwcm9jZXNzZWQgaW4gZG9jdW1lbnQgb3JkZXIgd2hlbiB0aGUgRE9NIGlzIGV4cGFuZGVkLgotICAgICAgICAgICAgZm9yIChpbnQgaSA9IGF0dHJDb3VudCAtIDE7IGkgPj0gMDsgLS1pKSB7Ci0KLSAgICAgICAgICAgICAgICAvLyBzZXQgdHlwZSBpbmZvcm1hdGlvbgotICAgICAgICAgICAgICAgIEF0dHJpYnV0ZVBTVkkgYXR0clBTVkkgPSAoQXR0cmlidXRlUFNWSSlhdHRyaWJ1dGVzLmdldEF1Z21lbnRhdGlvbnMgKGkpLmdldEl0ZW0gKENvbnN0YW50cy5BVFRSSUJVVEVfUFNWSSk7Ci0gICAgICAgICAgICAgICAgYm9vbGVhbiBpZCA9IGZhbHNlOwotCi0gICAgICAgICAgICAgICAgLy8gUkVWSVNJVDogY3VycmVudGx5IGl0IGlzIHBvc3NpYmxlIHRoYXQgc29tZW9uZSB0dXJucyBvZmYKLSAgICAgICAgICAgICAgICAvLyBuYW1lc3BhY2VzIGFuZCB0dXJucyBvbiB4bWwgc2NoZW1hIHZhbGlkYXRpb24KLSAgICAgICAgICAgICAgICAvLyBUbyBhdm9pZCBjbGFzc2Nhc3QgZXhjZXB0aW9uIGluIEF0dHJJbXBsIGNoZWNrIGZvciBuYW1lc3BhY2VzCi0gICAgICAgICAgICAgICAgLy8gaG93ZXZlciB0aGUgY29ycmVjdCBzb2x1dGlvbiBzaG91bGQgcHJvYmFibHkgZGlzYWxsb3cgc2V0dGluZwotICAgICAgICAgICAgICAgIC8vIG5hbWVzcGFjZXMgdG8gZmFsc2Ugd2hlbiBzY2hlbWEgcHJvY2Vzc2luZyBpcyB0dXJuZWQgb24uCi0gICAgICAgICAgICAgICAgaWYgKGF0dHJQU1ZJICE9IG51bGwgJiYgZk5hbWVzcGFjZUF3YXJlKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIFhNTCBTY2hlbWEKLSAgICAgICAgICAgICAgICAgICAgdHlwZSA9IGF0dHJQU1ZJLmdldE1lbWJlclR5cGVEZWZpbml0aW9uICgpOwotICAgICAgICAgICAgICAgICAgICBpZiAodHlwZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICB0eXBlID0gYXR0clBTVkkuZ2V0VHlwZURlZmluaXRpb24gKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZSAhPSBudWxsKXsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZCA9ICgoWFNTaW1wbGVUeXBlKSB0eXBlKS5pc0lEVHlwZSAoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlkID0gKChYU1NpbXBsZVR5cGUpIHR5cGUpLmlzSURUeXBlICgpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAvLyBEVEQKLSAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBpc0RlY2xhcmVkID0gQm9vbGVhbi5UUlVFLmVxdWFscyAoYXR0cmlidXRlcy5nZXRBdWdtZW50YXRpb25zIChpKS5nZXRJdGVtIChDb25zdGFudHMuQVRUUklCVVRFX0RFQ0xBUkVEKSk7Ci0gICAgICAgICAgICAgICAgICAgIC8vIEZvciBET00gTGV2ZWwgMyBUeXBlSW5mbywgdGhlIHR5cGUgbmFtZSBtdXN0Ci0gICAgICAgICAgICAgICAgICAgIC8vIGJlIG51bGwgaWYgdGhpcyBhdHRyaWJ1dGUgaGFzIG5vdCBiZWVuIGRlY2xhcmVkCi0gICAgICAgICAgICAgICAgICAgIC8vIGluIHRoZSBEVEQuCi0gICAgICAgICAgICAgICAgICAgIGlmIChpc0RlY2xhcmVkKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICB0eXBlID0gYXR0cmlidXRlcy5nZXRUeXBlIChpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlkID0gIklEIi5lcXVhbHMgKHR5cGUpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgLy8gY3JlYXRlIGF0dHJpYnV0ZQotICAgICAgICAgICAgICAgIGZEZWZlcnJlZERvY3VtZW50SW1wbC5zZXREZWZlcnJlZEF0dHJpYnV0ZSAoCi0gICAgICAgICAgICAgICAgZWwsCi0gICAgICAgICAgICAgICAgYXR0cmlidXRlcy5nZXRRTmFtZSAoaSksCi0gICAgICAgICAgICAgICAgYXR0cmlidXRlcy5nZXRVUkkgKGkpLAotICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXMuZ2V0VmFsdWUgKGkpLAotICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXMuaXNTcGVjaWZpZWQgKGkpLAotICAgICAgICAgICAgICAgIGlkLAotICAgICAgICAgICAgICAgIHR5cGUpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBmRGVmZXJyZWREb2N1bWVudEltcGwuYXBwZW5kQ2hpbGQgKGZDdXJyZW50Tm9kZUluZGV4LCBlbCk7Ci0gICAgICAgICAgICBmQ3VycmVudE5vZGVJbmRleCA9IGVsOwotICAgICAgICB9Ci0gICAgfSAvLyBzdGFydEVsZW1lbnQoUU5hbWUsWE1MQXR0cmlidXRlcykKLQotCi0gICAgLyoqCi0gICAgICogQW4gZW1wdHkgZWxlbWVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlbGVtZW50ICAgIFRoZSBuYW1lIG9mIHRoZSBlbGVtZW50LgotICAgICAqIEBwYXJhbSBhdHRyaWJ1dGVzIFRoZSBlbGVtZW50IGF0dHJpYnV0ZXMuCi0gICAgICogQHBhcmFtIGF1Z3MgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW1wdHlFbGVtZW50IChRTmFtZSBlbGVtZW50LCBYTUxBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMsIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLQotICAgICAgICBzdGFydEVsZW1lbnQgKGVsZW1lbnQsIGF0dHJpYnV0ZXMsIGF1Z3MpOwotICAgICAgICBlbmRFbGVtZW50IChlbGVtZW50LCBhdWdzKTsKLQotICAgIH0gLy8gZW1wdHlFbGVtZW50KFFOYW1lLFhNTEF0dHJpYnV0ZXMpCi0KLSAgICAvKioKLSAgICAgKiBDaGFyYWN0ZXIgY29udGVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSB0ZXh0IFRoZSBjb250ZW50LgotICAgICAqIEBwYXJhbSBhdWdzICAgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY2hhcmFjdGVycyAoWE1MU3RyaW5nIHRleHQsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgaWYgKERFQlVHX0VWRU5UUykgewotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuICgiPT0+Y2hhcmFjdGVycygpOiAiK3RleHQudG9TdHJpbmcgKCkpOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKCFmRGVmZXJOb2RlRXhwYW5zaW9uKSB7Ci0KLSAgICAgICAgICAgIGlmIChmRmlsdGVyUmVqZWN0KSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKGZJbkNEQVRBU2VjdGlvbiAmJiBmQ3JlYXRlQ0RBVEFOb2RlcykgewotICAgICAgICAgICAgICAgIGlmIChmQ3VycmVudENEQVRBU2VjdGlvbiA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZDdXJyZW50Q0RBVEFTZWN0aW9uID0KLSAgICAgICAgICAgICAgICAgICAgZkRvY3VtZW50LmNyZWF0ZUNEQVRBU2VjdGlvbiAodGV4dC50b1N0cmluZyAoKSk7Ci0gICAgICAgICAgICAgICAgICAgIGZDdXJyZW50Tm9kZS5hcHBlbmRDaGlsZCAoZkN1cnJlbnRDREFUQVNlY3Rpb24pOwotICAgICAgICAgICAgICAgICAgICBmQ3VycmVudE5vZGUgPSBmQ3VycmVudENEQVRBU2VjdGlvbjsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIGZDdXJyZW50Q0RBVEFTZWN0aW9uLmFwcGVuZERhdGEgKHRleHQudG9TdHJpbmcgKCkpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKCFmSW5EVEQpIHsKLSAgICAgICAgICAgICAgICAvLyBpZiB0eXBlIGlzIHVuaW9uIChYTUwgU2NoZW1hKSBpdCBpcyBwb3NzaWJsZSB0aGF0IHdlIHJlY2VpdmUKLSAgICAgICAgICAgICAgICAvLyBjaGFyYWN0ZXIgY2FsbCB3aXRoIGVtcHR5IGRhdGEKLSAgICAgICAgICAgICAgICBpZiAodGV4dC5sZW5ndGggPT0gMCkgewotICAgICAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgTm9kZSBjaGlsZCA9IGZDdXJyZW50Tm9kZS5nZXRMYXN0Q2hpbGQgKCk7Ci0gICAgICAgICAgICAgICAgaWYgKGNoaWxkICE9IG51bGwgJiYgY2hpbGQuZ2V0Tm9kZVR5cGUgKCkgPT0gTm9kZS5URVhUX05PREUpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gY29sbGVjdCBhbGwgdGhlIGRhdGEgaW50byB0aGUgc3RyaW5nIGJ1ZmZlci4KLSAgICAgICAgICAgICAgICAgICAgaWYgKGZGaXJzdENodW5rKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZkRvY3VtZW50SW1wbCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZlN0cmluZ0J1aWxkZXIuYXBwZW5kICgoKFRleHRJbXBsKWNoaWxkKS5yZW1vdmVEYXRhICgpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZlN0cmluZ0J1aWxkZXIuYXBwZW5kICgoKFRleHQpY2hpbGQpLmdldERhdGEgKCkpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoVGV4dCljaGlsZCkuc2V0Tm9kZVZhbHVlIChudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGZGaXJzdENodW5rID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgaWYgKHRleHQubGVuZ3RoID4gMCkgewotICAgICAgICAgICAgICAgICAgICAgICAgZlN0cmluZ0J1aWxkZXIuYXBwZW5kICh0ZXh0LmNoLCB0ZXh0Lm9mZnNldCwgdGV4dC5sZW5ndGgpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICBmRmlyc3RDaHVuayA9IHRydWU7Ci0gICAgICAgICAgICAgICAgICAgIFRleHQgdGV4dE5vZGUgPSBmRG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUgKHRleHQudG9TdHJpbmcoKSk7Ci0gICAgICAgICAgICAgICAgICAgIGZDdXJyZW50Tm9kZS5hcHBlbmRDaGlsZCAodGV4dE5vZGUpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgLy8gVGhlIFRleHQgYW5kIENEQVRBU2VjdGlvbiBub3JtYWxpemF0aW9uIGlzIHRha2VuIGNhcmUgb2Ygd2l0aGluCi0gICAgICAgICAgICAvLyB0aGUgRE9NIGluIHRoZSBkZWZlcnJlZCBjYXNlLgotICAgICAgICAgICAgaWYgKGZJbkNEQVRBU2VjdGlvbiAmJiBmQ3JlYXRlQ0RBVEFOb2RlcykgewotICAgICAgICAgICAgICAgIGlmIChmQ3VycmVudENEQVRBU2VjdGlvbkluZGV4ID09IC0xKSB7Ci0gICAgICAgICAgICAgICAgICAgIGludCBjcyA9IGZEZWZlcnJlZERvY3VtZW50SW1wbC4KLSAgICAgICAgICAgICAgICAgICAgY3JlYXRlRGVmZXJyZWRDREFUQVNlY3Rpb24gKHRleHQudG9TdHJpbmcgKCkpOwotCi0gICAgICAgICAgICAgICAgICAgIGZEZWZlcnJlZERvY3VtZW50SW1wbC5hcHBlbmRDaGlsZCAoZkN1cnJlbnROb2RlSW5kZXgsIGNzKTsKLSAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRDREFUQVNlY3Rpb25JbmRleCA9IGNzOwotICAgICAgICAgICAgICAgICAgICBmQ3VycmVudE5vZGVJbmRleCA9IGNzOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgaW50IHR4dCA9IGZEZWZlcnJlZERvY3VtZW50SW1wbC4KLSAgICAgICAgICAgICAgICAgICAgY3JlYXRlRGVmZXJyZWRUZXh0Tm9kZSAodGV4dC50b1N0cmluZyAoKSwgZmFsc2UpOwotICAgICAgICAgICAgICAgICAgICBmRGVmZXJyZWREb2N1bWVudEltcGwuYXBwZW5kQ2hpbGQgKGZDdXJyZW50Tm9kZUluZGV4LCB0eHQpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0gZWxzZSBpZiAoIWZJbkRURCkgewotICAgICAgICAgICAgICAgIC8vIGlmIHR5cGUgaXMgdW5pb24gKFhNTCBTY2hlbWEpIGl0IGlzIHBvc3NpYmxlIHRoYXQgd2UgcmVjZWl2ZQotICAgICAgICAgICAgICAgIC8vIGNoYXJhY3RlciBjYWxsIHdpdGggZW1wdHkgZGF0YQotICAgICAgICAgICAgICAgIGlmICh0ZXh0Lmxlbmd0aCA9PSAwKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBTdHJpbmcgdmFsdWUgPSB0ZXh0LnRvU3RyaW5nICgpOwotICAgICAgICAgICAgICAgIGludCB0eHQgPSBmRGVmZXJyZWREb2N1bWVudEltcGwuCi0gICAgICAgICAgICAgICAgY3JlYXRlRGVmZXJyZWRUZXh0Tm9kZSAodmFsdWUsIGZhbHNlKTsKLSAgICAgICAgICAgICAgICBmRGVmZXJyZWREb2N1bWVudEltcGwuYXBwZW5kQ2hpbGQgKGZDdXJyZW50Tm9kZUluZGV4LCB0eHQpOwotCi0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9IC8vIGNoYXJhY3RlcnMoWE1MU3RyaW5nKQotCi0gICAgLyoqCi0gICAgICogSWdub3JhYmxlIHdoaXRlc3BhY2UuIEZvciB0aGlzIG1ldGhvZCB0byBiZSBjYWxsZWQsIHRoZSBkb2N1bWVudAotICAgICAqIHNvdXJjZSBtdXN0IGhhdmUgc29tZSB3YXkgb2YgZGV0ZXJtaW5pbmcgdGhhdCB0aGUgdGV4dCBjb250YWluaW5nCi0gICAgICogb25seSB3aGl0ZXNwYWNlIGNoYXJhY3RlcnMgc2hvdWxkIGJlIGNvbnNpZGVyZWQgaWdub3JhYmxlLiBGb3IKLSAgICAgKiBleGFtcGxlLCB0aGUgdmFsaWRhdG9yIGNhbiBkZXRlcm1pbmUgaWYgYSBsZW5ndGggb2Ygd2hpdGVzcGFjZQotICAgICAqIGNoYXJhY3RlcnMgaW4gdGhlIGRvY3VtZW50IGFyZSBpZ25vcmFibGUgYmFzZWQgb24gdGhlIGVsZW1lbnQKLSAgICAgKiBjb250ZW50IG1vZGVsLgotICAgICAqCi0gICAgICogQHBhcmFtIHRleHQgVGhlIGlnbm9yYWJsZSB3aGl0ZXNwYWNlLgotICAgICAqIEBwYXJhbSBhdWdzICAgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgaWdub3JhYmxlV2hpdGVzcGFjZSAoWE1MU3RyaW5nIHRleHQsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgaWYgKCFmSW5jbHVkZUlnbm9yYWJsZVdoaXRlc3BhY2UgfHwgZkZpbHRlclJlamVjdCkgewotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0gICAgICAgIGlmICghZkRlZmVyTm9kZUV4cGFuc2lvbikgewotICAgICAgICAgICAgTm9kZSBjaGlsZCA9IGZDdXJyZW50Tm9kZS5nZXRMYXN0Q2hpbGQgKCk7Ci0gICAgICAgICAgICBpZiAoY2hpbGQgIT0gbnVsbCAmJiBjaGlsZC5nZXROb2RlVHlwZSAoKSA9PSBOb2RlLlRFWFRfTk9ERSkgewotICAgICAgICAgICAgICAgIFRleHQgdGV4dE5vZGUgPSAoVGV4dCljaGlsZDsKLSAgICAgICAgICAgICAgICB0ZXh0Tm9kZS5hcHBlbmREYXRhICh0ZXh0LnRvU3RyaW5nICgpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIFRleHQgdGV4dE5vZGUgPSBmRG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUgKHRleHQudG9TdHJpbmcgKCkpOwotICAgICAgICAgICAgICAgIGlmIChmRG9jdW1lbnRJbXBsICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgVGV4dEltcGwgdGV4dE5vZGVJbXBsID0gKFRleHRJbXBsKXRleHROb2RlOwotICAgICAgICAgICAgICAgICAgICB0ZXh0Tm9kZUltcGwuc2V0SWdub3JhYmxlV2hpdGVzcGFjZSAodHJ1ZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGZDdXJyZW50Tm9kZS5hcHBlbmRDaGlsZCAodGV4dE5vZGUpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgLy8gVGhlIFRleHQgbm9ybWFsaXphdGlvbiBpcyB0YWtlbiBjYXJlIG9mIHdpdGhpbiB0aGUgRE9NIGluIHRoZQotICAgICAgICAgICAgLy8gZGVmZXJyZWQgY2FzZS4KLSAgICAgICAgICAgIGludCB0eHQgPSBmRGVmZXJyZWREb2N1bWVudEltcGwuCi0gICAgICAgICAgICBjcmVhdGVEZWZlcnJlZFRleHROb2RlICh0ZXh0LnRvU3RyaW5nICgpLCB0cnVlKTsKLSAgICAgICAgICAgIGZEZWZlcnJlZERvY3VtZW50SW1wbC5hcHBlbmRDaGlsZCAoZkN1cnJlbnROb2RlSW5kZXgsIHR4dCk7Ci0gICAgICAgIH0KLQotICAgIH0gLy8gaWdub3JhYmxlV2hpdGVzcGFjZShYTUxTdHJpbmcpCi0KLSAgICAvKioKLSAgICAgKiBUaGUgZW5kIG9mIGFuIGVsZW1lbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZWxlbWVudCBUaGUgbmFtZSBvZiB0aGUgZWxlbWVudC4KLSAgICAgKiBAcGFyYW0gYXVncyAgICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZEVsZW1lbnQgKFFOYW1lIGVsZW1lbnQsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChERUJVR19FVkVOVFMpIHsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbiAoIj09PmVuZEVsZW1lbnQgKCIrZWxlbWVudC5yYXduYW1lKyIpIik7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKCFmRGVmZXJOb2RlRXhwYW5zaW9uKSB7Ci0KLSAgICAgICAgICAgIC8vIFJFVklTSVQ6IFNob3VsZCB0aGlzIGhhcHBlbiBhZnRlciB3ZSBjYWxsIHRoZSBmaWx0ZXI/Ci0gICAgICAgICAgICBpZiAoYXVncyAhPSBudWxsICYmIGZEb2N1bWVudEltcGwgIT0gbnVsbCAmJiAoZk5hbWVzcGFjZUF3YXJlIHx8IGZTdG9yZVBTVkkpKSB7Ci0gICAgICAgICAgICAgICAgRWxlbWVudFBTVkkgZWxlbWVudFBTVkkgPSAoRWxlbWVudFBTVkkpIGF1Z3MuZ2V0SXRlbShDb25zdGFudHMuRUxFTUVOVF9QU1ZJKTsKLSAgICAgICAgICAgICAgICBpZiAoZWxlbWVudFBTVkkgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAvLyBVcGRhdGluZyBUeXBlSW5mby4gSWYgdGhlIGRlY2xhcmVkIHR5cGUgaXMgYSB1bmlvbiB0aGUKLSAgICAgICAgICAgICAgICAgICAgLy8gW21lbWJlciB0eXBlIGRlZmluaXRpb25dIHdpbGwgb25seSBiZSBhdmFpbGFibGUgYXQgdGhlCi0gICAgICAgICAgICAgICAgICAgIC8vIGVuZCBvZiBhbiBlbGVtZW50LgotICAgICAgICAgICAgICAgICAgICBpZiAoZk5hbWVzcGFjZUF3YXJlKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBYU1R5cGVEZWZpbml0aW9uIHR5cGUgPSBlbGVtZW50UFNWSS5nZXRNZW1iZXJUeXBlRGVmaW5pdGlvbigpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGUgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUgPSBlbGVtZW50UFNWSS5nZXRUeXBlRGVmaW5pdGlvbigpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgKChFbGVtZW50TlNJbXBsKWZDdXJyZW50Tm9kZSkuc2V0VHlwZSh0eXBlKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBpZiAoZlN0b3JlUFNWSSkgewotICAgICAgICAgICAgICAgICAgICAgICAgKChQU1ZJRWxlbWVudE5TSW1wbClmQ3VycmVudE5vZGUpLnNldFBTVkkgKGVsZW1lbnRQU1ZJKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKGZET01GaWx0ZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGlmIChmRmlsdGVyUmVqZWN0KSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChmUmVqZWN0ZWRFbGVtZW50RGVwdGgtLSA9PSAwKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmRmlsdGVyUmVqZWN0ID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpZiAoIWZTa2lwcGVkRWxlbVN0YWNrLmlzRW1wdHkoKSkgewotICAgICAgICAgICAgICAgICAgICBpZiAoZlNraXBwZWRFbGVtU3RhY2sucG9wKCkgPT0gQm9vbGVhbi5UUlVFKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgc2V0Q2hhcmFjdGVyRGF0YSAoZmFsc2UpOwotICAgICAgICAgICAgICAgIGlmICgoZkN1cnJlbnROb2RlICE9IGZSb290KSAmJiAhZkluRW50aXR5UmVmICYmIChmRE9NRmlsdGVyLmdldFdoYXRUb1Nob3cgKCkgJiBOb2RlRmlsdGVyLlNIT1dfRUxFTUVOVCkhPTApIHsKLSAgICAgICAgICAgICAgICAgICAgc2hvcnQgY29kZSA9IGZET01GaWx0ZXIuYWNjZXB0Tm9kZSAoZkN1cnJlbnROb2RlKTsKLSAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChjb2RlKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIExTUGFyc2VyRmlsdGVyLkZJTFRFUl9JTlRFUlJVUFQ6ewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IEFib3J0LklOU1RBTkNFOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBMU1BhcnNlckZpbHRlci5GSUxURVJfUkVKRUNUOnsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBOb2RlIHBhcmVudCA9IGZDdXJyZW50Tm9kZS5nZXRQYXJlbnROb2RlICgpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudC5yZW1vdmVDaGlsZCAoZkN1cnJlbnROb2RlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmQ3VycmVudE5vZGUgPSBwYXJlbnQ7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBMU1BhcnNlckZpbHRlci5GSUxURVJfU0tJUDogewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG1ha2Ugc3VyZSB0aGF0IGlmIGFueSBjaGFyIGRhdGEgaXMgYXZhaWxhYmxlCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhlIGZGaXJzdENodW5rIGlzIHRydWUsIHNvIHRoYXQgaWYgdGhlIG5leHQgZXZlbnQKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpcyBjaGFyYWN0ZXJzKCksIGFuZCB0aGUgbGFzdCBub2RlIGlzIHRleHQsIHdlIHdpbGwgY29weQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoZSB2YWx1ZSBhbHJlYWR5IGluIHRoZSB0ZXh0IG5vZGUgdG8gZlN0cmluZ0J1ZmZlcgotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIChub3QgdG8gbG9zZSBpdCkuCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZkZpcnN0Q2h1bmsgPSB0cnVlOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcmVwbGFjZSBjaGlsZHJlbgotICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5vZGUgcGFyZW50ID0gZkN1cnJlbnROb2RlLmdldFBhcmVudE5vZGUgKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgTm9kZUxpc3QgbHMgPSBmQ3VycmVudE5vZGUuZ2V0Q2hpbGROb2RlcyAoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gbHMuZ2V0TGVuZ3RoICgpOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaT0wO2k8bGVuZ3RoO2krKykgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnQuYXBwZW5kQ2hpbGQgKGxzLml0ZW0gKDApKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50LnJlbW92ZUNoaWxkIChmQ3VycmVudE5vZGUpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZDdXJyZW50Tm9kZSA9IHBhcmVudDsKLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDogeyB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZkN1cnJlbnROb2RlID0gZkN1cnJlbnROb2RlLmdldFBhcmVudE5vZGUgKCk7Ci0KLSAgICAgICAgICAgIH0gLy8gZW5kLWlmIERPTUZpbHRlcgotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgc2V0Q2hhcmFjdGVyRGF0YSAoZmFsc2UpOwotICAgICAgICAgICAgICAgIGZDdXJyZW50Tm9kZSA9IGZDdXJyZW50Tm9kZS5nZXRQYXJlbnROb2RlICgpOwotICAgICAgICAgICAgfQotCi0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBpZiAoYXVncyAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgRWxlbWVudFBTVkkgZWxlbWVudFBTVkkgPSAoRWxlbWVudFBTVkkpIGF1Z3MuZ2V0SXRlbShDb25zdGFudHMuRUxFTUVOVF9QU1ZJKTsKLSAgICAgICAgICAgICAgICBpZiAoZWxlbWVudFBTVkkgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAvLyBTZXR0aW5nIFR5cGVJbmZvLiBJZiB0aGUgZGVjbGFyZWQgdHlwZSBpcyBhIHVuaW9uIHRoZQotICAgICAgICAgICAgICAgICAgICAvLyBbbWVtYmVyIHR5cGUgZGVmaW5pdGlvbl0gd2lsbCBvbmx5IGJlIGF2YWlsYWJsZSBhdCB0aGUKLSAgICAgICAgICAgICAgICAgICAgLy8gZW5kIG9mIGFuIGVsZW1lbnQuCi0gICAgICAgICAgICAgICAgICAgIFhTVHlwZURlZmluaXRpb24gdHlwZSA9IGVsZW1lbnRQU1ZJLmdldE1lbWJlclR5cGVEZWZpbml0aW9uKCk7Ci0gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUgPSBlbGVtZW50UFNWSS5nZXRUeXBlRGVmaW5pdGlvbigpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGZEZWZlcnJlZERvY3VtZW50SW1wbC5zZXRUeXBlSW5mbyhmQ3VycmVudE5vZGVJbmRleCwgdHlwZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZkN1cnJlbnROb2RlSW5kZXggPQotICAgICAgICAgICAgICAgIGZEZWZlcnJlZERvY3VtZW50SW1wbC5nZXRQYXJlbnROb2RlIChmQ3VycmVudE5vZGVJbmRleCwgZmFsc2UpOwotICAgICAgICB9Ci0KLQotICAgIH0gLy8gZW5kRWxlbWVudChRTmFtZSkKLQotCi0gICAgLyoqCi0gICAgICogVGhlIHN0YXJ0IG9mIGEgQ0RBVEEgc2VjdGlvbi4KLSAgICAgKiBAcGFyYW0gYXVncyAgICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0Q0RBVEEgKEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgZkluQ0RBVEFTZWN0aW9uID0gdHJ1ZTsKLSAgICAgICAgaWYgKCFmRGVmZXJOb2RlRXhwYW5zaW9uKSB7Ci0gICAgICAgICAgICBpZiAoZkZpbHRlclJlamVjdCkgewotICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChmQ3JlYXRlQ0RBVEFOb2RlcykgewotICAgICAgICAgICAgICAgIHNldENoYXJhY3RlckRhdGEgKGZhbHNlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0gLy8gc3RhcnRDREFUQSgpCi0KLSAgICAvKioKLSAgICAgKiBUaGUgZW5kIG9mIGEgQ0RBVEEgc2VjdGlvbi4KLSAgICAgKiBAcGFyYW0gYXVncyAgICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZENEQVRBIChBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotCi0gICAgICAgIGZJbkNEQVRBU2VjdGlvbiA9IGZhbHNlOwotICAgICAgICBpZiAoIWZEZWZlck5vZGVFeHBhbnNpb24pIHsKLQotICAgICAgICAgICAgaWYgKGZGaWx0ZXJSZWplY3QpIHsKLSAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmIChmQ3VycmVudENEQVRBU2VjdGlvbiAhPW51bGwpIHsKLQotICAgICAgICAgICAgICAgIGlmIChmRE9NRmlsdGVyICE9bnVsbCAmJiAhZkluRW50aXR5UmVmICYmCi0gICAgICAgICAgICAgICAgKGZET01GaWx0ZXIuZ2V0V2hhdFRvU2hvdyAoKSAmIE5vZGVGaWx0ZXIuU0hPV19DREFUQV9TRUNUSU9OKSE9IDApIHsKLSAgICAgICAgICAgICAgICAgICAgc2hvcnQgY29kZSA9IGZET01GaWx0ZXIuYWNjZXB0Tm9kZSAoZkN1cnJlbnRDREFUQVNlY3Rpb24pOwotICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGNvZGUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgTFNQYXJzZXJGaWx0ZXIuRklMVEVSX0lOVEVSUlVQVDp7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgQWJvcnQuSU5TVEFOQ0U7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIExTUGFyc2VyRmlsdGVyLkZJTFRFUl9SRUpFQ1Q6ewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZhbGwgdGhyb3VnaCB0byBTS0lQIHNpbmNlIENEQVRBIHNlY3Rpb24gaGFzIG5vIGNoaWxkcmVuLgotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBMU1BhcnNlckZpbHRlci5GSUxURVJfU0tJUDogewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5vZGUgcGFyZW50ID0gZkN1cnJlbnROb2RlLmdldFBhcmVudE5vZGUgKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50LnJlbW92ZUNoaWxkIChmQ3VycmVudENEQVRBU2VjdGlvbik7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnROb2RlID0gcGFyZW50OwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDogewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFjY2VwdCBub2RlCi0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBmQ3VycmVudE5vZGUgPSBmQ3VycmVudE5vZGUuZ2V0UGFyZW50Tm9kZSAoKTsKLSAgICAgICAgICAgICAgICBmQ3VycmVudENEQVRBU2VjdGlvbiA9IG51bGw7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBpZiAoZkN1cnJlbnRDREFUQVNlY3Rpb25JbmRleCAhPS0xKSB7Ci0gICAgICAgICAgICAgICAgZkN1cnJlbnROb2RlSW5kZXggPQotICAgICAgICAgICAgICAgIGZEZWZlcnJlZERvY3VtZW50SW1wbC5nZXRQYXJlbnROb2RlIChmQ3VycmVudE5vZGVJbmRleCwgZmFsc2UpOwotICAgICAgICAgICAgICAgIGZDdXJyZW50Q0RBVEFTZWN0aW9uSW5kZXggPSAtMTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgfSAvLyBlbmRDREFUQSgpCi0KLSAgICAvKioKLSAgICAgKiBUaGUgZW5kIG9mIHRoZSBkb2N1bWVudC4KLSAgICAgKiBAcGFyYW0gYXVncyAgICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZERvY3VtZW50IChBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotCi0gICAgICAgIGlmICghZkRlZmVyTm9kZUV4cGFuc2lvbikgewotICAgICAgICAgICAgLy8gUkVWSVNJVDogd2hlbiBET00gTGV2ZWwgMyBpcyBSRUMgcmVseSBvbiBEb2N1bWVudC5zdXBwb3J0Ci0gICAgICAgICAgICAvLyAgICAgICAgICBpbnN0ZWFkIG9mIHNwZWNpZmljIGNsYXNzCi0gICAgICAgICAgICAvLyBzZXQgdGhlIGFjdHVhbCBlbmNvZGluZyBhbmQgc2V0IERPTSBlcnJvciBjaGVja2luZyBiYWNrIG9uCi0gICAgICAgICAgICBpZiAoZkRvY3VtZW50SW1wbCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGZMb2NhdG9yICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGZMb2NhdG9yLmdldEVuY29kaW5nKCkgIT0gbnVsbCkKLSAgICAgICAgICAgICAgICAgICAgICAgIGZEb2N1bWVudEltcGwuc2V0SW5wdXRFbmNvZGluZyAoZkxvY2F0b3IuZ2V0RW5jb2RpbmcoKSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGZEb2N1bWVudEltcGwuc2V0U3RyaWN0RXJyb3JDaGVja2luZyAodHJ1ZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmQ3VycmVudE5vZGUgPSBudWxsOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgLy8gc2V0IHRoZSBhY3R1YWwgZW5jb2RpbmcKLSAgICAgICAgICAgIGlmIChmTG9jYXRvciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGZMb2NhdG9yLmdldEVuY29kaW5nKCkgIT0gbnVsbCkKLSAgICAgICAgICAgICAgICAgICAgZkRlZmVycmVkRG9jdW1lbnRJbXBsLnNldElucHV0RW5jb2RpbmcgKGZMb2NhdG9yLmdldEVuY29kaW5nKCkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZkN1cnJlbnROb2RlSW5kZXggPSAtMTsKLSAgICAgICAgfQotCi0gICAgfSAvLyBlbmREb2N1bWVudCgpCi0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBub3RpZmllcyB0aGUgZW5kIG9mIGEgZ2VuZXJhbCBlbnRpdHkuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGlzIG1ldGhvZCBpcyBub3QgY2FsbGVkIGZvciBlbnRpdHkgcmVmZXJlbmNlcwotICAgICAqIGFwcGVhcmluZyBhcyBwYXJ0IG9mIGF0dHJpYnV0ZSB2YWx1ZXMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSAgIFRoZSBuYW1lIG9mIHRoZSBlbnRpdHkuCi0gICAgICogQHBhcmFtIGF1Z3MgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIFhOSUV4Y2VwdGlvbgotICAgICAqICAgICAgICAgICAgICAgICAgIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbmRHZW5lcmFsRW50aXR5IChTdHJpbmcgbmFtZSwgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKERFQlVHX0VWRU5UUykgewotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuICgiPT0+ZW5kR2VuZXJhbEVudGl0eTogKCIrbmFtZSsiKSIpOwotICAgICAgICB9Ci0gICAgICAgIGlmICghZkRlZmVyTm9kZUV4cGFuc2lvbikgewotCi0gICAgICAgICAgICBpZiAoZkZpbHRlclJlamVjdCkgewotICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHNldENoYXJhY3RlckRhdGEgKHRydWUpOwotCi0gICAgICAgICAgICBpZiAoZkRvY3VtZW50VHlwZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgLy8gZ2V0IGN1cnJlbnQgZW50aXR5IGRlY2xhcmF0aW9uCi0gICAgICAgICAgICAgICAgTmFtZWROb2RlTWFwIGVudGl0aWVzID0gZkRvY3VtZW50VHlwZS5nZXRFbnRpdGllcyAoKTsKLSAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eURlY2wgPSAoRW50aXR5SW1wbCkgZW50aXRpZXMuZ2V0TmFtZWRJdGVtIChuYW1lKTsKLSAgICAgICAgICAgICAgICBpZiAoZkN1cnJlbnRFbnRpdHlEZWNsICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGZDdXJyZW50RW50aXR5RGVjbCAhPSBudWxsICYmIGZDdXJyZW50RW50aXR5RGVjbC5nZXRGaXJzdENoaWxkICgpID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5RGVjbC5zZXRSZWFkT25seSAoZmFsc2UsIHRydWUpOwotICAgICAgICAgICAgICAgICAgICAgICAgTm9kZSBjaGlsZCA9IGZDdXJyZW50Tm9kZS5nZXRGaXJzdENoaWxkICgpOwotICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGNoaWxkICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBOb2RlIGNvcHkgPSBjaGlsZC5jbG9uZU5vZGUgKHRydWUpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5RGVjbC5hcHBlbmRDaGlsZCAoY29weSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGQgPSBjaGlsZC5nZXROZXh0U2libGluZyAoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGZDdXJyZW50RW50aXR5RGVjbC5zZXRSZWFkT25seSAodHJ1ZSwgdHJ1ZSk7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vZW50aXRpZXMuc2V0TmFtZWRJdGVtKGZDdXJyZW50RW50aXR5RGVjbCk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHlEZWNsID0gbnVsbDsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGZJbkVudGl0eVJlZiA9IGZhbHNlOwotICAgICAgICAgICAgYm9vbGVhbiByZW1vdmVFbnRpdHlSZWYgPSBmYWxzZTsKLSAgICAgICAgICAgIGlmIChmQ3JlYXRlRW50aXR5UmVmTm9kZXMpIHsKLSAgICAgICAgICAgICAgICBpZiAoZkRvY3VtZW50SW1wbCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIE1ha2UgZW50aXR5IHJlZiBub2RlIHJlYWQgb25seQotICAgICAgICAgICAgICAgICAgICAoKE5vZGVJbXBsKWZDdXJyZW50Tm9kZSkuc2V0UmVhZE9ubHkgKHRydWUsIHRydWUpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIGlmIChmRE9NRmlsdGVyICE9bnVsbCAmJgotICAgICAgICAgICAgICAgIChmRE9NRmlsdGVyLmdldFdoYXRUb1Nob3cgKCkgJiBOb2RlRmlsdGVyLlNIT1dfRU5USVRZX1JFRkVSRU5DRSkhPSAwKSB7Ci0gICAgICAgICAgICAgICAgICAgIHNob3J0IGNvZGUgPSBmRE9NRmlsdGVyLmFjY2VwdE5vZGUgKGZDdXJyZW50Tm9kZSk7Ci0gICAgICAgICAgICAgICAgICAgIHN3aXRjaCAoY29kZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBMU1BhcnNlckZpbHRlci5GSUxURVJfSU5URVJSVVBUOnsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBBYm9ydC5JTlNUQU5DRTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgTFNQYXJzZXJGaWx0ZXIuRklMVEVSX1JFSkVDVDp7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgTm9kZSBwYXJlbnQgPSBmQ3VycmVudE5vZGUuZ2V0UGFyZW50Tm9kZSAoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnQucmVtb3ZlQ2hpbGQgKGZDdXJyZW50Tm9kZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnROb2RlID0gcGFyZW50OwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKLQotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBMU1BhcnNlckZpbHRlci5GSUxURVJfU0tJUDogewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG1ha2Ugc3VyZSB3ZSBkb24ndCBsb29zZSBjaGFycyBpZiBuZXh0IGV2ZW50IGlzIGNoYXJhY3RlcnMoKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZGaXJzdENodW5rID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICByZW1vdmVFbnRpdHlSZWYgPSB0cnVlOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OiB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnROb2RlID0gZkN1cnJlbnROb2RlLmdldFBhcmVudE5vZGUgKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICBmQ3VycmVudE5vZGUgPSBmQ3VycmVudE5vZGUuZ2V0UGFyZW50Tm9kZSAoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmICghZkNyZWF0ZUVudGl0eVJlZk5vZGVzIHx8IHJlbW92ZUVudGl0eVJlZikgewotICAgICAgICAgICAgICAgIC8vIG1vdmUgZW50aXR5IHJlZmVyZW5jZSBjaGlsZHJlbiB0byB0aGUgbGlzdCBvZgotICAgICAgICAgICAgICAgIC8vIHNpYmxpbmdzIG9mIGl0cyBwYXJlbnQgYW5kIHJlbW92ZSBlbnRpdHkgcmVmZXJlbmNlCi0gICAgICAgICAgICAgICAgTm9kZUxpc3QgY2hpbGRyZW4gPSBmQ3VycmVudE5vZGUuZ2V0Q2hpbGROb2RlcyAoKTsKLSAgICAgICAgICAgICAgICBOb2RlIHBhcmVudCA9IGZDdXJyZW50Tm9kZS5nZXRQYXJlbnROb2RlICgpOwotICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBjaGlsZHJlbi5nZXRMZW5ndGggKCk7Ci0gICAgICAgICAgICAgICAgaWYgKGxlbmd0aCA+IDApIHsKLQotICAgICAgICAgICAgICAgICAgICAvLyBnZXQgcHJldmlvdXMgc2libGluZyBvZiB0aGUgZW50aXR5IHJlZmVyZW5jZQotICAgICAgICAgICAgICAgICAgICBOb2RlIG5vZGUgPSBmQ3VycmVudE5vZGUuZ2V0UHJldmlvdXNTaWJsaW5nICgpOwotICAgICAgICAgICAgICAgICAgICAvLyBub3JtYWxpemUgdGV4dCBub2RlcwotICAgICAgICAgICAgICAgICAgICBOb2RlIGNoaWxkID0gY2hpbGRyZW4uaXRlbSAoMCk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChub2RlICE9IG51bGwgJiYgbm9kZS5nZXROb2RlVHlwZSAoKSA9PSBOb2RlLlRFWFRfTk9ERSAmJgotICAgICAgICAgICAgICAgICAgICBjaGlsZC5nZXROb2RlVHlwZSAoKSA9PSBOb2RlLlRFWFRfTk9ERSkgewotICAgICAgICAgICAgICAgICAgICAgICAgKChUZXh0KW5vZGUpLmFwcGVuZERhdGEgKGNoaWxkLmdldE5vZGVWYWx1ZSAoKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmQ3VycmVudE5vZGUucmVtb3ZlQ2hpbGQgKGNoaWxkKTsKLQotICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgbm9kZSA9IHBhcmVudC5pbnNlcnRCZWZvcmUgKGNoaWxkLCBmQ3VycmVudE5vZGUpOwotICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlQmFzZVVSSSAobm9kZSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpPTE7aSA8bGVuZ3RoO2krKykgewotICAgICAgICAgICAgICAgICAgICAgICAgbm9kZSA9IHBhcmVudC5pbnNlcnRCZWZvcmUgKGNoaWxkcmVuLml0ZW0gKDApLCBmQ3VycmVudE5vZGUpOwotICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlQmFzZVVSSSAobm9kZSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9IC8vIGxlbmd0aCA+IDAKLSAgICAgICAgICAgICAgICBwYXJlbnQucmVtb3ZlQ2hpbGQgKGZDdXJyZW50Tm9kZSk7Ci0gICAgICAgICAgICAgICAgZkN1cnJlbnROb2RlID0gcGFyZW50OwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotCi0gICAgICAgICAgICBpZiAoZkRvY3VtZW50VHlwZUluZGV4ICE9IC0xKSB7Ci0gICAgICAgICAgICAgICAgLy8gZmluZCBjb3JyZXNwb25kaW5nIEVudGl0eSBkZWNsCi0gICAgICAgICAgICAgICAgaW50IG5vZGUgPSBmRGVmZXJyZWREb2N1bWVudEltcGwuZ2V0TGFzdENoaWxkIChmRG9jdW1lbnRUeXBlSW5kZXgsIGZhbHNlKTsKLSAgICAgICAgICAgICAgICB3aGlsZSAobm9kZSAhPSAtMSkgewotICAgICAgICAgICAgICAgICAgICBzaG9ydCBub2RlVHlwZSA9IGZEZWZlcnJlZERvY3VtZW50SW1wbC5nZXROb2RlVHlwZSAobm9kZSwgZmFsc2UpOwotICAgICAgICAgICAgICAgICAgICBpZiAobm9kZVR5cGUgPT0gTm9kZS5FTlRJVFlfTk9ERSkgewotICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG5vZGVOYW1lID0KLSAgICAgICAgICAgICAgICAgICAgICAgIGZEZWZlcnJlZERvY3VtZW50SW1wbC5nZXROb2RlTmFtZSAobm9kZSwgZmFsc2UpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5vZGVOYW1lLmVxdWFscyAobmFtZSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmRGVmZXJyZWRFbnRpdHlEZWNsID0gbm9kZTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBub2RlID0gZkRlZmVycmVkRG9jdW1lbnRJbXBsLmdldFJlYWxQcmV2U2libGluZyAobm9kZSwgZmFsc2UpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKGZEZWZlcnJlZEVudGl0eURlY2wgIT0gLTEgJiYKLSAgICAgICAgICAgIGZEZWZlcnJlZERvY3VtZW50SW1wbC5nZXRMYXN0Q2hpbGQgKGZEZWZlcnJlZEVudGl0eURlY2wsIGZhbHNlKSA9PSAtMSkgewotICAgICAgICAgICAgICAgIC8vIGVudGl0eSBkZWZpbml0aW9uIGV4aXN0cyBhbmQgaXQgZG9lcyBub3QgaGF2ZSBhbnkgY2hpbGRyZW4KLSAgICAgICAgICAgICAgICBpbnQgcHJldkluZGV4ID0gLTE7Ci0gICAgICAgICAgICAgICAgaW50IGNoaWxkSW5kZXggPSBmRGVmZXJyZWREb2N1bWVudEltcGwuZ2V0TGFzdENoaWxkIChmQ3VycmVudE5vZGVJbmRleCwgZmFsc2UpOwotICAgICAgICAgICAgICAgIHdoaWxlIChjaGlsZEluZGV4ICE9IC0xKSB7Ci0gICAgICAgICAgICAgICAgICAgIGludCBjbG9uZUluZGV4ID0gZkRlZmVycmVkRG9jdW1lbnRJbXBsLmNsb25lTm9kZSAoY2hpbGRJbmRleCwgdHJ1ZSk7Ci0gICAgICAgICAgICAgICAgICAgIGZEZWZlcnJlZERvY3VtZW50SW1wbC5pbnNlcnRCZWZvcmUgKGZEZWZlcnJlZEVudGl0eURlY2wsIGNsb25lSW5kZXgsIHByZXZJbmRleCk7Ci0gICAgICAgICAgICAgICAgICAgIHByZXZJbmRleCA9IGNsb25lSW5kZXg7Ci0gICAgICAgICAgICAgICAgICAgIGNoaWxkSW5kZXggPSBmRGVmZXJyZWREb2N1bWVudEltcGwuZ2V0UmVhbFByZXZTaWJsaW5nIChjaGlsZEluZGV4LCBmYWxzZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKGZDcmVhdGVFbnRpdHlSZWZOb2RlcykgewotICAgICAgICAgICAgICAgIGZDdXJyZW50Tm9kZUluZGV4ID0KLSAgICAgICAgICAgICAgICBmRGVmZXJyZWREb2N1bWVudEltcGwuZ2V0UGFyZW50Tm9kZSAoZkN1cnJlbnROb2RlSW5kZXgsCi0gICAgICAgICAgICAgICAgZmFsc2UpOwotICAgICAgICAgICAgfSBlbHNlIHsgLy8hZkNyZWF0ZUVudGl0eVJlZk5vZGVzCi0gICAgICAgICAgICAgICAgLy8gbW92ZSBjaGlsZHJlbiBvZiBlbnRpdHkgcmVmIGJlZm9yZSB0aGUgZW50aXR5IHJlZi4KLSAgICAgICAgICAgICAgICAvLyByZW1vdmUgZW50aXR5IHJlZi4KLQotICAgICAgICAgICAgICAgIC8vIGhvbGRzIGEgY2hpbGQgb2YgZW50aXR5IHJlZgotICAgICAgICAgICAgICAgIGludCBjaGlsZEluZGV4ID0gZkRlZmVycmVkRG9jdW1lbnRJbXBsLmdldExhc3RDaGlsZCAoZkN1cnJlbnROb2RlSW5kZXgsIGZhbHNlKTsKLSAgICAgICAgICAgICAgICBpbnQgcGFyZW50SW5kZXggPQotICAgICAgICAgICAgICAgIGZEZWZlcnJlZERvY3VtZW50SW1wbC5nZXRQYXJlbnROb2RlIChmQ3VycmVudE5vZGVJbmRleCwKLSAgICAgICAgICAgICAgICBmYWxzZSk7Ci0KLSAgICAgICAgICAgICAgICBpbnQgcHJldkluZGV4ID0gZkN1cnJlbnROb2RlSW5kZXg7Ci0gICAgICAgICAgICAgICAgaW50IGxhc3RDaGlsZCA9IGNoaWxkSW5kZXg7Ci0gICAgICAgICAgICAgICAgaW50IHNpYmxpbmcgPSAtMTsKLSAgICAgICAgICAgICAgICB3aGlsZSAoY2hpbGRJbmRleCAhPSAtMSkgewotICAgICAgICAgICAgICAgICAgICBoYW5kbGVCYXNlVVJJIChjaGlsZEluZGV4KTsKLSAgICAgICAgICAgICAgICAgICAgc2libGluZyA9IGZEZWZlcnJlZERvY3VtZW50SW1wbC5nZXRSZWFsUHJldlNpYmxpbmcgKGNoaWxkSW5kZXgsIGZhbHNlKTsKLSAgICAgICAgICAgICAgICAgICAgZkRlZmVycmVkRG9jdW1lbnRJbXBsLmluc2VydEJlZm9yZSAocGFyZW50SW5kZXgsIGNoaWxkSW5kZXgsIHByZXZJbmRleCk7Ci0gICAgICAgICAgICAgICAgICAgIHByZXZJbmRleCA9IGNoaWxkSW5kZXg7Ci0gICAgICAgICAgICAgICAgICAgIGNoaWxkSW5kZXggPSBzaWJsaW5nOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpZihsYXN0Q2hpbGQgIT0gLTEpCi0gICAgICAgICAgICAgICAgICAgIGZEZWZlcnJlZERvY3VtZW50SW1wbC5zZXRBc0xhc3RDaGlsZCAocGFyZW50SW5kZXgsIGxhc3RDaGlsZCk7Ci0gICAgICAgICAgICAgICAgZWxzZXsKLSAgICAgICAgICAgICAgICAgICAgc2libGluZyA9IGZEZWZlcnJlZERvY3VtZW50SW1wbC5nZXRSZWFsUHJldlNpYmxpbmcgKHByZXZJbmRleCwgZmFsc2UpOwotICAgICAgICAgICAgICAgICAgICBmRGVmZXJyZWREb2N1bWVudEltcGwuc2V0QXNMYXN0Q2hpbGQgKHBhcmVudEluZGV4LCBzaWJsaW5nKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZkN1cnJlbnROb2RlSW5kZXggPSBwYXJlbnRJbmRleDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGZEZWZlcnJlZEVudGl0eURlY2wgPSAtMTsKLSAgICAgICAgfQotCi0KLSAgICB9IC8vIGVuZEdlbmVyYWxFbnRpdHkoU3RyaW5nLCBBdWdtZW50YXRpb25zKQotCi0KLSAgICAvKioKLSAgICAgKiBSZWNvcmQgYmFzZVVSSSBpbmZvcm1hdGlvbiBmb3IgdGhlIEVsZW1lbnQgKGJ5IGFkZGluZyB4bWw6YmFzZSBhdHRyaWJ1dGUpCi0gICAgICogb3IgZm9yIHRoZSBQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24gKGJ5IHNldHRpbmcgYSBiYXNlVVJJIGZpZWxkKQotICAgICAqIE5vbiBkZWZlcnJlZCBET00uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbm9kZQotICAgICAqLwotICAgIHByb3RlY3RlZCBmaW5hbCB2b2lkIGhhbmRsZUJhc2VVUkkgKE5vZGUgbm9kZSl7Ci0gICAgICAgIGlmIChmRG9jdW1lbnRJbXBsICE9IG51bGwpIHsKLSAgICAgICAgICAgIC8vIFJFVklTSVQ6IHJlbW92ZSBkZXBlbmRlbmN5IG9uIG91ciBpbXBsZW1lbnRhdGlvbiB3aGVuCi0gICAgICAgICAgICAvLyAgICAgICAgICBET00gTDMgYmVjb21lcyBSRUMKLQotICAgICAgICAgICAgU3RyaW5nIGJhc2VVUkkgPSBudWxsOwotICAgICAgICAgICAgc2hvcnQgbm9kZVR5cGUgPSBub2RlLmdldE5vZGVUeXBlICgpOwotCi0gICAgICAgICAgICBpZiAobm9kZVR5cGUgPT0gTm9kZS5FTEVNRU5UX05PREUpIHsKLSAgICAgICAgICAgICAgICAvLyBpZiBhbiBlbGVtZW50IGFscmVhZHkgaGFzIHhtbDpiYXNlIGF0dHJpYnV0ZQotICAgICAgICAgICAgICAgIC8vIGRvIG5vdGhpbmcKLSAgICAgICAgICAgICAgICBpZiAoZk5hbWVzcGFjZUF3YXJlKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmICgoKEVsZW1lbnQpbm9kZSkuZ2V0QXR0cmlidXRlTm9kZU5TICgiaHR0cDovL3d3dy53My5vcmcvWE1MLzE5OTgvbmFtZXNwYWNlIiwiYmFzZSIpIT1udWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCgoRWxlbWVudClub2RlKS5nZXRBdHRyaWJ1dGVOb2RlICgieG1sOmJhc2UiKSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLy8gcmV0cml2ZSB0aGUgYmFzZVVSSSBmcm9tIHRoZSBlbnRpdHkgcmVmZXJlbmNlCi0gICAgICAgICAgICAgICAgYmFzZVVSSSA9ICgoRW50aXR5UmVmZXJlbmNlSW1wbClmQ3VycmVudE5vZGUpLmdldEJhc2VVUkkgKCk7Ci0gICAgICAgICAgICAgICAgaWYgKGJhc2VVUkkgIT1udWxsICYmICFiYXNlVVJJLmVxdWFscyAoZkRvY3VtZW50SW1wbC5nZXREb2N1bWVudFVSSSAoKSkpIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGZOYW1lc3BhY2VBd2FyZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgKChFbGVtZW50KW5vZGUpLnNldEF0dHJpYnV0ZU5TICgiaHR0cDovL3d3dy53My5vcmcvWE1MLzE5OTgvbmFtZXNwYWNlIiwgInhtbDpiYXNlIiwgYmFzZVVSSSk7Ci0gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAoKEVsZW1lbnQpbm9kZSkuc2V0QXR0cmlidXRlICgieG1sOmJhc2UiLCBiYXNlVVJJKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKG5vZGVUeXBlID09IE5vZGUuUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFKSB7Ci0KLSAgICAgICAgICAgICAgICBiYXNlVVJJID0gKChFbnRpdHlSZWZlcmVuY2VJbXBsKWZDdXJyZW50Tm9kZSkuZ2V0QmFzZVVSSSAoKTsKLSAgICAgICAgICAgICAgICBpZiAoYmFzZVVSSSAhPW51bGwgJiYgZkVycm9ySGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIERPTUVycm9ySW1wbCBlcnJvciA9IG5ldyBET01FcnJvckltcGwgKCk7Ci0gICAgICAgICAgICAgICAgICAgIGVycm9yLmZUeXBlID0gInBpLWJhc2UtdXJpLW5vdC1wcmVzZXJ2ZWQiOwotICAgICAgICAgICAgICAgICAgICBlcnJvci5mUmVsYXRlZERhdGEgPSBiYXNlVVJJOwotICAgICAgICAgICAgICAgICAgICBlcnJvci5mU2V2ZXJpdHkgPSBET01FcnJvci5TRVZFUklUWV9XQVJOSU5HOwotICAgICAgICAgICAgICAgICAgICBmRXJyb3JIYW5kbGVyLmdldEVycm9ySGFuZGxlciAoKS5oYW5kbGVFcnJvciAoZXJyb3IpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqCi0gICAgICogUmVjb3JkIGJhc2VVUkkgaW5mb3JtYXRpb24gZm9yIHRoZSBFbGVtZW50IChieSBhZGRpbmcgeG1sOmJhc2UgYXR0cmlidXRlKQotICAgICAqIG9yIGZvciB0aGUgUHJvY2Vzc2luZ0luc3RydWN0aW9uIChieSBzZXR0aW5nIGEgYmFzZVVSSSBmaWVsZCkKLSAgICAgKiBEZWZlcnJlZCBET00uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbm9kZQotICAgICAqLwotICAgIHByb3RlY3RlZCBmaW5hbCB2b2lkIGhhbmRsZUJhc2VVUkkgKGludCBub2RlKXsKLSAgICAgICAgc2hvcnQgbm9kZVR5cGUgPSBmRGVmZXJyZWREb2N1bWVudEltcGwuZ2V0Tm9kZVR5cGUgKG5vZGUsIGZhbHNlKTsKLQotICAgICAgICBpZiAobm9kZVR5cGUgPT0gTm9kZS5FTEVNRU5UX05PREUpIHsKLSAgICAgICAgICAgIFN0cmluZyBiYXNlVVJJID0gZkRlZmVycmVkRG9jdW1lbnRJbXBsLmdldE5vZGVWYWx1ZVN0cmluZyAoZkN1cnJlbnROb2RlSW5kZXgsIGZhbHNlKTsKLSAgICAgICAgICAgIGlmIChiYXNlVVJJID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBiYXNlVVJJID0gZkRlZmVycmVkRG9jdW1lbnRJbXBsLmdldERlZmVycmVkRW50aXR5QmFzZVVSSSAoZkRlZmVycmVkRW50aXR5RGVjbCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoYmFzZVVSSSAhPW51bGwgJiYgIWJhc2VVUkkuZXF1YWxzIChmRGVmZXJyZWREb2N1bWVudEltcGwuZ2V0RG9jdW1lbnRVUkkgKCkpKSB7Ci0gICAgICAgICAgICAgICAgZkRlZmVycmVkRG9jdW1lbnRJbXBsLnNldERlZmVycmVkQXR0cmlidXRlIChub2RlLAotICAgICAgICAgICAgICAgICJ4bWw6YmFzZSIsCi0gICAgICAgICAgICAgICAgImh0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZSIsCi0gICAgICAgICAgICAgICAgYmFzZVVSSSwKLSAgICAgICAgICAgICAgICB0cnVlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChub2RlVHlwZSA9PSBOb2RlLlBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERSkgewotCi0KLSAgICAgICAgICAgIC8vIHJldHJpZXZlIGJhc2VVUkkgZnJvbSB0aGUgZW50aXR5IHJlZmVyZW5jZQotICAgICAgICAgICAgU3RyaW5nIGJhc2VVUkkgPSBmRGVmZXJyZWREb2N1bWVudEltcGwuZ2V0Tm9kZVZhbHVlU3RyaW5nIChmQ3VycmVudE5vZGVJbmRleCwgZmFsc2UpOwotCi0gICAgICAgICAgICBpZiAoYmFzZVVSSSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgLy8gdHJ5IGJhc2VVUkkgb2YgdGhlIGVudGl0eSBkZWNsYXJhdGlvbgotICAgICAgICAgICAgICAgIGJhc2VVUkkgPSBmRGVmZXJyZWREb2N1bWVudEltcGwuZ2V0RGVmZXJyZWRFbnRpdHlCYXNlVVJJIChmRGVmZXJyZWRFbnRpdHlEZWNsKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKGJhc2VVUkkgIT0gbnVsbCAmJiBmRXJyb3JIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBET01FcnJvckltcGwgZXJyb3IgPSBuZXcgRE9NRXJyb3JJbXBsICgpOwotICAgICAgICAgICAgICAgIGVycm9yLmZUeXBlID0gInBpLWJhc2UtdXJpLW5vdC1wcmVzZXJ2ZWQiOwotICAgICAgICAgICAgICAgIGVycm9yLmZSZWxhdGVkRGF0YSA9IGJhc2VVUkk7Ci0gICAgICAgICAgICAgICAgZXJyb3IuZlNldmVyaXR5ID0gRE9NRXJyb3IuU0VWRVJJVFlfV0FSTklORzsKLSAgICAgICAgICAgICAgICBmRXJyb3JIYW5kbGVyLmdldEVycm9ySGFuZGxlciAoKS5oYW5kbGVFcnJvciAoZXJyb3IpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICAvLwotICAgIC8vIFhNTERUREhhbmRsZXIgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBUaGUgc3RhcnQgb2YgdGhlIERURC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBsb2NhdG9yICBUaGUgZG9jdW1lbnQgbG9jYXRvciwgb3IgbnVsbCBpZiB0aGUgZG9jdW1lbnQKLSAgICAgKiAgICAgICAgICAgICAgICAgbG9jYXRpb24gY2Fubm90IGJlIHJlcG9ydGVkIGR1cmluZyB0aGUgcGFyc2luZyBvZgotICAgICAqICAgICAgICAgICAgICAgICB0aGUgZG9jdW1lbnQgRFRELiBIb3dldmVyLCBpdCBpcyA8ZW0+c3Ryb25nbHk8L2VtPgotICAgICAqICAgICAgICAgICAgICAgICByZWNvbW1lbmRlZCB0aGF0IGEgbG9jYXRvciBiZSBzdXBwbGllZCB0aGF0IGNhbgotICAgICAqICAgICAgICAgICAgICAgICBhdCBsZWFzdCByZXBvcnQgdGhlIGJhc2Ugc3lzdGVtIGlkZW50aWZpZXIgb2YgdGhlCi0gICAgICogICAgICAgICAgICAgICAgIERURC4KLSAgICAgKiBAcGFyYW0gYXVncyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnREVEQgKFhNTExvY2F0b3IgbG9jYXRvciwgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKERFQlVHX0VWRU5UUykgewotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuICgiPT0+c3RhcnREVEQiKTsKLSAgICAgICAgICAgIGlmIChERUJVR19CQVNFVVJJKSB7Ci0gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuICgiICAgZXhwYW5kZWRTeXN0ZW1JZDogIitsb2NhdG9yLmdldEV4cGFuZGVkU3lzdGVtSWQgKCkpOwotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbiAoIiAgIGJhc2VVUkk6IisgbG9jYXRvci5nZXRCYXNlU3lzdGVtSWQgKCkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgZkluRFREID0gdHJ1ZTsKLSAgICAgICAgaWYgKGxvY2F0b3IgIT0gbnVsbCkgewotICAgICAgICAgICAgZkJhc2VVUklTdGFjay5wdXNoIChsb2NhdG9yLmdldEJhc2VTeXN0ZW1JZCAoKSk7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGZEZWZlck5vZGVFeHBhbnNpb24gfHwgZkRvY3VtZW50SW1wbCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmSW50ZXJuYWxTdWJzZXQgPSBuZXcgU3RyaW5nQnVpbGRlciAoMTAyNCk7Ci0gICAgICAgIH0KLSAgICB9IC8vIHN0YXJ0RFREKFhNTExvY2F0b3IpCi0KLQotICAgIC8qKgotICAgICAqIFRoZSBlbmQgb2YgdGhlIERURC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBhdWdzIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbmREVEQgKEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChERUJVR19FVkVOVFMpIHsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbiAoIj09PmVuZERURCgpIik7Ci0gICAgICAgIH0KLSAgICAgICAgZkluRFREID0gZmFsc2U7Ci0gICAgICAgIGlmICghZkJhc2VVUklTdGFjay5pc0VtcHR5ICgpKSB7Ci0gICAgICAgICAgICBmQmFzZVVSSVN0YWNrLnBvcCAoKTsKLSAgICAgICAgfQotICAgICAgICBTdHJpbmcgaW50ZXJuYWxTdWJzZXQgPSBmSW50ZXJuYWxTdWJzZXQgIT0gbnVsbCAmJiBmSW50ZXJuYWxTdWJzZXQubGVuZ3RoICgpID4gMAotICAgICAgICA/IGZJbnRlcm5hbFN1YnNldC50b1N0cmluZyAoKSA6IG51bGw7Ci0gICAgICAgIGlmIChmRGVmZXJOb2RlRXhwYW5zaW9uKSB7Ci0gICAgICAgICAgICBpZiAoaW50ZXJuYWxTdWJzZXQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZEZWZlcnJlZERvY3VtZW50SW1wbC5zZXRJbnRlcm5hbFN1YnNldCAoZkRvY3VtZW50VHlwZUluZGV4LCBpbnRlcm5hbFN1YnNldCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoZkRvY3VtZW50SW1wbCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAoaW50ZXJuYWxTdWJzZXQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICgoRG9jdW1lbnRUeXBlSW1wbClmRG9jdW1lbnRUeXBlKS5zZXRJbnRlcm5hbFN1YnNldCAoaW50ZXJuYWxTdWJzZXQpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfSAvLyBlbmREVEQoKQotCi0gICAgLyoqCi0gICAgICogVGhlIHN0YXJ0IG9mIGEgY29uZGl0aW9uYWwgc2VjdGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSB0eXBlIFRoZSB0eXBlIG9mIHRoZSBjb25kaXRpb25hbCBzZWN0aW9uLiBUaGlzIHZhbHVlIHdpbGwKLSAgICAgKiAgICAgICAgICAgICBlaXRoZXIgYmUgQ09ORElUSU9OQUxfSU5DTFVERSBvciBDT05ESVRJT05BTF9JR05PUkUuCi0gICAgICogQHBhcmFtIGF1Z3MgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqCi0gICAgICogQHNlZSAjQ09ORElUSU9OQUxfSU5DTFVERQotICAgICAqIEBzZWUgI0NPTkRJVElPTkFMX0lHTk9SRQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0Q29uZGl0aW9uYWwgKHNob3J0IHR5cGUsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiAgewotICAgIH0gLy8gc3RhcnRDb25kaXRpb25hbChzaG9ydCkKLQotICAgIC8qKgotICAgICAqIFRoZSBlbmQgb2YgYSBjb25kaXRpb25hbCBzZWN0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIGF1Z3MgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZENvbmRpdGlvbmFsIChBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgIH0gLy8gZW5kQ29uZGl0aW9uYWwoKQotCi0KLSAgICAvKioKLSAgICAgKiBUaGUgc3RhcnQgb2YgdGhlIERURCBleHRlcm5hbCBzdWJzZXQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYXVncyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnRFeHRlcm5hbFN1YnNldCAoWE1MUmVzb3VyY2VJZGVudGlmaWVyIGlkZW50aWZpZXIsCi0gICAgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKERFQlVHX0VWRU5UUykgewotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuICgiPT0+c3RhcnRFeHRlcm5hbFN1YnNldCIpOwotICAgICAgICAgICAgaWYgKERFQlVHX0JBU0VVUkkpIHsKLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4gKCIgICBleHBhbmRlZFN5c3RlbUlkOiAiK2lkZW50aWZpZXIuZ2V0RXhwYW5kZWRTeXN0ZW1JZCAoKSk7Ci0gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuICgiICAgYmFzZVVSSToiKyBpZGVudGlmaWVyLmdldEJhc2VTeXN0ZW1JZCAoKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZkJhc2VVUklTdGFjay5wdXNoIChpZGVudGlmaWVyLmdldEJhc2VTeXN0ZW1JZCAoKSk7Ci0gICAgICAgIGZJbkRUREV4dGVybmFsU3Vic2V0ID0gdHJ1ZTsKLSAgICB9IC8vIHN0YXJ0RXh0ZXJuYWxTdWJzZXQoQXVnbWVudGF0aW9ucykKLQotICAgIC8qKgotICAgICAqIFRoZSBlbmQgb2YgdGhlIERURCBleHRlcm5hbCBzdWJzZXQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYXVncyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kRXh0ZXJuYWxTdWJzZXQgKEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIGZJbkRUREV4dGVybmFsU3Vic2V0ID0gZmFsc2U7Ci0gICAgICAgIGZCYXNlVVJJU3RhY2sucG9wICgpOwotICAgIH0gLy8gZW5kRXh0ZXJuYWxTdWJzZXQoQXVnbWVudGF0aW9ucykKLQotICAgIC8qKgotICAgICAqIEFuIGludGVybmFsIGVudGl0eSBkZWNsYXJhdGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBlbnRpdHkuIFBhcmFtZXRlciBlbnRpdHkgbmFtZXMgc3RhcnQgd2l0aAotICAgICAqICAgICAgICAgICAgICclJywgd2hlcmVhcyB0aGUgbmFtZSBvZiBhIGdlbmVyYWwgZW50aXR5IGlzIGp1c3QgdGhlCi0gICAgICogICAgICAgICAgICAgZW50aXR5IG5hbWUuCi0gICAgICogQHBhcmFtIHRleHQgVGhlIHZhbHVlIG9mIHRoZSBlbnRpdHkuCi0gICAgICogQHBhcmFtIG5vbk5vcm1hbGl6ZWRUZXh0IFRoZSBub24tbm9ybWFsaXplZCB2YWx1ZSBvZiB0aGUgZW50aXR5LiBUaGlzCi0gICAgICogICAgICAgICAgICAgdmFsdWUgY29udGFpbnMgdGhlIHNhbWUgc2VxdWVuY2Ugb2YgY2hhcmFjdGVycyB0aGF0IHdhcyBpbgotICAgICAqICAgICAgICAgICAgIHRoZSBpbnRlcm5hbCBlbnRpdHkgZGVjbGFyYXRpb24sIHdpdGhvdXQgYW55IGVudGl0eQotICAgICAqICAgICAgICAgICAgIHJlZmVyZW5jZXMgZXhwYW5kZWQuCi0gICAgICogQHBhcmFtIGF1Z3MgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGludGVybmFsRW50aXR5RGVjbCAoU3RyaW5nIG5hbWUsIFhNTFN0cmluZyB0ZXh0LAotICAgIFhNTFN0cmluZyBub25Ob3JtYWxpemVkVGV4dCwKLSAgICBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotCi0gICAgICAgIGlmIChERUJVR19FVkVOVFMpIHsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbiAoIj09PmludGVybmFsRW50aXR5RGVjbDogIituYW1lKTsKLSAgICAgICAgICAgIGlmIChERUJVR19CQVNFVVJJKSB7Ci0gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuICgiICAgYmFzZVVSSToiKyAoU3RyaW5nKWZCYXNlVVJJU3RhY2sucGVlayAoKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgLy8gaW50ZXJuYWwgc3Vic2V0IHN0cmluZwotICAgICAgICBpZiAoZkludGVybmFsU3Vic2V0ICE9IG51bGwgJiYgIWZJbkRUREV4dGVybmFsU3Vic2V0KSB7Ci0gICAgICAgICAgICBmSW50ZXJuYWxTdWJzZXQuYXBwZW5kICgiPCFFTlRJVFkgIik7Ci0gICAgICAgICAgICBpZiAobmFtZS5zdGFydHNXaXRoICgiJSIpKSB7Ci0gICAgICAgICAgICAgICAgZkludGVybmFsU3Vic2V0LmFwcGVuZCAoIiUgIik7Ci0gICAgICAgICAgICAgICAgZkludGVybmFsU3Vic2V0LmFwcGVuZCAobmFtZS5zdWJzdHJpbmcgKDEpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIGZJbnRlcm5hbFN1YnNldC5hcHBlbmQgKG5hbWUpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZkludGVybmFsU3Vic2V0LmFwcGVuZCAoJyAnKTsKLSAgICAgICAgICAgIFN0cmluZyB2YWx1ZSA9IG5vbk5vcm1hbGl6ZWRUZXh0LnRvU3RyaW5nICgpOwotICAgICAgICAgICAgYm9vbGVhbiBzaW5nbGVRdW90ZSA9IHZhbHVlLmluZGV4T2YgKCdcJycpID09IC0xOwotICAgICAgICAgICAgZkludGVybmFsU3Vic2V0LmFwcGVuZCAoc2luZ2xlUXVvdGUgPyAnXCcnIDogJyInKTsKLSAgICAgICAgICAgIGZJbnRlcm5hbFN1YnNldC5hcHBlbmQgKHZhbHVlKTsKLSAgICAgICAgICAgIGZJbnRlcm5hbFN1YnNldC5hcHBlbmQgKHNpbmdsZVF1b3RlID8gJ1wnJyA6ICciJyk7Ci0gICAgICAgICAgICBmSW50ZXJuYWxTdWJzZXQuYXBwZW5kICgiPlxuIik7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBOT1RFOiBXZSBvbmx5IGtub3cgaG93IHRvIGNyZWF0ZSB0aGVzZSBub2RlcyBmb3IgdGhlIFhlcmNlcwotICAgICAgICAvLyAgICAgICBET00gaW1wbGVtZW50YXRpb24gYmVjYXVzZSBET00gTGV2ZWwgMiBkb2VzIG5vdCBzcGVjaWZ5Ci0gICAgICAgIC8vICAgICAgIHRoYXQgZnVuY3Rpb25hbGl0eS4gLUFjCi0KLSAgICAgICAgLy8gY3JlYXRlIGZ1bGwgbm9kZQotICAgICAgICAvLyBkb24ndCBhZGQgcGFyYW1ldGVyIGVudGl0aWVzIQotICAgICAgICBpZihuYW1lLnN0YXJ0c1dpdGggKCIlIikpCi0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIGlmIChmRG9jdW1lbnRUeXBlICE9IG51bGwpIHsKLSAgICAgICAgICAgIE5hbWVkTm9kZU1hcCBlbnRpdGllcyA9IGZEb2N1bWVudFR5cGUuZ2V0RW50aXRpZXMgKCk7Ci0gICAgICAgICAgICBFbnRpdHlJbXBsIGVudGl0eSA9IChFbnRpdHlJbXBsKWVudGl0aWVzLmdldE5hbWVkSXRlbSAobmFtZSk7Ci0gICAgICAgICAgICBpZiAoZW50aXR5ID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBlbnRpdHkgPSAoRW50aXR5SW1wbClmRG9jdW1lbnRJbXBsLmNyZWF0ZUVudGl0eSAobmFtZSk7Ci0gICAgICAgICAgICAgICAgZW50aXR5LnNldEJhc2VVUkkgKChTdHJpbmcpZkJhc2VVUklTdGFjay5wZWVrICgpKTsKLSAgICAgICAgICAgICAgICBlbnRpdGllcy5zZXROYW1lZEl0ZW0gKGVudGl0eSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBjcmVhdGUgZGVmZXJyZWQgbm9kZQotICAgICAgICBpZiAoZkRvY3VtZW50VHlwZUluZGV4ICE9IC0xKSB7Ci0gICAgICAgICAgICBib29sZWFuIGZvdW5kID0gZmFsc2U7Ci0gICAgICAgICAgICBpbnQgbm9kZSA9IGZEZWZlcnJlZERvY3VtZW50SW1wbC5nZXRMYXN0Q2hpbGQgKGZEb2N1bWVudFR5cGVJbmRleCwgZmFsc2UpOwotICAgICAgICAgICAgd2hpbGUgKG5vZGUgIT0gLTEpIHsKLSAgICAgICAgICAgICAgICBzaG9ydCBub2RlVHlwZSA9IGZEZWZlcnJlZERvY3VtZW50SW1wbC5nZXROb2RlVHlwZSAobm9kZSwgZmFsc2UpOwotICAgICAgICAgICAgICAgIGlmIChub2RlVHlwZSA9PSBOb2RlLkVOVElUWV9OT0RFKSB7Ci0gICAgICAgICAgICAgICAgICAgIFN0cmluZyBub2RlTmFtZSA9IGZEZWZlcnJlZERvY3VtZW50SW1wbC5nZXROb2RlTmFtZSAobm9kZSwgZmFsc2UpOwotICAgICAgICAgICAgICAgICAgICBpZiAobm9kZU5hbWUuZXF1YWxzIChuYW1lKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgZm91bmQgPSB0cnVlOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgbm9kZSA9IGZEZWZlcnJlZERvY3VtZW50SW1wbC5nZXRSZWFsUHJldlNpYmxpbmcgKG5vZGUsIGZhbHNlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmICghZm91bmQpIHsKLSAgICAgICAgICAgICAgICBpbnQgZW50aXR5SW5kZXggPQotICAgICAgICAgICAgICAgIGZEZWZlcnJlZERvY3VtZW50SW1wbC5jcmVhdGVEZWZlcnJlZEVudGl0eSAobmFtZSwgbnVsbCwgbnVsbCwgbnVsbCwgKFN0cmluZylmQmFzZVVSSVN0YWNrLnBlZWsgKCkpOwotICAgICAgICAgICAgICAgIGZEZWZlcnJlZERvY3VtZW50SW1wbC5hcHBlbmRDaGlsZCAoZkRvY3VtZW50VHlwZUluZGV4LCBlbnRpdHlJbmRleCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgIH0gLy8gaW50ZXJuYWxFbnRpdHlEZWNsKFN0cmluZyxYTUxTdHJpbmcsWE1MU3RyaW5nKQotCi0gICAgLyoqCi0gICAgICogQW4gZXh0ZXJuYWwgZW50aXR5IGRlY2xhcmF0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgICAgIFRoZSBuYW1lIG9mIHRoZSBlbnRpdHkuIFBhcmFtZXRlciBlbnRpdHkgbmFtZXMgc3RhcnQKLSAgICAgKiAgICAgICAgICAgICAgICAgd2l0aCAnJScsIHdoZXJlYXMgdGhlIG5hbWUgb2YgYSBnZW5lcmFsIGVudGl0eSBpcyBqdXN0Ci0gICAgICogICAgICAgICAgICAgICAgIHRoZSBlbnRpdHkgbmFtZS4KLSAgICAgKiBAcGFyYW0gaWRlbnRpZmllciAgICBBbiBvYmplY3QgY29udGFpbmluZyBhbGwgbG9jYXRpb24gaW5mb3JtYXRpb24KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBwZXJ0aW5lbnQgdG8gdGhpcyBub3RhdGlvbi4KLSAgICAgKiBAcGFyYW0gYXVncyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZXh0ZXJuYWxFbnRpdHlEZWNsIChTdHJpbmcgbmFtZSwgWE1MUmVzb3VyY2VJZGVudGlmaWVyIGlkZW50aWZpZXIsCi0gICAgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLQotCi0gICAgICAgIGlmIChERUJVR19FVkVOVFMpIHsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbiAoIj09PmV4dGVybmFsRW50aXR5RGVjbDogIituYW1lKTsKLSAgICAgICAgICAgIGlmIChERUJVR19CQVNFVVJJKSB7Ci0gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuICgiICAgZXhwYW5kZWRTeXN0ZW1JZDoiKyBpZGVudGlmaWVyLmdldEV4cGFuZGVkU3lzdGVtSWQgKCkpOwotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbiAoIiAgIGJhc2VVUkk6IisgaWRlbnRpZmllci5nZXRCYXNlU3lzdGVtSWQgKCkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIC8vIGludGVybmFsIHN1YnNldCBzdHJpbmcKLSAgICAgICAgU3RyaW5nIHB1YmxpY0lkID0gaWRlbnRpZmllci5nZXRQdWJsaWNJZCAoKTsKLSAgICAgICAgU3RyaW5nIGxpdGVyYWxTeXN0ZW1JZCA9IGlkZW50aWZpZXIuZ2V0TGl0ZXJhbFN5c3RlbUlkICgpOwotICAgICAgICBpZiAoZkludGVybmFsU3Vic2V0ICE9IG51bGwgJiYgIWZJbkRUREV4dGVybmFsU3Vic2V0KSB7Ci0gICAgICAgICAgICBmSW50ZXJuYWxTdWJzZXQuYXBwZW5kICgiPCFFTlRJVFkgIik7Ci0gICAgICAgICAgICBpZiAobmFtZS5zdGFydHNXaXRoICgiJSIpKSB7Ci0gICAgICAgICAgICAgICAgZkludGVybmFsU3Vic2V0LmFwcGVuZCAoIiUgIik7Ci0gICAgICAgICAgICAgICAgZkludGVybmFsU3Vic2V0LmFwcGVuZCAobmFtZS5zdWJzdHJpbmcgKDEpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIGZJbnRlcm5hbFN1YnNldC5hcHBlbmQgKG5hbWUpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZkludGVybmFsU3Vic2V0LmFwcGVuZCAoJyAnKTsKLSAgICAgICAgICAgIGlmIChwdWJsaWNJZCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZkludGVybmFsU3Vic2V0LmFwcGVuZCAoIlBVQkxJQyAnIik7Ci0gICAgICAgICAgICAgICAgZkludGVybmFsU3Vic2V0LmFwcGVuZCAocHVibGljSWQpOwotICAgICAgICAgICAgICAgIGZJbnRlcm5hbFN1YnNldC5hcHBlbmQgKCInICciKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIGZJbnRlcm5hbFN1YnNldC5hcHBlbmQgKCJTWVNURU0gJyIpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZkludGVybmFsU3Vic2V0LmFwcGVuZCAobGl0ZXJhbFN5c3RlbUlkKTsKLSAgICAgICAgICAgIGZJbnRlcm5hbFN1YnNldC5hcHBlbmQgKCInPlxuIik7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBOT1RFOiBXZSBvbmx5IGtub3cgaG93IHRvIGNyZWF0ZSB0aGVzZSBub2RlcyBmb3IgdGhlIFhlcmNlcwotICAgICAgICAvLyAgICAgICBET00gaW1wbGVtZW50YXRpb24gYmVjYXVzZSBET00gTGV2ZWwgMiBkb2VzIG5vdCBzcGVjaWZ5Ci0gICAgICAgIC8vICAgICAgIHRoYXQgZnVuY3Rpb25hbGl0eS4gLUFjCi0KLSAgICAgICAgLy8gY3JlYXRlIGZ1bGwgbm9kZQotICAgICAgICAvLyBkb24ndCBhZGQgcGFyYW1ldGVyIGVudGl0aWVzIQotICAgICAgICBpZihuYW1lLnN0YXJ0c1dpdGggKCIlIikpCi0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIGlmIChmRG9jdW1lbnRUeXBlICE9IG51bGwpIHsKLSAgICAgICAgICAgIE5hbWVkTm9kZU1hcCBlbnRpdGllcyA9IGZEb2N1bWVudFR5cGUuZ2V0RW50aXRpZXMgKCk7Ci0gICAgICAgICAgICBFbnRpdHlJbXBsIGVudGl0eSA9IChFbnRpdHlJbXBsKWVudGl0aWVzLmdldE5hbWVkSXRlbSAobmFtZSk7Ci0gICAgICAgICAgICBpZiAoZW50aXR5ID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBlbnRpdHkgPSAoRW50aXR5SW1wbClmRG9jdW1lbnRJbXBsLmNyZWF0ZUVudGl0eSAobmFtZSk7Ci0gICAgICAgICAgICAgICAgZW50aXR5LnNldFB1YmxpY0lkIChwdWJsaWNJZCk7Ci0gICAgICAgICAgICAgICAgZW50aXR5LnNldFN5c3RlbUlkIChsaXRlcmFsU3lzdGVtSWQpOwotICAgICAgICAgICAgICAgIGVudGl0eS5zZXRCYXNlVVJJIChpZGVudGlmaWVyLmdldEJhc2VTeXN0ZW1JZCAoKSk7Ci0gICAgICAgICAgICAgICAgZW50aXRpZXMuc2V0TmFtZWRJdGVtIChlbnRpdHkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gY3JlYXRlIGRlZmVycmVkIG5vZGUKLSAgICAgICAgaWYgKGZEb2N1bWVudFR5cGVJbmRleCAhPSAtMSkgewotICAgICAgICAgICAgYm9vbGVhbiBmb3VuZCA9IGZhbHNlOwotICAgICAgICAgICAgaW50IG5vZGVJbmRleCA9IGZEZWZlcnJlZERvY3VtZW50SW1wbC5nZXRMYXN0Q2hpbGQgKGZEb2N1bWVudFR5cGVJbmRleCwgZmFsc2UpOwotICAgICAgICAgICAgd2hpbGUgKG5vZGVJbmRleCAhPSAtMSkgewotICAgICAgICAgICAgICAgIHNob3J0IG5vZGVUeXBlID0gZkRlZmVycmVkRG9jdW1lbnRJbXBsLmdldE5vZGVUeXBlIChub2RlSW5kZXgsIGZhbHNlKTsKLSAgICAgICAgICAgICAgICBpZiAobm9kZVR5cGUgPT0gTm9kZS5FTlRJVFlfTk9ERSkgewotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbm9kZU5hbWUgPSBmRGVmZXJyZWREb2N1bWVudEltcGwuZ2V0Tm9kZU5hbWUgKG5vZGVJbmRleCwgZmFsc2UpOwotICAgICAgICAgICAgICAgICAgICBpZiAobm9kZU5hbWUuZXF1YWxzIChuYW1lKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgZm91bmQgPSB0cnVlOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgbm9kZUluZGV4ID0gZkRlZmVycmVkRG9jdW1lbnRJbXBsLmdldFJlYWxQcmV2U2libGluZyAobm9kZUluZGV4LCBmYWxzZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoIWZvdW5kKSB7Ci0gICAgICAgICAgICAgICAgaW50IGVudGl0eUluZGV4ID0gZkRlZmVycmVkRG9jdW1lbnRJbXBsLmNyZWF0ZURlZmVycmVkRW50aXR5ICgKLSAgICAgICAgICAgICAgICBuYW1lLCBwdWJsaWNJZCwgbGl0ZXJhbFN5c3RlbUlkLCBudWxsLCBpZGVudGlmaWVyLmdldEJhc2VTeXN0ZW1JZCAoKSk7Ci0gICAgICAgICAgICAgICAgZkRlZmVycmVkRG9jdW1lbnRJbXBsLmFwcGVuZENoaWxkIChmRG9jdW1lbnRUeXBlSW5kZXgsIGVudGl0eUluZGV4KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgfSAvLyBleHRlcm5hbEVudGl0eURlY2woU3RyaW5nLFhNTFJlc291cmNlSWRlbnRpZmllciwgQXVnbWVudGF0aW9ucykKLQotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2Qgbm90aWZpZXMgb2YgdGhlIHN0YXJ0IG9mIGEgcGFyYW1ldGVyIGVudGl0eS4gVGhlIHBhcmFtZXRlcgotICAgICAqIGVudGl0eSBuYW1lIHN0YXJ0IHdpdGggYSAnJScgY2hhcmFjdGVyLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgICAgIFRoZSBuYW1lIG9mIHRoZSBwYXJhbWV0ZXIgZW50aXR5LgotICAgICAqIEBwYXJhbSBpZGVudGlmaWVyIFRoZSByZXNvdXJjZSBpZGVudGlmaWVyLgotICAgICAqIEBwYXJhbSBlbmNvZGluZyBUaGUgYXV0by1kZXRlY3RlZCBJQU5BIGVuY29kaW5nIG5hbWUgb2YgdGhlIGVudGl0eQotICAgICAqICAgICAgICAgICAgICAgICBzdHJlYW0uIFRoaXMgdmFsdWUgd2lsbCBiZSBudWxsIGluIHRob3NlIHNpdHVhdGlvbnMKLSAgICAgKiAgICAgICAgICAgICAgICAgd2hlcmUgdGhlIGVudGl0eSBlbmNvZGluZyBpcyBub3QgYXV0by1kZXRlY3RlZCAoZS5nLgotICAgICAqICAgICAgICAgICAgICAgICBpbnRlcm5hbCBwYXJhbWV0ZXIgZW50aXRpZXMpLgotICAgICAqIEBwYXJhbSBhdWdzIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydFBhcmFtZXRlckVudGl0eSAoU3RyaW5nIG5hbWUsCi0gICAgWE1MUmVzb3VyY2VJZGVudGlmaWVyIGlkZW50aWZpZXIsCi0gICAgU3RyaW5nIGVuY29kaW5nLAotICAgIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChERUJVR19FVkVOVFMpIHsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbiAoIj09PnN0YXJ0UGFyYW1ldGVyRW50aXR5OiAiK25hbWUpOwotICAgICAgICAgICAgaWYgKERFQlVHX0JBU0VVUkkpIHsKLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4gKCIgICBleHBhbmRlZFN5c3RlbUlkOiAiK2lkZW50aWZpZXIuZ2V0RXhwYW5kZWRTeXN0ZW1JZCAoKSk7Ci0gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuICgiICAgYmFzZVVSSToiKyBpZGVudGlmaWVyLmdldEJhc2VTeXN0ZW1JZCAoKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGF1Z3MgIT0gbnVsbCAmJiBmSW50ZXJuYWxTdWJzZXQgIT0gbnVsbCAmJgotICAgICAgICAgICAgIWZJbkRUREV4dGVybmFsU3Vic2V0ICYmCi0gICAgICAgICAgICBCb29sZWFuLlRSVUUuZXF1YWxzKGF1Z3MuZ2V0SXRlbShDb25zdGFudHMuRU5USVRZX1NLSVBQRUQpKSkgewotICAgICAgICAgICAgZkludGVybmFsU3Vic2V0LmFwcGVuZChuYW1lKS5hcHBlbmQoIjtcbiIpOwotICAgICAgICB9Ci0gICAgICAgIGZCYXNlVVJJU3RhY2sucHVzaCAoaWRlbnRpZmllci5nZXRFeHBhbmRlZFN5c3RlbUlkICgpKTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIG5vdGlmaWVzIHRoZSBlbmQgb2YgYSBwYXJhbWV0ZXIgZW50aXR5LiBQYXJhbWV0ZXIgZW50aXR5Ci0gICAgICogbmFtZXMgYmVnaW4gd2l0aCBhICclJyBjaGFyYWN0ZXIuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgcGFyYW1ldGVyIGVudGl0eS4KLSAgICAgKiBAcGFyYW0gYXVncyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kUGFyYW1ldGVyRW50aXR5IChTdHJpbmcgbmFtZSwgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLQotICAgICAgICBpZiAoREVCVUdfRVZFTlRTKSB7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4gKCI9PT5lbmRQYXJhbWV0ZXJFbnRpdHk6ICIrbmFtZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZkJhc2VVUklTdGFjay5wb3AgKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQW4gdW5wYXJzZWQgZW50aXR5IGRlY2xhcmF0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgICAgIFRoZSBuYW1lIG9mIHRoZSBlbnRpdHkuCi0gICAgICogQHBhcmFtIGlkZW50aWZpZXIgICAgQW4gb2JqZWN0IGNvbnRhaW5pbmcgYWxsIGxvY2F0aW9uIGluZm9ybWF0aW9uCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgcGVydGluZW50IHRvIHRoaXMgZW50aXR5LgotICAgICAqIEBwYXJhbSBub3RhdGlvbiBUaGUgbmFtZSBvZiB0aGUgbm90YXRpb24uCi0gICAgICogQHBhcmFtIGF1Z3MgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHVucGFyc2VkRW50aXR5RGVjbCAoU3RyaW5nIG5hbWUsIFhNTFJlc291cmNlSWRlbnRpZmllciBpZGVudGlmaWVyLAotICAgIFN0cmluZyBub3RhdGlvbiwgQXVnbWVudGF0aW9ucyBhdWdzKQotICAgIHRocm93cyBYTklFeGNlcHRpb24gewotCi0gICAgICAgIGlmIChERUJVR19FVkVOVFMpIHsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbiAoIj09PnVucGFyc2VkRW50aXR5RGVjbDogIituYW1lKTsKLSAgICAgICAgICAgIGlmIChERUJVR19CQVNFVVJJKSB7Ci0gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuICgiICAgZXhwYW5kZWRTeXN0ZW1JZDoiKyBpZGVudGlmaWVyLmdldEV4cGFuZGVkU3lzdGVtSWQgKCkpOwotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbiAoIiAgIGJhc2VVUkk6IisgaWRlbnRpZmllci5nZXRCYXNlU3lzdGVtSWQgKCkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIC8vIGludGVybmFsIHN1YnNldCBzdHJpbmcKLSAgICAgICAgU3RyaW5nIHB1YmxpY0lkID0gaWRlbnRpZmllci5nZXRQdWJsaWNJZCAoKTsKLSAgICAgICAgU3RyaW5nIGxpdGVyYWxTeXN0ZW1JZCA9IGlkZW50aWZpZXIuZ2V0TGl0ZXJhbFN5c3RlbUlkICgpOwotICAgICAgICBpZiAoZkludGVybmFsU3Vic2V0ICE9IG51bGwgJiYgIWZJbkRUREV4dGVybmFsU3Vic2V0KSB7Ci0gICAgICAgICAgICBmSW50ZXJuYWxTdWJzZXQuYXBwZW5kICgiPCFFTlRJVFkgIik7Ci0gICAgICAgICAgICBmSW50ZXJuYWxTdWJzZXQuYXBwZW5kIChuYW1lKTsKLSAgICAgICAgICAgIGZJbnRlcm5hbFN1YnNldC5hcHBlbmQgKCcgJyk7Ci0gICAgICAgICAgICBpZiAocHVibGljSWQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZJbnRlcm5hbFN1YnNldC5hcHBlbmQgKCJQVUJMSUMgJyIpOwotICAgICAgICAgICAgICAgIGZJbnRlcm5hbFN1YnNldC5hcHBlbmQgKHB1YmxpY0lkKTsKLSAgICAgICAgICAgICAgICBpZiAobGl0ZXJhbFN5c3RlbUlkICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgZkludGVybmFsU3Vic2V0LmFwcGVuZCAoIicgJyIpOwotICAgICAgICAgICAgICAgICAgICBmSW50ZXJuYWxTdWJzZXQuYXBwZW5kIChsaXRlcmFsU3lzdGVtSWQpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIGZJbnRlcm5hbFN1YnNldC5hcHBlbmQgKCJTWVNURU0gJyIpOwotICAgICAgICAgICAgICAgIGZJbnRlcm5hbFN1YnNldC5hcHBlbmQgKGxpdGVyYWxTeXN0ZW1JZCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmSW50ZXJuYWxTdWJzZXQuYXBwZW5kICgiJyBOREFUQSAiKTsKLSAgICAgICAgICAgIGZJbnRlcm5hbFN1YnNldC5hcHBlbmQgKG5vdGF0aW9uKTsKLSAgICAgICAgICAgIGZJbnRlcm5hbFN1YnNldC5hcHBlbmQgKCI+XG4iKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIE5PVEU6IFdlIG9ubHkga25vdyBob3cgdG8gY3JlYXRlIHRoZXNlIG5vZGVzIGZvciB0aGUgWGVyY2VzCi0gICAgICAgIC8vICAgICAgIERPTSBpbXBsZW1lbnRhdGlvbiBiZWNhdXNlIERPTSBMZXZlbCAyIGRvZXMgbm90IHNwZWNpZnkKLSAgICAgICAgLy8gICAgICAgdGhhdCBmdW5jdGlvbmFsaXR5LiAtQWMKLQotICAgICAgICAvLyBjcmVhdGUgZnVsbCBub2RlCi0gICAgICAgIGlmIChmRG9jdW1lbnRUeXBlICE9IG51bGwpIHsKLSAgICAgICAgICAgIE5hbWVkTm9kZU1hcCBlbnRpdGllcyA9IGZEb2N1bWVudFR5cGUuZ2V0RW50aXRpZXMgKCk7Ci0gICAgICAgICAgICBFbnRpdHlJbXBsIGVudGl0eSA9IChFbnRpdHlJbXBsKWVudGl0aWVzLmdldE5hbWVkSXRlbSAobmFtZSk7Ci0gICAgICAgICAgICBpZiAoZW50aXR5ID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBlbnRpdHkgPSAoRW50aXR5SW1wbClmRG9jdW1lbnRJbXBsLmNyZWF0ZUVudGl0eSAobmFtZSk7Ci0gICAgICAgICAgICAgICAgZW50aXR5LnNldFB1YmxpY0lkIChwdWJsaWNJZCk7Ci0gICAgICAgICAgICAgICAgZW50aXR5LnNldFN5c3RlbUlkIChsaXRlcmFsU3lzdGVtSWQpOwotICAgICAgICAgICAgICAgIGVudGl0eS5zZXROb3RhdGlvbk5hbWUgKG5vdGF0aW9uKTsKLSAgICAgICAgICAgICAgICBlbnRpdHkuc2V0QmFzZVVSSSAoaWRlbnRpZmllci5nZXRCYXNlU3lzdGVtSWQgKCkpOwotICAgICAgICAgICAgICAgIGVudGl0aWVzLnNldE5hbWVkSXRlbSAoZW50aXR5KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIGNyZWF0ZSBkZWZlcnJlZCBub2RlCi0gICAgICAgIGlmIChmRG9jdW1lbnRUeXBlSW5kZXggIT0gLTEpIHsKLSAgICAgICAgICAgIGJvb2xlYW4gZm91bmQgPSBmYWxzZTsKLSAgICAgICAgICAgIGludCBub2RlSW5kZXggPSBmRGVmZXJyZWREb2N1bWVudEltcGwuZ2V0TGFzdENoaWxkIChmRG9jdW1lbnRUeXBlSW5kZXgsIGZhbHNlKTsKLSAgICAgICAgICAgIHdoaWxlIChub2RlSW5kZXggIT0gLTEpIHsKLSAgICAgICAgICAgICAgICBzaG9ydCBub2RlVHlwZSA9IGZEZWZlcnJlZERvY3VtZW50SW1wbC5nZXROb2RlVHlwZSAobm9kZUluZGV4LCBmYWxzZSk7Ci0gICAgICAgICAgICAgICAgaWYgKG5vZGVUeXBlID09IE5vZGUuRU5USVRZX05PREUpIHsKLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG5vZGVOYW1lID0gZkRlZmVycmVkRG9jdW1lbnRJbXBsLmdldE5vZGVOYW1lIChub2RlSW5kZXgsIGZhbHNlKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKG5vZGVOYW1lLmVxdWFscyAobmFtZSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZvdW5kID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIG5vZGVJbmRleCA9IGZEZWZlcnJlZERvY3VtZW50SW1wbC5nZXRSZWFsUHJldlNpYmxpbmcgKG5vZGVJbmRleCwgZmFsc2UpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKCFmb3VuZCkgewotICAgICAgICAgICAgICAgIGludCBlbnRpdHlJbmRleCA9IGZEZWZlcnJlZERvY3VtZW50SW1wbC5jcmVhdGVEZWZlcnJlZEVudGl0eSAoCi0gICAgICAgICAgICAgICAgbmFtZSwgcHVibGljSWQsIGxpdGVyYWxTeXN0ZW1JZCwgbm90YXRpb24sIGlkZW50aWZpZXIuZ2V0QmFzZVN5c3RlbUlkICgpKTsKLSAgICAgICAgICAgICAgICBmRGVmZXJyZWREb2N1bWVudEltcGwuYXBwZW5kQ2hpbGQgKGZEb2N1bWVudFR5cGVJbmRleCwgZW50aXR5SW5kZXgpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICB9IC8vIHVucGFyc2VkRW50aXR5RGVjbChTdHJpbmcsWE1MUmVzb3VyY2VJZGVudGlmaWVyLCBTdHJpbmcsIEF1Z21lbnRhdGlvbnMpCi0KLSAgICAvKioKLSAgICAgKiBBIG5vdGF0aW9uIGRlY2xhcmF0aW9uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSAgICAgVGhlIG5hbWUgb2YgdGhlIG5vdGF0aW9uLgotICAgICAqIEBwYXJhbSBpZGVudGlmaWVyICAgIEFuIG9iamVjdCBjb250YWluaW5nIGFsbCBsb2NhdGlvbiBpbmZvcm1hdGlvbgotICAgICAqICAgICAgICAgICAgICAgICAgICAgIHBlcnRpbmVudCB0byB0aGlzIG5vdGF0aW9uLgotICAgICAqIEBwYXJhbSBhdWdzIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBub3RhdGlvbkRlY2wgKFN0cmluZyBuYW1lLCBYTUxSZXNvdXJjZUlkZW50aWZpZXIgaWRlbnRpZmllciwKLSAgICBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotCi0gICAgICAgIC8vIGludGVybmFsIHN1YnNldCBzdHJpbmcKLSAgICAgICAgU3RyaW5nIHB1YmxpY0lkID0gaWRlbnRpZmllci5nZXRQdWJsaWNJZCAoKTsKLSAgICAgICAgU3RyaW5nIGxpdGVyYWxTeXN0ZW1JZCA9IGlkZW50aWZpZXIuZ2V0TGl0ZXJhbFN5c3RlbUlkICgpOwotICAgICAgICBpZiAoZkludGVybmFsU3Vic2V0ICE9IG51bGwgJiYgIWZJbkRUREV4dGVybmFsU3Vic2V0KSB7Ci0gICAgICAgICAgICBmSW50ZXJuYWxTdWJzZXQuYXBwZW5kICgiPCFOT1RBVElPTiAiKTsKLSAgICAgICAgICAgIGZJbnRlcm5hbFN1YnNldC5hcHBlbmQgKG5hbWUpOwotICAgICAgICAgICAgaWYgKHB1YmxpY0lkICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmSW50ZXJuYWxTdWJzZXQuYXBwZW5kICgiIFBVQkxJQyAnIik7Ci0gICAgICAgICAgICAgICAgZkludGVybmFsU3Vic2V0LmFwcGVuZCAocHVibGljSWQpOwotICAgICAgICAgICAgICAgIGlmIChsaXRlcmFsU3lzdGVtSWQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBmSW50ZXJuYWxTdWJzZXQuYXBwZW5kICgiJyAnIik7Ci0gICAgICAgICAgICAgICAgICAgIGZJbnRlcm5hbFN1YnNldC5hcHBlbmQgKGxpdGVyYWxTeXN0ZW1JZCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgZkludGVybmFsU3Vic2V0LmFwcGVuZCAoIiBTWVNURU0gJyIpOwotICAgICAgICAgICAgICAgIGZJbnRlcm5hbFN1YnNldC5hcHBlbmQgKGxpdGVyYWxTeXN0ZW1JZCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmSW50ZXJuYWxTdWJzZXQuYXBwZW5kICgiJz5cbiIpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gTk9URTogV2Ugb25seSBrbm93IGhvdyB0byBjcmVhdGUgdGhlc2Ugbm9kZXMgZm9yIHRoZSBYZXJjZXMKLSAgICAgICAgLy8gICAgICAgRE9NIGltcGxlbWVudGF0aW9uIGJlY2F1c2UgRE9NIExldmVsIDIgZG9lcyBub3Qgc3BlY2lmeQotICAgICAgICAvLyAgICAgICB0aGF0IGZ1bmN0aW9uYWxpdHkuIC1BYwotCi0gICAgICAgIC8vIGNyZWF0ZSBmdWxsIG5vZGUKLSAgICAgICAgaWYgKGZEb2N1bWVudEltcGwgIT1udWxsICYmIGZEb2N1bWVudFR5cGUgIT0gbnVsbCkgewotICAgICAgICAgICAgTmFtZWROb2RlTWFwIG5vdGF0aW9ucyA9IGZEb2N1bWVudFR5cGUuZ2V0Tm90YXRpb25zICgpOwotICAgICAgICAgICAgaWYgKG5vdGF0aW9ucy5nZXROYW1lZEl0ZW0gKG5hbWUpID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBOb3RhdGlvbkltcGwgbm90YXRpb24gPSAoTm90YXRpb25JbXBsKWZEb2N1bWVudEltcGwuY3JlYXRlTm90YXRpb24gKG5hbWUpOwotICAgICAgICAgICAgICAgIG5vdGF0aW9uLnNldFB1YmxpY0lkIChwdWJsaWNJZCk7Ci0gICAgICAgICAgICAgICAgbm90YXRpb24uc2V0U3lzdGVtSWQgKGxpdGVyYWxTeXN0ZW1JZCk7Ci0gICAgICAgICAgICAgICAgbm90YXRpb24uc2V0QmFzZVVSSSAoaWRlbnRpZmllci5nZXRCYXNlU3lzdGVtSWQgKCkpOwotICAgICAgICAgICAgICAgIG5vdGF0aW9ucy5zZXROYW1lZEl0ZW0gKG5vdGF0aW9uKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIGNyZWF0ZSBkZWZlcnJlZCBub2RlCi0gICAgICAgIGlmIChmRG9jdW1lbnRUeXBlSW5kZXggIT0gLTEpIHsKLSAgICAgICAgICAgIGJvb2xlYW4gZm91bmQgPSBmYWxzZTsKLSAgICAgICAgICAgIGludCBub2RlSW5kZXggPSBmRGVmZXJyZWREb2N1bWVudEltcGwuZ2V0TGFzdENoaWxkIChmRG9jdW1lbnRUeXBlSW5kZXgsIGZhbHNlKTsKLSAgICAgICAgICAgIHdoaWxlIChub2RlSW5kZXggIT0gLTEpIHsKLSAgICAgICAgICAgICAgICBzaG9ydCBub2RlVHlwZSA9IGZEZWZlcnJlZERvY3VtZW50SW1wbC5nZXROb2RlVHlwZSAobm9kZUluZGV4LCBmYWxzZSk7Ci0gICAgICAgICAgICAgICAgaWYgKG5vZGVUeXBlID09IE5vZGUuTk9UQVRJT05fTk9ERSkgewotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbm9kZU5hbWUgPSBmRGVmZXJyZWREb2N1bWVudEltcGwuZ2V0Tm9kZU5hbWUgKG5vZGVJbmRleCwgZmFsc2UpOwotICAgICAgICAgICAgICAgICAgICBpZiAobm9kZU5hbWUuZXF1YWxzIChuYW1lKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgZm91bmQgPSB0cnVlOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgbm9kZUluZGV4ID0gZkRlZmVycmVkRG9jdW1lbnRJbXBsLmdldFByZXZTaWJsaW5nIChub2RlSW5kZXgsIGZhbHNlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmICghZm91bmQpIHsKLSAgICAgICAgICAgICAgICBpbnQgbm90YXRpb25JbmRleCA9IGZEZWZlcnJlZERvY3VtZW50SW1wbC5jcmVhdGVEZWZlcnJlZE5vdGF0aW9uICgKLSAgICAgICAgICAgICAgICBuYW1lLCBwdWJsaWNJZCwgbGl0ZXJhbFN5c3RlbUlkLCBpZGVudGlmaWVyLmdldEJhc2VTeXN0ZW1JZCAoKSk7Ci0gICAgICAgICAgICAgICAgZkRlZmVycmVkRG9jdW1lbnRJbXBsLmFwcGVuZENoaWxkIChmRG9jdW1lbnRUeXBlSW5kZXgsIG5vdGF0aW9uSW5kZXgpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICB9IC8vIG5vdGF0aW9uRGVjbChTdHJpbmcsWE1MUmVzb3VyY2VJZGVudGlmaWVyLCBBdWdtZW50YXRpb25zKQotCi0gICAgLyoqCi0gICAgICogQ2hhcmFjdGVycyB3aXRoaW4gYW4gSUdOT1JFIGNvbmRpdGlvbmFsIHNlY3Rpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdGV4dCBUaGUgaWdub3JlZCB0ZXh0LgotICAgICAqIEBwYXJhbSBhdWdzIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBpZ25vcmVkQ2hhcmFjdGVycyAoWE1MU3RyaW5nIHRleHQsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgfSAvLyBpZ25vcmVkQ2hhcmFjdGVycyhYTUxTdHJpbmcsIEF1Z21lbnRhdGlvbnMpCi0KLQotICAgIC8qKgotICAgICAqIEFuIGVsZW1lbnQgZGVjbGFyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSAgICAgICAgIFRoZSBuYW1lIG9mIHRoZSBlbGVtZW50LgotICAgICAqIEBwYXJhbSBjb250ZW50TW9kZWwgVGhlIGVsZW1lbnQgY29udGVudCBtb2RlbC4KLSAgICAgKiBAcGFyYW0gYXVncyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZWxlbWVudERlY2wgKFN0cmluZyBuYW1lLCBTdHJpbmcgY29udGVudE1vZGVsLCBBdWdtZW50YXRpb25zIGF1Z3MpCi0gICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy8gaW50ZXJuYWwgc3Vic2V0IHN0cmluZwotICAgICAgICBpZiAoZkludGVybmFsU3Vic2V0ICE9IG51bGwgJiYgIWZJbkRUREV4dGVybmFsU3Vic2V0KSB7Ci0gICAgICAgICAgICBmSW50ZXJuYWxTdWJzZXQuYXBwZW5kICgiPCFFTEVNRU5UICIpOwotICAgICAgICAgICAgZkludGVybmFsU3Vic2V0LmFwcGVuZCAobmFtZSk7Ci0gICAgICAgICAgICBmSW50ZXJuYWxTdWJzZXQuYXBwZW5kICgnICcpOwotICAgICAgICAgICAgZkludGVybmFsU3Vic2V0LmFwcGVuZCAoY29udGVudE1vZGVsKTsKLSAgICAgICAgICAgIGZJbnRlcm5hbFN1YnNldC5hcHBlbmQgKCI+XG4iKTsKLSAgICAgICAgfQotCi0gICAgfSAvLyBlbGVtZW50RGVjbChTdHJpbmcsU3RyaW5nKQotCi0gICAgLyoqCi0gICAgICogQW4gYXR0cmlidXRlIGRlY2xhcmF0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIGVsZW1lbnROYW1lICAgVGhlIG5hbWUgb2YgdGhlIGVsZW1lbnQgdGhhdCB0aGlzIGF0dHJpYnV0ZQotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGlzIGFzc29jaWF0ZWQgd2l0aC4KLSAgICAgKiBAcGFyYW0gYXR0cmlidXRlTmFtZSBUaGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlLgotICAgICAqIEBwYXJhbSB0eXBlICAgICAgICAgIFRoZSBhdHRyaWJ1dGUgdHlwZS4gVGhpcyB2YWx1ZSB3aWxsIGJlIG9uZSBvZgotICAgICAqICAgICAgICAgICAgICAgICAgICAgIHRoZSBmb2xsb3dpbmc6ICJDREFUQSIsICJFTlRJVFkiLCAiRU5USVRJRVMiLAotICAgICAqICAgICAgICAgICAgICAgICAgICAgICJFTlVNRVJBVElPTiIsICJJRCIsICJJRFJFRiIsICJJRFJFRlMiLAotICAgICAqICAgICAgICAgICAgICAgICAgICAgICJOTVRPS0VOIiwgIk5NVE9LRU5TIiwgb3IgIk5PVEFUSU9OIi4KLSAgICAgKiBAcGFyYW0gZW51bWVyYXRpb24gICBJZiB0aGUgdHlwZSBoYXMgdGhlIHZhbHVlICJFTlVNRVJBVElPTiIgb3IKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAiTk9UQVRJT04iLCB0aGlzIGFycmF5IGhvbGRzIHRoZSBhbGxvd2VkIGF0dHJpYnV0ZQotICAgICAqICAgICAgICAgICAgICAgICAgICAgIHZhbHVlczsgb3RoZXJ3aXNlLCB0aGlzIGFycmF5IGlzIG51bGwuCi0gICAgICogQHBhcmFtIGRlZmF1bHRUeXBlICAgVGhlIGF0dHJpYnV0ZSBkZWZhdWx0IHR5cGUuIFRoaXMgdmFsdWUgd2lsbCBiZQotICAgICAqICAgICAgICAgICAgICAgICAgICAgIG9uZSBvZiB0aGUgZm9sbG93aW5nOiAiI0ZJWEVEIiwgIiNJTVBMSUVEIiwKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAiI1JFUVVJUkVEIiwgb3IgbnVsbC4KLSAgICAgKiBAcGFyYW0gZGVmYXVsdFZhbHVlICBUaGUgYXR0cmlidXRlIGRlZmF1bHQgdmFsdWUsIG9yIG51bGwgaWYgbm8KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0IHZhbHVlIGlzIHNwZWNpZmllZC4KLSAgICAgKiBAcGFyYW0gbm9uTm9ybWFsaXplZERlZmF1bHRWYWx1ZSAgVGhlIGF0dHJpYnV0ZSBkZWZhdWx0IHZhbHVlIHdpdGggbm8gbm9ybWFsaXphdGlvbgotICAgICAqICAgICAgICAgICAgICAgICAgICAgIHBlcmZvcm1lZCwgb3IgbnVsbCBpZiBubyBkZWZhdWx0IHZhbHVlIGlzIHNwZWNpZmllZC4KLSAgICAgKiBAcGFyYW0gYXVncyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgYXR0cmlidXRlRGVjbCAoU3RyaW5nIGVsZW1lbnROYW1lLCBTdHJpbmcgYXR0cmlidXRlTmFtZSwKLSAgICBTdHJpbmcgdHlwZSwgU3RyaW5nW10gZW51bWVyYXRpb24sCi0gICAgU3RyaW5nIGRlZmF1bHRUeXBlLCBYTUxTdHJpbmcgZGVmYXVsdFZhbHVlLAotICAgIFhNTFN0cmluZyBub25Ob3JtYWxpemVkRGVmYXVsdFZhbHVlLCBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotCi0gICAgICAgIC8vIGludGVybmFsIHN1YnNldCBzdHJpbmcKLSAgICAgICAgaWYgKGZJbnRlcm5hbFN1YnNldCAhPSBudWxsICYmICFmSW5EVERFeHRlcm5hbFN1YnNldCkgewotICAgICAgICAgICAgZkludGVybmFsU3Vic2V0LmFwcGVuZCAoIjwhQVRUTElTVCAiKTsKLSAgICAgICAgICAgIGZJbnRlcm5hbFN1YnNldC5hcHBlbmQgKGVsZW1lbnROYW1lKTsKLSAgICAgICAgICAgIGZJbnRlcm5hbFN1YnNldC5hcHBlbmQgKCcgJyk7Ci0gICAgICAgICAgICBmSW50ZXJuYWxTdWJzZXQuYXBwZW5kIChhdHRyaWJ1dGVOYW1lKTsKLSAgICAgICAgICAgIGZJbnRlcm5hbFN1YnNldC5hcHBlbmQgKCcgJyk7Ci0gICAgICAgICAgICBpZiAodHlwZS5lcXVhbHMgKCJFTlVNRVJBVElPTiIpKSB7Ci0gICAgICAgICAgICAgICAgZkludGVybmFsU3Vic2V0LmFwcGVuZCAoJygnKTsKLSAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGVudW1lcmF0aW9uLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChpID4gMCkgewotICAgICAgICAgICAgICAgICAgICAgICAgZkludGVybmFsU3Vic2V0LmFwcGVuZCAoJ3wnKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBmSW50ZXJuYWxTdWJzZXQuYXBwZW5kIChlbnVtZXJhdGlvbltpXSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGZJbnRlcm5hbFN1YnNldC5hcHBlbmQgKCcpJyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBmSW50ZXJuYWxTdWJzZXQuYXBwZW5kICh0eXBlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChkZWZhdWx0VHlwZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZkludGVybmFsU3Vic2V0LmFwcGVuZCAoJyAnKTsKLSAgICAgICAgICAgICAgICBmSW50ZXJuYWxTdWJzZXQuYXBwZW5kIChkZWZhdWx0VHlwZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoZGVmYXVsdFZhbHVlICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmSW50ZXJuYWxTdWJzZXQuYXBwZW5kICgiICciKTsKLSAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGRlZmF1bHRWYWx1ZS5sZW5ndGg7IGkrKykgewotICAgICAgICAgICAgICAgICAgICBjaGFyIGMgPSBkZWZhdWx0VmFsdWUuY2hbZGVmYXVsdFZhbHVlLm9mZnNldCArIGldOwotICAgICAgICAgICAgICAgICAgICBpZiAoYyA9PSAnXCcnKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmSW50ZXJuYWxTdWJzZXQuYXBwZW5kICgiJmFwb3M7Iik7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmSW50ZXJuYWxTdWJzZXQuYXBwZW5kIChjKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBmSW50ZXJuYWxTdWJzZXQuYXBwZW5kICgnXCcnKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGZJbnRlcm5hbFN1YnNldC5hcHBlbmQgKCI+XG4iKTsKLSAgICAgICAgfQotICAgICAgICAvLyBSRVZJU0lUOiBUaGlzIGNvZGUgYXBwbGllcyB0byB0aGUgc3VwcG9ydCBvZiBkb214L2dyYW1tYXItYWNjZXNzCi0gICAgICAgIC8vIGZlYXR1cmUgaW4gWGVyY2VzIDEKLQotICAgICAgICAvLyBkZWZlcnJlZCBleHBhbnNpb24KLSAgICAgICAgaWYgKGZEZWZlcnJlZERvY3VtZW50SW1wbCAhPSBudWxsKSB7Ci0KLSAgICAgICAgICAgIC8vIGdldCB0aGUgZGVmYXVsdCB2YWx1ZQotICAgICAgICAgICAgaWYgKGRlZmF1bHRWYWx1ZSAhPSBudWxsKSB7Ci0KLSAgICAgICAgICAgICAgICAvLyBnZXQgZWxlbWVudCBkZWZpbml0aW9uCi0gICAgICAgICAgICAgICAgaW50IGVsZW1lbnREZWZJbmRleCAgPSBmRGVmZXJyZWREb2N1bWVudEltcGwubG9va3VwRWxlbWVudERlZmluaXRpb24gKGVsZW1lbnROYW1lKTsKLQotICAgICAgICAgICAgICAgIC8vIGNyZWF0ZSBlbGVtZW50IGRlZmluaXRpb24gaWYgbm90IGFscmVhZHkgdGhlcmUKLSAgICAgICAgICAgICAgICBpZiAoZWxlbWVudERlZkluZGV4ID09IC0xKSB7Ci0gICAgICAgICAgICAgICAgICAgIGVsZW1lbnREZWZJbmRleCA9IGZEZWZlcnJlZERvY3VtZW50SW1wbC5jcmVhdGVEZWZlcnJlZEVsZW1lbnREZWZpbml0aW9uIChlbGVtZW50TmFtZSk7Ci0gICAgICAgICAgICAgICAgICAgIGZEZWZlcnJlZERvY3VtZW50SW1wbC5hcHBlbmRDaGlsZCAoZkRvY3VtZW50VHlwZUluZGV4LCBlbGVtZW50RGVmSW5kZXgpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvLyBhZGQgZGVmYXVsdCBhdHRyaWJ1dGUKLSAgICAgICAgICAgICAgICBib29sZWFuIG5zRW5hYmxlZCA9IGZOYW1lc3BhY2VBd2FyZTsKLSAgICAgICAgICAgICAgICBTdHJpbmcgbmFtZXNwYWNlVVJJID0gbnVsbDsKLSAgICAgICAgICAgICAgICBpZiAobnNFbmFibGVkKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIERPTSBMZXZlbCAyIHdhbnRzIGFsbCBuYW1lc3BhY2UgZGVjbGFyYXRpb24gYXR0cmlidXRlcwotICAgICAgICAgICAgICAgICAgICAvLyB0byBiZSBib3VuZCB0byAiaHR0cDovL3d3dy53My5vcmcvMjAwMC94bWxucy8iCi0gICAgICAgICAgICAgICAgICAgIC8vIFNvIGFzIGxvbmcgYXMgdGhlIFhNTCBwYXJzZXIgZG9lc24ndCBkbyBpdCwgaXQgbmVlZHMgdG8KLSAgICAgICAgICAgICAgICAgICAgLy8gZG9uZSBoZXJlLgotICAgICAgICAgICAgICAgICAgICBpZiAoYXR0cmlidXRlTmFtZS5zdGFydHNXaXRoKCJ4bWxuczoiKSB8fAotICAgICAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlTmFtZS5lcXVhbHMoInhtbG5zIikpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZVVSSSA9IE5hbWVzcGFjZUNvbnRleHQuWE1MTlNfVVJJOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGF0dHJpYnV0ZU5hbWUuc3RhcnRzV2l0aCgieG1sOiIpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBuYW1lc3BhY2VVUkkgPSBOYW1lc3BhY2VDb250ZXh0LlhNTF9VUkk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaW50IGF0dHJJbmRleCA9IGZEZWZlcnJlZERvY3VtZW50SW1wbC5jcmVhdGVEZWZlcnJlZEF0dHJpYnV0ZSAoCi0gICAgICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVOYW1lLCBuYW1lc3BhY2VVUkksIGRlZmF1bHRWYWx1ZS50b1N0cmluZygpLCBmYWxzZSk7Ci0gICAgICAgICAgICAgICAgaWYgKCJJRCIuZXF1YWxzICh0eXBlKSkgewotICAgICAgICAgICAgICAgICAgICBmRGVmZXJyZWREb2N1bWVudEltcGwuc2V0SWRBdHRyaWJ1dGUgKGF0dHJJbmRleCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIC8vIFJFVklTSVQ6IHNldCBJRCB0eXBlIGNvcnJlY3RseQotICAgICAgICAgICAgICAgIGZEZWZlcnJlZERvY3VtZW50SW1wbC5hcHBlbmRDaGlsZCAoZWxlbWVudERlZkluZGV4LCBhdHRySW5kZXgpOwotICAgICAgICAgICAgfQotCi0gICAgICAgIH0gLy8gaWYgZGVmZXJyZWQKLQotICAgICAgICAvLyBmdWxsIGV4cGFuc2lvbgotICAgICAgICBlbHNlIGlmIChmRG9jdW1lbnRJbXBsICE9IG51bGwpIHsKLQotICAgICAgICAgICAgLy8gZ2V0IHRoZSBkZWZhdWx0IHZhbHVlCi0gICAgICAgICAgICBpZiAoZGVmYXVsdFZhbHVlICE9IG51bGwpIHsKLQotICAgICAgICAgICAgICAgIC8vIGdldCBlbGVtZW50IGRlZmluaXRpb24gbm9kZQotICAgICAgICAgICAgICAgIE5hbWVkTm9kZU1hcCBlbGVtZW50cyA9ICgoRG9jdW1lbnRUeXBlSW1wbClmRG9jdW1lbnRUeXBlKS5nZXRFbGVtZW50cyAoKTsKLSAgICAgICAgICAgICAgICBFbGVtZW50RGVmaW5pdGlvbkltcGwgZWxlbWVudERlZiA9IChFbGVtZW50RGVmaW5pdGlvbkltcGwpZWxlbWVudHMuZ2V0TmFtZWRJdGVtIChlbGVtZW50TmFtZSk7Ci0gICAgICAgICAgICAgICAgaWYgKGVsZW1lbnREZWYgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBlbGVtZW50RGVmID0gZkRvY3VtZW50SW1wbC5jcmVhdGVFbGVtZW50RGVmaW5pdGlvbiAoZWxlbWVudE5hbWUpOwotICAgICAgICAgICAgICAgICAgICAoKERvY3VtZW50VHlwZUltcGwpZkRvY3VtZW50VHlwZSkuZ2V0RWxlbWVudHMgKCkuc2V0TmFtZWRJdGVtIChlbGVtZW50RGVmKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyBSRVZJU0lUOiBDaGVjayBmb3IgdW5pcXVlbmVzcyBvZiBlbGVtZW50IG5hbWU/IC1BYwotCi0gICAgICAgICAgICAgICAgLy8gY3JlYXRlIGF0dHJpYnV0ZSBhbmQgc2V0IHByb3BlcnRpZXMKLSAgICAgICAgICAgICAgICBib29sZWFuIG5zRW5hYmxlZCA9IGZOYW1lc3BhY2VBd2FyZTsKLSAgICAgICAgICAgICAgICBBdHRySW1wbCBhdHRyOwotICAgICAgICAgICAgICAgIGlmIChuc0VuYWJsZWQpIHsKLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSA9IG51bGw7Ci0gICAgICAgICAgICAgICAgICAgIC8vIERPTSBMZXZlbCAyIHdhbnRzIGFsbCBuYW1lc3BhY2UgZGVjbGFyYXRpb24gYXR0cmlidXRlcwotICAgICAgICAgICAgICAgICAgICAvLyB0byBiZSBib3VuZCB0byAiaHR0cDovL3d3dy53My5vcmcvMjAwMC94bWxucy8iCi0gICAgICAgICAgICAgICAgICAgIC8vIFNvIGFzIGxvbmcgYXMgdGhlIFhNTCBwYXJzZXIgZG9lc24ndCBkbyBpdCwgaXQgbmVlZHMgdG8KLSAgICAgICAgICAgICAgICAgICAgLy8gZG9uZSBoZXJlLgotICAgICAgICAgICAgICAgICAgICBpZiAoYXR0cmlidXRlTmFtZS5zdGFydHNXaXRoKCJ4bWxuczoiKSB8fAotICAgICAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlTmFtZS5lcXVhbHMoInhtbG5zIikpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZVVSSSA9IE5hbWVzcGFjZUNvbnRleHQuWE1MTlNfVVJJOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGF0dHJpYnV0ZU5hbWUuc3RhcnRzV2l0aCgieG1sOiIpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBuYW1lc3BhY2VVUkkgPSBOYW1lc3BhY2VDb250ZXh0LlhNTF9VUkk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgYXR0ciA9IChBdHRySW1wbClmRG9jdW1lbnRJbXBsLmNyZWF0ZUF0dHJpYnV0ZU5TIChuYW1lc3BhY2VVUkksCi0gICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZU5hbWUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgYXR0ciA9IChBdHRySW1wbClmRG9jdW1lbnRJbXBsLmNyZWF0ZUF0dHJpYnV0ZSAoYXR0cmlidXRlTmFtZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGF0dHIuc2V0VmFsdWUgKGRlZmF1bHRWYWx1ZS50b1N0cmluZyAoKSk7Ci0gICAgICAgICAgICAgICAgYXR0ci5zZXRTcGVjaWZpZWQgKGZhbHNlKTsKLSAgICAgICAgICAgICAgICBhdHRyLnNldElkQXR0cmlidXRlICgiSUQiLmVxdWFscyAodHlwZSkpOwotCi0gICAgICAgICAgICAgICAgLy8gYWRkIGRlZmF1bHQgYXR0cmlidXRlIHRvIGVsZW1lbnQgZGVmaW5pdGlvbgotICAgICAgICAgICAgICAgIGlmIChuc0VuYWJsZWQpewotICAgICAgICAgICAgICAgICAgICBlbGVtZW50RGVmLmdldEF0dHJpYnV0ZXMgKCkuc2V0TmFtZWRJdGVtTlMgKGF0dHIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgZWxlbWVudERlZi5nZXRBdHRyaWJ1dGVzICgpLnNldE5hbWVkSXRlbSAoYXR0cik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgIH0gLy8gaWYgTk9UIGRlZmVyLW5vZGUtZXhwYW5zaW9uCi0KLSAgICB9IC8vIGF0dHJpYnV0ZURlY2woU3RyaW5nLFN0cmluZyxTdHJpbmcsU3RyaW5nW10sU3RyaW5nLFhNTFN0cmluZywgWE1MU3RyaW5nLCBBdWdtZW50YXRpb25zKQotCi0KLSAgICAvKioKLSAgICAgKiBUaGUgc3RhcnQgb2YgYW4gYXR0cmlidXRlIGxpc3QuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZWxlbWVudE5hbWUgVGhlIG5hbWUgb2YgdGhlIGVsZW1lbnQgdGhhdCB0aGlzIGF0dHJpYnV0ZQotICAgICAqICAgICAgICAgICAgICAgICAgICBsaXN0IGlzIGFzc29jaWF0ZWQgd2l0aC4KLSAgICAgKiBAcGFyYW0gYXVncyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnRBdHRsaXN0IChTdHJpbmcgZWxlbWVudE5hbWUsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgfSAvLyBzdGFydEF0dGxpc3QoU3RyaW5nKQotCi0KLSAgICAvKioKLSAgICAgKiBUaGUgZW5kIG9mIGFuIGF0dHJpYnV0ZSBsaXN0LgotICAgICAqCi0gICAgICogQHBhcmFtIGF1Z3MgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZEF0dGxpc3QgKEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgfSAvLyBlbmRBdHRsaXN0KCkKLQotCi0gICAgLy8gbWV0aG9kIHRvIGNyZWF0ZSBhbiBlbGVtZW50IG5vZGUuCi0gICAgLy8gc3ViY2xhc3NlcyBjYW4gb3ZlcnJpZGUgdGhpcyBtZXRob2QgdG8gY3JlYXRlIGVsZW1lbnQgbm9kZXMgaW4gb3RoZXIgd2F5cy4KLSAgICBwcm90ZWN0ZWQgRWxlbWVudCBjcmVhdGVFbGVtZW50Tm9kZSAoUU5hbWUgZWxlbWVudCkgewotICAgICAgICBFbGVtZW50IGVsID0gbnVsbDsKLQotICAgICAgICBpZiAoZk5hbWVzcGFjZUF3YXJlKSB7Ci0gICAgICAgICAgICAvLyBpZiB3ZSBhcmUgdXNpbmcgeGVyY2VzIERPTSBpbXBsZW1lbnRhdGlvbiwgY2FsbCBvdXIKLSAgICAgICAgICAgIC8vIG93biBjb25zdHJ1Y3RvciB0byByZXVzZSB0aGUgc3RyaW5ncyB3ZSBoYXZlIGhlcmUuCi0gICAgICAgICAgICBpZiAoZkRvY3VtZW50SW1wbCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZWwgPSBmRG9jdW1lbnRJbXBsLmNyZWF0ZUVsZW1lbnROUyAoZWxlbWVudC51cmksIGVsZW1lbnQucmF3bmFtZSwKLSAgICAgICAgICAgICAgICBlbGVtZW50LmxvY2FscGFydCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBlbCA9IGZEb2N1bWVudC5jcmVhdGVFbGVtZW50TlMgKGVsZW1lbnQudXJpLCBlbGVtZW50LnJhd25hbWUpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgZWwgPSBmRG9jdW1lbnQuY3JlYXRlRWxlbWVudCAoZWxlbWVudC5yYXduYW1lKTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBlbDsKLSAgICB9Ci0KLSAgICAvLyBtZXRob2QgdG8gY3JlYXRlIGFuIGF0dHJpYnV0ZSBub2RlLgotICAgIC8vIHN1YmNsYXNzZXMgY2FuIG92ZXJyaWRlIHRoaXMgbWV0aG9kIHRvIGNyZWF0ZSBhdHRyaWJ1dGUgbm9kZXMgaW4gb3RoZXIgd2F5cy4KLSAgICBwcm90ZWN0ZWQgQXR0ciBjcmVhdGVBdHRyTm9kZSAoUU5hbWUgYXR0clFOYW1lKSB7Ci0gICAgICAgIEF0dHIgYXR0ciA9IG51bGw7Ci0KLSAgICAgICAgaWYgKGZOYW1lc3BhY2VBd2FyZSkgewotICAgICAgICAgICAgaWYgKGZEb2N1bWVudEltcGwgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIC8vIGlmIHdlIGFyZSB1c2luZyB4ZXJjZXMgRE9NIGltcGxlbWVudGF0aW9uLCBjYWxsIG91cgotICAgICAgICAgICAgICAgIC8vIG93biBjb25zdHJ1Y3RvciB0byByZXVzZSB0aGUgc3RyaW5ncyB3ZSBoYXZlIGhlcmUuCi0gICAgICAgICAgICAgICAgYXR0ciA9IGZEb2N1bWVudEltcGwuY3JlYXRlQXR0cmlidXRlTlMgKGF0dHJRTmFtZS51cmksCi0gICAgICAgICAgICAgICAgYXR0clFOYW1lLnJhd25hbWUsCi0gICAgICAgICAgICAgICAgYXR0clFOYW1lLmxvY2FscGFydCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBhdHRyID0gZkRvY3VtZW50LmNyZWF0ZUF0dHJpYnV0ZU5TIChhdHRyUU5hbWUudXJpLAotICAgICAgICAgICAgICAgIGF0dHJRTmFtZS5yYXduYW1lKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIGF0dHIgPSBmRG9jdW1lbnQuY3JlYXRlQXR0cmlidXRlIChhdHRyUU5hbWUucmF3bmFtZSk7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gYXR0cjsKLSAgICB9Ci0KLSAgICAvKgotICAgICAqIFdoZW4gdGhlIGZpcnN0IGNoYXJhY3RlcnMoKSBjYWxsIGlzIHJlY2VpdmVkLCB0aGUgZGF0YSBpcyBzdG9yZWQgaW4KLSAgICAgKiBhIG5ldyBUZXh0IG5vZGUuIElmIHJpZ2h0IGFmdGVyIHRoZSBmaXJzdCBjaGFyYWN0ZXJzKCkgd2UgcmVjZWl2ZSBhbm90aGVyIGNodW5rIG9mIGRhdGEsCi0gICAgICogdGhlIGRhdGEgZnJvbSB0aGUgVGV4dCBub2RlLCBmb2xsb3dpbmcgdGhlIG5ldyBjaGFyYWN0ZXJzIGFyZSBhcHBlbmRlZAotICAgICAqIHRvIHRoZSBmU3RyaW5nQnVmZmVyIGFuZCB0aGUgdGV4dCBub2RlIGRhdGEgaXMgc2V0IHRvIGVtcHR5LgotICAgICAqCi0gICAgICogVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgd2hlbiB0aGUgc3RhdGUgaXMgY2hhbmdlZCBhbmQgdGhlCi0gICAgICogZGF0YSBtdXN0IGJlIGFwcGVuZGVkIHRvIHRoZSBjdXJyZW50IG5vZGUuCi0gICAgICoKLSAgICAgKiBOb3RlOiBpZiBET01GaWx0ZXIgaXMgc2V0LCB5b3UgbXVzdCBtYWtlIHN1cmUgdGhhdCBpZiBOb2RlIGlzIHNraXBwZWQsCi0gICAgICogb3IgcmVtb3ZlZCBmRmlzdENodW5rIG11c3QgYmUgc2V0IHRvIHRydWUsIG90aGVyd2lzZSBzb21lIGRhdGEgY2FuIGJlIGxvc3QuCi0gICAgICoKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCAgc2V0Q2hhcmFjdGVyRGF0YSAoYm9vbGVhbiBzYXdDaGFycyl7Ci0KLSAgICAgICAgLy8gaGFuZGxlIGNoYXJhY3RlciBkYXRhCi0gICAgICAgIGZGaXJzdENodW5rID0gc2F3Q2hhcnM7Ci0KLQotICAgICAgICAvLyBpZiB3ZSBoYXZlIGRhdGEgaW4gdGhlIGJ1ZmZlciB3ZSBtdXN0IGhhdmUgY3JlYXRlZAotICAgICAgICAvLyBhIHRleHQgbm9kZSBhbHJlYWR5LgotCi0gICAgICAgIE5vZGUgY2hpbGQgPSBmQ3VycmVudE5vZGUuZ2V0TGFzdENoaWxkICgpOwotICAgICAgICBpZiAoY2hpbGQgIT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKGZTdHJpbmdCdWlsZGVyLmxlbmd0aCAoKSA+IDApIHsKLSAgICAgICAgICAgICAgICAvLyBSRVZJU0lUOiBzaG91bGQgdGhpcyBjaGVjayBiZSBwZXJmb3JtZWQ/Ci0gICAgICAgICAgICAgICAgaWYgKGNoaWxkLmdldE5vZGVUeXBlICgpID09IE5vZGUuVEVYVF9OT0RFKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChmRG9jdW1lbnRJbXBsICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICgoVGV4dEltcGwpY2hpbGQpLnJlcGxhY2VEYXRhIChmU3RyaW5nQnVpbGRlci50b1N0cmluZyAoKSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAoKFRleHQpY2hpbGQpLnNldERhdGEgKGZTdHJpbmdCdWlsZGVyLnRvU3RyaW5nICgpKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvLyByZXNldCBzdHJpbmcgYnVmZmVyCi0gICAgICAgICAgICAgICAgZlN0cmluZ0J1aWxkZXIuc2V0TGVuZ3RoICgwKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKGZET01GaWx0ZXIgIT1udWxsICYmICFmSW5FbnRpdHlSZWYpIHsKLSAgICAgICAgICAgICAgICBpZiAoIChjaGlsZC5nZXROb2RlVHlwZSAoKSA9PSBOb2RlLlRFWFRfTk9ERSApICYmCi0gICAgICAgICAgICAgICAgKChmRE9NRmlsdGVyLmdldFdoYXRUb1Nob3cgKCkgJiBOb2RlRmlsdGVyLlNIT1dfVEVYVCkhPSAwKSApIHsKLSAgICAgICAgICAgICAgICAgICAgc2hvcnQgY29kZSA9IGZET01GaWx0ZXIuYWNjZXB0Tm9kZSAoY2hpbGQpOwotICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGNvZGUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgTFNQYXJzZXJGaWx0ZXIuRklMVEVSX0lOVEVSUlVQVDp7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgQWJvcnQuSU5TVEFOQ0U7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIExTUGFyc2VyRmlsdGVyLkZJTFRFUl9SRUpFQ1Q6ewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZhbGwgdGhyb3VnaCB0byBTS0lQIHNpbmNlIENvbW1lbnQgaGFzIG5vIGNoaWxkcmVuLgotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBMU1BhcnNlckZpbHRlci5GSUxURVJfU0tJUDogewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZDdXJyZW50Tm9kZS5yZW1vdmVDaGlsZCAoY2hpbGQpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBhY2NlcHQgbm9kZSAtLSBkbyBub3RoaW5nCi0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9ICAgLy8gZW5kLWlmIGZET01GaWx0ZXIgIT1udWxsCi0KLSAgICAgICAgfSAvLyBlbmQtaWYgY2hpbGQgIT1udWxsCi0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBAc2VlIG9yZy53M2MuZG9tLmxzLkxTUGFyc2VyI2Fib3J0KCkKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBhYm9ydCAoKSB7Ci0gICAgICAgIHRocm93IEFib3J0LklOU1RBTkNFOwotICAgIH0KLQotCi19IC8vIGNsYXNzIEFic3RyYWN0RE9NUGFyc2VyCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9wYXJzZXJzL0Fic3RyYWN0U0FYUGFyc2VyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9wYXJzZXJzL0Fic3RyYWN0U0FYUGFyc2VyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGVlYTcwNTcuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvcGFyc2Vycy9BYnN0cmFjdFNBWFBhcnNlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjQxNyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwucGFyc2VyczsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5Db25zdGFudHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLkVudGl0eVJlc29sdmVyMldyYXBwZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLkVudGl0eVJlc29sdmVyV3JhcHBlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuRXJyb3JIYW5kbGVyV3JhcHBlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuU0FYTWVzc2FnZUZvcm1hdHRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuU3RhdHVzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5TeW1ib2xIYXNoOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5YTUxTeW1ib2xzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbHMuWE1MU2VjdXJpdHlNYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLkF1Z21lbnRhdGlvbnM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuTmFtZXNwYWNlQ29udGV4dDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5RTmFtZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxBdHRyaWJ1dGVzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTExvY2F0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MUmVzb3VyY2VJZGVudGlmaWVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTFN0cmluZzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTklFeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTEVudGl0eVJlc29sdmVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxFcnJvckhhbmRsZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTElucHV0U291cmNlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxQYXJzZUV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MUGFyc2VyQ29uZmlndXJhdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLkF0dHJpYnV0ZVBTVkk7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5FbGVtZW50UFNWSTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlBTVklQcm92aWRlcjsKLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7Ci1pbXBvcnQgamF2YXgueG1sLlhNTENvbnN0YW50czsKLWltcG9ydCBvcmcueG1sLnNheC5BdHRyaWJ1dGVMaXN0OwotaW1wb3J0IG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LkRUREhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguRG9jdW1lbnRIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LkVudGl0eVJlc29sdmVyOwotaW1wb3J0IG9yZy54bWwuc2F4LkVycm9ySGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKLWltcG9ydCBvcmcueG1sLnNheC5QYXJzZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWFBhcnNlRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LlhNTFJlYWRlcjsKLWltcG9ydCBvcmcueG1sLnNheC5leHQuQXR0cmlidXRlczI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguZXh0LkRlY2xIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LmV4dC5FbnRpdHlSZXNvbHZlcjI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguZXh0LkxleGljYWxIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LmV4dC5Mb2NhdG9yMjsKLWltcG9ydCBvcmcueG1sLnNheC5oZWxwZXJzLkxvY2F0b3JJbXBsOwotCi0vKioKLSAqIFRoaXMgaXMgdGhlIGJhc2UgY2xhc3Mgb2YgYWxsIFNBWCBwYXJzZXJzLiBJdCBpbXBsZW1lbnRzIGJvdGggdGhlCi0gKiBTQVgxIGFuZCBTQVgyIHBhcnNlciBmdW5jdGlvbmFsaXR5LCB3aGlsZSB0aGUgYWN0dWFsIHBpcGVsaW5lIGlzCi0gKiBkZWZpbmVkIGluIHRoZSBwYXJzZXIgY29uZmlndXJhdGlvbi4KLSAqCi0gKiBAYXV0aG9yIEFybmF1ZCBMZSBIb3JzLCBJQk0KLSAqIEBhdXRob3IgQW5keSBDbGFyaywgSUJNCi0gKgotICogQHZlcnNpb24gJElkOiBBYnN0cmFjdFNBWFBhcnNlci5qYXZhLHYgMS42IDIwMTAtMTEtMDEgMDQ6NDA6MDkgam9laHcgRXhwICQKLSAqLwotcHVibGljIGFic3RyYWN0IGNsYXNzIEFic3RyYWN0U0FYUGFyc2VyCi0gICAgZXh0ZW5kcyBBYnN0cmFjdFhNTERvY3VtZW50UGFyc2VyCi0gICAgaW1wbGVtZW50cyBQU1ZJUHJvdmlkZXIsIC8vIFBTVkkKLSAgICAgICAgICAgICAgUGFyc2VyLCBYTUxSZWFkZXIgLy8gU0FYMSwgU0FYMgotewotCi0gICAgLy8KLSAgICAvLyBDb25zdGFudHMKLSAgICAvLwotCi0gICAgLy8gZmVhdHVyZXMKLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IG5hbWVzcGFjZXMuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgTkFNRVNQQUNFUyA9Ci0gICAgICAgIENvbnN0YW50cy5TQVhfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuTkFNRVNQQUNFU19GRUFUVVJFOwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogbmFtZXNwYWNlIHByZWZpeGVzLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIE5BTUVTUEFDRV9QUkVGSVhFUyA9Ci0gICAgICAgIENvbnN0YW50cy5TQVhfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuTkFNRVNQQUNFX1BSRUZJWEVTX0ZFQVRVUkU7Ci0KLSAgICAvKiogRmVhdHVyZSBpZDogc3RyaW5nIGludGVybmluZy4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBTVFJJTkdfSU5URVJOSU5HID0KLSAgICAgICAgQ29uc3RhbnRzLlNBWF9GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5TVFJJTkdfSU5URVJOSU5HX0ZFQVRVUkU7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiBhbGxvdyBub3RhdGlvbiBhbmQgdW5wYXJzZWQgZW50aXR5IGV2ZW50cyB0byBiZSBzZW50IG91dCBvZiBvcmRlci4gKi8KLSAgICAvLyB0aGlzIGlzIG5vdCBtZWFudCB0byBiZSBhIHJlY29nbml6ZWQgZmVhdHVyZSwgYnV0IHdlIG5lZWQgaXQgaGVyZSB0byB1c2UKLSAgICAvLyBpZiBpdCBpcyBhbHJlYWR5IGEgcmVjb2duaXplZCBmZWF0dXJlIGZvciB0aGUgcGlwZWxpbmUKLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBBTExPV19VRV9BTkRfTk9UQVRJT05fRVZFTlRTID0KLSAgICAgICAgQ29uc3RhbnRzLlNBWF9GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5BTExPV19EVERfRVZFTlRTX0FGVEVSX0VORERURF9GRUFUVVJFOwotCi0gICAgLyoqIFJlY29nbml6ZWQgZmVhdHVyZXMuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nW10gUkVDT0dOSVpFRF9GRUFUVVJFUyA9IHsKLSAgICAgICAgTkFNRVNQQUNFUywKLSAgICAgICAgTkFNRVNQQUNFX1BSRUZJWEVTLAotICAgICAgICBTVFJJTkdfSU5URVJOSU5HLAotICAgIH07Ci0KLSAgICAvLyBwcm9wZXJ0aWVzCi0KLSAgICAvKiogUHJvcGVydHkgaWQ6IGxleGljYWwgaGFuZGxlci4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBMRVhJQ0FMX0hBTkRMRVIgPQotICAgICAgICBDb25zdGFudHMuU0FYX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5MRVhJQ0FMX0hBTkRMRVJfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWQ6IGRlY2xhcmF0aW9uIGhhbmRsZXIuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgREVDTEFSQVRJT05fSEFORExFUiA9Ci0gICAgICAgIENvbnN0YW50cy5TQVhfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLkRFQ0xBUkFUSU9OX0hBTkRMRVJfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWQ6IERPTSBub2RlLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIERPTV9OT0RFID0KLSAgICAgICAgQ29uc3RhbnRzLlNBWF9QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuRE9NX05PREVfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWQ6IHNlY3VyaXR5IG1hbmFnZXIuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFNFQ1VSSVRZX01BTkFHRVIgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5TRUNVUklUWV9NQU5BR0VSX1BST1BFUlRZOwotCi0gICAgLyoqIFJlY29nbml6ZWQgcHJvcGVydGllcy4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSBSRUNPR05JWkVEX1BST1BFUlRJRVMgPSB7Ci0gICAgICAgIExFWElDQUxfSEFORExFUiwKLSAgICAgICAgREVDTEFSQVRJT05fSEFORExFUiwKLSAgICAgICAgRE9NX05PREUsCi0gICAgfTsKLQotICAgIC8vCi0gICAgLy8gRGF0YQotICAgIC8vCi0KLSAgICAvLyBmZWF0dXJlcwotCi0gICAgLyoqIE5hbWVzcGFjZXMuICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZk5hbWVzcGFjZXM7Ci0KLSAgICAvKiogTmFtZXNwYWNlIHByZWZpeGVzLiAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIGZOYW1lc3BhY2VQcmVmaXhlcyA9IGZhbHNlOwotCi0gICAgLyoqIExleGljYWwgaGFuZGxlciBwYXJhbWV0ZXIgZW50aXRpZXMuICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZkxleGljYWxIYW5kbGVyUGFyYW1ldGVyRW50aXRpZXMgPSB0cnVlOwotCi0gICAgLyoqIFN0YW5kYWxvbmUgZG9jdW1lbnQgZGVjbGFyYXRpb24uICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZlN0YW5kYWxvbmU7Ci0KLSAgICAvKiogUmVzb2x2ZSBEVEQgVVJJcy4gKi8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBmUmVzb2x2ZURURFVSSXMgPSB0cnVlOwotCi0gICAgLyoqIFVzZSBFbnRpdHlSZXNvbHZlcjIuICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZlVzZUVudGl0eVJlc29sdmVyMiA9IHRydWU7Ci0KLSAgICAvKioKLSAgICAgKiBYTUxOUyBVUklzOiBOYW1lc3BhY2UgZGVjbGFyYXRpb25zIGluIHRoZQotICAgICAqIGh0dHA6Ly93d3cudzMub3JnLzIwMDAveG1sbnMvIG5hbWVzcGFjZS4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBmWE1MTlNVUklzID0gZmFsc2U7Ci0KLSAgICAvLyBwYXJzZXIgaGFuZGxlcnMKLQotICAgIC8qKiBDb250ZW50IGhhbmRsZXIuICovCi0gICAgcHJvdGVjdGVkIENvbnRlbnRIYW5kbGVyIGZDb250ZW50SGFuZGxlcjsKLQotICAgIC8qKiBEb2N1bWVudCBoYW5kbGVyLiAqLwotICAgIHByb3RlY3RlZCBEb2N1bWVudEhhbmRsZXIgZkRvY3VtZW50SGFuZGxlcjsKLQotICAgIC8qKiBOYW1lc3BhY2UgY29udGV4dCAqLwotICAgIHByb3RlY3RlZCBOYW1lc3BhY2VDb250ZXh0IGZOYW1lc3BhY2VDb250ZXh0OwotCi0gICAgLyoqIERURCBoYW5kbGVyLiAqLwotICAgIHByb3RlY3RlZCBvcmcueG1sLnNheC5EVERIYW5kbGVyIGZEVERIYW5kbGVyOwotCi0gICAgLyoqIERlY2wgaGFuZGxlci4gKi8KLSAgICBwcm90ZWN0ZWQgRGVjbEhhbmRsZXIgZkRlY2xIYW5kbGVyOwotCi0gICAgLyoqIExleGljYWwgaGFuZGxlci4gKi8KLSAgICBwcm90ZWN0ZWQgTGV4aWNhbEhhbmRsZXIgZkxleGljYWxIYW5kbGVyOwotCi0gICAgcHJvdGVjdGVkIFFOYW1lIGZRTmFtZSA9IG5ldyBRTmFtZSgpOwotCi0gICAgLy8gc3RhdGUKLQotICAgIC8qKgotICAgICAqIFRydWUgaWYgYSBwYXJzZSBpcyBpbiBwcm9ncmVzcy4gVGhpcyBzdGF0ZSBpcyBuZWVkZWQgYmVjYXVzZQotICAgICAqIHNvbWUgZmVhdHVyZXMvcHJvcGVydGllcyBjYW5ub3QgYmUgc2V0IHdoaWxlIHBhcnNpbmcgKGUuZy4KLSAgICAgKiB2YWxpZGF0aW9uIGFuZCBuYW1lc3BhY2VzKS4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBmUGFyc2VJblByb2dyZXNzID0gZmFsc2U7Ci0KLSAgICAvLyB0cmFjayB0aGUgdmVyc2lvbiBvZiB0aGUgZG9jdW1lbnQgYmVpbmcgcGFyc2VkCi0gICAgcHJvdGVjdGVkIFN0cmluZyBmVmVyc2lvbjsKLQotICAgIC8vIHRlbXAgdmFycwotICAgIHByaXZhdGUgZmluYWwgQXR0cmlidXRlc1Byb3h5IGZBdHRyaWJ1dGVzUHJveHkgPSBuZXcgQXR0cmlidXRlc1Byb3h5KCk7Ci0gICAgcHJpdmF0ZSBBdWdtZW50YXRpb25zIGZBdWdtZW50YXRpb25zID0gbnVsbDsKLQotCi0gICAgLy8gdGVtcG9yYXJ5IGJ1ZmZlciBmb3Igc2VuZGluZyBub3JtYWxpemVkIHZhbHVlcwotICAgIC8vIFJFVklTSVQ6IHdoYXQgc2hvdWxkIGJlIHRoZSBzaXplIG9mIHRoZSBidWZmZXI/Ci0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEJVRkZFUl9TSVpFID0gMjA7Ci0gICAgcHJpdmF0ZSBjaGFyW10gZkNoYXJCdWZmZXIgPSAgbmV3IGNoYXJbQlVGRkVSX1NJWkVdOwotCi0gICAgLy8gYWxsb3dzIHVzIHRvIGtlZXAgdHJhY2sgb2Ygd2hldGhlciBhbiBhdHRyaWJ1dGUgaGFzCi0gICAgLy8gYmVlbiBkZWNsYXJlZCB0d2ljZSwgc28gdGhhdCB3ZSBjYW4gYXZvaWQgZXhwb3NpbmcgdGhlCi0gICAgLy8gc2Vjb25kIGRlY2xhcmF0aW9uIHRvIGFueSByZWdpc3RlcmVkIERlY2xIYW5kbGVyCi0gICAgcHJvdGVjdGVkIFN5bWJvbEhhc2ggZkRlY2xhcmVkQXR0cnMgPSBudWxsOwotCi0gICAgLy8KLSAgICAvLyBDb25zdHJ1Y3RvcnMKLSAgICAvLwotCi0gICAgLyoqIERlZmF1bHQgY29uc3RydWN0b3IuICovCi0gICAgcHJvdGVjdGVkIEFic3RyYWN0U0FYUGFyc2VyKFhNTFBhcnNlckNvbmZpZ3VyYXRpb24gY29uZmlnKSB7Ci0gICAgICAgIHN1cGVyKGNvbmZpZyk7Ci0KLSAgICAgICAgY29uZmlnLmFkZFJlY29nbml6ZWRGZWF0dXJlcyhSRUNPR05JWkVEX0ZFQVRVUkVTKTsKLSAgICAgICAgY29uZmlnLmFkZFJlY29nbml6ZWRQcm9wZXJ0aWVzKFJFQ09HTklaRURfUFJPUEVSVElFUyk7Ci0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGNvbmZpZy5zZXRGZWF0dXJlKEFMTE9XX1VFX0FORF9OT1RBVElPTl9FVkVOVFMsIGZhbHNlKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAvLyBpdCB3YXNuJ3QgYSByZWNvZ25pemVkIGZlYXR1cmUsIHNvIHdlIGRvbid0IHdvcnJ5IGFib3V0IGl0Ci0gICAgICAgIH0KLSAgICB9IC8vIDxpbml0PihYTUxQYXJzZXJDb25maWd1cmF0aW9uKQotCi0gICAgLy8KLSAgICAvLyBYTUxEb2N1bWVudEhhbmRsZXIgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBUaGUgc3RhcnQgb2YgdGhlIGRvY3VtZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIGxvY2F0b3IgVGhlIGRvY3VtZW50IGxvY2F0b3IsIG9yIG51bGwgaWYgdGhlIGRvY3VtZW50Ci0gICAgICogICAgICAgICAgICAgICAgIGxvY2F0aW9uIGNhbm5vdCBiZSByZXBvcnRlZCBkdXJpbmcgdGhlIHBhcnNpbmcKLSAgICAgKiAgICAgICAgICAgICAgICAgb2YgdGhpcyBkb2N1bWVudC4gSG93ZXZlciwgaXQgaXMgPGVtPnN0cm9uZ2x5PC9lbT4KLSAgICAgKiAgICAgICAgICAgICAgICAgcmVjb21tZW5kZWQgdGhhdCBhIGxvY2F0b3IgYmUgc3VwcGxpZWQgdGhhdCBjYW4KLSAgICAgKiAgICAgICAgICAgICAgICAgYXQgbGVhc3QgcmVwb3J0IHRoZSBzeXN0ZW0gaWRlbnRpZmllciBvZiB0aGUKLSAgICAgKiAgICAgICAgICAgICAgICAgZG9jdW1lbnQuCi0gICAgICogQHBhcmFtIGVuY29kaW5nIFRoZSBhdXRvLWRldGVjdGVkIElBTkEgZW5jb2RpbmcgbmFtZSBvZiB0aGUgZW50aXR5Ci0gICAgICogICAgICAgICAgICAgICAgIHN0cmVhbS4gVGhpcyB2YWx1ZSB3aWxsIGJlIG51bGwgaW4gdGhvc2Ugc2l0dWF0aW9ucwotICAgICAqICAgICAgICAgICAgICAgICB3aGVyZSB0aGUgZW50aXR5IGVuY29kaW5nIGlzIG5vdCBhdXRvLWRldGVjdGVkIChlLmcuCi0gICAgICogICAgICAgICAgICAgICAgIGludGVybmFsIGVudGl0aWVzIG9yIGEgZG9jdW1lbnQgZW50aXR5IHRoYXQgaXMKLSAgICAgKiAgICAgICAgICAgICAgICAgcGFyc2VkIGZyb20gYSBqYXZhLmlvLlJlYWRlcikuCi0gICAgICogQHBhcmFtIG5hbWVzcGFjZUNvbnRleHQKLSAgICAgKiAgICAgICAgICAgICAgICAgVGhlIG5hbWVzcGFjZSBjb250ZXh0IGluIGVmZmVjdCBhdCB0aGUKLSAgICAgKiAgICAgICAgICAgICAgICAgc3RhcnQgb2YgdGhpcyBkb2N1bWVudC4KLSAgICAgKiAgICAgICAgICAgICAgICAgVGhpcyBvYmplY3QgcmVwcmVzZW50cyB0aGUgY3VycmVudCBjb250ZXh0LgotICAgICAqICAgICAgICAgICAgICAgICBJbXBsZW1lbnRvcnMgb2YgdGhpcyBjbGFzcyBhcmUgcmVzcG9uc2libGUKLSAgICAgKiAgICAgICAgICAgICAgICAgZm9yIGNvcHlpbmcgdGhlIG5hbWVzcGFjZSBiaW5kaW5ncyBmcm9tIHRoZQotICAgICAqICAgICAgICAgICAgICAgICB0aGUgY3VycmVudCBjb250ZXh0IChhbmQgaXRzIHBhcmVudCBjb250ZXh0cykKLSAgICAgKiAgICAgICAgICAgICAgICAgaWYgdGhhdCBpbmZvcm1hdGlvbiBpcyBpbXBvcnRhbnQuCi0gICAgICogQHBhcmFtIGF1Z3MgICAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydERvY3VtZW50KFhNTExvY2F0b3IgbG9jYXRvciwgU3RyaW5nIGVuY29kaW5nLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmFtZXNwYWNlQ29udGV4dCBuYW1lc3BhY2VDb250ZXh0LCBBdWdtZW50YXRpb25zIGF1Z3MpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotCi0gICAgICAgIGZOYW1lc3BhY2VDb250ZXh0ID0gbmFtZXNwYWNlQ29udGV4dDsKLQotICAgICAgICB0cnkgewotICAgICAgICAgICAgLy8gU0FYMQotICAgICAgICAgICAgaWYgKGZEb2N1bWVudEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGlmIChsb2NhdG9yICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci5zZXREb2N1bWVudExvY2F0b3IobmV3IExvY2F0b3JQcm94eShsb2NhdG9yKSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGZEb2N1bWVudEhhbmRsZXIuc3RhcnREb2N1bWVudCgpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBTQVgyCi0gICAgICAgICAgICBpZiAoZkNvbnRlbnRIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBpZiAobG9jYXRvciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZDb250ZW50SGFuZGxlci5zZXREb2N1bWVudExvY2F0b3IobmV3IExvY2F0b3JQcm94eShsb2NhdG9yKSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGZDb250ZW50SGFuZGxlci5zdGFydERvY3VtZW50KCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWE5JRXhjZXB0aW9uKGUpOwotICAgICAgICB9Ci0KLSAgICB9IC8vIHN0YXJ0RG9jdW1lbnQobG9jYXRvcixlbmNvZGluZyxhdWdzKQotCi0gICAgLyoqCi0gICAgICogTm90aWZpZXMgb2YgdGhlIHByZXNlbmNlIG9mIGFuIFhNTERlY2wgbGluZSBpbiB0aGUgZG9jdW1lbnQuIElmCi0gICAgICogcHJlc2VudCwgdGhpcyBtZXRob2Qgd2lsbCBiZSBjYWxsZWQgaW1tZWRpYXRlbHkgZm9sbG93aW5nIHRoZQotICAgICAqIHN0YXJ0RG9jdW1lbnQgY2FsbC4KLSAgICAgKgotICAgICAqIEBwYXJhbSB2ZXJzaW9uICAgIFRoZSBYTUwgdmVyc2lvbi4KLSAgICAgKiBAcGFyYW0gZW5jb2RpbmcgICBUaGUgSUFOQSBlbmNvZGluZyBuYW1lIG9mIHRoZSBkb2N1bWVudCwgb3IgbnVsbCBpZgotICAgICAqICAgICAgICAgICAgICAgICAgIG5vdCBzcGVjaWZpZWQuCi0gICAgICogQHBhcmFtIHN0YW5kYWxvbmUgVGhlIHN0YW5kYWxvbmUgdmFsdWUsIG9yIG51bGwgaWYgbm90IHNwZWNpZmllZC4KLSAgICAgKiBAcGFyYW0gYXVncyAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB4bWxEZWNsKFN0cmluZyB2ZXJzaW9uLCBTdHJpbmcgZW5jb2RpbmcsIFN0cmluZyBzdGFuZGFsb25lLCBBdWdtZW50YXRpb25zIGF1Z3MpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICAvLyB0aGUgdmVyc2lvbiBuZWVkIG9ubHkgYmUgc2V0IG9uY2U7IGlmCi0gICAgICAgIC8vIGRvY3VtZW50J3MgWE1MIDEuMHwxLjEsIHRoYXQncyBob3cgaXQnbGwgc3RheQotICAgICAgICBmVmVyc2lvbiA9IHZlcnNpb247Ci0gICAgICAgIGZTdGFuZGFsb25lID0gInllcyIuZXF1YWxzKHN0YW5kYWxvbmUpOwotICAgIH0gLy8geG1sRGVjbChTdHJpbmcsU3RyaW5nLFN0cmluZykKLQotICAgIC8qKgotICAgICAqIE5vdGlmaWVzIG9mIHRoZSBwcmVzZW5jZSBvZiB0aGUgRE9DVFlQRSBsaW5lIGluIHRoZSBkb2N1bWVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSByb290RWxlbWVudCBUaGUgbmFtZSBvZiB0aGUgcm9vdCBlbGVtZW50LgotICAgICAqIEBwYXJhbSBwdWJsaWNJZCAgICBUaGUgcHVibGljIGlkZW50aWZpZXIgaWYgYW4gZXh0ZXJuYWwgRFREIG9yIG51bGwKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgaWYgdGhlIGV4dGVybmFsIERURCBpcyBzcGVjaWZpZWQgdXNpbmcgU1lTVEVNLgotICAgICAqIEBwYXJhbSBzeXN0ZW1JZCAgICBUaGUgc3lzdGVtIGlkZW50aWZpZXIgaWYgYW4gZXh0ZXJuYWwgRFRELCBudWxsCi0gICAgICogICAgICAgICAgICAgICAgICAgIG90aGVyd2lzZS4KLSAgICAgKiBAcGFyYW0gYXVncyAgICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGRvY3R5cGVEZWNsKFN0cmluZyByb290RWxlbWVudCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcHVibGljSWQsIFN0cmluZyBzeXN0ZW1JZCwgQXVnbWVudGF0aW9ucyBhdWdzKQotICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgZkluRFREID0gdHJ1ZTsKLQotICAgICAgICB0cnkgewotICAgICAgICAgICAgLy8gU0FYMiBleHRlbnNpb24KLSAgICAgICAgICAgIGlmIChmTGV4aWNhbEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZMZXhpY2FsSGFuZGxlci5zdGFydERURChyb290RWxlbWVudCwgcHVibGljSWQsIHN5c3RlbUlkKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBYTklFeGNlcHRpb24oZSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBpcyB0aGVyZSBhIERlY2xIYW5kbGVyPwotICAgICAgICBpZihmRGVjbEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkRlY2xhcmVkQXR0cnMgPSBuZXcgU3ltYm9sSGFzaCgpOwotICAgICAgICB9Ci0KLSAgICB9IC8vIGRvY3R5cGVEZWNsKFN0cmluZyxTdHJpbmcsU3RyaW5nKQotCi0gICAgICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIG5vdGlmaWVzIG9mIHRoZSBzdGFydCBvZiBhbiBlbnRpdHkuIFRoZSBEVEQgaGFzIHRoZQotICAgICAqIHBzZXVkby1uYW1lIG9mICJbZHRkXSIgcGFyYW1ldGVyIGVudGl0eSBuYW1lcyBzdGFydCB3aXRoICclJzsgYW5kCi0gICAgICogZ2VuZXJhbCBlbnRpdHkgbmFtZXMgYXJlIGp1c3QgdGhlIGVudGl0eSBuYW1lLgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gU2luY2UgdGhlIGRvY3VtZW50IGlzIGFuIGVudGl0eSwgdGhlIGhhbmRsZXIKLSAgICAgKiB3aWxsIGJlIG5vdGlmaWVkIG9mIHRoZSBzdGFydCBvZiB0aGUgZG9jdW1lbnQgZW50aXR5IGJ5IGNhbGxpbmcgdGhlCi0gICAgICogc3RhcnRFbnRpdHkgbWV0aG9kIHdpdGggdGhlIGVudGl0eSBuYW1lICJbeG1sXSIgPGVtPmJlZm9yZTwvZW0+IGNhbGxpbmcKLSAgICAgKiB0aGUgc3RhcnREb2N1bWVudCBtZXRob2QuIFdoZW4gZXhwb3NpbmcgZW50aXR5IGJvdW5kYXJpZXMgdGhyb3VnaCB0aGUKLSAgICAgKiBTQVggQVBJLCB0aGUgZG9jdW1lbnQgZW50aXR5IGlzIG5ldmVyIHJlcG9ydGVkLCBob3dldmVyLgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gVGhpcyBtZXRob2QgaXMgbm90IGNhbGxlZCBmb3IgZW50aXR5IHJlZmVyZW5jZXMKLSAgICAgKiBhcHBlYXJpbmcgYXMgcGFydCBvZiBhdHRyaWJ1dGUgdmFsdWVzLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgICAgIFRoZSBuYW1lIG9mIHRoZSBlbnRpdHkuCi0gICAgICogQHBhcmFtIGlkZW50aWZpZXIgVGhlIHJlc291cmNlIGlkZW50aWZpZXIuCi0gICAgICogQHBhcmFtIGVuY29kaW5nIFRoZSBhdXRvLWRldGVjdGVkIElBTkEgZW5jb2RpbmcgbmFtZSBvZiB0aGUgZW50aXR5Ci0gICAgICogICAgICAgICAgICAgICAgIHN0cmVhbS4gVGhpcyB2YWx1ZSB3aWxsIGJlIG51bGwgaW4gdGhvc2Ugc2l0dWF0aW9ucwotICAgICAqICAgICAgICAgICAgICAgICB3aGVyZSB0aGUgZW50aXR5IGVuY29kaW5nIGlzIG5vdCBhdXRvLWRldGVjdGVkIChlLmcuCi0gICAgICogICAgICAgICAgICAgICAgIGludGVybmFsIHBhcmFtZXRlciBlbnRpdGllcykuCi0gICAgICogQHBhcmFtIGF1Z3MgICAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydEdlbmVyYWxFbnRpdHkoU3RyaW5nIG5hbWUsIFhNTFJlc291cmNlSWRlbnRpZmllciBpZGVudGlmaWVyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgZW5jb2RpbmcsIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIC8vIE9ubHkgcmVwb3J0IHN0YXJ0RW50aXR5IGlmIHRoaXMgZW50aXR5IHdhcyBhY3R1YWxseSByZWFkLgotICAgICAgICAgICAgaWYgKGF1Z3MgIT0gbnVsbCAmJiBCb29sZWFuLlRSVUUuZXF1YWxzKGF1Z3MuZ2V0SXRlbShDb25zdGFudHMuRU5USVRZX1NLSVBQRUQpKSkgewotICAgICAgICAgICAgICAgIC8vIHJlcG9ydCBza2lwcGVkIGVudGl0eSB0byBjb250ZW50IGhhbmRsZXIKLSAgICAgICAgICAgICAgICBpZiAoZkNvbnRlbnRIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgZkNvbnRlbnRIYW5kbGVyLnNraXBwZWRFbnRpdHkobmFtZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgLy8gU0FYMiBleHRlbnNpb24KLSAgICAgICAgICAgICAgICBpZiAoZkxleGljYWxIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgZkxleGljYWxIYW5kbGVyLnN0YXJ0RW50aXR5KG5hbWUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBYTklFeGNlcHRpb24oZSk7Ci0gICAgICAgIH0KLQotICAgIH0gLy8gc3RhcnRHZW5lcmFsRW50aXR5KFN0cmluZyxTdHJpbmcsU3RyaW5nLFN0cmluZyxTdHJpbmcpCi0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBub3RpZmllcyB0aGUgZW5kIG9mIGFuIGVudGl0eS4gVGhlIERURCBoYXMgdGhlIHBzZXVkby1uYW1lCi0gICAgICogb2YgIltkdGRdIiBwYXJhbWV0ZXIgZW50aXR5IG5hbWVzIHN0YXJ0IHdpdGggJyUnOyBhbmQgZ2VuZXJhbCBlbnRpdHkKLSAgICAgKiBuYW1lcyBhcmUganVzdCB0aGUgZW50aXR5IG5hbWUuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBTaW5jZSB0aGUgZG9jdW1lbnQgaXMgYW4gZW50aXR5LCB0aGUgaGFuZGxlcgotICAgICAqIHdpbGwgYmUgbm90aWZpZWQgb2YgdGhlIGVuZCBvZiB0aGUgZG9jdW1lbnQgZW50aXR5IGJ5IGNhbGxpbmcgdGhlCi0gICAgICogZW5kRW50aXR5IG1ldGhvZCB3aXRoIHRoZSBlbnRpdHkgbmFtZSAiW3htbF0iIDxlbT5hZnRlcjwvZW0+IGNhbGxpbmcKLSAgICAgKiB0aGUgZW5kRG9jdW1lbnQgbWV0aG9kLiBXaGVuIGV4cG9zaW5nIGVudGl0eSBib3VuZGFyaWVzIHRocm91Z2ggdGhlCi0gICAgICogU0FYIEFQSSwgdGhlIGRvY3VtZW50IGVudGl0eSBpcyBuZXZlciByZXBvcnRlZCwgaG93ZXZlci4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoaXMgbWV0aG9kIGlzIG5vdCBjYWxsZWQgZm9yIGVudGl0eSByZWZlcmVuY2VzCi0gICAgICogYXBwZWFyaW5nIGFzIHBhcnQgb2YgYXR0cmlidXRlIHZhbHVlcy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBlbnRpdHkuCi0gICAgICogQHBhcmFtIGF1Z3MgICAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbmRHZW5lcmFsRW50aXR5KFN0cmluZyBuYW1lLCBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAvLyBPbmx5IHJlcG9ydCBlbmRFbnRpdHkgaWYgdGhpcyBlbnRpdHkgd2FzIGFjdHVhbGx5IHJlYWQuCi0gICAgICAgICAgICBpZiAoYXVncyA9PSBudWxsIHx8ICFCb29sZWFuLlRSVUUuZXF1YWxzKGF1Z3MuZ2V0SXRlbShDb25zdGFudHMuRU5USVRZX1NLSVBQRUQpKSkgewotICAgICAgICAgICAgICAgIC8vIFNBWDIgZXh0ZW5zaW9uCi0gICAgICAgICAgICAgICAgaWYgKGZMZXhpY2FsSGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZMZXhpY2FsSGFuZGxlci5lbmRFbnRpdHkobmFtZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChTQVhFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFhOSUV4Y2VwdGlvbihlKTsKLSAgICAgICAgfQotCi0gICAgfSAvLyBlbmRFbnRpdHkoU3RyaW5nKQotCi0gICAgIC8qKgotICAgICAqIFRoZSBzdGFydCBvZiBhbiBlbGVtZW50LiBJZiB0aGUgZG9jdW1lbnQgc3BlY2lmaWVzIHRoZSBzdGFydCBlbGVtZW50Ci0gICAgICogYnkgdXNpbmcgYW4gZW1wdHkgdGFnLCB0aGVuIHRoZSBzdGFydEVsZW1lbnQgbWV0aG9kIHdpbGwgaW1tZWRpYXRlbHkKLSAgICAgKiBiZSBmb2xsb3dlZCBieSB0aGUgZW5kRWxlbWVudCBtZXRob2QsIHdpdGggbm8gaW50ZXJ2ZW5pbmcgbWV0aG9kcy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlbGVtZW50ICAgIFRoZSBuYW1lIG9mIHRoZSBlbGVtZW50LgotICAgICAqIEBwYXJhbSBhdHRyaWJ1dGVzIFRoZSBlbGVtZW50IGF0dHJpYnV0ZXMuCi0gICAgICogQHBhcmFtIGF1Z3MgICAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQoUU5hbWUgZWxlbWVudCwgWE1MQXR0cmlidXRlcyBhdHRyaWJ1dGVzLCBBdWdtZW50YXRpb25zIGF1Z3MpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAvLyBTQVgxCi0gICAgICAgICAgICBpZiAoZkRvY3VtZW50SGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgLy8gUkVWSVNJVDogc2hvdWxkIHdlIHN1cHBvcnQgc2NoZW1hLW5vcm1hbGl6ZWQtdmFsdWUgZm9yIFNBWDEgZXZlbnRzCi0gICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICBmQXR0cmlidXRlc1Byb3h5LnNldEF0dHJpYnV0ZXMoYXR0cmlidXRlcyk7Ci0gICAgICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci5zdGFydEVsZW1lbnQoZWxlbWVudC5yYXduYW1lLCBmQXR0cmlidXRlc1Byb3h5KTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gU0FYMgotICAgICAgICAgICAgaWYgKGZDb250ZW50SGFuZGxlciAhPSBudWxsKSB7Ci0KLSAgICAgICAgICAgICAgICBpZiAoZk5hbWVzcGFjZXMpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gc2VuZCBwcmVmaXggbWFwcGluZyBldmVudHMKLSAgICAgICAgICAgICAgICAgICAgc3RhcnROYW1lc3BhY2VNYXBwaW5nKCk7Ci0KLSAgICAgICAgICAgICAgICAgICAgLy8gUkVWSVNJVDogSXQgc2hvdWxkIG5vdCBiZSBuZWNlc3NhcnkgdG8gaXRlcmF0ZSBvdmVyIHRoZSBhdHRyaWJ1dGUKLSAgICAgICAgICAgICAgICAgICAgLy8gbGlzdCB3aGVuIHRoZSBzZXQgb2YgW25hbWVzcGFjZSBhdHRyaWJ1dGVzXSBpcyBlbXB0eSBmb3IgdGhpcwotICAgICAgICAgICAgICAgICAgICAvLyBlbGVtZW50LiBUaGlzIHNob3VsZCBiZSBjb21wdXRhYmxlIGZyb20gdGhlIE5hbWVzcGFjZUNvbnRleHQsIGJ1dAotICAgICAgICAgICAgICAgICAgICAvLyBzaW5jZSB3ZSBjdXJyZW50bHkgZG9uJ3QgcmVwb3J0IHRoZSBtYXBwaW5ncyBmb3IgdGhlIHhtbCBwcmVmaXgKLSAgICAgICAgICAgICAgICAgICAgLy8gd2UgY2Fubm90IHVzZSB0aGUgZGVjbGFyZWQgcHJlZml4IGNvdW50IGZvciB0aGUgY3VycmVudCBjb250ZXh0Ci0gICAgICAgICAgICAgICAgICAgIC8vIHRvIHNraXAgdGhpcyBzZWN0aW9uLiAtLSBtcmdsYXZhcwotICAgICAgICAgICAgICAgICAgICBpbnQgbGVuID0gYXR0cmlidXRlcy5nZXRMZW5ndGgoKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKCFmTmFtZXNwYWNlUHJlZml4ZXMpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSBsZW4gLSAxOyBpID49IDA7IC0taSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXMuZ2V0TmFtZShpLCBmUU5hbWUpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoZlFOYW1lLnByZWZpeCA9PSBYTUxTeW1ib2xzLlBSRUZJWF9YTUxOUykgfHwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZlFOYW1lLnJhd25hbWUgPT0gWE1MU3ltYm9scy5QUkVGSVhfWE1MTlMpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHJlbW92ZSBuYW1lc3BhY2UgZGVjbGFyYXRpb24gYXR0cmlidXRlcwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzLnJlbW92ZUF0dHJpYnV0ZUF0KGkpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICghZlhNTE5TVVJJcykgewotICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IGxlbiAtIDE7IGkgPj0gMDsgLS1pKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlcy5nZXROYW1lKGksIGZRTmFtZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChmUU5hbWUucHJlZml4ID09IFhNTFN5bWJvbHMuUFJFRklYX1hNTE5TKSB8fAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChmUU5hbWUucmF3bmFtZSA9PSBYTUxTeW1ib2xzLlBSRUZJWF9YTUxOUykpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbG9jYWxwYXJ0IHNob3VsZCBiZSBlbXB0eSBzdHJpbmcgYXMgcGVyIFNBWCBkb2N1bWVudGF0aW9uOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBodHRwOi8vd3d3LnNheHByb2plY3Qub3JnLz9zZWxlY3RlZD1uYW1lc3BhY2VzCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZRTmFtZS5wcmVmaXggPSAiIjsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZlFOYW1lLnVyaSA9ICIiOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmUU5hbWUubG9jYWxwYXJ0ID0gIiI7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXMuc2V0TmFtZShpLCBmUU5hbWUpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIGZBdWdtZW50YXRpb25zID0gYXVnczsKLQotICAgICAgICAgICAgICAgIFN0cmluZyB1cmkgPSBlbGVtZW50LnVyaSAhPSBudWxsID8gZWxlbWVudC51cmkgOiAiIjsKLSAgICAgICAgICAgICAgICBTdHJpbmcgbG9jYWxwYXJ0ID0gZk5hbWVzcGFjZXMgPyBlbGVtZW50LmxvY2FscGFydCA6ICIiOwotICAgICAgICAgICAgICAgIGZBdHRyaWJ1dGVzUHJveHkuc2V0QXR0cmlidXRlcyhhdHRyaWJ1dGVzKTsKLSAgICAgICAgICAgICAgICBmQ29udGVudEhhbmRsZXIuc3RhcnRFbGVtZW50KHVyaSwgbG9jYWxwYXJ0LCBlbGVtZW50LnJhd25hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmQXR0cmlidXRlc1Byb3h5KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBYTklFeGNlcHRpb24oZSk7Ci0gICAgICAgIH0KLQotICAgIH0gLy8gc3RhcnRFbGVtZW50KFFOYW1lLFhNTEF0dHJpYnV0ZXMpCi0KLSAgICAvKioKLSAgICAgKiBDaGFyYWN0ZXIgY29udGVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSB0ZXh0IFRoZSBjb250ZW50LgotICAgICAqIEBwYXJhbSBhdWdzICAgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY2hhcmFjdGVycyhYTUxTdHJpbmcgdGV4dCwgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLQotICAgICAgICAvLyBpZiB0eXBlIGlzIHVuaW9uIChYTUwgU2NoZW1hKSBpdCBpcyBwb3NzaWJsZSB0aGF0IHdlIHJlY2VpdmUKLSAgICAgICAgLy8gY2hhcmFjdGVyIGNhbGwgd2l0aCBlbXB0eSBkYXRhCi0gICAgICAgIGlmICh0ZXh0Lmxlbmd0aCA9PSAwKSB7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLQotCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAvLyBTQVgxCi0gICAgICAgICAgICBpZiAoZkRvY3VtZW50SGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgLy8gUkVWSVNJVDogc2hvdWxkIHdlIHN1cHBvcnQgc2NoZW1hLW5vcm1hbGl6ZWQtdmFsdWUgZm9yIFNBWDEgZXZlbnRzCi0gICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLmNoYXJhY3RlcnModGV4dC5jaCwgdGV4dC5vZmZzZXQsIHRleHQubGVuZ3RoKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gU0FYMgotICAgICAgICAgICAgaWYgKGZDb250ZW50SGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZkNvbnRlbnRIYW5kbGVyLmNoYXJhY3RlcnModGV4dC5jaCwgdGV4dC5vZmZzZXQsIHRleHQubGVuZ3RoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBYTklFeGNlcHRpb24oZSk7Ci0gICAgICAgIH0KLQotICAgIH0gLy8gY2hhcmFjdGVycyhYTUxTdHJpbmcpCi0KLSAgICAvKioKLSAgICAgKiBJZ25vcmFibGUgd2hpdGVzcGFjZS4gRm9yIHRoaXMgbWV0aG9kIHRvIGJlIGNhbGxlZCwgdGhlIGRvY3VtZW50Ci0gICAgICogc291cmNlIG11c3QgaGF2ZSBzb21lIHdheSBvZiBkZXRlcm1pbmluZyB0aGF0IHRoZSB0ZXh0IGNvbnRhaW5pbmcKLSAgICAgKiBvbmx5IHdoaXRlc3BhY2UgY2hhcmFjdGVycyBzaG91bGQgYmUgY29uc2lkZXJlZCBpZ25vcmFibGUuIEZvcgotICAgICAqIGV4YW1wbGUsIHRoZSB2YWxpZGF0b3IgY2FuIGRldGVybWluZSBpZiBhIGxlbmd0aCBvZiB3aGl0ZXNwYWNlCi0gICAgICogY2hhcmFjdGVycyBpbiB0aGUgZG9jdW1lbnQgYXJlIGlnbm9yYWJsZSBiYXNlZCBvbiB0aGUgZWxlbWVudAotICAgICAqIGNvbnRlbnQgbW9kZWwuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdGV4dCBUaGUgaWdub3JhYmxlIHdoaXRlc3BhY2UuCi0gICAgICogQHBhcmFtIGF1Z3MgICAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBpZ25vcmFibGVXaGl0ZXNwYWNlKFhNTFN0cmluZyB0ZXh0LCBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAvLyBTQVgxCi0gICAgICAgICAgICBpZiAoZkRvY3VtZW50SGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci5pZ25vcmFibGVXaGl0ZXNwYWNlKHRleHQuY2gsIHRleHQub2Zmc2V0LCB0ZXh0Lmxlbmd0aCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIFNBWDIKLSAgICAgICAgICAgIGlmIChmQ29udGVudEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZDb250ZW50SGFuZGxlci5pZ25vcmFibGVXaGl0ZXNwYWNlKHRleHQuY2gsIHRleHQub2Zmc2V0LCB0ZXh0Lmxlbmd0aCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWE5JRXhjZXB0aW9uKGUpOwotICAgICAgICB9Ci0KLSAgICB9IC8vIGlnbm9yYWJsZVdoaXRlc3BhY2UoWE1MU3RyaW5nKQotCi0gICAgLyoqCi0gICAgICogVGhlIGVuZCBvZiBhbiBlbGVtZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIGVsZW1lbnQgVGhlIG5hbWUgb2YgdGhlIGVsZW1lbnQuCi0gICAgICogQHBhcmFtIGF1Z3MgICAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbmRFbGVtZW50KFFOYW1lIGVsZW1lbnQsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLQotICAgICAgICB0cnkgewotICAgICAgICAgICAgLy8gU0FYMQotICAgICAgICAgICAgaWYgKGZEb2N1bWVudEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZEb2N1bWVudEhhbmRsZXIuZW5kRWxlbWVudChlbGVtZW50LnJhd25hbWUpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBTQVgyCi0gICAgICAgICAgICBpZiAoZkNvbnRlbnRIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmQXVnbWVudGF0aW9ucyA9IGF1Z3M7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIHVyaSA9IGVsZW1lbnQudXJpICE9IG51bGwgPyBlbGVtZW50LnVyaSA6ICIiOwotICAgICAgICAgICAgICAgIFN0cmluZyBsb2NhbHBhcnQgPSBmTmFtZXNwYWNlcyA/IGVsZW1lbnQubG9jYWxwYXJ0IDogIiI7Ci0gICAgICAgICAgICAgICAgZkNvbnRlbnRIYW5kbGVyLmVuZEVsZW1lbnQodXJpLCBsb2NhbHBhcnQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5yYXduYW1lKTsKLSAgICAgICAgICAgICAgICBpZiAoZk5hbWVzcGFjZXMpIHsKLSAgICAgICAgICAgICAgICAgICAgZW5kTmFtZXNwYWNlTWFwcGluZygpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBYTklFeGNlcHRpb24oZSk7Ci0gICAgICAgIH0KLQotICAgIH0gLy8gZW5kRWxlbWVudChRTmFtZSkKLQotICAgICAgICAvKioKLSAgICAgKiBUaGUgc3RhcnQgb2YgYSBDREFUQSBzZWN0aW9uLgotICAgICAqIEBwYXJhbSBhdWdzICAgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnRDREFUQShBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAvLyBTQVgyIGV4dGVuc2lvbgotICAgICAgICAgICAgaWYgKGZMZXhpY2FsSGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZkxleGljYWxIYW5kbGVyLnN0YXJ0Q0RBVEEoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBYTklFeGNlcHRpb24oZSk7Ci0gICAgICAgIH0KLQotICAgIH0gLy8gc3RhcnRDREFUQSgpCi0KLSAgICAvKioKLSAgICAgKiBUaGUgZW5kIG9mIGEgQ0RBVEEgc2VjdGlvbi4KLSAgICAgKiBAcGFyYW0gYXVncyAgICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZENEQVRBKEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIC8vIFNBWDIgZXh0ZW5zaW9uCi0gICAgICAgICAgICBpZiAoZkxleGljYWxIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmTGV4aWNhbEhhbmRsZXIuZW5kQ0RBVEEoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBYTklFeGNlcHRpb24oZSk7Ci0gICAgICAgIH0KLQotICAgIH0gLy8gZW5kQ0RBVEEoKQotCi0gICAgLyoqCi0gICAgICogQSBjb21tZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIHRleHQgVGhlIHRleHQgaW4gdGhlIGNvbW1lbnQuCi0gICAgICogQHBhcmFtIGF1Z3MgICAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBhcHBsaWNhdGlvbiB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY29tbWVudChYTUxTdHJpbmcgdGV4dCwgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLQotICAgICAgICB0cnkgewotICAgICAgICAgICAgLy8gU0FYMiBleHRlbnNpb24KLSAgICAgICAgICAgIGlmIChmTGV4aWNhbEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZMZXhpY2FsSGFuZGxlci5jb21tZW50KHRleHQuY2gsIDAsIHRleHQubGVuZ3RoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBYTklFeGNlcHRpb24oZSk7Ci0gICAgICAgIH0KLQotICAgIH0gLy8gY29tbWVudChYTUxTdHJpbmcpCi0KLSAgICAvKioKLSAgICAgKiBBIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24uIFByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb25zIGNvbnNpc3Qgb2YgYQotICAgICAqIHRhcmdldCBuYW1lIGFuZCwgb3B0aW9uYWxseSwgdGV4dCBkYXRhLiBUaGUgZGF0YSBpcyBvbmx5IG1lYW5pbmdmdWwKLSAgICAgKiB0byB0aGUgYXBwbGljYXRpb24uCi0gICAgICogPHA+Ci0gICAgICogVHlwaWNhbGx5LCBhIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24ncyBkYXRhIHdpbGwgY29udGFpbiBhIHNlcmllcwotICAgICAqIG9mIHBzZXVkby1hdHRyaWJ1dGVzLiBUaGVzZSBwc2V1ZG8tYXR0cmlidXRlcyBmb2xsb3cgdGhlIGZvcm0gb2YKLSAgICAgKiBlbGVtZW50IGF0dHJpYnV0ZXMgYnV0IGFyZSA8c3Ryb25nPm5vdDwvc3Ryb25nPiBwYXJzZWQgb3IgcHJlc2VudGVkCi0gICAgICogdG8gdGhlIGFwcGxpY2F0aW9uIGFzIGFueXRoaW5nIG90aGVyIHRoYW4gdGV4dC4gVGhlIGFwcGxpY2F0aW9uIGlzCi0gICAgICogcmVzcG9uc2libGUgZm9yIHBhcnNpbmcgdGhlIGRhdGEuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdGFyZ2V0IFRoZSB0YXJnZXQuCi0gICAgICogQHBhcmFtIGRhdGEgICBUaGUgZGF0YSBvciBudWxsIGlmIG5vbmUgc3BlY2lmaWVkLgotICAgICAqIEBwYXJhbSBhdWdzICAgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcHJvY2Vzc2luZ0luc3RydWN0aW9uKFN0cmluZyB0YXJnZXQsIFhNTFN0cmluZyBkYXRhLCBBdWdtZW50YXRpb25zIGF1Z3MpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIFJFVklTSVQgLSBJIGtlZXAgcnVubmluZyBpbnRvIFNBWCBhcHBzIHRoYXQgZXhwZWN0Ci0gICAgICAgIC8vICAgbnVsbCBkYXRhIHRvIGJlIGFuIGVtcHR5IHN0cmluZywgd2hpY2ggaXMgY29udHJhcnkKLSAgICAgICAgLy8gICB0byB0aGUgY29tbWVudCBmb3IgdGhpcyBtZXRob2QgaW4gdGhlIFNBWCBBUEkuCi0gICAgICAgIC8vCi0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIC8vIFNBWDEKLSAgICAgICAgICAgIGlmIChmRG9jdW1lbnRIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLnByb2Nlc3NpbmdJbnN0cnVjdGlvbih0YXJnZXQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YS50b1N0cmluZygpKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gU0FYMgotICAgICAgICAgICAgaWYgKGZDb250ZW50SGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZkNvbnRlbnRIYW5kbGVyLnByb2Nlc3NpbmdJbnN0cnVjdGlvbih0YXJnZXQsIGRhdGEudG9TdHJpbmcoKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWE5JRXhjZXB0aW9uKGUpOwotICAgICAgICB9Ci0KLSAgICB9IC8vIHByb2Nlc3NpbmdJbnN0cnVjdGlvbihTdHJpbmcsWE1MU3RyaW5nKQotCi0KLSAgICAvKioKLSAgICAgKiBUaGUgZW5kIG9mIHRoZSBkb2N1bWVudC4KLSAgICAgKiBAcGFyYW0gYXVncyAgICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZERvY3VtZW50KEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIC8vIFNBWDEKLSAgICAgICAgICAgIGlmIChmRG9jdW1lbnRIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLmVuZERvY3VtZW50KCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIFNBWDIKLSAgICAgICAgICAgIGlmIChmQ29udGVudEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZDb250ZW50SGFuZGxlci5lbmREb2N1bWVudCgpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChTQVhFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFhOSUV4Y2VwdGlvbihlKTsKLSAgICAgICAgfQotCi0gICAgfSAvLyBlbmREb2N1bWVudCgpCi0KLSAgICAvLwotICAgIC8vIFhNTERUREhhbmRsZXIgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBUaGUgc3RhcnQgb2YgdGhlIERURCBleHRlcm5hbCBzdWJzZXQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYXVncyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnRFeHRlcm5hbFN1YnNldChYTUxSZXNvdXJjZUlkZW50aWZpZXIgaWRlbnRpZmllciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIHN0YXJ0UGFyYW1ldGVyRW50aXR5KCJbZHRkXSIsIG51bGwsIG51bGwsIGF1Z3MpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoZSBlbmQgb2YgdGhlIERURCBleHRlcm5hbCBzdWJzZXQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYXVncyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kRXh0ZXJuYWxTdWJzZXQoQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgZW5kUGFyYW1ldGVyRW50aXR5KCJbZHRkXSIsIGF1Z3MpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIG5vdGlmaWVzIG9mIHRoZSBzdGFydCBvZiBwYXJhbWV0ZXIgZW50aXR5LiBUaGUgRFREIGhhcyB0aGUKLSAgICAgKiBwc2V1ZG8tbmFtZSBvZiAiW2R0ZF0iIHBhcmFtZXRlciBlbnRpdHkgbmFtZXMgc3RhcnQgd2l0aCAnJSc7IGFuZAotICAgICAqIGdlbmVyYWwgZW50aXR5IG5hbWVzIGFyZSBqdXN0IHRoZSBlbnRpdHkgbmFtZS4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFNpbmNlIHRoZSBkb2N1bWVudCBpcyBhbiBlbnRpdHksIHRoZSBoYW5kbGVyCi0gICAgICogd2lsbCBiZSBub3RpZmllZCBvZiB0aGUgc3RhcnQgb2YgdGhlIGRvY3VtZW50IGVudGl0eSBieSBjYWxsaW5nIHRoZQotICAgICAqIHN0YXJ0RW50aXR5IG1ldGhvZCB3aXRoIHRoZSBlbnRpdHkgbmFtZSAiW3htbF0iIDxlbT5iZWZvcmU8L2VtPiBjYWxsaW5nCi0gICAgICogdGhlIHN0YXJ0RG9jdW1lbnQgbWV0aG9kLiBXaGVuIGV4cG9zaW5nIGVudGl0eSBib3VuZGFyaWVzIHRocm91Z2ggdGhlCi0gICAgICogU0FYIEFQSSwgdGhlIGRvY3VtZW50IGVudGl0eSBpcyBuZXZlciByZXBvcnRlZCwgaG93ZXZlci4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoaXMgbWV0aG9kIGlzIG5vdCBjYWxsZWQgZm9yIGVudGl0eSByZWZlcmVuY2VzCi0gICAgICogYXBwZWFyaW5nIGFzIHBhcnQgb2YgYXR0cmlidXRlIHZhbHVlcy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lICAgICBUaGUgbmFtZSBvZiB0aGUgcGFyYW1ldGVyIGVudGl0eS4KLSAgICAgKiBAcGFyYW0gaWRlbnRpZmllciBUaGUgcmVzb3VyY2UgaWRlbnRpZmllci4KLSAgICAgKiBAcGFyYW0gZW5jb2RpbmcgVGhlIGF1dG8tZGV0ZWN0ZWQgSUFOQSBlbmNvZGluZyBuYW1lIG9mIHRoZSBlbnRpdHkKLSAgICAgKiAgICAgICAgICAgICAgICAgc3RyZWFtLiBUaGlzIHZhbHVlIHdpbGwgYmUgbnVsbCBpbiB0aG9zZSBzaXR1YXRpb25zCi0gICAgICogICAgICAgICAgICAgICAgIHdoZXJlIHRoZSBlbnRpdHkgZW5jb2RpbmcgaXMgbm90IGF1dG8tZGV0ZWN0ZWQgKGUuZy4KLSAgICAgKiAgICAgICAgICAgICAgICAgaW50ZXJuYWwgcGFyYW1ldGVyIGVudGl0aWVzKS4KLSAgICAgKiBAcGFyYW0gYXVncyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnRQYXJhbWV0ZXJFbnRpdHkoU3RyaW5nIG5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MUmVzb3VyY2VJZGVudGlmaWVyIGlkZW50aWZpZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGVuY29kaW5nLCBBdWdtZW50YXRpb25zIGF1Z3MpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAvLyBPbmx5IHJlcG9ydCBzdGFydEVudGl0eSBpZiB0aGlzIGVudGl0eSB3YXMgYWN0dWFsbHkgcmVhZC4KLSAgICAgICAgICAgIGlmIChhdWdzICE9IG51bGwgJiYgQm9vbGVhbi5UUlVFLmVxdWFscyhhdWdzLmdldEl0ZW0oQ29uc3RhbnRzLkVOVElUWV9TS0lQUEVEKSkpIHsKLSAgICAgICAgICAgICAgICAvLyByZXBvcnQgc2tpcHBlZCBlbnRpdHkgdG8gY29udGVudCBoYW5kbGVyCi0gICAgICAgICAgICAgICAgaWYgKGZDb250ZW50SGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZDb250ZW50SGFuZGxlci5za2lwcGVkRW50aXR5KG5hbWUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIC8vIFNBWDIgZXh0ZW5zaW9uCi0gICAgICAgICAgICAgICAgaWYgKGZMZXhpY2FsSGFuZGxlciAhPSBudWxsICYmIGZMZXhpY2FsSGFuZGxlclBhcmFtZXRlckVudGl0aWVzKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZMZXhpY2FsSGFuZGxlci5zdGFydEVudGl0eShuYW1lKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWE5JRXhjZXB0aW9uKGUpOwotICAgICAgICB9Ci0KLSAgICB9IC8vIHN0YXJ0UGFyYW1ldGVyRW50aXR5KFN0cmluZyxpZGVudGlmaWVyLFN0cmluZyxBdWdtZW50YXRpb24pCi0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBub3RpZmllcyB0aGUgZW5kIG9mIGFuIGVudGl0eS4gVGhlIERURCBoYXMgdGhlIHBzZXVkby1uYW1lCi0gICAgICogb2YgIltkdGRdIiBwYXJhbWV0ZXIgZW50aXR5IG5hbWVzIHN0YXJ0IHdpdGggJyUnOyBhbmQgZ2VuZXJhbCBlbnRpdHkKLSAgICAgKiBuYW1lcyBhcmUganVzdCB0aGUgZW50aXR5IG5hbWUuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBTaW5jZSB0aGUgZG9jdW1lbnQgaXMgYW4gZW50aXR5LCB0aGUgaGFuZGxlcgotICAgICAqIHdpbGwgYmUgbm90aWZpZWQgb2YgdGhlIGVuZCBvZiB0aGUgZG9jdW1lbnQgZW50aXR5IGJ5IGNhbGxpbmcgdGhlCi0gICAgICogZW5kRW50aXR5IG1ldGhvZCB3aXRoIHRoZSBlbnRpdHkgbmFtZSAiW3htbF0iIDxlbT5hZnRlcjwvZW0+IGNhbGxpbmcKLSAgICAgKiB0aGUgZW5kRG9jdW1lbnQgbWV0aG9kLiBXaGVuIGV4cG9zaW5nIGVudGl0eSBib3VuZGFyaWVzIHRocm91Z2ggdGhlCi0gICAgICogU0FYIEFQSSwgdGhlIGRvY3VtZW50IGVudGl0eSBpcyBuZXZlciByZXBvcnRlZCwgaG93ZXZlci4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoaXMgbWV0aG9kIGlzIG5vdCBjYWxsZWQgZm9yIGVudGl0eSByZWZlcmVuY2VzCi0gICAgICogYXBwZWFyaW5nIGFzIHBhcnQgb2YgYXR0cmlidXRlIHZhbHVlcy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBwYXJhbWV0ZXIgZW50aXR5LgotICAgICAqIEBwYXJhbSBhdWdzIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbmRQYXJhbWV0ZXJFbnRpdHkoU3RyaW5nIG5hbWUsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIC8vIE9ubHkgcmVwb3J0IGVuZEVudGl0eSBpZiB0aGlzIGVudGl0eSB3YXMgYWN0dWFsbHkgcmVhZC4KLSAgICAgICAgICAgIGlmIChhdWdzID09IG51bGwgfHwgIUJvb2xlYW4uVFJVRS5lcXVhbHMoYXVncy5nZXRJdGVtKENvbnN0YW50cy5FTlRJVFlfU0tJUFBFRCkpKSB7Ci0gICAgICAgICAgICAgICAgLy8gU0FYMiBleHRlbnNpb24KLSAgICAgICAgICAgICAgICBpZiAoZkxleGljYWxIYW5kbGVyICE9IG51bGwgJiYgZkxleGljYWxIYW5kbGVyUGFyYW1ldGVyRW50aXRpZXMpIHsKLSAgICAgICAgICAgICAgICAgICAgZkxleGljYWxIYW5kbGVyLmVuZEVudGl0eShuYW1lKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWE5JRXhjZXB0aW9uKGUpOwotICAgICAgICB9Ci0KLSAgICB9IC8vIGVuZEVudGl0eShTdHJpbmcpCi0KLSAgICAvKioKLSAgICAgKiBBbiBlbGVtZW50IGRlY2xhcmF0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgICAgICAgICBUaGUgbmFtZSBvZiB0aGUgZWxlbWVudC4KLSAgICAgKiBAcGFyYW0gY29udGVudE1vZGVsIFRoZSBlbGVtZW50IGNvbnRlbnQgbW9kZWwuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYXVncyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZWxlbWVudERlY2woU3RyaW5nIG5hbWUsIFN0cmluZyBjb250ZW50TW9kZWwsIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIC8vIFNBWDIgZXh0ZW5zaW9uCi0gICAgICAgICAgICBpZiAoZkRlY2xIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmRGVjbEhhbmRsZXIuZWxlbWVudERlY2wobmFtZSwgY29udGVudE1vZGVsKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBYTklFeGNlcHRpb24oZSk7Ci0gICAgICAgIH0KLQotICAgIH0gLy8gZWxlbWVudERlY2woU3RyaW5nLFN0cmluZywgQXVnbWVudGF0aW9ucykKLQotICAgIC8qKgotICAgICAqIEFuIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlbGVtZW50TmFtZSAgIFRoZSBuYW1lIG9mIHRoZSBlbGVtZW50IHRoYXQgdGhpcyBhdHRyaWJ1dGUKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBpcyBhc3NvY2lhdGVkIHdpdGguCi0gICAgICogQHBhcmFtIGF0dHJpYnV0ZU5hbWUgVGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgKiBAcGFyYW0gdHlwZSAgICAgICAgICBUaGUgYXR0cmlidXRlIHR5cGUuIFRoaXMgdmFsdWUgd2lsbCBiZSBvbmUgb2YKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICB0aGUgZm9sbG93aW5nOiAiQ0RBVEEiLCAiRU5USVRZIiwgIkVOVElUSUVTIiwKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAiRU5VTUVSQVRJT04iLCAiSUQiLCAiSURSRUYiLCAiSURSRUZTIiwKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAiTk1UT0tFTiIsICJOTVRPS0VOUyIsIG9yICJOT1RBVElPTiIuCi0gICAgICogQHBhcmFtIGVudW1lcmF0aW9uICAgSWYgdGhlIHR5cGUgaGFzIHRoZSB2YWx1ZSAiRU5VTUVSQVRJT04iIG9yCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgIk5PVEFUSU9OIiwgdGhpcyBhcnJheSBob2xkcyB0aGUgYWxsb3dlZCBhdHRyaWJ1dGUKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICB2YWx1ZXM7IG90aGVyd2lzZSwgdGhpcyBhcnJheSBpcyBudWxsLgotICAgICAqIEBwYXJhbSBkZWZhdWx0VHlwZSAgIFRoZSBhdHRyaWJ1dGUgZGVmYXVsdCB0eXBlLiBUaGlzIHZhbHVlIHdpbGwgYmUKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBvbmUgb2YgdGhlIGZvbGxvd2luZzogIiNGSVhFRCIsICIjSU1QTElFRCIsCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgIiNSRVFVSVJFRCIsIG9yIG51bGwuCi0gICAgICogQHBhcmFtIGRlZmF1bHRWYWx1ZSAgVGhlIGF0dHJpYnV0ZSBkZWZhdWx0IHZhbHVlLCBvciBudWxsIGlmIG5vCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdCB2YWx1ZSBpcyBzcGVjaWZpZWQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbm9uTm9ybWFsaXplZERlZmF1bHRWYWx1ZSAgVGhlIGF0dHJpYnV0ZSBkZWZhdWx0IHZhbHVlIHdpdGggbm8gbm9ybWFsaXphdGlvbgotICAgICAqICAgICAgICAgICAgICAgICAgICAgIHBlcmZvcm1lZCwgb3IgbnVsbCBpZiBubyBkZWZhdWx0IHZhbHVlIGlzIHNwZWNpZmllZC4KLSAgICAgKiBAcGFyYW0gYXVncyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgYXR0cmlidXRlRGVjbChTdHJpbmcgZWxlbWVudE5hbWUsIFN0cmluZyBhdHRyaWJ1dGVOYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHR5cGUsIFN0cmluZ1tdIGVudW1lcmF0aW9uLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGRlZmF1bHRUeXBlLCBYTUxTdHJpbmcgZGVmYXVsdFZhbHVlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MU3RyaW5nIG5vbk5vcm1hbGl6ZWREZWZhdWx0VmFsdWUsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIC8vIFNBWDIgZXh0ZW5zaW9uCi0gICAgICAgICAgICBpZiAoZkRlY2xIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAvLyB1c2VkIGFzIGEga2V5IHRvIGRldGVjdCBkdXBsaWNhdGUgYXR0cmlidXRlIGRlZmluaXRpb25zLgotICAgICAgICAgICAgICAgIFN0cmluZyBlbGVtQXR0ciA9IG5ldyBTdHJpbmdCdWZmZXIoZWxlbWVudE5hbWUpLmFwcGVuZCgiPCIpLmFwcGVuZChhdHRyaWJ1dGVOYW1lKS50b1N0cmluZygpOwotICAgICAgICAgICAgICAgIGlmKGZEZWNsYXJlZEF0dHJzLmdldChlbGVtQXR0cikgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAvLyB3ZSBhcmVuJ3QgcGVybWl0dGVkIHRvIHJldHVybiBkdXBsaWNhdGUgYXR0cmlidXRlIGRlZmluaXRpb25zCi0gICAgICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZkRlY2xhcmVkQXR0cnMucHV0KGVsZW1BdHRyLCBCb29sZWFuLlRSVUUpOwotICAgICAgICAgICAgICAgIGlmICh0eXBlLmVxdWFscygiTk9UQVRJT04iKSB8fAotICAgICAgICAgICAgICAgICAgICB0eXBlLmVxdWFscygiRU5VTUVSQVRJT04iKSkgewotCi0gICAgICAgICAgICAgICAgICAgIFN0cmluZ0J1ZmZlciBzdHIgPSBuZXcgU3RyaW5nQnVmZmVyKCk7Ci0gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlLmVxdWFscygiTk9UQVRJT04iKSkgewotICAgICAgICAgICAgICAgICAgICAgIHN0ci5hcHBlbmQodHlwZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgc3RyLmFwcGVuZCgiICgiKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKCIoIik7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBlbnVtZXJhdGlvbi5sZW5ndGg7IGkrKykgewotICAgICAgICAgICAgICAgICAgICAgICAgc3RyLmFwcGVuZChlbnVtZXJhdGlvbltpXSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaSA8IGVudW1lcmF0aW9uLmxlbmd0aCAtIDEpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKCd8Jyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgc3RyLmFwcGVuZCgnKScpOwotICAgICAgICAgICAgICAgICAgICB0eXBlID0gc3RyLnRvU3RyaW5nKCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIFN0cmluZyB2YWx1ZSA9IChkZWZhdWx0VmFsdWU9PW51bGwpID8gbnVsbCA6IGRlZmF1bHRWYWx1ZS50b1N0cmluZygpOwotICAgICAgICAgICAgICAgIGZEZWNsSGFuZGxlci5hdHRyaWJ1dGVEZWNsKGVsZW1lbnROYW1lLCBhdHRyaWJ1dGVOYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUsIGRlZmF1bHRUeXBlLCB2YWx1ZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWE5JRXhjZXB0aW9uKGUpOwotICAgICAgICB9Ci0KLSAgICB9IC8vIGF0dHJpYnV0ZURlY2woU3RyaW5nLFN0cmluZyxTdHJpbmcsU3RyaW5nW10sU3RyaW5nLFhNTFN0cmluZywgWE1MU3RyaW5nLCBBdWdtZW50YXRpb25zKQotCi0gICAgLyoqCi0gICAgICogQW4gaW50ZXJuYWwgZW50aXR5IGRlY2xhcmF0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGVudGl0eS4gUGFyYW1ldGVyIGVudGl0eSBuYW1lcyBzdGFydCB3aXRoCi0gICAgICogICAgICAgICAgICAgJyUnLCB3aGVyZWFzIHRoZSBuYW1lIG9mIGEgZ2VuZXJhbCBlbnRpdHkgaXMganVzdCB0aGUKLSAgICAgKiAgICAgICAgICAgICBlbnRpdHkgbmFtZS4KLSAgICAgKiBAcGFyYW0gdGV4dCBUaGUgdmFsdWUgb2YgdGhlIGVudGl0eS4KLSAgICAgKiBAcGFyYW0gbm9uTm9ybWFsaXplZFRleHQgVGhlIG5vbi1ub3JtYWxpemVkIHZhbHVlIG9mIHRoZSBlbnRpdHkuIFRoaXMKLSAgICAgKiAgICAgICAgICAgICB2YWx1ZSBjb250YWlucyB0aGUgc2FtZSBzZXF1ZW5jZSBvZiBjaGFyYWN0ZXJzIHRoYXQgd2FzIGluCi0gICAgICogICAgICAgICAgICAgdGhlIGludGVybmFsIGVudGl0eSBkZWNsYXJhdGlvbiwgd2l0aG91dCBhbnkgZW50aXR5Ci0gICAgICogICAgICAgICAgICAgcmVmZXJlbmNlcyBleHBhbmRlZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBhdWdzIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBpbnRlcm5hbEVudGl0eURlY2woU3RyaW5nIG5hbWUsIFhNTFN0cmluZyB0ZXh0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxTdHJpbmcgbm9uTm9ybWFsaXplZFRleHQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIC8vIFNBWDIgZXh0ZW5zaW9ucwotICAgICAgICAgICAgaWYgKGZEZWNsSGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZkRlY2xIYW5kbGVyLmludGVybmFsRW50aXR5RGVjbChuYW1lLCB0ZXh0LnRvU3RyaW5nKCkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChTQVhFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFhOSUV4Y2VwdGlvbihlKTsKLSAgICAgICAgfQotCi0gICAgfSAvLyBpbnRlcm5hbEVudGl0eURlY2woU3RyaW5nLFhNTFN0cmluZyxYTUxTdHJpbmcpCi0KLSAgICAvKioKLSAgICAgKiBBbiBleHRlcm5hbCBlbnRpdHkgZGVjbGFyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSAgICAgVGhlIG5hbWUgb2YgdGhlIGVudGl0eS4gUGFyYW1ldGVyIGVudGl0eSBuYW1lcyBzdGFydAotICAgICAqICAgICAgICAgICAgICAgICB3aXRoICclJywgd2hlcmVhcyB0aGUgbmFtZSBvZiBhIGdlbmVyYWwgZW50aXR5IGlzIGp1c3QKLSAgICAgKiAgICAgICAgICAgICAgICAgdGhlIGVudGl0eSBuYW1lLgotICAgICAqIEBwYXJhbSBpZGVudGlmaWVyICAgIEFuIG9iamVjdCBjb250YWluaW5nIGFsbCBsb2NhdGlvbiBpbmZvcm1hdGlvbgotICAgICAqICAgICAgICAgICAgICAgICAgICAgIHBlcnRpbmVudCB0byB0aGlzIGVudGl0eS4KLSAgICAgKiBAcGFyYW0gYXVncyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZXh0ZXJuYWxFbnRpdHlEZWNsKFN0cmluZyBuYW1lLCBYTUxSZXNvdXJjZUlkZW50aWZpZXIgaWRlbnRpZmllciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIC8vIFNBWDIgZXh0ZW5zaW9uCi0gICAgICAgICAgICBpZiAoZkRlY2xIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgcHVibGljSWQgPSBpZGVudGlmaWVyLmdldFB1YmxpY0lkKCk7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIHN5c3RlbUlkID0gZlJlc29sdmVEVERVUklzID8KLSAgICAgICAgICAgICAgICAgICAgaWRlbnRpZmllci5nZXRFeHBhbmRlZFN5c3RlbUlkKCkgOiBpZGVudGlmaWVyLmdldExpdGVyYWxTeXN0ZW1JZCgpOwotICAgICAgICAgICAgICAgIGZEZWNsSGFuZGxlci5leHRlcm5hbEVudGl0eURlY2wobmFtZSwgcHVibGljSWQsIHN5c3RlbUlkKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBYTklFeGNlcHRpb24oZSk7Ci0gICAgICAgIH0KLQotICAgIH0gLy8gZXh0ZXJuYWxFbnRpdHlEZWNsKFN0cmluZywsWE1MUmVzb3VyY2VJZGVudGlmaWVyLCBBdWdtZW50YXRpb25zKQotCi0gICAgLyoqCi0gICAgICogQW4gdW5wYXJzZWQgZW50aXR5IGRlY2xhcmF0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgICAgIFRoZSBuYW1lIG9mIHRoZSBlbnRpdHkuCi0gICAgICogQHBhcmFtIGlkZW50aWZpZXIgICAgQW4gb2JqZWN0IGNvbnRhaW5pbmcgYWxsIGxvY2F0aW9uIGluZm9ybWF0aW9uCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgcGVydGluZW50IHRvIHRoaXMgZW50aXR5LgotICAgICAqIEBwYXJhbSBub3RhdGlvbiBUaGUgbmFtZSBvZiB0aGUgbm90YXRpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYXVncyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdW5wYXJzZWRFbnRpdHlEZWNsKFN0cmluZyBuYW1lLCBYTUxSZXNvdXJjZUlkZW50aWZpZXIgaWRlbnRpZmllciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG5vdGF0aW9uLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICB0cnkgewotICAgICAgICAgICAgLy8gU0FYMiBleHRlbnNpb24KLSAgICAgICAgICAgIGlmIChmRFRESGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIHB1YmxpY0lkID0gaWRlbnRpZmllci5nZXRQdWJsaWNJZCgpOwotICAgICAgICAgICAgICAgIFN0cmluZyBzeXN0ZW1JZCA9IGZSZXNvbHZlRFREVVJJcyA/Ci0gICAgICAgICAgICAgICAgICAgIGlkZW50aWZpZXIuZ2V0RXhwYW5kZWRTeXN0ZW1JZCgpIDogaWRlbnRpZmllci5nZXRMaXRlcmFsU3lzdGVtSWQoKTsKLSAgICAgICAgICAgICAgICBmRFRESGFuZGxlci51bnBhcnNlZEVudGl0eURlY2wobmFtZSwgcHVibGljSWQsIHN5c3RlbUlkLCBub3RhdGlvbik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWE5JRXhjZXB0aW9uKGUpOwotICAgICAgICB9Ci0KLSAgICB9IC8vIHVucGFyc2VkRW50aXR5RGVjbChTdHJpbmcsWE1MUmVzb3VyY2VJZGVudGlmaWVyLCBTdHJpbmcsIEF1Z21lbnRhdGlvbnMpCi0KLSAgICAvKioKLSAgICAgKiBBIG5vdGF0aW9uIGRlY2xhcmF0aW9uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSAgICAgVGhlIG5hbWUgb2YgdGhlIG5vdGF0aW9uLgotICAgICAqIEBwYXJhbSBpZGVudGlmaWVyICAgIEFuIG9iamVjdCBjb250YWluaW5nIGFsbCBsb2NhdGlvbiBpbmZvcm1hdGlvbgotICAgICAqICAgICAgICAgICAgICAgICAgICAgIHBlcnRpbmVudCB0byB0aGlzIG5vdGF0aW9uLgotICAgICAqIEBwYXJhbSBhdWdzIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBub3RhdGlvbkRlY2woU3RyaW5nIG5hbWUsIFhNTFJlc291cmNlSWRlbnRpZmllciBpZGVudGlmaWVyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICB0cnkgewotICAgICAgICAgICAgLy8gU0FYMSBhbmQgU0FYMgotICAgICAgICAgICAgaWYgKGZEVERIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgcHVibGljSWQgPSBpZGVudGlmaWVyLmdldFB1YmxpY0lkKCk7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIHN5c3RlbUlkID0gZlJlc29sdmVEVERVUklzID8KLSAgICAgICAgICAgICAgICAgICAgaWRlbnRpZmllci5nZXRFeHBhbmRlZFN5c3RlbUlkKCkgOiBpZGVudGlmaWVyLmdldExpdGVyYWxTeXN0ZW1JZCgpOwotICAgICAgICAgICAgICAgIGZEVERIYW5kbGVyLm5vdGF0aW9uRGVjbChuYW1lLCBwdWJsaWNJZCwgc3lzdGVtSWQpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChTQVhFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFhOSUV4Y2VwdGlvbihlKTsKLSAgICAgICAgfQotCi0gICAgfSAvLyBub3RhdGlvbkRlY2woU3RyaW5nLFhNTFJlc291cmNlSWRlbnRpZmllciwgQXVnbWVudGF0aW9ucykKLQotICAgIC8qKgotICAgICAqIFRoZSBlbmQgb2YgdGhlIERURC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBhdWdzIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbmREVEQoQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgZkluRFREID0gZmFsc2U7Ci0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIC8vIFNBWDIgZXh0ZW5zaW9uCi0gICAgICAgICAgICBpZiAoZkxleGljYWxIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmTGV4aWNhbEhhbmRsZXIuZW5kRFREKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWE5JRXhjZXB0aW9uKGUpOwotICAgICAgICB9Ci0gICAgICAgIGlmKGZEZWNsYXJlZEF0dHJzICE9IG51bGwpIHsKLSAgICAgICAgICAgIC8vIGhlbHAgb3V0IHRoZSBHQwotICAgICAgICAgICAgZkRlY2xhcmVkQXR0cnMuY2xlYXIoKTsKLSAgICAgICAgfQotCi0gICAgfSAvLyBlbmREVEQoKQotCi0gICAgLy8KLSAgICAvLyBQYXJzZXIgYW5kIFhNTFJlYWRlciBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFBhcnNlcyB0aGUgaW5wdXQgc291cmNlIHNwZWNpZmllZCBieSB0aGUgZ2l2ZW4gc3lzdGVtIGlkZW50aWZpZXIuCi0gICAgICogPHA+Ci0gICAgICogVGhpcyBtZXRob2QgaXMgZXF1aXZhbGVudCB0byB0aGUgZm9sbG93aW5nOgotICAgICAqIDxwcmU+Ci0gICAgICogICAgIHBhcnNlKG5ldyBJbnB1dFNvdXJjZShzeXN0ZW1JZCkpOwotICAgICAqIDwvcHJlPgotICAgICAqCi0gICAgICogQHBhcmFtIHN5c3RlbUlkIFRoZSBzeXN0ZW0gaWRlbnRpZmllciAoVVJJKS4KLSAgICAgKgotICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIFRocm93cyBleGNlcHRpb24gb24gU0FYIGVycm9yLgotICAgICAqIEBleGNlcHRpb24gamF2YS5pby5JT0V4Y2VwdGlvbiBUaHJvd3MgZXhjZXB0aW9uIG9uIGkvbyBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBwYXJzZShTdHJpbmcgc3lzdGVtSWQpIHRocm93cyBTQVhFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKLQotICAgICAgICAvLyBwYXJzZSBkb2N1bWVudAotICAgICAgICBYTUxJbnB1dFNvdXJjZSBzb3VyY2UgPSBuZXcgWE1MSW5wdXRTb3VyY2UobnVsbCwgc3lzdGVtSWQsIG51bGwpOwotICAgICAgICB0cnkgewotICAgICAgICAgICAgcGFyc2Uoc291cmNlKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIHdyYXAgWE5JIGV4Y2VwdGlvbnMgYXMgU0FYIGV4Y2VwdGlvbnMKLSAgICAgICAgY2F0Y2ggKFhNTFBhcnNlRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIEV4Y2VwdGlvbiBleCA9IGUuZ2V0RXhjZXB0aW9uKCk7Ci0gICAgICAgICAgICBpZiAoZXggPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIC8vIG11c3QgYmUgYSBwYXJzZXIgZXhjZXB0aW9uOyBtaW5lIGl0IGZvciBsb2NhdG9yIGluZm8gYW5kIHRocm93Ci0gICAgICAgICAgICAgICAgLy8gYSBTQVhQYXJzZUV4Y2VwdGlvbgotICAgICAgICAgICAgICAgIExvY2F0b3JJbXBsIGxvY2F0b3JJbXBsID0gbmV3IExvY2F0b3JJbXBsKCl7Ci0gICAgICAgICAgICAgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0WE1MVmVyc2lvbigpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmVmVyc2lvbjsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAvLyBzaW5jZSBYTUxQYXJzZUV4Y2VwdGlvbnMga25vdyBub3RoaW5nIGFib3V0IGVuY29kaW5nLAotICAgICAgICAgICAgICAgICAgICAvLyB3ZSBjYW5ub3QgcmV0dXJuIGFueXRoaW5nIG1lYW5pbmdmdWwgaW4gdGhpcyBjb250ZXh0LgotICAgICAgICAgICAgICAgICAgICAvLyBXZSAqY291bGQqIGNvbnN1bHQgdGhlIExvY2F0b3JQcm94eSwgYnV0IHRoZQotICAgICAgICAgICAgICAgICAgICAvLyBhcHBsaWNhdGlvbiBjYW4gZG8gdGhpcyBpdHNlbGYgaWYgaXQgd2lzaGVzIHRvIHBvc3NpYmx5Ci0gICAgICAgICAgICAgICAgICAgIC8vIGJlIG1pc2xlYWQuCi0gICAgICAgICAgICAgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0RW5jb2RpbmcoKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH07Ci0gICAgICAgICAgICAgICAgbG9jYXRvckltcGwuc2V0UHVibGljSWQoZS5nZXRQdWJsaWNJZCgpKTsKLSAgICAgICAgICAgICAgICBsb2NhdG9ySW1wbC5zZXRTeXN0ZW1JZChlLmdldEV4cGFuZGVkU3lzdGVtSWQoKSk7Ci0gICAgICAgICAgICAgICAgbG9jYXRvckltcGwuc2V0TGluZU51bWJlcihlLmdldExpbmVOdW1iZXIoKSk7Ci0gICAgICAgICAgICAgICAgbG9jYXRvckltcGwuc2V0Q29sdW1uTnVtYmVyKGUuZ2V0Q29sdW1uTnVtYmVyKCkpOwotICAgICAgICAgICAgICAgIHRocm93IG5ldyBTQVhQYXJzZUV4Y2VwdGlvbihlLmdldE1lc3NhZ2UoKSwgbG9jYXRvckltcGwpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKGV4IGluc3RhbmNlb2YgU0FYRXhjZXB0aW9uKSB7Ci0gICAgICAgICAgICAgICAgLy8gd2h5IGRpZCB3ZSBjcmVhdGUgYW4gWE1MUGFyc2VFeGNlcHRpb24/Ci0gICAgICAgICAgICAgICAgdGhyb3cgKFNBWEV4Y2VwdGlvbilleDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChleCBpbnN0YW5jZW9mIElPRXhjZXB0aW9uKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgKElPRXhjZXB0aW9uKWV4OwotICAgICAgICAgICAgfQotICAgICAgICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbihleCk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKFhOSUV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICBFeGNlcHRpb24gZXggPSBlLmdldEV4Y2VwdGlvbigpOwotICAgICAgICAgICAgaWYgKGV4ID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKGUuZ2V0TWVzc2FnZSgpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChleCBpbnN0YW5jZW9mIFNBWEV4Y2VwdGlvbikgewotICAgICAgICAgICAgICAgIHRocm93IChTQVhFeGNlcHRpb24pZXg7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoZXggaW5zdGFuY2VvZiBJT0V4Y2VwdGlvbikgewotICAgICAgICAgICAgICAgIHRocm93IChJT0V4Y2VwdGlvbilleDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oZXgpOwotICAgICAgICB9Ci0KLSAgICB9IC8vIHBhcnNlKFN0cmluZykKLQotICAgIC8qKgotICAgICAqIHBhcnNlCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaW5wdXRTb3VyY2UKLSAgICAgKgotICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAgICogQGV4Y2VwdGlvbiBqYXZhLmlvLklPRXhjZXB0aW9uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcGFyc2UoSW5wdXRTb3VyY2UgaW5wdXRTb3VyY2UpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKLQotICAgICAgICAvLyBwYXJzZSBkb2N1bWVudAotICAgICAgICB0cnkgewotICAgICAgICAgICAgWE1MSW5wdXRTb3VyY2UgeG1sSW5wdXRTb3VyY2UgPQotICAgICAgICAgICAgICAgIG5ldyBYTUxJbnB1dFNvdXJjZShpbnB1dFNvdXJjZS5nZXRQdWJsaWNJZCgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnB1dFNvdXJjZS5nZXRTeXN0ZW1JZCgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsKTsKLSAgICAgICAgICAgIHhtbElucHV0U291cmNlLnNldEJ5dGVTdHJlYW0oaW5wdXRTb3VyY2UuZ2V0Qnl0ZVN0cmVhbSgpKTsKLSAgICAgICAgICAgIHhtbElucHV0U291cmNlLnNldENoYXJhY3RlclN0cmVhbShpbnB1dFNvdXJjZS5nZXRDaGFyYWN0ZXJTdHJlYW0oKSk7Ci0gICAgICAgICAgICB4bWxJbnB1dFNvdXJjZS5zZXRFbmNvZGluZyhpbnB1dFNvdXJjZS5nZXRFbmNvZGluZygpKTsKLSAgICAgICAgICAgIHBhcnNlKHhtbElucHV0U291cmNlKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIHdyYXAgWE5JIGV4Y2VwdGlvbnMgYXMgU0FYIGV4Y2VwdGlvbnMKLSAgICAgICAgY2F0Y2ggKFhNTFBhcnNlRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIEV4Y2VwdGlvbiBleCA9IGUuZ2V0RXhjZXB0aW9uKCk7Ci0gICAgICAgICAgICBpZiAoZXggPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIC8vIG11c3QgYmUgYSBwYXJzZXIgZXhjZXB0aW9uOyBtaW5lIGl0IGZvciBsb2NhdG9yIGluZm8gYW5kIHRocm93Ci0gICAgICAgICAgICAgICAgLy8gYSBTQVhQYXJzZUV4Y2VwdGlvbgotICAgICAgICAgICAgICAgIExvY2F0b3JJbXBsIGxvY2F0b3JJbXBsID0gbmV3IExvY2F0b3JJbXBsKCkgewotICAgICAgICAgICAgICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFhNTFZlcnNpb24oKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZlZlcnNpb247Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgLy8gc2luY2UgWE1MUGFyc2VFeGNlcHRpb25zIGtub3cgbm90aGluZyBhYm91dCBlbmNvZGluZywKLSAgICAgICAgICAgICAgICAgICAgLy8gd2UgY2Fubm90IHJldHVybiBhbnl0aGluZyBtZWFuaW5nZnVsIGluIHRoaXMgY29udGV4dC4KLSAgICAgICAgICAgICAgICAgICAgLy8gV2UgKmNvdWxkKiBjb25zdWx0IHRoZSBMb2NhdG9yUHJveHksIGJ1dCB0aGUKLSAgICAgICAgICAgICAgICAgICAgLy8gYXBwbGljYXRpb24gY2FuIGRvIHRoaXMgaXRzZWxmIGlmIGl0IHdpc2hlcyB0byBwb3NzaWJseQotICAgICAgICAgICAgICAgICAgICAvLyBiZSBtaXNsZWFkLgotICAgICAgICAgICAgICAgICAgICBwdWJsaWMgU3RyaW5nIGdldEVuY29kaW5nKCkgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9OwotICAgICAgICAgICAgICAgIGxvY2F0b3JJbXBsLnNldFB1YmxpY0lkKGUuZ2V0UHVibGljSWQoKSk7Ci0gICAgICAgICAgICAgICAgbG9jYXRvckltcGwuc2V0U3lzdGVtSWQoZS5nZXRFeHBhbmRlZFN5c3RlbUlkKCkpOwotICAgICAgICAgICAgICAgIGxvY2F0b3JJbXBsLnNldExpbmVOdW1iZXIoZS5nZXRMaW5lTnVtYmVyKCkpOwotICAgICAgICAgICAgICAgIGxvY2F0b3JJbXBsLnNldENvbHVtbk51bWJlcihlLmdldENvbHVtbk51bWJlcigpKTsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU0FYUGFyc2VFeGNlcHRpb24oZS5nZXRNZXNzYWdlKCksIGxvY2F0b3JJbXBsKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChleCBpbnN0YW5jZW9mIFNBWEV4Y2VwdGlvbikgewotICAgICAgICAgICAgICAgIC8vIHdoeSBkaWQgd2UgY3JlYXRlIGFuIFhNTFBhcnNlRXhjZXB0aW9uPwotICAgICAgICAgICAgICAgIHRocm93IChTQVhFeGNlcHRpb24pZXg7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoZXggaW5zdGFuY2VvZiBJT0V4Y2VwdGlvbikgewotICAgICAgICAgICAgICAgIHRocm93IChJT0V4Y2VwdGlvbilleDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oZXgpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChYTklFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgRXhjZXB0aW9uIGV4ID0gZS5nZXRFeGNlcHRpb24oKTsKLSAgICAgICAgICAgIGlmIChleCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbihlLmdldE1lc3NhZ2UoKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoZXggaW5zdGFuY2VvZiBTQVhFeGNlcHRpb24pIHsKLSAgICAgICAgICAgICAgICB0aHJvdyAoU0FYRXhjZXB0aW9uKWV4OwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKGV4IGluc3RhbmNlb2YgSU9FeGNlcHRpb24pIHsKLSAgICAgICAgICAgICAgICB0aHJvdyAoSU9FeGNlcHRpb24pZXg7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKGV4KTsKLSAgICAgICAgfQotCi0gICAgfSAvLyBwYXJzZShJbnB1dFNvdXJjZSkKLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIHJlc29sdmVyIHVzZWQgdG8gcmVzb2x2ZSBleHRlcm5hbCBlbnRpdGllcy4gVGhlIEVudGl0eVJlc29sdmVyCi0gICAgICogaW50ZXJmYWNlIHN1cHBvcnRzIHJlc29sdXRpb24gb2YgcHVibGljIGFuZCBzeXN0ZW0gaWRlbnRpZmllcnMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcmVzb2x2ZXIgVGhlIG5ldyBlbnRpdHkgcmVzb2x2ZXIuIFBhc3NpbmcgYSBudWxsIHZhbHVlIHdpbGwKLSAgICAgKiAgICAgICAgICAgICAgICAgdW5pbnN0YWxsIHRoZSBjdXJyZW50bHkgaW5zdGFsbGVkIHJlc29sdmVyLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEVudGl0eVJlc29sdmVyKEVudGl0eVJlc29sdmVyIHJlc29sdmVyKSB7Ci0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIFhNTEVudGl0eVJlc29sdmVyIHhlciA9IChYTUxFbnRpdHlSZXNvbHZlcikgZkNvbmZpZ3VyYXRpb24uZ2V0UHJvcGVydHkoRU5USVRZX1JFU09MVkVSKTsKLSAgICAgICAgICAgIGlmIChmVXNlRW50aXR5UmVzb2x2ZXIyICYmIHJlc29sdmVyIGluc3RhbmNlb2YgRW50aXR5UmVzb2x2ZXIyKSB7Ci0gICAgICAgICAgICAgICAgaWYgKHhlciBpbnN0YW5jZW9mIEVudGl0eVJlc29sdmVyMldyYXBwZXIpIHsKLSAgICAgICAgICAgICAgICAgICAgRW50aXR5UmVzb2x2ZXIyV3JhcHBlciBlcjJ3ID0gKEVudGl0eVJlc29sdmVyMldyYXBwZXIpIHhlcjsKLSAgICAgICAgICAgICAgICAgICAgZXIydy5zZXRFbnRpdHlSZXNvbHZlcigoRW50aXR5UmVzb2x2ZXIyKSByZXNvbHZlcik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICBmQ29uZmlndXJhdGlvbi5zZXRQcm9wZXJ0eShFTlRJVFlfUkVTT0xWRVIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IEVudGl0eVJlc29sdmVyMldyYXBwZXIoKEVudGl0eVJlc29sdmVyMikgcmVzb2x2ZXIpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBpZiAoeGVyIGluc3RhbmNlb2YgRW50aXR5UmVzb2x2ZXJXcmFwcGVyKSB7Ci0gICAgICAgICAgICAgICAgICAgIEVudGl0eVJlc29sdmVyV3JhcHBlciBlcncgPSAoRW50aXR5UmVzb2x2ZXJXcmFwcGVyKSB4ZXI7Ci0gICAgICAgICAgICAgICAgICAgIGVydy5zZXRFbnRpdHlSZXNvbHZlcihyZXNvbHZlcik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICBmQ29uZmlndXJhdGlvbi5zZXRQcm9wZXJ0eShFTlRJVFlfUkVTT0xWRVIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IEVudGl0eVJlc29sdmVyV3JhcHBlcihyZXNvbHZlcikpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAvLyBkbyBub3RoaW5nCi0gICAgICAgIH0KLQotICAgIH0gLy8gc2V0RW50aXR5UmVzb2x2ZXIoRW50aXR5UmVzb2x2ZXIpCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIGN1cnJlbnQgZW50aXR5IHJlc29sdmVyLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgY3VycmVudCBlbnRpdHkgcmVzb2x2ZXIsIG9yIG51bGwgaWYgbm9uZQotICAgICAqICAgICAgICAgaGFzIGJlZW4gcmVnaXN0ZXJlZC4KLSAgICAgKiBAc2VlICNzZXRFbnRpdHlSZXNvbHZlcgotICAgICAqLwotICAgIHB1YmxpYyBFbnRpdHlSZXNvbHZlciBnZXRFbnRpdHlSZXNvbHZlcigpIHsKLQotICAgICAgICBFbnRpdHlSZXNvbHZlciBlbnRpdHlSZXNvbHZlciA9IG51bGw7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBYTUxFbnRpdHlSZXNvbHZlciB4bWxFbnRpdHlSZXNvbHZlciA9Ci0gICAgICAgICAgICAgICAgKFhNTEVudGl0eVJlc29sdmVyKWZDb25maWd1cmF0aW9uLmdldFByb3BlcnR5KEVOVElUWV9SRVNPTFZFUik7Ci0gICAgICAgICAgICBpZiAoeG1sRW50aXR5UmVzb2x2ZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGlmICh4bWxFbnRpdHlSZXNvbHZlciBpbnN0YW5jZW9mIEVudGl0eVJlc29sdmVyV3JhcHBlcikgewotICAgICAgICAgICAgICAgICAgICBlbnRpdHlSZXNvbHZlciA9Ci0gICAgICAgICAgICAgICAgICAgICAgICAoKEVudGl0eVJlc29sdmVyV3JhcHBlcikgeG1sRW50aXR5UmVzb2x2ZXIpLmdldEVudGl0eVJlc29sdmVyKCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgaWYgKHhtbEVudGl0eVJlc29sdmVyIGluc3RhbmNlb2YgRW50aXR5UmVzb2x2ZXIyV3JhcHBlcikgewotICAgICAgICAgICAgICAgICAgICBlbnRpdHlSZXNvbHZlciA9Ci0gICAgICAgICAgICAgICAgICAgICAgICAoKEVudGl0eVJlc29sdmVyMldyYXBwZXIpIHhtbEVudGl0eVJlc29sdmVyKS5nZXRFbnRpdHlSZXNvbHZlcigpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAvLyBkbyBub3RoaW5nCi0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGVudGl0eVJlc29sdmVyOwotCi0gICAgfSAvLyBnZXRFbnRpdHlSZXNvbHZlcigpOkVudGl0eVJlc29sdmVyCi0KLSAgICAvKioKLSAgICAgKiBBbGxvdyBhbiBhcHBsaWNhdGlvbiB0byByZWdpc3RlciBhbiBlcnJvciBldmVudCBoYW5kbGVyLgotICAgICAqCi0gICAgICogPHA+SWYgdGhlIGFwcGxpY2F0aW9uIGRvZXMgbm90IHJlZ2lzdGVyIGFuIGVycm9yIGhhbmRsZXIsIGFsbAotICAgICAqIGVycm9yIGV2ZW50cyByZXBvcnRlZCBieSB0aGUgU0FYIHBhcnNlciB3aWxsIGJlIHNpbGVudGx5Ci0gICAgICogaWdub3JlZDsgaG93ZXZlciwgbm9ybWFsIHByb2Nlc3NpbmcgbWF5IG5vdCBjb250aW51ZS4gIEl0IGlzCi0gICAgICogaGlnaGx5IHJlY29tbWVuZGVkIHRoYXQgYWxsIFNBWCBhcHBsaWNhdGlvbnMgaW1wbGVtZW50IGFuCi0gICAgICogZXJyb3IgaGFuZGxlciB0byBhdm9pZCB1bmV4cGVjdGVkIGJ1Z3MuPC9wPgotICAgICAqCi0gICAgICogPHA+QXBwbGljYXRpb25zIG1heSByZWdpc3RlciBhIG5ldyBvciBkaWZmZXJlbnQgaGFuZGxlciBpbiB0aGUKLSAgICAgKiBtaWRkbGUgb2YgYSBwYXJzZSwgYW5kIHRoZSBTQVggcGFyc2VyIG11c3QgYmVnaW4gdXNpbmcgdGhlIG5ldwotICAgICAqIGhhbmRsZXIgaW1tZWRpYXRlbHkuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGVycm9ySGFuZGxlciBUaGUgZXJyb3IgaGFuZGxlci4KLSAgICAgKiBAc2VlICNnZXRFcnJvckhhbmRsZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRFcnJvckhhbmRsZXIoRXJyb3JIYW5kbGVyIGVycm9ySGFuZGxlcikgewotCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBYTUxFcnJvckhhbmRsZXIgeGVoID0gKFhNTEVycm9ySGFuZGxlcikgZkNvbmZpZ3VyYXRpb24uZ2V0UHJvcGVydHkoRVJST1JfSEFORExFUik7Ci0gICAgICAgICAgICBpZiAoeGVoIGluc3RhbmNlb2YgRXJyb3JIYW5kbGVyV3JhcHBlcikgewotICAgICAgICAgICAgICAgIEVycm9ySGFuZGxlcldyYXBwZXIgZWh3ID0gKEVycm9ySGFuZGxlcldyYXBwZXIpIHhlaDsKLSAgICAgICAgICAgICAgICBlaHcuc2V0RXJyb3JIYW5kbGVyKGVycm9ySGFuZGxlcik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBmQ29uZmlndXJhdGlvbi5zZXRQcm9wZXJ0eShFUlJPUl9IQU5ETEVSLAotICAgICAgICAgICAgICAgICAgICAgICAgbmV3IEVycm9ySGFuZGxlcldyYXBwZXIoZXJyb3JIYW5kbGVyKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gZSkgewotICAgICAgICAgICAgLy8gZG8gbm90aGluZwotICAgICAgICB9Ci0KLSAgICB9IC8vIHNldEVycm9ySGFuZGxlcihFcnJvckhhbmRsZXIpCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIGN1cnJlbnQgZXJyb3IgaGFuZGxlci4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIGN1cnJlbnQgZXJyb3IgaGFuZGxlciwgb3IgbnVsbCBpZiBub25lCi0gICAgICogICAgICAgICBoYXMgYmVlbiByZWdpc3RlcmVkLgotICAgICAqIEBzZWUgI3NldEVycm9ySGFuZGxlcgotICAgICAqLwotICAgIHB1YmxpYyBFcnJvckhhbmRsZXIgZ2V0RXJyb3JIYW5kbGVyKCkgewotCi0gICAgICAgIEVycm9ySGFuZGxlciBlcnJvckhhbmRsZXIgPSBudWxsOwotICAgICAgICB0cnkgewotICAgICAgICAgICAgWE1MRXJyb3JIYW5kbGVyIHhtbEVycm9ySGFuZGxlciA9Ci0gICAgICAgICAgICAgICAgKFhNTEVycm9ySGFuZGxlcilmQ29uZmlndXJhdGlvbi5nZXRQcm9wZXJ0eShFUlJPUl9IQU5ETEVSKTsKLSAgICAgICAgICAgIGlmICh4bWxFcnJvckhhbmRsZXIgIT0gbnVsbCAmJgotICAgICAgICAgICAgICAgIHhtbEVycm9ySGFuZGxlciBpbnN0YW5jZW9mIEVycm9ySGFuZGxlcldyYXBwZXIpIHsKLSAgICAgICAgICAgICAgICBlcnJvckhhbmRsZXIgPSAoKEVycm9ySGFuZGxlcldyYXBwZXIpeG1sRXJyb3JIYW5kbGVyKS5nZXRFcnJvckhhbmRsZXIoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAvLyBkbyBub3RoaW5nCi0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGVycm9ySGFuZGxlcjsKLQotICAgIH0gLy8gZ2V0RXJyb3JIYW5kbGVyKCk6RXJyb3JIYW5kbGVyCi0KLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIGxvY2FsZSB0byB1c2UgZm9yIG1lc3NhZ2VzLgotICAgICAqCi0gICAgICogQHBhcmFtIGxvY2FsZSBUaGUgbG9jYWxlIG9iamVjdCB0byB1c2UgZm9yIGxvY2FsaXphdGlvbiBvZiBtZXNzYWdlcy4KLSAgICAgKgotICAgICAqIEBleGNlcHRpb24gU0FYRXhjZXB0aW9uIEFuIGV4Y2VwdGlvbiB0aHJvd24gaWYgdGhlIHBhcnNlciBkb2VzIG5vdAotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIHN1cHBvcnQgdGhlIHNwZWNpZmllZCBsb2NhbGUuCi0gICAgICoKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LlBhcnNlcgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldExvY2FsZShMb2NhbGUgbG9jYWxlKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICAgICAgLy9SRVZJU0lUOnRoaXMgbWV0aG9kcyBpcyBub3QgcGFydCBvZiBTQVgyIGludGVyZmFjZXMsIHdlIHNob3VsZCB0aHJvdyBleGNlcHRpb24KLSAgICAgICAgLy9pZiBhbnkgYXBwbGljYXRpb24gdXNlcyBTQVgyIGFuZCBzZXRzIGxvY2FsZSBhbHNvLiAtbmIKLSAgICAgICAgZkNvbmZpZ3VyYXRpb24uc2V0TG9jYWxlKGxvY2FsZSk7Ci0KLSAgICB9IC8vIHNldExvY2FsZShMb2NhbGUpCi0KLSAgICAvKioKLSAgICAgKiBBbGxvdyBhbiBhcHBsaWNhdGlvbiB0byByZWdpc3RlciBhIERURCBldmVudCBoYW5kbGVyLgotICAgICAqIDxwPgotICAgICAqIElmIHRoZSBhcHBsaWNhdGlvbiBkb2VzIG5vdCByZWdpc3RlciBhIERURCBoYW5kbGVyLCBhbGwgRFRECi0gICAgICogZXZlbnRzIHJlcG9ydGVkIGJ5IHRoZSBTQVggcGFyc2VyIHdpbGwgYmUgc2lsZW50bHkgaWdub3JlZC4KLSAgICAgKiA8cD4KLSAgICAgKiBBcHBsaWNhdGlvbnMgbWF5IHJlZ2lzdGVyIGEgbmV3IG9yIGRpZmZlcmVudCBoYW5kbGVyIGluIHRoZQotICAgICAqIG1pZGRsZSBvZiBhIHBhcnNlLCBhbmQgdGhlIFNBWCBwYXJzZXIgbXVzdCBiZWdpbiB1c2luZyB0aGUgbmV3Ci0gICAgICogaGFuZGxlciBpbW1lZGlhdGVseS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBkdGRIYW5kbGVyIFRoZSBEVEQgaGFuZGxlci4KLSAgICAgKgotCi0gICAgICogQHNlZSAjZ2V0RFRESGFuZGxlcgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldERUREhhbmRsZXIoRFRESGFuZGxlciBkdGRIYW5kbGVyKSB7Ci0gICAgICAgIGZEVERIYW5kbGVyID0gZHRkSGFuZGxlcjsKLSAgICB9IC8vIHNldERUREhhbmRsZXIoRFRESGFuZGxlcikKLQotICAgIC8vCi0gICAgLy8gUGFyc2VyIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogQWxsb3cgYW4gYXBwbGljYXRpb24gdG8gcmVnaXN0ZXIgYSBkb2N1bWVudCBldmVudCBoYW5kbGVyLgotICAgICAqIDxwPgotICAgICAqIElmIHRoZSBhcHBsaWNhdGlvbiBkb2VzIG5vdCByZWdpc3RlciBhIGRvY3VtZW50IGhhbmRsZXIsIGFsbAotICAgICAqIGRvY3VtZW50IGV2ZW50cyByZXBvcnRlZCBieSB0aGUgU0FYIHBhcnNlciB3aWxsIGJlIHNpbGVudGx5Ci0gICAgICogaWdub3JlZCAodGhpcyBpcyB0aGUgZGVmYXVsdCBiZWhhdmlvdXIgaW1wbGVtZW50ZWQgYnkKLSAgICAgKiBIYW5kbGVyQmFzZSkuCi0gICAgICogPHA+Ci0gICAgICogQXBwbGljYXRpb25zIG1heSByZWdpc3RlciBhIG5ldyBvciBkaWZmZXJlbnQgaGFuZGxlciBpbiB0aGUKLSAgICAgKiBtaWRkbGUgb2YgYSBwYXJzZSwgYW5kIHRoZSBTQVggcGFyc2VyIG11c3QgYmVnaW4gdXNpbmcgdGhlIG5ldwotICAgICAqIGhhbmRsZXIgaW1tZWRpYXRlbHkuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZG9jdW1lbnRIYW5kbGVyIFRoZSBkb2N1bWVudCBoYW5kbGVyLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldERvY3VtZW50SGFuZGxlcihEb2N1bWVudEhhbmRsZXIgZG9jdW1lbnRIYW5kbGVyKSB7Ci0gICAgICAgIGZEb2N1bWVudEhhbmRsZXIgPSBkb2N1bWVudEhhbmRsZXI7Ci0gICAgfSAvLyBzZXREb2N1bWVudEhhbmRsZXIoRG9jdW1lbnRIYW5kbGVyKQotCi0gICAgLy8KLSAgICAvLyBYTUxSZWFkZXIgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBBbGxvdyBhbiBhcHBsaWNhdGlvbiB0byByZWdpc3RlciBhIGNvbnRlbnQgZXZlbnQgaGFuZGxlci4KLSAgICAgKiA8cD4KLSAgICAgKiBJZiB0aGUgYXBwbGljYXRpb24gZG9lcyBub3QgcmVnaXN0ZXIgYSBjb250ZW50IGhhbmRsZXIsIGFsbAotICAgICAqIGNvbnRlbnQgZXZlbnRzIHJlcG9ydGVkIGJ5IHRoZSBTQVggcGFyc2VyIHdpbGwgYmUgc2lsZW50bHkKLSAgICAgKiBpZ25vcmVkLgotICAgICAqIDxwPgotICAgICAqIEFwcGxpY2F0aW9ucyBtYXkgcmVnaXN0ZXIgYSBuZXcgb3IgZGlmZmVyZW50IGhhbmRsZXIgaW4gdGhlCi0gICAgICogbWlkZGxlIG9mIGEgcGFyc2UsIGFuZCB0aGUgU0FYIHBhcnNlciBtdXN0IGJlZ2luIHVzaW5nIHRoZSBuZXcKLSAgICAgKiBoYW5kbGVyIGltbWVkaWF0ZWx5LgotICAgICAqCi0gICAgICogQHBhcmFtIGNvbnRlbnRIYW5kbGVyIFRoZSBjb250ZW50IGhhbmRsZXIuCi0gICAgICoKLSAgICAgKiBAc2VlICNnZXRDb250ZW50SGFuZGxlcgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldENvbnRlbnRIYW5kbGVyKENvbnRlbnRIYW5kbGVyIGNvbnRlbnRIYW5kbGVyKSB7Ci0gICAgICAgIGZDb250ZW50SGFuZGxlciA9IGNvbnRlbnRIYW5kbGVyOwotICAgIH0gLy8gc2V0Q29udGVudEhhbmRsZXIoQ29udGVudEhhbmRsZXIpCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIGN1cnJlbnQgY29udGVudCBoYW5kbGVyLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgY3VycmVudCBjb250ZW50IGhhbmRsZXIsIG9yIG51bGwgaWYgbm9uZQotICAgICAqICAgICAgICAgaGFzIGJlZW4gcmVnaXN0ZXJlZC4KLSAgICAgKgotICAgICAqIEBzZWUgI3NldENvbnRlbnRIYW5kbGVyCi0gICAgICovCi0gICAgcHVibGljIENvbnRlbnRIYW5kbGVyIGdldENvbnRlbnRIYW5kbGVyKCkgewotICAgICAgICByZXR1cm4gZkNvbnRlbnRIYW5kbGVyOwotICAgIH0gLy8gZ2V0Q29udGVudEhhbmRsZXIoKTpDb250ZW50SGFuZGxlcgotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSBjdXJyZW50IERURCBoYW5kbGVyLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgY3VycmVudCBEVEQgaGFuZGxlciwgb3IgbnVsbCBpZiBub25lCi0gICAgICogICAgICAgICBoYXMgYmVlbiByZWdpc3RlcmVkLgotICAgICAqIEBzZWUgI3NldERUREhhbmRsZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgRFRESGFuZGxlciBnZXREVERIYW5kbGVyKCkgewotICAgICAgICByZXR1cm4gZkRUREhhbmRsZXI7Ci0gICAgfSAvLyBnZXREVERIYW5kbGVyKCk6RFRESGFuZGxlcgotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSBzdGF0ZSBvZiBhbnkgZmVhdHVyZSBpbiBhIFNBWDIgcGFyc2VyLiAgVGhlIHBhcnNlcgotICAgICAqIG1pZ2h0IG5vdCByZWNvZ25pemUgdGhlIGZlYXR1cmUsIGFuZCBpZiBpdCBkb2VzIHJlY29nbml6ZQotICAgICAqIGl0LCBpdCBtaWdodCBub3QgYmUgYWJsZSB0byBmdWxmaWxsIHRoZSByZXF1ZXN0LgotICAgICAqCi0gICAgICogQHBhcmFtIGZlYXR1cmVJZCBUaGUgdW5pcXVlIGlkZW50aWZpZXIgKFVSSSkgb2YgdGhlIGZlYXR1cmUuCi0gICAgICogQHBhcmFtIHN0YXRlIFRoZSByZXF1ZXN0ZWQgc3RhdGUgb2YgdGhlIGZlYXR1cmUgKHRydWUgb3IgZmFsc2UpLgotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIElmIHRoZQotICAgICAqICAgICAgICAgICAgcmVxdWVzdGVkIGZlYXR1cmUgaXMgbm90IGtub3duLgotICAgICAqIEBleGNlcHRpb24gU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIElmIHRoZQotICAgICAqICAgICAgICAgICAgcmVxdWVzdGVkIGZlYXR1cmUgaXMga25vd24sIGJ1dCB0aGUgcmVxdWVzdGVkCi0gICAgICogICAgICAgICAgICBzdGF0ZSBpcyBub3Qgc3VwcG9ydGVkLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEZlYXR1cmUoU3RyaW5nIGZlYXR1cmVJZCwgYm9vbGVhbiBzdGF0ZSkKLSAgICAgICAgdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAvLyBTQVgyIEZlYXR1cmVzCi0gICAgICAgICAgICAvLwotCi0gICAgICAgICAgICBpZiAoZmVhdHVyZUlkLnN0YXJ0c1dpdGgoQ29uc3RhbnRzLlNBWF9GRUFUVVJFX1BSRUZJWCkpIHsKLSAgICAgICAgICAgICAgICBmaW5hbCBpbnQgc3VmZml4TGVuZ3RoID0gZmVhdHVyZUlkLmxlbmd0aCgpIC0gQ29uc3RhbnRzLlNBWF9GRUFUVVJFX1BSRUZJWC5sZW5ndGgoKTsKLQotICAgICAgICAgICAgICAgIC8vIGh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy9uYW1lc3BhY2VzCi0gICAgICAgICAgICAgICAgaWYgKHN1ZmZpeExlbmd0aCA9PSBDb25zdGFudHMuTkFNRVNQQUNFU19GRUFUVVJFLmxlbmd0aCgpICYmCi0gICAgICAgICAgICAgICAgICAgIGZlYXR1cmVJZC5lbmRzV2l0aChDb25zdGFudHMuTkFNRVNQQUNFU19GRUFUVVJFKSkgewotICAgICAgICAgICAgICAgICAgICBmQ29uZmlndXJhdGlvbi5zZXRGZWF0dXJlKGZlYXR1cmVJZCwgc3RhdGUpOwotICAgICAgICAgICAgICAgICAgICBmTmFtZXNwYWNlcyA9IHN0YXRlOwotICAgICAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgLy8gaHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL25hbWVzcGFjZS1wcmVmaXhlcwotICAgICAgICAgICAgICAgIC8vICAgY29udHJvbHMgdGhlIHJlcG9ydGluZyBvZiByYXcgcHJlZml4ZWQgbmFtZXMgYW5kIE5hbWVzcGFjZQotICAgICAgICAgICAgICAgIC8vICAgZGVjbGFyYXRpb25zICh4bWxucyogYXR0cmlidXRlcyk6IHdoZW4gdGhpcyBmZWF0dXJlIGlzIGZhbHNlCi0gICAgICAgICAgICAgICAgLy8gICAodGhlIGRlZmF1bHQpLCByYXcgcHJlZml4ZWQgbmFtZXMgbWF5IG9wdGlvbmFsbHkgYmUgcmVwb3J0ZWQsCi0gICAgICAgICAgICAgICAgLy8gICBhbmQgeG1sbnMqIGF0dHJpYnV0ZXMgbXVzdCBub3QgYmUgcmVwb3J0ZWQuCi0gICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICBpZiAoc3VmZml4TGVuZ3RoID09IENvbnN0YW50cy5OQU1FU1BBQ0VfUFJFRklYRVNfRkVBVFVSRS5sZW5ndGgoKSAmJgotICAgICAgICAgICAgICAgICAgICBmZWF0dXJlSWQuZW5kc1dpdGgoQ29uc3RhbnRzLk5BTUVTUEFDRV9QUkVGSVhFU19GRUFUVVJFKSkgewotICAgICAgICAgICAgICAgICAgICBmQ29uZmlndXJhdGlvbi5zZXRGZWF0dXJlKGZlYXR1cmVJZCwgc3RhdGUpOwotICAgICAgICAgICAgICAgICAgICBmTmFtZXNwYWNlUHJlZml4ZXMgPSBzdGF0ZTsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8vIGh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy9zdHJpbmctaW50ZXJuaW5nCi0gICAgICAgICAgICAgICAgLy8gICBjb250cm9scyB0aGUgdXNlIG9mIGphdmEubGFuZy5TdHJpbmcjaW50ZXJuKCkgZm9yIHN0cmluZ3MKLSAgICAgICAgICAgICAgICAvLyAgIHBhc3NlZCB0byBTQVggaGFuZGxlcnMuCi0gICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICBpZiAoc3VmZml4TGVuZ3RoID09IENvbnN0YW50cy5TVFJJTkdfSU5URVJOSU5HX0ZFQVRVUkUubGVuZ3RoKCkgJiYKLSAgICAgICAgICAgICAgICAgICAgZmVhdHVyZUlkLmVuZHNXaXRoKENvbnN0YW50cy5TVFJJTkdfSU5URVJOSU5HX0ZFQVRVUkUpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmICghc3RhdGUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgU0FYTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKGZDb25maWd1cmF0aW9uLmdldExvY2FsZSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICJmYWxzZS1ub3Qtc3VwcG9ydGVkIiwgbmV3IE9iamVjdCBbXSB7ZmVhdHVyZUlkfSkpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyBodHRwOi8veG1sLm9yZy9zYXgvZmVhdHVyZXMvbGV4aWNhbC1oYW5kbGVyL3BhcmFtZXRlci1lbnRpdGllcwotICAgICAgICAgICAgICAgIC8vICAgY29udHJvbHMgd2hldGhlciB0aGUgYmVnaW5uaW5nIGFuZCBlbmQgb2YgcGFyYW1ldGVyIGVudGl0aWVzCi0gICAgICAgICAgICAgICAgLy8gICB3aWxsIGJlIHJlcG9ydGVkIHRvIHRoZSBMZXhpY2FsSGFuZGxlci4KLSAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgIGlmIChzdWZmaXhMZW5ndGggPT0gQ29uc3RhbnRzLkxFWElDQUxfSEFORExFUl9QQVJBTUVURVJfRU5USVRJRVNfRkVBVFVSRS5sZW5ndGgoKSAmJgotICAgICAgICAgICAgICAgICAgICBmZWF0dXJlSWQuZW5kc1dpdGgoQ29uc3RhbnRzLkxFWElDQUxfSEFORExFUl9QQVJBTUVURVJfRU5USVRJRVNfRkVBVFVSRSkpIHsKLSAgICAgICAgICAgICAgICAgICAgZkxleGljYWxIYW5kbGVyUGFyYW1ldGVyRW50aXRpZXMgPSBzdGF0ZTsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8vIGh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy9yZXNvbHZlLWR0ZC11cmlzCi0gICAgICAgICAgICAgICAgLy8gICBjb250cm9scyB3aGV0aGVyIHN5c3RlbSBpZGVudGlmaWVycyB3aWxsIGJlIGFic29sdXRpemVkIHJlbGF0aXZlIHRvCi0gICAgICAgICAgICAgICAgLy8gICB0aGVpciBiYXNlIFVSSXMgYmVmb3JlIHJlcG9ydGluZy4KLSAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgIGlmIChzdWZmaXhMZW5ndGggPT0gQ29uc3RhbnRzLlJFU09MVkVfRFREX1VSSVNfRkVBVFVSRS5sZW5ndGgoKSAmJgotICAgICAgICAgICAgICAgICAgICBmZWF0dXJlSWQuZW5kc1dpdGgoQ29uc3RhbnRzLlJFU09MVkVfRFREX1VSSVNfRkVBVFVSRSkpIHsKLSAgICAgICAgICAgICAgICAgICAgZlJlc29sdmVEVERVUklzID0gc3RhdGU7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyBodHRwOi8veG1sLm9yZy9zYXgvZmVhdHVyZXMvdW5pY29kZS1ub3JtYWxpemF0aW9uLWNoZWNraW5nCi0gICAgICAgICAgICAgICAgLy8gICBjb250cm9scyB3aGV0aGVyIFVuaWNvZGUgbm9ybWFsaXphdGlvbiBjaGVja2luZyBpcyBwZXJmb3JtZWQKLSAgICAgICAgICAgICAgICAvLyAgIGFzIHBlciBBcHBlbmRpeCBCIG9mIHRoZSBYTUwgMS4xIHNwZWNpZmljYXRpb24KLSAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgIGlmIChzdWZmaXhMZW5ndGggPT0gQ29uc3RhbnRzLlVOSUNPREVfTk9STUFMSVpBVElPTl9DSEVDS0lOR19GRUFUVVJFLmxlbmd0aCgpICYmCi0gICAgICAgICAgICAgICAgICAgIGZlYXR1cmVJZC5lbmRzV2l0aChDb25zdGFudHMuVU5JQ09ERV9OT1JNQUxJWkFUSU9OX0NIRUNLSU5HX0ZFQVRVUkUpKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIFJFVklTSVQ6IEFsbG93IHRoaXMgZmVhdHVyZSB0byBiZSBzZXQgb25jZSBVbmljb2RlIG5vcm1hbGl6YXRpb24KLSAgICAgICAgICAgICAgICAgICAgLy8gY2hlY2tpbmcgaXMgc3VwcG9ydGVkIC0tIG1yZ2xhdmFzLgotICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdGUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgU0FYTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKGZDb25maWd1cmF0aW9uLmdldExvY2FsZSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0cnVlLW5vdC1zdXBwb3J0ZWQiLCBuZXcgT2JqZWN0IFtdIHtmZWF0dXJlSWR9KSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8vIGh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy94bWxucy11cmlzCi0gICAgICAgICAgICAgICAgLy8gICBjb250cm9scyB3aGV0aGVyIHRoZSBwYXJzZXIgcmVwb3J0cyB0aGF0IG5hbWVzcGFjZSBkZWNsYXJhdGlvbgotICAgICAgICAgICAgICAgIC8vICAgYXR0cmlidXRlcyBhcyBiZWluZyBpbiB0aGUgbmFtZXNwYWNlOiBodHRwOi8vd3d3LnczLm9yZy8yMDAwL3htbG5zLwotICAgICAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAgICAgaWYgKHN1ZmZpeExlbmd0aCA9PSBDb25zdGFudHMuWE1MTlNfVVJJU19GRUFUVVJFLmxlbmd0aCgpICYmCi0gICAgICAgICAgICAgICAgICAgIGZlYXR1cmVJZC5lbmRzV2l0aChDb25zdGFudHMuWE1MTlNfVVJJU19GRUFUVVJFKSkgewotICAgICAgICAgICAgICAgICAgICBmWE1MTlNVUklzID0gc3RhdGU7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyBodHRwOi8veG1sLm9yZy9zYXgvZmVhdHVyZXMvdXNlLWVudGl0eS1yZXNvbHZlcjIKLSAgICAgICAgICAgICAgICAvLyAgIGNvbnRyb2xzIHdoZXRoZXIgdGhlIG1ldGhvZHMgb2YgYW4gb2JqZWN0IGltcGxlbWVudGluZwotICAgICAgICAgICAgICAgIC8vICAgb3JnLnhtbC5zYXguZXh0LkVudGl0eVJlc29sdmVyMiB3aWxsIGJlIHVzZWQgYnkgdGhlIHBhcnNlci4KLSAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgIGlmIChzdWZmaXhMZW5ndGggPT0gQ29uc3RhbnRzLlVTRV9FTlRJVFlfUkVTT0xWRVIyX0ZFQVRVUkUubGVuZ3RoKCkgJiYKLSAgICAgICAgICAgICAgICAgICAgZmVhdHVyZUlkLmVuZHNXaXRoKENvbnN0YW50cy5VU0VfRU5USVRZX1JFU09MVkVSMl9GRUFUVVJFKSkgewotICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdGUgIT0gZlVzZUVudGl0eVJlc29sdmVyMikgewotICAgICAgICAgICAgICAgICAgICAgICAgZlVzZUVudGl0eVJlc29sdmVyMiA9IHN0YXRlOwotICAgICAgICAgICAgICAgICAgICAgICAgLy8gUmVmcmVzaCBFbnRpdHlSZXNvbHZlciB3cmFwcGVyLgotICAgICAgICAgICAgICAgICAgICAgICAgc2V0RW50aXR5UmVzb2x2ZXIoZ2V0RW50aXR5UmVzb2x2ZXIoKSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAgICAgLy8gUmVhZCBvbmx5IGZlYXR1cmVzLgotICAgICAgICAgICAgICAgIC8vCi0KLSAgICAgICAgICAgICAgICAvLyBodHRwOi8veG1sLm9yZy9zYXgvZmVhdHVyZXMvaXMtc3RhbmRhbG9uZQotICAgICAgICAgICAgICAgIC8vICAgcmVwb3J0cyB3aGV0aGVyIHRoZSBkb2N1bWVudCBzcGVjaWZpZWQgYSBzdGFuZGFsb25lIGRvY3VtZW50IGRlY2xhcmF0aW9uLgotICAgICAgICAgICAgICAgIC8vIGh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy91c2UtYXR0cmlidXRlczIKLSAgICAgICAgICAgICAgICAvLyAgIHJlcG9ydHMgd2hldGhlciBBdHRyaWJ1dGVzIG9iamVjdHMgcGFzc2VkIHRvIHN0YXJ0RWxlbWVudCBhbHNvIGltcGxlbWVudAotICAgICAgICAgICAgICAgIC8vICAgdGhlIG9yZy54bWwuc2F4LmV4dC5BdHRyaWJ1dGVzMiBpbnRlcmZhY2UuCi0gICAgICAgICAgICAgICAgLy8gaHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL3VzZS1sb2NhdG9yMgotICAgICAgICAgICAgICAgIC8vICAgcmVwb3J0cyB3aGV0aGVyIExvY2F0b3Igb2JqZWN0cyBwYXNzZWQgdG8gc2V0RG9jdW1lbnRMb2NhdG9yIGFsc28gaW1wbGVtZW50Ci0gICAgICAgICAgICAgICAgLy8gICB0aGUgb3JnLnhtbC5zYXguZXh0LkxvY2F0b3IyIGludGVyZmFjZS4KLSAgICAgICAgICAgICAgICAvLyBodHRwOi8veG1sLm9yZy9zYXgvZmVhdHVyZXMveG1sLTEuMQotICAgICAgICAgICAgICAgIC8vICAgcmVwb3J0cyB3aGV0aGVyIHRoZSBwYXJzZXIgc3VwcG9ydHMgYm90aCBYTUwgMS4xIGFuZCBYTUwgMS4wLgotICAgICAgICAgICAgICAgIGlmICgoc3VmZml4TGVuZ3RoID09IENvbnN0YW50cy5JU19TVEFOREFMT05FX0ZFQVRVUkUubGVuZ3RoKCkgJiYKLSAgICAgICAgICAgICAgICAgICAgZmVhdHVyZUlkLmVuZHNXaXRoKENvbnN0YW50cy5JU19TVEFOREFMT05FX0ZFQVRVUkUpKSB8fAotICAgICAgICAgICAgICAgICAgICAoc3VmZml4TGVuZ3RoID09IENvbnN0YW50cy5VU0VfQVRUUklCVVRFUzJfRkVBVFVSRS5sZW5ndGgoKSAmJgotICAgICAgICAgICAgICAgICAgICBmZWF0dXJlSWQuZW5kc1dpdGgoQ29uc3RhbnRzLlVTRV9BVFRSSUJVVEVTMl9GRUFUVVJFKSkgfHwKLSAgICAgICAgICAgICAgICAgICAgKHN1ZmZpeExlbmd0aCA9PSBDb25zdGFudHMuVVNFX0xPQ0FUT1IyX0ZFQVRVUkUubGVuZ3RoKCkgJiYKLSAgICAgICAgICAgICAgICAgICAgZmVhdHVyZUlkLmVuZHNXaXRoKENvbnN0YW50cy5VU0VfTE9DQVRPUjJfRkVBVFVSRSkpIHx8Ci0gICAgICAgICAgICAgICAgICAgIChzdWZmaXhMZW5ndGggPT0gQ29uc3RhbnRzLlhNTF8xMV9GRUFUVVJFLmxlbmd0aCgpICYmCi0gICAgICAgICAgICAgICAgICAgIGZlYXR1cmVJZC5lbmRzV2l0aChDb25zdGFudHMuWE1MXzExX0ZFQVRVUkUpKSkgewotICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICAgICAgU0FYTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKGZDb25maWd1cmF0aW9uLmdldExvY2FsZSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgImZlYXR1cmUtcmVhZC1vbmx5IiwgbmV3IE9iamVjdCBbXSB7ZmVhdHVyZUlkfSkpOwotICAgICAgICAgICAgICAgIH0KLQotCi0gICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICAvLyBEcm9wIHRocm91Z2ggYW5kIHBlcmZvcm0gZGVmYXVsdCBwcm9jZXNzaW5nCi0gICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKGZlYXR1cmVJZC5lcXVhbHMoWE1MQ29uc3RhbnRzLkZFQVRVUkVfU0VDVVJFX1BST0NFU1NJTkcpKSB7Ci0gICAgICAgICAgICAgICAgaWYgKHN0YXRlKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChmQ29uZmlndXJhdGlvbi5nZXRQcm9wZXJ0eShTRUNVUklUWV9NQU5BR0VSICk9PW51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZDb25maWd1cmF0aW9uLnNldFByb3BlcnR5KFNFQ1VSSVRZX01BTkFHRVIsIG5ldyBYTUxTZWN1cml0eU1hbmFnZXIoKSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAvLyBEZWZhdWx0IGhhbmRsaW5nCi0gICAgICAgICAgICAvLwotCi0gICAgICAgICAgICBmQ29uZmlndXJhdGlvbi5zZXRGZWF0dXJlKGZlYXR1cmVJZCwgc3RhdGUpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIFN0cmluZyBpZGVudGlmaWVyID0gZS5nZXRJZGVudGlmaWVyKCk7Ci0gICAgICAgICAgICBpZiAoZS5nZXRUeXBlKCkgPT0gU3RhdHVzLk5PVF9SRUNPR05JWkVEKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgIFNBWE1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShmQ29uZmlndXJhdGlvbi5nZXRMb2NhbGUoKSwKLSAgICAgICAgICAgICAgICAgICAgImZlYXR1cmUtbm90LXJlY29nbml6ZWQiLCBuZXcgT2JqZWN0IFtdIHtpZGVudGlmaWVyfSkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgU0FYTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKGZDb25maWd1cmF0aW9uLmdldExvY2FsZSgpLAotICAgICAgICAgICAgICAgICAgICAiZmVhdHVyZS1ub3Qtc3VwcG9ydGVkIiwgbmV3IE9iamVjdCBbXSB7aWRlbnRpZmllcn0pKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgfSAvLyBzZXRGZWF0dXJlKFN0cmluZyxib29sZWFuKQotCi0gICAgLyoqCi0gICAgICogUXVlcnkgdGhlIHN0YXRlIG9mIGEgZmVhdHVyZS4KLSAgICAgKgotICAgICAqIFF1ZXJ5IHRoZSBjdXJyZW50IHN0YXRlIG9mIGFueSBmZWF0dXJlIGluIGEgU0FYMiBwYXJzZXIuICBUaGUKLSAgICAgKiBwYXJzZXIgbWlnaHQgbm90IHJlY29nbml6ZSB0aGUgZmVhdHVyZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBmZWF0dXJlSWQgVGhlIHVuaXF1ZSBpZGVudGlmaWVyIChVUkkpIG9mIHRoZSBmZWF0dXJlCi0gICAgICogICAgICAgICAgICAgICAgICBiZWluZyBzZXQuCi0gICAgICogQHJldHVybiBUaGUgY3VycmVudCBzdGF0ZSBvZiB0aGUgZmVhdHVyZS4KLSAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24gSWYgdGhlCi0gICAgICogICAgICAgICAgICByZXF1ZXN0ZWQgZmVhdHVyZSBpcyBub3Qga25vd24uCi0gICAgICogQGV4Y2VwdGlvbiBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gSWYgdGhlCi0gICAgICogICAgICAgICAgICByZXF1ZXN0ZWQgZmVhdHVyZSBpcyBrbm93biBidXQgbm90IHN1cHBvcnRlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXRGZWF0dXJlKFN0cmluZyBmZWF0dXJlSWQpCi0gICAgICAgIHRocm93cyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uLCBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gewotCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAvLwotICAgICAgICAgICAgLy8gU0FYMiBGZWF0dXJlcwotICAgICAgICAgICAgLy8KLQotICAgICAgICAgICAgaWYgKGZlYXR1cmVJZC5zdGFydHNXaXRoKENvbnN0YW50cy5TQVhfRkVBVFVSRV9QUkVGSVgpKSB7Ci0gICAgICAgICAgICAgICAgZmluYWwgaW50IHN1ZmZpeExlbmd0aCA9IGZlYXR1cmVJZC5sZW5ndGgoKSAtIENvbnN0YW50cy5TQVhfRkVBVFVSRV9QUkVGSVgubGVuZ3RoKCk7Ci0KLSAgICAgICAgICAgICAgICAvLyBodHRwOi8veG1sLm9yZy9zYXgvZmVhdHVyZXMvbmFtZXNwYWNlLXByZWZpeGVzCi0gICAgICAgICAgICAgICAgLy8gICBjb250cm9scyB0aGUgcmVwb3J0aW5nIG9mIHJhdyBwcmVmaXhlZCBuYW1lcyBhbmQgTmFtZXNwYWNlCi0gICAgICAgICAgICAgICAgLy8gICBkZWNsYXJhdGlvbnMgKHhtbG5zKiBhdHRyaWJ1dGVzKTogd2hlbiB0aGlzIGZlYXR1cmUgaXMgZmFsc2UKLSAgICAgICAgICAgICAgICAvLyAgICh0aGUgZGVmYXVsdCksIHJhdyBwcmVmaXhlZCBuYW1lcyBtYXkgb3B0aW9uYWxseSBiZSByZXBvcnRlZCwKLSAgICAgICAgICAgICAgICAvLyAgIGFuZCB4bWxucyogYXR0cmlidXRlcyBtdXN0IG5vdCBiZSByZXBvcnRlZC4KLSAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgIGlmIChzdWZmaXhMZW5ndGggPT0gQ29uc3RhbnRzLk5BTUVTUEFDRV9QUkVGSVhFU19GRUFUVVJFLmxlbmd0aCgpICYmCi0gICAgICAgICAgICAgICAgICAgIGZlYXR1cmVJZC5lbmRzV2l0aChDb25zdGFudHMuTkFNRVNQQUNFX1BSRUZJWEVTX0ZFQVRVUkUpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gc3RhdGUgPSBmQ29uZmlndXJhdGlvbi5nZXRGZWF0dXJlKGZlYXR1cmVJZCk7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBzdGF0ZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLy8gaHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL3N0cmluZy1pbnRlcm5pbmcKLSAgICAgICAgICAgICAgICAvLyAgIGNvbnRyb2xzIHRoZSB1c2Ugb2YgamF2YS5sYW5nLlN0cmluZyNpbnRlcm4oKSBmb3Igc3RyaW5ncwotICAgICAgICAgICAgICAgIC8vICAgcGFzc2VkIHRvIFNBWCBoYW5kbGVycy4KLSAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgIGlmIChzdWZmaXhMZW5ndGggPT0gQ29uc3RhbnRzLlNUUklOR19JTlRFUk5JTkdfRkVBVFVSRS5sZW5ndGgoKSAmJgotICAgICAgICAgICAgICAgICAgICBmZWF0dXJlSWQuZW5kc1dpdGgoQ29uc3RhbnRzLlNUUklOR19JTlRFUk5JTkdfRkVBVFVSRSkpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgLy8gaHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL2lzLXN0YW5kYWxvbmUKLSAgICAgICAgICAgICAgICAvLyAgIHJlcG9ydHMgd2hldGhlciB0aGUgZG9jdW1lbnQgc3BlY2lmaWVkIGEgc3RhbmRhbG9uZSBkb2N1bWVudCBkZWNsYXJhdGlvbi4KLSAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgIGlmIChzdWZmaXhMZW5ndGggPT0gQ29uc3RhbnRzLklTX1NUQU5EQUxPTkVfRkVBVFVSRS5sZW5ndGgoKSAmJgotICAgICAgICAgICAgICAgICAgICBmZWF0dXJlSWQuZW5kc1dpdGgoQ29uc3RhbnRzLklTX1NUQU5EQUxPTkVfRkVBVFVSRSkpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZTdGFuZGFsb25lOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8vIGh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy94bWwtMS4xCi0gICAgICAgICAgICAgICAgLy8gICByZXBvcnRzIHdoZXRoZXIgdGhlIHBhcnNlciBzdXBwb3J0cyBib3RoIFhNTCAxLjEgYW5kIFhNTCAxLjAuCi0gICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICBpZiAoc3VmZml4TGVuZ3RoID09IENvbnN0YW50cy5YTUxfMTFfRkVBVFVSRS5sZW5ndGgoKSAmJgotICAgICAgICAgICAgICAgICAgICBmZWF0dXJlSWQuZW5kc1dpdGgoQ29uc3RhbnRzLlhNTF8xMV9GRUFUVVJFKSkgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gKGZDb25maWd1cmF0aW9uIGluc3RhbmNlb2YgWE1MMTFDb25maWd1cmFibGUpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8vIGh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy9sZXhpY2FsLWhhbmRsZXIvcGFyYW1ldGVyLWVudGl0aWVzCi0gICAgICAgICAgICAgICAgLy8gICBjb250cm9scyB3aGV0aGVyIHRoZSBiZWdpbm5pbmcgYW5kIGVuZCBvZiBwYXJhbWV0ZXIgZW50aXRpZXMKLSAgICAgICAgICAgICAgICAvLyAgIHdpbGwgYmUgcmVwb3J0ZWQgdG8gdGhlIExleGljYWxIYW5kbGVyLgotICAgICAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAgICAgaWYgKHN1ZmZpeExlbmd0aCA9PSBDb25zdGFudHMuTEVYSUNBTF9IQU5ETEVSX1BBUkFNRVRFUl9FTlRJVElFU19GRUFUVVJFLmxlbmd0aCgpICYmCi0gICAgICAgICAgICAgICAgICAgIGZlYXR1cmVJZC5lbmRzV2l0aChDb25zdGFudHMuTEVYSUNBTF9IQU5ETEVSX1BBUkFNRVRFUl9FTlRJVElFU19GRUFUVVJFKSkgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gZkxleGljYWxIYW5kbGVyUGFyYW1ldGVyRW50aXRpZXM7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgLy8gaHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL3Jlc29sdmUtZHRkLXVyaXMKLSAgICAgICAgICAgICAgICAvLyAgIGNvbnRyb2xzIHdoZXRoZXIgc3lzdGVtIGlkZW50aWZpZXJzIHdpbGwgYmUgYWJzb2x1dGl6ZWQgcmVsYXRpdmUgdG8KLSAgICAgICAgICAgICAgICAvLyAgIHRoZWlyIGJhc2UgVVJJcyBiZWZvcmUgcmVwb3J0aW5nLgotICAgICAgICAgICAgICAgIGlmIChzdWZmaXhMZW5ndGggPT0gQ29uc3RhbnRzLlJFU09MVkVfRFREX1VSSVNfRkVBVFVSRS5sZW5ndGgoKSAmJgotICAgICAgICAgICAgICAgICAgICBmZWF0dXJlSWQuZW5kc1dpdGgoQ29uc3RhbnRzLlJFU09MVkVfRFREX1VSSVNfRkVBVFVSRSkpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZSZXNvbHZlRFREVVJJczsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyBodHRwOi8veG1sLm9yZy9zYXgvZmVhdHVyZXMveG1sbnMtdXJpcwotICAgICAgICAgICAgICAgIC8vICAgY29udHJvbHMgd2hldGhlciB0aGUgcGFyc2VyIHJlcG9ydHMgdGhhdCBuYW1lc3BhY2UgZGVjbGFyYXRpb24KLSAgICAgICAgICAgICAgICAvLyAgIGF0dHJpYnV0ZXMgYXMgYmVpbmcgaW4gdGhlIG5hbWVzcGFjZTogaHR0cDovL3d3dy53My5vcmcvMjAwMC94bWxucy8KLSAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgIGlmIChzdWZmaXhMZW5ndGggPT0gQ29uc3RhbnRzLlhNTE5TX1VSSVNfRkVBVFVSRS5sZW5ndGgoKSAmJgotICAgICAgICAgICAgICAgICAgICBmZWF0dXJlSWQuZW5kc1dpdGgoQ29uc3RhbnRzLlhNTE5TX1VSSVNfRkVBVFVSRSkpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZYTUxOU1VSSXM7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgLy8gaHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL3VuaWNvZGUtbm9ybWFsaXphdGlvbi1jaGVja2luZwotICAgICAgICAgICAgICAgIC8vICAgY29udHJvbHMgd2hldGhlciBVbmljb2RlIG5vcm1hbGl6YXRpb24gY2hlY2tpbmcgaXMgcGVyZm9ybWVkCi0gICAgICAgICAgICAgICAgLy8gICBhcyBwZXIgQXBwZW5kaXggQiBvZiB0aGUgWE1MIDEuMSBzcGVjaWZpY2F0aW9uCi0gICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICBpZiAoc3VmZml4TGVuZ3RoID09IENvbnN0YW50cy5VTklDT0RFX05PUk1BTElaQVRJT05fQ0hFQ0tJTkdfRkVBVFVSRS5sZW5ndGgoKSAmJgotICAgICAgICAgICAgICAgICAgICBmZWF0dXJlSWQuZW5kc1dpdGgoQ29uc3RhbnRzLlVOSUNPREVfTk9STUFMSVpBVElPTl9DSEVDS0lOR19GRUFUVVJFKSkgewotICAgICAgICAgICAgICAgICAgICAvLyBSRVZJU0lUOiBBbGxvdyB0aGlzIGZlYXR1cmUgdG8gYmUgc2V0IG9uY2UgVW5pY29kZSBub3JtYWxpemF0aW9uCi0gICAgICAgICAgICAgICAgICAgIC8vIGNoZWNraW5nIGlzIHN1cHBvcnRlZCAtLSBtcmdsYXZhcy4KLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8vIGh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy91c2UtZW50aXR5LXJlc29sdmVyMgotICAgICAgICAgICAgICAgIC8vICAgY29udHJvbHMgd2hldGhlciB0aGUgbWV0aG9kcyBvZiBhbiBvYmplY3QgaW1wbGVtZW50aW5nCi0gICAgICAgICAgICAgICAgLy8gICBvcmcueG1sLnNheC5leHQuRW50aXR5UmVzb2x2ZXIyIHdpbGwgYmUgdXNlZCBieSB0aGUgcGFyc2VyLgotICAgICAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAgICAgaWYgKHN1ZmZpeExlbmd0aCA9PSBDb25zdGFudHMuVVNFX0VOVElUWV9SRVNPTFZFUjJfRkVBVFVSRS5sZW5ndGgoKSAmJgotICAgICAgICAgICAgICAgICAgICBmZWF0dXJlSWQuZW5kc1dpdGgoQ29uc3RhbnRzLlVTRV9FTlRJVFlfUkVTT0xWRVIyX0ZFQVRVUkUpKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBmVXNlRW50aXR5UmVzb2x2ZXIyOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8vIGh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy91c2UtYXR0cmlidXRlczIKLSAgICAgICAgICAgICAgICAvLyAgIHJlcG9ydHMgd2hldGhlciBBdHRyaWJ1dGVzIG9iamVjdHMgcGFzc2VkIHRvIHN0YXJ0RWxlbWVudCBhbHNvIGltcGxlbWVudAotICAgICAgICAgICAgICAgIC8vICAgdGhlIG9yZy54bWwuc2F4LmV4dC5BdHRyaWJ1dGVzMiBpbnRlcmZhY2UuCi0gICAgICAgICAgICAgICAgLy8gaHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL3VzZS1sb2NhdG9yMgotICAgICAgICAgICAgICAgIC8vICAgcmVwb3J0cyB3aGV0aGVyIExvY2F0b3Igb2JqZWN0cyBwYXNzZWQgdG8gc2V0RG9jdW1lbnRMb2NhdG9yIGFsc28gaW1wbGVtZW50Ci0gICAgICAgICAgICAgICAgLy8gICB0aGUgb3JnLnhtbC5zYXguZXh0LkxvY2F0b3IyIGludGVyZmFjZS4KLSAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgIGlmICgoc3VmZml4TGVuZ3RoID09IENvbnN0YW50cy5VU0VfQVRUUklCVVRFUzJfRkVBVFVSRS5sZW5ndGgoKSAmJgotICAgICAgICAgICAgICAgICAgICBmZWF0dXJlSWQuZW5kc1dpdGgoQ29uc3RhbnRzLlVTRV9BVFRSSUJVVEVTMl9GRUFUVVJFKSkgfHwKLSAgICAgICAgICAgICAgICAgICAgKHN1ZmZpeExlbmd0aCA9PSBDb25zdGFudHMuVVNFX0xPQ0FUT1IyX0ZFQVRVUkUubGVuZ3RoKCkgJiYKLSAgICAgICAgICAgICAgICAgICAgZmVhdHVyZUlkLmVuZHNXaXRoKENvbnN0YW50cy5VU0VfTE9DQVRPUjJfRkVBVFVSRSkpKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgICAgIH0KLQotCi0gICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICAvLyBEcm9wIHRocm91Z2ggYW5kIHBlcmZvcm0gZGVmYXVsdCBwcm9jZXNzaW5nCi0gICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIC8vIFhlcmNlcyBGZWF0dXJlcwotICAgICAgICAgICAgLy8KLQotICAgICAgICAgICAgLyoKLSAgICAgICAgICAgIGVsc2UgaWYgKGZlYXR1cmVJZC5zdGFydHNXaXRoKFhFUkNFU19GRUFUVVJFU19QUkVGSVgpKSB7Ci0gICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICAvLyBEcm9wIHRocm91Z2ggYW5kIHBlcmZvcm0gZGVmYXVsdCBwcm9jZXNzaW5nCi0gICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgICovCi0KLSAgICAgICAgICAgIHJldHVybiBmQ29uZmlndXJhdGlvbi5nZXRGZWF0dXJlKGZlYXR1cmVJZCk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gZSkgewotICAgICAgICAgICAgU3RyaW5nIGlkZW50aWZpZXIgPSBlLmdldElkZW50aWZpZXIoKTsKLSAgICAgICAgICAgIGlmIChlLmdldFR5cGUoKSA9PSBTdGF0dXMuTk9UX1JFQ09HTklaRUQpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgU0FYTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKGZDb25maWd1cmF0aW9uLmdldExvY2FsZSgpLAotICAgICAgICAgICAgICAgICAgICAiZmVhdHVyZS1ub3QtcmVjb2duaXplZCIsIG5ldyBPYmplY3QgW10ge2lkZW50aWZpZXJ9KSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICBTQVhNZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoZkNvbmZpZ3VyYXRpb24uZ2V0TG9jYWxlKCksCi0gICAgICAgICAgICAgICAgICAgICJmZWF0dXJlLW5vdC1zdXBwb3J0ZWQiLCBuZXcgT2JqZWN0IFtdIHtpZGVudGlmaWVyfSkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICB9IC8vIGdldEZlYXR1cmUoU3RyaW5nKTpib29sZWFuCi0KLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIHZhbHVlIG9mIGFueSBwcm9wZXJ0eSBpbiBhIFNBWDIgcGFyc2VyLiAgVGhlIHBhcnNlcgotICAgICAqIG1pZ2h0IG5vdCByZWNvZ25pemUgdGhlIHByb3BlcnR5LCBhbmQgaWYgaXQgZG9lcyByZWNvZ25pemUKLSAgICAgKiBpdCwgaXQgbWlnaHQgbm90IHN1cHBvcnQgdGhlIHJlcXVlc3RlZCB2YWx1ZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBwcm9wZXJ0eUlkIFRoZSB1bmlxdWUgaWRlbnRpZmllciAoVVJJKSBvZiB0aGUgcHJvcGVydHkKLSAgICAgKiAgICAgICAgICAgICAgICAgICBiZWluZyBzZXQuCi0gICAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZSB0byB3aGljaCB0aGUgcHJvcGVydHkgaXMgYmVpbmcgc2V0LgotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIElmIHRoZQotICAgICAqICAgICAgICAgICAgcmVxdWVzdGVkIHByb3BlcnR5IGlzIG5vdCBrbm93bi4KLSAgICAgKiBAZXhjZXB0aW9uIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBJZiB0aGUKLSAgICAgKiAgICAgICAgICAgIHJlcXVlc3RlZCBwcm9wZXJ0eSBpcyBrbm93biwgYnV0IHRoZSByZXF1ZXN0ZWQKLSAgICAgKiAgICAgICAgICAgIHZhbHVlIGlzIG5vdCBzdXBwb3J0ZWQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0UHJvcGVydHkoU3RyaW5nIHByb3BlcnR5SWQsIE9iamVjdCB2YWx1ZSkKLSAgICAgICAgdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAvLyBTQVgyIGNvcmUgcHJvcGVydGllcwotICAgICAgICAgICAgLy8KLQotICAgICAgICAgICAgaWYgKHByb3BlcnR5SWQuc3RhcnRzV2l0aChDb25zdGFudHMuU0FYX1BST1BFUlRZX1BSRUZJWCkpIHsKLSAgICAgICAgICAgICAgICBmaW5hbCBpbnQgc3VmZml4TGVuZ3RoID0gcHJvcGVydHlJZC5sZW5ndGgoKSAtIENvbnN0YW50cy5TQVhfUFJPUEVSVFlfUFJFRklYLmxlbmd0aCgpOwotCi0gICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICAvLyBodHRwOi8veG1sLm9yZy9zYXgvcHJvcGVydGllcy9sZXhpY2FsLWhhbmRsZXIKLSAgICAgICAgICAgICAgICAvLyBWYWx1ZSB0eXBlOiBvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXIKLSAgICAgICAgICAgICAgICAvLyBBY2Nlc3M6IHJlYWQvd3JpdGUsIHByZS1wYXJzZSBvbmx5Ci0gICAgICAgICAgICAgICAgLy8gICBTZXQgdGhlIGxleGljYWwgZXZlbnQgaGFuZGxlci4KLSAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgIGlmIChzdWZmaXhMZW5ndGggPT0gQ29uc3RhbnRzLkxFWElDQUxfSEFORExFUl9QUk9QRVJUWS5sZW5ndGgoKSAmJgotICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eUlkLmVuZHNXaXRoKENvbnN0YW50cy5MRVhJQ0FMX0hBTkRMRVJfUFJPUEVSVFkpKSB7Ci0gICAgICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzZXRMZXhpY2FsSGFuZGxlcigoTGV4aWNhbEhhbmRsZXIpdmFsdWUpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGNhdGNoIChDbGFzc0Nhc3RFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBTQVhNZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoZkNvbmZpZ3VyYXRpb24uZ2V0TG9jYWxlKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgImluY29tcGF0aWJsZS1jbGFzcyIsIG5ldyBPYmplY3QgW10ge3Byb3BlcnR5SWQsICJvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXIifSkpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICAvLyBodHRwOi8veG1sLm9yZy9zYXgvcHJvcGVydGllcy9kZWNsYXJhdGlvbi1oYW5kbGVyCi0gICAgICAgICAgICAgICAgLy8gVmFsdWUgdHlwZTogb3JnLnhtbC5zYXguZXh0LkRlY2xIYW5kbGVyCi0gICAgICAgICAgICAgICAgLy8gQWNjZXNzOiByZWFkL3dyaXRlLCBwcmUtcGFyc2Ugb25seQotICAgICAgICAgICAgICAgIC8vICAgU2V0IHRoZSBEVEQgZGVjbGFyYXRpb24gZXZlbnQgaGFuZGxlci4KLSAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgIGlmIChzdWZmaXhMZW5ndGggPT0gQ29uc3RhbnRzLkRFQ0xBUkFUSU9OX0hBTkRMRVJfUFJPUEVSVFkubGVuZ3RoKCkgJiYKLSAgICAgICAgICAgICAgICAgICAgcHJvcGVydHlJZC5lbmRzV2l0aChDb25zdGFudHMuREVDTEFSQVRJT05fSEFORExFUl9QUk9QRVJUWSkpIHsKLSAgICAgICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHNldERlY2xIYW5kbGVyKChEZWNsSGFuZGxlcil2YWx1ZSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNBWE1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShmQ29uZmlndXJhdGlvbi5nZXRMb2NhbGUoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAiaW5jb21wYXRpYmxlLWNsYXNzIiwgbmV3IE9iamVjdCBbXSB7cHJvcGVydHlJZCwgIm9yZy54bWwuc2F4LmV4dC5EZWNsSGFuZGxlciJ9KSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgIC8vIGh0dHA6Ly94bWwub3JnL3NheC9wcm9wZXJ0aWVzL2RvbS1ub2RlCi0gICAgICAgICAgICAgICAgLy8gVmFsdWUgdHlwZTogRE9NIE5vZGUKLSAgICAgICAgICAgICAgICAvLyBBY2Nlc3M6IHJlYWQtb25seQotICAgICAgICAgICAgICAgIC8vICAgR2V0IHRoZSBET00gbm9kZSBjdXJyZW50bHkgYmVpbmcgdmlzaXRlZCwgaWYgdGhlIFNBWCBwYXJzZXIgaXMKLSAgICAgICAgICAgICAgICAvLyAgIGl0ZXJhdGluZyBvdmVyIGEgRE9NIHRyZWUuICBJZiB0aGUgcGFyc2VyIHJlY29nbmlzZXMgYW5kCi0gICAgICAgICAgICAgICAgLy8gICBzdXBwb3J0cyB0aGlzIHByb3BlcnR5IGJ1dCBpcyBub3QgY3VycmVudGx5IHZpc2l0aW5nIGEgRE9NCi0gICAgICAgICAgICAgICAgLy8gICBub2RlLCBpdCBzaG91bGQgcmV0dXJuIG51bGwgKHRoaXMgaXMgYSBnb29kIHdheSB0byBjaGVjayBmb3IKLSAgICAgICAgICAgICAgICAvLyAgIGF2YWlsYWJpbGl0eSBiZWZvcmUgdGhlIHBhcnNlIGJlZ2lucykuCi0gICAgICAgICAgICAgICAgLy8gaHR0cDovL3htbC5vcmcvc2F4L3Byb3BlcnRpZXMvZG9jdW1lbnQteG1sLXZlcnNpb24KLSAgICAgICAgICAgICAgICAvLyBWYWx1ZSB0eXBlOiBqYXZhLmxhbmcuU3RyaW5nCi0gICAgICAgICAgICAgICAgLy8gQWNjZXNzOiByZWFkLW9ubHkKLSAgICAgICAgICAgICAgICAvLyAgIFRoZSBsaXRlcmFsIHN0cmluZyBkZXNjcmliaW5nIHRoZSBhY3R1YWwgWE1MIHZlcnNpb24gb2YgdGhlIGRvY3VtZW50LgotICAgICAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAgICAgaWYgKChzdWZmaXhMZW5ndGggPT0gQ29uc3RhbnRzLkRPTV9OT0RFX1BST1BFUlRZLmxlbmd0aCgpICYmCi0gICAgICAgICAgICAgICAgICAgIHByb3BlcnR5SWQuZW5kc1dpdGgoQ29uc3RhbnRzLkRPTV9OT0RFX1BST1BFUlRZKSkgfHwKLSAgICAgICAgICAgICAgICAgICAgKHN1ZmZpeExlbmd0aCA9PSBDb25zdGFudHMuRE9DVU1FTlRfWE1MX1ZFUlNJT05fUFJPUEVSVFkubGVuZ3RoKCkgJiYKLSAgICAgICAgICAgICAgICAgICAgcHJvcGVydHlJZC5lbmRzV2l0aChDb25zdGFudHMuRE9DVU1FTlRfWE1MX1ZFUlNJT05fUFJPUEVSVFkpKSkgewotICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICAgICAgU0FYTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKGZDb25maWd1cmF0aW9uLmdldExvY2FsZSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgInByb3BlcnR5LXJlYWQtb25seSIsIG5ldyBPYmplY3QgW10ge3Byb3BlcnR5SWR9KSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAgICAgLy8gRHJvcCB0aHJvdWdoIGFuZCBwZXJmb3JtIGRlZmF1bHQgcHJvY2Vzc2luZwotICAgICAgICAgICAgICAgIC8vCi0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAvLyBYZXJjZXMgUHJvcGVydGllcwotICAgICAgICAgICAgLy8KLQotICAgICAgICAgICAgLyoKLSAgICAgICAgICAgIGVsc2UgaWYgKHByb3BlcnR5SWQuc3RhcnRzV2l0aChYRVJDRVNfUFJPUEVSVElFU19QUkVGSVgpKSB7Ci0gICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICAvLyBEcm9wIHRocm91Z2ggYW5kIHBlcmZvcm0gZGVmYXVsdCBwcm9jZXNzaW5nCi0gICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgICovCi0KLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAvLyBQZXJmb3JtIGRlZmF1bHQgcHJvY2Vzc2luZwotICAgICAgICAgICAgLy8KLQotICAgICAgICAgICAgZkNvbmZpZ3VyYXRpb24uc2V0UHJvcGVydHkocHJvcGVydHlJZCwgdmFsdWUpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIFN0cmluZyBpZGVudGlmaWVyID0gZS5nZXRJZGVudGlmaWVyKCk7Ci0gICAgICAgICAgICBpZiAoZS5nZXRUeXBlKCkgPT0gU3RhdHVzLk5PVF9SRUNPR05JWkVEKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgIFNBWE1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShmQ29uZmlndXJhdGlvbi5nZXRMb2NhbGUoKSwKLSAgICAgICAgICAgICAgICAgICAgInByb3BlcnR5LW5vdC1yZWNvZ25pemVkIiwgbmV3IE9iamVjdCBbXSB7aWRlbnRpZmllcn0pKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgIFNBWE1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShmQ29uZmlndXJhdGlvbi5nZXRMb2NhbGUoKSwKLSAgICAgICAgICAgICAgICAgICAgInByb3BlcnR5LW5vdC1zdXBwb3J0ZWQiLCBuZXcgT2JqZWN0IFtdIHtpZGVudGlmaWVyfSkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICB9IC8vIHNldFByb3BlcnR5KFN0cmluZyxPYmplY3QpCi0KLSAgICAvKioKLSAgICAgKiBRdWVyeSB0aGUgdmFsdWUgb2YgYSBwcm9wZXJ0eS4KLSAgICAgKgotICAgICAqIFJldHVybiB0aGUgY3VycmVudCB2YWx1ZSBvZiBhIHByb3BlcnR5IGluIGEgU0FYMiBwYXJzZXIuCi0gICAgICogVGhlIHBhcnNlciBtaWdodCBub3QgcmVjb2duaXplIHRoZSBwcm9wZXJ0eS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBwcm9wZXJ0eUlkIFRoZSB1bmlxdWUgaWRlbnRpZmllciAoVVJJKSBvZiB0aGUgcHJvcGVydHkKLSAgICAgKiAgICAgICAgICAgICAgICAgICBiZWluZyBzZXQuCi0gICAgICogQHJldHVybiBUaGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgcHJvcGVydHkuCi0gICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIElmIHRoZQotICAgICAqICAgICAgICAgICAgcmVxdWVzdGVkIHByb3BlcnR5IGlzIG5vdCBrbm93bi4KLSAgICAgKiBAZXhjZXB0aW9uIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBJZiB0aGUKLSAgICAgKiAgICAgICAgICAgIHJlcXVlc3RlZCBwcm9wZXJ0eSBpcyBrbm93biBidXQgbm90IHN1cHBvcnRlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0IGdldFByb3BlcnR5KFN0cmluZyBwcm9wZXJ0eUlkKQotICAgICAgICB0aHJvd3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiwgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIHsKLQotICAgICAgICB0cnkgewotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIC8vIFNBWDIgY29yZSBwcm9wZXJ0aWVzCi0gICAgICAgICAgICAvLwotCi0gICAgICAgICAgICBpZiAocHJvcGVydHlJZC5zdGFydHNXaXRoKENvbnN0YW50cy5TQVhfUFJPUEVSVFlfUFJFRklYKSkgewotICAgICAgICAgICAgICAgIGZpbmFsIGludCBzdWZmaXhMZW5ndGggPSBwcm9wZXJ0eUlkLmxlbmd0aCgpIC0gQ29uc3RhbnRzLlNBWF9QUk9QRVJUWV9QUkVGSVgubGVuZ3RoKCk7Ci0KLSAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgIC8vIGh0dHA6Ly94bWwub3JnL3NheC9wcm9wZXJ0aWVzL2RvY3VtZW50LXhtbC12ZXJzaW9uCi0gICAgICAgICAgICAgICAgLy8gVmFsdWUgdHlwZTogamF2YS5sYW5nLlN0cmluZwotICAgICAgICAgICAgICAgIC8vIEFjY2VzczogcmVhZC1vbmx5Ci0gICAgICAgICAgICAgICAgLy8gICBUaGUgbGl0ZXJhbCBzdHJpbmcgZGVzY3JpYmluZyB0aGUgYWN0dWFsIFhNTCB2ZXJzaW9uIG9mIHRoZSBkb2N1bWVudC4KLSAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgIGlmIChzdWZmaXhMZW5ndGggPT0gQ29uc3RhbnRzLkRPQ1VNRU5UX1hNTF9WRVJTSU9OX1BST1BFUlRZLmxlbmd0aCgpICYmCi0gICAgICAgICAgICAgICAgICAgIHByb3BlcnR5SWQuZW5kc1dpdGgoQ29uc3RhbnRzLkRPQ1VNRU5UX1hNTF9WRVJTSU9OX1BST1BFUlRZKSkgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gZlZlcnNpb247Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICAvLyBodHRwOi8veG1sLm9yZy9zYXgvcHJvcGVydGllcy9sZXhpY2FsLWhhbmRsZXIKLSAgICAgICAgICAgICAgICAvLyBWYWx1ZSB0eXBlOiBvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXIKLSAgICAgICAgICAgICAgICAvLyBBY2Nlc3M6IHJlYWQvd3JpdGUsIHByZS1wYXJzZSBvbmx5Ci0gICAgICAgICAgICAgICAgLy8gICBTZXQgdGhlIGxleGljYWwgZXZlbnQgaGFuZGxlci4KLSAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgIGlmIChzdWZmaXhMZW5ndGggPT0gQ29uc3RhbnRzLkxFWElDQUxfSEFORExFUl9QUk9QRVJUWS5sZW5ndGgoKSAmJgotICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eUlkLmVuZHNXaXRoKENvbnN0YW50cy5MRVhJQ0FMX0hBTkRMRVJfUFJPUEVSVFkpKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBnZXRMZXhpY2FsSGFuZGxlcigpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgIC8vIGh0dHA6Ly94bWwub3JnL3NheC9wcm9wZXJ0aWVzL2RlY2xhcmF0aW9uLWhhbmRsZXIKLSAgICAgICAgICAgICAgICAvLyBWYWx1ZSB0eXBlOiBvcmcueG1sLnNheC5leHQuRGVjbEhhbmRsZXIKLSAgICAgICAgICAgICAgICAvLyBBY2Nlc3M6IHJlYWQvd3JpdGUsIHByZS1wYXJzZSBvbmx5Ci0gICAgICAgICAgICAgICAgLy8gICBTZXQgdGhlIERURCBkZWNsYXJhdGlvbiBldmVudCBoYW5kbGVyLgotICAgICAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAgICAgaWYgKHN1ZmZpeExlbmd0aCA9PSBDb25zdGFudHMuREVDTEFSQVRJT05fSEFORExFUl9QUk9QRVJUWS5sZW5ndGgoKSAmJgotICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eUlkLmVuZHNXaXRoKENvbnN0YW50cy5ERUNMQVJBVElPTl9IQU5ETEVSX1BST1BFUlRZKSkgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gZ2V0RGVjbEhhbmRsZXIoKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgIC8vIGh0dHA6Ly94bWwub3JnL3NheC9wcm9wZXJ0aWVzL2RvbS1ub2RlCi0gICAgICAgICAgICAgICAgLy8gVmFsdWUgdHlwZTogRE9NIE5vZGUKLSAgICAgICAgICAgICAgICAvLyBBY2Nlc3M6IHJlYWQtb25seQotICAgICAgICAgICAgICAgIC8vICAgR2V0IHRoZSBET00gbm9kZSBjdXJyZW50bHkgYmVpbmcgdmlzaXRlZCwgaWYgdGhlIFNBWCBwYXJzZXIgaXMKLSAgICAgICAgICAgICAgICAvLyAgIGl0ZXJhdGluZyBvdmVyIGEgRE9NIHRyZWUuICBJZiB0aGUgcGFyc2VyIHJlY29nbmlzZXMgYW5kCi0gICAgICAgICAgICAgICAgLy8gICBzdXBwb3J0cyB0aGlzIHByb3BlcnR5IGJ1dCBpcyBub3QgY3VycmVudGx5IHZpc2l0aW5nIGEgRE9NCi0gICAgICAgICAgICAgICAgLy8gICBub2RlLCBpdCBzaG91bGQgcmV0dXJuIG51bGwgKHRoaXMgaXMgYSBnb29kIHdheSB0byBjaGVjayBmb3IKLSAgICAgICAgICAgICAgICAvLyAgIGF2YWlsYWJpbGl0eSBiZWZvcmUgdGhlIHBhcnNlIGJlZ2lucykuCi0gICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICBpZiAoc3VmZml4TGVuZ3RoID09IENvbnN0YW50cy5ET01fTk9ERV9QUk9QRVJUWS5sZW5ndGgoKSAmJgotICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eUlkLmVuZHNXaXRoKENvbnN0YW50cy5ET01fTk9ERV9QUk9QRVJUWSkpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gd2UgYXJlIG5vdCBpdGVyYXRpbmcgYSBET00gdHJlZQotICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICAgICAgU0FYTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKGZDb25maWd1cmF0aW9uLmdldExvY2FsZSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgImRvbS1ub2RlLXJlYWQtbm90LXN1cHBvcnRlZCIsIG51bGwpKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgIC8vIERyb3AgdGhyb3VnaCBhbmQgcGVyZm9ybSBkZWZhdWx0IHByb2Nlc3NpbmcKLSAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgLy8gWGVyY2VzIHByb3BlcnRpZXMKLSAgICAgICAgICAgIC8vCi0KLSAgICAgICAgICAgIC8qCi0gICAgICAgICAgICBlbHNlIGlmIChwcm9wZXJ0eUlkLnN0YXJ0c1dpdGgoWEVSQ0VTX1BST1BFUlRJRVNfUFJFRklYKSkgewotICAgICAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAgICAgLy8gRHJvcCB0aHJvdWdoIGFuZCBwZXJmb3JtIGRlZmF1bHQgcHJvY2Vzc2luZwotICAgICAgICAgICAgICAgIC8vCi0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAqLwotCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgLy8gUGVyZm9ybSBkZWZhdWx0IHByb2Nlc3NpbmcKLSAgICAgICAgICAgIC8vCi0KLSAgICAgICAgICAgIHJldHVybiBmQ29uZmlndXJhdGlvbi5nZXRQcm9wZXJ0eShwcm9wZXJ0eUlkKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICBTdHJpbmcgaWRlbnRpZmllciA9IGUuZ2V0SWRlbnRpZmllcigpOwotICAgICAgICAgICAgaWYgKGUuZ2V0VHlwZSgpID09IFN0YXR1cy5OT1RfUkVDT0dOSVpFRCkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICBTQVhNZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoZkNvbmZpZ3VyYXRpb24uZ2V0TG9jYWxlKCksCi0gICAgICAgICAgICAgICAgICAgICJwcm9wZXJ0eS1ub3QtcmVjb2duaXplZCIsIG5ldyBPYmplY3QgW10ge2lkZW50aWZpZXJ9KSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICBTQVhNZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoZkNvbmZpZ3VyYXRpb24uZ2V0TG9jYWxlKCksCi0gICAgICAgICAgICAgICAgICAgICJwcm9wZXJ0eS1ub3Qtc3VwcG9ydGVkIiwgbmV3IE9iamVjdCBbXSB7aWRlbnRpZmllcn0pKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgfSAvLyBnZXRQcm9wZXJ0eShTdHJpbmcpOk9iamVjdAotCi0gICAgLy8KLSAgICAvLyBQcm90ZWN0ZWQgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvLyBTQVgyIGNvcmUgcHJvcGVydGllcwotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSBEVEQgZGVjbGFyYXRpb24gZXZlbnQgaGFuZGxlci4KLSAgICAgKiA8cD4KLSAgICAgKiBUaGlzIG1ldGhvZCBpcyB0aGUgZXF1aXZhbGVudCB0byB0aGUgcHJvcGVydHk6Ci0gICAgICogPHByZT4KLSAgICAgKiBodHRwOi8veG1sLm9yZy9zYXgvcHJvcGVydGllcy9kZWNsYXJhdGlvbi1oYW5kbGVyCi0gICAgICogPC9wcmU+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gaGFuZGxlciBUaGUgbmV3IGhhbmRsZXIuCi0gICAgICoKLSAgICAgKiBAc2VlICNnZXREZWNsSGFuZGxlcgotICAgICAqIEBzZWUgI3NldFByb3BlcnR5Ci0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgc2V0RGVjbEhhbmRsZXIoRGVjbEhhbmRsZXIgaGFuZGxlcikKLSAgICAgICAgdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgaWYgKGZQYXJzZUluUHJvZ3Jlc3MpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgU0FYTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKGZDb25maWd1cmF0aW9uLmdldExvY2FsZSgpLAotICAgICAgICAgICAgICAgICJwcm9wZXJ0eS1ub3QtcGFyc2luZy1zdXBwb3J0ZWQiLAotICAgICAgICAgICAgICAgIG5ldyBPYmplY3QgW10geyJodHRwOi8veG1sLm9yZy9zYXgvcHJvcGVydGllcy9kZWNsYXJhdGlvbi1oYW5kbGVyIn0pKTsKLSAgICAgICAgfQotICAgICAgICBmRGVjbEhhbmRsZXIgPSBoYW5kbGVyOwotCi0gICAgfSAvLyBzZXREZWNsSGFuZGxlcihEZWNsSGFuZGxlcikKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIERURCBkZWNsYXJhdGlvbiBldmVudCBoYW5kbGVyLgotICAgICAqCi0gICAgICogQHNlZSAjc2V0RGVjbEhhbmRsZXIKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgRGVjbEhhbmRsZXIgZ2V0RGVjbEhhbmRsZXIoKQotICAgICAgICB0aHJvd3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiwgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIHsKLSAgICAgICAgcmV0dXJuIGZEZWNsSGFuZGxlcjsKLSAgICB9IC8vIGdldERlY2xIYW5kbGVyKCk6RGVjbEhhbmRsZXIKLQotICAgIC8qKgotICAgICAqIFNldCB0aGUgbGV4aWNhbCBldmVudCBoYW5kbGVyLgotICAgICAqIDxwPgotICAgICAqIFRoaXMgbWV0aG9kIGlzIHRoZSBlcXVpdmFsZW50IHRvIHRoZSBwcm9wZXJ0eToKLSAgICAgKiA8cHJlPgotICAgICAqIGh0dHA6Ly94bWwub3JnL3NheC9wcm9wZXJ0aWVzL2xleGljYWwtaGFuZGxlcgotICAgICAqIDwvcHJlPgotICAgICAqCi0gICAgICogQHBhcmFtIGhhbmRsZXIgbGV4aWNhbCBldmVudCBoYW5kbGVyCi0gICAgICoKLSAgICAgKiBAc2VlICNnZXRMZXhpY2FsSGFuZGxlcgotICAgICAqIEBzZWUgI3NldFByb3BlcnR5Ci0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgc2V0TGV4aWNhbEhhbmRsZXIoTGV4aWNhbEhhbmRsZXIgaGFuZGxlcikKLSAgICAgICAgdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgaWYgKGZQYXJzZUluUHJvZ3Jlc3MpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgU0FYTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKGZDb25maWd1cmF0aW9uLmdldExvY2FsZSgpLAotICAgICAgICAgICAgICAgICJwcm9wZXJ0eS1ub3QtcGFyc2luZy1zdXBwb3J0ZWQiLAotICAgICAgICAgICAgICAgIG5ldyBPYmplY3QgW10geyJodHRwOi8veG1sLm9yZy9zYXgvcHJvcGVydGllcy9sZXhpY2FsLWhhbmRsZXIifSkpOwotICAgICAgICB9Ci0gICAgICAgIGZMZXhpY2FsSGFuZGxlciA9IGhhbmRsZXI7Ci0KLSAgICB9IC8vIHNldExleGljYWxIYW5kbGVyKExleGljYWxIYW5kbGVyKQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgbGV4aWNhbCBoYW5kbGVyLgotICAgICAqCi0gICAgICogQHNlZSAjc2V0TGV4aWNhbEhhbmRsZXIKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgTGV4aWNhbEhhbmRsZXIgZ2V0TGV4aWNhbEhhbmRsZXIoKQotICAgICAgICB0aHJvd3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiwgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIHsKLSAgICAgICAgcmV0dXJuIGZMZXhpY2FsSGFuZGxlcjsKLSAgICB9IC8vIGdldExleGljYWxIYW5kbGVyKCk6TGV4aWNhbEhhbmRsZXIKLQotICAgIC8qKgotICAgICAqIFNlbmQgc3RhcnRQcmVmaXhNYXBwaW5nIGV2ZW50cwotICAgICAqLwotICAgIHByb3RlY3RlZCBmaW5hbCB2b2lkIHN0YXJ0TmFtZXNwYWNlTWFwcGluZygpIHRocm93cyBTQVhFeGNlcHRpb257Ci0gICAgICAgIGludCBjb3VudCA9IGZOYW1lc3BhY2VDb250ZXh0LmdldERlY2xhcmVkUHJlZml4Q291bnQoKTsKLSAgICAgICAgaWYgKGNvdW50ID4gMCkgewotICAgICAgICAgICAgU3RyaW5nIHByZWZpeCA9IG51bGw7Ci0gICAgICAgICAgICBTdHJpbmcgdXJpID0gbnVsbDsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykgewotICAgICAgICAgICAgICAgIHByZWZpeCA9IGZOYW1lc3BhY2VDb250ZXh0LmdldERlY2xhcmVkUHJlZml4QXQoaSk7Ci0gICAgICAgICAgICAgICAgdXJpID0gZk5hbWVzcGFjZUNvbnRleHQuZ2V0VVJJKHByZWZpeCk7Ci0gICAgICAgICAgICAgICAgZkNvbnRlbnRIYW5kbGVyLnN0YXJ0UHJlZml4TWFwcGluZyhwcmVmaXgsCi0gICAgICAgICAgICAgICAgICAgICh1cmkgPT0gbnVsbCkgPyAiIiA6IHVyaSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZW5kIGVuZFByZWZpeE1hcHBpbmcgZXZlbnRzCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGZpbmFsIHZvaWQgZW5kTmFtZXNwYWNlTWFwcGluZygpIHRocm93cyBTQVhFeGNlcHRpb24gewotICAgICAgICBpbnQgY291bnQgPSBmTmFtZXNwYWNlQ29udGV4dC5nZXREZWNsYXJlZFByZWZpeENvdW50KCk7Ci0gICAgICAgIGlmIChjb3VudCA+IDApIHsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykgewotICAgICAgICAgICAgICAgIGZDb250ZW50SGFuZGxlci5lbmRQcmVmaXhNYXBwaW5nKGZOYW1lc3BhY2VDb250ZXh0LmdldERlY2xhcmVkUHJlZml4QXQoaSkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgLy8KLSAgICAvLyBYTUxEb2N1bWVudFBhcnNlciBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFJlc2V0IGFsbCBjb21wb25lbnRzIGJlZm9yZSBwYXJzaW5nLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGlmIGFuIGVycm9yIG9jY3VycyBkdXJpbmcgaW5pdGlhbGl6YXRpb24uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcmVzZXQoKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgc3VwZXIucmVzZXQoKTsKLQotICAgICAgICAvLyByZXNldCBzdGF0ZQotICAgICAgICBmSW5EVEQgPSBmYWxzZTsKLSAgICAgICAgZlZlcnNpb24gPSAiMS4wIjsKLSAgICAgICAgZlN0YW5kYWxvbmUgPSBmYWxzZTsKLQotICAgICAgICAvLyBmZWF0dXJlcwotICAgICAgICBmTmFtZXNwYWNlcyA9IGZDb25maWd1cmF0aW9uLmdldEZlYXR1cmUoTkFNRVNQQUNFUyk7Ci0gICAgICAgIGZOYW1lc3BhY2VQcmVmaXhlcyA9IGZDb25maWd1cmF0aW9uLmdldEZlYXR1cmUoTkFNRVNQQUNFX1BSRUZJWEVTKTsKLSAgICAgICAgZkF1Z21lbnRhdGlvbnMgPSBudWxsOwotICAgICAgICBmRGVjbGFyZWRBdHRycyA9IG51bGw7Ci0KLSAgICB9IC8vIHJlc2V0KCkKLQotICAgIC8vCi0gICAgLy8gQ2xhc3NlcwotICAgIC8vCi0KLSAgICBwcm90ZWN0ZWQgY2xhc3MgTG9jYXRvclByb3h5Ci0gICAgICAgIGltcGxlbWVudHMgTG9jYXRvcjIgewotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIERhdGEKLSAgICAgICAgLy8KLQotICAgICAgICAvKiogWE1MIGxvY2F0b3IuICovCi0gICAgICAgIHByb3RlY3RlZCBYTUxMb2NhdG9yIGZMb2NhdG9yOwotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIENvbnN0cnVjdG9ycwotICAgICAgICAvLwotCi0gICAgICAgIC8qKiBDb25zdHJ1Y3RzIGFuIFhNTCBsb2NhdG9yIHByb3h5LiAqLwotICAgICAgICBwdWJsaWMgTG9jYXRvclByb3h5KFhNTExvY2F0b3IgbG9jYXRvcikgewotICAgICAgICAgICAgZkxvY2F0b3IgPSBsb2NhdG9yOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gTG9jYXRvciBtZXRob2RzCi0gICAgICAgIC8vCi0KLSAgICAgICAgLyoqIFB1YmxpYyBpZGVudGlmaWVyLiAqLwotICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFB1YmxpY0lkKCkgewotICAgICAgICAgICAgcmV0dXJuIGZMb2NhdG9yLmdldFB1YmxpY0lkKCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvKiogU3lzdGVtIGlkZW50aWZpZXIuICovCi0gICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3lzdGVtSWQoKSB7Ci0gICAgICAgICAgICByZXR1cm4gZkxvY2F0b3IuZ2V0RXhwYW5kZWRTeXN0ZW1JZCgpOwotICAgICAgICB9Ci0gICAgICAgIC8qKiBMaW5lIG51bWJlci4gKi8KLSAgICAgICAgcHVibGljIGludCBnZXRMaW5lTnVtYmVyKCkgewotICAgICAgICAgICAgcmV0dXJuIGZMb2NhdG9yLmdldExpbmVOdW1iZXIoKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKiBDb2x1bW4gbnVtYmVyLiAqLwotICAgICAgICBwdWJsaWMgaW50IGdldENvbHVtbk51bWJlcigpIHsKLSAgICAgICAgICAgIHJldHVybiBmTG9jYXRvci5nZXRDb2x1bW5OdW1iZXIoKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIExvY2F0b3IyIG1ldGhvZHMKLSAgICAgICAgcHVibGljIFN0cmluZyBnZXRYTUxWZXJzaW9uKCkgewotICAgICAgICAgICAgcmV0dXJuIGZMb2NhdG9yLmdldFhNTFZlcnNpb24oKTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0RW5jb2RpbmcoKSB7Ci0gICAgICAgICAgICByZXR1cm4gZkxvY2F0b3IuZ2V0RW5jb2RpbmcoKTsKLSAgICAgICAgfQotCi0gICAgfSAvLyBjbGFzcyBMb2NhdG9yUHJveHkKLQotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgY2xhc3MgQXR0cmlidXRlc1Byb3h5Ci0gICAgICAgIGltcGxlbWVudHMgQXR0cmlidXRlTGlzdCwgQXR0cmlidXRlczIgewotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIERhdGEKLSAgICAgICAgLy8KLQotICAgICAgICAvKiogWE1MIGF0dHJpYnV0ZXMuICovCi0gICAgICAgIHByb3RlY3RlZCBYTUxBdHRyaWJ1dGVzIGZBdHRyaWJ1dGVzOwotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIFB1YmxpYyBtZXRob2RzCi0gICAgICAgIC8vCi0KLSAgICAgICAgLyoqIFNldHMgdGhlIFhNTCBhdHRyaWJ1dGVzLiAqLwotICAgICAgICBwdWJsaWMgdm9pZCBzZXRBdHRyaWJ1dGVzKFhNTEF0dHJpYnV0ZXMgYXR0cmlidXRlcykgewotICAgICAgICAgICAgZkF0dHJpYnV0ZXMgPSBhdHRyaWJ1dGVzOwotICAgICAgICB9IC8vIHNldEF0dHJpYnV0ZXMoWE1MQXR0cmlidXRlcykKLQotICAgICAgICBwdWJsaWMgaW50IGdldExlbmd0aCgpIHsKLSAgICAgICAgICAgIHJldHVybiBmQXR0cmlidXRlcy5nZXRMZW5ndGgoKTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZShpbnQgaSkgewotICAgICAgICAgICAgcmV0dXJuIGZBdHRyaWJ1dGVzLmdldFFOYW1lKGkpOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIFN0cmluZyBnZXRRTmFtZShpbnQgaW5kZXgpIHsKLSAgICAgICAgICAgIHJldHVybiBmQXR0cmlidXRlcy5nZXRRTmFtZShpbmRleCk7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFVSSShpbnQgaW5kZXgpIHsKLSAgICAgICAgICAgIC8vIFJFVklTSVQ6IHRoaXMgaGlkZXMgdGhlIGZhY3QgdGhhdCBpbnRlcm5hbGx5IHdlIHVzZQotICAgICAgICAgICAgLy8gICAgICAgICAgbnVsbCBpbnN0ZWFkIG9mIGVtcHR5IHN0cmluZwotICAgICAgICAgICAgLy8gICAgICAgICAgU0FYIHJlcXVpcmVzIFVSSSB0byBiZSBhIHN0cmluZyBvciBhbiBlbXB0eSBzdHJpbmcKLSAgICAgICAgICAgIFN0cmluZyB1cmk9IGZBdHRyaWJ1dGVzLmdldFVSSShpbmRleCk7Ci0gICAgICAgICAgICByZXR1cm4gdXJpICE9IG51bGwgPyB1cmkgOiAiIjsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0TG9jYWxOYW1lKGludCBpbmRleCkgewotICAgICAgICAgICAgcmV0dXJuIGZBdHRyaWJ1dGVzLmdldExvY2FsTmFtZShpbmRleCk7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFR5cGUoaW50IGkpIHsKLSAgICAgICAgICAgIHJldHVybiBmQXR0cmlidXRlcy5nZXRUeXBlKGkpOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIFN0cmluZyBnZXRUeXBlKFN0cmluZyBuYW1lKSB7Ci0gICAgICAgICAgICByZXR1cm4gZkF0dHJpYnV0ZXMuZ2V0VHlwZShuYW1lKTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0VHlwZShTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxOYW1lKSB7Ci0gICAgICAgICAgICByZXR1cm4gdXJpLmVxdWFscygiIikgPyBmQXR0cmlidXRlcy5nZXRUeXBlKG51bGwsIGxvY2FsTmFtZSkgOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkF0dHJpYnV0ZXMuZ2V0VHlwZSh1cmksIGxvY2FsTmFtZSk7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFZhbHVlKGludCBpKSB7Ci0gICAgICAgICAgICByZXR1cm4gZkF0dHJpYnV0ZXMuZ2V0VmFsdWUoaSk7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFZhbHVlKFN0cmluZyBuYW1lKSB7Ci0gICAgICAgICAgICByZXR1cm4gZkF0dHJpYnV0ZXMuZ2V0VmFsdWUobmFtZSk7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFZhbHVlKFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUpIHsKLSAgICAgICAgICAgIHJldHVybiB1cmkuZXF1YWxzKCIiKSA/IGZBdHRyaWJ1dGVzLmdldFZhbHVlKG51bGwsIGxvY2FsTmFtZSkgOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkF0dHJpYnV0ZXMuZ2V0VmFsdWUodXJpLCBsb2NhbE5hbWUpOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIGludCBnZXRJbmRleChTdHJpbmcgcU5hbWUpIHsKLSAgICAgICAgICAgIHJldHVybiBmQXR0cmlidXRlcy5nZXRJbmRleChxTmFtZSk7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgaW50IGdldEluZGV4KFN0cmluZyB1cmksIFN0cmluZyBsb2NhbFBhcnQpIHsKLSAgICAgICAgICAgIHJldHVybiB1cmkuZXF1YWxzKCIiKSA/IGZBdHRyaWJ1dGVzLmdldEluZGV4KG51bGwsIGxvY2FsUGFydCkgOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkF0dHJpYnV0ZXMuZ2V0SW5kZXgodXJpLCBsb2NhbFBhcnQpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gQXR0cmlidXRlczIgbWV0aG9kcwotICAgICAgICAvLyBSRVZJU0lUOiBMb2NhbGl6ZSBleGNlcHRpb24gbWVzc2FnZXMuIC0tIG1yZ2xhdmFzCi0gICAgICAgIHB1YmxpYyBib29sZWFuIGlzRGVjbGFyZWQoaW50IGluZGV4KSB7Ci0gICAgICAgICAgICBpZiAoaW5kZXggPCAwIHx8IGluZGV4ID49IGZBdHRyaWJ1dGVzLmdldExlbmd0aCgpKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihpbmRleCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gQm9vbGVhbi5UUlVFLmVxdWFscygKLSAgICAgICAgICAgICAgICBmQXR0cmlidXRlcy5nZXRBdWdtZW50YXRpb25zKGluZGV4KS5nZXRJdGVtKAotICAgICAgICAgICAgICAgIENvbnN0YW50cy5BVFRSSUJVVEVfREVDTEFSRUQpKTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyBib29sZWFuIGlzRGVjbGFyZWQoU3RyaW5nIHFOYW1lKSB7Ci0gICAgICAgICAgICBpbnQgaW5kZXggPSBnZXRJbmRleChxTmFtZSk7Ci0gICAgICAgICAgICBpZiAoaW5kZXggPT0gLTEpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKHFOYW1lKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiBCb29sZWFuLlRSVUUuZXF1YWxzKAotICAgICAgICAgICAgICAgIGZBdHRyaWJ1dGVzLmdldEF1Z21lbnRhdGlvbnMoaW5kZXgpLmdldEl0ZW0oCi0gICAgICAgICAgICAgICAgQ29uc3RhbnRzLkFUVFJJQlVURV9ERUNMQVJFRCkpOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIGJvb2xlYW4gaXNEZWNsYXJlZChTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxOYW1lKSB7Ci0gICAgICAgICAgICBpbnQgaW5kZXggPSBnZXRJbmRleCh1cmksIGxvY2FsTmFtZSk7Ci0gICAgICAgICAgICBpZiAoaW5kZXggPT0gLTEpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKGxvY2FsTmFtZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gQm9vbGVhbi5UUlVFLmVxdWFscygKLSAgICAgICAgICAgICAgICBmQXR0cmlidXRlcy5nZXRBdWdtZW50YXRpb25zKGluZGV4KS5nZXRJdGVtKAotICAgICAgICAgICAgICAgIENvbnN0YW50cy5BVFRSSUJVVEVfREVDTEFSRUQpKTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyBib29sZWFuIGlzU3BlY2lmaWVkKGludCBpbmRleCkgewotICAgICAgICAgICAgaWYgKGluZGV4IDwgMCB8fCBpbmRleCA+PSBmQXR0cmlidXRlcy5nZXRMZW5ndGgoKSkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oaW5kZXgpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIGZBdHRyaWJ1dGVzLmlzU3BlY2lmaWVkKGluZGV4KTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyBib29sZWFuIGlzU3BlY2lmaWVkKFN0cmluZyBxTmFtZSkgewotICAgICAgICAgICAgaW50IGluZGV4ID0gZ2V0SW5kZXgocU5hbWUpOwotICAgICAgICAgICAgaWYgKGluZGV4ID09IC0xKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihxTmFtZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gZkF0dHJpYnV0ZXMuaXNTcGVjaWZpZWQoaW5kZXgpOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIGJvb2xlYW4gaXNTcGVjaWZpZWQoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSkgewotICAgICAgICAgICAgaW50IGluZGV4ID0gZ2V0SW5kZXgodXJpLCBsb2NhbE5hbWUpOwotICAgICAgICAgICAgaWYgKGluZGV4ID09IC0xKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihsb2NhbE5hbWUpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIGZBdHRyaWJ1dGVzLmlzU3BlY2lmaWVkKGluZGV4KTsKLSAgICAgICAgfQotCi0gICAgfSAvLyBjbGFzcyBBdHRyaWJ1dGVzUHJveHkKLQotCi0gICAgLy8gUFNWSVByb3ZpZGVyIG1ldGhvZHMKLQotICAgIHB1YmxpYyBFbGVtZW50UFNWSSBnZXRFbGVtZW50UFNWSSgpewotICAgICAgICByZXR1cm4gKGZBdWdtZW50YXRpb25zICE9IG51bGwpPyhFbGVtZW50UFNWSSlmQXVnbWVudGF0aW9ucy5nZXRJdGVtKENvbnN0YW50cy5FTEVNRU5UX1BTVkkpOm51bGw7Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgQXR0cmlidXRlUFNWSSBnZXRBdHRyaWJ1dGVQU1ZJKGludCBpbmRleCl7Ci0KLSAgICAgICAgcmV0dXJuIChBdHRyaWJ1dGVQU1ZJKWZBdHRyaWJ1dGVzUHJveHkuZkF0dHJpYnV0ZXMuZ2V0QXVnbWVudGF0aW9ucyhpbmRleCkuZ2V0SXRlbShDb25zdGFudHMuQVRUUklCVVRFX1BTVkkpOwotICAgIH0KLQotCi0gICAgcHVibGljIEF0dHJpYnV0ZVBTVkkgZ2V0QXR0cmlidXRlUFNWSUJ5TmFtZShTdHJpbmcgdXJpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGxvY2FsbmFtZSl7Ci0gICAgICAgIHJldHVybiAoQXR0cmlidXRlUFNWSSlmQXR0cmlidXRlc1Byb3h5LmZBdHRyaWJ1dGVzLmdldEF1Z21lbnRhdGlvbnModXJpLCBsb2NhbG5hbWUpLmdldEl0ZW0oQ29uc3RhbnRzLkFUVFJJQlVURV9QU1ZJKTsKLSAgICB9Ci0KLX0gLy8gY2xhc3MgQWJzdHJhY3RTQVhQYXJzZXIKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3BhcnNlcnMvQWJzdHJhY3RYTUxEb2N1bWVudFBhcnNlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvcGFyc2Vycy9BYnN0cmFjdFhNTERvY3VtZW50UGFyc2VyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDU0NTk5N2MuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvcGFyc2Vycy9BYnN0cmFjdFhNTERvY3VtZW50UGFyc2VyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4MTIgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMSwgMjAwMiwyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnBhcnNlcnM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5BdWdtZW50YXRpb25zOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLk5hbWVzcGFjZUNvbnRleHQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuUU5hbWU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MQXR0cmlidXRlczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxEVERDb250ZW50TW9kZWxIYW5kbGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTERUREhhbmRsZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MRG9jdW1lbnRIYW5kbGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTExvY2F0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MUmVzb3VyY2VJZGVudGlmaWVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTFN0cmluZzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTklFeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTERURENvbnRlbnRNb2RlbFNvdXJjZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MRFREU291cmNlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxEb2N1bWVudFNvdXJjZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MUGFyc2VyQ29uZmlndXJhdGlvbjsKLQotLyoqCi0gKiBUaGlzIGlzIHRoZSBiYXNlIGNsYXNzIGZvciBhbGwgWE1MIGRvY3VtZW50IHBhcnNlcnMuIFhNTERvY3VtZW50UGFyc2VyCi0gKiBwcm92aWRlcyBhIGNvbW1vbiBpbXBsZW1lbnRhdGlvbiBzaGFyZWQgYnkgdGhlIHZhcmlvdXMgZG9jdW1lbnQgcGFyc2VycwotICogaW4gdGhlIFhlcmNlcyBwYWNrYWdlLiBXaGlsZSB0aGlzIGNsYXNzIGlzIHByb3ZpZGVkIGZvciBjb252ZW5pZW5jZSwgaXQKLSAqIGRvZXMgbm90IHByZXZlbnQgb3RoZXIga2luZHMgb2YgcGFyc2VycyB0byBiZSBjb25zdHJ1Y3RlZCB1c2luZyB0aGUgWE5JCi0gKiBpbnRlcmZhY2VzLgotICoKLSAqIEBhdXRob3IgQXJuYXVkICBMZSBIb3JzLCBJQk0KLSAqIEBhdXRob3IgQW5keSBDbGFyaywgSUJNCi0gKgotICovCi1wdWJsaWMgYWJzdHJhY3QgY2xhc3MgQWJzdHJhY3RYTUxEb2N1bWVudFBhcnNlcgotICAgIGV4dGVuZHMgWE1MUGFyc2VyCi0gICAgaW1wbGVtZW50cyBYTUxEb2N1bWVudEhhbmRsZXIsIFhNTERUREhhbmRsZXIsIFhNTERURENvbnRlbnRNb2RlbEhhbmRsZXIgewotCi0gICAgLy8KLSAgICAvLyBEYXRhCi0gICAgLy8KLQotICAgIC8vIHN0YXRlCi0KLSAgICAvKiogVHJ1ZSBpZiBpbnNpZGUgRFRELiAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIGZJbkRURDsKLQotICAgIC8qKiBEb2N1bWVudCBzb3VyY2UqLwotICAgIHByb3RlY3RlZCBYTUxEb2N1bWVudFNvdXJjZSBmRG9jdW1lbnRTb3VyY2U7Ci0KLSAgICAvKiogRFREIHNvdXJjZSovCi0gICAgcHJvdGVjdGVkIFhNTERURFNvdXJjZSBmRFREU291cmNlOwotCi0gICAgLyoqIERURCBjb250ZW50IG1vZGVsIHNvdXJjZSovCi0gICAgcHJvdGVjdGVkIFhNTERURENvbnRlbnRNb2RlbFNvdXJjZSBmRFREQ29udGVudE1vZGVsU291cmNlOwotCi0gICAgLy8KLSAgICAvLyBDb25zdHJ1Y3RvcnMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0cyBhIGRvY3VtZW50IHBhcnNlciB1c2luZyB0aGUgZGVmYXVsdCBzeW1ib2wgdGFibGUKLSAgICAgKiBhbmQgZ3JhbW1hciBwb29sLgotICAgICAqLwotICAgIHByb3RlY3RlZCBBYnN0cmFjdFhNTERvY3VtZW50UGFyc2VyKFhNTFBhcnNlckNvbmZpZ3VyYXRpb24gY29uZmlnKSB7Ci0gICAgICAgIHN1cGVyKGNvbmZpZyk7Ci0KLSAgICAgICAgLy8gc2V0IGhhbmRsZXJzCi0gICAgICAgIGNvbmZpZy5zZXREb2N1bWVudEhhbmRsZXIodGhpcyk7Ci0gICAgICAgIGNvbmZpZy5zZXREVERIYW5kbGVyKHRoaXMpOwotICAgICAgICBjb25maWcuc2V0RFREQ29udGVudE1vZGVsSGFuZGxlcih0aGlzKTsKLQotICAgIH0gLy8gPGluaXQ+KFhNTFBhcnNlckNvbmZpZ3VyYXRpb24pCi0KLSAgICAvLwotICAgIC8vIFhNTERvY3VtZW50SGFuZGxlciBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFRoZSBzdGFydCBvZiB0aGUgZG9jdW1lbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbG9jYXRvciBUaGUgc3lzdGVtIGlkZW50aWZpZXIgb2YgdGhlIGVudGl0eSBpZiB0aGUgZW50aXR5Ci0gICAgICogICAgICAgICAgICAgICAgIGlzIGV4dGVybmFsLCBudWxsIG90aGVyd2lzZS4KLSAgICAgKiBAcGFyYW0gZW5jb2RpbmcgVGhlIGF1dG8tZGV0ZWN0ZWQgSUFOQSBlbmNvZGluZyBuYW1lIG9mIHRoZSBlbnRpdHkKLSAgICAgKiAgICAgICAgICAgICAgICAgc3RyZWFtLiBUaGlzIHZhbHVlIHdpbGwgYmUgbnVsbCBpbiB0aG9zZSBzaXR1YXRpb25zCi0gICAgICogICAgICAgICAgICAgICAgIHdoZXJlIHRoZSBlbnRpdHkgZW5jb2RpbmcgaXMgbm90IGF1dG8tZGV0ZWN0ZWQgKGUuZy4KLSAgICAgKiAgICAgICAgICAgICAgICAgaW50ZXJuYWwgZW50aXRpZXMgb3IgYSBkb2N1bWVudCBlbnRpdHkgdGhhdCBpcwotICAgICAqICAgICAgICAgICAgICAgICBwYXJzZWQgZnJvbSBhIGphdmEuaW8uUmVhZGVyKS4KLSAgICAgKiBAcGFyYW0gbmFtZXNwYWNlQ29udGV4dAotICAgICAqICAgICAgICAgICAgICAgICBUaGUgbmFtZXNwYWNlIGNvbnRleHQgaW4gZWZmZWN0IGF0IHRoZQotICAgICAqICAgICAgICAgICAgICAgICBzdGFydCBvZiB0aGlzIGRvY3VtZW50LgotICAgICAqICAgICAgICAgICAgICAgICBUaGlzIG9iamVjdCByZXByZXNlbnRzIHRoZSBjdXJyZW50IGNvbnRleHQuCi0gICAgICogICAgICAgICAgICAgICAgIEltcGxlbWVudG9ycyBvZiB0aGlzIGNsYXNzIGFyZSByZXNwb25zaWJsZQotICAgICAqICAgICAgICAgICAgICAgICBmb3IgY29weWluZyB0aGUgbmFtZXNwYWNlIGJpbmRpbmdzIGZyb20gdGhlCi0gICAgICogICAgICAgICAgICAgICAgIHRoZSBjdXJyZW50IGNvbnRleHQgKGFuZCBpdHMgcGFyZW50IGNvbnRleHRzKQotICAgICAqICAgICAgICAgICAgICAgICBpZiB0aGF0IGluZm9ybWF0aW9uIGlzIGltcG9ydGFudC4KLSAgICAgKiBAcGFyYW0gYXVncyAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLQotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RG9jdW1lbnQoWE1MTG9jYXRvciBsb2NhdG9yLCBTdHJpbmcgZW5jb2RpbmcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOYW1lc3BhY2VDb250ZXh0IG5hbWVzcGFjZUNvbnRleHQsIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgfSAvLyBzdGFydERvY3VtZW50KFhNTExvY2F0b3IsU3RyaW5nKQotCi0gICAgLyoqCi0gICAgICogTm90aWZpZXMgb2YgdGhlIHByZXNlbmNlIG9mIGFuIFhNTERlY2wgbGluZSBpbiB0aGUgZG9jdW1lbnQuIElmCi0gICAgICogcHJlc2VudCwgdGhpcyBtZXRob2Qgd2lsbCBiZSBjYWxsZWQgaW1tZWRpYXRlbHkgZm9sbG93aW5nIHRoZQotICAgICAqIHN0YXJ0RG9jdW1lbnQgY2FsbC4KLSAgICAgKgotICAgICAqIEBwYXJhbSB2ZXJzaW9uICAgIFRoZSBYTUwgdmVyc2lvbi4KLSAgICAgKiBAcGFyYW0gZW5jb2RpbmcgICBUaGUgSUFOQSBlbmNvZGluZyBuYW1lIG9mIHRoZSBkb2N1bWVudCwgb3IgbnVsbCBpZgotICAgICAqICAgICAgICAgICAgICAgICAgIG5vdCBzcGVjaWZpZWQuCi0gICAgICogQHBhcmFtIHN0YW5kYWxvbmUgVGhlIHN0YW5kYWxvbmUgdmFsdWUsIG9yIG51bGwgaWYgbm90IHNwZWNpZmllZC4KLSAgICAgKiBAcGFyYW0gYXVncyAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB4bWxEZWNsKFN0cmluZyB2ZXJzaW9uLCBTdHJpbmcgZW5jb2RpbmcsIFN0cmluZyBzdGFuZGFsb25lLCBBdWdtZW50YXRpb25zIGF1Z3MpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotICAgIH0gLy8geG1sRGVjbChTdHJpbmcsU3RyaW5nLFN0cmluZykKLQotICAgIC8qKgotICAgICAqIE5vdGlmaWVzIG9mIHRoZSBwcmVzZW5jZSBvZiB0aGUgRE9DVFlQRSBsaW5lIGluIHRoZSBkb2N1bWVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSByb290RWxlbWVudCBUaGUgbmFtZSBvZiB0aGUgcm9vdCBlbGVtZW50LgotICAgICAqIEBwYXJhbSBwdWJsaWNJZCAgICBUaGUgcHVibGljIGlkZW50aWZpZXIgaWYgYW4gZXh0ZXJuYWwgRFREIG9yIG51bGwKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgaWYgdGhlIGV4dGVybmFsIERURCBpcyBzcGVjaWZpZWQgdXNpbmcgU1lTVEVNLgotICAgICAqIEBwYXJhbSBzeXN0ZW1JZCAgICBUaGUgc3lzdGVtIGlkZW50aWZpZXIgaWYgYW4gZXh0ZXJuYWwgRFRELCBudWxsCi0gICAgICogQHBhcmFtIGF1Z3MgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICogICAgICAgICAgICAgICAgICAgIG90aGVyd2lzZS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBkb2N0eXBlRGVjbChTdHJpbmcgcm9vdEVsZW1lbnQsIFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkLCBBdWdtZW50YXRpb25zIGF1Z3MpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotICAgIH0gLy8gZG9jdHlwZURlY2woU3RyaW5nLFN0cmluZyxTdHJpbmcpCi0KLSAgICAvKioKLSAgICAgKiBUaGUgc3RhcnQgb2YgYW4gZWxlbWVudC4gSWYgdGhlIGRvY3VtZW50IHNwZWNpZmllcyB0aGUgc3RhcnQgZWxlbWVudAotICAgICAqIGJ5IHVzaW5nIGFuIGVtcHR5IHRhZywgdGhlbiB0aGUgc3RhcnRFbGVtZW50IG1ldGhvZCB3aWxsIGltbWVkaWF0ZWx5Ci0gICAgICogYmUgZm9sbG93ZWQgYnkgdGhlIGVuZEVsZW1lbnQgbWV0aG9kLCB3aXRoIG5vIGludGVydmVuaW5nIG1ldGhvZHMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZWxlbWVudCAgICBUaGUgbmFtZSBvZiB0aGUgZWxlbWVudC4KLSAgICAgKiBAcGFyYW0gYXR0cmlidXRlcyBUaGUgZWxlbWVudCBhdHRyaWJ1dGVzLgotICAgICAqIEBwYXJhbSBhdWdzICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudChRTmFtZSBlbGVtZW50LCBYTUxBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMsIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgfSAvLyBzdGFydEVsZW1lbnQoUU5hbWUsWE1MQXR0cmlidXRlcykKLQotICAgIC8qKgotICAgICAqIEFuIGVtcHR5IGVsZW1lbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZWxlbWVudCAgICBUaGUgbmFtZSBvZiB0aGUgZWxlbWVudC4KLSAgICAgKiBAcGFyYW0gYXR0cmlidXRlcyBUaGUgZWxlbWVudCBhdHRyaWJ1dGVzLgotICAgICAqIEBwYXJhbSBhdWdzICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVtcHR5RWxlbWVudChRTmFtZSBlbGVtZW50LCBYTUxBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMsIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgc3RhcnRFbGVtZW50KGVsZW1lbnQsIGF0dHJpYnV0ZXMsIGF1Z3MpOwotICAgICAgICBlbmRFbGVtZW50KGVsZW1lbnQsIGF1Z3MpOwotCi0gICAgfSAvLyBlbXB0eUVsZW1lbnQoUU5hbWUsWE1MQXR0cmlidXRlcykKLQotICAgIC8qKgotICAgICAqIENoYXJhY3RlciBjb250ZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIHRleHQgVGhlIGNvbnRlbnQuCi0gICAgICogQHBhcmFtIGF1Z3MgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY2hhcmFjdGVycyhYTUxTdHJpbmcgdGV4dCwgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICB9IC8vIGNoYXJhY3RlcnMoWE1MU3RyaW5nKQotCi0gICAgLyoqCi0gICAgICogSWdub3JhYmxlIHdoaXRlc3BhY2UuIEZvciB0aGlzIG1ldGhvZCB0byBiZSBjYWxsZWQsIHRoZSBkb2N1bWVudAotICAgICAqIHNvdXJjZSBtdXN0IGhhdmUgc29tZSB3YXkgb2YgZGV0ZXJtaW5pbmcgdGhhdCB0aGUgdGV4dCBjb250YWluaW5nCi0gICAgICogb25seSB3aGl0ZXNwYWNlIGNoYXJhY3RlcnMgc2hvdWxkIGJlIGNvbnNpZGVyZWQgaWdub3JhYmxlLiBGb3IKLSAgICAgKiBleGFtcGxlLCB0aGUgdmFsaWRhdG9yIGNhbiBkZXRlcm1pbmUgaWYgYSBsZW5ndGggb2Ygd2hpdGVzcGFjZQotICAgICAqIGNoYXJhY3RlcnMgaW4gdGhlIGRvY3VtZW50IGFyZSBpZ25vcmFibGUgYmFzZWQgb24gdGhlIGVsZW1lbnQKLSAgICAgKiBjb250ZW50IG1vZGVsLgotICAgICAqCi0gICAgICogQHBhcmFtIHRleHQgVGhlIGlnbm9yYWJsZSB3aGl0ZXNwYWNlLgotICAgICAqIEBwYXJhbSBhdWdzICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGlnbm9yYWJsZVdoaXRlc3BhY2UoWE1MU3RyaW5nIHRleHQsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgfSAvLyBpZ25vcmFibGVXaGl0ZXNwYWNlKFhNTFN0cmluZykKLQotICAgIC8qKgotICAgICAqIFRoZSBlbmQgb2YgYW4gZWxlbWVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlbGVtZW50IFRoZSBuYW1lIG9mIHRoZSBlbGVtZW50LgotICAgICAqIEBwYXJhbSBhdWdzICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZEVsZW1lbnQoUU5hbWUgZWxlbWVudCwgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICB9IC8vIGVuZEVsZW1lbnQoUU5hbWUpCi0KLSAgICAvKioKLSAgICAgKiBUaGUgc3RhcnQgb2YgYSBDREFUQSBzZWN0aW9uLgotICAgICAqIEBwYXJhbSBhdWdzICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0Q0RBVEEoQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICB9IC8vIHN0YXJ0Q0RBVEEoKQotCi0gICAgLyoqCi0gICAgICogVGhlIGVuZCBvZiBhIENEQVRBIHNlY3Rpb24uCi0gICAgICogQHBhcmFtIGF1Z3MgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kQ0RBVEEoQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICB9IC8vIGVuZENEQVRBKCkKLQotICAgIC8qKgotICAgICAqIFRoZSBlbmQgb2YgdGhlIGRvY3VtZW50LgotICAgICAqIEBwYXJhbSBhdWdzICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZERvY3VtZW50KEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgfSAvLyBlbmREb2N1bWVudCgpCi0KLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIG5vdGlmaWVzIHRoZSBzdGFydCBvZiBhbiBlbnRpdHkuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGlzIG1ldGhvZCBpcyBub3QgY2FsbGVkIGZvciBlbnRpdHkgcmVmZXJlbmNlcwotICAgICAqIGFwcGVhcmluZyBhcyBwYXJ0IG9mIGF0dHJpYnV0ZSB2YWx1ZXMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSAgICAgVGhlIG5hbWUgb2YgdGhlIGVudGl0eS4KLSAgICAgKiBAcGFyYW0gaWRlbnRpZmllciBUaGUgcmVzb3VyY2UgaWRlbnRpZmllci4KLSAgICAgKiBAcGFyYW0gZW5jb2RpbmcgVGhlIGF1dG8tZGV0ZWN0ZWQgSUFOQSBlbmNvZGluZyBuYW1lIG9mIHRoZSBlbnRpdHkKLSAgICAgKiAgICAgICAgICAgICAgICAgc3RyZWFtLiBUaGlzIHZhbHVlIHdpbGwgYmUgbnVsbCBpbiB0aG9zZSBzaXR1YXRpb25zCi0gICAgICogICAgICAgICAgICAgICAgIHdoZXJlIHRoZSBlbnRpdHkgZW5jb2RpbmcgaXMgbm90IGF1dG8tZGV0ZWN0ZWQgKGUuZy4KLSAgICAgKiAgICAgICAgICAgICAgICAgaW50ZXJuYWwgZW50aXRpZXMgb3IgYSBkb2N1bWVudCBlbnRpdHkgdGhhdCBpcwotICAgICAqICAgICAgICAgICAgICAgICBwYXJzZWQgZnJvbSBhIGphdmEuaW8uUmVhZGVyKS4KLSAgICAgKiBAcGFyYW0gYXVncyAgICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0R2VuZXJhbEVudGl0eShTdHJpbmcgbmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MUmVzb3VyY2VJZGVudGlmaWVyIGlkZW50aWZpZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBlbmNvZGluZywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICB9IC8vIHN0YXJ0R2VuZXJhbEVudGl0eShTdHJpbmcsWE1MUmVzb3VyY2VJZGVudGlmaWVyLFN0cmluZyxBdWdtZW50YXRpb25zKQotCi0gICAgLyoqCi0gICAgICogTm90aWZpZXMgb2YgdGhlIHByZXNlbmNlIG9mIGEgVGV4dERlY2wgbGluZSBpbiBhbiBlbnRpdHkuIElmIHByZXNlbnQsCi0gICAgICogdGhpcyBtZXRob2Qgd2lsbCBiZSBjYWxsZWQgaW1tZWRpYXRlbHkgZm9sbG93aW5nIHRoZSBzdGFydEVudGl0eSBjYWxsLgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gVGhpcyBtZXRob2Qgd2lsbCBuZXZlciBiZSBjYWxsZWQgZm9yIHRoZQotICAgICAqIGRvY3VtZW50IGVudGl0eTsgaXQgaXMgb25seSBjYWxsZWQgZm9yIGV4dGVybmFsIGdlbmVyYWwgZW50aXRpZXMKLSAgICAgKiByZWZlcmVuY2VkIGluIGRvY3VtZW50IGNvbnRlbnQuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGlzIG1ldGhvZCBpcyBub3QgY2FsbGVkIGZvciBlbnRpdHkgcmVmZXJlbmNlcwotICAgICAqIGFwcGVhcmluZyBhcyBwYXJ0IG9mIGF0dHJpYnV0ZSB2YWx1ZXMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdmVyc2lvbiAgVGhlIFhNTCB2ZXJzaW9uLCBvciBudWxsIGlmIG5vdCBzcGVjaWZpZWQuCi0gICAgICogQHBhcmFtIGVuY29kaW5nIFRoZSBJQU5BIGVuY29kaW5nIG5hbWUgb2YgdGhlIGVudGl0eS4KLSAgICAgKiBAcGFyYW0gYXVncyAgICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBYTklFeGNlcHRpb24KLSAgICAgKiAgICAgICAgICAgICAgICAgICBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdGV4dERlY2woU3RyaW5nIHZlcnNpb24sIFN0cmluZyBlbmNvZGluZywgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICB9IC8vIHRleHREZWNsKFN0cmluZywgU3RyaW5nLCBBdWdtZW50YXRpb25zKQotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2Qgbm90aWZpZXMgdGhlIGVuZCBvZiBhbiBlbnRpdHkuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGlzIG1ldGhvZCBpcyBub3QgY2FsbGVkIGZvciBlbnRpdHkgcmVmZXJlbmNlcwotICAgICAqIGFwcGVhcmluZyBhcyBwYXJ0IG9mIGF0dHJpYnV0ZSB2YWx1ZXMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSAgIFRoZSBuYW1lIG9mIHRoZSBlbnRpdHkuCi0gICAgICogQHBhcmFtIGF1Z3MgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIFhOSUV4Y2VwdGlvbgotICAgICAqICAgICAgICAgICAgICAgICAgIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbmRHZW5lcmFsRW50aXR5KFN0cmluZyBuYW1lLCBBdWdtZW50YXRpb25zIGF1Z3MpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotICAgIH0gLy8gZW5kR2VuZXJhbEVudGl0eShTdHJpbmcsQXVnbWVudGF0aW9ucykKLQotICAgIC8qKgotICAgICAqIEEgY29tbWVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSB0ZXh0ICAgVGhlIHRleHQgaW4gdGhlIGNvbW1lbnQuCi0gICAgICogQHBhcmFtIGF1Z3MgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIFhOSUV4Y2VwdGlvbgotICAgICAqICAgICAgICAgICAgICAgICAgIFRocm93biBieSBhcHBsaWNhdGlvbiB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY29tbWVudChYTUxTdHJpbmcgdGV4dCwgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICB9IC8vIGNvbW1lbnQgKFhNTFN0cmluZywgQXVnbWVudGF0aW9ucykKLQotICAgIC8qKgotICAgICAqIEEgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbi4gUHJvY2Vzc2luZyBpbnN0cnVjdGlvbnMgY29uc2lzdCBvZiBhCi0gICAgICogdGFyZ2V0IG5hbWUgYW5kLCBvcHRpb25hbGx5LCB0ZXh0IGRhdGEuIFRoZSBkYXRhIGlzIG9ubHkgbWVhbmluZ2Z1bAotICAgICAqIHRvIHRoZSBhcHBsaWNhdGlvbi4KLSAgICAgKiA8cD4KLSAgICAgKiBUeXBpY2FsbHksIGEgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbidzIGRhdGEgd2lsbCBjb250YWluIGEgc2VyaWVzCi0gICAgICogb2YgcHNldWRvLWF0dHJpYnV0ZXMuIFRoZXNlIHBzZXVkby1hdHRyaWJ1dGVzIGZvbGxvdyB0aGUgZm9ybSBvZgotICAgICAqIGVsZW1lbnQgYXR0cmlidXRlcyBidXQgYXJlIDxzdHJvbmc+bm90PC9zdHJvbmc+IHBhcnNlZCBvciBwcmVzZW50ZWQKLSAgICAgKiB0byB0aGUgYXBwbGljYXRpb24gYXMgYW55dGhpbmcgb3RoZXIgdGhhbiB0ZXh0LiBUaGUgYXBwbGljYXRpb24gaXMKLSAgICAgKiByZXNwb25zaWJsZSBmb3IgcGFyc2luZyB0aGUgZGF0YS4KLSAgICAgKgotICAgICAqIEBwYXJhbSB0YXJnZXQgVGhlIHRhcmdldC4KLSAgICAgKiBAcGFyYW0gZGF0YSAgIFRoZSBkYXRhIG9yIG51bGwgaWYgbm9uZSBzcGVjaWZpZWQuCi0gICAgICogQHBhcmFtIGF1Z3MgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIFhOSUV4Y2VwdGlvbgotICAgICAqICAgICAgICAgICAgICAgICAgIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oU3RyaW5nIHRhcmdldCwgWE1MU3RyaW5nIGRhdGEsIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgfSAvLyBwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oU3RyaW5nLCBYTUxTdHJpbmcsIEF1Z21lbnRhdGlvbnMpCi0KLQotICAgIC8qKiBTZXRzIHRoZSBkb2N1bWVudCBzb3VyY2UgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXREb2N1bWVudFNvdXJjZShYTUxEb2N1bWVudFNvdXJjZSBzb3VyY2UpewotICAgICAgICBmRG9jdW1lbnRTb3VyY2UgPSBzb3VyY2U7Ci0gICAgfSAvLyBzZXREb2N1bWVudFNvdXJjZQotCi0gICAgLyoqIFJldHVybnMgdGhlIGRvY3VtZW50IHNvdXJjZSAqLwotICAgIHB1YmxpYyBYTUxEb2N1bWVudFNvdXJjZSBnZXREb2N1bWVudFNvdXJjZSAoKXsKLSAgICAgICAgcmV0dXJuIGZEb2N1bWVudFNvdXJjZTsKLSAgICB9IC8vIGdldERvY3VtZW50U291cmNlCi0gICAgLy8KLSAgICAvLyBYTUxEVERIYW5kbGVyIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogVGhlIHN0YXJ0IG9mIHRoZSBEVEQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbG9jYXRvciAgVGhlIGRvY3VtZW50IGxvY2F0b3IsIG9yIG51bGwgaWYgdGhlIGRvY3VtZW50Ci0gICAgICogICAgICAgICAgICAgICAgIGxvY2F0aW9uIGNhbm5vdCBiZSByZXBvcnRlZCBkdXJpbmcgdGhlIHBhcnNpbmcgb2YKLSAgICAgKiAgICAgICAgICAgICAgICAgdGhlIGRvY3VtZW50IERURC4gSG93ZXZlciwgaXQgaXMgPGVtPnN0cm9uZ2x5PC9lbT4KLSAgICAgKiAgICAgICAgICAgICAgICAgcmVjb21tZW5kZWQgdGhhdCBhIGxvY2F0b3IgYmUgc3VwcGxpZWQgdGhhdCBjYW4KLSAgICAgKiAgICAgICAgICAgICAgICAgYXQgbGVhc3QgcmVwb3J0IHRoZSBiYXNlIHN5c3RlbSBpZGVudGlmaWVyIG9mIHRoZQotICAgICAqICAgICAgICAgICAgICAgICBEVEQuCi0gICAgICogQHBhcmFtIGF1Z3MgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RFREKFhNTExvY2F0b3IgbG9jYXRvciwgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgZkluRFREID0gdHJ1ZTsKLSAgICB9IC8vIHN0YXJ0RFREKFhNTExvY2F0b3IpCi0KLQotICAgIC8qKgotICAgICAqIFRoZSBzdGFydCBvZiB0aGUgRFREIGV4dGVybmFsIHN1YnNldC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBhdWdtZW50YXRpb25zIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydEV4dGVybmFsU3Vic2V0KFhNTFJlc291cmNlSWRlbnRpZmllciBpZGVudGlmaWVyLCBBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotICAgIH0gLy8gc3RhcnRFeHRlcm5hbFN1YnNldChBdWdtZW50YXRpb25zKQotCi0gICAgLyoqCi0gICAgICogVGhlIGVuZCBvZiB0aGUgRFREIGV4dGVybmFsIHN1YnNldC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBhdWdtZW50YXRpb25zIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbmRFeHRlcm5hbFN1YnNldChBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotICAgIH0gLy8gZW5kRXh0ZXJuYWxTdWJzZXQoQXVnbWVudGF0aW9ucykKLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIG5vdGlmaWVzIHRoZSBzdGFydCBvZiBhbiBlbnRpdHkuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGlzIG1ldGhvZCBpcyBub3QgY2FsbGVkIGZvciBlbnRpdHkgcmVmZXJlbmNlcwotICAgICAqIGFwcGVhcmluZyBhcyBwYXJ0IG9mIGF0dHJpYnV0ZSB2YWx1ZXMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSAgICAgVGhlIG5hbWUgb2YgdGhlIGVudGl0eS4KLSAgICAgKiBAcGFyYW0gaWRlbnRpZmllciBUaGUgcmVzb3VyY2UgaWRlbnRpZmllci4KLSAgICAgKiBAcGFyYW0gZW5jb2RpbmcgVGhlIGF1dG8tZGV0ZWN0ZWQgSUFOQSBlbmNvZGluZyBuYW1lIG9mIHRoZSBlbnRpdHkKLSAgICAgKiAgICAgICAgICAgICAgICAgc3RyZWFtLiBUaGlzIHZhbHVlIHdpbGwgYmUgbnVsbCBpbiB0aG9zZSBzaXR1YXRpb25zCi0gICAgICogICAgICAgICAgICAgICAgIHdoZXJlIHRoZSBlbnRpdHkgZW5jb2RpbmcgaXMgbm90IGF1dG8tZGV0ZWN0ZWQgKGUuZy4KLSAgICAgKiAgICAgICAgICAgICAgICAgaW50ZXJuYWwgZW50aXRpZXMgb3IgYSBkb2N1bWVudCBlbnRpdHkgdGhhdCBpcwotICAgICAqICAgICAgICAgICAgICAgICBwYXJzZWQgZnJvbSBhIGphdmEuaW8uUmVhZGVyKS4KLSAgICAgKiBAcGFyYW0gYXVncyAgICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0UGFyYW1ldGVyRW50aXR5KFN0cmluZyBuYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTFJlc291cmNlSWRlbnRpZmllciBpZGVudGlmaWVyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBlbmNvZGluZywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgIH0gLy8gc3RhcnRQYXJhbWV0ZXJFbnRpdHkoU3RyaW5nLFhNTFJlc291cmNlSWRlbnRpZmllcixTdHJpbmcsQXVnbWVudGF0aW9ucykKLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIG5vdGlmaWVzIHRoZSBlbmQgb2YgYW4gZW50aXR5LgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gVGhpcyBtZXRob2QgaXMgbm90IGNhbGxlZCBmb3IgZW50aXR5IHJlZmVyZW5jZXMKLSAgICAgKiBhcHBlYXJpbmcgYXMgcGFydCBvZiBhdHRyaWJ1dGUgdmFsdWVzLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgICBUaGUgbmFtZSBvZiB0aGUgZW50aXR5LgotICAgICAqIEBwYXJhbSBhdWdzICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBYTklFeGNlcHRpb24KLSAgICAgKiAgICAgICAgICAgICAgICAgICBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kUGFyYW1ldGVyRW50aXR5KFN0cmluZyBuYW1lLCBBdWdtZW50YXRpb25zIGF1Z3MpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotICAgIH0gLy8gZW5kUGFyYW1ldGVyRW50aXR5KFN0cmluZyxBdWdtZW50YXRpb25zKQotCi0gICAgLyoqCi0gICAgICogQ2hhcmFjdGVycyB3aXRoaW4gYW4gSUdOT1JFIGNvbmRpdGlvbmFsIHNlY3Rpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdGV4dCBUaGUgaWdub3JlZCB0ZXh0LgotICAgICAqIEBwYXJhbSBhdWdzIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICAgcHVibGljIHZvaWQgaWdub3JlZENoYXJhY3RlcnMoWE1MU3RyaW5nIHRleHQsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgIH0gLy8gaWdub3JlZENoYXJhY3RlcnMoWE1MU3RyaW5nLCBBdWdtZW50YXRpb25zKQotCi0gICAgLyoqCi0gICAgICogQW4gZWxlbWVudCBkZWNsYXJhdGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lICAgICAgICAgVGhlIG5hbWUgb2YgdGhlIGVsZW1lbnQuCi0gICAgICogQHBhcmFtIGNvbnRlbnRNb2RlbCBUaGUgZWxlbWVudCBjb250ZW50IG1vZGVsLgotICAgICAqIEBwYXJhbSBhdWdzIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbGVtZW50RGVjbChTdHJpbmcgbmFtZSwgU3RyaW5nIGNvbnRlbnRNb2RlbCwgQXVnbWVudGF0aW9ucyBhdWdzKQotICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICB9IC8vIGVsZW1lbnREZWNsKFN0cmluZyxTdHJpbmcpCi0KLSAgICAvKioKLSAgICAgKiBUaGUgc3RhcnQgb2YgYW4gYXR0cmlidXRlIGxpc3QuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZWxlbWVudE5hbWUgVGhlIG5hbWUgb2YgdGhlIGVsZW1lbnQgdGhhdCB0aGlzIGF0dHJpYnV0ZQotICAgICAqICAgICAgICAgICAgICAgICAgICBsaXN0IGlzIGFzc29jaWF0ZWQgd2l0aC4KLSAgICAgKiBAcGFyYW0gYXVncyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnRBdHRsaXN0KFN0cmluZyBlbGVtZW50TmFtZSwgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICB9IC8vIHN0YXJ0QXR0bGlzdChTdHJpbmcpCi0KLSAgICAvKioKLSAgICAgKiBBbiBhdHRyaWJ1dGUgZGVjbGFyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZWxlbWVudE5hbWUgICBUaGUgbmFtZSBvZiB0aGUgZWxlbWVudCB0aGF0IHRoaXMgYXR0cmlidXRlCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgaXMgYXNzb2NpYXRlZCB3aXRoLgotICAgICAqIEBwYXJhbSBhdHRyaWJ1dGVOYW1lIFRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUuCi0gICAgICogQHBhcmFtIHR5cGUgICAgICAgICAgVGhlIGF0dHJpYnV0ZSB0eXBlLiBUaGlzIHZhbHVlIHdpbGwgYmUgb25lIG9mCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgdGhlIGZvbGxvd2luZzogIkNEQVRBIiwgIkVOVElUWSIsICJFTlRJVElFUyIsCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgIkVOVU1FUkFUSU9OIiwgIklEIiwgIklEUkVGIiwgIklEUkVGUyIsCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgIk5NVE9LRU4iLCAiTk1UT0tFTlMiLCBvciAiTk9UQVRJT04iLgotICAgICAqIEBwYXJhbSBlbnVtZXJhdGlvbiAgIElmIHRoZSB0eXBlIGhhcyB0aGUgdmFsdWUgIkVOVU1FUkFUSU9OIiBvcgotICAgICAqICAgICAgICAgICAgICAgICAgICAgICJOT1RBVElPTiIsIHRoaXMgYXJyYXkgaG9sZHMgdGhlIGFsbG93ZWQgYXR0cmlidXRlCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgdmFsdWVzOyBvdGhlcndpc2UsIHRoaXMgYXJyYXkgaXMgbnVsbC4KLSAgICAgKiBAcGFyYW0gZGVmYXVsdFR5cGUgICBUaGUgYXR0cmlidXRlIGRlZmF1bHQgdHlwZS4gVGhpcyB2YWx1ZSB3aWxsIGJlCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgb25lIG9mIHRoZSBmb2xsb3dpbmc6ICIjRklYRUQiLCAiI0lNUExJRUQiLAotICAgICAqICAgICAgICAgICAgICAgICAgICAgICIjUkVRVUlSRUQiLCBvciBudWxsLgotICAgICAqIEBwYXJhbSBkZWZhdWx0VmFsdWUgIFRoZSBhdHRyaWJ1dGUgZGVmYXVsdCB2YWx1ZSwgb3IgbnVsbCBpZiBubwotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQgdmFsdWUgaXMgc3BlY2lmaWVkLgotICAgICAqIEBwYXJhbSBub25Ob3JtYWxpemVkRGVmYXVsdFZhbHVlICBUaGUgYXR0cmlidXRlIGRlZmF1bHQgdmFsdWUgd2l0aCBubyBub3JtYWxpemF0aW9uCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgcGVyZm9ybWVkLCBvciBudWxsIGlmIG5vIGRlZmF1bHQgdmFsdWUgaXMgc3BlY2lmaWVkLgotICAgICAqIEBwYXJhbSBhdWdzIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBhdHRyaWJ1dGVEZWNsKFN0cmluZyBlbGVtZW50TmFtZSwgU3RyaW5nIGF0dHJpYnV0ZU5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdHlwZSwgU3RyaW5nW10gZW51bWVyYXRpb24sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgZGVmYXVsdFR5cGUsIFhNTFN0cmluZyBkZWZhdWx0VmFsdWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxTdHJpbmcgbm9uTm9ybWFsaXplZERlZmF1bHRWYWx1ZSwgQXVnbWVudGF0aW9ucyBhdWdzKQotICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICB9IC8vIGF0dHJpYnV0ZURlY2woU3RyaW5nLFN0cmluZyxTdHJpbmcsU3RyaW5nW10sU3RyaW5nLFhNTFN0cmluZywgWE1MU3RyaW5nLCBBdWdtZW50YXRpb25zKQotCi0gICAgLyoqCi0gICAgICogVGhlIGVuZCBvZiBhbiBhdHRyaWJ1dGUgbGlzdC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBhdWdzIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbmRBdHRsaXN0KEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgfSAvLyBlbmRBdHRsaXN0KCkKLQotICAgIC8qKgotICAgICAqIEFuIGludGVybmFsIGVudGl0eSBkZWNsYXJhdGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBlbnRpdHkuIFBhcmFtZXRlciBlbnRpdHkgbmFtZXMgc3RhcnQgd2l0aAotICAgICAqICAgICAgICAgICAgICclJywgd2hlcmVhcyB0aGUgbmFtZSBvZiBhIGdlbmVyYWwgZW50aXR5IGlzIGp1c3QgdGhlCi0gICAgICogICAgICAgICAgICAgZW50aXR5IG5hbWUuCi0gICAgICogQHBhcmFtIHRleHQgVGhlIHZhbHVlIG9mIHRoZSBlbnRpdHkuCi0gICAgICogQHBhcmFtIG5vbk5vcm1hbGl6ZWRUZXh0IFRoZSBub24tbm9ybWFsaXplZCB2YWx1ZSBvZiB0aGUgZW50aXR5LiBUaGlzCi0gICAgICogICAgICAgICAgICAgdmFsdWUgY29udGFpbnMgdGhlIHNhbWUgc2VxdWVuY2Ugb2YgY2hhcmFjdGVycyB0aGF0IHdhcyBpbgotICAgICAqICAgICAgICAgICAgIHRoZSBpbnRlcm5hbCBlbnRpdHkgZGVjbGFyYXRpb24sIHdpdGhvdXQgYW55IGVudGl0eQotICAgICAqICAgICAgICAgICAgIHJlZmVyZW5jZXMgZXhwYW5kZWQuCi0gICAgICogQHBhcmFtIGF1Z3MgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGludGVybmFsRW50aXR5RGVjbChTdHJpbmcgbmFtZSwgWE1MU3RyaW5nIHRleHQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTFN0cmluZyBub25Ob3JtYWxpemVkVGV4dCwgQXVnbWVudGF0aW9ucyBhdWdzKQotICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICB9IC8vIGludGVybmFsRW50aXR5RGVjbChTdHJpbmcsWE1MU3RyaW5nLFhNTFN0cmluZykKLQotICAgIC8qKgotICAgICAqIEFuIGV4dGVybmFsIGVudGl0eSBkZWNsYXJhdGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lICAgICBUaGUgbmFtZSBvZiB0aGUgZW50aXR5LiBQYXJhbWV0ZXIgZW50aXR5IG5hbWVzIHN0YXJ0Ci0gICAgICogICAgICAgICAgICAgICAgIHdpdGggJyUnLCB3aGVyZWFzIHRoZSBuYW1lIG9mIGEgZ2VuZXJhbCBlbnRpdHkgaXMganVzdAotICAgICAqICAgICAgICAgICAgICAgICB0aGUgZW50aXR5IG5hbWUuCi0gICAgICogQHBhcmFtIGlkZW50aWZpZXIgICAgQW4gb2JqZWN0IGNvbnRhaW5pbmcgYWxsIGxvY2F0aW9uIGluZm9ybWF0aW9uCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgcGVydGluZW50IHRvIHRoaXMgZW50aXR5LgotICAgICAqIEBwYXJhbSBhdWdzIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBleHRlcm5hbEVudGl0eURlY2woU3RyaW5nIG5hbWUsIFhNTFJlc291cmNlSWRlbnRpZmllciBpZGVudGlmaWVyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgIH0gLy8gZXh0ZXJuYWxFbnRpdHlEZWNsKFN0cmluZyxYTUxSZXNvdXJjZUlkZW50aWZpZXIsIEF1Z21lbnRhdGlvbnMpCi0KLSAgICAvKioKLSAgICAgKiBBbiB1bnBhcnNlZCBlbnRpdHkgZGVjbGFyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSAgICAgVGhlIG5hbWUgb2YgdGhlIGVudGl0eS4KLSAgICAgKiBAcGFyYW0gaWRlbnRpZmllciAgICBBbiBvYmplY3QgY29udGFpbmluZyBhbGwgbG9jYXRpb24gaW5mb3JtYXRpb24KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBwZXJ0aW5lbnQgdG8gdGhpcyBlbnRpdHkuCi0gICAgICogQHBhcmFtIG5vdGF0aW9uIFRoZSBuYW1lIG9mIHRoZSBub3RhdGlvbi4KLSAgICAgKiBAcGFyYW0gYXVncyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdW5wYXJzZWRFbnRpdHlEZWNsKFN0cmluZyBuYW1lLCBYTUxSZXNvdXJjZUlkZW50aWZpZXIgaWRlbnRpZmllciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG5vdGF0aW9uLCBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgIH0gLy8gdW5wYXJzZWRFbnRpdHlEZWNsKFN0cmluZyxYTUxSZXNvdXJjZUlkZW50aWZpZXIsIFN0cmluZywgQXVnbWVudGF0aW9ucykKLQotICAgIC8qKgotICAgICAqIEEgbm90YXRpb24gZGVjbGFyYXRpb24KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lICAgICBUaGUgbmFtZSBvZiB0aGUgbm90YXRpb24uCi0gICAgICogQHBhcmFtIGlkZW50aWZpZXIgICAgQW4gb2JqZWN0IGNvbnRhaW5pbmcgYWxsIGxvY2F0aW9uIGluZm9ybWF0aW9uCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgcGVydGluZW50IHRvIHRoaXMgbm90YXRpb24uCi0gICAgICogQHBhcmFtIGF1Z3MgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIG5vdGF0aW9uRGVjbChTdHJpbmcgbmFtZSwgWE1MUmVzb3VyY2VJZGVudGlmaWVyIGlkZW50aWZpZXIsCi0gICAgICAgIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgfSAvLyBub3RhdGlvbkRlY2woU3RyaW5nLFhNTFJlc291cmNlSWRlbnRpZmllciwgQXVnbWVudGF0aW9ucykKLQotICAgIC8qKgotICAgICAqIFRoZSBzdGFydCBvZiBhIGNvbmRpdGlvbmFsIHNlY3Rpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdHlwZSBUaGUgdHlwZSBvZiB0aGUgY29uZGl0aW9uYWwgc2VjdGlvbi4gVGhpcyB2YWx1ZSB3aWxsCi0gICAgICogICAgICAgICAgICAgZWl0aGVyIGJlIENPTkRJVElPTkFMX0lOQ0xVREUgb3IgQ09ORElUSU9OQUxfSUdOT1JFLgotICAgICAqIEBwYXJhbSBhdWdzIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKgotICAgICAqIEBzZWUgI0NPTkRJVElPTkFMX0lOQ0xVREUKLSAgICAgKiBAc2VlICNDT05ESVRJT05BTF9JR05PUkUKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydENvbmRpdGlvbmFsKHNob3J0IHR5cGUsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiAgewotICAgIH0gLy8gc3RhcnRDb25kaXRpb25hbChzaG9ydCkKLQotICAgIC8qKgotICAgICAqIFRoZSBlbmQgb2YgYSBjb25kaXRpb25hbCBzZWN0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIGF1Z3MgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZENvbmRpdGlvbmFsKEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgfSAvLyBlbmRDb25kaXRpb25hbCgpCi0KLSAgICAvKioKLSAgICAgKiBUaGUgZW5kIG9mIHRoZSBEVEQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYXVncyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kRFREKEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIGZJbkRURCA9IGZhbHNlOwotICAgIH0gLy8gZW5kRFREKCkKLQotICAgIC8vIHNldCB0aGUgc291cmNlIG9mIHRoaXMgaGFuZGxlcgotICAgIHB1YmxpYyB2b2lkIHNldERURFNvdXJjZShYTUxEVERTb3VyY2Ugc291cmNlKSB7Ci0gICAgICAgIGZEVERTb3VyY2UgPSBzb3VyY2U7Ci0gICAgfQotCi0gICAgLy8gcmV0dXJuIHRoZSBzb3VyY2UgZnJvbSB3aGljaCB0aGlzIGhhbmRsZXIgZGVyaXZlcyBpdHMgZXZlbnRzCi0gICAgcHVibGljIFhNTERURFNvdXJjZSBnZXREVERTb3VyY2UoKSB7Ci0gICAgICAgIHJldHVybiBmRFREU291cmNlOwotICAgIH0KLQotICAgIC8vCi0gICAgLy8gWE1MRFREQ29udGVudE1vZGVsSGFuZGxlciBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFRoZSBzdGFydCBvZiBhIGNvbnRlbnQgbW9kZWwuIERlcGVuZGluZyBvbiB0aGUgdHlwZSBvZiB0aGUgY29udGVudAotICAgICAqIG1vZGVsLCBzcGVjaWZpYyBtZXRob2RzIG1heSBiZSBjYWxsZWQgYmV0d2VlbiB0aGUgY2FsbCB0byB0aGUKLSAgICAgKiBzdGFydENvbnRlbnRNb2RlbCBtZXRob2QgYW5kIHRoZSBjYWxsIHRvIHRoZSBlbmRDb250ZW50TW9kZWwgbWV0aG9kLgotICAgICAqCi0gICAgICogQHBhcmFtIGVsZW1lbnROYW1lIFRoZSBuYW1lIG9mIHRoZSBlbGVtZW50LgotICAgICAqIEBwYXJhbSBhdWdzIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydENvbnRlbnRNb2RlbChTdHJpbmcgZWxlbWVudE5hbWUsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgfSAvLyBzdGFydENvbnRlbnRNb2RlbChTdHJpbmcsIEF1Z21lbnRhdGlvbnMpCi0KLSAgICAvKioKLSAgICAgKiBBIGNvbnRlbnQgbW9kZWwgb2YgQU5ZLgotICAgICAqCi0gICAgICogQHBhcmFtIGF1Z3MgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqCi0gICAgICogQHNlZSAjZW1wdHkKLSAgICAgKiBAc2VlICNzdGFydEdyb3VwCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgYW55KEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgfSAvLyBhbnkoQXVnbWVudGF0aW9ucykKLQotICAgIC8qKgotICAgICAqIEEgY29udGVudCBtb2RlbCBvZiBFTVBUWS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBhdWdzIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKgotICAgICAqIEBzZWUgI2FueQotICAgICAqIEBzZWUgI3N0YXJ0R3JvdXAKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbXB0eShBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgIH0gLy8gZW1wdHkoQXVnbWVudGF0aW9ucykKLQotICAgIC8qKgotICAgICAqIEEgc3RhcnQgb2YgZWl0aGVyIGEgbWl4ZWQgb3IgY2hpbGRyZW4gY29udGVudCBtb2RlbC4gQSBtaXhlZAotICAgICAqIGNvbnRlbnQgbW9kZWwgd2lsbCBpbW1lZGlhdGVseSBiZSBmb2xsb3dlZCBieSBhIGNhbGwgdG8gdGhlCi0gICAgICogPGNvZGU+cGNkYXRhKCk8L2NvZGU+IG1ldGhvZC4gQSBjaGlsZHJlbiBjb250ZW50IG1vZGVsIHdpbGwKLSAgICAgKiBjb250YWluIGFkZGl0aW9uYWwgZ3JvdXBzIGFuZC9vciBlbGVtZW50cy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBhdWdzIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKgotICAgICAqIEBzZWUgI2FueQotICAgICAqIEBzZWUgI2VtcHR5Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnRHcm91cChBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgIH0gLy8gc3RhcmdHcm91cChBdWdtZW50YXRpb25zKQotCi0gICAgLyoqCi0gICAgICogVGhlIGFwcGVhcmFuY2Ugb2YgIiNQQ0RBVEEiIHdpdGhpbiBhIGdyb3VwIHNpZ25pZnlpbmcgYQotICAgICAqIG1peGVkIGNvbnRlbnQgbW9kZWwuIFRoaXMgbWV0aG9kIHdpbGwgYmUgdGhlIGZpcnN0IGNhbGxlZAotICAgICAqIGZvbGxvd2luZyB0aGUgY29udGVudCBtb2RlbCdzIDxjb2RlPnN0YXJ0R3JvdXAoKTwvY29kZT4uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYXVncyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICoKLSAgICAgKiBAc2VlICNzdGFydEdyb3VwCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcGNkYXRhKEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgfSAvLyBwY2RhdGEoQXVnbWVudGF0aW9ucykKLQotICAgIC8qKgotICAgICAqIEEgcmVmZXJlbmNlZCBlbGVtZW50IGluIGEgbWl4ZWQgb3IgY2hpbGRyZW4gY29udGVudCBtb2RlbC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlbGVtZW50TmFtZSBUaGUgbmFtZSBvZiB0aGUgcmVmZXJlbmNlZCBlbGVtZW50LgotICAgICAqIEBwYXJhbSBhdWdzIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbGVtZW50KFN0cmluZyBlbGVtZW50TmFtZSwgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICB9IC8vIGVsZW1lbnQoU3RyaW5nLCBBdWdtZW50YXRpb25zKQotCi0gICAgLyoqCi0gICAgICogVGhlIHNlcGFyYXRvciBiZXR3ZWVuIGNob2ljZXMgb3Igc2VxdWVuY2VzIG9mIGEgbWl4ZWQgb3IgY2hpbGRyZW4KLSAgICAgKiBjb250ZW50IG1vZGVsLgotICAgICAqCi0gICAgICogQHBhcmFtIHNlcGFyYXRvciBUaGUgdHlwZSBvZiBjaGlsZHJlbiBzZXBhcmF0b3IuCi0gICAgICogQHBhcmFtIGF1Z3MgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqCi0gICAgICogQHNlZSAjU0VQQVJBVE9SX0NIT0lDRQotICAgICAqIEBzZWUgI1NFUEFSQVRPUl9TRVFVRU5DRQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNlcGFyYXRvcihzaG9ydCBzZXBhcmF0b3IsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgfSAvLyBzZXBhcmF0b3Ioc2hvcnQsIEF1Z21lbnRhdGlvbnMpCi0KLSAgICAvKioKLSAgICAgKiBUaGUgb2NjdXJyZW5jZSBjb3VudCBmb3IgYSBjaGlsZCBpbiBhIGNoaWxkcmVuIGNvbnRlbnQgbW9kZWwgb3IKLSAgICAgKiBmb3IgdGhlIG1peGVkIGNvbnRlbnQgbW9kZWwgZ3JvdXAuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gb2NjdXJyZW5jZSBUaGUgb2NjdXJyZW5jZSBjb3VudCBmb3IgdGhlIGxhc3QgZWxlbWVudAotICAgICAqICAgICAgICAgICAgICAgICAgIG9yIGdyb3VwLgotICAgICAqIEBwYXJhbSBhdWdzIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKgotICAgICAqIEBzZWUgI09DQ1VSU19aRVJPX09SX09ORQotICAgICAqIEBzZWUgI09DQ1VSU19aRVJPX09SX01PUkUKLSAgICAgKiBAc2VlICNPQ0NVUlNfT05FX09SX01PUkUKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBvY2N1cnJlbmNlKHNob3J0IG9jY3VycmVuY2UsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgfSAvLyBvY2N1cmVuY2Uoc2hvcnQsIEF1Z21lbnRhdGlvbnMpCi0KLSAgICAvKioKLSAgICAgKiBUaGUgZW5kIG9mIGEgZ3JvdXAgZm9yIG1peGVkIG9yIGNoaWxkcmVuIGNvbnRlbnQgbW9kZWxzLgotICAgICAqCi0gICAgICogQHBhcmFtIGF1Z3MgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZEdyb3VwKEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgfSAvLyBlbmRHcm91cChBdWdtZW50YXRpb25zKQotCi0gICAgLyoqCi0gICAgICogVGhlIGVuZCBvZiBhIGNvbnRlbnQgbW9kZWwuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYXVncyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kQ29udGVudE1vZGVsKEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgfSAvLyBlbmRDb250ZW50TW9kZWwoQXVnbWVudGF0aW9ucykKLQotICAgIC8vIHNldCBjb250ZW50IG1vZGVsIHNvdXJjZQotICAgIHB1YmxpYyB2b2lkIHNldERURENvbnRlbnRNb2RlbFNvdXJjZShYTUxEVERDb250ZW50TW9kZWxTb3VyY2Ugc291cmNlKSB7Ci0gICAgICAgIGZEVERDb250ZW50TW9kZWxTb3VyY2UgPSBzb3VyY2U7Ci0gICAgfQotCi0gICAgLy8gZ2V0IGNvbnRlbnQgbW9kZWwgc291cmNlCi0gICAgcHVibGljIFhNTERURENvbnRlbnRNb2RlbFNvdXJjZSBnZXREVERDb250ZW50TW9kZWxTb3VyY2UoKSB7Ci0gICAgICAgIHJldHVybiBmRFREQ29udGVudE1vZGVsU291cmNlOwotICAgIH0KLQotICAgIC8vCi0gICAgLy8gUHJvdGVjdGVkIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogcmVzZXQgYWxsIGNvbXBvbmVudHMgYmVmb3JlIHBhcnNpbmcKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCByZXNldCgpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBzdXBlci5yZXNldCgpOwotICAgICAgICBmSW5EVEQgPSBmYWxzZTsKLSAgICB9IC8vIHJlc2V0KCkKLQotfSAvLyBjbGFzcyBBYnN0cmFjdFhNTERvY3VtZW50UGFyc2VyCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9wYXJzZXJzL0Jhc2ljUGFyc2VyQ29uZmlndXJhdGlvbi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvcGFyc2Vycy9CYXNpY1BhcnNlckNvbmZpZ3VyYXRpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggM2IzNTI5Ni4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9wYXJzZXJzL0Jhc2ljUGFyc2VyQ29uZmlndXJhdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTg2ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5wYXJzZXJzOwotCi1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwotaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwotaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5GZWF0dXJlU3RhdGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlBhcnNlckNvbmZpZ3VyYXRpb25TZXR0aW5nczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuUHJvcGVydHlTdGF0ZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuU3RhdHVzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5TeW1ib2xUYWJsZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxEVERDb250ZW50TW9kZWxIYW5kbGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTERUREhhbmRsZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MRG9jdW1lbnRIYW5kbGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhOSUV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MQ29tcG9uZW50OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxDb21wb25lbnRNYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxEb2N1bWVudFNvdXJjZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MRW50aXR5UmVzb2x2ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTEVycm9ySGFuZGxlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MSW5wdXRTb3VyY2U7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTFBhcnNlckNvbmZpZ3VyYXRpb247Ci0KLS8qKgotICogQSB2ZXJ5IGJhc2ljIHBhcnNlciBjb25maWd1cmF0aW9uLiBUaGlzIGNvbmZpZ3VyYXRpb24gY2xhc3MgY2FuCi0gKiBiZSB1c2VkIGFzIGEgYmFzZSBjbGFzcyBmb3IgY3VzdG9tIHBhcnNlciBjb25maWd1cmF0aW9ucy4gVGhlCi0gKiBiYXNpYyBwYXJzZXIgY29uZmlndXJhdGlvbiBjcmVhdGVzIHRoZSBzeW1ib2wgdGFibGUgKGlmIG5vdAotICogc3BlY2lmaWVkIGF0IGNvbnN0cnVjdGlvbiB0aW1lKSBhbmQgbWFuYWdlcyBhbGwgb2YgdGhlIHJlY29nbml6ZWQKLSAqIGZlYXR1cmVzIGFuZCBwcm9wZXJ0aWVzLgotICogPHA+Ci0gKiBUaGUgYmFzaWMgcGFyc2VyIGNvbmZpZ3VyYXRpb24gZG9lcyA8c3Ryb25nPm5vdDwvc3Ryb25nPiBtYW5kYXRlCi0gKiBhbnkgcGFydGljdWxhciBwaXBlbGluZSBjb25maWd1cmF0aW9uIG9yIHRoZSB1c2Ugb2Ygc3BlY2lmaWMKLSAqIGNvbXBvbmVudHMgZXhjZXB0IGZvciB0aGUgc3ltYm9sIHRhYmxlLiBJZiBldmVuIHRoaXMgaXMgdG9vIG11Y2gKLSAqIGZvciBhIGJhc2ljIHBhcnNlciBjb25maWd1cmF0aW9uLCB0aGUgcHJvZ3JhbW1lciBjYW4gY3JlYXRlIGEgbmV3Ci0gKiBjb25maWd1cmF0aW9uIGNsYXNzIHRoYXQgaW1wbGVtZW50cyB0aGUKLSAqIDxjb2RlPlhNTFBhcnNlckNvbmZpZ3VyYXRpb248L2NvZGU+IGludGVyZmFjZS4KLSAqIDxwPgotICogU3ViY2xhc3NlcyBvZiB0aGUgYmFzaWMgcGFyc2VyIGNvbmZpZ3VyYXRpb24gY2FuIGFkZCB0aGVpciBvd24KLSAqIHJlY29nbml6ZWQgZmVhdHVyZXMgYW5kIHByb3BlcnRpZXMgYnkgY2FsbGluZyB0aGUKLSAqIDxjb2RlPmFkZFJlY29nbml6ZWRGZWF0dXJlPC9jb2RlPiBhbmQKLSAqIDxjb2RlPmFkZFJlY29nbml6ZWRQcm9wZXJ0eTwvY29kZT4gbWV0aG9kcywgcmVzcGVjdGl2ZWx5LgotICogPHA+Ci0gKiBUaGUgYmFzaWMgcGFyc2VyIGNvbmZpZ3VyYXRpb24gYXNzdW1lcyB0aGF0IHRoZSBjb25maWd1cmF0aW9uCi0gKiB3aWxsIGJlIG1hZGUgdXAgb2YgdmFyaW91cyBwYXJzZXIgY29tcG9uZW50cyB0aGF0IGltcGxlbWVudCB0aGUKLSAqIDxjb2RlPlhNTENvbXBvbmVudDwvY29kZT4gaW50ZXJmYWNlLiBJZiBzdWJjbGFzc2VzIG9mIHRoaXMKLSAqIGNvbmZpZ3VyYXRpb24gY3JlYXRlIHRoZWlyIG93biBjb21wb25lbnRzIGZvciB1c2UgaW4gdGhlCi0gKiBwYXJzZXIgY29uZmlndXJhdGlvbiwgdGhlbiBlYWNoIGNvbXBvbmVudCBzaG91bGQgYmUgYWRkZWQgdG8KLSAqIHRoZSBsaXN0IG9mIGNvbXBvbmVudHMgYnkgY2FsbGluZyB0aGUgPGNvZGU+YWRkQ29tcG9uZW50PC9jb2RlPgotICogbWV0aG9kLiBUaGUgYmFzaWMgcGFyc2VyIGNvbmZpZ3VyYXRpb24gd2lsbCBtYWtlIHN1cmUgdG8gY2FsbAotICogdGhlIDxjb2RlPnJlc2V0PC9jb2RlPiBtZXRob2Qgb2YgZWFjaCByZWdpc3RlcmVkIGNvbXBvbmVudAotICogYmVmb3JlIHBhcnNpbmcgYW4gaW5zdGFuY2UgZG9jdW1lbnQuCi0gKiA8cD4KLSAqIFRoaXMgY2xhc3MgcmVjb2duaXplcyB0aGUgZm9sbG93aW5nIGZlYXR1cmVzIGFuZCBwcm9wZXJ0aWVzOgotICogPHVsPgotICogPGxpPkZlYXR1cmVzCi0gKiAgPHVsPgotICogICA8bGk+aHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL3ZhbGlkYXRpb248L2xpPgotICogICA8bGk+aHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL25hbWVzcGFjZXM8L2xpPgotICogICA8bGk+aHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL2V4dGVybmFsLWdlbmVyYWwtZW50aXRpZXM8L2xpPgotICogICA8bGk+aHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL2V4dGVybmFsLXBhcmFtZXRlci1lbnRpdGllczwvbGk+Ci0gKiAgPC91bD4KLSAqIDxsaT5Qcm9wZXJ0aWVzCi0gKiAgPHVsPgotICogICA8bGk+aHR0cDovL3htbC5vcmcvc2F4L3Byb3BlcnRpZXMveG1sLXN0cmluZzwvbGk+Ci0gKiAgIDxsaT5odHRwOi8vYXBhY2hlLm9yZy94bWwvcHJvcGVydGllcy9pbnRlcm5hbC9zeW1ib2wtdGFibGU8L2xpPgotICogICA8bGk+aHR0cDovL2FwYWNoZS5vcmcveG1sL3Byb3BlcnRpZXMvaW50ZXJuYWwvZXJyb3ItaGFuZGxlcjwvbGk+Ci0gKiAgIDxsaT5odHRwOi8vYXBhY2hlLm9yZy94bWwvcHJvcGVydGllcy9pbnRlcm5hbC9lbnRpdHktcmVzb2x2ZXI8L2xpPgotICogIDwvdWw+Ci0gKiA8L3VsPgotICoKLSAqIEBhdXRob3IgQXJuYXVkICBMZSBIb3JzLCBJQk0KLSAqIEBhdXRob3IgQW5keSBDbGFyaywgSUJNCi0gKgotICogQHZlcnNpb24gJElkOiBCYXNpY1BhcnNlckNvbmZpZ3VyYXRpb24uamF2YSx2IDEuNiAyMDEwLTExLTAxIDA0OjQwOjA5IGpvZWh3IEV4cCAkCi0gKi8KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBCYXNpY1BhcnNlckNvbmZpZ3VyYXRpb24KLSAgICBleHRlbmRzIFBhcnNlckNvbmZpZ3VyYXRpb25TZXR0aW5ncwotICAgIGltcGxlbWVudHMgWE1MUGFyc2VyQ29uZmlndXJhdGlvbiB7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0YW50cwotICAgIC8vCi0KLSAgICAvLyBmZWF0dXJlIGlkZW50aWZpZXJzCi0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiB2YWxpZGF0aW9uLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFZBTElEQVRJT04gPQotICAgICAgICBDb25zdGFudHMuU0FYX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLlZBTElEQVRJT05fRkVBVFVSRTsKLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IG5hbWVzcGFjZXMuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgTkFNRVNQQUNFUyA9Ci0gICAgICAgIENvbnN0YW50cy5TQVhfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuTkFNRVNQQUNFU19GRUFUVVJFOwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogZXh0ZXJuYWwgZ2VuZXJhbCBlbnRpdGllcy4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBFWFRFUk5BTF9HRU5FUkFMX0VOVElUSUVTID0KLSAgICAgICAgQ29uc3RhbnRzLlNBWF9GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5FWFRFUk5BTF9HRU5FUkFMX0VOVElUSUVTX0ZFQVRVUkU7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiBleHRlcm5hbCBwYXJhbWV0ZXIgZW50aXRpZXMuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVhURVJOQUxfUEFSQU1FVEVSX0VOVElUSUVTID0KLSAgICAgICAgQ29uc3RhbnRzLlNBWF9GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5FWFRFUk5BTF9QQVJBTUVURVJfRU5USVRJRVNfRkVBVFVSRTsKLQotICAgIC8vIHByb3BlcnR5IGlkZW50aWZpZXJzCi0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogeG1sIHN0cmluZy4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxfU1RSSU5HID0KLSAgICAgICAgQ29uc3RhbnRzLlNBWF9QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuWE1MX1NUUklOR19QUk9QRVJUWTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBzeW1ib2wgdGFibGUuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1lNQk9MX1RBQkxFID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuU1lNQk9MX1RBQkxFX1BST1BFUlRZOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IGVycm9yIGhhbmRsZXIuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJST1JfSEFORExFUiA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLkVSUk9SX0hBTkRMRVJfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogZW50aXR5IHJlc29sdmVyLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIEVOVElUWV9SRVNPTFZFUiA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLkVOVElUWV9SRVNPTFZFUl9QUk9QRVJUWTsKLQotICAgIC8vCi0gICAgLy8gRGF0YQotICAgIC8vCi0KLSAgICAvLyBjb21wb25lbnRzIChub24tY29uZmlndXJhYmxlKQotCi0gICAgLyoqIFN5bWJvbCB0YWJsZS4gKi8KLSAgICBwcm90ZWN0ZWQgU3ltYm9sVGFibGUgZlN5bWJvbFRhYmxlOwotCi0KLSAgICAvLyBkYXRhCi0KLSAgICAvKiogTG9jYWxlLiAqLwotICAgIHByb3RlY3RlZCBMb2NhbGUgZkxvY2FsZTsKLQotICAgIC8qKiBDb21wb25lbnRzLiAqLwotICAgIHByb3RlY3RlZCBBcnJheUxpc3QgZkNvbXBvbmVudHM7Ci0KLSAgICAvLyBoYW5kbGVycwotCi0gICAgLyoqIFRoZSBkb2N1bWVudCBoYW5kbGVyLiAqLwotICAgIHByb3RlY3RlZCBYTUxEb2N1bWVudEhhbmRsZXIgZkRvY3VtZW50SGFuZGxlcjsKLQotICAgIC8qKiBUaGUgRFREIGhhbmRsZXIuICovCi0gICAgcHJvdGVjdGVkIFhNTERUREhhbmRsZXIgZkRUREhhbmRsZXI7Ci0KLSAgICAvKiogVGhlIERURCBjb250ZW50IG1vZGVsIGhhbmRsZXIuICovCi0gICAgcHJvdGVjdGVkIFhNTERURENvbnRlbnRNb2RlbEhhbmRsZXIgZkRURENvbnRlbnRNb2RlbEhhbmRsZXI7Ci0KLSAgICAvKiogTGFzdCBjb21wb25lbnQgaW4gdGhlIGRvY3VtZW50IHBpcGVsaW5lICovCi0gICAgcHJvdGVjdGVkIFhNTERvY3VtZW50U291cmNlIGZMYXN0Q29tcG9uZW50OwotCi0gICAgLy8KLSAgICAvLyBDb25zdHJ1Y3RvcnMKLSAgICAvLwotCi0gICAgLyoqIERlZmF1bHQgQ29uc3RydWN0b3IuICovCi0gICAgcHJvdGVjdGVkIEJhc2ljUGFyc2VyQ29uZmlndXJhdGlvbigpIHsKLSAgICAgICAgdGhpcyhudWxsLCBudWxsKTsKLSAgICB9IC8vIDxpbml0PigpCi0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RzIGEgcGFyc2VyIGNvbmZpZ3VyYXRpb24gdXNpbmcgdGhlIHNwZWNpZmllZCBzeW1ib2wgdGFibGUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc3ltYm9sVGFibGUgVGhlIHN5bWJvbCB0YWJsZSB0byB1c2UuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIEJhc2ljUGFyc2VyQ29uZmlndXJhdGlvbihTeW1ib2xUYWJsZSBzeW1ib2xUYWJsZSkgewotICAgICAgICB0aGlzKHN5bWJvbFRhYmxlLCBudWxsKTsKLSAgICB9IC8vIDxpbml0PihTeW1ib2xUYWJsZSkKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHMgYSBwYXJzZXIgY29uZmlndXJhdGlvbiB1c2luZyB0aGUgc3BlY2lmaWVkIHN5bWJvbCB0YWJsZQotICAgICAqIGFuZCBwYXJlbnQgc2V0dGluZ3MuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc3ltYm9sVGFibGUgICAgVGhlIHN5bWJvbCB0YWJsZSB0byB1c2UuCi0gICAgICogQHBhcmFtIHBhcmVudFNldHRpbmdzIFRoZSBwYXJlbnQgc2V0dGluZ3MuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIEJhc2ljUGFyc2VyQ29uZmlndXJhdGlvbihTeW1ib2xUYWJsZSBzeW1ib2xUYWJsZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTENvbXBvbmVudE1hbmFnZXIgcGFyZW50U2V0dGluZ3MpIHsKLSAgICAgICAgc3VwZXIocGFyZW50U2V0dGluZ3MpOwotCi0gICAgICAgIC8vIGNyZWF0ZSBhIHZlY3RvciB0byBob2xkIGFsbCB0aGUgY29tcG9uZW50cyBpbiB1c2UKLSAgICAgICAgZkNvbXBvbmVudHMgPSBuZXcgQXJyYXlMaXN0KCk7Ci0KLSAgICAgICAgLy8gY3JlYXRlIHRhYmxlIGZvciBmZWF0dXJlcyBhbmQgcHJvcGVydGllcwotICAgICAgICBmRmVhdHVyZXMgPSBuZXcgSGFzaE1hcCgpOwotICAgICAgICBmUHJvcGVydGllcyA9IG5ldyBIYXNoTWFwKCk7Ci0KLSAgICAgICAgLy8gYWRkIGRlZmF1bHQgcmVjb2duaXplZCBmZWF0dXJlcwotICAgICAgICBmaW5hbCBTdHJpbmdbXSByZWNvZ25pemVkRmVhdHVyZXMgPSB7Ci0gICAgICAgICAgICAgICAgUEFSU0VSX1NFVFRJTkdTLAotICAgICAgICAgICAgVkFMSURBVElPTiwKLSAgICAgICAgICAgIE5BTUVTUEFDRVMsCi0gICAgICAgICAgICBFWFRFUk5BTF9HRU5FUkFMX0VOVElUSUVTLAotICAgICAgICAgICAgRVhURVJOQUxfUEFSQU1FVEVSX0VOVElUSUVTLAotICAgICAgICB9OwotICAgICAgICBhZGRSZWNvZ25pemVkRmVhdHVyZXMocmVjb2duaXplZEZlYXR1cmVzKTsKLSAgICAgICAgZkZlYXR1cmVzLnB1dChQQVJTRVJfU0VUVElOR1MsIEJvb2xlYW4uVFJVRSk7Ci0gICAgICAgIC8vIHNldCBzdGF0ZSBmb3IgZGVmYXVsdCBmZWF0dXJlcwotICAgICAgICAgICAgICAgIGZGZWF0dXJlcy5wdXQoVkFMSURBVElPTiwgQm9vbGVhbi5GQUxTRSk7Ci0gICAgICAgICAgICAgICAgZkZlYXR1cmVzLnB1dChOQU1FU1BBQ0VTLCBCb29sZWFuLlRSVUUpOwotICAgICAgICAgICAgICAgIGZGZWF0dXJlcy5wdXQoRVhURVJOQUxfR0VORVJBTF9FTlRJVElFUywgQm9vbGVhbi5UUlVFKTsKLSAgICAgICAgICAgICAgICBmRmVhdHVyZXMucHV0KEVYVEVSTkFMX1BBUkFNRVRFUl9FTlRJVElFUywgQm9vbGVhbi5UUlVFKTsKLQotICAgICAgICAvLyBhZGQgZGVmYXVsdCByZWNvZ25pemVkIHByb3BlcnRpZXMKLSAgICAgICAgZmluYWwgU3RyaW5nW10gcmVjb2duaXplZFByb3BlcnRpZXMgPSB7Ci0gICAgICAgICAgICBYTUxfU1RSSU5HLAotICAgICAgICAgICAgU1lNQk9MX1RBQkxFLAotICAgICAgICAgICAgRVJST1JfSEFORExFUiwKLSAgICAgICAgICAgIEVOVElUWV9SRVNPTFZFUiwKLSAgICAgICAgfTsKLSAgICAgICAgYWRkUmVjb2duaXplZFByb3BlcnRpZXMocmVjb2duaXplZFByb3BlcnRpZXMpOwotCi0gICAgICAgIGlmIChzeW1ib2xUYWJsZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBzeW1ib2xUYWJsZSA9IG5ldyBTeW1ib2xUYWJsZSgpOwotICAgICAgICB9Ci0gICAgICAgIGZTeW1ib2xUYWJsZSA9IHN5bWJvbFRhYmxlOwotICAgICAgICBmUHJvcGVydGllcy5wdXQoU1lNQk9MX1RBQkxFLCBmU3ltYm9sVGFibGUpOwotCi0gICAgfSAvLyA8aW5pdD4oU3ltYm9sVGFibGUpCi0KLSAgICAvKioKLSAgICAgKiBBZGRzIGEgY29tcG9uZW50IHRvIHRoZSBwYXJzZXIgY29uZmlndXJhdGlvbi4gVGhpcyBtZXRob2Qgd2lsbAotICAgICAqIGFsc28gYWRkIGFsbCBvZiB0aGUgY29tcG9uZW50J3MgcmVjb2duaXplZCBmZWF0dXJlcyBhbmQgcHJvcGVydGllcwotICAgICAqIHRvIHRoZSBsaXN0IG9mIGRlZmF1bHQgcmVjb2duaXplZCBmZWF0dXJlcyBhbmQgcHJvcGVydGllcy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjb21wb25lbnQgVGhlIGNvbXBvbmVudCB0byBhZGQuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgYWRkQ29tcG9uZW50KFhNTENvbXBvbmVudCBjb21wb25lbnQpIHsKLQotICAgICAgICAvLyBkb24ndCBhZGQgYSBjb21wb25lbnQgbW9yZSB0aGFuIG9uY2UKLSAgICAgICAgaWYgKGZDb21wb25lbnRzLmNvbnRhaW5zKGNvbXBvbmVudCkpIHsKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotICAgICAgICBmQ29tcG9uZW50cy5hZGQoY29tcG9uZW50KTsKLQotICAgICAgICAvLyByZWdpc3RlciBjb21wb25lbnQncyByZWNvZ25pemVkIGZlYXR1cmVzCi0gICAgICAgIFN0cmluZ1tdIHJlY29nbml6ZWRGZWF0dXJlcyA9IGNvbXBvbmVudC5nZXRSZWNvZ25pemVkRmVhdHVyZXMoKTsKLSAgICAgICAgYWRkUmVjb2duaXplZEZlYXR1cmVzKHJlY29nbml6ZWRGZWF0dXJlcyk7Ci0KLSAgICAgICAgLy8gcmVnaXN0ZXIgY29tcG9uZW50J3MgcmVjb2duaXplZCBwcm9wZXJ0aWVzCi0gICAgICAgIFN0cmluZ1tdIHJlY29nbml6ZWRQcm9wZXJ0aWVzID0gY29tcG9uZW50LmdldFJlY29nbml6ZWRQcm9wZXJ0aWVzKCk7Ci0gICAgICAgIGFkZFJlY29nbml6ZWRQcm9wZXJ0aWVzKHJlY29nbml6ZWRQcm9wZXJ0aWVzKTsKLQotICAgICAgICAvLyBzZXQgZGVmYXVsdCB2YWx1ZXMKLSAgICAgICAgaWYgKHJlY29nbml6ZWRGZWF0dXJlcyAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlY29nbml6ZWRGZWF0dXJlcy5sZW5ndGg7IGkrKykgewotICAgICAgICAgICAgICAgIFN0cmluZyBmZWF0dXJlSWQgPSByZWNvZ25pemVkRmVhdHVyZXNbaV07Ci0gICAgICAgICAgICAgICAgQm9vbGVhbiBzdGF0ZSA9IGNvbXBvbmVudC5nZXRGZWF0dXJlRGVmYXVsdChmZWF0dXJlSWQpOwotICAgICAgICAgICAgICAgIGlmIChzdGF0ZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIHN1cGVyLnNldEZlYXR1cmUoZmVhdHVyZUlkLCBzdGF0ZS5ib29sZWFuVmFsdWUoKSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGlmIChyZWNvZ25pemVkUHJvcGVydGllcyAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlY29nbml6ZWRQcm9wZXJ0aWVzLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIHByb3BlcnR5SWQgPSByZWNvZ25pemVkUHJvcGVydGllc1tpXTsKLSAgICAgICAgICAgICAgICBPYmplY3QgdmFsdWUgPSBjb21wb25lbnQuZ2V0UHJvcGVydHlEZWZhdWx0KHByb3BlcnR5SWQpOwotICAgICAgICAgICAgICAgIGlmICh2YWx1ZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIHN1cGVyLnNldFByb3BlcnR5KHByb3BlcnR5SWQsIHZhbHVlKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgIH0gLy8gYWRkQ29tcG9uZW50KFhNTENvbXBvbmVudCkKLQotICAgIC8vCi0gICAgLy8gWE1MUGFyc2VyQ29uZmlndXJhdGlvbiBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFBhcnNlIGFuIFhNTCBkb2N1bWVudC4KLSAgICAgKiA8cD4KLSAgICAgKiBUaGUgcGFyc2VyIGNhbiB1c2UgdGhpcyBtZXRob2QgdG8gaW5zdHJ1Y3QgdGhpcyBjb25maWd1cmF0aW9uCi0gICAgICogdG8gYmVnaW4gcGFyc2luZyBhbiBYTUwgZG9jdW1lbnQgZnJvbSBhbnkgdmFsaWQgaW5wdXQgc291cmNlCi0gICAgICogKGEgY2hhcmFjdGVyIHN0cmVhbSwgYSBieXRlIHN0cmVhbSwgb3IgYSBVUkkpLgotICAgICAqIDxwPgotICAgICAqIFBhcnNlcnMgbWF5IG5vdCBpbnZva2UgdGhpcyBtZXRob2Qgd2hpbGUgYSBwYXJzZSBpcyBpbiBwcm9ncmVzcy4KLSAgICAgKiBPbmNlIGEgcGFyc2UgaXMgY29tcGxldGUsIHRoZSBwYXJzZXIgbWF5IHRoZW4gcGFyc2UgYW5vdGhlciBYTUwKLSAgICAgKiBkb2N1bWVudC4KLSAgICAgKiA8cD4KLSAgICAgKiBUaGlzIG1ldGhvZCBpcyBzeW5jaHJvbm91czogaXQgd2lsbCBub3QgcmV0dXJuIHVudGlsIHBhcnNpbmcKLSAgICAgKiBoYXMgZW5kZWQuICBJZiBhIGNsaWVudCBhcHBsaWNhdGlvbiB3YW50cyB0byB0ZXJtaW5hdGUKLSAgICAgKiBwYXJzaW5nIGVhcmx5LCBpdCBzaG91bGQgdGhyb3cgYW4gZXhjZXB0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIGlucHV0U291cmNlIFRoZSBpbnB1dCBzb3VyY2UgZm9yIHRoZSB0b3AtbGV2ZWwgb2YgdGhlCi0gICAgICogICAgICAgICAgICAgICBYTUwgZG9jdW1lbnQuCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIFhOSUV4Y2VwdGlvbiBBbnkgWE5JIGV4Y2VwdGlvbiwgcG9zc2libHkgd3JhcHBpbmcKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICAgKiBAZXhjZXB0aW9uIElPRXhjZXB0aW9uICBBbiBJTyBleGNlcHRpb24gZnJvbSB0aGUgcGFyc2VyLCBwb3NzaWJseQotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIGZyb20gYSBieXRlIHN0cmVhbSBvciBjaGFyYWN0ZXIgc3RyZWFtCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgc3VwcGxpZWQgYnkgdGhlIHBhcnNlci4KLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBwYXJzZShYTUxJbnB1dFNvdXJjZSBpbnB1dFNvdXJjZSkKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiwgSU9FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSBkb2N1bWVudCBoYW5kbGVyIG9uIHRoZSBsYXN0IGNvbXBvbmVudCBpbiB0aGUgcGlwZWxpbmUKLSAgICAgKiB0byByZWNlaXZlIGluZm9ybWF0aW9uIGFib3V0IHRoZSBkb2N1bWVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBkb2N1bWVudEhhbmRsZXIgICBUaGUgZG9jdW1lbnQgaGFuZGxlci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXREb2N1bWVudEhhbmRsZXIoWE1MRG9jdW1lbnRIYW5kbGVyIGRvY3VtZW50SGFuZGxlcikgewotICAgICAgICBmRG9jdW1lbnRIYW5kbGVyID0gZG9jdW1lbnRIYW5kbGVyOwotICAgICAgICBpZiAoZkxhc3RDb21wb25lbnQgIT0gbnVsbCkgewotICAgICAgICAgICAgZkxhc3RDb21wb25lbnQuc2V0RG9jdW1lbnRIYW5kbGVyKGZEb2N1bWVudEhhbmRsZXIpOwotICAgICAgICAgICAgaWYgKGZEb2N1bWVudEhhbmRsZXIgIT1udWxsKXsKLSAgICAgICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLnNldERvY3VtZW50U291cmNlKGZMYXN0Q29tcG9uZW50KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0gLy8gc2V0RG9jdW1lbnRIYW5kbGVyKFhNTERvY3VtZW50SGFuZGxlcikKLQotICAgIC8qKiBSZXR1cm5zIHRoZSByZWdpc3RlcmVkIGRvY3VtZW50IGhhbmRsZXIuICovCi0gICAgcHVibGljIFhNTERvY3VtZW50SGFuZGxlciBnZXREb2N1bWVudEhhbmRsZXIoKSB7Ci0gICAgICAgIHJldHVybiBmRG9jdW1lbnRIYW5kbGVyOwotICAgIH0gLy8gZ2V0RG9jdW1lbnRIYW5kbGVyKCk6WE1MRG9jdW1lbnRIYW5kbGVyCi0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSBEVEQgaGFuZGxlci4KLSAgICAgKgotICAgICAqIEBwYXJhbSBkdGRIYW5kbGVyIFRoZSBEVEQgaGFuZGxlci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXREVERIYW5kbGVyKFhNTERUREhhbmRsZXIgZHRkSGFuZGxlcikgewotICAgICAgICBmRFRESGFuZGxlciA9IGR0ZEhhbmRsZXI7Ci0gICAgfSAvLyBzZXREVERIYW5kbGVyKFhNTERUREhhbmRsZXIpCi0KLSAgICAvKiogUmV0dXJucyB0aGUgcmVnaXN0ZXJlZCBEVEQgaGFuZGxlci4gKi8KLSAgICBwdWJsaWMgWE1MRFRESGFuZGxlciBnZXREVERIYW5kbGVyKCkgewotICAgICAgICByZXR1cm4gZkRUREhhbmRsZXI7Ci0gICAgfSAvLyBnZXREVERIYW5kbGVyKCk6WE1MRFRESGFuZGxlcgotCi0gICAgLyoqCi0gICAgICogU2V0cyB0aGUgRFREIGNvbnRlbnQgbW9kZWwgaGFuZGxlci4KLSAgICAgKgotICAgICAqIEBwYXJhbSBoYW5kbGVyIFRoZSBEVEQgY29udGVudCBtb2RlbCBoYW5kbGVyLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldERURENvbnRlbnRNb2RlbEhhbmRsZXIoWE1MRFREQ29udGVudE1vZGVsSGFuZGxlciBoYW5kbGVyKSB7Ci0gICAgICAgIGZEVERDb250ZW50TW9kZWxIYW5kbGVyID0gaGFuZGxlcjsKLSAgICB9IC8vIHNldERURENvbnRlbnRNb2RlbEhhbmRsZXIoWE1MRFREQ29udGVudE1vZGVsSGFuZGxlcikKLQotICAgIC8qKiBSZXR1cm5zIHRoZSByZWdpc3RlcmVkIERURCBjb250ZW50IG1vZGVsIGhhbmRsZXIuICovCi0gICAgcHVibGljIFhNTERURENvbnRlbnRNb2RlbEhhbmRsZXIgZ2V0RFREQ29udGVudE1vZGVsSGFuZGxlcigpIHsKLSAgICAgICAgcmV0dXJuIGZEVERDb250ZW50TW9kZWxIYW5kbGVyOwotICAgIH0gLy8gZ2V0RFREQ29udGVudE1vZGVsSGFuZGxlcigpOlhNTERURENvbnRlbnRNb2RlbEhhbmRsZXIKLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIHJlc29sdmVyIHVzZWQgdG8gcmVzb2x2ZSBleHRlcm5hbCBlbnRpdGllcy4gVGhlIEVudGl0eVJlc29sdmVyCi0gICAgICogaW50ZXJmYWNlIHN1cHBvcnRzIHJlc29sdXRpb24gb2YgcHVibGljIGFuZCBzeXN0ZW0gaWRlbnRpZmllcnMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcmVzb2x2ZXIgVGhlIG5ldyBlbnRpdHkgcmVzb2x2ZXIuIFBhc3NpbmcgYSBudWxsIHZhbHVlIHdpbGwKLSAgICAgKiAgICAgICAgICAgICAgICAgdW5pbnN0YWxsIHRoZSBjdXJyZW50bHkgaW5zdGFsbGVkIHJlc29sdmVyLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEVudGl0eVJlc29sdmVyKFhNTEVudGl0eVJlc29sdmVyIHJlc29sdmVyKSB7Ci0gICAgICAgIC8vIFJFVklTSVQ6IFNob3VsZCB0aGlzIGJlIGEgcHJvcGVydHk/Ci0gICAgICAgIGZQcm9wZXJ0aWVzLnB1dChFTlRJVFlfUkVTT0xWRVIsIHJlc29sdmVyKTsKLSAgICB9IC8vIHNldEVudGl0eVJlc29sdmVyKFhNTEVudGl0eVJlc29sdmVyKQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSBjdXJyZW50IGVudGl0eSByZXNvbHZlci4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIGN1cnJlbnQgZW50aXR5IHJlc29sdmVyLCBvciBudWxsIGlmIG5vbmUKLSAgICAgKiAgICAgICAgIGhhcyBiZWVuIHJlZ2lzdGVyZWQuCi0gICAgICogQHNlZSAjc2V0RW50aXR5UmVzb2x2ZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgWE1MRW50aXR5UmVzb2x2ZXIgZ2V0RW50aXR5UmVzb2x2ZXIoKSB7Ci0gICAgICAgIC8vIFJFVklTSVQ6IFNob3VsZCB0aGlzIGJlIGEgcHJvcGVydHk/Ci0gICAgICAgIHJldHVybiAoWE1MRW50aXR5UmVzb2x2ZXIpZlByb3BlcnRpZXMuZ2V0KEVOVElUWV9SRVNPTFZFUik7Ci0gICAgfSAvLyBnZXRFbnRpdHlSZXNvbHZlcigpOlhNTEVudGl0eVJlc29sdmVyCi0KLSAgICAvKioKLSAgICAgKiBBbGxvdyBhbiBhcHBsaWNhdGlvbiB0byByZWdpc3RlciBhbiBlcnJvciBldmVudCBoYW5kbGVyLgotICAgICAqCi0gICAgICogPHA+SWYgdGhlIGFwcGxpY2F0aW9uIGRvZXMgbm90IHJlZ2lzdGVyIGFuIGVycm9yIGhhbmRsZXIsIGFsbAotICAgICAqIGVycm9yIGV2ZW50cyByZXBvcnRlZCBieSB0aGUgU0FYIHBhcnNlciB3aWxsIGJlIHNpbGVudGx5Ci0gICAgICogaWdub3JlZDsgaG93ZXZlciwgbm9ybWFsIHByb2Nlc3NpbmcgbWF5IG5vdCBjb250aW51ZS4gIEl0IGlzCi0gICAgICogaGlnaGx5IHJlY29tbWVuZGVkIHRoYXQgYWxsIFNBWCBhcHBsaWNhdGlvbnMgaW1wbGVtZW50IGFuCi0gICAgICogZXJyb3IgaGFuZGxlciB0byBhdm9pZCB1bmV4cGVjdGVkIGJ1Z3MuPC9wPgotICAgICAqCi0gICAgICogPHA+QXBwbGljYXRpb25zIG1heSByZWdpc3RlciBhIG5ldyBvciBkaWZmZXJlbnQgaGFuZGxlciBpbiB0aGUKLSAgICAgKiBtaWRkbGUgb2YgYSBwYXJzZSwgYW5kIHRoZSBTQVggcGFyc2VyIG11c3QgYmVnaW4gdXNpbmcgdGhlIG5ldwotICAgICAqIGhhbmRsZXIgaW1tZWRpYXRlbHkuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGVycm9ySGFuZGxlciBUaGUgZXJyb3IgaGFuZGxlci4KLSAgICAgKiBAZXhjZXB0aW9uIGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbiBJZiB0aGUgaGFuZGxlcgotICAgICAqICAgICAgICAgICAgYXJndW1lbnQgaXMgbnVsbC4KLSAgICAgKiBAc2VlICNnZXRFcnJvckhhbmRsZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRFcnJvckhhbmRsZXIoWE1MRXJyb3JIYW5kbGVyIGVycm9ySGFuZGxlcikgewotICAgICAgICAvLyBSRVZJU0lUOiBTaG91bGQgdGhpcyBiZSBhIHByb3BlcnR5PwotICAgICAgICBmUHJvcGVydGllcy5wdXQoRVJST1JfSEFORExFUiwgZXJyb3JIYW5kbGVyKTsKLSAgICB9IC8vIHNldEVycm9ySGFuZGxlcihYTUxFcnJvckhhbmRsZXIpCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIGN1cnJlbnQgZXJyb3IgaGFuZGxlci4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIGN1cnJlbnQgZXJyb3IgaGFuZGxlciwgb3IgbnVsbCBpZiBub25lCi0gICAgICogICAgICAgICBoYXMgYmVlbiByZWdpc3RlcmVkLgotICAgICAqIEBzZWUgI3NldEVycm9ySGFuZGxlcgotICAgICAqLwotICAgIHB1YmxpYyBYTUxFcnJvckhhbmRsZXIgZ2V0RXJyb3JIYW5kbGVyKCkgewotICAgICAgICAvLyBSRVZJU0lUOiBTaG91bGQgdGhpcyBiZSBhIHByb3BlcnR5PwotICAgICAgICByZXR1cm4gKFhNTEVycm9ySGFuZGxlcilmUHJvcGVydGllcy5nZXQoRVJST1JfSEFORExFUik7Ci0gICAgfSAvLyBnZXRFcnJvckhhbmRsZXIoKTpYTUxFcnJvckhhbmRsZXIKLQotICAgIC8qKgotICAgICAqIFNldCB0aGUgc3RhdGUgb2YgYSBmZWF0dXJlLgotICAgICAqCi0gICAgICogU2V0IHRoZSBzdGF0ZSBvZiBhbnkgZmVhdHVyZSBpbiBhIFNBWDIgcGFyc2VyLiAgVGhlIHBhcnNlcgotICAgICAqIG1pZ2h0IG5vdCByZWNvZ25pemUgdGhlIGZlYXR1cmUsIGFuZCBpZiBpdCBkb2VzIHJlY29nbml6ZQotICAgICAqIGl0LCBpdCBtaWdodCBub3QgYmUgYWJsZSB0byBmdWxmaWxsIHRoZSByZXF1ZXN0LgotICAgICAqCi0gICAgICogQHBhcmFtIGZlYXR1cmVJZCBUaGUgdW5pcXVlIGlkZW50aWZpZXIgKFVSSSkgb2YgdGhlIGZlYXR1cmUuCi0gICAgICogQHBhcmFtIHN0YXRlIFRoZSByZXF1ZXN0ZWQgc3RhdGUgb2YgdGhlIGZlYXR1cmUgKHRydWUgb3IgZmFsc2UpLgotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBJZiB0aGUKLSAgICAgKiAgICAgICAgICAgIHJlcXVlc3RlZCBmZWF0dXJlIGlzIG5vdCBrbm93bi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRGZWF0dXJlKFN0cmluZyBmZWF0dXJlSWQsIGJvb2xlYW4gc3RhdGUpCi0gICAgICAgIHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIHsKLQotICAgICAgICAvLyBmb3J3YXJkIHRvIGV2ZXJ5IGNvbXBvbmVudAotICAgICAgICBpbnQgY291bnQgPSBmQ29tcG9uZW50cy5zaXplKCk7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykgewotICAgICAgICAgICAgWE1MQ29tcG9uZW50IGMgPSAoWE1MQ29tcG9uZW50KSBmQ29tcG9uZW50cy5nZXQoaSk7Ci0gICAgICAgICAgICBjLnNldEZlYXR1cmUoZmVhdHVyZUlkLCBzdGF0ZSk7Ci0gICAgICAgIH0KLSAgICAgICAgLy8gc2F2ZSBzdGF0ZSBpZiBub29uZSAib2JqZWN0cyIKLSAgICAgICAgc3VwZXIuc2V0RmVhdHVyZShmZWF0dXJlSWQsIHN0YXRlKTsKLQotICAgIH0gLy8gc2V0RmVhdHVyZShTdHJpbmcsYm9vbGVhbikKLQotICAgIC8qKgotICAgICAqIHNldFByb3BlcnR5Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gcHJvcGVydHlJZAotICAgICAqIEBwYXJhbSB2YWx1ZQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFByb3BlcnR5KFN0cmluZyBwcm9wZXJ0eUlkLCBPYmplY3QgdmFsdWUpCi0gICAgICAgIHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIHsKLQotICAgICAgICAvLyBmb3J3YXJkIHRvIGV2ZXJ5IGNvbXBvbmVudAotICAgICAgICBpbnQgY291bnQgPSBmQ29tcG9uZW50cy5zaXplKCk7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykgewotICAgICAgICAgICAgWE1MQ29tcG9uZW50IGMgPSAoWE1MQ29tcG9uZW50KSBmQ29tcG9uZW50cy5nZXQoaSk7Ci0gICAgICAgICAgICBjLnNldFByb3BlcnR5KHByb3BlcnR5SWQsIHZhbHVlKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIHN0b3JlIHZhbHVlIGlmIG5vb25lICJvYmplY3RzIgotICAgICAgICBzdXBlci5zZXRQcm9wZXJ0eShwcm9wZXJ0eUlkLCB2YWx1ZSk7Ci0KLSAgICB9IC8vIHNldFByb3BlcnR5KFN0cmluZyxPYmplY3QpCi0KLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIGxvY2FsZSB0byB1c2UgZm9yIG1lc3NhZ2VzLgotICAgICAqCi0gICAgICogQHBhcmFtIGxvY2FsZSBUaGUgbG9jYWxlIG9iamVjdCB0byB1c2UgZm9yIGxvY2FsaXphdGlvbiBvZiBtZXNzYWdlcy4KLSAgICAgKgotICAgICAqIEBleGNlcHRpb24gWE5JRXhjZXB0aW9uIFRocm93biBpZiB0aGUgcGFyc2VyIGRvZXMgbm90IHN1cHBvcnQgdGhlCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgc3BlY2lmaWVkIGxvY2FsZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRMb2NhbGUoTG9jYWxlIGxvY2FsZSkgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIGZMb2NhbGUgPSBsb2NhbGU7Ci0gICAgfSAvLyBzZXRMb2NhbGUoTG9jYWxlKQotCi0gICAgLyoqIFJldHVybnMgdGhlIGxvY2FsZS4gKi8KLSAgICBwdWJsaWMgTG9jYWxlIGdldExvY2FsZSgpIHsKLSAgICAgICAgcmV0dXJuIGZMb2NhbGU7Ci0gICAgfSAvLyBnZXRMb2NhbGUoKTpMb2NhbGUKLQotICAgIC8vCi0gICAgLy8gUHJvdGVjdGVkIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogcmVzZXQgYWxsIGNvbXBvbmVudHMgYmVmb3JlIHBhcnNpbmcgYW5kIG5hbWVzcGFjZSBjb250ZXh0Ci0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgcmVzZXQoKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLQotICAgICAgICAvLyByZXNldCBldmVyeSBjb21wb25lbnQKLSAgICAgICAgaW50IGNvdW50ID0gZkNvbXBvbmVudHMuc2l6ZSgpOwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKLSAgICAgICAgICAgIFhNTENvbXBvbmVudCBjID0gKFhNTENvbXBvbmVudCkgZkNvbXBvbmVudHMuZ2V0KGkpOwotICAgICAgICAgICAgYy5yZXNldCh0aGlzKTsKLSAgICAgICAgfQotCi0gICAgfSAvLyByZXNldCgpCi0KLSAgICAvKioKLSAgICAgKiBDaGVjayBhIHByb3BlcnR5LiBJZiB0aGUgcHJvcGVydHkgaXMga25vd24gYW5kIHN1cHBvcnRlZCwgdGhpcyBtZXRob2QKLSAgICAgKiBzaW1wbHkgcmV0dXJucy4gT3RoZXJ3aXNlLCB0aGUgYXBwcm9wcmlhdGUgZXhjZXB0aW9uIGlzIHRocm93bi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBwcm9wZXJ0eUlkIFRoZSB1bmlxdWUgaWRlbnRpZmllciAoVVJJKSBvZiB0aGUgcHJvcGVydHkKLSAgICAgKiAgICAgICAgICAgICAgICAgICBiZWluZyBzZXQuCi0gICAgICogQGV4Y2VwdGlvbiBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBJZiB0aGUKLSAgICAgKiAgICAgICAgICAgIHJlcXVlc3RlZCBmZWF0dXJlIGlzIG5vdCBrbm93biBvciBzdXBwb3J0ZWQuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIFByb3BlcnR5U3RhdGUgY2hlY2tQcm9wZXJ0eShTdHJpbmcgcHJvcGVydHlJZCkKLSAgICAgICAgdGhyb3dzIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gewotCi0gICAgICAgIC8vIHNwZWNpYWwgY2FzZXMKLSAgICAgICAgaWYgKHByb3BlcnR5SWQuc3RhcnRzV2l0aChDb25zdGFudHMuU0FYX1BST1BFUlRZX1BSRUZJWCkpIHsKLSAgICAgICAgICAgIGZpbmFsIGludCBzdWZmaXhMZW5ndGggPSBwcm9wZXJ0eUlkLmxlbmd0aCgpIC0gQ29uc3RhbnRzLlNBWF9QUk9QRVJUWV9QUkVGSVgubGVuZ3RoKCk7Ci0KLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAvLyBodHRwOi8veG1sLm9yZy9zYXgvcHJvcGVydGllcy94bWwtc3RyaW5nCi0gICAgICAgICAgICAvLyBWYWx1ZSB0eXBlOiBTdHJpbmcKLSAgICAgICAgICAgIC8vIEFjY2VzczogcmVhZC1vbmx5Ci0gICAgICAgICAgICAvLyAgIEdldCB0aGUgbGl0ZXJhbCBzdHJpbmcgb2YgY2hhcmFjdGVycyBhc3NvY2lhdGVkIHdpdGggdGhlCi0gICAgICAgICAgICAvLyAgIGN1cnJlbnQgZXZlbnQuICBJZiB0aGUgcGFyc2VyIHJlY29nbmlzZXMgYW5kIHN1cHBvcnRzIHRoaXMKLSAgICAgICAgICAgIC8vICAgcHJvcGVydHkgYnV0IGlzIG5vdCBjdXJyZW50bHkgcGFyc2luZyB0ZXh0LCBpdCBzaG91bGQgcmV0dXJuCi0gICAgICAgICAgICAvLyAgIG51bGwgKHRoaXMgaXMgYSBnb29kIHdheSB0byBjaGVjayBmb3IgYXZhaWxhYmlsaXR5IGJlZm9yZSB0aGUKLSAgICAgICAgICAgIC8vICAgcGFyc2UgYmVnaW5zKS4KLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICBpZiAoc3VmZml4TGVuZ3RoID09IENvbnN0YW50cy5YTUxfU1RSSU5HX1BST1BFUlRZLmxlbmd0aCgpICYmCi0gICAgICAgICAgICAgICAgcHJvcGVydHlJZC5lbmRzV2l0aChDb25zdGFudHMuWE1MX1NUUklOR19QUk9QRVJUWSkpIHsKLSAgICAgICAgICAgICAgICAvLyBSRVZJU0lUIC0gd2Ugc2hvdWxkIHByb2JhYmx5IGFzayB4bWwtZGV2IGZvciBhIHByZWNpc2UKLSAgICAgICAgICAgICAgICAvLyBkZWZpbml0aW9uIG9mIHdoYXQgdGhpcyBpcyBhY3R1YWxseSBzdXBwb3NlZCB0byByZXR1cm4sIGFuZAotICAgICAgICAgICAgICAgIC8vIGluIGV4YWN0bHkgd2hpY2ggY2lyY3Vtc3RhbmNlcy4KLSAgICAgICAgICAgICAgICByZXR1cm4gUHJvcGVydHlTdGF0ZS5OT1RfU1VQUE9SVEVEOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gY2hlY2sgcHJvcGVydHkKLSAgICAgICAgcmV0dXJuIHN1cGVyLmNoZWNrUHJvcGVydHkocHJvcGVydHlJZCk7Ci0KLSAgICB9IC8vIGNoZWNrUHJvcGVydHkoU3RyaW5nKQotCi0KLSAgICAvKioKLSAgICAgKiBDaGVjayBhIGZlYXR1cmUuIElmIGZlYXR1cmUgaXMga25vdyBhbmQgc3VwcG9ydGVkLCB0aGlzIG1ldGhvZCBzaW1wbHkKLSAgICAgKiByZXR1cm5zLiBPdGhlcndpc2UsIHRoZSBhcHByb3ByaWF0ZSBleGNlcHRpb24gaXMgdGhyb3duLgotICAgICAqCi0gICAgICogQHBhcmFtIGZlYXR1cmVJZCBUaGUgdW5pcXVlIGlkZW50aWZpZXIgKFVSSSkgb2YgdGhlIGZlYXR1cmUuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gVGhyb3duIGZvciBjb25maWd1cmF0aW9uIGVycm9yLgotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbiBnZW5lcmFsLCBjb21wb25lbnRzIHNob3VsZAotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbmx5IHRocm93IHRoaXMgZXhjZXB0aW9uIGlmCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0IGlzIDxzdHJvbmc+cmVhbGx5PC9zdHJvbmc+Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGEgY3JpdGljYWwgZXJyb3IuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIEZlYXR1cmVTdGF0ZSBjaGVja0ZlYXR1cmUoU3RyaW5nIGZlYXR1cmVJZCkKLSAgICAgICAgdGhyb3dzIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gewotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIFhlcmNlcyBGZWF0dXJlcwotICAgICAgICAvLwotICAgICAgICBpZiAoZmVhdHVyZUlkLnN0YXJ0c1dpdGgoQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCkpIHsKLSAgICAgICAgICAgIGZpbmFsIGludCBzdWZmaXhMZW5ndGggPSBmZWF0dXJlSWQubGVuZ3RoKCkgLSBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYLmxlbmd0aCgpOwotCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgLy8gc3BlY2lhbCBwZXJmb3JtYW5jZSBmZWF0dXJlOiBubyBvbmUgYnkgY29tcG9uZW50IG1hbmFnZXIgaXMgYWxsb3dlZCB0byBzZXQgaXQKLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICBpZiAoc3VmZml4TGVuZ3RoID09IENvbnN0YW50cy5QQVJTRVJfU0VUVElOR1MubGVuZ3RoKCkgJiYKLSAgICAgICAgICAgICAgICBmZWF0dXJlSWQuZW5kc1dpdGgoQ29uc3RhbnRzLlBBUlNFUl9TRVRUSU5HUykpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gRmVhdHVyZVN0YXRlLk5PVF9TVVBQT1JURUQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gc3VwZXIuY2hlY2tGZWF0dXJlKGZlYXR1cmVJZCk7Ci0gICAgIH0gLy8gY2hlY2tGZWF0dXJlKFN0cmluZykKLQotCi19IC8vIGNsYXNzIEJhc2ljUGFyc2VyQ29uZmlndXJhdGlvbgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvcGFyc2Vycy9DYWNoaW5nUGFyc2VyUG9vbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvcGFyc2Vycy9DYWNoaW5nUGFyc2VyUG9vbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhOWY1MjI5Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3BhcnNlcnMvQ2FjaGluZ1BhcnNlclBvb2wuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQzMCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5wYXJzZXJzOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuZ3JhbW1hcnMuR3JhbW1hcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5ncmFtbWFycy5YTUxHcmFtbWFyUG9vbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5ncmFtbWFycy5YTUxHcmFtbWFyRGVzY3JpcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlhNTEdyYW1tYXJQb29sSW1wbDsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5TaGFkb3dlZFN5bWJvbFRhYmxlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5TeW1ib2xUYWJsZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuU3luY2hyb25pemVkU3ltYm9sVGFibGU7Ci0KLS8qKgotICogQSBwYXJzZXIgcG9vbCB0aGF0IGVuYWJsZXMgY2FjaGluZyBvZiBncmFtbWFycy4gVGhlIGNhY2hpbmcgcGFyc2VyCi0gKiBwb29sIGlzIGNvbnN0cnVjdGVkIHdpdGggYSBzcGVjaWZpYyBzeW1ib2wgdGFibGUgYW5kIGdyYW1tYXIgcG9vbAotICogdGhhdCBoYXMgYWxyZWFkeSBiZWVuIHBvcHVsYXRlZCB3aXRoIHRoZSBncmFtbWFycyB1c2VkIGJ5IHRoZQotICogYXBwbGljYXRpb24uCi0gKiA8cD4KLSAqIE9uY2UgdGhlIGNhY2hpbmcgcGFyc2VyIHBvb2wgaXMgY29uc3RydWN0ZWQsIHNwZWNpZmljIHBhcnNlcgotICogaW5zdGFuY2VzIGFyZSBjcmVhdGVkIGJ5IGNhbGxpbmcgdGhlIGFwcHJvcHJpYXRlIGZhY3RvcnkgbWV0aG9kCi0gKiBvbiB0aGUgcGFyc2VyIHBvb2wuCi0gKiA8cD4KLSAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gVGhlcmUgaXMgYSBwZXJmb3JtYW5jZSBwZW5hbHR5IGZvciB1c2luZwotICogYSBjYWNoaW5nIHBhcnNlciBwb29sIGR1ZSB0byB0aHJlYWQgc2FmZXR5LiBBY2Nlc3MgdG8gdGhlIHN5bWJvbAotICogdGFibGUgYW5kIGdyYW1tYXIgcG9vbCBtdXN0IGJlIHN5bmNocm9uaXplZCB0byBlbnN1cmUgdGhlIHNhZmUKLSAqIG9wZXJhdGlvbiBvZiB0aGUgc3ltYm9sIHRhYmxlIGFuZCBncmFtbWFyIHBvb2wuCi0gKiA8cD4KLSAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gSWYgcGVyZm9ybWFuY2UgaXMgY3JpdGljYWwsIHRoZW4gYW5vdGhlcgotICogbWVjaGFuaXNtIG5lZWRzIHRvIGJlIHVzZWQgaW5zdGVhZCBvZiB0aGUgY2FjaGluZyBwYXJzZXIgcG9vbC4KLSAqIE9uZSBhcHByb2FjaCB3b3VsZCBiZSB0byBjcmVhdGUgcGFyc2VyIGluc3RhbmNlcyB0aGF0IGRvIG5vdAotICogc2hhcmUgdGhlc2Ugc3RydWN0dXJlcy4gSW5zdGVhZCwgZWFjaCBpbnN0YW5jZSB3b3VsZCBnZXQgaXRzCi0gKiBvd24gY29weSB0byB1c2Ugd2hpbGUgcGFyc2luZy4gVGhpcyBhdm9pZHMgdGhlIHN5bmNocm9uaXphdGlvbgotICogb3ZlcmhlYWQgYXQgdGhlIGV4cGVuc2Ugb2YgbW9yZSBtZW1vcnkgYW5kIHRoZSB0aW1lIHJlcXVpcmVkCi0gKiB0byBjb3B5IHRoZSBzdHJ1Y3R1cmVzIGZvciBlYWNoIG5ldyBwYXJzZXIgaW5zdGFuY2UuIEFuZCBldmVuCi0gKiB3aGVuIGEgcGFyc2VyIGluc3RhbmNlIGlzIHJlLXVzZWQsIHRoZXJlIGlzIGEgcG90ZW50aWFsIGZvciBhCi0gKiBtZW1vcnkgbGVhayBkdWUgdG8gbmV3IHN5bWJvbHMgYmVpbmcgYWRkZWQgdG8gdGhlIHN5bWJvbCB0YWJsZQotICogb3ZlciB0aW1lLiBJbiBvdGhlciB3b3JkcywgYWx3YXlzIHRha2UgY2F1dGlvbiB0byBtYWtlIHN1cmUKLSAqIHRoYXQgeW91ciBhcHBsaWNhdGlvbiBpcyB0aHJlYWQtc2FmZSBhbmQgYXZvaWRzIGxlYWtpbmcgbWVtb3J5LgotICoKLSAqIEBhdXRob3IgQW5keSBDbGFyaywgSUJNCi0gKgotICovCi1wdWJsaWMgY2xhc3MgQ2FjaGluZ1BhcnNlclBvb2wgewotCi0gICAgLy8KLSAgICAvLyBDb25zdGFudHMKLSAgICAvLwotCi0gICAgLyoqIERlZmF1bHQgc2hhZG93IHN5bWJvbCB0YWJsZSAoZmFsc2UpLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgYm9vbGVhbiBERUZBVUxUX1NIQURPV19TWU1CT0xfVEFCTEUgPSBmYWxzZTsKLQotICAgIC8qKiBEZWZhdWx0IHNoYWRvdyBncmFtbWFyIHBvb2wgKGZhbHNlKS4gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGJvb2xlYW4gREVGQVVMVF9TSEFET1dfR1JBTU1BUl9QT09MID0gZmFsc2U7Ci0KLSAgICAvLwotICAgIC8vIERhdGEKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogU3ltYm9sIHRhYmxlLiBUaGUgc3ltYm9sIHRhYmxlIHRoYXQgdGhlIGNhY2hpbmcgcGFyc2VyIHBvb2wgaXMKLSAgICAgKiBjb25zdHJ1Y3RlZCB3aXRoIGlzIGF1dG9tYXRpY2FsbHkgd3JhcHBlZCBpbiBhIHN5bmNocm9uaXplZAotICAgICAqIHZlcnNpb24gZm9yIHRocmVhZC1zYWZldHkuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIFN5bWJvbFRhYmxlIGZTeW5jaHJvbml6ZWRTeW1ib2xUYWJsZTsKLQotICAgIC8qKgotICAgICAqIEdyYW1tYXIgcG9vbC4gVGhlIGdyYW1tYXIgcG9vbCB0aGF0IHRoZSBjYWNoaW5nIHBhcnNlciBwb29sIGlzCi0gICAgICogY29uc3RydWN0ZWQgd2l0aCBpcyBhdXRvbWF0aWNhbGx5IHdyYXBwZWQgaW4gYSBzeW5jaHJvbml6ZWQKLSAgICAgKiB2ZXJzaW9uIGZvciB0aHJlYWQtc2FmZXR5LgotICAgICAqLwotICAgIHByb3RlY3RlZCBYTUxHcmFtbWFyUG9vbCBmU3luY2hyb25pemVkR3JhbW1hclBvb2w7Ci0KLSAgICAvKioKLSAgICAgKiBTaGFkb3cgdGhlIHN5bWJvbCB0YWJsZSBmb3IgbmV3IHBhcnNlciBpbnN0YW5jZXMuIElmIHRydWUsCi0gICAgICogbmV3IHBhcnNlciBpbnN0YW5jZXMgdXNlIHNoYWRvdyBjb3BpZXMgb2YgdGhlIG1haW4gc3ltYm9sCi0gICAgICogdGFibGUgYW5kIGFyZSBub3QgYWxsb3dlZCB0byBhZGQgbmV3IHN5bWJvbHMgdG8gdGhlIG1haW4KLSAgICAgKiBzeW1ib2wgdGFibGUuIE5ldyBzeW1ib2xzIGFyZSBhZGRlZCB0byB0aGUgc2hhZG93IHN5bWJvbAotICAgICAqIHRhYmxlIGFuZCBhcmUgbG9jYWwgdG8gdGhlIHBhcnNlciBpbnN0YW5jZS4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBmU2hhZG93U3ltYm9sVGFibGUgPSBERUZBVUxUX1NIQURPV19TWU1CT0xfVEFCTEU7Ci0KLSAgICAvKioKLSAgICAgKiBTaGFkb3cgdGhlIGdyYW1tYXIgcG9vbCBmb3IgbmV3IHBhcnNlciBpbnN0YW5jZXMuIElmIHRydWUsCi0gICAgICogbmV3IHBhcnNlciBpbnN0YW5jZXMgdXNlIHNoYWRvdyBjb3BpZXMgb2YgdGhlIG1haW4gZ3JhbW1hcgotICAgICAqIHBvb2wgYW5kIGFyZSBub3QgYWxsb3dlZCB0byBhZGQgbmV3IGdyYW1tYXJzIHRvIHRoZSBtYWluCi0gICAgICogZ3JhbW1hciBwb29sLiBOZXcgZ3JhbW1hcnMgYXJlIGFkZGVkIHRvIHRoZSBzaGFkb3cgZ3JhbW1hcgotICAgICAqIHBvb2wgYW5kIGFyZSBsb2NhbCB0byB0aGUgcGFyc2VyIGluc3RhbmNlLgotICAgICAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIGZTaGFkb3dHcmFtbWFyUG9vbCA9IERFRkFVTFRfU0hBRE9XX0dSQU1NQVJfUE9PTDsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKiBEZWZhdWx0IGNvbnN0cnVjdG9yLiAqLwotICAgIHB1YmxpYyBDYWNoaW5nUGFyc2VyUG9vbCgpIHsKLSAgICAgICAgdGhpcyhuZXcgU3ltYm9sVGFibGUoKSwgbmV3IFhNTEdyYW1tYXJQb29sSW1wbCgpKTsKLSAgICB9IC8vIDxpbml0PigpCi0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RzIGEgY2FjaGluZyBwYXJzZXIgcG9vbCB3aXRoIHRoZSBzcGVjaWZpZWQgc3ltYm9sIHRhYmxlCi0gICAgICogYW5kIGdyYW1tYXIgcG9vbC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzeW1ib2xUYWJsZSBUaGUgc3ltYm9sIHRhYmxlLgotICAgICAqIEBwYXJhbSBncmFtbWFyUG9vbCBUaGUgZ3JhbW1hciBwb29sLgotICAgICAqLwotICAgIHB1YmxpYyBDYWNoaW5nUGFyc2VyUG9vbChTeW1ib2xUYWJsZSBzeW1ib2xUYWJsZSwgWE1MR3JhbW1hclBvb2wgZ3JhbW1hclBvb2wpIHsKLSAgICAgICAgZlN5bmNocm9uaXplZFN5bWJvbFRhYmxlID0gbmV3IFN5bmNocm9uaXplZFN5bWJvbFRhYmxlKHN5bWJvbFRhYmxlKTsKLSAgICAgICAgZlN5bmNocm9uaXplZEdyYW1tYXJQb29sID0gbmV3IFN5bmNocm9uaXplZEdyYW1tYXJQb29sKGdyYW1tYXJQb29sKTsKLSAgICB9IC8vIDxpbml0PihTeW1ib2xUYWJsZSxYTUxHcmFtbWFyUG9vbCkKLQotICAgIC8vCi0gICAgLy8gUHVibGljIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqIFJldHVybnMgdGhlIHN5bWJvbCB0YWJsZS4gKi8KLSAgICBwdWJsaWMgU3ltYm9sVGFibGUgZ2V0U3ltYm9sVGFibGUoKSB7Ci0gICAgICAgIHJldHVybiBmU3luY2hyb25pemVkU3ltYm9sVGFibGU7Ci0gICAgfSAvLyBnZXRTeW1ib2xUYWJsZSgpOlN5bWJvbFRhYmxlCi0KLSAgICAvKiogUmV0dXJucyB0aGUgZ3JhbW1hciBwb29sLiAqLwotICAgIHB1YmxpYyBYTUxHcmFtbWFyUG9vbCBnZXRYTUxHcmFtbWFyUG9vbCgpIHsKLSAgICAgICAgcmV0dXJuIGZTeW5jaHJvbml6ZWRHcmFtbWFyUG9vbDsKLSAgICB9IC8vIGdldFhNTEdyYW1tYXJQb29sKCk6WE1MR3JhbW1hclBvb2wKLQotICAgIC8vIHNldHRlcnMgYW5kIGdldHRlcnMKLQotICAgIC8qKgotICAgICAqIFNldHMgd2hldGhlciBuZXcgcGFyc2VyIGluc3RhbmNlIHJlY2VpdmUgc2hhZG93IGNvcGllcyBvZiB0aGUKLSAgICAgKiBtYWluIHN5bWJvbCB0YWJsZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzaGFkb3cgSWYgdHJ1ZSwgbmV3IHBhcnNlciBpbnN0YW5jZXMgdXNlIHNoYWRvdyBjb3BpZXMKLSAgICAgKiAgICAgICAgICAgICAgIG9mIHRoZSBtYWluIHN5bWJvbCB0YWJsZSBhbmQgYXJlIG5vdCBhbGxvd2VkIHRvCi0gICAgICogICAgICAgICAgICAgICBhZGQgbmV3IHN5bWJvbHMgdG8gdGhlIG1haW4gc3ltYm9sIHRhYmxlLiBOZXcKLSAgICAgKiAgICAgICAgICAgICAgIHN5bWJvbHMgYXJlIGFkZGVkIHRvIHRoZSBzaGFkb3cgc3ltYm9sIHRhYmxlIGFuZAotICAgICAqICAgICAgICAgICAgICAgYXJlIGxvY2FsIHRvIHRoZSBwYXJzZXIgaW5zdGFuY2UuIElmIGZhbHNlLCBuZXcKLSAgICAgKiAgICAgICAgICAgICAgIHBhcnNlciBpbnN0YW5jZXMgYXJlIGFsbG93ZWQgdG8gYWRkIG5ldyBzeW1ib2xzCi0gICAgICogICAgICAgICAgICAgICB0byB0aGUgbWFpbiBzeW1ib2wgdGFibGUuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0U2hhZG93U3ltYm9sVGFibGUoYm9vbGVhbiBzaGFkb3cpIHsKLSAgICAgICAgZlNoYWRvd1N5bWJvbFRhYmxlID0gc2hhZG93OwotICAgIH0gLy8gc2V0U2hhZG93U3ltYm9sVGFibGUoYm9vbGVhbikKLQotICAgIC8vIGZhY3RvcnkgbWV0aG9kcwotCi0gICAgLyoqIENyZWF0ZXMgYSBuZXcgRE9NIHBhcnNlci4gKi8KLSAgICBwdWJsaWMgRE9NUGFyc2VyIGNyZWF0ZURPTVBhcnNlcigpIHsKLSAgICAgICAgU3ltYm9sVGFibGUgc3ltYm9sVGFibGUgPSBmU2hhZG93U3ltYm9sVGFibGUKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBuZXcgU2hhZG93ZWRTeW1ib2xUYWJsZShmU3luY2hyb25pemVkU3ltYm9sVGFibGUpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogZlN5bmNocm9uaXplZFN5bWJvbFRhYmxlOwotICAgICAgICBYTUxHcmFtbWFyUG9vbCBncmFtbWFyUG9vbCA9IGZTaGFkb3dHcmFtbWFyUG9vbAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IG5ldyBTaGFkb3dlZEdyYW1tYXJQb29sKGZTeW5jaHJvbml6ZWRHcmFtbWFyUG9vbCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBmU3luY2hyb25pemVkR3JhbW1hclBvb2w7Ci0gICAgICAgIHJldHVybiBuZXcgRE9NUGFyc2VyKHN5bWJvbFRhYmxlLCBncmFtbWFyUG9vbCk7Ci0gICAgfSAvLyBjcmVhdGVET01QYXJzZXIoKTpET01QYXJzZXIKLQotICAgIC8qKiBDcmVhdGVzIGEgbmV3IFNBWCBwYXJzZXIuICovCi0gICAgcHVibGljIFNBWFBhcnNlciBjcmVhdGVTQVhQYXJzZXIoKSB7Ci0gICAgICAgIFN5bWJvbFRhYmxlIHN5bWJvbFRhYmxlID0gZlNoYWRvd1N5bWJvbFRhYmxlCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gbmV3IFNoYWRvd2VkU3ltYm9sVGFibGUoZlN5bmNocm9uaXplZFN5bWJvbFRhYmxlKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IGZTeW5jaHJvbml6ZWRTeW1ib2xUYWJsZTsKLSAgICAgICAgWE1MR3JhbW1hclBvb2wgZ3JhbW1hclBvb2wgPSBmU2hhZG93R3JhbW1hclBvb2wKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBuZXcgU2hhZG93ZWRHcmFtbWFyUG9vbChmU3luY2hyb25pemVkR3JhbW1hclBvb2wpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogZlN5bmNocm9uaXplZEdyYW1tYXJQb29sOwotICAgICAgICByZXR1cm4gbmV3IFNBWFBhcnNlcihzeW1ib2xUYWJsZSwgZ3JhbW1hclBvb2wpOwotICAgIH0gLy8gY3JlYXRlU0FYUGFyc2VyKCk6U0FYUGFyc2VyCi0KLSAgICAvLwotICAgIC8vIENsYXNzZXMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogU3luY2hyb25pemVkIGdyYW1tYXIgcG9vbC4KLSAgICAgKgotICAgICAqIEBhdXRob3IgQW5keSBDbGFyaywgSUJNCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBTeW5jaHJvbml6ZWRHcmFtbWFyUG9vbAotICAgICAgICBpbXBsZW1lbnRzIFhNTEdyYW1tYXJQb29sIHsKLQotICAgICAgICAvLwotICAgICAgICAvLyBEYXRhCi0gICAgICAgIC8vCi0KLSAgICAgICAgLyoqIE1haW4gZ3JhbW1hciBwb29sLiAqLwotICAgICAgICBwcml2YXRlIFhNTEdyYW1tYXJQb29sIGZHcmFtbWFyUG9vbDsKLQotICAgICAgICAvLwotICAgICAgICAvLyBDb25zdHJ1Y3RvcnMKLSAgICAgICAgLy8KLQotICAgICAgICAvKiogQ29uc3RydWN0cyBhIHN5bmNocm9uaXplZCBncmFtbWFyIHBvb2wuICovCi0gICAgICAgIHB1YmxpYyBTeW5jaHJvbml6ZWRHcmFtbWFyUG9vbChYTUxHcmFtbWFyUG9vbCBncmFtbWFyUG9vbCkgewotICAgICAgICAgICAgZkdyYW1tYXJQb29sID0gZ3JhbW1hclBvb2w7Ci0gICAgICAgIH0gLy8gPGluaXQ+KFhNTEdyYW1tYXJQb29sKQotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIEdyYW1tYXJQb29sIG1ldGhvZHMKLSAgICAgICAgLy8KLQotICAgICAgICAvLyByZXRyaWV2ZSB0aGUgaW5pdGlhbCBzZXQgb2YgZ3JhbW1hcnMgZm9yIHRoZSB2YWxpZGF0b3IKLSAgICAgICAgLy8gdG8gd29yayB3aXRoLgotICAgICAgICAvLyBSRVZJU0lUOiAgZG9lcyB0aGlzIG5lZWQgdG8gYmUgc3luY2hyb25pemVkIHNpbmNlIGl0J3MganVzdCByZWFkaW5nPwotICAgICAgICAvLyBAcGFyYW0gZ3JhbW1hclR5cGUgdHlwZSBvZiB0aGUgZ3JhbW1hcnMgdG8gYmUgcmV0cmlldmVkLgotICAgICAgICAvLyBAcmV0dXJuIHRoZSBpbml0aWFsIGdyYW1tYXIgc2V0IHRoZSB2YWxpZGF0b3IgbWF5IHBsYWNlIGluIGl0cyAiYnVja2V0IgotICAgICAgICBwdWJsaWMgR3JhbW1hciBbXSByZXRyaWV2ZUluaXRpYWxHcmFtbWFyU2V0KFN0cmluZyBncmFtbWFyVHlwZSApIHsKLSAgICAgICAgICAgIHN5bmNocm9uaXplZCAoZkdyYW1tYXJQb29sKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZHcmFtbWFyUG9vbC5yZXRyaWV2ZUluaXRpYWxHcmFtbWFyU2V0KGdyYW1tYXJUeXBlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSAvLyByZXRyaWV2ZUluaXRpYWxHcmFtbWFyU2V0KFN0cmluZyk6ICBHcmFtbWFyW10KLQotICAgICAgICAvLyByZXRyaWV2ZSBhIHBhcnRpY3VsYXIgZ3JhbW1hci4KLSAgICAgICAgLy8gUkVWSVNJVDogIGRvZXMgdGhpcyBuZWVkIHRvIGJlIHN5bmNocm9uaXplZCBzaW5jZSBpdCdzIGp1c3QgcmVhZGluZz8KLSAgICAgICAgLy8gQHBhcmFtIGdEZXNjIGRlc2NyaXB0aW9uIG9mIHRoZSBncmFtbWFyIHRvIGJlIHJldHJpZXZlZAotICAgICAgICAvLyBAcmV0dXJuIEdyYW1tYXIgY29ycmVzcG9uZGluZyB0byBnRGVzYywgb3IgbnVsbCBpZiBub25lIGV4aXN0cy4KLSAgICAgICAgcHVibGljIEdyYW1tYXIgcmV0cmlldmVHcmFtbWFyKFhNTEdyYW1tYXJEZXNjcmlwdGlvbiBnRGVzYykgewotICAgICAgICAgICAgc3luY2hyb25pemVkIChmR3JhbW1hclBvb2wpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZkdyYW1tYXJQb29sLnJldHJpZXZlR3JhbW1hcihnRGVzYyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gLy8gcmV0cmlldmVHcmFtbWFyKFhNTEdyYW1tYXJEZXNjKTogIEdyYW1tYXIKLQotICAgICAgICAvLyBnaXZlIHRoZSBncmFtbWFyUG9vbCB0aGUgb3B0aW9uIG9mIGNhY2hpbmcgdGhlc2UgZ3JhbW1hcnMuCi0gICAgICAgIC8vIFRoaXMgY2VydGFpbmx5IG11c3QgYmUgc3luY2hyb25pemVkLgotICAgICAgICAvLyBAcGFyYW0gZ3JhbW1hclR5cGUgVGhlIHR5cGUgb2YgdGhlIGdyYW1tYXJzIHRvIGJlIGNhY2hlZC4KLSAgICAgICAgLy8gQHBhcmFtIGdyYW1tYXJzIHRoZSBHcmFtbWFycyB0aGF0IG1heSBiZSBjYWNoZWQgKHVub3JkZXJlZCwgR3JhbW1hcnMgcHJldmlvdXNseQotICAgICAgICAvLyAgZ2l2ZW4gdG8gdGhlIHZhbGlkYXRvciBtYXkgYmUgaW5jbHVkZWQpLgotICAgICAgICBwdWJsaWMgdm9pZCBjYWNoZUdyYW1tYXJzKFN0cmluZyBncmFtbWFyVHlwZSwgR3JhbW1hcltdIGdyYW1tYXJzKSB7Ci0gICAgICAgICAgICBzeW5jaHJvbml6ZWQgKGZHcmFtbWFyUG9vbCkgewotICAgICAgICAgICAgICAgIGZHcmFtbWFyUG9vbC5jYWNoZUdyYW1tYXJzKGdyYW1tYXJUeXBlLCBncmFtbWFycyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gLy8gY2FjaGVHcmFtbWFycyhTdHJpbmcsIEdyYW1tYXJbXSk7Ci0KLSAgICAgICAgLyoqIGxvY2sgdGhlIGdyYW1tYXIgcG9vbCAqLwotICAgICAgICBwdWJsaWMgdm9pZCBsb2NrUG9vbCgpIHsKLSAgICAgICAgICAgIHN5bmNocm9uaXplZCAoZkdyYW1tYXJQb29sKSB7Ci0gICAgICAgICAgICAgICAgZkdyYW1tYXJQb29sLmxvY2tQb29sKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gLy8gbG9ja1Bvb2woKQotCi0gICAgICAgIC8qKiBjbGVhciB0aGUgZ3JhbW1hciBwb29sICovCi0gICAgICAgIHB1YmxpYyB2b2lkIGNsZWFyKCkgewotICAgICAgICAgICAgc3luY2hyb25pemVkIChmR3JhbW1hclBvb2wpIHsKLSAgICAgICAgICAgICAgICBmR3JhbW1hclBvb2wuY2xlYXIoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSAvLyBsb2NrUG9vbCgpCi0KLSAgICAgICAgLyoqIHVubG9jayB0aGUgZ3JhbW1hciBwb29sICovCi0gICAgICAgIHB1YmxpYyB2b2lkIHVubG9ja1Bvb2woKSB7Ci0gICAgICAgICAgICBzeW5jaHJvbml6ZWQgKGZHcmFtbWFyUG9vbCkgewotICAgICAgICAgICAgICAgIGZHcmFtbWFyUG9vbC51bmxvY2tQb29sKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gLy8gdW5sb2NrUG9vbCgpCi0KLSAgICAgICAgLyoqKgotICAgICAgICAgKiBNZXRob2RzIGNvcnJlc3BvbmRpbmcgdG8gb3JpZ2luYWwgKHByZSBYZXJjZXMyLjAuMGZpbmFsKQotICAgICAgICAgKiBncmFtbWFyUG9vbCBoYXZlIGJlZW4gY29tbWVudGVkIG91dC4KLSAgICAgICAgICovCi0gICAgICAgIC8qKgotICAgICAgICAgKiBQdXRzIHRoZSBzcGVjaWZpZWQgZ3JhbW1hciBpbnRvIHRoZSBncmFtbWFyIHBvb2wuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBrZXkgS2V5IHRvIGFzc29jaWF0ZSB3aXRoIGdyYW1tYXIuCi0gICAgICAgICAqIEBwYXJhbSBncmFtbWFyIEdyYW1tYXIgb2JqZWN0LgotICAgICAgICAgKi8KLSAgICAgICAgLyoqKioqKgotICAgICAgICBwdWJsaWMgdm9pZCBwdXRHcmFtbWFyKFN0cmluZyBrZXksIEdyYW1tYXIgZ3JhbW1hcikgewotICAgICAgICAgICAgc3luY2hyb25pemVkIChmR3JhbW1hclBvb2wpIHsKLSAgICAgICAgICAgICAgICBmR3JhbW1hclBvb2wucHV0R3JhbW1hcihrZXksIGdyYW1tYXIpOwotICAgICAgICAgICAgfQotICAgICAgICB9IC8vIHB1dEdyYW1tYXIoU3RyaW5nLEdyYW1tYXIpCi0gICAgICAgICoqKioqKiovCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFJldHVybnMgdGhlIGdyYW1tYXIgYXNzb2NpYXRlZCB0byB0aGUgc3BlY2lmaWVkIGtleS4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIGtleSBUaGUga2V5IG9mIHRoZSBncmFtbWFyLgotICAgICAgICAgKi8KLSAgICAgICAgLyoqKioqKioqKioKLSAgICAgICAgcHVibGljIEdyYW1tYXIgZ2V0R3JhbW1hcihTdHJpbmcga2V5KSB7Ci0gICAgICAgICAgICBzeW5jaHJvbml6ZWQgKGZHcmFtbWFyUG9vbCkgewotICAgICAgICAgICAgICAgIHJldHVybiBmR3JhbW1hclBvb2wuZ2V0R3JhbW1hcihrZXkpOwotICAgICAgICAgICAgfQotICAgICAgICB9IC8vIGdldEdyYW1tYXIoU3RyaW5nKTpHcmFtbWFyCi0gICAgICAgICoqKioqKioqKioqLwotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBSZW1vdmVzIHRoZSBncmFtbWFyIGFzc29jaWF0ZWQgdG8gdGhlIHNwZWNpZmllZCBrZXkgZnJvbSB0aGUKLSAgICAgICAgICogZ3JhbW1hciBwb29sIGFuZCByZXR1cm5zIHRoZSByZW1vdmVkIGdyYW1tYXIuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBrZXkgVGhlIGtleSBvZiB0aGUgZ3JhbW1hci4KLSAgICAgICAgICovCi0gICAgICAgIC8qKioqKioqKioqCi0gICAgICAgIHB1YmxpYyBHcmFtbWFyIHJlbW92ZUdyYW1tYXIoU3RyaW5nIGtleSkgewotICAgICAgICAgICAgc3luY2hyb25pemVkIChmR3JhbW1hclBvb2wpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZkdyYW1tYXJQb29sLnJlbW92ZUdyYW1tYXIoa2V5KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSAvLyByZW1vdmVHcmFtbWFyKFN0cmluZyk6R3JhbW1hcgotICAgICAgICAqKioqKiovCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgZ3JhbW1hciBwb29sIGNvbnRhaW5zIGEgZ3JhbW1hciBhc3NvY2lhdGVkCi0gICAgICAgICAqIHRvIHRoZSBzcGVjaWZpZWQga2V5LgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0ga2V5IFRoZSBrZXkgb2YgdGhlIGdyYW1tYXIuCi0gICAgICAgICAqLwotICAgICAgICAvKioqKioqKioqKgotICAgICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0dyYW1tYXIoU3RyaW5nIGtleSkgewotICAgICAgICAgICAgc3luY2hyb25pemVkIChmR3JhbW1hclBvb2wpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZkdyYW1tYXJQb29sLmNvbnRhaW5zR3JhbW1hcihrZXkpOwotICAgICAgICAgICAgfQotICAgICAgICB9IC8vIGNvbnRhaW5zR3JhbW1hcihTdHJpbmcpOmJvb2xlYW4KLSAgICAgICAgKioqKioqKiovCi0KLSAgICB9IC8vIGNsYXNzIFN5bmNocm9uaXplZEdyYW1tYXJQb29sCi0KLSAgICAvKioKLSAgICAgKiBTaGFkb3dlZCBncmFtbWFyIHBvb2wuCi0gICAgICogVGhpcyBjbGFzcyBpcyBwcmVkaWNhdGVkIG9uIHRoZSBleGlzdGVuY2Ugb2YgYSBjb25jcmV0ZSBpbXBsZW1lbnRhdGlvbjsKLSAgICAgKiBzbyB1c2luZyBvdXIgb3duIGRvZXNuJ3Qgc2VlbSB0byBiYWQgYW4gaWRlYS4KLSAgICAgKgotICAgICAqIEBhdXRob3IgQW5keSBDbGFyaywgSUJNCi0gICAgICogQGF1dGhvciBOZWlsIEdyYWhhbSwgSUJNCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBTaGFkb3dlZEdyYW1tYXJQb29sCi0gICAgICAgIGV4dGVuZHMgWE1MR3JhbW1hclBvb2xJbXBsIHsKLQotICAgICAgICAvLwotICAgICAgICAvLyBEYXRhCi0gICAgICAgIC8vCi0KLSAgICAgICAgLyoqIE1haW4gZ3JhbW1hciBwb29sLiAqLwotICAgICAgICBwcml2YXRlIFhNTEdyYW1tYXJQb29sIGZHcmFtbWFyUG9vbDsKLQotICAgICAgICAvLwotICAgICAgICAvLyBDb25zdHJ1Y3RvcnMKLSAgICAgICAgLy8KLQotICAgICAgICAvKiogQ29uc3RydWN0cyBhIHNoYWRvd2VkIGdyYW1tYXIgcG9vbC4gKi8KLSAgICAgICAgcHVibGljIFNoYWRvd2VkR3JhbW1hclBvb2woWE1MR3JhbW1hclBvb2wgZ3JhbW1hclBvb2wpIHsKLSAgICAgICAgICAgIGZHcmFtbWFyUG9vbCA9IGdyYW1tYXJQb29sOwotICAgICAgICB9IC8vIDxpbml0PihHcmFtbWFyUG9vbCkKLQotICAgICAgICAvLwotICAgICAgICAvLyBHcmFtbWFyUG9vbCBtZXRob2RzCi0gICAgICAgIC8vCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFJldHJpZXZlIHRoZSBpbml0aWFsIHNldCBvZiBncmFtbWFycyBmb3IgdGhlIHZhbGlkYXRvciB0byB3b3JrIHdpdGguCi0gICAgICAgICAqIFJFVklTSVQ6ICBkb2VzIHRoaXMgbmVlZCB0byBiZSBzeW5jaHJvbml6ZWQgc2luY2UgaXQncyBqdXN0IHJlYWRpbmc/Ci0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBncmFtbWFyVHlwZSBUeXBlIG9mIHRoZSBncmFtbWFycyB0byBiZSByZXRyaWV2ZWQuCi0gICAgICAgICAqIEByZXR1cm4gICAgICAgICAgICBUaGUgaW5pdGlhbCBncmFtbWFyIHNldCB0aGUgdmFsaWRhdG9yIG1heSBwbGFjZSBpbiBpdHMgImJ1Y2tldCIKLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBHcmFtbWFyIFtdIHJldHJpZXZlSW5pdGlhbEdyYW1tYXJTZXQoU3RyaW5nIGdyYW1tYXJUeXBlICkgewotICAgICAgICAgICAgR3JhbW1hciBbXSBncmFtbWFycyA9IHN1cGVyLnJldHJpZXZlSW5pdGlhbEdyYW1tYXJTZXQoZ3JhbW1hclR5cGUpOwotICAgICAgICAgICAgaWYgKGdyYW1tYXJzICE9IG51bGwpIHJldHVybiBncmFtbWFyczsKLSAgICAgICAgICAgIHJldHVybiBmR3JhbW1hclBvb2wucmV0cmlldmVJbml0aWFsR3JhbW1hclNldChncmFtbWFyVHlwZSk7Ci0gICAgICAgIH0gLy8gcmV0cmlldmVJbml0aWFsR3JhbW1hclNldChTdHJpbmcpOiAgR3JhbW1hcltdCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFJldHJpZXZlIGEgcGFydGljdWxhciBncmFtbWFyLgotICAgICAgICAgKiBSRVZJU0lUOiAgZG9lcyB0aGlzIG5lZWQgdG8gYmUgc3luY2hyb25pemVkIHNpbmNlIGl0J3MganVzdCByZWFkaW5nPwotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gZ0Rlc2MgRGVzY3JpcHRpb24gb2YgdGhlIGdyYW1tYXIgdG8gYmUgcmV0cmlldmVkCi0gICAgICAgICAqIEByZXR1cm4gICAgICBHcmFtbWFyIGNvcnJlc3BvbmRpbmcgdG8gZ0Rlc2MsIG9yIG51bGwgaWYgbm9uZSBleGlzdHMuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgR3JhbW1hciByZXRyaWV2ZUdyYW1tYXIoWE1MR3JhbW1hckRlc2NyaXB0aW9uIGdEZXNjKSB7Ci0gICAgICAgICAgICBHcmFtbWFyIGcgPSBzdXBlci5yZXRyaWV2ZUdyYW1tYXIoZ0Rlc2MpOwotICAgICAgICAgICAgaWYoZyAhPSBudWxsKSByZXR1cm4gZzsKLSAgICAgICAgICAgIHJldHVybiBmR3JhbW1hclBvb2wucmV0cmlldmVHcmFtbWFyKGdEZXNjKTsKLSAgICAgICAgfSAvLyByZXRyaWV2ZUdyYW1tYXIoWE1MR3JhbW1hckRlc2MpOiAgR3JhbW1hcgotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBHaXZlIHRoZSBncmFtbWFyUG9vbCB0aGUgb3B0aW9uIG9mIGNhY2hpbmcgdGhlc2UgZ3JhbW1hcnMuCi0gICAgICAgICAqIFRoaXMgY2VydGFpbmx5IG11c3QgYmUgc3luY2hyb25pemVkLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gZ3JhbW1hclR5cGUgVGhlIHR5cGUgb2YgdGhlIGdyYW1tYXJzIHRvIGJlIGNhY2hlZC4KLSAgICAgICAgICogQHBhcmFtIGdyYW1tYXJzICAgIFRoZSBHcmFtbWFycyB0aGF0IG1heSBiZSBjYWNoZWQgKHVub3JkZXJlZCwgR3JhbW1hcnMgcHJldmlvdXNseQotICAgICAgICAgKiAgICAgICAgICAgICAgICAgICAgZ2l2ZW4gdG8gdGhlIHZhbGlkYXRvciBtYXkgYmUgaW5jbHVkZWQpLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIHZvaWQgY2FjaGVHcmFtbWFycyhTdHJpbmcgZ3JhbW1hclR5cGUsIEdyYW1tYXJbXSBncmFtbWFycykgewotICAgICAgICAgICAvLyBiZXR0ZXIgZ2l2ZSBib3RoIGdyYW1tYXJzIGEgc2hvdC4uLgotICAgICAgICAgICBzdXBlci5jYWNoZUdyYW1tYXJzKGdyYW1tYXJUeXBlLCBncmFtbWFycyk7Ci0gICAgICAgICAgIGZHcmFtbWFyUG9vbC5jYWNoZUdyYW1tYXJzKGdyYW1tYXJUeXBlLCBncmFtbWFycyk7Ci0gICAgICAgIH0gLy8gY2FjaGVHcmFtbWFycyhncmFtbWFyVHlwZSwgR3JhbW1hcltdKTsKLQotICAgICAgICAvKioKLSAgICAgICAgICogUmV0dXJucyB0aGUgZ3JhbW1hciBhc3NvY2lhdGVkIHRvIHRoZSBzcGVjaWZpZWQgZGVzY3JpcHRpb24uCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBkZXNjIFRoZSBkZXNjcmlwdGlvbiBvZiB0aGUgZ3JhbW1hci4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBHcmFtbWFyIGdldEdyYW1tYXIoWE1MR3JhbW1hckRlc2NyaXB0aW9uIGRlc2MpIHsKLQotICAgICAgICAgICAgaWYgKHN1cGVyLmNvbnRhaW5zR3JhbW1hcihkZXNjKSkgewotICAgICAgICAgICAgICAgIHJldHVybiBzdXBlci5nZXRHcmFtbWFyKGRlc2MpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0KLSAgICAgICAgfSAvLyBnZXRHcmFtbWFyKFhNTEdyYW1tYXJEZXNjcmlwdGlvbik6R3JhbW1hcgotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIGdyYW1tYXIgcG9vbCBjb250YWlucyBhIGdyYW1tYXIgYXNzb2NpYXRlZAotICAgICAgICAgKiB0byB0aGUgc3BlY2lmaWVkIGRlc2NyaXB0aW9uLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gZGVzYyBUaGUgZGVzY3JpcHRpb24gb2YgdGhlIGdyYW1tYXIuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0dyYW1tYXIoWE1MR3JhbW1hckRlc2NyaXB0aW9uIGRlc2MpIHsKLSAgICAgICAgICAgIHJldHVybiBzdXBlci5jb250YWluc0dyYW1tYXIoZGVzYyk7Ci0gICAgICAgIH0gLy8gY29udGFpbnNHcmFtbWFyKFhNTEdyYW1tYXJEZXNjcmlwdGlvbik6Ym9vbGVhbgotCi0gICAgfSAvLyBjbGFzcyBTaGFkb3dlZEdyYW1tYXJQb29sCi0KLX0gLy8gY2xhc3MgQ2FjaGluZ1BhcnNlclBvb2wKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3BhcnNlcnMvRE9NUGFyc2VyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9wYXJzZXJzL0RPTVBhcnNlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmMjAyMGVmLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3BhcnNlcnMvRE9NUGFyc2VyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw2NjcgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMC0yMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnBhcnNlcnM7Ci0KLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLkNvbnN0YW50czsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuRW50aXR5UmVzb2x2ZXJXcmFwcGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5FbnRpdHlSZXNvbHZlcjJXcmFwcGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5FcnJvckhhbmRsZXJXcmFwcGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5TQVhNZXNzYWdlRm9ybWF0dGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5TdGF0dXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlN5bWJvbFRhYmxlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbHMuWE1MU2VjdXJpdHlNYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbHMuWE1MU2VjdXJpdHlQcm9wZXJ0eU1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE5JRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLmdyYW1tYXJzLlhNTEdyYW1tYXJQb29sOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxFbnRpdHlSZXNvbHZlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MRXJyb3JIYW5kbGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxJbnB1dFNvdXJjZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MUGFyc2VFeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTFBhcnNlckNvbmZpZ3VyYXRpb247Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcueG1sLnNheC5FbnRpdHlSZXNvbHZlcjsKLWltcG9ydCBvcmcueG1sLnNheC5FcnJvckhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguSW5wdXRTb3VyY2U7Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWFBhcnNlRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LmV4dC5FbnRpdHlSZXNvbHZlcjI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguaGVscGVycy5Mb2NhdG9ySW1wbDsKLQotLyoqCi0gKiBUaGlzIGlzIHRoZSBtYWluIFhlcmNlcyBET00gcGFyc2VyIGNsYXNzLiBJdCB1c2VzIHRoZSBhYnN0cmFjdCBET00KLSAqIHBhcnNlciB3aXRoIGEgZG9jdW1lbnQgc2Nhbm5lciwgYSBkdGQgc2Nhbm5lciwgYW5kIGEgdmFsaWRhdG9yLCBhcwotICogd2VsbCBhcyBhIGdyYW1tYXIgcG9vbC4KLSAqCi0gKiBAYXV0aG9yIEFybmF1ZCAgTGUgSG9ycywgSUJNCi0gKiBAYXV0aG9yIEFuZHkgQ2xhcmssIElCTQotICoKLSAqIEB2ZXJzaW9uICRJZDogRE9NUGFyc2VyLmphdmEsdiAxLjcgMjAxMC0xMS0wMSAwNDo0MDowOSBqb2VodyBFeHAgJAotICovCi1wdWJsaWMgY2xhc3MgRE9NUGFyc2VyCi0gICAgZXh0ZW5kcyBBYnN0cmFjdERPTVBhcnNlciB7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0YW50cwotICAgIC8vCi0KLSAgICAvLyBmZWF0dXJlcwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogRW50aXR5UmVzb2x2ZXIyLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFVTRV9FTlRJVFlfUkVTT0xWRVIyID0KLSAgICAgICAgQ29uc3RhbnRzLlNBWF9GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5VU0VfRU5USVRZX1JFU09MVkVSMl9GRUFUVVJFOwotCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgUkVQT1JUX1dISVRFU1BBQ0UgPQotICAgICAgICAgICAgQ29uc3RhbnRzLlNVTl9TQ0hFTUFfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuU1VOX1JFUE9SVF9JR05PUkVEX0VMRU1FTlRfQ09OVEVOVF9XSElURVNQQUNFOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IFNlY3VyaXR5IHByb3BlcnR5IG1hbmFnZXIuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFhNTF9TRUNVUklUWV9QUk9QRVJUWV9NQU5BR0VSID0KLSAgICAgICAgICAgIENvbnN0YW50cy5YTUxfU0VDVVJJVFlfUFJPUEVSVFlfTUFOQUdFUjsKLQotICAgIC8vIHJlY29nbml6ZWQgZmVhdHVyZXM6Ci0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nW10gUkVDT0dOSVpFRF9GRUFUVVJFUyA9IHsKLSAgICAgICAgUkVQT1JUX1dISVRFU1BBQ0UKLSAgICB9OwotCi0gICAgLy8gcHJvcGVydGllcwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IHN5bWJvbCB0YWJsZS4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBTWU1CT0xfVEFCTEUgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5TWU1CT0xfVEFCTEVfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogWE1MIGdyYW1tYXIgcG9vbC4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxHUkFNTUFSX1BPT0wgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCtDb25zdGFudHMuWE1MR1JBTU1BUl9QT09MX1BST1BFUlRZOwotCi0gICAgLyoqIFJlY29nbml6ZWQgcHJvcGVydGllcy4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSBSRUNPR05JWkVEX1BST1BFUlRJRVMgPSB7Ci0gICAgICAgIFNZTUJPTF9UQUJMRSwKLSAgICAgICAgWE1MR1JBTU1BUl9QT09MLAotICAgIH07Ci0KLSAgICAvLwotICAgIC8vIERhdGEKLSAgICAvLwotCi0gICAgLy8gZmVhdHVyZXMKLQotICAgIC8qKiBVc2UgRW50aXR5UmVzb2x2ZXIyLiAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIGZVc2VFbnRpdHlSZXNvbHZlcjIgPSB0cnVlOwotCi0gICAgLy8KLSAgICAvLyBDb25zdHJ1Y3RvcnMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0cyBhIERPTSBwYXJzZXIgdXNpbmcgdGhlIHNwZWNpZmllZCBwYXJzZXIgY29uZmlndXJhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgRE9NUGFyc2VyKFhNTFBhcnNlckNvbmZpZ3VyYXRpb24gY29uZmlnKSB7Ci0gICAgICAgIHN1cGVyKGNvbmZpZyk7Ci0gICAgfSAvLyA8aW5pdD4oWE1MUGFyc2VyQ29uZmlndXJhdGlvbikKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHMgYSBET00gcGFyc2VyIHVzaW5nIHRoZSBkdGQveG1sIHNjaGVtYSBwYXJzZXIgY29uZmlndXJhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgRE9NUGFyc2VyKCkgewotICAgICAgICB0aGlzKG51bGwsIG51bGwpOwotICAgIH0gLy8gPGluaXQ+KCkKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHMgYSBET00gcGFyc2VyIHVzaW5nIHRoZSBzcGVjaWZpZWQgc3ltYm9sIHRhYmxlLgotICAgICAqLwotICAgIHB1YmxpYyBET01QYXJzZXIoU3ltYm9sVGFibGUgc3ltYm9sVGFibGUpIHsKLSAgICAgICAgdGhpcyhzeW1ib2xUYWJsZSwgbnVsbCk7Ci0gICAgfSAvLyA8aW5pdD4oU3ltYm9sVGFibGUpCi0KLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHMgYSBET00gcGFyc2VyIHVzaW5nIHRoZSBzcGVjaWZpZWQgc3ltYm9sIHRhYmxlIGFuZAotICAgICAqIGdyYW1tYXIgcG9vbC4KLSAgICAgKi8KLSAgICBwdWJsaWMgRE9NUGFyc2VyKFN5bWJvbFRhYmxlIHN5bWJvbFRhYmxlLCBYTUxHcmFtbWFyUG9vbCBncmFtbWFyUG9vbCkgewotICAgICAgICBzdXBlcihuZXcgWEluY2x1ZGVBd2FyZVBhcnNlckNvbmZpZ3VyYXRpb24oKSk7Ci0KLSAgICAgICAgLy8gc2V0IHByb3BlcnRpZXMKLSAgICAgICAgZkNvbmZpZ3VyYXRpb24uYWRkUmVjb2duaXplZFByb3BlcnRpZXMoUkVDT0dOSVpFRF9QUk9QRVJUSUVTKTsKLSAgICAgICAgaWYgKHN5bWJvbFRhYmxlICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZDb25maWd1cmF0aW9uLnNldFByb3BlcnR5KFNZTUJPTF9UQUJMRSwgc3ltYm9sVGFibGUpOwotICAgICAgICB9Ci0gICAgICAgIGlmIChncmFtbWFyUG9vbCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmQ29uZmlndXJhdGlvbi5zZXRQcm9wZXJ0eShYTUxHUkFNTUFSX1BPT0wsIGdyYW1tYXJQb29sKTsKLSAgICAgICAgfQotCi0gICAgICAgIGZDb25maWd1cmF0aW9uLmFkZFJlY29nbml6ZWRGZWF0dXJlcyhSRUNPR05JWkVEX0ZFQVRVUkVTKTsKLQotICAgIH0gLy8gPGluaXQ+KFN5bWJvbFRhYmxlLFhNTEdyYW1tYXJQb29sKQotCi0gICAgLy8KLSAgICAvLyBYTUxSZWFkZXIgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBQYXJzZXMgdGhlIGlucHV0IHNvdXJjZSBzcGVjaWZpZWQgYnkgdGhlIGdpdmVuIHN5c3RlbSBpZGVudGlmaWVyLgotICAgICAqIDxwPgotICAgICAqIFRoaXMgbWV0aG9kIGlzIGVxdWl2YWxlbnQgdG8gdGhlIGZvbGxvd2luZzoKLSAgICAgKiA8cHJlPgotICAgICAqICAgICBwYXJzZShuZXcgSW5wdXRTb3VyY2Uoc3lzdGVtSWQpKTsKLSAgICAgKiA8L3ByZT4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzeXN0ZW1JZCBUaGUgc3lzdGVtIGlkZW50aWZpZXIgKFVSSSkuCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBUaHJvd3MgZXhjZXB0aW9uIG9uIFNBWCBlcnJvci4KLSAgICAgKiBAZXhjZXB0aW9uIGphdmEuaW8uSU9FeGNlcHRpb24gVGhyb3dzIGV4Y2VwdGlvbiBvbiBpL28gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcGFyc2UoU3RyaW5nIHN5c3RlbUlkKSB0aHJvd3MgU0FYRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy8gcGFyc2UgZG9jdW1lbnQKLSAgICAgICAgWE1MSW5wdXRTb3VyY2Ugc291cmNlID0gbmV3IFhNTElucHV0U291cmNlKG51bGwsIHN5c3RlbUlkLCBudWxsKTsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIHBhcnNlKHNvdXJjZSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyB3cmFwIFhOSSBleGNlcHRpb25zIGFzIFNBWCBleGNlcHRpb25zCi0gICAgICAgIGNhdGNoIChYTUxQYXJzZUV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICBFeGNlcHRpb24gZXggPSBlLmdldEV4Y2VwdGlvbigpOwotICAgICAgICAgICAgaWYgKGV4ID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAvLyBtdXN0IGJlIGEgcGFyc2VyIGV4Y2VwdGlvbjsgbWluZSBpdCBmb3IgbG9jYXRvciBpbmZvIGFuZCB0aHJvdwotICAgICAgICAgICAgICAgIC8vIGEgU0FYUGFyc2VFeGNlcHRpb24KLSAgICAgICAgICAgICAgICBMb2NhdG9ySW1wbCBsb2NhdG9ySW1wbCA9IG5ldyBMb2NhdG9ySW1wbCgpOwotICAgICAgICAgICAgICAgIGxvY2F0b3JJbXBsLnNldFB1YmxpY0lkKGUuZ2V0UHVibGljSWQoKSk7Ci0gICAgICAgICAgICAgICAgbG9jYXRvckltcGwuc2V0U3lzdGVtSWQoZS5nZXRFeHBhbmRlZFN5c3RlbUlkKCkpOwotICAgICAgICAgICAgICAgIGxvY2F0b3JJbXBsLnNldExpbmVOdW1iZXIoZS5nZXRMaW5lTnVtYmVyKCkpOwotICAgICAgICAgICAgICAgIGxvY2F0b3JJbXBsLnNldENvbHVtbk51bWJlcihlLmdldENvbHVtbk51bWJlcigpKTsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU0FYUGFyc2VFeGNlcHRpb24oZS5nZXRNZXNzYWdlKCksIGxvY2F0b3JJbXBsKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChleCBpbnN0YW5jZW9mIFNBWEV4Y2VwdGlvbikgewotICAgICAgICAgICAgICAgIC8vIHdoeSBkaWQgd2UgY3JlYXRlIGFuIFhNTFBhcnNlRXhjZXB0aW9uPwotICAgICAgICAgICAgICAgIHRocm93IChTQVhFeGNlcHRpb24pZXg7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoZXggaW5zdGFuY2VvZiBJT0V4Y2VwdGlvbikgewotICAgICAgICAgICAgICAgIHRocm93IChJT0V4Y2VwdGlvbilleDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oZXgpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChYTklFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgICAgICAgIEV4Y2VwdGlvbiBleCA9IGUuZ2V0RXhjZXB0aW9uKCk7Ci0gICAgICAgICAgICBpZiAoZXggPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oZS5nZXRNZXNzYWdlKCkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKGV4IGluc3RhbmNlb2YgU0FYRXhjZXB0aW9uKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgKFNBWEV4Y2VwdGlvbilleDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChleCBpbnN0YW5jZW9mIElPRXhjZXB0aW9uKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgKElPRXhjZXB0aW9uKWV4OwotICAgICAgICAgICAgfQotICAgICAgICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbihleCk7Ci0gICAgICAgIH0KLQotICAgIH0gLy8gcGFyc2UoU3RyaW5nKQotCi0gICAgLyoqCi0gICAgICogcGFyc2UKLSAgICAgKgotICAgICAqIEBwYXJhbSBpbnB1dFNvdXJjZQotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICAgKiBAZXhjZXB0aW9uIGphdmEuaW8uSU9FeGNlcHRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBwYXJzZShJbnB1dFNvdXJjZSBpbnB1dFNvdXJjZSkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewotCi0gICAgICAgIC8vIHBhcnNlIGRvY3VtZW50Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBYTUxJbnB1dFNvdXJjZSB4bWxJbnB1dFNvdXJjZSA9Ci0gICAgICAgICAgICAgICAgbmV3IFhNTElucHV0U291cmNlKGlucHV0U291cmNlLmdldFB1YmxpY0lkKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0U291cmNlLmdldFN5c3RlbUlkKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwpOwotICAgICAgICAgICAgeG1sSW5wdXRTb3VyY2Uuc2V0Qnl0ZVN0cmVhbShpbnB1dFNvdXJjZS5nZXRCeXRlU3RyZWFtKCkpOwotICAgICAgICAgICAgeG1sSW5wdXRTb3VyY2Uuc2V0Q2hhcmFjdGVyU3RyZWFtKGlucHV0U291cmNlLmdldENoYXJhY3RlclN0cmVhbSgpKTsKLSAgICAgICAgICAgIHhtbElucHV0U291cmNlLnNldEVuY29kaW5nKGlucHV0U291cmNlLmdldEVuY29kaW5nKCkpOwotICAgICAgICAgICAgcGFyc2UoeG1sSW5wdXRTb3VyY2UpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gd3JhcCBYTkkgZXhjZXB0aW9ucyBhcyBTQVggZXhjZXB0aW9ucwotICAgICAgICBjYXRjaCAoWE1MUGFyc2VFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgRXhjZXB0aW9uIGV4ID0gZS5nZXRFeGNlcHRpb24oKTsKLSAgICAgICAgICAgIGlmIChleCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgLy8gbXVzdCBiZSBhIHBhcnNlciBleGNlcHRpb247IG1pbmUgaXQgZm9yIGxvY2F0b3IgaW5mbyBhbmQgdGhyb3cKLSAgICAgICAgICAgICAgICAvLyBhIFNBWFBhcnNlRXhjZXB0aW9uCi0gICAgICAgICAgICAgICAgTG9jYXRvckltcGwgbG9jYXRvckltcGwgPSBuZXcgTG9jYXRvckltcGwoKTsKLSAgICAgICAgICAgICAgICBsb2NhdG9ySW1wbC5zZXRQdWJsaWNJZChlLmdldFB1YmxpY0lkKCkpOwotICAgICAgICAgICAgICAgIGxvY2F0b3JJbXBsLnNldFN5c3RlbUlkKGUuZ2V0RXhwYW5kZWRTeXN0ZW1JZCgpKTsKLSAgICAgICAgICAgICAgICBsb2NhdG9ySW1wbC5zZXRMaW5lTnVtYmVyKGUuZ2V0TGluZU51bWJlcigpKTsKLSAgICAgICAgICAgICAgICBsb2NhdG9ySW1wbC5zZXRDb2x1bW5OdW1iZXIoZS5nZXRDb2x1bW5OdW1iZXIoKSk7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFNBWFBhcnNlRXhjZXB0aW9uKGUuZ2V0TWVzc2FnZSgpLCBsb2NhdG9ySW1wbCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoZXggaW5zdGFuY2VvZiBTQVhFeGNlcHRpb24pIHsKLSAgICAgICAgICAgICAgICAvLyB3aHkgZGlkIHdlIGNyZWF0ZSBhbiBYTUxQYXJzZUV4Y2VwdGlvbj8KLSAgICAgICAgICAgICAgICB0aHJvdyAoU0FYRXhjZXB0aW9uKWV4OwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKGV4IGluc3RhbmNlb2YgSU9FeGNlcHRpb24pIHsKLSAgICAgICAgICAgICAgICB0aHJvdyAoSU9FeGNlcHRpb24pZXg7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKGV4KTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoWE5JRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIEV4Y2VwdGlvbiBleCA9IGUuZ2V0RXhjZXB0aW9uKCk7Ci0gICAgICAgICAgICBpZiAoZXggPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oZS5nZXRNZXNzYWdlKCkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKGV4IGluc3RhbmNlb2YgU0FYRXhjZXB0aW9uKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgKFNBWEV4Y2VwdGlvbilleDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChleCBpbnN0YW5jZW9mIElPRXhjZXB0aW9uKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgKElPRXhjZXB0aW9uKWV4OwotICAgICAgICAgICAgfQotICAgICAgICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbihleCk7Ci0gICAgICAgIH0KLQotICAgIH0gLy8gcGFyc2UoSW5wdXRTb3VyY2UpCi0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSByZXNvbHZlciB1c2VkIHRvIHJlc29sdmUgZXh0ZXJuYWwgZW50aXRpZXMuIFRoZSBFbnRpdHlSZXNvbHZlcgotICAgICAqIGludGVyZmFjZSBzdXBwb3J0cyByZXNvbHV0aW9uIG9mIHB1YmxpYyBhbmQgc3lzdGVtIGlkZW50aWZpZXJzLgotICAgICAqCi0gICAgICogQHBhcmFtIHJlc29sdmVyIFRoZSBuZXcgZW50aXR5IHJlc29sdmVyLiBQYXNzaW5nIGEgbnVsbCB2YWx1ZSB3aWxsCi0gICAgICogICAgICAgICAgICAgICAgIHVuaW5zdGFsbCB0aGUgY3VycmVudGx5IGluc3RhbGxlZCByZXNvbHZlci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRFbnRpdHlSZXNvbHZlcihFbnRpdHlSZXNvbHZlciByZXNvbHZlcikgewotCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBYTUxFbnRpdHlSZXNvbHZlciB4ZXIgPSAoWE1MRW50aXR5UmVzb2x2ZXIpIGZDb25maWd1cmF0aW9uLmdldFByb3BlcnR5KEVOVElUWV9SRVNPTFZFUik7Ci0gICAgICAgICAgICBpZiAoZlVzZUVudGl0eVJlc29sdmVyMiAmJiByZXNvbHZlciBpbnN0YW5jZW9mIEVudGl0eVJlc29sdmVyMikgewotICAgICAgICAgICAgICAgIGlmICh4ZXIgaW5zdGFuY2VvZiBFbnRpdHlSZXNvbHZlcjJXcmFwcGVyKSB7Ci0gICAgICAgICAgICAgICAgICAgIEVudGl0eVJlc29sdmVyMldyYXBwZXIgZXIydyA9IChFbnRpdHlSZXNvbHZlcjJXcmFwcGVyKSB4ZXI7Ci0gICAgICAgICAgICAgICAgICAgIGVyMncuc2V0RW50aXR5UmVzb2x2ZXIoKEVudGl0eVJlc29sdmVyMikgcmVzb2x2ZXIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgZkNvbmZpZ3VyYXRpb24uc2V0UHJvcGVydHkoRU5USVRZX1JFU09MVkVSLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBFbnRpdHlSZXNvbHZlcjJXcmFwcGVyKChFbnRpdHlSZXNvbHZlcjIpIHJlc29sdmVyKSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgaWYgKHhlciBpbnN0YW5jZW9mIEVudGl0eVJlc29sdmVyV3JhcHBlcikgewotICAgICAgICAgICAgICAgICAgICBFbnRpdHlSZXNvbHZlcldyYXBwZXIgZXJ3ID0gKEVudGl0eVJlc29sdmVyV3JhcHBlcikgeGVyOwotICAgICAgICAgICAgICAgICAgICBlcncuc2V0RW50aXR5UmVzb2x2ZXIocmVzb2x2ZXIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgZkNvbmZpZ3VyYXRpb24uc2V0UHJvcGVydHkoRU5USVRZX1JFU09MVkVSLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBFbnRpdHlSZXNvbHZlcldyYXBwZXIocmVzb2x2ZXIpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gZSkgewotICAgICAgICAgICAgLy8gZG8gbm90aGluZwotICAgICAgICB9Ci0KLSAgICB9IC8vIHNldEVudGl0eVJlc29sdmVyKEVudGl0eVJlc29sdmVyKQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSBjdXJyZW50IGVudGl0eSByZXNvbHZlci4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIGN1cnJlbnQgZW50aXR5IHJlc29sdmVyLCBvciBudWxsIGlmIG5vbmUKLSAgICAgKiAgICAgICAgIGhhcyBiZWVuIHJlZ2lzdGVyZWQuCi0gICAgICogQHNlZSAjc2V0RW50aXR5UmVzb2x2ZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgRW50aXR5UmVzb2x2ZXIgZ2V0RW50aXR5UmVzb2x2ZXIoKSB7Ci0KLSAgICAgICAgRW50aXR5UmVzb2x2ZXIgZW50aXR5UmVzb2x2ZXIgPSBudWxsOwotICAgICAgICB0cnkgewotICAgICAgICAgICAgWE1MRW50aXR5UmVzb2x2ZXIgeG1sRW50aXR5UmVzb2x2ZXIgPQotICAgICAgICAgICAgICAgIChYTUxFbnRpdHlSZXNvbHZlcilmQ29uZmlndXJhdGlvbi5nZXRQcm9wZXJ0eShFTlRJVFlfUkVTT0xWRVIpOwotICAgICAgICAgICAgaWYgKHhtbEVudGl0eVJlc29sdmVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBpZiAoeG1sRW50aXR5UmVzb2x2ZXIgaW5zdGFuY2VvZiBFbnRpdHlSZXNvbHZlcldyYXBwZXIpIHsKLSAgICAgICAgICAgICAgICAgICAgZW50aXR5UmVzb2x2ZXIgPQotICAgICAgICAgICAgICAgICAgICAgICAgKChFbnRpdHlSZXNvbHZlcldyYXBwZXIpIHhtbEVudGl0eVJlc29sdmVyKS5nZXRFbnRpdHlSZXNvbHZlcigpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIGlmICh4bWxFbnRpdHlSZXNvbHZlciBpbnN0YW5jZW9mIEVudGl0eVJlc29sdmVyMldyYXBwZXIpIHsKLSAgICAgICAgICAgICAgICAgICAgZW50aXR5UmVzb2x2ZXIgPQotICAgICAgICAgICAgICAgICAgICAgICAgKChFbnRpdHlSZXNvbHZlcjJXcmFwcGVyKSB4bWxFbnRpdHlSZXNvbHZlcikuZ2V0RW50aXR5UmVzb2x2ZXIoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gZSkgewotICAgICAgICAgICAgLy8gZG8gbm90aGluZwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBlbnRpdHlSZXNvbHZlcjsKLQotICAgIH0gLy8gZ2V0RW50aXR5UmVzb2x2ZXIoKTpFbnRpdHlSZXNvbHZlcgotCi0gICAgLyoqCi0gICAgICogQWxsb3cgYW4gYXBwbGljYXRpb24gdG8gcmVnaXN0ZXIgYW4gZXJyb3IgZXZlbnQgaGFuZGxlci4KLSAgICAgKgotICAgICAqIDxwPklmIHRoZSBhcHBsaWNhdGlvbiBkb2VzIG5vdCByZWdpc3RlciBhbiBlcnJvciBoYW5kbGVyLCBhbGwKLSAgICAgKiBlcnJvciBldmVudHMgcmVwb3J0ZWQgYnkgdGhlIFNBWCBwYXJzZXIgd2lsbCBiZSBzaWxlbnRseQotICAgICAqIGlnbm9yZWQ7IGhvd2V2ZXIsIG5vcm1hbCBwcm9jZXNzaW5nIG1heSBub3QgY29udGludWUuICBJdCBpcwotICAgICAqIGhpZ2hseSByZWNvbW1lbmRlZCB0aGF0IGFsbCBTQVggYXBwbGljYXRpb25zIGltcGxlbWVudCBhbgotICAgICAqIGVycm9yIGhhbmRsZXIgdG8gYXZvaWQgdW5leHBlY3RlZCBidWdzLjwvcD4KLSAgICAgKgotICAgICAqIDxwPkFwcGxpY2F0aW9ucyBtYXkgcmVnaXN0ZXIgYSBuZXcgb3IgZGlmZmVyZW50IGhhbmRsZXIgaW4gdGhlCi0gICAgICogbWlkZGxlIG9mIGEgcGFyc2UsIGFuZCB0aGUgU0FYIHBhcnNlciBtdXN0IGJlZ2luIHVzaW5nIHRoZSBuZXcKLSAgICAgKiBoYW5kbGVyIGltbWVkaWF0ZWx5LjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlcnJvckhhbmRsZXIgVGhlIGVycm9yIGhhbmRsZXIuCi0gICAgICogQGV4Y2VwdGlvbiBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24gSWYgdGhlIGhhbmRsZXIKLSAgICAgKiAgICAgICAgICAgIGFyZ3VtZW50IGlzIG51bGwuCi0gICAgICogQHNlZSAjZ2V0RXJyb3JIYW5kbGVyCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RXJyb3JIYW5kbGVyKEVycm9ySGFuZGxlciBlcnJvckhhbmRsZXIpIHsKLQotICAgICAgICB0cnkgewotICAgICAgICAgICAgWE1MRXJyb3JIYW5kbGVyIHhlaCA9IChYTUxFcnJvckhhbmRsZXIpIGZDb25maWd1cmF0aW9uLmdldFByb3BlcnR5KEVSUk9SX0hBTkRMRVIpOwotICAgICAgICAgICAgaWYgKHhlaCBpbnN0YW5jZW9mIEVycm9ySGFuZGxlcldyYXBwZXIpIHsKLSAgICAgICAgICAgICAgICBFcnJvckhhbmRsZXJXcmFwcGVyIGVodyA9IChFcnJvckhhbmRsZXJXcmFwcGVyKSB4ZWg7Ci0gICAgICAgICAgICAgICAgZWh3LnNldEVycm9ySGFuZGxlcihlcnJvckhhbmRsZXIpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgZkNvbmZpZ3VyYXRpb24uc2V0UHJvcGVydHkoRVJST1JfSEFORExFUiwKLSAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBFcnJvckhhbmRsZXJXcmFwcGVyKGVycm9ySGFuZGxlcikpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIC8vIGRvIG5vdGhpbmcKLSAgICAgICAgfQotCi0gICAgfSAvLyBzZXRFcnJvckhhbmRsZXIoRXJyb3JIYW5kbGVyKQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSBjdXJyZW50IGVycm9yIGhhbmRsZXIuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBjdXJyZW50IGVycm9yIGhhbmRsZXIsIG9yIG51bGwgaWYgbm9uZQotICAgICAqICAgICAgICAgaGFzIGJlZW4gcmVnaXN0ZXJlZC4KLSAgICAgKiBAc2VlICNzZXRFcnJvckhhbmRsZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgRXJyb3JIYW5kbGVyIGdldEVycm9ySGFuZGxlcigpIHsKLQotICAgICAgICBFcnJvckhhbmRsZXIgZXJyb3JIYW5kbGVyID0gbnVsbDsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIFhNTEVycm9ySGFuZGxlciB4bWxFcnJvckhhbmRsZXIgPQotICAgICAgICAgICAgICAgIChYTUxFcnJvckhhbmRsZXIpZkNvbmZpZ3VyYXRpb24uZ2V0UHJvcGVydHkoRVJST1JfSEFORExFUik7Ci0gICAgICAgICAgICBpZiAoeG1sRXJyb3JIYW5kbGVyICE9IG51bGwgJiYKLSAgICAgICAgICAgICAgICB4bWxFcnJvckhhbmRsZXIgaW5zdGFuY2VvZiBFcnJvckhhbmRsZXJXcmFwcGVyKSB7Ci0gICAgICAgICAgICAgICAgZXJyb3JIYW5kbGVyID0gKChFcnJvckhhbmRsZXJXcmFwcGVyKXhtbEVycm9ySGFuZGxlcikuZ2V0RXJyb3JIYW5kbGVyKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gZSkgewotICAgICAgICAgICAgLy8gZG8gbm90aGluZwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBlcnJvckhhbmRsZXI7Ci0KLSAgICB9IC8vIGdldEVycm9ySGFuZGxlcigpOkVycm9ySGFuZGxlcgotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSBzdGF0ZSBvZiBhbnkgZmVhdHVyZSBpbiBhIFNBWDIgcGFyc2VyLiAgVGhlIHBhcnNlcgotICAgICAqIG1pZ2h0IG5vdCByZWNvZ25pemUgdGhlIGZlYXR1cmUsIGFuZCBpZiBpdCBkb2VzIHJlY29nbml6ZQotICAgICAqIGl0LCBpdCBtaWdodCBub3QgYmUgYWJsZSB0byBmdWxmaWxsIHRoZSByZXF1ZXN0LgotICAgICAqCi0gICAgICogQHBhcmFtIGZlYXR1cmVJZCBUaGUgdW5pcXVlIGlkZW50aWZpZXIgKFVSSSkgb2YgdGhlIGZlYXR1cmUuCi0gICAgICogQHBhcmFtIHN0YXRlIFRoZSByZXF1ZXN0ZWQgc3RhdGUgb2YgdGhlIGZlYXR1cmUgKHRydWUgb3IgZmFsc2UpLgotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIElmIHRoZQotICAgICAqICAgICAgICAgICAgcmVxdWVzdGVkIGZlYXR1cmUgaXMgbm90IGtub3duLgotICAgICAqIEBleGNlcHRpb24gU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIElmIHRoZQotICAgICAqICAgICAgICAgICAgcmVxdWVzdGVkIGZlYXR1cmUgaXMga25vd24sIGJ1dCB0aGUgcmVxdWVzdGVkCi0gICAgICogICAgICAgICAgICBzdGF0ZSBpcyBub3Qgc3VwcG9ydGVkLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEZlYXR1cmUoU3RyaW5nIGZlYXR1cmVJZCwgYm9vbGVhbiBzdGF0ZSkKLSAgICAgICAgdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgdHJ5IHsKLQotICAgICAgICAgICAgLy8gaHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL3VzZS1lbnRpdHktcmVzb2x2ZXIyCi0gICAgICAgICAgICAvLyAgIGNvbnRyb2xzIHdoZXRoZXIgdGhlIG1ldGhvZHMgb2YgYW4gb2JqZWN0IGltcGxlbWVudGluZwotICAgICAgICAgICAgLy8gICBvcmcueG1sLnNheC5leHQuRW50aXR5UmVzb2x2ZXIyIHdpbGwgYmUgdXNlZCBieSB0aGUgcGFyc2VyLgotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIGlmIChmZWF0dXJlSWQuZXF1YWxzKFVTRV9FTlRJVFlfUkVTT0xWRVIyKSkgewotICAgICAgICAgICAgICAgIGlmIChzdGF0ZSAhPSBmVXNlRW50aXR5UmVzb2x2ZXIyKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZVc2VFbnRpdHlSZXNvbHZlcjIgPSBzdGF0ZTsKLSAgICAgICAgICAgICAgICAgICAgLy8gUmVmcmVzaCBFbnRpdHlSZXNvbHZlciB3cmFwcGVyLgotICAgICAgICAgICAgICAgICAgICBzZXRFbnRpdHlSZXNvbHZlcihnZXRFbnRpdHlSZXNvbHZlcigpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgLy8gRGVmYXVsdCBoYW5kbGluZwotICAgICAgICAgICAgLy8KLQotICAgICAgICAgICAgZkNvbmZpZ3VyYXRpb24uc2V0RmVhdHVyZShmZWF0dXJlSWQsIHN0YXRlKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICBTdHJpbmcgaWRlbnRpZmllciA9IGUuZ2V0SWRlbnRpZmllcigpOwotICAgICAgICAgICAgaWYgKGUuZ2V0VHlwZSgpID09IFN0YXR1cy5OT1RfUkVDT0dOSVpFRCkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICBTQVhNZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoZkNvbmZpZ3VyYXRpb24uZ2V0TG9jYWxlKCksCi0gICAgICAgICAgICAgICAgICAgICJmZWF0dXJlLW5vdC1yZWNvZ25pemVkIiwgbmV3IE9iamVjdCBbXSB7aWRlbnRpZmllcn0pKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgIFNBWE1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShmQ29uZmlndXJhdGlvbi5nZXRMb2NhbGUoKSwKLSAgICAgICAgICAgICAgICAgICAgImZlYXR1cmUtbm90LXN1cHBvcnRlZCIsIG5ldyBPYmplY3QgW10ge2lkZW50aWZpZXJ9KSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgIH0gLy8gc2V0RmVhdHVyZShTdHJpbmcsYm9vbGVhbikKLQotICAgIC8qKgotICAgICAqIFF1ZXJ5IHRoZSBzdGF0ZSBvZiBhIGZlYXR1cmUuCi0gICAgICoKLSAgICAgKiBRdWVyeSB0aGUgY3VycmVudCBzdGF0ZSBvZiBhbnkgZmVhdHVyZSBpbiBhIFNBWDIgcGFyc2VyLiAgVGhlCi0gICAgICogcGFyc2VyIG1pZ2h0IG5vdCByZWNvZ25pemUgdGhlIGZlYXR1cmUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZmVhdHVyZUlkIFRoZSB1bmlxdWUgaWRlbnRpZmllciAoVVJJKSBvZiB0aGUgZmVhdHVyZQotICAgICAqICAgICAgICAgICAgICAgICAgYmVpbmcgc2V0LgotICAgICAqIEByZXR1cm4gVGhlIGN1cnJlbnQgc3RhdGUgb2YgdGhlIGZlYXR1cmUuCi0gICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIElmIHRoZQotICAgICAqICAgICAgICAgICAgcmVxdWVzdGVkIGZlYXR1cmUgaXMgbm90IGtub3duLgotICAgICAqIEBleGNlcHRpb24gU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIElmIHRoZQotICAgICAqICAgICAgICAgICAgcmVxdWVzdGVkIGZlYXR1cmUgaXMga25vd24gYnV0IG5vdCBzdXBwb3J0ZWQuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0RmVhdHVyZShTdHJpbmcgZmVhdHVyZUlkKQotICAgICAgICB0aHJvd3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiwgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIHsKLQotICAgICAgICB0cnkgewotCi0gICAgICAgICAgICAvLyBodHRwOi8veG1sLm9yZy9zYXgvZmVhdHVyZXMvdXNlLWVudGl0eS1yZXNvbHZlcjIKLSAgICAgICAgICAgIC8vICAgY29udHJvbHMgd2hldGhlciB0aGUgbWV0aG9kcyBvZiBhbiBvYmplY3QgaW1wbGVtZW50aW5nCi0gICAgICAgICAgICAvLyAgIG9yZy54bWwuc2F4LmV4dC5FbnRpdHlSZXNvbHZlcjIgd2lsbCBiZSB1c2VkIGJ5IHRoZSBwYXJzZXIuCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgaWYgKGZlYXR1cmVJZC5lcXVhbHMoVVNFX0VOVElUWV9SRVNPTFZFUjIpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZVc2VFbnRpdHlSZXNvbHZlcjI7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAvLyBEZWZhdWx0IGhhbmRsaW5nCi0gICAgICAgICAgICAvLwotCi0gICAgICAgICAgICByZXR1cm4gZkNvbmZpZ3VyYXRpb24uZ2V0RmVhdHVyZShmZWF0dXJlSWQpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIFN0cmluZyBpZGVudGlmaWVyID0gZS5nZXRJZGVudGlmaWVyKCk7Ci0gICAgICAgICAgICBpZiAoZS5nZXRUeXBlKCkgPT0gU3RhdHVzLk5PVF9SRUNPR05JWkVEKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgIFNBWE1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShmQ29uZmlndXJhdGlvbi5nZXRMb2NhbGUoKSwKLSAgICAgICAgICAgICAgICAgICAgImZlYXR1cmUtbm90LXJlY29nbml6ZWQiLCBuZXcgT2JqZWN0IFtdIHtpZGVudGlmaWVyfSkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgU0FYTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKGZDb25maWd1cmF0aW9uLmdldExvY2FsZSgpLAotICAgICAgICAgICAgICAgICAgICAiZmVhdHVyZS1ub3Qtc3VwcG9ydGVkIiwgbmV3IE9iamVjdCBbXSB7aWRlbnRpZmllcn0pKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgfSAvLyBnZXRGZWF0dXJlKFN0cmluZyk6Ym9vbGVhbgotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSB2YWx1ZSBvZiBhbnkgcHJvcGVydHkgaW4gYSBTQVgyIHBhcnNlci4gIFRoZSBwYXJzZXIKLSAgICAgKiBtaWdodCBub3QgcmVjb2duaXplIHRoZSBwcm9wZXJ0eSwgYW5kIGlmIGl0IGRvZXMgcmVjb2duaXplCi0gICAgICogaXQsIGl0IG1pZ2h0IG5vdCBzdXBwb3J0IHRoZSByZXF1ZXN0ZWQgdmFsdWUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcHJvcGVydHlJZCBUaGUgdW5pcXVlIGlkZW50aWZpZXIgKFVSSSkgb2YgdGhlIHByb3BlcnR5Ci0gICAgICogICAgICAgICAgICAgICAgICAgYmVpbmcgc2V0LgotICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUgdG8gd2hpY2ggdGhlIHByb3BlcnR5IGlzIGJlaW5nIHNldC4KLSAgICAgKgotICAgICAqIEBleGNlcHRpb24gU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiBJZiB0aGUKLSAgICAgKiAgICAgICAgICAgIHJlcXVlc3RlZCBwcm9wZXJ0eSBpcyBub3Qga25vd24uCi0gICAgICogQGV4Y2VwdGlvbiBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gSWYgdGhlCi0gICAgICogICAgICAgICAgICByZXF1ZXN0ZWQgcHJvcGVydHkgaXMga25vd24sIGJ1dCB0aGUgcmVxdWVzdGVkCi0gICAgICogICAgICAgICAgICB2YWx1ZSBpcyBub3Qgc3VwcG9ydGVkLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFByb3BlcnR5KFN0cmluZyBwcm9wZXJ0eUlkLCBPYmplY3QgdmFsdWUpCi0gICAgICAgIHRocm93cyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uLCBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gewotICAgICAgICAvKioKLSAgICAgICAgICogSXQncyBwb3NzaWJsZSBmb3IgdXNlcnMgdG8gc2V0IGEgc2VjdXJpdHkgbWFuYWdlciB0aHJvdWdoIHRoZSBpbnRlcmZhY2UuCi0gICAgICAgICAqIElmIGl0J3MgdGhlIG9sZCBTZWN1cml0eU1hbmFnZXIsIGNvbnZlcnQgaXQgdG8gdGhlIG5ldyBYTUxTZWN1cml0eU1hbmFnZXIKLSAgICAgICAgICovCi0gICAgICAgIGlmIChwcm9wZXJ0eUlkLmVxdWFscyhDb25zdGFudHMuU0VDVVJJVFlfTUFOQUdFUikpIHsKLSAgICAgICAgICAgIHNlY3VyaXR5TWFuYWdlciA9IFhNTFNlY3VyaXR5TWFuYWdlci5jb252ZXJ0KHZhbHVlLCBzZWN1cml0eU1hbmFnZXIpOwotICAgICAgICAgICAgc2V0UHJvcGVydHkwKENvbnN0YW50cy5TRUNVUklUWV9NQU5BR0VSLCBzZWN1cml0eU1hbmFnZXIpOwotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0gICAgICAgIGlmIChwcm9wZXJ0eUlkLmVxdWFscyhDb25zdGFudHMuWE1MX1NFQ1VSSVRZX1BST1BFUlRZX01BTkFHRVIpKSB7Ci0gICAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHNlY3VyaXR5UHJvcGVydHlNYW5hZ2VyID0gbmV3IFhNTFNlY3VyaXR5UHJvcGVydHlNYW5hZ2VyKCk7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIHNlY3VyaXR5UHJvcGVydHlNYW5hZ2VyID0gKFhNTFNlY3VyaXR5UHJvcGVydHlNYW5hZ2VyKXZhbHVlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgc2V0UHJvcGVydHkwKENvbnN0YW50cy5YTUxfU0VDVVJJVFlfUFJPUEVSVFlfTUFOQUdFUiwgc2VjdXJpdHlQcm9wZXJ0eU1hbmFnZXIpOwotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKHNlY3VyaXR5TWFuYWdlciA9PSBudWxsKSB7Ci0gICAgICAgICAgICBzZWN1cml0eU1hbmFnZXIgPSBuZXcgWE1MU2VjdXJpdHlNYW5hZ2VyKHRydWUpOwotICAgICAgICAgICAgc2V0UHJvcGVydHkwKENvbnN0YW50cy5TRUNVUklUWV9NQU5BR0VSLCBzZWN1cml0eU1hbmFnZXIpOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKHNlY3VyaXR5UHJvcGVydHlNYW5hZ2VyID09IG51bGwpIHsKLSAgICAgICAgICAgIHNlY3VyaXR5UHJvcGVydHlNYW5hZ2VyID0gbmV3IFhNTFNlY3VyaXR5UHJvcGVydHlNYW5hZ2VyKCk7Ci0gICAgICAgICAgICBzZXRQcm9wZXJ0eTAoQ29uc3RhbnRzLlhNTF9TRUNVUklUWV9QUk9QRVJUWV9NQU5BR0VSLCBzZWN1cml0eVByb3BlcnR5TWFuYWdlcik7Ci0gICAgICAgIH0KLSAgICAgICAgaW50IGluZGV4ID0gc2VjdXJpdHlQcm9wZXJ0eU1hbmFnZXIuZ2V0SW5kZXgocHJvcGVydHlJZCk7Ci0KLSAgICAgICAgaWYgKGluZGV4ID4gLTEpIHsKLSAgICAgICAgICAgIC8qKgotICAgICAgICAgICAgICogdGhpcyBpcyBhIGRpcmVjdCBjYWxsIHRvIHRoaXMgcGFyc2VyLCBub3QgYSBzdWJjbGFzcyBzaW5jZQotICAgICAgICAgICAgICogaW50ZXJuYWxseSB0aGUgc3VwcG9ydCBvZiB0aGlzIHByb3BlcnR5IGlzIGRvbmUgdGhyb3VnaAotICAgICAgICAgICAgICogWE1MU2VjdXJpdHlQcm9wZXJ0eU1hbmFnZXIKLSAgICAgICAgICAgICAqLwotICAgICAgICAgICAgc2VjdXJpdHlQcm9wZXJ0eU1hbmFnZXIuc2V0VmFsdWUoaW5kZXgsIFhNTFNlY3VyaXR5UHJvcGVydHlNYW5hZ2VyLlN0YXRlLkFQSVBST1BFUlRZLCAoU3RyaW5nKXZhbHVlKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIC8vY2hlY2sgaWYgdGhlIHByb3BlcnR5IGlzIG1hbmFnZWQgYnkgc2VjdXJpdHkgbWFuYWdlcgotICAgICAgICAgICAgaWYgKCFzZWN1cml0eU1hbmFnZXIuc2V0TGltaXQocHJvcGVydHlJZCwgWE1MU2VjdXJpdHlNYW5hZ2VyLlN0YXRlLkFQSVBST1BFUlRZLCB2YWx1ZSkpIHsKLSAgICAgICAgICAgICAgICAvL2ZhbGwgYmFjayB0byB0aGUgZGVmYXVsdCBjb25maWd1cmF0aW9uIHRvIGhhbmRsZSB0aGUgcHJvcGVydHkKLSAgICAgICAgICAgICAgICBzZXRQcm9wZXJ0eTAocHJvcGVydHlJZCwgdmFsdWUpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0UHJvcGVydHkwKFN0cmluZyBwcm9wZXJ0eUlkLCBPYmplY3QgdmFsdWUpCi0gICAgICAgIHRocm93cyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uLCBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gewotICAgICAgICB0cnkgewotICAgICAgICAgICAgZkNvbmZpZ3VyYXRpb24uc2V0UHJvcGVydHkocHJvcGVydHlJZCwgdmFsdWUpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIFN0cmluZyBpZGVudGlmaWVyID0gZS5nZXRJZGVudGlmaWVyKCk7Ci0gICAgICAgICAgICBpZiAoZS5nZXRUeXBlKCkgPT0gU3RhdHVzLk5PVF9SRUNPR05JWkVEKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgIFNBWE1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShmQ29uZmlndXJhdGlvbi5nZXRMb2NhbGUoKSwKLSAgICAgICAgICAgICAgICAgICAgInByb3BlcnR5LW5vdC1yZWNvZ25pemVkIiwgbmV3IE9iamVjdCBbXSB7aWRlbnRpZmllcn0pKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgIFNBWE1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShmQ29uZmlndXJhdGlvbi5nZXRMb2NhbGUoKSwKLSAgICAgICAgICAgICAgICAgICAgInByb3BlcnR5LW5vdC1zdXBwb3J0ZWQiLCBuZXcgT2JqZWN0IFtdIHtpZGVudGlmaWVyfSkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICB9IC8vIHNldFByb3BlcnR5KFN0cmluZyxPYmplY3QpCi0KLSAgICAvKioKLSAgICAgKiBRdWVyeSB0aGUgdmFsdWUgb2YgYSBwcm9wZXJ0eS4KLSAgICAgKgotICAgICAqIFJldHVybiB0aGUgY3VycmVudCB2YWx1ZSBvZiBhIHByb3BlcnR5IGluIGEgU0FYMiBwYXJzZXIuCi0gICAgICogVGhlIHBhcnNlciBtaWdodCBub3QgcmVjb2duaXplIHRoZSBwcm9wZXJ0eS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBwcm9wZXJ0eUlkIFRoZSB1bmlxdWUgaWRlbnRpZmllciAoVVJJKSBvZiB0aGUgcHJvcGVydHkKLSAgICAgKiAgICAgICAgICAgICAgICAgICBiZWluZyBzZXQuCi0gICAgICogQHJldHVybiBUaGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgcHJvcGVydHkuCi0gICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIElmIHRoZQotICAgICAqICAgICAgICAgICAgcmVxdWVzdGVkIHByb3BlcnR5IGlzIG5vdCBrbm93bi4KLSAgICAgKiBAZXhjZXB0aW9uIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBJZiB0aGUKLSAgICAgKiAgICAgICAgICAgIHJlcXVlc3RlZCBwcm9wZXJ0eSBpcyBrbm93biBidXQgbm90IHN1cHBvcnRlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0IGdldFByb3BlcnR5KFN0cmluZyBwcm9wZXJ0eUlkKQotICAgICAgICB0aHJvd3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiwgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIHsKLQotICAgICAgIGlmIChwcm9wZXJ0eUlkLmVxdWFscyhDVVJSRU5UX0VMRU1FTlRfTk9ERSkpIHsKLSAgICAgICAgICAgYm9vbGVhbiBkZWZlcnJlZCA9IGZhbHNlOwotICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgZGVmZXJyZWQgPSBnZXRGZWF0dXJlKERFRkVSX05PREVfRVhQQU5TSU9OKTsKLSAgICAgICAgICAgfQotICAgICAgICAgICBjYXRjaCAoWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBlKXsKLSAgICAgICAgICAgICAgIC8vIGlnbm9yZQotICAgICAgICAgICB9Ci0gICAgICAgICAgIGlmIChkZWZlcnJlZCkgewotICAgICAgICAgICAgICAgdGhyb3cgbmV3IFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbigiQ3VycmVudCBlbGVtZW50IG5vZGUgY2Fubm90IGJlIHF1ZXJpZWQgd2hlbiBub2RlIGV4cGFuc2lvbiBpcyBkZWZlcnJlZC4iKTsKLSAgICAgICAgICAgfQotICAgICAgICAgICByZXR1cm4gKGZDdXJyZW50Tm9kZSE9bnVsbCAmJgotICAgICAgICAgICAgICAgICAgIGZDdXJyZW50Tm9kZS5nZXROb2RlVHlwZSgpID09IE5vZGUuRUxFTUVOVF9OT0RFKT8gZkN1cnJlbnROb2RlOm51bGw7Ci0gICAgICAgfQotCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBYTUxTZWN1cml0eVByb3BlcnR5TWFuYWdlciBzcG0gPSAoWE1MU2VjdXJpdHlQcm9wZXJ0eU1hbmFnZXIpCi0gICAgICAgICAgICAgICAgICAgIGZDb25maWd1cmF0aW9uLmdldFByb3BlcnR5KFhNTF9TRUNVUklUWV9QUk9QRVJUWV9NQU5BR0VSKTsKLSAgICAgICAgICAgIGludCBpbmRleCA9IHNwbS5nZXRJbmRleChwcm9wZXJ0eUlkKTsKLSAgICAgICAgICAgIGlmIChpbmRleCA+IC0xKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHNwbS5nZXRWYWx1ZUJ5SW5kZXgoaW5kZXgpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICByZXR1cm4gZkNvbmZpZ3VyYXRpb24uZ2V0UHJvcGVydHkocHJvcGVydHlJZCk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gZSkgewotICAgICAgICAgICAgU3RyaW5nIGlkZW50aWZpZXIgPSBlLmdldElkZW50aWZpZXIoKTsKLSAgICAgICAgICAgIGlmIChlLmdldFR5cGUoKSA9PSBTdGF0dXMuTk9UX1JFQ09HTklaRUQpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgU0FYTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKGZDb25maWd1cmF0aW9uLmdldExvY2FsZSgpLAotICAgICAgICAgICAgICAgICAgICAicHJvcGVydHktbm90LXJlY29nbml6ZWQiLCBuZXcgT2JqZWN0IFtdIHtpZGVudGlmaWVyfSkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgU0FYTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKGZDb25maWd1cmF0aW9uLmdldExvY2FsZSgpLAotICAgICAgICAgICAgICAgICAgICAicHJvcGVydHktbm90LXN1cHBvcnRlZCIsIG5ldyBPYmplY3QgW10ge2lkZW50aWZpZXJ9KSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgIH0gLy8gZ2V0UHJvcGVydHkoU3RyaW5nKTpPYmplY3QKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhpcyBwYXJzZXIncyBYTUxQYXJzZXJDb25maWd1cmF0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBYTUxQYXJzZXJDb25maWd1cmF0aW9uIGdldFhNTFBhcnNlckNvbmZpZ3VyYXRpb24oKSB7Ci0gICAgICAgIHJldHVybiBmQ29uZmlndXJhdGlvbjsKLSAgICB9IC8vIGdldFhNTFBhcnNlckNvbmZpZ3VyYXRpb24oKTpYTUxQYXJzZXJDb25maWd1cmF0aW9uCi0KLX0gLy8gY2xhc3MgRE9NUGFyc2VyCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9wYXJzZXJzL0RPTVBhcnNlckltcGwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3BhcnNlcnMvRE9NUGFyc2VySW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2MTRjODI2Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3BhcnNlcnMvRE9NUGFyc2VySW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTM5MiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAwLTIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwucGFyc2VyczsKLQotaW1wb3J0IGphdmEuaW8uU3RyaW5nUmVhZGVyOwotaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7Ci1pbXBvcnQgamF2YS51dGlsLlN0YWNrOwotaW1wb3J0IGphdmEudXRpbC5TdHJpbmdUb2tlbml6ZXI7Ci1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tLkRPTUVycm9ySW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbS5ET01NZXNzYWdlRm9ybWF0dGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tLkRPTVN0cmluZ0xpc3RJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5Db25zdGFudHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLkRPTUVudGl0eVJlc29sdmVyV3JhcHBlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuRE9NRXJyb3JIYW5kbGVyV3JhcHBlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuRE9NVXRpbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuU3ltYm9sVGFibGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlhNTFN5bWJvbHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuQXVnbWVudGF0aW9uczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5OYW1lc3BhY2VDb250ZXh0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlFOYW1lOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTEF0dHJpYnV0ZXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MRFREQ29udGVudE1vZGVsSGFuZGxlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxEVERIYW5kbGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTERvY3VtZW50SGFuZGxlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxMb2NhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTFJlc291cmNlSWRlbnRpZmllcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxTdHJpbmc7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE5JRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLmdyYW1tYXJzLlhNTEdyYW1tYXJQb29sOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxEVERDb250ZW50TW9kZWxTb3VyY2U7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTERURFNvdXJjZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MRG9jdW1lbnRTb3VyY2U7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTEVudGl0eVJlc29sdmVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxJbnB1dFNvdXJjZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MUGFyc2VFeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTFBhcnNlckNvbmZpZ3VyYXRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5wYXJzZXJzLlhJbmNsdWRlQXdhcmVQYXJzZXJDb25maWd1cmF0aW9uOwotaW1wb3J0IG9yZy53M2MuZG9tLkRPTUNvbmZpZ3VyYXRpb247Ci1pbXBvcnQgb3JnLnczYy5kb20uRE9NRXJyb3I7Ci1pbXBvcnQgb3JnLnczYy5kb20uRE9NRXJyb3JIYW5kbGVyOwotaW1wb3J0IG9yZy53M2MuZG9tLkRPTUV4Y2VwdGlvbjsKLWltcG9ydCBvcmcudzNjLmRvbS5ET01TdHJpbmdMaXN0OwotaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci1pbXBvcnQgb3JnLnczYy5kb20ubHMuTFNFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnczYy5kb20ubHMuTFNJbnB1dDsKLWltcG9ydCBvcmcudzNjLmRvbS5scy5MU1BhcnNlcjsKLWltcG9ydCBvcmcudzNjLmRvbS5scy5MU1BhcnNlckZpbHRlcjsKLWltcG9ydCBvcmcudzNjLmRvbS5scy5MU1Jlc291cmNlUmVzb2x2ZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotCi0KLS8qKgotICogVGhpcyBpcyBYZXJjZXMgRE9NIEJ1aWxkZXIgY2xhc3MuIEl0IHVzZXMgdGhlIGFic3RyYWN0IERPTQotICogcGFyc2VyIHdpdGggYSBkb2N1bWVudCBzY2FubmVyLCBhIGR0ZCBzY2FubmVyLCBhbmQgYSB2YWxpZGF0b3IsIGFzCi0gKiB3ZWxsIGFzIGEgZ3JhbW1hciBwb29sLgotICoKLSAqIEBhdXRob3IgUGF2YW5pIE11a3RoaXB1ZGksIFN1biBNaWNyb3N5c3RlbXMgSW5jLgotICogQGF1dGhvciBFbGVuYSBMaXRhbmksIElCTQotICogQGF1dGhvciBSYWh1bCBTcml2YXN0YXZhLCBTdW4gTWljcm9zeXN0ZW1zIEluYy4KLSAqIEB2ZXJzaW9uICRJZDogRE9NUGFyc2VySW1wbC5qYXZhLHYgMS44IDIwMTAtMTEtMDEgMDQ6NDA6MDkgam9laHcgRXhwICQKLSAqLwotCi0KLXB1YmxpYyBjbGFzcyBET01QYXJzZXJJbXBsCi1leHRlbmRzIEFic3RyYWN0RE9NUGFyc2VyIGltcGxlbWVudHMgTFNQYXJzZXIsIERPTUNvbmZpZ3VyYXRpb24gewotCi0KLQotICAgIC8vIFNBWCAmIFhlcmNlcyBmZWF0dXJlIGlkcwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogbmFtZXNwYWNlcy4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBOQU1FU1BBQ0VTID0KLSAgICBDb25zdGFudHMuU0FYX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLk5BTUVTUEFDRVNfRkVBVFVSRTsKLQotICAgIC8qKiBGZWF0dXJlIGlkOiB2YWxpZGF0aW9uLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFZBTElEQVRJT05fRkVBVFVSRSA9Ci0gICAgQ29uc3RhbnRzLlNBWF9GRUFUVVJFX1BSRUZJWCtDb25zdGFudHMuVkFMSURBVElPTl9GRUFUVVJFOwotCi0gICAgLyoqIFhNTCBTY2hlbWEgdmFsaWRhdGlvbiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFhNTFNDSEVNQSA9Ci0gICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5TQ0hFTUFfVkFMSURBVElPTl9GRUFUVVJFOwotCi0gICAgLyoqIFhNTCBTY2hlbWEgZnVsbCBjaGVja2luZyAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFhNTFNDSEVNQV9GVUxMX0NIRUNLSU5HID0KLSAgICBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLlNDSEVNQV9GVUxMX0NIRUNLSU5HOwotCi0gICAgLyoqIER5bmFtaWMgdmFsaWRhdGlvbiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIERZTkFNSUNfVkFMSURBVElPTiA9Ci0gICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5EWU5BTUlDX1ZBTElEQVRJT05fRkVBVFVSRTsKLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IGV4cG9zZSBzY2hlbWEgbm9ybWFsaXplZCB2YWx1ZSAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIE5PUk1BTElaRV9EQVRBID0KLSAgICBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLlNDSEVNQV9OT1JNQUxJWkVEX1ZBTFVFOwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogZGlzYWxsb3cgZG9jVHlwZSBEZWNscy4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBESVNBTExPV19ET0NUWVBFX0RFQ0xfRkVBVFVSRSA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuRElTQUxMT1dfRE9DVFlQRV9ERUNMX0ZFQVRVUkU7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiBuYW1lc3BhY2UgZ3Jvd3RoICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgTkFNRVNQQUNFX0dST1dUSCA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuTkFNRVNQQUNFX0dST1dUSF9GRUFUVVJFOwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogdG9sZXJhdGUgZHVwbGljYXRlcyAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFRPTEVSQVRFX0RVUExJQ0FURVMgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLlRPTEVSQVRFX0RVUExJQ0FURVNfRkVBVFVSRTsKLQotICAgIC8vIGludGVybmFsIHByb3BlcnRpZXMKLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBTWU1CT0xfVEFCTEUgPQotICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLlNZTUJPTF9UQUJMRV9QUk9QRVJUWTsKLQotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFBTVklfQVVHTUVOVCA9Ci0gICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArQ29uc3RhbnRzLlNDSEVNQV9BVUdNRU5UX1BTVkk7Ci0KLQotICAgIC8vCi0gICAgLy8gRGF0YQotICAgIC8vCi0KLSAgICAvKiogSW5jbHVkZSBuYW1lc3BhY2UgZGVjbGFyYXRpb24gYXR0cmlidXRlcyBpbiB0aGUgZG9jdW1lbnQuICoqLwotICAgIHByb3RlY3RlZCBib29sZWFuIGZOYW1lc3BhY2VEZWNsYXJhdGlvbnMgPSB0cnVlOwotCi0gICAgLy8gUkVWSVNJVDogdGhpcyB2YWx1ZSBzaG91bGQgYmUgbnVsbCBieSBkZWZhdWx0IGFuZCBzaG91bGQgYmUgc2V0IGR1cmluZyBjcmVhdGlvbiBvZgotICAgIC8vICAgICAgICAgIExTUGFyc2VyCi0gICAgcHJvdGVjdGVkIFN0cmluZyBmU2NoZW1hVHlwZSA9IG51bGw7Ci0KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBmQnVzeSA9IGZhbHNlOwotCi0gICAgcHJpdmF0ZSBib29sZWFuIGFib3J0Tm93ID0gZmFsc2U7Ci0KLSAgICBwcml2YXRlIFRocmVhZCBjdXJyZW50VGhyZWFkOwotCi0gICAgcHJvdGVjdGVkIGZpbmFsIHN0YXRpYyBib29sZWFuIERFQlVHID0gZmFsc2U7Ci0KLSAgICBwcml2YXRlIFZlY3RvciBmU2NoZW1hTG9jYXRpb25zID0gbmV3IFZlY3RvciAoKTsKLSAgICBwcml2YXRlIFN0cmluZyBmU2NoZW1hTG9jYXRpb24gPSBudWxsOwotICAgICAgICBwcml2YXRlIERPTVN0cmluZ0xpc3QgZlJlY29nbml6ZWRQYXJhbWV0ZXJzOwotCi0gICAgcHJpdmF0ZSBBYm9ydEhhbmRsZXIgYWJvcnRIYW5kbGVyID0gbnVsbDsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHMgYSBET00gQnVpbGRlciB1c2luZyB0aGUgc3RhbmRhcmQgcGFyc2VyIGNvbmZpZ3VyYXRpb24uCi0gICAgICovCi0gICAgcHVibGljIERPTVBhcnNlckltcGwgKFhNTFBhcnNlckNvbmZpZ3VyYXRpb24gY29uZmlnLCBTdHJpbmcgc2NoZW1hVHlwZSkgewotICAgICAgICB0aGlzIChjb25maWcpOwotICAgICAgICBpZiAoc2NoZW1hVHlwZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAoc2NoZW1hVHlwZS5lcXVhbHMgKENvbnN0YW50cy5OU19EVEQpKSB7Ci0gICAgICAgICAgICAgICAgLy9TY2hlbWEgdmFsaWRhdGlvbiBpcyBmYWxzZSBieSBkZWZhdWx0IGFuZCBoZW5jZSB0aGVyZSBpcyBubwotICAgICAgICAgICAgICAgIC8vbmVlZCB0byBzZXQgaXQgdG8gZmFsc2UgaGVyZS4gIEFsc28sIHNjaGVtYSB2YWxpZGF0aW9uIGlzCi0gICAgICAgICAgICAgICAgLy9ub3QgYSByZWNvZ25pemVkIGZlYXR1cmUgZm9yIERURENvbmZpZ3VyYXRpb24ncyBhbmQgc28KLSAgICAgICAgICAgICAgICAvL3NldHRpbmcgdGhpcyBmZWF0dXJlIGhlcmUgd291bGQgcmVzdWx0IGluIGEgQ29uZmlndXJhdGlvbgotICAgICAgICAgICAgICAgIC8vRXhjZXB0aW9uLgotICAgICAgICAgICAgICAgIGZDb25maWd1cmF0aW9uLnNldFByb3BlcnR5ICgKLSAgICAgICAgICAgICAgICBDb25zdGFudHMuSkFYUF9QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuU0NIRU1BX0xBTkdVQUdFLAotICAgICAgICAgICAgICAgIENvbnN0YW50cy5OU19EVEQpOwotICAgICAgICAgICAgICAgIGZTY2hlbWFUeXBlID0gQ29uc3RhbnRzLk5TX0RURDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKHNjaGVtYVR5cGUuZXF1YWxzIChDb25zdGFudHMuTlNfWE1MU0NIRU1BKSkgewotICAgICAgICAgICAgICAgIC8vIFhNTCBTY2hlbSB2YWxpZGF0aW9uCi0gICAgICAgICAgICAgICAgZkNvbmZpZ3VyYXRpb24uc2V0UHJvcGVydHkgKAotICAgICAgICAgICAgICAgIENvbnN0YW50cy5KQVhQX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5TQ0hFTUFfTEFOR1VBR0UsCi0gICAgICAgICAgICAgICAgQ29uc3RhbnRzLk5TX1hNTFNDSEVNQSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHMgYSBET00gQnVpbGRlciB1c2luZyB0aGUgc3BlY2lmaWVkIHBhcnNlciBjb25maWd1cmF0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBET01QYXJzZXJJbXBsIChYTUxQYXJzZXJDb25maWd1cmF0aW9uIGNvbmZpZykgewotICAgICAgICBzdXBlciAoY29uZmlnKTsKLQotICAgICAgICAvLyBhZGQgcmVjb2duaXplZCBmZWF0dXJlcwotICAgICAgICBmaW5hbCBTdHJpbmdbXSBkb21SZWNvZ25pemVkRmVhdHVyZXMgPSB7Ci0gICAgICAgICAgICBDb25zdGFudHMuRE9NX0NBTk9OSUNBTF9GT1JNLAotICAgICAgICAgICAgQ29uc3RhbnRzLkRPTV9DREFUQV9TRUNUSU9OUywKLSAgICAgICAgICAgIENvbnN0YW50cy5ET01fQ0hBUlNFVF9PVkVSUklERVNfWE1MX0VOQ09ESU5HLAotICAgICAgICAgICAgQ29uc3RhbnRzLkRPTV9JTkZPU0VULAotICAgICAgICAgICAgQ29uc3RhbnRzLkRPTV9OQU1FU1BBQ0VfREVDTEFSQVRJT05TLAotICAgICAgICAgICAgQ29uc3RhbnRzLkRPTV9TUExJVF9DREFUQSwKLSAgICAgICAgICAgIENvbnN0YW50cy5ET01fU1VQUE9SVEVEX01FRElBVFlQRVNfT05MWSwKLSAgICAgICAgICAgIENvbnN0YW50cy5ET01fQ0VSVElGSUVELAotICAgICAgICAgICAgQ29uc3RhbnRzLkRPTV9XRUxMRk9STUVELAotICAgICAgICAgICAgQ29uc3RhbnRzLkRPTV9JR05PUkVfVU5LTk9XTl9DSEFSQUNURVJfREVOT1JNQUxJWkFUSU9OUywKLSAgICAgICAgfTsKLQotICAgICAgICBmQ29uZmlndXJhdGlvbi5hZGRSZWNvZ25pemVkRmVhdHVyZXMgKGRvbVJlY29nbml6ZWRGZWF0dXJlcyk7Ci0KLSAgICAgICAgLy8gdHVybiBvZmYgZGVmZXJyZWQgRE9NCi0gICAgICAgIGZDb25maWd1cmF0aW9uLnNldEZlYXR1cmUgKERFRkVSX05PREVfRVhQQU5TSU9OLCBmYWxzZSk7Ci0KLSAgICAgICAgLy8gU2V0IHZhbHVlcyBzbyB0aGF0IHRoZSB2YWx1ZSBvZiB0aGUKLSAgICAgICAgLy8gaW5mb3NldCBwYXJhbWV0ZXIgaXMgdHJ1ZSAoaXRzIGRlZmF1bHQgdmFsdWUpLgotICAgICAgICAvLwotICAgICAgICAvLyB0cnVlOiBuYW1lc3BhY2UtZGVjbGFyYXRpb25zLCB3ZWxsLWZvcm1lZCwKLSAgICAgICAgLy8gZWxlbWVudC1jb250ZW50LXdoaXRlc3BhY2UsIGNvbW1lbnRzLCBuYW1lc3BhY2VzCi0gICAgICAgIC8vCi0gICAgICAgIC8vIGZhbHNlOiB2YWxpZGF0ZS1pZi1zY2hlbWEsIGVudGl0aWVzLAotICAgICAgICAvLyBkYXRhdHlwZS1ub3JtYWxpemF0aW9uLCBjZGF0YS1zZWN0aW9ucwotCi0gICAgICAgIGZDb25maWd1cmF0aW9uLnNldEZlYXR1cmUoQ29uc3RhbnRzLkRPTV9OQU1FU1BBQ0VfREVDTEFSQVRJT05TLCB0cnVlKTsKLSAgICAgICAgZkNvbmZpZ3VyYXRpb24uc2V0RmVhdHVyZShDb25zdGFudHMuRE9NX1dFTExGT1JNRUQsIHRydWUpOwotICAgICAgICBmQ29uZmlndXJhdGlvbi5zZXRGZWF0dXJlKElOQ0xVREVfQ09NTUVOVFNfRkVBVFVSRSwgdHJ1ZSk7Ci0gICAgICAgIGZDb25maWd1cmF0aW9uLnNldEZlYXR1cmUoSU5DTFVERV9JR05PUkFCTEVfV0hJVEVTUEFDRSwgdHJ1ZSk7Ci0gICAgICAgIGZDb25maWd1cmF0aW9uLnNldEZlYXR1cmUoTkFNRVNQQUNFUywgdHJ1ZSk7Ci0KLSAgICAgICAgZkNvbmZpZ3VyYXRpb24uc2V0RmVhdHVyZShEWU5BTUlDX1ZBTElEQVRJT04sIGZhbHNlKTsKLSAgICAgICAgZkNvbmZpZ3VyYXRpb24uc2V0RmVhdHVyZShDUkVBVEVfRU5USVRZX1JFRl9OT0RFUywgZmFsc2UpOwotICAgICAgICBmQ29uZmlndXJhdGlvbi5zZXRGZWF0dXJlKENSRUFURV9DREFUQV9OT0RFU19GRUFUVVJFLCBmYWxzZSk7Ci0KLSAgICAgICAgLy8gc2V0IG90aGVyIGRlZmF1bHQgdmFsdWVzCi0gICAgICAgIGZDb25maWd1cmF0aW9uLnNldEZlYXR1cmUgKENvbnN0YW50cy5ET01fQ0FOT05JQ0FMX0ZPUk0sIGZhbHNlKTsKLSAgICAgICAgZkNvbmZpZ3VyYXRpb24uc2V0RmVhdHVyZSAoQ29uc3RhbnRzLkRPTV9DSEFSU0VUX09WRVJSSURFU19YTUxfRU5DT0RJTkcsIHRydWUpOwotICAgICAgICBmQ29uZmlndXJhdGlvbi5zZXRGZWF0dXJlIChDb25zdGFudHMuRE9NX1NQTElUX0NEQVRBLCB0cnVlKTsKLSAgICAgICAgZkNvbmZpZ3VyYXRpb24uc2V0RmVhdHVyZSAoQ29uc3RhbnRzLkRPTV9TVVBQT1JURURfTUVESUFUWVBFU19PTkxZLCBmYWxzZSk7Ci0gICAgICAgIGZDb25maWd1cmF0aW9uLnNldEZlYXR1cmUgKENvbnN0YW50cy5ET01fSUdOT1JFX1VOS05PV05fQ0hBUkFDVEVSX0RFTk9STUFMSVpBVElPTlMsIHRydWUpOwotCi0gICAgICAgIC8vIFJFVklTSVQ6IGJ5IGRlZmF1bHQgWGVyY2VzIGFzc3VtZXMgdGhhdCBpbnB1dCBpcyBjZXJ0aWZpZWQuCi0gICAgICAgIC8vICAgICAgICAgIGRlZmF1bHQgaXMgZGlmZmVyZW50IGZyb20gdGhlIG9uZSBzcGVjaWZpZWQgaW4gdGhlIERPTSBzcGVjCi0gICAgICAgIGZDb25maWd1cmF0aW9uLnNldEZlYXR1cmUgKENvbnN0YW50cy5ET01fQ0VSVElGSUVELCB0cnVlKTsKLQotICAgICAgICAvLyBYZXJjZXMgZGF0YXR5cGUtbm9ybWFsaXphdGlvbiBmZWF0dXJlIGlzIG9uIGJ5IGRlZmF1bHQKLSAgICAgICAgLy8gVGhpcyBpcyBhIHJlY29nbml6ZWQgZmVhdHVyZSBvbmx5IGZvciBYTUwgU2NoZW1hcy4gSWYgdGhlCi0gICAgICAgIC8vIGNvbmZpZ3VyYXRpb24gZG9lc24ndCBzdXBwb3J0IHRoaXMgZmVhdHVyZSwgaWdub3JlIGl0LgotICAgICAgICB0cnkgewotICAgICAgICAgICAgZkNvbmZpZ3VyYXRpb24uc2V0RmVhdHVyZSAoIE5PUk1BTElaRV9EQVRBLCBmYWxzZSApOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIGV4Yykge30KLQotICAgIH0gLy8gPGluaXQ+KFhNTFBhcnNlckNvbmZpZ3VyYXRpb24pCi0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RzIGEgRE9NIEJ1aWxkZXIgdXNpbmcgdGhlIHNwZWNpZmllZCBzeW1ib2wgdGFibGUuCi0gICAgICovCi0gICAgcHVibGljIERPTVBhcnNlckltcGwgKFN5bWJvbFRhYmxlIHN5bWJvbFRhYmxlKSB7Ci0gICAgICAgIHRoaXMgKG5ldyBYSW5jbHVkZUF3YXJlUGFyc2VyQ29uZmlndXJhdGlvbigpKTsKLSAgICAgICAgZkNvbmZpZ3VyYXRpb24uc2V0UHJvcGVydHkgKAotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5TWU1CT0xfVEFCTEVfUFJPUEVSVFksCi0gICAgICAgIHN5bWJvbFRhYmxlKTsKLSAgICB9IC8vIDxpbml0PihTeW1ib2xUYWJsZSkKLQotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0cyBhIERPTSBCdWlsZGVyIHVzaW5nIHRoZSBzcGVjaWZpZWQgc3ltYm9sIHRhYmxlIGFuZAotICAgICAqIGdyYW1tYXIgcG9vbC4KLSAgICAgKi8KLSAgICBwdWJsaWMgRE9NUGFyc2VySW1wbCAoU3ltYm9sVGFibGUgc3ltYm9sVGFibGUsIFhNTEdyYW1tYXJQb29sIGdyYW1tYXJQb29sKSB7Ci0gICAgICAgIHRoaXMgKG5ldyBYSW5jbHVkZUF3YXJlUGFyc2VyQ29uZmlndXJhdGlvbigpKTsKLSAgICAgICAgZkNvbmZpZ3VyYXRpb24uc2V0UHJvcGVydHkgKAotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5TWU1CT0xfVEFCTEVfUFJPUEVSVFksCi0gICAgICAgIHN5bWJvbFRhYmxlKTsKLSAgICAgICAgZkNvbmZpZ3VyYXRpb24uc2V0UHJvcGVydHkgKAotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWAotICAgICAgICArIENvbnN0YW50cy5YTUxHUkFNTUFSX1BPT0xfUFJPUEVSVFksCi0gICAgICAgIGdyYW1tYXJQb29sKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXNldHMgdGhlIHBhcnNlciBzdGF0ZS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uIFRocm93biBvbiBpbml0aWFsaXphdGlvbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCByZXNldCAoKSB7Ci0gICAgICAgIHN1cGVyLnJlc2V0ICgpOwotCi0gICAgICAgIC8vIGdldCBzdGF0ZSBvZiBuYW1lc3BhY2UtZGVjbGFyYXRpb25zIHBhcmFtZXRlci4KLSAgICAgICAgZk5hbWVzcGFjZURlY2xhcmF0aW9ucyA9Ci0gICAgICAgICAgICBmQ29uZmlndXJhdGlvbi5nZXRGZWF0dXJlKENvbnN0YW50cy5ET01fTkFNRVNQQUNFX0RFQ0xBUkFUSU9OUyk7Ci0KLSAgICAgICAgLy8gRE9NIEZpbHRlcgotICAgICAgICBpZiAoZlNraXBwZWRFbGVtU3RhY2shPW51bGwpIHsKLSAgICAgICAgICAgIGZTa2lwcGVkRWxlbVN0YWNrLnJlbW92ZUFsbEVsZW1lbnRzICgpOwotICAgICAgICB9Ci0gICAgICAgIGZTY2hlbWFMb2NhdGlvbnMuY2xlYXIgKCk7Ci0gICAgICAgIGZSZWplY3RlZEVsZW1lbnREZXB0aCA9IDA7Ci0gICAgICAgIGZGaWx0ZXJSZWplY3QgPSBmYWxzZTsKLSAgICAgICAgZlNjaGVtYVR5cGUgPSBudWxsOwotCi0gICAgfSAvLyByZXNldCgpCi0KLSAgICAvLwotICAgIC8vIERPTVBhcnNlciBtZXRob2RzCi0gICAgLy8KLQotICAgIHB1YmxpYyBET01Db25maWd1cmF0aW9uIGdldERvbUNvbmZpZyAoKXsKLSAgICAgICAgcmV0dXJuIHRoaXM7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiAgV2hlbiB0aGUgYXBwbGljYXRpb24gcHJvdmlkZXMgYSBmaWx0ZXIsIHRoZSBwYXJzZXIgd2lsbCBjYWxsIG91dCB0bwotICAgICAqIHRoZSBmaWx0ZXIgYXQgdGhlIGNvbXBsZXRpb24gb2YgdGhlIGNvbnN0cnVjdGlvbiBvZiBlYWNoCi0gICAgICogPGNvZGU+RWxlbWVudDwvY29kZT4gbm9kZS4gVGhlIGZpbHRlciBpbXBsZW1lbnRhdGlvbiBjYW4gY2hvb3NlIHRvCi0gICAgICogcmVtb3ZlIHRoZSBlbGVtZW50IGZyb20gdGhlIGRvY3VtZW50IGJlaW5nIGNvbnN0cnVjdGVkICh1bmxlc3MgdGhlCi0gICAgICogZWxlbWVudCBpcyB0aGUgZG9jdW1lbnQgZWxlbWVudCkgb3IgdG8gdGVybWluYXRlIHRoZSBwYXJzZSBlYXJseS4gSWYKLSAgICAgKiB0aGUgZG9jdW1lbnQgaXMgYmVpbmcgdmFsaWRhdGVkIHdoZW4gaXQncyBsb2FkZWQgdGhlIHZhbGlkYXRpb24KLSAgICAgKiBoYXBwZW5zIGJlZm9yZSB0aGUgZmlsdGVyIGlzIGNhbGxlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgTFNQYXJzZXJGaWx0ZXIgZ2V0RmlsdGVyICgpIHsKLSAgICAgICAgcmV0dXJuIGZET01GaWx0ZXI7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogIFdoZW4gdGhlIGFwcGxpY2F0aW9uIHByb3ZpZGVzIGEgZmlsdGVyLCB0aGUgcGFyc2VyIHdpbGwgY2FsbCBvdXQgdG8KLSAgICAgKiB0aGUgZmlsdGVyIGF0IHRoZSBjb21wbGV0aW9uIG9mIHRoZSBjb25zdHJ1Y3Rpb24gb2YgZWFjaAotICAgICAqIDxjb2RlPkVsZW1lbnQ8L2NvZGU+IG5vZGUuIFRoZSBmaWx0ZXIgaW1wbGVtZW50YXRpb24gY2FuIGNob29zZSB0bwotICAgICAqIHJlbW92ZSB0aGUgZWxlbWVudCBmcm9tIHRoZSBkb2N1bWVudCBiZWluZyBjb25zdHJ1Y3RlZCAodW5sZXNzIHRoZQotICAgICAqIGVsZW1lbnQgaXMgdGhlIGRvY3VtZW50IGVsZW1lbnQpIG9yIHRvIHRlcm1pbmF0ZSB0aGUgcGFyc2UgZWFybHkuIElmCi0gICAgICogdGhlIGRvY3VtZW50IGlzIGJlaW5nIHZhbGlkYXRlZCB3aGVuIGl0J3MgbG9hZGVkIHRoZSB2YWxpZGF0aW9uCi0gICAgICogaGFwcGVucyBiZWZvcmUgdGhlIGZpbHRlciBpcyBjYWxsZWQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RmlsdGVyIChMU1BhcnNlckZpbHRlciBmaWx0ZXIpIHsKLSAgICAgICAgZkRPTUZpbHRlciA9IGZpbHRlcjsKLSAgICAgICAgaWYgKGZTa2lwcGVkRWxlbVN0YWNrID09IG51bGwpIHsKLSAgICAgICAgICAgIGZTa2lwcGVkRWxlbVN0YWNrID0gbmV3IFN0YWNrICgpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0IHBhcmFtZXRlcnMgYW5kIHByb3BlcnRpZXMKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRQYXJhbWV0ZXIgKFN0cmluZyBuYW1lLCBPYmplY3QgdmFsdWUpIHRocm93cyBET01FeGNlcHRpb24gewotICAgICAgICAvLyBzZXQgZmVhdHVyZXMKLQotICAgICAgICBpZih2YWx1ZSBpbnN0YW5jZW9mIEJvb2xlYW4pewotICAgICAgICAgICAgYm9vbGVhbiBzdGF0ZSA9ICgoQm9vbGVhbil2YWx1ZSkuYm9vbGVhblZhbHVlICgpOwotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICBpZiAobmFtZS5lcXVhbHNJZ25vcmVDYXNlIChDb25zdGFudHMuRE9NX0NPTU1FTlRTKSkgewotICAgICAgICAgICAgICAgICAgICBmQ29uZmlndXJhdGlvbi5zZXRGZWF0dXJlIChJTkNMVURFX0NPTU1FTlRTX0ZFQVRVUkUsIHN0YXRlKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSBpZiAobmFtZS5lcXVhbHNJZ25vcmVDYXNlIChDb25zdGFudHMuRE9NX0RBVEFUWVBFX05PUk1BTElaQVRJT04pKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZDb25maWd1cmF0aW9uLnNldEZlYXR1cmUgKE5PUk1BTElaRV9EQVRBLCBzdGF0ZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzSWdub3JlQ2FzZSAoQ29uc3RhbnRzLkRPTV9FTlRJVElFUykpIHsKLSAgICAgICAgICAgICAgICAgICAgZkNvbmZpZ3VyYXRpb24uc2V0RmVhdHVyZSAoQ1JFQVRFX0VOVElUWV9SRUZfTk9ERVMsIHN0YXRlKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSBpZiAobmFtZS5lcXVhbHNJZ25vcmVDYXNlIChDb25zdGFudHMuRE9NX0RJU0FMTE9XX0RPQ1RZUEUpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZDb25maWd1cmF0aW9uLnNldEZlYXR1cmUgKERJU0FMTE9XX0RPQ1RZUEVfREVDTF9GRUFUVVJFLCBzdGF0ZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzSWdub3JlQ2FzZSAoQ29uc3RhbnRzLkRPTV9TVVBQT1JURURfTUVESUFUWVBFU19PTkxZKQotICAgICAgICAgICAgICAgIHx8IG5hbWUuZXF1YWxzSWdub3JlQ2FzZShDb25zdGFudHMuRE9NX05PUk1BTElaRV9DSEFSQUNURVJTKQotICAgICAgICAgICAgICAgIHx8IG5hbWUuZXF1YWxzSWdub3JlQ2FzZSAoQ29uc3RhbnRzLkRPTV9DSEVDS19DSEFSX05PUk1BTElaQVRJT04pCi0gICAgICAgICAgICAgICAgfHwgbmFtZS5lcXVhbHNJZ25vcmVDYXNlIChDb25zdGFudHMuRE9NX0NBTk9OSUNBTF9GT1JNKSkgewotICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdGUpIHsgLy8gdHJ1ZSBpcyBub3Qgc3VwcG9ydGVkCi0gICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbXNnID0KLSAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZSAoCi0gICAgICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAiRkVBVFVSRV9OT1RfU1VQUE9SVEVEIiwKLSAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7IG5hbWUgfSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uIChET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIsIG1zZyk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgLy8gc2V0dGluZyB0aG9zZSBmZWF0dXJlcyB0byBmYWxzZSBpcyBuby1vcAotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFsc0lnbm9yZUNhc2UgKENvbnN0YW50cy5ET01fTkFNRVNQQUNFUykpIHsKLSAgICAgICAgICAgICAgICAgICAgZkNvbmZpZ3VyYXRpb24uc2V0RmVhdHVyZSAoTkFNRVNQQUNFUywgc3RhdGUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFsc0lnbm9yZUNhc2UgKENvbnN0YW50cy5ET01fSU5GT1NFVCkpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gU2V0dGluZyBmYWxzZSBoYXMgbm8gZWZmZWN0LgotICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdGUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRydWU6IG5hbWVzcGFjZXMsIG5hbWVzcGFjZS1kZWNsYXJhdGlvbnMsCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBjb21tZW50cywgZWxlbWVudC1jb250ZW50LXdoaXRlc3BhY2UKLSAgICAgICAgICAgICAgICAgICAgICAgIGZDb25maWd1cmF0aW9uLnNldEZlYXR1cmUoTkFNRVNQQUNFUywgdHJ1ZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmQ29uZmlndXJhdGlvbi5zZXRGZWF0dXJlKENvbnN0YW50cy5ET01fTkFNRVNQQUNFX0RFQ0xBUkFUSU9OUywgdHJ1ZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmQ29uZmlndXJhdGlvbi5zZXRGZWF0dXJlKElOQ0xVREVfQ09NTUVOVFNfRkVBVFVSRSwgdHJ1ZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmQ29uZmlndXJhdGlvbi5zZXRGZWF0dXJlKElOQ0xVREVfSUdOT1JBQkxFX1dISVRFU1BBQ0UsIHRydWUpOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBmYWxzZTogdmFsaWRhdGUtaWYtc2NoZW1hLCBlbnRpdGllcywKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGRhdGF0eXBlLW5vcm1hbGl6YXRpb24sIGNkYXRhLXNlY3Rpb25zCi0gICAgICAgICAgICAgICAgICAgICAgICBmQ29uZmlndXJhdGlvbi5zZXRGZWF0dXJlKERZTkFNSUNfVkFMSURBVElPTiwgZmFsc2UpOwotICAgICAgICAgICAgICAgICAgICAgICAgZkNvbmZpZ3VyYXRpb24uc2V0RmVhdHVyZShDUkVBVEVfRU5USVRZX1JFRl9OT0RFUywgZmFsc2UpOwotICAgICAgICAgICAgICAgICAgICAgICAgZkNvbmZpZ3VyYXRpb24uc2V0RmVhdHVyZShOT1JNQUxJWkVfREFUQSwgZmFsc2UpOwotICAgICAgICAgICAgICAgICAgICAgICAgZkNvbmZpZ3VyYXRpb24uc2V0RmVhdHVyZShDUkVBVEVfQ0RBVEFfTk9ERVNfRkVBVFVSRSwgZmFsc2UpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzSWdub3JlQ2FzZShDb25zdGFudHMuRE9NX0NEQVRBX1NFQ1RJT05TKSkgewotICAgICAgICAgICAgICAgICAgICBmQ29uZmlndXJhdGlvbi5zZXRGZWF0dXJlKENSRUFURV9DREFUQV9OT0RFU19GRUFUVVJFLCBzdGF0ZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzSWdub3JlQ2FzZSAoQ29uc3RhbnRzLkRPTV9OQU1FU1BBQ0VfREVDTEFSQVRJT05TKSkgewotICAgICAgICAgICAgICAgICAgICBmQ29uZmlndXJhdGlvbi5zZXRGZWF0dXJlKENvbnN0YW50cy5ET01fTkFNRVNQQUNFX0RFQ0xBUkFUSU9OUywgc3RhdGUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFsc0lnbm9yZUNhc2UgKENvbnN0YW50cy5ET01fV0VMTEZPUk1FRCkKLSAgICAgICAgICAgICAgICB8fCBuYW1lLmVxdWFsc0lnbm9yZUNhc2UgKENvbnN0YW50cy5ET01fSUdOT1JFX1VOS05PV05fQ0hBUkFDVEVSX0RFTk9STUFMSVpBVElPTlMpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmICghc3RhdGUpIHsgLy8gZmFsc2UgaXMgbm90IHN1cHBvcnRlZAotICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG1zZyA9Ci0gICAgICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UgKAotICAgICAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgIkZFQVRVUkVfTk9UX1NVUFBPUlRFRCIsCi0gICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBuYW1lIH0pOwotICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbiAoRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSLCBtc2cpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIC8vIHNldHRpbmcgdGhlc2UgZmVhdHVyZXMgdG8gdHJ1ZSBpcyBuby1vcAotICAgICAgICAgICAgICAgICAgICAvLyBSRVZJU0lUOiBpbXBsZW1lbnQgIm5hbWVzcGFjZS1kZWNsYXJhdGlvbiIgZmVhdHVyZQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFsc0lnbm9yZUNhc2UgKENvbnN0YW50cy5ET01fVkFMSURBVEUpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZDb25maWd1cmF0aW9uLnNldEZlYXR1cmUgKFZBTElEQVRJT05fRkVBVFVSRSwgc3RhdGUpOwotICAgICAgICAgICAgICAgICAgICBpZiAoZlNjaGVtYVR5cGUgIT0gQ29uc3RhbnRzLk5TX0RURCkgewotICAgICAgICAgICAgICAgICAgICAgICAgZkNvbmZpZ3VyYXRpb24uc2V0RmVhdHVyZSAoWE1MU0NIRU1BLCBzdGF0ZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmQ29uZmlndXJhdGlvbi5zZXRGZWF0dXJlIChYTUxTQ0hFTUFfRlVMTF9DSEVDS0lORywgc3RhdGUpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGlmIChzdGF0ZSl7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmQ29uZmlndXJhdGlvbi5zZXRGZWF0dXJlIChEWU5BTUlDX1ZBTElEQVRJT04sIGZhbHNlKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFsc0lnbm9yZUNhc2UgKENvbnN0YW50cy5ET01fVkFMSURBVEVfSUZfU0NIRU1BKSkgewotICAgICAgICAgICAgICAgICAgICBmQ29uZmlndXJhdGlvbi5zZXRGZWF0dXJlIChEWU5BTUlDX1ZBTElEQVRJT04sIHN0YXRlKTsKLSAgICAgICAgICAgICAgICAgICAgLy8gTm90ZTogdmFsaWRhdGlvbiBhbmQgZHluYW1pYyB2YWxpZGF0aW9uIGFyZSBtdXR1YWxseSBleGNsdXNpdmUKLSAgICAgICAgICAgICAgICAgICAgaWYgKHN0YXRlKXsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZDb25maWd1cmF0aW9uLnNldEZlYXR1cmUgKFZBTElEQVRJT05fRkVBVFVSRSwgZmFsc2UpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzSWdub3JlQ2FzZSAoQ29uc3RhbnRzLkRPTV9FTEVNRU5UX0NPTlRFTlRfV0hJVEVTUEFDRSkpIHsKLSAgICAgICAgICAgICAgICAgICAgZkNvbmZpZ3VyYXRpb24uc2V0RmVhdHVyZSAoSU5DTFVERV9JR05PUkFCTEVfV0hJVEVTUEFDRSwgc3RhdGUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFsc0lnbm9yZUNhc2UgKENvbnN0YW50cy5ET01fUFNWSSkpewotICAgICAgICAgICAgICAgICAgICAvL1hTTW9kZWwgLSB0dXJuIG9uIFBTVkkgYXVnbWVudGF0aW9uCi0gICAgICAgICAgICAgICAgICAgIGZDb25maWd1cmF0aW9uLnNldEZlYXR1cmUgKFBTVklfQVVHTUVOVCwgdHJ1ZSk7Ci0gICAgICAgICAgICAgICAgICAgIGZDb25maWd1cmF0aW9uLnNldFByb3BlcnR5IChET0NVTUVOVF9DTEFTU19OQU1FLAotICAgICAgICAgICAgICAgICAgICAiY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5kb20uUFNWSURvY3VtZW50SW1wbCIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gQ29uc3RhbnRzLkRPTV9DSEFSU0VUX09WRVJSSURFU19YTUxfRU5DT0RJTkcgZmVhdHVyZSwKLSAgICAgICAgICAgICAgICAgICAgLy8gQ29uc3RhbnRzLkRPTV9TUExJVF9DREFUQSBmZWF0dXJlLAotICAgICAgICAgICAgICAgICAgICAvLyBvciBhbnkgWGVyY2VzIGZlYXR1cmUKLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG5vcm1hbGl6ZWROYW1lOwotICAgICAgICAgICAgICAgICAgICBpZiAobmFtZS5lcXVhbHMoTkFNRVNQQUNFX0dST1dUSCkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIG5vcm1hbGl6ZWROYW1lID0gTkFNRVNQQUNFX0dST1dUSDsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFscyhUT0xFUkFURV9EVVBMSUNBVEVTKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgbm9ybWFsaXplZE5hbWUgPSBUT0xFUkFURV9EVVBMSUNBVEVTOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgbm9ybWFsaXplZE5hbWUgPSBuYW1lLnRvTG93ZXJDYXNlKExvY2FsZS5FTkdMSVNIKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBmQ29uZmlndXJhdGlvbi5zZXRGZWF0dXJlIChub3JtYWxpemVkTmFtZSwgc3RhdGUpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2F0Y2ggKFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgIFN0cmluZyBtc2cgPQotICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZSAoCi0gICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLAotICAgICAgICAgICAgICAgICJGRUFUVVJFX05PVF9GT1VORCIsCi0gICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgbmFtZSB9KTsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uIChET01FeGNlcHRpb24uTk9UX0ZPVU5EX0VSUiwgbXNnKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIHsgLy8gc2V0IHByb3BlcnRpZXMKLSAgICAgICAgICAgIGlmIChuYW1lLmVxdWFsc0lnbm9yZUNhc2UgKENvbnN0YW50cy5ET01fRVJST1JfSEFORExFUikpIHsKLSAgICAgICAgICAgICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBET01FcnJvckhhbmRsZXIgfHwgdmFsdWUgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICAgICAgZkVycm9ySGFuZGxlciA9IG5ldyBET01FcnJvckhhbmRsZXJXcmFwcGVyICgoRE9NRXJyb3JIYW5kbGVyKSB2YWx1ZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmQ29uZmlndXJhdGlvbi5zZXRQcm9wZXJ0eSAoRVJST1JfSEFORExFUiwgZkVycm9ySGFuZGxlcik7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgY2F0Y2ggKFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gZSkge30KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIFJFVklTSVQ6IHR5cGUgbWlzbWF0Y2gKLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG1zZyA9Ci0gICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZSAoCi0gICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgIlRZUEVfTUlTTUFUQ0hfRVJSIiwKLSAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgbmFtZSB9KTsKLSAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbiAoRE9NRXhjZXB0aW9uLlRZUEVfTUlTTUFUQ0hfRVJSLCBtc2cpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAobmFtZS5lcXVhbHNJZ25vcmVDYXNlIChDb25zdGFudHMuRE9NX1JFU09VUkNFX1JFU09MVkVSKSkgewotICAgICAgICAgICAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIExTUmVzb3VyY2VSZXNvbHZlciB8fCB2YWx1ZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmQ29uZmlndXJhdGlvbi5zZXRQcm9wZXJ0eSAoRU5USVRZX1JFU09MVkVSLCBuZXcgRE9NRW50aXR5UmVzb2x2ZXJXcmFwcGVyICgoTFNSZXNvdXJjZVJlc29sdmVyKSB2YWx1ZSkpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGNhdGNoIChYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIGUpIHt9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAvLyBSRVZJU0lUOiB0eXBlIG1pc21hdGNoCi0gICAgICAgICAgICAgICAgICAgIFN0cmluZyBtc2cgPQotICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UgKAotICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICJUWVBFX01JU01BVENIX0VSUiIsCi0gICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7IG5hbWUgfSk7Ci0gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24gKERPTUV4Y2VwdGlvbi5UWVBFX01JU01BVENIX0VSUiwgbXNnKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzSWdub3JlQ2FzZSAoQ29uc3RhbnRzLkRPTV9TQ0hFTUFfTE9DQVRJT04pKSB7Ci0gICAgICAgICAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgU3RyaW5nIHx8IHZhbHVlID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZlNjaGVtYUxvY2F0aW9uID0gbnVsbDsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmQ29uZmlndXJhdGlvbi5zZXRQcm9wZXJ0eSAoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbnN0YW50cy5KQVhQX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5TQ0hFTUFfU09VUkNFLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZTY2hlbWFMb2NhdGlvbiA9IChTdHJpbmcpdmFsdWU7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbWFwIERPTSBzY2hlbWEtbG9jYXRpb24gdG8gSkFYUCBzY2hlbWFTb3VyY2UgcHJvcGVydHkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0b2tlbml6ZSBsb2NhdGlvbiBzdHJpbmcKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmdUb2tlbml6ZXIgdCA9IG5ldyBTdHJpbmdUb2tlbml6ZXIgKGZTY2hlbWFMb2NhdGlvbiwgIiBcblx0XHIiKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodC5oYXNNb3JlVG9rZW5zICgpKXsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZlNjaGVtYUxvY2F0aW9ucy5jbGVhciAoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZlNjaGVtYUxvY2F0aW9ucy5hZGQgKHQubmV4dFRva2VuICgpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHQuaGFzTW9yZVRva2VucyAoKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZlNjaGVtYUxvY2F0aW9ucy5hZGQgKHQubmV4dFRva2VuICgpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmQ29uZmlndXJhdGlvbi5zZXRQcm9wZXJ0eSAoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbnN0YW50cy5KQVhQX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5TQ0hFTUFfU09VUkNFLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmU2NoZW1hTG9jYXRpb25zLnRvQXJyYXkgKCkpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkNvbmZpZ3VyYXRpb24uc2V0UHJvcGVydHkgKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb25zdGFudHMuSkFYUF9QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuU0NIRU1BX1NPVVJDRSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBjYXRjaCAoWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBlKSB7fQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gUkVWSVNJVDogdHlwZSBtaXNtYXRjaAotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbXNnID0KLSAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlICgKLSAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAiVFlQRV9NSVNNQVRDSF9FUlIiLAotICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBuYW1lIH0pOwotICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uIChET01FeGNlcHRpb24uVFlQRV9NSVNNQVRDSF9FUlIsIG1zZyk7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFsc0lnbm9yZUNhc2UgKENvbnN0YW50cy5ET01fU0NIRU1BX1RZUEUpKSB7Ci0gICAgICAgICAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgU3RyaW5nIHx8IHZhbHVlID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHVybiBvZmYgc2NoZW1hIGZlYXR1cmVzCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZkNvbmZpZ3VyYXRpb24uc2V0RmVhdHVyZSAoWE1MU0NIRU1BLCBmYWxzZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZkNvbmZpZ3VyYXRpb24uc2V0RmVhdHVyZSAoWE1MU0NIRU1BX0ZVTExfQ0hFQ0tJTkcsIGZhbHNlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBtYXAgdG8gSkFYUCBzY2hlbWFMYW5ndWFnZQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZDb25maWd1cmF0aW9uLnNldFByb3BlcnR5ICggQ29uc3RhbnRzLkpBWFBfUFJPUEVSVFlfUFJFRklYCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBDb25zdGFudHMuU0NIRU1BX0xBTkdVQUdFLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZTY2hlbWFUeXBlID0gbnVsbDsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHZhbHVlLmVxdWFscyAoQ29uc3RhbnRzLk5TX1hNTFNDSEVNQSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0dXJuIG9uIHNjaGVtYSBmZWF0dXJlcwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZDb25maWd1cmF0aW9uLnNldEZlYXR1cmUgKFhNTFNDSEVNQSwgdHJ1ZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZkNvbmZpZ3VyYXRpb24uc2V0RmVhdHVyZSAoWE1MU0NIRU1BX0ZVTExfQ0hFQ0tJTkcsIHRydWUpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG1hcCB0byBKQVhQIHNjaGVtYUxhbmd1YWdlCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZkNvbmZpZ3VyYXRpb24uc2V0UHJvcGVydHkgKCBDb25zdGFudHMuSkFYUF9QUk9QRVJUWV9QUkVGSVgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICArIENvbnN0YW50cy5TQ0hFTUFfTEFOR1VBR0UsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29uc3RhbnRzLk5TX1hNTFNDSEVNQSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZlNjaGVtYVR5cGUgPSBDb25zdGFudHMuTlNfWE1MU0NIRU1BOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAodmFsdWUuZXF1YWxzIChDb25zdGFudHMuTlNfRFREKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHR1cm4gb2ZmIHNjaGVtYSBmZWF0dXJlcwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZDb25maWd1cmF0aW9uLnNldEZlYXR1cmUgKFhNTFNDSEVNQSwgZmFsc2UpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZDb25maWd1cmF0aW9uLnNldEZlYXR1cmUgKFhNTFNDSEVNQV9GVUxMX0NIRUNLSU5HLCBmYWxzZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbWFwIHRvIEpBWFAgc2NoZW1hTGFuZ3VhZ2UKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmQ29uZmlndXJhdGlvbi5zZXRQcm9wZXJ0eSAoIENvbnN0YW50cy5KQVhQX1BST1BFUlRZX1BSRUZJWAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgQ29uc3RhbnRzLlNDSEVNQV9MQU5HVUFHRSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb25zdGFudHMuTlNfRFREKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmU2NoZW1hVHlwZSA9IENvbnN0YW50cy5OU19EVEQ7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgY2F0Y2ggKFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gZSkge30KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIFN0cmluZyBtc2cgPQotICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UgKAotICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICJUWVBFX01JU01BVENIX0VSUiIsCi0gICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7IG5hbWUgfSk7Ci0gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24gKERPTUV4Y2VwdGlvbi5UWVBFX01JU01BVENIX0VSUiwgbXNnKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzSWdub3JlQ2FzZSAoRE9DVU1FTlRfQ0xBU1NfTkFNRSkpIHsKLSAgICAgICAgICAgICAgICBmQ29uZmlndXJhdGlvbi5zZXRQcm9wZXJ0eSAoRE9DVU1FTlRfQ0xBU1NfTkFNRSwgdmFsdWUpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgLy8gVHJ5IHRvIHNldCB0aGUgcHJvcGVydHkuCi0gICAgICAgICAgICAgICAgU3RyaW5nIG5vcm1hbGl6ZWROYW1lID0gbmFtZS50b0xvd2VyQ2FzZShMb2NhbGUuRU5HTElTSCk7Ci0gICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgZkNvbmZpZ3VyYXRpb24uc2V0UHJvcGVydHkobm9ybWFsaXplZE5hbWUsIHZhbHVlKTsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBjYXRjaCAoWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBlKSB7fQotCi0gICAgICAgICAgICAgICAgLy8gSWYgdGhpcyBpcyBhIGJvb2xlYW4gcGFyYW1ldGVyIGEgdHlwZSBtaXNtYXRjaCBzaG91bGQgYmUgdGhyb3duLgotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChuYW1lLmVxdWFscyhOQU1FU1BBQ0VfR1JPV1RIKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgbm9ybWFsaXplZE5hbWUgPSBOQU1FU1BBQ0VfR1JPV1RIOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzKFRPTEVSQVRFX0RVUExJQ0FURVMpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBub3JtYWxpemVkTmFtZSA9IFRPTEVSQVRFX0RVUExJQ0FURVM7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZkNvbmZpZ3VyYXRpb24uZ2V0RmVhdHVyZShub3JtYWxpemVkTmFtZSk7Ci0gICAgICAgICAgICAgICAgICAgIHRocm93IG5ld1R5cGVNaXNtYXRjaEVycm9yKG5hbWUpOwotCi0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGNhdGNoIChYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIGUpIHt9Ci0KLSAgICAgICAgICAgICAgICAvLyBQYXJhbWV0ZXIgaXMgbm90IHJlY29nbml6ZWQKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXdGZWF0dXJlTm90Rm91bmRFcnJvcihuYW1lKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIExvb2sgdXAgdGhlIHZhbHVlIG9mIGEgZmVhdHVyZSBvciBhIHByb3BlcnR5LgotICAgICAqLwotICAgIHB1YmxpYyBPYmplY3QgZ2V0UGFyYW1ldGVyIChTdHJpbmcgbmFtZSkgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChuYW1lLmVxdWFsc0lnbm9yZUNhc2UgKENvbnN0YW50cy5ET01fQ09NTUVOVFMpKSB7Ci0gICAgICAgICAgICByZXR1cm4gKGZDb25maWd1cmF0aW9uLmdldEZlYXR1cmUgKElOQ0xVREVfQ09NTUVOVFNfRkVBVFVSRSkpCi0gICAgICAgICAgICA/IEJvb2xlYW4uVFJVRQotICAgICAgICAgICAgOiBCb29sZWFuLkZBTFNFOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzSWdub3JlQ2FzZSAoQ29uc3RhbnRzLkRPTV9EQVRBVFlQRV9OT1JNQUxJWkFUSU9OKSkgewotICAgICAgICAgICAgcmV0dXJuIChmQ29uZmlndXJhdGlvbi5nZXRGZWF0dXJlIChOT1JNQUxJWkVfREFUQSkpCi0gICAgICAgICAgICA/IEJvb2xlYW4uVFJVRQotICAgICAgICAgICAgOiBCb29sZWFuLkZBTFNFOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzSWdub3JlQ2FzZSAoQ29uc3RhbnRzLkRPTV9FTlRJVElFUykpIHsKLSAgICAgICAgICAgIHJldHVybiAoZkNvbmZpZ3VyYXRpb24uZ2V0RmVhdHVyZSAoQ1JFQVRFX0VOVElUWV9SRUZfTk9ERVMpKQotICAgICAgICAgICAgPyBCb29sZWFuLlRSVUUKLSAgICAgICAgICAgIDogQm9vbGVhbi5GQUxTRTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFsc0lnbm9yZUNhc2UgKENvbnN0YW50cy5ET01fTkFNRVNQQUNFUykpIHsKLSAgICAgICAgICAgIHJldHVybiAoZkNvbmZpZ3VyYXRpb24uZ2V0RmVhdHVyZSAoTkFNRVNQQUNFUykpCi0gICAgICAgICAgICA/IEJvb2xlYW4uVFJVRQotICAgICAgICAgICAgOiBCb29sZWFuLkZBTFNFOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzSWdub3JlQ2FzZSAoQ29uc3RhbnRzLkRPTV9WQUxJREFURSkpIHsKLSAgICAgICAgICAgIHJldHVybiAoZkNvbmZpZ3VyYXRpb24uZ2V0RmVhdHVyZSAoVkFMSURBVElPTl9GRUFUVVJFKSkKLSAgICAgICAgICAgID8gQm9vbGVhbi5UUlVFCi0gICAgICAgICAgICA6IEJvb2xlYW4uRkFMU0U7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAobmFtZS5lcXVhbHNJZ25vcmVDYXNlIChDb25zdGFudHMuRE9NX1ZBTElEQVRFX0lGX1NDSEVNQSkpIHsKLSAgICAgICAgICAgIHJldHVybiAoZkNvbmZpZ3VyYXRpb24uZ2V0RmVhdHVyZSAoRFlOQU1JQ19WQUxJREFUSU9OKSkKLSAgICAgICAgICAgID8gQm9vbGVhbi5UUlVFCi0gICAgICAgICAgICA6IEJvb2xlYW4uRkFMU0U7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAobmFtZS5lcXVhbHNJZ25vcmVDYXNlIChDb25zdGFudHMuRE9NX0VMRU1FTlRfQ09OVEVOVF9XSElURVNQQUNFKSkgewotICAgICAgICAgICAgcmV0dXJuIChmQ29uZmlndXJhdGlvbi5nZXRGZWF0dXJlIChJTkNMVURFX0lHTk9SQUJMRV9XSElURVNQQUNFKSkKLSAgICAgICAgICAgID8gQm9vbGVhbi5UUlVFCi0gICAgICAgICAgICA6IEJvb2xlYW4uRkFMU0U7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAobmFtZS5lcXVhbHNJZ25vcmVDYXNlIChDb25zdGFudHMuRE9NX0RJU0FMTE9XX0RPQ1RZUEUpKSB7Ci0gICAgICAgICAgICByZXR1cm4gKGZDb25maWd1cmF0aW9uLmdldEZlYXR1cmUgKERJU0FMTE9XX0RPQ1RZUEVfREVDTF9GRUFUVVJFKSkKLSAgICAgICAgICAgID8gQm9vbGVhbi5UUlVFCi0gICAgICAgICAgICA6IEJvb2xlYW4uRkFMU0U7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAobmFtZS5lcXVhbHNJZ25vcmVDYXNlIChDb25zdGFudHMuRE9NX0lORk9TRVQpKSB7Ci0gICAgICAgICAgICAvLyBSRVZJU0lUOiBUaGlzIGlzIHNvbWV3aGF0IGV4cGVuc2l2ZSB0byBjb21wdXRlCi0gICAgICAgICAgICAvLyBidXQgaXQncyBwb3NzaWJsZSB0aGF0IHRoZSB1c2VyIGhhcyBhIHJlZmVyZW5jZQotICAgICAgICAgICAgLy8gdG8gdGhlIGNvbmZpZ3VyYXRpb24gYW5kIGlzIGNoYW5naW5nIHRoZSB2YWx1ZXMKLSAgICAgICAgICAgIC8vIG9mIHRoZXNlIGZlYXR1cmVzIGRpcmVjdGx5IG9uIGl0LgotICAgICAgICAgICAgYm9vbGVhbiBpbmZvc2V0ID0gZkNvbmZpZ3VyYXRpb24uZ2V0RmVhdHVyZShOQU1FU1BBQ0VTKSAmJgotICAgICAgICAgICAgICAgIGZDb25maWd1cmF0aW9uLmdldEZlYXR1cmUoQ29uc3RhbnRzLkRPTV9OQU1FU1BBQ0VfREVDTEFSQVRJT05TKSAmJgotICAgICAgICAgICAgICAgIGZDb25maWd1cmF0aW9uLmdldEZlYXR1cmUoSU5DTFVERV9DT01NRU5UU19GRUFUVVJFKSAmJgotICAgICAgICAgICAgICAgIGZDb25maWd1cmF0aW9uLmdldEZlYXR1cmUoSU5DTFVERV9JR05PUkFCTEVfV0hJVEVTUEFDRSkgJiYKLSAgICAgICAgICAgICAgICAhZkNvbmZpZ3VyYXRpb24uZ2V0RmVhdHVyZShEWU5BTUlDX1ZBTElEQVRJT04pICYmCi0gICAgICAgICAgICAgICAgIWZDb25maWd1cmF0aW9uLmdldEZlYXR1cmUoQ1JFQVRFX0VOVElUWV9SRUZfTk9ERVMpICYmCi0gICAgICAgICAgICAgICAgIWZDb25maWd1cmF0aW9uLmdldEZlYXR1cmUoTk9STUFMSVpFX0RBVEEpICYmCi0gICAgICAgICAgICAgICAgIWZDb25maWd1cmF0aW9uLmdldEZlYXR1cmUoQ1JFQVRFX0NEQVRBX05PREVTX0ZFQVRVUkUpOwotICAgICAgICAgICAgcmV0dXJuIChpbmZvc2V0KSA/IEJvb2xlYW4uVFJVRSA6IEJvb2xlYW4uRkFMU0U7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAobmFtZS5lcXVhbHNJZ25vcmVDYXNlKENvbnN0YW50cy5ET01fQ0RBVEFfU0VDVElPTlMpKSB7Ci0gICAgICAgICAgICByZXR1cm4gKGZDb25maWd1cmF0aW9uLmdldEZlYXR1cmUoQ1JFQVRFX0NEQVRBX05PREVTX0ZFQVRVUkUpKQotICAgICAgICAgICAgICAgID8gQm9vbGVhbi5UUlVFIDogQm9vbGVhbi5GQUxTRTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFsc0lnbm9yZUNhc2UoQ29uc3RhbnRzLkRPTV9DSEVDS19DSEFSX05PUk1BTElaQVRJT04gKSB8fAotICAgICAgICAgICAgICAgICBuYW1lLmVxdWFsc0lnbm9yZUNhc2UoQ29uc3RhbnRzLkRPTV9OT1JNQUxJWkVfQ0hBUkFDVEVSUykpewotICAgICAgICAgICAgcmV0dXJuIEJvb2xlYW4uRkFMU0U7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAobmFtZS5lcXVhbHNJZ25vcmVDYXNlKENvbnN0YW50cy5ET01fTkFNRVNQQUNFX0RFQ0xBUkFUSU9OUykKLSAgICAgICAgfHwgbmFtZS5lcXVhbHNJZ25vcmVDYXNlIChDb25zdGFudHMuRE9NX1dFTExGT1JNRUQpCi0gICAgICAgIHx8IG5hbWUuZXF1YWxzSWdub3JlQ2FzZSAoQ29uc3RhbnRzLkRPTV9JR05PUkVfVU5LTk9XTl9DSEFSQUNURVJfREVOT1JNQUxJWkFUSU9OUykKLSAgICAgICAgfHwgbmFtZS5lcXVhbHNJZ25vcmVDYXNlIChDb25zdGFudHMuRE9NX0NBTk9OSUNBTF9GT1JNKQotICAgICAgICB8fCBuYW1lLmVxdWFsc0lnbm9yZUNhc2UgKENvbnN0YW50cy5ET01fU1VQUE9SVEVEX01FRElBVFlQRVNfT05MWSkKLSAgICAgICAgfHwgbmFtZS5lcXVhbHNJZ25vcmVDYXNlIChDb25zdGFudHMuRE9NX1NQTElUX0NEQVRBKQotICAgICAgICB8fCBuYW1lLmVxdWFsc0lnbm9yZUNhc2UgKENvbnN0YW50cy5ET01fQ0hBUlNFVF9PVkVSUklERVNfWE1MX0VOQ09ESU5HKSkgewotICAgICAgICAgICAgcmV0dXJuIChmQ29uZmlndXJhdGlvbi5nZXRGZWF0dXJlIChuYW1lLnRvTG93ZXJDYXNlKExvY2FsZS5FTkdMSVNIKSkpCi0gICAgICAgICAgICA/IEJvb2xlYW4uVFJVRQotICAgICAgICAgICAgOiBCb29sZWFuLkZBTFNFOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzSWdub3JlQ2FzZSAoQ29uc3RhbnRzLkRPTV9FUlJPUl9IQU5ETEVSKSkgewotICAgICAgICAgICAgaWYgKGZFcnJvckhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJldHVybiBmRXJyb3JIYW5kbGVyLmdldEVycm9ySGFuZGxlciAoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzSWdub3JlQ2FzZSAoQ29uc3RhbnRzLkRPTV9SRVNPVVJDRV9SRVNPTFZFUikpIHsKLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgWE1MRW50aXR5UmVzb2x2ZXIgZW50aXR5UmVzb2x2ZXIgPQotICAgICAgICAgICAgICAgIChYTUxFbnRpdHlSZXNvbHZlcikgZkNvbmZpZ3VyYXRpb24uZ2V0UHJvcGVydHkgKEVOVElUWV9SRVNPTFZFUik7Ci0gICAgICAgICAgICAgICAgaWYgKGVudGl0eVJlc29sdmVyICE9IG51bGwKLSAgICAgICAgICAgICAgICAmJiBlbnRpdHlSZXNvbHZlciBpbnN0YW5jZW9mIERPTUVudGl0eVJlc29sdmVyV3JhcHBlcikgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gKChET01FbnRpdHlSZXNvbHZlcldyYXBwZXIpIGVudGl0eVJlc29sdmVyKS5nZXRFbnRpdHlSZXNvbHZlciAoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXRjaCAoWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBlKSB7fQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzSWdub3JlQ2FzZSAoQ29uc3RhbnRzLkRPTV9TQ0hFTUFfVFlQRSkpIHsKLSAgICAgICAgICAgIHJldHVybiBmQ29uZmlndXJhdGlvbi5nZXRQcm9wZXJ0eSAoCi0gICAgICAgICAgICBDb25zdGFudHMuSkFYUF9QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuU0NIRU1BX0xBTkdVQUdFKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFsc0lnbm9yZUNhc2UgKENvbnN0YW50cy5ET01fU0NIRU1BX0xPQ0FUSU9OKSkgewotICAgICAgICAgICAgcmV0dXJuIGZTY2hlbWFMb2NhdGlvbjsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFsc0lnbm9yZUNhc2UgKFNZTUJPTF9UQUJMRSkpewotICAgICAgICAgICAgcmV0dXJuIGZDb25maWd1cmF0aW9uLmdldFByb3BlcnR5IChTWU1CT0xfVEFCTEUpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzSWdub3JlQ2FzZSAoRE9DVU1FTlRfQ0xBU1NfTkFNRSkpIHsKLSAgICAgICAgICAgIHJldHVybiBmQ29uZmlndXJhdGlvbi5nZXRQcm9wZXJ0eSAoRE9DVU1FTlRfQ0xBU1NfTkFNRSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAvLyBUaGlzIGNvdWxkIGJlIGEgcmVjb2duaXplZCBmZWF0dXJlIG9yIHByb3BlcnR5LgotICAgICAgICAgICAgU3RyaW5nIG5vcm1hbGl6ZWROYW1lOwotCi0gICAgICAgICAgICBpZiAobmFtZS5lcXVhbHMoTkFNRVNQQUNFX0dST1dUSCkpIHsKLSAgICAgICAgICAgICAgICBub3JtYWxpemVkTmFtZSA9IE5BTUVTUEFDRV9HUk9XVEg7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFscyhUT0xFUkFURV9EVVBMSUNBVEVTKSkgewotICAgICAgICAgICAgICAgIG5vcm1hbGl6ZWROYW1lID0gVE9MRVJBVEVfRFVQTElDQVRFUzsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIG5vcm1hbGl6ZWROYW1lID0gbmFtZS50b0xvd2VyQ2FzZShMb2NhbGUuRU5HTElTSCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIHJldHVybiBmQ29uZmlndXJhdGlvbi5nZXRGZWF0dXJlKG5vcm1hbGl6ZWROYW1lKQotICAgICAgICAgICAgICAgICAgICA/IEJvb2xlYW4uVFJVRSA6IEJvb2xlYW4uRkFMU0U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXRjaCAoWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBlKSB7fQotCi0gICAgICAgICAgICAvLyBUaGlzIGlzbid0IGEgZmVhdHVyZTsgcGVyaGFwcyBpdCdzIGEgcHJvcGVydHkKLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZDb25maWd1cmF0aW9uLmdldFByb3BlcnR5KG5vcm1hbGl6ZWROYW1lKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhdGNoIChYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIGUpIHt9Ci0KLSAgICAgICAgICAgIHRocm93IG5ld0ZlYXR1cmVOb3RGb3VuZEVycm9yKG5hbWUpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGNhblNldFBhcmFtZXRlciAoU3RyaW5nIG5hbWUsIE9iamVjdCB2YWx1ZSkgewotICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCl7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgIH0KLQotICAgICAgICBpZih2YWx1ZSBpbnN0YW5jZW9mIEJvb2xlYW4pewotICAgICAgICAgICAgYm9vbGVhbiBzdGF0ZSA9ICgoQm9vbGVhbil2YWx1ZSkuYm9vbGVhblZhbHVlICgpOwotICAgICAgICAgICAgaWYgKCBuYW1lLmVxdWFsc0lnbm9yZUNhc2UgKENvbnN0YW50cy5ET01fU1VQUE9SVEVEX01FRElBVFlQRVNfT05MWSkKLSAgICAgICAgICAgIHx8IG5hbWUuZXF1YWxzSWdub3JlQ2FzZShDb25zdGFudHMuRE9NX05PUk1BTElaRV9DSEFSQUNURVJTKQotICAgICAgICAgICAgfHwgbmFtZS5lcXVhbHNJZ25vcmVDYXNlKENvbnN0YW50cy5ET01fQ0hFQ0tfQ0hBUl9OT1JNQUxJWkFUSU9OICkKLSAgICAgICAgICAgIHx8IG5hbWUuZXF1YWxzSWdub3JlQ2FzZSAoQ29uc3RhbnRzLkRPTV9DQU5PTklDQUxfRk9STSkgKSB7Ci0gICAgICAgICAgICAgICAgLy8gdHJ1ZSBpcyBub3Qgc3VwcG9ydGVkCi0gICAgICAgICAgICAgICAgcmV0dXJuIChzdGF0ZSkgPyBmYWxzZSA6IHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFsc0lnbm9yZUNhc2UgKENvbnN0YW50cy5ET01fV0VMTEZPUk1FRCkKLSAgICAgICAgICAgIHx8IG5hbWUuZXF1YWxzSWdub3JlQ2FzZSAoQ29uc3RhbnRzLkRPTV9JR05PUkVfVU5LTk9XTl9DSEFSQUNURVJfREVOT1JNQUxJWkFUSU9OUykpIHsKLSAgICAgICAgICAgICAgICAvLyBmYWxzZSBpcyBub3Qgc3VwcG9ydGVkCi0gICAgICAgICAgICAgICAgcmV0dXJuIChzdGF0ZSkgPyB0cnVlIDogZmFsc2U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFsc0lnbm9yZUNhc2UgKENvbnN0YW50cy5ET01fQ0RBVEFfU0VDVElPTlMpCi0gICAgICAgICAgICB8fCBuYW1lLmVxdWFsc0lnbm9yZUNhc2UgKENvbnN0YW50cy5ET01fQ0hBUlNFVF9PVkVSUklERVNfWE1MX0VOQ09ESU5HKQotICAgICAgICAgICAgfHwgbmFtZS5lcXVhbHNJZ25vcmVDYXNlIChDb25zdGFudHMuRE9NX0NPTU1FTlRTKQotICAgICAgICAgICAgfHwgbmFtZS5lcXVhbHNJZ25vcmVDYXNlIChDb25zdGFudHMuRE9NX0RBVEFUWVBFX05PUk1BTElaQVRJT04pCi0gICAgICAgICAgICB8fCBuYW1lLmVxdWFsc0lnbm9yZUNhc2UgKENvbnN0YW50cy5ET01fRElTQUxMT1dfRE9DVFlQRSkKLSAgICAgICAgICAgIHx8IG5hbWUuZXF1YWxzSWdub3JlQ2FzZSAoQ29uc3RhbnRzLkRPTV9FTlRJVElFUykKLSAgICAgICAgICAgIHx8IG5hbWUuZXF1YWxzSWdub3JlQ2FzZSAoQ29uc3RhbnRzLkRPTV9JTkZPU0VUKQotICAgICAgICAgICAgfHwgbmFtZS5lcXVhbHNJZ25vcmVDYXNlIChDb25zdGFudHMuRE9NX05BTUVTUEFDRVMpCi0gICAgICAgICAgICB8fCBuYW1lLmVxdWFsc0lnbm9yZUNhc2UgKENvbnN0YW50cy5ET01fTkFNRVNQQUNFX0RFQ0xBUkFUSU9OUykKLSAgICAgICAgICAgIHx8IG5hbWUuZXF1YWxzSWdub3JlQ2FzZSAoQ29uc3RhbnRzLkRPTV9WQUxJREFURSkKLSAgICAgICAgICAgIHx8IG5hbWUuZXF1YWxzSWdub3JlQ2FzZSAoQ29uc3RhbnRzLkRPTV9WQUxJREFURV9JRl9TQ0hFTUEpCi0gICAgICAgICAgICB8fCBuYW1lLmVxdWFsc0lnbm9yZUNhc2UgKENvbnN0YW50cy5ET01fRUxFTUVOVF9DT05URU5UX1dISVRFU1BBQ0UpCi0gICAgICAgICAgICB8fCBuYW1lLmVxdWFsc0lnbm9yZUNhc2UgKENvbnN0YW50cy5ET01fWE1MREVDTCkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gUmVjb2duaXplIFhlcmNlcyBmZWF0dXJlcy4KLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIG5vcm1hbGl6ZWROYW1lOwotICAgICAgICAgICAgICAgIGlmIChuYW1lLmVxdWFsc0lnbm9yZUNhc2UoTkFNRVNQQUNFX0dST1dUSCkpIHsKLSAgICAgICAgICAgICAgICAgICAgbm9ybWFsaXplZE5hbWUgPSBOQU1FU1BBQ0VfR1JPV1RIOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFsc0lnbm9yZUNhc2UoVE9MRVJBVEVfRFVQTElDQVRFUykpIHsKLSAgICAgICAgICAgICAgICAgICAgbm9ybWFsaXplZE5hbWUgPSBUT0xFUkFURV9EVVBMSUNBVEVTOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgbm9ybWFsaXplZE5hbWUgPSBuYW1lLnRvTG93ZXJDYXNlKExvY2FsZS5FTkdMSVNIKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZkNvbmZpZ3VyYXRpb24uZ2V0RmVhdHVyZShub3JtYWxpemVkTmFtZSk7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXRjaCAoWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgeyAvLyBjaGVjayBwcm9wZXJ0aWVzCi0gICAgICAgICAgICBpZiAobmFtZS5lcXVhbHNJZ25vcmVDYXNlIChDb25zdGFudHMuRE9NX0VSUk9SX0hBTkRMRVIpKSB7Ci0gICAgICAgICAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgRE9NRXJyb3JIYW5kbGVyIHx8IHZhbHVlID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzSWdub3JlQ2FzZSAoQ29uc3RhbnRzLkRPTV9SRVNPVVJDRV9SRVNPTFZFUikpIHsKLSAgICAgICAgICAgICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBMU1Jlc291cmNlUmVzb2x2ZXIgfHwgdmFsdWUgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAobmFtZS5lcXVhbHNJZ25vcmVDYXNlIChDb25zdGFudHMuRE9NX1NDSEVNQV9UWVBFKSkgewotICAgICAgICAgICAgICAgIGlmICgodmFsdWUgaW5zdGFuY2VvZiBTdHJpbmcKLSAgICAgICAgICAgICAgICAmJiAodmFsdWUuZXF1YWxzIChDb25zdGFudHMuTlNfWE1MU0NIRU1BKQotICAgICAgICAgICAgICAgIHx8IHZhbHVlLmVxdWFscyAoQ29uc3RhbnRzLk5TX0RURCkpKSB8fCB2YWx1ZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFsc0lnbm9yZUNhc2UgKENvbnN0YW50cy5ET01fU0NIRU1BX0xPQ0FUSU9OKSkgewotICAgICAgICAgICAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIFN0cmluZyB8fCB2YWx1ZSA9PSBudWxsKQotICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFsc0lnbm9yZUNhc2UgKERPQ1VNRU5UX0NMQVNTX05BTUUpKXsKLSAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqICBET00gTGV2ZWwgMyBDUiAtIEV4cGVyaW1lbnRhbC4KLSAgICAgKgotICAgICAqICBUaGUgbGlzdCBvZiB0aGUgcGFyYW1ldGVycyBzdXBwb3J0ZWQgYnkgdGhpcwotICAgICAqIDxjb2RlPkRPTUNvbmZpZ3VyYXRpb248L2NvZGU+IG9iamVjdCBhbmQgZm9yIHdoaWNoIGF0IGxlYXN0IG9uZSB2YWx1ZQotICAgICAqIGNhbiBiZSBzZXQgYnkgdGhlIGFwcGxpY2F0aW9uLiBOb3RlIHRoYXQgdGhpcyBsaXN0IGNhbiBhbHNvIGNvbnRhaW4KLSAgICAgKiBwYXJhbWV0ZXIgbmFtZXMgZGVmaW5lZCBvdXRzaWRlIHRoaXMgc3BlY2lmaWNhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgRE9NU3RyaW5nTGlzdCBnZXRQYXJhbWV0ZXJOYW1lcyAoKSB7Ci0gICAgICAgIGlmIChmUmVjb2duaXplZFBhcmFtZXRlcnMgPT0gbnVsbCl7Ci0gICAgICAgICAgICBWZWN0b3IgcGFyYW1ldGVycyA9IG5ldyBWZWN0b3IoKTsKLQotICAgICAgICAgICAgLy8gUkVWSVNJVDogYWRkIFhlcmNlcyByZWNvZ25pemVkIHByb3BlcnRpZXMvZmVhdHVyZXMKLSAgICAgICAgICAgIHBhcmFtZXRlcnMuYWRkKENvbnN0YW50cy5ET01fTkFNRVNQQUNFUyk7Ci0gICAgICAgICAgICBwYXJhbWV0ZXJzLmFkZChDb25zdGFudHMuRE9NX0NEQVRBX1NFQ1RJT05TKTsKLSAgICAgICAgICAgIHBhcmFtZXRlcnMuYWRkKENvbnN0YW50cy5ET01fQ0FOT05JQ0FMX0ZPUk0pOwotICAgICAgICAgICAgcGFyYW1ldGVycy5hZGQoQ29uc3RhbnRzLkRPTV9OQU1FU1BBQ0VfREVDTEFSQVRJT05TKTsKLSAgICAgICAgICAgIHBhcmFtZXRlcnMuYWRkKENvbnN0YW50cy5ET01fU1BMSVRfQ0RBVEEpOwotCi0gICAgICAgICAgICBwYXJhbWV0ZXJzLmFkZChDb25zdGFudHMuRE9NX0VOVElUSUVTKTsKLSAgICAgICAgICAgIHBhcmFtZXRlcnMuYWRkKENvbnN0YW50cy5ET01fVkFMSURBVEVfSUZfU0NIRU1BKTsKLSAgICAgICAgICAgIHBhcmFtZXRlcnMuYWRkKENvbnN0YW50cy5ET01fVkFMSURBVEUpOwotICAgICAgICAgICAgcGFyYW1ldGVycy5hZGQoQ29uc3RhbnRzLkRPTV9EQVRBVFlQRV9OT1JNQUxJWkFUSU9OKTsKLQotICAgICAgICAgICAgcGFyYW1ldGVycy5hZGQoQ29uc3RhbnRzLkRPTV9DSEFSU0VUX09WRVJSSURFU19YTUxfRU5DT0RJTkcpOwotICAgICAgICAgICAgcGFyYW1ldGVycy5hZGQoQ29uc3RhbnRzLkRPTV9DSEVDS19DSEFSX05PUk1BTElaQVRJT04pOwotICAgICAgICAgICAgcGFyYW1ldGVycy5hZGQoQ29uc3RhbnRzLkRPTV9TVVBQT1JURURfTUVESUFUWVBFU19PTkxZKTsKLSAgICAgICAgICAgIHBhcmFtZXRlcnMuYWRkKENvbnN0YW50cy5ET01fSUdOT1JFX1VOS05PV05fQ0hBUkFDVEVSX0RFTk9STUFMSVpBVElPTlMpOwotCi0gICAgICAgICAgICBwYXJhbWV0ZXJzLmFkZChDb25zdGFudHMuRE9NX05PUk1BTElaRV9DSEFSQUNURVJTKTsKLSAgICAgICAgICAgIHBhcmFtZXRlcnMuYWRkKENvbnN0YW50cy5ET01fV0VMTEZPUk1FRCk7Ci0gICAgICAgICAgICBwYXJhbWV0ZXJzLmFkZChDb25zdGFudHMuRE9NX0lORk9TRVQpOwotICAgICAgICAgICAgcGFyYW1ldGVycy5hZGQoQ29uc3RhbnRzLkRPTV9ESVNBTExPV19ET0NUWVBFKTsKLSAgICAgICAgICAgIHBhcmFtZXRlcnMuYWRkKENvbnN0YW50cy5ET01fRUxFTUVOVF9DT05URU5UX1dISVRFU1BBQ0UpOwotICAgICAgICAgICAgcGFyYW1ldGVycy5hZGQoQ29uc3RhbnRzLkRPTV9DT01NRU5UUyk7Ci0KLSAgICAgICAgICAgIHBhcmFtZXRlcnMuYWRkKENvbnN0YW50cy5ET01fRVJST1JfSEFORExFUik7Ci0gICAgICAgICAgICBwYXJhbWV0ZXJzLmFkZChDb25zdGFudHMuRE9NX1JFU09VUkNFX1JFU09MVkVSKTsKLSAgICAgICAgICAgIHBhcmFtZXRlcnMuYWRkKENvbnN0YW50cy5ET01fU0NIRU1BX0xPQ0FUSU9OKTsKLSAgICAgICAgICAgIHBhcmFtZXRlcnMuYWRkKENvbnN0YW50cy5ET01fU0NIRU1BX1RZUEUpOwotCi0gICAgICAgICAgICBmUmVjb2duaXplZFBhcmFtZXRlcnMgPSBuZXcgRE9NU3RyaW5nTGlzdEltcGwocGFyYW1ldGVycyk7Ci0KLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBmUmVjb2duaXplZFBhcmFtZXRlcnM7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUGFyc2UgYW4gWE1MIGRvY3VtZW50IGZyb20gYSBsb2NhdGlvbiBpZGVudGlmaWVkIGJ5IGFuIFVSSSByZWZlcmVuY2UuCi0gICAgICogSWYgdGhlIFVSSSBjb250YWlucyBhIGZyYWdtZW50IGlkZW50aWZpZXIgKHNlZSBzZWN0aW9uIDQuMSBpbiApLCB0aGUKLSAgICAgKiBiZWhhdmlvciBpcyBub3QgZGVmaW5lZCBieSB0aGlzIHNwZWNpZmljYXRpb24uCi0gICAgICoKLSAgICAgKi8KLSAgICBwdWJsaWMgRG9jdW1lbnQgcGFyc2VVUkkgKFN0cmluZyB1cmkpIHRocm93cyBMU0V4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy9JZiBET01QYXJzZXIgaW5zc3RhbmNlIGlzIGFscmVhZHkgYnVzeSBwYXJzaW5nIGFub3RoZXIgZG9jdW1lbnQgd2hlbiB0aGlzCi0gICAgICAgIC8vIG1ldGhvZCBpcyBjYWxsZWQsIHRoZW4gcmFpc2UgSU5WQUxJRF9TVEFURV9FUlIgYWNjb3JkaW5nIHRvIERPTSBMMyBMUyBzcGVjCi0gICAgICAgIGlmICggZkJ1c3kgKSB7Ci0gICAgICAgICAgICBTdHJpbmcgbXNnID0gRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlICgKLSAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwKLSAgICAgICAgICAgICJJTlZBTElEX1NUQVRFX0VSUiIsbnVsbCk7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uICggRE9NRXhjZXB0aW9uLklOVkFMSURfU1RBVEVfRVJSLG1zZyk7Ci0gICAgICAgIH0KLQotICAgICAgICBYTUxJbnB1dFNvdXJjZSBzb3VyY2UgPSBuZXcgWE1MSW5wdXRTb3VyY2UgKG51bGwsIHVyaSwgbnVsbCk7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBjdXJyZW50VGhyZWFkID0gVGhyZWFkLmN1cnJlbnRUaHJlYWQoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZCdXN5ID0gdHJ1ZTsKLSAgICAgICAgICAgIHBhcnNlIChzb3VyY2UpOwotICAgICAgICAgICAgZkJ1c3kgPSBmYWxzZTsKLSAgICAgICAgICAgIGlmIChhYm9ydE5vdyAmJiBjdXJyZW50VGhyZWFkLmlzSW50ZXJydXB0ZWQoKSkgewotICAgICAgICAgICAgICAgIC8vcmVzZXQgaW50ZXJydXB0IHN0YXRlCi0gICAgICAgICAgICAgICAgYWJvcnROb3cgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICBUaHJlYWQuaW50ZXJydXB0ZWQoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpewotICAgICAgICAgICAgZkJ1c3kgPSBmYWxzZTsKLSAgICAgICAgICAgIGlmIChhYm9ydE5vdyAmJiBjdXJyZW50VGhyZWFkLmlzSW50ZXJydXB0ZWQoKSkgewotICAgICAgICAgICAgICAgIFRocmVhZC5pbnRlcnJ1cHRlZCgpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKGFib3J0Tm93KSB7Ci0gICAgICAgICAgICAgICAgYWJvcnROb3cgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICByZXN0b3JlSGFuZGxlcnMoKTsKLSAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIENvbnN1bWUgdGhpcyBleGNlcHRpb24gaWYgdGhlIHVzZXIKLSAgICAgICAgICAgIC8vIGlzc3VlZCBhbiBpbnRlcnJ1cHQgb3IgYW4gYWJvcnQuCi0gICAgICAgICAgICBpZiAoZSAhPSBBYm9ydC5JTlNUQU5DRSkgewotICAgICAgICAgICAgICAgIGlmICghKGUgaW5zdGFuY2VvZiBYTUxQYXJzZUV4Y2VwdGlvbikgJiYgZkVycm9ySGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIERPTUVycm9ySW1wbCBlcnJvciA9IG5ldyBET01FcnJvckltcGwgKCk7Ci0gICAgICAgICAgICAgICAgICAgIGVycm9yLmZFeGNlcHRpb24gPSBlOwotICAgICAgICAgICAgICAgICAgICBlcnJvci5mTWVzc2FnZSA9IGUuZ2V0TWVzc2FnZSAoKTsKLSAgICAgICAgICAgICAgICAgICAgZXJyb3IuZlNldmVyaXR5ID0gRE9NRXJyb3IuU0VWRVJJVFlfRkFUQUxfRVJST1I7Ci0gICAgICAgICAgICAgICAgICAgIGZFcnJvckhhbmRsZXIuZ2V0RXJyb3JIYW5kbGVyICgpLmhhbmRsZUVycm9yIChlcnJvcik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGlmIChERUJVRykgewotICAgICAgICAgICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSAoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgdGhyb3cgKExTRXhjZXB0aW9uKSBET01VdGlsLmNyZWF0ZUxTRXhjZXB0aW9uKExTRXhjZXB0aW9uLlBBUlNFX0VSUiwgZSkuZmlsbEluU3RhY2tUcmFjZSgpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIERvY3VtZW50IGRvYyA9IGdldERvY3VtZW50KCk7Ci0gICAgICAgIGRyb3BEb2N1bWVudFJlZmVyZW5jZXMoKTsKLSAgICAgICAgcmV0dXJuIGRvYzsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBQYXJzZSBhbiBYTUwgZG9jdW1lbnQgZnJvbSBhIHJlc291cmNlIGlkZW50aWZpZWQgYnkgYW4KLSAgICAgKiA8Y29kZT5MU0lucHV0PC9jb2RlPi4KLSAgICAgKgotICAgICAqLwotICAgIHB1YmxpYyBEb2N1bWVudCBwYXJzZSAoTFNJbnB1dCBpcykgdGhyb3dzIExTRXhjZXB0aW9uIHsKLQotICAgICAgICAvLyBuZWVkIHRvIHdyYXAgdGhlIExTSW5wdXQgd2l0aCBhbiBYTUxJbnB1dFNvdXJjZQotICAgICAgICBYTUxJbnB1dFNvdXJjZSB4bWxJbnB1dFNvdXJjZSA9IGRvbTJ4bWxJbnB1dFNvdXJjZSAoaXMpOwotICAgICAgICBpZiAoIGZCdXN5ICkgewotICAgICAgICAgICAgU3RyaW5nIG1zZyA9IERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZSAoCi0gICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sCi0gICAgICAgICAgICAiSU5WQUxJRF9TVEFURV9FUlIiLG51bGwpOwotICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbiAoIERPTUV4Y2VwdGlvbi5JTlZBTElEX1NUQVRFX0VSUixtc2cpOwotICAgICAgICB9Ci0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGN1cnJlbnRUaHJlYWQgPSBUaHJlYWQuY3VycmVudFRocmVhZCgpOwotICAgICAgICAgICAgICAgICAgICAgICAgZkJ1c3kgPSB0cnVlOwotICAgICAgICAgICAgcGFyc2UgKHhtbElucHV0U291cmNlKTsKLSAgICAgICAgICAgIGZCdXN5ID0gZmFsc2U7Ci0gICAgICAgICAgICBpZiAoYWJvcnROb3cgJiYgY3VycmVudFRocmVhZC5pc0ludGVycnVwdGVkKCkpIHsKLSAgICAgICAgICAgICAgICAvL3Jlc2V0IGludGVycnVwdCBzdGF0ZQotICAgICAgICAgICAgICAgIGFib3J0Tm93ID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgVGhyZWFkLmludGVycnVwdGVkKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICBmQnVzeSA9IGZhbHNlOwotICAgICAgICAgICAgaWYgKGFib3J0Tm93ICYmIGN1cnJlbnRUaHJlYWQuaXNJbnRlcnJ1cHRlZCgpKSB7Ci0gICAgICAgICAgICAgICAgVGhyZWFkLmludGVycnVwdGVkKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoYWJvcnROb3cpIHsKLSAgICAgICAgICAgICAgICBhYm9ydE5vdyA9IGZhbHNlOwotICAgICAgICAgICAgICAgIHJlc3RvcmVIYW5kbGVycygpOwotICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gQ29uc3VtZSB0aGlzIGV4Y2VwdGlvbiBpZiB0aGUgdXNlcgotICAgICAgICAgICAgLy8gaXNzdWVkIGFuIGludGVycnVwdCBvciBhbiBhYm9ydC4KLSAgICAgICAgICAgIGlmIChlICE9IEFib3J0LklOU1RBTkNFKSB7Ci0gICAgICAgICAgICAgICAgaWYgKCEoZSBpbnN0YW5jZW9mIFhNTFBhcnNlRXhjZXB0aW9uKSAmJiBmRXJyb3JIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICBET01FcnJvckltcGwgZXJyb3IgPSBuZXcgRE9NRXJyb3JJbXBsICgpOwotICAgICAgICAgICAgICAgICAgIGVycm9yLmZFeGNlcHRpb24gPSBlOwotICAgICAgICAgICAgICAgICAgIGVycm9yLmZNZXNzYWdlID0gZS5nZXRNZXNzYWdlICgpOwotICAgICAgICAgICAgICAgICAgIGVycm9yLmZTZXZlcml0eSA9IERPTUVycm9yLlNFVkVSSVRZX0ZBVEFMX0VSUk9SOwotICAgICAgICAgICAgICAgICAgIGZFcnJvckhhbmRsZXIuZ2V0RXJyb3JIYW5kbGVyKCkuaGFuZGxlRXJyb3IgKGVycm9yKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaWYgKERFQlVHKSB7Ci0gICAgICAgICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UgKCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHRocm93IChMU0V4Y2VwdGlvbikgRE9NVXRpbC5jcmVhdGVMU0V4Y2VwdGlvbihMU0V4Y2VwdGlvbi5QQVJTRV9FUlIsIGUpLmZpbGxJblN0YWNrVHJhY2UoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBEb2N1bWVudCBkb2MgPSBnZXREb2N1bWVudCgpOwotICAgICAgICBkcm9wRG9jdW1lbnRSZWZlcmVuY2VzKCk7Ci0gICAgICAgIHJldHVybiBkb2M7Ci0gICAgfQotCi0KLSAgICBwcml2YXRlIHZvaWQgcmVzdG9yZUhhbmRsZXJzKCkgewotICAgICAgICBmQ29uZmlndXJhdGlvbi5zZXREb2N1bWVudEhhbmRsZXIodGhpcyk7Ci0gICAgICAgIGZDb25maWd1cmF0aW9uLnNldERUREhhbmRsZXIodGhpcyk7Ci0gICAgICAgIGZDb25maWd1cmF0aW9uLnNldERURENvbnRlbnRNb2RlbEhhbmRsZXIodGhpcyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogIFBhcnNlIGFuIFhNTCBkb2N1bWVudCBvciBmcmFnbWVudCBmcm9tIGEgcmVzb3VyY2UgaWRlbnRpZmllZCBieSBhbgotICAgICAqIDxjb2RlPkxTSW5wdXQ8L2NvZGU+IGFuZCBpbnNlcnQgdGhlIGNvbnRlbnQgaW50byBhbiBleGlzdGluZwotICAgICAqIGRvY3VtZW50IGF0IHRoZSBwb3NpdGlvbiBlcGNpZmllZCB3aXRoIHRoZSA8Y29kZT5jb250ZXh0Tm9kZTwvY29kZT4KLSAgICAgKiBhbmQgPGNvZGU+YWN0aW9uPC9jb2RlPiBhcmd1bWVudHMuIFdoZW4gcGFyc2luZyB0aGUgaW5wdXQgc3RyZWFtIHRoZQotICAgICAqIGNvbnRleHQgbm9kZSBpcyB1c2VkIGZvciByZXNvbHZpbmcgdW5ib3VuZCBuYW1lc3BhY2UgcHJlZml4ZXMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaXMgIFRoZSA8Y29kZT5MU0lucHV0PC9jb2RlPiBmcm9tIHdoaWNoIHRoZSBzb3VyY2UKLSAgICAgKiAgIGRvY3VtZW50IGlzIHRvIGJlIHJlYWQuCi0gICAgICogQHBhcmFtIGNub2RlICBUaGUgPGNvZGU+Tm9kZTwvY29kZT4gdGhhdCBpcyB1c2VkIGFzIHRoZSBjb250ZXh0IGZvcgotICAgICAqICAgdGhlIGRhdGEgdGhhdCBpcyBiZWluZyBwYXJzZWQuCi0gICAgICogQHBhcmFtIGFjdGlvbiBUaGlzIHBhcmFtZXRlciBkZXNjcmliZXMgd2hpY2ggYWN0aW9uIHNob3VsZCBiZSB0YWtlbgotICAgICAqICAgYmV0d2VlbiB0aGUgbmV3IHNldCBvZiBub2RlIGJlaW5nIGluc2VydGVkIGFuZCB0aGUgZXhpc3RpbmcKLSAgICAgKiAgIGNoaWxkcmVuIG9mIHRoZSBjb250ZXh0IG5vZGUuIFRoZSBzZXQgb2YgcG9zc2libGUgYWN0aW9ucyBpcwotICAgICAqICAgZGVmaW5lZCBhYm92ZS4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgSElFUkFSQ0hZX1JFUVVFU1RfRVJSOiBUaHJvd24gaWYgdGhpcyBhY3Rpb24gcmVzdWx0cyBpbiBhbiBpbnZhbGlkCi0gICAgICogICBoaWVyYXJjaHkgKGkuZS4gYSBEb2N1bWVudCB3aXRoIG1vcmUgdGhhbiBvbmUgZG9jdW1lbnQgZWxlbWVudCkuCi0gICAgICovCi0gICAgcHVibGljIE5vZGUgcGFyc2VXaXRoQ29udGV4dCAoTFNJbnB1dCBpcywgTm9kZSBjbm9kZSwKLSAgICBzaG9ydCBhY3Rpb24pIHRocm93cyBET01FeGNlcHRpb24sIExTRXhjZXB0aW9uIHsKLSAgICAgICAgLy8gUkVWSVNJVDogbmVlZCB0byBpbXBsZW1lbnQuCi0gICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24gKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUiwgIk5vdCBzdXBwb3J0ZWQiKTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIE5PTi1ET006IGNvbnZlcnQgTFNJbnB1dCB0byBYTklJbnB1dFNvdXJjZQotICAgICAqCi0gICAgICogQHBhcmFtIGlzCi0gICAgICogQHJldHVybgotICAgICAqLwotICAgIFhNTElucHV0U291cmNlIGRvbTJ4bWxJbnB1dFNvdXJjZSAoTFNJbnB1dCBpcykgewotICAgICAgICAvLyBuZWVkIHRvIHdyYXAgdGhlIExTSW5wdXQgd2l0aCBhbiBYTUxJbnB1dFNvdXJjZQotICAgICAgICBYTUxJbnB1dFNvdXJjZSB4aXMgPSBudWxsOwotICAgICAgICAvLyBjaGVjayB3aGV0aGVyIHRoZXJlIGlzIGEgUmVhZGVyCi0gICAgICAgIC8vIGFjY29yZGluZyB0byBET00sIHdlIG5lZWQgdG8gdHJlYXQgc3VjaCByZWFkZXIgYXMgIlVURi0xNiIuCi0gICAgICAgIGlmIChpcy5nZXRDaGFyYWN0ZXJTdHJlYW0gKCkgIT0gbnVsbCkgewotICAgICAgICAgICAgeGlzID0gbmV3IFhNTElucHV0U291cmNlIChpcy5nZXRQdWJsaWNJZCAoKSwgaXMuZ2V0U3lzdGVtSWQgKCksCi0gICAgICAgICAgICBpcy5nZXRCYXNlVVJJICgpLCBpcy5nZXRDaGFyYWN0ZXJTdHJlYW0gKCksCi0gICAgICAgICAgICAiVVRGLTE2Iik7Ci0gICAgICAgIH0KLSAgICAgICAgLy8gY2hlY2sgd2hldGhlciB0aGVyZSBpcyBhbiBJbnB1dFN0cmVhbQotICAgICAgICBlbHNlIGlmIChpcy5nZXRCeXRlU3RyZWFtICgpICE9IG51bGwpIHsKLSAgICAgICAgICAgIHhpcyA9IG5ldyBYTUxJbnB1dFNvdXJjZSAoaXMuZ2V0UHVibGljSWQgKCksIGlzLmdldFN5c3RlbUlkICgpLAotICAgICAgICAgICAgaXMuZ2V0QmFzZVVSSSAoKSwgaXMuZ2V0Qnl0ZVN0cmVhbSAoKSwKLSAgICAgICAgICAgIGlzLmdldEVuY29kaW5nICgpKTsKLSAgICAgICAgfQotICAgICAgICAvLyBpZiB0aGVyZSBpcyBhIHN0cmluZyBkYXRhLCB1c2UgYSBTdHJpbmdSZWFkZXIKLSAgICAgICAgLy8gYWNjb3JkaW5nIHRvIERPTSwgd2UgbmVlZCB0byB0cmVhdCBzdWNoIGRhdGEgYXMgIlVURi0xNiIuCi0gICAgICAgIGVsc2UgaWYgKGlzLmdldFN0cmluZ0RhdGEgKCkgIT0gbnVsbCAmJiBpcy5nZXRTdHJpbmdEYXRhKCkubGVuZ3RoKCkgPiAwKSB7Ci0gICAgICAgICAgICB4aXMgPSBuZXcgWE1MSW5wdXRTb3VyY2UgKGlzLmdldFB1YmxpY0lkICgpLCBpcy5nZXRTeXN0ZW1JZCAoKSwKLSAgICAgICAgICAgIGlzLmdldEJhc2VVUkkgKCksIG5ldyBTdHJpbmdSZWFkZXIgKGlzLmdldFN0cmluZ0RhdGEgKCkpLAotICAgICAgICAgICAgIlVURi0xNiIpOwotICAgICAgICB9Ci0gICAgICAgIC8vIG90aGVyd2lzZSwganVzdCB1c2UgdGhlIHB1YmxpYy9zeXN0ZW0vYmFzZSBJZHMKLSAgICAgICAgZWxzZSBpZiAoKGlzLmdldFN5c3RlbUlkKCkgIT0gbnVsbCAmJiBpcy5nZXRTeXN0ZW1JZCgpLmxlbmd0aCgpID4gMCkgfHwKLSAgICAgICAgICAgIChpcy5nZXRQdWJsaWNJZCgpICE9IG51bGwgJiYgaXMuZ2V0UHVibGljSWQoKS5sZW5ndGgoKSA+IDApKSB7Ci0gICAgICAgICAgICB4aXMgPSBuZXcgWE1MSW5wdXRTb3VyY2UgKGlzLmdldFB1YmxpY0lkICgpLCBpcy5nZXRTeXN0ZW1JZCAoKSwKLSAgICAgICAgICAgIGlzLmdldEJhc2VVUkkgKCkpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgLy8gYWxsIGlucHV0cyBhcmUgbnVsbAotICAgICAgICAgICAgaWYgKGZFcnJvckhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIERPTUVycm9ySW1wbCBlcnJvciA9IG5ldyBET01FcnJvckltcGwoKTsKLSAgICAgICAgICAgICAgICBlcnJvci5mVHlwZSA9ICJuby1pbnB1dC1zcGVjaWZpZWQiOwotICAgICAgICAgICAgICAgIGVycm9yLmZNZXNzYWdlID0gIm5vLWlucHV0LXNwZWNpZmllZCI7Ci0gICAgICAgICAgICAgICAgZXJyb3IuZlNldmVyaXR5ID0gRE9NRXJyb3IuU0VWRVJJVFlfRkFUQUxfRVJST1I7Ci0gICAgICAgICAgICAgICAgZkVycm9ySGFuZGxlci5nZXRFcnJvckhhbmRsZXIoKS5oYW5kbGVFcnJvcihlcnJvcik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICB0aHJvdyBuZXcgTFNFeGNlcHRpb24oTFNFeGNlcHRpb24uUEFSU0VfRVJSLCAibm8taW5wdXQtc3BlY2lmaWVkIik7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHhpczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAc2VlIG9yZy53M2MuZG9tLmxzLkxTUGFyc2VyI2dldEFzeW5jKCkKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXRBc3luYyAoKSB7Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAc2VlIG9yZy53M2MuZG9tLmxzLkxTUGFyc2VyI2dldEJ1c3koKQotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGdldEJ1c3kgKCkgewotICAgICAgICByZXR1cm4gZkJ1c3k7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBvcmcudzNjLmRvbS5scy5ET01QYXJzZXIjYWJvcnQoKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGFib3J0ICgpIHsKLSAgICAgICAgLy8gSWYgcGFyc2Ugb3BlcmF0aW9uIGlzIGluIHByb2dyZXNzIHRoZW4gcmVzZXQgaXQKLSAgICAgICAgaWYgKCBmQnVzeSApIHsKLSAgICAgICAgICAgIGZCdXN5ID0gZmFsc2U7Ci0gICAgICAgICAgICBpZihjdXJyZW50VGhyZWFkICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBhYm9ydE5vdyA9IHRydWU7Ci0gICAgICAgICAgICAgICAgaWYgKGFib3J0SGFuZGxlciA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGFib3J0SGFuZGxlciA9IG5ldyBBYm9ydEhhbmRsZXIoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZkNvbmZpZ3VyYXRpb24uc2V0RG9jdW1lbnRIYW5kbGVyKGFib3J0SGFuZGxlcik7Ci0gICAgICAgICAgICAgICAgZkNvbmZpZ3VyYXRpb24uc2V0RFRESGFuZGxlcihhYm9ydEhhbmRsZXIpOwotICAgICAgICAgICAgICAgIGZDb25maWd1cmF0aW9uLnNldERURENvbnRlbnRNb2RlbEhhbmRsZXIoYWJvcnRIYW5kbGVyKTsKLQotICAgICAgICAgICAgICAgIGlmKGN1cnJlbnRUaHJlYWQgPT0gVGhyZWFkLmN1cnJlbnRUaHJlYWQoKSkKLSAgICAgICAgICAgICAgICAgICAgdGhyb3cgQWJvcnQuSU5TVEFOQ0U7Ci0KLSAgICAgICAgICAgICAgICBjdXJyZW50VGhyZWFkLmludGVycnVwdCgpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybjsgLy8gSWYgbm90IGJ1c3kgdGhlbiB0aGlzIGlzIG5vb3AKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgc3RhcnQgb2YgYW4gZWxlbWVudC4gSWYgdGhlIGRvY3VtZW50IHNwZWNpZmllcyB0aGUgc3RhcnQgZWxlbWVudAotICAgICAqIGJ5IHVzaW5nIGFuIGVtcHR5IHRhZywgdGhlbiB0aGUgc3RhcnRFbGVtZW50IG1ldGhvZCB3aWxsIGltbWVkaWF0ZWx5Ci0gICAgICogYmUgZm9sbG93ZWQgYnkgdGhlIGVuZEVsZW1lbnQgbWV0aG9kLCB3aXRoIG5vIGludGVydmVuaW5nIG1ldGhvZHMuCi0gICAgICogT3ZlcnJpZGluZyB0aGUgcGFyZW50IHRvIGhhbmRsZSBET01fTkFNRVNQQUNFX0RFQ0xBUkFUSU9OUz1mYWxzZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlbGVtZW50ICAgIFRoZSBuYW1lIG9mIHRoZSBlbGVtZW50LgotICAgICAqIEBwYXJhbSBhdHRyaWJ1dGVzIFRoZSBlbGVtZW50IGF0dHJpYnV0ZXMuCi0gICAgICogQHBhcmFtIGF1Z3MgICAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQgKFFOYW1lIGVsZW1lbnQsIFhNTEF0dHJpYnV0ZXMgYXR0cmlidXRlcywgQXVnbWVudGF0aW9ucyBhdWdzKSB7Ci0gICAgICAgIC8vIG5hbWVzcGFjZSBkZWNsYXJhdGlvbnMgcGFyYW1ldGVyIGhhcyBubyBlZmZlY3QgaWYgbmFtZXNwYWNlcyBpcyBmYWxzZS4KLSAgICAgICAgaWYgKCFmTmFtZXNwYWNlRGVjbGFyYXRpb25zICYmIGZOYW1lc3BhY2VBd2FyZSkgewotICAgICAgICAgICAgaW50IGxlbiA9IGF0dHJpYnV0ZXMuZ2V0TGVuZ3RoKCk7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gbGVuIC0gMTsgaSA+PSAwOyAtLWkpIHsKLSAgICAgICAgICAgICAgICBpZiAoWE1MU3ltYm9scy5QUkVGSVhfWE1MTlMgPT0gYXR0cmlidXRlcy5nZXRQcmVmaXgoaSkgfHwKLSAgICAgICAgICAgICAgICAgICAgWE1MU3ltYm9scy5QUkVGSVhfWE1MTlMgPT0gYXR0cmlidXRlcy5nZXRRTmFtZShpKSkgewotICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzLnJlbW92ZUF0dHJpYnV0ZUF0KGkpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBzdXBlci5zdGFydEVsZW1lbnQoZWxlbWVudCwgYXR0cmlidXRlcywgYXVncyk7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBjbGFzcyBBYm9ydEhhbmRsZXIgaW1wbGVtZW50cyBYTUxEb2N1bWVudEhhbmRsZXIsIFhNTERUREhhbmRsZXIsIFhNTERURENvbnRlbnRNb2RlbEhhbmRsZXIgIHsKLQotICAgICAgICBwcml2YXRlIFhNTERvY3VtZW50U291cmNlIGRvY3VtZW50U291cmNlOwotICAgICAgICBwcml2YXRlIFhNTERURENvbnRlbnRNb2RlbFNvdXJjZSBkdGRDb250ZW50U291cmNlOwotICAgICAgICBwcml2YXRlIFhNTERURFNvdXJjZSBkdGRTb3VyY2U7Ci0KLSAgICAgICAgcHVibGljIHZvaWQgc3RhcnREb2N1bWVudChYTUxMb2NhdG9yIGxvY2F0b3IsIFN0cmluZyBlbmNvZGluZywgTmFtZXNwYWNlQ29udGV4dCBuYW1lc3BhY2VDb250ZXh0LCBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICAgICAgdGhyb3cgQWJvcnQuSU5TVEFOQ0U7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCB4bWxEZWNsKFN0cmluZyB2ZXJzaW9uLCBTdHJpbmcgZW5jb2RpbmcsIFN0cmluZyBzdGFuZGFsb25lLCBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICAgICAgdGhyb3cgQWJvcnQuSU5TVEFOQ0U7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCBkb2N0eXBlRGVjbChTdHJpbmcgcm9vdEVsZW1lbnQsIFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkLCBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICAgICAgdGhyb3cgQWJvcnQuSU5TVEFOQ0U7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCBjb21tZW50KFhNTFN0cmluZyB0ZXh0LCBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICAgICAgdGhyb3cgQWJvcnQuSU5TVEFOQ0U7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCBwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oU3RyaW5nIHRhcmdldCwgWE1MU3RyaW5nIGRhdGEsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICB0aHJvdyBBYm9ydC5JTlNUQU5DRTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudChRTmFtZSBlbGVtZW50LCBYTUxBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICB0aHJvdyBBYm9ydC5JTlNUQU5DRTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyB2b2lkIGVtcHR5RWxlbWVudChRTmFtZSBlbGVtZW50LCBYTUxBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICB0aHJvdyBBYm9ydC5JTlNUQU5DRTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyB2b2lkIHN0YXJ0R2VuZXJhbEVudGl0eShTdHJpbmcgbmFtZSwgWE1MUmVzb3VyY2VJZGVudGlmaWVyIGlkZW50aWZpZXIsIFN0cmluZyBlbmNvZGluZywgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgICAgIHRocm93IEFib3J0LklOU1RBTkNFOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIHZvaWQgdGV4dERlY2woU3RyaW5nIHZlcnNpb24sIFN0cmluZyBlbmNvZGluZywgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgICAgIHRocm93IEFib3J0LklOU1RBTkNFOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIHZvaWQgZW5kR2VuZXJhbEVudGl0eShTdHJpbmcgbmFtZSwgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgICAgIHRocm93IEFib3J0LklOU1RBTkNFOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIHZvaWQgY2hhcmFjdGVycyhYTUxTdHJpbmcgdGV4dCwgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgICAgIHRocm93IEFib3J0LklOU1RBTkNFOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIHZvaWQgaWdub3JhYmxlV2hpdGVzcGFjZShYTUxTdHJpbmcgdGV4dCwgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgICAgIHRocm93IEFib3J0LklOU1RBTkNFOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIHZvaWQgZW5kRWxlbWVudChRTmFtZSBlbGVtZW50LCBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICAgICAgdGhyb3cgQWJvcnQuSU5TVEFOQ0U7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCBzdGFydENEQVRBKEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICB0aHJvdyBBYm9ydC5JTlNUQU5DRTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyB2b2lkIGVuZENEQVRBKEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICB0aHJvdyBBYm9ydC5JTlNUQU5DRTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyB2b2lkIGVuZERvY3VtZW50KEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICB0aHJvdyBBYm9ydC5JTlNUQU5DRTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyB2b2lkIHNldERvY3VtZW50U291cmNlKFhNTERvY3VtZW50U291cmNlIHNvdXJjZSkgewotICAgICAgICAgICAgZG9jdW1lbnRTb3VyY2UgPSBzb3VyY2U7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgWE1MRG9jdW1lbnRTb3VyY2UgZ2V0RG9jdW1lbnRTb3VyY2UoKSB7Ci0gICAgICAgICAgICByZXR1cm4gZG9jdW1lbnRTb3VyY2U7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCBzdGFydERURChYTUxMb2NhdG9yIGxvY2F0b3IsIEF1Z21lbnRhdGlvbnMgYXVnbWVudGF0aW9ucykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICB0aHJvdyBBYm9ydC5JTlNUQU5DRTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyB2b2lkIHN0YXJ0UGFyYW1ldGVyRW50aXR5KFN0cmluZyBuYW1lLCBYTUxSZXNvdXJjZUlkZW50aWZpZXIgaWRlbnRpZmllciwgU3RyaW5nIGVuY29kaW5nLCBBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICAgICAgdGhyb3cgQWJvcnQuSU5TVEFOQ0U7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCBlbmRQYXJhbWV0ZXJFbnRpdHkoU3RyaW5nIG5hbWUsIEF1Z21lbnRhdGlvbnMgYXVnbWVudGF0aW9ucykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICB0aHJvdyBBYm9ydC5JTlNUQU5DRTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyB2b2lkIHN0YXJ0RXh0ZXJuYWxTdWJzZXQoWE1MUmVzb3VyY2VJZGVudGlmaWVyIGlkZW50aWZpZXIsIEF1Z21lbnRhdGlvbnMgYXVnbWVudGF0aW9ucykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICB0aHJvdyBBYm9ydC5JTlNUQU5DRTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyB2b2lkIGVuZEV4dGVybmFsU3Vic2V0KEF1Z21lbnRhdGlvbnMgYXVnbWVudGF0aW9ucykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICB0aHJvdyBBYm9ydC5JTlNUQU5DRTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyB2b2lkIGVsZW1lbnREZWNsKFN0cmluZyBuYW1lLCBTdHJpbmcgY29udGVudE1vZGVsLCBBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICAgICAgdGhyb3cgQWJvcnQuSU5TVEFOQ0U7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCBzdGFydEF0dGxpc3QoU3RyaW5nIGVsZW1lbnROYW1lLCBBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICAgICAgdGhyb3cgQWJvcnQuSU5TVEFOQ0U7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCBhdHRyaWJ1dGVEZWNsKFN0cmluZyBlbGVtZW50TmFtZSwgU3RyaW5nIGF0dHJpYnV0ZU5hbWUsIFN0cmluZyB0eXBlLCBTdHJpbmdbXSBlbnVtZXJhdGlvbiwgU3RyaW5nIGRlZmF1bHRUeXBlLCBYTUxTdHJpbmcgZGVmYXVsdFZhbHVlLCBYTUxTdHJpbmcgbm9uTm9ybWFsaXplZERlZmF1bHRWYWx1ZSwgQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgICAgIHRocm93IEFib3J0LklOU1RBTkNFOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIHZvaWQgZW5kQXR0bGlzdChBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICAgICAgdGhyb3cgQWJvcnQuSU5TVEFOQ0U7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCBpbnRlcm5hbEVudGl0eURlY2woU3RyaW5nIG5hbWUsIFhNTFN0cmluZyB0ZXh0LCBYTUxTdHJpbmcgbm9uTm9ybWFsaXplZFRleHQsIEF1Z21lbnRhdGlvbnMgYXVnbWVudGF0aW9ucykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICB0aHJvdyBBYm9ydC5JTlNUQU5DRTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyB2b2lkIGV4dGVybmFsRW50aXR5RGVjbChTdHJpbmcgbmFtZSwgWE1MUmVzb3VyY2VJZGVudGlmaWVyIGlkZW50aWZpZXIsIEF1Z21lbnRhdGlvbnMgYXVnbWVudGF0aW9ucykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICB0aHJvdyBBYm9ydC5JTlNUQU5DRTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyB2b2lkIHVucGFyc2VkRW50aXR5RGVjbChTdHJpbmcgbmFtZSwgWE1MUmVzb3VyY2VJZGVudGlmaWVyIGlkZW50aWZpZXIsIFN0cmluZyBub3RhdGlvbiwgQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgICAgIHRocm93IEFib3J0LklOU1RBTkNFOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIHZvaWQgbm90YXRpb25EZWNsKFN0cmluZyBuYW1lLCBYTUxSZXNvdXJjZUlkZW50aWZpZXIgaWRlbnRpZmllciwgQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgICAgIHRocm93IEFib3J0LklOU1RBTkNFOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIHZvaWQgc3RhcnRDb25kaXRpb25hbChzaG9ydCB0eXBlLCBBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICAgICAgdGhyb3cgQWJvcnQuSU5TVEFOQ0U7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCBpZ25vcmVkQ2hhcmFjdGVycyhYTUxTdHJpbmcgdGV4dCwgQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgICAgIHRocm93IEFib3J0LklOU1RBTkNFOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIHZvaWQgZW5kQ29uZGl0aW9uYWwoQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgICAgIHRocm93IEFib3J0LklOU1RBTkNFOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIHZvaWQgZW5kRFREKEF1Z21lbnRhdGlvbnMgYXVnbWVudGF0aW9ucykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICB0aHJvdyBBYm9ydC5JTlNUQU5DRTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyB2b2lkIHNldERURFNvdXJjZShYTUxEVERTb3VyY2Ugc291cmNlKSB7Ci0gICAgICAgICAgICBkdGRTb3VyY2UgPSBzb3VyY2U7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgWE1MRFREU291cmNlIGdldERURFNvdXJjZSgpIHsKLSAgICAgICAgICAgIHJldHVybiBkdGRTb3VyY2U7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCBzdGFydENvbnRlbnRNb2RlbChTdHJpbmcgZWxlbWVudE5hbWUsIEF1Z21lbnRhdGlvbnMgYXVnbWVudGF0aW9ucykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICB0aHJvdyBBYm9ydC5JTlNUQU5DRTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyB2b2lkIGFueShBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICAgICAgdGhyb3cgQWJvcnQuSU5TVEFOQ0U7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCBlbXB0eShBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICAgICAgdGhyb3cgQWJvcnQuSU5TVEFOQ0U7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCBzdGFydEdyb3VwKEF1Z21lbnRhdGlvbnMgYXVnbWVudGF0aW9ucykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICB0aHJvdyBBYm9ydC5JTlNUQU5DRTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyB2b2lkIHBjZGF0YShBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICAgICAgdGhyb3cgQWJvcnQuSU5TVEFOQ0U7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCBlbGVtZW50KFN0cmluZyBlbGVtZW50TmFtZSwgQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgICAgIHRocm93IEFib3J0LklOU1RBTkNFOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIHZvaWQgc2VwYXJhdG9yKHNob3J0IHNlcGFyYXRvciwgQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgICAgIHRocm93IEFib3J0LklOU1RBTkNFOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIHZvaWQgb2NjdXJyZW5jZShzaG9ydCBvY2N1cnJlbmNlLCBBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICAgICAgdGhyb3cgQWJvcnQuSU5TVEFOQ0U7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCBlbmRHcm91cChBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICAgICAgdGhyb3cgQWJvcnQuSU5TVEFOQ0U7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCBlbmRDb250ZW50TW9kZWwoQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgICAgIHRocm93IEFib3J0LklOU1RBTkNFOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIHZvaWQgc2V0RFREQ29udGVudE1vZGVsU291cmNlKFhNTERURENvbnRlbnRNb2RlbFNvdXJjZSBzb3VyY2UpIHsKLSAgICAgICAgICAgIGR0ZENvbnRlbnRTb3VyY2UgPSBzb3VyY2U7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgWE1MRFREQ29udGVudE1vZGVsU291cmNlIGdldERURENvbnRlbnRNb2RlbFNvdXJjZSgpIHsKLSAgICAgICAgICAgIHJldHVybiBkdGRDb250ZW50U291cmNlOwotICAgICAgICB9Ci0KLSAgICB9Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBET01FeGNlcHRpb24gbmV3RmVhdHVyZU5vdEZvdW5kRXJyb3IoU3RyaW5nIG5hbWUpIHsKLSAgICAgICAgU3RyaW5nIG1zZyA9Ci0gICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UgKAotICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICJGRUFUVVJFX05PVF9GT1VORCIsCi0gICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7IG5hbWUgfSk7Ci0gICAgICAgIHJldHVybiBuZXcgRE9NRXhjZXB0aW9uIChET01FeGNlcHRpb24uTk9UX0ZPVU5EX0VSUiwgbXNnKTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBET01FeGNlcHRpb24gbmV3VHlwZU1pc21hdGNoRXJyb3IoU3RyaW5nIG5hbWUpIHsKLSAgICAgICAgU3RyaW5nIG1zZyA9Ci0gICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UgKAotICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICJUWVBFX01JU01BVENIX0VSUiIsCi0gICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7IG5hbWUgfSk7Ci0gICAgICAgIHJldHVybiBuZXcgRE9NRXhjZXB0aW9uIChET01FeGNlcHRpb24uVFlQRV9NSVNNQVRDSF9FUlIsIG1zZyk7Ci0gICAgfQotCi19IC8vIGNsYXNzIERPTVBhcnNlckltcGwKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3BhcnNlcnMvRFREQ29uZmlndXJhdGlvbi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvcGFyc2Vycy9EVERDb25maWd1cmF0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDBmMzdmN2MuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvcGFyc2Vycy9EVERDb25maWd1cmF0aW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4ODMgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnBhcnNlcnM7Ci0KLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5YTUxEVERTY2FubmVySW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuWE1MRG9jdW1lbnRTY2FubmVySW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuWE1MRW50aXR5TWFuYWdlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuWE1MRXJyb3JSZXBvcnRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuWE1MTmFtZXNwYWNlQmluZGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdGQuWE1MRFREUHJvY2Vzc29yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdGQuWE1MRFREVmFsaWRhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5EVEREVkZhY3Rvcnk7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLm1zZy5YTUxNZXNzYWdlRm9ybWF0dGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC52YWxpZGF0aW9uLlZhbGlkYXRpb25NYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5GZWF0dXJlU3RhdGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlByb3BlcnR5U3RhdGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlN0YXR1czsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuU3ltYm9sVGFibGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlscy5YTUxTZWN1cml0eVByb3BlcnR5TWFuYWdlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxMb2NhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhOSUV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5ncmFtbWFycy5YTUxHcmFtbWFyUG9vbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MQ29tcG9uZW50OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxDb21wb25lbnRNYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxEVERTY2FubmVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxEb2N1bWVudFNjYW5uZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTElucHV0U291cmNlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxQdWxsUGFyc2VyQ29uZmlndXJhdGlvbjsKLQotLyoqCi0gKiBUaGlzIGlzIHRoZSBEVEQtb25seSBwYXJzZXIgY29uZmlndXJhdGlvbi4gIEl0IGV4dGVuZHMgdGhlIGJhc2ljCi0gKiBjb25maWd1cmF0aW9uIHdpdGggYSBzdGFuZGFyZCBzZXQgb2YgcGFyc2VyIGNvbXBvbmVudHMgYXBwcm9wcmlhdGUKLSAqIHRvIERURC1jZW50cmljIHZhbGlkYXRpb24uIFNpbmNlCi0gKiB0aGUgWGVyY2VzMiByZWZlcmVuY2UgaW1wbGVtZW50YXRpb24gZG9jdW1lbnQgYW5kIERURCBzY2FubmVyCi0gKiBpbXBsZW1lbnRhdGlvbnMgYXJlIGNhcGFibGUgb2YgYWN0aW5nIGFzIHB1bGwgcGFyc2VycywgdGhpcwotICogY29uZmlndXJhdGlvbiBpbXBsZW1lbnRzIHRoZQotICogPGNvZGU+WE1MUHVsbFBhcnNlckNvbmZpZ3VyYXRpb248L2NvZGU+IGludGVyZmFjZS4KLSAqIDxwPgotICogSW4gYWRkaXRpb24gdG8gdGhlIGZlYXR1cmVzIGFuZCBwcm9wZXJ0aWVzIHJlY29nbml6ZWQgYnkgdGhlIGJhc2UKLSAqIHBhcnNlciBjb25maWd1cmF0aW9uLCB0aGlzIGNsYXNzIHJlY29nbml6ZXMgdGhlc2UgYWRkaXRpb25hbAotICogZmVhdHVyZXMgYW5kIHByb3BlcnRpZXM6Ci0gKiA8dWw+Ci0gKiA8bGk+RmVhdHVyZXMKLSAqICA8dWw+Ci0gKiAgIDxsaT5odHRwOi8vYXBhY2hlLm9yZy94bWwvZmVhdHVyZXMvdmFsaWRhdGlvbi93YXJuLW9uLWR1cGxpY2F0ZS1hdHRkZWY8L2xpPgotICogICA8bGk+aHR0cDovL2FwYWNoZS5vcmcveG1sL2ZlYXR1cmVzL3ZhbGlkYXRpb24vd2Fybi1vbi11bmRlY2xhcmVkLWVsZW1kZWY8L2xpPgotICogICA8bGk+aHR0cDovL2FwYWNoZS5vcmcveG1sL2ZlYXR1cmVzL2FsbG93LWphdmEtZW5jb2RpbmdzPC9saT4KLSAqICAgPGxpPmh0dHA6Ly9hcGFjaGUub3JnL3htbC9mZWF0dXJlcy9jb250aW51ZS1hZnRlci1mYXRhbC1lcnJvcjwvbGk+Ci0gKiAgIDxsaT5odHRwOi8vYXBhY2hlLm9yZy94bWwvZmVhdHVyZXMvbG9hZC1leHRlcm5hbC1kdGQ8L2xpPgotICogIDwvdWw+Ci0gKiA8bGk+UHJvcGVydGllcwotICogIDx1bD4KLSAqICAgPGxpPmh0dHA6Ly9hcGFjaGUub3JnL3htbC9wcm9wZXJ0aWVzL2ludGVybmFsL2Vycm9yLXJlcG9ydGVyPC9saT4KLSAqICAgPGxpPmh0dHA6Ly9hcGFjaGUub3JnL3htbC9wcm9wZXJ0aWVzL2ludGVybmFsL2VudGl0eS1tYW5hZ2VyPC9saT4KLSAqICAgPGxpPmh0dHA6Ly9hcGFjaGUub3JnL3htbC9wcm9wZXJ0aWVzL2ludGVybmFsL2RvY3VtZW50LXNjYW5uZXI8L2xpPgotICogICA8bGk+aHR0cDovL2FwYWNoZS5vcmcveG1sL3Byb3BlcnRpZXMvaW50ZXJuYWwvZHRkLXNjYW5uZXI8L2xpPgotICogICA8bGk+aHR0cDovL2FwYWNoZS5vcmcveG1sL3Byb3BlcnRpZXMvaW50ZXJuYWwvZ3JhbW1hci1wb29sPC9saT4KLSAqICAgPGxpPmh0dHA6Ly9hcGFjaGUub3JnL3htbC9wcm9wZXJ0aWVzL2ludGVybmFsL3ZhbGlkYXRvci9kdGQ8L2xpPgotICogICA8bGk+aHR0cDovL2FwYWNoZS5vcmcveG1sL3Byb3BlcnRpZXMvaW50ZXJuYWwvZGF0YXR5cGUtdmFsaWRhdG9yLWZhY3Rvcnk8L2xpPgotICogIDwvdWw+Ci0gKiA8L3VsPgotICoKLSAqIEBhdXRob3IgQXJuYXVkICBMZSBIb3JzLCBJQk0KLSAqIEBhdXRob3IgQW5keSBDbGFyaywgSUJNCi0gKiBAYXV0aG9yIE5laWwgR3JhaGFtLCBJQk0KLSAqCi0gKiBAdmVyc2lvbiAkSWQ6IERURENvbmZpZ3VyYXRpb24uamF2YSx2IDEuNyAyMDEwLTExLTAxIDA0OjQwOjA5IGpvZWh3IEV4cCAkCi0gKi8KLXB1YmxpYyBjbGFzcyBEVERDb25maWd1cmF0aW9uCi0gICAgZXh0ZW5kcyBCYXNpY1BhcnNlckNvbmZpZ3VyYXRpb24KLSAgICBpbXBsZW1lbnRzIFhNTFB1bGxQYXJzZXJDb25maWd1cmF0aW9uIHsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RhbnRzCi0gICAgLy8KLQotICAgIC8vIGZlYXR1cmUgaWRlbnRpZmllcnMKLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IHdhcm4gb24gZHVwbGljYXRlIGF0dHJpYnV0ZSBkZWZpbml0aW9uLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFdBUk5fT05fRFVQTElDQVRFX0FUVERFRiA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuV0FSTl9PTl9EVVBMSUNBVEVfQVRUREVGX0ZFQVRVUkU7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiB3YXJuIG9uIGR1cGxpY2F0ZSBlbnRpdHkgZGVmaW5pdGlvbi4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBXQVJOX09OX0RVUExJQ0FURV9FTlRJVFlERUYgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLldBUk5fT05fRFVQTElDQVRFX0VOVElUWURFRl9GRUFUVVJFOwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogd2FybiBvbiB1bmRlY2xhcmVkIGVsZW1lbnQgZGVmaW5pdGlvbi4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBXQVJOX09OX1VOREVDTEFSRURfRUxFTURFRiA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuV0FSTl9PTl9VTkRFQ0xBUkVEX0VMRU1ERUZfRkVBVFVSRTsKLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IGFsbG93IEphdmEgZW5jb2RpbmdzLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIEFMTE9XX0pBVkFfRU5DT0RJTkdTID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5BTExPV19KQVZBX0VOQ09ESU5HU19GRUFUVVJFOwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogY29udGludWUgYWZ0ZXIgZmF0YWwgZXJyb3IuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ09OVElOVUVfQUZURVJfRkFUQUxfRVJST1IgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLkNPTlRJTlVFX0FGVEVSX0ZBVEFMX0VSUk9SX0ZFQVRVUkU7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiBsb2FkIGV4dGVybmFsIERURC4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBMT0FEX0VYVEVSTkFMX0RURCA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuTE9BRF9FWFRFUk5BTF9EVERfRkVBVFVSRTsKLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IG5vdGlmeSBidWlsdC1pbiByZWZlcmVjZXMuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgTk9USUZZX0JVSUxUSU5fUkVGUyA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuTk9USUZZX0JVSUxUSU5fUkVGU19GRUFUVVJFOwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogbm90aWZ5IGNoYXJhY3RlciByZWZlcmVjZXMuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgTk9USUZZX0NIQVJfUkVGUyA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuTk9USUZZX0NIQVJfUkVGU19GRUFUVVJFOwotCi0KLSAgICAvLyBwcm9wZXJ0eSBpZGVudGlmaWVycwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IGVycm9yIHJlcG9ydGVyLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUk9SX1JFUE9SVEVSID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuRVJST1JfUkVQT1JURVJfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogZW50aXR5IG1hbmFnZXIuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgRU5USVRZX01BTkFHRVIgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5FTlRJVFlfTUFOQUdFUl9QUk9QRVJUWTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyIGRvY3VtZW50IHNjYW5uZXI6ICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgRE9DVU1FTlRfU0NBTk5FUiA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLkRPQ1VNRU5UX1NDQU5ORVJfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogRFREIHNjYW5uZXIuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgRFREX1NDQU5ORVIgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5EVERfU0NBTk5FUl9QUk9QRVJUWTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBncmFtbWFyIHBvb2wuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MR1JBTU1BUl9QT09MID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuWE1MR1JBTU1BUl9QT09MX1BST1BFUlRZOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IERURCBsb2FkZXIuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgRFREX1BST0NFU1NPUiA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLkRURF9QUk9DRVNTT1JfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogRFREIHZhbGlkYXRvci4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBEVERfVkFMSURBVE9SID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuRFREX1ZBTElEQVRPUl9QUk9QRVJUWTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBuYW1lc3BhY2UgYmluZGVyLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIE5BTUVTUEFDRV9CSU5ERVIgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5OQU1FU1BBQ0VfQklOREVSX1BST1BFUlRZOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IGRhdGF0eXBlIHZhbGlkYXRvciBmYWN0b3J5LiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIERBVEFUWVBFX1ZBTElEQVRPUl9GQUNUT1JZID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuREFUQVRZUEVfVkFMSURBVE9SX0ZBQ1RPUllfUFJPUEVSVFk7Ci0KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBWQUxJREFUSU9OX01BTkFHRVIgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5WQUxJREFUSU9OX01BTkFHRVJfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogSkFYUCBzY2hlbWEgbGFuZ3VhZ2UgLyBET00gc2NoZW1hLXR5cGUuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgSkFYUF9TQ0hFTUFfTEFOR1VBR0UgPQotICAgICAgICBDb25zdGFudHMuSkFYUF9QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuU0NIRU1BX0xBTkdVQUdFOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IEpBWFAgc2NoZW1hIHNvdXJjZS8gRE9NIHNjaGVtYS1sb2NhdGlvbi4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBKQVhQX1NDSEVNQV9TT1VSQ0UgPQotICAgICAgICBDb25zdGFudHMuSkFYUF9QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuU0NIRU1BX1NPVVJDRTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBsb2NhbGUuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgTE9DQUxFID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuTE9DQUxFX1BST1BFUlRZOwotCi0gICAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogU2VjdXJpdHkgcHJvcGVydHkgbWFuYWdlci4gKi8KLSAgICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFhNTF9TRUNVUklUWV9QUk9QRVJUWV9NQU5BR0VSID0KLSAgICAgICAgICAgICAgQ29uc3RhbnRzLlhNTF9TRUNVUklUWV9QUk9QRVJUWV9NQU5BR0VSOwotCi0gICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBTZWN1cml0eSBtYW5hZ2VyLiAqLwotICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgU0VDVVJJVFlfTUFOQUdFUiA9IENvbnN0YW50cy5TRUNVUklUWV9NQU5BR0VSOwotCi0gICAgLy8gZGVidWdnaW5nCi0KLSAgICAvKiogU2V0IHRvIHRydWUgYW5kIHJlY29tcGlsZSB0byBwcmludCBleGNlcHRpb24gc3RhY2sgdHJhY2UuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBib29sZWFuIFBSSU5UX0VYQ0VQVElPTl9TVEFDS19UUkFDRSA9IGZhbHNlOwotCi0gICAgLy8KLSAgICAvLyBEYXRhCi0gICAgLy8KLQotICAgIC8vIGNvbXBvbmVudHMgKG5vbi1jb25maWd1cmFibGUpCi0KLSAgICAvKiogR3JhbW1hciBwb29sLiAqLwotICAgIHByb3RlY3RlZCBYTUxHcmFtbWFyUG9vbCBmR3JhbW1hclBvb2w7Ci0KLSAgICAvKiogRGF0YXR5cGUgdmFsaWRhdG9yIGZhY3RvcnkuICovCi0gICAgcHJvdGVjdGVkIERURERWRmFjdG9yeSBmRGF0YXR5cGVWYWxpZGF0b3JGYWN0b3J5OwotCi0gICAgLy8gY29tcG9uZW50cyAoY29uZmlndXJhYmxlKQotCi0gICAgLyoqIEVycm9yIHJlcG9ydGVyLiAqLwotICAgIHByb3RlY3RlZCBYTUxFcnJvclJlcG9ydGVyIGZFcnJvclJlcG9ydGVyOwotCi0gICAgLyoqIEVudGl0eSBtYW5hZ2VyLiAqLwotICAgIHByb3RlY3RlZCBYTUxFbnRpdHlNYW5hZ2VyIGZFbnRpdHlNYW5hZ2VyOwotCi0gICAgLyoqIERvY3VtZW50IHNjYW5uZXIuICovCi0gICAgcHJvdGVjdGVkIFhNTERvY3VtZW50U2Nhbm5lciBmU2Nhbm5lcjsKLQotICAgIC8qKiBJbnB1dCBTb3VyY2UgKi8KLSAgICBwcm90ZWN0ZWQgWE1MSW5wdXRTb3VyY2UgZklucHV0U291cmNlOwotCi0gICAgLyoqIERURCBzY2FubmVyLiAqLwotICAgIHByb3RlY3RlZCBYTUxEVERTY2FubmVyIGZEVERTY2FubmVyOwotCi0gICAgLyoqIERURCBQcm9jZXNzb3IgLiAqLwotICAgIHByb3RlY3RlZCBYTUxEVERQcm9jZXNzb3IgZkRURFByb2Nlc3NvcjsKLQotICAgIC8qKiBEVEQgVmFsaWRhdG9yLiAqLwotICAgIHByb3RlY3RlZCBYTUxEVERWYWxpZGF0b3IgZkRURFZhbGlkYXRvcjsKLQotICAgIC8qKiBOYW1lc3BhY2UgYmluZGVyLiAqLwotICAgIHByb3RlY3RlZCBYTUxOYW1lc3BhY2VCaW5kZXIgZk5hbWVzcGFjZUJpbmRlcjsKLQotICAgIHByb3RlY3RlZCBWYWxpZGF0aW9uTWFuYWdlciBmVmFsaWRhdGlvbk1hbmFnZXI7Ci0gICAgLy8gc3RhdGUKLQotICAgIC8qKiBMb2NhdG9yICovCi0gICAgcHJvdGVjdGVkIFhNTExvY2F0b3IgZkxvY2F0b3I7Ci0KLSAgICAvKioKLSAgICAgKiBUcnVlIGlmIGEgcGFyc2UgaXMgaW4gcHJvZ3Jlc3MuIFRoaXMgc3RhdGUgaXMgbmVlZGVkIGJlY2F1c2UKLSAgICAgKiBzb21lIGZlYXR1cmVzL3Byb3BlcnRpZXMgY2Fubm90IGJlIHNldCB3aGlsZSBwYXJzaW5nIChlLmcuCi0gICAgICogdmFsaWRhdGlvbiBhbmQgbmFtZXNwYWNlcykuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZlBhcnNlSW5Qcm9ncmVzcyA9IGZhbHNlOwotCi0gICAgLy8KLSAgICAvLyBDb25zdHJ1Y3RvcnMKLSAgICAvLwotCi0gICAgLyoqIERlZmF1bHQgY29uc3RydWN0b3IuICovCi0gICAgcHVibGljIERURENvbmZpZ3VyYXRpb24oKSB7Ci0gICAgICAgIHRoaXMobnVsbCwgbnVsbCwgbnVsbCk7Ci0gICAgfSAvLyA8aW5pdD4oKQotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0cyBhIHBhcnNlciBjb25maWd1cmF0aW9uIHVzaW5nIHRoZSBzcGVjaWZpZWQgc3ltYm9sIHRhYmxlLgotICAgICAqCi0gICAgICogQHBhcmFtIHN5bWJvbFRhYmxlIFRoZSBzeW1ib2wgdGFibGUgdG8gdXNlLgotICAgICAqLwotICAgIHB1YmxpYyBEVERDb25maWd1cmF0aW9uKFN5bWJvbFRhYmxlIHN5bWJvbFRhYmxlKSB7Ci0gICAgICAgIHRoaXMoc3ltYm9sVGFibGUsIG51bGwsIG51bGwpOwotICAgIH0gLy8gPGluaXQ+KFN5bWJvbFRhYmxlKQotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0cyBhIHBhcnNlciBjb25maWd1cmF0aW9uIHVzaW5nIHRoZSBzcGVjaWZpZWQgc3ltYm9sIHRhYmxlIGFuZAotICAgICAqIGdyYW1tYXIgcG9vbC4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPlJFVklTSVQ6PC9zdHJvbmc+Ci0gICAgICogR3JhbW1hciBwb29sIHdpbGwgYmUgdXBkYXRlZCB3aGVuIHRoZSBuZXcgdmFsaWRhdGlvbiBlbmdpbmUgaXMKLSAgICAgKiBpbXBsZW1lbnRlZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzeW1ib2xUYWJsZSBUaGUgc3ltYm9sIHRhYmxlIHRvIHVzZS4KLSAgICAgKiBAcGFyYW0gZ3JhbW1hclBvb2wgVGhlIGdyYW1tYXIgcG9vbCB0byB1c2UuCi0gICAgICovCi0gICAgcHVibGljIERURENvbmZpZ3VyYXRpb24oU3ltYm9sVGFibGUgc3ltYm9sVGFibGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxHcmFtbWFyUG9vbCBncmFtbWFyUG9vbCkgewotICAgICAgICB0aGlzKHN5bWJvbFRhYmxlLCBncmFtbWFyUG9vbCwgbnVsbCk7Ci0gICAgfSAvLyA8aW5pdD4oU3ltYm9sVGFibGUsWE1MR3JhbW1hclBvb2wpCi0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RzIGEgcGFyc2VyIGNvbmZpZ3VyYXRpb24gdXNpbmcgdGhlIHNwZWNpZmllZCBzeW1ib2wgdGFibGUsCi0gICAgICogZ3JhbW1hciBwb29sLCBhbmQgcGFyZW50IHNldHRpbmdzLgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+UkVWSVNJVDo8L3N0cm9uZz4KLSAgICAgKiBHcmFtbWFyIHBvb2wgd2lsbCBiZSB1cGRhdGVkIHdoZW4gdGhlIG5ldyB2YWxpZGF0aW9uIGVuZ2luZSBpcwotICAgICAqIGltcGxlbWVudGVkLgotICAgICAqCi0gICAgICogQHBhcmFtIHN5bWJvbFRhYmxlICAgIFRoZSBzeW1ib2wgdGFibGUgdG8gdXNlLgotICAgICAqIEBwYXJhbSBncmFtbWFyUG9vbCAgICBUaGUgZ3JhbW1hciBwb29sIHRvIHVzZS4KLSAgICAgKiBAcGFyYW0gcGFyZW50U2V0dGluZ3MgVGhlIHBhcmVudCBzZXR0aW5ncy4KLSAgICAgKi8KLSAgICBwdWJsaWMgRFREQ29uZmlndXJhdGlvbihTeW1ib2xUYWJsZSBzeW1ib2xUYWJsZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTEdyYW1tYXJQb29sIGdyYW1tYXJQb29sLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MQ29tcG9uZW50TWFuYWdlciBwYXJlbnRTZXR0aW5ncykgewotICAgICAgICBzdXBlcihzeW1ib2xUYWJsZSwgcGFyZW50U2V0dGluZ3MpOwotCi0gICAgICAgIC8vIGFkZCBkZWZhdWx0IHJlY29nbml6ZWQgZmVhdHVyZXMKLSAgICAgICAgZmluYWwgU3RyaW5nW10gcmVjb2duaXplZEZlYXR1cmVzID0gewotICAgICAgICAgICAgLy9XQVJOX09OX0RVUExJQ0FURV9BVFRERUYsICAgICAvLyBmcm9tIFhNTERURFNjYW5uZXJJbXBsCi0gICAgICAgICAgICAvL1dBUk5fT05fVU5ERUNMQVJFRF9FTEVNREVGLCAgIC8vIGZyb20gWE1MRFREU2Nhbm5lckltcGwKLSAgICAgICAgICAgIC8vQUxMT1dfSkFWQV9FTkNPRElOR1MsICAgICAgICAgLy8gZnJvbSBYTUxFbnRpdHlNYW5hZ2VyCi0gICAgICAgICAgICBDT05USU5VRV9BRlRFUl9GQVRBTF9FUlJPUiwKLSAgICAgICAgICAgIExPQURfRVhURVJOQUxfRFRELCAgICAvLyBmcm9tIFhNTERURFNjYW5uZXJJbXBsCi0gICAgICAgICAgICAvL05PVElGWV9CVUlMVElOX1JFRlMsICAvLyBmcm9tIFhNTERvY3VtZW50RnJhZ21lbnRTY2FubmVySW1wbAotICAgICAgICAgICAgLy9OT1RJRllfQ0hBUl9SRUZTLCAgICAgICAgIC8vIGZyb20gWE1MRG9jdW1lbnRGcmFnbWVudFNjYW5uZXJJbXBsCi0gICAgICAgICAgICAvL1dBUk5fT05fRFVQTElDQVRFX0VOVElUWURFRiwgIC8vIGZyb20gWE1MRW50aXR5TWFuYWdlcgotICAgICAgICB9OwotICAgICAgICBhZGRSZWNvZ25pemVkRmVhdHVyZXMocmVjb2duaXplZEZlYXR1cmVzKTsKLQotICAgICAgICAvLyBzZXQgc3RhdGUgZm9yIGRlZmF1bHQgZmVhdHVyZXMKLSAgICAgICAgLy9zZXRGZWF0dXJlKFdBUk5fT05fRFVQTElDQVRFX0FUVERFRiwgZmFsc2UpOyAgLy8gZnJvbSBYTUxEVERTY2FubmVySW1wbAotICAgICAgICAvL3NldEZlYXR1cmUoV0FSTl9PTl9VTkRFQ0xBUkVEX0VMRU1ERUYsIGZhbHNlKTsgIC8vIGZyb20gWE1MRFREU2Nhbm5lckltcGwKLSAgICAgICAgLy9zZXRGZWF0dXJlKEFMTE9XX0pBVkFfRU5DT0RJTkdTLCBmYWxzZSk7ICAgICAgLy8gZnJvbSBYTUxFbnRpdHlNYW5hZ2VyCi0gICAgICAgIHNldEZlYXR1cmUoQ09OVElOVUVfQUZURVJfRkFUQUxfRVJST1IsIGZhbHNlKTsKLSAgICAgICAgc2V0RmVhdHVyZShMT0FEX0VYVEVSTkFMX0RURCwgdHJ1ZSk7ICAgICAgLy8gZnJvbSBYTUxEVERTY2FubmVySW1wbAotICAgICAgICAvL3NldEZlYXR1cmUoTk9USUZZX0JVSUxUSU5fUkVGUywgZmFsc2UpOyAgIC8vIGZyb20gWE1MRG9jdW1lbnRGcmFnbWVudFNjYW5uZXJJbXBsCi0gICAgICAgIC8vc2V0RmVhdHVyZShOT1RJRllfQ0hBUl9SRUZTLCBmYWxzZSk7ICAgICAgLy8gZnJvbSBYTUxEb2N1bWVudEZyYWdtZW50U2Nhbm5lckltcGwKLSAgICAgICAgLy9zZXRGZWF0dXJlKFdBUk5fT05fRFVQTElDQVRFX0VOVElUWURFRiwgZmFsc2UpOyAgIC8vIGZyb20gWE1MRW50aXR5TWFuYWdlcgotCi0gICAgICAgIC8vIGFkZCBkZWZhdWx0IHJlY29nbml6ZWQgcHJvcGVydGllcwotICAgICAgICBmaW5hbCBTdHJpbmdbXSByZWNvZ25pemVkUHJvcGVydGllcyA9IHsKLSAgICAgICAgICAgIEVSUk9SX1JFUE9SVEVSLAotICAgICAgICAgICAgRU5USVRZX01BTkFHRVIsCi0gICAgICAgICAgICBET0NVTUVOVF9TQ0FOTkVSLAotICAgICAgICAgICAgRFREX1NDQU5ORVIsCi0gICAgICAgICAgICBEVERfUFJPQ0VTU09SLAotICAgICAgICAgICAgRFREX1ZBTElEQVRPUiwKLSAgICAgICAgICAgIE5BTUVTUEFDRV9CSU5ERVIsCi0gICAgICAgICAgICBYTUxHUkFNTUFSX1BPT0wsCi0gICAgICAgICAgICBEQVRBVFlQRV9WQUxJREFUT1JfRkFDVE9SWSwKLSAgICAgICAgICAgIFZBTElEQVRJT05fTUFOQUdFUiwKLSAgICAgICAgICAgIEpBWFBfU0NIRU1BX1NPVVJDRSwKLSAgICAgICAgICAgIEpBWFBfU0NIRU1BX0xBTkdVQUdFLAotICAgICAgICAgICAgTE9DQUxFLAotICAgICAgICAgICAgU0VDVVJJVFlfTUFOQUdFUiwKLSAgICAgICAgICAgIFhNTF9TRUNVUklUWV9QUk9QRVJUWV9NQU5BR0VSCi0gICAgICAgIH07Ci0gICAgICAgIGFkZFJlY29nbml6ZWRQcm9wZXJ0aWVzKHJlY29nbml6ZWRQcm9wZXJ0aWVzKTsKLQotICAgICAgICBmR3JhbW1hclBvb2wgPSBncmFtbWFyUG9vbDsKLSAgICAgICAgaWYoZkdyYW1tYXJQb29sICE9IG51bGwpewotICAgICAgICAgICAgc2V0UHJvcGVydHkoWE1MR1JBTU1BUl9QT09MLCBmR3JhbW1hclBvb2wpOwotICAgICAgICB9Ci0KLSAgICAgICAgZkVudGl0eU1hbmFnZXIgPSBjcmVhdGVFbnRpdHlNYW5hZ2VyKCk7Ci0gICAgICAgIHNldFByb3BlcnR5KEVOVElUWV9NQU5BR0VSLCBmRW50aXR5TWFuYWdlcik7Ci0gICAgICAgIGFkZENvbXBvbmVudChmRW50aXR5TWFuYWdlcik7Ci0KLSAgICAgICAgZkVycm9yUmVwb3J0ZXIgPSBjcmVhdGVFcnJvclJlcG9ydGVyKCk7Ci0gICAgICAgIGZFcnJvclJlcG9ydGVyLnNldERvY3VtZW50TG9jYXRvcihmRW50aXR5TWFuYWdlci5nZXRFbnRpdHlTY2FubmVyKCkpOwotICAgICAgICBzZXRQcm9wZXJ0eShFUlJPUl9SRVBPUlRFUiwgZkVycm9yUmVwb3J0ZXIpOwotICAgICAgICBhZGRDb21wb25lbnQoZkVycm9yUmVwb3J0ZXIpOwotCi0gICAgICAgIGZTY2FubmVyID0gY3JlYXRlRG9jdW1lbnRTY2FubmVyKCk7Ci0gICAgICAgIHNldFByb3BlcnR5KERPQ1VNRU5UX1NDQU5ORVIsIGZTY2FubmVyKTsKLSAgICAgICAgaWYgKGZTY2FubmVyIGluc3RhbmNlb2YgWE1MQ29tcG9uZW50KSB7Ci0gICAgICAgICAgICBhZGRDb21wb25lbnQoKFhNTENvbXBvbmVudClmU2Nhbm5lcik7Ci0gICAgICAgIH0KLQotICAgICAgICBmRFREU2Nhbm5lciA9IGNyZWF0ZURURFNjYW5uZXIoKTsKLSAgICAgICAgaWYgKGZEVERTY2FubmVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIHNldFByb3BlcnR5KERURF9TQ0FOTkVSLCBmRFREU2Nhbm5lcik7Ci0gICAgICAgICAgICBpZiAoZkRURFNjYW5uZXIgaW5zdGFuY2VvZiBYTUxDb21wb25lbnQpIHsKLSAgICAgICAgICAgICAgICBhZGRDb21wb25lbnQoKFhNTENvbXBvbmVudClmRFREU2Nhbm5lcik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBmRFREUHJvY2Vzc29yID0gY3JlYXRlRFREUHJvY2Vzc29yKCk7Ci0gICAgICAgIGlmIChmRFREUHJvY2Vzc29yICE9IG51bGwpIHsKLSAgICAgICAgICAgIHNldFByb3BlcnR5KERURF9QUk9DRVNTT1IsIGZEVERQcm9jZXNzb3IpOwotICAgICAgICAgICAgaWYgKGZEVERQcm9jZXNzb3IgaW5zdGFuY2VvZiBYTUxDb21wb25lbnQpIHsKLSAgICAgICAgICAgICAgICBhZGRDb21wb25lbnQoKFhNTENvbXBvbmVudClmRFREUHJvY2Vzc29yKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGZEVERWYWxpZGF0b3IgPSBjcmVhdGVEVERWYWxpZGF0b3IoKTsKLSAgICAgICAgaWYgKGZEVERWYWxpZGF0b3IgIT0gbnVsbCkgewotICAgICAgICAgICAgc2V0UHJvcGVydHkoRFREX1ZBTElEQVRPUiwgZkRURFZhbGlkYXRvcik7Ci0gICAgICAgICAgICBhZGRDb21wb25lbnQoZkRURFZhbGlkYXRvcik7Ci0gICAgICAgIH0KLQotICAgICAgICBmTmFtZXNwYWNlQmluZGVyID0gY3JlYXRlTmFtZXNwYWNlQmluZGVyKCk7Ci0gICAgICAgIGlmIChmTmFtZXNwYWNlQmluZGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIHNldFByb3BlcnR5KE5BTUVTUEFDRV9CSU5ERVIsIGZOYW1lc3BhY2VCaW5kZXIpOwotICAgICAgICAgICAgYWRkQ29tcG9uZW50KGZOYW1lc3BhY2VCaW5kZXIpOwotICAgICAgICB9Ci0KLSAgICAgICAgZkRhdGF0eXBlVmFsaWRhdG9yRmFjdG9yeSA9IGNyZWF0ZURhdGF0eXBlVmFsaWRhdG9yRmFjdG9yeSgpOwotICAgICAgICBpZiAoZkRhdGF0eXBlVmFsaWRhdG9yRmFjdG9yeSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBzZXRQcm9wZXJ0eShEQVRBVFlQRV9WQUxJREFUT1JfRkFDVE9SWSwKLSAgICAgICAgICAgICAgICAgICAgICAgIGZEYXRhdHlwZVZhbGlkYXRvckZhY3RvcnkpOwotICAgICAgICB9Ci0gICAgICAgIGZWYWxpZGF0aW9uTWFuYWdlciA9IGNyZWF0ZVZhbGlkYXRpb25NYW5hZ2VyKCk7Ci0KLSAgICAgICAgaWYgKGZWYWxpZGF0aW9uTWFuYWdlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBzZXRQcm9wZXJ0eSAoVkFMSURBVElPTl9NQU5BR0VSLCBmVmFsaWRhdGlvbk1hbmFnZXIpOwotICAgICAgICB9Ci0gICAgICAgIC8vIGFkZCBtZXNzYWdlIGZvcm1hdHRlcnMKLSAgICAgICAgaWYgKGZFcnJvclJlcG9ydGVyLmdldE1lc3NhZ2VGb3JtYXR0ZXIoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOKSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBYTUxNZXNzYWdlRm9ybWF0dGVyIHhtZnQgPSBuZXcgWE1MTWVzc2FnZUZvcm1hdHRlcigpOwotICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucHV0TWVzc2FnZUZvcm1hdHRlcihYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sIHhtZnQpOwotICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucHV0TWVzc2FnZUZvcm1hdHRlcihYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTE5TX0RPTUFJTiwgeG1mdCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBzZXQgbG9jYWxlCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBzZXRMb2NhbGUoTG9jYWxlLmdldERlZmF1bHQoKSk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKFhOSUV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAvLyBkbyBub3RoaW5nCi0gICAgICAgICAgICAvLyBSRVZJU0lUOiBXaGF0IGlzIHRoZSByaWdodCB0aGluZyB0byBkbz8gLUFjCi0gICAgICAgIH0KLQotICAgICAgICBzZXRQcm9wZXJ0eShYTUxfU0VDVVJJVFlfUFJPUEVSVFlfTUFOQUdFUiwgbmV3IFhNTFNlY3VyaXR5UHJvcGVydHlNYW5hZ2VyKCkpOwotICAgIH0gLy8gPGluaXQ+KFN5bWJvbFRhYmxlLFhNTEdyYW1tYXJQb29sKQotCi0gICAgLy8KLSAgICAvLyBQdWJsaWMgbWV0aG9kcwotICAgIC8vCi0KLSAgICBwdWJsaWMgUHJvcGVydHlTdGF0ZSBnZXRQcm9wZXJ0eVN0YXRlKFN0cmluZyBwcm9wZXJ0eUlkKQotICAgICAgICB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChMT0NBTEUuZXF1YWxzKHByb3BlcnR5SWQpKSB7Ci0gICAgICAgICAgICByZXR1cm4gUHJvcGVydHlTdGF0ZS5pcyhnZXRMb2NhbGUoKSk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHN1cGVyLmdldFByb3BlcnR5U3RhdGUocHJvcGVydHlJZCk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0UHJvcGVydHkoU3RyaW5nIHByb3BlcnR5SWQsIE9iamVjdCB2YWx1ZSkKLSAgICAgICAgdGhyb3dzIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gewotICAgICAgICBpZiAoTE9DQUxFLmVxdWFscyhwcm9wZXJ0eUlkKSkgewotICAgICAgICAgICAgc2V0TG9jYWxlKChMb2NhbGUpIHZhbHVlKTsKLSAgICAgICAgfQotICAgICAgICBzdXBlci5zZXRQcm9wZXJ0eShwcm9wZXJ0eUlkLCB2YWx1ZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSBsb2NhbGUgdG8gdXNlIGZvciBtZXNzYWdlcy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBsb2NhbGUgVGhlIGxvY2FsZSBvYmplY3QgdG8gdXNlIGZvciBsb2NhbGl6YXRpb24gb2YgbWVzc2FnZXMuCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIFhOSUV4Y2VwdGlvbiBUaHJvd24gaWYgdGhlIHBhcnNlciBkb2VzIG5vdCBzdXBwb3J0IHRoZQotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIHNwZWNpZmllZCBsb2NhbGUuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0TG9jYWxlKExvY2FsZSBsb2NhbGUpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBzdXBlci5zZXRMb2NhbGUobG9jYWxlKTsKLSAgICAgICAgZkVycm9yUmVwb3J0ZXIuc2V0TG9jYWxlKGxvY2FsZSk7Ci0gICAgfSAvLyBzZXRMb2NhbGUoTG9jYWxlKQotCi0gICAgLy8KLSAgICAvLyBYTUxQdWxsUGFyc2VyQ29uZmlndXJhdGlvbiBtZXRob2RzCi0gICAgLy8KLQotICAgIC8vIHBhcnNpbmcKLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIGlucHV0IHNvdXJjZSBmb3IgdGhlIGRvY3VtZW50IHRvIHBhcnNlLgotICAgICAqCi0gICAgICogQHBhcmFtIGlucHV0U291cmNlIFRoZSBkb2N1bWVudCdzIGlucHV0IHNvdXJjZS4KLSAgICAgKgotICAgICAqIEBleGNlcHRpb24gWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBUaHJvd24gaWYgdGhlcmUgaXMgYQotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgY29uZmlndXJhdGlvbiBlcnJvciB3aGVuIGluaXRpYWxpemluZyB0aGUKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgIHBhcnNlci4KLSAgICAgKiBAZXhjZXB0aW9uIElPRXhjZXB0aW9uIFRocm93biBvbiBJL08gZXJyb3IuCi0gICAgICoKLSAgICAgKiBAc2VlICNwYXJzZShib29sZWFuKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldElucHV0U291cmNlKFhNTElucHV0U291cmNlIGlucHV0U291cmNlKQotICAgICAgICB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewotCi0gICAgICAgIC8vIFJFVklTSVQ6IHRoaXMgbWV0aG9kIHVzZWQgdG8gcmVzZXQgYWxsIHRoZSBjb21wb25lbnRzIGFuZAotICAgICAgICAvLyAgICAgICAgICBjb25zdHJ1Y3QgdGhlIHBpcGVsaW5lLiBOb3cgcmVzZXQoKSBpcyBjYWxsZWQKLSAgICAgICAgLy8gICAgICAgICAgaW4gcGFyc2UgKGJvb2xlYW4pIGp1c3QgYmVmb3JlIHdlIHBhcnNlIHRoZSBkb2N1bWVudAotICAgICAgICAvLyAgICAgICAgICBTaG91bGQgdGhpcyBtZXRob2Qgc3RpbGwgdGhyb3cgZXhjZXB0aW9ucy4uPwotCi0gICAgICAgIGZJbnB1dFNvdXJjZSA9IGlucHV0U291cmNlOwotCi0gICAgfSAvLyBzZXRJbnB1dFNvdXJjZShYTUxJbnB1dFNvdXJjZSkKLQotICAgIC8qKgotICAgICAqIFBhcnNlcyB0aGUgZG9jdW1lbnQgaW4gYSBwdWxsIHBhcnNpbmcgZmFzaGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjb21wbGV0ZSBUcnVlIGlmIHRoZSBwdWxsIHBhcnNlciBzaG91bGQgcGFyc2UgdGhlCi0gICAgICogICAgICAgICAgICAgICAgIHJlbWFpbmluZyBkb2N1bWVudCBjb21wbGV0ZWx5LgotICAgICAqCi0gICAgICogQHJldHVybiBUcnVlIGlmIHRoZXJlIGlzIG1vcmUgZG9jdW1lbnQgdG8gcGFyc2UuCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIFhOSUV4Y2VwdGlvbiBBbnkgWE5JIGV4Y2VwdGlvbiwgcG9zc2libHkgd3JhcHBpbmcKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICAgKiBAZXhjZXB0aW9uIElPRXhjZXB0aW9uICBBbiBJTyBleGNlcHRpb24gZnJvbSB0aGUgcGFyc2VyLCBwb3NzaWJseQotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIGZyb20gYSBieXRlIHN0cmVhbSBvciBjaGFyYWN0ZXIgc3RyZWFtCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgc3VwcGxpZWQgYnkgdGhlIHBhcnNlci4KLSAgICAgKgotICAgICAqIEBzZWUgI3NldElucHV0U291cmNlCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gcGFyc2UoYm9vbGVhbiBjb21wbGV0ZSkgdGhyb3dzIFhOSUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewotICAgICAgICAvLwotICAgICAgICAvLyByZXNldCBhbmQgY29uZmlndXJlIHBpcGVsaW5lIGFuZCBzZXQgSW5wdXRTb3VyY2UuCi0gICAgICAgIGlmIChmSW5wdXRTb3VyY2UgIT1udWxsKSB7Ci0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIC8vIHJlc2V0cyBhbmQgc2V0cyB0aGUgcGlwZWxpbmUuCi0gICAgICAgICAgICAgICAgcmVzZXQoKTsKLSAgICAgICAgICAgICAgICBmU2Nhbm5lci5zZXRJbnB1dFNvdXJjZShmSW5wdXRTb3VyY2UpOwotICAgICAgICAgICAgICAgIGZJbnB1dFNvdXJjZSA9IG51bGw7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXRjaCAoWE5JRXhjZXB0aW9uIGV4KSB7Ci0gICAgICAgICAgICAgICAgaWYgKFBSSU5UX0VYQ0VQVElPTl9TVEFDS19UUkFDRSkKLSAgICAgICAgICAgICAgICAgICAgZXgucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgICAgICAgICAgdGhyb3cgZXg7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKLSAgICAgICAgICAgICAgICBpZiAoUFJJTlRfRVhDRVBUSU9OX1NUQUNLX1RSQUNFKQotICAgICAgICAgICAgICAgICAgICBleC5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgICAgICAgICAgICB0aHJvdyBleDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIGV4KSB7Ci0gICAgICAgICAgICAgICAgaWYgKFBSSU5UX0VYQ0VQVElPTl9TVEFDS19UUkFDRSkKLSAgICAgICAgICAgICAgICAgICAgZXgucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgICAgICAgICAgdGhyb3cgZXg7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7Ci0gICAgICAgICAgICAgICAgaWYgKFBSSU5UX0VYQ0VQVElPTl9TVEFDS19UUkFDRSkKLSAgICAgICAgICAgICAgICAgICAgZXgucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFhOSUV4Y2VwdGlvbihleCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICB0cnkgewotICAgICAgICAgICAgcmV0dXJuIGZTY2FubmVyLnNjYW5Eb2N1bWVudChjb21wbGV0ZSk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKFhOSUV4Y2VwdGlvbiBleCkgewotICAgICAgICAgICAgaWYgKFBSSU5UX0VYQ0VQVElPTl9TVEFDS19UUkFDRSkKLSAgICAgICAgICAgICAgICBleC5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgICAgICAgIHRocm93IGV4OwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgewotICAgICAgICAgICAgaWYgKFBSSU5UX0VYQ0VQVElPTl9TVEFDS19UUkFDRSkKLSAgICAgICAgICAgICAgICBleC5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgICAgICAgIHRocm93IGV4OwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIGV4KSB7Ci0gICAgICAgICAgICBpZiAoUFJJTlRfRVhDRVBUSU9OX1NUQUNLX1RSQUNFKQotICAgICAgICAgICAgICAgIGV4LnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgICAgICAgdGhyb3cgZXg7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkgewotICAgICAgICAgICAgaWYgKFBSSU5UX0VYQ0VQVElPTl9TVEFDS19UUkFDRSkKLSAgICAgICAgICAgICAgICBleC5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgICAgICAgIHRocm93IG5ldyBYTklFeGNlcHRpb24oZXgpOwotICAgICAgICB9Ci0KLSAgICB9IC8vIHBhcnNlKGJvb2xlYW4pOmJvb2xlYW4KLQotICAgIC8qKgotICAgICAqIElmIHRoZSBhcHBsaWNhdGlvbiBkZWNpZGVzIHRvIHRlcm1pbmF0ZSBwYXJzaW5nIGJlZm9yZSB0aGUgeG1sIGRvY3VtZW50Ci0gICAgICogaXMgZnVsbHkgcGFyc2VkLCB0aGUgYXBwbGljYXRpb24gc2hvdWxkIGNhbGwgdGhpcyBtZXRob2QgdG8gZnJlZSBhbnkKLSAgICAgKiByZXNvdXJjZSBhbGxvY2F0ZWQgZHVyaW5nIHBhcnNpbmcuIEZvciBleGFtcGxlLCBjbG9zZSBhbGwgb3BlbmVkIHN0cmVhbXMuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY2xlYW51cCgpIHsKLSAgICAgICAgZkVudGl0eU1hbmFnZXIuY2xvc2VSZWFkZXJzKCk7Ci0gICAgfQotCi0gICAgLy8KLSAgICAvLyBYTUxQYXJzZXJDb25maWd1cmF0aW9uIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogUGFyc2VzIHRoZSBzcGVjaWZpZWQgaW5wdXQgc291cmNlLgotICAgICAqCi0gICAgICogQHBhcmFtIHNvdXJjZSBUaGUgaW5wdXQgc291cmNlLgotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBYTklFeGNlcHRpb24gVGhyb3dzIGV4Y2VwdGlvbiBvbiBYTkkgZXJyb3IuCi0gICAgICogQGV4Y2VwdGlvbiBqYXZhLmlvLklPRXhjZXB0aW9uIFRocm93cyBleGNlcHRpb24gb24gaS9vIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHBhcnNlKFhNTElucHV0U291cmNlIHNvdXJjZSkgdGhyb3dzIFhOSUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewotCi0gICAgICAgIGlmIChmUGFyc2VJblByb2dyZXNzKSB7Ci0gICAgICAgICAgICAvLyBSRVZJU0lUIC0gbmVlZCB0byBhZGQgbmV3IGVycm9yIG1lc3NhZ2UKLSAgICAgICAgICAgIHRocm93IG5ldyBYTklFeGNlcHRpb24oIkZXSzAwNSBwYXJzZSBtYXkgbm90IGJlIGNhbGxlZCB3aGlsZSBwYXJzaW5nLiIpOwotICAgICAgICB9Ci0gICAgICAgIGZQYXJzZUluUHJvZ3Jlc3MgPSB0cnVlOwotCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBzZXRJbnB1dFNvdXJjZShzb3VyY2UpOwotICAgICAgICAgICAgcGFyc2UodHJ1ZSk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKFhOSUV4Y2VwdGlvbiBleCkgewotICAgICAgICAgICAgaWYgKFBSSU5UX0VYQ0VQVElPTl9TVEFDS19UUkFDRSkKLSAgICAgICAgICAgICAgICBleC5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgICAgICAgIHRocm93IGV4OwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgewotICAgICAgICAgICAgaWYgKFBSSU5UX0VYQ0VQVElPTl9TVEFDS19UUkFDRSkKLSAgICAgICAgICAgICAgICBleC5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgICAgICAgIHRocm93IGV4OwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIGV4KSB7Ci0gICAgICAgICAgICBpZiAoUFJJTlRfRVhDRVBUSU9OX1NUQUNLX1RSQUNFKQotICAgICAgICAgICAgICAgIGV4LnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgICAgICAgdGhyb3cgZXg7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkgewotICAgICAgICAgICAgaWYgKFBSSU5UX0VYQ0VQVElPTl9TVEFDS19UUkFDRSkKLSAgICAgICAgICAgICAgICBleC5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgICAgICAgIHRocm93IG5ldyBYTklFeGNlcHRpb24oZXgpOwotICAgICAgICB9Ci0gICAgICAgIGZpbmFsbHkgewotICAgICAgICAgICAgZlBhcnNlSW5Qcm9ncmVzcyA9IGZhbHNlOwotICAgICAgICAgICAgLy8gY2xvc2UgYWxsIHN0cmVhbXMgb3BlbmVkIGJ5IHhlcmNlcwotICAgICAgICAgICAgdGhpcy5jbGVhbnVwKCk7Ci0gICAgICAgIH0KLQotICAgIH0gLy8gcGFyc2UoSW5wdXRTb3VyY2UpCi0KLSAgICAvLwotICAgIC8vIFByb3RlY3RlZCBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFJlc2V0IGFsbCBjb21wb25lbnRzIGJlZm9yZSBwYXJzaW5nLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGlmIGFuIGVycm9yIG9jY3VycyBkdXJpbmcgaW5pdGlhbGl6YXRpb24uCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgcmVzZXQoKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLQotICAgICAgICBpZiAoZlZhbGlkYXRpb25NYW5hZ2VyICE9IG51bGwpCi0gICAgICAgICAgICBmVmFsaWRhdGlvbk1hbmFnZXIucmVzZXQoKTsKLSAgICAgICAgLy8gY29uZmlndXJlIHRoZSBwaXBlbGluZSBhbmQgaW5pdGlhbGl6ZSB0aGUgY29tcG9uZW50cwotICAgICAgICBjb25maWd1cmVQaXBlbGluZSgpOwotICAgICAgICBzdXBlci5yZXNldCgpOwotICAgIH0gLy8gcmVzZXQoKQotCi0gICAgLyoqIENvbmZpZ3VyZXMgdGhlIHBpcGVsaW5lLiAqLwotICAgICAgICBwcm90ZWN0ZWQgdm9pZCBjb25maWd1cmVQaXBlbGluZSgpIHsKLQotICAgICAgICAgICAgICAgIC8vIFJFVklTSVQ6IFRoaXMgc2hvdWxkIGJlIGJldHRlciBkZXNpZ25lZC4gSW4gb3RoZXIgd29yZHMsIHdlCi0gICAgICAgICAgICAgICAgLy8gICAgICAgICAgbmVlZCB0byBmaWd1cmUgb3V0IHdoYXQgaXMgdGhlIGJlc3Qgd2F5IGZvciBwZW9wbGUgdG8KLSAgICAgICAgICAgICAgICAvLyAgICAgICAgICByZS11c2UgKm1vc3QqIG9mIHRoZSBzdGFuZGFyZCBjb25maWd1cmF0aW9uIGJ1dCBkbwotICAgICAgICAgICAgICAgIC8vICAgICAgICAgIHRoaW5ncyBjb21tb24gdGhpbmdzIHN1Y2ggYXMgcmVtb3ZlIGEgY29tcG9uZW50IChlLmcuCi0gICAgICAgICAgICAgICAgLy8gICAgICAgICAgdGhlIHZhbGlkYXRvciksIGluc2VydCBhIG5ldyBjb21wb25lbnQgKGUuZy4gWEluY2x1ZGUpLAotICAgICAgICAgICAgICAgIC8vICAgICAgICAgIGV0Yy4uLiAtQWMKLQotICAgICAgICAgICAgICAgIC8vIHNldHVwIGRvY3VtZW50IHBpcGVsaW5lCi0gICAgICAgICAgICAgICAgaWYgKGZEVERWYWxpZGF0b3IgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgZlNjYW5uZXIuc2V0RG9jdW1lbnRIYW5kbGVyKGZEVERWYWxpZGF0b3IpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZGZWF0dXJlcy5nZXQoTkFNRVNQQUNFUykgPT0gQm9vbGVhbi5UUlVFKSB7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZmlsdGVycwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmRFREVmFsaWRhdG9yLnNldERvY3VtZW50SGFuZGxlcihmTmFtZXNwYWNlQmluZGVyKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkRURFZhbGlkYXRvci5zZXREb2N1bWVudFNvdXJjZShmU2Nhbm5lcik7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZOYW1lc3BhY2VCaW5kZXIuc2V0RG9jdW1lbnRIYW5kbGVyKGZEb2N1bWVudEhhbmRsZXIpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmTmFtZXNwYWNlQmluZGVyLnNldERvY3VtZW50U291cmNlKGZEVERWYWxpZGF0b3IpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmTGFzdENvbXBvbmVudCA9IGZOYW1lc3BhY2VCaW5kZXI7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkRURFZhbGlkYXRvci5zZXREb2N1bWVudEhhbmRsZXIoZkRvY3VtZW50SGFuZGxlcik7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZEVERWYWxpZGF0b3Iuc2V0RG9jdW1lbnRTb3VyY2UoZlNjYW5uZXIpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmTGFzdENvbXBvbmVudCA9IGZEVERWYWxpZGF0b3I7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZGZWF0dXJlcy5nZXQoTkFNRVNQQUNFUykgPT0gQm9vbGVhbi5UUlVFKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZTY2FubmVyLnNldERvY3VtZW50SGFuZGxlcihmTmFtZXNwYWNlQmluZGVyKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZk5hbWVzcGFjZUJpbmRlci5zZXREb2N1bWVudEhhbmRsZXIoZkRvY3VtZW50SGFuZGxlcik7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZOYW1lc3BhY2VCaW5kZXIuc2V0RG9jdW1lbnRTb3VyY2UoZlNjYW5uZXIpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmTGFzdENvbXBvbmVudCA9IGZOYW1lc3BhY2VCaW5kZXI7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZlNjYW5uZXIuc2V0RG9jdW1lbnRIYW5kbGVyKGZEb2N1bWVudEhhbmRsZXIpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmTGFzdENvbXBvbmVudCA9IGZTY2FubmVyOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICBjb25maWd1cmVEVERQaXBlbGluZSgpOwotICAgICAgICB9IC8vIGNvbmZpZ3VyZVBpcGVsaW5lKCkKLQotICAgIHByb3RlY3RlZCB2b2lkIGNvbmZpZ3VyZURURFBpcGVsaW5lICgpewotCi0gICAgICAgIC8vIHNldHVwIGR0ZCBwaXBlbGluZQotICAgICAgICBpZiAoZkRURFNjYW5uZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZlByb3BlcnRpZXMucHV0KERURF9TQ0FOTkVSLCBmRFREU2Nhbm5lcik7Ci0gICAgICAgICAgICBpZiAoZkRURFByb2Nlc3NvciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZlByb3BlcnRpZXMucHV0KERURF9QUk9DRVNTT1IsIGZEVERQcm9jZXNzb3IpOwotICAgICAgICAgICAgICAgIGZEVERTY2FubmVyLnNldERUREhhbmRsZXIoZkRURFByb2Nlc3Nvcik7Ci0gICAgICAgICAgICAgICAgZkRURFByb2Nlc3Nvci5zZXREVERTb3VyY2UoZkRURFNjYW5uZXIpOwotICAgICAgICAgICAgICAgIGZEVERQcm9jZXNzb3Iuc2V0RFRESGFuZGxlcihmRFRESGFuZGxlcik7Ci0gICAgICAgICAgICAgICAgaWYgKGZEVERIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgZkRUREhhbmRsZXIuc2V0RFREU291cmNlKGZEVERQcm9jZXNzb3IpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIGZEVERTY2FubmVyLnNldERURENvbnRlbnRNb2RlbEhhbmRsZXIoZkRURFByb2Nlc3Nvcik7Ci0gICAgICAgICAgICAgICAgZkRURFByb2Nlc3Nvci5zZXREVERDb250ZW50TW9kZWxTb3VyY2UoZkRURFNjYW5uZXIpOwotICAgICAgICAgICAgICAgIGZEVERQcm9jZXNzb3Iuc2V0RFREQ29udGVudE1vZGVsSGFuZGxlcihmRFREQ29udGVudE1vZGVsSGFuZGxlcik7Ci0gICAgICAgICAgICAgICAgaWYgKGZEVERDb250ZW50TW9kZWxIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgZkRURENvbnRlbnRNb2RlbEhhbmRsZXIuc2V0RFREQ29udGVudE1vZGVsU291cmNlKGZEVERQcm9jZXNzb3IpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIGZEVERTY2FubmVyLnNldERUREhhbmRsZXIoZkRUREhhbmRsZXIpOwotICAgICAgICAgICAgICAgIGlmIChmRFRESGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZEVERIYW5kbGVyLnNldERURFNvdXJjZShmRFREU2Nhbm5lcik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGZEVERTY2FubmVyLnNldERURENvbnRlbnRNb2RlbEhhbmRsZXIoZkRURENvbnRlbnRNb2RlbEhhbmRsZXIpOwotICAgICAgICAgICAgICAgIGlmIChmRFREQ29udGVudE1vZGVsSGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZEVERDb250ZW50TW9kZWxIYW5kbGVyLnNldERURENvbnRlbnRNb2RlbFNvdXJjZShmRFREU2Nhbm5lcik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLQotICAgIH0KLQotICAgIC8vIGZlYXR1cmVzIGFuZCBwcm9wZXJ0aWVzCi0KLSAgICAvKioKLSAgICAgKiBDaGVjayBhIGZlYXR1cmUuIElmIGZlYXR1cmUgaXMga25vdyBhbmQgc3VwcG9ydGVkLCB0aGlzIG1ldGhvZCBzaW1wbHkKLSAgICAgKiByZXR1cm5zLiBPdGhlcndpc2UsIHRoZSBhcHByb3ByaWF0ZSBleGNlcHRpb24gaXMgdGhyb3duLgotICAgICAqCi0gICAgICogQHBhcmFtIGZlYXR1cmVJZCBUaGUgdW5pcXVlIGlkZW50aWZpZXIgKFVSSSkgb2YgdGhlIGZlYXR1cmUuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gVGhyb3duIGZvciBjb25maWd1cmF0aW9uIGVycm9yLgotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbiBnZW5lcmFsLCBjb21wb25lbnRzIHNob3VsZAotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbmx5IHRocm93IHRoaXMgZXhjZXB0aW9uIGlmCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0IGlzIDxzdHJvbmc+cmVhbGx5PC9zdHJvbmc+Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGEgY3JpdGljYWwgZXJyb3IuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIEZlYXR1cmVTdGF0ZSBjaGVja0ZlYXR1cmUoU3RyaW5nIGZlYXR1cmVJZCkKLSAgICAgICAgdGhyb3dzIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gewotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIFhlcmNlcyBGZWF0dXJlcwotICAgICAgICAvLwotCi0gICAgICAgIGlmIChmZWF0dXJlSWQuc3RhcnRzV2l0aChDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYKSkgewotICAgICAgICAgICAgZmluYWwgaW50IHN1ZmZpeExlbmd0aCA9IGZlYXR1cmVJZC5sZW5ndGgoKSAtIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVgubGVuZ3RoKCk7Ci0KLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAvLyBodHRwOi8vYXBhY2hlLm9yZy94bWwvZmVhdHVyZXMvdmFsaWRhdGlvbi9keW5hbWljCi0gICAgICAgICAgICAvLyAgIEFsbG93cyB0aGUgcGFyc2VyIHRvIHZhbGlkYXRlIGEgZG9jdW1lbnQgb25seSB3aGVuIGl0Ci0gICAgICAgICAgICAvLyAgIGNvbnRhaW5zIGEgZ3JhbW1hci4gVmFsaWRhdGlvbiBpcyB0dXJuZWQgb24vb2ZmIGJhc2VkCi0gICAgICAgICAgICAvLyAgIG9uIGVhY2ggZG9jdW1lbnQgaW5zdGFuY2UsIGF1dG9tYXRpY2FsbHkuCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgaWYgKHN1ZmZpeExlbmd0aCA9PSBDb25zdGFudHMuRFlOQU1JQ19WQUxJREFUSU9OX0ZFQVRVUkUubGVuZ3RoKCkgJiYKLSAgICAgICAgICAgICAgICBmZWF0dXJlSWQuZW5kc1dpdGgoQ29uc3RhbnRzLkRZTkFNSUNfVkFMSURBVElPTl9GRUFUVVJFKSkgewotICAgICAgICAgICAgICAgIHJldHVybiBGZWF0dXJlU3RhdGUuUkVDT0dOSVpFRDsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIC8vIGh0dHA6Ly9hcGFjaGUub3JnL3htbC9mZWF0dXJlcy92YWxpZGF0aW9uL2RlZmF1bHQtYXR0cmlidXRlLXZhbHVlcwotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIGlmIChzdWZmaXhMZW5ndGggPT0gQ29uc3RhbnRzLkRFRkFVTFRfQVRUUklCVVRFX1ZBTFVFU19GRUFUVVJFLmxlbmd0aCgpICYmCi0gICAgICAgICAgICAgICAgZmVhdHVyZUlkLmVuZHNXaXRoKENvbnN0YW50cy5ERUZBVUxUX0FUVFJJQlVURV9WQUxVRVNfRkVBVFVSRSkpIHsKLSAgICAgICAgICAgICAgICAvLyBSRVZJU0lUCi0gICAgICAgICAgICAgICAgcmV0dXJuIEZlYXR1cmVTdGF0ZS5OT1RfU1VQUE9SVEVEOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIC8vIGh0dHA6Ly9hcGFjaGUub3JnL3htbC9mZWF0dXJlcy92YWxpZGF0aW9uL2RlZmF1bHQtYXR0cmlidXRlLXZhbHVlcwotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIGlmIChzdWZmaXhMZW5ndGggPT0gQ29uc3RhbnRzLlZBTElEQVRFX0NPTlRFTlRfTU9ERUxTX0ZFQVRVUkUubGVuZ3RoKCkgJiYKLSAgICAgICAgICAgICAgICBmZWF0dXJlSWQuZW5kc1dpdGgoQ29uc3RhbnRzLlZBTElEQVRFX0NPTlRFTlRfTU9ERUxTX0ZFQVRVUkUpKSB7Ci0gICAgICAgICAgICAgICAgLy8gUkVWSVNJVAotICAgICAgICAgICAgICAgIHJldHVybiBGZWF0dXJlU3RhdGUuTk9UX1NVUFBPUlRFRDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAvLyBodHRwOi8vYXBhY2hlLm9yZy94bWwvZmVhdHVyZXMvdmFsaWRhdGlvbi9ub252YWxpZGF0aW5nL2xvYWQtZHRkLWdyYW1tYXIKLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICBpZiAoc3VmZml4TGVuZ3RoID09IENvbnN0YW50cy5MT0FEX0RURF9HUkFNTUFSX0ZFQVRVUkUubGVuZ3RoKCkgJiYKLSAgICAgICAgICAgICAgICBmZWF0dXJlSWQuZW5kc1dpdGgoQ29uc3RhbnRzLkxPQURfRFREX0dSQU1NQVJfRkVBVFVSRSkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gRmVhdHVyZVN0YXRlLlJFQ09HTklaRUQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLwotICAgICAgICAgICAgLy8gaHR0cDovL2FwYWNoZS5vcmcveG1sL2ZlYXR1cmVzL3ZhbGlkYXRpb24vbm9udmFsaWRhdGluZy9sb2FkLWV4dGVybmFsLWR0ZAotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIGlmIChzdWZmaXhMZW5ndGggPT0gQ29uc3RhbnRzLkxPQURfRVhURVJOQUxfRFREX0ZFQVRVUkUubGVuZ3RoKCkgJiYKLSAgICAgICAgICAgICAgICBmZWF0dXJlSWQuZW5kc1dpdGgoQ29uc3RhbnRzLkxPQURfRVhURVJOQUxfRFREX0ZFQVRVUkUpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIEZlYXR1cmVTdGF0ZS5SRUNPR05JWkVEOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgLy8gaHR0cDovL2FwYWNoZS5vcmcveG1sL2ZlYXR1cmVzL3ZhbGlkYXRpb24vZGVmYXVsdC1hdHRyaWJ1dGUtdmFsdWVzCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgaWYgKHN1ZmZpeExlbmd0aCA9PSBDb25zdGFudHMuVkFMSURBVEVfREFUQVRZUEVTX0ZFQVRVUkUubGVuZ3RoKCkgJiYKLSAgICAgICAgICAgICAgICBmZWF0dXJlSWQuZW5kc1dpdGgoQ29uc3RhbnRzLlZBTElEQVRFX0RBVEFUWVBFU19GRUFUVVJFKSkgewotICAgICAgICAgICAgICAgIHJldHVybiBGZWF0dXJlU3RhdGUuTk9UX1NVUFBPUlRFRDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIE5vdCByZWNvZ25pemVkCi0gICAgICAgIC8vCi0KLSAgICAgICAgcmV0dXJuIHN1cGVyLmNoZWNrRmVhdHVyZShmZWF0dXJlSWQpOwotCi0gICAgfSAvLyBjaGVja0ZlYXR1cmUoU3RyaW5nKQotCi0gICAgLyoqCi0gICAgICogQ2hlY2sgYSBwcm9wZXJ0eS4gSWYgdGhlIHByb3BlcnR5IGlzIGtub3cgYW5kIHN1cHBvcnRlZCwgdGhpcyBtZXRob2QKLSAgICAgKiBzaW1wbHkgcmV0dXJucy4gT3RoZXJ3aXNlLCB0aGUgYXBwcm9wcmlhdGUgZXhjZXB0aW9uIGlzIHRocm93bi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBwcm9wZXJ0eUlkIFRoZSB1bmlxdWUgaWRlbnRpZmllciAoVVJJKSBvZiB0aGUgcHJvcGVydHkKLSAgICAgKiAgICAgICAgICAgICAgICAgICBiZWluZyBzZXQuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gVGhyb3duIGZvciBjb25maWd1cmF0aW9uIGVycm9yLgotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbiBnZW5lcmFsLCBjb21wb25lbnRzIHNob3VsZAotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbmx5IHRocm93IHRoaXMgZXhjZXB0aW9uIGlmCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0IGlzIDxzdHJvbmc+cmVhbGx5PC9zdHJvbmc+Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGEgY3JpdGljYWwgZXJyb3IuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIFByb3BlcnR5U3RhdGUgY2hlY2tQcm9wZXJ0eShTdHJpbmcgcHJvcGVydHlJZCkKLSAgICAgICAgdGhyb3dzIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gewotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIFhlcmNlcyBQcm9wZXJ0aWVzCi0gICAgICAgIC8vCi0KLSAgICAgICAgaWYgKHByb3BlcnR5SWQuc3RhcnRzV2l0aChDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCkpIHsKLSAgICAgICAgICAgIGZpbmFsIGludCBzdWZmaXhMZW5ndGggPSBwcm9wZXJ0eUlkLmxlbmd0aCgpIC0gQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVgubGVuZ3RoKCk7Ci0KLSAgICAgICAgICAgIGlmIChzdWZmaXhMZW5ndGggPT0gQ29uc3RhbnRzLkRURF9TQ0FOTkVSX1BST1BFUlRZLmxlbmd0aCgpICYmCi0gICAgICAgICAgICAgICAgcHJvcGVydHlJZC5lbmRzV2l0aChDb25zdGFudHMuRFREX1NDQU5ORVJfUFJPUEVSVFkpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIFByb3BlcnR5U3RhdGUuUkVDT0dOSVpFRDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIE5vdCByZWNvZ25pemVkCi0gICAgICAgIC8vCi0KLSAgICAgICAgcmV0dXJuIHN1cGVyLmNoZWNrUHJvcGVydHkocHJvcGVydHlJZCk7Ci0KLSAgICB9IC8vIGNoZWNrUHJvcGVydHkoU3RyaW5nKQotCi0gICAgLy8gZmFjdG9yeSBtZXRob2RzCi0KLSAgICAvKiogQ3JlYXRlcyBhbiBlbnRpdHkgbWFuYWdlci4gKi8KLSAgICBwcm90ZWN0ZWQgWE1MRW50aXR5TWFuYWdlciBjcmVhdGVFbnRpdHlNYW5hZ2VyKCkgewotICAgICAgICByZXR1cm4gbmV3IFhNTEVudGl0eU1hbmFnZXIoKTsKLSAgICB9IC8vIGNyZWF0ZUVudGl0eU1hbmFnZXIoKTpYTUxFbnRpdHlNYW5hZ2VyCi0KLSAgICAvKiogQ3JlYXRlcyBhbiBlcnJvciByZXBvcnRlci4gKi8KLSAgICBwcm90ZWN0ZWQgWE1MRXJyb3JSZXBvcnRlciBjcmVhdGVFcnJvclJlcG9ydGVyKCkgewotICAgICAgICByZXR1cm4gbmV3IFhNTEVycm9yUmVwb3J0ZXIoKTsKLSAgICB9IC8vIGNyZWF0ZUVycm9yUmVwb3J0ZXIoKTpYTUxFcnJvclJlcG9ydGVyCi0KLSAgICAvKiogQ3JlYXRlIGEgZG9jdW1lbnQgc2Nhbm5lci4gKi8KLSAgICBwcm90ZWN0ZWQgWE1MRG9jdW1lbnRTY2FubmVyIGNyZWF0ZURvY3VtZW50U2Nhbm5lcigpIHsKLSAgICAgICAgcmV0dXJuIG5ldyBYTUxEb2N1bWVudFNjYW5uZXJJbXBsKCk7Ci0gICAgfSAvLyBjcmVhdGVEb2N1bWVudFNjYW5uZXIoKTpYTUxEb2N1bWVudFNjYW5uZXIKLQotICAgIC8qKiBDcmVhdGUgYSBEVEQgc2Nhbm5lci4gKi8KLSAgICBwcm90ZWN0ZWQgWE1MRFREU2Nhbm5lciBjcmVhdGVEVERTY2FubmVyKCkgewotICAgICAgICByZXR1cm4gbmV3IFhNTERURFNjYW5uZXJJbXBsKCk7Ci0gICAgfSAvLyBjcmVhdGVEVERTY2FubmVyKCk6WE1MRFREU2Nhbm5lcgotCi0gICAgLyoqIENyZWF0ZSBhIERURCBsb2FkZXIgLiAqLwotICAgIHByb3RlY3RlZCBYTUxEVERQcm9jZXNzb3IgY3JlYXRlRFREUHJvY2Vzc29yKCkgewotICAgICAgICByZXR1cm4gbmV3IFhNTERURFByb2Nlc3NvcigpOwotICAgIH0gLy8gY3JlYXRlRFREUHJvY2Vzc29yKCk6WE1MRFREUHJvY2Vzc29yCi0KLSAgICAvKiogQ3JlYXRlIGEgRFREIHZhbGlkYXRvci4gKi8KLSAgICBwcm90ZWN0ZWQgWE1MRFREVmFsaWRhdG9yIGNyZWF0ZURURFZhbGlkYXRvcigpIHsKLSAgICAgICAgcmV0dXJuIG5ldyBYTUxEVERWYWxpZGF0b3IoKTsKLSAgICB9IC8vIGNyZWF0ZURURFZhbGlkYXRvcigpOlhNTERURFZhbGlkYXRvcgotCi0gICAgLyoqIENyZWF0ZSBhIG5hbWVzcGFjZSBiaW5kZXIuICovCi0gICAgcHJvdGVjdGVkIFhNTE5hbWVzcGFjZUJpbmRlciBjcmVhdGVOYW1lc3BhY2VCaW5kZXIoKSB7Ci0gICAgICAgIHJldHVybiBuZXcgWE1MTmFtZXNwYWNlQmluZGVyKCk7Ci0gICAgfSAvLyBjcmVhdGVOYW1lc3BhY2VCaW5kZXIoKTpYTUxOYW1lc3BhY2VCaW5kZXIKLQotICAgIC8qKiBDcmVhdGUgYSBkYXRhdHlwZSB2YWxpZGF0b3IgZmFjdG9yeS4gKi8KLSAgICBwcm90ZWN0ZWQgRFRERFZGYWN0b3J5IGNyZWF0ZURhdGF0eXBlVmFsaWRhdG9yRmFjdG9yeSgpIHsKLSAgICAgICAgcmV0dXJuIERURERWRmFjdG9yeS5nZXRJbnN0YW5jZSgpOwotICAgIH0gLy8gY3JlYXRlRGF0YXR5cGVWYWxpZGF0b3JGYWN0b3J5KCk6RGF0YXR5cGVWYWxpZGF0b3JGYWN0b3J5Ci0gICAgcHJvdGVjdGVkIFZhbGlkYXRpb25NYW5hZ2VyIGNyZWF0ZVZhbGlkYXRpb25NYW5hZ2VyKCl7Ci0gICAgICAgIHJldHVybiBuZXcgVmFsaWRhdGlvbk1hbmFnZXIoKTsKLSAgICB9Ci0KLX0gLy8gY2xhc3MgRFREQ29uZmlndXJhdGlvbgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvcGFyc2Vycy9EVERQYXJzZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3BhcnNlcnMvRFREUGFyc2VyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDNjNzYyNGMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvcGFyc2Vycy9EVERQYXJzZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQ4MSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5wYXJzZXJzOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR0ZC5EVERHcmFtbWFyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5TeW1ib2xUYWJsZTsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLkF1Z21lbnRhdGlvbnM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MU3RyaW5nOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTERURENvbnRlbnRNb2RlbEhhbmRsZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MRFRESGFuZGxlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxMb2NhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhOSUV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MRFREU2Nhbm5lcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxSZXNvdXJjZUlkZW50aWZpZXI7Ci0KLS8qKgotICovCi1wdWJsaWMgYWJzdHJhY3QgY2xhc3MgRFREUGFyc2VyCi0gICAgZXh0ZW5kcyBYTUxHcmFtbWFyUGFyc2VyCi0gICAgaW1wbGVtZW50cyBYTUxEVERIYW5kbGVyLCBYTUxEVERDb250ZW50TW9kZWxIYW5kbGVyIHsKLQotICAgIC8vCi0gICAgLy8gRGF0YQotICAgIC8vCi0KLSAgICAvKiogZkRURFNjYW5uZXIgKi8KLSAgICBwcm90ZWN0ZWQgWE1MRFREU2Nhbm5lciBmRFREU2Nhbm5lcjsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc3ltYm9sVGFibGUKLSAgICAgKi8KLSAgICBwdWJsaWMgRFREUGFyc2VyKFN5bWJvbFRhYmxlIHN5bWJvbFRhYmxlKSB7Ci0gICAgICAgIHN1cGVyKHN5bWJvbFRhYmxlKTsKLSAgICB9Ci0KLSAgICAvLwotICAgIC8vIE1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogZ2V0RFRER3JhbW1hcgotICAgICAqCi0gICAgICogQHJldHVybiB0aGUgZ3JhbW1hciBjcmVhdGVkIGJ5IHRoaXMgcGFyc2VyCi0gICAgICovCi0gICAgcHVibGljIERUREdyYW1tYXIgZ2V0RFRER3JhbW1hcigpIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfSAvLyBnZXREVERHcmFtbWFyCi0KLSAgICAvLwotICAgIC8vIFhNTERUREhhbmRsZXIgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBub3RpZmllcyBvZiB0aGUgc3RhcnQgb2YgYW4gZW50aXR5LiBUaGUgRFREIGhhcyB0aGUKLSAgICAgKiBwc2V1ZG8tbmFtZSBvZiAiW2R0ZF0iIGFuZCBwYXJhbWV0ZXIgZW50aXR5IG5hbWVzIHN0YXJ0IHdpdGggJyUnLgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gU2luY2UgdGhlIERURCBpcyBhbiBlbnRpdHksIHRoZSBoYW5kbGVyCi0gICAgICogd2lsbCBiZSBub3RpZmllZCBvZiB0aGUgc3RhcnQgb2YgdGhlIERURCBlbnRpdHkgYnkgY2FsbGluZyB0aGUKLSAgICAgKiBzdGFydEVudGl0eSBtZXRob2Qgd2l0aCB0aGUgZW50aXR5IG5hbWUgIltkdGRdIiA8ZW0+YmVmb3JlPC9lbT4gY2FsbGluZwotICAgICAqIHRoZSBzdGFydERURCBtZXRob2QuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSAgICAgVGhlIG5hbWUgb2YgdGhlIGVudGl0eS4KLSAgICAgKiBAcGFyYW0gcHVibGljSWQgVGhlIHB1YmxpYyBpZGVudGlmaWVyIG9mIHRoZSBlbnRpdHkgaWYgdGhlIGVudGl0eQotICAgICAqICAgICAgICAgICAgICAgICBpcyBleHRlcm5hbCwgbnVsbCBvdGhlcndpc2UuCi0gICAgICogQHBhcmFtIHN5c3RlbUlkIFRoZSBzeXN0ZW0gaWRlbnRpZmllciBvZiB0aGUgZW50aXR5IGlmIHRoZSBlbnRpdHkKLSAgICAgKiAgICAgICAgICAgICAgICAgaXMgZXh0ZXJuYWwsIG51bGwgb3RoZXJ3aXNlLgotICAgICAqIEBwYXJhbSBlbmNvZGluZyBUaGUgYXV0by1kZXRlY3RlZCBJQU5BIGVuY29kaW5nIG5hbWUgb2YgdGhlIGVudGl0eQotICAgICAqICAgICAgICAgICAgICAgICBzdHJlYW0uIFRoaXMgdmFsdWUgd2lsbCBiZSBudWxsIGluIHRob3NlIHNpdHVhdGlvbnMKLSAgICAgKiAgICAgICAgICAgICAgICAgd2hlcmUgdGhlIGVudGl0eSBlbmNvZGluZyBpcyBub3QgYXV0by1kZXRlY3RlZCAoZS5nLgotICAgICAqICAgICAgICAgICAgICAgICBpbnRlcm5hbCBwYXJhbWV0ZXIgZW50aXRpZXMpLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RW50aXR5KFN0cmluZyBuYW1lLCBTdHJpbmcgcHVibGljSWQsIFN0cmluZyBzeXN0ZW1JZCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgZW5jb2RpbmcpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgIH0KLQotICAgIC8qKgotICAgICAqIE5vdGlmaWVzIG9mIHRoZSBwcmVzZW5jZSBvZiBhIFRleHREZWNsIGxpbmUgaW4gYW4gZW50aXR5LiBJZiBwcmVzZW50LAotICAgICAqIHRoaXMgbWV0aG9kIHdpbGwgYmUgY2FsbGVkIGltbWVkaWF0ZWx5IGZvbGxvd2luZyB0aGUgc3RhcnRFbnRpdHkgY2FsbC4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoaXMgbWV0aG9kIGlzIG9ubHkgY2FsbGVkIGZvciBleHRlcm5hbAotICAgICAqIHBhcmFtZXRlciBlbnRpdGllcyByZWZlcmVuY2VkIGluIHRoZSBEVEQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdmVyc2lvbiAgVGhlIFhNTCB2ZXJzaW9uLCBvciBudWxsIGlmIG5vdCBzcGVjaWZpZWQuCi0gICAgICogQHBhcmFtIGVuY29kaW5nIFRoZSBJQU5BIGVuY29kaW5nIG5hbWUgb2YgdGhlIGVudGl0eS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0ZXh0RGVjbChTdHJpbmcgdmVyc2lvbiwgU3RyaW5nIGVuY29kaW5nKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgc3RhcnQgb2YgdGhlIERURC4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydERURChYTUxMb2NhdG9yIGxvY2F0b3IsIEF1Z21lbnRhdGlvbnMgYXVnbWVudGF0aW9ucykKLSAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBIGNvbW1lbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdGV4dCBUaGUgdGV4dCBpbiB0aGUgY29tbWVudC4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBhcHBsaWNhdGlvbiB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY29tbWVudChYTUxTdHJpbmcgdGV4dCwgQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICB9IC8vIGNvbW1lbnQKLQotICAgIC8qKgotICAgICAqIEEgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbi4gUHJvY2Vzc2luZyBpbnN0cnVjdGlvbnMgY29uc2lzdCBvZiBhCi0gICAgICogdGFyZ2V0IG5hbWUgYW5kLCBvcHRpb25hbGx5LCB0ZXh0IGRhdGEuIFRoZSBkYXRhIGlzIG9ubHkgbWVhbmluZ2Z1bAotICAgICAqIHRvIHRoZSBhcHBsaWNhdGlvbi4KLSAgICAgKiA8cD4KLSAgICAgKiBUeXBpY2FsbHksIGEgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbidzIGRhdGEgd2lsbCBjb250YWluIGEgc2VyaWVzCi0gICAgICogb2YgcHNldWRvLWF0dHJpYnV0ZXMuIFRoZXNlIHBzZXVkby1hdHRyaWJ1dGVzIGZvbGxvdyB0aGUgZm9ybSBvZgotICAgICAqIGVsZW1lbnQgYXR0cmlidXRlcyBidXQgYXJlIDxzdHJvbmc+bm90PC9zdHJvbmc+IHBhcnNlZCBvciBwcmVzZW50ZWQKLSAgICAgKiB0byB0aGUgYXBwbGljYXRpb24gYXMgYW55dGhpbmcgb3RoZXIgdGhhbiB0ZXh0LiBUaGUgYXBwbGljYXRpb24gaXMKLSAgICAgKiByZXNwb25zaWJsZSBmb3IgcGFyc2luZyB0aGUgZGF0YS4KLSAgICAgKgotICAgICAqIEBwYXJhbSB0YXJnZXQgVGhlIHRhcmdldC4KLSAgICAgKiBAcGFyYW0gZGF0YSAgIFRoZSBkYXRhIG9yIG51bGwgaWYgbm9uZSBzcGVjaWZpZWQuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcHJvY2Vzc2luZ0luc3RydWN0aW9uKFN0cmluZyB0YXJnZXQsIFhNTFN0cmluZyBkYXRhLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotICAgIH0gLy8gcHJvY2Vzc2luZ0luc3RydWN0aW9uCi0KLSAgICAvKioKLSAgICAgKiBUaGUgc3RhcnQgb2YgdGhlIGV4dGVybmFsIHN1YnNldC4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydEV4dGVybmFsU3Vic2V0KFhNTFJlc291cmNlSWRlbnRpZmllciBpZGVudGlmaWVyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKSAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgfSAvLyBzdGFydEV4dGVybmFsU3Vic2V0Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgZW5kIG9mIHRoZSBleHRlcm5hbCBzdWJzZXQuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kRXh0ZXJuYWxTdWJzZXQoQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICB9IC8vIGVuZEV4dGVybmFsU3Vic2V0Ci0KLSAgICAvKioKLSAgICAgKiBBbiBlbGVtZW50IGRlY2xhcmF0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgICAgICAgICBUaGUgbmFtZSBvZiB0aGUgZWxlbWVudC4KLSAgICAgKiBAcGFyYW0gY29udGVudE1vZGVsIFRoZSBlbGVtZW50IGNvbnRlbnQgbW9kZWwuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZWxlbWVudERlY2woU3RyaW5nIG5hbWUsIFN0cmluZyBjb250ZW50TW9kZWwsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKQotICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICB9IC8vIGVsZW1lbnREZWNsCi0KLSAgICAvKioKLSAgICAgKiBUaGUgc3RhcnQgb2YgYW4gYXR0cmlidXRlIGxpc3QuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZWxlbWVudE5hbWUgVGhlIG5hbWUgb2YgdGhlIGVsZW1lbnQgdGhhdCB0aGlzIGF0dHJpYnV0ZQotICAgICAqICAgICAgICAgICAgICAgICAgICBsaXN0IGlzIGFzc29jaWF0ZWQgd2l0aC4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydEF0dGxpc3QoU3RyaW5nIGVsZW1lbnROYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgIH0gLy8gc3RhcnRBdHRsaXN0Ci0KLSAgICAvKioKLSAgICAgKiBBbiBhdHRyaWJ1dGUgZGVjbGFyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZWxlbWVudE5hbWUgICBUaGUgbmFtZSBvZiB0aGUgZWxlbWVudCB0aGF0IHRoaXMgYXR0cmlidXRlCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgaXMgYXNzb2NpYXRlZCB3aXRoLgotICAgICAqIEBwYXJhbSBhdHRyaWJ1dGVOYW1lIFRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUuCi0gICAgICogQHBhcmFtIHR5cGUgICAgICAgICAgVGhlIGF0dHJpYnV0ZSB0eXBlLiBUaGlzIHZhbHVlIHdpbGwgYmUgb25lIG9mCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgdGhlIGZvbGxvd2luZzogIkNEQVRBIiwgIkVOVElUWSIsICJFTlRJVElFUyIsCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgIkVOVU1FUkFUSU9OIiwgIklEIiwgIklEUkVGIiwgIklEUkVGUyIsCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgIk5NVE9LRU4iLCAiTk1UT0tFTlMiLCBvciAiTk9UQVRJT04iLgotICAgICAqIEBwYXJhbSBlbnVtZXJhdGlvbiAgIElmIHRoZSB0eXBlIGhhcyB0aGUgdmFsdWUgIkVOVU1FUkFUSU9OIiwgdGhpcwotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGFycmF5IGhvbGRzIHRoZSBhbGxvd2VkIGF0dHJpYnV0ZSB2YWx1ZXM7Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgb3RoZXJ3aXNlLCB0aGlzIGFycmF5IGlzIG51bGwuCi0gICAgICogQHBhcmFtIGRlZmF1bHRUeXBlICAgVGhlIGF0dHJpYnV0ZSBkZWZhdWx0IHR5cGUuIFRoaXMgdmFsdWUgd2lsbCBiZQotICAgICAqICAgICAgICAgICAgICAgICAgICAgIG9uZSBvZiB0aGUgZm9sbG93aW5nOiAiI0ZJWEVEIiwgIiNJTVBMSUVEIiwKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAiI1JFUVVJUkVEIiwgb3IgbnVsbC4KLSAgICAgKiBAcGFyYW0gZGVmYXVsdFZhbHVlICBUaGUgYXR0cmlidXRlIGRlZmF1bHQgdmFsdWUsIG9yIG51bGwgaWYgbm8KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0IHZhbHVlIGlzIHNwZWNpZmllZC4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBhdHRyaWJ1dGVEZWNsKFN0cmluZyBlbGVtZW50TmFtZSwgU3RyaW5nIGF0dHJpYnV0ZU5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdHlwZSwgU3RyaW5nW10gZW51bWVyYXRpb24sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgZGVmYXVsdFR5cGUsIFhNTFN0cmluZyBkZWZhdWx0VmFsdWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxTdHJpbmcgbm9uTm9ybWFsaXplZERlZmF1bHRWYWx1ZSwgQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKQotICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICB9IC8vIGF0dHJpYnV0ZURlY2wKLQotICAgIC8qKgotICAgICAqIFRoZSBlbmQgb2YgYW4gYXR0cmlidXRlIGxpc3QuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kQXR0bGlzdChBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgIH0gLy8gZW5kQXR0bGlzdAotCi0gICAgLyoqCi0gICAgICogQW4gaW50ZXJuYWwgZW50aXR5IGRlY2xhcmF0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGVudGl0eS4gUGFyYW1ldGVyIGVudGl0eSBuYW1lcyBzdGFydCB3aXRoCi0gICAgICogICAgICAgICAgICAgJyUnLCB3aGVyZWFzIHRoZSBuYW1lIG9mIGEgZ2VuZXJhbCBlbnRpdHkgaXMganVzdCB0aGUKLSAgICAgKiAgICAgICAgICAgICBlbnRpdHkgbmFtZS4KLSAgICAgKiBAcGFyYW0gdGV4dCBUaGUgdmFsdWUgb2YgdGhlIGVudGl0eS4KLSAgICAgKiBAcGFyYW0gbm9uTm9ybWFsaXplZFRleHQgVGhlIG5vbi1ub3JtYWxpemVkIHZhbHVlIG9mIHRoZSBlbnRpdHkuIFRoaXMKLSAgICAgKiAgICAgICAgICAgICB2YWx1ZSBjb250YWlucyB0aGUgc2FtZSBzZXF1ZW5jZSBvZiBjaGFyYWN0ZXJzIHRoYXQgd2FzIGluCi0gICAgICogICAgICAgICAgICAgdGhlIGludGVybmFsIGVudGl0eSBkZWNsYXJhdGlvbiwgd2l0aG91dCBhbnkgZW50aXR5Ci0gICAgICogICAgICAgICAgICAgcmVmZXJlbmNlcyBleHBhbmRlZC4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBpbnRlcm5hbEVudGl0eURlY2woU3RyaW5nIG5hbWUsIFhNTFN0cmluZyB0ZXh0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxTdHJpbmcgbm9uTm9ybWFsaXplZFRleHQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF1Z21lbnRhdGlvbnMgYXVnbWVudGF0aW9ucykKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgfSAvLyBpbnRlcm5hbEVudGl0eURlY2woU3RyaW5nLFhNTFN0cmluZyxYTUxTdHJpbmcpCi0KLSAgICAvKioKLSAgICAgKiBBbiBleHRlcm5hbCBlbnRpdHkgZGVjbGFyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSAgICAgVGhlIG5hbWUgb2YgdGhlIGVudGl0eS4gUGFyYW1ldGVyIGVudGl0eSBuYW1lcyBzdGFydAotICAgICAqICAgICAgICAgICAgICAgICB3aXRoICclJywgd2hlcmVhcyB0aGUgbmFtZSBvZiBhIGdlbmVyYWwgZW50aXR5IGlzIGp1c3QKLSAgICAgKiAgICAgICAgICAgICAgICAgdGhlIGVudGl0eSBuYW1lLgotICAgICAqIEBwYXJhbSBpZGVudGlmaWVyICAgIEFuIG9iamVjdCBjb250YWluaW5nIGFsbCBsb2NhdGlvbiBpbmZvcm1hdGlvbgotICAgICAqICAgICAgICAgICAgICAgICAgICAgIHBlcnRpbmVudCB0byB0aGlzIGVudGl0eS4KLSAgICAgKiBAcGFyYW0gYXVnbWVudGF0aW9ucyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZXh0ZXJuYWxFbnRpdHlEZWNsKFN0cmluZyBuYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxSZXNvdXJjZUlkZW50aWZpZXIgaWRlbnRpZmllciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKQotICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICB9IC8vIGV4dGVybmFsRW50aXR5RGVjbAotCi0gICAgLyoqCi0gICAgICogQW4gdW5wYXJzZWQgZW50aXR5IGRlY2xhcmF0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgICAgIFRoZSBuYW1lIG9mIHRoZSBlbnRpdHkuCi0gICAgICogQHBhcmFtIGlkZW50aWZpZXIgICAgQW4gb2JqZWN0IGNvbnRhaW5pbmcgYWxsIGxvY2F0aW9uIGluZm9ybWF0aW9uCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgcGVydGluZW50IHRvIHRoaXMgZW50aXR5LgotICAgICAqIEBwYXJhbSBub3RhdGlvbiBUaGUgbmFtZSBvZiB0aGUgbm90YXRpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYXVnbWVudGF0aW9ucyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdW5wYXJzZWRFbnRpdHlEZWNsKFN0cmluZyBuYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxSZXNvdXJjZUlkZW50aWZpZXIgaWRlbnRpZmllciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG5vdGF0aW9uLCBBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotICAgIH0gLy8gdW5wYXJzZWRFbnRpdHlEZWNsCi0KLSAgICAvKioKLSAgICAgKiBBIG5vdGF0aW9uIGRlY2xhcmF0aW9uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSAgICAgVGhlIG5hbWUgb2YgdGhlIG5vdGF0aW9uLgotICAgICAqIEBwYXJhbSBpZGVudGlmaWVyICAgIEFuIG9iamVjdCBjb250YWluaW5nIGFsbCBsb2NhdGlvbiBpbmZvcm1hdGlvbgotICAgICAqICAgICAgICAgICAgICAgICAgICAgIHBlcnRpbmVudCB0byB0aGlzIG5vdGF0aW9uLgotICAgICAqIEBwYXJhbSBhdWdtZW50YXRpb25zIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBub3RhdGlvbkRlY2woU3RyaW5nIG5hbWUsIFhNTFJlc291cmNlSWRlbnRpZmllciBpZGVudGlmaWVyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotICAgIH0gLy8gbm90YXRpb25EZWNsCi0KLSAgICAvKioKLSAgICAgKiBUaGUgc3RhcnQgb2YgYSBjb25kaXRpb25hbCBzZWN0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIHR5cGUgVGhlIHR5cGUgb2YgdGhlIGNvbmRpdGlvbmFsIHNlY3Rpb24uIFRoaXMgdmFsdWUgd2lsbAotICAgICAqICAgICAgICAgICAgIGVpdGhlciBiZSBDT05ESVRJT05BTF9JTkNMVURFIG9yIENPTkRJVElPTkFMX0lHTk9SRS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKgotICAgICAqIEBzZWUgWE1MRFRESGFuZGxlciNDT05ESVRJT05BTF9JTkNMVURFCi0gICAgICogQHNlZSBYTUxEVERIYW5kbGVyI0NPTkRJVElPTkFMX0lHTk9SRQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0Q29uZGl0aW9uYWwoc2hvcnQgdHlwZSwgQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICB9IC8vIHN0YXJ0Q29uZGl0aW9uYWwKLQotICAgIC8qKgotICAgICAqIFRoZSBlbmQgb2YgYSBjb25kaXRpb25hbCBzZWN0aW9uLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZENvbmRpdGlvbmFsKEF1Z21lbnRhdGlvbnMgYXVnbWVudGF0aW9ucykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgfSAvLyBlbmRDb25kaXRpb25hbAotCi0gICAgLyoqCi0gICAgICogVGhlIGVuZCBvZiB0aGUgRFRELgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZERURChBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgIH0gLy8gZW5kRFRECi0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBub3RpZmllcyB0aGUgZW5kIG9mIGFuIGVudGl0eS4gVGhlIERURCBoYXMgdGhlIHBzZXVkby1uYW1lCi0gICAgICogb2YgIltkdGRdIiBhbmQgcGFyYW1ldGVyIGVudGl0eSBuYW1lcyBzdGFydCB3aXRoICclJy4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFNpbmNlIHRoZSBEVEQgaXMgYW4gZW50aXR5LCB0aGUgaGFuZGxlcgotICAgICAqIHdpbGwgYmUgbm90aWZpZWQgb2YgdGhlIGVuZCBvZiB0aGUgRFREIGVudGl0eSBieSBjYWxsaW5nIHRoZQotICAgICAqIGVuZEVudGl0eSBtZXRob2Qgd2l0aCB0aGUgZW50aXR5IG5hbWUgIltkdGRdIiA8ZW0+YWZ0ZXI8L2VtPiBjYWxsaW5nCi0gICAgICogdGhlIGVuZERURCBtZXRob2QuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgZW50aXR5LgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZEVudGl0eShTdHJpbmcgbmFtZSwgQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICB9Ci0KLSAgICAvLwotICAgIC8vIFhNTERURENvbnRlbnRNb2RlbEhhbmRsZXIgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBUaGUgc3RhcnQgb2YgYSBjb250ZW50IG1vZGVsLiBEZXBlbmRpbmcgb24gdGhlIHR5cGUgb2YgdGhlIGNvbnRlbnQKLSAgICAgKiBtb2RlbCwgc3BlY2lmaWMgbWV0aG9kcyBtYXkgYmUgY2FsbGVkIGJldHdlZW4gdGhlIGNhbGwgdG8gdGhlCi0gICAgICogc3RhcnRDb250ZW50TW9kZWwgbWV0aG9kIGFuZCB0aGUgY2FsbCB0byB0aGUgZW5kQ29udGVudE1vZGVsIG1ldGhvZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlbGVtZW50TmFtZSBUaGUgbmFtZSBvZiB0aGUgZWxlbWVudC4KLSAgICAgKiBAcGFyYW0gdHlwZSAgICAgICAgVGhlIGNvbnRlbnQgbW9kZWwgdHlwZS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKgotICAgICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR0ZC5YTUxFbGVtZW50RGVjbCNUWVBFX0VNUFRZCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHRkLlhNTEVsZW1lbnREZWNsI1RZUEVfQU5ZCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHRkLlhNTEVsZW1lbnREZWNsI1RZUEVfTUlYRUQKLSAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdGQuWE1MRWxlbWVudERlY2wjVFlQRV9DSElMRFJFTgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0Q29udGVudE1vZGVsKFN0cmluZyBlbGVtZW50TmFtZSwgc2hvcnQgdHlwZSkKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgfSAvLyBzdGFydENvbnRlbnRNb2RlbAotCi0gICAgLyoqCi0gICAgICogQSByZWZlcmVuY2VkIGVsZW1lbnQgaW4gYSBtaXhlZCBjb250ZW50IG1vZGVsLiBJZiB0aGUgbWl4ZWQgY29udGVudAotICAgICAqIG1vZGVsIG9ubHkgYWxsb3dzIHRleHQgY29udGVudCwgdGhlbiB0aGlzIG1ldGhvZCB3aWxsIG5vdCBiZSBjYWxsZWQKLSAgICAgKiBmb3IgdGhhdCBtb2RlbC4gSG93ZXZlciwgaWYgdGhpcyBtZXRob2QgaXMgY2FsbGVkIGZvciBhIG1peGVkCi0gICAgICogY29udGVudCBtb2RlbCwgdGhlbiB0aGUgemVybyBvciBtb3JlIG9jY3VycmVuY2UgY291bnQgaXMgaW1wbGllZC4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoaXMgbWV0aG9kIGlzIG9ubHkgY2FsbGVkIGFmdGVyIGEgY2FsbCB0bwotICAgICAqIHRoZSBzdGFydENvbnRlbnRNb2RlbCBtZXRob2Qgd2hlcmUgdGhlIHR5cGUgaXMgVFlQRV9NSVhFRC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlbGVtZW50TmFtZSBUaGUgbmFtZSBvZiB0aGUgcmVmZXJlbmNlZCBlbGVtZW50LgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHRkLlhNTEVsZW1lbnREZWNsI1RZUEVfTUlYRUQKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBtaXhlZEVsZW1lbnQoU3RyaW5nIGVsZW1lbnROYW1lKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICB9IC8vIG1peGVkRWxlbWVudAotCi0gICAgLyoqCi0gICAgICogVGhlIHN0YXJ0IG9mIGEgY2hpbGRyZW4gZ3JvdXAuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGlzIG1ldGhvZCBpcyBvbmx5IGNhbGxlZCBhZnRlciBhIGNhbGwgdG8KLSAgICAgKiB0aGUgc3RhcnRDb250ZW50TW9kZWwgbWV0aG9kIHdoZXJlIHRoZSB0eXBlIGlzIFRZUEVfQ0hJTERSRU4uCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBDaGlsZHJlbiBncm91cHMgY2FuIGJlIG5lc3RlZCBhbmQgaGF2ZQotICAgICAqIGFzc29jaWF0ZWQgb2NjdXJyZW5jZSBjb3VudHMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICoKLSAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdGQuWE1MRWxlbWVudERlY2wjVFlQRV9DSElMRFJFTgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGNoaWxkcmVuU3RhcnRHcm91cCgpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgIH0gLy8gY2hpbGRyZW5TdGFydEdyb3VwCi0KLSAgICAvKioKLSAgICAgKiBBIHJlZmVyZW5jZWQgZWxlbWVudCBpbiBhIGNoaWxkcmVuIGNvbnRlbnQgbW9kZWwuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZWxlbWVudE5hbWUgVGhlIG5hbWUgb2YgdGhlIHJlZmVyZW5jZWQgZWxlbWVudC4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKgotICAgICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR0ZC5YTUxFbGVtZW50RGVjbCNUWVBFX0NISUxEUkVOCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY2hpbGRyZW5FbGVtZW50KFN0cmluZyBlbGVtZW50TmFtZSkgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgfSAvLyBjaGlsZHJlbkVsZW1lbnQKLQotICAgIC8qKgotICAgICAqIFRoZSBzZXBhcmF0b3IgYmV0d2VlbiBjaG9pY2VzIG9yIHNlcXVlbmNlcyBvZiBhIGNoaWxkcmVuIGNvbnRlbnQKLSAgICAgKiBtb2RlbC4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoaXMgbWV0aG9kIGlzIG9ubHkgY2FsbGVkIGFmdGVyIGEgY2FsbCB0bwotICAgICAqIHRoZSBzdGFydENvbnRlbnRNb2RlbCBtZXRob2Qgd2hlcmUgdGhlIHR5cGUgaXMgVFlQRV9DSElMRFJFTi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzZXBhcmF0b3IgVGhlIHR5cGUgb2YgY2hpbGRyZW4gc2VwYXJhdG9yLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqCi0gICAgICogQHNlZSBYTUxEVERDb250ZW50TW9kZWxIYW5kbGVyI1NFUEFSQVRPUl9DSE9JQ0UKLSAgICAgKiBAc2VlIFhNTERURENvbnRlbnRNb2RlbEhhbmRsZXIjU0VQQVJBVE9SX1NFUVVFTkNFCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHRkLlhNTEVsZW1lbnREZWNsI1RZUEVfQ0hJTERSRU4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBjaGlsZHJlblNlcGFyYXRvcihzaG9ydCBzZXBhcmF0b3IpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgIH0gLy8gY2hpbGRyZW5TZXBhcmF0b3IKLQotICAgIC8qKgotICAgICAqIFRoZSBvY2N1cnJlbmNlIGNvdW50IGZvciBhIGNoaWxkIGluIGEgY2hpbGRyZW4gY29udGVudCBtb2RlbC4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoaXMgbWV0aG9kIGlzIG9ubHkgY2FsbGVkIGFmdGVyIGEgY2FsbCB0bwotICAgICAqIHRoZSBzdGFydENvbnRlbnRNb2RlbCBtZXRob2Qgd2hlcmUgdGhlIHR5cGUgaXMgVFlQRV9DSElMRFJFTi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBvY2N1cnJlbmNlIFRoZSBvY2N1cnJlbmNlIGNvdW50IGZvciB0aGUgbGFzdCBjaGlsZHJlbiBlbGVtZW50Ci0gICAgICogICAgICAgICAgICAgICAgICAgb3IgY2hpbGRyZW4gZ3JvdXAuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICoKLSAgICAgKiBAc2VlIFhNTERURENvbnRlbnRNb2RlbEhhbmRsZXIjT0NDVVJTX1pFUk9fT1JfT05FCi0gICAgICogQHNlZSBYTUxEVERDb250ZW50TW9kZWxIYW5kbGVyI09DQ1VSU19aRVJPX09SX01PUkUKLSAgICAgKiBAc2VlIFhNTERURENvbnRlbnRNb2RlbEhhbmRsZXIjT0NDVVJTX09ORV9PUl9NT1JFCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHRkLlhNTEVsZW1lbnREZWNsI1RZUEVfQ0hJTERSRU4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBjaGlsZHJlbk9jY3VycmVuY2Uoc2hvcnQgb2NjdXJyZW5jZSkgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgfSAvLyBjaGlsZHJlbk9jY3VycmVuY2UKLQotICAgIC8qKgotICAgICAqIFRoZSBlbmQgb2YgYSBjaGlsZHJlbiBncm91cC4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoaXMgbWV0aG9kIGlzIG9ubHkgY2FsbGVkIGFmdGVyIGEgY2FsbCB0bwotICAgICAqIHRoZSBzdGFydENvbnRlbnRNb2RlbCBtZXRob2Qgd2hlcmUgdGhlIHR5cGUgaXMgVFlQRV9DSElMRFJFTi4KLSAgICAgKgotICAgICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR0ZC5YTUxFbGVtZW50RGVjbCNUWVBFX0NISUxEUkVOCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY2hpbGRyZW5FbmRHcm91cCgpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgIH0gLy8gY2hpbGRyZW5FbmRHcm91cAotCi0gICAgLyoqCi0gICAgICogVGhlIGVuZCBvZiBhIGNvbnRlbnQgbW9kZWwuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kQ29udGVudE1vZGVsKCkgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgfSAvLyBlbmRDb250ZW50TW9kZWwKLQotfSAvLyBjbGFzcyBEVERQYXJzZXIKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3BhcnNlcnMvSW50ZWdyYXRlZFBhcnNlckNvbmZpZ3VyYXRpb24uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3BhcnNlcnMvSW50ZWdyYXRlZFBhcnNlckNvbmZpZ3VyYXRpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZjkwNTk4Yy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9wYXJzZXJzL0ludGVncmF0ZWRQYXJzZXJDb25maWd1cmF0aW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyNTEgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMSwgMjAwMiwyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnBhcnNlcnM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuWE1MRG9jdW1lbnRTY2FubmVySW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuWE1MTlNEb2N1bWVudFNjYW5uZXJJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdGQuWE1MRFREVmFsaWRhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdGQuWE1MTlNEVERWYWxpZGF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlhNTFNjaGVtYVZhbGlkYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMuWFNNZXNzYWdlRm9ybWF0dGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5TeW1ib2xUYWJsZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5ncmFtbWFycy5YTUxHcmFtbWFyUG9vbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MQ29tcG9uZW50OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxDb21wb25lbnRNYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxEb2N1bWVudFNjYW5uZXI7Ci0KLS8qKgotICogVGhpcyBpcyBjb25maWd1cmF0aW9uIHVzZXMgYSBzY2FubmVyIHRoYXQgaW50ZWdyYXRlcyBib3RoIHNjYW5uaW5nIG9mIHRoZSBkb2N1bWVudAotICogYW5kIGJpbmRpbmcgbmFtZXNwYWNlcy4KLSAqCi0gKiBJZiBuYW1lc3BhY2UgZmVhdHVyZSBpcyB0dXJuZWQgb24sIHRoZSBwaXBlbGluZSBpcyBjb25zdHJ1Y3R1cmVkIHdpdGggdGhlCi0gKiBmb2xsb3dpbmcgY29tcG9uZW50czoKLSAqIFhNTE5TRG9jdW1lbnRTY2FubmVySW1wbCAtPiBYTUxOU0RURFZhbGlkYXRvciAtPiAob3B0aW9uYWwpIFhNTFNjaGVtYVZhbGlkYXRvcgotICoKLSAqIElmIHRoZSBuYW1lc3BhY2UgZmVhdHVyZSBpcyB0dXJuZWQgb2ZmIHRoZSBkZWZhdWx0IGRvY3VtZW50IHNjYW5uZXIgaW1wbGVtZW50YXRpb24KLSAqIGlzIHVzZWQgKFhNTERvY3VtZW50U2Nhbm5lckltcGwpLgotICogPHA+Ci0gKiBJbiBhZGRpdGlvbiB0byB0aGUgZmVhdHVyZXMgYW5kIHByb3BlcnRpZXMgcmVjb2duaXplZCBieSB0aGUgYmFzZQotICogcGFyc2VyIGNvbmZpZ3VyYXRpb24sIHRoaXMgY2xhc3MgcmVjb2duaXplcyB0aGVzZSBhZGRpdGlvbmFsCi0gKiBmZWF0dXJlcyBhbmQgcHJvcGVydGllczoKLSAqIDx1bD4KLSAqIDxsaT5GZWF0dXJlcwotICogIDx1bD4KLSAqICA8bGk+aHR0cDovL2FwYWNoZS5vcmcveG1sL2ZlYXR1cmVzL3ZhbGlkYXRpb24vc2NoZW1hPC9saT4KLSAqICA8bGk+aHR0cDovL2FwYWNoZS5vcmcveG1sL2ZlYXR1cmVzL3ZhbGlkYXRpb24vc2NoZW1hLWZ1bGwtY2hlY2tpbmc8L2xpPgotICogIDxsaT5odHRwOi8vYXBhY2hlLm9yZy94bWwvZmVhdHVyZXMvdmFsaWRhdGlvbi9zY2hlbWEvbm9ybWFsaXplZC12YWx1ZTwvbGk+Ci0gKiAgPGxpPmh0dHA6Ly9hcGFjaGUub3JnL3htbC9mZWF0dXJlcy92YWxpZGF0aW9uL3NjaGVtYS9lbGVtZW50LWRlZmF1bHQ8L2xpPgotICogIDwvdWw+Ci0gKiA8bGk+UHJvcGVydGllcwotICogIDx1bD4KLSAqICAgPGxpPmh0dHA6Ly9hcGFjaGUub3JnL3htbC9wcm9wZXJ0aWVzL2ludGVybmFsL2Vycm9yLXJlcG9ydGVyPC9saT4KLSAqICAgPGxpPmh0dHA6Ly9hcGFjaGUub3JnL3htbC9wcm9wZXJ0aWVzL2ludGVybmFsL2VudGl0eS1tYW5hZ2VyPC9saT4KLSAqICAgPGxpPmh0dHA6Ly9hcGFjaGUub3JnL3htbC9wcm9wZXJ0aWVzL2ludGVybmFsL2RvY3VtZW50LXNjYW5uZXI8L2xpPgotICogICA8bGk+aHR0cDovL2FwYWNoZS5vcmcveG1sL3Byb3BlcnRpZXMvaW50ZXJuYWwvZHRkLXNjYW5uZXI8L2xpPgotICogICA8bGk+aHR0cDovL2FwYWNoZS5vcmcveG1sL3Byb3BlcnRpZXMvaW50ZXJuYWwvZ3JhbW1hci1wb29sPC9saT4KLSAqICAgPGxpPmh0dHA6Ly9hcGFjaGUub3JnL3htbC9wcm9wZXJ0aWVzL2ludGVybmFsL3ZhbGlkYXRvci9kdGQ8L2xpPgotICogICA8bGk+aHR0cDovL2FwYWNoZS5vcmcveG1sL3Byb3BlcnRpZXMvaW50ZXJuYWwvZGF0YXR5cGUtdmFsaWRhdG9yLWZhY3Rvcnk8L2xpPgotICogIDwvdWw+Ci0gKiA8L3VsPgotICoKLSAqIEBhdXRob3IgRWxlbmEgTGl0YW5pLCBJQk0KLSAqCi0gKi8KLXB1YmxpYyBjbGFzcyBJbnRlZ3JhdGVkUGFyc2VyQ29uZmlndXJhdGlvbgotZXh0ZW5kcyBTdGFuZGFyZFBhcnNlckNvbmZpZ3VyYXRpb24gewotCi0KLSAgICAvLwotICAgIC8vIFJFVklTSVQ6IHNob3VsZCB0aGlzIGNvbmZpZ3VyYXRpb24gZGVwZW5kIG9uIHRoZSBvdGhlcnMKLSAgICAvLyAgICAgICAgICBsaWtlIERURC9TdGFuZGFyZCBvbmU/Ci0gICAgLy8KLQotICAgIC8qKiBEb2N1bWVudCBzY2FubmVyIHRoYXQgZG9lcyBuYW1lc3BhY2UgYmluZGluZy4gKi8KLSAgICBwcm90ZWN0ZWQgWE1MTlNEb2N1bWVudFNjYW5uZXJJbXBsIGZOYW1lc3BhY2VTY2FubmVyOwotCi0gICAgLyoqIERlZmF1bHQgWGVyY2VzIGltcGxlbWVudGF0aW9uIG9mIHNjYW5uZXIgKi8KLSAgICBwcm90ZWN0ZWQgWE1MRG9jdW1lbnRTY2FubmVySW1wbCBmTm9uTlNTY2FubmVyOwotCi0gICAgLyoqIERURCBWYWxpZGF0b3IgdGhhdCBkb2VzIG5vdCBiaW5kIG5hbWVzcGFjZXMgKi8KLSAgICBwcm90ZWN0ZWQgWE1MRFREVmFsaWRhdG9yIGZOb25OU0RURFZhbGlkYXRvcjsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKiBEZWZhdWx0IGNvbnN0cnVjdG9yLiAqLwotICAgIHB1YmxpYyBJbnRlZ3JhdGVkUGFyc2VyQ29uZmlndXJhdGlvbigpIHsKLSAgICAgICAgdGhpcyhudWxsLCBudWxsLCBudWxsKTsKLSAgICB9IC8vIDxpbml0PigpCi0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RzIGEgcGFyc2VyIGNvbmZpZ3VyYXRpb24gdXNpbmcgdGhlIHNwZWNpZmllZCBzeW1ib2wgdGFibGUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc3ltYm9sVGFibGUgVGhlIHN5bWJvbCB0YWJsZSB0byB1c2UuCi0gICAgICovCi0gICAgcHVibGljIEludGVncmF0ZWRQYXJzZXJDb25maWd1cmF0aW9uKFN5bWJvbFRhYmxlIHN5bWJvbFRhYmxlKSB7Ci0gICAgICAgIHRoaXMoc3ltYm9sVGFibGUsIG51bGwsIG51bGwpOwotICAgIH0gLy8gPGluaXQ+KFN5bWJvbFRhYmxlKQotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0cyBhIHBhcnNlciBjb25maWd1cmF0aW9uIHVzaW5nIHRoZSBzcGVjaWZpZWQgc3ltYm9sIHRhYmxlIGFuZAotICAgICAqIGdyYW1tYXIgcG9vbC4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPlJFVklTSVQ6PC9zdHJvbmc+Ci0gICAgICogR3JhbW1hciBwb29sIHdpbGwgYmUgdXBkYXRlZCB3aGVuIHRoZSBuZXcgdmFsaWRhdGlvbiBlbmdpbmUgaXMKLSAgICAgKiBpbXBsZW1lbnRlZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzeW1ib2xUYWJsZSBUaGUgc3ltYm9sIHRhYmxlIHRvIHVzZS4KLSAgICAgKiBAcGFyYW0gZ3JhbW1hclBvb2wgVGhlIGdyYW1tYXIgcG9vbCB0byB1c2UuCi0gICAgICovCi0gICAgcHVibGljIEludGVncmF0ZWRQYXJzZXJDb25maWd1cmF0aW9uKFN5bWJvbFRhYmxlIHN5bWJvbFRhYmxlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxHcmFtbWFyUG9vbCBncmFtbWFyUG9vbCkgewotICAgICAgICB0aGlzKHN5bWJvbFRhYmxlLCBncmFtbWFyUG9vbCwgbnVsbCk7Ci0gICAgfSAvLyA8aW5pdD4oU3ltYm9sVGFibGUsWE1MR3JhbW1hclBvb2wpCi0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RzIGEgcGFyc2VyIGNvbmZpZ3VyYXRpb24gdXNpbmcgdGhlIHNwZWNpZmllZCBzeW1ib2wgdGFibGUsCi0gICAgICogZ3JhbW1hciBwb29sLCBhbmQgcGFyZW50IHNldHRpbmdzLgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+UkVWSVNJVDo8L3N0cm9uZz4KLSAgICAgKiBHcmFtbWFyIHBvb2wgd2lsbCBiZSB1cGRhdGVkIHdoZW4gdGhlIG5ldyB2YWxpZGF0aW9uIGVuZ2luZSBpcwotICAgICAqIGltcGxlbWVudGVkLgotICAgICAqCi0gICAgICogQHBhcmFtIHN5bWJvbFRhYmxlICAgIFRoZSBzeW1ib2wgdGFibGUgdG8gdXNlLgotICAgICAqIEBwYXJhbSBncmFtbWFyUG9vbCAgICBUaGUgZ3JhbW1hciBwb29sIHRvIHVzZS4KLSAgICAgKiBAcGFyYW0gcGFyZW50U2V0dGluZ3MgVGhlIHBhcmVudCBzZXR0aW5ncy4KLSAgICAgKi8KLSAgICBwdWJsaWMgSW50ZWdyYXRlZFBhcnNlckNvbmZpZ3VyYXRpb24oU3ltYm9sVGFibGUgc3ltYm9sVGFibGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTEdyYW1tYXJQb29sIGdyYW1tYXJQb29sLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxDb21wb25lbnRNYW5hZ2VyIHBhcmVudFNldHRpbmdzKSB7Ci0gICAgICAgIHN1cGVyKHN5bWJvbFRhYmxlLCBncmFtbWFyUG9vbCwgcGFyZW50U2V0dGluZ3MpOwotCi0gICAgICAgIC8vIGNyZWF0ZSBjb21wb25lbnRzCi0gICAgICAgIGZOb25OU1NjYW5uZXIgPSBuZXcgWE1MRG9jdW1lbnRTY2FubmVySW1wbCgpOwotICAgICAgICBmTm9uTlNEVERWYWxpZGF0b3IgPSBuZXcgWE1MRFREVmFsaWRhdG9yKCk7Ci0KLSAgICAgICAgLy8gYWRkIGNvbXBvbmVudHMKLSAgICAgICAgYWRkQ29tcG9uZW50KChYTUxDb21wb25lbnQpZk5vbk5TU2Nhbm5lcik7Ci0gICAgICAgIGFkZENvbXBvbmVudCgoWE1MQ29tcG9uZW50KWZOb25OU0RURFZhbGlkYXRvcik7Ci0KLSAgICB9IC8vIDxpbml0PihTeW1ib2xUYWJsZSxYTUxHcmFtbWFyUG9vbCkKLQotCi0gICAgLyoqIENvbmZpZ3VyZXMgdGhlIHBpcGVsaW5lLiAqLwotICAgICAgICBwcm90ZWN0ZWQgdm9pZCBjb25maWd1cmVQaXBlbGluZSgpIHsKLQotICAgICAgICAgICAgICAgIC8vIHVzZSBYTUwgMS4wIGRhdGF0eXBlIGxpYnJhcnkKLSAgICAgICAgICAgICAgICBzZXRQcm9wZXJ0eShEQVRBVFlQRV9WQUxJREFUT1JfRkFDVE9SWSwgZkRhdGF0eXBlVmFsaWRhdG9yRmFjdG9yeSk7Ci0KLSAgICAgICAgICAgICAgICAvLyBzZXR1cCBEVEQgcGlwZWxpbmUKLSAgICAgICAgICAgICAgICBjb25maWd1cmVEVERQaXBlbGluZSgpOwotCi0gICAgICAgICAgICAgICAgLy8gc2V0dXAgZG9jdW1lbnQgcGlwZWxpbmUKLSAgICAgICAgICAgICAgICBpZiAoZkZlYXR1cmVzLmdldChOQU1FU1BBQ0VTKSA9PSBCb29sZWFuLlRSVUUpIHsKLSAgICAgICAgICAgIGZQcm9wZXJ0aWVzLnB1dChOQU1FU1BBQ0VfQklOREVSLCBmTmFtZXNwYWNlQmluZGVyKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZTY2FubmVyID0gZk5hbWVzcGFjZVNjYW5uZXI7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmUHJvcGVydGllcy5wdXQoRE9DVU1FTlRfU0NBTk5FUiwgZk5hbWVzcGFjZVNjYW5uZXIpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZEVERWYWxpZGF0b3IgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmUHJvcGVydGllcy5wdXQoRFREX1ZBTElEQVRPUiwgZkRURFZhbGlkYXRvcik7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZOYW1lc3BhY2VTY2FubmVyLnNldERURFZhbGlkYXRvcihmRFREVmFsaWRhdG9yKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZk5hbWVzcGFjZVNjYW5uZXIuc2V0RG9jdW1lbnRIYW5kbGVyKGZEVERWYWxpZGF0b3IpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmRFREVmFsaWRhdG9yLnNldERvY3VtZW50U291cmNlKGZOYW1lc3BhY2VTY2FubmVyKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkRURFZhbGlkYXRvci5zZXREb2N1bWVudEhhbmRsZXIoZkRvY3VtZW50SGFuZGxlcik7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmRG9jdW1lbnRIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLnNldERvY3VtZW50U291cmNlKGZEVERWYWxpZGF0b3IpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZMYXN0Q29tcG9uZW50ID0gZkRURFZhbGlkYXRvcjsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmTmFtZXNwYWNlU2Nhbm5lci5zZXREb2N1bWVudEhhbmRsZXIoZkRvY3VtZW50SGFuZGxlcik7Ci0gICAgICAgICAgICAgICAgZk5hbWVzcGFjZVNjYW5uZXIuc2V0RFREVmFsaWRhdG9yKG51bGwpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZkRvY3VtZW50SGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci5zZXREb2N1bWVudFNvdXJjZShmTmFtZXNwYWNlU2Nhbm5lcik7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkxhc3RDb21wb25lbnQgPSBmTmFtZXNwYWNlU2Nhbm5lcjsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmU2Nhbm5lciA9IGZOb25OU1NjYW5uZXI7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmUHJvcGVydGllcy5wdXQoRE9DVU1FTlRfU0NBTk5FUiwgZk5vbk5TU2Nhbm5lcik7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZk5vbk5TRFREVmFsaWRhdG9yICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZlByb3BlcnRpZXMucHV0KERURF9WQUxJREFUT1IsIGZOb25OU0RURFZhbGlkYXRvcik7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZOb25OU1NjYW5uZXIuc2V0RG9jdW1lbnRIYW5kbGVyKGZOb25OU0RURFZhbGlkYXRvcik7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZOb25OU0RURFZhbGlkYXRvci5zZXREb2N1bWVudFNvdXJjZShmTm9uTlNTY2FubmVyKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZk5vbk5TRFREVmFsaWRhdG9yLnNldERvY3VtZW50SGFuZGxlcihmRG9jdW1lbnRIYW5kbGVyKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZEb2N1bWVudEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZEb2N1bWVudEhhbmRsZXIuc2V0RG9jdW1lbnRTb3VyY2UoZk5vbk5TRFREVmFsaWRhdG9yKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmTGFzdENvbXBvbmVudCA9IGZOb25OU0RURFZhbGlkYXRvcjsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmU2Nhbm5lci5zZXREb2N1bWVudEhhbmRsZXIoZkRvY3VtZW50SGFuZGxlcik7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmRG9jdW1lbnRIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLnNldERvY3VtZW50U291cmNlKGZTY2FubmVyKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmTGFzdENvbXBvbmVudCA9IGZTY2FubmVyOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8vIHNldHVwIGRvY3VtZW50IHBpcGVsaW5lCi0gICAgICAgICAgICAgICAgaWYgKGZGZWF0dXJlcy5nZXQoWE1MU0NIRU1BX1ZBTElEQVRJT04pID09IEJvb2xlYW4uVFJVRSkgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gSWYgc2NoZW1hIHZhbGlkYXRvciB3YXMgbm90IGluIHRoZSBwaXBlbGluZSBpbnNlcnQgaXQuCi0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZlNjaGVtYVZhbGlkYXRvciA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZTY2hlbWFWYWxpZGF0b3IgPSBuZXcgWE1MU2NoZW1hVmFsaWRhdG9yKCk7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYWRkIHNjaGVtYSBjb21wb25lbnQKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZlByb3BlcnRpZXMucHV0KFNDSEVNQV9WQUxJREFUT1IsIGZTY2hlbWFWYWxpZGF0b3IpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRDb21wb25lbnQoZlNjaGVtYVZhbGlkYXRvcik7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFkZCBzY2hlbWEgbWVzc2FnZSBmb3JtYXR0ZXIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZFcnJvclJlcG9ydGVyLmdldE1lc3NhZ2VGb3JtYXR0ZXIoWFNNZXNzYWdlRm9ybWF0dGVyLlNDSEVNQV9ET01BSU4pID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYU01lc3NhZ2VGb3JtYXR0ZXIgeG1mdCA9IG5ldyBYU01lc3NhZ2VGb3JtYXR0ZXIoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmRXJyb3JSZXBvcnRlci5wdXRNZXNzYWdlRm9ybWF0dGVyKFhTTWVzc2FnZUZvcm1hdHRlci5TQ0hFTUFfRE9NQUlOLCB4bWZ0KTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIGZMYXN0Q29tcG9uZW50LnNldERvY3VtZW50SGFuZGxlcihmU2NoZW1hVmFsaWRhdG9yKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZTY2hlbWFWYWxpZGF0b3Iuc2V0RG9jdW1lbnRTb3VyY2UoZkxhc3RDb21wb25lbnQpOwotICAgICAgICAgICAgICAgICAgICAgICAgZlNjaGVtYVZhbGlkYXRvci5zZXREb2N1bWVudEhhbmRsZXIoZkRvY3VtZW50SGFuZGxlcik7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZkRvY3VtZW50SGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZEb2N1bWVudEhhbmRsZXIuc2V0RG9jdW1lbnRTb3VyY2UoZlNjaGVtYVZhbGlkYXRvcik7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBmTGFzdENvbXBvbmVudCA9IGZTY2hlbWFWYWxpZGF0b3I7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICB9IC8vIGNvbmZpZ3VyZVBpcGVsaW5lKCkKLQotCi0KLSAgICAvKiogQ3JlYXRlIGEgZG9jdW1lbnQgc2Nhbm5lcjogdGhpcyBzY2FubmVyIHBlcmZvcm1zIG5hbWVzcGFjZSBiaW5kaW5nCi0gICAgICAqLwotICAgIHByb3RlY3RlZCBYTUxEb2N1bWVudFNjYW5uZXIgY3JlYXRlRG9jdW1lbnRTY2FubmVyKCkgewotICAgICAgICBmTmFtZXNwYWNlU2Nhbm5lciA9IG5ldyBYTUxOU0RvY3VtZW50U2Nhbm5lckltcGwoKTsKLSAgICAgICAgcmV0dXJuIGZOYW1lc3BhY2VTY2FubmVyOwotICAgIH0gLy8gY3JlYXRlRG9jdW1lbnRTY2FubmVyKCk6WE1MRG9jdW1lbnRTY2FubmVyCi0KLQotICAgIC8qKiBDcmVhdGUgYSBEVEQgdmFsaWRhdG9yOiB0aGlzIHZhbGlkYXRvciBwZXJmb3JtcyBuYW1lc3BhY2UgYmluZGluZy4KLSAgICAgICovCi0gICAgcHJvdGVjdGVkIFhNTERURFZhbGlkYXRvciBjcmVhdGVEVERWYWxpZGF0b3IoKSB7Ci0gICAgICAgIHJldHVybiBuZXcgWE1MTlNEVERWYWxpZGF0b3IoKTsKLSAgICB9IC8vIGNyZWF0ZURURFZhbGlkYXRvcigpOlhNTERURFZhbGlkYXRvcgotCi19IC8vIGNsYXNzIEludGVncmF0ZWRQYXJzZXJDb25maWd1cmF0aW9uCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9wYXJzZXJzL05vblZhbGlkYXRpbmdDb25maWd1cmF0aW9uLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9wYXJzZXJzL05vblZhbGlkYXRpbmdDb25maWd1cmF0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDQ2OTc4MDEuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvcGFyc2Vycy9Ob25WYWxpZGF0aW5nQ29uZmlndXJhdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsODA2ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5wYXJzZXJzOwotCi1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLkNvbnN0YW50czsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuWE1MRFREU2Nhbm5lckltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLlhNTERvY3VtZW50U2Nhbm5lckltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLlhNTEVudGl0eU1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLlhNTEVycm9yUmVwb3J0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLlhNTE5TRG9jdW1lbnRTY2FubmVySW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYuRFRERFZGYWN0b3J5OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5tc2cuWE1MTWVzc2FnZUZvcm1hdHRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwudmFsaWRhdGlvbi5WYWxpZGF0aW9uTWFuYWdlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuRmVhdHVyZVN0YXRlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5Qcm9wZXJ0eVN0YXRlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5TdGF0dXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlN5bWJvbFRhYmxlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbHMuWE1MU2VjdXJpdHlQcm9wZXJ0eU1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MTG9jYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTklFeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuZ3JhbW1hcnMuWE1MR3JhbW1hclBvb2w7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTENvbXBvbmVudDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MQ29tcG9uZW50TWFuYWdlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MRFREU2Nhbm5lcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MRG9jdW1lbnRTY2FubmVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxJbnB1dFNvdXJjZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MUHVsbFBhcnNlckNvbmZpZ3VyYXRpb247Ci0KLS8qKgotICogVGhpcyBpcyB0aGUgbm9uIHZhbGlkYXRpbmcgcGFyc2VyIGNvbmZpZ3VyYXRpb24uIEl0IGV4dGVuZHMgdGhlIGJhc2ljCi0gKiBjb25maWd1cmF0aW9uIHdpdGggdGhlIHNldCBvZiBmb2xsb3dpbmcgcGFyc2VyIGNvbXBvbmVudHM6Ci0gKiBEb2N1bWVudCBzY2FubmVyLCBEVEQgc2Nhbm5lciwgbmFtZXNwYWNlIGJpbmRlciwgZG9jdW1lbnQgaGFuZGxlci4KLSAqIDxwPgotICogWGVyY2VzIHBhcnNlciB0aGF0IHVzZXMgdGhpcyBjb25maWd1cmF0aW9uIGlzIDxzdHJvbmc+bm90PC9zdHJvbmc+IDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy14bWwjc2VjLWNvbmZvcm1hbmNlIj5jb25mb3JtYW50PC9hPgotICogbm9uLXZhbGlkYXRpbmcgWE1MIHByb2Nlc3Nvciwgc2luY2UgY29uZm9ybWFudCBub24tdmFsaWRhdGluZyBwcm9jZXNzb3IgaXMgcmVxdWlyZWQKLSAqIHRvIHByb2Nlc3MgImFsbCB0aGUgZGVjbGFyYXRpb25zIHRoZXkgcmVhZCBpbiB0aGUgaW50ZXJuYWwgRFREIHN1YnNldCAuLi4gbXVzdCB1c2UgdGhlIGluZm9ybWF0aW9uIGluIHRob3NlIGRlY2xhcmF0aW9ucyB0byBub3JtYWxpemUgYXR0cmlidXRlIHZhbHVlcywKLSAqIGluY2x1ZGUgdGhlIHJlcGxhY2VtZW50IHRleHQgb2YgaW50ZXJuYWwgZW50aXRpZXMsIGFuZCBzdXBwbHkgZGVmYXVsdCBhdHRyaWJ1dGUgdmFsdWVzIi4KLSAqCi0gKiBAYXV0aG9yIEVsZW5hIExpdGFuaSwgSUJNCi0gKiBAdmVyc2lvbiAkSWQ6IE5vblZhbGlkYXRpbmdDb25maWd1cmF0aW9uLmphdmEsdiAxLjcgMjAxMC0xMS0wMSAwNDo0MDowOSBqb2VodyBFeHAgJAotICovCi1wdWJsaWMgY2xhc3MgTm9uVmFsaWRhdGluZ0NvbmZpZ3VyYXRpb24KLSAgICBleHRlbmRzIEJhc2ljUGFyc2VyQ29uZmlndXJhdGlvbgotICAgIGltcGxlbWVudHMgWE1MUHVsbFBhcnNlckNvbmZpZ3VyYXRpb24gewotCi0gICAgLy8KLSAgICAvLyBDb25zdGFudHMKLSAgICAvLwotCi0gICAgLy8gZmVhdHVyZSBpZGVudGlmaWVycwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogd2FybiBvbiBkdXBsaWNhdGUgYXR0cmlidXRlIGRlZmluaXRpb24uICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0FSTl9PTl9EVVBMSUNBVEVfQVRUREVGID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5XQVJOX09OX0RVUExJQ0FURV9BVFRERUZfRkVBVFVSRTsKLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IHdhcm4gb24gZHVwbGljYXRlIGVudGl0eSBkZWZpbml0aW9uLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFdBUk5fT05fRFVQTElDQVRFX0VOVElUWURFRiA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuV0FSTl9PTl9EVVBMSUNBVEVfRU5USVRZREVGX0ZFQVRVUkU7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiB3YXJuIG9uIHVuZGVjbGFyZWQgZWxlbWVudCBkZWZpbml0aW9uLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFdBUk5fT05fVU5ERUNMQVJFRF9FTEVNREVGID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5XQVJOX09OX1VOREVDTEFSRURfRUxFTURFRl9GRUFUVVJFOwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogYWxsb3cgSmF2YSBlbmNvZGluZ3MuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgQUxMT1dfSkFWQV9FTkNPRElOR1MgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLkFMTE9XX0pBVkFfRU5DT0RJTkdTX0ZFQVRVUkU7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiBjb250aW51ZSBhZnRlciBmYXRhbCBlcnJvci4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBDT05USU5VRV9BRlRFUl9GQVRBTF9FUlJPUiA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuQ09OVElOVUVfQUZURVJfRkFUQUxfRVJST1JfRkVBVFVSRTsKLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IGxvYWQgZXh0ZXJuYWwgRFRELiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIExPQURfRVhURVJOQUxfRFREID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5MT0FEX0VYVEVSTkFMX0RURF9GRUFUVVJFOwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogbm90aWZ5IGJ1aWx0LWluIHJlZmVyZWNlcy4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBOT1RJRllfQlVJTFRJTl9SRUZTID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5OT1RJRllfQlVJTFRJTl9SRUZTX0ZFQVRVUkU7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiBub3RpZnkgY2hhcmFjdGVyIHJlZmVyZWNlcy4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBOT1RJRllfQ0hBUl9SRUZTID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5OT1RJRllfQ0hBUl9SRUZTX0ZFQVRVUkU7Ci0KLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IGV4cG9zZSBzY2hlbWEgbm9ybWFsaXplZCB2YWx1ZSAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIE5PUk1BTElaRV9EQVRBID0KLSAgICBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLlNDSEVNQV9OT1JNQUxJWkVEX1ZBTFVFOwotCi0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiBzZW5kIGVsZW1lbnQgZGVmYXVsdCB2YWx1ZSB2aWEgY2hhcmFjdGVycygpICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgU0NIRU1BX0VMRU1FTlRfREVGQVVMVCA9Ci0gICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5TQ0hFTUFfRUxFTUVOVF9ERUZBVUxUOwotCi0gICAgLy8gcHJvcGVydHkgaWRlbnRpZmllcnMKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBlcnJvciByZXBvcnRlci4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJPUl9SRVBPUlRFUiA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLkVSUk9SX1JFUE9SVEVSX1BST1BFUlRZOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IGVudGl0eSBtYW5hZ2VyLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIEVOVElUWV9NQU5BR0VSID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuRU5USVRZX01BTkFHRVJfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllciBkb2N1bWVudCBzY2FubmVyOiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIERPQ1VNRU5UX1NDQU5ORVIgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5ET0NVTUVOVF9TQ0FOTkVSX1BST1BFUlRZOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IERURCBzY2FubmVyLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIERURF9TQ0FOTkVSID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuRFREX1NDQU5ORVJfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogZ3JhbW1hciBwb29sLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFhNTEdSQU1NQVJfUE9PTCA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLlhNTEdSQU1NQVJfUE9PTF9QUk9QRVJUWTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBEVEQgdmFsaWRhdG9yLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIERURF9WQUxJREFUT1IgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5EVERfVkFMSURBVE9SX1BST1BFUlRZOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IG5hbWVzcGFjZSBiaW5kZXIuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgTkFNRVNQQUNFX0JJTkRFUiA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLk5BTUVTUEFDRV9CSU5ERVJfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogZGF0YXR5cGUgdmFsaWRhdG9yIGZhY3RvcnkuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgREFUQVRZUEVfVkFMSURBVE9SX0ZBQ1RPUlkgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5EQVRBVFlQRV9WQUxJREFUT1JfRkFDVE9SWV9QUk9QRVJUWTsKLQotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFZBTElEQVRJT05fTUFOQUdFUiA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLlZBTElEQVRJT05fTUFOQUdFUl9QUk9QRVJUWTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBYTUwgU2NoZW1hIHZhbGlkYXRvci4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBTQ0hFTUFfVkFMSURBVE9SID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuU0NIRU1BX1ZBTElEQVRPUl9QUk9QRVJUWTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBsb2NhbGUuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgTE9DQUxFID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuTE9DQUxFX1BST1BFUlRZOwotCi0gICAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogU2VjdXJpdHkgcHJvcGVydHkgbWFuYWdlci4gKi8KLSAgICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFhNTF9TRUNVUklUWV9QUk9QRVJUWV9NQU5BR0VSID0KLSAgICAgICAgICAgICAgQ29uc3RhbnRzLlhNTF9TRUNVUklUWV9QUk9QRVJUWV9NQU5BR0VSOwotCi0gICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBTZWN1cml0eSBtYW5hZ2VyLiAqLwotICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgU0VDVVJJVFlfTUFOQUdFUiA9IENvbnN0YW50cy5TRUNVUklUWV9NQU5BR0VSOwotCi0gICAgLy8gZGVidWdnaW5nCi0KLSAgICAvKiogU2V0IHRvIHRydWUgYW5kIHJlY29tcGlsZSB0byBwcmludCBleGNlcHRpb24gc3RhY2sgdHJhY2UuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbiBQUklOVF9FWENFUFRJT05fU1RBQ0tfVFJBQ0UgPSBmYWxzZTsKLQotICAgIC8vCi0gICAgLy8gRGF0YQotICAgIC8vCi0KLSAgICAvLyBjb21wb25lbnRzIChub24tY29uZmlndXJhYmxlKQotCi0gICAgLyoqIEdyYW1tYXIgcG9vbC4gKi8KLSAgICBwcm90ZWN0ZWQgWE1MR3JhbW1hclBvb2wgZkdyYW1tYXJQb29sOwotCi0gICAgLyoqIERhdGF0eXBlIHZhbGlkYXRvciBmYWN0b3J5LiAqLwotICAgIHByb3RlY3RlZCBEVEREVkZhY3RvcnkgZkRhdGF0eXBlVmFsaWRhdG9yRmFjdG9yeTsKLQotICAgIC8vIGNvbXBvbmVudHMgKGNvbmZpZ3VyYWJsZSkKLQotICAgIC8qKiBFcnJvciByZXBvcnRlci4gKi8KLSAgICBwcm90ZWN0ZWQgWE1MRXJyb3JSZXBvcnRlciBmRXJyb3JSZXBvcnRlcjsKLQotICAgIC8qKiBFbnRpdHkgbWFuYWdlci4gKi8KLSAgICBwcm90ZWN0ZWQgWE1MRW50aXR5TWFuYWdlciBmRW50aXR5TWFuYWdlcjsKLQotICAgIC8qKiBEb2N1bWVudCBzY2FubmVyLiAqLwotICAgIHByb3RlY3RlZCBYTUxEb2N1bWVudFNjYW5uZXIgZlNjYW5uZXI7Ci0KLSAgICAvKiogSW5wdXQgU291cmNlICovCi0gICAgcHJvdGVjdGVkIFhNTElucHV0U291cmNlIGZJbnB1dFNvdXJjZTsKLQotICAgIC8qKiBEVEQgc2Nhbm5lci4gKi8KLSAgICBwcm90ZWN0ZWQgWE1MRFREU2Nhbm5lciBmRFREU2Nhbm5lcjsKLQotCi0gICAgcHJvdGVjdGVkIFZhbGlkYXRpb25NYW5hZ2VyIGZWYWxpZGF0aW9uTWFuYWdlcjsKLQotICAgIC8vIHByaXZhdGUgZGF0YQotCi0gICAgLyoqIERvY3VtZW50IHNjYW5uZXIgdGhhdCBkb2VzIG5hbWVzcGFjZSBiaW5kaW5nLiAqLwotICAgIHByaXZhdGUgWE1MTlNEb2N1bWVudFNjYW5uZXJJbXBsIGZOYW1lc3BhY2VTY2FubmVyOwotCi0gICAgLyoqIERlZmF1bHQgWGVyY2VzIGltcGxlbWVudGF0aW9uIG9mIHNjYW5uZXIqLwotICAgIHByaXZhdGUgWE1MRG9jdW1lbnRTY2FubmVySW1wbCBmTm9uTlNTY2FubmVyOwotCi0KLSAgICAgICAgLyoqIGZDb25maWdVcGRhdGVkIGlzIHNldCB0byB0cnVlIGlmIHRoZXJlIGhhcyBiZWVuIGFueSBjaGFuZ2UgdG8gdGhlIGNvbmZpZ3VyYXRpb24gc2V0dGluZ3MsCi0gICAgICAgICAqIGkuZSBhIGZlYXR1cmUgb3IgYSBwcm9wZXJ0eSB3YXMgY2hhbmdlZC4KLSAgICAgICAgICovCi0gICAgICAgIHByb3RlY3RlZCBib29sZWFuIGZDb25maWdVcGRhdGVkID0gZmFsc2U7Ci0KLQotICAgIC8vIHN0YXRlCi0KLSAgICAvKiogTG9jYXRvciAqLwotICAgIHByb3RlY3RlZCBYTUxMb2NhdG9yIGZMb2NhdG9yOwotCi0gICAgLyoqCi0gICAgICogVHJ1ZSBpZiBhIHBhcnNlIGlzIGluIHByb2dyZXNzLiBUaGlzIHN0YXRlIGlzIG5lZWRlZCBiZWNhdXNlCi0gICAgICogc29tZSBmZWF0dXJlcy9wcm9wZXJ0aWVzIGNhbm5vdCBiZSBzZXQgd2hpbGUgcGFyc2luZyAoZS5nLgotICAgICAqIHZhbGlkYXRpb24gYW5kIG5hbWVzcGFjZXMpLgotICAgICAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIGZQYXJzZUluUHJvZ3Jlc3MgPSBmYWxzZTsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKiBEZWZhdWx0IGNvbnN0cnVjdG9yLiAqLwotICAgIHB1YmxpYyBOb25WYWxpZGF0aW5nQ29uZmlndXJhdGlvbigpIHsKLSAgICAgICAgdGhpcyhudWxsLCBudWxsLCBudWxsKTsKLSAgICB9IC8vIDxpbml0PigpCi0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RzIGEgcGFyc2VyIGNvbmZpZ3VyYXRpb24gdXNpbmcgdGhlIHNwZWNpZmllZCBzeW1ib2wgdGFibGUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc3ltYm9sVGFibGUgVGhlIHN5bWJvbCB0YWJsZSB0byB1c2UuCi0gICAgICovCi0gICAgcHVibGljIE5vblZhbGlkYXRpbmdDb25maWd1cmF0aW9uKFN5bWJvbFRhYmxlIHN5bWJvbFRhYmxlKSB7Ci0gICAgICAgIHRoaXMoc3ltYm9sVGFibGUsIG51bGwsIG51bGwpOwotICAgIH0gLy8gPGluaXQ+KFN5bWJvbFRhYmxlKQotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0cyBhIHBhcnNlciBjb25maWd1cmF0aW9uIHVzaW5nIHRoZSBzcGVjaWZpZWQgc3ltYm9sIHRhYmxlIGFuZAotICAgICAqIGdyYW1tYXIgcG9vbC4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPlJFVklTSVQ6PC9zdHJvbmc+Ci0gICAgICogR3JhbW1hciBwb29sIHdpbGwgYmUgdXBkYXRlZCB3aGVuIHRoZSBuZXcgdmFsaWRhdGlvbiBlbmdpbmUgaXMKLSAgICAgKiBpbXBsZW1lbnRlZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzeW1ib2xUYWJsZSBUaGUgc3ltYm9sIHRhYmxlIHRvIHVzZS4KLSAgICAgKiBAcGFyYW0gZ3JhbW1hclBvb2wgVGhlIGdyYW1tYXIgcG9vbCB0byB1c2UuCi0gICAgICovCi0gICAgcHVibGljIE5vblZhbGlkYXRpbmdDb25maWd1cmF0aW9uKFN5bWJvbFRhYmxlIHN5bWJvbFRhYmxlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MR3JhbW1hclBvb2wgZ3JhbW1hclBvb2wpIHsKLSAgICAgICAgdGhpcyhzeW1ib2xUYWJsZSwgZ3JhbW1hclBvb2wsIG51bGwpOwotICAgIH0gLy8gPGluaXQ+KFN5bWJvbFRhYmxlLFhNTEdyYW1tYXJQb29sKQotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0cyBhIHBhcnNlciBjb25maWd1cmF0aW9uIHVzaW5nIHRoZSBzcGVjaWZpZWQgc3ltYm9sIHRhYmxlLAotICAgICAqIGdyYW1tYXIgcG9vbCwgYW5kIHBhcmVudCBzZXR0aW5ncy4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPlJFVklTSVQ6PC9zdHJvbmc+Ci0gICAgICogR3JhbW1hciBwb29sIHdpbGwgYmUgdXBkYXRlZCB3aGVuIHRoZSBuZXcgdmFsaWRhdGlvbiBlbmdpbmUgaXMKLSAgICAgKiBpbXBsZW1lbnRlZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzeW1ib2xUYWJsZSAgICBUaGUgc3ltYm9sIHRhYmxlIHRvIHVzZS4KLSAgICAgKiBAcGFyYW0gZ3JhbW1hclBvb2wgICAgVGhlIGdyYW1tYXIgcG9vbCB0byB1c2UuCi0gICAgICogQHBhcmFtIHBhcmVudFNldHRpbmdzIFRoZSBwYXJlbnQgc2V0dGluZ3MuCi0gICAgICovCi0gICAgcHVibGljIE5vblZhbGlkYXRpbmdDb25maWd1cmF0aW9uKFN5bWJvbFRhYmxlIHN5bWJvbFRhYmxlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MR3JhbW1hclBvb2wgZ3JhbW1hclBvb2wsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxDb21wb25lbnRNYW5hZ2VyIHBhcmVudFNldHRpbmdzKSB7Ci0gICAgICAgIHN1cGVyKHN5bWJvbFRhYmxlLCBwYXJlbnRTZXR0aW5ncyk7Ci0KLSAgICAgICAgLy8gYWRkIGRlZmF1bHQgcmVjb2duaXplZCBmZWF0dXJlcwotICAgICAgICBmaW5hbCBTdHJpbmdbXSByZWNvZ25pemVkRmVhdHVyZXMgPSB7Ci0gICAgICAgICAgICAgICAgUEFSU0VSX1NFVFRJTkdTLAotICAgICAgICAgICAgICAgICAgICAgICAgTkFNRVNQQUNFUywKLSAgICAgICAgICAgIC8vV0FSTl9PTl9EVVBMSUNBVEVfQVRUREVGLCAgICAgLy8gZnJvbSBYTUxEVERTY2FubmVySW1wbAotICAgICAgICAgICAgLy9XQVJOX09OX1VOREVDTEFSRURfRUxFTURFRiwgICAvLyBmcm9tIFhNTERURFNjYW5uZXJJbXBsCi0gICAgICAgICAgICAvL0FMTE9XX0pBVkFfRU5DT0RJTkdTLCAgICAgICAgIC8vIGZyb20gWE1MRW50aXR5TWFuYWdlcgotICAgICAgICAgICAgQ09OVElOVUVfQUZURVJfRkFUQUxfRVJST1IsCi0gICAgICAgICAgICAvL0xPQURfRVhURVJOQUxfRFRELCAgICAvLyBmcm9tIFhNTERURFNjYW5uZXJJbXBsCi0gICAgICAgICAgICAvL05PVElGWV9CVUlMVElOX1JFRlMsICAvLyBmcm9tIFhNTERvY3VtZW50RnJhZ21lbnRTY2FubmVySW1wbAotICAgICAgICAgICAgLy9OT1RJRllfQ0hBUl9SRUZTLCAgICAgICAgIC8vIGZyb20gWE1MRG9jdW1lbnRGcmFnbWVudFNjYW5uZXJJbXBsCi0gICAgICAgICAgICAvL1dBUk5fT05fRFVQTElDQVRFX0VOVElUWURFRiAgIC8vIGZyb20gWE1MRW50aXR5TWFuYWdlcgotICAgICAgICB9OwotICAgICAgICBhZGRSZWNvZ25pemVkRmVhdHVyZXMocmVjb2duaXplZEZlYXR1cmVzKTsKLQotICAgICAgICAvLyBzZXQgc3RhdGUgZm9yIGRlZmF1bHQgZmVhdHVyZXMKLSAgICAgICAgLy9zZXRGZWF0dXJlKFdBUk5fT05fRFVQTElDQVRFX0FUVERFRiwgZmFsc2UpOyAgLy8gZnJvbSBYTUxEVERTY2FubmVySW1wbAotICAgICAgICAvL3NldEZlYXR1cmUoV0FSTl9PTl9VTkRFQ0xBUkVEX0VMRU1ERUYsIGZhbHNlKTsgICAgLy8gZnJvbSBYTUxEVERTY2FubmVySW1wbAotICAgICAgICAvL3NldEZlYXR1cmUoQUxMT1dfSkFWQV9FTkNPRElOR1MsIGZhbHNlKTsgICAgICAvLyBmcm9tIFhNTEVudGl0eU1hbmFnZXIKLSAgICAgICAgZkZlYXR1cmVzLnB1dChDT05USU5VRV9BRlRFUl9GQVRBTF9FUlJPUiwgQm9vbGVhbi5GQUxTRSk7Ci0gICAgICAgICAgICAgICAgZkZlYXR1cmVzLnB1dChQQVJTRVJfU0VUVElOR1MsIEJvb2xlYW4uVFJVRSk7Ci0gICAgICAgICAgICAgICAgZkZlYXR1cmVzLnB1dChOQU1FU1BBQ0VTLCBCb29sZWFuLlRSVUUpOwotICAgICAgICAvL3NldEZlYXR1cmUoTE9BRF9FWFRFUk5BTF9EVEQsIHRydWUpOyAgICAgIC8vIGZyb20gWE1MRFREU2Nhbm5lckltcGwKLSAgICAgICAgLy9zZXRGZWF0dXJlKE5PVElGWV9CVUlMVElOX1JFRlMsIGZhbHNlKTsgICAvLyBmcm9tIFhNTERvY3VtZW50RnJhZ21lbnRTY2FubmVySW1wbAotICAgICAgICAvL3NldEZlYXR1cmUoTk9USUZZX0NIQVJfUkVGUywgZmFsc2UpOyAgICAgIC8vIGZyb20gWE1MRG9jdW1lbnRGcmFnbWVudFNjYW5uZXJJbXBsCi0gICAgICAgIC8vc2V0RmVhdHVyZShXQVJOX09OX0RVUExJQ0FURV9FTlRJVFlERUYsIGZhbHNlKTsgICAvLyBmcm9tIFhNTEVudGl0eU1hbmFnZXIKLQotICAgICAgICAvLyBhZGQgZGVmYXVsdCByZWNvZ25pemVkIHByb3BlcnRpZXMKLSAgICAgICAgZmluYWwgU3RyaW5nW10gcmVjb2duaXplZFByb3BlcnRpZXMgPSB7Ci0gICAgICAgICAgICBFUlJPUl9SRVBPUlRFUiwKLSAgICAgICAgICAgIEVOVElUWV9NQU5BR0VSLAotICAgICAgICAgICAgRE9DVU1FTlRfU0NBTk5FUiwKLSAgICAgICAgICAgIERURF9TQ0FOTkVSLAotICAgICAgICAgICAgRFREX1ZBTElEQVRPUiwKLSAgICAgICAgICAgIE5BTUVTUEFDRV9CSU5ERVIsCi0gICAgICAgICAgICBYTUxHUkFNTUFSX1BPT0wsCi0gICAgICAgICAgICBEQVRBVFlQRV9WQUxJREFUT1JfRkFDVE9SWSwKLSAgICAgICAgICAgIFZBTElEQVRJT05fTUFOQUdFUiwKLSAgICAgICAgICAgIExPQ0FMRSwKLSAgICAgICAgICAgIFNFQ1VSSVRZX01BTkFHRVIsCi0gICAgICAgICAgICBYTUxfU0VDVVJJVFlfUFJPUEVSVFlfTUFOQUdFUgotICAgICAgICB9OwotICAgICAgICBhZGRSZWNvZ25pemVkUHJvcGVydGllcyhyZWNvZ25pemVkUHJvcGVydGllcyk7Ci0KLSAgICAgICAgZkdyYW1tYXJQb29sID0gZ3JhbW1hclBvb2w7Ci0gICAgICAgIGlmKGZHcmFtbWFyUG9vbCAhPSBudWxsKXsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZQcm9wZXJ0aWVzLnB1dChYTUxHUkFNTUFSX1BPT0wsIGZHcmFtbWFyUG9vbCk7Ci0gICAgICAgIH0KLQotICAgICAgICBmRW50aXR5TWFuYWdlciA9IGNyZWF0ZUVudGl0eU1hbmFnZXIoKTsKLSAgICAgICAgICAgICAgICBmUHJvcGVydGllcy5wdXQoRU5USVRZX01BTkFHRVIsIGZFbnRpdHlNYW5hZ2VyKTsKLSAgICAgICAgYWRkQ29tcG9uZW50KGZFbnRpdHlNYW5hZ2VyKTsKLQotICAgICAgICBmRXJyb3JSZXBvcnRlciA9IGNyZWF0ZUVycm9yUmVwb3J0ZXIoKTsKLSAgICAgICAgZkVycm9yUmVwb3J0ZXIuc2V0RG9jdW1lbnRMb2NhdG9yKGZFbnRpdHlNYW5hZ2VyLmdldEVudGl0eVNjYW5uZXIoKSk7Ci0gICAgICAgICAgICAgICAgZlByb3BlcnRpZXMucHV0KEVSUk9SX1JFUE9SVEVSLCBmRXJyb3JSZXBvcnRlcik7Ci0gICAgICAgIGFkZENvbXBvbmVudChmRXJyb3JSZXBvcnRlcik7Ci0KLSAgICAgICAgLy8gdGhpcyBjb25maWd1cmF0aW9uIGRlbGF5cyBjcmVhdGlvbiBvZiB0aGUgc2Nhbm5lcgotICAgICAgICAvLyB0aWxsIGl0IGlzIGtub3duIGlmIG5hbWVzcGFjZSBwcm9jZXNzaW5nIHNob3VsZCBiZSBwZXJmb3JtZWQKLQotICAgICAgICBmRFREU2Nhbm5lciA9IGNyZWF0ZURURFNjYW5uZXIoKTsKLSAgICAgICAgaWYgKGZEVERTY2FubmVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZQcm9wZXJ0aWVzLnB1dChEVERfU0NBTk5FUiwgZkRURFNjYW5uZXIpOwotICAgICAgICAgICAgaWYgKGZEVERTY2FubmVyIGluc3RhbmNlb2YgWE1MQ29tcG9uZW50KSB7Ci0gICAgICAgICAgICAgICAgYWRkQ29tcG9uZW50KChYTUxDb21wb25lbnQpZkRURFNjYW5uZXIpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgZkRhdGF0eXBlVmFsaWRhdG9yRmFjdG9yeSA9IGNyZWF0ZURhdGF0eXBlVmFsaWRhdG9yRmFjdG9yeSgpOwotICAgICAgICBpZiAoZkRhdGF0eXBlVmFsaWRhdG9yRmFjdG9yeSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmUHJvcGVydGllcy5wdXQoREFUQVRZUEVfVkFMSURBVE9SX0ZBQ1RPUlksCi0gICAgICAgICAgICAgICAgICAgICAgICBmRGF0YXR5cGVWYWxpZGF0b3JGYWN0b3J5KTsKLSAgICAgICAgfQotICAgICAgICBmVmFsaWRhdGlvbk1hbmFnZXIgPSBjcmVhdGVWYWxpZGF0aW9uTWFuYWdlcigpOwotCi0gICAgICAgIGlmIChmVmFsaWRhdGlvbk1hbmFnZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgZlByb3BlcnRpZXMucHV0KFZBTElEQVRJT05fTUFOQUdFUiwgZlZhbGlkYXRpb25NYW5hZ2VyKTsKLSAgICAgICAgfQotICAgICAgICAvLyBhZGQgbWVzc2FnZSBmb3JtYXR0ZXJzCi0gICAgICAgIGlmIChmRXJyb3JSZXBvcnRlci5nZXRNZXNzYWdlRm9ybWF0dGVyKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTikgPT0gbnVsbCkgewotICAgICAgICAgICAgWE1MTWVzc2FnZUZvcm1hdHRlciB4bWZ0ID0gbmV3IFhNTE1lc3NhZ2VGb3JtYXR0ZXIoKTsKLSAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnB1dE1lc3NhZ2VGb3JtYXR0ZXIoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLCB4bWZ0KTsKLSAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnB1dE1lc3NhZ2VGb3JtYXR0ZXIoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxOU19ET01BSU4sIHhtZnQpOwotICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBmQ29uZmlnVXBkYXRlZCA9IGZhbHNlOwotCi0gICAgICAgIC8vIHNldCBsb2NhbGUKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIHNldExvY2FsZShMb2NhbGUuZ2V0RGVmYXVsdCgpKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoWE5JRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIC8vIGRvIG5vdGhpbmcKLSAgICAgICAgICAgIC8vIFJFVklTSVQ6IFdoYXQgaXMgdGhlIHJpZ2h0IHRoaW5nIHRvIGRvPyAtQWMKLSAgICAgICAgfQotCi0gICAgICAgIHNldFByb3BlcnR5KFhNTF9TRUNVUklUWV9QUk9QRVJUWV9NQU5BR0VSLCBuZXcgWE1MU2VjdXJpdHlQcm9wZXJ0eU1hbmFnZXIoKSk7Ci0gICAgfSAvLyA8aW5pdD4oU3ltYm9sVGFibGUsWE1MR3JhbW1hclBvb2wpCi0KLSAgICAvLwotICAgIC8vIFB1YmxpYyBtZXRob2RzCi0gICAgLy8KLSAgICAgICAgcHVibGljIHZvaWQgc2V0RmVhdHVyZShTdHJpbmcgZmVhdHVyZUlkLCBib29sZWFuIHN0YXRlKQotICAgICAgICAgICAgICAgIHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIHsKLSAgICAgICAgICAgICAgICBmQ29uZmlnVXBkYXRlZCA9IHRydWU7Ci0gICAgICAgICAgICAgICAgc3VwZXIuc2V0RmVhdHVyZShmZWF0dXJlSWQsIHN0YXRlKTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyBQcm9wZXJ0eVN0YXRlIGdldFByb3BlcnR5U3RhdGUoU3RyaW5nIHByb3BlcnR5SWQpCi0gICAgICAgICAgICAgdGhyb3dzIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gewotICAgICAgICAgICAgIGlmIChMT0NBTEUuZXF1YWxzKHByb3BlcnR5SWQpKSB7Ci0gICAgICAgICAgICAgICAgIHJldHVybiBQcm9wZXJ0eVN0YXRlLmlzKGdldExvY2FsZSgpKTsKLSAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmdldFByb3BlcnR5U3RhdGUocHJvcGVydHlJZCk7Ci0gICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIHZvaWQgc2V0UHJvcGVydHkoU3RyaW5nIHByb3BlcnR5SWQsIE9iamVjdCB2YWx1ZSkKLSAgICAgICAgICAgICB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICAgZkNvbmZpZ1VwZGF0ZWQgPSB0cnVlOwotICAgICAgICAgICAgIGlmIChMT0NBTEUuZXF1YWxzKHByb3BlcnR5SWQpKSB7Ci0gICAgICAgICAgICAgICAgIHNldExvY2FsZSgoTG9jYWxlKSB2YWx1ZSk7Ci0gICAgICAgICAgICAgfQotICAgICAgICAgICAgIHN1cGVyLnNldFByb3BlcnR5KHByb3BlcnR5SWQsIHZhbHVlKTsKLSAgICAgICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldCB0aGUgbG9jYWxlIHRvIHVzZSBmb3IgbWVzc2FnZXMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbG9jYWxlIFRoZSBsb2NhbGUgb2JqZWN0IHRvIHVzZSBmb3IgbG9jYWxpemF0aW9uIG9mIG1lc3NhZ2VzLgotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBYTklFeGNlcHRpb24gVGhyb3duIGlmIHRoZSBwYXJzZXIgZG9lcyBub3Qgc3VwcG9ydCB0aGUKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBzcGVjaWZpZWQgbG9jYWxlLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldExvY2FsZShMb2NhbGUgbG9jYWxlKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgc3VwZXIuc2V0TG9jYWxlKGxvY2FsZSk7Ci0gICAgICAgIGZFcnJvclJlcG9ydGVyLnNldExvY2FsZShsb2NhbGUpOwotICAgIH0gLy8gc2V0TG9jYWxlKExvY2FsZSkKLQotICAgICAgICBwdWJsaWMgRmVhdHVyZVN0YXRlIGdldEZlYXR1cmVTdGF0ZShTdHJpbmcgZmVhdHVyZUlkKQotICAgICAgICAgICAgICAgIHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIG1ha2UgdGhpcyBmZWF0dXJlIHNwZWNpYWwKLSAgICAgICAgICAgICAgICBpZiAoZmVhdHVyZUlkLmVxdWFscyhQQVJTRVJfU0VUVElOR1MpKXsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBGZWF0dXJlU3RhdGUuaXMoZkNvbmZpZ1VwZGF0ZWQpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICByZXR1cm4gc3VwZXIuZ2V0RmVhdHVyZVN0YXRlKGZlYXR1cmVJZCk7Ci0KLSAgICAgICAgfSAvLyBnZXRGZWF0dXJlKFN0cmluZyk6Ym9vbGVhbgotICAgIC8vCi0gICAgLy8gWE1MUHVsbFBhcnNlckNvbmZpZ3VyYXRpb24gbWV0aG9kcwotICAgIC8vCi0KLSAgICAvLyBwYXJzaW5nCi0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSBpbnB1dCBzb3VyY2UgZm9yIHRoZSBkb2N1bWVudCB0byBwYXJzZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBpbnB1dFNvdXJjZSBUaGUgZG9jdW1lbnQncyBpbnB1dCBzb3VyY2UuCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gVGhyb3duIGlmIHRoZXJlIGlzIGEKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZpZ3VyYXRpb24gZXJyb3Igd2hlbiBpbml0aWFsaXppbmcgdGhlCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICBwYXJzZXIuCi0gICAgICogQGV4Y2VwdGlvbiBJT0V4Y2VwdGlvbiBUaHJvd24gb24gSS9PIGVycm9yLgotICAgICAqCi0gICAgICogQHNlZSAjcGFyc2UoYm9vbGVhbikKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRJbnB1dFNvdXJjZShYTUxJbnB1dFNvdXJjZSBpbnB1dFNvdXJjZSkKLSAgICAgICAgdGhyb3dzIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKLQotICAgICAgICAvLyBSRVZJU0lUOiB0aGlzIG1ldGhvZCB1c2VkIHRvIHJlc2V0IGFsbCB0aGUgY29tcG9uZW50cyBhbmQKLSAgICAgICAgLy8gICAgICAgICAgY29uc3RydWN0IHRoZSBwaXBlbGluZS4gTm93IHJlc2V0KCkgaXMgY2FsbGVkCi0gICAgICAgIC8vICAgICAgICAgIGluIHBhcnNlIChib29sZWFuKSBqdXN0IGJlZm9yZSB3ZSBwYXJzZSB0aGUgZG9jdW1lbnQKLSAgICAgICAgLy8gICAgICAgICAgU2hvdWxkIHRoaXMgbWV0aG9kIHN0aWxsIHRocm93IGV4Y2VwdGlvbnMuLj8KLQotICAgICAgICBmSW5wdXRTb3VyY2UgPSBpbnB1dFNvdXJjZTsKLQotICAgIH0gLy8gc2V0SW5wdXRTb3VyY2UoWE1MSW5wdXRTb3VyY2UpCi0KLSAgICAvKioKLSAgICAgKiBQYXJzZXMgdGhlIGRvY3VtZW50IGluIGEgcHVsbCBwYXJzaW5nIGZhc2hpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29tcGxldGUgVHJ1ZSBpZiB0aGUgcHVsbCBwYXJzZXIgc2hvdWxkIHBhcnNlIHRoZQotICAgICAqICAgICAgICAgICAgICAgICByZW1haW5pbmcgZG9jdW1lbnQgY29tcGxldGVseS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVHJ1ZSBpZiB0aGVyZSBpcyBtb3JlIGRvY3VtZW50IHRvIHBhcnNlLgotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBYTklFeGNlcHRpb24gQW55IFhOSSBleGNlcHRpb24sIHBvc3NpYmx5IHdyYXBwaW5nCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgYW5vdGhlciBleGNlcHRpb24uCi0gICAgICogQGV4Y2VwdGlvbiBJT0V4Y2VwdGlvbiAgQW4gSU8gZXhjZXB0aW9uIGZyb20gdGhlIHBhcnNlciwgcG9zc2libHkKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBmcm9tIGEgYnl0ZSBzdHJlYW0gb3IgY2hhcmFjdGVyIHN0cmVhbQotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIHN1cHBsaWVkIGJ5IHRoZSBwYXJzZXIuCi0gICAgICoKLSAgICAgKiBAc2VlICNzZXRJbnB1dFNvdXJjZQotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIHBhcnNlKGJvb2xlYW4gY29tcGxldGUpIHRocm93cyBYTklFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKLSAgICAgICAgLy8KLSAgICAgICAgLy8gcmVzZXQgYW5kIGNvbmZpZ3VyZSBwaXBlbGluZSBhbmQgc2V0IElucHV0U291cmNlLgotICAgICAgICBpZiAoZklucHV0U291cmNlICE9bnVsbCkgewotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAvLyByZXNldHMgYW5kIHNldHMgdGhlIHBpcGVsaW5lLgotICAgICAgICAgICAgICAgIHJlc2V0KCk7Ci0gICAgICAgICAgICAgICAgZlNjYW5uZXIuc2V0SW5wdXRTb3VyY2UoZklucHV0U291cmNlKTsKLSAgICAgICAgICAgICAgICBmSW5wdXRTb3VyY2UgPSBudWxsOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2F0Y2ggKFhOSUV4Y2VwdGlvbiBleCkgewotICAgICAgICAgICAgICAgIGlmIChQUklOVF9FWENFUFRJT05fU1RBQ0tfVFJBQ0UpCi0gICAgICAgICAgICAgICAgICAgIGV4LnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgICAgICAgICAgIHRocm93IGV4OwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7Ci0gICAgICAgICAgICAgICAgaWYgKFBSSU5UX0VYQ0VQVElPTl9TVEFDS19UUkFDRSkKLSAgICAgICAgICAgICAgICAgICAgZXgucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgICAgICAgICAgdGhyb3cgZXg7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiBleCkgewotICAgICAgICAgICAgICAgIGlmIChQUklOVF9FWENFUFRJT05fU1RBQ0tfVFJBQ0UpCi0gICAgICAgICAgICAgICAgICAgIGV4LnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgICAgICAgICAgIHRocm93IGV4OwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkgewotICAgICAgICAgICAgICAgIGlmIChQUklOVF9FWENFUFRJT05fU1RBQ0tfVFJBQ0UpCi0gICAgICAgICAgICAgICAgICAgIGV4LnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgICAgICAgICAgIHRocm93IG5ldyBYTklFeGNlcHRpb24oZXgpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIHJldHVybiBmU2Nhbm5lci5zY2FuRG9jdW1lbnQoY29tcGxldGUpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChYTklFeGNlcHRpb24gZXgpIHsKLSAgICAgICAgICAgIGlmIChQUklOVF9FWENFUFRJT05fU1RBQ0tfVFJBQ0UpCi0gICAgICAgICAgICAgICAgZXgucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgICAgICB0aHJvdyBleDsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKLSAgICAgICAgICAgIGlmIChQUklOVF9FWENFUFRJT05fU1RBQ0tfVFJBQ0UpCi0gICAgICAgICAgICAgICAgZXgucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgICAgICB0aHJvdyBleDsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiBleCkgewotICAgICAgICAgICAgaWYgKFBSSU5UX0VYQ0VQVElPTl9TVEFDS19UUkFDRSkKLSAgICAgICAgICAgICAgICBleC5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgICAgICAgIHRocm93IGV4OwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpIHsKLSAgICAgICAgICAgIGlmIChQUklOVF9FWENFUFRJT05fU1RBQ0tfVFJBQ0UpCi0gICAgICAgICAgICAgICAgZXgucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWE5JRXhjZXB0aW9uKGV4KTsKLSAgICAgICAgfQotCi0gICAgfSAvLyBwYXJzZShib29sZWFuKTpib29sZWFuCi0KLSAgICAvKioKLSAgICAgKiBJZiB0aGUgYXBwbGljYXRpb24gZGVjaWRlcyB0byB0ZXJtaW5hdGUgcGFyc2luZyBiZWZvcmUgdGhlIHhtbCBkb2N1bWVudAotICAgICAqIGlzIGZ1bGx5IHBhcnNlZCwgdGhlIGFwcGxpY2F0aW9uIHNob3VsZCBjYWxsIHRoaXMgbWV0aG9kIHRvIGZyZWUgYW55Ci0gICAgICogcmVzb3VyY2UgYWxsb2NhdGVkIGR1cmluZyBwYXJzaW5nLiBGb3IgZXhhbXBsZSwgY2xvc2UgYWxsIG9wZW5lZCBzdHJlYW1zLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGNsZWFudXAoKSB7Ci0gICAgICAgIGZFbnRpdHlNYW5hZ2VyLmNsb3NlUmVhZGVycygpOwotICAgIH0KLQotICAgIC8vCi0gICAgLy8gWE1MUGFyc2VyQ29uZmlndXJhdGlvbiBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFBhcnNlcyB0aGUgc3BlY2lmaWVkIGlucHV0IHNvdXJjZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzb3VyY2UgVGhlIGlucHV0IHNvdXJjZS4KLSAgICAgKgotICAgICAqIEBleGNlcHRpb24gWE5JRXhjZXB0aW9uIFRocm93cyBleGNlcHRpb24gb24gWE5JIGVycm9yLgotICAgICAqIEBleGNlcHRpb24gamF2YS5pby5JT0V4Y2VwdGlvbiBUaHJvd3MgZXhjZXB0aW9uIG9uIGkvbyBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBwYXJzZShYTUxJbnB1dFNvdXJjZSBzb3VyY2UpIHRocm93cyBYTklFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKLQotICAgICAgICBpZiAoZlBhcnNlSW5Qcm9ncmVzcykgewotICAgICAgICAgICAgLy8gUkVWSVNJVCAtIG5lZWQgdG8gYWRkIG5ldyBlcnJvciBtZXNzYWdlCi0gICAgICAgICAgICB0aHJvdyBuZXcgWE5JRXhjZXB0aW9uKCJGV0swMDUgcGFyc2UgbWF5IG5vdCBiZSBjYWxsZWQgd2hpbGUgcGFyc2luZy4iKTsKLSAgICAgICAgfQotICAgICAgICBmUGFyc2VJblByb2dyZXNzID0gdHJ1ZTsKLQotICAgICAgICB0cnkgewotICAgICAgICAgICAgc2V0SW5wdXRTb3VyY2Uoc291cmNlKTsKLSAgICAgICAgICAgIHBhcnNlKHRydWUpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChYTklFeGNlcHRpb24gZXgpIHsKLSAgICAgICAgICAgIGlmIChQUklOVF9FWENFUFRJT05fU1RBQ0tfVFJBQ0UpCi0gICAgICAgICAgICAgICAgZXgucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgICAgICB0aHJvdyBleDsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKLSAgICAgICAgICAgIGlmIChQUklOVF9FWENFUFRJT05fU1RBQ0tfVFJBQ0UpCi0gICAgICAgICAgICAgICAgZXgucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgICAgICB0aHJvdyBleDsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiBleCkgewotICAgICAgICAgICAgaWYgKFBSSU5UX0VYQ0VQVElPTl9TVEFDS19UUkFDRSkKLSAgICAgICAgICAgICAgICBleC5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgICAgICAgIHRocm93IGV4OwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpIHsKLSAgICAgICAgICAgIGlmIChQUklOVF9FWENFUFRJT05fU1RBQ0tfVFJBQ0UpCi0gICAgICAgICAgICAgICAgZXgucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWE5JRXhjZXB0aW9uKGV4KTsKLSAgICAgICAgfQotICAgICAgICBmaW5hbGx5IHsKLSAgICAgICAgICAgIGZQYXJzZUluUHJvZ3Jlc3MgPSBmYWxzZTsKLSAgICAgICAgICAgIC8vIGNsb3NlIGFsbCBzdHJlYW1zIG9wZW5lZCBieSB4ZXJjZXMKLSAgICAgICAgICAgIHRoaXMuY2xlYW51cCgpOwotICAgICAgICB9Ci0KLSAgICB9IC8vIHBhcnNlKElucHV0U291cmNlKQotCi0gICAgLy8KLSAgICAvLyBQcm90ZWN0ZWQgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBSZXNldCBhbGwgY29tcG9uZW50cyBiZWZvcmUgcGFyc2luZy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBpZiBhbiBlcnJvciBvY2N1cnMgZHVyaW5nIGluaXRpYWxpemF0aW9uLgotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIHJlc2V0KCkgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgaWYgKGZWYWxpZGF0aW9uTWFuYWdlciAhPSBudWxsKQotICAgICAgICAgICAgZlZhbGlkYXRpb25NYW5hZ2VyLnJlc2V0KCk7Ci0gICAgICAgIC8vIGNvbmZpZ3VyZSB0aGUgcGlwZWxpbmUgYW5kIGluaXRpYWxpemUgdGhlIGNvbXBvbmVudHMKLSAgICAgICAgY29uZmlndXJlUGlwZWxpbmUoKTsKLSAgICAgICAgc3VwZXIucmVzZXQoKTsKLQotICAgIH0gLy8gcmVzZXQoKQotCi0gICAgLyoqIENvbmZpZ3VyZXMgdGhlIHBpcGVsaW5lLiAqLwotICAgIHByb3RlY3RlZCB2b2lkIGNvbmZpZ3VyZVBpcGVsaW5lKCkgewotICAgICAgICAvLyBjcmVhdGUgYXBwcm9wcmlhdGUgc2Nhbm5lcgotICAgICAgICAvLyBhbmQgcmVnaXN0ZXIgaXQgYXMgb25lIG9mIHRoZSBjb21wb25lbnRzLgotICAgICAgICBpZiAoZkZlYXR1cmVzLmdldChOQU1FU1BBQ0VTKSA9PSBCb29sZWFuLlRSVUUpIHsKLSAgICAgICAgICAgIGlmIChmTmFtZXNwYWNlU2Nhbm5lciA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZk5hbWVzcGFjZVNjYW5uZXIgPSBuZXcgWE1MTlNEb2N1bWVudFNjYW5uZXJJbXBsKCk7Ci0gICAgICAgICAgICAgICAgYWRkQ29tcG9uZW50KChYTUxDb21wb25lbnQpZk5hbWVzcGFjZVNjYW5uZXIpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZlByb3BlcnRpZXMucHV0KERPQ1VNRU5UX1NDQU5ORVIsIGZOYW1lc3BhY2VTY2FubmVyKTsKLSAgICAgICAgICAgIGZOYW1lc3BhY2VTY2FubmVyLnNldERURFZhbGlkYXRvcihudWxsKTsKLSAgICAgICAgICAgIGZTY2FubmVyID0gZk5hbWVzcGFjZVNjYW5uZXI7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBpZiAoZk5vbk5TU2Nhbm5lciA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZk5vbk5TU2Nhbm5lciA9IG5ldyBYTUxEb2N1bWVudFNjYW5uZXJJbXBsKCk7Ci0gICAgICAgICAgICAgICAgYWRkQ29tcG9uZW50KChYTUxDb21wb25lbnQpZk5vbk5TU2Nhbm5lcik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmUHJvcGVydGllcy5wdXQoRE9DVU1FTlRfU0NBTk5FUiwgZk5vbk5TU2Nhbm5lcik7Ci0gICAgICAgICAgICBmU2Nhbm5lciA9IGZOb25OU1NjYW5uZXI7Ci0gICAgICAgIH0KLQotICAgICAgICBmU2Nhbm5lci5zZXREb2N1bWVudEhhbmRsZXIoZkRvY3VtZW50SGFuZGxlcik7Ci0gICAgICAgIGZMYXN0Q29tcG9uZW50ID0gZlNjYW5uZXI7Ci0gICAgICAgIC8vIHNldHVwIGR0ZCBwaXBlbGluZQotICAgICAgICBpZiAoZkRURFNjYW5uZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZEVERTY2FubmVyLnNldERUREhhbmRsZXIoZkRUREhhbmRsZXIpOwotICAgICAgICAgICAgICAgIGZEVERTY2FubmVyLnNldERURENvbnRlbnRNb2RlbEhhbmRsZXIoZkRURENvbnRlbnRNb2RlbEhhbmRsZXIpOwotICAgICAgICB9Ci0KLQotICAgIH0gLy8gY29uZmlndXJlUGlwZWxpbmUoKQotCi0gICAgLy8gZmVhdHVyZXMgYW5kIHByb3BlcnRpZXMKLQotICAgIC8qKgotICAgICAqIENoZWNrIGEgZmVhdHVyZS4gSWYgZmVhdHVyZSBpcyBrbm93IGFuZCBzdXBwb3J0ZWQsIHRoaXMgbWV0aG9kIHNpbXBseQotICAgICAqIHJldHVybnMuIE90aGVyd2lzZSwgdGhlIGFwcHJvcHJpYXRlIGV4Y2VwdGlvbiBpcyB0aHJvd24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZmVhdHVyZUlkIFRoZSB1bmlxdWUgaWRlbnRpZmllciAoVVJJKSBvZiB0aGUgZmVhdHVyZS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBUaHJvd24gZm9yIGNvbmZpZ3VyYXRpb24gZXJyb3IuCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluIGdlbmVyYWwsIGNvbXBvbmVudHMgc2hvdWxkCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9ubHkgdGhyb3cgdGhpcyBleGNlcHRpb24gaWYKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXQgaXMgPHN0cm9uZz5yZWFsbHk8L3N0cm9uZz4KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYSBjcml0aWNhbCBlcnJvci4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgRmVhdHVyZVN0YXRlIGNoZWNrRmVhdHVyZShTdHJpbmcgZmVhdHVyZUlkKQotICAgICAgICB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gWGVyY2VzIEZlYXR1cmVzCi0gICAgICAgIC8vCi0KLSAgICAgICAgaWYgKGZlYXR1cmVJZC5zdGFydHNXaXRoKENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVgpKSB7Ci0gICAgICAgICAgICBmaW5hbCBpbnQgc3VmZml4TGVuZ3RoID0gZmVhdHVyZUlkLmxlbmd0aCgpIC0gQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWC5sZW5ndGgoKTsKLQotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIC8vIGh0dHA6Ly9hcGFjaGUub3JnL3htbC9mZWF0dXJlcy92YWxpZGF0aW9uL2R5bmFtaWMKLSAgICAgICAgICAgIC8vICAgQWxsb3dzIHRoZSBwYXJzZXIgdG8gdmFsaWRhdGUgYSBkb2N1bWVudCBvbmx5IHdoZW4gaXQKLSAgICAgICAgICAgIC8vICAgY29udGFpbnMgYSBncmFtbWFyLiBWYWxpZGF0aW9uIGlzIHR1cm5lZCBvbi9vZmYgYmFzZWQKLSAgICAgICAgICAgIC8vICAgb24gZWFjaCBkb2N1bWVudCBpbnN0YW5jZSwgYXV0b21hdGljYWxseS4KLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICBpZiAoc3VmZml4TGVuZ3RoID09IENvbnN0YW50cy5EWU5BTUlDX1ZBTElEQVRJT05fRkVBVFVSRS5sZW5ndGgoKSAmJgotICAgICAgICAgICAgICAgIGZlYXR1cmVJZC5lbmRzV2l0aChDb25zdGFudHMuRFlOQU1JQ19WQUxJREFUSU9OX0ZFQVRVUkUpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIEZlYXR1cmVTdGF0ZS5SRUNPR05JWkVEOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIC8vIGh0dHA6Ly9hcGFjaGUub3JnL3htbC9mZWF0dXJlcy92YWxpZGF0aW9uL2RlZmF1bHQtYXR0cmlidXRlLXZhbHVlcwotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIGlmIChzdWZmaXhMZW5ndGggPT0gQ29uc3RhbnRzLkRFRkFVTFRfQVRUUklCVVRFX1ZBTFVFU19GRUFUVVJFLmxlbmd0aCgpICYmCi0gICAgICAgICAgICAgICAgZmVhdHVyZUlkLmVuZHNXaXRoKENvbnN0YW50cy5ERUZBVUxUX0FUVFJJQlVURV9WQUxVRVNfRkVBVFVSRSkpIHsKLSAgICAgICAgICAgICAgICAvLyBSRVZJU0lUCi0gICAgICAgICAgICAgICAgcmV0dXJuIEZlYXR1cmVTdGF0ZS5OT1RfU1VQUE9SVEVEOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIC8vIGh0dHA6Ly9hcGFjaGUub3JnL3htbC9mZWF0dXJlcy92YWxpZGF0aW9uL2RlZmF1bHQtYXR0cmlidXRlLXZhbHVlcwotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIGlmIChzdWZmaXhMZW5ndGggPT0gQ29uc3RhbnRzLlZBTElEQVRFX0NPTlRFTlRfTU9ERUxTX0ZFQVRVUkUubGVuZ3RoKCkgJiYKLSAgICAgICAgICAgICAgICBmZWF0dXJlSWQuZW5kc1dpdGgoQ29uc3RhbnRzLlZBTElEQVRFX0NPTlRFTlRfTU9ERUxTX0ZFQVRVUkUpKSB7Ci0gICAgICAgICAgICAgICAgLy8gUkVWSVNJVAotICAgICAgICAgICAgICAgIHJldHVybiBGZWF0dXJlU3RhdGUuTk9UX1NVUFBPUlRFRDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAvLyBodHRwOi8vYXBhY2hlLm9yZy94bWwvZmVhdHVyZXMvdmFsaWRhdGlvbi9ub252YWxpZGF0aW5nL2xvYWQtZHRkLWdyYW1tYXIKLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICBpZiAoc3VmZml4TGVuZ3RoID09IENvbnN0YW50cy5MT0FEX0RURF9HUkFNTUFSX0ZFQVRVUkUubGVuZ3RoKCkgJiYKLSAgICAgICAgICAgICAgICBmZWF0dXJlSWQuZW5kc1dpdGgoQ29uc3RhbnRzLkxPQURfRFREX0dSQU1NQVJfRkVBVFVSRSkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gRmVhdHVyZVN0YXRlLlJFQ09HTklaRUQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLwotICAgICAgICAgICAgLy8gaHR0cDovL2FwYWNoZS5vcmcveG1sL2ZlYXR1cmVzL3ZhbGlkYXRpb24vbm9udmFsaWRhdGluZy9sb2FkLWV4dGVybmFsLWR0ZAotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIGlmIChzdWZmaXhMZW5ndGggPT0gQ29uc3RhbnRzLkxPQURfRVhURVJOQUxfRFREX0ZFQVRVUkUubGVuZ3RoKCkgJiYKLSAgICAgICAgICAgICAgICBmZWF0dXJlSWQuZW5kc1dpdGgoQ29uc3RhbnRzLkxPQURfRVhURVJOQUxfRFREX0ZFQVRVUkUpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIEZlYXR1cmVTdGF0ZS5SRUNPR05JWkVEOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgLy8gaHR0cDovL2FwYWNoZS5vcmcveG1sL2ZlYXR1cmVzL3ZhbGlkYXRpb24vZGVmYXVsdC1hdHRyaWJ1dGUtdmFsdWVzCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgaWYgKHN1ZmZpeExlbmd0aCA9PSBDb25zdGFudHMuVkFMSURBVEVfREFUQVRZUEVTX0ZFQVRVUkUubGVuZ3RoKCkgJiYKLSAgICAgICAgICAgICAgICBmZWF0dXJlSWQuZW5kc1dpdGgoQ29uc3RhbnRzLlZBTElEQVRFX0RBVEFUWVBFU19GRUFUVVJFKSkgewotICAgICAgICAgICAgICAgIHJldHVybiBGZWF0dXJlU3RhdGUuTk9UX1NVUFBPUlRFRDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIE5vdCByZWNvZ25pemVkCi0gICAgICAgIC8vCi0KLSAgICAgICAgcmV0dXJuIHN1cGVyLmNoZWNrRmVhdHVyZShmZWF0dXJlSWQpOwotCi0gICAgfSAvLyBjaGVja0ZlYXR1cmUoU3RyaW5nKQotCi0gICAgLyoqCi0gICAgICogQ2hlY2sgYSBwcm9wZXJ0eS4gSWYgdGhlIHByb3BlcnR5IGlzIGtub3cgYW5kIHN1cHBvcnRlZCwgdGhpcyBtZXRob2QKLSAgICAgKiBzaW1wbHkgcmV0dXJucy4gT3RoZXJ3aXNlLCB0aGUgYXBwcm9wcmlhdGUgZXhjZXB0aW9uIGlzIHRocm93bi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBwcm9wZXJ0eUlkIFRoZSB1bmlxdWUgaWRlbnRpZmllciAoVVJJKSBvZiB0aGUgcHJvcGVydHkKLSAgICAgKiAgICAgICAgICAgICAgICAgICBiZWluZyBzZXQuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gVGhyb3duIGZvciBjb25maWd1cmF0aW9uIGVycm9yLgotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbiBnZW5lcmFsLCBjb21wb25lbnRzIHNob3VsZAotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbmx5IHRocm93IHRoaXMgZXhjZXB0aW9uIGlmCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0IGlzIDxzdHJvbmc+cmVhbGx5PC9zdHJvbmc+Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGEgY3JpdGljYWwgZXJyb3IuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIFByb3BlcnR5U3RhdGUgY2hlY2tQcm9wZXJ0eShTdHJpbmcgcHJvcGVydHlJZCkKLSAgICAgICAgdGhyb3dzIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gewotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIFhlcmNlcyBQcm9wZXJ0aWVzCi0gICAgICAgIC8vCi0KLSAgICAgICAgaWYgKHByb3BlcnR5SWQuc3RhcnRzV2l0aChDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCkpIHsKLSAgICAgICAgICAgIGZpbmFsIGludCBzdWZmaXhMZW5ndGggPSBwcm9wZXJ0eUlkLmxlbmd0aCgpIC0gQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVgubGVuZ3RoKCk7Ci0KLSAgICAgICAgICAgIGlmIChzdWZmaXhMZW5ndGggPT0gQ29uc3RhbnRzLkRURF9TQ0FOTkVSX1BST1BFUlRZLmxlbmd0aCgpICYmCi0gICAgICAgICAgICAgICAgcHJvcGVydHlJZC5lbmRzV2l0aChDb25zdGFudHMuRFREX1NDQU5ORVJfUFJPUEVSVFkpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIFByb3BlcnR5U3RhdGUuUkVDT0dOSVpFRDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGlmIChwcm9wZXJ0eUlkLnN0YXJ0c1dpdGgoQ29uc3RhbnRzLkpBWFBfUFJPUEVSVFlfUFJFRklYKSkgewotICAgICAgICAgICAgZmluYWwgaW50IHN1ZmZpeExlbmd0aCA9IHByb3BlcnR5SWQubGVuZ3RoKCkgLSBDb25zdGFudHMuSkFYUF9QUk9QRVJUWV9QUkVGSVgubGVuZ3RoKCk7Ci0KLSAgICAgICAgICAgIGlmIChzdWZmaXhMZW5ndGggPT0gQ29uc3RhbnRzLlNDSEVNQV9TT1VSQ0UubGVuZ3RoKCkgJiYKLSAgICAgICAgICAgICAgICBwcm9wZXJ0eUlkLmVuZHNXaXRoKENvbnN0YW50cy5TQ0hFTUFfU09VUkNFKSkgewotICAgICAgICAgICAgICAgIHJldHVybiBQcm9wZXJ0eVN0YXRlLlJFQ09HTklaRUQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLwotICAgICAgICAvLyBOb3QgcmVjb2duaXplZAotICAgICAgICAvLwotCi0gICAgICAgIHJldHVybiBzdXBlci5jaGVja1Byb3BlcnR5KHByb3BlcnR5SWQpOwotCi0gICAgfSAvLyBjaGVja1Byb3BlcnR5KFN0cmluZykKLQotICAgIC8vIGZhY3RvcnkgbWV0aG9kcwotCi0gICAgLyoqIENyZWF0ZXMgYW4gZW50aXR5IG1hbmFnZXIuICovCi0gICAgcHJvdGVjdGVkIFhNTEVudGl0eU1hbmFnZXIgY3JlYXRlRW50aXR5TWFuYWdlcigpIHsKLSAgICAgICAgcmV0dXJuIG5ldyBYTUxFbnRpdHlNYW5hZ2VyKCk7Ci0gICAgfSAvLyBjcmVhdGVFbnRpdHlNYW5hZ2VyKCk6WE1MRW50aXR5TWFuYWdlcgotCi0gICAgLyoqIENyZWF0ZXMgYW4gZXJyb3IgcmVwb3J0ZXIuICovCi0gICAgcHJvdGVjdGVkIFhNTEVycm9yUmVwb3J0ZXIgY3JlYXRlRXJyb3JSZXBvcnRlcigpIHsKLSAgICAgICAgcmV0dXJuIG5ldyBYTUxFcnJvclJlcG9ydGVyKCk7Ci0gICAgfSAvLyBjcmVhdGVFcnJvclJlcG9ydGVyKCk6WE1MRXJyb3JSZXBvcnRlcgotCi0gICAgLyoqIENyZWF0ZSBhIGRvY3VtZW50IHNjYW5uZXIuICovCi0gICAgcHJvdGVjdGVkIFhNTERvY3VtZW50U2Nhbm5lciBjcmVhdGVEb2N1bWVudFNjYW5uZXIoKSB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0gLy8gY3JlYXRlRG9jdW1lbnRTY2FubmVyKCk6WE1MRG9jdW1lbnRTY2FubmVyCi0KLSAgICAvKiogQ3JlYXRlIGEgRFREIHNjYW5uZXIuICovCi0gICAgcHJvdGVjdGVkIFhNTERURFNjYW5uZXIgY3JlYXRlRFREU2Nhbm5lcigpIHsKLSAgICAgICAgcmV0dXJuIG5ldyBYTUxEVERTY2FubmVySW1wbCgpOwotICAgIH0gLy8gY3JlYXRlRFREU2Nhbm5lcigpOlhNTERURFNjYW5uZXIKLQotICAgIC8qKiBDcmVhdGUgYSBkYXRhdHlwZSB2YWxpZGF0b3IgZmFjdG9yeS4gKi8KLSAgICBwcm90ZWN0ZWQgRFRERFZGYWN0b3J5IGNyZWF0ZURhdGF0eXBlVmFsaWRhdG9yRmFjdG9yeSgpIHsKLSAgICAgICAgcmV0dXJuIERURERWRmFjdG9yeS5nZXRJbnN0YW5jZSgpOwotICAgIH0gLy8gY3JlYXRlRGF0YXR5cGVWYWxpZGF0b3JGYWN0b3J5KCk6RGF0YXR5cGVWYWxpZGF0b3JGYWN0b3J5Ci0gICAgcHJvdGVjdGVkIFZhbGlkYXRpb25NYW5hZ2VyIGNyZWF0ZVZhbGlkYXRpb25NYW5hZ2VyKCl7Ci0gICAgICAgIHJldHVybiBuZXcgVmFsaWRhdGlvbk1hbmFnZXIoKTsKLSAgICB9Ci0KLX0gLy8gY2xhc3MgTm9uVmFsaWRhdGluZ0NvbmZpZ3VyYXRpb24KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3BhcnNlcnMvU0FYUGFyc2VyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9wYXJzZXJzL1NBWFBhcnNlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0OGI4YTFlLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3BhcnNlcnMvU0FYUGFyc2VyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNzkgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMC0yMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnBhcnNlcnM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5TeW1ib2xUYWJsZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWxzLlhNTFNlY3VyaXR5TWFuYWdlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWxzLlhNTFNlY3VyaXR5UHJvcGVydHlNYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLmdyYW1tYXJzLlhNTEdyYW1tYXJQb29sOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxQYXJzZXJDb25maWd1cmF0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uOwotCi0vKioKLSAqIFRoaXMgaXMgdGhlIG1haW4gWGVyY2VzIFNBWCBwYXJzZXIgY2xhc3MuIEl0IHVzZXMgdGhlIGFic3RyYWN0IFNBWAotICogcGFyc2VyIHdpdGggYSBkb2N1bWVudCBzY2FubmVyLCBhIGR0ZCBzY2FubmVyLCBhbmQgYSB2YWxpZGF0b3IsIGFzCi0gKiB3ZWxsIGFzIGEgZ3JhbW1hciBwb29sLgotICoKLSAqIEBhdXRob3IgQXJuYXVkICBMZSBIb3JzLCBJQk0KLSAqIEBhdXRob3IgQW5keSBDbGFyaywgSUJNCi0gKgotICogQHZlcnNpb24gJElkOiBTQVhQYXJzZXIuamF2YSx2IDEuNyAyMDEwLTExLTAxIDA0OjQwOjA5IGpvZWh3IEV4cCAkCi0gKi8KLXB1YmxpYyBjbGFzcyBTQVhQYXJzZXIKLSAgICBleHRlbmRzIEFic3RyYWN0U0FYUGFyc2VyIHsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RhbnRzCi0gICAgLy8KLQotICAgIC8vIGZlYXR1cmVzCi0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiBub3RpZnkgYnVpbHQtaW4gcmVmZXJlY2VzLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIE5PVElGWV9CVUlMVElOX1JFRlMgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLk5PVElGWV9CVUlMVElOX1JFRlNfRkVBVFVSRTsKLQotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFJFUE9SVF9XSElURVNQQUNFID0KLSAgICAgICAgICAgIENvbnN0YW50cy5TVU5fU0NIRU1BX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLlNVTl9SRVBPUlRfSUdOT1JFRF9FTEVNRU5UX0NPTlRFTlRfV0hJVEVTUEFDRTsKLQotICAgIC8qKiBSZWNvZ25pemVkIGZlYXR1cmVzLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZ1tdIFJFQ09HTklaRURfRkVBVFVSRVMgPSB7Ci0gICAgICAgIE5PVElGWV9CVUlMVElOX1JFRlMsCi0gICAgICAgIFJFUE9SVF9XSElURVNQQUNFCi0gICAgfTsKLQotICAgIC8vIHByb3BlcnRpZXMKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBzeW1ib2wgdGFibGUuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1lNQk9MX1RBQkxFID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuU1lNQk9MX1RBQkxFX1BST1BFUlRZOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IFhNTCBncmFtbWFyIHBvb2wuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MR1JBTU1BUl9QT09MID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVgrQ29uc3RhbnRzLlhNTEdSQU1NQVJfUE9PTF9QUk9QRVJUWTsKLQotICAgIC8qKiBSZWNvZ25pemVkIHByb3BlcnRpZXMuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nW10gUkVDT0dOSVpFRF9QUk9QRVJUSUVTID0gewotICAgICAgICBTWU1CT0xfVEFCTEUsCi0gICAgICAgIFhNTEdSQU1NQVJfUE9PTCwKLSAgICB9OwotCi0KLSAgICAvLwotICAgIC8vIENvbnN0cnVjdG9ycwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RzIGEgU0FYIHBhcnNlciB1c2luZyB0aGUgc3BlY2lmaWVkIHBhcnNlciBjb25maWd1cmF0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBTQVhQYXJzZXIoWE1MUGFyc2VyQ29uZmlndXJhdGlvbiBjb25maWcpIHsKLSAgICAgICAgc3VwZXIoY29uZmlnKTsKLSAgICB9IC8vIDxpbml0PihYTUxQYXJzZXJDb25maWd1cmF0aW9uKQotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0cyBhIFNBWCBwYXJzZXIgdXNpbmcgdGhlIGR0ZC94bWwgc2NoZW1hIHBhcnNlciBjb25maWd1cmF0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBTQVhQYXJzZXIoKSB7Ci0gICAgICAgIHRoaXMobnVsbCwgbnVsbCk7Ci0gICAgfSAvLyA8aW5pdD4oKQotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0cyBhIFNBWCBwYXJzZXIgdXNpbmcgdGhlIHNwZWNpZmllZCBzeW1ib2wgdGFibGUuCi0gICAgICovCi0gICAgcHVibGljIFNBWFBhcnNlcihTeW1ib2xUYWJsZSBzeW1ib2xUYWJsZSkgewotICAgICAgICB0aGlzKHN5bWJvbFRhYmxlLCBudWxsKTsKLSAgICB9IC8vIDxpbml0PihTeW1ib2xUYWJsZSkKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHMgYSBTQVggcGFyc2VyIHVzaW5nIHRoZSBzcGVjaWZpZWQgc3ltYm9sIHRhYmxlIGFuZAotICAgICAqIGdyYW1tYXIgcG9vbC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU0FYUGFyc2VyKFN5bWJvbFRhYmxlIHN5bWJvbFRhYmxlLCBYTUxHcmFtbWFyUG9vbCBncmFtbWFyUG9vbCkgewotICAgICAgICBzdXBlcihuZXcgWEluY2x1ZGVBd2FyZVBhcnNlckNvbmZpZ3VyYXRpb24oKSk7Ci0KLSAgICAgICAgLy8gc2V0IGZlYXR1cmVzCi0gICAgICAgIGZDb25maWd1cmF0aW9uLmFkZFJlY29nbml6ZWRGZWF0dXJlcyhSRUNPR05JWkVEX0ZFQVRVUkVTKTsKLSAgICAgICAgZkNvbmZpZ3VyYXRpb24uc2V0RmVhdHVyZShOT1RJRllfQlVJTFRJTl9SRUZTLCB0cnVlKTsKLQotICAgICAgICAvLyBzZXQgcHJvcGVydGllcwotICAgICAgICBmQ29uZmlndXJhdGlvbi5hZGRSZWNvZ25pemVkUHJvcGVydGllcyhSRUNPR05JWkVEX1BST1BFUlRJRVMpOwotICAgICAgICBpZiAoc3ltYm9sVGFibGUgIT0gbnVsbCkgewotICAgICAgICAgICAgZkNvbmZpZ3VyYXRpb24uc2V0UHJvcGVydHkoU1lNQk9MX1RBQkxFLCBzeW1ib2xUYWJsZSk7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGdyYW1tYXJQb29sICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZDb25maWd1cmF0aW9uLnNldFByb3BlcnR5KFhNTEdSQU1NQVJfUE9PTCwgZ3JhbW1hclBvb2wpOwotICAgICAgICB9Ci0KLSAgICB9IC8vIDxpbml0PihTeW1ib2xUYWJsZSxYTUxHcmFtbWFyUG9vbCkKLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIHBhcnRpY3VsYXIgcHJvcGVydHkgaW4gdGhlIHVuZGVybHlpbmcgaW1wbGVtZW50YXRpb24gb2YKLSAgICAgKiBvcmcueG1sLnNheC5YTUxSZWFkZXIuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0UHJvcGVydHkoU3RyaW5nIG5hbWUsIE9iamVjdCB2YWx1ZSkKLSAgICAgICAgdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiB7Ci0gICAgICAgIC8qKgotICAgICAgICAgKiBJdCdzIHBvc3NpYmxlIGZvciB1c2VycyB0byBzZXQgYSBzZWN1cml0eSBtYW5hZ2VyIHRocm91Z2ggdGhlIGludGVyZmFjZS4KLSAgICAgICAgICogSWYgaXQncyB0aGUgb2xkIFNlY3VyaXR5TWFuYWdlciwgY29udmVydCBpdCB0byB0aGUgbmV3IFhNTFNlY3VyaXR5TWFuYWdlcgotICAgICAgICAgKi8KLSAgICAgICAgaWYgKG5hbWUuZXF1YWxzKENvbnN0YW50cy5TRUNVUklUWV9NQU5BR0VSKSkgewotICAgICAgICAgICAgc2VjdXJpdHlNYW5hZ2VyID0gWE1MU2VjdXJpdHlNYW5hZ2VyLmNvbnZlcnQodmFsdWUsIHNlY3VyaXR5TWFuYWdlcik7Ci0gICAgICAgICAgICBzdXBlci5zZXRQcm9wZXJ0eShDb25zdGFudHMuU0VDVVJJVFlfTUFOQUdFUiwgc2VjdXJpdHlNYW5hZ2VyKTsKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotICAgICAgICBpZiAobmFtZS5lcXVhbHMoQ29uc3RhbnRzLlhNTF9TRUNVUklUWV9QUk9QRVJUWV9NQU5BR0VSKSkgewotICAgICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBzZWN1cml0eVByb3BlcnR5TWFuYWdlciA9IG5ldyBYTUxTZWN1cml0eVByb3BlcnR5TWFuYWdlcigpOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBzZWN1cml0eVByb3BlcnR5TWFuYWdlciA9IChYTUxTZWN1cml0eVByb3BlcnR5TWFuYWdlcil2YWx1ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHN1cGVyLnNldFByb3BlcnR5KENvbnN0YW50cy5YTUxfU0VDVVJJVFlfUFJPUEVSVFlfTUFOQUdFUiwgc2VjdXJpdHlQcm9wZXJ0eU1hbmFnZXIpOwotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKHNlY3VyaXR5TWFuYWdlciA9PSBudWxsKSB7Ci0gICAgICAgICAgICBzZWN1cml0eU1hbmFnZXIgPSBuZXcgWE1MU2VjdXJpdHlNYW5hZ2VyKHRydWUpOwotICAgICAgICAgICAgc3VwZXIuc2V0UHJvcGVydHkoQ29uc3RhbnRzLlNFQ1VSSVRZX01BTkFHRVIsIHNlY3VyaXR5TWFuYWdlcik7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoc2VjdXJpdHlQcm9wZXJ0eU1hbmFnZXIgPT0gbnVsbCkgewotICAgICAgICAgICAgc2VjdXJpdHlQcm9wZXJ0eU1hbmFnZXIgPSBuZXcgWE1MU2VjdXJpdHlQcm9wZXJ0eU1hbmFnZXIoKTsKLSAgICAgICAgICAgIHN1cGVyLnNldFByb3BlcnR5KENvbnN0YW50cy5YTUxfU0VDVVJJVFlfUFJPUEVSVFlfTUFOQUdFUiwgc2VjdXJpdHlQcm9wZXJ0eU1hbmFnZXIpOwotICAgICAgICB9Ci0KLSAgICAgICAgaW50IGluZGV4ID0gc2VjdXJpdHlQcm9wZXJ0eU1hbmFnZXIuZ2V0SW5kZXgobmFtZSk7Ci0gICAgICAgIGlmIChpbmRleCA+IC0xKSB7Ci0gICAgICAgICAgICAvKioKLSAgICAgICAgICAgICAqIHRoaXMgaXMgYSBkaXJlY3QgY2FsbCB0byB0aGlzIHBhcnNlciwgbm90IGEgc3ViY2xhc3Mgc2luY2UKLSAgICAgICAgICAgICAqIGludGVybmFsbHkgdGhlIHN1cHBvcnQgb2YgdGhpcyBwcm9wZXJ0eSBpcyBkb25lIHRocm91Z2gKLSAgICAgICAgICAgICAqIFhNTFNlY3VyaXR5UHJvcGVydHlNYW5hZ2VyCi0gICAgICAgICAgICAgKi8KLSAgICAgICAgICAgIHNlY3VyaXR5UHJvcGVydHlNYW5hZ2VyLnNldFZhbHVlKGluZGV4LCBYTUxTZWN1cml0eVByb3BlcnR5TWFuYWdlci5TdGF0ZS5BUElQUk9QRVJUWSwgKFN0cmluZyl2YWx1ZSk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAvL2NoZWNrIGlmIHRoZSBwcm9wZXJ0eSBpcyBtYW5hZ2VkIGJ5IHNlY3VyaXR5IG1hbmFnZXIKLSAgICAgICAgICAgIGlmICghc2VjdXJpdHlNYW5hZ2VyLnNldExpbWl0KG5hbWUsIFhNTFNlY3VyaXR5TWFuYWdlci5TdGF0ZS5BUElQUk9QRVJUWSwgdmFsdWUpKSB7Ci0gICAgICAgICAgICAgICAgLy9mYWxsIGJhY2sgdG8gdGhlIGRlZmF1bHQgY29uZmlndXJhdGlvbiB0byBoYW5kbGUgdGhlIHByb3BlcnR5Ci0gICAgICAgICAgICAgICAgc3VwZXIuc2V0UHJvcGVydHkobmFtZSwgdmFsdWUpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotfSAvLyBjbGFzcyBTQVhQYXJzZXIKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3BhcnNlcnMvU2VjdXJpdHlDb25maWd1cmF0aW9uLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9wYXJzZXJzL1NlY3VyaXR5Q29uZmlndXJhdGlvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2NWM4NWQxLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3BhcnNlcnMvU2VjdXJpdHlDb25maWd1cmF0aW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMTQgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnBhcnNlcnM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLmdyYW1tYXJzLlhNTEdyYW1tYXJQb29sOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxDb21wb25lbnRNYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5TeW1ib2xUYWJsZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWxzLlhNTFNlY3VyaXR5TWFuYWdlcjsKLQotLyoqCi0gKiBUaGlzIGNvbmZpZ3VyYXRpb24gYWxsb3dzIFhlcmNlcyB0byBiZWhhdmUgaW4gYSBzZWN1cml0eS1jb25zY2lvdXMgbWFubmVyOyB0aGF0IGlzLAotICogaXQgcGVybWl0cyBhcHBsaWNhdGlvbnMgdG8gaW5zdHJ1Y3QgWGVyY2VzIHRvIGxpbWl0IGNlcnRhaW4KLSAqIG9wZXJhdGlvbnMgdGhhdCBjb3VsZCBiZSBleHBsb2l0ZWQgYnkgbWFsaWNpb3VzIGRvY3VtZW50IGF1dGhvcnMgdG8gY2F1c2UgYSBkZW5haWwtb2Ytc2VydmljZQotICogYXR0YWNrIHdoZW4gdGhlIGRvY3VtZW50IGlzIHBhcnNlZC4KLSAqCi0gKiBJbiBhZGRpdGlvbiB0byB0aGUgZmVhdHVyZXMgYW5kIHByb3BlcnRpZXMgcmVjb2duaXplZCBieSB0aGUgYmFzZQotICogcGFyc2VyIGNvbmZpZ3VyYXRpb24sIHRoaXMgY2xhc3MgcmVjb2duaXplcyB0aGVzZSBhZGRpdGlvbmFsCi0gKiBmZWF0dXJlcyBhbmQgcHJvcGVydGllczoKLSAqIDx1bD4KLSAqIDxsaT5Qcm9wZXJ0aWVzCi0gKiAgPHVsPgotICogICA8bGk+aHR0cDovL2FwYWNoZS5vcmcveG1sL3Byb3BlcnRpZXMvc2VjdXJpdHktbWFuYWdlcjwvbGk+Ci0gKiAgPC91bD4KLSAqIDwvdWw+Ci0gKgotICogQGF1dGhvciBOZWlsIEdyYWhhbSwgSUJNCi0gKgotICogQHZlcnNpb24gJElkOiBTZWN1cml0eUNvbmZpZ3VyYXRpb24uamF2YSx2IDEuNiAyMDEwLTExLTAxIDA0OjQwOjA5IGpvZWh3IEV4cCAkCi0gKi8KLXB1YmxpYyBjbGFzcyBTZWN1cml0eUNvbmZpZ3VyYXRpb24gZXh0ZW5kcyBYSW5jbHVkZUF3YXJlUGFyc2VyQ29uZmlndXJhdGlvbgotewotCi0gICAgLy8KLSAgICAvLyBDb25zdGFudHMKLSAgICAvLwotCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgU0VDVVJJVFlfTUFOQUdFUl9QUk9QRVJUWSA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLlNFQ1VSSVRZX01BTkFHRVJfUFJPUEVSVFk7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0cnVjdG9ycwotICAgIC8vCi0KLSAgICAvKiogRGVmYXVsdCBjb25zdHJ1Y3Rvci4gKi8KLSAgICBwdWJsaWMgU2VjdXJpdHlDb25maWd1cmF0aW9uICgpIHsKLSAgICAgICAgdGhpcyhudWxsLCBudWxsLCBudWxsKTsKLSAgICB9IC8vIDxpbml0PigpCi0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RzIGEgcGFyc2VyIGNvbmZpZ3VyYXRpb24gdXNpbmcgdGhlIHNwZWNpZmllZCBzeW1ib2wgdGFibGUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc3ltYm9sVGFibGUgVGhlIHN5bWJvbCB0YWJsZSB0byB1c2UuCi0gICAgICovCi0gICAgcHVibGljIFNlY3VyaXR5Q29uZmlndXJhdGlvbiAoU3ltYm9sVGFibGUgc3ltYm9sVGFibGUpIHsKLSAgICAgICAgdGhpcyhzeW1ib2xUYWJsZSwgbnVsbCwgbnVsbCk7Ci0gICAgfSAvLyA8aW5pdD4oU3ltYm9sVGFibGUpCi0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RzIGEgcGFyc2VyIGNvbmZpZ3VyYXRpb24gdXNpbmcgdGhlIHNwZWNpZmllZCBzeW1ib2wgdGFibGUgYW5kCi0gICAgICogZ3JhbW1hciBwb29sLgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+UkVWSVNJVDo8L3N0cm9uZz4KLSAgICAgKiBHcmFtbWFyIHBvb2wgd2lsbCBiZSB1cGRhdGVkIHdoZW4gdGhlIG5ldyB2YWxpZGF0aW9uIGVuZ2luZSBpcwotICAgICAqIGltcGxlbWVudGVkLgotICAgICAqCi0gICAgICogQHBhcmFtIHN5bWJvbFRhYmxlIFRoZSBzeW1ib2wgdGFibGUgdG8gdXNlLgotICAgICAqIEBwYXJhbSBncmFtbWFyUG9vbCBUaGUgZ3JhbW1hciBwb29sIHRvIHVzZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgU2VjdXJpdHlDb25maWd1cmF0aW9uIChTeW1ib2xUYWJsZSBzeW1ib2xUYWJsZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MR3JhbW1hclBvb2wgZ3JhbW1hclBvb2wpIHsKLSAgICAgICAgdGhpcyhzeW1ib2xUYWJsZSwgZ3JhbW1hclBvb2wsIG51bGwpOwotICAgIH0gLy8gPGluaXQ+KFN5bWJvbFRhYmxlLFhNTEdyYW1tYXJQb29sKQotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0cyBhIHBhcnNlciBjb25maWd1cmF0aW9uIHVzaW5nIHRoZSBzcGVjaWZpZWQgc3ltYm9sIHRhYmxlLAotICAgICAqIGdyYW1tYXIgcG9vbCwgYW5kIHBhcmVudCBzZXR0aW5ncy4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPlJFVklTSVQ6PC9zdHJvbmc+Ci0gICAgICogR3JhbW1hciBwb29sIHdpbGwgYmUgdXBkYXRlZCB3aGVuIHRoZSBuZXcgdmFsaWRhdGlvbiBlbmdpbmUgaXMKLSAgICAgKiBpbXBsZW1lbnRlZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzeW1ib2xUYWJsZSAgICBUaGUgc3ltYm9sIHRhYmxlIHRvIHVzZS4KLSAgICAgKiBAcGFyYW0gZ3JhbW1hclBvb2wgICAgVGhlIGdyYW1tYXIgcG9vbCB0byB1c2UuCi0gICAgICogQHBhcmFtIHBhcmVudFNldHRpbmdzIFRoZSBwYXJlbnQgc2V0dGluZ3MuCi0gICAgICovCi0gICAgcHVibGljIFNlY3VyaXR5Q29uZmlndXJhdGlvbiAoU3ltYm9sVGFibGUgc3ltYm9sVGFibGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTEdyYW1tYXJQb29sIGdyYW1tYXJQb29sLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxDb21wb25lbnRNYW5hZ2VyIHBhcmVudFNldHRpbmdzKSB7Ci0gICAgICAgIHN1cGVyKHN5bWJvbFRhYmxlLCBncmFtbWFyUG9vbCwgcGFyZW50U2V0dGluZ3MpOwotCi0gICAgICAgIC8vIGNyZWF0ZSB0aGUgU2VjdXJpdHlNYW5hZ2VyIHByb3BlcnR5OgotICAgICAgICBzZXRQcm9wZXJ0eShTRUNVUklUWV9NQU5BR0VSX1BST1BFUlRZLCBuZXcgWE1MU2VjdXJpdHlNYW5hZ2VyKHRydWUpKTsKLSAgICB9IC8vIDxpbml0PihTeW1ib2xUYWJsZSxYTUxHcmFtbWFyUG9vbCkKLQotfSAvLyBjbGFzcyBTZWN1cml0eUNvbmZpZ3VyYXRpb24KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3BhcnNlcnMvU3RhbmRhcmRQYXJzZXJDb25maWd1cmF0aW9uLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9wYXJzZXJzL1N0YW5kYXJkUGFyc2VyQ29uZmlndXJhdGlvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3Y2FhZDViLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3BhcnNlcnMvU3RhbmRhcmRQYXJzZXJDb25maWd1cmF0aW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzODUgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnBhcnNlcnM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5YTUxTY2hlbWFWYWxpZGF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlhTTWVzc2FnZUZvcm1hdHRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuRmVhdHVyZVN0YXRlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5Qcm9wZXJ0eVN0YXRlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5TdGF0dXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlN5bWJvbFRhYmxlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLmdyYW1tYXJzLlhNTEdyYW1tYXJQb29sOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxDb21wb25lbnRNYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uOwotCi0vKioKLSAqIFRoaXMgaXMgdGhlICJzdGFuZGFyZCIgcGFyc2VyIGNvbmZpZ3VyYXRpb24uIEl0IGV4dGVuZHMgdGhlIERURAotICogY29uZmlndXJhdGlvbiB3aXRoIHRoZSBzdGFuZGFyZCBzZXQgb2YgcGFyc2VyIGNvbXBvbmVudHMuCi0gKiBUaGUgc3RhbmRhcmQgc2V0IG9mIHBhcnNlciBjb21wb25lbnRzIGluY2x1ZGUgdGhvc2UgbmVlZGVkCi0gKiB0byBwYXJzZSBhbmQgdmFsaWRhdGUgd2l0aCBEVEQncywgYW5kIHRob3NlIG5lZWRlZCBmb3IgWE1MCi0gKiBTY2hlbWEuPC9wPgotICogPHA+Ci0gKiBJbiBhZGRpdGlvbiB0byB0aGUgZmVhdHVyZXMgYW5kIHByb3BlcnRpZXMgcmVjb2duaXplZCBieSB0aGUgYmFzZQotICogcGFyc2VyIGNvbmZpZ3VyYXRpb24sIHRoaXMgY2xhc3MgcmVjb2duaXplcyB0aGVzZSBhZGRpdGlvbmFsCi0gKiBmZWF0dXJlcyBhbmQgcHJvcGVydGllczoKLSAqIDx1bD4KLSAqIDxsaT5GZWF0dXJlcwotICogIDx1bD4KLSAqICA8bGk+aHR0cDovL2FwYWNoZS5vcmcveG1sL2ZlYXR1cmVzL3ZhbGlkYXRpb24vc2NoZW1hPC9saT4KLSAqICA8bGk+aHR0cDovL2FwYWNoZS5vcmcveG1sL2ZlYXR1cmVzL3ZhbGlkYXRpb24vc2NoZW1hLWZ1bGwtY2hlY2tpbmc8L2xpPgotICogIDxsaT5odHRwOi8vYXBhY2hlLm9yZy94bWwvZmVhdHVyZXMvdmFsaWRhdGlvbi9zY2hlbWEvbm9ybWFsaXplZC12YWx1ZTwvbGk+Ci0gKiAgPGxpPmh0dHA6Ly9hcGFjaGUub3JnL3htbC9mZWF0dXJlcy92YWxpZGF0aW9uL3NjaGVtYS9lbGVtZW50LWRlZmF1bHQ8L2xpPgotICogIDwvdWw+Ci0gKiA8bGk+UHJvcGVydGllcwotICogIDx1bD4KLSAqICAgPGxpPmh0dHA6Ly9hcGFjaGUub3JnL3htbC9wcm9wZXJ0aWVzL2ludGVybmFsL2Vycm9yLXJlcG9ydGVyPC9saT4KLSAqICAgPGxpPmh0dHA6Ly9hcGFjaGUub3JnL3htbC9wcm9wZXJ0aWVzL2ludGVybmFsL2VudGl0eS1tYW5hZ2VyPC9saT4KLSAqICAgPGxpPmh0dHA6Ly9hcGFjaGUub3JnL3htbC9wcm9wZXJ0aWVzL2ludGVybmFsL2RvY3VtZW50LXNjYW5uZXI8L2xpPgotICogICA8bGk+aHR0cDovL2FwYWNoZS5vcmcveG1sL3Byb3BlcnRpZXMvaW50ZXJuYWwvZHRkLXNjYW5uZXI8L2xpPgotICogICA8bGk+aHR0cDovL2FwYWNoZS5vcmcveG1sL3Byb3BlcnRpZXMvaW50ZXJuYWwvZ3JhbW1hci1wb29sPC9saT4KLSAqICAgPGxpPmh0dHA6Ly9hcGFjaGUub3JnL3htbC9wcm9wZXJ0aWVzL2ludGVybmFsL3ZhbGlkYXRvci9kdGQ8L2xpPgotICogICA8bGk+aHR0cDovL2FwYWNoZS5vcmcveG1sL3Byb3BlcnRpZXMvaW50ZXJuYWwvZGF0YXR5cGUtdmFsaWRhdG9yLWZhY3Rvcnk8L2xpPgotICogIDwvdWw+Ci0gKiA8L3VsPgotICoKLSAqIEBhdXRob3IgQXJuYXVkICBMZSBIb3JzLCBJQk0KLSAqIEBhdXRob3IgQW5keSBDbGFyaywgSUJNCi0gKgotICogQHZlcnNpb24gJElkOiBTdGFuZGFyZFBhcnNlckNvbmZpZ3VyYXRpb24uamF2YSx2IDEuNyAyMDEwLTExLTAxIDA0OjQwOjEwIGpvZWh3IEV4cCAkCi0gKi8KLXB1YmxpYyBjbGFzcyBTdGFuZGFyZFBhcnNlckNvbmZpZ3VyYXRpb24KLSAgICBleHRlbmRzIERURENvbmZpZ3VyYXRpb24gewotCi0gICAgLy8KLSAgICAvLyBDb25zdGFudHMKLSAgICAvLwotCi0gICAgLy8gZmVhdHVyZSBpZGVudGlmaWVycwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogZXhwb3NlIHNjaGVtYSBub3JtYWxpemVkIHZhbHVlICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgTk9STUFMSVpFX0RBVEEgPQotICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuU0NIRU1BX05PUk1BTElaRURfVkFMVUU7Ci0KLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IHNlbmQgZWxlbWVudCBkZWZhdWx0IHZhbHVlIHZpYSBjaGFyYWN0ZXJzKCkgKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBTQ0hFTUFfRUxFTUVOVF9ERUZBVUxUID0KLSAgICBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLlNDSEVNQV9FTEVNRU5UX0RFRkFVTFQ7Ci0KLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IGF1Z21lbnQgUFNWSSAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFNDSEVNQV9BVUdNRU5UX1BTVkkgPQotICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuU0NIRU1BX0FVR01FTlRfUFNWSTsKLQotCi0gICAgLyoqIGZlYXR1cmUgaWRlbnRpZmllcjogWE1MIFNjaGVtYSB2YWxpZGF0aW9uICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MU0NIRU1BX1ZBTElEQVRJT04gPQotICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuU0NIRU1BX1ZBTElEQVRJT05fRkVBVFVSRTsKLQotICAgIC8qKiBmZWF0dXJlIGlkZW50aWZpZXI6IFhNTCBTY2hlbWEgdmFsaWRhdGlvbiAtLSBmdWxsIGNoZWNraW5nICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MU0NIRU1BX0ZVTExfQ0hFQ0tJTkcgPQotICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuU0NIRU1BX0ZVTExfQ0hFQ0tJTkc7Ci0KLSAgICAvKiogRmVhdHVyZTogZ2VuZXJhdGUgc3ludGhldGljIGFubm90YXRpb25zICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgR0VORVJBVEVfU1lOVEhFVElDX0FOTk9UQVRJT05TID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5HRU5FUkFURV9TWU5USEVUSUNfQU5OT1RBVElPTlNfRkVBVFVSRTsKLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IHZhbGlkYXRlIGFubm90YXRpb25zICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgVkFMSURBVEVfQU5OT1RBVElPTlMgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLlZBTElEQVRFX0FOTk9UQVRJT05TX0ZFQVRVUkU7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiBob25vdXIgYWxsIHNjaGVtYUxvY2F0aW9ucyAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIEhPTk9VUl9BTExfU0NIRU1BTE9DQVRJT05TID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5IT05PVVJfQUxMX1NDSEVNQUxPQ0FUSU9OU19GRUFUVVJFOwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogbmFtZXNwYWNlIGdyb3d0aCAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIE5BTUVTUEFDRV9HUk9XVEggPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLk5BTUVTUEFDRV9HUk9XVEhfRkVBVFVSRTsKLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IHRvbGVyYXRlIGR1cGxpY2F0ZXMgKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBUT0xFUkFURV9EVVBMSUNBVEVTID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5UT0xFUkFURV9EVVBMSUNBVEVTX0ZFQVRVUkU7Ci0KLSAgICAvLyBwcm9wZXJ0eSBpZGVudGlmaWVycwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IFhNTCBTY2hlbWEgdmFsaWRhdG9yLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFNDSEVNQV9WQUxJREFUT1IgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5TQ0hFTUFfVkFMSURBVE9SX1BST1BFUlRZOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IHNjaGVtYSBsb2NhdGlvbi4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBTQ0hFTUFfTE9DQVRJT04gPQotICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLlNDSEVNQV9MT0NBVElPTjsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBubyBuYW1lc3BhY2Ugc2NoZW1hIGxvY2F0aW9uLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFNDSEVNQV9OT05TX0xPQ0FUSU9OID0KLSAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5TQ0hFTUFfTk9OU19MT0NBVElPTjsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBTY2hlbWEgRFYgRmFjdG9yeSAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFNDSEVNQV9EVl9GQUNUT1JZID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuU0NIRU1BX0RWX0ZBQ1RPUllfUFJPUEVSVFk7Ci0KLSAgICAvLwotICAgIC8vIERhdGEKLSAgICAvLwotCi0gICAgLy8gY29tcG9uZW50cyAobm9uLWNvbmZpZ3VyYWJsZSkKLQotICAgIC8qKiBYTUwgU2NoZW1hIFZhbGlkYXRvci4gKi8KLSAgICBwcm90ZWN0ZWQgWE1MU2NoZW1hVmFsaWRhdG9yIGZTY2hlbWFWYWxpZGF0b3I7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0cnVjdG9ycwotICAgIC8vCi0KLSAgICAvKiogRGVmYXVsdCBjb25zdHJ1Y3Rvci4gKi8KLSAgICBwdWJsaWMgU3RhbmRhcmRQYXJzZXJDb25maWd1cmF0aW9uKCkgewotICAgICAgICB0aGlzKG51bGwsIG51bGwsIG51bGwpOwotICAgIH0gLy8gPGluaXQ+KCkKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHMgYSBwYXJzZXIgY29uZmlndXJhdGlvbiB1c2luZyB0aGUgc3BlY2lmaWVkIHN5bWJvbCB0YWJsZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzeW1ib2xUYWJsZSBUaGUgc3ltYm9sIHRhYmxlIHRvIHVzZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RhbmRhcmRQYXJzZXJDb25maWd1cmF0aW9uKFN5bWJvbFRhYmxlIHN5bWJvbFRhYmxlKSB7Ci0gICAgICAgIHRoaXMoc3ltYm9sVGFibGUsIG51bGwsIG51bGwpOwotICAgIH0gLy8gPGluaXQ+KFN5bWJvbFRhYmxlKQotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0cyBhIHBhcnNlciBjb25maWd1cmF0aW9uIHVzaW5nIHRoZSBzcGVjaWZpZWQgc3ltYm9sIHRhYmxlIGFuZAotICAgICAqIGdyYW1tYXIgcG9vbC4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPlJFVklTSVQ6PC9zdHJvbmc+Ci0gICAgICogR3JhbW1hciBwb29sIHdpbGwgYmUgdXBkYXRlZCB3aGVuIHRoZSBuZXcgdmFsaWRhdGlvbiBlbmdpbmUgaXMKLSAgICAgKiBpbXBsZW1lbnRlZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzeW1ib2xUYWJsZSBUaGUgc3ltYm9sIHRhYmxlIHRvIHVzZS4KLSAgICAgKiBAcGFyYW0gZ3JhbW1hclBvb2wgVGhlIGdyYW1tYXIgcG9vbCB0byB1c2UuCi0gICAgICovCi0gICAgcHVibGljIFN0YW5kYXJkUGFyc2VyQ29uZmlndXJhdGlvbihTeW1ib2xUYWJsZSBzeW1ib2xUYWJsZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTEdyYW1tYXJQb29sIGdyYW1tYXJQb29sKSB7Ci0gICAgICAgIHRoaXMoc3ltYm9sVGFibGUsIGdyYW1tYXJQb29sLCBudWxsKTsKLSAgICB9IC8vIDxpbml0PihTeW1ib2xUYWJsZSxYTUxHcmFtbWFyUG9vbCkKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHMgYSBwYXJzZXIgY29uZmlndXJhdGlvbiB1c2luZyB0aGUgc3BlY2lmaWVkIHN5bWJvbCB0YWJsZSwKLSAgICAgKiBncmFtbWFyIHBvb2wsIGFuZCBwYXJlbnQgc2V0dGluZ3MuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5SRVZJU0lUOjwvc3Ryb25nPgotICAgICAqIEdyYW1tYXIgcG9vbCB3aWxsIGJlIHVwZGF0ZWQgd2hlbiB0aGUgbmV3IHZhbGlkYXRpb24gZW5naW5lIGlzCi0gICAgICogaW1wbGVtZW50ZWQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc3ltYm9sVGFibGUgICAgVGhlIHN5bWJvbCB0YWJsZSB0byB1c2UuCi0gICAgICogQHBhcmFtIGdyYW1tYXJQb29sICAgIFRoZSBncmFtbWFyIHBvb2wgdG8gdXNlLgotICAgICAqIEBwYXJhbSBwYXJlbnRTZXR0aW5ncyBUaGUgcGFyZW50IHNldHRpbmdzLgotICAgICAqLwotICAgIHB1YmxpYyBTdGFuZGFyZFBhcnNlckNvbmZpZ3VyYXRpb24oU3ltYm9sVGFibGUgc3ltYm9sVGFibGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxHcmFtbWFyUG9vbCBncmFtbWFyUG9vbCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTENvbXBvbmVudE1hbmFnZXIgcGFyZW50U2V0dGluZ3MpIHsKLSAgICAgICAgc3VwZXIoc3ltYm9sVGFibGUsIGdyYW1tYXJQb29sLCBwYXJlbnRTZXR0aW5ncyk7Ci0KLSAgICAgICAgLy8gYWRkIGRlZmF1bHQgcmVjb2duaXplZCBmZWF0dXJlcwotICAgICAgICBmaW5hbCBTdHJpbmdbXSByZWNvZ25pemVkRmVhdHVyZXMgPSB7Ci0gICAgICAgICAgICBOT1JNQUxJWkVfREFUQSwKLSAgICAgICAgICAgIFNDSEVNQV9FTEVNRU5UX0RFRkFVTFQsCi0gICAgICAgICAgICBTQ0hFTUFfQVVHTUVOVF9QU1ZJLAotICAgICAgICAgICAgR0VORVJBVEVfU1lOVEhFVElDX0FOTk9UQVRJT05TLAotICAgICAgICAgICAgVkFMSURBVEVfQU5OT1RBVElPTlMsCi0gICAgICAgICAgICBIT05PVVJfQUxMX1NDSEVNQUxPQ0FUSU9OUywKLSAgICAgICAgICAgIE5BTUVTUEFDRV9HUk9XVEgsCi0gICAgICAgICAgICBUT0xFUkFURV9EVVBMSUNBVEVTLAotICAgICAgICAgICAgLy8gTk9URTogVGhlc2Ugc2hvdWxkbid0IHJlYWxseSBiZSBoZXJlIGJ1dCBzaW5jZSB0aGUgWE1MIFNjaGVtYQotICAgICAgICAgICAgLy8gICAgICAgdmFsaWRhdG9yIGlzIGNvbnN0cnVjdGVkIGR5bmFtaWNhbGx5LCBpdHMgcmVjb2duaXplZAotICAgICAgICAgICAgLy8gICAgICAgZmVhdHVyZXMgbWlnaHQgbm90IGhhdmUgYmVlbiBzZXQgYW5kIGl0IHdvdWxkIGNhdXNlIGEKLSAgICAgICAgICAgIC8vICAgICAgIG5vdC1yZWNvZ25pemVkIGV4Y2VwdGlvbiB0byBiZSB0aHJvd24uIC1BYwotICAgICAgICAgICAgWE1MU0NIRU1BX1ZBTElEQVRJT04sCi0gICAgICAgICAgICBYTUxTQ0hFTUFfRlVMTF9DSEVDS0lORywKLSAgICAgICAgfTsKLSAgICAgICAgYWRkUmVjb2duaXplZEZlYXR1cmVzKHJlY29nbml6ZWRGZWF0dXJlcyk7Ci0KLSAgICAgICAgLy8gc2V0IHN0YXRlIGZvciBkZWZhdWx0IGZlYXR1cmVzCi0gICAgICAgIHNldEZlYXR1cmUoU0NIRU1BX0VMRU1FTlRfREVGQVVMVCwgdHJ1ZSk7Ci0gICAgICAgIHNldEZlYXR1cmUoTk9STUFMSVpFX0RBVEEsIHRydWUpOwotICAgICAgICBzZXRGZWF0dXJlKFNDSEVNQV9BVUdNRU5UX1BTVkksIHRydWUpOwotICAgICAgICBzZXRGZWF0dXJlKEdFTkVSQVRFX1NZTlRIRVRJQ19BTk5PVEFUSU9OUywgZmFsc2UpOwotICAgICAgICBzZXRGZWF0dXJlKFZBTElEQVRFX0FOTk9UQVRJT05TLCBmYWxzZSk7Ci0gICAgICAgIHNldEZlYXR1cmUoSE9OT1VSX0FMTF9TQ0hFTUFMT0NBVElPTlMsIGZhbHNlKTsKLSAgICAgICAgc2V0RmVhdHVyZShOQU1FU1BBQ0VfR1JPV1RILCBmYWxzZSk7Ci0gICAgICAgIHNldEZlYXR1cmUoVE9MRVJBVEVfRFVQTElDQVRFUywgZmFsc2UpOwotCi0gICAgICAgIC8vIGFkZCBkZWZhdWx0IHJlY29nbml6ZWQgcHJvcGVydGllcwotCi0gICAgICAgIGZpbmFsIFN0cmluZ1tdIHJlY29nbml6ZWRQcm9wZXJ0aWVzID0gewotICAgICAgICAgICAgLy8gTk9URTogVGhlc2Ugc2hvdWxkbid0IHJlYWxseSBiZSBoZXJlIGJ1dCBzaW5jZSB0aGUgWE1MIFNjaGVtYQotICAgICAgICAgICAgLy8gICAgICAgdmFsaWRhdG9yIGlzIGNvbnN0cnVjdGVkIGR5bmFtaWNhbGx5LCBpdHMgcmVjb2duaXplZAotICAgICAgICAgICAgLy8gICAgICAgcHJvcGVydGllcyBtaWdodCBub3QgaGF2ZSBiZWVuIHNldCBhbmQgaXQgd291bGQgY2F1c2UgYQotICAgICAgICAgICAgLy8gICAgICAgbm90LXJlY29nbml6ZWQgZXhjZXB0aW9uIHRvIGJlIHRocm93bi4gLUFjCi0gICAgICAgICAgICBTQ0hFTUFfTE9DQVRJT04sCi0gICAgICAgICAgICBTQ0hFTUFfTk9OU19MT0NBVElPTiwKLSAgICAgICAgICAgIFNDSEVNQV9EVl9GQUNUT1JZLAotICAgICAgICAgICAgfTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgYWRkUmVjb2duaXplZFByb3BlcnRpZXMocmVjb2duaXplZFByb3BlcnRpZXMpOwotCi0gICAgfSAvLyA8aW5pdD4oU3ltYm9sVGFibGUsWE1MR3JhbW1hclBvb2wpCi0KLSAgICAvLwotICAgIC8vIFB1YmxpYyBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKiBDb25maWd1cmVzIHRoZSBwaXBlbGluZS4gKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCBjb25maWd1cmVQaXBlbGluZSgpIHsKLSAgICAgICAgc3VwZXIuY29uZmlndXJlUGlwZWxpbmUoKTsKLSAgICAgICAgaWYgKCBnZXRGZWF0dXJlKFhNTFNDSEVNQV9WQUxJREFUSU9OICkpIHsKLSAgICAgICAgICAgIC8vIElmIHNjaGVtYSB2YWxpZGF0b3Igd2FzIG5vdCBpbiB0aGUgcGlwZWxpbmUgaW5zZXJ0IGl0LgotICAgICAgICAgICAgaWYgKGZTY2hlbWFWYWxpZGF0b3IgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZTY2hlbWFWYWxpZGF0b3IgPSBuZXcgWE1MU2NoZW1hVmFsaWRhdG9yKCk7Ci0KLSAgICAgICAgICAgICAgICAvLyBhZGQgc2NoZW1hIGNvbXBvbmVudAotICAgICAgICAgICAgICAgIGZQcm9wZXJ0aWVzLnB1dChTQ0hFTUFfVkFMSURBVE9SLCBmU2NoZW1hVmFsaWRhdG9yKTsKLSAgICAgICAgICAgICAgICBhZGRDb21wb25lbnQoZlNjaGVtYVZhbGlkYXRvcik7Ci0gICAgICAgICAgICAgICAgIC8vIGFkZCBzY2hlbWEgbWVzc2FnZSBmb3JtYXR0ZXIKLSAgICAgICAgICAgICAgICBpZiAoZkVycm9yUmVwb3J0ZXIuZ2V0TWVzc2FnZUZvcm1hdHRlcihYU01lc3NhZ2VGb3JtYXR0ZXIuU0NIRU1BX0RPTUFJTikgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBYU01lc3NhZ2VGb3JtYXR0ZXIgeG1mdCA9IG5ldyBYU01lc3NhZ2VGb3JtYXR0ZXIoKTsKLSAgICAgICAgICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucHV0TWVzc2FnZUZvcm1hdHRlcihYU01lc3NhZ2VGb3JtYXR0ZXIuU0NIRU1BX0RPTUFJTiwgeG1mdCk7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmTGFzdENvbXBvbmVudCA9IGZTY2hlbWFWYWxpZGF0b3I7Ci0gICAgICAgICAgICBmTmFtZXNwYWNlQmluZGVyLnNldERvY3VtZW50SGFuZGxlcihmU2NoZW1hVmFsaWRhdG9yKTsKLQotICAgICAgICAgICAgZlNjaGVtYVZhbGlkYXRvci5zZXREb2N1bWVudEhhbmRsZXIoZkRvY3VtZW50SGFuZGxlcik7Ci0gICAgICAgICAgICBmU2NoZW1hVmFsaWRhdG9yLnNldERvY3VtZW50U291cmNlKGZOYW1lc3BhY2VCaW5kZXIpOwotICAgICAgICB9Ci0KLQotICAgIH0gLy8gY29uZmlndXJlUGlwZWxpbmUoKQotCi0gICAgLy8gZmVhdHVyZXMgYW5kIHByb3BlcnRpZXMKLQotICAgIC8qKgotICAgICAqIENoZWNrIGEgZmVhdHVyZS4gSWYgZmVhdHVyZSBpcyBrbm93IGFuZCBzdXBwb3J0ZWQsIHRoaXMgbWV0aG9kIHNpbXBseQotICAgICAqIHJldHVybnMuIE90aGVyd2lzZSwgdGhlIGFwcHJvcHJpYXRlIGV4Y2VwdGlvbiBpcyB0aHJvd24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZmVhdHVyZUlkIFRoZSB1bmlxdWUgaWRlbnRpZmllciAoVVJJKSBvZiB0aGUgZmVhdHVyZS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBUaHJvd24gZm9yIGNvbmZpZ3VyYXRpb24gZXJyb3IuCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluIGdlbmVyYWwsIGNvbXBvbmVudHMgc2hvdWxkCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9ubHkgdGhyb3cgdGhpcyBleGNlcHRpb24gaWYKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXQgaXMgPHN0cm9uZz5yZWFsbHk8L3N0cm9uZz4KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYSBjcml0aWNhbCBlcnJvci4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgRmVhdHVyZVN0YXRlIGNoZWNrRmVhdHVyZShTdHJpbmcgZmVhdHVyZUlkKQotICAgICAgICB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gWGVyY2VzIEZlYXR1cmVzCi0gICAgICAgIC8vCi0KLSAgICAgICAgaWYgKGZlYXR1cmVJZC5zdGFydHNXaXRoKENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVgpKSB7Ci0gICAgICAgICAgICBmaW5hbCBpbnQgc3VmZml4TGVuZ3RoID0gZmVhdHVyZUlkLmxlbmd0aCgpIC0gQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWC5sZW5ndGgoKTsKLQotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIC8vIGh0dHA6Ly9hcGFjaGUub3JnL3htbC9mZWF0dXJlcy92YWxpZGF0aW9uL3NjaGVtYQotICAgICAgICAgICAgLy8gICBMZXRzIHRoZSB1c2VyIHR1cm4gU2NoZW1hIHZhbGlkYXRpb24gc3VwcG9ydCBvbi9vZmYuCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgaWYgKHN1ZmZpeExlbmd0aCA9PSBDb25zdGFudHMuU0NIRU1BX1ZBTElEQVRJT05fRkVBVFVSRS5sZW5ndGgoKSAmJgotICAgICAgICAgICAgICAgIGZlYXR1cmVJZC5lbmRzV2l0aChDb25zdGFudHMuU0NIRU1BX1ZBTElEQVRJT05fRkVBVFVSRSkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gRmVhdHVyZVN0YXRlLlJFQ09HTklaRUQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyBhY3RpdmF0ZSBmdWxsIHNjaGVtYSBjaGVja2luZwotICAgICAgICAgICAgaWYgKHN1ZmZpeExlbmd0aCA9PSBDb25zdGFudHMuU0NIRU1BX0ZVTExfQ0hFQ0tJTkcubGVuZ3RoKCkgJiYKLSAgICAgICAgICAgICAgICBmZWF0dXJlSWQuZW5kc1dpdGgoQ29uc3RhbnRzLlNDSEVNQV9GVUxMX0NIRUNLSU5HKSkgewotICAgICAgICAgICAgICAgIHJldHVybiBGZWF0dXJlU3RhdGUuUkVDT0dOSVpFRDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIEZlYXR1cmUgaWRlbnRpZmllcjogZXhwb3NlIHNjaGVtYSBub3JtYWxpemVkIHZhbHVlCi0gICAgICAgICAgICAvLyAgaHR0cDovL2FwYWNoZS5vcmcveG1sL2ZlYXR1cmVzL3ZhbGlkYXRpb24vc2NoZW1hL25vcm1hbGl6ZWQtdmFsdWUKLSAgICAgICAgICAgIGlmIChzdWZmaXhMZW5ndGggPT0gQ29uc3RhbnRzLlNDSEVNQV9OT1JNQUxJWkVEX1ZBTFVFLmxlbmd0aCgpICYmCi0gICAgICAgICAgICAgICAgZmVhdHVyZUlkLmVuZHNXaXRoKENvbnN0YW50cy5TQ0hFTUFfTk9STUFMSVpFRF9WQUxVRSkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gRmVhdHVyZVN0YXRlLlJFQ09HTklaRUQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyBGZWF0dXJlIGlkZW50aWZpZXI6IHNlbmQgZWxlbWVudCBkZWZhdWx0IHZhbHVlIHZpYSBjaGFyYWN0ZXJzKCkKLSAgICAgICAgICAgIC8vIGh0dHA6Ly9hcGFjaGUub3JnL3htbC9mZWF0dXJlcy92YWxpZGF0aW9uL3NjaGVtYS9lbGVtZW50LWRlZmF1bHQKLSAgICAgICAgICAgIGlmIChzdWZmaXhMZW5ndGggPT0gQ29uc3RhbnRzLlNDSEVNQV9FTEVNRU5UX0RFRkFVTFQubGVuZ3RoKCkgJiYKLSAgICAgICAgICAgICAgICBmZWF0dXJlSWQuZW5kc1dpdGgoQ29uc3RhbnRzLlNDSEVNQV9FTEVNRU5UX0RFRkFVTFQpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIEZlYXR1cmVTdGF0ZS5SRUNPR05JWkVEOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gTm90IHJlY29nbml6ZWQKLSAgICAgICAgLy8KLQotICAgICAgICByZXR1cm4gc3VwZXIuY2hlY2tGZWF0dXJlKGZlYXR1cmVJZCk7Ci0KLSAgICB9IC8vIGNoZWNrRmVhdHVyZShTdHJpbmcpCi0KLSAgICAvKioKLSAgICAgKiBDaGVjayBhIHByb3BlcnR5LiBJZiB0aGUgcHJvcGVydHkgaXMga25vdyBhbmQgc3VwcG9ydGVkLCB0aGlzIG1ldGhvZAotICAgICAqIHNpbXBseSByZXR1cm5zLiBPdGhlcndpc2UsIHRoZSBhcHByb3ByaWF0ZSBleGNlcHRpb24gaXMgdGhyb3duLgotICAgICAqCi0gICAgICogQHBhcmFtIHByb3BlcnR5SWQgVGhlIHVuaXF1ZSBpZGVudGlmaWVyIChVUkkpIG9mIHRoZSBwcm9wZXJ0eQotICAgICAqICAgICAgICAgICAgICAgICAgIGJlaW5nIHNldC4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBUaHJvd24gZm9yIGNvbmZpZ3VyYXRpb24gZXJyb3IuCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluIGdlbmVyYWwsIGNvbXBvbmVudHMgc2hvdWxkCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9ubHkgdGhyb3cgdGhpcyBleGNlcHRpb24gaWYKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXQgaXMgPHN0cm9uZz5yZWFsbHk8L3N0cm9uZz4KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYSBjcml0aWNhbCBlcnJvci4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgUHJvcGVydHlTdGF0ZSBjaGVja1Byb3BlcnR5KFN0cmluZyBwcm9wZXJ0eUlkKQotICAgICAgICB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gWGVyY2VzIFByb3BlcnRpZXMKLSAgICAgICAgLy8KLQotICAgICAgICBpZiAocHJvcGVydHlJZC5zdGFydHNXaXRoKENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYKSkgewotICAgICAgICAgICAgZmluYWwgaW50IHN1ZmZpeExlbmd0aCA9IHByb3BlcnR5SWQubGVuZ3RoKCkgLSBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWC5sZW5ndGgoKTsKLQotICAgICAgICAgICAgaWYgKHN1ZmZpeExlbmd0aCA9PSBDb25zdGFudHMuU0NIRU1BX0xPQ0FUSU9OLmxlbmd0aCgpICYmCi0gICAgICAgICAgICAgICAgcHJvcGVydHlJZC5lbmRzV2l0aChDb25zdGFudHMuU0NIRU1BX0xPQ0FUSU9OKSkgewotICAgICAgICAgICAgICAgIHJldHVybiBQcm9wZXJ0eVN0YXRlLlJFQ09HTklaRUQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoc3VmZml4TGVuZ3RoID09IENvbnN0YW50cy5TQ0hFTUFfTk9OU19MT0NBVElPTi5sZW5ndGgoKSAmJgotICAgICAgICAgICAgICAgIHByb3BlcnR5SWQuZW5kc1dpdGgoQ29uc3RhbnRzLlNDSEVNQV9OT05TX0xPQ0FUSU9OKSkgewotICAgICAgICAgICAgICAgIHJldHVybiBQcm9wZXJ0eVN0YXRlLlJFQ09HTklaRUQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAocHJvcGVydHlJZC5zdGFydHNXaXRoKENvbnN0YW50cy5KQVhQX1BST1BFUlRZX1BSRUZJWCkpIHsKLSAgICAgICAgICAgIGZpbmFsIGludCBzdWZmaXhMZW5ndGggPSBwcm9wZXJ0eUlkLmxlbmd0aCgpIC0gQ29uc3RhbnRzLkpBWFBfUFJPUEVSVFlfUFJFRklYLmxlbmd0aCgpOwotCi0gICAgICAgICAgICBpZiAoc3VmZml4TGVuZ3RoID09IENvbnN0YW50cy5TQ0hFTUFfU09VUkNFLmxlbmd0aCgpICYmCi0gICAgICAgICAgICAgICAgcHJvcGVydHlJZC5lbmRzV2l0aChDb25zdGFudHMuU0NIRU1BX1NPVVJDRSkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gUHJvcGVydHlTdGF0ZS5SRUNPR05JWkVEOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gTm90IHJlY29nbml6ZWQKLSAgICAgICAgLy8KLQotICAgICAgICByZXR1cm4gc3VwZXIuY2hlY2tQcm9wZXJ0eShwcm9wZXJ0eUlkKTsKLQotICAgIH0gLy8gY2hlY2tQcm9wZXJ0eShTdHJpbmcpCi0KLX0gLy8gY2xhc3MgU3RhbmRhcmRQYXJzZXJDb25maWd1cmF0aW9uCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9wYXJzZXJzL1hJbmNsdWRlQXdhcmVQYXJzZXJDb25maWd1cmF0aW9uLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9wYXJzZXJzL1hJbmNsdWRlQXdhcmVQYXJzZXJDb25maWd1cmF0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDViNzk1ZTUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvcGFyc2Vycy9YSW5jbHVkZUF3YXJlUGFyc2VyQ29uZmlndXJhdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjk3ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwucGFyc2VyczsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5Db25zdGFudHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLkZlYXR1cmVTdGF0ZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuTmFtZXNwYWNlU3VwcG9ydDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuU3ltYm9sVGFibGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54aW5jbHVkZS5YSW5jbHVkZUhhbmRsZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54aW5jbHVkZS5YSW5jbHVkZU5hbWVzcGFjZVN1cHBvcnQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuTmFtZXNwYWNlQ29udGV4dDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxEb2N1bWVudEhhbmRsZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuZ3JhbW1hcnMuWE1MR3JhbW1hclBvb2w7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTENvbXBvbmVudE1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTERvY3VtZW50U291cmNlOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgaXMgdGhlIGNvbmZpZ3VyYXRpb24gdXNlZCB0byBwYXJzZSBYTUwgMS4wIGFuZCBYTUwgMS4xIGRvY3VtZW50cwotICogYW5kIHByb3ZpZGVzIHN1cHBvcnQgZm9yIFhJbmNsdWRlLiBUaGlzIGlzIHRoZSBkZWZhdWx0IFhlcmNlcyBjb25maWd1cmF0aW9uLgotICoKLSAqIEBhdXRob3IgTWljaGFlbCBHbGF2YXNzZXZpY2gsIElCTQotICoKLSAqIEB2ZXJzaW9uICRJZDogWEluY2x1ZGVBd2FyZVBhcnNlckNvbmZpZ3VyYXRpb24uamF2YSx2IDEuNSAyMDEwLTExLTAxIDA0OjQwOjEwIGpvZWh3IEV4cCAkCi0gKi8KLXB1YmxpYyBjbGFzcyBYSW5jbHVkZUF3YXJlUGFyc2VyQ29uZmlndXJhdGlvbiBleHRlbmRzIFhNTDExQ29uZmlndXJhdGlvbiB7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiBhbGxvdyBub3RhdGlvbiBhbmQgdW5wYXJzZWQgZW50aXR5IGV2ZW50cyB0byBiZSBzZW50IG91dCBvZiBvcmRlci4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBBTExPV19VRV9BTkRfTk9UQVRJT05fRVZFTlRTID0KLSAgICAgICAgQ29uc3RhbnRzLlNBWF9GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5BTExPV19EVERfRVZFTlRTX0FGVEVSX0VORERURF9GRUFUVVJFOwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogZml4dXAgYmFzZSBVUklzLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFhJTkNMVURFX0ZJWFVQX0JBU0VfVVJJUyA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuWElOQ0xVREVfRklYVVBfQkFTRV9VUklTX0ZFQVRVUkU7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiBmaXh1cCBsYW5ndWFnZS4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBYSU5DTFVERV9GSVhVUF9MQU5HVUFHRSA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuWElOQ0xVREVfRklYVVBfTEFOR1VBR0VfRkVBVFVSRTsKLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IFhJbmNsdWRlIHByb2Nlc3NpbmcgKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBYSU5DTFVERV9GRUFUVVJFID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5YSU5DTFVERV9GRUFUVVJFOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IGVycm9yIHJlcG9ydGVyLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFhJTkNMVURFX0hBTkRMRVIgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5YSU5DTFVERV9IQU5ETEVSX1BST1BFUlRZOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IGVycm9yIHJlcG9ydGVyLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIE5BTUVTUEFDRV9DT05URVhUID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuTkFNRVNQQUNFX0NPTlRFWFRfUFJPUEVSVFk7Ci0KLSAgICAvLwotICAgIC8vIENvbXBvbmVudHMKLSAgICAvLwotCi0gICAgLyoqIFhJbmNsdWRlIGhhbmRsZXIuICovCi0gICAgcHJvdGVjdGVkIFhJbmNsdWRlSGFuZGxlciBmWEluY2x1ZGVIYW5kbGVyOwotCi0gICAgLyoqIE5vbi1YSW5jbHVkZSBOYW1lc3BhY2VDb250ZXh0LiAqLwotICAgIHByb3RlY3RlZCBOYW1lc3BhY2VTdXBwb3J0IGZOb25YSW5jbHVkZU5TQ29udGV4dDsKLQotICAgIC8qKiBYSW5jbHVkZSBOYW1lc3BhY2VDb250ZXh0LiAqLwotICAgIHByb3RlY3RlZCBYSW5jbHVkZU5hbWVzcGFjZVN1cHBvcnQgZlhJbmNsdWRlTlNDb250ZXh0OwotCi0gICAgLyoqIEN1cnJlbnQgTmFtZXNwYWNlQ29udGV4dC4gKi8KLSAgICBwcm90ZWN0ZWQgTmFtZXNwYWNlQ29udGV4dCBmQ3VycmVudE5TQ29udGV4dDsKLQotICAgIC8qKiBGbGFnIGluZGljYXRpbmcgd2hldGhlciBYSW5jbHVkZSBwcm9jZXNzc2luZyBpcyBlbmFibGVkLiAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIGZYSW5jbHVkZUVuYWJsZWQgPSBmYWxzZTsKLQotICAgIC8qKiBEZWZhdWx0IGNvbnN0cnVjdG9yLiAqLwotICAgIHB1YmxpYyBYSW5jbHVkZUF3YXJlUGFyc2VyQ29uZmlndXJhdGlvbigpIHsKLSAgICAgICAgdGhpcyhudWxsLCBudWxsLCBudWxsKTsKLSAgICB9IC8vIDxpbml0PigpCi0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RzIGEgcGFyc2VyIGNvbmZpZ3VyYXRpb24gdXNpbmcgdGhlIHNwZWNpZmllZCBzeW1ib2wgdGFibGUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc3ltYm9sVGFibGUgVGhlIHN5bWJvbCB0YWJsZSB0byB1c2UuCi0gICAgICovCi0gICAgcHVibGljIFhJbmNsdWRlQXdhcmVQYXJzZXJDb25maWd1cmF0aW9uKFN5bWJvbFRhYmxlIHN5bWJvbFRhYmxlKSB7Ci0gICAgICAgIHRoaXMoc3ltYm9sVGFibGUsIG51bGwsIG51bGwpOwotICAgIH0gLy8gPGluaXQ+KFN5bWJvbFRhYmxlKQotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0cyBhIHBhcnNlciBjb25maWd1cmF0aW9uIHVzaW5nIHRoZSBzcGVjaWZpZWQgc3ltYm9sIHRhYmxlIGFuZAotICAgICAqIGdyYW1tYXIgcG9vbC4KLSAgICAgKiA8cD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzeW1ib2xUYWJsZSBUaGUgc3ltYm9sIHRhYmxlIHRvIHVzZS4KLSAgICAgKiBAcGFyYW0gZ3JhbW1hclBvb2wgVGhlIGdyYW1tYXIgcG9vbCB0byB1c2UuCi0gICAgICovCi0gICAgcHVibGljIFhJbmNsdWRlQXdhcmVQYXJzZXJDb25maWd1cmF0aW9uKAotICAgICAgICAgICAgU3ltYm9sVGFibGUgc3ltYm9sVGFibGUsCi0gICAgICAgICAgICBYTUxHcmFtbWFyUG9vbCBncmFtbWFyUG9vbCkgewotICAgICAgICB0aGlzKHN5bWJvbFRhYmxlLCBncmFtbWFyUG9vbCwgbnVsbCk7Ci0gICAgfSAvLyA8aW5pdD4oU3ltYm9sVGFibGUsWE1MR3JhbW1hclBvb2wpCi0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RzIGEgcGFyc2VyIGNvbmZpZ3VyYXRpb24gdXNpbmcgdGhlIHNwZWNpZmllZCBzeW1ib2wgdGFibGUsCi0gICAgICogZ3JhbW1hciBwb29sLCBhbmQgcGFyZW50IHNldHRpbmdzLgotICAgICAqIDxwPgotICAgICAqCi0gICAgICogQHBhcmFtIHN5bWJvbFRhYmxlICAgIFRoZSBzeW1ib2wgdGFibGUgdG8gdXNlLgotICAgICAqIEBwYXJhbSBncmFtbWFyUG9vbCAgICBUaGUgZ3JhbW1hciBwb29sIHRvIHVzZS4KLSAgICAgKiBAcGFyYW0gcGFyZW50U2V0dGluZ3MgVGhlIHBhcmVudCBzZXR0aW5ncy4KLSAgICAgKi8KLSAgICBwdWJsaWMgWEluY2x1ZGVBd2FyZVBhcnNlckNvbmZpZ3VyYXRpb24oCi0gICAgICAgICAgICBTeW1ib2xUYWJsZSBzeW1ib2xUYWJsZSwKLSAgICAgICAgICAgIFhNTEdyYW1tYXJQb29sIGdyYW1tYXJQb29sLAotICAgICAgICAgICAgWE1MQ29tcG9uZW50TWFuYWdlciBwYXJlbnRTZXR0aW5ncykgewotICAgICAgICBzdXBlcihzeW1ib2xUYWJsZSwgZ3JhbW1hclBvb2wsIHBhcmVudFNldHRpbmdzKTsKLQotICAgICAgICBmaW5hbCBTdHJpbmdbXSByZWNvZ25pemVkRmVhdHVyZXMgPSB7Ci0gICAgICAgICAgICAgICAgQUxMT1dfVUVfQU5EX05PVEFUSU9OX0VWRU5UUywKLSAgICAgICAgICAgICAgICBYSU5DTFVERV9GSVhVUF9CQVNFX1VSSVMsCi0gICAgICAgICAgICAgICAgWElOQ0xVREVfRklYVVBfTEFOR1VBR0UKLSAgICAgICAgfTsKLSAgICAgICAgYWRkUmVjb2duaXplZEZlYXR1cmVzKHJlY29nbml6ZWRGZWF0dXJlcyk7Ci0KLSAgICAgICAgLy8gYWRkIGRlZmF1bHQgcmVjb2duaXplZCBwcm9wZXJ0aWVzCi0gICAgICAgIGZpbmFsIFN0cmluZ1tdIHJlY29nbml6ZWRQcm9wZXJ0aWVzID0KLSAgICAgICAgeyBYSU5DTFVERV9IQU5ETEVSLCBOQU1FU1BBQ0VfQ09OVEVYVCB9OwotICAgICAgICBhZGRSZWNvZ25pemVkUHJvcGVydGllcyhyZWNvZ25pemVkUHJvcGVydGllcyk7Ci0KLSAgICAgICAgc2V0RmVhdHVyZShBTExPV19VRV9BTkRfTk9UQVRJT05fRVZFTlRTLCB0cnVlKTsKLSAgICAgICAgc2V0RmVhdHVyZShYSU5DTFVERV9GSVhVUF9CQVNFX1VSSVMsIHRydWUpOwotICAgICAgICBzZXRGZWF0dXJlKFhJTkNMVURFX0ZJWFVQX0xBTkdVQUdFLCB0cnVlKTsKLQotICAgICAgICBmTm9uWEluY2x1ZGVOU0NvbnRleHQgPSBuZXcgTmFtZXNwYWNlU3VwcG9ydCgpOwotICAgICAgICBmQ3VycmVudE5TQ29udGV4dCA9IGZOb25YSW5jbHVkZU5TQ29udGV4dDsKLSAgICAgICAgc2V0UHJvcGVydHkoTkFNRVNQQUNFX0NPTlRFWFQsIGZOb25YSW5jbHVkZU5TQ29udGV4dCk7Ci0gICAgfQotCi0KLSAgICAvKiogQ29uZmlndXJlcyB0aGUgcGlwZWxpbmUuICovCi0gICAgcHJvdGVjdGVkIHZvaWQgY29uZmlndXJlUGlwZWxpbmUoKSB7Ci0gICAgICAgIHN1cGVyLmNvbmZpZ3VyZVBpcGVsaW5lKCk7Ci0gICAgICAgIGlmIChmWEluY2x1ZGVFbmFibGVkKSB7Ci0gICAgICAgICAgICAvLyBJZiB0aGUgWEluY2x1ZGUgaGFuZGxlciB3YXMgbm90IGluIHRoZSBwaXBlbGluZSBpbnNlcnQgaXQuCi0gICAgICAgICAgICBpZiAoZlhJbmNsdWRlSGFuZGxlciA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZlhJbmNsdWRlSGFuZGxlciA9IG5ldyBYSW5jbHVkZUhhbmRsZXIoKTsKLSAgICAgICAgICAgICAgICAvLyBhZGQgWEluY2x1ZGUgY29tcG9uZW50Ci0gICAgICAgICAgICAgICAgc2V0UHJvcGVydHkoWElOQ0xVREVfSEFORExFUiwgZlhJbmNsdWRlSGFuZGxlcik7Ci0gICAgICAgICAgICAgICAgYWRkQ29tbW9uQ29tcG9uZW50KGZYSW5jbHVkZUhhbmRsZXIpOwotICAgICAgICAgICAgICAgIGZYSW5jbHVkZUhhbmRsZXIucmVzZXQodGhpcyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyBTZXR1cCBOYW1lc3BhY2VDb250ZXh0Ci0gICAgICAgICAgICBpZiAoZkN1cnJlbnROU0NvbnRleHQgIT0gZlhJbmNsdWRlTlNDb250ZXh0KSB7Ci0gICAgICAgICAgICAgICAgaWYgKGZYSW5jbHVkZU5TQ29udGV4dCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZYSW5jbHVkZU5TQ29udGV4dCA9IG5ldyBYSW5jbHVkZU5hbWVzcGFjZVN1cHBvcnQoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZkN1cnJlbnROU0NvbnRleHQgPSBmWEluY2x1ZGVOU0NvbnRleHQ7Ci0gICAgICAgICAgICAgICAgc2V0UHJvcGVydHkoTkFNRVNQQUNFX0NPTlRFWFQsIGZYSW5jbHVkZU5TQ29udGV4dCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvL2NvbmZpZ3VyZSBEVEQgcGlwZWxpbmUKLSAgICAgICAgICAgIGZEVERTY2FubmVyLnNldERUREhhbmRsZXIoZkRURFByb2Nlc3Nvcik7Ci0gICAgICAgICAgICBmRFREUHJvY2Vzc29yLnNldERURFNvdXJjZShmRFREU2Nhbm5lcik7Ci0gICAgICAgICAgICBmRFREUHJvY2Vzc29yLnNldERUREhhbmRsZXIoZlhJbmNsdWRlSGFuZGxlcik7Ci0gICAgICAgICAgICBmWEluY2x1ZGVIYW5kbGVyLnNldERURFNvdXJjZShmRFREUHJvY2Vzc29yKTsKLSAgICAgICAgICAgIGZYSW5jbHVkZUhhbmRsZXIuc2V0RFRESGFuZGxlcihmRFRESGFuZGxlcik7Ci0gICAgICAgICAgICBpZiAoZkRUREhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZEVERIYW5kbGVyLnNldERURFNvdXJjZShmWEluY2x1ZGVIYW5kbGVyKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gY29uZmlndXJlIFhNTCBkb2N1bWVudCBwaXBlbGluZTogaW5zZXJ0IGFmdGVyIERURFZhbGlkYXRvciBhbmQKLSAgICAgICAgICAgIC8vIGJlZm9yZSBYTUwgU2NoZW1hIHZhbGlkYXRvcgotICAgICAgICAgICAgWE1MRG9jdW1lbnRTb3VyY2UgcHJldiA9IG51bGw7Ci0gICAgICAgICAgICBpZiAoZkZlYXR1cmVzLmdldChYTUxTQ0hFTUFfVkFMSURBVElPTikgPT0gQm9vbGVhbi5UUlVFKSB7Ci0gICAgICAgICAgICAgICAgLy8gd2UgZG9uJ3QgaGF2ZSB0byB3b3JyeSBhYm91dCBmU2NoZW1hVmFsaWRhdG9yIGJlaW5nIG51bGwsIHNpbmNlCi0gICAgICAgICAgICAgICAgLy8gc3VwZXIuY29uZmlndXJlUGlwZWxpbmUoKSBpbnN0YW50aWF0ZWQgaXQgaWYgdGhlIGZlYXR1cmUgd2FzIHNldAotICAgICAgICAgICAgICAgIHByZXYgPSBmU2NoZW1hVmFsaWRhdG9yLmdldERvY3VtZW50U291cmNlKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyBPdGhlcndpc2UsIGluc2VydCBhZnRlciB0aGUgbGFzdCBjb21wb25lbnQgaW4gdGhlIHBpcGVsaW5lCi0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBwcmV2ID0gZkxhc3RDb21wb25lbnQ7Ci0gICAgICAgICAgICAgICAgZkxhc3RDb21wb25lbnQgPSBmWEluY2x1ZGVIYW5kbGVyOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBYTUxEb2N1bWVudEhhbmRsZXIgbmV4dCA9IHByZXYuZ2V0RG9jdW1lbnRIYW5kbGVyKCk7Ci0gICAgICAgICAgICBwcmV2LnNldERvY3VtZW50SGFuZGxlcihmWEluY2x1ZGVIYW5kbGVyKTsKLSAgICAgICAgICAgIGZYSW5jbHVkZUhhbmRsZXIuc2V0RG9jdW1lbnRTb3VyY2UocHJldik7Ci0gICAgICAgICAgICBpZiAobmV4dCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZlhJbmNsdWRlSGFuZGxlci5zZXREb2N1bWVudEhhbmRsZXIobmV4dCk7Ci0gICAgICAgICAgICAgICAgbmV4dC5zZXREb2N1bWVudFNvdXJjZShmWEluY2x1ZGVIYW5kbGVyKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIC8vIFNldHVwIE5hbWVzcGFjZUNvbnRleHQKLSAgICAgICAgICAgIGlmIChmQ3VycmVudE5TQ29udGV4dCAhPSBmTm9uWEluY2x1ZGVOU0NvbnRleHQpIHsKLSAgICAgICAgICAgICAgICBmQ3VycmVudE5TQ29udGV4dCA9IGZOb25YSW5jbHVkZU5TQ29udGV4dDsKLSAgICAgICAgICAgICAgICBzZXRQcm9wZXJ0eShOQU1FU1BBQ0VfQ09OVEVYVCwgZk5vblhJbmNsdWRlTlNDb250ZXh0KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0gLy8gY29uZmlndXJlUGlwZWxpbmUoKQotCi0gICAgcHJvdGVjdGVkIHZvaWQgY29uZmlndXJlWE1MMTFQaXBlbGluZSgpIHsKLSAgICAgICAgc3VwZXIuY29uZmlndXJlWE1MMTFQaXBlbGluZSgpOwotICAgICAgICBpZiAoZlhJbmNsdWRlRW5hYmxlZCkgewotICAgICAgICAgICAgLy8gSWYgdGhlIFhJbmNsdWRlIGhhbmRsZXIgd2FzIG5vdCBpbiB0aGUgcGlwZWxpbmUgaW5zZXJ0IGl0LgotICAgICAgICAgICAgaWYgKGZYSW5jbHVkZUhhbmRsZXIgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZYSW5jbHVkZUhhbmRsZXIgPSBuZXcgWEluY2x1ZGVIYW5kbGVyKCk7Ci0gICAgICAgICAgICAgICAgLy8gYWRkIFhJbmNsdWRlIGNvbXBvbmVudAotICAgICAgICAgICAgICAgIHNldFByb3BlcnR5KFhJTkNMVURFX0hBTkRMRVIsIGZYSW5jbHVkZUhhbmRsZXIpOwotICAgICAgICAgICAgICAgIGFkZENvbW1vbkNvbXBvbmVudChmWEluY2x1ZGVIYW5kbGVyKTsKLSAgICAgICAgICAgICAgICBmWEluY2x1ZGVIYW5kbGVyLnJlc2V0KHRoaXMpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gU2V0dXAgTmFtZXNwYWNlQ29udGV4dAotICAgICAgICAgICAgaWYgKGZDdXJyZW50TlNDb250ZXh0ICE9IGZYSW5jbHVkZU5TQ29udGV4dCkgewotICAgICAgICAgICAgICAgIGlmIChmWEluY2x1ZGVOU0NvbnRleHQgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBmWEluY2x1ZGVOU0NvbnRleHQgPSBuZXcgWEluY2x1ZGVOYW1lc3BhY2VTdXBwb3J0KCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGZDdXJyZW50TlNDb250ZXh0ID0gZlhJbmNsdWRlTlNDb250ZXh0OwotICAgICAgICAgICAgICAgIHNldFByb3BlcnR5KE5BTUVTUEFDRV9DT05URVhULCBmWEluY2x1ZGVOU0NvbnRleHQpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gY29uZmlndXJlIFhNTCAxLjEuIERURCBwaXBlbGluZQotICAgICAgICAgICAgZlhNTDExRFREU2Nhbm5lci5zZXREVERIYW5kbGVyKGZYTUwxMURURFByb2Nlc3Nvcik7Ci0gICAgICAgICAgICBmWE1MMTFEVERQcm9jZXNzb3Iuc2V0RFREU291cmNlKGZYTUwxMURURFNjYW5uZXIpOwotICAgICAgICAgICAgZlhNTDExRFREUHJvY2Vzc29yLnNldERUREhhbmRsZXIoZlhJbmNsdWRlSGFuZGxlcik7Ci0gICAgICAgICAgICBmWEluY2x1ZGVIYW5kbGVyLnNldERURFNvdXJjZShmWE1MMTFEVERQcm9jZXNzb3IpOwotICAgICAgICAgICAgZlhJbmNsdWRlSGFuZGxlci5zZXREVERIYW5kbGVyKGZEVERIYW5kbGVyKTsKLSAgICAgICAgICAgIGlmIChmRFRESGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZkRUREhhbmRsZXIuc2V0RFREU291cmNlKGZYSW5jbHVkZUhhbmRsZXIpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBjb25maWd1cmUgWE1MIGRvY3VtZW50IHBpcGVsaW5lOiBpbnNlcnQgYWZ0ZXIgRFREVmFsaWRhdG9yIGFuZAotICAgICAgICAgICAgLy8gYmVmb3JlIFhNTCBTY2hlbWEgdmFsaWRhdG9yCi0gICAgICAgICAgICBYTUxEb2N1bWVudFNvdXJjZSBwcmV2ID0gbnVsbDsKLSAgICAgICAgICAgIGlmIChmRmVhdHVyZXMuZ2V0KFhNTFNDSEVNQV9WQUxJREFUSU9OKSA9PSBCb29sZWFuLlRSVUUpIHsKLSAgICAgICAgICAgICAgICAvLyB3ZSBkb24ndCBoYXZlIHRvIHdvcnJ5IGFib3V0IGZTY2hlbWFWYWxpZGF0b3IgYmVpbmcgbnVsbCwgc2luY2UKLSAgICAgICAgICAgICAgICAvLyBzdXBlci5jb25maWd1cmVQaXBlbGluZSgpIGluc3RhbnRpYXRlZCBpdCBpZiB0aGUgZmVhdHVyZSB3YXMgc2V0Ci0gICAgICAgICAgICAgICAgcHJldiA9IGZTY2hlbWFWYWxpZGF0b3IuZ2V0RG9jdW1lbnRTb3VyY2UoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIE90aGVyd2lzZSwgaW5zZXJ0IGFmdGVyIHRoZSBsYXN0IGNvbXBvbmVudCBpbiB0aGUgcGlwZWxpbmUKLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIHByZXYgPSBmTGFzdENvbXBvbmVudDsKLSAgICAgICAgICAgICAgICBmTGFzdENvbXBvbmVudCA9IGZYSW5jbHVkZUhhbmRsZXI7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIFhNTERvY3VtZW50SGFuZGxlciBuZXh0ID0gcHJldi5nZXREb2N1bWVudEhhbmRsZXIoKTsKLSAgICAgICAgICAgIHByZXYuc2V0RG9jdW1lbnRIYW5kbGVyKGZYSW5jbHVkZUhhbmRsZXIpOwotICAgICAgICAgICAgZlhJbmNsdWRlSGFuZGxlci5zZXREb2N1bWVudFNvdXJjZShwcmV2KTsKLSAgICAgICAgICAgIGlmIChuZXh0ICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmWEluY2x1ZGVIYW5kbGVyLnNldERvY3VtZW50SGFuZGxlcihuZXh0KTsKLSAgICAgICAgICAgICAgICBuZXh0LnNldERvY3VtZW50U291cmNlKGZYSW5jbHVkZUhhbmRsZXIpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgLy8gU2V0dXAgTmFtZXNwYWNlQ29udGV4dAotICAgICAgICAgICAgaWYgKGZDdXJyZW50TlNDb250ZXh0ICE9IGZOb25YSW5jbHVkZU5TQ29udGV4dCkgewotICAgICAgICAgICAgICAgIGZDdXJyZW50TlNDb250ZXh0ID0gZk5vblhJbmNsdWRlTlNDb250ZXh0OwotICAgICAgICAgICAgICAgIHNldFByb3BlcnR5KE5BTUVTUEFDRV9DT05URVhULCBmTm9uWEluY2x1ZGVOU0NvbnRleHQpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfSAvLyBjb25maWd1cmVYTUwxMVBpcGVsaW5lKCkKLQotICAgIHB1YmxpYyBGZWF0dXJlU3RhdGUgZ2V0RmVhdHVyZVN0YXRlKFN0cmluZyBmZWF0dXJlSWQpCi0gICAgICAgIHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKGZlYXR1cmVJZC5lcXVhbHMoUEFSU0VSX1NFVFRJTkdTKSkgewotICAgICAgICAgICAgcmV0dXJuIEZlYXR1cmVTdGF0ZS5pcyhmQ29uZmlnVXBkYXRlZCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoZmVhdHVyZUlkLmVxdWFscyhYSU5DTFVERV9GRUFUVVJFKSkgewotICAgICAgICAgICAgcmV0dXJuIEZlYXR1cmVTdGF0ZS5pcyhmWEluY2x1ZGVFbmFibGVkKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gc3VwZXIuZ2V0RmVhdHVyZVN0YXRlMChmZWF0dXJlSWQpOwotCi0gICAgfSAvLyBnZXRGZWF0dXJlKFN0cmluZyk6Ym9vbGVhbgotCi0gICAgcHVibGljIHZvaWQgc2V0RmVhdHVyZShTdHJpbmcgZmVhdHVyZUlkLCBib29sZWFuIHN0YXRlKQotICAgICAgICB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChmZWF0dXJlSWQuZXF1YWxzKFhJTkNMVURFX0ZFQVRVUkUpKSB7Ci0gICAgICAgICAgICBmWEluY2x1ZGVFbmFibGVkID0gc3RhdGU7Ci0gICAgICAgICAgICBmQ29uZmlnVXBkYXRlZCA9IHRydWU7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLSAgICAgICAgc3VwZXIuc2V0RmVhdHVyZShmZWF0dXJlSWQsc3RhdGUpOwotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvcGFyc2Vycy9YSW5jbHVkZVBhcnNlckNvbmZpZ3VyYXRpb24uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3BhcnNlcnMvWEluY2x1ZGVQYXJzZXJDb25maWd1cmF0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDI5YzE4ZmEuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvcGFyc2Vycy9YSW5jbHVkZVBhcnNlckNvbmZpZ3VyYXRpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIyMSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnBhcnNlcnM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5TeW1ib2xUYWJsZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhpbmNsdWRlLlhJbmNsdWRlSGFuZGxlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhpbmNsdWRlLlhJbmNsdWRlTmFtZXNwYWNlU3VwcG9ydDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxEb2N1bWVudEhhbmRsZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuZ3JhbW1hcnMuWE1MR3JhbW1hclBvb2w7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTENvbXBvbmVudE1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTERvY3VtZW50U291cmNlOwotCi0vKioKLSAqIFRoaXMgcGFyc2VyIGNvbmZpZ3VyYXRpb24gaW5jbHVkZXMgYW4gPGNvZGU+WEluY2x1ZGVIYW5kbGVyPC9jb2RlPiBpbiB0aGUgcGlwZWxpbmUKLSAqIGJlZm9yZSB0aGUgc2NoZW1hIHZhbGlkYXRvciwgb3IgYXMgdGhlIGxhc3QgY29tcG9uZW50IGluIHRoZSBwaXBlbGluZSBpZiB0aGVyZSBpcwotICogbm8gc2NoZW1hIHZhbGlkYXRvci4gIFVzaW5nIHRoaXMgcGlwZWxpbmUgd2lsbCBlbmFibGUgcHJvY2Vzc2luZyBhY2NvcmRpbmcgdG8gdGhlCi0gKiBYTUwgSW5jbHVzaW9ucyBzcGVjaWZpY2F0aW9uLCB0byB0aGUgY29uZm9ybWFuY2UgbGV2ZWwgZGVzY3JpYmVkIGluCi0gKiA8Y29kZT5YSW5jbHVkZUhhbmRsZXI8L2NvZGU+LgotICoKLSAqIEBhdXRob3IgUGV0ZXIgTWNDcmFja2VuLCBJQk0KLSAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54aW5jbHVkZS5YSW5jbHVkZUhhbmRsZXIKLSAqLwotcHVibGljIGNsYXNzIFhJbmNsdWRlUGFyc2VyQ29uZmlndXJhdGlvbiBleHRlbmRzIFhNTDExQ29uZmlndXJhdGlvbiB7Ci0KLSAgICBwcml2YXRlIFhJbmNsdWRlSGFuZGxlciBmWEluY2x1ZGVIYW5kbGVyOwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogYWxsb3cgbm90YXRpb24gYW5kIHVucGFyc2VkIGVudGl0eSBldmVudHMgdG8gYmUgc2VudCBvdXQgb2Ygb3JkZXIuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgQUxMT1dfVUVfQU5EX05PVEFUSU9OX0VWRU5UUyA9Ci0gICAgICAgIENvbnN0YW50cy5TQVhfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuQUxMT1dfRFREX0VWRU5UU19BRlRFUl9FTkREVERfRkVBVFVSRTsKLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IGZpeHVwIGJhc2UgVVJJcy4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBYSU5DTFVERV9GSVhVUF9CQVNFX1VSSVMgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLlhJTkNMVURFX0ZJWFVQX0JBU0VfVVJJU19GRUFUVVJFOwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogZml4dXAgbGFuZ3VhZ2UuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgWElOQ0xVREVfRklYVVBfTEFOR1VBR0UgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLlhJTkNMVURFX0ZJWFVQX0xBTkdVQUdFX0ZFQVRVUkU7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogZXJyb3IgcmVwb3J0ZXIuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgWElOQ0xVREVfSEFORExFUiA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLlhJTkNMVURFX0hBTkRMRVJfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogZXJyb3IgcmVwb3J0ZXIuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgTkFNRVNQQUNFX0NPTlRFWFQgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5OQU1FU1BBQ0VfQ09OVEVYVF9QUk9QRVJUWTsKLQotICAgIC8qKiBEZWZhdWx0IGNvbnN0cnVjdG9yLiAqLwotICAgIHB1YmxpYyBYSW5jbHVkZVBhcnNlckNvbmZpZ3VyYXRpb24oKSB7Ci0gICAgICAgIHRoaXMobnVsbCwgbnVsbCwgbnVsbCk7Ci0gICAgfSAvLyA8aW5pdD4oKQotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0cyBhIHBhcnNlciBjb25maWd1cmF0aW9uIHVzaW5nIHRoZSBzcGVjaWZpZWQgc3ltYm9sIHRhYmxlLgotICAgICAqCi0gICAgICogQHBhcmFtIHN5bWJvbFRhYmxlIFRoZSBzeW1ib2wgdGFibGUgdG8gdXNlLgotICAgICAqLwotICAgIHB1YmxpYyBYSW5jbHVkZVBhcnNlckNvbmZpZ3VyYXRpb24oU3ltYm9sVGFibGUgc3ltYm9sVGFibGUpIHsKLSAgICAgICAgdGhpcyhzeW1ib2xUYWJsZSwgbnVsbCwgbnVsbCk7Ci0gICAgfSAvLyA8aW5pdD4oU3ltYm9sVGFibGUpCi0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RzIGEgcGFyc2VyIGNvbmZpZ3VyYXRpb24gdXNpbmcgdGhlIHNwZWNpZmllZCBzeW1ib2wgdGFibGUgYW5kCi0gICAgICogZ3JhbW1hciBwb29sLgotICAgICAqIDxwPgotICAgICAqCi0gICAgICogQHBhcmFtIHN5bWJvbFRhYmxlIFRoZSBzeW1ib2wgdGFibGUgdG8gdXNlLgotICAgICAqIEBwYXJhbSBncmFtbWFyUG9vbCBUaGUgZ3JhbW1hciBwb29sIHRvIHVzZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgWEluY2x1ZGVQYXJzZXJDb25maWd1cmF0aW9uKAotICAgICAgICBTeW1ib2xUYWJsZSBzeW1ib2xUYWJsZSwKLSAgICAgICAgWE1MR3JhbW1hclBvb2wgZ3JhbW1hclBvb2wpIHsKLSAgICAgICAgdGhpcyhzeW1ib2xUYWJsZSwgZ3JhbW1hclBvb2wsIG51bGwpOwotICAgIH0gLy8gPGluaXQ+KFN5bWJvbFRhYmxlLFhNTEdyYW1tYXJQb29sKQotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0cyBhIHBhcnNlciBjb25maWd1cmF0aW9uIHVzaW5nIHRoZSBzcGVjaWZpZWQgc3ltYm9sIHRhYmxlLAotICAgICAqIGdyYW1tYXIgcG9vbCwgYW5kIHBhcmVudCBzZXR0aW5ncy4KLSAgICAgKiA8cD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzeW1ib2xUYWJsZSAgICBUaGUgc3ltYm9sIHRhYmxlIHRvIHVzZS4KLSAgICAgKiBAcGFyYW0gZ3JhbW1hclBvb2wgICAgVGhlIGdyYW1tYXIgcG9vbCB0byB1c2UuCi0gICAgICogQHBhcmFtIHBhcmVudFNldHRpbmdzIFRoZSBwYXJlbnQgc2V0dGluZ3MuCi0gICAgICovCi0gICAgcHVibGljIFhJbmNsdWRlUGFyc2VyQ29uZmlndXJhdGlvbigKLSAgICAgICAgU3ltYm9sVGFibGUgc3ltYm9sVGFibGUsCi0gICAgICAgIFhNTEdyYW1tYXJQb29sIGdyYW1tYXJQb29sLAotICAgICAgICBYTUxDb21wb25lbnRNYW5hZ2VyIHBhcmVudFNldHRpbmdzKSB7Ci0gICAgICAgIHN1cGVyKHN5bWJvbFRhYmxlLCBncmFtbWFyUG9vbCwgcGFyZW50U2V0dGluZ3MpOwotCi0gICAgICAgIGZYSW5jbHVkZUhhbmRsZXIgPSBuZXcgWEluY2x1ZGVIYW5kbGVyKCk7Ci0gICAgICAgIGFkZENvbW1vbkNvbXBvbmVudChmWEluY2x1ZGVIYW5kbGVyKTsKLQotICAgICAgICBmaW5hbCBTdHJpbmdbXSByZWNvZ25pemVkRmVhdHVyZXMgPSB7Ci0gICAgICAgICAgICBBTExPV19VRV9BTkRfTk9UQVRJT05fRVZFTlRTLAotICAgICAgICAgICAgWElOQ0xVREVfRklYVVBfQkFTRV9VUklTLAotICAgICAgICAgICAgWElOQ0xVREVfRklYVVBfTEFOR1VBR0UKLSAgICAgICAgfTsKLSAgICAgICAgYWRkUmVjb2duaXplZEZlYXR1cmVzKHJlY29nbml6ZWRGZWF0dXJlcyk7Ci0KLSAgICAgICAgLy8gYWRkIGRlZmF1bHQgcmVjb2duaXplZCBwcm9wZXJ0aWVzCi0gICAgICAgIGZpbmFsIFN0cmluZ1tdIHJlY29nbml6ZWRQcm9wZXJ0aWVzID0KLSAgICAgICAgICAgIHsgWElOQ0xVREVfSEFORExFUiwgTkFNRVNQQUNFX0NPTlRFWFQgfTsKLSAgICAgICAgYWRkUmVjb2duaXplZFByb3BlcnRpZXMocmVjb2duaXplZFByb3BlcnRpZXMpOwotCi0gICAgICAgIHNldEZlYXR1cmUoQUxMT1dfVUVfQU5EX05PVEFUSU9OX0VWRU5UUywgdHJ1ZSk7Ci0gICAgICAgIHNldEZlYXR1cmUoWElOQ0xVREVfRklYVVBfQkFTRV9VUklTLCB0cnVlKTsKLSAgICAgICAgc2V0RmVhdHVyZShYSU5DTFVERV9GSVhVUF9MQU5HVUFHRSwgdHJ1ZSk7Ci0KLSAgICAgICAgc2V0UHJvcGVydHkoWElOQ0xVREVfSEFORExFUiwgZlhJbmNsdWRlSGFuZGxlcik7Ci0gICAgICAgIHNldFByb3BlcnR5KE5BTUVTUEFDRV9DT05URVhULCBuZXcgWEluY2x1ZGVOYW1lc3BhY2VTdXBwb3J0KCkpOwotICAgIH0gLy8gPGluaXQ+KFN5bWJvbFRhYmxlLFhNTEdyYW1tYXJQb29sKX0KLQotCi0gICAgICAgIC8qKiBDb25maWd1cmVzIHRoZSBwaXBlbGluZS4gKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCBjb25maWd1cmVQaXBlbGluZSgpIHsKLSAgICAgICAgc3VwZXIuY29uZmlndXJlUGlwZWxpbmUoKTsKLQotICAgICAgICAvL2NvbmZpZ3VyZSBEVEQgcGlwZWxpbmUKLSAgICAgICAgZkRURFNjYW5uZXIuc2V0RFRESGFuZGxlcihmRFREUHJvY2Vzc29yKTsKLSAgICAgICAgZkRURFByb2Nlc3Nvci5zZXREVERTb3VyY2UoZkRURFNjYW5uZXIpOwotICAgICAgICBmRFREUHJvY2Vzc29yLnNldERUREhhbmRsZXIoZlhJbmNsdWRlSGFuZGxlcik7Ci0gICAgICAgIGZYSW5jbHVkZUhhbmRsZXIuc2V0RFREU291cmNlKGZEVERQcm9jZXNzb3IpOwotICAgICAgICAgICAgICAgIGZYSW5jbHVkZUhhbmRsZXIuc2V0RFRESGFuZGxlcihmRFRESGFuZGxlcik7Ci0gICAgICAgIGlmIChmRFRESGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmRFRESGFuZGxlci5zZXREVERTb3VyY2UoZlhJbmNsdWRlSGFuZGxlcik7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBjb25maWd1cmUgWE1MIGRvY3VtZW50IHBpcGVsaW5lOiBpbnNlcnQgYWZ0ZXIgRFREVmFsaWRhdG9yIGFuZAotICAgICAgICAvLyBiZWZvcmUgWE1MIFNjaGVtYSB2YWxpZGF0b3IKLSAgICAgICAgWE1MRG9jdW1lbnRTb3VyY2UgcHJldiA9IG51bGw7Ci0gICAgICAgIGlmIChmRmVhdHVyZXMuZ2V0KFhNTFNDSEVNQV9WQUxJREFUSU9OKSA9PSBCb29sZWFuLlRSVUUpIHsKLSAgICAgICAgICAgIC8vIHdlIGRvbid0IGhhdmUgdG8gd29ycnkgYWJvdXQgZlNjaGVtYVZhbGlkYXRvciBiZWluZyBudWxsLCBzaW5jZQotICAgICAgICAgICAgLy8gc3VwZXIuY29uZmlndXJlUGlwZWxpbmUoKSBpbnN0YW50aWF0ZWQgaXQgaWYgdGhlIGZlYXR1cmUgd2FzIHNldAotICAgICAgICAgICAgcHJldiA9IGZTY2hlbWFWYWxpZGF0b3IuZ2V0RG9jdW1lbnRTb3VyY2UoKTsKLSAgICAgICAgfQotICAgICAgICAvLyBPdGhlcndpc2UsIGluc2VydCBhZnRlciB0aGUgbGFzdCBjb21wb25lbnQgaW4gdGhlIHBpcGVsaW5lCi0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgcHJldiA9IGZMYXN0Q29tcG9uZW50OwotICAgICAgICAgICAgZkxhc3RDb21wb25lbnQgPSBmWEluY2x1ZGVIYW5kbGVyOwotICAgICAgICB9Ci0KLSAgICAgICAgIGlmIChwcmV2ICE9IG51bGwpIHsKLSAgICAgICAgICAgIFhNTERvY3VtZW50SGFuZGxlciBuZXh0ID0gcHJldi5nZXREb2N1bWVudEhhbmRsZXIoKTsKLSAgICAgICAgICAgIHByZXYuc2V0RG9jdW1lbnRIYW5kbGVyKGZYSW5jbHVkZUhhbmRsZXIpOwotICAgICAgICAgICAgZlhJbmNsdWRlSGFuZGxlci5zZXREb2N1bWVudFNvdXJjZShwcmV2KTsKLSAgICAgICAgICAgIGlmIChuZXh0ICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmWEluY2x1ZGVIYW5kbGVyLnNldERvY3VtZW50SGFuZGxlcihuZXh0KTsKLSAgICAgICAgICAgICAgICBuZXh0LnNldERvY3VtZW50U291cmNlKGZYSW5jbHVkZUhhbmRsZXIpOwotICAgICAgICAgICAgfQotICAgICAgICAgfQotICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBzZXREb2N1bWVudEhhbmRsZXIoZlhJbmNsdWRlSGFuZGxlcik7Ci0gICAgICAgICB9Ci0KLSAgICB9IC8vIGNvbmZpZ3VyZVBpcGVsaW5lKCkKLQotICAgICAgICBwcm90ZWN0ZWQgdm9pZCBjb25maWd1cmVYTUwxMVBpcGVsaW5lKCkgewotICAgICAgICAgICAgICAgIHN1cGVyLmNvbmZpZ3VyZVhNTDExUGlwZWxpbmUoKTsKLQotICAgICAgICAvLyBjb25maWd1cmUgWE1MIDEuMS4gRFREIHBpcGVsaW5lCi0gICAgICAgICAgICAgICAgZlhNTDExRFREU2Nhbm5lci5zZXREVERIYW5kbGVyKGZYTUwxMURURFByb2Nlc3Nvcik7Ci0gICAgICAgICAgICAgICAgZlhNTDExRFREUHJvY2Vzc29yLnNldERURFNvdXJjZShmWE1MMTFEVERTY2FubmVyKTsKLSAgICAgICAgICAgICAgICBmWE1MMTFEVERQcm9jZXNzb3Iuc2V0RFRESGFuZGxlcihmWEluY2x1ZGVIYW5kbGVyKTsKLSAgICAgICAgICAgICAgICBmWEluY2x1ZGVIYW5kbGVyLnNldERURFNvdXJjZShmWE1MMTFEVERQcm9jZXNzb3IpOwotICAgICAgICAgICAgICAgIGZYSW5jbHVkZUhhbmRsZXIuc2V0RFRESGFuZGxlcihmRFRESGFuZGxlcik7Ci0gICAgICAgICAgICAgICAgaWYgKGZEVERIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZEVERIYW5kbGVyLnNldERURFNvdXJjZShmWEluY2x1ZGVIYW5kbGVyKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyBjb25maWd1cmUgWE1MIGRvY3VtZW50IHBpcGVsaW5lOiBpbnNlcnQgYWZ0ZXIgRFREVmFsaWRhdG9yIGFuZAotICAgICAgICAgICAgICAgIC8vIGJlZm9yZSBYTUwgU2NoZW1hIHZhbGlkYXRvcgotICAgICAgICAgICAgICAgIFhNTERvY3VtZW50U291cmNlIHByZXYgPSBudWxsOwotICAgICAgICAgICAgICAgIGlmIChmRmVhdHVyZXMuZ2V0KFhNTFNDSEVNQV9WQUxJREFUSU9OKSA9PSBCb29sZWFuLlRSVUUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIHdlIGRvbid0IGhhdmUgdG8gd29ycnkgYWJvdXQgZlNjaGVtYVZhbGlkYXRvciBiZWluZyBudWxsLCBzaW5jZQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gc3VwZXIuY29uZmlndXJlUGlwZWxpbmUoKSBpbnN0YW50aWF0ZWQgaXQgaWYgdGhlIGZlYXR1cmUgd2FzIHNldAotICAgICAgICAgICAgICAgICAgICAgICAgcHJldiA9IGZTY2hlbWFWYWxpZGF0b3IuZ2V0RG9jdW1lbnRTb3VyY2UoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLy8gT3RoZXJ3aXNlLCBpbnNlcnQgYWZ0ZXIgdGhlIGxhc3QgY29tcG9uZW50IGluIHRoZSBwaXBlbGluZQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgcHJldiA9IGZMYXN0Q29tcG9uZW50OwotICAgICAgICAgICAgICAgICAgICAgICAgZkxhc3RDb21wb25lbnQgPSBmWEluY2x1ZGVIYW5kbGVyOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIFhNTERvY3VtZW50SGFuZGxlciBuZXh0ID0gcHJldi5nZXREb2N1bWVudEhhbmRsZXIoKTsKLSAgICAgICAgICAgICAgICBwcmV2LnNldERvY3VtZW50SGFuZGxlcihmWEluY2x1ZGVIYW5kbGVyKTsKLSAgICAgICAgICAgICAgICBmWEluY2x1ZGVIYW5kbGVyLnNldERvY3VtZW50U291cmNlKHByZXYpOwotICAgICAgICAgICAgICAgIGlmIChuZXh0ICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZYSW5jbHVkZUhhbmRsZXIuc2V0RG9jdW1lbnRIYW5kbGVyKG5leHQpOwotICAgICAgICAgICAgICAgICAgICAgICAgbmV4dC5zZXREb2N1bWVudFNvdXJjZShmWEluY2x1ZGVIYW5kbGVyKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgfSAvLyBjb25maWd1cmVYTUwxMVBpcGVsaW5lKCkKLQotICAgIHB1YmxpYyB2b2lkIHNldFByb3BlcnR5KFN0cmluZyBwcm9wZXJ0eUlkLCBPYmplY3QgdmFsdWUpCi0gICAgICAgIHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIHsKLQotICAgICAgICBpZiAocHJvcGVydHlJZC5lcXVhbHMoWElOQ0xVREVfSEFORExFUikpIHsKLSAgICAgICAgfQotCi0gICAgICAgIHN1cGVyLnNldFByb3BlcnR5KHByb3BlcnR5SWQsIHZhbHVlKTsKLSAgICB9IC8vIHNldFByb3BlcnR5KFN0cmluZyxPYmplY3QpCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9wYXJzZXJzL1hNTDExQ29uZmlndXJhYmxlLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9wYXJzZXJzL1hNTDExQ29uZmlndXJhYmxlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDdiNTM4N2EuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvcGFyc2Vycy9YTUwxMUNvbmZpZ3VyYWJsZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzAgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5wYXJzZXJzOwotCi0vKioKLSAqIDxwPkFuIDxjb2RlPlhNTFBhcnNlckNvbmZpZ3VyYXRpb248L2NvZGU+IGltcGxlbWVudHMgdGhpcyBpbnRlcmZhY2UKLSAqIGluIG9yZGVyIHRvIGluZGljYXRlIHRoYXQgaXQgcHJvdmlkZXMgc3VwcG9ydCBmb3IgWE1MIDEuMS48L3A+Ci0gKgotICogQGF1dGhvciBNaWNoYWVsIEdsYXZhc3NldmljaCwgSUJNCi0gKgotICovCi1wdWJsaWMgaW50ZXJmYWNlIFhNTDExQ29uZmlndXJhYmxlIHt9CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9wYXJzZXJzL1hNTDExQ29uZmlndXJhdGlvbi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvcGFyc2Vycy9YTUwxMUNvbmZpZ3VyYXRpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYWM4NGUxZS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9wYXJzZXJzL1hNTDExQ29uZmlndXJhdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTU2MiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwucGFyc2VyczsKLQotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci1pbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKLWltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwotaW1wb3J0IGphdmF4LnhtbC5YTUxDb25zdGFudHM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5YTUwxMURURFNjYW5uZXJJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5YTUwxMURvY3VtZW50U2Nhbm5lckltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLlhNTDExTlNEb2N1bWVudFNjYW5uZXJJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5YTUxEVERTY2FubmVySW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuWE1MRG9jdW1lbnRTY2FubmVySW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuWE1MRW50aXR5SGFuZGxlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuWE1MRW50aXR5TWFuYWdlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuWE1MRXJyb3JSZXBvcnRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuWE1MTlNEb2N1bWVudFNjYW5uZXJJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5YTUxWZXJzaW9uRGV0ZWN0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR0ZC5YTUwxMURURFByb2Nlc3NvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHRkLlhNTDExRFREVmFsaWRhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdGQuWE1MMTFOU0RURFZhbGlkYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHRkLlhNTERURFByb2Nlc3NvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHRkLlhNTERURFZhbGlkYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHRkLlhNTE5TRFREVmFsaWRhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5EVEREVkZhY3Rvcnk7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLm1zZy5YTUxNZXNzYWdlRm9ybWF0dGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC52YWxpZGF0aW9uLlZhbGlkYXRpb25NYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5YTUxTY2hlbWFWYWxpZGF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlhTTWVzc2FnZUZvcm1hdHRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuRmVhdHVyZVN0YXRlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5QYXJzZXJDb25maWd1cmF0aW9uU2V0dGluZ3M7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlByb3BlcnR5U3RhdGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlN5bWJvbFRhYmxlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbHMuWE1MU2VjdXJpdHlQcm9wZXJ0eU1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MRFREQ29udGVudE1vZGVsSGFuZGxlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxEVERIYW5kbGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTERvY3VtZW50SGFuZGxlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxMb2NhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhOSUV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5ncmFtbWFycy5YTUxHcmFtbWFyUG9vbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MQ29tcG9uZW50OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxDb21wb25lbnRNYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxEVERTY2FubmVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxEb2N1bWVudFNjYW5uZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTERvY3VtZW50U291cmNlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxFbnRpdHlSZXNvbHZlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MRXJyb3JIYW5kbGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxJbnB1dFNvdXJjZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MUHVsbFBhcnNlckNvbmZpZ3VyYXRpb247Ci0KLS8qKgotICogVGhpcyBjbGFzcyBpcyB0aGUgY29uZmlndXJhdGlvbiB1c2VkIHRvIHBhcnNlIFhNTCAxLjAgYW5kIFhNTCAxLjEgZG9jdW1lbnRzLgotICoKLSAqIEBhdXRob3IgRWxlbmEgTGl0YW5pLCBJQk0KLSAqIEBhdXRob3IgTmVpbCBHcmFoYW0sIElCTQotICogQGF1dGhvciBNaWNoYWVsIEdsYXZhc3NldmljaCwgSUJNCi0gKgotICogQHZlcnNpb24gJElkOiBYTUwxMUNvbmZpZ3VyYXRpb24uamF2YSx2IDEuOSAyMDEwLTExLTAxIDA0OjQwOjEwIGpvZWh3IEV4cCAkCi0gKi8KLXB1YmxpYyBjbGFzcyBYTUwxMUNvbmZpZ3VyYXRpb24gZXh0ZW5kcyBQYXJzZXJDb25maWd1cmF0aW9uU2V0dGluZ3MKLSAgICBpbXBsZW1lbnRzIFhNTFB1bGxQYXJzZXJDb25maWd1cmF0aW9uLCBYTUwxMUNvbmZpZ3VyYWJsZSB7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0YW50cwotICAgIC8vCi0gICAgcHJvdGVjdGVkIGZpbmFsIHN0YXRpYyBTdHJpbmcgWE1MMTFfREFUQVRZUEVfVkFMSURBVE9SX0ZBQ1RPUlkgPQotICAgICAgICAiY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LmR0ZC5YTUwxMURURERWRmFjdG9yeUltcGwiOwotCi0gICAgLy8gZmVhdHVyZSBpZGVudGlmaWVycwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogd2FybiBvbiBkdXBsaWNhdGUgYXR0cmlidXRlIGRlZmluaXRpb24uICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0FSTl9PTl9EVVBMSUNBVEVfQVRUREVGID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5XQVJOX09OX0RVUExJQ0FURV9BVFRERUZfRkVBVFVSRTsKLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IHdhcm4gb24gZHVwbGljYXRlIGVudGl0eSBkZWZpbml0aW9uLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFdBUk5fT05fRFVQTElDQVRFX0VOVElUWURFRiA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuV0FSTl9PTl9EVVBMSUNBVEVfRU5USVRZREVGX0ZFQVRVUkU7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiB3YXJuIG9uIHVuZGVjbGFyZWQgZWxlbWVudCBkZWZpbml0aW9uLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFdBUk5fT05fVU5ERUNMQVJFRF9FTEVNREVGID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5XQVJOX09OX1VOREVDTEFSRURfRUxFTURFRl9GRUFUVVJFOwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogYWxsb3cgSmF2YSBlbmNvZGluZ3MuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgQUxMT1dfSkFWQV9FTkNPRElOR1MgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLkFMTE9XX0pBVkFfRU5DT0RJTkdTX0ZFQVRVUkU7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiBjb250aW51ZSBhZnRlciBmYXRhbCBlcnJvci4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBDT05USU5VRV9BRlRFUl9GQVRBTF9FUlJPUiA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuQ09OVElOVUVfQUZURVJfRkFUQUxfRVJST1JfRkVBVFVSRTsKLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IGxvYWQgZXh0ZXJuYWwgRFRELiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIExPQURfRVhURVJOQUxfRFREID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5MT0FEX0VYVEVSTkFMX0RURF9GRUFUVVJFOwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogbm90aWZ5IGJ1aWx0LWluIHJlZmVyZWNlcy4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBOT1RJRllfQlVJTFRJTl9SRUZTID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5OT1RJRllfQlVJTFRJTl9SRUZTX0ZFQVRVUkU7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiBub3RpZnkgY2hhcmFjdGVyIHJlZmVyZWNlcy4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBOT1RJRllfQ0hBUl9SRUZTID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5OT1RJRllfQ0hBUl9SRUZTX0ZFQVRVUkU7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiBleHBvc2Ugc2NoZW1hIG5vcm1hbGl6ZWQgdmFsdWUgKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBOT1JNQUxJWkVfREFUQSA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuU0NIRU1BX05PUk1BTElaRURfVkFMVUU7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiBzZW5kIGVsZW1lbnQgZGVmYXVsdCB2YWx1ZSB2aWEgY2hhcmFjdGVycygpICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgU0NIRU1BX0VMRU1FTlRfREVGQVVMVCA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuU0NIRU1BX0VMRU1FTlRfREVGQVVMVDsKLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IGF1Z21lbnQgUFNWSSAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFNDSEVNQV9BVUdNRU5UX1BTVkkgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLlNDSEVNQV9BVUdNRU5UX1BTVkk7Ci0KLSAgICAvKiogZmVhdHVyZSBpZGVudGlmaWVyOiBYTUwgU2NoZW1hIHZhbGlkYXRpb24gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxTQ0hFTUFfVkFMSURBVElPTiA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuU0NIRU1BX1ZBTElEQVRJT05fRkVBVFVSRTsKLQotICAgIC8qKiBmZWF0dXJlIGlkZW50aWZpZXI6IFhNTCBTY2hlbWEgdmFsaWRhdGlvbiAtLSBmdWxsIGNoZWNraW5nICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MU0NIRU1BX0ZVTExfQ0hFQ0tJTkcgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLlNDSEVNQV9GVUxMX0NIRUNLSU5HOwotCi0gICAgLyoqIEZlYXR1cmU6IGdlbmVyYXRlIHN5bnRoZXRpYyBhbm5vdGF0aW9ucyAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIEdFTkVSQVRFX1NZTlRIRVRJQ19BTk5PVEFUSU9OUyA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuR0VORVJBVEVfU1lOVEhFVElDX0FOTk9UQVRJT05TX0ZFQVRVUkU7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiB2YWxpZGF0ZSBhbm5vdGF0aW9ucyAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFZBTElEQVRFX0FOTk9UQVRJT05TID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5WQUxJREFURV9BTk5PVEFUSU9OU19GRUFUVVJFOwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogaG9ub3VyIGFsbCBzY2hlbWFMb2NhdGlvbnMgKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBIT05PVVJfQUxMX1NDSEVNQUxPQ0FUSU9OUyA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuSE9OT1VSX0FMTF9TQ0hFTUFMT0NBVElPTlNfRkVBVFVSRTsKLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IG5hbWVzcGFjZSBncm93dGggKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBOQU1FU1BBQ0VfR1JPV1RIID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5OQU1FU1BBQ0VfR1JPV1RIX0ZFQVRVUkU7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiB0b2xlcmF0ZSBkdXBsaWNhdGVzICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgVE9MRVJBVEVfRFVQTElDQVRFUyA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuVE9MRVJBVEVfRFVQTElDQVRFU19GRUFUVVJFOwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogdXNlIGdyYW1tYXIgcG9vbCBvbmx5ICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgVVNFX0dSQU1NQVJfUE9PTF9PTkxZID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5VU0VfR1JBTU1BUl9QT09MX09OTFlfRkVBVFVSRTsKLQotICAgIC8vIGZlYXR1cmUgaWRlbnRpZmllcnMKLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IHZhbGlkYXRpb24uICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgVkFMSURBVElPTiA9Ci0gICAgICAgIENvbnN0YW50cy5TQVhfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuVkFMSURBVElPTl9GRUFUVVJFOwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogbmFtZXNwYWNlcy4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBOQU1FU1BBQ0VTID0KLSAgICAgICAgQ29uc3RhbnRzLlNBWF9GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5OQU1FU1BBQ0VTX0ZFQVRVUkU7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiBleHRlcm5hbCBnZW5lcmFsIGVudGl0aWVzLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIEVYVEVSTkFMX0dFTkVSQUxfRU5USVRJRVMgPQotICAgICAgICBDb25zdGFudHMuU0FYX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLkVYVEVSTkFMX0dFTkVSQUxfRU5USVRJRVNfRkVBVFVSRTsKLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IGV4dGVybmFsIHBhcmFtZXRlciBlbnRpdGllcy4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBFWFRFUk5BTF9QQVJBTUVURVJfRU5USVRJRVMgPQotICAgICAgICBDb25zdGFudHMuU0FYX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLkVYVEVSTkFMX1BBUkFNRVRFUl9FTlRJVElFU19GRUFUVVJFOwotCi0gICAgLy8gcHJvcGVydHkgaWRlbnRpZmllcnMKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiB4bWwgc3RyaW5nLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFhNTF9TVFJJTkcgPQotICAgICAgICBDb25zdGFudHMuU0FYX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5YTUxfU1RSSU5HX1BST1BFUlRZOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IHN5bWJvbCB0YWJsZS4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBTWU1CT0xfVEFCTEUgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5TWU1CT0xfVEFCTEVfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogZXJyb3IgaGFuZGxlci4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJPUl9IQU5ETEVSID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuRVJST1JfSEFORExFUl9QUk9QRVJUWTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBlbnRpdHkgcmVzb2x2ZXIuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgRU5USVRZX1JFU09MVkVSID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuRU5USVRZX1JFU09MVkVSX1BST1BFUlRZOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IFhNTCBTY2hlbWEgdmFsaWRhdG9yLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFNDSEVNQV9WQUxJREFUT1IgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5TQ0hFTUFfVkFMSURBVE9SX1BST1BFUlRZOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IHNjaGVtYSBsb2NhdGlvbi4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBTQ0hFTUFfTE9DQVRJT04gPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5TQ0hFTUFfTE9DQVRJT047Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogbm8gbmFtZXNwYWNlIHNjaGVtYSBsb2NhdGlvbi4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBTQ0hFTUFfTk9OU19MT0NBVElPTiA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLlNDSEVNQV9OT05TX0xPQ0FUSU9OOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IGVycm9yIHJlcG9ydGVyLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUk9SX1JFUE9SVEVSID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuRVJST1JfUkVQT1JURVJfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogZW50aXR5IG1hbmFnZXIuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgRU5USVRZX01BTkFHRVIgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5FTlRJVFlfTUFOQUdFUl9QUk9QRVJUWTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyIGRvY3VtZW50IHNjYW5uZXI6ICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgRE9DVU1FTlRfU0NBTk5FUiA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLkRPQ1VNRU5UX1NDQU5ORVJfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogRFREIHNjYW5uZXIuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgRFREX1NDQU5ORVIgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5EVERfU0NBTk5FUl9QUk9QRVJUWTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBncmFtbWFyIHBvb2wuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MR1JBTU1BUl9QT09MID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuWE1MR1JBTU1BUl9QT09MX1BST1BFUlRZOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IERURCBsb2FkZXIuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgRFREX1BST0NFU1NPUiA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLkRURF9QUk9DRVNTT1JfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogRFREIHZhbGlkYXRvci4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBEVERfVkFMSURBVE9SID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuRFREX1ZBTElEQVRPUl9QUk9QRVJUWTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBuYW1lc3BhY2UgYmluZGVyLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIE5BTUVTUEFDRV9CSU5ERVIgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5OQU1FU1BBQ0VfQklOREVSX1BST1BFUlRZOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IGRhdGF0eXBlIHZhbGlkYXRvciBmYWN0b3J5LiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIERBVEFUWVBFX1ZBTElEQVRPUl9GQUNUT1JZID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuREFUQVRZUEVfVkFMSURBVE9SX0ZBQ1RPUllfUFJPUEVSVFk7Ci0KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBWQUxJREFUSU9OX01BTkFHRVIgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5WQUxJREFUSU9OX01BTkFHRVJfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogSkFYUCBzY2hlbWEgbGFuZ3VhZ2UgLyBET00gc2NoZW1hLXR5cGUuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgSkFYUF9TQ0hFTUFfTEFOR1VBR0UgPQotICAgICAgICBDb25zdGFudHMuSkFYUF9QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuU0NIRU1BX0xBTkdVQUdFOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IEpBWFAgc2NoZW1hIHNvdXJjZS8gRE9NIHNjaGVtYS1sb2NhdGlvbi4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBKQVhQX1NDSEVNQV9TT1VSQ0UgPQotICAgICAgICBDb25zdGFudHMuSkFYUF9QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuU0NIRU1BX1NPVVJDRTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBsb2NhbGUuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgTE9DQUxFID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuTE9DQUxFX1BST1BFUlRZOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IFNjaGVtYSBEViBGYWN0b3J5ICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgU0NIRU1BX0RWX0ZBQ1RPUlkgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5TQ0hFTUFfRFZfRkFDVE9SWV9QUk9QRVJUWTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBTZWN1cml0eSBwcm9wZXJ0eSBtYW5hZ2VyLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxfU0VDVVJJVFlfUFJPUEVSVFlfTUFOQUdFUiA9Ci0gICAgICAgICAgICBDb25zdGFudHMuWE1MX1NFQ1VSSVRZX1BST1BFUlRZX01BTkFHRVI7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogU2VjdXJpdHkgbWFuYWdlci4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgU0VDVVJJVFlfTUFOQUdFUiA9IENvbnN0YW50cy5TRUNVUklUWV9NQU5BR0VSOwotCi0gICAgLy8gZGVidWdnaW5nCi0KLSAgICAvKiogU2V0IHRvIHRydWUgYW5kIHJlY29tcGlsZSB0byBwcmludCBleGNlcHRpb24gc3RhY2sgdHJhY2UuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBib29sZWFuIFBSSU5UX0VYQ0VQVElPTl9TVEFDS19UUkFDRSA9IGZhbHNlOwotCi0gICAgLy8KLSAgICAvLyBEYXRhCi0gICAgLy8KLQotICAgIHByb3RlY3RlZCBTeW1ib2xUYWJsZSBmU3ltYm9sVGFibGU7Ci0gICAgcHJvdGVjdGVkIFhNTElucHV0U291cmNlIGZJbnB1dFNvdXJjZTsKLSAgICBwcm90ZWN0ZWQgVmFsaWRhdGlvbk1hbmFnZXIgZlZhbGlkYXRpb25NYW5hZ2VyOwotICAgIHByb3RlY3RlZCBYTUxWZXJzaW9uRGV0ZWN0b3IgZlZlcnNpb25EZXRlY3RvcjsKLSAgICBwcm90ZWN0ZWQgWE1MTG9jYXRvciBmTG9jYXRvcjsKLSAgICBwcm90ZWN0ZWQgTG9jYWxlIGZMb2NhbGU7Ci0KLSAgICAvKiogWE1MIDEuMCBDb21wb25lbnRzLiAqLwotICAgIHByb3RlY3RlZCBBcnJheUxpc3Q8WE1MQ29tcG9uZW50PiBmQ29tcG9uZW50czsKLQotICAgIC8qKiBYTUwgMS4xLiBDb21wb25lbnRzLiAqLwotICAgIHByb3RlY3RlZCBBcnJheUxpc3Q8WE1MQ29tcG9uZW50PiBmWE1MMTFDb21wb25lbnRzID0gbnVsbDsKLQotICAgIC8qKiBDb21tb24gY29tcG9uZW50czogWE1MRW50aXR5TWFuYWdlciwgWE1MRXJyb3JSZXBvcnRlciwgWE1MU2NoZW1hVmFsaWRhdG9yICovCi0gICAgcHJvdGVjdGVkIEFycmF5TGlzdDxYTUxDb21wb25lbnQ+IGZDb21tb25Db21wb25lbnRzID0gbnVsbDsKLQotICAgIC8qKiBUaGUgZG9jdW1lbnQgaGFuZGxlci4gKi8KLSAgICBwcm90ZWN0ZWQgWE1MRG9jdW1lbnRIYW5kbGVyIGZEb2N1bWVudEhhbmRsZXI7Ci0KLSAgICAvKiogVGhlIERURCBoYW5kbGVyLiAqLwotICAgIHByb3RlY3RlZCBYTUxEVERIYW5kbGVyIGZEVERIYW5kbGVyOwotCi0gICAgLyoqIFRoZSBEVEQgY29udGVudCBtb2RlbCBoYW5kbGVyLiAqLwotICAgIHByb3RlY3RlZCBYTUxEVERDb250ZW50TW9kZWxIYW5kbGVyIGZEVERDb250ZW50TW9kZWxIYW5kbGVyOwotCi0gICAgLyoqIExhc3QgY29tcG9uZW50IGluIHRoZSBkb2N1bWVudCBwaXBlbGluZSAqLwotICAgIHByb3RlY3RlZCBYTUxEb2N1bWVudFNvdXJjZSBmTGFzdENvbXBvbmVudDsKLQotICAgIC8qKgotICAgICAqIFRydWUgaWYgYSBwYXJzZSBpcyBpbiBwcm9ncmVzcy4gVGhpcyBzdGF0ZSBpcyBuZWVkZWQgYmVjYXVzZQotICAgICAqIHNvbWUgZmVhdHVyZXMvcHJvcGVydGllcyBjYW5ub3QgYmUgc2V0IHdoaWxlIHBhcnNpbmcgKGUuZy4KLSAgICAgKiB2YWxpZGF0aW9uIGFuZCBuYW1lc3BhY2VzKS4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBmUGFyc2VJblByb2dyZXNzID0gZmFsc2U7Ci0KLSAgICAvKiogZkNvbmZpZ1VwZGF0ZWQgaXMgc2V0IHRvIHRydWUgaWYgdGhlcmUgaGFzIGJlZW4gYW55IGNoYW5nZSB0byB0aGUgY29uZmlndXJhdGlvbiBzZXR0aW5ncywKLSAgICAgKiBpLmUgYSBmZWF0dXJlIG9yIGEgcHJvcGVydHkgd2FzIGNoYW5nZWQuCi0gICAgICovCi0gICAgICAgIHByb3RlY3RlZCBib29sZWFuIGZDb25maWdVcGRhdGVkID0gZmFsc2U7Ci0KLSAgICAvLwotICAgIC8vIFhNTCAxLjAgY29tcG9uZW50cwotICAgIC8vCi0KLSAgICAvKiogVGhlIFhNTCAxLjAgRGF0YXR5cGUgdmFsaWRhdG9yIGZhY3RvcnkuICovCi0gICAgcHJvdGVjdGVkIERURERWRmFjdG9yeSBmRGF0YXR5cGVWYWxpZGF0b3JGYWN0b3J5OwotCi0gICAgLyoqIFRoZSBYTUwgMS4wIERvY3VtZW50IHNjYW5uZXIgdGhhdCBkb2VzIG5hbWVzcGFjZSBiaW5kaW5nLiAqLwotICAgIHByb3RlY3RlZCBYTUxOU0RvY3VtZW50U2Nhbm5lckltcGwgZk5hbWVzcGFjZVNjYW5uZXI7Ci0gICAgLyoqIFRoZSBYTUwgMS4wIE5vbi1uYW1lc3BhY2UgaW1wbGVtZW50YXRpb24gb2Ygc2Nhbm5lciAqLwotICAgIHByb3RlY3RlZCBYTUxEb2N1bWVudFNjYW5uZXJJbXBsIGZOb25OU1NjYW5uZXI7Ci0gICAgLyoqIFRoZSBYTUwgMS4wIERURCBWYWxpZGF0b3I6IGJpbmRzIG5hbWVzcGFjZXMgKi8KLSAgICBwcm90ZWN0ZWQgWE1MRFREVmFsaWRhdG9yIGZEVERWYWxpZGF0b3I7Ci0gICAgLyoqIFRoZSBYTUwgMS4wIERURCBWYWxpZGF0b3IgdGhhdCBkb2VzIG5vdCBiaW5kIG5hbWVzcGFjZXMgKi8KLSAgICBwcm90ZWN0ZWQgWE1MRFREVmFsaWRhdG9yIGZOb25OU0RURFZhbGlkYXRvcjsKLSAgICAvKiogVGhlIFhNTCAxLjAgRFREIHNjYW5uZXIuICovCi0gICAgcHJvdGVjdGVkIFhNTERURFNjYW5uZXIgZkRURFNjYW5uZXI7Ci0gICAgLyoqIFRoZSBYTUwgMS4wIERURCBQcm9jZXNzb3IgLiAqLwotICAgIHByb3RlY3RlZCBYTUxEVERQcm9jZXNzb3IgZkRURFByb2Nlc3NvcjsKLQotICAgIC8vCi0gICAgLy8gWE1MIDEuMSBjb21wb25lbnRzCi0gICAgLy8KLQotICAgIC8qKiBUaGUgWE1MIDEuMSBkYXRhdHlwZSBmYWN0b3J5LiAqKi8KLSAgICBwcm90ZWN0ZWQgRFRERFZGYWN0b3J5IGZYTUwxMURhdGF0eXBlRmFjdG9yeSA9IG51bGw7Ci0KLSAgICAvKiogVGhlIFhNTCAxLjEgZG9jdW1lbnQgc2Nhbm5lciB0aGF0IGRvZXMgbmFtZXNwYWNlIGJpbmRpbmcuICoqLwotICAgIHByb3RlY3RlZCBYTUwxMU5TRG9jdW1lbnRTY2FubmVySW1wbCBmWE1MMTFOU0RvY1NjYW5uZXIgPSBudWxsOwotCi0gICAgLyoqIFRoZSBYTUwgMS4xIGRvY3VtZW50IHNjYW5uZXIgdGhhdCBkb2VzIG5vdCBkbyBuYW1lc3BhY2UgYmluZGluZy4gKiovCi0gICAgcHJvdGVjdGVkIFhNTDExRG9jdW1lbnRTY2FubmVySW1wbCBmWE1MMTFEb2NTY2FubmVyID0gbnVsbDsKLQotICAgIC8qKiBUaGUgWE1MIDEuMSBEVEQgdmFsaWRhdG9yIHRoYXQgZG9lcyBuYW1lc3BhY2UgYmluZGluZy4gKiovCi0gICAgcHJvdGVjdGVkIFhNTDExTlNEVERWYWxpZGF0b3IgZlhNTDExTlNEVERWYWxpZGF0b3IgPSBudWxsOwotCi0gICAgLyoqIFRoZSBYTUwgMS4xIERURCB2YWxpZGF0b3IgdGhhdCBkb2VzIG5vdCBkbyBuYW1lc3BhY2UgYmluZGluZy4gKiovCi0gICAgcHJvdGVjdGVkIFhNTDExRFREVmFsaWRhdG9yIGZYTUwxMURURFZhbGlkYXRvciA9IG51bGw7Ci0KLSAgICAvKiogVGhlIFhNTCAxLjEgRFREIHNjYW5uZXIuICoqLwotICAgIHByb3RlY3RlZCBYTUwxMURURFNjYW5uZXJJbXBsIGZYTUwxMURURFNjYW5uZXIgPSBudWxsOwotICAgIC8qKiBUaGUgWE1MIDEuMSBEVEQgcHJvY2Vzc29yLiAqKi8KLSAgICBwcm90ZWN0ZWQgWE1MMTFEVERQcm9jZXNzb3IgZlhNTDExRFREUHJvY2Vzc29yID0gbnVsbDsKLQotICAgIC8vCi0gICAgLy8gQ29tbW9uIGNvbXBvbmVudHMKLSAgICAvLwotCi0gICAgLyoqIEdyYW1tYXIgcG9vbC4gKi8KLSAgICBwcm90ZWN0ZWQgWE1MR3JhbW1hclBvb2wgZkdyYW1tYXJQb29sOwotCi0gICAgLyoqIEVycm9yIHJlcG9ydGVyLiAqLwotICAgIHByb3RlY3RlZCBYTUxFcnJvclJlcG9ydGVyIGZFcnJvclJlcG9ydGVyOwotCi0gICAgLyoqIEVudGl0eSBtYW5hZ2VyLiAqLwotICAgIHByb3RlY3RlZCBYTUxFbnRpdHlNYW5hZ2VyIGZFbnRpdHlNYW5hZ2VyOwotCi0gICAgLyoqIFhNTCBTY2hlbWEgVmFsaWRhdG9yLiAqLwotICAgIHByb3RlY3RlZCBYTUxTY2hlbWFWYWxpZGF0b3IgZlNjaGVtYVZhbGlkYXRvcjsKLQotICAgIC8qKiBDdXJyZW50IHNjYW5uZXIgKi8KLSAgICBwcm90ZWN0ZWQgWE1MRG9jdW1lbnRTY2FubmVyIGZDdXJyZW50U2Nhbm5lcjsKLSAgICAvKiogQ3VycmVudCBEYXRhdHlwZSB2YWxpZGF0b3IgZmFjdG9yeS4gKi8KLSAgICBwcm90ZWN0ZWQgRFRERFZGYWN0b3J5IGZDdXJyZW50RFZGYWN0b3J5OwotICAgIC8qKiBDdXJyZW50IERURCBzY2FubmVyLiAqLwotICAgIHByb3RlY3RlZCBYTUxEVERTY2FubmVyIGZDdXJyZW50RFREU2Nhbm5lcjsKLQotICAgIC8qKiBGbGFnIGluZGljaWF0aW5nIHdoZXRoZXIgWE1MMTEgY29tcG9uZW50cyBoYXZlIGJlZW4gaW5pdGlhbGl6ZWQuICovCi0gICAgcHJpdmF0ZSBib29sZWFuIGYxMUluaXRpYWxpemVkID0gZmFsc2U7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0cnVjdG9ycwotICAgIC8vCi0KLSAgICAvKiogRGVmYXVsdCBjb25zdHJ1Y3Rvci4gKi8KLSAgICBwdWJsaWMgWE1MMTFDb25maWd1cmF0aW9uKCkgewotICAgICAgICB0aGlzKG51bGwsIG51bGwsIG51bGwpOwotICAgIH0gLy8gPGluaXQ+KCkKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHMgYSBwYXJzZXIgY29uZmlndXJhdGlvbiB1c2luZyB0aGUgc3BlY2lmaWVkIHN5bWJvbCB0YWJsZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzeW1ib2xUYWJsZSBUaGUgc3ltYm9sIHRhYmxlIHRvIHVzZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgWE1MMTFDb25maWd1cmF0aW9uKFN5bWJvbFRhYmxlIHN5bWJvbFRhYmxlKSB7Ci0gICAgICAgIHRoaXMoc3ltYm9sVGFibGUsIG51bGwsIG51bGwpOwotICAgIH0gLy8gPGluaXQ+KFN5bWJvbFRhYmxlKQotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0cyBhIHBhcnNlciBjb25maWd1cmF0aW9uIHVzaW5nIHRoZSBzcGVjaWZpZWQgc3ltYm9sIHRhYmxlIGFuZAotICAgICAqIGdyYW1tYXIgcG9vbC4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPlJFVklTSVQ6PC9zdHJvbmc+Ci0gICAgICogR3JhbW1hciBwb29sIHdpbGwgYmUgdXBkYXRlZCB3aGVuIHRoZSBuZXcgdmFsaWRhdGlvbiBlbmdpbmUgaXMKLSAgICAgKiBpbXBsZW1lbnRlZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzeW1ib2xUYWJsZSBUaGUgc3ltYm9sIHRhYmxlIHRvIHVzZS4KLSAgICAgKiBAcGFyYW0gZ3JhbW1hclBvb2wgVGhlIGdyYW1tYXIgcG9vbCB0byB1c2UuCi0gICAgICovCi0gICAgcHVibGljIFhNTDExQ29uZmlndXJhdGlvbihTeW1ib2xUYWJsZSBzeW1ib2xUYWJsZSwgWE1MR3JhbW1hclBvb2wgZ3JhbW1hclBvb2wpIHsKLSAgICAgICAgdGhpcyhzeW1ib2xUYWJsZSwgZ3JhbW1hclBvb2wsIG51bGwpOwotICAgIH0gLy8gPGluaXQ+KFN5bWJvbFRhYmxlLFhNTEdyYW1tYXJQb29sKQotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0cyBhIHBhcnNlciBjb25maWd1cmF0aW9uIHVzaW5nIHRoZSBzcGVjaWZpZWQgc3ltYm9sIHRhYmxlLAotICAgICAqIGdyYW1tYXIgcG9vbCwgYW5kIHBhcmVudCBzZXR0aW5ncy4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPlJFVklTSVQ6PC9zdHJvbmc+Ci0gICAgICogR3JhbW1hciBwb29sIHdpbGwgYmUgdXBkYXRlZCB3aGVuIHRoZSBuZXcgdmFsaWRhdGlvbiBlbmdpbmUgaXMKLSAgICAgKiBpbXBsZW1lbnRlZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzeW1ib2xUYWJsZSAgICBUaGUgc3ltYm9sIHRhYmxlIHRvIHVzZS4KLSAgICAgKiBAcGFyYW0gZ3JhbW1hclBvb2wgICAgVGhlIGdyYW1tYXIgcG9vbCB0byB1c2UuCi0gICAgICogQHBhcmFtIHBhcmVudFNldHRpbmdzIFRoZSBwYXJlbnQgc2V0dGluZ3MuCi0gICAgICovCi0gICAgcHVibGljIFhNTDExQ29uZmlndXJhdGlvbigKLSAgICAgICAgU3ltYm9sVGFibGUgc3ltYm9sVGFibGUsCi0gICAgICAgIFhNTEdyYW1tYXJQb29sIGdyYW1tYXJQb29sLAotICAgICAgICBYTUxDb21wb25lbnRNYW5hZ2VyIHBhcmVudFNldHRpbmdzKSB7Ci0KLSAgICAgICAgc3VwZXIocGFyZW50U2V0dGluZ3MpOwotCi0gICAgICAgIC8vIGNyZWF0ZSBhIHZlY3RvciB0byBob2xkIGFsbCB0aGUgY29tcG9uZW50cyBpbiB1c2UKLSAgICAgICAgLy8gWE1MIDEuMCBzcGVjaWFsaXplZCBjb21wb25lbnRzCi0gICAgICAgIGZDb21wb25lbnRzID0gbmV3IEFycmF5TGlzdDw+KCk7Ci0gICAgICAgIC8vIFhNTCAxLjEgc3BlY2lhbGl6ZWQgY29tcG9uZW50cwotICAgICAgICBmWE1MMTFDb21wb25lbnRzID0gbmV3IEFycmF5TGlzdDw+KCk7Ci0gICAgICAgIC8vIENvbW1vbiBjb21wb25lbnRzIGZvciBYTUwgMS4xLiBhbmQgWE1MIDEuMAotICAgICAgICBmQ29tbW9uQ29tcG9uZW50cyA9IG5ldyBBcnJheUxpc3Q8PigpOwotCi0gICAgICAgIC8vIGNyZWF0ZSB0YWJsZSBmb3IgZmVhdHVyZXMgYW5kIHByb3BlcnRpZXMKLSAgICAgICAgZkZlYXR1cmVzID0gbmV3IEhhc2hNYXA8PigpOwotICAgICAgICBmUHJvcGVydGllcyA9IG5ldyBIYXNoTWFwPD4oKTsKLQotICAgICAgICAvLyBhZGQgZGVmYXVsdCByZWNvZ25pemVkIGZlYXR1cmVzCi0gICAgICAgIGZpbmFsIFN0cmluZ1tdIHJlY29nbml6ZWRGZWF0dXJlcyA9Ci0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgQ09OVElOVUVfQUZURVJfRkFUQUxfRVJST1IsIExPQURfRVhURVJOQUxfRFRELCAvLyBmcm9tIFhNTERURFNjYW5uZXJJbXBsCi0gICAgICAgICAgICAgICAgVkFMSURBVElPTiwKLSAgICAgICAgICAgICAgICBOQU1FU1BBQ0VTLAotICAgICAgICAgICAgICAgIE5PUk1BTElaRV9EQVRBLCBTQ0hFTUFfRUxFTUVOVF9ERUZBVUxULCBTQ0hFTUFfQVVHTUVOVF9QU1ZJLAotICAgICAgICAgICAgICAgIEdFTkVSQVRFX1NZTlRIRVRJQ19BTk5PVEFUSU9OUywgVkFMSURBVEVfQU5OT1RBVElPTlMsCi0gICAgICAgICAgICAgICAgSE9OT1VSX0FMTF9TQ0hFTUFMT0NBVElPTlMsIE5BTUVTUEFDRV9HUk9XVEgsCi0gICAgICAgICAgICAgICAgVE9MRVJBVEVfRFVQTElDQVRFUywKLSAgICAgICAgICAgICAgICBVU0VfR1JBTU1BUl9QT09MX09OTFksCi0gICAgICAgICAgICAgICAgLy8gTk9URTogVGhlc2Ugc2hvdWxkbid0IHJlYWxseSBiZSBoZXJlIGJ1dCBzaW5jZSB0aGUgWE1MIFNjaGVtYQotICAgICAgICAgICAgICAgIC8vICAgICAgIHZhbGlkYXRvciBpcyBjb25zdHJ1Y3RlZCBkeW5hbWljYWxseSwgaXRzIHJlY29nbml6ZWQKLSAgICAgICAgICAgICAgICAvLyAgICAgICBmZWF0dXJlcyBtaWdodCBub3QgaGF2ZSBiZWVuIHNldCBhbmQgaXQgd291bGQgY2F1c2UgYQotICAgICAgICAgICAgICAgIC8vICAgICAgIG5vdC1yZWNvZ25pemVkIGV4Y2VwdGlvbiB0byBiZSB0aHJvd24uIC1BYwotICAgICAgICAgICAgICAgIFhNTFNDSEVNQV9WQUxJREFUSU9OLCBYTUxTQ0hFTUFfRlVMTF9DSEVDS0lORywKLSAgICAgICAgICAgICAgICBFWFRFUk5BTF9HRU5FUkFMX0VOVElUSUVTLAotICAgICAgICAgICAgICAgIEVYVEVSTkFMX1BBUkFNRVRFUl9FTlRJVElFUywKLSAgICAgICAgICAgICAgICBQQVJTRVJfU0VUVElOR1MsCi0gICAgICAgICAgICAgICAgWE1MQ29uc3RhbnRzLkZFQVRVUkVfU0VDVVJFX1BST0NFU1NJTkcKLSAgICAgICAgICAgICAgICAgICAgICAgIH07Ci0gICAgICAgIGFkZFJlY29nbml6ZWRGZWF0dXJlcyhyZWNvZ25pemVkRmVhdHVyZXMpOwotICAgICAgICAvLyBzZXQgc3RhdGUgZm9yIGRlZmF1bHQgZmVhdHVyZXMKLSAgICAgICAgZkZlYXR1cmVzLnB1dChWQUxJREFUSU9OLCBCb29sZWFuLkZBTFNFKTsKLSAgICAgICAgZkZlYXR1cmVzLnB1dChOQU1FU1BBQ0VTLCBCb29sZWFuLlRSVUUpOwotICAgICAgICBmRmVhdHVyZXMucHV0KEVYVEVSTkFMX0dFTkVSQUxfRU5USVRJRVMsIEJvb2xlYW4uVFJVRSk7Ci0gICAgICAgIGZGZWF0dXJlcy5wdXQoRVhURVJOQUxfUEFSQU1FVEVSX0VOVElUSUVTLCBCb29sZWFuLlRSVUUpOwotICAgICAgICBmRmVhdHVyZXMucHV0KENPTlRJTlVFX0FGVEVSX0ZBVEFMX0VSUk9SLCBCb29sZWFuLkZBTFNFKTsKLSAgICAgICAgZkZlYXR1cmVzLnB1dChMT0FEX0VYVEVSTkFMX0RURCwgQm9vbGVhbi5UUlVFKTsKLSAgICAgICAgZkZlYXR1cmVzLnB1dChTQ0hFTUFfRUxFTUVOVF9ERUZBVUxULCBCb29sZWFuLlRSVUUpOwotICAgICAgICBmRmVhdHVyZXMucHV0KE5PUk1BTElaRV9EQVRBLCBCb29sZWFuLlRSVUUpOwotICAgICAgICBmRmVhdHVyZXMucHV0KFNDSEVNQV9BVUdNRU5UX1BTVkksIEJvb2xlYW4uVFJVRSk7Ci0gICAgICAgIGZGZWF0dXJlcy5wdXQoR0VORVJBVEVfU1lOVEhFVElDX0FOTk9UQVRJT05TLCBCb29sZWFuLkZBTFNFKTsKLSAgICAgICAgZkZlYXR1cmVzLnB1dChWQUxJREFURV9BTk5PVEFUSU9OUywgQm9vbGVhbi5GQUxTRSk7Ci0gICAgICAgIGZGZWF0dXJlcy5wdXQoSE9OT1VSX0FMTF9TQ0hFTUFMT0NBVElPTlMsIEJvb2xlYW4uRkFMU0UpOwotICAgICAgICBmRmVhdHVyZXMucHV0KE5BTUVTUEFDRV9HUk9XVEgsIEJvb2xlYW4uRkFMU0UpOwotICAgICAgICBmRmVhdHVyZXMucHV0KFRPTEVSQVRFX0RVUExJQ0FURVMsIEJvb2xlYW4uRkFMU0UpOwotICAgICAgICBmRmVhdHVyZXMucHV0KFVTRV9HUkFNTUFSX1BPT0xfT05MWSwgQm9vbGVhbi5GQUxTRSk7Ci0gICAgICAgIGZGZWF0dXJlcy5wdXQoUEFSU0VSX1NFVFRJTkdTLCBCb29sZWFuLlRSVUUpOwotICAgICAgICBmRmVhdHVyZXMucHV0KFhNTENvbnN0YW50cy5GRUFUVVJFX1NFQ1VSRV9QUk9DRVNTSU5HLCBCb29sZWFuLlRSVUUpOwotCi0gICAgICAgIC8vIGFkZCBkZWZhdWx0IHJlY29nbml6ZWQgcHJvcGVydGllcwotICAgICAgICBmaW5hbCBTdHJpbmdbXSByZWNvZ25pemVkUHJvcGVydGllcyA9Ci0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNZTUJPTF9UQUJMRSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRVJST1JfSEFORExFUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRU5USVRZX1JFU09MVkVSLAotICAgICAgICAgICAgICAgIEVSUk9SX1JFUE9SVEVSLAotICAgICAgICAgICAgICAgIEVOVElUWV9NQU5BR0VSLAotICAgICAgICAgICAgICAgIERPQ1VNRU5UX1NDQU5ORVIsCi0gICAgICAgICAgICAgICAgRFREX1NDQU5ORVIsCi0gICAgICAgICAgICAgICAgRFREX1BST0NFU1NPUiwKLSAgICAgICAgICAgICAgICBEVERfVkFMSURBVE9SLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEQVRBVFlQRV9WQUxJREFUT1JfRkFDVE9SWSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVkFMSURBVElPTl9NQU5BR0VSLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTQ0hFTUFfVkFMSURBVE9SLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxfU1RSSU5HLAotICAgICAgICAgICAgICAgIFhNTEdSQU1NQVJfUE9PTCwKLSAgICAgICAgICAgICAgICBKQVhQX1NDSEVNQV9TT1VSQ0UsCi0gICAgICAgICAgICAgICAgSkFYUF9TQ0hFTUFfTEFOR1VBR0UsCi0gICAgICAgICAgICAgICAgLy8gTk9URTogVGhlc2Ugc2hvdWxkbid0IHJlYWxseSBiZSBoZXJlIGJ1dCBzaW5jZSB0aGUgWE1MIFNjaGVtYQotICAgICAgICAgICAgICAgIC8vICAgICAgIHZhbGlkYXRvciBpcyBjb25zdHJ1Y3RlZCBkeW5hbWljYWxseSwgaXRzIHJlY29nbml6ZWQKLSAgICAgICAgICAgICAgICAvLyAgICAgICBwcm9wZXJ0aWVzIG1pZ2h0IG5vdCBoYXZlIGJlZW4gc2V0IGFuZCBpdCB3b3VsZCBjYXVzZSBhCi0gICAgICAgICAgICAgICAgLy8gICAgICAgbm90LXJlY29nbml6ZWQgZXhjZXB0aW9uIHRvIGJlIHRocm93bi4gLUFjCi0gICAgICAgICAgICAgICAgU0NIRU1BX0xPQ0FUSU9OLAotICAgICAgICAgICAgICAgIFNDSEVNQV9OT05TX0xPQ0FUSU9OLAotICAgICAgICAgICAgICAgIExPQ0FMRSwKLSAgICAgICAgICAgICAgICBTQ0hFTUFfRFZfRkFDVE9SWSwKLSAgICAgICAgICAgICAgICBTRUNVUklUWV9NQU5BR0VSLAotICAgICAgICAgICAgICAgIFhNTF9TRUNVUklUWV9QUk9QRVJUWV9NQU5BR0VSCi0gICAgICAgIH07Ci0gICAgICAgIGFkZFJlY29nbml6ZWRQcm9wZXJ0aWVzKHJlY29nbml6ZWRQcm9wZXJ0aWVzKTsKLQotICAgICAgICAgICAgICAgIGlmIChzeW1ib2xUYWJsZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzeW1ib2xUYWJsZSA9IG5ldyBTeW1ib2xUYWJsZSgpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBmU3ltYm9sVGFibGUgPSBzeW1ib2xUYWJsZTsKLSAgICAgICAgICAgICAgICBmUHJvcGVydGllcy5wdXQoU1lNQk9MX1RBQkxFLCBmU3ltYm9sVGFibGUpOwotCi0gICAgICAgIGZHcmFtbWFyUG9vbCA9IGdyYW1tYXJQb29sOwotICAgICAgICBpZiAoZkdyYW1tYXJQb29sICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZQcm9wZXJ0aWVzLnB1dChYTUxHUkFNTUFSX1BPT0wsIGZHcmFtbWFyUG9vbCk7Ci0gICAgICAgIH0KLQotICAgICAgICBmRW50aXR5TWFuYWdlciA9IG5ldyBYTUxFbnRpdHlNYW5hZ2VyKCk7Ci0gICAgICAgIGZQcm9wZXJ0aWVzLnB1dChFTlRJVFlfTUFOQUdFUiwgZkVudGl0eU1hbmFnZXIpOwotICAgICAgICBhZGRDb21tb25Db21wb25lbnQoZkVudGl0eU1hbmFnZXIpOwotCi0gICAgICAgIGZFcnJvclJlcG9ydGVyID0gbmV3IFhNTEVycm9yUmVwb3J0ZXIoKTsKLSAgICAgICAgZkVycm9yUmVwb3J0ZXIuc2V0RG9jdW1lbnRMb2NhdG9yKGZFbnRpdHlNYW5hZ2VyLmdldEVudGl0eVNjYW5uZXIoKSk7Ci0gICAgICAgIGZQcm9wZXJ0aWVzLnB1dChFUlJPUl9SRVBPUlRFUiwgZkVycm9yUmVwb3J0ZXIpOwotICAgICAgICBhZGRDb21tb25Db21wb25lbnQoZkVycm9yUmVwb3J0ZXIpOwotCi0gICAgICAgIGZOYW1lc3BhY2VTY2FubmVyID0gbmV3IFhNTE5TRG9jdW1lbnRTY2FubmVySW1wbCgpOwotICAgICAgICBmUHJvcGVydGllcy5wdXQoRE9DVU1FTlRfU0NBTk5FUiwgZk5hbWVzcGFjZVNjYW5uZXIpOwotICAgICAgICBhZGRDb21wb25lbnQoKFhNTENvbXBvbmVudCkgZk5hbWVzcGFjZVNjYW5uZXIpOwotCi0gICAgICAgIGZEVERTY2FubmVyID0gbmV3IFhNTERURFNjYW5uZXJJbXBsKCk7Ci0gICAgICAgIGZQcm9wZXJ0aWVzLnB1dChEVERfU0NBTk5FUiwgZkRURFNjYW5uZXIpOwotICAgICAgICBhZGRDb21wb25lbnQoKFhNTENvbXBvbmVudCkgZkRURFNjYW5uZXIpOwotCi0gICAgICAgIGZEVERQcm9jZXNzb3IgPSBuZXcgWE1MRFREUHJvY2Vzc29yKCk7Ci0gICAgICAgIGZQcm9wZXJ0aWVzLnB1dChEVERfUFJPQ0VTU09SLCBmRFREUHJvY2Vzc29yKTsKLSAgICAgICAgYWRkQ29tcG9uZW50KChYTUxDb21wb25lbnQpIGZEVERQcm9jZXNzb3IpOwotCi0gICAgICAgIGZEVERWYWxpZGF0b3IgPSBuZXcgWE1MTlNEVERWYWxpZGF0b3IoKTsKLSAgICAgICAgZlByb3BlcnRpZXMucHV0KERURF9WQUxJREFUT1IsIGZEVERWYWxpZGF0b3IpOwotICAgICAgICBhZGRDb21wb25lbnQoZkRURFZhbGlkYXRvcik7Ci0KLSAgICAgICAgZkRhdGF0eXBlVmFsaWRhdG9yRmFjdG9yeSA9IERURERWRmFjdG9yeS5nZXRJbnN0YW5jZSgpOwotICAgICAgICBmUHJvcGVydGllcy5wdXQoREFUQVRZUEVfVkFMSURBVE9SX0ZBQ1RPUlksIGZEYXRhdHlwZVZhbGlkYXRvckZhY3RvcnkpOwotCi0gICAgICAgIGZWYWxpZGF0aW9uTWFuYWdlciA9IG5ldyBWYWxpZGF0aW9uTWFuYWdlcigpOwotICAgICAgICBmUHJvcGVydGllcy5wdXQoVkFMSURBVElPTl9NQU5BR0VSLCBmVmFsaWRhdGlvbk1hbmFnZXIpOwotCi0gICAgICAgIGZWZXJzaW9uRGV0ZWN0b3IgPSBuZXcgWE1MVmVyc2lvbkRldGVjdG9yKCk7Ci0KLSAgICAgICAgLy8gYWRkIG1lc3NhZ2UgZm9ybWF0dGVycwotICAgICAgICBpZiAoZkVycm9yUmVwb3J0ZXIuZ2V0TWVzc2FnZUZvcm1hdHRlcihYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4pID09IG51bGwpIHsKLSAgICAgICAgICAgIFhNTE1lc3NhZ2VGb3JtYXR0ZXIgeG1mdCA9IG5ldyBYTUxNZXNzYWdlRm9ybWF0dGVyKCk7Ci0gICAgICAgICAgICBmRXJyb3JSZXBvcnRlci5wdXRNZXNzYWdlRm9ybWF0dGVyKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwgeG1mdCk7Ci0gICAgICAgICAgICBmRXJyb3JSZXBvcnRlci5wdXRNZXNzYWdlRm9ybWF0dGVyKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MTlNfRE9NQUlOLCB4bWZ0KTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIHNldCBsb2NhbGUKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIHNldExvY2FsZShMb2NhbGUuZ2V0RGVmYXVsdCgpKTsKLSAgICAgICAgfSBjYXRjaCAoWE5JRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIC8vIGRvIG5vdGhpbmcKLSAgICAgICAgICAgIC8vIFJFVklTSVQ6IFdoYXQgaXMgdGhlIHJpZ2h0IHRoaW5nIHRvIGRvPyAtQWMKLSAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgZkNvbmZpZ1VwZGF0ZWQgPSBmYWxzZTsKLQotICAgIH0gLy8gPGluaXQ+KFN5bWJvbFRhYmxlLFhNTEdyYW1tYXJQb29sKQotCi0gICAgLy8KLSAgICAvLyBQdWJsaWMgbWV0aG9kcwotICAgIC8vCi0gICAgLyoqCi0gICAgICogU2V0cyB0aGUgaW5wdXQgc291cmNlIGZvciB0aGUgZG9jdW1lbnQgdG8gcGFyc2UuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaW5wdXRTb3VyY2UgVGhlIGRvY3VtZW50J3MgaW5wdXQgc291cmNlLgotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIFRocm93biBpZiB0aGVyZSBpcyBhCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICBjb25maWd1cmF0aW9uIGVycm9yIHdoZW4gaW5pdGlhbGl6aW5nIHRoZQotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2VyLgotICAgICAqIEBleGNlcHRpb24gSU9FeGNlcHRpb24gVGhyb3duIG9uIEkvTyBlcnJvci4KLSAgICAgKgotICAgICAqIEBzZWUgI3BhcnNlKGJvb2xlYW4pCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0SW5wdXRTb3VyY2UoWE1MSW5wdXRTb3VyY2UgaW5wdXRTb3VyY2UpCi0gICAgICAgIHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy8gUkVWSVNJVDogdGhpcyBtZXRob2QgdXNlZCB0byByZXNldCBhbGwgdGhlIGNvbXBvbmVudHMgYW5kCi0gICAgICAgIC8vICAgICAgICAgIGNvbnN0cnVjdCB0aGUgcGlwZWxpbmUuIE5vdyByZXNldCgpIGlzIGNhbGxlZAotICAgICAgICAvLyAgICAgICAgICBpbiBwYXJzZSAoYm9vbGVhbikganVzdCBiZWZvcmUgd2UgcGFyc2UgdGhlIGRvY3VtZW50Ci0gICAgICAgIC8vICAgICAgICAgIFNob3VsZCB0aGlzIG1ldGhvZCBzdGlsbCB0aHJvdyBleGNlcHRpb25zLi4/Ci0KLSAgICAgICAgZklucHV0U291cmNlID0gaW5wdXRTb3VyY2U7Ci0KLSAgICB9IC8vIHNldElucHV0U291cmNlKFhNTElucHV0U291cmNlKQotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSBsb2NhbGUgdG8gdXNlIGZvciBtZXNzYWdlcy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBsb2NhbGUgVGhlIGxvY2FsZSBvYmplY3QgdG8gdXNlIGZvciBsb2NhbGl6YXRpb24gb2YgbWVzc2FnZXMuCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIFhOSUV4Y2VwdGlvbiBUaHJvd24gaWYgdGhlIHBhcnNlciBkb2VzIG5vdCBzdXBwb3J0IHRoZQotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIHNwZWNpZmllZCBsb2NhbGUuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0TG9jYWxlKExvY2FsZSBsb2NhbGUpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBmTG9jYWxlID0gbG9jYWxlOwotICAgICAgICBmRXJyb3JSZXBvcnRlci5zZXRMb2NhbGUobG9jYWxlKTsKLSAgICB9IC8vIHNldExvY2FsZShMb2NhbGUpCi0gICAgICAgIC8qKgotICAgICAgICAgKiBTZXRzIHRoZSBkb2N1bWVudCBoYW5kbGVyIG9uIHRoZSBsYXN0IGNvbXBvbmVudCBpbiB0aGUgcGlwZWxpbmUKLSAgICAgICAgICogdG8gcmVjZWl2ZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgZG9jdW1lbnQuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBkb2N1bWVudEhhbmRsZXIgICBUaGUgZG9jdW1lbnQgaGFuZGxlci4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyB2b2lkIHNldERvY3VtZW50SGFuZGxlcihYTUxEb2N1bWVudEhhbmRsZXIgZG9jdW1lbnRIYW5kbGVyKSB7Ci0gICAgICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlciA9IGRvY3VtZW50SGFuZGxlcjsKLSAgICAgICAgICAgICAgICBpZiAoZkxhc3RDb21wb25lbnQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgZkxhc3RDb21wb25lbnQuc2V0RG9jdW1lbnRIYW5kbGVyKGZEb2N1bWVudEhhbmRsZXIpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZEb2N1bWVudEhhbmRsZXIgIT1udWxsKXsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci5zZXREb2N1bWVudFNvdXJjZShmTGFzdENvbXBvbmVudCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICB9IC8vIHNldERvY3VtZW50SGFuZGxlcihYTUxEb2N1bWVudEhhbmRsZXIpCi0KLSAgICAgICAgLyoqIFJldHVybnMgdGhlIHJlZ2lzdGVyZWQgZG9jdW1lbnQgaGFuZGxlci4gKi8KLSAgICAgICAgcHVibGljIFhNTERvY3VtZW50SGFuZGxlciBnZXREb2N1bWVudEhhbmRsZXIoKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZEb2N1bWVudEhhbmRsZXI7Ci0gICAgICAgIH0gLy8gZ2V0RG9jdW1lbnRIYW5kbGVyKCk6WE1MRG9jdW1lbnRIYW5kbGVyCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFNldHMgdGhlIERURCBoYW5kbGVyLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gZHRkSGFuZGxlciBUaGUgRFREIGhhbmRsZXIuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgdm9pZCBzZXREVERIYW5kbGVyKFhNTERUREhhbmRsZXIgZHRkSGFuZGxlcikgewotICAgICAgICAgICAgICAgIGZEVERIYW5kbGVyID0gZHRkSGFuZGxlcjsKLSAgICAgICAgfSAvLyBzZXREVERIYW5kbGVyKFhNTERUREhhbmRsZXIpCi0KLSAgICAgICAgLyoqIFJldHVybnMgdGhlIHJlZ2lzdGVyZWQgRFREIGhhbmRsZXIuICovCi0gICAgICAgIHB1YmxpYyBYTUxEVERIYW5kbGVyIGdldERUREhhbmRsZXIoKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZEVERIYW5kbGVyOwotICAgICAgICB9IC8vIGdldERUREhhbmRsZXIoKTpYTUxEVERIYW5kbGVyCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFNldHMgdGhlIERURCBjb250ZW50IG1vZGVsIGhhbmRsZXIuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBoYW5kbGVyIFRoZSBEVEQgY29udGVudCBtb2RlbCBoYW5kbGVyLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIHZvaWQgc2V0RFREQ29udGVudE1vZGVsSGFuZGxlcihYTUxEVERDb250ZW50TW9kZWxIYW5kbGVyIGhhbmRsZXIpIHsKLSAgICAgICAgICAgICAgICBmRFREQ29udGVudE1vZGVsSGFuZGxlciA9IGhhbmRsZXI7Ci0gICAgICAgIH0gLy8gc2V0RFREQ29udGVudE1vZGVsSGFuZGxlcihYTUxEVERDb250ZW50TW9kZWxIYW5kbGVyKQotCi0gICAgICAgIC8qKiBSZXR1cm5zIHRoZSByZWdpc3RlcmVkIERURCBjb250ZW50IG1vZGVsIGhhbmRsZXIuICovCi0gICAgICAgIHB1YmxpYyBYTUxEVERDb250ZW50TW9kZWxIYW5kbGVyIGdldERURENvbnRlbnRNb2RlbEhhbmRsZXIoKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZEVERDb250ZW50TW9kZWxIYW5kbGVyOwotICAgICAgICB9IC8vIGdldERURENvbnRlbnRNb2RlbEhhbmRsZXIoKTpYTUxEVERDb250ZW50TW9kZWxIYW5kbGVyCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFNldHMgdGhlIHJlc29sdmVyIHVzZWQgdG8gcmVzb2x2ZSBleHRlcm5hbCBlbnRpdGllcy4gVGhlIEVudGl0eVJlc29sdmVyCi0gICAgICAgICAqIGludGVyZmFjZSBzdXBwb3J0cyByZXNvbHV0aW9uIG9mIHB1YmxpYyBhbmQgc3lzdGVtIGlkZW50aWZpZXJzLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gcmVzb2x2ZXIgVGhlIG5ldyBlbnRpdHkgcmVzb2x2ZXIuIFBhc3NpbmcgYSBudWxsIHZhbHVlIHdpbGwKLSAgICAgICAgICogICAgICAgICAgICAgICAgIHVuaW5zdGFsbCB0aGUgY3VycmVudGx5IGluc3RhbGxlZCByZXNvbHZlci4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyB2b2lkIHNldEVudGl0eVJlc29sdmVyKFhNTEVudGl0eVJlc29sdmVyIHJlc29sdmVyKSB7Ci0gICAgICAgICAgICAgICAgZlByb3BlcnRpZXMucHV0KEVOVElUWV9SRVNPTFZFUiwgcmVzb2x2ZXIpOwotICAgICAgICB9IC8vIHNldEVudGl0eVJlc29sdmVyKFhNTEVudGl0eVJlc29sdmVyKQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBSZXR1cm4gdGhlIGN1cnJlbnQgZW50aXR5IHJlc29sdmVyLgotICAgICAgICAgKgotICAgICAgICAgKiBAcmV0dXJuIFRoZSBjdXJyZW50IGVudGl0eSByZXNvbHZlciwgb3IgbnVsbCBpZiBub25lCi0gICAgICAgICAqICAgICAgICAgaGFzIGJlZW4gcmVnaXN0ZXJlZC4KLSAgICAgICAgICogQHNlZSAjc2V0RW50aXR5UmVzb2x2ZXIKLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBYTUxFbnRpdHlSZXNvbHZlciBnZXRFbnRpdHlSZXNvbHZlcigpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gKFhNTEVudGl0eVJlc29sdmVyKWZQcm9wZXJ0aWVzLmdldChFTlRJVFlfUkVTT0xWRVIpOwotICAgICAgICB9IC8vIGdldEVudGl0eVJlc29sdmVyKCk6WE1MRW50aXR5UmVzb2x2ZXIKLQotICAgICAgICAvKioKLSAgICAgICAgICogQWxsb3cgYW4gYXBwbGljYXRpb24gdG8gcmVnaXN0ZXIgYW4gZXJyb3IgZXZlbnQgaGFuZGxlci4KLSAgICAgICAgICoKLSAgICAgICAgICogPHA+SWYgdGhlIGFwcGxpY2F0aW9uIGRvZXMgbm90IHJlZ2lzdGVyIGFuIGVycm9yIGhhbmRsZXIsIGFsbAotICAgICAgICAgKiBlcnJvciBldmVudHMgcmVwb3J0ZWQgYnkgdGhlIFNBWCBwYXJzZXIgd2lsbCBiZSBzaWxlbnRseQotICAgICAgICAgKiBpZ25vcmVkOyBob3dldmVyLCBub3JtYWwgcHJvY2Vzc2luZyBtYXkgbm90IGNvbnRpbnVlLiAgSXQgaXMKLSAgICAgICAgICogaGlnaGx5IHJlY29tbWVuZGVkIHRoYXQgYWxsIFNBWCBhcHBsaWNhdGlvbnMgaW1wbGVtZW50IGFuCi0gICAgICAgICAqIGVycm9yIGhhbmRsZXIgdG8gYXZvaWQgdW5leHBlY3RlZCBidWdzLjwvcD4KLSAgICAgICAgICoKLSAgICAgICAgICogPHA+QXBwbGljYXRpb25zIG1heSByZWdpc3RlciBhIG5ldyBvciBkaWZmZXJlbnQgaGFuZGxlciBpbiB0aGUKLSAgICAgICAgICogbWlkZGxlIG9mIGEgcGFyc2UsIGFuZCB0aGUgU0FYIHBhcnNlciBtdXN0IGJlZ2luIHVzaW5nIHRoZSBuZXcKLSAgICAgICAgICogaGFuZGxlciBpbW1lZGlhdGVseS48L3A+Ci0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBlcnJvckhhbmRsZXIgVGhlIGVycm9yIGhhbmRsZXIuCi0gICAgICAgICAqIEBleGNlcHRpb24gamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uIElmIHRoZSBoYW5kbGVyCi0gICAgICAgICAqICAgICAgICAgICAgYXJndW1lbnQgaXMgbnVsbC4KLSAgICAgICAgICogQHNlZSAjZ2V0RXJyb3JIYW5kbGVyCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgdm9pZCBzZXRFcnJvckhhbmRsZXIoWE1MRXJyb3JIYW5kbGVyIGVycm9ySGFuZGxlcikgewotICAgICAgICAgICAgICAgIGZQcm9wZXJ0aWVzLnB1dChFUlJPUl9IQU5ETEVSLCBlcnJvckhhbmRsZXIpOwotICAgICAgICB9IC8vIHNldEVycm9ySGFuZGxlcihYTUxFcnJvckhhbmRsZXIpCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFJldHVybiB0aGUgY3VycmVudCBlcnJvciBoYW5kbGVyLgotICAgICAgICAgKgotICAgICAgICAgKiBAcmV0dXJuIFRoZSBjdXJyZW50IGVycm9yIGhhbmRsZXIsIG9yIG51bGwgaWYgbm9uZQotICAgICAgICAgKiAgICAgICAgIGhhcyBiZWVuIHJlZ2lzdGVyZWQuCi0gICAgICAgICAqIEBzZWUgI3NldEVycm9ySGFuZGxlcgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIFhNTEVycm9ySGFuZGxlciBnZXRFcnJvckhhbmRsZXIoKSB7Ci0gICAgICAgICAgICAgICAgLy8gUkVWSVNJVDogU2hvdWxkIHRoaXMgYmUgYSBwcm9wZXJ0eT8KLSAgICAgICAgICAgICAgICByZXR1cm4gKFhNTEVycm9ySGFuZGxlcilmUHJvcGVydGllcy5nZXQoRVJST1JfSEFORExFUik7Ci0gICAgICAgIH0gLy8gZ2V0RXJyb3JIYW5kbGVyKCk6WE1MRXJyb3JIYW5kbGVyCi0KLQotICAgIC8qKgotICAgICAqIElmIHRoZSBhcHBsaWNhdGlvbiBkZWNpZGVzIHRvIHRlcm1pbmF0ZSBwYXJzaW5nIGJlZm9yZSB0aGUgeG1sIGRvY3VtZW50Ci0gICAgICogaXMgZnVsbHkgcGFyc2VkLCB0aGUgYXBwbGljYXRpb24gc2hvdWxkIGNhbGwgdGhpcyBtZXRob2QgdG8gZnJlZSBhbnkKLSAgICAgKiByZXNvdXJjZSBhbGxvY2F0ZWQgZHVyaW5nIHBhcnNpbmcuIEZvciBleGFtcGxlLCBjbG9zZSBhbGwgb3BlbmVkIHN0cmVhbXMuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY2xlYW51cCgpIHsKLSAgICAgICAgZkVudGl0eU1hbmFnZXIuY2xvc2VSZWFkZXJzKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUGFyc2VzIHRoZSBzcGVjaWZpZWQgaW5wdXQgc291cmNlLgotICAgICAqCi0gICAgICogQHBhcmFtIHNvdXJjZSBUaGUgaW5wdXQgc291cmNlLgotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBYTklFeGNlcHRpb24gVGhyb3dzIGV4Y2VwdGlvbiBvbiBYTkkgZXJyb3IuCi0gICAgICogQGV4Y2VwdGlvbiBqYXZhLmlvLklPRXhjZXB0aW9uIFRocm93cyBleGNlcHRpb24gb24gaS9vIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHBhcnNlKFhNTElucHV0U291cmNlIHNvdXJjZSkgdGhyb3dzIFhOSUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewotCi0gICAgICAgIGlmIChmUGFyc2VJblByb2dyZXNzKSB7Ci0gICAgICAgICAgICAvLyBSRVZJU0lUIC0gbmVlZCB0byBhZGQgbmV3IGVycm9yIG1lc3NhZ2UKLSAgICAgICAgICAgIHRocm93IG5ldyBYTklFeGNlcHRpb24oIkZXSzAwNSBwYXJzZSBtYXkgbm90IGJlIGNhbGxlZCB3aGlsZSBwYXJzaW5nLiIpOwotICAgICAgICB9Ci0gICAgICAgIGZQYXJzZUluUHJvZ3Jlc3MgPSB0cnVlOwotCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBzZXRJbnB1dFNvdXJjZShzb3VyY2UpOwotICAgICAgICAgICAgcGFyc2UodHJ1ZSk7Ci0gICAgICAgIH0gY2F0Y2ggKFhOSUV4Y2VwdGlvbiBleCkgewotICAgICAgICAgICAgaWYgKFBSSU5UX0VYQ0VQVElPTl9TVEFDS19UUkFDRSkKLSAgICAgICAgICAgICAgICBleC5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgICAgICAgIHRocm93IGV4OwotICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgewotICAgICAgICAgICAgaWYgKFBSSU5UX0VYQ0VQVElPTl9TVEFDS19UUkFDRSkKLSAgICAgICAgICAgICAgICBleC5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgICAgICAgIHRocm93IGV4OwotICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIGV4KSB7Ci0gICAgICAgICAgICBpZiAoUFJJTlRfRVhDRVBUSU9OX1NUQUNLX1RSQUNFKQotICAgICAgICAgICAgICAgIGV4LnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgICAgICAgdGhyb3cgZXg7Ci0gICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgewotICAgICAgICAgICAgaWYgKFBSSU5UX0VYQ0VQVElPTl9TVEFDS19UUkFDRSkKLSAgICAgICAgICAgICAgICBleC5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgICAgICAgIHRocm93IG5ldyBYTklFeGNlcHRpb24oZXgpOwotICAgICAgICB9IGZpbmFsbHkgewotICAgICAgICAgICAgZlBhcnNlSW5Qcm9ncmVzcyA9IGZhbHNlOwotICAgICAgICAgICAgLy8gY2xvc2UgYWxsIHN0cmVhbXMgb3BlbmVkIGJ5IHhlcmNlcwotICAgICAgICAgICAgdGhpcy5jbGVhbnVwKCk7Ci0gICAgICAgIH0KLQotICAgIH0gLy8gcGFyc2UoSW5wdXRTb3VyY2UpCi0KLSAgICBwdWJsaWMgYm9vbGVhbiBwYXJzZShib29sZWFuIGNvbXBsZXRlKSB0aHJvd3MgWE5JRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgIC8vCi0gICAgICAgIC8vIHJlc2V0IGFuZCBjb25maWd1cmUgcGlwZWxpbmUgYW5kIHNldCBJbnB1dFNvdXJjZS4KLSAgICAgICAgaWYgKGZJbnB1dFNvdXJjZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIGZWYWxpZGF0aW9uTWFuYWdlci5yZXNldCgpOwotICAgICAgICAgICAgICAgIGZWZXJzaW9uRGV0ZWN0b3IucmVzZXQodGhpcyk7Ci0gICAgICAgICAgICAgICAgZkNvbmZpZ1VwZGF0ZWQgPSB0cnVlOwotICAgICAgICAgICAgICAgIHJlc2V0Q29tbW9uKCk7Ci0KLSAgICAgICAgICAgICAgICBzaG9ydCB2ZXJzaW9uID0gZlZlcnNpb25EZXRlY3Rvci5kZXRlcm1pbmVEb2NWZXJzaW9uKGZJbnB1dFNvdXJjZSk7Ci0gICAgICAgICAgICAgICAgaWYgKHZlcnNpb24gPT0gQ29uc3RhbnRzLlhNTF9WRVJTSU9OXzFfMSkgewotICAgICAgICAgICAgICAgICAgICBpbml0WE1MMTFDb21wb25lbnRzKCk7Ci0gICAgICAgICAgICAgICAgICAgIGNvbmZpZ3VyZVhNTDExUGlwZWxpbmUoKTsKLSAgICAgICAgICAgICAgICAgICAgcmVzZXRYTUwxMSgpOwotICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIGNvbmZpZ3VyZVBpcGVsaW5lKCk7Ci0gICAgICAgICAgICAgICAgICAgIHJlc2V0KCk7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgLy8gbWFyayBjb25maWd1cmF0aW9uIGFzIGZpeGVkCi0gICAgICAgICAgICAgICAgZkNvbmZpZ1VwZGF0ZWQgPSBmYWxzZTsKLQotICAgICAgICAgICAgICAgIC8vIHJlc2V0cyBhbmQgc2V0cyB0aGUgcGlwZWxpbmUuCi0gICAgICAgICAgICAgICAgZlZlcnNpb25EZXRlY3Rvci5zdGFydERvY3VtZW50UGFyc2luZygoWE1MRW50aXR5SGFuZGxlcikgZkN1cnJlbnRTY2FubmVyLCB2ZXJzaW9uKTsKLSAgICAgICAgICAgICAgICBmSW5wdXRTb3VyY2UgPSBudWxsOwotICAgICAgICAgICAgfSBjYXRjaCAoWE5JRXhjZXB0aW9uIGV4KSB7Ci0gICAgICAgICAgICAgICAgaWYgKFBSSU5UX0VYQ0VQVElPTl9TVEFDS19UUkFDRSkKLSAgICAgICAgICAgICAgICAgICAgZXgucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgICAgICAgICAgdGhyb3cgZXg7Ci0gICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgewotICAgICAgICAgICAgICAgIGlmIChQUklOVF9FWENFUFRJT05fU1RBQ0tfVFJBQ0UpCi0gICAgICAgICAgICAgICAgICAgIGV4LnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgICAgICAgICAgIHRocm93IGV4OwotICAgICAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiBleCkgewotICAgICAgICAgICAgICAgIGlmIChQUklOVF9FWENFUFRJT05fU1RBQ0tfVFJBQ0UpCi0gICAgICAgICAgICAgICAgICAgIGV4LnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgICAgICAgICAgIHRocm93IGV4OwotICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7Ci0gICAgICAgICAgICAgICAgaWYgKFBSSU5UX0VYQ0VQVElPTl9TVEFDS19UUkFDRSkKLSAgICAgICAgICAgICAgICAgICAgZXgucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFhOSUV4Y2VwdGlvbihleCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICB0cnkgewotICAgICAgICAgICAgcmV0dXJuIGZDdXJyZW50U2Nhbm5lci5zY2FuRG9jdW1lbnQoY29tcGxldGUpOwotICAgICAgICB9IGNhdGNoIChYTklFeGNlcHRpb24gZXgpIHsKLSAgICAgICAgICAgIGlmIChQUklOVF9FWENFUFRJT05fU1RBQ0tfVFJBQ0UpCi0gICAgICAgICAgICAgICAgZXgucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgICAgICB0aHJvdyBleDsKLSAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKLSAgICAgICAgICAgIGlmIChQUklOVF9FWENFUFRJT05fU1RBQ0tfVFJBQ0UpCi0gICAgICAgICAgICAgICAgZXgucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgICAgICB0aHJvdyBleDsKLSAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiBleCkgewotICAgICAgICAgICAgaWYgKFBSSU5UX0VYQ0VQVElPTl9TVEFDS19UUkFDRSkKLSAgICAgICAgICAgICAgICBleC5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgICAgICAgIHRocm93IGV4OwotICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKLSAgICAgICAgICAgIGlmIChQUklOVF9FWENFUFRJT05fU1RBQ0tfVFJBQ0UpCi0gICAgICAgICAgICAgICAgZXgucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWE5JRXhjZXB0aW9uKGV4KTsKLSAgICAgICAgfQotCi0gICAgfSAvLyBwYXJzZShib29sZWFuKTpib29sZWFuCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFJldHVybnMgdGhlIHN0YXRlIG9mIGEgZmVhdHVyZS4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIGZlYXR1cmVJZCBUaGUgZmVhdHVyZSBpZGVudGlmaWVyLgotICAgICAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGZlYXR1cmUgaXMgc3VwcG9ydGVkCi0gICAgICAgICAqCi0gICAgICAgICAqIEB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBUaHJvd24gZm9yIGNvbmZpZ3VyYXRpb24gZXJyb3IuCi0gICAgICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbiBnZW5lcmFsLCBjb21wb25lbnRzIHNob3VsZAotICAgICAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb25seSB0aHJvdyB0aGlzIGV4Y2VwdGlvbiBpZgotICAgICAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXQgaXMgPHN0cm9uZz5yZWFsbHk8L3N0cm9uZz4KLSAgICAgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGEgY3JpdGljYWwgZXJyb3IuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgRmVhdHVyZVN0YXRlIGdldEZlYXR1cmVTdGF0ZShTdHJpbmcgZmVhdHVyZUlkKQotICAgICAgICAgICAgICAgIHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIG1ha2UgdGhpcyBmZWF0dXJlIHNwZWNpYWwKLSAgICAgICAgaWYgKGZlYXR1cmVJZC5lcXVhbHMoUEFSU0VSX1NFVFRJTkdTKSl7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIEZlYXR1cmVTdGF0ZS5pcyhmQ29uZmlnVXBkYXRlZCk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHN1cGVyLmdldEZlYXR1cmVTdGF0ZShmZWF0dXJlSWQpOwotCi0gICAgICAgIH0gLy8gZ2V0RmVhdHVyZShTdHJpbmcpOmJvb2xlYW4KLQotICAgICAgICAvKioKLSAgICAgICAgICogU2V0IHRoZSBzdGF0ZSBvZiBhIGZlYXR1cmUuCi0gICAgICAgICAqCi0gICAgICAgICAqIFNldCB0aGUgc3RhdGUgb2YgYW55IGZlYXR1cmUgaW4gYSBTQVgyIHBhcnNlci4gIFRoZSBwYXJzZXIKLSAgICAgICAgICogbWlnaHQgbm90IHJlY29nbml6ZSB0aGUgZmVhdHVyZSwgYW5kIGlmIGl0IGRvZXMgcmVjb2duaXplCi0gICAgICAgICAqIGl0LCBpdCBtaWdodCBub3QgYmUgYWJsZSB0byBmdWxmaWxsIHRoZSByZXF1ZXN0LgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gZmVhdHVyZUlkIFRoZSB1bmlxdWUgaWRlbnRpZmllciAoVVJJKSBvZiB0aGUgZmVhdHVyZS4KLSAgICAgICAgICogQHBhcmFtIHN0YXRlIFRoZSByZXF1ZXN0ZWQgc3RhdGUgb2YgdGhlIGZlYXR1cmUgKHRydWUgb3IgZmFsc2UpLgotICAgICAgICAgKgotICAgICAgICAgKiBAZXhjZXB0aW9uIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIElmIHRoZQotICAgICAgICAgKiAgICAgICAgICAgIHJlcXVlc3RlZCBmZWF0dXJlIGlzIG5vdCBrbm93bi4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyB2b2lkIHNldEZlYXR1cmUoU3RyaW5nIGZlYXR1cmVJZCwgYm9vbGVhbiBzdGF0ZSkKLSAgICAgICAgICAgICAgICB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICAgICAgZkNvbmZpZ1VwZGF0ZWQgPSB0cnVlOwotICAgICAgICAgICAgICAgIC8vIGZvcndhcmQgdG8gZXZlcnkgWE1MIDEuMCBjb21wb25lbnQKLSAgICAgICAgICAgICAgICBpbnQgY291bnQgPSBmQ29tcG9uZW50cy5zaXplKCk7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBYTUxDb21wb25lbnQgYyA9IGZDb21wb25lbnRzLmdldChpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGMuc2V0RmVhdHVyZShmZWF0dXJlSWQsIHN0YXRlKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLy8gZm9yd2FyZCBpdCB0byBjb21tb24gY29tcG9uZW50cwotICAgICAgICAgICAgICAgIGNvdW50ID0gZkNvbW1vbkNvbXBvbmVudHMuc2l6ZSgpOwotICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykgewotICAgICAgICAgICAgICAgICAgICAgICAgWE1MQ29tcG9uZW50IGMgPSBmQ29tbW9uQ29tcG9uZW50cy5nZXQoaSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBjLnNldEZlYXR1cmUoZmVhdHVyZUlkLCBzdGF0ZSk7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgLy8gZm9yd2FyZCB0byBldmVyeSBYTUwgMS4xIGNvbXBvbmVudAotICAgICAgICAgICAgICAgIGNvdW50ID0gZlhNTDExQ29tcG9uZW50cy5zaXplKCk7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBYTUxDb21wb25lbnQgYyA9IGZYTUwxMUNvbXBvbmVudHMuZ2V0KGkpOwotICAgICAgICAgICAgICAgICAgICAgICAgdHJ5ewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLnNldEZlYXR1cmUoZmVhdHVyZUlkLCBzdGF0ZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGUpewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBubyBvcAotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvLyBzYXZlIHN0YXRlIGlmIG5vb25lICJvYmplY3RzIgotICAgICAgICAgICAgICAgIHN1cGVyLnNldEZlYXR1cmUoZmVhdHVyZUlkLCBzdGF0ZSk7Ci0KLSAgICAgICAgfSAvLyBzZXRGZWF0dXJlKFN0cmluZyxib29sZWFuKQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgYSBwcm9wZXJ0eS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBwcm9wZXJ0eUlkIFRoZSBwcm9wZXJ0eSBpZGVudGlmaWVyLgotICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBwcm9wZXJ0eQotICAgICAqCi0gICAgICogQHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIFRocm93biBmb3IgY29uZmlndXJhdGlvbiBlcnJvci4KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW4gZ2VuZXJhbCwgY29tcG9uZW50cyBzaG91bGQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb25seSB0aHJvdyB0aGlzIGV4Y2VwdGlvbiBpZgotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdCBpcyA8c3Ryb25nPnJlYWxseTwvc3Ryb25nPgotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhIGNyaXRpY2FsIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyBQcm9wZXJ0eVN0YXRlIGdldFByb3BlcnR5U3RhdGUoU3RyaW5nIHByb3BlcnR5SWQpCi0gICAgICAgIHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKExPQ0FMRS5lcXVhbHMocHJvcGVydHlJZCkpIHsKLSAgICAgICAgICAgIHJldHVybiBQcm9wZXJ0eVN0YXRlLmlzKGdldExvY2FsZSgpKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gc3VwZXIuZ2V0UHJvcGVydHlTdGF0ZShwcm9wZXJ0eUlkKTsKLSAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIHNldFByb3BlcnR5Ci0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBwcm9wZXJ0eUlkCi0gICAgICAgICAqIEBwYXJhbSB2YWx1ZQotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIHZvaWQgc2V0UHJvcGVydHkoU3RyaW5nIHByb3BlcnR5SWQsIE9iamVjdCB2YWx1ZSkKLSAgICAgICAgICAgICAgICB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICAgICAgZkNvbmZpZ1VwZGF0ZWQgPSB0cnVlOwotICAgICAgICAgICAgICAgIGlmIChMT0NBTEUuZXF1YWxzKHByb3BlcnR5SWQpKSB7Ci0gICAgICAgICAgICAgICAgICAgIHNldExvY2FsZSgoTG9jYWxlKSB2YWx1ZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIC8vIGZvcndhcmQgdG8gZXZlcnkgWE1MIDEuMCBjb21wb25lbnQKLSAgICAgICAgICAgICAgICBpbnQgY291bnQgPSBmQ29tcG9uZW50cy5zaXplKCk7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBYTUxDb21wb25lbnQgYyA9IGZDb21wb25lbnRzLmdldChpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGMuc2V0UHJvcGVydHkocHJvcGVydHlJZCwgdmFsdWUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvLyBmb3J3YXJkIGl0IHRvIGV2ZXJ5IGNvbW1vbiBDb21wb25lbnQKLSAgICAgICAgICAgICAgICBjb3VudCA9IGZDb21tb25Db21wb25lbnRzLnNpemUoKTsKLSAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIFhNTENvbXBvbmVudCBjID0gZkNvbW1vbkNvbXBvbmVudHMuZ2V0KGkpOwotICAgICAgICAgICAgICAgICAgICAgICAgYy5zZXRQcm9wZXJ0eShwcm9wZXJ0eUlkLCB2YWx1ZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIC8vIGZvcndhcmQgaXQgdG8gZXZlcnkgWE1MIDEuMSBjb21wb25lbnQKLSAgICAgICAgICAgICAgICBjb3VudCA9IGZYTUwxMUNvbXBvbmVudHMuc2l6ZSgpOwotICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykgewotICAgICAgICAgICAgICAgICAgICAgICAgWE1MQ29tcG9uZW50IGMgPSBmWE1MMTFDb21wb25lbnRzLmdldChpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHRyeXsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYy5zZXRQcm9wZXJ0eShwcm9wZXJ0eUlkLCB2YWx1ZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGUpewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpZ25vcmUgaXQKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyBzdG9yZSB2YWx1ZSBpZiBub29uZSAib2JqZWN0cyIKLSAgICAgICAgICAgICAgICBzdXBlci5zZXRQcm9wZXJ0eShwcm9wZXJ0eUlkLCB2YWx1ZSk7Ci0KLSAgICAgICAgfSAvLyBzZXRQcm9wZXJ0eShTdHJpbmcsT2JqZWN0KQotCi0KLSAgICAgICAgLyoqIFJldHVybnMgdGhlIGxvY2FsZS4gKi8KLSAgICAgICAgcHVibGljIExvY2FsZSBnZXRMb2NhbGUoKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZMb2NhbGU7Ci0gICAgICAgIH0gLy8gZ2V0TG9jYWxlKCk6TG9jYWxlCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIHJlc2V0IGFsbCBYTUwgMS4wIGNvbXBvbmVudHMgYmVmb3JlIHBhcnNpbmcgYW5kIG5hbWVzcGFjZSBjb250ZXh0Ci0gICAgICAgICAqLwotICAgICAgICBwcm90ZWN0ZWQgdm9pZCByZXNldCgpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICAgICAgICAgIGludCBjb3VudCA9IGZDb21wb25lbnRzLnNpemUoKTsKLSAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIFhNTENvbXBvbmVudCBjID0gZkNvbXBvbmVudHMuZ2V0KGkpOwotICAgICAgICAgICAgICAgICAgICAgICAgYy5yZXNldCh0aGlzKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgfSAvLyByZXNldCgpCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIHJlc2V0IGFsbCBjb21tb24gY29tcG9uZW50cyBiZWZvcmUgcGFyc2luZwotICAgICAgICAgKi8KLSAgICAgICAgcHJvdGVjdGVkIHZvaWQgcmVzZXRDb21tb24oKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgICAgICAgICAvLyByZXNldCBjb21tb24gY29tcG9uZW50cwotICAgICAgICAgICAgICAgIGludCBjb3VudCA9IGZDb21tb25Db21wb25lbnRzLnNpemUoKTsKLSAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIFhNTENvbXBvbmVudCBjID0gZkNvbW1vbkNvbXBvbmVudHMuZ2V0KGkpOwotICAgICAgICAgICAgICAgICAgICAgICAgYy5yZXNldCh0aGlzKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgfSAvLyByZXNldENvbW1vbigpCi0KLQotICAgICAgICAvKioKLSAgICAgICAgICogcmVzZXQgYWxsIGNvbXBvbmVudHMgYmVmb3JlIHBhcnNpbmcgYW5kIG5hbWVzcGFjZSBjb250ZXh0Ci0gICAgICAgICAqLwotICAgICAgICBwcm90ZWN0ZWQgdm9pZCByZXNldFhNTDExKCkgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICAgICAgLy8gcmVzZXQgZXZlcnkgY29tcG9uZW50Ci0gICAgICAgICAgICAgICAgaW50IGNvdW50ID0gZlhNTDExQ29tcG9uZW50cy5zaXplKCk7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBYTUxDb21wb25lbnQgYyA9IGZYTUwxMUNvbXBvbmVudHMuZ2V0KGkpOwotICAgICAgICAgICAgICAgICAgICAgICAgYy5yZXNldCh0aGlzKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgfSAvLyByZXNldFhNTDExKCkKLQotCi0gICAgLyoqCi0gICAgICogIENvbmZpZ3VyZXMgdGhlIFhNTCAxLjEgcGlwZWxpbmUuCi0gICAgICogIE5vdGU6IHRoaXMgbWV0aG9kIGFsc28gcmVzZXRzIHRoZSBuZXcgWE1MMTEgY29tcG9uZW50cy4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCBjb25maWd1cmVYTUwxMVBpcGVsaW5lKCkgewotICAgICAgICBpZiAoZkN1cnJlbnREVkZhY3RvcnkgIT0gZlhNTDExRGF0YXR5cGVGYWN0b3J5KSB7Ci0gICAgICAgICAgICBmQ3VycmVudERWRmFjdG9yeSA9IGZYTUwxMURhdGF0eXBlRmFjdG9yeTsKLSAgICAgICAgICAgIHNldFByb3BlcnR5KERBVEFUWVBFX1ZBTElEQVRPUl9GQUNUT1JZLCBmQ3VycmVudERWRmFjdG9yeSk7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGZDdXJyZW50RFREU2Nhbm5lciAhPSBmWE1MMTFEVERTY2FubmVyKSB7Ci0gICAgICAgICAgICBmQ3VycmVudERURFNjYW5uZXIgPSBmWE1MMTFEVERTY2FubmVyOwotICAgICAgICAgICAgc2V0UHJvcGVydHkoRFREX1NDQU5ORVIsIGZDdXJyZW50RFREU2Nhbm5lcik7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzZXRQcm9wZXJ0eShEVERfUFJPQ0VTU09SLCBmWE1MMTFEVERQcm9jZXNzb3IpOwotICAgICAgICB9Ci0KLSAgICAgICAgZlhNTDExRFREU2Nhbm5lci5zZXREVERIYW5kbGVyKGZYTUwxMURURFByb2Nlc3Nvcik7Ci0gICAgICAgIGZYTUwxMURURFByb2Nlc3Nvci5zZXREVERTb3VyY2UoZlhNTDExRFREU2Nhbm5lcik7Ci0gICAgICAgIGZYTUwxMURURFByb2Nlc3Nvci5zZXREVERIYW5kbGVyKGZEVERIYW5kbGVyKTsKLSAgICAgICAgaWYgKGZEVERIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZEVERIYW5kbGVyLnNldERURFNvdXJjZShmWE1MMTFEVERQcm9jZXNzb3IpOwotICAgICAgICB9Ci0KLSAgICAgICAgZlhNTDExRFREU2Nhbm5lci5zZXREVERDb250ZW50TW9kZWxIYW5kbGVyKGZYTUwxMURURFByb2Nlc3Nvcik7Ci0gICAgICAgIGZYTUwxMURURFByb2Nlc3Nvci5zZXREVERDb250ZW50TW9kZWxTb3VyY2UoZlhNTDExRFREU2Nhbm5lcik7Ci0gICAgICAgIGZYTUwxMURURFByb2Nlc3Nvci5zZXREVERDb250ZW50TW9kZWxIYW5kbGVyKGZEVERDb250ZW50TW9kZWxIYW5kbGVyKTsKLSAgICAgICAgaWYgKGZEVERDb250ZW50TW9kZWxIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZEVERDb250ZW50TW9kZWxIYW5kbGVyLnNldERURENvbnRlbnRNb2RlbFNvdXJjZShmWE1MMTFEVERQcm9jZXNzb3IpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gc2V0dXAgWE1MIDEuMSBkb2N1bWVudCBwaXBlbGluZQotICAgICAgICBpZiAoZkZlYXR1cmVzLmdldChOQU1FU1BBQ0VTKSA9PSBCb29sZWFuLlRSVUUpIHsKLSAgICAgICAgICAgIGlmIChmQ3VycmVudFNjYW5uZXIgIT0gZlhNTDExTlNEb2NTY2FubmVyKSB7Ci0gICAgICAgICAgICAgICAgZkN1cnJlbnRTY2FubmVyID0gZlhNTDExTlNEb2NTY2FubmVyOwotICAgICAgICAgICAgICAgIHNldFByb3BlcnR5KERPQ1VNRU5UX1NDQU5ORVIsIGZYTUwxMU5TRG9jU2Nhbm5lcik7Ci0gICAgICAgICAgICAgICAgc2V0UHJvcGVydHkoRFREX1ZBTElEQVRPUiwgZlhNTDExTlNEVERWYWxpZGF0b3IpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBmWE1MMTFOU0RvY1NjYW5uZXIuc2V0RFREVmFsaWRhdG9yKGZYTUwxMU5TRFREVmFsaWRhdG9yKTsKLSAgICAgICAgICAgIGZYTUwxMU5TRG9jU2Nhbm5lci5zZXREb2N1bWVudEhhbmRsZXIoZlhNTDExTlNEVERWYWxpZGF0b3IpOwotICAgICAgICAgICAgZlhNTDExTlNEVERWYWxpZGF0b3Iuc2V0RG9jdW1lbnRTb3VyY2UoZlhNTDExTlNEb2NTY2FubmVyKTsKLSAgICAgICAgICAgIGZYTUwxMU5TRFREVmFsaWRhdG9yLnNldERvY3VtZW50SGFuZGxlcihmRG9jdW1lbnRIYW5kbGVyKTsKLQotICAgICAgICAgICAgaWYgKGZEb2N1bWVudEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZEb2N1bWVudEhhbmRsZXIuc2V0RG9jdW1lbnRTb3VyY2UoZlhNTDExTlNEVERWYWxpZGF0b3IpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZkxhc3RDb21wb25lbnQgPSBmWE1MMTFOU0RURFZhbGlkYXRvcjsKLQotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gY3JlYXRlIGNvbXBvbmVudHMKLSAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZYTUwxMURvY1NjYW5uZXIgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG5vbiBuYW1lc3BhY2UgZG9jdW1lbnQgcGlwZWxpbmUKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmWE1MMTFEb2NTY2FubmVyID0gbmV3IFhNTDExRG9jdW1lbnRTY2FubmVySW1wbCgpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZFhNTDExQ29tcG9uZW50KGZYTUwxMURvY1NjYW5uZXIpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZYTUwxMURURFZhbGlkYXRvciA9IG5ldyBYTUwxMURURFZhbGlkYXRvcigpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZFhNTDExQ29tcG9uZW50KGZYTUwxMURURFZhbGlkYXRvcik7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChmQ3VycmVudFNjYW5uZXIgIT0gZlhNTDExRG9jU2Nhbm5lcikgewotICAgICAgICAgICAgICAgIGZDdXJyZW50U2Nhbm5lciA9IGZYTUwxMURvY1NjYW5uZXI7Ci0gICAgICAgICAgICAgICAgc2V0UHJvcGVydHkoRE9DVU1FTlRfU0NBTk5FUiwgZlhNTDExRG9jU2Nhbm5lcik7Ci0gICAgICAgICAgICAgICAgc2V0UHJvcGVydHkoRFREX1ZBTElEQVRPUiwgZlhNTDExRFREVmFsaWRhdG9yKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGZYTUwxMURvY1NjYW5uZXIuc2V0RG9jdW1lbnRIYW5kbGVyKGZYTUwxMURURFZhbGlkYXRvcik7Ci0gICAgICAgICAgICBmWE1MMTFEVERWYWxpZGF0b3Iuc2V0RG9jdW1lbnRTb3VyY2UoZlhNTDExRG9jU2Nhbm5lcik7Ci0gICAgICAgICAgICBmWE1MMTFEVERWYWxpZGF0b3Iuc2V0RG9jdW1lbnRIYW5kbGVyKGZEb2N1bWVudEhhbmRsZXIpOwotCi0gICAgICAgICAgICBpZiAoZkRvY3VtZW50SGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci5zZXREb2N1bWVudFNvdXJjZShmWE1MMTFEVERWYWxpZGF0b3IpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZkxhc3RDb21wb25lbnQgPSBmWE1MMTFEVERWYWxpZGF0b3I7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBzZXR1cCBkb2N1bWVudCBwaXBlbGluZQotICAgICAgICBpZiAoZkZlYXR1cmVzLmdldChYTUxTQ0hFTUFfVkFMSURBVElPTikgPT0gQm9vbGVhbi5UUlVFKSB7Ci0gICAgICAgICAgICAvLyBJZiBzY2hlbWEgdmFsaWRhdG9yIHdhcyBub3QgaW4gdGhlIHBpcGVsaW5lIGluc2VydCBpdC4KLSAgICAgICAgICAgIGlmIChmU2NoZW1hVmFsaWRhdG9yID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmU2NoZW1hVmFsaWRhdG9yID0gbmV3IFhNTFNjaGVtYVZhbGlkYXRvcigpOwotICAgICAgICAgICAgICAgIC8vIGFkZCBzY2hlbWEgY29tcG9uZW50Ci0gICAgICAgICAgICAgICAgc2V0UHJvcGVydHkoU0NIRU1BX1ZBTElEQVRPUiwgZlNjaGVtYVZhbGlkYXRvcik7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZENvbW1vbkNvbXBvbmVudChmU2NoZW1hVmFsaWRhdG9yKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZlNjaGVtYVZhbGlkYXRvci5yZXNldCh0aGlzKTsKLSAgICAgICAgICAgICAgICAvLyBhZGQgc2NoZW1hIG1lc3NhZ2UgZm9ybWF0dGVyCi0gICAgICAgICAgICAgICAgaWYgKGZFcnJvclJlcG9ydGVyLmdldE1lc3NhZ2VGb3JtYXR0ZXIoWFNNZXNzYWdlRm9ybWF0dGVyLlNDSEVNQV9ET01BSU4pID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgWFNNZXNzYWdlRm9ybWF0dGVyIHhtZnQgPSBuZXcgWFNNZXNzYWdlRm9ybWF0dGVyKCk7Ci0gICAgICAgICAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnB1dE1lc3NhZ2VGb3JtYXR0ZXIoWFNNZXNzYWdlRm9ybWF0dGVyLlNDSEVNQV9ET01BSU4sIHhtZnQpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgZkxhc3RDb21wb25lbnQuc2V0RG9jdW1lbnRIYW5kbGVyKGZTY2hlbWFWYWxpZGF0b3IpOwotICAgICAgICAgICAgZlNjaGVtYVZhbGlkYXRvci5zZXREb2N1bWVudFNvdXJjZShmTGFzdENvbXBvbmVudCk7Ci0gICAgICAgICAgICBmU2NoZW1hVmFsaWRhdG9yLnNldERvY3VtZW50SGFuZGxlcihmRG9jdW1lbnRIYW5kbGVyKTsKLSAgICAgICAgICAgIGlmIChmRG9jdW1lbnRIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLnNldERvY3VtZW50U291cmNlKGZTY2hlbWFWYWxpZGF0b3IpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZkxhc3RDb21wb25lbnQgPSBmU2NoZW1hVmFsaWRhdG9yOwotICAgICAgICB9Ci0KLSAgICB9IC8vIGNvbmZpZ3VyZVhNTDExUGlwZWxpbmUoKQotCi0gICAgLyoqIENvbmZpZ3VyZXMgdGhlIHBpcGVsaW5lLiAqLwotICAgIHByb3RlY3RlZCB2b2lkIGNvbmZpZ3VyZVBpcGVsaW5lKCkgewotICAgICAgICBpZiAoZkN1cnJlbnREVkZhY3RvcnkgIT0gZkRhdGF0eXBlVmFsaWRhdG9yRmFjdG9yeSkgewotICAgICAgICAgICAgZkN1cnJlbnREVkZhY3RvcnkgPSBmRGF0YXR5cGVWYWxpZGF0b3JGYWN0b3J5OwotICAgICAgICAgICAgLy8gdXNlIFhNTCAxLjAgZGF0YXR5cGUgbGlicmFyeQotICAgICAgICAgICAgc2V0UHJvcGVydHkoREFUQVRZUEVfVkFMSURBVE9SX0ZBQ1RPUlksIGZDdXJyZW50RFZGYWN0b3J5KTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIHNldHVwIERURCBwaXBlbGluZQotICAgICAgICBpZiAoZkN1cnJlbnREVERTY2FubmVyICE9IGZEVERTY2FubmVyKSB7Ci0gICAgICAgICAgICBmQ3VycmVudERURFNjYW5uZXIgPSBmRFREU2Nhbm5lcjsKLSAgICAgICAgICAgIHNldFByb3BlcnR5KERURF9TQ0FOTkVSLCBmQ3VycmVudERURFNjYW5uZXIpOwotICAgICAgICAgICAgc2V0UHJvcGVydHkoRFREX1BST0NFU1NPUiwgZkRURFByb2Nlc3Nvcik7Ci0gICAgICAgIH0KLSAgICAgICAgZkRURFNjYW5uZXIuc2V0RFRESGFuZGxlcihmRFREUHJvY2Vzc29yKTsKLSAgICAgICAgZkRURFByb2Nlc3Nvci5zZXREVERTb3VyY2UoZkRURFNjYW5uZXIpOwotICAgICAgICBmRFREUHJvY2Vzc29yLnNldERUREhhbmRsZXIoZkRUREhhbmRsZXIpOwotICAgICAgICBpZiAoZkRUREhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkRUREhhbmRsZXIuc2V0RFREU291cmNlKGZEVERQcm9jZXNzb3IpOwotICAgICAgICB9Ci0KLSAgICAgICAgZkRURFNjYW5uZXIuc2V0RFREQ29udGVudE1vZGVsSGFuZGxlcihmRFREUHJvY2Vzc29yKTsKLSAgICAgICAgZkRURFByb2Nlc3Nvci5zZXREVERDb250ZW50TW9kZWxTb3VyY2UoZkRURFNjYW5uZXIpOwotICAgICAgICBmRFREUHJvY2Vzc29yLnNldERURENvbnRlbnRNb2RlbEhhbmRsZXIoZkRURENvbnRlbnRNb2RlbEhhbmRsZXIpOwotICAgICAgICBpZiAoZkRURENvbnRlbnRNb2RlbEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkRURENvbnRlbnRNb2RlbEhhbmRsZXIuc2V0RFREQ29udGVudE1vZGVsU291cmNlKGZEVERQcm9jZXNzb3IpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gc2V0dXAgZG9jdW1lbnQgcGlwZWxpbmUKLSAgICAgICAgaWYgKGZGZWF0dXJlcy5nZXQoTkFNRVNQQUNFUykgPT0gQm9vbGVhbi5UUlVFKSB7Ci0gICAgICAgICAgICBpZiAoZkN1cnJlbnRTY2FubmVyICE9IGZOYW1lc3BhY2VTY2FubmVyKSB7Ci0gICAgICAgICAgICAgICAgZkN1cnJlbnRTY2FubmVyID0gZk5hbWVzcGFjZVNjYW5uZXI7Ci0gICAgICAgICAgICAgICAgc2V0UHJvcGVydHkoRE9DVU1FTlRfU0NBTk5FUiwgZk5hbWVzcGFjZVNjYW5uZXIpOwotICAgICAgICAgICAgICAgIHNldFByb3BlcnR5KERURF9WQUxJREFUT1IsIGZEVERWYWxpZGF0b3IpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZk5hbWVzcGFjZVNjYW5uZXIuc2V0RFREVmFsaWRhdG9yKGZEVERWYWxpZGF0b3IpOwotICAgICAgICAgICAgZk5hbWVzcGFjZVNjYW5uZXIuc2V0RG9jdW1lbnRIYW5kbGVyKGZEVERWYWxpZGF0b3IpOwotICAgICAgICAgICAgZkRURFZhbGlkYXRvci5zZXREb2N1bWVudFNvdXJjZShmTmFtZXNwYWNlU2Nhbm5lcik7Ci0gICAgICAgICAgICBmRFREVmFsaWRhdG9yLnNldERvY3VtZW50SGFuZGxlcihmRG9jdW1lbnRIYW5kbGVyKTsKLSAgICAgICAgICAgIGlmIChmRG9jdW1lbnRIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLnNldERvY3VtZW50U291cmNlKGZEVERWYWxpZGF0b3IpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZkxhc3RDb21wb25lbnQgPSBmRFREVmFsaWRhdG9yOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgLy8gY3JlYXRlIGNvbXBvbmVudHMKLSAgICAgICAgICAgIGlmIChmTm9uTlNTY2FubmVyID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmTm9uTlNTY2FubmVyID0gbmV3IFhNTERvY3VtZW50U2Nhbm5lckltcGwoKTsKLSAgICAgICAgICAgICAgICBmTm9uTlNEVERWYWxpZGF0b3IgPSBuZXcgWE1MRFREVmFsaWRhdG9yKCk7Ci0gICAgICAgICAgICAgICAgLy8gYWRkIGNvbXBvbmVudHMKLSAgICAgICAgICAgICAgICBhZGRDb21wb25lbnQoKFhNTENvbXBvbmVudCkgZk5vbk5TU2Nhbm5lcik7Ci0gICAgICAgICAgICAgICAgYWRkQ29tcG9uZW50KChYTUxDb21wb25lbnQpIGZOb25OU0RURFZhbGlkYXRvcik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoZkN1cnJlbnRTY2FubmVyICE9IGZOb25OU1NjYW5uZXIpIHsKLSAgICAgICAgICAgICAgICBmQ3VycmVudFNjYW5uZXIgPSBmTm9uTlNTY2FubmVyOwotICAgICAgICAgICAgICAgIHNldFByb3BlcnR5KERPQ1VNRU5UX1NDQU5ORVIsIGZOb25OU1NjYW5uZXIpOwotICAgICAgICAgICAgICAgIHNldFByb3BlcnR5KERURF9WQUxJREFUT1IsIGZOb25OU0RURFZhbGlkYXRvcik7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGZOb25OU1NjYW5uZXIuc2V0RG9jdW1lbnRIYW5kbGVyKGZOb25OU0RURFZhbGlkYXRvcik7Ci0gICAgICAgICAgICBmTm9uTlNEVERWYWxpZGF0b3Iuc2V0RG9jdW1lbnRTb3VyY2UoZk5vbk5TU2Nhbm5lcik7Ci0gICAgICAgICAgICBmTm9uTlNEVERWYWxpZGF0b3Iuc2V0RG9jdW1lbnRIYW5kbGVyKGZEb2N1bWVudEhhbmRsZXIpOwotICAgICAgICAgICAgaWYgKGZEb2N1bWVudEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZEb2N1bWVudEhhbmRsZXIuc2V0RG9jdW1lbnRTb3VyY2UoZk5vbk5TRFREVmFsaWRhdG9yKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGZMYXN0Q29tcG9uZW50ID0gZk5vbk5TRFREVmFsaWRhdG9yOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gYWRkIFhNTCBTY2hlbWEgdmFsaWRhdG9yIGlmIG5lZWRlZAotICAgICAgICBpZiAoZkZlYXR1cmVzLmdldChYTUxTQ0hFTUFfVkFMSURBVElPTikgPT0gQm9vbGVhbi5UUlVFKSB7Ci0gICAgICAgICAgICAvLyBJZiBzY2hlbWEgdmFsaWRhdG9yIHdhcyBub3QgaW4gdGhlIHBpcGVsaW5lIGluc2VydCBpdC4KLSAgICAgICAgICAgIGlmIChmU2NoZW1hVmFsaWRhdG9yID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmU2NoZW1hVmFsaWRhdG9yID0gbmV3IFhNTFNjaGVtYVZhbGlkYXRvcigpOwotICAgICAgICAgICAgICAgIC8vIGFkZCBzY2hlbWEgY29tcG9uZW50Ci0gICAgICAgICAgICAgICAgc2V0UHJvcGVydHkoU0NIRU1BX1ZBTElEQVRPUiwgZlNjaGVtYVZhbGlkYXRvcik7Ci0gICAgICAgICAgICAgICAgYWRkQ29tbW9uQ29tcG9uZW50KGZTY2hlbWFWYWxpZGF0b3IpOwotICAgICAgICAgICAgICAgIGZTY2hlbWFWYWxpZGF0b3IucmVzZXQodGhpcyk7Ci0gICAgICAgICAgICAgICAgLy8gYWRkIHNjaGVtYSBtZXNzYWdlIGZvcm1hdHRlcgotICAgICAgICAgICAgICAgIGlmIChmRXJyb3JSZXBvcnRlci5nZXRNZXNzYWdlRm9ybWF0dGVyKFhTTWVzc2FnZUZvcm1hdHRlci5TQ0hFTUFfRE9NQUlOKSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIFhTTWVzc2FnZUZvcm1hdHRlciB4bWZ0ID0gbmV3IFhTTWVzc2FnZUZvcm1hdHRlcigpOwotICAgICAgICAgICAgICAgICAgICBmRXJyb3JSZXBvcnRlci5wdXRNZXNzYWdlRm9ybWF0dGVyKFhTTWVzc2FnZUZvcm1hdHRlci5TQ0hFTUFfRE9NQUlOLCB4bWZ0KTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGZMYXN0Q29tcG9uZW50LnNldERvY3VtZW50SGFuZGxlcihmU2NoZW1hVmFsaWRhdG9yKTsKLSAgICAgICAgICAgIGZTY2hlbWFWYWxpZGF0b3Iuc2V0RG9jdW1lbnRTb3VyY2UoZkxhc3RDb21wb25lbnQpOwotICAgICAgICAgICAgZlNjaGVtYVZhbGlkYXRvci5zZXREb2N1bWVudEhhbmRsZXIoZkRvY3VtZW50SGFuZGxlcik7Ci0gICAgICAgICAgICBpZiAoZkRvY3VtZW50SGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci5zZXREb2N1bWVudFNvdXJjZShmU2NoZW1hVmFsaWRhdG9yKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGZMYXN0Q29tcG9uZW50ID0gZlNjaGVtYVZhbGlkYXRvcjsKLSAgICAgICAgfQotICAgIH0gLy8gY29uZmlndXJlUGlwZWxpbmUoKQotCi0KLSAgICAvLyBmZWF0dXJlcyBhbmQgcHJvcGVydGllcwotCi0gICAgLyoqCi0gICAgICogQ2hlY2sgYSBmZWF0dXJlLiBJZiBmZWF0dXJlIGlzIGtub3cgYW5kIHN1cHBvcnRlZCwgdGhpcyBtZXRob2Qgc2ltcGx5Ci0gICAgICogcmV0dXJucy4gT3RoZXJ3aXNlLCB0aGUgYXBwcm9wcmlhdGUgZXhjZXB0aW9uIGlzIHRocm93bi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBmZWF0dXJlSWQgVGhlIHVuaXF1ZSBpZGVudGlmaWVyIChVUkkpIG9mIHRoZSBmZWF0dXJlLgotICAgICAqCi0gICAgICogQHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIFRocm93biBmb3IgY29uZmlndXJhdGlvbiBlcnJvci4KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW4gZ2VuZXJhbCwgY29tcG9uZW50cyBzaG91bGQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb25seSB0aHJvdyB0aGlzIGV4Y2VwdGlvbiBpZgotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdCBpcyA8c3Ryb25nPnJlYWxseTwvc3Ryb25nPgotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhIGNyaXRpY2FsIGVycm9yLgotICAgICAqLwotICAgIHByb3RlY3RlZCBGZWF0dXJlU3RhdGUgY2hlY2tGZWF0dXJlKFN0cmluZyBmZWF0dXJlSWQpIHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIHsKLQotICAgICAgICAvLwotICAgICAgICAvLyBYZXJjZXMgRmVhdHVyZXMKLSAgICAgICAgLy8KLQotICAgICAgICBpZiAoZmVhdHVyZUlkLnN0YXJ0c1dpdGgoQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCkpIHsKLSAgICAgICAgICAgIGZpbmFsIGludCBzdWZmaXhMZW5ndGggPSBmZWF0dXJlSWQubGVuZ3RoKCkgLSBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYLmxlbmd0aCgpOwotCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgLy8gaHR0cDovL2FwYWNoZS5vcmcveG1sL2ZlYXR1cmVzL3ZhbGlkYXRpb24vZHluYW1pYwotICAgICAgICAgICAgLy8gICBBbGxvd3MgdGhlIHBhcnNlciB0byB2YWxpZGF0ZSBhIGRvY3VtZW50IG9ubHkgd2hlbiBpdAotICAgICAgICAgICAgLy8gICBjb250YWlucyBhIGdyYW1tYXIuIFZhbGlkYXRpb24gaXMgdHVybmVkIG9uL29mZiBiYXNlZAotICAgICAgICAgICAgLy8gICBvbiBlYWNoIGRvY3VtZW50IGluc3RhbmNlLCBhdXRvbWF0aWNhbGx5LgotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIGlmIChzdWZmaXhMZW5ndGggPT0gQ29uc3RhbnRzLkRZTkFNSUNfVkFMSURBVElPTl9GRUFUVVJFLmxlbmd0aCgpICYmCi0gICAgICAgICAgICAgICAgZmVhdHVyZUlkLmVuZHNXaXRoKENvbnN0YW50cy5EWU5BTUlDX1ZBTElEQVRJT05fRkVBVFVSRSkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gRmVhdHVyZVN0YXRlLlJFQ09HTklaRUQ7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAvLyBodHRwOi8vYXBhY2hlLm9yZy94bWwvZmVhdHVyZXMvdmFsaWRhdGlvbi9kZWZhdWx0LWF0dHJpYnV0ZS12YWx1ZXMKLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICBpZiAoc3VmZml4TGVuZ3RoID09IENvbnN0YW50cy5ERUZBVUxUX0FUVFJJQlVURV9WQUxVRVNfRkVBVFVSRS5sZW5ndGgoKSAmJgotICAgICAgICAgICAgICAgIGZlYXR1cmVJZC5lbmRzV2l0aChDb25zdGFudHMuREVGQVVMVF9BVFRSSUJVVEVfVkFMVUVTX0ZFQVRVUkUpKSB7Ci0gICAgICAgICAgICAgICAgLy8gUkVWSVNJVAotICAgICAgICAgICAgICAgIHJldHVybiBGZWF0dXJlU3RhdGUuTk9UX1NVUFBPUlRFRDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAvLyBodHRwOi8vYXBhY2hlLm9yZy94bWwvZmVhdHVyZXMvdmFsaWRhdGlvbi9kZWZhdWx0LWF0dHJpYnV0ZS12YWx1ZXMKLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICBpZiAoc3VmZml4TGVuZ3RoID09IENvbnN0YW50cy5WQUxJREFURV9DT05URU5UX01PREVMU19GRUFUVVJFLmxlbmd0aCgpICYmCi0gICAgICAgICAgICAgICAgZmVhdHVyZUlkLmVuZHNXaXRoKENvbnN0YW50cy5WQUxJREFURV9DT05URU5UX01PREVMU19GRUFUVVJFKSkgewotICAgICAgICAgICAgICAgIC8vIFJFVklTSVQKLSAgICAgICAgICAgICAgICByZXR1cm4gRmVhdHVyZVN0YXRlLk5PVF9TVVBQT1JURUQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLwotICAgICAgICAgICAgLy8gaHR0cDovL2FwYWNoZS5vcmcveG1sL2ZlYXR1cmVzL3ZhbGlkYXRpb24vbm9udmFsaWRhdGluZy9sb2FkLWR0ZC1ncmFtbWFyCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgaWYgKHN1ZmZpeExlbmd0aCA9PSBDb25zdGFudHMuTE9BRF9EVERfR1JBTU1BUl9GRUFUVVJFLmxlbmd0aCgpICYmCi0gICAgICAgICAgICAgICAgZmVhdHVyZUlkLmVuZHNXaXRoKENvbnN0YW50cy5MT0FEX0RURF9HUkFNTUFSX0ZFQVRVUkUpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIEZlYXR1cmVTdGF0ZS5SRUNPR05JWkVEOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIC8vIGh0dHA6Ly9hcGFjaGUub3JnL3htbC9mZWF0dXJlcy92YWxpZGF0aW9uL25vbnZhbGlkYXRpbmcvbG9hZC1leHRlcm5hbC1kdGQKLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICBpZiAoc3VmZml4TGVuZ3RoID09IENvbnN0YW50cy5MT0FEX0VYVEVSTkFMX0RURF9GRUFUVVJFLmxlbmd0aCgpICYmCi0gICAgICAgICAgICAgICAgZmVhdHVyZUlkLmVuZHNXaXRoKENvbnN0YW50cy5MT0FEX0VYVEVSTkFMX0RURF9GRUFUVVJFKSkgewotICAgICAgICAgICAgICAgIHJldHVybiBGZWF0dXJlU3RhdGUuUkVDT0dOSVpFRDsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIC8vIGh0dHA6Ly9hcGFjaGUub3JnL3htbC9mZWF0dXJlcy92YWxpZGF0aW9uL2RlZmF1bHQtYXR0cmlidXRlLXZhbHVlcwotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIGlmIChzdWZmaXhMZW5ndGggPT0gQ29uc3RhbnRzLlZBTElEQVRFX0RBVEFUWVBFU19GRUFUVVJFLmxlbmd0aCgpICYmCi0gICAgICAgICAgICAgICAgZmVhdHVyZUlkLmVuZHNXaXRoKENvbnN0YW50cy5WQUxJREFURV9EQVRBVFlQRVNfRkVBVFVSRSkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gRmVhdHVyZVN0YXRlLk5PVF9TVVBQT1JURUQ7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAvLyBodHRwOi8vYXBhY2hlLm9yZy94bWwvZmVhdHVyZXMvdmFsaWRhdGlvbi9zY2hlbWEKLSAgICAgICAgICAgIC8vICAgTGV0cyB0aGUgdXNlciB0dXJuIFNjaGVtYSB2YWxpZGF0aW9uIHN1cHBvcnQgb24vb2ZmLgotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIGlmIChzdWZmaXhMZW5ndGggPT0gQ29uc3RhbnRzLlNDSEVNQV9WQUxJREFUSU9OX0ZFQVRVUkUubGVuZ3RoKCkgJiYKLSAgICAgICAgICAgICAgICBmZWF0dXJlSWQuZW5kc1dpdGgoQ29uc3RhbnRzLlNDSEVNQV9WQUxJREFUSU9OX0ZFQVRVUkUpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIEZlYXR1cmVTdGF0ZS5SRUNPR05JWkVEOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gYWN0aXZhdGUgZnVsbCBzY2hlbWEgY2hlY2tpbmcKLSAgICAgICAgICAgIGlmIChzdWZmaXhMZW5ndGggPT0gQ29uc3RhbnRzLlNDSEVNQV9GVUxMX0NIRUNLSU5HLmxlbmd0aCgpICYmCi0gICAgICAgICAgICAgICAgZmVhdHVyZUlkLmVuZHNXaXRoKENvbnN0YW50cy5TQ0hFTUFfRlVMTF9DSEVDS0lORykpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gRmVhdHVyZVN0YXRlLlJFQ09HTklaRUQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyBGZWF0dXJlIGlkZW50aWZpZXI6IGV4cG9zZSBzY2hlbWEgbm9ybWFsaXplZCB2YWx1ZQotICAgICAgICAgICAgLy8gIGh0dHA6Ly9hcGFjaGUub3JnL3htbC9mZWF0dXJlcy92YWxpZGF0aW9uL3NjaGVtYS9ub3JtYWxpemVkLXZhbHVlCi0gICAgICAgICAgICBpZiAoc3VmZml4TGVuZ3RoID09IENvbnN0YW50cy5TQ0hFTUFfTk9STUFMSVpFRF9WQUxVRS5sZW5ndGgoKSAmJgotICAgICAgICAgICAgICAgIGZlYXR1cmVJZC5lbmRzV2l0aChDb25zdGFudHMuU0NIRU1BX05PUk1BTElaRURfVkFMVUUpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIEZlYXR1cmVTdGF0ZS5SRUNPR05JWkVEOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gRmVhdHVyZSBpZGVudGlmaWVyOiBzZW5kIGVsZW1lbnQgZGVmYXVsdCB2YWx1ZSB2aWEgY2hhcmFjdGVycygpCi0gICAgICAgICAgICAvLyBodHRwOi8vYXBhY2hlLm9yZy94bWwvZmVhdHVyZXMvdmFsaWRhdGlvbi9zY2hlbWEvZWxlbWVudC1kZWZhdWx0Ci0gICAgICAgICAgICBpZiAoc3VmZml4TGVuZ3RoID09IENvbnN0YW50cy5TQ0hFTUFfRUxFTUVOVF9ERUZBVUxULmxlbmd0aCgpICYmCi0gICAgICAgICAgICAgICAgZmVhdHVyZUlkLmVuZHNXaXRoKENvbnN0YW50cy5TQ0hFTUFfRUxFTUVOVF9ERUZBVUxUKSkgewotICAgICAgICAgICAgICAgIHJldHVybiBGZWF0dXJlU3RhdGUuUkVDT0dOSVpFRDsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gc3BlY2lhbCBwZXJmb3JtYW5jZSBmZWF0dXJlOiBvbmx5IGNvbXBvbmVudCBtYW5hZ2VyIGlzIGFsbG93ZWQgdG8gc2V0IGl0LgotICAgICAgICAgICAgaWYgKHN1ZmZpeExlbmd0aCA9PSBDb25zdGFudHMuUEFSU0VSX1NFVFRJTkdTLmxlbmd0aCgpICYmCi0gICAgICAgICAgICAgICAgZmVhdHVyZUlkLmVuZHNXaXRoKENvbnN0YW50cy5QQVJTRVJfU0VUVElOR1MpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIEZlYXR1cmVTdGF0ZS5OT1RfU1VQUE9SVEVEOwotICAgICAgICAgICAgfQotCi0gICAgICAgIH0KLQotICAgICAgICAvLwotICAgICAgICAvLyBOb3QgcmVjb2duaXplZAotICAgICAgICAvLwotCi0gICAgICAgIHJldHVybiBzdXBlci5jaGVja0ZlYXR1cmUoZmVhdHVyZUlkKTsKLQotICAgIH0gLy8gY2hlY2tGZWF0dXJlKFN0cmluZykKLQotICAgIC8qKgotICAgICAqIENoZWNrIGEgcHJvcGVydHkuIElmIHRoZSBwcm9wZXJ0eSBpcyBrbm93IGFuZCBzdXBwb3J0ZWQsIHRoaXMgbWV0aG9kCi0gICAgICogc2ltcGx5IHJldHVybnMuIE90aGVyd2lzZSwgdGhlIGFwcHJvcHJpYXRlIGV4Y2VwdGlvbiBpcyB0aHJvd24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcHJvcGVydHlJZCBUaGUgdW5pcXVlIGlkZW50aWZpZXIgKFVSSSkgb2YgdGhlIHByb3BlcnR5Ci0gICAgICogICAgICAgICAgICAgICAgICAgYmVpbmcgc2V0LgotICAgICAqCi0gICAgICogQHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIFRocm93biBmb3IgY29uZmlndXJhdGlvbiBlcnJvci4KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW4gZ2VuZXJhbCwgY29tcG9uZW50cyBzaG91bGQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb25seSB0aHJvdyB0aGlzIGV4Y2VwdGlvbiBpZgotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdCBpcyA8c3Ryb25nPnJlYWxseTwvc3Ryb25nPgotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhIGNyaXRpY2FsIGVycm9yLgotICAgICAqLwotICAgIHByb3RlY3RlZCBQcm9wZXJ0eVN0YXRlIGNoZWNrUHJvcGVydHkoU3RyaW5nIHByb3BlcnR5SWQpIHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIHsKLQotICAgICAgICAvLwotICAgICAgICAvLyBYZXJjZXMgUHJvcGVydGllcwotICAgICAgICAvLwotCi0gICAgICAgIGlmIChwcm9wZXJ0eUlkLnN0YXJ0c1dpdGgoQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVgpKSB7Ci0gICAgICAgICAgICBmaW5hbCBpbnQgc3VmZml4TGVuZ3RoID0gcHJvcGVydHlJZC5sZW5ndGgoKSAtIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYLmxlbmd0aCgpOwotCi0gICAgICAgICAgICBpZiAoc3VmZml4TGVuZ3RoID09IENvbnN0YW50cy5EVERfU0NBTk5FUl9QUk9QRVJUWS5sZW5ndGgoKSAmJgotICAgICAgICAgICAgICAgIHByb3BlcnR5SWQuZW5kc1dpdGgoQ29uc3RhbnRzLkRURF9TQ0FOTkVSX1BST1BFUlRZKSkgewotICAgICAgICAgICAgICAgIHJldHVybiBQcm9wZXJ0eVN0YXRlLlJFQ09HTklaRUQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoc3VmZml4TGVuZ3RoID09IENvbnN0YW50cy5TQ0hFTUFfTE9DQVRJT04ubGVuZ3RoKCkgJiYKLSAgICAgICAgICAgICAgICBwcm9wZXJ0eUlkLmVuZHNXaXRoKENvbnN0YW50cy5TQ0hFTUFfTE9DQVRJT04pKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIFByb3BlcnR5U3RhdGUuUkVDT0dOSVpFRDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChzdWZmaXhMZW5ndGggPT0gQ29uc3RhbnRzLlNDSEVNQV9OT05TX0xPQ0FUSU9OLmxlbmd0aCgpICYmCi0gICAgICAgICAgICAgICAgcHJvcGVydHlJZC5lbmRzV2l0aChDb25zdGFudHMuU0NIRU1BX05PTlNfTE9DQVRJT04pKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIFByb3BlcnR5U3RhdGUuUkVDT0dOSVpFRDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGlmIChwcm9wZXJ0eUlkLnN0YXJ0c1dpdGgoQ29uc3RhbnRzLkpBWFBfUFJPUEVSVFlfUFJFRklYKSkgewotICAgICAgICAgICAgZmluYWwgaW50IHN1ZmZpeExlbmd0aCA9IHByb3BlcnR5SWQubGVuZ3RoKCkgLSBDb25zdGFudHMuSkFYUF9QUk9QRVJUWV9QUkVGSVgubGVuZ3RoKCk7Ci0KLSAgICAgICAgICAgIGlmIChzdWZmaXhMZW5ndGggPT0gQ29uc3RhbnRzLlNDSEVNQV9TT1VSQ0UubGVuZ3RoKCkgJiYKLSAgICAgICAgICAgICAgICBwcm9wZXJ0eUlkLmVuZHNXaXRoKENvbnN0YW50cy5TQ0hFTUFfU09VUkNFKSkgewotICAgICAgICAgICAgICAgIHJldHVybiBQcm9wZXJ0eVN0YXRlLlJFQ09HTklaRUQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBzcGVjaWFsIGNhc2VzCi0gICAgICAgIGlmIChwcm9wZXJ0eUlkLnN0YXJ0c1dpdGgoQ29uc3RhbnRzLlNBWF9QUk9QRVJUWV9QUkVGSVgpKSB7Ci0gICAgICAgICAgICBmaW5hbCBpbnQgc3VmZml4TGVuZ3RoID0gcHJvcGVydHlJZC5sZW5ndGgoKSAtIENvbnN0YW50cy5TQVhfUFJPUEVSVFlfUFJFRklYLmxlbmd0aCgpOwotCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgLy8gaHR0cDovL3htbC5vcmcvc2F4L3Byb3BlcnRpZXMveG1sLXN0cmluZwotICAgICAgICAgICAgLy8gVmFsdWUgdHlwZTogU3RyaW5nCi0gICAgICAgICAgICAvLyBBY2Nlc3M6IHJlYWQtb25seQotICAgICAgICAgICAgLy8gICBHZXQgdGhlIGxpdGVyYWwgc3RyaW5nIG9mIGNoYXJhY3RlcnMgYXNzb2NpYXRlZCB3aXRoIHRoZQotICAgICAgICAgICAgLy8gICBjdXJyZW50IGV2ZW50LiAgSWYgdGhlIHBhcnNlciByZWNvZ25pc2VzIGFuZCBzdXBwb3J0cyB0aGlzCi0gICAgICAgICAgICAvLyAgIHByb3BlcnR5IGJ1dCBpcyBub3QgY3VycmVudGx5IHBhcnNpbmcgdGV4dCwgaXQgc2hvdWxkIHJldHVybgotICAgICAgICAgICAgLy8gICBudWxsICh0aGlzIGlzIGEgZ29vZCB3YXkgdG8gY2hlY2sgZm9yIGF2YWlsYWJpbGl0eSBiZWZvcmUgdGhlCi0gICAgICAgICAgICAvLyAgIHBhcnNlIGJlZ2lucykuCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgaWYgKHN1ZmZpeExlbmd0aCA9PSBDb25zdGFudHMuWE1MX1NUUklOR19QUk9QRVJUWS5sZW5ndGgoKSAmJgotICAgICAgICAgICAgICAgIHByb3BlcnR5SWQuZW5kc1dpdGgoQ29uc3RhbnRzLlhNTF9TVFJJTkdfUFJPUEVSVFkpKSB7Ci0gICAgICAgICAgICAgICAgLy8gUkVWSVNJVCAtIHdlIHNob3VsZCBwcm9iYWJseSBhc2sgeG1sLWRldiBmb3IgYSBwcmVjaXNlCi0gICAgICAgICAgICAgICAgLy8gZGVmaW5pdGlvbiBvZiB3aGF0IHRoaXMgaXMgYWN0dWFsbHkgc3VwcG9zZWQgdG8gcmV0dXJuLCBhbmQKLSAgICAgICAgICAgICAgICAvLyBpbiBleGFjdGx5IHdoaWNoIGNpcmN1bXN0YW5jZXMuCi0gICAgICAgICAgICAgICAgcmV0dXJuIFByb3BlcnR5U3RhdGUuTk9UX1NVUFBPUlRFRDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIE5vdCByZWNvZ25pemVkCi0gICAgICAgIC8vCi0KLSAgICAgICAgcmV0dXJuIHN1cGVyLmNoZWNrUHJvcGVydHkocHJvcGVydHlJZCk7Ci0KLSAgICB9IC8vIGNoZWNrUHJvcGVydHkoU3RyaW5nKQotCi0KLSAgICAvKioKLSAgICAgKiBBZGRzIGEgY29tcG9uZW50IHRvIHRoZSBwYXJzZXIgY29uZmlndXJhdGlvbi4gVGhpcyBtZXRob2Qgd2lsbAotICAgICAqIGFsc28gYWRkIGFsbCBvZiB0aGUgY29tcG9uZW50J3MgcmVjb2duaXplZCBmZWF0dXJlcyBhbmQgcHJvcGVydGllcwotICAgICAqIHRvIHRoZSBsaXN0IG9mIGRlZmF1bHQgcmVjb2duaXplZCBmZWF0dXJlcyBhbmQgcHJvcGVydGllcy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjb21wb25lbnQgVGhlIGNvbXBvbmVudCB0byBhZGQuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgYWRkQ29tcG9uZW50KFhNTENvbXBvbmVudCBjb21wb25lbnQpIHsKLQotICAgICAgICAvLyBkb24ndCBhZGQgYSBjb21wb25lbnQgbW9yZSB0aGFuIG9uY2UKLSAgICAgICAgaWYgKGZDb21wb25lbnRzLmNvbnRhaW5zKGNvbXBvbmVudCkpIHsKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotICAgICAgICBmQ29tcG9uZW50cy5hZGQoY29tcG9uZW50KTsKLSAgICAgICAgYWRkUmVjb2duaXplZFBhcmFtc0FuZFNldERlZmF1bHRzKGNvbXBvbmVudCk7Ci0KLSAgICB9IC8vIGFkZENvbXBvbmVudChYTUxDb21wb25lbnQpCi0KLSAgICAvKioKLSAgICAgKiBBZGRzIGNvbW1vbiBjb21wb25lbnQgdG8gdGhlIHBhcnNlciBjb25maWd1cmF0aW9uLiBUaGlzIG1ldGhvZCB3aWxsCi0gICAgICogYWxzbyBhZGQgYWxsIG9mIHRoZSBjb21wb25lbnQncyByZWNvZ25pemVkIGZlYXR1cmVzIGFuZCBwcm9wZXJ0aWVzCi0gICAgICogdG8gdGhlIGxpc3Qgb2YgZGVmYXVsdCByZWNvZ25pemVkIGZlYXR1cmVzIGFuZCBwcm9wZXJ0aWVzLgotICAgICAqCi0gICAgICogQHBhcmFtIGNvbXBvbmVudCBUaGUgY29tcG9uZW50IHRvIGFkZC4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCBhZGRDb21tb25Db21wb25lbnQoWE1MQ29tcG9uZW50IGNvbXBvbmVudCkgewotCi0gICAgICAgIC8vIGRvbid0IGFkZCBhIGNvbXBvbmVudCBtb3JlIHRoYW4gb25jZQotICAgICAgICBpZiAoZkNvbW1vbkNvbXBvbmVudHMuY29udGFpbnMoY29tcG9uZW50KSkgewotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0gICAgICAgIGZDb21tb25Db21wb25lbnRzLmFkZChjb21wb25lbnQpOwotICAgICAgICBhZGRSZWNvZ25pemVkUGFyYW1zQW5kU2V0RGVmYXVsdHMoY29tcG9uZW50KTsKLQotICAgIH0gLy8gYWRkQ29tbW9uQ29tcG9uZW50KFhNTENvbXBvbmVudCkKLQotICAgIC8qKgotICAgICAqIEFkZHMgYW4gWE1MIDEuMSBjb21wb25lbnQgdG8gdGhlIHBhcnNlciBjb25maWd1cmF0aW9uLiBUaGlzIG1ldGhvZCB3aWxsCi0gICAgICogYWxzbyBhZGQgYWxsIG9mIHRoZSBjb21wb25lbnQncyByZWNvZ25pemVkIGZlYXR1cmVzIGFuZCBwcm9wZXJ0aWVzCi0gICAgICogdG8gdGhlIGxpc3Qgb2YgZGVmYXVsdCByZWNvZ25pemVkIGZlYXR1cmVzIGFuZCBwcm9wZXJ0aWVzLgotICAgICAqCi0gICAgICogQHBhcmFtIGNvbXBvbmVudCBUaGUgY29tcG9uZW50IHRvIGFkZC4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCBhZGRYTUwxMUNvbXBvbmVudChYTUxDb21wb25lbnQgY29tcG9uZW50KSB7Ci0KLSAgICAgICAgLy8gZG9uJ3QgYWRkIGEgY29tcG9uZW50IG1vcmUgdGhhbiBvbmNlCi0gICAgICAgIGlmIChmWE1MMTFDb21wb25lbnRzLmNvbnRhaW5zKGNvbXBvbmVudCkpIHsKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotICAgICAgICBmWE1MMTFDb21wb25lbnRzLmFkZChjb21wb25lbnQpOwotICAgICAgICBhZGRSZWNvZ25pemVkUGFyYW1zQW5kU2V0RGVmYXVsdHMoY29tcG9uZW50KTsKLQotICAgIH0gLy8gYWRkWE1MMTFDb21wb25lbnQoWE1MQ29tcG9uZW50KQotCi0gICAgLyoqCi0gICAgICogQWRkcyBhbGwgb2YgdGhlIGNvbXBvbmVudCdzIHJlY29nbml6ZWQgZmVhdHVyZXMgYW5kIHByb3BlcnRpZXMKLSAgICAgKiB0byB0aGUgbGlzdCBvZiBkZWZhdWx0IHJlY29nbml6ZWQgZmVhdHVyZXMgYW5kIHByb3BlcnRpZXMsIGFuZAotICAgICAqIHNldHMgZGVmYXVsdCB2YWx1ZXMgb24gdGhlIGNvbmZpZ3VyYXRpb24gZm9yIGZlYXR1cmVzIGFuZAotICAgICAqIHByb3BlcnRpZXMgd2hpY2ggd2VyZSBwcmV2aW91c2x5IGFic2VudCBmcm9tIHRoZSBjb25maWd1cmF0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIGNvbXBvbmVudCBUaGUgY29tcG9uZW50IHdob3NlIHJlY29nbml6ZWQgZmVhdHVyZXMKLSAgICAgKiBhbmQgcHJvcGVydGllcyB3aWxsIGJlIGFkZGVkIHRvIHRoZSBjb25maWd1cmF0aW9uCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgYWRkUmVjb2duaXplZFBhcmFtc0FuZFNldERlZmF1bHRzKFhNTENvbXBvbmVudCBjb21wb25lbnQpIHsKLQotICAgICAgICAvLyByZWdpc3RlciBjb21wb25lbnQncyByZWNvZ25pemVkIGZlYXR1cmVzCi0gICAgICAgIFN0cmluZ1tdIHJlY29nbml6ZWRGZWF0dXJlcyA9IGNvbXBvbmVudC5nZXRSZWNvZ25pemVkRmVhdHVyZXMoKTsKLSAgICAgICAgYWRkUmVjb2duaXplZEZlYXR1cmVzKHJlY29nbml6ZWRGZWF0dXJlcyk7Ci0KLSAgICAgICAgLy8gcmVnaXN0ZXIgY29tcG9uZW50J3MgcmVjb2duaXplZCBwcm9wZXJ0aWVzCi0gICAgICAgIFN0cmluZ1tdIHJlY29nbml6ZWRQcm9wZXJ0aWVzID0gY29tcG9uZW50LmdldFJlY29nbml6ZWRQcm9wZXJ0aWVzKCk7Ci0gICAgICAgIGFkZFJlY29nbml6ZWRQcm9wZXJ0aWVzKHJlY29nbml6ZWRQcm9wZXJ0aWVzKTsKLQotICAgICAgICAvLyBzZXQgZGVmYXVsdCB2YWx1ZXMKLSAgICAgICAgaWYgKHJlY29nbml6ZWRGZWF0dXJlcyAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlY29nbml6ZWRGZWF0dXJlcy5sZW5ndGg7ICsraSkgewotICAgICAgICAgICAgICAgIFN0cmluZyBmZWF0dXJlSWQgPSByZWNvZ25pemVkRmVhdHVyZXNbaV07Ci0gICAgICAgICAgICAgICAgQm9vbGVhbiBzdGF0ZSA9IGNvbXBvbmVudC5nZXRGZWF0dXJlRGVmYXVsdChmZWF0dXJlSWQpOwotICAgICAgICAgICAgICAgIGlmIChzdGF0ZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIERvIG5vdCBvdmVyd3JpdGUgdmFsdWVzIGFscmVhZHkgc2V0IG9uIHRoZSBjb25maWd1cmF0aW9uLgotICAgICAgICAgICAgICAgICAgICBpZiAoIWZGZWF0dXJlcy5jb250YWluc0tleShmZWF0dXJlSWQpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmRmVhdHVyZXMucHV0KGZlYXR1cmVJZCwgc3RhdGUpOwotICAgICAgICAgICAgICAgICAgICAgICAgLy8gRm9yIG5ld2x5IGFkZGVkIGNvbXBvbmVudHMgd2hvIHJlY29nbml6ZSB0aGlzIGZlYXR1cmUKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGJ1dCBkaWQgbm90IG9mZmVyIGEgZGVmYXVsdCB2YWx1ZSwgd2UgbmVlZCB0byBtYWtlCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBzdXJlIHRoZXNlIGNvbXBvbmVudHMgd2lsbCBnZXQgYW4gb3Bwb3J0dW5pdHkgdG8gcmVhZAotICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhlIHZhbHVlIGJlZm9yZSBwYXJzaW5nIGJlZ2lucy4KLSAgICAgICAgICAgICAgICAgICAgICAgIGZDb25maWdVcGRhdGVkID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBpZiAocmVjb2duaXplZFByb3BlcnRpZXMgIT0gbnVsbCkgewotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZWNvZ25pemVkUHJvcGVydGllcy5sZW5ndGg7ICsraSkgewotICAgICAgICAgICAgICAgIFN0cmluZyBwcm9wZXJ0eUlkID0gcmVjb2duaXplZFByb3BlcnRpZXNbaV07Ci0gICAgICAgICAgICAgICAgT2JqZWN0IHZhbHVlID0gY29tcG9uZW50LmdldFByb3BlcnR5RGVmYXVsdChwcm9wZXJ0eUlkKTsKLSAgICAgICAgICAgICAgICBpZiAodmFsdWUgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAvLyBEbyBub3Qgb3ZlcndyaXRlIHZhbHVlcyBhbHJlYWR5IHNldCBvbiB0aGUgY29uZmlndXJhdGlvbi4KLSAgICAgICAgICAgICAgICAgICAgaWYgKCFmUHJvcGVydGllcy5jb250YWluc0tleShwcm9wZXJ0eUlkKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgZlByb3BlcnRpZXMucHV0KHByb3BlcnR5SWQsIHZhbHVlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIEZvciBuZXdseSBhZGRlZCBjb21wb25lbnRzIHdobyByZWNvZ25pemUgdGhpcyBwcm9wZXJ0eQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gYnV0IGRpZCBub3Qgb2ZmZXIgYSBkZWZhdWx0IHZhbHVlLCB3ZSBuZWVkIHRvIG1ha2UKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIHN1cmUgdGhlc2UgY29tcG9uZW50cyB3aWxsIGdldCBhbiBvcHBvcnR1bml0eSB0byByZWFkCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGUgdmFsdWUgYmVmb3JlIHBhcnNpbmcgYmVnaW5zLgotICAgICAgICAgICAgICAgICAgICAgICAgZkNvbmZpZ1VwZGF0ZWQgPSB0cnVlOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIGluaXRYTUwxMUNvbXBvbmVudHMoKSB7Ci0gICAgICAgIGlmICghZjExSW5pdGlhbGl6ZWQpIHsKLQotICAgICAgICAgICAgLy8gY3JlYXRlIGRhdGF0eXBlIGZhY3RvcnkKLSAgICAgICAgICAgIGZYTUwxMURhdGF0eXBlRmFjdG9yeSA9IERURERWRmFjdG9yeS5nZXRJbnN0YW5jZShYTUwxMV9EQVRBVFlQRV9WQUxJREFUT1JfRkFDVE9SWSk7Ci0KLSAgICAgICAgICAgIC8vIHNldHVwIFhNTCAxLjEgRFREIHBpcGVsaW5lCi0gICAgICAgICAgICBmWE1MMTFEVERTY2FubmVyID0gbmV3IFhNTDExRFREU2Nhbm5lckltcGwoKTsKLSAgICAgICAgICAgIGFkZFhNTDExQ29tcG9uZW50KGZYTUwxMURURFNjYW5uZXIpOwotICAgICAgICAgICAgZlhNTDExRFREUHJvY2Vzc29yID0gbmV3IFhNTDExRFREUHJvY2Vzc29yKCk7Ci0gICAgICAgICAgICBhZGRYTUwxMUNvbXBvbmVudChmWE1MMTFEVERQcm9jZXNzb3IpOwotCi0gICAgICAgICAgICAvLyBzZXR1cCBYTUwgMS4xLiBkb2N1bWVudCBwaXBlbGluZSAtIG5hbWVzcGFjZSBhd2FyZQotICAgICAgICAgICAgZlhNTDExTlNEb2NTY2FubmVyID0gbmV3IFhNTDExTlNEb2N1bWVudFNjYW5uZXJJbXBsKCk7Ci0gICAgICAgICAgICBhZGRYTUwxMUNvbXBvbmVudChmWE1MMTFOU0RvY1NjYW5uZXIpOwotICAgICAgICAgICAgZlhNTDExTlNEVERWYWxpZGF0b3IgPSBuZXcgWE1MMTFOU0RURFZhbGlkYXRvcigpOwotICAgICAgICAgICAgYWRkWE1MMTFDb21wb25lbnQoZlhNTDExTlNEVERWYWxpZGF0b3IpOwotCi0gICAgICAgICAgICBmMTFJbml0aWFsaXplZCA9IHRydWU7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBzdGF0ZSBvZiBhIGZlYXR1cmUuIFRoaXMgbWV0aG9kIGNhbGxzIGdldEZlYXR1cmUoKQotICAgICAqIG9uIFBhcnNlckNvbmZpZ3VyYXRpb25TZXR0aW5ncywgYnlwYXNzaW5nIGdldEZlYXR1cmUoKSBvbiB0aGlzCi0gICAgICogY2xhc3MuCi0gICAgICovCi0gICAgRmVhdHVyZVN0YXRlIGdldEZlYXR1cmVTdGF0ZTAoU3RyaW5nIGZlYXR1cmVJZCkKLSAgICAgICAgdGhyb3dzIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gewotICAgICAgICByZXR1cm4gc3VwZXIuZ2V0RmVhdHVyZVN0YXRlKGZlYXR1cmVJZCk7Ci0gICAgfQotCi19IC8vIGNsYXNzIFhNTDExQ29uZmlndXJhdGlvbgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvcGFyc2Vycy9YTUwxMURURENvbmZpZ3VyYXRpb24uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3BhcnNlcnMvWE1MMTFEVERDb25maWd1cmF0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDNkZmE4NWUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvcGFyc2Vycy9YTUwxMURURENvbmZpZ3VyYXRpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEzMzUgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5wYXJzZXJzOwotCi1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwotaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwotaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5YTUwxMURURFNjYW5uZXJJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5YTUwxMURvY3VtZW50U2Nhbm5lckltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLlhNTDExTlNEb2N1bWVudFNjYW5uZXJJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5YTUxEVERTY2FubmVySW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuWE1MRG9jdW1lbnRTY2FubmVySW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuWE1MRW50aXR5SGFuZGxlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuWE1MRW50aXR5TWFuYWdlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuWE1MRXJyb3JSZXBvcnRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuWE1MTlNEb2N1bWVudFNjYW5uZXJJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5YTUxWZXJzaW9uRGV0ZWN0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR0ZC5YTUwxMURURFByb2Nlc3NvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHRkLlhNTDExRFREVmFsaWRhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdGQuWE1MMTFOU0RURFZhbGlkYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHRkLlhNTERURFByb2Nlc3NvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHRkLlhNTERURFZhbGlkYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHRkLlhNTE5TRFREVmFsaWRhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5EVEREVkZhY3Rvcnk7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLm1zZy5YTUxNZXNzYWdlRm9ybWF0dGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC52YWxpZGF0aW9uLlZhbGlkYXRpb25NYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5GZWF0dXJlU3RhdGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlBhcnNlckNvbmZpZ3VyYXRpb25TZXR0aW5nczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuUHJvcGVydHlTdGF0ZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuU3RhdHVzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5TeW1ib2xUYWJsZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxEVERDb250ZW50TW9kZWxIYW5kbGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTERUREhhbmRsZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MRG9jdW1lbnRIYW5kbGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTExvY2F0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE5JRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLmdyYW1tYXJzLlhNTEdyYW1tYXJQb29sOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxDb21wb25lbnQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTENvbXBvbmVudE1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTERURFNjYW5uZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTERvY3VtZW50U2Nhbm5lcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MRG9jdW1lbnRTb3VyY2U7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTEVudGl0eVJlc29sdmVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxFcnJvckhhbmRsZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTElucHV0U291cmNlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxQdWxsUGFyc2VyQ29uZmlndXJhdGlvbjsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGlzIHRoZSBEVEQtb25seSBwYXJzZXIgY29uZmlndXJhdGlvbgotICogdXNlZCB0byBwYXJzZSBYTUwgMS4wIGFuZCBYTUwgMS4xIGRvY3VtZW50cy4KLSAqCi0gKiA8cD4KLSAqIFRoaXMgY2xhc3MgcmVjb2duaXplcyB0aGUgZm9sbG93aW5nIGZlYXR1cmVzIGFuZCBwcm9wZXJ0aWVzOgotICogPHVsPgotICogPGxpPkZlYXR1cmVzCi0gKiAgPHVsPgotICogICA8bGk+aHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL3ZhbGlkYXRpb248L2xpPgotICogICA8bGk+aHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL25hbWVzcGFjZXM8L2xpPgotICogICA8bGk+aHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL2V4dGVybmFsLWdlbmVyYWwtZW50aXRpZXM8L2xpPgotICogICA8bGk+aHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL2V4dGVybmFsLXBhcmFtZXRlci1lbnRpdGllczwvbGk+Ci0gKiAgIDxsaT5odHRwOi8vYXBhY2hlLm9yZy94bWwvZmVhdHVyZXMvY29udGludWUtYWZ0ZXItZmF0YWwtZXJyb3I8L2xpPgotICogICA8bGk+aHR0cDovL2FwYWNoZS5vcmcveG1sL2ZlYXR1cmVzL2xvYWQtZXh0ZXJuYWwtZHRkPC9saT4KLSAqICA8L3VsPgotICogPGxpPlByb3BlcnRpZXMKLSAqICA8dWw+Ci0gKiAgIDxsaT5odHRwOi8veG1sLm9yZy9zYXgvcHJvcGVydGllcy94bWwtc3RyaW5nPC9saT4KLSAqICAgPGxpPmh0dHA6Ly9hcGFjaGUub3JnL3htbC9wcm9wZXJ0aWVzL2ludGVybmFsL3N5bWJvbC10YWJsZTwvbGk+Ci0gKiAgIDxsaT5odHRwOi8vYXBhY2hlLm9yZy94bWwvcHJvcGVydGllcy9pbnRlcm5hbC9lcnJvci1oYW5kbGVyPC9saT4KLSAqICAgPGxpPmh0dHA6Ly9hcGFjaGUub3JnL3htbC9wcm9wZXJ0aWVzL2ludGVybmFsL2VudGl0eS1yZXNvbHZlcjwvbGk+Ci0gKiAgIDxsaT5odHRwOi8vYXBhY2hlLm9yZy94bWwvcHJvcGVydGllcy9pbnRlcm5hbC9lcnJvci1yZXBvcnRlcjwvbGk+Ci0gKiAgIDxsaT5odHRwOi8vYXBhY2hlLm9yZy94bWwvcHJvcGVydGllcy9pbnRlcm5hbC9lbnRpdHktbWFuYWdlcjwvbGk+Ci0gKiAgIDxsaT5odHRwOi8vYXBhY2hlLm9yZy94bWwvcHJvcGVydGllcy9pbnRlcm5hbC9kb2N1bWVudC1zY2FubmVyPC9saT4KLSAqICAgPGxpPmh0dHA6Ly9hcGFjaGUub3JnL3htbC9wcm9wZXJ0aWVzL2ludGVybmFsL2R0ZC1zY2FubmVyPC9saT4KLSAqICAgPGxpPmh0dHA6Ly9hcGFjaGUub3JnL3htbC9wcm9wZXJ0aWVzL2ludGVybmFsL2dyYW1tYXItcG9vbDwvbGk+Ci0gKiAgIDxsaT5odHRwOi8vYXBhY2hlLm9yZy94bWwvcHJvcGVydGllcy9pbnRlcm5hbC92YWxpZGF0b3IvZHRkPC9saT4KLSAqICAgPGxpPmh0dHA6Ly9hcGFjaGUub3JnL3htbC9wcm9wZXJ0aWVzL2ludGVybmFsL2RhdGF0eXBlLXZhbGlkYXRvci1mYWN0b3J5PC9saT4KLSAqICA8L3VsPgotICogPC91bD4KLSAqIEBhdXRob3IgRWxlbmEgTGl0YW5pLCBJQk0KLSAqIEBhdXRob3IgTmVpbCBHcmFoYW0sIElCTQotICogQGF1dGhvciBNaWNoYWVsIEdsYXZhc3NldmljaCwgSUJNCi0gKiBAYXV0aG9yIEpvaG4gS2ltLCBJQk0KLSAqCi0gKiBAdmVyc2lvbiAkSWQ6IFhNTDExRFREQ29uZmlndXJhdGlvbi5qYXZhLHYgMS41IDIwMTAtMTEtMDEgMDQ6NDA6MTAgam9laHcgRXhwICQKLSAqLwotcHVibGljIGNsYXNzIFhNTDExRFREQ29uZmlndXJhdGlvbiBleHRlbmRzIFBhcnNlckNvbmZpZ3VyYXRpb25TZXR0aW5ncwotICAgIGltcGxlbWVudHMgWE1MUHVsbFBhcnNlckNvbmZpZ3VyYXRpb24sIFhNTDExQ29uZmlndXJhYmxlIHsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RhbnRzCi0gICAgLy8KLSAgICBwcm90ZWN0ZWQgZmluYWwgc3RhdGljIFN0cmluZyBYTUwxMV9EQVRBVFlQRV9WQUxJREFUT1JfRkFDVE9SWSA9Ci0gICAgICAgICJjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYuZHRkLlhNTDExRFRERFZGYWN0b3J5SW1wbCI7Ci0KLSAgICAvLyBmZWF0dXJlIGlkZW50aWZpZXJzCi0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiB2YWxpZGF0aW9uLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFZBTElEQVRJT04gPQotICAgICAgICBDb25zdGFudHMuU0FYX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLlZBTElEQVRJT05fRkVBVFVSRTsKLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IG5hbWVzcGFjZXMuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgTkFNRVNQQUNFUyA9Ci0gICAgICAgIENvbnN0YW50cy5TQVhfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuTkFNRVNQQUNFU19GRUFUVVJFOwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogZXh0ZXJuYWwgZ2VuZXJhbCBlbnRpdGllcy4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBFWFRFUk5BTF9HRU5FUkFMX0VOVElUSUVTID0KLSAgICAgICAgQ29uc3RhbnRzLlNBWF9GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5FWFRFUk5BTF9HRU5FUkFMX0VOVElUSUVTX0ZFQVRVUkU7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiBleHRlcm5hbCBwYXJhbWV0ZXIgZW50aXRpZXMuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVhURVJOQUxfUEFSQU1FVEVSX0VOVElUSUVTID0KLSAgICAgICAgQ29uc3RhbnRzLlNBWF9GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5FWFRFUk5BTF9QQVJBTUVURVJfRU5USVRJRVNfRkVBVFVSRTsKLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IGNvbnRpbnVlIGFmdGVyIGZhdGFsIGVycm9yLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIENPTlRJTlVFX0FGVEVSX0ZBVEFMX0VSUk9SID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5DT05USU5VRV9BRlRFUl9GQVRBTF9FUlJPUl9GRUFUVVJFOwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogbG9hZCBleHRlcm5hbCBEVEQuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgTE9BRF9FWFRFUk5BTF9EVEQgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLkxPQURfRVhURVJOQUxfRFREX0ZFQVRVUkU7Ci0KLSAgICAvLyBwcm9wZXJ0eSBpZGVudGlmaWVycwotCi0gICAgICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiB4bWwgc3RyaW5nLiAqLwotICAgICAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxfU1RSSU5HID0KLSAgICAgICAgICAgICAgICBDb25zdGFudHMuU0FYX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5YTUxfU1RSSU5HX1BST1BFUlRZOwotCi0gICAgICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBzeW1ib2wgdGFibGUuICovCi0gICAgICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFNZTUJPTF9UQUJMRSA9Ci0gICAgICAgICAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuU1lNQk9MX1RBQkxFX1BST1BFUlRZOwotCi0gICAgICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBlcnJvciBoYW5kbGVyLiAqLwotICAgICAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJPUl9IQU5ETEVSID0KLSAgICAgICAgICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5FUlJPUl9IQU5ETEVSX1BST1BFUlRZOwotCi0gICAgICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBlbnRpdHkgcmVzb2x2ZXIuICovCi0gICAgICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIEVOVElUWV9SRVNPTFZFUiA9Ci0gICAgICAgICAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuRU5USVRZX1JFU09MVkVSX1BST1BFUlRZOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IGVycm9yIHJlcG9ydGVyLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUk9SX1JFUE9SVEVSID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuRVJST1JfUkVQT1JURVJfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogZW50aXR5IG1hbmFnZXIuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgRU5USVRZX01BTkFHRVIgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5FTlRJVFlfTUFOQUdFUl9QUk9QRVJUWTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyIGRvY3VtZW50IHNjYW5uZXI6ICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgRE9DVU1FTlRfU0NBTk5FUiA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLkRPQ1VNRU5UX1NDQU5ORVJfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogRFREIHNjYW5uZXIuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgRFREX1NDQU5ORVIgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5EVERfU0NBTk5FUl9QUk9QRVJUWTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBncmFtbWFyIHBvb2wuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MR1JBTU1BUl9QT09MID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuWE1MR1JBTU1BUl9QT09MX1BST1BFUlRZOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IERURCBsb2FkZXIuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgRFREX1BST0NFU1NPUiA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLkRURF9QUk9DRVNTT1JfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogRFREIHZhbGlkYXRvci4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBEVERfVkFMSURBVE9SID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuRFREX1ZBTElEQVRPUl9QUk9QRVJUWTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBuYW1lc3BhY2UgYmluZGVyLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIE5BTUVTUEFDRV9CSU5ERVIgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5OQU1FU1BBQ0VfQklOREVSX1BST1BFUlRZOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IGRhdGF0eXBlIHZhbGlkYXRvciBmYWN0b3J5LiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIERBVEFUWVBFX1ZBTElEQVRPUl9GQUNUT1JZID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuREFUQVRZUEVfVkFMSURBVE9SX0ZBQ1RPUllfUFJPUEVSVFk7Ci0KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBWQUxJREFUSU9OX01BTkFHRVIgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5WQUxJREFUSU9OX01BTkFHRVJfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogSkFYUCBzY2hlbWEgbGFuZ3VhZ2UgLyBET00gc2NoZW1hLXR5cGUuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgSkFYUF9TQ0hFTUFfTEFOR1VBR0UgPQotICAgICAgICBDb25zdGFudHMuSkFYUF9QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuU0NIRU1BX0xBTkdVQUdFOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IEpBWFAgc2NoZW1hIHNvdXJjZS8gRE9NIHNjaGVtYS1sb2NhdGlvbi4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBKQVhQX1NDSEVNQV9TT1VSQ0UgPQotICAgICAgICBDb25zdGFudHMuSkFYUF9QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuU0NIRU1BX1NPVVJDRTsKLQotICAgIC8vIGRlYnVnZ2luZwotCi0gICAgLyoqIFNldCB0byB0cnVlIGFuZCByZWNvbXBpbGUgdG8gcHJpbnQgZXhjZXB0aW9uIHN0YWNrIHRyYWNlLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgYm9vbGVhbiBQUklOVF9FWENFUFRJT05fU1RBQ0tfVFJBQ0UgPSBmYWxzZTsKLQotICAgIC8vCi0gICAgLy8gRGF0YQotICAgIC8vCi0gICAgcHJvdGVjdGVkIFN5bWJvbFRhYmxlIGZTeW1ib2xUYWJsZTsKLSAgICBwcm90ZWN0ZWQgWE1MSW5wdXRTb3VyY2UgZklucHV0U291cmNlOwotICAgIHByb3RlY3RlZCBWYWxpZGF0aW9uTWFuYWdlciBmVmFsaWRhdGlvbk1hbmFnZXI7Ci0gICAgcHJvdGVjdGVkIFhNTFZlcnNpb25EZXRlY3RvciBmVmVyc2lvbkRldGVjdG9yOwotICAgIHByb3RlY3RlZCBYTUxMb2NhdG9yIGZMb2NhdG9yOwotICAgIHByb3RlY3RlZCBMb2NhbGUgZkxvY2FsZTsKLQotICAgIC8qKiBYTUwgMS4wIENvbXBvbmVudHMuICovCi0gICAgcHJvdGVjdGVkIEFycmF5TGlzdCBmQ29tcG9uZW50czsKLQotICAgIC8qKiBYTUwgMS4xLiBDb21wb25lbnRzLiAqLwotICAgIHByb3RlY3RlZCBBcnJheUxpc3QgZlhNTDExQ29tcG9uZW50cyA9IG51bGw7Ci0KLSAgICAvKiogQ29tbW9uIGNvbXBvbmVudHM6IFhNTEVudGl0eU1hbmFnZXIsIFhNTEVycm9yUmVwb3J0ZXIgKi8KLSAgICBwcm90ZWN0ZWQgQXJyYXlMaXN0IGZDb21tb25Db21wb25lbnRzID0gbnVsbDsKLQotICAgIC8qKiBUaGUgZG9jdW1lbnQgaGFuZGxlci4gKi8KLSAgICBwcm90ZWN0ZWQgWE1MRG9jdW1lbnRIYW5kbGVyIGZEb2N1bWVudEhhbmRsZXI7Ci0KLSAgICAvKiogVGhlIERURCBoYW5kbGVyLiAqLwotICAgIHByb3RlY3RlZCBYTUxEVERIYW5kbGVyIGZEVERIYW5kbGVyOwotCi0gICAgLyoqIFRoZSBEVEQgY29udGVudCBtb2RlbCBoYW5kbGVyLiAqLwotICAgIHByb3RlY3RlZCBYTUxEVERDb250ZW50TW9kZWxIYW5kbGVyIGZEVERDb250ZW50TW9kZWxIYW5kbGVyOwotCi0gICAgLyoqIExhc3QgY29tcG9uZW50IGluIHRoZSBkb2N1bWVudCBwaXBlbGluZSAqLwotICAgIHByb3RlY3RlZCBYTUxEb2N1bWVudFNvdXJjZSBmTGFzdENvbXBvbmVudDsKLQotICAgIC8qKgotICAgICAqIFRydWUgaWYgYSBwYXJzZSBpcyBpbiBwcm9ncmVzcy4gVGhpcyBzdGF0ZSBpcyBuZWVkZWQgYmVjYXVzZQotICAgICAqIHNvbWUgZmVhdHVyZXMvcHJvcGVydGllcyBjYW5ub3QgYmUgc2V0IHdoaWxlIHBhcnNpbmcgKGUuZy4KLSAgICAgKiB2YWxpZGF0aW9uIGFuZCBuYW1lc3BhY2VzKS4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBmUGFyc2VJblByb2dyZXNzID0gZmFsc2U7Ci0KLSAgICAvKioKLSAgICAgKiBmQ29uZmlnVXBkYXRlZCBpcyBzZXQgdG8gdHJ1ZSBpZiB0aGVyZSBoYXMgYmVlbiBhbnkgY2hhbmdlIHRvIHRoZSBjb25maWd1cmF0aW9uIHNldHRpbmdzLAotICAgICAqIGkuZSBhIGZlYXR1cmUgb3IgYSBwcm9wZXJ0eSB3YXMgY2hhbmdlZC4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBmQ29uZmlnVXBkYXRlZCA9IGZhbHNlOwotCi0gICAgLy8KLSAgICAvLyBYTUwgMS4wIGNvbXBvbmVudHMKLSAgICAvLwotCi0gICAgLyoqIFRoZSBYTUwgMS4wIERhdGF0eXBlIHZhbGlkYXRvciBmYWN0b3J5LiAqLwotICAgIHByb3RlY3RlZCBEVEREVkZhY3RvcnkgZkRhdGF0eXBlVmFsaWRhdG9yRmFjdG9yeTsKLQotICAgIC8qKiBUaGUgWE1MIDEuMCBEb2N1bWVudCBzY2FubmVyIHRoYXQgZG9lcyBuYW1lc3BhY2UgYmluZGluZy4gKi8KLSAgICBwcm90ZWN0ZWQgWE1MTlNEb2N1bWVudFNjYW5uZXJJbXBsIGZOYW1lc3BhY2VTY2FubmVyOwotCi0gICAgLyoqIFRoZSBYTUwgMS4wIE5vbi1uYW1lc3BhY2UgaW1wbGVtZW50YXRpb24gb2Ygc2Nhbm5lciAqLwotICAgIHByb3RlY3RlZCBYTUxEb2N1bWVudFNjYW5uZXJJbXBsIGZOb25OU1NjYW5uZXI7Ci0KLSAgICAvKiogVGhlIFhNTCAxLjAgRFREIFZhbGlkYXRvcjogYmluZHMgbmFtZXNwYWNlcyAqLwotICAgIHByb3RlY3RlZCBYTUxEVERWYWxpZGF0b3IgZkRURFZhbGlkYXRvcjsKLQotICAgIC8qKiBUaGUgWE1MIDEuMCBEVEQgVmFsaWRhdG9yIHRoYXQgZG9lcyBub3QgYmluZCBuYW1lc3BhY2VzICovCi0gICAgcHJvdGVjdGVkIFhNTERURFZhbGlkYXRvciBmTm9uTlNEVERWYWxpZGF0b3I7Ci0KLSAgICAvKiogVGhlIFhNTCAxLjAgRFREIHNjYW5uZXIuICovCi0gICAgcHJvdGVjdGVkIFhNTERURFNjYW5uZXIgZkRURFNjYW5uZXI7Ci0KLSAgICAvKiogVGhlIFhNTCAxLjAgRFREIFByb2Nlc3NvciAuICovCi0gICAgcHJvdGVjdGVkIFhNTERURFByb2Nlc3NvciBmRFREUHJvY2Vzc29yOwotCi0gICAgLy8KLSAgICAvLyBYTUwgMS4xIGNvbXBvbmVudHMKLSAgICAvLwotCi0gICAgLyoqIFRoZSBYTUwgMS4xIGRhdGF0eXBlIGZhY3RvcnkuICoqLwotICAgIHByb3RlY3RlZCBEVEREVkZhY3RvcnkgZlhNTDExRGF0YXR5cGVGYWN0b3J5ID0gbnVsbDsKLQotICAgIC8qKiBUaGUgWE1MIDEuMSBkb2N1bWVudCBzY2FubmVyIHRoYXQgZG9lcyBuYW1lc3BhY2UgYmluZGluZy4gKiovCi0gICAgcHJvdGVjdGVkIFhNTDExTlNEb2N1bWVudFNjYW5uZXJJbXBsIGZYTUwxMU5TRG9jU2Nhbm5lciA9IG51bGw7Ci0KLSAgICAvKiogVGhlIFhNTCAxLjEgZG9jdW1lbnQgc2Nhbm5lciB0aGF0IGRvZXMgbm90IGRvIG5hbWVzcGFjZSBiaW5kaW5nLiAqKi8KLSAgICBwcm90ZWN0ZWQgWE1MMTFEb2N1bWVudFNjYW5uZXJJbXBsIGZYTUwxMURvY1NjYW5uZXIgPSBudWxsOwotCi0gICAgLyoqIFRoZSBYTUwgMS4xIERURCB2YWxpZGF0b3IgdGhhdCBkb2VzIG5hbWVzcGFjZSBiaW5kaW5nLiAqKi8KLSAgICBwcm90ZWN0ZWQgWE1MMTFOU0RURFZhbGlkYXRvciBmWE1MMTFOU0RURFZhbGlkYXRvciA9IG51bGw7Ci0KLSAgICAvKiogVGhlIFhNTCAxLjEgRFREIHZhbGlkYXRvciB0aGF0IGRvZXMgbm90IGRvIG5hbWVzcGFjZSBiaW5kaW5nLiAqKi8KLSAgICBwcm90ZWN0ZWQgWE1MMTFEVERWYWxpZGF0b3IgZlhNTDExRFREVmFsaWRhdG9yID0gbnVsbDsKLQotICAgIC8qKiBUaGUgWE1MIDEuMSBEVEQgc2Nhbm5lci4gKiovCi0gICAgcHJvdGVjdGVkIFhNTDExRFREU2Nhbm5lckltcGwgZlhNTDExRFREU2Nhbm5lciA9IG51bGw7Ci0KLSAgICAvKiogVGhlIFhNTCAxLjEgRFREIHByb2Nlc3Nvci4gKiovCi0gICAgcHJvdGVjdGVkIFhNTDExRFREUHJvY2Vzc29yIGZYTUwxMURURFByb2Nlc3NvciA9IG51bGw7Ci0KLSAgICAvLwotICAgIC8vIENvbW1vbiBjb21wb25lbnRzCi0gICAgLy8KLQotICAgIC8qKiBHcmFtbWFyIHBvb2wuICovCi0gICAgcHJvdGVjdGVkIFhNTEdyYW1tYXJQb29sIGZHcmFtbWFyUG9vbDsKLQotICAgIC8qKiBFcnJvciByZXBvcnRlci4gKi8KLSAgICBwcm90ZWN0ZWQgWE1MRXJyb3JSZXBvcnRlciBmRXJyb3JSZXBvcnRlcjsKLQotICAgIC8qKiBFbnRpdHkgbWFuYWdlci4gKi8KLSAgICBwcm90ZWN0ZWQgWE1MRW50aXR5TWFuYWdlciBmRW50aXR5TWFuYWdlcjsKLQotICAgIC8qKiBDdXJyZW50IHNjYW5uZXIgKi8KLSAgICBwcm90ZWN0ZWQgWE1MRG9jdW1lbnRTY2FubmVyIGZDdXJyZW50U2Nhbm5lcjsKLQotICAgIC8qKiBDdXJyZW50IERhdGF0eXBlIHZhbGlkYXRvciBmYWN0b3J5LiAqLwotICAgIHByb3RlY3RlZCBEVEREVkZhY3RvcnkgZkN1cnJlbnREVkZhY3Rvcnk7Ci0KLSAgICAvKiogQ3VycmVudCBEVEQgc2Nhbm5lci4gKi8KLSAgICBwcm90ZWN0ZWQgWE1MRFREU2Nhbm5lciBmQ3VycmVudERURFNjYW5uZXI7Ci0KLSAgICAvKiogRmxhZyBpbmRpY2lhdGluZyB3aGV0aGVyIFhNTDExIGNvbXBvbmVudHMgaGF2ZSBiZWVuIGluaXRpYWxpemVkLiAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBmMTFJbml0aWFsaXplZCA9IGZhbHNlOwotCi0gICAgLy8KLSAgICAvLyBDb25zdHJ1Y3RvcnMKLSAgICAvLwotCi0gICAgLyoqIERlZmF1bHQgY29uc3RydWN0b3IuICovCi0gICAgcHVibGljIFhNTDExRFREQ29uZmlndXJhdGlvbigpIHsKLSAgICAgICAgdGhpcyhudWxsLCBudWxsLCBudWxsKTsKLSAgICB9IC8vIDxpbml0PigpCi0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RzIGEgcGFyc2VyIGNvbmZpZ3VyYXRpb24gdXNpbmcgdGhlIHNwZWNpZmllZCBzeW1ib2wgdGFibGUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc3ltYm9sVGFibGUgVGhlIHN5bWJvbCB0YWJsZSB0byB1c2UuCi0gICAgICovCi0gICAgcHVibGljIFhNTDExRFREQ29uZmlndXJhdGlvbihTeW1ib2xUYWJsZSBzeW1ib2xUYWJsZSkgewotICAgICAgICB0aGlzKHN5bWJvbFRhYmxlLCBudWxsLCBudWxsKTsKLSAgICB9IC8vIDxpbml0PihTeW1ib2xUYWJsZSkKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHMgYSBwYXJzZXIgY29uZmlndXJhdGlvbiB1c2luZyB0aGUgc3BlY2lmaWVkIHN5bWJvbCB0YWJsZSBhbmQKLSAgICAgKiBncmFtbWFyIHBvb2wuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5SRVZJU0lUOjwvc3Ryb25nPgotICAgICAqIEdyYW1tYXIgcG9vbCB3aWxsIGJlIHVwZGF0ZWQgd2hlbiB0aGUgbmV3IHZhbGlkYXRpb24gZW5naW5lIGlzCi0gICAgICogaW1wbGVtZW50ZWQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc3ltYm9sVGFibGUgVGhlIHN5bWJvbCB0YWJsZSB0byB1c2UuCi0gICAgICogQHBhcmFtIGdyYW1tYXJQb29sIFRoZSBncmFtbWFyIHBvb2wgdG8gdXNlLgotICAgICAqLwotICAgIHB1YmxpYyBYTUwxMURURENvbmZpZ3VyYXRpb24oU3ltYm9sVGFibGUgc3ltYm9sVGFibGUsIFhNTEdyYW1tYXJQb29sIGdyYW1tYXJQb29sKSB7Ci0gICAgICAgIHRoaXMoc3ltYm9sVGFibGUsIGdyYW1tYXJQb29sLCBudWxsKTsKLSAgICB9IC8vIDxpbml0PihTeW1ib2xUYWJsZSxYTUxHcmFtbWFyUG9vbCkKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHMgYSBwYXJzZXIgY29uZmlndXJhdGlvbiB1c2luZyB0aGUgc3BlY2lmaWVkIHN5bWJvbCB0YWJsZSwKLSAgICAgKiBncmFtbWFyIHBvb2wsIGFuZCBwYXJlbnQgc2V0dGluZ3MuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5SRVZJU0lUOjwvc3Ryb25nPgotICAgICAqIEdyYW1tYXIgcG9vbCB3aWxsIGJlIHVwZGF0ZWQgd2hlbiB0aGUgbmV3IHZhbGlkYXRpb24gZW5naW5lIGlzCi0gICAgICogaW1wbGVtZW50ZWQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc3ltYm9sVGFibGUgICAgVGhlIHN5bWJvbCB0YWJsZSB0byB1c2UuCi0gICAgICogQHBhcmFtIGdyYW1tYXJQb29sICAgIFRoZSBncmFtbWFyIHBvb2wgdG8gdXNlLgotICAgICAqIEBwYXJhbSBwYXJlbnRTZXR0aW5ncyBUaGUgcGFyZW50IHNldHRpbmdzLgotICAgICAqLwotICAgIHB1YmxpYyBYTUwxMURURENvbmZpZ3VyYXRpb24oCi0gICAgICAgIFN5bWJvbFRhYmxlIHN5bWJvbFRhYmxlLAotICAgICAgICBYTUxHcmFtbWFyUG9vbCBncmFtbWFyUG9vbCwKLSAgICAgICAgWE1MQ29tcG9uZW50TWFuYWdlciBwYXJlbnRTZXR0aW5ncykgewotCi0gICAgICAgICAgICAgICAgc3VwZXIocGFyZW50U2V0dGluZ3MpOwotCi0gICAgICAgICAgICAgICAgLy8gY3JlYXRlIGEgdmVjdG9yIHRvIGhvbGQgYWxsIHRoZSBjb21wb25lbnRzIGluIHVzZQotICAgICAgICAgICAgICAgIC8vIFhNTCAxLjAgc3BlY2lhbGl6ZWQgY29tcG9uZW50cwotICAgICAgICAgICAgICAgIGZDb21wb25lbnRzID0gbmV3IEFycmF5TGlzdCgpOwotICAgICAgICAgICAgICAgIC8vIFhNTCAxLjEgc3BlY2lhbGl6ZWQgY29tcG9uZW50cwotICAgICAgICAgICAgICAgIGZYTUwxMUNvbXBvbmVudHMgPSBuZXcgQXJyYXlMaXN0KCk7Ci0gICAgICAgICAgICAgICAgLy8gQ29tbW9uIGNvbXBvbmVudHMgZm9yIFhNTCAxLjEuIGFuZCBYTUwgMS4wCi0gICAgICAgICAgICAgICAgZkNvbW1vbkNvbXBvbmVudHMgPSBuZXcgQXJyYXlMaXN0KCk7Ci0KLSAgICAgICAgICAgICAgICAvLyBjcmVhdGUgdGFibGUgZm9yIGZlYXR1cmVzIGFuZCBwcm9wZXJ0aWVzCi0gICAgICAgICAgICAgICAgZkZlYXR1cmVzID0gbmV3IEhhc2hNYXAoKTsKLSAgICAgICAgICAgICAgICBmUHJvcGVydGllcyA9IG5ldyBIYXNoTWFwKCk7Ci0KLSAgICAgICAgLy8gYWRkIGRlZmF1bHQgcmVjb2duaXplZCBmZWF0dXJlcwotICAgICAgICBmaW5hbCBTdHJpbmdbXSByZWNvZ25pemVkRmVhdHVyZXMgPQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIENPTlRJTlVFX0FGVEVSX0ZBVEFMX0VSUk9SLCBMT0FEX0VYVEVSTkFMX0RURCwgLy8gZnJvbSBYTUxEVERTY2FubmVySW1wbAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWQUxJREFUSU9OLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOQU1FU1BBQ0VTLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFWFRFUk5BTF9HRU5FUkFMX0VOVElUSUVTLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFWFRFUk5BTF9QQVJBTUVURVJfRU5USVRJRVMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBBUlNFUl9TRVRUSU5HUwotICAgICAgICAgICAgICAgICAgICAgICAgfTsKLSAgICAgICAgYWRkUmVjb2duaXplZEZlYXR1cmVzKHJlY29nbml6ZWRGZWF0dXJlcyk7Ci0gICAgICAgICAgICAgICAgLy8gc2V0IHN0YXRlIGZvciBkZWZhdWx0IGZlYXR1cmVzCi0gICAgICAgICAgICAgICAgZkZlYXR1cmVzLnB1dChWQUxJREFUSU9OLCBCb29sZWFuLkZBTFNFKTsKLSAgICAgICAgICAgICAgICBmRmVhdHVyZXMucHV0KE5BTUVTUEFDRVMsIEJvb2xlYW4uVFJVRSk7Ci0gICAgICAgICAgICAgICAgZkZlYXR1cmVzLnB1dChFWFRFUk5BTF9HRU5FUkFMX0VOVElUSUVTLCBCb29sZWFuLlRSVUUpOwotICAgICAgICAgICAgICAgIGZGZWF0dXJlcy5wdXQoRVhURVJOQUxfUEFSQU1FVEVSX0VOVElUSUVTLCBCb29sZWFuLlRSVUUpOwotICAgICAgICAgICAgICAgIGZGZWF0dXJlcy5wdXQoQ09OVElOVUVfQUZURVJfRkFUQUxfRVJST1IsIEJvb2xlYW4uRkFMU0UpOwotICAgICAgICAgICAgICAgIGZGZWF0dXJlcy5wdXQoTE9BRF9FWFRFUk5BTF9EVEQsIEJvb2xlYW4uVFJVRSk7Ci0gICAgICAgICAgICAgICAgZkZlYXR1cmVzLnB1dChQQVJTRVJfU0VUVElOR1MsIEJvb2xlYW4uVFJVRSk7Ci0KLSAgICAgICAgLy8gYWRkIGRlZmF1bHQgcmVjb2duaXplZCBwcm9wZXJ0aWVzCi0gICAgICAgIGZpbmFsIFN0cmluZ1tdIHJlY29nbml6ZWRQcm9wZXJ0aWVzID0KLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU1lNQk9MX1RBQkxFLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFUlJPUl9IQU5ETEVSLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFTlRJVFlfUkVTT0xWRVIsCi0gICAgICAgICAgICAgICAgRVJST1JfUkVQT1JURVIsCi0gICAgICAgICAgICAgICAgRU5USVRZX01BTkFHRVIsCi0gICAgICAgICAgICAgICAgRE9DVU1FTlRfU0NBTk5FUiwKLSAgICAgICAgICAgICAgICBEVERfU0NBTk5FUiwKLSAgICAgICAgICAgICAgICBEVERfUFJPQ0VTU09SLAotICAgICAgICAgICAgICAgIERURF9WQUxJREFUT1IsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERBVEFUWVBFX1ZBTElEQVRPUl9GQUNUT1JZLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWQUxJREFUSU9OX01BTkFHRVIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTF9TVFJJTkcsCi0gICAgICAgICAgICAgICAgWE1MR1JBTU1BUl9QT09MLAotICAgICAgICAgICAgICAgIEpBWFBfU0NIRU1BX1NPVVJDRSwKLSAgICAgICAgICAgICAgICBKQVhQX1NDSEVNQV9MQU5HVUFHRX07Ci0gICAgICAgIGFkZFJlY29nbml6ZWRQcm9wZXJ0aWVzKHJlY29nbml6ZWRQcm9wZXJ0aWVzKTsKLQotICAgICAgICAgICAgICAgIGlmIChzeW1ib2xUYWJsZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzeW1ib2xUYWJsZSA9IG5ldyBTeW1ib2xUYWJsZSgpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBmU3ltYm9sVGFibGUgPSBzeW1ib2xUYWJsZTsKLSAgICAgICAgICAgICAgICBmUHJvcGVydGllcy5wdXQoU1lNQk9MX1RBQkxFLCBmU3ltYm9sVGFibGUpOwotCi0gICAgICAgIGZHcmFtbWFyUG9vbCA9IGdyYW1tYXJQb29sOwotICAgICAgICBpZiAoZkdyYW1tYXJQb29sICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZQcm9wZXJ0aWVzLnB1dChYTUxHUkFNTUFSX1BPT0wsIGZHcmFtbWFyUG9vbCk7Ci0gICAgICAgIH0KLQotICAgICAgICBmRW50aXR5TWFuYWdlciA9IG5ldyBYTUxFbnRpdHlNYW5hZ2VyKCk7Ci0gICAgICAgICAgICAgICAgZlByb3BlcnRpZXMucHV0KEVOVElUWV9NQU5BR0VSLCBmRW50aXR5TWFuYWdlcik7Ci0gICAgICAgIGFkZENvbW1vbkNvbXBvbmVudChmRW50aXR5TWFuYWdlcik7Ci0KLSAgICAgICAgZkVycm9yUmVwb3J0ZXIgPSBuZXcgWE1MRXJyb3JSZXBvcnRlcigpOwotICAgICAgICBmRXJyb3JSZXBvcnRlci5zZXREb2N1bWVudExvY2F0b3IoZkVudGl0eU1hbmFnZXIuZ2V0RW50aXR5U2Nhbm5lcigpKTsKLSAgICAgICAgICAgICAgICBmUHJvcGVydGllcy5wdXQoRVJST1JfUkVQT1JURVIsIGZFcnJvclJlcG9ydGVyKTsKLSAgICAgICAgYWRkQ29tbW9uQ29tcG9uZW50KGZFcnJvclJlcG9ydGVyKTsKLQotICAgICAgICBmTmFtZXNwYWNlU2Nhbm5lciA9IG5ldyBYTUxOU0RvY3VtZW50U2Nhbm5lckltcGwoKTsKLSAgICAgICAgICAgICAgICBmUHJvcGVydGllcy5wdXQoRE9DVU1FTlRfU0NBTk5FUiwgZk5hbWVzcGFjZVNjYW5uZXIpOwotICAgICAgICBhZGRDb21wb25lbnQoKFhNTENvbXBvbmVudCkgZk5hbWVzcGFjZVNjYW5uZXIpOwotCi0gICAgICAgIGZEVERTY2FubmVyID0gbmV3IFhNTERURFNjYW5uZXJJbXBsKCk7Ci0gICAgICAgICAgICAgICAgZlByb3BlcnRpZXMucHV0KERURF9TQ0FOTkVSLCBmRFREU2Nhbm5lcik7Ci0gICAgICAgIGFkZENvbXBvbmVudCgoWE1MQ29tcG9uZW50KSBmRFREU2Nhbm5lcik7Ci0KLSAgICAgICAgZkRURFByb2Nlc3NvciA9IG5ldyBYTUxEVERQcm9jZXNzb3IoKTsKLSAgICAgICAgICAgICAgICBmUHJvcGVydGllcy5wdXQoRFREX1BST0NFU1NPUiwgZkRURFByb2Nlc3Nvcik7Ci0gICAgICAgIGFkZENvbXBvbmVudCgoWE1MQ29tcG9uZW50KSBmRFREUHJvY2Vzc29yKTsKLQotICAgICAgICBmRFREVmFsaWRhdG9yID0gbmV3IFhNTE5TRFREVmFsaWRhdG9yKCk7Ci0gICAgICAgICAgICAgICAgZlByb3BlcnRpZXMucHV0KERURF9WQUxJREFUT1IsIGZEVERWYWxpZGF0b3IpOwotICAgICAgICBhZGRDb21wb25lbnQoZkRURFZhbGlkYXRvcik7Ci0KLSAgICAgICAgZkRhdGF0eXBlVmFsaWRhdG9yRmFjdG9yeSA9IERURERWRmFjdG9yeS5nZXRJbnN0YW5jZSgpOwotICAgICAgICAgICAgICAgIGZQcm9wZXJ0aWVzLnB1dChEQVRBVFlQRV9WQUxJREFUT1JfRkFDVE9SWSwgZkRhdGF0eXBlVmFsaWRhdG9yRmFjdG9yeSk7Ci0KLSAgICAgICAgZlZhbGlkYXRpb25NYW5hZ2VyID0gbmV3IFZhbGlkYXRpb25NYW5hZ2VyKCk7Ci0gICAgICAgICAgICAgICAgZlByb3BlcnRpZXMucHV0KFZBTElEQVRJT05fTUFOQUdFUiwgZlZhbGlkYXRpb25NYW5hZ2VyKTsKLQotICAgICAgICBmVmVyc2lvbkRldGVjdG9yID0gbmV3IFhNTFZlcnNpb25EZXRlY3RvcigpOwotCi0gICAgICAgIC8vIGFkZCBtZXNzYWdlIGZvcm1hdHRlcnMKLSAgICAgICAgaWYgKGZFcnJvclJlcG9ydGVyLmdldE1lc3NhZ2VGb3JtYXR0ZXIoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOKSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBYTUxNZXNzYWdlRm9ybWF0dGVyIHhtZnQgPSBuZXcgWE1MTWVzc2FnZUZvcm1hdHRlcigpOwotICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucHV0TWVzc2FnZUZvcm1hdHRlcihYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sIHhtZnQpOwotICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucHV0TWVzc2FnZUZvcm1hdHRlcihYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTE5TX0RPTUFJTiwgeG1mdCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBzZXQgbG9jYWxlCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBzZXRMb2NhbGUoTG9jYWxlLmdldERlZmF1bHQoKSk7Ci0gICAgICAgIH0gY2F0Y2ggKFhOSUV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAvLyBkbyBub3RoaW5nCi0gICAgICAgICAgICAvLyBSRVZJU0lUOiBXaGF0IGlzIHRoZSByaWdodCB0aGluZyB0byBkbz8gLUFjCi0gICAgICAgIH0KLQotICAgICAgICAgICAgICAgIGZDb25maWdVcGRhdGVkID0gZmFsc2U7Ci0KLSAgICB9IC8vIDxpbml0PihTeW1ib2xUYWJsZSxYTUxHcmFtbWFyUG9vbCkKLQotICAgIC8vCi0gICAgLy8gUHVibGljIG1ldGhvZHMKLSAgICAvLwotICAgIC8qKgotICAgICAqIFNldHMgdGhlIGlucHV0IHNvdXJjZSBmb3IgdGhlIGRvY3VtZW50IHRvIHBhcnNlLgotICAgICAqCi0gICAgICogQHBhcmFtIGlucHV0U291cmNlIFRoZSBkb2N1bWVudCdzIGlucHV0IHNvdXJjZS4KLSAgICAgKgotICAgICAqIEBleGNlcHRpb24gWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBUaHJvd24gaWYgdGhlcmUgaXMgYQotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgY29uZmlndXJhdGlvbiBlcnJvciB3aGVuIGluaXRpYWxpemluZyB0aGUKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgIHBhcnNlci4KLSAgICAgKiBAZXhjZXB0aW9uIElPRXhjZXB0aW9uIFRocm93biBvbiBJL08gZXJyb3IuCi0gICAgICoKLSAgICAgKiBAc2VlICNwYXJzZShib29sZWFuKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldElucHV0U291cmNlKFhNTElucHV0U291cmNlIGlucHV0U291cmNlKQotICAgICAgICB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewotCi0gICAgICAgIC8vIFJFVklTSVQ6IHRoaXMgbWV0aG9kIHVzZWQgdG8gcmVzZXQgYWxsIHRoZSBjb21wb25lbnRzIGFuZAotICAgICAgICAvLyAgICAgICAgICBjb25zdHJ1Y3QgdGhlIHBpcGVsaW5lLiBOb3cgcmVzZXQoKSBpcyBjYWxsZWQKLSAgICAgICAgLy8gICAgICAgICAgaW4gcGFyc2UgKGJvb2xlYW4pIGp1c3QgYmVmb3JlIHdlIHBhcnNlIHRoZSBkb2N1bWVudAotICAgICAgICAvLyAgICAgICAgICBTaG91bGQgdGhpcyBtZXRob2Qgc3RpbGwgdGhyb3cgZXhjZXB0aW9ucy4uPwotCi0gICAgICAgIGZJbnB1dFNvdXJjZSA9IGlucHV0U291cmNlOwotCi0gICAgfSAvLyBzZXRJbnB1dFNvdXJjZShYTUxJbnB1dFNvdXJjZSkKLQotICAgIC8qKgotICAgICAqIFNldCB0aGUgbG9jYWxlIHRvIHVzZSBmb3IgbWVzc2FnZXMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbG9jYWxlIFRoZSBsb2NhbGUgb2JqZWN0IHRvIHVzZSBmb3IgbG9jYWxpemF0aW9uIG9mIG1lc3NhZ2VzLgotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBYTklFeGNlcHRpb24gVGhyb3duIGlmIHRoZSBwYXJzZXIgZG9lcyBub3Qgc3VwcG9ydCB0aGUKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBzcGVjaWZpZWQgbG9jYWxlLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldExvY2FsZShMb2NhbGUgbG9jYWxlKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgZkxvY2FsZSA9IGxvY2FsZTsKLSAgICAgICAgZkVycm9yUmVwb3J0ZXIuc2V0TG9jYWxlKGxvY2FsZSk7Ci0gICAgfSAvLyBzZXRMb2NhbGUoTG9jYWxlKQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBTZXRzIHRoZSBkb2N1bWVudCBoYW5kbGVyIG9uIHRoZSBsYXN0IGNvbXBvbmVudCBpbiB0aGUgcGlwZWxpbmUKLSAgICAgICAgICogdG8gcmVjZWl2ZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgZG9jdW1lbnQuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBkb2N1bWVudEhhbmRsZXIgICBUaGUgZG9jdW1lbnQgaGFuZGxlci4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyB2b2lkIHNldERvY3VtZW50SGFuZGxlcihYTUxEb2N1bWVudEhhbmRsZXIgZG9jdW1lbnRIYW5kbGVyKSB7Ci0gICAgICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlciA9IGRvY3VtZW50SGFuZGxlcjsKLSAgICAgICAgICAgICAgICBpZiAoZkxhc3RDb21wb25lbnQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgZkxhc3RDb21wb25lbnQuc2V0RG9jdW1lbnRIYW5kbGVyKGZEb2N1bWVudEhhbmRsZXIpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZEb2N1bWVudEhhbmRsZXIgIT1udWxsKXsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci5zZXREb2N1bWVudFNvdXJjZShmTGFzdENvbXBvbmVudCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICB9IC8vIHNldERvY3VtZW50SGFuZGxlcihYTUxEb2N1bWVudEhhbmRsZXIpCi0KLSAgICAgICAgLyoqIFJldHVybnMgdGhlIHJlZ2lzdGVyZWQgZG9jdW1lbnQgaGFuZGxlci4gKi8KLSAgICAgICAgcHVibGljIFhNTERvY3VtZW50SGFuZGxlciBnZXREb2N1bWVudEhhbmRsZXIoKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZEb2N1bWVudEhhbmRsZXI7Ci0gICAgICAgIH0gLy8gZ2V0RG9jdW1lbnRIYW5kbGVyKCk6WE1MRG9jdW1lbnRIYW5kbGVyCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFNldHMgdGhlIERURCBoYW5kbGVyLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gZHRkSGFuZGxlciBUaGUgRFREIGhhbmRsZXIuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgdm9pZCBzZXREVERIYW5kbGVyKFhNTERUREhhbmRsZXIgZHRkSGFuZGxlcikgewotICAgICAgICAgICAgICAgIGZEVERIYW5kbGVyID0gZHRkSGFuZGxlcjsKLSAgICAgICAgfSAvLyBzZXREVERIYW5kbGVyKFhNTERUREhhbmRsZXIpCi0KLSAgICAgICAgLyoqIFJldHVybnMgdGhlIHJlZ2lzdGVyZWQgRFREIGhhbmRsZXIuICovCi0gICAgICAgIHB1YmxpYyBYTUxEVERIYW5kbGVyIGdldERUREhhbmRsZXIoKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZEVERIYW5kbGVyOwotICAgICAgICB9IC8vIGdldERUREhhbmRsZXIoKTpYTUxEVERIYW5kbGVyCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFNldHMgdGhlIERURCBjb250ZW50IG1vZGVsIGhhbmRsZXIuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBoYW5kbGVyIFRoZSBEVEQgY29udGVudCBtb2RlbCBoYW5kbGVyLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIHZvaWQgc2V0RFREQ29udGVudE1vZGVsSGFuZGxlcihYTUxEVERDb250ZW50TW9kZWxIYW5kbGVyIGhhbmRsZXIpIHsKLSAgICAgICAgICAgICAgICBmRFREQ29udGVudE1vZGVsSGFuZGxlciA9IGhhbmRsZXI7Ci0gICAgICAgIH0gLy8gc2V0RFREQ29udGVudE1vZGVsSGFuZGxlcihYTUxEVERDb250ZW50TW9kZWxIYW5kbGVyKQotCi0gICAgICAgIC8qKiBSZXR1cm5zIHRoZSByZWdpc3RlcmVkIERURCBjb250ZW50IG1vZGVsIGhhbmRsZXIuICovCi0gICAgICAgIHB1YmxpYyBYTUxEVERDb250ZW50TW9kZWxIYW5kbGVyIGdldERURENvbnRlbnRNb2RlbEhhbmRsZXIoKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZEVERDb250ZW50TW9kZWxIYW5kbGVyOwotICAgICAgICB9IC8vIGdldERURENvbnRlbnRNb2RlbEhhbmRsZXIoKTpYTUxEVERDb250ZW50TW9kZWxIYW5kbGVyCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFNldHMgdGhlIHJlc29sdmVyIHVzZWQgdG8gcmVzb2x2ZSBleHRlcm5hbCBlbnRpdGllcy4gVGhlIEVudGl0eVJlc29sdmVyCi0gICAgICAgICAqIGludGVyZmFjZSBzdXBwb3J0cyByZXNvbHV0aW9uIG9mIHB1YmxpYyBhbmQgc3lzdGVtIGlkZW50aWZpZXJzLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gcmVzb2x2ZXIgVGhlIG5ldyBlbnRpdHkgcmVzb2x2ZXIuIFBhc3NpbmcgYSBudWxsIHZhbHVlIHdpbGwKLSAgICAgICAgICogICAgICAgICAgICAgICAgIHVuaW5zdGFsbCB0aGUgY3VycmVudGx5IGluc3RhbGxlZCByZXNvbHZlci4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyB2b2lkIHNldEVudGl0eVJlc29sdmVyKFhNTEVudGl0eVJlc29sdmVyIHJlc29sdmVyKSB7Ci0gICAgICAgICAgICAgICAgZlByb3BlcnRpZXMucHV0KEVOVElUWV9SRVNPTFZFUiwgcmVzb2x2ZXIpOwotICAgICAgICB9IC8vIHNldEVudGl0eVJlc29sdmVyKFhNTEVudGl0eVJlc29sdmVyKQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBSZXR1cm4gdGhlIGN1cnJlbnQgZW50aXR5IHJlc29sdmVyLgotICAgICAgICAgKgotICAgICAgICAgKiBAcmV0dXJuIFRoZSBjdXJyZW50IGVudGl0eSByZXNvbHZlciwgb3IgbnVsbCBpZiBub25lCi0gICAgICAgICAqICAgICAgICAgaGFzIGJlZW4gcmVnaXN0ZXJlZC4KLSAgICAgICAgICogQHNlZSAjc2V0RW50aXR5UmVzb2x2ZXIKLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBYTUxFbnRpdHlSZXNvbHZlciBnZXRFbnRpdHlSZXNvbHZlcigpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gKFhNTEVudGl0eVJlc29sdmVyKWZQcm9wZXJ0aWVzLmdldChFTlRJVFlfUkVTT0xWRVIpOwotICAgICAgICB9IC8vIGdldEVudGl0eVJlc29sdmVyKCk6WE1MRW50aXR5UmVzb2x2ZXIKLQotICAgICAgICAvKioKLSAgICAgICAgICogQWxsb3cgYW4gYXBwbGljYXRpb24gdG8gcmVnaXN0ZXIgYW4gZXJyb3IgZXZlbnQgaGFuZGxlci4KLSAgICAgICAgICoKLSAgICAgICAgICogPHA+SWYgdGhlIGFwcGxpY2F0aW9uIGRvZXMgbm90IHJlZ2lzdGVyIGFuIGVycm9yIGhhbmRsZXIsIGFsbAotICAgICAgICAgKiBlcnJvciBldmVudHMgcmVwb3J0ZWQgYnkgdGhlIFNBWCBwYXJzZXIgd2lsbCBiZSBzaWxlbnRseQotICAgICAgICAgKiBpZ25vcmVkOyBob3dldmVyLCBub3JtYWwgcHJvY2Vzc2luZyBtYXkgbm90IGNvbnRpbnVlLiAgSXQgaXMKLSAgICAgICAgICogaGlnaGx5IHJlY29tbWVuZGVkIHRoYXQgYWxsIFNBWCBhcHBsaWNhdGlvbnMgaW1wbGVtZW50IGFuCi0gICAgICAgICAqIGVycm9yIGhhbmRsZXIgdG8gYXZvaWQgdW5leHBlY3RlZCBidWdzLjwvcD4KLSAgICAgICAgICoKLSAgICAgICAgICogPHA+QXBwbGljYXRpb25zIG1heSByZWdpc3RlciBhIG5ldyBvciBkaWZmZXJlbnQgaGFuZGxlciBpbiB0aGUKLSAgICAgICAgICogbWlkZGxlIG9mIGEgcGFyc2UsIGFuZCB0aGUgU0FYIHBhcnNlciBtdXN0IGJlZ2luIHVzaW5nIHRoZSBuZXcKLSAgICAgICAgICogaGFuZGxlciBpbW1lZGlhdGVseS48L3A+Ci0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBlcnJvckhhbmRsZXIgVGhlIGVycm9yIGhhbmRsZXIuCi0gICAgICAgICAqIEBleGNlcHRpb24gamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uIElmIHRoZSBoYW5kbGVyCi0gICAgICAgICAqICAgICAgICAgICAgYXJndW1lbnQgaXMgbnVsbC4KLSAgICAgICAgICogQHNlZSAjZ2V0RXJyb3JIYW5kbGVyCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgdm9pZCBzZXRFcnJvckhhbmRsZXIoWE1MRXJyb3JIYW5kbGVyIGVycm9ySGFuZGxlcikgewotICAgICAgICAgICAgICAgIGZQcm9wZXJ0aWVzLnB1dChFUlJPUl9IQU5ETEVSLCBlcnJvckhhbmRsZXIpOwotICAgICAgICB9IC8vIHNldEVycm9ySGFuZGxlcihYTUxFcnJvckhhbmRsZXIpCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFJldHVybiB0aGUgY3VycmVudCBlcnJvciBoYW5kbGVyLgotICAgICAgICAgKgotICAgICAgICAgKiBAcmV0dXJuIFRoZSBjdXJyZW50IGVycm9yIGhhbmRsZXIsIG9yIG51bGwgaWYgbm9uZQotICAgICAgICAgKiAgICAgICAgIGhhcyBiZWVuIHJlZ2lzdGVyZWQuCi0gICAgICAgICAqIEBzZWUgI3NldEVycm9ySGFuZGxlcgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIFhNTEVycm9ySGFuZGxlciBnZXRFcnJvckhhbmRsZXIoKSB7Ci0gICAgICAgICAgICAgICAgLy8gUkVWSVNJVDogU2hvdWxkIHRoaXMgYmUgYSBwcm9wZXJ0eT8KLSAgICAgICAgICAgICAgICByZXR1cm4gKFhNTEVycm9ySGFuZGxlcilmUHJvcGVydGllcy5nZXQoRVJST1JfSEFORExFUik7Ci0gICAgICAgIH0gLy8gZ2V0RXJyb3JIYW5kbGVyKCk6WE1MRXJyb3JIYW5kbGVyCi0KLQotICAgIC8qKgotICAgICAqIElmIHRoZSBhcHBsaWNhdGlvbiBkZWNpZGVzIHRvIHRlcm1pbmF0ZSBwYXJzaW5nIGJlZm9yZSB0aGUgeG1sIGRvY3VtZW50Ci0gICAgICogaXMgZnVsbHkgcGFyc2VkLCB0aGUgYXBwbGljYXRpb24gc2hvdWxkIGNhbGwgdGhpcyBtZXRob2QgdG8gZnJlZSBhbnkKLSAgICAgKiByZXNvdXJjZSBhbGxvY2F0ZWQgZHVyaW5nIHBhcnNpbmcuIEZvciBleGFtcGxlLCBjbG9zZSBhbGwgb3BlbmVkIHN0cmVhbXMuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY2xlYW51cCgpIHsKLSAgICAgICAgZkVudGl0eU1hbmFnZXIuY2xvc2VSZWFkZXJzKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUGFyc2VzIHRoZSBzcGVjaWZpZWQgaW5wdXQgc291cmNlLgotICAgICAqCi0gICAgICogQHBhcmFtIHNvdXJjZSBUaGUgaW5wdXQgc291cmNlLgotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBYTklFeGNlcHRpb24gVGhyb3dzIGV4Y2VwdGlvbiBvbiBYTkkgZXJyb3IuCi0gICAgICogQGV4Y2VwdGlvbiBqYXZhLmlvLklPRXhjZXB0aW9uIFRocm93cyBleGNlcHRpb24gb24gaS9vIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHBhcnNlKFhNTElucHV0U291cmNlIHNvdXJjZSkgdGhyb3dzIFhOSUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewotCi0gICAgICAgIGlmIChmUGFyc2VJblByb2dyZXNzKSB7Ci0gICAgICAgICAgICAvLyBSRVZJU0lUIC0gbmVlZCB0byBhZGQgbmV3IGVycm9yIG1lc3NhZ2UKLSAgICAgICAgICAgIHRocm93IG5ldyBYTklFeGNlcHRpb24oIkZXSzAwNSBwYXJzZSBtYXkgbm90IGJlIGNhbGxlZCB3aGlsZSBwYXJzaW5nLiIpOwotICAgICAgICB9Ci0gICAgICAgIGZQYXJzZUluUHJvZ3Jlc3MgPSB0cnVlOwotCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBzZXRJbnB1dFNvdXJjZShzb3VyY2UpOwotICAgICAgICAgICAgcGFyc2UodHJ1ZSk7Ci0gICAgICAgIH0gY2F0Y2ggKFhOSUV4Y2VwdGlvbiBleCkgewotICAgICAgICAgICAgaWYgKFBSSU5UX0VYQ0VQVElPTl9TVEFDS19UUkFDRSkKLSAgICAgICAgICAgICAgICBleC5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgICAgICAgIHRocm93IGV4OwotICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgewotICAgICAgICAgICAgaWYgKFBSSU5UX0VYQ0VQVElPTl9TVEFDS19UUkFDRSkKLSAgICAgICAgICAgICAgICBleC5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgICAgICAgIHRocm93IGV4OwotICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIGV4KSB7Ci0gICAgICAgICAgICBpZiAoUFJJTlRfRVhDRVBUSU9OX1NUQUNLX1RSQUNFKQotICAgICAgICAgICAgICAgIGV4LnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgICAgICAgdGhyb3cgZXg7Ci0gICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgewotICAgICAgICAgICAgaWYgKFBSSU5UX0VYQ0VQVElPTl9TVEFDS19UUkFDRSkKLSAgICAgICAgICAgICAgICBleC5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgICAgICAgIHRocm93IG5ldyBYTklFeGNlcHRpb24oZXgpOwotICAgICAgICB9IGZpbmFsbHkgewotICAgICAgICAgICAgZlBhcnNlSW5Qcm9ncmVzcyA9IGZhbHNlOwotICAgICAgICAgICAgLy8gY2xvc2UgYWxsIHN0cmVhbXMgb3BlbmVkIGJ5IHhlcmNlcwotICAgICAgICAgICAgdGhpcy5jbGVhbnVwKCk7Ci0gICAgICAgIH0KLQotICAgIH0gLy8gcGFyc2UoSW5wdXRTb3VyY2UpCi0KLSAgICBwdWJsaWMgYm9vbGVhbiBwYXJzZShib29sZWFuIGNvbXBsZXRlKSB0aHJvd3MgWE5JRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgIC8vCi0gICAgICAgIC8vIHJlc2V0IGFuZCBjb25maWd1cmUgcGlwZWxpbmUgYW5kIHNldCBJbnB1dFNvdXJjZS4KLSAgICAgICAgaWYgKGZJbnB1dFNvdXJjZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmVmFsaWRhdGlvbk1hbmFnZXIucmVzZXQoKTsKLSAgICAgICAgICAgICAgICBmVmVyc2lvbkRldGVjdG9yLnJlc2V0KHRoaXMpOwotICAgICAgICAgICAgICAgIHJlc2V0Q29tbW9uKCk7Ci0KLSAgICAgICAgICAgICAgICBzaG9ydCB2ZXJzaW9uID0gZlZlcnNpb25EZXRlY3Rvci5kZXRlcm1pbmVEb2NWZXJzaW9uKGZJbnB1dFNvdXJjZSk7Ci0gICAgICAgICAgICAgICAgaWYgKHZlcnNpb24gPT0gQ29uc3RhbnRzLlhNTF9WRVJTSU9OXzFfMSkgewotICAgICAgICAgICAgICAgICAgICBpbml0WE1MMTFDb21wb25lbnRzKCk7Ci0gICAgICAgICAgICAgICAgICAgIGNvbmZpZ3VyZVhNTDExUGlwZWxpbmUoKTsKLSAgICAgICAgICAgICAgICAgICAgcmVzZXRYTUwxMSgpOwotICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIGNvbmZpZ3VyZVBpcGVsaW5lKCk7Ci0gICAgICAgICAgICAgICAgICAgIHJlc2V0KCk7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgLy8gbWFyayBjb25maWd1cmF0aW9uIGFzIGZpeGVkCi0gICAgICAgICAgICAgICAgZkNvbmZpZ1VwZGF0ZWQgPSBmYWxzZTsKLQotICAgICAgICAgICAgICAgIC8vIHJlc2V0cyBhbmQgc2V0cyB0aGUgcGlwZWxpbmUuCi0gICAgICAgICAgICAgICAgZlZlcnNpb25EZXRlY3Rvci5zdGFydERvY3VtZW50UGFyc2luZygoWE1MRW50aXR5SGFuZGxlcikgZkN1cnJlbnRTY2FubmVyLCB2ZXJzaW9uKTsKLSAgICAgICAgICAgICAgICBmSW5wdXRTb3VyY2UgPSBudWxsOwotICAgICAgICAgICAgfSBjYXRjaCAoWE5JRXhjZXB0aW9uIGV4KSB7Ci0gICAgICAgICAgICAgICAgaWYgKFBSSU5UX0VYQ0VQVElPTl9TVEFDS19UUkFDRSkKLSAgICAgICAgICAgICAgICAgICAgZXgucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgICAgICAgICAgdGhyb3cgZXg7Ci0gICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgewotICAgICAgICAgICAgICAgIGlmIChQUklOVF9FWENFUFRJT05fU1RBQ0tfVFJBQ0UpCi0gICAgICAgICAgICAgICAgICAgIGV4LnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgICAgICAgICAgIHRocm93IGV4OwotICAgICAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiBleCkgewotICAgICAgICAgICAgICAgIGlmIChQUklOVF9FWENFUFRJT05fU1RBQ0tfVFJBQ0UpCi0gICAgICAgICAgICAgICAgICAgIGV4LnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgICAgICAgICAgIHRocm93IGV4OwotICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7Ci0gICAgICAgICAgICAgICAgaWYgKFBSSU5UX0VYQ0VQVElPTl9TVEFDS19UUkFDRSkKLSAgICAgICAgICAgICAgICAgICAgZXgucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFhOSUV4Y2VwdGlvbihleCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICB0cnkgewotICAgICAgICAgICAgcmV0dXJuIGZDdXJyZW50U2Nhbm5lci5zY2FuRG9jdW1lbnQoY29tcGxldGUpOwotICAgICAgICB9IGNhdGNoIChYTklFeGNlcHRpb24gZXgpIHsKLSAgICAgICAgICAgIGlmIChQUklOVF9FWENFUFRJT05fU1RBQ0tfVFJBQ0UpCi0gICAgICAgICAgICAgICAgZXgucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgICAgICB0aHJvdyBleDsKLSAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKLSAgICAgICAgICAgIGlmIChQUklOVF9FWENFUFRJT05fU1RBQ0tfVFJBQ0UpCi0gICAgICAgICAgICAgICAgZXgucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgICAgICB0aHJvdyBleDsKLSAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiBleCkgewotICAgICAgICAgICAgaWYgKFBSSU5UX0VYQ0VQVElPTl9TVEFDS19UUkFDRSkKLSAgICAgICAgICAgICAgICBleC5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgICAgICAgIHRocm93IGV4OwotICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKLSAgICAgICAgICAgIGlmIChQUklOVF9FWENFUFRJT05fU1RBQ0tfVFJBQ0UpCi0gICAgICAgICAgICAgICAgZXgucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWE5JRXhjZXB0aW9uKGV4KTsKLSAgICAgICAgfQotCi0gICAgfSAvLyBwYXJzZShib29sZWFuKTpib29sZWFuCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFJldHVybnMgdGhlIHN0YXRlIG9mIGEgZmVhdHVyZS4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIGZlYXR1cmVJZCBUaGUgZmVhdHVyZSBpZGVudGlmaWVyLgotICAgICAgICAgICAgICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgZmVhdHVyZSBpcyBzdXBwb3J0ZWQKLSAgICAgICAgICoKLSAgICAgICAgICogQHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIFRocm93biBmb3IgY29uZmlndXJhdGlvbiBlcnJvci4KLSAgICAgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluIGdlbmVyYWwsIGNvbXBvbmVudHMgc2hvdWxkCi0gICAgICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbmx5IHRocm93IHRoaXMgZXhjZXB0aW9uIGlmCi0gICAgICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdCBpcyA8c3Ryb25nPnJlYWxseTwvc3Ryb25nPgotICAgICAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYSBjcml0aWNhbCBlcnJvci4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBGZWF0dXJlU3RhdGUgZ2V0RmVhdHVyZVN0YXRlKFN0cmluZyBmZWF0dXJlSWQpCi0gICAgICAgICAgICAgICAgdGhyb3dzIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gbWFrZSB0aGlzIGZlYXR1cmUgc3BlY2lhbAotICAgICAgICBpZiAoZmVhdHVyZUlkLmVxdWFscyhQQVJTRVJfU0VUVElOR1MpKXsKLSAgICAgICAgICAgICAgICByZXR1cm4gRmVhdHVyZVN0YXRlLmlzKGZDb25maWdVcGRhdGVkKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gc3VwZXIuZ2V0RmVhdHVyZVN0YXRlKGZlYXR1cmVJZCk7Ci0KLSAgICAgICAgfSAvLyBnZXRGZWF0dXJlKFN0cmluZyk6Ym9vbGVhbgotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBTZXQgdGhlIHN0YXRlIG9mIGEgZmVhdHVyZS4KLSAgICAgICAgICoKLSAgICAgICAgICogU2V0IHRoZSBzdGF0ZSBvZiBhbnkgZmVhdHVyZSBpbiBhIFNBWDIgcGFyc2VyLiAgVGhlIHBhcnNlcgotICAgICAgICAgKiBtaWdodCBub3QgcmVjb2duaXplIHRoZSBmZWF0dXJlLCBhbmQgaWYgaXQgZG9lcyByZWNvZ25pemUKLSAgICAgICAgICogaXQsIGl0IG1pZ2h0IG5vdCBiZSBhYmxlIHRvIGZ1bGZpbGwgdGhlIHJlcXVlc3QuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBmZWF0dXJlSWQgVGhlIHVuaXF1ZSBpZGVudGlmaWVyIChVUkkpIG9mIHRoZSBmZWF0dXJlLgotICAgICAgICAgKiBAcGFyYW0gc3RhdGUgVGhlIHJlcXVlc3RlZCBzdGF0ZSBvZiB0aGUgZmVhdHVyZSAodHJ1ZSBvciBmYWxzZSkuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBleGNlcHRpb24gY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gSWYgdGhlCi0gICAgICAgICAqICAgICAgICAgICAgcmVxdWVzdGVkIGZlYXR1cmUgaXMgbm90IGtub3duLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIHZvaWQgc2V0RmVhdHVyZShTdHJpbmcgZmVhdHVyZUlkLCBib29sZWFuIHN0YXRlKQotICAgICAgICAgICAgICAgIHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIHsKLSAgICAgICAgICAgICAgICBmQ29uZmlnVXBkYXRlZCA9IHRydWU7Ci0gICAgICAgICAgICAgICAgLy8gZm9yd2FyZCB0byBldmVyeSBYTUwgMS4wIGNvbXBvbmVudAotICAgICAgICAgICAgICAgIGludCBjb3VudCA9IGZDb21wb25lbnRzLnNpemUoKTsKLSAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIFhNTENvbXBvbmVudCBjID0gKFhNTENvbXBvbmVudCkgZkNvbXBvbmVudHMuZ2V0KGkpOwotICAgICAgICAgICAgICAgICAgICAgICAgYy5zZXRGZWF0dXJlKGZlYXR1cmVJZCwgc3RhdGUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvLyBmb3J3YXJkIGl0IHRvIGNvbW1vbiBjb21wb25lbnRzCi0gICAgICAgICAgICAgICAgY291bnQgPSBmQ29tbW9uQ29tcG9uZW50cy5zaXplKCk7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBYTUxDb21wb25lbnQgYyA9IChYTUxDb21wb25lbnQpIGZDb21tb25Db21wb25lbnRzLmdldChpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGMuc2V0RmVhdHVyZShmZWF0dXJlSWQsIHN0YXRlKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyBmb3J3YXJkIHRvIGV2ZXJ5IFhNTCAxLjEgY29tcG9uZW50Ci0gICAgICAgICAgICAgICAgY291bnQgPSBmWE1MMTFDb21wb25lbnRzLnNpemUoKTsKLSAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIFhNTENvbXBvbmVudCBjID0gKFhNTENvbXBvbmVudCkgZlhNTDExQ29tcG9uZW50cy5nZXQoaSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB0cnl7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMuc2V0RmVhdHVyZShmZWF0dXJlSWQsIHN0YXRlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGNhdGNoIChFeGNlcHRpb24gZSl7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG5vIG9wCi0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIC8vIHNhdmUgc3RhdGUgaWYgbm9vbmUgIm9iamVjdHMiCi0gICAgICAgICAgICAgICAgc3VwZXIuc2V0RmVhdHVyZShmZWF0dXJlSWQsIHN0YXRlKTsKLQotICAgICAgICB9IC8vIHNldEZlYXR1cmUoU3RyaW5nLGJvb2xlYW4pCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIHNldFByb3BlcnR5Ci0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBwcm9wZXJ0eUlkCi0gICAgICAgICAqIEBwYXJhbSB2YWx1ZQotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIHZvaWQgc2V0UHJvcGVydHkoU3RyaW5nIHByb3BlcnR5SWQsIE9iamVjdCB2YWx1ZSkKLSAgICAgICAgICAgICAgICB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICAgICAgZkNvbmZpZ1VwZGF0ZWQgPSB0cnVlOwotICAgICAgICAgICAgICAgIC8vIGZvcndhcmQgdG8gZXZlcnkgWE1MIDEuMCBjb21wb25lbnQKLSAgICAgICAgICAgICAgICBpbnQgY291bnQgPSBmQ29tcG9uZW50cy5zaXplKCk7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBYTUxDb21wb25lbnQgYyA9IChYTUxDb21wb25lbnQpIGZDb21wb25lbnRzLmdldChpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGMuc2V0UHJvcGVydHkocHJvcGVydHlJZCwgdmFsdWUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvLyBmb3J3YXJkIGl0IHRvIGV2ZXJ5IGNvbW1vbiBDb21wb25lbnQKLSAgICAgICAgICAgICAgICBjb3VudCA9IGZDb21tb25Db21wb25lbnRzLnNpemUoKTsKLSAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIFhNTENvbXBvbmVudCBjID0gKFhNTENvbXBvbmVudCkgZkNvbW1vbkNvbXBvbmVudHMuZ2V0KGkpOwotICAgICAgICAgICAgICAgICAgICAgICAgYy5zZXRQcm9wZXJ0eShwcm9wZXJ0eUlkLCB2YWx1ZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIC8vIGZvcndhcmQgaXQgdG8gZXZlcnkgWE1MIDEuMSBjb21wb25lbnQKLSAgICAgICAgICAgICAgICBjb3VudCA9IGZYTUwxMUNvbXBvbmVudHMuc2l6ZSgpOwotICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykgewotICAgICAgICAgICAgICAgICAgICAgICAgWE1MQ29tcG9uZW50IGMgPSAoWE1MQ29tcG9uZW50KSBmWE1MMTFDb21wb25lbnRzLmdldChpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHRyeXsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYy5zZXRQcm9wZXJ0eShwcm9wZXJ0eUlkLCB2YWx1ZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGUpewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpZ25vcmUgaXQKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyBzdG9yZSB2YWx1ZSBpZiBub29uZSAib2JqZWN0cyIKLSAgICAgICAgICAgICAgICBzdXBlci5zZXRQcm9wZXJ0eShwcm9wZXJ0eUlkLCB2YWx1ZSk7Ci0KLSAgICAgICAgfSAvLyBzZXRQcm9wZXJ0eShTdHJpbmcsT2JqZWN0KQotCi0KLSAgICAgICAgLyoqIFJldHVybnMgdGhlIGxvY2FsZS4gKi8KLSAgICAgICAgcHVibGljIExvY2FsZSBnZXRMb2NhbGUoKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZMb2NhbGU7Ci0gICAgICAgIH0gLy8gZ2V0TG9jYWxlKCk6TG9jYWxlCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIHJlc2V0IGFsbCBYTUwgMS4wIGNvbXBvbmVudHMgYmVmb3JlIHBhcnNpbmcgYW5kIG5hbWVzcGFjZSBjb250ZXh0Ci0gICAgICAgICAqLwotICAgICAgICBwcm90ZWN0ZWQgdm9pZCByZXNldCgpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICAgICAgICAgIGludCBjb3VudCA9IGZDb21wb25lbnRzLnNpemUoKTsKLSAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIFhNTENvbXBvbmVudCBjID0gKFhNTENvbXBvbmVudCkgZkNvbXBvbmVudHMuZ2V0KGkpOwotICAgICAgICAgICAgICAgICAgICAgICAgYy5yZXNldCh0aGlzKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgfSAvLyByZXNldCgpCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIHJlc2V0IGFsbCBjb21tb24gY29tcG9uZW50cyBiZWZvcmUgcGFyc2luZwotICAgICAgICAgKi8KLSAgICAgICAgcHJvdGVjdGVkIHZvaWQgcmVzZXRDb21tb24oKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgICAgICAgICAvLyByZXNldCBjb21tb24gY29tcG9uZW50cwotICAgICAgICAgICAgICAgIGludCBjb3VudCA9IGZDb21tb25Db21wb25lbnRzLnNpemUoKTsKLSAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIFhNTENvbXBvbmVudCBjID0gKFhNTENvbXBvbmVudCkgZkNvbW1vbkNvbXBvbmVudHMuZ2V0KGkpOwotICAgICAgICAgICAgICAgICAgICAgICAgYy5yZXNldCh0aGlzKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgfSAvLyByZXNldENvbW1vbigpCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIHJlc2V0IGFsbCBjb21wb25lbnRzIGJlZm9yZSBwYXJzaW5nIGFuZCBuYW1lc3BhY2UgY29udGV4dAotICAgICAgICAgKi8KLSAgICAgICAgcHJvdGVjdGVkIHZvaWQgcmVzZXRYTUwxMSgpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICAgICAgICAgIC8vIHJlc2V0IGV2ZXJ5IGNvbXBvbmVudAotICAgICAgICAgICAgICAgIGludCBjb3VudCA9IGZYTUwxMUNvbXBvbmVudHMuc2l6ZSgpOwotICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykgewotICAgICAgICAgICAgICAgICAgICAgICAgWE1MQ29tcG9uZW50IGMgPSAoWE1MQ29tcG9uZW50KSBmWE1MMTFDb21wb25lbnRzLmdldChpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGMucmVzZXQodGhpcyk7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgIH0gLy8gcmVzZXRYTUwxMSgpCi0KLSAgICAvKioKLSAgICAgKiAgQ29uZmlndXJlcyB0aGUgWE1MIDEuMSBwaXBlbGluZS4KLSAgICAgKiAgTm90ZTogdGhpcyBtZXRob2QgYWxzbyByZXNldHMgdGhlIG5ldyBYTUwxMSBjb21wb25lbnRzLgotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIGNvbmZpZ3VyZVhNTDExUGlwZWxpbmUoKSB7Ci0gICAgICAgIGlmIChmQ3VycmVudERWRmFjdG9yeSAhPSBmWE1MMTFEYXRhdHlwZUZhY3RvcnkpIHsKLSAgICAgICAgICAgIGZDdXJyZW50RFZGYWN0b3J5ID0gZlhNTDExRGF0YXR5cGVGYWN0b3J5OwotICAgICAgICAgICAgc2V0UHJvcGVydHkoREFUQVRZUEVfVkFMSURBVE9SX0ZBQ1RPUlksIGZDdXJyZW50RFZGYWN0b3J5KTsKLSAgICAgICAgfQotICAgICAgICBpZiAoZkN1cnJlbnREVERTY2FubmVyICE9IGZYTUwxMURURFNjYW5uZXIpIHsKLSAgICAgICAgICAgIGZDdXJyZW50RFREU2Nhbm5lciA9IGZYTUwxMURURFNjYW5uZXI7Ci0gICAgICAgICAgICBzZXRQcm9wZXJ0eShEVERfU0NBTk5FUiwgZkN1cnJlbnREVERTY2FubmVyKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHNldFByb3BlcnR5KERURF9QUk9DRVNTT1IsIGZYTUwxMURURFByb2Nlc3Nvcik7Ci0gICAgICAgIH0KLQotICAgICAgICBmWE1MMTFEVERTY2FubmVyLnNldERUREhhbmRsZXIoZlhNTDExRFREUHJvY2Vzc29yKTsKLSAgICAgICAgZlhNTDExRFREUHJvY2Vzc29yLnNldERURFNvdXJjZShmWE1MMTFEVERTY2FubmVyKTsKLSAgICAgICAgZlhNTDExRFREUHJvY2Vzc29yLnNldERUREhhbmRsZXIoZkRUREhhbmRsZXIpOwotICAgICAgICBpZiAoZkRUREhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkRUREhhbmRsZXIuc2V0RFREU291cmNlKGZYTUwxMURURFByb2Nlc3Nvcik7Ci0gICAgICAgIH0KLQotICAgICAgICBmWE1MMTFEVERTY2FubmVyLnNldERURENvbnRlbnRNb2RlbEhhbmRsZXIoZlhNTDExRFREUHJvY2Vzc29yKTsKLSAgICAgICAgZlhNTDExRFREUHJvY2Vzc29yLnNldERURENvbnRlbnRNb2RlbFNvdXJjZShmWE1MMTFEVERTY2FubmVyKTsKLSAgICAgICAgZlhNTDExRFREUHJvY2Vzc29yLnNldERURENvbnRlbnRNb2RlbEhhbmRsZXIoZkRURENvbnRlbnRNb2RlbEhhbmRsZXIpOwotICAgICAgICBpZiAoZkRURENvbnRlbnRNb2RlbEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkRURENvbnRlbnRNb2RlbEhhbmRsZXIuc2V0RFREQ29udGVudE1vZGVsU291cmNlKGZYTUwxMURURFByb2Nlc3Nvcik7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBzZXR1cCBYTUwgMS4xIGRvY3VtZW50IHBpcGVsaW5lCi0gICAgICAgIGlmIChmRmVhdHVyZXMuZ2V0KE5BTUVTUEFDRVMpID09IEJvb2xlYW4uVFJVRSkgewotICAgICAgICAgICAgaWYgKGZDdXJyZW50U2Nhbm5lciAhPSBmWE1MMTFOU0RvY1NjYW5uZXIpIHsKLSAgICAgICAgICAgICAgICBmQ3VycmVudFNjYW5uZXIgPSBmWE1MMTFOU0RvY1NjYW5uZXI7Ci0gICAgICAgICAgICAgICAgc2V0UHJvcGVydHkoRE9DVU1FTlRfU0NBTk5FUiwgZlhNTDExTlNEb2NTY2FubmVyKTsKLSAgICAgICAgICAgICAgICBzZXRQcm9wZXJ0eShEVERfVkFMSURBVE9SLCBmWE1MMTFOU0RURFZhbGlkYXRvcik7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGZYTUwxMU5TRG9jU2Nhbm5lci5zZXREVERWYWxpZGF0b3IoZlhNTDExTlNEVERWYWxpZGF0b3IpOwotICAgICAgICAgICAgZlhNTDExTlNEb2NTY2FubmVyLnNldERvY3VtZW50SGFuZGxlcihmWE1MMTFOU0RURFZhbGlkYXRvcik7Ci0gICAgICAgICAgICBmWE1MMTFOU0RURFZhbGlkYXRvci5zZXREb2N1bWVudFNvdXJjZShmWE1MMTFOU0RvY1NjYW5uZXIpOwotICAgICAgICAgICAgZlhNTDExTlNEVERWYWxpZGF0b3Iuc2V0RG9jdW1lbnRIYW5kbGVyKGZEb2N1bWVudEhhbmRsZXIpOwotCi0gICAgICAgICAgICBpZiAoZkRvY3VtZW50SGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci5zZXREb2N1bWVudFNvdXJjZShmWE1MMTFOU0RURFZhbGlkYXRvcik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmTGFzdENvbXBvbmVudCA9IGZYTUwxMU5TRFREVmFsaWRhdG9yOwotCi0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBjcmVhdGUgY29tcG9uZW50cwotICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZlhNTDExRG9jU2Nhbm5lciA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbm9uIG5hbWVzcGFjZSBkb2N1bWVudCBwaXBlbGluZQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZYTUwxMURvY1NjYW5uZXIgPSBuZXcgWE1MMTFEb2N1bWVudFNjYW5uZXJJbXBsKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkWE1MMTFDb21wb25lbnQoZlhNTDExRG9jU2Nhbm5lcik7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZlhNTDExRFREVmFsaWRhdG9yID0gbmV3IFhNTDExRFREVmFsaWRhdG9yKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkWE1MMTFDb21wb25lbnQoZlhNTDExRFREVmFsaWRhdG9yKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKGZDdXJyZW50U2Nhbm5lciAhPSBmWE1MMTFEb2NTY2FubmVyKSB7Ci0gICAgICAgICAgICAgICAgZkN1cnJlbnRTY2FubmVyID0gZlhNTDExRG9jU2Nhbm5lcjsKLSAgICAgICAgICAgICAgICBzZXRQcm9wZXJ0eShET0NVTUVOVF9TQ0FOTkVSLCBmWE1MMTFEb2NTY2FubmVyKTsKLSAgICAgICAgICAgICAgICBzZXRQcm9wZXJ0eShEVERfVkFMSURBVE9SLCBmWE1MMTFEVERWYWxpZGF0b3IpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZlhNTDExRG9jU2Nhbm5lci5zZXREb2N1bWVudEhhbmRsZXIoZlhNTDExRFREVmFsaWRhdG9yKTsKLSAgICAgICAgICAgIGZYTUwxMURURFZhbGlkYXRvci5zZXREb2N1bWVudFNvdXJjZShmWE1MMTFEb2NTY2FubmVyKTsKLSAgICAgICAgICAgIGZYTUwxMURURFZhbGlkYXRvci5zZXREb2N1bWVudEhhbmRsZXIoZkRvY3VtZW50SGFuZGxlcik7Ci0KLSAgICAgICAgICAgIGlmIChmRG9jdW1lbnRIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLnNldERvY3VtZW50U291cmNlKGZYTUwxMURURFZhbGlkYXRvcik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmTGFzdENvbXBvbmVudCA9IGZYTUwxMURURFZhbGlkYXRvcjsKLSAgICAgICAgfQotCi0gICAgfSAvLyBjb25maWd1cmVYTUwxMVBpcGVsaW5lKCkKLQotICAgIC8qKiBDb25maWd1cmVzIHRoZSBwaXBlbGluZS4gKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCBjb25maWd1cmVQaXBlbGluZSgpIHsKLSAgICAgICAgaWYgKGZDdXJyZW50RFZGYWN0b3J5ICE9IGZEYXRhdHlwZVZhbGlkYXRvckZhY3RvcnkpIHsKLSAgICAgICAgICAgIGZDdXJyZW50RFZGYWN0b3J5ID0gZkRhdGF0eXBlVmFsaWRhdG9yRmFjdG9yeTsKLSAgICAgICAgICAgIC8vIHVzZSBYTUwgMS4wIGRhdGF0eXBlIGxpYnJhcnkKLSAgICAgICAgICAgIHNldFByb3BlcnR5KERBVEFUWVBFX1ZBTElEQVRPUl9GQUNUT1JZLCBmQ3VycmVudERWRmFjdG9yeSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBzZXR1cCBEVEQgcGlwZWxpbmUKLSAgICAgICAgaWYgKGZDdXJyZW50RFREU2Nhbm5lciAhPSBmRFREU2Nhbm5lcikgewotICAgICAgICAgICAgZkN1cnJlbnREVERTY2FubmVyID0gZkRURFNjYW5uZXI7Ci0gICAgICAgICAgICBzZXRQcm9wZXJ0eShEVERfU0NBTk5FUiwgZkN1cnJlbnREVERTY2FubmVyKTsKLSAgICAgICAgICAgIHNldFByb3BlcnR5KERURF9QUk9DRVNTT1IsIGZEVERQcm9jZXNzb3IpOwotICAgICAgICB9Ci0gICAgICAgIGZEVERTY2FubmVyLnNldERUREhhbmRsZXIoZkRURFByb2Nlc3Nvcik7Ci0gICAgICAgIGZEVERQcm9jZXNzb3Iuc2V0RFREU291cmNlKGZEVERTY2FubmVyKTsKLSAgICAgICAgZkRURFByb2Nlc3Nvci5zZXREVERIYW5kbGVyKGZEVERIYW5kbGVyKTsKLSAgICAgICAgaWYgKGZEVERIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZEVERIYW5kbGVyLnNldERURFNvdXJjZShmRFREUHJvY2Vzc29yKTsKLSAgICAgICAgfQotCi0gICAgICAgIGZEVERTY2FubmVyLnNldERURENvbnRlbnRNb2RlbEhhbmRsZXIoZkRURFByb2Nlc3Nvcik7Ci0gICAgICAgIGZEVERQcm9jZXNzb3Iuc2V0RFREQ29udGVudE1vZGVsU291cmNlKGZEVERTY2FubmVyKTsKLSAgICAgICAgZkRURFByb2Nlc3Nvci5zZXREVERDb250ZW50TW9kZWxIYW5kbGVyKGZEVERDb250ZW50TW9kZWxIYW5kbGVyKTsKLSAgICAgICAgaWYgKGZEVERDb250ZW50TW9kZWxIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZEVERDb250ZW50TW9kZWxIYW5kbGVyLnNldERURENvbnRlbnRNb2RlbFNvdXJjZShmRFREUHJvY2Vzc29yKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIHNldHVwIGRvY3VtZW50IHBpcGVsaW5lCi0gICAgICAgIGlmIChmRmVhdHVyZXMuZ2V0KE5BTUVTUEFDRVMpID09IEJvb2xlYW4uVFJVRSkgewotICAgICAgICAgICAgaWYgKGZDdXJyZW50U2Nhbm5lciAhPSBmTmFtZXNwYWNlU2Nhbm5lcikgewotICAgICAgICAgICAgICAgIGZDdXJyZW50U2Nhbm5lciA9IGZOYW1lc3BhY2VTY2FubmVyOwotICAgICAgICAgICAgICAgIHNldFByb3BlcnR5KERPQ1VNRU5UX1NDQU5ORVIsIGZOYW1lc3BhY2VTY2FubmVyKTsKLSAgICAgICAgICAgICAgICBzZXRQcm9wZXJ0eShEVERfVkFMSURBVE9SLCBmRFREVmFsaWRhdG9yKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGZOYW1lc3BhY2VTY2FubmVyLnNldERURFZhbGlkYXRvcihmRFREVmFsaWRhdG9yKTsKLSAgICAgICAgICAgIGZOYW1lc3BhY2VTY2FubmVyLnNldERvY3VtZW50SGFuZGxlcihmRFREVmFsaWRhdG9yKTsKLSAgICAgICAgICAgIGZEVERWYWxpZGF0b3Iuc2V0RG9jdW1lbnRTb3VyY2UoZk5hbWVzcGFjZVNjYW5uZXIpOwotICAgICAgICAgICAgZkRURFZhbGlkYXRvci5zZXREb2N1bWVudEhhbmRsZXIoZkRvY3VtZW50SGFuZGxlcik7Ci0gICAgICAgICAgICBpZiAoZkRvY3VtZW50SGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci5zZXREb2N1bWVudFNvdXJjZShmRFREVmFsaWRhdG9yKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGZMYXN0Q29tcG9uZW50ID0gZkRURFZhbGlkYXRvcjsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIC8vIGNyZWF0ZSBjb21wb25lbnRzCi0gICAgICAgICAgICBpZiAoZk5vbk5TU2Nhbm5lciA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZk5vbk5TU2Nhbm5lciA9IG5ldyBYTUxEb2N1bWVudFNjYW5uZXJJbXBsKCk7Ci0gICAgICAgICAgICAgICAgZk5vbk5TRFREVmFsaWRhdG9yID0gbmV3IFhNTERURFZhbGlkYXRvcigpOwotICAgICAgICAgICAgICAgIC8vIGFkZCBjb21wb25lbnRzCi0gICAgICAgICAgICAgICAgYWRkQ29tcG9uZW50KChYTUxDb21wb25lbnQpIGZOb25OU1NjYW5uZXIpOwotICAgICAgICAgICAgICAgIGFkZENvbXBvbmVudCgoWE1MQ29tcG9uZW50KSBmTm9uTlNEVERWYWxpZGF0b3IpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKGZDdXJyZW50U2Nhbm5lciAhPSBmTm9uTlNTY2FubmVyKSB7Ci0gICAgICAgICAgICAgICAgZkN1cnJlbnRTY2FubmVyID0gZk5vbk5TU2Nhbm5lcjsKLSAgICAgICAgICAgICAgICBzZXRQcm9wZXJ0eShET0NVTUVOVF9TQ0FOTkVSLCBmTm9uTlNTY2FubmVyKTsKLSAgICAgICAgICAgICAgICBzZXRQcm9wZXJ0eShEVERfVkFMSURBVE9SLCBmTm9uTlNEVERWYWxpZGF0b3IpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBmTm9uTlNTY2FubmVyLnNldERvY3VtZW50SGFuZGxlcihmTm9uTlNEVERWYWxpZGF0b3IpOwotICAgICAgICAgICAgZk5vbk5TRFREVmFsaWRhdG9yLnNldERvY3VtZW50U291cmNlKGZOb25OU1NjYW5uZXIpOwotICAgICAgICAgICAgZk5vbk5TRFREVmFsaWRhdG9yLnNldERvY3VtZW50SGFuZGxlcihmRG9jdW1lbnRIYW5kbGVyKTsKLSAgICAgICAgICAgIGlmIChmRG9jdW1lbnRIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLnNldERvY3VtZW50U291cmNlKGZOb25OU0RURFZhbGlkYXRvcik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmTGFzdENvbXBvbmVudCA9IGZOb25OU0RURFZhbGlkYXRvcjsKLSAgICAgICAgfQotCi0gICAgfSAvLyBjb25maWd1cmVQaXBlbGluZSgpCi0KLQotICAgIC8vIGZlYXR1cmVzIGFuZCBwcm9wZXJ0aWVzCi0KLSAgICAvKioKLSAgICAgKiBDaGVjayBhIGZlYXR1cmUuIElmIGZlYXR1cmUgaXMga25vdyBhbmQgc3VwcG9ydGVkLCB0aGlzIG1ldGhvZCBzaW1wbHkKLSAgICAgKiByZXR1cm5zLiBPdGhlcndpc2UsIHRoZSBhcHByb3ByaWF0ZSBleGNlcHRpb24gaXMgdGhyb3duLgotICAgICAqCi0gICAgICogQHBhcmFtIGZlYXR1cmVJZCBUaGUgdW5pcXVlIGlkZW50aWZpZXIgKFVSSSkgb2YgdGhlIGZlYXR1cmUuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gVGhyb3duIGZvciBjb25maWd1cmF0aW9uIGVycm9yLgotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbiBnZW5lcmFsLCBjb21wb25lbnRzIHNob3VsZAotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbmx5IHRocm93IHRoaXMgZXhjZXB0aW9uIGlmCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0IGlzIDxzdHJvbmc+cmVhbGx5PC9zdHJvbmc+Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGEgY3JpdGljYWwgZXJyb3IuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIEZlYXR1cmVTdGF0ZSBjaGVja0ZlYXR1cmUoU3RyaW5nIGZlYXR1cmVJZCkgdGhyb3dzIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gewotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIFhlcmNlcyBGZWF0dXJlcwotICAgICAgICAvLwotCi0gICAgICAgIGlmIChmZWF0dXJlSWQuc3RhcnRzV2l0aChDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYKSkgewotICAgICAgICAgICAgZmluYWwgaW50IHN1ZmZpeExlbmd0aCA9IGZlYXR1cmVJZC5sZW5ndGgoKSAtIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVgubGVuZ3RoKCk7Ci0KLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAvLyBodHRwOi8vYXBhY2hlLm9yZy94bWwvZmVhdHVyZXMvdmFsaWRhdGlvbi9keW5hbWljCi0gICAgICAgICAgICAvLyAgIEFsbG93cyB0aGUgcGFyc2VyIHRvIHZhbGlkYXRlIGEgZG9jdW1lbnQgb25seSB3aGVuIGl0Ci0gICAgICAgICAgICAvLyAgIGNvbnRhaW5zIGEgZ3JhbW1hci4gVmFsaWRhdGlvbiBpcyB0dXJuZWQgb24vb2ZmIGJhc2VkCi0gICAgICAgICAgICAvLyAgIG9uIGVhY2ggZG9jdW1lbnQgaW5zdGFuY2UsIGF1dG9tYXRpY2FsbHkuCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgaWYgKHN1ZmZpeExlbmd0aCA9PSBDb25zdGFudHMuRFlOQU1JQ19WQUxJREFUSU9OX0ZFQVRVUkUubGVuZ3RoKCkgJiYKLSAgICAgICAgICAgICAgICBmZWF0dXJlSWQuZW5kc1dpdGgoQ29uc3RhbnRzLkRZTkFNSUNfVkFMSURBVElPTl9GRUFUVVJFKSkgewotICAgICAgICAgICAgICAgIHJldHVybiBGZWF0dXJlU3RhdGUuUkVDT0dOSVpFRDsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIC8vIGh0dHA6Ly9hcGFjaGUub3JnL3htbC9mZWF0dXJlcy92YWxpZGF0aW9uL2RlZmF1bHQtYXR0cmlidXRlLXZhbHVlcwotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIGlmIChzdWZmaXhMZW5ndGggPT0gQ29uc3RhbnRzLkRFRkFVTFRfQVRUUklCVVRFX1ZBTFVFU19GRUFUVVJFLmxlbmd0aCgpICYmCi0gICAgICAgICAgICAgICAgZmVhdHVyZUlkLmVuZHNXaXRoKENvbnN0YW50cy5ERUZBVUxUX0FUVFJJQlVURV9WQUxVRVNfRkVBVFVSRSkpIHsKLSAgICAgICAgICAgICAgICAvLyBSRVZJU0lUCi0gICAgICAgICAgICAgICAgcmV0dXJuIEZlYXR1cmVTdGF0ZS5OT1RfU1VQUE9SVEVEOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIC8vIGh0dHA6Ly9hcGFjaGUub3JnL3htbC9mZWF0dXJlcy92YWxpZGF0aW9uL2RlZmF1bHQtYXR0cmlidXRlLXZhbHVlcwotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIGlmIChzdWZmaXhMZW5ndGggPT0gQ29uc3RhbnRzLlZBTElEQVRFX0NPTlRFTlRfTU9ERUxTX0ZFQVRVUkUubGVuZ3RoKCkgJiYKLSAgICAgICAgICAgICAgICBmZWF0dXJlSWQuZW5kc1dpdGgoQ29uc3RhbnRzLlZBTElEQVRFX0NPTlRFTlRfTU9ERUxTX0ZFQVRVUkUpKSB7Ci0gICAgICAgICAgICAgICAgLy8gUkVWSVNJVAotICAgICAgICAgICAgICAgIHJldHVybiBGZWF0dXJlU3RhdGUuTk9UX1NVUFBPUlRFRDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAvLyBodHRwOi8vYXBhY2hlLm9yZy94bWwvZmVhdHVyZXMvdmFsaWRhdGlvbi9ub252YWxpZGF0aW5nL2xvYWQtZHRkLWdyYW1tYXIKLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICBpZiAoc3VmZml4TGVuZ3RoID09IENvbnN0YW50cy5MT0FEX0RURF9HUkFNTUFSX0ZFQVRVUkUubGVuZ3RoKCkgJiYKLSAgICAgICAgICAgICAgICBmZWF0dXJlSWQuZW5kc1dpdGgoQ29uc3RhbnRzLkxPQURfRFREX0dSQU1NQVJfRkVBVFVSRSkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gRmVhdHVyZVN0YXRlLlJFQ09HTklaRUQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLwotICAgICAgICAgICAgLy8gaHR0cDovL2FwYWNoZS5vcmcveG1sL2ZlYXR1cmVzL3ZhbGlkYXRpb24vbm9udmFsaWRhdGluZy9sb2FkLWV4dGVybmFsLWR0ZAotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIGlmIChzdWZmaXhMZW5ndGggPT0gQ29uc3RhbnRzLkxPQURfRVhURVJOQUxfRFREX0ZFQVRVUkUubGVuZ3RoKCkgJiYKLSAgICAgICAgICAgICAgICBmZWF0dXJlSWQuZW5kc1dpdGgoQ29uc3RhbnRzLkxPQURfRVhURVJOQUxfRFREX0ZFQVRVUkUpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIEZlYXR1cmVTdGF0ZS5SRUNPR05JWkVEOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgLy8gaHR0cDovL2FwYWNoZS5vcmcveG1sL2ZlYXR1cmVzL3ZhbGlkYXRpb24vZGVmYXVsdC1hdHRyaWJ1dGUtdmFsdWVzCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgaWYgKHN1ZmZpeExlbmd0aCA9PSBDb25zdGFudHMuVkFMSURBVEVfREFUQVRZUEVTX0ZFQVRVUkUubGVuZ3RoKCkgJiYKLSAgICAgICAgICAgICAgICBmZWF0dXJlSWQuZW5kc1dpdGgoQ29uc3RhbnRzLlZBTElEQVRFX0RBVEFUWVBFU19GRUFUVVJFKSkgewotICAgICAgICAgICAgICAgIHJldHVybiBGZWF0dXJlU3RhdGUuTk9UX1NVUFBPUlRFRDsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gc3BlY2lhbCBwZXJmb3JtYW5jZSBmZWF0dXJlOiBvbmx5IGNvbXBvbmVudCBtYW5hZ2VyIGlzIGFsbG93ZWQgdG8gc2V0IGl0LgotICAgICAgICAgICAgaWYgKHN1ZmZpeExlbmd0aCA9PSBDb25zdGFudHMuUEFSU0VSX1NFVFRJTkdTLmxlbmd0aCgpICYmCi0gICAgICAgICAgICAgICAgZmVhdHVyZUlkLmVuZHNXaXRoKENvbnN0YW50cy5QQVJTRVJfU0VUVElOR1MpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIEZlYXR1cmVTdGF0ZS5OT1RfU1VQUE9SVEVEOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gTm90IHJlY29nbml6ZWQKLSAgICAgICAgLy8KLQotICAgICAgICByZXR1cm4gc3VwZXIuY2hlY2tGZWF0dXJlKGZlYXR1cmVJZCk7Ci0KLSAgICB9IC8vIGNoZWNrRmVhdHVyZShTdHJpbmcpCi0KLSAgICAvKioKLSAgICAgKiBDaGVjayBhIHByb3BlcnR5LiBJZiB0aGUgcHJvcGVydHkgaXMga25vdyBhbmQgc3VwcG9ydGVkLCB0aGlzIG1ldGhvZAotICAgICAqIHNpbXBseSByZXR1cm5zLiBPdGhlcndpc2UsIHRoZSBhcHByb3ByaWF0ZSBleGNlcHRpb24gaXMgdGhyb3duLgotICAgICAqCi0gICAgICogQHBhcmFtIHByb3BlcnR5SWQgVGhlIHVuaXF1ZSBpZGVudGlmaWVyIChVUkkpIG9mIHRoZSBwcm9wZXJ0eQotICAgICAqICAgICAgICAgICAgICAgICAgIGJlaW5nIHNldC4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBUaHJvd24gZm9yIGNvbmZpZ3VyYXRpb24gZXJyb3IuCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluIGdlbmVyYWwsIGNvbXBvbmVudHMgc2hvdWxkCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9ubHkgdGhyb3cgdGhpcyBleGNlcHRpb24gaWYKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXQgaXMgPHN0cm9uZz5yZWFsbHk8L3N0cm9uZz4KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYSBjcml0aWNhbCBlcnJvci4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgUHJvcGVydHlTdGF0ZSBjaGVja1Byb3BlcnR5KFN0cmluZyBwcm9wZXJ0eUlkKSB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gWGVyY2VzIFByb3BlcnRpZXMKLSAgICAgICAgLy8KLQotICAgICAgICBpZiAocHJvcGVydHlJZC5zdGFydHNXaXRoKENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYKSkgewotICAgICAgICAgICAgZmluYWwgaW50IHN1ZmZpeExlbmd0aCA9IHByb3BlcnR5SWQubGVuZ3RoKCkgLSBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWC5sZW5ndGgoKTsKLQotICAgICAgICAgICAgaWYgKHN1ZmZpeExlbmd0aCA9PSBDb25zdGFudHMuRFREX1NDQU5ORVJfUFJPUEVSVFkubGVuZ3RoKCkgJiYKLSAgICAgICAgICAgICAgICBwcm9wZXJ0eUlkLmVuZHNXaXRoKENvbnN0YW50cy5EVERfU0NBTk5FUl9QUk9QRVJUWSkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gUHJvcGVydHlTdGF0ZS5SRUNPR05JWkVEOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gc3BlY2lhbCBjYXNlcwotICAgICAgICBpZiAocHJvcGVydHlJZC5zdGFydHNXaXRoKENvbnN0YW50cy5TQVhfUFJPUEVSVFlfUFJFRklYKSkgewotICAgICAgICAgICAgZmluYWwgaW50IHN1ZmZpeExlbmd0aCA9IHByb3BlcnR5SWQubGVuZ3RoKCkgLSBDb25zdGFudHMuU0FYX1BST1BFUlRZX1BSRUZJWC5sZW5ndGgoKTsKLQotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIC8vIGh0dHA6Ly94bWwub3JnL3NheC9wcm9wZXJ0aWVzL3htbC1zdHJpbmcKLSAgICAgICAgICAgIC8vIFZhbHVlIHR5cGU6IFN0cmluZwotICAgICAgICAgICAgLy8gQWNjZXNzOiByZWFkLW9ubHkKLSAgICAgICAgICAgIC8vICAgR2V0IHRoZSBsaXRlcmFsIHN0cmluZyBvZiBjaGFyYWN0ZXJzIGFzc29jaWF0ZWQgd2l0aCB0aGUKLSAgICAgICAgICAgIC8vICAgY3VycmVudCBldmVudC4gIElmIHRoZSBwYXJzZXIgcmVjb2duaXNlcyBhbmQgc3VwcG9ydHMgdGhpcwotICAgICAgICAgICAgLy8gICBwcm9wZXJ0eSBidXQgaXMgbm90IGN1cnJlbnRseSBwYXJzaW5nIHRleHQsIGl0IHNob3VsZCByZXR1cm4KLSAgICAgICAgICAgIC8vICAgbnVsbCAodGhpcyBpcyBhIGdvb2Qgd2F5IHRvIGNoZWNrIGZvciBhdmFpbGFiaWxpdHkgYmVmb3JlIHRoZQotICAgICAgICAgICAgLy8gICBwYXJzZSBiZWdpbnMpLgotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIGlmIChzdWZmaXhMZW5ndGggPT0gQ29uc3RhbnRzLlhNTF9TVFJJTkdfUFJPUEVSVFkubGVuZ3RoKCkgJiYKLSAgICAgICAgICAgICAgICBwcm9wZXJ0eUlkLmVuZHNXaXRoKENvbnN0YW50cy5YTUxfU1RSSU5HX1BST1BFUlRZKSkgewotICAgICAgICAgICAgICAgIC8vIFJFVklTSVQgLSB3ZSBzaG91bGQgcHJvYmFibHkgYXNrIHhtbC1kZXYgZm9yIGEgcHJlY2lzZQotICAgICAgICAgICAgICAgIC8vIGRlZmluaXRpb24gb2Ygd2hhdCB0aGlzIGlzIGFjdHVhbGx5IHN1cHBvc2VkIHRvIHJldHVybiwgYW5kCi0gICAgICAgICAgICAgICAgLy8gaW4gZXhhY3RseSB3aGljaCBjaXJjdW1zdGFuY2VzLgotICAgICAgICAgICAgICAgIHJldHVybiBQcm9wZXJ0eVN0YXRlLk5PVF9TVVBQT1JURUQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLwotICAgICAgICAvLyBOb3QgcmVjb2duaXplZAotICAgICAgICAvLwotCi0gICAgICAgIHJldHVybiBzdXBlci5jaGVja1Byb3BlcnR5KHByb3BlcnR5SWQpOwotCi0gICAgfSAvLyBjaGVja1Byb3BlcnR5KFN0cmluZykKLQotCi0gICAgLyoqCi0gICAgICogQWRkcyBhIGNvbXBvbmVudCB0byB0aGUgcGFyc2VyIGNvbmZpZ3VyYXRpb24uIFRoaXMgbWV0aG9kIHdpbGwKLSAgICAgKiBhbHNvIGFkZCBhbGwgb2YgdGhlIGNvbXBvbmVudCdzIHJlY29nbml6ZWQgZmVhdHVyZXMgYW5kIHByb3BlcnRpZXMKLSAgICAgKiB0byB0aGUgbGlzdCBvZiBkZWZhdWx0IHJlY29nbml6ZWQgZmVhdHVyZXMgYW5kIHByb3BlcnRpZXMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29tcG9uZW50IFRoZSBjb21wb25lbnQgdG8gYWRkLgotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIGFkZENvbXBvbmVudChYTUxDb21wb25lbnQgY29tcG9uZW50KSB7Ci0KLSAgICAgICAgLy8gZG9uJ3QgYWRkIGEgY29tcG9uZW50IG1vcmUgdGhhbiBvbmNlCi0gICAgICAgIGlmIChmQ29tcG9uZW50cy5jb250YWlucyhjb21wb25lbnQpKSB7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLSAgICAgICAgZkNvbXBvbmVudHMuYWRkKGNvbXBvbmVudCk7Ci0gICAgICAgIGFkZFJlY29nbml6ZWRQYXJhbXNBbmRTZXREZWZhdWx0cyhjb21wb25lbnQpOwotCi0gICAgfSAvLyBhZGRDb21wb25lbnQoWE1MQ29tcG9uZW50KQotCi0gICAgLyoqCi0gICAgICogQWRkcyBjb21tb24gY29tcG9uZW50IHRvIHRoZSBwYXJzZXIgY29uZmlndXJhdGlvbi4gVGhpcyBtZXRob2Qgd2lsbAotICAgICAqIGFsc28gYWRkIGFsbCBvZiB0aGUgY29tcG9uZW50J3MgcmVjb2duaXplZCBmZWF0dXJlcyBhbmQgcHJvcGVydGllcwotICAgICAqIHRvIHRoZSBsaXN0IG9mIGRlZmF1bHQgcmVjb2duaXplZCBmZWF0dXJlcyBhbmQgcHJvcGVydGllcy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjb21wb25lbnQgVGhlIGNvbXBvbmVudCB0byBhZGQuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgYWRkQ29tbW9uQ29tcG9uZW50KFhNTENvbXBvbmVudCBjb21wb25lbnQpIHsKLQotICAgICAgICAvLyBkb24ndCBhZGQgYSBjb21wb25lbnQgbW9yZSB0aGFuIG9uY2UKLSAgICAgICAgaWYgKGZDb21tb25Db21wb25lbnRzLmNvbnRhaW5zKGNvbXBvbmVudCkpIHsKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotICAgICAgICBmQ29tbW9uQ29tcG9uZW50cy5hZGQoY29tcG9uZW50KTsKLSAgICAgICAgYWRkUmVjb2duaXplZFBhcmFtc0FuZFNldERlZmF1bHRzKGNvbXBvbmVudCk7Ci0KLSAgICB9IC8vIGFkZENvbW1vbkNvbXBvbmVudChYTUxDb21wb25lbnQpCi0KLSAgICAvKioKLSAgICAgKiBBZGRzIGFuIFhNTCAxLjEgY29tcG9uZW50IHRvIHRoZSBwYXJzZXIgY29uZmlndXJhdGlvbi4gVGhpcyBtZXRob2Qgd2lsbAotICAgICAqIGFsc28gYWRkIGFsbCBvZiB0aGUgY29tcG9uZW50J3MgcmVjb2duaXplZCBmZWF0dXJlcyBhbmQgcHJvcGVydGllcwotICAgICAqIHRvIHRoZSBsaXN0IG9mIGRlZmF1bHQgcmVjb2duaXplZCBmZWF0dXJlcyBhbmQgcHJvcGVydGllcy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjb21wb25lbnQgVGhlIGNvbXBvbmVudCB0byBhZGQuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgYWRkWE1MMTFDb21wb25lbnQoWE1MQ29tcG9uZW50IGNvbXBvbmVudCkgewotCi0gICAgICAgIC8vIGRvbid0IGFkZCBhIGNvbXBvbmVudCBtb3JlIHRoYW4gb25jZQotICAgICAgICBpZiAoZlhNTDExQ29tcG9uZW50cy5jb250YWlucyhjb21wb25lbnQpKSB7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLSAgICAgICAgZlhNTDExQ29tcG9uZW50cy5hZGQoY29tcG9uZW50KTsKLSAgICAgICAgYWRkUmVjb2duaXplZFBhcmFtc0FuZFNldERlZmF1bHRzKGNvbXBvbmVudCk7Ci0KLSAgICB9IC8vIGFkZFhNTDExQ29tcG9uZW50KFhNTENvbXBvbmVudCkKLQotICAgIC8qKgotICAgICAqIEFkZHMgYWxsIG9mIHRoZSBjb21wb25lbnQncyByZWNvZ25pemVkIGZlYXR1cmVzIGFuZCBwcm9wZXJ0aWVzCi0gICAgICogdG8gdGhlIGxpc3Qgb2YgZGVmYXVsdCByZWNvZ25pemVkIGZlYXR1cmVzIGFuZCBwcm9wZXJ0aWVzLCBhbmQKLSAgICAgKiBzZXRzIGRlZmF1bHQgdmFsdWVzIG9uIHRoZSBjb25maWd1cmF0aW9uIGZvciBmZWF0dXJlcyBhbmQKLSAgICAgKiBwcm9wZXJ0aWVzIHdoaWNoIHdlcmUgcHJldmlvdXNseSBhYnNlbnQgZnJvbSB0aGUgY29uZmlndXJhdGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjb21wb25lbnQgVGhlIGNvbXBvbmVudCB3aG9zZSByZWNvZ25pemVkIGZlYXR1cmVzCi0gICAgICogYW5kIHByb3BlcnRpZXMgd2lsbCBiZSBhZGRlZCB0byB0aGUgY29uZmlndXJhdGlvbgotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIGFkZFJlY29nbml6ZWRQYXJhbXNBbmRTZXREZWZhdWx0cyhYTUxDb21wb25lbnQgY29tcG9uZW50KSB7Ci0KLSAgICAgICAgLy8gcmVnaXN0ZXIgY29tcG9uZW50J3MgcmVjb2duaXplZCBmZWF0dXJlcwotICAgICAgICBTdHJpbmdbXSByZWNvZ25pemVkRmVhdHVyZXMgPSBjb21wb25lbnQuZ2V0UmVjb2duaXplZEZlYXR1cmVzKCk7Ci0gICAgICAgIGFkZFJlY29nbml6ZWRGZWF0dXJlcyhyZWNvZ25pemVkRmVhdHVyZXMpOwotCi0gICAgICAgIC8vIHJlZ2lzdGVyIGNvbXBvbmVudCdzIHJlY29nbml6ZWQgcHJvcGVydGllcwotICAgICAgICBTdHJpbmdbXSByZWNvZ25pemVkUHJvcGVydGllcyA9IGNvbXBvbmVudC5nZXRSZWNvZ25pemVkUHJvcGVydGllcygpOwotICAgICAgICBhZGRSZWNvZ25pemVkUHJvcGVydGllcyhyZWNvZ25pemVkUHJvcGVydGllcyk7Ci0KLSAgICAgICAgLy8gc2V0IGRlZmF1bHQgdmFsdWVzCi0gICAgICAgIGlmIChyZWNvZ25pemVkRmVhdHVyZXMgIT0gbnVsbCkgewotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZWNvZ25pemVkRmVhdHVyZXMubGVuZ3RoOyArK2kpIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgZmVhdHVyZUlkID0gcmVjb2duaXplZEZlYXR1cmVzW2ldOwotICAgICAgICAgICAgICAgIEJvb2xlYW4gc3RhdGUgPSBjb21wb25lbnQuZ2V0RmVhdHVyZURlZmF1bHQoZmVhdHVyZUlkKTsKLSAgICAgICAgICAgICAgICBpZiAoc3RhdGUgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAvLyBEbyBub3Qgb3ZlcndyaXRlIHZhbHVlcyBhbHJlYWR5IHNldCBvbiB0aGUgY29uZmlndXJhdGlvbi4KLSAgICAgICAgICAgICAgICAgICAgaWYgKCFmRmVhdHVyZXMuY29udGFpbnNLZXkoZmVhdHVyZUlkKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgZkZlYXR1cmVzLnB1dChmZWF0dXJlSWQsIHN0YXRlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIEZvciBuZXdseSBhZGRlZCBjb21wb25lbnRzIHdobyByZWNvZ25pemUgdGhpcyBmZWF0dXJlCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBidXQgZGlkIG5vdCBvZmZlciBhIGRlZmF1bHQgdmFsdWUsIHdlIG5lZWQgdG8gbWFrZQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gc3VyZSB0aGVzZSBjb21wb25lbnRzIHdpbGwgZ2V0IGFuIG9wcG9ydHVuaXR5IHRvIHJlYWQKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoZSB2YWx1ZSBiZWZvcmUgcGFyc2luZyBiZWdpbnMuCi0gICAgICAgICAgICAgICAgICAgICAgICBmQ29uZmlnVXBkYXRlZCA9IHRydWU7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKHJlY29nbml6ZWRQcm9wZXJ0aWVzICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVjb2duaXplZFByb3BlcnRpZXMubGVuZ3RoOyArK2kpIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgcHJvcGVydHlJZCA9IHJlY29nbml6ZWRQcm9wZXJ0aWVzW2ldOwotICAgICAgICAgICAgICAgIE9iamVjdCB2YWx1ZSA9IGNvbXBvbmVudC5nZXRQcm9wZXJ0eURlZmF1bHQocHJvcGVydHlJZCk7Ci0gICAgICAgICAgICAgICAgaWYgKHZhbHVlICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gRG8gbm90IG92ZXJ3cml0ZSB2YWx1ZXMgYWxyZWFkeSBzZXQgb24gdGhlIGNvbmZpZ3VyYXRpb24uCi0gICAgICAgICAgICAgICAgICAgIGlmICghZlByb3BlcnRpZXMuY29udGFpbnNLZXkocHJvcGVydHlJZCkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZQcm9wZXJ0aWVzLnB1dChwcm9wZXJ0eUlkLCB2YWx1ZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBGb3IgbmV3bHkgYWRkZWQgY29tcG9uZW50cyB3aG8gcmVjb2duaXplIHRoaXMgcHJvcGVydHkKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGJ1dCBkaWQgbm90IG9mZmVyIGEgZGVmYXVsdCB2YWx1ZSwgd2UgbmVlZCB0byBtYWtlCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBzdXJlIHRoZXNlIGNvbXBvbmVudHMgd2lsbCBnZXQgYW4gb3Bwb3J0dW5pdHkgdG8gcmVhZAotICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhlIHZhbHVlIGJlZm9yZSBwYXJzaW5nIGJlZ2lucy4KLSAgICAgICAgICAgICAgICAgICAgICAgIGZDb25maWdVcGRhdGVkID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBpbml0WE1MMTFDb21wb25lbnRzKCkgewotICAgICAgICBpZiAoIWYxMUluaXRpYWxpemVkKSB7Ci0KLSAgICAgICAgICAgIC8vIGNyZWF0ZSBkYXRhdHlwZSBmYWN0b3J5Ci0gICAgICAgICAgICBmWE1MMTFEYXRhdHlwZUZhY3RvcnkgPSBEVEREVkZhY3RvcnkuZ2V0SW5zdGFuY2UoWE1MMTFfREFUQVRZUEVfVkFMSURBVE9SX0ZBQ1RPUlkpOwotCi0gICAgICAgICAgICAvLyBzZXR1cCBYTUwgMS4xIERURCBwaXBlbGluZQotICAgICAgICAgICAgZlhNTDExRFREU2Nhbm5lciA9IG5ldyBYTUwxMURURFNjYW5uZXJJbXBsKCk7Ci0gICAgICAgICAgICBhZGRYTUwxMUNvbXBvbmVudChmWE1MMTFEVERTY2FubmVyKTsKLSAgICAgICAgICAgIGZYTUwxMURURFByb2Nlc3NvciA9IG5ldyBYTUwxMURURFByb2Nlc3NvcigpOwotICAgICAgICAgICAgYWRkWE1MMTFDb21wb25lbnQoZlhNTDExRFREUHJvY2Vzc29yKTsKLQotICAgICAgICAgICAgLy8gc2V0dXAgWE1MIDEuMS4gZG9jdW1lbnQgcGlwZWxpbmUgLSBuYW1lc3BhY2UgYXdhcmUKLSAgICAgICAgICAgIGZYTUwxMU5TRG9jU2Nhbm5lciA9IG5ldyBYTUwxMU5TRG9jdW1lbnRTY2FubmVySW1wbCgpOwotICAgICAgICAgICAgYWRkWE1MMTFDb21wb25lbnQoZlhNTDExTlNEb2NTY2FubmVyKTsKLSAgICAgICAgICAgIGZYTUwxMU5TRFREVmFsaWRhdG9yID0gbmV3IFhNTDExTlNEVERWYWxpZGF0b3IoKTsKLSAgICAgICAgICAgIGFkZFhNTDExQ29tcG9uZW50KGZYTUwxMU5TRFREVmFsaWRhdG9yKTsKLQotICAgICAgICAgICAgZjExSW5pdGlhbGl6ZWQgPSB0cnVlOwotICAgICAgICB9Ci0gICAgfQotCi19IC8vIGNsYXNzIFhNTDExRFREQ29uZmlndXJhdGlvbgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvcGFyc2Vycy9YTUwxMU5vblZhbGlkYXRpbmdDb25maWd1cmF0aW9uLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9wYXJzZXJzL1hNTDExTm9uVmFsaWRhdGluZ0NvbmZpZ3VyYXRpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNDNmODczMC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9wYXJzZXJzL1hNTDExTm9uVmFsaWRhdGluZ0NvbmZpZ3VyYXRpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEyMzAgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5wYXJzZXJzOwotCi1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwotaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwotaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5YTUwxMURURFNjYW5uZXJJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5YTUwxMURvY3VtZW50U2Nhbm5lckltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLlhNTDExTlNEb2N1bWVudFNjYW5uZXJJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5YTUxEVERTY2FubmVySW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuWE1MRG9jdW1lbnRTY2FubmVySW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuWE1MRW50aXR5SGFuZGxlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuWE1MRW50aXR5TWFuYWdlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuWE1MRXJyb3JSZXBvcnRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuWE1MTlNEb2N1bWVudFNjYW5uZXJJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5YTUxWZXJzaW9uRGV0ZWN0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LkRURERWRmFjdG9yeTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwubXNnLlhNTE1lc3NhZ2VGb3JtYXR0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnZhbGlkYXRpb24uVmFsaWRhdGlvbk1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLkZlYXR1cmVTdGF0ZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuUGFyc2VyQ29uZmlndXJhdGlvblNldHRpbmdzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5Qcm9wZXJ0eVN0YXRlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5TdGF0dXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlN5bWJvbFRhYmxlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTERURENvbnRlbnRNb2RlbEhhbmRsZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MRFRESGFuZGxlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxEb2N1bWVudEhhbmRsZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MTG9jYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTklFeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuZ3JhbW1hcnMuWE1MR3JhbW1hclBvb2w7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTENvbXBvbmVudDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MQ29tcG9uZW50TWFuYWdlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MRFREU2Nhbm5lcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MRG9jdW1lbnRTY2FubmVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxEb2N1bWVudFNvdXJjZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MRW50aXR5UmVzb2x2ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTEVycm9ySGFuZGxlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MSW5wdXRTb3VyY2U7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTFB1bGxQYXJzZXJDb25maWd1cmF0aW9uOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgaXMgdGhlIG5vbiB2bGFpZGF0aW5nIHBhcnNlciBjb25maWd1cmF0aW9uCi0gKiB1c2VkIHRvIHBhcnNlIFhNTCAxLjAgYW5kIFhNTCAxLjEgZG9jdW1lbnRzLgotICoKLSAqIFhlcmNlcyBwYXJzZXIgdGhhdCB1c2VzIHRoaXMgY29uZmlndXJhdGlvbiBpcyA8c3Ryb25nPm5vdDwvc3Ryb25nPiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMteG1sI3NlYy1jb25mb3JtYW5jZSI+Y29uZm9ybWFudDwvYT4KLSAqIG5vbi12YWxpZGF0aW5nIFhNTCBwcm9jZXNzb3IsIHNpbmNlIGNvbmZvcm1hbnQgbm9uLXZhbGlkYXRpbmcgcHJvY2Vzc29yIGlzIHJlcXVpcmVkCi0gKiB0byBwcm9jZXNzICJhbGwgdGhlIGRlY2xhcmF0aW9ucyB0aGV5IHJlYWQgaW4gdGhlIGludGVybmFsIERURCBzdWJzZXQgLi4uIG11c3QgdXNlIHRoZSBpbmZvcm1hdGlvbiBpbiB0aG9zZSBkZWNsYXJhdGlvbnMgdG8gbm9ybWFsaXplIGF0dHJpYnV0ZSB2YWx1ZXMsCi0gKiBpbmNsdWRlIHRoZSByZXBsYWNlbWVudCB0ZXh0IG9mIGludGVybmFsIGVudGl0aWVzLCBhbmQgc3VwcGx5IGRlZmF1bHQgYXR0cmlidXRlIHZhbHVlcyIuCi0KLSAqIEBhdXRob3IgRWxlbmEgTGl0YW5pLCBJQk0KLSAqIEBhdXRob3IgSm9obiBLaW0sIElCTQotICogQGF1dGhvciBNaWNoYWVsIEdsYXZhc3NldmljaCwgSUJNCi0gKgotICogQHZlcnNpb24gJElkOiBYTUwxMU5vblZhbGlkYXRpbmdDb25maWd1cmF0aW9uLmphdmEsdiAxLjUgMjAxMC0xMS0wMSAwNDo0MDoxMCBqb2VodyBFeHAgJAotICovCi1wdWJsaWMgY2xhc3MgWE1MMTFOb25WYWxpZGF0aW5nQ29uZmlndXJhdGlvbiBleHRlbmRzIFBhcnNlckNvbmZpZ3VyYXRpb25TZXR0aW5ncwotICAgIGltcGxlbWVudHMgWE1MUHVsbFBhcnNlckNvbmZpZ3VyYXRpb24sIFhNTDExQ29uZmlndXJhYmxlIHsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RhbnRzCi0gICAgLy8KLSAgICBwcm90ZWN0ZWQgZmluYWwgc3RhdGljIFN0cmluZyBYTUwxMV9EQVRBVFlQRV9WQUxJREFUT1JfRkFDVE9SWSA9Ci0gICAgICAgICJjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYuZHRkLlhNTDExRFRERFZGYWN0b3J5SW1wbCI7Ci0KLSAgICAvLyBmZWF0dXJlIGlkZW50aWZpZXJzCi0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiB2YWxpZGF0aW9uLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFZBTElEQVRJT04gPQotICAgICAgICBDb25zdGFudHMuU0FYX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLlZBTElEQVRJT05fRkVBVFVSRTsKLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IG5hbWVzcGFjZXMuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgTkFNRVNQQUNFUyA9Ci0gICAgICAgIENvbnN0YW50cy5TQVhfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuTkFNRVNQQUNFU19GRUFUVVJFOwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogZXh0ZXJuYWwgZ2VuZXJhbCBlbnRpdGllcy4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBFWFRFUk5BTF9HRU5FUkFMX0VOVElUSUVTID0KLSAgICAgICAgQ29uc3RhbnRzLlNBWF9GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5FWFRFUk5BTF9HRU5FUkFMX0VOVElUSUVTX0ZFQVRVUkU7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiBleHRlcm5hbCBwYXJhbWV0ZXIgZW50aXRpZXMuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVhURVJOQUxfUEFSQU1FVEVSX0VOVElUSUVTID0KLSAgICAgICAgQ29uc3RhbnRzLlNBWF9GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5FWFRFUk5BTF9QQVJBTUVURVJfRU5USVRJRVNfRkVBVFVSRTsKLQotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogY29udGludWUgYWZ0ZXIgZmF0YWwgZXJyb3IuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ09OVElOVUVfQUZURVJfRkFUQUxfRVJST1IgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLkNPTlRJTlVFX0FGVEVSX0ZBVEFMX0VSUk9SX0ZFQVRVUkU7Ci0KLQotICAgIC8vIHByb3BlcnR5IGlkZW50aWZpZXJzCi0KLSAgICAgICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IHhtbCBzdHJpbmcuICovCi0gICAgICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFhNTF9TVFJJTkcgPQotICAgICAgICAgICAgICAgIENvbnN0YW50cy5TQVhfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLlhNTF9TVFJJTkdfUFJPUEVSVFk7Ci0KLSAgICAgICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IHN5bWJvbCB0YWJsZS4gKi8KLSAgICAgICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1lNQk9MX1RBQkxFID0KLSAgICAgICAgICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5TWU1CT0xfVEFCTEVfUFJPUEVSVFk7Ci0KLSAgICAgICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IGVycm9yIGhhbmRsZXIuICovCi0gICAgICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUk9SX0hBTkRMRVIgPQotICAgICAgICAgICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLkVSUk9SX0hBTkRMRVJfUFJPUEVSVFk7Ci0KLSAgICAgICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IGVudGl0eSByZXNvbHZlci4gKi8KLSAgICAgICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgRU5USVRZX1JFU09MVkVSID0KLSAgICAgICAgICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5FTlRJVFlfUkVTT0xWRVJfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogZXJyb3IgcmVwb3J0ZXIuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJST1JfUkVQT1JURVIgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5FUlJPUl9SRVBPUlRFUl9QUk9QRVJUWTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBlbnRpdHkgbWFuYWdlci4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBFTlRJVFlfTUFOQUdFUiA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLkVOVElUWV9NQU5BR0VSX1BST1BFUlRZOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXIgZG9jdW1lbnQgc2Nhbm5lcjogKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBET0NVTUVOVF9TQ0FOTkVSID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuRE9DVU1FTlRfU0NBTk5FUl9QUk9QRVJUWTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBEVEQgc2Nhbm5lci4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBEVERfU0NBTk5FUiA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLkRURF9TQ0FOTkVSX1BST1BFUlRZOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IGdyYW1tYXIgcG9vbC4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxHUkFNTUFSX1BPT0wgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5YTUxHUkFNTUFSX1BPT0xfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogRFREIHZhbGlkYXRvci4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBEVERfVkFMSURBVE9SID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuRFREX1ZBTElEQVRPUl9QUk9QRVJUWTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBuYW1lc3BhY2UgYmluZGVyLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIE5BTUVTUEFDRV9CSU5ERVIgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5OQU1FU1BBQ0VfQklOREVSX1BST1BFUlRZOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IGRhdGF0eXBlIHZhbGlkYXRvciBmYWN0b3J5LiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIERBVEFUWVBFX1ZBTElEQVRPUl9GQUNUT1JZID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuREFUQVRZUEVfVkFMSURBVE9SX0ZBQ1RPUllfUFJPUEVSVFk7Ci0KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBWQUxJREFUSU9OX01BTkFHRVIgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5WQUxJREFUSU9OX01BTkFHRVJfUFJPUEVSVFk7Ci0KLSAgICAvLyBkZWJ1Z2dpbmcKLQotICAgIC8qKiBTZXQgdG8gdHJ1ZSBhbmQgcmVjb21waWxlIHRvIHByaW50IGV4Y2VwdGlvbiBzdGFjayB0cmFjZS4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGJvb2xlYW4gUFJJTlRfRVhDRVBUSU9OX1NUQUNLX1RSQUNFID0gZmFsc2U7Ci0KLSAgICAvLwotICAgIC8vIERhdGEKLSAgICAvLwotICAgIHByb3RlY3RlZCBTeW1ib2xUYWJsZSBmU3ltYm9sVGFibGU7Ci0gICAgcHJvdGVjdGVkIFhNTElucHV0U291cmNlIGZJbnB1dFNvdXJjZTsKLSAgICBwcm90ZWN0ZWQgVmFsaWRhdGlvbk1hbmFnZXIgZlZhbGlkYXRpb25NYW5hZ2VyOwotICAgIHByb3RlY3RlZCBYTUxWZXJzaW9uRGV0ZWN0b3IgZlZlcnNpb25EZXRlY3RvcjsKLSAgICBwcm90ZWN0ZWQgWE1MTG9jYXRvciBmTG9jYXRvcjsKLSAgICBwcm90ZWN0ZWQgTG9jYWxlIGZMb2NhbGU7Ci0KLSAgICAvKiogWE1MIDEuMCBDb21wb25lbnRzLiAqLwotICAgIHByb3RlY3RlZCBBcnJheUxpc3QgZkNvbXBvbmVudHM7Ci0KLSAgICAvKiogWE1MIDEuMS4gQ29tcG9uZW50cy4gKi8KLSAgICBwcm90ZWN0ZWQgQXJyYXlMaXN0IGZYTUwxMUNvbXBvbmVudHMgPSBudWxsOwotCi0gICAgLyoqIENvbW1vbiBjb21wb25lbnRzOiBYTUxFbnRpdHlNYW5hZ2VyLCBYTUxFcnJvclJlcG9ydGVyICovCi0gICAgcHJvdGVjdGVkIEFycmF5TGlzdCBmQ29tbW9uQ29tcG9uZW50cyA9IG51bGw7Ci0KLSAgICAvKiogVGhlIGRvY3VtZW50IGhhbmRsZXIuICovCi0gICAgcHJvdGVjdGVkIFhNTERvY3VtZW50SGFuZGxlciBmRG9jdW1lbnRIYW5kbGVyOwotCi0gICAgLyoqIFRoZSBEVEQgaGFuZGxlci4gKi8KLSAgICBwcm90ZWN0ZWQgWE1MRFRESGFuZGxlciBmRFRESGFuZGxlcjsKLQotICAgIC8qKiBUaGUgRFREIGNvbnRlbnQgbW9kZWwgaGFuZGxlci4gKi8KLSAgICBwcm90ZWN0ZWQgWE1MRFREQ29udGVudE1vZGVsSGFuZGxlciBmRFREQ29udGVudE1vZGVsSGFuZGxlcjsKLQotICAgIC8qKiBMYXN0IGNvbXBvbmVudCBpbiB0aGUgZG9jdW1lbnQgcGlwZWxpbmUgKi8KLSAgICBwcm90ZWN0ZWQgWE1MRG9jdW1lbnRTb3VyY2UgZkxhc3RDb21wb25lbnQ7Ci0KLSAgICAvKioKLSAgICAgKiBUcnVlIGlmIGEgcGFyc2UgaXMgaW4gcHJvZ3Jlc3MuIFRoaXMgc3RhdGUgaXMgbmVlZGVkIGJlY2F1c2UKLSAgICAgKiBzb21lIGZlYXR1cmVzL3Byb3BlcnRpZXMgY2Fubm90IGJlIHNldCB3aGlsZSBwYXJzaW5nIChlLmcuCi0gICAgICogbmFtZXNwYWNlcykuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZlBhcnNlSW5Qcm9ncmVzcyA9IGZhbHNlOwotCi0gICAgLyoqIGZDb25maWdVcGRhdGVkIGlzIHNldCB0byB0cnVlIGlmIHRoZXJlIGhhcyBiZWVuIGFueSBjaGFuZ2UgdG8gdGhlIGNvbmZpZ3VyYXRpb24gc2V0dGluZ3MsCi0gICAgICogaS5lIGEgZmVhdHVyZSBvciBhIHByb3BlcnR5IHdhcyBjaGFuZ2VkLgotICAgICAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIGZDb25maWdVcGRhdGVkID0gZmFsc2U7Ci0KLSAgICAvLwotICAgIC8vIFhNTCAxLjAgY29tcG9uZW50cwotICAgIC8vCi0KLSAgICAvKiogVGhlIFhNTCAxLjAgRGF0YXR5cGUgdmFsaWRhdG9yIGZhY3RvcnkuICovCi0gICAgcHJvdGVjdGVkIERURERWRmFjdG9yeSBmRGF0YXR5cGVWYWxpZGF0b3JGYWN0b3J5OwotCi0gICAgLyoqIFRoZSBYTUwgMS4wIERvY3VtZW50IHNjYW5uZXIgdGhhdCBkb2VzIG5hbWVzcGFjZSBiaW5kaW5nLiAqLwotICAgIHByb3RlY3RlZCBYTUxOU0RvY3VtZW50U2Nhbm5lckltcGwgZk5hbWVzcGFjZVNjYW5uZXI7Ci0KLSAgICAvKiogVGhlIFhNTCAxLjAgTm9uLW5hbWVzcGFjZSBpbXBsZW1lbnRhdGlvbiBvZiBzY2FubmVyICovCi0gICAgcHJvdGVjdGVkIFhNTERvY3VtZW50U2Nhbm5lckltcGwgZk5vbk5TU2Nhbm5lcjsKLQotICAgIC8qKiBUaGUgWE1MIDEuMCBEVEQgc2Nhbm5lci4gKi8KLSAgICBwcm90ZWN0ZWQgWE1MRFREU2Nhbm5lciBmRFREU2Nhbm5lcjsKLQotICAgIC8vCi0gICAgLy8gWE1MIDEuMSBjb21wb25lbnRzCi0gICAgLy8KLQotICAgIC8qKiBUaGUgWE1MIDEuMSBkYXRhdHlwZSBmYWN0b3J5LiAqKi8KLSAgICBwcm90ZWN0ZWQgRFRERFZGYWN0b3J5IGZYTUwxMURhdGF0eXBlRmFjdG9yeSA9IG51bGw7Ci0KLSAgICAvKiogVGhlIFhNTCAxLjEgZG9jdW1lbnQgc2Nhbm5lciB0aGF0IGRvZXMgbmFtZXNwYWNlIGJpbmRpbmcuICoqLwotICAgIHByb3RlY3RlZCBYTUwxMU5TRG9jdW1lbnRTY2FubmVySW1wbCBmWE1MMTFOU0RvY1NjYW5uZXIgPSBudWxsOwotCi0gICAgLyoqIFRoZSBYTUwgMS4xIGRvY3VtZW50IHNjYW5uZXIgdGhhdCBkb2VzIG5vdCBkbyBuYW1lc3BhY2UgYmluZGluZy4gKiovCi0gICAgcHJvdGVjdGVkIFhNTDExRG9jdW1lbnRTY2FubmVySW1wbCBmWE1MMTFEb2NTY2FubmVyID0gbnVsbDsKLQotICAgIC8qKiBUaGUgWE1MIDEuMSBEVEQgc2Nhbm5lci4gKiovCi0gICAgcHJvdGVjdGVkIFhNTDExRFREU2Nhbm5lckltcGwgZlhNTDExRFREU2Nhbm5lciA9IG51bGw7Ci0KLSAgICAvLwotICAgIC8vIENvbW1vbiBjb21wb25lbnRzCi0gICAgLy8KLQotICAgIC8qKiBHcmFtbWFyIHBvb2wuICovCi0gICAgcHJvdGVjdGVkIFhNTEdyYW1tYXJQb29sIGZHcmFtbWFyUG9vbDsKLQotICAgIC8qKiBFcnJvciByZXBvcnRlci4gKi8KLSAgICBwcm90ZWN0ZWQgWE1MRXJyb3JSZXBvcnRlciBmRXJyb3JSZXBvcnRlcjsKLQotICAgIC8qKiBFbnRpdHkgbWFuYWdlci4gKi8KLSAgICBwcm90ZWN0ZWQgWE1MRW50aXR5TWFuYWdlciBmRW50aXR5TWFuYWdlcjsKLQotICAgIC8qKiBDdXJyZW50IHNjYW5uZXIgKi8KLSAgICBwcm90ZWN0ZWQgWE1MRG9jdW1lbnRTY2FubmVyIGZDdXJyZW50U2Nhbm5lcjsKLQotICAgIC8qKiBDdXJyZW50IERhdGF0eXBlIHZhbGlkYXRvciBmYWN0b3J5LiAqLwotICAgIHByb3RlY3RlZCBEVEREVkZhY3RvcnkgZkN1cnJlbnREVkZhY3Rvcnk7Ci0KLSAgICAvKiogQ3VycmVudCBEVEQgc2Nhbm5lci4gKi8KLSAgICBwcm90ZWN0ZWQgWE1MRFREU2Nhbm5lciBmQ3VycmVudERURFNjYW5uZXI7Ci0KLQotICAgIC8qKiBGbGFnIGluZGljaWF0aW5nIHdoZXRoZXIgWE1MMTEgY29tcG9uZW50cyBoYXZlIGJlZW4gaW5pdGlhbGl6ZWQuICovCi0gICAgcHJpdmF0ZSBib29sZWFuIGYxMUluaXRpYWxpemVkID0gZmFsc2U7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0cnVjdG9ycwotICAgIC8vCi0KLSAgICAvKiogRGVmYXVsdCBjb25zdHJ1Y3Rvci4gKi8KLSAgICBwdWJsaWMgWE1MMTFOb25WYWxpZGF0aW5nQ29uZmlndXJhdGlvbigpIHsKLSAgICAgICAgdGhpcyhudWxsLCBudWxsLCBudWxsKTsKLSAgICB9IC8vIDxpbml0PigpCi0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RzIGEgcGFyc2VyIGNvbmZpZ3VyYXRpb24gdXNpbmcgdGhlIHNwZWNpZmllZCBzeW1ib2wgdGFibGUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc3ltYm9sVGFibGUgVGhlIHN5bWJvbCB0YWJsZSB0byB1c2UuCi0gICAgICovCi0gICAgcHVibGljIFhNTDExTm9uVmFsaWRhdGluZ0NvbmZpZ3VyYXRpb24oU3ltYm9sVGFibGUgc3ltYm9sVGFibGUpIHsKLSAgICAgICAgdGhpcyhzeW1ib2xUYWJsZSwgbnVsbCwgbnVsbCk7Ci0gICAgfSAvLyA8aW5pdD4oU3ltYm9sVGFibGUpCi0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RzIGEgcGFyc2VyIGNvbmZpZ3VyYXRpb24gdXNpbmcgdGhlIHNwZWNpZmllZCBzeW1ib2wgdGFibGUgYW5kCi0gICAgICogZ3JhbW1hciBwb29sLgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+UkVWSVNJVDo8L3N0cm9uZz4KLSAgICAgKiBHcmFtbWFyIHBvb2wgd2lsbCBiZSB1cGRhdGVkIHdoZW4gdGhlIG5ldyB2YWxpZGF0aW9uIGVuZ2luZSBpcwotICAgICAqIGltcGxlbWVudGVkLgotICAgICAqCi0gICAgICogQHBhcmFtIHN5bWJvbFRhYmxlIFRoZSBzeW1ib2wgdGFibGUgdG8gdXNlLgotICAgICAqIEBwYXJhbSBncmFtbWFyUG9vbCBUaGUgZ3JhbW1hciBwb29sIHRvIHVzZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgWE1MMTFOb25WYWxpZGF0aW5nQ29uZmlndXJhdGlvbihTeW1ib2xUYWJsZSBzeW1ib2xUYWJsZSwgWE1MR3JhbW1hclBvb2wgZ3JhbW1hclBvb2wpIHsKLSAgICAgICAgdGhpcyhzeW1ib2xUYWJsZSwgZ3JhbW1hclBvb2wsIG51bGwpOwotICAgIH0gLy8gPGluaXQ+KFN5bWJvbFRhYmxlLFhNTEdyYW1tYXJQb29sKQotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0cyBhIHBhcnNlciBjb25maWd1cmF0aW9uIHVzaW5nIHRoZSBzcGVjaWZpZWQgc3ltYm9sIHRhYmxlLAotICAgICAqIGdyYW1tYXIgcG9vbCwgYW5kIHBhcmVudCBzZXR0aW5ncy4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPlJFVklTSVQ6PC9zdHJvbmc+Ci0gICAgICogR3JhbW1hciBwb29sIHdpbGwgYmUgdXBkYXRlZCB3aGVuIHRoZSBuZXcgdmFsaWRhdGlvbiBlbmdpbmUgaXMKLSAgICAgKiBpbXBsZW1lbnRlZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzeW1ib2xUYWJsZSAgICBUaGUgc3ltYm9sIHRhYmxlIHRvIHVzZS4KLSAgICAgKiBAcGFyYW0gZ3JhbW1hclBvb2wgICAgVGhlIGdyYW1tYXIgcG9vbCB0byB1c2UuCi0gICAgICogQHBhcmFtIHBhcmVudFNldHRpbmdzIFRoZSBwYXJlbnQgc2V0dGluZ3MuCi0gICAgICovCi0gICAgcHVibGljIFhNTDExTm9uVmFsaWRhdGluZ0NvbmZpZ3VyYXRpb24oCi0gICAgICAgIFN5bWJvbFRhYmxlIHN5bWJvbFRhYmxlLAotICAgICAgICBYTUxHcmFtbWFyUG9vbCBncmFtbWFyUG9vbCwKLSAgICAgICAgWE1MQ29tcG9uZW50TWFuYWdlciBwYXJlbnRTZXR0aW5ncykgewotCi0gICAgICAgICAgICAgICAgc3VwZXIocGFyZW50U2V0dGluZ3MpOwotCi0gICAgICAgICAgICAgICAgLy8gY3JlYXRlIGEgdmVjdG9yIHRvIGhvbGQgYWxsIHRoZSBjb21wb25lbnRzIGluIHVzZQotICAgICAgICAgICAgICAgIC8vIFhNTCAxLjAgc3BlY2lhbGl6ZWQgY29tcG9uZW50cwotICAgICAgICAgICAgICAgIGZDb21wb25lbnRzID0gbmV3IEFycmF5TGlzdCgpOwotICAgICAgICAgICAgICAgIC8vIFhNTCAxLjEgc3BlY2lhbGl6ZWQgY29tcG9uZW50cwotICAgICAgICAgICAgICAgIGZYTUwxMUNvbXBvbmVudHMgPSBuZXcgQXJyYXlMaXN0KCk7Ci0gICAgICAgICAgICAgICAgLy8gQ29tbW9uIGNvbXBvbmVudHMgZm9yIFhNTCAxLjEuIGFuZCBYTUwgMS4wCi0gICAgICAgICAgICAgICAgZkNvbW1vbkNvbXBvbmVudHMgPSBuZXcgQXJyYXlMaXN0KCk7Ci0KLSAgICAgICAgICAgICAgICAvLyBjcmVhdGUgdGFibGUgZm9yIGZlYXR1cmVzIGFuZCBwcm9wZXJ0aWVzCi0gICAgICAgICAgICAgICAgZkZlYXR1cmVzID0gbmV3IEhhc2hNYXAoKTsKLSAgICAgICAgICAgICAgICBmUHJvcGVydGllcyA9IG5ldyBIYXNoTWFwKCk7Ci0KLSAgICAgICAgLy8gYWRkIGRlZmF1bHQgcmVjb2duaXplZCBmZWF0dXJlcwotICAgICAgICBmaW5hbCBTdHJpbmdbXSByZWNvZ25pemVkRmVhdHVyZXMgPQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIENPTlRJTlVFX0FGVEVSX0ZBVEFMX0VSUk9SLCAvLyBmcm9tIFhNTERURFNjYW5uZXJJbXBsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZBTElEQVRJT04sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5BTUVTUEFDRVMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVYVEVSTkFMX0dFTkVSQUxfRU5USVRJRVMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVYVEVSTkFMX1BBUkFNRVRFUl9FTlRJVElFUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUEFSU0VSX1NFVFRJTkdTCi0gICAgICAgICAgICAgICAgICAgICAgICB9OwotICAgICAgICBhZGRSZWNvZ25pemVkRmVhdHVyZXMocmVjb2duaXplZEZlYXR1cmVzKTsKLQotICAgICAgICAgICAgICAgIC8vIHNldCBzdGF0ZSBmb3IgZGVmYXVsdCBmZWF0dXJlcwotICAgICAgICAgICAgICAgIGZGZWF0dXJlcy5wdXQoVkFMSURBVElPTiwgQm9vbGVhbi5GQUxTRSk7Ci0gICAgICAgICAgICAgICAgZkZlYXR1cmVzLnB1dChOQU1FU1BBQ0VTLCBCb29sZWFuLlRSVUUpOwotICAgICAgICAgICAgICAgIGZGZWF0dXJlcy5wdXQoRVhURVJOQUxfR0VORVJBTF9FTlRJVElFUywgQm9vbGVhbi5UUlVFKTsKLSAgICAgICAgICAgICAgICBmRmVhdHVyZXMucHV0KEVYVEVSTkFMX1BBUkFNRVRFUl9FTlRJVElFUywgQm9vbGVhbi5UUlVFKTsKLSAgICAgICAgICAgICAgICBmRmVhdHVyZXMucHV0KENPTlRJTlVFX0FGVEVSX0ZBVEFMX0VSUk9SLCBCb29sZWFuLkZBTFNFKTsKLSAgICAgICAgICAgICAgICBmRmVhdHVyZXMucHV0KFBBUlNFUl9TRVRUSU5HUywgQm9vbGVhbi5UUlVFKTsKLQotICAgICAgICAvLyBhZGQgZGVmYXVsdCByZWNvZ25pemVkIHByb3BlcnRpZXMKLSAgICAgICAgZmluYWwgU3RyaW5nW10gcmVjb2duaXplZFByb3BlcnRpZXMgPQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIFhNTF9TVFJJTkcsCi0gICAgICAgICAgICAgICAgU1lNQk9MX1RBQkxFLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFUlJPUl9IQU5ETEVSLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFTlRJVFlfUkVTT0xWRVIsCi0gICAgICAgICAgICAgICAgRVJST1JfUkVQT1JURVIsCi0gICAgICAgICAgICAgICAgRU5USVRZX01BTkFHRVIsCi0gICAgICAgICAgICAgICAgRE9DVU1FTlRfU0NBTk5FUiwKLSAgICAgICAgICAgICAgICBEVERfU0NBTk5FUiwKLSAgICAgICAgICAgICAgICBEVERfVkFMSURBVE9SLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEQVRBVFlQRV9WQUxJREFUT1JfRkFDVE9SWSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVkFMSURBVElPTl9NQU5BR0VSLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxfU1RSSU5HLAotICAgICAgICAgICAgICAgIFhNTEdSQU1NQVJfUE9PTCwgfTsKLSAgICAgICAgYWRkUmVjb2duaXplZFByb3BlcnRpZXMocmVjb2duaXplZFByb3BlcnRpZXMpOwotCi0gICAgICAgICAgICAgICAgaWYgKHN5bWJvbFRhYmxlID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHN5bWJvbFRhYmxlID0gbmV3IFN5bWJvbFRhYmxlKCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGZTeW1ib2xUYWJsZSA9IHN5bWJvbFRhYmxlOwotICAgICAgICAgICAgICAgIGZQcm9wZXJ0aWVzLnB1dChTWU1CT0xfVEFCTEUsIGZTeW1ib2xUYWJsZSk7Ci0KLSAgICAgICAgZkdyYW1tYXJQb29sID0gZ3JhbW1hclBvb2w7Ci0gICAgICAgIGlmIChmR3JhbW1hclBvb2wgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgZlByb3BlcnRpZXMucHV0KFhNTEdSQU1NQVJfUE9PTCwgZkdyYW1tYXJQb29sKTsKLSAgICAgICAgfQotCi0gICAgICAgIGZFbnRpdHlNYW5hZ2VyID0gbmV3IFhNTEVudGl0eU1hbmFnZXIoKTsKLSAgICAgICAgICAgICAgICBmUHJvcGVydGllcy5wdXQoRU5USVRZX01BTkFHRVIsIGZFbnRpdHlNYW5hZ2VyKTsKLSAgICAgICAgYWRkQ29tbW9uQ29tcG9uZW50KGZFbnRpdHlNYW5hZ2VyKTsKLQotICAgICAgICBmRXJyb3JSZXBvcnRlciA9IG5ldyBYTUxFcnJvclJlcG9ydGVyKCk7Ci0gICAgICAgIGZFcnJvclJlcG9ydGVyLnNldERvY3VtZW50TG9jYXRvcihmRW50aXR5TWFuYWdlci5nZXRFbnRpdHlTY2FubmVyKCkpOwotICAgICAgICAgICAgICAgIGZQcm9wZXJ0aWVzLnB1dChFUlJPUl9SRVBPUlRFUiwgZkVycm9yUmVwb3J0ZXIpOwotICAgICAgICBhZGRDb21tb25Db21wb25lbnQoZkVycm9yUmVwb3J0ZXIpOwotCi0gICAgICAgIGZOYW1lc3BhY2VTY2FubmVyID0gbmV3IFhNTE5TRG9jdW1lbnRTY2FubmVySW1wbCgpOwotICAgICAgICAgICAgICAgIGZQcm9wZXJ0aWVzLnB1dChET0NVTUVOVF9TQ0FOTkVSLCBmTmFtZXNwYWNlU2Nhbm5lcik7Ci0gICAgICAgIGFkZENvbXBvbmVudCgoWE1MQ29tcG9uZW50KSBmTmFtZXNwYWNlU2Nhbm5lcik7Ci0KLSAgICAgICAgZkRURFNjYW5uZXIgPSBuZXcgWE1MRFREU2Nhbm5lckltcGwoKTsKLSAgICAgICAgICAgICAgICBmUHJvcGVydGllcy5wdXQoRFREX1NDQU5ORVIsIGZEVERTY2FubmVyKTsKLSAgICAgICAgYWRkQ29tcG9uZW50KChYTUxDb21wb25lbnQpIGZEVERTY2FubmVyKTsKLQotICAgICAgICBmRGF0YXR5cGVWYWxpZGF0b3JGYWN0b3J5ID0gRFRERFZGYWN0b3J5LmdldEluc3RhbmNlKCk7Ci0gICAgICAgICAgICAgICAgZlByb3BlcnRpZXMucHV0KERBVEFUWVBFX1ZBTElEQVRPUl9GQUNUT1JZLCBmRGF0YXR5cGVWYWxpZGF0b3JGYWN0b3J5KTsKLQotICAgICAgICBmVmFsaWRhdGlvbk1hbmFnZXIgPSBuZXcgVmFsaWRhdGlvbk1hbmFnZXIoKTsKLSAgICAgICAgICAgICAgICBmUHJvcGVydGllcy5wdXQoVkFMSURBVElPTl9NQU5BR0VSLCBmVmFsaWRhdGlvbk1hbmFnZXIpOwotCi0gICAgICAgIGZWZXJzaW9uRGV0ZWN0b3IgPSBuZXcgWE1MVmVyc2lvbkRldGVjdG9yKCk7Ci0KLSAgICAgICAgLy8gYWRkIG1lc3NhZ2UgZm9ybWF0dGVycwotICAgICAgICBpZiAoZkVycm9yUmVwb3J0ZXIuZ2V0TWVzc2FnZUZvcm1hdHRlcihYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4pID09IG51bGwpIHsKLSAgICAgICAgICAgIFhNTE1lc3NhZ2VGb3JtYXR0ZXIgeG1mdCA9IG5ldyBYTUxNZXNzYWdlRm9ybWF0dGVyKCk7Ci0gICAgICAgICAgICBmRXJyb3JSZXBvcnRlci5wdXRNZXNzYWdlRm9ybWF0dGVyKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwgeG1mdCk7Ci0gICAgICAgICAgICBmRXJyb3JSZXBvcnRlci5wdXRNZXNzYWdlRm9ybWF0dGVyKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MTlNfRE9NQUlOLCB4bWZ0KTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIHNldCBsb2NhbGUKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIHNldExvY2FsZShMb2NhbGUuZ2V0RGVmYXVsdCgpKTsKLSAgICAgICAgfSBjYXRjaCAoWE5JRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIC8vIGRvIG5vdGhpbmcKLSAgICAgICAgICAgIC8vIFJFVklTSVQ6IFdoYXQgaXMgdGhlIHJpZ2h0IHRoaW5nIHRvIGRvPyAtQWMKLSAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgZkNvbmZpZ1VwZGF0ZWQgPSBmYWxzZTsKLQotICAgIH0gLy8gPGluaXQ+KFN5bWJvbFRhYmxlLFhNTEdyYW1tYXJQb29sKQotCi0gICAgLyoqCi0gICAgICogU2V0cyB0aGUgaW5wdXQgc291cmNlIGZvciB0aGUgZG9jdW1lbnQgdG8gcGFyc2UuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaW5wdXRTb3VyY2UgVGhlIGRvY3VtZW50J3MgaW5wdXQgc291cmNlLgotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIFRocm93biBpZiB0aGVyZSBpcyBhCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICBjb25maWd1cmF0aW9uIGVycm9yIHdoZW4gaW5pdGlhbGl6aW5nIHRoZQotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2VyLgotICAgICAqIEBleGNlcHRpb24gSU9FeGNlcHRpb24gVGhyb3duIG9uIEkvTyBlcnJvci4KLSAgICAgKgotICAgICAqIEBzZWUgI3BhcnNlKGJvb2xlYW4pCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0SW5wdXRTb3VyY2UoWE1MSW5wdXRTb3VyY2UgaW5wdXRTb3VyY2UpCi0gICAgICAgIHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy8gUkVWSVNJVDogdGhpcyBtZXRob2QgdXNlZCB0byByZXNldCBhbGwgdGhlIGNvbXBvbmVudHMgYW5kCi0gICAgICAgIC8vICAgICAgICAgIGNvbnN0cnVjdCB0aGUgcGlwZWxpbmUuIE5vdyByZXNldCgpIGlzIGNhbGxlZAotICAgICAgICAvLyAgICAgICAgICBpbiBwYXJzZSAoYm9vbGVhbikganVzdCBiZWZvcmUgd2UgcGFyc2UgdGhlIGRvY3VtZW50Ci0gICAgICAgIC8vICAgICAgICAgIFNob3VsZCB0aGlzIG1ldGhvZCBzdGlsbCB0aHJvdyBleGNlcHRpb25zLi4/Ci0KLSAgICAgICAgZklucHV0U291cmNlID0gaW5wdXRTb3VyY2U7Ci0KLSAgICB9IC8vIHNldElucHV0U291cmNlKFhNTElucHV0U291cmNlKQotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSBsb2NhbGUgdG8gdXNlIGZvciBtZXNzYWdlcy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBsb2NhbGUgVGhlIGxvY2FsZSBvYmplY3QgdG8gdXNlIGZvciBsb2NhbGl6YXRpb24gb2YgbWVzc2FnZXMuCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIFhOSUV4Y2VwdGlvbiBUaHJvd24gaWYgdGhlIHBhcnNlciBkb2VzIG5vdCBzdXBwb3J0IHRoZQotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIHNwZWNpZmllZCBsb2NhbGUuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0TG9jYWxlKExvY2FsZSBsb2NhbGUpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBmTG9jYWxlID0gbG9jYWxlOwotICAgICAgICBmRXJyb3JSZXBvcnRlci5zZXRMb2NhbGUobG9jYWxlKTsKLSAgICB9IC8vIHNldExvY2FsZShMb2NhbGUpCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFNldHMgdGhlIGRvY3VtZW50IGhhbmRsZXIgb24gdGhlIGxhc3QgY29tcG9uZW50IGluIHRoZSBwaXBlbGluZQotICAgICAgICAgKiB0byByZWNlaXZlIGluZm9ybWF0aW9uIGFib3V0IHRoZSBkb2N1bWVudC4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIGRvY3VtZW50SGFuZGxlciAgIFRoZSBkb2N1bWVudCBoYW5kbGVyLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIHZvaWQgc2V0RG9jdW1lbnRIYW5kbGVyKFhNTERvY3VtZW50SGFuZGxlciBkb2N1bWVudEhhbmRsZXIpIHsKLSAgICAgICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyID0gZG9jdW1lbnRIYW5kbGVyOwotICAgICAgICAgICAgICAgIGlmIChmTGFzdENvbXBvbmVudCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmTGFzdENvbXBvbmVudC5zZXREb2N1bWVudEhhbmRsZXIoZkRvY3VtZW50SGFuZGxlcik7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZkRvY3VtZW50SGFuZGxlciAhPW51bGwpewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLnNldERvY3VtZW50U291cmNlKGZMYXN0Q29tcG9uZW50KTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgIH0gLy8gc2V0RG9jdW1lbnRIYW5kbGVyKFhNTERvY3VtZW50SGFuZGxlcikKLQotICAgICAgICAvKiogUmV0dXJucyB0aGUgcmVnaXN0ZXJlZCBkb2N1bWVudCBoYW5kbGVyLiAqLwotICAgICAgICBwdWJsaWMgWE1MRG9jdW1lbnRIYW5kbGVyIGdldERvY3VtZW50SGFuZGxlcigpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZkRvY3VtZW50SGFuZGxlcjsKLSAgICAgICAgfSAvLyBnZXREb2N1bWVudEhhbmRsZXIoKTpYTUxEb2N1bWVudEhhbmRsZXIKLQotICAgICAgICAvKioKLSAgICAgICAgICogU2V0cyB0aGUgRFREIGhhbmRsZXIuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBkdGRIYW5kbGVyIFRoZSBEVEQgaGFuZGxlci4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyB2b2lkIHNldERUREhhbmRsZXIoWE1MRFRESGFuZGxlciBkdGRIYW5kbGVyKSB7Ci0gICAgICAgICAgICAgICAgZkRUREhhbmRsZXIgPSBkdGRIYW5kbGVyOwotICAgICAgICB9IC8vIHNldERUREhhbmRsZXIoWE1MRFRESGFuZGxlcikKLQotICAgICAgICAvKiogUmV0dXJucyB0aGUgcmVnaXN0ZXJlZCBEVEQgaGFuZGxlci4gKi8KLSAgICAgICAgcHVibGljIFhNTERUREhhbmRsZXIgZ2V0RFRESGFuZGxlcigpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZkRUREhhbmRsZXI7Ci0gICAgICAgIH0gLy8gZ2V0RFRESGFuZGxlcigpOlhNTERUREhhbmRsZXIKLQotICAgICAgICAvKioKLSAgICAgICAgICogU2V0cyB0aGUgRFREIGNvbnRlbnQgbW9kZWwgaGFuZGxlci4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIGhhbmRsZXIgVGhlIERURCBjb250ZW50IG1vZGVsIGhhbmRsZXIuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgdm9pZCBzZXREVERDb250ZW50TW9kZWxIYW5kbGVyKFhNTERURENvbnRlbnRNb2RlbEhhbmRsZXIgaGFuZGxlcikgewotICAgICAgICAgICAgICAgIGZEVERDb250ZW50TW9kZWxIYW5kbGVyID0gaGFuZGxlcjsKLSAgICAgICAgfSAvLyBzZXREVERDb250ZW50TW9kZWxIYW5kbGVyKFhNTERURENvbnRlbnRNb2RlbEhhbmRsZXIpCi0KLSAgICAgICAgLyoqIFJldHVybnMgdGhlIHJlZ2lzdGVyZWQgRFREIGNvbnRlbnQgbW9kZWwgaGFuZGxlci4gKi8KLSAgICAgICAgcHVibGljIFhNTERURENvbnRlbnRNb2RlbEhhbmRsZXIgZ2V0RFREQ29udGVudE1vZGVsSGFuZGxlcigpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZkRURENvbnRlbnRNb2RlbEhhbmRsZXI7Ci0gICAgICAgIH0gLy8gZ2V0RFREQ29udGVudE1vZGVsSGFuZGxlcigpOlhNTERURENvbnRlbnRNb2RlbEhhbmRsZXIKLQotICAgICAgICAvKioKLSAgICAgICAgICogU2V0cyB0aGUgcmVzb2x2ZXIgdXNlZCB0byByZXNvbHZlIGV4dGVybmFsIGVudGl0aWVzLiBUaGUgRW50aXR5UmVzb2x2ZXIKLSAgICAgICAgICogaW50ZXJmYWNlIHN1cHBvcnRzIHJlc29sdXRpb24gb2YgcHVibGljIGFuZCBzeXN0ZW0gaWRlbnRpZmllcnMuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSByZXNvbHZlciBUaGUgbmV3IGVudGl0eSByZXNvbHZlci4gUGFzc2luZyBhIG51bGwgdmFsdWUgd2lsbAotICAgICAgICAgKiAgICAgICAgICAgICAgICAgdW5pbnN0YWxsIHRoZSBjdXJyZW50bHkgaW5zdGFsbGVkIHJlc29sdmVyLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIHZvaWQgc2V0RW50aXR5UmVzb2x2ZXIoWE1MRW50aXR5UmVzb2x2ZXIgcmVzb2x2ZXIpIHsKLSAgICAgICAgICAgICAgICBmUHJvcGVydGllcy5wdXQoRU5USVRZX1JFU09MVkVSLCByZXNvbHZlcik7Ci0gICAgICAgIH0gLy8gc2V0RW50aXR5UmVzb2x2ZXIoWE1MRW50aXR5UmVzb2x2ZXIpCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFJldHVybiB0aGUgY3VycmVudCBlbnRpdHkgcmVzb2x2ZXIuCi0gICAgICAgICAqCi0gICAgICAgICAqIEByZXR1cm4gVGhlIGN1cnJlbnQgZW50aXR5IHJlc29sdmVyLCBvciBudWxsIGlmIG5vbmUKLSAgICAgICAgICogICAgICAgICBoYXMgYmVlbiByZWdpc3RlcmVkLgotICAgICAgICAgKiBAc2VlICNzZXRFbnRpdHlSZXNvbHZlcgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIFhNTEVudGl0eVJlc29sdmVyIGdldEVudGl0eVJlc29sdmVyKCkgewotICAgICAgICAgICAgICAgIHJldHVybiAoWE1MRW50aXR5UmVzb2x2ZXIpZlByb3BlcnRpZXMuZ2V0KEVOVElUWV9SRVNPTFZFUik7Ci0gICAgICAgIH0gLy8gZ2V0RW50aXR5UmVzb2x2ZXIoKTpYTUxFbnRpdHlSZXNvbHZlcgotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBBbGxvdyBhbiBhcHBsaWNhdGlvbiB0byByZWdpc3RlciBhbiBlcnJvciBldmVudCBoYW5kbGVyLgotICAgICAgICAgKgotICAgICAgICAgKiA8cD5JZiB0aGUgYXBwbGljYXRpb24gZG9lcyBub3QgcmVnaXN0ZXIgYW4gZXJyb3IgaGFuZGxlciwgYWxsCi0gICAgICAgICAqIGVycm9yIGV2ZW50cyByZXBvcnRlZCBieSB0aGUgU0FYIHBhcnNlciB3aWxsIGJlIHNpbGVudGx5Ci0gICAgICAgICAqIGlnbm9yZWQ7IGhvd2V2ZXIsIG5vcm1hbCBwcm9jZXNzaW5nIG1heSBub3QgY29udGludWUuICBJdCBpcwotICAgICAgICAgKiBoaWdobHkgcmVjb21tZW5kZWQgdGhhdCBhbGwgU0FYIGFwcGxpY2F0aW9ucyBpbXBsZW1lbnQgYW4KLSAgICAgICAgICogZXJyb3IgaGFuZGxlciB0byBhdm9pZCB1bmV4cGVjdGVkIGJ1Z3MuPC9wPgotICAgICAgICAgKgotICAgICAgICAgKiA8cD5BcHBsaWNhdGlvbnMgbWF5IHJlZ2lzdGVyIGEgbmV3IG9yIGRpZmZlcmVudCBoYW5kbGVyIGluIHRoZQotICAgICAgICAgKiBtaWRkbGUgb2YgYSBwYXJzZSwgYW5kIHRoZSBTQVggcGFyc2VyIG11c3QgYmVnaW4gdXNpbmcgdGhlIG5ldwotICAgICAgICAgKiBoYW5kbGVyIGltbWVkaWF0ZWx5LjwvcD4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIGVycm9ySGFuZGxlciBUaGUgZXJyb3IgaGFuZGxlci4KLSAgICAgICAgICogQGV4Y2VwdGlvbiBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24gSWYgdGhlIGhhbmRsZXIKLSAgICAgICAgICogICAgICAgICAgICBhcmd1bWVudCBpcyBudWxsLgotICAgICAgICAgKiBAc2VlICNnZXRFcnJvckhhbmRsZXIKLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyB2b2lkIHNldEVycm9ySGFuZGxlcihYTUxFcnJvckhhbmRsZXIgZXJyb3JIYW5kbGVyKSB7Ci0gICAgICAgICAgICAgICAgZlByb3BlcnRpZXMucHV0KEVSUk9SX0hBTkRMRVIsIGVycm9ySGFuZGxlcik7Ci0gICAgICAgIH0gLy8gc2V0RXJyb3JIYW5kbGVyKFhNTEVycm9ySGFuZGxlcikKLQotICAgICAgICAvKioKLSAgICAgICAgICogUmV0dXJuIHRoZSBjdXJyZW50IGVycm9yIGhhbmRsZXIuCi0gICAgICAgICAqCi0gICAgICAgICAqIEByZXR1cm4gVGhlIGN1cnJlbnQgZXJyb3IgaGFuZGxlciwgb3IgbnVsbCBpZiBub25lCi0gICAgICAgICAqICAgICAgICAgaGFzIGJlZW4gcmVnaXN0ZXJlZC4KLSAgICAgICAgICogQHNlZSAjc2V0RXJyb3JIYW5kbGVyCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgWE1MRXJyb3JIYW5kbGVyIGdldEVycm9ySGFuZGxlcigpIHsKLSAgICAgICAgICAgICAgICAvLyBSRVZJU0lUOiBTaG91bGQgdGhpcyBiZSBhIHByb3BlcnR5PwotICAgICAgICAgICAgICAgIHJldHVybiAoWE1MRXJyb3JIYW5kbGVyKWZQcm9wZXJ0aWVzLmdldChFUlJPUl9IQU5ETEVSKTsKLSAgICAgICAgfSAvLyBnZXRFcnJvckhhbmRsZXIoKTpYTUxFcnJvckhhbmRsZXIKLQotCi0gICAgLyoqCi0gICAgICogSWYgdGhlIGFwcGxpY2F0aW9uIGRlY2lkZXMgdG8gdGVybWluYXRlIHBhcnNpbmcgYmVmb3JlIHRoZSB4bWwgZG9jdW1lbnQKLSAgICAgKiBpcyBmdWxseSBwYXJzZWQsIHRoZSBhcHBsaWNhdGlvbiBzaG91bGQgY2FsbCB0aGlzIG1ldGhvZCB0byBmcmVlIGFueQotICAgICAqIHJlc291cmNlIGFsbG9jYXRlZCBkdXJpbmcgcGFyc2luZy4gRm9yIGV4YW1wbGUsIGNsb3NlIGFsbCBvcGVuZWQgc3RyZWFtcy4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBjbGVhbnVwKCkgewotICAgICAgICBmRW50aXR5TWFuYWdlci5jbG9zZVJlYWRlcnMoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBQYXJzZXMgdGhlIHNwZWNpZmllZCBpbnB1dCBzb3VyY2UuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc291cmNlIFRoZSBpbnB1dCBzb3VyY2UuCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIFhOSUV4Y2VwdGlvbiBUaHJvd3MgZXhjZXB0aW9uIG9uIFhOSSBlcnJvci4KLSAgICAgKiBAZXhjZXB0aW9uIGphdmEuaW8uSU9FeGNlcHRpb24gVGhyb3dzIGV4Y2VwdGlvbiBvbiBpL28gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcGFyc2UoWE1MSW5wdXRTb3VyY2Ugc291cmNlKSB0aHJvd3MgWE5JRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7Ci0KLSAgICAgICAgaWYgKGZQYXJzZUluUHJvZ3Jlc3MpIHsKLSAgICAgICAgICAgIC8vIFJFVklTSVQgLSBuZWVkIHRvIGFkZCBuZXcgZXJyb3IgbWVzc2FnZQotICAgICAgICAgICAgdGhyb3cgbmV3IFhOSUV4Y2VwdGlvbigiRldLMDA1IHBhcnNlIG1heSBub3QgYmUgY2FsbGVkIHdoaWxlIHBhcnNpbmcuIik7Ci0gICAgICAgIH0KLSAgICAgICAgZlBhcnNlSW5Qcm9ncmVzcyA9IHRydWU7Ci0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIHNldElucHV0U291cmNlKHNvdXJjZSk7Ci0gICAgICAgICAgICBwYXJzZSh0cnVlKTsKLSAgICAgICAgfSBjYXRjaCAoWE5JRXhjZXB0aW9uIGV4KSB7Ci0gICAgICAgICAgICBpZiAoUFJJTlRfRVhDRVBUSU9OX1NUQUNLX1RSQUNFKQotICAgICAgICAgICAgICAgIGV4LnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgICAgICAgdGhyb3cgZXg7Ci0gICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7Ci0gICAgICAgICAgICBpZiAoUFJJTlRfRVhDRVBUSU9OX1NUQUNLX1RSQUNFKQotICAgICAgICAgICAgICAgIGV4LnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgICAgICAgdGhyb3cgZXg7Ci0gICAgICAgIH0gY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gZXgpIHsKLSAgICAgICAgICAgIGlmIChQUklOVF9FWENFUFRJT05fU1RBQ0tfVFJBQ0UpCi0gICAgICAgICAgICAgICAgZXgucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgICAgICB0aHJvdyBleDsKLSAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7Ci0gICAgICAgICAgICBpZiAoUFJJTlRfRVhDRVBUSU9OX1NUQUNLX1RSQUNFKQotICAgICAgICAgICAgICAgIGV4LnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgICAgICAgdGhyb3cgbmV3IFhOSUV4Y2VwdGlvbihleCk7Ci0gICAgICAgIH0gZmluYWxseSB7Ci0gICAgICAgICAgICBmUGFyc2VJblByb2dyZXNzID0gZmFsc2U7Ci0gICAgICAgICAgICAvLyBjbG9zZSBhbGwgc3RyZWFtcyBvcGVuZWQgYnkgeGVyY2VzCi0gICAgICAgICAgICB0aGlzLmNsZWFudXAoKTsKLSAgICAgICAgfQotCi0gICAgfSAvLyBwYXJzZShJbnB1dFNvdXJjZSkKLQotICAgIHB1YmxpYyBib29sZWFuIHBhcnNlKGJvb2xlYW4gY29tcGxldGUpIHRocm93cyBYTklFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKLSAgICAgICAgLy8KLSAgICAgICAgLy8gcmVzZXQgYW5kIGNvbmZpZ3VyZSBwaXBlbGluZSBhbmQgc2V0IElucHV0U291cmNlLgotICAgICAgICBpZiAoZklucHV0U291cmNlICE9IG51bGwpIHsKLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZWYWxpZGF0aW9uTWFuYWdlci5yZXNldCgpOwotICAgICAgICAgICAgICAgIGZWZXJzaW9uRGV0ZWN0b3IucmVzZXQodGhpcyk7Ci0gICAgICAgICAgICAgICAgcmVzZXRDb21tb24oKTsKLQotICAgICAgICAgICAgICAgIHNob3J0IHZlcnNpb24gPSBmVmVyc2lvbkRldGVjdG9yLmRldGVybWluZURvY1ZlcnNpb24oZklucHV0U291cmNlKTsKLSAgICAgICAgICAgICAgICBpZiAodmVyc2lvbiA9PSBDb25zdGFudHMuWE1MX1ZFUlNJT05fMV8xKSB7Ci0gICAgICAgICAgICAgICAgICAgIGluaXRYTUwxMUNvbXBvbmVudHMoKTsKLSAgICAgICAgICAgICAgICAgICAgY29uZmlndXJlWE1MMTFQaXBlbGluZSgpOwotICAgICAgICAgICAgICAgICAgICByZXNldFhNTDExKCk7Ci0gICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgY29uZmlndXJlUGlwZWxpbmUoKTsKLSAgICAgICAgICAgICAgICAgICAgcmVzZXQoKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyBtYXJrIGNvbmZpZ3VyYXRpb24gYXMgZml4ZWQKLSAgICAgICAgICAgICAgICBmQ29uZmlnVXBkYXRlZCA9IGZhbHNlOwotCi0gICAgICAgICAgICAgICAgLy8gcmVzZXRzIGFuZCBzZXRzIHRoZSBwaXBlbGluZS4KLSAgICAgICAgICAgICAgICBmVmVyc2lvbkRldGVjdG9yLnN0YXJ0RG9jdW1lbnRQYXJzaW5nKChYTUxFbnRpdHlIYW5kbGVyKSBmQ3VycmVudFNjYW5uZXIsIHZlcnNpb24pOwotICAgICAgICAgICAgICAgIGZJbnB1dFNvdXJjZSA9IG51bGw7Ci0gICAgICAgICAgICB9IGNhdGNoIChYTklFeGNlcHRpb24gZXgpIHsKLSAgICAgICAgICAgICAgICBpZiAoUFJJTlRfRVhDRVBUSU9OX1NUQUNLX1RSQUNFKQotICAgICAgICAgICAgICAgICAgICBleC5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgICAgICAgICAgICB0aHJvdyBleDsKLSAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7Ci0gICAgICAgICAgICAgICAgaWYgKFBSSU5UX0VYQ0VQVElPTl9TVEFDS19UUkFDRSkKLSAgICAgICAgICAgICAgICAgICAgZXgucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgICAgICAgICAgdGhyb3cgZXg7Ci0gICAgICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIGV4KSB7Ci0gICAgICAgICAgICAgICAgaWYgKFBSSU5UX0VYQ0VQVElPTl9TVEFDS19UUkFDRSkKLSAgICAgICAgICAgICAgICAgICAgZXgucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgICAgICAgICAgdGhyb3cgZXg7Ci0gICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKLSAgICAgICAgICAgICAgICBpZiAoUFJJTlRfRVhDRVBUSU9OX1NUQUNLX1RSQUNFKQotICAgICAgICAgICAgICAgICAgICBleC5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWE5JRXhjZXB0aW9uKGV4KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICByZXR1cm4gZkN1cnJlbnRTY2FubmVyLnNjYW5Eb2N1bWVudChjb21wbGV0ZSk7Ci0gICAgICAgIH0gY2F0Y2ggKFhOSUV4Y2VwdGlvbiBleCkgewotICAgICAgICAgICAgaWYgKFBSSU5UX0VYQ0VQVElPTl9TVEFDS19UUkFDRSkKLSAgICAgICAgICAgICAgICBleC5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgICAgICAgIHRocm93IGV4OwotICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgewotICAgICAgICAgICAgaWYgKFBSSU5UX0VYQ0VQVElPTl9TVEFDS19UUkFDRSkKLSAgICAgICAgICAgICAgICBleC5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgICAgICAgIHRocm93IGV4OwotICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIGV4KSB7Ci0gICAgICAgICAgICBpZiAoUFJJTlRfRVhDRVBUSU9OX1NUQUNLX1RSQUNFKQotICAgICAgICAgICAgICAgIGV4LnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgICAgICAgdGhyb3cgZXg7Ci0gICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgewotICAgICAgICAgICAgaWYgKFBSSU5UX0VYQ0VQVElPTl9TVEFDS19UUkFDRSkKLSAgICAgICAgICAgICAgICBleC5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgICAgICAgIHRocm93IG5ldyBYTklFeGNlcHRpb24oZXgpOwotICAgICAgICB9Ci0KLSAgICB9IC8vIHBhcnNlKGJvb2xlYW4pOmJvb2xlYW4KLQotICAgICAgICAvKioKLSAgICAgICAgICogUmV0dXJucyB0aGUgc3RhdGUgb2YgYSBmZWF0dXJlLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gZmVhdHVyZUlkIFRoZSBmZWF0dXJlIGlkZW50aWZpZXIuCi0gICAgICAgICAgICAgICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBmZWF0dXJlIGlzIHN1cHBvcnRlZAotICAgICAgICAgKgotICAgICAgICAgKiBAdGhyb3dzIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gVGhyb3duIGZvciBjb25maWd1cmF0aW9uIGVycm9yLgotICAgICAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW4gZ2VuZXJhbCwgY29tcG9uZW50cyBzaG91bGQKLSAgICAgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9ubHkgdGhyb3cgdGhpcyBleGNlcHRpb24gaWYKLSAgICAgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0IGlzIDxzdHJvbmc+cmVhbGx5PC9zdHJvbmc+Ci0gICAgICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhIGNyaXRpY2FsIGVycm9yLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIEZlYXR1cmVTdGF0ZSBnZXRGZWF0dXJlU3RhdGUoU3RyaW5nIGZlYXR1cmVJZCkKLSAgICAgICAgICAgICAgICB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBtYWtlIHRoaXMgZmVhdHVyZSBzcGVjaWFsCi0gICAgICAgIGlmIChmZWF0dXJlSWQuZXF1YWxzKFBBUlNFUl9TRVRUSU5HUykpewotICAgICAgICAgICAgICAgIHJldHVybiBGZWF0dXJlU3RhdGUuaXMoZkNvbmZpZ1VwZGF0ZWQpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBzdXBlci5nZXRGZWF0dXJlU3RhdGUoZmVhdHVyZUlkKTsKLQotICAgICAgICB9IC8vIGdldEZlYXR1cmUoU3RyaW5nKTpib29sZWFuCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFNldCB0aGUgc3RhdGUgb2YgYSBmZWF0dXJlLgotICAgICAgICAgKgotICAgICAgICAgKiBTZXQgdGhlIHN0YXRlIG9mIGFueSBmZWF0dXJlIGluIGEgU0FYMiBwYXJzZXIuICBUaGUgcGFyc2VyCi0gICAgICAgICAqIG1pZ2h0IG5vdCByZWNvZ25pemUgdGhlIGZlYXR1cmUsIGFuZCBpZiBpdCBkb2VzIHJlY29nbml6ZQotICAgICAgICAgKiBpdCwgaXQgbWlnaHQgbm90IGJlIGFibGUgdG8gZnVsZmlsbCB0aGUgcmVxdWVzdC4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIGZlYXR1cmVJZCBUaGUgdW5pcXVlIGlkZW50aWZpZXIgKFVSSSkgb2YgdGhlIGZlYXR1cmUuCi0gICAgICAgICAqIEBwYXJhbSBzdGF0ZSBUaGUgcmVxdWVzdGVkIHN0YXRlIG9mIHRoZSBmZWF0dXJlICh0cnVlIG9yIGZhbHNlKS4KLSAgICAgICAgICoKLSAgICAgICAgICogQGV4Y2VwdGlvbiBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBJZiB0aGUKLSAgICAgICAgICogICAgICAgICAgICByZXF1ZXN0ZWQgZmVhdHVyZSBpcyBub3Qga25vd24uCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgdm9pZCBzZXRGZWF0dXJlKFN0cmluZyBmZWF0dXJlSWQsIGJvb2xlYW4gc3RhdGUpCi0gICAgICAgICAgICAgICAgdGhyb3dzIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gewotICAgICAgICAgICAgICAgIGZDb25maWdVcGRhdGVkID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAvLyBmb3J3YXJkIHRvIGV2ZXJ5IFhNTCAxLjAgY29tcG9uZW50Ci0gICAgICAgICAgICAgICAgaW50IGNvdW50ID0gZkNvbXBvbmVudHMuc2l6ZSgpOwotICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykgewotICAgICAgICAgICAgICAgICAgICAgICAgWE1MQ29tcG9uZW50IGMgPSAoWE1MQ29tcG9uZW50KSBmQ29tcG9uZW50cy5nZXQoaSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBjLnNldEZlYXR1cmUoZmVhdHVyZUlkLCBzdGF0ZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIC8vIGZvcndhcmQgaXQgdG8gY29tbW9uIGNvbXBvbmVudHMKLSAgICAgICAgICAgICAgICBjb3VudCA9IGZDb21tb25Db21wb25lbnRzLnNpemUoKTsKLSAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIFhNTENvbXBvbmVudCBjID0gKFhNTENvbXBvbmVudCkgZkNvbW1vbkNvbXBvbmVudHMuZ2V0KGkpOwotICAgICAgICAgICAgICAgICAgICAgICAgYy5zZXRGZWF0dXJlKGZlYXR1cmVJZCwgc3RhdGUpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8vIGZvcndhcmQgdG8gZXZlcnkgWE1MIDEuMSBjb21wb25lbnQKLSAgICAgICAgICAgICAgICBjb3VudCA9IGZYTUwxMUNvbXBvbmVudHMuc2l6ZSgpOwotICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykgewotICAgICAgICAgICAgICAgICAgICAgICAgWE1MQ29tcG9uZW50IGMgPSAoWE1MQ29tcG9uZW50KSBmWE1MMTFDb21wb25lbnRzLmdldChpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHRyeXsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYy5zZXRGZWF0dXJlKGZlYXR1cmVJZCwgc3RhdGUpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKXsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbm8gb3AKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLy8gc2F2ZSBzdGF0ZSBpZiBub29uZSAib2JqZWN0cyIKLSAgICAgICAgICAgICAgICBzdXBlci5zZXRGZWF0dXJlKGZlYXR1cmVJZCwgc3RhdGUpOwotCi0gICAgICAgIH0gLy8gc2V0RmVhdHVyZShTdHJpbmcsYm9vbGVhbikKLQotICAgICAgICAvKioKLSAgICAgICAgICogc2V0UHJvcGVydHkKLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIHByb3BlcnR5SWQKLSAgICAgICAgICogQHBhcmFtIHZhbHVlCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgdm9pZCBzZXRQcm9wZXJ0eShTdHJpbmcgcHJvcGVydHlJZCwgT2JqZWN0IHZhbHVlKQotICAgICAgICAgICAgICAgIHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIHsKLSAgICAgICAgICAgICAgICBmQ29uZmlnVXBkYXRlZCA9IHRydWU7Ci0gICAgICAgICAgICAgICAgLy8gZm9yd2FyZCB0byBldmVyeSBYTUwgMS4wIGNvbXBvbmVudAotICAgICAgICAgICAgICAgIGludCBjb3VudCA9IGZDb21wb25lbnRzLnNpemUoKTsKLSAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIFhNTENvbXBvbmVudCBjID0gKFhNTENvbXBvbmVudCkgZkNvbXBvbmVudHMuZ2V0KGkpOwotICAgICAgICAgICAgICAgICAgICAgICAgYy5zZXRQcm9wZXJ0eShwcm9wZXJ0eUlkLCB2YWx1ZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIC8vIGZvcndhcmQgaXQgdG8gZXZlcnkgY29tbW9uIENvbXBvbmVudAotICAgICAgICAgICAgICAgIGNvdW50ID0gZkNvbW1vbkNvbXBvbmVudHMuc2l6ZSgpOwotICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykgewotICAgICAgICAgICAgICAgICAgICAgICAgWE1MQ29tcG9uZW50IGMgPSAoWE1MQ29tcG9uZW50KSBmQ29tbW9uQ29tcG9uZW50cy5nZXQoaSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBjLnNldFByb3BlcnR5KHByb3BlcnR5SWQsIHZhbHVlKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLy8gZm9yd2FyZCBpdCB0byBldmVyeSBYTUwgMS4xIGNvbXBvbmVudAotICAgICAgICAgICAgICAgIGNvdW50ID0gZlhNTDExQ29tcG9uZW50cy5zaXplKCk7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBYTUxDb21wb25lbnQgYyA9IChYTUxDb21wb25lbnQpIGZYTUwxMUNvbXBvbmVudHMuZ2V0KGkpOwotICAgICAgICAgICAgICAgICAgICAgICAgdHJ5ewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLnNldFByb3BlcnR5KHByb3BlcnR5SWQsIHZhbHVlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGNhdGNoIChFeGNlcHRpb24gZSl7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlnbm9yZSBpdAotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8vIHN0b3JlIHZhbHVlIGlmIG5vb25lICJvYmplY3RzIgotICAgICAgICAgICAgICAgIHN1cGVyLnNldFByb3BlcnR5KHByb3BlcnR5SWQsIHZhbHVlKTsKLQotICAgICAgICB9IC8vIHNldFByb3BlcnR5KFN0cmluZyxPYmplY3QpCi0KLQotICAgICAgICAvKiogUmV0dXJucyB0aGUgbG9jYWxlLiAqLwotICAgICAgICBwdWJsaWMgTG9jYWxlIGdldExvY2FsZSgpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZkxvY2FsZTsKLSAgICAgICAgfSAvLyBnZXRMb2NhbGUoKTpMb2NhbGUKLQotICAgICAgICAvKioKLSAgICAgICAgICogcmVzZXQgYWxsIFhNTCAxLjAgY29tcG9uZW50cyBiZWZvcmUgcGFyc2luZyBhbmQgbmFtZXNwYWNlIGNvbnRleHQKLSAgICAgICAgICovCi0gICAgICAgIHByb3RlY3RlZCB2b2lkIHJlc2V0KCkgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICAgICAgaW50IGNvdW50ID0gZkNvbXBvbmVudHMuc2l6ZSgpOwotICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykgewotICAgICAgICAgICAgICAgICAgICAgICAgWE1MQ29tcG9uZW50IGMgPSAoWE1MQ29tcG9uZW50KSBmQ29tcG9uZW50cy5nZXQoaSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBjLnJlc2V0KHRoaXMpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICB9IC8vIHJlc2V0KCkKLQotICAgICAgICAvKioKLSAgICAgICAgICogcmVzZXQgYWxsIGNvbW1vbiBjb21wb25lbnRzIGJlZm9yZSBwYXJzaW5nCi0gICAgICAgICAqLwotICAgICAgICBwcm90ZWN0ZWQgdm9pZCByZXNldENvbW1vbigpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICAgICAgICAgIC8vIHJlc2V0IGNvbW1vbiBjb21wb25lbnRzCi0gICAgICAgICAgICAgICAgaW50IGNvdW50ID0gZkNvbW1vbkNvbXBvbmVudHMuc2l6ZSgpOwotICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykgewotICAgICAgICAgICAgICAgICAgICAgICAgWE1MQ29tcG9uZW50IGMgPSAoWE1MQ29tcG9uZW50KSBmQ29tbW9uQ29tcG9uZW50cy5nZXQoaSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBjLnJlc2V0KHRoaXMpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICB9IC8vIHJlc2V0Q29tbW9uKCkKLQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiByZXNldCBhbGwgY29tcG9uZW50cyBiZWZvcmUgcGFyc2luZyBhbmQgbmFtZXNwYWNlIGNvbnRleHQKLSAgICAgICAgICovCi0gICAgICAgIHByb3RlY3RlZCB2b2lkIHJlc2V0WE1MMTEoKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgICAgICAgICAvLyByZXNldCBldmVyeSBjb21wb25lbnQKLSAgICAgICAgICAgICAgICBpbnQgY291bnQgPSBmWE1MMTFDb21wb25lbnRzLnNpemUoKTsKLSAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIFhNTENvbXBvbmVudCBjID0gKFhNTENvbXBvbmVudCkgZlhNTDExQ29tcG9uZW50cy5nZXQoaSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBjLnJlc2V0KHRoaXMpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICB9IC8vIHJlc2V0WE1MMTEoKQotCi0KLSAgICAvKioKLSAgICAgKiAgQ29uZmlndXJlcyB0aGUgWE1MIDEuMSBwaXBlbGluZS4KLSAgICAgKiAgTm90ZTogdGhpcyBtZXRob2QgYWxzbyByZXNldHMgdGhlIG5ldyBYTUwxMSBjb21wb25lbnRzLgotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIGNvbmZpZ3VyZVhNTDExUGlwZWxpbmUoKSB7Ci0gICAgICAgIGlmIChmQ3VycmVudERWRmFjdG9yeSAhPSBmWE1MMTFEYXRhdHlwZUZhY3RvcnkpIHsKLSAgICAgICAgICAgIGZDdXJyZW50RFZGYWN0b3J5ID0gZlhNTDExRGF0YXR5cGVGYWN0b3J5OwotICAgICAgICAgICAgc2V0UHJvcGVydHkoREFUQVRZUEVfVkFMSURBVE9SX0ZBQ1RPUlksIGZDdXJyZW50RFZGYWN0b3J5KTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIHNldHVwIERURCBwaXBlbGluZQotICAgICAgICBpZiAoZkN1cnJlbnREVERTY2FubmVyICE9IGZYTUwxMURURFNjYW5uZXIpIHsKLSAgICAgICAgICAgIGZDdXJyZW50RFREU2Nhbm5lciA9IGZYTUwxMURURFNjYW5uZXI7Ci0gICAgICAgICAgICBzZXRQcm9wZXJ0eShEVERfU0NBTk5FUiwgZkN1cnJlbnREVERTY2FubmVyKTsKLSAgICAgICAgfQotICAgICAgICBmWE1MMTFEVERTY2FubmVyLnNldERUREhhbmRsZXIoZkRUREhhbmRsZXIpOwotICAgICAgICBmWE1MMTFEVERTY2FubmVyLnNldERURENvbnRlbnRNb2RlbEhhbmRsZXIoZkRURENvbnRlbnRNb2RlbEhhbmRsZXIpOwotCi0gICAgICAgIC8vIHNldHVwIFhNTCAxLjEgZG9jdW1lbnQgcGlwZWxpbmUKLSAgICAgICAgaWYgKGZGZWF0dXJlcy5nZXQoTkFNRVNQQUNFUykgPT0gQm9vbGVhbi5UUlVFKSB7Ci0gICAgICAgICAgICBpZiAoZkN1cnJlbnRTY2FubmVyICE9IGZYTUwxMU5TRG9jU2Nhbm5lcikgewotICAgICAgICAgICAgICAgIGZDdXJyZW50U2Nhbm5lciA9IGZYTUwxMU5TRG9jU2Nhbm5lcjsKLSAgICAgICAgICAgICAgICBzZXRQcm9wZXJ0eShET0NVTUVOVF9TQ0FOTkVSLCBmWE1MMTFOU0RvY1NjYW5uZXIpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBmWE1MMTFOU0RvY1NjYW5uZXIuc2V0RFREVmFsaWRhdG9yKG51bGwpOwotICAgICAgICAgICAgZlhNTDExTlNEb2NTY2FubmVyLnNldERvY3VtZW50SGFuZGxlcihmRG9jdW1lbnRIYW5kbGVyKTsKLSAgICAgICAgICAgIGlmIChmRG9jdW1lbnRIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLnNldERvY3VtZW50U291cmNlKGZYTUwxMU5TRG9jU2Nhbm5lcik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmTGFzdENvbXBvbmVudCA9IGZYTUwxMU5TRG9jU2Nhbm5lcjsKLQotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gY3JlYXRlIGNvbXBvbmVudHMKLSAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZYTUwxMURvY1NjYW5uZXIgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG5vbiBuYW1lc3BhY2UgZG9jdW1lbnQgcGlwZWxpbmUKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmWE1MMTFEb2NTY2FubmVyID0gbmV3IFhNTDExRG9jdW1lbnRTY2FubmVySW1wbCgpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZFhNTDExQ29tcG9uZW50KGZYTUwxMURvY1NjYW5uZXIpOwotICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoZkN1cnJlbnRTY2FubmVyICE9IGZYTUwxMURvY1NjYW5uZXIpIHsKLSAgICAgICAgICAgICAgICBmQ3VycmVudFNjYW5uZXIgPSBmWE1MMTFEb2NTY2FubmVyOwotICAgICAgICAgICAgICAgIHNldFByb3BlcnR5KERPQ1VNRU5UX1NDQU5ORVIsIGZYTUwxMURvY1NjYW5uZXIpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZlhNTDExRG9jU2Nhbm5lci5zZXREb2N1bWVudEhhbmRsZXIoZkRvY3VtZW50SGFuZGxlcik7Ci0KLSAgICAgICAgICAgIGlmIChmRG9jdW1lbnRIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLnNldERvY3VtZW50U291cmNlKGZYTUwxMURvY1NjYW5uZXIpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZkxhc3RDb21wb25lbnQgPSBmWE1MMTFEb2NTY2FubmVyOwotICAgICAgICB9Ci0KLSAgICB9IC8vIGNvbmZpZ3VyZVhNTDExUGlwZWxpbmUoKQotCi0gICAgLyoqIENvbmZpZ3VyZXMgdGhlIHBpcGVsaW5lLiAqLwotICAgIHByb3RlY3RlZCB2b2lkIGNvbmZpZ3VyZVBpcGVsaW5lKCkgewotICAgICAgICBpZiAoZkN1cnJlbnREVkZhY3RvcnkgIT0gZkRhdGF0eXBlVmFsaWRhdG9yRmFjdG9yeSkgewotICAgICAgICAgICAgZkN1cnJlbnREVkZhY3RvcnkgPSBmRGF0YXR5cGVWYWxpZGF0b3JGYWN0b3J5OwotICAgICAgICAgICAgLy8gdXNlIFhNTCAxLjAgZGF0YXR5cGUgbGlicmFyeQotICAgICAgICAgICAgc2V0UHJvcGVydHkoREFUQVRZUEVfVkFMSURBVE9SX0ZBQ1RPUlksIGZDdXJyZW50RFZGYWN0b3J5KTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIHNldHVwIERURCBwaXBlbGluZQotICAgICAgICBpZiAoZkN1cnJlbnREVERTY2FubmVyICE9IGZEVERTY2FubmVyKSB7Ci0gICAgICAgICAgICBmQ3VycmVudERURFNjYW5uZXIgPSBmRFREU2Nhbm5lcjsKLSAgICAgICAgICAgIHNldFByb3BlcnR5KERURF9TQ0FOTkVSLCBmQ3VycmVudERURFNjYW5uZXIpOwotICAgICAgICB9Ci0gICAgICAgIGZEVERTY2FubmVyLnNldERUREhhbmRsZXIoZkRUREhhbmRsZXIpOwotICAgICAgICBmRFREU2Nhbm5lci5zZXREVERDb250ZW50TW9kZWxIYW5kbGVyKGZEVERDb250ZW50TW9kZWxIYW5kbGVyKTsKLQotICAgICAgICAvLyBzZXR1cCBkb2N1bWVudCBwaXBlbGluZQotICAgICAgICBpZiAoZkZlYXR1cmVzLmdldChOQU1FU1BBQ0VTKSA9PSBCb29sZWFuLlRSVUUpIHsKLSAgICAgICAgICAgIGlmIChmQ3VycmVudFNjYW5uZXIgIT0gZk5hbWVzcGFjZVNjYW5uZXIpIHsKLSAgICAgICAgICAgICAgICBmQ3VycmVudFNjYW5uZXIgPSBmTmFtZXNwYWNlU2Nhbm5lcjsKLSAgICAgICAgICAgICAgICBzZXRQcm9wZXJ0eShET0NVTUVOVF9TQ0FOTkVSLCBmTmFtZXNwYWNlU2Nhbm5lcik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmTmFtZXNwYWNlU2Nhbm5lci5zZXREVERWYWxpZGF0b3IobnVsbCk7Ci0gICAgICAgICAgICBmTmFtZXNwYWNlU2Nhbm5lci5zZXREb2N1bWVudEhhbmRsZXIoZkRvY3VtZW50SGFuZGxlcik7Ci0gICAgICAgICAgICBpZiAoZkRvY3VtZW50SGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci5zZXREb2N1bWVudFNvdXJjZShmTmFtZXNwYWNlU2Nhbm5lcik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmTGFzdENvbXBvbmVudCA9IGZOYW1lc3BhY2VTY2FubmVyOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgLy8gY3JlYXRlIGNvbXBvbmVudHMKLSAgICAgICAgICAgIGlmIChmTm9uTlNTY2FubmVyID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmTm9uTlNTY2FubmVyID0gbmV3IFhNTERvY3VtZW50U2Nhbm5lckltcGwoKTsKLSAgICAgICAgICAgICAgICAvLyBhZGQgY29tcG9uZW50cwotICAgICAgICAgICAgICAgIGFkZENvbXBvbmVudCgoWE1MQ29tcG9uZW50KSBmTm9uTlNTY2FubmVyKTsKLQotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKGZDdXJyZW50U2Nhbm5lciAhPSBmTm9uTlNTY2FubmVyKSB7Ci0gICAgICAgICAgICAgICAgZkN1cnJlbnRTY2FubmVyID0gZk5vbk5TU2Nhbm5lcjsKLSAgICAgICAgICAgICAgICBzZXRQcm9wZXJ0eShET0NVTUVOVF9TQ0FOTkVSLCBmTm9uTlNTY2FubmVyKTsKLQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBmTm9uTlNTY2FubmVyLnNldERvY3VtZW50SGFuZGxlcihmRG9jdW1lbnRIYW5kbGVyKTsKLSAgICAgICAgICAgIGlmIChmRG9jdW1lbnRIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLnNldERvY3VtZW50U291cmNlKGZOb25OU1NjYW5uZXIpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZkxhc3RDb21wb25lbnQgPSBmTm9uTlNTY2FubmVyOwotICAgICAgICB9Ci0KLSAgICB9IC8vIGNvbmZpZ3VyZVBpcGVsaW5lKCkKLQotCi0gICAgLy8gZmVhdHVyZXMgYW5kIHByb3BlcnRpZXMKLQotICAgIC8qKgotICAgICAqIENoZWNrIGEgZmVhdHVyZS4gSWYgZmVhdHVyZSBpcyBrbm93IGFuZCBzdXBwb3J0ZWQsIHRoaXMgbWV0aG9kIHNpbXBseQotICAgICAqIHJldHVybnMuIE90aGVyd2lzZSwgdGhlIGFwcHJvcHJpYXRlIGV4Y2VwdGlvbiBpcyB0aHJvd24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZmVhdHVyZUlkIFRoZSB1bmlxdWUgaWRlbnRpZmllciAoVVJJKSBvZiB0aGUgZmVhdHVyZS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBUaHJvd24gZm9yIGNvbmZpZ3VyYXRpb24gZXJyb3IuCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluIGdlbmVyYWwsIGNvbXBvbmVudHMgc2hvdWxkCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9ubHkgdGhyb3cgdGhpcyBleGNlcHRpb24gaWYKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXQgaXMgPHN0cm9uZz5yZWFsbHk8L3N0cm9uZz4KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYSBjcml0aWNhbCBlcnJvci4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgRmVhdHVyZVN0YXRlIGNoZWNrRmVhdHVyZShTdHJpbmcgZmVhdHVyZUlkKSB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gWGVyY2VzIEZlYXR1cmVzCi0gICAgICAgIC8vCi0KLSAgICAgICAgaWYgKGZlYXR1cmVJZC5zdGFydHNXaXRoKENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVgpKSB7Ci0gICAgICAgICAgICBmaW5hbCBpbnQgc3VmZml4TGVuZ3RoID0gZmVhdHVyZUlkLmxlbmd0aCgpIC0gQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWC5sZW5ndGgoKTsKLQotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIC8vIGh0dHA6Ly9hcGFjaGUub3JnL3htbC9mZWF0dXJlcy92YWxpZGF0aW9uL2R5bmFtaWMKLSAgICAgICAgICAgIC8vICAgQWxsb3dzIHRoZSBwYXJzZXIgdG8gdmFsaWRhdGUgYSBkb2N1bWVudCBvbmx5IHdoZW4gaXQKLSAgICAgICAgICAgIC8vICAgY29udGFpbnMgYSBncmFtbWFyLiBWYWxpZGF0aW9uIGlzIHR1cm5lZCBvbi9vZmYgYmFzZWQKLSAgICAgICAgICAgIC8vICAgb24gZWFjaCBkb2N1bWVudCBpbnN0YW5jZSwgYXV0b21hdGljYWxseS4KLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICBpZiAoc3VmZml4TGVuZ3RoID09IENvbnN0YW50cy5EWU5BTUlDX1ZBTElEQVRJT05fRkVBVFVSRS5sZW5ndGgoKSAmJgotICAgICAgICAgICAgICAgIGZlYXR1cmVJZC5lbmRzV2l0aChDb25zdGFudHMuRFlOQU1JQ19WQUxJREFUSU9OX0ZFQVRVUkUpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIEZlYXR1cmVTdGF0ZS5SRUNPR05JWkVEOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgLy8gaHR0cDovL2FwYWNoZS5vcmcveG1sL2ZlYXR1cmVzL3ZhbGlkYXRpb24vZGVmYXVsdC1hdHRyaWJ1dGUtdmFsdWVzCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgaWYgKHN1ZmZpeExlbmd0aCA9PSBDb25zdGFudHMuREVGQVVMVF9BVFRSSUJVVEVfVkFMVUVTX0ZFQVRVUkUubGVuZ3RoKCkgJiYKLSAgICAgICAgICAgICAgICBmZWF0dXJlSWQuZW5kc1dpdGgoQ29uc3RhbnRzLkRFRkFVTFRfQVRUUklCVVRFX1ZBTFVFU19GRUFUVVJFKSkgewotICAgICAgICAgICAgICAgIC8vIFJFVklTSVQKLSAgICAgICAgICAgICAgICByZXR1cm4gRmVhdHVyZVN0YXRlLk5PVF9TVVBQT1JURUQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLwotICAgICAgICAgICAgLy8gaHR0cDovL2FwYWNoZS5vcmcveG1sL2ZlYXR1cmVzL3ZhbGlkYXRpb24vZGVmYXVsdC1hdHRyaWJ1dGUtdmFsdWVzCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgaWYgKHN1ZmZpeExlbmd0aCA9PSBDb25zdGFudHMuVkFMSURBVEVfQ09OVEVOVF9NT0RFTFNfRkVBVFVSRS5sZW5ndGgoKSAmJgotICAgICAgICAgICAgICAgIGZlYXR1cmVJZC5lbmRzV2l0aChDb25zdGFudHMuVkFMSURBVEVfQ09OVEVOVF9NT0RFTFNfRkVBVFVSRSkpIHsKLSAgICAgICAgICAgICAgICAvLyBSRVZJU0lUCi0gICAgICAgICAgICAgICAgcmV0dXJuIEZlYXR1cmVTdGF0ZS5OT1RfU1VQUE9SVEVEOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIC8vIGh0dHA6Ly9hcGFjaGUub3JnL3htbC9mZWF0dXJlcy92YWxpZGF0aW9uL25vbnZhbGlkYXRpbmcvbG9hZC1kdGQtZ3JhbW1hcgotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIGlmIChzdWZmaXhMZW5ndGggPT0gQ29uc3RhbnRzLkxPQURfRFREX0dSQU1NQVJfRkVBVFVSRS5sZW5ndGgoKSAmJgotICAgICAgICAgICAgICAgIGZlYXR1cmVJZC5lbmRzV2l0aChDb25zdGFudHMuTE9BRF9EVERfR1JBTU1BUl9GRUFUVVJFKSkgewotICAgICAgICAgICAgICAgIHJldHVybiBGZWF0dXJlU3RhdGUuUkVDT0dOSVpFRDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAvLyBodHRwOi8vYXBhY2hlLm9yZy94bWwvZmVhdHVyZXMvdmFsaWRhdGlvbi9ub252YWxpZGF0aW5nL2xvYWQtZXh0ZXJuYWwtZHRkCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgaWYgKHN1ZmZpeExlbmd0aCA9PSBDb25zdGFudHMuTE9BRF9FWFRFUk5BTF9EVERfRkVBVFVSRS5sZW5ndGgoKSAmJgotICAgICAgICAgICAgICAgIGZlYXR1cmVJZC5lbmRzV2l0aChDb25zdGFudHMuTE9BRF9FWFRFUk5BTF9EVERfRkVBVFVSRSkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gRmVhdHVyZVN0YXRlLlJFQ09HTklaRUQ7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAvLyBodHRwOi8vYXBhY2hlLm9yZy94bWwvZmVhdHVyZXMvdmFsaWRhdGlvbi9kZWZhdWx0LWF0dHJpYnV0ZS12YWx1ZXMKLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICBpZiAoc3VmZml4TGVuZ3RoID09IENvbnN0YW50cy5WQUxJREFURV9EQVRBVFlQRVNfRkVBVFVSRS5sZW5ndGgoKSAmJgotICAgICAgICAgICAgICAgIGZlYXR1cmVJZC5lbmRzV2l0aChDb25zdGFudHMuVkFMSURBVEVfREFUQVRZUEVTX0ZFQVRVUkUpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIEZlYXR1cmVTdGF0ZS5OT1RfU1VQUE9SVEVEOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBzcGVjaWFsIHBlcmZvcm1hbmNlIGZlYXR1cmU6IG9ubHkgY29tcG9uZW50IG1hbmFnZXIgaXMgYWxsb3dlZCB0byBzZXQgaXQuCi0gICAgICAgICAgICBpZiAoc3VmZml4TGVuZ3RoID09IENvbnN0YW50cy5QQVJTRVJfU0VUVElOR1MubGVuZ3RoKCkgJiYKLSAgICAgICAgICAgICAgICBmZWF0dXJlSWQuZW5kc1dpdGgoQ29uc3RhbnRzLlBBUlNFUl9TRVRUSU5HUykpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gRmVhdHVyZVN0YXRlLk5PVF9TVVBQT1JURUQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLwotICAgICAgICAvLyBOb3QgcmVjb2duaXplZAotICAgICAgICAvLwotCi0gICAgICAgIHJldHVybiBzdXBlci5jaGVja0ZlYXR1cmUoZmVhdHVyZUlkKTsKLQotICAgIH0gLy8gY2hlY2tGZWF0dXJlKFN0cmluZykKLQotICAgIC8qKgotICAgICAqIENoZWNrIGEgcHJvcGVydHkuIElmIHRoZSBwcm9wZXJ0eSBpcyBrbm93IGFuZCBzdXBwb3J0ZWQsIHRoaXMgbWV0aG9kCi0gICAgICogc2ltcGx5IHJldHVybnMuIE90aGVyd2lzZSwgdGhlIGFwcHJvcHJpYXRlIGV4Y2VwdGlvbiBpcyB0aHJvd24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcHJvcGVydHlJZCBUaGUgdW5pcXVlIGlkZW50aWZpZXIgKFVSSSkgb2YgdGhlIHByb3BlcnR5Ci0gICAgICogICAgICAgICAgICAgICAgICAgYmVpbmcgc2V0LgotICAgICAqCi0gICAgICogQHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIFRocm93biBmb3IgY29uZmlndXJhdGlvbiBlcnJvci4KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW4gZ2VuZXJhbCwgY29tcG9uZW50cyBzaG91bGQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb25seSB0aHJvdyB0aGlzIGV4Y2VwdGlvbiBpZgotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdCBpcyA8c3Ryb25nPnJlYWxseTwvc3Ryb25nPgotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhIGNyaXRpY2FsIGVycm9yLgotICAgICAqLwotICAgIHByb3RlY3RlZCBQcm9wZXJ0eVN0YXRlIGNoZWNrUHJvcGVydHkoU3RyaW5nIHByb3BlcnR5SWQpIHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIHsKLQotICAgICAgICAvLwotICAgICAgICAvLyBYZXJjZXMgUHJvcGVydGllcwotICAgICAgICAvLwotCi0gICAgICAgIGlmIChwcm9wZXJ0eUlkLnN0YXJ0c1dpdGgoQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVgpKSB7Ci0gICAgICAgICAgICBmaW5hbCBpbnQgc3VmZml4TGVuZ3RoID0gcHJvcGVydHlJZC5sZW5ndGgoKSAtIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYLmxlbmd0aCgpOwotCi0gICAgICAgICAgICBpZiAoc3VmZml4TGVuZ3RoID09IENvbnN0YW50cy5EVERfU0NBTk5FUl9QUk9QRVJUWS5sZW5ndGgoKSAmJgotICAgICAgICAgICAgICAgIHByb3BlcnR5SWQuZW5kc1dpdGgoQ29uc3RhbnRzLkRURF9TQ0FOTkVSX1BST1BFUlRZKSkgewotICAgICAgICAgICAgICAgIHJldHVybiBQcm9wZXJ0eVN0YXRlLlJFQ09HTklaRUQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAocHJvcGVydHlJZC5zdGFydHNXaXRoKENvbnN0YW50cy5KQVhQX1BST1BFUlRZX1BSRUZJWCkpIHsKLSAgICAgICAgICAgIGZpbmFsIGludCBzdWZmaXhMZW5ndGggPSBwcm9wZXJ0eUlkLmxlbmd0aCgpIC0gQ29uc3RhbnRzLkpBWFBfUFJPUEVSVFlfUFJFRklYLmxlbmd0aCgpOwotCi0gICAgICAgICAgICBpZiAoc3VmZml4TGVuZ3RoID09IENvbnN0YW50cy5TQ0hFTUFfU09VUkNFLmxlbmd0aCgpICYmCi0gICAgICAgICAgICAgICAgcHJvcGVydHlJZC5lbmRzV2l0aChDb25zdGFudHMuU0NIRU1BX1NPVVJDRSkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gUHJvcGVydHlTdGF0ZS5SRUNPR05JWkVEOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gc3BlY2lhbCBjYXNlcwotICAgICAgICBpZiAocHJvcGVydHlJZC5zdGFydHNXaXRoKENvbnN0YW50cy5TQVhfUFJPUEVSVFlfUFJFRklYKSkgewotICAgICAgICAgICAgZmluYWwgaW50IHN1ZmZpeExlbmd0aCA9IHByb3BlcnR5SWQubGVuZ3RoKCkgLSBDb25zdGFudHMuU0FYX1BST1BFUlRZX1BSRUZJWC5sZW5ndGgoKTsKLQotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIC8vIGh0dHA6Ly94bWwub3JnL3NheC9wcm9wZXJ0aWVzL3htbC1zdHJpbmcKLSAgICAgICAgICAgIC8vIFZhbHVlIHR5cGU6IFN0cmluZwotICAgICAgICAgICAgLy8gQWNjZXNzOiByZWFkLW9ubHkKLSAgICAgICAgICAgIC8vICAgR2V0IHRoZSBsaXRlcmFsIHN0cmluZyBvZiBjaGFyYWN0ZXJzIGFzc29jaWF0ZWQgd2l0aCB0aGUKLSAgICAgICAgICAgIC8vICAgY3VycmVudCBldmVudC4gIElmIHRoZSBwYXJzZXIgcmVjb2duaXNlcyBhbmQgc3VwcG9ydHMgdGhpcwotICAgICAgICAgICAgLy8gICBwcm9wZXJ0eSBidXQgaXMgbm90IGN1cnJlbnRseSBwYXJzaW5nIHRleHQsIGl0IHNob3VsZCByZXR1cm4KLSAgICAgICAgICAgIC8vICAgbnVsbCAodGhpcyBpcyBhIGdvb2Qgd2F5IHRvIGNoZWNrIGZvciBhdmFpbGFiaWxpdHkgYmVmb3JlIHRoZQotICAgICAgICAgICAgLy8gICBwYXJzZSBiZWdpbnMpLgotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIGlmIChzdWZmaXhMZW5ndGggPT0gQ29uc3RhbnRzLlhNTF9TVFJJTkdfUFJPUEVSVFkubGVuZ3RoKCkgJiYKLSAgICAgICAgICAgICAgICBwcm9wZXJ0eUlkLmVuZHNXaXRoKENvbnN0YW50cy5YTUxfU1RSSU5HX1BST1BFUlRZKSkgewotICAgICAgICAgICAgICAgIC8vIFJFVklTSVQgLSB3ZSBzaG91bGQgcHJvYmFibHkgYXNrIHhtbC1kZXYgZm9yIGEgcHJlY2lzZQotICAgICAgICAgICAgICAgIC8vIGRlZmluaXRpb24gb2Ygd2hhdCB0aGlzIGlzIGFjdHVhbGx5IHN1cHBvc2VkIHRvIHJldHVybiwgYW5kCi0gICAgICAgICAgICAgICAgLy8gaW4gZXhhY3RseSB3aGljaCBjaXJjdW1zdGFuY2VzLgotICAgICAgICAgICAgICAgIHJldHVybiBQcm9wZXJ0eVN0YXRlLk5PVF9TVVBQT1JURUQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLwotICAgICAgICAvLyBOb3QgcmVjb2duaXplZAotICAgICAgICAvLwotCi0gICAgICAgIHJldHVybiBzdXBlci5jaGVja1Byb3BlcnR5KHByb3BlcnR5SWQpOwotCi0gICAgfSAvLyBjaGVja1Byb3BlcnR5KFN0cmluZykKLQotCi0gICAgLyoqCi0gICAgICogQWRkcyBhIGNvbXBvbmVudCB0byB0aGUgcGFyc2VyIGNvbmZpZ3VyYXRpb24uIFRoaXMgbWV0aG9kIHdpbGwKLSAgICAgKiBhbHNvIGFkZCBhbGwgb2YgdGhlIGNvbXBvbmVudCdzIHJlY29nbml6ZWQgZmVhdHVyZXMgYW5kIHByb3BlcnRpZXMKLSAgICAgKiB0byB0aGUgbGlzdCBvZiBkZWZhdWx0IHJlY29nbml6ZWQgZmVhdHVyZXMgYW5kIHByb3BlcnRpZXMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29tcG9uZW50IFRoZSBjb21wb25lbnQgdG8gYWRkLgotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIGFkZENvbXBvbmVudChYTUxDb21wb25lbnQgY29tcG9uZW50KSB7Ci0KLSAgICAgICAgLy8gZG9uJ3QgYWRkIGEgY29tcG9uZW50IG1vcmUgdGhhbiBvbmNlCi0gICAgICAgIGlmIChmQ29tcG9uZW50cy5jb250YWlucyhjb21wb25lbnQpKSB7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLSAgICAgICAgZkNvbXBvbmVudHMuYWRkKGNvbXBvbmVudCk7Ci0gICAgICAgIGFkZFJlY29nbml6ZWRQYXJhbXNBbmRTZXREZWZhdWx0cyhjb21wb25lbnQpOwotCi0gICAgfSAvLyBhZGRDb21wb25lbnQoWE1MQ29tcG9uZW50KQotCi0gICAgLyoqCi0gICAgICogQWRkcyBjb21tb24gY29tcG9uZW50IHRvIHRoZSBwYXJzZXIgY29uZmlndXJhdGlvbi4gVGhpcyBtZXRob2Qgd2lsbAotICAgICAqIGFsc28gYWRkIGFsbCBvZiB0aGUgY29tcG9uZW50J3MgcmVjb2duaXplZCBmZWF0dXJlcyBhbmQgcHJvcGVydGllcwotICAgICAqIHRvIHRoZSBsaXN0IG9mIGRlZmF1bHQgcmVjb2duaXplZCBmZWF0dXJlcyBhbmQgcHJvcGVydGllcy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjb21wb25lbnQgVGhlIGNvbXBvbmVudCB0byBhZGQuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgYWRkQ29tbW9uQ29tcG9uZW50KFhNTENvbXBvbmVudCBjb21wb25lbnQpIHsKLQotICAgICAgICAvLyBkb24ndCBhZGQgYSBjb21wb25lbnQgbW9yZSB0aGFuIG9uY2UKLSAgICAgICAgaWYgKGZDb21tb25Db21wb25lbnRzLmNvbnRhaW5zKGNvbXBvbmVudCkpIHsKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotICAgICAgICBmQ29tbW9uQ29tcG9uZW50cy5hZGQoY29tcG9uZW50KTsKLSAgICAgICAgYWRkUmVjb2duaXplZFBhcmFtc0FuZFNldERlZmF1bHRzKGNvbXBvbmVudCk7Ci0KLSAgICB9IC8vIGFkZENvbW1vbkNvbXBvbmVudChYTUxDb21wb25lbnQpCi0KLSAgICAvKioKLSAgICAgKiBBZGRzIGFuIFhNTCAxLjEgY29tcG9uZW50IHRvIHRoZSBwYXJzZXIgY29uZmlndXJhdGlvbi4gVGhpcyBtZXRob2Qgd2lsbAotICAgICAqIGFsc28gYWRkIGFsbCBvZiB0aGUgY29tcG9uZW50J3MgcmVjb2duaXplZCBmZWF0dXJlcyBhbmQgcHJvcGVydGllcwotICAgICAqIHRvIHRoZSBsaXN0IG9mIGRlZmF1bHQgcmVjb2duaXplZCBmZWF0dXJlcyBhbmQgcHJvcGVydGllcy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjb21wb25lbnQgVGhlIGNvbXBvbmVudCB0byBhZGQuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgYWRkWE1MMTFDb21wb25lbnQoWE1MQ29tcG9uZW50IGNvbXBvbmVudCkgewotCi0gICAgICAgIC8vIGRvbid0IGFkZCBhIGNvbXBvbmVudCBtb3JlIHRoYW4gb25jZQotICAgICAgICBpZiAoZlhNTDExQ29tcG9uZW50cy5jb250YWlucyhjb21wb25lbnQpKSB7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLSAgICAgICAgZlhNTDExQ29tcG9uZW50cy5hZGQoY29tcG9uZW50KTsKLSAgICAgICAgYWRkUmVjb2duaXplZFBhcmFtc0FuZFNldERlZmF1bHRzKGNvbXBvbmVudCk7Ci0KLSAgICB9IC8vIGFkZFhNTDExQ29tcG9uZW50KFhNTENvbXBvbmVudCkKLQotICAgIC8qKgotICAgICAqIEFkZHMgYWxsIG9mIHRoZSBjb21wb25lbnQncyByZWNvZ25pemVkIGZlYXR1cmVzIGFuZCBwcm9wZXJ0aWVzCi0gICAgICogdG8gdGhlIGxpc3Qgb2YgZGVmYXVsdCByZWNvZ25pemVkIGZlYXR1cmVzIGFuZCBwcm9wZXJ0aWVzLCBhbmQKLSAgICAgKiBzZXRzIGRlZmF1bHQgdmFsdWVzIG9uIHRoZSBjb25maWd1cmF0aW9uIGZvciBmZWF0dXJlcyBhbmQKLSAgICAgKiBwcm9wZXJ0aWVzIHdoaWNoIHdlcmUgcHJldmlvdXNseSBhYnNlbnQgZnJvbSB0aGUgY29uZmlndXJhdGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjb21wb25lbnQgVGhlIGNvbXBvbmVudCB3aG9zZSByZWNvZ25pemVkIGZlYXR1cmVzCi0gICAgICogYW5kIHByb3BlcnRpZXMgd2lsbCBiZSBhZGRlZCB0byB0aGUgY29uZmlndXJhdGlvbgotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIGFkZFJlY29nbml6ZWRQYXJhbXNBbmRTZXREZWZhdWx0cyhYTUxDb21wb25lbnQgY29tcG9uZW50KSB7Ci0KLSAgICAgICAgLy8gcmVnaXN0ZXIgY29tcG9uZW50J3MgcmVjb2duaXplZCBmZWF0dXJlcwotICAgICAgICBTdHJpbmdbXSByZWNvZ25pemVkRmVhdHVyZXMgPSBjb21wb25lbnQuZ2V0UmVjb2duaXplZEZlYXR1cmVzKCk7Ci0gICAgICAgIGFkZFJlY29nbml6ZWRGZWF0dXJlcyhyZWNvZ25pemVkRmVhdHVyZXMpOwotCi0gICAgICAgIC8vIHJlZ2lzdGVyIGNvbXBvbmVudCdzIHJlY29nbml6ZWQgcHJvcGVydGllcwotICAgICAgICBTdHJpbmdbXSByZWNvZ25pemVkUHJvcGVydGllcyA9IGNvbXBvbmVudC5nZXRSZWNvZ25pemVkUHJvcGVydGllcygpOwotICAgICAgICBhZGRSZWNvZ25pemVkUHJvcGVydGllcyhyZWNvZ25pemVkUHJvcGVydGllcyk7Ci0KLSAgICAgICAgLy8gc2V0IGRlZmF1bHQgdmFsdWVzCi0gICAgICAgIGlmIChyZWNvZ25pemVkRmVhdHVyZXMgIT0gbnVsbCkgewotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZWNvZ25pemVkRmVhdHVyZXMubGVuZ3RoOyArK2kpIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgZmVhdHVyZUlkID0gcmVjb2duaXplZEZlYXR1cmVzW2ldOwotICAgICAgICAgICAgICAgIEJvb2xlYW4gc3RhdGUgPSBjb21wb25lbnQuZ2V0RmVhdHVyZURlZmF1bHQoZmVhdHVyZUlkKTsKLSAgICAgICAgICAgICAgICBpZiAoc3RhdGUgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAvLyBEbyBub3Qgb3ZlcndyaXRlIHZhbHVlcyBhbHJlYWR5IHNldCBvbiB0aGUgY29uZmlndXJhdGlvbi4KLSAgICAgICAgICAgICAgICAgICAgaWYgKCFmRmVhdHVyZXMuY29udGFpbnNLZXkoZmVhdHVyZUlkKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgZkZlYXR1cmVzLnB1dChmZWF0dXJlSWQsIHN0YXRlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIEZvciBuZXdseSBhZGRlZCBjb21wb25lbnRzIHdobyByZWNvZ25pemUgdGhpcyBmZWF0dXJlCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBidXQgZGlkIG5vdCBvZmZlciBhIGRlZmF1bHQgdmFsdWUsIHdlIG5lZWQgdG8gbWFrZQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gc3VyZSB0aGVzZSBjb21wb25lbnRzIHdpbGwgZ2V0IGFuIG9wcG9ydHVuaXR5IHRvIHJlYWQKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoZSB2YWx1ZSBiZWZvcmUgcGFyc2luZyBiZWdpbnMuCi0gICAgICAgICAgICAgICAgICAgICAgICBmQ29uZmlnVXBkYXRlZCA9IHRydWU7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKHJlY29nbml6ZWRQcm9wZXJ0aWVzICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVjb2duaXplZFByb3BlcnRpZXMubGVuZ3RoOyArK2kpIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgcHJvcGVydHlJZCA9IHJlY29nbml6ZWRQcm9wZXJ0aWVzW2ldOwotICAgICAgICAgICAgICAgIE9iamVjdCB2YWx1ZSA9IGNvbXBvbmVudC5nZXRQcm9wZXJ0eURlZmF1bHQocHJvcGVydHlJZCk7Ci0gICAgICAgICAgICAgICAgaWYgKHZhbHVlICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gRG8gbm90IG92ZXJ3cml0ZSB2YWx1ZXMgYWxyZWFkeSBzZXQgb24gdGhlIGNvbmZpZ3VyYXRpb24uCi0gICAgICAgICAgICAgICAgICAgIGlmICghZlByb3BlcnRpZXMuY29udGFpbnNLZXkocHJvcGVydHlJZCkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZQcm9wZXJ0aWVzLnB1dChwcm9wZXJ0eUlkLCB2YWx1ZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBGb3IgbmV3bHkgYWRkZWQgY29tcG9uZW50cyB3aG8gcmVjb2duaXplIHRoaXMgcHJvcGVydHkKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGJ1dCBkaWQgbm90IG9mZmVyIGEgZGVmYXVsdCB2YWx1ZSwgd2UgbmVlZCB0byBtYWtlCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBzdXJlIHRoZXNlIGNvbXBvbmVudHMgd2lsbCBnZXQgYW4gb3Bwb3J0dW5pdHkgdG8gcmVhZAotICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhlIHZhbHVlIGJlZm9yZSBwYXJzaW5nIGJlZ2lucy4KLSAgICAgICAgICAgICAgICAgICAgICAgIGZDb25maWdVcGRhdGVkID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBpbml0WE1MMTFDb21wb25lbnRzKCkgewotICAgICAgICBpZiAoIWYxMUluaXRpYWxpemVkKSB7Ci0KLSAgICAgICAgICAgIC8vIGNyZWF0ZSBkYXRhdHlwZSBmYWN0b3J5Ci0gICAgICAgICAgICBmWE1MMTFEYXRhdHlwZUZhY3RvcnkgPSBEVEREVkZhY3RvcnkuZ2V0SW5zdGFuY2UoWE1MMTFfREFUQVRZUEVfVkFMSURBVE9SX0ZBQ1RPUlkpOwotCi0gICAgICAgICAgICAvLyBzZXR1cCBYTUwgMS4xIERURCBwaXBlbGluZQotICAgICAgICAgICAgZlhNTDExRFREU2Nhbm5lciA9IG5ldyBYTUwxMURURFNjYW5uZXJJbXBsKCk7Ci0gICAgICAgICAgICBhZGRYTUwxMUNvbXBvbmVudChmWE1MMTFEVERTY2FubmVyKTsKLQotICAgICAgICAgICAgLy8gc2V0dXAgWE1MIDEuMS4gZG9jdW1lbnQgcGlwZWxpbmUgLSBuYW1lc3BhY2UgYXdhcmUKLSAgICAgICAgICAgIGZYTUwxMU5TRG9jU2Nhbm5lciA9IG5ldyBYTUwxMU5TRG9jdW1lbnRTY2FubmVySW1wbCgpOwotICAgICAgICAgICAgYWRkWE1MMTFDb21wb25lbnQoZlhNTDExTlNEb2NTY2FubmVyKTsKLQotICAgICAgICAgICAgZjExSW5pdGlhbGl6ZWQgPSB0cnVlOwotICAgICAgICB9Ci0gICAgfQotCi19IC8vIGNsYXNzIFhNTDExTm9uVmFsaWRhdGluZ0NvbmZpZ3VyYXRpb24KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3BhcnNlcnMvWE1MRG9jdW1lbnRQYXJzZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3BhcnNlcnMvWE1MRG9jdW1lbnRQYXJzZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOGE4OWU5OC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9wYXJzZXJzL1hNTERvY3VtZW50UGFyc2VyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3OSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwucGFyc2VyczsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5Db25zdGFudHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlN5bWJvbFRhYmxlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLmdyYW1tYXJzLlhNTEdyYW1tYXJQb29sOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxQYXJzZXJDb25maWd1cmF0aW9uOwotCi0vKioKLSAqIFRoaXMgaXMgYSBjb25jcmV0ZSB2YW5pbGxhIFhNTCBwYXJzZXIgY2xhc3MuIEl0IHVzZXMgdGhlIGFic3RyYWN0IHBhcnNlcgotICogd2l0aCBlaXRoZXIgYSBCYXNpY0NvbmZpZ3VyYXRpb24gb2JqZWN0IG9yIHRoZSBvbmUgc3BlY2lmaWVkIGJ5IHRoZQotICogYXBwbGljYXRpb24uCi0gKgotICogQGF1dGhvciBBcm5hdWQgIExlIEhvcnMsIElCTQotICogQGF1dGhvciBBbmR5IENsYXJrLCBJQk0KLSAqCi0gKiBAdmVyc2lvbiAkSWQ6IFhNTERvY3VtZW50UGFyc2VyLmphdmEsdiAxLjYgMjAxMC0xMS0wMSAwNDo0MDoxMCBqb2VodyBFeHAgJAotICovCi1wdWJsaWMgY2xhc3MgWE1MRG9jdW1lbnRQYXJzZXIKLSAgICBleHRlbmRzIEFic3RyYWN0WE1MRG9jdW1lbnRQYXJzZXIgewotCi0gICAgLy8KLSAgICAvLyBDb25zdHJ1Y3RvcnMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0cyBhIGRvY3VtZW50IHBhcnNlciB1c2luZyB0aGUgZGVmYXVsdCBiYXNpYyBwYXJzZXIKLSAgICAgKiBjb25maWd1cmF0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBYTUxEb2N1bWVudFBhcnNlcigpIHsKLSAgICAgICAgc3VwZXIobmV3IFhJbmNsdWRlQXdhcmVQYXJzZXJDb25maWd1cmF0aW9uKCkpOwotICAgIH0gLy8gPGluaXQ+KCkKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHMgYSBkb2N1bWVudCBwYXJzZXIgdXNpbmcgdGhlIHNwZWNpZmllZCBwYXJzZXIgY29uZmlndXJhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgWE1MRG9jdW1lbnRQYXJzZXIoWE1MUGFyc2VyQ29uZmlndXJhdGlvbiBjb25maWcpIHsKLSAgICAgICAgc3VwZXIoY29uZmlnKTsKLSAgICB9IC8vIDxpbml0PihQYXJzZXJDb25maWd1cmF0aW9uKQotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0cyBhIGRvY3VtZW50IHBhcnNlciB1c2luZyB0aGUgc3BlY2lmaWVkIHN5bWJvbCB0YWJsZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgWE1MRG9jdW1lbnRQYXJzZXIoU3ltYm9sVGFibGUgc3ltYm9sVGFibGUpIHsKLSAgICAgICAgc3VwZXIobmV3IFhJbmNsdWRlQXdhcmVQYXJzZXJDb25maWd1cmF0aW9uKCkpOwotICAgICAgICBmQ29uZmlndXJhdGlvbi5zZXRQcm9wZXJ0eShDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCtDb25zdGFudHMuU1lNQk9MX1RBQkxFX1BST1BFUlRZLCBzeW1ib2xUYWJsZSk7Ci0gICAgfSAvLyA8aW5pdD4oU3ltYm9sVGFibGUpCi0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RzIGEgZG9jdW1lbnQgcGFyc2VyIHVzaW5nIHRoZSBzcGVjaWZpZWQgc3ltYm9sIHRhYmxlIGFuZAotICAgICAqIGdyYW1tYXIgcG9vbC4KLSAgICAgKi8KLSAgICBwdWJsaWMgWE1MRG9jdW1lbnRQYXJzZXIoU3ltYm9sVGFibGUgc3ltYm9sVGFibGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTEdyYW1tYXJQb29sIGdyYW1tYXJQb29sKSB7Ci0gICAgICAgIHN1cGVyKG5ldyBYSW5jbHVkZUF3YXJlUGFyc2VyQ29uZmlndXJhdGlvbigpKTsKLSAgICAgICAgZkNvbmZpZ3VyYXRpb24uc2V0UHJvcGVydHkoQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVgrQ29uc3RhbnRzLlNZTUJPTF9UQUJMRV9QUk9QRVJUWSwgc3ltYm9sVGFibGUpOwotICAgICAgICBmQ29uZmlndXJhdGlvbi5zZXRQcm9wZXJ0eShDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCtDb25zdGFudHMuWE1MR1JBTU1BUl9QT09MX1BST1BFUlRZLCBncmFtbWFyUG9vbCk7Ci0gICAgfQotCi19IC8vIGNsYXNzIFhNTERvY3VtZW50UGFyc2VyCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9wYXJzZXJzL1hNTEdyYW1tYXJDYWNoaW5nQ29uZmlndXJhdGlvbi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvcGFyc2Vycy9YTUxHcmFtbWFyQ2FjaGluZ0NvbmZpZ3VyYXRpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggODk3Yjc1NC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9wYXJzZXJzL1hNTEdyYW1tYXJDYWNoaW5nQ29uZmlndXJhdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzEyICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5wYXJzZXJzOwotCi1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5Db25zdGFudHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR0ZC5EVERHcmFtbWFyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdGQuWE1MRFRETG9hZGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5TY2hlbWFHcmFtbWFyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5YTUxTY2hlbWFMb2FkZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLlhTTWVzc2FnZUZvcm1hdHRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuU3ltYm9sVGFibGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlN5bmNocm9uaXplZFN5bWJvbFRhYmxlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5YTUxHcmFtbWFyUG9vbEltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE5JRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLmdyYW1tYXJzLkdyYW1tYXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuZ3JhbW1hcnMuWE1MR3JhbW1hckRlc2NyaXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLmdyYW1tYXJzLlhNTEdyYW1tYXJQb29sOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxDb21wb25lbnRNYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxFbnRpdHlSZXNvbHZlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MSW5wdXRTb3VyY2U7Ci0KLS8qKgotICogPHA+IFRoaXMgY29uZmlndXJhdGlvbiBwcm92aWRlcyBhIGdlbmVyaWMgd2F5IG9mIHVzaW5nCi0gKiBYZXJjZXMncyBncmFtbWFyIGNhY2hpbmcgZmFjaWxpdGllcy4gIEl0IGV4dGVuZHMgdGhlCi0gKiBYSW5jbHVkZUF3YXJlUGFyc2VyQ29uZmlndXJhdGlvbiBhbmQgdGh1cyBtYXkgdmFsaWRhdGUgZG9jdW1lbnRzCi0gKiBhY2NvcmRpbmcgdG8gWE1MIHNjaGVtYXMgb3IgRFREJ3MuICBJdCBhbHNvIGFsbG93cyB0aGUgdXNlciB0bwotICogcHJlcGFyc2UgYSBncmFtbWFyLCBhbmQgdG8gbG9jayB0aGUgZ3JhbW1hciBwb29sCi0gKiBpbXBsZW1lbnRhdGlvbiBzdWNoIHRoYXQgbm8gbW9yZSBncmFtbWFycyB3aWxsIGJlIGFkZGVkLjwvcD4KLSAqIDxwPiBVc2luZyB0aGUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyIHByb3BlcnR5LCBhbgotICogYXBwbGljYXRpb24gbWF5IGluc3RhbnRpYXRlIGEgWGVyY2VzIFNBWCBvciBET00gcGFyc2VyIHdpdGgKLSAqIHRoaXMgY29uZmlndXJhdGlvbi4gIFdoZW4gaW52b2tlZCBpbiB0aGlzIG1hbm5lciwgdGhlIGRlZmF1bHQKLSAqIGJlaGF2aW91ciB3aWxsIGJlIGVsaWNpdGVkOyB0byB1c2UgdGhpcyBjb25maWd1cmF0aW9uJ3MKLSAqIHNwZWNpZmljIGZhY2lsaXRpZXMsIHRoZSB1c2VyIHdpbGwgbmVlZCB0byByZWZlcmVuY2UgaXQKLSAqIGRpcmVjdGx5LjwvcD4KLSAqIDxwPgotICogSW4gYWRkaXRpb24gdG8gdGhlIGZlYXR1cmVzIGFuZCBwcm9wZXJ0aWVzIHJlY29nbml6ZWQgYnkgdGhlIGJhc2UKLSAqIHBhcnNlciBjb25maWd1cmF0aW9uLCB0aGlzIGNsYXNzIHJlY29nbml6ZXMgdGhlc2UgYWRkaXRpb25hbAotICogZmVhdHVyZXMgYW5kIHByb3BlcnRpZXM6Ci0gKiA8dWw+Ci0gKiA8L3VsPgotICoKLSAqIEBhdXRob3IgTmVpbCBHcmFoYW0sIElCTQotICoKLSAqIEB2ZXJzaW9uICRJZDogWE1MR3JhbW1hckNhY2hpbmdDb25maWd1cmF0aW9uLmphdmEsdiAxLjYgMjAxMC0xMS0wMSAwNDo0MDoxMCBqb2VodyBFeHAgJAotICovCi1wdWJsaWMgY2xhc3MgWE1MR3JhbW1hckNhY2hpbmdDb25maWd1cmF0aW9uCi0gICAgZXh0ZW5kcyBYSW5jbHVkZUF3YXJlUGFyc2VyQ29uZmlndXJhdGlvbiB7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0YW50cwotICAgIC8vCi0KLSAgICAvLyBhIGxhcmcoaXNoKSBwcmltZSB0byB1c2UgZm9yIGEgc3ltYm9sIHRhYmxlIHRvIGJlIHNoYXJlZAotICAgIC8vIGFtb25nCi0gICAgLy8gcG90ZW50aWFsbHkgbWFuIHBhcnNlcnMuICBTdGFydCBvbmUgYXMgY2xvc2UgdG8gMksgKDIwCi0gICAgLy8gdGltZXMgbGFyZ2VyIHRoYW4gbm9ybWFsKSBhbmQgc2VlIHdoYXQgaGFwcGVucy4uLgotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJJR19QUklNRSA9IDIwMzk7Ci0KLSAgICAvLyB0aGUgc3RhdGljIHN5bWJvbCB0YWJsZSB0byBiZSBzaGFyZWQgYW1vbmdzdCBwYXJzZXJzCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTeW5jaHJvbml6ZWRTeW1ib2xUYWJsZSBmU3RhdGljU3ltYm9sVGFibGUgPQotICAgICAgICAgICAgbmV3IFN5bmNocm9uaXplZFN5bWJvbFRhYmxlKEJJR19QUklNRSk7Ci0KLSAgICAvLyB0aGUgR3JhbW1hciBQb29sIHRvIGJlIHNoYXJlZCBzaW1pbGFybHkKLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFhNTEdyYW1tYXJQb29sSW1wbCBmU3RhdGljR3JhbW1hclBvb2wgPQotICAgICAgICAgICAgbmV3IFhNTEdyYW1tYXJQb29sSW1wbCgpOwotCi0gICAgLy8gc2NoZW1hIGZ1bGwgY2hlY2tpbmcgY29uc3RhbnQKLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBTQ0hFTUFfRlVMTF9DSEVDS0lORyA9Ci0gICAgICAgICAgICBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYK0NvbnN0YW50cy5TQ0hFTUFfRlVMTF9DSEVDS0lORzsKLQotICAgIC8vIERhdGEKLQotICAgIC8vIHZhcmlhYmxlcyBuZWVkZWQgZm9yIGNhY2hpbmcgc2NoZW1hIGdyYW1tYXJzLgotICAgIHByb3RlY3RlZCBYTUxTY2hlbWFMb2FkZXIgZlNjaGVtYUxvYWRlcjsKLQotICAgIC8vIHRoZSBEVEQgZ3JhbW1hciBsb2FkZXIKLSAgICBwcm90ZWN0ZWQgWE1MRFRETG9hZGVyIGZEVERMb2FkZXI7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0cnVjdG9ycwotICAgIC8vCi0KLSAgICAvKiogRGVmYXVsdCBjb25zdHJ1Y3Rvci4gKi8KLSAgICBwdWJsaWMgWE1MR3JhbW1hckNhY2hpbmdDb25maWd1cmF0aW9uKCkgewotICAgICAgICB0aGlzKGZTdGF0aWNTeW1ib2xUYWJsZSwgZlN0YXRpY0dyYW1tYXJQb29sLCBudWxsKTsKLSAgICB9IC8vIDxpbml0PigpCi0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RzIGEgcGFyc2VyIGNvbmZpZ3VyYXRpb24gdXNpbmcgdGhlIHNwZWNpZmllZCBzeW1ib2wgdGFibGUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc3ltYm9sVGFibGUgVGhlIHN5bWJvbCB0YWJsZSB0byB1c2UuCi0gICAgICovCi0gICAgcHVibGljIFhNTEdyYW1tYXJDYWNoaW5nQ29uZmlndXJhdGlvbihTeW1ib2xUYWJsZSBzeW1ib2xUYWJsZSkgewotICAgICAgICB0aGlzKHN5bWJvbFRhYmxlLCBmU3RhdGljR3JhbW1hclBvb2wsIG51bGwpOwotICAgIH0gLy8gPGluaXQ+KFN5bWJvbFRhYmxlKQotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0cyBhIHBhcnNlciBjb25maWd1cmF0aW9uIHVzaW5nIHRoZSBzcGVjaWZpZWQgc3ltYm9sIHRhYmxlIGFuZAotICAgICAqIGdyYW1tYXIgcG9vbC4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPlJFVklTSVQ6PC9zdHJvbmc+Ci0gICAgICogR3JhbW1hciBwb29sIHdpbGwgYmUgdXBkYXRlZCB3aGVuIHRoZSBuZXcgdmFsaWRhdGlvbiBlbmdpbmUgaXMKLSAgICAgKiBpbXBsZW1lbnRlZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzeW1ib2xUYWJsZSBUaGUgc3ltYm9sIHRhYmxlIHRvIHVzZS4KLSAgICAgKiBAcGFyYW0gZ3JhbW1hclBvb2wgVGhlIGdyYW1tYXIgcG9vbCB0byB1c2UuCi0gICAgICovCi0gICAgcHVibGljIFhNTEdyYW1tYXJDYWNoaW5nQ29uZmlndXJhdGlvbihTeW1ib2xUYWJsZSBzeW1ib2xUYWJsZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTEdyYW1tYXJQb29sIGdyYW1tYXJQb29sKSB7Ci0gICAgICAgIHRoaXMoc3ltYm9sVGFibGUsIGdyYW1tYXJQb29sLCBudWxsKTsKLSAgICB9IC8vIDxpbml0PihTeW1ib2xUYWJsZSxYTUxHcmFtbWFyUG9vbCkKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHMgYSBwYXJzZXIgY29uZmlndXJhdGlvbiB1c2luZyB0aGUgc3BlY2lmaWVkIHN5bWJvbCB0YWJsZSwKLSAgICAgKiBncmFtbWFyIHBvb2wsIGFuZCBwYXJlbnQgc2V0dGluZ3MuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5SRVZJU0lUOjwvc3Ryb25nPgotICAgICAqIEdyYW1tYXIgcG9vbCB3aWxsIGJlIHVwZGF0ZWQgd2hlbiB0aGUgbmV3IHZhbGlkYXRpb24gZW5naW5lIGlzCi0gICAgICogaW1wbGVtZW50ZWQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc3ltYm9sVGFibGUgICAgVGhlIHN5bWJvbCB0YWJsZSB0byB1c2UuCi0gICAgICogQHBhcmFtIGdyYW1tYXJQb29sICAgIFRoZSBncmFtbWFyIHBvb2wgdG8gdXNlLgotICAgICAqIEBwYXJhbSBwYXJlbnRTZXR0aW5ncyBUaGUgcGFyZW50IHNldHRpbmdzLgotICAgICAqLwotICAgIHB1YmxpYyBYTUxHcmFtbWFyQ2FjaGluZ0NvbmZpZ3VyYXRpb24oU3ltYm9sVGFibGUgc3ltYm9sVGFibGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxHcmFtbWFyUG9vbCBncmFtbWFyUG9vbCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTENvbXBvbmVudE1hbmFnZXIgcGFyZW50U2V0dGluZ3MpIHsKLSAgICAgICAgc3VwZXIoc3ltYm9sVGFibGUsIGdyYW1tYXJQb29sLCBwYXJlbnRTZXR0aW5ncyk7Ci0KLSAgICAgICAgLy8gUkVWSVNJVDogIG1heSBuZWVkIHRvIGFkZCBzb21lIGZlYXR1cmVzL3Byb3BlcnRpZXMKLSAgICAgICAgLy8gc3BlY2lmaWMgdG8gdGhpcyBjb25maWd1cmF0aW9uIGF0IHNvbWUgcG9pbnQuLi4KLQotICAgICAgICAvLyBhZGQgZGVmYXVsdCByZWNvZ25pemVkIGZlYXR1cmVzCi0gICAgICAgIC8vIHNldCBzdGF0ZSBmb3IgZGVmYXVsdCBmZWF0dXJlcwotICAgICAgICAvLyBhZGQgZGVmYXVsdCByZWNvZ25pemVkIHByb3BlcnRpZXMKLSAgICAgICAgLy8gY3JlYXRlIGFuZCByZWdpc3RlciBtaXNzaW5nIGNvbXBvbmVudHMKLSAgICAgICAgZlNjaGVtYUxvYWRlciA9IG5ldyBYTUxTY2hlbWFMb2FkZXIoZlN5bWJvbFRhYmxlKTsKLSAgICAgICAgZlNjaGVtYUxvYWRlci5zZXRQcm9wZXJ0eShYTUxHUkFNTUFSX1BPT0wsIGZHcmFtbWFyUG9vbCk7Ci0KLSAgICAgICAgLy8gYW5kIHNldCB1cCB0aGUgRFREIGxvYWRlciB0b286Ci0gICAgICAgIGZEVERMb2FkZXIgPSBuZXcgWE1MRFRETG9hZGVyKGZTeW1ib2xUYWJsZSwgZkdyYW1tYXJQb29sKTsKLSAgICB9IC8vIDxpbml0PihTeW1ib2xUYWJsZSxYTUxHcmFtbWFyUG9vbCwgWE1MQ29tcG9uZW50TWFuYWdlcikKLQotICAgIC8vCi0gICAgLy8gUHVibGljIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoKLSAgICAgKiBsb2NrIHRoZSBYTUxHcmFtbWFyUG9vbEltcGwgb2JqZWN0IHNvIHRoYXQgaXQgZG9lcyBub3QKLSAgICAgKiBhY2NlcHQgYW55IG1vcmUgZ3JhbW1hcnMgZnJvbSB0aGUgdmFsaWRhdG9ycy4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBsb2NrR3JhbW1hclBvb2woKSB7Ci0gICAgICAgIGZHcmFtbWFyUG9vbC5sb2NrUG9vbCgpOwotICAgIH0gLy8gbG9ja0dyYW1tYXJQb29sKCkKLQotICAgIC8qCi0gICAgICogY2xlYXIgdGhlIFhNTEdyYW1tYXJQb29sSW1wbCBvYmplY3Qgc28gdGhhdCBpdCBkb2VzIG5vdAotICAgICAqIGNvbnRhaW4gYW55IG1vcmUgZ3JhbW1hcnMuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY2xlYXJHcmFtbWFyUG9vbCgpIHsKLSAgICAgICAgZkdyYW1tYXJQb29sLmNsZWFyKCk7Ci0gICAgfSAvLyBjbGVhckdyYW1tYXJQb29sKCkKLQotICAgIC8qCi0gICAgICogdW5sb2NrIHRoZSBYTUxHcmFtbWFyUG9vbEltcGwgb2JqZWN0IHNvIHRoYXQgaXQKLSAgICAgKiBhY2NlcHRzIG1vcmUgZ3JhbW1hcnMgZnJvbSB0aGUgdmFsaWRhdG9ycy4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB1bmxvY2tHcmFtbWFyUG9vbCgpIHsKLSAgICAgICAgZkdyYW1tYXJQb29sLnVubG9ja1Bvb2woKTsKLSAgICB9IC8vIHVubG9ja0dyYW1tYXJQb29sKCkKLQotICAgIC8qKgotICAgICAqIFBhcnNlIGEgZ3JhbW1hciBmcm9tIGEgbG9jYXRpb24gaWRlbnRpZmllZCBieSBhbiBVUkkuCi0gICAgICogVGhpcyBtZXRob2QgYWxzbyBhZGRzIHRoaXMgZ3JhbW1hciB0byB0aGUgWE1MR3JhbW1hclBvb2wKLSAgICAgKgotICAgICAqIEBwYXJhbSB0eXBlIFRoZSB0eXBlIG9mIHRoZSBncmFtbWFyIHRvIGJlIGNvbnN0cnVjdGVkCi0gICAgICogQHBhcmFtIHVyaSBUaGUgbG9jYXRpb24gb2YgdGhlIGdyYW1tYXIgdG8gYmUgY29uc3RydWN0ZWQuCi0gICAgICogPHN0cm9uZz5UaGUgcGFyc2VyIHdpbGwgbm90IGV4cGFuZCB0aGlzIFVSSSBvciBtYWtlIGl0Ci0gICAgICogYXZhaWxhYmxlIHRvIHRoZSBFbnRpdHlSZXNvbHZlcjwvc3Ryb25nPgotICAgICAqIEByZXR1cm4gVGhlIG5ld2x5IGNyZWF0ZWQgPGNvZGU+R3JhbW1hcjwvY29kZT4uCi0gICAgICogQGV4Y2VwdGlvbiBYTklFeGNlcHRpb24gdGhyb3duIG9uIGFuIGVycm9yIGluIGdyYW1tYXIKLSAgICAgKiBjb25zdHJ1Y3Rpb24KLSAgICAgKiBAZXhjZXB0aW9uIElPRXhjZXB0aW9uIHRocm93biBpZiBhbiBlcnJvciBpcyBlbmNvdW50ZXJlZAotICAgICAqIGluIHJlYWRpbmcgdGhlIGZpbGUKLSAgICAgKi8KLSAgICBwdWJsaWMgR3JhbW1hciBwYXJzZUdyYW1tYXIoU3RyaW5nIHR5cGUsIFN0cmluZyB1cmkpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgIFhNTElucHV0U291cmNlIHNvdXJjZSA9IG5ldyBYTUxJbnB1dFNvdXJjZShudWxsLCB1cmksIG51bGwpOwotICAgICAgICByZXR1cm4gcGFyc2VHcmFtbWFyKHR5cGUsIHNvdXJjZSk7Ci0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBQYXJzZSBhIGdyYW1tYXIgZnJvbSBhIGxvY2F0aW9uIGlkZW50aWZpZWQgYnkgYW4KLSAgICAgKiBYTUxJbnB1dFNvdXJjZS4KLSAgICAgKiBUaGlzIG1ldGhvZCBhbHNvIGFkZHMgdGhpcyBncmFtbWFyIHRvIHRoZSBYTUxHcmFtbWFyUG9vbAotICAgICAqCi0gICAgICogQHBhcmFtIHR5cGUgVGhlIHR5cGUgb2YgdGhlIGdyYW1tYXIgdG8gYmUgY29uc3RydWN0ZWQKLSAgICAgKiBAcGFyYW0gaXMgVGhlIFhNTElucHV0U291cmNlIGNvbnRhaW5pbmcgdGhpcyBncmFtbWFyJ3MKLSAgICAgKiBpbmZvcm1hdGlvbgotICAgICAqIDxzdHJvbmc+SWYgYSBVUkkgaXMgaW5jbHVkZWQgaW4gdGhlIHN5c3RlbUlkIGZpZWxkLCB0aGUgcGFyc2VyIHdpbGwgbm90IGV4cGFuZCB0aGlzIFVSSSBvciBtYWtlIGl0Ci0gICAgICogYXZhaWxhYmxlIHRvIHRoZSBFbnRpdHlSZXNvbHZlcjwvc3Ryb25nPgotICAgICAqIEByZXR1cm4gVGhlIG5ld2x5IGNyZWF0ZWQgPGNvZGU+R3JhbW1hcjwvY29kZT4uCi0gICAgICogQGV4Y2VwdGlvbiBYTklFeGNlcHRpb24gdGhyb3duIG9uIGFuIGVycm9yIGluIGdyYW1tYXIKLSAgICAgKiBjb25zdHJ1Y3Rpb24KLSAgICAgKiBAZXhjZXB0aW9uIElPRXhjZXB0aW9uIHRocm93biBpZiBhbiBlcnJvciBpcyBlbmNvdW50ZXJlZAotICAgICAqIGluIHJlYWRpbmcgdGhlIGZpbGUKLSAgICAgKi8KLSAgICBwdWJsaWMgR3JhbW1hciBwYXJzZUdyYW1tYXIoU3RyaW5nIHR5cGUsIFhNTElucHV0U291cmNlCi0gICAgICAgICAgICAgICAgaXMpIHRocm93cyBYTklFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKLSAgICAgICAgaWYodHlwZS5lcXVhbHMoWE1MR3JhbW1hckRlc2NyaXB0aW9uLlhNTF9TQ0hFTUEpKSB7Ci0gICAgICAgICAgICAvLyBieSBkZWZhdWx0LCBtYWtlIGFsbCBYTUxHcmFtbWFyUG9vbEltcGwncyBzY2hlbWEgZ3JhbW1hcnMgYXZhaWxhYmxlIHRvIGZTY2hlbWFIYW5kbGVyCi0gICAgICAgICAgICByZXR1cm4gcGFyc2VYTUxTY2hlbWEoaXMpOwotICAgICAgICB9IGVsc2UgaWYodHlwZS5lcXVhbHMoWE1MR3JhbW1hckRlc2NyaXB0aW9uLlhNTF9EVEQpKSB7Ci0gICAgICAgICAgICByZXR1cm4gcGFyc2VEVEQoaXMpOwotICAgICAgICB9Ci0gICAgICAgIC8vIGRvbid0IGtub3cgdGhpcyBncmFtbWFyLi4uCi0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0gLy8gcGFyc2VHcmFtbWFyKFN0cmluZywgWE1MSW5wdXRTb3VyY2UpOiAgR3JhbW1hcgotCi0gICAgLy8KLSAgICAvLyBQcm90ZWN0ZWQgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvLyBwYWNrYWdlLXByb3RlY3RlZCBtZXRob2RzCi0KLSAgICAvKiBUaGlzIG1ldGhvZCBwYXJzZXMgYW4gWE1MIFNjaGVtYSBkb2N1bWVudC4KLSAgICAgKiBJdCByZXF1aXJlcyBhIEdyYW1tYXJCdWNrZXQgcGFyYW1ldGVyIHNvIHRoYXQgRE9NQVNCdWlsZGVyIGNhbgotICAgICAqIGV4dHJhY3QgdGhlIGluZm8gaXQgbmVlZHMuCi0gICAgICogVGhlcmVmb3JlLCBidWNrZXQgbXVzdCBub3QgYmUgbnVsbCEKLSAgICAgKi8KLSAgICBTY2hlbWFHcmFtbWFyIHBhcnNlWE1MU2NoZW1hKFhNTElucHV0U291cmNlIGlzKQotICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgIFhNTEVudGl0eVJlc29sdmVyIHJlc29sdmVyID0gZ2V0RW50aXR5UmVzb2x2ZXIoKTsKLSAgICAgICAgaWYocmVzb2x2ZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZlNjaGVtYUxvYWRlci5zZXRFbnRpdHlSZXNvbHZlcihyZXNvbHZlcik7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGZFcnJvclJlcG9ydGVyLmdldE1lc3NhZ2VGb3JtYXR0ZXIoWFNNZXNzYWdlRm9ybWF0dGVyLlNDSEVNQV9ET01BSU4pID09IG51bGwpIHsKLSAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnB1dE1lc3NhZ2VGb3JtYXR0ZXIoWFNNZXNzYWdlRm9ybWF0dGVyLlNDSEVNQV9ET01BSU4sIG5ldyBYU01lc3NhZ2VGb3JtYXR0ZXIoKSk7Ci0gICAgICAgIH0KLSAgICAgICAgZlNjaGVtYUxvYWRlci5zZXRQcm9wZXJ0eShFUlJPUl9SRVBPUlRFUiwgZkVycm9yUmVwb3J0ZXIpOwotCi0gICAgICAgIFN0cmluZyBwcm9wUHJlZml4ID0gQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVg7Ci0gICAgICAgIFN0cmluZyBwcm9wTmFtZSA9IHByb3BQcmVmaXggKyBDb25zdGFudHMuU0NIRU1BX0xPQ0FUSU9OOwotICAgICAgICBmU2NoZW1hTG9hZGVyLnNldFByb3BlcnR5KHByb3BOYW1lLCBnZXRQcm9wZXJ0eShwcm9wTmFtZSkpOwotICAgICAgICBwcm9wTmFtZSA9IHByb3BQcmVmaXggKyBDb25zdGFudHMuU0NIRU1BX05PTlNfTE9DQVRJT047Ci0gICAgICAgIGZTY2hlbWFMb2FkZXIuc2V0UHJvcGVydHkocHJvcE5hbWUsIGdldFByb3BlcnR5KHByb3BOYW1lKSk7Ci0gICAgICAgIHByb3BOYW1lID0gQ29uc3RhbnRzLkpBWFBfUFJPUEVSVFlfUFJFRklYK0NvbnN0YW50cy5TQ0hFTUFfU09VUkNFOwotICAgICAgICBmU2NoZW1hTG9hZGVyLnNldFByb3BlcnR5KHByb3BOYW1lLCBnZXRQcm9wZXJ0eShwcm9wTmFtZSkpOwotICAgICAgICBmU2NoZW1hTG9hZGVyLnNldEZlYXR1cmUoU0NIRU1BX0ZVTExfQ0hFQ0tJTkcsIGdldEZlYXR1cmUoU0NIRU1BX0ZVTExfQ0hFQ0tJTkcpKTsKLQotICAgICAgICAvLyBTaG91bGQgY2hlY2sgd2hldGhlciB0aGUgZ3JhbW1hciB3aXRoIHRoaXMgbmFtZXNwYWNlIGlzIGFscmVhZHkgaW4KLSAgICAgICAgLy8gdGhlIGdyYW1tYXIgcmVzb2x2ZXIuIEJ1dCBzaW5jZSB3ZSBkb24ndCBrbm93IHRoZSB0YXJnZXQgbmFtZXNwYWNlCi0gICAgICAgIC8vIG9mIHRoZSBkb2N1bWVudCBoZXJlLCB3ZSBsZWF2ZSBzdWNoIGNoZWNrIHRvIFhTREhhbmRsZXIKLSAgICAgICAgU2NoZW1hR3JhbW1hciBncmFtbWFyID0gKFNjaGVtYUdyYW1tYXIpZlNjaGVtYUxvYWRlci5sb2FkR3JhbW1hcihpcyk7Ci0gICAgICAgIC8vIGJ5IGRlZmF1bHQsIGhhbmQgaXQgb2ZmIHRvIHRoZSBncmFtbWFyIHBvb2wKLSAgICAgICAgaWYgKGdyYW1tYXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkdyYW1tYXJQb29sLmNhY2hlR3JhbW1hcnMoWE1MR3JhbW1hckRlc2NyaXB0aW9uLlhNTF9TQ0hFTUEsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBHcmFtbWFyW117Z3JhbW1hcn0pOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIGdyYW1tYXI7Ci0KLSAgICB9IC8vIHBhcnNlWE1MU2NoZW1hKFhNTElucHV0U291cmNlKSA6ICBTY2hlbWFHcmFtbWFyCi0KLSAgICAvKiBUaGlzIG1ldGhvZCBwYXJzZXMgYW4gZXh0ZXJuYWwgRFREIGVudGl0eS4KLSAgICAgKi8KLSAgICBEVERHcmFtbWFyIHBhcnNlRFREKFhNTElucHV0U291cmNlIGlzKQotICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgIFhNTEVudGl0eVJlc29sdmVyIHJlc29sdmVyID0gZ2V0RW50aXR5UmVzb2x2ZXIoKTsKLSAgICAgICAgaWYocmVzb2x2ZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkRURExvYWRlci5zZXRFbnRpdHlSZXNvbHZlcihyZXNvbHZlcik7Ci0gICAgICAgIH0KLSAgICAgICAgZkRURExvYWRlci5zZXRQcm9wZXJ0eShFUlJPUl9SRVBPUlRFUiwgZkVycm9yUmVwb3J0ZXIpOwotCi0gICAgICAgIC8vIFNob3VsZCBjaGVjayB3aGV0aGVyIHRoZSBncmFtbWFyIHdpdGggdGhpcyBuYW1lc3BhY2UgaXMgYWxyZWFkeSBpbgotICAgICAgICAvLyB0aGUgZ3JhbW1hciByZXNvbHZlci4gQnV0IHNpbmNlIHdlIGRvbid0IGtub3cgdGhlIHRhcmdldCBuYW1lc3BhY2UKLSAgICAgICAgLy8gb2YgdGhlIGRvY3VtZW50IGhlcmUsIHdlIGxlYXZlIHN1Y2ggY2hlY2sgdG8gdGhlIGFwcGxpY2F0aW9uLi4uCi0gICAgICAgIERUREdyYW1tYXIgZ3JhbW1hciA9IChEVERHcmFtbWFyKWZEVERMb2FkZXIubG9hZEdyYW1tYXIoaXMpOwotICAgICAgICAvLyBieSBkZWZhdWx0LCBoYW5kIGl0IG9mZiB0byB0aGUgZ3JhbW1hciBwb29sCi0gICAgICAgIGlmIChncmFtbWFyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZHcmFtbWFyUG9vbC5jYWNoZUdyYW1tYXJzKFhNTEdyYW1tYXJEZXNjcmlwdGlvbi5YTUxfRFRELAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgR3JhbW1hcltde2dyYW1tYXJ9KTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBncmFtbWFyOwotCi0gICAgfSAvLyBwYXJzZVhNTERURChYTUxJbnB1dFNvdXJjZSkgOiAgRFRER3JhbW1hcgotCi0KLX0gLy8gY2xhc3MgWE1MR3JhbW1hckNhY2hpbmdDb25maWd1cmF0aW9uCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9wYXJzZXJzL1hNTEdyYW1tYXJQYXJzZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3BhcnNlcnMvWE1MR3JhbW1hclBhcnNlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3ZDg4NzgxLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3BhcnNlcnMvWE1MR3JhbW1hclBhcnNlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTQgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnBhcnNlcnM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5EVEREVkZhY3Rvcnk7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlN5bWJvbFRhYmxlOwotCi0vKioKLSAqIEB2ZXJzaW9uICRJZDogWE1MR3JhbW1hclBhcnNlci5qYXZhLHYgMS42IDIwMTAtMTEtMDEgMDQ6NDA6MTAgam9laHcgRXhwICQKLSAqLwotcHVibGljIGFic3RyYWN0IGNsYXNzIFhNTEdyYW1tYXJQYXJzZXIKLSAgICBleHRlbmRzIFhNTFBhcnNlciB7Ci0KLSAgICAvLwotICAgIC8vIERhdGEKLSAgICAvLwotCi0gICAgLyoqIGZEYXRhdHlwZVZhbGlkYXRvckZhY3RvcnkgKi8KLSAgICBwcm90ZWN0ZWQgRFRERFZGYWN0b3J5IGZEYXRhdHlwZVZhbGlkYXRvckZhY3Rvcnk7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0cnVjdG9ycwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3QgYW4gWE1MR3JhbW1hclBhcnNlciB3aXRoIHRoZSBzcGVjaWZpZWQgc3ltYm9sIHRhYmxlCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc3ltYm9sVGFibGUKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgWE1MR3JhbW1hclBhcnNlcihTeW1ib2xUYWJsZSBzeW1ib2xUYWJsZSkgewotICAgICAgICBzdXBlcihuZXcgWEluY2x1ZGVBd2FyZVBhcnNlckNvbmZpZ3VyYXRpb24oKSk7Ci0gICAgICAgIGZDb25maWd1cmF0aW9uLnNldFByb3BlcnR5KENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYK0NvbnN0YW50cy5TWU1CT0xfVEFCTEVfUFJPUEVSVFksIHN5bWJvbFRhYmxlKTsKLSAgICB9Ci0KLX0gLy8gY2xhc3MgWE1MR3JhbW1hclBhcnNlcgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvcGFyc2Vycy9YTUxHcmFtbWFyUHJlcGFyc2VyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9wYXJzZXJzL1hNTEdyYW1tYXJQcmVwYXJzZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOWZkNjZlNS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9wYXJzZXJzL1hNTEdyYW1tYXJQcmVwYXJzZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDM0MSArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDE1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICovCi0vKgotICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCi0gKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKLSAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KLSAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCi0gKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAotICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5wYXJzZXJzOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLkNvbnN0YW50czsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuWE1MRW50aXR5TWFuYWdlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuWE1MRXJyb3JSZXBvcnRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuU3ltYm9sVGFibGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlscy5PYmplY3RGYWN0b3J5OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhOSUV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5ncmFtbWFycy5HcmFtbWFyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLmdyYW1tYXJzLlhNTEdyYW1tYXJEZXNjcmlwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5ncmFtbWFycy5YTUxHcmFtbWFyTG9hZGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLmdyYW1tYXJzLlhNTEdyYW1tYXJQb29sOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxFbnRpdHlSZXNvbHZlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MRXJyb3JIYW5kbGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxJbnB1dFNvdXJjZTsKLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKLWltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwotaW1wb3J0IGphdmEudXRpbC5NYXA7Ci0KLS8qKgotICogPHA+IFRoaXMgY2xhc3MgcHJvdmlkZXMgYW4gZWFzeSB3YXkgZm9yIGEgdXNlciB0byBwcmVwYXJzZSBncmFtbWFycwotICogb2YgdmFyaW91cyB0eXBlcy4gIEJ5IGRlZmF1bHQsIGl0IGtub3dzIGhvdyB0byBwcmVwYXJzZSBleHRlcm5hbAotICogRFREJ3MgYW5kIHNjaGVtYXM7IGl0IHByb3ZpZGVzIGFuIGVhc3kgd2F5IGZvciB1c2VyIGFwcGxpY2F0aW9ucyB0bwotICogcmVnaXN0ZXIgY2xhc3NlcyB0aGF0IGtub3cgaG93IHRvIHBhcnNlIGFkZGl0aW9uYWwgZ3JhbW1hciB0eXBlcy4KLSAqIEJ5IGRlZmF1bHQsIGl0IGRvZXMgbm8gZ3JhbW1hciBjYWNoaW5nOyBidXQgaXQgcHJvdmlkZXMgd2F5cyBmb3IKLSAqIHVzZXIgYXBwbGljYXRpb25zIHRvIGRvIHNvLgotICoKLSAqIEBhdXRob3IgTmVpbCBHcmFoYW0sIElCTQotICoKLSAqIEB2ZXJzaW9uICRJZDogWE1MR3JhbW1hclByZXBhcnNlci5qYXZhLHYgMS43IDIwMTAtMTEtMDEgMDQ6NDA6MTAgam9laHcgRXhwICQKLSAqLwotcHVibGljIGNsYXNzIFhNTEdyYW1tYXJQcmVwYXJzZXIgewotCi0gICAgLy8KLSAgICAvLyBDb25zdGFudHMKLSAgICAvLwotCi0gICAgLy8gZmVhdHVyZTogIGNvbnRpbnVlLWFmdGVyLWZhdGFsLWVycm9yCi0gICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgU3RyaW5nIENPTlRJTlVFX0FGVEVSX0ZBVEFMX0VSUk9SID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5DT05USU5VRV9BRlRFUl9GQVRBTF9FUlJPUl9GRUFUVVJFOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IHN5bWJvbCB0YWJsZS4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBTWU1CT0xfVEFCTEUgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5TWU1CT0xfVEFCTEVfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogZXJyb3IgcmVwb3J0ZXIuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJST1JfUkVQT1JURVIgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5FUlJPUl9SRVBPUlRFUl9QUk9QRVJUWTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBlcnJvciBoYW5kbGVyLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUk9SX0hBTkRMRVIgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5FUlJPUl9IQU5ETEVSX1BST1BFUlRZOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IGVudGl0eSByZXNvbHZlci4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBFTlRJVFlfUkVTT0xWRVIgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5FTlRJVFlfUkVTT0xWRVJfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogZ3JhbW1hciBwb29sIC4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBHUkFNTUFSX1BPT0wgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5YTUxHUkFNTUFSX1BPT0xfUFJPUEVSVFk7Ci0KLSAgICAvLyB0aGUgImJ1aWx0LWluIiBncmFtbWFyIGxvYWRlcnMKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBNYXA8U3RyaW5nLCBTdHJpbmc+IEtOT1dOX0xPQURFUlM7Ci0KLSAgICBzdGF0aWMgewotICAgICAgICBNYXA8U3RyaW5nLCBTdHJpbmc+IGxvYWRlcnMgPSBuZXcgSGFzaE1hcDw+KCk7Ci0gICAgICAgIGxvYWRlcnMucHV0KFhNTEdyYW1tYXJEZXNjcmlwdGlvbi5YTUxfU0NIRU1BLAotICAgICAgICAgICAgImNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5YTUxTY2hlbWFMb2FkZXIiKTsKLSAgICAgICAgbG9hZGVycy5wdXQoWE1MR3JhbW1hckRlc2NyaXB0aW9uLlhNTF9EVEQsCi0gICAgICAgICAgICAiY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR0ZC5YTUxEVERMb2FkZXIiKTsKLSAgICAgICAgS05PV05fTE9BREVSUyA9IENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZU1hcChsb2FkZXJzKTsKLSAgICB9Ci0KLSAgICAvKiogUmVjb2duaXplZCBwcm9wZXJ0aWVzLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZ1tdIFJFQ09HTklaRURfUFJPUEVSVElFUyA9IHsKLSAgICAgICAgU1lNQk9MX1RBQkxFLAotICAgICAgICBFUlJPUl9SRVBPUlRFUiwKLSAgICAgICAgRVJST1JfSEFORExFUiwKLSAgICAgICAgRU5USVRZX1JFU09MVkVSLAotICAgICAgICBHUkFNTUFSX1BPT0wsCi0gICAgfTsKLQotICAgIC8vIERhdGEKLSAgICBwcm90ZWN0ZWQgU3ltYm9sVGFibGUgZlN5bWJvbFRhYmxlOwotICAgIHByb3RlY3RlZCBYTUxFcnJvclJlcG9ydGVyIGZFcnJvclJlcG9ydGVyOwotICAgIHByb3RlY3RlZCBYTUxFbnRpdHlSZXNvbHZlciBmRW50aXR5UmVzb2x2ZXI7Ci0gICAgcHJvdGVjdGVkIFhNTEdyYW1tYXJQb29sIGZHcmFtbWFyUG9vbDsKLQotICAgIHByb3RlY3RlZCBMb2NhbGUgZkxvY2FsZTsKLQotICAgIC8vIE1hcCBob2xkaW5nIG91ciBsb2FkZXJzCi0gICAgcHJpdmF0ZSBNYXA8U3RyaW5nLCBYTUxHcmFtbWFyTG9hZGVyPiBmTG9hZGVyczsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKiBEZWZhdWx0IGNvbnN0cnVjdG9yLiAqLwotICAgIHB1YmxpYyBYTUxHcmFtbWFyUHJlcGFyc2VyKCkgewotICAgICAgICB0aGlzKG5ldyBTeW1ib2xUYWJsZSgpKTsKLSAgICB9IC8vIDxpbml0PigpCi0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RzIGEgcHJlcGFyc2VyIHVzaW5nIHRoZSBzcGVjaWZpZWQgc3ltYm9sIHRhYmxlLgotICAgICAqCi0gICAgICogQHBhcmFtIHN5bWJvbFRhYmxlIFRoZSBzeW1ib2wgdGFibGUgdG8gdXNlLgotICAgICAqLwotICAgIHB1YmxpYyBYTUxHcmFtbWFyUHJlcGFyc2VyIChTeW1ib2xUYWJsZSBzeW1ib2xUYWJsZSkgewotICAgICAgICBmU3ltYm9sVGFibGUgPSBzeW1ib2xUYWJsZTsKLQotICAgICAgICBmTG9hZGVycyA9IG5ldyBIYXNoTWFwPD4oKTsKLSAgICAgICAgZkVycm9yUmVwb3J0ZXIgPSBuZXcgWE1MRXJyb3JSZXBvcnRlcigpOwotICAgICAgICBzZXRMb2NhbGUoTG9jYWxlLmdldERlZmF1bHQoKSk7Ci0gICAgICAgIGZFbnRpdHlSZXNvbHZlciA9IG5ldyBYTUxFbnRpdHlNYW5hZ2VyKCk7Ci0gICAgICAgIC8vIHRob3NlIGFyZSBhbGwgdGhlIGJhc2ljIHByb3BlcnRpZXMuLi4KLSAgICB9IC8vIDxpbml0PihTeW1ib2xUYWJsZSkKLQotICAgIC8vCi0gICAgLy8gUHVibGljIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoKLSAgICAqIFJlZ2lzdGVyIGEgdHlwZSBvZiBncmFtbWFyIHRvIG1ha2UgaXQgcHJlcGFyc2FibGUuICAgSWYKLSAgICAqIHRoZSBzZWNvbmQgcGFyYW1ldGVyIGlzIG51bGwsIHRoZSBwYXJzZXIgd2lsbCB1c2UgaXRzICBidWlsdC1pbgotICAgICogZmFjaWxpdGllcyBmb3IgdGhhdCBncmFtbWFyIHR5cGUuCi0gICAgKiBUaGlzIHNob3VsZCBiZSBjYWxsZWQgYnkgdGhlIGFwcGxpY2F0aW9uIGltbWVkaWF0ZWx5Ci0gICAgKiBhZnRlciBjcmVhdGluZyB0aGlzIG9iamVjdCBhbmQgYmVmb3JlIGluaXRpYWxpemluZyBhbnkgcHJvcGVydGllcy9mZWF0dXJlcy4KLSAgICAqIEBwYXJhbSB0eXBlICAgVVJJIGlkZW50aWZ5aW5nIHRoZSB0eXBlIG9mIHRoZSBncmFtbWFyCi0gICAgKiBAcGFyYW0gbG9hZGVyIGFuIG9iamVjdCBjYXBhYmxlIG9mIHByZXBhcnNpbmcgdGhhdCB0eXBlOyBudWxsIGlmIHRoZSBwcHJlcGFyc2VyIHNob3VsZCB1c2UgYnVpbHQtaW4ga25vd2xlZGdlLgotICAgICogQHJldHVybiB0cnVlIGlmIHN1Y2Nlc3NmdWw7IGZhbHNlIGlmIG5vIGJ1aWx0LWluIGtub3dsZWRnZSBvZgotICAgICogICAgICAgdGhlIHR5cGUgb3IgaWYgdW5hYmxlIHRvIGluc3RhbnRpYXRlIHRoZSBzdHJpbmcgd2Uga25vdyBhYm91dAotICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gcmVnaXN0ZXJQcmVwYXJzZXIoU3RyaW5nIGdyYW1tYXJUeXBlLCBYTUxHcmFtbWFyTG9hZGVyIGxvYWRlcikgewotICAgICAgICBpZihsb2FkZXIgPT0gbnVsbCkgeyAvLyBub25lIHNwZWNpZmllZCEKLSAgICAgICAgICAgIGlmKEtOT1dOX0xPQURFUlMuY29udGFpbnNLZXkoZ3JhbW1hclR5cGUpKSB7Ci0gICAgICAgICAgICAgICAgLy8gZ290IG9uZTsganVzdCBpbnN0YW50aWF0ZSBpdC4uLgotICAgICAgICAgICAgICAgIFN0cmluZyBsb2FkZXJOYW1lID0gKFN0cmluZylLTk9XTl9MT0FERVJTLmdldChncmFtbWFyVHlwZSk7Ci0gICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgWE1MR3JhbW1hckxvYWRlciBnbCA9IChYTUxHcmFtbWFyTG9hZGVyKShPYmplY3RGYWN0b3J5Lm5ld0luc3RhbmNlKGxvYWRlck5hbWUsIHRydWUpKTsKLSAgICAgICAgICAgICAgICAgICAgZkxvYWRlcnMucHV0KGdyYW1tYXJUeXBlLCBnbCk7Ci0gICAgICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotICAgICAgICAvLyB3ZXJlIGdpdmVuIG9uZQotICAgICAgICBmTG9hZGVycy5wdXQoZ3JhbW1hclR5cGUsIGxvYWRlcik7Ci0gICAgICAgIHJldHVybiB0cnVlOwotICAgIH0gLy8gcmVnaXN0ZXJQcmVwYXJzZXIoU3RyaW5nLCBYTUxHcmFtbWFyTG9hZGVyKTogIGJvb2xlYW4KLQotICAgIC8qKgotICAgICAqIFBhcnNlIGEgZ3JhbW1hciBmcm9tIGEgbG9jYXRpb24gaWRlbnRpZmllZCBieSBhbgotICAgICAqIFhNTElucHV0U291cmNlLgotICAgICAqIFRoaXMgbWV0aG9kIGFsc28gYWRkcyB0aGlzIGdyYW1tYXIgdG8gdGhlIFhNTEdyYW1tYXJQb29sCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdHlwZSBUaGUgdHlwZSBvZiB0aGUgZ3JhbW1hciB0byBiZSBjb25zdHJ1Y3RlZAotICAgICAqIEBwYXJhbSBpcyBUaGUgWE1MSW5wdXRTb3VyY2UgY29udGFpbmluZyB0aGlzIGdyYW1tYXIncwotICAgICAqIGluZm9ybWF0aW9uCi0gICAgICogPHN0cm9uZz5JZiBhIFVSSSBpcyBpbmNsdWRlZCBpbiB0aGUgc3lzdGVtSWQgZmllbGQsIHRoZSBwYXJzZXIgd2lsbCBub3QgZXhwYW5kIHRoaXMgVVJJIG9yIG1ha2UgaXQKLSAgICAgKiBhdmFpbGFibGUgdG8gdGhlIEVudGl0eVJlc29sdmVyPC9zdHJvbmc+Ci0gICAgICogQHJldHVybiBUaGUgbmV3bHkgY3JlYXRlZCA8Y29kZT5HcmFtbWFyPC9jb2RlPi4KLSAgICAgKiBAZXhjZXB0aW9uIFhOSUV4Y2VwdGlvbiB0aHJvd24gb24gYW4gZXJyb3IgaW4gZ3JhbW1hcgotICAgICAqIGNvbnN0cnVjdGlvbgotICAgICAqIEBleGNlcHRpb24gSU9FeGNlcHRpb24gdGhyb3duIGlmIGFuIGVycm9yIGlzIGVuY291bnRlcmVkCi0gICAgICogaW4gcmVhZGluZyB0aGUgZmlsZQotICAgICAqLwotICAgIHB1YmxpYyBHcmFtbWFyIHByZXBhcnNlR3JhbW1hcihTdHJpbmcgdHlwZSwgWE1MSW5wdXRTb3VyY2UKLSAgICAgICAgICAgICAgICBpcykgdGhyb3dzIFhOSUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewotICAgICAgICBpZihmTG9hZGVycy5jb250YWluc0tleSh0eXBlKSkgewotICAgICAgICAgICAgWE1MR3JhbW1hckxvYWRlciBnbCA9IGZMb2FkZXJzLmdldCh0eXBlKTsKLSAgICAgICAgICAgIC8vIG1ha2Ugc3VyZSBnbCdzIGJlZW4gc2V0IHVwIHdpdGggYWxsIHRoZSAiYmFzaWMiIHByb3BlcnRpZXM6Ci0gICAgICAgICAgICBnbC5zZXRQcm9wZXJ0eShTWU1CT0xfVEFCTEUsIGZTeW1ib2xUYWJsZSk7Ci0gICAgICAgICAgICBnbC5zZXRQcm9wZXJ0eShFTlRJVFlfUkVTT0xWRVIsIGZFbnRpdHlSZXNvbHZlcik7Ci0gICAgICAgICAgICBnbC5zZXRQcm9wZXJ0eShFUlJPUl9SRVBPUlRFUiwgZkVycm9yUmVwb3J0ZXIpOwotICAgICAgICAgICAgLy8gcG90ZW50aWFsbHksIG5vdCBhbGwgd2lsbCBzdXBwb3J0IHRoaXMgb25lLi4uCi0gICAgICAgICAgICBpZihmR3JhbW1hclBvb2wgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgIGdsLnNldFByb3BlcnR5KEdSQU1NQVJfUE9PTCwgZkdyYW1tYXJQb29sKTsKLSAgICAgICAgICAgICAgICB9IGNhdGNoKEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIHRvbyBiYWQuLi4KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gZ2wubG9hZEdyYW1tYXIoaXMpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0gLy8gcHJlcGFyc2VHcmFtbWFyKFN0cmluZywgWE1MSW5wdXRTb3VyY2UpOiAgR3JhbW1hcgotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSBsb2NhbGUgdG8gdXNlIGZvciBtZXNzYWdlcy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBsb2NhbGUgVGhlIGxvY2FsZSBvYmplY3QgdG8gdXNlIGZvciBsb2NhbGl6YXRpb24gb2YgbWVzc2FnZXMuCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIFhOSUV4Y2VwdGlvbiBUaHJvd24gaWYgdGhlIHBhcnNlciBkb2VzIG5vdCBzdXBwb3J0IHRoZQotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIHNwZWNpZmllZCBsb2NhbGUuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0TG9jYWxlKExvY2FsZSBsb2NhbGUpIHsKLSAgICAgICAgZkxvY2FsZSA9IGxvY2FsZTsKLSAgICAgICAgZkVycm9yUmVwb3J0ZXIuc2V0TG9jYWxlKGxvY2FsZSk7Ci0gICAgfSAvLyBzZXRMb2NhbGUoTG9jYWxlKQotCi0gICAgLyoqIFJldHVybiB0aGUgTG9jYWxlIHRoZSBYTUxHcmFtbWFyTG9hZGVyIGlzIHVzaW5nLiAqLwotICAgIHB1YmxpYyBMb2NhbGUgZ2V0TG9jYWxlKCkgewotICAgICAgICByZXR1cm4gZkxvY2FsZTsKLSAgICB9IC8vIGdldExvY2FsZSgpOiAgTG9jYWxlCi0KLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIGVycm9yIGhhbmRsZXIuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZXJyb3JIYW5kbGVyIFRoZSBlcnJvciBoYW5kbGVyLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEVycm9ySGFuZGxlcihYTUxFcnJvckhhbmRsZXIgZXJyb3JIYW5kbGVyKSB7Ci0gICAgICAgIGZFcnJvclJlcG9ydGVyLnNldFByb3BlcnR5KEVSUk9SX0hBTkRMRVIsIGVycm9ySGFuZGxlcik7Ci0gICAgfSAvLyBzZXRFcnJvckhhbmRsZXIoWE1MRXJyb3JIYW5kbGVyKQotCi0gICAgLyoqIFJldHVybnMgdGhlIHJlZ2lzdGVyZWQgZXJyb3IgaGFuZGxlci4gICovCi0gICAgcHVibGljIFhNTEVycm9ySGFuZGxlciBnZXRFcnJvckhhbmRsZXIoKSB7Ci0gICAgICAgIHJldHVybiBmRXJyb3JSZXBvcnRlci5nZXRFcnJvckhhbmRsZXIoKTsKLSAgICB9IC8vIGdldEVycm9ySGFuZGxlcigpOiAgWE1MRXJyb3JIYW5kbGVyCi0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSBlbnRpdHkgcmVzb2x2ZXIuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZW50aXR5UmVzb2x2ZXIgVGhlIG5ldyBlbnRpdHkgcmVzb2x2ZXIuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RW50aXR5UmVzb2x2ZXIoWE1MRW50aXR5UmVzb2x2ZXIgZW50aXR5UmVzb2x2ZXIpIHsKLSAgICAgICAgZkVudGl0eVJlc29sdmVyID0gZW50aXR5UmVzb2x2ZXI7Ci0gICAgfSAvLyBzZXRFbnRpdHlSZXNvbHZlcihYTUxFbnRpdHlSZXNvbHZlcikKLQotICAgIC8qKiBSZXR1cm5zIHRoZSByZWdpc3RlcmVkIGVudGl0eSByZXNvbHZlci4gICovCi0gICAgcHVibGljIFhNTEVudGl0eVJlc29sdmVyIGdldEVudGl0eVJlc29sdmVyKCkgewotICAgICAgICByZXR1cm4gZkVudGl0eVJlc29sdmVyOwotICAgIH0gLy8gZ2V0RW50aXR5UmVzb2x2ZXIoKTogIFhNTEVudGl0eVJlc29sdmVyCi0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSBncmFtbWFyIHBvb2wuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZ3JhbW1hclBvb2wgVGhlIG5ldyBncmFtbWFyIHBvb2wuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0R3JhbW1hclBvb2woWE1MR3JhbW1hclBvb2wgZ3JhbW1hclBvb2wpIHsKLSAgICAgICAgZkdyYW1tYXJQb29sID0gZ3JhbW1hclBvb2w7Ci0gICAgfSAvLyBzZXRHcmFtbWFyUG9vbChYTUxHcmFtbWFyUG9vbCkKLQotICAgIC8qKiBSZXR1cm5zIHRoZSByZWdpc3RlcmVkIGdyYW1tYXIgcG9vbC4gICovCi0gICAgcHVibGljIFhNTEdyYW1tYXJQb29sIGdldEdyYW1tYXJQb29sKCkgewotICAgICAgICByZXR1cm4gZkdyYW1tYXJQb29sOwotICAgIH0gLy8gZ2V0R3JhbW1hclBvb2woKTogIFhNTEdyYW1tYXJQb29sCi0KLSAgICAvLyBpdCdzIHBvc3NpYmxlIHRoZSBhcHBsaWNhdGlvbiBtYXkgd2FudCBhY2Nlc3MgdG8gYSBjZXJ0YWluIGxvYWRlciB0byBkbwotICAgIC8vIHNvbWUgY3VzdG9tIHdvcmsuCi0gICAgcHVibGljIFhNTEdyYW1tYXJMb2FkZXIgZ2V0TG9hZGVyKFN0cmluZyB0eXBlKSB7Ci0gICAgICAgIHJldHVybiBmTG9hZGVycy5nZXQodHlwZSk7Ci0gICAgfSAvLyBnZXRMb2FkZXIoU3RyaW5nKTogIFhNTEdyYW1tYXJMb2FkZXIKLQotICAgIC8vIHNldCBhIGZlYXR1cmUuICBUaGlzIG1ldGhvZCB0cmllcyB0byBzZXQgaXQgb24gYWxsCi0gICAgLy8gcmVnaXN0ZXJlZCBsb2FkZXJzOyBpdCBlYXRzIGFueSByZXN1bHRpbmcgZXhjZXB0aW9ucy4gIElmCi0gICAgLy8gYW4gYXBwIG5lZWRzIHRvIGtub3cgaWYgYSBwYXJ0aWN1bGFyIGZlYXR1cmUgaXMgc3VwcG9ydGVkCi0gICAgLy8gYnkgYSBncmFtbWFyIGxvYWRlciBvZiBhIHBhcnRpY3VsYXIgdHlwZSwgaXQgd2lsbCBoYXZlCi0gICAgLy8gdG8gcmV0cmlldmUgdGhhdCBsb2FkZXIgYW5kIHVzZSB0aGUgbG9hZGVyJ3Mgc2V0RmVhdHVyZSBtZXRob2QuCi0gICAgcHVibGljIHZvaWQgc2V0RmVhdHVyZShTdHJpbmcgZmVhdHVyZUlkLCBib29sZWFuIHZhbHVlKSB7Ci0gICAgICAgIGZvciAoTWFwLkVudHJ5PFN0cmluZywgWE1MR3JhbW1hckxvYWRlcj4gZW50cnkgOiBmTG9hZGVycy5lbnRyeVNldCgpKSB7Ci0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIFhNTEdyYW1tYXJMb2FkZXIgZ2wgPSBlbnRyeS5nZXRWYWx1ZSgpOwotICAgICAgICAgICAgICAgIGdsLnNldEZlYXR1cmUoZmVhdHVyZUlkLCB2YWx1ZSk7Ci0gICAgICAgICAgICB9IGNhdGNoKEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgLy8gZWF0IGl0IHVwLi4uCi0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgLy8gc2luY2Ugb3VyIGVycm9yIHJlcG9ydGVyIGlzIGEgcHJvcGVydHkgd2Ugc2V0IGxhdGVyLAotICAgICAgICAvLyBtYWtlIHN1cmUgZmVhdHVyZXMgaXQgdW5kZXJzdGFuZHMgYXJlIGFsc28gc2V0LgotICAgICAgICBpZihmZWF0dXJlSWQuZXF1YWxzKENPTlRJTlVFX0FGVEVSX0ZBVEFMX0VSUk9SKSkgewotICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIuc2V0RmVhdHVyZShDT05USU5VRV9BRlRFUl9GQVRBTF9FUlJPUiwgdmFsdWUpOwotICAgICAgICB9Ci0gICAgfSAvL3NldEZlYXR1cmUoU3RyaW5nLCBib29sZWFuKQotCi0gICAgLy8gc2V0IGEgcHJvcGVydHkuICBUaGlzIG1ldGhvZCB0cmllcyB0byBzZXQgaXQgb24gYWxsCi0gICAgLy8gcmVnaXN0ZXJlZCBsb2FkZXJzOyBpdCBlYXRzIGFueSByZXN1bHRpbmcgZXhjZXB0aW9ucy4gIElmCi0gICAgLy8gYW4gYXBwIG5lZWRzIHRvIGtub3cgaWYgYSBwYXJ0aWN1bGFyIHByb3BlcnR5IGlzIHN1cHBvcnRlZAotICAgIC8vIGJ5IGEgZ3JhbW1hciBsb2FkZXIgb2YgYSBwYXJ0aWN1bGFyIHR5cGUsIGl0IHdpbGwgaGF2ZQotICAgIC8vIHRvIHJldHJpZXZlIHRoYXQgbG9hZGVyIGFuZCB1c2UgdGhlIGxvYWRlcidzIHNldFByb3BlcnR5IG1ldGhvZC4KLSAgICAvLyA8cD4gPHN0cm9uZz5BbiBhcHBsaWNhdGlvbiBzaG91bGQgdXNlIHRoZSBleHBsaWNpdCBtZXRob2QKLSAgICAvLyBpbiB0aGlzIGNsYXNzIHRvIHNldCAic3RhbmRhcmQiIHByb3BlcnRpZXMgbGlrZSBlcnJvciBoYW5kbGVyIGV0Yy48L3N0cm9uZz4KLSAgICBwdWJsaWMgdm9pZCBzZXRQcm9wZXJ0eShTdHJpbmcgcHJvcElkLCBPYmplY3QgdmFsdWUpIHsKLSAgICAgICAgZm9yIChNYXAuRW50cnk8U3RyaW5nLCBYTUxHcmFtbWFyTG9hZGVyPiBlbnRyeSA6IGZMb2FkZXJzLmVudHJ5U2V0KCkpIHsKLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgWE1MR3JhbW1hckxvYWRlciBnbCA9IGVudHJ5LmdldFZhbHVlKCk7Ci0gICAgICAgICAgICAgICAgZ2wuc2V0UHJvcGVydHkocHJvcElkLCB2YWx1ZSk7Ci0gICAgICAgICAgICB9IGNhdGNoKEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgLy8gZWF0IGl0IHVwLi4uCi0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9IC8vc2V0UHJvcGVydHkoU3RyaW5nLCBPYmplY3QpCi0KLSAgICAvLyBnZXQgc3RhdHVzIG9mIGZlYXR1cmUgaW4gYSBwYXJ0aWN1bGFyIGxvYWRlci4gIFRoaXMKLSAgICAvLyBjYXRjaGVzIG5vIGV4Y2VwdGlvbnMtLWluY2x1ZGluZyBOUEUncy0tc28gdGhlIGFwcGxpY2F0aW9uIGhhZAotICAgIC8vIGJldHRlciBtYWtlIHN1cmUgdGhlIGxvYWRlciBleGlzdHMgYW5kIGtub3dzIGFib3V0IHRoaXMgZmVhdHVyZS4KLSAgICAvLyBAcGFyYW0gdHlwZSB0eXBlIG9mIGdyYW1tYXIgdG8gbG9vayBmb3IgdGhlIGZlYXR1cmUgaW4uCi0gICAgLy8gQHBhcmFtIGZlYXR1cmVJZCB0aGUgZmVhdHVyZSBzdHJpbmcgdG8gcXVlcnkuCi0gICAgLy8gQHJldHVybiB0aGUgdmFsdWUgb2YgdGhlIGZlYXR1cmUuCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0RmVhdHVyZShTdHJpbmcgdHlwZSwgU3RyaW5nIGZlYXR1cmVJZCkgewotICAgICAgICBYTUxHcmFtbWFyTG9hZGVyIGdsID0gZkxvYWRlcnMuZ2V0KHR5cGUpOwotICAgICAgICByZXR1cm4gZ2wuZ2V0RmVhdHVyZShmZWF0dXJlSWQpOwotICAgIH0gLy8gZ2V0RmVhdHVyZSAoU3RyaW5nLCBTdHJpbmcpOiAgYm9vbGVhbgotCi0gICAgLy8gZ2V0IHN0YXR1cyBvZiBwcm9wZXJ0eSBpbiBhIHBhcnRpY3VsYXIgbG9hZGVyLiAgVGhpcwotICAgIC8vIGNhdGNoZXMgbm8gZXhjZXB0aW9ucy0taW5jbHVkaW5nIE5QRSdzLS1zbyB0aGUgYXBwbGljYXRpb24gaGFkCi0gICAgLy8gYmV0dGVyIG1ha2Ugc3VyZSB0aGUgbG9hZGVyIGV4aXN0cyBhbmQga25vd3MgYWJvdXQgdGhpcyBwcm9wZXJ0eS4KLSAgICAvLyA8c3Ryb25nPkZvciBzdGFuZGFyZCBwcm9wZXJ0aWVzLS10aGF0IHdpbGwgYmUgc3VwcG9ydGVkCi0gICAgLy8gYnkgYWxsIGxvYWRlcnMtLXRoZSBzcGVjaWZpYyBtZXRob2RzIHNob3VsZCBiZSBxdWVyaWVkITwvc3Ryb25nPgotICAgIC8vIEBwYXJhbSB0eXBlIHR5cGUgb2YgZ3JhbW1hciB0byBsb29rIGZvciB0aGUgcHJvcGVydHkgaW4uCi0gICAgLy8gQHBhcmFtIHByb3BlcnR5SWQgdGhlIHByb3BlcnR5IHN0cmluZyB0byBxdWVyeS4KLSAgICAvLyBAcmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgcHJvcGVydHkuCi0gICAgcHVibGljIE9iamVjdCBnZXRQcm9wZXJ0eShTdHJpbmcgdHlwZSwgU3RyaW5nIHByb3BlcnR5SWQpIHsKLSAgICAgICAgWE1MR3JhbW1hckxvYWRlciBnbCA9IGZMb2FkZXJzLmdldCh0eXBlKTsKLSAgICAgICAgcmV0dXJuIGdsLmdldFByb3BlcnR5KHByb3BlcnR5SWQpOwotICAgIH0gLy8gZ2V0UHJvcGVydHkoU3RyaW5nLCBTdHJpbmcpOiAgT2JqZWN0Ci19IC8vIGNsYXNzIFhNTEdyYW1tYXJQcmVwYXJzZXIKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3BhcnNlcnMvWE1MUGFyc2VyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9wYXJzZXJzL1hNTFBhcnNlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA5NzBjYzUxLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3BhcnNlcnMvWE1MUGFyc2VyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNTUgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnBhcnNlcnM7Ci0KLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLkNvbnN0YW50czsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWxzLlhNTFNlY3VyaXR5TWFuYWdlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWxzLlhNTFNlY3VyaXR5UHJvcGVydHlNYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhOSUV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MSW5wdXRTb3VyY2U7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTFBhcnNlckNvbmZpZ3VyYXRpb247Ci0KLWltcG9ydCBvcmcueG1sLnNheC5TQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbjsKLQotLyoqCi0gKiBCYXNlIGNsYXNzIG9mIGFsbCBYTUwtcmVsYXRlZCBwYXJzZXJzLgotICogPHA+Ci0gKiBJbiBhZGRpdGlvbiB0byB0aGUgZmVhdHVyZXMgYW5kIHByb3BlcnRpZXMgcmVjb2duaXplZCBieSB0aGUgcGFyc2VyCi0gKiBjb25maWd1cmF0aW9uLCB0aGlzIHBhcnNlciByZWNvZ25pemVzIHRoZXNlIGFkZGl0aW9uYWwgZmVhdHVyZXMgYW5kCi0gKiBwcm9wZXJ0aWVzOgotICogPHVsPgotICogPGxpPlByb3BlcnRpZXMKLSAqICA8dWw+Ci0gKiAgIDxsaT5odHRwOi8vYXBhY2hlLm9yZy94bWwvcHJvcGVydGllcy9pbnRlcm5hbC9lcnJvci1oYW5kbGVyPC9saT4KLSAqICAgPGxpPmh0dHA6Ly9hcGFjaGUub3JnL3htbC9wcm9wZXJ0aWVzL2ludGVybmFsL2VudGl0eS1yZXNvbHZlcjwvbGk+Ci0gKiAgPC91bD4KLSAqIDwvdWw+Ci0gKgotICogQGF1dGhvciBBcm5hdWQgIExlIEhvcnMsIElCTQotICogQGF1dGhvciBBbmR5IENsYXJrLCBJQk0KLSAqCi0gKiBAdmVyc2lvbiAkSWQ6IFhNTFBhcnNlci5qYXZhLHYgMS41IDIwMDcvMDcvMjAgMTQ6MTE6MjEgc3BlcmljYXMgRXhwICQKLSAqLwotcHVibGljIGFic3RyYWN0IGNsYXNzIFhNTFBhcnNlciB7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0YW50cwotICAgIC8vCi0KLSAgICAvLyBwcm9wZXJ0aWVzCi0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogZW50aXR5IHJlc29sdmVyLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIEVOVElUWV9SRVNPTFZFUiA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLkVOVElUWV9SRVNPTFZFUl9QUk9QRVJUWTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBlcnJvciBoYW5kbGVyLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUk9SX0hBTkRMRVIgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5FUlJPUl9IQU5ETEVSX1BST1BFUlRZOwotCi0gICAgLyoqIFJlY29nbml6ZWQgcHJvcGVydGllcy4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSBSRUNPR05JWkVEX1BST1BFUlRJRVMgPSB7Ci0gICAgICAgIEVOVElUWV9SRVNPTFZFUiwKLSAgICAgICAgRVJST1JfSEFORExFUiwKLSAgICB9OwotCi0gICAgLy8KLSAgICAvLyBEYXRhCi0gICAgLy8KLQotICAgIC8qKiBUaGUgcGFyc2VyIGNvbmZpZ3VyYXRpb24uICovCi0gICAgcHJvdGVjdGVkIFhNTFBhcnNlckNvbmZpZ3VyYXRpb24gZkNvbmZpZ3VyYXRpb247Ci0KLSAgICAvKiogVGhlIFhNTCBTZWN1cml0eSBNYW5hZ2VyLiAqLwotICAgIFhNTFNlY3VyaXR5TWFuYWdlciBzZWN1cml0eU1hbmFnZXI7Ci0KLSAgICAvKiogVGhlIFhNTCBTZWN1cml0eSBQcm9wZXJ0eSBNYW5hZ2VyLiAqLwotICAgIFhNTFNlY3VyaXR5UHJvcGVydHlNYW5hZ2VyIHNlY3VyaXR5UHJvcGVydHlNYW5hZ2VyOwotCi0KLSAgICAvLwotICAgIC8vIENvbnN0cnVjdG9ycwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBRdWVyeSB0aGUgc3RhdGUgb2YgYSBmZWF0dXJlLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGdldEZlYXR1cmUoU3RyaW5nIGZlYXR1cmVJZCkKLSAgICAgICAgICAgIHRocm93cyBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24sIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24gewotICAgICAgICByZXR1cm4gZkNvbmZpZ3VyYXRpb24uZ2V0RmVhdHVyZShmZWF0dXJlSWQpOwotCi0gICAgfQotCi0gICAgLyoqCi0gICAgICogRGVmYXVsdCBDb25zdHJ1Y3Rvci4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgWE1MUGFyc2VyKFhNTFBhcnNlckNvbmZpZ3VyYXRpb24gY29uZmlnKSB7Ci0KLSAgICAgICAgLy8gc2F2ZSBjb25maWd1cmF0aW9uCi0gICAgICAgIGZDb25maWd1cmF0aW9uID0gY29uZmlnOwotCi0gICAgICAgIC8vIGFkZCBkZWZhdWx0IHJlY29nbml6ZWQgcHJvcGVydGllcwotICAgICAgICBmQ29uZmlndXJhdGlvbi5hZGRSZWNvZ25pemVkUHJvcGVydGllcyhSRUNPR05JWkVEX1BST1BFUlRJRVMpOwotCi0gICAgfSAvLyA8aW5pdD4oWE1MUGFyc2VyQ29uZmlndXJhdGlvbikKLQotICAgIC8vCi0gICAgLy8gUHVibGljIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogcGFyc2UKLSAgICAgKgotICAgICAqIEBwYXJhbSBpbnB1dFNvdXJjZQotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBYTklFeGNlcHRpb24KLSAgICAgKiBAZXhjZXB0aW9uIGphdmEuaW8uSU9FeGNlcHRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBwYXJzZShYTUxJbnB1dFNvdXJjZSBpbnB1dFNvdXJjZSkKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewotICAgICAgICAvLyBudWxsIGluZGljYXRlcyB0aGF0IHRoZSBwYXJzZXIgaXMgY2FsbGVkIGRpcmVjdGx5LCBpbml0aWFsaXplIHRoZW0KLSAgICAgICAgaWYgKHNlY3VyaXR5TWFuYWdlciA9PSBudWxsKSB7Ci0gICAgICAgICAgICBzZWN1cml0eU1hbmFnZXIgPSBuZXcgWE1MU2VjdXJpdHlNYW5hZ2VyKHRydWUpOwotICAgICAgICAgICAgZkNvbmZpZ3VyYXRpb24uc2V0UHJvcGVydHkoQ29uc3RhbnRzLlNFQ1VSSVRZX01BTkFHRVIsIHNlY3VyaXR5TWFuYWdlcik7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKHNlY3VyaXR5UHJvcGVydHlNYW5hZ2VyID09IG51bGwpIHsKLSAgICAgICAgICAgIHNlY3VyaXR5UHJvcGVydHlNYW5hZ2VyID0gbmV3IFhNTFNlY3VyaXR5UHJvcGVydHlNYW5hZ2VyKCk7Ci0gICAgICAgICAgICBmQ29uZmlndXJhdGlvbi5zZXRQcm9wZXJ0eShDb25zdGFudHMuWE1MX1NFQ1VSSVRZX1BST1BFUlRZX01BTkFHRVIsIHNlY3VyaXR5UHJvcGVydHlNYW5hZ2VyKTsKLSAgICAgICAgfQotCi0gICAgICAgIHJlc2V0KCk7Ci0gICAgICAgIGZDb25maWd1cmF0aW9uLnBhcnNlKGlucHV0U291cmNlKTsKLQotICAgIH0gLy8gcGFyc2UoWE1MSW5wdXRTb3VyY2UpCi0KLSAgICAvLwotICAgIC8vIFByb3RlY3RlZCBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIHJlc2V0IGFsbCBjb21wb25lbnRzIGJlZm9yZSBwYXJzaW5nCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgcmVzZXQoKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICB9IC8vIHJlc2V0KCkKLQotfSAvLyBjbGFzcyBYTUxQYXJzZXIKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3BhcnNlcnMvWFBvaW50ZXJQYXJzZXJDb25maWd1cmF0aW9uLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC9wYXJzZXJzL1hQb2ludGVyUGFyc2VyQ29uZmlndXJhdGlvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjYWNkNjhjLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3BhcnNlcnMvWFBvaW50ZXJQYXJzZXJDb25maWd1cmF0aW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyNDMgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwucGFyc2VyczsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5Db25zdGFudHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlN5bWJvbFRhYmxlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHBvaW50ZXIuWFBvaW50ZXJIYW5kbGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueGluY2x1ZGUuWEluY2x1ZGVIYW5kbGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueGluY2x1ZGUuWEluY2x1ZGVOYW1lc3BhY2VTdXBwb3J0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTERvY3VtZW50SGFuZGxlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5ncmFtbWFycy5YTUxHcmFtbWFyUG9vbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MQ29tcG9uZW50TWFuYWdlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MRG9jdW1lbnRTb3VyY2U7Ci0KLS8qKgotICogVGhpcyBwYXJzZXIgY29uZmlndXJhdGlvbiBpbmNsdWRlcyBhbiA8Y29kZT5YUG9pbnRlckhhbmRsZXI8L2NvZGU+IGluIHRoZSBwaXBlbGluZQotICogYmVmb3JlIHRoZSBzY2hlbWEgdmFsaWRhdG9yLCBvciBhcyB0aGUgbGFzdCBjb21wb25lbnQgaW4gdGhlIHBpcGVsaW5lIGlmIHRoZXJlIGlzCi0gKiBubyBzY2hlbWEgdmFsaWRhdG9yLiAgVXNpbmcgdGhpcyBwaXBlbGluZSB3aWxsIGVuYWJsZSBwcm9jZXNzaW5nIGFjY29yZGluZyB0byB0aGUKLSAqIFhNTCBJbmNsdXNpb25zIHNwZWNpZmljYXRpb24gd2l0aCBYUG9pbnRlcnMsIHRvIHRoZSBjb25mb3JtYW5jZSBsZXZlbCBkZXNjcmliZWQgaW4KLSAqIDxjb2RlPlhQb2ludGVySGFuZGxlci48L2NvZGU+LgotICoKLSAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cG9pbnRlci5YUG9pbnRlckhhbmRsZXIKLSAqLwotcHVibGljIGNsYXNzIFhQb2ludGVyUGFyc2VyQ29uZmlndXJhdGlvbiBleHRlbmRzIFhNTDExQ29uZmlndXJhdGlvbiB7Ci0KLSAgICBwcml2YXRlIFhQb2ludGVySGFuZGxlciBmWFBvaW50ZXJIYW5kbGVyOwotCi0gICAgcHJpdmF0ZSBYSW5jbHVkZUhhbmRsZXIgZlhJbmNsdWRlSGFuZGxlcjsKLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IGFsbG93IG5vdGF0aW9uIGFuZCB1bnBhcnNlZCBlbnRpdHkgZXZlbnRzIHRvIGJlIHNlbnQgb3V0IG9mIG9yZGVyLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIEFMTE9XX1VFX0FORF9OT1RBVElPTl9FVkVOVFMgPQotICAgICAgICBDb25zdGFudHMuU0FYX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLkFMTE9XX0RURF9FVkVOVFNfQUZURVJfRU5ERFREX0ZFQVRVUkU7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiBmaXh1cCBiYXNlIFVSSXMuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgWElOQ0xVREVfRklYVVBfQkFTRV9VUklTID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5YSU5DTFVERV9GSVhVUF9CQVNFX1VSSVNfRkVBVFVSRTsKLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IGZpeHVwIGxhbmd1YWdlLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFhJTkNMVURFX0ZJWFVQX0xBTkdVQUdFID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5YSU5DTFVERV9GSVhVUF9MQU5HVUFHRV9GRUFUVVJFOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IGVycm9yIHJlcG9ydGVyLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFhQT0lOVEVSX0hBTkRMRVIgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5YUE9JTlRFUl9IQU5ETEVSX1BST1BFUlRZOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IGVycm9yIHJlcG9ydGVyLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFhJTkNMVURFX0hBTkRMRVIgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5YSU5DTFVERV9IQU5ETEVSX1BST1BFUlRZOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IGVycm9yIHJlcG9ydGVyLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIE5BTUVTUEFDRV9DT05URVhUID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuTkFNRVNQQUNFX0NPTlRFWFRfUFJPUEVSVFk7Ci0KLSAgICAvKiogRGVmYXVsdCBjb25zdHJ1Y3Rvci4gKi8KLSAgICBwdWJsaWMgWFBvaW50ZXJQYXJzZXJDb25maWd1cmF0aW9uKCkgewotICAgICAgICB0aGlzKG51bGwsIG51bGwsIG51bGwpOwotICAgIH0gLy8gPGluaXQ+KCkKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHMgYSBwYXJzZXIgY29uZmlndXJhdGlvbiB1c2luZyB0aGUgc3BlY2lmaWVkIHN5bWJvbCB0YWJsZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzeW1ib2xUYWJsZSBUaGUgc3ltYm9sIHRhYmxlIHRvIHVzZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFBvaW50ZXJQYXJzZXJDb25maWd1cmF0aW9uKFN5bWJvbFRhYmxlIHN5bWJvbFRhYmxlKSB7Ci0gICAgICAgIHRoaXMoc3ltYm9sVGFibGUsIG51bGwsIG51bGwpOwotICAgIH0gLy8gPGluaXQ+KFN5bWJvbFRhYmxlKQotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0cyBhIHBhcnNlciBjb25maWd1cmF0aW9uIHVzaW5nIHRoZSBzcGVjaWZpZWQgc3ltYm9sIHRhYmxlIGFuZAotICAgICAqIGdyYW1tYXIgcG9vbC4KLSAgICAgKiA8cD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzeW1ib2xUYWJsZSBUaGUgc3ltYm9sIHRhYmxlIHRvIHVzZS4KLSAgICAgKiBAcGFyYW0gZ3JhbW1hclBvb2wgVGhlIGdyYW1tYXIgcG9vbCB0byB1c2UuCi0gICAgICovCi0gICAgcHVibGljIFhQb2ludGVyUGFyc2VyQ29uZmlndXJhdGlvbigKLSAgICAgICAgU3ltYm9sVGFibGUgc3ltYm9sVGFibGUsCi0gICAgICAgIFhNTEdyYW1tYXJQb29sIGdyYW1tYXJQb29sKSB7Ci0gICAgICAgIHRoaXMoc3ltYm9sVGFibGUsIGdyYW1tYXJQb29sLCBudWxsKTsKLSAgICB9IC8vIDxpbml0PihTeW1ib2xUYWJsZSxYTUxHcmFtbWFyUG9vbCkKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHMgYSBwYXJzZXIgY29uZmlndXJhdGlvbiB1c2luZyB0aGUgc3BlY2lmaWVkIHN5bWJvbCB0YWJsZSwKLSAgICAgKiBncmFtbWFyIHBvb2wsIGFuZCBwYXJlbnQgc2V0dGluZ3MuCi0gICAgICogPHA+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gc3ltYm9sVGFibGUgICAgVGhlIHN5bWJvbCB0YWJsZSB0byB1c2UuCi0gICAgICogQHBhcmFtIGdyYW1tYXJQb29sICAgIFRoZSBncmFtbWFyIHBvb2wgdG8gdXNlLgotICAgICAqIEBwYXJhbSBwYXJlbnRTZXR0aW5ncyBUaGUgcGFyZW50IHNldHRpbmdzLgotICAgICAqLwotICAgIHB1YmxpYyBYUG9pbnRlclBhcnNlckNvbmZpZ3VyYXRpb24oCi0gICAgICAgIFN5bWJvbFRhYmxlIHN5bWJvbFRhYmxlLAotICAgICAgICBYTUxHcmFtbWFyUG9vbCBncmFtbWFyUG9vbCwKLSAgICAgICAgWE1MQ29tcG9uZW50TWFuYWdlciBwYXJlbnRTZXR0aW5ncykgewotICAgICAgICBzdXBlcihzeW1ib2xUYWJsZSwgZ3JhbW1hclBvb2wsIHBhcmVudFNldHRpbmdzKTsKLQotICAgICAgICBmWEluY2x1ZGVIYW5kbGVyID0gbmV3IFhJbmNsdWRlSGFuZGxlcigpOwotICAgICAgICBhZGRDb21tb25Db21wb25lbnQoZlhJbmNsdWRlSGFuZGxlcik7Ci0KLSAgICAgICAgZlhQb2ludGVySGFuZGxlciA9IG5ldyBYUG9pbnRlckhhbmRsZXIoKTsKLSAgICAgICAgYWRkQ29tbW9uQ29tcG9uZW50KGZYUG9pbnRlckhhbmRsZXIpOwotCi0gICAgICAgIGZpbmFsIFN0cmluZ1tdIHJlY29nbml6ZWRGZWF0dXJlcyA9IHsKLSAgICAgICAgICAgIEFMTE9XX1VFX0FORF9OT1RBVElPTl9FVkVOVFMsCi0gICAgICAgICAgICBYSU5DTFVERV9GSVhVUF9CQVNFX1VSSVMsCi0gICAgICAgICAgICBYSU5DTFVERV9GSVhVUF9MQU5HVUFHRQotICAgICAgICB9OwotICAgICAgICBhZGRSZWNvZ25pemVkRmVhdHVyZXMocmVjb2duaXplZEZlYXR1cmVzKTsKLQotICAgICAgICAvLyBhZGQgZGVmYXVsdCByZWNvZ25pemVkIHByb3BlcnRpZXMKLSAgICAgICAgZmluYWwgU3RyaW5nW10gcmVjb2duaXplZFByb3BlcnRpZXMgPQotICAgICAgICAgICAgeyBYSU5DTFVERV9IQU5ETEVSLCBYUE9JTlRFUl9IQU5ETEVSLCBOQU1FU1BBQ0VfQ09OVEVYVCB9OwotICAgICAgICBhZGRSZWNvZ25pemVkUHJvcGVydGllcyhyZWNvZ25pemVkUHJvcGVydGllcyk7Ci0KLSAgICAgICAgc2V0RmVhdHVyZShBTExPV19VRV9BTkRfTk9UQVRJT05fRVZFTlRTLCB0cnVlKTsKLSAgICAgICAgc2V0RmVhdHVyZShYSU5DTFVERV9GSVhVUF9CQVNFX1VSSVMsIHRydWUpOwotICAgICAgICBzZXRGZWF0dXJlKFhJTkNMVURFX0ZJWFVQX0xBTkdVQUdFLCB0cnVlKTsKLQotICAgICAgICBzZXRQcm9wZXJ0eShYSU5DTFVERV9IQU5ETEVSLCBmWEluY2x1ZGVIYW5kbGVyKTsKLSAgICAgICAgc2V0UHJvcGVydHkoWFBPSU5URVJfSEFORExFUiwgZlhQb2ludGVySGFuZGxlcik7Ci0gICAgICAgIHNldFByb3BlcnR5KE5BTUVTUEFDRV9DT05URVhULCBuZXcgWEluY2x1ZGVOYW1lc3BhY2VTdXBwb3J0KCkpOwotCi0KLSAgICB9IC8vIDxpbml0PihTeW1ib2xUYWJsZSxYTUxHcmFtbWFyUG9vbCl9Ci0KLQotICAgICAgICAvKiogQ29uZmlndXJlcyB0aGUgcGlwZWxpbmUuICovCi0gICAgcHJvdGVjdGVkIHZvaWQgY29uZmlndXJlUGlwZWxpbmUoKSB7Ci0gICAgICAgIHN1cGVyLmNvbmZpZ3VyZVBpcGVsaW5lKCk7Ci0KLSAgICAgICAgLy9jb25maWd1cmUgRFREIHBpcGVsaW5lCi0gICAgICAgIGZEVERTY2FubmVyLnNldERUREhhbmRsZXIoZkRURFByb2Nlc3Nvcik7Ci0gICAgICAgIGZEVERQcm9jZXNzb3Iuc2V0RFREU291cmNlKGZEVERTY2FubmVyKTsKLQotICAgICAgICBmRFREUHJvY2Vzc29yLnNldERUREhhbmRsZXIoZlhJbmNsdWRlSGFuZGxlcik7Ci0gICAgICAgIGZYSW5jbHVkZUhhbmRsZXIuc2V0RFREU291cmNlKGZEVERQcm9jZXNzb3IpOwotICAgICAgICBmWEluY2x1ZGVIYW5kbGVyLnNldERUREhhbmRsZXIoZlhQb2ludGVySGFuZGxlcik7Ci0gICAgICAgIGZYUG9pbnRlckhhbmRsZXIuc2V0RFREU291cmNlKGZYSW5jbHVkZUhhbmRsZXIpOwotICAgICAgICBmWFBvaW50ZXJIYW5kbGVyLnNldERUREhhbmRsZXIoZkRUREhhbmRsZXIpOwotICAgICAgICBpZiAoZkRUREhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkRUREhhbmRsZXIuc2V0RFREU291cmNlKGZYUG9pbnRlckhhbmRsZXIpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gY29uZmlndXJlIFhNTCBkb2N1bWVudCBwaXBlbGluZTogaW5zZXJ0IGFmdGVyIERURFZhbGlkYXRvciBhbmQKLSAgICAgICAgLy8gYmVmb3JlIFhNTCBTY2hlbWEgdmFsaWRhdG9yCi0gICAgICAgIFhNTERvY3VtZW50U291cmNlIHByZXYgPSBudWxsOwotICAgICAgICBpZiAoZkZlYXR1cmVzLmdldChYTUxTQ0hFTUFfVkFMSURBVElPTikgPT0gQm9vbGVhbi5UUlVFKSB7Ci0gICAgICAgICAgICAvLyB3ZSBkb24ndCBoYXZlIHRvIHdvcnJ5IGFib3V0IGZTY2hlbWFWYWxpZGF0b3IgYmVpbmcgbnVsbCwgc2luY2UKLSAgICAgICAgICAgIC8vIHN1cGVyLmNvbmZpZ3VyZVBpcGVsaW5lKCkgaW5zdGFudGlhdGVkIGl0IGlmIHRoZSBmZWF0dXJlIHdhcyBzZXQKLSAgICAgICAgICAgIHByZXYgPSBmU2NoZW1hVmFsaWRhdG9yLmdldERvY3VtZW50U291cmNlKCk7Ci0gICAgICAgIH0KLSAgICAgICAgLy8gT3RoZXJ3aXNlLCBpbnNlcnQgYWZ0ZXIgdGhlIGxhc3QgY29tcG9uZW50IGluIHRoZSBwaXBlbGluZQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHByZXYgPSBmTGFzdENvbXBvbmVudDsKLSAgICAgICAgICAgIGZMYXN0Q29tcG9uZW50ID0gZlhQb2ludGVySGFuZGxlcjsKLSAgICAgICAgfQotCi0gICAgICAgIFhNTERvY3VtZW50SGFuZGxlciBuZXh0ID0gcHJldi5nZXREb2N1bWVudEhhbmRsZXIoKTsKLSAgICAgICAgICAgICAgICBwcmV2LnNldERvY3VtZW50SGFuZGxlcihmWEluY2x1ZGVIYW5kbGVyKTsKLSAgICAgICAgICAgICAgICBmWEluY2x1ZGVIYW5kbGVyLnNldERvY3VtZW50U291cmNlKHByZXYpOwotCi0gICAgICAgICAgICAgICAgaWYgKG5leHQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgZlhJbmNsdWRlSGFuZGxlci5zZXREb2N1bWVudEhhbmRsZXIobmV4dCk7Ci0gICAgICAgICAgICBuZXh0LnNldERvY3VtZW50U291cmNlKGZYSW5jbHVkZUhhbmRsZXIpOwotICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBmWEluY2x1ZGVIYW5kbGVyLnNldERvY3VtZW50SGFuZGxlcihmWFBvaW50ZXJIYW5kbGVyKTsKLSAgICAgICAgICAgICAgICBmWFBvaW50ZXJIYW5kbGVyLnNldERvY3VtZW50U291cmNlKGZYSW5jbHVkZUhhbmRsZXIpOwotICAgIH0gLy8gY29uZmlndXJlUGlwZWxpbmUoKQotCi0gICAgICAgIHByb3RlY3RlZCB2b2lkIGNvbmZpZ3VyZVhNTDExUGlwZWxpbmUoKSB7Ci0gICAgICAgICAgICAgICAgc3VwZXIuY29uZmlndXJlWE1MMTFQaXBlbGluZSgpOwotCi0gICAgICAgIC8vIGNvbmZpZ3VyZSBYTUwgMS4xLiBEVEQgcGlwZWxpbmUKLSAgICAgICAgICAgICAgICBmWE1MMTFEVERTY2FubmVyLnNldERUREhhbmRsZXIoZlhNTDExRFREUHJvY2Vzc29yKTsKLSAgICAgICAgICAgICAgICBmWE1MMTFEVERQcm9jZXNzb3Iuc2V0RFREU291cmNlKGZYTUwxMURURFNjYW5uZXIpOwotCi0gICAgICAgIGZEVERQcm9jZXNzb3Iuc2V0RFRESGFuZGxlcihmWEluY2x1ZGVIYW5kbGVyKTsKLSAgICAgICAgZlhJbmNsdWRlSGFuZGxlci5zZXREVERTb3VyY2UoZlhNTDExRFREUHJvY2Vzc29yKTsKLSAgICAgICAgZlhJbmNsdWRlSGFuZGxlci5zZXREVERIYW5kbGVyKGZYUG9pbnRlckhhbmRsZXIpOwotICAgICAgICBmWFBvaW50ZXJIYW5kbGVyLnNldERURFNvdXJjZShmWEluY2x1ZGVIYW5kbGVyKTsKLSAgICAgICAgZlhQb2ludGVySGFuZGxlci5zZXREVERIYW5kbGVyKGZEVERIYW5kbGVyKTsKLSAgICAgICAgaWYgKGZEVERIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZEVERIYW5kbGVyLnNldERURFNvdXJjZShmWFBvaW50ZXJIYW5kbGVyKTsKLSAgICAgICAgfQotCi0KLSAgICAgICAgICAgICAgICAvLyBjb25maWd1cmUgWE1MIGRvY3VtZW50IHBpcGVsaW5lOiBpbnNlcnQgYWZ0ZXIgRFREVmFsaWRhdG9yIGFuZAotICAgICAgICAgICAgICAgIC8vIGJlZm9yZSBYTUwgU2NoZW1hIHZhbGlkYXRvcgotICAgICAgICAgICAgICAgIFhNTERvY3VtZW50U291cmNlIHByZXYgPSBudWxsOwotICAgICAgICAgICAgICAgIGlmIChmRmVhdHVyZXMuZ2V0KFhNTFNDSEVNQV9WQUxJREFUSU9OKSA9PSBCb29sZWFuLlRSVUUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIHdlIGRvbid0IGhhdmUgdG8gd29ycnkgYWJvdXQgZlNjaGVtYVZhbGlkYXRvciBiZWluZyBudWxsLCBzaW5jZQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gc3VwZXIuY29uZmlndXJlUGlwZWxpbmUoKSBpbnN0YW50aWF0ZWQgaXQgaWYgdGhlIGZlYXR1cmUgd2FzIHNldAotICAgICAgICAgICAgICAgICAgICAgICAgcHJldiA9IGZTY2hlbWFWYWxpZGF0b3IuZ2V0RG9jdW1lbnRTb3VyY2UoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLy8gT3RoZXJ3aXNlLCBpbnNlcnQgYWZ0ZXIgdGhlIGxhc3QgY29tcG9uZW50IGluIHRoZSBwaXBlbGluZQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgcHJldiA9IGZMYXN0Q29tcG9uZW50OwotICAgICAgICAgICAgICAgICAgICAgICAgZkxhc3RDb21wb25lbnQgPSBmWFBvaW50ZXJIYW5kbGVyOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICBYTUxEb2N1bWVudEhhbmRsZXIgbmV4dCA9IHByZXYuZ2V0RG9jdW1lbnRIYW5kbGVyKCk7Ci0gICAgICAgICAgICAgICAgcHJldi5zZXREb2N1bWVudEhhbmRsZXIoZlhJbmNsdWRlSGFuZGxlcik7Ci0gICAgICAgICAgICAgICAgZlhJbmNsdWRlSGFuZGxlci5zZXREb2N1bWVudFNvdXJjZShwcmV2KTsKLQotICAgICAgICAgICAgICAgIGlmIChuZXh0ICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZYSW5jbHVkZUhhbmRsZXIuc2V0RG9jdW1lbnRIYW5kbGVyKG5leHQpOwotICAgICAgICAgICAgbmV4dC5zZXREb2N1bWVudFNvdXJjZShmWEluY2x1ZGVIYW5kbGVyKTsKLSAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgZlhJbmNsdWRlSGFuZGxlci5zZXREb2N1bWVudEhhbmRsZXIoZlhQb2ludGVySGFuZGxlcik7Ci0gICAgICAgICAgICAgICAgZlhQb2ludGVySGFuZGxlci5zZXREb2N1bWVudFNvdXJjZShmWEluY2x1ZGVIYW5kbGVyKTsKLQotCi0gICAgICAgIH0gLy8gY29uZmlndXJlWE1MMTFQaXBlbGluZSgpCi0KLSAgICBwdWJsaWMgdm9pZCBzZXRQcm9wZXJ0eShTdHJpbmcgcHJvcGVydHlJZCwgT2JqZWN0IHZhbHVlKQotICAgICAgICB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy9pZiAocHJvcGVydHlJZC5lcXVhbHMoWElOQ0xVREVfSEFORExFUikpIHsKLSAgICAgICAgLy99Ci0KLSAgICAgICAgc3VwZXIuc2V0UHJvcGVydHkocHJvcGVydHlJZCwgdmFsdWUpOwotICAgIH0gLy8gc2V0UHJvcGVydHkoU3RyaW5nLE9iamVjdCkKLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3BhcnNlcnMvb3JnLmFwYWNoZS54ZXJjZXMueG5pLnBhcnNlci5EVERDb25maWd1cmF0aW9uIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvcGFyc2Vycy9vcmcuYXBhY2hlLnhlcmNlcy54bmkucGFyc2VyLkRURENvbmZpZ3VyYXRpb24KZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDhmNmFjOGIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvcGFyc2Vycy9vcmcuYXBhY2hlLnhlcmNlcy54bmkucGFyc2VyLkRURENvbmZpZ3VyYXRpb24KKysrIC9kZXYvbnVsbApAQCAtMSArMCwwIEBACi1jb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnBhcnNlcnMuRFREQ29uZmlndXJhdGlvbgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvcGFyc2Vycy9vcmcuYXBhY2hlLnhlcmNlcy54bmkucGFyc2VyLlhNTDExQ29uZmlndXJhdGlvbiBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3BhcnNlcnMvb3JnLmFwYWNoZS54ZXJjZXMueG5pLnBhcnNlci5YTUwxMUNvbmZpZ3VyYXRpb24KZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGFmMTkyNjQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvcGFyc2Vycy9vcmcuYXBhY2hlLnhlcmNlcy54bmkucGFyc2VyLlhNTDExQ29uZmlndXJhdGlvbgorKysgL2Rldi9udWxsCkBAIC0xICswLDAgQEAKLWNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwucGFyc2Vycy5YTUwxMUNvbmZpZ3VyYXRpb24KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3BhcnNlcnMvb3JnLmFwYWNoZS54ZXJjZXMueG5pLnBhcnNlci5YTUxQYXJzZXJDb25maWd1cmF0aW9uIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvcGFyc2Vycy9vcmcuYXBhY2hlLnhlcmNlcy54bmkucGFyc2VyLlhNTFBhcnNlckNvbmZpZ3VyYXRpb24KZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGNhOGJjM2UuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvcGFyc2Vycy9vcmcuYXBhY2hlLnhlcmNlcy54bmkucGFyc2VyLlhNTFBhcnNlckNvbmZpZ3VyYXRpb24KKysrIC9kZXYvbnVsbApAQCAtMSArMCwwIEBACi1jb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnBhcnNlcnMuWEluY2x1ZGVBd2FyZVBhcnNlckNvbmZpZ3VyYXRpb24KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3BhcnNlcnMvb3JnLnhtbC5zYXguZHJpdmVyIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvcGFyc2Vycy9vcmcueG1sLnNheC5kcml2ZXIKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGUxYTM4NzQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvcGFyc2Vycy9vcmcueG1sLnNheC5kcml2ZXIKKysrIC9kZXYvbnVsbApAQCAtMSwyICswLDAgQEAKLWNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwucGFyc2Vycy5TQVhQYXJzZXIKLQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9BdHRyaWJ1dGVzUHJveHkuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3V0aWwvQXR0cmlidXRlc1Byb3h5LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDJjN2I4MjcuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9BdHRyaWJ1dGVzUHJveHkuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE5MiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWw7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTEF0dHJpYnV0ZXM7Ci1pbXBvcnQgb3JnLnhtbC5zYXguQXR0cmlidXRlTGlzdDsKLWltcG9ydCBvcmcueG1sLnNheC5leHQuQXR0cmlidXRlczI7Ci0KLS8qKgotICogV3JhcHMge0BsaW5rIFhNTEF0dHJpYnV0ZXN9IGFuZCBtYWtlcyBpdCBsb29rIGxpa2UKLSAqIHtAbGluayBBdHRyaWJ1dGVMaXN0fSBhbmQge0BsaW5rIEF0dHJpYnV0ZXN9LgotICoKLSAqIEBhdXRob3IgQXJuYXVkIExlIEhvcnMsIElCTQotICogQGF1dGhvciBBbmR5IENsYXJrLCBJQk0KLSAqCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBBdHRyaWJ1dGVzUHJveHkKLSAgICBpbXBsZW1lbnRzIEF0dHJpYnV0ZUxpc3QsIEF0dHJpYnV0ZXMyIHsKLQotICAgIC8vCi0gICAgLy8gRGF0YQotICAgIC8vCi0KLSAgICAvKiogWE1MIGF0dHJpYnV0ZXMuICovCi0gICAgcHJpdmF0ZSBYTUxBdHRyaWJ1dGVzIGZBdHRyaWJ1dGVzOwotCi0gICAgLy8KLSAgICAvLyBDb25zdHJ1Y3RvcnMKLSAgICAvLwotCi0gICAgcHVibGljIEF0dHJpYnV0ZXNQcm94eShYTUxBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMpIHsKLSAgICAgICAgZkF0dHJpYnV0ZXMgPSBhdHRyaWJ1dGVzOwotICAgIH0KLQotICAgIC8vCi0gICAgLy8gUHVibGljIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqIFNldHMgdGhlIFhNTCBhdHRyaWJ1dGVzIHRvIGJlIHdyYXBwZWQuICovCi0gICAgcHVibGljIHZvaWQgc2V0QXR0cmlidXRlcyhYTUxBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMpIHsKLSAgICAgICAgZkF0dHJpYnV0ZXMgPSBhdHRyaWJ1dGVzOwotICAgIH0gLy8gc2V0QXR0cmlidXRlcyhYTUxBdHRyaWJ1dGVzKQotCi0gICAgcHVibGljIFhNTEF0dHJpYnV0ZXMgZ2V0QXR0cmlidXRlcygpIHsKLSAgICAgICAgcmV0dXJuIGZBdHRyaWJ1dGVzOwotICAgIH0KLQotICAgIC8qCi0gICAgICogQXR0cmlidXRlcyBtZXRob2RzCi0gICAgICovCi0KLSAgICBwdWJsaWMgaW50IGdldExlbmd0aCgpIHsKLSAgICAgICAgcmV0dXJuIGZBdHRyaWJ1dGVzLmdldExlbmd0aCgpOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0UU5hbWUoaW50IGluZGV4KSB7Ci0gICAgICAgIHJldHVybiBmQXR0cmlidXRlcy5nZXRRTmFtZShpbmRleCk7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRVUkkoaW50IGluZGV4KSB7Ci0gICAgICAgIC8vIFRoaXMgaGlkZXMgdGhlIGZhY3QgdGhhdCBpbnRlcm5hbGx5IHdlIHVzZSBudWxsIGluc3RlYWQgb2YgZW1wdHkgc3RyaW5nCi0gICAgICAgIC8vIFNBWCByZXF1aXJlcyB0aGUgVVJJIHRvIGJlIGEgc3RyaW5nIG9yIGFuIGVtcHR5IHN0cmluZwotICAgICAgICBTdHJpbmcgdXJpID0gZkF0dHJpYnV0ZXMuZ2V0VVJJKGluZGV4KTsKLSAgICAgICAgcmV0dXJuIHVyaSAhPSBudWxsID8gdXJpIDogWE1MU3ltYm9scy5FTVBUWV9TVFJJTkc7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRMb2NhbE5hbWUoaW50IGluZGV4KSB7Ci0gICAgICAgIHJldHVybiBmQXR0cmlidXRlcy5nZXRMb2NhbE5hbWUoaW5kZXgpOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VHlwZShpbnQgaSkgewotICAgICAgICByZXR1cm4gZkF0dHJpYnV0ZXMuZ2V0VHlwZShpKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldFR5cGUoU3RyaW5nIG5hbWUpIHsKLSAgICAgICAgcmV0dXJuIGZBdHRyaWJ1dGVzLmdldFR5cGUobmFtZSk7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRUeXBlKFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUpIHsKLSAgICAgICAgcmV0dXJuIHVyaS5lcXVhbHMoWE1MU3ltYm9scy5FTVBUWV9TVFJJTkcpID8KLSAgICAgICAgICAgICAgICBmQXR0cmlidXRlcy5nZXRUeXBlKG51bGwsIGxvY2FsTmFtZSkgOgotICAgICAgICAgICAgICAgICAgICBmQXR0cmlidXRlcy5nZXRUeXBlKHVyaSwgbG9jYWxOYW1lKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldFZhbHVlKGludCBpKSB7Ci0gICAgICAgIHJldHVybiBmQXR0cmlidXRlcy5nZXRWYWx1ZShpKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldFZhbHVlKFN0cmluZyBuYW1lKSB7Ci0gICAgICAgIHJldHVybiBmQXR0cmlidXRlcy5nZXRWYWx1ZShuYW1lKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldFZhbHVlKFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUpIHsKLSAgICAgICAgcmV0dXJuIHVyaS5lcXVhbHMoWE1MU3ltYm9scy5FTVBUWV9TVFJJTkcpID8KLSAgICAgICAgICAgICAgICBmQXR0cmlidXRlcy5nZXRWYWx1ZShudWxsLCBsb2NhbE5hbWUpIDoKLSAgICAgICAgICAgICAgICAgICAgZkF0dHJpYnV0ZXMuZ2V0VmFsdWUodXJpLCBsb2NhbE5hbWUpOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgZ2V0SW5kZXgoU3RyaW5nIHFOYW1lKSB7Ci0gICAgICAgIHJldHVybiBmQXR0cmlidXRlcy5nZXRJbmRleChxTmFtZSk7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBnZXRJbmRleChTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxQYXJ0KSB7Ci0gICAgICAgIHJldHVybiB1cmkuZXF1YWxzKFhNTFN5bWJvbHMuRU1QVFlfU1RSSU5HKSA/Ci0gICAgICAgICAgICAgICAgZkF0dHJpYnV0ZXMuZ2V0SW5kZXgobnVsbCwgbG9jYWxQYXJ0KSA6Ci0gICAgICAgICAgICAgICAgICAgIGZBdHRyaWJ1dGVzLmdldEluZGV4KHVyaSwgbG9jYWxQYXJ0KTsKLSAgICB9Ci0KLSAgICAvKgotICAgICAqIEF0dHJpYnV0ZXMyIG1ldGhvZHMKLSAgICAgKi8KLQotICAgIHB1YmxpYyBib29sZWFuIGlzRGVjbGFyZWQoaW50IGluZGV4KSB7Ci0gICAgICAgIGlmIChpbmRleCA8IDAgfHwgaW5kZXggPj0gZkF0dHJpYnV0ZXMuZ2V0TGVuZ3RoKCkpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oaW5kZXgpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBCb29sZWFuLlRSVUUuZXF1YWxzKAotICAgICAgICAgICAgZkF0dHJpYnV0ZXMuZ2V0QXVnbWVudGF0aW9ucyhpbmRleCkuZ2V0SXRlbSgKLSAgICAgICAgICAgIENvbnN0YW50cy5BVFRSSUJVVEVfREVDTEFSRUQpKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0RlY2xhcmVkKFN0cmluZyBxTmFtZSkgewotICAgICAgICBpbnQgaW5kZXggPSBnZXRJbmRleChxTmFtZSk7Ci0gICAgICAgIGlmIChpbmRleCA9PSAtMSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihxTmFtZSk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIEJvb2xlYW4uVFJVRS5lcXVhbHMoCi0gICAgICAgICAgICBmQXR0cmlidXRlcy5nZXRBdWdtZW50YXRpb25zKGluZGV4KS5nZXRJdGVtKAotICAgICAgICAgICAgQ29uc3RhbnRzLkFUVFJJQlVURV9ERUNMQVJFRCkpOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGlzRGVjbGFyZWQoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSkgewotICAgICAgICBpbnQgaW5kZXggPSBnZXRJbmRleCh1cmksIGxvY2FsTmFtZSk7Ci0gICAgICAgIGlmIChpbmRleCA9PSAtMSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihsb2NhbE5hbWUpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBCb29sZWFuLlRSVUUuZXF1YWxzKAotICAgICAgICAgICAgZkF0dHJpYnV0ZXMuZ2V0QXVnbWVudGF0aW9ucyhpbmRleCkuZ2V0SXRlbSgKLSAgICAgICAgICAgIENvbnN0YW50cy5BVFRSSUJVVEVfREVDTEFSRUQpKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBpc1NwZWNpZmllZChpbnQgaW5kZXgpIHsKLSAgICAgICAgaWYgKGluZGV4IDwgMCB8fCBpbmRleCA+PSBmQXR0cmlidXRlcy5nZXRMZW5ndGgoKSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihpbmRleCk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGZBdHRyaWJ1dGVzLmlzU3BlY2lmaWVkKGluZGV4KTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBpc1NwZWNpZmllZChTdHJpbmcgcU5hbWUpIHsKLSAgICAgICAgaW50IGluZGV4ID0gZ2V0SW5kZXgocU5hbWUpOwotICAgICAgICBpZiAoaW5kZXggPT0gLTEpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24ocU5hbWUpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmQXR0cmlidXRlcy5pc1NwZWNpZmllZChpbmRleCk7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gaXNTcGVjaWZpZWQoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSkgewotICAgICAgICBpbnQgaW5kZXggPSBnZXRJbmRleCh1cmksIGxvY2FsTmFtZSk7Ci0gICAgICAgIGlmIChpbmRleCA9PSAtMSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihsb2NhbE5hbWUpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmQXR0cmlidXRlcy5pc1NwZWNpZmllZChpbmRleCk7Ci0gICAgfQotCi0gICAgLyoKLSAgICAgKiBBdHRyaWJ1dGVMaXN0IG1ldGhvZHMKLSAgICAgKi8KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZShpbnQgaSkgewotICAgICAgICByZXR1cm4gZkF0dHJpYnV0ZXMuZ2V0UU5hbWUoaSk7Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL0F1Z21lbnRhdGlvbnNJbXBsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL0F1Z21lbnRhdGlvbnNJbXBsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDQyNWE0MTUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9BdWdtZW50YXRpb25zSW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjg2ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKi8KLS8qCi0gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKLSAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAotICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgotICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKLSAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCi0gKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWw7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5BdWdtZW50YXRpb25zOwotaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKLWltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247Ci1pbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7Ci1pbXBvcnQgamF2YS51dGlsLk1hcDsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIHByb3ZpZGVzIGFuIGltcGxlbWVudGF0aW9uIGZvciBBdWdtZW50YXRpb25zIGludGVyZmFjZS4KLSAqIEF1Z21lbnRhdGlvbnMgaW50ZXJmYWNlIGRlZmluZXMgYSBtYXAgb2YgYWRkaXRpb25hbCBkYXRhIHRoYXQgY291bGQKLSAqIGJlIHBhc3NlZCBhbG9uZyB0aGUgZG9jdW1lbnQgcGlwZWxpbmUuIFRoZSBpbmZvcm1hdGlvbiBjYW4gY29udGFpbiBleHRyYQotICogYXJndW1lbnRzIG9yIGluZm9zZXQgYXVnbWVudGF0aW9ucywgZm9yIGV4YW1wbGUgUFNWSS4gVGhpcyBhZGRpdGlvbmFsCi0gKiBpbmZvcm1hdGlvbiBpcyBpZGVudGlmaWVkIGJ5IGEgU3RyaW5nIGtleS4KLSAqIDxwPgotICoKLSAqIEBhdXRob3IgRWxlbmEgTGl0YW5pLCBJQk0KLSAqLwotcHVibGljIGNsYXNzIEF1Z21lbnRhdGlvbnNJbXBsIGltcGxlbWVudHMgQXVnbWVudGF0aW9uc3sKLQotICAgIHByaXZhdGUgQXVnbWVudGF0aW9uc0l0ZW1zQ29udGFpbmVyIGZBdWdtZW50YXRpb25zQ29udGFpbmVyID0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgU21hbGxDb250YWluZXIoKTsKLQotICAgIC8qKgotICAgICAqIEFkZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIGlkZW50aWZpZWQgYnkgYSBrZXkgdG8gdGhlIEF1Z21lbnRhdGlvbnMgc3RydWN0dXJlLgotICAgICAqCi0gICAgICogQHBhcmFtIGtleSAgICBJZGVudGlmaWVyLCBjYW4ndCBiZSA8Y29kZT5udWxsPC9jb2RlPgotICAgICAqIEBwYXJhbSBpdGVtICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbgotICAgICAqCi0gICAgICogQHJldHVybiB0aGUgcHJldmlvdXMgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBrZXkgaW4gdGhlIEF1Z21lbnRhdGlvbnMgc3RydWN1dHJlLAotICAgICAqICAgICAgICAgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgaXQgZGlkIG5vdCBoYXZlIG9uZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0IHB1dEl0ZW0gKFN0cmluZyBrZXksIE9iamVjdCBpdGVtKXsKLSAgICAgICAgT2JqZWN0IG9sZFZhbHVlID0gZkF1Z21lbnRhdGlvbnNDb250YWluZXIucHV0SXRlbShrZXksIGl0ZW0pOwotCi0gICAgICAgIGlmIChvbGRWYWx1ZSA9PSBudWxsICYmIGZBdWdtZW50YXRpb25zQ29udGFpbmVyLmlzRnVsbCgpKSB7Ci0gICAgICAgICAgICBmQXVnbWVudGF0aW9uc0NvbnRhaW5lciA9IGZBdWdtZW50YXRpb25zQ29udGFpbmVyLmV4cGFuZCgpOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIG9sZFZhbHVlOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogR2V0IGluZm9ybWF0aW9uIGlkZW50aWZpZWQgYnkgYSBrZXkgZnJvbSB0aGUgQXVnbWVudGF0aW9ucyBzdHJ1Y3R1cmUKLSAgICAgKgotICAgICAqIEBwYXJhbSBrZXkgICAgSWRlbnRpZmllciwgY2FuJ3QgYmUgPGNvZGU+bnVsbDwvY29kZT4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIHRvIHdoaWNoIHRoZSBrZXkgaXMgbWFwcGVkIGluIHRoZSBBdWdtZW50YXRpb25zIHN0cnVjdHVyZTsKLSAgICAgKiAgICAgICAgIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoZSBrZXkgaXMgbm90IG1hcHBlZCB0byBhbnkgdmFsdWUuCi0gICAgICovCi0gICAgcHVibGljIE9iamVjdCBnZXRJdGVtKFN0cmluZyBrZXkpewotICAgICAgICByZXR1cm4gZkF1Z21lbnRhdGlvbnNDb250YWluZXIuZ2V0SXRlbShrZXkpOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogUmVtb3ZlIGFkZGl0aW9uYWwgaW5mbyBmcm9tIHRoZSBBdWdtZW50YXRpb25zIHN0cnVjdHVyZQotICAgICAqCi0gICAgICogQHBhcmFtIGtleSAgICBJZGVudGlmaWVyLCBjYW4ndCBiZSA8Y29kZT5udWxsPC9jb2RlPgotICAgICAqLwotICAgIHB1YmxpYyBPYmplY3QgcmVtb3ZlSXRlbSAoU3RyaW5nIGtleSl7Ci0gICAgICAgIHJldHVybiBmQXVnbWVudGF0aW9uc0NvbnRhaW5lci5yZW1vdmVJdGVtKGtleSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhbiBlbnVtZXJhdGlvbiBvZiB0aGUga2V5cyBpbiB0aGUgQXVnbWVudGF0aW9ucyBzdHJ1Y3R1cmUKLSAgICAgKgotICAgICAqLwotICAgIHB1YmxpYyBFbnVtZXJhdGlvbiBrZXlzICgpewotICAgICAgICByZXR1cm4gZkF1Z21lbnRhdGlvbnNDb250YWluZXIua2V5cygpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJlbW92ZSBhbGwgb2JqZWN0cyBmcm9tIHRoZSBBdWdtZW50YXRpb25zIHN0cnVjdHVyZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCByZW1vdmVBbGxJdGVtcygpIHsKLSAgICAgICAgZkF1Z21lbnRhdGlvbnNDb250YWluZXIuY2xlYXIoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgICAgICByZXR1cm4gZkF1Z21lbnRhdGlvbnNDb250YWluZXIudG9TdHJpbmcoKTsKLSAgICB9Ci0KLSAgICBhYnN0cmFjdCBjbGFzcyBBdWdtZW50YXRpb25zSXRlbXNDb250YWluZXIgewotICAgICAgICBhYnN0cmFjdCBwdWJsaWMgT2JqZWN0IHB1dEl0ZW0oT2JqZWN0IGtleSwgT2JqZWN0IGl0ZW0pOwotICAgICAgICBhYnN0cmFjdCBwdWJsaWMgT2JqZWN0IGdldEl0ZW0oT2JqZWN0IGtleSk7Ci0gICAgICAgIGFic3RyYWN0IHB1YmxpYyBPYmplY3QgcmVtb3ZlSXRlbShPYmplY3Qga2V5KTsKLSAgICAgICAgYWJzdHJhY3QgcHVibGljIEVudW1lcmF0aW9uIGtleXMoKTsKLSAgICAgICAgYWJzdHJhY3QgcHVibGljIHZvaWQgY2xlYXIoKTsKLSAgICAgICAgYWJzdHJhY3QgcHVibGljIGJvb2xlYW4gaXNGdWxsKCk7Ci0gICAgICAgIGFic3RyYWN0IHB1YmxpYyBBdWdtZW50YXRpb25zSXRlbXNDb250YWluZXIgZXhwYW5kKCk7Ci0gICAgfQotCi0gICAgY2xhc3MgU21hbGxDb250YWluZXIgZXh0ZW5kcyBBdWdtZW50YXRpb25zSXRlbXNDb250YWluZXIgewotICAgICAgICBmaW5hbCBzdGF0aWMgaW50IFNJWkVfTElNSVQgPSAxMDsKLSAgICAgICAgZmluYWwgT2JqZWN0W10gZkF1Z21lbnRhdGlvbnMgPSBuZXcgT2JqZWN0W1NJWkVfTElNSVQqMl07Ci0gICAgICAgIGludCBmTnVtRW50cmllcyA9IDA7Ci0KLSAgICAgICAgcHVibGljIEVudW1lcmF0aW9uIGtleXMoKSB7Ci0gICAgICAgICAgICByZXR1cm4gbmV3IFNtYWxsQ29udGFpbmVyS2V5RW51bWVyYXRpb24oKTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyBPYmplY3QgZ2V0SXRlbShPYmplY3Qga2V5KSB7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZOdW1FbnRyaWVzKjI7IGkgPSBpICsgMikgewotICAgICAgICAgICAgICAgIGlmIChmQXVnbWVudGF0aW9uc1tpXS5lcXVhbHMoa2V5KSkgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gZkF1Z21lbnRhdGlvbnNbaSsxXTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIE9iamVjdCBwdXRJdGVtKE9iamVjdCBrZXksIE9iamVjdCBpdGVtKSB7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZOdW1FbnRyaWVzKjI7IGkgPSBpICsgMikgewotICAgICAgICAgICAgICAgIGlmIChmQXVnbWVudGF0aW9uc1tpXS5lcXVhbHMoa2V5KSkgewotICAgICAgICAgICAgICAgICAgICBPYmplY3Qgb2xkVmFsdWUgPSBmQXVnbWVudGF0aW9uc1tpKzFdOwotICAgICAgICAgICAgICAgICAgICBmQXVnbWVudGF0aW9uc1tpKzFdID0gaXRlbTsKLQotICAgICAgICAgICAgICAgICAgICByZXR1cm4gb2xkVmFsdWU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBmQXVnbWVudGF0aW9uc1tmTnVtRW50cmllcyoyXSA9IGtleTsKLSAgICAgICAgICAgIGZBdWdtZW50YXRpb25zW2ZOdW1FbnRyaWVzKjIrMV0gPSBpdGVtOwotICAgICAgICAgICAgZk51bUVudHJpZXMrKzsKLQotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLQotCi0gICAgICAgIHB1YmxpYyBPYmplY3QgcmVtb3ZlSXRlbShPYmplY3Qga2V5KSB7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZOdW1FbnRyaWVzKjI7IGkgPSBpICsgMikgewotICAgICAgICAgICAgICAgIGlmIChmQXVnbWVudGF0aW9uc1tpXS5lcXVhbHMoa2V5KSkgewotICAgICAgICAgICAgICAgICAgICBPYmplY3Qgb2xkVmFsdWUgPSBmQXVnbWVudGF0aW9uc1tpKzFdOwotCi0gICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGogPSBpOyBqIDwgZk51bUVudHJpZXMqMiAtIDI7IGogPSBqICsgMikgewotICAgICAgICAgICAgICAgICAgICAgICAgZkF1Z21lbnRhdGlvbnNbal0gPSBmQXVnbWVudGF0aW9uc1tqKzJdOwotICAgICAgICAgICAgICAgICAgICAgICAgZkF1Z21lbnRhdGlvbnNbaisxXSA9IGZBdWdtZW50YXRpb25zW2orM107Ci0gICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICBmQXVnbWVudGF0aW9uc1tmTnVtRW50cmllcyoyLTJdID0gbnVsbDsKLSAgICAgICAgICAgICAgICAgICAgZkF1Z21lbnRhdGlvbnNbZk51bUVudHJpZXMqMi0xXSA9IG51bGw7Ci0gICAgICAgICAgICAgICAgICAgIGZOdW1FbnRyaWVzLS07Ci0KLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG9sZFZhbHVlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCBjbGVhcigpIHsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZk51bUVudHJpZXMqMjsgaSA9IGkgKyAyKSB7Ci0gICAgICAgICAgICAgICAgZkF1Z21lbnRhdGlvbnNbaV0gPSBudWxsOwotICAgICAgICAgICAgICAgIGZBdWdtZW50YXRpb25zW2krMV0gPSBudWxsOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBmTnVtRW50cmllcyA9IDA7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc0Z1bGwoKSB7Ci0gICAgICAgICAgICByZXR1cm4gKGZOdW1FbnRyaWVzID09IFNJWkVfTElNSVQpOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIEF1Z21lbnRhdGlvbnNJdGVtc0NvbnRhaW5lciBleHBhbmQoKSB7Ci0gICAgICAgICAgICBMYXJnZUNvbnRhaW5lciBleHBhbmRlZENvbnRhaW5lciA9IG5ldyBMYXJnZUNvbnRhaW5lcigpOwotCi0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZOdW1FbnRyaWVzKjI7IGkgPSBpICsgMikgewotICAgICAgICAgICAgICAgIGV4cGFuZGVkQ29udGFpbmVyLnB1dEl0ZW0oZkF1Z21lbnRhdGlvbnNbaV0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmQXVnbWVudGF0aW9uc1tpKzFdKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgcmV0dXJuIGV4cGFuZGVkQ29udGFpbmVyOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKLSAgICAgICAgICAgIFN0cmluZ0J1aWxkZXIgYnVmZiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7Ci0gICAgICAgICAgICBidWZmLmFwcGVuZCgiU21hbGxDb250YWluZXIgLSBmTnVtRW50cmllcyA9PSAiKS5hcHBlbmQoZk51bUVudHJpZXMpOwotCi0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IFNJWkVfTElNSVQqMjsgaT1pKzIpIHsKLSAgICAgICAgICAgICAgICBidWZmLmFwcGVuZCgiXG5mQXVnbWVudGF0aW9uc1siKQotICAgICAgICAgICAgICAgICAgICAuYXBwZW5kKGkpCi0gICAgICAgICAgICAgICAgICAgIC5hcHBlbmQoIl0gPT0gIikKLSAgICAgICAgICAgICAgICAgICAgLmFwcGVuZChmQXVnbWVudGF0aW9uc1tpXSkKLSAgICAgICAgICAgICAgICAgICAgLmFwcGVuZCgiOyBmQXVnbWVudGF0aW9uc1siKQotICAgICAgICAgICAgICAgICAgICAuYXBwZW5kKGkrMSkKLSAgICAgICAgICAgICAgICAgICAgLmFwcGVuZCgiXSA9PSAiKQotICAgICAgICAgICAgICAgICAgICAuYXBwZW5kKGZBdWdtZW50YXRpb25zW2krMV0pOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICByZXR1cm4gYnVmZi50b1N0cmluZygpOwotICAgICAgICB9Ci0KLSAgICAgICAgY2xhc3MgU21hbGxDb250YWluZXJLZXlFbnVtZXJhdGlvbiBpbXBsZW1lbnRzIEVudW1lcmF0aW9uIHsKLSAgICAgICAgICAgIE9iamVjdCBbXSBlbnVtQXJyYXkgPSBuZXcgT2JqZWN0W2ZOdW1FbnRyaWVzXTsKLSAgICAgICAgICAgIGludCBuZXh0ID0gMDsKLQotICAgICAgICAgICAgU21hbGxDb250YWluZXJLZXlFbnVtZXJhdGlvbigpIHsKLSAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZOdW1FbnRyaWVzOyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgZW51bUFycmF5W2ldID0gZkF1Z21lbnRhdGlvbnNbaSoyXTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIHB1YmxpYyBib29sZWFuIGhhc01vcmVFbGVtZW50cygpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gbmV4dCA8IGVudW1BcnJheS5sZW5ndGg7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIHB1YmxpYyBPYmplY3QgbmV4dEVsZW1lbnQoKSB7Ci0gICAgICAgICAgICAgICAgaWYgKG5leHQgPj0gZW51bUFycmF5Lmxlbmd0aCkgewotICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgamF2YS51dGlsLk5vU3VjaEVsZW1lbnRFeGNlcHRpb24oKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBPYmplY3QgbmV4dFZhbCA9IGVudW1BcnJheVtuZXh0XTsKLSAgICAgICAgICAgICAgICBlbnVtQXJyYXlbbmV4dF0gPSBudWxsOwotICAgICAgICAgICAgICAgIG5leHQrKzsKLQotICAgICAgICAgICAgICAgIHJldHVybiBuZXh0VmFsOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgY2xhc3MgTGFyZ2VDb250YWluZXIgZXh0ZW5kcyBBdWdtZW50YXRpb25zSXRlbXNDb250YWluZXIgewotICAgICAgICBmaW5hbCBNYXA8T2JqZWN0LCBPYmplY3Q+IGZBdWdtZW50YXRpb25zID0gbmV3IEhhc2hNYXA8PigpOwotCi0gICAgICAgIHB1YmxpYyBPYmplY3QgZ2V0SXRlbShPYmplY3Qga2V5KSB7Ci0gICAgICAgICAgICByZXR1cm4gZkF1Z21lbnRhdGlvbnMuZ2V0KGtleSk7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgT2JqZWN0IHB1dEl0ZW0oT2JqZWN0IGtleSwgT2JqZWN0IGl0ZW0pIHsKLSAgICAgICAgICAgIHJldHVybiBmQXVnbWVudGF0aW9ucy5wdXQoa2V5LCBpdGVtKTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyBPYmplY3QgcmVtb3ZlSXRlbShPYmplY3Qga2V5KSB7Ci0gICAgICAgICAgICByZXR1cm4gZkF1Z21lbnRhdGlvbnMucmVtb3ZlKGtleSk7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgRW51bWVyYXRpb24ga2V5cygpIHsKLSAgICAgICAgICAgIHJldHVybiBDb2xsZWN0aW9ucy5lbnVtZXJhdGlvbihmQXVnbWVudGF0aW9ucy5rZXlTZXQoKSk7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCBjbGVhcigpIHsKLSAgICAgICAgICAgIGZBdWdtZW50YXRpb25zLmNsZWFyKCk7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc0Z1bGwoKSB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgQXVnbWVudGF0aW9uc0l0ZW1zQ29udGFpbmVyIGV4cGFuZCgpIHsKLSAgICAgICAgICAgIHJldHVybiB0aGlzOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKLSAgICAgICAgICAgIFN0cmluZ0J1aWxkZXIgYnVmZiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7Ci0gICAgICAgICAgICBidWZmLmFwcGVuZCgiTGFyZ2VDb250YWluZXIiKTsKLSAgICAgICAgICAgIGZvcihPYmplY3Qga2V5IDogZkF1Z21lbnRhdGlvbnMua2V5U2V0KCkpIHsKLSAgICAgICAgICAgICAgICBidWZmLmFwcGVuZCgiXG5rZXkgPT0gIik7Ci0gICAgICAgICAgICAgICAgYnVmZi5hcHBlbmQoa2V5KTsKLSAgICAgICAgICAgICAgICBidWZmLmFwcGVuZCgiOyB2YWx1ZSA9PSAiKTsKLSAgICAgICAgICAgICAgICBidWZmLmFwcGVuZChmQXVnbWVudGF0aW9ucy5nZXQoa2V5KSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gYnVmZi50b1N0cmluZygpOwotICAgICAgICB9Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9ET01FbnRpdHlSZXNvbHZlcldyYXBwZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3V0aWwvRE9NRW50aXR5UmVzb2x2ZXJXcmFwcGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGZkZmQ5ZjQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9ET01FbnRpdHlSZXNvbHZlcldyYXBwZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE3MCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbDsKLQotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE5JRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTFJlc291cmNlSWRlbnRpZmllcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5ncmFtbWFycy5YTUxHcmFtbWFyRGVzY3JpcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTEVudGl0eVJlc29sdmVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxJbnB1dFNvdXJjZTsKLQotaW1wb3J0IG9yZy53M2MuZG9tLmxzLkxTUmVzb3VyY2VSZXNvbHZlcjsKLWltcG9ydCBvcmcudzNjLmRvbS5scy5MU0lucHV0OwotCi1pbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotaW1wb3J0IGphdmEuaW8uUmVhZGVyOwotaW1wb3J0IGphdmEuaW8uU3RyaW5nUmVhZGVyOwotCi0KLS8qKgotICogVGhpcyBjbGFzcyB3cmFwcyBET00gZW50aXR5IHJlc29sdmVyIHRvIFhOSSBlbnRpdHkgcmVzb2x2ZXIuCi0gKgotICogQHNlZSBMU1Jlc291cmNlUmVzb2x2ZXIKLSAqCi0gKiBAYXV0aG9yIEdvcGFsIFNoYXJtYSwgU1VOIE1pY3JvU3lzdGVtcyBJbmMuCi0gKiBAYXV0aG9yIEVsZW5hIExpdGFuaSwgSUJNCi0gKiBAYXV0aG9yIFJhbWVzaCBNYW5kYXZhLCBTdW4gTWljcm9zeXN0ZW1zCi0gKi8KLXB1YmxpYyBjbGFzcyBET01FbnRpdHlSZXNvbHZlcldyYXBwZXIKLSAgICBpbXBsZW1lbnRzIFhNTEVudGl0eVJlc29sdmVyIHsKLQotICAgIC8vCi0gICAgLy8gRGF0YQotICAgIC8vCi0KLSAgICAvKiogWE1MIDEuMCB0eXBlIGNvbnN0YW50IGFjY29yZGluZyB0byBET00gTDMgTFMgQ1Igc3BlYyAiaHR0cDovL3d3dy53My5vcmcvVFIvMjAwMy9DUi1ET00tTGV2ZWwtMy1MUy0yMDAzMTEwNyIgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MX1RZUEUgPSAiaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLXhtbCI7Ci0KLSAgICAvKiogWE1MIFNjaGVtYSBjb25zdGFudCBhY2NvcmRpbmcgdG8gRE9NIEwzIExTIENSIHNwZWMgImh0dHA6Ly93d3cudzMub3JnL1RSLzIwMDMvQ1ItRE9NLUxldmVsLTMtTFMtMjAwMzExMDciICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFhTRF9UWVBFID0gImh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hIjsKLQotICAgIC8qKiBUaGUgRE9NIGVudGl0eSByZXNvbHZlci4gKi8KLSAgICBwcm90ZWN0ZWQgTFNSZXNvdXJjZVJlc29sdmVyIGZFbnRpdHlSZXNvbHZlcjsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKiBEZWZhdWx0IGNvbnN0cnVjdG9yLiAqLwotICAgIHB1YmxpYyBET01FbnRpdHlSZXNvbHZlcldyYXBwZXIoKSB7fQotCi0gICAgLyoqIFdyYXBzIHRoZSBzcGVjaWZpZWQgRE9NIGVudGl0eSByZXNvbHZlci4gKi8KLSAgICBwdWJsaWMgRE9NRW50aXR5UmVzb2x2ZXJXcmFwcGVyKExTUmVzb3VyY2VSZXNvbHZlciBlbnRpdHlSZXNvbHZlcikgewotICAgICAgICBzZXRFbnRpdHlSZXNvbHZlcihlbnRpdHlSZXNvbHZlcik7Ci0gICAgfSAvLyBMU1Jlc291cmNlUmVzb2x2ZXIKLQotICAgIC8vCi0gICAgLy8gUHVibGljIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqIFNldHMgdGhlIERPTSBlbnRpdHkgcmVzb2x2ZXIuICovCi0gICAgcHVibGljIHZvaWQgc2V0RW50aXR5UmVzb2x2ZXIoTFNSZXNvdXJjZVJlc29sdmVyIGVudGl0eVJlc29sdmVyKSB7Ci0gICAgICAgIGZFbnRpdHlSZXNvbHZlciA9IGVudGl0eVJlc29sdmVyOwotICAgIH0gLy8gc2V0RW50aXR5UmVzb2x2ZXIoTFNSZXNvdXJjZVJlc29sdmVyKQotCi0gICAgLyoqIFJldHVybnMgdGhlIERPTSBlbnRpdHkgcmVzb2x2ZXIuICovCi0gICAgcHVibGljIExTUmVzb3VyY2VSZXNvbHZlciBnZXRFbnRpdHlSZXNvbHZlcigpIHsKLSAgICAgICAgcmV0dXJuIGZFbnRpdHlSZXNvbHZlcjsKLSAgICB9IC8vIGdldEVudGl0eVJlc29sdmVyKCk6TFNSZXNvdXJjZVJlc29sdmVyCi0KLSAgICAvLwotICAgIC8vIFhNTEVudGl0eVJlc29sdmVyIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogUmVzb2x2ZXMgYW4gZXh0ZXJuYWwgcGFyc2VkIGVudGl0eS4gSWYgdGhlIGVudGl0eSBjYW5ub3QgYmUKLSAgICAgKiByZXNvbHZlZCwgdGhpcyBtZXRob2Qgc2hvdWxkIHJldHVybiBudWxsLgotICAgICAqCi0gICAgICogQHBhcmFtIHJlc291cmNlSWRlbnRpZmllciAgICAgICAgZGVzY3JpcHRpb24gb2YgdGhlIHJlc291cmNlIHRvIGJlIHJldnNvdmVkCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIG9uIGdlbmVyYWwgZXJyb3IuCi0gICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiAgVGhyb3duIGlmIHJlc29sdmVkIGVudGl0eSBzdHJlYW0gY2Fubm90IGJlCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgb3BlbmVkIG9yIHNvbWUgb3RoZXIgaS9vIGVycm9yIG9jY3Vycy4KLSAgICAgKi8KLSAgICBwdWJsaWMgWE1MSW5wdXRTb3VyY2UgcmVzb2x2ZUVudGl0eShYTUxSZXNvdXJjZUlkZW50aWZpZXIgcmVzb3VyY2VJZGVudGlmaWVyKQotICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgIC8vIHJlc29sdmUgZW50aXR5IHVzaW5nIERPTSBlbnRpdHkgcmVzb2x2ZXIKLSAgICAgICAgaWYgKGZFbnRpdHlSZXNvbHZlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAvLyBGb3IgZW50aXR5IHJlc29sdXRpb24gdGhlIHR5cGUgb2YgdGhlIHJlc291cmNlIHdvdWxkIGJlICBYTUwgVFlQRQotICAgICAgICAgICAgLy8gRE9NIEwzIExTIHNwZWMgbWVudGlvbiBvbmx5IHRoZSBYTUwgMS4wIHJlY29tbWVuZGF0aW9uIHJpZ2h0IG5vdwotICAgICAgICAgICAgTFNJbnB1dCBpbnB1dFNvdXJjZSA9Ci0gICAgICAgICAgICAgICAgcmVzb3VyY2VJZGVudGlmaWVyID09IG51bGwKLSAgICAgICAgICAgICAgICAgICAgPyBmRW50aXR5UmVzb2x2ZXIucmVzb2x2ZVJlc291cmNlKAotICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwKLSAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsCi0gICAgICAgICAgICAgICAgICAgICAgICBudWxsLAotICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwKLSAgICAgICAgICAgICAgICAgICAgICAgIG51bGwpCi0gICAgICAgICAgICAgICAgICAgIDogZkVudGl0eVJlc29sdmVyLnJlc29sdmVSZXNvdXJjZSgKLSAgICAgICAgICAgICAgICAgICAgICAgIGdldFR5cGUocmVzb3VyY2VJZGVudGlmaWVyKSwKLSAgICAgICAgICAgICAgICAgICAgICAgIHJlc291cmNlSWRlbnRpZmllci5nZXROYW1lc3BhY2UoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgIHJlc291cmNlSWRlbnRpZmllci5nZXRQdWJsaWNJZCgpLAotICAgICAgICAgICAgICAgICAgICAgICAgcmVzb3VyY2VJZGVudGlmaWVyLmdldExpdGVyYWxTeXN0ZW1JZCgpLAotICAgICAgICAgICAgICAgICAgICAgICAgcmVzb3VyY2VJZGVudGlmaWVyLmdldEJhc2VTeXN0ZW1JZCgpKTsKLSAgICAgICAgICAgIGlmIChpbnB1dFNvdXJjZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIHB1YmxpY0lkID0gaW5wdXRTb3VyY2UuZ2V0UHVibGljSWQoKTsKLSAgICAgICAgICAgICAgICBTdHJpbmcgc3lzdGVtSWQgPSBpbnB1dFNvdXJjZS5nZXRTeXN0ZW1JZCgpOwotICAgICAgICAgICAgICAgIFN0cmluZyBiYXNlU3lzdGVtSWQgPSBpbnB1dFNvdXJjZS5nZXRCYXNlVVJJKCk7Ci0gICAgICAgICAgICAgICAgSW5wdXRTdHJlYW0gYnl0ZVN0cmVhbSA9IGlucHV0U291cmNlLmdldEJ5dGVTdHJlYW0oKTsKLSAgICAgICAgICAgICAgICBSZWFkZXIgY2hhclN0cmVhbSA9IGlucHV0U291cmNlLmdldENoYXJhY3RlclN0cmVhbSgpOwotICAgICAgICAgICAgICAgIFN0cmluZyBlbmNvZGluZyA9IGlucHV0U291cmNlLmdldEVuY29kaW5nKCk7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIGRhdGEgPSBpbnB1dFNvdXJjZS5nZXRTdHJpbmdEYXRhKCk7Ci0KLSAgICAgICAgICAgICAgICAvKioKLSAgICAgICAgICAgICAgICAgKiBBbiBMU1BhcnNlciBsb29rcyBhdCBpbnB1dHMgc3BlY2lmaWVkIGluIExTSW5wdXQgaW4KLSAgICAgICAgICAgICAgICAgKiB0aGUgZm9sbG93aW5nIG9yZGVyOiBjaGFyYWN0ZXJTdHJlYW0sIGJ5dGVTdHJlYW0sCi0gICAgICAgICAgICAgICAgICogc3RyaW5nRGF0YSwgc3lzdGVtSWQsIHB1YmxpY0lkLgotICAgICAgICAgICAgICAgICAqLwotICAgICAgICAgICAgICAgIFhNTElucHV0U291cmNlIHhtbElucHV0U291cmNlID0KLSAgICAgICAgICAgICAgICAgICAgbmV3IFhNTElucHV0U291cmNlKHB1YmxpY0lkLCBzeXN0ZW1JZCwgYmFzZVN5c3RlbUlkKTsKLQotICAgICAgICAgICAgICAgIGlmIChjaGFyU3RyZWFtICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgeG1sSW5wdXRTb3VyY2Uuc2V0Q2hhcmFjdGVyU3RyZWFtKGNoYXJTdHJlYW0pOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIGlmIChieXRlU3RyZWFtICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgeG1sSW5wdXRTb3VyY2Uuc2V0Qnl0ZVN0cmVhbSgoSW5wdXRTdHJlYW0pIGJ5dGVTdHJlYW0pOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIGlmIChkYXRhICE9IG51bGwgJiYgZGF0YS5sZW5ndGgoKSAhPSAwKSB7Ci0gICAgICAgICAgICAgICAgICAgIHhtbElucHV0U291cmNlLnNldENoYXJhY3RlclN0cmVhbShuZXcgU3RyaW5nUmVhZGVyKGRhdGEpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgeG1sSW5wdXRTb3VyY2Uuc2V0RW5jb2RpbmcoZW5jb2RpbmcpOwotICAgICAgICAgICAgICAgIHJldHVybiB4bWxJbnB1dFNvdXJjZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIHVuYWJsZSB0byByZXNvbHZlIGVudGl0eQotICAgICAgICByZXR1cm4gbnVsbDsKLQotICAgIH0gLy8gcmVzb2x2ZUVudGl0eShTdHJpbmcsU3RyaW5nLFN0cmluZyk6WE1MSW5wdXRTb3VyY2UKLQotICAgIC8qKiBEZXRlcm1pbmVzIHRoZSB0eXBlIG9mIHJlc291cmNlIGJlaW5nIHJlc29sdmVkICoqLwotICAgIHByaXZhdGUgU3RyaW5nIGdldFR5cGUoWE1MUmVzb3VyY2VJZGVudGlmaWVyIHJlc291cmNlSWRlbnRpZmllcikgewotICAgICAgICBpZiAocmVzb3VyY2VJZGVudGlmaWVyIGluc3RhbmNlb2YgWE1MR3JhbW1hckRlc2NyaXB0aW9uKSB7Ci0gICAgICAgICAgICBYTUxHcmFtbWFyRGVzY3JpcHRpb24gZGVzYyA9IChYTUxHcmFtbWFyRGVzY3JpcHRpb24pIHJlc291cmNlSWRlbnRpZmllcjsKLSAgICAgICAgICAgIGlmIChYTUxHcmFtbWFyRGVzY3JpcHRpb24uWE1MX1NDSEVNQS5lcXVhbHMoZGVzYy5nZXRHcmFtbWFyVHlwZSgpKSkgewotICAgICAgICAgICAgICAgIHJldHVybiBYU0RfVFlQRTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gWE1MX1RZUEU7Ci0gICAgfSAvLyBnZXRUeXBlKFhNTFJlc291cmNlSWRlbnRpZmllcik6U3RyaW5nCi0KLX0gLy8gRE9NRW50aXR5UmVzb2x2ZXJXcmFwcGVyCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL0RPTUVycm9ySGFuZGxlcldyYXBwZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3V0aWwvRE9NRXJyb3JIYW5kbGVyV3JhcHBlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4M2M1OWMzLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3V0aWwvRE9NRXJyb3JIYW5kbGVyV3JhcHBlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDIyICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKi8KLS8qCi0gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKLSAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAotICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgotICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKLSAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCi0gKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWw7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbS5ET01FcnJvckltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5kb20uRE9NTG9jYXRvckltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLm1zZy5YTUxNZXNzYWdlRm9ybWF0dGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhOSUV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MRXJyb3JIYW5kbGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxQYXJzZUV4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLlByaW50V3JpdGVyOwotaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKLWltcG9ydCBqYXZhLnV0aWwuTWFwOwotaW1wb3J0IG9yZy53M2MuZG9tLkRPTUVycm9yOwotaW1wb3J0IG9yZy53M2MuZG9tLkRPTUVycm9ySGFuZGxlcjsKLWltcG9ydCBvcmcudzNjLmRvbS5ET01Mb2NhdG9yOwotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci0KLS8qKgotICogVGhpcyBjbGFzcyBoYW5kbGVzIERPTSBlcnJvcnMgLgotICoKLSAqIEBzZWUgRE9NRXJyb3JIYW5kbGVyCi0gKgotICogQGF1dGhvciBHb3BhbCBTaGFybWEsIFNVTiBNaWNyb3N5c3RlbXMgSW5jLgotICovCi0KLS8vIFJFVklTSVQ6IGN1cnJlbnQgaW1wbGVtZW50YXRpb25zIHdyYXBzIGVycm9yIHNldmVyYWwgdGltZXM6Ci0vLyAgICAgICAgICBYTUxFcnJvclJlcG9ydC5yZXBvcnRFcnJvciBjcmVhdGVzIFhNTFBhcnNlckV4Y2VwdGlvbiAoYnkgd3JhcHBpbmcgYWxsIGluZm8pCi0vLyAgICAgICAgICBhbmQgZ29lcyB2aWEgc3dpdGNoIHRvIHNlbmQgZXJyb3JzLgotLy8gICAgICAgICAgRE9NRXJyb3JIYW5kbGVyV3JhcHBlciBjYXRjaGVzIGNhbGxzLCBjb3BpZXMgaW5mbyBmcm9tIFhNTFBhcnNlckV4Y2VwdGlvbiBhbmQKLS8vICAgICAgICAgIHNlbmRzIG9uZSBjYWxsIGJhY2sgdG8gdGhlIGFwcGxpY2F0aW9uCi0vLyAgICAgICAgICBJIHRoaW5rIHdlIGNhbiBhdm9pZCB0aGlzIGluZGlyZWN0aW9uIGlmIHdlIG1vZGlmeSBYTUxFcnJvclJlcG9ydGVyLiAtLWVsCi0KLXB1YmxpYyBjbGFzcyBET01FcnJvckhhbmRsZXJXcmFwcGVyCi0gICAgaW1wbGVtZW50cyBYTUxFcnJvckhhbmRsZXIsIERPTUVycm9ySGFuZGxlciB7Ci0KLQotCi0gICAgLy8gSXQga2VlcHMgdGhlIHJlZmVyZW5jZSBvZiBET01FcnJvckhhbmRsZXIgb2YgYXBwbGljYXRpb24KLSAgICBwcm90ZWN0ZWQgRE9NRXJyb3JIYW5kbGVyIGZEb21FcnJvckhhbmRsZXI7Ci0KLSAgICAvLyBFcnJvciBTdGF0dXMKLSAgICBib29sZWFuIGVTdGF0dXMgPSB0cnVlIDsKLQotICAgIC8vIFByaW50IHdyaXRlcgotICAgIHByb3RlY3RlZCBQcmludFdyaXRlciBmT3V0OwotCi0gICAgLy8gc29tZSBjb21wb25lbnRzIG1heSBzZXQgZXJyb3Igbm9kZQotICAgIC8vIEBzZWUgRE9NTm9ybWFsaXplci4KLSAgICBwdWJsaWMgTm9kZSBmQ3VycmVudE5vZGU7Ci0KLSAgICAvKiogRXJyb3IgY29kZSBmb3IgY29tcGFyaXNvbnMuICoqLwotICAgIHByb3RlY3RlZCBmaW5hbCBYTUxFcnJvckNvZGUgZkVycm9yQ29kZSA9IG5ldyBYTUxFcnJvckNvZGUobnVsbCwgbnVsbCk7Ci0KLSAgICBwcm90ZWN0ZWQgZmluYWwgRE9NRXJyb3JJbXBsIGZET01FcnJvciA9IG5ldyBET01FcnJvckltcGwoKTsKLQotCi0KLSAgICAvLwotICAgIC8vIENvbnN0cnVjdG9ycwotICAgIC8vCi0KLSAgICAvLyBEZWZhdWx0IGNvbnN0cnVjdG9yIC8KLQotICAgIHB1YmxpYyBET01FcnJvckhhbmRsZXJXcmFwcGVyKCkgewotICAgICAgICBmT3V0ID0gbmV3IFByaW50V3JpdGVyKFN5c3RlbS5lcnIpOwotICAgIH0KLQotCi0gICAgcHVibGljIERPTUVycm9ySGFuZGxlcldyYXBwZXIoRE9NRXJyb3JIYW5kbGVyIGRvbUVycm9ySGFuZGxlcikgewotICAgICAgICBmRG9tRXJyb3JIYW5kbGVyID0gZG9tRXJyb3JIYW5kbGVyOwotICAgIH0gLy8gRE9NRXJyb3JIYW5kbGVyV3JhcHBlcihET01FcnJvckhhbmRsZXIgZG9tRXJyb3JIYW5kbGVyKQotCi0KLSAgICAvLwotICAgIC8vIFB1YmxpYyBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKiBTZXRzIHRoZSBET00gZXJyb3IgaGFuZGxlci4gKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRFcnJvckhhbmRsZXIoRE9NRXJyb3JIYW5kbGVyIGVycm9ySGFuZGxlcikgewotICAgICAgICBmRG9tRXJyb3JIYW5kbGVyID0gZXJyb3JIYW5kbGVyOwotICAgIH0gLy8gc2V0RXJyb3JIYW5kbGVyKEVycm9ySGFuZGxlcikKLQotCi0gICAgcHVibGljIERPTUVycm9ySGFuZGxlciBnZXRFcnJvckhhbmRsZXIoKXsKLSAgICAgICAgcmV0dXJuIGZEb21FcnJvckhhbmRsZXI7Ci0gICAgfSAvL2dldEVycm9ySGFuZGxlcigpCi0KLSAgICAvLwotICAgIC8vIFhNTEVycm9ySGFuZGxlciBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFJlcG9ydHMgYSB3YXJuaW5nLiBXYXJuaW5ncyBhcmUgbm9uLWZhdGFsIGFuZCBjYW4gYmUgc2FmZWx5IGlnbm9yZWQKLSAgICAgKiBieSBtb3N0IGFwcGxpY2F0aW9ucy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBkb21haW4gICAgVGhlIGRvbWFpbiBvZiB0aGUgd2FybmluZy4gVGhlIGRvbWFpbiBjYW4gYmUgYW55Ci0gICAgICogICAgICAgICAgICAgICAgICBzdHJpbmcgYnV0IGlzIHN1Z2dlc3RlZCB0byBiZSBhIHZhbGlkIFVSSS4gVGhlCi0gICAgICogICAgICAgICAgICAgICAgICBkb21haW4gY2FuIGJlIHVzZWQgdG8gY29udmVuaWVudGx5IHNwZWNpZnkgYSB3ZWIKLSAgICAgKiAgICAgICAgICAgICAgICAgIHNpdGUgbG9jYXRpb24gb2YgdGhlIHJlbGV2ZW50IHNwZWNpZmljYXRpb24gb3IKLSAgICAgKiAgICAgICAgICAgICAgICAgIGRvY3VtZW50IHBlcnRhaW5pbmcgdG8gdGhpcyB3YXJuaW5nLgotICAgICAqIEBwYXJhbSBrZXkgICAgICAgVGhlIHdhcm5pbmcga2V5LiBUaGlzIGtleSBjYW4gYmUgYW55IHN0cmluZyBhbmQKLSAgICAgKiAgICAgICAgICAgICAgICAgIGlzIGltcGxlbWVudGF0aW9uIGRlcGVuZGVudC4KLSAgICAgKiBAcGFyYW0gZXhjZXB0aW9uIEV4Y2VwdGlvbi4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biB0byBzaWduYWwgdGhhdCB0aGUgcGFyc2VyIHNob3VsZCBzdG9wCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgcGFyc2luZyB0aGUgZG9jdW1lbnQuCi0gICAgICovCi0KLSAgICBwdWJsaWMgdm9pZCB3YXJuaW5nKFN0cmluZyBkb21haW4sIFN0cmluZyBrZXksCi0gICAgICAgICAgICAgICAgICAgICAgICBYTUxQYXJzZUV4Y2VwdGlvbiBleGNlcHRpb24pIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBmRE9NRXJyb3IuZlNldmVyaXR5ID0gRE9NRXJyb3IuU0VWRVJJVFlfV0FSTklORzsKLSAgICAgICAgZkRPTUVycm9yLmZFeGNlcHRpb24gPSBleGNlcHRpb247Ci0gICAgICAgIC8vIFJFVklTSVQ6IE1heSBuZWVkIHRvIGxvb2t1cCBmcm9tIERPTUVycm9yVHlwZU1hcCBpbiB0aGUgZnV0dXJlLgotICAgICAgICBmRE9NRXJyb3IuZlR5cGUgPSBrZXk7Ci0gICAgICAgIGZET01FcnJvci5mUmVsYXRlZERhdGEgPSBmRE9NRXJyb3IuZk1lc3NhZ2UgPSBleGNlcHRpb24uZ2V0TWVzc2FnZSgpOwotICAgICAgICBET01Mb2NhdG9ySW1wbCBsb2NhdG9yID0gZkRPTUVycm9yLmZMb2NhdG9yOwotICAgICAgICBpZiAobG9jYXRvciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBsb2NhdG9yLmZDb2x1bW5OdW1iZXIgPSBleGNlcHRpb24uZ2V0Q29sdW1uTnVtYmVyKCk7Ci0gICAgICAgICAgICBsb2NhdG9yLmZMaW5lTnVtYmVyID0gZXhjZXB0aW9uLmdldExpbmVOdW1iZXIoKTsKLSAgICAgICAgICAgIGxvY2F0b3IuZlV0ZjE2T2Zmc2V0ID0gZXhjZXB0aW9uLmdldENoYXJhY3Rlck9mZnNldCgpOwotICAgICAgICAgICAgbG9jYXRvci5mVXJpID0gZXhjZXB0aW9uLmdldEV4cGFuZGVkU3lzdGVtSWQoKTsKLSAgICAgICAgICAgIGxvY2F0b3IuZlJlbGF0ZWROb2RlID0gZkN1cnJlbnROb2RlOwotICAgICAgICB9Ci0gICAgICAgIGlmIChmRG9tRXJyb3JIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZEb21FcnJvckhhbmRsZXIuaGFuZGxlRXJyb3IoZkRPTUVycm9yKTsKLSAgICAgICAgfQotICAgIH0gLy8gd2FybmluZyhTdHJpbmcsU3RyaW5nLFhNTFBhcnNlRXhjZXB0aW9uKQotCi0gICAgLyoqCi0gICAgICogUmVwb3J0cyBhbiBlcnJvci4gRXJyb3JzIGFyZSBub24tZmF0YWwgYW5kIHVzdWFsbHkgc2lnbmlmeSB0aGF0IHRoZQotICAgICAqIGRvY3VtZW50IGlzIGludmFsaWQgd2l0aCByZXNwZWN0IHRvIGl0cyBncmFtbWFyKHMpLgotICAgICAqCi0gICAgICogQHBhcmFtIGRvbWFpbiAgICBUaGUgZG9tYWluIG9mIHRoZSBlcnJvci4gVGhlIGRvbWFpbiBjYW4gYmUgYW55Ci0gICAgICogICAgICAgICAgICAgICAgICBzdHJpbmcgYnV0IGlzIHN1Z2dlc3RlZCB0byBiZSBhIHZhbGlkIFVSSS4gVGhlCi0gICAgICogICAgICAgICAgICAgICAgICBkb21haW4gY2FuIGJlIHVzZWQgdG8gY29udmVuaWVudGx5IHNwZWNpZnkgYSB3ZWIKLSAgICAgKiAgICAgICAgICAgICAgICAgIHNpdGUgbG9jYXRpb24gb2YgdGhlIHJlbGV2ZW50IHNwZWNpZmljYXRpb24gb3IKLSAgICAgKiAgICAgICAgICAgICAgICAgIGRvY3VtZW50IHBlcnRhaW5pbmcgdG8gdGhpcyBlcnJvci4KLSAgICAgKiBAcGFyYW0ga2V5ICAgICAgIFRoZSBlcnJvciBrZXkuIFRoaXMga2V5IGNhbiBiZSBhbnkgc3RyaW5nIGFuZAotICAgICAqICAgICAgICAgICAgICAgICAgaXMgaW1wbGVtZW50YXRpb24gZGVwZW5kZW50LgotICAgICAqIEBwYXJhbSBleGNlcHRpb24gRXhjZXB0aW9uLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIHRvIHNpZ25hbCB0aGF0IHRoZSBwYXJzZXIgc2hvdWxkIHN0b3AKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBwYXJzaW5nIHRoZSBkb2N1bWVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlcnJvcihTdHJpbmcgZG9tYWluLCBTdHJpbmcga2V5LAotICAgICAgICAgICAgICAgICAgICAgIFhNTFBhcnNlRXhjZXB0aW9uIGV4Y2VwdGlvbikgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIGZET01FcnJvci5mU2V2ZXJpdHkgPSBET01FcnJvci5TRVZFUklUWV9FUlJPUjsKLSAgICAgICAgZkRPTUVycm9yLmZFeGNlcHRpb24gPSBleGNlcHRpb247Ci0gICAgICAgIC8vIFJFVklTSVQ6IE1heSBuZWVkIHRvIGxvb2t1cCBmcm9tIERPTUVycm9yVHlwZU1hcCBpbiB0aGUgZnV0dXJlLgotICAgICAgICBmRE9NRXJyb3IuZlR5cGUgPSBrZXk7Ci0gICAgICAgIGZET01FcnJvci5mUmVsYXRlZERhdGEgPSBmRE9NRXJyb3IuZk1lc3NhZ2UgPSBleGNlcHRpb24uZ2V0TWVzc2FnZSgpOwotICAgICAgICBET01Mb2NhdG9ySW1wbCBsb2NhdG9yID0gZkRPTUVycm9yLmZMb2NhdG9yOwotICAgICAgICBpZiAobG9jYXRvciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBsb2NhdG9yLmZDb2x1bW5OdW1iZXIgPSBleGNlcHRpb24uZ2V0Q29sdW1uTnVtYmVyKCk7Ci0gICAgICAgICAgICBsb2NhdG9yLmZMaW5lTnVtYmVyID0gZXhjZXB0aW9uLmdldExpbmVOdW1iZXIoKTsKLSAgICAgICAgICAgIGxvY2F0b3IuZlV0ZjE2T2Zmc2V0ID0gZXhjZXB0aW9uLmdldENoYXJhY3Rlck9mZnNldCgpOwotICAgICAgICAgICAgbG9jYXRvci5mVXJpID0gZXhjZXB0aW9uLmdldEV4cGFuZGVkU3lzdGVtSWQoKTsKLSAgICAgICAgICAgIGxvY2F0b3IuZlJlbGF0ZWROb2RlPSBmQ3VycmVudE5vZGU7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGZEb21FcnJvckhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkRvbUVycm9ySGFuZGxlci5oYW5kbGVFcnJvcihmRE9NRXJyb3IpOwotICAgICAgICB9Ci0gICAgfSAvLyBlcnJvcihTdHJpbmcsU3RyaW5nLFhNTFBhcnNlRXhjZXB0aW9uKQotCi0gICAgLyoqCi0gICAgICogUmVwb3J0IGEgZmF0YWwgZXJyb3IuIEZhdGFsIGVycm9ycyB1c3VhbGx5IG9jY3VyIHdoZW4gdGhlIGRvY3VtZW50Ci0gICAgICogaXMgbm90IHdlbGwtZm9ybWVkIGFuZCBzaWduaWZpZXMgdGhhdCB0aGUgcGFyc2VyIGNhbm5vdCBjb250aW51ZQotICAgICAqIG5vcm1hbCBvcGVyYXRpb24uCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGUgZXJyb3IgaGFuZGxlciBzaG91bGQgPGVtPmFsd2F5czwvZW0+Ci0gICAgICogdGhyb3cgYW4gPGNvZGU+WE5JRXhjZXB0aW9uPC9jb2RlPiBmcm9tIHRoaXMgbWV0aG9kLiBUaGlzIGV4Y2VwdGlvbgotICAgICAqIGNhbiBlaXRoZXIgYmUgdGhlIHNhbWUgZXhjZXB0aW9uIHRoYXQgaXMgcGFzc2VkIGFzIGEgcGFyYW1ldGVyIHRvCi0gICAgICogdGhlIG1ldGhvZCBvciBhIG5ldyBYTkkgZXhjZXB0aW9uIG9iamVjdC4gSWYgdGhlIHJlZ2lzdGVyZWQgZXJyb3IKLSAgICAgKiBoYW5kbGVyIGZhaWxzIHRvIHRocm93IGFuIGV4Y2VwdGlvbiwgdGhlIGNvbnRpbnVpbmcgb3BlcmF0aW9uIG9mCi0gICAgICogdGhlIHBhcnNlciBpcyB1bmRldGVybWluZWQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZG9tYWluICAgIFRoZSBkb21haW4gb2YgdGhlIGZhdGFsIGVycm9yLiBUaGUgZG9tYWluIGNhbiBiZQotICAgICAqICAgICAgICAgICAgICAgICAgYW55IHN0cmluZyBidXQgaXMgc3VnZ2VzdGVkIHRvIGJlIGEgdmFsaWQgVVJJLiBUaGUKLSAgICAgKiAgICAgICAgICAgICAgICAgIGRvbWFpbiBjYW4gYmUgdXNlZCB0byBjb252ZW5pZW50bHkgc3BlY2lmeSBhIHdlYgotICAgICAqICAgICAgICAgICAgICAgICAgc2l0ZSBsb2NhdGlvbiBvZiB0aGUgcmVsZXZlbnQgc3BlY2lmaWNhdGlvbiBvcgotICAgICAqICAgICAgICAgICAgICAgICAgZG9jdW1lbnQgcGVydGFpbmluZyB0byB0aGlzIGZhdGFsIGVycm9yLgotICAgICAqIEBwYXJhbSBrZXkgICAgICAgVGhlIGZhdGFsIGVycm9yIGtleS4gVGhpcyBrZXkgY2FuIGJlIGFueSBzdHJpbmcKLSAgICAgKiAgICAgICAgICAgICAgICAgIGFuZCBpcyBpbXBsZW1lbnRhdGlvbiBkZXBlbmRlbnQuCi0gICAgICogQHBhcmFtIGV4Y2VwdGlvbiBFeGNlcHRpb24uCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gdG8gc2lnbmFsIHRoYXQgdGhlIHBhcnNlciBzaG91bGQgc3RvcAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIHBhcnNpbmcgdGhlIGRvY3VtZW50LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGZhdGFsRXJyb3IoU3RyaW5nIGRvbWFpbiwgU3RyaW5nIGtleSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTFBhcnNlRXhjZXB0aW9uIGV4Y2VwdGlvbikgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIGZET01FcnJvci5mU2V2ZXJpdHkgPSBET01FcnJvci5TRVZFUklUWV9GQVRBTF9FUlJPUjsKLSAgICAgICAgZkRPTUVycm9yLmZFeGNlcHRpb24gPSBleGNlcHRpb247Ci0gICAgICAgIGZFcnJvckNvZGUuc2V0VmFsdWVzKGRvbWFpbiwga2V5KTsKLSAgICAgICAgU3RyaW5nIGRvbUVycm9yVHlwZSA9IERPTUVycm9yVHlwZU1hcC5nZXRET01FcnJvclR5cGUoZkVycm9yQ29kZSk7Ci0gICAgICAgIGZET01FcnJvci5mVHlwZSA9IChkb21FcnJvclR5cGUgIT0gbnVsbCkgPyBkb21FcnJvclR5cGUgOiBrZXk7Ci0gICAgICAgIGZET01FcnJvci5mUmVsYXRlZERhdGEgPSBmRE9NRXJyb3IuZk1lc3NhZ2UgPSBleGNlcHRpb24uZ2V0TWVzc2FnZSgpOwotICAgICAgICBET01Mb2NhdG9ySW1wbCBsb2NhdG9yID0gZkRPTUVycm9yLmZMb2NhdG9yOwotICAgICAgICBpZiAobG9jYXRvciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBsb2NhdG9yLmZDb2x1bW5OdW1iZXIgPSBleGNlcHRpb24uZ2V0Q29sdW1uTnVtYmVyKCk7Ci0gICAgICAgICAgICBsb2NhdG9yLmZMaW5lTnVtYmVyID0gZXhjZXB0aW9uLmdldExpbmVOdW1iZXIoKTsKLSAgICAgICAgICAgIGxvY2F0b3IuZlV0ZjE2T2Zmc2V0ID0gZXhjZXB0aW9uLmdldENoYXJhY3Rlck9mZnNldCgpOwotICAgICAgICAgICAgbG9jYXRvci5mVXJpID0gZXhjZXB0aW9uLmdldEV4cGFuZGVkU3lzdGVtSWQoKTsKLSAgICAgICAgICAgIGxvY2F0b3IuZlJlbGF0ZWROb2RlID0gZkN1cnJlbnROb2RlOwotICAgICAgICB9Ci0gICAgICAgIGlmIChmRG9tRXJyb3JIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZEb21FcnJvckhhbmRsZXIuaGFuZGxlRXJyb3IoZkRPTUVycm9yKTsKLSAgICAgICAgfQotICAgIH0gLy8gZmF0YWxFcnJvcihTdHJpbmcsU3RyaW5nLFhNTFBhcnNlRXhjZXB0aW9uKQotCi0KLSAgICBwdWJsaWMgYm9vbGVhbiBoYW5kbGVFcnJvcihET01FcnJvciBlcnJvcikgewotICAgICAgICBwcmludEVycm9yKGVycm9yKTsKLSAgICAgICAgcmV0dXJuIGVTdGF0dXM7Ci0gICAgfQotCi0gICAgLyoqIFByaW50cyB0aGUgZXJyb3IgbWVzc2FnZS4gKi8KLQotICAgIHByaXZhdGUgdm9pZCBwcmludEVycm9yKERPTUVycm9yIGVycm9yKSB7Ci0gICAgICAgIGludCBzZXZlcml0eSA9IGVycm9yLmdldFNldmVyaXR5KCk7Ci0gICAgICAgIGZPdXQucHJpbnQoIlsiKTsKLSAgICAgICAgaWYgKCBzZXZlcml0eSA9PSBET01FcnJvci5TRVZFUklUWV9XQVJOSU5HKSB7Ci0gICAgICAgICAgICBmT3V0LnByaW50KCJXYXJuaW5nIik7Ci0gICAgICAgIH0gZWxzZSBpZiAoIHNldmVyaXR5ID09IERPTUVycm9yLlNFVkVSSVRZX0VSUk9SKSB7Ci0gICAgICAgICAgICBmT3V0LnByaW50KCJFcnJvciIpOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgZk91dC5wcmludCgiRmF0YWxFcnJvciIpOwotICAgICAgICAgICAgZVN0YXR1cyA9IGZhbHNlIDsgLy9SRVZJU0lUOiBBYm9ydCBwcm9jZXNzaW5nIGlmIGZhdGFsIGVycm9yLCBkbyB3ZSBuZWVkIHRvPz8KLSAgICAgICAgfQotICAgICAgICBmT3V0LnByaW50KCJdICIpOwotICAgICAgICBET01Mb2NhdG9yIGxvY2F0b3IgPSBlcnJvci5nZXRMb2NhdGlvbigpOwotICAgICAgICBpZiAobG9jYXRvciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmT3V0LnByaW50KGxvY2F0b3IuZ2V0TGluZU51bWJlcigpKTsKLSAgICAgICAgICAgIGZPdXQucHJpbnQoIjoiKTsKLSAgICAgICAgICAgIGZPdXQucHJpbnQobG9jYXRvci5nZXRDb2x1bW5OdW1iZXIoKSk7Ci0gICAgICAgICAgICBmT3V0LnByaW50KCI6Iik7Ci0gICAgICAgICAgICBmT3V0LnByaW50KGxvY2F0b3IuZ2V0Qnl0ZU9mZnNldCgpKTsKLSAgICAgICAgICAgIGZPdXQucHJpbnQoIiwiKTsKLSAgICAgICAgICAgIGZPdXQucHJpbnQobG9jYXRvci5nZXRVdGYxNk9mZnNldCgpKTsKLSAgICAgICAgICAgIE5vZGUgbm9kZSA9IGxvY2F0b3IuZ2V0UmVsYXRlZE5vZGUoKTsKLSAgICAgICAgICAgIGlmIChub2RlICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmT3V0LnByaW50KCJbIik7Ci0gICAgICAgICAgICAgICAgZk91dC5wcmludChub2RlLmdldE5vZGVOYW1lKCkpOwotICAgICAgICAgICAgICAgIGZPdXQucHJpbnQoIl0iKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIFN0cmluZyBzeXN0ZW1JZCA9IGxvY2F0b3IuZ2V0VXJpKCk7Ci0gICAgICAgICAgICBpZiAoc3lzdGVtSWQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGludCBpbmRleCA9IHN5c3RlbUlkLmxhc3RJbmRleE9mKCcvJyk7Ci0gICAgICAgICAgICAgICAgaWYgKGluZGV4ICE9IC0xKQotICAgICAgICAgICAgICAgICAgICBzeXN0ZW1JZCA9IHN5c3RlbUlkLnN1YnN0cmluZyhpbmRleCArIDEpOwotICAgICAgICAgICAgICAgIGZPdXQucHJpbnQoIjogIik7Ci0gICAgICAgICAgICAgICAgZk91dC5wcmludChzeXN0ZW1JZCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgfQotCi0gICAgICAgIGZPdXQucHJpbnQoIjoiKTsKLSAgICAgICAgZk91dC5wcmludChlcnJvci5nZXRNZXNzYWdlKCkpOwotICAgICAgICBmT3V0LnByaW50bG4oKTsKLSAgICAgICAgZk91dC5mbHVzaCgpOwotCi0gICAgfSAvLyBwcmludEVycm9yKERPTUVycm9yKQotCi0gICAgLyoqCi0gICAgICogQSBjb252ZW5pZW5jZSBjbGFzcyBmb3IgY29udmVydGluZyBiZXR3ZWVuIGludGVybmFsCi0gICAgICogZXJyb3IgY29kZXMgYW5kIERPTSBlcnJvciB0eXBlcy4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBET01FcnJvclR5cGVNYXAgewotCi0gICAgICAgIC8qKiBNYXAgZm9yIGNvbnZlcnRpbmcgaW50ZXJuYWwgZXJyb3IgY29kZXMgdG8gRE9NIGVycm9yIHR5cGVzLiAqKi8KLSAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTWFwPFhNTEVycm9yQ29kZSwgU3RyaW5nPiBmZ0RPTUVycm9yVHlwZVRhYmxlOwotCi0gICAgICAgIHN0YXRpYyB7Ci0gICAgICAgICAgICAvLyBpbml0aWFsaXplIGVycm9yIHR5cGUgdGFibGU6IGludGVybmFsIGVycm9yIGNvZGVzIChyZXByZXNlbnRlZCBieSBkb21haW4gYW5kIGtleSkgbmVlZCB0byBiZSBtYXBwZWQgdG8gYSBET00gZXJyb3IgdHlwZS4KLQotICAgICAgICAgICAgLy8gUkVWSVNJVDogZG8gd2VsbC1mb3JtZWRuZXNzIGlzc3VlcyBpbnZvbHZpbmcgWE1MIGRlY2xhcmF0aW9uIDw/eG1sIC4uLiA/PiBuZWVkIHRvIGJlIGFkZGVkIHRvIGhhc2ggdGFibGUgKG5vIFhNTCBkZWNsYXJhdGlvbiBub2RlIGluIERPTSwgYnV0IERvY3VtZW50IGluY2x1ZGVzIHhtbEVuY29kaW5nLCB4bWxTdGFuZGFsb25lLCB4bWxWZXJzaW9uLCBldGMuCi0KLSAgICAgICAgICAgIE1hcDxYTUxFcnJvckNvZGUsIFN0cmluZz4gYURPTUVycm9yVHlwZVRhYmxlID0gbmV3IEhhc2hNYXA8PigpOwotICAgICAgICAgICAgYURPTUVycm9yVHlwZVRhYmxlLnB1dChuZXcgWE1MRXJyb3JDb2RlKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwgIkludmFsaWRDaGFySW5DRFNlY3QiKSwgIndmLWludmFsaWQtY2hhcmFjdGVyIik7Ci0gICAgICAgICAgICBhRE9NRXJyb3JUeXBlVGFibGUucHV0KG5ldyBYTUxFcnJvckNvZGUoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLCAiSW52YWxpZENoYXJJbkNvbnRlbnQiKSwgIndmLWludmFsaWQtY2hhcmFjdGVyIik7Ci0gICAgICAgICAgICBhRE9NRXJyb3JUeXBlVGFibGUucHV0KG5ldyBYTUxFcnJvckNvZGUoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLCAiVHdvQ29sb25zSW5RTmFtZSIpLCAid2YtaW52YWxpZC1jaGFyYWN0ZXItaW4tbm9kZS1uYW1lIik7Ci0gICAgICAgICAgICBhRE9NRXJyb3JUeXBlVGFibGUucHV0KG5ldyBYTUxFcnJvckNvZGUoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLCAiQ29sb25Ob3RMZWdhbFdpdGhOUyIpLCAid2YtaW52YWxpZC1jaGFyYWN0ZXItaW4tbm9kZS1uYW1lIik7Ci0gICAgICAgICAgICBhRE9NRXJyb3JUeXBlVGFibGUucHV0KG5ldyBYTUxFcnJvckNvZGUoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLCAiSW52YWxpZENoYXJJblByb2xvZyIpLCAid2YtaW52YWxpZC1jaGFyYWN0ZXIiKTsgIC8vIGUuZy4gaW4gUHJvY2Vzc2luZyBJbnN0cnVjdGlvbgotCi0gICAgICAgICAgICAvLyBJbnZhbGlkQ2hhckluWE1MRGVjbCBvbWl0dGVkIGJlY2F1c2UgWE1MIGRlY2xhcmF0aW9uIGlzIG5vdCBhIERPTSBOb2RlCi0gICAgICAgICAgICBhRE9NRXJyb3JUeXBlVGFibGUucHV0KG5ldyBYTUxFcnJvckNvZGUoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLCAiQ0RFbmRJbkNvbnRlbnQiKSwgIndmLWludmFsaWQtY2hhcmFjdGVyIik7Ci0gICAgICAgICAgICBhRE9NRXJyb3JUeXBlVGFibGUucHV0KG5ldyBYTUxFcnJvckNvZGUoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLCAiQ0RTZWN0VW50ZXJtaW5hdGVkIiksICJ3Zi1pbnZhbGlkLWNoYXJhY3RlciIpOwotICAgICAgICAgICAgYURPTUVycm9yVHlwZVRhYmxlLnB1dChuZXcgWE1MRXJyb3JDb2RlKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwgIkRvY3R5cGVOb3RBbGxvd2VkIiksICJkb2N0eXBlLW5vdC1hbGxvd2VkIik7Ci0gICAgICAgICAgICBhRE9NRXJyb3JUeXBlVGFibGUucHV0KG5ldyBYTUxFcnJvckNvZGUoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLCAiRVRhZ1JlcXVpcmVkIiksICJ3Zi1pbnZhbGlkLWNoYXJhY3Rlci1pbi1ub2RlLW5hbWUiKTsKLSAgICAgICAgICAgIGFET01FcnJvclR5cGVUYWJsZS5wdXQobmV3IFhNTEVycm9yQ29kZShYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sICJFbGVtZW50VW50ZXJtaW5hdGVkIiksICJ3Zi1pbnZhbGlkLWNoYXJhY3Rlci1pbi1ub2RlLW5hbWUiKTsKLSAgICAgICAgICAgIGFET01FcnJvclR5cGVUYWJsZS5wdXQobmV3IFhNTEVycm9yQ29kZShYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sICJFcVJlcXVpcmVkSW5BdHRyaWJ1dGUiKSwgIndmLWludmFsaWQtY2hhcmFjdGVyIik7Ci0gICAgICAgICAgICBhRE9NRXJyb3JUeXBlVGFibGUucHV0KG5ldyBYTUxFcnJvckNvZGUoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLCAiT3BlblF1b3RlRXhwZWN0ZWQiKSwgIndmLWludmFsaWQtY2hhcmFjdGVyIik7Ci0gICAgICAgICAgICBhRE9NRXJyb3JUeXBlVGFibGUucHV0KG5ldyBYTUxFcnJvckNvZGUoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLCAiQ2xvc2VRdW90ZUV4cGVjdGVkIiksICJ3Zi1pbnZhbGlkLWNoYXJhY3RlciIpOwotICAgICAgICAgICAgYURPTUVycm9yVHlwZVRhYmxlLnB1dChuZXcgWE1MRXJyb3JDb2RlKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwgIkVUYWdVbnRlcm1pbmF0ZWQiKSwgIndmLWludmFsaWQtY2hhcmFjdGVyLWluLW5vZGUtbmFtZSIpOwotICAgICAgICAgICAgYURPTUVycm9yVHlwZVRhYmxlLnB1dChuZXcgWE1MRXJyb3JDb2RlKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwgIk1hcmt1cE5vdFJlY29nbml6ZWRJbkNvbnRlbnQiKSwgIndmLWludmFsaWQtY2hhcmFjdGVyIik7Ci0gICAgICAgICAgICBhRE9NRXJyb3JUeXBlVGFibGUucHV0KG5ldyBYTUxFcnJvckNvZGUoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLCAiRG9jdHlwZUlsbGVnYWxJbkNvbnRlbnQiKSwgImRvY3R5cGUtbm90LWFsbG93ZWQiKTsKLSAgICAgICAgICAgIGFET01FcnJvclR5cGVUYWJsZS5wdXQobmV3IFhNTEVycm9yQ29kZShYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sICJJbnZhbGlkQ2hhckluQXR0VmFsdWUiKSwgIndmLWludmFsaWQtY2hhcmFjdGVyIik7Ci0gICAgICAgICAgICBhRE9NRXJyb3JUeXBlVGFibGUucHV0KG5ldyBYTUxFcnJvckNvZGUoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLCAiSW52YWxpZENoYXJJblBJIiksICJ3Zi1pbnZhbGlkLWNoYXJhY3RlciIpOwotICAgICAgICAgICAgYURPTUVycm9yVHlwZVRhYmxlLnB1dChuZXcgWE1MRXJyb3JDb2RlKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwgIkludmFsaWRDaGFySW5JbnRlcm5hbFN1YnNldCIpLCAid2YtaW52YWxpZC1jaGFyYWN0ZXIiKTsKLSAgICAgICAgICAgIGFET01FcnJvclR5cGVUYWJsZS5wdXQobmV3IFhNTEVycm9yQ29kZShYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sICJRdW90ZVJlcXVpcmVkSW5BdHRWYWx1ZSIpLCAid2YtaW52YWxpZC1jaGFyYWN0ZXIiKTsKLSAgICAgICAgICAgIGFET01FcnJvclR5cGVUYWJsZS5wdXQobmV3IFhNTEVycm9yQ29kZShYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sICJMZXNzdGhhbkluQXR0VmFsdWUiKSwgIndmLWludmFsaWQtY2hhcmFjdGVyIik7Ci0gICAgICAgICAgICBhRE9NRXJyb3JUeXBlVGFibGUucHV0KG5ldyBYTUxFcnJvckNvZGUoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLCAiQXR0cmlidXRlVmFsdWVVbnRlcm1pbmF0ZWQiKSwgIndmLWludmFsaWQtY2hhcmFjdGVyIik7Ci0gICAgICAgICAgICBhRE9NRXJyb3JUeXBlVGFibGUucHV0KG5ldyBYTUxFcnJvckNvZGUoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLCAiUElUYXJnZXRSZXF1aXJlZCIpLCAid2YtaW52YWxpZC1jaGFyYWN0ZXIiKTsKLSAgICAgICAgICAgIGFET01FcnJvclR5cGVUYWJsZS5wdXQobmV3IFhNTEVycm9yQ29kZShYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sICJTcGFjZVJlcXVpcmVkSW5QSSIpLCAid2YtaW52YWxpZC1jaGFyYWN0ZXIiKTsKLSAgICAgICAgICAgIGFET01FcnJvclR5cGVUYWJsZS5wdXQobmV3IFhNTEVycm9yQ29kZShYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sICJQSVVudGVybWluYXRlZCIpLCAid2YtaW52YWxpZC1jaGFyYWN0ZXIiKTsKLSAgICAgICAgICAgIGFET01FcnJvclR5cGVUYWJsZS5wdXQobmV3IFhNTEVycm9yQ29kZShYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sICJSZXNlcnZlZFBJVGFyZ2V0IiksICJ3Zi1pbnZhbGlkLWNoYXJhY3RlciIpOwotICAgICAgICAgICAgYURPTUVycm9yVHlwZVRhYmxlLnB1dChuZXcgWE1MRXJyb3JDb2RlKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwgIlBJX05PVF9JTl9PTkVfRU5USVRZIiksICJ3Zi1pbnZhbGlkLWNoYXJhY3RlciIpOwotICAgICAgICAgICAgYURPTUVycm9yVHlwZVRhYmxlLnB1dChuZXcgWE1MRXJyb3JDb2RlKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwgIlBJTm90SW5PbmVFbnRpdHkiKSwgIndmLWludmFsaWQtY2hhcmFjdGVyIik7Ci0gICAgICAgICAgICBhRE9NRXJyb3JUeXBlVGFibGUucHV0KG5ldyBYTUxFcnJvckNvZGUoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLCAiRW5jb2RpbmdEZWNsSW52YWxpZCIpLCAidW5zdXBwb3J0ZWQtZW5jb2RpbmciKTsKLSAgICAgICAgICAgIGFET01FcnJvclR5cGVUYWJsZS5wdXQobmV3IFhNTEVycm9yQ29kZShYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sICJFbmNvZGluZ0J5dGVPcmRlclVuc3VwcG9ydGVkIiksICJ1bnN1cHBvcnRlZC1lbmNvZGluZyIpOwotICAgICAgICAgICAgYURPTUVycm9yVHlwZVRhYmxlLnB1dChuZXcgWE1MRXJyb3JDb2RlKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwgIkludmFsaWRDaGFySW5FbnRpdHlWYWx1ZSIpLCAid2YtaW52YWxpZC1jaGFyYWN0ZXItaW4tbm9kZS1uYW1lIik7Ci0gICAgICAgICAgICBhRE9NRXJyb3JUeXBlVGFibGUucHV0KG5ldyBYTUxFcnJvckNvZGUoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLCAiSW52YWxpZENoYXJJbkV4dGVybmFsU3Vic2V0IiksICJ3Zi1pbnZhbGlkLWNoYXJhY3RlciIpOwotICAgICAgICAgICAgYURPTUVycm9yVHlwZVRhYmxlLnB1dChuZXcgWE1MRXJyb3JDb2RlKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwgIkludmFsaWRDaGFySW5JZ25vcmVTZWN0IiksICJ3Zi1pbnZhbGlkLWNoYXJhY3RlciIpOwotICAgICAgICAgICAgYURPTUVycm9yVHlwZVRhYmxlLnB1dChuZXcgWE1MRXJyb3JDb2RlKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwgIkludmFsaWRDaGFySW5QdWJsaWNJRCIpLCAid2YtaW52YWxpZC1jaGFyYWN0ZXIiKTsKLSAgICAgICAgICAgIGFET01FcnJvclR5cGVUYWJsZS5wdXQobmV3IFhNTEVycm9yQ29kZShYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sICJJbnZhbGlkQ2hhckluU3lzdGVtSUQiKSwgIndmLWludmFsaWQtY2hhcmFjdGVyIik7Ci0gICAgICAgICAgICBhRE9NRXJyb3JUeXBlVGFibGUucHV0KG5ldyBYTUxFcnJvckNvZGUoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLCAiU3BhY2VSZXF1aXJlZEFmdGVyU1lTVEVNIiksICJ3Zi1pbnZhbGlkLWNoYXJhY3RlciIpOwotICAgICAgICAgICAgYURPTUVycm9yVHlwZVRhYmxlLnB1dChuZXcgWE1MRXJyb3JDb2RlKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwgIlF1b3RlUmVxdWlyZWRJblN5c3RlbUlEIiksICJ3Zi1pbnZhbGlkLWNoYXJhY3RlciIpOwotICAgICAgICAgICAgYURPTUVycm9yVHlwZVRhYmxlLnB1dChuZXcgWE1MRXJyb3JDb2RlKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwgIlN5c3RlbUlEVW50ZXJtaW5hdGVkIiksICJ3Zi1pbnZhbGlkLWNoYXJhY3RlciIpOwotICAgICAgICAgICAgYURPTUVycm9yVHlwZVRhYmxlLnB1dChuZXcgWE1MRXJyb3JDb2RlKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwgIlNwYWNlUmVxdWlyZWRBZnRlclBVQkxJQyIpLCAid2YtaW52YWxpZC1jaGFyYWN0ZXIiKTsKLSAgICAgICAgICAgIGFET01FcnJvclR5cGVUYWJsZS5wdXQobmV3IFhNTEVycm9yQ29kZShYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sICJRdW90ZVJlcXVpcmVkSW5QdWJsaWNJRCIpLCAid2YtaW52YWxpZC1jaGFyYWN0ZXIiKTsKLSAgICAgICAgICAgIGFET01FcnJvclR5cGVUYWJsZS5wdXQobmV3IFhNTEVycm9yQ29kZShYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sICJQdWJsaWNJRFVudGVybWluYXRlZCIpLCAid2YtaW52YWxpZC1jaGFyYWN0ZXIiKTsKLSAgICAgICAgICAgIGFET01FcnJvclR5cGVUYWJsZS5wdXQobmV3IFhNTEVycm9yQ29kZShYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sICJQdWJpZENoYXJJbGxlZ2FsIiksICJ3Zi1pbnZhbGlkLWNoYXJhY3RlciIpOwotICAgICAgICAgICAgYURPTUVycm9yVHlwZVRhYmxlLnB1dChuZXcgWE1MRXJyb3JDb2RlKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwgIlNwYWNlUmVxdWlyZWRCZXR3ZWVuUHVibGljQW5kU3lzdGVtIiksICJ3Zi1pbnZhbGlkLWNoYXJhY3RlciIpOwotICAgICAgICAgICAgYURPTUVycm9yVHlwZVRhYmxlLnB1dChuZXcgWE1MRXJyb3JDb2RlKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwgIk1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfUk9PVF9FTEVNRU5UX1RZUEVfSU5fRE9DVFlQRURFQ0wiKSwgIndmLWludmFsaWQtY2hhcmFjdGVyLWluLW5vZGUtbmFtZSIpOyAgLy8gY29uc2lkZXJlZCBlcnJvciBpbiBuYW1lIG9mIG5vZGUgKHdoaWNoIGZvbGxvd3MgIURPQ1RZUEUpCi0gICAgICAgICAgICBhRE9NRXJyb3JUeXBlVGFibGUucHV0KG5ldyBYTUxFcnJvckNvZGUoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLCAiTVNHX1JPT1RfRUxFTUVOVF9UWVBFX1JFUVVJUkVEIiksICJ3Zi1pbnZhbGlkLWNoYXJhY3Rlci1pbi1ub2RlLW5hbWUiKTsKLSAgICAgICAgICAgIGFET01FcnJvclR5cGVUYWJsZS5wdXQobmV3IFhNTEVycm9yQ29kZShYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sICJEb2N0eXBlZGVjbFVudGVybWluYXRlZCIpLCAid2YtaW52YWxpZC1jaGFyYWN0ZXItaW4tbm9kZS1uYW1lIik7Ci0gICAgICAgICAgICBhRE9NRXJyb3JUeXBlVGFibGUucHV0KG5ldyBYTUxFcnJvckNvZGUoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLCAiUEVSZWZlcmVuY2VXaXRoaW5NYXJrdXAiKSwgIndmLWludmFsaWQtY2hhcmFjdGVyIik7Ci0gICAgICAgICAgICBhRE9NRXJyb3JUeXBlVGFibGUucHV0KG5ldyBYTUxFcnJvckNvZGUoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLCAiTVNHX01BUktVUF9OT1RfUkVDT0dOSVpFRF9JTl9EVEQiKSwgIndmLWludmFsaWQtY2hhcmFjdGVyIik7Ci0gICAgICAgICAgICBhRE9NRXJyb3JUeXBlVGFibGUucHV0KG5ldyBYTUxFcnJvckNvZGUoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLCAiTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9FTEVNRU5UX1RZUEVfSU5fRUxFTUVOVERFQ0wiKSwgIndmLWludmFsaWQtY2hhcmFjdGVyIik7Ci0gICAgICAgICAgICBhRE9NRXJyb3JUeXBlVGFibGUucHV0KG5ldyBYTUxFcnJvckNvZGUoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLCAiTVNHX0VMRU1FTlRfVFlQRV9SRVFVSVJFRF9JTl9FTEVNRU5UREVDTCIpLCAid2YtaW52YWxpZC1jaGFyYWN0ZXIiKTsKLSAgICAgICAgICAgIGFET01FcnJvclR5cGVUYWJsZS5wdXQobmV3IFhNTEVycm9yQ29kZShYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sICJNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX0NPTlRFTlRTUEVDX0lOX0VMRU1FTlRERUNMIiksICJ3Zi1pbnZhbGlkLWNoYXJhY3RlciIpOwotICAgICAgICAgICAgYURPTUVycm9yVHlwZVRhYmxlLnB1dChuZXcgWE1MRXJyb3JDb2RlKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwgIk1TR19DT05URU5UU1BFQ19SRVFVSVJFRF9JTl9FTEVNRU5UREVDTCIpLCAid2YtaW52YWxpZC1jaGFyYWN0ZXIiKTsKLSAgICAgICAgICAgIGFET01FcnJvclR5cGVUYWJsZS5wdXQobmV3IFhNTEVycm9yQ29kZShYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sICJFbGVtZW50RGVjbFVudGVybWluYXRlZCIpLCAid2YtaW52YWxpZC1jaGFyYWN0ZXIiKTsKLSAgICAgICAgICAgIGFET01FcnJvclR5cGVUYWJsZS5wdXQobmV3IFhNTEVycm9yQ29kZShYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sICJNU0dfT1BFTl9QQVJFTl9PUl9FTEVNRU5UX1RZUEVfUkVRVUlSRURfSU5fQ0hJTERSRU4iKSwgIndmLWludmFsaWQtY2hhcmFjdGVyIik7Ci0gICAgICAgICAgICBhRE9NRXJyb3JUeXBlVGFibGUucHV0KG5ldyBYTUxFcnJvckNvZGUoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLCAiTVNHX0NMT1NFX1BBUkVOX1JFUVVJUkVEX0lOX0NISUxEUkVOIiksICJ3Zi1pbnZhbGlkLWNoYXJhY3RlciIpOwotICAgICAgICAgICAgYURPTUVycm9yVHlwZVRhYmxlLnB1dChuZXcgWE1MRXJyb3JDb2RlKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwgIk1TR19FTEVNRU5UX1RZUEVfUkVRVUlSRURfSU5fTUlYRURfQ09OVEVOVCIpLCAid2YtaW52YWxpZC1jaGFyYWN0ZXIiKTsKLSAgICAgICAgICAgIGFET01FcnJvclR5cGVUYWJsZS5wdXQobmV3IFhNTEVycm9yQ29kZShYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sICJNU0dfQ0xPU0VfUEFSRU5fUkVRVUlSRURfSU5fTUlYRUQiKSwgIndmLWludmFsaWQtY2hhcmFjdGVyIik7Ci0gICAgICAgICAgICBhRE9NRXJyb3JUeXBlVGFibGUucHV0KG5ldyBYTUxFcnJvckNvZGUoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLCAiTWl4ZWRDb250ZW50VW50ZXJtaW5hdGVkIiksICJ3Zi1pbnZhbGlkLWNoYXJhY3RlciIpOwotICAgICAgICAgICAgYURPTUVycm9yVHlwZVRhYmxlLnB1dChuZXcgWE1MRXJyb3JDb2RlKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwgIk1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfRUxFTUVOVF9UWVBFX0lOX0FUVExJU1RERUNMIiksICJ3Zi1pbnZhbGlkLWNoYXJhY3RlciIpOwotICAgICAgICAgICAgYURPTUVycm9yVHlwZVRhYmxlLnB1dChuZXcgWE1MRXJyb3JDb2RlKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwgIk1TR19FTEVNRU5UX1RZUEVfUkVRVUlSRURfSU5fQVRUTElTVERFQ0wiKSwgIndmLWludmFsaWQtY2hhcmFjdGVyIik7Ci0gICAgICAgICAgICBhRE9NRXJyb3JUeXBlVGFibGUucHV0KG5ldyBYTUxFcnJvckNvZGUoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLCAiTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9BVFRSSUJVVEVfTkFNRV9JTl9BVFRERUYiKSwgIndmLWludmFsaWQtY2hhcmFjdGVyIik7Ci0gICAgICAgICAgICBhRE9NRXJyb3JUeXBlVGFibGUucHV0KG5ldyBYTUxFcnJvckNvZGUoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLCAiQXR0TmFtZVJlcXVpcmVkSW5BdHREZWYiKSwgIndmLWludmFsaWQtY2hhcmFjdGVyIik7Ci0gICAgICAgICAgICBhRE9NRXJyb3JUeXBlVGFibGUucHV0KG5ldyBYTUxFcnJvckNvZGUoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLCAiTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9BVFRUWVBFX0lOX0FUVERFRiIpLCAid2YtaW52YWxpZC1jaGFyYWN0ZXIiKTsKLSAgICAgICAgICAgIGFET01FcnJvclR5cGVUYWJsZS5wdXQobmV3IFhNTEVycm9yQ29kZShYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sICJBdHRUeXBlUmVxdWlyZWRJbkF0dERlZiIpLCAid2YtaW52YWxpZC1jaGFyYWN0ZXIiKTsKLSAgICAgICAgICAgIGFET01FcnJvclR5cGVUYWJsZS5wdXQobmV3IFhNTEVycm9yQ29kZShYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sICJNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX0RFRkFVTFRERUNMX0lOX0FUVERFRiIpLCAid2YtaW52YWxpZC1jaGFyYWN0ZXIiKTsKLSAgICAgICAgICAgIGFET01FcnJvclR5cGVUYWJsZS5wdXQobmV3IFhNTEVycm9yQ29kZShYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sICJNU0dfRFVQTElDQVRFX0FUVFJJQlVURV9ERUZJTklUSU9OIiksICJ3Zi1pbnZhbGlkLWNoYXJhY3RlciIpOwotICAgICAgICAgICAgYURPTUVycm9yVHlwZVRhYmxlLnB1dChuZXcgWE1MRXJyb3JDb2RlKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwgIk1TR19TUEFDRV9SRVFVSVJFRF9BRlRFUl9OT1RBVElPTl9JTl9OT1RBVElPTlRZUEUiKSwgIndmLWludmFsaWQtY2hhcmFjdGVyIik7Ci0gICAgICAgICAgICBhRE9NRXJyb3JUeXBlVGFibGUucHV0KG5ldyBYTUxFcnJvckNvZGUoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLCAiTVNHX09QRU5fUEFSRU5fUkVRVUlSRURfSU5fTk9UQVRJT05UWVBFIiksICJ3Zi1pbnZhbGlkLWNoYXJhY3RlciIpOwotICAgICAgICAgICAgYURPTUVycm9yVHlwZVRhYmxlLnB1dChuZXcgWE1MRXJyb3JDb2RlKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwgIk1TR19OQU1FX1JFUVVJUkVEX0lOX05PVEFUSU9OVFlQRSIpLCAid2YtaW52YWxpZC1jaGFyYWN0ZXIiKTsKLSAgICAgICAgICAgIGFET01FcnJvclR5cGVUYWJsZS5wdXQobmV3IFhNTEVycm9yQ29kZShYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sICJOb3RhdGlvblR5cGVVbnRlcm1pbmF0ZWQiKSwgIndmLWludmFsaWQtY2hhcmFjdGVyIik7Ci0gICAgICAgICAgICBhRE9NRXJyb3JUeXBlVGFibGUucHV0KG5ldyBYTUxFcnJvckNvZGUoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLCAiTVNHX05NVE9LRU5fUkVRVUlSRURfSU5fRU5VTUVSQVRJT04iKSwgIndmLWludmFsaWQtY2hhcmFjdGVyIik7Ci0gICAgICAgICAgICBhRE9NRXJyb3JUeXBlVGFibGUucHV0KG5ldyBYTUxFcnJvckNvZGUoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLCAiRW51bWVyYXRpb25VbnRlcm1pbmF0ZWQiKSwgIndmLWludmFsaWQtY2hhcmFjdGVyIik7Ci0gICAgICAgICAgICBhRE9NRXJyb3JUeXBlVGFibGUucHV0KG5ldyBYTUxFcnJvckNvZGUoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLCAiTVNHX0RJU1RJTkNUX1RPS0VOU19JTl9FTlVNRVJBVElPTiIpLCAid2YtaW52YWxpZC1jaGFyYWN0ZXIiKTsKLSAgICAgICAgICAgIGFET01FcnJvclR5cGVUYWJsZS5wdXQobmV3IFhNTEVycm9yQ29kZShYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sICJNU0dfRElTVElOQ1RfTk9UQVRJT05fSU5fRU5VTUVSQVRJT04iKSwgIndmLWludmFsaWQtY2hhcmFjdGVyIik7Ci0gICAgICAgICAgICBhRE9NRXJyb3JUeXBlVGFibGUucHV0KG5ldyBYTUxFcnJvckNvZGUoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLCAiTVNHX1NQQUNFX1JFUVVJUkVEX0FGVEVSX0ZJWEVEX0lOX0RFRkFVTFRERUNMIiksICJ3Zi1pbnZhbGlkLWNoYXJhY3RlciIpOwotICAgICAgICAgICAgYURPTUVycm9yVHlwZVRhYmxlLnB1dChuZXcgWE1MRXJyb3JDb2RlKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwgIkluY2x1ZGVTZWN0VW50ZXJtaW5hdGVkIiksICJ3Zi1pbnZhbGlkLWNoYXJhY3RlciIpOwotICAgICAgICAgICAgYURPTUVycm9yVHlwZVRhYmxlLnB1dChuZXcgWE1MRXJyb3JDb2RlKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwgIklnbm9yZVNlY3RVbnRlcm1pbmF0ZWQiKSwgIndmLWludmFsaWQtY2hhcmFjdGVyIik7Ci0gICAgICAgICAgICBhRE9NRXJyb3JUeXBlVGFibGUucHV0KG5ldyBYTUxFcnJvckNvZGUoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLCAiTmFtZVJlcXVpcmVkSW5QRVJlZmVyZW5jZSIpLCAid2YtaW52YWxpZC1jaGFyYWN0ZXIiKTsKLSAgICAgICAgICAgIGFET01FcnJvclR5cGVUYWJsZS5wdXQobmV3IFhNTEVycm9yQ29kZShYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sICJTZW1pY29sb25SZXF1aXJlZEluUEVSZWZlcmVuY2UiKSwgIndmLWludmFsaWQtY2hhcmFjdGVyIik7Ci0gICAgICAgICAgICBhRE9NRXJyb3JUeXBlVGFibGUucHV0KG5ldyBYTUxFcnJvckNvZGUoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLCAiTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9FTlRJVFlfTkFNRV9JTl9FTlRJVFlERUNMIiksICJ3Zi1pbnZhbGlkLWNoYXJhY3Rlci1pbi1ub2RlLW5hbWUiKTsgIC8vIGNvbnNpZGVyZWQgZXJyb3IgaW4gbmFtZSBvZiBub2RlICh3aGljaCBmb2xsb3dzICFFTlRJVFkpCi0gICAgICAgICAgICBhRE9NRXJyb3JUeXBlVGFibGUucHV0KG5ldyBYTUxFcnJvckNvZGUoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLCAiTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9QRVJDRU5UX0lOX1BFREVDTCIpLCAid2YtaW52YWxpZC1jaGFyYWN0ZXItaW4tbm9kZS1uYW1lIik7ICAvLyBjb25zaWRlcmVkIGVycm9yIGluIG5hbWUgb2Ygbm9kZSAod2hpY2ggZm9sbG93cyAhRU5USVRZICUpCi0gICAgICAgICAgICBhRE9NRXJyb3JUeXBlVGFibGUucHV0KG5ldyBYTUxFcnJvckNvZGUoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLCAiTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9FTlRJVFlfTkFNRV9JTl9QRURFQ0wiKSwgIndmLWludmFsaWQtY2hhcmFjdGVyLWluLW5vZGUtbmFtZSIpOyAgLy8gY29uc2lkZXJlZCBlcnJvciBpbiBuYW1lIG9mIG5vZGUgKHdoaWNoIGZvbGxvd3MgIUVOVElUWSAlKQotICAgICAgICAgICAgYURPTUVycm9yVHlwZVRhYmxlLnB1dChuZXcgWE1MRXJyb3JDb2RlKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwgIk1TR19FTlRJVFlfTkFNRV9SRVFVSVJFRF9JTl9FTlRJVFlERUNMIiksICJ3Zi1pbnZhbGlkLWNoYXJhY3Rlci1pbi1ub2RlLW5hbWUiKTsgIC8vIGNvbnNpZGVyZWQgZXJyb3IgaW4gbmFtZSBvZiBub2RlICh3aGljaCBmb2xsb3dzICFFTlRJVFkpCi0gICAgICAgICAgICBhRE9NRXJyb3JUeXBlVGFibGUucHV0KG5ldyBYTUxFcnJvckNvZGUoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLCAiTVNHX1NQQUNFX1JFUVVJUkVEX0FGVEVSX0VOVElUWV9OQU1FX0lOX0VOVElUWURFQ0wiKSwgIndmLWludmFsaWQtY2hhcmFjdGVyLWluLW5vZGUtbmFtZSIpOyAgLy8gY29uc2lkZXJlZCBlcnJvciBpbiBuYW1lIG9mIG5vZGUKLSAgICAgICAgICAgIGFET01FcnJvclR5cGVUYWJsZS5wdXQobmV3IFhNTEVycm9yQ29kZShYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sICJNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX05PVEFUSU9OX05BTUVfSU5fVU5QQVJTRURfRU5USVRZREVDTCIpLCAid2YtaW52YWxpZC1jaGFyYWN0ZXIiKTsKLSAgICAgICAgICAgIGFET01FcnJvclR5cGVUYWJsZS5wdXQobmV3IFhNTEVycm9yQ29kZShYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sICJNU0dfU1BBQ0VfUkVRVUlSRURfQkVGT1JFX05EQVRBX0lOX1VOUEFSU0VEX0VOVElUWURFQ0wiKSwgIndmLWludmFsaWQtY2hhcmFjdGVyIik7Ci0gICAgICAgICAgICBhRE9NRXJyb3JUeXBlVGFibGUucHV0KG5ldyBYTUxFcnJvckNvZGUoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLCAiTVNHX05PVEFUSU9OX05BTUVfUkVRVUlSRURfRk9SX1VOUEFSU0VEX0VOVElUWURFQ0wiKSwgIndmLWludmFsaWQtY2hhcmFjdGVyIik7Ci0gICAgICAgICAgICBhRE9NRXJyb3JUeXBlVGFibGUucHV0KG5ldyBYTUxFcnJvckNvZGUoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLCAiRW50aXR5RGVjbFVudGVybWluYXRlZCIpLCAid2YtaW52YWxpZC1jaGFyYWN0ZXItaW4tbm9kZS1uYW1lIik7Ci0gICAgICAgICAgICBhRE9NRXJyb3JUeXBlVGFibGUucHV0KG5ldyBYTUxFcnJvckNvZGUoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLCAiTVNHX0RVUExJQ0FURV9FTlRJVFlfREVGSU5JVElPTiIpLCAid2YtaW52YWxpZC1jaGFyYWN0ZXItaW4tbm9kZS1uYW1lIik7Ci0gICAgICAgICAgICBhRE9NRXJyb3JUeXBlVGFibGUucHV0KG5ldyBYTUxFcnJvckNvZGUoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLCAiRXh0ZXJuYWxJRFJlcXVpcmVkIiksICJ3Zi1pbnZhbGlkLWNoYXJhY3RlciIpOwotICAgICAgICAgICAgYURPTUVycm9yVHlwZVRhYmxlLnB1dChuZXcgWE1MRXJyb3JDb2RlKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwgIk1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfUFVCSURMSVRFUkFMX0lOX0VYVEVSTkFMSUQiKSwgIndmLWludmFsaWQtY2hhcmFjdGVyIik7Ci0gICAgICAgICAgICBhRE9NRXJyb3JUeXBlVGFibGUucHV0KG5ldyBYTUxFcnJvckNvZGUoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLCAiTVNHX1NQQUNFX1JFUVVJUkVEX0FGVEVSX1BVQklETElURVJBTF9JTl9FWFRFUk5BTElEIiksICJ3Zi1pbnZhbGlkLWNoYXJhY3RlciIpOwotICAgICAgICAgICAgYURPTUVycm9yVHlwZVRhYmxlLnB1dChuZXcgWE1MRXJyb3JDb2RlKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwgIk1TR19TUEFDRV9SRVFVSVJFRF9CRUZPUkVfU1lTVEVNTElURVJBTF9JTl9FWFRFUk5BTElEIiksICJ3Zi1pbnZhbGlkLWNoYXJhY3RlciIpOwotICAgICAgICAgICAgYURPTUVycm9yVHlwZVRhYmxlLnB1dChuZXcgWE1MRXJyb3JDb2RlKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwgIk1TR19VUklfRlJBR01FTlRfSU5fU1lTVEVNSUQiKSwgIndmLWludmFsaWQtY2hhcmFjdGVyIik7Ci0gICAgICAgICAgICBhRE9NRXJyb3JUeXBlVGFibGUucHV0KG5ldyBYTUxFcnJvckNvZGUoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLCAiTVNHX1NQQUNFX1JFUVVJUkVEX0JFRk9SRV9OT1RBVElPTl9OQU1FX0lOX05PVEFUSU9OREVDTCIpLCAid2YtaW52YWxpZC1jaGFyYWN0ZXItaW4tbm9kZS1uYW1lIik7ICAvLyBjb25zaWRlcmVkIGVycm9yIGluIG5hbWUgb2Ygbm9kZSwgd2hpY2ggZm9sbG93cyAhTk9UQVRJT04KLSAgICAgICAgICAgIGFET01FcnJvclR5cGVUYWJsZS5wdXQobmV3IFhNTEVycm9yQ29kZShYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sICJNU0dfTk9UQVRJT05fTkFNRV9SRVFVSVJFRF9JTl9OT1RBVElPTkRFQ0wiKSwgIndmLWludmFsaWQtY2hhcmFjdGVyLWluLW5vZGUtbmFtZSIpOyAgLy8gY29uc2lkZXJlZCBlcnJvciBpbiBuYW1lIG9mIG5vZGUsIHdoaWNoIGZvbGxvd3MgIU5PVEFUSU9OCi0gICAgICAgICAgICBhRE9NRXJyb3JUeXBlVGFibGUucHV0KG5ldyBYTUxFcnJvckNvZGUoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLCAiTVNHX1NQQUNFX1JFUVVJUkVEX0FGVEVSX05PVEFUSU9OX05BTUVfSU5fTk9UQVRJT05ERUNMIiksICJ3Zi1pbnZhbGlkLWNoYXJhY3Rlci1pbi1ub2RlLW5hbWUiKTsgIC8vIGNvbnNpZGVyZWQgZXJyb3IgaW4gbmFtZSBvZiBub2RlLCB3aGljaCBmb2xsb3dzICFOT1RBVElPTgotICAgICAgICAgICAgYURPTUVycm9yVHlwZVRhYmxlLnB1dChuZXcgWE1MRXJyb3JDb2RlKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwgIkV4dGVybmFsSURvclB1YmxpY0lEUmVxdWlyZWQiKSwgIndmLWludmFsaWQtY2hhcmFjdGVyIik7Ci0gICAgICAgICAgICBhRE9NRXJyb3JUeXBlVGFibGUucHV0KG5ldyBYTUxFcnJvckNvZGUoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLCAiTm90YXRpb25EZWNsVW50ZXJtaW5hdGVkIiksICJ3Zi1pbnZhbGlkLWNoYXJhY3Rlci1pbi1ub2RlLW5hbWUiKTsKLSAgICAgICAgICAgIGFET01FcnJvclR5cGVUYWJsZS5wdXQobmV3IFhNTEVycm9yQ29kZShYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sICJSZWZlcmVuY2VUb0V4dGVybmFsRW50aXR5IiksICJ3Zi1pbnZhbGlkLWNoYXJhY3RlciIpOwotICAgICAgICAgICAgYURPTUVycm9yVHlwZVRhYmxlLnB1dChuZXcgWE1MRXJyb3JDb2RlKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwgIlJlZmVyZW5jZVRvVW5wYXJzZWRFbnRpdHkiKSwgIndmLWludmFsaWQtY2hhcmFjdGVyIik7Ci0KLSAgICAgICAgICAgIC8vIFJFVklTSVQ6IGRvIEVudGl0eU5vdERlY2xhcmVkLCBSZWN1cnNpdmVSZWZlcmVuY2UsIFJlY3Vyc2l2ZUdlbmVyYWxSZWZlcmVuY2UsIFJlY3Vyc2l2ZVBFUmVmZXJlbmNlIGJlbG9uZyBoZXJlPwotICAgICAgICAgICAgYURPTUVycm9yVHlwZVRhYmxlLnB1dChuZXcgWE1MRXJyb3JDb2RlKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwgIkVuY29kaW5nTm90U3VwcG9ydGVkIiksICJ1bnN1cHBvcnRlZC1lbmNvZGluZyIpOwotICAgICAgICAgICAgYURPTUVycm9yVHlwZVRhYmxlLnB1dChuZXcgWE1MRXJyb3JDb2RlKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwgIkVuY29kaW5nUmVxdWlyZWQiKSwgInVuc3VwcG9ydGVkLWVuY29kaW5nIik7Ci0gICAgICAgICAgICBhRE9NRXJyb3JUeXBlVGFibGUucHV0KG5ldyBYTUxFcnJvckNvZGUoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLCAiSWxsZWdhbFFOYW1lIiksICJ3Zi1pbnZhbGlkLWNoYXJhY3Rlci1pbi1ub2RlLW5hbWUiKTsKLSAgICAgICAgICAgIGFET01FcnJvclR5cGVUYWJsZS5wdXQobmV3IFhNTEVycm9yQ29kZShYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sICJFbGVtZW50WE1MTlNQcmVmaXgiKSwgIndmLWludmFsaWQtY2hhcmFjdGVyLWluLW5vZGUtbmFtZSIpOwotICAgICAgICAgICAgYURPTUVycm9yVHlwZVRhYmxlLnB1dChuZXcgWE1MRXJyb3JDb2RlKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwgIkVsZW1lbnRQcmVmaXhVbmJvdW5kIiksICJ3Zi1pbnZhbGlkLWNoYXJhY3Rlci1pbi1ub2RlLW5hbWUiKTsKLSAgICAgICAgICAgIGFET01FcnJvclR5cGVUYWJsZS5wdXQobmV3IFhNTEVycm9yQ29kZShYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sICJBdHRyaWJ1dGVQcmVmaXhVbmJvdW5kIiksICJ3Zi1pbnZhbGlkLWNoYXJhY3Rlci1pbi1ub2RlLW5hbWUiKTsKLSAgICAgICAgICAgIGFET01FcnJvclR5cGVUYWJsZS5wdXQobmV3IFhNTEVycm9yQ29kZShYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sICJFbXB0eVByZWZpeGVkQXR0TmFtZSIpLCAid2YtaW52YWxpZC1jaGFyYWN0ZXItaW4tbm9kZS1uYW1lIik7Ci0gICAgICAgICAgICBhRE9NRXJyb3JUeXBlVGFibGUucHV0KG5ldyBYTUxFcnJvckNvZGUoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLCAiUHJlZml4RGVjbGFyZWQiKSwgIndmLWludmFsaWQtY2hhcmFjdGVyLWluLW5vZGUtbmFtZSIpOwotCi0gICAgICAgICAgICBmZ0RPTUVycm9yVHlwZVRhYmxlID0gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTWFwKGFET01FcnJvclR5cGVUYWJsZSk7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBnZXRET01FcnJvclR5cGUgKFhNTEVycm9yQ29kZSBlcnJvcikgewotICAgICAgICAgICAgcmV0dXJuIGZnRE9NRXJyb3JUeXBlVGFibGUuZ2V0KGVycm9yKTsKLSAgICAgICAgfQotCi0gICAgICAgIHByaXZhdGUgRE9NRXJyb3JUeXBlTWFwICgpIHt9Ci0gICAgfQotCi19IC8vIGNsYXNzIERPTUVycm9ySGFuZGxlcldyYXBwZXIKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3V0aWwvRE9NSW5wdXRTb3VyY2UuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3V0aWwvRE9NSW5wdXRTb3VyY2UuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNjIxZGQ3ZC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL0RPTUlucHV0U291cmNlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3NiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWw7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MSW5wdXRTb3VyY2U7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLQotLyoqCi0gKiA8cD5BbiA8Y29kZT5YTUxJbnB1dFNvdXJjZTwvY29kZT4gYW5hbG9ndWUgdG8gPGNvZGU+amF2YXgueG1sLnRyYW5zZm9ybS5kb20uRE9NU291cmNlPC9jb2RlPi48L3A+Ci0gKgotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgRE9NSW5wdXRTb3VyY2UgZXh0ZW5kcyBYTUxJbnB1dFNvdXJjZSB7Ci0KLSAgICBwcml2YXRlIE5vZGUgZk5vZGU7Ci0KLSAgICBwdWJsaWMgRE9NSW5wdXRTb3VyY2UoKSB7Ci0gICAgICAgIHRoaXMobnVsbCk7Ci0gICAgfQotCi0gICAgcHVibGljIERPTUlucHV0U291cmNlKE5vZGUgbm9kZSkgewotICAgICAgICBzdXBlcihudWxsLCBnZXRTeXN0ZW1JZEZyb21Ob2RlKG5vZGUpLCBudWxsKTsKLSAgICAgICAgZk5vZGUgPSBub2RlOwotICAgIH0KLQotICAgIHB1YmxpYyBET01JbnB1dFNvdXJjZShOb2RlIG5vZGUsIFN0cmluZyBzeXN0ZW1JZCkgewotICAgICAgICBzdXBlcihudWxsLCBzeXN0ZW1JZCwgbnVsbCk7Ci0gICAgICAgIGZOb2RlID0gbm9kZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgTm9kZSBnZXROb2RlKCkgewotICAgICAgICByZXR1cm4gZk5vZGU7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0Tm9kZShOb2RlIG5vZGUpIHsKLSAgICAgICAgZk5vZGUgPSBub2RlOwotICAgIH0KLQotICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBnZXRTeXN0ZW1JZEZyb21Ob2RlKE5vZGUgbm9kZSkgewotICAgICAgICBpZiAobm9kZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIHJldHVybiBub2RlLmdldEJhc2VVUkkoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIElmIHRoZSBET00gaW1wbGVtZW50YXRpb24gaXMgRE9NIExldmVsIDIKLSAgICAgICAgICAgIC8vIHRoZW4gYSBOb1N1Y2hNZXRob2RFcnJvciB3aWxsIGJlIHRocm93bi4KLSAgICAgICAgICAgIC8vIEp1c3QgaWdub3JlIGl0LgotICAgICAgICAgICAgY2F0Y2ggKE5vU3VjaE1ldGhvZEVycm9yIGUpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIFRoZXJlIHdhcyBhIGZhaWx1cmUgZm9yIHNvbWUgb3RoZXIgcmVhc29uCi0gICAgICAgICAgICAvLyBJZ25vcmUgaXQgYXMgd2VsbC4KLSAgICAgICAgICAgIGNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotfSAvLyBET01JbnB1dFNvdXJjZQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9ET01VdGlsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL0RPTVV0aWwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNWUwYmMyNC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL0RPTVV0aWwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDkwMSArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDE1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICovCi0vKgotICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCi0gKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKLSAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KLSAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCi0gKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAotICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5kb20uQXR0ckltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5kb20uRG9jdW1lbnRJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5vcHRpLkVsZW1lbnRJbXBsOwotaW1wb3J0IGphdmEudXRpbC5NYXA7Ci1pbXBvcnQgb3JnLnczYy5kb20uQXR0cjsKLWltcG9ydCBvcmcudzNjLmRvbS5ET01FeGNlcHRpb247Ci1pbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7Ci1pbXBvcnQgb3JnLnczYy5kb20uRWxlbWVudDsKLWltcG9ydCBvcmcudzNjLmRvbS5OYW1lZE5vZGVNYXA7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcudzNjLmRvbS5scy5MU0V4Y2VwdGlvbjsKLQotLyoqCi0gKiBTb21lIHVzZWZ1bCB1dGlsaXR5IG1ldGhvZHMuCi0gKiBUaGlzIGNsYXNzIHdhcyBtb2RpZmllZCBpbiBYZXJjZXMyIHdpdGggYSB2aWV3IHRvIGFic3RyYWN0aW5nIGFzCi0gKiBtdWNoIGFzIHBvc3NpYmxlIGF3YXkgZnJvbSB0aGUgcmVwcmVzZW50YXRpb24gb2YgdGhlIHVuZGVybHlpbmcKLSAqIHBhcnNlZCBzdHJ1Y3R1cmUgKGkuZS4sIHRoZSBET00pLiAgVGhpcyB3YXMgZG9uZSBzbyB0aGF0LCBpZiBYZXJjZXMKLSAqIGV2ZXIgYWRvcHRzIGFuIGluLW1lbW9yeSByZXByZXNlbnRhdGlvbiBtb3JlIGVmZmljaWVudCB0aGFuIHRoZSBET00KLSAqIChzdWNoIGFzIGEgRFRNKSwgd2Ugc2hvdWxkIGVhc2lseSBiZSBhYmxlIHRvIGNvbnZlcnQgb3VyIHNjaGVtYQotICogcGFyc2luZyB0byB1dGlsaXplIGl0LgotICoKLSAqIEB2ZXJzaW9uICRJZDogRE9NVXRpbC5qYXZhLHYgMS43IDIwMTAtMTEtMDEgMDQ6NDA6MTQgam9laHcgRXhwICQKLSAqLwotcHVibGljIGNsYXNzIERPTVV0aWwgewotCi0gICAgLy8KLSAgICAvLyBDb25zdHJ1Y3RvcnMKLSAgICAvLwotCi0gICAgLyoqIFRoaXMgY2xhc3MgY2Fubm90IGJlIGluc3RhbnRpYXRlZC4gKi8KLSAgICBwcm90ZWN0ZWQgRE9NVXRpbCgpIHt9Ci0KLSAgICAvLwotICAgIC8vIFB1YmxpYyBzdGF0aWMgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBDb3BpZXMgdGhlIHNvdXJjZSB0cmVlIGludG8gdGhlIHNwZWNpZmllZCBwbGFjZSBpbiBhIGRlc3RpbmF0aW9uCi0gICAgICogdHJlZS4gVGhlIHNvdXJjZSBub2RlIGFuZCBpdHMgY2hpbGRyZW4gYXJlIGFwcGVuZGVkIGFzIGNoaWxkcmVuCi0gICAgICogb2YgdGhlIGRlc3RpbmF0aW9uIG5vZGUuCi0gICAgICogPHA+Ci0gICAgICogPGVtPk5vdGU6PC9lbT4gVGhpcyBpcyBhbiBpdGVyYXRpdmUgaW1wbGVtZW50YXRpb24uCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyB2b2lkIGNvcHlJbnRvKE5vZGUgc3JjLCBOb2RlIGRlc3QpIHRocm93cyBET01FeGNlcHRpb24gewotCi0gICAgICAgIC8vIGdldCBub2RlIGZhY3RvcnkKLSAgICAgICAgRG9jdW1lbnQgZmFjdG9yeSA9IGRlc3QuZ2V0T3duZXJEb2N1bWVudCgpOwotICAgICAgICBib29sZWFuIGRvbWltcGwgPSBmYWN0b3J5IGluc3RhbmNlb2YgRG9jdW1lbnRJbXBsOwotCi0gICAgICAgIC8vIHBsYWNlbWVudCB2YXJpYWJsZXMKLSAgICAgICAgTm9kZSBzdGFydCAgPSBzcmM7Ci0gICAgICAgIE5vZGUgcGFyZW50ID0gc3JjOwotICAgICAgICBOb2RlIHBsYWNlICA9IHNyYzsKLQotICAgICAgICAvLyB0cmF2ZXJzZSBzb3VyY2UgdHJlZQotICAgICAgICB3aGlsZSAocGxhY2UgIT0gbnVsbCkgewotCi0gICAgICAgICAgICAvLyBjb3B5IHRoaXMgbm9kZQotICAgICAgICAgICAgTm9kZSBub2RlID0gbnVsbDsKLSAgICAgICAgICAgIGludCAgdHlwZSA9IHBsYWNlLmdldE5vZGVUeXBlKCk7Ci0gICAgICAgICAgICBzd2l0Y2ggKHR5cGUpIHsKLSAgICAgICAgICAgIGNhc2UgTm9kZS5DREFUQV9TRUNUSU9OX05PREU6IHsKLSAgICAgICAgICAgICAgICBub2RlID0gZmFjdG9yeS5jcmVhdGVDREFUQVNlY3Rpb24ocGxhY2UuZ2V0Tm9kZVZhbHVlKCkpOwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2FzZSBOb2RlLkNPTU1FTlRfTk9ERTogewotICAgICAgICAgICAgICAgIG5vZGUgPSBmYWN0b3J5LmNyZWF0ZUNvbW1lbnQocGxhY2UuZ2V0Tm9kZVZhbHVlKCkpOwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2FzZSBOb2RlLkVMRU1FTlRfTk9ERTogewotICAgICAgICAgICAgICAgIEVsZW1lbnQgZWxlbWVudCA9IGZhY3RvcnkuY3JlYXRlRWxlbWVudChwbGFjZS5nZXROb2RlTmFtZSgpKTsKLSAgICAgICAgICAgICAgICBub2RlID0gZWxlbWVudDsKLSAgICAgICAgICAgICAgICBOYW1lZE5vZGVNYXAgYXR0cnMgID0gcGxhY2UuZ2V0QXR0cmlidXRlcygpOwotICAgICAgICAgICAgICAgIGludCBhdHRyQ291bnQgPSBhdHRycy5nZXRMZW5ndGgoKTsKLSAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGF0dHJDb3VudDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgICAgIEF0dHIgYXR0ciA9IChBdHRyKWF0dHJzLml0ZW0oaSk7Ci0gICAgICAgICAgICAgICAgICAgIFN0cmluZyBhdHRyTmFtZSA9IGF0dHIuZ2V0Tm9kZU5hbWUoKTsKLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGF0dHJWYWx1ZSA9IGF0dHIuZ2V0Tm9kZVZhbHVlKCk7Ci0gICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKGF0dHJOYW1lLCBhdHRyVmFsdWUpOwotICAgICAgICAgICAgICAgICAgICBpZiAoZG9taW1wbCAmJiAhYXR0ci5nZXRTcGVjaWZpZWQoKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgKChBdHRySW1wbCllbGVtZW50LmdldEF0dHJpYnV0ZU5vZGUoYXR0ck5hbWUpKS5zZXRTcGVjaWZpZWQoZmFsc2UpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2FzZSBOb2RlLkVOVElUWV9SRUZFUkVOQ0VfTk9ERTogewotICAgICAgICAgICAgICAgIG5vZGUgPSBmYWN0b3J5LmNyZWF0ZUVudGl0eVJlZmVyZW5jZShwbGFjZS5nZXROb2RlTmFtZSgpKTsKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhc2UgTm9kZS5QUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREU6IHsKLSAgICAgICAgICAgICAgICBub2RlID0gZmFjdG9yeS5jcmVhdGVQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24ocGxhY2UuZ2V0Tm9kZU5hbWUoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgIHBsYWNlLmdldE5vZGVWYWx1ZSgpKTsKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhc2UgTm9kZS5URVhUX05PREU6IHsKLSAgICAgICAgICAgICAgICBub2RlID0gZmFjdG9yeS5jcmVhdGVUZXh0Tm9kZShwbGFjZS5nZXROb2RlVmFsdWUoKSk7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBkZWZhdWx0OiB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiY2FuJ3QgY29weSBub2RlIHR5cGUsICIrCi0gICAgICAgICAgICAgICAgICAgICAgICB0eXBlKyIgKCIrCi0gICAgICAgICAgICAgICAgICAgICAgICBwbGFjZS5nZXROb2RlTmFtZSgpKycpJyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBkZXN0LmFwcGVuZENoaWxkKG5vZGUpOwotCi0gICAgICAgICAgICAvLyBpdGVyYXRlIG92ZXIgY2hpbGRyZW4KLSAgICAgICAgICAgIGlmIChwbGFjZS5oYXNDaGlsZE5vZGVzKCkpIHsKLSAgICAgICAgICAgICAgICBwYXJlbnQgPSBwbGFjZTsKLSAgICAgICAgICAgICAgICBwbGFjZSAgPSBwbGFjZS5nZXRGaXJzdENoaWxkKCk7Ci0gICAgICAgICAgICAgICAgZGVzdCAgID0gbm9kZTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gYWR2YW5jZQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgcGxhY2UgPSBwbGFjZS5nZXROZXh0U2libGluZygpOwotICAgICAgICAgICAgICAgIHdoaWxlIChwbGFjZSA9PSBudWxsICYmIHBhcmVudCAhPSBzdGFydCkgewotICAgICAgICAgICAgICAgICAgICBwbGFjZSAgPSBwYXJlbnQuZ2V0TmV4dFNpYmxpbmcoKTsKLSAgICAgICAgICAgICAgICAgICAgcGFyZW50ID0gcGFyZW50LmdldFBhcmVudE5vZGUoKTsKLSAgICAgICAgICAgICAgICAgICAgZGVzdCAgID0gZGVzdC5nZXRQYXJlbnROb2RlKCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgIH0KLQotICAgIH0gLy8gY29weUludG8oTm9kZSxOb2RlKQotCi0gICAgLyoqIEZpbmRzIGFuZCByZXR1cm5zIHRoZSBmaXJzdCBjaGlsZCBlbGVtZW50IG5vZGUuICovCi0gICAgcHVibGljIHN0YXRpYyBFbGVtZW50IGdldEZpcnN0Q2hpbGRFbGVtZW50KE5vZGUgcGFyZW50KSB7Ci0KLSAgICAgICAgLy8gc2VhcmNoIGZvciBub2RlCi0gICAgICAgIE5vZGUgY2hpbGQgPSBwYXJlbnQuZ2V0Rmlyc3RDaGlsZCgpOwotICAgICAgICB3aGlsZSAoY2hpbGQgIT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKGNoaWxkLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5FTEVNRU5UX05PREUpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gKEVsZW1lbnQpY2hpbGQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjaGlsZCA9IGNoaWxkLmdldE5leHRTaWJsaW5nKCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBub3QgZm91bmQKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0KLSAgICB9IC8vIGdldEZpcnN0Q2hpbGRFbGVtZW50KE5vZGUpOkVsZW1lbnQKLQotICAgIC8qKiBGaW5kcyBhbmQgcmV0dXJucyB0aGUgZmlyc3QgdmlzaWJsZSBjaGlsZCBlbGVtZW50IG5vZGUuICovCi0gICAgcHVibGljIHN0YXRpYyBFbGVtZW50IGdldEZpcnN0VmlzaWJsZUNoaWxkRWxlbWVudChOb2RlIHBhcmVudCkgewotCi0gICAgICAgIC8vIHNlYXJjaCBmb3Igbm9kZQotICAgICAgICBOb2RlIGNoaWxkID0gcGFyZW50LmdldEZpcnN0Q2hpbGQoKTsKLSAgICAgICAgd2hpbGUgKGNoaWxkICE9IG51bGwpIHsKLSAgICAgICAgICAgIGlmIChjaGlsZC5nZXROb2RlVHlwZSgpID09IE5vZGUuRUxFTUVOVF9OT0RFICYmCi0gICAgICAgICAgICAgICAgICAgICFpc0hpZGRlbihjaGlsZCkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gKEVsZW1lbnQpY2hpbGQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjaGlsZCA9IGNoaWxkLmdldE5leHRTaWJsaW5nKCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBub3QgZm91bmQKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0KLSAgICB9IC8vIGdldEZpcnN0Q2hpbGRFbGVtZW50KE5vZGUpOkVsZW1lbnQKLQotICAgIC8qKiBGaW5kcyBhbmQgcmV0dXJucyB0aGUgZmlyc3QgdmlzaWJsZSBjaGlsZCBlbGVtZW50IG5vZGUuICovCi0gICAgcHVibGljIHN0YXRpYyBFbGVtZW50IGdldEZpcnN0VmlzaWJsZUNoaWxkRWxlbWVudChOb2RlIHBhcmVudCwgTWFwPE5vZGUsIFN0cmluZz4gaGlkZGVuTm9kZXMpIHsKLQotICAgICAgICAvLyBzZWFyY2ggZm9yIG5vZGUKLSAgICAgICAgTm9kZSBjaGlsZCA9IHBhcmVudC5nZXRGaXJzdENoaWxkKCk7Ci0gICAgICAgIHdoaWxlIChjaGlsZCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAoY2hpbGQuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLkVMRU1FTlRfTk9ERSAmJgotICAgICAgICAgICAgICAgICAgICAhaXNIaWRkZW4oY2hpbGQsIGhpZGRlbk5vZGVzKSkgewotICAgICAgICAgICAgICAgIHJldHVybiAoRWxlbWVudCljaGlsZDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNoaWxkID0gY2hpbGQuZ2V0TmV4dFNpYmxpbmcoKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIG5vdCBmb3VuZAotICAgICAgICByZXR1cm4gbnVsbDsKLQotICAgIH0gLy8gZ2V0Rmlyc3RDaGlsZEVsZW1lbnQoTm9kZSk6RWxlbWVudAotCi0gICAgLyoqIEZpbmRzIGFuZCByZXR1cm5zIHRoZSBsYXN0IGNoaWxkIGVsZW1lbnQgbm9kZS4KLSAgICAgKiAgT3ZlcmxvYWQgcHJldmlvdXMgbWV0aG9kIGZvciBub24tWGVyY2VzIG5vZGUgaW1wbC4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIEVsZW1lbnQgZ2V0TGFzdENoaWxkRWxlbWVudChOb2RlIHBhcmVudCkgewotCi0gICAgICAgIC8vIHNlYXJjaCBmb3Igbm9kZQotICAgICAgICBOb2RlIGNoaWxkID0gcGFyZW50LmdldExhc3RDaGlsZCgpOwotICAgICAgICB3aGlsZSAoY2hpbGQgIT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKGNoaWxkLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5FTEVNRU5UX05PREUpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gKEVsZW1lbnQpY2hpbGQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjaGlsZCA9IGNoaWxkLmdldFByZXZpb3VzU2libGluZygpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gbm90IGZvdW5kCi0gICAgICAgIHJldHVybiBudWxsOwotCi0gICAgfSAvLyBnZXRMYXN0Q2hpbGRFbGVtZW50KE5vZGUpOkVsZW1lbnQKLQotICAgIC8qKiBGaW5kcyBhbmQgcmV0dXJucyB0aGUgbGFzdCB2aXNpYmxlIGNoaWxkIGVsZW1lbnQgbm9kZS4gKi8KLSAgICBwdWJsaWMgc3RhdGljIEVsZW1lbnQgZ2V0TGFzdFZpc2libGVDaGlsZEVsZW1lbnQoTm9kZSBwYXJlbnQpIHsKLQotICAgICAgICAvLyBzZWFyY2ggZm9yIG5vZGUKLSAgICAgICAgTm9kZSBjaGlsZCA9IHBhcmVudC5nZXRMYXN0Q2hpbGQoKTsKLSAgICAgICAgd2hpbGUgKGNoaWxkICE9IG51bGwpIHsKLSAgICAgICAgICAgIGlmIChjaGlsZC5nZXROb2RlVHlwZSgpID09IE5vZGUuRUxFTUVOVF9OT0RFICYmCi0gICAgICAgICAgICAgICAgICAgICFpc0hpZGRlbihjaGlsZCkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gKEVsZW1lbnQpY2hpbGQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjaGlsZCA9IGNoaWxkLmdldFByZXZpb3VzU2libGluZygpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gbm90IGZvdW5kCi0gICAgICAgIHJldHVybiBudWxsOwotCi0gICAgfSAvLyBnZXRMYXN0Q2hpbGRFbGVtZW50KE5vZGUpOkVsZW1lbnQKLQotICAgIC8qKiBGaW5kcyBhbmQgcmV0dXJucyB0aGUgbGFzdCB2aXNpYmxlIGNoaWxkIGVsZW1lbnQgbm9kZS4KLSAgICAgKiAgT3ZlcmxvYWQgcHJldmlvdXMgbWV0aG9kIGZvciBub24tWGVyY2VzIG5vZGUgaW1wbAotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgRWxlbWVudCBnZXRMYXN0VmlzaWJsZUNoaWxkRWxlbWVudChOb2RlIHBhcmVudCwgTWFwPE5vZGUsIFN0cmluZz4gaGlkZGVuTm9kZXMpIHsKLQotICAgICAgICAvLyBzZWFyY2ggZm9yIG5vZGUKLSAgICAgICAgTm9kZSBjaGlsZCA9IHBhcmVudC5nZXRMYXN0Q2hpbGQoKTsKLSAgICAgICAgd2hpbGUgKGNoaWxkICE9IG51bGwpIHsKLSAgICAgICAgICAgIGlmIChjaGlsZC5nZXROb2RlVHlwZSgpID09IE5vZGUuRUxFTUVOVF9OT0RFICYmCi0gICAgICAgICAgICAgICAgICAgICFpc0hpZGRlbihjaGlsZCwgaGlkZGVuTm9kZXMpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIChFbGVtZW50KWNoaWxkOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2hpbGQgPSBjaGlsZC5nZXRQcmV2aW91c1NpYmxpbmcoKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIG5vdCBmb3VuZAotICAgICAgICByZXR1cm4gbnVsbDsKLQotICAgIH0gLy8gZ2V0TGFzdENoaWxkRWxlbWVudChOb2RlKTpFbGVtZW50Ci0gICAgLyoqIEZpbmRzIGFuZCByZXR1cm5zIHRoZSBuZXh0IHNpYmxpbmcgZWxlbWVudCBub2RlLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgRWxlbWVudCBnZXROZXh0U2libGluZ0VsZW1lbnQoTm9kZSBub2RlKSB7Ci0KLSAgICAgICAgLy8gc2VhcmNoIGZvciBub2RlCi0gICAgICAgIE5vZGUgc2libGluZyA9IG5vZGUuZ2V0TmV4dFNpYmxpbmcoKTsKLSAgICAgICAgd2hpbGUgKHNpYmxpbmcgIT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKHNpYmxpbmcuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLkVMRU1FTlRfTk9ERSkgewotICAgICAgICAgICAgICAgIHJldHVybiAoRWxlbWVudClzaWJsaW5nOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgc2libGluZyA9IHNpYmxpbmcuZ2V0TmV4dFNpYmxpbmcoKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIG5vdCBmb3VuZAotICAgICAgICByZXR1cm4gbnVsbDsKLQotICAgIH0gLy8gZ2V0TmV4dFNpYmxpbmdFbGVtZW50KE5vZGUpOkVsZW1lbnQKLQotICAgIC8vIGdldCBuZXh0IHZpc2libGUgKHVuLWhpZGRlbikgbm9kZS4KLSAgICBwdWJsaWMgc3RhdGljIEVsZW1lbnQgZ2V0TmV4dFZpc2libGVTaWJsaW5nRWxlbWVudChOb2RlIG5vZGUpIHsKLQotICAgICAgICAvLyBzZWFyY2ggZm9yIG5vZGUKLSAgICAgICAgTm9kZSBzaWJsaW5nID0gbm9kZS5nZXROZXh0U2libGluZygpOwotICAgICAgICB3aGlsZSAoc2libGluZyAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAoc2libGluZy5nZXROb2RlVHlwZSgpID09IE5vZGUuRUxFTUVOVF9OT0RFICYmCi0gICAgICAgICAgICAgICAgICAgICFpc0hpZGRlbihzaWJsaW5nKSkgewotICAgICAgICAgICAgICAgIHJldHVybiAoRWxlbWVudClzaWJsaW5nOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgc2libGluZyA9IHNpYmxpbmcuZ2V0TmV4dFNpYmxpbmcoKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIG5vdCBmb3VuZAotICAgICAgICByZXR1cm4gbnVsbDsKLQotICAgIH0gLy8gZ2V0TmV4dFNpYmxpbmdkRWxlbWVudChOb2RlKTpFbGVtZW50Ci0KLSAgICAvLyBnZXQgbmV4dCB2aXNpYmxlICh1bi1oaWRkZW4pIG5vZGUsIG92ZXJsb2FkIHByZXZpb3VzIG1ldGhvZCBmb3Igbm9uIFhlcmNlcyBub2RlIGltcGwKLSAgICBwdWJsaWMgc3RhdGljIEVsZW1lbnQgZ2V0TmV4dFZpc2libGVTaWJsaW5nRWxlbWVudChOb2RlIG5vZGUsIE1hcDxOb2RlLCBTdHJpbmc+IGhpZGRlbk5vZGVzKSB7Ci0KLSAgICAgICAgLy8gc2VhcmNoIGZvciBub2RlCi0gICAgICAgIE5vZGUgc2libGluZyA9IG5vZGUuZ2V0TmV4dFNpYmxpbmcoKTsKLSAgICAgICAgd2hpbGUgKHNpYmxpbmcgIT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKHNpYmxpbmcuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLkVMRU1FTlRfTk9ERSAmJgotICAgICAgICAgICAgICAgICAgICAhaXNIaWRkZW4oc2libGluZywgaGlkZGVuTm9kZXMpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIChFbGVtZW50KXNpYmxpbmc7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBzaWJsaW5nID0gc2libGluZy5nZXROZXh0U2libGluZygpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gbm90IGZvdW5kCi0gICAgICAgIHJldHVybiBudWxsOwotCi0gICAgfSAvLyBnZXROZXh0U2libGluZ2RFbGVtZW50KE5vZGUpOkVsZW1lbnQKLQotICAgIC8vIHNldCB0aGlzIE5vZGUgYXMgYmVpbmcgaGlkZGVuCi0gICAgcHVibGljIHN0YXRpYyB2b2lkIHNldEhpZGRlbihOb2RlIG5vZGUpIHsKLSAgICAgICAgaWYgKG5vZGUgaW5zdGFuY2VvZiBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMub3B0aS5Ob2RlSW1wbCkKLSAgICAgICAgICAgICgoY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLm9wdGkuTm9kZUltcGwpbm9kZSkuc2V0UmVhZE9ubHkodHJ1ZSwgZmFsc2UpOwotICAgICAgICBlbHNlIGlmIChub2RlIGluc3RhbmNlb2YgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5kb20uTm9kZUltcGwpCi0gICAgICAgICAgICAoKGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tLk5vZGVJbXBsKW5vZGUpLnNldFJlYWRPbmx5KHRydWUsIGZhbHNlKTsKLSAgICB9IC8vIHNldEhpZGRlbihub2RlKTp2b2lkCi0KLSAgICAvLyBzZXQgdGhpcyBOb2RlIGFzIGJlaW5nIGhpZGRlbiwgb3ZlcmxvYWRlZCBtZXRob2QKLSAgICBwdWJsaWMgc3RhdGljIHZvaWQgc2V0SGlkZGVuKE5vZGUgbm9kZSwgTWFwPE5vZGUsIFN0cmluZz4gaGlkZGVuTm9kZXMpIHsKLSAgICAgICAgaWYgKG5vZGUgaW5zdGFuY2VvZiBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMub3B0aS5Ob2RlSW1wbCkgewotICAgICAgICAgICAgKChjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMub3B0aS5Ob2RlSW1wbClub2RlKS5zZXRSZWFkT25seSh0cnVlLCBmYWxzZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgaGlkZGVuTm9kZXMucHV0KG5vZGUsICIiKTsKLSAgICAgICAgfQotICAgIH0gLy8gc2V0SGlkZGVuKG5vZGUpOnZvaWQKLQotICAgIC8vIHNldCB0aGlzIE5vZGUgYXMgYmVpbmcgdmlzaWJsZQotICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzZXRWaXNpYmxlKE5vZGUgbm9kZSkgewotICAgICAgICBpZiAobm9kZSBpbnN0YW5jZW9mIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5vcHRpLk5vZGVJbXBsKQotICAgICAgICAgICAgKChjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMub3B0aS5Ob2RlSW1wbClub2RlKS5zZXRSZWFkT25seShmYWxzZSwgZmFsc2UpOwotICAgICAgICBlbHNlIGlmIChub2RlIGluc3RhbmNlb2YgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5kb20uTm9kZUltcGwpCi0gICAgICAgICAgICAoKGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tLk5vZGVJbXBsKW5vZGUpLnNldFJlYWRPbmx5KGZhbHNlLCBmYWxzZSk7Ci0gICAgfSAvLyBzZXRWaXNpYmxlKG5vZGUpOnZvaWQKLQotICAgIC8vIHNldCB0aGlzIE5vZGUgYXMgYmVpbmcgdmlzaWJsZSwgb3ZlcmxvYWRlZCBtZXRob2QKLSAgICBwdWJsaWMgc3RhdGljIHZvaWQgc2V0VmlzaWJsZShOb2RlIG5vZGUsIE1hcDxOb2RlLCBTdHJpbmc+IGhpZGRlbk5vZGVzKSB7Ci0gICAgICAgIGlmIChub2RlIGluc3RhbmNlb2YgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLm9wdGkuTm9kZUltcGwpIHsKLSAgICAgICAgICAgICgoY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLm9wdGkuTm9kZUltcGwpbm9kZSkuc2V0UmVhZE9ubHkoZmFsc2UsIGZhbHNlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIGhpZGRlbk5vZGVzLnJlbW92ZShub2RlKTsKLSAgICAgICAgfQotICAgIH0gLy8gc2V0VmlzaWJsZShub2RlKTp2b2lkCi0KLSAgICAvLyBpcyB0aGlzIG5vZGUgaGlkZGVuPwotICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0hpZGRlbihOb2RlIG5vZGUpIHsKLSAgICAgICAgaWYgKG5vZGUgaW5zdGFuY2VvZiBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMub3B0aS5Ob2RlSW1wbCkKLSAgICAgICAgICAgIHJldHVybiAoKGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5vcHRpLk5vZGVJbXBsKW5vZGUpLmdldFJlYWRPbmx5KCk7Ci0gICAgICAgIGVsc2UgaWYgKG5vZGUgaW5zdGFuY2VvZiBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbS5Ob2RlSW1wbCkKLSAgICAgICAgICAgIHJldHVybiAoKGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tLk5vZGVJbXBsKW5vZGUpLmdldFJlYWRPbmx5KCk7Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9IC8vIGlzSGlkZGVuKE5vZGUpOmJvb2xlYW4KLQotICAgIC8vIGlzIHRoaXMgbm9kZSBoaWRkZW4/IG92ZXJsb2FkZWQgbWV0aG9kCi0gICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzSGlkZGVuKE5vZGUgbm9kZSwgTWFwPE5vZGUsIFN0cmluZz4gaGlkZGVuTm9kZXMpIHsKLSAgICAgICAgaWYgKG5vZGUgaW5zdGFuY2VvZiBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMub3B0aS5Ob2RlSW1wbCkgewotICAgICAgICAgICAgcmV0dXJuICgoY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLm9wdGkuTm9kZUltcGwpbm9kZSkuZ2V0UmVhZE9ubHkoKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiBoaWRkZW5Ob2Rlcy5jb250YWluc0tleShub2RlKTsKLSAgICAgICAgfQotICAgIH0gLy8gaXNIaWRkZW4oTm9kZSk6Ym9vbGVhbgotCi0gICAgLyoqIEZpbmRzIGFuZCByZXR1cm5zIHRoZSBmaXJzdCBjaGlsZCBub2RlIHdpdGggdGhlIGdpdmVuIG5hbWUuICovCi0gICAgcHVibGljIHN0YXRpYyBFbGVtZW50IGdldEZpcnN0Q2hpbGRFbGVtZW50KE5vZGUgcGFyZW50LCBTdHJpbmcgZWxlbU5hbWUpIHsKLQotICAgICAgICAvLyBzZWFyY2ggZm9yIG5vZGUKLSAgICAgICAgTm9kZSBjaGlsZCA9IHBhcmVudC5nZXRGaXJzdENoaWxkKCk7Ci0gICAgICAgIHdoaWxlIChjaGlsZCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAoY2hpbGQuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLkVMRU1FTlRfTk9ERSkgewotICAgICAgICAgICAgICAgIGlmIChjaGlsZC5nZXROb2RlTmFtZSgpLmVxdWFscyhlbGVtTmFtZSkpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChFbGVtZW50KWNoaWxkOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNoaWxkID0gY2hpbGQuZ2V0TmV4dFNpYmxpbmcoKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIG5vdCBmb3VuZAotICAgICAgICByZXR1cm4gbnVsbDsKLQotICAgIH0gLy8gZ2V0Rmlyc3RDaGlsZEVsZW1lbnQoTm9kZSxTdHJpbmcpOkVsZW1lbnQKLQotICAgIC8qKiBGaW5kcyBhbmQgcmV0dXJucyB0aGUgbGFzdCBjaGlsZCBub2RlIHdpdGggdGhlIGdpdmVuIG5hbWUuICovCi0gICAgcHVibGljIHN0YXRpYyBFbGVtZW50IGdldExhc3RDaGlsZEVsZW1lbnQoTm9kZSBwYXJlbnQsIFN0cmluZyBlbGVtTmFtZSkgewotCi0gICAgICAgIC8vIHNlYXJjaCBmb3Igbm9kZQotICAgICAgICBOb2RlIGNoaWxkID0gcGFyZW50LmdldExhc3RDaGlsZCgpOwotICAgICAgICB3aGlsZSAoY2hpbGQgIT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKGNoaWxkLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5FTEVNRU5UX05PREUpIHsKLSAgICAgICAgICAgICAgICBpZiAoY2hpbGQuZ2V0Tm9kZU5hbWUoKS5lcXVhbHMoZWxlbU5hbWUpKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiAoRWxlbWVudCljaGlsZDsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjaGlsZCA9IGNoaWxkLmdldFByZXZpb3VzU2libGluZygpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gbm90IGZvdW5kCi0gICAgICAgIHJldHVybiBudWxsOwotCi0gICAgfSAvLyBnZXRMYXN0Q2hpbGRFbGVtZW50KE5vZGUsU3RyaW5nKTpFbGVtZW50Ci0KLSAgICAvKiogRmluZHMgYW5kIHJldHVybnMgdGhlIG5leHQgc2libGluZyBub2RlIHdpdGggdGhlIGdpdmVuIG5hbWUuICovCi0gICAgcHVibGljIHN0YXRpYyBFbGVtZW50IGdldE5leHRTaWJsaW5nRWxlbWVudChOb2RlIG5vZGUsIFN0cmluZyBlbGVtTmFtZSkgewotCi0gICAgICAgIC8vIHNlYXJjaCBmb3Igbm9kZQotICAgICAgICBOb2RlIHNpYmxpbmcgPSBub2RlLmdldE5leHRTaWJsaW5nKCk7Ci0gICAgICAgIHdoaWxlIChzaWJsaW5nICE9IG51bGwpIHsKLSAgICAgICAgICAgIGlmIChzaWJsaW5nLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5FTEVNRU5UX05PREUpIHsKLSAgICAgICAgICAgICAgICBpZiAoc2libGluZy5nZXROb2RlTmFtZSgpLmVxdWFscyhlbGVtTmFtZSkpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChFbGVtZW50KXNpYmxpbmc7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgc2libGluZyA9IHNpYmxpbmcuZ2V0TmV4dFNpYmxpbmcoKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIG5vdCBmb3VuZAotICAgICAgICByZXR1cm4gbnVsbDsKLQotICAgIH0gLy8gZ2V0TmV4dFNpYmxpbmdkRWxlbWVudChOb2RlLFN0cmluZyk6RWxlbWVudAotCi0gICAgLyoqIEZpbmRzIGFuZCByZXR1cm5zIHRoZSBmaXJzdCBjaGlsZCBub2RlIHdpdGggdGhlIGdpdmVuIHF1YWxpZmllZCBuYW1lLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgRWxlbWVudCBnZXRGaXJzdENoaWxkRWxlbWVudE5TKE5vZGUgcGFyZW50LAotICAgICAgICAgICAgU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FscGFydCkgewotCi0gICAgICAgIC8vIHNlYXJjaCBmb3Igbm9kZQotICAgICAgICBOb2RlIGNoaWxkID0gcGFyZW50LmdldEZpcnN0Q2hpbGQoKTsKLSAgICAgICAgd2hpbGUgKGNoaWxkICE9IG51bGwpIHsKLSAgICAgICAgICAgIGlmIChjaGlsZC5nZXROb2RlVHlwZSgpID09IE5vZGUuRUxFTUVOVF9OT0RFKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIGNoaWxkVVJJID0gY2hpbGQuZ2V0TmFtZXNwYWNlVVJJKCk7Ci0gICAgICAgICAgICAgICAgaWYgKGNoaWxkVVJJICE9IG51bGwgJiYgY2hpbGRVUkkuZXF1YWxzKHVyaSkgJiYKLSAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkLmdldExvY2FsTmFtZSgpLmVxdWFscyhsb2NhbHBhcnQpKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiAoRWxlbWVudCljaGlsZDsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjaGlsZCA9IGNoaWxkLmdldE5leHRTaWJsaW5nKCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBub3QgZm91bmQKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0KLSAgICB9IC8vIGdldEZpcnN0Q2hpbGRFbGVtZW50TlMoTm9kZSxTdHJpbmcsU3RyaW5nKTpFbGVtZW50Ci0KLSAgICAvKiogRmluZHMgYW5kIHJldHVybnMgdGhlIGxhc3QgY2hpbGQgbm9kZSB3aXRoIHRoZSBnaXZlbiBxdWFsaWZpZWQgbmFtZS4gKi8KLSAgICBwdWJsaWMgc3RhdGljIEVsZW1lbnQgZ2V0TGFzdENoaWxkRWxlbWVudE5TKE5vZGUgcGFyZW50LAotICAgICAgICAgICAgU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FscGFydCkgewotCi0gICAgICAgIC8vIHNlYXJjaCBmb3Igbm9kZQotICAgICAgICBOb2RlIGNoaWxkID0gcGFyZW50LmdldExhc3RDaGlsZCgpOwotICAgICAgICB3aGlsZSAoY2hpbGQgIT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKGNoaWxkLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5FTEVNRU5UX05PREUpIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgY2hpbGRVUkkgPSBjaGlsZC5nZXROYW1lc3BhY2VVUkkoKTsKLSAgICAgICAgICAgICAgICBpZiAoY2hpbGRVUkkgIT0gbnVsbCAmJiBjaGlsZFVSSS5lcXVhbHModXJpKSAmJgotICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGQuZ2V0TG9jYWxOYW1lKCkuZXF1YWxzKGxvY2FscGFydCkpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChFbGVtZW50KWNoaWxkOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNoaWxkID0gY2hpbGQuZ2V0UHJldmlvdXNTaWJsaW5nKCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBub3QgZm91bmQKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0KLSAgICB9IC8vIGdldExhc3RDaGlsZEVsZW1lbnROUyhOb2RlLFN0cmluZyxTdHJpbmcpOkVsZW1lbnQKLQotICAgIC8qKiBGaW5kcyBhbmQgcmV0dXJucyB0aGUgbmV4dCBzaWJsaW5nIG5vZGUgd2l0aCB0aGUgZ2l2ZW4gcXVhbGlmaWVkIG5hbWUuICovCi0gICAgcHVibGljIHN0YXRpYyBFbGVtZW50IGdldE5leHRTaWJsaW5nRWxlbWVudE5TKE5vZGUgbm9kZSwKLSAgICAgICAgICAgIFN0cmluZyB1cmksIFN0cmluZyBsb2NhbHBhcnQpIHsKLQotICAgICAgICAvLyBzZWFyY2ggZm9yIG5vZGUKLSAgICAgICAgTm9kZSBzaWJsaW5nID0gbm9kZS5nZXROZXh0U2libGluZygpOwotICAgICAgICB3aGlsZSAoc2libGluZyAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAoc2libGluZy5nZXROb2RlVHlwZSgpID09IE5vZGUuRUxFTUVOVF9OT0RFKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIHNpYmxpbmdVUkkgPSBzaWJsaW5nLmdldE5hbWVzcGFjZVVSSSgpOwotICAgICAgICAgICAgICAgIGlmIChzaWJsaW5nVVJJICE9IG51bGwgJiYgc2libGluZ1VSSS5lcXVhbHModXJpKSAmJgotICAgICAgICAgICAgICAgICAgICAgICAgc2libGluZy5nZXRMb2NhbE5hbWUoKS5lcXVhbHMobG9jYWxwYXJ0KSkgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gKEVsZW1lbnQpc2libGluZzsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBzaWJsaW5nID0gc2libGluZy5nZXROZXh0U2libGluZygpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gbm90IGZvdW5kCi0gICAgICAgIHJldHVybiBudWxsOwotCi0gICAgfSAvLyBnZXROZXh0U2libGluZ2RFbGVtZW50TlMoTm9kZSxTdHJpbmcsU3RyaW5nKTpFbGVtZW50Ci0KLSAgICAvKiogRmluZHMgYW5kIHJldHVybnMgdGhlIGZpcnN0IGNoaWxkIG5vZGUgd2l0aCB0aGUgZ2l2ZW4gbmFtZS4gKi8KLSAgICBwdWJsaWMgc3RhdGljIEVsZW1lbnQgZ2V0Rmlyc3RDaGlsZEVsZW1lbnQoTm9kZSBwYXJlbnQsIFN0cmluZyBlbGVtTmFtZXNbXSkgewotCi0gICAgICAgIC8vIHNlYXJjaCBmb3Igbm9kZQotICAgICAgICBOb2RlIGNoaWxkID0gcGFyZW50LmdldEZpcnN0Q2hpbGQoKTsKLSAgICAgICAgd2hpbGUgKGNoaWxkICE9IG51bGwpIHsKLSAgICAgICAgICAgIGlmIChjaGlsZC5nZXROb2RlVHlwZSgpID09IE5vZGUuRUxFTUVOVF9OT0RFKSB7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBlbGVtTmFtZXMubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGNoaWxkLmdldE5vZGVOYW1lKCkuZXF1YWxzKGVsZW1OYW1lc1tpXSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoRWxlbWVudCljaGlsZDsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNoaWxkID0gY2hpbGQuZ2V0TmV4dFNpYmxpbmcoKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIG5vdCBmb3VuZAotICAgICAgICByZXR1cm4gbnVsbDsKLQotICAgIH0gLy8gZ2V0Rmlyc3RDaGlsZEVsZW1lbnQoTm9kZSxTdHJpbmdbXSk6RWxlbWVudAotCi0gICAgLyoqIEZpbmRzIGFuZCByZXR1cm5zIHRoZSBsYXN0IGNoaWxkIG5vZGUgd2l0aCB0aGUgZ2l2ZW4gbmFtZS4gKi8KLSAgICBwdWJsaWMgc3RhdGljIEVsZW1lbnQgZ2V0TGFzdENoaWxkRWxlbWVudChOb2RlIHBhcmVudCwgU3RyaW5nIGVsZW1OYW1lc1tdKSB7Ci0KLSAgICAgICAgLy8gc2VhcmNoIGZvciBub2RlCi0gICAgICAgIE5vZGUgY2hpbGQgPSBwYXJlbnQuZ2V0TGFzdENoaWxkKCk7Ci0gICAgICAgIHdoaWxlIChjaGlsZCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAoY2hpbGQuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLkVMRU1FTlRfTk9ERSkgewotICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZWxlbU5hbWVzLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChjaGlsZC5nZXROb2RlTmFtZSgpLmVxdWFscyhlbGVtTmFtZXNbaV0pKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKEVsZW1lbnQpY2hpbGQ7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjaGlsZCA9IGNoaWxkLmdldFByZXZpb3VzU2libGluZygpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gbm90IGZvdW5kCi0gICAgICAgIHJldHVybiBudWxsOwotCi0gICAgfSAvLyBnZXRMYXN0Q2hpbGRFbGVtZW50KE5vZGUsU3RyaW5nW10pOkVsZW1lbnQKLQotICAgIC8qKiBGaW5kcyBhbmQgcmV0dXJucyB0aGUgbmV4dCBzaWJsaW5nIG5vZGUgd2l0aCB0aGUgZ2l2ZW4gbmFtZS4gKi8KLSAgICBwdWJsaWMgc3RhdGljIEVsZW1lbnQgZ2V0TmV4dFNpYmxpbmdFbGVtZW50KE5vZGUgbm9kZSwgU3RyaW5nIGVsZW1OYW1lc1tdKSB7Ci0KLSAgICAgICAgLy8gc2VhcmNoIGZvciBub2RlCi0gICAgICAgIE5vZGUgc2libGluZyA9IG5vZGUuZ2V0TmV4dFNpYmxpbmcoKTsKLSAgICAgICAgd2hpbGUgKHNpYmxpbmcgIT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKHNpYmxpbmcuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLkVMRU1FTlRfTk9ERSkgewotICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZWxlbU5hbWVzLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChzaWJsaW5nLmdldE5vZGVOYW1lKCkuZXF1YWxzKGVsZW1OYW1lc1tpXSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoRWxlbWVudClzaWJsaW5nOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgc2libGluZyA9IHNpYmxpbmcuZ2V0TmV4dFNpYmxpbmcoKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIG5vdCBmb3VuZAotICAgICAgICByZXR1cm4gbnVsbDsKLQotICAgIH0gLy8gZ2V0TmV4dFNpYmxpbmdkRWxlbWVudChOb2RlLFN0cmluZ1tdKTpFbGVtZW50Ci0KLSAgICAvKiogRmluZHMgYW5kIHJldHVybnMgdGhlIGZpcnN0IGNoaWxkIG5vZGUgd2l0aCB0aGUgZ2l2ZW4gcXVhbGlmaWVkIG5hbWUuICovCi0gICAgcHVibGljIHN0YXRpYyBFbGVtZW50IGdldEZpcnN0Q2hpbGRFbGVtZW50TlMoTm9kZSBwYXJlbnQsCi0gICAgICAgICAgICBTdHJpbmdbXVtdIGVsZW1OYW1lcykgewotCi0gICAgICAgIC8vIHNlYXJjaCBmb3Igbm9kZQotICAgICAgICBOb2RlIGNoaWxkID0gcGFyZW50LmdldEZpcnN0Q2hpbGQoKTsKLSAgICAgICAgd2hpbGUgKGNoaWxkICE9IG51bGwpIHsKLSAgICAgICAgICAgIGlmIChjaGlsZC5nZXROb2RlVHlwZSgpID09IE5vZGUuRUxFTUVOVF9OT0RFKSB7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBlbGVtTmFtZXMubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHVyaSA9IGNoaWxkLmdldE5hbWVzcGFjZVVSSSgpOwotICAgICAgICAgICAgICAgICAgICBpZiAodXJpICE9IG51bGwgJiYgdXJpLmVxdWFscyhlbGVtTmFtZXNbaV1bMF0pICYmCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGQuZ2V0TG9jYWxOYW1lKCkuZXF1YWxzKGVsZW1OYW1lc1tpXVsxXSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoRWxlbWVudCljaGlsZDsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNoaWxkID0gY2hpbGQuZ2V0TmV4dFNpYmxpbmcoKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIG5vdCBmb3VuZAotICAgICAgICByZXR1cm4gbnVsbDsKLQotICAgIH0gLy8gZ2V0Rmlyc3RDaGlsZEVsZW1lbnROUyhOb2RlLFN0cmluZ1tdW10pOkVsZW1lbnQKLQotICAgIC8qKiBGaW5kcyBhbmQgcmV0dXJucyB0aGUgbGFzdCBjaGlsZCBub2RlIHdpdGggdGhlIGdpdmVuIHF1YWxpZmllZCBuYW1lLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgRWxlbWVudCBnZXRMYXN0Q2hpbGRFbGVtZW50TlMoTm9kZSBwYXJlbnQsCi0gICAgICAgICAgICBTdHJpbmdbXVtdIGVsZW1OYW1lcykgewotCi0gICAgICAgIC8vIHNlYXJjaCBmb3Igbm9kZQotICAgICAgICBOb2RlIGNoaWxkID0gcGFyZW50LmdldExhc3RDaGlsZCgpOwotICAgICAgICB3aGlsZSAoY2hpbGQgIT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKGNoaWxkLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5FTEVNRU5UX05PREUpIHsKLSAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGVsZW1OYW1lcy5sZW5ndGg7IGkrKykgewotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdXJpID0gY2hpbGQuZ2V0TmFtZXNwYWNlVVJJKCk7Ci0gICAgICAgICAgICAgICAgICAgIGlmICh1cmkgIT0gbnVsbCAmJiB1cmkuZXF1YWxzKGVsZW1OYW1lc1tpXVswXSkgJiYKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZC5nZXRMb2NhbE5hbWUoKS5lcXVhbHMoZWxlbU5hbWVzW2ldWzFdKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChFbGVtZW50KWNoaWxkOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2hpbGQgPSBjaGlsZC5nZXRQcmV2aW91c1NpYmxpbmcoKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIG5vdCBmb3VuZAotICAgICAgICByZXR1cm4gbnVsbDsKLQotICAgIH0gLy8gZ2V0TGFzdENoaWxkRWxlbWVudE5TKE5vZGUsU3RyaW5nW11bXSk6RWxlbWVudAotCi0gICAgLyoqIEZpbmRzIGFuZCByZXR1cm5zIHRoZSBuZXh0IHNpYmxpbmcgbm9kZSB3aXRoIHRoZSBnaXZlbiBxdWFsaWZpZWQgbmFtZS4gKi8KLSAgICBwdWJsaWMgc3RhdGljIEVsZW1lbnQgZ2V0TmV4dFNpYmxpbmdFbGVtZW50TlMoTm9kZSBub2RlLAotICAgICAgICAgICAgU3RyaW5nW11bXSBlbGVtTmFtZXMpIHsKLQotICAgICAgICAvLyBzZWFyY2ggZm9yIG5vZGUKLSAgICAgICAgTm9kZSBzaWJsaW5nID0gbm9kZS5nZXROZXh0U2libGluZygpOwotICAgICAgICB3aGlsZSAoc2libGluZyAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAoc2libGluZy5nZXROb2RlVHlwZSgpID09IE5vZGUuRUxFTUVOVF9OT0RFKSB7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBlbGVtTmFtZXMubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHVyaSA9IHNpYmxpbmcuZ2V0TmFtZXNwYWNlVVJJKCk7Ci0gICAgICAgICAgICAgICAgICAgIGlmICh1cmkgIT0gbnVsbCAmJiB1cmkuZXF1YWxzKGVsZW1OYW1lc1tpXVswXSkgJiYKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaWJsaW5nLmdldExvY2FsTmFtZSgpLmVxdWFscyhlbGVtTmFtZXNbaV1bMV0pKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKEVsZW1lbnQpc2libGluZzsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHNpYmxpbmcgPSBzaWJsaW5nLmdldE5leHRTaWJsaW5nKCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBub3QgZm91bmQKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0KLSAgICB9IC8vIGdldE5leHRTaWJsaW5nZEVsZW1lbnROUyhOb2RlLFN0cmluZ1tdW10pOkVsZW1lbnQKLQotICAgIC8qKgotICAgICAqIEZpbmRzIGFuZCByZXR1cm5zIHRoZSBmaXJzdCBjaGlsZCBub2RlIHdpdGggdGhlIGdpdmVuIG5hbWUgYW5kCi0gICAgICogYXR0cmlidXRlIG5hbWUsIHZhbHVlIHBhaXIuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBFbGVtZW50IGdldEZpcnN0Q2hpbGRFbGVtZW50KE5vZGUgICBwYXJlbnQsCi0gICAgICAgICAgICBTdHJpbmcgZWxlbU5hbWUsCi0gICAgICAgICAgICBTdHJpbmcgYXR0ck5hbWUsCi0gICAgICAgICAgICBTdHJpbmcgYXR0clZhbHVlKSB7Ci0KLSAgICAgICAgLy8gc2VhcmNoIGZvciBub2RlCi0gICAgICAgIE5vZGUgY2hpbGQgPSBwYXJlbnQuZ2V0Rmlyc3RDaGlsZCgpOwotICAgICAgICB3aGlsZSAoY2hpbGQgIT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKGNoaWxkLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5FTEVNRU5UX05PREUpIHsKLSAgICAgICAgICAgICAgICBFbGVtZW50IGVsZW1lbnQgPSAoRWxlbWVudCljaGlsZDsKLSAgICAgICAgICAgICAgICBpZiAoZWxlbWVudC5nZXROb2RlTmFtZSgpLmVxdWFscyhlbGVtTmFtZSkgJiYKLSAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuZ2V0QXR0cmlidXRlKGF0dHJOYW1lKS5lcXVhbHMoYXR0clZhbHVlKSkgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gZWxlbWVudDsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjaGlsZCA9IGNoaWxkLmdldE5leHRTaWJsaW5nKCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBub3QgZm91bmQKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0KLSAgICB9IC8vIGdldEZpcnN0Q2hpbGRFbGVtZW50KE5vZGUsU3RyaW5nLFN0cmluZyxTdHJpbmcpOkVsZW1lbnQKLQotICAgIC8qKgotICAgICAqIEZpbmRzIGFuZCByZXR1cm5zIHRoZSBsYXN0IGNoaWxkIG5vZGUgd2l0aCB0aGUgZ2l2ZW4gbmFtZSBhbmQKLSAgICAgKiBhdHRyaWJ1dGUgbmFtZSwgdmFsdWUgcGFpci4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIEVsZW1lbnQgZ2V0TGFzdENoaWxkRWxlbWVudChOb2RlICAgcGFyZW50LAotICAgICAgICAgICAgU3RyaW5nIGVsZW1OYW1lLAotICAgICAgICAgICAgU3RyaW5nIGF0dHJOYW1lLAotICAgICAgICAgICAgU3RyaW5nIGF0dHJWYWx1ZSkgewotCi0gICAgICAgIC8vIHNlYXJjaCBmb3Igbm9kZQotICAgICAgICBOb2RlIGNoaWxkID0gcGFyZW50LmdldExhc3RDaGlsZCgpOwotICAgICAgICB3aGlsZSAoY2hpbGQgIT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKGNoaWxkLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5FTEVNRU5UX05PREUpIHsKLSAgICAgICAgICAgICAgICBFbGVtZW50IGVsZW1lbnQgPSAoRWxlbWVudCljaGlsZDsKLSAgICAgICAgICAgICAgICBpZiAoZWxlbWVudC5nZXROb2RlTmFtZSgpLmVxdWFscyhlbGVtTmFtZSkgJiYKLSAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuZ2V0QXR0cmlidXRlKGF0dHJOYW1lKS5lcXVhbHMoYXR0clZhbHVlKSkgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gZWxlbWVudDsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjaGlsZCA9IGNoaWxkLmdldFByZXZpb3VzU2libGluZygpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gbm90IGZvdW5kCi0gICAgICAgIHJldHVybiBudWxsOwotCi0gICAgfSAvLyBnZXRMYXN0Q2hpbGRFbGVtZW50KE5vZGUsU3RyaW5nLFN0cmluZyxTdHJpbmcpOkVsZW1lbnQKLQotICAgIC8qKgotICAgICAqIEZpbmRzIGFuZCByZXR1cm5zIHRoZSBuZXh0IHNpYmxpbmcgbm9kZSB3aXRoIHRoZSBnaXZlbiBuYW1lIGFuZAotICAgICAqIGF0dHJpYnV0ZSBuYW1lLCB2YWx1ZSBwYWlyLiBTaW5jZSBvbmx5IGVsZW1lbnRzIGhhdmUgYXR0cmlidXRlcywKLSAgICAgKiB0aGUgbm9kZSByZXR1cm5lZCB3aWxsIGJlIG9mIHR5cGUgTm9kZS5FTEVNRU5UX05PREUuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBFbGVtZW50IGdldE5leHRTaWJsaW5nRWxlbWVudChOb2RlICAgbm9kZSwKLSAgICAgICAgICAgIFN0cmluZyBlbGVtTmFtZSwKLSAgICAgICAgICAgIFN0cmluZyBhdHRyTmFtZSwKLSAgICAgICAgICAgIFN0cmluZyBhdHRyVmFsdWUpIHsKLQotICAgICAgICAvLyBzZWFyY2ggZm9yIG5vZGUKLSAgICAgICAgTm9kZSBzaWJsaW5nID0gbm9kZS5nZXROZXh0U2libGluZygpOwotICAgICAgICB3aGlsZSAoc2libGluZyAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAoc2libGluZy5nZXROb2RlVHlwZSgpID09IE5vZGUuRUxFTUVOVF9OT0RFKSB7Ci0gICAgICAgICAgICAgICAgRWxlbWVudCBlbGVtZW50ID0gKEVsZW1lbnQpc2libGluZzsKLSAgICAgICAgICAgICAgICBpZiAoZWxlbWVudC5nZXROb2RlTmFtZSgpLmVxdWFscyhlbGVtTmFtZSkgJiYKLSAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuZ2V0QXR0cmlidXRlKGF0dHJOYW1lKS5lcXVhbHMoYXR0clZhbHVlKSkgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gZWxlbWVudDsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBzaWJsaW5nID0gc2libGluZy5nZXROZXh0U2libGluZygpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gbm90IGZvdW5kCi0gICAgICAgIHJldHVybiBudWxsOwotCi0gICAgfSAvLyBnZXROZXh0U2libGluZ0VsZW1lbnQoTm9kZSxTdHJpbmcsU3RyaW5nLFN0cmluZyk6RWxlbWVudAotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgY29uY2F0ZW5hdGVkIGNoaWxkIHRleHQgb2YgdGhlIHNwZWNpZmllZCBub2RlLgotICAgICAqIFRoaXMgbWV0aG9kIG9ubHkgbG9va3MgYXQgdGhlIGltbWVkaWF0ZSBjaGlsZHJlbiBvZiB0eXBlCi0gICAgICogPGNvZGU+Tm9kZS5URVhUX05PREU8L2NvZGU+IG9yIHRoZSBjaGlsZHJlbiBvZiBhbnkgY2hpbGQKLSAgICAgKiBub2RlIHRoYXQgaXMgb2YgdHlwZSA8Y29kZT5Ob2RlLkNEQVRBX1NFQ1RJT05fTk9ERTwvY29kZT4KLSAgICAgKiBmb3IgdGhlIGNvbmNhdGVuYXRpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbm9kZSBUaGUgbm9kZSB0byBsb29rIGF0LgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldENoaWxkVGV4dChOb2RlIG5vZGUpIHsKLQotICAgICAgICAvLyBpcyB0aGVyZSBhbnl0aGluZyB0byBkbz8KLSAgICAgICAgaWYgKG5vZGUgPT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBjb25jYXRlbmF0ZSBjaGlsZHJlbiB0ZXh0Ci0gICAgICAgIFN0cmluZ0J1ZmZlciBzdHIgPSBuZXcgU3RyaW5nQnVmZmVyKCk7Ci0gICAgICAgIE5vZGUgY2hpbGQgPSBub2RlLmdldEZpcnN0Q2hpbGQoKTsKLSAgICAgICAgd2hpbGUgKGNoaWxkICE9IG51bGwpIHsKLSAgICAgICAgICAgIHNob3J0IHR5cGUgPSBjaGlsZC5nZXROb2RlVHlwZSgpOwotICAgICAgICAgICAgaWYgKHR5cGUgPT0gTm9kZS5URVhUX05PREUpIHsKLSAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKGNoaWxkLmdldE5vZGVWYWx1ZSgpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKHR5cGUgPT0gTm9kZS5DREFUQV9TRUNUSU9OX05PREUpIHsKLSAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKGdldENoaWxkVGV4dChjaGlsZCkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2hpbGQgPSBjaGlsZC5nZXROZXh0U2libGluZygpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gcmV0dXJuIHRleHQgdmFsdWUKLSAgICAgICAgcmV0dXJuIHN0ci50b1N0cmluZygpOwotCi0gICAgfSAvLyBnZXRDaGlsZFRleHQoTm9kZSk6U3RyaW5nCi0KLSAgICAvLyByZXR1cm4gdGhlIG5hbWUgb2YgdGhpcyBlbGVtZW50Ci0gICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0TmFtZShOb2RlIG5vZGUpIHsKLSAgICAgICAgcmV0dXJuIG5vZGUuZ2V0Tm9kZU5hbWUoKTsKLSAgICB9IC8vIGdldExvY2FsTmFtZShFbGVtZW50KTogIFN0cmluZwotCi0gICAgLyoqIHJldHVybnMgbG9jYWwgbmFtZSBvZiB0aGlzIGVsZW1lbnQgaWYgbm90IG51bGwsIG90aGVyd2lzZQotICAgICByZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSBub2RlCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0TG9jYWxOYW1lKE5vZGUgbm9kZSkgewotICAgICAgICBTdHJpbmcgbmFtZSA9IG5vZGUuZ2V0TG9jYWxOYW1lKCk7Ci0gICAgICAgIHJldHVybiAobmFtZSE9bnVsbCk/IG5hbWU6bm9kZS5nZXROb2RlTmFtZSgpOwotICAgIH0gLy8gZ2V0TG9jYWxOYW1lKEVsZW1lbnQpOiAgU3RyaW5nCi0KLSAgICBwdWJsaWMgc3RhdGljIEVsZW1lbnQgZ2V0UGFyZW50KEVsZW1lbnQgZWxlbSkgewotICAgICAgICBOb2RlIHBhcmVudCA9IGVsZW0uZ2V0UGFyZW50Tm9kZSgpOwotICAgICAgICBpZiAocGFyZW50IGluc3RhbmNlb2YgRWxlbWVudCkKLSAgICAgICAgICAgIHJldHVybiAoRWxlbWVudClwYXJlbnQ7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0gLy8gZ2V0UGFyZW50KEVsZW1lbnQpOkVsZW1lbnQKLQotICAgIC8vIGdldCB0aGUgRG9jdW1lbnQgb2Ygd2hpY2ggdGhpcyBOb2RlIGlzIGEgcGFydAotICAgIHB1YmxpYyBzdGF0aWMgRG9jdW1lbnQgZ2V0RG9jdW1lbnQoTm9kZSBub2RlKSB7Ci0gICAgICAgIHJldHVybiBub2RlLmdldE93bmVyRG9jdW1lbnQoKTsKLSAgICB9IC8vIGdldERvY3VtZW50KE5vZGUpOkRvY3VtZW50Ci0KLSAgICAvLyByZXR1cm4gdGhpcyBEb2N1bWVudCdzIHJvb3Qgbm9kZQotICAgIHB1YmxpYyBzdGF0aWMgRWxlbWVudCBnZXRSb290KERvY3VtZW50IGRvYykgewotICAgICAgICByZXR1cm4gZG9jLmdldERvY3VtZW50RWxlbWVudCgpOwotICAgIH0gLy8gZ2V0Um9vdChEb2N1bWVudCg6ICBFbGVtZW50Ci0KLSAgICAvLyBzb21lIG1ldGhvZHMgZm9yIGhhbmRsaW5nIGF0dHJpYnV0ZXM6Ci0KLSAgICAvLyByZXR1cm4gdGhlIHJpZ2h0IGF0dHJpYnV0ZSBub2RlCi0gICAgcHVibGljIHN0YXRpYyBBdHRyIGdldEF0dHIoRWxlbWVudCBlbGVtLCBTdHJpbmcgbmFtZSkgewotICAgICAgICByZXR1cm4gZWxlbS5nZXRBdHRyaWJ1dGVOb2RlKG5hbWUpOwotICAgIH0gLy8gZ2V0QXR0cihFbGVtZW50LCBTdHJpbmcpOkF0dHIKLQotICAgIC8vIHJldHVybiB0aGUgcmlnaHQgYXR0cmlidXRlIG5vZGUKLSAgICBwdWJsaWMgc3RhdGljIEF0dHIgZ2V0QXR0ck5TKEVsZW1lbnQgZWxlbSwgU3RyaW5nIG5zVXJpLAotICAgICAgICAgICAgU3RyaW5nIGxvY2FsTmFtZSkgewotICAgICAgICByZXR1cm4gZWxlbS5nZXRBdHRyaWJ1dGVOb2RlTlMobnNVcmksIGxvY2FsTmFtZSk7Ci0gICAgfSAvLyBnZXRBdHRyTlMoRWxlbWVudCwgU3RyaW5nKTpBdHRyCi0KLSAgICAvLyBnZXQgYWxsIHRoZSBhdHRyaWJ1dGVzIGZvciBhbiBFbGVtZW50Ci0gICAgcHVibGljIHN0YXRpYyBBdHRyW10gZ2V0QXR0cnMoRWxlbWVudCBlbGVtKSB7Ci0gICAgICAgIE5hbWVkTm9kZU1hcCBhdHRyTWFwID0gZWxlbS5nZXRBdHRyaWJ1dGVzKCk7Ci0gICAgICAgIEF0dHIgW10gYXR0ckFycmF5ID0gbmV3IEF0dHJbYXR0ck1hcC5nZXRMZW5ndGgoKV07Ci0gICAgICAgIGZvciAoaW50IGk9MDsgaTxhdHRyTWFwLmdldExlbmd0aCgpOyBpKyspCi0gICAgICAgICAgICBhdHRyQXJyYXlbaV0gPSAoQXR0cilhdHRyTWFwLml0ZW0oaSk7Ci0gICAgICAgIHJldHVybiBhdHRyQXJyYXk7Ci0gICAgfSAvLyBnZXRBdHRycyhFbGVtZW50KTogIEF0dHJbXQotCi0gICAgLy8gZ2V0IGF0dHJpYnV0ZSdzIHZhbHVlCi0gICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0VmFsdWUoQXR0ciBhdHRyaWJ1dGUpIHsKLSAgICAgICAgcmV0dXJuIGF0dHJpYnV0ZS5nZXRWYWx1ZSgpOwotICAgIH0gLy8gZ2V0VmFsdWUoQXR0cik6U3RyaW5nCi0KLSAgICAvLyBJdCBpcyBub3Rld29ydGh5IHRoYXQsIGJlY2F1c2Ugb2YgdGhlIHdheSB0aGUgRE9NIHNwZWNzCi0gICAgLy8gd29yaywgdGhlIG5leHQgdHdvIG1ldGhvZHMgcmV0dXJuIHRoZSBlbXB0eSBzdHJpbmcgKG5vdAotICAgIC8vIG51bGwhKSB3aGVuIHRoZSBhdHRyaWJ1dGUgd2l0aCB0aGUgc3BlY2lmaWVkIG5hbWUgZG9lcyBub3QKLSAgICAvLyBleGlzdCBvbiBhbiBlbGVtZW50LiAgQmV3YXJlIQotCi0gICAgLy8gcmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgYXR0cmlidXRlIG9mIHRoZSBnaXZlbiBlbGVtZW50Ci0gICAgLy8gd2l0aCB0aGUgZ2l2ZW4gbmFtZQotICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldEF0dHJWYWx1ZShFbGVtZW50IGVsZW0sIFN0cmluZyBuYW1lKSB7Ci0gICAgICAgIHJldHVybiBlbGVtLmdldEF0dHJpYnV0ZShuYW1lKTsKLSAgICB9IC8vIGdldEF0dHIoRWxlbWVudCwgU3RyaW5nKTpBdHRyCi0KLSAgICAvLyByZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUgb2YgdGhlIGdpdmVuIGVsZW1lbnQKLSAgICAvLyB3aXRoIHRoZSBnaXZlbiBuYW1lCi0gICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0QXR0clZhbHVlTlMoRWxlbWVudCBlbGVtLCBTdHJpbmcgbnNVcmksCi0gICAgICAgICAgICBTdHJpbmcgbG9jYWxOYW1lKSB7Ci0gICAgICAgIHJldHVybiBlbGVtLmdldEF0dHJpYnV0ZU5TKG5zVXJpLCBsb2NhbE5hbWUpOwotICAgIH0gLy8gZ2V0QXR0clZhbHVlTlMoRWxlbWVudCwgU3RyaW5nKTpBdHRyCi0KLSAgICAvLyByZXR1cm4gdGhlIHByZWZpeAotICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldFByZWZpeChOb2RlIG5vZGUpIHsKLSAgICAgICAgcmV0dXJuIG5vZGUuZ2V0UHJlZml4KCk7Ci0gICAgfQotCi0gICAgLy8gcmV0dXJuIHRoZSBuYW1lc3BhY2UgVVJJCi0gICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0TmFtZXNwYWNlVVJJKE5vZGUgbm9kZSkgewotICAgICAgICByZXR1cm4gbm9kZS5nZXROYW1lc3BhY2VVUkkoKTsKLSAgICB9Ci0KLSAgICAvLyByZXR1cm4gYW5ub3RhdGlvbgotICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldEFubm90YXRpb24oTm9kZSBub2RlKSB7Ci0gICAgICAgIGlmIChub2RlIGluc3RhbmNlb2YgRWxlbWVudEltcGwpIHsKLSAgICAgICAgICAgIHJldHVybiAoKEVsZW1lbnRJbXBsKW5vZGUpLmdldEFubm90YXRpb24oKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICAvLyByZXR1cm4gc3ludGhldGljIGFubm90YXRpb24KLSAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBnZXRTeW50aGV0aWNBbm5vdGF0aW9uKE5vZGUgbm9kZSkgewotICAgICAgICBpZiAobm9kZSBpbnN0YW5jZW9mIEVsZW1lbnRJbXBsKSB7Ci0gICAgICAgICAgICByZXR1cm4gKChFbGVtZW50SW1wbClub2RlKS5nZXRTeW50aGV0aWNBbm5vdGF0aW9uKCk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlcyBhIERPTUV4Y2VwdGlvbi4gT24gSjJTRSAxLjQgYW5kIGFib3ZlIHRoZSBjYXVzZSBmb3IgdGhlIGV4Y2VwdGlvbiB3aWxsIGJlIHNldC4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIERPTUV4Y2VwdGlvbiBjcmVhdGVET01FeGNlcHRpb24oc2hvcnQgY29kZSwgVGhyb3dhYmxlIGNhdXNlKSB7Ci0gICAgICAgIERPTUV4Y2VwdGlvbiBkZSA9IG5ldyBET01FeGNlcHRpb24oY29kZSwgY2F1c2UgIT0gbnVsbCA/IGNhdXNlLmdldE1lc3NhZ2UoKSA6IG51bGwpOwotICAgICAgICBpZiAoY2F1c2UgIT0gbnVsbCAmJiBUaHJvd2FibGVNZXRob2RzLmZnVGhyb3dhYmxlTWV0aG9kc0F2YWlsYWJsZSkgewotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICBUaHJvd2FibGVNZXRob2RzLmZnVGhyb3dhYmxlSW5pdENhdXNlTWV0aG9kLmludm9rZShkZSwgbmV3IE9iamVjdCBbXSB7Y2F1c2V9KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIFNvbWV0aGluZyB3ZW50IHdyb25nLiBUaGVyZSdzIG5vdCBtdWNoIHdlIGNhbiBkbyBhYm91dCBpdC4KLSAgICAgICAgICAgIGNhdGNoIChFeGNlcHRpb24gZSkge30KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZGU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlcyBhbiBMU0V4Y2VwdGlvbi4gT24gSjJTRSAxLjQgYW5kIGFib3ZlIHRoZSBjYXVzZSBmb3IgdGhlIGV4Y2VwdGlvbiB3aWxsIGJlIHNldC4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIExTRXhjZXB0aW9uIGNyZWF0ZUxTRXhjZXB0aW9uKHNob3J0IGNvZGUsIFRocm93YWJsZSBjYXVzZSkgewotICAgICAgICBMU0V4Y2VwdGlvbiBsc2UgPSBuZXcgTFNFeGNlcHRpb24oY29kZSwgY2F1c2UgIT0gbnVsbCA/IGNhdXNlLmdldE1lc3NhZ2UoKSA6IG51bGwpOwotICAgICAgICBpZiAoY2F1c2UgIT0gbnVsbCAmJiBUaHJvd2FibGVNZXRob2RzLmZnVGhyb3dhYmxlTWV0aG9kc0F2YWlsYWJsZSkgewotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICBUaHJvd2FibGVNZXRob2RzLmZnVGhyb3dhYmxlSW5pdENhdXNlTWV0aG9kLmludm9rZShsc2UsIG5ldyBPYmplY3QgW10ge2NhdXNlfSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyBTb21ldGhpbmcgd2VudCB3cm9uZy4gVGhlcmUncyBub3QgbXVjaCB3ZSBjYW4gZG8gYWJvdXQgaXQuCi0gICAgICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGUpIHt9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGxzZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBIb2xkZXIgb2YgbWV0aG9kcyBmcm9tIGphdmEubGFuZy5UaHJvd2FibGUuCi0gICAgICovCi0gICAgc3RhdGljIGNsYXNzIFRocm93YWJsZU1ldGhvZHMgewotCi0gICAgICAgIC8vIE1ldGhvZDogamF2YS5sYW5nLlRocm93YWJsZS5pbml0Q2F1c2UoamF2YS5sYW5nLlRocm93YWJsZSkKLSAgICAgICAgcHJpdmF0ZSBzdGF0aWMgamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kIGZnVGhyb3dhYmxlSW5pdENhdXNlTWV0aG9kID0gbnVsbDsKLQotICAgICAgICAvLyBGbGFnIGluZGljYXRpbmcgd2hldGhlciBvciBub3QgVGhyb3dhYmxlIG1ldGhvZHMgYXZhaWxhYmxlLgotICAgICAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGZnVGhyb3dhYmxlTWV0aG9kc0F2YWlsYWJsZSA9IGZhbHNlOwotCi0gICAgICAgIHByaXZhdGUgVGhyb3dhYmxlTWV0aG9kcygpIHt9Ci0KLSAgICAgICAgLy8gQXR0ZW1wdCB0byBnZXQgbWV0aG9kcyBmb3IgamF2YS5sYW5nLlRocm93YWJsZSBvbiBjbGFzcyBpbml0aWFsaXphdGlvbi4KLSAgICAgICAgc3RhdGljIHsKLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgZmdUaHJvd2FibGVJbml0Q2F1c2VNZXRob2QgPSBUaHJvd2FibGUuY2xhc3MuZ2V0TWV0aG9kKCJpbml0Q2F1c2UiLCBuZXcgQ2xhc3MgW10ge1Rocm93YWJsZS5jbGFzc30pOwotICAgICAgICAgICAgICAgIGZnVGhyb3dhYmxlTWV0aG9kc0F2YWlsYWJsZSA9IHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uLCBOb1N1Y2hNZXRob2RFeGNlcHRpb24gb3IgU2VjdXJpdHlFeGNlcHRpb24KLSAgICAgICAgICAgIC8vIFdoYXRldmVyIHRoZSBjYXNlLCB3ZSBjYW5ub3QgdXNlIGphdmEubGFuZy5UaHJvd2FibGUuaW5pdENhdXNlKGphdmEubGFuZy5UaHJvd2FibGUpLgotICAgICAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleGMpIHsKLSAgICAgICAgICAgICAgICBmZ1Rocm93YWJsZUluaXRDYXVzZU1ldGhvZCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgZmdUaHJvd2FibGVNZXRob2RzQXZhaWxhYmxlID0gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLX0gLy8gY2xhc3MgRE9NVXRpbApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9EYXRhdHlwZU1lc3NhZ2VGb3JtYXR0ZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3V0aWwvRGF0YXR5cGVNZXNzYWdlRm9ybWF0dGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGI5NjRhOGYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9EYXRhdHlwZU1lc3NhZ2VGb3JtYXR0ZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEwNCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWw7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWxzLlNlY3VyaXR5U3VwcG9ydDsKLWltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwotaW1wb3J0IGphdmEudXRpbC5NaXNzaW5nUmVzb3VyY2VFeGNlcHRpb247Ci1pbXBvcnQgamF2YS51dGlsLlJlc291cmNlQnVuZGxlOwotCi0vKioKLSAqIDxwPlVzZWQgdG8gZm9ybWF0IEpBWFAgMS4zIERhdGF0eXBlIEFQSSBlcnJvciBtZXNzYWdlcyB1c2luZyBhIHNwZWNpZmllZCBsb2NhbGUuPC9wPgotICoKLSAqIEBhdXRob3IgIE5lZXJhaiBCYWphaiwgU3VuIE1pY3Jvc3lzdGVtcwotICogQHZlcnNpb24gJElkOiBEYXRhdHlwZU1lc3NhZ2VGb3JtYXR0ZXIuamF2YSx2IDEuNiAyMDEwLTExLTAxIDA0OjQwOjE0IGpvZWh3IEV4cCAkCi0gKi8KLXB1YmxpYyBjbGFzcyBEYXRhdHlwZU1lc3NhZ2VGb3JtYXR0ZXIgewotCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEJBU0VfTkFNRSA9ICJjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwubXNnLkRhdGF0eXBlTWVzc2FnZXMiOwotCi0gICAgLyoqCi0gICAgICogRm9ybWF0cyBhIG1lc3NhZ2Ugd2l0aCB0aGUgc3BlY2lmaWVkIGFyZ3VtZW50cyB1c2luZyB0aGUgZ2l2ZW4KLSAgICAgKiBsb2NhbGUgaW5mb3JtYXRpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbG9jYWxlICAgIFRoZSBsb2NhbGUgb2YgdGhlIG1lc3NhZ2UuCi0gICAgICogQHBhcmFtIGtleSAgICAgICBUaGUgbWVzc2FnZSBrZXkuCi0gICAgICogQHBhcmFtIGFyZ3VtZW50cyBUaGUgbWVzc2FnZSByZXBsYWNlbWVudCB0ZXh0IGFyZ3VtZW50cy4gVGhlIG9yZGVyCi0gICAgICogICAgICAgICAgICAgICAgICBvZiB0aGUgYXJndW1lbnRzIG11c3QgbWF0Y2ggdGhhdCBvZiB0aGUgcGxhY2Vob2xkZXJzCi0gICAgICogICAgICAgICAgICAgICAgICBpbiB0aGUgYWN0dWFsIG1lc3NhZ2UuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuICAgICAgICAgIHRoZSBmb3JtYXR0ZWQgbWVzc2FnZS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uIFRocm93biBpZiB0aGUgbWVzc2FnZSB3aXRoIHRoZQotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwZWNpZmllZCBrZXkgY2Fubm90IGJlIGZvdW5kLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGZvcm1hdE1lc3NhZ2UoTG9jYWxlIGxvY2FsZSwKLSAgICAgICAgU3RyaW5nIGtleSwgT2JqZWN0W10gYXJndW1lbnRzKQotICAgICAgICB0aHJvd3MgTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uIHsKLQotICAgICAgICBSZXNvdXJjZUJ1bmRsZSByZXNvdXJjZUJ1bmRsZSA9IG51bGw7Ci0gICAgICAgIGlmIChsb2NhbGUgIT0gbnVsbCkgewotICAgICAgICAgICAgcmVzb3VyY2VCdW5kbGUgPQotICAgICAgICAgICAgICAgIFNlY3VyaXR5U3VwcG9ydC5nZXRSZXNvdXJjZUJ1bmRsZShCQVNFX05BTUUsIGxvY2FsZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICByZXNvdXJjZUJ1bmRsZSA9Ci0gICAgICAgICAgICAgICAgU2VjdXJpdHlTdXBwb3J0LmdldFJlc291cmNlQnVuZGxlKEJBU0VfTkFNRSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBmb3JtYXQgbWVzc2FnZQotICAgICAgICBTdHJpbmcgbXNnOwotICAgICAgICB0cnkgewotICAgICAgICAgICAgbXNnID0gcmVzb3VyY2VCdW5kbGUuZ2V0U3RyaW5nKGtleSk7Ci0gICAgICAgICAgICBpZiAoYXJndW1lbnRzICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICBtc2cgPSBqYXZhLnRleHQuTWVzc2FnZUZvcm1hdC5mb3JtYXQobXNnLCBhcmd1bWVudHMpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICAgICAgbXNnID0gcmVzb3VyY2VCdW5kbGUuZ2V0U3RyaW5nKCJGb3JtYXRGYWlsZWQiKTsKLSAgICAgICAgICAgICAgICAgICAgbXNnICs9ICIgIiArIHJlc291cmNlQnVuZGxlLmdldFN0cmluZyhrZXkpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIGVycm9yCi0gICAgICAgIGNhdGNoIChNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgbXNnID0gcmVzb3VyY2VCdW5kbGUuZ2V0U3RyaW5nKCJCYWRNZXNzYWdlS2V5Iik7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uKGtleSwgbXNnLCBrZXkpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gbm8gbWVzc2FnZQotICAgICAgICBpZiAobXNnID09IG51bGwpIHsKLSAgICAgICAgICAgIG1zZyA9IGtleTsKLSAgICAgICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMCkgewotICAgICAgICAgICAgICAgIFN0cmluZ0J1ZmZlciBzdHIgPSBuZXcgU3RyaW5nQnVmZmVyKG1zZyk7Ci0gICAgICAgICAgICAgICAgc3RyLmFwcGVuZCgnPycpOwotICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChpID4gMCkgewotICAgICAgICAgICAgICAgICAgICAgICAgc3RyLmFwcGVuZCgnJicpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIHN0ci5hcHBlbmQoU3RyaW5nLnZhbHVlT2YoYXJndW1lbnRzW2ldKSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBtc2c7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9EZWZhdWx0RXJyb3JIYW5kbGVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL0RlZmF1bHRFcnJvckhhbmRsZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggY2E1ZTAzOS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL0RlZmF1bHRFcnJvckhhbmRsZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExNiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAwLTIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsOwotCi1pbXBvcnQgamF2YS5pby5QcmludFdyaXRlcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhOSUV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MRXJyb3JIYW5kbGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxQYXJzZUV4Y2VwdGlvbjsKLQotLyoqCi0gKiBEZWZhdWx0IGVycm9yIGhhbmRsZXIuCi0gKgotICogQGF1dGhvciBBbmR5IENsYXJrLCBJQk0KLSAqCi0gKi8KLXB1YmxpYyBjbGFzcyBEZWZhdWx0RXJyb3JIYW5kbGVyCi0gICAgaW1wbGVtZW50cyBYTUxFcnJvckhhbmRsZXIgewotCi0gICAgLy8KLSAgICAvLyBEYXRhCi0gICAgLy8KLQotICAgIC8qKiBQcmludCB3cml0ZXIuICovCi0gICAgcHJvdGVjdGVkIFByaW50V3JpdGVyIGZPdXQ7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0cnVjdG9ycwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RzIGFuIGVycm9yIGhhbmRsZXIgdGhhdCBwcmludHMgZXJyb3IgbWVzc2FnZXMgdG8KLSAgICAgKiA8Y29kZT5TeXN0ZW0uZXJyPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgRGVmYXVsdEVycm9ySGFuZGxlcigpIHsKLSAgICAgICAgdGhpcyhuZXcgUHJpbnRXcml0ZXIoU3lzdGVtLmVycikpOwotICAgIH0gLy8gPGluaXQ+KCkKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHMgYW4gZXJyb3IgaGFuZGxlciB0aGF0IHByaW50cyBlcnJvciBtZXNzYWdlcyB0byB0aGUKLSAgICAgKiBzcGVjaWZpZWQgPGNvZGU+UHJpbnRXcml0ZXI8L2NvZGUuCi0gICAgICovCi0gICAgcHVibGljIERlZmF1bHRFcnJvckhhbmRsZXIoUHJpbnRXcml0ZXIgb3V0KSB7Ci0gICAgICAgIGZPdXQgPSBvdXQ7Ci0gICAgfSAvLyA8aW5pdD4oUHJpbnRXcml0ZXIpCi0KLSAgICAvLwotICAgIC8vIEVycm9ySGFuZGxlciBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKiBXYXJuaW5nLiAqLwotICAgIHB1YmxpYyB2b2lkIHdhcm5pbmcoU3RyaW5nIGRvbWFpbiwgU3RyaW5nIGtleSwgWE1MUGFyc2VFeGNlcHRpb24gZXgpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBwcmludEVycm9yKCJXYXJuaW5nIiwgZXgpOwotICAgIH0gLy8gd2FybmluZyhYTUxQYXJzZUV4Y2VwdGlvbikKLQotICAgIC8qKiBFcnJvci4gKi8KLSAgICBwdWJsaWMgdm9pZCBlcnJvcihTdHJpbmcgZG9tYWluLCBTdHJpbmcga2V5LCBYTUxQYXJzZUV4Y2VwdGlvbiBleCkKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIHByaW50RXJyb3IoIkVycm9yIiwgZXgpOwotICAgIH0gLy8gZXJyb3IoWE1MUGFyc2VFeGNlcHRpb24pCi0KLSAgICAvKiogRmF0YWwgZXJyb3IuICovCi0gICAgcHVibGljIHZvaWQgZmF0YWxFcnJvcihTdHJpbmcgZG9tYWluLCBTdHJpbmcga2V5LCBYTUxQYXJzZUV4Y2VwdGlvbiBleCkKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIHByaW50RXJyb3IoIkZhdGFsIEVycm9yIiwgZXgpOwotICAgICAgICB0aHJvdyBleDsKLSAgICB9IC8vIGZhdGFsRXJyb3IoWE1MUGFyc2VFeGNlcHRpb24pCi0KLSAgICAvLwotICAgIC8vIFByaXZhdGUgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKiogUHJpbnRzIHRoZSBlcnJvciBtZXNzYWdlLiAqLwotICAgIHByaXZhdGUgdm9pZCBwcmludEVycm9yKFN0cmluZyB0eXBlLCBYTUxQYXJzZUV4Y2VwdGlvbiBleCkgewotCi0gICAgICAgIGZPdXQucHJpbnQoIlsiKTsKLSAgICAgICAgZk91dC5wcmludCh0eXBlKTsKLSAgICAgICAgZk91dC5wcmludCgiXSAiKTsKLSAgICAgICAgU3RyaW5nIHN5c3RlbUlkID0gZXguZ2V0RXhwYW5kZWRTeXN0ZW1JZCgpOwotICAgICAgICBpZiAoc3lzdGVtSWQgIT0gbnVsbCkgewotICAgICAgICAgICAgaW50IGluZGV4ID0gc3lzdGVtSWQubGFzdEluZGV4T2YoJy8nKTsKLSAgICAgICAgICAgIGlmIChpbmRleCAhPSAtMSkKLSAgICAgICAgICAgICAgICBzeXN0ZW1JZCA9IHN5c3RlbUlkLnN1YnN0cmluZyhpbmRleCArIDEpOwotICAgICAgICAgICAgZk91dC5wcmludChzeXN0ZW1JZCk7Ci0gICAgICAgIH0KLSAgICAgICAgZk91dC5wcmludCgnOicpOwotICAgICAgICBmT3V0LnByaW50KGV4LmdldExpbmVOdW1iZXIoKSk7Ci0gICAgICAgIGZPdXQucHJpbnQoJzonKTsKLSAgICAgICAgZk91dC5wcmludChleC5nZXRDb2x1bW5OdW1iZXIoKSk7Ci0gICAgICAgIGZPdXQucHJpbnQoIjogIik7Ci0gICAgICAgIGZPdXQucHJpbnQoZXguZ2V0TWVzc2FnZSgpKTsKLSAgICAgICAgZk91dC5wcmludGxuKCk7Ci0gICAgICAgIGZPdXQuZmx1c2goKTsKLQotICAgIH0gLy8gcHJpbnRFcnJvcihTdHJpbmcsU0FYUGFyc2VFeGNlcHRpb24pCi0KLX0gLy8gY2xhc3MgRGVmYXVsdEVycm9ySGFuZGxlcgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9EcmFjb25pYW5FcnJvckhhbmRsZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3V0aWwvRHJhY29uaWFuRXJyb3JIYW5kbGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDg5YjM4YTUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9EcmFjb25pYW5FcnJvckhhbmRsZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDkwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDAtMjAwMiBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhlcmNlcyIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgSW50ZXJuYXRpb25hbAotICogQnVzaW5lc3MgTWFjaGluZXMsIEluYy4sIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWw7Ci0KLWltcG9ydCBvcmcueG1sLnNheC5FcnJvckhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWFBhcnNlRXhjZXB0aW9uOwotCi0vKioKLSAqIHtAbGluayBFcnJvckhhbmRsZXJ9IHRoYXQgdGhyb3dzIGFsbCBlcnJvcnMgYW5kIGZhdGFsIGVycm9ycy4KLSAqCi0gKiBAYXV0aG9yCi0gKiAgICAgS29oc3VrZSBLYXdhZ3VjaGkgKGtvaHN1a2Uua2F3YWd1Y2hpQHN1bi5jb20pCi0gKi8KLXB1YmxpYyBjbGFzcyBEcmFjb25pYW5FcnJvckhhbmRsZXIgaW1wbGVtZW50cyBFcnJvckhhbmRsZXIgewotICAgIC8qKgotICAgICAqIFVzZSB0aGlzIHNpbmdsZXRvbiBpbnN0YW5jZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEVycm9ySGFuZGxlciB0aGVJbnN0YW5jZSA9IG5ldyBEcmFjb25pYW5FcnJvckhhbmRsZXIoKTsKLQotICAgIHByaXZhdGUgRHJhY29uaWFuRXJyb3JIYW5kbGVyKCkge30KLQotICAgIHB1YmxpYyB2b2lkIGVycm9yKFNBWFBhcnNlRXhjZXB0aW9uIGUpIHRocm93cyBTQVhFeGNlcHRpb24gewotICAgICAgICB0aHJvdyBlOwotICAgIH0KLSAgICBwdWJsaWMgdm9pZCBmYXRhbEVycm9yKFNBWFBhcnNlRXhjZXB0aW9uIGUpIHRocm93cyBTQVhFeGNlcHRpb24gewotICAgICAgICB0aHJvdyBlOwotICAgIH0KLSAgICBwdWJsaWMgdm9pZCB3YXJuaW5nKFNBWFBhcnNlRXhjZXB0aW9uIGUpIHRocm93cyBTQVhFeGNlcHRpb24gewotICAgICAgICA7IC8vIG5vb3AKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL0VuY29kaW5nTWFwLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL0VuY29kaW5nTWFwLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGVmMzQ0MTAuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9FbmNvZGluZ01hcC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTgxICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKi8KLS8qCi0gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKLSAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAotICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgotICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKLSAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCi0gKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbDsKLQotaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKLWltcG9ydCBqYXZhLnV0aWwuTWFwOwotCi0vKioKLSAqIEVuY29kaW5nTWFwIGlzIGEgY29udmVuaWVuY2UgY2xhc3Mgd2hpY2ggaGFuZGxlcyBjb252ZXJzaW9ucyBiZXR3ZWVuCi0gKiBJQU5BIGVuY29kaW5nIG5hbWVzIGFuZCBKYXZhIGVuY29kaW5nIG5hbWVzLCBhbmQgdmljZSB2ZXJzYS4gVGhlCi0gKiBlbmNvZGluZyBuYW1lcyB1c2VkIGluIFhNTCBpbnN0YW5jZSBkb2N1bWVudHMgPHN0cm9uZz5tdXN0PC9zdHJvbmc+Ci0gKiBiZSB0aGUgSUFOQSBlbmNvZGluZyBuYW1lcyBzcGVjaWZpZWQgb3Igb25lIG9mIHRoZSBhbGlhc2VzIGZvciB0aG9zZSBuYW1lcwotICogd2hpY2ggSUFOQSBkZWZpbmVzLgotICogPHA+Ci0gKiA8VEFCTEUgQk9SREVSPSIwIiBXSURUSD0iMTAwJSI+Ci0gKiAgPFRSPgotICogICAgICA8VEQgV0lEVEg9IjMzJSI+Ci0gKiAgICAgICAgICA8UCBBTElHTj0iQ0VOVEVSIj48Qj5Db21tb24gTmFtZTwvQj4KLSAqICAgICAgPC9URD4KLSAqICAgICAgPFREIFdJRFRIPSIxNSUiPgotICogICAgICAgICAgPFAgQUxJR049IkNFTlRFUiI+PEI+VXNlIHRoaXMgbmFtZSBpbiBYTUwgZmlsZXM8L0I+Ci0gKiAgICAgIDwvVEQ+Ci0gKiAgICAgIDxURCBXSURUSD0iMTIlIj4KLSAqICAgICAgICAgIDxQIEFMSUdOPSJDRU5URVIiPjxCPk5hbWUgVHlwZTwvQj4KLSAqICAgICAgPC9URD4KLSAqICAgICAgPFREIFdJRFRIPSIzMSUiPgotICogICAgICAgICAgPFAgQUxJR049IkNFTlRFUiI+PEI+WGVyY2VzIGNvbnZlcnRzIHRvIHRoaXMgSmF2YSBFbmNvZGVyIE5hbWU8L0I+Ci0gKiAgICAgIDwvVEQ+Ci0gKiAgPC9UUj4KLSAqICA8VFI+Ci0gKiAgICAgIDxURCBXSURUSD0iMzMlIj44IGJpdCBVbmljb2RlPC9URD4KLSAqICAgICAgPFREIFdJRFRIPSIxNSUiPgotICogICAgICAgICAgPFAgQUxJR049IkNFTlRFUiI+VVRGLTgKLSAqICAgICAgPC9URD4KLSAqICAgICAgPFREIFdJRFRIPSIxMiUiPgotICogICAgICAgICAgPFAgQUxJR049IkNFTlRFUiI+SUFOQQotICogICAgICA8L1REPgotICogICAgICA8VEQgV0lEVEg9IjMxJSI+Ci0gKiAgICAgICAgICA8UCBBTElHTj0iQ0VOVEVSIj5VVEY4Ci0gKiAgICAgIDwvVEQ+Ci0gKiAgPC9UUj4KLSAqICA8VFI+Ci0gKiAgICAgIDxURCBXSURUSD0iMzMlIj5JU08gTGF0aW4gMTwvVEQ+Ci0gKiAgICAgIDxURCBXSURUSD0iMTUlIj4KLSAqICAgICAgICAgIDxQIEFMSUdOPSJDRU5URVIiPklTTy04ODU5LTEKLSAqICAgICAgPC9URD4KLSAqICAgICAgPFREIFdJRFRIPSIxMiUiPgotICogICAgICAgICAgPFAgQUxJR049IkNFTlRFUiI+TUlNRQotICogICAgICA8L1REPgotICogICAgICA8VEQgV0lEVEg9IjMxJSI+Ci0gKiAgICAgICAgICA8UCBBTElHTj0iQ0VOVEVSIj5JU08tODg1OS0xCi0gKiAgICAgIDwvVEQ+Ci0gKiAgPC9UUj4KLSAqICA8VFI+Ci0gKiAgICAgIDxURCBXSURUSD0iMzMlIj5JU08gTGF0aW4gMjwvVEQ+Ci0gKiAgICAgIDxURCBXSURUSD0iMTUlIj4KLSAqICAgICAgICAgIDxQIEFMSUdOPSJDRU5URVIiPklTTy04ODU5LTIKLSAqICAgICAgPC9URD4KLSAqICAgICAgPFREIFdJRFRIPSIxMiUiPgotICogICAgICAgICAgPFAgQUxJR049IkNFTlRFUiI+TUlNRQotICogICAgICA8L1REPgotICogICAgICA8VEQgV0lEVEg9IjMxJSI+Ci0gKiAgICAgICAgICA8UCBBTElHTj0iQ0VOVEVSIj5JU08tODg1OS0yCi0gKiAgICAgIDwvVEQ+Ci0gKiAgPC9UUj4KLSAqICA8VFI+Ci0gKiAgICAgIDxURCBXSURUSD0iMzMlIj5JU08gTGF0aW4gMzwvVEQ+Ci0gKiAgICAgIDxURCBXSURUSD0iMTUlIj4KLSAqICAgICAgICAgIDxQIEFMSUdOPSJDRU5URVIiPklTTy04ODU5LTMKLSAqICAgICAgPC9URD4KLSAqICAgICAgPFREIFdJRFRIPSIxMiUiPgotICogICAgICAgICAgPFAgQUxJR049IkNFTlRFUiI+TUlNRQotICogICAgICA8L1REPgotICogICAgICA8VEQgV0lEVEg9IjMxJSI+Ci0gKiAgICAgICAgICA8UCBBTElHTj0iQ0VOVEVSIj5JU08tODg1OS0zCi0gKiAgICAgIDwvVEQ+Ci0gKiAgPC9UUj4KLSAqICA8VFI+Ci0gKiAgICAgIDxURCBXSURUSD0iMzMlIj5JU08gTGF0aW4gNDwvVEQ+Ci0gKiAgICAgIDxURCBXSURUSD0iMTUlIj4KLSAqICAgICAgICAgIDxQIEFMSUdOPSJDRU5URVIiPklTTy04ODU5LTQKLSAqICAgICAgPC9URD4KLSAqICAgICAgPFREIFdJRFRIPSIxMiUiPgotICogICAgICAgICAgPFAgQUxJR049IkNFTlRFUiI+TUlNRQotICogICAgICA8L1REPgotICogICAgICA8VEQgV0lEVEg9IjMxJSI+Ci0gKiAgICAgICAgICA8UCBBTElHTj0iQ0VOVEVSIj5JU08tODg1OS00Ci0gKiAgICAgIDwvVEQ+Ci0gKiAgPC9UUj4KLSAqICA8VFI+Ci0gKiAgICAgIDxURCBXSURUSD0iMzMlIj5JU08gTGF0aW4gQ3lyaWxsaWM8L1REPgotICogICAgICA8VEQgV0lEVEg9IjE1JSI+Ci0gKiAgICAgICAgICA8UCBBTElHTj0iQ0VOVEVSIj5JU08tODg1OS01Ci0gKiAgICAgIDwvVEQ+Ci0gKiAgICAgIDxURCBXSURUSD0iMTIlIj4KLSAqICAgICAgICAgIDxQIEFMSUdOPSJDRU5URVIiPk1JTUUKLSAqICAgICAgPC9URD4KLSAqICAgICAgPFREIFdJRFRIPSIzMSUiPgotICogICAgICAgICAgPFAgQUxJR049IkNFTlRFUiI+SVNPLTg4NTktNQotICogICAgICA8L1REPgotICogIDwvVFI+Ci0gKiAgPFRSPgotICogICAgICA8VEQgV0lEVEg9IjMzJSI+SVNPIExhdGluIEFyYWJpYzwvVEQ+Ci0gKiAgICAgIDxURCBXSURUSD0iMTUlIj4KLSAqICAgICAgICAgIDxQIEFMSUdOPSJDRU5URVIiPklTTy04ODU5LTYKLSAqICAgICAgPC9URD4KLSAqICAgICAgPFREIFdJRFRIPSIxMiUiPgotICogICAgICAgICAgPFAgQUxJR049IkNFTlRFUiI+TUlNRQotICogICAgICA8L1REPgotICogICAgICA8VEQgV0lEVEg9IjMxJSI+Ci0gKiAgICAgICAgICA8UCBBTElHTj0iQ0VOVEVSIj5JU08tODg1OS02Ci0gKiAgICAgIDwvVEQ+Ci0gKiAgPC9UUj4KLSAqICA8VFI+Ci0gKiAgICAgIDxURCBXSURUSD0iMzMlIj5JU08gTGF0aW4gR3JlZWs8L1REPgotICogICAgICA8VEQgV0lEVEg9IjE1JSI+Ci0gKiAgICAgICAgICA8UCBBTElHTj0iQ0VOVEVSIj5JU08tODg1OS03Ci0gKiAgICAgIDwvVEQ+Ci0gKiAgICAgIDxURCBXSURUSD0iMTIlIj4KLSAqICAgICAgICAgIDxQIEFMSUdOPSJDRU5URVIiPk1JTUUKLSAqICAgICAgPC9URD4KLSAqICAgICAgPFREIFdJRFRIPSIzMSUiPgotICogICAgICAgICAgPFAgQUxJR049IkNFTlRFUiI+SVNPLTg4NTktNwotICogICAgICA8L1REPgotICogIDwvVFI+Ci0gKiAgPFRSPgotICogICAgICA8VEQgV0lEVEg9IjMzJSI+SVNPIExhdGluIEhlYnJldzwvVEQ+Ci0gKiAgICAgIDxURCBXSURUSD0iMTUlIj4KLSAqICAgICAgICAgIDxQIEFMSUdOPSJDRU5URVIiPklTTy04ODU5LTgKLSAqICAgICAgPC9URD4KLSAqICAgICAgPFREIFdJRFRIPSIxMiUiPgotICogICAgICAgICAgPFAgQUxJR049IkNFTlRFUiI+TUlNRQotICogICAgICA8L1REPgotICogICAgICA8VEQgV0lEVEg9IjMxJSI+Ci0gKiAgICAgICAgICA8UCBBTElHTj0iQ0VOVEVSIj5JU08tODg1OS04Ci0gKiAgICAgIDwvVEQ+Ci0gKiAgPC9UUj4KLSAqICA8VFI+Ci0gKiAgICAgIDxURCBXSURUSD0iMzMlIj5JU08gTGF0aW4gNTwvVEQ+Ci0gKiAgICAgIDxURCBXSURUSD0iMTUlIj4KLSAqICAgICAgICAgIDxQIEFMSUdOPSJDRU5URVIiPklTTy04ODU5LTkKLSAqICAgICAgPC9URD4KLSAqICAgICAgPFREIFdJRFRIPSIxMiUiPgotICogICAgICAgICAgPFAgQUxJR049IkNFTlRFUiI+TUlNRQotICogICAgICA8L1REPgotICogICAgICA8VEQgV0lEVEg9IjMxJSI+Ci0gKiAgICAgICAgICA8UCBBTElHTj0iQ0VOVEVSIj5JU08tODg1OS05Ci0gKiAgICAgIDwvVEQ+Ci0gKiAgPC9UUj4KLSAqICA8VFI+Ci0gKiAgICAgIDxURCBXSURUSD0iMzMlIj5FQkNESUM6IFVTPC9URD4KLSAqICAgICAgPFREIFdJRFRIPSIxNSUiPgotICogICAgICAgICAgPFAgQUxJR049IkNFTlRFUiI+ZWJjZGljLWNwLXVzCi0gKiAgICAgIDwvVEQ+Ci0gKiAgICAgIDxURCBXSURUSD0iMTIlIj4KLSAqICAgICAgICAgIDxQIEFMSUdOPSJDRU5URVIiPklBTkEKLSAqICAgICAgPC9URD4KLSAqICAgICAgPFREIFdJRFRIPSIzMSUiPgotICogICAgICAgICAgPFAgQUxJR049IkNFTlRFUiI+Y3AwMzcKLSAqICAgICAgPC9URD4KLSAqICA8L1RSPgotICogIDxUUj4KLSAqICAgICAgPFREIFdJRFRIPSIzMyUiPkVCQ0RJQzogQ2FuYWRhPC9URD4KLSAqICAgICAgPFREIFdJRFRIPSIxNSUiPgotICogICAgICAgICAgPFAgQUxJR049IkNFTlRFUiI+ZWJjZGljLWNwLWNhCi0gKiAgICAgIDwvVEQ+Ci0gKiAgICAgIDxURCBXSURUSD0iMTIlIj4KLSAqICAgICAgICAgIDxQIEFMSUdOPSJDRU5URVIiPklBTkEKLSAqICAgICAgPC9URD4KLSAqICAgICAgPFREIFdJRFRIPSIzMSUiPgotICogICAgICAgICAgPFAgQUxJR049IkNFTlRFUiI+Y3AwMzcKLSAqICAgICAgPC9URD4KLSAqICA8L1RSPgotICogIDxUUj4KLSAqICAgICAgPFREIFdJRFRIPSIzMyUiPkVCQ0RJQzogTmV0aGVybGFuZHM8L1REPgotICogICAgICA8VEQgV0lEVEg9IjE1JSI+Ci0gKiAgICAgICAgICA8UCBBTElHTj0iQ0VOVEVSIj5lYmNkaWMtY3AtbmwKLSAqICAgICAgPC9URD4KLSAqICAgICAgPFREIFdJRFRIPSIxMiUiPgotICogICAgICAgICAgPFAgQUxJR049IkNFTlRFUiI+SUFOQQotICogICAgICA8L1REPgotICogICAgICA8VEQgV0lEVEg9IjMxJSI+Ci0gKiAgICAgICAgICA8UCBBTElHTj0iQ0VOVEVSIj5jcDAzNwotICogICAgICA8L1REPgotICogIDwvVFI+Ci0gKiAgPFRSPgotICogICAgICA8VEQgV0lEVEg9IjMzJSI+RUJDRElDOiBEZW5tYXJrPC9URD4KLSAqICAgICAgPFREIFdJRFRIPSIxNSUiPgotICogICAgICAgICAgPFAgQUxJR049IkNFTlRFUiI+ZWJjZGljLWNwLWRrCi0gKiAgICAgIDwvVEQ+Ci0gKiAgICAgIDxURCBXSURUSD0iMTIlIj4KLSAqICAgICAgICAgIDxQIEFMSUdOPSJDRU5URVIiPklBTkEKLSAqICAgICAgPC9URD4KLSAqICAgICAgPFREIFdJRFRIPSIzMSUiPgotICogICAgICAgICAgPFAgQUxJR049IkNFTlRFUiI+Y3AyNzcKLSAqICAgICAgPC9URD4KLSAqICA8L1RSPgotICogIDxUUj4KLSAqICAgICAgPFREIFdJRFRIPSIzMyUiPkVCQ0RJQzogTm9yd2F5PC9URD4KLSAqICAgICAgPFREIFdJRFRIPSIxNSUiPgotICogICAgICAgICAgPFAgQUxJR049IkNFTlRFUiI+ZWJjZGljLWNwLW5vCi0gKiAgICAgIDwvVEQ+Ci0gKiAgICAgIDxURCBXSURUSD0iMTIlIj4KLSAqICAgICAgICAgIDxQIEFMSUdOPSJDRU5URVIiPklBTkEKLSAqICAgICAgPC9URD4KLSAqICAgICAgPFREIFdJRFRIPSIzMSUiPgotICogICAgICAgICAgPFAgQUxJR049IkNFTlRFUiI+Y3AyNzcKLSAqICAgICAgPC9URD4KLSAqICA8L1RSPgotICogIDxUUj4KLSAqICAgICAgPFREIFdJRFRIPSIzMyUiPkVCQ0RJQzogRmlubGFuZDwvVEQ+Ci0gKiAgICAgIDxURCBXSURUSD0iMTUlIj4KLSAqICAgICAgICAgIDxQIEFMSUdOPSJDRU5URVIiPmViY2RpYy1jcC1maQotICogICAgICA8L1REPgotICogICAgICA8VEQgV0lEVEg9IjEyJSI+Ci0gKiAgICAgICAgICA8UCBBTElHTj0iQ0VOVEVSIj5JQU5BCi0gKiAgICAgIDwvVEQ+Ci0gKiAgICAgIDxURCBXSURUSD0iMzElIj4KLSAqICAgICAgICAgIDxQIEFMSUdOPSJDRU5URVIiPmNwMjc4Ci0gKiAgICAgIDwvVEQ+Ci0gKiAgPC9UUj4KLSAqICA8VFI+Ci0gKiAgICAgIDxURCBXSURUSD0iMzMlIj5FQkNESUM6IFN3ZWRlbjwvVEQ+Ci0gKiAgICAgIDxURCBXSURUSD0iMTUlIj4KLSAqICAgICAgICAgIDxQIEFMSUdOPSJDRU5URVIiPmViY2RpYy1jcC1zZQotICogICAgICA8L1REPgotICogICAgICA8VEQgV0lEVEg9IjEyJSI+Ci0gKiAgICAgICAgICA8UCBBTElHTj0iQ0VOVEVSIj5JQU5BCi0gKiAgICAgIDwvVEQ+Ci0gKiAgICAgIDxURCBXSURUSD0iMzElIj4KLSAqICAgICAgICAgIDxQIEFMSUdOPSJDRU5URVIiPmNwMjc4Ci0gKiAgICAgIDwvVEQ+Ci0gKiAgPC9UUj4KLSAqICA8VFI+Ci0gKiAgICAgIDxURCBXSURUSD0iMzMlIj5FQkNESUM6IEl0YWx5PC9URD4KLSAqICAgICAgPFREIFdJRFRIPSIxNSUiPgotICogICAgICAgICAgPFAgQUxJR049IkNFTlRFUiI+ZWJjZGljLWNwLWl0Ci0gKiAgICAgIDwvVEQ+Ci0gKiAgICAgIDxURCBXSURUSD0iMTIlIj4KLSAqICAgICAgICAgIDxQIEFMSUdOPSJDRU5URVIiPklBTkEKLSAqICAgICAgPC9URD4KLSAqICAgICAgPFREIFdJRFRIPSIzMSUiPgotICogICAgICAgICAgPFAgQUxJR049IkNFTlRFUiI+Y3AyODAKLSAqICAgICAgPC9URD4KLSAqICA8L1RSPgotICogIDxUUj4KLSAqICAgICAgPFREIFdJRFRIPSIzMyUiPkVCQ0RJQzogU3BhaW4sIExhdGluIEFtZXJpY2E8L1REPgotICogICAgICA8VEQgV0lEVEg9IjE1JSI+Ci0gKiAgICAgICAgICA8UCBBTElHTj0iQ0VOVEVSIj5lYmNkaWMtY3AtZXMKLSAqICAgICAgPC9URD4KLSAqICAgICAgPFREIFdJRFRIPSIxMiUiPgotICogICAgICAgICAgPFAgQUxJR049IkNFTlRFUiI+SUFOQQotICogICAgICA8L1REPgotICogICAgICA8VEQgV0lEVEg9IjMxJSI+Ci0gKiAgICAgICAgICA8UCBBTElHTj0iQ0VOVEVSIj5jcDI4NAotICogICAgICA8L1REPgotICogIDwvVFI+Ci0gKiAgPFRSPgotICogICAgICA8VEQgV0lEVEg9IjMzJSI+RUJDRElDOiBHcmVhdCBCcml0YWluPC9URD4KLSAqICAgICAgPFREIFdJRFRIPSIxNSUiPgotICogICAgICAgICAgPFAgQUxJR049IkNFTlRFUiI+ZWJjZGljLWNwLWdiCi0gKiAgICAgIDwvVEQ+Ci0gKiAgICAgIDxURCBXSURUSD0iMTIlIj4KLSAqICAgICAgICAgIDxQIEFMSUdOPSJDRU5URVIiPklBTkEKLSAqICAgICAgPC9URD4KLSAqICAgICAgPFREIFdJRFRIPSIzMSUiPgotICogICAgICAgICAgPFAgQUxJR049IkNFTlRFUiI+Y3AyODUKLSAqICAgICAgPC9URD4KLSAqICA8L1RSPgotICogIDxUUj4KLSAqICAgICAgPFREIFdJRFRIPSIzMyUiPkVCQ0RJQzogRnJhbmNlPC9URD4KLSAqICAgICAgPFREIFdJRFRIPSIxNSUiPgotICogICAgICAgICAgPFAgQUxJR049IkNFTlRFUiI+ZWJjZGljLWNwLWZyCi0gKiAgICAgIDwvVEQ+Ci0gKiAgICAgIDxURCBXSURUSD0iMTIlIj4KLSAqICAgICAgICAgIDxQIEFMSUdOPSJDRU5URVIiPklBTkEKLSAqICAgICAgPC9URD4KLSAqICAgICAgPFREIFdJRFRIPSIzMSUiPgotICogICAgICAgICAgPFAgQUxJR049IkNFTlRFUiI+Y3AyOTcKLSAqICAgICAgPC9URD4KLSAqICA8L1RSPgotICogIDxUUj4KLSAqICAgICAgPFREIFdJRFRIPSIzMyUiPkVCQ0RJQzogQXJhYmljPC9URD4KLSAqICAgICAgPFREIFdJRFRIPSIxNSUiPgotICogICAgICAgICAgPFAgQUxJR049IkNFTlRFUiI+ZWJjZGljLWNwLWFyMQotICogICAgICA8L1REPgotICogICAgICA8VEQgV0lEVEg9IjEyJSI+Ci0gKiAgICAgICAgICA8UCBBTElHTj0iQ0VOVEVSIj5JQU5BCi0gKiAgICAgIDwvVEQ+Ci0gKiAgICAgIDxURCBXSURUSD0iMzElIj4KLSAqICAgICAgICAgIDxQIEFMSUdOPSJDRU5URVIiPmNwNDIwCi0gKiAgICAgIDwvVEQ+Ci0gKiAgPC9UUj4KLSAqICA8VFI+Ci0gKiAgICAgIDxURCBXSURUSD0iMzMlIj5FQkNESUM6IEhlYnJldzwvVEQ+Ci0gKiAgICAgIDxURCBXSURUSD0iMTUlIj4KLSAqICAgICAgICAgIDxQIEFMSUdOPSJDRU5URVIiPmViY2RpYy1jcC1oZQotICogICAgICA8L1REPgotICogICAgICA8VEQgV0lEVEg9IjEyJSI+Ci0gKiAgICAgICAgICA8UCBBTElHTj0iQ0VOVEVSIj5JQU5BCi0gKiAgICAgIDwvVEQ+Ci0gKiAgICAgIDxURCBXSURUSD0iMzElIj4KLSAqICAgICAgICAgIDxQIEFMSUdOPSJDRU5URVIiPmNwNDI0Ci0gKiAgICAgIDwvVEQ+Ci0gKiAgPC9UUj4KLSAqICA8VFI+Ci0gKiAgICAgIDxURCBXSURUSD0iMzMlIj5FQkNESUM6IFN3aXR6ZXJsYW5kPC9URD4KLSAqICAgICAgPFREIFdJRFRIPSIxNSUiPgotICogICAgICAgICAgPFAgQUxJR049IkNFTlRFUiI+ZWJjZGljLWNwLWNoCi0gKiAgICAgIDwvVEQ+Ci0gKiAgICAgIDxURCBXSURUSD0iMTIlIj4KLSAqICAgICAgICAgIDxQIEFMSUdOPSJDRU5URVIiPklBTkEKLSAqICAgICAgPC9URD4KLSAqICAgICAgPFREIFdJRFRIPSIzMSUiPgotICogICAgICAgICAgPFAgQUxJR049IkNFTlRFUiI+Y3A1MDAKLSAqICAgICAgPC9URD4KLSAqICA8L1RSPgotICogIDxUUj4KLSAqICAgICAgPFREIFdJRFRIPSIzMyUiPkVCQ0RJQzogUm9lY2U8L1REPgotICogICAgICA8VEQgV0lEVEg9IjE1JSI+Ci0gKiAgICAgICAgICA8UCBBTElHTj0iQ0VOVEVSIj5lYmNkaWMtY3Atcm9lY2UKLSAqICAgICAgPC9URD4KLSAqICAgICAgPFREIFdJRFRIPSIxMiUiPgotICogICAgICAgICAgPFAgQUxJR049IkNFTlRFUiI+SUFOQQotICogICAgICA8L1REPgotICogICAgICA8VEQgV0lEVEg9IjMxJSI+Ci0gKiAgICAgICAgICA8UCBBTElHTj0iQ0VOVEVSIj5jcDg3MAotICogICAgICA8L1REPgotICogIDwvVFI+Ci0gKiAgPFRSPgotICogICAgICA8VEQgV0lEVEg9IjMzJSI+RUJDRElDOiBZdWdvc2xhdmlhPC9URD4KLSAqICAgICAgPFREIFdJRFRIPSIxNSUiPgotICogICAgICAgICAgPFAgQUxJR049IkNFTlRFUiI+ZWJjZGljLWNwLXl1Ci0gKiAgICAgIDwvVEQ+Ci0gKiAgICAgIDxURCBXSURUSD0iMTIlIj4KLSAqICAgICAgICAgIDxQIEFMSUdOPSJDRU5URVIiPklBTkEKLSAqICAgICAgPC9URD4KLSAqICAgICAgPFREIFdJRFRIPSIzMSUiPgotICogICAgICAgICAgPFAgQUxJR049IkNFTlRFUiI+Y3A4NzAKLSAqICAgICAgPC9URD4KLSAqICA8L1RSPgotICogIDxUUj4KLSAqICAgICAgPFREIFdJRFRIPSIzMyUiPkVCQ0RJQzogSWNlbGFuZDwvVEQ+Ci0gKiAgICAgIDxURCBXSURUSD0iMTUlIj4KLSAqICAgICAgICAgIDxQIEFMSUdOPSJDRU5URVIiPmViY2RpYy1jcC1pcwotICogICAgICA8L1REPgotICogICAgICA8VEQgV0lEVEg9IjEyJSI+Ci0gKiAgICAgICAgICA8UCBBTElHTj0iQ0VOVEVSIj5JQU5BCi0gKiAgICAgIDwvVEQ+Ci0gKiAgICAgIDxURCBXSURUSD0iMzElIj4KLSAqICAgICAgICAgIDxQIEFMSUdOPSJDRU5URVIiPmNwODcxCi0gKiAgICAgIDwvVEQ+Ci0gKiAgPC9UUj4KLSAqICA8VFI+Ci0gKiAgICAgIDxURCBXSURUSD0iMzMlIj5FQkNESUM6IFVyZHU8L1REPgotICogICAgICA8VEQgV0lEVEg9IjE1JSI+Ci0gKiAgICAgICAgICA8UCBBTElHTj0iQ0VOVEVSIj5lYmNkaWMtY3AtYXIyCi0gKiAgICAgIDwvVEQ+Ci0gKiAgICAgIDxURCBXSURUSD0iMTIlIj4KLSAqICAgICAgICAgIDxQIEFMSUdOPSJDRU5URVIiPklBTkEKLSAqICAgICAgPC9URD4KLSAqICAgICAgPFREIFdJRFRIPSIzMSUiPgotICogICAgICAgICAgPFAgQUxJR049IkNFTlRFUiI+Y3A5MTgKLSAqICAgICAgPC9URD4KLSAqICA8L1RSPgotICogIDxUUj4KLSAqICAgICAgPFREIFdJRFRIPSIzMyUiPkNoaW5lc2UgZm9yIFBSQywgbWl4ZWQgMS8yIGJ5dGU8L1REPgotICogICAgICA8VEQgV0lEVEg9IjE1JSI+Ci0gKiAgICAgICAgICA8UCBBTElHTj0iQ0VOVEVSIj5nYjIzMTIKLSAqICAgICAgPC9URD4KLSAqICAgICAgPFREIFdJRFRIPSIxMiUiPgotICogICAgICAgICAgPFAgQUxJR049IkNFTlRFUiI+TUlNRQotICogICAgICA8L1REPgotICogICAgICA8VEQgV0lEVEg9IjMxJSI+Ci0gKiAgICAgICAgICA8UCBBTElHTj0iQ0VOVEVSIj5HQjIzMTIKLSAqICAgICAgPC9URD4KLSAqICA8L1RSPgotICogIDxUUj4KLSAqICAgICAgPFREIFdJRFRIPSIzMyUiPkV4dGVuZGVkIFVuaXggQ29kZSwgcGFja2VkIGZvciBKYXBhbmVzZTwvVEQ+Ci0gKiAgICAgIDxURCBXSURUSD0iMTUlIj4KLSAqICAgICAgICAgIDxQIEFMSUdOPSJDRU5URVIiPmV1Yy1qcAotICogICAgICA8L1REPgotICogICAgICA8VEQgV0lEVEg9IjEyJSI+Ci0gKiAgICAgICAgICA8UCBBTElHTj0iQ0VOVEVSIj5NSU1FCi0gKiAgICAgIDwvVEQ+Ci0gKiAgICAgIDxURCBXSURUSD0iMzElIj4KLSAqICAgICAgICAgIDxQIEFMSUdOPSJDRU5URVIiPmV1Y2ppcwotICogICAgICA8L1REPgotICogIDwvVFI+Ci0gKiAgPFRSPgotICogICAgICA8VEQgV0lEVEg9IjMzJSI+SmFwYW5lc2U6IGlzby0yMDIyLWpwPC9URD4KLSAqICAgICAgPFREIFdJRFRIPSIxNSUiPgotICogICAgICAgICAgPFAgQUxJR049IkNFTlRFUiI+aXNvLTIwMjAtanAKLSAqICAgICAgPC9URD4KLSAqICAgICAgPFREIFdJRFRIPSIxMiUiPgotICogICAgICAgICAgPFAgQUxJR049IkNFTlRFUiI+TUlNRQotICogICAgICA8L1REPgotICogICAgICA8VEQgV0lEVEg9IjMxJSI+Ci0gKiAgICAgICAgICA8UCBBTElHTj0iQ0VOVEVSIj5KSVMKLSAqICAgICAgPC9URD4KLSAqICA8L1RSPgotICogIDxUUj4KLSAqICAgICAgPFREIFdJRFRIPSIzMyUiPkphcGFuZXNlOiBTaGlmdCBKSVM8L1REPgotICogICAgICA8VEQgV0lEVEg9IjE1JSI+Ci0gKiAgICAgICAgICA8UCBBTElHTj0iQ0VOVEVSIj5TaGlmdF9KSVMKLSAqICAgICAgPC9URD4KLSAqICAgICAgPFREIFdJRFRIPSIxMiUiPgotICogICAgICAgICAgPFAgQUxJR049IkNFTlRFUiI+TUlNRQotICogICAgICA8L1REPgotICogICAgICA8VEQgV0lEVEg9IjMxJSI+Ci0gKiAgICAgICAgICA8UCBBTElHTj0iQ0VOVEVSIj5TSklTCi0gKiAgICAgIDwvVEQ+Ci0gKiAgPC9UUj4KLSAqICA8VFI+Ci0gKiAgICAgIDxURCBXSURUSD0iMzMlIj5DaGluZXNlOiBCaWc1PC9URD4KLSAqICAgICAgPFREIFdJRFRIPSIxNSUiPgotICogICAgICAgICAgPFAgQUxJR049IkNFTlRFUiI+QmlnNQotICogICAgICA8L1REPgotICogICAgICA8VEQgV0lEVEg9IjEyJSI+Ci0gKiAgICAgICAgICA8UCBBTElHTj0iQ0VOVEVSIj5NSU1FCi0gKiAgICAgIDwvVEQ+Ci0gKiAgICAgIDxURCBXSURUSD0iMzElIj4KLSAqICAgICAgICAgIDxQIEFMSUdOPSJDRU5URVIiPkJpZzUKLSAqICAgICAgPC9URD4KLSAqICA8L1RSPgotICogIDxUUj4KLSAqICAgICAgPFREIFdJRFRIPSIzMyUiPkV4dGVuZGVkIFVuaXggQ29kZSwgcGFja2VkIGZvciBLb3JlYW48L1REPgotICogICAgICA8VEQgV0lEVEg9IjE1JSI+Ci0gKiAgICAgICAgICA8UCBBTElHTj0iQ0VOVEVSIj5ldWMta3IKLSAqICAgICAgPC9URD4KLSAqICAgICAgPFREIFdJRFRIPSIxMiUiPgotICogICAgICAgICAgPFAgQUxJR049IkNFTlRFUiI+TUlNRQotICogICAgICA8L1REPgotICogICAgICA8VEQgV0lEVEg9IjMxJSI+Ci0gKiAgICAgICAgICA8UCBBTElHTj0iQ0VOVEVSIj5pc28yMDIya3IKLSAqICAgICAgPC9URD4KLSAqICA8L1RSPgotICogIDxUUj4KLSAqICAgICAgPFREIFdJRFRIPSIzMyUiPkN5cmlsbGljPC9URD4KLSAqICAgICAgPFREIFdJRFRIPSIxNSUiPgotICogICAgICAgICAgPFAgQUxJR049IkNFTlRFUiI+a29pOC1yCi0gKiAgICAgIDwvVEQ+Ci0gKiAgICAgIDxURCBXSURUSD0iMTIlIj4KLSAqICAgICAgICAgIDxQIEFMSUdOPSJDRU5URVIiPk1JTUUKLSAqICAgICAgPC9URD4KLSAqICAgICAgPFREIFdJRFRIPSIzMSUiPgotICogICAgICAgICAgPFAgQUxJR049IkNFTlRFUiI+a29pOC1yCi0gKiAgICAgIDwvVEQ+Ci0gKiAgPC9UUj4KLSAqIDwvVEFCTEU+Ci0gKgotICogQGF1dGhvciBUQU1VUkEgS2VudCwgSUJNCi0gKiBAYXV0aG9yIEFuZHkgQ2xhcmssIElCTQotICoKLSAqLwotcHVibGljIGNsYXNzIEVuY29kaW5nTWFwIHsKLQotICAgIC8vCi0gICAgLy8gRGF0YQotICAgIC8vCi0KLSAgICAvKiogZklBTkEySmF2YU1hcCAqLwotICAgIHByb3RlY3RlZCBmaW5hbCBzdGF0aWMgTWFwPFN0cmluZywgU3RyaW5nPiBmSUFOQTJKYXZhTWFwOwotCi0gICAgLyoqIGZKYXZhMklBTkFNYXAgKi8KLSAgICBwcm90ZWN0ZWQgZmluYWwgc3RhdGljIE1hcDxTdHJpbmcsIFN0cmluZz4gZkphdmEySUFOQU1hcDsKLQotICAgIC8vCi0gICAgLy8gU3RhdGljIGluaXRpYWxpemF0aW9uCi0gICAgLy8KLQotICAgIHN0YXRpYyB7Ci0gICAgICAgIE1hcDxTdHJpbmcsIFN0cmluZz4gYUlBTkEySmF2YU1hcCA9IG5ldyBIYXNoTWFwPD4oKTsKLSAgICAgICAgTWFwPFN0cmluZywgU3RyaW5nPiBhSmF2YTJJQU5BTWFwID0gbmV3IEhhc2hNYXA8PigpOwotCi0gICAgICAgIC8vIGFkZCBJQU5BIHRvIEphdmEgZW5jb2RpbmcgbWFwcGluZ3MuCi0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJCSUc1IiwgICAgICAgICAgICAiQmlnNSIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiQ1NCSUc1IiwgICAgICAgICAgICAiQmlnNSIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiQ1AwMzciLCAgICAiQ1AwMzciKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklCTTAzNyIsICAgICJDUDAzNyIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiQ1NJQk0wMzciLCAgICAiQ1AwMzciKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkVCQ0RJQy1DUC1VUyIsICAgICJDUDAzNyIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiRUJDRElDLUNQLUNBIiwgICAgIkNQMDM3Iik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJFQkNESUMtQ1AtTkwiLCAgICAiQ1AwMzciKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkVCQ0RJQy1DUC1XVCIsICAgICJDUDAzNyIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiSUJNMjczIiwgICAgIkNQMjczIik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJDUDI3MyIsICAgICJDUDI3MyIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiQ1NJQk0yNzMiLCAgICAiQ1AyNzMiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklCTTI3NyIsICAgICJDUDI3NyIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiQ1AyNzciLCAgICAiQ1AyNzciKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkNTSUJNMjc3IiwgICAgIkNQMjc3Iik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJFQkNESUMtQ1AtREsiLCAgICAiQ1AyNzciKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkVCQ0RJQy1DUC1OTyIsICAgICJDUDI3NyIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiSUJNMjc4IiwgICAgIkNQMjc4Iik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJDUDI3OCIsICAgICJDUDI3OCIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiQ1NJQk0yNzgiLCAgICAiQ1AyNzgiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkVCQ0RJQy1DUC1GSSIsICAgICJDUDI3OCIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiRUJDRElDLUNQLVNFIiwgICAgIkNQMjc4Iik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJJQk0yODAiLCAgICAiQ1AyODAiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkNQMjgwIiwgICAgIkNQMjgwIik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJDU0lCTTI4MCIsICAgICJDUDI4MCIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiRUJDRElDLUNQLUlUIiwgICAgIkNQMjgwIik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJJQk0yODQiLCAgICAiQ1AyODQiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkNQMjg0IiwgICAgIkNQMjg0Iik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJDU0lCTTI4NCIsICAgICJDUDI4NCIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiRUJDRElDLUNQLUVTIiwgICAgIkNQMjg0Iik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJFQkNESUMtQ1AtR0IiLCAgICAiQ1AyODUiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklCTTI4NSIsICAgICJDUDI4NSIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiQ1AyODUiLCAgICAiQ1AyODUiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkNTSUJNMjg1IiwgICAgIkNQMjg1Iik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJFQkNESUMtSlAtS0FOQSIsICAgICJDUDI5MCIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiSUJNMjkwIiwgICAgIkNQMjkwIik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJDUDI5MCIsICAgICJDUDI5MCIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiQ1NJQk0yOTAiLCAgICAiQ1AyOTAiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkVCQ0RJQy1DUC1GUiIsICAgICJDUDI5NyIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiSUJNMjk3IiwgICAgIkNQMjk3Iik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJDUDI5NyIsICAgICJDUDI5NyIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiQ1NJQk0yOTciLCAgICAiQ1AyOTciKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkVCQ0RJQy1DUC1BUjEiLCAgICJDUDQyMCIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiSUJNNDIwIiwgICAgIkNQNDIwIik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJDUDQyMCIsICAgICJDUDQyMCIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiQ1NJQk00MjAiLCAgICAiQ1A0MjAiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkVCQ0RJQy1DUC1IRSIsICAgICJDUDQyNCIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiSUJNNDI0IiwgICAgIkNQNDI0Iik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJDUDQyNCIsICAgICJDUDQyNCIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiQ1NJQk00MjQiLCAgICAiQ1A0MjQiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklCTTQzNyIsICAgICJDUDQzNyIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiNDM3IiwgICAgIkNQNDM3Iik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJDUDQzNyIsICAgICJDUDQzNyIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiQ1NQQzhDT0RFUEFHRTQzNyIsICAgICJDUDQzNyIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiRUJDRElDLUNQLUNIIiwgICAgIkNQNTAwIik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJJQk01MDAiLCAgICAiQ1A1MDAiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkNQNTAwIiwgICAgIkNQNTAwIik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJDU0lCTTUwMCIsICAgICJDUDUwMCIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiRUJDRElDLUNQLUNIIiwgICAgIkNQNTAwIik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJFQkNESUMtQ1AtQkUiLCAgICAiQ1A1MDAiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklCTTc3NSIsICAgICJDUDc3NSIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiQ1A3NzUiLCAgICAiQ1A3NzUiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkNTUEM3NzVCQUxUSUMiLCAgICAiQ1A3NzUiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklCTTg1MCIsICAgICJDUDg1MCIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiODUwIiwgICAgIkNQODUwIik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJDUDg1MCIsICAgICJDUDg1MCIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiQ1NQQzg1ME1VTFRJTElOR1VBTCIsICAgICJDUDg1MCIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiSUJNODUyIiwgICAgIkNQODUyIik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCI4NTIiLCAgICAiQ1A4NTIiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkNQODUyIiwgICAgIkNQODUyIik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJDU1BDUDg1MiIsICAgICJDUDg1MiIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiSUJNODU1IiwgICAgIkNQODU1Iik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCI4NTUiLCAgICAiQ1A4NTUiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkNQODU1IiwgICAgIkNQODU1Iik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJDU0lCTTg1NSIsICAgICJDUDg1NSIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiSUJNODU3IiwgICAgIkNQODU3Iik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCI4NTciLCAgICAiQ1A4NTciKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkNQODU3IiwgICAgIkNQODU3Iik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJDU0lCTTg1NyIsICAgICJDUDg1NyIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiSUJNMDA4NTgiLCAgICAiQ1A4NTgiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkNQMDA4NTgiLCAgICAiQ1A4NTgiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkNDU0lEMDA4NTgiLCAgICAiQ1A4NTgiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklCTTg2MCIsICAgICJDUDg2MCIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiODYwIiwgICAgIkNQODYwIik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJDUDg2MCIsICAgICJDUDg2MCIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiQ1NJQk04NjAiLCAgICAiQ1A4NjAiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklCTTg2MSIsICAgICJDUDg2MSIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiODYxIiwgICAgIkNQODYxIik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJDUDg2MSIsICAgICJDUDg2MSIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiQ1AtSVMiLCAgICAiQ1A4NjEiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkNTSUJNODYxIiwgICAgIkNQODYxIik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJJQk04NjIiLCAgICAiQ1A4NjIiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIjg2MiIsICAgICJDUDg2MiIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiQ1A4NjIiLCAgICAiQ1A4NjIiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkNTUEM4NjJMQVRJTkhFQlJFVyIsICAgICJDUDg2MiIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiSUJNODYzIiwgICAgIkNQODYzIik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCI4NjMiLCAgICAiQ1A4NjMiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkNQODYzIiwgICAgIkNQODYzIik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJDU0lCTTg2MyIsICAgICJDUDg2MyIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiSUJNODY0IiwgICAgIkNQODY0Iik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJDUDg2NCIsICAgICJDUDg2NCIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiQ1NJQk04NjQiLCAgICAiQ1A4NjQiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklCTTg2NSIsICAgICJDUDg2NSIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiODY1IiwgICAgIkNQODY1Iik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJDUDg2NSIsICAgICJDUDg2NSIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiQ1NJQk04NjUiLCAgICAiQ1A4NjUiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklCTTg2NiIsICAgICJDUDg2NiIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiODY2IiwgICAgIkNQODY2Iik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJDUDg2NiIsICAgICJDUDg2NiIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiQ1NJQk04NjYiLCAgICAiQ1A4NjYiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklCTTg2OCIsICAgICJDUDg2OCIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiQ1A4NjgiLCAgICAiQ1A4NjgiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkNTSUJNODY4IiwgICAgIkNQODY4Iik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJDUC1BUiIsICAgICAgICAiQ1A4NjgiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklCTTg2OSIsICAgICJDUDg2OSIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiQ1A4NjkiLCAgICAiQ1A4NjkiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkNTSUJNODY5IiwgICAgIkNQODY5Iik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJDUC1HUiIsICAgICAgICAiQ1A4NjkiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklCTTg3MCIsICAgICJDUDg3MCIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiQ1A4NzAiLCAgICAiQ1A4NzAiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkNTSUJNODcwIiwgICAgIkNQODcwIik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJFQkNESUMtQ1AtUk9FQ0UiLCAiQ1A4NzAiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkVCQ0RJQy1DUC1ZVSIsICAgICJDUDg3MCIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiSUJNODcxIiwgICAgIkNQODcxIik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJDUDg3MSIsICAgICJDUDg3MSIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiQ1NJQk04NzEiLCAgICAiQ1A4NzEiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkVCQ0RJQy1DUC1JUyIsICAgICJDUDg3MSIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiSUJNOTE4IiwgICAgIkNQOTE4Iik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJDUDkxOCIsICAgICJDUDkxOCIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiQ1NJQk05MTgiLCAgICAiQ1A5MTgiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkVCQ0RJQy1DUC1BUjIiLCAgICJDUDkxOCIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiSUJNMDA5MjQiLCAgICAiQ1A5MjQiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkNQMDA5MjQiLCAgICAiQ1A5MjQiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkNDU0lEMDA5MjQiLCAgICAiQ1A5MjQiKTsKLSAgICAgICAgLy8gaXMgdGhpcyBhbiBlcnJvcj8/PwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiRUJDRElDLUxBVElOOS0tRVVSTyIsICAgICJDUDkyNCIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiSUJNMTAyNiIsICAgICJDUDEwMjYiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkNQMTAyNiIsICAgICJDUDEwMjYiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkNTSUJNMTAyNiIsICAgICJDUDEwMjYiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklCTTAxMTQwIiwgICAgIkNwMTE0MCIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiQ1AwMTE0MCIsICAgICJDcDExNDAiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkNDU0lEMDExNDAiLCAgICAiQ3AxMTQwIik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJJQk0wMTE0MSIsICAgICJDcDExNDEiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkNQMDExNDEiLCAgICAiQ3AxMTQxIik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJDQ1NJRDAxMTQxIiwgICAgIkNwMTE0MSIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiSUJNMDExNDIiLCAgICAiQ3AxMTQyIik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJDUDAxMTQyIiwgICAgIkNwMTE0MiIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiQ0NTSUQwMTE0MiIsICAgICJDcDExNDIiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklCTTAxMTQzIiwgICAgIkNwMTE0MyIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiQ1AwMTE0MyIsICAgICJDcDExNDMiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkNDU0lEMDExNDMiLCAgICAiQ3AxMTQzIik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJJQk0wMTE0NCIsICAgICJDcDExNDQiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkNQMDExNDQiLCAgICAiQ3AxMTQ0Iik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJDQ1NJRDAxMTQ0IiwgICAgIkNwMTE0NCIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiSUJNMDExNDUiLCAgICAiQ3AxMTQ1Iik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJDUDAxMTQ1IiwgICAgIkNwMTE0NSIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiQ0NTSUQwMTE0NSIsICAgICJDcDExNDUiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklCTTAxMTQ2IiwgICAgIkNwMTE0NiIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiQ1AwMTE0NiIsICAgICJDcDExNDYiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkNDU0lEMDExNDYiLCAgICAiQ3AxMTQ2Iik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJJQk0wMTE0NyIsICAgICJDcDExNDciKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkNQMDExNDciLCAgICAiQ3AxMTQ3Iik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJDQ1NJRDAxMTQ3IiwgICAgIkNwMTE0NyIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiSUJNMDExNDgiLCAgICAiQ3AxMTQ4Iik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJDUDAxMTQ4IiwgICAgIkNwMTE0OCIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiQ0NTSUQwMTE0OCIsICAgICJDcDExNDgiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklCTTAxMTQ5IiwgICAgIkNwMTE0OSIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiQ1AwMTE0OSIsICAgICJDcDExNDkiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkNDU0lEMDExNDkiLCAgICAiQ3AxMTQ5Iik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJFVUMtSlAiLCAgICAgICAgICAiRVVDSklTIik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJDU0VVQ1BLREZNVEpBUEFORVNFIiwgICAgICAgICAgIkVVQ0pJUyIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiRVhURU5ERURfVU5JWF9DT0RFX1BBQ0tFRF9GT1JNQVRfRk9SX0pBUEFORVNFIiwgICAgICAgICAgIkVVQ0pJUyIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiRVVDLUtSIiwgICAgICAgICAgIktTQzU2MDEiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkNTRVVDS1IiLCAgICAgICAgICAiS1NDNTYwMSIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiS1NfQ181NjAxLTE5ODciLCAgICAgICAgICAiS1NfQ181NjAxLTE5ODciKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklTTy1JUi0xNDkiLCAgICAgICAgICAiS1NfQ181NjAxLTE5ODciKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIktTX0NfNTYwMS0xOTg5IiwgICAgICAgICAgIktTX0NfNTYwMS0xOTg3Iik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJLU0NfNTYwMSIsICAgICAgICAgICJLU19DXzU2MDEtMTk4NyIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiS09SRUFOIiwgICAgICAgICAgIktTX0NfNTYwMS0xOTg3Iik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJDU0tTQzU2MDExOTg3IiwgICAgICAgICAgIktTX0NfNTYwMS0xOTg3Iik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJHQjIzMTIiLCAgICAgICAgICAiR0IyMzEyIik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJDU0dCMjMxMiIsICAgICAgICAgICJHQjIzMTIiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklTTy0yMDIyLUpQIiwgICAgICJKSVMiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkNTSVNPMjAyMkpQIiwgICAgICJKSVMiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklTTy0yMDIyLUtSIiwgICAgICJJU08yMDIyS1IiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkNTSVNPMjAyMktSIiwgICAgICJJU08yMDIyS1IiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklTTy0yMDIyLUNOIiwgICAgICJJU08yMDIyQ04iKTsKLQotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiWDAyMDEiLCAgIkpJUzAyMDEiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkNTSVNPMTNKSVNDNjIyMEpQIiwgIkpJUzAyMDEiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIlgwMjA4IiwgICJKSVMwMjA4Iik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJJU08tSVItODciLCAgIkpJUzAyMDgiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIlgwMjA4ZGJpSklTX1gwMjA4LTE5ODMiLCAgIkpJUzAyMDgiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkNTSVNPODdKSVNYMDIwOCIsICAiSklTMDIwOCIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiWDAyMTIiLCAgIkpJUzAyMTIiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklTTy1JUi0xNTkiLCAgIkpJUzAyMTIiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkNTSVNPMTU5SklTWDAyMTIxOTkwIiwgICJKSVMwMjEyIik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJHQjE4MDMwIiwgICAgICAgIkdCMTgwMzAiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkdCSyIsICAgICAgICJHQksiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkNQOTM2IiwgICAgICAgIkdCSyIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiTVM5MzYiLCAgICAgICAiR0JLIik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJXSU5ET1dTLTkzNiIsICAgICAgICJHQksiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIlNISUZUX0pJUyIsICAgICAgICJTSklTIik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJDU1NISUZUSklTIiwgICAgICAgIlNKSVMiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIk1TX0tBTkpJIiwgICAgICAgIlNKSVMiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIldJTkRPV1MtMzFKIiwgICAgICAgIk1TOTMyIik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJDU1dJTkRPV1MzMUoiLCAgICAgICAiTVM5MzIiKTsKLQotICAgICAgICAgICAgLy8gQWRkIHN1cHBvcnQgZm9yIENwMTI1MiBhbmQgaXRzIGZyaWVuZHMKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIldJTkRPV1MtMTI1MCIsICAgIkNwMTI1MCIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiV0lORE9XUy0xMjUxIiwgICAiQ3AxMjUxIik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJXSU5ET1dTLTEyNTIiLCAgICJDcDEyNTIiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIldJTkRPV1MtMTI1MyIsICAgIkNwMTI1MyIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiV0lORE9XUy0xMjU0IiwgICAiQ3AxMjU0Iik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJXSU5ET1dTLTEyNTUiLCAgICJDcDEyNTUiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIldJTkRPV1MtMTI1NiIsICAgIkNwMTI1NiIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiV0lORE9XUy0xMjU3IiwgICAiQ3AxMjU3Iik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJXSU5ET1dTLTEyNTgiLCAgICJDcDEyNTgiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIlRJUy02MjAiLCAgICJUSVM2MjAiKTsKLQotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiSVNPLTg4NTktMSIsICAgICAgIklTTzg4NTlfMSIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiSVNPLUlSLTEwMCIsICAgICAgIklTTzg4NTlfMSIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiSVNPXzg4NTktMSIsICAgICAgIklTTzg4NTlfMSIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiTEFUSU4xIiwgICAgICAiSVNPODg1OV8xIik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJDU0lTT0xBVElOMSIsICAgICAgIklTTzg4NTlfMSIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiTDEiLCAgICAgICJJU084ODU5XzEiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklCTTgxOSIsICAgICAgIklTTzg4NTlfMSIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiQ1A4MTkiLCAgICAgICJJU084ODU5XzEiKTsKLQotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiSVNPLTg4NTktMiIsICAgICAgIklTTzg4NTlfMiIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiSVNPLUlSLTEwMSIsICAgICAgIklTTzg4NTlfMiIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiSVNPXzg4NTktMiIsICAgICAgIklTTzg4NTlfMiIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiTEFUSU4yIiwgICAgICAiSVNPODg1OV8yIik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJDU0lTT0xBVElOMiIsICAgICAgIklTTzg4NTlfMiIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiTDIiLCAgICAgICJJU084ODU5XzIiKTsKLQotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiSVNPLTg4NTktMyIsICAgICAgIklTTzg4NTlfMyIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiSVNPLUlSLTEwOSIsICAgICAgIklTTzg4NTlfMyIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiSVNPXzg4NTktMyIsICAgICAgIklTTzg4NTlfMyIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiTEFUSU4zIiwgICAgICAiSVNPODg1OV8zIik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJDU0lTT0xBVElOMyIsICAgICAgIklTTzg4NTlfMyIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiTDMiLCAgICAgICJJU084ODU5XzMiKTsKLQotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiSVNPLTg4NTktNCIsICAgICAgIklTTzg4NTlfNCIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiSVNPLUlSLTExMCIsICAgICAgIklTTzg4NTlfNCIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiSVNPXzg4NTktNCIsICAgICAgIklTTzg4NTlfNCIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiTEFUSU40IiwgICAgICAiSVNPODg1OV80Iik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJDU0lTT0xBVElONCIsICAgICAgIklTTzg4NTlfNCIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiTDQiLCAgICAgICJJU084ODU5XzQiKTsKLQotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiSVNPLTg4NTktNSIsICAgICAgIklTTzg4NTlfNSIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiSVNPLUlSLTE0NCIsICAgICAgIklTTzg4NTlfNSIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiSVNPXzg4NTktNSIsICAgICAgIklTTzg4NTlfNSIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiQ1lSSUxMSUMiLCAgICAgICJJU084ODU5XzUiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkNTSVNPTEFUSU5DWVJJTExJQyIsICAgICAgIklTTzg4NTlfNSIpOwotCi0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJJU08tODg1OS02IiwgICAgICAiSVNPODg1OV82Iik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJJU08tSVItMTI3IiwgICAgICAiSVNPODg1OV82Iik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJJU09fODg1OS02IiwgICAgICAiSVNPODg1OV82Iik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJFQ01BLTExNCIsICAgICAgIklTTzg4NTlfNiIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiQVNNTy03MDgiLCAgICAgICJJU084ODU5XzYiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkFSQUJJQyIsICAgICAgIklTTzg4NTlfNiIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiQ1NJU09MQVRJTkFSQUJJQyIsICAgICAgIklTTzg4NTlfNiIpOwotCi0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJJU08tODg1OS03IiwgICAgICAiSVNPODg1OV83Iik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJJU08tSVItMTI2IiwgICAgICAiSVNPODg1OV83Iik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJJU09fODg1OS03IiwgICAgICAiSVNPODg1OV83Iik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJFTE9UXzkyOCIsICAgICAgIklTTzg4NTlfNyIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiRUNNQS0xMTgiLCAgICAgICJJU084ODU5XzciKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkdSRUVLIiwgICAgICAiSVNPODg1OV83Iik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJDU0lTT0xBVElOR1JFRUsiLCAgICAgICJJU084ODU5XzciKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkdSRUVLOCIsICAgICAgIklTTzg4NTlfNyIpOwotCi0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJJU08tODg1OS04IiwgICAgICAiSVNPODg1OV84Iik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJJU08tODg1OS04LUkiLCAgICAgICJJU084ODU5XzgiKTsgLy8gYWRkZWQgc2luY2UgdGhpcyBlbmNvZGluZyBvbmx5IGRpZmZlcnMgdy5yLnQuIHByZXNlbnRhdGlvbgotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiSVNPLUlSLTEzOCIsICAgICAgIklTTzg4NTlfOCIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiSVNPXzg4NTktOCIsICAgICAgIklTTzg4NTlfOCIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiSEVCUkVXIiwgICAgICAiSVNPODg1OV84Iik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJDU0lTT0xBVElOSEVCUkVXIiwgICAgICAiSVNPODg1OV84Iik7Ci0KLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklTTy04ODU5LTkiLCAgICAgICJJU084ODU5XzkiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklTTy1JUi0xNDgiLCAgICAgICJJU084ODU5XzkiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklTT184ODU5LTkiLCAgICAgICJJU084ODU5XzkiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkxBVElONSIsICAgICAgIklTTzg4NTlfOSIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiQ1NJU09MQVRJTjUiLCAgICAgICJJU084ODU5XzkiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkw1IiwgICAgICAiSVNPODg1OV85Iik7Ci0KLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklTTy04ODU5LTEzIiwgICAgICAiSVNPODg1OV8xMyIpOwotCi0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJJU08tODg1OS0xNSIsICAgICAgIklTTzg4NTlfMTVfRkRJUyIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiSVNPXzg4NTktMTUiLCAgICAgICJJU084ODU5XzE1X0ZESVMiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkxBVElOLTkiLCAgICAgICAgICAiSVNPODg1OV8xNV9GRElTIik7Ci0KLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIktPSTgtUiIsICAgICAgICAgICJLT0k4X1IiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkNTS09JOFIiLCAgICAgICAgICAiS09JOF9SIik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJVUy1BU0NJSSIsICAgICAgICAiQVNDSUkiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklTTy1JUi02IiwgICAgICAgICJBU0NJSSIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiQU5TSV9YMy40LTE5NjgiLCAgICAgICAgIkFTQ0lJIik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJBTlNJX1gzLjQtMTk4NiIsICAgICAgICAiQVNDSUkiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklTT182NDYuSVJWOjE5OTEiLCAgICAgICAgIkFTQ0lJIik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJBU0NJSSIsICAgICAgICAiQVNDSUkiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkNTQVNDSUkiLCAgICAgICAgIkFTQ0lJIik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJJU082NDYtVVMiLCAgICAgICAgIkFTQ0lJIik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJVUyIsICAgICAgICAiQVNDSUkiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklCTTM2NyIsICAgICAgICAiQVNDSUkiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkNQMzY3IiwgICAgICAgICJBU0NJSSIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiVVRGLTgiLCAgICAgICAgICAgIlVURjgiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIlVURi0xNiIsICAgICAgICAgICAiVVRGLTE2Iik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJVVEYtMTZCRSIsICAgICAgICAgICAiVW5pY29kZUJpZyIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiVVRGLTE2TEUiLCAgICAgICAgICAgIlVuaWNvZGVMaXR0bGUiKTsKLQotICAgICAgICAvLyBzdXBwb3J0IGZvciAxMDQ3LCBhcyBwcm9wb3NlZCB0byBiZSBhZGRlZCB0byB0aGUKLSAgICAgICAgLy8gSUFOQSByZWdpc3RyeSBpbgotICAgICAgICAvLyBodHRwOi8vbGlzdHMudzMub3JnL0FyY2hpdmVzL1B1YmxpYy9pZXRmLWNoYXJzZXQvMjAwMkp1bFNlcC8wMDQ5Lmh0bWwKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklCTS0xMDQ3IiwgICAgIkNwMTA0NyIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiSUJNMTA0NyIsICAgICJDcDEwNDciKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIkNQMTA0NyIsICAgICJDcDEwNDciKTsKLQotICAgICAgICAvLyBBZGRpbmcgbmV3IGFsaWFzZXMgYXMgcHJvcG9zZWQgaW4KLSAgICAgICAgLy8gaHR0cDovL2xpc3RzLnczLm9yZy9BcmNoaXZlcy9QdWJsaWMvaWV0Zi1jaGFyc2V0LzIwMDJKdWxTZXAvMDA1OC5odG1sCi0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJJQk0tMzciLCAgICAiQ1AwMzciKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklCTS0yNzMiLCAgICAiQ1AyNzMiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklCTS0yNzciLCAgICAiQ1AyNzciKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklCTS0yNzgiLCAgICAiQ1AyNzgiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklCTS0yODAiLCAgICAiQ1AyODAiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklCTS0yODQiLCAgICAiQ1AyODQiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklCTS0yODUiLCAgICAiQ1AyODUiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklCTS0yOTAiLCAgICAiQ1AyOTAiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklCTS0yOTciLCAgICAiQ1AyOTciKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklCTS00MjAiLCAgICAiQ1A0MjAiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklCTS00MjQiLCAgICAiQ1A0MjQiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklCTS00MzciLCAgICAiQ1A0MzciKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklCTS01MDAiLCAgICAiQ1A1MDAiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklCTS03NzUiLCAgICAiQ1A3NzUiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklCTS04NTAiLCAgICAiQ1A4NTAiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklCTS04NTIiLCAgICAiQ1A4NTIiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklCTS04NTUiLCAgICAiQ1A4NTUiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklCTS04NTciLCAgICAiQ1A4NTciKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklCTS04NTgiLCAgICAiQ1A4NTgiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklCTS04NjAiLCAgICAiQ1A4NjAiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklCTS04NjEiLCAgICAiQ1A4NjEiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklCTS04NjIiLCAgICAiQ1A4NjIiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklCTS04NjMiLCAgICAiQ1A4NjMiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklCTS04NjQiLCAgICAiQ1A4NjQiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklCTS04NjUiLCAgICAiQ1A4NjUiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklCTS04NjYiLCAgICAiQ1A4NjYiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklCTS04NjgiLCAgICAiQ1A4NjgiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklCTS04NjkiLCAgICAiQ1A4NjkiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklCTS04NzAiLCAgICAiQ1A4NzAiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklCTS04NzEiLCAgICAiQ1A4NzEiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklCTS05MTgiLCAgICAiQ1A5MTgiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklCTS05MjQiLCAgICAiQ1A5MjQiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklCTS0xMDI2IiwgICAgIkNQMTAyNiIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiSUJNLTExNDAiLCAgICAiQ3AxMTQwIik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJJQk0tMTE0MSIsICAgICJDcDExNDEiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklCTS0xMTQyIiwgICAgIkNwMTE0MiIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiSUJNLTExNDMiLCAgICAiQ3AxMTQzIik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJJQk0tMTE0NCIsICAgICJDcDExNDQiKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklCTS0xMTQ1IiwgICAgIkNwMTE0NSIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiSUJNLTExNDYiLCAgICAiQ3AxMTQ2Iik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJJQk0tMTE0NyIsICAgICJDcDExNDciKTsKLSAgICAgICAgYUlBTkEySmF2YU1hcC5wdXQoIklCTS0xMTQ4IiwgICAgIkNwMTE0OCIpOwotICAgICAgICBhSUFOQTJKYXZhTWFwLnB1dCgiSUJNLTExNDkiLCAgICAiQ3AxMTQ5Iik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJJQk0tODE5IiwgICAgICAiSVNPODg1OV8xIik7Ci0gICAgICAgIGFJQU5BMkphdmFNYXAucHV0KCJJQk0tMzY3IiwgICAgICAgICJBU0NJSSIpOwotCi0gICAgICAgIGZJQU5BMkphdmFNYXAgPSBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVNYXAoYUlBTkEySmF2YU1hcCk7Ci0gICAgICAgIC8vIFJFVklTSVQ6Ci0gICAgICAgIC8vICAgajpDTlMxMTY0MyAtPiBFVUMtVFc/Ci0gICAgICAgIC8vICAgSVNPLTIwMjItQ04/IElTTy0yMDIyLUNOLUVYVD8KLQotICAgICAgICAvLyBhZGQgSmF2YSB0byBJQU5BIGVuY29kaW5nIG1hcHBpbmdzCi0gICAgICAgIC8vYUphdmEySUFOQU1hcC5wdXQoIjg4NTlfMSIsICAgICJVUy1BU0NJSSIpOyAvLyA/Ci0gICAgICAgIGFKYXZhMklBTkFNYXAucHV0KCJJU084ODU5XzEiLCAgICAiSVNPLTg4NTktMSIpOwotICAgICAgICBhSmF2YTJJQU5BTWFwLnB1dCgiSVNPODg1OV8yIiwgICAgIklTTy04ODU5LTIiKTsKLSAgICAgICAgYUphdmEySUFOQU1hcC5wdXQoIklTTzg4NTlfMyIsICAgICJJU08tODg1OS0zIik7Ci0gICAgICAgIGFKYXZhMklBTkFNYXAucHV0KCJJU084ODU5XzQiLCAgICAiSVNPLTg4NTktNCIpOwotICAgICAgICBhSmF2YTJJQU5BTWFwLnB1dCgiSVNPODg1OV81IiwgICAgIklTTy04ODU5LTUiKTsKLSAgICAgICAgYUphdmEySUFOQU1hcC5wdXQoIklTTzg4NTlfNiIsICAgICJJU08tODg1OS02Iik7Ci0gICAgICAgIGFKYXZhMklBTkFNYXAucHV0KCJJU084ODU5XzciLCAgICAiSVNPLTg4NTktNyIpOwotICAgICAgICBhSmF2YTJJQU5BTWFwLnB1dCgiSVNPODg1OV84IiwgICAgIklTTy04ODU5LTgiKTsKLSAgICAgICAgYUphdmEySUFOQU1hcC5wdXQoIklTTzg4NTlfOSIsICAgICJJU08tODg1OS05Iik7Ci0gICAgICAgIGFKYXZhMklBTkFNYXAucHV0KCJJU084ODU5XzEzIiwgICAgIklTTy04ODU5LTEzIik7Ci0gICAgICAgIGFKYXZhMklBTkFNYXAucHV0KCJJU084ODU5XzE1IiwgICAgIklTTy04ODU5LTE1Iik7Ci0gICAgICAgIGFKYXZhMklBTkFNYXAucHV0KCJJU084ODU5XzE1X0ZESVMiLCAgICAiSVNPLTg4NTktMTUiKTsKLSAgICAgICAgYUphdmEySUFOQU1hcC5wdXQoIkJpZzUiLCAgICAgICJCSUc1Iik7Ci0gICAgICAgIGFKYXZhMklBTkFNYXAucHV0KCJDUDAzNyIsICAgICAiRUJDRElDLUNQLVVTIik7Ci0gICAgICAgIGFKYXZhMklBTkFNYXAucHV0KCJDUDI3MyIsICAgICAiSUJNMjczIik7Ci0gICAgICAgIGFKYXZhMklBTkFNYXAucHV0KCJDUDI3NyIsICAgICAiRUJDRElDLUNQLURLIik7Ci0gICAgICAgIGFKYXZhMklBTkFNYXAucHV0KCJDUDI3OCIsICAgICAiRUJDRElDLUNQLUZJIik7Ci0gICAgICAgIGFKYXZhMklBTkFNYXAucHV0KCJDUDI4MCIsICAgICAiRUJDRElDLUNQLUlUIik7Ci0gICAgICAgIGFKYXZhMklBTkFNYXAucHV0KCJDUDI4NCIsICAgICAiRUJDRElDLUNQLUVTIik7Ci0gICAgICAgIGFKYXZhMklBTkFNYXAucHV0KCJDUDI4NSIsICAgICAiRUJDRElDLUNQLUdCIik7Ci0gICAgICAgIGFKYXZhMklBTkFNYXAucHV0KCJDUDI5MCIsICAgICAiRUJDRElDLUpQLUtBTkEiKTsKLSAgICAgICAgYUphdmEySUFOQU1hcC5wdXQoIkNQMjk3IiwgICAgICJFQkNESUMtQ1AtRlIiKTsKLSAgICAgICAgYUphdmEySUFOQU1hcC5wdXQoIkNQNDIwIiwgICAgICJFQkNESUMtQ1AtQVIxIik7Ci0gICAgICAgIGFKYXZhMklBTkFNYXAucHV0KCJDUDQyNCIsICAgICAiRUJDRElDLUNQLUhFIik7Ci0gICAgICAgIGFKYXZhMklBTkFNYXAucHV0KCJDUDQzNyIsICAgICAiSUJNNDM3Iik7Ci0gICAgICAgIGFKYXZhMklBTkFNYXAucHV0KCJDUDUwMCIsICAgICAiRUJDRElDLUNQLUNIIik7Ci0gICAgICAgIGFKYXZhMklBTkFNYXAucHV0KCJDUDc3NSIsICAgICAiSUJNNzc1Iik7Ci0gICAgICAgIGFKYXZhMklBTkFNYXAucHV0KCJDUDg1MCIsICAgICAiSUJNODUwIik7Ci0gICAgICAgIGFKYXZhMklBTkFNYXAucHV0KCJDUDg1MiIsICAgICAiSUJNODUyIik7Ci0gICAgICAgIGFKYXZhMklBTkFNYXAucHV0KCJDUDg1NSIsICAgICAiSUJNODU1Iik7Ci0gICAgICAgIGFKYXZhMklBTkFNYXAucHV0KCJDUDg1NyIsICAgICAiSUJNODU3Iik7Ci0gICAgICAgIGFKYXZhMklBTkFNYXAucHV0KCJDUDg1OCIsICAgICAiSUJNMDA4NTgiKTsKLSAgICAgICAgYUphdmEySUFOQU1hcC5wdXQoIkNQODYwIiwgICAgICJJQk04NjAiKTsKLSAgICAgICAgYUphdmEySUFOQU1hcC5wdXQoIkNQODYxIiwgICAgICJJQk04NjEiKTsKLSAgICAgICAgYUphdmEySUFOQU1hcC5wdXQoIkNQODYyIiwgICAgICJJQk04NjIiKTsKLSAgICAgICAgYUphdmEySUFOQU1hcC5wdXQoIkNQODYzIiwgICAgICJJQk04NjMiKTsKLSAgICAgICAgYUphdmEySUFOQU1hcC5wdXQoIkNQODY0IiwgICAgICJJQk04NjQiKTsKLSAgICAgICAgYUphdmEySUFOQU1hcC5wdXQoIkNQODY1IiwgICAgICJJQk04NjUiKTsKLSAgICAgICAgYUphdmEySUFOQU1hcC5wdXQoIkNQODY2IiwgICAgICJJQk04NjYiKTsKLSAgICAgICAgYUphdmEySUFOQU1hcC5wdXQoIkNQODY4IiwgICAgICJJQk04NjgiKTsKLSAgICAgICAgYUphdmEySUFOQU1hcC5wdXQoIkNQODY5IiwgICAgICJJQk04NjkiKTsKLSAgICAgICAgYUphdmEySUFOQU1hcC5wdXQoIkNQODcwIiwgICAgICJFQkNESUMtQ1AtUk9FQ0UiKTsKLSAgICAgICAgYUphdmEySUFOQU1hcC5wdXQoIkNQODcxIiwgICAgICJFQkNESUMtQ1AtSVMiKTsKLSAgICAgICAgYUphdmEySUFOQU1hcC5wdXQoIkNQOTE4IiwgICAgICJFQkNESUMtQ1AtQVIyIik7Ci0gICAgICAgIGFKYXZhMklBTkFNYXAucHV0KCJDUDkyNCIsICAgICAiSUJNMDA5MjQiKTsKLSAgICAgICAgYUphdmEySUFOQU1hcC5wdXQoIkNQMTAyNiIsICAgICAiSUJNMTAyNiIpOwotICAgICAgICBhSmF2YTJJQU5BTWFwLnB1dCgiQ1AxMTQwIiwgICAgICJJQk0wMTE0MCIpOwotICAgICAgICBhSmF2YTJJQU5BTWFwLnB1dCgiQ1AxMTQxIiwgICAgICJJQk0wMTE0MSIpOwotICAgICAgICBhSmF2YTJJQU5BTWFwLnB1dCgiQ1AxMTQyIiwgICAgICJJQk0wMTE0MiIpOwotICAgICAgICBhSmF2YTJJQU5BTWFwLnB1dCgiQ1AxMTQzIiwgICAgICJJQk0wMTE0MyIpOwotICAgICAgICBhSmF2YTJJQU5BTWFwLnB1dCgiQ1AxMTQ0IiwgICAgICJJQk0wMTE0NCIpOwotICAgICAgICBhSmF2YTJJQU5BTWFwLnB1dCgiQ1AxMTQ1IiwgICAgICJJQk0wMTE0NSIpOwotICAgICAgICBhSmF2YTJJQU5BTWFwLnB1dCgiQ1AxMTQ2IiwgICAgICJJQk0wMTE0NiIpOwotICAgICAgICBhSmF2YTJJQU5BTWFwLnB1dCgiQ1AxMTQ3IiwgICAgICJJQk0wMTE0NyIpOwotICAgICAgICBhSmF2YTJJQU5BTWFwLnB1dCgiQ1AxMTQ4IiwgICAgICJJQk0wMTE0OCIpOwotICAgICAgICBhSmF2YTJJQU5BTWFwLnB1dCgiQ1AxMTQ5IiwgICAgICJJQk0wMTE0OSIpOwotICAgICAgICBhSmF2YTJJQU5BTWFwLnB1dCgiRVVDSklTIiwgICAgIkVVQy1KUCIpOwotICAgICAgICBhSmF2YTJJQU5BTWFwLnB1dCgiS1NfQ181NjAxLTE5ODciLCAgICAgICAgICAiS1NfQ181NjAxLTE5ODciKTsKLSAgICAgICAgYUphdmEySUFOQU1hcC5wdXQoIkdCMjMxMiIsICAgICJHQjIzMTIiKTsKLSAgICAgICAgYUphdmEySUFOQU1hcC5wdXQoIklTTzIwMjJLUiIsICJJU08tMjAyMi1LUiIpOwotICAgICAgICBhSmF2YTJJQU5BTWFwLnB1dCgiSVNPMjAyMkNOIiwgIklTTy0yMDIyLUNOIik7Ci0gICAgICAgIGFKYXZhMklBTkFNYXAucHV0KCJKSVMiLCAgICAgICAiSVNPLTIwMjItSlAiKTsKLSAgICAgICAgYUphdmEySUFOQU1hcC5wdXQoIktPSThfUiIsICAgICJLT0k4LVIiKTsKLSAgICAgICAgYUphdmEySUFOQU1hcC5wdXQoIktTQzU2MDEiLCAgICJFVUMtS1IiKTsKLSAgICAgICAgYUphdmEySUFOQU1hcC5wdXQoIkdCMTgwMzAiLCAgICAgICJHQjE4MDMwIik7Ci0gICAgICAgIGFKYXZhMklBTkFNYXAucHV0KCJHQksiLCAgICAgICAiR0JLIik7Ci0gICAgICAgIGFKYXZhMklBTkFNYXAucHV0KCJTSklTIiwgICAgICAiU0hJRlRfSklTIik7Ci0gICAgICAgIGFKYXZhMklBTkFNYXAucHV0KCJNUzkzMiIsICAgICAgIldJTkRPV1MtMzFKIik7Ci0gICAgICAgIGFKYXZhMklBTkFNYXAucHV0KCJVVEY4IiwgICAgICAiVVRGLTgiKTsKLSAgICAgICAgYUphdmEySUFOQU1hcC5wdXQoIlVuaWNvZGUiLCAgICJVVEYtMTYiKTsKLSAgICAgICAgYUphdmEySUFOQU1hcC5wdXQoIlVuaWNvZGVCaWciLCAgICJVVEYtMTZCRSIpOwotICAgICAgICBhSmF2YTJJQU5BTWFwLnB1dCgiVW5pY29kZUxpdHRsZSIsICAgIlVURi0xNkxFIik7Ci0gICAgICAgIGFKYXZhMklBTkFNYXAucHV0KCJKSVMwMjAxIiwgICJYMDIwMSIpOwotICAgICAgICBhSmF2YTJJQU5BTWFwLnB1dCgiSklTMDIwOCIsICAiWDAyMDgiKTsKLSAgICAgICAgYUphdmEySUFOQU1hcC5wdXQoIkpJUzAyMTIiLCAgIklTTy1JUi0xNTkiKTsKLQotICAgICAgICAvLyBwcm9wb3NlZCBhZGRpdGlvbiAoc2VlIGFib3ZlIGZvciBkZXRhaWxzKToKLSAgICAgICAgYUphdmEySUFOQU1hcC5wdXQoIkNQMTA0NyIsICAgICJJQk0xMDQ3Iik7Ci0KLSAgICAgICAgZkphdmEySUFOQU1hcCA9IENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZU1hcChhSUFOQTJKYXZhTWFwKTsKLSAgICB9IC8vIDxjbGluaXQ+KCkKLQotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKiBEZWZhdWx0IGNvbnN0cnVjdG9yLiAqLwotICAgIHB1YmxpYyBFbmNvZGluZ01hcCgpIHt9Ci0KLSAgICAvLwotICAgIC8vIFB1YmxpYyBzdGF0aWMgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBKYXZhIGVuY29kaW5nIG5hbWUgZm9yIHRoZSBzcGVjaWZpZWQgSUFOQSBlbmNvZGluZyBuYW1lLgotICAgICAqCi0gICAgICogQHBhcmFtIGlhbmFFbmNvZGluZyBUaGUgSUFOQSBlbmNvZGluZyBuYW1lLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldElBTkEySmF2YU1hcHBpbmcoU3RyaW5nIGlhbmFFbmNvZGluZykgewotICAgICAgICByZXR1cm4gZklBTkEySmF2YU1hcC5nZXQoaWFuYUVuY29kaW5nKTsKLSAgICB9IC8vIGdldElBTkEySmF2YU1hcHBpbmcoU3RyaW5nKTpTdHJpbmcKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIElBTkEgZW5jb2RpbmcgbmFtZSBmb3IgdGhlIHNwZWNpZmllZCBKYXZhIGVuY29kaW5nIG5hbWUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gamF2YUVuY29kaW5nIFRoZSBKYXZhIGVuY29kaW5nIG5hbWUuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0SmF2YTJJQU5BTWFwcGluZyhTdHJpbmcgamF2YUVuY29kaW5nKSB7Ci0gICAgICAgIHJldHVybiBmSmF2YTJJQU5BTWFwLmdldChqYXZhRW5jb2RpbmcpOwotICAgIH0gLy8gZ2V0SmF2YTJJQU5BTWFwcGluZyhTdHJpbmcpOlN0cmluZwotCi0KLX0gLy8gY2xhc3MgRW5jb2RpbmdNYXAKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3V0aWwvRW50aXR5UmVzb2x2ZXIyV3JhcHBlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9FbnRpdHlSZXNvbHZlcjJXcmFwcGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDA1NzJkZTEuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9FbnRpdHlSZXNvbHZlcjJXcmFwcGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMTUgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwNCwyMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWw7Ci0KLWltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci1pbXBvcnQgamF2YS5pby5SZWFkZXI7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuRXh0ZXJuYWxTdWJzZXRSZXNvbHZlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuWE1MRW50aXR5RGVzY3JpcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MUmVzb3VyY2VJZGVudGlmaWVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhOSUV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5ncmFtbWFycy5YTUxEVEREZXNjcmlwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MSW5wdXRTb3VyY2U7Ci0KLWltcG9ydCBvcmcueG1sLnNheC5leHQuRW50aXR5UmVzb2x2ZXIyOwotaW1wb3J0IG9yZy54bWwuc2F4LklucHV0U291cmNlOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKLQotLyoqCi0gKiA8cD5UaGlzIGNsYXNzIHdyYXBzIGEgU0FYIGVudGl0eSByZXNvbHZlciAoRW50aXR5UmVzb2x2ZXIyKSBpbiBhbiBYTkkgZW50aXR5IHJlc29sdmVyLjwvcD4KLSAqCi0gKiBAYXV0aG9yIE1pY2hhZWwgR2xhdmFzc2V2aWNoLCBJQk0KLSAqCi0gKi8KLXB1YmxpYyBjbGFzcyBFbnRpdHlSZXNvbHZlcjJXcmFwcGVyCi0gICAgaW1wbGVtZW50cyBFeHRlcm5hbFN1YnNldFJlc29sdmVyIHsKLQotICAgIC8vCi0gICAgLy8gRGF0YQotICAgIC8vCi0KLSAgICAvKiogQW4gaW5zdGFuY2Ugb2YgU0FYMiBFeHRlbnNpb25zIDEuMSdzIEVudGl0eVJlc29sdmVyMi4gKi8KLSAgICBwcm90ZWN0ZWQgRW50aXR5UmVzb2x2ZXIyIGZFbnRpdHlSZXNvbHZlcjsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKiBEZWZhdWx0IGNvbnN0cnVjdG9yLiAqLwotICAgIHB1YmxpYyBFbnRpdHlSZXNvbHZlcjJXcmFwcGVyKCkge30KLQotICAgIC8qKgotICAgICAqIDxwPkNyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugd3JhcHBpbmcgdGhlIGdpdmVuIFNBWCBlbnRpdHkgcmVzb2x2ZXIuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGVudGl0eVJlc29sdmVyIHRoZSBTQVggZW50aXR5IHJlc29sdmVyIHRvIHdyYXAKLSAgICAgKi8KLSAgICBwdWJsaWMgRW50aXR5UmVzb2x2ZXIyV3JhcHBlcihFbnRpdHlSZXNvbHZlcjIgZW50aXR5UmVzb2x2ZXIpIHsKLSAgICAgICAgc2V0RW50aXR5UmVzb2x2ZXIoZW50aXR5UmVzb2x2ZXIpOwotICAgIH0gLy8gPGluaXQ+KEVudGl0eVJlc29sdmVyMikKLQotICAgIC8vCi0gICAgLy8gUHVibGljIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogPHA+U2V0cyB0aGUgU0FYIGVudGl0eSByZXNvbHZlciB3cmFwcGVkIGJ5IHRoaXMgb2JqZWN0LjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlbnRpdHlSZXNvbHZlciB0aGUgU0FYIGVudGl0eSByZXNvbHZlciB0byB3cmFwCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RW50aXR5UmVzb2x2ZXIoRW50aXR5UmVzb2x2ZXIyIGVudGl0eVJlc29sdmVyKSB7Ci0gICAgICAgIGZFbnRpdHlSZXNvbHZlciA9IGVudGl0eVJlc29sdmVyOwotICAgIH0gLy8gc2V0RW50aXR5UmVzb2x2ZXIoRW50aXR5UmVzb2x2ZXIyKQotCi0gICAgLyoqCi0gICAgICogPHA+UmV0dXJucyB0aGUgU0FYIGVudGl0eSByZXNvbHZlciB3cmFwcGVkIGJ5IHRoaXMgb2JqZWN0LjwvcD4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdGhlIFNBWCBlbnRpdHkgcmVzb2x2ZXIgd3JhcHBlZCBieSB0aGlzIG9iamVjdAotICAgICAqLwotICAgIHB1YmxpYyBFbnRpdHlSZXNvbHZlcjIgZ2V0RW50aXR5UmVzb2x2ZXIoKSB7Ci0gICAgICAgIHJldHVybiBmRW50aXR5UmVzb2x2ZXI7Ci0gICAgfSAvLyBnZXRFbnRpdHlSZXNvbHZlcigpOkVudGl0eVJlc29sdmVyMgotCi0gICAgLy8KLSAgICAvLyBFeHRlcm5hbFN1YnNldFJlc29sdmVyIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogPHA+TG9jYXRlcyBhbiBleHRlcm5hbCBzdWJzZXQgZm9yIGRvY3VtZW50cyB3aGljaCBkbyBub3QgZXhwbGljaXRseQotICAgICAqIHByb3ZpZGUgb25lLiBJZiBubyBleHRlcm5hbCBzdWJzZXQgaXMgcHJvdmlkZWQsIHRoaXMgbWV0aG9kIHNob3VsZAotICAgICAqIHJldHVybiA8Y29kZT5udWxsPC9jb2RlPi48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gZ3JhbW1hckRlc2NyaXB0aW9uIGEgZGVzY3JpcHRpb24gb2YgdGhlIERURAotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIG9uIGdlbmVyYWwgZXJyb3IuCi0gICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiAgVGhyb3duIGlmIHJlc29sdmVkIGVudGl0eSBzdHJlYW0gY2Fubm90IGJlCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgb3BlbmVkIG9yIHNvbWUgb3RoZXIgaS9vIGVycm9yIG9jY3Vycy4KLSAgICAgKi8KLSAgICBwdWJsaWMgWE1MSW5wdXRTb3VyY2UgZ2V0RXh0ZXJuYWxTdWJzZXQoWE1MRFRERGVzY3JpcHRpb24gZ3JhbW1hckRlc2NyaXB0aW9uKQotICAgICAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewotCi0gICAgICAgIGlmIChmRW50aXR5UmVzb2x2ZXIgIT0gbnVsbCkgewotCi0gICAgICAgICAgICBTdHJpbmcgbmFtZSA9IGdyYW1tYXJEZXNjcmlwdGlvbi5nZXRSb290TmFtZSgpOwotICAgICAgICAgICAgU3RyaW5nIGJhc2VVUkkgPSBncmFtbWFyRGVzY3JpcHRpb24uZ2V0QmFzZVN5c3RlbUlkKCk7Ci0KLSAgICAgICAgICAgIC8vIFJlc29sdmUgdXNpbmcgRW50aXR5UmVzb2x2ZXIyCi0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIElucHV0U291cmNlIGlucHV0U291cmNlID0gZkVudGl0eVJlc29sdmVyLmdldEV4dGVybmFsU3Vic2V0KG5hbWUsIGJhc2VVUkkpOwotICAgICAgICAgICAgICAgIHJldHVybiAoaW5wdXRTb3VyY2UgIT0gbnVsbCkgPyBjcmVhdGVYTUxJbnB1dFNvdXJjZShpbnB1dFNvdXJjZSwgYmFzZVVSSSkgOiBudWxsOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gZXJyb3IgcmVzb2x2aW5nIGV4dGVybmFsIHN1YnNldAotICAgICAgICAgICAgY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgRXhjZXB0aW9uIGV4ID0gZS5nZXRFeGNlcHRpb24oKTsKLSAgICAgICAgICAgICAgICBpZiAoZXggPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBleCA9IGU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHRocm93IG5ldyBYTklFeGNlcHRpb24oZXgpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gdW5hYmxlIHRvIHJlc29sdmUgZXh0ZXJuYWwgc3Vic2V0Ci0gICAgICAgIHJldHVybiBudWxsOwotCi0gICAgfSAvLyBnZXRFeHRlcm5hbFN1YnNldChYTUxEVEREZXNjcmlwdGlvbik6WE1MSW5wdXRTb3VyY2UKLQotICAgIC8vCi0gICAgLy8gWE1MRW50aXR5UmVzb2x2ZXIgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBSZXNvbHZlcyBhbiBleHRlcm5hbCBwYXJzZWQgZW50aXR5LiBJZiB0aGUgZW50aXR5IGNhbm5vdCBiZQotICAgICAqIHJlc29sdmVkLCB0aGlzIG1ldGhvZCBzaG91bGQgcmV0dXJuIG51bGwuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcmVzb3VyY2VJZGVudGlmaWVyIGNvbnRhaW5zIHRoZSBwaHlzaWNhbCBjby1vcmRpbmF0ZXMgb2YgdGhlIHJlc291cmNlIHRvIGJlIHJlc29sdmVkCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gb24gZ2VuZXJhbCBlcnJvci4KLSAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uICBUaHJvd24gaWYgcmVzb2x2ZWQgZW50aXR5IHN0cmVhbSBjYW5ub3QgYmUKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBvcGVuZWQgb3Igc29tZSBvdGhlciBpL28gZXJyb3Igb2NjdXJzLgotICAgICAqLwotICAgIHB1YmxpYyBYTUxJbnB1dFNvdXJjZSByZXNvbHZlRW50aXR5KFhNTFJlc291cmNlSWRlbnRpZmllciByZXNvdXJjZUlkZW50aWZpZXIpCi0gICAgICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7Ci0KLSAgICAgICAgaWYgKGZFbnRpdHlSZXNvbHZlciAhPSBudWxsKSB7Ci0KLSAgICAgICAgICAgIFN0cmluZyBwdWJJZCA9IHJlc291cmNlSWRlbnRpZmllci5nZXRQdWJsaWNJZCgpOwotICAgICAgICAgICAgU3RyaW5nIHN5c0lkID0gcmVzb3VyY2VJZGVudGlmaWVyLmdldExpdGVyYWxTeXN0ZW1JZCgpOwotICAgICAgICAgICAgU3RyaW5nIGJhc2VVUkkgPSByZXNvdXJjZUlkZW50aWZpZXIuZ2V0QmFzZVN5c3RlbUlkKCk7Ci0gICAgICAgICAgICBTdHJpbmcgbmFtZSA9IG51bGw7Ci0gICAgICAgICAgICBpZiAocmVzb3VyY2VJZGVudGlmaWVyIGluc3RhbmNlb2YgWE1MRFRERGVzY3JpcHRpb24pIHsKLSAgICAgICAgICAgICAgICBuYW1lID0gIltkdGRdIjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKHJlc291cmNlSWRlbnRpZmllciBpbnN0YW5jZW9mIFhNTEVudGl0eURlc2NyaXB0aW9uKSB7Ci0gICAgICAgICAgICAgICAgbmFtZSA9ICgoWE1MRW50aXR5RGVzY3JpcHRpb24pIHJlc291cmNlSWRlbnRpZmllcikuZ2V0RW50aXR5TmFtZSgpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBXaGVuIGJvdGggcHViSWQgYW5kIHN5c0lkIGFyZSBudWxsLCB0aGUgdXNlcidzIGVudGl0eSByZXNvbHZlcgotICAgICAgICAgICAgLy8gY2FuIGRvIG5vdGhpbmcgYWJvdXQgaXQuIFdlJ2QgYmV0dGVyIG5vdCBib3RoZXIgY2FsbGluZyBpdC4KLSAgICAgICAgICAgIC8vIFRoaXMgaGFwcGVucyB3aGVuIHRoZSByZXNvdXJjZUlkZW50aWZpZXIgaXMgYSBHcmFtbWFyRGVzY3JpcHRpb24sCi0gICAgICAgICAgICAvLyB3aGljaCBkZXNjcmliZXMgYSBzY2hlbWEgZ3JhbW1hciBvZiBzb21lIG5hbWVzcGFjZSwgYnV0IHdpdGhvdXQKLSAgICAgICAgICAgIC8vIGFueSBzY2hlbWEgbG9jYXRpb24gaGludC4gLVNnCi0gICAgICAgICAgICBpZiAocHViSWQgPT0gbnVsbCAmJiBzeXNJZCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIFJlc29sdmUgdXNpbmcgRW50aXR5UmVzb2x2ZXIyCi0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIElucHV0U291cmNlIGlucHV0U291cmNlID0KLSAgICAgICAgICAgICAgICAgICAgZkVudGl0eVJlc29sdmVyLnJlc29sdmVFbnRpdHkobmFtZSwgcHViSWQsIGJhc2VVUkksIHN5c0lkKTsKLSAgICAgICAgICAgICAgICByZXR1cm4gKGlucHV0U291cmNlICE9IG51bGwpID8gY3JlYXRlWE1MSW5wdXRTb3VyY2UoaW5wdXRTb3VyY2UsIGJhc2VVUkkpIDogbnVsbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIGVycm9yIHJlc29sdmluZyBlbnRpdHkKLSAgICAgICAgICAgIGNhdGNoIChTQVhFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgIEV4Y2VwdGlvbiBleCA9IGUuZ2V0RXhjZXB0aW9uKCk7Ci0gICAgICAgICAgICAgICAgaWYgKGV4ID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgZXggPSBlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWE5JRXhjZXB0aW9uKGV4KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIHVuYWJsZSB0byByZXNvbHZlIGVudGl0eQotICAgICAgICByZXR1cm4gbnVsbDsKLQotICAgIH0gLy8gcmVzb2x2ZUVudGl0eShYTUxSZXNvdXJjZUlkZW50aWZpZXIpOlhNTElucHV0U291cmNlCi0KLSAgICAvKioKLSAgICAgKiBDcmVhdGVzIGFuIFhNTElucHV0U291cmNlIGZyb20gYSBTQVggSW5wdXRTb3VyY2UuCi0gICAgICovCi0gICAgcHJpdmF0ZSBYTUxJbnB1dFNvdXJjZSBjcmVhdGVYTUxJbnB1dFNvdXJjZShJbnB1dFNvdXJjZSBzb3VyY2UsIFN0cmluZyBiYXNlVVJJKSB7Ci0KLSAgICAgICAgU3RyaW5nIHB1YmxpY0lkID0gc291cmNlLmdldFB1YmxpY0lkKCk7Ci0gICAgICAgIFN0cmluZyBzeXN0ZW1JZCA9IHNvdXJjZS5nZXRTeXN0ZW1JZCgpOwotICAgICAgICBTdHJpbmcgYmFzZVN5c3RlbUlkID0gYmFzZVVSSTsKLSAgICAgICAgSW5wdXRTdHJlYW0gYnl0ZVN0cmVhbSA9IHNvdXJjZS5nZXRCeXRlU3RyZWFtKCk7Ci0gICAgICAgIFJlYWRlciBjaGFyU3RyZWFtID0gc291cmNlLmdldENoYXJhY3RlclN0cmVhbSgpOwotICAgICAgICBTdHJpbmcgZW5jb2RpbmcgPSBzb3VyY2UuZ2V0RW5jb2RpbmcoKTsKLSAgICAgICAgWE1MSW5wdXRTb3VyY2UgeG1sSW5wdXRTb3VyY2UgPQotICAgICAgICAgICAgbmV3IFhNTElucHV0U291cmNlKHB1YmxpY0lkLCBzeXN0ZW1JZCwgYmFzZVN5c3RlbUlkKTsKLSAgICAgICAgeG1sSW5wdXRTb3VyY2Uuc2V0Qnl0ZVN0cmVhbShieXRlU3RyZWFtKTsKLSAgICAgICAgeG1sSW5wdXRTb3VyY2Uuc2V0Q2hhcmFjdGVyU3RyZWFtKGNoYXJTdHJlYW0pOwotICAgICAgICB4bWxJbnB1dFNvdXJjZS5zZXRFbmNvZGluZyhlbmNvZGluZyk7Ci0gICAgICAgIHJldHVybiB4bWxJbnB1dFNvdXJjZTsKLQotICAgIH0gLy8gY3JlYXRlWE1MSW5wdXRTb3VyY2UoSW5wdXRTb3VyY2UsU3RyaW5nKTpYTUxJbnB1dFNvdXJjZQotCi19IC8vIGNsYXNzIEVudGl0eVJlc29sdmVyMldyYXBwZXIKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3V0aWwvRW50aXR5UmVzb2x2ZXJXcmFwcGVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL0VudGl0eVJlc29sdmVyV3JhcHBlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0NjAwNDdiLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3V0aWwvRW50aXR5UmVzb2x2ZXJXcmFwcGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNDEgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMSwgMjAwMiwyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWw7Ci0KLWltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci1pbXBvcnQgamF2YS5pby5SZWFkZXI7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTklFeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MUmVzb3VyY2VJZGVudGlmaWVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxFbnRpdHlSZXNvbHZlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MSW5wdXRTb3VyY2U7Ci0KLWltcG9ydCBvcmcueG1sLnNheC5FbnRpdHlSZXNvbHZlcjsKLWltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci0KLS8qKgotICogVGhpcyBjbGFzcyB3cmFwcyBhIFNBWCBlbnRpdHkgcmVzb2x2ZXIgaW4gYW4gWE5JIGVudGl0eSByZXNvbHZlci4KLSAqCi0gKiBAc2VlIEVudGl0eVJlc29sdmVyCi0gKgotICogQGF1dGhvciBBbmR5IENsYXJrLCBJQk0KLSAqCi0gKi8KLXB1YmxpYyBjbGFzcyBFbnRpdHlSZXNvbHZlcldyYXBwZXIKLSAgICBpbXBsZW1lbnRzIFhNTEVudGl0eVJlc29sdmVyIHsKLQotICAgIC8vCi0gICAgLy8gRGF0YQotICAgIC8vCi0KLSAgICAvKiogVGhlIFNBWCBlbnRpdHkgcmVzb2x2ZXIuICovCi0gICAgcHJvdGVjdGVkIEVudGl0eVJlc29sdmVyIGZFbnRpdHlSZXNvbHZlcjsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKiBEZWZhdWx0IGNvbnN0cnVjdG9yLiAqLwotICAgIHB1YmxpYyBFbnRpdHlSZXNvbHZlcldyYXBwZXIoKSB7fQotCi0gICAgLyoqIFdyYXBzIHRoZSBzcGVjaWZpZWQgU0FYIGVudGl0eSByZXNvbHZlci4gKi8KLSAgICBwdWJsaWMgRW50aXR5UmVzb2x2ZXJXcmFwcGVyKEVudGl0eVJlc29sdmVyIGVudGl0eVJlc29sdmVyKSB7Ci0gICAgICAgIHNldEVudGl0eVJlc29sdmVyKGVudGl0eVJlc29sdmVyKTsKLSAgICB9IC8vIDxpbml0PihFbnRpdHlSZXNvbHZlcikKLQotICAgIC8vCi0gICAgLy8gUHVibGljIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqIFNldHMgdGhlIFNBWCBlbnRpdHkgcmVzb2x2ZXIuICovCi0gICAgcHVibGljIHZvaWQgc2V0RW50aXR5UmVzb2x2ZXIoRW50aXR5UmVzb2x2ZXIgZW50aXR5UmVzb2x2ZXIpIHsKLSAgICAgICAgZkVudGl0eVJlc29sdmVyID0gZW50aXR5UmVzb2x2ZXI7Ci0gICAgfSAvLyBzZXRFbnRpdHlSZXNvbHZlcihFbnRpdHlSZXNvbHZlcikKLQotICAgIC8qKiBSZXR1cm5zIHRoZSBTQVggZW50aXR5IHJlc29sdmVyLiAqLwotICAgIHB1YmxpYyBFbnRpdHlSZXNvbHZlciBnZXRFbnRpdHlSZXNvbHZlcigpIHsKLSAgICAgICAgcmV0dXJuIGZFbnRpdHlSZXNvbHZlcjsKLSAgICB9IC8vIGdldEVudGl0eVJlc29sdmVyKCk6RW50aXR5UmVzb2x2ZXIKLQotICAgIC8vCi0gICAgLy8gWE1MRW50aXR5UmVzb2x2ZXIgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBSZXNvbHZlcyBhbiBleHRlcm5hbCBwYXJzZWQgZW50aXR5LiBJZiB0aGUgZW50aXR5IGNhbm5vdCBiZQotICAgICAqIHJlc29sdmVkLCB0aGlzIG1ldGhvZCBzaG91bGQgcmV0dXJuIG51bGwuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcmVzb3VyY2VJZGVudGlmaWVyICAgICAgICBjb250YWlucyB0aGUgcGh5c2ljYWwgY28tb3JkaW5hdGVzIG9mIHRoZSByZXNvdXJjZSB0byBiZSByZXNvbHZlZAotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIG9uIGdlbmVyYWwgZXJyb3IuCi0gICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiAgVGhyb3duIGlmIHJlc29sdmVkIGVudGl0eSBzdHJlYW0gY2Fubm90IGJlCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgb3BlbmVkIG9yIHNvbWUgb3RoZXIgaS9vIGVycm9yIG9jY3Vycy4KLSAgICAgKi8KLSAgICBwdWJsaWMgWE1MSW5wdXRTb3VyY2UgcmVzb2x2ZUVudGl0eShYTUxSZXNvdXJjZUlkZW50aWZpZXIgcmVzb3VyY2VJZGVudGlmaWVyKQotICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy8gV2hlbiBib3RoIHB1YklkIGFuZCBzeXNJZCBhcmUgbnVsbCwgdGhlIHVzZXIncyBlbnRpdHkgcmVzb2x2ZXIKLSAgICAgICAgLy8gY2FuIGRvIG5vdGhpbmcgYWJvdXQgaXQuIFdlJ2QgYmV0dGVyIG5vdCBib3RoZXIgY2FsbGluZyBpdC4KLSAgICAgICAgLy8gVGhpcyBoYXBwZW5zIHdoZW4gdGhlIHJlc291cmNlSWRlbnRpZmllciBpcyBhIEdyYW1tYXJEZXNjcmlwdGlvbiwKLSAgICAgICAgLy8gd2hpY2ggZGVzY3JpYmVzIGEgc2NoZW1hIGdyYW1tYXIgb2Ygc29tZSBuYW1lc3BhY2UsIGJ1dCB3aXRob3V0Ci0gICAgICAgIC8vIGFueSBzY2hlbWEgbG9jYXRpb24gaGludC4gLVNnCi0gICAgICAgIFN0cmluZyBwdWJJZCA9IHJlc291cmNlSWRlbnRpZmllci5nZXRQdWJsaWNJZCgpOwotICAgICAgICBTdHJpbmcgc3lzSWQgPSByZXNvdXJjZUlkZW50aWZpZXIuZ2V0RXhwYW5kZWRTeXN0ZW1JZCgpOwotICAgICAgICBpZiAocHViSWQgPT0gbnVsbCAmJiBzeXNJZCA9PSBudWxsKQotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0KLSAgICAgICAgLy8gcmVzb2x2ZSBlbnRpdHkgdXNpbmcgU0FYIGVudGl0eSByZXNvbHZlcgotICAgICAgICBpZiAoZkVudGl0eVJlc29sdmVyICE9IG51bGwgJiYgcmVzb3VyY2VJZGVudGlmaWVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgSW5wdXRTb3VyY2UgaW5wdXRTb3VyY2UgPSBmRW50aXR5UmVzb2x2ZXIucmVzb2x2ZUVudGl0eShwdWJJZCwgc3lzSWQpOwotICAgICAgICAgICAgICAgIGlmIChpbnB1dFNvdXJjZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIFN0cmluZyBwdWJsaWNJZCA9IGlucHV0U291cmNlLmdldFB1YmxpY0lkKCk7Ci0gICAgICAgICAgICAgICAgICAgIFN0cmluZyBzeXN0ZW1JZCA9IGlucHV0U291cmNlLmdldFN5c3RlbUlkKCk7Ci0gICAgICAgICAgICAgICAgICAgIFN0cmluZyBiYXNlU3lzdGVtSWQgPSByZXNvdXJjZUlkZW50aWZpZXIuZ2V0QmFzZVN5c3RlbUlkKCk7Ci0gICAgICAgICAgICAgICAgICAgIElucHV0U3RyZWFtIGJ5dGVTdHJlYW0gPSBpbnB1dFNvdXJjZS5nZXRCeXRlU3RyZWFtKCk7Ci0gICAgICAgICAgICAgICAgICAgIFJlYWRlciBjaGFyU3RyZWFtID0gaW5wdXRTb3VyY2UuZ2V0Q2hhcmFjdGVyU3RyZWFtKCk7Ci0gICAgICAgICAgICAgICAgICAgIFN0cmluZyBlbmNvZGluZyA9IGlucHV0U291cmNlLmdldEVuY29kaW5nKCk7Ci0gICAgICAgICAgICAgICAgICAgIFhNTElucHV0U291cmNlIHhtbElucHV0U291cmNlID0KLSAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBYTUxJbnB1dFNvdXJjZShwdWJsaWNJZCwgc3lzdGVtSWQsIGJhc2VTeXN0ZW1JZCk7Ci0gICAgICAgICAgICAgICAgICAgIHhtbElucHV0U291cmNlLnNldEJ5dGVTdHJlYW0oYnl0ZVN0cmVhbSk7Ci0gICAgICAgICAgICAgICAgICAgIHhtbElucHV0U291cmNlLnNldENoYXJhY3RlclN0cmVhbShjaGFyU3RyZWFtKTsKLSAgICAgICAgICAgICAgICAgICAgeG1sSW5wdXRTb3VyY2Uuc2V0RW5jb2RpbmcoZW5jb2RpbmcpOwotICAgICAgICAgICAgICAgICAgICByZXR1cm4geG1sSW5wdXRTb3VyY2U7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBlcnJvciByZXNvbHZpbmcgZW50aXR5Ci0gICAgICAgICAgICBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICBFeGNlcHRpb24gZXggPSBlLmdldEV4Y2VwdGlvbigpOwotICAgICAgICAgICAgICAgIGlmIChleCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGV4ID0gZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFhOSUV4Y2VwdGlvbihleCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyB1bmFibGUgdG8gcmVzb2x2ZSBlbnRpdHkKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0KLSAgICB9IC8vIHJlc29sdmVFbnRpdHkoU3RyaW5nLFN0cmluZyxTdHJpbmcpOlhNTElucHV0U291cmNlCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL0Vycm9ySGFuZGxlclByb3h5LmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL0Vycm9ySGFuZGxlclByb3h5LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDhiM2FlOWIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9FcnJvckhhbmRsZXJQcm94eS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsODAgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTEVycm9ySGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5FcnJvckhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWFBhcnNlRXhjZXB0aW9uOwotCi0vKioKLSAqIFdyYXBzIHtAbGluayBYTUxFcnJvckhhbmRsZXJ9IGFuZCBtYWtlIGl0IGxvb2sgbGlrZSBhIFNBWCB7QGxpbmsgRXJyb3JIYW5kbGVyfS4KLSAqCi0gKiA8cD4KLSAqIFRoZSBkZXJpdmVkIGNsYXNzIHNob3VsZCBvdmVycmlkZSB0aGUge0BsaW5rICNnZXRFcnJvckhhbmRsZXIoKX0gbWV0aG9kCi0gKiBzbyB0aGF0IGl0IHdpbGwgcmV0dXJuIHRoZSBjb3JyZWN0IHtAbGluayBYTUxFcnJvckhhbmRsZXJ9IGluc3RhbmNlLgotICogVGhpcyBtZXRob2Qgd2lsbCBiZSBjYWxsZWQgd2hlbmV2ZXIgYW4gZXJyb3Ivd2FybmluZyBpcyBmb3VuZC4KLSAqCi0gKiA8cD4KLSAqIEV4cGVyaWVuY2Ugc2hvd3MgdGhhdCBpdCBpcyBiZXR0ZXIgdG8gc3RvcmUgdGhlIGFjdHVhbAotICoge0BsaW5rIFhNTEVycm9ySGFuZGxlcn0gaW4gb25lIHBsYWNlIGFuZCBsb29rcyB1cCB0aGF0IHZhcmlhYmxlLAotICogcmF0aGVyIHRoYW4gY29weWluZyBpdCBpbnRvIGV2ZXJ5IGNvbXBvbmVudCB0aGF0IG5lZWRzIGFuIGVycm9yIGhhbmRsZXIKLSAqIGFuZCB1cGRhdGUgYWxsIG9mIHRoZW0gd2hlbmV2ZXIgaXQgaXMgY2hhbmdlZCwgSU1PLgotICoKLSAqIEBhdXRob3IgS29oc3VrZSBLYXdhZ3VjaGkgKGtvaHN1a2Uua2F3YWd1Y2hpQHN1bi5jb20pCi0gKgotICovCi1wdWJsaWMgYWJzdHJhY3QgY2xhc3MgRXJyb3JIYW5kbGVyUHJveHkgaW1wbGVtZW50cyBFcnJvckhhbmRsZXIgewotCi0gICAgcHVibGljIHZvaWQgZXJyb3IoU0FYUGFyc2VFeGNlcHRpb24gZSkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0gICAgICAgIFhNTEVycm9ySGFuZGxlciBlaCA9IGdldEVycm9ySGFuZGxlcigpOwotICAgICAgICBpZiAoZWggaW5zdGFuY2VvZiBFcnJvckhhbmRsZXJXcmFwcGVyKSB7Ci0gICAgICAgICAgICAoKEVycm9ySGFuZGxlcldyYXBwZXIpZWgpLmZFcnJvckhhbmRsZXIuZXJyb3IoZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBlaC5lcnJvcigiIiwiIixFcnJvckhhbmRsZXJXcmFwcGVyLmNyZWF0ZVhNTFBhcnNlRXhjZXB0aW9uKGUpKTsKLSAgICAgICAgfQotICAgICAgICAvLyBpZiBhbiBYTklFeGNlcHRpb24gaXMgdGhyb3duLCBqdXN0IGxldCBpdCBnby4KLSAgICAgICAgLy8gUkVWSVNJVDogaXMgdGhpcyBPSz8gb3Igc2hvdWxkIHdlIHRyeSB0byB3cmFwIGl0IGludG8gU0FYRXhjZXB0aW9uPwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGZhdGFsRXJyb3IoU0FYUGFyc2VFeGNlcHRpb24gZSkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0gICAgICAgIFhNTEVycm9ySGFuZGxlciBlaCA9IGdldEVycm9ySGFuZGxlcigpOwotICAgICAgICBpZiAoZWggaW5zdGFuY2VvZiBFcnJvckhhbmRsZXJXcmFwcGVyKSB7Ci0gICAgICAgICAgICAoKEVycm9ySGFuZGxlcldyYXBwZXIpZWgpLmZFcnJvckhhbmRsZXIuZmF0YWxFcnJvcihlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIGVoLmZhdGFsRXJyb3IoIiIsIiIsRXJyb3JIYW5kbGVyV3JhcHBlci5jcmVhdGVYTUxQYXJzZUV4Y2VwdGlvbihlKSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCB3YXJuaW5nKFNBWFBhcnNlRXhjZXB0aW9uIGUpIHRocm93cyBTQVhFeGNlcHRpb24gewotICAgICAgICBYTUxFcnJvckhhbmRsZXIgZWggPSBnZXRFcnJvckhhbmRsZXIoKTsKLSAgICAgICAgaWYgKGVoIGluc3RhbmNlb2YgRXJyb3JIYW5kbGVyV3JhcHBlcikgewotICAgICAgICAgICAgKChFcnJvckhhbmRsZXJXcmFwcGVyKWVoKS5mRXJyb3JIYW5kbGVyLndhcm5pbmcoZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBlaC53YXJuaW5nKCIiLCIiLEVycm9ySGFuZGxlcldyYXBwZXIuY3JlYXRlWE1MUGFyc2VFeGNlcHRpb24oZSkpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHJvdGVjdGVkIGFic3RyYWN0IFhNTEVycm9ySGFuZGxlciBnZXRFcnJvckhhbmRsZXIoKTsKLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3V0aWwvRXJyb3JIYW5kbGVyV3JhcHBlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9FcnJvckhhbmRsZXJXcmFwcGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDI0NTVmZTMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9FcnJvckhhbmRsZXJXcmFwcGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMzIgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWw7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxMb2NhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhOSUV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MRXJyb3JIYW5kbGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxQYXJzZUV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5FcnJvckhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWFBhcnNlRXhjZXB0aW9uOwotCi0vKioKLSAqIFRoaXMgY2xhc3Mgd3JhcHMgYSBTQVggZXJyb3IgaGFuZGxlciBpbiBhbiBYTkkgZXJyb3IgaGFuZGxlci4KLSAqCi0gKiBAc2VlIEVycm9ySGFuZGxlcgotICoKLSAqIEBhdXRob3IgQW5keSBDbGFyaywgSUJNCi0gKgotICovCi1wdWJsaWMgY2xhc3MgRXJyb3JIYW5kbGVyV3JhcHBlcgotICAgIGltcGxlbWVudHMgWE1MRXJyb3JIYW5kbGVyIHsKLQotICAgIC8vCi0gICAgLy8gRGF0YQotICAgIC8vCi0KLSAgICAvKiogVGhlIFNBWCBlcnJvciBoYW5kbGVyLiAqLwotICAgIHByb3RlY3RlZCBFcnJvckhhbmRsZXIgZkVycm9ySGFuZGxlcjsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKiBEZWZhdWx0IGNvbnN0cnVjdG9yLiAqLwotICAgIHB1YmxpYyBFcnJvckhhbmRsZXJXcmFwcGVyKCkge30KLQotICAgIC8qKiBXcmFwcyB0aGUgc3BlY2lmaWVkIFNBWCBlcnJvciBoYW5kbGVyLiAqLwotICAgIHB1YmxpYyBFcnJvckhhbmRsZXJXcmFwcGVyKEVycm9ySGFuZGxlciBlcnJvckhhbmRsZXIpIHsKLSAgICAgICAgc2V0RXJyb3JIYW5kbGVyKGVycm9ySGFuZGxlcik7Ci0gICAgfSAvLyA8aW5pdD4oRXJyb3JIYW5kbGVyKQotCi0gICAgLy8KLSAgICAvLyBQdWJsaWMgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKiogU2V0cyB0aGUgU0FYIGVycm9yIGhhbmRsZXIuICovCi0gICAgcHVibGljIHZvaWQgc2V0RXJyb3JIYW5kbGVyKEVycm9ySGFuZGxlciBlcnJvckhhbmRsZXIpIHsKLSAgICAgICAgZkVycm9ySGFuZGxlciA9IGVycm9ySGFuZGxlcjsKLSAgICB9IC8vIHNldEVycm9ySGFuZGxlcihFcnJvckhhbmRsZXIpCi0KLSAgICAvKiogUmV0dXJucyB0aGUgU0FYIGVycm9yIGhhbmRsZXIuICovCi0gICAgcHVibGljIEVycm9ySGFuZGxlciBnZXRFcnJvckhhbmRsZXIoKSB7Ci0gICAgICAgIHJldHVybiBmRXJyb3JIYW5kbGVyOwotICAgIH0gLy8gZ2V0RXJyb3JIYW5kbGVyKCk6RXJyb3JIYW5kbGVyCi0KLSAgICAvLwotICAgIC8vIFhNTEVycm9ySGFuZGxlciBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFJlcG9ydHMgYSB3YXJuaW5nLiBXYXJuaW5ncyBhcmUgbm9uLWZhdGFsIGFuZCBjYW4gYmUgc2FmZWx5IGlnbm9yZWQKLSAgICAgKiBieSBtb3N0IGFwcGxpY2F0aW9ucy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBkb21haW4gICAgVGhlIGRvbWFpbiBvZiB0aGUgd2FybmluZy4gVGhlIGRvbWFpbiBjYW4gYmUgYW55Ci0gICAgICogICAgICAgICAgICAgICAgICBzdHJpbmcgYnV0IGlzIHN1Z2dlc3RlZCB0byBiZSBhIHZhbGlkIFVSSS4gVGhlCi0gICAgICogICAgICAgICAgICAgICAgICBkb21haW4gY2FuIGJlIHVzZWQgdG8gY29udmVuaWVudGx5IHNwZWNpZnkgYSB3ZWIKLSAgICAgKiAgICAgICAgICAgICAgICAgIHNpdGUgbG9jYXRpb24gb2YgdGhlIHJlbGV2ZW50IHNwZWNpZmljYXRpb24gb3IKLSAgICAgKiAgICAgICAgICAgICAgICAgIGRvY3VtZW50IHBlcnRhaW5pbmcgdG8gdGhpcyB3YXJuaW5nLgotICAgICAqIEBwYXJhbSBrZXkgICAgICAgVGhlIHdhcm5pbmcga2V5LiBUaGlzIGtleSBjYW4gYmUgYW55IHN0cmluZyBhbmQKLSAgICAgKiAgICAgICAgICAgICAgICAgIGlzIGltcGxlbWVudGF0aW9uIGRlcGVuZGVudC4KLSAgICAgKiBAcGFyYW0gZXhjZXB0aW9uIEV4Y2VwdGlvbi4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biB0byBzaWduYWwgdGhhdCB0aGUgcGFyc2VyIHNob3VsZCBzdG9wCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgcGFyc2luZyB0aGUgZG9jdW1lbnQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgd2FybmluZyhTdHJpbmcgZG9tYWluLCBTdHJpbmcga2V5LAotICAgICAgICAgICAgICAgICAgICAgICAgWE1MUGFyc2VFeGNlcHRpb24gZXhjZXB0aW9uKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLQotICAgICAgICBpZiAoZkVycm9ySGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgU0FYUGFyc2VFeGNlcHRpb24gc2F4RXhjZXB0aW9uID0gY3JlYXRlU0FYUGFyc2VFeGNlcHRpb24oZXhjZXB0aW9uKTsKLQotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmRXJyb3JIYW5kbGVyLndhcm5pbmcoc2F4RXhjZXB0aW9uKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgY2F0Y2ggKFNBWFBhcnNlRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZVhNTFBhcnNlRXhjZXB0aW9uKGUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZVhOSUV4Y2VwdGlvbihlKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgIH0gLy8gd2FybmluZyhTdHJpbmcsU3RyaW5nLFhNTFBhcnNlRXhjZXB0aW9uKQotCi0gICAgLyoqCi0gICAgICogUmVwb3J0cyBhbiBlcnJvci4gRXJyb3JzIGFyZSBub24tZmF0YWwgYW5kIHVzdWFsbHkgc2lnbmlmeSB0aGF0IHRoZQotICAgICAqIGRvY3VtZW50IGlzIGludmFsaWQgd2l0aCByZXNwZWN0IHRvIGl0cyBncmFtbWFyKHMpLgotICAgICAqCi0gICAgICogQHBhcmFtIGRvbWFpbiAgICBUaGUgZG9tYWluIG9mIHRoZSBlcnJvci4gVGhlIGRvbWFpbiBjYW4gYmUgYW55Ci0gICAgICogICAgICAgICAgICAgICAgICBzdHJpbmcgYnV0IGlzIHN1Z2dlc3RlZCB0byBiZSBhIHZhbGlkIFVSSS4gVGhlCi0gICAgICogICAgICAgICAgICAgICAgICBkb21haW4gY2FuIGJlIHVzZWQgdG8gY29udmVuaWVudGx5IHNwZWNpZnkgYSB3ZWIKLSAgICAgKiAgICAgICAgICAgICAgICAgIHNpdGUgbG9jYXRpb24gb2YgdGhlIHJlbGV2ZW50IHNwZWNpZmljYXRpb24gb3IKLSAgICAgKiAgICAgICAgICAgICAgICAgIGRvY3VtZW50IHBlcnRhaW5pbmcgdG8gdGhpcyBlcnJvci4KLSAgICAgKiBAcGFyYW0ga2V5ICAgICAgIFRoZSBlcnJvciBrZXkuIFRoaXMga2V5IGNhbiBiZSBhbnkgc3RyaW5nIGFuZAotICAgICAqICAgICAgICAgICAgICAgICAgaXMgaW1wbGVtZW50YXRpb24gZGVwZW5kZW50LgotICAgICAqIEBwYXJhbSBleGNlcHRpb24gRXhjZXB0aW9uLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIHRvIHNpZ25hbCB0aGF0IHRoZSBwYXJzZXIgc2hvdWxkIHN0b3AKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBwYXJzaW5nIHRoZSBkb2N1bWVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlcnJvcihTdHJpbmcgZG9tYWluLCBTdHJpbmcga2V5LAotICAgICAgICAgICAgICAgICAgICAgIFhNTFBhcnNlRXhjZXB0aW9uIGV4Y2VwdGlvbikgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgaWYgKGZFcnJvckhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIFNBWFBhcnNlRXhjZXB0aW9uIHNheEV4Y2VwdGlvbiA9IGNyZWF0ZVNBWFBhcnNlRXhjZXB0aW9uKGV4Y2VwdGlvbik7Ci0KLSAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICAgICAgZkVycm9ySGFuZGxlci5lcnJvcihzYXhFeGNlcHRpb24pOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBjYXRjaCAoU0FYUGFyc2VFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlWE1MUGFyc2VFeGNlcHRpb24oZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGNhdGNoIChTQVhFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlWE5JRXhjZXB0aW9uKGUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgfSAvLyBlcnJvcihTdHJpbmcsU3RyaW5nLFhNTFBhcnNlRXhjZXB0aW9uKQotCi0gICAgLyoqCi0gICAgICogUmVwb3J0IGEgZmF0YWwgZXJyb3IuIEZhdGFsIGVycm9ycyB1c3VhbGx5IG9jY3VyIHdoZW4gdGhlIGRvY3VtZW50Ci0gICAgICogaXMgbm90IHdlbGwtZm9ybWVkIGFuZCBzaWduaWZpZXMgdGhhdCB0aGUgcGFyc2VyIGNhbm5vdCBjb250aW51ZQotICAgICAqIG5vcm1hbCBvcGVyYXRpb24uCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGUgZXJyb3IgaGFuZGxlciBzaG91bGQgPGVtPmFsd2F5czwvZW0+Ci0gICAgICogdGhyb3cgYW4gPGNvZGU+WE5JRXhjZXB0aW9uPC9jb2RlPiBmcm9tIHRoaXMgbWV0aG9kLiBUaGlzIGV4Y2VwdGlvbgotICAgICAqIGNhbiBlaXRoZXIgYmUgdGhlIHNhbWUgZXhjZXB0aW9uIHRoYXQgaXMgcGFzc2VkIGFzIGEgcGFyYW1ldGVyIHRvCi0gICAgICogdGhlIG1ldGhvZCBvciBhIG5ldyBYTkkgZXhjZXB0aW9uIG9iamVjdC4gSWYgdGhlIHJlZ2lzdGVyZWQgZXJyb3IKLSAgICAgKiBoYW5kbGVyIGZhaWxzIHRvIHRocm93IGFuIGV4Y2VwdGlvbiwgdGhlIGNvbnRpbnVpbmcgb3BlcmF0aW9uIG9mCi0gICAgICogdGhlIHBhcnNlciBpcyB1bmRldGVybWluZWQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZG9tYWluICAgIFRoZSBkb21haW4gb2YgdGhlIGZhdGFsIGVycm9yLiBUaGUgZG9tYWluIGNhbiBiZQotICAgICAqICAgICAgICAgICAgICAgICAgYW55IHN0cmluZyBidXQgaXMgc3VnZ2VzdGVkIHRvIGJlIGEgdmFsaWQgVVJJLiBUaGUKLSAgICAgKiAgICAgICAgICAgICAgICAgIGRvbWFpbiBjYW4gYmUgdXNlZCB0byBjb252ZW5pZW50bHkgc3BlY2lmeSBhIHdlYgotICAgICAqICAgICAgICAgICAgICAgICAgc2l0ZSBsb2NhdGlvbiBvZiB0aGUgcmVsZXZlbnQgc3BlY2lmaWNhdGlvbiBvcgotICAgICAqICAgICAgICAgICAgICAgICAgZG9jdW1lbnQgcGVydGFpbmluZyB0byB0aGlzIGZhdGFsIGVycm9yLgotICAgICAqIEBwYXJhbSBrZXkgICAgICAgVGhlIGZhdGFsIGVycm9yIGtleS4gVGhpcyBrZXkgY2FuIGJlIGFueSBzdHJpbmcKLSAgICAgKiAgICAgICAgICAgICAgICAgIGFuZCBpcyBpbXBsZW1lbnRhdGlvbiBkZXBlbmRlbnQuCi0gICAgICogQHBhcmFtIGV4Y2VwdGlvbiBFeGNlcHRpb24uCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gdG8gc2lnbmFsIHRoYXQgdGhlIHBhcnNlciBzaG91bGQgc3RvcAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIHBhcnNpbmcgdGhlIGRvY3VtZW50LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGZhdGFsRXJyb3IoU3RyaW5nIGRvbWFpbiwgU3RyaW5nIGtleSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTFBhcnNlRXhjZXB0aW9uIGV4Y2VwdGlvbikgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgaWYgKGZFcnJvckhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIFNBWFBhcnNlRXhjZXB0aW9uIHNheEV4Y2VwdGlvbiA9IGNyZWF0ZVNBWFBhcnNlRXhjZXB0aW9uKGV4Y2VwdGlvbik7Ci0KLSAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICAgICAgZkVycm9ySGFuZGxlci5mYXRhbEVycm9yKHNheEV4Y2VwdGlvbik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGNhdGNoIChTQVhQYXJzZUV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVYTUxQYXJzZUV4Y2VwdGlvbihlKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVYTklFeGNlcHRpb24oZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICB9IC8vIGZhdGFsRXJyb3IoU3RyaW5nLFN0cmluZyxYTUxQYXJzZUV4Y2VwdGlvbikKLQotICAgIC8vCi0gICAgLy8gUHJvdGVjdGVkIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqIENyZWF0ZXMgYSBTQVhQYXJzZUV4Y2VwdGlvbiBmcm9tIGFuIFhNTFBhcnNlRXhjZXB0aW9uLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgU0FYUGFyc2VFeGNlcHRpb24gY3JlYXRlU0FYUGFyc2VFeGNlcHRpb24oWE1MUGFyc2VFeGNlcHRpb24gZXhjZXB0aW9uKSB7Ci0gICAgICAgIHJldHVybiBuZXcgU0FYUGFyc2VFeGNlcHRpb24oZXhjZXB0aW9uLmdldE1lc3NhZ2UoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleGNlcHRpb24uZ2V0UHVibGljSWQoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleGNlcHRpb24uZ2V0RXhwYW5kZWRTeXN0ZW1JZCgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4Y2VwdGlvbi5nZXRMaW5lTnVtYmVyKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhjZXB0aW9uLmdldENvbHVtbk51bWJlcigpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4Y2VwdGlvbi5nZXRFeGNlcHRpb24oKSk7Ci0gICAgfSAvLyBjcmVhdGVTQVhQYXJzZUV4Y2VwdGlvbihYTUxQYXJzZUV4Y2VwdGlvbik6U0FYUGFyc2VFeGNlcHRpb24KLQotICAgIC8qKiBDcmVhdGVzIGFuIFhNTFBhcnNlRXhjZXB0aW9uIGZyb20gYSBTQVhQYXJzZUV4Y2VwdGlvbi4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIFhNTFBhcnNlRXhjZXB0aW9uIGNyZWF0ZVhNTFBhcnNlRXhjZXB0aW9uKFNBWFBhcnNlRXhjZXB0aW9uIGV4Y2VwdGlvbikgewotICAgICAgICBmaW5hbCBTdHJpbmcgZlB1YmxpY0lkID0gZXhjZXB0aW9uLmdldFB1YmxpY0lkKCk7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBmRXhwYW5kZWRTeXN0ZW1JZCA9IGV4Y2VwdGlvbi5nZXRTeXN0ZW1JZCgpOwotICAgICAgICBmaW5hbCBpbnQgZkxpbmVOdW1iZXIgPSBleGNlcHRpb24uZ2V0TGluZU51bWJlcigpOwotICAgICAgICBmaW5hbCBpbnQgZkNvbHVtbk51bWJlciA9IGV4Y2VwdGlvbi5nZXRDb2x1bW5OdW1iZXIoKTsKLSAgICAgICAgWE1MTG9jYXRvciBsb2NhdGlvbiA9IG5ldyBYTUxMb2NhdG9yKCkgewotICAgICAgICAgICAgcHVibGljIFN0cmluZyBnZXRQdWJsaWNJZCgpIHsgcmV0dXJuIGZQdWJsaWNJZDsgfQotICAgICAgICAgICAgcHVibGljIFN0cmluZyBnZXRFeHBhbmRlZFN5c3RlbUlkKCkgeyByZXR1cm4gZkV4cGFuZGVkU3lzdGVtSWQ7IH0KLSAgICAgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0QmFzZVN5c3RlbUlkKCkgeyByZXR1cm4gbnVsbDsgfQotICAgICAgICAgICAgcHVibGljIFN0cmluZyBnZXRMaXRlcmFsU3lzdGVtSWQoKSB7IHJldHVybiBudWxsOyB9Ci0gICAgICAgICAgICBwdWJsaWMgaW50IGdldENvbHVtbk51bWJlcigpIHsgcmV0dXJuIGZDb2x1bW5OdW1iZXI7IH0KLSAgICAgICAgICAgIHB1YmxpYyBpbnQgZ2V0TGluZU51bWJlcigpIHsgcmV0dXJuIGZMaW5lTnVtYmVyOyB9Ci0gICAgICAgICAgICBwdWJsaWMgaW50IGdldENoYXJhY3Rlck9mZnNldCgpIHsgcmV0dXJuIC0xOyB9Ci0gICAgICAgICAgICBwdWJsaWMgU3RyaW5nIGdldEVuY29kaW5nKCkgeyByZXR1cm4gbnVsbDsgfQotICAgICAgICAgICAgcHVibGljIFN0cmluZyBnZXRYTUxWZXJzaW9uKCkgeyByZXR1cm4gbnVsbDsgfQotICAgICAgICB9OwotICAgICAgICByZXR1cm4gbmV3IFhNTFBhcnNlRXhjZXB0aW9uKGxvY2F0aW9uLCBleGNlcHRpb24uZ2V0TWVzc2FnZSgpLGV4Y2VwdGlvbik7Ci0gICAgfSAvLyBjcmVhdGVYTUxQYXJzZUV4Y2VwdGlvbihTQVhQYXJzZUV4Y2VwdGlvbik6WE1MUGFyc2VFeGNlcHRpb24KLQotICAgIC8qKiBDcmVhdGVzIGFuIFhOSUV4Y2VwdGlvbiBmcm9tIGEgU0FYRXhjZXB0aW9uLgotICAgICAgICBOT1RFOiAgY2FyZSBzaG91bGQgYmUgdGFrZW4gKm5vdCogdG8gY2FsbCB0aGlzIHdpdGggYSBTQVhQYXJzZUV4Y2VwdGlvbjsgdGhpcyB3aWxsCi0gICAgICAgIGxvc2UgaW5mb3JtYXRpb24hISEgKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIFhOSUV4Y2VwdGlvbiBjcmVhdGVYTklFeGNlcHRpb24oU0FYRXhjZXB0aW9uIGV4Y2VwdGlvbikgewotICAgICAgICByZXR1cm4gbmV3IFhOSUV4Y2VwdGlvbihleGNlcHRpb24uZ2V0TWVzc2FnZSgpLGV4Y2VwdGlvbik7Ci0gICAgfSAvLyBjcmVhdGVYTklFeGNlcHRpb24oU0FYRXhjZXB0aW9uKTpYTUxQYXJzZUV4Y2VwdGlvbgotfSAvLyBjbGFzcyBFcnJvckhhbmRsZXJXcmFwcGVyCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL0ZlYXR1cmVTdGF0ZS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9GZWF0dXJlU3RhdGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZTc4YjMwYy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL0ZlYXR1cmVTdGF0ZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNjQgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwOSBieSBPcmFjbGUgQ29ycG9yYXRpb24uIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCi0gKi8KLQotLyoKLSAqICRJZDogRmVhdHVyZVN0YXRlLmphdmEgMzAyNCAyMDExLTAzLTAxIDAzOjQ2OjEzWiBqb2VodyAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWw7Ci0KLXB1YmxpYyBjbGFzcyBGZWF0dXJlU3RhdGUgewotCi0gICAgcHVibGljIGZpbmFsIFN0YXR1cyBzdGF0dXM7Ci0gICAgcHVibGljIGZpbmFsIGJvb2xlYW4gc3RhdGU7Ci0KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEZlYXR1cmVTdGF0ZSBTRVRfRU5BQkxFRCA9IG5ldyBGZWF0dXJlU3RhdGUoU3RhdHVzLlNFVCwgdHJ1ZSk7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBGZWF0dXJlU3RhdGUgU0VUX0RJU0FCTEVEID0gbmV3IEZlYXR1cmVTdGF0ZShTdGF0dXMuU0VULCBmYWxzZSk7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBGZWF0dXJlU3RhdGUgVU5LTk9XTiA9IG5ldyBGZWF0dXJlU3RhdGUoU3RhdHVzLlVOS05PV04sIGZhbHNlKTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEZlYXR1cmVTdGF0ZSBSRUNPR05JWkVEID0gbmV3IEZlYXR1cmVTdGF0ZShTdGF0dXMuUkVDT0dOSVpFRCwgZmFsc2UpOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgRmVhdHVyZVN0YXRlIE5PVF9TVVBQT1JURUQgPSBuZXcgRmVhdHVyZVN0YXRlKFN0YXR1cy5OT1RfU1VQUE9SVEVELCBmYWxzZSk7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBGZWF0dXJlU3RhdGUgTk9UX1JFQ09HTklaRUQgPSBuZXcgRmVhdHVyZVN0YXRlKFN0YXR1cy5OT1RfUkVDT0dOSVpFRCwgZmFsc2UpOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgRmVhdHVyZVN0YXRlIE5PVF9BTExPV0VEID0gbmV3IEZlYXR1cmVTdGF0ZShTdGF0dXMuTk9UX0FMTE9XRUQsIGZhbHNlKTsKLQotICAgIHB1YmxpYyBGZWF0dXJlU3RhdGUoU3RhdHVzIHN0YXR1cywgYm9vbGVhbiBzdGF0ZSkgewotICAgICAgICB0aGlzLnN0YXR1cyA9IHN0YXR1czsKLSAgICAgICAgdGhpcy5zdGF0ZSA9IHN0YXRlOwotICAgIH0KLQotICAgIHB1YmxpYyBzdGF0aWMgRmVhdHVyZVN0YXRlIG9mKFN0YXR1cyBzdGF0dXMpIHsKLSAgICAgICAgcmV0dXJuIG5ldyBGZWF0dXJlU3RhdGUoc3RhdHVzLCBmYWxzZSk7Ci0gICAgfQotCi0gICAgcHVibGljIHN0YXRpYyBGZWF0dXJlU3RhdGUgaXMoYm9vbGVhbiB2YWx1ZSkgewotICAgICAgICByZXR1cm4gbmV3IEZlYXR1cmVTdGF0ZShTdGF0dXMuU0VULCB2YWx1ZSk7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gaXNFeGNlcHRpb25hbCgpIHsKLSAgICAgICAgcmV0dXJuIHRoaXMuc3RhdHVzLmlzRXhjZXB0aW9uYWwoKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL0hUVFBJbnB1dFNvdXJjZS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9IVFRQSW5wdXRTb3VyY2UuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYzliYmVkOS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL0hUVFBJbnB1dFNvdXJjZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTk1ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDcsIDIwMTYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKi8KLQotLyoKLSAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQotICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCi0gKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCi0gKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAotICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKLSAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MUmVzb3VyY2VJZGVudGlmaWVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxJbnB1dFNvdXJjZTsKLWltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uUmVhZGVyOwotaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwotaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKLWltcG9ydCBqYXZhLnV0aWwuTWFwOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgcmVwcmVzZW50cyBhbiBpbnB1dCBzb3VyY2UgZm9yIGFuIFhNTCByZXNvdXJjZQotICogcmV0cmlldmFibGUgb3ZlciBIVFRQLiBJbiBhZGRpdGlvbiB0byB0aGUgcHJvcGVydGllcwotICogcHJvdmlkZWQgYnkgYW4gPGNvZGU+WE1MSW5wdXRTb3VyY2U8L2NvZGU+IGFuIEhUVFAgaW5wdXQKLSAqIHNvdXJjZSBhbHNvIGhhcyBIVFRQIHJlcXVlc3QgcHJvcGVydGllcyBhbmQgYSBwcmVmZXJlbmNlCi0gKiB3aGV0aGVyIEhUVFAgcmVkaXJlY3RzIHdpbGwgYmUgZm9sbG93ZWQuIE5vdGUgdGhhdCB0aGVzZQotICogcHJvcGVydGllcyB3aWxsIG9ubHkgYmUgdXNlZCBpZiByZWFkaW5nIHRoaXMgaW5wdXQgc291cmNlCi0gKiB3aWxsIGluZHVjZSBhbiBIVFRQIGNvbm5lY3Rpb24uCi0gKgotICogQGF1dGhvciBNaWNoYWVsIEdsYXZhc3NldmljaCwgSUJNCi0gKgotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgSFRUUElucHV0U291cmNlIGV4dGVuZHMgWE1MSW5wdXRTb3VyY2UgewotCi0gICAgLy8KLSAgICAvLyBEYXRhCi0gICAgLy8KLQotICAgIC8qKiBQcmVmZXJlbmNlIGZvciB3aGV0aGVyIEhUVFAgcmVkaXJlY3RzIHNob3VsZCBiZSBmb2xsb3dlZC4gKiovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZkZvbGxvd1JlZGlyZWN0cyA9IHRydWU7Ci0KLSAgICAvKiogSFRUUCByZXF1ZXN0IHByb3BlcnRpZXMuICoqLwotICAgIHByb3RlY3RlZCBNYXA8U3RyaW5nLCBTdHJpbmc+IGZIVFRQUmVxdWVzdFByb3BlcnRpZXMgPSBuZXcgSGFzaE1hcDw+KCk7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0cnVjdG9ycwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RzIGFuIGlucHV0IHNvdXJjZSBmcm9tIGp1c3QgdGhlIHB1YmxpYyBhbmQgc3lzdGVtCi0gICAgICogaWRlbnRpZmllcnMsIGxlYXZpbmcgcmVzb2x1dGlvbiBvZiB0aGUgZW50aXR5IGFuZCBvcGVuaW5nIG9mCi0gICAgICogdGhlIGlucHV0IHN0cmVhbSB1cCB0byB0aGUgY2FsbGVyLgotICAgICAqCi0gICAgICogQHBhcmFtIHB1YmxpY0lkICAgICBUaGUgcHVibGljIGlkZW50aWZpZXIsIGlmIGtub3duLgotICAgICAqIEBwYXJhbSBzeXN0ZW1JZCAgICAgVGhlIHN5c3RlbSBpZGVudGlmaWVyLiBUaGlzIHZhbHVlIHNob3VsZAotICAgICAqICAgICAgICAgICAgICAgICAgICAgYWx3YXlzIGJlIHNldCwgaWYgcG9zc2libGUsIGFuZCBjYW4gYmUKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgIHJlbGF0aXZlIG9yIGFic29sdXRlLiBJZiB0aGUgc3lzdGVtIGlkZW50aWZpZXIKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgIGlzIHJlbGF0aXZlLCB0aGVuIHRoZSBiYXNlIHN5c3RlbSBpZGVudGlmaWVyCi0gICAgICogICAgICAgICAgICAgICAgICAgICBzaG91bGQgYmUgc2V0LgotICAgICAqIEBwYXJhbSBiYXNlU3lzdGVtSWQgVGhlIGJhc2Ugc3lzdGVtIGlkZW50aWZpZXIuIFRoaXMgdmFsdWUgc2hvdWxkCi0gICAgICogICAgICAgICAgICAgICAgICAgICBhbHdheXMgYmUgc2V0IHRvIHRoZSBmdWxseSBleHBhbmRlZCBVUkkgb2YgdGhlCi0gICAgICogICAgICAgICAgICAgICAgICAgICBiYXNlIHN5c3RlbSBpZGVudGlmaWVyLCBpZiBwb3NzaWJsZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgSFRUUElucHV0U291cmNlKFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkLCBTdHJpbmcgYmFzZVN5c3RlbUlkKSB7Ci0gICAgICAgIHN1cGVyKHB1YmxpY0lkLCBzeXN0ZW1JZCwgYmFzZVN5c3RlbUlkKTsKLSAgICB9IC8vIDxpbml0PihTdHJpbmcsU3RyaW5nLFN0cmluZykKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHMgYW4gaW5wdXQgc291cmNlIGZyb20gYSBYTUxSZXNvdXJjZUlkZW50aWZpZXIKLSAgICAgKiBvYmplY3QsIGxlYXZpbmcgcmVzb2x1dGlvbiBvZiB0aGUgZW50aXR5IGFuZCBvcGVuaW5nIG9mCi0gICAgICogdGhlIGlucHV0IHN0cmVhbSB1cCB0byB0aGUgY2FsbGVyLgotICAgICAqCi0gICAgICogQHBhcmFtIHJlc291cmNlSWRlbnRpZmllciB0aGUgWE1MUmVzb3VyY2VJZGVudGlmaWVyIGNvbnRhaW5pbmcgdGhlIGluZm9ybWF0aW9uCi0gICAgICovCi0gICAgcHVibGljIEhUVFBJbnB1dFNvdXJjZShYTUxSZXNvdXJjZUlkZW50aWZpZXIgcmVzb3VyY2VJZGVudGlmaWVyKSB7Ci0gICAgICAgIHN1cGVyKHJlc291cmNlSWRlbnRpZmllcik7Ci0gICAgfSAvLyA8aW5pdD4oWE1MUmVzb3VyY2VJZGVudGlmaWVyKQotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0cyBhbiBpbnB1dCBzb3VyY2UgZnJvbSBhIGJ5dGUgc3RyZWFtLgotICAgICAqCi0gICAgICogQHBhcmFtIHB1YmxpY0lkICAgICBUaGUgcHVibGljIGlkZW50aWZpZXIsIGlmIGtub3duLgotICAgICAqIEBwYXJhbSBzeXN0ZW1JZCAgICAgVGhlIHN5c3RlbSBpZGVudGlmaWVyLiBUaGlzIHZhbHVlIHNob3VsZAotICAgICAqICAgICAgICAgICAgICAgICAgICAgYWx3YXlzIGJlIHNldCwgaWYgcG9zc2libGUsIGFuZCBjYW4gYmUKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgIHJlbGF0aXZlIG9yIGFic29sdXRlLiBJZiB0aGUgc3lzdGVtIGlkZW50aWZpZXIKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgIGlzIHJlbGF0aXZlLCB0aGVuIHRoZSBiYXNlIHN5c3RlbSBpZGVudGlmaWVyCi0gICAgICogICAgICAgICAgICAgICAgICAgICBzaG91bGQgYmUgc2V0LgotICAgICAqIEBwYXJhbSBiYXNlU3lzdGVtSWQgVGhlIGJhc2Ugc3lzdGVtIGlkZW50aWZpZXIuIFRoaXMgdmFsdWUgc2hvdWxkCi0gICAgICogICAgICAgICAgICAgICAgICAgICBhbHdheXMgYmUgc2V0IHRvIHRoZSBmdWxseSBleHBhbmRlZCBVUkkgb2YgdGhlCi0gICAgICogICAgICAgICAgICAgICAgICAgICBiYXNlIHN5c3RlbSBpZGVudGlmaWVyLCBpZiBwb3NzaWJsZS4KLSAgICAgKiBAcGFyYW0gYnl0ZVN0cmVhbSAgIFRoZSBieXRlIHN0cmVhbS4KLSAgICAgKiBAcGFyYW0gZW5jb2RpbmcgICAgIFRoZSBlbmNvZGluZyBvZiB0aGUgYnl0ZSBzdHJlYW0sIGlmIGtub3duLgotICAgICAqLwotICAgIHB1YmxpYyBIVFRQSW5wdXRTb3VyY2UoU3RyaW5nIHB1YmxpY0lkLCBTdHJpbmcgc3lzdGVtSWQsCi0gICAgICAgICAgICBTdHJpbmcgYmFzZVN5c3RlbUlkLCBJbnB1dFN0cmVhbSBieXRlU3RyZWFtLCBTdHJpbmcgZW5jb2RpbmcpIHsKLSAgICAgICAgc3VwZXIocHVibGljSWQsIHN5c3RlbUlkLCBiYXNlU3lzdGVtSWQsIGJ5dGVTdHJlYW0sIGVuY29kaW5nKTsKLSAgICB9IC8vIDxpbml0PihTdHJpbmcsU3RyaW5nLFN0cmluZyxJbnB1dFN0cmVhbSxTdHJpbmcpCi0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RzIGFuIGlucHV0IHNvdXJjZSBmcm9tIGEgY2hhcmFjdGVyIHN0cmVhbS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBwdWJsaWNJZCAgICAgVGhlIHB1YmxpYyBpZGVudGlmaWVyLCBpZiBrbm93bi4KLSAgICAgKiBAcGFyYW0gc3lzdGVtSWQgICAgIFRoZSBzeXN0ZW0gaWRlbnRpZmllci4gVGhpcyB2YWx1ZSBzaG91bGQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgIGFsd2F5cyBiZSBzZXQsIGlmIHBvc3NpYmxlLCBhbmQgY2FuIGJlCi0gICAgICogICAgICAgICAgICAgICAgICAgICByZWxhdGl2ZSBvciBhYnNvbHV0ZS4gSWYgdGhlIHN5c3RlbSBpZGVudGlmaWVyCi0gICAgICogICAgICAgICAgICAgICAgICAgICBpcyByZWxhdGl2ZSwgdGhlbiB0aGUgYmFzZSBzeXN0ZW0gaWRlbnRpZmllcgotICAgICAqICAgICAgICAgICAgICAgICAgICAgc2hvdWxkIGJlIHNldC4KLSAgICAgKiBAcGFyYW0gYmFzZVN5c3RlbUlkIFRoZSBiYXNlIHN5c3RlbSBpZGVudGlmaWVyLiBUaGlzIHZhbHVlIHNob3VsZAotICAgICAqICAgICAgICAgICAgICAgICAgICAgYWx3YXlzIGJlIHNldCB0byB0aGUgZnVsbHkgZXhwYW5kZWQgVVJJIG9mIHRoZQotICAgICAqICAgICAgICAgICAgICAgICAgICAgYmFzZSBzeXN0ZW0gaWRlbnRpZmllciwgaWYgcG9zc2libGUuCi0gICAgICogQHBhcmFtIGNoYXJTdHJlYW0gICBUaGUgY2hhcmFjdGVyIHN0cmVhbS4KLSAgICAgKiBAcGFyYW0gZW5jb2RpbmcgICAgIFRoZSBvcmlnaW5hbCBlbmNvZGluZyBvZiB0aGUgYnl0ZSBzdHJlYW0KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgIHVzZWQgYnkgdGhlIHJlYWRlciwgaWYga25vd24uCi0gICAgICovCi0gICAgcHVibGljIEhUVFBJbnB1dFNvdXJjZShTdHJpbmcgcHVibGljSWQsIFN0cmluZyBzeXN0ZW1JZCwKLSAgICAgICAgICAgIFN0cmluZyBiYXNlU3lzdGVtSWQsIFJlYWRlciBjaGFyU3RyZWFtLCBTdHJpbmcgZW5jb2RpbmcpIHsKLSAgICAgICAgc3VwZXIocHVibGljSWQsIHN5c3RlbUlkLCBiYXNlU3lzdGVtSWQsIGNoYXJTdHJlYW0sIGVuY29kaW5nKTsKLSAgICB9IC8vIDxpbml0PihTdHJpbmcsU3RyaW5nLFN0cmluZyxSZWFkZXIsU3RyaW5nKQotCi0gICAgLy8KLSAgICAvLyBQdWJsaWMgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBwcmVmZXJlbmNlIHdoZXRoZXIgSFRUUCByZWRpcmVjdHMgc2hvdWxkCi0gICAgICogYmUgZm9sbG93ZWQuIEJ5IGRlZmF1bHQgSFRUUCByZWRpcmVjdHMgd2lsbCBiZSBmb2xsb3dlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXRGb2xsb3dIVFRQUmVkaXJlY3RzKCkgewotICAgICAgICByZXR1cm4gZkZvbGxvd1JlZGlyZWN0czsKLSAgICB9IC8vIGdldEZvbGxvd0hUVFBSZWRpcmVjdHMoKTpib29sZWFuCi0KLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIHByZWZlcmVuY2Ugd2hldGhlciBIVFRQIHJlZGlyZWN0cyBzaG91bGQKLSAgICAgKiBiZSBmb2xsb3dlZC4gQnkgZGVmYXVsdCBIVFRQIHJlZGlyZWN0cyB3aWxsIGJlIGZvbGxvd2VkLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEZvbGxvd0hUVFBSZWRpcmVjdHMoYm9vbGVhbiBmb2xsb3dSZWRpcmVjdHMpIHsKLSAgICAgICAgZkZvbGxvd1JlZGlyZWN0cyA9IGZvbGxvd1JlZGlyZWN0czsKLSAgICB9IC8vIHNldEZvbGxvd0hUVFBSZWRpcmVjdHMoYm9vbGVhbikKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIHRoZSByZXF1ZXN0IHByb3BlcnR5Ci0gICAgICogYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBwcm9wZXJ0eSBuYW1lLgotICAgICAqCi0gICAgICogQHBhcmFtIGtleSB0aGUgbmFtZSBvZiB0aGUgcmVxdWVzdCBwcm9wZXJ0eQotICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSByZXF1ZXN0IHByb3BlcnR5IG9yCi0gICAgICogPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhpcyBwcm9wZXJ0eSBoYXMgbm90Ci0gICAgICogYmVlbiBzZXQKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEhUVFBSZXF1ZXN0UHJvcGVydHkoU3RyaW5nIGtleSkgewotICAgICAgICByZXR1cm4gZkhUVFBSZXF1ZXN0UHJvcGVydGllcy5nZXQoa2V5KTsKLSAgICB9IC8vIGdldEhUVFBSZXF1ZXN0UHJvcGVydHkoU3RyaW5nKTpTdHJpbmcKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYW4gaXRlcmF0b3IgZm9yIHRoZSByZXF1ZXN0IHByb3BlcnRpZXMgdGhpcwotICAgICAqIGlucHV0IHNvdXJjZSBjb250YWlucy4gRWFjaCBvYmplY3QgcmV0dXJuZWQgYnkgdGhlCi0gICAgICogaXRlcmF0b3IgaXMgYW4gaW5zdGFuY2Ugb2YgPGNvZGU+amF2YS51dGlsLk1hcC5FbnRyeTwvY29kZT4KLSAgICAgKiB3aGVyZSBlYWNoIGtleSBhbmQgdmFsdWUgYXJlIGEgcGFpciBvZiBzdHJpbmdzIGNvcnJlc3BvbmRpbmcKLSAgICAgKiB0byB0aGUgbmFtZSBhbmQgdmFsdWUgb2YgYSByZXF1ZXN0IHByb3BlcnR5LgotICAgICAqCi0gICAgICogQHJldHVybiBhbiBpdGVyYXRvciBmb3IgdGhlIHJlcXVlc3QgcHJvcGVydGllcyB0aGlzCi0gICAgICogaW5wdXQgc291cmNlIGNvbnRhaW5zCi0gICAgICovCi0gICAgcHVibGljIEl0ZXJhdG9yPE1hcC5FbnRyeTxTdHJpbmcsIFN0cmluZz4+IGdldEhUVFBSZXF1ZXN0UHJvcGVydGllcygpIHsKLSAgICAgICAgcmV0dXJuIGZIVFRQUmVxdWVzdFByb3BlcnRpZXMuZW50cnlTZXQoKS5pdGVyYXRvcigpOwotICAgIH0gLy8gZ2V0SFRUUFJlcXVlc3RQcm9wZXJ0aWVzKCk6SXRlcmF0b3IKLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIHRoZSByZXF1ZXN0IHByb3BlcnR5Ci0gICAgICogYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBwcm9wZXJ0eSBuYW1lLgotICAgICAqCi0gICAgICogQHBhcmFtIGtleSB0aGUgbmFtZSBvZiB0aGUgcmVxdWVzdCBwcm9wZXJ0eQotICAgICAqIEBwYXJhbSB2YWx1ZSB0aGUgdmFsdWUgb2YgdGhlIHJlcXVlc3QgcHJvcGVydHkKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRIVFRQUmVxdWVzdFByb3BlcnR5KFN0cmluZyBrZXksIFN0cmluZyB2YWx1ZSkgewotICAgICAgICBpZiAodmFsdWUgIT0gbnVsbCkgewotICAgICAgICAgICAgZkhUVFBSZXF1ZXN0UHJvcGVydGllcy5wdXQoa2V5LCB2YWx1ZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBmSFRUUFJlcXVlc3RQcm9wZXJ0aWVzLnJlbW92ZShrZXkpOwotICAgICAgICB9Ci0gICAgfSAvLyBzZXRIVFRQUmVxdWVzdFByb3BlcnR5KFN0cmluZyxTdHJpbmcpCi0KLX0gLy8gY2xhc3MgSFRUUElucHV0U291cmNlCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL0ludFN0YWNrLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL0ludFN0YWNrLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDU0MWQxN2EuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9JbnRTdGFjay5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTE2ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDAtMjAwMiwyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWw7Ci0KLS8qKgotICogQSBzaW1wbGUgaW50ZWdlciBiYXNlZCBzdGFjay4KLSAqCi0gKiBtb3ZlZCB0byBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwgYnkgbmVpbGcgdG8gc3VwcG9ydCB0aGUKLSAqIFhQYXRoTWF0Y2hlci4KLSAqIEBhdXRob3IgIEFuZHkgQ2xhcmssIElCTQotICoKLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIEludFN0YWNrIHsKLQotICAgIC8vCi0gICAgLy8gRGF0YQotICAgIC8vCi0KLSAgICAvKiogU3RhY2sgZGVwdGguICovCi0gICAgcHJpdmF0ZSBpbnQgZkRlcHRoOwotCi0gICAgLyoqIFN0YWNrIGRhdGEuICovCi0gICAgcHJpdmF0ZSBpbnRbXSBmRGF0YTsKLQotICAgIC8vCi0gICAgLy8gUHVibGljIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqIFJldHVybnMgdGhlIHNpemUgb2YgdGhlIHN0YWNrLiAqLwotICAgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKLSAgICAgICAgcmV0dXJuIGZEZXB0aDsKLSAgICB9Ci0KLSAgICAvKiogUHVzaGVzIGEgdmFsdWUgb250byB0aGUgc3RhY2suICovCi0gICAgcHVibGljIHZvaWQgcHVzaChpbnQgdmFsdWUpIHsKLSAgICAgICAgZW5zdXJlQ2FwYWNpdHkoZkRlcHRoICsgMSk7Ci0gICAgICAgIGZEYXRhW2ZEZXB0aCsrXSA9IHZhbHVlOwotICAgIH0KLQotICAgIC8qKiBQZWVrcyBhdCB0aGUgdG9wIG9mIHRoZSBzdGFjay4gKi8KLSAgICBwdWJsaWMgaW50IHBlZWsoKSB7Ci0gICAgICAgIHJldHVybiBmRGF0YVtmRGVwdGggLSAxXTsKLSAgICB9Ci0KLSAgICAvKiogUmV0dXJucyB0aGUgZWxlbWVudCBhdCB0aGUgc3BlY2lmaWVkIGRlcHRoIGluIHRoZSBzdGFjay4gKi8KLSAgICBwdWJsaWMgaW50IGVsZW1lbnRBdChpbnQgZGVwdGgpIHsKLSAgICAgICAgcmV0dXJuIGZEYXRhW2RlcHRoXTsKLSAgICB9Ci0KLSAgICAvKiogUG9wcyBhIHZhbHVlIG9mZiBvZiB0aGUgc3RhY2suICovCi0gICAgcHVibGljIGludCBwb3AoKSB7Ci0gICAgICAgIHJldHVybiBmRGF0YVstLWZEZXB0aF07Ci0gICAgfQotCi0gICAgLyoqIENsZWFycyB0aGUgc3RhY2suICovCi0gICAgcHVibGljIHZvaWQgY2xlYXIoKSB7Ci0gICAgICAgIGZEZXB0aCA9IDA7Ci0gICAgfQotCi0gICAgLy8gZGVidWdnaW5nCi0KLSAgICAvKiogUHJpbnRzIHRoZSBzdGFjay4gKi8KLSAgICBwdWJsaWMgdm9pZCBwcmludCgpIHsKLSAgICAgICAgU3lzdGVtLm91dC5wcmludCgnKCcpOwotICAgICAgICBTeXN0ZW0ub3V0LnByaW50KGZEZXB0aCk7Ci0gICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIikgeyIpOwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZEZXB0aDsgaSsrKSB7Ci0gICAgICAgICAgICBpZiAoaSA9PSAzKSB7Ci0gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiIC4uLiIpOwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgnICcpOwotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludChmRGF0YVtpXSk7Ci0gICAgICAgICAgICBpZiAoaSA8IGZEZXB0aCAtIDEpIHsKLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCcsJyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgU3lzdGVtLm91dC5wcmludCgiIH0iKTsKLSAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCk7Ci0gICAgfQotCi0gICAgLy8KLSAgICAvLyBQcml2YXRlIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqIEVuc3VyZXMgY2FwYWNpdHkuICovCi0gICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUNhcGFjaXR5KGludCBzaXplKSB7Ci0gICAgICAgIGlmIChmRGF0YSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBmRGF0YSA9IG5ldyBpbnRbMzJdOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKGZEYXRhLmxlbmd0aCA8PSBzaXplKSB7Ci0gICAgICAgICAgICBpbnRbXSBuZXdkYXRhID0gbmV3IGludFtmRGF0YS5sZW5ndGggKiAyXTsKLSAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZkRhdGEsIDAsIG5ld2RhdGEsIDAsIGZEYXRhLmxlbmd0aCk7Ci0gICAgICAgICAgICBmRGF0YSA9IG5ld2RhdGE7Ci0gICAgICAgIH0KLSAgICB9Ci0KLX0gLy8gY2xhc3MgSW50U3RhY2sKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3V0aWwvSkFYUE5hbWVzcGFjZUNvbnRleHRXcmFwcGVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL0pBWFBOYW1lc3BhY2VDb250ZXh0V3JhcHBlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjZGY2MmQwLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3V0aWwvSkFYUE5hbWVzcGFjZUNvbnRleHRXcmFwcGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNTAgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKLSAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAotICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgotICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKLSAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCi0gKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWw7Ci0KLQotaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKLWltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247Ci1pbXBvcnQgamF2YS51dGlsLkxpc3Q7Ci1pbXBvcnQgamF2YS51dGlsLlRyZWVTZXQ7Ci1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotaW1wb3J0IGphdmF4LnhtbC5YTUxDb25zdGFudHM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5OYW1lc3BhY2VDb250ZXh0OwotCi0vKioKLSAqIDxwPkEgcmVhZC1vbmx5IFhOSSB3cmFwcGVyIGFyb3VuZCBhIEpBWFAgTmFtZXNwYWNlQ29udGV4dC48L3A+Ci0gKgotICogQGF1dGhvciBNaWNoYWVsIEdsYXZhc3NldmljaCwgSUJNCi0gKgotICogQHZlcnNpb24gJElkOiBKQVhQTmFtZXNwYWNlQ29udGV4dFdyYXBwZXIuamF2YSx2IDEuMiAyMDEwLTEwLTI2IDIzOjAxOjEzIGpvZWh3IEV4cCAkCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBKQVhQTmFtZXNwYWNlQ29udGV4dFdyYXBwZXIgaW1wbGVtZW50cyBOYW1lc3BhY2VDb250ZXh0IHsKLQotICAgIHByaXZhdGUgamF2YXgueG1sLm5hbWVzcGFjZS5OYW1lc3BhY2VDb250ZXh0IGZOYW1lc3BhY2VDb250ZXh0OwotICAgIHByaXZhdGUgU3ltYm9sVGFibGUgZlN5bWJvbFRhYmxlOwotICAgIHByaXZhdGUgTGlzdCBmUHJlZml4ZXM7Ci0gICAgcHJpdmF0ZSBmaW5hbCBWZWN0b3IgZkFsbFByZWZpeGVzID0gbmV3IFZlY3RvcigpOwotCi0gICAgcHJpdmF0ZSBpbnRbXSBmQ29udGV4dCA9IG5ldyBpbnRbOF07Ci0gICAgcHJpdmF0ZSBpbnQgZkN1cnJlbnRDb250ZXh0OwotCi0gICAgcHVibGljIEpBWFBOYW1lc3BhY2VDb250ZXh0V3JhcHBlcihTeW1ib2xUYWJsZSBzeW1ib2xUYWJsZSkgewotICAgICAgICBzZXRTeW1ib2xUYWJsZShzeW1ib2xUYWJsZSk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0TmFtZXNwYWNlQ29udGV4dChqYXZheC54bWwubmFtZXNwYWNlLk5hbWVzcGFjZUNvbnRleHQgY29udGV4dCkgewotICAgICAgICBmTmFtZXNwYWNlQ29udGV4dCA9IGNvbnRleHQ7Ci0gICAgfQotCi0gICAgcHVibGljIGphdmF4LnhtbC5uYW1lc3BhY2UuTmFtZXNwYWNlQ29udGV4dCBnZXROYW1lc3BhY2VDb250ZXh0KCkgewotICAgICAgICByZXR1cm4gZk5hbWVzcGFjZUNvbnRleHQ7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0U3ltYm9sVGFibGUoU3ltYm9sVGFibGUgc3ltYm9sVGFibGUpIHsKLSAgICAgICAgZlN5bWJvbFRhYmxlID0gc3ltYm9sVGFibGU7Ci0gICAgfQotCi0gICAgcHVibGljIFN5bWJvbFRhYmxlIGdldFN5bWJvbFRhYmxlKCkgewotICAgICAgICByZXR1cm4gZlN5bWJvbFRhYmxlOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldERlY2xhcmVkUHJlZml4ZXMoTGlzdCBwcmVmaXhlcykgewotICAgICAgICBmUHJlZml4ZXMgPSBwcmVmaXhlczsKLSAgICB9Ci0KLSAgICBwdWJsaWMgTGlzdCBnZXREZWNsYXJlZFByZWZpeGVzKCkgewotICAgICAgICByZXR1cm4gZlByZWZpeGVzOwotICAgIH0KLQotICAgIC8qCi0gICAgICogTmFtZXNwYWNlQ29udGV4dCBtZXRob2RzCi0gICAgICovCi0KLSAgICBwdWJsaWMgU3RyaW5nIGdldFVSSShTdHJpbmcgcHJlZml4KSB7Ci0gICAgICAgIGlmIChmTmFtZXNwYWNlQ29udGV4dCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBTdHJpbmcgdXJpID0gZk5hbWVzcGFjZUNvbnRleHQuZ2V0TmFtZXNwYWNlVVJJKHByZWZpeCk7Ci0gICAgICAgICAgICBpZiAodXJpICE9IG51bGwgJiYgIVhNTENvbnN0YW50cy5OVUxMX05TX1VSSS5lcXVhbHModXJpKSkgewotICAgICAgICAgICAgICAgIHJldHVybiAoZlN5bWJvbFRhYmxlICE9IG51bGwpID8gZlN5bWJvbFRhYmxlLmFkZFN5bWJvbCh1cmkpIDogdXJpLmludGVybigpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0UHJlZml4KFN0cmluZyB1cmkpIHsKLSAgICAgICAgaWYgKGZOYW1lc3BhY2VDb250ZXh0ICE9IG51bGwpIHsKLSAgICAgICAgICAgIGlmICh1cmkgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHVyaSA9IFhNTENvbnN0YW50cy5OVUxMX05TX1VSSTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIFN0cmluZyBwcmVmaXggPSBmTmFtZXNwYWNlQ29udGV4dC5nZXRQcmVmaXgodXJpKTsKLSAgICAgICAgICAgIGlmIChwcmVmaXggPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHByZWZpeCA9IFhNTENvbnN0YW50cy5ERUZBVUxUX05TX1BSRUZJWDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiAoZlN5bWJvbFRhYmxlICE9IG51bGwpID8gZlN5bWJvbFRhYmxlLmFkZFN5bWJvbChwcmVmaXgpIDogcHJlZml4LmludGVybigpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIHB1YmxpYyBFbnVtZXJhdGlvbiBnZXRBbGxQcmVmaXhlcygpIHsKLSAgICAgICAgLy8gVGhlcmUgbWF5IGJlIGR1cGxpY2F0ZSBwcmVmaXhlcyBpbiB0aGUgbGlzdCBzbyB3ZQotICAgICAgICAvLyBmaXJzdCB0cmFuc2ZlciB0aGVtIHRvIGEgc2V0IHRvIGVuc3VyZSB1bmlxdWVuZXNzLgotICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnMuZW51bWVyYXRpb24obmV3IFRyZWVTZXQoZkFsbFByZWZpeGVzKSk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgcHVzaENvbnRleHQoKSB7Ci0gICAgICAgIC8vIGV4dGVuZCB0aGUgYXJyYXksIGlmIG5lY2Vzc2FyeQotICAgICAgICBpZiAoZkN1cnJlbnRDb250ZXh0ICsgMSA9PSBmQ29udGV4dC5sZW5ndGgpIHsKLSAgICAgICAgICAgIGludFtdIGNvbnRleHRhcnJheSA9IG5ldyBpbnRbZkNvbnRleHQubGVuZ3RoICogMl07Ci0gICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGZDb250ZXh0LCAwLCBjb250ZXh0YXJyYXksIDAsIGZDb250ZXh0Lmxlbmd0aCk7Ci0gICAgICAgICAgICBmQ29udGV4dCA9IGNvbnRleHRhcnJheTsKLSAgICAgICAgfQotICAgICAgICAvLyBwdXNoIGNvbnRleHQKLSAgICAgICAgZkNvbnRleHRbKytmQ3VycmVudENvbnRleHRdID0gZkFsbFByZWZpeGVzLnNpemUoKTsKLSAgICAgICAgaWYgKGZQcmVmaXhlcyAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmQWxsUHJlZml4ZXMuYWRkQWxsKGZQcmVmaXhlcyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBwb3BDb250ZXh0KCkgewotICAgICAgICBmQWxsUHJlZml4ZXMuc2V0U2l6ZShmQ29udGV4dFtmQ3VycmVudENvbnRleHQtLV0pOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGRlY2xhcmVQcmVmaXgoU3RyaW5nIHByZWZpeCwgU3RyaW5nIHVyaSkgewotICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldERlY2xhcmVkUHJlZml4Q291bnQoKSB7Ci0gICAgICAgIHJldHVybiAoZlByZWZpeGVzICE9IG51bGwpID8gZlByZWZpeGVzLnNpemUoKSA6IDA7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXREZWNsYXJlZFByZWZpeEF0KGludCBpbmRleCkgewotICAgICAgICByZXR1cm4gKFN0cmluZykgZlByZWZpeGVzLmdldChpbmRleCk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgcmVzZXQoKSB7Ci0gICAgICAgIGZDdXJyZW50Q29udGV4dCA9IDA7Ci0gICAgICAgIGZDb250ZXh0W2ZDdXJyZW50Q29udGV4dF0gPSAwOwotICAgICAgICBmQWxsUHJlZml4ZXMuY2xlYXIoKTsKLSAgICB9Ci0KLX0gLy8gSkFYUE5hbWVzcGFjZUNvbnRleHRXcmFwcGVyCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL0xvY2F0b3JQcm94eS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9Mb2NhdG9yUHJveHkuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNjljNzhhMS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL0xvY2F0b3JQcm94eS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsODggKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MTG9jYXRvcjsKLWltcG9ydCBvcmcueG1sLnNheC5Mb2NhdG9yOwotaW1wb3J0IG9yZy54bWwuc2F4LmV4dC5Mb2NhdG9yMjsKLQotLyoqCi0gKiBXcmFwcyB7QGxpbmsgWE1MTG9jYXRvcn0gYW5kIG1ha2UgaXQgbG9vayBsaWtlIGEgU0FYIHtAbGluayBMb2NhdG9yfS4KLSAqCi0gKiBAYXV0aG9yIEFybmF1ZCBMZSBIb3JzLCBJQk0KLSAqIEBhdXRob3IgQW5keSBDbGFyaywgSUJNCi0gKgotICovCi1wdWJsaWMgY2xhc3MgTG9jYXRvclByb3h5IGltcGxlbWVudHMgTG9jYXRvcjIgewotCi0gICAgLy8KLSAgICAvLyBEYXRhCi0gICAgLy8KLQotICAgIC8qKiBYTUwgbG9jYXRvci4gKi8KLSAgICBwcml2YXRlIGZpbmFsIFhNTExvY2F0b3IgZkxvY2F0b3I7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0cnVjdG9ycwotICAgIC8vCi0KLSAgICAvKiogQ29uc3RydWN0cyBhbiBYTUwgbG9jYXRvciBwcm94eS4gKi8KLSAgICBwdWJsaWMgTG9jYXRvclByb3h5KFhNTExvY2F0b3IgbG9jYXRvcikgewotICAgICAgICBmTG9jYXRvciA9IGxvY2F0b3I7Ci0gICAgfQotCi0gICAgLy8KLSAgICAvLyBMb2NhdG9yIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqIFB1YmxpYyBpZGVudGlmaWVyLiAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0UHVibGljSWQoKSB7Ci0gICAgICAgIHJldHVybiBmTG9jYXRvci5nZXRQdWJsaWNJZCgpOwotICAgIH0KLQotICAgIC8qKiBTeXN0ZW0gaWRlbnRpZmllci4gKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFN5c3RlbUlkKCkgewotICAgICAgICByZXR1cm4gZkxvY2F0b3IuZ2V0RXhwYW5kZWRTeXN0ZW1JZCgpOwotICAgIH0KLQotICAgIC8qKiBMaW5lIG51bWJlci4gKi8KLSAgICBwdWJsaWMgaW50IGdldExpbmVOdW1iZXIoKSB7Ci0gICAgICAgIHJldHVybiBmTG9jYXRvci5nZXRMaW5lTnVtYmVyKCk7Ci0gICAgfQotCi0gICAgLyoqIENvbHVtbiBudW1iZXIuICovCi0gICAgcHVibGljIGludCBnZXRDb2x1bW5OdW1iZXIoKSB7Ci0gICAgICAgIHJldHVybiBmTG9jYXRvci5nZXRDb2x1bW5OdW1iZXIoKTsKLSAgICB9Ci0KLSAgICAvLwotICAgIC8vIExvY2F0b3IyIG1ldGhvZHMKLSAgICAvLwotCi0gICAgcHVibGljIFN0cmluZyBnZXRYTUxWZXJzaW9uKCkgewotICAgICAgICByZXR1cm4gZkxvY2F0b3IuZ2V0WE1MVmVyc2lvbigpOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0RW5jb2RpbmcoKSB7Ci0gICAgICAgIHJldHVybiBmTG9jYXRvci5nZXRFbmNvZGluZygpOwotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9Mb2NhdG9yV3JhcHBlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9Mb2NhdG9yV3JhcHBlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkNDQ0NWU2Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3V0aWwvTG9jYXRvcldyYXBwZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExMCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAwLTIwMDIgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYZXJjZXMiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIEludGVybmF0aW9uYWwKLSAqIEJ1c2luZXNzIE1hY2hpbmVzLCBJbmMuLCBodHRwOi8vd3d3LmFwYWNoZS5vcmcuICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MTG9jYXRvcjsKLWltcG9ydCBvcmcueG1sLnNheC5Mb2NhdG9yOwotCi0vKioKLSAqIFdyYXBzIFNBWCB7QGxpbmsgTG9jYXRvcn0gaW50byBYZXJjZXMge0BsaW5rIFhNTExvY2F0b3J9LgotICoKLSAqIEBhdXRob3IKLSAqICAgICBLb2hzdWtlIEthd2FndWNoaSAoa29oc3VrZS5rYXdhZ3VjaGlAc3VuLmNvbSkKLSAqLwotcHVibGljIGNsYXNzIExvY2F0b3JXcmFwcGVyIGltcGxlbWVudHMgWE1MTG9jYXRvciB7Ci0KLSAgICBwcml2YXRlIGZpbmFsIExvY2F0b3IgbG9jYXRvcjsKLQotICAgIHB1YmxpYyBMb2NhdG9yV3JhcHBlciggTG9jYXRvciBfbG9jICkgeyB0aGlzLmxvY2F0b3I9X2xvYzsgfQotCi0gICAgcHVibGljIGludCBnZXRDb2x1bW5OdW1iZXIoKSAgeyByZXR1cm4gbG9jYXRvci5nZXRDb2x1bW5OdW1iZXIoKTsgfQotICAgIHB1YmxpYyBpbnQgZ2V0TGluZU51bWJlcigpICAgIHsgcmV0dXJuIGxvY2F0b3IuZ2V0TGluZU51bWJlcigpOyB9Ci0gICAgcHVibGljIFN0cmluZyBnZXRCYXNlU3lzdGVtSWQoKSB7IHJldHVybiBudWxsOyB9Ci0gICAgcHVibGljIFN0cmluZyBnZXRFeHBhbmRlZFN5c3RlbUlkKCkgeyByZXR1cm4gbG9jYXRvci5nZXRTeXN0ZW1JZCgpOyB9Ci0gICAgcHVibGljIFN0cmluZyBnZXRMaXRlcmFsU3lzdGVtSWQoKSB7IHJldHVybiBsb2NhdG9yLmdldFN5c3RlbUlkKCk7IH0KLSAgICBwdWJsaWMgU3RyaW5nIGdldFB1YmxpY0lkKCkgICB7IHJldHVybiBsb2NhdG9yLmdldFB1YmxpY0lkKCk7IH0KLSAgICBwdWJsaWMgU3RyaW5nIGdldEVuY29kaW5nKCkgeyByZXR1cm4gbnVsbDsgfQotCi0gICAgLyoqCi0gICAgICogPHA+UmV0dXJucyB0aGUgY2hhcmFjdGVyIG9mZnNldCwKLSAgICAgKiBvciA8Y29kZT4tMTwvY29kZT4sCi0gICAgICogaWYgbm8gY2hhcmFjdGVyIG9mZnNldCBpcyBhdmFpbGFibGUuPHA+Ci0gICAgICoKLSAgICAgKiA8cD5BcyB0aGlzIGluZm9ybWF0aW9uIGlzIG5vdCBhdmFpbGFibGUgZnJvbQotICAgICAqIHtAbGluayBvcmcueG1sLnNheC5Mb2NhdG9yfSwKLSAgICAgKiBhbHdheXMgcmV0dXJuIDxjb2RlPi0xPC9jb2RlPi48L3A+Ci0gICAgICovCi0gICAgcHVibGljIGludCBnZXRDaGFyYWN0ZXJPZmZzZXQoKSB7Ci0gICAgICAgIHJldHVybiAtMTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5SZXR1cm5zIHRoZSBYTUwgdmVyc2lvbiBvZiB0aGUgY3VycmVudCBlbnRpdHkuPC9wPgotICAgICAqCi0gICAgICogPHA+QXMgdGhpcyBpbmZvcm1hdGlvbiBpcyBub3QgYXZhaWxhYmxlIGZyb20KLSAgICAgKiB7QGxpbmsgb3JnLnhtbC5zYXguTG9jYXRvcn0sCi0gICAgICogYWx3YXlzIHJldHVybiA8Y29kZT5udWxsPC9jb2RlPi48L3A+Ci0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRYTUxWZXJzaW9uKCkgewotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3V0aWwvTWVzc2FnZUZvcm1hdHRlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9NZXNzYWdlRm9ybWF0dGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGY1NWJhNWUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9NZXNzYWdlRm9ybWF0dGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw2MCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsOwotCi1pbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKLWltcG9ydCBqYXZhLnV0aWwuTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uOwotCi0vKioKLSAqIFRoaXMgaW50ZXJmYWNlIHByb3ZpZGVzIGEgZ2VuZXJpYyBtZXNzYWdlIGZvcm1hdHRpbmcgbWVjaGFuaXNtIGFuZAotICogaXMgdXNlZnVsIGZvciBwcm9kdWNpbmcgbWVzc2FnZXMgdGhhdCBtdXN0IGJlIGxvY2FsZWQgYW5kL29yIGZvcm1hdHRlZAotICogd2l0aCByZXBsYWNlbWVudCB0ZXh0LgotICoKLSAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLlhNTEVycm9yUmVwb3J0ZXIKLSAqCi0gKiBAYXV0aG9yIEFuZHkgQ2xhcmsKLSAqCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgTWVzc2FnZUZvcm1hdHRlciB7Ci0KLSAgICAvLwotICAgIC8vIE1lc3NhZ2VGb3JtYXR0ZXIgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBGb3JtYXRzIGEgbWVzc2FnZSB3aXRoIHRoZSBzcGVjaWZpZWQgYXJndW1lbnRzIHVzaW5nIHRoZSBnaXZlbgotICAgICAqIGxvY2FsZSBpbmZvcm1hdGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBsb2NhbGUgICAgVGhlIGxvY2FsZSBvZiB0aGUgbWVzc2FnZS4KLSAgICAgKiBAcGFyYW0ga2V5ICAgICAgIFRoZSBtZXNzYWdlIGtleS4KLSAgICAgKiBAcGFyYW0gYXJndW1lbnRzIFRoZSBtZXNzYWdlIHJlcGxhY2VtZW50IHRleHQgYXJndW1lbnRzLiBUaGUgb3JkZXIKLSAgICAgKiAgICAgICAgICAgICAgICAgIG9mIHRoZSBhcmd1bWVudHMgbXVzdCBtYXRjaCB0aGF0IG9mIHRoZSBwbGFjZWhvbGRlcnMKLSAgICAgKiAgICAgICAgICAgICAgICAgIGluIHRoZSBhY3R1YWwgbWVzc2FnZS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gUmV0dXJucyB0aGUgZm9ybWF0dGVkIG1lc3NhZ2UuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbiBUaHJvd24gaWYgdGhlIG1lc3NhZ2Ugd2l0aCB0aGUKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGVjaWZpZWQga2V5IGNhbm5vdCBiZSBmb3VuZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGZvcm1hdE1lc3NhZ2UoTG9jYWxlIGxvY2FsZSwgU3RyaW5nIGtleSwgT2JqZWN0W10gYXJndW1lbnRzKQotICAgICAgICB0aHJvd3MgTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uOwotCi19IC8vIGludGVyZmFjZSBNZXNzYWdlRm9ybWF0dGVyCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL05hbWVzcGFjZUNvbnRleHRXcmFwcGVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL05hbWVzcGFjZUNvbnRleHRXcmFwcGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDIxNDMxNTkuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9OYW1lc3BhY2VDb250ZXh0V3JhcHBlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTAgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAwNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWw7Ci0KLWltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247Ci1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLWltcG9ydCBqYXZheC54bWwubmFtZXNwYWNlLk5hbWVzcGFjZUNvbnRleHQ7Ci0KLS8qKgotICogV3JpdGluZyBhIHdyYXBwZXIgdG8gcmUtdXNlIG1vc3Qgb2YgdGhlIG5hbWVzcGFjZSBmdW5jdGlvbmFsaXR5Ci0gKiBhbHJlYWR5IHByb3ZpZGVkIGJ5IE5hbWVzcGFjZVN1cHBvcnQsIHdoaWNoIGltcGxlbWVudHMgTmFtZXNwYWNlQ29udGV4dAotICogZnJvbSBYTkkuIEl0IHdvdWxkIGJlIGdvb2QgaWYgd2UgY2FuIGNoYW5nZSB0aGUgWE5JIE5hbWVzcGFjZUNvbnRleHQKLSAqIGludGVyZmFjZSB0byBpbXBsZW1lbnQgdGhlIEpBWFAgTmFtZXNwYWNlQ29udGV4dCBpbnRlcmZhY2UuCi0gKgotICogTm90ZSB0aGF0IE5hbWVzcGFjZVN1cHBvcnQgYXNzdW1lcyB0aGUgdXNlIG9mIHN5bWJvbHMuIFNpbmNlIHRoaXMgY2xhc3MKLSAqIGNhbiBiZSBleHBvc2VkIHRvIHRoZSBhcHBsaWNhdGlvbiwgd2UgbXVzdCBpbnRlcm4gYWxsIFN0cmluZ3MgYmVmb3JlCi0gKiBjYWxsaW5nIE5hbWVzcGFjZVN1cHBvcnQgbWV0aG9kcy4KLSAqCi0gKiBAYXV0aG9yICBOZWVyYWogQmFqYWosIFN1biBNaWNyb3N5c3RlbXMsIGluYy4KLSAqIEBhdXRob3IgU2FudGlhZ28uUGVyaWNhc0dlZXJ0c2VuQHN1bi5jb20KLSAqCi0gKi8KLXB1YmxpYyBjbGFzcyBOYW1lc3BhY2VDb250ZXh0V3JhcHBlciBpbXBsZW1lbnRzIE5hbWVzcGFjZUNvbnRleHQgewotCi0gICAgcHJpdmF0ZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5OYW1lc3BhY2VDb250ZXh0IGZOYW1lc3BhY2VDb250ZXh0OwotCi0gICAgcHVibGljIE5hbWVzcGFjZUNvbnRleHRXcmFwcGVyKE5hbWVzcGFjZVN1cHBvcnQgbmFtZXNwYWNlQ29udGV4dCkgewotICAgICAgICBmTmFtZXNwYWNlQ29udGV4dCA9IG5hbWVzcGFjZUNvbnRleHQgOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZXNwYWNlVVJJKFN0cmluZyBwcmVmaXgpIHsKLSAgICAgICAgaWYgKHByZWZpeCA9PSBudWxsKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJQcmVmaXggY2FuJ3QgYmUgbnVsbCIpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmTmFtZXNwYWNlQ29udGV4dC5nZXRVUkkocHJlZml4LmludGVybigpKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldFByZWZpeChTdHJpbmcgbmFtZXNwYWNlVVJJKSB7Ci0gICAgICAgIGlmIChuYW1lc3BhY2VVUkkgPT0gbnVsbCkgewotICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiVVJJIGNhbid0IGJlIG51bGwuIik7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGZOYW1lc3BhY2VDb250ZXh0LmdldFByZWZpeChuYW1lc3BhY2VVUkkuaW50ZXJuKCkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRPRE86IE5hbWVzcGFjZSBkb2Vzbid0IGdpdmUgaW5mb3JtYXRpb24gZ2l2aW5nIG11bHRpcGxlIHByZWZpeGVzIGZvcgotICAgICAqIHRoZSBzYW1lIG5hbWVzcGFjZVVSSS4KLSAgICAgKi8KLSAgICBwdWJsaWMgamF2YS51dGlsLkl0ZXJhdG9yIGdldFByZWZpeGVzKFN0cmluZyBuYW1lc3BhY2VVUkkpIHsKLSAgICAgICAgaWYgKG5hbWVzcGFjZVVSSSA9PSBudWxsKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJVUkkgY2FuJ3QgYmUgbnVsbC4iKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIFZlY3RvciB2ZWN0b3IgPQotICAgICAgICAgICAgICAgICgoTmFtZXNwYWNlU3VwcG9ydCkgZk5hbWVzcGFjZUNvbnRleHQpLmdldFByZWZpeGVzKG5hbWVzcGFjZVVSSS5pbnRlcm4oKSk7Ci0gICAgICAgICAgICByZXR1cm4gdmVjdG9yLml0ZXJhdG9yKCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBzdXBwb3J0cyBhbGwgZnVuY3Rpb25zIGluIHRoZSBOYW1lc3BhY2VDb250ZXh0IHV0aWxpdHkgY2xhc3MKLSAgICAgKi8KLSAgICBwdWJsaWMgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuTmFtZXNwYWNlQ29udGV4dCBnZXROYW1lc3BhY2VDb250ZXh0KCkgewotICAgICAgICByZXR1cm4gZk5hbWVzcGFjZUNvbnRleHQ7Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL05hbWVzcGFjZVN1cHBvcnQuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3V0aWwvTmFtZXNwYWNlU3VwcG9ydC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyY2Q2MzJjLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3V0aWwvTmFtZXNwYWNlU3VwcG9ydC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDg0ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDAtMjAwMiBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGVyY2VzIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBJbnRlcm5hdGlvbmFsCi0gKiBCdXNpbmVzcyBNYWNoaW5lcywgSW5jLiwgaHR0cDovL3d3dy5hcGFjaGUub3JnLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsOwotCi1pbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOwotaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKLWltcG9ydCBqYXZhLnV0aWwuTm9TdWNoRWxlbWVudEV4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuTmFtZXNwYWNlQ29udGV4dDsKLQotLyoqCi0gKiBOYW1lc3BhY2Ugc3VwcG9ydCBmb3IgWE1MIGRvY3VtZW50IGhhbmRsZXJzLiBUaGlzIGNsYXNzIGRvZXNuJ3QKLSAqIHBlcmZvcm0gYW55IGVycm9yIGNoZWNraW5nIGFuZCBhc3N1bWVzIHRoYXQgYWxsIHN0cmluZ3MgcGFzc2VkCi0gKiBhcyBhcmd1bWVudHMgdG8gbWV0aG9kcyBhcmUgdW5pcXVlIHN5bWJvbHMuIFRoZSBTeW1ib2xUYWJsZSBjbGFzcwotICogY2FuIGJlIHVzZWQgZm9yIHRoaXMgcHVycG9zZS4KLSAqCi0gKiBAYXV0aG9yIEFuZHkgQ2xhcmssIElCTQotICoKLSAqLwotcHVibGljIGNsYXNzIE5hbWVzcGFjZVN1cHBvcnQgaW1wbGVtZW50cyBOYW1lc3BhY2VDb250ZXh0IHsKLQotICAgIC8vCi0gICAgLy8gRGF0YQotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBOYW1lc3BhY2UgYmluZGluZyBpbmZvcm1hdGlvbi4gVGhpcyBhcnJheSBpcyBjb21wb3NlZCBvZiBhCi0gICAgICogc2VyaWVzIG9mIHR1cGxlcyBjb250YWluaW5nIHRoZSBuYW1lc3BhY2UgYmluZGluZyBpbmZvcm1hdGlvbjoKLSAgICAgKiAmbHQ7cHJlZml4LCB1cmkmZ3Q7LiBUaGUgZGVmYXVsdCBzaXplIGNhbiBiZSBzZXQgdG8gYW55dGhpbmcKLSAgICAgKiBhcyBsb25nIGFzIGl0IGlzIGEgcG93ZXIgb2YgMiBncmVhdGVyIHRoYW4gMS4KLSAgICAgKgotICAgICAqIEBzZWUgI2ZOYW1lc3BhY2VTaXplCi0gICAgICogQHNlZSAjZkNvbnRleHQKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgU3RyaW5nW10gZk5hbWVzcGFjZSA9IG5ldyBTdHJpbmdbMTYgKiAyXTsKLQotICAgIC8qKiBUaGUgdG9wIG9mIHRoZSBuYW1lc3BhY2UgaW5mb3JtYXRpb24gYXJyYXkuICovCi0gICAgcHJvdGVjdGVkIGludCBmTmFtZXNwYWNlU2l6ZTsKLQotICAgIC8vIE5PVEU6IFRoZSBjb25zdHJ1Y3RvciBkZXBlbmRzIG9uIHRoZSBpbml0aWFsIGNvbnRleHQgc2l6ZQotICAgIC8vICAgICAgIGJlaW5nIGF0IGxlYXN0IDEuIC1BYwotCi0gICAgLyoqCi0gICAgICogQ29udGV4dCBpbmRleGVzLiBUaGlzIGFycmF5IGNvbnRhaW5zIGluZGV4ZXMgaW50byB0aGUgbmFtZXNwYWNlCi0gICAgICogaW5mb3JtYXRpb24gYXJyYXkuIFRoZSBpbmRleCBhdCB0aGUgY3VycmVudCBjb250ZXh0IGlzIHRoZSBzdGFydAotICAgICAqIGluZGV4IG9mIGRlY2xhcmVkIG5hbWVzcGFjZSBiaW5kaW5ncyBhbmQgcnVucyB0byB0aGUgc2l6ZSBvZiB0aGUKLSAgICAgKiBuYW1lc3BhY2UgaW5mb3JtYXRpb24gYXJyYXkuCi0gICAgICoKLSAgICAgKiBAc2VlICNmTmFtZXNwYWNlU2l6ZQotICAgICAqLwotICAgIHByb3RlY3RlZCBpbnRbXSBmQ29udGV4dCA9IG5ldyBpbnRbOF07Ci0KLSAgICAvKiogVGhlIGN1cnJlbnQgY29udGV4dC4gKi8KLSAgICBwcm90ZWN0ZWQgaW50IGZDdXJyZW50Q29udGV4dDsKLQotICAgIHByb3RlY3RlZCBTdHJpbmdbXSBmUHJlZml4ZXMgPSBuZXcgU3RyaW5nWzE2XTsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKiBEZWZhdWx0IGNvbnN0cnVjdG9yLiAqLwotICAgIHB1YmxpYyBOYW1lc3BhY2VTdXBwb3J0KCkgewotICAgIH0gLy8gPGluaXQ+KCkKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHMgYSBuYW1lc3BhY2UgY29udGV4dCBvYmplY3QgYW5kIGluaXRpYWxpemVzIGl0IHdpdGgKLSAgICAgKiB0aGUgcHJlZml4ZXMgZGVjbGFyZWQgaW4gdGhlIHNwZWNpZmllZCBjb250ZXh0LgotICAgICAqLwotICAgIHB1YmxpYyBOYW1lc3BhY2VTdXBwb3J0KE5hbWVzcGFjZUNvbnRleHQgY29udGV4dCkgewotICAgICAgICBwdXNoQ29udGV4dCgpOwotICAgICAgICAvLyBjb3B5IGRlY2xhcmF0aW9uIGluIHRoZSBjb250ZXh0Ci0gICAgICAgIEVudW1lcmF0aW9uIHByZWZpeGVzID0gY29udGV4dC5nZXRBbGxQcmVmaXhlcygpOwotICAgICAgICB3aGlsZSAocHJlZml4ZXMuaGFzTW9yZUVsZW1lbnRzKCkpewotICAgICAgICAgICAgU3RyaW5nIHByZWZpeCA9IChTdHJpbmcpcHJlZml4ZXMubmV4dEVsZW1lbnQoKTsKLSAgICAgICAgICAgIFN0cmluZyB1cmkgPSBjb250ZXh0LmdldFVSSShwcmVmaXgpOwotICAgICAgICAgICAgZGVjbGFyZVByZWZpeChwcmVmaXgsIHVyaSk7Ci0gICAgICAgIH0KLSAgICB9IC8vIDxpbml0PihOYW1lc3BhY2VDb250ZXh0KQotCi0KLSAgICAvLwotICAgIC8vIFB1YmxpYyBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuTmFtZXNwYWNlQ29udGV4dCNyZXNldCgpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcmVzZXQoKSB7Ci0KLSAgICAgICAgLy8gcmVzZXQgbmFtZXNwYWNlIGFuZCBjb250ZXh0IGluZm8KLSAgICAgICAgZk5hbWVzcGFjZVNpemUgPSAwOwotICAgICAgICBmQ3VycmVudENvbnRleHQgPSAwOwotCi0KLSAgICAgICAgLy8gYmluZCAieG1sIiBwcmVmaXggdG8gdGhlIFhNTCB1cmkKLSAgICAgICAgZk5hbWVzcGFjZVtmTmFtZXNwYWNlU2l6ZSsrXSA9IFhNTFN5bWJvbHMuUFJFRklYX1hNTDsKLSAgICAgICAgZk5hbWVzcGFjZVtmTmFtZXNwYWNlU2l6ZSsrXSA9IE5hbWVzcGFjZUNvbnRleHQuWE1MX1VSSTsKLSAgICAgICAgLy8gYmluZCAieG1sbnMiIHByZWZpeCB0byB0aGUgWE1MTlMgdXJpCi0gICAgICAgIGZOYW1lc3BhY2VbZk5hbWVzcGFjZVNpemUrK10gPSBYTUxTeW1ib2xzLlBSRUZJWF9YTUxOUzsKLSAgICAgICAgZk5hbWVzcGFjZVtmTmFtZXNwYWNlU2l6ZSsrXSA9IE5hbWVzcGFjZUNvbnRleHQuWE1MTlNfVVJJOwotCi0gICAgICAgIGZDb250ZXh0W2ZDdXJyZW50Q29udGV4dF0gPSBmTmFtZXNwYWNlU2l6ZTsKLSAgICAgICAgLy8rK2ZDdXJyZW50Q29udGV4dDsKLQotICAgIH0gLy8gcmVzZXQoU3ltYm9sVGFibGUpCi0KLQotICAgIC8qKgotICAgICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuTmFtZXNwYWNlQ29udGV4dCNwdXNoQ29udGV4dCgpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcHVzaENvbnRleHQoKSB7Ci0KLSAgICAgICAgLy8gZXh0ZW5kIHRoZSBhcnJheSwgaWYgbmVjZXNzYXJ5Ci0gICAgICAgIGlmIChmQ3VycmVudENvbnRleHQgKyAxID09IGZDb250ZXh0Lmxlbmd0aCkgewotICAgICAgICAgICAgaW50W10gY29udGV4dGFycmF5ID0gbmV3IGludFtmQ29udGV4dC5sZW5ndGggKiAyXTsKLSAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZkNvbnRleHQsIDAsIGNvbnRleHRhcnJheSwgMCwgZkNvbnRleHQubGVuZ3RoKTsKLSAgICAgICAgICAgIGZDb250ZXh0ID0gY29udGV4dGFycmF5OwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gcHVzaCBjb250ZXh0Ci0gICAgICAgIGZDb250ZXh0WysrZkN1cnJlbnRDb250ZXh0XSA9IGZOYW1lc3BhY2VTaXplOwotICAgICAgICAvL1N5c3RlbS5vdXQucHJpbnRsbigiY2FsbGluZyBwdXNoIGNvbnRleHQsIGN1cnJlbnQgY29udGV4dCA9ICIgKyBmQ3VycmVudENvbnRleHQpOwotICAgIH0gLy8gcHVzaENvbnRleHQoKQotCi0KLSAgICAvKioKLSAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLk5hbWVzcGFjZUNvbnRleHQjcG9wQ29udGV4dCgpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcG9wQ29udGV4dCgpIHsKLSAgICAgICAgZk5hbWVzcGFjZVNpemUgPSBmQ29udGV4dFtmQ3VycmVudENvbnRleHQtLV07Ci0gICAgICAgIC8vU3lzdGVtLm91dC5wcmludGxuKCJDYWxsaW5nIHBvcENvbnRleHQsIGZDdXJyZW50Q29udGV4dCA9ICIgKyBmQ3VycmVudENvbnRleHQpOwotICAgIH0gLy8gcG9wQ29udGV4dCgpCi0KLSAgICAvKioKLSAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLk5hbWVzcGFjZUNvbnRleHQjZGVjbGFyZVByZWZpeChTdHJpbmcsIFN0cmluZykKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBkZWNsYXJlUHJlZml4KFN0cmluZyBwcmVmaXgsIFN0cmluZyB1cmkpIHsKLSAgICAgICAgLy8gaWdub3JlICJ4bWwiIGFuZCAieG1sbnMiIHByZWZpeGVzCi0gICAgICAgIGlmIChwcmVmaXggPT0gWE1MU3ltYm9scy5QUkVGSVhfWE1MIHx8IHByZWZpeCA9PSBYTUxTeW1ib2xzLlBSRUZJWF9YTUxOUykgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gc2VlIGlmIHByZWZpeCBhbHJlYWR5IGV4aXN0cyBpbiBjdXJyZW50IGNvbnRleHQKLSAgICAgICAgZm9yIChpbnQgaSA9IGZOYW1lc3BhY2VTaXplOyBpID4gZkNvbnRleHRbZkN1cnJlbnRDb250ZXh0XTsgaSAtPSAyKSB7Ci0gICAgICAgICAgICBpZiAoZk5hbWVzcGFjZVtpIC0gMl0gPT0gcHJlZml4KSB7Ci0gICAgICAgICAgICAgICAgLy8gUkVWSVNJVDogW1FdIFNob3VsZCB0aGUgbmV3IGJpbmRpbmcgb3ZlcnJpZGUgdGhlCi0gICAgICAgICAgICAgICAgLy8gICAgICAgICAgcHJldmlvdXNseSBkZWNsYXJlZCBiaW5kaW5nIG9yIHNob3VsZCBpdAotICAgICAgICAgICAgICAgIC8vICAgICAgICAgIGl0IGJlIGlnbm9yZWQ/IC1BYwotICAgICAgICAgICAgICAgIC8vIE5PVEU6ICAgIFRoZSBTQVgyICJOYW1lc3BhY2VTdXBwb3J0IiBoZWxwZXIgYWxsb3dzCi0gICAgICAgICAgICAgICAgLy8gICAgICAgICAgcmUtYmluZGluZ3Mgd2l0aCB0aGUgbmV3IGJpbmRpbmcgb3ZlcndyaXRpbmcKLSAgICAgICAgICAgICAgICAvLyAgICAgICAgICB0aGUgcHJldmlvdXMgYmluZGluZy4gLUFjCi0gICAgICAgICAgICAgICAgZk5hbWVzcGFjZVtpIC0gMV0gPSB1cmk7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyByZXNpemUgYXJyYXksIGlmIG5lZWRlZAotICAgICAgICBpZiAoZk5hbWVzcGFjZVNpemUgPT0gZk5hbWVzcGFjZS5sZW5ndGgpIHsKLSAgICAgICAgICAgIFN0cmluZ1tdIG5hbWVzcGFjZWFycmF5ID0gbmV3IFN0cmluZ1tmTmFtZXNwYWNlU2l6ZSAqIDJdOwotICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShmTmFtZXNwYWNlLCAwLCBuYW1lc3BhY2VhcnJheSwgMCwgZk5hbWVzcGFjZVNpemUpOwotICAgICAgICAgICAgZk5hbWVzcGFjZSA9IG5hbWVzcGFjZWFycmF5OwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gYmluZCBwcmVmaXggdG8gdXJpIGluIGN1cnJlbnQgY29udGV4dAotICAgICAgICBmTmFtZXNwYWNlW2ZOYW1lc3BhY2VTaXplKytdID0gcHJlZml4OwotICAgICAgICBmTmFtZXNwYWNlW2ZOYW1lc3BhY2VTaXplKytdID0gdXJpOwotCi0gICAgICAgIHJldHVybiB0cnVlOwotCi0gICAgfSAvLyBkZWNsYXJlUHJlZml4KFN0cmluZyxTdHJpbmcpOmJvb2xlYW4KLQotICAgIC8qKgotICAgICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuTmFtZXNwYWNlQ29udGV4dCNnZXRVUkkoU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VVJJKFN0cmluZyBwcmVmaXgpIHsKLQotICAgICAgICAvLyBmaW5kIHByZWZpeCBpbiBjdXJyZW50IGNvbnRleHQKLSAgICAgICAgZm9yIChpbnQgaSA9IGZOYW1lc3BhY2VTaXplOyBpID4gMDsgaSAtPSAyKSB7Ci0gICAgICAgICAgICBpZiAoZk5hbWVzcGFjZVtpIC0gMl0gPT0gcHJlZml4KSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZOYW1lc3BhY2VbaSAtIDFdOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gcHJlZml4IG5vdCBmb3VuZAotICAgICAgICByZXR1cm4gbnVsbDsKLQotICAgIH0gLy8gZ2V0VVJJKFN0cmluZyk6U3RyaW5nCi0KLQotICAgIC8qKgotICAgICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuTmFtZXNwYWNlQ29udGV4dCNnZXRQcmVmaXgoU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0UHJlZml4KFN0cmluZyB1cmkpIHsKLQotICAgICAgICAvLyBmaW5kIHVyaSBpbiBjdXJyZW50IGNvbnRleHQKLSAgICAgICAgZm9yIChpbnQgaSA9IGZOYW1lc3BhY2VTaXplOyBpID4gMDsgaSAtPSAyKSB7Ci0gICAgICAgICAgICBpZiAoZk5hbWVzcGFjZVtpIC0gMV0gPT0gdXJpKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGdldFVSSShmTmFtZXNwYWNlW2kgLSAyXSkgPT0gdXJpKQotICAgICAgICAgICAgICAgICAgICByZXR1cm4gZk5hbWVzcGFjZVtpIC0gMl07Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyB1cmkgbm90IGZvdW5kCi0gICAgICAgIHJldHVybiBudWxsOwotCi0gICAgfSAvLyBnZXRQcmVmaXgoU3RyaW5nKTpTdHJpbmcKLQotICAgIC8qKgotICAgICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuTmFtZXNwYWNlQ29udGV4dCNnZXREZWNsYXJlZFByZWZpeENvdW50KCkKLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldERlY2xhcmVkUHJlZml4Q291bnQoKSB7Ci0gICAgICAgIHJldHVybiAoZk5hbWVzcGFjZVNpemUgLSBmQ29udGV4dFtmQ3VycmVudENvbnRleHRdKSAvIDI7Ci0gICAgfSAvLyBnZXREZWNsYXJlZFByZWZpeENvdW50KCk6aW50Ci0KLSAgICAvKioKLSAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLk5hbWVzcGFjZUNvbnRleHQjZ2V0RGVjbGFyZWRQcmVmaXhBdChpbnQpCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXREZWNsYXJlZFByZWZpeEF0KGludCBpbmRleCkgewotICAgICAgICByZXR1cm4gZk5hbWVzcGFjZVtmQ29udGV4dFtmQ3VycmVudENvbnRleHRdICsgaW5kZXggKiAyXTsKLSAgICB9IC8vIGdldERlY2xhcmVkUHJlZml4QXQoaW50KTpTdHJpbmcKLQotICAgIHB1YmxpYyBJdGVyYXRvciBnZXRQcmVmaXhlcygpewotICAgICAgICBpbnQgY291bnQgPSAwOwotICAgICAgICBpZiAoZlByZWZpeGVzLmxlbmd0aCA8IChmTmFtZXNwYWNlLmxlbmd0aC8yKSkgewotICAgICAgICAgICAgLy8gcmVzaXplIHByZWZpeCBhcnJheQotICAgICAgICAgICAgU3RyaW5nW10gcHJlZml4ZXMgPSBuZXcgU3RyaW5nW2ZOYW1lc3BhY2VTaXplXTsKLSAgICAgICAgICAgIGZQcmVmaXhlcyA9IHByZWZpeGVzOwotICAgICAgICB9Ci0gICAgICAgIFN0cmluZyBwcmVmaXggPSBudWxsOwotICAgICAgICBib29sZWFuIHVuaXF1ZSA9IHRydWU7Ci0gICAgICAgIGZvciAoaW50IGkgPSAyOyBpIDwgKGZOYW1lc3BhY2VTaXplLTIpOyBpICs9IDIpIHsKLSAgICAgICAgICAgIHByZWZpeCA9IGZOYW1lc3BhY2VbaSArIDJdOwotICAgICAgICAgICAgZm9yIChpbnQgaz0wO2s8Y291bnQ7aysrKXsKLSAgICAgICAgICAgICAgICBpZiAoZlByZWZpeGVzW2tdPT1wcmVmaXgpewotICAgICAgICAgICAgICAgICAgICB1bmlxdWUgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKHVuaXF1ZSl7Ci0gICAgICAgICAgICAgICAgZlByZWZpeGVzW2NvdW50KytdID0gcHJlZml4OwotICAgICAgICAgICAgfQotICAgICAgICAgICAgdW5pcXVlID0gdHJ1ZTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbmV3IEl0ZXJhdG9yUHJlZml4ZXMoZlByZWZpeGVzLCBjb3VudCk7Ci0gICAgfS8vZ2V0UHJlZml4ZXMKLSAgICAvKioKLSAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLk5hbWVzcGFjZUNvbnRleHQjZ2V0QWxsUHJlZml4ZXMoKQotICAgICAqLwotICAgIHB1YmxpYyBFbnVtZXJhdGlvbiBnZXRBbGxQcmVmaXhlcygpIHsKLSAgICAgICAgaW50IGNvdW50ID0gMDsKLSAgICAgICAgaWYgKGZQcmVmaXhlcy5sZW5ndGggPCAoZk5hbWVzcGFjZS5sZW5ndGgvMikpIHsKLSAgICAgICAgICAgIC8vIHJlc2l6ZSBwcmVmaXggYXJyYXkKLSAgICAgICAgICAgIFN0cmluZ1tdIHByZWZpeGVzID0gbmV3IFN0cmluZ1tmTmFtZXNwYWNlU2l6ZV07Ci0gICAgICAgICAgICBmUHJlZml4ZXMgPSBwcmVmaXhlczsKLSAgICAgICAgfQotICAgICAgICBTdHJpbmcgcHJlZml4ID0gbnVsbDsKLSAgICAgICAgYm9vbGVhbiB1bmlxdWUgPSB0cnVlOwotICAgICAgICBmb3IgKGludCBpID0gMjsgaSA8IChmTmFtZXNwYWNlU2l6ZS0yKTsgaSArPSAyKSB7Ci0gICAgICAgICAgICBwcmVmaXggPSBmTmFtZXNwYWNlW2kgKyAyXTsKLSAgICAgICAgICAgIGZvciAoaW50IGs9MDtrPGNvdW50O2srKyl7Ci0gICAgICAgICAgICAgICAgaWYgKGZQcmVmaXhlc1trXT09cHJlZml4KXsKLSAgICAgICAgICAgICAgICAgICAgdW5pcXVlID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmICh1bmlxdWUpewotICAgICAgICAgICAgICAgIGZQcmVmaXhlc1tjb3VudCsrXSA9IHByZWZpeDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHVuaXF1ZSA9IHRydWU7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG5ldyBQcmVmaXhlcyhmUHJlZml4ZXMsIGNvdW50KTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgIFZlY3RvciBnZXRQcmVmaXhlcyhTdHJpbmcgdXJpKXsKLSAgICAgICAgaW50IGNvdW50ID0gMDsKLSAgICAgICAgU3RyaW5nIHByZWZpeCA9IG51bGw7Ci0gICAgICAgIGJvb2xlYW4gdW5pcXVlID0gdHJ1ZTsKLSAgICAgICAgVmVjdG9yIHByZWZpeExpc3QgPSBuZXcgVmVjdG9yKCk7Ci0gICAgICAgIGZvciAoaW50IGkgPSBmTmFtZXNwYWNlU2l6ZTsgaSA+MCA7IGkgLT0gMikgewotICAgICAgICAgICAgaWYoZk5hbWVzcGFjZVtpLTFdID09IHVyaSl7Ci0gICAgICAgICAgICAgICAgaWYoIXByZWZpeExpc3QuY29udGFpbnMoZk5hbWVzcGFjZVtpLTJdKSkKLSAgICAgICAgICAgICAgICAgICAgcHJlZml4TGlzdC5hZGQoZk5hbWVzcGFjZVtpLTJdKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gcHJlZml4TGlzdDsKLSAgICB9Ci0KLSAgICAvKgotICAgICAqIG5vbi1OYW1lc3BhY2VDb250ZXh0IG1ldGhvZHMKLSAgICAgKi8KLQotICAgIC8qKgotICAgICAqIENoZWNrcyB3aGV0aGVyIGEgYmluZGluZyBvciB1bmJpbmRpbmcgZm9yCi0gICAgICogdGhlIGdpdmVuIHByZWZpeCBleGlzdHMgaW4gdGhlIGNvbnRleHQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcHJlZml4IFRoZSBwcmVmaXggdG8gbG9vayB1cC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgZ2l2ZW4gcHJlZml4IGV4aXN0cyBpbiB0aGUgY29udGV4dAotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zUHJlZml4KFN0cmluZyBwcmVmaXgpIHsKLQotICAgICAgICAvLyBmaW5kIHByZWZpeCBpbiBjb250ZXh0Ci0gICAgICAgIGZvciAoaW50IGkgPSBmTmFtZXNwYWNlU2l6ZTsgaSA+IDA7IGkgLT0gMikgewotICAgICAgICAgICAgaWYgKGZOYW1lc3BhY2VbaSAtIDJdID09IHByZWZpeCkgewotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gcHJlZml4IG5vdCBmb3VuZAotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ2hlY2tzIHdoZXRoZXIgYSBiaW5kaW5nIG9yIHVuYmluZGluZyBmb3IKLSAgICAgKiB0aGUgZ2l2ZW4gcHJlZml4IGV4aXN0cyBpbiB0aGUgY3VycmVudCBjb250ZXh0LgotICAgICAqCi0gICAgICogQHBhcmFtIHByZWZpeCBUaGUgcHJlZml4IHRvIGxvb2sgdXAuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGdpdmVuIHByZWZpeCBleGlzdHMgaW4gdGhlIGN1cnJlbnQgY29udGV4dAotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zUHJlZml4SW5DdXJyZW50Q29udGV4dChTdHJpbmcgcHJlZml4KSB7Ci0KLSAgICAgICAgLy8gZmluZCBwcmVmaXggaW4gY3VycmVudCBjb250ZXh0Ci0gICAgICAgIGZvciAoaW50IGkgPSBmQ29udGV4dFtmQ3VycmVudENvbnRleHRdOyBpIDwgZk5hbWVzcGFjZVNpemU7IGkgKz0gMikgewotICAgICAgICAgICAgaWYgKGZOYW1lc3BhY2VbaV0gPT0gcHJlZml4KSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBwcmVmaXggbm90IGZvdW5kCi0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICBwcm90ZWN0ZWQgZmluYWwgY2xhc3MgSXRlcmF0b3JQcmVmaXhlcyBpbXBsZW1lbnRzIEl0ZXJhdG9yICB7Ci0gICAgICAgIHByaXZhdGUgU3RyaW5nW10gcHJlZml4ZXM7Ci0gICAgICAgIHByaXZhdGUgaW50IGNvdW50ZXIgPSAwOwotICAgICAgICBwcml2YXRlIGludCBzaXplID0gMDsKLQotICAgICAgICAvKioKLSAgICAgICAgICogQ29uc3RydWN0b3IgZm9yIFByZWZpeGVzLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIEl0ZXJhdG9yUHJlZml4ZXMoU3RyaW5nIFtdIHByZWZpeGVzLCBpbnQgc2l6ZSkgewotICAgICAgICAgICAgdGhpcy5wcmVmaXhlcyA9IHByZWZpeGVzOwotICAgICAgICAgICAgdGhpcy5zaXplID0gc2l6ZTsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBAc2VlIGphdmEudXRpbC5FbnVtZXJhdGlvbiNoYXNNb3JlRWxlbWVudHMoKQotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzTmV4dCgpIHsKLSAgICAgICAgICAgIHJldHVybiAoY291bnRlciA8IHNpemUpOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIEBzZWUgamF2YS51dGlsLkVudW1lcmF0aW9uI25leHRFbGVtZW50KCkKLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBPYmplY3QgbmV4dCgpIHsKLSAgICAgICAgICAgIGlmIChjb3VudGVyPCBzaXplKXsKLSAgICAgICAgICAgICAgICByZXR1cm4gZlByZWZpeGVzW2NvdW50ZXIrK107Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbigiSWxsZWdhbCBhY2Nlc3MgdG8gTmFtZXNwYWNlIHByZWZpeGVzIGVudW1lcmF0aW9uLiIpOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpewotICAgICAgICAgICAgU3RyaW5nQnVmZmVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLSAgICAgICAgICAgIGZvciAoaW50IGk9MDtpPHNpemU7aSsrKXsKLSAgICAgICAgICAgICAgICBidWYuYXBwZW5kKHByZWZpeGVzW2ldKTsKLSAgICAgICAgICAgICAgICBidWYuYXBwZW5kKCIgIik7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIHJldHVybiBidWYudG9TdHJpbmcoKTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyB2b2lkIHJlbW92ZSgpewotICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIHByb3RlY3RlZCBmaW5hbCBjbGFzcyBQcmVmaXhlcyBpbXBsZW1lbnRzIEVudW1lcmF0aW9uIHsKLSAgICAgICAgcHJpdmF0ZSBTdHJpbmdbXSBwcmVmaXhlczsKLSAgICAgICAgcHJpdmF0ZSBpbnQgY291bnRlciA9IDA7Ci0gICAgICAgIHByaXZhdGUgaW50IHNpemUgPSAwOwotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBDb25zdHJ1Y3RvciBmb3IgUHJlZml4ZXMuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgUHJlZml4ZXMoU3RyaW5nIFtdIHByZWZpeGVzLCBpbnQgc2l6ZSkgewotICAgICAgICAgICAgdGhpcy5wcmVmaXhlcyA9IHByZWZpeGVzOwotICAgICAgICAgICAgdGhpcy5zaXplID0gc2l6ZTsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBAc2VlIGphdmEudXRpbC5FbnVtZXJhdGlvbiNoYXNNb3JlRWxlbWVudHMoKQotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzTW9yZUVsZW1lbnRzKCkgewotICAgICAgICAgICAgcmV0dXJuIChjb3VudGVyPCBzaXplKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBAc2VlIGphdmEudXRpbC5FbnVtZXJhdGlvbiNuZXh0RWxlbWVudCgpCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgT2JqZWN0IG5leHRFbGVtZW50KCkgewotICAgICAgICAgICAgaWYgKGNvdW50ZXI8IHNpemUpewotICAgICAgICAgICAgICAgIHJldHVybiBmUHJlZml4ZXNbY291bnRlcisrXTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uKCJJbGxlZ2FsIGFjY2VzcyB0byBOYW1lc3BhY2UgcHJlZml4ZXMgZW51bWVyYXRpb24uIik7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCl7Ci0gICAgICAgICAgICBTdHJpbmdCdWZmZXIgYnVmID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotICAgICAgICAgICAgZm9yIChpbnQgaT0wO2k8c2l6ZTtpKyspewotICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQocHJlZml4ZXNbaV0pOwotICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoIiAiKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgcmV0dXJuIGJ1Zi50b1N0cmluZygpOwotICAgICAgICB9Ci0KLQotICAgIH0KLQotfSAvLyBjbGFzcyBOYW1lc3BhY2VTdXBwb3J0CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL1BhcnNlckNvbmZpZ3VyYXRpb25TZXR0aW5ncy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9QYXJzZXJDb25maWd1cmF0aW9uU2V0dGluZ3MuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYTEzZDgxNS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL1BhcnNlckNvbmZpZ3VyYXRpb25TZXR0aW5ncy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzMyICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEsIDIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsOwotCi1pbXBvcnQgamF2YS51dGlsLkFycmF5czsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaFNldDsKLWltcG9ydCBqYXZhLnV0aWwuTWFwOwotaW1wb3J0IGphdmEudXRpbC5TZXQ7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxDb21wb25lbnRNYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgaW1wbGVtZW50cyB0aGUgYmFzaWMgb3BlcmF0aW9ucyBmb3IgbWFuYWdpbmcgcGFyc2VyCi0gKiBjb25maWd1cmF0aW9uIGZlYXR1cmVzIGFuZCBwcm9wZXJ0aWVzLiBUaGlzIHV0aWxpdHkgY2xhc3MgY2FuCi0gKiBiZSB1c2VkIGFzIGEgYmFzZSBjbGFzcyBmb3IgcGFyc2VyIGNvbmZpZ3VyYXRpb25zIG9yIHNlcGFyYXRlbHkKLSAqIHRvIGVuY2Fwc3VsYXRlIGEgbnVtYmVyIG9mIHBhcnNlciBzZXR0aW5ncyBhcyBhIGNvbXBvbmVudAotICogbWFuYWdlci4KLSAqIDxwPgotICogVGhpcyBjbGFzcyBjYW4gYmUgY29uc3RydWN0ZWQgd2l0aCBhICJwYXJlbnQiIHNldHRpbmdzIG9iamVjdAotICogKGluIHRoZSBmb3JtIG9mIGFuIDxjb2RlPlhNTENvbXBvbmVudE1hbmFnZXI8L2NvZGU+KSB0aGF0IGFsbG93cwotICogcGFyc2VyIGNvbmZpZ3VyYXRpb24gc2V0dGluZ3MgdG8gYmUgImNoYWluZWQiIHRvZ2V0aGVyLgotICoKLSAqIEBhdXRob3IgQW5keSBDbGFyaywgSUJNCi0gKgotICogQHZlcnNpb24gJElkOiBQYXJzZXJDb25maWd1cmF0aW9uU2V0dGluZ3MuamF2YSx2IDEuNiAyMDEwLTExLTAxIDA0OjQwOjE0IGpvZWh3IEV4cCAkCi0gKi8KLXB1YmxpYyBjbGFzcyBQYXJzZXJDb25maWd1cmF0aW9uU2V0dGluZ3MKLSAgICBpbXBsZW1lbnRzIFhNTENvbXBvbmVudE1hbmFnZXIgewotCi0gICAgICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFBBUlNFUl9TRVRUSU5HUyA9Ci0gICAgICAgICAgICAgICAgICAgICAgICBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLlBBUlNFUl9TRVRUSU5HUzsKLQotICAgIC8vCi0gICAgLy8gRGF0YQotICAgIC8vCi0KLSAgICAvLyBkYXRhCi0KLSAgICAvKiogUmVjb2duaXplZCBwcm9wZXJ0aWVzLiAqLwotICAgIHByb3RlY3RlZCBTZXQ8U3RyaW5nPiBmUmVjb2duaXplZFByb3BlcnRpZXM7Ci0KLSAgICAvKiogUHJvcGVydGllcy4gKi8KLSAgICBwcm90ZWN0ZWQgTWFwPFN0cmluZywgT2JqZWN0PiBmUHJvcGVydGllczsKLQotICAgIC8qKiBSZWNvZ25pemVkIGZlYXR1cmVzLiAqLwotICAgIHByb3RlY3RlZCBTZXQ8U3RyaW5nPiBmUmVjb2duaXplZEZlYXR1cmVzOwotCi0gICAgLyoqIEZlYXR1cmVzLiAqLwotICAgIHByb3RlY3RlZCBNYXA8U3RyaW5nLCBCb29sZWFuPiBmRmVhdHVyZXM7Ci0KLSAgICAvKiogUGFyZW50IHBhcnNlciBjb25maWd1cmF0aW9uIHNldHRpbmdzLiAqLwotICAgIHByb3RlY3RlZCBYTUxDb21wb25lbnRNYW5hZ2VyIGZQYXJlbnRTZXR0aW5nczsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKiBEZWZhdWx0IENvbnN0cnVjdG9yLiAqLwotICAgIHB1YmxpYyBQYXJzZXJDb25maWd1cmF0aW9uU2V0dGluZ3MoKSB7Ci0gICAgICAgIHRoaXMobnVsbCk7Ci0gICAgfSAvLyA8aW5pdD4oKQotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0cyBhIHBhcnNlciBjb25maWd1cmF0aW9uIHNldHRpbmdzIG9iamVjdCB3aXRoIGEKLSAgICAgKiBwYXJlbnQgc2V0dGluZ3Mgb2JqZWN0LgotICAgICAqLwotICAgIHB1YmxpYyBQYXJzZXJDb25maWd1cmF0aW9uU2V0dGluZ3MoWE1MQ29tcG9uZW50TWFuYWdlciBwYXJlbnQpIHsKLQotICAgICAgICAvLyBjcmVhdGUgc3RvcmFnZSBmb3IgcmVjb2duaXplZCBmZWF0dXJlcyBhbmQgcHJvcGVydGllcwotICAgICAgICBmUmVjb2duaXplZEZlYXR1cmVzID0gbmV3IEhhc2hTZXQ8U3RyaW5nPigpOwotICAgICAgICBmUmVjb2duaXplZFByb3BlcnRpZXMgPSBuZXcgSGFzaFNldDxTdHJpbmc+KCk7Ci0KLSAgICAgICAgLy8gY3JlYXRlIHRhYmxlIGZvciBmZWF0dXJlcyBhbmQgcHJvcGVydGllcwotICAgICAgICBmRmVhdHVyZXMgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIEJvb2xlYW4+KCk7Ci0gICAgICAgIGZQcm9wZXJ0aWVzID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBPYmplY3Q+KCk7Ci0KLSAgICAgICAgLy8gc2F2ZSBwYXJlbnQKLSAgICAgICAgZlBhcmVudFNldHRpbmdzID0gcGFyZW50OwotCi0gICAgfSAvLyA8aW5pdD4oWE1MQ29tcG9uZW50TWFuYWdlcikKLQotICAgIC8vCi0gICAgLy8gWE1MUGFyc2VyQ29uZmlndXJhdGlvbiBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIEFsbG93cyBhIHBhcnNlciB0byBhZGQgcGFyc2VyIHNwZWNpZmljIGZlYXR1cmVzIHRvIGJlIHJlY29nbml6ZWQKLSAgICAgKiBhbmQgbWFuYWdlZCBieSB0aGUgcGFyc2VyIGNvbmZpZ3VyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZmVhdHVyZUlkcyBBbiBhcnJheSBvZiB0aGUgYWRkaXRpb25hbCBmZWF0dXJlIGlkZW50aWZpZXJzCi0gICAgICogICAgICAgICAgICAgICAgICAgdG8gYmUgcmVjb2duaXplZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBhZGRSZWNvZ25pemVkRmVhdHVyZXMoU3RyaW5nW10gZmVhdHVyZUlkcykgewotCi0gICAgICAgIC8vIGFkZCByZWNvZ25pemVkIGZlYXR1cmVzCi0gICAgICAgIGludCBmZWF0dXJlSWRzQ291bnQgPSBmZWF0dXJlSWRzICE9IG51bGwgPyBmZWF0dXJlSWRzLmxlbmd0aCA6IDA7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmVhdHVyZUlkc0NvdW50OyBpKyspIHsKLSAgICAgICAgICAgIFN0cmluZyBmZWF0dXJlSWQgPSBmZWF0dXJlSWRzW2ldOwotICAgICAgICAgICAgaWYgKCFmUmVjb2duaXplZEZlYXR1cmVzLmNvbnRhaW5zKGZlYXR1cmVJZCkpIHsKLSAgICAgICAgICAgICAgICBmUmVjb2duaXplZEZlYXR1cmVzLmFkZChmZWF0dXJlSWQpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICB9IC8vIGFkZFJlY29nbml6ZWRGZWF0dXJlcyhTdHJpbmdbXSkKLQotICAgIC8qKgotICAgICAqIFNldCB0aGUgc3RhdGUgb2YgYSBmZWF0dXJlLgotICAgICAqCi0gICAgICogU2V0IHRoZSBzdGF0ZSBvZiBhbnkgZmVhdHVyZSBpbiBhIFNBWDIgcGFyc2VyLiAgVGhlIHBhcnNlcgotICAgICAqIG1pZ2h0IG5vdCByZWNvZ25pemUgdGhlIGZlYXR1cmUsIGFuZCBpZiBpdCBkb2VzIHJlY29nbml6ZQotICAgICAqIGl0LCBpdCBtaWdodCBub3QgYmUgYWJsZSB0byBmdWxmaWxsIHRoZSByZXF1ZXN0LgotICAgICAqCi0gICAgICogQHBhcmFtIGZlYXR1cmVJZCBUaGUgdW5pcXVlIGlkZW50aWZpZXIgKFVSSSkgb2YgdGhlIGZlYXR1cmUuCi0gICAgICogQHBhcmFtIHN0YXRlIFRoZSByZXF1ZXN0ZWQgc3RhdGUgb2YgdGhlIGZlYXR1cmUgKHRydWUgb3IgZmFsc2UpLgotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBJZiB0aGUKLSAgICAgKiAgICAgICAgICAgIHJlcXVlc3RlZCBmZWF0dXJlIGlzIG5vdCBrbm93bi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRGZWF0dXJlKFN0cmluZyBmZWF0dXJlSWQsIGJvb2xlYW4gc3RhdGUpCi0gICAgICAgIHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIHsKLQotICAgICAgICAvLyBjaGVjayBhbmQgc3RvcmUKLSAgICAgICAgRmVhdHVyZVN0YXRlIGNoZWNrU3RhdGUgPSBjaGVja0ZlYXR1cmUoZmVhdHVyZUlkKTsKLSAgICAgICAgaWYgKGNoZWNrU3RhdGUuaXNFeGNlcHRpb25hbCgpKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbihjaGVja1N0YXRlLnN0YXR1cywgZmVhdHVyZUlkKTsKLSAgICAgICAgfQotCi0gICAgICAgIGZGZWF0dXJlcy5wdXQoZmVhdHVyZUlkLCBzdGF0ZSk7Ci0gICAgfSAvLyBzZXRGZWF0dXJlKFN0cmluZyxib29sZWFuKQotCi0gICAgLyoqCi0gICAgICogQWxsb3dzIGEgcGFyc2VyIHRvIGFkZCBwYXJzZXIgc3BlY2lmaWMgcHJvcGVydGllcyB0byBiZSByZWNvZ25pemVkCi0gICAgICogYW5kIG1hbmFnZWQgYnkgdGhlIHBhcnNlciBjb25maWd1cmF0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIHByb3BlcnR5SWRzIEFuIGFycmF5IG9mIHRoZSBhZGRpdGlvbmFsIHByb3BlcnR5IGlkZW50aWZpZXJzCi0gICAgICogICAgICAgICAgICAgICAgICAgIHRvIGJlIHJlY29nbml6ZWQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgYWRkUmVjb2duaXplZFByb3BlcnRpZXMoU3RyaW5nW10gcHJvcGVydHlJZHMpIHsKLSAgICAgICAgZlJlY29nbml6ZWRQcm9wZXJ0aWVzLmFkZEFsbChBcnJheXMuYXNMaXN0KHByb3BlcnR5SWRzKSk7Ci0gICAgfSAvLyBhZGRSZWNvZ25pemVkUHJvcGVydGllcyhTdHJpbmdbXSkKLQotICAgIC8qKgotICAgICAqIHNldFByb3BlcnR5Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gcHJvcGVydHlJZAotICAgICAqIEBwYXJhbSB2YWx1ZQotICAgICAqIEBleGNlcHRpb24gY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gSWYgdGhlCi0gICAgICogICAgICAgICAgICByZXF1ZXN0ZWQgZmVhdHVyZSBpcyBub3Qga25vd24uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0UHJvcGVydHkoU3RyaW5nIHByb3BlcnR5SWQsIE9iamVjdCB2YWx1ZSkKLSAgICAgICAgdGhyb3dzIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gewotCi0gICAgICAgIC8vIGNoZWNrIGFuZCBzdG9yZQotICAgICAgICBQcm9wZXJ0eVN0YXRlIGNoZWNrU3RhdGUgPSBjaGVja1Byb3BlcnR5KHByb3BlcnR5SWQpOwotICAgICAgICBpZiAoY2hlY2tTdGF0ZS5pc0V4Y2VwdGlvbmFsKCkpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uKGNoZWNrU3RhdGUuc3RhdHVzLCBwcm9wZXJ0eUlkKTsKLSAgICAgICAgfQotICAgICAgICBmUHJvcGVydGllcy5wdXQocHJvcGVydHlJZCwgdmFsdWUpOwotCi0gICAgfSAvLyBzZXRQcm9wZXJ0eShTdHJpbmcsT2JqZWN0KQotCi0gICAgLy8KLSAgICAvLyBYTUxDb21wb25lbnRNYW5hZ2VyIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgc3RhdGUgb2YgYSBmZWF0dXJlLgotICAgICAqCi0gICAgICogQHBhcmFtIGZlYXR1cmVJZCBUaGUgZmVhdHVyZSBpZGVudGlmaWVyLgotICAgICAgICAgICAgICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgZmVhdHVyZSBpcyBzdXBwb3J0ZWQKLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBUaHJvd24gZm9yIGNvbmZpZ3VyYXRpb24gZXJyb3IuCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluIGdlbmVyYWwsIGNvbXBvbmVudHMgc2hvdWxkCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9ubHkgdGhyb3cgdGhpcyBleGNlcHRpb24gaWYKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXQgaXMgPHN0cm9uZz5yZWFsbHk8L3N0cm9uZz4KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYSBjcml0aWNhbCBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBnZXRGZWF0dXJlKFN0cmluZyBmZWF0dXJlSWQpCi0gICAgICAgIHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIHsKLQotICAgICAgICBGZWF0dXJlU3RhdGUgc3RhdGUgPSBnZXRGZWF0dXJlU3RhdGUoZmVhdHVyZUlkKTsKLSAgICAgICAgaWYgKHN0YXRlLmlzRXhjZXB0aW9uYWwoKSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24oc3RhdGUuc3RhdHVzLCBmZWF0dXJlSWQpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBzdGF0ZS5zdGF0ZTsKLSAgICB9IC8vIGdldEZlYXR1cmUoU3RyaW5nKTpib29sZWFuCi0KLSAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBnZXRGZWF0dXJlKFN0cmluZyBmZWF0dXJlSWQsIGJvb2xlYW4gZGVmYXVsdFZhbHVlKSB7Ci0gICAgICAgIEZlYXR1cmVTdGF0ZSBzdGF0ZSA9IGdldEZlYXR1cmVTdGF0ZShmZWF0dXJlSWQpOwotICAgICAgICBpZiAoc3RhdGUuaXNFeGNlcHRpb25hbCgpKSB7Ci0gICAgICAgICAgICByZXR1cm4gZGVmYXVsdFZhbHVlOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBzdGF0ZS5zdGF0ZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgRmVhdHVyZVN0YXRlIGdldEZlYXR1cmVTdGF0ZShTdHJpbmcgZmVhdHVyZUlkKSB7Ci0gICAgICAgIEJvb2xlYW4gc3RhdGUgPSAoQm9vbGVhbikgZkZlYXR1cmVzLmdldChmZWF0dXJlSWQpOwotCi0gICAgICAgIGlmIChzdGF0ZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBGZWF0dXJlU3RhdGUgY2hlY2tTdGF0ZSA9IGNoZWNrRmVhdHVyZShmZWF0dXJlSWQpOwotICAgICAgICAgICAgaWYgKGNoZWNrU3RhdGUuaXNFeGNlcHRpb25hbCgpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGNoZWNrU3RhdGU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gRmVhdHVyZVN0YXRlLmlzKGZhbHNlKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gRmVhdHVyZVN0YXRlLmlzKHN0YXRlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiBhIHByb3BlcnR5LgotICAgICAqCi0gICAgICogQHBhcmFtIHByb3BlcnR5SWQgVGhlIHByb3BlcnR5IGlkZW50aWZpZXIuCi0gICAgICAgICAgICAgICAgICogQHJldHVybiB0aGUgdmFsdWUgb2YgdGhlIHByb3BlcnR5Ci0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gVGhyb3duIGZvciBjb25maWd1cmF0aW9uIGVycm9yLgotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbiBnZW5lcmFsLCBjb21wb25lbnRzIHNob3VsZAotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbmx5IHRocm93IHRoaXMgZXhjZXB0aW9uIGlmCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0IGlzIDxzdHJvbmc+cmVhbGx5PC9zdHJvbmc+Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGEgY3JpdGljYWwgZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIE9iamVjdCBnZXRQcm9wZXJ0eShTdHJpbmcgcHJvcGVydHlJZCkKLSAgICAgICAgdGhyb3dzIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gewotCi0gICAgICAgIFByb3BlcnR5U3RhdGUgc3RhdGUgPSBnZXRQcm9wZXJ0eVN0YXRlKHByb3BlcnR5SWQpOwotICAgICAgICBpZiAoc3RhdGUuaXNFeGNlcHRpb25hbCgpKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbihzdGF0ZS5zdGF0dXMsIHByb3BlcnR5SWQpOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIHN0YXRlLnN0YXRlOwotICAgIH0gLy8gZ2V0UHJvcGVydHkoU3RyaW5nKTpPYmplY3QKLQotICAgIHB1YmxpYyBmaW5hbCBPYmplY3QgZ2V0UHJvcGVydHkoU3RyaW5nIHByb3BlcnR5SWQsIE9iamVjdCBkZWZhdWx0VmFsdWUpIHsKLSAgICAgICAgUHJvcGVydHlTdGF0ZSBzdGF0ZSA9IGdldFByb3BlcnR5U3RhdGUocHJvcGVydHlJZCk7Ci0gICAgICAgIGlmIChzdGF0ZS5pc0V4Y2VwdGlvbmFsKCkpIHsKLSAgICAgICAgICAgIHJldHVybiBkZWZhdWx0VmFsdWU7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gc3RhdGUuc3RhdGU7Ci0gICAgfQotCi0gICAgcHVibGljIFByb3BlcnR5U3RhdGUgZ2V0UHJvcGVydHlTdGF0ZShTdHJpbmcgcHJvcGVydHlJZCkgewotICAgICAgICBPYmplY3QgcHJvcGVydHlWYWx1ZSA9IGZQcm9wZXJ0aWVzLmdldChwcm9wZXJ0eUlkKTsKLQotICAgICAgICBpZiAocHJvcGVydHlWYWx1ZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBQcm9wZXJ0eVN0YXRlIHN0YXRlID0gY2hlY2tQcm9wZXJ0eShwcm9wZXJ0eUlkKTsKLSAgICAgICAgICAgIGlmIChzdGF0ZS5pc0V4Y2VwdGlvbmFsKCkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gc3RhdGU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gUHJvcGVydHlTdGF0ZS5pcyhwcm9wZXJ0eVZhbHVlKTsKLSAgICB9Ci0KLSAgICAvLwotICAgIC8vIFByb3RlY3RlZCBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIENoZWNrIGEgZmVhdHVyZS4gSWYgZmVhdHVyZSBpcyBrbm93biBhbmQgc3VwcG9ydGVkLCB0aGlzIG1ldGhvZCBzaW1wbHkKLSAgICAgKiByZXR1cm5zLiBPdGhlcndpc2UsIHRoZSBhcHByb3ByaWF0ZSBleGNlcHRpb24gaXMgdGhyb3duLgotICAgICAqCi0gICAgICogQHBhcmFtIGZlYXR1cmVJZCBUaGUgdW5pcXVlIGlkZW50aWZpZXIgKFVSSSkgb2YgdGhlIGZlYXR1cmUuCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIElmIHRoZQotICAgICAqICAgICAgICAgICAgcmVxdWVzdGVkIGZlYXR1cmUgaXMgbm90IGtub3duLgotICAgICAqLwotICAgIHByb3RlY3RlZCBGZWF0dXJlU3RhdGUgY2hlY2tGZWF0dXJlKFN0cmluZyBmZWF0dXJlSWQpCi0gICAgICAgIHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIHsKLQotICAgICAgICAvLyBjaGVjayBmZWF0dXJlCi0gICAgICAgIGlmICghZlJlY29nbml6ZWRGZWF0dXJlcy5jb250YWlucyhmZWF0dXJlSWQpKSB7Ci0gICAgICAgICAgICBpZiAoZlBhcmVudFNldHRpbmdzICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZlBhcmVudFNldHRpbmdzLmdldEZlYXR1cmVTdGF0ZShmZWF0dXJlSWQpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIEZlYXR1cmVTdGF0ZS5OT1RfUkVDT0dOSVpFRDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIFRPRE86IHJlYXNvbmFibGUgZGVmYXVsdD8KLSAgICAgICAgcmV0dXJuIEZlYXR1cmVTdGF0ZS5SRUNPR05JWkVEOwotICAgIH0gLy8gY2hlY2tGZWF0dXJlKFN0cmluZykKLQotICAgIC8qKgotICAgICAqIENoZWNrIGEgcHJvcGVydHkuIElmIHRoZSBwcm9wZXJ0eSBpcyBrbm93biBhbmQgc3VwcG9ydGVkLCB0aGlzIG1ldGhvZAotICAgICAqIHNpbXBseSByZXR1cm5zLiBPdGhlcndpc2UsIHRoZSBhcHByb3ByaWF0ZSBleGNlcHRpb24gaXMgdGhyb3duLgotICAgICAqCi0gICAgICogQHBhcmFtIHByb3BlcnR5SWQgVGhlIHVuaXF1ZSBpZGVudGlmaWVyIChVUkkpIG9mIHRoZSBwcm9wZXJ0eQotICAgICAqICAgICAgICAgICAgICAgICAgIGJlaW5nIHNldC4KLSAgICAgKiBAZXhjZXB0aW9uIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIElmIHRoZQotICAgICAqICAgICAgICAgICAgcmVxdWVzdGVkIGZlYXR1cmUgaXMgbm90IGtub3duLgotICAgICAqLwotICAgIHByb3RlY3RlZCBQcm9wZXJ0eVN0YXRlIGNoZWNrUHJvcGVydHkoU3RyaW5nIHByb3BlcnR5SWQpCi0gICAgICAgIHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIHsKLQotICAgICAgICAvLyBjaGVjayBwcm9wZXJ0eQotICAgICAgICBpZiAoIWZSZWNvZ25pemVkUHJvcGVydGllcy5jb250YWlucyhwcm9wZXJ0eUlkKSkgewotICAgICAgICAgICAgaWYgKGZQYXJlbnRTZXR0aW5ncyAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgUHJvcGVydHlTdGF0ZSBzdGF0ZSA9IGZQYXJlbnRTZXR0aW5ncy5nZXRQcm9wZXJ0eVN0YXRlKHByb3BlcnR5SWQpOwotICAgICAgICAgICAgICAgIGlmIChzdGF0ZS5pc0V4Y2VwdGlvbmFsKCkpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN0YXRlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIHJldHVybiBQcm9wZXJ0eVN0YXRlLk5PVF9SRUNPR05JWkVEOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBQcm9wZXJ0eVN0YXRlLlJFQ09HTklaRUQ7Ci0gICAgfSAvLyBjaGVja1Byb3BlcnR5KFN0cmluZykKLQotfSAvLyBjbGFzcyBQYXJzZXJDb25maWd1cmF0aW9uU2V0dGluZ3MKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3V0aWwvUHJpbWVOdW1iZXJTZXF1ZW5jZUdlbmVyYXRvci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9QcmltZU51bWJlclNlcXVlbmNlR2VuZXJhdG9yLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDJkZDk1NDguLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9QcmltZU51bWJlclNlcXVlbmNlR2VuZXJhdG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0NSArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDE1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICovCi0vKgotICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCi0gKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKLSAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KLSAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCi0gKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAotICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbDsKLQotaW1wb3J0IGphdmEudXRpbC5SYW5kb207Ci0KLSAvKioKLSAqIEZpbGxzIGFuIGFycmF5IHdpdGggYSByYW5kb20gc2VxdWVuY2Ugb2YgcHJpbWUgbnVtYmVycy4KLSAgKi8KLWZpbmFsIGNsYXNzIFByaW1lTnVtYmVyU2VxdWVuY2VHZW5lcmF0b3IgewotCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFtdIFBSSU1FUyA9IHsKLSAgICAgICAgMywgICA1LCAgIDcsICAxMSwgIDEzLCAgMTcsICAxOSwgIDIzLCAgMjksICAzMSwgIDM3LCAgNDEsICA0MywgIDQ3LCAgNTMsICA1OSwKLSAgICAgICA2MSwgIDY3LCAgNzEsICA3MywgIDc5LCAgODMsICA4OSwgIDk3LCAxMDEsIDEwMywgMTA3LCAxMDksIDExMywgMTI3LCAxMzEsIDEzNywKLSAgICAgIDEzOSwgMTQ5LCAxNTEsIDE1NywgMTYzLCAxNjcsIDE3MywgMTc5LCAxODEsIDE5MSwgMTkzLCAxOTcsIDE5OSwgMjExLCAyMjMsIDIyNywKLSAgICAgIDIyOSwgMjMzLCAyMzksIDI0MSwgMjUxLCAyNTcsIDI2MywgMjY5LCAyNzEsIDI3NywgMjgxLCAyODMsIDI5MywgMzA3LCAzMTEsIDMxMywKLSAgICAgIDMxNywgMzMxLCAzMzcsIDM0NywgMzQ5LCAzNTMsIDM1OSwgMzY3LCAzNzMsIDM3OSwgMzgzLCAzODksIDM5NywgNDAxLCA0MDksIDQxOSwKLSAgICAgIDQyMSwgNDMxLCA0MzMsIDQzOSwgNDQzLCA0NDksIDQ1NywgNDYxLCA0NjMsIDQ2NywgNDc5LCA0ODcsIDQ5MSwgNDk5LCA1MDMsIDUwOSwKLSAgICAgIDUyMSwgNTIzLCA1NDEsIDU0NywgNTU3LCA1NjMsIDU2OSwgNTcxLCA1NzcsIDU4NywgNTkzLCA1OTksIDYwMSwgNjA3LCA2MTMsIDYxNywKLSAgICAgIDYxOSwgNjMxLCA2NDEsIDY0MywgNjQ3LCA2NTMsIDY1OSwgNjYxLCA2NzMsIDY3NywgNjgzLCA2OTEsIDcwMSwgNzA5LCA3MTksIDcyN307Ci0KLSAgICBzdGF0aWMgdm9pZCBnZW5lcmF0ZVNlcXVlbmNlKGludFtdIGFycmF5VG9GaWxsKSB7Ci0gICAgICAgIFJhbmRvbSByID0gbmV3IFJhbmRvbSgpOwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGFycmF5VG9GaWxsLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICBhcnJheVRvRmlsbFtpXSA9IFBSSU1FU1tyLm5leHRJbnQoUFJJTUVTLmxlbmd0aCldOwotICAgICAgICB9Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9Qcm9wZXJ0eVN0YXRlLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL1Byb3BlcnR5U3RhdGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNWUxMzNjYS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL1Byb3BlcnR5U3RhdGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDYyICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDkgYnkgT3JhY2xlIENvcnBvcmF0aW9uLiBBbGwgUmlnaHRzIFJlc2VydmVkLgotICovCi0KLS8qCi0gKiAkSWQ6IFByb3BlcnR5U3RhdGUuamF2YSAzMDI0IDIwMTEtMDMtMDEgMDM6NDY6MTNaIGpvZWh3ICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWw7Ci0KLXB1YmxpYyBjbGFzcyBQcm9wZXJ0eVN0YXRlIHsKLQotICAgIHB1YmxpYyBmaW5hbCBTdGF0dXMgc3RhdHVzOwotICAgIHB1YmxpYyBmaW5hbCBPYmplY3Qgc3RhdGU7Ci0KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFByb3BlcnR5U3RhdGUgVU5LTk9XTiA9IG5ldyBQcm9wZXJ0eVN0YXRlKFN0YXR1cy5VTktOT1dOLCBudWxsKTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFByb3BlcnR5U3RhdGUgUkVDT0dOSVpFRCA9IG5ldyBQcm9wZXJ0eVN0YXRlKFN0YXR1cy5SRUNPR05JWkVELCBudWxsKTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFByb3BlcnR5U3RhdGUgTk9UX1NVUFBPUlRFRCA9IG5ldyBQcm9wZXJ0eVN0YXRlKFN0YXR1cy5OT1RfU1VQUE9SVEVELCBudWxsKTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFByb3BlcnR5U3RhdGUgTk9UX1JFQ09HTklaRUQgPSBuZXcgUHJvcGVydHlTdGF0ZShTdGF0dXMuTk9UX1JFQ09HTklaRUQsIG51bGwpOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgUHJvcGVydHlTdGF0ZSBOT1RfQUxMT1dFRCA9IG5ldyBQcm9wZXJ0eVN0YXRlKFN0YXR1cy5OT1RfQUxMT1dFRCwgbnVsbCk7Ci0KLQotICAgIHB1YmxpYyBQcm9wZXJ0eVN0YXRlKFN0YXR1cyBzdGF0dXMsIE9iamVjdCBzdGF0ZSkgewotICAgICAgICB0aGlzLnN0YXR1cyA9IHN0YXR1czsKLSAgICAgICAgdGhpcy5zdGF0ZSA9IHN0YXRlOwotICAgIH0KLQotICAgIHB1YmxpYyBzdGF0aWMgUHJvcGVydHlTdGF0ZSBvZihTdGF0dXMgc3RhdHVzKSB7Ci0gICAgICAgIHJldHVybiBuZXcgUHJvcGVydHlTdGF0ZShzdGF0dXMsIG51bGwpOwotICAgIH0KLQotICAgIHB1YmxpYyBzdGF0aWMgUHJvcGVydHlTdGF0ZSBpcyhPYmplY3QgdmFsdWUpIHsKLSAgICAgICAgcmV0dXJuIG5ldyBQcm9wZXJ0eVN0YXRlKFN0YXR1cy5TRVQsIHZhbHVlKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0V4Y2VwdGlvbmFsKCkgewotICAgICAgICByZXR1cm4gdGhpcy5zdGF0dXMuaXNFeGNlcHRpb25hbCgpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3V0aWwvU0FYMlhOSS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9TQVgyWE5JLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGIwMDE3ZTYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9TQVgyWE5JLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyNTYgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMC0yMDAyIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGVyY2VzIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBJbnRlcm5hdGlvbmFsCi0gKiBCdXNpbmVzcyBNYWNoaW5lcywgSW5jLiwgaHR0cDovL3d3dy5hcGFjaGUub3JnLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbDsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy51dGlsLlNpbXBsZUxvY2F0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5qYXhwLnZhbGlkYXRpb24uV3JhcHBlZFNBWEV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5RTmFtZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxBdHRyaWJ1dGVzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTERvY3VtZW50SGFuZGxlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxMb2NhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTFN0cmluZzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MRG9jdW1lbnRTb3VyY2U7Ci1pbXBvcnQgb3JnLnhtbC5zYXguQXR0cmlidXRlczsKLWltcG9ydCBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5Mb2NhdG9yOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKLQotLyoqCi0gKiBSZWNldmVzIFNBWCB7QGxpbmsgQ29udGVudEhhbmRsZXJ9IGV2ZW50cwotICogYW5kIHByb2R1Y2VzIHRoZSBlcXVpdmFsZW50IHtAbGluayBYTUxEb2N1bWVudEhhbmRsZXJ9IGV2ZW50cy4KLSAqCi0gKiBAYXV0aG9yCi0gKiAgICAgS29oc3VrZSBLYXdhZ3VjaGkgKGtvaHN1a2Uua2F3YWd1Y2hpQHN1bi5jb20pCi0gKi8KLXB1YmxpYyBjbGFzcyBTQVgyWE5JIGltcGxlbWVudHMgQ29udGVudEhhbmRsZXIsIFhNTERvY3VtZW50U291cmNlIHsKLSAgICBwdWJsaWMgU0FYMlhOSSggWE1MRG9jdW1lbnRIYW5kbGVyIGNvcmUgKSB7Ci0gICAgICAgIHRoaXMuZkNvcmUgPSBjb3JlOwotICAgIH0KLQotICAgIHByaXZhdGUgWE1MRG9jdW1lbnRIYW5kbGVyIGZDb3JlOwotCi0gICAgcHJpdmF0ZSBmaW5hbCBOYW1lc3BhY2VTdXBwb3J0IG5zQ29udGV4dCA9IG5ldyBOYW1lc3BhY2VTdXBwb3J0KCk7Ci0gICAgcHJpdmF0ZSBmaW5hbCBTeW1ib2xUYWJsZSBzeW1ib2xUYWJsZSA9IG5ldyBTeW1ib2xUYWJsZSgpOwotCi0KLSAgICBwdWJsaWMgdm9pZCBzZXREb2N1bWVudEhhbmRsZXIoWE1MRG9jdW1lbnRIYW5kbGVyIGhhbmRsZXIpIHsKLSAgICAgICAgZkNvcmUgPSBoYW5kbGVyOwotICAgIH0KLQotICAgIHB1YmxpYyBYTUxEb2N1bWVudEhhbmRsZXIgZ2V0RG9jdW1lbnRIYW5kbGVyKCkgewotICAgICAgICByZXR1cm4gZkNvcmU7Ci0gICAgfQotCi0KLSAgICAvLwotICAgIC8vCi0gICAgLy8gQ29udGVudEhhbmRsZXIgaW1wbGVtZW50YXRpb24KLSAgICAvLwotICAgIC8vCi0gICAgcHVibGljIHZvaWQgc3RhcnREb2N1bWVudCgpIHRocm93cyBTQVhFeGNlcHRpb24gewotICAgICAgICB0cnkgewotICAgICAgICAgICAgbnNDb250ZXh0LnJlc2V0KCk7Ci0KLSAgICAgICAgICAgIFhNTExvY2F0b3IgeG1sTG9jYXRvcjsKLSAgICAgICAgICAgIGlmKGxvY2F0b3I9PW51bGwpCi0gICAgICAgICAgICAgICAgLy8gc29tZSBTQVggc291cmNlIGRvZXNuJ3QgcHJvdmlkZSBhIGxvY2F0b3IsCi0gICAgICAgICAgICAgICAgLy8gaW4gd2hpY2ggY2FzZSB3ZSBhc3N1bWUgbm8gbGluZSBpbmZvcm1hdGlvbiBpcyBhdmFpbGFibGUKLSAgICAgICAgICAgICAgICAvLyBhbmQgdXNlIGEgZHVtbXkgbG9jYXRvci4gV2l0aCB0aGlzLCBkb3duc3RyZWFtIGNvbXBvbmVudHMKLSAgICAgICAgICAgICAgICAvLyBjYW4gYWx3YXlzIGFzc3VtZSB0aGF0IHRoZXkgd2lsbCBnZXQgYSBub24tbnVsbCBMb2NhdG9yLgotICAgICAgICAgICAgICAgIHhtbExvY2F0b3I9bmV3IFNpbXBsZUxvY2F0b3IobnVsbCxudWxsLC0xLC0xKTsKLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICB4bWxMb2NhdG9yPW5ldyBMb2NhdG9yV3JhcHBlcihsb2NhdG9yKTsKLQotICAgICAgICAgICAgZkNvcmUuc3RhcnREb2N1bWVudCgKLSAgICAgICAgICAgICAgICAgICAgeG1sTG9jYXRvciwKLSAgICAgICAgICAgICAgICAgICAgbnVsbCwKLSAgICAgICAgICAgICAgICAgICAgbnNDb250ZXh0LAotICAgICAgICAgICAgICAgICAgICBudWxsKTsKLSAgICAgICAgfSBjYXRjaCggV3JhcHBlZFNBWEV4Y2VwdGlvbiBlICkgewotICAgICAgICAgICAgdGhyb3cgZS5leGNlcHRpb247Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBlbmREb2N1bWVudCgpIHRocm93cyBTQVhFeGNlcHRpb24gewotICAgICAgICB0cnkgewotICAgICAgICAgICAgZkNvcmUuZW5kRG9jdW1lbnQobnVsbCk7Ci0gICAgICAgIH0gY2F0Y2goIFdyYXBwZWRTQVhFeGNlcHRpb24gZSApIHsKLSAgICAgICAgICAgIHRocm93IGUuZXhjZXB0aW9uOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc3RhcnRFbGVtZW50KCBTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWwsIFN0cmluZyBxbmFtZSwgQXR0cmlidXRlcyBhdHQgKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGZDb3JlLnN0YXJ0RWxlbWVudChjcmVhdGVRTmFtZSh1cmksbG9jYWwscW5hbWUpLGNyZWF0ZUF0dHJpYnV0ZXMoYXR0KSxudWxsKTsKLSAgICAgICAgfSBjYXRjaCggV3JhcHBlZFNBWEV4Y2VwdGlvbiBlICkgewotICAgICAgICAgICAgdGhyb3cgZS5leGNlcHRpb247Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBlbmRFbGVtZW50KCBTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWwsIFN0cmluZyBxbmFtZSApIHRocm93cyBTQVhFeGNlcHRpb24gewotICAgICAgICB0cnkgewotICAgICAgICAgICAgZkNvcmUuZW5kRWxlbWVudChjcmVhdGVRTmFtZSh1cmksbG9jYWwscW5hbWUpLG51bGwpOwotICAgICAgICB9IGNhdGNoKCBXcmFwcGVkU0FYRXhjZXB0aW9uIGUgKSB7Ci0gICAgICAgICAgICB0aHJvdyBlLmV4Y2VwdGlvbjsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGNoYXJhY3RlcnMoIGNoYXJbXSBidWYsIGludCBvZmZzZXQsIGludCBsZW4gKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGZDb3JlLmNoYXJhY3RlcnMobmV3IFhNTFN0cmluZyhidWYsb2Zmc2V0LGxlbiksbnVsbCk7Ci0gICAgICAgIH0gY2F0Y2goIFdyYXBwZWRTQVhFeGNlcHRpb24gZSApIHsKLSAgICAgICAgICAgIHRocm93IGUuZXhjZXB0aW9uOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgaWdub3JhYmxlV2hpdGVzcGFjZSggY2hhcltdIGJ1ZiwgaW50IG9mZnNldCwgaW50IGxlbiApIHRocm93cyBTQVhFeGNlcHRpb24gewotICAgICAgICB0cnkgewotICAgICAgICAgICAgZkNvcmUuaWdub3JhYmxlV2hpdGVzcGFjZShuZXcgWE1MU3RyaW5nKGJ1ZixvZmZzZXQsbGVuKSxudWxsKTsKLSAgICAgICAgfSBjYXRjaCggV3JhcHBlZFNBWEV4Y2VwdGlvbiBlICkgewotICAgICAgICAgICAgdGhyb3cgZS5leGNlcHRpb247Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzdGFydFByZWZpeE1hcHBpbmcoIFN0cmluZyBwcmVmaXgsIFN0cmluZyB1cmkgKSB7Ci0gICAgICAgIG5zQ29udGV4dC5wdXNoQ29udGV4dCgpOwotICAgICAgICBuc0NvbnRleHQuZGVjbGFyZVByZWZpeChwcmVmaXgsdXJpKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBlbmRQcmVmaXhNYXBwaW5nKCBTdHJpbmcgcHJlZml4ICkgewotICAgICAgICBuc0NvbnRleHQucG9wQ29udGV4dCgpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHByb2Nlc3NpbmdJbnN0cnVjdGlvbiggU3RyaW5nIHRhcmdldCwgU3RyaW5nIGRhdGEgKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGZDb3JlLnByb2Nlc3NpbmdJbnN0cnVjdGlvbigKLSAgICAgICAgICAgICAgICAgICAgc3ltYm9saXplKHRhcmdldCksY3JlYXRlWE1MU3RyaW5nKGRhdGEpLG51bGwpOwotICAgICAgICB9IGNhdGNoKCBXcmFwcGVkU0FYRXhjZXB0aW9uIGUgKSB7Ci0gICAgICAgICAgICB0aHJvdyBlLmV4Y2VwdGlvbjsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNraXBwZWRFbnRpdHkoIFN0cmluZyBuYW1lICkgewotICAgIH0KLQotICAgIHByaXZhdGUgTG9jYXRvciBsb2NhdG9yOwotICAgIHB1YmxpYyB2b2lkIHNldERvY3VtZW50TG9jYXRvciggTG9jYXRvciBfbG9jICkgewotICAgICAgICB0aGlzLmxvY2F0b3IgPSBfbG9jOwotICAgIH0KLQotICAgIC8qKiBDcmVhdGVzIGEgUU5hbWUgb2JqZWN0LiAqLwotICAgIHByaXZhdGUgUU5hbWUgY3JlYXRlUU5hbWUoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsLCBTdHJpbmcgcmF3KSB7Ci0KLSAgICAgICAgaW50IGlkeCA9IHJhdy5pbmRleE9mKCc6Jyk7Ci0KLSAgICAgICAgaWYoIGxvY2FsLmxlbmd0aCgpPT0wICkgewotICAgICAgICAgICAgLy8gaWYgbmFlbXNwYWNlIHByb2Nlc3NpbmcgaXMgdHVybmVkIG9mZiwgbG9jYWwgY291bGQgYmUgIiIuCi0gICAgICAgICAgICAvLyBpbiB0aGF0IGNhc2UsIHRyZWF0IGV2ZXJ5dGhpbmcgdG8gYmUgaW4gdGhlIG5vIG5hbWVzcGFjZS4KLSAgICAgICAgICAgIHVyaSA9ICIiOwotICAgICAgICAgICAgaWYoaWR4PDApCi0gICAgICAgICAgICAgICAgbG9jYWwgPSByYXc7Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgbG9jYWwgPSByYXcuc3Vic3RyaW5nKGlkeCsxKTsKLSAgICAgICAgfQotCi0gICAgICAgIFN0cmluZyBwcmVmaXg7Ci0gICAgICAgIGlmIChpZHggPCAwKQotICAgICAgICAgICAgcHJlZml4ID0gbnVsbDsKLSAgICAgICAgZWxzZQotICAgICAgICAgICAgcHJlZml4ID0gcmF3LnN1YnN0cmluZygwLCBpZHgpOwotCi0gICAgICAgIGlmICh1cmkgIT0gbnVsbCAmJiB1cmkubGVuZ3RoKCkgPT0gMCkKLSAgICAgICAgICAgIHVyaSA9IG51bGw7IC8vIFhOSSB1c2VzIG51bGwgd2hlcmVhcyBTQVggdXNlcyB0aGUgZW1wdHkgc3RyaW5nCi0KLSAgICAgICAgcmV0dXJuIG5ldyBRTmFtZShzeW1ib2xpemUocHJlZml4KSwgc3ltYm9saXplKGxvY2FsKSwgc3ltYm9saXplKHJhdyksIHN5bWJvbGl6ZSh1cmkpKTsKLSAgICB9Ci0KLSAgICAvKiogU3ltYm9saXplcyB0aGUgc3BlY2lmaWVkIHN0cmluZy4gKi8KLSAgICBwcml2YXRlIFN0cmluZyBzeW1ib2xpemUoU3RyaW5nIHMpIHsKLSAgICAgICAgaWYgKHMgPT0gbnVsbCkKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICBlbHNlCi0gICAgICAgICAgICByZXR1cm4gc3ltYm9sVGFibGUuYWRkU3ltYm9sKHMpOwotICAgIH0KLQotICAgIHByaXZhdGUgWE1MU3RyaW5nIGNyZWF0ZVhNTFN0cmluZyhTdHJpbmcgc3RyKSB7Ci0gICAgICAgIC8vIHdpdGggbXkgcGF0Y2gKLSAgICAgICAgLy8gcmV0dXJuIG5ldyBYTUxTdHJpbmcoc3RyKTsKLQotICAgICAgICAvLyBmb3Igbm93Ci0gICAgICAgIHJldHVybiBuZXcgWE1MU3RyaW5nKHN0ci50b0NoYXJBcnJheSgpLCAwLCBzdHIubGVuZ3RoKCkpOwotICAgIH0KLQotCi0gICAgLyoqIG9ubHkgb25lIGluc3RhbmNlIG9mIFhNTEF0dHJpYnV0ZXMgaXMgdXNlZC4gKi8KLSAgICBwcml2YXRlIGZpbmFsIFhNTEF0dHJpYnV0ZXMgeGEgPSBuZXcgWE1MQXR0cmlidXRlc0ltcGwoKTsKLQotICAgIC8qKiBDcmVhdGVzIGFuIFhNTEF0dHJpYnV0ZXMgb2JqZWN0LiAqLwotICAgIHByaXZhdGUgWE1MQXR0cmlidXRlcyBjcmVhdGVBdHRyaWJ1dGVzKEF0dHJpYnV0ZXMgYXR0KSB7Ci0gICAgICAgIHhhLnJlbW92ZUFsbEF0dHJpYnV0ZXMoKTsKLSAgICAgICAgaW50IGxlbiA9IGF0dC5nZXRMZW5ndGgoKTsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW47IGkrKykKLSAgICAgICAgICAgIHhhLmFkZEF0dHJpYnV0ZSgKLSAgICAgICAgICAgICAgICAgICAgY3JlYXRlUU5hbWUoYXR0LmdldFVSSShpKSwgYXR0LmdldExvY2FsTmFtZShpKSwgYXR0LmdldFFOYW1lKGkpKSwKLSAgICAgICAgICAgICAgICAgICAgYXR0LmdldFR5cGUoaSksCi0gICAgICAgICAgICAgICAgICAgIGF0dC5nZXRWYWx1ZShpKSk7Ci0gICAgICAgIHJldHVybiB4YTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL1NBWElucHV0U291cmNlLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL1NBWElucHV0U291cmNlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDU0MDQ0MGEuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9TQVhJbnB1dFNvdXJjZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTY0ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbDsKLQotaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5pby5SZWFkZXI7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MSW5wdXRTb3VyY2U7Ci1pbXBvcnQgb3JnLnhtbC5zYXguSW5wdXRTb3VyY2U7Ci1pbXBvcnQgb3JnLnhtbC5zYXguWE1MUmVhZGVyOwotCi0vKioKLSAqIDxwPkFuIDxjb2RlPlhNTElucHV0U291cmNlPC9jb2RlPiBhbmFsb2d1ZSB0byA8Y29kZT5qYXZheC54bWwudHJhbnNmb3JtLnNheC5TQVhTb3VyY2U8L2NvZGU+LjwvcD4KLSAqCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBTQVhJbnB1dFNvdXJjZSBleHRlbmRzIFhNTElucHV0U291cmNlIHsKLQotICAgIHByaXZhdGUgWE1MUmVhZGVyIGZYTUxSZWFkZXI7Ci0gICAgcHJpdmF0ZSBJbnB1dFNvdXJjZSBmSW5wdXRTb3VyY2U7Ci0KLSAgICBwdWJsaWMgU0FYSW5wdXRTb3VyY2UoKSB7Ci0gICAgICAgIHRoaXMobnVsbCk7Ci0gICAgfQotCi0gICAgcHVibGljIFNBWElucHV0U291cmNlKElucHV0U291cmNlIGlucHV0U291cmNlKSB7Ci0gICAgICAgIHRoaXMobnVsbCwgaW5wdXRTb3VyY2UpOwotICAgIH0KLQotICAgIHB1YmxpYyBTQVhJbnB1dFNvdXJjZShYTUxSZWFkZXIgcmVhZGVyLCBJbnB1dFNvdXJjZSBpbnB1dFNvdXJjZSkgewotICAgICAgICBzdXBlcihpbnB1dFNvdXJjZSAhPSBudWxsID8gaW5wdXRTb3VyY2UuZ2V0UHVibGljSWQoKSA6IG51bGwsCi0gICAgICAgICAgICAgICAgaW5wdXRTb3VyY2UgIT0gbnVsbCA/IGlucHV0U291cmNlLmdldFN5c3RlbUlkKCkgOiBudWxsLCBudWxsKTsKLSAgICAgICAgaWYgKGlucHV0U291cmNlICE9IG51bGwpIHsKLSAgICAgICAgICAgIHNldEJ5dGVTdHJlYW0oaW5wdXRTb3VyY2UuZ2V0Qnl0ZVN0cmVhbSgpKTsKLSAgICAgICAgICAgIHNldENoYXJhY3RlclN0cmVhbShpbnB1dFNvdXJjZS5nZXRDaGFyYWN0ZXJTdHJlYW0oKSk7Ci0gICAgICAgICAgICBzZXRFbmNvZGluZyhpbnB1dFNvdXJjZS5nZXRFbmNvZGluZygpKTsKLSAgICAgICAgfQotICAgICAgICBmSW5wdXRTb3VyY2UgPSBpbnB1dFNvdXJjZTsKLSAgICAgICAgZlhNTFJlYWRlciA9IHJlYWRlcjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRYTUxSZWFkZXIoWE1MUmVhZGVyIHJlYWRlcikgewotICAgICAgICBmWE1MUmVhZGVyID0gcmVhZGVyOwotICAgIH0KLQotICAgIHB1YmxpYyBYTUxSZWFkZXIgZ2V0WE1MUmVhZGVyKCkgewotICAgICAgICByZXR1cm4gZlhNTFJlYWRlcjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRJbnB1dFNvdXJjZShJbnB1dFNvdXJjZSBpbnB1dFNvdXJjZSkgewotICAgICAgICBpZiAoaW5wdXRTb3VyY2UgIT0gbnVsbCkgewotICAgICAgICAgICAgc2V0UHVibGljSWQoaW5wdXRTb3VyY2UuZ2V0UHVibGljSWQoKSk7Ci0gICAgICAgICAgICBzZXRTeXN0ZW1JZChpbnB1dFNvdXJjZS5nZXRTeXN0ZW1JZCgpKTsKLSAgICAgICAgICAgIHNldEJ5dGVTdHJlYW0oaW5wdXRTb3VyY2UuZ2V0Qnl0ZVN0cmVhbSgpKTsKLSAgICAgICAgICAgIHNldENoYXJhY3RlclN0cmVhbShpbnB1dFNvdXJjZS5nZXRDaGFyYWN0ZXJTdHJlYW0oKSk7Ci0gICAgICAgICAgICBzZXRFbmNvZGluZyhpbnB1dFNvdXJjZS5nZXRFbmNvZGluZygpKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHNldFB1YmxpY0lkKG51bGwpOwotICAgICAgICAgICAgc2V0U3lzdGVtSWQobnVsbCk7Ci0gICAgICAgICAgICBzZXRCeXRlU3RyZWFtKG51bGwpOwotICAgICAgICAgICAgc2V0Q2hhcmFjdGVyU3RyZWFtKG51bGwpOwotICAgICAgICAgICAgc2V0RW5jb2RpbmcobnVsbCk7Ci0gICAgICAgIH0KLSAgICAgICAgZklucHV0U291cmNlID0gaW5wdXRTb3VyY2U7Ci0gICAgfQotCi0gICAgcHVibGljIElucHV0U291cmNlIGdldElucHV0U291cmNlKCkgewotICAgICAgICByZXR1cm4gZklucHV0U291cmNlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIHB1YmxpYyBpZGVudGlmaWVyLgotICAgICAqCi0gICAgICogQHBhcmFtIHB1YmxpY0lkIFRoZSBuZXcgcHVibGljIGlkZW50aWZpZXIuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0UHVibGljSWQoU3RyaW5nIHB1YmxpY0lkKSB7Ci0gICAgICAgIHN1cGVyLnNldFB1YmxpY0lkKHB1YmxpY0lkKTsKLSAgICAgICAgaWYgKGZJbnB1dFNvdXJjZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBmSW5wdXRTb3VyY2UgPSBuZXcgSW5wdXRTb3VyY2UoKTsKLSAgICAgICAgfQotICAgICAgICBmSW5wdXRTb3VyY2Uuc2V0UHVibGljSWQocHVibGljSWQpOwotICAgIH0gLy8gc2V0UHVibGljSWQoU3RyaW5nKQotCi0gICAgLyoqCi0gICAgICogU2V0cyB0aGUgc3lzdGVtIGlkZW50aWZpZXIuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc3lzdGVtSWQgVGhlIG5ldyBzeXN0ZW0gaWRlbnRpZmllci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRTeXN0ZW1JZChTdHJpbmcgc3lzdGVtSWQpIHsKLSAgICAgICAgc3VwZXIuc2V0U3lzdGVtSWQoc3lzdGVtSWQpOwotICAgICAgICBpZiAoZklucHV0U291cmNlID09IG51bGwpIHsKLSAgICAgICAgICAgIGZJbnB1dFNvdXJjZSA9IG5ldyBJbnB1dFNvdXJjZSgpOwotICAgICAgICB9Ci0gICAgICAgIGZJbnB1dFNvdXJjZS5zZXRTeXN0ZW1JZChzeXN0ZW1JZCk7Ci0gICAgfSAvLyBzZXRTeXN0ZW1JZChTdHJpbmcpCi0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSBieXRlIHN0cmVhbS4gSWYgdGhlIGJ5dGUgc3RyZWFtIGlzIG5vdCBhbHJlYWR5IG9wZW5lZAotICAgICAqIHdoZW4gdGhpcyBvYmplY3QgaXMgaW5zdGFudGlhdGVkLCB0aGVuIHRoZSBjb2RlIHRoYXQgb3BlbnMgdGhlCi0gICAgICogc3RyZWFtIHNob3VsZCBhbHNvIHNldCB0aGUgYnl0ZSBzdHJlYW0gb24gdGhpcyBvYmplY3QuIEFsc28sIGlmCi0gICAgICogdGhlIGVuY29kaW5nIGlzIGF1dG8tZGV0ZWN0ZWQsIHRoZW4gdGhlIGVuY29kaW5nIHNob3VsZCBhbHNvIGJlCi0gICAgICogc2V0IG9uIHRoaXMgb2JqZWN0LgotICAgICAqCi0gICAgICogQHBhcmFtIGJ5dGVTdHJlYW0gVGhlIG5ldyBieXRlIHN0cmVhbS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRCeXRlU3RyZWFtKElucHV0U3RyZWFtIGJ5dGVTdHJlYW0pIHsKLSAgICAgICAgc3VwZXIuc2V0Qnl0ZVN0cmVhbShieXRlU3RyZWFtKTsKLSAgICAgICAgaWYgKGZJbnB1dFNvdXJjZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBmSW5wdXRTb3VyY2UgPSBuZXcgSW5wdXRTb3VyY2UoKTsKLSAgICAgICAgfQotICAgICAgICBmSW5wdXRTb3VyY2Uuc2V0Qnl0ZVN0cmVhbShieXRlU3RyZWFtKTsKLSAgICB9IC8vIHNldEJ5dGVTdHJlYW0oSW5wdXRTdHJlYW0pCi0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSBjaGFyYWN0ZXIgc3RyZWFtLiBJZiB0aGUgY2hhcmFjdGVyIHN0cmVhbSBpcyBub3QgYWxyZWFkeQotICAgICAqIG9wZW5lZCB3aGVuIHRoaXMgb2JqZWN0IGlzIGluc3RhbnRpYXRlZCwgdGhlbiB0aGUgY29kZSB0aGF0IG9wZW5zCi0gICAgICogdGhlIHN0cmVhbSBzaG91bGQgYWxzbyBzZXQgdGhlIGNoYXJhY3RlciBzdHJlYW0gb24gdGhpcyBvYmplY3QuCi0gICAgICogQWxzbywgdGhlIGVuY29kaW5nIG9mIHRoZSBieXRlIHN0cmVhbSB1c2VkIGJ5IHRoZSByZWFkZXIgc2hvdWxkCi0gICAgICogYWxzbyBiZSBzZXQgb24gdGhpcyBvYmplY3QsIGlmIGtub3duLgotICAgICAqCi0gICAgICogQHBhcmFtIGNoYXJTdHJlYW0gVGhlIG5ldyBjaGFyYWN0ZXIgc3RyZWFtLgotICAgICAqCi0gICAgICogQHNlZSAjc2V0RW5jb2RpbmcKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRDaGFyYWN0ZXJTdHJlYW0oUmVhZGVyIGNoYXJTdHJlYW0pIHsKLSAgICAgICAgc3VwZXIuc2V0Q2hhcmFjdGVyU3RyZWFtKGNoYXJTdHJlYW0pOwotICAgICAgICBpZiAoZklucHV0U291cmNlID09IG51bGwpIHsKLSAgICAgICAgICAgIGZJbnB1dFNvdXJjZSA9IG5ldyBJbnB1dFNvdXJjZSgpOwotICAgICAgICB9Ci0gICAgICAgIGZJbnB1dFNvdXJjZS5zZXRDaGFyYWN0ZXJTdHJlYW0oY2hhclN0cmVhbSk7Ci0gICAgfSAvLyBzZXRDaGFyYWN0ZXJTdHJlYW0oUmVhZGVyKQotCi0gICAgLyoqCi0gICAgICogU2V0cyB0aGUgZW5jb2Rpbmcgb2YgdGhlIHN0cmVhbS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlbmNvZGluZyBUaGUgbmV3IGVuY29kaW5nLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEVuY29kaW5nKFN0cmluZyBlbmNvZGluZykgewotICAgICAgICBzdXBlci5zZXRFbmNvZGluZyhlbmNvZGluZyk7Ci0gICAgICAgIGlmIChmSW5wdXRTb3VyY2UgPT0gbnVsbCkgewotICAgICAgICAgICAgZklucHV0U291cmNlID0gbmV3IElucHV0U291cmNlKCk7Ci0gICAgICAgIH0KLSAgICAgICAgZklucHV0U291cmNlLnNldEVuY29kaW5nKGVuY29kaW5nKTsKLSAgICB9IC8vIHNldEVuY29kaW5nKFN0cmluZykKLQotfSAvLyBTQVhJbnB1dFNvdXJjZQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9TQVhMb2NhdG9yV3JhcHBlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9TQVhMb2NhdG9yV3JhcHBlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1NzMzODQ1Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3V0aWwvU0FYTG9jYXRvcldyYXBwZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExMSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWw7Ci0KLWltcG9ydCBvcmcueG1sLnNheC5Mb2NhdG9yOwotaW1wb3J0IG9yZy54bWwuc2F4LmV4dC5Mb2NhdG9yMjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTExvY2F0b3I7Ci0KLS8qKgotICogPHA+QSBsaWdodCB3cmFwcGVyIGFyb3VuZCBhIFNBWCBsb2NhdG9yLiBUaGlzIGlzIHVzZWZ1bAotICogd2hlbiBicmlkZ2luZyBiZXR3ZWVuIFNBWCBhbmQgWE5JIGNvbXBvbmVudHMuPC9wPgotICoKLSAqIEBhdXRob3IgTWljaGFlbCBHbGF2YXNzZXZpY2gsIElCTQotICoKLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIFNBWExvY2F0b3JXcmFwcGVyIGltcGxlbWVudHMgWE1MTG9jYXRvciB7Ci0KLSAgICBwcml2YXRlIExvY2F0b3IgZkxvY2F0b3IgPSBudWxsOwotICAgIHByaXZhdGUgTG9jYXRvcjIgZkxvY2F0b3IyID0gbnVsbDsKLQotICAgIHB1YmxpYyBTQVhMb2NhdG9yV3JhcHBlcigpIHt9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRMb2NhdG9yKExvY2F0b3IgbG9jYXRvcikgewotICAgICAgICBmTG9jYXRvciA9IGxvY2F0b3I7Ci0gICAgICAgIGlmIChsb2NhdG9yIGluc3RhbmNlb2YgTG9jYXRvcjIgfHwgbG9jYXRvciA9PSBudWxsKSB7Ci0gICAgICAgICAgICBmTG9jYXRvcjIgPSAoTG9jYXRvcjIpIGxvY2F0b3I7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgTG9jYXRvciBnZXRMb2NhdG9yKCkgewotICAgICAgICByZXR1cm4gZkxvY2F0b3I7Ci0gICAgfQotCi0gICAgLyoKLSAgICAgKiBYTUxMb2NhdG9yIG1ldGhvZHMKLSAgICAgKi8KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0UHVibGljSWQoKSB7Ci0gICAgICAgIGlmIChmTG9jYXRvciAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gZkxvY2F0b3IuZ2V0UHVibGljSWQoKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldExpdGVyYWxTeXN0ZW1JZCgpIHsKLSAgICAgICAgaWYgKGZMb2NhdG9yICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBmTG9jYXRvci5nZXRTeXN0ZW1JZCgpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0QmFzZVN5c3RlbUlkKCkgewotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldEV4cGFuZGVkU3lzdGVtSWQoKSB7Ci0gICAgICAgIHJldHVybiBnZXRMaXRlcmFsU3lzdGVtSWQoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldExpbmVOdW1iZXIoKSB7Ci0gICAgICAgIGlmIChmTG9jYXRvciAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gZkxvY2F0b3IuZ2V0TGluZU51bWJlcigpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiAtMTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldENvbHVtbk51bWJlcigpIHsKLSAgICAgICAgaWYgKGZMb2NhdG9yICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBmTG9jYXRvci5nZXRDb2x1bW5OdW1iZXIoKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gLTE7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBnZXRDaGFyYWN0ZXJPZmZzZXQoKSB7Ci0gICAgICAgIHJldHVybiAtMTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldEVuY29kaW5nKCkgewotICAgICAgICBpZiAoZkxvY2F0b3IyICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBmTG9jYXRvcjIuZ2V0RW5jb2RpbmcoKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldFhNTFZlcnNpb24oKSB7Ci0gICAgICAgIGlmIChmTG9jYXRvcjIgIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIGZMb2NhdG9yMi5nZXRYTUxWZXJzaW9uKCk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi19IC8vIFNBWExvY2F0b3JXcmFwcGVyCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL1NBWE1lc3NhZ2VGb3JtYXR0ZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3V0aWwvU0FYTWVzc2FnZUZvcm1hdHRlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyOTY0OGE2Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3V0aWwvU0FYTWVzc2FnZUZvcm1hdHRlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTAyICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWw7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWxzLlNlY3VyaXR5U3VwcG9ydDsKLWltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwotaW1wb3J0IGphdmEudXRpbC5NaXNzaW5nUmVzb3VyY2VFeGNlcHRpb247Ci1pbXBvcnQgamF2YS51dGlsLlJlc291cmNlQnVuZGxlOwotCi0vKioKLSAqIFVzZWQgdG8gZm9ybWF0IFNBWCBlcnJvciBtZXNzYWdlcyB1c2luZyBhIHNwZWNpZmllZCBsb2NhbGUuCi0gKgotICogQGF1dGhvciBNaWNoYWVsIEdsYXZhc3NldmljaCwgSUJNCi0gKgotICogQHZlcnNpb24gJElkOiBTQVhNZXNzYWdlRm9ybWF0dGVyLmphdmEsdiAxLjYgMjAxMC0xMS0wMSAwNDo0MDoxNCBqb2VodyBFeHAgJAotICovCi1wdWJsaWMgY2xhc3MgU0FYTWVzc2FnZUZvcm1hdHRlciB7Ci0KLSAgICAvKioKLSAgICAgKiBGb3JtYXRzIGEgbWVzc2FnZSB3aXRoIHRoZSBzcGVjaWZpZWQgYXJndW1lbnRzIHVzaW5nIHRoZSBnaXZlbgotICAgICAqIGxvY2FsZSBpbmZvcm1hdGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBsb2NhbGUgICAgVGhlIGxvY2FsZSBvZiB0aGUgbWVzc2FnZS4KLSAgICAgKiBAcGFyYW0ga2V5ICAgICAgIFRoZSBtZXNzYWdlIGtleS4KLSAgICAgKiBAcGFyYW0gYXJndW1lbnRzIFRoZSBtZXNzYWdlIHJlcGxhY2VtZW50IHRleHQgYXJndW1lbnRzLiBUaGUgb3JkZXIKLSAgICAgKiAgICAgICAgICAgICAgICAgIG9mIHRoZSBhcmd1bWVudHMgbXVzdCBtYXRjaCB0aGF0IG9mIHRoZSBwbGFjZWhvbGRlcnMKLSAgICAgKiAgICAgICAgICAgICAgICAgIGluIHRoZSBhY3R1YWwgbWVzc2FnZS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gICAgICAgICAgdGhlIGZvcm1hdHRlZCBtZXNzYWdlLgotICAgICAqCi0gICAgICogQHRocm93cyBNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24gVGhyb3duIGlmIHRoZSBtZXNzYWdlIHdpdGggdGhlCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BlY2lmaWVkIGtleSBjYW5ub3QgYmUgZm91bmQuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZm9ybWF0TWVzc2FnZShMb2NhbGUgbG9jYWxlLAotICAgICAgICBTdHJpbmcga2V5LCBPYmplY3RbXSBhcmd1bWVudHMpCi0gICAgICAgIHRocm93cyBNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24gewotCi0gICAgICAgIFJlc291cmNlQnVuZGxlIHJlc291cmNlQnVuZGxlID0gbnVsbDsKLSAgICAgICAgaWYgKGxvY2FsZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXNvdXJjZUJ1bmRsZSA9Ci0gICAgICAgICAgICAgICAgU2VjdXJpdHlTdXBwb3J0LmdldFJlc291cmNlQnVuZGxlKCJjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwubXNnLlNBWE1lc3NhZ2VzIiwgbG9jYWxlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHJlc291cmNlQnVuZGxlID0KLSAgICAgICAgICAgICAgICBTZWN1cml0eVN1cHBvcnQuZ2V0UmVzb3VyY2VCdW5kbGUoImNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5tc2cuU0FYTWVzc2FnZXMiKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIGZvcm1hdCBtZXNzYWdlCi0gICAgICAgIFN0cmluZyBtc2c7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBtc2cgPSByZXNvdXJjZUJ1bmRsZS5nZXRTdHJpbmcoa2V5KTsKLSAgICAgICAgICAgIGlmIChhcmd1bWVudHMgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgIG1zZyA9IGphdmEudGV4dC5NZXNzYWdlRm9ybWF0LmZvcm1hdChtc2csIGFyZ3VtZW50cyk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgICAgICBtc2cgPSByZXNvdXJjZUJ1bmRsZS5nZXRTdHJpbmcoIkZvcm1hdEZhaWxlZCIpOwotICAgICAgICAgICAgICAgICAgICBtc2cgKz0gIiAiICsgcmVzb3VyY2VCdW5kbGUuZ2V0U3RyaW5nKGtleSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gZXJyb3IKLSAgICAgICAgY2F0Y2ggKE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICBtc2cgPSByZXNvdXJjZUJ1bmRsZS5nZXRTdHJpbmcoIkJhZE1lc3NhZ2VLZXkiKTsKLSAgICAgICAgICAgIHRocm93IG5ldyBNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24oa2V5LCBtc2csIGtleSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBubyBtZXNzYWdlCi0gICAgICAgIGlmIChtc2cgPT0gbnVsbCkgewotICAgICAgICAgICAgbXNnID0ga2V5OwotICAgICAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAwKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nQnVmZmVyIHN0ciA9IG5ldyBTdHJpbmdCdWZmZXIobXNnKTsKLSAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKCc/Jyk7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGkgPiAwKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKCcmJyk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgc3RyLmFwcGVuZChTdHJpbmcudmFsdWVPZihhcmd1bWVudHNbaV0pKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG1zZzsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL1NlY3VyaXR5TWFuYWdlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9TZWN1cml0eU1hbmFnZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZDkxNmY1Yi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL1NlY3VyaXR5TWFuYWdlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjE1ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDMgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICogQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhlcmNlcyIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgSW50ZXJuYXRpb25hbAotICogQnVzaW5lc3MgTWFjaGluZXMsIEluYy4sIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuQ29uc3RhbnRzOwotLyoqCi0gKiBUaGlzIGNsYXNzIGlzIGEgY29udGFpbmVyIGZvciBwYXJzZXIgc2V0dGluZ3MgdGhhdCByZWxhdGUgdG8KLSAqIHNlY3VyaXR5LCBvciBtb3JlIHNwZWNpZmljYWxseSwgaXQgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCB0byBwcmV2ZW50IGRlbmlhbC1vZi1zZXJ2aWNlCi0gKiBhdHRhY2tzIGZyb20gYmVpbmcgbGF1bmNoZWQgYWdhaW5zdCBhIHN5c3RlbSBydW5uaW5nIFhlcmNlcy4KLSAqIEFueSBjb21wb25lbnQgdGhhdCBpcyBhd2FyZSBvZiBhIGRlbmlhbC1vZi1zZXJ2aWNlIGF0dGFjayB0aGF0IGNhbiBhcmlzZQotICogZnJvbSBpdHMgcHJvY2Vzc2luZyBvZiBhIGNlcnRhaW4ga2luZCBvZiBkb2N1bWVudCBtYXkgcXVlcnkgaXRzIENvbXBvbmVudCBNYW5hZ2VyCi0gKiBmb3IgdGhlIHByb3BlcnR5IChodHRwOi8vYXBhY2hlLm9yZy94bWwvcHJvcGVydGllcy9zZWN1cml0eS1tYW5hZ2VyKQotICogd2hvc2UgdmFsdWUgd2lsbCBiZSBhbiBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzLgotICogSWYgbm8gdmFsdWUgaGFzIGJlZW4gc2V0IGZvciB0aGUgcHJvcGVydHksIHRoZSBjb21wb25lbnQgc2hvdWxkIHByb2NlZWQgaW4gdGhlICJ1c3VhbCIgKHNwZWMtY29tcGxpYW50KQotICogbWFubmVyLiAgSWYgYSB2YWx1ZSBoYXMgYmVlbiBzZXQsIHRoZW4gaXQgbXVzdCBiZSB0aGUgY2FzZSB0aGF0IHRoZSBjb21wb25lbnQgaW4KLSAqIHF1ZXN0aW9uIG5lZWRzIHRvIGtub3cgd2hhdCBtZXRob2Qgb2YgdGhpcyBjbGFzcyB0byBxdWVyeS4gIFRoaXMgY2xhc3MKLSAqIHdpbGwgcHJvdmlkZSBkZWZhdWx0cyBmb3IgYWxsIGtub3duIHNlY3VyaXR5IGlzc3VlcywgYnV0IHdpbGwgYWxzbyBwcm92aWRlCi0gKiBzZXR0ZXJzIHNvIHRoYXQgdGhvc2UgdmFsdWVzIGNhbiBiZSB0YWlsb3JlZCBieSBhcHBsaWNhdGlvbnMgdGhhdCBjYXJlLgotICoKLSAqIEBhdXRob3IgIE5laWwgR3JhaGFtLCBJQk0KLSAqCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBTZWN1cml0eU1hbmFnZXIgewotCi0gICAgLy8KLSAgICAvLyBDb25zdGFudHMKLSAgICAvLwotCi0gICAgLy8gZGVmYXVsdCB2YWx1ZSBmb3IgZW50aXR5IGV4cGFuc2lvbiBsaW1pdAotICAgIHByaXZhdGUgZmluYWwgc3RhdGljIGludCBERUZBVUxUX0VOVElUWV9FWFBBTlNJT05fTElNSVQgPSA2NDAwMDsKLQotICAgIC8qKiBEZWZhdWx0IHZhbHVlIG9mIG51bWJlciBvZiBub2RlcyBjcmVhdGVkLiAqKi8KLSAgICBwcml2YXRlIGZpbmFsIHN0YXRpYyBpbnQgREVGQVVMVF9NQVhfT0NDVVJfTk9ERV9MSU1JVCA9IDUwMDA7Ci0KLSAgICAvLwotICAgIC8vIERhdGEKLSAgICAvLwotCi0gICAgICAgIHByaXZhdGUgZmluYWwgc3RhdGljIGludCBERUZBVUxUX0VMRU1FTlRfQVRUUklCVVRFX0xJTUlUID0gMTAwMDA7Ci0KLSAgICAvKiogRW50aXR5IGV4cGFuc2lvbiBsaW1pdC4gKiovCi0gICAgcHJpdmF0ZSBpbnQgZW50aXR5RXhwYW5zaW9uTGltaXQ7Ci0KLSAgICAvKiogVzNDIFhNTCBTY2hlbWEgbWF4T2NjdXJzIGxpbWl0LiAqKi8KLSAgICBwcml2YXRlIGludCBtYXhPY2N1ckxpbWl0OwotCi0gICAgICAgIHByaXZhdGUgaW50IGZFbGVtZW50QXR0cmlidXRlTGltaXQ7Ci0gICAgLy8gZGVmYXVsdCBjb25zdHJ1Y3Rvci4gIEVzdGFibGlzaGVzIGRlZmF1bHQgdmFsdWVzIGZvcgotICAgIC8vIGFsbCBrbm93biBzZWN1cml0eSBob2xlcy4KLSAgICAvKioKLSAgICAgKiBEZWZhdWx0IGNvbnN0cnVjdG9yLiAgRXN0YWJsaXNoZXMgZGVmYXVsdCB2YWx1ZXMKLSAgICAgKiBmb3Iga25vd24gc2VjdXJpdHkgdnVsbmVyYWJpbGl0aWVzLgotICAgICAqLwotICAgIHB1YmxpYyBTZWN1cml0eU1hbmFnZXIoKSB7Ci0gICAgICAgIGVudGl0eUV4cGFuc2lvbkxpbWl0ID0gREVGQVVMVF9FTlRJVFlfRVhQQU5TSU9OX0xJTUlUOwotICAgICAgICBtYXhPY2N1ckxpbWl0ID0gREVGQVVMVF9NQVhfT0NDVVJfTk9ERV9MSU1JVCA7Ci0gICAgICAgICAgICAgICAgZkVsZW1lbnRBdHRyaWJ1dGVMaW1pdCA9IERFRkFVTFRfRUxFTUVOVF9BVFRSSUJVVEVfTElNSVQ7Ci0gICAgICAgICAgICAgICAgLy9XZSBhcmUgcmVhZGluZyBzeXN0ZW0gcHJvcGVydGllcyBvbmx5IG9uY2UgLAotICAgICAgICAgICAgICAgIC8vYXQgdGhlIHRpbWUgb2YgY3JlYXRpb24gb2YgdGhpcyBvYmplY3QgLAotICAgICAgICAgICAgICAgIHJlYWRTeXN0ZW1Qcm9wZXJ0aWVzKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+U2V0cyB0aGUgbnVtYmVyIG9mIGVudGl0eSBleHBhbnNpb25zIHRoYXQgdGhlCi0gICAgICogcGFyc2VyIHNob3VsZCBwZXJtaXQgaW4gYSBkb2N1bWVudC48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gbGltaXQgdGhlIG51bWJlciBvZiBlbnRpdHkgZXhwYW5zaW9ucwotICAgICAqIHBlcm1pdHRlZCBpbiBhIGRvY3VtZW50Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RW50aXR5RXhwYW5zaW9uTGltaXQoaW50IGxpbWl0KSB7Ci0gICAgICAgIGVudGl0eUV4cGFuc2lvbkxpbWl0ID0gbGltaXQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+UmV0dXJucyB0aGUgbnVtYmVyIG9mIGVudGl0eSBleHBhbnNpb25zCi0gICAgICogdGhhdCB0aGUgcGFyc2VyIHBlcm1pdHMgaW4gYSBkb2N1bWVudC48L3A+Ci0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgZW50aXR5IGV4cGFuc2lvbnMKLSAgICAgKiBwZXJtaXR0ZWQgaW4gYSBkb2N1bWVudAotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0RW50aXR5RXhwYW5zaW9uTGltaXQoKSB7Ci0gICAgICAgIHJldHVybiBlbnRpdHlFeHBhbnNpb25MaW1pdDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5TZXRzIHRoZSBsaW1pdCBvZiB0aGUgbnVtYmVyIG9mIGNvbnRlbnQgbW9kZWwgbm9kZXMKLSAgICAgKiB0aGF0IG1heSBiZSBjcmVhdGVkIHdoZW4gYnVpbGRpbmcgYSBncmFtbWFyIGZvciBhIFczQwotICAgICAqIFhNTCBTY2hlbWEgdGhhdCBjb250YWlucyBtYXhPY2N1cnMgYXR0cmlidXRlcyB3aXRoIHZhbHVlcwotICAgICAqIG90aGVyIHRoYW4gInVuYm91bmRlZCIuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGxpbWl0IHRoZSBtYXhpbXVtIHZhbHVlIGZvciBtYXhPY2N1cnMgb3RoZXIKLSAgICAgKiB0aGFuICJ1bmJvdW5kZWQiCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0TWF4T2NjdXJOb2RlTGltaXQoaW50IGxpbWl0KXsKLSAgICAgICAgbWF4T2NjdXJMaW1pdCA9IGxpbWl0OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPlJldHVybnMgdGhlIGxpbWl0IG9mIHRoZSBudW1iZXIgb2YgY29udGVudCBtb2RlbCBub2RlcwotICAgICAqIHRoYXQgbWF5IGJlIGNyZWF0ZWQgd2hlbiBidWlsZGluZyBhIGdyYW1tYXIgZm9yIGEgVzNDCi0gICAgICogWE1MIFNjaGVtYSB0aGF0IGNvbnRhaW5zIG1heE9jY3VycyBhdHRyaWJ1dGVzIHdpdGggdmFsdWVzCi0gICAgICogb3RoZXIgdGhhbiAidW5ib3VuZGVkIi48L3A+Ci0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRoZSBtYXhpbXVtIHZhbHVlIGZvciBtYXhPY2N1cnMgb3RoZXIKLSAgICAgKiB0aGFuICJ1bmJvdW5kZWQiCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRNYXhPY2N1ck5vZGVMaW1pdCgpewotICAgICAgICByZXR1cm4gbWF4T2NjdXJMaW1pdDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldEVsZW1lbnRBdHRyTGltaXQoKXsKLSAgICAgICAgICAgICAgICByZXR1cm4gZkVsZW1lbnRBdHRyaWJ1dGVMaW1pdDsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyB2b2lkIHNldEVsZW1lbnRBdHRyTGltaXQoaW50IGxpbWl0KXsKLSAgICAgICAgICAgICAgICBmRWxlbWVudEF0dHJpYnV0ZUxpbWl0ID0gbGltaXQ7Ci0gICAgICAgIH0KLQotICAgICAgICBwcml2YXRlIHZvaWQgcmVhZFN5c3RlbVByb3BlcnRpZXMoKXsKLQotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdmFsdWUgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoQ29uc3RhbnRzLkVOVElUWV9FWFBBTlNJT05fTElNSVQpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYodmFsdWUgIT0gbnVsbCAmJiAhdmFsdWUuZXF1YWxzKCIiKSl7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVudGl0eUV4cGFuc2lvbkxpbWl0ID0gSW50ZWdlci5wYXJzZUludCh2YWx1ZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlbnRpdHlFeHBhbnNpb25MaW1pdCA8IDApCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW50aXR5RXhwYW5zaW9uTGltaXQgPSBERUZBVUxUX0VOVElUWV9FWFBBTlNJT05fTElNSVQ7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVudGl0eUV4cGFuc2lvbkxpbWl0ID0gREVGQVVMVF9FTlRJVFlfRVhQQU5TSU9OX0xJTUlUOwotICAgICAgICAgICAgICAgIH1jYXRjaChFeGNlcHRpb24gZXgpe30KLQotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdmFsdWUgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoQ29uc3RhbnRzLk1BWF9PQ0NVUl9MSU1JVCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZih2YWx1ZSAhPSBudWxsICYmICF2YWx1ZS5lcXVhbHMoIiIpKXsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF4T2NjdXJMaW1pdCA9IEludGVnZXIucGFyc2VJbnQodmFsdWUpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobWF4T2NjdXJMaW1pdCA8IDApCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF4T2NjdXJMaW1pdCA9IERFRkFVTFRfTUFYX09DQ1VSX05PREVfTElNSVQ7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1heE9jY3VyTGltaXQgPSBERUZBVUxUX01BWF9PQ0NVUl9OT0RFX0xJTUlUOwotICAgICAgICAgICAgICAgIH1jYXRjaChFeGNlcHRpb24gZXgpe30KLQotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdmFsdWUgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoQ29uc3RhbnRzLkVMRU1FTlRfQVRUUklCVVRFX0xJTUlUKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmKHZhbHVlICE9IG51bGwgJiYgIXZhbHVlLmVxdWFscygiIikpewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmRWxlbWVudEF0dHJpYnV0ZUxpbWl0ID0gSW50ZWdlci5wYXJzZUludCh2YWx1ZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICggZkVsZW1lbnRBdHRyaWJ1dGVMaW1pdCA8IDApCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkVsZW1lbnRBdHRyaWJ1dGVMaW1pdCA9IERFRkFVTFRfRUxFTUVOVF9BVFRSSUJVVEVfTElNSVQ7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZFbGVtZW50QXR0cmlidXRlTGltaXQgPSBERUZBVUxUX0VMRU1FTlRfQVRUUklCVVRFX0xJTUlUOwotCi0gICAgICAgICAgICAgICAgfWNhdGNoKEV4Y2VwdGlvbiBleCl7fQotCi0gICAgICAgIH0KLQotfSAvLyBjbGFzcyBTZWN1cml0eU1hbmFnZXIKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3V0aWwvU2hhZG93ZWRTeW1ib2xUYWJsZS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9TaGFkb3dlZFN5bWJvbFRhYmxlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDA1NTBjNTAuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9TaGFkb3dlZFN5bWJvbFRhYmxlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMjEgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDAyLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbDsKLQotCi0vKioKLSAqIFNoYWRvd2VkIHN5bWJvbCB0YWJsZS4KLSAqCi0gKiBUaGUgdGFibGUgaGFzIGEgcmVmZXJlbmNlIHRvIHRoZSBtYWluIHN5bWJvbCB0YWJsZSBhbmQgaXMKLSAqIG5vdCBhbGxvd2VkIHRvIGFkZCBuZXcgc3ltYm9scyB0byB0aGUgbWFpbiBzeW1ib2wgdGFibGUuCi0gKiBOZXcgc3ltYm9scyBhcmUgYWRkZWQgdG8gdGhlIHNoYWRvdyBzeW1ib2wgdGFibGUgYW5kIGFyZSBsb2NhbAotICogdG8gdGhlIGNvbXBvbmVudCB1c2luZyB0aGlzIHRhYmxlLgotICoKLSAqIEBhdXRob3IgQW5keSBDbGFyayBJQk0KLSAqLwotCi1wdWJsaWMgZmluYWwgY2xhc3MgU2hhZG93ZWRTeW1ib2xUYWJsZQotZXh0ZW5kcyBTeW1ib2xUYWJsZSB7Ci0KLSAgICAvLwotICAgIC8vIERhdGEKLSAgICAvLwotCi0gICAgLyoqIE1haW4gc3ltYm9sIHRhYmxlLiAqLwotICAgIHByb3RlY3RlZCBTeW1ib2xUYWJsZSBmU3ltYm9sVGFibGU7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0cnVjdG9ycwotICAgIC8vCi0KLSAgICAvKiogQ29uc3RydWN0cyBhIHNoYWRvdyBvZiB0aGUgc3BlY2lmaWVkIHN5bWJvbCB0YWJsZS4gKi8KLSAgICBwdWJsaWMgU2hhZG93ZWRTeW1ib2xUYWJsZShTeW1ib2xUYWJsZSBzeW1ib2xUYWJsZSkgewotICAgICAgICBmU3ltYm9sVGFibGUgPSBzeW1ib2xUYWJsZTsKLSAgICB9IC8vIDxpbml0PihTeW1ib2xUYWJsZSkKLQotICAgIC8vCi0gICAgLy8gU3ltYm9sVGFibGUgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBBZGRzIHRoZSBzcGVjaWZpZWQgc3ltYm9sIHRvIHRoZSBzeW1ib2wgdGFibGUgYW5kIHJldHVybnMgYQotICAgICAqIHJlZmVyZW5jZSB0byB0aGUgdW5pcXVlIHN5bWJvbC4gSWYgdGhlIHN5bWJvbCBhbHJlYWR5IGV4aXN0cywKLSAgICAgKiB0aGUgcHJldmlvdXMgc3ltYm9sIHJlZmVyZW5jZSBpcyByZXR1cm5lZCBpbnN0ZWFkLCBpbiBvcmRlcgotICAgICAqIGd1YXJhbnRlZSB0aGF0IHN5bWJvbCByZWZlcmVuY2VzIHJlbWFpbiB1bmlxdWUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc3ltYm9sIFRoZSBuZXcgc3ltYm9sLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgYWRkU3ltYm9sKFN0cmluZyBzeW1ib2wpIHsKLQotICAgICAgICBpZiAoZlN5bWJvbFRhYmxlLmNvbnRhaW5zU3ltYm9sKHN5bWJvbCkpIHsKLSAgICAgICAgICAgIHJldHVybiBmU3ltYm9sVGFibGUuYWRkU3ltYm9sKHN5bWJvbCk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFN5bWJvbChzeW1ib2wpOwotCi0gICAgfSAvLyBhZGRTeW1ib2woU3RyaW5nKQotCi0gICAgLyoqCi0gICAgICogQWRkcyB0aGUgc3BlY2lmaWVkIHN5bWJvbCB0byB0aGUgc3ltYm9sIHRhYmxlIGFuZCByZXR1cm5zIGEKLSAgICAgKiByZWZlcmVuY2UgdG8gdGhlIHVuaXF1ZSBzeW1ib2wuIElmIHRoZSBzeW1ib2wgYWxyZWFkeSBleGlzdHMsCi0gICAgICogdGhlIHByZXZpb3VzIHN5bWJvbCByZWZlcmVuY2UgaXMgcmV0dXJuZWQgaW5zdGVhZCwgaW4gb3JkZXIKLSAgICAgKiBndWFyYW50ZWUgdGhhdCBzeW1ib2wgcmVmZXJlbmNlcyByZW1haW4gdW5pcXVlLgotICAgICAqCi0gICAgICogQHBhcmFtIGJ1ZmZlciBUaGUgYnVmZmVyIGNvbnRhaW5pbmcgdGhlIG5ldyBzeW1ib2wuCi0gICAgICogQHBhcmFtIG9mZnNldCBUaGUgb2Zmc2V0IGludG8gdGhlIGJ1ZmZlciBvZiB0aGUgbmV3IHN5bWJvbC4KLSAgICAgKiBAcGFyYW0gbGVuZ3RoIFRoZSBsZW5ndGggb2YgdGhlIG5ldyBzeW1ib2wgaW4gdGhlIGJ1ZmZlci4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGFkZFN5bWJvbChjaGFyW10gYnVmZmVyLCBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoKSB7Ci0KLSAgICAgICAgaWYgKGZTeW1ib2xUYWJsZS5jb250YWluc1N5bWJvbChidWZmZXIsIG9mZnNldCwgbGVuZ3RoKSkgewotICAgICAgICAgICAgcmV0dXJuIGZTeW1ib2xUYWJsZS5hZGRTeW1ib2woYnVmZmVyLCBvZmZzZXQsIGxlbmd0aCk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFN5bWJvbChidWZmZXIsIG9mZnNldCwgbGVuZ3RoKTsKLQotICAgIH0gLy8gYWRkU3ltYm9sKGNoYXJbXSxpbnQsaW50KTpTdHJpbmcKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYSBoYXNoY29kZSB2YWx1ZSBmb3IgdGhlIHNwZWNpZmllZCBzeW1ib2wuIFRoZSB2YWx1ZQotICAgICAqIHJldHVybmVkIGJ5IHRoaXMgbWV0aG9kIG11c3QgYmUgaWRlbnRpY2FsIHRvIHRoZSB2YWx1ZSByZXR1cm5lZAotICAgICAqIGJ5IHRoZSA8Y29kZT5oYXNoKGNoYXJbXSxpbnQsaW50KTwvY29kZT4gbWV0aG9kIHdoZW4gY2FsbGVkCi0gICAgICogd2l0aCB0aGUgY2hhcmFjdGVyIGFycmF5IHRoYXQgY29tcHJpc2VzIHRoZSBzeW1ib2wgc3RyaW5nLgotICAgICAqCi0gICAgICogQHBhcmFtIHN5bWJvbCBUaGUgc3ltYm9sIHRvIGhhc2guCi0gICAgICovCi0gICAgcHVibGljIGludCBoYXNoKFN0cmluZyBzeW1ib2wpIHsKLSAgICAgICAgcmV0dXJuIGZTeW1ib2xUYWJsZS5oYXNoKHN5bWJvbCk7Ci0gICAgfSAvLyBoYXNoKFN0cmluZyk6aW50Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGEgaGFzaGNvZGUgdmFsdWUgZm9yIHRoZSBzcGVjaWZpZWQgc3ltYm9sIGluZm9ybWF0aW9uLgotICAgICAqIFRoZSB2YWx1ZSByZXR1cm5lZCBieSB0aGlzIG1ldGhvZCBtdXN0IGJlIGlkZW50aWNhbCB0byB0aGUgdmFsdWUKLSAgICAgKiByZXR1cm5lZCBieSB0aGUgPGNvZGU+aGFzaChTdHJpbmcpPC9jb2RlPiBtZXRob2Qgd2hlbiBjYWxsZWQKLSAgICAgKiB3aXRoIHRoZSBzdHJpbmcgb2JqZWN0IGNyZWF0ZWQgZnJvbSB0aGUgc3ltYm9sIGluZm9ybWF0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIGJ1ZmZlciBUaGUgY2hhcmFjdGVyIGJ1ZmZlciBjb250YWluaW5nIHRoZSBzeW1ib2wuCi0gICAgICogQHBhcmFtIG9mZnNldCBUaGUgb2Zmc2V0IGludG8gdGhlIGNoYXJhY3RlciBidWZmZXIgb2YgdGhlIHN0YXJ0Ci0gICAgICogICAgICAgICAgICAgICBvZiB0aGUgc3ltYm9sLgotICAgICAqIEBwYXJhbSBsZW5ndGggVGhlIGxlbmd0aCBvZiB0aGUgc3ltYm9sLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgaGFzaChjaGFyW10gYnVmZmVyLCBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoKSB7Ci0gICAgICAgIHJldHVybiBmU3ltYm9sVGFibGUuaGFzaChidWZmZXIsIG9mZnNldCwgbGVuZ3RoKTsKLSAgICB9IC8vIGhhc2goY2hhcltdLGludCxpbnQpOmludAotCi19IC8vIGNsYXNzIFNoYWRvd2VkU3ltYm9sVGFibGUKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3V0aWwvU3RBWElucHV0U291cmNlLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL1N0QVhJbnB1dFNvdXJjZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyNGRlZjcyLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3V0aWwvU3RBWElucHV0U291cmNlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5NSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQotICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCi0gKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCi0gKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAotICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKLSAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbDsKLQotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uWE1MRXZlbnRSZWFkZXI7Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5YTUxTdHJlYW1FeGNlcHRpb247Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5YTUxTdHJlYW1SZWFkZXI7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MSW5wdXRTb3VyY2U7Ci0KLS8qKgotICogPHA+QW4gPGNvZGU+WE1MSW5wdXRTb3VyY2U8L2NvZGU+IGFuYWxvZ3VlIHRvIDxjb2RlPmphdmF4LnhtbC50cmFuc2Zvcm0uc3RheC5TdEFYU291cmNlPC9jb2RlPi48L3A+Ci0gKgotICogQHZlcnNpb24gJElkOiBTdEFYSW5wdXRTb3VyY2UuamF2YSx2IDEuMiAyMDEwLTEwLTI2IDIzOjAxOjE3IGpvZWh3IEV4cCAkCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBTdEFYSW5wdXRTb3VyY2UgZXh0ZW5kcyBYTUxJbnB1dFNvdXJjZSB7Ci0KLSAgICBwcml2YXRlIGZpbmFsIFhNTFN0cmVhbVJlYWRlciBmU3RyZWFtUmVhZGVyOwotICAgIHByaXZhdGUgZmluYWwgWE1MRXZlbnRSZWFkZXIgZkV2ZW50UmVhZGVyOwotICAgIHByaXZhdGUgZmluYWwgYm9vbGVhbiBmQ29uc3VtZVJlbWFpbmluZ0NvbnRlbnQ7Ci0KLSAgICBwdWJsaWMgU3RBWElucHV0U291cmNlKFhNTFN0cmVhbVJlYWRlciBzb3VyY2UpIHsKLSAgICAgICAgdGhpcyhzb3VyY2UsIGZhbHNlKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RBWElucHV0U291cmNlKFhNTFN0cmVhbVJlYWRlciBzb3VyY2UsIGJvb2xlYW4gY29uc3VtZVJlbWFpbmluZ0NvbnRlbnQpIHsKLSAgICAgICAgc3VwZXIobnVsbCwgc291cmNlLmdldExvY2F0aW9uKCkuZ2V0U3lzdGVtSWQoKSwgbnVsbCk7Ci0gICAgICAgIGlmIChzb3VyY2UgPT0gbnVsbCkgewotICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiWE1MU3RyZWFtUmVhZGVyIHBhcmFtZXRlciBjYW5ub3QgYmUgbnVsbC4iKTsKLSAgICAgICAgfQotICAgICAgICBmU3RyZWFtUmVhZGVyID0gc291cmNlOwotICAgICAgICBmRXZlbnRSZWFkZXIgPSBudWxsOwotICAgICAgICBmQ29uc3VtZVJlbWFpbmluZ0NvbnRlbnQgPSBjb25zdW1lUmVtYWluaW5nQ29udGVudDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RBWElucHV0U291cmNlKFhNTEV2ZW50UmVhZGVyIHNvdXJjZSkgewotICAgICAgICB0aGlzKHNvdXJjZSwgZmFsc2UpOwotICAgIH0KLQotICAgIHB1YmxpYyBTdEFYSW5wdXRTb3VyY2UoWE1MRXZlbnRSZWFkZXIgc291cmNlLCBib29sZWFuIGNvbnN1bWVSZW1haW5pbmdDb250ZW50KSB7Ci0gICAgICAgIHN1cGVyKG51bGwsIGdldEV2ZW50UmVhZGVyU3lzdGVtSWQoc291cmNlKSwgbnVsbCk7Ci0gICAgICAgIGlmIChzb3VyY2UgPT0gbnVsbCkgewotICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiWE1MRXZlbnRSZWFkZXIgcGFyYW1ldGVyIGNhbm5vdCBiZSBudWxsLiIpOwotICAgICAgICB9Ci0gICAgICAgIGZTdHJlYW1SZWFkZXIgPSBudWxsOwotICAgICAgICBmRXZlbnRSZWFkZXIgPSBzb3VyY2U7Ci0gICAgICAgIGZDb25zdW1lUmVtYWluaW5nQ29udGVudCA9IGNvbnN1bWVSZW1haW5pbmdDb250ZW50OwotICAgIH0KLQotICAgIHB1YmxpYyBYTUxTdHJlYW1SZWFkZXIgZ2V0WE1MU3RyZWFtUmVhZGVyKCkgewotICAgICAgICByZXR1cm4gZlN0cmVhbVJlYWRlcjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgWE1MRXZlbnRSZWFkZXIgZ2V0WE1MRXZlbnRSZWFkZXIoKSB7Ci0gICAgICAgIHJldHVybiBmRXZlbnRSZWFkZXI7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gc2hvdWxkQ29uc3VtZVJlbWFpbmluZ0NvbnRlbnQoKSB7Ci0gICAgICAgIHJldHVybiBmQ29uc3VtZVJlbWFpbmluZ0NvbnRlbnQ7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0U3lzdGVtSWQoU3RyaW5nIHN5c3RlbUlkKXsKLSAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJDYW5ub3Qgc2V0IHRoZSBzeXN0ZW0gSUQgb24gYSBTdEFYSW5wdXRTb3VyY2UiKTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgZ2V0RXZlbnRSZWFkZXJTeXN0ZW1JZChYTUxFdmVudFJlYWRlciByZWFkZXIpIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGlmIChyZWFkZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJldHVybiByZWFkZXIucGVlaygpLmdldExvY2F0aW9uKCkuZ2V0U3lzdGVtSWQoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoWE1MU3RyZWFtRXhjZXB0aW9uIGUpIHt9Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotfSAvLyBTdEFYSW5wdXRTb3VyY2UKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3V0aWwvU3RBWExvY2F0aW9uV3JhcHBlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9TdEFYTG9jYXRpb25XcmFwcGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDU2NjUzM2QuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9TdEFYTG9jYXRpb25XcmFwcGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMDYgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKLSAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAotICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgotICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKLSAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCi0gKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWw7Ci0KLQotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uTG9jYXRpb247Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxMb2NhdG9yOwotCi0vKioKLSAqIDxwPkEgbGlnaHQgd3JhcHBlciBhcm91bmQgYSBTdEFYIGxvY2F0aW9uLiBUaGlzIGlzIHVzZWZ1bAotICogd2hlbiBicmlkZ2luZyBiZXR3ZWVuIFN0QVggYW5kIFhOSSBjb21wb25lbnRzLjwvcD4KLSAqCi0gKiBAYXV0aG9yIE1pY2hhZWwgR2xhdmFzc2V2aWNoLCBJQk0KLSAqCi0gKiBAdmVyc2lvbiAkSWQ6IFN0QVhMb2NhdGlvbldyYXBwZXIuamF2YSx2IDEuMiAyMDEwLTEwLTI2IDIzOjAxOjEzIGpvZWh3IEV4cCAkCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBTdEFYTG9jYXRpb25XcmFwcGVyIGltcGxlbWVudHMgWE1MTG9jYXRvciB7Ci0KLSAgICBwcml2YXRlIExvY2F0aW9uIGZMb2NhdGlvbiA9IG51bGw7Ci0KLSAgICBwdWJsaWMgU3RBWExvY2F0aW9uV3JhcHBlcigpIHt9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRMb2NhdGlvbihMb2NhdGlvbiBsb2NhdGlvbikgewotICAgICAgICBmTG9jYXRpb24gPSBsb2NhdGlvbjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgTG9jYXRpb24gZ2V0TG9jYXRpb24oKSB7Ci0gICAgICAgIHJldHVybiBmTG9jYXRpb247Ci0gICAgfQotCi0gICAgLyoKLSAgICAgKiBYTUxMb2NhdG9yIG1ldGhvZHMKLSAgICAgKi8KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0UHVibGljSWQoKSB7Ci0gICAgICAgIGlmIChmTG9jYXRpb24gIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIGZMb2NhdGlvbi5nZXRQdWJsaWNJZCgpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TGl0ZXJhbFN5c3RlbUlkKCkgewotICAgICAgICBpZiAoZkxvY2F0aW9uICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBmTG9jYXRpb24uZ2V0U3lzdGVtSWQoKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldEJhc2VTeXN0ZW1JZCgpIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRFeHBhbmRlZFN5c3RlbUlkKCkgewotICAgICAgICByZXR1cm4gZ2V0TGl0ZXJhbFN5c3RlbUlkKCk7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBnZXRMaW5lTnVtYmVyKCkgewotICAgICAgICBpZiAoZkxvY2F0aW9uICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBmTG9jYXRpb24uZ2V0TGluZU51bWJlcigpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiAtMTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldENvbHVtbk51bWJlcigpIHsKLSAgICAgICAgaWYgKGZMb2NhdGlvbiAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gZkxvY2F0aW9uLmdldENvbHVtbk51bWJlcigpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiAtMTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldENoYXJhY3Rlck9mZnNldCgpIHsKLSAgICAgICAgaWYgKGZMb2NhdGlvbiAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gZkxvY2F0aW9uLmdldENoYXJhY3Rlck9mZnNldCgpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiAtMTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldEVuY29kaW5nKCkgewotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldFhNTFZlcnNpb24oKSB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotfSAvLyBTdEFYTG9jYXRpb25XcmFwcGVyCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL1N0YXR1cy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9TdGF0dXMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNWZkY2M1ZS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL1N0YXR1cy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTkgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwOSBieSBPcmFjbGUgQ29ycG9yYXRpb24uIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCi0gKi8KLQotLyoKLSAqICRJZDogU3RhdHVzLmphdmEgMzAyNCAyMDExLTAzLTAxIDAzOjQ2OjEzWiBqb2VodyAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsOwotCi1wdWJsaWMgZW51bSBTdGF0dXMgewotICAgIFNFVCgoc2hvcnQpLTMsIGZhbHNlKSwKLSAgICBVTktOT1dOKChzaG9ydCktMiwgZmFsc2UpLAotICAgIFJFQ09HTklaRUQoKHNob3J0KS0xLCBmYWxzZSksCi0gICAgTk9UX1NVUFBPUlRFRCgoc2hvcnQpMCwgdHJ1ZSksCi0gICAgTk9UX1JFQ09HTklaRUQoKHNob3J0KTEsIHRydWUpLAotICAgIE5PVF9BTExPV0VEKChzaG9ydCkyLCB0cnVlKSwKLSAgICA7Ci0KLSAgICBwcml2YXRlIGZpbmFsIHNob3J0IHR5cGU7Ci0KLSAgICBwcml2YXRlIGJvb2xlYW4gaXNFeGNlcHRpb25hbDsKLQotICAgIFN0YXR1cyhzaG9ydCB0eXBlLCBib29sZWFuIGlzRXhjZXB0aW9uYWwpIHsKLSAgICAgICAgdGhpcy50eXBlID0gdHlwZTsKLSAgICAgICAgdGhpcy5pc0V4Y2VwdGlvbmFsID0gaXNFeGNlcHRpb25hbDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgc2hvcnQgZ2V0VHlwZSgpIHsKLSAgICAgICAgcmV0dXJuIHR5cGU7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gaXNFeGNlcHRpb25hbCgpIHsKLSAgICAgICAgcmV0dXJuIGlzRXhjZXB0aW9uYWw7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9TeW1ib2xIYXNoLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL1N5bWJvbEhhc2guamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMmYxNmIzNi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL1N5bWJvbEhhc2guamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDMyOSArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDE1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICovCi0vKgotICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCi0gKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKLSAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KLSAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCi0gKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAotICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsOwotCi0KLS8qKgotICogVGhpcyBjbGFzcyBpcyBhbiB1bnN5bmNocm9uaXplZCBoYXNoIHRhYmxlIHByaW1hcnkgdXNlZCBmb3IgU3RyaW5nCi0gKiB0byBPYmplY3QgbWFwcGluZy4KLSAqIDxwPgotICogVGhlIGhhc2ggY29kZSB1c2VzIHRoZSBzYW1lIGFsZ29yaXRobSBhcyBTeW1ib2xUYWJsZSBjbGFzcy4KLSAqCi0gKiBAYXV0aG9yIEVsZW5hIExpdGFuaQotICogQHZlcnNpb24gJElkOiBTeW1ib2xIYXNoLmphdmEsdiAxLjcgMjAxMC0xMS0wMSAwNDo0MDoxNCBqb2VodyBFeHAgJAotICovCi1wdWJsaWMgY2xhc3MgU3ltYm9sSGFzaCB7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0YW50cwotICAgIC8vCi0KLSAgICAvKiogRGVmYXVsdCB0YWJsZSBzaXplLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgaW50IFRBQkxFX1NJWkUgPSAxMDE7Ci0KLSAgICAvKiogTWF4aW11bSBoYXNoIGNvbGxpc2lvbnMgcGVyIGJ1Y2tldC4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBNQVhfSEFTSF9DT0xMSVNJT05TID0gNDA7Ci0KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBNVUxUSVBMSUVSU19TSVpFID0gMSA8PCA1OwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgaW50IE1VTFRJUExJRVJTX01BU0sgPSBNVUxUSVBMSUVSU19TSVpFIC0gMTsKLQotICAgIC8vCi0gICAgLy8gRGF0YQotICAgIC8vCi0KLSAgICAvKiogQWN0dWFsIHRhYmxlIHNpemUgKiovCi0gICAgcHJvdGVjdGVkIGludCBmVGFibGVTaXplOwotCi0gICAgLyoqIEJ1Y2tldHMuICovCi0gICAgcHJvdGVjdGVkIEVudHJ5W10gZkJ1Y2tldHM7Ci0KLSAgICAvKiogTnVtYmVyIG9mIGVsZW1lbnRzLiAqLwotICAgIHByb3RlY3RlZCBpbnQgZk51bSA9IDA7Ci0KLSAgICAvKioKLSAgICAgKiBBcnJheSBvZiByYW5kb21seSBzZWxlY3RlZCBoYXNoIGZ1bmN0aW9uIG11bHRpcGxpZXJzIG9yIDxjb2RlPm51bGw8L2NvZGU+Ci0gICAgICogaWYgdGhlIGRlZmF1bHQgU3RyaW5nLmhhc2hDb2RlKCkgZnVuY3Rpb24gc2hvdWxkIGJlIHVzZWQuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGludFtdIGZIYXNoTXVsdGlwbGllcnM7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0cnVjdG9ycwotICAgIC8vCi0KLSAgICAvKiogQ29uc3RydWN0cyBhIGtleSB0YWJsZSB3aXRoIHRoZSBkZWZhdWx0IHNpemUuICovCi0gICAgcHVibGljIFN5bWJvbEhhc2goKSB7Ci0gICAgICAgIHRoaXMoVEFCTEVfU0laRSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0cyBhIGtleSB0YWJsZSB3aXRoIGEgZ2l2ZW4gc2l6ZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzaXplICB0aGUgc2l6ZSBvZiB0aGUga2V5IHRhYmxlLgotICAgICAqLwotICAgIHB1YmxpYyBTeW1ib2xIYXNoKGludCBzaXplKSB7Ci0gICAgICAgIGZUYWJsZVNpemUgPSBzaXplOwotICAgICAgICBmQnVja2V0cyA9IG5ldyBFbnRyeVtmVGFibGVTaXplXTsKLSAgICB9Ci0KLSAgICAvLwotICAgIC8vIFB1YmxpYyBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIEFkZHMgdGhlIGtleS92YWx1ZSBtYXBwaW5nIHRvIHRoZSBrZXkgdGFibGUuIElmIHRoZSBrZXkgYWxyZWFkeSBleGlzdHMsCi0gICAgICogdGhlIHByZXZpb3VzIHZhbHVlIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGtleSBpcyBvdmVyd3JpdHRlbiBieSB0aGUgbmV3Ci0gICAgICogdmFsdWUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0ga2V5Ci0gICAgICogQHBhcmFtIHZhbHVlCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcHV0KE9iamVjdCBrZXksIE9iamVjdCB2YWx1ZSkgewotCi0gICAgICAgIC8vIHNlYXJjaCBmb3IgaWRlbnRpY2FsIGtleQotICAgICAgICBpbnQgY29sbGlzaW9uQ291bnQgPSAwOwotICAgICAgICBmaW5hbCBpbnQgaGFzaCA9IGhhc2goa2V5KTsKLSAgICAgICAgaW50IGJ1Y2tldCA9IGhhc2ggJSBmVGFibGVTaXplOwotICAgICAgICBmb3IgKEVudHJ5IGVudHJ5ID0gZkJ1Y2tldHNbYnVja2V0XTsgZW50cnkgIT0gbnVsbDsgZW50cnkgPSBlbnRyeS5uZXh0KSB7Ci0gICAgICAgICAgICBpZiAoa2V5LmVxdWFscyhlbnRyeS5rZXkpKSB7Ci0gICAgICAgICAgICAgICAgLy8gcmVwbGFjZSBvbGQgdmFsdWUKLSAgICAgICAgICAgICAgICBlbnRyeS52YWx1ZSA9IHZhbHVlOwotICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgICsrY29sbGlzaW9uQ291bnQ7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoZk51bSA+PSBmVGFibGVTaXplKSB7Ci0gICAgICAgICAgICAvLyBSZWhhc2ggdGhlIHRhYmxlIGlmIHRoZSBudW1iZXIgb2YgZW50cmllcwotICAgICAgICAgICAgLy8gd291bGQgZXhjZWVkIHRoZSBudW1iZXIgb2YgYnVja2V0cy4KLSAgICAgICAgICAgIHJlaGFzaCgpOwotICAgICAgICAgICAgYnVja2V0ID0gaGFzaCAlIGZUYWJsZVNpemU7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoY29sbGlzaW9uQ291bnQgPj0gTUFYX0hBU0hfQ09MTElTSU9OUyAmJiBrZXkgaW5zdGFuY2VvZiBTdHJpbmcpIHsKLSAgICAgICAgICAgIC8vIFNlbGVjdCBhIG5ldyBoYXNoIGZ1bmN0aW9uIGFuZCByZWhhc2ggdGhlIHRhYmxlIGlmCi0gICAgICAgICAgICAvLyBNQVhfSEFTSF9DT0xMSVNJT05TIGlzIGV4Y2VlZGVkLgotICAgICAgICAgICAgcmViYWxhbmNlKCk7Ci0gICAgICAgICAgICBidWNrZXQgPSBoYXNoKGtleSkgJSBmVGFibGVTaXplOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gY3JlYXRlIG5ldyBlbnRyeQotICAgICAgICBFbnRyeSBlbnRyeSA9IG5ldyBFbnRyeShrZXksIHZhbHVlLCBmQnVja2V0c1tidWNrZXRdKTsKLSAgICAgICAgZkJ1Y2tldHNbYnVja2V0XSA9IGVudHJ5OwotICAgICAgICArK2ZOdW07Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSB2YWx1ZSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIGtleS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBrZXkKLSAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIGtleS4KLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0IGdldChPYmplY3Qga2V5KSB7Ci0gICAgICAgIGludCBidWNrZXQgPSBoYXNoKGtleSkgJSBmVGFibGVTaXplOwotICAgICAgICBFbnRyeSBlbnRyeSA9IHNlYXJjaChrZXksIGJ1Y2tldCk7Ci0gICAgICAgIGlmIChlbnRyeSAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gZW50cnkudmFsdWU7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBudW1iZXIgb2Yga2V5L3ZhbHVlIHBhaXJzIHN0b3JlZCBpbiB0aGlzIHRhYmxlLgotICAgICAqCi0gICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGtleS92YWx1ZSBwYWlycyBzdG9yZWQgaW4gdGhpcyB0YWJsZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldExlbmd0aCgpIHsKLSAgICAgICAgcmV0dXJuIGZOdW07Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQWRkIGFsbCB2YWx1ZXMgdG8gdGhlIGdpdmVuIGFycmF5LiBUaGUgYXJyYXkgbXVzdCBoYXZlIGVub3VnaCBlbnRyeS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlbGVtZW50cyAgdGhlIGFycmF5IHRvIHN0b3JlIHRoZSBlbGVtZW50cwotICAgICAqIEBwYXJhbSBmcm9tICAgICAgd2hlcmUgdG8gc3RhcnQgc3RvcmUgZWxlbWVudCBpbiB0aGUgYXJyYXkKLSAgICAgKiBAcmV0dXJuICAgICAgICAgIG51bWJlciBvZiBlbGVtZW50cyBjb3BpZWQgdG8gdGhlIGFycmF5Ci0gICAgICovCi0gICAgcHVibGljIGludCBnZXRWYWx1ZXMoT2JqZWN0W10gZWxlbWVudHMsIGludCBmcm9tKSB7Ci0gICAgICAgIGZvciAoaW50IGk9MCwgaj0wOyBpPGZUYWJsZVNpemUgJiYgajxmTnVtOyBpKyspIHsKLSAgICAgICAgICAgIGZvciAoRW50cnkgZW50cnkgPSBmQnVja2V0c1tpXTsgZW50cnkgIT0gbnVsbDsgZW50cnkgPSBlbnRyeS5uZXh0KSB7Ci0gICAgICAgICAgICAgICAgZWxlbWVudHNbZnJvbStqXSA9IGVudHJ5LnZhbHVlOwotICAgICAgICAgICAgICAgIGorKzsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZk51bTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4ga2V5L3ZhbHVlIHBhaXJzIG9mIGFsbCBlbnRyaWVzIGluIHRoZSBtYXAKLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0W10gZ2V0RW50cmllcygpIHsKLSAgICAgICAgT2JqZWN0W10gZW50cmllcyA9IG5ldyBPYmplY3RbZk51bSA8PCAxXTsKLSAgICAgICAgZm9yIChpbnQgaT0wLCBqPTA7IGk8ZlRhYmxlU2l6ZSAmJiBqPGZOdW0gPDwgMTsgaSsrKSB7Ci0gICAgICAgICAgICBmb3IgKEVudHJ5IGVudHJ5ID0gZkJ1Y2tldHNbaV07IGVudHJ5ICE9IG51bGw7IGVudHJ5ID0gZW50cnkubmV4dCkgewotICAgICAgICAgICAgICAgIGVudHJpZXNbal0gPSBlbnRyeS5rZXk7Ci0gICAgICAgICAgICAgICAgZW50cmllc1srK2pdID0gZW50cnkudmFsdWU7Ci0gICAgICAgICAgICAgICAgaisrOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBlbnRyaWVzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIE1ha2UgYSBjbG9uZSBvZiB0aGlzIG9iamVjdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3ltYm9sSGFzaCBtYWtlQ2xvbmUoKSB7Ci0gICAgICAgIFN5bWJvbEhhc2ggbmV3VGFibGUgPSBuZXcgU3ltYm9sSGFzaChmVGFibGVTaXplKTsKLSAgICAgICAgbmV3VGFibGUuZk51bSA9IGZOdW07Ci0gICAgICAgIG5ld1RhYmxlLmZIYXNoTXVsdGlwbGllcnMgPSBmSGFzaE11bHRpcGxpZXJzICE9IG51bGwgPyAoaW50W10pIGZIYXNoTXVsdGlwbGllcnMuY2xvbmUoKSA6IG51bGw7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZlRhYmxlU2l6ZTsgaSsrKSB7Ci0gICAgICAgICAgICBpZiAoZkJ1Y2tldHNbaV0gIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIG5ld1RhYmxlLmZCdWNrZXRzW2ldID0gZkJ1Y2tldHNbaV0ubWFrZUNsb25lKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG5ld1RhYmxlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJlbW92ZSBhbGwga2V5L3ZhbHVlIGFzc29jaWF0aW9uLiBUaGlzIHRyaWVzIHRvIHNhdmUgYSBiaXQgb2YgR0MnaW5nCi0gICAgICogYnkgYXQgbGVhc3Qga2VlcGluZyB0aGUgZkJ1Y2tldHMgYXJyYXkgYXJvdW5kLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGNsZWFyKCkgewotICAgICAgICBmb3IgKGludCBpPTA7IGk8ZlRhYmxlU2l6ZTsgaSsrKSB7Ci0gICAgICAgICAgICBmQnVja2V0c1tpXSA9IG51bGw7Ci0gICAgICAgIH0KLSAgICAgICAgZk51bSA9IDA7Ci0gICAgICAgIGZIYXNoTXVsdGlwbGllcnMgPSBudWxsOwotICAgIH0gLy8gY2xlYXIoKTogIHZvaWQKLQotICAgIHByb3RlY3RlZCBFbnRyeSBzZWFyY2goT2JqZWN0IGtleSwgaW50IGJ1Y2tldCkgewotICAgICAgICAvLyBzZWFyY2ggZm9yIGlkZW50aWNhbCBrZXkKLSAgICAgICAgZm9yIChFbnRyeSBlbnRyeSA9IGZCdWNrZXRzW2J1Y2tldF07IGVudHJ5ICE9IG51bGw7IGVudHJ5ID0gZW50cnkubmV4dCkgewotICAgICAgICAgICAgaWYgKGtleS5lcXVhbHMoZW50cnkua2V5KSkKLSAgICAgICAgICAgICAgICByZXR1cm4gZW50cnk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhIGhhc2hjb2RlIHZhbHVlIGZvciB0aGUgc3BlY2lmaWVkIGtleS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBrZXkgVGhlIGtleSB0byBoYXNoLgotICAgICAqLwotICAgIHByb3RlY3RlZCBpbnQgaGFzaChPYmplY3Qga2V5KSB7Ci0gICAgICAgIGlmIChmSGFzaE11bHRpcGxpZXJzID09IG51bGwgfHwgIShrZXkgaW5zdGFuY2VvZiBTdHJpbmcpKSB7Ci0gICAgICAgICAgICByZXR1cm4ga2V5Lmhhc2hDb2RlKCkgJiAweDdGRkZGRkZGOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBoYXNoMCgoU3RyaW5nKSBrZXkpOwotICAgIH0gLy8gaGFzaChPYmplY3QpOmludAotCi0gICAgcHJpdmF0ZSBpbnQgaGFzaDAoU3RyaW5nIHN5bWJvbCkgewotICAgICAgICBpbnQgY29kZSA9IDA7Ci0gICAgICAgIGZpbmFsIGludCBsZW5ndGggPSBzeW1ib2wubGVuZ3RoKCk7Ci0gICAgICAgIGZpbmFsIGludFtdIG11bHRpcGxpZXJzID0gZkhhc2hNdWx0aXBsaWVyczsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkgewotICAgICAgICAgICAgY29kZSA9IGNvZGUgKiBtdWx0aXBsaWVyc1tpICYgTVVMVElQTElFUlNfTUFTS10gKyBzeW1ib2wuY2hhckF0KGkpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBjb2RlICYgMHg3RkZGRkZGRjsKLSAgICB9IC8vIGhhc2gwKFN0cmluZyk6aW50Ci0KLSAgICAvKioKLSAgICAgKiBJbmNyZWFzZXMgdGhlIGNhcGFjaXR5IG9mIGFuZCBpbnRlcm5hbGx5IHJlb3JnYW5pemVzIHRoaXMKLSAgICAgKiBTeW1ib2xIYXNoLCBpbiBvcmRlciB0byBhY2NvbW1vZGF0ZSBhbmQgYWNjZXNzIGl0cyBlbnRyaWVzIG1vcmUKLSAgICAgKiBlZmZpY2llbnRseS4gIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBhdXRvbWF0aWNhbGx5IHdoZW4gdGhlCi0gICAgICogbnVtYmVyIG9mIGtleXMgaW4gdGhlIFN5bWJvbEhhc2ggZXhjZWVkcyBpdHMgbnVtYmVyIG9mIGJ1Y2tldHMuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgcmVoYXNoKCkgewotICAgICAgICByZWhhc2hDb21tb24oKGZCdWNrZXRzLmxlbmd0aCA8PCAxKSArIDEpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJhbmRvbWx5IHNlbGVjdHMgYSBuZXcgaGFzaCBmdW5jdGlvbiBhbmQgcmVvcmdhbml6ZXMgdGhpcyBTeW1ib2xIYXNoCi0gICAgICogaW4gb3JkZXIgdG8gbW9yZSBldmVubHkgZGlzdHJpYnV0ZSBpdHMgZW50cmllcyBhY3Jvc3MgdGhlIHRhYmxlLiBUaGlzCi0gICAgICogbWV0aG9kIGlzIGNhbGxlZCBhdXRvbWF0aWNhbGx5IHdoZW4gdGhlIG51bWJlciBrZXlzIGluIG9uZSBvZiB0aGUKLSAgICAgKiBTeW1ib2xIYXNoJ3MgYnVja2V0cyBleGNlZWRzIE1BWF9IQVNIX0NPTExJU0lPTlMuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgcmViYWxhbmNlKCkgewotICAgICAgICBpZiAoZkhhc2hNdWx0aXBsaWVycyA9PSBudWxsKSB7Ci0gICAgICAgICAgICBmSGFzaE11bHRpcGxpZXJzID0gbmV3IGludFtNVUxUSVBMSUVSU19TSVpFXTsKLSAgICAgICAgfQotICAgICAgICBQcmltZU51bWJlclNlcXVlbmNlR2VuZXJhdG9yLmdlbmVyYXRlU2VxdWVuY2UoZkhhc2hNdWx0aXBsaWVycyk7Ci0gICAgICAgIHJlaGFzaENvbW1vbihmQnVja2V0cy5sZW5ndGgpOwotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCByZWhhc2hDb21tb24oZmluYWwgaW50IG5ld0NhcGFjaXR5KSB7Ci0KLSAgICAgICAgZmluYWwgaW50IG9sZENhcGFjaXR5ID0gZkJ1Y2tldHMubGVuZ3RoOwotICAgICAgICBmaW5hbCBFbnRyeVtdIG9sZFRhYmxlID0gZkJ1Y2tldHM7Ci0KLSAgICAgICAgZmluYWwgRW50cnlbXSBuZXdUYWJsZSA9IG5ldyBFbnRyeVtuZXdDYXBhY2l0eV07Ci0KLSAgICAgICAgZkJ1Y2tldHMgPSBuZXdUYWJsZTsKLSAgICAgICAgZlRhYmxlU2l6ZSA9IGZCdWNrZXRzLmxlbmd0aDsKLQotICAgICAgICBmb3IgKGludCBpID0gb2xkQ2FwYWNpdHk7IGktLSA+IDA7KSB7Ci0gICAgICAgICAgICBmb3IgKEVudHJ5IG9sZCA9IG9sZFRhYmxlW2ldOyBvbGQgIT0gbnVsbDsgKSB7Ci0gICAgICAgICAgICAgICAgRW50cnkgZSA9IG9sZDsKLSAgICAgICAgICAgICAgICBvbGQgPSBvbGQubmV4dDsKLQotICAgICAgICAgICAgICAgIGludCBpbmRleCA9IGhhc2goZS5rZXkpICUgbmV3Q2FwYWNpdHk7Ci0gICAgICAgICAgICAgICAgZS5uZXh0ID0gbmV3VGFibGVbaW5kZXhdOwotICAgICAgICAgICAgICAgIG5ld1RhYmxlW2luZGV4XSA9IGU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvLwotICAgIC8vIENsYXNzZXMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogVGhpcyBjbGFzcyBpcyBhIGtleSB0YWJsZSBlbnRyeS4gRWFjaCBlbnRyeSBhY3RzIGFzIGEgbm9kZQotICAgICAqIGluIGEgbGlua2VkIGxpc3QuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBjbGFzcyBFbnRyeSB7Ci0gICAgICAgIC8vIGtleS92YWx1ZQotICAgICAgICBwdWJsaWMgT2JqZWN0IGtleTsKLSAgICAgICAgcHVibGljIE9iamVjdCB2YWx1ZTsKLSAgICAgICAgLyoqIFRoZSBuZXh0IGVudHJ5LiAqLwotICAgICAgICBwdWJsaWMgRW50cnkgbmV4dDsKLQotICAgICAgICBwdWJsaWMgRW50cnkoKSB7Ci0gICAgICAgICAgICBrZXkgPSBudWxsOwotICAgICAgICAgICAgdmFsdWUgPSBudWxsOwotICAgICAgICAgICAgbmV4dCA9IG51bGw7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgRW50cnkoT2JqZWN0IGtleSwgT2JqZWN0IHZhbHVlLCBFbnRyeSBuZXh0KSB7Ci0gICAgICAgICAgICB0aGlzLmtleSA9IGtleTsKLSAgICAgICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKLSAgICAgICAgICAgIHRoaXMubmV4dCA9IG5leHQ7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgRW50cnkgbWFrZUNsb25lKCkgewotICAgICAgICAgICAgRW50cnkgZW50cnkgPSBuZXcgRW50cnkoKTsKLSAgICAgICAgICAgIGVudHJ5LmtleSA9IGtleTsKLSAgICAgICAgICAgIGVudHJ5LnZhbHVlID0gdmFsdWU7Ci0gICAgICAgICAgICBpZiAobmV4dCAhPSBudWxsKQotICAgICAgICAgICAgICAgIGVudHJ5Lm5leHQgPSBuZXh0Lm1ha2VDbG9uZSgpOwotICAgICAgICAgICAgcmV0dXJuIGVudHJ5OwotICAgICAgICB9Ci0gICAgfSAvLyBlbnRyeQotCi19IC8vIGNsYXNzIFN5bWJvbEhhc2gKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3V0aWwvU3ltYm9sVGFibGUuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3V0aWwvU3ltYm9sVGFibGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOWVlZWY2Ni4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL1N5bWJvbFRhYmxlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0NjcgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAxNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqLwotLyoKLSAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQotICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCi0gKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCi0gKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAotICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKLSAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbDsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGlzIGEgc3ltYm9sIHRhYmxlIGltcGxlbWVudGF0aW9uIHRoYXQgZ3VhcmFudGVlcyB0aGF0Ci0gKiBzdHJpbmdzIHVzZWQgYXMgaWRlbnRpZmllcnMgYXJlIHVuaXF1ZSByZWZlcmVuY2VzLiBNdWx0aXBsZSBjYWxscwotICogdG8gPGNvZGU+YWRkU3ltYm9sPC9jb2RlPiB3aWxsIGFsd2F5cyByZXR1cm4gdGhlIHNhbWUgc3RyaW5nCi0gKiByZWZlcmVuY2UuCi0gKiA8cD4KLSAqIFRoZSBzeW1ib2wgdGFibGUgcGVyZm9ybXMgdGhlIHNhbWUgdGFzayBhcyA8Y29kZT5TdHJpbmcuaW50ZXJuKCk8L2NvZGU+Ci0gKiB3aXRoIHRoZSBmb2xsb3dpbmcgZGlmZmVyZW5jZXM6Ci0gKiA8dWw+Ci0gKiAgPGxpPgotICogICBBIG5ldyBzdHJpbmcgb2JqZWN0IGRvZXMgbm90IG5lZWQgdG8gYmUgY3JlYXRlZCBpbiBvcmRlciB0bwotICogICByZXRyaWV2ZSBhIHVuaXF1ZSByZWZlcmVuY2UuIFN5bWJvbHMgY2FuIGJlIGFkZGVkIGJ5IHVzaW5nCi0gKiAgIGEgc2VyaWVzIG9mIGNoYXJhY3RlcnMgaW4gYSBjaGFyYWN0ZXIgYXJyYXkuCi0gKiAgPC9saT4KLSAqICA8bGk+Ci0gKiAgIFVzZXJzIG9mIHRoZSBzeW1ib2wgdGFibGUgY2FuIHByb3ZpZGUgdGhlaXIgb3duIHN5bWJvbCBoYXNoaW5nCi0gKiAgIGltcGxlbWVudGF0aW9uLiBGb3IgZXhhbXBsZSwgYSBzaW1wbGUgc3RyaW5nIGhhc2hpbmcgYWxnb3JpdGhtCi0gKiAgIG1heSBmYWlsIHRvIHByb2R1Y2UgYSBiYWxhbmNlZCBzZXQgb2YgaGFzaGNvZGVzIGZvciBzeW1ib2xzCi0gKiAgIHRoYXQgYXJlIDxlbT5tb3N0bHk8L2VtPiB1bmlxdWUuIFN0cmluZ3Mgd2l0aCBzaW1pbGFyIGxlYWRpbmcKLSAqICAgY2hhcmFjdGVycyBhcmUgZXNwZWNpYWxseSBwcm9uZSB0byB0aGlzIHBvb3IgaGFzaGluZyBiZWhhdmlvci4KLSAqICA8L2xpPgotICogPC91bD4KLSAqCi0gKiBAc2VlIFN5bWJvbEhhc2gKLSAqCi0gKiBAYXV0aG9yIEFuZHkgQ2xhcmsKLSAqCi0gKi8KLXB1YmxpYyBjbGFzcyBTeW1ib2xUYWJsZSB7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0YW50cwotICAgIC8vCi0KLSAgICAvKiogRGVmYXVsdCB0YWJsZSBzaXplLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgaW50IFRBQkxFX1NJWkUgPSAxMDE7Ci0KLSAgICAvKiogTWF4aW11bSBoYXNoIGNvbGxpc2lvbnMgcGVyIGJ1Y2tldCBmb3IgYSB0YWJsZSB3aXRoIGxvYWQgZmFjdG9yID09IDEuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBpbnQgTUFYX0hBU0hfQ09MTElTSU9OUyA9IDQwOwotCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBpbnQgTVVMVElQTElFUlNfU0laRSA9IDEgPDwgNTsKLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBNVUxUSVBMSUVSU19NQVNLID0gTVVMVElQTElFUlNfU0laRSAtIDE7Ci0KLSAgICAvLwotICAgIC8vIERhdGEKLSAgICAvLwotCi0gICAgLyoqIEJ1Y2tldHMuICovCi0gICAgcHJvdGVjdGVkIEVudHJ5W10gZkJ1Y2tldHMgPSBudWxsOwotCi0gICAgLyoqIGFjdHVhbCB0YWJsZSBzaXplICovCi0gICAgcHJvdGVjdGVkIGludCBmVGFibGVTaXplOwotCi0gICAgLyoqIFRoZSB0b3RhbCBudW1iZXIgb2YgZW50cmllcyBpbiB0aGUgaGFzaCB0YWJsZS4gKi8KLSAgICBwcm90ZWN0ZWQgdHJhbnNpZW50IGludCBmQ291bnQ7Ci0KLSAgICAvKiogVGhlIHRhYmxlIGlzIHJlaGFzaGVkIHdoZW4gaXRzIHNpemUgZXhjZWVkcyB0aGlzIHRocmVzaG9sZC4gIChUaGUKLSAgICAgKiB2YWx1ZSBvZiB0aGlzIGZpZWxkIGlzIChpbnQpKGNhcGFjaXR5ICogbG9hZEZhY3RvcikuKSAqLwotICAgIHByb3RlY3RlZCBpbnQgZlRocmVzaG9sZDsKLQotICAgIC8qKiBUaGUgbG9hZCBmYWN0b3IgZm9yIHRoZSBTeW1ib2xUYWJsZS4gKi8KLSAgICBwcm90ZWN0ZWQgZmxvYXQgZkxvYWRGYWN0b3I7Ci0KLSAgICAvKioKLSAgICAgKiBBIG5ldyBoYXNoIGZ1bmN0aW9uIGlzIHNlbGVjdGVkIGFuZCB0aGUgdGFibGUgaXMgcmVoYXNoZWQgd2hlbgotICAgICAqIHRoZSBudW1iZXIgb2Yga2V5cyBpbiB0aGUgYnVja2V0IGV4Y2VlZHMgdGhpcyB0aHJlc2hvbGQuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGZpbmFsIGludCBmQ29sbGlzaW9uVGhyZXNob2xkOwotCi0gICAgLyoqCi0gICAgICogQXJyYXkgb2YgcmFuZG9tbHkgc2VsZWN0ZWQgaGFzaCBmdW5jdGlvbiBtdWx0aXBsaWVycyBvciA8Y29kZT5udWxsPC9jb2RlPgotICAgICAqIGlmIHRoZSBkZWZhdWx0IFN0cmluZy5oYXNoQ29kZSgpIGZ1bmN0aW9uIHNob3VsZCBiZSB1c2VkLgotICAgICAqLwotICAgIHByb3RlY3RlZCBpbnRbXSBmSGFzaE11bHRpcGxpZXJzOwotCi0gICAgLy8KLSAgICAvLyBDb25zdHJ1Y3RvcnMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0cyBhIG5ldywgZW1wdHkgU3ltYm9sVGFibGUgd2l0aCB0aGUgc3BlY2lmaWVkIGluaXRpYWwKLSAgICAgKiBjYXBhY2l0eSBhbmQgdGhlIHNwZWNpZmllZCBsb2FkIGZhY3Rvci4KLSAgICAgKgotICAgICAqIEBwYXJhbSAgICAgIGluaXRpYWxDYXBhY2l0eSAgIHRoZSBpbml0aWFsIGNhcGFjaXR5IG9mIHRoZSBTeW1ib2xUYWJsZS4KLSAgICAgKiBAcGFyYW0gICAgICBsb2FkRmFjdG9yICAgICAgICB0aGUgbG9hZCBmYWN0b3Igb2YgdGhlIFN5bWJvbFRhYmxlLgotICAgICAqIEB0aHJvd3MgICAgIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiAgaWYgdGhlIGluaXRpYWwgY2FwYWNpdHkgaXMgbGVzcwotICAgICAqICAgICAgICAgICAgIHRoYW4gemVybywgb3IgaWYgdGhlIGxvYWQgZmFjdG9yIGlzIG5vbnBvc2l0aXZlLgotICAgICAqLwotICAgIHB1YmxpYyBTeW1ib2xUYWJsZShpbnQgaW5pdGlhbENhcGFjaXR5LCBmbG9hdCBsb2FkRmFjdG9yKSB7Ci0KLSAgICAgICAgaWYgKGluaXRpYWxDYXBhY2l0eSA8IDApIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIklsbGVnYWwgQ2FwYWNpdHk6ICIgKyBpbml0aWFsQ2FwYWNpdHkpOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKGxvYWRGYWN0b3IgPD0gMCB8fCBGbG9hdC5pc05hTihsb2FkRmFjdG9yKSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiSWxsZWdhbCBMb2FkOiAiICsgbG9hZEZhY3Rvcik7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoaW5pdGlhbENhcGFjaXR5ID09IDApIHsKLSAgICAgICAgICAgIGluaXRpYWxDYXBhY2l0eSA9IDE7Ci0gICAgICAgIH0KLQotICAgICAgICBmTG9hZEZhY3RvciA9IGxvYWRGYWN0b3I7Ci0gICAgICAgIGZUYWJsZVNpemUgPSBpbml0aWFsQ2FwYWNpdHk7Ci0gICAgICAgIGZCdWNrZXRzID0gbmV3IEVudHJ5W2ZUYWJsZVNpemVdOwotICAgICAgICBmVGhyZXNob2xkID0gKGludCkoZlRhYmxlU2l6ZSAqIGxvYWRGYWN0b3IpOwotICAgICAgICBmQ29sbGlzaW9uVGhyZXNob2xkID0gKGludCkoTUFYX0hBU0hfQ09MTElTSU9OUyAqIGxvYWRGYWN0b3IpOwotICAgICAgICBmQ291bnQgPSAwOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHMgYSBuZXcsIGVtcHR5IFN5bWJvbFRhYmxlIHdpdGggdGhlIHNwZWNpZmllZCBpbml0aWFsIGNhcGFjaXR5Ci0gICAgICogYW5kIGRlZmF1bHQgbG9hZCBmYWN0b3IsIHdoaWNoIGlzIDx0dD4wLjc1PC90dD4uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gICAgIGluaXRpYWxDYXBhY2l0eSAgIHRoZSBpbml0aWFsIGNhcGFjaXR5IG9mIHRoZSBoYXNodGFibGUuCi0gICAgICogQHRocm93cyAgICBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgdGhlIGluaXRpYWwgY2FwYWNpdHkgaXMgbGVzcwotICAgICAqICAgICAgICAgICAgdGhhbiB6ZXJvLgotICAgICAqLwotICAgIHB1YmxpYyBTeW1ib2xUYWJsZShpbnQgaW5pdGlhbENhcGFjaXR5KSB7Ci0gICAgICAgIHRoaXMoaW5pdGlhbENhcGFjaXR5LCAwLjc1Zik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0cyBhIG5ldywgZW1wdHkgU3ltYm9sVGFibGUgd2l0aCBhIGRlZmF1bHQgaW5pdGlhbCBjYXBhY2l0eSAoMTAxKQotICAgICAqIGFuZCBsb2FkIGZhY3Rvciwgd2hpY2ggaXMgPHR0PjAuNzU8L3R0Pi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3ltYm9sVGFibGUoKSB7Ci0gICAgICAgIHRoaXMoVEFCTEVfU0laRSwgMC43NWYpOwotICAgIH0KLQotICAgIC8vCi0gICAgLy8gUHVibGljIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogQWRkcyB0aGUgc3BlY2lmaWVkIHN5bWJvbCB0byB0aGUgc3ltYm9sIHRhYmxlIGFuZCByZXR1cm5zIGEKLSAgICAgKiByZWZlcmVuY2UgdG8gdGhlIHVuaXF1ZSBzeW1ib2wuIElmIHRoZSBzeW1ib2wgYWxyZWFkeSBleGlzdHMsCi0gICAgICogdGhlIHByZXZpb3VzIHN5bWJvbCByZWZlcmVuY2UgaXMgcmV0dXJuZWQgaW5zdGVhZCwgaW4gb3JkZXIKLSAgICAgKiBndWFyYW50ZWUgdGhhdCBzeW1ib2wgcmVmZXJlbmNlcyByZW1haW4gdW5pcXVlLgotICAgICAqCi0gICAgICogQHBhcmFtIHN5bWJvbCBUaGUgbmV3IHN5bWJvbC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGFkZFN5bWJvbChTdHJpbmcgc3ltYm9sKSB7Ci0KLSAgICAgICAgLy8gc2VhcmNoIGZvciBpZGVudGljYWwgc3ltYm9sCi0gICAgICAgIGludCBjb2xsaXNpb25Db3VudCA9IDA7Ci0gICAgICAgIGludCBidWNrZXQgPSBoYXNoKHN5bWJvbCkgJSBmVGFibGVTaXplOwotICAgICAgICBmb3IgKEVudHJ5IGVudHJ5ID0gZkJ1Y2tldHNbYnVja2V0XTsgZW50cnkgIT0gbnVsbDsgZW50cnkgPSBlbnRyeS5uZXh0KSB7Ci0gICAgICAgICAgICBpZiAoZW50cnkuc3ltYm9sLmVxdWFscyhzeW1ib2wpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGVudHJ5LnN5bWJvbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgICsrY29sbGlzaW9uQ291bnQ7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGFkZFN5bWJvbDAoc3ltYm9sLCBidWNrZXQsIGNvbGxpc2lvbkNvdW50KTsKLQotICAgIH0gLy8gYWRkU3ltYm9sKFN0cmluZyk6U3RyaW5nCi0KLSAgICBwcml2YXRlIFN0cmluZyBhZGRTeW1ib2wwKFN0cmluZyBzeW1ib2wsIGludCBidWNrZXQsIGludCBjb2xsaXNpb25Db3VudCkgewotCi0gICAgICAgIGlmIChmQ291bnQgPj0gZlRocmVzaG9sZCkgewotICAgICAgICAgICAgLy8gUmVoYXNoIHRoZSB0YWJsZSBpZiB0aGUgdGhyZXNob2xkIGlzIGV4Y2VlZGVkCi0gICAgICAgICAgICByZWhhc2goKTsKLSAgICAgICAgICAgIGJ1Y2tldCA9IGhhc2goc3ltYm9sKSAlIGZUYWJsZVNpemU7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoY29sbGlzaW9uQ291bnQgPj0gZkNvbGxpc2lvblRocmVzaG9sZCkgewotICAgICAgICAgICAgLy8gU2VsZWN0IGEgbmV3IGhhc2ggZnVuY3Rpb24gYW5kIHJlaGFzaCB0aGUgdGFibGUgaWYKLSAgICAgICAgICAgIC8vIHRoZSBjb2xsaXNpb24gdGhyZXNob2xkIGlzIGV4Y2VlZGVkLgotICAgICAgICAgICAgcmViYWxhbmNlKCk7Ci0gICAgICAgICAgICBidWNrZXQgPSBoYXNoKHN5bWJvbCkgJSBmVGFibGVTaXplOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gY3JlYXRlIG5ldyBlbnRyeQotICAgICAgICBFbnRyeSBlbnRyeSA9IG5ldyBFbnRyeShzeW1ib2wsIGZCdWNrZXRzW2J1Y2tldF0pOwotICAgICAgICBmQnVja2V0c1tidWNrZXRdID0gZW50cnk7Ci0gICAgICAgICsrZkNvdW50OwotICAgICAgICByZXR1cm4gZW50cnkuc3ltYm9sOwotCi0gICAgfSAvLyBhZGRTeW1ib2wwKFN0cmluZyxpbnQsaW50KTpTdHJpbmcKLQotICAgIC8qKgotICAgICAqIEFkZHMgdGhlIHNwZWNpZmllZCBzeW1ib2wgdG8gdGhlIHN5bWJvbCB0YWJsZSBhbmQgcmV0dXJucyBhCi0gICAgICogcmVmZXJlbmNlIHRvIHRoZSB1bmlxdWUgc3ltYm9sLiBJZiB0aGUgc3ltYm9sIGFscmVhZHkgZXhpc3RzLAotICAgICAqIHRoZSBwcmV2aW91cyBzeW1ib2wgcmVmZXJlbmNlIGlzIHJldHVybmVkIGluc3RlYWQsIGluIG9yZGVyCi0gICAgICogZ3VhcmFudGVlIHRoYXQgc3ltYm9sIHJlZmVyZW5jZXMgcmVtYWluIHVuaXF1ZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBidWZmZXIgVGhlIGJ1ZmZlciBjb250YWluaW5nIHRoZSBuZXcgc3ltYm9sLgotICAgICAqIEBwYXJhbSBvZmZzZXQgVGhlIG9mZnNldCBpbnRvIHRoZSBidWZmZXIgb2YgdGhlIG5ldyBzeW1ib2wuCi0gICAgICogQHBhcmFtIGxlbmd0aCBUaGUgbGVuZ3RoIG9mIHRoZSBuZXcgc3ltYm9sIGluIHRoZSBidWZmZXIuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBhZGRTeW1ib2woY2hhcltdIGJ1ZmZlciwgaW50IG9mZnNldCwgaW50IGxlbmd0aCkgewotCi0gICAgICAgIC8vIHNlYXJjaCBmb3IgaWRlbnRpY2FsIHN5bWJvbAotICAgICAgICBpbnQgY29sbGlzaW9uQ291bnQgPSAwOwotICAgICAgICBpbnQgYnVja2V0ID0gaGFzaChidWZmZXIsIG9mZnNldCwgbGVuZ3RoKSAlIGZUYWJsZVNpemU7Ci0gICAgICAgIE9VVEVSOiBmb3IgKEVudHJ5IGVudHJ5ID0gZkJ1Y2tldHNbYnVja2V0XTsgZW50cnkgIT0gbnVsbDsgZW50cnkgPSBlbnRyeS5uZXh0KSB7Ci0gICAgICAgICAgICBpZiAobGVuZ3RoID09IGVudHJ5LmNoYXJhY3RlcnMubGVuZ3RoKSB7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykgewotICAgICAgICAgICAgICAgICAgICBpZiAoYnVmZmVyW29mZnNldCArIGldICE9IGVudHJ5LmNoYXJhY3RlcnNbaV0pIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICsrY29sbGlzaW9uQ291bnQ7Ci0gICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZSBPVVRFUjsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICByZXR1cm4gZW50cnkuc3ltYm9sOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgKytjb2xsaXNpb25Db3VudDsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gYWRkU3ltYm9sMChidWZmZXIsIG9mZnNldCwgbGVuZ3RoLCBidWNrZXQsIGNvbGxpc2lvbkNvdW50KTsKLQotICAgIH0gLy8gYWRkU3ltYm9sKGNoYXJbXSxpbnQsaW50KTpTdHJpbmcKLQotICAgIHByaXZhdGUgU3RyaW5nIGFkZFN5bWJvbDAoY2hhcltdIGJ1ZmZlciwgaW50IG9mZnNldCwgaW50IGxlbmd0aCwgaW50IGJ1Y2tldCwgaW50IGNvbGxpc2lvbkNvdW50KSB7Ci0KLSAgICAgICAgaWYgKGZDb3VudCA+PSBmVGhyZXNob2xkKSB7Ci0gICAgICAgICAgICAvLyBSZWhhc2ggdGhlIHRhYmxlIGlmIHRoZSB0aHJlc2hvbGQgaXMgZXhjZWVkZWQKLSAgICAgICAgICAgIHJlaGFzaCgpOwotICAgICAgICAgICAgYnVja2V0ID0gaGFzaChidWZmZXIsIG9mZnNldCwgbGVuZ3RoKSAlIGZUYWJsZVNpemU7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoY29sbGlzaW9uQ291bnQgPj0gZkNvbGxpc2lvblRocmVzaG9sZCkgewotICAgICAgICAgICAgLy8gU2VsZWN0IGEgbmV3IGhhc2ggZnVuY3Rpb24gYW5kIHJlaGFzaCB0aGUgdGFibGUgaWYKLSAgICAgICAgICAgIC8vIHRoZSBjb2xsaXNpb24gdGhyZXNob2xkIGlzIGV4Y2VlZGVkLgotICAgICAgICAgICAgcmViYWxhbmNlKCk7Ci0gICAgICAgICAgICBidWNrZXQgPSBoYXNoKGJ1ZmZlciwgb2Zmc2V0LCBsZW5ndGgpICUgZlRhYmxlU2l6ZTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIGFkZCBuZXcgZW50cnkKLSAgICAgICAgRW50cnkgZW50cnkgPSBuZXcgRW50cnkoYnVmZmVyLCBvZmZzZXQsIGxlbmd0aCwgZkJ1Y2tldHNbYnVja2V0XSk7Ci0gICAgICAgIGZCdWNrZXRzW2J1Y2tldF0gPSBlbnRyeTsKLSAgICAgICAgKytmQ291bnQ7Ci0gICAgICAgIHJldHVybiBlbnRyeS5zeW1ib2w7Ci0KLSAgICB9IC8vIGFkZFN5bWJvbDAoY2hhcltdLGludCxpbnQsaW50LGludCk6U3RyaW5nCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGEgaGFzaGNvZGUgdmFsdWUgZm9yIHRoZSBzcGVjaWZpZWQgc3ltYm9sLiBUaGUgdmFsdWUKLSAgICAgKiByZXR1cm5lZCBieSB0aGlzIG1ldGhvZCBtdXN0IGJlIGlkZW50aWNhbCB0byB0aGUgdmFsdWUgcmV0dXJuZWQKLSAgICAgKiBieSB0aGUgPGNvZGU+aGFzaChjaGFyW10saW50LGludCk8L2NvZGU+IG1ldGhvZCB3aGVuIGNhbGxlZAotICAgICAqIHdpdGggdGhlIGNoYXJhY3RlciBhcnJheSB0aGF0IGNvbXByaXNlcyB0aGUgc3ltYm9sIHN0cmluZy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzeW1ib2wgVGhlIHN5bWJvbCB0byBoYXNoLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgaGFzaChTdHJpbmcgc3ltYm9sKSB7Ci0gICAgICAgIGlmIChmSGFzaE11bHRpcGxpZXJzID09IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBzeW1ib2wuaGFzaENvZGUoKSAmIDB4N0ZGRkZGRkY7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGhhc2gwKHN5bWJvbCk7Ci0gICAgfSAvLyBoYXNoKFN0cmluZyk6aW50Ci0KLSAgICBwcml2YXRlIGludCBoYXNoMChTdHJpbmcgc3ltYm9sKSB7Ci0gICAgICAgIGludCBjb2RlID0gMDsKLSAgICAgICAgZmluYWwgaW50IGxlbmd0aCA9IHN5bWJvbC5sZW5ndGgoKTsKLSAgICAgICAgZmluYWwgaW50W10gbXVsdGlwbGllcnMgPSBmSGFzaE11bHRpcGxpZXJzOwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7Ci0gICAgICAgICAgICBjb2RlID0gY29kZSAqIG11bHRpcGxpZXJzW2kgJiBNVUxUSVBMSUVSU19NQVNLXSArIHN5bWJvbC5jaGFyQXQoaSk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGNvZGUgJiAweDdGRkZGRkZGOwotICAgIH0gLy8gaGFzaDAoU3RyaW5nKTppbnQKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYSBoYXNoY29kZSB2YWx1ZSBmb3IgdGhlIHNwZWNpZmllZCBzeW1ib2wgaW5mb3JtYXRpb24uCi0gICAgICogVGhlIHZhbHVlIHJldHVybmVkIGJ5IHRoaXMgbWV0aG9kIG11c3QgYmUgaWRlbnRpY2FsIHRvIHRoZSB2YWx1ZQotICAgICAqIHJldHVybmVkIGJ5IHRoZSA8Y29kZT5oYXNoKFN0cmluZyk8L2NvZGU+IG1ldGhvZCB3aGVuIGNhbGxlZAotICAgICAqIHdpdGggdGhlIHN0cmluZyBvYmplY3QgY3JlYXRlZCBmcm9tIHRoZSBzeW1ib2wgaW5mb3JtYXRpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYnVmZmVyIFRoZSBjaGFyYWN0ZXIgYnVmZmVyIGNvbnRhaW5pbmcgdGhlIHN5bWJvbC4KLSAgICAgKiBAcGFyYW0gb2Zmc2V0IFRoZSBvZmZzZXQgaW50byB0aGUgY2hhcmFjdGVyIGJ1ZmZlciBvZiB0aGUgc3RhcnQKLSAgICAgKiAgICAgICAgICAgICAgIG9mIHRoZSBzeW1ib2wuCi0gICAgICogQHBhcmFtIGxlbmd0aCBUaGUgbGVuZ3RoIG9mIHRoZSBzeW1ib2wuCi0gICAgICovCi0gICAgcHVibGljIGludCBoYXNoKGNoYXJbXSBidWZmZXIsIGludCBvZmZzZXQsIGludCBsZW5ndGgpIHsKLSAgICAgICAgaWYgKGZIYXNoTXVsdGlwbGllcnMgPT0gbnVsbCkgewotICAgICAgICAgICAgaW50IGNvZGUgPSAwOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkgewotICAgICAgICAgICAgICAgIGNvZGUgPSBjb2RlICogMzEgKyBidWZmZXJbb2Zmc2V0ICsgaV07Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gY29kZSAmIDB4N0ZGRkZGRkY7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGhhc2gwKGJ1ZmZlciwgb2Zmc2V0LCBsZW5ndGgpOwotCi0gICAgfSAvLyBoYXNoKGNoYXJbXSxpbnQsaW50KTppbnQKLQotICAgIHByaXZhdGUgaW50IGhhc2gwKGNoYXJbXSBidWZmZXIsIGludCBvZmZzZXQsIGludCBsZW5ndGgpIHsKLSAgICAgICAgaW50IGNvZGUgPSAwOwotICAgICAgICBmaW5hbCBpbnRbXSBtdWx0aXBsaWVycyA9IGZIYXNoTXVsdGlwbGllcnM7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyArK2kpIHsKLSAgICAgICAgICAgIGNvZGUgPSBjb2RlICogbXVsdGlwbGllcnNbaSAmIE1VTFRJUExJRVJTX01BU0tdICsgYnVmZmVyW29mZnNldCArIGldOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBjb2RlICYgMHg3RkZGRkZGRjsKLSAgICB9IC8vIGhhc2gwKGNoYXJbXSxpbnQsaW50KTppbnQKLQotICAgIC8qKgotICAgICAqIEluY3JlYXNlcyB0aGUgY2FwYWNpdHkgb2YgYW5kIGludGVybmFsbHkgcmVvcmdhbml6ZXMgdGhpcwotICAgICAqIFN5bWJvbFRhYmxlLCBpbiBvcmRlciB0byBhY2NvbW1vZGF0ZSBhbmQgYWNjZXNzIGl0cyBlbnRyaWVzIG1vcmUKLSAgICAgKiBlZmZpY2llbnRseS4gIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBhdXRvbWF0aWNhbGx5IHdoZW4gdGhlCi0gICAgICogbnVtYmVyIG9mIGtleXMgaW4gdGhlIFN5bWJvbFRhYmxlIGV4Y2VlZHMgdGhpcyBoYXNodGFibGUncyBjYXBhY2l0eQotICAgICAqIGFuZCBsb2FkIGZhY3Rvci4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCByZWhhc2goKSB7Ci0gICAgICAgIHJlaGFzaENvbW1vbihmQnVja2V0cy5sZW5ndGggKiAyICsgMSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmFuZG9tbHkgc2VsZWN0cyBhIG5ldyBoYXNoIGZ1bmN0aW9uIGFuZCByZW9yZ2FuaXplcyB0aGlzIFN5bWJvbFRhYmxlCi0gICAgICogaW4gb3JkZXIgdG8gbW9yZSBldmVubHkgZGlzdHJpYnV0ZSBpdHMgZW50cmllcyBhY3Jvc3MgdGhlIHRhYmxlLiBUaGlzCi0gICAgICogbWV0aG9kIGlzIGNhbGxlZCBhdXRvbWF0aWNhbGx5IHdoZW4gdGhlIG51bWJlciBrZXlzIGluIG9uZSBvZiB0aGUKLSAgICAgKiBTeW1ib2xUYWJsZSdzIGJ1Y2tldHMgZXhjZWVkcyB0aGUgZ2l2ZW4gY29sbGlzaW9uIHRocmVzaG9sZC4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCByZWJhbGFuY2UoKSB7Ci0gICAgICAgIGlmIChmSGFzaE11bHRpcGxpZXJzID09IG51bGwpIHsKLSAgICAgICAgICAgIGZIYXNoTXVsdGlwbGllcnMgPSBuZXcgaW50W01VTFRJUExJRVJTX1NJWkVdOwotICAgICAgICB9Ci0gICAgICAgIFByaW1lTnVtYmVyU2VxdWVuY2VHZW5lcmF0b3IuZ2VuZXJhdGVTZXF1ZW5jZShmSGFzaE11bHRpcGxpZXJzKTsKLSAgICAgICAgcmVoYXNoQ29tbW9uKGZCdWNrZXRzLmxlbmd0aCk7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIHJlaGFzaENvbW1vbihmaW5hbCBpbnQgbmV3Q2FwYWNpdHkpIHsKLQotICAgICAgICBpbnQgb2xkQ2FwYWNpdHkgPSBmQnVja2V0cy5sZW5ndGg7Ci0gICAgICAgIEVudHJ5W10gb2xkVGFibGUgPSBmQnVja2V0czsKLQotICAgICAgICBFbnRyeVtdIG5ld1RhYmxlID0gbmV3IEVudHJ5W25ld0NhcGFjaXR5XTsKLQotICAgICAgICBmVGhyZXNob2xkID0gKGludCkobmV3Q2FwYWNpdHkgKiBmTG9hZEZhY3Rvcik7Ci0gICAgICAgIGZCdWNrZXRzID0gbmV3VGFibGU7Ci0gICAgICAgIGZUYWJsZVNpemUgPSBmQnVja2V0cy5sZW5ndGg7Ci0KLSAgICAgICAgZm9yIChpbnQgaSA9IG9sZENhcGFjaXR5IDsgaS0tID4gMCA7KSB7Ci0gICAgICAgICAgICBmb3IgKEVudHJ5IG9sZCA9IG9sZFRhYmxlW2ldIDsgb2xkICE9IG51bGwgOyApIHsKLSAgICAgICAgICAgICAgICBFbnRyeSBlID0gb2xkOwotICAgICAgICAgICAgICAgIG9sZCA9IG9sZC5uZXh0OwotCi0gICAgICAgICAgICAgICAgaW50IGluZGV4ID0gaGFzaChlLnN5bWJvbCkgJSBuZXdDYXBhY2l0eTsKLSAgICAgICAgICAgICAgICBlLm5leHQgPSBuZXdUYWJsZVtpbmRleF07Ci0gICAgICAgICAgICAgICAgbmV3VGFibGVbaW5kZXhdID0gZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgc3ltYm9sIHRhYmxlIGFscmVhZHkgY29udGFpbnMgdGhlIHNwZWNpZmllZAotICAgICAqIHN5bWJvbC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzeW1ib2wgVGhlIHN5bWJvbCB0byBsb29rIGZvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1N5bWJvbChTdHJpbmcgc3ltYm9sKSB7Ci0KLSAgICAgICAgLy8gc2VhcmNoIGZvciBpZGVudGljYWwgc3ltYm9sCi0gICAgICAgIGludCBidWNrZXQgPSBoYXNoKHN5bWJvbCkgJSBmVGFibGVTaXplOwotICAgICAgICBpbnQgbGVuZ3RoID0gc3ltYm9sLmxlbmd0aCgpOwotICAgICAgICBPVVRFUjogZm9yIChFbnRyeSBlbnRyeSA9IGZCdWNrZXRzW2J1Y2tldF07IGVudHJ5ICE9IG51bGw7IGVudHJ5ID0gZW50cnkubmV4dCkgewotICAgICAgICAgICAgaWYgKGxlbmd0aCA9PSBlbnRyeS5jaGFyYWN0ZXJzLmxlbmd0aCkgewotICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKHN5bWJvbC5jaGFyQXQoaSkgIT0gZW50cnkuY2hhcmFjdGVyc1tpXSkgewotICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWUgT1VURVI7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gZmFsc2U7Ci0KLSAgICB9IC8vIGNvbnRhaW5zU3ltYm9sKFN0cmluZyk6Ym9vbGVhbgotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBzeW1ib2wgdGFibGUgYWxyZWFkeSBjb250YWlucyB0aGUgc3BlY2lmaWVkCi0gICAgICogc3ltYm9sLgotICAgICAqCi0gICAgICogQHBhcmFtIGJ1ZmZlciBUaGUgYnVmZmVyIGNvbnRhaW5pbmcgdGhlIHN5bWJvbCB0byBsb29rIGZvci4KLSAgICAgKiBAcGFyYW0gb2Zmc2V0IFRoZSBvZmZzZXQgaW50byB0aGUgYnVmZmVyLgotICAgICAqIEBwYXJhbSBsZW5ndGggVGhlIGxlbmd0aCBvZiB0aGUgc3ltYm9sIGluIHRoZSBidWZmZXIuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNTeW1ib2woY2hhcltdIGJ1ZmZlciwgaW50IG9mZnNldCwgaW50IGxlbmd0aCkgewotCi0gICAgICAgIC8vIHNlYXJjaCBmb3IgaWRlbnRpY2FsIHN5bWJvbAotICAgICAgICBpbnQgYnVja2V0ID0gaGFzaChidWZmZXIsIG9mZnNldCwgbGVuZ3RoKSAlIGZUYWJsZVNpemU7Ci0gICAgICAgIE9VVEVSOiBmb3IgKEVudHJ5IGVudHJ5ID0gZkJ1Y2tldHNbYnVja2V0XTsgZW50cnkgIT0gbnVsbDsgZW50cnkgPSBlbnRyeS5uZXh0KSB7Ci0gICAgICAgICAgICBpZiAobGVuZ3RoID09IGVudHJ5LmNoYXJhY3RlcnMubGVuZ3RoKSB7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykgewotICAgICAgICAgICAgICAgICAgICBpZiAoYnVmZmVyW29mZnNldCArIGldICE9IGVudHJ5LmNoYXJhY3RlcnNbaV0pIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlIE9VVEVSOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIGZhbHNlOwotCi0gICAgfSAvLyBjb250YWluc1N5bWJvbChjaGFyW10saW50LGludCk6Ym9vbGVhbgotCi0gICAgLy8KLSAgICAvLyBDbGFzc2VzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFRoaXMgY2xhc3MgaXMgYSBzeW1ib2wgdGFibGUgZW50cnkuIEVhY2ggZW50cnkgYWN0cyBhcyBhIG5vZGUKLSAgICAgKiBpbiBhIGxpbmtlZCBsaXN0LgotICAgICAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgY2xhc3MgRW50cnkgewotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIERhdGEKLSAgICAgICAgLy8KLQotICAgICAgICAvKiogU3ltYm9sLiAqLwotICAgICAgICBwdWJsaWMgZmluYWwgU3RyaW5nIHN5bWJvbDsKLQotICAgICAgICAvKioKLSAgICAgICAgICogU3ltYm9sIGNoYXJhY3RlcnMuIFRoaXMgaW5mb3JtYXRpb24gaXMgZHVwbGljYXRlZCBoZXJlIGZvcgotICAgICAgICAgKiBjb21wYXJpc29uIHBlcmZvcm1hbmNlLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIGZpbmFsIGNoYXJbXSBjaGFyYWN0ZXJzOwotCi0gICAgICAgIC8qKiBUaGUgbmV4dCBlbnRyeS4gKi8KLSAgICAgICAgcHVibGljIEVudHJ5IG5leHQ7Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gQ29uc3RydWN0b3JzCi0gICAgICAgIC8vCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIENvbnN0cnVjdHMgYSBuZXcgZW50cnkgZnJvbSB0aGUgc3BlY2lmaWVkIHN5bWJvbCBhbmQgbmV4dCBlbnRyeQotICAgICAgICAgKiByZWZlcmVuY2UuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgRW50cnkoU3RyaW5nIHN5bWJvbCwgRW50cnkgbmV4dCkgewotICAgICAgICAgICAgdGhpcy5zeW1ib2wgPSBzeW1ib2wuaW50ZXJuKCk7Ci0gICAgICAgICAgICBjaGFyYWN0ZXJzID0gbmV3IGNoYXJbc3ltYm9sLmxlbmd0aCgpXTsKLSAgICAgICAgICAgIHN5bWJvbC5nZXRDaGFycygwLCBjaGFyYWN0ZXJzLmxlbmd0aCwgY2hhcmFjdGVycywgMCk7Ci0gICAgICAgICAgICB0aGlzLm5leHQgPSBuZXh0OwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIENvbnN0cnVjdHMgYSBuZXcgZW50cnkgZnJvbSB0aGUgc3BlY2lmaWVkIHN5bWJvbCBpbmZvcm1hdGlvbiBhbmQKLSAgICAgICAgICogbmV4dCBlbnRyeSByZWZlcmVuY2UuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgRW50cnkoY2hhcltdIGNoLCBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoLCBFbnRyeSBuZXh0KSB7Ci0gICAgICAgICAgICBjaGFyYWN0ZXJzID0gbmV3IGNoYXJbbGVuZ3RoXTsKLSAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoY2gsIG9mZnNldCwgY2hhcmFjdGVycywgMCwgbGVuZ3RoKTsKLSAgICAgICAgICAgIHN5bWJvbCA9IG5ldyBTdHJpbmcoY2hhcmFjdGVycykuaW50ZXJuKCk7Ci0gICAgICAgICAgICB0aGlzLm5leHQgPSBuZXh0OwotICAgICAgICB9Ci0KLSAgICB9IC8vIGNsYXNzIEVudHJ5Ci0KLX0gLy8gY2xhc3MgU3ltYm9sVGFibGUKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3V0aWwvU3luY2hyb25pemVkU3ltYm9sVGFibGUuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3V0aWwvU3luY2hyb25pemVkU3ltYm9sVGFibGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDIwODZlZi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL1N5bmNocm9uaXplZFN5bWJvbFRhYmxlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMjkgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMC0yMDAyLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbDsKLQotLyoqCi0gKiBTeW5jaHJvbml6ZWQgc3ltYm9sIHRhYmxlLgotICoKLSAqIFRoaXMgY2xhc3MgbW92ZWQgaW50byB0aGUgdXRpbCBwYWNrYWdlIHNpbmNlIGl0J3MgbmVlZGVkIGJ5IG11bHRpcGxlCi0gKiBvdGhlciBjbGFzc2VzIChDYWNoaW5nUGFyc2VyUG9vbCwgWE1MR3JhbW1hckNhY2hpbmdDb25maWd1cmF0aW9uKS4KLSAqCi0gKiBAYXV0aG9yIEFuZHkgQ2xhcmssIElCTQotICovCi0KLXB1YmxpYyBmaW5hbCBjbGFzcyBTeW5jaHJvbml6ZWRTeW1ib2xUYWJsZQotICAgIGV4dGVuZHMgU3ltYm9sVGFibGUgewotCi0gICAgLy8KLSAgICAvLyBEYXRhCi0gICAgLy8KLQotICAgIC8qKiBNYWluIHN5bWJvbCB0YWJsZS4gKi8KLSAgICBwcm90ZWN0ZWQgU3ltYm9sVGFibGUgZlN5bWJvbFRhYmxlOwotCi0gICAgLy8KLSAgICAvLyBDb25zdHJ1Y3RvcnMKLSAgICAvLwotCi0gICAgLyoqIENvbnN0cnVjdHMgYSBzeW5jaHJvbml6ZWQgc3ltYm9sIHRhYmxlLiAqLwotICAgIHB1YmxpYyBTeW5jaHJvbml6ZWRTeW1ib2xUYWJsZShTeW1ib2xUYWJsZSBzeW1ib2xUYWJsZSkgewotICAgICAgICBmU3ltYm9sVGFibGUgPSBzeW1ib2xUYWJsZTsKLSAgICB9IC8vIDxpbml0PihTeW1ib2xUYWJsZSkKLQotICAgIC8vIGNvbnN0cnVjdCBzeW5jaHJvbml6ZWQgc3ltYm9sIHRhYmxlIG9mIGRlZmF1bHQgc2l6ZQotICAgIHB1YmxpYyBTeW5jaHJvbml6ZWRTeW1ib2xUYWJsZSgpIHsKLSAgICAgICAgZlN5bWJvbFRhYmxlID0gbmV3IFN5bWJvbFRhYmxlKCk7Ci0gICAgfSAvLyBpbml0KCkKLQotICAgIC8vIGNvbnN0cnVjdCBzeW5jaHJvbml6ZWQgc3ltYm9sIHRhYmxlIG9mIGdpdmVuIHNpemUKLSAgICBwdWJsaWMgU3luY2hyb25pemVkU3ltYm9sVGFibGUoaW50IHNpemUpIHsKLSAgICAgICAgZlN5bWJvbFRhYmxlID0gbmV3IFN5bWJvbFRhYmxlKHNpemUpOwotICAgIH0gLy8gaW5pdChpbnQpCi0KLSAgICAvLwotICAgIC8vIFN5bWJvbFRhYmxlIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogQWRkcyB0aGUgc3BlY2lmaWVkIHN5bWJvbCB0byB0aGUgc3ltYm9sIHRhYmxlIGFuZCByZXR1cm5zIGEKLSAgICAgKiByZWZlcmVuY2UgdG8gdGhlIHVuaXF1ZSBzeW1ib2wuIElmIHRoZSBzeW1ib2wgYWxyZWFkeSBleGlzdHMsCi0gICAgICogdGhlIHByZXZpb3VzIHN5bWJvbCByZWZlcmVuY2UgaXMgcmV0dXJuZWQgaW5zdGVhZCwgaW4gb3JkZXIKLSAgICAgKiBndWFyYW50ZWUgdGhhdCBzeW1ib2wgcmVmZXJlbmNlcyByZW1haW4gdW5pcXVlLgotICAgICAqCi0gICAgICogQHBhcmFtIHN5bWJvbCBUaGUgbmV3IHN5bWJvbC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGFkZFN5bWJvbChTdHJpbmcgc3ltYm9sKSB7Ci0KLSAgICAgICAgc3luY2hyb25pemVkIChmU3ltYm9sVGFibGUpIHsKLSAgICAgICAgICAgIHJldHVybiBmU3ltYm9sVGFibGUuYWRkU3ltYm9sKHN5bWJvbCk7Ci0gICAgICAgIH0KLQotICAgIH0gLy8gYWRkU3ltYm9sKFN0cmluZykKLQotICAgIC8qKgotICAgICAqIEFkZHMgdGhlIHNwZWNpZmllZCBzeW1ib2wgdG8gdGhlIHN5bWJvbCB0YWJsZSBhbmQgcmV0dXJucyBhCi0gICAgICogcmVmZXJlbmNlIHRvIHRoZSB1bmlxdWUgc3ltYm9sLiBJZiB0aGUgc3ltYm9sIGFscmVhZHkgZXhpc3RzLAotICAgICAqIHRoZSBwcmV2aW91cyBzeW1ib2wgcmVmZXJlbmNlIGlzIHJldHVybmVkIGluc3RlYWQsIGluIG9yZGVyCi0gICAgICogZ3VhcmFudGVlIHRoYXQgc3ltYm9sIHJlZmVyZW5jZXMgcmVtYWluIHVuaXF1ZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBidWZmZXIgVGhlIGJ1ZmZlciBjb250YWluaW5nIHRoZSBuZXcgc3ltYm9sLgotICAgICAqIEBwYXJhbSBvZmZzZXQgVGhlIG9mZnNldCBpbnRvIHRoZSBidWZmZXIgb2YgdGhlIG5ldyBzeW1ib2wuCi0gICAgICogQHBhcmFtIGxlbmd0aCBUaGUgbGVuZ3RoIG9mIHRoZSBuZXcgc3ltYm9sIGluIHRoZSBidWZmZXIuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBhZGRTeW1ib2woY2hhcltdIGJ1ZmZlciwgaW50IG9mZnNldCwgaW50IGxlbmd0aCkgewotCi0gICAgICAgIHN5bmNocm9uaXplZCAoZlN5bWJvbFRhYmxlKSB7Ci0gICAgICAgICAgICByZXR1cm4gZlN5bWJvbFRhYmxlLmFkZFN5bWJvbChidWZmZXIsIG9mZnNldCwgbGVuZ3RoKTsKLSAgICAgICAgfQotCi0gICAgfSAvLyBhZGRTeW1ib2woY2hhcltdLGludCxpbnQpOlN0cmluZwotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBzeW1ib2wgdGFibGUgYWxyZWFkeSBjb250YWlucyB0aGUgc3BlY2lmaWVkCi0gICAgICogc3ltYm9sLgotICAgICAqCi0gICAgICogQHBhcmFtIHN5bWJvbCBUaGUgc3ltYm9sIHRvIGxvb2sgZm9yLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zU3ltYm9sKFN0cmluZyBzeW1ib2wpIHsKLQotICAgICAgICBzeW5jaHJvbml6ZWQgKGZTeW1ib2xUYWJsZSkgewotICAgICAgICAgICAgcmV0dXJuIGZTeW1ib2xUYWJsZS5jb250YWluc1N5bWJvbChzeW1ib2wpOwotICAgICAgICB9Ci0KLSAgICB9IC8vIGNvbnRhaW5zU3ltYm9sKFN0cmluZyk6Ym9vbGVhbgotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBzeW1ib2wgdGFibGUgYWxyZWFkeSBjb250YWlucyB0aGUgc3BlY2lmaWVkCi0gICAgICogc3ltYm9sLgotICAgICAqCi0gICAgICogQHBhcmFtIGJ1ZmZlciBUaGUgYnVmZmVyIGNvbnRhaW5pbmcgdGhlIHN5bWJvbCB0byBsb29rIGZvci4KLSAgICAgKiBAcGFyYW0gb2Zmc2V0IFRoZSBvZmZzZXQgaW50byB0aGUgYnVmZmVyLgotICAgICAqIEBwYXJhbSBsZW5ndGggVGhlIGxlbmd0aCBvZiB0aGUgc3ltYm9sIGluIHRoZSBidWZmZXIuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNTeW1ib2woY2hhcltdIGJ1ZmZlciwgaW50IG9mZnNldCwgaW50IGxlbmd0aCkgewotCi0gICAgICAgIHN5bmNocm9uaXplZCAoZlN5bWJvbFRhYmxlKSB7Ci0gICAgICAgICAgICByZXR1cm4gZlN5bWJvbFRhYmxlLmNvbnRhaW5zU3ltYm9sKGJ1ZmZlciwgb2Zmc2V0LCBsZW5ndGgpOwotICAgICAgICB9Ci0KLSAgICB9IC8vIGNvbnRhaW5zU3ltYm9sKGNoYXJbXSxpbnQsaW50KTpib29sZWFuCi0KLX0gLy8gY2xhc3MgU3luY2hyb25pemVkU3ltYm9sVGFibGUKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3V0aWwvVGVlWE1MRG9jdW1lbnRGaWx0ZXJJbXBsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL1RlZVhNTERvY3VtZW50RmlsdGVySW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhN2RhNzA2Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3V0aWwvVGVlWE1MRG9jdW1lbnRGaWx0ZXJJbXBsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMTcgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMC0yMDAyIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGVyY2VzIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBJbnRlcm5hdGlvbmFsCi0gKiBCdXNpbmVzcyBNYWNoaW5lcywgSW5jLiwgaHR0cDovL3d3dy5hcGFjaGUub3JnLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbDsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLkF1Z21lbnRhdGlvbnM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuTmFtZXNwYWNlQ29udGV4dDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5RTmFtZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxBdHRyaWJ1dGVzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTERvY3VtZW50SGFuZGxlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxMb2NhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTFJlc291cmNlSWRlbnRpZmllcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxTdHJpbmc7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE5JRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxEb2N1bWVudEZpbHRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MRG9jdW1lbnRTb3VyY2U7Ci0KLS8qKgotICoKLSAqCi0gKiBAYXV0aG9yCi0gKiAgICAgS29oc3VrZSBLYXdhZ3VjaGkgKGtvaHN1a2Uua2F3YWd1Y2hpQHN1bi5jb20pCi0gKi8KLXB1YmxpYyBjbGFzcyBUZWVYTUxEb2N1bWVudEZpbHRlckltcGwgaW1wbGVtZW50cyBYTUxEb2N1bWVudEZpbHRlciB7Ci0gICAgLyoqCi0gICAgICogVGhlIG5leHQgY29tcG9uZW50IGluIHRoZSBwaXBlbGluZSB3aG8gcmVjZWl2ZXMgdGhlIGV2ZW50LgotICAgICAqIFRoaXMgY29tcG9uZW50IHJlY2VpdmVzIGV2ZW50cyBhZnRlciB0aGUgInNpZGUiIGhhbmRsZXIKLSAgICAgKiByZWNlaXZlcyB0aGVtLgotICAgICAqLwotICAgIHByaXZhdGUgWE1MRG9jdW1lbnRIYW5kbGVyIG5leHQ7Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgY29tcG9uZW50IHdobyBpbnRlcmNlcHRzIGV2ZW50cy4KLSAgICAgKi8KLSAgICBwcml2YXRlIFhNTERvY3VtZW50SGFuZGxlciBzaWRlOwotCi0gICAgLyoqCi0gICAgICogVGhlIHNvdXJjZSBvZiB0aGUgZXZlbnQuCi0gICAgICovCi0gICAgcHJpdmF0ZSBYTUxEb2N1bWVudFNvdXJjZSBzb3VyY2U7Ci0KLQotCi0gICAgcHVibGljIFhNTERvY3VtZW50SGFuZGxlciBnZXRTaWRlKCkgewotICAgICAgICByZXR1cm4gc2lkZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRTaWRlKFhNTERvY3VtZW50SGFuZGxlciBzaWRlKSB7Ci0gICAgICAgIHRoaXMuc2lkZSA9IHNpZGU7Ci0gICAgfQotCi0gICAgcHVibGljIFhNTERvY3VtZW50U291cmNlIGdldERvY3VtZW50U291cmNlKCkgewotICAgICAgICByZXR1cm4gc291cmNlOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldERvY3VtZW50U291cmNlKFhNTERvY3VtZW50U291cmNlIHNvdXJjZSkgewotICAgICAgICB0aGlzLnNvdXJjZSA9IHNvdXJjZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgWE1MRG9jdW1lbnRIYW5kbGVyIGdldERvY3VtZW50SGFuZGxlcigpIHsKLSAgICAgICAgcmV0dXJuIG5leHQ7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0RG9jdW1lbnRIYW5kbGVyKFhNTERvY3VtZW50SGFuZGxlciBoYW5kbGVyKSB7Ci0gICAgICAgIG5leHQgPSBoYW5kbGVyOwotICAgIH0KLQotLy8KLS8vCi0vLyBYTUxEb2N1bWVudEhhbmRsZXIgaW1wbGVtZW50YXRpb24KLS8vCi0vLwotICAgIHB1YmxpYyB2b2lkIGNoYXJhY3RlcnMoWE1MU3RyaW5nIHRleHQsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIHNpZGUuY2hhcmFjdGVycyh0ZXh0LCBhdWdzKTsKLSAgICAgICAgbmV4dC5jaGFyYWN0ZXJzKHRleHQsIGF1Z3MpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGNvbW1lbnQoWE1MU3RyaW5nIHRleHQsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIHNpZGUuY29tbWVudCh0ZXh0LCBhdWdzKTsKLSAgICAgICAgbmV4dC5jb21tZW50KHRleHQsIGF1Z3MpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGRvY3R5cGVEZWNsKFN0cmluZyByb290RWxlbWVudCwgU3RyaW5nIHB1YmxpY0lkLCBTdHJpbmcgc3lzdGVtSWQsIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIHNpZGUuZG9jdHlwZURlY2wocm9vdEVsZW1lbnQsIHB1YmxpY0lkLCBzeXN0ZW1JZCwgYXVncyk7Ci0gICAgICAgIG5leHQuZG9jdHlwZURlY2wocm9vdEVsZW1lbnQsIHB1YmxpY0lkLCBzeXN0ZW1JZCwgYXVncyk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgZW1wdHlFbGVtZW50KFFOYW1lIGVsZW1lbnQsIFhNTEF0dHJpYnV0ZXMgYXR0cmlidXRlcywgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgc2lkZS5lbXB0eUVsZW1lbnQoZWxlbWVudCwgYXR0cmlidXRlcywgYXVncyk7Ci0gICAgICAgIG5leHQuZW1wdHlFbGVtZW50KGVsZW1lbnQsIGF0dHJpYnV0ZXMsIGF1Z3MpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGVuZENEQVRBKEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIHNpZGUuZW5kQ0RBVEEoYXVncyk7Ci0gICAgICAgIG5leHQuZW5kQ0RBVEEoYXVncyk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgZW5kRG9jdW1lbnQoQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgc2lkZS5lbmREb2N1bWVudChhdWdzKTsKLSAgICAgICAgbmV4dC5lbmREb2N1bWVudChhdWdzKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBlbmRFbGVtZW50KFFOYW1lIGVsZW1lbnQsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIHNpZGUuZW5kRWxlbWVudChlbGVtZW50LCBhdWdzKTsKLSAgICAgICAgbmV4dC5lbmRFbGVtZW50KGVsZW1lbnQsIGF1Z3MpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGVuZEdlbmVyYWxFbnRpdHkoU3RyaW5nIG5hbWUsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIHNpZGUuZW5kR2VuZXJhbEVudGl0eShuYW1lLCBhdWdzKTsKLSAgICAgICAgbmV4dC5lbmRHZW5lcmFsRW50aXR5KG5hbWUsIGF1Z3MpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGlnbm9yYWJsZVdoaXRlc3BhY2UoWE1MU3RyaW5nIHRleHQsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIHNpZGUuaWdub3JhYmxlV2hpdGVzcGFjZSh0ZXh0LCBhdWdzKTsKLSAgICAgICAgbmV4dC5pZ25vcmFibGVXaGl0ZXNwYWNlKHRleHQsIGF1Z3MpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHByb2Nlc3NpbmdJbnN0cnVjdGlvbihTdHJpbmcgdGFyZ2V0LCBYTUxTdHJpbmcgZGF0YSwgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgc2lkZS5wcm9jZXNzaW5nSW5zdHJ1Y3Rpb24odGFyZ2V0LCBkYXRhLCBhdWdzKTsKLSAgICAgICAgbmV4dC5wcm9jZXNzaW5nSW5zdHJ1Y3Rpb24odGFyZ2V0LCBkYXRhLCBhdWdzKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzdGFydENEQVRBKEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIHNpZGUuc3RhcnRDREFUQShhdWdzKTsKLSAgICAgICAgbmV4dC5zdGFydENEQVRBKGF1Z3MpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RG9jdW1lbnQoCi0gICAgICAgIFhNTExvY2F0b3IgbG9jYXRvciwKLSAgICAgICAgU3RyaW5nIGVuY29kaW5nLAotICAgICAgICBOYW1lc3BhY2VDb250ZXh0IG5hbWVzcGFjZUNvbnRleHQsCi0gICAgICAgIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIHNpZGUuc3RhcnREb2N1bWVudChsb2NhdG9yLCBlbmNvZGluZywgbmFtZXNwYWNlQ29udGV4dCwgYXVncyk7Ci0gICAgICAgIG5leHQuc3RhcnREb2N1bWVudChsb2NhdG9yLCBlbmNvZGluZywgbmFtZXNwYWNlQ29udGV4dCwgYXVncyk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc3RhcnRFbGVtZW50KFFOYW1lIGVsZW1lbnQsIFhNTEF0dHJpYnV0ZXMgYXR0cmlidXRlcywgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgc2lkZS5zdGFydEVsZW1lbnQoZWxlbWVudCwgYXR0cmlidXRlcywgYXVncyk7Ci0gICAgICAgIG5leHQuc3RhcnRFbGVtZW50KGVsZW1lbnQsIGF0dHJpYnV0ZXMsIGF1Z3MpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHN0YXJ0R2VuZXJhbEVudGl0eShTdHJpbmcgbmFtZSwgWE1MUmVzb3VyY2VJZGVudGlmaWVyIGlkZW50aWZpZXIsIFN0cmluZyBlbmNvZGluZywgQXVnbWVudGF0aW9ucyBhdWdzKQotICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgc2lkZS5zdGFydEdlbmVyYWxFbnRpdHkobmFtZSwgaWRlbnRpZmllciwgZW5jb2RpbmcsIGF1Z3MpOwotICAgICAgICBuZXh0LnN0YXJ0R2VuZXJhbEVudGl0eShuYW1lLCBpZGVudGlmaWVyLCBlbmNvZGluZywgYXVncyk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgdGV4dERlY2woU3RyaW5nIHZlcnNpb24sIFN0cmluZyBlbmNvZGluZywgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgc2lkZS50ZXh0RGVjbCh2ZXJzaW9uLCBlbmNvZGluZywgYXVncyk7Ci0gICAgICAgIG5leHQudGV4dERlY2wodmVyc2lvbiwgZW5jb2RpbmcsIGF1Z3MpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHhtbERlY2woU3RyaW5nIHZlcnNpb24sIFN0cmluZyBlbmNvZGluZywgU3RyaW5nIHN0YW5kYWxvbmUsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIHNpZGUueG1sRGVjbCh2ZXJzaW9uLCBlbmNvZGluZywgc3RhbmRhbG9uZSwgYXVncyk7Ci0gICAgICAgIG5leHQueG1sRGVjbCh2ZXJzaW9uLCBlbmNvZGluZywgc3RhbmRhbG9uZSwgYXVncyk7Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL1VSSS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9VUkkuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYTkyY2QyMC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL1VSSS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjIxMCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbDsKLQotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci1pbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7Ci1pbXBvcnQgamF2YS51dGlsLk9iamVjdHM7Ci0KLS8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0qIEEgY2xhc3MgdG8gcmVwcmVzZW50IGEgVW5pZm9ybSBSZXNvdXJjZSBJZGVudGlmaWVyIChVUkkpLiBUaGlzIGNsYXNzCi0qIGlzIGRlc2lnbmVkIHRvIGhhbmRsZSB0aGUgcGFyc2luZyBvZiBVUklzIGFuZCBwcm92aWRlIGFjY2VzcyB0bwotKiB0aGUgdmFyaW91cyBjb21wb25lbnRzIChzY2hlbWUsIGhvc3QsIHBvcnQsIHVzZXJpbmZvLCBwYXRoLCBxdWVyeQotKiBzdHJpbmcgYW5kIGZyYWdtZW50KSB0aGF0IG1heSBjb25zdGl0dXRlIGEgVVJJLgotKiA8cD4KLSogUGFyc2luZyBvZiBhIFVSSSBzcGVjaWZpY2F0aW9uIGlzIGRvbmUgYWNjb3JkaW5nIHRvIHRoZSBVUkkKLSogc3ludGF4IGRlc2NyaWJlZCBpbgotKiA8YSBocmVmPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyMzk2LnR4dD9udW1iZXI9MjM5NiI+UkZDIDIzOTY8L2E+LAotKiBhbmQgYW1lbmRlZCBieQotKiA8YSBocmVmPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyNzMyLnR4dD9udW1iZXI9MjczMiI+UkZDIDI3MzI8L2E+LgotKiA8cD4KLSogRXZlcnkgYWJzb2x1dGUgVVJJIGNvbnNpc3RzIG9mIGEgc2NoZW1lLCBmb2xsb3dlZCBieSBhIGNvbG9uICgnOicpLAotKiBmb2xsb3dlZCBieSBhIHNjaGVtZS1zcGVjaWZpYyBwYXJ0LiBGb3IgVVJJcyB0aGF0IGZvbGxvdyB0aGUKLSogImdlbmVyaWMgVVJJIiBzeW50YXgsIHRoZSBzY2hlbWUtc3BlY2lmaWMgcGFydCBiZWdpbnMgd2l0aCB0d28KLSogc2xhc2hlcyAoIi8vIikgYW5kIG1heSBiZSBmb2xsb3dlZCBieSBhbiBhdXRob3JpdHkgc2VnbWVudCAoY29tcHJpc2VkCi0qIG9mIHVzZXIgaW5mb3JtYXRpb24sIGhvc3QsIGFuZCBwb3J0KSwgcGF0aCBzZWdtZW50LCBxdWVyeSBzZWdtZW50Ci0qIGFuZCBmcmFnbWVudC4gTm90ZSB0aGF0IFJGQyAyMzk2IG5vIGxvbmdlciBzcGVjaWZpZXMgdGhlIHVzZSBvZiB0aGUKLSogcGFyYW1ldGVycyBzZWdtZW50IGFuZCBleGNsdWRlcyB0aGUgInVzZXI6cGFzc3dvcmQiIHN5bnRheCBhcyBwYXJ0IG9mCi0qIHRoZSBhdXRob3JpdHkgc2VnbWVudC4gSWYgInVzZXI6cGFzc3dvcmQiIGFwcGVhcnMgaW4gYSBVUkksIHRoZSBlbnRpcmUKLSogdXNlci9wYXNzd29yZCBzdHJpbmcgaXMgc3RvcmVkIGFzIHVzZXJpbmZvLgotKiA8cD4KLSogRm9yIFVSSXMgdGhhdCBkbyBub3QgZm9sbG93IHRoZSAiZ2VuZXJpYyBVUkkiIHN5bnRheCAoZS5nLiBtYWlsdG8pLAotKiB0aGUgZW50aXJlIHNjaGVtZS1zcGVjaWZpYyBwYXJ0IGlzIHRyZWF0ZWQgYXMgdGhlICJwYXRoIiBwb3J0aW9uCi0qIG9mIHRoZSBVUkkuCi0qIDxwPgotKiBOb3RlIHRoYXQsIHVubGlrZSB0aGUgamF2YS5uZXQuVVJMIGNsYXNzLCB0aGlzIGNsYXNzIGRvZXMgbm90IHByb3ZpZGUKLSogYW55IGJ1aWx0LWluIG5ldHdvcmsgYWNjZXNzIGZ1bmN0aW9uYWxpdHkgbm9yIGRvZXMgaXQgcHJvdmlkZSBhbnkKLSogc2NoZW1lLXNwZWNpZmljIGZ1bmN0aW9uYWxpdHkgKGZvciBleGFtcGxlLCBpdCBkb2VzIG5vdCBrbm93IGEKLSogZGVmYXVsdCBwb3J0IGZvciBhIHNwZWNpZmljIHNjaGVtZSkuIFJhdGhlciwgaXQgb25seSBrbm93cyB0aGUKLSogZ3JhbW1hciBhbmQgYmFzaWMgc2V0IG9mIG9wZXJhdGlvbnMgdGhhdCBjYW4gYmUgYXBwbGllZCB0byBhIFVSSS4KLSoKLSoKLSoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi0gcHVibGljIGNsYXNzIFVSSSBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZSB7Ci0KLSAgLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLSAgKiBNYWxmb3JtZWRVUklFeGNlcHRpb25zIGFyZSB0aHJvd24gaW4gdGhlIHByb2Nlc3Mgb2YgYnVpbGRpbmcgYSBVUkkKLSAgKiBvciBzZXR0aW5nIGZpZWxkcyBvbiBhIFVSSSB3aGVuIGFuIG9wZXJhdGlvbiB3b3VsZCByZXN1bHQgaW4gYW4KLSAgKiBpbnZhbGlkIFVSSSBzcGVjaWZpY2F0aW9uLgotICAqCi0gICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwotICBwdWJsaWMgc3RhdGljIGNsYXNzIE1hbGZvcm1lZFVSSUV4Y2VwdGlvbiBleHRlbmRzIElPRXhjZXB0aW9uIHsKLQotICAgLyoqIFNlcmlhbGl6YXRpb24gdmVyc2lvbi4gKi8KLSAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNjY5NTA1NDgzNDM0Mjk1MTkzMEw7Ci0KLSAgIC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLSAgICAqIENvbnN0cnVjdHMgYSA8Y29kZT5NYWxmb3JtZWRVUklFeGNlcHRpb248L2NvZGU+IHdpdGggbm8gc3BlY2lmaWVkCi0gICAgKiBkZXRhaWwgbWVzc2FnZS4KLSAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi0gICAgcHVibGljIE1hbGZvcm1lZFVSSUV4Y2VwdGlvbigpIHsKLSAgICAgIHN1cGVyKCk7Ci0gICAgfQotCi0gICAgLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0gICAgKiBDb25zdHJ1Y3RzIGEgPGNvZGU+TWFsZm9ybWVkVVJJRXhjZXB0aW9uPC9jb2RlPiB3aXRoIHRoZQotICAgICogc3BlY2lmaWVkIGRldGFpbCBtZXNzYWdlLgotICAgICoKLSAgICAqIEBwYXJhbSBwX21zZyB0aGUgZGV0YWlsIG1lc3NhZ2UuCi0gICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwotICAgIHB1YmxpYyBNYWxmb3JtZWRVUklFeGNlcHRpb24oU3RyaW5nIHBfbXNnKSB7Ci0gICAgICBzdXBlcihwX21zZyk7Ci0gICAgfQotICB9Ci0KLSAgLyoqIFNlcmlhbGl6YXRpb24gdmVyc2lvbi4gKi8KLSAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDE2MDE5MjE3NzQ2ODUzNTcyMTRMOwotCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGUgW10gZmdMb29rdXBUYWJsZSA9IG5ldyBieXRlWzEyOF07Ci0KLSAgLyoqCi0gICAqIENoYXJhY3RlciBDbGFzc2VzCi0gICAqLwotCi0gIC8qKiByZXNlcnZlZCBjaGFyYWN0ZXJzIDsvPzpAJj0rJCxbXSAqLwotICAvL1JGQyAyNzMyIGFkZGVkICdbJyBhbmQgJ10nIGFzIHJlc2VydmVkIGNoYXJhY3RlcnMKLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFJFU0VSVkVEX0NIQVJBQ1RFUlMgPSAweDAxOwotCi0gIC8qKiBVUkkgcHVuY3R1YXRpb24gbWFyayBjaGFyYWN0ZXJzOiAtXy4hfionKCkgLSB0aGVzZSwgY29tYmluZWQgd2l0aAotICAgICAgYWxwaGFudW1lcmljcywgY29uc3RpdHV0ZSB0aGUgInVucmVzZXJ2ZWQiIGNoYXJhY3RlcnMgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE1BUktfQ0hBUkFDVEVSUyA9IDB4MDI7Ci0KLSAgLyoqIHNjaGVtZSBjYW4gYmUgY29tcG9zZWQgb2YgYWxwaGFudW1lcmljcyBhbmQgdGhlc2UgY2hhcmFjdGVyczogKy0uICovCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBTQ0hFTUVfQ0hBUkFDVEVSUyA9IDB4MDQ7Ci0KLSAgLyoqIHVzZXJpbmZvIGNhbiBiZSBjb21wb3NlZCBvZiB1bnJlc2VydmVkLCBlc2NhcGVkIGFuZCB0aGVzZQotICAgICAgY2hhcmFjdGVyczogOzomPSskLCAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgVVNFUklORk9fQ0hBUkFDVEVSUyA9IDB4MDg7Ci0KLSAgLyoqIEFTQ0lJIGxldHRlciBjaGFyYWN0ZXJzICovCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBBU0NJSV9BTFBIQV9DSEFSQUNURVJTID0gMHgxMDsKLQotICAvKiogQVNDSUkgZGlnaXQgY2hhcmFjdGVycyAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQVNDSUlfRElHSVRfQ0hBUkFDVEVSUyA9IDB4MjA7Ci0KLSAgLyoqIEFTQ0lJIGhleCBjaGFyYWN0ZXJzICovCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBBU0NJSV9IRVhfQ0hBUkFDVEVSUyA9IDB4NDA7Ci0KLSAgLyoqIFBhdGggY2hhcmFjdGVycyAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgUEFUSF9DSEFSQUNURVJTID0gMHg4MDsKLQotICAvKiogTWFzayBmb3IgYWxwaGEtbnVtZXJpYyBjaGFyYWN0ZXJzICovCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBNQVNLX0FMUEhBX05VTUVSSUMgPSBBU0NJSV9BTFBIQV9DSEFSQUNURVJTIHwgQVNDSUlfRElHSVRfQ0hBUkFDVEVSUzsKLQotICAvKiogTWFzayBmb3IgdW5yZXNlcnZlZCBjaGFyYWN0ZXJzICovCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBNQVNLX1VOUkVTRVJWRURfTUFTSyA9IE1BU0tfQUxQSEFfTlVNRVJJQyB8IE1BUktfQ0hBUkFDVEVSUzsKLQotICAvKiogTWFzayBmb3IgVVJJIGFsbG93YWJsZSBjaGFyYWN0ZXJzIGV4Y2VwdCBmb3IgJSAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTUFTS19VUklfQ0hBUkFDVEVSID0gTUFTS19VTlJFU0VSVkVEX01BU0sgfCBSRVNFUlZFRF9DSEFSQUNURVJTOwotCi0gIC8qKiBNYXNrIGZvciBzY2hlbWUgY2hhcmFjdGVycyAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTUFTS19TQ0hFTUVfQ0hBUkFDVEVSID0gTUFTS19BTFBIQV9OVU1FUklDIHwgU0NIRU1FX0NIQVJBQ1RFUlM7Ci0KLSAgLyoqIE1hc2sgZm9yIHVzZXJpbmZvIGNoYXJhY3RlcnMgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE1BU0tfVVNFUklORk9fQ0hBUkFDVEVSID0gTUFTS19VTlJFU0VSVkVEX01BU0sgfCBVU0VSSU5GT19DSEFSQUNURVJTOwotCi0gIC8qKiBNYXNrIGZvciBwYXRoIGNoYXJhY3RlcnMgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE1BU0tfUEFUSF9DSEFSQUNURVIgPSBNQVNLX1VOUkVTRVJWRURfTUFTSyB8IFBBVEhfQ0hBUkFDVEVSUzsKLQotICBzdGF0aWMgewotICAgICAgLy8gQWRkIEFTQ0lJIERpZ2l0cyBhbmQgQVNDSUkgSGV4IE51bWJlcnMKLSAgICAgIGZvciAoaW50IGkgPSAnMCc7IGkgPD0gJzknOyArK2kpIHsKLSAgICAgICAgICBmZ0xvb2t1cFRhYmxlW2ldIHw9IEFTQ0lJX0RJR0lUX0NIQVJBQ1RFUlMgfCBBU0NJSV9IRVhfQ0hBUkFDVEVSUzsKLSAgICAgIH0KLQotICAgICAgLy8gQWRkIEFTQ0lJIExldHRlcnMgYW5kIEFTQ0lJIEhleCBOdW1iZXJzCi0gICAgICBmb3IgKGludCBpID0gJ0EnOyBpIDw9ICdGJzsgKytpKSB7Ci0gICAgICAgICAgZmdMb29rdXBUYWJsZVtpXSB8PSBBU0NJSV9BTFBIQV9DSEFSQUNURVJTIHwgQVNDSUlfSEVYX0NIQVJBQ1RFUlM7Ci0gICAgICAgICAgZmdMb29rdXBUYWJsZVtpKzB4MDAwMDAwMjBdIHw9IEFTQ0lJX0FMUEhBX0NIQVJBQ1RFUlMgfCBBU0NJSV9IRVhfQ0hBUkFDVEVSUzsKLSAgICAgIH0KLQotICAgICAgLy8gQWRkIEFTQ0lJIExldHRlcnMKLSAgICAgIGZvciAoaW50IGkgPSAnRyc7IGkgPD0gJ1onOyArK2kpIHsKLSAgICAgICAgICBmZ0xvb2t1cFRhYmxlW2ldIHw9IEFTQ0lJX0FMUEhBX0NIQVJBQ1RFUlM7Ci0gICAgICAgICAgZmdMb29rdXBUYWJsZVtpKzB4MDAwMDAwMjBdIHw9IEFTQ0lJX0FMUEhBX0NIQVJBQ1RFUlM7Ci0gICAgICB9Ci0KLSAgICAgIC8vIEFkZCBSZXNlcnZlZCBDaGFyYWN0ZXJzCi0gICAgICBmZ0xvb2t1cFRhYmxlWyc7J10gfD0gUkVTRVJWRURfQ0hBUkFDVEVSUzsKLSAgICAgIGZnTG9va3VwVGFibGVbJy8nXSB8PSBSRVNFUlZFRF9DSEFSQUNURVJTOwotICAgICAgZmdMb29rdXBUYWJsZVsnPyddIHw9IFJFU0VSVkVEX0NIQVJBQ1RFUlM7Ci0gICAgICBmZ0xvb2t1cFRhYmxlWyc6J10gfD0gUkVTRVJWRURfQ0hBUkFDVEVSUzsKLSAgICAgIGZnTG9va3VwVGFibGVbJ0AnXSB8PSBSRVNFUlZFRF9DSEFSQUNURVJTOwotICAgICAgZmdMb29rdXBUYWJsZVsnJiddIHw9IFJFU0VSVkVEX0NIQVJBQ1RFUlM7Ci0gICAgICBmZ0xvb2t1cFRhYmxlWyc9J10gfD0gUkVTRVJWRURfQ0hBUkFDVEVSUzsKLSAgICAgIGZnTG9va3VwVGFibGVbJysnXSB8PSBSRVNFUlZFRF9DSEFSQUNURVJTOwotICAgICAgZmdMb29rdXBUYWJsZVsnJCddIHw9IFJFU0VSVkVEX0NIQVJBQ1RFUlM7Ci0gICAgICBmZ0xvb2t1cFRhYmxlWycsJ10gfD0gUkVTRVJWRURfQ0hBUkFDVEVSUzsKLSAgICAgIGZnTG9va3VwVGFibGVbJ1snXSB8PSBSRVNFUlZFRF9DSEFSQUNURVJTOwotICAgICAgZmdMb29rdXBUYWJsZVsnXSddIHw9IFJFU0VSVkVEX0NIQVJBQ1RFUlM7Ci0KLSAgICAgIC8vIEFkZCBNYXJrIENoYXJhY3RlcnMKLSAgICAgIGZnTG9va3VwVGFibGVbJy0nXSB8PSBNQVJLX0NIQVJBQ1RFUlM7Ci0gICAgICBmZ0xvb2t1cFRhYmxlWydfJ10gfD0gTUFSS19DSEFSQUNURVJTOwotICAgICAgZmdMb29rdXBUYWJsZVsnLiddIHw9IE1BUktfQ0hBUkFDVEVSUzsKLSAgICAgIGZnTG9va3VwVGFibGVbJyEnXSB8PSBNQVJLX0NIQVJBQ1RFUlM7Ci0gICAgICBmZ0xvb2t1cFRhYmxlWyd+J10gfD0gTUFSS19DSEFSQUNURVJTOwotICAgICAgZmdMb29rdXBUYWJsZVsnKiddIHw9IE1BUktfQ0hBUkFDVEVSUzsKLSAgICAgIGZnTG9va3VwVGFibGVbJ1wnJ10gfD0gTUFSS19DSEFSQUNURVJTOwotICAgICAgZmdMb29rdXBUYWJsZVsnKCddIHw9IE1BUktfQ0hBUkFDVEVSUzsKLSAgICAgIGZnTG9va3VwVGFibGVbJyknXSB8PSBNQVJLX0NIQVJBQ1RFUlM7Ci0KLSAgICAgIC8vIEFkZCBTY2hlbWUgQ2hhcmFjdGVycwotICAgICAgZmdMb29rdXBUYWJsZVsnKyddIHw9IFNDSEVNRV9DSEFSQUNURVJTOwotICAgICAgZmdMb29rdXBUYWJsZVsnLSddIHw9IFNDSEVNRV9DSEFSQUNURVJTOwotICAgICAgZmdMb29rdXBUYWJsZVsnLiddIHw9IFNDSEVNRV9DSEFSQUNURVJTOwotCi0gICAgICAvLyBBZGQgVXNlcmluZm8gQ2hhcmFjdGVycwotICAgICAgZmdMb29rdXBUYWJsZVsnOyddIHw9IFVTRVJJTkZPX0NIQVJBQ1RFUlM7Ci0gICAgICBmZ0xvb2t1cFRhYmxlWyc6J10gfD0gVVNFUklORk9fQ0hBUkFDVEVSUzsKLSAgICAgIGZnTG9va3VwVGFibGVbJyYnXSB8PSBVU0VSSU5GT19DSEFSQUNURVJTOwotICAgICAgZmdMb29rdXBUYWJsZVsnPSddIHw9IFVTRVJJTkZPX0NIQVJBQ1RFUlM7Ci0gICAgICBmZ0xvb2t1cFRhYmxlWycrJ10gfD0gVVNFUklORk9fQ0hBUkFDVEVSUzsKLSAgICAgIGZnTG9va3VwVGFibGVbJyQnXSB8PSBVU0VSSU5GT19DSEFSQUNURVJTOwotICAgICAgZmdMb29rdXBUYWJsZVsnLCddIHw9IFVTRVJJTkZPX0NIQVJBQ1RFUlM7Ci0KLSAgICAgIC8vIEFkZCBQYXRoIENoYXJhY3RlcnMKLSAgICAgIGZnTG9va3VwVGFibGVbJzsnXSB8PSBQQVRIX0NIQVJBQ1RFUlM7Ci0gICAgICBmZ0xvb2t1cFRhYmxlWycvJ10gfD0gUEFUSF9DSEFSQUNURVJTOwotICAgICAgZmdMb29rdXBUYWJsZVsnOiddIHw9IFBBVEhfQ0hBUkFDVEVSUzsKLSAgICAgIGZnTG9va3VwVGFibGVbJ0AnXSB8PSBQQVRIX0NIQVJBQ1RFUlM7Ci0gICAgICBmZ0xvb2t1cFRhYmxlWycmJ10gfD0gUEFUSF9DSEFSQUNURVJTOwotICAgICAgZmdMb29rdXBUYWJsZVsnPSddIHw9IFBBVEhfQ0hBUkFDVEVSUzsKLSAgICAgIGZnTG9va3VwVGFibGVbJysnXSB8PSBQQVRIX0NIQVJBQ1RFUlM7Ci0gICAgICBmZ0xvb2t1cFRhYmxlWyckJ10gfD0gUEFUSF9DSEFSQUNURVJTOwotICAgICAgZmdMb29rdXBUYWJsZVsnLCddIHw9IFBBVEhfQ0hBUkFDVEVSUzsKLSAgfQotCi0gIC8qKiBTdG9yZXMgdGhlIHNjaGVtZSAodXN1YWxseSB0aGUgcHJvdG9jb2wpIGZvciB0aGlzIFVSSS4gKi8KLSAgcHJpdmF0ZSBTdHJpbmcgbV9zY2hlbWUgPSBudWxsOwotCi0gIC8qKiBJZiBzcGVjaWZpZWQsIHN0b3JlcyB0aGUgdXNlcmluZm8gZm9yIHRoaXMgVVJJOyBvdGhlcndpc2UgbnVsbCAqLwotICBwcml2YXRlIFN0cmluZyBtX3VzZXJpbmZvID0gbnVsbDsKLQotICAvKiogSWYgc3BlY2lmaWVkLCBzdG9yZXMgdGhlIGhvc3QgZm9yIHRoaXMgVVJJOyBvdGhlcndpc2UgbnVsbCAqLwotICBwcml2YXRlIFN0cmluZyBtX2hvc3QgPSBudWxsOwotCi0gIC8qKiBJZiBzcGVjaWZpZWQsIHN0b3JlcyB0aGUgcG9ydCBmb3IgdGhpcyBVUkk7IG90aGVyd2lzZSAtMSAqLwotICBwcml2YXRlIGludCBtX3BvcnQgPSAtMTsKLQotICAvKiogSWYgc3BlY2lmaWVkLCBzdG9yZXMgdGhlIHJlZ2lzdHJ5IGJhc2VkIGF1dGhvcml0eSBmb3IgdGhpcyBVUkk7IG90aGVyd2lzZSAtMSAqLwotICBwcml2YXRlIFN0cmluZyBtX3JlZ0F1dGhvcml0eSA9IG51bGw7Ci0KLSAgLyoqIElmIHNwZWNpZmllZCwgc3RvcmVzIHRoZSBwYXRoIGZvciB0aGlzIFVSSTsgb3RoZXJ3aXNlIG51bGwgKi8KLSAgcHJpdmF0ZSBTdHJpbmcgbV9wYXRoID0gbnVsbDsKLQotICAvKiogSWYgc3BlY2lmaWVkLCBzdG9yZXMgdGhlIHF1ZXJ5IHN0cmluZyBmb3IgdGhpcyBVUkk7IG90aGVyd2lzZQotICAgICAgbnVsbC4gICovCi0gIHByaXZhdGUgU3RyaW5nIG1fcXVlcnlTdHJpbmcgPSBudWxsOwotCi0gIC8qKiBJZiBzcGVjaWZpZWQsIHN0b3JlcyB0aGUgZnJhZ21lbnQgZm9yIHRoaXMgVVJJOyBvdGhlcndpc2UgbnVsbCAqLwotICBwcml2YXRlIFN0cmluZyBtX2ZyYWdtZW50ID0gbnVsbDsKLQotICBwcml2YXRlIHN0YXRpYyBib29sZWFuIERFQlVHID0gZmFsc2U7Ci0KLSAgLyoqCi0gICogQ29uc3RydWN0IGEgbmV3IGFuZCB1bmluaXRpYWxpemVkIFVSSS4KLSAgKi8KLSAgcHVibGljIFVSSSgpIHsKLSAgfQotCi0gLyoqCi0gICogQ29uc3RydWN0IGEgbmV3IFVSSSBmcm9tIGFub3RoZXIgVVJJLiBBbGwgZmllbGRzIGZvciB0aGlzIFVSSSBhcmUKLSAgKiBzZXQgZXF1YWwgdG8gdGhlIGZpZWxkcyBvZiB0aGUgVVJJIHBhc3NlZCBpbi4KLSAgKgotICAqIEBwYXJhbSBwX290aGVyIHRoZSBVUkkgdG8gY29weSAoY2Fubm90IGJlIG51bGwpCi0gICovCi0gIHB1YmxpYyBVUkkoVVJJIHBfb3RoZXIpIHsKLSAgICBpbml0aWFsaXplKHBfb3RoZXIpOwotICB9Ci0KLSAvKioKLSAgKiBDb25zdHJ1Y3QgYSBuZXcgVVJJIGZyb20gYSBVUkkgc3BlY2lmaWNhdGlvbiBzdHJpbmcuIElmIHRoZQotICAqIHNwZWNpZmljYXRpb24gZm9sbG93cyB0aGUgImdlbmVyaWMgVVJJIiBzeW50YXgsICh0d28gc2xhc2hlcwotICAqIGZvbGxvd2luZyB0aGUgZmlyc3QgY29sb24pLCB0aGUgc3BlY2lmaWNhdGlvbiB3aWxsIGJlIHBhcnNlZAotICAqIGFjY29yZGluZ2x5IC0gc2V0dGluZyB0aGUgc2NoZW1lLCB1c2VyaW5mbywgaG9zdCxwb3J0LCBwYXRoLCBxdWVyeQotICAqIHN0cmluZyBhbmQgZnJhZ21lbnQgZmllbGRzIGFzIG5lY2Vzc2FyeS4gSWYgdGhlIHNwZWNpZmljYXRpb24gZG9lcwotICAqIG5vdCBmb2xsb3cgdGhlICJnZW5lcmljIFVSSSIgc3ludGF4LCB0aGUgc3BlY2lmaWNhdGlvbiBpcyBwYXJzZWQKLSAgKiBpbnRvIGEgc2NoZW1lIGFuZCBzY2hlbWUtc3BlY2lmaWMgcGFydCAoc3RvcmVkIGFzIHRoZSBwYXRoKSBvbmx5LgotICAqCi0gICogQHBhcmFtIHBfdXJpU3BlYyB0aGUgVVJJIHNwZWNpZmljYXRpb24gc3RyaW5nIChjYW5ub3QgYmUgbnVsbCBvcgotICAqICAgICAgICAgICAgICAgICAgZW1wdHkpCi0gICoKLSAgKiBAZXhjZXB0aW9uIE1hbGZvcm1lZFVSSUV4Y2VwdGlvbiBpZiBwX3VyaVNwZWMgdmlvbGF0ZXMgYW55IHN5bnRheAotICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBydWxlcwotICAqLwotICBwdWJsaWMgVVJJKFN0cmluZyBwX3VyaVNwZWMpIHRocm93cyBNYWxmb3JtZWRVUklFeGNlcHRpb24gewotICAgIHRoaXMoKFVSSSludWxsLCBwX3VyaVNwZWMpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhIG5ldyBVUkkgZnJvbSBhIFVSSSBzcGVjaWZpY2F0aW9uIHN0cmluZy4gSWYgdGhlCi0gICAqIHNwZWNpZmljYXRpb24gZm9sbG93cyB0aGUgImdlbmVyaWMgVVJJIiBzeW50YXgsICh0d28gc2xhc2hlcwotICAgKiBmb2xsb3dpbmcgdGhlIGZpcnN0IGNvbG9uKSwgdGhlIHNwZWNpZmljYXRpb24gd2lsbCBiZSBwYXJzZWQKLSAgICogYWNjb3JkaW5nbHkgLSBzZXR0aW5nIHRoZSBzY2hlbWUsIHVzZXJpbmZvLCBob3N0LHBvcnQsIHBhdGgsIHF1ZXJ5Ci0gICAqIHN0cmluZyBhbmQgZnJhZ21lbnQgZmllbGRzIGFzIG5lY2Vzc2FyeS4gSWYgdGhlIHNwZWNpZmljYXRpb24gZG9lcwotICAgKiBub3QgZm9sbG93IHRoZSAiZ2VuZXJpYyBVUkkiIHN5bnRheCwgdGhlIHNwZWNpZmljYXRpb24gaXMgcGFyc2VkCi0gICAqIGludG8gYSBzY2hlbWUgYW5kIHNjaGVtZS1zcGVjaWZpYyBwYXJ0IChzdG9yZWQgYXMgdGhlIHBhdGgpIG9ubHkuCi0gICAqIENvbnN0cnVjdCBhIHJlbGF0aXZlIFVSSSBpZiBib29sZWFuIGlzIGFzc2lnbmVkIHRvICJ0cnVlIgotICAgKiBhbmQgcF91cmlTcGVjIGlzIG5vdCB2YWxpZCBhYnNvbHV0ZSBVUkksIGluc3RlYWQgb2YgdGhyb3dpbmcgYW4gZXhjZXB0aW9uLgotICAgKgotICAgKiBAcGFyYW0gcF91cmlTcGVjIHRoZSBVUkkgc3BlY2lmaWNhdGlvbiBzdHJpbmcgKGNhbm5vdCBiZSBudWxsIG9yCi0gICAqICAgICAgICAgICAgICAgICAgZW1wdHkpCi0gICAqIEBwYXJhbSBhbGxvd05vbkFic29sdXRlVVJJIHRydWUgdG8gcGVybWl0IG5vbi1hYnNvbHV0ZSBVUklzLAotICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSBvdGhlcndpc2UuCi0gICAqCi0gICAqIEBleGNlcHRpb24gTWFsZm9ybWVkVVJJRXhjZXB0aW9uIGlmIHBfdXJpU3BlYyB2aW9sYXRlcyBhbnkgc3ludGF4Ci0gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBydWxlcwotICAgKi8KLSAgcHVibGljIFVSSShTdHJpbmcgcF91cmlTcGVjLCBib29sZWFuIGFsbG93Tm9uQWJzb2x1dGVVUkkpIHRocm93cyBNYWxmb3JtZWRVUklFeGNlcHRpb24gewotICAgICAgdGhpcygoVVJJKW51bGwsIHBfdXJpU3BlYywgYWxsb3dOb25BYnNvbHV0ZVVSSSk7Ci0gIH0KLQotIC8qKgotICAqIENvbnN0cnVjdCBhIG5ldyBVUkkgZnJvbSBhIGJhc2UgVVJJIGFuZCBhIFVSSSBzcGVjaWZpY2F0aW9uIHN0cmluZy4KLSAgKiBUaGUgVVJJIHNwZWNpZmljYXRpb24gc3RyaW5nIG1heSBiZSBhIHJlbGF0aXZlIFVSSS4KLSAgKgotICAqIEBwYXJhbSBwX2Jhc2UgdGhlIGJhc2UgVVJJIChjYW5ub3QgYmUgbnVsbCBpZiBwX3VyaVNwZWMgaXMgbnVsbCBvcgotICAqICAgICAgICAgICAgICAgZW1wdHkpCi0gICogQHBhcmFtIHBfdXJpU3BlYyB0aGUgVVJJIHNwZWNpZmljYXRpb24gc3RyaW5nIChjYW5ub3QgYmUgbnVsbCBvcgotICAqICAgICAgICAgICAgICAgICAgZW1wdHkgaWYgcF9iYXNlIGlzIG51bGwpCi0gICoKLSAgKiBAZXhjZXB0aW9uIE1hbGZvcm1lZFVSSUV4Y2VwdGlvbiBpZiBwX3VyaVNwZWMgdmlvbGF0ZXMgYW55IHN5bnRheAotICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJ1bGVzCi0gICovCi0gIHB1YmxpYyBVUkkoVVJJIHBfYmFzZSwgU3RyaW5nIHBfdXJpU3BlYykgdGhyb3dzIE1hbGZvcm1lZFVSSUV4Y2VwdGlvbiB7Ci0gICAgaW5pdGlhbGl6ZShwX2Jhc2UsIHBfdXJpU3BlYyk7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgbmV3IFVSSSBmcm9tIGEgYmFzZSBVUkkgYW5kIGEgVVJJIHNwZWNpZmljYXRpb24gc3RyaW5nLgotICAgKiBUaGUgVVJJIHNwZWNpZmljYXRpb24gc3RyaW5nIG1heSBiZSBhIHJlbGF0aXZlIFVSSS4KLSAgICogQ29uc3RydWN0IGEgcmVsYXRpdmUgVVJJIGlmIGJvb2xlYW4gaXMgYXNzaWduZWQgdG8gInRydWUiCi0gICAqIGFuZCBwX3VyaVNwZWMgaXMgbm90IHZhbGlkIGFic29sdXRlIFVSSSBhbmQgcF9iYXNlIGlzIG51bGwKLSAgICogaW5zdGVhZCBvZiB0aHJvd2luZyBhbiBleGNlcHRpb24uCi0gICAqCi0gICAqIEBwYXJhbSBwX2Jhc2UgdGhlIGJhc2UgVVJJIChjYW5ub3QgYmUgbnVsbCBpZiBwX3VyaVNwZWMgaXMgbnVsbCBvcgotICAgKiAgICAgICAgICAgICAgIGVtcHR5KQotICAgKiBAcGFyYW0gcF91cmlTcGVjIHRoZSBVUkkgc3BlY2lmaWNhdGlvbiBzdHJpbmcgKGNhbm5vdCBiZSBudWxsIG9yCi0gICAqICAgICAgICAgICAgICAgICAgZW1wdHkgaWYgcF9iYXNlIGlzIG51bGwpCi0gICAqIEBwYXJhbSBhbGxvd05vbkFic29sdXRlVVJJIHRydWUgdG8gcGVybWl0IG5vbi1hYnNvbHV0ZSBVUklzLAotICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSBvdGhlcndpc2UuCi0gICAqCi0gICAqIEBleGNlcHRpb24gTWFsZm9ybWVkVVJJRXhjZXB0aW9uIGlmIHBfdXJpU3BlYyB2aW9sYXRlcyBhbnkgc3ludGF4Ci0gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJ1bGVzCi0gICAqLwotICBwdWJsaWMgVVJJKFVSSSBwX2Jhc2UsIFN0cmluZyBwX3VyaVNwZWMsIGJvb2xlYW4gYWxsb3dOb25BYnNvbHV0ZVVSSSkgdGhyb3dzIE1hbGZvcm1lZFVSSUV4Y2VwdGlvbiB7Ci0gICAgICBpbml0aWFsaXplKHBfYmFzZSwgcF91cmlTcGVjLCBhbGxvd05vbkFic29sdXRlVVJJKTsKLSAgfQotCi0gLyoqCi0gICogQ29uc3RydWN0IGEgbmV3IFVSSSB0aGF0IGRvZXMgbm90IGZvbGxvdyB0aGUgZ2VuZXJpYyBVUkkgc3ludGF4LgotICAqIE9ubHkgdGhlIHNjaGVtZSBhbmQgc2NoZW1lLXNwZWNpZmljIHBhcnQgKHN0b3JlZCBhcyB0aGUgcGF0aCkgYXJlCi0gICogaW5pdGlhbGl6ZWQuCi0gICoKLSAgKiBAcGFyYW0gcF9zY2hlbWUgdGhlIFVSSSBzY2hlbWUgKGNhbm5vdCBiZSBudWxsIG9yIGVtcHR5KQotICAqIEBwYXJhbSBwX3NjaGVtZVNwZWNpZmljUGFydCB0aGUgc2NoZW1lLXNwZWNpZmljIHBhcnQgKGNhbm5vdCBiZQotICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsIG9yIGVtcHR5KQotICAqCi0gICogQGV4Y2VwdGlvbiBNYWxmb3JtZWRVUklFeGNlcHRpb24gaWYgcF9zY2hlbWUgdmlvbGF0ZXMgYW55Ci0gICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ludGF4IHJ1bGVzCi0gICovCi0gIHB1YmxpYyBVUkkoU3RyaW5nIHBfc2NoZW1lLCBTdHJpbmcgcF9zY2hlbWVTcGVjaWZpY1BhcnQpCi0gICAgICAgICAgICAgdGhyb3dzIE1hbGZvcm1lZFVSSUV4Y2VwdGlvbiB7Ci0gICAgaWYgKHBfc2NoZW1lID09IG51bGwgfHwgcF9zY2hlbWUudHJpbSgpLmxlbmd0aCgpID09IDApIHsKLSAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVUklFeGNlcHRpb24oCi0gICAgICAgICAgICAiQ2Fubm90IGNvbnN0cnVjdCBVUkkgd2l0aCBudWxsL2VtcHR5IHNjaGVtZSEiKTsKLSAgICB9Ci0gICAgaWYgKHBfc2NoZW1lU3BlY2lmaWNQYXJ0ID09IG51bGwgfHwKLSAgICAgICAgcF9zY2hlbWVTcGVjaWZpY1BhcnQudHJpbSgpLmxlbmd0aCgpID09IDApIHsKLSAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVUklFeGNlcHRpb24oCi0gICAgICAgICAgIkNhbm5vdCBjb25zdHJ1Y3QgVVJJIHdpdGggbnVsbC9lbXB0eSBzY2hlbWUtc3BlY2lmaWMgcGFydCEiKTsKLSAgICB9Ci0gICAgc2V0U2NoZW1lKHBfc2NoZW1lKTsKLSAgICBzZXRQYXRoKHBfc2NoZW1lU3BlY2lmaWNQYXJ0KTsKLSAgfQotCi0gLyoqCi0gICogQ29uc3RydWN0IGEgbmV3IFVSSSB0aGF0IGZvbGxvd3MgdGhlIGdlbmVyaWMgVVJJIHN5bnRheCBmcm9tIGl0cwotICAqIGNvbXBvbmVudCBwYXJ0cy4gRWFjaCBjb21wb25lbnQgaXMgdmFsaWRhdGVkIGZvciBzeW50YXggYW5kIHNvbWUKLSAgKiBiYXNpYyBzZW1hbnRpYyBjaGVja3MgYXJlIHBlcmZvcm1lZCBhcyB3ZWxsLiAgU2VlIHRoZSBpbmRpdmlkdWFsCi0gICogc2V0dGVyIG1ldGhvZHMgZm9yIHNwZWNpZmljcy4KLSAgKgotICAqIEBwYXJhbSBwX3NjaGVtZSB0aGUgVVJJIHNjaGVtZSAoY2Fubm90IGJlIG51bGwgb3IgZW1wdHkpCi0gICogQHBhcmFtIHBfaG9zdCB0aGUgaG9zdG5hbWUsIElQdjQgYWRkcmVzcyBvciBJUHY2IHJlZmVyZW5jZSBmb3IgdGhlIFVSSQotICAqIEBwYXJhbSBwX3BhdGggdGhlIFVSSSBwYXRoIC0gaWYgdGhlIHBhdGggY29udGFpbnMgJz8nIG9yICcjJywKLSAgKiAgICAgICAgICAgICAgIHRoZW4gdGhlIHF1ZXJ5IHN0cmluZyBhbmQvb3IgZnJhZ21lbnQgd2lsbCBiZQotICAqICAgICAgICAgICAgICAgc2V0IGZyb20gdGhlIHBhdGg7IGhvd2V2ZXIsIGlmIHRoZSBxdWVyeSBhbmQKLSAgKiAgICAgICAgICAgICAgIGZyYWdtZW50IGFyZSBzcGVjaWZpZWQgYm90aCBpbiB0aGUgcGF0aCBhbmQgYXMKLSAgKiAgICAgICAgICAgICAgIHNlcGFyYXRlIHBhcmFtZXRlcnMsIGFuIGV4Y2VwdGlvbiBpcyB0aHJvd24KLSAgKiBAcGFyYW0gcF9xdWVyeVN0cmluZyB0aGUgVVJJIHF1ZXJ5IHN0cmluZyAoY2Fubm90IGJlIHNwZWNpZmllZAotICAqICAgICAgICAgICAgICAgICAgICAgIGlmIHBhdGggaXMgbnVsbCkKLSAgKiBAcGFyYW0gcF9mcmFnbWVudCB0aGUgVVJJIGZyYWdtZW50IChjYW5ub3QgYmUgc3BlY2lmaWVkIGlmIHBhdGgKLSAgKiAgICAgICAgICAgICAgICAgICBpcyBudWxsKQotICAqCi0gICogQGV4Y2VwdGlvbiBNYWxmb3JtZWRVUklFeGNlcHRpb24gaWYgYW55IG9mIHRoZSBwYXJhbWV0ZXJzIHZpb2xhdGVzCi0gICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ludGF4IHJ1bGVzIG9yIHNlbWFudGljIHJ1bGVzCi0gICovCi0gIHB1YmxpYyBVUkkoU3RyaW5nIHBfc2NoZW1lLCBTdHJpbmcgcF9ob3N0LCBTdHJpbmcgcF9wYXRoLAotICAgICAgICAgICAgIFN0cmluZyBwX3F1ZXJ5U3RyaW5nLCBTdHJpbmcgcF9mcmFnbWVudCkKLSAgICAgICAgIHRocm93cyBNYWxmb3JtZWRVUklFeGNlcHRpb24gewotICAgIHRoaXMocF9zY2hlbWUsIG51bGwsIHBfaG9zdCwgLTEsIHBfcGF0aCwgcF9xdWVyeVN0cmluZywgcF9mcmFnbWVudCk7Ci0gIH0KLQotIC8qKgotICAqIENvbnN0cnVjdCBhIG5ldyBVUkkgdGhhdCBmb2xsb3dzIHRoZSBnZW5lcmljIFVSSSBzeW50YXggZnJvbSBpdHMKLSAgKiBjb21wb25lbnQgcGFydHMuIEVhY2ggY29tcG9uZW50IGlzIHZhbGlkYXRlZCBmb3Igc3ludGF4IGFuZCBzb21lCi0gICogYmFzaWMgc2VtYW50aWMgY2hlY2tzIGFyZSBwZXJmb3JtZWQgYXMgd2VsbC4gIFNlZSB0aGUgaW5kaXZpZHVhbAotICAqIHNldHRlciBtZXRob2RzIGZvciBzcGVjaWZpY3MuCi0gICoKLSAgKiBAcGFyYW0gcF9zY2hlbWUgdGhlIFVSSSBzY2hlbWUgKGNhbm5vdCBiZSBudWxsIG9yIGVtcHR5KQotICAqIEBwYXJhbSBwX3VzZXJpbmZvIHRoZSBVUkkgdXNlcmluZm8gKGNhbm5vdCBiZSBzcGVjaWZpZWQgaWYgaG9zdAotICAqICAgICAgICAgICAgICAgICAgIGlzIG51bGwpCi0gICogQHBhcmFtIHBfaG9zdCB0aGUgaG9zdG5hbWUsIElQdjQgYWRkcmVzcyBvciBJUHY2IHJlZmVyZW5jZSBmb3IgdGhlIFVSSQotICAqIEBwYXJhbSBwX3BvcnQgdGhlIFVSSSBwb3J0IChtYXkgYmUgLTEgZm9yICJ1bnNwZWNpZmllZCI7IGNhbm5vdAotICAqICAgICAgICAgICAgICAgYmUgc3BlY2lmaWVkIGlmIGhvc3QgaXMgbnVsbCkKLSAgKiBAcGFyYW0gcF9wYXRoIHRoZSBVUkkgcGF0aCAtIGlmIHRoZSBwYXRoIGNvbnRhaW5zICc/JyBvciAnIycsCi0gICogICAgICAgICAgICAgICB0aGVuIHRoZSBxdWVyeSBzdHJpbmcgYW5kL29yIGZyYWdtZW50IHdpbGwgYmUKLSAgKiAgICAgICAgICAgICAgIHNldCBmcm9tIHRoZSBwYXRoOyBob3dldmVyLCBpZiB0aGUgcXVlcnkgYW5kCi0gICogICAgICAgICAgICAgICBmcmFnbWVudCBhcmUgc3BlY2lmaWVkIGJvdGggaW4gdGhlIHBhdGggYW5kIGFzCi0gICogICAgICAgICAgICAgICBzZXBhcmF0ZSBwYXJhbWV0ZXJzLCBhbiBleGNlcHRpb24gaXMgdGhyb3duCi0gICogQHBhcmFtIHBfcXVlcnlTdHJpbmcgdGhlIFVSSSBxdWVyeSBzdHJpbmcgKGNhbm5vdCBiZSBzcGVjaWZpZWQKLSAgKiAgICAgICAgICAgICAgICAgICAgICBpZiBwYXRoIGlzIG51bGwpCi0gICogQHBhcmFtIHBfZnJhZ21lbnQgdGhlIFVSSSBmcmFnbWVudCAoY2Fubm90IGJlIHNwZWNpZmllZCBpZiBwYXRoCi0gICogICAgICAgICAgICAgICAgICAgaXMgbnVsbCkKLSAgKgotICAqIEBleGNlcHRpb24gTWFsZm9ybWVkVVJJRXhjZXB0aW9uIGlmIGFueSBvZiB0aGUgcGFyYW1ldGVycyB2aW9sYXRlcwotICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bnRheCBydWxlcyBvciBzZW1hbnRpYyBydWxlcwotICAqLwotICBwdWJsaWMgVVJJKFN0cmluZyBwX3NjaGVtZSwgU3RyaW5nIHBfdXNlcmluZm8sCi0gICAgICAgICAgICAgU3RyaW5nIHBfaG9zdCwgaW50IHBfcG9ydCwgU3RyaW5nIHBfcGF0aCwKLSAgICAgICAgICAgICBTdHJpbmcgcF9xdWVyeVN0cmluZywgU3RyaW5nIHBfZnJhZ21lbnQpCi0gICAgICAgICB0aHJvd3MgTWFsZm9ybWVkVVJJRXhjZXB0aW9uIHsKLSAgICBpZiAocF9zY2hlbWUgPT0gbnVsbCB8fCBwX3NjaGVtZS50cmltKCkubGVuZ3RoKCkgPT0gMCkgewotICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVSSUV4Y2VwdGlvbigiU2NoZW1lIGlzIHJlcXVpcmVkISIpOwotICAgIH0KLQotICAgIGlmIChwX2hvc3QgPT0gbnVsbCkgewotICAgICAgaWYgKHBfdXNlcmluZm8gIT0gbnVsbCkgewotICAgICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVVJJRXhjZXB0aW9uKAotICAgICAgICAgICAgICJVc2VyaW5mbyBtYXkgbm90IGJlIHNwZWNpZmllZCBpZiBob3N0IGlzIG5vdCBzcGVjaWZpZWQhIik7Ci0gICAgICB9Ci0gICAgICBpZiAocF9wb3J0ICE9IC0xKSB7Ci0gICAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVUklFeGNlcHRpb24oCi0gICAgICAgICAgICAgIlBvcnQgbWF5IG5vdCBiZSBzcGVjaWZpZWQgaWYgaG9zdCBpcyBub3Qgc3BlY2lmaWVkISIpOwotICAgICAgfQotICAgIH0KLQotICAgIGlmIChwX3BhdGggIT0gbnVsbCkgewotICAgICAgaWYgKHBfcGF0aC5pbmRleE9mKCc/JykgIT0gLTEgJiYgcF9xdWVyeVN0cmluZyAhPSBudWxsKSB7Ci0gICAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVUklFeGNlcHRpb24oCi0gICAgICAgICAgIlF1ZXJ5IHN0cmluZyBjYW5ub3QgYmUgc3BlY2lmaWVkIGluIHBhdGggYW5kIHF1ZXJ5IHN0cmluZyEiKTsKLSAgICAgIH0KLQotICAgICAgaWYgKHBfcGF0aC5pbmRleE9mKCcjJykgIT0gLTEgJiYgcF9mcmFnbWVudCAhPSBudWxsKSB7Ci0gICAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVUklFeGNlcHRpb24oCi0gICAgICAgICAgIkZyYWdtZW50IGNhbm5vdCBiZSBzcGVjaWZpZWQgaW4gYm90aCB0aGUgcGF0aCBhbmQgZnJhZ21lbnQhIik7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgc2V0U2NoZW1lKHBfc2NoZW1lKTsKLSAgICBzZXRIb3N0KHBfaG9zdCk7Ci0gICAgc2V0UG9ydChwX3BvcnQpOwotICAgIHNldFVzZXJpbmZvKHBfdXNlcmluZm8pOwotICAgIHNldFBhdGgocF9wYXRoKTsKLSAgICBzZXRRdWVyeVN0cmluZyhwX3F1ZXJ5U3RyaW5nKTsKLSAgICBzZXRGcmFnbWVudChwX2ZyYWdtZW50KTsKLSAgfQotCi0gLyoqCi0gICogSW5pdGlhbGl6ZSBhbGwgZmllbGRzIG9mIHRoaXMgVVJJIGZyb20gYW5vdGhlciBVUkkuCi0gICoKLSAgKiBAcGFyYW0gcF9vdGhlciB0aGUgVVJJIHRvIGNvcHkgKGNhbm5vdCBiZSBudWxsKQotICAqLwotICBwcml2YXRlIHZvaWQgaW5pdGlhbGl6ZShVUkkgcF9vdGhlcikgewotICAgIG1fc2NoZW1lID0gcF9vdGhlci5nZXRTY2hlbWUoKTsKLSAgICBtX3VzZXJpbmZvID0gcF9vdGhlci5nZXRVc2VyaW5mbygpOwotICAgIG1faG9zdCA9IHBfb3RoZXIuZ2V0SG9zdCgpOwotICAgIG1fcG9ydCA9IHBfb3RoZXIuZ2V0UG9ydCgpOwotICAgIG1fcmVnQXV0aG9yaXR5ID0gcF9vdGhlci5nZXRSZWdCYXNlZEF1dGhvcml0eSgpOwotICAgIG1fcGF0aCA9IHBfb3RoZXIuZ2V0UGF0aCgpOwotICAgIG1fcXVlcnlTdHJpbmcgPSBwX290aGVyLmdldFF1ZXJ5U3RyaW5nKCk7Ci0gICAgbV9mcmFnbWVudCA9IHBfb3RoZXIuZ2V0RnJhZ21lbnQoKTsKLSAgfQotCi0gIC8qKgotICAgKiBJbml0aWFsaXplcyB0aGlzIFVSSSBmcm9tIGEgYmFzZSBVUkkgYW5kIGEgVVJJIHNwZWNpZmljYXRpb24gc3RyaW5nLgotICAgKiBTZWUgUkZDIDIzOTYgU2VjdGlvbiA0IGFuZCBBcHBlbmRpeCBCIGZvciBzcGVjaWZpY2F0aW9ucyBvbiBwYXJzaW5nCi0gICAqIHRoZSBVUkkgYW5kIFNlY3Rpb24gNSBmb3Igc3BlY2lmaWNhdGlvbnMgb24gcmVzb2x2aW5nIHJlbGF0aXZlIFVSSXMKLSAgICogYW5kIHJlbGF0aXZlIHBhdGhzLgotICAgKgotICAgKiBAcGFyYW0gcF9iYXNlIHRoZSBiYXNlIFVSSSAobWF5IGJlIG51bGwgaWYgcF91cmlTcGVjIGlzIGFuIGFic29sdXRlCi0gICAqICAgICAgICAgICAgICAgVVJJKQotICAgKiBAcGFyYW0gcF91cmlTcGVjIHRoZSBVUkkgc3BlYyBzdHJpbmcgd2hpY2ggbWF5IGJlIGFuIGFic29sdXRlIG9yCi0gICAqICAgICAgICAgICAgICAgICAgcmVsYXRpdmUgVVJJIChjYW4gb25seSBiZSBudWxsL2VtcHR5IGlmIHBfYmFzZQotICAgKiAgICAgICAgICAgICAgICAgIGlzIG5vdCBudWxsKQotICAgKiBAcGFyYW0gYWxsb3dOb25BYnNvbHV0ZVVSSSB0cnVlIHRvIHBlcm1pdCBub24tYWJzb2x1dGUgVVJJcywKLSAgICogICAgICAgICAgICAgICAgICAgICAgICAgaW4gY2FzZSBvZiByZWxhdGl2ZSBVUkksIGZhbHNlIG90aGVyd2lzZS4KLSAgICoKLSAgICogQGV4Y2VwdGlvbiBNYWxmb3JtZWRVUklFeGNlcHRpb24gaWYgcF9iYXNlIGlzIG51bGwgYW5kIHBfdXJpU3BlYwotICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpcyBub3QgYW4gYWJzb2x1dGUgVVJJIG9yIGlmCi0gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBfdXJpU3BlYyB2aW9sYXRlcyBzeW50YXggcnVsZXMKLSAgICovCi0gIHByaXZhdGUgdm9pZCBpbml0aWFsaXplKFVSSSBwX2Jhc2UsIFN0cmluZyBwX3VyaVNwZWMsIGJvb2xlYW4gYWxsb3dOb25BYnNvbHV0ZVVSSSkKLSAgICAgIHRocm93cyBNYWxmb3JtZWRVUklFeGNlcHRpb24gewotCi0gICAgICBTdHJpbmcgdXJpU3BlYyA9IHBfdXJpU3BlYzsKLSAgICAgIGludCB1cmlTcGVjTGVuID0gKHVyaVNwZWMgIT0gbnVsbCkgPyB1cmlTcGVjLmxlbmd0aCgpIDogMDsKLQotICAgICAgaWYgKHBfYmFzZSA9PSBudWxsICYmIHVyaVNwZWNMZW4gPT0gMCkgewotICAgICAgICAgIGlmIChhbGxvd05vbkFic29sdXRlVVJJKSB7Ci0gICAgICAgICAgICAgIG1fcGF0aCA9ICIiOwotICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgfQotICAgICAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVUklFeGNlcHRpb24oIkNhbm5vdCBpbml0aWFsaXplIFVSSSB3aXRoIGVtcHR5IHBhcmFtZXRlcnMuIik7Ci0gICAgICB9Ci0KLSAgICAgIC8vIGp1c3QgbWFrZSBhIGNvcHkgb2YgdGhlIGJhc2UgaWYgc3BlYyBpcyBlbXB0eQotICAgICAgaWYgKHVyaVNwZWNMZW4gPT0gMCkgewotICAgICAgICAgIGluaXRpYWxpemUocF9iYXNlKTsKLSAgICAgICAgICByZXR1cm47Ci0gICAgICB9Ci0KLSAgICAgIGludCBpbmRleCA9IDA7Ci0KLSAgICAgIC8vIENoZWNrIGZvciBzY2hlbWUsIHdoaWNoIG11c3QgYmUgYmVmb3JlICcvJywgJz8nIG9yICcjJy4KLSAgICAgIGludCBjb2xvbklkeCA9IHVyaVNwZWMuaW5kZXhPZignOicpOwotICAgICAgaWYgKGNvbG9uSWR4ICE9IC0xKSB7Ci0gICAgICAgICAgZmluYWwgaW50IHNlYXJjaEZyb20gPSBjb2xvbklkeCAtIDE7Ci0gICAgICAgICAgLy8gc2VhcmNoIGJhY2t3YXJkcyBzdGFydGluZyBmcm9tIGNoYXJhY3RlciBiZWZvcmUgJzonLgotICAgICAgICAgIGludCBzbGFzaElkeCA9IHVyaVNwZWMubGFzdEluZGV4T2YoJy8nLCBzZWFyY2hGcm9tKTsKLSAgICAgICAgICBpbnQgcXVlcnlJZHggPSB1cmlTcGVjLmxhc3RJbmRleE9mKCc/Jywgc2VhcmNoRnJvbSk7Ci0gICAgICAgICAgaW50IGZyYWdtZW50SWR4ID0gdXJpU3BlYy5sYXN0SW5kZXhPZignIycsIHNlYXJjaEZyb20pOwotCi0gICAgICAgICAgaWYgKGNvbG9uSWR4ID09IDAgfHwgc2xhc2hJZHggIT0gLTEgfHwKLSAgICAgICAgICAgICAgcXVlcnlJZHggIT0gLTEgfHwgZnJhZ21lbnRJZHggIT0gLTEpIHsKLSAgICAgICAgICAgICAgLy8gQSBzdGFuZGFsb25lIGJhc2UgaXMgYSB2YWxpZCBVUkkgYWNjb3JkaW5nIHRvIHNwZWMKLSAgICAgICAgICAgICAgaWYgKGNvbG9uSWR4ID09IDAgfHwgKHBfYmFzZSA9PSBudWxsICYmIGZyYWdtZW50SWR4ICE9IDAgJiYgIWFsbG93Tm9uQWJzb2x1dGVVUkkpKSB7Ci0gICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVVJJRXhjZXB0aW9uKCJObyBzY2hlbWUgZm91bmQgaW4gVVJJLiIpOwotICAgICAgICAgICAgICB9Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICBpbml0aWFsaXplU2NoZW1lKHVyaVNwZWMpOwotICAgICAgICAgICAgICBpbmRleCA9IG1fc2NoZW1lLmxlbmd0aCgpKzE7Ci0KLSAgICAgICAgICAgICAgLy8gTmVpdGhlciAnc2NoZW1lOicgb3IgJ3NjaGVtZTojZnJhZ21lbnQnIGFyZSB2YWxpZCBVUklzLgotICAgICAgICAgICAgICBpZiAoY29sb25JZHggPT0gdXJpU3BlY0xlbiAtIDEgfHwgdXJpU3BlYy5jaGFyQXQoY29sb25JZHgrMSkgPT0gJyMnKSB7Ci0gICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVVJJRXhjZXB0aW9uKCJTY2hlbWUgc3BlY2lmaWMgcGFydCBjYW5ub3QgYmUgZW1wdHkuIik7Ci0gICAgICAgICAgICAgIH0KLSAgICAgICAgICB9Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmIChwX2Jhc2UgPT0gbnVsbCAmJiB1cmlTcGVjLmluZGV4T2YoJyMnKSAhPSAwICYmICFhbGxvd05vbkFic29sdXRlVVJJKSB7Ci0gICAgICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVSSUV4Y2VwdGlvbigiTm8gc2NoZW1lIGZvdW5kIGluIFVSSS4iKTsKLSAgICAgIH0KLQotICAgICAgLy8gVHdvIHNsYXNoZXMgbWVhbnMgd2UgbWF5IGhhdmUgYXV0aG9yaXR5LCBidXQgZGVmaW5pdGVseSBtZWFucyB3ZSdyZSBlaXRoZXIKLSAgICAgIC8vIG1hdGNoaW5nIG5ldF9wYXRoIG9yIGFic19wYXRoLiBUaGVzZSB0d28gcHJvZHVjdGlvbnMgYXJlIGFtYmlndW91cyBpbiB0aGF0Ci0gICAgICAvLyBldmVyeSBuZXRfcGF0aCAoZXhjZXB0IHRob3NlIGNvbnRhaW5pbmcgYW4gSVB2NlJlZmVyZW5jZSkgaXMgYW4gYWJzX3BhdGguCi0gICAgICAvLyBSRkMgMjM5NiByZXNvbHZlcyB0aGlzIGFtYmlndWl0eSBieSBhcHBseWluZyBhIGdyZWVkeSBsZWZ0IG1vc3QgbWF0Y2hpbmcgcnVsZS4KLSAgICAgIC8vIFRyeSBtYXRjaGluZyBuZXRfcGF0aCBmaXJzdCwgYW5kIGlmIHRoYXQgZmFpbHMgd2UgZG9uJ3QgaGF2ZSBhdXRob3JpdHkgc28KLSAgICAgIC8vIHRoZW4gYXR0ZW1wdCB0byBtYXRjaCBhYnNfcGF0aC4KLSAgICAgIC8vCi0gICAgICAvLyBuZXRfcGF0aCA9ICIvLyIgYXV0aG9yaXR5IFsgYWJzX3BhdGggXQotICAgICAgLy8gYWJzX3BhdGggPSAiLyIgIHBhdGhfc2VnbWVudHMKLSAgICAgIGlmICgoKGluZGV4KzEpIDwgdXJpU3BlY0xlbikgJiYKLSAgICAgICAgICAodXJpU3BlYy5jaGFyQXQoaW5kZXgpID09ICcvJyAmJiB1cmlTcGVjLmNoYXJBdChpbmRleCsxKSA9PSAnLycpKSB7Ci0gICAgICAgICAgaW5kZXggKz0gMjsKLSAgICAgICAgICBpbnQgc3RhcnRQb3MgPSBpbmRleDsKLQotICAgICAgICAgIC8vIEF1dGhvcml0eSB3aWxsIGJlIGV2ZXJ5dGhpbmcgdXAgdG8gcGF0aCwgcXVlcnkgb3IgZnJhZ21lbnQKLSAgICAgICAgICBjaGFyIHRlc3RDaGFyID0gJ1wwJzsKLSAgICAgICAgICB3aGlsZSAoaW5kZXggPCB1cmlTcGVjTGVuKSB7Ci0gICAgICAgICAgICAgIHRlc3RDaGFyID0gdXJpU3BlYy5jaGFyQXQoaW5kZXgpOwotICAgICAgICAgICAgICBpZiAodGVzdENoYXIgPT0gJy8nIHx8IHRlc3RDaGFyID09ICc/JyB8fCB0ZXN0Q2hhciA9PSAnIycpIHsKLSAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgIGluZGV4Kys7Ci0gICAgICAgICAgfQotCi0gICAgICAgICAgLy8gQXR0ZW1wdCB0byBwYXJzZSBhdXRob3JpdHkuIElmIHRoZSBzZWN0aW9uIGlzIGFuIGVtcHR5IHN0cmluZwotICAgICAgICAgIC8vIHRoaXMgaXMgYSB2YWxpZCBzZXJ2ZXIgYmFzZWQgYXV0aG9yaXR5LCBzbyBzZXQgdGhlIGhvc3QgdG8gdGhpcwotICAgICAgICAgIC8vIHZhbHVlLgotICAgICAgICAgIGlmIChpbmRleCA+IHN0YXJ0UG9zKSB7Ci0gICAgICAgICAgICAgIC8vIElmIHdlIGRpZG4ndCBmaW5kIGF1dGhvcml0eSB3ZSBuZWVkIHRvIGJhY2sgdXAuIEF0dGVtcHQgdG8KLSAgICAgICAgICAgICAgLy8gbWF0Y2ggYWdhaW5zdCBhYnNfcGF0aCBuZXh0LgotICAgICAgICAgICAgICBpZiAoIWluaXRpYWxpemVBdXRob3JpdHkodXJpU3BlYy5zdWJzdHJpbmcoc3RhcnRQb3MsIGluZGV4KSkpIHsKLSAgICAgICAgICAgICAgICAgIGluZGV4ID0gc3RhcnRQb3MgLSAyOwotICAgICAgICAgICAgICB9Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICBtX2hvc3QgPSAiIjsKLSAgICAgICAgICB9Ci0gICAgICB9Ci0KLSAgICAgIGluaXRpYWxpemVQYXRoKHVyaVNwZWMsIGluZGV4KTsKLQotICAgICAgLy8gUmVzb2x2ZSByZWxhdGl2ZSBVUkkgdG8gYmFzZSBVUkkgLSBzZWUgUkZDIDIzOTYgU2VjdGlvbiA1LjIKLSAgICAgIC8vIEluIHNvbWUgY2FzZXMsIGl0IG1pZ2h0IG1ha2UgbW9yZSBzZW5zZSB0byB0aHJvdyBhbiBleGNlcHRpb24KLSAgICAgIC8vICh3aGVuIHNjaGVtZSBpcyBzcGVjaWZpZWQgaXMgdGhlIHN0cmluZyBzcGVjIGFuZCB0aGUgYmFzZSBVUkkKLSAgICAgIC8vIGlzIGFsc28gc3BlY2lmaWVkLCBmb3IgZXhhbXBsZSksIGJ1dCB3ZSdyZSBqdXN0IGZvbGxvd2luZyB0aGUKLSAgICAgIC8vIFJGQyBzcGVjaWZpY2F0aW9ucwotICAgICAgaWYgKHBfYmFzZSAhPSBudWxsKSB7Ci0gICAgICAgICAgYWJzb2x1dGl6ZShwX2Jhc2UpOwotICAgICAgfQotICB9Ci0KLSAvKioKLSAgKiBJbml0aWFsaXplcyB0aGlzIFVSSSBmcm9tIGEgYmFzZSBVUkkgYW5kIGEgVVJJIHNwZWNpZmljYXRpb24gc3RyaW5nLgotICAqIFNlZSBSRkMgMjM5NiBTZWN0aW9uIDQgYW5kIEFwcGVuZGl4IEIgZm9yIHNwZWNpZmljYXRpb25zIG9uIHBhcnNpbmcKLSAgKiB0aGUgVVJJIGFuZCBTZWN0aW9uIDUgZm9yIHNwZWNpZmljYXRpb25zIG9uIHJlc29sdmluZyByZWxhdGl2ZSBVUklzCi0gICogYW5kIHJlbGF0aXZlIHBhdGhzLgotICAqCi0gICogQHBhcmFtIHBfYmFzZSB0aGUgYmFzZSBVUkkgKG1heSBiZSBudWxsIGlmIHBfdXJpU3BlYyBpcyBhbiBhYnNvbHV0ZQotICAqICAgICAgICAgICAgICAgVVJJKQotICAqIEBwYXJhbSBwX3VyaVNwZWMgdGhlIFVSSSBzcGVjIHN0cmluZyB3aGljaCBtYXkgYmUgYW4gYWJzb2x1dGUgb3IKLSAgKiAgICAgICAgICAgICAgICAgIHJlbGF0aXZlIFVSSSAoY2FuIG9ubHkgYmUgbnVsbC9lbXB0eSBpZiBwX2Jhc2UKLSAgKiAgICAgICAgICAgICAgICAgIGlzIG5vdCBudWxsKQotICAqCi0gICogQGV4Y2VwdGlvbiBNYWxmb3JtZWRVUklFeGNlcHRpb24gaWYgcF9iYXNlIGlzIG51bGwgYW5kIHBfdXJpU3BlYwotICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzIG5vdCBhbiBhYnNvbHV0ZSBVUkkgb3IgaWYKLSAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwX3VyaVNwZWMgdmlvbGF0ZXMgc3ludGF4IHJ1bGVzCi0gICovCi0gIHByaXZhdGUgdm9pZCBpbml0aWFsaXplKFVSSSBwX2Jhc2UsIFN0cmluZyBwX3VyaVNwZWMpCi0gICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIE1hbGZvcm1lZFVSSUV4Y2VwdGlvbiB7Ci0KLSAgICBTdHJpbmcgdXJpU3BlYyA9IHBfdXJpU3BlYzsKLSAgICBpbnQgdXJpU3BlY0xlbiA9ICh1cmlTcGVjICE9IG51bGwpID8gdXJpU3BlYy5sZW5ndGgoKSA6IDA7Ci0KLSAgICBpZiAocF9iYXNlID09IG51bGwgJiYgdXJpU3BlY0xlbiA9PSAwKSB7Ci0gICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVVJJRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgIkNhbm5vdCBpbml0aWFsaXplIFVSSSB3aXRoIGVtcHR5IHBhcmFtZXRlcnMuIik7Ci0gICAgfQotCi0gICAgLy8ganVzdCBtYWtlIGEgY29weSBvZiB0aGUgYmFzZSBpZiBzcGVjIGlzIGVtcHR5Ci0gICAgaWYgKHVyaVNwZWNMZW4gPT0gMCkgewotICAgICAgaW5pdGlhbGl6ZShwX2Jhc2UpOwotICAgICAgcmV0dXJuOwotICAgIH0KLQotICAgIGludCBpbmRleCA9IDA7Ci0KLSAgICAvLyBDaGVjayBmb3Igc2NoZW1lLCB3aGljaCBtdXN0IGJlIGJlZm9yZSAnLycsICc/JyBvciAnIycuCi0gICAgaW50IGNvbG9uSWR4ID0gdXJpU3BlYy5pbmRleE9mKCc6Jyk7Ci0gICAgaWYgKGNvbG9uSWR4ICE9IC0xKSB7Ci0gICAgICAgIGZpbmFsIGludCBzZWFyY2hGcm9tID0gY29sb25JZHggLSAxOwotICAgICAgICAvLyBzZWFyY2ggYmFja3dhcmRzIHN0YXJ0aW5nIGZyb20gY2hhcmFjdGVyIGJlZm9yZSAnOicuCi0gICAgICAgIGludCBzbGFzaElkeCA9IHVyaVNwZWMubGFzdEluZGV4T2YoJy8nLCBzZWFyY2hGcm9tKTsKLSAgICAgICAgaW50IHF1ZXJ5SWR4ID0gdXJpU3BlYy5sYXN0SW5kZXhPZignPycsIHNlYXJjaEZyb20pOwotICAgICAgICBpbnQgZnJhZ21lbnRJZHggPSB1cmlTcGVjLmxhc3RJbmRleE9mKCcjJywgc2VhcmNoRnJvbSk7Ci0KLSAgICAgICAgaWYgKGNvbG9uSWR4ID09IDAgfHwgc2xhc2hJZHggIT0gLTEgfHwKLSAgICAgICAgICAgIHF1ZXJ5SWR4ICE9IC0xIHx8IGZyYWdtZW50SWR4ICE9IC0xKSB7Ci0gICAgICAgICAgICAvLyBBIHN0YW5kYWxvbmUgYmFzZSBpcyBhIHZhbGlkIFVSSSBhY2NvcmRpbmcgdG8gc3BlYwotICAgICAgICAgICAgaWYgKGNvbG9uSWR4ID09IDAgfHwgKHBfYmFzZSA9PSBudWxsICYmIGZyYWdtZW50SWR4ICE9IDApKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVSSUV4Y2VwdGlvbigiTm8gc2NoZW1lIGZvdW5kIGluIFVSSS4iKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIGluaXRpYWxpemVTY2hlbWUodXJpU3BlYyk7Ci0gICAgICAgICAgICBpbmRleCA9IG1fc2NoZW1lLmxlbmd0aCgpKzE7Ci0KLSAgICAgICAgICAgIC8vIE5laXRoZXIgJ3NjaGVtZTonIG9yICdzY2hlbWU6I2ZyYWdtZW50JyBhcmUgdmFsaWQgVVJJcy4KLSAgICAgICAgICAgIGlmIChjb2xvbklkeCA9PSB1cmlTcGVjTGVuIC0gMSB8fCB1cmlTcGVjLmNoYXJBdChjb2xvbklkeCsxKSA9PSAnIycpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVVJJRXhjZXB0aW9uKCJTY2hlbWUgc3BlY2lmaWMgcGFydCBjYW5ub3QgYmUgZW1wdHkuIik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0gICAgZWxzZSBpZiAocF9iYXNlID09IG51bGwgJiYgdXJpU3BlYy5pbmRleE9mKCcjJykgIT0gMCkgewotICAgICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVVJJRXhjZXB0aW9uKCJObyBzY2hlbWUgZm91bmQgaW4gVVJJLiIpOwotICAgIH0KLQotICAgIC8vIFR3byBzbGFzaGVzIG1lYW5zIHdlIG1heSBoYXZlIGF1dGhvcml0eSwgYnV0IGRlZmluaXRlbHkgbWVhbnMgd2UncmUgZWl0aGVyCi0gICAgLy8gbWF0Y2hpbmcgbmV0X3BhdGggb3IgYWJzX3BhdGguIFRoZXNlIHR3byBwcm9kdWN0aW9ucyBhcmUgYW1iaWd1b3VzIGluIHRoYXQKLSAgICAvLyBldmVyeSBuZXRfcGF0aCAoZXhjZXB0IHRob3NlIGNvbnRhaW5pbmcgYW4gSVB2NlJlZmVyZW5jZSkgaXMgYW4gYWJzX3BhdGguCi0gICAgLy8gUkZDIDIzOTYgcmVzb2x2ZXMgdGhpcyBhbWJpZ3VpdHkgYnkgYXBwbHlpbmcgYSBncmVlZHkgbGVmdCBtb3N0IG1hdGNoaW5nIHJ1bGUuCi0gICAgLy8gVHJ5IG1hdGNoaW5nIG5ldF9wYXRoIGZpcnN0LCBhbmQgaWYgdGhhdCBmYWlscyB3ZSBkb24ndCBoYXZlIGF1dGhvcml0eSBzbwotICAgIC8vIHRoZW4gYXR0ZW1wdCB0byBtYXRjaCBhYnNfcGF0aC4KLSAgICAvLwotICAgIC8vIG5ldF9wYXRoID0gIi8vIiBhdXRob3JpdHkgWyBhYnNfcGF0aCBdCi0gICAgLy8gYWJzX3BhdGggPSAiLyIgIHBhdGhfc2VnbWVudHMKLSAgICBpZiAoKChpbmRleCsxKSA8IHVyaVNwZWNMZW4pICYmCi0gICAgICAgICh1cmlTcGVjLmNoYXJBdChpbmRleCkgPT0gJy8nICYmIHVyaVNwZWMuY2hhckF0KGluZGV4KzEpID09ICcvJykpIHsKLSAgICAgIGluZGV4ICs9IDI7Ci0gICAgICBpbnQgc3RhcnRQb3MgPSBpbmRleDsKLQotICAgICAgLy8gQXV0aG9yaXR5IHdpbGwgYmUgZXZlcnl0aGluZyB1cCB0byBwYXRoLCBxdWVyeSBvciBmcmFnbWVudAotICAgICAgY2hhciB0ZXN0Q2hhciA9ICdcMCc7Ci0gICAgICB3aGlsZSAoaW5kZXggPCB1cmlTcGVjTGVuKSB7Ci0gICAgICAgIHRlc3RDaGFyID0gdXJpU3BlYy5jaGFyQXQoaW5kZXgpOwotICAgICAgICBpZiAodGVzdENoYXIgPT0gJy8nIHx8IHRlc3RDaGFyID09ICc/JyB8fCB0ZXN0Q2hhciA9PSAnIycpIHsKLSAgICAgICAgICBicmVhazsKLSAgICAgICAgfQotICAgICAgICBpbmRleCsrOwotICAgICAgfQotCi0gICAgICAvLyBBdHRlbXB0IHRvIHBhcnNlIGF1dGhvcml0eS4gSWYgdGhlIHNlY3Rpb24gaXMgYW4gZW1wdHkgc3RyaW5nCi0gICAgICAvLyB0aGlzIGlzIGEgdmFsaWQgc2VydmVyIGJhc2VkIGF1dGhvcml0eSwgc28gc2V0IHRoZSBob3N0IHRvIHRoaXMKLSAgICAgIC8vIHZhbHVlLgotICAgICAgaWYgKGluZGV4ID4gc3RhcnRQb3MpIHsKLSAgICAgICAgLy8gSWYgd2UgZGlkbid0IGZpbmQgYXV0aG9yaXR5IHdlIG5lZWQgdG8gYmFjayB1cC4gQXR0ZW1wdCB0bwotICAgICAgICAvLyBtYXRjaCBhZ2FpbnN0IGFic19wYXRoIG5leHQuCi0gICAgICAgIGlmICghaW5pdGlhbGl6ZUF1dGhvcml0eSh1cmlTcGVjLnN1YnN0cmluZyhzdGFydFBvcywgaW5kZXgpKSkgewotICAgICAgICAgIGluZGV4ID0gc3RhcnRQb3MgLSAyOwotICAgICAgICB9Ci0gICAgICB9IGVsc2UgaWYgKGluZGV4IDwgdXJpU3BlY0xlbikgewotICAgICAgICAvL1NhbWUgYXMgamF2YS5uZXQuVVJJOgotICAgICAgICAvLyBERVZJQVRJT046IEFsbG93IGVtcHR5IGF1dGhvcml0eSBwcmlvciB0byBub24tZW1wdHkKLSAgICAgICAgLy8gcGF0aCwgcXVlcnkgY29tcG9uZW50IG9yIGZyYWdtZW50IGlkZW50aWZpZXIKLSAgICAgICAgbV9ob3N0ID0gIiI7Ci0gICAgICB9IGVsc2UgewotICAgICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVVJJRXhjZXB0aW9uKCJFeHBlY3RlZCBhdXRob3JpdHkuIik7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgaW5pdGlhbGl6ZVBhdGgodXJpU3BlYywgaW5kZXgpOwotCi0gICAgLy8gUmVzb2x2ZSByZWxhdGl2ZSBVUkkgdG8gYmFzZSBVUkkgLSBzZWUgUkZDIDIzOTYgU2VjdGlvbiA1LjIKLSAgICAvLyBJbiBzb21lIGNhc2VzLCBpdCBtaWdodCBtYWtlIG1vcmUgc2Vuc2UgdG8gdGhyb3cgYW4gZXhjZXB0aW9uCi0gICAgLy8gKHdoZW4gc2NoZW1lIGlzIHNwZWNpZmllZCBpcyB0aGUgc3RyaW5nIHNwZWMgYW5kIHRoZSBiYXNlIFVSSQotICAgIC8vIGlzIGFsc28gc3BlY2lmaWVkLCBmb3IgZXhhbXBsZSksIGJ1dCB3ZSdyZSBqdXN0IGZvbGxvd2luZyB0aGUKLSAgICAvLyBSRkMgc3BlY2lmaWNhdGlvbnMKLSAgICBpZiAocF9iYXNlICE9IG51bGwpIHsKLSAgICAgICAgYWJzb2x1dGl6ZShwX2Jhc2UpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBBYnNvbHV0aXplIFVSSSB3aXRoIGdpdmVuIGJhc2UgVVJJLgotICAgKgotICAgKiBAcGFyYW0gcF9iYXNlIGJhc2UgVVJJIGZvciBhYnNvbHV0aXphdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgYWJzb2x1dGl6ZShVUkkgcF9iYXNlKSB7Ci0KLSAgICAgIC8vIGNoZWNrIHRvIHNlZSBpZiB0aGlzIGlzIHRoZSBjdXJyZW50IGRvYyAtIFJGQyAyMzk2IDUuMiAjMgotICAgICAgLy8gbm90ZSB0aGF0IHRoaXMgaXMgc2xpZ2h0bHkgZGlmZmVyZW50IGZyb20gdGhlIFJGQyBzcGVjIGluIHRoYXQKLSAgICAgIC8vIHdlIGRvbid0IGluY2x1ZGUgdGhlIGNoZWNrIGZvciBxdWVyeSBzdHJpbmcgYmVpbmcgbnVsbAotICAgICAgLy8gLSB0aGlzIGhhbmRsZXMgY2FzZXMgd2hlcmUgdGhlIHVyaXNwZWMgaXMganVzdCBhIHF1ZXJ5Ci0gICAgICAvLyBzdHJpbmcgb3IgYSBmcmFnbWVudCAoZS5nLiAiP3kiIG9yICIjcyIpIC0KLSAgICAgIC8vIHNlZSA8aHR0cDovL3d3dy5pY3MudWNpLmVkdS9+ZmllbGRpbmcvdXJsL3Rlc3QxLmh0bWw+IHdoaWNoCi0gICAgICAvLyBpZGVudGlmaWVkIHRoaXMgYXMgYSBidWcgaW4gdGhlIFJGQwotICAgICAgaWYgKG1fcGF0aC5sZW5ndGgoKSA9PSAwICYmIG1fc2NoZW1lID09IG51bGwgJiYKLSAgICAgICAgICBtX2hvc3QgPT0gbnVsbCAmJiBtX3JlZ0F1dGhvcml0eSA9PSBudWxsKSB7Ci0gICAgICAgICAgbV9zY2hlbWUgPSBwX2Jhc2UuZ2V0U2NoZW1lKCk7Ci0gICAgICAgICAgbV91c2VyaW5mbyA9IHBfYmFzZS5nZXRVc2VyaW5mbygpOwotICAgICAgICAgIG1faG9zdCA9IHBfYmFzZS5nZXRIb3N0KCk7Ci0gICAgICAgICAgbV9wb3J0ID0gcF9iYXNlLmdldFBvcnQoKTsKLSAgICAgICAgICBtX3JlZ0F1dGhvcml0eSA9IHBfYmFzZS5nZXRSZWdCYXNlZEF1dGhvcml0eSgpOwotICAgICAgICAgIG1fcGF0aCA9IHBfYmFzZS5nZXRQYXRoKCk7Ci0KLSAgICAgICAgICBpZiAobV9xdWVyeVN0cmluZyA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgIG1fcXVlcnlTdHJpbmcgPSBwX2Jhc2UuZ2V0UXVlcnlTdHJpbmcoKTsKLQotICAgICAgICAgICAgICBpZiAobV9mcmFnbWVudCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICBtX2ZyYWdtZW50ID0gcF9iYXNlLmdldEZyYWdtZW50KCk7Ci0gICAgICAgICAgICAgIH0KLSAgICAgICAgICB9Ci0gICAgICAgICAgcmV0dXJuOwotICAgICAgfQotCi0gICAgICAvLyBjaGVjayBmb3Igc2NoZW1lIC0gUkZDIDIzOTYgNS4yICMzCi0gICAgICAvLyBpZiB3ZSBmb3VuZCBhIHNjaGVtZSwgaXQgbWVhbnMgYWJzb2x1dGUgVVJJLCBzbyB3ZSdyZSBkb25lCi0gICAgICBpZiAobV9zY2hlbWUgPT0gbnVsbCkgewotICAgICAgICAgIG1fc2NoZW1lID0gcF9iYXNlLmdldFNjaGVtZSgpOwotICAgICAgfQotICAgICAgZWxzZSB7Ci0gICAgICAgICAgcmV0dXJuOwotICAgICAgfQotCi0gICAgICAvLyBjaGVjayBmb3IgYXV0aG9yaXR5IC0gUkZDIDIzOTYgNS4yICM0Ci0gICAgICAvLyBpZiB3ZSBmb3VuZCBhIGhvc3QsIHRoZW4gd2UndmUgZ290IGEgbmV0d29yayBwYXRoLCBzbyB3ZSdyZSBkb25lCi0gICAgICBpZiAobV9ob3N0ID09IG51bGwgJiYgbV9yZWdBdXRob3JpdHkgPT0gbnVsbCkgewotICAgICAgICAgIG1fdXNlcmluZm8gPSBwX2Jhc2UuZ2V0VXNlcmluZm8oKTsKLSAgICAgICAgICBtX2hvc3QgPSBwX2Jhc2UuZ2V0SG9zdCgpOwotICAgICAgICAgIG1fcG9ydCA9IHBfYmFzZS5nZXRQb3J0KCk7Ci0gICAgICAgICAgbV9yZWdBdXRob3JpdHkgPSBwX2Jhc2UuZ2V0UmVnQmFzZWRBdXRob3JpdHkoKTsKLSAgICAgIH0KLSAgICAgIGVsc2UgewotICAgICAgICAgIHJldHVybjsKLSAgICAgIH0KLQotICAgICAgLy8gY2hlY2sgZm9yIGFic29sdXRlIHBhdGggLSBSRkMgMjM5NiA1LjIgIzUKLSAgICAgIGlmIChtX3BhdGgubGVuZ3RoKCkgPiAwICYmCi0gICAgICAgICAgICAgIG1fcGF0aC5zdGFydHNXaXRoKCIvIikpIHsKLSAgICAgICAgICByZXR1cm47Ci0gICAgICB9Ci0KLSAgICAgIC8vIGlmIHdlIGdldCB0byB0aGlzIHBvaW50LCB3ZSBuZWVkIHRvIHJlc29sdmUgcmVsYXRpdmUgcGF0aAotICAgICAgLy8gUkZDIDIzOTYgNS4yICM2Ci0gICAgICBTdHJpbmcgcGF0aCA9ICIiOwotICAgICAgU3RyaW5nIGJhc2VQYXRoID0gcF9iYXNlLmdldFBhdGgoKTsKLQotICAgICAgLy8gNmEgLSBnZXQgYWxsIGJ1dCB0aGUgbGFzdCBzZWdtZW50IG9mIHRoZSBiYXNlIFVSSSBwYXRoCi0gICAgICBpZiAoYmFzZVBhdGggIT0gbnVsbCAmJiBiYXNlUGF0aC5sZW5ndGgoKSA+IDApIHsKLSAgICAgICAgICBpbnQgbGFzdFNsYXNoID0gYmFzZVBhdGgubGFzdEluZGV4T2YoJy8nKTsKLSAgICAgICAgICBpZiAobGFzdFNsYXNoICE9IC0xKSB7Ci0gICAgICAgICAgICAgIHBhdGggPSBiYXNlUGF0aC5zdWJzdHJpbmcoMCwgbGFzdFNsYXNoKzEpOwotICAgICAgICAgIH0KLSAgICAgIH0KLSAgICAgIGVsc2UgaWYgKG1fcGF0aC5sZW5ndGgoKSA+IDApIHsKLSAgICAgICAgICBwYXRoID0gIi8iOwotICAgICAgfQotCi0gICAgICAvLyA2YiAtIGFwcGVuZCB0aGUgcmVsYXRpdmUgVVJJIHBhdGgKLSAgICAgIHBhdGggPSBwYXRoLmNvbmNhdChtX3BhdGgpOwotCi0gICAgICAvLyA2YyAtIHJlbW92ZSBhbGwgIi4vIiB3aGVyZSAiLiIgaXMgYSBjb21wbGV0ZSBwYXRoIHNlZ21lbnQKLSAgICAgIGludCBpbmRleCA9IC0xOwotICAgICAgd2hpbGUgKChpbmRleCA9IHBhdGguaW5kZXhPZigiLy4vIikpICE9IC0xKSB7Ci0gICAgICAgICAgcGF0aCA9IHBhdGguc3Vic3RyaW5nKDAsIGluZGV4KzEpLmNvbmNhdChwYXRoLnN1YnN0cmluZyhpbmRleCszKSk7Ci0gICAgICB9Ci0KLSAgICAgIC8vIDZkIC0gcmVtb3ZlICIuIiBpZiBwYXRoIGVuZHMgd2l0aCAiLiIgYXMgYSBjb21wbGV0ZSBwYXRoIHNlZ21lbnQKLSAgICAgIGlmIChwYXRoLmVuZHNXaXRoKCIvLiIpKSB7Ci0gICAgICAgICAgcGF0aCA9IHBhdGguc3Vic3RyaW5nKDAsIHBhdGgubGVuZ3RoKCktMSk7Ci0gICAgICB9Ci0KLSAgICAgIC8vIDZlIC0gcmVtb3ZlIGFsbCAiPHNlZ21lbnQ+Ly4uLyIgd2hlcmUgIjxzZWdtZW50PiIgaXMgYSBjb21wbGV0ZQotICAgICAgLy8gcGF0aCBzZWdtZW50IG5vdCBlcXVhbCB0byAiLi4iCi0gICAgICBpbmRleCA9IDE7Ci0gICAgICBpbnQgc2VnSW5kZXggPSAtMTsKLSAgICAgIFN0cmluZyB0ZW1wU3RyaW5nID0gbnVsbDsKLQotICAgICAgd2hpbGUgKChpbmRleCA9IHBhdGguaW5kZXhPZigiLy4uLyIsIGluZGV4KSkgPiAwKSB7Ci0gICAgICAgICAgdGVtcFN0cmluZyA9IHBhdGguc3Vic3RyaW5nKDAsIHBhdGguaW5kZXhPZigiLy4uLyIpKTsKLSAgICAgICAgICBzZWdJbmRleCA9IHRlbXBTdHJpbmcubGFzdEluZGV4T2YoJy8nKTsKLSAgICAgICAgICBpZiAoc2VnSW5kZXggIT0gLTEpIHsKLSAgICAgICAgICAgICAgaWYgKCF0ZW1wU3RyaW5nLnN1YnN0cmluZyhzZWdJbmRleCkuZXF1YWxzKCIuLiIpKSB7Ci0gICAgICAgICAgICAgICAgICBwYXRoID0gcGF0aC5zdWJzdHJpbmcoMCwgc2VnSW5kZXgrMSkuY29uY2F0KHBhdGguc3Vic3RyaW5nKGluZGV4KzQpKTsKLSAgICAgICAgICAgICAgICAgIGluZGV4ID0gc2VnSW5kZXg7Ci0gICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICBpbmRleCArPSA0OwotICAgICAgICAgICAgICB9Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICBpbmRleCArPSA0OwotICAgICAgICAgIH0KLSAgICAgIH0KLQotICAgICAgLy8gNmYgLSByZW1vdmUgZW5kaW5nICI8c2VnbWVudD4vLi4iIHdoZXJlICI8c2VnbWVudD4iIGlzIGEKLSAgICAgIC8vIGNvbXBsZXRlIHBhdGggc2VnbWVudAotICAgICAgaWYgKHBhdGguZW5kc1dpdGgoIi8uLiIpKSB7Ci0gICAgICAgICAgdGVtcFN0cmluZyA9IHBhdGguc3Vic3RyaW5nKDAsIHBhdGgubGVuZ3RoKCktMyk7Ci0gICAgICAgICAgc2VnSW5kZXggPSB0ZW1wU3RyaW5nLmxhc3RJbmRleE9mKCcvJyk7Ci0gICAgICAgICAgaWYgKHNlZ0luZGV4ICE9IC0xKSB7Ci0gICAgICAgICAgICAgIHBhdGggPSBwYXRoLnN1YnN0cmluZygwLCBzZWdJbmRleCsxKTsKLSAgICAgICAgICB9Ci0gICAgICB9Ci0gICAgICBtX3BhdGggPSBwYXRoOwotICB9Ci0KLSAvKioKLSAgKiBJbml0aWFsaXplIHRoZSBzY2hlbWUgZm9yIHRoaXMgVVJJIGZyb20gYSBVUkkgc3RyaW5nIHNwZWMuCi0gICoKLSAgKiBAcGFyYW0gcF91cmlTcGVjIHRoZSBVUkkgc3BlY2lmaWNhdGlvbiAoY2Fubm90IGJlIG51bGwpCi0gICoKLSAgKiBAZXhjZXB0aW9uIE1hbGZvcm1lZFVSSUV4Y2VwdGlvbiBpZiBVUkkgZG9lcyBub3QgaGF2ZSBhIGNvbmZvcm1hbnQKLSAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2hlbWUKLSAgKi8KLSAgcHJpdmF0ZSB2b2lkIGluaXRpYWxpemVTY2hlbWUoU3RyaW5nIHBfdXJpU3BlYykKLSAgICAgICAgICAgICAgICAgdGhyb3dzIE1hbGZvcm1lZFVSSUV4Y2VwdGlvbiB7Ci0gICAgaW50IHVyaVNwZWNMZW4gPSBwX3VyaVNwZWMubGVuZ3RoKCk7Ci0gICAgaW50IGluZGV4ID0gMDsKLSAgICBTdHJpbmcgc2NoZW1lID0gbnVsbDsKLSAgICBjaGFyIHRlc3RDaGFyID0gJ1wwJzsKLQotICAgIHdoaWxlIChpbmRleCA8IHVyaVNwZWNMZW4pIHsKLSAgICAgIHRlc3RDaGFyID0gcF91cmlTcGVjLmNoYXJBdChpbmRleCk7Ci0gICAgICBpZiAodGVzdENoYXIgPT0gJzonIHx8IHRlc3RDaGFyID09ICcvJyB8fAotICAgICAgICAgIHRlc3RDaGFyID09ICc/JyB8fCB0ZXN0Q2hhciA9PSAnIycpIHsKLSAgICAgICAgYnJlYWs7Ci0gICAgICB9Ci0gICAgICBpbmRleCsrOwotICAgIH0KLSAgICBzY2hlbWUgPSBwX3VyaVNwZWMuc3Vic3RyaW5nKDAsIGluZGV4KTsKLQotICAgIGlmIChzY2hlbWUubGVuZ3RoKCkgPT0gMCkgewotICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVSSUV4Y2VwdGlvbigiTm8gc2NoZW1lIGZvdW5kIGluIFVSSS4iKTsKLSAgICB9Ci0gICAgZWxzZSB7Ci0gICAgICBzZXRTY2hlbWUoc2NoZW1lKTsKLSAgICB9Ci0gIH0KLQotIC8qKgotICAqIEluaXRpYWxpemUgdGhlIGF1dGhvcml0eSAoZWl0aGVyIHNlcnZlciBvciByZWdpc3RyeSBiYXNlZCkKLSAgKiBmb3IgdGhpcyBVUkkgZnJvbSBhIFVSSSBzdHJpbmcgc3BlYy4KLSAgKgotICAqIEBwYXJhbSBwX3VyaVNwZWMgdGhlIFVSSSBzcGVjaWZpY2F0aW9uIChjYW5ub3QgYmUgbnVsbCkKLSAgKgotICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgZ2l2ZW4gc3RyaW5nIG1hdGNoZWQgc2VydmVyIG9yIHJlZ2lzdHJ5Ci0gICogYmFzZWQgYXV0aG9yaXR5Ci0gICovCi0gIHByaXZhdGUgYm9vbGVhbiBpbml0aWFsaXplQXV0aG9yaXR5KFN0cmluZyBwX3VyaVNwZWMpIHsKLQotICAgIGludCBpbmRleCA9IDA7Ci0gICAgaW50IHN0YXJ0ID0gMDsKLSAgICBpbnQgZW5kID0gcF91cmlTcGVjLmxlbmd0aCgpOwotCi0gICAgY2hhciB0ZXN0Q2hhciA9ICdcMCc7Ci0gICAgU3RyaW5nIHVzZXJpbmZvID0gbnVsbDsKLQotICAgIC8vIHVzZXJpbmZvIGlzIGV2ZXJ5dGhpbmcgdXAgdG8gQAotICAgIGlmIChwX3VyaVNwZWMuaW5kZXhPZignQCcsIHN0YXJ0KSAhPSAtMSkgewotICAgICAgd2hpbGUgKGluZGV4IDwgZW5kKSB7Ci0gICAgICAgIHRlc3RDaGFyID0gcF91cmlTcGVjLmNoYXJBdChpbmRleCk7Ci0gICAgICAgIGlmICh0ZXN0Q2hhciA9PSAnQCcpIHsKLSAgICAgICAgICBicmVhazsKLSAgICAgICAgfQotICAgICAgICBpbmRleCsrOwotICAgICAgfQotICAgICAgdXNlcmluZm8gPSBwX3VyaVNwZWMuc3Vic3RyaW5nKHN0YXJ0LCBpbmRleCk7Ci0gICAgICBpbmRleCsrOwotICAgIH0KLQotICAgIC8vIGhvc3QgaXMgZXZlcnl0aGluZyB1cCB0byBsYXN0ICc6Jywgb3IgdXAgdG8KLSAgICAvLyBhbmQgaW5jbHVkaW5nICddJyBpZiBmb2xsb3dlZCBieSAnOicuCi0gICAgU3RyaW5nIGhvc3QgPSBudWxsOwotICAgIHN0YXJ0ID0gaW5kZXg7Ci0gICAgYm9vbGVhbiBoYXNQb3J0ID0gZmFsc2U7Ci0gICAgaWYgKGluZGV4IDwgZW5kKSB7Ci0gICAgICBpZiAocF91cmlTcGVjLmNoYXJBdChzdGFydCkgPT0gJ1snKSB7Ci0gICAgICAgIGludCBicmFja2V0SW5kZXggPSBwX3VyaVNwZWMuaW5kZXhPZignXScsIHN0YXJ0KTsKLSAgICAgICAgaW5kZXggPSAoYnJhY2tldEluZGV4ICE9IC0xKSA/IGJyYWNrZXRJbmRleCA6IGVuZDsKLSAgICAgICAgaWYgKGluZGV4KzEgPCBlbmQgJiYgcF91cmlTcGVjLmNoYXJBdChpbmRleCsxKSA9PSAnOicpIHsKLSAgICAgICAgICArK2luZGV4OwotICAgICAgICAgIGhhc1BvcnQgPSB0cnVlOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgIGluZGV4ID0gZW5kOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgICBlbHNlIHsKLSAgICAgICAgaW50IGNvbG9uSW5kZXggPSBwX3VyaVNwZWMubGFzdEluZGV4T2YoJzonLCBlbmQpOwotICAgICAgICBpbmRleCA9IChjb2xvbkluZGV4ID4gc3RhcnQpID8gY29sb25JbmRleCA6IGVuZDsKLSAgICAgICAgaGFzUG9ydCA9IChpbmRleCAhPSBlbmQpOwotICAgICAgfQotICAgIH0KLSAgICBob3N0ID0gcF91cmlTcGVjLnN1YnN0cmluZyhzdGFydCwgaW5kZXgpOwotICAgIGludCBwb3J0ID0gLTE7Ci0gICAgaWYgKGhvc3QubGVuZ3RoKCkgPiAwKSB7Ci0gICAgICAvLyBwb3J0Ci0gICAgICBpZiAoaGFzUG9ydCkgewotICAgICAgICBpbmRleCsrOwotICAgICAgICBzdGFydCA9IGluZGV4OwotICAgICAgICB3aGlsZSAoaW5kZXggPCBlbmQpIHsKLSAgICAgICAgICBpbmRleCsrOwotICAgICAgICB9Ci0gICAgICAgIFN0cmluZyBwb3J0U3RyID0gcF91cmlTcGVjLnN1YnN0cmluZyhzdGFydCwgaW5kZXgpOwotICAgICAgICBpZiAocG9ydFN0ci5sZW5ndGgoKSA+IDApIHsKLSAgICAgICAgICAvLyBSRVZJU0lUOiBSZW1vdmUgdGhpcyBjb2RlLgotICAgICAgICAgIC8qKiBmb3IgKGludCBpID0gMDsgaSA8IHBvcnRTdHIubGVuZ3RoKCk7IGkrKykgewotICAgICAgICAgICAgaWYgKCFpc0RpZ2l0KHBvcnRTdHIuY2hhckF0KGkpKSkgewotICAgICAgICAgICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVVJJRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgIHBvcnRTdHIgKwotICAgICAgICAgICAgICAgICAgICIgaXMgaW52YWxpZC4gUG9ydCBzaG91bGQgb25seSBjb250YWluIGRpZ2l0cyEiKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICB9KiovCi0gICAgICAgICAgLy8gUkVWSVNJVDogUmVtb3ZlIHRoaXMgY29kZS4KLSAgICAgICAgICAvLyBTdG9yZSBwb3J0IHZhbHVlIGFzIHN0cmluZyBpbnN0ZWFkIG9mIGludGVnZXIuCi0gICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIHBvcnQgPSBJbnRlZ2VyLnBhcnNlSW50KHBvcnRTdHIpOwotICAgICAgICAgICAgaWYgKHBvcnQgPT0gLTEpIC0tcG9ydDsKLSAgICAgICAgICB9Ci0gICAgICAgICAgY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBuZmUpIHsKLSAgICAgICAgICAgIHBvcnQgPSAtMjsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICB9Ci0KLSAgICBpZiAoaXNWYWxpZFNlcnZlckJhc2VkQXV0aG9yaXR5KGhvc3QsIHBvcnQsIHVzZXJpbmZvKSkgewotICAgICAgbV9ob3N0ID0gaG9zdDsKLSAgICAgIG1fcG9ydCA9IHBvcnQ7Ci0gICAgICBtX3VzZXJpbmZvID0gdXNlcmluZm87Ci0gICAgICByZXR1cm4gdHJ1ZTsKLSAgICB9Ci0gICAgLy8gTm90ZTogUmVnaXN0cnkgYmFzZWQgYXV0aG9yaXR5IGlzIGJlaW5nIHJlbW92ZWQgZnJvbSBhCi0gICAgLy8gbmV3IHNwZWMgZm9yIFVSSSB3aGljaCB3b3VsZCBvYnNvbGV0ZSBSRkMgMjM5Ni4gSWYgdGhlCi0gICAgLy8gc3BlYyBpcyBhZGRlZCB0byBYTUwgZXJyYXRhLCBwcm9jZXNzaW5nIG9mIHJlZ19uYW1lCi0gICAgLy8gbmVlZHMgdG8gYmUgcmVtb3ZlZC4gLSBtcmdsYXZhcy4KLSAgICBlbHNlIGlmIChpc1ZhbGlkUmVnaXN0cnlCYXNlZEF1dGhvcml0eShwX3VyaVNwZWMpKSB7Ci0gICAgICBtX3JlZ0F1dGhvcml0eSA9IHBfdXJpU3BlYzsKLSAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLSAgICByZXR1cm4gZmFsc2U7Ci0gIH0KLQotICAvKioKLSAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBjb21wb25lbnRzIGhvc3QsIHBvcnQsIGFuZCB1c2VyIGluZm8KLSAgICogYXJlIHZhbGlkIGFzIGEgc2VydmVyIGF1dGhvcml0eS4KLSAgICoKLSAgICogQHBhcmFtIGhvc3QgdGhlIGhvc3QgY29tcG9uZW50IG9mIGF1dGhvcml0eQotICAgKiBAcGFyYW0gcG9ydCB0aGUgcG9ydCBudW1iZXIgY29tcG9uZW50IG9mIGF1dGhvcml0eQotICAgKiBAcGFyYW0gdXNlcmluZm8gdGhlIHVzZXIgaW5mbyBjb21wb25lbnQgb2YgYXV0aG9yaXR5Ci0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgZ2l2ZW4gaG9zdCwgcG9ydCwgYW5kIHVzZXJpbmZvIGNvbXBvc2UKLSAgICogYSB2YWxpZCBzZXJ2ZXIgYXV0aG9yaXR5Ci0gICAqLwotICBwcml2YXRlIGJvb2xlYW4gaXNWYWxpZFNlcnZlckJhc2VkQXV0aG9yaXR5KFN0cmluZyBob3N0LCBpbnQgcG9ydCwgU3RyaW5nIHVzZXJpbmZvKSB7Ci0KLSAgICAvLyBDaGVjayBpZiB0aGUgaG9zdCBpcyB3ZWxsIGZvcm1lZC4KLSAgICBpZiAoIWlzV2VsbEZvcm1lZEFkZHJlc3MoaG9zdCkpIHsKLSAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICAvLyBDaGVjayB0aGF0IHBvcnQgaXMgd2VsbCBmb3JtZWQgaWYgaXQgZXhpc3RzLgotICAgIC8vIFJFVklTSVQ6IFRoZXJlJ3Mgbm8gcmVzdHJpY3Rpb24gb24gcG9ydCB2YWx1ZSByYW5nZXMsIGJ1dAotICAgIC8vIHBlcmZvcm0gdGhlIHNhbWUgY2hlY2sgYXMgaW4gc2V0UG9ydCB0byBiZSBjb25zaXN0ZW50LiBQYXNzCi0gICAgLy8gaW4gYSBzdHJpbmcgdG8gdGhpcyBtZXRob2QgaW5zdGVhZCBvZiBhbiBpbnRlZ2VyLgotICAgIGlmIChwb3J0IDwgLTEgfHwgcG9ydCA+IDY1NTM1KSB7Ci0gICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgLy8gQ2hlY2sgdGhhdCB1c2VyaW5mbyBpcyB3ZWxsIGZvcm1lZCBpZiBpdCBleGlzdHMuCi0gICAgaWYgKHVzZXJpbmZvICE9IG51bGwpIHsKLSAgICAgIC8vIFVzZXJpbmZvIGNhbiBjb250YWluIGFscGhhbnVtZXJpY3MsIG1hcmsgY2hhcmFjdGVycywgZXNjYXBlZAotICAgICAgLy8gYW5kICc7JywnOicsJyYnLCc9JywnKycsJyQnLCcsJwotICAgICAgaW50IGluZGV4ID0gMDsKLSAgICAgIGludCBlbmQgPSB1c2VyaW5mby5sZW5ndGgoKTsKLSAgICAgIGNoYXIgdGVzdENoYXIgPSAnXDAnOwotICAgICAgd2hpbGUgKGluZGV4IDwgZW5kKSB7Ci0gICAgICAgIHRlc3RDaGFyID0gdXNlcmluZm8uY2hhckF0KGluZGV4KTsKLSAgICAgICAgaWYgKHRlc3RDaGFyID09ICclJykgewotICAgICAgICAgIGlmIChpbmRleCsyID49IGVuZCB8fAotICAgICAgICAgICAgIWlzSGV4KHVzZXJpbmZvLmNoYXJBdChpbmRleCsxKSkgfHwKLSAgICAgICAgICAgICFpc0hleCh1c2VyaW5mby5jaGFyQXQoaW5kZXgrMikpKSB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgfQotICAgICAgICAgIGluZGV4ICs9IDI7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoIWlzVXNlcmluZm9DaGFyYWN0ZXIodGVzdENoYXIpKSB7Ci0gICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0gICAgICAgICsraW5kZXg7Ci0gICAgICB9Ci0gICAgfQotICAgIHJldHVybiB0cnVlOwotICB9Ci0KLSAgLyoqCi0gICAqIERldGVybWluZXMgd2hldGhlciB0aGUgZ2l2ZW4gc3RyaW5nIGlzIGEgcmVnaXN0cnkgYmFzZWQgYXV0aG9yaXR5LgotICAgKgotICAgKiBAcGFyYW0gYXV0aG9yaXR5IHRoZSBhdXRob3JpdHkgY29tcG9uZW50IG9mIGEgVVJJCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgZ2l2ZW4gc3RyaW5nIGlzIGEgcmVnaXN0cnkgYmFzZWQgYXV0aG9yaXR5Ci0gICAqLwotICBwcml2YXRlIGJvb2xlYW4gaXNWYWxpZFJlZ2lzdHJ5QmFzZWRBdXRob3JpdHkoU3RyaW5nIGF1dGhvcml0eSkgewotICAgIGludCBpbmRleCA9IDA7Ci0gICAgaW50IGVuZCA9IGF1dGhvcml0eS5sZW5ndGgoKTsKLSAgICBjaGFyIHRlc3RDaGFyOwotCi0gICAgd2hpbGUgKGluZGV4IDwgZW5kKSB7Ci0gICAgICB0ZXN0Q2hhciA9IGF1dGhvcml0eS5jaGFyQXQoaW5kZXgpOwotCi0gICAgICAvLyBjaGVjayBmb3IgdmFsaWQgZXNjYXBlIHNlcXVlbmNlCi0gICAgICBpZiAodGVzdENoYXIgPT0gJyUnKSB7Ci0gICAgICAgIGlmIChpbmRleCsyID49IGVuZCB8fAotICAgICAgICAgICAgIWlzSGV4KGF1dGhvcml0eS5jaGFyQXQoaW5kZXgrMSkpIHx8Ci0gICAgICAgICAgICAhaXNIZXgoYXV0aG9yaXR5LmNoYXJBdChpbmRleCsyKSkpIHsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotICAgICAgICBpbmRleCArPSAyOwotICAgICAgfQotICAgICAgLy8gY2FuIGNoZWNrIGFnYWluc3QgcGF0aCBjaGFyYWN0ZXJzIGJlY2F1c2UgdGhlIHNldAotICAgICAgLy8gaXMgdGhlIHNhbWUgZXhjZXB0IGZvciAnLycgd2hpY2ggd2UndmUgYWxyZWFkeSBleGNsdWRlZC4KLSAgICAgIGVsc2UgaWYgKCFpc1BhdGhDaGFyYWN0ZXIodGVzdENoYXIpKSB7Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgIH0KLSAgICAgICsraW5kZXg7Ci0gICAgfQotICAgIHJldHVybiB0cnVlOwotICB9Ci0KLSAvKioKLSAgKiBJbml0aWFsaXplIHRoZSBwYXRoIGZvciB0aGlzIFVSSSBmcm9tIGEgVVJJIHN0cmluZyBzcGVjLgotICAqCi0gICogQHBhcmFtIHBfdXJpU3BlYyB0aGUgVVJJIHNwZWNpZmljYXRpb24gKGNhbm5vdCBiZSBudWxsKQotICAqIEBwYXJhbSBwX25TdGFydEluZGV4IHRoZSBpbmRleCB0byBiZWdpbiBzY2FubmluZyBmcm9tCi0gICoKLSAgKiBAZXhjZXB0aW9uIE1hbGZvcm1lZFVSSUV4Y2VwdGlvbiBpZiBwX3VyaVNwZWMgdmlvbGF0ZXMgc3ludGF4IHJ1bGVzCi0gICovCi0gIHByaXZhdGUgdm9pZCBpbml0aWFsaXplUGF0aChTdHJpbmcgcF91cmlTcGVjLCBpbnQgcF9uU3RhcnRJbmRleCkKLSAgICAgICAgICAgICAgICAgdGhyb3dzIE1hbGZvcm1lZFVSSUV4Y2VwdGlvbiB7Ci0gICAgaWYgKHBfdXJpU3BlYyA9PSBudWxsKSB7Ci0gICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVVJJRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICJDYW5ub3QgaW5pdGlhbGl6ZSBwYXRoIGZyb20gbnVsbCBzdHJpbmchIik7Ci0gICAgfQotCi0gICAgaW50IGluZGV4ID0gcF9uU3RhcnRJbmRleDsKLSAgICBpbnQgc3RhcnQgPSBwX25TdGFydEluZGV4OwotICAgIGludCBlbmQgPSBwX3VyaVNwZWMubGVuZ3RoKCk7Ci0gICAgY2hhciB0ZXN0Q2hhciA9ICdcMCc7Ci0KLSAgICAvLyBwYXRoIC0gZXZlcnl0aGluZyB1cCB0byBxdWVyeSBzdHJpbmcgb3IgZnJhZ21lbnQKLSAgICBpZiAoc3RhcnQgPCBlbmQpIHsKLSAgICAgICAgLy8gUkZDIDI3MzIgb25seSBhbGxvd3MgJ1snIGFuZCAnXScgdG8gYXBwZWFyIGluIHRoZSBvcGFxdWUgcGFydC4KLSAgICAgICAgaWYgKGdldFNjaGVtZSgpID09IG51bGwgfHwgcF91cmlTcGVjLmNoYXJBdChzdGFydCkgPT0gJy8nKSB7Ci0KLSAgICAgICAgICAgIC8vIFNjYW4gcGF0aC4KLSAgICAgICAgICAgIC8vIGFic19wYXRoID0gIi8iICBwYXRoX3NlZ21lbnRzCi0gICAgICAgICAgICAvLyByZWxfcGF0aCA9IHJlbF9zZWdtZW50IFsgYWJzX3BhdGggXQotICAgICAgICAgICAgd2hpbGUgKGluZGV4IDwgZW5kKSB7Ci0gICAgICAgICAgICAgICAgdGVzdENoYXIgPSBwX3VyaVNwZWMuY2hhckF0KGluZGV4KTsKLQotICAgICAgICAgICAgICAgIC8vIGNoZWNrIGZvciB2YWxpZCBlc2NhcGUgc2VxdWVuY2UKLSAgICAgICAgICAgICAgICBpZiAodGVzdENoYXIgPT0gJyUnKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChpbmRleCsyID49IGVuZCB8fAotICAgICAgICAgICAgICAgICAgICAhaXNIZXgocF91cmlTcGVjLmNoYXJBdChpbmRleCsxKSkgfHwKLSAgICAgICAgICAgICAgICAgICAgIWlzSGV4KHBfdXJpU3BlYy5jaGFyQXQoaW5kZXgrMikpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVVJJRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICJQYXRoIGNvbnRhaW5zIGludmFsaWQgZXNjYXBlIHNlcXVlbmNlISIpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGluZGV4ICs9IDI7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIC8vIFBhdGggc2VnbWVudHMgY2Fubm90IGNvbnRhaW4gJ1snIG9yICddJyBzaW5jZSBwY2hhcgotICAgICAgICAgICAgICAgIC8vIHByb2R1Y3Rpb24gd2FzIG5vdCBjaGFuZ2VkIGJ5IFJGQyAyNzMyLgotICAgICAgICAgICAgICAgIGVsc2UgaWYgKCFpc1BhdGhDaGFyYWN0ZXIodGVzdENoYXIpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmICh0ZXN0Q2hhciA9PSAnPycgfHwgdGVzdENoYXIgPT0gJyMnKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVVJJRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICAgICAgIlBhdGggY29udGFpbnMgaW52YWxpZCBjaGFyYWN0ZXI6ICIgKyB0ZXN0Q2hhcik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICsraW5kZXg7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0KLSAgICAgICAgICAgIC8vIFNjYW4gb3BhcXVlIHBhcnQuCi0gICAgICAgICAgICAvLyBvcGFxdWVfcGFydCA9IHVyaWNfbm9fc2xhc2ggKnVyaWMKLSAgICAgICAgICAgIHdoaWxlIChpbmRleCA8IGVuZCkgewotICAgICAgICAgICAgICAgIHRlc3RDaGFyID0gcF91cmlTcGVjLmNoYXJBdChpbmRleCk7Ci0KLSAgICAgICAgICAgICAgICBpZiAodGVzdENoYXIgPT0gJz8nIHx8IHRlc3RDaGFyID09ICcjJykgewotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyBjaGVjayBmb3IgdmFsaWQgZXNjYXBlIHNlcXVlbmNlCi0gICAgICAgICAgICAgICAgaWYgKHRlc3RDaGFyID09ICclJykgewotICAgICAgICAgICAgICAgICAgICBpZiAoaW5kZXgrMiA+PSBlbmQgfHwKLSAgICAgICAgICAgICAgICAgICAgIWlzSGV4KHBfdXJpU3BlYy5jaGFyQXQoaW5kZXgrMSkpIHx8Ci0gICAgICAgICAgICAgICAgICAgICFpc0hleChwX3VyaVNwZWMuY2hhckF0KGluZGV4KzIpKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVSSUV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAiT3BhcXVlIHBhcnQgY29udGFpbnMgaW52YWxpZCBlc2NhcGUgc2VxdWVuY2UhIik7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgaW5kZXggKz0gMjsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLy8gSWYgdGhlIHNjaGVtZSBzcGVjaWZpYyBwYXJ0IGlzIG9wYXF1ZSwgaXQgY2FuIGNvbnRhaW4gJ1snCi0gICAgICAgICAgICAgICAgLy8gYW5kICddJy4gdXJpY19ub19zbGFzaCB3YXNuJ3QgbW9kaWZpZWQgYnkgUkZDIDI3MzIsIHdoaWNoCi0gICAgICAgICAgICAgICAgLy8gSSd2ZSBpbnRlcnByZXRlZCBhcyBhbiBlcnJvciBpbiB0aGUgc3BlYywgc2luY2UgdGhlCi0gICAgICAgICAgICAgICAgLy8gcHJvZHVjdGlvbiBzaG91bGQgYmUgZXF1aXZhbGVudCB0byAodXJpYyAtICcvJyksIGFuZCB1cmljCi0gICAgICAgICAgICAgICAgLy8gY29udGFpbnMgJ1snIGFuZCAnXScuIC0gbXJnbGF2YXMKLSAgICAgICAgICAgICAgICBlbHNlIGlmICghaXNVUklDaGFyYWN0ZXIodGVzdENoYXIpKSB7Ci0gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVUklFeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgICAgICAiT3BhcXVlIHBhcnQgY29udGFpbnMgaW52YWxpZCBjaGFyYWN0ZXI6ICIgKyB0ZXN0Q2hhcik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICsraW5kZXg7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0gICAgbV9wYXRoID0gcF91cmlTcGVjLnN1YnN0cmluZyhzdGFydCwgaW5kZXgpOwotCi0gICAgLy8gcXVlcnkgLSBzdGFydHMgd2l0aCA/IGFuZCB1cCB0byBmcmFnbWVudCBvciBlbmQKLSAgICBpZiAodGVzdENoYXIgPT0gJz8nKSB7Ci0gICAgICBpbmRleCsrOwotICAgICAgc3RhcnQgPSBpbmRleDsKLSAgICAgIHdoaWxlIChpbmRleCA8IGVuZCkgewotICAgICAgICB0ZXN0Q2hhciA9IHBfdXJpU3BlYy5jaGFyQXQoaW5kZXgpOwotICAgICAgICBpZiAodGVzdENoYXIgPT0gJyMnKSB7Ci0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKHRlc3RDaGFyID09ICclJykgewotICAgICAgICAgICBpZiAoaW5kZXgrMiA+PSBlbmQgfHwKLSAgICAgICAgICAgICAgIWlzSGV4KHBfdXJpU3BlYy5jaGFyQXQoaW5kZXgrMSkpIHx8Ci0gICAgICAgICAgICAgICFpc0hleChwX3VyaVNwZWMuY2hhckF0KGluZGV4KzIpKSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVSSUV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgIlF1ZXJ5IHN0cmluZyBjb250YWlucyBpbnZhbGlkIGVzY2FwZSBzZXF1ZW5jZSEiKTsKLSAgICAgICAgICAgfQotICAgICAgICAgICBpbmRleCArPSAyOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKCFpc1VSSUNoYXJhY3Rlcih0ZXN0Q2hhcikpIHsKLSAgICAgICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVVJJRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICJRdWVyeSBzdHJpbmcgY29udGFpbnMgaW52YWxpZCBjaGFyYWN0ZXI6ICIgKyB0ZXN0Q2hhcik7Ci0gICAgICAgIH0KLSAgICAgICAgaW5kZXgrKzsKLSAgICAgIH0KLSAgICAgIG1fcXVlcnlTdHJpbmcgPSBwX3VyaVNwZWMuc3Vic3RyaW5nKHN0YXJ0LCBpbmRleCk7Ci0gICAgfQotCi0gICAgLy8gZnJhZ21lbnQgLSBzdGFydHMgd2l0aCAjCi0gICAgaWYgKHRlc3RDaGFyID09ICcjJykgewotICAgICAgaW5kZXgrKzsKLSAgICAgIHN0YXJ0ID0gaW5kZXg7Ci0gICAgICB3aGlsZSAoaW5kZXggPCBlbmQpIHsKLSAgICAgICAgdGVzdENoYXIgPSBwX3VyaVNwZWMuY2hhckF0KGluZGV4KTsKLQotICAgICAgICBpZiAodGVzdENoYXIgPT0gJyUnKSB7Ci0gICAgICAgICAgIGlmIChpbmRleCsyID49IGVuZCB8fAotICAgICAgICAgICAgICAhaXNIZXgocF91cmlTcGVjLmNoYXJBdChpbmRleCsxKSkgfHwKLSAgICAgICAgICAgICAgIWlzSGV4KHBfdXJpU3BlYy5jaGFyQXQoaW5kZXgrMikpKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVVJJRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICAiRnJhZ21lbnQgY29udGFpbnMgaW52YWxpZCBlc2NhcGUgc2VxdWVuY2UhIik7Ci0gICAgICAgICAgIH0KLSAgICAgICAgICAgaW5kZXggKz0gMjsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICghaXNVUklDaGFyYWN0ZXIodGVzdENoYXIpKSB7Ci0gICAgICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVSSUV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAiRnJhZ21lbnQgY29udGFpbnMgaW52YWxpZCBjaGFyYWN0ZXI6ICIrdGVzdENoYXIpOwotICAgICAgICB9Ci0gICAgICAgIGluZGV4Kys7Ci0gICAgICB9Ci0gICAgICBtX2ZyYWdtZW50ID0gcF91cmlTcGVjLnN1YnN0cmluZyhzdGFydCwgaW5kZXgpOwotICAgIH0KLSAgfQotCi0gLyoqCi0gICogR2V0IHRoZSBzY2hlbWUgZm9yIHRoaXMgVVJJLgotICAqCi0gICogQHJldHVybiB0aGUgc2NoZW1lIGZvciB0aGlzIFVSSQotICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFNjaGVtZSgpIHsKLSAgICByZXR1cm4gbV9zY2hlbWU7Ci0gIH0KLQotIC8qKgotICAqIEdldCB0aGUgc2NoZW1lLXNwZWNpZmljIHBhcnQgZm9yIHRoaXMgVVJJIChldmVyeXRoaW5nIGZvbGxvd2luZyB0aGUKLSAgKiBzY2hlbWUgYW5kIHRoZSBmaXJzdCBjb2xvbikuIFNlZSBSRkMgMjM5NiBTZWN0aW9uIDUuMiBmb3Igc3BlYy4KLSAgKgotICAqIEByZXR1cm4gdGhlIHNjaGVtZS1zcGVjaWZpYyBwYXJ0IGZvciB0aGlzIFVSSQotICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFNjaGVtZVNwZWNpZmljUGFydCgpIHsKLSAgICBmaW5hbCBTdHJpbmdCdWlsZGVyIHNjaGVtZXNwZWMgPSBuZXcgU3RyaW5nQnVpbGRlcigpOwotCi0gICAgaWYgKG1faG9zdCAhPSBudWxsIHx8IG1fcmVnQXV0aG9yaXR5ICE9IG51bGwpIHsKLSAgICAgIHNjaGVtZXNwZWMuYXBwZW5kKCIvLyIpOwotCi0gICAgICAvLyBTZXJ2ZXIgYmFzZWQgYXV0aG9yaXR5LgotICAgICAgaWYgKG1faG9zdCAhPSBudWxsKSB7Ci0KLSAgICAgICAgaWYgKG1fdXNlcmluZm8gIT0gbnVsbCkgewotICAgICAgICAgIHNjaGVtZXNwZWMuYXBwZW5kKG1fdXNlcmluZm8pOwotICAgICAgICAgIHNjaGVtZXNwZWMuYXBwZW5kKCdAJyk7Ci0gICAgICAgIH0KLQotICAgICAgICBzY2hlbWVzcGVjLmFwcGVuZChtX2hvc3QpOwotCi0gICAgICAgIGlmIChtX3BvcnQgIT0gLTEpIHsKLSAgICAgICAgICBzY2hlbWVzcGVjLmFwcGVuZCgnOicpOwotICAgICAgICAgIHNjaGVtZXNwZWMuYXBwZW5kKG1fcG9ydCk7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICAgIC8vIFJlZ2lzdHJ5IGJhc2VkIGF1dGhvcml0eS4KLSAgICAgIGVsc2UgewotICAgICAgICBzY2hlbWVzcGVjLmFwcGVuZChtX3JlZ0F1dGhvcml0eSk7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgaWYgKG1fcGF0aCAhPSBudWxsKSB7Ci0gICAgICBzY2hlbWVzcGVjLmFwcGVuZCgobV9wYXRoKSk7Ci0gICAgfQotCi0gICAgaWYgKG1fcXVlcnlTdHJpbmcgIT0gbnVsbCkgewotICAgICAgc2NoZW1lc3BlYy5hcHBlbmQoJz8nKTsKLSAgICAgIHNjaGVtZXNwZWMuYXBwZW5kKG1fcXVlcnlTdHJpbmcpOwotICAgIH0KLQotICAgIGlmIChtX2ZyYWdtZW50ICE9IG51bGwpIHsKLSAgICAgIHNjaGVtZXNwZWMuYXBwZW5kKCcjJyk7Ci0gICAgICBzY2hlbWVzcGVjLmFwcGVuZChtX2ZyYWdtZW50KTsKLSAgICB9Ci0KLSAgICByZXR1cm4gc2NoZW1lc3BlYy50b1N0cmluZygpOwotICB9Ci0KLSAvKioKLSAgKiBHZXQgdGhlIHVzZXJpbmZvIGZvciB0aGlzIFVSSS4KLSAgKgotICAqIEByZXR1cm4gdGhlIHVzZXJpbmZvIGZvciB0aGlzIFVSSSAobnVsbCBpZiBub3Qgc3BlY2lmaWVkKS4KLSAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRVc2VyaW5mbygpIHsKLSAgICByZXR1cm4gbV91c2VyaW5mbzsKLSAgfQotCi0gIC8qKgotICAqIEdldCB0aGUgaG9zdCBmb3IgdGhpcyBVUkkuCi0gICoKLSAgKiBAcmV0dXJuIHRoZSBob3N0IGZvciB0aGlzIFVSSSAobnVsbCBpZiBub3Qgc3BlY2lmaWVkKS4KLSAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRIb3N0KCkgewotICAgIHJldHVybiBtX2hvc3Q7Ci0gIH0KLQotIC8qKgotICAqIEdldCB0aGUgcG9ydCBmb3IgdGhpcyBVUkkuCi0gICoKLSAgKiBAcmV0dXJuIHRoZSBwb3J0IGZvciB0aGlzIFVSSSAoLTEgaWYgbm90IHNwZWNpZmllZCkuCi0gICovCi0gIHB1YmxpYyBpbnQgZ2V0UG9ydCgpIHsKLSAgICByZXR1cm4gbV9wb3J0OwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgcmVnaXN0cnkgYmFzZWQgYXV0aG9yaXR5IGZvciB0aGlzIFVSSS4KLSAgICoKLSAgICogQHJldHVybiB0aGUgcmVnaXN0cnkgYmFzZWQgYXV0aG9yaXR5IChudWxsIGlmIG5vdCBzcGVjaWZpZWQpLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRSZWdCYXNlZEF1dGhvcml0eSgpIHsKLSAgICByZXR1cm4gbV9yZWdBdXRob3JpdHk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBhdXRob3JpdHkgZm9yIHRoaXMgVVJJLgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBhdXRob3JpdHkKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0QXV0aG9yaXR5KCkgewotICAgICAgZmluYWwgU3RyaW5nQnVpbGRlciBhdXRob3JpdHkgPSBuZXcgU3RyaW5nQnVpbGRlcigpOwotICAgICAgaWYgKG1faG9zdCAhPSBudWxsIHx8IG1fcmVnQXV0aG9yaXR5ICE9IG51bGwpIHsKLSAgICAgICAgICBhdXRob3JpdHkuYXBwZW5kKCIvLyIpOwotCi0gICAgICAgICAgLy8gU2VydmVyIGJhc2VkIGF1dGhvcml0eS4KLSAgICAgICAgICBpZiAobV9ob3N0ICE9IG51bGwpIHsKLQotICAgICAgICAgICAgICBpZiAobV91c2VyaW5mbyAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICBhdXRob3JpdHkuYXBwZW5kKG1fdXNlcmluZm8pOwotICAgICAgICAgICAgICAgICAgYXV0aG9yaXR5LmFwcGVuZCgnQCcpOwotICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgYXV0aG9yaXR5LmFwcGVuZChtX2hvc3QpOwotCi0gICAgICAgICAgICAgIGlmIChtX3BvcnQgIT0gLTEpIHsKLSAgICAgICAgICAgICAgICAgIGF1dGhvcml0eS5hcHBlbmQoJzonKTsKLSAgICAgICAgICAgICAgICAgIGF1dGhvcml0eS5hcHBlbmQobV9wb3J0KTsKLSAgICAgICAgICAgICAgfQotICAgICAgICAgIH0KLSAgICAgICAgICAvLyBSZWdpc3RyeSBiYXNlZCBhdXRob3JpdHkuCi0gICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgIGF1dGhvcml0eS5hcHBlbmQobV9yZWdBdXRob3JpdHkpOwotICAgICAgICAgIH0KLSAgICAgIH0KLSAgICAgIHJldHVybiBhdXRob3JpdHkudG9TdHJpbmcoKTsKLSAgfQotCi0gLyoqCi0gICogR2V0IHRoZSBwYXRoIGZvciB0aGlzIFVSSSAob3B0aW9uYWxseSB3aXRoIHRoZSBxdWVyeSBzdHJpbmcgYW5kCi0gICogZnJhZ21lbnQpLgotICAqCi0gICogQHBhcmFtIHBfaW5jbHVkZVF1ZXJ5U3RyaW5nIGlmIHRydWUgKGFuZCBxdWVyeSBzdHJpbmcgaXMgbm90IG51bGwpLAotICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGEgIj8iIGZvbGxvd2VkIGJ5IHRoZSBxdWVyeSBzdHJpbmcKLSAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lsbCBiZSBhcHBlbmRlZAotICAqIEBwYXJhbSBwX2luY2x1ZGVGcmFnbWVudCBpZiB0cnVlIChhbmQgZnJhZ21lbnQgaXMgbm90IG51bGwpLAotICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGEgIiMiIGZvbGxvd2VkIGJ5IHRoZSBmcmFnbWVudAotICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWxsIGJlIGFwcGVuZGVkCi0gICoKLSAgKiBAcmV0dXJuIHRoZSBwYXRoIGZvciB0aGlzIFVSSSBwb3NzaWJseSBpbmNsdWRpbmcgdGhlIHF1ZXJ5IHN0cmluZwotICAqICAgICAgICAgYW5kIGZyYWdtZW50Ci0gICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0UGF0aChib29sZWFuIHBfaW5jbHVkZVF1ZXJ5U3RyaW5nLAotICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBwX2luY2x1ZGVGcmFnbWVudCkgewotICAgIGZpbmFsIFN0cmluZ0J1aWxkZXIgcGF0aFN0cmluZyA9IG5ldyBTdHJpbmdCdWlsZGVyKG1fcGF0aCk7Ci0KLSAgICBpZiAocF9pbmNsdWRlUXVlcnlTdHJpbmcgJiYgbV9xdWVyeVN0cmluZyAhPSBudWxsKSB7Ci0gICAgICBwYXRoU3RyaW5nLmFwcGVuZCgnPycpOwotICAgICAgcGF0aFN0cmluZy5hcHBlbmQobV9xdWVyeVN0cmluZyk7Ci0gICAgfQotCi0gICAgaWYgKHBfaW5jbHVkZUZyYWdtZW50ICYmIG1fZnJhZ21lbnQgIT0gbnVsbCkgewotICAgICAgcGF0aFN0cmluZy5hcHBlbmQoJyMnKTsKLSAgICAgIHBhdGhTdHJpbmcuYXBwZW5kKG1fZnJhZ21lbnQpOwotICAgIH0KLSAgICByZXR1cm4gcGF0aFN0cmluZy50b1N0cmluZygpOwotICB9Ci0KLSAvKioKLSAgKiBHZXQgdGhlIHBhdGggZm9yIHRoaXMgVVJJLiBOb3RlIHRoYXQgdGhlIHZhbHVlIHJldHVybmVkIGlzIHRoZSBwYXRoCi0gICogb25seSBhbmQgZG9lcyBub3QgaW5jbHVkZSB0aGUgcXVlcnkgc3RyaW5nIG9yIGZyYWdtZW50LgotICAqCi0gICogQHJldHVybiB0aGUgcGF0aCBmb3IgdGhpcyBVUkkuCi0gICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0UGF0aCgpIHsKLSAgICByZXR1cm4gbV9wYXRoOwotICB9Ci0KLSAvKioKLSAgKiBHZXQgdGhlIHF1ZXJ5IHN0cmluZyBmb3IgdGhpcyBVUkkuCi0gICoKLSAgKiBAcmV0dXJuIHRoZSBxdWVyeSBzdHJpbmcgZm9yIHRoaXMgVVJJLiBOdWxsIGlzIHJldHVybmVkIGlmIHRoZXJlCi0gICogICAgICAgICB3YXMgbm8gIj8iIGluIHRoZSBVUkkgc3BlYywgZW1wdHkgc3RyaW5nIGlmIHRoZXJlIHdhcyBhCi0gICogICAgICAgICAiPyIgYnV0IG5vIHF1ZXJ5IHN0cmluZyBmb2xsb3dpbmcgaXQuCi0gICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0UXVlcnlTdHJpbmcoKSB7Ci0gICAgcmV0dXJuIG1fcXVlcnlTdHJpbmc7Ci0gIH0KLQotIC8qKgotICAqIEdldCB0aGUgZnJhZ21lbnQgZm9yIHRoaXMgVVJJLgotICAqCi0gICogQHJldHVybiB0aGUgZnJhZ21lbnQgZm9yIHRoaXMgVVJJLiBOdWxsIGlzIHJldHVybmVkIGlmIHRoZXJlCi0gICogICAgICAgICB3YXMgbm8gIiMiIGluIHRoZSBVUkkgc3BlYywgZW1wdHkgc3RyaW5nIGlmIHRoZXJlIHdhcyBhCi0gICogICAgICAgICAiIyIgYnV0IG5vIGZyYWdtZW50IGZvbGxvd2luZyBpdC4KLSAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRGcmFnbWVudCgpIHsKLSAgICByZXR1cm4gbV9mcmFnbWVudDsKLSAgfQotCi0gLyoqCi0gICogU2V0IHRoZSBzY2hlbWUgZm9yIHRoaXMgVVJJLiBUaGUgc2NoZW1lIGlzIGNvbnZlcnRlZCB0byBsb3dlcmNhc2UKLSAgKiBiZWZvcmUgaXQgaXMgc2V0LgotICAqCi0gICogQHBhcmFtIHBfc2NoZW1lIHRoZSBzY2hlbWUgZm9yIHRoaXMgVVJJIChjYW5ub3QgYmUgbnVsbCkKLSAgKgotICAqIEBleGNlcHRpb24gTWFsZm9ybWVkVVJJRXhjZXB0aW9uIGlmIHBfc2NoZW1lIGlzIG5vdCBhIGNvbmZvcm1hbnQKLSAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2hlbWUgbmFtZQotICAqLwotICBwdWJsaWMgdm9pZCBzZXRTY2hlbWUoU3RyaW5nIHBfc2NoZW1lKSB0aHJvd3MgTWFsZm9ybWVkVVJJRXhjZXB0aW9uIHsKLSAgICBpZiAocF9zY2hlbWUgPT0gbnVsbCkgewotICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVSSUV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAiQ2Fubm90IHNldCBzY2hlbWUgZnJvbSBudWxsIHN0cmluZyEiKTsKLSAgICB9Ci0gICAgaWYgKCFpc0NvbmZvcm1hbnRTY2hlbWVOYW1lKHBfc2NoZW1lKSkgewotICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVSSUV4Y2VwdGlvbigiVGhlIHNjaGVtZSBpcyBub3QgY29uZm9ybWFudC4iKTsKLSAgICB9Ci0KLSAgICBtX3NjaGVtZSA9IHBfc2NoZW1lLnRvTG93ZXJDYXNlKCk7Ci0gIH0KLQotIC8qKgotICAqIFNldCB0aGUgdXNlcmluZm8gZm9yIHRoaXMgVVJJLiBJZiBhIG5vbi1udWxsIHZhbHVlIGlzIHBhc3NlZCBpbiBhbmQKLSAgKiB0aGUgaG9zdCB2YWx1ZSBpcyBudWxsLCB0aGVuIGFuIGV4Y2VwdGlvbiBpcyB0aHJvd24uCi0gICoKLSAgKiBAcGFyYW0gcF91c2VyaW5mbyB0aGUgdXNlcmluZm8gZm9yIHRoaXMgVVJJCi0gICoKLSAgKiBAZXhjZXB0aW9uIE1hbGZvcm1lZFVSSUV4Y2VwdGlvbiBpZiBwX3VzZXJpbmZvIGNvbnRhaW5zIGludmFsaWQKLSAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFyYWN0ZXJzCi0gICovCi0gIHB1YmxpYyB2b2lkIHNldFVzZXJpbmZvKFN0cmluZyBwX3VzZXJpbmZvKSB0aHJvd3MgTWFsZm9ybWVkVVJJRXhjZXB0aW9uIHsKLSAgICBpZiAocF91c2VyaW5mbyA9PSBudWxsKSB7Ci0gICAgICBtX3VzZXJpbmZvID0gbnVsbDsKLSAgICAgIHJldHVybjsKLSAgICB9Ci0gICAgZWxzZSB7Ci0gICAgICBpZiAobV9ob3N0ID09IG51bGwpIHsKLSAgICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVSSUV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgICJVc2VyaW5mbyBjYW5ub3QgYmUgc2V0IHdoZW4gaG9zdCBpcyBudWxsISIpOwotICAgICAgfQotCi0gICAgICAvLyB1c2VyaW5mbyBjYW4gY29udGFpbiBhbHBoYW51bWVyaWNzLCBtYXJrIGNoYXJhY3RlcnMsIGVzY2FwZWQKLSAgICAgIC8vIGFuZCAnOycsJzonLCcmJywnPScsJysnLCckJywnLCcKLSAgICAgIGludCBpbmRleCA9IDA7Ci0gICAgICBpbnQgZW5kID0gcF91c2VyaW5mby5sZW5ndGgoKTsKLSAgICAgIGNoYXIgdGVzdENoYXIgPSAnXDAnOwotICAgICAgd2hpbGUgKGluZGV4IDwgZW5kKSB7Ci0gICAgICAgIHRlc3RDaGFyID0gcF91c2VyaW5mby5jaGFyQXQoaW5kZXgpOwotICAgICAgICBpZiAodGVzdENoYXIgPT0gJyUnKSB7Ci0gICAgICAgICAgaWYgKGluZGV4KzIgPj0gZW5kIHx8Ci0gICAgICAgICAgICAgICFpc0hleChwX3VzZXJpbmZvLmNoYXJBdChpbmRleCsxKSkgfHwKLSAgICAgICAgICAgICAgIWlzSGV4KHBfdXNlcmluZm8uY2hhckF0KGluZGV4KzIpKSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVSSUV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICJVc2VyaW5mbyBjb250YWlucyBpbnZhbGlkIGVzY2FwZSBzZXF1ZW5jZSEiKTsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoIWlzVXNlcmluZm9DaGFyYWN0ZXIodGVzdENoYXIpKSB7Ci0gICAgICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVSSUV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICJVc2VyaW5mbyBjb250YWlucyBpbnZhbGlkIGNoYXJhY3RlcjoiK3Rlc3RDaGFyKTsKLSAgICAgICAgfQotICAgICAgICBpbmRleCsrOwotICAgICAgfQotICAgIH0KLSAgICBtX3VzZXJpbmZvID0gcF91c2VyaW5mbzsKLSAgfQotCi0gLyoqCi0gICogPHA+U2V0IHRoZSBob3N0IGZvciB0aGlzIFVSSS4gSWYgbnVsbCBpcyBwYXNzZWQgaW4sIHRoZSB1c2VyaW5mbwotICAqIGZpZWxkIGlzIGFsc28gc2V0IHRvIG51bGwgYW5kIHRoZSBwb3J0IGlzIHNldCB0byAtMS48L3A+Ci0gICoKLSAgKiA8cD5Ob3RlOiBUaGlzIG1ldGhvZCBvdmVyd3JpdGVzIHJlZ2lzdHJ5IGJhc2VkIGF1dGhvcml0eSBpZiBpdAotICAqIHByZXZpb3VzbHkgZXhpc3RlZCBpbiB0aGlzIFVSSS48L3A+Ci0gICoKLSAgKiBAcGFyYW0gcF9ob3N0IHRoZSBob3N0IGZvciB0aGlzIFVSSQotICAqCi0gICogQGV4Y2VwdGlvbiBNYWxmb3JtZWRVUklFeGNlcHRpb24gaWYgcF9ob3N0IGlzIG5vdCBhIHZhbGlkIElQCi0gICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkcmVzcyBvciBETlMgaG9zdG5hbWUuCi0gICovCi0gIHB1YmxpYyB2b2lkIHNldEhvc3QoU3RyaW5nIHBfaG9zdCkgdGhyb3dzIE1hbGZvcm1lZFVSSUV4Y2VwdGlvbiB7Ci0gICAgaWYgKHBfaG9zdCA9PSBudWxsIHx8IHBfaG9zdC5sZW5ndGgoKSA9PSAwKSB7Ci0gICAgICBpZiAocF9ob3N0ICE9IG51bGwpIHsKLSAgICAgICAgbV9yZWdBdXRob3JpdHkgPSBudWxsOwotICAgICAgfQotICAgICAgbV9ob3N0ID0gcF9ob3N0OwotICAgICAgbV91c2VyaW5mbyA9IG51bGw7Ci0gICAgICBtX3BvcnQgPSAtMTsKLSAgICAgIHJldHVybjsKLSAgICB9Ci0gICAgZWxzZSBpZiAoIWlzV2VsbEZvcm1lZEFkZHJlc3MocF9ob3N0KSkgewotICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVSSUV4Y2VwdGlvbigiSG9zdCBpcyBub3QgYSB3ZWxsIGZvcm1lZCBhZGRyZXNzISIpOwotICAgIH0KLSAgICBtX2hvc3QgPSBwX2hvc3Q7Ci0gICAgbV9yZWdBdXRob3JpdHkgPSBudWxsOwotICB9Ci0KLSAvKioKLSAgKiBTZXQgdGhlIHBvcnQgZm9yIHRoaXMgVVJJLiAtMSBpcyB1c2VkIHRvIGluZGljYXRlIHRoYXQgdGhlIHBvcnQgaXMKLSAgKiBub3Qgc3BlY2lmaWVkLCBvdGhlcndpc2UgdmFsaWQgcG9ydCBudW1iZXJzIGFyZSAgYmV0d2VlbiAwIGFuZCA2NTUzNS4KLSAgKiBJZiBhIHZhbGlkIHBvcnQgbnVtYmVyIGlzIHBhc3NlZCBpbiBhbmQgdGhlIGhvc3QgZmllbGQgaXMgbnVsbCwKLSAgKiBhbiBleGNlcHRpb24gaXMgdGhyb3duLgotICAqCi0gICogQHBhcmFtIHBfcG9ydCB0aGUgcG9ydCBudW1iZXIgZm9yIHRoaXMgVVJJCi0gICoKLSAgKiBAZXhjZXB0aW9uIE1hbGZvcm1lZFVSSUV4Y2VwdGlvbiBpZiBwX3BvcnQgaXMgbm90IC0xIGFuZCBub3QgYQotICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbGlkIHBvcnQgbnVtYmVyCi0gICovCi0gIHB1YmxpYyB2b2lkIHNldFBvcnQoaW50IHBfcG9ydCkgdGhyb3dzIE1hbGZvcm1lZFVSSUV4Y2VwdGlvbiB7Ci0gICAgaWYgKHBfcG9ydCA+PSAwICYmIHBfcG9ydCA8PSA2NTUzNSkgewotICAgICAgaWYgKG1faG9zdCA9PSBudWxsKSB7Ci0gICAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVUklFeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgICAgIlBvcnQgY2Fubm90IGJlIHNldCB3aGVuIGhvc3QgaXMgbnVsbCEiKTsKLSAgICAgIH0KLSAgICB9Ci0gICAgZWxzZSBpZiAocF9wb3J0ICE9IC0xKSB7Ci0gICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVVJJRXhjZXB0aW9uKCJJbnZhbGlkIHBvcnQgbnVtYmVyISIpOwotICAgIH0KLSAgICBtX3BvcnQgPSBwX3BvcnQ7Ci0gIH0KLQotICAvKioKLSAgICogPHA+U2V0cyB0aGUgcmVnaXN0cnkgYmFzZWQgYXV0aG9yaXR5IGZvciB0aGlzIFVSSS48L3A+Ci0gICAqCi0gICAqIDxwPk5vdGU6IFRoaXMgbWV0aG9kIG92ZXJ3cml0ZXMgc2VydmVyIGJhc2VkIGF1dGhvcml0eQotICAgKiBpZiBpdCBwcmV2aW91c2x5IGV4aXN0ZWQgaW4gdGhpcyBVUkkuPC9wPgotICAgKgotICAgKiBAcGFyYW0gYXV0aG9yaXR5IHRoZSByZWdpc3RyeSBiYXNlZCBhdXRob3JpdHkgZm9yIHRoaXMgVVJJCi0gICAqCi0gICAqIEBleGNlcHRpb24gTWFsZm9ybWVkVVJJRXhjZXB0aW9uIGl0IGF1dGhvcml0eSBpcyBub3QgYQotICAgKiB3ZWxsIGZvcm1lZCByZWdpc3RyeSBiYXNlZCBhdXRob3JpdHkKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFJlZ0Jhc2VkQXV0aG9yaXR5KFN0cmluZyBhdXRob3JpdHkpCi0gICAgdGhyb3dzIE1hbGZvcm1lZFVSSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgaWYgKGF1dGhvcml0eSA9PSBudWxsKSB7Ci0gICAgICAgICAgbV9yZWdBdXRob3JpdHkgPSBudWxsOwotICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotICAgICAgICAvLyByZWdfbmFtZSA9IDEqKCB1bnJlc2VydmVkIHwgZXNjYXBlZCB8ICIkIiB8ICIsIiB8Ci0gICAgICAgIC8vICAgICAgICAgICAgIjsiIHwgIjoiIHwgIkAiIHwgIiYiIHwgIj0iIHwgIisiICkKLSAgICAgICAgZWxzZSBpZiAoYXV0aG9yaXR5Lmxlbmd0aCgpIDwgMSB8fAotICAgICAgICAgICFpc1ZhbGlkUmVnaXN0cnlCYXNlZEF1dGhvcml0eShhdXRob3JpdHkpIHx8Ci0gICAgICAgICAgYXV0aG9yaXR5LmluZGV4T2YoJy8nKSAhPSAtMSkgewotICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVSSUV4Y2VwdGlvbigiUmVnaXN0cnkgYmFzZWQgYXV0aG9yaXR5IGlzIG5vdCB3ZWxsIGZvcm1lZC4iKTsKLSAgICAgICAgfQotICAgICAgICBtX3JlZ0F1dGhvcml0eSA9IGF1dGhvcml0eTsKLSAgICAgICAgbV9ob3N0ID0gbnVsbDsKLSAgICAgICAgbV91c2VyaW5mbyA9IG51bGw7Ci0gICAgICAgIG1fcG9ydCA9IC0xOwotICB9Ci0KLSAvKioKLSAgKiBTZXQgdGhlIHBhdGggZm9yIHRoaXMgVVJJLiBJZiB0aGUgc3VwcGxpZWQgcGF0aCBpcyBudWxsLCB0aGVuIHRoZQotICAqIHF1ZXJ5IHN0cmluZyBhbmQgZnJhZ21lbnQgYXJlIHNldCB0byBudWxsIGFzIHdlbGwuIElmIHRoZSBzdXBwbGllZAotICAqIHBhdGggaW5jbHVkZXMgYSBxdWVyeSBzdHJpbmcgYW5kL29yIGZyYWdtZW50LCB0aGVzZSBmaWVsZHMgd2lsbCBiZQotICAqIHBhcnNlZCBhbmQgc2V0IGFzIHdlbGwuIE5vdGUgdGhhdCwgZm9yIFVSSXMgZm9sbG93aW5nIHRoZSAiZ2VuZXJpYwotICAqIFVSSSIgc3ludGF4LCB0aGUgcGF0aCBzcGVjaWZpZWQgc2hvdWxkIHN0YXJ0IHdpdGggYSBzbGFzaC4KLSAgKiBGb3IgVVJJcyB0aGF0IGRvIG5vdCBmb2xsb3cgdGhlIGdlbmVyaWMgVVJJIHN5bnRheCwgdGhpcyBtZXRob2QKLSAgKiBzZXRzIHRoZSBzY2hlbWUtc3BlY2lmaWMgcGFydC4KLSAgKgotICAqIEBwYXJhbSBwX3BhdGggdGhlIHBhdGggZm9yIHRoaXMgVVJJIChtYXkgYmUgbnVsbCkKLSAgKgotICAqIEBleGNlcHRpb24gTWFsZm9ybWVkVVJJRXhjZXB0aW9uIGlmIHBfcGF0aCBjb250YWlucyBpbnZhbGlkCi0gICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhcmFjdGVycwotICAqLwotICBwdWJsaWMgdm9pZCBzZXRQYXRoKFN0cmluZyBwX3BhdGgpIHRocm93cyBNYWxmb3JtZWRVUklFeGNlcHRpb24gewotICAgIGlmIChwX3BhdGggPT0gbnVsbCkgewotICAgICAgbV9wYXRoID0gbnVsbDsKLSAgICAgIG1fcXVlcnlTdHJpbmcgPSBudWxsOwotICAgICAgbV9mcmFnbWVudCA9IG51bGw7Ci0gICAgfQotICAgIGVsc2UgewotICAgICAgaW5pdGlhbGl6ZVBhdGgocF9wYXRoLCAwKTsKLSAgICB9Ci0gIH0KLQotIC8qKgotICAqIEFwcGVuZCB0byB0aGUgZW5kIG9mIHRoZSBwYXRoIG9mIHRoaXMgVVJJLiBJZiB0aGUgY3VycmVudCBwYXRoIGRvZXMKLSAgKiBub3QgZW5kIGluIGEgc2xhc2ggYW5kIHRoZSBwYXRoIHRvIGJlIGFwcGVuZGVkIGRvZXMgbm90IGJlZ2luIHdpdGgKLSAgKiBhIHNsYXNoLCBhIHNsYXNoIHdpbGwgYmUgYXBwZW5kZWQgdG8gdGhlIGN1cnJlbnQgcGF0aCBiZWZvcmUgdGhlCi0gICogbmV3IHNlZ21lbnQgaXMgYWRkZWQuIEFsc28sIGlmIHRoZSBjdXJyZW50IHBhdGggZW5kcyBpbiBhIHNsYXNoCi0gICogYW5kIHRoZSBuZXcgc2VnbWVudCBiZWdpbnMgd2l0aCBhIHNsYXNoLCB0aGUgZXh0cmEgc2xhc2ggd2lsbCBiZQotICAqIHJlbW92ZWQgYmVmb3JlIHRoZSBuZXcgc2VnbWVudCBpcyBhcHBlbmRlZC4KLSAgKgotICAqIEBwYXJhbSBwX2FkZFRvUGF0aCB0aGUgbmV3IHNlZ21lbnQgdG8gYmUgYWRkZWQgdG8gdGhlIGN1cnJlbnQgcGF0aAotICAqCi0gICogQGV4Y2VwdGlvbiBNYWxmb3JtZWRVUklFeGNlcHRpb24gaWYgcF9hZGRUb1BhdGggY29udGFpbnMgc3ludGF4Ci0gICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JzCi0gICovCi0gIHB1YmxpYyB2b2lkIGFwcGVuZFBhdGgoU3RyaW5nIHBfYWRkVG9QYXRoKQotICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBNYWxmb3JtZWRVUklFeGNlcHRpb24gewotICAgIGlmIChwX2FkZFRvUGF0aCA9PSBudWxsIHx8IHBfYWRkVG9QYXRoLnRyaW0oKS5sZW5ndGgoKSA9PSAwKSB7Ci0gICAgICByZXR1cm47Ci0gICAgfQotCi0gICAgaWYgKCFpc1VSSVN0cmluZyhwX2FkZFRvUGF0aCkpIHsKLSAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVUklFeGNlcHRpb24oCi0gICAgICAgICAgICAgICJQYXRoIGNvbnRhaW5zIGludmFsaWQgY2hhcmFjdGVyISIpOwotICAgIH0KLQotICAgIGlmIChtX3BhdGggPT0gbnVsbCB8fCBtX3BhdGgudHJpbSgpLmxlbmd0aCgpID09IDApIHsKLSAgICAgIGlmIChwX2FkZFRvUGF0aC5zdGFydHNXaXRoKCIvIikpIHsKLSAgICAgICAgbV9wYXRoID0gcF9hZGRUb1BhdGg7Ci0gICAgICB9Ci0gICAgICBlbHNlIHsKLSAgICAgICAgbV9wYXRoID0gIi8iICsgcF9hZGRUb1BhdGg7Ci0gICAgICB9Ci0gICAgfQotICAgIGVsc2UgaWYgKG1fcGF0aC5lbmRzV2l0aCgiLyIpKSB7Ci0gICAgICBpZiAocF9hZGRUb1BhdGguc3RhcnRzV2l0aCgiLyIpKSB7Ci0gICAgICAgIG1fcGF0aCA9IG1fcGF0aC5jb25jYXQocF9hZGRUb1BhdGguc3Vic3RyaW5nKDEpKTsKLSAgICAgIH0KLSAgICAgIGVsc2UgewotICAgICAgICBtX3BhdGggPSBtX3BhdGguY29uY2F0KHBfYWRkVG9QYXRoKTsKLSAgICAgIH0KLSAgICB9Ci0gICAgZWxzZSB7Ci0gICAgICBpZiAocF9hZGRUb1BhdGguc3RhcnRzV2l0aCgiLyIpKSB7Ci0gICAgICAgIG1fcGF0aCA9IG1fcGF0aC5jb25jYXQocF9hZGRUb1BhdGgpOwotICAgICAgfQotICAgICAgZWxzZSB7Ci0gICAgICAgIG1fcGF0aCA9IG1fcGF0aC5jb25jYXQoIi8iICsgcF9hZGRUb1BhdGgpOwotICAgICAgfQotICAgIH0KLSAgfQotCi0gLyoqCi0gICogU2V0IHRoZSBxdWVyeSBzdHJpbmcgZm9yIHRoaXMgVVJJLiBBIG5vbi1udWxsIHZhbHVlIGlzIHZhbGlkIG9ubHkKLSAgKiBpZiB0aGlzIGlzIGFuIFVSSSBjb25mb3JtaW5nIHRvIHRoZSBnZW5lcmljIFVSSSBzeW50YXggYW5kCi0gICogdGhlIHBhdGggdmFsdWUgaXMgbm90IG51bGwuCi0gICoKLSAgKiBAcGFyYW0gcF9xdWVyeVN0cmluZyB0aGUgcXVlcnkgc3RyaW5nIGZvciB0aGlzIFVSSQotICAqCi0gICogQGV4Y2VwdGlvbiBNYWxmb3JtZWRVUklFeGNlcHRpb24gaWYgcF9xdWVyeVN0cmluZyBpcyBub3QgbnVsbCBhbmQgdGhpcwotICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVSSSBkb2VzIG5vdCBjb25mb3JtIHRvIHRoZSBnZW5lcmljCi0gICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVVJJIHN5bnRheCBvciBpZiB0aGUgcGF0aCBpcyBudWxsCi0gICovCi0gIHB1YmxpYyB2b2lkIHNldFF1ZXJ5U3RyaW5nKFN0cmluZyBwX3F1ZXJ5U3RyaW5nKSB0aHJvd3MgTWFsZm9ybWVkVVJJRXhjZXB0aW9uIHsKLSAgICBpZiAocF9xdWVyeVN0cmluZyA9PSBudWxsKSB7Ci0gICAgICBtX3F1ZXJ5U3RyaW5nID0gbnVsbDsKLSAgICB9Ci0gICAgZWxzZSBpZiAoIWlzR2VuZXJpY1VSSSgpKSB7Ci0gICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVVJJRXhjZXB0aW9uKAotICAgICAgICAgICAgICAiUXVlcnkgc3RyaW5nIGNhbiBvbmx5IGJlIHNldCBmb3IgYSBnZW5lcmljIFVSSSEiKTsKLSAgICB9Ci0gICAgZWxzZSBpZiAoZ2V0UGF0aCgpID09IG51bGwpIHsKLSAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVUklFeGNlcHRpb24oCi0gICAgICAgICAgICAgICJRdWVyeSBzdHJpbmcgY2Fubm90IGJlIHNldCB3aGVuIHBhdGggaXMgbnVsbCEiKTsKLSAgICB9Ci0gICAgZWxzZSBpZiAoIWlzVVJJU3RyaW5nKHBfcXVlcnlTdHJpbmcpKSB7Ci0gICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVVJJRXhjZXB0aW9uKAotICAgICAgICAgICAgICAiUXVlcnkgc3RyaW5nIGNvbnRhaW5zIGludmFsaWQgY2hhcmFjdGVyISIpOwotICAgIH0KLSAgICBlbHNlIHsKLSAgICAgIG1fcXVlcnlTdHJpbmcgPSBwX3F1ZXJ5U3RyaW5nOwotICAgIH0KLSAgfQotCi0gLyoqCi0gICogU2V0IHRoZSBmcmFnbWVudCBmb3IgdGhpcyBVUkkuIEEgbm9uLW51bGwgdmFsdWUgaXMgdmFsaWQgb25seQotICAqIGlmIHRoaXMgaXMgYSBVUkkgY29uZm9ybWluZyB0byB0aGUgZ2VuZXJpYyBVUkkgc3ludGF4IGFuZAotICAqIHRoZSBwYXRoIHZhbHVlIGlzIG5vdCBudWxsLgotICAqCi0gICogQHBhcmFtIHBfZnJhZ21lbnQgdGhlIGZyYWdtZW50IGZvciB0aGlzIFVSSQotICAqCi0gICogQGV4Y2VwdGlvbiBNYWxmb3JtZWRVUklFeGNlcHRpb24gaWYgcF9mcmFnbWVudCBpcyBub3QgbnVsbCBhbmQgdGhpcwotICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVSSSBkb2VzIG5vdCBjb25mb3JtIHRvIHRoZSBnZW5lcmljCi0gICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVVJJIHN5bnRheCBvciBpZiB0aGUgcGF0aCBpcyBudWxsCi0gICovCi0gIHB1YmxpYyB2b2lkIHNldEZyYWdtZW50KFN0cmluZyBwX2ZyYWdtZW50KSB0aHJvd3MgTWFsZm9ybWVkVVJJRXhjZXB0aW9uIHsKLSAgICBpZiAocF9mcmFnbWVudCA9PSBudWxsKSB7Ci0gICAgICBtX2ZyYWdtZW50ID0gbnVsbDsKLSAgICB9Ci0gICAgZWxzZSBpZiAoIWlzR2VuZXJpY1VSSSgpKSB7Ci0gICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVVJJRXhjZXB0aW9uKAotICAgICAgICAgIkZyYWdtZW50IGNhbiBvbmx5IGJlIHNldCBmb3IgYSBnZW5lcmljIFVSSSEiKTsKLSAgICB9Ci0gICAgZWxzZSBpZiAoZ2V0UGF0aCgpID09IG51bGwpIHsKLSAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVUklFeGNlcHRpb24oCi0gICAgICAgICAgICAgICJGcmFnbWVudCBjYW5ub3QgYmUgc2V0IHdoZW4gcGF0aCBpcyBudWxsISIpOwotICAgIH0KLSAgICBlbHNlIGlmICghaXNVUklTdHJpbmcocF9mcmFnbWVudCkpIHsKLSAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVUklFeGNlcHRpb24oCi0gICAgICAgICAgICAgICJGcmFnbWVudCBjb250YWlucyBpbnZhbGlkIGNoYXJhY3RlciEiKTsKLSAgICB9Ci0gICAgZWxzZSB7Ci0gICAgICBtX2ZyYWdtZW50ID0gcF9mcmFnbWVudDsKLSAgICB9Ci0gIH0KLQotIC8qKgotICAqIERldGVybWluZXMgaWYgdGhlIHBhc3NlZC1pbiBPYmplY3QgaXMgZXF1aXZhbGVudCB0byB0aGlzIFVSSS4KLSAgKgotICAqIEBwYXJhbSBwX3Rlc3QgdGhlIE9iamVjdCB0byB0ZXN0IGZvciBlcXVhbGl0eS4KLSAgKgotICAqIEByZXR1cm4gdHJ1ZSBpZiBwX3Rlc3QgaXMgYSBVUkkgd2l0aCBhbGwgdmFsdWVzIGVxdWFsIHRvIHRoaXMKLSAgKiAgICAgICAgIFVSSSwgZmFsc2Ugb3RoZXJ3aXNlCi0gICovCi0gIEBPdmVycmlkZQotICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IHBfdGVzdCkgewotICAgIGlmIChwX3Rlc3QgaW5zdGFuY2VvZiBVUkkpIHsKLSAgICAgIFVSSSB0ZXN0VVJJID0gKFVSSSkgcF90ZXN0OwotICAgICAgaWYgKCgobV9zY2hlbWUgPT0gbnVsbCAmJiB0ZXN0VVJJLm1fc2NoZW1lID09IG51bGwpIHx8Ci0gICAgICAgICAgIChtX3NjaGVtZSAhPSBudWxsICYmIHRlc3RVUkkubV9zY2hlbWUgIT0gbnVsbCAmJgotICAgICAgICAgICAgbV9zY2hlbWUuZXF1YWxzKHRlc3RVUkkubV9zY2hlbWUpKSkgJiYKLSAgICAgICAgICAoKG1fdXNlcmluZm8gPT0gbnVsbCAmJiB0ZXN0VVJJLm1fdXNlcmluZm8gPT0gbnVsbCkgfHwKLSAgICAgICAgICAgKG1fdXNlcmluZm8gIT0gbnVsbCAmJiB0ZXN0VVJJLm1fdXNlcmluZm8gIT0gbnVsbCAmJgotICAgICAgICAgICAgbV91c2VyaW5mby5lcXVhbHModGVzdFVSSS5tX3VzZXJpbmZvKSkpICYmCi0gICAgICAgICAgKChtX2hvc3QgPT0gbnVsbCAmJiB0ZXN0VVJJLm1faG9zdCA9PSBudWxsKSB8fAotICAgICAgICAgICAobV9ob3N0ICE9IG51bGwgJiYgdGVzdFVSSS5tX2hvc3QgIT0gbnVsbCAmJgotICAgICAgICAgICAgbV9ob3N0LmVxdWFscyh0ZXN0VVJJLm1faG9zdCkpKSAmJgotICAgICAgICAgICAgbV9wb3J0ID09IHRlc3RVUkkubV9wb3J0ICYmCi0gICAgICAgICAgKChtX3BhdGggPT0gbnVsbCAmJiB0ZXN0VVJJLm1fcGF0aCA9PSBudWxsKSB8fAotICAgICAgICAgICAobV9wYXRoICE9IG51bGwgJiYgdGVzdFVSSS5tX3BhdGggIT0gbnVsbCAmJgotICAgICAgICAgICAgbV9wYXRoLmVxdWFscyh0ZXN0VVJJLm1fcGF0aCkpKSAmJgotICAgICAgICAgICgobV9xdWVyeVN0cmluZyA9PSBudWxsICYmIHRlc3RVUkkubV9xdWVyeVN0cmluZyA9PSBudWxsKSB8fAotICAgICAgICAgICAobV9xdWVyeVN0cmluZyAhPSBudWxsICYmIHRlc3RVUkkubV9xdWVyeVN0cmluZyAhPSBudWxsICYmCi0gICAgICAgICAgICBtX3F1ZXJ5U3RyaW5nLmVxdWFscyh0ZXN0VVJJLm1fcXVlcnlTdHJpbmcpKSkgJiYKLSAgICAgICAgICAoKG1fZnJhZ21lbnQgPT0gbnVsbCAmJiB0ZXN0VVJJLm1fZnJhZ21lbnQgPT0gbnVsbCkgfHwKLSAgICAgICAgICAgKG1fZnJhZ21lbnQgIT0gbnVsbCAmJiB0ZXN0VVJJLm1fZnJhZ21lbnQgIT0gbnVsbCAmJgotICAgICAgICAgICAgbV9mcmFnbWVudC5lcXVhbHModGVzdFVSSS5tX2ZyYWdtZW50KSkpKSB7Ci0gICAgICAgIHJldHVybiB0cnVlOwotICAgICAgfQotICAgIH0KLSAgICByZXR1cm4gZmFsc2U7Ci0gIH0KLQotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7Ci0gICAgICAgIGludCBoYXNoID0gNTsKLSAgICAgICAgaGFzaCA9IDQ3ICogaGFzaCArIE9iamVjdHMuaGFzaENvZGUodGhpcy5tX3NjaGVtZSk7Ci0gICAgICAgIGhhc2ggPSA0NyAqIGhhc2ggKyBPYmplY3RzLmhhc2hDb2RlKHRoaXMubV91c2VyaW5mbyk7Ci0gICAgICAgIGhhc2ggPSA0NyAqIGhhc2ggKyBPYmplY3RzLmhhc2hDb2RlKHRoaXMubV9ob3N0KTsKLSAgICAgICAgaGFzaCA9IDQ3ICogaGFzaCArIHRoaXMubV9wb3J0OwotICAgICAgICBoYXNoID0gNDcgKiBoYXNoICsgT2JqZWN0cy5oYXNoQ29kZSh0aGlzLm1fcGF0aCk7Ci0gICAgICAgIGhhc2ggPSA0NyAqIGhhc2ggKyBPYmplY3RzLmhhc2hDb2RlKHRoaXMubV9xdWVyeVN0cmluZyk7Ci0gICAgICAgIGhhc2ggPSA0NyAqIGhhc2ggKyBPYmplY3RzLmhhc2hDb2RlKHRoaXMubV9mcmFnbWVudCk7Ci0gICAgICAgIHJldHVybiBoYXNoOwotICAgIH0KLQotIC8qKgotICAqIEdldCB0aGUgVVJJIGFzIGEgc3RyaW5nIHNwZWNpZmljYXRpb24uIFNlZSBSRkMgMjM5NiBTZWN0aW9uIDUuMi4KLSAgKgotICAqIEByZXR1cm4gdGhlIFVSSSBzdHJpbmcgc3BlY2lmaWNhdGlvbgotICAqLwotICBAT3ZlcnJpZGUKLSAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKLSAgICBmaW5hbCBTdHJpbmdCdWlsZGVyIHVyaVNwZWNTdHJpbmcgPSBuZXcgU3RyaW5nQnVpbGRlcigpOwotCi0gICAgaWYgKG1fc2NoZW1lICE9IG51bGwpIHsKLSAgICAgIHVyaVNwZWNTdHJpbmcuYXBwZW5kKG1fc2NoZW1lKTsKLSAgICAgIHVyaVNwZWNTdHJpbmcuYXBwZW5kKCc6Jyk7Ci0gICAgfQotICAgIHVyaVNwZWNTdHJpbmcuYXBwZW5kKGdldFNjaGVtZVNwZWNpZmljUGFydCgpKTsKLSAgICByZXR1cm4gdXJpU3BlY1N0cmluZy50b1N0cmluZygpOwotICB9Ci0KLSAvKioKLSAgKiBHZXQgdGhlIGluZGljYXRvciBhcyB0byB3aGV0aGVyIHRoaXMgVVJJIHVzZXMgdGhlICJnZW5lcmljIFVSSSIKLSAgKiBzeW50YXguCi0gICoKLSAgKiBAcmV0dXJuIHRydWUgaWYgdGhpcyBVUkkgdXNlcyB0aGUgImdlbmVyaWMgVVJJIiBzeW50YXgsIGZhbHNlCi0gICogICAgICAgICBvdGhlcndpc2UKLSAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNHZW5lcmljVVJJKCkgewotICAgIC8vIHByZXNlbmNlIG9mIHRoZSBob3N0ICh3aGV0aGVyIHZhbGlkIG9yIGVtcHR5KSBtZWFucwotICAgIC8vIGRvdWJsZS1zbGFzaGVzIHdoaWNoIG1lYW5zIGdlbmVyaWMgdXJpCi0gICAgcmV0dXJuIChtX2hvc3QgIT0gbnVsbCk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyB3aGV0aGVyIHRoaXMgVVJJIHJlcHJlc2VudHMgYW4gYWJzb2x1dGUgVVJJLgotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhpcyBVUkkgcmVwcmVzZW50cyBhbiBhYnNvbHV0ZSBVUkksIGZhbHNlCi0gICAqICAgICAgICAgb3RoZXJ3aXNlCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBpc0Fic29sdXRlVVJJKCkgewotICAgICAgLy8gcHJlc2VuY2Ugb2YgdGhlIHNjaGVtZSBtZWFucyBhYnNvbHV0ZSB1cmkKLSAgICAgIHJldHVybiAobV9zY2hlbWUgIT0gbnVsbCk7Ci0gIH0KLQotIC8qKgotICAqIERldGVybWluZSB3aGV0aGVyIGEgc2NoZW1lIGNvbmZvcm1zIHRvIHRoZSBydWxlcyBmb3IgYSBzY2hlbWUgbmFtZS4KLSAgKiBBIHNjaGVtZSBpcyBjb25mb3JtYW50IGlmIGl0IHN0YXJ0cyB3aXRoIGFuIGFscGhhbnVtZXJpYywgYW5kCi0gICogY29udGFpbnMgb25seSBhbHBoYW51bWVyaWNzLCAnKycsJy0nIGFuZCAnLicuCi0gICoKLSAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHNjaGVtZSBpcyBjb25mb3JtYW50LCBmYWxzZSBvdGhlcndpc2UKLSAgKi8KLSAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzQ29uZm9ybWFudFNjaGVtZU5hbWUoU3RyaW5nIHBfc2NoZW1lKSB7Ci0gICAgaWYgKHBfc2NoZW1lID09IG51bGwgfHwgcF9zY2hlbWUudHJpbSgpLmxlbmd0aCgpID09IDApIHsKLSAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICBpZiAoIWlzQWxwaGEocF9zY2hlbWUuY2hhckF0KDApKSkgewotICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIGNoYXIgdGVzdENoYXI7Ci0gICAgaW50IHNjaGVtZUxlbmd0aCA9IHBfc2NoZW1lLmxlbmd0aCgpOwotICAgIGZvciAoaW50IGkgPSAxOyBpIDwgc2NoZW1lTGVuZ3RoOyArK2kpIHsKLSAgICAgIHRlc3RDaGFyID0gcF9zY2hlbWUuY2hhckF0KGkpOwotICAgICAgaWYgKCFpc1NjaGVtZUNoYXJhY3Rlcih0ZXN0Q2hhcikpIHsKLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiB0cnVlOwotICB9Ci0KLSAvKioKLSAgKiBEZXRlcm1pbmUgd2hldGhlciBhIHN0cmluZyBpcyBzeW50YWN0aWNhbGx5IGNhcGFibGUgb2YgcmVwcmVzZW50aW5nCi0gICogYSB2YWxpZCBJUHY0IGFkZHJlc3MsIElQdjYgcmVmZXJlbmNlIG9yIHRoZSBkb21haW4gbmFtZSBvZiBhIG5ldHdvcmsgaG9zdC4KLSAgKiBBIHZhbGlkIElQdjQgYWRkcmVzcyBjb25zaXN0cyBvZiBmb3VyIGRlY2ltYWwgZGlnaXQgZ3JvdXBzIHNlcGFyYXRlZCBieSBhCi0gICogJy4nLiBFYWNoIGdyb3VwIG11c3QgY29uc2lzdCBvZiBvbmUgdG8gdGhyZWUgZGlnaXRzLiBTZWUgUkZDIDI3MzIgU2VjdGlvbiAzLAotICAqIGFuZCBSRkMgMjM3MyBTZWN0aW9uIDIuMiwgZm9yIHRoZSBkZWZpbml0aW9uIG9mIElQdjYgcmVmZXJlbmNlcy4gQSBob3N0bmFtZQotICAqIGNvbnNpc3RzIG9mIGRvbWFpbiBsYWJlbHMgKGVhY2ggb2Ygd2hpY2ggbXVzdCBiZWdpbiBhbmQgZW5kIHdpdGggYW4gYWxwaGFudW1lcmljCi0gICogYnV0IG1heSBjb250YWluICctJykgc2VwYXJhdGVkICYgYnkgYSAnLicuIFNlZSBSRkMgMjM5NiBTZWN0aW9uIDMuMi4yLgotICAqCi0gICogQHJldHVybiB0cnVlIGlmIHRoZSBzdHJpbmcgaXMgYSBzeW50YWN0aWNhbGx5IHZhbGlkIElQdjQgYWRkcmVzcywKLSAgKiBJUHY2IHJlZmVyZW5jZSBvciBob3N0bmFtZQotICAqLwotICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNXZWxsRm9ybWVkQWRkcmVzcyhTdHJpbmcgYWRkcmVzcykgewotICAgIGlmIChhZGRyZXNzID09IG51bGwpIHsKLSAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICBpbnQgYWRkckxlbmd0aCA9IGFkZHJlc3MubGVuZ3RoKCk7Ci0gICAgaWYgKGFkZHJMZW5ndGggPT0gMCkgewotICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIC8vIENoZWNrIGlmIHRoZSBob3N0IGlzIGEgdmFsaWQgSVB2NnJlZmVyZW5jZS4KLSAgICBpZiAoYWRkcmVzcy5zdGFydHNXaXRoKCJbIikpIHsKLSAgICAgIHJldHVybiBpc1dlbGxGb3JtZWRJUHY2UmVmZXJlbmNlKGFkZHJlc3MpOwotICAgIH0KLQotICAgIC8vIENhbm5vdCBzdGFydCB3aXRoIGEgJy4nLCAnLScsIG9yIGVuZCB3aXRoIGEgJy0nLgotICAgIGlmIChhZGRyZXNzLnN0YXJ0c1dpdGgoIi4iKSB8fAotICAgICAgICBhZGRyZXNzLnN0YXJ0c1dpdGgoIi0iKSB8fAotICAgICAgICBhZGRyZXNzLmVuZHNXaXRoKCItIikpIHsKLSAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICAvLyByaWdodG1vc3QgZG9tYWluIGxhYmVsIHN0YXJ0aW5nIHdpdGggZGlnaXQgaW5kaWNhdGVzIElQIGFkZHJlc3MKLSAgICAvLyBzaW5jZSB0b3AgbGV2ZWwgZG9tYWluIGxhYmVsIGNhbiBvbmx5IHN0YXJ0IHdpdGggYW4gYWxwaGEKLSAgICAvLyBzZWUgUkZDIDIzOTYgU2VjdGlvbiAzLjIuMgotICAgIGludCBpbmRleCA9IGFkZHJlc3MubGFzdEluZGV4T2YoJy4nKTsKLSAgICBpZiAoYWRkcmVzcy5lbmRzV2l0aCgiLiIpKSB7Ci0gICAgICBpbmRleCA9IGFkZHJlc3Muc3Vic3RyaW5nKDAsIGluZGV4KS5sYXN0SW5kZXhPZignLicpOwotICAgIH0KLQotICAgIGlmIChpbmRleCsxIDwgYWRkckxlbmd0aCAmJiBpc0RpZ2l0KGFkZHJlc3MuY2hhckF0KGluZGV4KzEpKSkgewotICAgICAgcmV0dXJuIGlzV2VsbEZvcm1lZElQdjRBZGRyZXNzKGFkZHJlc3MpOwotICAgIH0KLSAgICBlbHNlIHsKLSAgICAgIC8vIGhvc3RuYW1lICAgICAgPSAqKCBkb21haW5sYWJlbCAiLiIgKSB0b3BsYWJlbCBbICIuIiBdCi0gICAgICAvLyBkb21haW5sYWJlbCAgID0gYWxwaGFudW0gfCBhbHBoYW51bSAqKCBhbHBoYW51bSB8ICItIiApIGFscGhhbnVtCi0gICAgICAvLyB0b3BsYWJlbCAgICAgID0gYWxwaGEgfCBhbHBoYSAqKCBhbHBoYW51bSB8ICItIiApIGFscGhhbnVtCi0KLSAgICAgIC8vIFJGQyAyMzk2IHN0YXRlcyB0aGF0IGhvc3RuYW1lcyB0YWtlIHRoZSBmb3JtIGRlc2NyaWJlZCBpbgotICAgICAgLy8gUkZDIDEwMzQgKFNlY3Rpb24gMykgYW5kIFJGQyAxMTIzIChTZWN0aW9uIDIuMSkuIEFjY29yZGluZwotICAgICAgLy8gdG8gUkZDIDEwMzQsIGhvc3RuYW1lcyBhcmUgbGltaXRlZCB0byAyNTUgY2hhcmFjdGVycy4KLSAgICAgIGlmIChhZGRyTGVuZ3RoID4gMjU1KSB7Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgIH0KLQotICAgICAgLy8gZG9tYWluIGxhYmVscyBjYW4gY29udGFpbiBhbHBoYW51bWVyaWNzIGFuZCAnLSIKLSAgICAgIC8vIGJ1dCBtdXN0IHN0YXJ0IGFuZCBlbmQgd2l0aCBhbiBhbHBoYW51bWVyaWMKLSAgICAgIGNoYXIgdGVzdENoYXI7Ci0gICAgICBpbnQgbGFiZWxDaGFyQ291bnQgPSAwOwotCi0gICAgICBmb3IgKGludCBpID0gMDsgaSA8IGFkZHJMZW5ndGg7IGkrKykgewotICAgICAgICB0ZXN0Q2hhciA9IGFkZHJlc3MuY2hhckF0KGkpOwotICAgICAgICBpZiAodGVzdENoYXIgPT0gJy4nKSB7Ci0gICAgICAgICAgaWYgKCFpc0FscGhhbnVtKGFkZHJlc3MuY2hhckF0KGktMSkpKSB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgfQotICAgICAgICAgIGlmIChpKzEgPCBhZGRyTGVuZ3RoICYmICFpc0FscGhhbnVtKGFkZHJlc3MuY2hhckF0KGkrMSkpKSB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgfQotICAgICAgICAgIGxhYmVsQ2hhckNvdW50ID0gMDsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICghaXNBbHBoYW51bSh0ZXN0Q2hhcikgJiYgdGVzdENoYXIgIT0gJy0nKSB7Ci0gICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0gICAgICAgIC8vIFJGQyAxMDM0OiBMYWJlbHMgbXVzdCBiZSA2MyBjaGFyYWN0ZXJzIG9yIGxlc3MuCi0gICAgICAgIGVsc2UgaWYgKCsrbGFiZWxDaGFyQ291bnQgPiA2MykgewotICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLSAgICByZXR1cm4gdHJ1ZTsKLSAgfQotCi0gIC8qKgotICAgKiA8cD5EZXRlcm1pbmVzIHdoZXRoZXIgYSBzdHJpbmcgaXMgYW4gSVB2NCBhZGRyZXNzIGFzIGRlZmluZWQgYnkKLSAgICogUkZDIDIzNzMsIGFuZCB1bmRlciB0aGUgZnVydGhlciBjb25zdHJhaW50IHRoYXQgaXQgbXVzdCBiZSBhIDMyLWJpdAotICAgKiBhZGRyZXNzLiBUaG91Z2ggbm90IGV4cHJlc3NlZCBpbiB0aGUgZ3JhbW1hciwgaW4gb3JkZXIgdG8gc2F0aXNmeQotICAgKiB0aGUgMzItYml0IGFkZHJlc3MgY29uc3RyYWludCwgZWFjaCBzZWdtZW50IG9mIHRoZSBhZGRyZXNzIGNhbm5vdAotICAgKiBiZSBncmVhdGVyIHRoYW4gMjU1ICg4IGJpdHMgb2YgaW5mb3JtYXRpb24pLjwvcD4KLSAgICoKLSAgICogPHA+PGNvZGU+SVB2NGFkZHJlc3MgPSAxKjNESUdJVCAiLiIgMSozRElHSVQgIi4iIDEqM0RJR0lUICIuIiAxKjNESUdJVDwvY29kZT48L3A+Ci0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgc3RyaW5nIGlzIGEgc3ludGFjdGljYWxseSB2YWxpZCBJUHY0IGFkZHJlc3MKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc1dlbGxGb3JtZWRJUHY0QWRkcmVzcyhTdHJpbmcgYWRkcmVzcykgewotCi0gICAgICBpbnQgYWRkckxlbmd0aCA9IGFkZHJlc3MubGVuZ3RoKCk7Ci0gICAgICBjaGFyIHRlc3RDaGFyOwotICAgICAgaW50IG51bURvdHMgPSAwOwotICAgICAgaW50IG51bURpZ2l0cyA9IDA7Ci0KLSAgICAgIC8vIG1ha2Ugc3VyZSB0aGF0IDEpIHdlIHNlZSBvbmx5IGRpZ2l0cyBhbmQgZG90IHNlcGFyYXRvcnMsIDIpIHRoYXQKLSAgICAgIC8vIGFueSBkb3Qgc2VwYXJhdG9yIGlzIHByZWNlZGVkIGFuZCBmb2xsb3dlZCBieSBhIGRpZ2l0IGFuZAotICAgICAgLy8gMykgdGhhdCB3ZSBmaW5kIDMgZG90cwotICAgICAgLy8KLSAgICAgIC8vIFJGQyAyNzMyIGFtZW5kZWQgUkZDIDIzOTYgYnkgcmVwbGFjaW5nIHRoZSBkZWZpbml0aW9uCi0gICAgICAvLyBvZiBJUHY0YWRkcmVzcyB3aXRoIHRoZSBvbmUgZGVmaW5lZCBieSBSRkMgMjM3My4gLSBtcmdsYXZhcwotICAgICAgLy8KLSAgICAgIC8vIElQdjRhZGRyZXNzID0gMSozRElHSVQgIi4iIDEqM0RJR0lUICIuIiAxKjNESUdJVCAiLiIgMSozRElHSVQKLSAgICAgIC8vCi0gICAgICAvLyBPbmUgdG8gdGhyZWUgZGlnaXRzIG11c3QgYmUgaW4gZWFjaCBzZWdtZW50LgotICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhZGRyTGVuZ3RoOyBpKyspIHsKLSAgICAgICAgdGVzdENoYXIgPSBhZGRyZXNzLmNoYXJBdChpKTsKLSAgICAgICAgaWYgKHRlc3RDaGFyID09ICcuJykgewotICAgICAgICAgIGlmICgoaSA+IDAgJiYgIWlzRGlnaXQoYWRkcmVzcy5jaGFyQXQoaS0xKSkpIHx8Ci0gICAgICAgICAgICAgIChpKzEgPCBhZGRyTGVuZ3RoICYmICFpc0RpZ2l0KGFkZHJlc3MuY2hhckF0KGkrMSkpKSkgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgIH0KLSAgICAgICAgICBudW1EaWdpdHMgPSAwOwotICAgICAgICAgIGlmICgrK251bURvdHMgPiAzKSB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKCFpc0RpZ2l0KHRlc3RDaGFyKSkgewotICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotICAgICAgICAvLyBDaGVjayB0aGF0IHRoYXQgdGhlcmUgYXJlIG5vIG1vcmUgdGhhbiB0aHJlZSBkaWdpdHMKLSAgICAgICAgLy8gaW4gdGhpcyBzZWdtZW50LgotICAgICAgICBlbHNlIGlmICgrK251bURpZ2l0cyA+IDMpIHsKLSAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLSAgICAgICAgLy8gQ2hlY2sgdGhhdCB0aGlzIHNlZ21lbnQgaXMgbm90IGdyZWF0ZXIgdGhhbiAyNTUuCi0gICAgICAgIGVsc2UgaWYgKG51bURpZ2l0cyA9PSAzKSB7Ci0gICAgICAgICAgY2hhciBmaXJzdCA9IGFkZHJlc3MuY2hhckF0KGktMik7Ci0gICAgICAgICAgY2hhciBzZWNvbmQgPSBhZGRyZXNzLmNoYXJBdChpLTEpOwotICAgICAgICAgIGlmICghKGZpcnN0IDwgJzInIHx8Ci0gICAgICAgICAgICAgICAoZmlyc3QgPT0gJzInICYmCi0gICAgICAgICAgICAgICAoc2Vjb25kIDwgJzUnIHx8Ci0gICAgICAgICAgICAgICAoc2Vjb25kID09ICc1JyAmJiB0ZXN0Q2hhciA8PSAnNScpKSkpKSB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICB9Ci0gICAgICByZXR1cm4gKG51bURvdHMgPT0gMyk7Ci0gIH0KLQotICAvKioKLSAgICogPHA+RGV0ZXJtaW5lcyB3aGV0aGVyIGEgc3RyaW5nIGlzIGFuIElQdjYgcmVmZXJlbmNlIGFzIGRlZmluZWQKLSAgICogYnkgUkZDIDI3MzIsIHdoZXJlIElQdjZhZGRyZXNzIGlzIGRlZmluZWQgaW4gUkZDIDIzNzMuIFRoZQotICAgKiBJUHY2IGFkZHJlc3MgaXMgcGFyc2VkIGFjY29yZGluZyB0byBTZWN0aW9uIDIuMiBvZiBSRkMgMjM3MywKLSAgICogd2l0aCB0aGUgYWRkaXRpb25hbCBjb25zdHJhaW50IHRoYXQgdGhlIGFkZHJlc3MgYmUgY29tcG9zZWQgb2YKLSAgICogMTI4IGJpdHMgb2YgaW5mb3JtYXRpb24uPC9wPgotICAgKgotICAgKiA8cD48Y29kZT5JUHY2cmVmZXJlbmNlID0gIlsiIElQdjZhZGRyZXNzICJdIjwvY29kZT48L3A+Ci0gICAqCi0gICAqIDxwPk5vdGU6IFRoZSBCTkYgZXhwcmVzc2VkIGluIFJGQyAyMzczIEFwcGVuZGl4IEIgZG9lcyBub3QKLSAgICogYWNjdXJhdGVseSBkZXNjcmliZSBzZWN0aW9uIDIuMiwgYW5kIHdhcyBpbiBmYWN0IHJlbW92ZWQgZnJvbQotICAgKiBSRkMgMzUxMywgdGhlIHN1Y2Nlc3NvciBvZiBSRkMgMjM3My48L3A+Ci0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgc3RyaW5nIGlzIGEgc3ludGFjdGljYWxseSB2YWxpZCBJUHY2IHJlZmVyZW5jZQotICAgKi8KLSAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzV2VsbEZvcm1lZElQdjZSZWZlcmVuY2UoU3RyaW5nIGFkZHJlc3MpIHsKLQotICAgICAgaW50IGFkZHJMZW5ndGggPSBhZGRyZXNzLmxlbmd0aCgpOwotICAgICAgaW50IGluZGV4ID0gMTsKLSAgICAgIGludCBlbmQgPSBhZGRyTGVuZ3RoLTE7Ci0KLSAgICAgIC8vIENoZWNrIGlmIHN0cmluZyBpcyBhIHBvdGVudGlhbCBtYXRjaCBmb3IgSVB2NnJlZmVyZW5jZS4KLSAgICAgIGlmICghKGFkZHJMZW5ndGggPiAyICYmIGFkZHJlc3MuY2hhckF0KDApID09ICdbJwotICAgICAgICAgICYmIGFkZHJlc3MuY2hhckF0KGVuZCkgPT0gJ10nKSkgewotICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgIH0KLQotICAgICAgLy8gQ291bnRlciBmb3IgdGhlIG51bWJlciBvZiAxNi1iaXQgc2VjdGlvbnMgcmVhZCBpbiB0aGUgYWRkcmVzcy4KLSAgICAgIGludCBbXSBjb3VudGVyID0gbmV3IGludFsxXTsKLQotICAgICAgLy8gU2NhbiBoZXggc2VxdWVuY2UgYmVmb3JlIHBvc3NpYmxlICc6Oicgb3IgSVB2NCBhZGRyZXNzLgotICAgICAgaW5kZXggPSBzY2FuSGV4U2VxdWVuY2UoYWRkcmVzcywgaW5kZXgsIGVuZCwgY291bnRlcik7Ci0gICAgICBpZiAoaW5kZXggPT0gLTEpIHsKLSAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICB9Ci0gICAgICAvLyBBZGRyZXNzIG11c3QgY29udGFpbiAxMjgtYml0cyBvZiBpbmZvcm1hdGlvbi4KLSAgICAgIGVsc2UgaWYgKGluZGV4ID09IGVuZCkgewotICAgICAgICAgIHJldHVybiAoY291bnRlclswXSA9PSA4KTsKLSAgICAgIH0KLQotICAgICAgaWYgKGluZGV4KzEgPCBlbmQgJiYgYWRkcmVzcy5jaGFyQXQoaW5kZXgpID09ICc6JykgewotICAgICAgICAgIGlmIChhZGRyZXNzLmNoYXJBdChpbmRleCsxKSA9PSAnOicpIHsKLSAgICAgICAgICAgICAgLy8gJzo6JyByZXByZXNlbnRzIGF0IGxlYXN0IG9uZSAxNi1iaXQgZ3JvdXAgb2YgemVyb3MuCi0gICAgICAgICAgICAgIGlmICgrK2NvdW50ZXJbMF0gPiA4KSB7Ci0gICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgaW5kZXggKz0gMjsKLSAgICAgICAgICAgICAgLy8gVHJhaWxpbmcgemVyb3Mgd2lsbCBmaWxsIG91dCB0aGUgcmVzdCBvZiB0aGUgYWRkcmVzcy4KLSAgICAgICAgICAgICAgaWYgKGluZGV4ID09IGVuZCkgewotICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgICAgICAgfQotICAgICAgICAgIH0KLSAgICAgICAgICAvLyBJZiB0aGUgc2Vjb25kIGNoYXJhY3RlciB3YXNuJ3QgJzonLCBpbiBvcmRlciB0byBiZSB2YWxpZCwKLSAgICAgICAgICAvLyB0aGUgcmVtYWluZGVyIG9mIHRoZSBzdHJpbmcgbXVzdCBtYXRjaCBJUHY0QWRkcmVzcywKLSAgICAgICAgICAvLyBhbmQgd2UgbXVzdCBoYXZlIHJlYWQgZXhhY3RseSA2IDE2LWJpdCBncm91cHMuCi0gICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgIHJldHVybiAoY291bnRlclswXSA9PSA2KSAmJgotICAgICAgICAgICAgICAgICAgaXNXZWxsRm9ybWVkSVB2NEFkZHJlc3MoYWRkcmVzcy5zdWJzdHJpbmcoaW5kZXgrMSwgZW5kKSk7Ci0gICAgICAgICAgfQotICAgICAgfQotICAgICAgZWxzZSB7Ci0gICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgfQotCi0gICAgICAvLyAzLiBTY2FuIGhleCBzZXF1ZW5jZSBhZnRlciAnOjonLgotICAgICAgaW50IHByZXZDb3VudCA9IGNvdW50ZXJbMF07Ci0gICAgICBpbmRleCA9IHNjYW5IZXhTZXF1ZW5jZShhZGRyZXNzLCBpbmRleCwgZW5kLCBjb3VudGVyKTsKLQotICAgICAgLy8gV2UndmUgZWl0aGVyIHJlYWNoZWQgdGhlIGVuZCBvZiB0aGUgc3RyaW5nLCB0aGUgYWRkcmVzcyBlbmRzIGluCi0gICAgICAvLyBhbiBJUHY0IGFkZHJlc3MsIG9yIGl0IGlzIGludmFsaWQuIHNjYW5IZXhTZXF1ZW5jZSBoYXMgYWxyZWFkeQotICAgICAgLy8gbWFkZSBzdXJlIHRoYXQgd2UgaGF2ZSB0aGUgcmlnaHQgbnVtYmVyIG9mIGJpdHMuCi0gICAgICByZXR1cm4gKGluZGV4ID09IGVuZCkgfHwKLSAgICAgICAgICAoaW5kZXggIT0gLTEgJiYgaXNXZWxsRm9ybWVkSVB2NEFkZHJlc3MoCi0gICAgICAgICAgYWRkcmVzcy5zdWJzdHJpbmcoKGNvdW50ZXJbMF0gPiBwcmV2Q291bnQpID8gaW5kZXgrMSA6IGluZGV4LCBlbmQpKSk7Ci0gIH0KLQotICAvKioKLSAgICogSGVscGVyIG1ldGhvZCBmb3IgaXNXZWxsRm9ybWVkSVB2NlJlZmVyZW5jZSB3aGljaCBzY2FucyB0aGUKLSAgICogaGV4IHNlcXVlbmNlcyBvZiBhbiBJUHY2IGFkZHJlc3MuIEl0IHJldHVybnMgdGhlIGluZGV4IG9mIHRoZQotICAgKiBuZXh0IGNoYXJhY3RlciB0byBzY2FuIGluIHRoZSBhZGRyZXNzLCBvciAtMSBpZiB0aGUgc3RyaW5nCi0gICAqIGNhbm5vdCBtYXRjaCBhIHZhbGlkIElQdjYgYWRkcmVzcy4KLSAgICoKLSAgICogQHBhcmFtIGFkZHJlc3MgdGhlIHN0cmluZyB0byBiZSBzY2FubmVkCi0gICAqIEBwYXJhbSBpbmRleCB0aGUgYmVnaW5uaW5nIGluZGV4IChpbmNsdXNpdmUpCi0gICAqIEBwYXJhbSBlbmQgdGhlIGVuZGluZyBpbmRleCAoZXhjbHVzaXZlKQotICAgKiBAcGFyYW0gY291bnRlciBhIGNvdW50ZXIgZm9yIHRoZSBudW1iZXIgb2YgMTYtYml0IHNlY3Rpb25zIHJlYWQKLSAgICogaW4gdGhlIGFkZHJlc3MKLSAgICoKLSAgICogQHJldHVybiB0aGUgaW5kZXggb2YgdGhlIG5leHQgY2hhcmFjdGVyIHRvIHNjYW4sIG9yIC0xIGlmIHRoZQotICAgKiBzdHJpbmcgY2Fubm90IG1hdGNoIGEgdmFsaWQgSVB2NiBhZGRyZXNzCi0gICAqLwotICBwcml2YXRlIHN0YXRpYyBpbnQgc2NhbkhleFNlcXVlbmNlIChTdHJpbmcgYWRkcmVzcywgaW50IGluZGV4LCBpbnQgZW5kLCBpbnQgW10gY291bnRlcikgewotCi0gICAgICBjaGFyIHRlc3RDaGFyOwotICAgICAgaW50IG51bURpZ2l0cyA9IDA7Ci0gICAgICBpbnQgc3RhcnQgPSBpbmRleDsKLQotICAgICAgLy8gVHJ5aW5nIHRvIG1hdGNoIHRoZSBmb2xsb3dpbmcgcHJvZHVjdGlvbnM6Ci0gICAgICAvLyBoZXhzZXEgPSBoZXg0ICooICI6IiBoZXg0KQotICAgICAgLy8gaGV4NCAgID0gMSo0SEVYRElHCi0gICAgICBmb3IgKDsgaW5kZXggPCBlbmQ7ICsraW5kZXgpIHsKLSAgICAgICAgdGVzdENoYXIgPSBhZGRyZXNzLmNoYXJBdChpbmRleCk7Ci0gICAgICAgIGlmICh0ZXN0Q2hhciA9PSAnOicpIHsKLSAgICAgICAgICAgIC8vIElQdjYgYWRkcmVzc2VzIGFyZSAxMjgtYml0LCBzbyB0aGVyZSBjYW4gYmUgYXQgbW9zdCBlaWdodCBzZWN0aW9ucy4KLSAgICAgICAgICAgIGlmIChudW1EaWdpdHMgPiAwICYmICsrY291bnRlclswXSA+IDgpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gLTE7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyBUaGlzIGNvdWxkIGJlICc6OicuCi0gICAgICAgICAgICBpZiAobnVtRGlnaXRzID09IDAgfHwgKChpbmRleCsxIDwgZW5kKSAmJiBhZGRyZXNzLmNoYXJBdChpbmRleCsxKSA9PSAnOicpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGluZGV4OwotICAgICAgICAgICAgfQotICAgICAgICAgICAgbnVtRGlnaXRzID0gMDsKLSAgICAgICAgfQotICAgICAgICAvLyBUaGlzIG1pZ2h0IGJlIGludmFsaWQgb3IgYW4gSVB2NGFkZHJlc3MuIElmIGl0J3MgcG90ZW50aWFsbHkgYW4gSVB2NGFkZHJlc3MsCi0gICAgICAgIC8vIGJhY2t1cCB0byBqdXN0IGFmdGVyIHRoZSBsYXN0IHZhbGlkIGNoYXJhY3RlciB0aGF0IG1hdGNoZXMgaGV4c2VxLgotICAgICAgICBlbHNlIGlmICghaXNIZXgodGVzdENoYXIpKSB7Ci0gICAgICAgICAgICBpZiAodGVzdENoYXIgPT0gJy4nICYmIG51bURpZ2l0cyA8IDQgJiYgbnVtRGlnaXRzID4gMCAmJiBjb3VudGVyWzBdIDw9IDYpIHsKLSAgICAgICAgICAgICAgICBpbnQgYmFjayA9IGluZGV4IC0gbnVtRGlnaXRzIC0gMTsKLSAgICAgICAgICAgICAgICByZXR1cm4gKGJhY2sgPj0gc3RhcnQpID8gYmFjayA6IChiYWNrKzEpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIC0xOwotICAgICAgICB9Ci0gICAgICAgIC8vIFRoZXJlIGNhbiBiZSBhdCBtb3N0IDQgaGV4IGRpZ2l0cyBwZXIgZ3JvdXAuCi0gICAgICAgIGVsc2UgaWYgKCsrbnVtRGlnaXRzID4gNCkgewotICAgICAgICAgICAgcmV0dXJuIC0xOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgICByZXR1cm4gKG51bURpZ2l0cyA+IDAgJiYgKytjb3VudGVyWzBdIDw9IDgpID8gZW5kIDogLTE7Ci0gIH0KLQotCi0gLyoqCi0gICogRGV0ZXJtaW5lIHdoZXRoZXIgYSBjaGFyIGlzIGEgZGlnaXQuCi0gICoKLSAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGNoYXIgaXMgYmV0d2VlZW4gJzAnIGFuZCAnOScsIGZhbHNlIG90aGVyd2lzZQotICAqLwotICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGlzRGlnaXQoY2hhciBwX2NoYXIpIHsKLSAgICByZXR1cm4gcF9jaGFyID49ICcwJyAmJiBwX2NoYXIgPD0gJzknOwotICB9Ci0KLSAvKioKLSAgKiBEZXRlcm1pbmUgd2hldGhlciBhIGNoYXJhY3RlciBpcyBhIGhleGFkZWNpbWFsIGNoYXJhY3Rlci4KLSAgKgotICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgY2hhciBpcyBiZXR3ZWVlbiAnMCcgYW5kICc5JywgJ2EnIGFuZCAnZicKLSAgKiAgICAgICAgIG9yICdBJyBhbmQgJ0YnLCBmYWxzZSBvdGhlcndpc2UKLSAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBpc0hleChjaGFyIHBfY2hhcikgewotICAgIHJldHVybiAocF9jaGFyIDw9ICdmJyAmJiAoZmdMb29rdXBUYWJsZVtwX2NoYXJdICYgQVNDSUlfSEVYX0NIQVJBQ1RFUlMpICE9IDApOwotICB9Ci0KLSAvKioKLSAgKiBEZXRlcm1pbmUgd2hldGhlciBhIGNoYXIgaXMgYW4gYWxwaGFiZXRpYyBjaGFyYWN0ZXI6IGEteiBvciBBLVoKLSAgKgotICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgY2hhciBpcyBhbHBoYWJldGljLCBmYWxzZSBvdGhlcndpc2UKLSAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBpc0FscGhhKGNoYXIgcF9jaGFyKSB7Ci0gICAgICByZXR1cm4gKChwX2NoYXIgPj0gJ2EnICYmIHBfY2hhciA8PSAneicpIHx8IChwX2NoYXIgPj0gJ0EnICYmIHBfY2hhciA8PSAnWicgKSk7Ci0gIH0KLQotIC8qKgotICAqIERldGVybWluZSB3aGV0aGVyIGEgY2hhciBpcyBhbiBhbHBoYW51bWVyaWM6IDAtOSwgYS16IG9yIEEtWgotICAqCi0gICogQHJldHVybiB0cnVlIGlmIHRoZSBjaGFyIGlzIGFscGhhbnVtZXJpYywgZmFsc2Ugb3RoZXJ3aXNlCi0gICovCi0gIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNBbHBoYW51bShjaGFyIHBfY2hhcikgewotICAgICByZXR1cm4gKHBfY2hhciA8PSAneicgJiYgKGZnTG9va3VwVGFibGVbcF9jaGFyXSAmIE1BU0tfQUxQSEFfTlVNRVJJQykgIT0gMCk7Ci0gIH0KLQotIC8qKgotICAqIERldGVybWluZSB3aGV0aGVyIGEgY2hhcmFjdGVyIGlzIGEgcmVzZXJ2ZWQgY2hhcmFjdGVyOgotICAqICc7JywgJy8nLCAnPycsICc6JywgJ0AnLCAnJicsICc9JywgJysnLCAnJCcsICcsJywgJ1snLCBvciAnXScKLSAgKgotICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgc3RyaW5nIGNvbnRhaW5zIGFueSByZXNlcnZlZCBjaGFyYWN0ZXJzCi0gICovCi0gIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNSZXNlcnZlZENoYXJhY3RlcihjaGFyIHBfY2hhcikgewotICAgICByZXR1cm4gKHBfY2hhciA8PSAnXScgJiYgKGZnTG9va3VwVGFibGVbcF9jaGFyXSAmIFJFU0VSVkVEX0NIQVJBQ1RFUlMpICE9IDApOwotICB9Ci0KLSAvKioKLSAgKiBEZXRlcm1pbmUgd2hldGhlciBhIGNoYXIgaXMgYW4gdW5yZXNlcnZlZCBjaGFyYWN0ZXIuCi0gICoKLSAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGNoYXIgaXMgdW5yZXNlcnZlZCwgZmFsc2Ugb3RoZXJ3aXNlCi0gICovCi0gIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNVbnJlc2VydmVkQ2hhcmFjdGVyKGNoYXIgcF9jaGFyKSB7Ci0gICAgIHJldHVybiAocF9jaGFyIDw9ICd+JyAmJiAoZmdMb29rdXBUYWJsZVtwX2NoYXJdICYgTUFTS19VTlJFU0VSVkVEX01BU0spICE9IDApOwotICB9Ci0KLSAvKioKLSAgKiBEZXRlcm1pbmUgd2hldGhlciBhIGNoYXIgaXMgYSBVUkkgY2hhcmFjdGVyIChyZXNlcnZlZCBvcgotICAqIHVucmVzZXJ2ZWQsIG5vdCBpbmNsdWRpbmcgJyUnIGZvciBlc2NhcGVkIG9jdGV0cykuCi0gICoKLSAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGNoYXIgaXMgYSBVUkkgY2hhcmFjdGVyLCBmYWxzZSBvdGhlcndpc2UKLSAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBpc1VSSUNoYXJhY3RlciAoY2hhciBwX2NoYXIpIHsKLSAgICAgIHJldHVybiAocF9jaGFyIDw9ICd+JyAmJiAoZmdMb29rdXBUYWJsZVtwX2NoYXJdICYgTUFTS19VUklfQ0hBUkFDVEVSKSAhPSAwKTsKLSAgfQotCi0gLyoqCi0gICogRGV0ZXJtaW5lIHdoZXRoZXIgYSBjaGFyIGlzIGEgc2NoZW1lIGNoYXJhY3Rlci4KLSAgKgotICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgY2hhciBpcyBhIHNjaGVtZSBjaGFyYWN0ZXIsIGZhbHNlIG90aGVyd2lzZQotICAqLwotICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGlzU2NoZW1lQ2hhcmFjdGVyIChjaGFyIHBfY2hhcikgewotICAgICAgcmV0dXJuIChwX2NoYXIgPD0gJ3onICYmIChmZ0xvb2t1cFRhYmxlW3BfY2hhcl0gJiBNQVNLX1NDSEVNRV9DSEFSQUNURVIpICE9IDApOwotICB9Ci0KLSAvKioKLSAgKiBEZXRlcm1pbmUgd2hldGhlciBhIGNoYXIgaXMgYSB1c2VyaW5mbyBjaGFyYWN0ZXIuCi0gICoKLSAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGNoYXIgaXMgYSB1c2VyaW5mbyBjaGFyYWN0ZXIsIGZhbHNlIG90aGVyd2lzZQotICAqLwotICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGlzVXNlcmluZm9DaGFyYWN0ZXIgKGNoYXIgcF9jaGFyKSB7Ci0gICAgICByZXR1cm4gKHBfY2hhciA8PSAneicgJiYgKGZnTG9va3VwVGFibGVbcF9jaGFyXSAmIE1BU0tfVVNFUklORk9fQ0hBUkFDVEVSKSAhPSAwKTsKLSAgfQotCi0gLyoqCi0gICogRGV0ZXJtaW5lIHdoZXRoZXIgYSBjaGFyIGlzIGEgcGF0aCBjaGFyYWN0ZXIuCi0gICoKLSAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGNoYXIgaXMgYSBwYXRoIGNoYXJhY3RlciwgZmFsc2Ugb3RoZXJ3aXNlCi0gICovCi0gIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNQYXRoQ2hhcmFjdGVyIChjaGFyIHBfY2hhcikgewotICAgICAgcmV0dXJuIChwX2NoYXIgPD0gJ34nICYmIChmZ0xvb2t1cFRhYmxlW3BfY2hhcl0gJiBNQVNLX1BBVEhfQ0hBUkFDVEVSKSAhPSAwKTsKLSAgfQotCi0KLSAvKioKLSAgKiBEZXRlcm1pbmUgd2hldGhlciBhIGdpdmVuIHN0cmluZyBjb250YWlucyBvbmx5IFVSSSBjaGFyYWN0ZXJzIChhbHNvCi0gICogY2FsbGVkICJ1cmljIiBpbiBSRkMgMjM5NikuIHVyaWMgY29uc2lzdCBvZiBhbGwgcmVzZXJ2ZWQKLSAgKiBjaGFyYWN0ZXJzLCB1bnJlc2VydmVkIGNoYXJhY3RlcnMgYW5kIGVzY2FwZWQgY2hhcmFjdGVycy4KLSAgKgotICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgc3RyaW5nIGlzIGNvbXByaXNlZCBvZiB1cmljLCBmYWxzZSBvdGhlcndpc2UKLSAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBpc1VSSVN0cmluZyhTdHJpbmcgcF91cmljKSB7Ci0gICAgaWYgKHBfdXJpYyA9PSBudWxsKSB7Ci0gICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotICAgIGludCBlbmQgPSBwX3VyaWMubGVuZ3RoKCk7Ci0gICAgY2hhciB0ZXN0Q2hhciA9ICdcMCc7Ci0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBlbmQ7IGkrKykgewotICAgICAgdGVzdENoYXIgPSBwX3VyaWMuY2hhckF0KGkpOwotICAgICAgaWYgKHRlc3RDaGFyID09ICclJykgewotICAgICAgICBpZiAoaSsyID49IGVuZCB8fAotICAgICAgICAgICAgIWlzSGV4KHBfdXJpYy5jaGFyQXQoaSsxKSkgfHwKLSAgICAgICAgICAgICFpc0hleChwX3VyaWMuY2hhckF0KGkrMikpKSB7Ci0gICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgIGkgKz0gMjsKLSAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgfQotICAgICAgfQotICAgICAgaWYgKGlzVVJJQ2hhcmFjdGVyKHRlc3RDaGFyKSkgewotICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgfQotICAgICAgZWxzZSB7Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgIH0KLSAgICB9Ci0gICAgcmV0dXJuIHRydWU7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3V0aWwvWE1MMTFDaGFyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL1hNTDExQ2hhci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkMTk1MThlLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3V0aWwvWE1MMTFDaGFyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0MTUgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWw7Ci0KLWltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgZGVmaW5lcyB0aGUgYmFzaWMgcHJvcGVydGllcyBvZiBjaGFyYWN0ZXJzIGluIFhNTCAxLjEuIFRoZSBkYXRhCi0gKiBpbiB0aGlzIGNsYXNzIGNhbiBiZSB1c2VkIHRvIHZlcmlmeSB0aGF0IGEgY2hhcmFjdGVyIGlzIGEgdmFsaWQKLSAqIFhNTCAxLjEgY2hhcmFjdGVyIG9yIGlmIHRoZSBjaGFyYWN0ZXIgaXMgYSBzcGFjZSwgbmFtZSBzdGFydCwgb3IgbmFtZQotICogY2hhcmFjdGVyLgotICogPHA+Ci0gKiBBIHNlcmllcyBvZiBjb252ZW5pZW5jZSBtZXRob2RzIGFyZSBzdXBwbGllZCB0byBlYXNlIHRoZSBidXJkZW4KLSAqIG9mIHRoZSBkZXZlbG9wZXIuICBVc2luZyB0aGUgY2hhcmFjdGVyIGFzIGFuIGluZGV4IGludG8gdGhlIDxjb2RlPlhNTDExQ0hBUlM8L2NvZGU+Ci0gKiBhcnJheSBhbmQgYXBwbHlpbmcgdGhlIGFwcHJvcHJpYXRlIG1hc2sgZmxhZyAoZS5nLgotICogPGNvZGU+TUFTS19WQUxJRDwvY29kZT4pLCB5aWVsZHMgdGhlIHNhbWUgcmVzdWx0cyBhcyBjYWxsaW5nIHRoZQotICogY29udmVuaWVuY2UgbWV0aG9kcy4gVGhlcmUgaXMgb25lIGV4Y2VwdGlvbjogY2hlY2sgdGhlIGNvbW1lbnRzCi0gKiBmb3IgdGhlIDxjb2RlPmlzVmFsaWQ8L2NvZGU+IG1ldGhvZCBmb3IgZGV0YWlscy4KLSAqCi0gKiBAYXV0aG9yIEdsZW5uIE1hcmN5LCBJQk0KLSAqIEBhdXRob3IgQW5keSBDbGFyaywgSUJNCi0gKiBAYXV0aG9yIEFybmF1ZCAgTGUgSG9ycywgSUJNCi0gKiBAYXV0aG9yIE5laWwgR3JhaGFtLCBJQk0KLSAqIEBhdXRob3IgTWljaGFlbCBHbGF2YXNzZXZpY2gsIElCTQotICoKLSAqIEB2ZXJzaW9uICRJZDogWE1MMTFDaGFyLmphdmEsdiAxLjcgMjAxMC0xMS0wMSAwNDo0MDoxNSBqb2VodyBFeHAgJAotICovCi1wdWJsaWMgY2xhc3MgWE1MMTFDaGFyIHsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RhbnRzCi0gICAgLy8KLQotICAgIC8qKiBDaGFyYWN0ZXIgZmxhZ3MgZm9yIFhNTCAxLjEuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZSBYTUwxMUNIQVJTIFtdID0gbmV3IGJ5dGUgWzEgPDwgMTZdOwotCi0gICAgLyoqIFhNTCAxLjEgVmFsaWQgY2hhcmFjdGVyIG1hc2suICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFTS19YTUwxMV9WQUxJRCA9IDB4MDE7Ci0KLSAgICAvKiogWE1MIDEuMSBTcGFjZSBjaGFyYWN0ZXIgbWFzay4gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVNLX1hNTDExX1NQQUNFID0gMHgwMjsKLQotICAgIC8qKiBYTUwgMS4xIE5hbWUgc3RhcnQgY2hhcmFjdGVyIG1hc2suICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFTS19YTUwxMV9OQU1FX1NUQVJUID0gMHgwNDsKLQotICAgIC8qKiBYTUwgMS4xIE5hbWUgY2hhcmFjdGVyIG1hc2suICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFTS19YTUwxMV9OQU1FID0gMHgwODsKLQotICAgIC8qKiBYTUwgMS4xIGNvbnRyb2wgY2hhcmFjdGVyIG1hc2sgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVNLX1hNTDExX0NPTlRST0wgPSAweDEwOwotCi0gICAgLyoqIFhNTCAxLjEgY29udGVudCBmb3IgZXh0ZXJuYWwgZW50aXRpZXMgKHZhbGlkIC0gInNwZWNpYWwiIGNoYXJzIC0gY29udHJvbCBjaGFycykgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVNLX1hNTDExX0NPTlRFTlQgPSAweDIwOwotCi0gICAgLyoqIFhNTCBuYW1lc3BhY2VzIDEuMSBOQ05hbWVTdGFydCAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BU0tfWE1MMTFfTkNOQU1FX1NUQVJUID0gMHg0MDsKLQotICAgIC8qKiBYTUwgbmFtZXNwYWNlcyAxLjEgTkNOYW1lICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFTS19YTUwxMV9OQ05BTUUgPSAweDgwOwotCi0gICAgLyoqIFhNTCAxLjEgY29udGVudCBmb3IgaW50ZXJuYWwgZW50aXRpZXMgKHZhbGlkIC0gInNwZWNpYWwiIGNoYXJzKSAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BU0tfWE1MMTFfQ09OVEVOVF9JTlRFUk5BTCA9IE1BU0tfWE1MMTFfQ09OVFJPTCB8IE1BU0tfWE1MMTFfQ09OVEVOVDsKLQotICAgIC8vCi0gICAgLy8gU3RhdGljIGluaXRpYWxpemF0aW9uCi0gICAgLy8KLQotICAgIHN0YXRpYyB7Ci0KLSAgICAgICAgLy8gSW5pdGlhbGl6aW5nIHRoZSBDaGFyYWN0ZXIgRmxhZyBBcnJheQotICAgICAgICAvLyBDb2RlIGdlbmVyYXRlZCBieTogWE1MMTFDaGFyR2VuZXJhdG9yLgotCi0gICAgICAgIEFycmF5cy5maWxsKFhNTDExQ0hBUlMsIDEsIDksIChieXRlKSAxNyApOyAvLyBGaWxsIDggb2YgdmFsdWUgKGJ5dGUpIDE3Ci0gICAgICAgIFhNTDExQ0hBUlNbOV0gPSAzNTsKLSAgICAgICAgWE1MMTFDSEFSU1sxMF0gPSAzOwotICAgICAgICBBcnJheXMuZmlsbChYTUwxMUNIQVJTLCAxMSwgMTMsIChieXRlKSAxNyApOyAvLyBGaWxsIDIgb2YgdmFsdWUgKGJ5dGUpIDE3Ci0gICAgICAgIFhNTDExQ0hBUlNbMTNdID0gMzsKLSAgICAgICAgQXJyYXlzLmZpbGwoWE1MMTFDSEFSUywgMTQsIDMyLCAoYnl0ZSkgMTcgKTsgLy8gRmlsbCAxOCBvZiB2YWx1ZSAoYnl0ZSkgMTcKLSAgICAgICAgWE1MMTFDSEFSU1szMl0gPSAzNTsKLSAgICAgICAgQXJyYXlzLmZpbGwoWE1MMTFDSEFSUywgMzMsIDM4LCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCA1IG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBYTUwxMUNIQVJTWzM4XSA9IDE7Ci0gICAgICAgIEFycmF5cy5maWxsKFhNTDExQ0hBUlMsIDM5LCA0NSwgKGJ5dGUpIDMzICk7IC8vIEZpbGwgNiBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgQXJyYXlzLmZpbGwoWE1MMTFDSEFSUywgNDUsIDQ3LCAoYnl0ZSkgLTg3ICk7IC8vIEZpbGwgMiBvZiB2YWx1ZSAoYnl0ZSkgLTg3Ci0gICAgICAgIFhNTDExQ0hBUlNbNDddID0gMzM7Ci0gICAgICAgIEFycmF5cy5maWxsKFhNTDExQ0hBUlMsIDQ4LCA1OCwgKGJ5dGUpIC04NyApOyAvLyBGaWxsIDEwIG9mIHZhbHVlIChieXRlKSAtODcKLSAgICAgICAgWE1MMTFDSEFSU1s1OF0gPSA0NTsKLSAgICAgICAgWE1MMTFDSEFSU1s1OV0gPSAzMzsKLSAgICAgICAgWE1MMTFDSEFSU1s2MF0gPSAxOwotICAgICAgICBBcnJheXMuZmlsbChYTUwxMUNIQVJTLCA2MSwgNjUsIChieXRlKSAzMyApOyAvLyBGaWxsIDQgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIEFycmF5cy5maWxsKFhNTDExQ0hBUlMsIDY1LCA5MSwgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDI2IG9mIHZhbHVlIChieXRlKSAtMTkKLSAgICAgICAgQXJyYXlzLmZpbGwoWE1MMTFDSEFSUywgOTEsIDkzLCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCAyIG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBYTUwxMUNIQVJTWzkzXSA9IDE7Ci0gICAgICAgIFhNTDExQ0hBUlNbOTRdID0gMzM7Ci0gICAgICAgIFhNTDExQ0hBUlNbOTVdID0gLTE5OwotICAgICAgICBYTUwxMUNIQVJTWzk2XSA9IDMzOwotICAgICAgICBBcnJheXMuZmlsbChYTUwxMUNIQVJTLCA5NywgMTIzLCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgMjYgb2YgdmFsdWUgKGJ5dGUpIC0xOQotICAgICAgICBBcnJheXMuZmlsbChYTUwxMUNIQVJTLCAxMjMsIDEyNywgKGJ5dGUpIDMzICk7IC8vIEZpbGwgNCBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgQXJyYXlzLmZpbGwoWE1MMTFDSEFSUywgMTI3LCAxMzMsIChieXRlKSAxNyApOyAvLyBGaWxsIDYgb2YgdmFsdWUgKGJ5dGUpIDE3Ci0gICAgICAgIFhNTDExQ0hBUlNbMTMzXSA9IDM1OwotICAgICAgICBBcnJheXMuZmlsbChYTUwxMUNIQVJTLCAxMzQsIDE2MCwgKGJ5dGUpIDE3ICk7IC8vIEZpbGwgMjYgb2YgdmFsdWUgKGJ5dGUpIDE3Ci0gICAgICAgIEFycmF5cy5maWxsKFhNTDExQ0hBUlMsIDE2MCwgMTgzLCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCAyMyBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgWE1MMTFDSEFSU1sxODNdID0gLTg3OwotICAgICAgICBBcnJheXMuZmlsbChYTUwxMUNIQVJTLCAxODQsIDE5MiwgKGJ5dGUpIDMzICk7IC8vIEZpbGwgOCBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgQXJyYXlzLmZpbGwoWE1MMTFDSEFSUywgMTkyLCAyMTUsIChieXRlKSAtMTkgKTsgLy8gRmlsbCAyMyBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIFhNTDExQ0hBUlNbMjE1XSA9IDMzOwotICAgICAgICBBcnJheXMuZmlsbChYTUwxMUNIQVJTLCAyMTYsIDI0NywgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDMxIG9mIHZhbHVlIChieXRlKSAtMTkKLSAgICAgICAgWE1MMTFDSEFSU1syNDddID0gMzM7Ci0gICAgICAgIEFycmF5cy5maWxsKFhNTDExQ0hBUlMsIDI0OCwgNzY4LCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgNTIwIG9mIHZhbHVlIChieXRlKSAtMTkKLSAgICAgICAgQXJyYXlzLmZpbGwoWE1MMTFDSEFSUywgNzY4LCA4ODAsIChieXRlKSAtODcgKTsgLy8gRmlsbCAxMTIgb2YgdmFsdWUgKGJ5dGUpIC04NwotICAgICAgICBBcnJheXMuZmlsbChYTUwxMUNIQVJTLCA4ODAsIDg5NCwgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDE0IG9mIHZhbHVlIChieXRlKSAtMTkKLSAgICAgICAgWE1MMTFDSEFSU1s4OTRdID0gMzM7Ci0gICAgICAgIEFycmF5cy5maWxsKFhNTDExQ0hBUlMsIDg5NSwgODE5MiwgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDcyOTcgb2YgdmFsdWUgKGJ5dGUpIC0xOQotICAgICAgICBBcnJheXMuZmlsbChYTUwxMUNIQVJTLCA4MTkyLCA4MjA0LCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCAxMiBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgQXJyYXlzLmZpbGwoWE1MMTFDSEFSUywgODIwNCwgODIwNiwgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDIgb2YgdmFsdWUgKGJ5dGUpIC0xOQotICAgICAgICBBcnJheXMuZmlsbChYTUwxMUNIQVJTLCA4MjA2LCA4MjMyLCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCAyNiBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgWE1MMTFDSEFSU1s4MjMyXSA9IDM1OwotICAgICAgICBBcnJheXMuZmlsbChYTUwxMUNIQVJTLCA4MjMzLCA4MjU1LCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCAyMiBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgQXJyYXlzLmZpbGwoWE1MMTFDSEFSUywgODI1NSwgODI1NywgKGJ5dGUpIC04NyApOyAvLyBGaWxsIDIgb2YgdmFsdWUgKGJ5dGUpIC04NwotICAgICAgICBBcnJheXMuZmlsbChYTUwxMUNIQVJTLCA4MjU3LCA4MzA0LCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCA0NyBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgQXJyYXlzLmZpbGwoWE1MMTFDSEFSUywgODMwNCwgODU5MiwgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDI4OCBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIEFycmF5cy5maWxsKFhNTDExQ0hBUlMsIDg1OTIsIDExMjY0LCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCAyNjcyIG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBBcnJheXMuZmlsbChYTUwxMUNIQVJTLCAxMTI2NCwgMTIyNzIsIChieXRlKSAtMTkgKTsgLy8gRmlsbCAxMDA4IG9mIHZhbHVlIChieXRlKSAtMTkKLSAgICAgICAgQXJyYXlzLmZpbGwoWE1MMTFDSEFSUywgMTIyNzIsIDEyMjg5LCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCAxNyBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgQXJyYXlzLmZpbGwoWE1MMTFDSEFSUywgMTIyODksIDU1Mjk2LCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgNDMwMDcgb2YgdmFsdWUgKGJ5dGUpIC0xOQotICAgICAgICBBcnJheXMuZmlsbChYTUwxMUNIQVJTLCA1NzM0NCwgNjM3NDQsIChieXRlKSAzMyApOyAvLyBGaWxsIDY0MDAgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIEFycmF5cy5maWxsKFhNTDExQ0hBUlMsIDYzNzQ0LCA2NDk3NiwgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDEyMzIgb2YgdmFsdWUgKGJ5dGUpIC0xOQotICAgICAgICBBcnJheXMuZmlsbChYTUwxMUNIQVJTLCA2NDk3NiwgNjUwMDgsIChieXRlKSAzMyApOyAvLyBGaWxsIDMyIG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBBcnJheXMuZmlsbChYTUwxMUNIQVJTLCA2NTAwOCwgNjU1MzQsIChieXRlKSAtMTkgKTsgLy8gRmlsbCA1MjYgb2YgdmFsdWUgKGJ5dGUpIC0xOQotCi0gICAgfSAvLyA8Y2xpbml0PigpCi0KLSAgICAvLwotICAgIC8vIFB1YmxpYyBzdGF0aWMgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXIgaXMgYSBzcGFjZSBjaGFyYWN0ZXIKLSAgICAgKiBhcyBhbWRlbmRlZCBpbiB0aGUgWE1MIDEuMSBzcGVjaWZpY2F0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIGMgVGhlIGNoYXJhY3RlciB0byBjaGVjay4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNYTUwxMVNwYWNlKGludCBjKSB7Ci0gICAgICAgIHJldHVybiAoYyA8IDB4MTAwMDAgJiYgKFhNTDExQ0hBUlNbY10gJiBNQVNLX1hNTDExX1NQQUNFKSAhPSAwKTsKLSAgICB9IC8vIGlzWE1MMTFTcGFjZShpbnQpOmJvb2xlYW4KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgc3BlY2lmaWVkIGNoYXJhY3RlciBpcyB2YWxpZC4gVGhpcyBtZXRob2QKLSAgICAgKiBhbHNvIGNoZWNrcyB0aGUgc3Vycm9nYXRlIGNoYXJhY3RlciByYW5nZSBmcm9tIDB4MTAwMDAgdG8gMHgxMEZGRkYuCi0gICAgICogPHA+Ci0gICAgICogSWYgdGhlIHByb2dyYW0gY2hvb3NlcyB0byBhcHBseSB0aGUgbWFzayBkaXJlY3RseSB0byB0aGUKLSAgICAgKiA8Y29kZT5YTUwxMUNIQVJTPC9jb2RlPiBhcnJheSwgdGhlbiB0aGV5IGFyZSByZXNwb25zaWJsZSBmb3IgY2hlY2tpbmcKLSAgICAgKiB0aGUgc3Vycm9nYXRlIGNoYXJhY3RlciByYW5nZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjIFRoZSBjaGFyYWN0ZXIgdG8gY2hlY2suCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzWE1MMTFWYWxpZChpbnQgYykgewotICAgICAgICByZXR1cm4gKGMgPCAweDEwMDAwICYmIChYTUwxMUNIQVJTW2NdICYgTUFTS19YTUwxMV9WQUxJRCkgIT0gMCkKLSAgICAgICAgICAgICAgICB8fCAoMHgxMDAwMCA8PSBjICYmIGMgPD0gMHgxMEZGRkYpOwotICAgIH0gLy8gaXNYTUwxMVZhbGlkKGludCk6Ym9vbGVhbgotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyIGlzIGludmFsaWQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYyBUaGUgY2hhcmFjdGVyIHRvIGNoZWNrLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc1hNTDExSW52YWxpZChpbnQgYykgewotICAgICAgICByZXR1cm4gIWlzWE1MMTFWYWxpZChjKTsKLSAgICB9IC8vIGlzWE1MMTFJbnZhbGlkKGludCk6Ym9vbGVhbgotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyIGlzIHZhbGlkIGFuZCBwZXJtaXR0ZWQgb3V0c2lkZQotICAgICAqIG9mIGEgY2hhcmFjdGVyIHJlZmVyZW5jZS4KLSAgICAgKiBUaGF0IGlzLCB0aGlzIG1ldGhvZCB3aWxsIHJldHVybiBmYWxzZSBmb3IgdGhlIHNhbWUgc2V0IGFzCi0gICAgICogaXNYTUwxMVZhbGlkLCBleGNlcHQgaXQgYWxzbyByZXBvcnRzIGZhbHNlIGZvciAiY29udHJvbCBjaGFyYWN0ZXJzIi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjIFRoZSBjaGFyYWN0ZXIgdG8gY2hlY2suCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzWE1MMTFWYWxpZExpdGVyYWwoaW50IGMpIHsKLSAgICAgICAgcmV0dXJuICgoYyA8IDB4MTAwMDAgJiYgKChYTUwxMUNIQVJTW2NdICYgTUFTS19YTUwxMV9WQUxJRCkgIT0gMCAmJiAoWE1MMTFDSEFSU1tjXSAmIE1BU0tfWE1MMTFfQ09OVFJPTCkgPT0gMCkpCi0gICAgICAgICAgICB8fCAoMHgxMDAwMCA8PSBjICYmIGMgPD0gMHgxMEZGRkYpKTsKLSAgICB9IC8vIGlzWE1MMTFWYWxpZExpdGVyYWwoaW50KTpib29sZWFuCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXIgY2FuIGJlIGNvbnNpZGVyZWQKLSAgICAgKiBjb250ZW50IGluIGFuIGV4dGVybmFsIHBhcnNlZCBlbnRpdHkuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYyBUaGUgY2hhcmFjdGVyIHRvIGNoZWNrLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc1hNTDExQ29udGVudChpbnQgYykgewotICAgICAgICByZXR1cm4gKGMgPCAweDEwMDAwICYmIChYTUwxMUNIQVJTW2NdICYgTUFTS19YTUwxMV9DT05URU5UKSAhPSAwKSB8fAotICAgICAgICAgICAgICAgKDB4MTAwMDAgPD0gYyAmJiBjIDw9IDB4MTBGRkZGKTsKLSAgICB9IC8vIGlzWE1MMTFDb250ZW50KGludCk6Ym9vbGVhbgotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyIGNhbiBiZSBjb25zaWRlcmVkCi0gICAgICogY29udGVudCBpbiBhbiBpbnRlcm5hbCBwYXJzZWQgZW50aXR5LgotICAgICAqCi0gICAgICogQHBhcmFtIGMgVGhlIGNoYXJhY3RlciB0byBjaGVjay4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNYTUwxMUludGVybmFsRW50aXR5Q29udGVudChpbnQgYykgewotICAgICAgICByZXR1cm4gKGMgPCAweDEwMDAwICYmIChYTUwxMUNIQVJTW2NdICYgTUFTS19YTUwxMV9DT05URU5UX0lOVEVSTkFMKSAhPSAwKSB8fAotICAgICAgICAgICAgICAgKDB4MTAwMDAgPD0gYyAmJiBjIDw9IDB4MTBGRkZGKTsKLSAgICB9IC8vIGlzWE1MMTFJbnRlcm5hbEVudGl0eUNvbnRlbnQoaW50KTpib29sZWFuCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXIgaXMgYSB2YWxpZCBuYW1lIHN0YXJ0Ci0gICAgICogY2hhcmFjdGVyIGFzIGRlZmluZWQgYnkgcHJvZHVjdGlvbiBbNF0gaW4gdGhlIFhNTCAxLjEKLSAgICAgKiBzcGVjaWZpY2F0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIGMgVGhlIGNoYXJhY3RlciB0byBjaGVjay4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNYTUwxMU5hbWVTdGFydChpbnQgYykgewotICAgICAgICByZXR1cm4gKGMgPCAweDEwMDAwICYmIChYTUwxMUNIQVJTW2NdICYgTUFTS19YTUwxMV9OQU1FX1NUQVJUKSAhPSAwKQotICAgICAgICAgICAgfHwgKDB4MTAwMDAgPD0gYyAmJiBjIDwgMHhGMDAwMCk7Ci0gICAgfSAvLyBpc1hNTDExTmFtZVN0YXJ0KGludCk6Ym9vbGVhbgotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyIGlzIGEgdmFsaWQgbmFtZQotICAgICAqIGNoYXJhY3RlciBhcyBkZWZpbmVkIGJ5IHByb2R1Y3Rpb24gWzRhXSBpbiB0aGUgWE1MIDEuMQotICAgICAqIHNwZWNpZmljYXRpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYyBUaGUgY2hhcmFjdGVyIHRvIGNoZWNrLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc1hNTDExTmFtZShpbnQgYykgewotICAgICAgICByZXR1cm4gKGMgPCAweDEwMDAwICYmIChYTUwxMUNIQVJTW2NdICYgTUFTS19YTUwxMV9OQU1FKSAhPSAwKQotICAgICAgICAgICAgfHwgKGMgPj0gMHgxMDAwMCAmJiBjIDwgMHhGMDAwMCk7Ci0gICAgfSAvLyBpc1hNTDExTmFtZShpbnQpOmJvb2xlYW4KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgc3BlY2lmaWVkIGNoYXJhY3RlciBpcyBhIHZhbGlkIE5DTmFtZSBzdGFydAotICAgICAqIGNoYXJhY3RlciBhcyBkZWZpbmVkIGJ5IHByb2R1Y3Rpb24gWzRdIGluIE5hbWVzcGFjZXMgaW4gWE1MCi0gICAgICogMS4xIHJlY29tbWVuZGF0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIGMgVGhlIGNoYXJhY3RlciB0byBjaGVjay4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNYTUwxMU5DTmFtZVN0YXJ0KGludCBjKSB7Ci0gICAgICAgIHJldHVybiAoYyA8IDB4MTAwMDAgJiYgKFhNTDExQ0hBUlNbY10gJiBNQVNLX1hNTDExX05DTkFNRV9TVEFSVCkgIT0gMCkKLSAgICAgICAgICAgIHx8ICgweDEwMDAwIDw9IGMgJiYgYyA8IDB4RjAwMDApOwotICAgIH0gLy8gaXNYTUwxMU5DTmFtZVN0YXJ0KGludCk6Ym9vbGVhbgotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyIGlzIGEgdmFsaWQgTkNOYW1lCi0gICAgICogY2hhcmFjdGVyIGFzIGRlZmluZWQgYnkgcHJvZHVjdGlvbiBbNV0gaW4gTmFtZXNwYWNlcyBpbiBYTUwKLSAgICAgKiAxLjEgcmVjb21tZW5kYXRpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYyBUaGUgY2hhcmFjdGVyIHRvIGNoZWNrLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc1hNTDExTkNOYW1lKGludCBjKSB7Ci0gICAgICAgIHJldHVybiAoYyA8IDB4MTAwMDAgJiYgKFhNTDExQ0hBUlNbY10gJiBNQVNLX1hNTDExX05DTkFNRSkgIT0gMCkKLSAgICAgICAgICAgIHx8ICgweDEwMDAwIDw9IGMgJiYgYyA8IDB4RjAwMDApOwotICAgIH0gLy8gaXNYTUwxMU5DTmFtZShpbnQpOmJvb2xlYW4KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgd2hldGhlciB0aGUgZ2l2ZW4gY2hhcmFjdGVyIGlzIGEgdmFsaWQKLSAgICAgKiBoaWdoIHN1cnJvZ2F0ZSBmb3IgYSBuYW1lIGNoYXJhY3Rlci4gVGhpcyBpbmNsdWRlcwotICAgICAqIGFsbCBoaWdoIHN1cnJvZ2F0ZXMgZm9yIGNoYXJhY3RlcnMgWzB4MTAwMDAtMHhFRkZGRl0uCi0gICAgICogSW4gb3RoZXIgd29yZHMgZXZlcnl0aGluZyBleGNsdWRpbmcgcGxhbmVzIDE1IGFuZCAxNi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjIFRoZSBjaGFyYWN0ZXIgdG8gY2hlY2suCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzWE1MMTFOYW1lSGlnaFN1cnJvZ2F0ZShpbnQgYykgewotICAgICAgICByZXR1cm4gKDB4RDgwMCA8PSBjICYmIGMgPD0gMHhEQjdGKTsKLSAgICB9Ci0KLSAgICAvKgotICAgICAqIFs1XSBOYW1lIDo6PSBOYW1lU3RhcnRDaGFyIE5hbWVDaGFyKgotICAgICAqLwotICAgIC8qKgotICAgICAqIENoZWNrIHRvIHNlZSBpZiBhIHN0cmluZyBpcyBhIHZhbGlkIE5hbWUgYWNjb3JkaW5nIHRvIFs1XQotICAgICAqIGluIHRoZSBYTUwgMS4xIFJlY29tbWVuZGF0aW9uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSBzdHJpbmcgdG8gY2hlY2sKLSAgICAgKiBAcmV0dXJuIHRydWUgaWYgbmFtZSBpcyBhIHZhbGlkIE5hbWUKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNYTUwxMVZhbGlkTmFtZShTdHJpbmcgbmFtZSkgewotICAgICAgICBmaW5hbCBpbnQgbGVuZ3RoID0gbmFtZS5sZW5ndGgoKTsKLSAgICAgICAgaWYgKGxlbmd0aCA9PSAwKSB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLSAgICAgICAgaW50IGkgPSAxOwotICAgICAgICBjaGFyIGNoID0gbmFtZS5jaGFyQXQoMCk7Ci0gICAgICAgIGlmICghaXNYTUwxMU5hbWVTdGFydChjaCkpIHsKLSAgICAgICAgICAgIGlmIChsZW5ndGggPiAxICYmIGlzWE1MMTFOYW1lSGlnaFN1cnJvZ2F0ZShjaCkpIHsKLSAgICAgICAgICAgICAgICBjaGFyIGNoMiA9IG5hbWUuY2hhckF0KDEpOwotICAgICAgICAgICAgICAgIGlmICghWE1MQ2hhci5pc0xvd1N1cnJvZ2F0ZShjaDIpIHx8Ci0gICAgICAgICAgICAgICAgICAgICFpc1hNTDExTmFtZVN0YXJ0KFhNTENoYXIuc3VwcGxlbWVudGFsKGNoLCBjaDIpKSkgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGkgPSAyOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHdoaWxlIChpIDwgbGVuZ3RoKSB7Ci0gICAgICAgICAgICBjaCA9IG5hbWUuY2hhckF0KGkpOwotICAgICAgICAgICAgaWYgKCFpc1hNTDExTmFtZShjaCkpIHsKLSAgICAgICAgICAgICAgICBpZiAoKytpIDwgbGVuZ3RoICYmIGlzWE1MMTFOYW1lSGlnaFN1cnJvZ2F0ZShjaCkpIHsKLSAgICAgICAgICAgICAgICAgICAgY2hhciBjaDIgPSBuYW1lLmNoYXJBdChpKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKCFYTUxDaGFyLmlzTG93U3Vycm9nYXRlKGNoMikgfHwKLSAgICAgICAgICAgICAgICAgICAgICAgICFpc1hNTDExTmFtZShYTUxDaGFyLnN1cHBsZW1lbnRhbChjaCwgY2gyKSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgICsraTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICB9IC8vIGlzWE1MMTFWYWxpZE5hbWUoU3RyaW5nKTpib29sZWFuCi0KLSAgICAvKgotICAgICAqIGZyb20gdGhlIG5hbWVzcGFjZSAxLjEgcmVjCi0gICAgICogWzRdIE5DTmFtZSA6Oj0gTkNOYW1lU3RhcnRDaGFyIE5DTmFtZUNoYXIqCi0gICAgICovCi0gICAgLyoqCi0gICAgICogQ2hlY2sgdG8gc2VlIGlmIGEgc3RyaW5nIGlzIGEgdmFsaWQgTkNOYW1lIGFjY29yZGluZyB0byBbNF0KLSAgICAgKiBmcm9tIHRoZSBYTUwgTmFtZXNwYWNlcyAxLjEgUmVjb21tZW5kYXRpb24KLSAgICAgKgotICAgICAqIEBwYXJhbSBuY05hbWUgc3RyaW5nIHRvIGNoZWNrCi0gICAgICogQHJldHVybiB0cnVlIGlmIG5hbWUgaXMgYSB2YWxpZCBOQ05hbWUKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNYTUwxMVZhbGlkTkNOYW1lKFN0cmluZyBuY05hbWUpIHsKLSAgICAgICAgZmluYWwgaW50IGxlbmd0aCA9IG5jTmFtZS5sZW5ndGgoKTsKLSAgICAgICAgaWYgKGxlbmd0aCA9PSAwKSB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLSAgICAgICAgaW50IGkgPSAxOwotICAgICAgICBjaGFyIGNoID0gbmNOYW1lLmNoYXJBdCgwKTsKLSAgICAgICAgaWYgKCFpc1hNTDExTkNOYW1lU3RhcnQoY2gpKSB7Ci0gICAgICAgICAgICBpZiAobGVuZ3RoID4gMSAmJiBpc1hNTDExTmFtZUhpZ2hTdXJyb2dhdGUoY2gpKSB7Ci0gICAgICAgICAgICAgICAgY2hhciBjaDIgPSBuY05hbWUuY2hhckF0KDEpOwotICAgICAgICAgICAgICAgIGlmICghWE1MQ2hhci5pc0xvd1N1cnJvZ2F0ZShjaDIpIHx8Ci0gICAgICAgICAgICAgICAgICAgICFpc1hNTDExTkNOYW1lU3RhcnQoWE1MQ2hhci5zdXBwbGVtZW50YWwoY2gsIGNoMikpKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaSA9IDI7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgd2hpbGUgKGkgPCBsZW5ndGgpIHsKLSAgICAgICAgICAgIGNoID0gbmNOYW1lLmNoYXJBdChpKTsKLSAgICAgICAgICAgIGlmICghaXNYTUwxMU5DTmFtZShjaCkpIHsKLSAgICAgICAgICAgICAgICBpZiAoKytpIDwgbGVuZ3RoICYmIGlzWE1MMTFOYW1lSGlnaFN1cnJvZ2F0ZShjaCkpIHsKLSAgICAgICAgICAgICAgICAgICAgY2hhciBjaDIgPSBuY05hbWUuY2hhckF0KGkpOwotICAgICAgICAgICAgICAgICAgICBpZiAoIVhNTENoYXIuaXNMb3dTdXJyb2dhdGUoY2gyKSB8fAotICAgICAgICAgICAgICAgICAgICAgICAgIWlzWE1MMTFOQ05hbWUoWE1MQ2hhci5zdXBwbGVtZW50YWwoY2gsIGNoMikpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICArK2k7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfSAvLyBpc1hNTDExVmFsaWROQ05hbWUoU3RyaW5nKTpib29sZWFuCi0KLSAgICAvKgotICAgICAqIFs3XSBObXRva2VuIDo6PSAoTmFtZUNoYXIpKwotICAgICAqLwotICAgIC8qKgotICAgICAqIENoZWNrIHRvIHNlZSBpZiBhIHN0cmluZyBpcyBhIHZhbGlkIE5tdG9rZW4gYWNjb3JkaW5nIHRvIFs3XQotICAgICAqIGluIHRoZSBYTUwgMS4xIFJlY29tbWVuZGF0aW9uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbm10b2tlbiBzdHJpbmcgdG8gY2hlY2sKLSAgICAgKiBAcmV0dXJuIHRydWUgaWYgbm10b2tlbiBpcyBhIHZhbGlkIE5tdG9rZW4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNYTUwxMVZhbGlkTm10b2tlbihTdHJpbmcgbm10b2tlbikgewotICAgICAgICBmaW5hbCBpbnQgbGVuZ3RoID0gbm10b2tlbi5sZW5ndGgoKTsKLSAgICAgICAgaWYgKGxlbmd0aCA9PSAwKSB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkgewotICAgICAgICAgICAgY2hhciBjaCA9IG5tdG9rZW4uY2hhckF0KGkpOwotICAgICAgICAgICAgaWYgKCFpc1hNTDExTmFtZShjaCkpIHsKLSAgICAgICAgICAgICAgICBpZiAoKytpIDwgbGVuZ3RoICYmIGlzWE1MMTFOYW1lSGlnaFN1cnJvZ2F0ZShjaCkpIHsKLSAgICAgICAgICAgICAgICAgICAgY2hhciBjaDIgPSBubXRva2VuLmNoYXJBdChpKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKCFYTUxDaGFyLmlzTG93U3Vycm9nYXRlKGNoMikgfHwKLSAgICAgICAgICAgICAgICAgICAgICAgICFpc1hNTDExTmFtZShYTUxDaGFyLnN1cHBsZW1lbnRhbChjaCwgY2gyKSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICB9IC8vIGlzWE1MMTFWYWxpZE5hbWUoU3RyaW5nKTpib29sZWFuCi0KLX0gLy8gY2xhc3MgWE1MMTFDaGFyCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL1hNTEF0dHJpYnV0ZXNJbXBsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL1hNTEF0dHJpYnV0ZXNJbXBsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGEwMmQ1NGEuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9YTUxBdHRyaWJ1dGVzSW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTI5NiArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDE1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICovCi0vKgotICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCi0gKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKLSAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KLSAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCi0gKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAotICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWw7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5BdWdtZW50YXRpb25zOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlFOYW1lOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTEF0dHJpYnV0ZXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MU3RyaW5nOwotaW1wb3J0IGNvbS5zdW4ueG1sLmludGVybmFsLnN0cmVhbS5YTUxCdWZmZXJMaXN0ZW5lcjsKLS8qKgotICogVGhlIFhNTEF0dHJpYnV0ZXNJbXBsIGNsYXNzIGlzIGFuIGltcGxlbWVudGF0aW9uIG9mIHRoZSBYTUxBdHRyaWJ1dGVzCi0gKiBpbnRlcmZhY2Ugd2hpY2ggZGVmaW5lcyBhIGNvbGxlY3Rpb24gb2YgYXR0cmlidXRlcyBmb3IgYW4gZWxlbWVudC4KLSAqIEluIHRoZSBwYXJzZXIsIHRoZSBkb2N1bWVudCBzb3VyY2Ugd291bGQgc2NhbiB0aGUgZW50aXJlIHN0YXJ0IGVsZW1lbnQKLSAqIGFuZCBjb2xsZWN0IHRoZSBhdHRyaWJ1dGVzLiBUaGUgYXR0cmlidXRlcyBhcmUgY29tbXVuaWNhdGVkIHRvIHRoZQotICogZG9jdW1lbnQgaGFuZGxlciBpbiB0aGUgc3RhcnRFbGVtZW50IG1ldGhvZC4KLSAqIDxwPgotICogVGhlIGF0dHJpYnV0ZXMgYXJlIHJlYWQtd3JpdGUgc28gdGhhdCBzdWJzZXF1ZW50IHN0YWdlcyBpbiB0aGUgZG9jdW1lbnQKLSAqIHBpcGVsaW5lIGNhbiBtb2RpZnkgdGhlIHZhbHVlcyBvciBjaGFuZ2UgdGhlIGF0dHJpYnV0ZXMgdGhhdCBhcmUKLSAqIHByb3BvZ2F0ZWQgdG8gdGhlIG5leHQgc3RhZ2UuCi0gKgotICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxEb2N1bWVudEhhbmRsZXIjc3RhcnRFbGVtZW50Ci0gKgotICogQGF1dGhvciBBbmR5IENsYXJrLCBJQk0KLSAqIEBhdXRob3IgRWxlbmEgTGl0YW5pLCBJQk0KLSAqIEBhdXRob3IgTWljaGFlbCBHbGF2YXNzZXZpY2gsIElCTQotICoKLSAqIEB2ZXJzaW9uICRJZDogWE1MQXR0cmlidXRlc0ltcGwuamF2YSx2IDEuNyAyMDEwLzA1LzA3IDIwOjEzOjA5IGpvZWh3IEV4cCAkCi0gKi8KLXB1YmxpYyBjbGFzcyBYTUxBdHRyaWJ1dGVzSW1wbAotaW1wbGVtZW50cyBYTUxBdHRyaWJ1dGVzLCBYTUxCdWZmZXJMaXN0ZW5lciB7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0YW50cwotICAgIC8vCi0KLSAgICAvKiogRGVmYXVsdCB0YWJsZSBzaXplLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgaW50IFRBQkxFX1NJWkUgPSAxMDE7Ci0KLSAgICAvKiogTWF4aW11bSBoYXNoIGNvbGxpc2lvbnMgcGVyIGJ1Y2tldC4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBNQVhfSEFTSF9DT0xMSVNJT05TID0gNDA7Ci0KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBNVUxUSVBMSUVSU19TSVpFID0gMSA8PCA1OwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgaW50IE1VTFRJUExJRVJTX01BU0sgPSBNVUxUSVBMSUVSU19TSVpFIC0gMTsKLQotICAgIC8qKgotICAgICAqIFRocmVzaG9sZCBhdCB3aGljaCBhbiBpbnN0YW5jZSBpcyB0cmVhdGVkCi0gICAgICogYXMgYSBsYXJnZSBhdHRyaWJ1dGUgbGlzdC4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBTSVpFX0xJTUlUID0gMjA7Ci0KLSAgICAvLwotICAgIC8vIERhdGEKLSAgICAvLwotCi0gICAgLy8gZmVhdHVyZXMKLQotICAgIC8qKiBOYW1lc3BhY2VzLiAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIGZOYW1lc3BhY2VzID0gdHJ1ZTsKLQotICAgIC8vIGRhdGEKLQotICAgIC8qKgotICAgICAqIFVzYWdlIGNvdW50IGZvciB0aGUgYXR0cmlidXRlIHRhYmxlIHZpZXcuCi0gICAgICogSW5jcmVtZW50ZWQgZWFjaCB0aW1lIGFsbCBhdHRyaWJ1dGVzIGFyZSByZW1vdmVkCi0gICAgICogd2hlbiB0aGUgYXR0cmlidXRlIHRhYmxlIHZpZXcgaXMgaW4gdXNlLgotICAgICAqLwotICAgIHByb3RlY3RlZCBpbnQgZkxhcmdlQ291bnQgPSAxOwotCi0gICAgLyoqIEF0dHJpYnV0ZSBjb3VudC4gKi8KLSAgICBwcm90ZWN0ZWQgaW50IGZMZW5ndGg7Ci0KLSAgICAvKiogQXR0cmlidXRlIGluZm9ybWF0aW9uLiAqLwotICAgIHByb3RlY3RlZCBBdHRyaWJ1dGVbXSBmQXR0cmlidXRlcyA9IG5ldyBBdHRyaWJ1dGVbNF07Ci0KLSAgICAvKioKLSAgICAgKiBQcm92aWRlcyBhbiBhbHRlcm5hdGUgdmlldyBvZiB0aGUgYXR0cmlidXRlIHNwZWNpZmljYXRpb24uCi0gICAgICovCi0gICAgcHJvdGVjdGVkIEF0dHJpYnV0ZVtdIGZBdHRyaWJ1dGVUYWJsZVZpZXc7Ci0KLSAgICAvKioKLSAgICAgKiBUcmFja3Mgd2hldGhlciBlYWNoIGNoYWluIGluIHRoZSBoYXNoIHRhYmxlIGlzIHN0YWxlCi0gICAgICogd2l0aCByZXNwZWN0IHRvIHRoZSBjdXJyZW50IHN0YXRlIG9mIHRoaXMgb2JqZWN0LgotICAgICAqIEEgY2hhaW4gaXMgc3RhbGUgaWYgaXRzIHN0YXRlIGlzIG5vdCB0aGUgc2FtZSBhcyB0aGUgbnVtYmVyCi0gICAgICogb2YgdGltZXMgdGhlIGF0dHJpYnV0ZSB0YWJsZSB2aWV3IGhhcyBiZWVuIHVzZWQuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGludFtdIGZBdHRyaWJ1dGVUYWJsZVZpZXdDaGFpblN0YXRlOwotCi0gICAgLyoqCi0gICAgICogQWN0dWFsIG51bWJlciBvZiBidWNrZXRzIGluIHRoZSB0YWJsZSB2aWV3LgotICAgICAqLwotICAgIHByb3RlY3RlZCBpbnQgZlRhYmxlVmlld0J1Y2tldHM7Ci0KLSAgICAvKioKLSAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGUgdGFibGUgdmlldyBjb250YWlucyBjb25zaXN0ZW50IGRhdGEuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZklzVGFibGVWaWV3Q29uc2lzdGVudDsKLQotICAgIC8qKgotICAgICAqIEFycmF5IG9mIHJhbmRvbWx5IHNlbGVjdGVkIGhhc2ggZnVuY3Rpb24gbXVsdGlwbGllcnMgb3IgPGNvZGU+bnVsbDwvY29kZT4KLSAgICAgKiBpZiB0aGUgZGVmYXVsdCBTdHJpbmcuaGFzaENvZGUoKSBmdW5jdGlvbiBzaG91bGQgYmUgdXNlZC4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgaW50W10gZkhhc2hNdWx0aXBsaWVyczsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKiBEZWZhdWx0IGNvbnN0cnVjdG9yLiAqLwotICAgIHB1YmxpYyBYTUxBdHRyaWJ1dGVzSW1wbCgpIHsKLSAgICAgICAgdGhpcyhUQUJMRV9TSVpFKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAcGFyYW0gdGFibGVTaXplIGluaXRpYWwgc2l6ZSBvZiB0YWJsZSB2aWV3Ci0gICAgICovCi0gICAgcHVibGljIFhNTEF0dHJpYnV0ZXNJbXBsKGludCB0YWJsZVNpemUpIHsKLSAgICAgICAgZlRhYmxlVmlld0J1Y2tldHMgPSB0YWJsZVNpemU7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZkF0dHJpYnV0ZXMubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgIGZBdHRyaWJ1dGVzW2ldID0gbmV3IEF0dHJpYnV0ZSgpOwotICAgICAgICB9Ci0gICAgfSAvLyA8aW5pdD4oKQotCi0gICAgLy8KLSAgICAvLyBQdWJsaWMgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBTZXRzIHdoZXRoZXIgbmFtZXNwYWNlIHByb2Nlc3NpbmcgaXMgYmVpbmcgcGVyZm9ybWVkLiBUaGlzIHN0YXRlCi0gICAgICogaXMgbmVlZGVkIHRvIHJldHVybiB0aGUgY29ycmVjdCB2YWx1ZSBmcm9tIHRoZSBnZXRMb2NhbE5hbWUgbWV0aG9kLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWVzcGFjZXMgVHJ1ZSBpZiBuYW1lc3BhY2UgcHJvY2Vzc2luZyBpcyB0dXJuZWQgb24uCi0gICAgICoKLSAgICAgKiBAc2VlICNnZXRMb2NhbE5hbWUKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXROYW1lc3BhY2VzKGJvb2xlYW4gbmFtZXNwYWNlcykgewotICAgICAgICBmTmFtZXNwYWNlcyA9IG5hbWVzcGFjZXM7Ci0gICAgfSAvLyBzZXROYW1lc3BhY2VzKGJvb2xlYW4pCi0KLSAgICAvLwotICAgIC8vIFhNTEF0dHJpYnV0ZXMgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBBZGRzIGFuIGF0dHJpYnV0ZS4gVGhlIGF0dHJpYnV0ZSdzIG5vbi1ub3JtYWxpemVkIHZhbHVlIG9mIHRoZQotICAgICAqIGF0dHJpYnV0ZSB3aWxsIGhhdmUgdGhlIHNhbWUgdmFsdWUgYXMgdGhlIGF0dHJpYnV0ZSB2YWx1ZSB1bnRpbAotICAgICAqIHNldCB1c2luZyB0aGUgPGNvZGU+c2V0Tm9uTm9ybWFsaXplZFZhbHVlPC9jb2RlPiBtZXRob2QuIEFsc28sCi0gICAgICogdGhlIGFkZGVkIGF0dHJpYnV0ZSB3aWxsIGJlIG1hcmtlZCBhcyBzcGVjaWZpZWQgaW4gdGhlIFhNTCBpbnN0YW5jZQotICAgICAqIGRvY3VtZW50IHVubGVzcyBzZXQgb3RoZXJ3aXNlIHVzaW5nIHRoZSA8Y29kZT5zZXRTcGVjaWZpZWQ8L2NvZGU+Ci0gICAgICogbWV0aG9kLgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gSWYgYW4gYXR0cmlidXRlIG9mIHRoZSBzYW1lIG5hbWUgYWxyZWFkeQotICAgICAqIGV4aXN0cywgdGhlIG9sZCB2YWx1ZXMgZm9yIHRoZSBhdHRyaWJ1dGUgYXJlIHJlcGxhY2VkIGJ5IHRoZSBuZXcKLSAgICAgKiB2YWx1ZXMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSAgVGhlIGF0dHJpYnV0ZSBuYW1lLgotICAgICAqIEBwYXJhbSB0eXBlICBUaGUgYXR0cmlidXRlIHR5cGUuIFRoZSB0eXBlIG5hbWUgaXMgZGV0ZXJtaW5lZCBieQotICAgICAqICAgICAgICAgICAgICAgICAgdGhlIHR5cGUgc3BlY2lmaWVkIGZvciB0aGlzIGF0dHJpYnV0ZSBpbiB0aGUgRFRELgotICAgICAqICAgICAgICAgICAgICAgICAgRm9yIGV4YW1wbGU6ICJDREFUQSIsICJJRCIsICJOTVRPS0VOIiwgZXRjLiBIb3dldmVyLAotICAgICAqICAgICAgICAgICAgICAgICAgYXR0cmlidXRlcyBvZiB0eXBlIGVudW1lcmF0aW9uIHdpbGwgaGF2ZSB0aGUgdHlwZQotICAgICAqICAgICAgICAgICAgICAgICAgdmFsdWUgc3BlY2lmaWVkIGFzIHRoZSBwaXBlICgnfCcpIHNlcGFyYXRlZCBsaXN0IG9mCi0gICAgICogICAgICAgICAgICAgICAgICB0aGUgZW51bWVyYXRpb24gdmFsdWVzIHByZWZpeGVkIGJ5IGFuIG9wZW4KLSAgICAgKiAgICAgICAgICAgICAgICAgIHBhcmVudGhlc2lzIGFuZCBzdWZmaXhlZCBieSBhIGNsb3NlIHBhcmVudGhlc2lzLgotICAgICAqICAgICAgICAgICAgICAgICAgRm9yIGV4YW1wbGU6ICIodHJ1ZXxmYWxzZSkiLgotICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYXR0cmlidXRlIHZhbHVlLgotICAgICAqCi0gICAgICogQHJldHVybiBSZXR1cm5zIHRoZSBhdHRyaWJ1dGUgaW5kZXguCi0gICAgICoKLSAgICAgKiBAc2VlICNzZXROb25Ob3JtYWxpemVkVmFsdWUKLSAgICAgKiBAc2VlICNzZXRTcGVjaWZpZWQKLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGFkZEF0dHJpYnV0ZShRTmFtZSBuYW1lLCBTdHJpbmcgdHlwZSwgU3RyaW5nIHZhbHVlKSB7Ci0gICAgICByZXR1cm4gYWRkQXR0cmlidXRlKG5hbWUsdHlwZSx2YWx1ZSxudWxsKTsKLSAgICB9Ci0gICAgcHVibGljIGludCBhZGRBdHRyaWJ1dGUoUU5hbWUgbmFtZSwgU3RyaW5nIHR5cGUsIFN0cmluZyB2YWx1ZSxYTUxTdHJpbmcgdmFsdWVDYWNoZSkgewotCi0gICAgICAgIGludCBpbmRleDsKLSAgICAgICAgaWYgKGZMZW5ndGggPCBTSVpFX0xJTUlUKSB7Ci0gICAgICAgICAgICBpbmRleCA9IG5hbWUudXJpICE9IG51bGwgJiYgIW5hbWUudXJpLmVxdWFscygiIikKLSAgICAgICAgICAgICAgICA/IGdldEluZGV4RmFzdChuYW1lLnVyaSwgbmFtZS5sb2NhbHBhcnQpCi0gICAgICAgICAgICAgICAgOiBnZXRJbmRleEZhc3QobmFtZS5yYXduYW1lKTsKLQotICAgICAgICAgICAgaWYgKGluZGV4ID09IC0xKSB7Ci0gICAgICAgICAgICAgICAgaW5kZXggPSBmTGVuZ3RoOwotICAgICAgICAgICAgICAgIGlmIChmTGVuZ3RoKysgPT0gZkF0dHJpYnV0ZXMubGVuZ3RoKSB7Ci0gICAgICAgICAgICAgICAgICAgIEF0dHJpYnV0ZVtdIGF0dHJpYnV0ZXMgPSBuZXcgQXR0cmlidXRlW2ZBdHRyaWJ1dGVzLmxlbmd0aCArIDRdOwotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGZBdHRyaWJ1dGVzLCAwLCBhdHRyaWJ1dGVzLCAwLCBmQXR0cmlidXRlcy5sZW5ndGgpOwotICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gZkF0dHJpYnV0ZXMubGVuZ3RoOyBpIDwgYXR0cmlidXRlcy5sZW5ndGg7IGkrKykgewotICAgICAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlc1tpXSA9IG5ldyBBdHRyaWJ1dGUoKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBmQXR0cmlidXRlcyA9IGF0dHJpYnV0ZXM7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKG5hbWUudXJpID09IG51bGwgfHwKLSAgICAgICAgICAgIG5hbWUudXJpLmxlbmd0aCgpID09IDAgfHwKLSAgICAgICAgICAgIChpbmRleCA9IGdldEluZGV4RmFzdChuYW1lLnVyaSwgbmFtZS5sb2NhbHBhcnQpKSA9PSAtMSkgewotCi0gICAgICAgICAgICAvKioKLSAgICAgICAgICAgICAqIElmIGF0dHJpYnV0ZXMgd2VyZSByZW1vdmVkIGZyb20gdGhlIGxpc3QgYWZ0ZXIgdGhlIHRhYmxlCi0gICAgICAgICAgICAgKiBiZWNvbWVzIGluIHVzZSB0aGlzIGlzbid0IHJlZmxlY3RlZCBpbiB0aGUgdGFibGUgdmlldy4gSXQncwotICAgICAgICAgICAgICogYXNzdW1lZCB0aGF0IG9uY2UgYSB1c2VyIHN0YXJ0cyByZW1vdmluZyBhdHRyaWJ1dGVzIHRoZXkncmUKLSAgICAgICAgICAgICAqIG5vdCBsaWtlbHkgdG8gYWRkIG1vcmUuIFdlIG9ubHkgbWFrZSB0aGUgdmlldyBjb25zaXN0ZW50IGlmCi0gICAgICAgICAgICAgKiB0aGUgdXNlciBvZiB0aGlzIGNsYXNzIGFkZHMgYXR0cmlidXRlcywgcmVtb3ZlcyB0aGVtLCBhbmQKLSAgICAgICAgICAgICAqIHRoZW4gYWRkcyBtb3JlLgotICAgICAgICAgICAgICovCi0gICAgICAgICAgICBpZiAoIWZJc1RhYmxlVmlld0NvbnNpc3RlbnQgfHwgZkxlbmd0aCA9PSBTSVpFX0xJTUlUIHx8Ci0gICAgICAgICAgICAgICAgKGZMZW5ndGggPiBTSVpFX0xJTUlUICYmIGZMZW5ndGggPiBmVGFibGVWaWV3QnVja2V0cykpIHsKLSAgICAgICAgICAgICAgICBwcmVwYXJlQW5kUG9wdWxhdGVUYWJsZVZpZXcoKTsKLSAgICAgICAgICAgICAgICBmSXNUYWJsZVZpZXdDb25zaXN0ZW50ID0gdHJ1ZTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaW50IGJ1Y2tldCA9IGdldFRhYmxlVmlld0J1Y2tldChuYW1lLnJhd25hbWUpOwotCi0gICAgICAgICAgICAvLyBUaGUgY2hhaW4gaXMgc3RhbGUuCi0gICAgICAgICAgICAvLyBUaGlzIG11c3QgYmUgYSB1bmlxdWUgYXR0cmlidXRlLgotICAgICAgICAgICAgaWYgKGZBdHRyaWJ1dGVUYWJsZVZpZXdDaGFpblN0YXRlW2J1Y2tldF0gIT0gZkxhcmdlQ291bnQpIHsKLSAgICAgICAgICAgICAgICBpbmRleCA9IGZMZW5ndGg7Ci0gICAgICAgICAgICAgICAgaWYgKGZMZW5ndGgrKyA9PSBmQXR0cmlidXRlcy5sZW5ndGgpIHsKLSAgICAgICAgICAgICAgICAgICAgQXR0cmlidXRlW10gYXR0cmlidXRlcyA9IG5ldyBBdHRyaWJ1dGVbZkF0dHJpYnV0ZXMubGVuZ3RoIDw8IDFdOwotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGZBdHRyaWJ1dGVzLCAwLCBhdHRyaWJ1dGVzLCAwLCBmQXR0cmlidXRlcy5sZW5ndGgpOwotICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gZkF0dHJpYnV0ZXMubGVuZ3RoOyBpIDwgYXR0cmlidXRlcy5sZW5ndGg7IGkrKykgewotICAgICAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlc1tpXSA9IG5ldyBBdHRyaWJ1dGUoKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBmQXR0cmlidXRlcyA9IGF0dHJpYnV0ZXM7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgLy8gVXBkYXRlIHRhYmxlIHZpZXcuCi0gICAgICAgICAgICAgICAgZkF0dHJpYnV0ZVRhYmxlVmlld0NoYWluU3RhdGVbYnVja2V0XSA9IGZMYXJnZUNvdW50OwotICAgICAgICAgICAgICAgIGZBdHRyaWJ1dGVzW2luZGV4XS5uZXh0ID0gbnVsbDsKLSAgICAgICAgICAgICAgICBmQXR0cmlidXRlVGFibGVWaWV3W2J1Y2tldF0gPSBmQXR0cmlidXRlc1tpbmRleF07Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyBUaGlzIGNoYWluIGlzIGFjdGl2ZS4KLSAgICAgICAgICAgIC8vIFdlIG5lZWQgdG8gY2hlY2sgaWYgYW55IG9mIHRoZSBhdHRyaWJ1dGVzIGhhcyB0aGUgc2FtZSByYXduYW1lLgotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgLy8gU2VhcmNoIHRoZSB0YWJsZS4KLSAgICAgICAgICAgICAgICBpbnQgY29sbGlzaW9uQ291bnQgPSAwOwotICAgICAgICAgICAgICAgIEF0dHJpYnV0ZSBmb3VuZCA9IGZBdHRyaWJ1dGVUYWJsZVZpZXdbYnVja2V0XTsKLSAgICAgICAgICAgICAgICB3aGlsZSAoZm91bmQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBpZiAoZm91bmQubmFtZS5yYXduYW1lID09IG5hbWUucmF3bmFtZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZm91bmQgPSBmb3VuZC5uZXh0OwotICAgICAgICAgICAgICAgICAgICArK2NvbGxpc2lvbkNvdW50OwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvLyBUaGlzIGF0dHJpYnV0ZSBpcyB1bmlxdWUuCi0gICAgICAgICAgICAgICAgaWYgKGZvdW5kID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgaW5kZXggPSBmTGVuZ3RoOwotICAgICAgICAgICAgICAgICAgICBpZiAoZkxlbmd0aCsrID09IGZBdHRyaWJ1dGVzLmxlbmd0aCkgewotICAgICAgICAgICAgICAgICAgICAgICAgQXR0cmlidXRlW10gYXR0cmlidXRlcyA9IG5ldyBBdHRyaWJ1dGVbZkF0dHJpYnV0ZXMubGVuZ3RoIDw8IDFdOwotICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShmQXR0cmlidXRlcywgMCwgYXR0cmlidXRlcywgMCwgZkF0dHJpYnV0ZXMubGVuZ3RoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSBmQXR0cmlidXRlcy5sZW5ndGg7IGkgPCBhdHRyaWJ1dGVzLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlc1tpXSA9IG5ldyBBdHRyaWJ1dGUoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGZBdHRyaWJ1dGVzID0gYXR0cmlidXRlczsKLSAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgIC8vIFNlbGVjdCBhIG5ldyBoYXNoIGZ1bmN0aW9uIGFuZCByZWhhc2ggdGhlIHRhYmxlIHZpZXcKLSAgICAgICAgICAgICAgICAgICAgLy8gaWYgdGhlIGNvbGxpc2lvbiB0aHJlc2hvbGQgaXMgZXhjZWVkZWQuCi0gICAgICAgICAgICAgICAgICAgIGlmIChjb2xsaXNpb25Db3VudCA+PSBNQVhfSEFTSF9DT0xMSVNJT05TKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGUgY3VycmVudCBhdHRyaWJ1dGUgd2lsbCBiZSBwcm9jZXNzZWQgaW4gdGhlIHJlaGFzaC4KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5lZWQgdG8gc2V0IGl0cyBuYW1lIGZpcnN0LgotICAgICAgICAgICAgICAgICAgICAgICAgZkF0dHJpYnV0ZXNbaW5kZXhdLm5hbWUuc2V0VmFsdWVzKG5hbWUpOwotICAgICAgICAgICAgICAgICAgICAgICAgcmViYWxhbmNlVGFibGVWaWV3KGZMZW5ndGgpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gVXBkYXRlIHRhYmxlIHZpZXcKLSAgICAgICAgICAgICAgICAgICAgICAgIGZBdHRyaWJ1dGVzW2luZGV4XS5uZXh0ID0gZkF0dHJpYnV0ZVRhYmxlVmlld1tidWNrZXRdOwotICAgICAgICAgICAgICAgICAgICAgICAgZkF0dHJpYnV0ZVRhYmxlVmlld1tidWNrZXRdID0gZkF0dHJpYnV0ZXNbaW5kZXhdOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIC8vIER1cGxpY2F0ZS4gV2Ugc3RpbGwgbmVlZCB0byBmaW5kIHRoZSBpbmRleC4KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgaW5kZXggPSBnZXRJbmRleEZhc3QobmFtZS5yYXduYW1lKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBzZXQgdmFsdWVzCi0gICAgICAgIEF0dHJpYnV0ZSBhdHRyaWJ1dGUgPSBmQXR0cmlidXRlc1tpbmRleF07Ci0gICAgICAgIGF0dHJpYnV0ZS5uYW1lLnNldFZhbHVlcyhuYW1lKTsKLSAgICAgICAgYXR0cmlidXRlLnR5cGUgPSB0eXBlOwotICAgICAgICBhdHRyaWJ1dGUudmFsdWUgPSB2YWx1ZTsKLSAgICAgICAgYXR0cmlidXRlLnhtbFZhbHVlID0gdmFsdWVDYWNoZTsKLSAgICAgICAgYXR0cmlidXRlLm5vbk5vcm1hbGl6ZWRWYWx1ZSA9IHZhbHVlOwotICAgICAgICBhdHRyaWJ1dGUuc3BlY2lmaWVkID0gZmFsc2U7Ci0KLSAgICAgICAgLy8gY2xlYXIgYXVnbWVudGF0aW9ucwotICAgICAgICBpZihhdHRyaWJ1dGUuYXVncyAhPSBudWxsKQotICAgICAgICAgICAgYXR0cmlidXRlLmF1Z3MucmVtb3ZlQWxsSXRlbXMoKTsKLQotICAgICAgICByZXR1cm4gaW5kZXg7Ci0KLSAgICB9IC8vIGFkZEF0dHJpYnV0ZShRTmFtZSxTdHJpbmcsWE1MU3RyaW5nKQotCi0gICAgLyoqCi0gICAgICogUmVtb3ZlcyBhbGwgb2YgdGhlIGF0dHJpYnV0ZXMuIFRoaXMgbWV0aG9kIHdpbGwgYWxzbyByZW1vdmUgYWxsCi0gICAgICogZW50aXRpZXMgYXNzb2NpYXRlZCB0byB0aGUgYXR0cmlidXRlcy4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCByZW1vdmVBbGxBdHRyaWJ1dGVzKCkgewotICAgICAgICBmTGVuZ3RoID0gMDsKLSAgICB9IC8vIHJlbW92ZUFsbEF0dHJpYnV0ZXMoKQotCi0gICAgLyoqCi0gICAgICogUmVtb3ZlcyB0aGUgYXR0cmlidXRlIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXguCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGlzIG9wZXJhdGlvbiBjaGFuZ2VzIHRoZSBpbmRleGVzIG9mIGFsbAotICAgICAqIGF0dHJpYnV0ZXMgZm9sbG93aW5nIHRoZSBhdHRyaWJ1dGUgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBhdHRySW5kZXggVGhlIGF0dHJpYnV0ZSBpbmRleC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCByZW1vdmVBdHRyaWJ1dGVBdChpbnQgYXR0ckluZGV4KSB7Ci0gICAgICAgIGZJc1RhYmxlVmlld0NvbnNpc3RlbnQgPSBmYWxzZTsKLSAgICAgICAgaWYgKGF0dHJJbmRleCA8IGZMZW5ndGggLSAxKSB7Ci0gICAgICAgICAgICBBdHRyaWJ1dGUgcmVtb3ZlZEF0dHIgPSBmQXR0cmlidXRlc1thdHRySW5kZXhdOwotICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShmQXR0cmlidXRlcywgYXR0ckluZGV4ICsgMSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkF0dHJpYnV0ZXMsIGF0dHJJbmRleCwgZkxlbmd0aCAtIGF0dHJJbmRleCAtIDEpOwotICAgICAgICAgICAgLy8gTWFrZSB0aGUgZGlzY2FyZGVkIEF0dHJpYnV0ZSBvYmplY3QgYXZhaWxhYmxlIGZvciByZS11c2UKLSAgICAgICAgICAgIC8vIGJ5IHR1Y2tpbmcgaXQgYWZ0ZXIgdGhlIEF0dHJpYnV0ZXMgdGhhdCBhcmUgc3RpbGwgaW4gdXNlCi0gICAgICAgICAgICBmQXR0cmlidXRlc1tmTGVuZ3RoLTFdID0gcmVtb3ZlZEF0dHI7Ci0gICAgICAgIH0KLSAgICAgICAgZkxlbmd0aC0tOwotICAgIH0gLy8gcmVtb3ZlQXR0cmlidXRlQXQoaW50KQotCi0gICAgLyoqCi0gICAgICogU2V0cyB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXguCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYXR0ckluZGV4IFRoZSBhdHRyaWJ1dGUgaW5kZXguCi0gICAgICogQHBhcmFtIGF0dHJOYW1lICBUaGUgbmV3IGF0dHJpYnV0ZSBuYW1lLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldE5hbWUoaW50IGF0dHJJbmRleCwgUU5hbWUgYXR0ck5hbWUpIHsKLSAgICAgICAgZkF0dHJpYnV0ZXNbYXR0ckluZGV4XS5uYW1lLnNldFZhbHVlcyhhdHRyTmFtZSk7Ci0gICAgfSAvLyBzZXROYW1lKGludCxRTmFtZSkKLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIGZpZWxkcyBpbiB0aGUgZ2l2ZW4gUU5hbWUgc3RydWN0dXJlIHdpdGggdGhlIHZhbHVlcwotICAgICAqIG9mIHRoZSBhdHRyaWJ1dGUgbmFtZSBhdCB0aGUgc3BlY2lmaWVkIGluZGV4LgotICAgICAqCi0gICAgICogQHBhcmFtIGF0dHJJbmRleCBUaGUgYXR0cmlidXRlIGluZGV4LgotICAgICAqIEBwYXJhbSBhdHRyTmFtZSAgVGhlIGF0dHJpYnV0ZSBuYW1lIHN0cnVjdHVyZSB0byBmaWxsIGluLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGdldE5hbWUoaW50IGF0dHJJbmRleCwgUU5hbWUgYXR0ck5hbWUpIHsKLSAgICAgICAgYXR0ck5hbWUuc2V0VmFsdWVzKGZBdHRyaWJ1dGVzW2F0dHJJbmRleF0ubmFtZSk7Ci0gICAgfSAvLyBnZXROYW1lKGludCxRTmFtZSkKLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIHR5cGUgb2YgdGhlIGF0dHJpYnV0ZSBhdCB0aGUgc3BlY2lmaWVkIGluZGV4LgotICAgICAqCi0gICAgICogQHBhcmFtIGF0dHJJbmRleCBUaGUgYXR0cmlidXRlIGluZGV4LgotICAgICAqIEBwYXJhbSBhdHRyVHlwZSAgVGhlIGF0dHJpYnV0ZSB0eXBlLiBUaGUgdHlwZSBuYW1lIGlzIGRldGVybWluZWQgYnkKLSAgICAgKiAgICAgICAgICAgICAgICAgIHRoZSB0eXBlIHNwZWNpZmllZCBmb3IgdGhpcyBhdHRyaWJ1dGUgaW4gdGhlIERURC4KLSAgICAgKiAgICAgICAgICAgICAgICAgIEZvciBleGFtcGxlOiAiQ0RBVEEiLCAiSUQiLCAiTk1UT0tFTiIsIGV0Yy4gSG93ZXZlciwKLSAgICAgKiAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXMgb2YgdHlwZSBlbnVtZXJhdGlvbiB3aWxsIGhhdmUgdGhlIHR5cGUKLSAgICAgKiAgICAgICAgICAgICAgICAgIHZhbHVlIHNwZWNpZmllZCBhcyB0aGUgcGlwZSAoJ3wnKSBzZXBhcmF0ZWQgbGlzdCBvZgotICAgICAqICAgICAgICAgICAgICAgICAgdGhlIGVudW1lcmF0aW9uIHZhbHVlcyBwcmVmaXhlZCBieSBhbiBvcGVuCi0gICAgICogICAgICAgICAgICAgICAgICBwYXJlbnRoZXNpcyBhbmQgc3VmZml4ZWQgYnkgYSBjbG9zZSBwYXJlbnRoZXNpcy4KLSAgICAgKiAgICAgICAgICAgICAgICAgIEZvciBleGFtcGxlOiAiKHRydWV8ZmFsc2UpIi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRUeXBlKGludCBhdHRySW5kZXgsIFN0cmluZyBhdHRyVHlwZSkgewotICAgICAgICBmQXR0cmlidXRlc1thdHRySW5kZXhdLnR5cGUgPSBhdHRyVHlwZTsKLSAgICB9IC8vIHNldFR5cGUoaW50LFN0cmluZykKLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4gVGhpcwotICAgICAqIG1ldGhvZCB3aWxsIG92ZXJ3cml0ZSB0aGUgbm9uLW5vcm1hbGl6ZWQgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBhdHRySW5kZXggVGhlIGF0dHJpYnV0ZSBpbmRleC4KLSAgICAgKiBAcGFyYW0gYXR0clZhbHVlIFRoZSBuZXcgYXR0cmlidXRlIHZhbHVlLgotICAgICAqCi0gICAgICogQHNlZSAjc2V0Tm9uTm9ybWFsaXplZFZhbHVlCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0VmFsdWUoaW50IGF0dHJJbmRleCwgU3RyaW5nIGF0dHJWYWx1ZSkgewotICAgICAgICBzZXRWYWx1ZShhdHRySW5kZXgsYXR0clZhbHVlLG51bGwpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldFZhbHVlKGludCBhdHRySW5kZXgsIFN0cmluZyBhdHRyVmFsdWUsWE1MU3RyaW5nIHZhbHVlKSB7Ci0gICAgICAgIEF0dHJpYnV0ZSBhdHRyaWJ1dGUgPSBmQXR0cmlidXRlc1thdHRySW5kZXhdOwotICAgICAgICBhdHRyaWJ1dGUudmFsdWUgPSBhdHRyVmFsdWU7Ci0gICAgICAgIGF0dHJpYnV0ZS5ub25Ob3JtYWxpemVkVmFsdWUgPSBhdHRyVmFsdWU7Ci0gICAgICAgIGF0dHJpYnV0ZS54bWxWYWx1ZSA9IHZhbHVlOwotICAgIH0gLy8gc2V0VmFsdWUoaW50LFN0cmluZykKLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIG5vbi1ub3JtYWxpemVkIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUgYXQgdGhlIHNwZWNpZmllZAotICAgICAqIGluZGV4LgotICAgICAqCi0gICAgICogQHBhcmFtIGF0dHJJbmRleCBUaGUgYXR0cmlidXRlIGluZGV4LgotICAgICAqIEBwYXJhbSBhdHRyVmFsdWUgVGhlIG5ldyBub24tbm9ybWFsaXplZCBhdHRyaWJ1dGUgdmFsdWUuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0Tm9uTm9ybWFsaXplZFZhbHVlKGludCBhdHRySW5kZXgsIFN0cmluZyBhdHRyVmFsdWUpIHsKLSAgICAgICAgaWYgKGF0dHJWYWx1ZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBhdHRyVmFsdWUgPSBmQXR0cmlidXRlc1thdHRySW5kZXhdLnZhbHVlOwotICAgICAgICB9Ci0gICAgICAgIGZBdHRyaWJ1dGVzW2F0dHJJbmRleF0ubm9uTm9ybWFsaXplZFZhbHVlID0gYXR0clZhbHVlOwotICAgIH0gLy8gc2V0Tm9uTm9ybWFsaXplZFZhbHVlKGludCxTdHJpbmcpCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBub24tbm9ybWFsaXplZCB2YWx1ZSBvZiB0aGUgYXR0cmlidXRlIGF0IHRoZSBzcGVjaWZpZWQKLSAgICAgKiBpbmRleC4gSWYgbm8gbm9uLW5vcm1hbGl6ZWQgdmFsdWUgaXMgc2V0LCB0aGlzIG1ldGhvZCB3aWxsIHJldHVybgotICAgICAqIHRoZSBzYW1lIHZhbHVlIGFzIHRoZSA8Y29kZT5nZXRWYWx1ZShpbnQpPC9jb2RlPiBtZXRob2QuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYXR0ckluZGV4IFRoZSBhdHRyaWJ1dGUgaW5kZXguCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXROb25Ob3JtYWxpemVkVmFsdWUoaW50IGF0dHJJbmRleCkgewotICAgICAgICBTdHJpbmcgdmFsdWUgPSBmQXR0cmlidXRlc1thdHRySW5kZXhdLm5vbk5vcm1hbGl6ZWRWYWx1ZTsKLSAgICAgICAgcmV0dXJuIHZhbHVlOwotICAgIH0gLy8gZ2V0Tm9uTm9ybWFsaXplZFZhbHVlKGludCk6U3RyaW5nCi0KLSAgICAvKioKLSAgICAgKiBTZXRzIHdoZXRoZXIgYW4gYXR0cmlidXRlIGlzIHNwZWNpZmllZCBpbiB0aGUgaW5zdGFuY2UgZG9jdW1lbnQKLSAgICAgKiBvciBub3QuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYXR0ckluZGV4IFRoZSBhdHRyaWJ1dGUgaW5kZXguCi0gICAgICogQHBhcmFtIHNwZWNpZmllZCBUcnVlIGlmIHRoZSBhdHRyaWJ1dGUgaXMgc3BlY2lmaWVkIGluIHRoZSBpbnN0YW5jZQotICAgICAqICAgICAgICAgICAgICAgICAgZG9jdW1lbnQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0U3BlY2lmaWVkKGludCBhdHRySW5kZXgsIGJvb2xlYW4gc3BlY2lmaWVkKSB7Ci0gICAgICAgIGZBdHRyaWJ1dGVzW2F0dHJJbmRleF0uc3BlY2lmaWVkID0gc3BlY2lmaWVkOwotICAgIH0gLy8gc2V0U3BlY2lmaWVkKGludCxib29sZWFuKQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBhdHRyaWJ1dGUgaXMgc3BlY2lmaWVkIGluIHRoZSBpbnN0YW5jZSBkb2N1bWVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBhdHRySW5kZXggVGhlIGF0dHJpYnV0ZSBpbmRleC4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc1NwZWNpZmllZChpbnQgYXR0ckluZGV4KSB7Ci0gICAgICAgIHJldHVybiBmQXR0cmlidXRlc1thdHRySW5kZXhdLnNwZWNpZmllZDsKLSAgICB9IC8vIGlzU3BlY2lmaWVkKGludCk6Ym9vbGVhbgotCi0gICAgLy8KLSAgICAvLyBBdHRyaWJ1dGVMaXN0IGFuZCBBdHRyaWJ1dGVzIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSBudW1iZXIgb2YgYXR0cmlidXRlcyBpbiB0aGUgbGlzdC4KLSAgICAgKgotICAgICAqIDxwPk9uY2UgeW91IGtub3cgdGhlIG51bWJlciBvZiBhdHRyaWJ1dGVzLCB5b3UgY2FuIGl0ZXJhdGUKLSAgICAgKiB0aHJvdWdoIHRoZSBsaXN0LjwvcD4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIG51bWJlciBvZiBhdHRyaWJ1dGVzIGluIHRoZSBsaXN0LgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0TGVuZ3RoKCkgewotICAgICAgICByZXR1cm4gZkxlbmd0aDsKLSAgICB9IC8vIGdldExlbmd0aCgpOmludAotCi0gICAgLyoqCi0gICAgICogTG9vayB1cCBhbiBhdHRyaWJ1dGUncyB0eXBlIGJ5IGluZGV4LgotICAgICAqCi0gICAgICogPHA+VGhlIGF0dHJpYnV0ZSB0eXBlIGlzIG9uZSBvZiB0aGUgc3RyaW5ncyAiQ0RBVEEiLCAiSUQiLAotICAgICAqICJJRFJFRiIsICJJRFJFRlMiLCAiTk1UT0tFTiIsICJOTVRPS0VOUyIsICJFTlRJVFkiLCAiRU5USVRJRVMiLAotICAgICAqIG9yICJOT1RBVElPTiIgKGFsd2F5cyBpbiB1cHBlciBjYXNlKS48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5JZiB0aGUgcGFyc2VyIGhhcyBub3QgcmVhZCBhIGRlY2xhcmF0aW9uIGZvciB0aGUgYXR0cmlidXRlLAotICAgICAqIG9yIGlmIHRoZSBwYXJzZXIgZG9lcyBub3QgcmVwb3J0IGF0dHJpYnV0ZSB0eXBlcywgdGhlbiBpdCBtdXN0Ci0gICAgICogcmV0dXJuIHRoZSB2YWx1ZSAiQ0RBVEEiIGFzIHN0YXRlZCBpbiB0aGUgWE1MIDEuMCBSZWNvbW1lbnRhdGlvbgotICAgICAqIChjbGF1c2UgMy4zLjMsICJBdHRyaWJ1dGUtVmFsdWUgTm9ybWFsaXphdGlvbiIpLjwvcD4KLSAgICAgKgotICAgICAqIDxwPkZvciBhbiBlbnVtZXJhdGVkIGF0dHJpYnV0ZSB0aGF0IGlzIG5vdCBhIG5vdGF0aW9uLCB0aGUKLSAgICAgKiBwYXJzZXIgd2lsbCByZXBvcnQgdGhlIHR5cGUgYXMgIk5NVE9LRU4iLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBpbmRleCBUaGUgYXR0cmlidXRlIGluZGV4ICh6ZXJvLWJhc2VkKS4KLSAgICAgKiBAcmV0dXJuIFRoZSBhdHRyaWJ1dGUncyB0eXBlIGFzIGEgc3RyaW5nLCBvciBudWxsIGlmIHRoZQotICAgICAqICAgICAgICAgaW5kZXggaXMgb3V0IG9mIHJhbmdlLgotICAgICAqIEBzZWUgI2dldExlbmd0aAotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VHlwZShpbnQgaW5kZXgpIHsKLSAgICAgICAgaWYgKGluZGV4IDwgMCB8fCBpbmRleCA+PSBmTGVuZ3RoKSB7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZ2V0UmVwb3J0YWJsZVR5cGUoZkF0dHJpYnV0ZXNbaW5kZXhdLnR5cGUpOwotICAgIH0gLy8gZ2V0VHlwZShpbnQpOlN0cmluZwotCi0gICAgLyoqCi0gICAgICogTG9vayB1cCBhbiBhdHRyaWJ1dGUncyB0eXBlIGJ5IFhNTCAxLjAgcXVhbGlmaWVkIG5hbWUuCi0gICAgICoKLSAgICAgKiA8cD5TZWUge0BsaW5rICNnZXRUeXBlKGludCkgZ2V0VHlwZShpbnQpfSBmb3IgYSBkZXNjcmlwdGlvbgotICAgICAqIG9mIHRoZSBwb3NzaWJsZSB0eXBlcy48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gcW5hbWUgVGhlIFhNTCAxLjAgcXVhbGlmaWVkIG5hbWUuCi0gICAgICogQHJldHVybiBUaGUgYXR0cmlidXRlIHR5cGUgYXMgYSBzdHJpbmcsIG9yIG51bGwgaWYgdGhlCi0gICAgICogICAgICAgICBhdHRyaWJ1dGUgaXMgbm90IGluIHRoZSBsaXN0IG9yIGlmIHF1YWxpZmllZCBuYW1lcwotICAgICAqICAgICAgICAgYXJlIG5vdCBhdmFpbGFibGUuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRUeXBlKFN0cmluZyBxbmFtZSkgewotICAgICAgICBpbnQgaW5kZXggPSBnZXRJbmRleChxbmFtZSk7Ci0gICAgICAgIHJldHVybiBpbmRleCAhPSAtMSA/IGdldFJlcG9ydGFibGVUeXBlKGZBdHRyaWJ1dGVzW2luZGV4XS50eXBlKSA6IG51bGw7Ci0gICAgfSAvLyBnZXRUeXBlKFN0cmluZyk6U3RyaW5nCi0KLSAgICAvKioKLSAgICAgKiBMb29rIHVwIGFuIGF0dHJpYnV0ZSdzIHZhbHVlIGJ5IGluZGV4LgotICAgICAqCi0gICAgICogPHA+SWYgdGhlIGF0dHJpYnV0ZSB2YWx1ZSBpcyBhIGxpc3Qgb2YgdG9rZW5zIChJRFJFRlMsCi0gICAgICogRU5USVRJRVMsIG9yIE5NVE9LRU5TKSwgdGhlIHRva2VucyB3aWxsIGJlIGNvbmNhdGVuYXRlZAotICAgICAqIGludG8gYSBzaW5nbGUgc3RyaW5nIHdpdGggZWFjaCB0b2tlbiBzZXBhcmF0ZWQgYnkgYQotICAgICAqIHNpbmdsZSBzcGFjZS48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGF0dHJpYnV0ZSBpbmRleCAoemVyby1iYXNlZCkuCi0gICAgICogQHJldHVybiBUaGUgYXR0cmlidXRlJ3MgdmFsdWUgYXMgYSBzdHJpbmcsIG9yIG51bGwgaWYgdGhlCi0gICAgICogICAgICAgICBpbmRleCBpcyBvdXQgb2YgcmFuZ2UuCi0gICAgICogQHNlZSAjZ2V0TGVuZ3RoCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRWYWx1ZShpbnQgaW5kZXgpIHsKLSAgICAgICAgaWYgKGluZGV4IDwgMCB8fCBpbmRleCA+PSBmTGVuZ3RoKSB7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotICAgICAgICBpZihmQXR0cmlidXRlc1tpbmRleF0udmFsdWUgPT0gbnVsbCAmJiBmQXR0cmlidXRlc1tpbmRleF0ueG1sVmFsdWUgIT0gbnVsbCkKLSAgICAgICAgICAgIGZBdHRyaWJ1dGVzW2luZGV4XS52YWx1ZSA9IGZBdHRyaWJ1dGVzW2luZGV4XS54bWxWYWx1ZS50b1N0cmluZygpOwotICAgICAgICByZXR1cm4gZkF0dHJpYnV0ZXNbaW5kZXhdLnZhbHVlOwotICAgIH0gLy8gZ2V0VmFsdWUoaW50KTpTdHJpbmcKLQotICAgIC8qKgotICAgICAqIExvb2sgdXAgYW4gYXR0cmlidXRlJ3MgdmFsdWUgYnkgWE1MIDEuMCBxdWFsaWZpZWQgbmFtZS4KLSAgICAgKgotICAgICAqIDxwPlNlZSB7QGxpbmsgI2dldFZhbHVlKGludCkgZ2V0VmFsdWUoaW50KX0gZm9yIGEgZGVzY3JpcHRpb24KLSAgICAgKiBvZiB0aGUgcG9zc2libGUgdmFsdWVzLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBxbmFtZSBUaGUgWE1MIDEuMCBxdWFsaWZpZWQgbmFtZS4KLSAgICAgKiBAcmV0dXJuIFRoZSBhdHRyaWJ1dGUgdmFsdWUgYXMgYSBzdHJpbmcsIG9yIG51bGwgaWYgdGhlCi0gICAgICogICAgICAgICBhdHRyaWJ1dGUgaXMgbm90IGluIHRoZSBsaXN0IG9yIGlmIHF1YWxpZmllZCBuYW1lcwotICAgICAqICAgICAgICAgYXJlIG5vdCBhdmFpbGFibGUuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRWYWx1ZShTdHJpbmcgcW5hbWUpIHsKLSAgICAgICAgaW50IGluZGV4ID0gZ2V0SW5kZXgocW5hbWUpOwotICAgICAgICBpZihpbmRleCA9PSAtMSApCi0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgaWYoZkF0dHJpYnV0ZXNbaW5kZXhdLnZhbHVlID09IG51bGwpCi0gICAgICAgICAgICBmQXR0cmlidXRlc1tpbmRleF0udmFsdWUgPSBmQXR0cmlidXRlc1tpbmRleF0ueG1sVmFsdWUudG9TdHJpbmcoKTsKLSAgICAgICAgcmV0dXJuIGZBdHRyaWJ1dGVzW2luZGV4XS52YWx1ZTsKLSAgICB9IC8vIGdldFZhbHVlKFN0cmluZyk6U3RyaW5nCi0KLSAgICAvLwotICAgIC8vIEF0dHJpYnV0ZUxpc3QgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIG5hbWUgb2YgYW4gYXR0cmlidXRlIGluIHRoaXMgbGlzdCAoYnkgcG9zaXRpb24pLgotICAgICAqCi0gICAgICogPHA+VGhlIG5hbWVzIG11c3QgYmUgdW5pcXVlOiB0aGUgU0FYIHBhcnNlciBzaGFsbCBub3QgaW5jbHVkZSB0aGUKLSAgICAgKiBzYW1lIGF0dHJpYnV0ZSB0d2ljZS4gIEF0dHJpYnV0ZXMgd2l0aG91dCB2YWx1ZXMgKHRob3NlIGRlY2xhcmVkCi0gICAgICogI0lNUExJRUQgd2l0aG91dCBhIHZhbHVlIHNwZWNpZmllZCBpbiB0aGUgc3RhcnQgdGFnKSB3aWxsIGJlCi0gICAgICogb21pdHRlZCBmcm9tIHRoZSBsaXN0LjwvcD4KLSAgICAgKgotICAgICAqIDxwPklmIHRoZSBhdHRyaWJ1dGUgbmFtZSBoYXMgYSBuYW1lc3BhY2UgcHJlZml4LCB0aGUgcHJlZml4Ci0gICAgICogd2lsbCBzdGlsbCBiZSBhdHRhY2hlZC48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gaSBUaGUgaW5kZXggb2YgdGhlIGF0dHJpYnV0ZSBpbiB0aGUgbGlzdCAoc3RhcnRpbmcgYXQgMCkuCi0gICAgICogQHJldHVybiBUaGUgbmFtZSBvZiB0aGUgaW5kZXhlZCBhdHRyaWJ1dGUsIG9yIG51bGwKLSAgICAgKiAgICAgICAgIGlmIHRoZSBpbmRleCBpcyBvdXQgb2YgcmFuZ2UuCi0gICAgICogQHNlZSAjZ2V0TGVuZ3RoCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXROYW1lKGludCBpbmRleCkgewotICAgICAgICBpZiAoaW5kZXggPCAwIHx8IGluZGV4ID49IGZMZW5ndGgpIHsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmQXR0cmlidXRlc1tpbmRleF0ubmFtZS5yYXduYW1lOwotICAgIH0gLy8gZ2V0TmFtZShpbnQpOlN0cmluZwotCi0gICAgLy8KLSAgICAvLyBBdHRyaWJ1dGVzIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogTG9vayB1cCB0aGUgaW5kZXggb2YgYW4gYXR0cmlidXRlIGJ5IFhNTCAxLjAgcXVhbGlmaWVkIG5hbWUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcU5hbWUgVGhlIHF1YWxpZmllZCAocHJlZml4ZWQpIG5hbWUuCi0gICAgICogQHJldHVybiBUaGUgaW5kZXggb2YgdGhlIGF0dHJpYnV0ZSwgb3IgLTEgaWYgaXQgZG9lcyBub3QKLSAgICAgKiAgICAgICAgIGFwcGVhciBpbiB0aGUgbGlzdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldEluZGV4KFN0cmluZyBxTmFtZSkgewotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZMZW5ndGg7IGkrKykgewotICAgICAgICAgICAgQXR0cmlidXRlIGF0dHJpYnV0ZSA9IGZBdHRyaWJ1dGVzW2ldOwotICAgICAgICAgICAgaWYgKGF0dHJpYnV0ZS5uYW1lLnJhd25hbWUgIT0gbnVsbCAmJgotICAgICAgICAgICAgICAgIGF0dHJpYnV0ZS5uYW1lLnJhd25hbWUuZXF1YWxzKHFOYW1lKSkgewotICAgICAgICAgICAgICAgIHJldHVybiBpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiAtMTsKLSAgICB9IC8vIGdldEluZGV4KFN0cmluZyk6aW50Ci0KLSAgICAvKioKLSAgICAgKiBMb29rIHVwIHRoZSBpbmRleCBvZiBhbiBhdHRyaWJ1dGUgYnkgTmFtZXNwYWNlIG5hbWUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdXJpIFRoZSBOYW1lc3BhY2UgVVJJLCBvciBudWxsIGlmCi0gICAgICogICAgICAgIHRoZSBuYW1lIGhhcyBubyBOYW1lc3BhY2UgVVJJLgotICAgICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGF0dHJpYnV0ZSdzIGxvY2FsIG5hbWUuCi0gICAgICogQHJldHVybiBUaGUgaW5kZXggb2YgdGhlIGF0dHJpYnV0ZSwgb3IgLTEgaWYgaXQgZG9lcyBub3QKLSAgICAgKiAgICAgICAgIGFwcGVhciBpbiB0aGUgbGlzdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldEluZGV4KFN0cmluZyB1cmksIFN0cmluZyBsb2NhbFBhcnQpIHsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmTGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgIEF0dHJpYnV0ZSBhdHRyaWJ1dGUgPSBmQXR0cmlidXRlc1tpXTsKLSAgICAgICAgICAgIGlmIChhdHRyaWJ1dGUubmFtZS5sb2NhbHBhcnQgIT0gbnVsbCAmJgotICAgICAgICAgICAgICAgIGF0dHJpYnV0ZS5uYW1lLmxvY2FscGFydC5lcXVhbHMobG9jYWxQYXJ0KSAmJgotICAgICAgICAgICAgICAgICgodXJpPT1hdHRyaWJ1dGUubmFtZS51cmkpIHx8Ci0gICAgICAgICAgICAodXJpIT1udWxsICYmIGF0dHJpYnV0ZS5uYW1lLnVyaSE9bnVsbCAmJiBhdHRyaWJ1dGUubmFtZS51cmkuZXF1YWxzKHVyaSkpKSkgewotICAgICAgICAgICAgICAgIHJldHVybiBpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiAtMTsKLSAgICB9IC8vIGdldEluZGV4KFN0cmluZyxTdHJpbmcpOmludAotCi0gICAgLyoqCi0gICAgICogTG9vayB1cCB0aGUgaW5kZXggb2YgYW4gYXR0cmlidXRlIGJ5IGxvY2FsIG5hbWUgb25seSwKLSAgICAgKiBpZ25vcmluZyBpdHMgbmFtZXNwYWNlLgotICAgICAqCi0gICAgICogQHBhcmFtIGxvY2FsTmFtZSBUaGUgYXR0cmlidXRlJ3MgbG9jYWwgbmFtZS4KLSAgICAgKiBAcmV0dXJuIFRoZSBpbmRleCBvZiB0aGUgYXR0cmlidXRlLCBvciAtMSBpZiBpdCBkb2VzIG5vdAotICAgICAqICAgICAgICAgYXBwZWFyIGluIHRoZSBsaXN0LgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0SW5kZXhCeUxvY2FsTmFtZShTdHJpbmcgbG9jYWxQYXJ0KSB7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZkxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICBBdHRyaWJ1dGUgYXR0cmlidXRlID0gZkF0dHJpYnV0ZXNbaV07Ci0gICAgICAgICAgICBpZiAoYXR0cmlidXRlLm5hbWUubG9jYWxwYXJ0ICE9IG51bGwgJiYKLSAgICAgICAgICAgICAgICBhdHRyaWJ1dGUubmFtZS5sb2NhbHBhcnQuZXF1YWxzKGxvY2FsUGFydCkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gaTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gLTE7Ci0gICAgfSAvLyBnZXRJbmRleChTdHJpbmcpOmludAotCi0gICAgLyoqCi0gICAgICogTG9vayB1cCBhbiBhdHRyaWJ1dGUncyBsb2NhbCBuYW1lIGJ5IGluZGV4LgotICAgICAqCi0gICAgICogQHBhcmFtIGluZGV4IFRoZSBhdHRyaWJ1dGUgaW5kZXggKHplcm8tYmFzZWQpLgotICAgICAqIEByZXR1cm4gVGhlIGxvY2FsIG5hbWUsIG9yIHRoZSBlbXB0eSBzdHJpbmcgaWYgTmFtZXNwYWNlCi0gICAgICogICAgICAgICBwcm9jZXNzaW5nIGlzIG5vdCBiZWluZyBwZXJmb3JtZWQsIG9yIG51bGwKLSAgICAgKiAgICAgICAgIGlmIHRoZSBpbmRleCBpcyBvdXQgb2YgcmFuZ2UuCi0gICAgICogQHNlZSAjZ2V0TGVuZ3RoCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRMb2NhbE5hbWUoaW50IGluZGV4KSB7Ci0gICAgICAgIGlmICghZk5hbWVzcGFjZXMpIHsKLSAgICAgICAgICAgIHJldHVybiAiIjsKLSAgICAgICAgfQotICAgICAgICBpZiAoaW5kZXggPCAwIHx8IGluZGV4ID49IGZMZW5ndGgpIHsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmQXR0cmlidXRlc1tpbmRleF0ubmFtZS5sb2NhbHBhcnQ7Ci0gICAgfSAvLyBnZXRMb2NhbE5hbWUoaW50KTpTdHJpbmcKLQotICAgIC8qKgotICAgICAqIExvb2sgdXAgYW4gYXR0cmlidXRlJ3MgWE1MIDEuMCBxdWFsaWZpZWQgbmFtZSBieSBpbmRleC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBpbmRleCBUaGUgYXR0cmlidXRlIGluZGV4ICh6ZXJvLWJhc2VkKS4KLSAgICAgKiBAcmV0dXJuIFRoZSBYTUwgMS4wIHF1YWxpZmllZCBuYW1lLCBvciB0aGUgZW1wdHkgc3RyaW5nCi0gICAgICogICAgICAgICBpZiBub25lIGlzIGF2YWlsYWJsZSwgb3IgbnVsbCBpZiB0aGUgaW5kZXgKLSAgICAgKiAgICAgICAgIGlzIG91dCBvZiByYW5nZS4KLSAgICAgKiBAc2VlICNnZXRMZW5ndGgKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFFOYW1lKGludCBpbmRleCkgewotICAgICAgICBpZiAoaW5kZXggPCAwIHx8IGluZGV4ID49IGZMZW5ndGgpIHsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgICAgIFN0cmluZyByYXduYW1lID0gZkF0dHJpYnV0ZXNbaW5kZXhdLm5hbWUucmF3bmFtZTsKLSAgICAgICAgcmV0dXJuIHJhd25hbWUgIT0gbnVsbCA/IHJhd25hbWUgOiAiIjsKLSAgICB9IC8vIGdldFFOYW1lKGludCk6U3RyaW5nCi0KLSAgICBwdWJsaWMgUU5hbWUgZ2V0UXVhbGlmaWVkTmFtZShpbnQgaW5kZXgpewotICAgICAgICBpZiAoaW5kZXggPCAwIHx8IGluZGV4ID49IGZMZW5ndGgpIHsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmQXR0cmlidXRlc1tpbmRleF0ubmFtZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBMb29rIHVwIGFuIGF0dHJpYnV0ZSdzIHR5cGUgYnkgTmFtZXNwYWNlIG5hbWUuCi0gICAgICoKLSAgICAgKiA8cD5TZWUge0BsaW5rICNnZXRUeXBlKGludCkgZ2V0VHlwZShpbnQpfSBmb3IgYSBkZXNjcmlwdGlvbgotICAgICAqIG9mIHRoZSBwb3NzaWJsZSB0eXBlcy48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gdXJpIFRoZSBOYW1lc3BhY2UgVVJJLCBvciBudWxsIGlmIHRoZQotICAgICAqICAgICAgICBuYW1lIGhhcyBubyBOYW1lc3BhY2UgVVJJLgotICAgICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGxvY2FsIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgKiBAcmV0dXJuIFRoZSBhdHRyaWJ1dGUgdHlwZSBhcyBhIHN0cmluZywgb3IgbnVsbCBpZiB0aGUKLSAgICAgKiAgICAgICAgIGF0dHJpYnV0ZSBpcyBub3QgaW4gdGhlIGxpc3Qgb3IgaWYgTmFtZXNwYWNlCi0gICAgICogICAgICAgICBwcm9jZXNzaW5nIGlzIG5vdCBiZWluZyBwZXJmb3JtZWQuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRUeXBlKFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUpIHsKLSAgICAgICAgaWYgKCFmTmFtZXNwYWNlcykgewotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLSAgICAgICAgaW50IGluZGV4ID0gZ2V0SW5kZXgodXJpLCBsb2NhbE5hbWUpOwotICAgICAgICByZXR1cm4gaW5kZXggIT0gLTEgPyBnZXRUeXBlKGluZGV4KSA6IG51bGw7Ci0gICAgfSAvLyBnZXRUeXBlKFN0cmluZyxTdHJpbmcpOlN0cmluZwotICAgIC8qKgotICAgICAqIExvb2sgdXAgdGhlIGluZGV4IG9mIGFuIGF0dHJpYnV0ZSBieSBYTUwgMS4wIHF1YWxpZmllZCBuYW1lLgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4KLSAgICAgKiBUaGlzIG1ldGhvZCB1c2VzIHJlZmVyZW5jZSBjb21wYXJpc29uLCBhbmQgdGh1cyBzaG91bGQKLSAgICAgKiBvbmx5IGJlIHVzZWQgaW50ZXJuYWxseS4gV2UgY2Fubm90IHVzZSB0aGlzIG1ldGhvZCBpbiBhbnkKLSAgICAgKiBjb2RlIGV4cG9zZWQgdG8gdXNlcnMgYXMgdGhleSBtYXkgbm90IHBhc3MgaW4gdW5pcXVlIHN0cmluZ3MuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcU5hbWUgVGhlIHF1YWxpZmllZCAocHJlZml4ZWQpIG5hbWUuCi0gICAgICogQHJldHVybiBUaGUgaW5kZXggb2YgdGhlIGF0dHJpYnV0ZSwgb3IgLTEgaWYgaXQgZG9lcyBub3QKLSAgICAgKiAgICAgICAgIGFwcGVhciBpbiB0aGUgbGlzdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldEluZGV4RmFzdChTdHJpbmcgcU5hbWUpIHsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmTGVuZ3RoOyArK2kpIHsKLSAgICAgICAgICAgIEF0dHJpYnV0ZSBhdHRyaWJ1dGUgPSBmQXR0cmlidXRlc1tpXTsKLSAgICAgICAgICAgIGlmIChhdHRyaWJ1dGUubmFtZS5yYXduYW1lID09IHFOYW1lKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIC0xOwotICAgIH0gLy8gZ2V0SW5kZXhGYXN0KFN0cmluZyk6aW50Ci0KLSAgICAvKioKLSAgICAgKiBBZGRzIGFuIGF0dHJpYnV0ZS4gVGhlIGF0dHJpYnV0ZSdzIG5vbi1ub3JtYWxpemVkIHZhbHVlIG9mIHRoZQotICAgICAqIGF0dHJpYnV0ZSB3aWxsIGhhdmUgdGhlIHNhbWUgdmFsdWUgYXMgdGhlIGF0dHJpYnV0ZSB2YWx1ZSB1bnRpbAotICAgICAqIHNldCB1c2luZyB0aGUgPGNvZGU+c2V0Tm9uTm9ybWFsaXplZFZhbHVlPC9jb2RlPiBtZXRob2QuIEFsc28sCi0gICAgICogdGhlIGFkZGVkIGF0dHJpYnV0ZSB3aWxsIGJlIG1hcmtlZCBhcyBzcGVjaWZpZWQgaW4gdGhlIFhNTCBpbnN0YW5jZQotICAgICAqIGRvY3VtZW50IHVubGVzcyBzZXQgb3RoZXJ3aXNlIHVzaW5nIHRoZSA8Y29kZT5zZXRTcGVjaWZpZWQ8L2NvZGU+Ci0gICAgICogbWV0aG9kLgotICAgICAqIDxwPgotICAgICAqIFRoaXMgbWV0aG9kIGRpZmZlcnMgZnJvbSA8Y29kZT5hZGRBdHRyaWJ1dGU8L2NvZGU+IGluIHRoYXQgaXQKLSAgICAgKiBkb2VzIG5vdCBjaGVjayBpZiBhbiBhdHRyaWJ1dGUgb2YgdGhlIHNhbWUgbmFtZSBhbHJlYWR5IGV4aXN0cwotICAgICAqIGluIHRoZSBsaXN0IGJlZm9yZSBhZGRpbmcgaXQuIEluIG9yZGVyIHRvIGltcHJvdmUgcGVyZm9ybWFuY2UKLSAgICAgKiBvZiBuYW1lc3BhY2UgcHJvY2Vzc2luZywgdGhpcyBtZXRob2QgYWxsb3dzIHVuaXF1ZW5lc3MgY2hlY2tzCi0gICAgICogdG8gYmUgZGVmZXJyZWQgdW50aWwgYWxsIHRoZSBuYW1lc3BhY2UgaW5mb3JtYXRpb24gaXMgYXZhaWxhYmxlCi0gICAgICogYWZ0ZXIgdGhlIGVudGlyZSBhdHRyaWJ1dGUgc3BlY2lmaWNhdGlvbiBoYXMgYmVlbiByZWFkLgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Q2F1dGlvbjo8L3N0cm9uZz4gSWYgdGhpcyBtZXRob2QgaXMgY2FsbGVkIGl0IHNob3VsZAotICAgICAqIG5vdCBiZSBtaXhlZCB3aXRoIGNhbGxzIHRvIDxjb2RlPmFkZEF0dHJpYnV0ZTwvY29kZT4gdW5sZXNzCi0gICAgICogaXQgaGFzIGJlZW4gZGV0ZXJtaW5lZCB0aGF0IGFsbCB0aGUgYXR0cmlidXRlIG5hbWVzIGFyZSB1bmlxdWUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSB0aGUgYXR0cmlidXRlIG5hbWUKLSAgICAgKiBAcGFyYW0gdHlwZSB0aGUgYXR0cmlidXRlIHR5cGUKLSAgICAgKiBAcGFyYW0gdmFsdWUgdGhlIGF0dHJpYnV0ZSB2YWx1ZQotICAgICAqCi0gICAgICogQHNlZSAjc2V0Tm9uTm9ybWFsaXplZFZhbHVlCi0gICAgICogQHNlZSAjc2V0U3BlY2lmaWVkCi0gICAgICogQHNlZSAjY2hlY2tEdXBsaWNhdGVzTlMKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBhZGRBdHRyaWJ1dGVOUyhRTmFtZSBuYW1lLCBTdHJpbmcgdHlwZSwgU3RyaW5nIHZhbHVlKSB7Ci0gICAgICAgIGludCBpbmRleCA9IGZMZW5ndGg7Ci0gICAgICAgIGlmIChmTGVuZ3RoKysgPT0gZkF0dHJpYnV0ZXMubGVuZ3RoKSB7Ci0gICAgICAgICAgICBBdHRyaWJ1dGVbXSBhdHRyaWJ1dGVzOwotICAgICAgICAgICAgaWYgKGZMZW5ndGggPCBTSVpFX0xJTUlUKSB7Ci0gICAgICAgICAgICAgICAgYXR0cmlidXRlcyA9IG5ldyBBdHRyaWJ1dGVbZkF0dHJpYnV0ZXMubGVuZ3RoICsgNF07Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzID0gbmV3IEF0dHJpYnV0ZVtmQXR0cmlidXRlcy5sZW5ndGggPDwgMV07Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGZBdHRyaWJ1dGVzLCAwLCBhdHRyaWJ1dGVzLCAwLCBmQXR0cmlidXRlcy5sZW5ndGgpOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IGZBdHRyaWJ1dGVzLmxlbmd0aDsgaSA8IGF0dHJpYnV0ZXMubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzW2ldID0gbmV3IEF0dHJpYnV0ZSgpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZkF0dHJpYnV0ZXMgPSBhdHRyaWJ1dGVzOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gc2V0IHZhbHVlcwotICAgICAgICBBdHRyaWJ1dGUgYXR0cmlidXRlID0gZkF0dHJpYnV0ZXNbaW5kZXhdOwotICAgICAgICBhdHRyaWJ1dGUubmFtZS5zZXRWYWx1ZXMobmFtZSk7Ci0gICAgICAgIGF0dHJpYnV0ZS50eXBlID0gdHlwZTsKLSAgICAgICAgYXR0cmlidXRlLnZhbHVlID0gdmFsdWU7Ci0gICAgICAgIGF0dHJpYnV0ZS5ub25Ob3JtYWxpemVkVmFsdWUgPSB2YWx1ZTsKLSAgICAgICAgYXR0cmlidXRlLnNwZWNpZmllZCA9IGZhbHNlOwotCi0gICAgICAgIC8vIGNsZWFyIGF1Z21lbnRhdGlvbnMKLSAgICAgICAgYXR0cmlidXRlLmF1Z3MucmVtb3ZlQWxsSXRlbXMoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDaGVja3MgZm9yIGR1cGxpY2F0ZSBleHBhbmRlZCBuYW1lcyAobG9jYWwgcGFydCBhbmQgbmFtZXNwYWNlIG5hbWUKLSAgICAgKiBwYWlycykgaW4gdGhlIGF0dHJpYnV0ZSBzcGVjaWZpY2F0aW9uLiBJZiBhIGR1cGxpY2F0ZSBpcyBmb3VuZCBpdHMKLSAgICAgKiBuYW1lIGlzIHJldHVybmVkLgotICAgICAqIDxwPgotICAgICAqIFRoaXMgc2hvdWxkIGJlIGNhbGxlZCBvbmNlIGFsbCB0aGUgaW4tc2NvcGUgbmFtZXNwYWNlcyBmb3IgdGhlIGVsZW1lbnQKLSAgICAgKiBlbmNsb3NpbmcgdGhlc2UgYXR0cmlidXRlcyBpcyBrbm93biwgYW5kIGFmdGVyIGFsbCB0aGUgYXR0cmlidXRlcwotICAgICAqIGhhdmUgZ29uZSB0aHJvdWdoIG5hbWVzcGFjZSBiaW5kaW5nLgotICAgICAqCi0gICAgICogQHJldHVybiB0aGUgbmFtZSBvZiBhIGR1cGxpY2F0ZSBhdHRyaWJ1dGUgZm91bmQgaW4gdGhlIHNlYXJjaCwKLSAgICAgKiBvdGhlcndpc2UgbnVsbC4KLSAgICAgKi8KLSAgICBwdWJsaWMgUU5hbWUgY2hlY2tEdXBsaWNhdGVzTlMoKSB7Ci0gICAgICAgIC8vIElmIHRoZSBsaXN0IGlzIHNtYWxsIGNoZWNrIGZvciBkdXBsaWNhdGVzIHVzaW5nIHBhaXJ3aXNlIGNvbXBhcmlzb24uCi0gICAgICAgIGZpbmFsIGludCBsZW5ndGggPSBmTGVuZ3RoOwotICAgICAgICBpZiAobGVuZ3RoIDw9IFNJWkVfTElNSVQpIHsKLSAgICAgICAgICAgIGZpbmFsIEF0dHJpYnV0ZVtdIGF0dHJpYnV0ZXMgPSBmQXR0cmlidXRlczsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoIC0gMTsgKytpKSB7Ci0gICAgICAgICAgICAgICAgQXR0cmlidXRlIGF0dDEgPSBhdHRyaWJ1dGVzW2ldOwotICAgICAgICAgICAgICAgIGZvciAoaW50IGogPSBpICsgMTsgaiA8IGxlbmd0aDsgKytqKSB7Ci0gICAgICAgICAgICAgICAgICAgIEF0dHJpYnV0ZSBhdHQyID0gYXR0cmlidXRlc1tqXTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGF0dDEubmFtZS5sb2NhbHBhcnQgPT0gYXR0Mi5uYW1lLmxvY2FscGFydCAmJgotICAgICAgICAgICAgICAgICAgICAgICAgYXR0MS5uYW1lLnVyaSA9PSBhdHQyLm5hbWUudXJpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYXR0Mi5uYW1lOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLSAgICAgICAgLy8gSWYgdGhlIGxpc3QgaXMgbGFyZ2UgY2hlY2sgZHVwbGljYXRlcyB1c2luZyBhIGhhc2ggdGFibGUuCi0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIGNoZWNrTWFueUR1cGxpY2F0ZXNOUygpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBRTmFtZSBjaGVja01hbnlEdXBsaWNhdGVzTlMoKSB7Ci0gICAgICAgIC8vIFdlIGRvbid0IHdhbnQgdGhpcyB0YWJsZSB2aWV3IHRvIGJlIHJlYWQgaWYgc29tZW9uZSBjYWxscwotICAgICAgICAvLyBhZGRBdHRyaWJ1dGUgc28gd2UgaW52YWxpZGF0ZSBpdCB1cCBmcm9udC4KLSAgICAgICAgZklzVGFibGVWaWV3Q29uc2lzdGVudCA9IGZhbHNlOwotCi0gICAgICAgIHByZXBhcmVUYWJsZVZpZXcoKTsKLQotICAgICAgICBBdHRyaWJ1dGUgYXR0cjsKLSAgICAgICAgaW50IGJ1Y2tldDsKLQotICAgICAgICBmaW5hbCBpbnQgbGVuZ3RoID0gZkxlbmd0aDsKLSAgICAgICAgZmluYWwgQXR0cmlidXRlW10gYXR0cmlidXRlcyA9IGZBdHRyaWJ1dGVzOwotICAgICAgICBmaW5hbCBBdHRyaWJ1dGVbXSBhdHRyaWJ1dGVUYWJsZVZpZXcgPSBmQXR0cmlidXRlVGFibGVWaWV3OwotICAgICAgICBmaW5hbCBpbnRbXSBhdHRyaWJ1dGVUYWJsZVZpZXdDaGFpblN0YXRlID0gZkF0dHJpYnV0ZVRhYmxlVmlld0NoYWluU3RhdGU7Ci0gICAgICAgIGludCBsYXJnZUNvdW50ID0gZkxhcmdlQ291bnQ7Ci0KLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkgewotICAgICAgICAgICAgYXR0ciA9IGF0dHJpYnV0ZXNbaV07Ci0gICAgICAgICAgICBidWNrZXQgPSBnZXRUYWJsZVZpZXdCdWNrZXQoYXR0ci5uYW1lLmxvY2FscGFydCwgYXR0ci5uYW1lLnVyaSk7Ci0KLSAgICAgICAgICAgIC8vIFRoZSBjaGFpbiBpcyBzdGFsZS4KLSAgICAgICAgICAgIC8vIFRoaXMgbXVzdCBiZSBhIHVuaXF1ZSBhdHRyaWJ1dGUuCi0gICAgICAgICAgICBpZiAoYXR0cmlidXRlVGFibGVWaWV3Q2hhaW5TdGF0ZVtidWNrZXRdICE9IGxhcmdlQ291bnQpIHsKLSAgICAgICAgICAgICAgICBhdHRyaWJ1dGVUYWJsZVZpZXdDaGFpblN0YXRlW2J1Y2tldF0gPSBsYXJnZUNvdW50OwotICAgICAgICAgICAgICAgIGF0dHIubmV4dCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgYXR0cmlidXRlVGFibGVWaWV3W2J1Y2tldF0gPSBhdHRyOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gVGhpcyBjaGFpbiBpcyBhY3RpdmUuCi0gICAgICAgICAgICAvLyBXZSBuZWVkIHRvIGNoZWNrIGlmIGFueSBvZiB0aGUgYXR0cmlidXRlcyBoYXMgdGhlIHNhbWUgbmFtZS4KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIC8vIFNlYXJjaCB0aGUgdGFibGUuCi0gICAgICAgICAgICAgICAgaW50IGNvbGxpc2lvbkNvdW50ID0gMDsKLSAgICAgICAgICAgICAgICBBdHRyaWJ1dGUgZm91bmQgPSBhdHRyaWJ1dGVUYWJsZVZpZXdbYnVja2V0XTsKLSAgICAgICAgICAgICAgICB3aGlsZSAoZm91bmQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBpZiAoZm91bmQubmFtZS5sb2NhbHBhcnQgPT0gYXR0ci5uYW1lLmxvY2FscGFydCAmJgotICAgICAgICAgICAgICAgICAgICAgICAgZm91bmQubmFtZS51cmkgPT0gYXR0ci5uYW1lLnVyaSkgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGF0dHIubmFtZTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBmb3VuZCA9IGZvdW5kLm5leHQ7Ci0gICAgICAgICAgICAgICAgICAgICsrY29sbGlzaW9uQ291bnQ7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIC8vIFNlbGVjdCBhIG5ldyBoYXNoIGZ1bmN0aW9uIGFuZCByZWhhc2ggdGhlIHRhYmxlIHZpZXcKLSAgICAgICAgICAgICAgICAvLyBpZiB0aGUgY29sbGlzaW9uIHRocmVzaG9sZCBpcyBleGNlZWRlZC4KLSAgICAgICAgICAgICAgICBpZiAoY29sbGlzaW9uQ291bnQgPj0gTUFYX0hBU0hfQ09MTElTSU9OUykgewotICAgICAgICAgICAgICAgICAgICAvLyBUaGUgY3VycmVudCBhdHRyaWJ1dGUgd2lsbCBiZSBwcm9jZXNzZWQgaW4gdGhlIHJlaGFzaC4KLSAgICAgICAgICAgICAgICAgICAgcmViYWxhbmNlVGFibGVWaWV3TlMoaSsxKTsKLSAgICAgICAgICAgICAgICAgICAgbGFyZ2VDb3VudCA9IGZMYXJnZUNvdW50OwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gVXBkYXRlIHRhYmxlIHZpZXcKLSAgICAgICAgICAgICAgICAgICAgYXR0ci5uZXh0ID0gYXR0cmlidXRlVGFibGVWaWV3W2J1Y2tldF07Ci0gICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZVRhYmxlVmlld1tidWNrZXRdID0gYXR0cjsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogTG9vayB1cCB0aGUgaW5kZXggb2YgYW4gYXR0cmlidXRlIGJ5IE5hbWVzcGFjZSBuYW1lLgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4KLSAgICAgKiBUaGlzIG1ldGhvZCB1c2VzIHJlZmVyZW5jZSBjb21wYXJpc29uLCBhbmQgdGh1cyBzaG91bGQKLSAgICAgKiBvbmx5IGJlIHVzZWQgaW50ZXJuYWxseS4gV2UgY2Fubm90IHVzZSB0aGlzIG1ldGhvZCBpbiBhbnkKLSAgICAgKiBjb2RlIGV4cG9zZWQgdG8gdXNlcnMgYXMgdGhleSBtYXkgbm90IHBhc3MgaW4gdW5pcXVlIHN0cmluZ3MuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdXJpIFRoZSBOYW1lc3BhY2UgVVJJLCBvciBudWxsIGlmCi0gICAgICogICAgICAgIHRoZSBuYW1lIGhhcyBubyBOYW1lc3BhY2UgVVJJLgotICAgICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGF0dHJpYnV0ZSdzIGxvY2FsIG5hbWUuCi0gICAgICogQHJldHVybiBUaGUgaW5kZXggb2YgdGhlIGF0dHJpYnV0ZSwgb3IgLTEgaWYgaXQgZG9lcyBub3QKLSAgICAgKiAgICAgICAgIGFwcGVhciBpbiB0aGUgbGlzdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldEluZGV4RmFzdChTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxQYXJ0KSB7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZkxlbmd0aDsgKytpKSB7Ci0gICAgICAgICAgICBBdHRyaWJ1dGUgYXR0cmlidXRlID0gZkF0dHJpYnV0ZXNbaV07Ci0gICAgICAgICAgICBpZiAoYXR0cmlidXRlLm5hbWUubG9jYWxwYXJ0ID09IGxvY2FsUGFydCAmJgotICAgICAgICAgICAgICAgIGF0dHJpYnV0ZS5uYW1lLnVyaSA9PSB1cmkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gaTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gLTE7Ci0gICAgfSAvLyBnZXRJbmRleEZhc3QoU3RyaW5nLFN0cmluZyk6aW50Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBwYXNzZWQgaW4gb3IgTk1UT0tFTiBpZiBpdCdzIGFuIGVudW1lcmF0ZWQgdHlwZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSB0eXBlIGF0dHJpYnV0ZSB0eXBlCi0gICAgICogQHJldHVybiB0aGUgdmFsdWUgcGFzc2VkIGluIG9yIE5NVE9LRU4gaWYgaXQncyBhbiBlbnVtZXJhdGVkIHR5cGUuCi0gICAgICovCi0gICAgcHJpdmF0ZSBTdHJpbmcgZ2V0UmVwb3J0YWJsZVR5cGUoU3RyaW5nIHR5cGUpIHsKLQotICAgICAgICBpZiAodHlwZS5jaGFyQXQoMCkgPT0gJygnKSB7Ci0gICAgICAgICAgICByZXR1cm4gIk5NVE9LRU4iOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiB0eXBlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIHBvc2l0aW9uIGluIHRoZSB0YWJsZSB2aWV3Ci0gICAgICogd2hlcmUgdGhlIGdpdmVuIGF0dHJpYnV0ZSBuYW1lIHdvdWxkIGJlIGhhc2hlZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBxbmFtZSB0aGUgYXR0cmlidXRlIG5hbWUKLSAgICAgKiBAcmV0dXJuIHRoZSBwb3NpdGlvbiBpbiB0aGUgdGFibGUgdmlldyB3aGVyZSB0aGUgZ2l2ZW4gYXR0cmlidXRlCi0gICAgICogd291bGQgYmUgaGFzaGVkCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGludCBnZXRUYWJsZVZpZXdCdWNrZXQoU3RyaW5nIHFuYW1lKSB7Ci0gICAgICAgIHJldHVybiAoaGFzaChxbmFtZSkgJiAweDdGRkZGRkZGKSAlIGZUYWJsZVZpZXdCdWNrZXRzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIHBvc2l0aW9uIGluIHRoZSB0YWJsZSB2aWV3Ci0gICAgICogd2hlcmUgdGhlIGdpdmVuIGF0dHJpYnV0ZSBuYW1lIHdvdWxkIGJlIGhhc2hlZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBsb2NhbHBhcnQgdGhlIGxvY2FsIHBhcnQgb2YgdGhlIGF0dHJpYnV0ZQotICAgICAqIEBwYXJhbSB1cmkgdGhlIG5hbWVzcGFjZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUKLSAgICAgKiBAcmV0dXJuIHRoZSBwb3NpdGlvbiBpbiB0aGUgdGFibGUgdmlldyB3aGVyZSB0aGUgZ2l2ZW4gYXR0cmlidXRlCi0gICAgICogd291bGQgYmUgaGFzaGVkCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGludCBnZXRUYWJsZVZpZXdCdWNrZXQoU3RyaW5nIGxvY2FscGFydCwgU3RyaW5nIHVyaSkgewotICAgICAgICBpZiAodXJpID09IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiAoaGFzaChsb2NhbHBhcnQpICYgMHg3RkZGRkZGRikgJSBmVGFibGVWaWV3QnVja2V0czsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiAoaGFzaChsb2NhbHBhcnQsIHVyaSkgJiAweDdGRkZGRkZGKSAlIGZUYWJsZVZpZXdCdWNrZXRzOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBpbnQgaGFzaChTdHJpbmcgbG9jYWxwYXJ0KSB7Ci0gICAgICAgIGlmIChmSGFzaE11bHRpcGxpZXJzID09IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBsb2NhbHBhcnQuaGFzaENvZGUoKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gaGFzaDAobG9jYWxwYXJ0KTsKLSAgICB9IC8vIGhhc2goU3RyaW5nKTppbnQKLQotICAgIHByaXZhdGUgaW50IGhhc2goU3RyaW5nIGxvY2FscGFydCwgU3RyaW5nIHVyaSkgewotICAgICAgICBpZiAoZkhhc2hNdWx0aXBsaWVycyA9PSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gbG9jYWxwYXJ0Lmhhc2hDb2RlKCkgKyB1cmkuaGFzaENvZGUoKSAqIDMxOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBoYXNoMChsb2NhbHBhcnQpICsgaGFzaDAodXJpKSAqIGZIYXNoTXVsdGlwbGllcnNbTVVMVElQTElFUlNfU0laRV07Ci0gICAgfSAvLyBoYXNoKFN0cmluZyxTdHJpbmcpOmludAotCi0gICAgcHJpdmF0ZSBpbnQgaGFzaDAoU3RyaW5nIHN5bWJvbCkgewotICAgICAgICBpbnQgY29kZSA9IDA7Ci0gICAgICAgIGZpbmFsIGludCBsZW5ndGggPSBzeW1ib2wubGVuZ3RoKCk7Ci0gICAgICAgIGZpbmFsIGludFtdIG11bHRpcGxpZXJzID0gZkhhc2hNdWx0aXBsaWVyczsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkgewotICAgICAgICAgICAgY29kZSA9IGNvZGUgKiBtdWx0aXBsaWVyc1tpICYgTVVMVElQTElFUlNfTUFTS10gKyBzeW1ib2wuY2hhckF0KGkpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBjb2RlOwotICAgIH0gLy8gaGFzaDAoU3RyaW5nKTppbnQKLQotICAgIC8qKgotICAgICAqIFB1cmdlcyBhbGwgZWxlbWVudHMgZnJvbSB0aGUgdGFibGUgdmlldy4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCBjbGVhblRhYmxlVmlldygpIHsKLSAgICAgICAgaWYgKCsrZkxhcmdlQ291bnQgPCAwKSB7Ci0gICAgICAgICAgICAvLyBPdmVyZmxvdy4gV2UgYWN0dWFsbHkgbmVlZCB0byB2aXNpdCB0aGUgY2hhaW4gc3RhdGUgYXJyYXkuCi0gICAgICAgICAgICBpZiAoZkF0dHJpYnV0ZVRhYmxlVmlld0NoYWluU3RhdGUgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSBmVGFibGVWaWV3QnVja2V0cyAtIDE7IGkgPj0gMDsgLS1pKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZBdHRyaWJ1dGVUYWJsZVZpZXdDaGFpblN0YXRlW2ldID0gMDsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmTGFyZ2VDb3VudCA9IDE7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAgLyoqCi0gICAgICogSW5jcmVhc2VzIHRoZSBjYXBhY2l0eSBvZiB0aGUgdGFibGUgdmlldy4KLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgZ3Jvd1RhYmxlVmlldygpIHsKLSAgICAgICAgZmluYWwgaW50IGxlbmd0aCA9IGZMZW5ndGg7Ci0gICAgICAgIGludCB0YWJsZVZpZXdCdWNrZXRzID0gZlRhYmxlVmlld0J1Y2tldHM7Ci0gICAgICAgIGRvIHsKLSAgICAgICAgICAgIHRhYmxlVmlld0J1Y2tldHMgPSAodGFibGVWaWV3QnVja2V0cyA8PCAxKSArIDE7Ci0gICAgICAgICAgICBpZiAodGFibGVWaWV3QnVja2V0cyA8IDApIHsKLSAgICAgICAgICAgICAgICB0YWJsZVZpZXdCdWNrZXRzID0gSW50ZWdlci5NQVhfVkFMVUU7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICB3aGlsZSAobGVuZ3RoID4gdGFibGVWaWV3QnVja2V0cyk7Ci0gICAgICAgIGZUYWJsZVZpZXdCdWNrZXRzID0gdGFibGVWaWV3QnVja2V0czsKLSAgICAgICAgZkF0dHJpYnV0ZVRhYmxlVmlldyA9IG51bGw7Ci0gICAgICAgIGZMYXJnZUNvdW50ID0gMTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBQcmVwYXJlcyB0aGUgdGFibGUgdmlldyBvZiB0aGUgYXR0cmlidXRlcyBsaXN0IGZvciB1c2UuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgcHJlcGFyZVRhYmxlVmlldygpIHsKLSAgICAgICAgaWYgKGZMZW5ndGggPiBmVGFibGVWaWV3QnVja2V0cykgewotICAgICAgICAgICAgZ3Jvd1RhYmxlVmlldygpOwotICAgICAgICB9Ci0gICAgICAgIGlmIChmQXR0cmlidXRlVGFibGVWaWV3ID09IG51bGwpIHsKLSAgICAgICAgICAgIGZBdHRyaWJ1dGVUYWJsZVZpZXcgPSBuZXcgQXR0cmlidXRlW2ZUYWJsZVZpZXdCdWNrZXRzXTsKLSAgICAgICAgICAgIGZBdHRyaWJ1dGVUYWJsZVZpZXdDaGFpblN0YXRlID0gbmV3IGludFtmVGFibGVWaWV3QnVja2V0c107Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBjbGVhblRhYmxlVmlldygpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUHJlcGFyZXMgdGhlIHRhYmxlIHZpZXcgb2YgdGhlIGF0dHJpYnV0ZXMgbGlzdCBmb3IgdXNlLAotICAgICAqIGFuZCBwb3B1bGF0ZXMgaXQgd2l0aCB0aGUgYXR0cmlidXRlcyB3aGljaCBoYXZlIGJlZW4KLSAgICAgKiBwcmV2aW91c2x5IHJlYWQuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgcHJlcGFyZUFuZFBvcHVsYXRlVGFibGVWaWV3KCkgewotICAgICAgICBwcmVwYXJlQW5kUG9wdWxhdGVUYWJsZVZpZXcoZkxlbmd0aCk7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIHByZXBhcmVBbmRQb3B1bGF0ZVRhYmxlVmlldyhmaW5hbCBpbnQgY291bnQpIHsKLSAgICAgICAgcHJlcGFyZVRhYmxlVmlldygpOwotICAgICAgICAvLyBOZWVkIHRvIHBvcHVsYXRlIHRoZSBoYXNoIHRhYmxlIHdpdGggdGhlIGF0dHJpYnV0ZXMgd2UndmUgcHJvY2Vzc2VkIHNvIGZhci4KLSAgICAgICAgQXR0cmlidXRlIGF0dHI7Ci0gICAgICAgIGludCBidWNrZXQ7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7ICsraSkgewotICAgICAgICAgICAgYXR0ciA9IGZBdHRyaWJ1dGVzW2ldOwotICAgICAgICAgICAgYnVja2V0ID0gZ2V0VGFibGVWaWV3QnVja2V0KGF0dHIubmFtZS5yYXduYW1lKTsKLSAgICAgICAgICAgIGlmIChmQXR0cmlidXRlVGFibGVWaWV3Q2hhaW5TdGF0ZVtidWNrZXRdICE9IGZMYXJnZUNvdW50KSB7Ci0gICAgICAgICAgICAgICAgZkF0dHJpYnV0ZVRhYmxlVmlld0NoYWluU3RhdGVbYnVja2V0XSA9IGZMYXJnZUNvdW50OwotICAgICAgICAgICAgICAgIGF0dHIubmV4dCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgZkF0dHJpYnV0ZVRhYmxlVmlld1tidWNrZXRdID0gYXR0cjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIC8vIFVwZGF0ZSB0YWJsZSB2aWV3Ci0gICAgICAgICAgICAgICAgYXR0ci5uZXh0ID0gZkF0dHJpYnV0ZVRhYmxlVmlld1tidWNrZXRdOwotICAgICAgICAgICAgICAgIGZBdHRyaWJ1dGVUYWJsZVZpZXdbYnVja2V0XSA9IGF0dHI7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIHByZWZpeCBvZiB0aGUgYXR0cmlidXRlIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXguCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBhdHRyaWJ1dGUuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRQcmVmaXgoaW50IGluZGV4KSB7Ci0gICAgICAgIGlmIChpbmRleCA8IDAgfHwgaW5kZXggPj0gZkxlbmd0aCkgewotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLSAgICAgICAgU3RyaW5nIHByZWZpeCA9IGZBdHRyaWJ1dGVzW2luZGV4XS5uYW1lLnByZWZpeDsKLSAgICAgICAgLy8gUkVWSVNJVDogVGhlIGVtcHR5IHN0cmluZyBpcyBub3QgZW50ZXJlZCBpbiB0aGUgc3ltYm9sIHRhYmxlIQotICAgICAgICByZXR1cm4gcHJlZml4ICE9IG51bGwgPyBwcmVmaXggOiAiIjsKLSAgICB9IC8vIGdldFByZWZpeChpbnQpOlN0cmluZwotCi0gICAgLyoqCi0gICAgICogTG9vayB1cCBhbiBhdHRyaWJ1dGUncyBOYW1lc3BhY2UgVVJJIGJ5IGluZGV4LgotICAgICAqCi0gICAgICogQHBhcmFtIGluZGV4IFRoZSBhdHRyaWJ1dGUgaW5kZXggKHplcm8tYmFzZWQpLgotICAgICAqIEByZXR1cm4gVGhlIE5hbWVzcGFjZSBVUkkKLSAgICAgKiBAc2VlICNnZXRMZW5ndGgKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFVSSShpbnQgaW5kZXgpIHsKLSAgICAgICAgaWYgKGluZGV4IDwgMCB8fCBpbmRleCA+PSBmTGVuZ3RoKSB7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotICAgICAgICBTdHJpbmcgdXJpID0gZkF0dHJpYnV0ZXNbaW5kZXhdLm5hbWUudXJpOwotICAgICAgICByZXR1cm4gdXJpOwotICAgIH0gLy8gZ2V0VVJJKGludCk6U3RyaW5nCi0KLSAgICAvKioKLSAgICAgKiBMb29rIHVwIGFuIGF0dHJpYnV0ZSdzIHZhbHVlIGJ5IE5hbWVzcGFjZSBuYW1lIGFuZAotICAgICAqIExvY2FsIG5hbWUuIElmIE5hbWVzcGFjZSBpcyBudWxsLCBpZ25vcmUgbmFtZXNwYWNlCi0gICAgICogY29tcGFyaXNvbi4gSWYgTmFtZXNwYWNlIGlzICIiLCB0cmVhdCB0aGUgbmFtZSBhcwotICAgICAqIGhhdmluZyBubyBOYW1lc3BhY2UgVVJJLgotICAgICAqCi0gICAgICogPHA+U2VlIHtAbGluayAjZ2V0VmFsdWUoaW50KSBnZXRWYWx1ZShpbnQpfSBmb3IgYSBkZXNjcmlwdGlvbgotICAgICAqIG9mIHRoZSBwb3NzaWJsZSB2YWx1ZXMuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIHVyaSBUaGUgTmFtZXNwYWNlIFVSSSwgb3IgbnVsbCBuYW1lc3BhY2VzIGFyZSBpZ25vcmVkLgotICAgICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGxvY2FsIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgKiBAcmV0dXJuIFRoZSBhdHRyaWJ1dGUgdmFsdWUgYXMgYSBzdHJpbmcsIG9yIG51bGwgaWYgdGhlCi0gICAgICogICAgICAgICBhdHRyaWJ1dGUgaXMgbm90IGluIHRoZSBsaXN0LgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VmFsdWUoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSkgewotICAgICAgICBpbnQgaW5kZXggPSBnZXRJbmRleCh1cmksIGxvY2FsTmFtZSk7Ci0gICAgICAgIHJldHVybiBpbmRleCAhPSAtMSA/IGdldFZhbHVlKGluZGV4KSA6IG51bGw7Ci0gICAgfSAvLyBnZXRWYWx1ZShTdHJpbmcsU3RyaW5nKTpTdHJpbmcKLQotICAgIC8qKgotICAgICAqIExvb2sgdXAgYW4gYXVnbWVudGF0aW9ucyBieSBOYW1lc3BhY2UgbmFtZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSB1cmkgVGhlIE5hbWVzcGFjZSBVUkksIG9yIG51bGwgaWYgdGhlCi0gICAgICogQHBhcmFtIGxvY2FsTmFtZSBUaGUgbG9jYWwgbmFtZSBvZiB0aGUgYXR0cmlidXRlLgotICAgICAqIEByZXR1cm4gQXVnbWVudGF0aW9ucwotICAgICAqLwotICAgIHB1YmxpYyBBdWdtZW50YXRpb25zIGdldEF1Z21lbnRhdGlvbnMgKFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUpIHsKLSAgICAgICAgaW50IGluZGV4ID0gZ2V0SW5kZXgodXJpLCBsb2NhbE5hbWUpOwotICAgICAgICByZXR1cm4gaW5kZXggIT0gLTEgPyBmQXR0cmlidXRlc1tpbmRleF0uYXVncyA6IG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogTG9vayB1cCBhbiBhdWdtZW50YXRpb24gYnkgWE1MIDEuMCBxdWFsaWZpZWQgbmFtZS4KLSAgICAgKiA8cD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBxTmFtZSBUaGUgWE1MIDEuMCBxdWFsaWZpZWQgbmFtZS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gQXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICovCi0gICAgcHVibGljIEF1Z21lbnRhdGlvbnMgZ2V0QXVnbWVudGF0aW9ucyhTdHJpbmcgcU5hbWUpewotICAgICAgICBpbnQgaW5kZXggPSBnZXRJbmRleChxTmFtZSk7Ci0gICAgICAgIHJldHVybiBpbmRleCAhPSAtMSA/IGZBdHRyaWJ1dGVzW2luZGV4XS5hdWdzIDogbnVsbDsKLSAgICB9Ci0KLQotCi0gICAgLyoqCi0gICAgICogTG9vayB1cCBhbiBhdWdtZW50YXRpb25zIGJ5IGF0dHJpYnV0ZXMgaW5kZXguCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYXR0cmlidXRlSW5kZXggVGhlIGF0dHJpYnV0ZSBpbmRleC4KLSAgICAgKiBAcmV0dXJuIEF1Z21lbnRhdGlvbnMKLSAgICAgKi8KLSAgICBwdWJsaWMgQXVnbWVudGF0aW9ucyBnZXRBdWdtZW50YXRpb25zIChpbnQgYXR0cmlidXRlSW5kZXgpewotICAgICAgICBpZiAoYXR0cmlidXRlSW5kZXggPCAwIHx8IGF0dHJpYnV0ZUluZGV4ID49IGZMZW5ndGgpIHsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmQXR0cmlidXRlc1thdHRyaWJ1dGVJbmRleF0uYXVnczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSBhdWdtZW50YXRpb25zIG9mIHRoZSBhdHRyaWJ1dGUgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBhdHRySW5kZXggVGhlIGF0dHJpYnV0ZSBpbmRleC4KLSAgICAgKiBAcGFyYW0gYXVncyAgICAgIFRoZSBhdWdtZW50YXRpb25zLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEF1Z21lbnRhdGlvbnMoaW50IGF0dHJJbmRleCwgQXVnbWVudGF0aW9ucyBhdWdzKSB7Ci0gICAgICAgIGZBdHRyaWJ1dGVzW2F0dHJJbmRleF0uYXVncyA9IGF1Z3M7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0cyB0aGUgdXJpIG9mIHRoZSBhdHRyaWJ1dGUgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBhdHRySW5kZXggVGhlIGF0dHJpYnV0ZSBpbmRleC4KLSAgICAgKiBAcGFyYW0gdXJpICAgICAgIE5hbWVzcGFjZSB1cmkKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRVUkkoaW50IGF0dHJJbmRleCwgU3RyaW5nIHVyaSkgewotICAgICAgICBmQXR0cmlidXRlc1thdHRySW5kZXhdLm5hbWUudXJpID0gdXJpOwotICAgIH0gLy8gZ2V0VVJJKGludCxRTmFtZSkKLQotICAgIC8vIEltcGxlbWVudGF0aW9uIG1ldGhvZHMKLSAgICBwdWJsaWMgdm9pZCBzZXRTY2hlbWFJZChpbnQgYXR0ckluZGV4LCBib29sZWFuIHNjaGVtYUlkKSB7Ci0gICAgICAgIGZBdHRyaWJ1dGVzW2F0dHJJbmRleF0uc2NoZW1hSWQgPSBzY2hlbWFJZDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXRTY2hlbWFJZChpbnQgaW5kZXgpIHsKLSAgICAgICAgaWYgKGluZGV4IDwgMCB8fCBpbmRleCA+PSBmTGVuZ3RoKSB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGZBdHRyaWJ1dGVzW2luZGV4XS5zY2hlbWFJZDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXRTY2hlbWFJZChTdHJpbmcgcW5hbWUpIHsKLSAgICAgICAgaW50IGluZGV4ID0gZ2V0SW5kZXgocW5hbWUpOwotICAgICAgICByZXR1cm4gaW5kZXggIT0gLTEgPyBmQXR0cmlidXRlc1tpbmRleF0uc2NoZW1hSWQgOiBmYWxzZTsKLSAgICB9IC8vIGdldFR5cGUoU3RyaW5nKTpTdHJpbmcKLQotICAgIHB1YmxpYyBib29sZWFuIGdldFNjaGVtYUlkKFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUpIHsKLSAgICAgICAgaWYgKCFmTmFtZXNwYWNlcykgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0gICAgICAgIGludCBpbmRleCA9IGdldEluZGV4KHVyaSwgbG9jYWxOYW1lKTsKLSAgICAgICAgcmV0dXJuIGluZGV4ICE9IC0xID8gZkF0dHJpYnV0ZXNbaW5kZXhdLnNjaGVtYUlkIDogZmFsc2U7Ci0gICAgfSAvLyBnZXRUeXBlKFN0cmluZyxTdHJpbmcpOlN0cmluZwotCi0gICAgLy9YTUxCdWZmZXJMaXN0ZW5lciBtZXRob2RzCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2Qgd2lsbCBiZSBpbnZva2VkIGJ5IFhNTEVudGl0eVJlYWRlciBiZWZvcmUgU2Nhbm5lZEVudGl0aWVzIGJ1ZmZlcgotICAgICAqIGlzIHJlbG9hZGVkLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHJlZnJlc2goKSB7Ci0gICAgICAgIGlmKGZMZW5ndGggPiAwKXsKLSAgICAgICAgICAgIGZvcihpbnQgaSA9IDAgOyBpIDwgZkxlbmd0aCA7IGkrKyl7Ci0gICAgICAgICAgICAgICAgZ2V0VmFsdWUoaSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0gICAgcHVibGljIHZvaWQgcmVmcmVzaChpbnQgcG9zKSB7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIHByZXBhcmVBbmRQb3B1bGF0ZVRhYmxlVmlld05TKGZpbmFsIGludCBjb3VudCkgewotICAgICAgICBwcmVwYXJlVGFibGVWaWV3KCk7Ci0gICAgICAgIC8vIE5lZWQgdG8gcG9wdWxhdGUgdGhlIGhhc2ggdGFibGUgd2l0aCB0aGUgYXR0cmlidXRlcyB3ZSd2ZSBwcm9jZXNzZWQgc28gZmFyLgotICAgICAgICBBdHRyaWJ1dGUgYXR0cjsKLSAgICAgICAgaW50IGJ1Y2tldDsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb3VudDsgKytpKSB7Ci0gICAgICAgICAgICBhdHRyID0gZkF0dHJpYnV0ZXNbaV07Ci0gICAgICAgICAgICBidWNrZXQgPSBnZXRUYWJsZVZpZXdCdWNrZXQoYXR0ci5uYW1lLmxvY2FscGFydCwgYXR0ci5uYW1lLnVyaSk7Ci0gICAgICAgICAgICBpZiAoZkF0dHJpYnV0ZVRhYmxlVmlld0NoYWluU3RhdGVbYnVja2V0XSAhPSBmTGFyZ2VDb3VudCkgewotICAgICAgICAgICAgICAgIGZBdHRyaWJ1dGVUYWJsZVZpZXdDaGFpblN0YXRlW2J1Y2tldF0gPSBmTGFyZ2VDb3VudDsKLSAgICAgICAgICAgICAgICBhdHRyLm5leHQgPSBudWxsOwotICAgICAgICAgICAgICAgIGZBdHRyaWJ1dGVUYWJsZVZpZXdbYnVja2V0XSA9IGF0dHI7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAvLyBVcGRhdGUgdGFibGUgdmlldwotICAgICAgICAgICAgICAgIGF0dHIubmV4dCA9IGZBdHRyaWJ1dGVUYWJsZVZpZXdbYnVja2V0XTsKLSAgICAgICAgICAgICAgICBmQXR0cmlidXRlVGFibGVWaWV3W2J1Y2tldF0gPSBhdHRyOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmFuZG9tbHkgc2VsZWN0cyBhIG5ldyBoYXNoIGZ1bmN0aW9uIGFuZCByZW9yZ2FuaXplcyB0aGUgdGFibGUgdmlldwotICAgICAqIGluIG9yZGVyIHRvIG1vcmUgZXZlbmx5IGRpc3RyaWJ1dGUgaXRzIGVudHJpZXMuIFRoaXMgbWV0aG9kIGlzIGNhbGxlZAotICAgICAqIGF1dG9tYXRpY2FsbHkgd2hlbiB0aGUgbnVtYmVyIG9mIGF0dHJpYnV0ZXMgaW4gb25lIGJ1Y2tldCBleGNlZWRzCi0gICAgICogTUFYX0hBU0hfQ09MTElTSU9OUy4KLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgcmViYWxhbmNlVGFibGVWaWV3KGZpbmFsIGludCBjb3VudCkgewotICAgICAgICBpZiAoZkhhc2hNdWx0aXBsaWVycyA9PSBudWxsKSB7Ci0gICAgICAgICAgICBmSGFzaE11bHRpcGxpZXJzID0gbmV3IGludFtNVUxUSVBMSUVSU19TSVpFICsgMV07Ci0gICAgICAgIH0KLSAgICAgICAgUHJpbWVOdW1iZXJTZXF1ZW5jZUdlbmVyYXRvci5nZW5lcmF0ZVNlcXVlbmNlKGZIYXNoTXVsdGlwbGllcnMpOwotICAgICAgICBwcmVwYXJlQW5kUG9wdWxhdGVUYWJsZVZpZXcoY291bnQpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJhbmRvbWx5IHNlbGVjdHMgYSBuZXcgaGFzaCBmdW5jdGlvbiBhbmQgcmVvcmdhbml6ZXMgdGhlIHRhYmxlIHZpZXcKLSAgICAgKiBpbiBvcmRlciB0byBtb3JlIGV2ZW5seSBkaXN0cmlidXRlIGl0cyBlbnRyaWVzLiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQKLSAgICAgKiBhdXRvbWF0aWNhbGx5IHdoZW4gdGhlIG51bWJlciBvZiBhdHRyaWJ1dGVzIGluIG9uZSBidWNrZXQgZXhjZWVkcwotICAgICAqIE1BWF9IQVNIX0NPTExJU0lPTlMuCi0gICAgICovCi0gICAgcHJpdmF0ZSB2b2lkIHJlYmFsYW5jZVRhYmxlVmlld05TKGZpbmFsIGludCBjb3VudCkgewotICAgICAgICBpZiAoZkhhc2hNdWx0aXBsaWVycyA9PSBudWxsKSB7Ci0gICAgICAgICAgICBmSGFzaE11bHRpcGxpZXJzID0gbmV3IGludFtNVUxUSVBMSUVSU19TSVpFICsgMV07Ci0gICAgICAgIH0KLSAgICAgICAgUHJpbWVOdW1iZXJTZXF1ZW5jZUdlbmVyYXRvci5nZW5lcmF0ZVNlcXVlbmNlKGZIYXNoTXVsdGlwbGllcnMpOwotICAgICAgICBwcmVwYXJlQW5kUG9wdWxhdGVUYWJsZVZpZXdOUyhjb3VudCk7Ci0gICAgfQotCi0gICAgLy8KLSAgICAvLyBDbGFzc2VzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIEF0dHJpYnV0ZSBpbmZvcm1hdGlvbi4KLSAgICAgKgotICAgICAqIEBhdXRob3IgQW5keSBDbGFyaywgSUJNCi0gICAgICovCi0gICAgc3RhdGljIGNsYXNzIEF0dHJpYnV0ZSB7Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gRGF0YQotICAgICAgICAvLwotCi0gICAgICAgIC8vIGJhc2ljIGluZm8KLQotICAgICAgICAvKiogTmFtZS4gKi8KLSAgICAgICAgcHVibGljIFFOYW1lIG5hbWUgPSBuZXcgUU5hbWUoKTsKLQotICAgICAgICAvKiogVHlwZS4gKi8KLSAgICAgICAgcHVibGljIFN0cmluZyB0eXBlOwotCi0gICAgICAgIC8qKiBWYWx1ZS4gKi8KLSAgICAgICAgcHVibGljIFN0cmluZyB2YWx1ZTsKLQotICAgICAgICAvKiogVGhpcyB3aWxsIHBvaW50IHRvIHRoZSBTY2FubmVkRW50aXRpZXMgYnVmZmVyLiovCi0gICAgICAgIHB1YmxpYyBYTUxTdHJpbmcgeG1sVmFsdWU7Ci0KLSAgICAgICAgLyoqIE5vbi1ub3JtYWxpemVkIHZhbHVlLiAqLwotICAgICAgICBwdWJsaWMgU3RyaW5nIG5vbk5vcm1hbGl6ZWRWYWx1ZTsKLQotICAgICAgICAvKiogU3BlY2lmaWVkLiAqLwotICAgICAgICBwdWJsaWMgYm9vbGVhbiBzcGVjaWZpZWQ7Ci0KLSAgICAgICAgLyoqIFNjaGVtYSBJRCB0eXBlLiAqLwotICAgICAgICBwdWJsaWMgYm9vbGVhbiBzY2hlbWFJZDsKLQotICAgICAgICAvKioKLSAgICAgICAgICogQXVnbWVudGF0aW9ucyBpbmZvcm1hdGlvbiBmb3IgdGhpcyBhdHRyaWJ1dGUuCi0gICAgICAgICAqIFhNTEF0dHJpYnV0ZXMgaGFzIG5vIGtub3dsZWRnZSBpZiBhbnkgYXVnbWVudGF0aW9ucwotICAgICAgICAgKiB3ZXJlIGF0dGFjaGVkIHRvIEF1Z21lbnRhdGlvbnMuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgQXVnbWVudGF0aW9ucyBhdWdzID0gbmV3IEF1Z21lbnRhdGlvbnNJbXBsKCk7Ci0KLSAgICAgICAgLy8gQWRkaXRpb25hbCBkYXRhIGZvciBhdHRyaWJ1dGUgdGFibGUgdmlldwotCi0gICAgICAgIC8qKiBQb2ludGVyIHRvIHRoZSBuZXh0IGF0dHJpYnV0ZSBpbiB0aGUgY2hhaW4uICoqLwotICAgICAgICBwdWJsaWMgQXR0cmlidXRlIG5leHQ7Ci0KLSAgICB9IC8vIGNsYXNzIEF0dHJpYnV0ZQotCi19IC8vIGNsYXNzIFhNTEF0dHJpYnV0ZXNJbXBsCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL1hNTEF0dHJpYnV0ZXNJdGVyYXRvckltcGwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3V0aWwvWE1MQXR0cmlidXRlc0l0ZXJhdG9ySW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3ZjRkYWZiLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3V0aWwvWE1MQXR0cmlidXRlc0l0ZXJhdG9ySW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTAyICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsOwotCi0vL2phdmEgaW1wb3J0cwotaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvciA7Ci1pbXBvcnQgamF2YS51dGlsLk5vU3VjaEVsZW1lbnRFeGNlcHRpb247Ci0KLS8veGVyY2VzIGltcG9ydHMKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuWE1MQXR0cmlidXRlc0ltcGwgOwotCi0vKioKLSAqCi0gKiBAYXV0aG9yICBOZWVyYWogQmFqYWosIFN1biBNaWNyb3N5c3RlbXMKLSAqLwotCi0vKioKLSAqIEl0cyBiZXR0ZXIgdG8gZXh0ZW5kIHRoZSBmdW5jdGlvbmFsaXR5IG9mIGV4aXN0aW5nIFhNTEF0dHJpYnV0ZXNJbXBsIGFuZCBhbHNvIG1ha2UgaXQgb2YgdHlwZSBJdGVyYXRvci4KLSAqIFdlIGNhbiBkaXJlY3RseSAgZ2l2ZSBhbiBvYmplY3Qgb2YgdHlwZSBpdGVyYXRvciBmcm9tIFN0YXJ0RWxlbWVudCBldmVudC4gV2Ugc2hvdWxkIGFsc28gaGF2ZQotICogQXR0cmlidXRlIG9iamVjdCBvZiB0eXBlIGphdmF4LnhtbC5zdHJlYW0uQXR0cmlidXRlIGludGVybmFsbHkuIEl0IHdvdWxkIGF2b2lkIHRoZSBuZWVkIG9mIGNyZWF0aW5nCi0gKiBuZXcgamF2YXgueG1sLnN0cmVhbS5BdHRyaWJ1dGUgb2JqZWN0IGF0IHRoZSBsYXRlciBzdGFnZS4KLSAqCi0gKiBTaG91bGQgd2UgY2hhbmdlIFhNTEF0dHJpYnV0ZXMgaW50ZXJmYWNlIHRvIGltcGxlbWVudCBJdGVyYW90ciA/IEkgdGhpbmsgaXRzIGJldHRlciBhdm9pZCB0b3VjaGluZyBYTkkgYXMKLSAqIG11Y2ggYXMgcG9zc2libGUuIC0gTkIuCi0gKi8KLQotcHVibGljIGNsYXNzIFhNTEF0dHJpYnV0ZXNJdGVyYXRvckltcGwgZXh0ZW5kcyBYTUxBdHRyaWJ1dGVzSW1wbCBpbXBsZW1lbnRzIEl0ZXJhdG9yIHsKLQotICAgIC8vcG9pbnRlciB0byBjdXJyZW50IHBvc2l0aW9uLgotICAgIHByb3RlY3RlZCBpbnQgZkN1cnJlbnQgPSAwIDsKLQotICAgIHByb3RlY3RlZCBYTUxBdHRyaWJ1dGVzSW1wbC5BdHRyaWJ1dGUgZkxhc3RSZXR1cm5lZEl0ZW0gOwotCi0gICAgLyoqIENyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgWE1MQXR0cmlidXRlc0l0ZXJhdG9ySW1wbCAqLwotICAgIHB1YmxpYyBYTUxBdHRyaWJ1dGVzSXRlcmF0b3JJbXBsKCkgewotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGhhc05leHQoKSB7Ci0gICAgICAgIHJldHVybiBmQ3VycmVudCA8IGdldExlbmd0aCgpID8gdHJ1ZSA6IGZhbHNlIDsKLSAgICB9Ly9oYXNOZXh0KCkKLQotICAgIHB1YmxpYyBPYmplY3QgbmV4dCgpIHsKLSAgICAgICAgaWYoaGFzTmV4dCgpKXsKLSAgICAgICAgICAgIC8vIHNob3VsZCB0aGlzIGJlIG9mIHR5cGUgamF2YXgueG1sLnN0cmVhbS5BdHRyaWJ1dGUgPwotICAgICAgICAgICAgcmV0dXJuIGZMYXN0UmV0dXJuZWRJdGVtID0gZkF0dHJpYnV0ZXNbZkN1cnJlbnQrK10gOwotICAgICAgICB9Ci0gICAgICAgIGVsc2V7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbigpIDsKLSAgICAgICAgfQotICAgIH0vL25leHQKLQotICAgIHB1YmxpYyB2b2lkIHJlbW92ZSgpIHsKLSAgICAgICAgLy9tYWtlIHN1cmUgdGhhdCBvbmx5IGxhc3QgcmV0dXJuZWQgaXRlbSBjYW4gYmUgcmVtb3ZlZC4KLSAgICAgICAgaWYoZkxhc3RSZXR1cm5lZEl0ZW0gPT0gZkF0dHJpYnV0ZXNbZkN1cnJlbnQgLSAxXSl7Ci0gICAgICAgICAgICAvL3JlbW92ZSB0aGUgYXR0cmlidXRlIGF0IGN1cnJlbnQgaW5kZXggYW5kIGxvd2VyIHRoZSBjdXJyZW50IHBvc2l0aW9uIGJ5IDEuCi0gICAgICAgICAgICByZW1vdmVBdHRyaWJ1dGVBdChmQ3VycmVudC0tKSA7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAvL2VpdGhlciB0aGUgbmV4dCBtZXRob2QgaGFzIGJlZW4gY2FsbGVkIHlldCwgb3IgdGhlIHJlbW92ZSBtZXRob2QgaGFzIGFscmVhZHkgYmVlbiBjYWxsZWQKLSAgICAgICAgICAgIC8vYWZ0ZXIgdGhlIGxhc3QgY2FsbCB0byB0aGUgbmV4dCBtZXRob2QuCi0gICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCk7Ci0gICAgICAgIH0KLSAgICB9Ly9yZW1vdmUKLQotICAgIHB1YmxpYyB2b2lkIHJlbW92ZUFsbEF0dHJpYnV0ZXMoKSB7Ci0gICAgICAgIHN1cGVyLnJlbW92ZUFsbEF0dHJpYnV0ZXMoKSA7Ci0gICAgICAgIGZDdXJyZW50ID0gMCA7Ci0gICAgfQotICAgIC8qKiB4eHg6IHNob3VsZCB3ZSBiZSBkb2luZyB0aGlzIHdheSA/IEF0dHJpYnV0ZSBldmVudCBkZWZpbmVzIHNvIG1hbnkgZnVuY3Rpb25zIHdoaWNoIGRvZXNuJ3QgbWFrZSBhbnkgc2Vuc2UKLSAgICAgKmZvciBBdHRyaWJ1dGUuCi0gICAgICoKLSAgICAgKi8KLSAgICAvKgotICAgIGNsYXNzIEF0dHJpYnV0ZUltcGwgZXh0ZW5kcyBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuWE1MQXR0cmlidXRlc0ltcGwuQXR0cmlidXRlIGltcGxlbWVudHMgamF2YXgueG1sLnN0cmVhbS5ldmVudHMuQXR0cmlidXRlewotCi0gICAgfQotICAgICAqLwotCi19IC8vWE1MQXR0cmlidXRlc0l0ZXJhdG9ySW1wbApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9YTUxDYXRhbG9nUmVzb2x2ZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3V0aWwvWE1MQ2F0YWxvZ1Jlc29sdmVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDYwZTA0MGQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9YTUxDYXRhbG9nUmVzb2x2ZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDU4NiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDA0LDIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbDsKLQotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci0KLWltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguZXh0LkVudGl0eVJlc29sdmVyMjsKLQotaW1wb3J0IG9yZy53M2MuZG9tLmxzLkxTSW5wdXQ7Ci1pbXBvcnQgb3JnLnczYy5kb20ubHMuTFNSZXNvdXJjZVJlc29sdmVyOwotCi1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyRmFjdG9yeTsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tLkRPTUlucHV0SW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmpheHAuU0FYUGFyc2VyRmFjdG9yeUltcGw7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTklFeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MUmVzb3VyY2VJZGVudGlmaWVyOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTEVudGl0eVJlc29sdmVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxJbnB1dFNvdXJjZTsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzb2x2ZXIuQ2F0YWxvZzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnJlc29sdmVyLkNhdGFsb2dNYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzb2x2ZXIucmVhZGVycy5PQVNJU1hNTENhdGFsb2dSZWFkZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXNvbHZlci5yZWFkZXJzLlNBWENhdGFsb2dSZWFkZXI7Ci0KLS8qKgotICogPHA+VGhlIGNhdGFsb2cgcmVzb2x2ZXIgaGFuZGxlcyB0aGUgcmVzb2x1dGlvbiBvZiBleHRlcm5hbAotICogaWRlbnRpZmllcnMgYW5kIFVSSSByZWZlcmVuY2VzIHRocm91Z2ggWE1MIGNhdGFsb2dzLiBUaGlzCi0gKiBjb21wb25lbnQgc3VwcG9ydHMgWE1MIGNhdGFsb2dzIGRlZmluZWQgYnkgdGhlCi0gKiA8YSBocmVmPSJodHRwOi8vd3d3Lm9hc2lzLW9wZW4ub3JnL2NvbW1pdHRlZXMvZW50aXR5L3NwZWMuaHRtbCI+Ci0gKiBPQVNJUyBYTUwgQ2F0YWxvZ3MgU3BlY2lmaWNhdGlvbjwvYT4uIEl0IGVuY2Fwc3VsYXRlcyB0aGUKLSAqIDxhIGhyZWY9Imh0dHA6Ly94bWwuYXBhY2hlLm9yZy9jb21tb25zLyI+WE1MIENvbW1vbnM8L2E+IHJlc29sdmVyLgotICogQW4gaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcyBtYXkgYmUgcmVnaXN0ZXJlZCBvbiB0aGUgcGFyc2VyCi0gKiBhcyBhIFNBWCBlbnRpdHkgcmVzb2x2ZXIsIGFzIGEgRE9NIExTUmVzb3VyY2VSZXNvbHZlciBvcgotICogYXMgYW4gWE5JIGVudGl0eSByZXNvbHZlciBieSBzZXR0aW5nIHRoZSBwcm9wZXJ0eQotICogKGh0dHA6Ly9hcGFjaGUub3JnL3htbC9wcm9wZXJ0aWVzL2ludGVybmFsL2VudGl0eS1yZXNvbHZlcikuPC9wPgotICoKLSAqIDxwPkl0IGlzIGludGVuZGVkIHRoYXQgdGhpcyBjbGFzcyBtYXkgYmUgdXNlZCBzdGFuZGFsb25lIHRvIHBlcmZvcm0KLSAqIGNhdGFsb2cgcmVzb2x1dGlvbiBvdXRzaWRlIG9mIGEgcGFyc2luZyBjb250ZXh0LiBJdCBtYXkgYmUgc2hhcmVkCi0gKiBiZXR3ZWVuIHNldmVyYWwgcGFyc2VycyBhbmQgdGhlIGFwcGxpY2F0aW9uLjwvcD4KLSAqCi0gKiBAYXV0aG9yIE1pY2hhZWwgR2xhdmFzc2V2aWNoLCBJQk0KLSAqCi0gKi8KLXB1YmxpYyBjbGFzcyBYTUxDYXRhbG9nUmVzb2x2ZXIKLSAgICBpbXBsZW1lbnRzIFhNTEVudGl0eVJlc29sdmVyLCBFbnRpdHlSZXNvbHZlcjIsIExTUmVzb3VyY2VSZXNvbHZlciB7Ci0KLSAgICAvKiogSW50ZXJuYWwgY2F0YWxvZyBtYW5hZ2VyIGZvciBBcGFjaGUgY2F0YWxvZ3MuICoqLwotICAgIHByaXZhdGUgQ2F0YWxvZ01hbmFnZXIgZlJlc29sdmVyQ2F0YWxvZ01hbmFnZXIgPSBudWxsOwotCi0gICAgLyoqIEludGVybmFsIGNhdGFsb2cgc3RydWN0dXJlLiAqKi8KLSAgICBwcml2YXRlIENhdGFsb2cgZkNhdGFsb2cgPSBudWxsOwotCi0gICAgLyoqIEFuIGFycmF5IG9mIGNhdGFsb2cgVVJJcy4gKiovCi0gICAgcHJpdmF0ZSBTdHJpbmcgW10gZkNhdGFsb2dzTGlzdCA9IG51bGw7Ci0KLSAgICAvKioKLSAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGUgbGlzdCBvZiBjYXRhbG9ncyBoYXMKLSAgICAgKiBjaGFuZ2VkIHNpbmNlIGl0IHdhcyBwcm9jZXNzZWQuCi0gICAgICovCi0gICAgcHJpdmF0ZSBib29sZWFuIGZDYXRhbG9nc0NoYW5nZWQgPSB0cnVlOwotCi0gICAgLyoqIEFwcGxpY2F0aW9uIHNwZWNpZmllZCBwcmVmZXIgcHVibGljIHNldHRpbmcuICoqLwotICAgIHByaXZhdGUgYm9vbGVhbiBmUHJlZmVyUHVibGljID0gdHJ1ZTsKLQotICAgIC8qKgotICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoZSBhcHBsaWNhdGlvbiBkZXNpcmVzIHRoYXQKLSAgICAgKiB0aGUgcGFyc2VyIG9yIHNvbWUgb3RoZXIgY29tcG9uZW50IHBlcmZvcm1pbmcgY2F0YWxvZwotICAgICAqIHJlc29sdXRpb24gc2hvdWxkIHVzZSB0aGUgbGl0ZXJhbCBzeXN0ZW0gaWRlbnRpZmllcgotICAgICAqIGluc3RlYWQgb2YgdGhlIGV4cGFuZGVkIHN5c3RlbSBpZGVudGlmaWVyLgotICAgICAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBmVXNlTGl0ZXJhbFN5c3RlbUlkID0gdHJ1ZTsKLQotICAgIC8qKgotICAgICAqIDxwPkNvbnN0cnVjdHMgYSBjYXRhbG9nIHJlc29sdmVyIHdpdGggYSBkZWZhdWx0IGNvbmZpZ3VyYXRpb24uPC9wPgotICAgICAqLwotICAgIHB1YmxpYyBYTUxDYXRhbG9nUmVzb2x2ZXIgKCkgewotICAgICAgICB0aGlzKG51bGwsIHRydWUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPkNvbnN0cnVjdHMgYSBjYXRhbG9nIHJlc29sdmVyIHdpdGggdGhlIGdpdmVuCi0gICAgICogbGlzdCBvZiBlbnRyeSBmaWxlcy48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gY2F0YWxvZ3MgYW4gb3JkZXJlZCBhcnJheSBsaXN0IG9mIGFic29sdXRlIFVSSXMKLSAgICAgKi8KLSAgICBwdWJsaWMgWE1MQ2F0YWxvZ1Jlc29sdmVyIChTdHJpbmcgW10gY2F0YWxvZ3MpIHsKLSAgICAgICAgdGhpcyhjYXRhbG9ncywgdHJ1ZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+Q29uc3RydWN0cyBhIGNhdGFsb2cgcmVzb2x2ZXIgd2l0aCB0aGUgZ2l2ZW4KLSAgICAgKiBsaXN0IG9mIGVudHJ5IGZpbGVzIGFuZCB0aGUgcHJlZmVyZW5jZSBmb3Igd2hldGhlcgotICAgICAqIHN5c3RlbSBvciBwdWJsaWMgbWF0Y2hlcyBhcmUgcHJlZmVycmVkLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjYXRhbG9ncyBhbiBvcmRlcmVkIGFycmF5IGxpc3Qgb2YgYWJzb2x1dGUgVVJJcwotICAgICAqIEBwYXJhbSBwcmVmZXJQdWJsaWMgdGhlIHByZWZlciBwdWJsaWMgc2V0dGluZwotICAgICAqLwotICAgIHB1YmxpYyBYTUxDYXRhbG9nUmVzb2x2ZXIgKFN0cmluZyBbXSBjYXRhbG9ncywgYm9vbGVhbiBwcmVmZXJQdWJsaWMpIHsKLSAgICAgICAgaW5pdChjYXRhbG9ncywgcHJlZmVyUHVibGljKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5SZXR1cm5zIHRoZSBpbml0aWFsIGxpc3Qgb2YgY2F0YWxvZyBlbnRyeSBmaWxlcy48L3A+Ci0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRoZSBpbml0aWFsIGxpc3Qgb2YgY2F0YWxvZyBlbnRyeSBmaWxlcwotICAgICAqLwotICAgIHB1YmxpYyBmaW5hbCBzeW5jaHJvbml6ZWQgU3RyaW5nIFtdIGdldENhdGFsb2dMaXN0ICgpIHsKLSAgICAgICAgcmV0dXJuIChmQ2F0YWxvZ3NMaXN0ICE9IG51bGwpCi0gICAgICAgICAgICA/IChTdHJpbmdbXSkgZkNhdGFsb2dzTGlzdC5jbG9uZSgpIDogbnVsbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5TZXRzIHRoZSBpbml0aWFsIGxpc3Qgb2YgY2F0YWxvZyBlbnRyeSBmaWxlcy4KLSAgICAgKiBJZiB0aGVyZSB3ZXJlIGFueSBjYXRhbG9nIG1hcHBpbmdzIGNhY2hlZCBmcm9tCi0gICAgICogdGhlIHByZXZpb3VzIGxpc3QgdGhleSB3aWxsIGJlIHJlcGxhY2VkIGJ5IGNhdGFsb2cKLSAgICAgKiBtYXBwaW5ncyBmcm9tIHRoZSBuZXcgbGlzdCB0aGUgbmV4dCB0aW1lIHRoZSBjYXRhbG9nCi0gICAgICogaXMgcXVlcmllZC48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gY2F0YWxvZ3MgYW4gb3JkZXJlZCBhcnJheSBsaXN0IG9mIGFic29sdXRlIFVSSXMKLSAgICAgKi8KLSAgICBwdWJsaWMgZmluYWwgc3luY2hyb25pemVkIHZvaWQgc2V0Q2F0YWxvZ0xpc3QgKFN0cmluZyBbXSBjYXRhbG9ncykgewotICAgICAgICBmQ2F0YWxvZ3NDaGFuZ2VkID0gdHJ1ZTsKLSAgICAgICAgZkNhdGFsb2dzTGlzdCA9IChjYXRhbG9ncyAhPSBudWxsKQotICAgICAgICAgICAgPyAoU3RyaW5nW10pIGNhdGFsb2dzLmNsb25lKCkgOiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPkZvcmNlcyB0aGUgY2FjaGUgb2YgY2F0YWxvZyBtYXBwaW5ncyB0byBiZSBjbGVhcmVkLjwvcD4KLSAgICAgKi8KLSAgICBwdWJsaWMgZmluYWwgc3luY2hyb25pemVkIHZvaWQgY2xlYXIgKCkgewotICAgICAgICBmQ2F0YWxvZyA9IG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+UmV0dXJucyB0aGUgcHJlZmVyZW5jZSBmb3Igd2hldGhlciBzeXN0ZW0gb3IgcHVibGljCi0gICAgICogbWF0Y2hlcyBhcmUgcHJlZmVycmVkLiBUaGlzIGlzIHVzZWQgaW4gdGhlIGFic2VuY2UKLSAgICAgKiBvZiBhbnkgb2NjdXJlbmNlIG9mIHRoZSA8Y29kZT5wcmVmZXI8L2NvZGU+IGF0dHJpYnV0ZQotICAgICAqIG9uIHRoZSA8Y29kZT5jYXRhbG9nPC9jb2RlPiBlbnRyeSBvZiBhIGNhdGFsb2cuIElmIHRoaXMKLSAgICAgKiBwcm9wZXJ0eSBoYXMgbm90IHlldCBiZWVuIGV4cGxpY2l0bHkgc2V0IGl0cyB2YWx1ZSBpcwotICAgICAqIDxjb2RlPnRydWU8L2NvZGU+LjwvcD4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdGhlIHByZWZlciBwdWJsaWMgc2V0dGluZwotICAgICAqLwotICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGdldFByZWZlclB1YmxpYyAoKSB7Ci0gICAgICAgIHJldHVybiBmUHJlZmVyUHVibGljOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPlNldHMgdGhlIHByZWZlcmVuY2UgZm9yIHdoZXRoZXIgc3lzdGVtIG9yIHB1YmxpYwotICAgICAqIG1hdGNoZXMgYXJlIHByZWZlcnJlZC4gVGhpcyBpcyB1c2VkIGluIHRoZSBhYnNlbmNlCi0gICAgICogb2YgYW55IG9jY3VyZW5jZSBvZiB0aGUgPGNvZGU+cHJlZmVyPC9jb2RlPiBhdHRyaWJ1dGUKLSAgICAgKiBvbiB0aGUgPGNvZGU+Y2F0YWxvZzwvY29kZT4gZW50cnkgb2YgYSBjYXRhbG9nLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBwcmVmZXJQdWJsaWMgdGhlIHByZWZlciBwdWJsaWMgc2V0dGluZwotICAgICAqLwotICAgIHB1YmxpYyBmaW5hbCB2b2lkIHNldFByZWZlclB1YmxpYyAoYm9vbGVhbiBwcmVmZXJQdWJsaWMpIHsKLSAgICAgICAgZlByZWZlclB1YmxpYyA9IHByZWZlclB1YmxpYzsKLSAgICAgICAgZlJlc29sdmVyQ2F0YWxvZ01hbmFnZXIuc2V0UHJlZmVyUHVibGljKHByZWZlclB1YmxpYyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+UmV0dXJucyB0aGUgcHJlZmVyZW5jZSBmb3Igd2hldGhlciB0aGUgbGl0ZXJhbCBzeXN0ZW0KLSAgICAgKiBpZGVudGlmaWVyIHNob3VsZCBiZSB1c2VkIHdoZW4gcmVzb2x2aW5nIHN5c3RlbQotICAgICAqIGlkZW50aWZpZXJzIHdoZW4gYm90aCBpdCBhbmQgdGhlIGV4cGFuZGVkIHN5c3RlbQotICAgICAqIGlkZW50aWZpZXIgYXJlIGF2YWlsYWJsZS4gSWYgdGhpcyBwcm9wZXJ0eSBoYXMgbm90IHlldAotICAgICAqIGJlZW4gZXhwbGljaXRseSBzZXQgaXRzIHZhbHVlIGlzIDxjb2RlPnRydWU8L2NvZGU+LjwvcD4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdGhlIHByZWZlcmVuY2UgZm9yIHVzaW5nIGxpdGVyYWwgc3lzdGVtIGlkZW50aWZlcnMKLSAgICAgKiBmb3IgY2F0YWxvZyByZXNvbHV0aW9uCi0gICAgICoKLSAgICAgKiBAc2VlICNzZXRVc2VMaXRlcmFsU3lzdGVtSWQKLSAgICAgKi8KLSAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBnZXRVc2VMaXRlcmFsU3lzdGVtSWQgKCkgewotICAgICAgICByZXR1cm4gZlVzZUxpdGVyYWxTeXN0ZW1JZDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5TZXRzIHRoZSBwcmVmZXJlbmNlIGZvciB3aGV0aGVyIHRoZSBsaXRlcmFsIHN5c3RlbQotICAgICAqIGlkZW50aWZpZXIgc2hvdWxkIGJlIHVzZWQgd2hlbiByZXNvbHZpbmcgc3lzdGVtCi0gICAgICogaWRlbnRpZmllcnMgd2hlbiBib3RoIGl0IGFuZCB0aGUgZXhwYW5kZWQgc3lzdGVtCi0gICAgICogaWRlbnRpZmllciBhcmUgYXZhaWxhYmxlLjwvcD4KLSAgICAgKgotICAgICAqIDxwPlRoZSBsaXRlcmFsIHN5c3RlbSBpZGVudGlmaWVyIGlzIHRoZSBVUkkgYXMgaXQgd2FzCi0gICAgICogcHJvdmlkZWQgYmVmb3JlIGFic29sdXRpemF0aW9uLiBJdCBtYXkgYmUgZW1iZWRkZWQgd2l0aGluCi0gICAgICogYW4gZW50aXR5LiBJdCBtYXkgYmUgcHJvdmlkZWQgZXh0ZXJuYWxseSBvciBpdCBtYXkgYmUgdGhlCi0gICAgICogcmVzdWx0IG9mIHJlZGlyZWN0aW9uLiBGb3IgZXhhbXBsZSwgcmVkaXJlY3Rpb24gbWF5Ci0gICAgICogaGF2ZSBjb21lIGZyb20gdGhlIHByb3RvY29sIGxldmVsIHRocm91Z2ggSFRUUCBvciBmcm9tCi0gICAgICogYW4gYXBwbGljYXRpb24ncyBlbnRpdHkgcmVzb2x2ZXIuPC9wPgotICAgICAqCi0gICAgICogPHA+VGhlIGV4cGFuZGVkIHN5c3RlbSBpZGVudGlmaWVyIGlzIGFuIGFic29sdXRlIFVSSQotICAgICAqIHdoaWNoIGlzIHRoZSByZXN1bHQgb2YgcmVzb2x2aW5nIHRoZSBsaXRlcmFsIHN5c3RlbQotICAgICAqIGlkZW50aWZpZXIgYWdhaW5zdCBhIGJhc2UgVVJJLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSB1c2VMaXRlcmFsU3lzdGVtSWQgdGhlIHByZWZlcmVuY2UgZm9yIHVzaW5nCi0gICAgICogbGl0ZXJhbCBzeXN0ZW0gaWRlbnRpZmVycyBmb3IgY2F0YWxvZyByZXNvbHV0aW9uCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIHZvaWQgc2V0VXNlTGl0ZXJhbFN5c3RlbUlkIChib29sZWFuIHVzZUxpdGVyYWxTeXN0ZW1JZCkgewotICAgICAgICBmVXNlTGl0ZXJhbFN5c3RlbUlkID0gdXNlTGl0ZXJhbFN5c3RlbUlkOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPlJlc29sdmVzIGFuIGV4dGVybmFsIGVudGl0eS4gSWYgdGhlIGVudGl0eSBjYW5ub3QgYmUKLSAgICAgKiByZXNvbHZlZCwgdGhpcyBtZXRob2Qgc2hvdWxkIHJldHVybiA8Y29kZT5udWxsPC9jb2RlPi4gVGhpcwotICAgICAqIG1ldGhvZCByZXR1cm5zIGFuIGlucHV0IHNvdXJjZSBpZiBhbiBlbnRyeSB3YXMgZm91bmQgaW4gdGhlCi0gICAgICogY2F0YWxvZyBmb3IgdGhlIGdpdmVuIGV4dGVybmFsIGlkZW50aWZpZXIuIEl0IHNob3VsZCBiZQotICAgICAqIG92ZXJyaWRlZCBpZiBvdGhlciBiZWhhdmlvdXIgaXMgcmVxdWlyZWQuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIHB1YmxpY0lkIHRoZSBwdWJsaWMgaWRlbnRpZmllciwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgbm9uZSB3YXMgc3VwcGxpZWQKLSAgICAgKiBAcGFyYW0gc3lzdGVtSWQgdGhlIHN5c3RlbSBpZGVudGlmaWVyCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBhbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24KLSAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIHRocm93biBpZiBzb21lIGkvbyBlcnJvciBvY2N1cnMKLSAgICAgKi8KLSAgICBwdWJsaWMgSW5wdXRTb3VyY2UgcmVzb2x2ZUVudGl0eShTdHJpbmcgcHVibGljSWQsIFN0cmluZyBzeXN0ZW1JZCkKLSAgICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKLQotICAgICAgICBTdHJpbmcgcmVzb2x2ZWRJZCA9IG51bGw7Ci0gICAgICAgIGlmIChwdWJsaWNJZCAhPSBudWxsICYmIHN5c3RlbUlkICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJlc29sdmVkSWQgPSByZXNvbHZlUHVibGljKHB1YmxpY0lkLCBzeXN0ZW1JZCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoc3lzdGVtSWQgIT0gbnVsbCkgewotICAgICAgICAgICAgcmVzb2x2ZWRJZCA9IHJlc29sdmVTeXN0ZW0oc3lzdGVtSWQpOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKHJlc29sdmVkSWQgIT0gbnVsbCkgewotICAgICAgICAgICAgSW5wdXRTb3VyY2Ugc291cmNlID0gbmV3IElucHV0U291cmNlKHJlc29sdmVkSWQpOwotICAgICAgICAgICAgc291cmNlLnNldFB1YmxpY0lkKHB1YmxpY0lkKTsKLSAgICAgICAgICAgIHJldHVybiBzb3VyY2U7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgIC8qKgotICAgICAgKiA8cD5SZXNvbHZlcyBhbiBleHRlcm5hbCBlbnRpdHkuIElmIHRoZSBlbnRpdHkgY2Fubm90IGJlCi0gICAgICAqIHJlc29sdmVkLCB0aGlzIG1ldGhvZCBzaG91bGQgcmV0dXJuIDxjb2RlPm51bGw8L2NvZGU+LiBUaGlzCi0gICAgICAqIG1ldGhvZCByZXR1cm5zIGFuIGlucHV0IHNvdXJjZSBpZiBhbiBlbnRyeSB3YXMgZm91bmQgaW4gdGhlCi0gICAgICAqIGNhdGFsb2cgZm9yIHRoZSBnaXZlbiBleHRlcm5hbCBpZGVudGlmaWVyLiBJdCBzaG91bGQgYmUKLSAgICAgICogb3ZlcnJpZGVkIGlmIG90aGVyIGJlaGF2aW91ciBpcyByZXF1aXJlZC48L3A+Ci0gICAgICAqCi0gICAgICAqIEBwYXJhbSBuYW1lIHRoZSBpZGVudGlmaWVyIG9mIHRoZSBleHRlcm5hbCBlbnRpdHkKLSAgICAgICogQHBhcmFtIHB1YmxpY0lkIHRoZSBwdWJsaWMgaWRlbnRpZmllciwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgbm9uZSB3YXMgc3VwcGxpZWQKLSAgICAgICogQHBhcmFtIGJhc2VVUkkgdGhlIFVSSSB3aXRoIHJlc3BlY3QgdG8gd2hpY2ggcmVsYXRpdmUgc3lzdGVtSURzIGFyZSBpbnRlcnByZXRlZC4KLSAgICAgICogQHBhcmFtIHN5c3RlbUlkIHRoZSBzeXN0ZW0gaWRlbnRpZmllcgotICAgICAgKgotICAgICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBhbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24KLSAgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiB0aHJvd24gaWYgc29tZSBpL28gZXJyb3Igb2NjdXJzCi0gICAgICAqLwotICAgICBwdWJsaWMgSW5wdXRTb3VyY2UgcmVzb2x2ZUVudGl0eShTdHJpbmcgbmFtZSwgU3RyaW5nIHB1YmxpY0lkLAotICAgICAgICAgU3RyaW5nIGJhc2VVUkksIFN0cmluZyBzeXN0ZW1JZCkgdGhyb3dzIFNBWEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewotCi0gICAgICAgICBTdHJpbmcgcmVzb2x2ZWRJZCA9IG51bGw7Ci0KLSAgICAgICAgIGlmICghZ2V0VXNlTGl0ZXJhbFN5c3RlbUlkKCkgJiYgYmFzZVVSSSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgLy8gQXR0ZW1wdCB0byByZXNvbHZlIHRoZSBzeXN0ZW0gaWRlbnRpZmllciBhZ2FpbnN0IHRoZSBiYXNlIFVSSS4KLSAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICBVUkkgdXJpID0gbmV3IFVSSShuZXcgVVJJKGJhc2VVUkkpLCBzeXN0ZW1JZCk7Ci0gICAgICAgICAgICAgICAgIHN5c3RlbUlkID0gdXJpLnRvU3RyaW5nKCk7Ci0gICAgICAgICAgICAgfQotICAgICAgICAgICAgIC8vIElnbm9yZSB0aGUgZXhjZXB0aW9uLiBGYWxsYmFjayB0byB0aGUgbGl0ZXJhbCBzeXN0ZW0gaWRlbnRpZmllci4KLSAgICAgICAgICAgICBjYXRjaCAoVVJJLk1hbGZvcm1lZFVSSUV4Y2VwdGlvbiBleCkge30KLSAgICAgICAgIH0KLQotICAgICAgICAgaWYgKHB1YmxpY0lkICE9IG51bGwgJiYgc3lzdGVtSWQgIT0gbnVsbCkgewotICAgICAgICAgICAgIHJlc29sdmVkSWQgPSByZXNvbHZlUHVibGljKHB1YmxpY0lkLCBzeXN0ZW1JZCk7Ci0gICAgICAgICB9Ci0gICAgICAgICBlbHNlIGlmIChzeXN0ZW1JZCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgcmVzb2x2ZWRJZCA9IHJlc29sdmVTeXN0ZW0oc3lzdGVtSWQpOwotICAgICAgICAgfQotCi0gICAgICAgICBpZiAocmVzb2x2ZWRJZCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgSW5wdXRTb3VyY2Ugc291cmNlID0gbmV3IElucHV0U291cmNlKHJlc29sdmVkSWQpOwotICAgICAgICAgICAgIHNvdXJjZS5zZXRQdWJsaWNJZChwdWJsaWNJZCk7Ci0gICAgICAgICAgICAgcmV0dXJuIHNvdXJjZTsKLSAgICAgICAgIH0KLSAgICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgICAvKioKLSAgICAgICogPHA+TG9jYXRlcyBhbiBleHRlcm5hbCBzdWJzZXQgZm9yIGRvY3VtZW50cyB3aGljaCBkbyBub3QgZXhwbGljaXRseQotICAgICAgKiBwcm92aWRlIG9uZS4gVGhpcyBtZXRob2QgYWx3YXlzIHJldHVybnMgPGNvZGU+bnVsbDwvY29kZT4uIEl0Ci0gICAgICAqIHNob3VsZCBiZSBvdmVycmlkZWQgaWYgb3RoZXIgYmVoYXZpb3VyIGlzIHJlcXVpcmVkLjwvcD4KLSAgICAgICoKLSAgICAgICogQHBhcmFtIG5hbWUgdGhlIGlkZW50aWZpZXIgb2YgdGhlIGRvY3VtZW50IHJvb3QgZWxlbWVudAotICAgICAgKiBAcGFyYW0gYmFzZVVSSSB0aGUgZG9jdW1lbnQncyBiYXNlIFVSSQotICAgICAgKgotICAgICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBhbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24KLSAgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiB0aHJvd24gaWYgc29tZSBpL28gZXJyb3Igb2NjdXJzCi0gICAgICAqLwotICAgICBwdWJsaWMgSW5wdXRTb3VyY2UgZ2V0RXh0ZXJuYWxTdWJzZXQoU3RyaW5nIG5hbWUsIFN0cmluZyBiYXNlVVJJKQotICAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewotICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPlJlc29sdmVzIGEgcmVzb3VyY2UgdXNpbmcgdGhlIGNhdGFsb2cuIFRoaXMgbWV0aG9kIGludGVycHJldHMgdGhhdAotICAgICAqIHRoZSBuYW1lc3BhY2UgVVJJIGNvcnJlc3BvbmRzIHRvIHVyaSBlbnRyaWVzIGluIHRoZSBjYXRhbG9nLgotICAgICAqIFdoZXJlIGJvdGggYSBuYW1lc3BhY2UgYW5kIGFuIGV4dGVybmFsIGlkZW50aWZpZXIgZXhpc3QsIHRoZSBuYW1lc3BhY2UKLSAgICAgKiB0YWtlcyBwcmVjZWRlbmNlLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSB0eXBlIHRoZSB0eXBlIG9mIHRoZSByZXNvdXJjZSBiZWluZyByZXNvbHZlZAotICAgICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkgdGhlIG5hbWVzcGFjZSBvZiB0aGUgcmVzb3VyY2UgYmVpbmcgcmVzb2x2ZWQsCi0gICAgICogb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgbm9uZSB3YXMgc3VwcGxpZWQKLSAgICAgKiBAcGFyYW0gcHVibGljSWQgdGhlIHB1YmxpYyBpZGVudGlmaWVyIG9mIHRoZSByZXNvdXJjZSBiZWluZyByZXNvbHZlZCwKLSAgICAgKiBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiBub25lIHdhcyBzdXBwbGllZAotICAgICAqIEBwYXJhbSBzeXN0ZW1JZCB0aGUgc3lzdGVtIGlkZW50aWZpZXIgb2YgdGhlIHJlc291cmNlIGJlaW5nIHJlc29sdmVkLAotICAgICAqIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIG5vbmUgd2FzIHN1cHBsaWVkCi0gICAgICogQHBhcmFtIGJhc2VVUkkgdGhlIGFic29sdXRlIGJhc2UgVVJJIG9mIHRoZSByZXNvdXJjZSBiZWluZyBwYXJzZWQsCi0gICAgICogb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlcmUgaXMgbm8gYmFzZSBVUkkKLSAgICAgKi8KLSAgICBwdWJsaWMgTFNJbnB1dCByZXNvbHZlUmVzb3VyY2UoU3RyaW5nIHR5cGUsIFN0cmluZyBuYW1lc3BhY2VVUkksCi0gICAgICAgIFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkLCBTdHJpbmcgYmFzZVVSSSkgewotCi0gICAgICAgIFN0cmluZyByZXNvbHZlZElkID0gbnVsbDsKLQotICAgICAgICB0cnkgewotICAgICAgICAgICAgLy8gVGhlIG5hbWVzcGFjZSBpcyB1c2VmdWwgZm9yIHJlc29sdmluZyBuYW1lc3BhY2UgYXdhcmUKLSAgICAgICAgICAgIC8vIGdyYW1tYXJzIHN1Y2ggYXMgWE1MIHNjaGVtYS4gTGV0IGl0IHRha2UgcHJlY2VkZW5jZSBvdmVyCi0gICAgICAgICAgICAvLyB0aGUgZXh0ZXJuYWwgaWRlbnRpZmllciBpZiBvbmUgZXhpc3RzLgotICAgICAgICAgICAgaWYgKG5hbWVzcGFjZVVSSSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgcmVzb2x2ZWRJZCA9IHJlc29sdmVVUkkobmFtZXNwYWNlVVJJKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKCFnZXRVc2VMaXRlcmFsU3lzdGVtSWQoKSAmJiBiYXNlVVJJICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAvLyBBdHRlbXB0IHRvIHJlc29sdmUgdGhlIHN5c3RlbSBpZGVudGlmaWVyIGFnYWluc3QgdGhlIGJhc2UgVVJJLgotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgIFVSSSB1cmkgPSBuZXcgVVJJKG5ldyBVUkkoYmFzZVVSSSksIHN5c3RlbUlkKTsKLSAgICAgICAgICAgICAgICAgICAgc3lzdGVtSWQgPSB1cmkudG9TdHJpbmcoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLy8gSWdub3JlIHRoZSBleGNlcHRpb24uIEZhbGxiYWNrIHRvIHRoZSBsaXRlcmFsIHN5c3RlbSBpZGVudGlmaWVyLgotICAgICAgICAgICAgICAgIGNhdGNoIChVUkkuTWFsZm9ybWVkVVJJRXhjZXB0aW9uIGV4KSB7fQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBSZXNvbHZlIGFnYWluc3QgYW4gZXh0ZXJuYWwgaWRlbnRpZmllciBpZiBvbmUgZXhpc3RzLiBUaGlzCi0gICAgICAgICAgICAvLyBpcyB1c2VmdWwgZm9yIHJlc29sdmluZyBEVEQgZXh0ZXJuYWwgc3Vic2V0cyBhbmQgb3RoZXIKLSAgICAgICAgICAgIC8vIGV4dGVybmFsIGVudGl0aWVzLiBGb3IgWE1MIHNjaGVtYXMgaWYgdGhlcmUgd2FzIG5vIG5hbWVzcGFjZQotICAgICAgICAgICAgLy8gbWFwcGluZyB3ZSBtaWdodCBiZSBhYmxlIHRvIHJlc29sdmUgYSBzeXN0ZW0gaWRlbnRpZmllcgotICAgICAgICAgICAgLy8gc3BlY2lmaWVkIGFzIGEgbG9jYXRpb24gaGludC4KLSAgICAgICAgICAgIGlmIChyZXNvbHZlZElkID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBpZiAocHVibGljSWQgIT0gbnVsbCAmJiBzeXN0ZW1JZCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJlc29sdmVkSWQgPSByZXNvbHZlUHVibGljKHB1YmxpY0lkLCBzeXN0ZW1JZCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgaWYgKHN5c3RlbUlkICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZWRJZCA9IHJlc29sdmVTeXN0ZW0oc3lzdGVtSWQpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICAvLyBJZ25vcmUgSU9FeGNlcHRpb24uIEl0IGNhbm5vdCBiZSB0aHJvd24gZnJvbSB0aGlzIG1ldGhvZC4KLSAgICAgICAgY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7fQotCi0gICAgICAgIGlmIChyZXNvbHZlZElkICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBuZXcgRE9NSW5wdXRJbXBsKHB1YmxpY0lkLCByZXNvbHZlZElkLCBiYXNlVVJJKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIDxwPlJlc29sdmVzIGFuIGV4dGVybmFsIGVudGl0eS4gSWYgdGhlIGVudGl0eSBjYW5ub3QgYmUKLSAgICAgKiByZXNvbHZlZCwgdGhpcyBtZXRob2Qgc2hvdWxkIHJldHVybiA8Y29kZT5udWxsPC9jb2RlPi4gVGhpcwotICAgICAqIG1ldGhvZCBvbmx5IGNhbGxzIDxjb2RlPnJlc29sdmVJZGVudGlmaWVyPC9jb2RlPiBhbmQgcmV0dXJucwotICAgICAqIGFuIGlucHV0IHNvdXJjZSBpZiBhbiBlbnRyeSB3YXMgZm91bmQgaW4gdGhlIGNhdGFsb2cuIEl0Ci0gICAgICogc2hvdWxkIGJlIG92ZXJyaWRlZCBpZiBvdGhlciBiZWhhdmlvdXIgaXMgcmVxdWlyZWQuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIHJlc291cmNlSWRlbnRpZmllciBsb2NhdGlvbiBvZiB0aGUgWE1MIHJlc291cmNlIHRvIHJlc29sdmUKLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIHRocm93biBvbiBnZW5lcmFsIGVycm9yCi0gICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiB0aHJvd24gaWYgc29tZSBpL28gZXJyb3Igb2NjdXJzCi0gICAgICovCi0gICAgcHVibGljIFhNTElucHV0U291cmNlIHJlc29sdmVFbnRpdHkoWE1MUmVzb3VyY2VJZGVudGlmaWVyIHJlc291cmNlSWRlbnRpZmllcikKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewotCi0gICAgICAgIFN0cmluZyByZXNvbHZlZElkID0gcmVzb2x2ZUlkZW50aWZpZXIocmVzb3VyY2VJZGVudGlmaWVyKTsKLSAgICAgICAgaWYgKHJlc29sdmVkSWQgIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIG5ldyBYTUxJbnB1dFNvdXJjZShyZXNvdXJjZUlkZW50aWZpZXIuZ2V0UHVibGljSWQoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZWRJZCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb3VyY2VJZGVudGlmaWVyLmdldEJhc2VTeXN0ZW1JZCgpKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5SZXNvbHZlcyBhbiBpZGVudGlmaWVyIHVzaW5nIHRoZSBjYXRhbG9nLiBUaGlzIG1ldGhvZCBpbnRlcnByZXRzIHRoYXQKLSAgICAgKiB0aGUgbmFtZXNwYWNlIG9mIHRoZSBpZGVudGlmaWVyIGNvcnJlc3BvbmRzIHRvIHVyaSBlbnRyaWVzIGluIHRoZSBjYXRhbG9nLgotICAgICAqIFdoZXJlIGJvdGggYSBuYW1lc3BhY2UgYW5kIGFuIGV4dGVybmFsIGlkZW50aWZpZXIgZXhpc3QsIHRoZSBuYW1lc3BhY2UKLSAgICAgKiB0YWtlcyBwcmVjZWRlbmNlLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSByZXNvdXJjZUlkZW50aWZpZXIgdGhlIGlkZW50aWZpZXIgdG8gcmVzb2x2ZQotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gdGhyb3duIG9uIGdlbmVyYWwgZXJyb3IKLSAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIHRocm93biBpZiBzb21lIGkvbyBlcnJvciBvY2N1cnMKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIHJlc29sdmVJZGVudGlmaWVyKFhNTFJlc291cmNlSWRlbnRpZmllciByZXNvdXJjZUlkZW50aWZpZXIpCi0gICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgWE5JRXhjZXB0aW9uIHsKLQotICAgICAgICBTdHJpbmcgcmVzb2x2ZWRJZCA9IG51bGw7Ci0KLSAgICAgICAgLy8gVGhlIG5hbWVzcGFjZSBpcyB1c2VmdWwgZm9yIHJlc29sdmluZyBuYW1lc3BhY2UgYXdhcmUKLSAgICAgICAgLy8gZ3JhbW1hcnMgc3VjaCBhcyBYTUwgc2NoZW1hLiBMZXQgaXQgdGFrZSBwcmVjZWRlbmNlIG92ZXIKLSAgICAgICAgLy8gdGhlIGV4dGVybmFsIGlkZW50aWZpZXIgaWYgb25lIGV4aXN0cy4KLSAgICAgICAgU3RyaW5nIG5hbWVzcGFjZSA9IHJlc291cmNlSWRlbnRpZmllci5nZXROYW1lc3BhY2UoKTsKLSAgICAgICAgaWYgKG5hbWVzcGFjZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXNvbHZlZElkID0gcmVzb2x2ZVVSSShuYW1lc3BhY2UpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gUmVzb2x2ZSBhZ2FpbnN0IGFuIGV4dGVybmFsIGlkZW50aWZpZXIgaWYgb25lIGV4aXN0cy4gVGhpcwotICAgICAgICAvLyBpcyB1c2VmdWwgZm9yIHJlc29sdmluZyBEVEQgZXh0ZXJuYWwgc3Vic2V0cyBhbmQgb3RoZXIKLSAgICAgICAgLy8gZXh0ZXJuYWwgZW50aXRpZXMuIEZvciBYTUwgc2NoZW1hcyBpZiB0aGVyZSB3YXMgbm8gbmFtZXNwYWNlCi0gICAgICAgIC8vIG1hcHBpbmcgd2UgbWlnaHQgYmUgYWJsZSB0byByZXNvbHZlIGEgc3lzdGVtIGlkZW50aWZpZXIKLSAgICAgICAgLy8gc3BlY2lmaWVkIGFzIGEgbG9jYXRpb24gaGludC4KLSAgICAgICAgaWYgKHJlc29sdmVkSWQgPT0gbnVsbCkgewotICAgICAgICAgICAgU3RyaW5nIHB1YmxpY0lkID0gcmVzb3VyY2VJZGVudGlmaWVyLmdldFB1YmxpY0lkKCk7Ci0gICAgICAgICAgICBTdHJpbmcgc3lzdGVtSWQgPSBnZXRVc2VMaXRlcmFsU3lzdGVtSWQoKQotICAgICAgICAgICAgICAgID8gcmVzb3VyY2VJZGVudGlmaWVyLmdldExpdGVyYWxTeXN0ZW1JZCgpCi0gICAgICAgICAgICAgICAgOiByZXNvdXJjZUlkZW50aWZpZXIuZ2V0RXhwYW5kZWRTeXN0ZW1JZCgpOwotICAgICAgICAgICAgaWYgKHB1YmxpY0lkICE9IG51bGwgJiYgc3lzdGVtSWQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJlc29sdmVkSWQgPSByZXNvbHZlUHVibGljKHB1YmxpY0lkLCBzeXN0ZW1JZCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChzeXN0ZW1JZCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgcmVzb2x2ZWRJZCA9IHJlc29sdmVTeXN0ZW0oc3lzdGVtSWQpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiByZXNvbHZlZElkOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPlJldHVybnMgdGhlIFVSSSBtYXBwaW5nIGluIHRoZSBjYXRhbG9nIGZvciB0aGUgZ2l2ZW4KLSAgICAgKiBleHRlcm5hbCBpZGVudGlmaWVyIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIG5vIG1hcHBpbmcKLSAgICAgKiBleGlzdHMuIElmIHRoZSBzeXN0ZW0gaWRlbnRpZmllciBpcyBhbiBVUk4gaW4gdGhlCi0gICAgICogPGNvZGU+cHVibGljaWQ8L2NvZGU+IG5hbWVzcGFjZSBpdCBpcyBjb252ZXJ0ZWQgaW50bwotICAgICAqIGEgcHVibGljIGlkZW50aWZpZXIgYnkgVVJOICJ1bndyYXBwaW5nIiBhcyBzcGVjaWZpZWQKLSAgICAgKiBpbiB0aGUgWE1MIENhdGFsb2dzIHNwZWNpZmljYXRpb24uPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIHN5c3RlbUlkIHRoZSBzeXN0ZW0gaWRlbnRpZmllciB0byBsb2NhdGUgaW4gdGhlIGNhdGFsb2cKLSAgICAgKgotICAgICAqIEByZXR1cm4gdGhlIG1hcHBlZCBVUkkgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgbm8gbWFwcGluZwotICAgICAqIHdhcyBmb3VuZCBpbiB0aGUgY2F0YWxvZwotICAgICAqCi0gICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiBhbiBpL28gZXJyb3Igb2NjdXJyZWQgd2hpbGUgcmVhZGluZwotICAgICAqIHRoZSBjYXRhbG9nCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIHN5bmNocm9uaXplZCBTdHJpbmcgcmVzb2x2ZVN5c3RlbSAoU3RyaW5nIHN5c3RlbUlkKQotICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24gewotCi0gICAgICAgIGlmIChmQ2F0YWxvZ3NDaGFuZ2VkKSB7Ci0gICAgICAgICAgICBwYXJzZUNhdGFsb2dzKCk7Ci0gICAgICAgICAgICBmQ2F0YWxvZ3NDaGFuZ2VkID0gZmFsc2U7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIChmQ2F0YWxvZyAhPSBudWxsKQotICAgICAgICAgICAgPyBmQ2F0YWxvZy5yZXNvbHZlU3lzdGVtKHN5c3RlbUlkKSA6IG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+UmV0dXJucyB0aGUgVVJJIG1hcHBpbmcgaW4gdGhlIGNhdGFsb2cgZm9yIHRoZSBnaXZlbgotICAgICAqIGV4dGVybmFsIGlkZW50aWZpZXIgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgbm8gbWFwcGluZwotICAgICAqIGV4aXN0cy4gUHVibGljIGlkZW50aWZpZXJzIGFyZSBub3JtYWxpemVkIGJlZm9yZQotICAgICAqIGNvbXBhcmlzb24uPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIHB1YmxpY0lkIHRoZSBwdWJsaWMgaWRlbnRpZmllciB0byBsb2NhdGUgaW4gdGhlIGNhdGFsb2cKLSAgICAgKiBAcGFyYW0gc3lzdGVtSWQgdGhlIHN5c3RlbSBpZGVudGlmaWVyIHRvIGxvY2F0ZSBpbiB0aGUgY2F0YWxvZwotICAgICAqCi0gICAgICogQHJldHVybiB0aGUgbWFwcGVkIFVSSSBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiBubyBtYXBwaW5nCi0gICAgICogd2FzIGZvdW5kIGluIHRoZSBjYXRhbG9nCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIGFuIGkvbyBlcnJvciBvY2N1cnJlZCB3aGlsZSByZWFkaW5nCi0gICAgICogdGhlIGNhdGFsb2cKLSAgICAgKi8KLSAgICBwdWJsaWMgZmluYWwgc3luY2hyb25pemVkIFN0cmluZyByZXNvbHZlUHVibGljIChTdHJpbmcgcHVibGljSWQsIFN0cmluZyBzeXN0ZW1JZCkKLSAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKLQotICAgICAgICBpZiAoZkNhdGFsb2dzQ2hhbmdlZCkgewotICAgICAgICAgICAgcGFyc2VDYXRhbG9ncygpOwotICAgICAgICAgICAgZkNhdGFsb2dzQ2hhbmdlZCA9IGZhbHNlOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiAoZkNhdGFsb2cgIT0gbnVsbCkKLSAgICAgICAgICAgID8gZkNhdGFsb2cucmVzb2x2ZVB1YmxpYyhwdWJsaWNJZCwgc3lzdGVtSWQpIDogbnVsbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5SZXR1cm5zIHRoZSBVUkkgbWFwcGluZyBpbiB0aGUgY2F0YWxvZyBmb3IgdGhlIGdpdmVuIFVSSQotICAgICAqIHJlZmVyZW5jZSBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiBubyBtYXBwaW5nIGV4aXN0cy4KLSAgICAgKiBVUkkgY29tcGFyaXNvbiBpcyBjYXNlIHNlbnNpdGl2ZS4gSWYgdGhlIFVSSSByZWZlcmVuY2UKLSAgICAgKiBpcyBhbiBVUk4gaW4gdGhlIDxjb2RlPnB1YmxpY2lkPC9jb2RlPiBuYW1lc3BhY2UKLSAgICAgKiBpdCBpcyBjb252ZXJ0ZWQgaW50byBhIHB1YmxpYyBpZGVudGlmaWVyIGJ5IFVSTiAidW53cmFwcGluZyIKLSAgICAgKiBhcyBzcGVjaWZpZWQgaW4gdGhlIFhNTCBDYXRhbG9ncyBzcGVjaWZpY2F0aW9uIGFuZCB0aGVuCi0gICAgICogcmVzb2x1dGlvbiBpcyBwZXJmb3JtZWQgZm9sbG93aW5nIHRoZSBzZW1hbnRpY3Mgb2YKLSAgICAgKiBleHRlcm5hbCBpZGVudGlmaWVyIHJlc29sdXRpb24uPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIHVyaSB0aGUgVVJJIHRvIGxvY2F0ZSBpbiB0aGUgY2F0YWxvZwotICAgICAqCi0gICAgICogQHJldHVybiB0aGUgbWFwcGVkIFVSSSBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiBubyBtYXBwaW5nCi0gICAgICogd2FzIGZvdW5kIGluIHRoZSBjYXRhbG9nCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIGFuIGkvbyBlcnJvciBvY2N1cnJlZCB3aGlsZSByZWFkaW5nCi0gICAgICogdGhlIGNhdGFsb2cKLSAgICAgKi8KLSAgICBwdWJsaWMgZmluYWwgc3luY2hyb25pemVkIFN0cmluZyByZXNvbHZlVVJJIChTdHJpbmcgdXJpKQotICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24gewotCi0gICAgICAgIGlmIChmQ2F0YWxvZ3NDaGFuZ2VkKSB7Ci0gICAgICAgICAgICBwYXJzZUNhdGFsb2dzKCk7Ci0gICAgICAgICAgICBmQ2F0YWxvZ3NDaGFuZ2VkID0gZmFsc2U7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIChmQ2F0YWxvZyAhPSBudWxsKQotICAgICAgICAgICAgPyBmQ2F0YWxvZy5yZXNvbHZlVVJJKHVyaSkgOiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEluaXRpYWxpemF0aW9uLiBDcmVhdGUgYSBDYXRhbG9nTWFuYWdlciBhbmQgc2V0IGFsbAotICAgICAqIHRoZSBwcm9wZXJ0aWVzIHVwZnJvbnQuIFRoaXMgcHJldmVudHMgSlZNIHdpZGUgc3lzdGVtIHByb3BlcnRpZXMKLSAgICAgKiBvciBhIHByb3BlcnR5IGZpbGUgc29tZXdoZXJlIGluIHRoZSBlbnZpcm9ubWVudCBmcm9tIGFmZmVjdGluZwotICAgICAqIHRoZSBiZWhhdmlvdXIgb2YgdGhpcyBjYXRhbG9nIHJlc29sdmVyLgotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCBpbml0IChTdHJpbmcgW10gY2F0YWxvZ3MsIGJvb2xlYW4gcHJlZmVyUHVibGljKSB7Ci0gICAgICAgIGZDYXRhbG9nc0xpc3QgPSAoY2F0YWxvZ3MgIT0gbnVsbCkgPyAoU3RyaW5nW10pIGNhdGFsb2dzLmNsb25lKCkgOiBudWxsOwotICAgICAgICBmUHJlZmVyUHVibGljID0gcHJlZmVyUHVibGljOwotICAgICAgICBmUmVzb2x2ZXJDYXRhbG9nTWFuYWdlciA9IG5ldyBDYXRhbG9nTWFuYWdlcigpOwotICAgICAgICBmUmVzb2x2ZXJDYXRhbG9nTWFuYWdlci5zZXRBbGxvd09hc2lzWE1MQ2F0YWxvZ1BJKGZhbHNlKTsKLSAgICAgICAgZlJlc29sdmVyQ2F0YWxvZ01hbmFnZXIuc2V0Q2F0YWxvZ0NsYXNzTmFtZSgiY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXNvbHZlci5DYXRhbG9nIik7Ci0gICAgICAgIGZSZXNvbHZlckNhdGFsb2dNYW5hZ2VyLnNldENhdGFsb2dGaWxlcygiIik7Ci0gICAgICAgIGZSZXNvbHZlckNhdGFsb2dNYW5hZ2VyLnNldElnbm9yZU1pc3NpbmdQcm9wZXJ0aWVzKHRydWUpOwotICAgICAgICBmUmVzb2x2ZXJDYXRhbG9nTWFuYWdlci5zZXRQcmVmZXJQdWJsaWMoZlByZWZlclB1YmxpYyk7Ci0gICAgICAgIGZSZXNvbHZlckNhdGFsb2dNYW5hZ2VyLnNldFJlbGF0aXZlQ2F0YWxvZ3MoZmFsc2UpOwotICAgICAgICBmUmVzb2x2ZXJDYXRhbG9nTWFuYWdlci5zZXRVc2VTdGF0aWNDYXRhbG9nKGZhbHNlKTsKLSAgICAgICAgZlJlc29sdmVyQ2F0YWxvZ01hbmFnZXIuc2V0VmVyYm9zaXR5KDApOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEluc3RydWN0IHRoZSA8Y29kZT5DYXRhbG9nPC9jb2RlPiB0byBwYXJzZSBlYWNoIG9mIHRoZQotICAgICAqIGNhdGFsb2dzIGluIHRoZSBsaXN0LiBPbmx5IHRoZSBmaXJzdCBjYXRhbG9nIHdpbGwgYWN0dWFsbHkgYmUKLSAgICAgKiBwYXJzZWQgaW1tZWRpYXRlbHkuIFRoZSBvdGhlcnMgd2lsbCBiZSBxdWV1ZWQgYW5kIHJlYWQgaWYKLSAgICAgKiB0aGV5IGFyZSBuZWVkZWQgbGF0ZXIuCi0gICAgICovCi0gICAgcHJpdmF0ZSB2b2lkIHBhcnNlQ2F0YWxvZ3MgKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKGZDYXRhbG9nc0xpc3QgIT0gbnVsbCkgewotICAgICAgICAgICAgZkNhdGFsb2cgPSBuZXcgQ2F0YWxvZyhmUmVzb2x2ZXJDYXRhbG9nTWFuYWdlcik7Ci0gICAgICAgICAgICBhdHRhY2hSZWFkZXJUb0NhdGFsb2coZkNhdGFsb2cpOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmQ2F0YWxvZ3NMaXN0Lmxlbmd0aDsgKytpKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIGNhdGFsb2cgPSBmQ2F0YWxvZ3NMaXN0W2ldOwotICAgICAgICAgICAgICAgIGlmIChjYXRhbG9nICE9IG51bGwgJiYgY2F0YWxvZy5sZW5ndGgoKSA+IDApIHsKLSAgICAgICAgICAgICAgICAgICAgZkNhdGFsb2cucGFyc2VDYXRhbG9nKGNhdGFsb2cpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIGZDYXRhbG9nID0gbnVsbDsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEF0dGFjaGVzIHRoZSByZWFkZXIgdG8gdGhlIGNhdGFsb2cuCi0gICAgICovCi0gICAgcHJpdmF0ZSB2b2lkIGF0dGFjaFJlYWRlclRvQ2F0YWxvZyAoQ2F0YWxvZyBjYXRhbG9nKSB7Ci0KLSAgICAgICAgU0FYUGFyc2VyRmFjdG9yeSBzcGYgPSBuZXcgU0FYUGFyc2VyRmFjdG9yeUltcGwoKTsKLSAgICAgICAgc3BmLnNldE5hbWVzcGFjZUF3YXJlKHRydWUpOwotICAgICAgICBzcGYuc2V0VmFsaWRhdGluZyhmYWxzZSk7Ci0KLSAgICAgICAgU0FYQ2F0YWxvZ1JlYWRlciBzYXhSZWFkZXIgPSBuZXcgU0FYQ2F0YWxvZ1JlYWRlcihzcGYpOwotICAgICAgICBzYXhSZWFkZXIuc2V0Q2F0YWxvZ1BhcnNlcihPQVNJU1hNTENhdGFsb2dSZWFkZXIubmFtZXNwYWNlTmFtZSwgImNhdGFsb2ciLAotICAgICAgICAgICAgImNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzb2x2ZXIucmVhZGVycy5PQVNJU1hNTENhdGFsb2dSZWFkZXIiKTsKLSAgICAgICAgY2F0YWxvZy5hZGRSZWFkZXIoImFwcGxpY2F0aW9uL3htbCIsIHNheFJlYWRlcik7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9YTUxDaGFyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL1hNTENoYXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNzMxYjMxYS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL1hNTENoYXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEwNjUgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWw7Ci0KLWltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgZGVmaW5lcyB0aGUgYmFzaWMgWE1MIGNoYXJhY3RlciBwcm9wZXJ0aWVzLiBUaGUgZGF0YQotICogaW4gdGhpcyBjbGFzcyBjYW4gYmUgdXNlZCB0byB2ZXJpZnkgdGhhdCBhIGNoYXJhY3RlciBpcyBhIHZhbGlkCi0gKiBYTUwgY2hhcmFjdGVyIG9yIGlmIHRoZSBjaGFyYWN0ZXIgaXMgYSBzcGFjZSwgbmFtZSBzdGFydCwgb3IgbmFtZQotICogY2hhcmFjdGVyLgotICogPHA+Ci0gKiBBIHNlcmllcyBvZiBjb252ZW5pZW5jZSBtZXRob2RzIGFyZSBzdXBwbGllZCB0byBlYXNlIHRoZSBidXJkZW4KLSAqIG9mIHRoZSBkZXZlbG9wZXIuIEJlY2F1c2UgaW5saW5pbmcgdGhlIGNoZWNrcyBjYW4gaW1wcm92ZSBwZXIKLSAqIGNoYXJhY3RlciBwZXJmb3JtYW5jZSwgdGhlIHRhYmxlcyBvZiBjaGFyYWN0ZXIgcHJvcGVydGllcyBhcmUKLSAqIHB1YmxpYy4gVXNpbmcgdGhlIGNoYXJhY3RlciBhcyBhbiBpbmRleCBpbnRvIHRoZSA8Y29kZT5DSEFSUzwvY29kZT4KLSAqIGFycmF5IGFuZCBhcHBseWluZyB0aGUgYXBwcm9wcmlhdGUgbWFzayBmbGFnIChlLmcuCi0gKiA8Y29kZT5NQVNLX1ZBTElEPC9jb2RlPiksIHlpZWxkcyB0aGUgc2FtZSByZXN1bHRzIGFzIGNhbGxpbmcgdGhlCi0gKiBjb252ZW5pZW5jZSBtZXRob2RzLiBUaGVyZSBpcyBvbmUgZXhjZXB0aW9uOiBjaGVjayB0aGUgY29tbWVudHMKLSAqIGZvciB0aGUgPGNvZGU+aXNWYWxpZDwvY29kZT4gbWV0aG9kIGZvciBkZXRhaWxzLgotICoKLSAqIEBhdXRob3IgR2xlbm4gTWFyY3ksIElCTQotICogQGF1dGhvciBBbmR5IENsYXJrLCBJQk0KLSAqIEBhdXRob3IgRXJpYyBZZSwgSUJNCi0gKiBAYXV0aG9yIEFybmF1ZCAgTGUgSG9ycywgSUJNCi0gKiBAYXV0aG9yIE1pY2hhZWwgR2xhdmFzc2V2aWNoLCBJQk0KLSAqIEBhdXRob3IgUmFodWwgU3JpdmFzdGF2YSwgU3VuIE1pY3Jvc3lzdGVtcyBJbmMuCi0gKgotICogQHZlcnNpb24gJElkOiBYTUxDaGFyLmphdmEsdiAxLjcgMjAxMC0xMS0wMSAwNDo0MDoxNSBqb2VodyBFeHAgJAotICovCi1wdWJsaWMgY2xhc3MgWE1MQ2hhciB7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0YW50cwotICAgIC8vCi0KLSAgICAvKiogQ2hhcmFjdGVyIGZsYWdzLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSBDSEFSUyA9IG5ldyBieXRlWzEgPDwgMTZdOwotCi0gICAgLyoqIFZhbGlkIGNoYXJhY3RlciBtYXNrLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BU0tfVkFMSUQgPSAweDAxOwotCi0gICAgLyoqIFNwYWNlIGNoYXJhY3RlciBtYXNrLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BU0tfU1BBQ0UgPSAweDAyOwotCi0gICAgLyoqIE5hbWUgc3RhcnQgY2hhcmFjdGVyIG1hc2suICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFTS19OQU1FX1NUQVJUID0gMHgwNDsKLQotICAgIC8qKiBOYW1lIGNoYXJhY3RlciBtYXNrLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BU0tfTkFNRSA9IDB4MDg7Ci0KLSAgICAvKiogUHViaWQgY2hhcmFjdGVyIG1hc2suICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFTS19QVUJJRCA9IDB4MTA7Ci0KLSAgICAvKioKLSAgICAgKiBDb250ZW50IGNoYXJhY3RlciBtYXNrLiBTcGVjaWFsIGNoYXJhY3RlcnMgYXJlIHRob3NlIHRoYXQgY2FuCi0gICAgICogYmUgY29uc2lkZXJlZCB0aGUgc3RhcnQgb2YgbWFya3VwLCBzdWNoIGFzICcmbHQ7JyBhbmQgJyZhbXA7Jy4KLSAgICAgKiBUaGUgdmFyaW91cyBuZXdsaW5lIGNoYXJhY3RlcnMgYXJlIGNvbnNpZGVyZWQgc3BlY2lhbCBhcyB3ZWxsLgotICAgICAqIEFsbCBvdGhlciB2YWxpZCBYTUwgY2hhcmFjdGVycyBjYW4gYmUgY29uc2lkZXJlZCBjb250ZW50LgotICAgICAqIDxwPgotICAgICAqIFRoaXMgaXMgYW4gb3B0aW1pemF0aW9uIGZvciB0aGUgaW5uZXIgbG9vcCBvZiBjaGFyYWN0ZXIgc2Nhbm5pbmcuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFTS19DT05URU5UID0gMHgyMDsKLQotICAgIC8qKiBOQ05hbWUgc3RhcnQgY2hhcmFjdGVyIG1hc2suICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFTS19OQ05BTUVfU1RBUlQgPSAweDQwOwotCi0gICAgLyoqIE5DTmFtZSBjaGFyYWN0ZXIgbWFzay4gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVNLX05DTkFNRSA9IDB4ODA7Ci0KLSAgICAvLwotICAgIC8vIFN0YXRpYyBpbml0aWFsaXphdGlvbgotICAgIC8vCi0KLSAgICBzdGF0aWMgewotCi0gICAgICAgIC8vIEluaXRpYWxpemluZyB0aGUgQ2hhcmFjdGVyIEZsYWcgQXJyYXkKLSAgICAgICAgLy8gQ29kZSBnZW5lcmF0ZWQgYnk6IFhNTENoYXJHZW5lcmF0b3IuCi0KLSAgICAgICAgQ0hBUlNbOV0gPSAzNTsKLSAgICAgICAgQ0hBUlNbMTBdID0gMTk7Ci0gICAgICAgIENIQVJTWzEzXSA9IDE5OwotICAgICAgICBDSEFSU1szMl0gPSA1MTsKLSAgICAgICAgQ0hBUlNbMzNdID0gNDk7Ci0gICAgICAgIENIQVJTWzM0XSA9IDMzOwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMzUsIDM4LCAoYnl0ZSkgNDkgKTsgLy8gRmlsbCAzIG9mIHZhbHVlIChieXRlKSA0OQotICAgICAgICBDSEFSU1szOF0gPSAxOwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMzksIDQ1LCAoYnl0ZSkgNDkgKTsgLy8gRmlsbCA2IG9mIHZhbHVlIChieXRlKSA0OQotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgNDUsIDQ3LCAoYnl0ZSkgLTcxICk7IC8vIEZpbGwgMiBvZiB2YWx1ZSAoYnl0ZSkgLTcxCi0gICAgICAgIENIQVJTWzQ3XSA9IDQ5OwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgNDgsIDU4LCAoYnl0ZSkgLTcxICk7IC8vIEZpbGwgMTAgb2YgdmFsdWUgKGJ5dGUpIC03MQotICAgICAgICBDSEFSU1s1OF0gPSA2MTsKLSAgICAgICAgQ0hBUlNbNTldID0gNDk7Ci0gICAgICAgIENIQVJTWzYwXSA9IDE7Ci0gICAgICAgIENIQVJTWzYxXSA9IDQ5OwotICAgICAgICBDSEFSU1s2Ml0gPSAzMzsKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDYzLCA2NSwgKGJ5dGUpIDQ5ICk7IC8vIEZpbGwgMiBvZiB2YWx1ZSAoYnl0ZSkgNDkKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDY1LCA5MSwgKGJ5dGUpIC0zICk7IC8vIEZpbGwgMjYgb2YgdmFsdWUgKGJ5dGUpIC0zCi0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCA5MSwgOTMsIChieXRlKSAzMyApOyAvLyBGaWxsIDIgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIENIQVJTWzkzXSA9IDE7Ci0gICAgICAgIENIQVJTWzk0XSA9IDMzOwotICAgICAgICBDSEFSU1s5NV0gPSAtMzsKLSAgICAgICAgQ0hBUlNbOTZdID0gMzM7Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCA5NywgMTIzLCAoYnl0ZSkgLTMgKTsgLy8gRmlsbCAyNiBvZiB2YWx1ZSAoYnl0ZSkgLTMKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDEyMywgMTgzLCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCA2MCBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgQ0hBUlNbMTgzXSA9IC04NzsKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDE4NCwgMTkyLCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCA4IG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMTkyLCAyMTUsIChieXRlKSAtMTkgKTsgLy8gRmlsbCAyMyBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIENIQVJTWzIxNV0gPSAzMzsKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDIxNiwgMjQ3LCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgMzEgb2YgdmFsdWUgKGJ5dGUpIC0xOQotICAgICAgICBDSEFSU1syNDddID0gMzM7Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAyNDgsIDMwNiwgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDU4IG9mIHZhbHVlIChieXRlKSAtMTkKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDMwNiwgMzA4LCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCAyIG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMzA4LCAzMTksIChieXRlKSAtMTkgKTsgLy8gRmlsbCAxMSBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAzMTksIDMyMSwgKGJ5dGUpIDMzICk7IC8vIEZpbGwgMiBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDMyMSwgMzI5LCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgOCBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIENIQVJTWzMyOV0gPSAzMzsKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDMzMCwgMzgzLCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgNTMgb2YgdmFsdWUgKGJ5dGUpIC0xOQotICAgICAgICBDSEFSU1szODNdID0gMzM7Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAzODQsIDQ1MiwgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDY4IG9mIHZhbHVlIChieXRlKSAtMTkKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDQ1MiwgNDYxLCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCA5IG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgNDYxLCA0OTcsIChieXRlKSAtMTkgKTsgLy8gRmlsbCAzNiBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCA0OTcsIDUwMCwgKGJ5dGUpIDMzICk7IC8vIEZpbGwgMyBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDUwMCwgNTAyLCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgMiBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCA1MDIsIDUwNiwgKGJ5dGUpIDMzICk7IC8vIEZpbGwgNCBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDUwNiwgNTM2LCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgMzAgb2YgdmFsdWUgKGJ5dGUpIC0xOQotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgNTM2LCA1OTIsIChieXRlKSAzMyApOyAvLyBGaWxsIDU2IG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgNTkyLCA2ODEsIChieXRlKSAtMTkgKTsgLy8gRmlsbCA4OSBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCA2ODEsIDY5OSwgKGJ5dGUpIDMzICk7IC8vIEZpbGwgMTggb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCA2OTksIDcwNiwgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDcgb2YgdmFsdWUgKGJ5dGUpIC0xOQotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgNzA2LCA3MjAsIChieXRlKSAzMyApOyAvLyBGaWxsIDE0IG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgNzIwLCA3MjIsIChieXRlKSAtODcgKTsgLy8gRmlsbCAyIG9mIHZhbHVlIChieXRlKSAtODcKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDcyMiwgNzY4LCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCA0NiBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDc2OCwgODM4LCAoYnl0ZSkgLTg3ICk7IC8vIEZpbGwgNzAgb2YgdmFsdWUgKGJ5dGUpIC04NwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgODM4LCA4NjQsIChieXRlKSAzMyApOyAvLyBGaWxsIDI2IG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgODY0LCA4NjYsIChieXRlKSAtODcgKTsgLy8gRmlsbCAyIG9mIHZhbHVlIChieXRlKSAtODcKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDg2NiwgOTAyLCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCAzNiBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgQ0hBUlNbOTAyXSA9IC0xOTsKLSAgICAgICAgQ0hBUlNbOTAzXSA9IC04NzsKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDkwNCwgOTA3LCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgMyBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIENIQVJTWzkwN10gPSAzMzsKLSAgICAgICAgQ0hBUlNbOTA4XSA9IC0xOTsKLSAgICAgICAgQ0hBUlNbOTA5XSA9IDMzOwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgOTEwLCA5MzAsIChieXRlKSAtMTkgKTsgLy8gRmlsbCAyMCBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIENIQVJTWzkzMF0gPSAzMzsKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDkzMSwgOTc1LCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgNDQgb2YgdmFsdWUgKGJ5dGUpIC0xOQotICAgICAgICBDSEFSU1s5NzVdID0gMzM7Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCA5NzYsIDk4MywgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDcgb2YgdmFsdWUgKGJ5dGUpIC0xOQotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgOTgzLCA5ODYsIChieXRlKSAzMyApOyAvLyBGaWxsIDMgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIENIQVJTWzk4Nl0gPSAtMTk7Ci0gICAgICAgIENIQVJTWzk4N10gPSAzMzsKLSAgICAgICAgQ0hBUlNbOTg4XSA9IC0xOTsKLSAgICAgICAgQ0hBUlNbOTg5XSA9IDMzOwotICAgICAgICBDSEFSU1s5OTBdID0gLTE5OwotICAgICAgICBDSEFSU1s5OTFdID0gMzM7Ci0gICAgICAgIENIQVJTWzk5Ml0gPSAtMTk7Ci0gICAgICAgIENIQVJTWzk5M10gPSAzMzsKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDk5NCwgMTAxMiwgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDE4IG9mIHZhbHVlIChieXRlKSAtMTkKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDEwMTIsIDEwMjUsIChieXRlKSAzMyApOyAvLyBGaWxsIDEzIG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMTAyNSwgMTAzNywgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDEyIG9mIHZhbHVlIChieXRlKSAtMTkKLSAgICAgICAgQ0hBUlNbMTAzN10gPSAzMzsKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDEwMzgsIDExMDQsIChieXRlKSAtMTkgKTsgLy8gRmlsbCA2NiBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIENIQVJTWzExMDRdID0gMzM7Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAxMTA1LCAxMTE3LCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgMTIgb2YgdmFsdWUgKGJ5dGUpIC0xOQotICAgICAgICBDSEFSU1sxMTE3XSA9IDMzOwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMTExOCwgMTE1NCwgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDM2IG9mIHZhbHVlIChieXRlKSAtMTkKLSAgICAgICAgQ0hBUlNbMTE1NF0gPSAzMzsKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDExNTUsIDExNTksIChieXRlKSAtODcgKTsgLy8gRmlsbCA0IG9mIHZhbHVlIChieXRlKSAtODcKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDExNTksIDExNjgsIChieXRlKSAzMyApOyAvLyBGaWxsIDkgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAxMTY4LCAxMjIxLCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgNTMgb2YgdmFsdWUgKGJ5dGUpIC0xOQotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMTIyMSwgMTIyMywgKGJ5dGUpIDMzICk7IC8vIEZpbGwgMiBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDEyMjMsIDEyMjUsIChieXRlKSAtMTkgKTsgLy8gRmlsbCAyIG9mIHZhbHVlIChieXRlKSAtMTkKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDEyMjUsIDEyMjcsIChieXRlKSAzMyApOyAvLyBGaWxsIDIgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAxMjI3LCAxMjI5LCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgMiBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAxMjI5LCAxMjMyLCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCAzIG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMTIzMiwgMTI2MCwgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDI4IG9mIHZhbHVlIChieXRlKSAtMTkKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDEyNjAsIDEyNjIsIChieXRlKSAzMyApOyAvLyBGaWxsIDIgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAxMjYyLCAxMjcwLCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgOCBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAxMjcwLCAxMjcyLCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCAyIG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMTI3MiwgMTI3NCwgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDIgb2YgdmFsdWUgKGJ5dGUpIC0xOQotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMTI3NCwgMTMyOSwgKGJ5dGUpIDMzICk7IC8vIEZpbGwgNTUgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAxMzI5LCAxMzY3LCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgMzggb2YgdmFsdWUgKGJ5dGUpIC0xOQotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMTM2NywgMTM2OSwgKGJ5dGUpIDMzICk7IC8vIEZpbGwgMiBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgQ0hBUlNbMTM2OV0gPSAtMTk7Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAxMzcwLCAxMzc3LCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCA3IG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMTM3NywgMTQxNSwgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDM4IG9mIHZhbHVlIChieXRlKSAtMTkKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDE0MTUsIDE0MjUsIChieXRlKSAzMyApOyAvLyBGaWxsIDEwIG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMTQyNSwgMTQ0MiwgKGJ5dGUpIC04NyApOyAvLyBGaWxsIDE3IG9mIHZhbHVlIChieXRlKSAtODcKLSAgICAgICAgQ0hBUlNbMTQ0Ml0gPSAzMzsKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDE0NDMsIDE0NjYsIChieXRlKSAtODcgKTsgLy8gRmlsbCAyMyBvZiB2YWx1ZSAoYnl0ZSkgLTg3Ci0gICAgICAgIENIQVJTWzE0NjZdID0gMzM7Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAxNDY3LCAxNDcwLCAoYnl0ZSkgLTg3ICk7IC8vIEZpbGwgMyBvZiB2YWx1ZSAoYnl0ZSkgLTg3Ci0gICAgICAgIENIQVJTWzE0NzBdID0gMzM7Ci0gICAgICAgIENIQVJTWzE0NzFdID0gLTg3OwotICAgICAgICBDSEFSU1sxNDcyXSA9IDMzOwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMTQ3MywgMTQ3NSwgKGJ5dGUpIC04NyApOyAvLyBGaWxsIDIgb2YgdmFsdWUgKGJ5dGUpIC04NwotICAgICAgICBDSEFSU1sxNDc1XSA9IDMzOwotICAgICAgICBDSEFSU1sxNDc2XSA9IC04NzsKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDE0NzcsIDE0ODgsIChieXRlKSAzMyApOyAvLyBGaWxsIDExIG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMTQ4OCwgMTUxNSwgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDI3IG9mIHZhbHVlIChieXRlKSAtMTkKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDE1MTUsIDE1MjAsIChieXRlKSAzMyApOyAvLyBGaWxsIDUgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAxNTIwLCAxNTIzLCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgMyBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAxNTIzLCAxNTY5LCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCA0NiBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDE1NjksIDE1OTUsIChieXRlKSAtMTkgKTsgLy8gRmlsbCAyNiBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAxNTk1LCAxNjAwLCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCA1IG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBDSEFSU1sxNjAwXSA9IC04NzsKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDE2MDEsIDE2MTEsIChieXRlKSAtMTkgKTsgLy8gRmlsbCAxMCBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAxNjExLCAxNjE5LCAoYnl0ZSkgLTg3ICk7IC8vIEZpbGwgOCBvZiB2YWx1ZSAoYnl0ZSkgLTg3Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAxNjE5LCAxNjMyLCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCAxMyBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDE2MzIsIDE2NDIsIChieXRlKSAtODcgKTsgLy8gRmlsbCAxMCBvZiB2YWx1ZSAoYnl0ZSkgLTg3Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAxNjQyLCAxNjQ4LCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCA2IG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBDSEFSU1sxNjQ4XSA9IC04NzsKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDE2NDksIDE3MjAsIChieXRlKSAtMTkgKTsgLy8gRmlsbCA3MSBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAxNzIwLCAxNzIyLCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCAyIG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMTcyMiwgMTcyNywgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDUgb2YgdmFsdWUgKGJ5dGUpIC0xOQotICAgICAgICBDSEFSU1sxNzI3XSA9IDMzOwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMTcyOCwgMTc0MywgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDE1IG9mIHZhbHVlIChieXRlKSAtMTkKLSAgICAgICAgQ0hBUlNbMTc0M10gPSAzMzsKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDE3NDQsIDE3NDgsIChieXRlKSAtMTkgKTsgLy8gRmlsbCA0IG9mIHZhbHVlIChieXRlKSAtMTkKLSAgICAgICAgQ0hBUlNbMTc0OF0gPSAzMzsKLSAgICAgICAgQ0hBUlNbMTc0OV0gPSAtMTk7Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAxNzUwLCAxNzY1LCAoYnl0ZSkgLTg3ICk7IC8vIEZpbGwgMTUgb2YgdmFsdWUgKGJ5dGUpIC04NwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMTc2NSwgMTc2NywgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDIgb2YgdmFsdWUgKGJ5dGUpIC0xOQotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMTc2NywgMTc2OSwgKGJ5dGUpIC04NyApOyAvLyBGaWxsIDIgb2YgdmFsdWUgKGJ5dGUpIC04NwotICAgICAgICBDSEFSU1sxNzY5XSA9IDMzOwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMTc3MCwgMTc3NCwgKGJ5dGUpIC04NyApOyAvLyBGaWxsIDQgb2YgdmFsdWUgKGJ5dGUpIC04NwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMTc3NCwgMTc3NiwgKGJ5dGUpIDMzICk7IC8vIEZpbGwgMiBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDE3NzYsIDE3ODYsIChieXRlKSAtODcgKTsgLy8gRmlsbCAxMCBvZiB2YWx1ZSAoYnl0ZSkgLTg3Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAxNzg2LCAyMzA1LCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCA1MTkgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAyMzA1LCAyMzA4LCAoYnl0ZSkgLTg3ICk7IC8vIEZpbGwgMyBvZiB2YWx1ZSAoYnl0ZSkgLTg3Ci0gICAgICAgIENIQVJTWzIzMDhdID0gMzM7Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAyMzA5LCAyMzYyLCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgNTMgb2YgdmFsdWUgKGJ5dGUpIC0xOQotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMjM2MiwgMjM2NCwgKGJ5dGUpIDMzICk7IC8vIEZpbGwgMiBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgQ0hBUlNbMjM2NF0gPSAtODc7Ci0gICAgICAgIENIQVJTWzIzNjVdID0gLTE5OwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMjM2NiwgMjM4MiwgKGJ5dGUpIC04NyApOyAvLyBGaWxsIDE2IG9mIHZhbHVlIChieXRlKSAtODcKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDIzODIsIDIzODUsIChieXRlKSAzMyApOyAvLyBGaWxsIDMgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAyMzg1LCAyMzg5LCAoYnl0ZSkgLTg3ICk7IC8vIEZpbGwgNCBvZiB2YWx1ZSAoYnl0ZSkgLTg3Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAyMzg5LCAyMzkyLCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCAzIG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMjM5MiwgMjQwMiwgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDEwIG9mIHZhbHVlIChieXRlKSAtMTkKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDI0MDIsIDI0MDQsIChieXRlKSAtODcgKTsgLy8gRmlsbCAyIG9mIHZhbHVlIChieXRlKSAtODcKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDI0MDQsIDI0MDYsIChieXRlKSAzMyApOyAvLyBGaWxsIDIgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAyNDA2LCAyNDE2LCAoYnl0ZSkgLTg3ICk7IC8vIEZpbGwgMTAgb2YgdmFsdWUgKGJ5dGUpIC04NwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMjQxNiwgMjQzMywgKGJ5dGUpIDMzICk7IC8vIEZpbGwgMTcgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAyNDMzLCAyNDM2LCAoYnl0ZSkgLTg3ICk7IC8vIEZpbGwgMyBvZiB2YWx1ZSAoYnl0ZSkgLTg3Ci0gICAgICAgIENIQVJTWzI0MzZdID0gMzM7Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAyNDM3LCAyNDQ1LCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgOCBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAyNDQ1LCAyNDQ3LCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCAyIG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMjQ0NywgMjQ0OSwgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDIgb2YgdmFsdWUgKGJ5dGUpIC0xOQotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMjQ0OSwgMjQ1MSwgKGJ5dGUpIDMzICk7IC8vIEZpbGwgMiBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDI0NTEsIDI0NzMsIChieXRlKSAtMTkgKTsgLy8gRmlsbCAyMiBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIENIQVJTWzI0NzNdID0gMzM7Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAyNDc0LCAyNDgxLCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgNyBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIENIQVJTWzI0ODFdID0gMzM7Ci0gICAgICAgIENIQVJTWzI0ODJdID0gLTE5OwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMjQ4MywgMjQ4NiwgKGJ5dGUpIDMzICk7IC8vIEZpbGwgMyBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDI0ODYsIDI0OTAsIChieXRlKSAtMTkgKTsgLy8gRmlsbCA0IG9mIHZhbHVlIChieXRlKSAtMTkKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDI0OTAsIDI0OTIsIChieXRlKSAzMyApOyAvLyBGaWxsIDIgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIENIQVJTWzI0OTJdID0gLTg3OwotICAgICAgICBDSEFSU1syNDkzXSA9IDMzOwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMjQ5NCwgMjUwMSwgKGJ5dGUpIC04NyApOyAvLyBGaWxsIDcgb2YgdmFsdWUgKGJ5dGUpIC04NwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMjUwMSwgMjUwMywgKGJ5dGUpIDMzICk7IC8vIEZpbGwgMiBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDI1MDMsIDI1MDUsIChieXRlKSAtODcgKTsgLy8gRmlsbCAyIG9mIHZhbHVlIChieXRlKSAtODcKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDI1MDUsIDI1MDcsIChieXRlKSAzMyApOyAvLyBGaWxsIDIgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAyNTA3LCAyNTEwLCAoYnl0ZSkgLTg3ICk7IC8vIEZpbGwgMyBvZiB2YWx1ZSAoYnl0ZSkgLTg3Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAyNTEwLCAyNTE5LCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCA5IG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBDSEFSU1syNTE5XSA9IC04NzsKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDI1MjAsIDI1MjQsIChieXRlKSAzMyApOyAvLyBGaWxsIDQgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAyNTI0LCAyNTI2LCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgMiBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIENIQVJTWzI1MjZdID0gMzM7Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAyNTI3LCAyNTMwLCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgMyBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAyNTMwLCAyNTMyLCAoYnl0ZSkgLTg3ICk7IC8vIEZpbGwgMiBvZiB2YWx1ZSAoYnl0ZSkgLTg3Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAyNTMyLCAyNTM0LCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCAyIG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMjUzNCwgMjU0NCwgKGJ5dGUpIC04NyApOyAvLyBGaWxsIDEwIG9mIHZhbHVlIChieXRlKSAtODcKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDI1NDQsIDI1NDYsIChieXRlKSAtMTkgKTsgLy8gRmlsbCAyIG9mIHZhbHVlIChieXRlKSAtMTkKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDI1NDYsIDI1NjIsIChieXRlKSAzMyApOyAvLyBGaWxsIDE2IG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBDSEFSU1syNTYyXSA9IC04NzsKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDI1NjMsIDI1NjUsIChieXRlKSAzMyApOyAvLyBGaWxsIDIgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAyNTY1LCAyNTcxLCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgNiBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAyNTcxLCAyNTc1LCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCA0IG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMjU3NSwgMjU3NywgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDIgb2YgdmFsdWUgKGJ5dGUpIC0xOQotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMjU3NywgMjU3OSwgKGJ5dGUpIDMzICk7IC8vIEZpbGwgMiBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDI1NzksIDI2MDEsIChieXRlKSAtMTkgKTsgLy8gRmlsbCAyMiBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIENIQVJTWzI2MDFdID0gMzM7Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAyNjAyLCAyNjA5LCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgNyBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIENIQVJTWzI2MDldID0gMzM7Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAyNjEwLCAyNjEyLCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgMiBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIENIQVJTWzI2MTJdID0gMzM7Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAyNjEzLCAyNjE1LCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgMiBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIENIQVJTWzI2MTVdID0gMzM7Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAyNjE2LCAyNjE4LCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgMiBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAyNjE4LCAyNjIwLCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCAyIG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBDSEFSU1syNjIwXSA9IC04NzsKLSAgICAgICAgQ0hBUlNbMjYyMV0gPSAzMzsKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDI2MjIsIDI2MjcsIChieXRlKSAtODcgKTsgLy8gRmlsbCA1IG9mIHZhbHVlIChieXRlKSAtODcKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDI2MjcsIDI2MzEsIChieXRlKSAzMyApOyAvLyBGaWxsIDQgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAyNjMxLCAyNjMzLCAoYnl0ZSkgLTg3ICk7IC8vIEZpbGwgMiBvZiB2YWx1ZSAoYnl0ZSkgLTg3Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAyNjMzLCAyNjM1LCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCAyIG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMjYzNSwgMjYzOCwgKGJ5dGUpIC04NyApOyAvLyBGaWxsIDMgb2YgdmFsdWUgKGJ5dGUpIC04NwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMjYzOCwgMjY0OSwgKGJ5dGUpIDMzICk7IC8vIEZpbGwgMTEgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAyNjQ5LCAyNjUzLCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgNCBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIENIQVJTWzI2NTNdID0gMzM7Ci0gICAgICAgIENIQVJTWzI2NTRdID0gLTE5OwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMjY1NSwgMjY2MiwgKGJ5dGUpIDMzICk7IC8vIEZpbGwgNyBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDI2NjIsIDI2NzQsIChieXRlKSAtODcgKTsgLy8gRmlsbCAxMiBvZiB2YWx1ZSAoYnl0ZSkgLTg3Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAyNjc0LCAyNjc3LCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgMyBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAyNjc3LCAyNjg5LCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCAxMiBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDI2ODksIDI2OTIsIChieXRlKSAtODcgKTsgLy8gRmlsbCAzIG9mIHZhbHVlIChieXRlKSAtODcKLSAgICAgICAgQ0hBUlNbMjY5Ml0gPSAzMzsKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDI2OTMsIDI3MDAsIChieXRlKSAtMTkgKTsgLy8gRmlsbCA3IG9mIHZhbHVlIChieXRlKSAtMTkKLSAgICAgICAgQ0hBUlNbMjcwMF0gPSAzMzsKLSAgICAgICAgQ0hBUlNbMjcwMV0gPSAtMTk7Ci0gICAgICAgIENIQVJTWzI3MDJdID0gMzM7Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAyNzAzLCAyNzA2LCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgMyBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIENIQVJTWzI3MDZdID0gMzM7Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAyNzA3LCAyNzI5LCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgMjIgb2YgdmFsdWUgKGJ5dGUpIC0xOQotICAgICAgICBDSEFSU1syNzI5XSA9IDMzOwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMjczMCwgMjczNywgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDcgb2YgdmFsdWUgKGJ5dGUpIC0xOQotICAgICAgICBDSEFSU1syNzM3XSA9IDMzOwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMjczOCwgMjc0MCwgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDIgb2YgdmFsdWUgKGJ5dGUpIC0xOQotICAgICAgICBDSEFSU1syNzQwXSA9IDMzOwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMjc0MSwgMjc0NiwgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDUgb2YgdmFsdWUgKGJ5dGUpIC0xOQotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMjc0NiwgMjc0OCwgKGJ5dGUpIDMzICk7IC8vIEZpbGwgMiBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgQ0hBUlNbMjc0OF0gPSAtODc7Ci0gICAgICAgIENIQVJTWzI3NDldID0gLTE5OwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMjc1MCwgMjc1OCwgKGJ5dGUpIC04NyApOyAvLyBGaWxsIDggb2YgdmFsdWUgKGJ5dGUpIC04NwotICAgICAgICBDSEFSU1syNzU4XSA9IDMzOwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMjc1OSwgMjc2MiwgKGJ5dGUpIC04NyApOyAvLyBGaWxsIDMgb2YgdmFsdWUgKGJ5dGUpIC04NwotICAgICAgICBDSEFSU1syNzYyXSA9IDMzOwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMjc2MywgMjc2NiwgKGJ5dGUpIC04NyApOyAvLyBGaWxsIDMgb2YgdmFsdWUgKGJ5dGUpIC04NwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMjc2NiwgMjc4NCwgKGJ5dGUpIDMzICk7IC8vIEZpbGwgMTggb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIENIQVJTWzI3ODRdID0gLTE5OwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMjc4NSwgMjc5MCwgKGJ5dGUpIDMzICk7IC8vIEZpbGwgNSBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDI3OTAsIDI4MDAsIChieXRlKSAtODcgKTsgLy8gRmlsbCAxMCBvZiB2YWx1ZSAoYnl0ZSkgLTg3Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAyODAwLCAyODE3LCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCAxNyBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDI4MTcsIDI4MjAsIChieXRlKSAtODcgKTsgLy8gRmlsbCAzIG9mIHZhbHVlIChieXRlKSAtODcKLSAgICAgICAgQ0hBUlNbMjgyMF0gPSAzMzsKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDI4MjEsIDI4MjksIChieXRlKSAtMTkgKTsgLy8gRmlsbCA4IG9mIHZhbHVlIChieXRlKSAtMTkKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDI4MjksIDI4MzEsIChieXRlKSAzMyApOyAvLyBGaWxsIDIgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAyODMxLCAyODMzLCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgMiBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAyODMzLCAyODM1LCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCAyIG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMjgzNSwgMjg1NywgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDIyIG9mIHZhbHVlIChieXRlKSAtMTkKLSAgICAgICAgQ0hBUlNbMjg1N10gPSAzMzsKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDI4NTgsIDI4NjUsIChieXRlKSAtMTkgKTsgLy8gRmlsbCA3IG9mIHZhbHVlIChieXRlKSAtMTkKLSAgICAgICAgQ0hBUlNbMjg2NV0gPSAzMzsKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDI4NjYsIDI4NjgsIChieXRlKSAtMTkgKTsgLy8gRmlsbCAyIG9mIHZhbHVlIChieXRlKSAtMTkKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDI4NjgsIDI4NzAsIChieXRlKSAzMyApOyAvLyBGaWxsIDIgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAyODcwLCAyODc0LCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgNCBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAyODc0LCAyODc2LCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCAyIG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBDSEFSU1syODc2XSA9IC04NzsKLSAgICAgICAgQ0hBUlNbMjg3N10gPSAtMTk7Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAyODc4LCAyODg0LCAoYnl0ZSkgLTg3ICk7IC8vIEZpbGwgNiBvZiB2YWx1ZSAoYnl0ZSkgLTg3Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAyODg0LCAyODg3LCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCAzIG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMjg4NywgMjg4OSwgKGJ5dGUpIC04NyApOyAvLyBGaWxsIDIgb2YgdmFsdWUgKGJ5dGUpIC04NwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMjg4OSwgMjg5MSwgKGJ5dGUpIDMzICk7IC8vIEZpbGwgMiBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDI4OTEsIDI4OTQsIChieXRlKSAtODcgKTsgLy8gRmlsbCAzIG9mIHZhbHVlIChieXRlKSAtODcKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDI4OTQsIDI5MDIsIChieXRlKSAzMyApOyAvLyBGaWxsIDggb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAyOTAyLCAyOTA0LCAoYnl0ZSkgLTg3ICk7IC8vIEZpbGwgMiBvZiB2YWx1ZSAoYnl0ZSkgLTg3Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAyOTA0LCAyOTA4LCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCA0IG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMjkwOCwgMjkxMCwgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDIgb2YgdmFsdWUgKGJ5dGUpIC0xOQotICAgICAgICBDSEFSU1syOTEwXSA9IDMzOwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMjkxMSwgMjkxNCwgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDMgb2YgdmFsdWUgKGJ5dGUpIC0xOQotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMjkxNCwgMjkxOCwgKGJ5dGUpIDMzICk7IC8vIEZpbGwgNCBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDI5MTgsIDI5MjgsIChieXRlKSAtODcgKTsgLy8gRmlsbCAxMCBvZiB2YWx1ZSAoYnl0ZSkgLTg3Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAyOTI4LCAyOTQ2LCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCAxOCBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDI5NDYsIDI5NDgsIChieXRlKSAtODcgKTsgLy8gRmlsbCAyIG9mIHZhbHVlIChieXRlKSAtODcKLSAgICAgICAgQ0hBUlNbMjk0OF0gPSAzMzsKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDI5NDksIDI5NTUsIChieXRlKSAtMTkgKTsgLy8gRmlsbCA2IG9mIHZhbHVlIChieXRlKSAtMTkKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDI5NTUsIDI5NTgsIChieXRlKSAzMyApOyAvLyBGaWxsIDMgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAyOTU4LCAyOTYxLCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgMyBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIENIQVJTWzI5NjFdID0gMzM7Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAyOTYyLCAyOTY2LCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgNCBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAyOTY2LCAyOTY5LCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCAzIG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMjk2OSwgMjk3MSwgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDIgb2YgdmFsdWUgKGJ5dGUpIC0xOQotICAgICAgICBDSEFSU1syOTcxXSA9IDMzOwotICAgICAgICBDSEFSU1syOTcyXSA9IC0xOTsKLSAgICAgICAgQ0hBUlNbMjk3M10gPSAzMzsKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDI5NzQsIDI5NzYsIChieXRlKSAtMTkgKTsgLy8gRmlsbCAyIG9mIHZhbHVlIChieXRlKSAtMTkKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDI5NzYsIDI5NzksIChieXRlKSAzMyApOyAvLyBGaWxsIDMgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAyOTc5LCAyOTgxLCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgMiBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAyOTgxLCAyOTg0LCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCAzIG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMjk4NCwgMjk4NywgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDMgb2YgdmFsdWUgKGJ5dGUpIC0xOQotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMjk4NywgMjk5MCwgKGJ5dGUpIDMzICk7IC8vIEZpbGwgMyBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDI5OTAsIDI5OTgsIChieXRlKSAtMTkgKTsgLy8gRmlsbCA4IG9mIHZhbHVlIChieXRlKSAtMTkKLSAgICAgICAgQ0hBUlNbMjk5OF0gPSAzMzsKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDI5OTksIDMwMDIsIChieXRlKSAtMTkgKTsgLy8gRmlsbCAzIG9mIHZhbHVlIChieXRlKSAtMTkKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDMwMDIsIDMwMDYsIChieXRlKSAzMyApOyAvLyBGaWxsIDQgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAzMDA2LCAzMDExLCAoYnl0ZSkgLTg3ICk7IC8vIEZpbGwgNSBvZiB2YWx1ZSAoYnl0ZSkgLTg3Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAzMDExLCAzMDE0LCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCAzIG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMzAxNCwgMzAxNywgKGJ5dGUpIC04NyApOyAvLyBGaWxsIDMgb2YgdmFsdWUgKGJ5dGUpIC04NwotICAgICAgICBDSEFSU1szMDE3XSA9IDMzOwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMzAxOCwgMzAyMiwgKGJ5dGUpIC04NyApOyAvLyBGaWxsIDQgb2YgdmFsdWUgKGJ5dGUpIC04NwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMzAyMiwgMzAzMSwgKGJ5dGUpIDMzICk7IC8vIEZpbGwgOSBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgQ0hBUlNbMzAzMV0gPSAtODc7Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAzMDMyLCAzMDQ3LCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCAxNSBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDMwNDcsIDMwNTYsIChieXRlKSAtODcgKTsgLy8gRmlsbCA5IG9mIHZhbHVlIChieXRlKSAtODcKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDMwNTYsIDMwNzMsIChieXRlKSAzMyApOyAvLyBGaWxsIDE3IG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMzA3MywgMzA3NiwgKGJ5dGUpIC04NyApOyAvLyBGaWxsIDMgb2YgdmFsdWUgKGJ5dGUpIC04NwotICAgICAgICBDSEFSU1szMDc2XSA9IDMzOwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMzA3NywgMzA4NSwgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDggb2YgdmFsdWUgKGJ5dGUpIC0xOQotICAgICAgICBDSEFSU1szMDg1XSA9IDMzOwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMzA4NiwgMzA4OSwgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDMgb2YgdmFsdWUgKGJ5dGUpIC0xOQotICAgICAgICBDSEFSU1szMDg5XSA9IDMzOwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMzA5MCwgMzExMywgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDIzIG9mIHZhbHVlIChieXRlKSAtMTkKLSAgICAgICAgQ0hBUlNbMzExM10gPSAzMzsKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDMxMTQsIDMxMjQsIChieXRlKSAtMTkgKTsgLy8gRmlsbCAxMCBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIENIQVJTWzMxMjRdID0gMzM7Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAzMTI1LCAzMTMwLCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgNSBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAzMTMwLCAzMTM0LCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCA0IG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMzEzNCwgMzE0MSwgKGJ5dGUpIC04NyApOyAvLyBGaWxsIDcgb2YgdmFsdWUgKGJ5dGUpIC04NwotICAgICAgICBDSEFSU1szMTQxXSA9IDMzOwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMzE0MiwgMzE0NSwgKGJ5dGUpIC04NyApOyAvLyBGaWxsIDMgb2YgdmFsdWUgKGJ5dGUpIC04NwotICAgICAgICBDSEFSU1szMTQ1XSA9IDMzOwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMzE0NiwgMzE1MCwgKGJ5dGUpIC04NyApOyAvLyBGaWxsIDQgb2YgdmFsdWUgKGJ5dGUpIC04NwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMzE1MCwgMzE1NywgKGJ5dGUpIDMzICk7IC8vIEZpbGwgNyBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDMxNTcsIDMxNTksIChieXRlKSAtODcgKTsgLy8gRmlsbCAyIG9mIHZhbHVlIChieXRlKSAtODcKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDMxNTksIDMxNjgsIChieXRlKSAzMyApOyAvLyBGaWxsIDkgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAzMTY4LCAzMTcwLCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgMiBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAzMTcwLCAzMTc0LCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCA0IG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMzE3NCwgMzE4NCwgKGJ5dGUpIC04NyApOyAvLyBGaWxsIDEwIG9mIHZhbHVlIChieXRlKSAtODcKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDMxODQsIDMyMDIsIChieXRlKSAzMyApOyAvLyBGaWxsIDE4IG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMzIwMiwgMzIwNCwgKGJ5dGUpIC04NyApOyAvLyBGaWxsIDIgb2YgdmFsdWUgKGJ5dGUpIC04NwotICAgICAgICBDSEFSU1szMjA0XSA9IDMzOwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMzIwNSwgMzIxMywgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDggb2YgdmFsdWUgKGJ5dGUpIC0xOQotICAgICAgICBDSEFSU1szMjEzXSA9IDMzOwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMzIxNCwgMzIxNywgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDMgb2YgdmFsdWUgKGJ5dGUpIC0xOQotICAgICAgICBDSEFSU1szMjE3XSA9IDMzOwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMzIxOCwgMzI0MSwgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDIzIG9mIHZhbHVlIChieXRlKSAtMTkKLSAgICAgICAgQ0hBUlNbMzI0MV0gPSAzMzsKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDMyNDIsIDMyNTIsIChieXRlKSAtMTkgKTsgLy8gRmlsbCAxMCBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIENIQVJTWzMyNTJdID0gMzM7Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAzMjUzLCAzMjU4LCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgNSBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAzMjU4LCAzMjYyLCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCA0IG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMzI2MiwgMzI2OSwgKGJ5dGUpIC04NyApOyAvLyBGaWxsIDcgb2YgdmFsdWUgKGJ5dGUpIC04NwotICAgICAgICBDSEFSU1szMjY5XSA9IDMzOwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMzI3MCwgMzI3MywgKGJ5dGUpIC04NyApOyAvLyBGaWxsIDMgb2YgdmFsdWUgKGJ5dGUpIC04NwotICAgICAgICBDSEFSU1szMjczXSA9IDMzOwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMzI3NCwgMzI3OCwgKGJ5dGUpIC04NyApOyAvLyBGaWxsIDQgb2YgdmFsdWUgKGJ5dGUpIC04NwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMzI3OCwgMzI4NSwgKGJ5dGUpIDMzICk7IC8vIEZpbGwgNyBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDMyODUsIDMyODcsIChieXRlKSAtODcgKTsgLy8gRmlsbCAyIG9mIHZhbHVlIChieXRlKSAtODcKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDMyODcsIDMyOTQsIChieXRlKSAzMyApOyAvLyBGaWxsIDcgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIENIQVJTWzMyOTRdID0gLTE5OwotICAgICAgICBDSEFSU1szMjk1XSA9IDMzOwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMzI5NiwgMzI5OCwgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDIgb2YgdmFsdWUgKGJ5dGUpIC0xOQotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMzI5OCwgMzMwMiwgKGJ5dGUpIDMzICk7IC8vIEZpbGwgNCBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDMzMDIsIDMzMTIsIChieXRlKSAtODcgKTsgLy8gRmlsbCAxMCBvZiB2YWx1ZSAoYnl0ZSkgLTg3Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAzMzEyLCAzMzMwLCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCAxOCBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDMzMzAsIDMzMzIsIChieXRlKSAtODcgKTsgLy8gRmlsbCAyIG9mIHZhbHVlIChieXRlKSAtODcKLSAgICAgICAgQ0hBUlNbMzMzMl0gPSAzMzsKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDMzMzMsIDMzNDEsIChieXRlKSAtMTkgKTsgLy8gRmlsbCA4IG9mIHZhbHVlIChieXRlKSAtMTkKLSAgICAgICAgQ0hBUlNbMzM0MV0gPSAzMzsKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDMzNDIsIDMzNDUsIChieXRlKSAtMTkgKTsgLy8gRmlsbCAzIG9mIHZhbHVlIChieXRlKSAtMTkKLSAgICAgICAgQ0hBUlNbMzM0NV0gPSAzMzsKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDMzNDYsIDMzNjksIChieXRlKSAtMTkgKTsgLy8gRmlsbCAyMyBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIENIQVJTWzMzNjldID0gMzM7Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAzMzcwLCAzMzg2LCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgMTYgb2YgdmFsdWUgKGJ5dGUpIC0xOQotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMzM4NiwgMzM5MCwgKGJ5dGUpIDMzICk7IC8vIEZpbGwgNCBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDMzOTAsIDMzOTYsIChieXRlKSAtODcgKTsgLy8gRmlsbCA2IG9mIHZhbHVlIChieXRlKSAtODcKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDMzOTYsIDMzOTgsIChieXRlKSAzMyApOyAvLyBGaWxsIDIgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAzMzk4LCAzNDAxLCAoYnl0ZSkgLTg3ICk7IC8vIEZpbGwgMyBvZiB2YWx1ZSAoYnl0ZSkgLTg3Ci0gICAgICAgIENIQVJTWzM0MDFdID0gMzM7Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAzNDAyLCAzNDA2LCAoYnl0ZSkgLTg3ICk7IC8vIEZpbGwgNCBvZiB2YWx1ZSAoYnl0ZSkgLTg3Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAzNDA2LCAzNDE1LCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCA5IG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBDSEFSU1szNDE1XSA9IC04NzsKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDM0MTYsIDM0MjQsIChieXRlKSAzMyApOyAvLyBGaWxsIDggb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAzNDI0LCAzNDI2LCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgMiBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAzNDI2LCAzNDMwLCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCA0IG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMzQzMCwgMzQ0MCwgKGJ5dGUpIC04NyApOyAvLyBGaWxsIDEwIG9mIHZhbHVlIChieXRlKSAtODcKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDM0NDAsIDM1ODUsIChieXRlKSAzMyApOyAvLyBGaWxsIDE0NSBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDM1ODUsIDM2MzEsIChieXRlKSAtMTkgKTsgLy8gRmlsbCA0NiBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIENIQVJTWzM2MzFdID0gMzM7Ci0gICAgICAgIENIQVJTWzM2MzJdID0gLTE5OwotICAgICAgICBDSEFSU1szNjMzXSA9IC04NzsKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDM2MzQsIDM2MzYsIChieXRlKSAtMTkgKTsgLy8gRmlsbCAyIG9mIHZhbHVlIChieXRlKSAtMTkKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDM2MzYsIDM2NDMsIChieXRlKSAtODcgKTsgLy8gRmlsbCA3IG9mIHZhbHVlIChieXRlKSAtODcKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDM2NDMsIDM2NDgsIChieXRlKSAzMyApOyAvLyBGaWxsIDUgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAzNjQ4LCAzNjU0LCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgNiBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAzNjU0LCAzNjYzLCAoYnl0ZSkgLTg3ICk7IC8vIEZpbGwgOSBvZiB2YWx1ZSAoYnl0ZSkgLTg3Ci0gICAgICAgIENIQVJTWzM2NjNdID0gMzM7Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAzNjY0LCAzNjc0LCAoYnl0ZSkgLTg3ICk7IC8vIEZpbGwgMTAgb2YgdmFsdWUgKGJ5dGUpIC04NwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMzY3NCwgMzcxMywgKGJ5dGUpIDMzICk7IC8vIEZpbGwgMzkgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAzNzEzLCAzNzE1LCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgMiBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIENIQVJTWzM3MTVdID0gMzM7Ci0gICAgICAgIENIQVJTWzM3MTZdID0gLTE5OwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMzcxNywgMzcxOSwgKGJ5dGUpIDMzICk7IC8vIEZpbGwgMiBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDM3MTksIDM3MjEsIChieXRlKSAtMTkgKTsgLy8gRmlsbCAyIG9mIHZhbHVlIChieXRlKSAtMTkKLSAgICAgICAgQ0hBUlNbMzcyMV0gPSAzMzsKLSAgICAgICAgQ0hBUlNbMzcyMl0gPSAtMTk7Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAzNzIzLCAzNzI1LCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCAyIG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBDSEFSU1szNzI1XSA9IC0xOTsKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDM3MjYsIDM3MzIsIChieXRlKSAzMyApOyAvLyBGaWxsIDYgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAzNzMyLCAzNzM2LCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgNCBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIENIQVJTWzM3MzZdID0gMzM7Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAzNzM3LCAzNzQ0LCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgNyBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIENIQVJTWzM3NDRdID0gMzM7Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAzNzQ1LCAzNzQ4LCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgMyBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIENIQVJTWzM3NDhdID0gMzM7Ci0gICAgICAgIENIQVJTWzM3NDldID0gLTE5OwotICAgICAgICBDSEFSU1szNzUwXSA9IDMzOwotICAgICAgICBDSEFSU1szNzUxXSA9IC0xOTsKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDM3NTIsIDM3NTQsIChieXRlKSAzMyApOyAvLyBGaWxsIDIgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAzNzU0LCAzNzU2LCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgMiBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIENIQVJTWzM3NTZdID0gMzM7Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAzNzU3LCAzNzU5LCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgMiBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIENIQVJTWzM3NTldID0gMzM7Ci0gICAgICAgIENIQVJTWzM3NjBdID0gLTE5OwotICAgICAgICBDSEFSU1szNzYxXSA9IC04NzsKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDM3NjIsIDM3NjQsIChieXRlKSAtMTkgKTsgLy8gRmlsbCAyIG9mIHZhbHVlIChieXRlKSAtMTkKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDM3NjQsIDM3NzAsIChieXRlKSAtODcgKTsgLy8gRmlsbCA2IG9mIHZhbHVlIChieXRlKSAtODcKLSAgICAgICAgQ0hBUlNbMzc3MF0gPSAzMzsKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDM3NzEsIDM3NzMsIChieXRlKSAtODcgKTsgLy8gRmlsbCAyIG9mIHZhbHVlIChieXRlKSAtODcKLSAgICAgICAgQ0hBUlNbMzc3M10gPSAtMTk7Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAzNzc0LCAzNzc2LCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCAyIG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMzc3NiwgMzc4MSwgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDUgb2YgdmFsdWUgKGJ5dGUpIC0xOQotICAgICAgICBDSEFSU1szNzgxXSA9IDMzOwotICAgICAgICBDSEFSU1szNzgyXSA9IC04NzsKLSAgICAgICAgQ0hBUlNbMzc4M10gPSAzMzsKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDM3ODQsIDM3OTAsIChieXRlKSAtODcgKTsgLy8gRmlsbCA2IG9mIHZhbHVlIChieXRlKSAtODcKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDM3OTAsIDM3OTIsIChieXRlKSAzMyApOyAvLyBGaWxsIDIgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAzNzkyLCAzODAyLCAoYnl0ZSkgLTg3ICk7IC8vIEZpbGwgMTAgb2YgdmFsdWUgKGJ5dGUpIC04NwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMzgwMiwgMzg2NCwgKGJ5dGUpIDMzICk7IC8vIEZpbGwgNjIgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAzODY0LCAzODY2LCAoYnl0ZSkgLTg3ICk7IC8vIEZpbGwgMiBvZiB2YWx1ZSAoYnl0ZSkgLTg3Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAzODY2LCAzODcyLCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCA2IG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMzg3MiwgMzg4MiwgKGJ5dGUpIC04NyApOyAvLyBGaWxsIDEwIG9mIHZhbHVlIChieXRlKSAtODcKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDM4ODIsIDM4OTMsIChieXRlKSAzMyApOyAvLyBGaWxsIDExIG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBDSEFSU1szODkzXSA9IC04NzsKLSAgICAgICAgQ0hBUlNbMzg5NF0gPSAzMzsKLSAgICAgICAgQ0hBUlNbMzg5NV0gPSAtODc7Ci0gICAgICAgIENIQVJTWzM4OTZdID0gMzM7Ci0gICAgICAgIENIQVJTWzM4OTddID0gLTg3OwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMzg5OCwgMzkwMiwgKGJ5dGUpIDMzICk7IC8vIEZpbGwgNCBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDM5MDIsIDM5MDQsIChieXRlKSAtODcgKTsgLy8gRmlsbCAyIG9mIHZhbHVlIChieXRlKSAtODcKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDM5MDQsIDM5MTIsIChieXRlKSAtMTkgKTsgLy8gRmlsbCA4IG9mIHZhbHVlIChieXRlKSAtMTkKLSAgICAgICAgQ0hBUlNbMzkxMl0gPSAzMzsKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDM5MTMsIDM5NDYsIChieXRlKSAtMTkgKTsgLy8gRmlsbCAzMyBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAzOTQ2LCAzOTUzLCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCA3IG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMzk1MywgMzk3MywgKGJ5dGUpIC04NyApOyAvLyBGaWxsIDIwIG9mIHZhbHVlIChieXRlKSAtODcKLSAgICAgICAgQ0hBUlNbMzk3M10gPSAzMzsKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDM5NzQsIDM5ODAsIChieXRlKSAtODcgKTsgLy8gRmlsbCA2IG9mIHZhbHVlIChieXRlKSAtODcKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDM5ODAsIDM5ODQsIChieXRlKSAzMyApOyAvLyBGaWxsIDQgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAzOTg0LCAzOTkwLCAoYnl0ZSkgLTg3ICk7IC8vIEZpbGwgNiBvZiB2YWx1ZSAoYnl0ZSkgLTg3Ci0gICAgICAgIENIQVJTWzM5OTBdID0gMzM7Ci0gICAgICAgIENIQVJTWzM5OTFdID0gLTg3OwotICAgICAgICBDSEFSU1szOTkyXSA9IDMzOwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMzk5MywgNDAxNCwgKGJ5dGUpIC04NyApOyAvLyBGaWxsIDIxIG9mIHZhbHVlIChieXRlKSAtODcKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDQwMTQsIDQwMTcsIChieXRlKSAzMyApOyAvLyBGaWxsIDMgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCA0MDE3LCA0MDI0LCAoYnl0ZSkgLTg3ICk7IC8vIEZpbGwgNyBvZiB2YWx1ZSAoYnl0ZSkgLTg3Ci0gICAgICAgIENIQVJTWzQwMjRdID0gMzM7Ci0gICAgICAgIENIQVJTWzQwMjVdID0gLTg3OwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgNDAyNiwgNDI1NiwgKGJ5dGUpIDMzICk7IC8vIEZpbGwgMjMwIG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgNDI1NiwgNDI5NCwgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDM4IG9mIHZhbHVlIChieXRlKSAtMTkKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDQyOTQsIDQzMDQsIChieXRlKSAzMyApOyAvLyBGaWxsIDEwIG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgNDMwNCwgNDM0MywgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDM5IG9mIHZhbHVlIChieXRlKSAtMTkKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDQzNDMsIDQzNTIsIChieXRlKSAzMyApOyAvLyBGaWxsIDkgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIENIQVJTWzQzNTJdID0gLTE5OwotICAgICAgICBDSEFSU1s0MzUzXSA9IDMzOwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgNDM1NCwgNDM1NiwgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDIgb2YgdmFsdWUgKGJ5dGUpIC0xOQotICAgICAgICBDSEFSU1s0MzU2XSA9IDMzOwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgNDM1NywgNDM2MCwgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDMgb2YgdmFsdWUgKGJ5dGUpIC0xOQotICAgICAgICBDSEFSU1s0MzYwXSA9IDMzOwotICAgICAgICBDSEFSU1s0MzYxXSA9IC0xOTsKLSAgICAgICAgQ0hBUlNbNDM2Ml0gPSAzMzsKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDQzNjMsIDQzNjUsIChieXRlKSAtMTkgKTsgLy8gRmlsbCAyIG9mIHZhbHVlIChieXRlKSAtMTkKLSAgICAgICAgQ0hBUlNbNDM2NV0gPSAzMzsKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDQzNjYsIDQzNzEsIChieXRlKSAtMTkgKTsgLy8gRmlsbCA1IG9mIHZhbHVlIChieXRlKSAtMTkKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDQzNzEsIDQ0MTIsIChieXRlKSAzMyApOyAvLyBGaWxsIDQxIG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBDSEFSU1s0NDEyXSA9IC0xOTsKLSAgICAgICAgQ0hBUlNbNDQxM10gPSAzMzsKLSAgICAgICAgQ0hBUlNbNDQxNF0gPSAtMTk7Ci0gICAgICAgIENIQVJTWzQ0MTVdID0gMzM7Ci0gICAgICAgIENIQVJTWzQ0MTZdID0gLTE5OwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgNDQxNywgNDQyOCwgKGJ5dGUpIDMzICk7IC8vIEZpbGwgMTEgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIENIQVJTWzQ0MjhdID0gLTE5OwotICAgICAgICBDSEFSU1s0NDI5XSA9IDMzOwotICAgICAgICBDSEFSU1s0NDMwXSA9IC0xOTsKLSAgICAgICAgQ0hBUlNbNDQzMV0gPSAzMzsKLSAgICAgICAgQ0hBUlNbNDQzMl0gPSAtMTk7Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCA0NDMzLCA0NDM2LCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCAzIG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgNDQzNiwgNDQzOCwgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDIgb2YgdmFsdWUgKGJ5dGUpIC0xOQotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgNDQzOCwgNDQ0MSwgKGJ5dGUpIDMzICk7IC8vIEZpbGwgMyBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgQ0hBUlNbNDQ0MV0gPSAtMTk7Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCA0NDQyLCA0NDQ3LCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCA1IG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgNDQ0NywgNDQ1MCwgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDMgb2YgdmFsdWUgKGJ5dGUpIC0xOQotICAgICAgICBDSEFSU1s0NDUwXSA9IDMzOwotICAgICAgICBDSEFSU1s0NDUxXSA9IC0xOTsKLSAgICAgICAgQ0hBUlNbNDQ1Ml0gPSAzMzsKLSAgICAgICAgQ0hBUlNbNDQ1M10gPSAtMTk7Ci0gICAgICAgIENIQVJTWzQ0NTRdID0gMzM7Ci0gICAgICAgIENIQVJTWzQ0NTVdID0gLTE5OwotICAgICAgICBDSEFSU1s0NDU2XSA9IDMzOwotICAgICAgICBDSEFSU1s0NDU3XSA9IC0xOTsKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDQ0NTgsIDQ0NjEsIChieXRlKSAzMyApOyAvLyBGaWxsIDMgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCA0NDYxLCA0NDYzLCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgMiBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCA0NDYzLCA0NDY2LCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCAzIG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgNDQ2NiwgNDQ2OCwgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDIgb2YgdmFsdWUgKGJ5dGUpIC0xOQotICAgICAgICBDSEFSU1s0NDY4XSA9IDMzOwotICAgICAgICBDSEFSU1s0NDY5XSA9IC0xOTsKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDQ0NzAsIDQ1MTAsIChieXRlKSAzMyApOyAvLyBGaWxsIDQwIG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBDSEFSU1s0NTEwXSA9IC0xOTsKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDQ1MTEsIDQ1MjAsIChieXRlKSAzMyApOyAvLyBGaWxsIDkgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIENIQVJTWzQ1MjBdID0gLTE5OwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgNDUyMSwgNDUyMywgKGJ5dGUpIDMzICk7IC8vIEZpbGwgMiBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgQ0hBUlNbNDUyM10gPSAtMTk7Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCA0NTI0LCA0NTI2LCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCAyIG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgNDUyNiwgNDUyOCwgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDIgb2YgdmFsdWUgKGJ5dGUpIC0xOQotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgNDUyOCwgNDUzNSwgKGJ5dGUpIDMzICk7IC8vIEZpbGwgNyBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDQ1MzUsIDQ1MzcsIChieXRlKSAtMTkgKTsgLy8gRmlsbCAyIG9mIHZhbHVlIChieXRlKSAtMTkKLSAgICAgICAgQ0hBUlNbNDUzN10gPSAzMzsKLSAgICAgICAgQ0hBUlNbNDUzOF0gPSAtMTk7Ci0gICAgICAgIENIQVJTWzQ1MzldID0gMzM7Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCA0NTQwLCA0NTQ3LCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgNyBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCA0NTQ3LCA0NTg3LCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCA0MCBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgQ0hBUlNbNDU4N10gPSAtMTk7Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCA0NTg4LCA0NTkyLCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCA0IG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBDSEFSU1s0NTkyXSA9IC0xOTsKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDQ1OTMsIDQ2MDEsIChieXRlKSAzMyApOyAvLyBGaWxsIDggb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIENIQVJTWzQ2MDFdID0gLTE5OwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgNDYwMiwgNzY4MCwgKGJ5dGUpIDMzICk7IC8vIEZpbGwgMzA3OCBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDc2ODAsIDc4MzYsIChieXRlKSAtMTkgKTsgLy8gRmlsbCAxNTYgb2YgdmFsdWUgKGJ5dGUpIC0xOQotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgNzgzNiwgNzg0MCwgKGJ5dGUpIDMzICk7IC8vIEZpbGwgNCBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDc4NDAsIDc5MzAsIChieXRlKSAtMTkgKTsgLy8gRmlsbCA5MCBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCA3OTMwLCA3OTM2LCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCA2IG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgNzkzNiwgNzk1OCwgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDIyIG9mIHZhbHVlIChieXRlKSAtMTkKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDc5NTgsIDc5NjAsIChieXRlKSAzMyApOyAvLyBGaWxsIDIgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCA3OTYwLCA3OTY2LCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgNiBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCA3OTY2LCA3OTY4LCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCAyIG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgNzk2OCwgODAwNiwgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDM4IG9mIHZhbHVlIChieXRlKSAtMTkKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDgwMDYsIDgwMDgsIChieXRlKSAzMyApOyAvLyBGaWxsIDIgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCA4MDA4LCA4MDE0LCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgNiBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCA4MDE0LCA4MDE2LCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCAyIG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgODAxNiwgODAyNCwgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDggb2YgdmFsdWUgKGJ5dGUpIC0xOQotICAgICAgICBDSEFSU1s4MDI0XSA9IDMzOwotICAgICAgICBDSEFSU1s4MDI1XSA9IC0xOTsKLSAgICAgICAgQ0hBUlNbODAyNl0gPSAzMzsKLSAgICAgICAgQ0hBUlNbODAyN10gPSAtMTk7Ci0gICAgICAgIENIQVJTWzgwMjhdID0gMzM7Ci0gICAgICAgIENIQVJTWzgwMjldID0gLTE5OwotICAgICAgICBDSEFSU1s4MDMwXSA9IDMzOwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgODAzMSwgODA2MiwgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDMxIG9mIHZhbHVlIChieXRlKSAtMTkKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDgwNjIsIDgwNjQsIChieXRlKSAzMyApOyAvLyBGaWxsIDIgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCA4MDY0LCA4MTE3LCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgNTMgb2YgdmFsdWUgKGJ5dGUpIC0xOQotICAgICAgICBDSEFSU1s4MTE3XSA9IDMzOwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgODExOCwgODEyNSwgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDcgb2YgdmFsdWUgKGJ5dGUpIC0xOQotICAgICAgICBDSEFSU1s4MTI1XSA9IDMzOwotICAgICAgICBDSEFSU1s4MTI2XSA9IC0xOTsKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDgxMjcsIDgxMzAsIChieXRlKSAzMyApOyAvLyBGaWxsIDMgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCA4MTMwLCA4MTMzLCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgMyBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIENIQVJTWzgxMzNdID0gMzM7Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCA4MTM0LCA4MTQxLCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgNyBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCA4MTQxLCA4MTQ0LCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCAzIG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgODE0NCwgODE0OCwgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDQgb2YgdmFsdWUgKGJ5dGUpIC0xOQotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgODE0OCwgODE1MCwgKGJ5dGUpIDMzICk7IC8vIEZpbGwgMiBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDgxNTAsIDgxNTYsIChieXRlKSAtMTkgKTsgLy8gRmlsbCA2IG9mIHZhbHVlIChieXRlKSAtMTkKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDgxNTYsIDgxNjAsIChieXRlKSAzMyApOyAvLyBGaWxsIDQgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCA4MTYwLCA4MTczLCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgMTMgb2YgdmFsdWUgKGJ5dGUpIC0xOQotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgODE3MywgODE3OCwgKGJ5dGUpIDMzICk7IC8vIEZpbGwgNSBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDgxNzgsIDgxODEsIChieXRlKSAtMTkgKTsgLy8gRmlsbCAzIG9mIHZhbHVlIChieXRlKSAtMTkKLSAgICAgICAgQ0hBUlNbODE4MV0gPSAzMzsKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDgxODIsIDgxODksIChieXRlKSAtMTkgKTsgLy8gRmlsbCA3IG9mIHZhbHVlIChieXRlKSAtMTkKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDgxODksIDg0MDAsIChieXRlKSAzMyApOyAvLyBGaWxsIDIxMSBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDg0MDAsIDg0MTMsIChieXRlKSAtODcgKTsgLy8gRmlsbCAxMyBvZiB2YWx1ZSAoYnl0ZSkgLTg3Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCA4NDEzLCA4NDE3LCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCA0IG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBDSEFSU1s4NDE3XSA9IC04NzsKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDg0MTgsIDg0ODYsIChieXRlKSAzMyApOyAvLyBGaWxsIDY4IG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBDSEFSU1s4NDg2XSA9IC0xOTsKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDg0ODcsIDg0OTAsIChieXRlKSAzMyApOyAvLyBGaWxsIDMgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCA4NDkwLCA4NDkyLCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgMiBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCA4NDkyLCA4NDk0LCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCAyIG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBDSEFSU1s4NDk0XSA9IC0xOTsKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDg0OTUsIDg1NzYsIChieXRlKSAzMyApOyAvLyBGaWxsIDgxIG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgODU3NiwgODU3OSwgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDMgb2YgdmFsdWUgKGJ5dGUpIC0xOQotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgODU3OSwgMTIyOTMsIChieXRlKSAzMyApOyAvLyBGaWxsIDM3MTQgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIENIQVJTWzEyMjkzXSA9IC04NzsKLSAgICAgICAgQ0hBUlNbMTIyOTRdID0gMzM7Ci0gICAgICAgIENIQVJTWzEyMjk1XSA9IC0xOTsKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDEyMjk2LCAxMjMyMSwgKGJ5dGUpIDMzICk7IC8vIEZpbGwgMjUgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAxMjMyMSwgMTIzMzAsIChieXRlKSAtMTkgKTsgLy8gRmlsbCA5IG9mIHZhbHVlIChieXRlKSAtMTkKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDEyMzMwLCAxMjMzNiwgKGJ5dGUpIC04NyApOyAvLyBGaWxsIDYgb2YgdmFsdWUgKGJ5dGUpIC04NwotICAgICAgICBDSEFSU1sxMjMzNl0gPSAzMzsKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDEyMzM3LCAxMjM0MiwgKGJ5dGUpIC04NyApOyAvLyBGaWxsIDUgb2YgdmFsdWUgKGJ5dGUpIC04NwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMTIzNDIsIDEyMzUzLCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCAxMSBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDEyMzUzLCAxMjQzNywgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDg0IG9mIHZhbHVlIChieXRlKSAtMTkKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDEyNDM3LCAxMjQ0MSwgKGJ5dGUpIDMzICk7IC8vIEZpbGwgNCBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgQXJyYXlzLmZpbGwoQ0hBUlMsIDEyNDQxLCAxMjQ0MywgKGJ5dGUpIC04NyApOyAvLyBGaWxsIDIgb2YgdmFsdWUgKGJ5dGUpIC04NwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMTI0NDMsIDEyNDQ1LCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCAyIG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMTI0NDUsIDEyNDQ3LCAoYnl0ZSkgLTg3ICk7IC8vIEZpbGwgMiBvZiB2YWx1ZSAoYnl0ZSkgLTg3Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAxMjQ0NywgMTI0NDksIChieXRlKSAzMyApOyAvLyBGaWxsIDIgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAxMjQ0OSwgMTI1MzksIChieXRlKSAtMTkgKTsgLy8gRmlsbCA5MCBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIENIQVJTWzEyNTM5XSA9IDMzOwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgMTI1NDAsIDEyNTQzLCAoYnl0ZSkgLTg3ICk7IC8vIEZpbGwgMyBvZiB2YWx1ZSAoYnl0ZSkgLTg3Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAxMjU0MywgMTI1NDksIChieXRlKSAzMyApOyAvLyBGaWxsIDYgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAxMjU0OSwgMTI1ODksIChieXRlKSAtMTkgKTsgLy8gRmlsbCA0MCBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAxMjU4OSwgMTk5NjgsIChieXRlKSAzMyApOyAvLyBGaWxsIDczNzkgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCAxOTk2OCwgNDA4NzAsIChieXRlKSAtMTkgKTsgLy8gRmlsbCAyMDkwMiBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCA0MDg3MCwgNDQwMzIsIChieXRlKSAzMyApOyAvLyBGaWxsIDMxNjIgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCA0NDAzMiwgNTUyMDQsIChieXRlKSAtMTkgKTsgLy8gRmlsbCAxMTE3MiBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIEFycmF5cy5maWxsKENIQVJTLCA1NTIwNCwgNTUyOTYsIChieXRlKSAzMyApOyAvLyBGaWxsIDkyIG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBBcnJheXMuZmlsbChDSEFSUywgNTczNDQsIDY1NTM0LCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCA4MTkwIG9mIHZhbHVlIChieXRlKSAzMwotCi0gICAgfSAvLyA8Y2xpbml0PigpCi0KLSAgICAvLwotICAgIC8vIFB1YmxpYyBzdGF0aWMgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXIgaXMgYSBzdXBwbGVtZW50YWwgY2hhcmFjdGVyLgotICAgICAqCi0gICAgICogQHBhcmFtIGMgVGhlIGNoYXJhY3RlciB0byBjaGVjay4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNTdXBwbGVtZW50YWwoaW50IGMpIHsKLSAgICAgICAgcmV0dXJuIChjID49IDB4MTAwMDAgJiYgYyA8PSAweDEwRkZGRik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIHRoZSBzdXBwbGVtZW50YWwgY2hhcmFjdGVyIGNvcnJlc3BvbmRpbmcgdG8gdGhlIGdpdmVuCi0gICAgICogc3Vycm9nYXRlcy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBoIFRoZSBoaWdoIHN1cnJvZ2F0ZS4KLSAgICAgKiBAcGFyYW0gbCBUaGUgbG93IHN1cnJvZ2F0ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGludCBzdXBwbGVtZW50YWwoY2hhciBoLCBjaGFyIGwpIHsKLSAgICAgICAgcmV0dXJuIChoIC0gMHhEODAwKSAqIDB4NDAwICsgKGwgLSAweERDMDApICsgMHgxMDAwMDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBoaWdoIHN1cnJvZ2F0ZSBvZiBhIHN1cHBsZW1lbnRhbCBjaGFyYWN0ZXIKLSAgICAgKgotICAgICAqIEBwYXJhbSBjIFRoZSBzdXBwbGVtZW50YWwgY2hhcmFjdGVyIHRvICJzcGxpdCIuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBjaGFyIGhpZ2hTdXJyb2dhdGUoaW50IGMpIHsKLSAgICAgICAgcmV0dXJuIChjaGFyKSAoKChjIC0gMHgwMDAxMDAwMCkgPj4gMTApICsgMHhEODAwKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBsb3cgc3Vycm9nYXRlIG9mIGEgc3VwcGxlbWVudGFsIGNoYXJhY3RlcgotICAgICAqCi0gICAgICogQHBhcmFtIGMgVGhlIHN1cHBsZW1lbnRhbCBjaGFyYWN0ZXIgdG8gInNwbGl0Ii4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGNoYXIgbG93U3Vycm9nYXRlKGludCBjKSB7Ci0gICAgICAgIHJldHVybiAoY2hhcikgKCgoYyAtIDB4MDAwMTAwMDApICYgMHgzRkYpICsgMHhEQzAwKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhlIGdpdmVuIGNoYXJhY3RlciBpcyBhIGhpZ2ggc3Vycm9nYXRlCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYyBUaGUgY2hhcmFjdGVyIHRvIGNoZWNrLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0hpZ2hTdXJyb2dhdGUoaW50IGMpIHsKLSAgICAgICAgcmV0dXJuICgweEQ4MDAgPD0gYyAmJiBjIDw9IDB4REJGRik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB3aGV0aGVyIHRoZSBnaXZlbiBjaGFyYWN0ZXIgaXMgYSBsb3cgc3Vycm9nYXRlCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYyBUaGUgY2hhcmFjdGVyIHRvIGNoZWNrLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0xvd1N1cnJvZ2F0ZShpbnQgYykgewotICAgICAgICByZXR1cm4gKDB4REMwMCA8PSBjICYmIGMgPD0gMHhERkZGKTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgc3BlY2lmaWVkIGNoYXJhY3RlciBpcyB2YWxpZC4gVGhpcyBtZXRob2QKLSAgICAgKiBhbHNvIGNoZWNrcyB0aGUgc3Vycm9nYXRlIGNoYXJhY3RlciByYW5nZSBmcm9tIDB4MTAwMDAgdG8gMHgxMEZGRkYuCi0gICAgICogPHA+Ci0gICAgICogSWYgdGhlIHByb2dyYW0gY2hvb3NlcyB0byBhcHBseSB0aGUgbWFzayBkaXJlY3RseSB0byB0aGUKLSAgICAgKiA8Y29kZT5DSEFSUzwvY29kZT4gYXJyYXksIHRoZW4gdGhleSBhcmUgcmVzcG9uc2libGUgZm9yIGNoZWNraW5nCi0gICAgICogdGhlIHN1cnJvZ2F0ZSBjaGFyYWN0ZXIgcmFuZ2UuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYyBUaGUgY2hhcmFjdGVyIHRvIGNoZWNrLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc1ZhbGlkKGludCBjKSB7Ci0gICAgICAgIHJldHVybiAoYyA8IDB4MTAwMDAgJiYgKENIQVJTW2NdICYgTUFTS19WQUxJRCkgIT0gMCkgfHwKLSAgICAgICAgICAgICAgICgweDEwMDAwIDw9IGMgJiYgYyA8PSAweDEwRkZGRik7Ci0gICAgfSAvLyBpc1ZhbGlkKGludCk6Ym9vbGVhbgotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyIGlzIGludmFsaWQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYyBUaGUgY2hhcmFjdGVyIHRvIGNoZWNrLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0ludmFsaWQoaW50IGMpIHsKLSAgICAgICAgcmV0dXJuICFpc1ZhbGlkKGMpOwotICAgIH0gLy8gaXNJbnZhbGlkKGludCk6Ym9vbGVhbgotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyIGNhbiBiZSBjb25zaWRlcmVkIGNvbnRlbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYyBUaGUgY2hhcmFjdGVyIHRvIGNoZWNrLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0NvbnRlbnQoaW50IGMpIHsKLSAgICAgICAgcmV0dXJuIChjIDwgMHgxMDAwMCAmJiAoQ0hBUlNbY10gJiBNQVNLX0NPTlRFTlQpICE9IDApIHx8Ci0gICAgICAgICAgICAgICAoMHgxMDAwMCA8PSBjICYmIGMgPD0gMHgxMEZGRkYpOwotICAgIH0gLy8gaXNDb250ZW50KGludCk6Ym9vbGVhbgotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyIGNhbiBiZSBjb25zaWRlcmVkIG1hcmt1cC4KLSAgICAgKiBNYXJrdXAgY2hhcmFjdGVycyBpbmNsdWRlICcmbHQ7JywgJyZhbXA7JywgYW5kICclJy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjIFRoZSBjaGFyYWN0ZXIgdG8gY2hlY2suCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzTWFya3VwKGludCBjKSB7Ci0gICAgICAgIHJldHVybiBjID09ICc8JyB8fCBjID09ICcmJyB8fCBjID09ICclJzsKLSAgICB9IC8vIGlzTWFya3VwKGludCk6Ym9vbGVhbgotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyIGlzIGEgc3BhY2UgY2hhcmFjdGVyCi0gICAgICogYXMgZGVmaW5lZCBieSBwcm9kdWN0aW9uIFszXSBpbiB0aGUgWE1MIDEuMCBzcGVjaWZpY2F0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIGMgVGhlIGNoYXJhY3RlciB0byBjaGVjay4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNTcGFjZShpbnQgYykgewotICAgICAgICByZXR1cm4gYyA8PSAweDIwICYmIChDSEFSU1tjXSAmIE1BU0tfU1BBQ0UpICE9IDA7Ci0gICAgfSAvLyBpc1NwYWNlKGludCk6Ym9vbGVhbgotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyIGlzIGEgdmFsaWQgbmFtZSBzdGFydAotICAgICAqIGNoYXJhY3RlciBhcyBkZWZpbmVkIGJ5IHByb2R1Y3Rpb24gWzVdIGluIHRoZSBYTUwgMS4wCi0gICAgICogc3BlY2lmaWNhdGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjIFRoZSBjaGFyYWN0ZXIgdG8gY2hlY2suCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzTmFtZVN0YXJ0KGludCBjKSB7Ci0gICAgICAgIHJldHVybiBjIDwgMHgxMDAwMCAmJiAoQ0hBUlNbY10gJiBNQVNLX05BTUVfU1RBUlQpICE9IDA7Ci0gICAgfSAvLyBpc05hbWVTdGFydChpbnQpOmJvb2xlYW4KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgc3BlY2lmaWVkIGNoYXJhY3RlciBpcyBhIHZhbGlkIG5hbWUKLSAgICAgKiBjaGFyYWN0ZXIgYXMgZGVmaW5lZCBieSBwcm9kdWN0aW9uIFs0XSBpbiB0aGUgWE1MIDEuMAotICAgICAqIHNwZWNpZmljYXRpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYyBUaGUgY2hhcmFjdGVyIHRvIGNoZWNrLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc05hbWUoaW50IGMpIHsKLSAgICAgICAgcmV0dXJuIGMgPCAweDEwMDAwICYmIChDSEFSU1tjXSAmIE1BU0tfTkFNRSkgIT0gMDsKLSAgICB9IC8vIGlzTmFtZShpbnQpOmJvb2xlYW4KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgc3BlY2lmaWVkIGNoYXJhY3RlciBpcyBhIHZhbGlkIE5DTmFtZSBzdGFydAotICAgICAqIGNoYXJhY3RlciBhcyBkZWZpbmVkIGJ5IHByb2R1Y3Rpb24gWzRdIGluIE5hbWVzcGFjZXMgaW4gWE1MCi0gICAgICogcmVjb21tZW5kYXRpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYyBUaGUgY2hhcmFjdGVyIHRvIGNoZWNrLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc05DTmFtZVN0YXJ0KGludCBjKSB7Ci0gICAgICAgIHJldHVybiBjIDwgMHgxMDAwMCAmJiAoQ0hBUlNbY10gJiBNQVNLX05DTkFNRV9TVEFSVCkgIT0gMDsKLSAgICB9IC8vIGlzTkNOYW1lU3RhcnQoaW50KTpib29sZWFuCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXIgaXMgYSB2YWxpZCBOQ05hbWUKLSAgICAgKiBjaGFyYWN0ZXIgYXMgZGVmaW5lZCBieSBwcm9kdWN0aW9uIFs1XSBpbiBOYW1lc3BhY2VzIGluIFhNTAotICAgICAqIHJlY29tbWVuZGF0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIGMgVGhlIGNoYXJhY3RlciB0byBjaGVjay4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNOQ05hbWUoaW50IGMpIHsKLSAgICAgICAgcmV0dXJuIGMgPCAweDEwMDAwICYmIChDSEFSU1tjXSAmIE1BU0tfTkNOQU1FKSAhPSAwOwotICAgIH0gLy8gaXNOQ05hbWUoaW50KTpib29sZWFuCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXIgaXMgYSB2YWxpZCBQdWJpZAotICAgICAqIGNoYXJhY3RlciBhcyBkZWZpbmVkIGJ5IHByb2R1Y3Rpb24gWzEzXSBpbiB0aGUgWE1MIDEuMAotICAgICAqIHNwZWNpZmljYXRpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYyBUaGUgY2hhcmFjdGVyIHRvIGNoZWNrLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc1B1YmlkKGludCBjKSB7Ci0gICAgICAgIHJldHVybiBjIDwgMHgxMDAwMCAmJiAoQ0hBUlNbY10gJiBNQVNLX1BVQklEKSAhPSAwOwotICAgIH0gLy8gaXNQdWJpZChpbnQpOmJvb2xlYW4KLQotICAgIC8qCi0gICAgICogWzVdIE5hbWUgOjo9IChMZXR0ZXIgfCAnXycgfCAnOicpIChOYW1lQ2hhcikqCi0gICAgICovCi0gICAgLyoqCi0gICAgICogQ2hlY2sgdG8gc2VlIGlmIGEgc3RyaW5nIGlzIGEgdmFsaWQgTmFtZSBhY2NvcmRpbmcgdG8gWzVdCi0gICAgICogaW4gdGhlIFhNTCAxLjAgUmVjb21tZW5kYXRpb24KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lIHN0cmluZyB0byBjaGVjawotICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBuYW1lIGlzIGEgdmFsaWQgTmFtZQotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc1ZhbGlkTmFtZShTdHJpbmcgbmFtZSkgewotICAgICAgICBmaW5hbCBpbnQgbGVuZ3RoID0gbmFtZS5sZW5ndGgoKTsKLSAgICAgICAgaWYgKGxlbmd0aCA9PSAwKSB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLSAgICAgICAgY2hhciBjaCA9IG5hbWUuY2hhckF0KDApOwotICAgICAgICBpZiAoIWlzTmFtZVN0YXJ0KGNoKSkgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0gICAgICAgIGZvciAoaW50IGkgPSAxOyBpIDwgbGVuZ3RoOyArK2kpIHsKLSAgICAgICAgICAgIGNoID0gbmFtZS5jaGFyQXQoaSk7Ci0gICAgICAgICAgICBpZiAoIWlzTmFtZShjaCkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfSAvLyBpc1ZhbGlkTmFtZShTdHJpbmcpOmJvb2xlYW4KLQotICAgIC8qCi0gICAgICogZnJvbSB0aGUgbmFtZXNwYWNlIHJlYwotICAgICAqIFs0XSBOQ05hbWUgOjo9IChMZXR0ZXIgfCAnXycpIChOQ05hbWVDaGFyKSoKLSAgICAgKi8KLSAgICAvKioKLSAgICAgKiBDaGVjayB0byBzZWUgaWYgYSBzdHJpbmcgaXMgYSB2YWxpZCBOQ05hbWUgYWNjb3JkaW5nIHRvIFs0XQotICAgICAqIGZyb20gdGhlIFhNTCBOYW1lc3BhY2VzIDEuMCBSZWNvbW1lbmRhdGlvbgotICAgICAqCi0gICAgICogQHBhcmFtIG5jTmFtZSBzdHJpbmcgdG8gY2hlY2sKLSAgICAgKiBAcmV0dXJuIHRydWUgaWYgbmFtZSBpcyBhIHZhbGlkIE5DTmFtZQotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc1ZhbGlkTkNOYW1lKFN0cmluZyBuY05hbWUpIHsKLSAgICAgICAgZmluYWwgaW50IGxlbmd0aCA9IG5jTmFtZS5sZW5ndGgoKTsKLSAgICAgICAgaWYgKGxlbmd0aCA9PSAwKSB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLSAgICAgICAgY2hhciBjaCA9IG5jTmFtZS5jaGFyQXQoMCk7Ci0gICAgICAgIGlmICghaXNOQ05hbWVTdGFydChjaCkpIHsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotICAgICAgICBmb3IgKGludCBpID0gMTsgaSA8IGxlbmd0aDsgKytpKSB7Ci0gICAgICAgICAgICBjaCA9IG5jTmFtZS5jaGFyQXQoaSk7Ci0gICAgICAgICAgICBpZiAoIWlzTkNOYW1lKGNoKSkgewotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICB9IC8vIGlzVmFsaWROQ05hbWUoU3RyaW5nKTpib29sZWFuCi0KLSAgICAvKgotICAgICAqIFs3XSBObXRva2VuIDo6PSAoTmFtZUNoYXIpKwotICAgICAqLwotICAgIC8qKgotICAgICAqIENoZWNrIHRvIHNlZSBpZiBhIHN0cmluZyBpcyBhIHZhbGlkIE5tdG9rZW4gYWNjb3JkaW5nIHRvIFs3XQotICAgICAqIGluIHRoZSBYTUwgMS4wIFJlY29tbWVuZGF0aW9uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbm10b2tlbiBzdHJpbmcgdG8gY2hlY2sKLSAgICAgKiBAcmV0dXJuIHRydWUgaWYgbm10b2tlbiBpcyBhIHZhbGlkIE5tdG9rZW4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNWYWxpZE5tdG9rZW4oU3RyaW5nIG5tdG9rZW4pIHsKLSAgICAgICAgZmluYWwgaW50IGxlbmd0aCA9IG5tdG9rZW4ubGVuZ3RoKCk7Ci0gICAgICAgIGlmIChsZW5ndGggPT0gMCkgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyArK2kpIHsKLSAgICAgICAgICAgIGNoYXIgY2ggPSBubXRva2VuLmNoYXJBdChpKTsKLSAgICAgICAgICAgIGlmICghaXNOYW1lKGNoKSkgewotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICB9IC8vIGlzVmFsaWROYW1lKFN0cmluZyk6Ym9vbGVhbgotCi0KLQotCi0KLSAgICAvLyBlbmNvZGluZ3MKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgZW5jb2RpbmcgbmFtZSBpcyBhIHZhbGlkIElBTkEgZW5jb2RpbmcuCi0gICAgICogVGhpcyBtZXRob2QgZG9lcyBub3QgdmVyaWZ5IHRoYXQgdGhlcmUgaXMgYSBkZWNvZGVyIGF2YWlsYWJsZQotICAgICAqIGZvciB0aGlzIGVuY29kaW5nLCBvbmx5IHRoYXQgdGhlIGNoYXJhY3RlcnMgYXJlIHZhbGlkIGZvciBhbgotICAgICAqIElBTkEgZW5jb2RpbmcgbmFtZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBpYW5hRW5jb2RpbmcgVGhlIElBTkEgZW5jb2RpbmcgbmFtZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNWYWxpZElBTkFFbmNvZGluZyhTdHJpbmcgaWFuYUVuY29kaW5nKSB7Ci0gICAgICAgIGlmIChpYW5hRW5jb2RpbmcgIT0gbnVsbCkgewotICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlhbmFFbmNvZGluZy5sZW5ndGgoKTsKLSAgICAgICAgICAgIGlmIChsZW5ndGggPiAwKSB7Ci0gICAgICAgICAgICAgICAgY2hhciBjID0gaWFuYUVuY29kaW5nLmNoYXJBdCgwKTsKLSAgICAgICAgICAgICAgICBpZiAoKGMgPj0gJ0EnICYmIGMgPD0gJ1onKSB8fCAoYyA+PSAnYScgJiYgYyA8PSAneicpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAxOyBpIDwgbGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGMgPSBpYW5hRW5jb2RpbmcuY2hhckF0KGkpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChjIDwgJ0EnIHx8IGMgPiAnWicpICYmIChjIDwgJ2EnIHx8IGMgPiAneicpICYmCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGMgPCAnMCcgfHwgYyA+ICc5JykgJiYgYyAhPSAnLicgJiYgYyAhPSAnXycgJiYKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjICE9ICctJykgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0gLy8gaXNWYWxpZElBTkFFbmNvZGluZyhTdHJpbmcpOmJvb2xlYW4KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgZW5jb2RpbmcgbmFtZSBpcyBhIHZhbGlkIEphdmEgZW5jb2RpbmcuCi0gICAgICogVGhpcyBtZXRob2QgZG9lcyBub3QgdmVyaWZ5IHRoYXQgdGhlcmUgaXMgYSBkZWNvZGVyIGF2YWlsYWJsZQotICAgICAqIGZvciB0aGlzIGVuY29kaW5nLCBvbmx5IHRoYXQgdGhlIGNoYXJhY3RlcnMgYXJlIHZhbGlkIGZvciBhbgotICAgICAqIEphdmEgZW5jb2RpbmcgbmFtZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBqYXZhRW5jb2RpbmcgVGhlIEphdmEgZW5jb2RpbmcgbmFtZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNWYWxpZEphdmFFbmNvZGluZyhTdHJpbmcgamF2YUVuY29kaW5nKSB7Ci0gICAgICAgIGlmIChqYXZhRW5jb2RpbmcgIT0gbnVsbCkgewotICAgICAgICAgICAgaW50IGxlbmd0aCA9IGphdmFFbmNvZGluZy5sZW5ndGgoKTsKLSAgICAgICAgICAgIGlmIChsZW5ndGggPiAwKSB7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDE7IGkgPCBsZW5ndGg7IGkrKykgewotICAgICAgICAgICAgICAgICAgICBjaGFyIGMgPSBqYXZhRW5jb2RpbmcuY2hhckF0KGkpOwotICAgICAgICAgICAgICAgICAgICBpZiAoKGMgPCAnQScgfHwgYyA+ICdaJykgJiYgKGMgPCAnYScgfHwgYyA+ICd6JykgJiYKLSAgICAgICAgICAgICAgICAgICAgICAgIChjIDwgJzAnIHx8IGMgPiAnOScpICYmIGMgIT0gJy4nICYmIGMgIT0gJ18nICYmCi0gICAgICAgICAgICAgICAgICAgICAgICBjICE9ICctJykgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9IC8vIGlzVmFsaWRJQU5BRW5jb2RpbmcoU3RyaW5nKTpib29sZWFuCi0KLSAgICAvLyBvdGhlciBtZXRob2RzCi0KLSAgICAvKioKLSAgICAgKiBUcmltcyBzcGFjZSBjaGFyYWN0ZXJzIGFzIGRlZmluZWQgYnkgcHJvZHVjdGlvbiBbM10gaW4KLSAgICAgKiB0aGUgWE1MIDEuMCBzcGVjaWZpY2F0aW9uIGZyb20gYm90aCBlbmRzIG9mIHRoZSBnaXZlbiBzdHJpbmcuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdmFsdWUgdGhlIHN0cmluZyB0byBiZSB0cmltbWVkCi0gICAgICogQHJldHVybiB0aGUgZ2l2ZW4gc3RyaW5nIHdpdGggdGhlIHNwYWNlIGNoYXJhY3RlcnMgdHJpbW1lZAotICAgICAqIGZyb20gYm90aCBlbmRzCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBTdHJpbmcgdHJpbShTdHJpbmcgdmFsdWUpIHsKLSAgICAgICAgaW50IHN0YXJ0OwotICAgICAgICBpbnQgZW5kOwotICAgICAgICBmaW5hbCBpbnQgbGVuZ3RoTWludXNPbmUgPSB2YWx1ZS5sZW5ndGgoKSAtIDE7Ci0gICAgICAgIGZvciAoc3RhcnQgPSAwOyBzdGFydCA8PSBsZW5ndGhNaW51c09uZTsgKytzdGFydCkgewotICAgICAgICAgICAgaWYgKCFpc1NwYWNlKHZhbHVlLmNoYXJBdChzdGFydCkpKSB7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZm9yIChlbmQgPSBsZW5ndGhNaW51c09uZTsgZW5kID49IHN0YXJ0OyAtLWVuZCkgewotICAgICAgICAgICAgaWYgKCFpc1NwYWNlKHZhbHVlLmNoYXJBdChlbmQpKSkgewotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGlmIChzdGFydCA9PSAwICYmIGVuZCA9PSBsZW5ndGhNaW51c09uZSkgewotICAgICAgICAgICAgcmV0dXJuIHZhbHVlOwotICAgICAgICB9Ci0gICAgICAgIGlmIChzdGFydCA+IGxlbmd0aE1pbnVzT25lKSB7Ci0gICAgICAgICAgICByZXR1cm4gIiI7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHZhbHVlLnN1YnN0cmluZyhzdGFydCwgZW5kICsgMSk7Ci0gICAgfSAvLyB0cmltKFN0cmluZyk6U3RyaW5nCi0KLX0gLy8gY2xhc3MgWE1MQ2hhcgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9YTUxEb2N1bWVudEZpbHRlckltcGwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3V0aWwvWE1MRG9jdW1lbnRGaWx0ZXJJbXBsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGJkZTZmZDIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9YTUxEb2N1bWVudEZpbHRlckltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE4MiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAwLTIwMDIgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYZXJjZXMiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIEludGVybmF0aW9uYWwKLSAqIEJ1c2luZXNzIE1hY2hpbmVzLCBJbmMuLCBodHRwOi8vd3d3LmFwYWNoZS5vcmcuICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuQXVnbWVudGF0aW9uczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5OYW1lc3BhY2VDb250ZXh0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlFOYW1lOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTEF0dHJpYnV0ZXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MRG9jdW1lbnRIYW5kbGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTExvY2F0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MUmVzb3VyY2VJZGVudGlmaWVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTFN0cmluZzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTklFeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTERvY3VtZW50RmlsdGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxEb2N1bWVudFNvdXJjZTsKLQotLyoqCi0gKiBEZWZhdWx0IGltcGxlbWVudGF0aW9uIG9mIHtAbGluayBYTUxEb2N1bWVudEZpbHRlcn0KLSAqIHRoYXQgc2ltcGx5IHBhc3NlcyB0aHJvdWdoIGV2ZW50cyB0byB0aGUgbmV4dCBjb21wb25lbnQuCi0gKgotICogPHA+Ci0gKiBDYW4gYmUgdXNlZCBhcyBhIGJhc2UgaW1wbGVtZW50YXRpb24gb2Ygb3RoZXIgbW9yZSBzb3BoaXN0aWNhdGVkCi0gKiB7QGxpbmsgWE1MRG9jdW1lbnRGaWx0ZXJ9cy4KLSAqCi0gKiBAYXV0aG9yCi0gKiAgICAgS29oc3VrZSBLYXdhZ3VjaGkgKGtvaHN1a2Uua2F3YWd1Y2hpQHN1bi5jb20pCi0gKi8KLXB1YmxpYyBjbGFzcyBYTUxEb2N1bWVudEZpbHRlckltcGwgaW1wbGVtZW50cyBYTUxEb2N1bWVudEZpbHRlciB7Ci0gICAgcHJpdmF0ZSBYTUxEb2N1bWVudEhhbmRsZXIgbmV4dDsKLSAgICBwcml2YXRlIFhNTERvY3VtZW50U291cmNlIHNvdXJjZTsKLQotCi0gICAgcHVibGljIHZvaWQgc2V0RG9jdW1lbnRIYW5kbGVyKFhNTERvY3VtZW50SGFuZGxlciBoYW5kbGVyKSB7Ci0gICAgICAgIHRoaXMubmV4dCA9IGhhbmRsZXI7Ci0gICAgfQotCi0gICAgcHVibGljIFhNTERvY3VtZW50SGFuZGxlciBnZXREb2N1bWVudEhhbmRsZXIoKSB7Ci0gICAgICAgIHJldHVybiBuZXh0OwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldERvY3VtZW50U291cmNlKFhNTERvY3VtZW50U291cmNlIHNvdXJjZSkgewotICAgICAgICB0aGlzLnNvdXJjZSA9IHNvdXJjZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgWE1MRG9jdW1lbnRTb3VyY2UgZ2V0RG9jdW1lbnRTb3VyY2UoKSB7Ci0gICAgICAgIHJldHVybiBzb3VyY2U7Ci0gICAgfQotCi0KLQotCi0KLQotICAgIHB1YmxpYyB2b2lkIGNoYXJhY3RlcnMoWE1MU3RyaW5nIHRleHQsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIG5leHQuY2hhcmFjdGVycyh0ZXh0LCBhdWdzKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBjb21tZW50KFhNTFN0cmluZyB0ZXh0LCBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBuZXh0LmNvbW1lbnQodGV4dCwgYXVncyk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgZG9jdHlwZURlY2woU3RyaW5nIHJvb3RFbGVtZW50LCBTdHJpbmcgcHVibGljSWQsIFN0cmluZyBzeXN0ZW1JZCwgQXVnbWVudGF0aW9ucyBhdWdzKQotICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgbmV4dC5kb2N0eXBlRGVjbChyb290RWxlbWVudCwgcHVibGljSWQsIHN5c3RlbUlkLCBhdWdzKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBlbXB0eUVsZW1lbnQoUU5hbWUgZWxlbWVudCwgWE1MQXR0cmlidXRlcyBhdHRyaWJ1dGVzLCBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBuZXh0LmVtcHR5RWxlbWVudChlbGVtZW50LCBhdHRyaWJ1dGVzLCBhdWdzKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBlbmRDREFUQShBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBuZXh0LmVuZENEQVRBKGF1Z3MpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGVuZERvY3VtZW50KEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIG5leHQuZW5kRG9jdW1lbnQoYXVncyk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgZW5kRWxlbWVudChRTmFtZSBlbGVtZW50LCBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBuZXh0LmVuZEVsZW1lbnQoZWxlbWVudCwgYXVncyk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgZW5kR2VuZXJhbEVudGl0eShTdHJpbmcgbmFtZSwgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgbmV4dC5lbmRHZW5lcmFsRW50aXR5KG5hbWUsIGF1Z3MpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGlnbm9yYWJsZVdoaXRlc3BhY2UoWE1MU3RyaW5nIHRleHQsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIG5leHQuaWdub3JhYmxlV2hpdGVzcGFjZSh0ZXh0LCBhdWdzKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oU3RyaW5nIHRhcmdldCwgWE1MU3RyaW5nIGRhdGEsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIG5leHQucHJvY2Vzc2luZ0luc3RydWN0aW9uKHRhcmdldCwgZGF0YSwgYXVncyk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc3RhcnRDREFUQShBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBuZXh0LnN0YXJ0Q0RBVEEoYXVncyk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc3RhcnREb2N1bWVudCgKLSAgICAgICAgWE1MTG9jYXRvciBsb2NhdG9yLAotICAgICAgICBTdHJpbmcgZW5jb2RpbmcsCi0gICAgICAgIE5hbWVzcGFjZUNvbnRleHQgbmFtZXNwYWNlQ29udGV4dCwKLSAgICAgICAgQXVnbWVudGF0aW9ucyBhdWdzKQotICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgbmV4dC5zdGFydERvY3VtZW50KGxvY2F0b3IsIGVuY29kaW5nLCBuYW1lc3BhY2VDb250ZXh0LCBhdWdzKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQoUU5hbWUgZWxlbWVudCwgWE1MQXR0cmlidXRlcyBhdHRyaWJ1dGVzLCBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBuZXh0LnN0YXJ0RWxlbWVudChlbGVtZW50LCBhdHRyaWJ1dGVzLCBhdWdzKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzdGFydEdlbmVyYWxFbnRpdHkoU3RyaW5nIG5hbWUsIFhNTFJlc291cmNlSWRlbnRpZmllciBpZGVudGlmaWVyLCBTdHJpbmcgZW5jb2RpbmcsIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIG5leHQuc3RhcnRHZW5lcmFsRW50aXR5KG5hbWUsIGlkZW50aWZpZXIsIGVuY29kaW5nLCBhdWdzKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCB0ZXh0RGVjbChTdHJpbmcgdmVyc2lvbiwgU3RyaW5nIGVuY29kaW5nLCBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBuZXh0LnRleHREZWNsKHZlcnNpb24sIGVuY29kaW5nLCBhdWdzKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCB4bWxEZWNsKFN0cmluZyB2ZXJzaW9uLCBTdHJpbmcgZW5jb2RpbmcsIFN0cmluZyBzdGFuZGFsb25lLCBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBuZXh0LnhtbERlY2wodmVyc2lvbiwgZW5jb2RpbmcsIHN0YW5kYWxvbmUsIGF1Z3MpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3V0aWwvWE1MRW50aXR5RGVzY3JpcHRpb25JbXBsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL1hNTEVudGl0eURlc2NyaXB0aW9uSW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwYTY1M2E5Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3V0aWwvWE1MRW50aXR5RGVzY3JpcHRpb25JbXBsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxODEgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLlhNTEVudGl0eURlc2NyaXB0aW9uOwotCi0vKioKLSAqIDxwPlRoaXMgY2xhc3MgaXMgYW4gaW1wbGVtZW50YXRpb24gb2YgdGhlIFhNTEVudGl0eURlc2NyaXB0aW9uCi0gKiBpbnRlcmZhY2Ugd2hpY2ggZGVzY3JpYmVzIHRoZSBwcm9wZXJ0aWVzIG9mIGFuIGVudGl0eS48L3A+Ci0gKgotICogQGF1dGhvciBNaWNoYWVsIEdsYXZhc3NldmljaCwgSUJNCi0gKgotICovCi1wdWJsaWMgY2xhc3MgWE1MRW50aXR5RGVzY3JpcHRpb25JbXBsCi0gICAgZXh0ZW5kcyBYTUxSZXNvdXJjZUlkZW50aWZpZXJJbXBsCi0gICAgaW1wbGVtZW50cyBYTUxFbnRpdHlEZXNjcmlwdGlvbiB7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0cnVjdG9ycwotICAgIC8vCi0KLSAgICAvKiogQ29uc3RydWN0cyBhbiBlbXB0eSBlbnRpdHkgZGVzY3JpcHRpb24uICovCi0gICAgcHVibGljIFhNTEVudGl0eURlc2NyaXB0aW9uSW1wbCgpIHt9IC8vIDxpbml0PigpCi0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RzIGFuIGVudGl0eSBkZXNjcmlwdGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlbnRpdHlOYW1lIFRoZSBuYW1lIG9mIHRoZSBlbnRpdHkuCi0gICAgICogQHBhcmFtIHB1YmxpY0lkIFRoZSBwdWJsaWMgaWRlbnRpZmllci4KLSAgICAgKiBAcGFyYW0gbGl0ZXJhbFN5c3RlbUlkIFRoZSBsaXRlcmFsIHN5c3RlbSBpZGVudGlmaWVyLgotICAgICAqIEBwYXJhbSBiYXNlU3lzdGVtSWQgVGhlIGJhc2Ugc3lzdGVtIGlkZW50aWZpZXIuCi0gICAgICogQHBhcmFtIGV4cGFuZGVkU3lzdGVtSWQgVGhlIGV4cGFuZGVkIHN5c3RlbSBpZGVudGlmaWVyLgotICAgICAqLwotICAgIHB1YmxpYyBYTUxFbnRpdHlEZXNjcmlwdGlvbkltcGwoU3RyaW5nIGVudGl0eU5hbWUsIFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIGxpdGVyYWxTeXN0ZW1JZCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBiYXNlU3lzdGVtSWQsIFN0cmluZyBleHBhbmRlZFN5c3RlbUlkKSB7Ci0gICAgICAgIHNldERlc2NyaXB0aW9uKGVudGl0eU5hbWUsIHB1YmxpY0lkLCBsaXRlcmFsU3lzdGVtSWQsIGJhc2VTeXN0ZW1JZCwgZXhwYW5kZWRTeXN0ZW1JZCk7Ci0gICAgfSAvLyA8aW5pdD4oU3RyaW5nLFN0cmluZyxTdHJpbmcsU3RyaW5nLFN0cmluZykKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHMgYSByZXNvdXJjZSBpZGVudGlmaWVyLgotICAgICAqCi0gICAgICogQHBhcmFtIGVudGl0eU5hbWUgVGhlIG5hbWUgb2YgdGhlIGVudGl0eS4KLSAgICAgKiBAcGFyYW0gcHVibGljSWQgVGhlIHB1YmxpYyBpZGVudGlmaWVyLgotICAgICAqIEBwYXJhbSBsaXRlcmFsU3lzdGVtSWQgVGhlIGxpdGVyYWwgc3lzdGVtIGlkZW50aWZpZXIuCi0gICAgICogQHBhcmFtIGJhc2VTeXN0ZW1JZCBUaGUgYmFzZSBzeXN0ZW0gaWRlbnRpZmllci4KLSAgICAgKiBAcGFyYW0gZXhwYW5kZWRTeXN0ZW1JZCBUaGUgZXhwYW5kZWQgc3lzdGVtIGlkZW50aWZpZXIuCi0gICAgICogQHBhcmFtIG5hbWVzcGFjZSBUaGUgbmFtZXNwYWNlLgotICAgICAqLwotICAgIHB1YmxpYyBYTUxFbnRpdHlEZXNjcmlwdGlvbkltcGwoU3RyaW5nIGVudGl0eU5hbWUsIFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIGxpdGVyYWxTeXN0ZW1JZCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBiYXNlU3lzdGVtSWQsIFN0cmluZyBleHBhbmRlZFN5c3RlbUlkLCBTdHJpbmcgbmFtZXNwYWNlKSB7Ci0gICAgICAgIHNldERlc2NyaXB0aW9uKGVudGl0eU5hbWUsIHB1YmxpY0lkLCBsaXRlcmFsU3lzdGVtSWQsIGJhc2VTeXN0ZW1JZCwgZXhwYW5kZWRTeXN0ZW1JZCwgbmFtZXNwYWNlKTsKLSAgICB9IC8vIDxpbml0PihTdHJpbmcsU3RyaW5nLFN0cmluZyxTdHJpbmcsU3RyaW5nLFN0cmluZykKLQotICAgIC8vCi0gICAgLy8gRGF0YQotICAgIC8vCi0KLSAgICAvKiogVGhlIG5hbWUgb2YgdGhlIGVudGl0eS4gKi8KLSAgICBwcm90ZWN0ZWQgU3RyaW5nIGZFbnRpdHlOYW1lOwotCi0gICAgLy8KLSAgICAvLyBQdWJsaWMgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSBuYW1lIG9mIHRoZSBlbnRpdHkuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSB0aGUgbmFtZSBvZiB0aGUgZW50aXR5Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RW50aXR5TmFtZShTdHJpbmcgbmFtZSkgewotICAgICAgICBmRW50aXR5TmFtZSA9IG5hbWU7Ci0gICAgfSAvLyBzZXRFbnRpdHlOYW1lKFN0cmluZykKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhlIGVudGl0eS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdGhlIG5hbWUgb2YgdGhlIGVudGl0eQotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0RW50aXR5TmFtZSgpIHsKLSAgICAgICAgcmV0dXJuIGZFbnRpdHlOYW1lOwotICAgIH0gLy8gZ2V0RW50aXR5TmFtZSgpOlN0cmluZwotCi0gICAgLyoqCi0gICAgICogPHA+U2V0cyB0aGUgdmFsdWVzIG9mIHRoaXMgZW50aXR5IGRlc2NyaXB0aW9uLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlbnRpdHlOYW1lIFRoZSBuYW1lIG9mIHRoZSBlbnRpdHkuCi0gICAgICogQHBhcmFtIHB1YmxpY0lkIFRoZSBwdWJsaWMgaWRlbnRpZmllci4KLSAgICAgKiBAcGFyYW0gbGl0ZXJhbFN5c3RlbUlkIFRoZSBsaXRlcmFsIHN5c3RlbSBpZGVudGlmaWVyLgotICAgICAqIEBwYXJhbSBiYXNlU3lzdGVtSWQgVGhlIGJhc2Ugc3lzdGVtIGlkZW50aWZpZXIuCi0gICAgICogQHBhcmFtIGV4cGFuZGVkU3lzdGVtSWQgVGhlIGV4cGFuZGVkIHN5c3RlbSBpZGVudGlmaWVyLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldERlc2NyaXB0aW9uKFN0cmluZyBlbnRpdHlOYW1lLCBTdHJpbmcgcHVibGljSWQsIFN0cmluZyBsaXRlcmFsU3lzdGVtSWQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGJhc2VTeXN0ZW1JZCwgU3RyaW5nIGV4cGFuZGVkU3lzdGVtSWQpIHsKLSAgICAgICAgc2V0RGVzY3JpcHRpb24oZW50aXR5TmFtZSwgcHVibGljSWQsIGxpdGVyYWxTeXN0ZW1JZCwgYmFzZVN5c3RlbUlkLCBleHBhbmRlZFN5c3RlbUlkLCBudWxsKTsKLSAgICB9IC8vIHNldERlc2NyaXB0aW9uKFN0cmluZyxTdHJpbmcsU3RyaW5nLFN0cmluZyxTdHJpbmcpCi0KLSAgICAvKioKLSAgICAgKiA8cD5TZXRzIHRoZSB2YWx1ZXMgb2YgdGhpcyBlbnRpdHkgZGVzY3JpcHRpb24uPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGVudGl0eU5hbWUgVGhlIG5hbWUgb2YgdGhlIGVudGl0eS4KLSAgICAgKiBAcGFyYW0gcHVibGljSWQgVGhlIHB1YmxpYyBpZGVudGlmaWVyLgotICAgICAqIEBwYXJhbSBsaXRlcmFsU3lzdGVtSWQgVGhlIGxpdGVyYWwgc3lzdGVtIGlkZW50aWZpZXIuCi0gICAgICogQHBhcmFtIGJhc2VTeXN0ZW1JZCBUaGUgYmFzZSBzeXN0ZW0gaWRlbnRpZmllci4KLSAgICAgKiBAcGFyYW0gZXhwYW5kZWRTeXN0ZW1JZCBUaGUgZXhwYW5kZWQgc3lzdGVtIGlkZW50aWZpZXIuCi0gICAgICogQHBhcmFtIG5hbWVzcGFjZSBUaGUgbmFtZXNwYWNlLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldERlc2NyaXB0aW9uKFN0cmluZyBlbnRpdHlOYW1lLCBTdHJpbmcgcHVibGljSWQsIFN0cmluZyBsaXRlcmFsU3lzdGVtSWQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGJhc2VTeXN0ZW1JZCwgU3RyaW5nIGV4cGFuZGVkU3lzdGVtSWQsIFN0cmluZyBuYW1lc3BhY2UpIHsKLSAgICAgICAgZkVudGl0eU5hbWUgPSBlbnRpdHlOYW1lOwotICAgICAgICBzZXRWYWx1ZXMocHVibGljSWQsIGxpdGVyYWxTeXN0ZW1JZCwgYmFzZVN5c3RlbUlkLCBleHBhbmRlZFN5c3RlbUlkLCBuYW1lc3BhY2UpOwotICAgIH0gLy8gc2V0RGVzY3JpcHRpb24oU3RyaW5nLFN0cmluZyxTdHJpbmcsU3RyaW5nLFN0cmluZyxTdHJpbmcpCi0KLSAgICAvKioKLSAgICAgKiA8cD5DbGVhcnMgdGhlIHZhbHVlcy48L3A+Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgY2xlYXIoKSB7Ci0gICAgICAgIHN1cGVyLmNsZWFyKCk7Ci0gICAgICAgIGZFbnRpdHlOYW1lID0gbnVsbDsKLSAgICB9IC8vIGNsZWFyKCkKLQotICAgIC8vCi0gICAgLy8gT2JqZWN0IG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqIFJldHVybnMgYSBoYXNoIGNvZGUgZm9yIHRoaXMgb2JqZWN0LiAqLwotICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7Ci0gICAgICAgIGludCBjb2RlID0gc3VwZXIuaGFzaENvZGUoKTsKLSAgICAgICAgaWYgKGZFbnRpdHlOYW1lICE9IG51bGwpIHsKLSAgICAgICAgICAgIGNvZGUgKz0gZkVudGl0eU5hbWUuaGFzaENvZGUoKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gY29kZTsKLSAgICB9IC8vIGhhc2hDb2RlKCk6aW50Ci0KLSAgICAvKiogUmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIG9iamVjdC4gKi8KLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgICAgICBTdHJpbmdCdWZmZXIgc3RyID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotICAgICAgICBpZiAoZkVudGl0eU5hbWUgIT0gbnVsbCkgewotICAgICAgICAgICAgc3RyLmFwcGVuZChmRW50aXR5TmFtZSk7Ci0gICAgICAgIH0KLSAgICAgICAgc3RyLmFwcGVuZCgnOicpOwotICAgICAgICBpZiAoZlB1YmxpY0lkICE9IG51bGwpIHsKLSAgICAgICAgICAgIHN0ci5hcHBlbmQoZlB1YmxpY0lkKTsKLSAgICAgICAgfQotICAgICAgICBzdHIuYXBwZW5kKCc6Jyk7Ci0gICAgICAgIGlmIChmTGl0ZXJhbFN5c3RlbUlkICE9IG51bGwpIHsKLSAgICAgICAgICAgIHN0ci5hcHBlbmQoZkxpdGVyYWxTeXN0ZW1JZCk7Ci0gICAgICAgIH0KLSAgICAgICAgc3RyLmFwcGVuZCgnOicpOwotICAgICAgICBpZiAoZkJhc2VTeXN0ZW1JZCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBzdHIuYXBwZW5kKGZCYXNlU3lzdGVtSWQpOwotICAgICAgICB9Ci0gICAgICAgIHN0ci5hcHBlbmQoJzonKTsKLSAgICAgICAgaWYgKGZFeHBhbmRlZFN5c3RlbUlkICE9IG51bGwpIHsKLSAgICAgICAgICAgIHN0ci5hcHBlbmQoZkV4cGFuZGVkU3lzdGVtSWQpOwotICAgICAgICB9Ci0gICAgICAgIHN0ci5hcHBlbmQoJzonKTsKLSAgICAgICAgaWYgKGZOYW1lc3BhY2UgIT0gbnVsbCkgewotICAgICAgICAgICAgc3RyLmFwcGVuZChmTmFtZXNwYWNlKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gc3RyLnRvU3RyaW5nKCk7Ci0gICAgfSAvLyB0b1N0cmluZygpOlN0cmluZwotCi19IC8vIFhNTEVudGl0eURlc2NyaXB0aW9uSW1wbApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9YTUxFcnJvckNvZGUuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3V0aWwvWE1MRXJyb3JDb2RlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDhkMTczYWYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9YTUxFcnJvckNvZGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDg0ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDQsMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsOwotCi0vKioKLSAqIDxwPkEgc3RydWN0dXJlIHRoYXQgcmVwcmVzZW50cyBhbiBlcnJvciBjb2RlLCBjaGFyYWN0ZXJpemVkIGJ5Ci0gKiBhIGRvbWFpbiBhbmQgYSBtZXNzYWdlIGtleS48L3A+Ci0gKgotICogQGF1dGhvciBOYWVsYSBOaXNzYXIsIElCTQotICoKLSAqLwotZmluYWwgY2xhc3MgWE1MRXJyb3JDb2RlIHsKLQotICAgIC8vCi0gICAgLy8gRGF0YQotICAgIC8vCi0KLSAgICAvKiogZXJyb3IgZG9tYWluICoqLwotICAgIHByaXZhdGUgU3RyaW5nIGZEb21haW47Ci0KLSAgICAvKiogbWVzc2FnZSBrZXkgKiovCi0gICAgcHJpdmF0ZSBTdHJpbmcgZktleTsKLQotICAgIC8qKgotICAgICAqIDxwPkNvbnN0cnVjdHMgYW4gWE1MRXJyb3JDb2RlIHdpdGggdGhlIGdpdmVuIGRvbWFpbiBhbmQga2V5LjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBkb21haW4gVGhlIGVycm9yIGRvbWFpbi4KLSAgICAgKiBAcGFyYW0ga2V5IFRoZSBrZXkgb2YgdGhlIGVycm9yIG1lc3NhZ2UuCi0gICAgICovCi0gICAgcHVibGljIFhNTEVycm9yQ29kZShTdHJpbmcgZG9tYWluLCBTdHJpbmcga2V5KSB7Ci0gICAgICAgIGZEb21haW4gPSBkb21haW47Ci0gICAgICAgIGZLZXkgPSBrZXk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+Q29udmVuaWVuY2UgbWV0aG9kIHRvIHNldCB0aGUgdmFsdWVzIG9mIGFuIFhNTEVycm9yQ29kZS48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gZG9tYWluIFRoZSBlcnJvciBkb21haW4uCi0gICAgICogQHBhcmFtIGtleSBUaGUga2V5IG9mIHRoZSBlcnJvciBtZXNzYWdlLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFZhbHVlcyhTdHJpbmcgZG9tYWluLCBTdHJpbmcga2V5KSB7Ci0gICAgICAgIGZEb21haW4gPSBkb21haW47Ci0gICAgICAgIGZLZXkgPSBrZXk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+SW5kaWNhdGVzIHdoZXRoZXIgc29tZSBvdGhlciBvYmplY3QgaXMgZXF1YWwgdG8gdGhpcyBYTUxFcnJvckNvZGUuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIG9iaiB0aGUgb2JqZWN0IHdpdGggd2hpY2ggdG8gY29tcGFyZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaikgewotICAgICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBYTUxFcnJvckNvZGUpKQotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICBYTUxFcnJvckNvZGUgZXJyID0gKFhNTEVycm9yQ29kZSkgb2JqOwotICAgICAgICByZXR1cm4gKGZEb21haW4uZXF1YWxzKGVyci5mRG9tYWluKSAmJiBmS2V5LmVxdWFscyhlcnIuZktleSkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPlJldHVybnMgYSBoYXNoIGNvZGUgdmFsdWUgZm9yIHRoaXMgWE1MRXJyb3JDb2RlLjwvcD4KLSAgICAgKgotICAgICAqIEByZXR1cm4gYSBoYXNoIGNvZGUgdmFsdWUgZm9yIHRoaXMgWE1MRXJyb3JDb2RlLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7Ci0gICAgICAgIHJldHVybiBmRG9tYWluLmhhc2hDb2RlKCkgKyBmS2V5Lmhhc2hDb2RlKCk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9YTUxHcmFtbWFyUG9vbEltcGwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3V0aWwvWE1MR3JhbW1hclBvb2xJbXBsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDI3N2QzYTMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9YTUxHcmFtbWFyUG9vbEltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDM2NiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuZ3JhbW1hcnMuR3JhbW1hcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5ncmFtbWFycy5YTUxHcmFtbWFyRGVzY3JpcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuZ3JhbW1hcnMuWE1MR3JhbW1hclBvb2w7Ci0KLS8qKgotICogU3RvcmVzIGdyYW1tYXJzIGluIGEgcG9vbCBhc3NvY2lhdGVkIHRvIGEgc3BlY2lmaWMga2V5LiBUaGlzIGdyYW1tYXIgcG9vbAotICogaW1wbGVtZW50YXRpb24gc3RvcmVzIHR3byB0eXBlcyBvZiBncmFtbWFyczogdGhvc2Uga2V5ZWQgYnkgdGhlIHJvb3QgZWxlbWVudAotICogbmFtZSwgYW5kIHRob3NlIGtleWVkIGJ5IHRoZSBncmFtbWFyJ3MgdGFyZ2V0IG5hbWVzcGFjZS4KLSAqCi0gKiBUaGlzIGlzIHRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBHcmFtbWFyUG9vbCBpbnRlcmZhY2UuCi0gKiBBcyB3ZSBtb3ZlIGZvcndhcmQsIHRoaXMgd2lsbCBiZWNvbWUgbW9yZSBmdW5jdGlvbi1yaWNoIGFuZCByb2J1c3QuCi0gKgotICogQGF1dGhvciBKZWZmcmV5IFJvZHJpZ3VleiwgSUJNCi0gKiBAYXV0aG9yIEFuZHkgQ2xhcmssIElCTQotICogQGF1dGhvciBOZWlsIEdyYWhhbSwgSUJNCi0gKiBAYXV0aG9yIFBhdmFuaSBNdWt0aGlwdWRpLCBTdW4gTWljcm9zeXN0ZW1zCi0gKiBAYXV0aG9yIE5lZXJhaiBCYWphaiwgU1VOIE1pY3Jvc3lzdGVtcwotICoKLSAqLwotcHVibGljIGNsYXNzIFhNTEdyYW1tYXJQb29sSW1wbCBpbXBsZW1lbnRzIFhNTEdyYW1tYXJQb29sIHsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RhbnRzCi0gICAgLy8KLQotICAgIC8qKiBEZWZhdWx0IHNpemUuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBpbnQgVEFCTEVfU0laRSA9IDExOwotCi0gICAgLy8KLSAgICAvLyBEYXRhCi0gICAgLy8KLQotICAgIC8qKiBHcmFtbWFycy4gKi8KLSAgICBwcm90ZWN0ZWQgRW50cnlbXSBmR3JhbW1hcnMgPSBudWxsOwotCi0gICAgLy8gd2hldGhlciB0aGlzIHBvb2wgaXMgbG9ja2VkCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZlBvb2xJc0xvY2tlZDsKLQotICAgIC8vIHRoZSBudW1iZXIgb2YgZ3JhbW1hcnMgaW4gdGhlIHBvb2wKLSAgICBwcm90ZWN0ZWQgaW50IGZHcmFtbWFyQ291bnQgPSAwOwotCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbiBERUJVRyA9IGZhbHNlIDsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKiBDb25zdHJ1Y3RzIGEgZ3JhbW1hciBwb29sIHdpdGggYSBkZWZhdWx0IG51bWJlciBvZiBidWNrZXRzLiAqLwotICAgIHB1YmxpYyBYTUxHcmFtbWFyUG9vbEltcGwoKSB7Ci0gICAgICAgIGZHcmFtbWFycyA9IG5ldyBFbnRyeVtUQUJMRV9TSVpFXTsKLSAgICAgICAgZlBvb2xJc0xvY2tlZCA9IGZhbHNlOwotICAgIH0gLy8gPGluaXQ+KCkKLQotICAgIC8qKiBDb25zdHJ1Y3RzIGEgZ3JhbW1hciBwb29sIHdpdGggYSBzcGVjaWZpZWQgbnVtYmVyIG9mIGJ1Y2tldHMuICovCi0gICAgcHVibGljIFhNTEdyYW1tYXJQb29sSW1wbChpbnQgaW5pdGlhbENhcGFjaXR5KSB7Ci0gICAgICAgIGZHcmFtbWFycyA9IG5ldyBFbnRyeVtpbml0aWFsQ2FwYWNpdHldOwotICAgICAgICBmUG9vbElzTG9ja2VkID0gZmFsc2U7Ci0gICAgfQotCi0gICAgLy8KLSAgICAvLyBYTUxHcmFtbWFyUG9vbCBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qIDxwPiBSZXRyaWV2ZSB0aGUgaW5pdGlhbCBrbm93biBzZXQgb2YgZ3JhbW1hcnMuIFRoaXMgbWV0aG9kIGlzCi0gICAgICogY2FsbGVkIGJ5IGEgdmFsaWRhdG9yIGJlZm9yZSB0aGUgdmFsaWRhdGlvbiBzdGFydHMuIFRoZSBhcHBsaWNhdGlvbgotICAgICAqIGNhbiBwcm92aWRlIGFuIGluaXRpYWwgc2V0IG9mIGdyYW1tYXJzIGF2YWlsYWJsZSB0byB0aGUgY3VycmVudAotICAgICAqIHZhbGlkYXRpb24gYXR0ZW1wdC4gPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGdyYW1tYXJUeXBlIFRoZSB0eXBlIG9mIHRoZSBncmFtbWFyLCBmcm9tIHRoZQotICAgICAqICAgICAgICAgICAgICAgICAgICA8Y29kZT5jb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5ncmFtbWFycy5YTUxHcmFtbWFyRGVzY3JpcHRpb248L2NvZGU+Ci0gICAgICogICAgICAgICAgICAgICAgICAgIGludGVyZmFjZS4KLSAgICAgKiBAcmV0dXJuICAgICAgICAgICAgVGhlIHNldCBvZiBncmFtbWFycyB0aGUgdmFsaWRhdG9yIG1heSBwdXQgaW4gaXRzICJidWNrZXQiCi0gICAgICovCi0gICAgcHVibGljIEdyYW1tYXIgW10gcmV0cmlldmVJbml0aWFsR3JhbW1hclNldCAoU3RyaW5nIGdyYW1tYXJUeXBlKSB7Ci0gICAgICAgIHN5bmNocm9uaXplZCAoZkdyYW1tYXJzKSB7Ci0gICAgICAgICAgICBpbnQgZ3JhbW1hclNpemUgPSBmR3JhbW1hcnMubGVuZ3RoIDsKLSAgICAgICAgICAgIEdyYW1tYXIgW10gdGVtcEdyYW1tYXJzID0gbmV3IEdyYW1tYXJbZkdyYW1tYXJDb3VudF07Ci0gICAgICAgICAgICBpbnQgcG9zID0gMDsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZ3JhbW1hclNpemU7IGkrKykgewotICAgICAgICAgICAgICAgIGZvciAoRW50cnkgZSA9IGZHcmFtbWFyc1tpXTsgZSAhPSBudWxsOyBlID0gZS5uZXh0KSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChlLmRlc2MuZ2V0R3JhbW1hclR5cGUoKS5lcXVhbHMoZ3JhbW1hclR5cGUpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICB0ZW1wR3JhbW1hcnNbcG9zKytdID0gZS5ncmFtbWFyOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgR3JhbW1hcltdIHRvUmV0dXJuID0gbmV3IEdyYW1tYXJbcG9zXTsKLSAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkodGVtcEdyYW1tYXJzLCAwLCB0b1JldHVybiwgMCwgcG9zKTsKLSAgICAgICAgICAgIHJldHVybiB0b1JldHVybjsKLSAgICAgICAgfQotICAgIH0gLy8gcmV0cmlldmVJbml0aWFsR3JhbW1hclNldCAoU3RyaW5nKTogR3JhbW1hcltdCi0KLSAgICAvKiA8cD4gUmV0dXJuIHRoZSBmaW5hbCBzZXQgb2YgZ3JhbW1hcnMgdGhhdCB0aGUgdmFsaWRhdG9yIGVuZGVkIHVwCi0gICAgICogd2l0aC4gVGhpcyBtZXRob2QgaXMgY2FsbGVkIGFmdGVyIHRoZSB2YWxpZGF0aW9uIGZpbmlzaGVzLiBUaGUKLSAgICAgKiBhcHBsaWNhdGlvbiBtYXkgdGhlbiBjaG9vc2UgdG8gY2FjaGUgc29tZSBvZiB0aGUgcmV0dXJuZWQgZ3JhbW1hcnMuPC9wPgotICAgICAqIDxwPkluIHRoaXMgaW1wbGVtZW50YXRpb24sIHdlIG1ha2Ugb3VyIGNob2ljZSBiYXNlZCBvbiB3aGV0aGVyIHRoaXMgb2JqZWN0Ci0gICAgICogaXMgImxvY2tlZCItLXRoYXQgaXMsIHdoZXRoZXIgdGhlIGFwcGxpY2F0aW9uIGhhcyBpbnN0cnVjdGVkCi0gICAgICogdXMgbm90IHRvIGFjY2VwdCBhbnkgbmV3IGdyYW1tYXJzLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBncmFtbWFyVHlwZSBUaGUgdHlwZSBvZiB0aGUgZ3JhbW1hcnMgYmVpbmcgcmV0dXJuZWQ7Ci0gICAgICogQHBhcmFtIGdyYW1tYXJzICAgIEFuIGFycmF5IGNvbnRhaW5pbmcgdGhlIHNldCBvZiBncmFtbWFycyBiZWluZwotICAgICAqICAgICAgICAgICAgICAgICAgICByZXR1cm5lZDsgb3JkZXIgaXMgbm90IHNpZ25pZmljYW50LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGNhY2hlR3JhbW1hcnMoU3RyaW5nIGdyYW1tYXJUeXBlLCBHcmFtbWFyW10gZ3JhbW1hcnMpIHsKLSAgICAgICAgaWYoIWZQb29sSXNMb2NrZWQpIHsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZ3JhbW1hcnMubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgICAgICBpZihERUJVRykgewotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkNBQ0hFRCBHUkFNTUFSICIgKyAoaSsxKSApIDsKLSAgICAgICAgICAgICAgICAgICAgR3JhbW1hciB0ZW1wID0gZ3JhbW1hcnNbaV0gOwotICAgICAgICAgICAgICAgICAgICAvL3ByaW50KHRlbXAuZ2V0R3JhbW1hckRlc2NyaXB0aW9uKCkpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBwdXRHcmFtbWFyKGdyYW1tYXJzW2ldKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0gLy8gY2FjaGVHcmFtbWFycyhTdHJpbmcsIEdyYW1tYXJbXSk7Ci0KLSAgICAvKiA8cD4gVGhpcyBtZXRob2QgcmVxdWVzdHMgdGhhdCB0aGUgYXBwbGljYXRpb24gcmV0cmlldmUgYSBncmFtbWFyCi0gICAgICogY29ycmVzcG9uZGluZyB0byB0aGUgZ2l2ZW4gR3JhbW1hcklkZW50aWZpZXIgZnJvbSBpdHMgY2FjaGUuCi0gICAgICogSWYgaXQgY2Fubm90IGRvIHNvIGl0IG11c3QgcmV0dXJuIG51bGw7IHRoZSBwYXJzZXIgd2lsbCB0aGVuCi0gICAgICogY2FsbCB0aGUgRW50aXR5UmVzb2x2ZXIuIDwvcD4KLSAgICAgKiA8c3Ryb25nPkFuIGFwcGxpY2F0aW9uIG11c3Qgbm90IGNhbGwgaXRzIEVudGl0eVJlc29sdmVyIGl0c2VsZgotICAgICAqIGZyb20gdGhpcyBtZXRob2Q7IHRoaXMgbWF5IHJlc3VsdCBpbiBpbmZpbml0ZSByZWN1cnNpb25zLjwvc3Ryb25nPgotICAgICAqCi0gICAgICogVGhpcyBpbXBsZW1lbnRhdGlvbiBjaG9vc2VzIHRvIHVzZSB0aGUgcm9vdCBlbGVtZW50IG5hbWUgdG8gaWRlbnRpZnkgYSBEVEQgZ3JhbW1hcgotICAgICAqIGFuZCB0aGUgdGFyZ2V0IG5hbWVzcGFjZSB0byBpZGVudGlmeSBhIFNjaGVtYSBncmFtbWFyLgotICAgICAqCi0gICAgICogQHBhcmFtIGRlc2MgVGhlIGRlc2NyaXB0aW9uIG9mIHRoZSBHcmFtbWFyIGJlaW5nIHJlcXVlc3RlZC4KLSAgICAgKiBAcmV0dXJuICAgICBUaGUgR3JhbW1hciBjb3JyZXNwb25kaW5nIHRvIHRoaXMgZGVzY3JpcHRpb24gb3IgbnVsbCBpZgotICAgICAqICAgICAgICAgICAgIG5vIHN1Y2ggR3JhbW1hciBpcyBrbm93bi4KLSAgICAgKi8KLSAgICBwdWJsaWMgR3JhbW1hciByZXRyaWV2ZUdyYW1tYXIoWE1MR3JhbW1hckRlc2NyaXB0aW9uIGRlc2MpIHsKLSAgICAgICAgaWYoREVCVUcpewotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJSRVRSSUVWSU5HIEdSQU1NQVIgRlJPTSBUSEUgQVBQTElDQVRJT04gV0lUSCBGT0xMT1dJTkcgREVTQ1JJUFRJT04gOiIpOwotICAgICAgICAgICAgLy9wcmludChkZXNjKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZ2V0R3JhbW1hcihkZXNjKTsKLSAgICB9IC8vIHJldHJpZXZlR3JhbW1hcihYTUxHcmFtbWFyRGVzY3JpcHRpb24pOiAgR3JhbW1hcgotCi0gICAgLy8KLSAgICAvLyBQdWJsaWMgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBQdXRzIHRoZSBzcGVjaWZpZWQgZ3JhbW1hciBpbnRvIHRoZSBncmFtbWFyIHBvb2wgYW5kIGFzc29jaWF0ZXMgaXQgdG8KLSAgICAgKiBpdHMgcm9vdCBlbGVtZW50IG5hbWUgb3IgaXRzIHRhcmdldCBuYW1lc3BhY2UuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZ3JhbW1hciBUaGUgR3JhbW1hci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBwdXRHcmFtbWFyKEdyYW1tYXIgZ3JhbW1hcikgewotICAgICAgICBpZighZlBvb2xJc0xvY2tlZCkgewotICAgICAgICAgICAgc3luY2hyb25pemVkIChmR3JhbW1hcnMpIHsKLSAgICAgICAgICAgICAgICBYTUxHcmFtbWFyRGVzY3JpcHRpb24gZGVzYyA9IGdyYW1tYXIuZ2V0R3JhbW1hckRlc2NyaXB0aW9uKCk7Ci0gICAgICAgICAgICAgICAgaW50IGhhc2ggPSBoYXNoQ29kZShkZXNjKTsKLSAgICAgICAgICAgICAgICBpbnQgaW5kZXggPSAoaGFzaCAmIDB4N0ZGRkZGRkYpICUgZkdyYW1tYXJzLmxlbmd0aDsKLSAgICAgICAgICAgICAgICBmb3IgKEVudHJ5IGVudHJ5ID0gZkdyYW1tYXJzW2luZGV4XTsgZW50cnkgIT0gbnVsbDsgZW50cnkgPSBlbnRyeS5uZXh0KSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChlbnRyeS5oYXNoID09IGhhc2ggJiYgZXF1YWxzKGVudHJ5LmRlc2MsIGRlc2MpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBlbnRyeS5ncmFtbWFyID0gZ3JhbW1hcjsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvLyBjcmVhdGUgYSBuZXcgZW50cnkKLSAgICAgICAgICAgICAgICBFbnRyeSBlbnRyeSA9IG5ldyBFbnRyeShoYXNoLCBkZXNjLCBncmFtbWFyLCBmR3JhbW1hcnNbaW5kZXhdKTsKLSAgICAgICAgICAgICAgICBmR3JhbW1hcnNbaW5kZXhdID0gZW50cnk7Ci0gICAgICAgICAgICAgICAgZkdyYW1tYXJDb3VudCsrOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfSAvLyBwdXRHcmFtbWFyKEdyYW1tYXIpCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBncmFtbWFyIGFzc29jaWF0ZWQgdG8gdGhlIHNwZWNpZmllZCBncmFtbWFyIGRlc2NyaXB0aW9uLgotICAgICAqIEN1cnJlbnRseSwgdGhlIHJvb3QgZWxlbWVudCBuYW1lIGlzIHVzZWQgYXMgdGhlIGtleSBmb3IgRFREIGdyYW1tYXJzCi0gICAgICogYW5kIHRoZSB0YXJnZXQgbmFtZXNwYWNlICBpcyB1c2VkIGFzIHRoZSBrZXkgZm9yIFNjaGVtYSBncmFtbWFycy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBkZXNjIFRoZSBHcmFtbWFyIERlc2NyaXB0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBHcmFtbWFyIGdldEdyYW1tYXIoWE1MR3JhbW1hckRlc2NyaXB0aW9uIGRlc2MpIHsKLSAgICAgICAgc3luY2hyb25pemVkIChmR3JhbW1hcnMpIHsKLSAgICAgICAgICAgIGludCBoYXNoID0gaGFzaENvZGUoZGVzYyk7Ci0gICAgICAgIGludCBpbmRleCA9IChoYXNoICYgMHg3RkZGRkZGRikgJSBmR3JhbW1hcnMubGVuZ3RoOwotICAgICAgICBmb3IgKEVudHJ5IGVudHJ5ID0gZkdyYW1tYXJzW2luZGV4XSA7IGVudHJ5ICE9IG51bGwgOyBlbnRyeSA9IGVudHJ5Lm5leHQpIHsKLSAgICAgICAgICAgIGlmICgoZW50cnkuaGFzaCA9PSBoYXNoKSAmJiBlcXVhbHMoZW50cnkuZGVzYywgZGVzYykpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZW50cnkuZ3JhbW1hcjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0gICAgfSAvLyBnZXRHcmFtbWFyKFhNTEdyYW1tYXJEZXNjcmlwdGlvbik6R3JhbW1hcgotCi0gICAgLyoqCi0gICAgICogUmVtb3ZlcyB0aGUgZ3JhbW1hciBhc3NvY2lhdGVkIHRvIHRoZSBzcGVjaWZpZWQgZ3JhbW1hciBkZXNjcmlwdGlvbiBmcm9tIHRoZQotICAgICAqIGdyYW1tYXIgcG9vbCBhbmQgcmV0dXJucyB0aGUgcmVtb3ZlZCBncmFtbWFyLiBDdXJyZW50bHksIHRoZSByb290IGVsZW1lbnQgbmFtZQotICAgICAqIGlzIHVzZWQgYXMgdGhlIGtleSBmb3IgRFREIGdyYW1tYXJzIGFuZCB0aGUgdGFyZ2V0IG5hbWVzcGFjZSAgaXMgdXNlZAotICAgICAqIGFzIHRoZSBrZXkgZm9yIFNjaGVtYSBncmFtbWFycy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBkZXNjIFRoZSBHcmFtbWFyIERlc2NyaXB0aW9uLgotICAgICAqIEByZXR1cm4gICAgIFRoZSByZW1vdmVkIGdyYW1tYXIuCi0gICAgICovCi0gICAgcHVibGljIEdyYW1tYXIgcmVtb3ZlR3JhbW1hcihYTUxHcmFtbWFyRGVzY3JpcHRpb24gZGVzYykgewotICAgICAgICBzeW5jaHJvbml6ZWQgKGZHcmFtbWFycykgewotICAgICAgICAgICAgaW50IGhhc2ggPSBoYXNoQ29kZShkZXNjKTsKLSAgICAgICAgaW50IGluZGV4ID0gKGhhc2ggJiAweDdGRkZGRkZGKSAlIGZHcmFtbWFycy5sZW5ndGg7Ci0gICAgICAgIGZvciAoRW50cnkgZW50cnkgPSBmR3JhbW1hcnNbaW5kZXhdLCBwcmV2ID0gbnVsbCA7IGVudHJ5ICE9IG51bGwgOyBwcmV2ID0gZW50cnksIGVudHJ5ID0gZW50cnkubmV4dCkgewotICAgICAgICAgICAgaWYgKChlbnRyeS5oYXNoID09IGhhc2gpICYmIGVxdWFscyhlbnRyeS5kZXNjLCBkZXNjKSkgewotICAgICAgICAgICAgICAgIGlmIChwcmV2ICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHByZXYubmV4dCA9IGVudHJ5Lm5leHQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBmR3JhbW1hcnNbaW5kZXhdID0gZW50cnkubmV4dDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBHcmFtbWFyIHRlbXBHcmFtbWFyID0gZW50cnkuZ3JhbW1hcjsKLSAgICAgICAgICAgICAgICBlbnRyeS5ncmFtbWFyID0gbnVsbDsKLSAgICAgICAgICAgICAgICBmR3JhbW1hckNvdW50LS07Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHRlbXBHcmFtbWFyOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgfSAvLyByZW1vdmVHcmFtbWFyKFhNTEdyYW1tYXJEZXNjcmlwdGlvbik6R3JhbW1hcgotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBncmFtbWFyIHBvb2wgY29udGFpbnMgYSBncmFtbWFyIGFzc29jaWF0ZWQKLSAgICAgKiB0byB0aGUgc3BlY2lmaWVkIGdyYW1tYXIgZGVzY3JpcHRpb24uIEN1cnJlbnRseSwgdGhlIHJvb3QgZWxlbWVudCBuYW1lCi0gICAgICogaXMgdXNlZCBhcyB0aGUga2V5IGZvciBEVEQgZ3JhbW1hcnMgYW5kIHRoZSB0YXJnZXQgbmFtZXNwYWNlICBpcyB1c2VkCi0gICAgICogYXMgdGhlIGtleSBmb3IgU2NoZW1hIGdyYW1tYXJzLgotICAgICAqCi0gICAgICogQHBhcmFtIGRlc2MgVGhlIEdyYW1tYXIgRGVzY3JpcHRpb24uCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNHcmFtbWFyKFhNTEdyYW1tYXJEZXNjcmlwdGlvbiBkZXNjKSB7Ci0gICAgICAgIHN5bmNocm9uaXplZCAoZkdyYW1tYXJzKSB7Ci0gICAgICAgICAgICBpbnQgaGFzaCA9IGhhc2hDb2RlKGRlc2MpOwotICAgICAgICBpbnQgaW5kZXggPSAoaGFzaCAmIDB4N0ZGRkZGRkYpICUgZkdyYW1tYXJzLmxlbmd0aDsKLSAgICAgICAgZm9yIChFbnRyeSBlbnRyeSA9IGZHcmFtbWFyc1tpbmRleF0gOyBlbnRyeSAhPSBudWxsIDsgZW50cnkgPSBlbnRyeS5uZXh0KSB7Ci0gICAgICAgICAgICBpZiAoKGVudHJ5Lmhhc2ggPT0gaGFzaCkgJiYgZXF1YWxzKGVudHJ5LmRlc2MsIGRlc2MpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLSAgICB9IC8vIGNvbnRhaW5zR3JhbW1hcihYTUxHcmFtbWFyRGVzY3JpcHRpb24pOmJvb2xlYW4KLQotICAgIC8qIDxwPiBTZXRzIHRoaXMgZ3JhbW1hciBwb29sIHRvIGEgImxvY2tlZCIgc3RhdGUtLWkuZS4sCi0gICAgICogbm8gbmV3IGdyYW1tYXJzIHdpbGwgYmUgYWRkZWQgdW50aWwgaXQgaXMgInVubG9ja2VkIi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBsb2NrUG9vbCgpIHsKLSAgICAgICAgZlBvb2xJc0xvY2tlZCA9IHRydWU7Ci0gICAgfSAvLyBsb2NrUG9vbCgpCi0KLSAgICAvKiA8cD4gU2V0cyB0aGlzIGdyYW1tYXIgcG9vbCB0byBhbiAidW5sb2NrZWQiIHN0YXRlLS1pLmUuLAotICAgICAqIG5ldyBncmFtbWFycyB3aWxsIGJlIGFkZGVkIHdoZW4gcHV0R3JhbW1hciBvciBjYWNoZUdyYW1tYXJzCi0gICAgICogYXJlIGNhbGxlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB1bmxvY2tQb29sKCkgewotICAgICAgICBmUG9vbElzTG9ja2VkID0gZmFsc2U7Ci0gICAgfSAvLyB1bmxvY2tQb29sKCkKLQotICAgIC8qCi0gICAgICogPHA+VGhpcyBtZXRob2QgY2xlYXJzIHRoZSBwb29sLWkuZS4sIHJlbW92ZXMgcmVmZXJlbmNlcwotICAgICAqIHRvIGFsbCB0aGUgZ3JhbW1hcnMgaW4gaXQuPC9wPgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGNsZWFyKCkgewotICAgICAgICBmb3IgKGludCBpPTA7IGk8ZkdyYW1tYXJzLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICBpZihmR3JhbW1hcnNbaV0gIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZHcmFtbWFyc1tpXS5jbGVhcigpOwotICAgICAgICAgICAgICAgIGZHcmFtbWFyc1tpXSA9IG51bGw7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZkdyYW1tYXJDb3VudCA9IDA7Ci0gICAgfSAvLyBjbGVhcigpCi0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBjaGVja3Mgd2hldGhlciB0d28gZ3JhbW1hcnMgYXJlIHRoZSBzYW1lLiBDdXJyZW50bHksIHdlIGNvbXBhcmUKLSAgICAgKiB0aGUgcm9vdCBlbGVtZW50IG5hbWVzIGZvciBEVEQgZ3JhbW1hcnMgYW5kIHRoZSB0YXJnZXQgbmFtZXNwYWNlcyBmb3IgU2NoZW1hIGdyYW1tYXJzLgotICAgICAqIFRoZSBhcHBsaWNhdGlvbiBjYW4gb3ZlcnJpZGUgdGhpcyBiZWhhdmlvdXIgYW5kIGFkZCBpdHMgb3duIGxvZ2ljLgotICAgICAqCi0gICAgICogQHBhcmFtIGRlc2MxIFRoZSBncmFtbWFyIGRlc2NyaXB0aW9uCi0gICAgICogQHBhcmFtIGRlc2MyIFRoZSBncmFtbWFyIGRlc2NyaXB0aW9uIG9mIHRoZSBncmFtbWFyIHRvIGJlIGNvbXBhcmVkIHRvCi0gICAgICogQHJldHVybiAgICAgIFRydWUgaWYgdGhlIGdyYW1tYXJzIGFyZSBlcXVhbCwgb3RoZXJ3aXNlIGZhbHNlCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKFhNTEdyYW1tYXJEZXNjcmlwdGlvbiBkZXNjMSwgWE1MR3JhbW1hckRlc2NyaXB0aW9uIGRlc2MyKSB7Ci0gICAgICAgIHJldHVybiBkZXNjMS5lcXVhbHMoZGVzYzIpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIGhhc2ggY29kZSB2YWx1ZSBmb3IgdGhlIGdpdmVuIGdyYW1tYXIgZGVzY3JpcHRpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZGVzYyBUaGUgZ3JhbW1hciBkZXNjcmlwdGlvbgotICAgICAqIEByZXR1cm4gICAgIFRoZSBoYXNoIGNvZGUgdmFsdWUKLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGhhc2hDb2RlKFhNTEdyYW1tYXJEZXNjcmlwdGlvbiBkZXNjKSB7Ci0gICAgICAgIHJldHVybiBkZXNjLmhhc2hDb2RlKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBjbGFzcyBpcyBhIGdyYW1tYXIgcG9vbCBlbnRyeS4gRWFjaCBlbnRyeSBhY3RzIGFzIGEgbm9kZQotICAgICAqIGluIGEgbGlua2VkIGxpc3QuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBjbGFzcyBFbnRyeSB7Ci0gICAgICAgIHB1YmxpYyBpbnQgaGFzaDsKLSAgICAgICAgcHVibGljIFhNTEdyYW1tYXJEZXNjcmlwdGlvbiBkZXNjOwotICAgICAgICBwdWJsaWMgR3JhbW1hciBncmFtbWFyOwotICAgICAgICBwdWJsaWMgRW50cnkgbmV4dDsKLQotICAgICAgICBwcm90ZWN0ZWQgRW50cnkoaW50IGhhc2gsIFhNTEdyYW1tYXJEZXNjcmlwdGlvbiBkZXNjLCBHcmFtbWFyIGdyYW1tYXIsIEVudHJ5IG5leHQpIHsKLSAgICAgICAgICAgIHRoaXMuaGFzaCA9IGhhc2g7Ci0gICAgICAgICAgICB0aGlzLmRlc2MgPSBkZXNjOwotICAgICAgICAgICAgdGhpcy5ncmFtbWFyID0gZ3JhbW1hcjsKLSAgICAgICAgICAgIHRoaXMubmV4dCA9IG5leHQ7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBjbGVhciB0aGlzIGVudHJ5OyB1c2VmdWwgdG8gcHJvbW90ZSBnYXJiYWdlIGNvbGxlY3Rpb24KLSAgICAgICAgLy8gc2luY2UgcmVkdWNlcyByZWZlcmVuY2UgY291bnQgb2Ygb2JqZWN0cyB0byBiZSBkZXN0cm95ZWQKLSAgICAgICAgcHJvdGVjdGVkIHZvaWQgY2xlYXIgKCkgewotICAgICAgICAgICAgZGVzYyA9IG51bGw7Ci0gICAgICAgICAgICBncmFtbWFyID0gbnVsbDsKLSAgICAgICAgICAgIGlmKG5leHQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIG5leHQuY2xlYXIoKTsKLSAgICAgICAgICAgICAgICBuZXh0ID0gbnVsbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSAvLyBjbGVhcigpCi0gICAgfSAvLyBjbGFzcyBFbnRyeQotCi0gICAgLyogRm9yIERURCBidWlsZCB3ZSBjYW4ndCBpbXBvcnQgaGVyZSBYU0REZXNjcmlwdGlvbi4gVGh1cywgdGhpcyBtZXRob2QgaXMgY29tbWVudGVkIG91dC4uICovCi0gICAgLyogcHVibGljIHZvaWQgcHJpbnQoWE1MR3JhbW1hckRlc2NyaXB0aW9uIGRlc2NyaXB0aW9uKXsKLSAgICAgICAgaWYoZGVzY3JpcHRpb24uZ2V0R3JhbW1hclR5cGUoKS5lcXVhbHMoWE1MR3JhbW1hckRlc2NyaXB0aW9uLlhNTF9EVEQpKXsKLQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYoZGVzY3JpcHRpb24uZ2V0R3JhbW1hclR5cGUoKS5lcXVhbHMoWE1MR3JhbW1hckRlc2NyaXB0aW9uLlhNTF9TQ0hFTUEpKXsKLSAgICAgICAgICAgIFhTRERlc2NyaXB0aW9uIHNjaGVtYSA9IChYU0REZXNjcmlwdGlvbilkZXNjcmlwdGlvbiA7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkNvbnRleHQgPSAiICsgc2NoZW1hLmdldENvbnRleHRUeXBlKCkpOwotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJUYXJnZXROYW1lc3BhY2UgPSAiICsgc2NoZW1hLmdldFRhcmdldE5hbWVzcGFjZSgpKTsKLSAgICAgICAgICAgIFN0cmluZyBbXSB0ZW1wID0gc2NoZW1hLmdldExvY2F0aW9uSGludHMoKTsKLQotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDAgOyAodGVtcCAhPSBudWxsICYmIGkgPCB0ZW1wLmxlbmd0aCkgOyBpKyspewotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiTG9jYXRpb25IaW50ICIgKyBpICsgIiA9ICIrIHRlbXBbaV0pOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlRyaWdnZXJpbmcgQ29tcG9uZW50ID0gIiArIHNjaGVtYS5nZXRUcmlnZ2VyaW5nQ29tcG9uZW50KCkpOwotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJFbmNsb3NpbmdFbGVtZW50TmFtZSA9IiArIHNjaGVtYS5nZXRFbmNsb3NpbmdFbGVtZW50TmFtZSgpKTsKLQotICAgICAgICB9Ci0KLSAgICB9Ly9wcmludAotICAgICovCi0KLX0gLy8gY2xhc3MgWE1MR3JhbW1hclBvb2xJbXBsCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL1hNTElucHV0U291cmNlQWRhcHRvci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9YTUxJbnB1dFNvdXJjZUFkYXB0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNzM1MjYyNS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL1hNTElucHV0U291cmNlQWRhcHRvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTA3ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDAtMjAwMiBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhlcmNlcyIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgSW50ZXJuYXRpb25hbAotICogQnVzaW5lc3MgTWFjaGluZXMsIEluYy4sIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWw7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlNvdXJjZTsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5YTUxFbnRpdHlNYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5VUkkuTWFsZm9ybWVkVVJJRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxJbnB1dFNvdXJjZTsKLQotLyoqCi0gKiB7QGxpbmsgU291cmNlfSB0aGF0IHJlcHJlc2VudHMgYW4ge0BsaW5rIFhNTElucHV0U291cmNlfS4KLSAqCi0gKiA8cD4KLSAqIElkZWFsbHksIHdlIHNob3VsZCBiZSBhYmxlIHRvIGhhdmUge0BsaW5rIFhNTElucHV0U291cmNlfQotICogZGVyaXZlIGZyb20ge0BsaW5rIFNvdXJjZX0sIGJ1dCB0aGUgd2F5Ci0gKiB0aGUge0BsaW5rIFhNTElucHV0U291cmNlI2dldFN5c3RlbUlkKCl9IG1ldGhvZCB3b3JrcyBpcwotICogZGlmZmVyZW50IGZyb20gdGhlIHdheSB7QGxpbmsgU291cmNlI2dldFN5c3RlbUlkKCl9IG1ldGhvZCB3b3Jrcy4KLSAqCi0gKiA8cD4KLSAqIEluIGEgbG9uZyBydW4sIHdlIHNob3VsZCBtYWtlIHRoZW0gY29uc2lzdGVudCBzbyB0aGF0IHdlIGNhbgotICogZ2V0IHJpZCBvZiB0aGlzIGF3a3dhcmQgYWRhcHRvciBjbGFzcy4KLSAqCi0gKiBAYXV0aG9yCi0gKiAgICAgS29oc3VrZSBLYXdhZ3VjaGkgKGtvaHN1a2Uua2F3YWd1Y2hpQHN1bi5jb20pCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBYTUxJbnB1dFNvdXJjZUFkYXB0b3IgaW1wbGVtZW50cyBTb3VyY2UgewotICAgIC8qKgotICAgICAqIHRoZSBhY3R1YWwgc291cmNlIGluZm9ybWF0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBmaW5hbCBYTUxJbnB1dFNvdXJjZSBmU291cmNlOwotCi0gICAgcHVibGljIFhNTElucHV0U291cmNlQWRhcHRvciggWE1MSW5wdXRTb3VyY2UgY29yZSApIHsKLSAgICAgICAgZlNvdXJjZSA9IGNvcmU7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0U3lzdGVtSWQoU3RyaW5nIHN5c3RlbUlkKSB7Ci0gICAgICAgIGZTb3VyY2Uuc2V0U3lzdGVtSWQoc3lzdGVtSWQpOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3lzdGVtSWQoKSB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICByZXR1cm4gWE1MRW50aXR5TWFuYWdlci5leHBhbmRTeXN0ZW1JZCgKLSAgICAgICAgICAgICAgICAgICAgZlNvdXJjZS5nZXRTeXN0ZW1JZCgpLCBmU291cmNlLmdldEJhc2VTeXN0ZW1JZCgpLCBmYWxzZSk7Ci0gICAgICAgIH0gY2F0Y2ggKE1hbGZvcm1lZFVSSUV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICByZXR1cm4gZlNvdXJjZS5nZXRTeXN0ZW1JZCgpOwotICAgICAgICB9Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9YTUxSZXNvdXJjZUlkZW50aWZpZXJJbXBsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL1hNTFJlc291cmNlSWRlbnRpZmllckltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDQ5ZDQxMi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL1hNTFJlc291cmNlSWRlbnRpZmllckltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIzMCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAyLCAyMDAzLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbDsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTFJlc291cmNlSWRlbnRpZmllcjsKLQotLyoqCi0gKiBUaGUgWE1MUmVzb3VyY2VJZGVudGlmaWVySW1wbCBjbGFzcyBpcyBhbiBpbXBsZW1lbnRhdGlvbiBvZiB0aGUKLSAqIFhNTFJlc291cmNlSWRlbnRpZmllciBpbnRlcmZhY2Ugd2hpY2ggZGVmaW5lcyB0aGUgbG9jYXRpb24gaWRlbnRpdHkKLSAqIG9mIGEgcmVzb3VyY2UuCi0gKgotICogQGF1dGhvciBBbmR5IENsYXJrCi0gKgotICovCi1wdWJsaWMgY2xhc3MgWE1MUmVzb3VyY2VJZGVudGlmaWVySW1wbAotICAgIGltcGxlbWVudHMgWE1MUmVzb3VyY2VJZGVudGlmaWVyIHsKLQotICAgIC8vCi0gICAgLy8gRGF0YQotICAgIC8vCi0KLSAgICAvKiogVGhlIHB1YmxpYyBpZGVudGlmaWVyLiAqLwotICAgIHByb3RlY3RlZCBTdHJpbmcgZlB1YmxpY0lkOwotCi0gICAgLyoqIFRoZSBsaXRlcmFsIHN5c3RlbSBpZGVudGlmaWVyLiAqLwotICAgIHByb3RlY3RlZCBTdHJpbmcgZkxpdGVyYWxTeXN0ZW1JZDsKLQotICAgIC8qKiBUaGUgYmFzZSBzeXN0ZW0gaWRlbnRpZmllci4gKi8KLSAgICBwcm90ZWN0ZWQgU3RyaW5nIGZCYXNlU3lzdGVtSWQ7Ci0KLSAgICAvKiogVGhlIGV4cGFuZGVkIHN5c3RlbSBpZGVudGlmaWVyLiAqLwotICAgIHByb3RlY3RlZCBTdHJpbmcgZkV4cGFuZGVkU3lzdGVtSWQ7Ci0KLSAgICAvKiogVGhlIG5hbWVzcGFjZSBvZiB0aGUgcmVzb3VyY2UuICovCi0gICAgcHJvdGVjdGVkIFN0cmluZyBmTmFtZXNwYWNlOwotCi0gICAgLy8KLSAgICAvLyBDb25zdHJ1Y3RvcnMKLSAgICAvLwotCi0gICAgLyoqIENvbnN0cnVjdHMgYW4gZW1wdHkgcmVzb3VyY2UgaWRlbnRpZmllci4gKi8KLSAgICBwdWJsaWMgWE1MUmVzb3VyY2VJZGVudGlmaWVySW1wbCgpIHt9IC8vIDxpbml0PigpCi0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RzIGEgcmVzb3VyY2UgaWRlbnRpZmllci4KLSAgICAgKgotICAgICAqIEBwYXJhbSBwdWJsaWNJZCBUaGUgcHVibGljIGlkZW50aWZpZXIuCi0gICAgICogQHBhcmFtIGxpdGVyYWxTeXN0ZW1JZCBUaGUgbGl0ZXJhbCBzeXN0ZW0gaWRlbnRpZmllci4KLSAgICAgKiBAcGFyYW0gYmFzZVN5c3RlbUlkIFRoZSBiYXNlIHN5c3RlbSBpZGVudGlmaWVyLgotICAgICAqIEBwYXJhbSBleHBhbmRlZFN5c3RlbUlkIFRoZSBleHBhbmRlZCBzeXN0ZW0gaWRlbnRpZmllci4KLSAgICAgKi8KLSAgICBwdWJsaWMgWE1MUmVzb3VyY2VJZGVudGlmaWVySW1wbChTdHJpbmcgcHVibGljSWQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGxpdGVyYWxTeXN0ZW1JZCwgU3RyaW5nIGJhc2VTeXN0ZW1JZCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgZXhwYW5kZWRTeXN0ZW1JZCkgewotICAgICAgICBzZXRWYWx1ZXMocHVibGljSWQsIGxpdGVyYWxTeXN0ZW1JZCwgYmFzZVN5c3RlbUlkLAotICAgICAgICAgICAgICAgICAgZXhwYW5kZWRTeXN0ZW1JZCwgbnVsbCk7Ci0gICAgfSAvLyA8aW5pdD4oU3RyaW5nLFN0cmluZyxTdHJpbmcsU3RyaW5nKQotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0cyBhIHJlc291cmNlIGlkZW50aWZpZXIuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcHVibGljSWQgVGhlIHB1YmxpYyBpZGVudGlmaWVyLgotICAgICAqIEBwYXJhbSBsaXRlcmFsU3lzdGVtSWQgVGhlIGxpdGVyYWwgc3lzdGVtIGlkZW50aWZpZXIuCi0gICAgICogQHBhcmFtIGJhc2VTeXN0ZW1JZCBUaGUgYmFzZSBzeXN0ZW0gaWRlbnRpZmllci4KLSAgICAgKiBAcGFyYW0gZXhwYW5kZWRTeXN0ZW1JZCBUaGUgZXhwYW5kZWQgc3lzdGVtIGlkZW50aWZpZXIuCi0gICAgICogQHBhcmFtIG5hbWVzcGFjZSBUaGUgbmFtZXNwYWNlLgotICAgICAqLwotICAgIHB1YmxpYyBYTUxSZXNvdXJjZUlkZW50aWZpZXJJbXBsKFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIGxpdGVyYWxTeXN0ZW1JZCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgYmFzZVN5c3RlbUlkLCBTdHJpbmcgZXhwYW5kZWRTeXN0ZW1JZCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbmFtZXNwYWNlKSB7Ci0gICAgICAgIHNldFZhbHVlcyhwdWJsaWNJZCwgbGl0ZXJhbFN5c3RlbUlkLCBiYXNlU3lzdGVtSWQsCi0gICAgICAgICAgICAgICAgICBleHBhbmRlZFN5c3RlbUlkLCBuYW1lc3BhY2UpOwotICAgIH0gLy8gPGluaXQ+KFN0cmluZyxTdHJpbmcsU3RyaW5nLFN0cmluZyxTdHJpbmcpCi0KLSAgICAvLwotICAgIC8vIFB1YmxpYyBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKiBTZXRzIHRoZSB2YWx1ZXMgb2YgdGhlIHJlc291cmNlIGlkZW50aWZpZXIuICovCi0gICAgcHVibGljIHZvaWQgc2V0VmFsdWVzKFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIGxpdGVyYWxTeXN0ZW1JZCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGJhc2VTeXN0ZW1JZCwgU3RyaW5nIGV4cGFuZGVkU3lzdGVtSWQpIHsKLSAgICAgICAgc2V0VmFsdWVzKHB1YmxpY0lkLCBsaXRlcmFsU3lzdGVtSWQsIGJhc2VTeXN0ZW1JZCwKLSAgICAgICAgICAgICAgICAgIGV4cGFuZGVkU3lzdGVtSWQsIG51bGwpOwotICAgIH0gLy8gc2V0VmFsdWVzKFN0cmluZyxTdHJpbmcsU3RyaW5nLFN0cmluZykKLQotICAgIC8qKiBTZXRzIHRoZSB2YWx1ZXMgb2YgdGhlIHJlc291cmNlIGlkZW50aWZpZXIuICovCi0gICAgcHVibGljIHZvaWQgc2V0VmFsdWVzKFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIGxpdGVyYWxTeXN0ZW1JZCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGJhc2VTeXN0ZW1JZCwgU3RyaW5nIGV4cGFuZGVkU3lzdGVtSWQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBuYW1lc3BhY2UpIHsKLSAgICAgICAgZlB1YmxpY0lkID0gcHVibGljSWQ7Ci0gICAgICAgIGZMaXRlcmFsU3lzdGVtSWQgPSBsaXRlcmFsU3lzdGVtSWQ7Ci0gICAgICAgIGZCYXNlU3lzdGVtSWQgPSBiYXNlU3lzdGVtSWQ7Ci0gICAgICAgIGZFeHBhbmRlZFN5c3RlbUlkID0gZXhwYW5kZWRTeXN0ZW1JZDsKLSAgICAgICAgZk5hbWVzcGFjZSA9IG5hbWVzcGFjZTsKLSAgICB9IC8vIHNldFZhbHVlcyhTdHJpbmcsU3RyaW5nLFN0cmluZyxTdHJpbmcsU3RyaW5nKQotCi0gICAgLyoqIENsZWFycyB0aGUgdmFsdWVzLiAqLwotICAgIHB1YmxpYyB2b2lkIGNsZWFyKCkgewotICAgICAgICBmUHVibGljSWQgPSBudWxsOwotICAgICAgICBmTGl0ZXJhbFN5c3RlbUlkID0gbnVsbDsKLSAgICAgICAgZkJhc2VTeXN0ZW1JZCA9IG51bGw7Ci0gICAgICAgIGZFeHBhbmRlZFN5c3RlbUlkID0gbnVsbDsKLSAgICAgICAgZk5hbWVzcGFjZSA9IG51bGw7Ci0gICAgfSAvLyBjbGVhcigpCi0KLSAgICAvKiogU2V0cyB0aGUgcHVibGljIGlkZW50aWZpZXIuICovCi0gICAgcHVibGljIHZvaWQgc2V0UHVibGljSWQoU3RyaW5nIHB1YmxpY0lkKSB7Ci0gICAgICAgIGZQdWJsaWNJZCA9IHB1YmxpY0lkOwotICAgIH0gLy8gc2V0UHVibGljSWQoU3RyaW5nKQotCi0gICAgLyoqIFNldHMgdGhlIGxpdGVyYWwgc3lzdGVtIGlkZW50aWZpZXIuICovCi0gICAgcHVibGljIHZvaWQgc2V0TGl0ZXJhbFN5c3RlbUlkKFN0cmluZyBsaXRlcmFsU3lzdGVtSWQpIHsKLSAgICAgICAgZkxpdGVyYWxTeXN0ZW1JZCA9IGxpdGVyYWxTeXN0ZW1JZDsKLSAgICB9IC8vIHNldExpdGVyYWxTeXN0ZW1JZChTdHJpbmcpCi0KLSAgICAvKiogU2V0cyB0aGUgYmFzZSBzeXN0ZW0gaWRlbnRpZmllci4gKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRCYXNlU3lzdGVtSWQoU3RyaW5nIGJhc2VTeXN0ZW1JZCkgewotICAgICAgICBmQmFzZVN5c3RlbUlkID0gYmFzZVN5c3RlbUlkOwotICAgIH0gLy8gc2V0QmFzZVN5c3RlbUlkKFN0cmluZykKLQotICAgIC8qKiBTZXRzIHRoZSBleHBhbmRlZCBzeXN0ZW0gaWRlbnRpZmllci4gKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRFeHBhbmRlZFN5c3RlbUlkKFN0cmluZyBleHBhbmRlZFN5c3RlbUlkKSB7Ci0gICAgICAgIGZFeHBhbmRlZFN5c3RlbUlkID0gZXhwYW5kZWRTeXN0ZW1JZDsKLSAgICB9IC8vIHNldEV4cGFuZGVkU3lzdGVtSWQoU3RyaW5nKQotCi0gICAgLyoqIFNldHMgdGhlIG5hbWVzcGFjZSBvZiB0aGUgcmVzb3VyY2UuICovCi0gICAgcHVibGljIHZvaWQgc2V0TmFtZXNwYWNlKFN0cmluZyBuYW1lc3BhY2UpIHsKLSAgICAgICAgZk5hbWVzcGFjZSA9IG5hbWVzcGFjZTsKLSAgICB9IC8vIHNldE5hbWVzcGFjZShTdHJpbmcpCi0KLSAgICAvLwotICAgIC8vIFhNTFJlc291cmNlSWRlbnRpZmllciBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKiBSZXR1cm5zIHRoZSBwdWJsaWMgaWRlbnRpZmllci4gKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFB1YmxpY0lkKCkgewotICAgICAgICByZXR1cm4gZlB1YmxpY0lkOwotICAgIH0gLy8gZ2V0UHVibGljSWQoKTpTdHJpbmcKLQotICAgIC8qKiBSZXR1cm5zIHRoZSBsaXRlcmFsIHN5c3RlbSBpZGVudGlmaWVyLiAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TGl0ZXJhbFN5c3RlbUlkKCkgewotICAgICAgICByZXR1cm4gZkxpdGVyYWxTeXN0ZW1JZDsKLSAgICB9IC8vIGdldExpdGVyYWxTeXN0ZW1JZCgpOlN0cmluZwotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgYmFzZSBVUkkgYWdhaW5zdCB3aGljaCB0aGUgbGl0ZXJhbCBTeXN0ZW1JZCBpcyB0byBiZSByZXNvbHZlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEJhc2VTeXN0ZW1JZCgpIHsKLSAgICAgICAgcmV0dXJuIGZCYXNlU3lzdGVtSWQ7Ci0gICAgfSAvLyBnZXRCYXNlU3lzdGVtSWQoKTpTdHJpbmcKLQotICAgIC8qKiBSZXR1cm5zIHRoZSBleHBhbmRlZCBzeXN0ZW0gaWRlbnRpZmllci4gKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEV4cGFuZGVkU3lzdGVtSWQoKSB7Ci0gICAgICAgIHJldHVybiBmRXhwYW5kZWRTeXN0ZW1JZDsKLSAgICB9IC8vIGdldEV4cGFuZGVkU3lzdGVtSWQoKTpTdHJpbmcKLQotICAgIC8qKiBSZXR1cm5zIHRoZSBuYW1lc3BhY2Ugb2YgdGhlIHJlc291cmNlLiAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZXNwYWNlKCkgewotICAgICAgICByZXR1cm4gZk5hbWVzcGFjZTsKLSAgICB9IC8vIGdldE5hbWVzcGFjZSgpOlN0cmluZwotCi0gICAgLy8KLSAgICAvLyBPYmplY3QgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKiogUmV0dXJucyBhIGhhc2ggY29kZSBmb3IgdGhpcyBvYmplY3QuICovCi0gICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKLSAgICAgICAgaW50IGNvZGUgPSAwOwotICAgICAgICBpZiAoZlB1YmxpY0lkICE9IG51bGwpIHsKLSAgICAgICAgICAgIGNvZGUgKz0gZlB1YmxpY0lkLmhhc2hDb2RlKCk7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGZMaXRlcmFsU3lzdGVtSWQgIT0gbnVsbCkgewotICAgICAgICAgICAgY29kZSArPSBmTGl0ZXJhbFN5c3RlbUlkLmhhc2hDb2RlKCk7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGZCYXNlU3lzdGVtSWQgIT0gbnVsbCkgewotICAgICAgICAgICAgY29kZSArPSBmQmFzZVN5c3RlbUlkLmhhc2hDb2RlKCk7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGZFeHBhbmRlZFN5c3RlbUlkICE9IG51bGwpIHsKLSAgICAgICAgICAgIGNvZGUgKz0gZkV4cGFuZGVkU3lzdGVtSWQuaGFzaENvZGUoKTsKLSAgICAgICAgfQotICAgICAgICBpZiAoZk5hbWVzcGFjZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBjb2RlICs9IGZOYW1lc3BhY2UuaGFzaENvZGUoKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gY29kZTsKLSAgICB9IC8vIGhhc2hDb2RlKCk6aW50Ci0KLSAgICAvKiogUmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIG9iamVjdC4gKi8KLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgICAgICBTdHJpbmdCdWZmZXIgc3RyID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotICAgICAgICBpZiAoZlB1YmxpY0lkICE9IG51bGwpIHsKLSAgICAgICAgICAgIHN0ci5hcHBlbmQoZlB1YmxpY0lkKTsKLSAgICAgICAgfQotICAgICAgICBzdHIuYXBwZW5kKCc6Jyk7Ci0gICAgICAgIGlmIChmTGl0ZXJhbFN5c3RlbUlkICE9IG51bGwpIHsKLSAgICAgICAgICAgIHN0ci5hcHBlbmQoZkxpdGVyYWxTeXN0ZW1JZCk7Ci0gICAgICAgIH0KLSAgICAgICAgc3RyLmFwcGVuZCgnOicpOwotICAgICAgICBpZiAoZkJhc2VTeXN0ZW1JZCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBzdHIuYXBwZW5kKGZCYXNlU3lzdGVtSWQpOwotICAgICAgICB9Ci0gICAgICAgIHN0ci5hcHBlbmQoJzonKTsKLSAgICAgICAgaWYgKGZFeHBhbmRlZFN5c3RlbUlkICE9IG51bGwpIHsKLSAgICAgICAgICAgIHN0ci5hcHBlbmQoZkV4cGFuZGVkU3lzdGVtSWQpOwotICAgICAgICB9Ci0gICAgICAgIHN0ci5hcHBlbmQoJzonKTsKLSAgICAgICAgaWYgKGZOYW1lc3BhY2UgIT0gbnVsbCkgewotICAgICAgICAgICAgc3RyLmFwcGVuZChmTmFtZXNwYWNlKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gc3RyLnRvU3RyaW5nKCk7Ci0gICAgfSAvLyB0b1N0cmluZygpOlN0cmluZwotCi19IC8vIGNsYXNzIFhNTFJlc291cmNlSWRlbnRpZmllckltcGwKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3V0aWwvWE1MU3RyaW5nQnVmZmVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL1hNTFN0cmluZ0J1ZmZlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxN2Y0NjcxLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3V0aWwvWE1MU3RyaW5nQnVmZmVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMzAgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OS0yMDAyIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGVyY2VzIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBJbnRlcm5hdGlvbmFsCi0gKiBCdXNpbmVzcyBNYWNoaW5lcywgSW5jLiwgaHR0cDovL3d3dy5hcGFjaGUub3JnLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MU3RyaW5nOwotCi0vKioKLSAqIFhNTFN0cmluZyBpcyBhIHN0cnVjdHVyZSB1c2VkIHRvIHBhc3MgY2hhcmFjdGVyIGFycmF5cy4gSG93ZXZlciwKLSAqIFhNTFN0cmluZ0J1ZmZlciBpcyBhIGJ1ZmZlciBpbiB3aGljaCBjaGFyYWN0ZXJzIGNhbiBiZSBhcHBlbmRlZAotICogYW5kIGV4dGVuZHMgWE1MU3RyaW5nIHNvIHRoYXQgaXQgY2FuIGJlIHBhc3NlZCB0byBtZXRob2RzCi0gKiBleHBlY3RpbmcgYW4gWE1MU3RyaW5nIG9iamVjdC4gVGhpcyBpcyBhIHNhZmUgb3BlcmF0aW9uIGJlY2F1c2UKLSAqIGl0IGlzIGFzc3VtZWQgdGhhdCBhbnkgY2FsbGVlIHdpbGwgPHN0cm9uZz5ub3Q8L3N0cm9uZz4gbW9kaWZ5Ci0gKiB0aGUgY29udGVudHMgb2YgdGhlIFhNTFN0cmluZyBzdHJ1Y3R1cmUuCi0gKiA8cD4KLSAqIFRoZSBjb250ZW50cyBvZiB0aGUgc3RyaW5nIGFyZSBtYW5hZ2VkIGJ5IHRoZSBzdHJpbmcgYnVmZmVyLiBBcwotICogY2hhcmFjdGVycyBhcmUgYXBwZW5kZWQsIHRoZSBzdHJpbmcgYnVmZmVyIHdpbGwgZ3JvdyBhcyBuZWVkZWQuCi0gKiA8cD4KLSAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gTmV2ZXIgc2V0IHRoZSA8Y29kZT5jaDwvY29kZT4sCi0gKiA8Y29kZT5vZmZzZXQ8L2NvZGU+LCBhbmQgPGNvZGU+bGVuZ3RoPC9jb2RlPiBmaWVsZHMgZGlyZWN0bHkuCi0gKiBUaGVzZSBmaWVsZHMgYXJlIG1hbmFnZWQgYnkgdGhlIHN0cmluZyBidWZmZXIuIEluIG9yZGVyIHRvIHJlc2V0Ci0gKiB0aGUgYnVmZmVyLCBjYWxsIDxjb2RlPmNsZWFyKCk8L2NvZGU+LgotICoKLSAqIEBhdXRob3IgQW5keSBDbGFyaywgSUJNCi0gKiBAYXV0aG9yIEVyaWMgWWUsIElCTQotICoKLSAqLwotcHVibGljIGNsYXNzIFhNTFN0cmluZ0J1ZmZlcgotZXh0ZW5kcyBYTUxTdHJpbmcgewotCi0gICAgLy8KLSAgICAvLyBDb25zdGFudHMKLSAgICAvLwotCi0KLSAgICAvKiogRGVmYXVsdCBidWZmZXIgc2l6ZSAoMzIpLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFRkFVTFRfU0laRSA9IDMyOwotCi0gICAgLy8KLSAgICAvLyBEYXRhCi0gICAgLy8KLQotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqCi0gICAgICovCi0gICAgcHVibGljIFhNTFN0cmluZ0J1ZmZlcigpIHsKLSAgICAgICAgdGhpcyhERUZBVUxUX1NJWkUpOwotICAgIH0gLy8gPGluaXQ+KCkKLQotICAgIC8qKgotICAgICAqCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc2l6ZQotICAgICAqLwotICAgIHB1YmxpYyBYTUxTdHJpbmdCdWZmZXIoaW50IHNpemUpIHsKLSAgICAgICAgY2ggPSBuZXcgY2hhcltzaXplXTsKLSAgICB9IC8vIDxpbml0PihpbnQpCi0KLSAgICAvKiogQ29uc3RydWN0cyBhIHN0cmluZyBidWZmZXIgZnJvbSBhIGNoYXIuICovCi0gICAgcHVibGljIFhNTFN0cmluZ0J1ZmZlcihjaGFyIGMpIHsKLSAgICAgICAgdGhpcygxKTsKLSAgICAgICAgYXBwZW5kKGMpOwotICAgIH0gLy8gPGluaXQ+KGNoYXIpCi0KLSAgICAvKiogQ29uc3RydWN0cyBhIHN0cmluZyBidWZmZXIgZnJvbSBhIFN0cmluZy4gKi8KLSAgICBwdWJsaWMgWE1MU3RyaW5nQnVmZmVyKFN0cmluZyBzKSB7Ci0gICAgICAgIHRoaXMocy5sZW5ndGgoKSk7Ci0gICAgICAgIGFwcGVuZChzKTsKLSAgICB9IC8vIDxpbml0PihTdHJpbmcpCi0KLSAgICAvKiogQ29uc3RydWN0cyBhIHN0cmluZyBidWZmZXIgZnJvbSB0aGUgc3BlY2lmaWVkIGNoYXJhY3RlciBhcnJheS4gKi8KLSAgICBwdWJsaWMgWE1MU3RyaW5nQnVmZmVyKGNoYXJbXSBjaCwgaW50IG9mZnNldCwgaW50IGxlbmd0aCkgewotICAgICAgICB0aGlzKGxlbmd0aCk7Ci0gICAgICAgIGFwcGVuZChjaCwgb2Zmc2V0LCBsZW5ndGgpOwotICAgIH0gLy8gPGluaXQ+KGNoYXJbXSxpbnQsaW50KQotCi0gICAgLyoqIENvbnN0cnVjdHMgYSBzdHJpbmcgYnVmZmVyIGZyb20gdGhlIHNwZWNpZmllZCBYTUxTdHJpbmcuICovCi0gICAgcHVibGljIFhNTFN0cmluZ0J1ZmZlcihYTUxTdHJpbmcgcykgewotICAgICAgICB0aGlzKHMubGVuZ3RoKTsKLSAgICAgICAgYXBwZW5kKHMpOwotICAgIH0gLy8gPGluaXQ+KFhNTFN0cmluZykKLQotICAgIC8vCi0gICAgLy8gUHVibGljIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqIENsZWFycyB0aGUgc3RyaW5nIGJ1ZmZlci4gKi8KLSAgICBwdWJsaWMgdm9pZCBjbGVhcigpIHsKLSAgICAgICAgb2Zmc2V0ID0gMDsKLSAgICAgICAgbGVuZ3RoID0gMDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBhcHBlbmQKLSAgICAgKgotICAgICAqIEBwYXJhbSBjCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgYXBwZW5kKGNoYXIgYykgewotICAgICAgICBpZih0aGlzLmxlbmd0aCArIDEgPiB0aGlzLmNoLmxlbmd0aCl7Ci0gICAgICAgICAgICBpbnQgbmV3TGVuZ3RoID0gdGhpcy5jaC5sZW5ndGggKiAyIDsKLSAgICAgICAgICAgIGlmKG5ld0xlbmd0aCA8IHRoaXMuY2gubGVuZ3RoICsgREVGQVVMVF9TSVpFKXsKLSAgICAgICAgICAgICAgICBuZXdMZW5ndGggPSB0aGlzLmNoLmxlbmd0aCArIERFRkFVTFRfU0laRTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNoYXIgW10gdG1wID0gbmV3IGNoYXJbbmV3TGVuZ3RoXTsKLSAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkodGhpcy5jaCwgMCwgdG1wLCAwLCB0aGlzLmxlbmd0aCk7Ci0gICAgICAgICAgICB0aGlzLmNoID0gdG1wOwotICAgICAgICB9Ci0gICAgICAgIHRoaXMuY2hbdGhpcy5sZW5ndGhdID0gYyA7Ci0gICAgICAgIHRoaXMubGVuZ3RoKys7Ci0gICAgfSAvLyBhcHBlbmQoY2hhcikKLQotICAgIC8qKgotICAgICAqIGFwcGVuZAotICAgICAqCi0gICAgICogQHBhcmFtIHMKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBhcHBlbmQoU3RyaW5nIHMpIHsKLSAgICAgICAgaW50IGxlbmd0aCA9IHMubGVuZ3RoKCk7Ci0gICAgICAgIGlmICh0aGlzLmxlbmd0aCArIGxlbmd0aCA+IHRoaXMuY2gubGVuZ3RoKSB7Ci0gICAgICAgICAgICBpbnQgbmV3TGVuZ3RoID0gdGhpcy5jaC5sZW5ndGggKiAyIDsKLSAgICAgICAgICAgIGlmKG5ld0xlbmd0aCA8IHRoaXMuY2gubGVuZ3RoICsgbGVuZ3RoICsgREVGQVVMVF9TSVpFKXsKLSAgICAgICAgICAgICAgICBuZXdMZW5ndGggPSB0aGlzLmNoLmxlbmd0aCArIGxlbmd0aCsgREVGQVVMVF9TSVpFOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBjaGFyW10gbmV3Y2ggPSBuZXcgY2hhcltuZXdMZW5ndGhdOwotICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weSh0aGlzLmNoLCAwLCBuZXdjaCwgMCwgdGhpcy5sZW5ndGgpOwotICAgICAgICAgICAgdGhpcy5jaCA9IG5ld2NoOwotICAgICAgICB9Ci0gICAgICAgIHMuZ2V0Q2hhcnMoMCwgbGVuZ3RoLCB0aGlzLmNoLCB0aGlzLmxlbmd0aCk7Ci0gICAgICAgIHRoaXMubGVuZ3RoICs9IGxlbmd0aDsKLSAgICB9IC8vIGFwcGVuZChTdHJpbmcpCi0KLSAgICAvKioKLSAgICAgKiBhcHBlbmQKLSAgICAgKgotICAgICAqIEBwYXJhbSBjaAotICAgICAqIEBwYXJhbSBvZmZzZXQKLSAgICAgKiBAcGFyYW0gbGVuZ3RoCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgYXBwZW5kKGNoYXJbXSBjaCwgaW50IG9mZnNldCwgaW50IGxlbmd0aCkgewotICAgICAgICBpZiAodGhpcy5sZW5ndGggKyBsZW5ndGggPiB0aGlzLmNoLmxlbmd0aCkgewotICAgICAgICAgICAgaW50IG5ld0xlbmd0aCA9IHRoaXMuY2gubGVuZ3RoICogMiA7Ci0gICAgICAgICAgICBpZihuZXdMZW5ndGggPCB0aGlzLmNoLmxlbmd0aCArIGxlbmd0aCArIERFRkFVTFRfU0laRSl7Ci0gICAgICAgICAgICAgICAgbmV3TGVuZ3RoID0gdGhpcy5jaC5sZW5ndGggKyBsZW5ndGggKyBERUZBVUxUX1NJWkU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjaGFyW10gbmV3Y2ggPSBuZXcgY2hhcltuZXdMZW5ndGhdOwotICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weSh0aGlzLmNoLCAwLCBuZXdjaCwgMCwgdGhpcy5sZW5ndGgpOwotICAgICAgICAgICAgdGhpcy5jaCA9IG5ld2NoOwotICAgICAgICB9Ci0gICAgICAgIC8vbWFraW5nIHRoZSBjb2RlIG1vcmUgcm9idXN0IGFzIGl0IHdvdWxkIGhhbmRsZSBudWxsIG9yIDAgbGVuZ3RoIGRhdGEsCi0gICAgICAgIC8vYWRkIHRoZSBkYXRhIG9ubHkgd2hlbiBpdCBjb250YWlucyBzb21lIHRoaW5nCi0gICAgICAgIGlmKGNoICE9IG51bGwgJiYgbGVuZ3RoID4gMCl7Ci0gICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGNoLCBvZmZzZXQsIHRoaXMuY2gsIHRoaXMubGVuZ3RoLCBsZW5ndGgpOwotICAgICAgICAgICAgdGhpcy5sZW5ndGggKz0gbGVuZ3RoOwotICAgICAgICB9Ci0gICAgfSAvLyBhcHBlbmQoY2hhcltdLGludCxpbnQpCi0KLSAgICAvKioKLSAgICAgKiBhcHBlbmQKLSAgICAgKgotICAgICAqIEBwYXJhbSBzCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgYXBwZW5kKFhNTFN0cmluZyBzKSB7Ci0gICAgICAgIGFwcGVuZChzLmNoLCBzLm9mZnNldCwgcy5sZW5ndGgpOwotICAgIH0gLy8gYXBwZW5kKFhNTFN0cmluZykKLQotCi19IC8vIGNsYXNzIFhNTFN0cmluZ0J1ZmZlcgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9YTUxTeW1ib2xzLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL1hNTFN5bWJvbHMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggODVmODNlMC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlsL1hNTFN5bWJvbHMuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEwMyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAyLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbDsKLQotLyoqCi0gKiBBbGwgaW50ZXJuYWxpemVkIHhtbCBzeW1ib2xzLiBUaGV5IGNhbiBiZSBjb21wYXJlZCB1c2luZyAiPT0iLgotICoKLSAqIEBhdXRob3IgU2FuZHkgR2FvLCBJQk0KLSAqLwotcHVibGljIGNsYXNzIFhNTFN5bWJvbHMgewotCi0gICAgLy8gcHVibGljIGNvbnN0cnVjdG9yLgotICAgIHB1YmxpYyBYTUxTeW1ib2xzKCl7fQotCi0gICAgLy89PT09PT09PT09PT09PT09PT09PT09PT09PQotICAgIC8vIENvbW1vbmx5IHVzZWQgc3RyaW5ncwotICAgIC8vPT09PT09PT09PT09PT09PT09PT09PT09PT0KLQotICAgIC8qKgotICAgICAqIFRoZSBlbXB0eSBzdHJpbmcuCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIHN0YXRpYyBTdHJpbmcgRU1QVFlfU1RSSU5HID0gIiIuaW50ZXJuKCk7Ci0KLSAgICAvLz09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gICAgLy8gTmFtZXNwYWNlIHByZWZpeGVzL3VyaXMKLSAgICAvLz09PT09PT09PT09PT09PT09PT09PT09PT09Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgaW50ZXJuYWxpemVkICJ4bWwiIHByZWZpeC4KLSAgICAgKi8KLSAgICBwdWJsaWMgZmluYWwgc3RhdGljIFN0cmluZyBQUkVGSVhfWE1MID0gInhtbCIuaW50ZXJuKCk7Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgaW50ZXJuYWxpemVkICJ4bWxucyIgcHJlZml4LgotICAgICAqLwotICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgU3RyaW5nIFBSRUZJWF9YTUxOUyA9ICJ4bWxucyIuaW50ZXJuKCk7Ci0KLSAgICAvLz09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gICAgLy8gRFREIHN5bWJvbHMKLSAgICAvLz09PT09PT09PT09PT09PT09PT09PT09PT09Ci0KLSAgICAvKiogU3ltYm9sOiAiQU5ZIi4gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBmQU5ZU3ltYm9sID0gIkFOWSIuaW50ZXJuKCk7Ci0KLSAgICAvKiogU3ltYm9sOiAiQ0RBVEEiLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIGZDREFUQVN5bWJvbCA9ICJDREFUQSIuaW50ZXJuKCk7Ci0KLSAgICAvKiogU3ltYm9sOiAiSUQiLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIGZJRFN5bWJvbCA9ICJJRCIuaW50ZXJuKCk7Ci0KLSAgICAvKiogU3ltYm9sOiAiSURSRUYiLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIGZJRFJFRlN5bWJvbCA9ICJJRFJFRiIuaW50ZXJuKCk7Ci0KLSAgICAvKiogU3ltYm9sOiAiSURSRUZTIi4gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBmSURSRUZTU3ltYm9sID0gIklEUkVGUyIuaW50ZXJuKCk7Ci0KLSAgICAvKiogU3ltYm9sOiAiRU5USVRZIi4gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBmRU5USVRZU3ltYm9sID0gIkVOVElUWSIuaW50ZXJuKCk7Ci0KLSAgICAvKiogU3ltYm9sOiAiRU5USVRJRVMiLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIGZFTlRJVElFU1N5bWJvbCA9ICJFTlRJVElFUyIuaW50ZXJuKCk7Ci0KLSAgICAvKiogU3ltYm9sOiAiTk1UT0tFTiIuICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgZk5NVE9LRU5TeW1ib2wgPSAiTk1UT0tFTiIuaW50ZXJuKCk7Ci0KLSAgICAvKiogU3ltYm9sOiAiTk1UT0tFTlMiLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIGZOTVRPS0VOU1N5bWJvbCA9ICJOTVRPS0VOUyIuaW50ZXJuKCk7Ci0KLSAgICAvKiogU3ltYm9sOiAiTk9UQVRJT04iLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIGZOT1RBVElPTlN5bWJvbCA9ICJOT1RBVElPTiIuaW50ZXJuKCk7Ci0KLSAgICAvKiogU3ltYm9sOiAiRU5VTUVSQVRJT04iLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIGZFTlVNRVJBVElPTlN5bWJvbCA9ICJFTlVNRVJBVElPTiIuaW50ZXJuKCk7Ci0KLSAgICAvKiogU3ltYm9sOiAiI0lNUExJRUQuICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgZklNUExJRURTeW1ib2wgPSAiI0lNUExJRUQiLmludGVybigpOwotCi0gICAgLyoqIFN5bWJvbDogIiNSRVFVSVJFRCIuICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgZlJFUVVJUkVEU3ltYm9sID0gIiNSRVFVSVJFRCIuaW50ZXJuKCk7Ci0KLSAgICAvKiogU3ltYm9sOiAiI0ZJWEVEIi4gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBmRklYRURTeW1ib2wgPSAiI0ZJWEVEIi5pbnRlcm4oKTsKLQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlscy9Db25maWd1cmF0aW9uRXJyb3IuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3V0aWxzL0NvbmZpZ3VyYXRpb25FcnJvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA5Y2Q4NjczLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3V0aWxzL0NvbmZpZ3VyYXRpb25FcnJvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTggKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWxzOwotCi0vKioKLSAqIEEgY29uZmlndXJhdGlvbiBlcnJvci4gVGhpcyB3YXMgYW4gaW50ZXJuYWwgY2xhc3MgaW4gT2JqZWN0RmFjdG9yeSBwcmV2aW91c2x5Ci0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBDb25maWd1cmF0aW9uRXJyb3IKLSAgICBleHRlbmRzIEVycm9yIHsKLQotICAgIC8vCi0gICAgLy8gRGF0YQotICAgIC8vCi0KLSAgICAvKiogRXhjZXB0aW9uLiAqLwotICAgIHByaXZhdGUgRXhjZXB0aW9uIGV4Y2VwdGlvbjsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdCBhIG5ldyBpbnN0YW5jZSB3aXRoIHRoZSBzcGVjaWZpZWQgZGV0YWlsIHN0cmluZyBhbmQKLSAgICAgKiBleGNlcHRpb24uCi0gICAgICovCi0gICAgQ29uZmlndXJhdGlvbkVycm9yKFN0cmluZyBtc2csIEV4Y2VwdGlvbiB4KSB7Ci0gICAgICAgIHN1cGVyKG1zZyk7Ci0gICAgICAgIHRoaXMuZXhjZXB0aW9uID0geDsKLSAgICB9IC8vIDxpbml0PihTdHJpbmcsRXhjZXB0aW9uKQotCi0gICAgLy8KLSAgICAvLyBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKiBSZXR1cm5zIHRoZSBleGNlcHRpb24gYXNzb2NpYXRlZCB0byB0aGlzIGVycm9yLiAqLwotICAgIHB1YmxpYyBFeGNlcHRpb24gZ2V0RXhjZXB0aW9uKCkgewotICAgICAgICByZXR1cm4gZXhjZXB0aW9uOwotICAgIH0gLy8gZ2V0RXhjZXB0aW9uKCk6RXhjZXB0aW9uCi0KLX0gLy8gY2xhc3MgQ29uZmlndXJhdGlvbkVycm9yCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlscy9PYmplY3RGYWN0b3J5LmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlscy9PYmplY3RGYWN0b3J5LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGQxODU3ZWIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbHMvT2JqZWN0RmFjdG9yeS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjMxICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsczsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGlzIGR1cGxpY2F0ZWQgZm9yIGVhY2ggSkFYUCBzdWJwYWNrYWdlIHNvIGtlZXAgaXQgaW4gc3luYy4KLSAqIEl0IGlzIHBhY2thZ2UgcHJpdmF0ZSBhbmQgdGhlcmVmb3JlIGlzIG5vdCBleHBvc2VkIGFzIHBhcnQgb2YgdGhlIEpBWFAKLSAqIEFQSS4KLSAqIDxwPgotICogVGhpcyBjb2RlIGlzIGRlc2lnbmVkIHRvIGltcGxlbWVudCB0aGUgSkFYUCAxLjEgc3BlYyBwbHVnZ2FiaWxpdHkKLSAqIGZlYXR1cmUgYW5kIGlzIGRlc2lnbmVkIHRvIHJ1biBvbiBKREsgdmVyc2lvbiAxLjEgYW5kCi0gKiBsYXRlciwgYW5kIHRvIGNvbXBpbGUgb24gSkRLIDEuMiBhbmQgb253YXJkLgotICogVGhlIGNvZGUgYWxzbyBydW5zIGJvdGggYXMgcGFydCBvZiBhbiB1bmJ1bmRsZWQgamFyIGZpbGUgYW5kCi0gKiB3aGVuIGJ1bmRsZWQgYXMgcGFydCBvZiB0aGUgSkRLLgotICogPHA+Ci0gKgotICogQHZlcnNpb24gJElkOiBPYmplY3RGYWN0b3J5LmphdmEsdiAxLjYgMjAxMC8wNC8yMyAwMTo0NDozNCBqb2VodyBFeHAgJAotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgT2JqZWN0RmFjdG9yeSB7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0YW50cwotICAgIC8vCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEpBWFBfSU5URVJOQUwgPSAiY29tLnN1bi5vcmcuYXBhY2hlIjsKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1RBWF9JTlRFUk5BTCA9ICJjb20uc3VuLnhtbC5pbnRlcm5hbCI7Ci0KLSAgICAvKiogU2V0IHRvIHRydWUgZm9yIGRlYnVnZ2luZyAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW4gREVCVUcgPSBpc0RlYnVnRW5hYmxlZCgpOwotCi0KLSAgICAvLwotICAgIC8vIFByaXZhdGUgc3RhdGljIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqIFJldHVybnMgdHJ1ZSBpZiBkZWJ1ZyBoYXMgYmVlbiBlbmFibGVkLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNEZWJ1Z0VuYWJsZWQoKSB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBTdHJpbmcgdmFsID0gU2VjdXJpdHlTdXBwb3J0LmdldFN5c3RlbVByb3BlcnR5KCJ4ZXJjZXMuZGVidWciKTsKLSAgICAgICAgICAgIC8vIEFsbG93IHNpbXBseSBzZXR0aW5nIHRoZSBwcm9wIHRvIHR1cm4gb24gZGVidWcKLSAgICAgICAgICAgIHJldHVybiAodmFsICE9IG51bGwgJiYgKCEiZmFsc2UiLmVxdWFscyh2YWwpKSk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIHNlKSB7fQotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfSAvLyBpc0RlYnVnRW5hYmxlZCgpCi0KLSAgICAvKiogUHJpbnRzIGEgbWVzc2FnZSB0byBzdGFuZGFyZCBlcnJvciBpZiBkZWJ1Z2dpbmcgaXMgZW5hYmxlZC4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGRlYnVnUHJpbnRsbihTdHJpbmcgbXNnKSB7Ci0gICAgICAgIGlmIChERUJVRykgewotICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJYRVJDRVM6ICIgKyBtc2cpOwotICAgICAgICB9Ci0gICAgfSAvLyBkZWJ1Z1ByaW50bG4oU3RyaW5nKQotCi0gICAgLyoqCi0gICAgICogRmlndXJlIG91dCB3aGljaCBDbGFzc0xvYWRlciB0byB1c2UuICBGb3IgSkRLIDEuMiBhbmQgbGF0ZXIgdXNlCi0gICAgICogdGhlIGNvbnRleHQgQ2xhc3NMb2FkZXIuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBDbGFzc0xvYWRlciBmaW5kQ2xhc3NMb2FkZXIoKQotICAgICAgICB0aHJvd3MgQ29uZmlndXJhdGlvbkVycm9yCi0gICAgewotICAgICAgICBpZiAoU3lzdGVtLmdldFNlY3VyaXR5TWFuYWdlcigpIT1udWxsKSB7Ci0gICAgICAgICAgICAvL3RoaXMgd2lsbCBlbnN1cmUgYm9vdGNsYXNzbG9hZGVyIGlzIHVzZWQKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgICAgIC8vIEZpZ3VyZSBvdXQgd2hpY2ggQ2xhc3NMb2FkZXIgdG8gdXNlIGZvciBsb2FkaW5nIHRoZSBwcm92aWRlcgotICAgICAgICAvLyBjbGFzcy4gIElmIHRoZXJlIGlzIGEgQ29udGV4dCBDbGFzc0xvYWRlciB0aGVuIHVzZSBpdC4KLSAgICAgICAgQ2xhc3NMb2FkZXIgY29udGV4dCA9IFNlY3VyaXR5U3VwcG9ydC5nZXRDb250ZXh0Q2xhc3NMb2FkZXIoKTsKLSAgICAgICAgQ2xhc3NMb2FkZXIgc3lzdGVtID0gU2VjdXJpdHlTdXBwb3J0LmdldFN5c3RlbUNsYXNzTG9hZGVyKCk7Ci0KLSAgICAgICAgQ2xhc3NMb2FkZXIgY2hhaW4gPSBzeXN0ZW07Ci0gICAgICAgIHdoaWxlICh0cnVlKSB7Ci0gICAgICAgICAgICBpZiAoY29udGV4dCA9PSBjaGFpbikgewotICAgICAgICAgICAgICAgIC8vIEFzc2VydDogd2UgYXJlIG9uIEpESyAxLjEgb3Igd2UgaGF2ZSBubyBDb250ZXh0IENsYXNzTG9hZGVyCi0gICAgICAgICAgICAgICAgLy8gb3IgYW55IENvbnRleHQgQ2xhc3NMb2FkZXIgaW4gY2hhaW4gb2Ygc3lzdGVtIGNsYXNzbG9hZGVyCi0gICAgICAgICAgICAgICAgLy8gKGluY2x1ZGluZyBleHRlbnNpb24gQ2xhc3NMb2FkZXIpIHNvIGV4dGVuZCB0byB3aWRlc3QKLSAgICAgICAgICAgICAgICAvLyBDbGFzc0xvYWRlciAoYWx3YXlzIGxvb2sgaW4gc3lzdGVtIENsYXNzTG9hZGVyIGlmIFhlcmNlcwotICAgICAgICAgICAgICAgIC8vIGlzIGluIGJvb3QvZXh0ZW5zaW9uL3N5c3RlbSBjbGFzc3BhdGggYW5kIGluIGN1cnJlbnQKLSAgICAgICAgICAgICAgICAvLyBDbGFzc0xvYWRlciBvdGhlcndpc2UpOyBub3JtYWwgY2xhc3Nsb2FkZXJzIGRlbGVnYXRlCi0gICAgICAgICAgICAgICAgLy8gYmFjayB0byBzeXN0ZW0gQ2xhc3NMb2FkZXIgZmlyc3Qgc28gdGhpcyB3aWRlbmluZyBkb2Vzbid0Ci0gICAgICAgICAgICAgICAgLy8gY2hhbmdlIHRoZSBmYWN0IHRoYXQgY29udGV4dCBDbGFzc0xvYWRlciB3aWxsIGJlIGNvbnN1bHRlZAotICAgICAgICAgICAgICAgIENsYXNzTG9hZGVyIGN1cnJlbnQgPSBPYmplY3RGYWN0b3J5LmNsYXNzLmdldENsYXNzTG9hZGVyKCk7Ci0KLSAgICAgICAgICAgICAgICBjaGFpbiA9IHN5c3RlbTsKLSAgICAgICAgICAgICAgICB3aGlsZSAodHJ1ZSkgewotICAgICAgICAgICAgICAgICAgICBpZiAoY3VycmVudCA9PSBjaGFpbikgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gQXNzZXJ0OiBDdXJyZW50IENsYXNzTG9hZGVyIGluIGNoYWluIG9mCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBib290L2V4dGVuc2lvbi9zeXN0ZW0gQ2xhc3NMb2FkZXJzCi0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3lzdGVtOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGlmIChjaGFpbiA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBjaGFpbiA9IFNlY3VyaXR5U3VwcG9ydC5nZXRQYXJlbnRDbGFzc0xvYWRlcihjaGFpbik7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgLy8gQXNzZXJ0OiBDdXJyZW50IENsYXNzTG9hZGVyIG5vdCBpbiBjaGFpbiBvZgotICAgICAgICAgICAgICAgIC8vIGJvb3QvZXh0ZW5zaW9uL3N5c3RlbSBDbGFzc0xvYWRlcnMKLSAgICAgICAgICAgICAgICByZXR1cm4gY3VycmVudDsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKGNoYWluID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAvLyBib290IENsYXNzTG9hZGVyIHJlYWNoZWQKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gQ2hlY2sgZm9yIGFueSBleHRlbnNpb24gQ2xhc3NMb2FkZXJzIGluIGNoYWluIHVwIHRvCi0gICAgICAgICAgICAvLyBib290IENsYXNzTG9hZGVyCi0gICAgICAgICAgICBjaGFpbiA9IFNlY3VyaXR5U3VwcG9ydC5nZXRQYXJlbnRDbGFzc0xvYWRlcihjaGFpbik7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBBc3NlcnQ6IENvbnRleHQgQ2xhc3NMb2FkZXIgbm90IGluIGNoYWluIG9mCi0gICAgICAgIC8vIGJvb3QvZXh0ZW5zaW9uL3N5c3RlbSBDbGFzc0xvYWRlcnMKLSAgICAgICAgcmV0dXJuIGNvbnRleHQ7Ci0gICAgfSAvLyBmaW5kQ2xhc3NMb2FkZXIoKTpDbGFzc0xvYWRlcgotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlIGFuIGluc3RhbmNlIG9mIGEgY2xhc3MgdXNpbmcgdGhlIHNhbWUgY2xhc3Nsb2FkZXIgZm9yIHRoZSBPYmplY3RGYWN0b3J5IGJ5IGRlZmF1bHQKLSAgICAgKiBvciBib290Y2xhc3Nsb2FkZXIgd2hlbiBTZWN1cml0eSBNYW5hZ2VyIGlzIGluIHBsYWNlCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBPYmplY3QgbmV3SW5zdGFuY2UoU3RyaW5nIGNsYXNzTmFtZSwgYm9vbGVhbiBkb0ZhbGxiYWNrKQotICAgICAgICB0aHJvd3MgQ29uZmlndXJhdGlvbkVycm9yCi0gICAgewotICAgICAgICBpZiAoU3lzdGVtLmdldFNlY3VyaXR5TWFuYWdlcigpIT1udWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gbmV3SW5zdGFuY2UoY2xhc3NOYW1lLCBudWxsLCBkb0ZhbGxiYWNrKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiBuZXdJbnN0YW5jZShjbGFzc05hbWUsCi0gICAgICAgICAgICAgICAgZmluZENsYXNzTG9hZGVyICgpLCBkb0ZhbGxiYWNrKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIENyZWF0ZSBhbiBpbnN0YW5jZSBvZiBhIGNsYXNzIHVzaW5nIHRoZSBzcGVjaWZpZWQgQ2xhc3NMb2FkZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIE9iamVjdCBuZXdJbnN0YW5jZShTdHJpbmcgY2xhc3NOYW1lLCBDbGFzc0xvYWRlciBjbCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBkb0ZhbGxiYWNrKQotICAgICAgICB0aHJvd3MgQ29uZmlndXJhdGlvbkVycm9yCi0gICAgewotICAgICAgICAvLyBhc3NlcnQoY2xhc3NOYW1lICE9IG51bGwpOwotICAgICAgICB0cnl7Ci0gICAgICAgICAgICBDbGFzcyBwcm92aWRlckNsYXNzID0gZmluZFByb3ZpZGVyQ2xhc3MoY2xhc3NOYW1lLCBjbCwgZG9GYWxsYmFjayk7Ci0gICAgICAgICAgICBPYmplY3QgaW5zdGFuY2UgPSBwcm92aWRlckNsYXNzLm5ld0luc3RhbmNlKCk7Ci0gICAgICAgICAgICBpZiAoREVCVUcpIGRlYnVnUHJpbnRsbigiY3JlYXRlZCBuZXcgaW5zdGFuY2Ugb2YgIiArIHByb3ZpZGVyQ2xhc3MgKwotICAgICAgICAgICAgICAgICAgICIgdXNpbmcgQ2xhc3NMb2FkZXI6ICIgKyBjbCk7Ci0gICAgICAgICAgICByZXR1cm4gaW5zdGFuY2U7Ci0gICAgICAgIH0gY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24geCkgewotICAgICAgICAgICAgdGhyb3cgbmV3IENvbmZpZ3VyYXRpb25FcnJvcigKLSAgICAgICAgICAgICAgICAiUHJvdmlkZXIgIiArIGNsYXNzTmFtZSArICIgbm90IGZvdW5kIiwgeCk7Ci0gICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiB4KSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgQ29uZmlndXJhdGlvbkVycm9yKAotICAgICAgICAgICAgICAgICJQcm92aWRlciAiICsgY2xhc3NOYW1lICsgIiBjb3VsZCBub3QgYmUgaW5zdGFudGlhdGVkOiAiICsgeCwKLSAgICAgICAgICAgICAgICB4KTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEZpbmQgYSBDbGFzcyB1c2luZyB0aGUgc2FtZSBjbGFzc2xvYWRlciBmb3IgdGhlIE9iamVjdEZhY3RvcnkgYnkgZGVmYXVsdAotICAgICAqIG9yIGJvb3RjbGFzc2xvYWRlciB3aGVuIFNlY3VyaXR5IE1hbmFnZXIgaXMgaW4gcGxhY2UKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIENsYXNzIGZpbmRQcm92aWRlckNsYXNzKFN0cmluZyBjbGFzc05hbWUsIGJvb2xlYW4gZG9GYWxsYmFjaykKLSAgICAgICAgdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb24sIENvbmZpZ3VyYXRpb25FcnJvcgotICAgIHsKLSAgICAgICAgcmV0dXJuIGZpbmRQcm92aWRlckNsYXNzIChjbGFzc05hbWUsCi0gICAgICAgICAgICAgICAgZmluZENsYXNzTG9hZGVyICgpLCBkb0ZhbGxiYWNrKTsKLSAgICB9Ci0gICAgLyoqCi0gICAgICogRmluZCBhIENsYXNzIHVzaW5nIHRoZSBzcGVjaWZpZWQgQ2xhc3NMb2FkZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIENsYXNzIGZpbmRQcm92aWRlckNsYXNzKFN0cmluZyBjbGFzc05hbWUsIENsYXNzTG9hZGVyIGNsLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGRvRmFsbGJhY2spCi0gICAgICAgIHRocm93cyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uLCBDb25maWd1cmF0aW9uRXJyb3IKLSAgICB7Ci0gICAgICAgIC8vdGhyb3cgc2VjdXJpdHkgZXhjZXB0aW9uIGlmIHRoZSBjYWxsaW5nIHRocmVhZCBpcyBub3QgYWxsb3dlZCB0byBhY2Nlc3MgdGhlIHBhY2thZ2UKLSAgICAgICAgLy9yZXN0cmljdCB0aGUgYWNjZXNzIHRvIHBhY2thZ2UgYXMgc3BlaWNpZmllZCBpbiBqYXZhLnNlY3VyaXR5IHBvbGljeQotICAgICAgICBTZWN1cml0eU1hbmFnZXIgc2VjdXJpdHkgPSBTeXN0ZW0uZ2V0U2VjdXJpdHlNYW5hZ2VyKCk7Ci0gICAgICAgIGlmIChzZWN1cml0eSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAoY2xhc3NOYW1lLnN0YXJ0c1dpdGgoSkFYUF9JTlRFUk5BTCkgfHwKLSAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lLnN0YXJ0c1dpdGgoU1RBWF9JTlRFUk5BTCkpIHsKLSAgICAgICAgICAgICAgICBjbCA9IG51bGw7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIGZpbmFsIGludCBsYXN0RG90ID0gY2xhc3NOYW1lLmxhc3RJbmRleE9mKCIuIik7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIHBhY2thZ2VOYW1lID0gY2xhc3NOYW1lOwotICAgICAgICAgICAgICAgIGlmIChsYXN0RG90ICE9IC0xKSBwYWNrYWdlTmFtZSA9IGNsYXNzTmFtZS5zdWJzdHJpbmcoMCwgbGFzdERvdCk7Ci0gICAgICAgICAgICAgICAgc2VjdXJpdHkuY2hlY2tQYWNrYWdlQWNjZXNzKHBhY2thZ2VOYW1lKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBDbGFzcyBwcm92aWRlckNsYXNzOwotICAgICAgICBpZiAoY2wgPT0gbnVsbCkgewotICAgICAgICAgICAgLy91c2UgdGhlIGJvb3RzdHJhcCBDbGFzc0xvYWRlci4KLSAgICAgICAgICAgIHByb3ZpZGVyQ2xhc3MgPSBDbGFzcy5mb3JOYW1lKGNsYXNzTmFtZSwgZmFsc2UsIE9iamVjdEZhY3RvcnkuY2xhc3MuZ2V0Q2xhc3NMb2FkZXIoKSk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIHByb3ZpZGVyQ2xhc3MgPSBjbC5sb2FkQ2xhc3MoY2xhc3NOYW1lKTsKLSAgICAgICAgICAgIH0gY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24geCkgewotICAgICAgICAgICAgICAgIGlmIChkb0ZhbGxiYWNrKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIEZhbGwgYmFjayB0byBjdXJyZW50IGNsYXNzbG9hZGVyCi0gICAgICAgICAgICAgICAgICAgIENsYXNzTG9hZGVyIGN1cnJlbnQgPSBPYmplY3RGYWN0b3J5LmNsYXNzLmdldENsYXNzTG9hZGVyKCk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChjdXJyZW50ID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHByb3ZpZGVyQ2xhc3MgPSBDbGFzcy5mb3JOYW1lKGNsYXNzTmFtZSk7Ci0gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoY2wgIT0gY3VycmVudCkgewotICAgICAgICAgICAgICAgICAgICAgICAgY2wgPSBjdXJyZW50OwotICAgICAgICAgICAgICAgICAgICAgICAgcHJvdmlkZXJDbGFzcyA9IGNsLmxvYWRDbGFzcyhjbGFzc05hbWUpOwotICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgeDsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIHRocm93IHg7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIHByb3ZpZGVyQ2xhc3M7Ci0gICAgfQotCi19IC8vIGNsYXNzIE9iamVjdEZhY3RvcnkKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3V0aWxzL1NlY3VyaXR5U3VwcG9ydC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbHMvU2VjdXJpdHlTdXBwb3J0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDYxM2Q2NTEuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbHMvU2VjdXJpdHlTdXBwb3J0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzMzkgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMiwyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWxzOwotCi1pbXBvcnQgamF2YS5pby5GaWxlOwotaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uRmlsZU5vdEZvdW5kRXhjZXB0aW9uOwotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci1pbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKLWltcG9ydCBqYXZhLm5ldC5VUkw7Ci1pbXBvcnQgamF2YS5zZWN1cml0eS5BY2Nlc3NDb250cm9sbGVyOwotaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpdmlsZWdlZEFjdGlvbjsKLWltcG9ydCBqYXZhLnNlY3VyaXR5LlByaXZpbGVnZWRBY3Rpb25FeGNlcHRpb247Ci1pbXBvcnQgamF2YS5zZWN1cml0eS5Qcml2aWxlZ2VkRXhjZXB0aW9uQWN0aW9uOwotaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7Ci1pbXBvcnQgamF2YS51dGlsLk1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKLWltcG9ydCBqYXZhLnV0aWwuUHJvcGVydHlSZXNvdXJjZUJ1bmRsZTsKLWltcG9ydCBqYXZhLnV0aWwuUmVzb3VyY2VCdW5kbGU7Ci0KLS8qKgotICogVGhpcyBjbGFzcyBpcyBkdXBsaWNhdGVkIGZvciBlYWNoIHN1YnBhY2thZ2Ugc28ga2VlcCBpdCBpbiBzeW5jLgotICogSXQgaXMgcGFja2FnZSBwcml2YXRlIGFuZCB0aGVyZWZvcmUgaXMgbm90IGV4cG9zZWQgYXMgcGFydCBvZiBhbnkgQVBJLgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIFNlY3VyaXR5U3VwcG9ydCB7Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTZWN1cml0eVN1cHBvcnQgc2VjdXJpdHlTdXBwb3J0ID0gbmV3IFNlY3VyaXR5U3VwcG9ydCgpOwotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIGFuIGluc3RhbmNlIG9mIHRoaXMgY2xhc3MuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBTZWN1cml0eVN1cHBvcnQgZ2V0SW5zdGFuY2UoKSB7Ci0gICAgICAgIHJldHVybiBzZWN1cml0eVN1cHBvcnQ7Ci0gICAgfQotCi0gICAgc3RhdGljIENsYXNzTG9hZGVyIGdldENvbnRleHRDbGFzc0xvYWRlcigpIHsKLSAgICAgICAgcmV0dXJuIChDbGFzc0xvYWRlcikKLSAgICAgICAgQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQobmV3IFByaXZpbGVnZWRBY3Rpb24oKSB7Ci0gICAgICAgICAgICBwdWJsaWMgT2JqZWN0IHJ1bigpIHsKLSAgICAgICAgICAgICAgICBDbGFzc0xvYWRlciBjbCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgY2wgPSBUaHJlYWQuY3VycmVudFRocmVhZCgpLmdldENvbnRleHRDbGFzc0xvYWRlcigpOwotICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIGV4KSB7IH0KLSAgICAgICAgICAgICAgICByZXR1cm4gY2w7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0pOwotICAgIH0KLQotICAgIHN0YXRpYyBDbGFzc0xvYWRlciBnZXRTeXN0ZW1DbGFzc0xvYWRlcigpIHsKLSAgICAgICAgcmV0dXJuIChDbGFzc0xvYWRlcikKLSAgICAgICAgQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQobmV3IFByaXZpbGVnZWRBY3Rpb24oKSB7Ci0gICAgICAgICAgICBwdWJsaWMgT2JqZWN0IHJ1bigpIHsKLSAgICAgICAgICAgICAgICBDbGFzc0xvYWRlciBjbCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgY2wgPSBDbGFzc0xvYWRlci5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpOwotICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIGV4KSB7fQotICAgICAgICAgICAgICAgIHJldHVybiBjbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSk7Ci0gICAgfQotCi0gICAgc3RhdGljIENsYXNzTG9hZGVyIGdldFBhcmVudENsYXNzTG9hZGVyKGZpbmFsIENsYXNzTG9hZGVyIGNsKSB7Ci0gICAgICAgIHJldHVybiAoQ2xhc3NMb2FkZXIpCi0gICAgICAgIEFjY2Vzc0NvbnRyb2xsZXIuZG9Qcml2aWxlZ2VkKG5ldyBQcml2aWxlZ2VkQWN0aW9uKCkgewotICAgICAgICAgICAgcHVibGljIE9iamVjdCBydW4oKSB7Ci0gICAgICAgICAgICAgICAgQ2xhc3NMb2FkZXIgcGFyZW50ID0gbnVsbDsKLSAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICBwYXJlbnQgPSBjbC5nZXRQYXJlbnQoKTsKLSAgICAgICAgICAgICAgICB9IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBleCkge30KLQotICAgICAgICAgICAgICAgIC8vIGVsaW1pbmF0ZSBsb29wcyBpbiBjYXNlIG9mIHRoZSBib290Ci0gICAgICAgICAgICAgICAgLy8gQ2xhc3NMb2FkZXIgcmV0dXJuaW5nIGl0c2VsZiBhcyBhIHBhcmVudAotICAgICAgICAgICAgICAgIHJldHVybiAocGFyZW50ID09IGNsKSA/IG51bGwgOiBwYXJlbnQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0pOwotICAgIH0KLQotICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldFN5c3RlbVByb3BlcnR5KGZpbmFsIFN0cmluZyBwcm9wTmFtZSkgewotICAgICAgICByZXR1cm4gKFN0cmluZykKLSAgICAgICAgQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQobmV3IFByaXZpbGVnZWRBY3Rpb24oKSB7Ci0gICAgICAgICAgICBwdWJsaWMgT2JqZWN0IHJ1bigpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gU3lzdGVtLmdldFByb3BlcnR5KHByb3BOYW1lKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSk7Ci0gICAgfQotCi0gICAgc3RhdGljIEZpbGVJbnB1dFN0cmVhbSBnZXRGaWxlSW5wdXRTdHJlYW0oZmluYWwgRmlsZSBmaWxlKQotICAgIHRocm93cyBGaWxlTm90Rm91bmRFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICByZXR1cm4gKEZpbGVJbnB1dFN0cmVhbSkKLSAgICAgICAgICAgIEFjY2Vzc0NvbnRyb2xsZXIuZG9Qcml2aWxlZ2VkKG5ldyBQcml2aWxlZ2VkRXhjZXB0aW9uQWN0aW9uKCkgewotICAgICAgICAgICAgICAgIHB1YmxpYyBPYmplY3QgcnVuKCkgdGhyb3dzIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgRmlsZUlucHV0U3RyZWFtKGZpbGUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0pOwotICAgICAgICB9IGNhdGNoIChQcml2aWxlZ2VkQWN0aW9uRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIHRocm93IChGaWxlTm90Rm91bmRFeGNlcHRpb24pZS5nZXRFeGNlcHRpb24oKTsKLSAgICAgICAgfQotICAgIH0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gcmVzb3VyY2UgdXNpbmcgdGhlIHNhbWUgY2xhc3Nsb2FkZXIgZm9yIHRoZSBPYmplY3RGYWN0b3J5IGJ5IGRlZmF1bHQKLSAgICAgKiBvciBib290Y2xhc3Nsb2FkZXIgd2hlbiBTZWN1cml0eSBNYW5hZ2VyIGlzIGluIHBsYWNlCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBJbnB1dFN0cmVhbSBnZXRSZXNvdXJjZUFzU3RyZWFtKGZpbmFsIFN0cmluZyBuYW1lKSB7Ci0gICAgICAgIGlmIChTeXN0ZW0uZ2V0U2VjdXJpdHlNYW5hZ2VyKCkhPW51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBnZXRSZXNvdXJjZUFzU3RyZWFtKG51bGwsIG5hbWUpOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIGdldFJlc291cmNlQXNTdHJlYW0oT2JqZWN0RmFjdG9yeS5maW5kQ2xhc3NMb2FkZXIoKSwgbmFtZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgc3RhdGljIElucHV0U3RyZWFtIGdldFJlc291cmNlQXNTdHJlYW0oZmluYWwgQ2xhc3NMb2FkZXIgY2wsCi0gICAgICAgICAgICBmaW5hbCBTdHJpbmcgbmFtZSkKLSAgICB7Ci0gICAgICAgIHJldHVybiAoSW5wdXRTdHJlYW0pCi0gICAgICAgIEFjY2Vzc0NvbnRyb2xsZXIuZG9Qcml2aWxlZ2VkKG5ldyBQcml2aWxlZ2VkQWN0aW9uKCkgewotICAgICAgICAgICAgcHVibGljIE9iamVjdCBydW4oKSB7Ci0gICAgICAgICAgICAgICAgSW5wdXRTdHJlYW0gcmlzOwotICAgICAgICAgICAgICAgIGlmIChjbCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJpcyA9IE9iamVjdC5jbGFzcy5nZXRSZXNvdXJjZUFzU3RyZWFtKCIvIituYW1lKTsKLSAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICByaXMgPSBjbC5nZXRSZXNvdXJjZUFzU3RyZWFtKG5hbWUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICByZXR1cm4gcmlzOwotICAgICAgICAgICAgfQotICAgICAgICB9KTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXRzIGEgcmVzb3VyY2UgYnVuZGxlIHVzaW5nIHRoZSBzcGVjaWZpZWQgYmFzZSBuYW1lLCB0aGUgZGVmYXVsdCBsb2NhbGUsIGFuZCB0aGUgY2FsbGVyJ3MgY2xhc3MgbG9hZGVyLgotICAgICAqIEBwYXJhbSBidW5kbGUgdGhlIGJhc2UgbmFtZSBvZiB0aGUgcmVzb3VyY2UgYnVuZGxlLCBhIGZ1bGx5IHF1YWxpZmllZCBjbGFzcyBuYW1lCi0gICAgICogQHJldHVybiBhIHJlc291cmNlIGJ1bmRsZSBmb3IgdGhlIGdpdmVuIGJhc2UgbmFtZSBhbmQgdGhlIGRlZmF1bHQgbG9jYWxlCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBSZXNvdXJjZUJ1bmRsZSBnZXRSZXNvdXJjZUJ1bmRsZShTdHJpbmcgYnVuZGxlKSB7Ci0gICAgICAgIHJldHVybiBnZXRSZXNvdXJjZUJ1bmRsZShidW5kbGUsIExvY2FsZS5nZXREZWZhdWx0KCkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldHMgYSByZXNvdXJjZSBidW5kbGUgdXNpbmcgdGhlIHNwZWNpZmllZCBiYXNlIG5hbWUgYW5kIGxvY2FsZSwgYW5kIHRoZSBjYWxsZXIncyBjbGFzcyBsb2FkZXIuCi0gICAgICogQHBhcmFtIGJ1bmRsZSB0aGUgYmFzZSBuYW1lIG9mIHRoZSByZXNvdXJjZSBidW5kbGUsIGEgZnVsbHkgcXVhbGlmaWVkIGNsYXNzIG5hbWUKLSAgICAgKiBAcGFyYW0gbG9jYWxlIHRoZSBsb2NhbGUgZm9yIHdoaWNoIGEgcmVzb3VyY2UgYnVuZGxlIGlzIGRlc2lyZWQKLSAgICAgKiBAcmV0dXJuIGEgcmVzb3VyY2UgYnVuZGxlIGZvciB0aGUgZ2l2ZW4gYmFzZSBuYW1lIGFuZCBsb2NhbGUKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFJlc291cmNlQnVuZGxlIGdldFJlc291cmNlQnVuZGxlKGZpbmFsIFN0cmluZyBidW5kbGUsIGZpbmFsIExvY2FsZSBsb2NhbGUpIHsKLSAgICAgICAgcmV0dXJuIEFjY2Vzc0NvbnRyb2xsZXIuZG9Qcml2aWxlZ2VkKG5ldyBQcml2aWxlZ2VkQWN0aW9uPFJlc291cmNlQnVuZGxlPigpIHsKLSAgICAgICAgICAgIHB1YmxpYyBSZXNvdXJjZUJ1bmRsZSBydW4oKSB7Ci0gICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb3BlcnR5UmVzb3VyY2VCdW5kbGUuZ2V0QnVuZGxlKGJ1bmRsZSwgbG9jYWxlKTsKLSAgICAgICAgICAgICAgICB9IGNhdGNoIChNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb3BlcnR5UmVzb3VyY2VCdW5kbGUuZ2V0QnVuZGxlKGJ1bmRsZSwgbmV3IExvY2FsZSgiZW4iLCAiVVMiKSk7Ci0gICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbiBlMikgewotICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNvdWxkIG5vdCBsb2FkIGFueSByZXNvdXJjZSBidW5kbGUgYnkgIiArIGJ1bmRsZSwgYnVuZGxlLCAiIik7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0pOwotICAgIH0KLQotICAgIHN0YXRpYyBib29sZWFuIGdldEZpbGVFeGlzdHMoZmluYWwgRmlsZSBmKSB7Ci0gICAgICAgIHJldHVybiAoKEJvb2xlYW4pCi0gICAgICAgICAgICAgICAgQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQobmV3IFByaXZpbGVnZWRBY3Rpb24oKSB7Ci0gICAgICAgICAgICAgICAgICAgIHB1YmxpYyBPYmplY3QgcnVuKCkgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGYuZXhpc3RzKCkgPyBCb29sZWFuLlRSVUUgOiBCb29sZWFuLkZBTFNFOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfSkpLmJvb2xlYW5WYWx1ZSgpOwotICAgIH0KLQotICAgIHN0YXRpYyBsb25nIGdldExhc3RNb2RpZmllZChmaW5hbCBGaWxlIGYpIHsKLSAgICAgICAgcmV0dXJuICgoTG9uZykKLSAgICAgICAgICAgICAgICBBY2Nlc3NDb250cm9sbGVyLmRvUHJpdmlsZWdlZChuZXcgUHJpdmlsZWdlZEFjdGlvbigpIHsKLSAgICAgICAgICAgICAgICAgICAgcHVibGljIE9iamVjdCBydW4oKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IExvbmcoZi5sYXN0TW9kaWZpZWQoKSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9KSkubG9uZ1ZhbHVlKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU3RyaXAgb2ZmIHBhdGggZnJvbSBhbiBVUkkKLSAgICAgKgotICAgICAqIEBwYXJhbSB1cmkgYW4gVVJJIHdpdGggZnVsbCBwYXRoCi0gICAgICogQHJldHVybiB0aGUgZmlsZSBuYW1lIG9ubHkKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBzYW5pdGl6ZVBhdGgoU3RyaW5nIHVyaSkgewotICAgICAgICBpZiAodXJpID09IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiAiIjsKLSAgICAgICAgfQotICAgICAgICBpbnQgaSA9IHVyaS5sYXN0SW5kZXhPZigiLyIpOwotICAgICAgICBpZiAoaSA+IDApIHsKLSAgICAgICAgICAgIHJldHVybiB1cmkuc3Vic3RyaW5nKGkrMSwgdXJpLmxlbmd0aCgpKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gdXJpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENoZWNrIHRoZSBwcm90b2NvbCB1c2VkIGluIHRoZSBzeXN0ZW1JZCBhZ2FpbnN0IGFsbG93ZWQgcHJvdG9jb2xzCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc3lzdGVtSWQgdGhlIElkIG9mIHRoZSBVUkkKLSAgICAgKiBAcGFyYW0gYWxsb3dlZFByb3RvY29scyBhIGxpc3Qgb2YgYWxsb3dlZCBwcm90b2NvbHMgc2VwYXJhdGVkIGJ5IGNvbW1hCi0gICAgICogQHBhcmFtIGFjY2Vzc0FueSBrZXl3b3JkIHRvIGluZGljYXRlIGFsbG93aW5nIGFueSBwcm90b2NvbAotICAgICAqIEByZXR1cm4gdGhlIG5hbWUgb2YgdGhlIHByb3RvY29sIGlmIHJlamVjdGVkLCBudWxsIG90aGVyd2lzZQotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGNoZWNrQWNjZXNzKFN0cmluZyBzeXN0ZW1JZCwgU3RyaW5nIGFsbG93ZWRQcm90b2NvbHMsIFN0cmluZyBhY2Nlc3NBbnkpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChzeXN0ZW1JZCA9PSBudWxsIHx8IChhbGxvd2VkUHJvdG9jb2xzICE9IG51bGwgJiYKLSAgICAgICAgICAgICAgICBhbGxvd2VkUHJvdG9jb2xzLmVxdWFsc0lnbm9yZUNhc2UoYWNjZXNzQW55KSkpIHsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0KLSAgICAgICAgU3RyaW5nIHByb3RvY29sOwotICAgICAgICBpZiAoc3lzdGVtSWQuaW5kZXhPZigiOiIpPT0tMSkgewotICAgICAgICAgICAgcHJvdG9jb2wgPSAiZmlsZSI7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBVUkwgdXJsID0gbmV3IFVSTChzeXN0ZW1JZCk7Ci0gICAgICAgICAgICBwcm90b2NvbCA9IHVybC5nZXRQcm90b2NvbCgpOwotICAgICAgICAgICAgaWYgKHByb3RvY29sLmVxdWFsc0lnbm9yZUNhc2UoImphciIpKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIHBhdGggPSB1cmwuZ2V0UGF0aCgpOwotICAgICAgICAgICAgICAgIHByb3RvY29sID0gcGF0aC5zdWJzdHJpbmcoMCwgcGF0aC5pbmRleE9mKCI6IikpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKGlzUHJvdG9jb2xBbGxvd2VkKHByb3RvY29sLCBhbGxvd2VkUHJvdG9jb2xzKSkgewotICAgICAgICAgICAgLy9hY2Nlc3MgYWxsb3dlZAotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gcHJvdG9jb2w7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDaGVjayBpZiB0aGUgcHJvdG9jb2wgaXMgaW4gdGhlIGFsbG93ZWQgbGlzdCBvZiBwcm90b2NvbHMuIFRoZSBjaGVjawotICAgICAqIGlzIGNhc2UtaW5zZW5zaXRpdmUgd2hpbGUgaWdub3Jpbmcgd2hpdGVzcGFjZXMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcHJvdG9jb2wgYSBwcm90b2NvbAotICAgICAqIEBwYXJhbSBhbGxvd2VkUHJvdG9jb2xzIGEgbGlzdCBvZiBhbGxvd2VkIHByb3RvY29scwotICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgcHJvdG9jb2wgaXMgaW4gdGhlIGxpc3QKLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGlzUHJvdG9jb2xBbGxvd2VkKFN0cmluZyBwcm90b2NvbCwgU3RyaW5nIGFsbG93ZWRQcm90b2NvbHMpIHsKLSAgICAgICAgIGlmIChhbGxvd2VkUHJvdG9jb2xzID09IG51bGwpIHsKLSAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICB9Ci0gICAgICAgICBTdHJpbmcgdGVtcFtdID0gYWxsb3dlZFByb3RvY29scy5zcGxpdCgiLCIpOwotICAgICAgICAgZm9yIChTdHJpbmcgdCA6IHRlbXApIHsKLSAgICAgICAgICAgICB0ID0gdC50cmltKCk7Ci0gICAgICAgICAgICAgaWYgKHQuZXF1YWxzSWdub3JlQ2FzZShwcm90b2NvbCkpIHsKLSAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICAgfQotICAgICAgICAgfQotICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZWFkIEpBWFAgc3lzdGVtIHByb3BlcnR5IGluIHRoaXMgb3JkZXI6IHN5c3RlbSBwcm9wZXJ0eSwKLSAgICAgKiAkamF2YS5ob21lL2xpYi9qYXhwLnByb3BlcnRpZXMgaWYgdGhlIHN5c3RlbSBwcm9wZXJ0eSBpcyBub3Qgc3BlY2lmaWVkCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcHJvcGVydHlJZCB0aGUgSWQgb2YgdGhlIHByb3BlcnR5Ci0gICAgICogQHJldHVybiB0aGUgdmFsdWUgb2YgdGhlIHByb3BlcnR5Ci0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0SkFYUFN5c3RlbVByb3BlcnR5KFN0cmluZyBzeXNQcm9wZXJ0eUlkKSB7Ci0gICAgICAgIFN0cmluZyBhY2Nlc3NFeHRlcm5hbCA9IGdldFN5c3RlbVByb3BlcnR5KHN5c1Byb3BlcnR5SWQpOwotICAgICAgICBpZiAoYWNjZXNzRXh0ZXJuYWwgPT0gbnVsbCkgewotICAgICAgICAgICAgYWNjZXNzRXh0ZXJuYWwgPSByZWFkSkFYUFByb3BlcnR5KHN5c1Byb3BlcnR5SWQpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBhY2Nlc3NFeHRlcm5hbDsKLSAgICB9Ci0KLSAgICAgLyoqCi0gICAgICogUmVhZCBmcm9tICRqYXZhLmhvbWUvbGliL2pheHAucHJvcGVydGllcyBmb3IgdGhlIHNwZWNpZmllZCBwcm9wZXJ0eQotICAgICAqIFRoZSBwcm9ncmFtCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcHJvcGVydHlJZCB0aGUgSWQgb2YgdGhlIHByb3BlcnR5Ci0gICAgICogQHJldHVybiB0aGUgdmFsdWUgb2YgdGhlIHByb3BlcnR5Ci0gICAgICovCi0gICAgc3RhdGljIFN0cmluZyByZWFkSkFYUFByb3BlcnR5KFN0cmluZyBwcm9wZXJ0eUlkKSB7Ci0gICAgICAgIFN0cmluZyB2YWx1ZSA9IG51bGw7Ci0gICAgICAgIElucHV0U3RyZWFtIGlzID0gbnVsbDsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGlmIChmaXJzdFRpbWUpIHsKLSAgICAgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKGNhY2hlUHJvcHMpIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGZpcnN0VGltZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGNvbmZpZ0ZpbGUgPSBnZXRTeXN0ZW1Qcm9wZXJ0eSgiamF2YS5ob21lIikgKyBGaWxlLnNlcGFyYXRvciArCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgImxpYiIgKyBGaWxlLnNlcGFyYXRvciArICJqYXhwLnByb3BlcnRpZXMiOwotICAgICAgICAgICAgICAgICAgICAgICAgRmlsZSBmID0gbmV3IEZpbGUoY29uZmlnRmlsZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZ2V0RmlsZUV4aXN0cyhmKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzID0gZ2V0RmlsZUlucHV0U3RyZWFtKGYpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhY2hlUHJvcHMubG9hZChpcyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBmaXJzdFRpbWUgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHZhbHVlID0gY2FjaGVQcm9wcy5nZXRQcm9wZXJ0eShwcm9wZXJ0eUlkKTsKLQotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpIHt9Ci0gICAgICAgIGZpbmFsbHkgewotICAgICAgICAgICAgaWYgKGlzICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICBpcy5jbG9zZSgpOwotICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7fQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIHZhbHVlOwotICAgIH0KLQotICAgLyoqCi0gICAgICogQ2FjaGUgZm9yIHByb3BlcnRpZXMgaW4gamF2YS5ob21lL2xpYi9qYXhwLnByb3BlcnRpZXMKLSAgICAgKi8KLSAgICBzdGF0aWMgZmluYWwgUHJvcGVydGllcyBjYWNoZVByb3BzID0gbmV3IFByb3BlcnRpZXMoKTsKLQotICAgIC8qKgotICAgICAqIEZsYWcgaW5kaWNhdGluZyBpZiB0aGUgcHJvZ3JhbSBoYXMgdHJpZWQgcmVhZGluZyBqYXZhLmhvbWUvbGliL2pheHAucHJvcGVydGllcwotICAgICAqLwotICAgIHN0YXRpYyB2b2xhdGlsZSBib29sZWFuIGZpcnN0VGltZSA9IHRydWU7Ci0KLSAgICBwcml2YXRlIFNlY3VyaXR5U3VwcG9ydCAoKSB7fQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbHMvWE1MTGltaXRBbmFseXplci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbHMvWE1MTGltaXRBbmFseXplci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4ZGZlNmM3Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3V0aWxzL1hNTExpbWl0QW5hbHl6ZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI2NCArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEhFQURFUi4KLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMTMsIDIwMTYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKgotICogVGhlIGNvbnRlbnRzIG9mIHRoaXMgZmlsZSBhcmUgc3ViamVjdCB0byB0aGUgdGVybXMgb2YgZWl0aGVyIHRoZSBHTlUKLSAqIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgVmVyc2lvbiAyIG9ubHkgKCJHUEwiKSBvciB0aGUgQ29tbW9uIERldmVsb3BtZW50Ci0gKiBhbmQgRGlzdHJpYnV0aW9uIExpY2Vuc2UoIkNEREwiKSAoY29sbGVjdGl2ZWx5LCB0aGUgIkxpY2Vuc2UiKS4gIFlvdQotICogbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgY2FuCi0gKiBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKiBodHRwczovL2dsYXNzZmlzaC5kZXYuamF2YS5uZXQvcHVibGljL0NEREwrR1BMXzFfMS5odG1sCi0gKiBvciBwYWNrYWdlci9sZWdhbC9MSUNFTlNFLnR4dC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljCi0gKiBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICoKLSAqIFdoZW4gZGlzdHJpYnV0aW5nIHRoZSBzb2Z0d2FyZSwgaW5jbHVkZSB0aGlzIExpY2Vuc2UgSGVhZGVyIE5vdGljZSBpbiBlYWNoCi0gKiBmaWxlIGFuZCBpbmNsdWRlIHRoZSBMaWNlbnNlIGZpbGUgYXQgcGFja2FnZXIvbGVnYWwvTElDRU5TRS50eHQuCi0gKgotICogR1BMIENsYXNzcGF0aCBFeGNlcHRpb246Ci0gKiBPcmFjbGUgZGVzaWduYXRlcyB0aGlzIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIgotICogZXhjZXB0aW9uIGFzIHByb3ZpZGVkIGJ5IE9yYWNsZSBpbiB0aGUgR1BMIFZlcnNpb24gMiBzZWN0aW9uIG9mIHRoZSBMaWNlbnNlCi0gKiBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIE1vZGlmaWNhdGlvbnM6Ci0gKiBJZiBhcHBsaWNhYmxlLCBhZGQgdGhlIGZvbGxvd2luZyBiZWxvdyB0aGUgTGljZW5zZSBIZWFkZXIsIHdpdGggdGhlIGZpZWxkcwotICogZW5jbG9zZWQgYnkgYnJhY2tldHMgW10gcmVwbGFjZWQgYnkgeW91ciBvd24gaWRlbnRpZnlpbmcgaW5mb3JtYXRpb246Ci0gKiAiUG9ydGlvbnMgQ29weXJpZ2h0IFt5ZWFyXSBbbmFtZSBvZiBjb3B5cmlnaHQgb3duZXJdIgotICoKLSAqIENvbnRyaWJ1dG9yKHMpOgotICogSWYgeW91IHdpc2ggeW91ciB2ZXJzaW9uIG9mIHRoaXMgZmlsZSB0byBiZSBnb3Zlcm5lZCBieSBvbmx5IHRoZSBDRERMIG9yCi0gKiBvbmx5IHRoZSBHUEwgVmVyc2lvbiAyLCBpbmRpY2F0ZSB5b3VyIGRlY2lzaW9uIGJ5IGFkZGluZyAiW0NvbnRyaWJ1dG9yXQotICogZWxlY3RzIHRvIGluY2x1ZGUgdGhpcyBzb2Z0d2FyZSBpbiB0aGlzIGRpc3RyaWJ1dGlvbiB1bmRlciB0aGUgW0NEREwgb3IgR1BMCi0gKiBWZXJzaW9uIDJdIGxpY2Vuc2UuIiAgSWYgeW91IGRvbid0IGluZGljYXRlIGEgc2luZ2xlIGNob2ljZSBvZiBsaWNlbnNlLCBhCi0gKiByZWNpcGllbnQgaGFzIHRoZSBvcHRpb24gdG8gZGlzdHJpYnV0ZSB5b3VyIHZlcnNpb24gb2YgdGhpcyBmaWxlIHVuZGVyCi0gKiBlaXRoZXIgdGhlIENEREwsIHRoZSBHUEwgVmVyc2lvbiAyIG9yIHRvIGV4dGVuZCB0aGUgY2hvaWNlIG9mIGxpY2Vuc2UgdG8KLSAqIGl0cyBsaWNlbnNlZXMgYXMgcHJvdmlkZWQgYWJvdmUuICBIb3dldmVyLCBpZiB5b3UgYWRkIEdQTCBWZXJzaW9uIDIgY29kZQotICogYW5kIHRoZXJlZm9yZSwgZWxlY3RlZCB0aGUgR1BMIFZlcnNpb24gMiBsaWNlbnNlLCB0aGVuIHRoZSBvcHRpb24gYXBwbGllcwotICogb25seSBpZiB0aGUgbmV3IGNvZGUgaXMgbWFkZSBzdWJqZWN0IHRvIHN1Y2ggb3B0aW9uIGJ5IHRoZSBjb3B5cmlnaHQKLSAqIGhvbGRlci4KLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWxzOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLkNvbnN0YW50czsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWxzLlhNTFNlY3VyaXR5TWFuYWdlci5MaW1pdDsKLWltcG9ydCBqYXZhLnV0aWwuRm9ybWF0dGVyOwotaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwotaW1wb3J0IGphdmEudXRpbC5NYXA7Ci0KLS8qKgotICogQSBoZWxwZXIgZm9yIGFuYWx5emluZyBlbnRpdHkgZXhwYW5zaW9uIGxpbWl0cwotICoKLSAqIEBhdXRob3IgSm9lIFdhbmcgT3JhY2xlIENvcnAuCi0gKgotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgWE1MTGltaXRBbmFseXplciB7Ci0KLSAgICAvKioKLSAgICAgKiBNYXAgb2xkIHByb3BlcnR5IG5hbWVzIHdpdGggdGhlIG5ldyBvbmVzCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBlbnVtIE5hbWVNYXAgewotICAgICAgICBFTlRJVFlfRVhQQU5TSU9OX0xJTUlUKENvbnN0YW50cy5TUF9FTlRJVFlfRVhQQU5TSU9OX0xJTUlULCBDb25zdGFudHMuRU5USVRZX0VYUEFOU0lPTl9MSU1JVCksCi0gICAgICAgIE1BWF9PQ0NVUl9OT0RFX0xJTUlUKENvbnN0YW50cy5TUF9NQVhfT0NDVVJfTElNSVQsIENvbnN0YW50cy5NQVhfT0NDVVJfTElNSVQpLAotICAgICAgICBFTEVNRU5UX0FUVFJJQlVURV9MSU1JVChDb25zdGFudHMuU1BfRUxFTUVOVF9BVFRSSUJVVEVfTElNSVQsIENvbnN0YW50cy5FTEVNRU5UX0FUVFJJQlVURV9MSU1JVCk7Ci0KLSAgICAgICAgZmluYWwgU3RyaW5nIG5ld05hbWU7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBvbGROYW1lOwotCi0gICAgICAgIE5hbWVNYXAoU3RyaW5nIG5ld05hbWUsIFN0cmluZyBvbGROYW1lKSB7Ci0gICAgICAgICAgICB0aGlzLm5ld05hbWUgPSBuZXdOYW1lOwotICAgICAgICAgICAgdGhpcy5vbGROYW1lID0gb2xkTmFtZTsKLSAgICAgICAgfQotCi0gICAgICAgIFN0cmluZyBnZXRPbGROYW1lKFN0cmluZyBuZXdOYW1lKSB7Ci0gICAgICAgICAgICBpZiAobmV3TmFtZS5lcXVhbHModGhpcy5uZXdOYW1lKSkgewotICAgICAgICAgICAgICAgIHJldHVybiBvbGROYW1lOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBNYXggdmFsdWUgYWNjdW11bGF0ZWQgZm9yIGVhY2ggcHJvcGVydHkKLSAgICAgKi8KLSAgICBwcml2YXRlIGZpbmFsIGludFtdIHZhbHVlczsKLSAgICAvKioKLSAgICAgKiBOYW1lcyBvZiB0aGUgZW50aXRpZXMgY29ycmVzcG9uZGluZyB0byB0aGVpciBtYXggdmFsdWVzCi0gICAgICovCi0gICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmdbXSBuYW1lczsKLSAgICAvKioKLSAgICAgKiBUb3RhbCB2YWx1ZSBvZiBhY2N1bXVsYXRlZCBlbnRpdGllcwotICAgICAqLwotICAgIHByaXZhdGUgZmluYWwgaW50W10gdG90YWxWYWx1ZTsKLQotICAgIC8qKgotICAgICAqIE1haW50YWluIHZhbHVlcyBvZiB0aGUgdG9wIDEwIGVsZW1lbnRzIGluIHRoZSBwcm9jZXNzIG9mIHBhcnNpbmcKLSAgICAgKi8KLSAgICBwcml2YXRlIGZpbmFsIE1hcFtdIGNhY2hlczsKLQotICAgIHByaXZhdGUgU3RyaW5nIGVudGl0eVN0YXJ0LCBlbnRpdHlFbmQ7Ci0gICAgLyoqCi0gICAgICogRGVmYXVsdCBjb25zdHJ1Y3Rvci4gRXN0YWJsaXNoZXMgZGVmYXVsdCB2YWx1ZXMgZm9yIGtub3duIHNlY3VyaXR5Ci0gICAgICogdnVsbmVyYWJpbGl0aWVzLgotICAgICAqLwotICAgIHB1YmxpYyBYTUxMaW1pdEFuYWx5emVyKCkgewotICAgICAgICB2YWx1ZXMgPSBuZXcgaW50W0xpbWl0LnZhbHVlcygpLmxlbmd0aF07Ci0gICAgICAgIHRvdGFsVmFsdWUgPSBuZXcgaW50W0xpbWl0LnZhbHVlcygpLmxlbmd0aF07Ci0gICAgICAgIG5hbWVzID0gbmV3IFN0cmluZ1tMaW1pdC52YWx1ZXMoKS5sZW5ndGhdOwotICAgICAgICBjYWNoZXMgPSBuZXcgTWFwW0xpbWl0LnZhbHVlcygpLmxlbmd0aF07Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQWRkIHRoZSB2YWx1ZSB0byB0aGUgY3VycmVudCBtYXggY291bnQgZm9yIHRoZSBzcGVjaWZpZWQgcHJvcGVydHkKLSAgICAgKiBUbyBmaW5kIHRoZSBtYXggdmFsdWUgb2YgYWxsIGVudGl0aWVzLCBzZXQgbm8gbGltaXQKLSAgICAgKgotICAgICAqIEBwYXJhbSBsaW1pdCB0aGUgdHlwZSBvZiB0aGUgcHJvcGVydHkKLSAgICAgKiBAcGFyYW0gZW50aXR5TmFtZSB0aGUgbmFtZSBvZiB0aGUgZW50aXR5Ci0gICAgICogQHBhcmFtIHZhbHVlIHRoZSB2YWx1ZSBvZiB0aGUgZW50aXR5Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgYWRkVmFsdWUoTGltaXQgbGltaXQsIFN0cmluZyBlbnRpdHlOYW1lLCBpbnQgdmFsdWUpIHsKLSAgICAgICAgYWRkVmFsdWUobGltaXQub3JkaW5hbCgpLCBlbnRpdHlOYW1lLCB2YWx1ZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQWRkIHRoZSB2YWx1ZSB0byB0aGUgY3VycmVudCBjb3VudCBieSB0aGUgaW5kZXggb2YgdGhlIHByb3BlcnR5Ci0gICAgICogQHBhcmFtIGluZGV4IHRoZSBpbmRleCBvZiB0aGUgcHJvcGVydHkKLSAgICAgKiBAcGFyYW0gZW50aXR5TmFtZSB0aGUgbmFtZSBvZiB0aGUgZW50aXR5Ci0gICAgICogQHBhcmFtIHZhbHVlIHRoZSB2YWx1ZSBvZiB0aGUgZW50aXR5Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgYWRkVmFsdWUoaW50IGluZGV4LCBTdHJpbmcgZW50aXR5TmFtZSwgaW50IHZhbHVlKSB7Ci0gICAgICAgIGlmIChpbmRleCA9PSBMaW1pdC5FTlRJVFlfRVhQQU5TSU9OX0xJTUlULm9yZGluYWwoKSB8fAotICAgICAgICAgICAgICAgIGluZGV4ID09IExpbWl0Lk1BWF9PQ0NVUl9OT0RFX0xJTUlULm9yZGluYWwoKSB8fAotICAgICAgICAgICAgICAgIGluZGV4ID09IExpbWl0LkVMRU1FTlRfQVRUUklCVVRFX0xJTUlULm9yZGluYWwoKSB8fAotICAgICAgICAgICAgICAgIGluZGV4ID09IExpbWl0LlRPVEFMX0VOVElUWV9TSVpFX0xJTUlULm9yZGluYWwoKSB8fAotICAgICAgICAgICAgICAgIGluZGV4ID09IExpbWl0LkVOVElUWV9SRVBMQUNFTUVOVF9MSU1JVC5vcmRpbmFsKCkKLSAgICAgICAgICAgICAgICApIHsKLSAgICAgICAgICAgIHRvdGFsVmFsdWVbaW5kZXhdICs9IHZhbHVlOwotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0gICAgICAgIGlmIChpbmRleCA9PSBMaW1pdC5NQVhfRUxFTUVOVF9ERVBUSF9MSU1JVC5vcmRpbmFsKCkgfHwKLSAgICAgICAgICAgICAgICBpbmRleCA9PSBMaW1pdC5NQVhfTkFNRV9MSU1JVC5vcmRpbmFsKCkpIHsKLSAgICAgICAgICAgIHZhbHVlc1tpbmRleF0gPSB2YWx1ZTsKLSAgICAgICAgICAgIHRvdGFsVmFsdWVbaW5kZXhdID0gdmFsdWU7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLQotICAgICAgICBNYXA8U3RyaW5nLCBJbnRlZ2VyPiBjYWNoZTsKLSAgICAgICAgaWYgKGNhY2hlc1tpbmRleF0gPT0gbnVsbCkgewotICAgICAgICAgICAgY2FjaGUgPSBuZXcgSGFzaE1hcDw+KDEwKTsKLSAgICAgICAgICAgIGNhY2hlc1tpbmRleF0gPSBjYWNoZTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIGNhY2hlID0gY2FjaGVzW2luZGV4XTsKLSAgICAgICAgfQotCi0gICAgICAgIGludCBhY2N1bXVsYXRlZFZhbHVlID0gdmFsdWU7Ci0gICAgICAgIGlmIChjYWNoZS5jb250YWluc0tleShlbnRpdHlOYW1lKSkgewotICAgICAgICAgICAgYWNjdW11bGF0ZWRWYWx1ZSArPSBjYWNoZS5nZXQoZW50aXR5TmFtZSk7Ci0gICAgICAgICAgICBjYWNoZS5wdXQoZW50aXR5TmFtZSwgYWNjdW11bGF0ZWRWYWx1ZSk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBjYWNoZS5wdXQoZW50aXR5TmFtZSwgdmFsdWUpOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKGFjY3VtdWxhdGVkVmFsdWUgPiB2YWx1ZXNbaW5kZXhdKSB7Ci0gICAgICAgICAgICB2YWx1ZXNbaW5kZXhdID0gYWNjdW11bGF0ZWRWYWx1ZTsKLSAgICAgICAgICAgIG5hbWVzW2luZGV4XSA9IGVudGl0eU5hbWU7Ci0gICAgICAgIH0KLQotCi0gICAgICAgIGlmIChpbmRleCA9PSBMaW1pdC5HRU5FUkFMX0VOVElUWV9TSVpFX0xJTUlULm9yZGluYWwoKSB8fAotICAgICAgICAgICAgICAgIGluZGV4ID09IExpbWl0LlBBUkFNRVRFUl9FTlRJVFlfU0laRV9MSU1JVC5vcmRpbmFsKCkpIHsKLSAgICAgICAgICAgIHRvdGFsVmFsdWVbTGltaXQuVE9UQUxfRU5USVRZX1NJWkVfTElNSVQub3JkaW5hbCgpXSArPSB2YWx1ZTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybiB0aGUgdmFsdWUgb2YgdGhlIGN1cnJlbnQgbWF4IGNvdW50IGZvciB0aGUgc3BlY2lmaWVkIHByb3BlcnR5Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gbGltaXQgdGhlIHByb3BlcnR5Ci0gICAgICogQHJldHVybiB0aGUgdmFsdWUgb2YgdGhlIHByb3BlcnR5Ci0gICAgICovCi0gICAgcHVibGljIGludCBnZXRWYWx1ZShMaW1pdCBsaW1pdCkgewotICAgICAgICByZXR1cm4gZ2V0VmFsdWUobGltaXQub3JkaW5hbCgpKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldFZhbHVlKGludCBpbmRleCkgewotICAgICAgICBpZiAoaW5kZXggPT0gTGltaXQuRU5USVRZX1JFUExBQ0VNRU5UX0xJTUlULm9yZGluYWwoKSkgewotICAgICAgICAgICAgcmV0dXJuIHRvdGFsVmFsdWVbaW5kZXhdOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiB2YWx1ZXNbaW5kZXhdOwotICAgIH0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIHRvdGFsIHZhbHVlIGFjY3VtdWxhdGVkIHNvIGZhcgotICAgICAqCi0gICAgICogQHBhcmFtIGxpbWl0IHRoZSBwcm9wZXJ0eQotICAgICAqIEByZXR1cm4gdGhlIGFjY3VtdWxhdGVkIHZhbHVlIG9mIHRoZSBwcm9wZXJ0eQotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0VG90YWxWYWx1ZShMaW1pdCBsaW1pdCkgewotICAgICAgICByZXR1cm4gdG90YWxWYWx1ZVtsaW1pdC5vcmRpbmFsKCldOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgZ2V0VG90YWxWYWx1ZShpbnQgaW5kZXgpIHsKLSAgICAgICAgcmV0dXJuIHRvdGFsVmFsdWVbaW5kZXhdOwotICAgIH0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIGN1cnJlbnQgbWF4IHZhbHVlIChjb3VudCBvciBsZW5ndGgpIGJ5IHRoZSBpbmRleCBvZiBhIHByb3BlcnR5Ci0gICAgICogQHBhcmFtIGluZGV4IHRoZSBpbmRleCBvZiBhIHByb3BlcnR5Ci0gICAgICogQHJldHVybiBjb3VudCBvZiBhIHByb3BlcnR5Ci0gICAgICovCi0gICAgcHVibGljIGludCBnZXRWYWx1ZUJ5SW5kZXgoaW50IGluZGV4KSB7Ci0gICAgICAgIHJldHVybiB2YWx1ZXNbaW5kZXhdOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RW50aXR5KFN0cmluZyBuYW1lKSB7Ci0gICAgICAgIGVudGl0eVN0YXJ0ID0gbmFtZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBpc1RyYWNraW5nKFN0cmluZyBuYW1lKSB7Ci0gICAgICAgIGlmIChlbnRpdHlTdGFydCA9PSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGVudGl0eVN0YXJ0LmVxdWFscyhuYW1lKTsKLSAgICB9Ci0gICAgLyoqCi0gICAgICogU3RvcCB0cmFja2luZyB0aGUgZW50aXR5Ci0gICAgICogQHBhcmFtIGxpbWl0IHRoZSBsaW1pdCBwcm9wZXJ0eQotICAgICAqIEBwYXJhbSBuYW1lIHRoZSBuYW1lIG9mIGFuIGVudGl0eQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZEVudGl0eShMaW1pdCBsaW1pdCwgU3RyaW5nIG5hbWUpIHsKLSAgICAgICAgZW50aXR5U3RhcnQgPSAiIjsKLSAgICAgICAgTWFwPFN0cmluZywgSW50ZWdlcj4gY2FjaGUgPSBjYWNoZXNbbGltaXQub3JkaW5hbCgpXTsKLSAgICAgICAgaWYgKGNhY2hlICE9IG51bGwpIHsKLSAgICAgICAgICAgIGNhY2hlLnJlbW92ZShuYW1lKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJlc2V0cyB0aGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIGxpbWl0LgotICAgICAqIEBwYXJhbSBsaW1pdCBUaGUgbGltaXQgdG8gYmUgcmVzZXQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcmVzZXQoTGltaXQgbGltaXQpIHsKLSAgICAgICAgaWYgKGxpbWl0Lm9yZGluYWwoKSA9PSBMaW1pdC5UT1RBTF9FTlRJVFlfU0laRV9MSU1JVC5vcmRpbmFsKCkpIHsKLSAgICAgICAgICAgIHRvdGFsVmFsdWVbbGltaXQub3JkaW5hbCgpXSA9IDA7Ci0gICAgICAgIH0gZWxzZSBpZiAobGltaXQub3JkaW5hbCgpID09IExpbWl0LkdFTkVSQUxfRU5USVRZX1NJWkVfTElNSVQub3JkaW5hbCgpKSB7Ci0gICAgICAgICAgICBuYW1lc1tsaW1pdC5vcmRpbmFsKCldID0gbnVsbDsKLSAgICAgICAgICAgIHZhbHVlc1tsaW1pdC5vcmRpbmFsKCldID0gMDsKLSAgICAgICAgICAgIGNhY2hlc1tsaW1pdC5vcmRpbmFsKCldID0gbnVsbDsKLSAgICAgICAgICAgIHRvdGFsVmFsdWVbbGltaXQub3JkaW5hbCgpXSA9IDA7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBkZWJ1Z1ByaW50KFhNTFNlY3VyaXR5TWFuYWdlciBzZWN1cml0eU1hbmFnZXIpIHsKLSAgICAgICAgRm9ybWF0dGVyIGZvcm1hdHRlciA9IG5ldyBGb3JtYXR0ZXIoKTsKLSAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKGZvcm1hdHRlci5mb3JtYXQoIiUzMHMgJTE1cyAlMTVzICUxNXMgJTMwcyIsCi0gICAgICAgICAgICAgICAgIlByb3BlcnR5IiwiTGltaXQiLCJUb3RhbCBzaXplIiwiU2l6ZSIsIkVudGl0eSBOYW1lIikpOwotCi0gICAgICAgIGZvciAoTGltaXQgbGltaXQgOiBMaW1pdC52YWx1ZXMoKSkgewotICAgICAgICAgICAgZm9ybWF0dGVyID0gbmV3IEZvcm1hdHRlcigpOwotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKGZvcm1hdHRlci5mb3JtYXQoIiUzMHMgJTE1ZCAlMTVkICUxNWQgJTMwcyIsCi0gICAgICAgICAgICAgICAgICAgIGxpbWl0Lm5hbWUoKSwKLSAgICAgICAgICAgICAgICAgICAgc2VjdXJpdHlNYW5hZ2VyLmdldExpbWl0KGxpbWl0KSwKLSAgICAgICAgICAgICAgICAgICAgdG90YWxWYWx1ZVtsaW1pdC5vcmRpbmFsKCldLAotICAgICAgICAgICAgICAgICAgICB2YWx1ZXNbbGltaXQub3JkaW5hbCgpXSwKLSAgICAgICAgICAgICAgICAgICAgbmFtZXNbbGltaXQub3JkaW5hbCgpXSkpOwotICAgICAgICB9Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbHMvWE1MU2VjdXJpdHlNYW5hZ2VyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlscy9YTUxTZWN1cml0eU1hbmFnZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNmY0NDE3Ny4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlscy9YTUxTZWN1cml0eU1hbmFnZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDU4MSArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDEzLCAyMDE2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbHM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5TZWN1cml0eU1hbmFnZXI7Ci1pbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuQ29weU9uV3JpdGVBcnJheUxpc3Q7Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgbWFuYWdlcyBzdGFuZGFyZCBhbmQgaW1wbGVtZW50YXRpb24tc3BlY2lmaWMgbGltaXRhdGlvbnMuCi0gKgotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgWE1MU2VjdXJpdHlNYW5hZ2VyIHsKLQotICAgIC8qKgotICAgICAqIFN0YXRlcyBvZiB0aGUgc2V0dGluZ3Mgb2YgYSBwcm9wZXJ0eSwgaW4gdGhlIG9yZGVyOiBkZWZhdWx0IHZhbHVlLCB2YWx1ZQotICAgICAqIHNldCBieSBGRUFUVVJFX1NFQ1VSRV9QUk9DRVNTSU5HLCBqYXhwLnByb3BlcnRpZXMgZmlsZSwgamF4cCBzeXN0ZW0KLSAgICAgKiBwcm9wZXJ0aWVzLCBhbmQgamF4cCBhcGkgcHJvcGVydGllcwotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZW51bSBTdGF0ZSB7Ci0gICAgICAgIC8vdGhpcyBvcmRlciByZWZsZWN0cyB0aGUgb3ZlcnJpZGluZyBvcmRlcgotCi0gICAgICAgIERFRkFVTFQoImRlZmF1bHQiKSwgRlNQKCJGRUFUVVJFX1NFQ1VSRV9QUk9DRVNTSU5HIiksCi0gICAgICAgIEpBWFBET1RQUk9QRVJUSUVTKCJqYXhwLnByb3BlcnRpZXMiKSwgU1lTVEVNUFJPUEVSVFkoInN5c3RlbSBwcm9wZXJ0eSIpLAotICAgICAgICBBUElQUk9QRVJUWSgicHJvcGVydHkiKTsKLQotICAgICAgICBmaW5hbCBTdHJpbmcgbGl0ZXJhbDsKLSAgICAgICAgU3RhdGUoU3RyaW5nIGxpdGVyYWwpIHsKLSAgICAgICAgICAgIHRoaXMubGl0ZXJhbCA9IGxpdGVyYWw7Ci0gICAgICAgIH0KLQotICAgICAgICBTdHJpbmcgbGl0ZXJhbCgpIHsKLSAgICAgICAgICAgIHJldHVybiBsaXRlcmFsOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogTGltaXRzIG1hbmFnZWQgYnkgdGhlIHNlY3VyaXR5IG1hbmFnZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGVudW0gTGltaXQgewotCi0gICAgICAgIEVOVElUWV9FWFBBTlNJT05fTElNSVQoIkVudGl0eUV4cGFuc2lvbkxpbWl0IiwKLSAgICAgICAgICAgICAgICBDb25zdGFudHMuSkRLX0VOVElUWV9FWFBBTlNJT05fTElNSVQsIENvbnN0YW50cy5TUF9FTlRJVFlfRVhQQU5TSU9OX0xJTUlULCAwLCA2NDAwMCksCi0gICAgICAgIE1BWF9PQ0NVUl9OT0RFX0xJTUlUKCJNYXhPY2N1ckxpbWl0IiwKLSAgICAgICAgICAgICAgICBDb25zdGFudHMuSkRLX01BWF9PQ0NVUl9MSU1JVCwgQ29uc3RhbnRzLlNQX01BWF9PQ0NVUl9MSU1JVCwgMCwgNTAwMCksCi0gICAgICAgIEVMRU1FTlRfQVRUUklCVVRFX0xJTUlUKCJFbGVtZW50QXR0cmlidXRlTGltaXQiLAotICAgICAgICAgICAgICAgIENvbnN0YW50cy5KREtfRUxFTUVOVF9BVFRSSUJVVEVfTElNSVQsIENvbnN0YW50cy5TUF9FTEVNRU5UX0FUVFJJQlVURV9MSU1JVCwgMCwgMTAwMDApLAotICAgICAgICBUT1RBTF9FTlRJVFlfU0laRV9MSU1JVCgiVG90YWxFbnRpdHlTaXplTGltaXQiLAotICAgICAgICAgICAgICAgIENvbnN0YW50cy5KREtfVE9UQUxfRU5USVRZX1NJWkVfTElNSVQsIENvbnN0YW50cy5TUF9UT1RBTF9FTlRJVFlfU0laRV9MSU1JVCwgMCwgNTAwMDAwMDApLAotICAgICAgICBHRU5FUkFMX0VOVElUWV9TSVpFX0xJTUlUKCJNYXhFbnRpdHlTaXplTGltaXQiLAotICAgICAgICAgICAgICAgIENvbnN0YW50cy5KREtfR0VORVJBTF9FTlRJVFlfU0laRV9MSU1JVCwgQ29uc3RhbnRzLlNQX0dFTkVSQUxfRU5USVRZX1NJWkVfTElNSVQsIDAsIDApLAotICAgICAgICBQQVJBTUVURVJfRU5USVRZX1NJWkVfTElNSVQoIk1heEVudGl0eVNpemVMaW1pdCIsCi0gICAgICAgICAgICAgICAgQ29uc3RhbnRzLkpES19QQVJBTUVURVJfRU5USVRZX1NJWkVfTElNSVQsIENvbnN0YW50cy5TUF9QQVJBTUVURVJfRU5USVRZX1NJWkVfTElNSVQsIDAsIDEwMDAwMDApLAotICAgICAgICBNQVhfRUxFTUVOVF9ERVBUSF9MSU1JVCgiTWF4RWxlbWVudERlcHRoTGltaXQiLAotICAgICAgICAgICAgICAgIENvbnN0YW50cy5KREtfTUFYX0VMRU1FTlRfREVQVEgsIENvbnN0YW50cy5TUF9NQVhfRUxFTUVOVF9ERVBUSCwgMCwgMCksCi0gICAgICAgIE1BWF9OQU1FX0xJTUlUKCJNYXhYTUxOYW1lTGltaXQiLAotICAgICAgICAgICAgICAgIENvbnN0YW50cy5KREtfWE1MX05BTUVfTElNSVQsIENvbnN0YW50cy5TUF9YTUxfTkFNRV9MSU1JVCwgMTAwMCwgMTAwMCksCi0gICAgICAgIEVOVElUWV9SRVBMQUNFTUVOVF9MSU1JVCgiRW50aXR5UmVwbGFjZW1lbnRMaW1pdCIsCi0gICAgICAgICAgICAgICAgQ29uc3RhbnRzLkpES19FTlRJVFlfUkVQTEFDRU1FTlRfTElNSVQsIENvbnN0YW50cy5TUF9FTlRJVFlfUkVQTEFDRU1FTlRfTElNSVQsIDAsIDMwMDAwMDApOwotCi0gICAgICAgIGZpbmFsIFN0cmluZyBrZXk7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBhcGlQcm9wZXJ0eTsKLSAgICAgICAgZmluYWwgU3RyaW5nIHN5c3RlbVByb3BlcnR5OwotICAgICAgICBmaW5hbCBpbnQgZGVmYXVsdFZhbHVlOwotICAgICAgICBmaW5hbCBpbnQgc2VjdXJlVmFsdWU7Ci0KLSAgICAgICAgTGltaXQoU3RyaW5nIGtleSwgU3RyaW5nIGFwaVByb3BlcnR5LCBTdHJpbmcgc3lzdGVtUHJvcGVydHksIGludCB2YWx1ZSwgaW50IHNlY3VyZVZhbHVlKSB7Ci0gICAgICAgICAgICB0aGlzLmtleSA9IGtleTsKLSAgICAgICAgICAgIHRoaXMuYXBpUHJvcGVydHkgPSBhcGlQcm9wZXJ0eTsKLSAgICAgICAgICAgIHRoaXMuc3lzdGVtUHJvcGVydHkgPSBzeXN0ZW1Qcm9wZXJ0eTsKLSAgICAgICAgICAgIHRoaXMuZGVmYXVsdFZhbHVlID0gdmFsdWU7Ci0gICAgICAgICAgICB0aGlzLnNlY3VyZVZhbHVlID0gc2VjdXJlVmFsdWU7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHNBUElQcm9wZXJ0eU5hbWUoU3RyaW5nIHByb3BlcnR5TmFtZSkgewotICAgICAgICAgICAgcmV0dXJuIChwcm9wZXJ0eU5hbWUgPT0gbnVsbCkgPyBmYWxzZSA6IGFwaVByb3BlcnR5LmVxdWFscyhwcm9wZXJ0eU5hbWUpOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzU3lzdGVtUHJvcGVydHlOYW1lKFN0cmluZyBwcm9wZXJ0eU5hbWUpIHsKLSAgICAgICAgICAgIHJldHVybiAocHJvcGVydHlOYW1lID09IG51bGwpID8gZmFsc2UgOiBzeXN0ZW1Qcm9wZXJ0eS5lcXVhbHMocHJvcGVydHlOYW1lKTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyBTdHJpbmcga2V5KCkgewotICAgICAgICAgICAgcmV0dXJuIGtleTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyBTdHJpbmcgYXBpUHJvcGVydHkoKSB7Ci0gICAgICAgICAgICByZXR1cm4gYXBpUHJvcGVydHk7Ci0gICAgICAgIH0KLQotICAgICAgICBTdHJpbmcgc3lzdGVtUHJvcGVydHkoKSB7Ci0gICAgICAgICAgICByZXR1cm4gc3lzdGVtUHJvcGVydHk7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgaW50IGRlZmF1bHRWYWx1ZSgpIHsKLSAgICAgICAgICAgIHJldHVybiBkZWZhdWx0VmFsdWU7Ci0gICAgICAgIH0KLQotICAgICAgICBpbnQgc2VjdXJlVmFsdWUoKSB7Ci0gICAgICAgICAgICByZXR1cm4gc2VjdXJlVmFsdWU7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBNYXAgb2xkIHByb3BlcnR5IG5hbWVzIHdpdGggdGhlIG5ldyBvbmVzCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBlbnVtIE5hbWVNYXAgewotCi0gICAgICAgIEVOVElUWV9FWFBBTlNJT05fTElNSVQoQ29uc3RhbnRzLlNQX0VOVElUWV9FWFBBTlNJT05fTElNSVQsIENvbnN0YW50cy5FTlRJVFlfRVhQQU5TSU9OX0xJTUlUKSwKLSAgICAgICAgTUFYX09DQ1VSX05PREVfTElNSVQoQ29uc3RhbnRzLlNQX01BWF9PQ0NVUl9MSU1JVCwgQ29uc3RhbnRzLk1BWF9PQ0NVUl9MSU1JVCksCi0gICAgICAgIEVMRU1FTlRfQVRUUklCVVRFX0xJTUlUKENvbnN0YW50cy5TUF9FTEVNRU5UX0FUVFJJQlVURV9MSU1JVCwgQ29uc3RhbnRzLkVMRU1FTlRfQVRUUklCVVRFX0xJTUlUKTsKLSAgICAgICAgZmluYWwgU3RyaW5nIG5ld05hbWU7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBvbGROYW1lOwotCi0gICAgICAgIE5hbWVNYXAoU3RyaW5nIG5ld05hbWUsIFN0cmluZyBvbGROYW1lKSB7Ci0gICAgICAgICAgICB0aGlzLm5ld05hbWUgPSBuZXdOYW1lOwotICAgICAgICAgICAgdGhpcy5vbGROYW1lID0gb2xkTmFtZTsKLSAgICAgICAgfQotCi0gICAgICAgIFN0cmluZyBnZXRPbGROYW1lKFN0cmluZyBuZXdOYW1lKSB7Ci0gICAgICAgICAgICBpZiAobmV3TmFtZS5lcXVhbHModGhpcy5uZXdOYW1lKSkgewotICAgICAgICAgICAgICAgIHJldHVybiBvbGROYW1lOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLSAgICB9Ci0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE5PX0xJTUlUID0gMDsKLSAgICAvKioKLSAgICAgKiBWYWx1ZXMgb2YgdGhlIHByb3BlcnRpZXMKLSAgICAgKi8KLSAgICBwcml2YXRlIGZpbmFsIGludFtdIHZhbHVlczsKLSAgICAvKioKLSAgICAgKiBTdGF0ZXMgb2YgdGhlIHNldHRpbmdzIGZvciBlYWNoIHByb3BlcnR5Ci0gICAgICovCi0gICAgcHJpdmF0ZSBTdGF0ZVtdIHN0YXRlczsKLSAgICAvKioKLSAgICAgKiBGbGFnIGluZGljYXRpbmcgaWYgc2VjdXJlIHByb2Nlc3NpbmcgaXMgc2V0Ci0gICAgICovCi0gICAgYm9vbGVhbiBzZWN1cmVQcm9jZXNzaW5nOwotCi0gICAgLyoqCi0gICAgICogU3RhdGVzIHRoYXQgZGV0ZXJtaW5lIGlmIHByb3BlcnRpZXMgYXJlIHNldCBleHBsaWNpdGx5Ci0gICAgICovCi0gICAgcHJpdmF0ZSBib29sZWFuW10gaXNTZXQ7Ci0KLQotICAgIC8qKgotICAgICAqIEluZGV4IG9mIHRoZSBzcGVjaWFsIGVudGl0eUNvdW50SW5mbyBwcm9wZXJ0eQotICAgICAqLwotICAgIHByaXZhdGUgZmluYWwgaW50IGluZGV4RW50aXR5Q291bnRJbmZvID0gMTAwMDA7Ci0gICAgcHJpdmF0ZSBTdHJpbmcgcHJpbnRFbnRpdHlDb3VudEluZm8gPSAiIjsKLQotICAgIC8qKgotICAgICAqIERlZmF1bHQgY29uc3RydWN0b3IuIEVzdGFibGlzaGVzIGRlZmF1bHQgdmFsdWVzIGZvciBrbm93biBzZWN1cml0eQotICAgICAqIHZ1bG5lcmFiaWxpdGllcy4KLSAgICAgKi8KLSAgICBwdWJsaWMgWE1MU2VjdXJpdHlNYW5hZ2VyKCkgewotICAgICAgICB0aGlzKGZhbHNlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJbnN0YW50aWF0ZSBTZWN1cml0eSBNYW5hZ2VyIGluIGFjY29yZGFuY2Ugd2l0aCB0aGUgc3RhdHVzIG9mCi0gICAgICogc2VjdXJlIHByb2Nlc3NpbmcKLSAgICAgKiBAcGFyYW0gc2VjdXJlUHJvY2Vzc2luZwotICAgICAqLwotICAgIHB1YmxpYyBYTUxTZWN1cml0eU1hbmFnZXIoYm9vbGVhbiBzZWN1cmVQcm9jZXNzaW5nKSB7Ci0gICAgICAgIHZhbHVlcyA9IG5ldyBpbnRbTGltaXQudmFsdWVzKCkubGVuZ3RoXTsKLSAgICAgICAgc3RhdGVzID0gbmV3IFN0YXRlW0xpbWl0LnZhbHVlcygpLmxlbmd0aF07Ci0gICAgICAgIGlzU2V0ID0gbmV3IGJvb2xlYW5bTGltaXQudmFsdWVzKCkubGVuZ3RoXTsKLSAgICAgICAgdGhpcy5zZWN1cmVQcm9jZXNzaW5nID0gc2VjdXJlUHJvY2Vzc2luZzsKLSAgICAgICAgZm9yIChMaW1pdCBsaW1pdCA6IExpbWl0LnZhbHVlcygpKSB7Ci0gICAgICAgICAgICBpZiAoc2VjdXJlUHJvY2Vzc2luZykgewotICAgICAgICAgICAgICAgIHZhbHVlc1tsaW1pdC5vcmRpbmFsKCldID0gbGltaXQuc2VjdXJlVmFsdWU7Ci0gICAgICAgICAgICAgICAgc3RhdGVzW2xpbWl0Lm9yZGluYWwoKV0gPSBTdGF0ZS5GU1A7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIHZhbHVlc1tsaW1pdC5vcmRpbmFsKCldID0gbGltaXQuZGVmYXVsdFZhbHVlKCk7Ci0gICAgICAgICAgICAgICAgc3RhdGVzW2xpbWl0Lm9yZGluYWwoKV0gPSBTdGF0ZS5ERUZBVUxUOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIC8vcmVhZCBzeXN0ZW0gcHJvcGVydGllcyBvciBqYXhwLnByb3BlcnRpZXMKLSAgICAgICAgcmVhZFN5c3RlbVByb3BlcnRpZXMoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXR0aW5nIEZFQVRVUkVfU0VDVVJFX1BST0NFU1NJTkcgZXhwbGljaXRseQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFNlY3VyZVByb2Nlc3NpbmcoYm9vbGVhbiBzZWN1cmUpIHsKLSAgICAgICAgc2VjdXJlUHJvY2Vzc2luZyA9IHNlY3VyZTsKLSAgICAgICAgZm9yIChMaW1pdCBsaW1pdCA6IExpbWl0LnZhbHVlcygpKSB7Ci0gICAgICAgICAgICBpZiAoc2VjdXJlKSB7Ci0gICAgICAgICAgICAgICAgc2V0TGltaXQobGltaXQub3JkaW5hbCgpLCBTdGF0ZS5GU1AsIGxpbWl0LnNlY3VyZVZhbHVlKCkpOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBzZXRMaW1pdChsaW1pdC5vcmRpbmFsKCksIFN0YXRlLkZTUCwgbGltaXQuZGVmYXVsdFZhbHVlKCkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSBzdGF0ZSBvZiBzZWN1cmUgcHJvY2Vzc2luZwotICAgICAqIEByZXR1cm4gdGhlIHN0YXRlIG9mIHNlY3VyZSBwcm9jZXNzaW5nCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNTZWN1cmVQcm9jZXNzaW5nKCkgewotICAgICAgICByZXR1cm4gc2VjdXJlUHJvY2Vzc2luZzsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFNldCBsaW1pdCBieSBwcm9wZXJ0eSBuYW1lIGFuZCBzdGF0ZQotICAgICAqIEBwYXJhbSBwcm9wZXJ0eU5hbWUgcHJvcGVydHkgbmFtZQotICAgICAqIEBwYXJhbSBzdGF0ZSB0aGUgc3RhdGUgb2YgdGhlIHByb3BlcnR5Ci0gICAgICogQHBhcmFtIHZhbHVlIHRoZSB2YWx1ZSBvZiB0aGUgcHJvcGVydHkKLSAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHByb3BlcnR5IGlzIG1hbmFnZWQgYnkgdGhlIHNlY3VyaXR5IG1hbmFnZXI7IGZhbHNlCi0gICAgICogICAgICAgICAgICAgIGlmIG90aGVyd2lzZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBzZXRMaW1pdChTdHJpbmcgcHJvcGVydHlOYW1lLCBTdGF0ZSBzdGF0ZSwgT2JqZWN0IHZhbHVlKSB7Ci0gICAgICAgIGludCBpbmRleCA9IGdldEluZGV4KHByb3BlcnR5TmFtZSk7Ci0gICAgICAgIGlmIChpbmRleCA+IC0xKSB7Ci0gICAgICAgICAgICBzZXRMaW1pdChpbmRleCwgc3RhdGUsIHZhbHVlKTsKLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIHZhbHVlIGZvciBhIHNwZWNpZmljIGxpbWl0LgotICAgICAqCi0gICAgICogQHBhcmFtIGxpbWl0IHRoZSBsaW1pdAotICAgICAqIEBwYXJhbSBzdGF0ZSB0aGUgc3RhdGUgb2YgdGhlIHByb3BlcnR5Ci0gICAgICogQHBhcmFtIHZhbHVlIHRoZSB2YWx1ZSBvZiB0aGUgcHJvcGVydHkKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRMaW1pdChMaW1pdCBsaW1pdCwgU3RhdGUgc3RhdGUsIGludCB2YWx1ZSkgewotICAgICAgICBzZXRMaW1pdChsaW1pdC5vcmRpbmFsKCksIHN0YXRlLCB2YWx1ZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSB2YWx1ZSBvZiBhIHByb3BlcnR5IGJ5IGl0cyBpbmRleAotICAgICAqCi0gICAgICogQHBhcmFtIGluZGV4IHRoZSBpbmRleCBvZiB0aGUgcHJvcGVydHkKLSAgICAgKiBAcGFyYW0gc3RhdGUgdGhlIHN0YXRlIG9mIHRoZSBwcm9wZXJ0eQotICAgICAqIEBwYXJhbSB2YWx1ZSB0aGUgdmFsdWUgb2YgdGhlIHByb3BlcnR5Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0TGltaXQoaW50IGluZGV4LCBTdGF0ZSBzdGF0ZSwgT2JqZWN0IHZhbHVlKSB7Ci0gICAgICAgIGlmIChpbmRleCA9PSBpbmRleEVudGl0eUNvdW50SW5mbykgewotICAgICAgICAgICAgcHJpbnRFbnRpdHlDb3VudEluZm8gPSAoU3RyaW5nKXZhbHVlOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgaW50IHRlbXA7Ci0gICAgICAgICAgICBpZiAoSW50ZWdlci5jbGFzcy5pc0Fzc2lnbmFibGVGcm9tKHZhbHVlLmdldENsYXNzKCkpKSB7Ci0gICAgICAgICAgICAgICAgdGVtcCA9ICgoSW50ZWdlcil2YWx1ZSkuaW50VmFsdWUoKTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgdGVtcCA9IEludGVnZXIucGFyc2VJbnQoKFN0cmluZykgdmFsdWUpOwotICAgICAgICAgICAgICAgIGlmICh0ZW1wIDwgMCkgewotICAgICAgICAgICAgICAgICAgICB0ZW1wID0gMDsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBzZXRMaW1pdChpbmRleCwgc3RhdGUsIHRlbXApOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSB2YWx1ZSBvZiBhIHByb3BlcnR5IGJ5IGl0cyBpbmRleAotICAgICAqCi0gICAgICogQHBhcmFtIGluZGV4IHRoZSBpbmRleCBvZiB0aGUgcHJvcGVydHkKLSAgICAgKiBAcGFyYW0gc3RhdGUgdGhlIHN0YXRlIG9mIHRoZSBwcm9wZXJ0eQotICAgICAqIEBwYXJhbSB2YWx1ZSB0aGUgdmFsdWUgb2YgdGhlIHByb3BlcnR5Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0TGltaXQoaW50IGluZGV4LCBTdGF0ZSBzdGF0ZSwgaW50IHZhbHVlKSB7Ci0gICAgICAgIGlmIChpbmRleCA9PSBpbmRleEVudGl0eUNvdW50SW5mbykgewotICAgICAgICAgICAgLy9pZiBpdCdzIGV4cGxpY2l0bHkgc2V0LCBpdCdzIHRyZWF0ZWQgYXMgeWVzIG5vIG1hdHRlciB0aGUgdmFsdWUKLSAgICAgICAgICAgIHByaW50RW50aXR5Q291bnRJbmZvID0gQ29uc3RhbnRzLkpES19ZRVM7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAvL29ubHkgdXBkYXRlIGlmIGl0IHNoYWxsIG92ZXJyaWRlCi0gICAgICAgICAgICBpZiAoc3RhdGUuY29tcGFyZVRvKHN0YXRlc1tpbmRleF0pID49IDApIHsKLSAgICAgICAgICAgICAgICB2YWx1ZXNbaW5kZXhdID0gdmFsdWU7Ci0gICAgICAgICAgICAgICAgc3RhdGVzW2luZGV4XSA9IHN0YXRlOwotICAgICAgICAgICAgICAgIGlzU2V0W2luZGV4XSA9IHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgcHJvcGVydHkKLSAgICAgKgotICAgICAqIEBwYXJhbSBwcm9wZXJ0eU5hbWUgdGhlIHByb3BlcnR5IG5hbWUKLSAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgcHJvcGVydHkgYXMgYSBzdHJpbmcuIElmIGEgcHJvcGVydHkgaXMgbWFuYWdlZAotICAgICAqIGJ5IHRoaXMgbWFuYWdlciwgaXRzIHZhbHVlIHNoYWxsIG5vdCBiZSBudWxsLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TGltaXRBc1N0cmluZyhTdHJpbmcgcHJvcGVydHlOYW1lKSB7Ci0gICAgICAgIGludCBpbmRleCA9IGdldEluZGV4KHByb3BlcnR5TmFtZSk7Ci0gICAgICAgIGlmIChpbmRleCA+IC0xKSB7Ci0gICAgICAgICAgICByZXR1cm4gZ2V0TGltaXRWYWx1ZUJ5SW5kZXgoaW5kZXgpOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotICAgIC8qKgotICAgICAqIFJldHVybiB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBwcm9wZXJ0eQotICAgICAqCi0gICAgICogQHBhcmFtIGxpbWl0IHRoZSBwcm9wZXJ0eQotICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBwcm9wZXJ0eQotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0TGltaXQoTGltaXQgbGltaXQpIHsKLSAgICAgICAgcmV0dXJuIHZhbHVlc1tsaW1pdC5vcmRpbmFsKCldOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybiB0aGUgdmFsdWUgb2YgYSBwcm9wZXJ0eSBieSBpdHMgb3JkaW5hbAotICAgICAqCi0gICAgICogQHBhcmFtIGxpbWl0IHRoZSBwcm9wZXJ0eQotICAgICAqIEByZXR1cm4gdmFsdWUgb2YgYSBwcm9wZXJ0eQotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TGltaXRWYWx1ZUFzU3RyaW5nKExpbWl0IGxpbWl0KSB7Ci0gICAgICAgIHJldHVybiBJbnRlZ2VyLnRvU3RyaW5nKHZhbHVlc1tsaW1pdC5vcmRpbmFsKCldKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIHZhbHVlIG9mIGEgcHJvcGVydHkgYnkgaXRzIG9yZGluYWwKLSAgICAgKgotICAgICAqIEBwYXJhbSBpbmRleCB0aGUgaW5kZXggb2YgYSBwcm9wZXJ0eQotICAgICAqIEByZXR1cm4gbGltaXQgb2YgYSBwcm9wZXJ0eSBhcyBhIHN0cmluZwotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TGltaXRWYWx1ZUJ5SW5kZXgoaW50IGluZGV4KSB7Ci0gICAgICAgIGlmIChpbmRleCA9PSBpbmRleEVudGl0eUNvdW50SW5mbykgewotICAgICAgICAgICAgcmV0dXJuIHByaW50RW50aXR5Q291bnRJbmZvOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIEludGVnZXIudG9TdHJpbmcodmFsdWVzW2luZGV4XSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSBzdGF0ZSBvZiB0aGUgbGltaXQgcHJvcGVydHkKLSAgICAgKgotICAgICAqIEBwYXJhbSBsaW1pdCB0aGUgbGltaXQKLSAgICAgKiBAcmV0dXJuIHRoZSBzdGF0ZSBvZiB0aGUgbGltaXQgcHJvcGVydHkKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RhdGUgZ2V0U3RhdGUoTGltaXQgbGltaXQpIHsKLSAgICAgICAgcmV0dXJuIHN0YXRlc1tsaW1pdC5vcmRpbmFsKCldOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybiB0aGUgc3RhdGUgb2YgdGhlIGxpbWl0IHByb3BlcnR5Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gbGltaXQgdGhlIGxpbWl0Ci0gICAgICogQHJldHVybiB0aGUgc3RhdGUgb2YgdGhlIGxpbWl0IHByb3BlcnR5Ci0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRTdGF0ZUxpdGVyYWwoTGltaXQgbGltaXQpIHsKLSAgICAgICAgcmV0dXJuIHN0YXRlc1tsaW1pdC5vcmRpbmFsKCldLmxpdGVyYWwoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIGluZGV4IGJ5IHByb3BlcnR5IG5hbWUKLSAgICAgKgotICAgICAqIEBwYXJhbSBwcm9wZXJ0eU5hbWUgcHJvcGVydHkgbmFtZQotICAgICAqIEByZXR1cm4gdGhlIGluZGV4IG9mIHRoZSBwcm9wZXJ0eSBpZiBmb3VuZDsgcmV0dXJuIC0xIGlmIG5vdAotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0SW5kZXgoU3RyaW5nIHByb3BlcnR5TmFtZSkgewotICAgICAgICBmb3IgKExpbWl0IGxpbWl0IDogTGltaXQudmFsdWVzKCkpIHsKLSAgICAgICAgICAgIGlmIChsaW1pdC5lcXVhbHNBUElQcm9wZXJ0eU5hbWUocHJvcGVydHlOYW1lKSkgewotICAgICAgICAgICAgICAgIC8vaW50ZXJuYWxseSwgb3JkaW5hbCBpcyB1c2VkIGFzIGluZGV4Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGxpbWl0Lm9yZGluYWwoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICAvL3NwZWNpYWwgcHJvcGVydHkgdG8gcmV0dXJuIGVudGl0eSBjb3VudCBpbmZvCi0gICAgICAgIGlmIChwcm9wZXJ0eU5hbWUuZXF1YWxzKENvbnN0YW50cy5KREtfRU5USVRZX0NPVU5UX0lORk8pKSB7Ci0gICAgICAgICAgICByZXR1cm4gaW5kZXhFbnRpdHlDb3VudEluZm87Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIC0xOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENoZWNrIGlmIHRoZXJlJ3Mgbm8gbGltaXQgZGVmaW5lZCBieSB0aGUgU2VjdXJpdHkgTWFuYWdlcgotICAgICAqIEBwYXJhbSBsaW1pdAotICAgICAqIEByZXR1cm4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc05vTGltaXQoaW50IGxpbWl0KSB7Ci0gICAgICAgIHJldHVybiBsaW1pdD09Tk9fTElNSVQ7Ci0gICAgfQotICAgIC8qKgotICAgICAqIENoZWNrIGlmIHRoZSBzaXplIChsZW5ndGggb3IgY291bnQpIG9mIHRoZSBzcGVjaWZpZWQgbGltaXQgcHJvcGVydHkgaXMKLSAgICAgKiBvdmVyIHRoZSBsaW1pdAotICAgICAqCi0gICAgICogQHBhcmFtIGxpbWl0IHRoZSB0eXBlIG9mIHRoZSBsaW1pdCBwcm9wZXJ0eQotICAgICAqIEBwYXJhbSBlbnRpdHlOYW1lIHRoZSBuYW1lIG9mIHRoZSBlbnRpdHkKLSAgICAgKiBAcGFyYW0gc2l6ZSB0aGUgc2l6ZSAoY291bnQgb3IgbGVuZ3RoKSBvZiB0aGUgZW50aXR5Ci0gICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBzaXplIGlzIG92ZXIgdGhlIGxpbWl0LCBmYWxzZSBvdGhlcndpc2UKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc092ZXJMaW1pdChMaW1pdCBsaW1pdCwgU3RyaW5nIGVudGl0eU5hbWUsIGludCBzaXplLAotICAgICAgICAgICAgWE1MTGltaXRBbmFseXplciBsaW1pdEFuYWx5emVyKSB7Ci0gICAgICAgIHJldHVybiBpc092ZXJMaW1pdChsaW1pdC5vcmRpbmFsKCksIGVudGl0eU5hbWUsIHNpemUsIGxpbWl0QW5hbHl6ZXIpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENoZWNrIGlmIHRoZSB2YWx1ZSAobGVuZ3RoIG9yIGNvdW50KSBvZiB0aGUgc3BlY2lmaWVkIGxpbWl0IHByb3BlcnR5IGlzCi0gICAgICogb3ZlciB0aGUgbGltaXQKLSAgICAgKgotICAgICAqIEBwYXJhbSBpbmRleCB0aGUgaW5kZXggb2YgdGhlIGxpbWl0IHByb3BlcnR5Ci0gICAgICogQHBhcmFtIGVudGl0eU5hbWUgdGhlIG5hbWUgb2YgdGhlIGVudGl0eQotICAgICAqIEBwYXJhbSBzaXplIHRoZSBzaXplIChjb3VudCBvciBsZW5ndGgpIG9mIHRoZSBlbnRpdHkKLSAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHNpemUgaXMgb3ZlciB0aGUgbGltaXQsIGZhbHNlIG90aGVyd2lzZQotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzT3ZlckxpbWl0KGludCBpbmRleCwgU3RyaW5nIGVudGl0eU5hbWUsIGludCBzaXplLAotICAgICAgICAgICAgWE1MTGltaXRBbmFseXplciBsaW1pdEFuYWx5emVyKSB7Ci0gICAgICAgIGlmICh2YWx1ZXNbaW5kZXhdID09IE5PX0xJTUlUKSB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKHNpemUgPiB2YWx1ZXNbaW5kZXhdKSB7Ci0gICAgICAgICAgICBsaW1pdEFuYWx5emVyLmFkZFZhbHVlKGluZGV4LCBlbnRpdHlOYW1lLCBzaXplKTsKLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDaGVjayBhZ2FpbnN0IGN1bXVsYXRlZCB2YWx1ZQotICAgICAqCi0gICAgICogQHBhcmFtIGxpbWl0IHRoZSB0eXBlIG9mIHRoZSBsaW1pdCBwcm9wZXJ0eQotICAgICAqIEBwYXJhbSBzaXplIHRoZSBzaXplIChjb3VudCBvciBsZW5ndGgpIG9mIHRoZSBlbnRpdHkKLSAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHNpemUgaXMgb3ZlciB0aGUgbGltaXQsIGZhbHNlIG90aGVyd2lzZQotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzT3ZlckxpbWl0KExpbWl0IGxpbWl0LCBYTUxMaW1pdEFuYWx5emVyIGxpbWl0QW5hbHl6ZXIpIHsKLSAgICAgICAgcmV0dXJuIGlzT3ZlckxpbWl0KGxpbWl0Lm9yZGluYWwoKSwgbGltaXRBbmFseXplcik7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gaXNPdmVyTGltaXQoaW50IGluZGV4LCBYTUxMaW1pdEFuYWx5emVyIGxpbWl0QW5hbHl6ZXIpIHsKLSAgICAgICAgaWYgKHZhbHVlc1tpbmRleF0gPT0gTk9fTElNSVQpIHsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChpbmRleCA9PSBMaW1pdC5FTEVNRU5UX0FUVFJJQlVURV9MSU1JVC5vcmRpbmFsKCkgfHwKLSAgICAgICAgICAgICAgICBpbmRleCA9PSBMaW1pdC5FTlRJVFlfRVhQQU5TSU9OX0xJTUlULm9yZGluYWwoKSB8fAotICAgICAgICAgICAgICAgIGluZGV4ID09IExpbWl0LlRPVEFMX0VOVElUWV9TSVpFX0xJTUlULm9yZGluYWwoKSB8fAotICAgICAgICAgICAgICAgIGluZGV4ID09IExpbWl0LkVOVElUWV9SRVBMQUNFTUVOVF9MSU1JVC5vcmRpbmFsKCkgfHwKLSAgICAgICAgICAgICAgICBpbmRleCA9PSBMaW1pdC5NQVhfRUxFTUVOVF9ERVBUSF9MSU1JVC5vcmRpbmFsKCkgfHwKLSAgICAgICAgICAgICAgICBpbmRleCA9PSBMaW1pdC5NQVhfTkFNRV9MSU1JVC5vcmRpbmFsKCkKLSAgICAgICAgICAgICAgICApIHsKLSAgICAgICAgICAgIHJldHVybiAobGltaXRBbmFseXplci5nZXRUb3RhbFZhbHVlKGluZGV4KSA+IHZhbHVlc1tpbmRleF0pOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIChsaW1pdEFuYWx5emVyLmdldFZhbHVlKGluZGV4KSA+IHZhbHVlc1tpbmRleF0pOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgZGVidWdQcmludChYTUxMaW1pdEFuYWx5emVyIGxpbWl0QW5hbHl6ZXIpIHsKLSAgICAgICAgaWYgKHByaW50RW50aXR5Q291bnRJbmZvLmVxdWFscyhDb25zdGFudHMuSkRLX1lFUykpIHsKLSAgICAgICAgICAgIGxpbWl0QW5hbHl6ZXIuZGVidWdQcmludCh0aGlzKTsKLSAgICAgICAgfQotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogSW5kaWNhdGUgaWYgYSBwcm9wZXJ0eSBpcyBzZXQgZXhwbGljaXRseQotICAgICAqIEBwYXJhbSBpbmRleAotICAgICAqIEByZXR1cm4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc1NldChpbnQgaW5kZXgpIHsKLSAgICAgICAgcmV0dXJuIGlzU2V0W2luZGV4XTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBwcmludEVudGl0eUNvdW50SW5mbygpIHsKLSAgICAgICAgcmV0dXJuIHByaW50RW50aXR5Q291bnRJbmZvLmVxdWFscyhDb25zdGFudHMuSkRLX1lFUyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmVhZCBmcm9tIHN5c3RlbSBwcm9wZXJ0aWVzLCBvciB0aG9zZSBpbiBqYXhwLnByb3BlcnRpZXMKLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgcmVhZFN5c3RlbVByb3BlcnRpZXMoKSB7Ci0KLSAgICAgICAgZm9yIChMaW1pdCBsaW1pdCA6IExpbWl0LnZhbHVlcygpKSB7Ci0gICAgICAgICAgICBpZiAoIWdldFN5c3RlbVByb3BlcnR5KGxpbWl0LCBsaW1pdC5zeXN0ZW1Qcm9wZXJ0eSgpKSkgewotICAgICAgICAgICAgICAgIC8vaWYgc3lzdGVtIHByb3BlcnR5IGlzIG5vdCBmb3VuZCwgdHJ5IHRoZSBvbGRlciBmb3JtIGlmIGFueQotICAgICAgICAgICAgICAgIGZvciAoTmFtZU1hcCBuYW1lTWFwIDogTmFtZU1hcC52YWx1ZXMoKSkgewotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgb2xkTmFtZSA9IG5hbWVNYXAuZ2V0T2xkTmFtZShsaW1pdC5zeXN0ZW1Qcm9wZXJ0eSgpKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKG9sZE5hbWUgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgZ2V0U3lzdGVtUHJvcGVydHkobGltaXQsIG9sZE5hbWUpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICB9Ci0KLSAgICAvLyBBcnJheSBsaXN0IHRvIHN0b3JlIHByaW50ZWQgd2FybmluZ3MgZm9yIGVhY2ggU0FYIHBhcnNlciB1c2VkCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQ29weU9uV3JpdGVBcnJheUxpc3Q8U3RyaW5nPiBwcmludGVkV2FybmluZ3MgPSBuZXcgQ29weU9uV3JpdGVBcnJheUxpc3Q8PigpOwotCi0gICAgLyoqCi0gICAgICogUHJpbnRzIG91dCB3YXJuaW5ncyBpZiBhIHBhcnNlciBkb2VzIG5vdCBzdXBwb3J0IHRoZSBzcGVjaWZpZWQgZmVhdHVyZS9wcm9wZXJ0eS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBwYXJzZXJDbGFzc05hbWUgdGhlIG5hbWUgb2YgdGhlIHBhcnNlciBjbGFzcwotICAgICAqIEBwYXJhbSBwcm9wZXJ0eU5hbWUgdGhlIHByb3BlcnR5IG5hbWUKLSAgICAgKiBAcGFyYW0gZXhjZXB0aW9uIHRoZSBleGNlcHRpb24gdGhyb3duIGJ5IHRoZSBwYXJzZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIHZvaWQgcHJpbnRXYXJuaW5nKFN0cmluZyBwYXJzZXJDbGFzc05hbWUsIFN0cmluZyBwcm9wZXJ0eU5hbWUsIFNBWEV4Y2VwdGlvbiBleGNlcHRpb24pIHsKLSAgICAgICAgU3RyaW5nIGtleSA9IHBhcnNlckNsYXNzTmFtZSsiOiIrcHJvcGVydHlOYW1lOwotICAgICAgICBpZiAocHJpbnRlZFdhcm5pbmdzLmFkZElmQWJzZW50KGtleSkpIHsKLSAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbiggIldhcm5pbmc6ICIrcGFyc2VyQ2xhc3NOYW1lKyI6ICIrZXhjZXB0aW9uLmdldE1lc3NhZ2UoKSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZWFkIGZyb20gc3lzdGVtIHByb3BlcnRpZXMsIG9yIHRob3NlIGluIGpheHAucHJvcGVydGllcwotICAgICAqCi0gICAgICogQHBhcmFtIHByb3BlcnR5IHRoZSB0eXBlIG9mIHRoZSBwcm9wZXJ0eQotICAgICAqIEBwYXJhbSBzeXNQcm9wZXJ0eU5hbWUgdGhlIG5hbWUgb2Ygc3lzdGVtIHByb3BlcnR5Ci0gICAgICovCi0gICAgcHJpdmF0ZSBib29sZWFuIGdldFN5c3RlbVByb3BlcnR5KExpbWl0IGxpbWl0LCBTdHJpbmcgc3lzUHJvcGVydHlOYW1lKSB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBTdHJpbmcgdmFsdWUgPSBTZWN1cml0eVN1cHBvcnQuZ2V0U3lzdGVtUHJvcGVydHkoc3lzUHJvcGVydHlOYW1lKTsKLSAgICAgICAgICAgIGlmICh2YWx1ZSAhPSBudWxsICYmICF2YWx1ZS5lcXVhbHMoIiIpKSB7Ci0gICAgICAgICAgICAgICAgdmFsdWVzW2xpbWl0Lm9yZGluYWwoKV0gPSBJbnRlZ2VyLnBhcnNlSW50KHZhbHVlKTsKLSAgICAgICAgICAgICAgICBzdGF0ZXNbbGltaXQub3JkaW5hbCgpXSA9IFN0YXRlLlNZU1RFTVBST1BFUlRZOwotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICB2YWx1ZSA9IFNlY3VyaXR5U3VwcG9ydC5yZWFkSkFYUFByb3BlcnR5KHN5c1Byb3BlcnR5TmFtZSk7Ci0gICAgICAgICAgICBpZiAodmFsdWUgIT0gbnVsbCAmJiAhdmFsdWUuZXF1YWxzKCIiKSkgewotICAgICAgICAgICAgICAgIHZhbHVlc1tsaW1pdC5vcmRpbmFsKCldID0gSW50ZWdlci5wYXJzZUludCh2YWx1ZSk7Ci0gICAgICAgICAgICAgICAgc3RhdGVzW2xpbWl0Lm9yZGluYWwoKV0gPSBTdGF0ZS5KQVhQRE9UUFJPUEVSVElFUzsKLSAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIC8vaW52YWxpZCBzZXR0aW5nCi0gICAgICAgICAgICB0aHJvdyBuZXcgTnVtYmVyRm9ybWF0RXhjZXB0aW9uKCJJbnZhbGlkIHNldHRpbmcgZm9yIHN5c3RlbSBwcm9wZXJ0eTogIiArIGxpbWl0LnN5c3RlbVByb3BlcnR5KCkpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIENvbnZlcnQgYSB2YWx1ZSBzZXQgdGhyb3VnaCBzZXRQcm9wZXJ0eSB0byBYTUxTZWN1cml0eU1hbmFnZXIuCi0gICAgICogSWYgdGhlIHZhbHVlIGlzIGFuIGluc3RhbmNlIG9mIFhNTFNlY3VyaXR5TWFuYWdlciwgdXNlIGl0IHRvIG92ZXJyaWRlIHRoZSBkZWZhdWx0OwotICAgICAqIElmIHRoZSB2YWx1ZSBpcyBhbiBvbGQgU2VjdXJpdHlNYW5hZ2VyLCBjb252ZXJ0IHRvIHRoZSBuZXcgWE1MU2VjdXJpdHlNYW5hZ2VyLgotICAgICAqCi0gICAgICogQHBhcmFtIHZhbHVlIHVzZXIgc3BlY2lmaWVkIHNlY3VyaXR5IG1hbmFnZXIKLSAgICAgKiBAcGFyYW0gc2VjdXJpdHlNYW5hZ2VyIGFuIGluc3RhbmNlIG9mIFhNTFNlY3VyaXR5TWFuYWdlcgotICAgICAqIEByZXR1cm4gYW4gaW5zdGFuY2Ugb2YgdGhlIG5ldyBzZWN1cml0eSBtYW5hZ2VyIFhNTFNlY3VyaXR5TWFuYWdlcgotICAgICAqLwotICAgIHN0YXRpYyBwdWJsaWMgWE1MU2VjdXJpdHlNYW5hZ2VyIGNvbnZlcnQoT2JqZWN0IHZhbHVlLCBYTUxTZWN1cml0eU1hbmFnZXIgc2VjdXJpdHlNYW5hZ2VyKSB7Ci0gICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAoc2VjdXJpdHlNYW5hZ2VyID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBzZWN1cml0eU1hbmFnZXIgPSBuZXcgWE1MU2VjdXJpdHlNYW5hZ2VyKHRydWUpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIHNlY3VyaXR5TWFuYWdlcjsKLSAgICAgICAgfQotICAgICAgICBpZiAoWE1MU2VjdXJpdHlNYW5hZ2VyLmNsYXNzLmlzQXNzaWduYWJsZUZyb20odmFsdWUuZ2V0Q2xhc3MoKSkpIHsKLSAgICAgICAgICAgIHJldHVybiAoWE1MU2VjdXJpdHlNYW5hZ2VyKXZhbHVlOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgaWYgKHNlY3VyaXR5TWFuYWdlciA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgc2VjdXJpdHlNYW5hZ2VyID0gbmV3IFhNTFNlY3VyaXR5TWFuYWdlcih0cnVlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChTZWN1cml0eU1hbmFnZXIuY2xhc3MuaXNBc3NpZ25hYmxlRnJvbSh2YWx1ZS5nZXRDbGFzcygpKSkgewotICAgICAgICAgICAgICAgIFNlY3VyaXR5TWFuYWdlciBvcmlnU00gPSAoU2VjdXJpdHlNYW5hZ2VyKXZhbHVlOwotICAgICAgICAgICAgICAgIHNlY3VyaXR5TWFuYWdlci5zZXRMaW1pdChMaW1pdC5NQVhfT0NDVVJfTk9ERV9MSU1JVCwgU3RhdGUuQVBJUFJPUEVSVFksIG9yaWdTTS5nZXRNYXhPY2N1ck5vZGVMaW1pdCgpKTsKLSAgICAgICAgICAgICAgICBzZWN1cml0eU1hbmFnZXIuc2V0TGltaXQoTGltaXQuRU5USVRZX0VYUEFOU0lPTl9MSU1JVCwgU3RhdGUuQVBJUFJPUEVSVFksIG9yaWdTTS5nZXRFbnRpdHlFeHBhbnNpb25MaW1pdCgpKTsKLSAgICAgICAgICAgICAgICBzZWN1cml0eU1hbmFnZXIuc2V0TGltaXQoTGltaXQuRUxFTUVOVF9BVFRSSUJVVEVfTElNSVQsIFN0YXRlLkFQSVBST1BFUlRZLCBvcmlnU00uZ2V0RWxlbWVudEF0dHJMaW1pdCgpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiBzZWN1cml0eU1hbmFnZXI7Ci0gICAgICAgIH0KLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlscy9YTUxTZWN1cml0eVByb3BlcnR5TWFuYWdlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbHMvWE1MU2VjdXJpdHlQcm9wZXJ0eU1hbmFnZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNDMzMjZlMS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC91dGlscy9YTUxTZWN1cml0eVByb3BlcnR5TWFuYWdlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjI1ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMTMsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsczsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5Db25zdGFudHM7Ci1pbXBvcnQgamF2YXgueG1sLlhNTENvbnN0YW50czsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIG1hbmFnZXMgc2VjdXJpdHkgcmVsYXRlZCBwcm9wZXJ0aWVzCi0gKgotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgWE1MU2VjdXJpdHlQcm9wZXJ0eU1hbmFnZXIgewotCi0gICAgLyoqCi0gICAgICogU3RhdGVzIG9mIHRoZSBzZXR0aW5ncyBvZiBhIHByb3BlcnR5LCBpbiB0aGUgb3JkZXI6IGRlZmF1bHQgdmFsdWUsIHZhbHVlCi0gICAgICogc2V0IGJ5IEZFQVRVUkVfU0VDVVJFX1BST0NFU1NJTkcsIGpheHAucHJvcGVydGllcyBmaWxlLCBqYXhwIHN5c3RlbQotICAgICAqIHByb3BlcnRpZXMsIGFuZCBqYXhwIGFwaSBwcm9wZXJ0aWVzCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBlbnVtIFN0YXRlIHsKLSAgICAgICAgLy90aGlzIG9yZGVyIHJlZmxlY3RzIHRoZSBvdmVycmlkaW5nIG9yZGVyCi0gICAgICAgIERFRkFVTFQsIEZTUCwgSkFYUERPVFBST1BFUlRJRVMsIFNZU1RFTVBST1BFUlRZLCBBUElQUk9QRVJUWQotICAgIH0KLQotICAgIC8qKgotICAgICAqIExpbWl0cyBtYW5hZ2VkIGJ5IHRoZSBzZWN1cml0eSBtYW5hZ2VyCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBlbnVtIFByb3BlcnR5IHsKLSAgICAgICAgQUNDRVNTX0VYVEVSTkFMX0RURChYTUxDb25zdGFudHMuQUNDRVNTX0VYVEVSTkFMX0RURCwKLSAgICAgICAgICAgICAgICBDb25zdGFudHMuRVhURVJOQUxfQUNDRVNTX0RFRkFVTFQpLAotICAgICAgICBBQ0NFU1NfRVhURVJOQUxfU0NIRU1BKFhNTENvbnN0YW50cy5BQ0NFU1NfRVhURVJOQUxfU0NIRU1BLAotICAgICAgICAgICAgICAgIENvbnN0YW50cy5FWFRFUk5BTF9BQ0NFU1NfREVGQVVMVCk7Ci0KLSAgICAgICAgZmluYWwgU3RyaW5nIG5hbWU7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBkZWZhdWx0VmFsdWU7Ci0KLSAgICAgICAgUHJvcGVydHkoU3RyaW5nIG5hbWUsIFN0cmluZyB2YWx1ZSkgewotICAgICAgICAgICAgdGhpcy5uYW1lID0gbmFtZTsKLSAgICAgICAgICAgIHRoaXMuZGVmYXVsdFZhbHVlID0gdmFsdWU7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHNOYW1lKFN0cmluZyBwcm9wZXJ0eU5hbWUpIHsKLSAgICAgICAgICAgIHJldHVybiAocHJvcGVydHlOYW1lID09IG51bGwpID8gZmFsc2UgOiBuYW1lLmVxdWFscyhwcm9wZXJ0eU5hbWUpOwotICAgICAgICB9Ci0KLSAgICAgICAgU3RyaW5nIGRlZmF1bHRWYWx1ZSgpIHsKLSAgICAgICAgICAgIHJldHVybiBkZWZhdWx0VmFsdWU7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBWYWx1ZXMgb2YgdGhlIHByb3BlcnRpZXMgYXMgZGVmaW5lZCBpbiBlbnVtIFByb3BlcnRpZXMKLSAgICAgKi8KLSAgICBwcml2YXRlIGZpbmFsIFN0cmluZ1tdIHZhbHVlczsKLSAgICAvKioKLSAgICAgKiBTdGF0ZXMgb2YgdGhlIHNldHRpbmdzIGZvciBlYWNoIHByb3BlcnR5IGluIFByb3BlcnRpZXMgYWJvdmUKLSAgICAgKi8KLSAgICBwcml2YXRlIFN0YXRlW10gc3RhdGVzID0ge1N0YXRlLkRFRkFVTFQsIFN0YXRlLkRFRkFVTFR9OwotCi0gICAgLyoqCi0gICAgICogRGVmYXVsdCBjb25zdHJ1Y3Rvci4gRXN0YWJsaXNoZXMgZGVmYXVsdCB2YWx1ZXMKLSAgICAgKi8KLSAgICBwdWJsaWMgWE1MU2VjdXJpdHlQcm9wZXJ0eU1hbmFnZXIoKSB7Ci0gICAgICAgIHZhbHVlcyA9IG5ldyBTdHJpbmdbUHJvcGVydHkudmFsdWVzKCkubGVuZ3RoXTsKLSAgICAgICAgZm9yIChQcm9wZXJ0eSBwcm9wZXJ0eSA6IFByb3BlcnR5LnZhbHVlcygpKSB7Ci0gICAgICAgICAgICB2YWx1ZXNbcHJvcGVydHkub3JkaW5hbCgpXSA9IHByb3BlcnR5LmRlZmF1bHRWYWx1ZSgpOwotICAgICAgICB9Ci0gICAgICAgIC8vcmVhZCBzeXN0ZW0gcHJvcGVydGllcyBvciBqYXhwLnByb3BlcnRpZXMKLSAgICAgICAgcmVhZFN5c3RlbVByb3BlcnRpZXMoKTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFNldCBsaW1pdCBieSBwcm9wZXJ0eSBuYW1lIGFuZCBzdGF0ZQotICAgICAqIEBwYXJhbSBwcm9wZXJ0eU5hbWUgcHJvcGVydHkgbmFtZQotICAgICAqIEBwYXJhbSBzdGF0ZSB0aGUgc3RhdGUgb2YgdGhlIHByb3BlcnR5Ci0gICAgICogQHBhcmFtIHZhbHVlIHRoZSB2YWx1ZSBvZiB0aGUgcHJvcGVydHkKLSAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHByb3BlcnR5IGlzIG1hbmFnZWQgYnkgdGhlIHNlY3VyaXR5IHByb3BlcnR5IG1hbmFnZXI7Ci0gICAgICogICAgICAgICBmYWxzZSBpZiBvdGhlcndpc2UuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gc2V0VmFsdWUoU3RyaW5nIHByb3BlcnR5TmFtZSwgU3RhdGUgc3RhdGUsIE9iamVjdCB2YWx1ZSkgewotICAgICAgICBpbnQgaW5kZXggPSBnZXRJbmRleChwcm9wZXJ0eU5hbWUpOwotICAgICAgICBpZiAoaW5kZXggPiAtMSkgewotICAgICAgICAgICAgc2V0VmFsdWUoaW5kZXgsIHN0YXRlLCAoU3RyaW5nKXZhbHVlKTsKLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIHZhbHVlIGZvciBhIHNwZWNpZmljIHByb3BlcnR5LgotICAgICAqCi0gICAgICogQHBhcmFtIHByb3BlcnR5IHRoZSBwcm9wZXJ0eQotICAgICAqIEBwYXJhbSBzdGF0ZSB0aGUgc3RhdGUgb2YgdGhlIHByb3BlcnR5Ci0gICAgICogQHBhcmFtIHZhbHVlIHRoZSB2YWx1ZSBvZiB0aGUgcHJvcGVydHkKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRWYWx1ZShQcm9wZXJ0eSBwcm9wZXJ0eSwgU3RhdGUgc3RhdGUsIFN0cmluZyB2YWx1ZSkgewotICAgICAgICAvL29ubHkgdXBkYXRlIGlmIGl0IHNoYWxsIG92ZXJyaWRlCi0gICAgICAgIGlmIChzdGF0ZS5jb21wYXJlVG8oc3RhdGVzW3Byb3BlcnR5Lm9yZGluYWwoKV0pID49IDApIHsKLSAgICAgICAgICAgIHZhbHVlc1twcm9wZXJ0eS5vcmRpbmFsKCldID0gdmFsdWU7Ci0gICAgICAgICAgICBzdGF0ZXNbcHJvcGVydHkub3JkaW5hbCgpXSA9IHN0YXRlOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSB2YWx1ZSBvZiBhIHByb3BlcnR5IGJ5IGl0cyBpbmRleAotICAgICAqIEBwYXJhbSBpbmRleCB0aGUgaW5kZXggb2YgdGhlIHByb3BlcnR5Ci0gICAgICogQHBhcmFtIHN0YXRlIHRoZSBzdGF0ZSBvZiB0aGUgcHJvcGVydHkKLSAgICAgKiBAcGFyYW0gdmFsdWUgdGhlIHZhbHVlIG9mIHRoZSBwcm9wZXJ0eQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFZhbHVlKGludCBpbmRleCwgU3RhdGUgc3RhdGUsIFN0cmluZyB2YWx1ZSkgewotICAgICAgICAvL29ubHkgdXBkYXRlIGlmIGl0IHNoYWxsIG92ZXJyaWRlCi0gICAgICAgIGlmIChzdGF0ZS5jb21wYXJlVG8oc3RhdGVzW2luZGV4XSkgPj0gMCkgewotICAgICAgICAgICAgdmFsdWVzW2luZGV4XSA9IHZhbHVlOwotICAgICAgICAgICAgc3RhdGVzW2luZGV4XSA9IHN0YXRlOwotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgcHJvcGVydHkKLSAgICAgKgotICAgICAqIEBwYXJhbSBwcm9wZXJ0eU5hbWUgdGhlIHByb3BlcnR5IG5hbWUKLSAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgcHJvcGVydHkgYXMgYSBzdHJpbmcKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFZhbHVlKFN0cmluZyBwcm9wZXJ0eU5hbWUpIHsKLSAgICAgICAgaW50IGluZGV4ID0gZ2V0SW5kZXgocHJvcGVydHlOYW1lKTsKLSAgICAgICAgaWYgKGluZGV4ID4gLTEpIHsKLSAgICAgICAgICAgIHJldHVybiBnZXRWYWx1ZUJ5SW5kZXgoaW5kZXgpOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIHByb3BlcnR5Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gcHJvcGVydHkgdGhlIHByb3BlcnR5Ci0gICAgICogQHJldHVybiB0aGUgdmFsdWUgb2YgdGhlIHByb3BlcnR5Ci0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRWYWx1ZShQcm9wZXJ0eSBwcm9wZXJ0eSkgewotICAgICAgICByZXR1cm4gdmFsdWVzW3Byb3BlcnR5Lm9yZGluYWwoKV07Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSB2YWx1ZSBvZiBhIHByb3BlcnR5IGJ5IGl0cyBvcmRpbmFsCi0gICAgICogQHBhcmFtIGluZGV4IHRoZSBpbmRleCBvZiBhIHByb3BlcnR5Ci0gICAgICogQHJldHVybiB2YWx1ZSBvZiBhIHByb3BlcnR5Ci0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRWYWx1ZUJ5SW5kZXgoaW50IGluZGV4KSB7Ci0gICAgICAgIHJldHVybiB2YWx1ZXNbaW5kZXhdOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgaW5kZXggYnkgcHJvcGVydHkgbmFtZQotICAgICAqIEBwYXJhbSBwcm9wZXJ0eU5hbWUgcHJvcGVydHkgbmFtZQotICAgICAqIEByZXR1cm4gdGhlIGluZGV4IG9mIHRoZSBwcm9wZXJ0eSBpZiBmb3VuZDsgcmV0dXJuIC0xIGlmIG5vdAotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0SW5kZXgoU3RyaW5nIHByb3BlcnR5TmFtZSl7Ci0gICAgICAgIGZvciAoUHJvcGVydHkgcHJvcGVydHkgOiBQcm9wZXJ0eS52YWx1ZXMoKSkgewotICAgICAgICAgICAgaWYgKHByb3BlcnR5LmVxdWFsc05hbWUocHJvcGVydHlOYW1lKSkgewotICAgICAgICAgICAgICAgIC8vaW50ZXJuYWxseSwgb3JkaW5hbCBpcyB1c2VkIGFzIGluZGV4Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHByb3BlcnR5Lm9yZGluYWwoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gLTE7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmVhZCBmcm9tIHN5c3RlbSBwcm9wZXJ0aWVzLCBvciB0aG9zZSBpbiBqYXhwLnByb3BlcnRpZXMKLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgcmVhZFN5c3RlbVByb3BlcnRpZXMoKSB7Ci0gICAgICAgIGdldFN5c3RlbVByb3BlcnR5KFByb3BlcnR5LkFDQ0VTU19FWFRFUk5BTF9EVEQsCi0gICAgICAgICAgICAgICAgQ29uc3RhbnRzLlNQX0FDQ0VTU19FWFRFUk5BTF9EVEQpOwotICAgICAgICBnZXRTeXN0ZW1Qcm9wZXJ0eShQcm9wZXJ0eS5BQ0NFU1NfRVhURVJOQUxfU0NIRU1BLAotICAgICAgICAgICAgICAgIENvbnN0YW50cy5TUF9BQ0NFU1NfRVhURVJOQUxfU0NIRU1BKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZWFkIGZyb20gc3lzdGVtIHByb3BlcnRpZXMsIG9yIHRob3NlIGluIGpheHAucHJvcGVydGllcwotICAgICAqCi0gICAgICogQHBhcmFtIHByb3BlcnR5IHRoZSBwcm9wZXJ0eQotICAgICAqIEBwYXJhbSBzeXN0ZW1Qcm9wZXJ0eSB0aGUgbmFtZSBvZiB0aGUgc3lzdGVtIHByb3BlcnR5Ci0gICAgICovCi0gICAgcHJpdmF0ZSB2b2lkIGdldFN5c3RlbVByb3BlcnR5KFByb3BlcnR5IHByb3BlcnR5LCBTdHJpbmcgc3lzdGVtUHJvcGVydHkpIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIFN0cmluZyB2YWx1ZSA9IFNlY3VyaXR5U3VwcG9ydC5nZXRTeXN0ZW1Qcm9wZXJ0eShzeXN0ZW1Qcm9wZXJ0eSk7Ci0gICAgICAgICAgICBpZiAodmFsdWUgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHZhbHVlc1twcm9wZXJ0eS5vcmRpbmFsKCldID0gdmFsdWU7Ci0gICAgICAgICAgICAgICAgc3RhdGVzW3Byb3BlcnR5Lm9yZGluYWwoKV0gPSBTdGF0ZS5TWVNURU1QUk9QRVJUWTsKLSAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIHZhbHVlID0gU2VjdXJpdHlTdXBwb3J0LnJlYWRKQVhQUHJvcGVydHkoc3lzdGVtUHJvcGVydHkpOwotICAgICAgICAgICAgaWYgKHZhbHVlICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICB2YWx1ZXNbcHJvcGVydHkub3JkaW5hbCgpXSA9IHZhbHVlOwotICAgICAgICAgICAgICAgIHN0YXRlc1twcm9wZXJ0eS5vcmRpbmFsKCldID0gU3RhdGUuSkFYUERPVFBST1BFUlRJRVM7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAvL2ludmFsaWQgc2V0dGluZyBpZ25vcmVkCi0gICAgICAgIH0KLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94aW5jbHVkZS9NdWx0aXBsZVNjb3BlTmFtZXNwYWNlU3VwcG9ydC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveGluY2x1ZGUvTXVsdGlwbGVTY29wZU5hbWVzcGFjZVN1cHBvcnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMjdhYzhlZS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94aW5jbHVkZS9NdWx0aXBsZVNjb3BlTmFtZXNwYWNlU3VwcG9ydC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTk2ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDMtMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueGluY2x1ZGU7Ci0KLWltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuTmFtZXNwYWNlU3VwcG9ydDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuWE1MU3ltYm9sczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5OYW1lc3BhY2VDb250ZXh0OwotCi0vKioKLSAqIFRoaXMgaW1wbGVtZW50YXRpb24gb2YgTmFtZXNwYWNlQ29udGV4dCBoYXMgdGhlIGFiaWxpdHkgdG8gbWFpbnRhaW4gbXVsdGlwbGUKLSAqIHNjb3BlcyBvZiBuYW1lc3BhY2UvcHJlZml4IGJpbmRpbmdzLiAgVGhpcyBpcyB1c2VmdWwgaW4gc2l0dWF0aW9ucyB3aGVuIGl0IGlzCi0gKiBub3QgYWx3YXlzIGFwcHJvcHJpYXRlIGZvciBlbGVtZW50cyB0byBpbmhlcml0IHRoZSBuYW1lc3BhY2UgYmluZGluZ3Mgb2YgdGhlaXIKLSAqIGFuY2VzdG9ycyAoc3VjaCBhcyBpbmNsdWRlZCBlbGVtZW50cyBpbiBYSW5jbHVkZSkuCi0gKgotICogV2hlbiBzZWFyY2hpbmcgZm9yIGEgVVJJIHRvIG1hdGNoIGEgcHJlZml4LCBvciBhIHByZWZpeCB0byBtYXRjaCBhIFVSSSwgaXQgaXMKLSAqIHNlYXJjaGVkIGZvciBpbiB0aGUgY3VycmVudCBjb250ZXh0LCB0aGVuIHRoZSBhbmNlc3RvcnMgb2YgdGhlIGN1cnJlbnQgY29udGV4dCwKLSAqIHVwIHRvIHRoZSBiZWdpbm5pbmcgb2YgdGhlIGN1cnJlbnQgc2NvcGUuICBPdGhlciBzY29wZXMgYXJlIG5vdCBzZWFyY2hlZC4KLSAqCi0gKiBAYXV0aG9yIFBldGVyIE1jQ3JhY2tlbiwgSUJNCi0gKgotICovCi1wdWJsaWMgY2xhc3MgTXVsdGlwbGVTY29wZU5hbWVzcGFjZVN1cHBvcnQgZXh0ZW5kcyBOYW1lc3BhY2VTdXBwb3J0IHsKLQotICAgIHByb3RlY3RlZCBpbnRbXSBmU2NvcGUgPSBuZXcgaW50WzhdOwotICAgIHByb3RlY3RlZCBpbnQgZkN1cnJlbnRTY29wZTsKLQotICAgIC8qKgotICAgICAqCi0gICAgICovCi0gICAgcHVibGljIE11bHRpcGxlU2NvcGVOYW1lc3BhY2VTdXBwb3J0KCkgewotICAgICAgICBzdXBlcigpOwotICAgICAgICBmQ3VycmVudFNjb3BlID0gMDsKLSAgICAgICAgZlNjb3BlWzBdID0gMDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAcGFyYW0gY29udGV4dAotICAgICAqLwotICAgIHB1YmxpYyBNdWx0aXBsZVNjb3BlTmFtZXNwYWNlU3VwcG9ydChOYW1lc3BhY2VDb250ZXh0IGNvbnRleHQpIHsKLSAgICAgICAgc3VwZXIoY29udGV4dCk7Ci0gICAgICAgIGZDdXJyZW50U2NvcGUgPSAwOwotICAgICAgICBmU2NvcGVbMF0gPSAwOwotICAgIH0KLQotICAgIC8qIChub24tSmF2YWRvYykKLSAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLk5hbWVzcGFjZUNvbnRleHQjZ2V0QWxsUHJlZml4ZXMoKQotICAgICAqLwotICAgIHB1YmxpYyBFbnVtZXJhdGlvbiBnZXRBbGxQcmVmaXhlcygpIHsKLSAgICAgICAgaW50IGNvdW50ID0gMDsKLSAgICAgICAgaWYgKGZQcmVmaXhlcy5sZW5ndGggPCAoZk5hbWVzcGFjZS5sZW5ndGggLyAyKSkgewotICAgICAgICAgICAgLy8gcmVzaXplIHByZWZpeCBhcnJheQotICAgICAgICAgICAgU3RyaW5nW10gcHJlZml4ZXMgPSBuZXcgU3RyaW5nW2ZOYW1lc3BhY2VTaXplXTsKLSAgICAgICAgICAgIGZQcmVmaXhlcyA9IHByZWZpeGVzOwotICAgICAgICB9Ci0gICAgICAgIFN0cmluZyBwcmVmaXggPSBudWxsOwotICAgICAgICBib29sZWFuIHVuaXF1ZSA9IHRydWU7Ci0gICAgICAgIGZvciAoaW50IGkgPSBmQ29udGV4dFtmU2NvcGVbZkN1cnJlbnRTY29wZV1dOwotICAgICAgICAgICAgaSA8PSAoZk5hbWVzcGFjZVNpemUgLSAyKTsKLSAgICAgICAgICAgIGkgKz0gMikgewotICAgICAgICAgICAgcHJlZml4ID0gZk5hbWVzcGFjZVtpXTsKLSAgICAgICAgICAgIGZvciAoaW50IGsgPSAwOyBrIDwgY291bnQ7IGsrKykgewotICAgICAgICAgICAgICAgIGlmIChmUHJlZml4ZXNba10gPT0gcHJlZml4KSB7Ci0gICAgICAgICAgICAgICAgICAgIHVuaXF1ZSA9IGZhbHNlOwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAodW5pcXVlKSB7Ci0gICAgICAgICAgICAgICAgZlByZWZpeGVzW2NvdW50KytdID0gcHJlZml4OwotICAgICAgICAgICAgfQotICAgICAgICAgICAgdW5pcXVlID0gdHJ1ZTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbmV3IFByZWZpeGVzKGZQcmVmaXhlcywgY291bnQpOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgZ2V0U2NvcGVGb3JDb250ZXh0KGludCBjb250ZXh0KSB7Ci0gICAgICAgIGludCBzY29wZSA9IGZDdXJyZW50U2NvcGU7Ci0gICAgICAgIHdoaWxlIChjb250ZXh0IDwgZlNjb3BlW3Njb3BlXSkgewotICAgICAgICAgICAgc2NvcGUtLTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gc2NvcGU7Ci0gICAgfQotCi0gICAgLyogKG5vbi1KYXZhZG9jKQotICAgICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuTmFtZXNwYWNlQ29udGV4dCNnZXRQcmVmaXgoamF2YS5sYW5nLlN0cmluZykKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFByZWZpeChTdHJpbmcgdXJpKSB7Ci0gICAgICAgIHJldHVybiBnZXRQcmVmaXgodXJpLCBmTmFtZXNwYWNlU2l6ZSwgZkNvbnRleHRbZlNjb3BlW2ZDdXJyZW50U2NvcGVdXSk7Ci0gICAgfQotCi0gICAgLyogKG5vbi1KYXZhZG9jKQotICAgICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuTmFtZXNwYWNlQ29udGV4dCNnZXRVUkkoamF2YS5sYW5nLlN0cmluZykKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFVSSShTdHJpbmcgcHJlZml4KSB7Ci0gICAgICAgIHJldHVybiBnZXRVUkkocHJlZml4LCBmTmFtZXNwYWNlU2l6ZSwgZkNvbnRleHRbZlNjb3BlW2ZDdXJyZW50U2NvcGVdXSk7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRQcmVmaXgoU3RyaW5nIHVyaSwgaW50IGNvbnRleHQpIHsKLSAgICAgICAgcmV0dXJuIGdldFByZWZpeCh1cmksIGZDb250ZXh0W2NvbnRleHQrMV0sIGZDb250ZXh0W2ZTY29wZVtnZXRTY29wZUZvckNvbnRleHQoY29udGV4dCldXSk7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRVUkkoU3RyaW5nIHByZWZpeCwgaW50IGNvbnRleHQpIHsKLSAgICAgICAgcmV0dXJuIGdldFVSSShwcmVmaXgsIGZDb250ZXh0W2NvbnRleHQrMV0sIGZDb250ZXh0W2ZTY29wZVtnZXRTY29wZUZvckNvbnRleHQoY29udGV4dCldXSk7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRQcmVmaXgoU3RyaW5nIHVyaSwgaW50IHN0YXJ0LCBpbnQgZW5kKSB7Ci0gICAgICAgIC8vIHRoaXMgc2F2ZXMgdXMgZnJvbSBoYXZpbmcgYSBjb3B5IG9mIGVhY2ggb2YgdGhlc2UgaW4gZk5hbWVzcGFjZSBmb3IgZWFjaCBzY29wZQotICAgICAgICBpZiAodXJpID09IE5hbWVzcGFjZUNvbnRleHQuWE1MX1VSSSkgewotICAgICAgICAgICAgcmV0dXJuIFhNTFN5bWJvbHMuUFJFRklYX1hNTDsKLSAgICAgICAgfQotICAgICAgICBpZiAodXJpID09IE5hbWVzcGFjZUNvbnRleHQuWE1MTlNfVVJJKSB7Ci0gICAgICAgICAgICByZXR1cm4gWE1MU3ltYm9scy5QUkVGSVhfWE1MTlM7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBmaW5kIHVyaSBpbiBjdXJyZW50IGNvbnRleHQKLSAgICAgICAgZm9yIChpbnQgaSA9IHN0YXJ0OyBpID4gZW5kOyBpIC09IDIpIHsKLSAgICAgICAgICAgIGlmIChmTmFtZXNwYWNlW2kgLSAxXSA9PSB1cmkpIHsKLSAgICAgICAgICAgICAgICBpZiAoZ2V0VVJJKGZOYW1lc3BhY2VbaSAtIDJdKSA9PSB1cmkpCi0gICAgICAgICAgICAgICAgICAgIHJldHVybiBmTmFtZXNwYWNlW2kgLSAyXTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIHVyaSBub3QgZm91bmQKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRVUkkoU3RyaW5nIHByZWZpeCwgaW50IHN0YXJ0LCBpbnQgZW5kKSB7Ci0gICAgICAgIC8vIHRoaXMgc2F2ZXMgdXMgZnJvbSBoYXZpbmcgYSBjb3B5IG9mIGVhY2ggb2YgdGhlc2UgaW4gZk5hbWVzcGFjZSBmb3IgZWFjaCBzY29wZQotICAgICAgICBpZiAocHJlZml4ID09IFhNTFN5bWJvbHMuUFJFRklYX1hNTCkgewotICAgICAgICAgICAgcmV0dXJuIE5hbWVzcGFjZUNvbnRleHQuWE1MX1VSSTsKLSAgICAgICAgfQotICAgICAgICBpZiAocHJlZml4ID09IFhNTFN5bWJvbHMuUFJFRklYX1hNTE5TKSB7Ci0gICAgICAgICAgICByZXR1cm4gTmFtZXNwYWNlQ29udGV4dC5YTUxOU19VUkk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBmaW5kIHByZWZpeCBpbiBjdXJyZW50IGNvbnRleHQKLSAgICAgICAgZm9yIChpbnQgaSA9IHN0YXJ0OyBpID4gZW5kOyBpIC09IDIpIHsKLSAgICAgICAgICAgIGlmIChmTmFtZXNwYWNlW2kgLSAyXSA9PSBwcmVmaXgpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZk5hbWVzcGFjZVtpIC0gMV07Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBwcmVmaXggbm90IGZvdW5kCi0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIE9ubHkgcmVzZXRzIHRoZSBjdXJyZW50IHNjb3BlIC0tIGFsbCBuYW1lc3BhY2VzIGRlZmluZWQgaW4gbG93ZXIgc2NvcGVzCi0gICAgICogcmVtYWluIHZhbGlkIGFmdGVyIGEgY2FsbCB0byByZXNldC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCByZXNldCgpIHsKLSAgICAgICAgZkN1cnJlbnRDb250ZXh0ID0gZlNjb3BlW2ZDdXJyZW50U2NvcGVdOwotICAgICAgICBmTmFtZXNwYWNlU2l6ZSA9IGZDb250ZXh0W2ZDdXJyZW50Q29udGV4dF07Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQmVnaW5zIGEgbmV3IHNjb3BlLiAgTm9uZSBvZiB0aGUgcHJldmlvdXMgbmFtZXNwYWNlIGJpbmRpbmdzIHdpbGwgYmUgdXNlZCwKLSAgICAgKiB1bnRpbCB0aGUgbmV3IHNjb3BlIGlzIHBvcHBlZCB3aXRoIHBvcFNjb3BlKCkKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBwdXNoU2NvcGUoKSB7Ci0gICAgICAgIGlmIChmQ3VycmVudFNjb3BlICsgMSA9PSBmU2NvcGUubGVuZ3RoKSB7Ci0gICAgICAgICAgICBpbnRbXSBjb250ZXh0YXJyYXkgPSBuZXcgaW50W2ZTY29wZS5sZW5ndGggKiAyXTsKLSAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZlNjb3BlLCAwLCBjb250ZXh0YXJyYXksIDAsIGZTY29wZS5sZW5ndGgpOwotICAgICAgICAgICAgZlNjb3BlID0gY29udGV4dGFycmF5OwotICAgICAgICB9Ci0gICAgICAgIHB1c2hDb250ZXh0KCk7Ci0gICAgICAgIGZTY29wZVsrK2ZDdXJyZW50U2NvcGVdID0gZkN1cnJlbnRDb250ZXh0OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFBvcHMgdGhlIGN1cnJlbnQgc2NvcGUuICBUaGUgbmFtZXNwYWNlIGJpbmRpbmdzIGZyb20gdGhlIG5ldyBjdXJyZW50IHNjb3BlCi0gICAgICogYXJlIHRoZW4gdXNlZCBmb3Igc2VhcmNoaW5nIGZvciBuYW1lc3BhY2VzIGFuZCBwcmVmaXhlcy4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBwb3BTY29wZSgpIHsKLSAgICAgICAgZkN1cnJlbnRDb250ZXh0ID0gZlNjb3BlW2ZDdXJyZW50U2NvcGUtLV07Ci0gICAgICAgIHBvcENvbnRleHQoKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94aW5jbHVkZS9TZWN1cml0eVN1cHBvcnQuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3hpbmNsdWRlL1NlY3VyaXR5U3VwcG9ydC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlYjg3NWUyLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3hpbmNsdWRlL1NlY3VyaXR5U3VwcG9ydC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTUyICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54aW5jbHVkZTsKLQotaW1wb3J0IGphdmEuaW8uRmlsZTsKLWltcG9ydCBqYXZhLmlvLkZpbGVJbnB1dFN0cmVhbTsKLWltcG9ydCBqYXZhLmlvLkZpbGVOb3RGb3VuZEV4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOwotCi1pbXBvcnQgamF2YS5zZWN1cml0eS5BY2Nlc3NDb250cm9sbGVyOwotaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpdmlsZWdlZEFjdGlvbjsKLWltcG9ydCBqYXZhLnNlY3VyaXR5LlByaXZpbGVnZWRBY3Rpb25FeGNlcHRpb247Ci1pbXBvcnQgamF2YS5zZWN1cml0eS5Qcml2aWxlZ2VkRXhjZXB0aW9uQWN0aW9uOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgaXMgZHVwbGljYXRlZCBmb3IgZWFjaCBzdWJwYWNrYWdlIHNvIGtlZXAgaXQgaW4gc3luYy4KLSAqIEl0IGlzIHBhY2thZ2UgcHJpdmF0ZSBhbmQgdGhlcmVmb3JlIGlzIG5vdCBleHBvc2VkIGFzIHBhcnQgb2YgYW55IEFQSS4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKi8KLWZpbmFsIGNsYXNzIFNlY3VyaXR5U3VwcG9ydCB7Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTZWN1cml0eVN1cHBvcnQgc2VjdXJpdHlTdXBwb3J0ID0gbmV3IFNlY3VyaXR5U3VwcG9ydCgpOwotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIGFuIGluc3RhbmNlIG9mIHRoaXMgY2xhc3MuCi0gICAgICovCi0gICAgc3RhdGljIFNlY3VyaXR5U3VwcG9ydCBnZXRJbnN0YW5jZSgpIHsKLSAgICAgICAgcmV0dXJuIHNlY3VyaXR5U3VwcG9ydDsKLSAgICB9Ci0KLSAgICBDbGFzc0xvYWRlciBnZXRDb250ZXh0Q2xhc3NMb2FkZXIoKSB7Ci0gICAgICAgIHJldHVybiAoQ2xhc3NMb2FkZXIpCi0gICAgICAgIEFjY2Vzc0NvbnRyb2xsZXIuZG9Qcml2aWxlZ2VkKG5ldyBQcml2aWxlZ2VkQWN0aW9uKCkgewotICAgICAgICAgICAgcHVibGljIE9iamVjdCBydW4oKSB7Ci0gICAgICAgICAgICAgICAgQ2xhc3NMb2FkZXIgY2wgPSBudWxsOwotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgIGNsID0gVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5nZXRDb250ZXh0Q2xhc3NMb2FkZXIoKTsKLSAgICAgICAgICAgICAgICB9IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBleCkgeyB9Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGNsOwotICAgICAgICAgICAgfQotICAgICAgICB9KTsKLSAgICB9Ci0KLSAgICBDbGFzc0xvYWRlciBnZXRTeXN0ZW1DbGFzc0xvYWRlcigpIHsKLSAgICAgICAgcmV0dXJuIChDbGFzc0xvYWRlcikKLSAgICAgICAgQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQobmV3IFByaXZpbGVnZWRBY3Rpb24oKSB7Ci0gICAgICAgICAgICBwdWJsaWMgT2JqZWN0IHJ1bigpIHsKLSAgICAgICAgICAgICAgICBDbGFzc0xvYWRlciBjbCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgY2wgPSBDbGFzc0xvYWRlci5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpOwotICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIGV4KSB7fQotICAgICAgICAgICAgICAgIHJldHVybiBjbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSk7Ci0gICAgfQotCi0gICAgQ2xhc3NMb2FkZXIgZ2V0UGFyZW50Q2xhc3NMb2FkZXIoZmluYWwgQ2xhc3NMb2FkZXIgY2wpIHsKLSAgICAgICAgcmV0dXJuIChDbGFzc0xvYWRlcikKLSAgICAgICAgQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQobmV3IFByaXZpbGVnZWRBY3Rpb24oKSB7Ci0gICAgICAgICAgICBwdWJsaWMgT2JqZWN0IHJ1bigpIHsKLSAgICAgICAgICAgICAgICBDbGFzc0xvYWRlciBwYXJlbnQgPSBudWxsOwotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgIHBhcmVudCA9IGNsLmdldFBhcmVudCgpOwotICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIGV4KSB7fQotCi0gICAgICAgICAgICAgICAgLy8gZWxpbWluYXRlIGxvb3BzIGluIGNhc2Ugb2YgdGhlIGJvb3QKLSAgICAgICAgICAgICAgICAvLyBDbGFzc0xvYWRlciByZXR1cm5pbmcgaXRzZWxmIGFzIGEgcGFyZW50Ci0gICAgICAgICAgICAgICAgcmV0dXJuIChwYXJlbnQgPT0gY2wpID8gbnVsbCA6IHBhcmVudDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSk7Ci0gICAgfQotCi0gICAgU3RyaW5nIGdldFN5c3RlbVByb3BlcnR5KGZpbmFsIFN0cmluZyBwcm9wTmFtZSkgewotICAgICAgICByZXR1cm4gKFN0cmluZykKLSAgICAgICAgQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQobmV3IFByaXZpbGVnZWRBY3Rpb24oKSB7Ci0gICAgICAgICAgICBwdWJsaWMgT2JqZWN0IHJ1bigpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gU3lzdGVtLmdldFByb3BlcnR5KHByb3BOYW1lKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSk7Ci0gICAgfQotCi0gICAgRmlsZUlucHV0U3RyZWFtIGdldEZpbGVJbnB1dFN0cmVhbShmaW5hbCBGaWxlIGZpbGUpCi0gICAgdGhyb3dzIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIHJldHVybiAoRmlsZUlucHV0U3RyZWFtKQotICAgICAgICAgICAgQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQobmV3IFByaXZpbGVnZWRFeGNlcHRpb25BY3Rpb24oKSB7Ci0gICAgICAgICAgICAgICAgcHVibGljIE9iamVjdCBydW4oKSB0aHJvd3MgRmlsZU5vdEZvdW5kRXhjZXB0aW9uIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBGaWxlSW5wdXRTdHJlYW0oZmlsZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfSk7Ci0gICAgICAgIH0gY2F0Y2ggKFByaXZpbGVnZWRBY3Rpb25FeGNlcHRpb24gZSkgewotICAgICAgICAgICAgdGhyb3cgKEZpbGVOb3RGb3VuZEV4Y2VwdGlvbillLmdldEV4Y2VwdGlvbigpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgSW5wdXRTdHJlYW0gZ2V0UmVzb3VyY2VBc1N0cmVhbShmaW5hbCBDbGFzc0xvYWRlciBjbCwKLSAgICAgICAgICAgIGZpbmFsIFN0cmluZyBuYW1lKQotICAgIHsKLSAgICAgICAgcmV0dXJuIChJbnB1dFN0cmVhbSkKLSAgICAgICAgQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQobmV3IFByaXZpbGVnZWRBY3Rpb24oKSB7Ci0gICAgICAgICAgICBwdWJsaWMgT2JqZWN0IHJ1bigpIHsKLSAgICAgICAgICAgICAgICBJbnB1dFN0cmVhbSByaXM7Ci0gICAgICAgICAgICAgICAgaWYgKGNsID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgcmlzID0gQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtUmVzb3VyY2VBc1N0cmVhbShuYW1lKTsKLSAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICByaXMgPSBjbC5nZXRSZXNvdXJjZUFzU3RyZWFtKG5hbWUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICByZXR1cm4gcmlzOwotICAgICAgICAgICAgfQotICAgICAgICB9KTsKLSAgICB9Ci0KLSAgICBib29sZWFuIGdldEZpbGVFeGlzdHMoZmluYWwgRmlsZSBmKSB7Ci0gICAgICAgIHJldHVybiAoKEJvb2xlYW4pCi0gICAgICAgICAgICAgICAgQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQobmV3IFByaXZpbGVnZWRBY3Rpb24oKSB7Ci0gICAgICAgICAgICAgICAgICAgIHB1YmxpYyBPYmplY3QgcnVuKCkgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBCb29sZWFuKGYuZXhpc3RzKCkpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfSkpLmJvb2xlYW5WYWx1ZSgpOwotICAgIH0KLQotICAgIGxvbmcgZ2V0TGFzdE1vZGlmaWVkKGZpbmFsIEZpbGUgZikgewotICAgICAgICByZXR1cm4gKChMb25nKQotICAgICAgICAgICAgICAgIEFjY2Vzc0NvbnRyb2xsZXIuZG9Qcml2aWxlZ2VkKG5ldyBQcml2aWxlZ2VkQWN0aW9uKCkgewotICAgICAgICAgICAgICAgICAgICBwdWJsaWMgT2JqZWN0IHJ1bigpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgTG9uZyhmLmxhc3RNb2RpZmllZCgpKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0pKS5sb25nVmFsdWUoKTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIFNlY3VyaXR5U3VwcG9ydCAoKSB7fQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveGluY2x1ZGUvWEluY2x1ZGUxMVRleHRSZWFkZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3hpbmNsdWRlL1hJbmNsdWRlMTFUZXh0UmVhZGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDdmZjdlY2IuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveGluY2x1ZGUvWEluY2x1ZGUxMVRleHRSZWFkZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDYyICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDMtMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueGluY2x1ZGU7Ci0KLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlhNTDExQ2hhcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MSW5wdXRTb3VyY2U7Ci0KLS8qKgotICogVGhpcyBjbGFzcyBpcyB1c2VkIGZvciByZWFkaW5nIHJlc291cmNlcyByZXF1ZXN0ZWQgaW4gJmx0O2luY2x1ZGUmZ3Q7IGVsZW1lbnRzIGluCi0gKiBYTUwgMS4xIGVudGl0aWVzLCB3aGVuIHRoZSBwYXJzZSBhdHRyaWJ1dGUgb2YgdGhlICZsdDtpbmNsdWRlJmd0OyBlbGVtZW50IGlzICJ0ZXh0Ii4KLSAqIFVzaW5nIHRoaXMgY2xhc3Mgd2lsbCBvcGVuIHRoZSBsb2NhdGlvbiwgZGV0ZWN0IHRoZSBlbmNvZGluZywgYW5kIGRpc2NhcmQgdGhlCi0gKiBieXRlIG9yZGVyIG1hcmssIGlmIGFwcGxpY2FibGUuCi0gKgotICogQGF1dGhvciBNaWNoYWVsIEdsYXZhc3NldmljaCwgSUJNCi0gKgotICoKLSAqIEBzZWUgWEluY2x1ZGVIYW5kbGVyCi0gKi8KLXB1YmxpYyBjbGFzcyBYSW5jbHVkZTExVGV4dFJlYWRlcgotICAgIGV4dGVuZHMgWEluY2x1ZGVUZXh0UmVhZGVyIHsKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdCB0aGUgWEluY2x1ZGVSZWFkZXIgdXNpbmcgdGhlIFhNTElucHV0U291cmNlIGFuZCBYSW5jbHVkZUhhbmRsZXIuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc291cmNlIFRoZSBYTUxJbnB1dFNvdXJjZSB0byB1c2UuCi0gICAgICogQHBhcmFtIGhhbmRsZXIgVGhlIFhJbmNsdWRlSGFuZGxlciB0byB1c2UuCi0gICAgICogQHBhcmFtIGJ1ZmZlclNpemUgVGhlIHNpemUgb2YgdGhpcyB0ZXh0IHJlYWRlcidzIGJ1ZmZlci4KLSAgICAgKi8KLSAgICBwdWJsaWMgWEluY2x1ZGUxMVRleHRSZWFkZXIoWE1MSW5wdXRTb3VyY2Ugc291cmNlLCBYSW5jbHVkZUhhbmRsZXIgaGFuZGxlciwgaW50IGJ1ZmZlclNpemUpCi0gICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgIHN1cGVyKHNvdXJjZSwgaGFuZGxlciwgYnVmZmVyU2l6ZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyIGlzIGEgdmFsaWQgWE1MIGNoYXJhY3RlcgotICAgICAqIGFzIHBlciB0aGUgcnVsZXMgb2YgWE1MIDEuMS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjaCBUaGUgY2hhcmFjdGVyIHRvIGNoZWNrLgotICAgICAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIGlzVmFsaWQoaW50IGNoKSB7Ci0gICAgICAgIHJldHVybiBYTUwxMUNoYXIuaXNYTUwxMVZhbGlkKGNoKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94aW5jbHVkZS9YSW5jbHVkZUhhbmRsZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3hpbmNsdWRlL1hJbmNsdWRlSGFuZGxlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhMDYwZjk5Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3hpbmNsdWRlL1hJbmNsdWRlSGFuZGxlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzA4MCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAzLTIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhpbmNsdWRlOwotCi1pbXBvcnQgamF2YS5pby5DaGFyQ29udmVyc2lvbkV4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7Ci1pbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOwotaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7Ci1pbXBvcnQgamF2YS51dGlsLlN0YWNrOwotaW1wb3J0IGphdmEudXRpbC5TdHJpbmdUb2tlbml6ZXI7Ci1pbXBvcnQgamF2YXgueG1sLlhNTENvbnN0YW50czsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5Db25zdGFudHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLlhNTEVudGl0eU1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLlhNTEVycm9yUmVwb3J0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmlvLk1hbGZvcm1lZEJ5dGVTZXF1ZW5jZUV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwubXNnLlhNTE1lc3NhZ2VGb3JtYXR0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLkF1Z21lbnRhdGlvbnNJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5IVFRQSW5wdXRTb3VyY2U7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLkludFN0YWNrOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5QYXJzZXJDb25maWd1cmF0aW9uU2V0dGluZ3M7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlN5bWJvbFRhYmxlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5VUkk7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlhNTEF0dHJpYnV0ZXNJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5YTUxSZXNvdXJjZUlkZW50aWZpZXJJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5YTUxDaGFyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5YTUxTeW1ib2xzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5VUkkuTWFsZm9ybWVkVVJJRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbHMuWE1MU2VjdXJpdHlNYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLkF1Z21lbnRhdGlvbnM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuTmFtZXNwYWNlQ29udGV4dDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5RTmFtZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxBdHRyaWJ1dGVzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTERUREhhbmRsZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MRG9jdW1lbnRIYW5kbGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTExvY2F0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MUmVzb3VyY2VJZGVudGlmaWVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTFN0cmluZzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTklFeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTENvbXBvbmVudDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MQ29tcG9uZW50TWFuYWdlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MRFRERmlsdGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxEVERTb3VyY2U7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTERvY3VtZW50RmlsdGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxEb2N1bWVudFNvdXJjZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MRW50aXR5UmVzb2x2ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTElucHV0U291cmNlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxQYXJzZXJDb25maWd1cmF0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHBvaW50ZXIuWFBvaW50ZXJIYW5kbGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHBvaW50ZXIuWFBvaW50ZXJQcm9jZXNzb3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlscy5PYmplY3RGYWN0b3J5OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbHMuWE1MU2VjdXJpdHlQcm9wZXJ0eU1hbmFnZXI7Ci1pbXBvcnQgamF2YS51dGlsLk9iamVjdHM7Ci0KLS8qKgotICogPHA+Ci0gKiBUaGlzIGlzIGEgcGlwZWxpbmUgY29tcG9uZW50IHdoaWNoIHBlcmZvcm1zIFhJbmNsdWRlIGhhbmRsaW5nLCBhY2NvcmRpbmcgdG8gdGhlCi0gKiBXM0Mgc3BlY2lmaWNhdGlvbiBmb3IgWE1MIEluY2x1c2lvbnMuCi0gKiA8L3A+Ci0gKiA8cD4KLSAqIFRoaXMgY29tcG9uZW50IGFuYWx5emVzIGVhY2ggZXZlbnQgaW4gdGhlIHBpcGVsaW5lLCBsb29raW5nIGZvciAmbHQ7aW5jbHVkZSZndDsKLSAqIGVsZW1lbnRzLiBBbiAmbHQ7aW5jbHVkZSZndDsgZWxlbWVudCBpcyBvbmUgd2hpY2ggaGFzIGEgbmFtZXNwYWNlIG9mCi0gKiA8Y29kZT5odHRwOi8vd3d3LnczLm9yZy8yMDAxL1hJbmNsdWRlPC9jb2RlPiBhbmQgYSBsb2NhbG5hbWUgb2YgPGNvZGU+aW5jbHVkZTwvY29kZT4uCi0gKiBXaGVuIGl0IGZpbmRzIGFuICZsdDtpbmNsdWRlJmd0OyBlbGVtZW50LCBpdCBhdHRlbXB0cyB0byBpbmNsdWRlIHRoZSBmaWxlIHNwZWNpZmllZAotICogaW4gdGhlIDxjb2RlPmhyZWY8L2NvZGU+IGF0dHJpYnV0ZSBvZiB0aGUgZWxlbWVudC4gIElmIGluY2x1c2lvbiBzdWNjZWVkcywgYWxsCi0gKiBjaGlsZHJlbiBvZiB0aGUgJmx0O2luY2x1ZGUmZ3Q7IGVsZW1lbnQgYXJlIGlnbm9yZWQgKHdpdGggdGhlIGV4Y2VwdGlvbiBvZgotICogY2hlY2tpbmcgZm9yIGludmFsaWQgY2hpbGRyZW4gYXMgb3V0bGluZWQgaW4gdGhlIHNwZWNpZmljYXRpb24pLiAgSWYgdGhlIGluY2x1c2lvbgotICogZmFpbHMsIHRoZSAmbHQ7ZmFsbGJhY2smZ3Q7IGNoaWxkIG9mIHRoZSAmbHQ7aW5jbHVkZSZndDsgZWxlbWVudCBpcyBwcm9jZXNzZWQuCi0gKiA8L3A+Ci0gKiA8cD4KLSAqIFNlZSB0aGUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveGluY2x1ZGUvIj5YSW5jbHVkZSBzcGVjaWZpY2F0aW9uPC9hPiBmb3IKLSAqIG1vcmUgaW5mb3JtYXRpb24gb24gaG93IFhJbmNsdWRlIGlzIHRvIGJlIHVzZWQuCi0gKiA8L3A+Ci0gKiA8cD4KLSAqIFRoaXMgY29tcG9uZW50IHJlcXVpcmVzIHRoZSBmb2xsb3dpbmcgZmVhdHVyZXMgYW5kIHByb3BlcnRpZXMgZnJvbSB0aGUKLSAqIGNvbXBvbmVudCBtYW5hZ2VyIHRoYXQgdXNlcyBpdDoKLSAqIDx1bD4KLSAqICA8bGk+aHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL2FsbG93LWR0ZC1ldmVudHMtYWZ0ZXItZW5kRFREPC9saT4KLSAqICA8bGk+aHR0cDovL2FwYWNoZS5vcmcveG1sL3Byb3BlcnRpZXMvaW50ZXJuYWwvZXJyb3ItcmVwb3J0ZXI8L2xpPgotICogIDxsaT5odHRwOi8vYXBhY2hlLm9yZy94bWwvcHJvcGVydGllcy9pbnRlcm5hbC9lbnRpdHktcmVzb2x2ZXI8L2xpPgotICogPC91bD4KLSAqIE9wdGlvbmFsIHByb3BlcnR5OgotICogPHVsPgotICogIDxsaT5odHRwOi8vYXBhY2hlLm9yZy94bWwvcHJvcGVydGllcy9pbnB1dC1idWZmZXItc2l6ZTwvbGk+Ci0gKiA8L3VsPgotICoKLSAqIEZ1cnRoZXJtb3JlLCB0aGUgPGNvZGU+TmFtZXNwYWNlQ29udGV4dDwvY29kZT4gdXNlZCBpbiB0aGUgcGlwZWxpbmUgaXMgcmVxdWlyZWQKLSAqIHRvIGJlIGFuIGluc3RhbmNlIG9mIDxjb2RlPlhJbmNsdWRlTmFtZXNwYWNlU3VwcG9ydDwvY29kZT4uCi0gKiA8L3A+Ci0gKiA8cD4KLSAqIEN1cnJlbnRseSwgdGhpcyBpbXBsZW1lbnRhdGlvbiBoYXMgb25seSBwYXJ0aWFsIHN1cHBvcnQgZm9yIHRoZSBYSW5jbHVkZSBzcGVjaWZpY2F0aW9uLgotICogU3BlY2lmaWNhbGx5LCBpdCBpcyBtaXNzaW5nIHN1cHBvcnQgZm9yIFhQb2ludGVyIGRvY3VtZW50IGZyYWdtZW50cy4gIFRodXMsIG9ubHkgd2hvbGUKLSAqIGRvY3VtZW50cyBjYW4gYmUgaW5jbHVkZWQgdXNpbmcgdGhpcyBjb21wb25lbnQgaW4gdGhlIHBpcGVsaW5lLgotICogPC9wPgotICoKLSAqIEBhdXRob3IgUGV0ZXIgTWNDcmFja2VuLCBJQk0KLSAqIEBhdXRob3IgTWljaGFlbCBHbGF2YXNzZXZpY2gsIElCTQotICoKLSAqIEB2ZXJzaW9uICRJZDogWEluY2x1ZGVIYW5kbGVyLmphdmEsdiAxLjcgMjAxMC0xMS0wMSAwNDo0MDoxOCBqb2VodyBFeHAgJAotICoKLSAqIEBzZWUgWEluY2x1ZGVOYW1lc3BhY2VTdXBwb3J0Ci0gKi8KLXB1YmxpYyBjbGFzcyBYSW5jbHVkZUhhbmRsZXIKLSAgICBpbXBsZW1lbnRzIFhNTENvbXBvbmVudCwgWE1MRG9jdW1lbnRGaWx0ZXIsIFhNTERUREZpbHRlciB7Ci0KLSAgICBwdWJsaWMgZmluYWwgc3RhdGljIFN0cmluZyBYSU5DTFVERV9ERUZBVUxUX0NPTkZJR1VSQVRJT04gPQotICAgICAgICAiY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5wYXJzZXJzLlhJbmNsdWRlUGFyc2VyQ29uZmlndXJhdGlvbiI7Ci0gICAgcHVibGljIGZpbmFsIHN0YXRpYyBTdHJpbmcgSFRUUF9BQ0NFUFQgPSAiQWNjZXB0IjsKLSAgICBwdWJsaWMgZmluYWwgc3RhdGljIFN0cmluZyBIVFRQX0FDQ0VQVF9MQU5HVUFHRSA9ICJBY2NlcHQtTGFuZ3VhZ2UiOwotICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgU3RyaW5nIFhQT0lOVEVSID0gInhwb2ludGVyIjsKLQotICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgU3RyaW5nIFhJTkNMVURFX05TX1VSSSA9Ci0gICAgICAgICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hJbmNsdWRlIi5pbnRlcm4oKTsKLSAgICBwdWJsaWMgZmluYWwgc3RhdGljIFN0cmluZyBYSU5DTFVERV9JTkNMVURFID0gImluY2x1ZGUiLmludGVybigpOwotICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgU3RyaW5nIFhJTkNMVURFX0ZBTExCQUNLID0gImZhbGxiYWNrIi5pbnRlcm4oKTsKLQotICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgU3RyaW5nIFhJTkNMVURFX1BBUlNFX1hNTCA9ICJ4bWwiLmludGVybigpOwotICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgU3RyaW5nIFhJTkNMVURFX1BBUlNFX1RFWFQgPSAidGV4dCIuaW50ZXJuKCk7Ci0KLSAgICBwdWJsaWMgZmluYWwgc3RhdGljIFN0cmluZyBYSU5DTFVERV9BVFRSX0hSRUYgPSAiaHJlZiIuaW50ZXJuKCk7Ci0gICAgcHVibGljIGZpbmFsIHN0YXRpYyBTdHJpbmcgWElOQ0xVREVfQVRUUl9QQVJTRSA9ICJwYXJzZSIuaW50ZXJuKCk7Ci0gICAgcHVibGljIGZpbmFsIHN0YXRpYyBTdHJpbmcgWElOQ0xVREVfQVRUUl9FTkNPRElORyA9ICJlbmNvZGluZyIuaW50ZXJuKCk7Ci0gICAgcHVibGljIGZpbmFsIHN0YXRpYyBTdHJpbmcgWElOQ0xVREVfQVRUUl9BQ0NFUFQgPSAiYWNjZXB0Ii5pbnRlcm4oKTsKLSAgICBwdWJsaWMgZmluYWwgc3RhdGljIFN0cmluZyBYSU5DTFVERV9BVFRSX0FDQ0VQVF9MQU5HVUFHRSA9ICJhY2NlcHQtbGFuZ3VhZ2UiLmludGVybigpOwotCi0gICAgLy8gVG9wIExldmVsIEluZm9ybWF0aW9uIEl0ZW1zIGhhdmUgW2luY2x1ZGVkXSBwcm9wZXJ0eSBpbiBpbmZvc2V0Ci0gICAgcHVibGljIGZpbmFsIHN0YXRpYyBTdHJpbmcgWElOQ0xVREVfSU5DTFVERUQgPSAiW2luY2x1ZGVkXSIuaW50ZXJuKCk7Ci0KLSAgICAvKiogVGhlIGlkZW50aWZpZXIgZm9yIHRoZSBBdWdtZW50YXRpb24gdGhhdCBjb250YWlucyB0aGUgY3VycmVudCBiYXNlIFVSSSAqLwotICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgU3RyaW5nIENVUlJFTlRfQkFTRV9VUkkgPSAiY3VycmVudEJhc2VVUkkiOwotCi0gICAgLy8gdXNlZCBmb3IgYWRkaW5nIFtiYXNlIFVSSV0gYXR0cmlidXRlcwotICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgU3RyaW5nIFhJTkNMVURFX0JBU0UgPSAiYmFzZSIuaW50ZXJuKCk7Ci0gICAgcHVibGljIGZpbmFsIHN0YXRpYyBRTmFtZSBYTUxfQkFTRV9RTkFNRSA9Ci0gICAgICAgIG5ldyBRTmFtZSgKLSAgICAgICAgICAgIFhNTFN5bWJvbHMuUFJFRklYX1hNTCwKLSAgICAgICAgICAgIFhJTkNMVURFX0JBU0UsCi0gICAgICAgICAgICAoWE1MU3ltYm9scy5QUkVGSVhfWE1MICsgIjoiICsgWElOQ0xVREVfQkFTRSkuaW50ZXJuKCksCi0gICAgICAgICAgICBOYW1lc3BhY2VDb250ZXh0LlhNTF9VUkkpOwotCi0gICAgLy8gdXNlZCBmb3IgYWRkaW5nIFtsYW5ndWFnZV0gYXR0cmlidXRlcwotICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgU3RyaW5nIFhJTkNMVURFX0xBTkcgPSAibGFuZyIuaW50ZXJuKCk7Ci0gICAgcHVibGljIGZpbmFsIHN0YXRpYyBRTmFtZSBYTUxfTEFOR19RTkFNRSA9Ci0gICAgICAgIG5ldyBRTmFtZSgKLSAgICAgICAgICAgIFhNTFN5bWJvbHMuUFJFRklYX1hNTCwKLSAgICAgICAgICAgIFhJTkNMVURFX0xBTkcsCi0gICAgICAgICAgICAoWE1MU3ltYm9scy5QUkVGSVhfWE1MICsgIjoiICsgWElOQ0xVREVfTEFORykuaW50ZXJuKCksCi0gICAgICAgICAgICBOYW1lc3BhY2VDb250ZXh0LlhNTF9VUkkpOwotCi0gICAgcHVibGljIGZpbmFsIHN0YXRpYyBRTmFtZSBORVdfTlNfQVRUUl9RTkFNRSA9Ci0gICAgICAgIG5ldyBRTmFtZSgKLSAgICAgICAgICAgIFhNTFN5bWJvbHMuUFJFRklYX1hNTE5TLAotICAgICAgICAgICAgIiIsCi0gICAgICAgICAgICBYTUxTeW1ib2xzLlBSRUZJWF9YTUxOUyArICI6IiwKLSAgICAgICAgICAgIE5hbWVzcGFjZUNvbnRleHQuWE1MTlNfVVJJKTsKLQotICAgIC8vIFByb2Nlc3NpbmcgU3RhdGVzCi0gICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgaW50IFNUQVRFX05PUk1BTF9QUk9DRVNTSU5HID0gMTsKLSAgICAvLyB3ZSBnbyBpbnRvIHRoaXMgc3RhdGUgYWZ0ZXIgYSBzdWNjZXNzZnVsIGluY2x1ZGUgKHRodXMgd2UgaWdub3JlIHRoZSBjaGlsZHJlbgotICAgIC8vIG9mIHRoZSBpbmNsdWRlKSBvciBhZnRlciBhIGZhbGxiYWNrCi0gICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgaW50IFNUQVRFX0lHTk9SRSA9IDI7Ci0gICAgLy8gd2UgZ28gaW50byB0aGlzIHN0YXRlIGFmdGVyIGEgZmFpbGVkIGluY2x1ZGUuICBJZiB3ZSBkb24ndCBlbmNvdW50ZXIgYSBmYWxsYmFjawotICAgIC8vIGJlZm9yZSB3ZSByZWFjaCB0aGUgZW5kIGluY2x1ZGUgdGFnLCBpdCdzIGEgZmF0YWwgZXJyb3IKLSAgICBwcml2YXRlIGZpbmFsIHN0YXRpYyBpbnQgU1RBVEVfRVhQRUNUX0ZBTExCQUNLID0gMzsKLQotICAgIC8vIHJlY29nbml6ZWQgZmVhdHVyZXMgYW5kIHByb3BlcnRpZXMKLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IHZhbGlkYXRpb24uICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgVkFMSURBVElPTiA9Ci0gICAgICAgIENvbnN0YW50cy5TQVhfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuVkFMSURBVElPTl9GRUFUVVJFOwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogc2NoZW1hIHZhbGlkYXRpb24uICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgU0NIRU1BX1ZBTElEQVRJT04gPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLlNDSEVNQV9WQUxJREFUSU9OX0ZFQVRVUkU7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiBkeW5hbWljIHZhbGlkYXRpb24uICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgRFlOQU1JQ19WQUxJREFUSU9OID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWCArIENvbnN0YW50cy5EWU5BTUlDX1ZBTElEQVRJT05fRkVBVFVSRTsKLQotICAgIC8qKiBGZWF0dXJlIGlkZW50aWZpZXI6IGFsbG93IG5vdGF0aW9uIGFuZCB1bnBhcnNlZCBlbnRpdHkgZXZlbnRzIHRvIGJlIHNlbnQgb3V0IG9mIG9yZGVyLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIEFMTE9XX1VFX0FORF9OT1RBVElPTl9FVkVOVFMgPQotICAgICAgICBDb25zdGFudHMuU0FYX0ZFQVRVUkVfUFJFRklYCi0gICAgICAgICAgICArIENvbnN0YW50cy5BTExPV19EVERfRVZFTlRTX0FGVEVSX0VORERURF9GRUFUVVJFOwotCi0gICAgLyoqIEZlYXR1cmUgaWRlbnRpZmllcjogZml4dXAgYmFzZSBVUklzLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFhJTkNMVURFX0ZJWFVQX0JBU0VfVVJJUyA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuWElOQ0xVREVfRklYVVBfQkFTRV9VUklTX0ZFQVRVUkU7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiBmaXh1cCBsYW5ndWFnZS4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBYSU5DTFVERV9GSVhVUF9MQU5HVUFHRSA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuWElOQ0xVREVfRklYVVBfTEFOR1VBR0VfRkVBVFVSRTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBzeW1ib2wgdGFibGUuICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1lNQk9MX1RBQkxFID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuU1lNQk9MX1RBQkxFX1BST1BFUlRZOwotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IGVycm9yIHJlcG9ydGVyLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUk9SX1JFUE9SVEVSID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuRVJST1JfUkVQT1JURVJfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogZW50aXR5IHJlc29sdmVyLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIEVOVElUWV9SRVNPTFZFUiA9Ci0gICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLkVOVElUWV9SRVNPTFZFUl9QUk9QRVJUWTsKLQotICAgIC8qKiBwcm9wZXJ0eSBpZGVudGlmaWVyOiBzZWN1cml0eSBtYW5hZ2VyLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFNFQ1VSSVRZX01BTkFHRVIgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5TRUNVUklUWV9NQU5BR0VSX1BST1BFUlRZOwotCi0gICAgLyoqIHByb3BlcnR5IGlkZW50aWZpZXI6IGJ1ZmZlciBzaXplLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEJVRkZFUl9TSVpFID0KLSAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuQlVGRkVSX1NJWkVfUFJPUEVSVFk7Ci0KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBQQVJTRVJfU0VUVElOR1MgPQotICAgICAgICBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYICsgQ29uc3RhbnRzLlBBUlNFUl9TRVRUSU5HUzsKLQotICAgIC8qKiBwcm9wZXJ0eSBpZGVudGlmaWVyOiBYTUwgc2VjdXJpdHkgcHJvcGVydHkgbWFuYWdlci4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxfU0VDVVJJVFlfUFJPUEVSVFlfTUFOQUdFUiA9Ci0gICAgICAgICAgICBDb25zdGFudHMuWE1MX1NFQ1VSSVRZX1BST1BFUlRZX01BTkFHRVI7Ci0KLSAgICAvKiogUmVjb2duaXplZCBmZWF0dXJlcy4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSBSRUNPR05JWkVEX0ZFQVRVUkVTID0KLSAgICAgICAgeyBBTExPV19VRV9BTkRfTk9UQVRJT05fRVZFTlRTLCBYSU5DTFVERV9GSVhVUF9CQVNFX1VSSVMsIFhJTkNMVURFX0ZJWFVQX0xBTkdVQUdFIH07Ci0KLSAgICAvKiogRmVhdHVyZSBkZWZhdWx0cy4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBCb29sZWFuW10gRkVBVFVSRV9ERUZBVUxUUyA9IHsgQm9vbGVhbi5UUlVFLCBCb29sZWFuLlRSVUUsIEJvb2xlYW4uVFJVRSB9OwotCi0gICAgLyoqIFJlY29nbml6ZWQgcHJvcGVydGllcy4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSBSRUNPR05JWkVEX1BST1BFUlRJRVMgPQotICAgICAgICB7IEVSUk9SX1JFUE9SVEVSLCBFTlRJVFlfUkVTT0xWRVIsIFNFQ1VSSVRZX01BTkFHRVIsIEJVRkZFUl9TSVpFIH07Ci0KLSAgICAvKiogUHJvcGVydHkgZGVmYXVsdHMuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgT2JqZWN0W10gUFJPUEVSVFlfREVGQVVMVFMgPSB7IG51bGwsIG51bGwsIG51bGwsIG5ldyBJbnRlZ2VyKFhNTEVudGl0eU1hbmFnZXIuREVGQVVMVF9CVUZGRVJfU0laRSkgfTsKLQotICAgIC8vIGluc3RhbmNlIHZhcmlhYmxlcwotCi0gICAgLy8gZm9yIFhNTERvY3VtZW50RmlsdGVyCi0gICAgcHJvdGVjdGVkIFhNTERvY3VtZW50SGFuZGxlciBmRG9jdW1lbnRIYW5kbGVyOwotICAgIHByb3RlY3RlZCBYTUxEb2N1bWVudFNvdXJjZSBmRG9jdW1lbnRTb3VyY2U7Ci0KLSAgICAvLyBmb3IgWE1MRFRERmlsdGVyCi0gICAgcHJvdGVjdGVkIFhNTERUREhhbmRsZXIgZkRUREhhbmRsZXI7Ci0gICAgcHJvdGVjdGVkIFhNTERURFNvdXJjZSBmRFREU291cmNlOwotCi0gICAgLy8gZm9yIFhJbmNsdWRlSGFuZGxlcgotICAgIHByb3RlY3RlZCBYSW5jbHVkZUhhbmRsZXIgZlBhcmVudFhJbmNsdWRlSGFuZGxlcjsKLQotICAgIC8vIGZvciBidWZmZXIgc2l6ZSBpbiBYSW5jbHVkZVRleHRSZWFkZXIKLSAgICBwcm90ZWN0ZWQgaW50IGZCdWZmZXJTaXplID0gWE1MRW50aXR5TWFuYWdlci5ERUZBVUxUX0JVRkZFUl9TSVpFOwotCi0gICAgLy8gSXQgImZlZWxzIHdyb25nIiB0byBzdG9yZSB0aGlzIHZhbHVlIGhlcmUuICBIb3dldmVyLAotICAgIC8vIGNhbGN1bGF0aW5nIGl0IGNhbiBiZSB0aW1lIGNvbnN1bWluZywgc28gd2UgY2FjaGUgaXQuCi0gICAgLy8gSXQncyBuZXZlciBnb2luZyB0byBjaGFuZ2UgaW4gdGhlIGxpZmV0aW1lIG9mIHRoaXMgWEluY2x1ZGVIYW5kbGVyCi0gICAgcHJvdGVjdGVkIFN0cmluZyBmUGFyZW50UmVsYXRpdmVVUkk7Ci0KLSAgICAvLyB3ZSBjYWNoZSB0aGUgY2hpbGQgcGFyc2VyIGNvbmZpZ3VyYXRpb24sIHNvIHdlIGRvbid0IGhhdmUgdG8gcmUtY3JlYXRlCi0gICAgLy8gdGhlIG9iamVjdHMgd2hlbiB0aGUgcGFyc2VyIGlzIHJlLXVzZWQKLSAgICBwcm90ZWN0ZWQgWE1MUGFyc2VyQ29uZmlndXJhdGlvbiBmQ2hpbGRDb25maWc7Ci0KLSAgICAvLyBUaGUgY2FjaGVkIGNoaWxkIHBhcnNlciBjb25maWd1cmF0aW9uLCBtYXkgY29udGFpbiBhCi0gICAgLy8gWEluY2x1ZGUgb3IgWFBvaW50ZXIgSGFuZGxlci4gIENhY2hlIGJvdGggdGhlc2UKLSAgICBwcm90ZWN0ZWQgWE1MUGFyc2VyQ29uZmlndXJhdGlvbiBmWEluY2x1ZGVDaGlsZENvbmZpZzsKLSAgICBwcm90ZWN0ZWQgWE1MUGFyc2VyQ29uZmlndXJhdGlvbiBmWFBvaW50ZXJDaGlsZENvbmZpZzsKLQotICAgIC8vIFRoZSBYUG9pbnRlclByb2Nlc3NvcgotICAgIHByb3RlY3RlZCBYUG9pbnRlclByb2Nlc3NvciBmWFB0clByb2Nlc3NvciA9IG51bGw7Ci0KLSAgICBwcm90ZWN0ZWQgWE1MTG9jYXRvciBmRG9jTG9jYXRpb247Ci0gICAgcHJvdGVjdGVkIFhJbmNsdWRlTWVzc2FnZUZvcm1hdHRlciBmWEluY2x1ZGVNZXNzYWdlRm9ybWF0dGVyID0gbmV3IFhJbmNsdWRlTWVzc2FnZUZvcm1hdHRlcigpOwotICAgIHByb3RlY3RlZCBYSW5jbHVkZU5hbWVzcGFjZVN1cHBvcnQgZk5hbWVzcGFjZUNvbnRleHQ7Ci0gICAgcHJvdGVjdGVkIFN5bWJvbFRhYmxlIGZTeW1ib2xUYWJsZTsKLSAgICBwcm90ZWN0ZWQgWE1MRXJyb3JSZXBvcnRlciBmRXJyb3JSZXBvcnRlcjsKLSAgICBwcm90ZWN0ZWQgWE1MRW50aXR5UmVzb2x2ZXIgZkVudGl0eVJlc29sdmVyOwotICAgIHByb3RlY3RlZCBYTUxTZWN1cml0eU1hbmFnZXIgZlNlY3VyaXR5TWFuYWdlcjsKLSAgICBwcm90ZWN0ZWQgWE1MU2VjdXJpdHlQcm9wZXJ0eU1hbmFnZXIgZlNlY3VyaXR5UHJvcGVydHlNZ3I7Ci0KLSAgICAvLyB0aGVzZSBhcmUgbmVlZGVkIGZvciB0ZXh0IGluY2x1ZGUgcHJvY2Vzc2luZwotICAgIHByb3RlY3RlZCBYSW5jbHVkZVRleHRSZWFkZXIgZlhJbmNsdWRlMTBUZXh0UmVhZGVyOwotICAgIHByb3RlY3RlZCBYSW5jbHVkZVRleHRSZWFkZXIgZlhJbmNsdWRlMTFUZXh0UmVhZGVyOwotCi0gICAgLy8gdGhlc2UgYXJlIG5lZWRlZCBmb3IgWE1MIEJhc2UgcHJvY2Vzc2luZwotICAgIHByb3RlY3RlZCBYTUxSZXNvdXJjZUlkZW50aWZpZXIgZkN1cnJlbnRCYXNlVVJJOwotICAgIHByb3RlY3RlZCBJbnRTdGFjayBmQmFzZVVSSVNjb3BlOwotICAgIHByb3RlY3RlZCBTdGFjayBmQmFzZVVSSTsKLSAgICBwcm90ZWN0ZWQgU3RhY2sgZkxpdGVyYWxTeXN0ZW1JRDsKLSAgICBwcm90ZWN0ZWQgU3RhY2sgZkV4cGFuZGVkU3lzdGVtSUQ7Ci0KLSAgICAvLyB0aGVzZSBhcmUgbmVlZGVkIGZvciBMYW5ndWFnZSBGaXh1cAotICAgIHByb3RlY3RlZCBJbnRTdGFjayBmTGFuZ3VhZ2VTY29wZTsKLSAgICBwcm90ZWN0ZWQgU3RhY2sgZkxhbmd1YWdlU3RhY2s7Ci0gICAgcHJvdGVjdGVkIFN0cmluZyBmQ3VycmVudExhbmd1YWdlOwotCi0gICAgLy8gdXNlZCBmb3IgcGFzc2luZyBmZWF0dXJlcyBvbiB0byBjaGlsZCBYSW5jbHVkZUhhbmRsZXIgb2JqZWN0cwotICAgIHByb3RlY3RlZCBQYXJzZXJDb25maWd1cmF0aW9uU2V0dGluZ3MgZlNldHRpbmdzOwotCi0gICAgLy8gVGhlIGN1cnJlbnQgZWxlbWVudCBkZXB0aC4gIFdlIHN0YXJ0IGF0IGRlcHRoIDAgKGJlZm9yZSB3ZSd2ZSByZWFjaGVkIGFueSBlbGVtZW50cykuCi0gICAgLy8gVGhlIGZpcnN0IGVsZW1lbnQgaXMgYXQgZGVwdGggMS4KLSAgICBwcml2YXRlIGludCBmRGVwdGg7Ci0KLSAgICAvLyBUaGUgY3VycmVudCBlbGVtZW50IGRlcHRoIG9mIHRoZSByZXN1bHQgaW5mb3NldC4KLSAgICBwcml2YXRlIGludCBmUmVzdWx0RGVwdGg7Ci0KLSAgICAvLyB0aGlzIHZhbHVlIG11c3QgYmUgYXQgbGVhc3QgMQotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBJTklUSUFMX1NJWkUgPSA4OwotCi0gICAgLy8gVXNlZCB0byBlbnN1cmUgdGhhdCBmYWxsYmFja3MgYXJlIGFsd2F5cyBjaGlsZHJlbiBvZiBpbmNsdWRlIGVsZW1lbnRzLAotICAgIC8vIGFuZCB0aGF0IGluY2x1ZGUgZWxlbWVudHMgYXJlIG5ldmVyIGNoaWxkcmVuIG9mIG90aGVyIGluY2x1ZGUgZWxlbWVudHMuCi0gICAgLy8gQW4gaW5kZXggY29udGFpbnMgdHJ1ZSBpZiB0aGUgYW5jZXN0b3Igb2YgdGhlIGN1cnJlbnQgZWxlbWVudCB3aGljaCByZXNpZGVzCi0gICAgLy8gYXQgdGhhdCBkZXB0aCB3YXMgYW4gaW5jbHVkZSBlbGVtZW50LgotICAgIHByaXZhdGUgYm9vbGVhbltdIGZTYXdJbmNsdWRlID0gbmV3IGJvb2xlYW5bSU5JVElBTF9TSVpFXTsKLQotICAgIC8vIEVuc3VyZXMgdGhhdCBvbmx5IG9uZSBmYWxsYmFjayBlbGVtZW50IGNhbiBiZSBhdCBhIHNpbmdsZSBkZXB0aC4KLSAgICAvLyBBbiBpbmRleCBjb250YWlucyB0cnVlIGlmIHdlIGhhdmUgc2VlbiBhbnkgZmFsbGJhY2sgZWxlbWVudHMgYXQgdGhhdCBkZXB0aCwKLSAgICAvLyBhbmQgaXQgaXMgb25seSByZXNldCB0byBmYWxzZSB3aGVuIHRoZSBlbmQgdGFnIG9mIHRoZSBwYXJlbnQgaXMgZW5jb3VudGVyZWQuCi0gICAgcHJpdmF0ZSBib29sZWFuW10gZlNhd0ZhbGxiYWNrID0gbmV3IGJvb2xlYW5bSU5JVElBTF9TSVpFXTsKLQotICAgIC8vIFRoZSBzdGF0ZSBvZiB0aGUgcHJvY2Vzc29yIGF0IGVhY2ggZ2l2ZW4gZGVwdGguCi0gICAgcHJpdmF0ZSBpbnRbXSBmU3RhdGUgPSBuZXcgaW50W0lOSVRJQUxfU0laRV07Ci0KLSAgICAvLyBidWZmZXJpbmcgdGhlIG5lY2Vzc2FyeSBEVEQgZXZlbnRzCi0gICAgcHJpdmF0ZSBBcnJheUxpc3QgZk5vdGF0aW9uczsKLSAgICBwcml2YXRlIEFycmF5TGlzdCBmVW5wYXJzZWRFbnRpdGllczsKLQotICAgIC8vIGZsYWdzIHdoaWNoIGNvbnRyb2wgd2hldGhlciBiYXNlIFVSSSBvciBsYW5ndWFnZSBmaXh1cCBpcyBwZXJmb3JtZWQuCi0gICAgcHJpdmF0ZSBib29sZWFuIGZGaXh1cEJhc2VVUklzID0gdHJ1ZTsKLSAgICBwcml2YXRlIGJvb2xlYW4gZkZpeHVwTGFuZ3VhZ2UgPSB0cnVlOwotCi0gICAgLy8gZm9yIFNBWCBjb21wYXRpYmlsaXR5LgotICAgIC8vIEhhcyB0aGUgdmFsdWUgb2YgdGhlIEFMTE9XX1VFX0FORF9OT1RBVElPTl9FVkVOVFMgZmVhdHVyZQotICAgIHByaXZhdGUgYm9vbGVhbiBmU2VuZFVFQW5kTm90YXRpb25FdmVudHM7Ci0KLSAgICAvLyB0cmFjayB0aGUgdmVyc2lvbiBvZiB0aGUgZG9jdW1lbnQgYmVpbmcgcGFyc2VkCi0gICAgcHJpdmF0ZSBib29sZWFuIGZJc1hNTDExOwotCi0gICAgLy8gdHJhY2sgd2hldGhlciBhIERURCBpcyBiZWluZyBwYXJzZWQKLSAgICBwcml2YXRlIGJvb2xlYW4gZkluRFREOwotCi0gICAgLy8gdHJhY2sgd2hldGhlciB0aGUgcm9vdCBlbGVtZW50IG9mIHRoZSByZXN1bHQgaW5mb3NldCBoYXMgYmVlbiBwcm9jZXNzZWQKLSAgICBwcml2YXRlIGJvb2xlYW4gZlNlZW5Sb290RWxlbWVudDsKLQotICAgIC8vIHRyYWNrIHdoZXRoZXIgdGhlIGNoaWxkIGNvbmZpZyBuZWVkcyBpdHMgZmVhdHVyZXMgcmVmcmVzaGVkCi0gICAgcHJpdmF0ZSBib29sZWFuIGZOZWVkQ29weUZlYXR1cmVzID0gdHJ1ZTsKLQotICAgIC8vIENvbnN0cnVjdG9ycwotCi0gICAgcHVibGljIFhJbmNsdWRlSGFuZGxlcigpIHsKLSAgICAgICAgZkRlcHRoID0gMDsKLQotICAgICAgICBmU2F3RmFsbGJhY2tbZkRlcHRoXSA9IGZhbHNlOwotICAgICAgICBmU2F3SW5jbHVkZVtmRGVwdGhdID0gZmFsc2U7Ci0gICAgICAgIGZTdGF0ZVtmRGVwdGhdID0gU1RBVEVfTk9STUFMX1BST0NFU1NJTkc7Ci0gICAgICAgIGZOb3RhdGlvbnMgPSBuZXcgQXJyYXlMaXN0KCk7Ci0gICAgICAgIGZVbnBhcnNlZEVudGl0aWVzID0gbmV3IEFycmF5TGlzdCgpOwotCi0gICAgICAgIGZCYXNlVVJJU2NvcGUgPSBuZXcgSW50U3RhY2soKTsKLSAgICAgICAgZkJhc2VVUkkgPSBuZXcgU3RhY2soKTsKLSAgICAgICAgZkxpdGVyYWxTeXN0ZW1JRCA9IG5ldyBTdGFjaygpOwotICAgICAgICBmRXhwYW5kZWRTeXN0ZW1JRCA9IG5ldyBTdGFjaygpOwotICAgICAgICBmQ3VycmVudEJhc2VVUkkgPSBuZXcgWE1MUmVzb3VyY2VJZGVudGlmaWVySW1wbCgpOwotCi0gICAgICAgIGZMYW5ndWFnZVNjb3BlID0gbmV3IEludFN0YWNrKCk7Ci0gICAgICAgIGZMYW5ndWFnZVN0YWNrID0gbmV3IFN0YWNrKCk7Ci0gICAgICAgIGZDdXJyZW50TGFuZ3VhZ2UgPSBudWxsOwotICAgIH0KLQotICAgIC8vIFhNTENvbXBvbmVudCBtZXRob2RzCi0KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgdm9pZCByZXNldChYTUxDb21wb25lbnRNYW5hZ2VyIGNvbXBvbmVudE1hbmFnZXIpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBmTmFtZXNwYWNlQ29udGV4dCA9IG51bGw7Ci0gICAgICAgIGZEZXB0aCA9IDA7Ci0gICAgICAgIGZSZXN1bHREZXB0aCA9IGlzUm9vdERvY3VtZW50KCkgPyAwIDogZlBhcmVudFhJbmNsdWRlSGFuZGxlci5nZXRSZXN1bHREZXB0aCgpOwotICAgICAgICBmTm90YXRpb25zLmNsZWFyKCk7Ci0gICAgICAgIGZVbnBhcnNlZEVudGl0aWVzLmNsZWFyKCk7Ci0gICAgICAgIGZQYXJlbnRSZWxhdGl2ZVVSSSA9IG51bGw7Ci0gICAgICAgIGZJc1hNTDExID0gZmFsc2U7Ci0gICAgICAgIGZJbkRURCA9IGZhbHNlOwotICAgICAgICBmU2VlblJvb3RFbGVtZW50ID0gZmFsc2U7Ci0KLSAgICAgICAgZkJhc2VVUklTY29wZS5jbGVhcigpOwotICAgICAgICBmQmFzZVVSSS5jbGVhcigpOwotICAgICAgICBmTGl0ZXJhbFN5c3RlbUlELmNsZWFyKCk7Ci0gICAgICAgIGZFeHBhbmRlZFN5c3RlbUlELmNsZWFyKCk7Ci0gICAgICAgIGZMYW5ndWFnZVNjb3BlLmNsZWFyKCk7Ci0gICAgICAgIGZMYW5ndWFnZVN0YWNrLmNsZWFyKCk7Ci0KLSAgICAgICAgLy8gUkVWSVNJVDogRmluZCBhIGJldHRlciBtZXRob2QgZm9yIG1haW50YWluaW5nCi0gICAgICAgIC8vIHRoZSBzdGF0ZSBvZiB0aGUgWEluY2x1ZGUgcHJvY2Vzc29yLiBUaGVzZSBhcnJheXMKLSAgICAgICAgLy8gY2FuIHBvdGVudGlhbGx5IGdyb3cgcXVpdGUgbGFyZ2UuIENsZWFuaW5nIHRoZW0KLSAgICAgICAgLy8gb3V0IG9uIHJlc2V0IG1heSBiZSB2ZXJ5IHRpbWUgY29uc3VtaW5nLiAtLSBtcmdsYXZhcwotICAgICAgICAvLwotICAgICAgICAvLyBjbGVhciB0aGUgcHJldmlvdXMgc2V0dGluZ3MgZnJvbSB0aGUgYXJyYXlzCi0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZlN0YXRlLmxlbmd0aDsgKytpKSB7Ci0gICAgICAgICAgICBmU3RhdGVbaV0gPSBTVEFURV9OT1JNQUxfUFJPQ0VTU0lORzsKLSAgICAgICAgfQotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZTYXdGYWxsYmFjay5sZW5ndGg7ICsraSkgewotICAgICAgICAgICAgZlNhd0ZhbGxiYWNrW2ldID0gZmFsc2U7Ci0gICAgICAgIH0KLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmU2F3SW5jbHVkZS5sZW5ndGg7ICsraSkgewotICAgICAgICAgICAgZlNhd0luY2x1ZGVbaV0gPSBmYWxzZTsKLSAgICAgICAgfQotCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBpZiAoIWNvbXBvbmVudE1hbmFnZXIuZ2V0RmVhdHVyZShQQVJTRVJfU0VUVElOR1MpKSB7Ci0gICAgICAgICAgICAgICAgLy8gaWYgcGFyc2VyIHNldHRpbmdzIGhhdmUgbm90IGNoYW5nZWQgcmV0dXJuLgotICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBlKSB7fQotCi0gICAgICAgIC8vIHBhcnNlciBzZXR0aW5ncyBjaGFuZ2VkLiBOZWVkIHRvIHJlZnJlc2ggZmVhdHVyZXMgb24gY2hpbGQgY29uZmlnLgotICAgICAgICBmTmVlZENvcHlGZWF0dXJlcyA9IHRydWU7Ci0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGZTZW5kVUVBbmROb3RhdGlvbkV2ZW50cyA9Ci0gICAgICAgICAgICAgICAgY29tcG9uZW50TWFuYWdlci5nZXRGZWF0dXJlKEFMTE9XX1VFX0FORF9OT1RBVElPTl9FVkVOVFMpOwotICAgICAgICAgICAgaWYgKGZDaGlsZENvbmZpZyAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZkNoaWxkQ29uZmlnLnNldEZlYXR1cmUoCi0gICAgICAgICAgICAgICAgICAgIEFMTE9XX1VFX0FORF9OT1RBVElPTl9FVkVOVFMsCi0gICAgICAgICAgICAgICAgICAgIGZTZW5kVUVBbmROb3RhdGlvbkV2ZW50cyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gZSkgewotICAgICAgICB9Ci0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGZGaXh1cEJhc2VVUklzID0KLSAgICAgICAgICAgICAgICBjb21wb25lbnRNYW5hZ2VyLmdldEZlYXR1cmUoWElOQ0xVREVfRklYVVBfQkFTRV9VUklTKTsKLSAgICAgICAgICAgIGlmIChmQ2hpbGRDb25maWcgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZDaGlsZENvbmZpZy5zZXRGZWF0dXJlKAotICAgICAgICAgICAgICAgICAgICBYSU5DTFVERV9GSVhVUF9CQVNFX1VSSVMsCi0gICAgICAgICAgICAgICAgICAgIGZGaXh1cEJhc2VVUklzKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICBmRml4dXBCYXNlVVJJcyA9IHRydWU7Ci0gICAgICAgIH0KLQotICAgICAgICB0cnkgewotICAgICAgICAgICAgZkZpeHVwTGFuZ3VhZ2UgPQotICAgICAgICAgICAgICAgIGNvbXBvbmVudE1hbmFnZXIuZ2V0RmVhdHVyZShYSU5DTFVERV9GSVhVUF9MQU5HVUFHRSk7Ci0gICAgICAgICAgICBpZiAoZkNoaWxkQ29uZmlnICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmQ2hpbGRDb25maWcuc2V0RmVhdHVyZSgKLSAgICAgICAgICAgICAgICAgICAgWElOQ0xVREVfRklYVVBfTEFOR1VBR0UsCi0gICAgICAgICAgICAgICAgICAgIGZGaXh1cExhbmd1YWdlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICBmRml4dXBMYW5ndWFnZSA9IHRydWU7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBHZXQgc3ltYm9sIHRhYmxlLgotICAgICAgICB0cnkgewotICAgICAgICAgICAgU3ltYm9sVGFibGUgdmFsdWUgPQotICAgICAgICAgICAgICAgIChTeW1ib2xUYWJsZSljb21wb25lbnRNYW5hZ2VyLmdldFByb3BlcnR5KFNZTUJPTF9UQUJMRSk7Ci0gICAgICAgICAgICBpZiAodmFsdWUgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZTeW1ib2xUYWJsZSA9IHZhbHVlOwotICAgICAgICAgICAgICAgIGlmIChmQ2hpbGRDb25maWcgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBmQ2hpbGRDb25maWcuc2V0UHJvcGVydHkoU1lNQk9MX1RBQkxFLCB2YWx1ZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIGZTeW1ib2xUYWJsZSA9IG51bGw7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBHZXQgZXJyb3IgcmVwb3J0ZXIuCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBYTUxFcnJvclJlcG9ydGVyIHZhbHVlID0KLSAgICAgICAgICAgICAgICAoWE1MRXJyb3JSZXBvcnRlciljb21wb25lbnRNYW5hZ2VyLmdldFByb3BlcnR5KEVSUk9SX1JFUE9SVEVSKTsKLSAgICAgICAgICAgIGlmICh2YWx1ZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgc2V0RXJyb3JSZXBvcnRlcih2YWx1ZSk7Ci0gICAgICAgICAgICAgICAgaWYgKGZDaGlsZENvbmZpZyAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZDaGlsZENvbmZpZy5zZXRQcm9wZXJ0eShFUlJPUl9SRVBPUlRFUiwgdmFsdWUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICBmRXJyb3JSZXBvcnRlciA9IG51bGw7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBHZXQgZW50aXR5IHJlc29sdmVyLgotICAgICAgICB0cnkgewotICAgICAgICAgICAgWE1MRW50aXR5UmVzb2x2ZXIgdmFsdWUgPQotICAgICAgICAgICAgICAgIChYTUxFbnRpdHlSZXNvbHZlciljb21wb25lbnRNYW5hZ2VyLmdldFByb3BlcnR5KAotICAgICAgICAgICAgICAgICAgICBFTlRJVFlfUkVTT0xWRVIpOwotCi0gICAgICAgICAgICBpZiAodmFsdWUgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZFbnRpdHlSZXNvbHZlciA9IHZhbHVlOwotICAgICAgICAgICAgICAgIGlmIChmQ2hpbGRDb25maWcgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBmQ2hpbGRDb25maWcuc2V0UHJvcGVydHkoRU5USVRZX1JFU09MVkVSLCB2YWx1ZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIGZFbnRpdHlSZXNvbHZlciA9IG51bGw7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBHZXQgc2VjdXJpdHkgbWFuYWdlci4KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIFhNTFNlY3VyaXR5TWFuYWdlciB2YWx1ZSA9Ci0gICAgICAgICAgICAgICAgKFhNTFNlY3VyaXR5TWFuYWdlciljb21wb25lbnRNYW5hZ2VyLmdldFByb3BlcnR5KAotICAgICAgICAgICAgICAgICAgICBTRUNVUklUWV9NQU5BR0VSKTsKLQotICAgICAgICAgICAgaWYgKHZhbHVlICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmU2VjdXJpdHlNYW5hZ2VyID0gdmFsdWU7Ci0gICAgICAgICAgICAgICAgaWYgKGZDaGlsZENvbmZpZyAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZDaGlsZENvbmZpZy5zZXRQcm9wZXJ0eShTRUNVUklUWV9NQU5BR0VSLCB2YWx1ZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIGZTZWN1cml0eU1hbmFnZXIgPSBudWxsOwotICAgICAgICB9Ci0KLSAgICAgICAgZlNlY3VyaXR5UHJvcGVydHlNZ3IgPSAoWE1MU2VjdXJpdHlQcm9wZXJ0eU1hbmFnZXIpCi0gICAgICAgICAgICAgICAgY29tcG9uZW50TWFuYWdlci5nZXRQcm9wZXJ0eShDb25zdGFudHMuWE1MX1NFQ1VSSVRZX1BST1BFUlRZX01BTkFHRVIpOwotCi0gICAgICAgIC8vIEdldCBidWZmZXIgc2l6ZS4KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIEludGVnZXIgdmFsdWUgPQotICAgICAgICAgICAgICAgIChJbnRlZ2VyKWNvbXBvbmVudE1hbmFnZXIuZ2V0UHJvcGVydHkoCi0gICAgICAgICAgICAgICAgICAgIEJVRkZFUl9TSVpFKTsKLQotICAgICAgICAgICAgaWYgKHZhbHVlICE9IG51bGwgJiYgdmFsdWUuaW50VmFsdWUoKSA+IDApIHsKLSAgICAgICAgICAgICAgICBmQnVmZmVyU2l6ZSA9IHZhbHVlLmludFZhbHVlKCk7Ci0gICAgICAgICAgICAgICAgaWYgKGZDaGlsZENvbmZpZyAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZDaGlsZENvbmZpZy5zZXRQcm9wZXJ0eShCVUZGRVJfU0laRSwgdmFsdWUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIGZCdWZmZXJTaXplID0gKChJbnRlZ2VyKWdldFByb3BlcnR5RGVmYXVsdChCVUZGRVJfU0laRSkpLmludFZhbHVlKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgIGZCdWZmZXJTaXplID0gKChJbnRlZ2VyKWdldFByb3BlcnR5RGVmYXVsdChCVUZGRVJfU0laRSkpLmludFZhbHVlKCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBSZXNldCBYTUwgMS4wIHRleHQgcmVhZGVyLgotICAgICAgICBpZiAoZlhJbmNsdWRlMTBUZXh0UmVhZGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmWEluY2x1ZGUxMFRleHRSZWFkZXIuc2V0QnVmZmVyU2l6ZShmQnVmZmVyU2l6ZSk7Ci0gICAgICAgIH0KLSAgICAgICAgLy8gUmVzZXQgWE1MIDEuMSB0ZXh0IHJlYWRlci4KLSAgICAgICAgaWYgKGZYSW5jbHVkZTExVGV4dFJlYWRlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmWEluY2x1ZGUxMVRleHRSZWFkZXIuc2V0QnVmZmVyU2l6ZShmQnVmZmVyU2l6ZSk7Ci0gICAgICAgIH0KLQotICAgICAgICBmU2V0dGluZ3MgPSBuZXcgUGFyc2VyQ29uZmlndXJhdGlvblNldHRpbmdzKCk7Ci0gICAgICAgIGNvcHlGZWF0dXJlcyhjb21wb25lbnRNYW5hZ2VyLCBmU2V0dGluZ3MpOwotCi0gICAgICAgIC8vIFdlIGRvbid0IHdhbnQgYSBzY2hlbWEgdmFsaWRhdG9yIG9uIHRoZSBuZXcgcGlwZWxpbmUsCi0gICAgICAgIC8vIHNvIGlmIGl0IHdhcyBlbmFibGVkLCB3ZSBzZXQgdGhlIGZlYXR1cmUgdG8gZmFsc2UuIElmCi0gICAgICAgIC8vIHRoZSB2YWxpZGF0aW9uIGZlYXR1cmUgd2FzIGFsc28gZW5hYmxlZCB3ZSB0dXJuIG9uCi0gICAgICAgIC8vIGR5bmFtaWMgdmFsaWRhdGlvbiwgc28gdGhhdCBEVEQgdmFsaWRhdGlvbiBpcyBwZXJmb3JtZWQKLSAgICAgICAgLy8gb24gdGhlIGluY2x1ZGVkIGRvY3VtZW50cyBvbmx5IGlmIHRoZXkgaGF2ZSBhIERPQ1RZUEUuCi0gICAgICAgIC8vIFRoaXMgaXMgY29uc2lzdGVudCB3aXRoIHRoZSBiZWhhdmlvdXIgb24gdGhlIG1haW4gcGlwZWxpbmUuCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBpZiAoY29tcG9uZW50TWFuYWdlci5nZXRGZWF0dXJlKFNDSEVNQV9WQUxJREFUSU9OKSkgewotICAgICAgICAgICAgICAgIGZTZXR0aW5ncy5zZXRGZWF0dXJlKFNDSEVNQV9WQUxJREFUSU9OLCBmYWxzZSk7Ci0gICAgICAgICAgICAgICAgaWYgKGNvbXBvbmVudE1hbmFnZXIuZ2V0RmVhdHVyZShWQUxJREFUSU9OKSkgewotICAgICAgICAgICAgICAgICAgICBmU2V0dGluZ3Muc2V0RmVhdHVyZShEWU5BTUlDX1ZBTElEQVRJT04sIHRydWUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBlKSB7fQotCi0gICAgICAgIC8vIERvbid0IHJlc2V0IGZDaGlsZENvbmZpZyAtLSB3ZSBkb24ndCB3YW50IGl0IHRvIHNoYXJlIHRoZSBzYW1lIGNvbXBvbmVudHMuCi0gICAgICAgIC8vIEl0IHdpbGwgYmUgcmVzZXQgd2hlbiBpdCBpcyBhY3R1YWxseSB1c2VkIHRvIHBhcnNlIHNvbWV0aGluZy4KLSAgICB9IC8vIHJlc2V0KFhNTENvbXBvbmVudE1hbmFnZXIpCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGEgbGlzdCBvZiBmZWF0dXJlIGlkZW50aWZpZXJzIHRoYXQgYXJlIHJlY29nbml6ZWQgYnkKLSAgICAgKiB0aGlzIGNvbXBvbmVudC4gVGhpcyBtZXRob2QgbWF5IHJldHVybiBudWxsIGlmIG5vIGZlYXR1cmVzCi0gICAgICogYXJlIHJlY29nbml6ZWQgYnkgdGhpcyBjb21wb25lbnQuCi0gICAgICovCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIFN0cmluZ1tdIGdldFJlY29nbml6ZWRGZWF0dXJlcygpIHsKLSAgICAgICAgcmV0dXJuIChTdHJpbmdbXSkoUkVDT0dOSVpFRF9GRUFUVVJFUy5jbG9uZSgpKTsKLSAgICB9IC8vIGdldFJlY29nbml6ZWRGZWF0dXJlcygpOlN0cmluZ1tdCi0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSBzdGF0ZSBvZiBhIGZlYXR1cmUuIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSB0aGUgY29tcG9uZW50Ci0gICAgICogbWFuYWdlciBhbnkgdGltZSBhZnRlciByZXNldCB3aGVuIGEgZmVhdHVyZSBjaGFuZ2VzIHN0YXRlLgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gQ29tcG9uZW50cyBzaG91bGQgc2lsZW50bHkgaWdub3JlIGZlYXR1cmVzCi0gICAgICogdGhhdCBkbyBub3QgYWZmZWN0IHRoZSBvcGVyYXRpb24gb2YgdGhlIGNvbXBvbmVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBmZWF0dXJlSWQgVGhlIGZlYXR1cmUgaWRlbnRpZmllci4KLSAgICAgKiBAcGFyYW0gc3RhdGUgICAgIFRoZSBzdGF0ZSBvZiB0aGUgZmVhdHVyZS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiBUaGUgY29tcG9uZW50IHNob3VsZCBub3QgdGhyb3cKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcyBleGNlcHRpb24uCi0gICAgICogQHRocm93cyBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gVGhlIGNvbXBvbmVudCBzaG91bGQgbm90IHRocm93Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcyBleGNlcHRpb24uCi0gICAgICovCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIHZvaWQgc2V0RmVhdHVyZShTdHJpbmcgZmVhdHVyZUlkLCBib29sZWFuIHN0YXRlKQotICAgICAgICB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChmZWF0dXJlSWQuZXF1YWxzKEFMTE9XX1VFX0FORF9OT1RBVElPTl9FVkVOVFMpKSB7Ci0gICAgICAgICAgICBmU2VuZFVFQW5kTm90YXRpb25FdmVudHMgPSBzdGF0ZTsKLSAgICAgICAgfQotICAgICAgICBpZiAoZlNldHRpbmdzICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZOZWVkQ29weUZlYXR1cmVzID0gdHJ1ZTsKLSAgICAgICAgICAgIGZTZXR0aW5ncy5zZXRGZWF0dXJlKGZlYXR1cmVJZCwgc3RhdGUpOwotICAgICAgICB9Ci0gICAgfSAvLyBzZXRGZWF0dXJlKFN0cmluZyxib29sZWFuKQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhIGxpc3Qgb2YgcHJvcGVydHkgaWRlbnRpZmllcnMgdGhhdCBhcmUgcmVjb2duaXplZCBieQotICAgICAqIHRoaXMgY29tcG9uZW50LiBUaGlzIG1ldGhvZCBtYXkgcmV0dXJuIG51bGwgaWYgbm8gcHJvcGVydGllcwotICAgICAqIGFyZSByZWNvZ25pemVkIGJ5IHRoaXMgY29tcG9uZW50LgotICAgICAqLwotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyBTdHJpbmdbXSBnZXRSZWNvZ25pemVkUHJvcGVydGllcygpIHsKLSAgICAgICAgcmV0dXJuIChTdHJpbmdbXSkoUkVDT0dOSVpFRF9QUk9QRVJUSUVTLmNsb25lKCkpOwotICAgIH0gLy8gZ2V0UmVjb2duaXplZFByb3BlcnRpZXMoKTpTdHJpbmdbXQotCi0gICAgLyoqCi0gICAgICogU2V0cyB0aGUgdmFsdWUgb2YgYSBwcm9wZXJ0eS4gVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBjb21wb25lbnQKLSAgICAgKiBtYW5hZ2VyIGFueSB0aW1lIGFmdGVyIHJlc2V0IHdoZW4gYSBwcm9wZXJ0eSBjaGFuZ2VzIHZhbHVlLgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gQ29tcG9uZW50cyBzaG91bGQgc2lsZW50bHkgaWdub3JlIHByb3BlcnRpZXMKLSAgICAgKiB0aGF0IGRvIG5vdCBhZmZlY3QgdGhlIG9wZXJhdGlvbiBvZiB0aGUgY29tcG9uZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIHByb3BlcnR5SWQgVGhlIHByb3BlcnR5IGlkZW50aWZpZXIuCi0gICAgICogQHBhcmFtIHZhbHVlICAgICAgVGhlIHZhbHVlIG9mIHRoZSBwcm9wZXJ0eS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiBUaGUgY29tcG9uZW50IHNob3VsZCBub3QgdGhyb3cKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcyBleGNlcHRpb24uCi0gICAgICogQHRocm93cyBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gVGhlIGNvbXBvbmVudCBzaG91bGQgbm90IHRocm93Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcyBleGNlcHRpb24uCi0gICAgICovCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIHZvaWQgc2V0UHJvcGVydHkoU3RyaW5nIHByb3BlcnR5SWQsIE9iamVjdCB2YWx1ZSkKLSAgICAgICAgdGhyb3dzIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gewotICAgICAgICBpZiAocHJvcGVydHlJZC5lcXVhbHMoU1lNQk9MX1RBQkxFKSkgewotICAgICAgICAgICAgZlN5bWJvbFRhYmxlID0gKFN5bWJvbFRhYmxlKXZhbHVlOwotICAgICAgICAgICAgaWYgKGZDaGlsZENvbmZpZyAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZkNoaWxkQ29uZmlnLnNldFByb3BlcnR5KHByb3BlcnR5SWQsIHZhbHVlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotICAgICAgICBpZiAocHJvcGVydHlJZC5lcXVhbHMoRVJST1JfUkVQT1JURVIpKSB7Ci0gICAgICAgICAgICBzZXRFcnJvclJlcG9ydGVyKChYTUxFcnJvclJlcG9ydGVyKXZhbHVlKTsKLSAgICAgICAgICAgIGlmIChmQ2hpbGRDb25maWcgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZDaGlsZENvbmZpZy5zZXRQcm9wZXJ0eShwcm9wZXJ0eUlkLCB2YWx1ZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKHByb3BlcnR5SWQuZXF1YWxzKEVOVElUWV9SRVNPTFZFUikpIHsKLSAgICAgICAgICAgIGZFbnRpdHlSZXNvbHZlciA9IChYTUxFbnRpdHlSZXNvbHZlcil2YWx1ZTsKLSAgICAgICAgICAgIGlmIChmQ2hpbGRDb25maWcgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZDaGlsZENvbmZpZy5zZXRQcm9wZXJ0eShwcm9wZXJ0eUlkLCB2YWx1ZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKHByb3BlcnR5SWQuZXF1YWxzKFNFQ1VSSVRZX01BTkFHRVIpKSB7Ci0gICAgICAgICAgICBmU2VjdXJpdHlNYW5hZ2VyID0gKFhNTFNlY3VyaXR5TWFuYWdlcil2YWx1ZTsKLSAgICAgICAgICAgIGlmIChmQ2hpbGRDb25maWcgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZDaGlsZENvbmZpZy5zZXRQcm9wZXJ0eShwcm9wZXJ0eUlkLCB2YWx1ZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKHByb3BlcnR5SWQuZXF1YWxzKFhNTF9TRUNVUklUWV9QUk9QRVJUWV9NQU5BR0VSKSkgewotICAgICAgICAgICAgZlNlY3VyaXR5UHJvcGVydHlNZ3IgPSAoWE1MU2VjdXJpdHlQcm9wZXJ0eU1hbmFnZXIpdmFsdWU7Ci0KLSAgICAgICAgICAgIGlmIChmQ2hpbGRDb25maWcgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZDaGlsZENvbmZpZy5zZXRQcm9wZXJ0eShYTUxfU0VDVVJJVFlfUFJPUEVSVFlfTUFOQUdFUiwgdmFsdWUpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAocHJvcGVydHlJZC5lcXVhbHMoQlVGRkVSX1NJWkUpKSB7Ci0gICAgICAgICAgICBJbnRlZ2VyIGJ1ZmZlclNpemUgPSAoSW50ZWdlcikgdmFsdWU7Ci0gICAgICAgICAgICBpZiAoZkNoaWxkQ29uZmlnICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmQ2hpbGRDb25maWcuc2V0UHJvcGVydHkocHJvcGVydHlJZCwgdmFsdWUpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKGJ1ZmZlclNpemUgIT0gbnVsbCAmJiBidWZmZXJTaXplLmludFZhbHVlKCkgPiAwKSB7Ci0gICAgICAgICAgICAgICAgZkJ1ZmZlclNpemUgPSBidWZmZXJTaXplLmludFZhbHVlKCk7Ci0gICAgICAgICAgICAgICAgLy8gUmVzZXQgWE1MIDEuMCB0ZXh0IHJlYWRlci4KLSAgICAgICAgICAgICAgICBpZiAoZlhJbmNsdWRlMTBUZXh0UmVhZGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgZlhJbmNsdWRlMTBUZXh0UmVhZGVyLnNldEJ1ZmZlclNpemUoZkJ1ZmZlclNpemUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvLyBSZXNldCBYTUwgMS4xIHRleHQgcmVhZGVyLgotICAgICAgICAgICAgICAgIGlmIChmWEluY2x1ZGUxMVRleHRSZWFkZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBmWEluY2x1ZGUxMVRleHRSZWFkZXIuc2V0QnVmZmVyU2l6ZShmQnVmZmVyU2l6ZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0KLSAgICB9IC8vIHNldFByb3BlcnR5KFN0cmluZyxPYmplY3QpCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBkZWZhdWx0IHN0YXRlIGZvciBhIGZlYXR1cmUsIG9yIG51bGwgaWYgdGhpcwotICAgICAqIGNvbXBvbmVudCBkb2VzIG5vdCB3YW50IHRvIHJlcG9ydCBhIGRlZmF1bHQgdmFsdWUgZm9yIHRoaXMKLSAgICAgKiBmZWF0dXJlLgotICAgICAqCi0gICAgICogQHBhcmFtIGZlYXR1cmVJZCBUaGUgZmVhdHVyZSBpZGVudGlmaWVyLgotICAgICAqCi0gICAgICogQHNpbmNlIFhlcmNlcyAyLjIuMAotICAgICAqLwotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyBCb29sZWFuIGdldEZlYXR1cmVEZWZhdWx0KFN0cmluZyBmZWF0dXJlSWQpIHsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBSRUNPR05JWkVEX0ZFQVRVUkVTLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICBpZiAoUkVDT0dOSVpFRF9GRUFUVVJFU1tpXS5lcXVhbHMoZmVhdHVyZUlkKSkgewotICAgICAgICAgICAgICAgIHJldHVybiBGRUFUVVJFX0RFRkFVTFRTW2ldOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0gLy8gZ2V0RmVhdHVyZURlZmF1bHQoU3RyaW5nKTpCb29sZWFuCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBkZWZhdWx0IHN0YXRlIGZvciBhIHByb3BlcnR5LCBvciBudWxsIGlmIHRoaXMKLSAgICAgKiBjb21wb25lbnQgZG9lcyBub3Qgd2FudCB0byByZXBvcnQgYSBkZWZhdWx0IHZhbHVlIGZvciB0aGlzCi0gICAgICogcHJvcGVydHkuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcHJvcGVydHlJZCBUaGUgcHJvcGVydHkgaWRlbnRpZmllci4KLSAgICAgKgotICAgICAqIEBzaW5jZSBYZXJjZXMgMi4yLjAKLSAgICAgKi8KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgT2JqZWN0IGdldFByb3BlcnR5RGVmYXVsdChTdHJpbmcgcHJvcGVydHlJZCkgewotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IFJFQ09HTklaRURfUFJPUEVSVElFUy5sZW5ndGg7IGkrKykgewotICAgICAgICAgICAgaWYgKFJFQ09HTklaRURfUFJPUEVSVElFU1tpXS5lcXVhbHMocHJvcGVydHlJZCkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gUFJPUEVSVFlfREVGQVVMVFNbaV07Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfSAvLyBnZXRQcm9wZXJ0eURlZmF1bHQoU3RyaW5nKTpPYmplY3QKLQotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyB2b2lkIHNldERvY3VtZW50SGFuZGxlcihYTUxEb2N1bWVudEhhbmRsZXIgaGFuZGxlcikgewotICAgICAgICBmRG9jdW1lbnRIYW5kbGVyID0gaGFuZGxlcjsKLSAgICB9Ci0KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgWE1MRG9jdW1lbnRIYW5kbGVyIGdldERvY3VtZW50SGFuZGxlcigpIHsKLSAgICAgICAgcmV0dXJuIGZEb2N1bWVudEhhbmRsZXI7Ci0gICAgfQotCi0gICAgLy8gWE1MRG9jdW1lbnRIYW5kbGVyIG1ldGhvZHMKLQotICAgIC8qKgotICAgICAqIEV2ZW50IHNlbnQgYXQgdGhlIHN0YXJ0IG9mIHRoZSBkb2N1bWVudC4KLSAgICAgKgotICAgICAqIEEgZmF0YWwgZXJyb3Igd2lsbCBvY2N1ciBoZXJlLCBpZiBpdCBpcyBkZXRlY3RlZCB0aGF0IHRoaXMgZG9jdW1lbnQgaGFzIGJlZW4gcHJvY2Vzc2VkCi0gICAgICogYmVmb3JlLgotICAgICAqCi0gICAgICogVGhpcyBldmVudCBpcyBvbmx5IHBhc3NlZCBvbiB0byB0aGUgZG9jdW1lbnQgaGFuZGxlciBpZiB0aGlzIGlzIHRoZSByb290IGRvY3VtZW50LgotICAgICAqLwotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RG9jdW1lbnQoCi0gICAgICAgIFhNTExvY2F0b3IgbG9jYXRvciwKLSAgICAgICAgU3RyaW5nIGVuY29kaW5nLAotICAgICAgICBOYW1lc3BhY2VDb250ZXh0IG5hbWVzcGFjZUNvbnRleHQsCi0gICAgICAgIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy8gd2UgZG8gdGhpcyB0byBlbnN1cmUgdGhhdCB0aGUgcHJvcGVyIGxvY2F0aW9uIGlzIHJlcG9ydGVkIGluIGVycm9ycwotICAgICAgICAvLyBvdGhlcndpc2UsIHRoZSBsb2NhdG9yIGZyb20gdGhlIHJvb3QgZG9jdW1lbnQgd291bGQgYWx3YXlzIGJlIHVzZWQKLSAgICAgICAgZkVycm9yUmVwb3J0ZXIuc2V0RG9jdW1lbnRMb2NhdG9yKGxvY2F0b3IpOwotCi0gICAgICAgIGlmICghaXNSb290RG9jdW1lbnQoKQotICAgICAgICAgICAgJiYgZlBhcmVudFhJbmNsdWRlSGFuZGxlci5zZWFyY2hGb3JSZWN1cnNpdmVJbmNsdWRlcyhsb2NhdG9yKSkgewotICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigKLSAgICAgICAgICAgICAgICAiUmVjdXJzaXZlSW5jbHVkZSIsCi0gICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgbG9jYXRvci5nZXRFeHBhbmRlZFN5c3RlbUlkKCl9KTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmICghKG5hbWVzcGFjZUNvbnRleHQgaW5zdGFuY2VvZiBYSW5jbHVkZU5hbWVzcGFjZVN1cHBvcnQpKSB7Ci0gICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJJbmNvbXBhdGlibGVOYW1lc3BhY2VDb250ZXh0Iik7Ci0gICAgICAgIH0KLSAgICAgICAgZk5hbWVzcGFjZUNvbnRleHQgPSAoWEluY2x1ZGVOYW1lc3BhY2VTdXBwb3J0KW5hbWVzcGFjZUNvbnRleHQ7Ci0gICAgICAgIGZEb2NMb2NhdGlvbiA9IGxvY2F0b3I7Ci0KLSAgICAgICAgLy8gaW5pdGlhbGl6ZSB0aGUgY3VycmVudCBiYXNlIFVSSQotICAgICAgICBmQ3VycmVudEJhc2VVUkkuc2V0QmFzZVN5c3RlbUlkKGxvY2F0b3IuZ2V0QmFzZVN5c3RlbUlkKCkpOwotICAgICAgICBmQ3VycmVudEJhc2VVUkkuc2V0RXhwYW5kZWRTeXN0ZW1JZChsb2NhdG9yLmdldEV4cGFuZGVkU3lzdGVtSWQoKSk7Ci0gICAgICAgIGZDdXJyZW50QmFzZVVSSS5zZXRMaXRlcmFsU3lzdGVtSWQobG9jYXRvci5nZXRMaXRlcmFsU3lzdGVtSWQoKSk7Ci0gICAgICAgIHNhdmVCYXNlVVJJKCk7Ci0gICAgICAgIGlmIChhdWdzID09IG51bGwpIHsKLSAgICAgICAgICAgIGF1Z3MgPSBuZXcgQXVnbWVudGF0aW9uc0ltcGwoKTsKLSAgICAgICAgfQotICAgICAgICBhdWdzLnB1dEl0ZW0oQ1VSUkVOVF9CQVNFX1VSSSwgZkN1cnJlbnRCYXNlVVJJKTsKLQotICAgICAgICAvLyBpbml0aWFsaXplIHRoZSBjdXJyZW50IGxhbmd1YWdlCi0gICAgICAgIGZDdXJyZW50TGFuZ3VhZ2UgPSBYTUxTeW1ib2xzLkVNUFRZX1NUUklORzsKLSAgICAgICAgc2F2ZUxhbmd1YWdlKGZDdXJyZW50TGFuZ3VhZ2UpOwotCi0gICAgICAgIGlmIChpc1Jvb3REb2N1bWVudCgpICYmIGZEb2N1bWVudEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci5zdGFydERvY3VtZW50KAotICAgICAgICAgICAgICAgIGxvY2F0b3IsCi0gICAgICAgICAgICAgICAgZW5jb2RpbmcsCi0gICAgICAgICAgICAgICAgbmFtZXNwYWNlQ29udGV4dCwKLSAgICAgICAgICAgICAgICBhdWdzKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyB2b2lkIHhtbERlY2woCi0gICAgICAgIFN0cmluZyB2ZXJzaW9uLAotICAgICAgICBTdHJpbmcgZW5jb2RpbmcsCi0gICAgICAgIFN0cmluZyBzdGFuZGFsb25lLAotICAgICAgICBBdWdtZW50YXRpb25zIGF1Z3MpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBmSXNYTUwxMSA9ICIxLjEiLmVxdWFscyh2ZXJzaW9uKTsKLSAgICAgICAgaWYgKGlzUm9vdERvY3VtZW50KCkgJiYgZkRvY3VtZW50SGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLnhtbERlY2wodmVyc2lvbiwgZW5jb2RpbmcsIHN0YW5kYWxvbmUsIGF1Z3MpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIHZvaWQgZG9jdHlwZURlY2woCi0gICAgICAgIFN0cmluZyByb290RWxlbWVudCwKLSAgICAgICAgU3RyaW5nIHB1YmxpY0lkLAotICAgICAgICBTdHJpbmcgc3lzdGVtSWQsCi0gICAgICAgIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChpc1Jvb3REb2N1bWVudCgpICYmIGZEb2N1bWVudEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci5kb2N0eXBlRGVjbChyb290RWxlbWVudCwgcHVibGljSWQsIHN5c3RlbUlkLCBhdWdzKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyB2b2lkIGNvbW1lbnQoWE1MU3RyaW5nIHRleHQsIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmICghZkluRFREKSB7Ci0gICAgICAgICAgICBpZiAoZkRvY3VtZW50SGFuZGxlciAhPSBudWxsCi0gICAgICAgICAgICAgICAgJiYgZ2V0U3RhdGUoKSA9PSBTVEFURV9OT1JNQUxfUFJPQ0VTU0lORykgewotICAgICAgICAgICAgICAgIGZEZXB0aCsrOwotICAgICAgICAgICAgICAgIGF1Z3MgPSBtb2RpZnlBdWdtZW50YXRpb25zKGF1Z3MpOwotICAgICAgICAgICAgICAgIGZEb2N1bWVudEhhbmRsZXIuY29tbWVudCh0ZXh0LCBhdWdzKTsKLSAgICAgICAgICAgICAgICBmRGVwdGgtLTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChmRFRESGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmRFRESGFuZGxlci5jb21tZW50KHRleHQsIGF1Z3MpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIHZvaWQgcHJvY2Vzc2luZ0luc3RydWN0aW9uKAotICAgICAgICBTdHJpbmcgdGFyZ2V0LAotICAgICAgICBYTUxTdHJpbmcgZGF0YSwKLSAgICAgICAgQXVnbWVudGF0aW9ucyBhdWdzKQotICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKCFmSW5EVEQpIHsKLSAgICAgICAgICAgIGlmIChmRG9jdW1lbnRIYW5kbGVyICE9IG51bGwKLSAgICAgICAgICAgICAgICAmJiBnZXRTdGF0ZSgpID09IFNUQVRFX05PUk1BTF9QUk9DRVNTSU5HKSB7Ci0gICAgICAgICAgICAgICAgLy8gd2UgbmVlZCB0byBjaGFuZ2UgdGhlIGRlcHRoIGxpa2UgdGhpcyBzbyB0aGF0IG1vZGlmeUF1Z21lbnRhdGlvbnMoKSB3b3JrcwotICAgICAgICAgICAgICAgIGZEZXB0aCsrOwotICAgICAgICAgICAgICAgIGF1Z3MgPSBtb2RpZnlBdWdtZW50YXRpb25zKGF1Z3MpOwotICAgICAgICAgICAgICAgIGZEb2N1bWVudEhhbmRsZXIucHJvY2Vzc2luZ0luc3RydWN0aW9uKHRhcmdldCwgZGF0YSwgYXVncyk7Ci0gICAgICAgICAgICAgICAgZkRlcHRoLS07Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoZkRUREhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkRUREhhbmRsZXIucHJvY2Vzc2luZ0luc3RydWN0aW9uKHRhcmdldCwgZGF0YSwgYXVncyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQoCi0gICAgICAgIFFOYW1lIGVsZW1lbnQsCi0gICAgICAgIFhNTEF0dHJpYnV0ZXMgYXR0cmlidXRlcywKLSAgICAgICAgQXVnbWVudGF0aW9ucyBhdWdzKQotICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgZkRlcHRoKys7Ci0gICAgICAgIGludCBsYXN0U3RhdGUgPSBnZXRTdGF0ZShmRGVwdGggLSAxKTsKLSAgICAgICAgLy8gSWYgdGhlIGxhc3QgdHdvIHN0YXRlcyB3ZXJlIGZhbGxiYWNrIHRoZW4gdGhpcyBtdXN0IGJlIGEgZGVzY2VuZGFudCBvZiBhbiBpbmNsdWRlCi0gICAgICAgIC8vIGNoaWxkIHdoaWNoIGlzbid0IGEgZmFsbGJhY2suIFRoZSBzcGVjaWZpY2F0aW9uIHNheXMgd2Ugc2hvdWxkIGlnbm9yZSBzdWNoIGVsZW1lbnRzCi0gICAgICAgIC8vIGFuZCB0aGVpciBjaGlsZHJlbi4KLSAgICAgICAgaWYgKGxhc3RTdGF0ZSA9PSBTVEFURV9FWFBFQ1RfRkFMTEJBQ0sgJiYgZ2V0U3RhdGUoZkRlcHRoIC0gMikgPT0gU1RBVEVfRVhQRUNUX0ZBTExCQUNLKSB7Ci0gICAgICAgICAgICBzZXRTdGF0ZShTVEFURV9JR05PUkUpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgc2V0U3RhdGUobGFzdFN0YXRlKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIHdlIHByb2Nlc3MgdGhlIHhtbDpiYXNlIGFuZCB4bWw6bGFuZyBhdHRyaWJ1dGVzIHJlZ2FyZGxlc3MKLSAgICAgICAgLy8gb2Ygd2hhdCB0eXBlIG9mIGVsZW1lbnQgaXQgaXMuCi0gICAgICAgIHByb2Nlc3NYTUxCYXNlQXR0cmlidXRlcyhhdHRyaWJ1dGVzKTsKLSAgICAgICAgaWYgKGZGaXh1cExhbmd1YWdlKSB7Ci0gICAgICAgICAgICBwcm9jZXNzWE1MTGFuZ0F0dHJpYnV0ZXMoYXR0cmlidXRlcyk7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoaXNJbmNsdWRlRWxlbWVudChlbGVtZW50KSkgewotICAgICAgICAgICAgYm9vbGVhbiBzdWNjZXNzID0gdGhpcy5oYW5kbGVJbmNsdWRlRWxlbWVudChhdHRyaWJ1dGVzKTsKLSAgICAgICAgICAgIGlmIChzdWNjZXNzKSB7Ci0gICAgICAgICAgICAgICAgc2V0U3RhdGUoU1RBVEVfSUdOT1JFKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIHNldFN0YXRlKFNUQVRFX0VYUEVDVF9GQUxMQkFDSyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoaXNGYWxsYmFja0VsZW1lbnQoZWxlbWVudCkpIHsKLSAgICAgICAgICAgIHRoaXMuaGFuZGxlRmFsbGJhY2tFbGVtZW50KCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoaGFzWEluY2x1ZGVOYW1lc3BhY2UoZWxlbWVudCkpIHsKLSAgICAgICAgICAgIGlmIChnZXRTYXdJbmNsdWRlKGZEZXB0aCAtIDEpKSB7Ci0gICAgICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigKLSAgICAgICAgICAgICAgICAgICAgIkluY2x1ZGVDaGlsZCIsCi0gICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7IGVsZW1lbnQucmF3bmFtZSB9KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChnZXRTYXdGYWxsYmFjayhmRGVwdGggLSAxKSkgewotICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoCi0gICAgICAgICAgICAgICAgICAgICJGYWxsYmFja0NoaWxkIiwKLSAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgZWxlbWVudC5yYXduYW1lIH0pOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKGdldFN0YXRlKCkgPT0gU1RBVEVfTk9STUFMX1BST0NFU1NJTkcpIHsKLSAgICAgICAgICAgICAgICBpZiAoZlJlc3VsdERlcHRoKysgPT0gMCkgewotICAgICAgICAgICAgICAgICAgICBjaGVja011bHRpcGxlUm9vdEVsZW1lbnRzKCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGlmIChmRG9jdW1lbnRIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgYXVncyA9IG1vZGlmeUF1Z21lbnRhdGlvbnMoYXVncyk7Ci0gICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXMgPSBwcm9jZXNzQXR0cmlidXRlcyhhdHRyaWJ1dGVzKTsKLSAgICAgICAgICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci5zdGFydEVsZW1lbnQoZWxlbWVudCwgYXR0cmlidXRlcywgYXVncyk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKGdldFN0YXRlKCkgPT0gU1RBVEVfTk9STUFMX1BST0NFU1NJTkcpIHsKLSAgICAgICAgICAgIGlmIChmUmVzdWx0RGVwdGgrKyA9PSAwKSB7Ci0gICAgICAgICAgICAgICAgY2hlY2tNdWx0aXBsZVJvb3RFbGVtZW50cygpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKGZEb2N1bWVudEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGF1Z3MgPSBtb2RpZnlBdWdtZW50YXRpb25zKGF1Z3MpOwotICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXMgPSBwcm9jZXNzQXR0cmlidXRlcyhhdHRyaWJ1dGVzKTsKLSAgICAgICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLnN0YXJ0RWxlbWVudChlbGVtZW50LCBhdHRyaWJ1dGVzLCBhdWdzKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyB2b2lkIGVtcHR5RWxlbWVudCgKLSAgICAgICAgUU5hbWUgZWxlbWVudCwKLSAgICAgICAgWE1MQXR0cmlidXRlcyBhdHRyaWJ1dGVzLAotICAgICAgICBBdWdtZW50YXRpb25zIGF1Z3MpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBmRGVwdGgrKzsKLSAgICAgICAgaW50IGxhc3RTdGF0ZSA9IGdldFN0YXRlKGZEZXB0aCAtIDEpOwotICAgICAgICAvLyBJZiB0aGUgbGFzdCB0d28gc3RhdGVzIHdlcmUgZmFsbGJhY2sgdGhlbiB0aGlzIG11c3QgYmUgYSBkZXNjZW5kYW50IG9mIGFuIGluY2x1ZGUKLSAgICAgICAgLy8gY2hpbGQgd2hpY2ggaXNuJ3QgYSBmYWxsYmFjay4gVGhlIHNwZWNpZmljYXRpb24gc2F5cyB3ZSBzaG91bGQgaWdub3JlIHN1Y2ggZWxlbWVudHMKLSAgICAgICAgLy8gYW5kIHRoZWlyIGNoaWxkcmVuLgotICAgICAgICBpZiAobGFzdFN0YXRlID09IFNUQVRFX0VYUEVDVF9GQUxMQkFDSyAmJiBnZXRTdGF0ZShmRGVwdGggLSAyKSA9PSBTVEFURV9FWFBFQ1RfRkFMTEJBQ0spIHsKLSAgICAgICAgICAgIHNldFN0YXRlKFNUQVRFX0lHTk9SRSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBzZXRTdGF0ZShsYXN0U3RhdGUpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gd2UgcHJvY2VzcyB0aGUgeG1sOmJhc2UgYW5kIHhtbDpsYW5nIGF0dHJpYnV0ZXMgcmVnYXJkbGVzcwotICAgICAgICAvLyBvZiB3aGF0IHR5cGUgb2YgZWxlbWVudCBpdCBpcy4KLSAgICAgICAgcHJvY2Vzc1hNTEJhc2VBdHRyaWJ1dGVzKGF0dHJpYnV0ZXMpOwotICAgICAgICBpZiAoZkZpeHVwTGFuZ3VhZ2UpIHsKLSAgICAgICAgICAgIHByb2Nlc3NYTUxMYW5nQXR0cmlidXRlcyhhdHRyaWJ1dGVzKTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChpc0luY2x1ZGVFbGVtZW50KGVsZW1lbnQpKSB7Ci0gICAgICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSB0aGlzLmhhbmRsZUluY2x1ZGVFbGVtZW50KGF0dHJpYnV0ZXMpOwotICAgICAgICAgICAgaWYgKHN1Y2Nlc3MpIHsKLSAgICAgICAgICAgICAgICBzZXRTdGF0ZShTVEFURV9JR05PUkUpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiTm9GYWxsYmFjayIsCi0gICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7IGF0dHJpYnV0ZXMuZ2V0VmFsdWUobnVsbCwgImhyZWYiKSB9KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChpc0ZhbGxiYWNrRWxlbWVudChlbGVtZW50KSkgewotICAgICAgICAgICAgdGhpcy5oYW5kbGVGYWxsYmFja0VsZW1lbnQoKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChoYXNYSW5jbHVkZU5hbWVzcGFjZShlbGVtZW50KSkgewotICAgICAgICAgICAgaWYgKGdldFNhd0luY2x1ZGUoZkRlcHRoIC0gMSkpIHsKLSAgICAgICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKAotICAgICAgICAgICAgICAgICAgICAiSW5jbHVkZUNoaWxkIiwKLSAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgZWxlbWVudC5yYXduYW1lIH0pOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKGdldFNhd0ZhbGxiYWNrKGZEZXB0aCAtIDEpKSB7Ci0gICAgICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigKLSAgICAgICAgICAgICAgICAgICAgIkZhbGxiYWNrQ2hpbGQiLAotICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBlbGVtZW50LnJhd25hbWUgfSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoZ2V0U3RhdGUoKSA9PSBTVEFURV9OT1JNQUxfUFJPQ0VTU0lORykgewotICAgICAgICAgICAgICAgIGlmIChmUmVzdWx0RGVwdGggPT0gMCkgewotICAgICAgICAgICAgICAgICAgICBjaGVja011bHRpcGxlUm9vdEVsZW1lbnRzKCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGlmIChmRG9jdW1lbnRIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgYXVncyA9IG1vZGlmeUF1Z21lbnRhdGlvbnMoYXVncyk7Ci0gICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXMgPSBwcm9jZXNzQXR0cmlidXRlcyhhdHRyaWJ1dGVzKTsKLSAgICAgICAgICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci5lbXB0eUVsZW1lbnQoZWxlbWVudCwgYXR0cmlidXRlcywgYXVncyk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKGdldFN0YXRlKCkgPT0gU1RBVEVfTk9STUFMX1BST0NFU1NJTkcpIHsKLSAgICAgICAgICAgIGlmIChmUmVzdWx0RGVwdGggPT0gMCkgewotICAgICAgICAgICAgICAgIGNoZWNrTXVsdGlwbGVSb290RWxlbWVudHMoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChmRG9jdW1lbnRIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBhdWdzID0gbW9kaWZ5QXVnbWVudGF0aW9ucyhhdWdzKTsKLSAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzID0gcHJvY2Vzc0F0dHJpYnV0ZXMoYXR0cmlidXRlcyk7Ci0gICAgICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci5lbXB0eUVsZW1lbnQoZWxlbWVudCwgYXR0cmlidXRlcywgYXVncyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgLy8gcmVzZXQgdGhlIG91dCBvZiBzY29wZSBzdGFjayBlbGVtZW50cwotICAgICAgICBzZXRTYXdGYWxsYmFjayhmRGVwdGggKyAxLCBmYWxzZSk7Ci0gICAgICAgIHNldFNhd0luY2x1ZGUoZkRlcHRoLCBmYWxzZSk7Ci0KLSAgICAgICAgLy8gY2hlY2sgaWYgYW4geG1sOmJhc2UgaGFzIGdvbmUgb3V0IG9mIHNjb3BlCi0gICAgICAgIGlmIChmQmFzZVVSSVNjb3BlLnNpemUoKSA+IDAgJiYgZkRlcHRoID09IGZCYXNlVVJJU2NvcGUucGVlaygpKSB7Ci0gICAgICAgICAgICAvLyBwb3AgdGhlIHZhbHVlcyBmcm9tIHRoZSBzdGFjawotICAgICAgICAgICAgcmVzdG9yZUJhc2VVUkkoKTsKLSAgICAgICAgfQotICAgICAgICBmRGVwdGgtLTsKLSAgICB9Ci0KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgdm9pZCBlbmRFbGVtZW50KFFOYW1lIGVsZW1lbnQsIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgaWYgKGlzSW5jbHVkZUVsZW1lbnQoZWxlbWVudCkpIHsKLSAgICAgICAgICAgIC8vIGlmIHdlJ3JlIGVuZGluZyBhbiBpbmNsdWRlIGVsZW1lbnQsIGFuZCB3ZSB3ZXJlIGV4cGVjdGluZyBhIGZhbGxiYWNrCi0gICAgICAgICAgICAvLyB3ZSBjaGVjayB0byBzZWUgaWYgdGhlIGNoaWxkcmVuIG9mIHRoaXMgaW5jbHVkZSBlbGVtZW50IGNvbnRhaW5lZCBhIGZhbGxiYWNrCi0gICAgICAgICAgICBpZiAoZ2V0U3RhdGUoKSA9PSBTVEFURV9FWFBFQ1RfRkFMTEJBQ0sKLSAgICAgICAgICAgICAgICAmJiAhZ2V0U2F3RmFsbGJhY2soZkRlcHRoICsgMSkpIHsKLSAgICAgICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJOb0ZhbGxiYWNrIiwKLSAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgInVua25vd24iIH0pOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGlmIChpc0ZhbGxiYWNrRWxlbWVudChlbGVtZW50KSkgewotICAgICAgICAgICAgLy8gdGhlIHN0YXRlIHdvdWxkIGhhdmUgYmVlbiBzZXQgdG8gbm9ybWFsIHByb2Nlc3NpbmcgaWYgd2Ugd2VyZSBleHBlY3RpbmcgdGhlIGZhbGxiYWNrIGVsZW1lbnQKLSAgICAgICAgICAgIC8vIG5vdyB0aGF0IHdlJ3JlIGRvbmUgcHJvY2Vzc2luZyBpdCwgd2Ugc2hvdWxkIGlnbm9yZSBhbGwgdGhlIG90aGVyIGNoaWxkcmVuIG9mIHRoZSBpbmNsdWRlIGVsZW1lbnQKLSAgICAgICAgICAgIGlmIChnZXRTdGF0ZSgpID09IFNUQVRFX05PUk1BTF9QUk9DRVNTSU5HKSB7Ci0gICAgICAgICAgICAgICAgc2V0U3RhdGUoU1RBVEVfSUdOT1JFKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChnZXRTdGF0ZSgpID09IFNUQVRFX05PUk1BTF9QUk9DRVNTSU5HKSB7Ci0gICAgICAgICAgICAtLWZSZXN1bHREZXB0aDsKLSAgICAgICAgICAgIGlmIChmRG9jdW1lbnRIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLmVuZEVsZW1lbnQoZWxlbWVudCwgYXVncyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyByZXNldCB0aGUgb3V0IG9mIHNjb3BlIHN0YWNrIGVsZW1lbnRzCi0gICAgICAgIHNldFNhd0ZhbGxiYWNrKGZEZXB0aCArIDEsIGZhbHNlKTsKLSAgICAgICAgc2V0U2F3SW5jbHVkZShmRGVwdGgsIGZhbHNlKTsKLQotICAgICAgICAvLyBjaGVjayBpZiBhbiB4bWw6YmFzZSBoYXMgZ29uZSBvdXQgb2Ygc2NvcGUKLSAgICAgICAgaWYgKGZCYXNlVVJJU2NvcGUuc2l6ZSgpID4gMCAmJiBmRGVwdGggPT0gZkJhc2VVUklTY29wZS5wZWVrKCkpIHsKLSAgICAgICAgICAgIC8vIHBvcCB0aGUgdmFsdWVzIGZyb20gdGhlIHN0YWNrCi0gICAgICAgICAgICByZXN0b3JlQmFzZVVSSSgpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gY2hlY2sgaWYgYW4geG1sOmxhbmcgaGFzIGdvbmUgb3V0IG9mIHNjb3BlCi0gICAgICAgIGlmIChmTGFuZ3VhZ2VTY29wZS5zaXplKCkgPiAwICYmIGZEZXB0aCA9PSBmTGFuZ3VhZ2VTY29wZS5wZWVrKCkpIHsKLSAgICAgICAgICAgIC8vIHBvcCB0aGUgbGFuZ3VhZ2UgZnJvbSB0aGUgc3RhY2sKLSAgICAgICAgICAgIGZDdXJyZW50TGFuZ3VhZ2UgPSByZXN0b3JlTGFuZ3VhZ2UoKTsKLSAgICAgICAgfQotCi0gICAgICAgIGZEZXB0aC0tOwotICAgIH0KLQotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyB2b2lkIHN0YXJ0R2VuZXJhbEVudGl0eSgKLSAgICAgICAgU3RyaW5nIG5hbWUsCi0gICAgICAgIFhNTFJlc291cmNlSWRlbnRpZmllciByZXNJZCwKLSAgICAgICAgU3RyaW5nIGVuY29kaW5nLAotICAgICAgICBBdWdtZW50YXRpb25zIGF1Z3MpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBpZiAoZ2V0U3RhdGUoKSA9PSBTVEFURV9OT1JNQUxfUFJPQ0VTU0lORykgewotICAgICAgICAgICAgaWYgKGZSZXN1bHREZXB0aCA9PSAwKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGF1Z3MgIT0gbnVsbCAmJiBCb29sZWFuLlRSVUUuZXF1YWxzKGF1Z3MuZ2V0SXRlbShDb25zdGFudHMuRU5USVRZX1NLSVBQRUQpKSkgewotICAgICAgICAgICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJVbmV4cGFuZGVkRW50aXR5UmVmZXJlbmNlSWxsZWdhbCIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKGZEb2N1bWVudEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZEb2N1bWVudEhhbmRsZXIuc3RhcnRHZW5lcmFsRW50aXR5KG5hbWUsIHJlc0lkLCBlbmNvZGluZywgYXVncyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgdm9pZCB0ZXh0RGVjbChTdHJpbmcgdmVyc2lvbiwgU3RyaW5nIGVuY29kaW5nLCBBdWdtZW50YXRpb25zIGF1Z3MpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBpZiAoZkRvY3VtZW50SGFuZGxlciAhPSBudWxsCi0gICAgICAgICAgICAmJiBnZXRTdGF0ZSgpID09IFNUQVRFX05PUk1BTF9QUk9DRVNTSU5HKSB7Ci0gICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLnRleHREZWNsKHZlcnNpb24sIGVuY29kaW5nLCBhdWdzKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyB2b2lkIGVuZEdlbmVyYWxFbnRpdHkoU3RyaW5nIG5hbWUsIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChmRG9jdW1lbnRIYW5kbGVyICE9IG51bGwKLSAgICAgICAgICAgICYmIGdldFN0YXRlKCkgPT0gU1RBVEVfTk9STUFMX1BST0NFU1NJTkcKLSAgICAgICAgICAgICYmIGZSZXN1bHREZXB0aCAhPSAwKSB7Ci0gICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLmVuZEdlbmVyYWxFbnRpdHkobmFtZSwgYXVncyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgdm9pZCBjaGFyYWN0ZXJzKFhNTFN0cmluZyB0ZXh0LCBBdWdtZW50YXRpb25zIGF1Z3MpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBpZiAoZ2V0U3RhdGUoKSA9PSBTVEFURV9OT1JNQUxfUFJPQ0VTU0lORykgewotICAgICAgICAgICAgaWYgKGZSZXN1bHREZXB0aCA9PSAwKSB7Ci0gICAgICAgICAgICAgICAgY2hlY2tXaGl0ZXNwYWNlKHRleHQpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoZkRvY3VtZW50SGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgLy8gd2UgbmVlZCB0byBjaGFuZ2UgdGhlIGRlcHRoIGxpa2UgdGhpcyBzbyB0aGF0IG1vZGlmeUF1Z21lbnRhdGlvbnMoKSB3b3JrcwotICAgICAgICAgICAgICAgIGZEZXB0aCsrOwotICAgICAgICAgICAgICAgIGF1Z3MgPSBtb2RpZnlBdWdtZW50YXRpb25zKGF1Z3MpOwotICAgICAgICAgICAgICAgIGZEb2N1bWVudEhhbmRsZXIuY2hhcmFjdGVycyh0ZXh0LCBhdWdzKTsKLSAgICAgICAgICAgICAgICBmRGVwdGgtLTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyB2b2lkIGlnbm9yYWJsZVdoaXRlc3BhY2UoWE1MU3RyaW5nIHRleHQsIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChmRG9jdW1lbnRIYW5kbGVyICE9IG51bGwKLSAgICAgICAgICAgICYmIGdldFN0YXRlKCkgPT0gU1RBVEVfTk9STUFMX1BST0NFU1NJTkcKLSAgICAgICAgICAgICYmIGZSZXN1bHREZXB0aCAhPSAwKSB7Ci0gICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLmlnbm9yYWJsZVdoaXRlc3BhY2UodGV4dCwgYXVncyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgdm9pZCBzdGFydENEQVRBKEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChmRG9jdW1lbnRIYW5kbGVyICE9IG51bGwKLSAgICAgICAgICAgICYmIGdldFN0YXRlKCkgPT0gU1RBVEVfTk9STUFMX1BST0NFU1NJTkcKLSAgICAgICAgICAgICYmIGZSZXN1bHREZXB0aCAhPSAwKSB7Ci0gICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLnN0YXJ0Q0RBVEEoYXVncyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgdm9pZCBlbmRDREFUQShBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBpZiAoZkRvY3VtZW50SGFuZGxlciAhPSBudWxsCi0gICAgICAgICAgICAmJiBnZXRTdGF0ZSgpID09IFNUQVRFX05PUk1BTF9QUk9DRVNTSU5HCi0gICAgICAgICAgICAmJiBmUmVzdWx0RGVwdGggIT0gMCkgewotICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci5lbmRDREFUQShhdWdzKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyB2b2lkIGVuZERvY3VtZW50KEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChpc1Jvb3REb2N1bWVudCgpKSB7Ci0gICAgICAgICAgICBpZiAoIWZTZWVuUm9vdEVsZW1lbnQpIHsKLSAgICAgICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJSb290RWxlbWVudFJlcXVpcmVkIik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoZkRvY3VtZW50SGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci5lbmREb2N1bWVudChhdWdzKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyB2b2lkIHNldERvY3VtZW50U291cmNlKFhNTERvY3VtZW50U291cmNlIHNvdXJjZSkgewotICAgICAgICBmRG9jdW1lbnRTb3VyY2UgPSBzb3VyY2U7Ci0gICAgfQotCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIFhNTERvY3VtZW50U291cmNlIGdldERvY3VtZW50U291cmNlKCkgewotICAgICAgICByZXR1cm4gZkRvY3VtZW50U291cmNlOwotICAgIH0KLQotICAgIC8vIERUREhhbmRsZXIgbWV0aG9kcwotICAgIC8vIFdlIGFyZSBvbmx5IGludGVyZXN0ZWQgaW4gdGhlIG5vdGF0aW9uIGFuZCB1bnBhcnNlZCBlbnRpdHkgZGVjbGFyYXRpb25zLAotICAgIC8vIHRoZSByZXN0IHdlIGp1c3QgcGFzcyBvbgotCi0gICAgLyogKG5vbi1KYXZhZG9jKQotICAgICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MRFRESGFuZGxlciNhdHRyaWJ1dGVEZWNsKGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmdbXSwgamF2YS5sYW5nLlN0cmluZywgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MU3RyaW5nLCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxTdHJpbmcsIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLkF1Z21lbnRhdGlvbnMpCi0gICAgICovCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIHZvaWQgYXR0cmlidXRlRGVjbCgKLSAgICAgICAgU3RyaW5nIGVsZW1lbnROYW1lLAotICAgICAgICBTdHJpbmcgYXR0cmlidXRlTmFtZSwKLSAgICAgICAgU3RyaW5nIHR5cGUsCi0gICAgICAgIFN0cmluZ1tdIGVudW1lcmF0aW9uLAotICAgICAgICBTdHJpbmcgZGVmYXVsdFR5cGUsCi0gICAgICAgIFhNTFN0cmluZyBkZWZhdWx0VmFsdWUsCi0gICAgICAgIFhNTFN0cmluZyBub25Ob3JtYWxpemVkRGVmYXVsdFZhbHVlLAotICAgICAgICBBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBpZiAoZkRUREhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkRUREhhbmRsZXIuYXR0cmlidXRlRGVjbCgKLSAgICAgICAgICAgICAgICBlbGVtZW50TmFtZSwKLSAgICAgICAgICAgICAgICBhdHRyaWJ1dGVOYW1lLAotICAgICAgICAgICAgICAgIHR5cGUsCi0gICAgICAgICAgICAgICAgZW51bWVyYXRpb24sCi0gICAgICAgICAgICAgICAgZGVmYXVsdFR5cGUsCi0gICAgICAgICAgICAgICAgZGVmYXVsdFZhbHVlLAotICAgICAgICAgICAgICAgIG5vbk5vcm1hbGl6ZWREZWZhdWx0VmFsdWUsCi0gICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKiAobm9uLUphdmFkb2MpCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxEVERIYW5kbGVyI2VsZW1lbnREZWNsKGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmcsIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLkF1Z21lbnRhdGlvbnMpCi0gICAgICovCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIHZvaWQgZWxlbWVudERlY2woCi0gICAgICAgIFN0cmluZyBuYW1lLAotICAgICAgICBTdHJpbmcgY29udGVudE1vZGVsLAotICAgICAgICBBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBpZiAoZkRUREhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkRUREhhbmRsZXIuZWxlbWVudERlY2wobmFtZSwgY29udGVudE1vZGVsLCBhdWdtZW50YXRpb25zKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qIChub24tSmF2YWRvYykKLSAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTERUREhhbmRsZXIjZW5kQXR0bGlzdChjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5BdWdtZW50YXRpb25zKQotICAgICAqLwotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyB2b2lkIGVuZEF0dGxpc3QoQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKGZEVERIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZEVERIYW5kbGVyLmVuZEF0dGxpc3QoYXVnbWVudGF0aW9ucyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKiAobm9uLUphdmFkb2MpCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxEVERIYW5kbGVyI2VuZENvbmRpdGlvbmFsKGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLkF1Z21lbnRhdGlvbnMpCi0gICAgICovCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIHZvaWQgZW5kQ29uZGl0aW9uYWwoQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKQotICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKGZEVERIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZEVERIYW5kbGVyLmVuZENvbmRpdGlvbmFsKGF1Z21lbnRhdGlvbnMpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyogKG5vbi1KYXZhZG9jKQotICAgICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MRFRESGFuZGxlciNlbmREVEQoY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuQXVnbWVudGF0aW9ucykKLSAgICAgKi8KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgdm9pZCBlbmREVEQoQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKGZEVERIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZEVERIYW5kbGVyLmVuZERURChhdWdtZW50YXRpb25zKTsKLSAgICAgICAgfQotICAgICAgICBmSW5EVEQgPSBmYWxzZTsKLSAgICB9Ci0KLSAgICAvKiAobm9uLUphdmFkb2MpCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxEVERIYW5kbGVyI2VuZEV4dGVybmFsU3Vic2V0KGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLkF1Z21lbnRhdGlvbnMpCi0gICAgICovCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIHZvaWQgZW5kRXh0ZXJuYWxTdWJzZXQoQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKQotICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKGZEVERIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZEVERIYW5kbGVyLmVuZEV4dGVybmFsU3Vic2V0KGF1Z21lbnRhdGlvbnMpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyogKG5vbi1KYXZhZG9jKQotICAgICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MRFRESGFuZGxlciNlbmRQYXJhbWV0ZXJFbnRpdHkoamF2YS5sYW5nLlN0cmluZywgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuQXVnbWVudGF0aW9ucykKLSAgICAgKi8KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgdm9pZCBlbmRQYXJhbWV0ZXJFbnRpdHkoU3RyaW5nIG5hbWUsIEF1Z21lbnRhdGlvbnMgYXVnbWVudGF0aW9ucykKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChmRFRESGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmRFRESGFuZGxlci5lbmRQYXJhbWV0ZXJFbnRpdHkobmFtZSwgYXVnbWVudGF0aW9ucyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKiAobm9uLUphdmFkb2MpCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxEVERIYW5kbGVyI2V4dGVybmFsRW50aXR5RGVjbChqYXZhLmxhbmcuU3RyaW5nLCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxSZXNvdXJjZUlkZW50aWZpZXIsIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLkF1Z21lbnRhdGlvbnMpCi0gICAgICovCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIHZvaWQgZXh0ZXJuYWxFbnRpdHlEZWNsKAotICAgICAgICBTdHJpbmcgbmFtZSwKLSAgICAgICAgWE1MUmVzb3VyY2VJZGVudGlmaWVyIGlkZW50aWZpZXIsCi0gICAgICAgIEF1Z21lbnRhdGlvbnMgYXVnbWVudGF0aW9ucykKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChmRFRESGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmRFRESGFuZGxlci5leHRlcm5hbEVudGl0eURlY2wobmFtZSwgaWRlbnRpZmllciwgYXVnbWVudGF0aW9ucyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKiAobm9uLUphdmFkb2MpCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxEVERIYW5kbGVyI2dldERURFNvdXJjZSgpCi0gICAgICovCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIFhNTERURFNvdXJjZSBnZXREVERTb3VyY2UoKSB7Ci0gICAgICAgIHJldHVybiBmRFREU291cmNlOwotICAgIH0KLQotICAgIC8qIChub24tSmF2YWRvYykKLSAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTERUREhhbmRsZXIjaWdub3JlZENoYXJhY3RlcnMoY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MU3RyaW5nLCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5BdWdtZW50YXRpb25zKQotICAgICAqLwotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyB2b2lkIGlnbm9yZWRDaGFyYWN0ZXJzKFhNTFN0cmluZyB0ZXh0LCBBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBpZiAoZkRUREhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkRUREhhbmRsZXIuaWdub3JlZENoYXJhY3RlcnModGV4dCwgYXVnbWVudGF0aW9ucyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKiAobm9uLUphdmFkb2MpCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxEVERIYW5kbGVyI2ludGVybmFsRW50aXR5RGVjbChqYXZhLmxhbmcuU3RyaW5nLCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxTdHJpbmcsIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTFN0cmluZywgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuQXVnbWVudGF0aW9ucykKLSAgICAgKi8KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgdm9pZCBpbnRlcm5hbEVudGl0eURlY2woCi0gICAgICAgIFN0cmluZyBuYW1lLAotICAgICAgICBYTUxTdHJpbmcgdGV4dCwKLSAgICAgICAgWE1MU3RyaW5nIG5vbk5vcm1hbGl6ZWRUZXh0LAotICAgICAgICBBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBpZiAoZkRUREhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkRUREhhbmRsZXIuaW50ZXJuYWxFbnRpdHlEZWNsKAotICAgICAgICAgICAgICAgIG5hbWUsCi0gICAgICAgICAgICAgICAgdGV4dCwKLSAgICAgICAgICAgICAgICBub25Ob3JtYWxpemVkVGV4dCwKLSAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qIChub24tSmF2YWRvYykKLSAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTERUREhhbmRsZXIjbm90YXRpb25EZWNsKGphdmEubGFuZy5TdHJpbmcsIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTFJlc291cmNlSWRlbnRpZmllciwgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuQXVnbWVudGF0aW9ucykKLSAgICAgKi8KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgdm9pZCBub3RhdGlvbkRlY2woCi0gICAgICAgIFN0cmluZyBuYW1lLAotICAgICAgICBYTUxSZXNvdXJjZUlkZW50aWZpZXIgaWRlbnRpZmllciwKLSAgICAgICAgQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKQotICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgdGhpcy5hZGROb3RhdGlvbihuYW1lLCBpZGVudGlmaWVyLCBhdWdtZW50YXRpb25zKTsKLSAgICAgICAgaWYgKGZEVERIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZEVERIYW5kbGVyLm5vdGF0aW9uRGVjbChuYW1lLCBpZGVudGlmaWVyLCBhdWdtZW50YXRpb25zKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qIChub24tSmF2YWRvYykKLSAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTERUREhhbmRsZXIjc2V0RFREU291cmNlKGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxEVERTb3VyY2UpCi0gICAgICovCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIHZvaWQgc2V0RFREU291cmNlKFhNTERURFNvdXJjZSBzb3VyY2UpIHsKLSAgICAgICAgZkRURFNvdXJjZSA9IHNvdXJjZTsKLSAgICB9Ci0KLSAgICAvKiAobm9uLUphdmFkb2MpCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxEVERIYW5kbGVyI3N0YXJ0QXR0bGlzdChqYXZhLmxhbmcuU3RyaW5nLCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5BdWdtZW50YXRpb25zKQotICAgICAqLwotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyB2b2lkIHN0YXJ0QXR0bGlzdChTdHJpbmcgZWxlbWVudE5hbWUsIEF1Z21lbnRhdGlvbnMgYXVnbWVudGF0aW9ucykKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChmRFRESGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmRFRESGFuZGxlci5zdGFydEF0dGxpc3QoZWxlbWVudE5hbWUsIGF1Z21lbnRhdGlvbnMpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyogKG5vbi1KYXZhZG9jKQotICAgICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MRFRESGFuZGxlciNzdGFydENvbmRpdGlvbmFsKHNob3J0LCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5BdWdtZW50YXRpb25zKQotICAgICAqLwotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyB2b2lkIHN0YXJ0Q29uZGl0aW9uYWwoc2hvcnQgdHlwZSwgQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKQotICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKGZEVERIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZEVERIYW5kbGVyLnN0YXJ0Q29uZGl0aW9uYWwodHlwZSwgYXVnbWVudGF0aW9ucyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKiAobm9uLUphdmFkb2MpCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxEVERIYW5kbGVyI3N0YXJ0RFREKGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTExvY2F0b3IsIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLkF1Z21lbnRhdGlvbnMpCi0gICAgICovCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIHZvaWQgc3RhcnREVEQoWE1MTG9jYXRvciBsb2NhdG9yLCBBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBmSW5EVEQgPSB0cnVlOwotICAgICAgICBpZiAoZkRUREhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkRUREhhbmRsZXIuc3RhcnREVEQobG9jYXRvciwgYXVnbWVudGF0aW9ucyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKiAobm9uLUphdmFkb2MpCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxEVERIYW5kbGVyI3N0YXJ0RXh0ZXJuYWxTdWJzZXQoY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MUmVzb3VyY2VJZGVudGlmaWVyLCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5BdWdtZW50YXRpb25zKQotICAgICAqLwotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RXh0ZXJuYWxTdWJzZXQoCi0gICAgICAgIFhNTFJlc291cmNlSWRlbnRpZmllciBpZGVudGlmaWVyLAotICAgICAgICBBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBpZiAoZkRUREhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkRUREhhbmRsZXIuc3RhcnRFeHRlcm5hbFN1YnNldChpZGVudGlmaWVyLCBhdWdtZW50YXRpb25zKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qIChub24tSmF2YWRvYykKLSAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTERUREhhbmRsZXIjc3RhcnRQYXJhbWV0ZXJFbnRpdHkoamF2YS5sYW5nLlN0cmluZywgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MUmVzb3VyY2VJZGVudGlmaWVyLCBqYXZhLmxhbmcuU3RyaW5nLCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5BdWdtZW50YXRpb25zKQotICAgICAqLwotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyB2b2lkIHN0YXJ0UGFyYW1ldGVyRW50aXR5KAotICAgICAgICBTdHJpbmcgbmFtZSwKLSAgICAgICAgWE1MUmVzb3VyY2VJZGVudGlmaWVyIGlkZW50aWZpZXIsCi0gICAgICAgIFN0cmluZyBlbmNvZGluZywKLSAgICAgICAgQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKQotICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKGZEVERIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZEVERIYW5kbGVyLnN0YXJ0UGFyYW1ldGVyRW50aXR5KAotICAgICAgICAgICAgICAgIG5hbWUsCi0gICAgICAgICAgICAgICAgaWRlbnRpZmllciwKLSAgICAgICAgICAgICAgICBlbmNvZGluZywKLSAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qIChub24tSmF2YWRvYykKLSAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTERUREhhbmRsZXIjdW5wYXJzZWRFbnRpdHlEZWNsKGphdmEubGFuZy5TdHJpbmcsIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTFJlc291cmNlSWRlbnRpZmllciwgamF2YS5sYW5nLlN0cmluZywgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuQXVnbWVudGF0aW9ucykKLSAgICAgKi8KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgdm9pZCB1bnBhcnNlZEVudGl0eURlY2woCi0gICAgICAgIFN0cmluZyBuYW1lLAotICAgICAgICBYTUxSZXNvdXJjZUlkZW50aWZpZXIgaWRlbnRpZmllciwKLSAgICAgICAgU3RyaW5nIG5vdGF0aW9uLAotICAgICAgICBBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICB0aGlzLmFkZFVucGFyc2VkRW50aXR5KG5hbWUsIGlkZW50aWZpZXIsIG5vdGF0aW9uLCBhdWdtZW50YXRpb25zKTsKLSAgICAgICAgaWYgKGZEVERIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZEVERIYW5kbGVyLnVucGFyc2VkRW50aXR5RGVjbCgKLSAgICAgICAgICAgICAgICBuYW1lLAotICAgICAgICAgICAgICAgIGlkZW50aWZpZXIsCi0gICAgICAgICAgICAgICAgbm90YXRpb24sCi0gICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKiAobm9uLUphdmFkb2MpCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MRFREU291cmNlI2dldERUREhhbmRsZXIoKQotICAgICAqLwotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyBYTUxEVERIYW5kbGVyIGdldERUREhhbmRsZXIoKSB7Ci0gICAgICAgIHJldHVybiBmRFRESGFuZGxlcjsKLSAgICB9Ci0KLSAgICAvKiAobm9uLUphdmFkb2MpCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MRFREU291cmNlI3NldERUREhhbmRsZXIoY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MRFRESGFuZGxlcikKLSAgICAgKi8KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgdm9pZCBzZXREVERIYW5kbGVyKFhNTERUREhhbmRsZXIgaGFuZGxlcikgewotICAgICAgICBmRFRESGFuZGxlciA9IGhhbmRsZXI7Ci0gICAgfQotCi0gICAgLy8gWEluY2x1ZGVIYW5kbGVyIG1ldGhvZHMKLQotICAgIHByaXZhdGUgdm9pZCBzZXRFcnJvclJlcG9ydGVyKFhNTEVycm9yUmVwb3J0ZXIgcmVwb3J0ZXIpIHsKLSAgICAgICAgZkVycm9yUmVwb3J0ZXIgPSByZXBvcnRlcjsKLSAgICAgICAgaWYgKGZFcnJvclJlcG9ydGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnB1dE1lc3NhZ2VGb3JtYXR0ZXIoCi0gICAgICAgICAgICAgICAgWEluY2x1ZGVNZXNzYWdlRm9ybWF0dGVyLlhJTkNMVURFX0RPTUFJTiwgZlhJbmNsdWRlTWVzc2FnZUZvcm1hdHRlcik7Ci0gICAgICAgICAgICAvLyB0aGlzIGVuc3VyZXMgdGhlIHByb3BlciBsb2NhdGlvbiBpcyBkaXNwbGF5ZWQgaW4gZXJyb3IgbWVzc2FnZXMKLSAgICAgICAgICAgIGlmIChmRG9jTG9jYXRpb24gIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnNldERvY3VtZW50TG9jYXRvcihmRG9jTG9jYXRpb24pOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHJvdGVjdGVkIHZvaWQgaGFuZGxlRmFsbGJhY2tFbGVtZW50KCkgewotICAgICAgICBpZiAoIWdldFNhd0luY2x1ZGUoZkRlcHRoIC0gMSkpIHsKLSAgICAgICAgICAgIGlmIChnZXRTdGF0ZSgpID09IFNUQVRFX0lHTk9SRSkgewotICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIkZhbGxiYWNrUGFyZW50Iik7Ci0gICAgICAgIH0KLQotICAgICAgICBzZXRTYXdJbmNsdWRlKGZEZXB0aCwgZmFsc2UpOwotICAgICAgICBmTmFtZXNwYWNlQ29udGV4dC5zZXRDb250ZXh0SW52YWxpZCgpOwotCi0gICAgICAgIGlmIChnZXRTYXdGYWxsYmFjayhmRGVwdGgpKSB7Ci0gICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJNdWx0aXBsZUZhbGxiYWNrcyIpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgc2V0U2F3RmFsbGJhY2soZkRlcHRoLCB0cnVlKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIEVpdGhlciB0aGUgc3RhdGUgaXMgU1RBVEVfRVhQRUNUX0ZBTExCQUNLIG9yIGl0J3MgU1RBVEVfSUdOT1JFLgotICAgICAgICAvLyBJZiB3ZSdyZSBpZ25vcmluZywgd2Ugd2FudCB0byBzdGF5IGlnbm9yaW5nLiBCdXQgaWYgd2UncmUgZXhwZWN0aW5nIHRoaXMgZmFsbGJhY2sgZWxlbWVudCwKLSAgICAgICAgLy8gd2Ugd2FudCB0byBzaWduYWwgdGhhdCB3ZSBzaG91bGQgcHJvY2VzcyB0aGUgY2hpbGRyZW4uCi0gICAgICAgIGlmIChnZXRTdGF0ZSgpID09IFNUQVRFX0VYUEVDVF9GQUxMQkFDSykgewotICAgICAgICAgICAgc2V0U3RhdGUoU1RBVEVfTk9STUFMX1BST0NFU1NJTkcpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gaGFuZGxlSW5jbHVkZUVsZW1lbnQoWE1MQXR0cmlidXRlcyBhdHRyaWJ1dGVzKQotICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKGdldFNhd0luY2x1ZGUoZkRlcHRoIC0gMSkpIHsKLSAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIkluY2x1ZGVDaGlsZCIsIG5ldyBPYmplY3RbXSB7IFhJTkNMVURFX0lOQ0xVREUgfSk7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGdldFN0YXRlKCkgPT0gU1RBVEVfSUdOT1JFKSB7Ci0gICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgfQotICAgICAgICBzZXRTYXdJbmNsdWRlKGZEZXB0aCwgdHJ1ZSk7Ci0gICAgICAgIGZOYW1lc3BhY2VDb250ZXh0LnNldENvbnRleHRJbnZhbGlkKCk7Ci0KLSAgICAgICAgLy8gVE9ETzogZG9lcyBKYXZhIHVzZSBJVVJJcyBieSBkZWZhdWx0PwotICAgICAgICAvLyAgICAgICBbRGVmaW5pdGlvbjogQW4gaW50ZXJuYXRpb25hbGl6ZWQgVVJJIHJlZmVyZW5jZSwgb3IgSVVSSSwgaXMgYSBVUkkgcmVmZXJlbmNlIHRoYXQgZGlyZWN0bHkgdXNlcyBbVW5pY29kZV0gY2hhcmFjdGVycy5dCi0gICAgICAgIC8vIFRPRE86IGZpZ3VyZSBvdXQgd2hhdCBzZWN0aW9uIDQuMS4xIG9mIHRoZSBYSW5jbHVkZSBzcGVjIGlzIHRhbGtpbmcgYWJvdXQKLSAgICAgICAgLy8gICAgICAgaGFzIHRvIGRvIHdpdGggZGlzYWxsb3dlZCBBU0NJSSBjaGFyYWN0ZXIgZXNjYXBpbmcKLSAgICAgICAgLy8gICAgICAgdGhpcyB0aWVzIGluIHdpdGggdGhlIGFib3ZlIElVUkkgc2VjdGlvbiwgYnV0IEkgc3VzcGVjdCBKYXZhIGFscmVhZHkgZG9lcyBpdAotCi0gICAgICAgIFN0cmluZyBocmVmID0gYXR0cmlidXRlcy5nZXRWYWx1ZShYSU5DTFVERV9BVFRSX0hSRUYpOwotICAgICAgICBTdHJpbmcgcGFyc2UgPSBhdHRyaWJ1dGVzLmdldFZhbHVlKFhJTkNMVURFX0FUVFJfUEFSU0UpOwotICAgICAgICBTdHJpbmcgeHBvaW50ZXIgPSAgYXR0cmlidXRlcy5nZXRWYWx1ZShYUE9JTlRFUik7Ci0gICAgICAgIFN0cmluZyBhY2NlcHQgPSBhdHRyaWJ1dGVzLmdldFZhbHVlKFhJTkNMVURFX0FUVFJfQUNDRVBUKTsKLSAgICAgICAgU3RyaW5nIGFjY2VwdExhbmd1YWdlID0gYXR0cmlidXRlcy5nZXRWYWx1ZShYSU5DTFVERV9BVFRSX0FDQ0VQVF9MQU5HVUFHRSk7Ci0KLSAgICAgICAgaWYgKHBhcnNlID09IG51bGwpIHsKLSAgICAgICAgICAgIHBhcnNlID0gWElOQ0xVREVfUEFSU0VfWE1MOwotICAgICAgICB9Ci0gICAgICAgIGlmIChocmVmID09IG51bGwpIHsKLSAgICAgICAgICAgIGhyZWYgPSBYTUxTeW1ib2xzLkVNUFRZX1NUUklORzsKLSAgICAgICAgfQotICAgICAgICBpZiAoaHJlZi5sZW5ndGgoKSA9PSAwICYmIFhJTkNMVURFX1BBUlNFX1hNTC5lcXVhbHMocGFyc2UpKSB7Ci0gICAgICAgICAgICBpZiAoeHBvaW50ZXIgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIlhwb2ludGVyTWlzc2luZyIpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgLy8gV2hlbiBwYXJzZT0ieG1sIiBhbmQgYW4geHBvaW50ZXIgaXMgc3BlY2lmaWVkIHRyZWF0Ci0gICAgICAgICAgICAgICAgLy8gYWxsIGFic2VuY2VzIG9mIHRoZSBocmVmIGF0dHJpYnV0ZSBhcyBhIHJlc291cmNlIGVycm9yLgotICAgICAgICAgICAgICAgIExvY2FsZSBsb2NhbGUgPSAoZkVycm9yUmVwb3J0ZXIgIT0gbnVsbCkgPyBmRXJyb3JSZXBvcnRlci5nZXRMb2NhbGUoKSA6IG51bGw7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIHJlYXNvbiA9IGZYSW5jbHVkZU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShsb2NhbGUsICJYUG9pbnRlclN0cmVhbWFiaWxpdHkiLCBudWxsKTsKLSAgICAgICAgICAgICAgICByZXBvcnRSZXNvdXJjZUVycm9yKCJYTUxSZXNvdXJjZUVycm9yIiwgbmV3IE9iamVjdFtdIHsgaHJlZiwgcmVhc29uIH0pOwotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIFVSSSBocmVmVVJJID0gbnVsbDsKLQotICAgICAgICAvLyBDaGVjayB3aGV0aGVyIGhyZWYgaXMgY29ycmVjdCBhbmQgcGVyZm9ybSBlc2NhcGluZyBhcyBwZXIgc2VjdGlvbiA0LjEuMSBvZiB0aGUgWEluY2x1ZGUgc3BlYy4KLSAgICAgICAgLy8gUmVwb3J0IGZhdGFsIGVycm9yIGlmIHRoZSBocmVmIHZhbHVlIGNvbnRhaW5zIGEgZnJhZ21lbnQgaWRlbnRpZmllciBvciBpZiB0aGUgdmFsdWUgYWZ0ZXIKLSAgICAgICAgLy8gZXNjYXBpbmcgaXMgYSBzeW50YWN0aWNhbGx5IGludmFsaWQgVVJJIG9yIElSSS4KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGhyZWZVUkkgPSBuZXcgVVJJKGhyZWYsIHRydWUpOwotICAgICAgICAgICAgaWYgKGhyZWZVUkkuZ2V0RnJhZ21lbnQoKSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiSHJlZkZyYWdtZW50SWRlbnRpZmllcklsbGVnYWwiLCBuZXcgT2JqZWN0W10ge2hyZWZ9KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoVVJJLk1hbGZvcm1lZFVSSUV4Y2VwdGlvbiBleGMpIHsKLSAgICAgICAgICAgIFN0cmluZyBuZXdIcmVmID0gZXNjYXBlSHJlZihocmVmKTsKLSAgICAgICAgICAgIGlmIChocmVmICE9IG5ld0hyZWYpIHsKLSAgICAgICAgICAgICAgICBocmVmID0gbmV3SHJlZjsKLSAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICBocmVmVVJJID0gbmV3IFVSSShocmVmLCB0cnVlKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGhyZWZVUkkuZ2V0RnJhZ21lbnQoKSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJIcmVmRnJhZ21lbnRJZGVudGlmaWVySWxsZWdhbCIsIG5ldyBPYmplY3RbXSB7aHJlZn0pOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGNhdGNoIChVUkkuTWFsZm9ybWVkVVJJRXhjZXB0aW9uIGV4YzIpIHsKLSAgICAgICAgICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiSHJlZlN5bnRhY3RpY2FsbHlJbnZhbGlkIiwgbmV3IE9iamVjdFtdIHtocmVmfSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiSHJlZlN5bnRhY3RpY2FsbHlJbnZhbGlkIiwgbmV3IE9iamVjdFtdIHtocmVmfSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBWZXJpZnkgdGhhdCBpZiBhbiBhY2NlcHQgYW5kL29yIGFuIGFjY2VwdC1sYW5ndWFnZSBhdHRyaWJ1dGUgZXhpc3QKLSAgICAgICAgLy8gdGhhdCB0aGUgdmFsdWUocykgZG9uJ3QgY29udGFpbiBkaXNhbGxvd2VkIGNoYXJhY3RlcnMuCi0gICAgICAgIGlmIChhY2NlcHQgIT0gbnVsbCAmJiAhaXNWYWxpZEluSFRUUEhlYWRlcihhY2NlcHQpKSB7Ci0gICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJBY2NlcHRNYWxmb3JtZWQiLCBudWxsKTsKLSAgICAgICAgICAgIGFjY2VwdCA9IG51bGw7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGFjY2VwdExhbmd1YWdlICE9IG51bGwgJiYgIWlzVmFsaWRJbkhUVFBIZWFkZXIoYWNjZXB0TGFuZ3VhZ2UpKSB7Ci0gICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJBY2NlcHRMYW5ndWFnZU1hbGZvcm1lZCIsIG51bGwpOwotICAgICAgICAgICAgYWNjZXB0TGFuZ3VhZ2UgPSBudWxsOwotICAgICAgICB9Ci0KLSAgICAgICAgWE1MSW5wdXRTb3VyY2UgaW5jbHVkZWRTb3VyY2UgPSBudWxsOwotICAgICAgICBpZiAoZkVudGl0eVJlc29sdmVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgWE1MUmVzb3VyY2VJZGVudGlmaWVyIHJlc291cmNlSWRlbnRpZmllciA9Ci0gICAgICAgICAgICAgICAgICAgIG5ldyBYTUxSZXNvdXJjZUlkZW50aWZpZXJJbXBsKAotICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwKLSAgICAgICAgICAgICAgICAgICAgICAgIGhyZWYsCi0gICAgICAgICAgICAgICAgICAgICAgICBmQ3VycmVudEJhc2VVUkkuZ2V0RXhwYW5kZWRTeXN0ZW1JZCgpLAotICAgICAgICAgICAgICAgICAgICAgICAgWE1MRW50aXR5TWFuYWdlci5leHBhbmRTeXN0ZW1JZCgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBocmVmLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZDdXJyZW50QmFzZVVSSS5nZXRFeHBhbmRlZFN5c3RlbUlkKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UpKTsKLQotICAgICAgICAgICAgICAgIGluY2x1ZGVkU291cmNlID0KLSAgICAgICAgICAgICAgICAgICAgZkVudGl0eVJlc29sdmVyLnJlc29sdmVFbnRpdHkocmVzb3VyY2VJZGVudGlmaWVyKTsKLQotICAgICAgICAgICAgICAgIGlmIChpbmNsdWRlZFNvdXJjZSAhPSBudWxsICYmCi0gICAgICAgICAgICAgICAgICAgICEoaW5jbHVkZWRTb3VyY2UgaW5zdGFuY2VvZiBIVFRQSW5wdXRTb3VyY2UpICYmCi0gICAgICAgICAgICAgICAgICAgIChhY2NlcHQgIT0gbnVsbCB8fCBhY2NlcHRMYW5ndWFnZSAhPSBudWxsKSAmJgotICAgICAgICAgICAgICAgICAgICBpbmNsdWRlZFNvdXJjZS5nZXRDaGFyYWN0ZXJTdHJlYW0oKSA9PSBudWxsICYmCi0gICAgICAgICAgICAgICAgICAgIGluY2x1ZGVkU291cmNlLmdldEJ5dGVTdHJlYW0oKSA9PSBudWxsKSB7Ci0KLSAgICAgICAgICAgICAgICAgICAgaW5jbHVkZWRTb3VyY2UgPSBjcmVhdGVJbnB1dFNvdXJjZShpbmNsdWRlZFNvdXJjZS5nZXRQdWJsaWNJZCgpLCBpbmNsdWRlZFNvdXJjZS5nZXRTeXN0ZW1JZCgpLAotICAgICAgICAgICAgICAgICAgICAgICAgaW5jbHVkZWRTb3VyY2UuZ2V0QmFzZVN5c3RlbUlkKCksIGFjY2VwdCwgYWNjZXB0TGFuZ3VhZ2UpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgcmVwb3J0UmVzb3VyY2VFcnJvcigKLSAgICAgICAgICAgICAgICAgICAgIlhNTFJlc291cmNlRXJyb3IiLAotICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBocmVmLCBlLmdldE1lc3NhZ2UoKX0pOwotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGlmIChpbmNsdWRlZFNvdXJjZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAvLyBzZXR1cCBhbiBIVFRQSW5wdXRTb3VyY2UgaWYgZWl0aGVyIG9mIHRoZSBjb250ZW50IG5lZ290YXRpb24gYXR0cmlidXRlcyB3ZXJlIHNwZWNpZmllZC4KLSAgICAgICAgICAgIGlmIChhY2NlcHQgIT0gbnVsbCB8fCBhY2NlcHRMYW5ndWFnZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgaW5jbHVkZWRTb3VyY2UgPSBjcmVhdGVJbnB1dFNvdXJjZShudWxsLCBocmVmLCBmQ3VycmVudEJhc2VVUkkuZ2V0RXhwYW5kZWRTeXN0ZW1JZCgpLCBhY2NlcHQsIGFjY2VwdExhbmd1YWdlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIGluY2x1ZGVkU291cmNlID0gbmV3IFhNTElucHV0U291cmNlKG51bGwsIGhyZWYsIGZDdXJyZW50QmFzZVVSSS5nZXRFeHBhbmRlZFN5c3RlbUlkKCkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKHBhcnNlLmVxdWFscyhYSU5DTFVERV9QQVJTRV9YTUwpKSB7Ci0gICAgICAgICAgICAvLyBJbnN0ZWFkIG9mIGFsd2F5cyBjcmVhdGluZyBhIG5ldyBjb25maWd1cmF0aW9uLCB0aGUgZmlyc3Qgb25lIGNhbiBiZSByZXVzZWQKLSAgICAgICAgICAgIGlmICgoeHBvaW50ZXIgIT0gbnVsbCAmJiBmWFBvaW50ZXJDaGlsZENvbmZpZyA9PSBudWxsKQotICAgICAgICAgICAgICAgICAgICAgICAgfHwgKHhwb2ludGVyID09IG51bGwgJiYgZlhJbmNsdWRlQ2hpbGRDb25maWcgPT0gbnVsbCkgKSB7Ci0KLSAgICAgICAgICAgICAgICBTdHJpbmcgcGFyc2VyTmFtZSA9IFhJTkNMVURFX0RFRkFVTFRfQ09ORklHVVJBVElPTjsKLSAgICAgICAgICAgICAgICBpZiAoeHBvaW50ZXIgIT0gbnVsbCkKLSAgICAgICAgICAgICAgICAgICAgICAgIHBhcnNlck5hbWUgPSAiY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5wYXJzZXJzLlhQb2ludGVyUGFyc2VyQ29uZmlndXJhdGlvbiI7Ci0KLSAgICAgICAgICAgICAgICBmQ2hpbGRDb25maWcgPQotICAgICAgICAgICAgICAgICAgICAoWE1MUGFyc2VyQ29uZmlndXJhdGlvbilPYmplY3RGYWN0b3J5Lm5ld0luc3RhbmNlKAotICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2VyTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgIHRydWUpOwotCi0gICAgICAgICAgICAgICAgLy8gdXNlIHRoZSBzYW1lIHN5bWJvbCB0YWJsZSwgZXJyb3IgcmVwb3J0ZXIsIGVudGl0eSByZXNvbHZlciwgc2VjdXJpdHkgbWFuYWdlciBhbmQgYnVmZmVyIHNpemUuCi0gICAgICAgICAgICAgICAgaWYgKGZTeW1ib2xUYWJsZSAhPSBudWxsKSBmQ2hpbGRDb25maWcuc2V0UHJvcGVydHkoU1lNQk9MX1RBQkxFLCBmU3ltYm9sVGFibGUpOwotICAgICAgICAgICAgICAgIGlmIChmRXJyb3JSZXBvcnRlciAhPSBudWxsKSBmQ2hpbGRDb25maWcuc2V0UHJvcGVydHkoRVJST1JfUkVQT1JURVIsIGZFcnJvclJlcG9ydGVyKTsKLSAgICAgICAgICAgICAgICBpZiAoZkVudGl0eVJlc29sdmVyICE9IG51bGwpIGZDaGlsZENvbmZpZy5zZXRQcm9wZXJ0eShFTlRJVFlfUkVTT0xWRVIsIGZFbnRpdHlSZXNvbHZlcik7Ci0gICAgICAgICAgICAgICAgZkNoaWxkQ29uZmlnLnNldFByb3BlcnR5KFNFQ1VSSVRZX01BTkFHRVIsIGZTZWN1cml0eU1hbmFnZXIpOwotICAgICAgICAgICAgICAgIGZDaGlsZENvbmZpZy5zZXRQcm9wZXJ0eShYTUxfU0VDVVJJVFlfUFJPUEVSVFlfTUFOQUdFUiwgZlNlY3VyaXR5UHJvcGVydHlNZ3IpOwotICAgICAgICAgICAgICAgIGZDaGlsZENvbmZpZy5zZXRQcm9wZXJ0eShCVUZGRVJfU0laRSwgbmV3IEludGVnZXIoZkJ1ZmZlclNpemUpKTsKLQotICAgICAgICAgICAgICAgIC8vIGZlYXR1cmVzIG11c3QgYmUgY29waWVkIHRvIGNoaWxkIGNvbmZpZ3VyYXRpb24KLSAgICAgICAgICAgICAgICBmTmVlZENvcHlGZWF0dXJlcyA9IHRydWU7Ci0KLSAgICAgICAgICAgICAgICAvLyB1c2UgdGhlIHNhbWUgbmFtZXNwYWNlIGNvbnRleHQKLSAgICAgICAgICAgICAgICBmQ2hpbGRDb25maWcuc2V0UHJvcGVydHkoCi0gICAgICAgICAgICAgICAgICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYCi0gICAgICAgICAgICAgICAgICAgICAgICArIENvbnN0YW50cy5OQU1FU1BBQ0VfQ09OVEVYVF9QUk9QRVJUWSwKLSAgICAgICAgICAgICAgICAgICAgZk5hbWVzcGFjZUNvbnRleHQpOwotCi0gICAgICAgICAgICAgICAgZkNoaWxkQ29uZmlnLnNldEZlYXR1cmUoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgWElOQ0xVREVfRklYVVBfQkFTRV9VUklTLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZGaXh1cEJhc2VVUklzKTsKLQotICAgICAgICAgICAgICAgIGZDaGlsZENvbmZpZy5zZXRGZWF0dXJlKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhJTkNMVURFX0ZJWFVQX0xBTkdVQUdFLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZGaXh1cExhbmd1YWdlKTsKLQotCi0gICAgICAgICAgICAgICAgLy8gSWYgdGhlIHhwb2ludGVyIGF0dHJpYnV0ZSBpcyBwcmVzZW50Ci0gICAgICAgICAgICAgICAgaWYgKHhwb2ludGVyICE9IG51bGwgKSB7Ci0KLSAgICAgICAgICAgICAgICAgICAgWFBvaW50ZXJIYW5kbGVyIG5ld0hhbmRsZXIgPQotICAgICAgICAgICAgICAgICAgICAgICAgKFhQb2ludGVySGFuZGxlcilmQ2hpbGRDb25maWcuZ2V0UHJvcGVydHkoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBDb25zdGFudHMuWFBPSU5URVJfSEFORExFUl9QUk9QRVJUWSk7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIGZYUHRyUHJvY2Vzc29yID0gbmV3SGFuZGxlcjsKLQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gPz8/Ci0gICAgICAgICAgICAgICAgICAgICAgICAoKFhQb2ludGVySGFuZGxlcilmWFB0clByb2Nlc3Nvcikuc2V0UHJvcGVydHkoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICArIENvbnN0YW50cy5OQU1FU1BBQ0VfQ09OVEVYVF9QUk9QRVJUWSwKLSAgICAgICAgICAgICAgICAgICAgICAgIGZOYW1lc3BhY2VDb250ZXh0KTsKLQotICAgICAgICAgICAgICAgICAgICAoKFhQb2ludGVySGFuZGxlcilmWFB0clByb2Nlc3Nvcikuc2V0UHJvcGVydHkoWElOQ0xVREVfRklYVVBfQkFTRV9VUklTLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZGaXh1cEJhc2VVUklzKTsKLQotICAgICAgICAgICAgICAgICAgICAoKFhQb2ludGVySGFuZGxlcilmWFB0clByb2Nlc3Nvcikuc2V0UHJvcGVydHkoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgWElOQ0xVREVfRklYVVBfTEFOR1VBR0UsIGZGaXh1cExhbmd1YWdlKTsKLQotICAgICAgICAgICAgICAgICAgICBpZiAoZkVycm9yUmVwb3J0ZXIgIT0gbnVsbCkKLSAgICAgICAgICAgICAgICAgICAgICAgICgoWFBvaW50ZXJIYW5kbGVyKWZYUHRyUHJvY2Vzc29yKS5zZXRQcm9wZXJ0eShFUlJPUl9SRVBPUlRFUiwgZkVycm9yUmVwb3J0ZXIpOwotICAgICAgICAgICAgICAgICAgICAgICAgLy8gPz8/Ci0KLSAgICAgICAgICAgICAgICAgICAgbmV3SGFuZGxlci5zZXRQYXJlbnQodGhpcyk7Ci0gICAgICAgICAgICAgICAgICAgIG5ld0hhbmRsZXIuc2V0RG9jdW1lbnRIYW5kbGVyKHRoaXMuZ2V0RG9jdW1lbnRIYW5kbGVyKCkpOwotICAgICAgICAgICAgICAgICAgICBmWFBvaW50ZXJDaGlsZENvbmZpZyA9IGZDaGlsZENvbmZpZzsKLSAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICBYSW5jbHVkZUhhbmRsZXIgbmV3SGFuZGxlciA9Ci0gICAgICAgICAgICAgICAgICAgICAgICAoWEluY2x1ZGVIYW5kbGVyKWZDaGlsZENvbmZpZy5nZXRQcm9wZXJ0eSgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIENvbnN0YW50cy5YSU5DTFVERV9IQU5ETEVSX1BST1BFUlRZKTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgbmV3SGFuZGxlci5zZXRQYXJlbnQodGhpcyk7Ci0gICAgICAgICAgICAgICAgICAgIG5ld0hhbmRsZXIuc2V0RG9jdW1lbnRIYW5kbGVyKHRoaXMuZ2V0RG9jdW1lbnRIYW5kbGVyKCkpOwotICAgICAgICAgICAgICAgICAgICBmWEluY2x1ZGVDaGlsZENvbmZpZyA9IGZDaGlsZENvbmZpZzsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIElmIGFuIHhwb2ludGVyIGF0dHJpYnV0ZSBpcyBwcmVzZW50Ci0gICAgICAgICAgICBpZiAoeHBvaW50ZXIgIT0gbnVsbCApIHsKLSAgICAgICAgICAgICAgICBmQ2hpbGRDb25maWcgPSBmWFBvaW50ZXJDaGlsZENvbmZpZyA7Ci0KLSAgICAgICAgICAgICAgICAvLyBQYXJzZSB0aGUgWFBvaW50ZXIgZXhwcmVzc2lvbgotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgICgoWFBvaW50ZXJQcm9jZXNzb3IpZlhQdHJQcm9jZXNzb3IpLnBhcnNlWFBvaW50ZXIoeHBvaW50ZXIpOwotCi0gICAgICAgICAgICAgICAgfSBjYXRjaCAoWE5JRXhjZXB0aW9uIGV4KSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIHJlcG9ydCB0aGUgWFBvaW50ZXIgZXJyb3IgYXMgYSByZXNvdXJjZSBlcnJvcgotICAgICAgICAgICAgICAgICAgICByZXBvcnRSZXNvdXJjZUVycm9yKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICJYTUxSZXNvdXJjZUVycm9yIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBocmVmLCBleC5nZXRNZXNzYWdlKCl9KTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIGZDaGlsZENvbmZpZyA9IGZYSW5jbHVkZUNoaWxkQ29uZmlnOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBzZXQgYWxsIGZlYXR1cmVzIG9uIHBhcnNlckNvbmZpZyB0byBtYXRjaCB0aGlzIHBhcnNlciBjb25maWd1cmF0aW9uCi0gICAgICAgICAgICBpZiAoZk5lZWRDb3B5RmVhdHVyZXMpIHsKLSAgICAgICAgICAgICAgICBjb3B5RmVhdHVyZXMoZlNldHRpbmdzLCBmQ2hpbGRDb25maWcpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZk5lZWRDb3B5RmVhdHVyZXMgPSBmYWxzZTsKLQotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICBmTmFtZXNwYWNlQ29udGV4dC5wdXNoU2NvcGUoKTsKLQotICAgICAgICAgICAgICAgIGZDaGlsZENvbmZpZy5wYXJzZShpbmNsdWRlZFNvdXJjZSk7Ci0gICAgICAgICAgICAgICAgLy8gbmVjZXNzYXJ5IHRvIG1ha2Ugc3VyZSBwcm9wZXIgbG9jYXRpb24gaXMgcmVwb3J0ZWQgaW4gZXJyb3JzCi0gICAgICAgICAgICAgICAgaWYgKGZFcnJvclJlcG9ydGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIuc2V0RG9jdW1lbnRMb2NhdG9yKGZEb2NMb2NhdGlvbik7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgLy8gSWYgdGhlIHhwb2ludGVyIGF0dHJpYnV0ZSBpcyBwcmVzZW50Ci0gICAgICAgICAgICAgICAgaWYgKHhwb2ludGVyICE9IG51bGwgKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBhbmQgaXQgd2FzIG5vdCByZXNvbHZlZAotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEoKFhQb2ludGVyUHJvY2Vzc29yKWZYUHRyUHJvY2Vzc29yKS5pc1hQb2ludGVyUmVzb2x2ZWQoKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgTG9jYWxlIGxvY2FsZSA9IChmRXJyb3JSZXBvcnRlciAhPSBudWxsKSA/IGZFcnJvclJlcG9ydGVyLmdldExvY2FsZSgpIDogbnVsbDsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyByZWFzb24gPSBmWEluY2x1ZGVNZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UobG9jYWxlLCAiWFBvaW50ZXJSZXNvbHV0aW9uVW5zdWNjZXNzZnVsIiwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRSZXNvdXJjZUVycm9yKCJYTUxSZXNvdXJjZUVycm9yIiwgbmV3IE9iamVjdFtdIHtocmVmLCByZWFzb259KTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdXNlIHRoZSBmYWxsYmFjawotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2F0Y2ggKFhOSUV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgLy8gbmVjZXNzYXJ5IHRvIG1ha2Ugc3VyZSBwcm9wZXIgbG9jYXRpb24gaXMgcmVwb3J0ZWQgaW4gZXJyb3JzCi0gICAgICAgICAgICAgICAgaWYgKGZFcnJvclJlcG9ydGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIuc2V0RG9jdW1lbnRMb2NhdG9yKGZEb2NMb2NhdGlvbik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIlhNTFBhcnNlRXJyb3IiLCBuZXcgT2JqZWN0W10geyBocmVmLCBlLmdldE1lc3NhZ2UoKSB9KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgLy8gbmVjZXNzYXJ5IHRvIG1ha2Ugc3VyZSBwcm9wZXIgbG9jYXRpb24gaXMgcmVwb3J0ZWQgaW4gZXJyb3JzCi0gICAgICAgICAgICAgICAgaWYgKGZFcnJvclJlcG9ydGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIuc2V0RG9jdW1lbnRMb2NhdG9yKGZEb2NMb2NhdGlvbik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIC8vIEFuIElPRXhjZXB0aW9uIGluZGljYXRlcyB0aGF0IHdlIGhhZCB0cm91YmxlIHJlYWRpbmcgdGhlIGZpbGUsIG5vdAotICAgICAgICAgICAgICAgIC8vIHRoYXQgaXQgd2FzIGFuIGludmFsaWQgWE1MIGZpbGUuICBTbyB3ZSBzZW5kIGEgcmVzb3VyY2UgZXJyb3IsIG5vdCBhCi0gICAgICAgICAgICAgICAgLy8gZmF0YWwgZXJyb3IuCi0gICAgICAgICAgICAgICAgcmVwb3J0UmVzb3VyY2VFcnJvcigKLSAgICAgICAgICAgICAgICAgICAgIlhNTFJlc291cmNlRXJyb3IiLAotICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBocmVmLCBlLmdldE1lc3NhZ2UoKX0pOwotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGZpbmFsbHkgewotICAgICAgICAgICAgICAgIGZOYW1lc3BhY2VDb250ZXh0LnBvcFNjb3BlKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAocGFyc2UuZXF1YWxzKFhJTkNMVURFX1BBUlNFX1RFWFQpKSB7Ci0gICAgICAgICAgICAvLyB3ZSBvbmx5IGNhcmUgYWJvdXQgZW5jb2RpbmcgZm9yIHBhcnNlPSJ0ZXh0IgotICAgICAgICAgICAgU3RyaW5nIGVuY29kaW5nID0gYXR0cmlidXRlcy5nZXRWYWx1ZShYSU5DTFVERV9BVFRSX0VOQ09ESU5HKTsKLSAgICAgICAgICAgIGluY2x1ZGVkU291cmNlLnNldEVuY29kaW5nKGVuY29kaW5nKTsKLSAgICAgICAgICAgIFhJbmNsdWRlVGV4dFJlYWRlciB0ZXh0UmVhZGVyID0gbnVsbDsKLQotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAvLyBTZXR1cCB0aGUgYXBwcm9wcmlhdGUgdGV4dCByZWFkZXIuCi0gICAgICAgICAgICAgICAgaWYgKCFmSXNYTUwxMSkgewotICAgICAgICAgICAgICAgICAgICBpZiAoZlhJbmNsdWRlMTBUZXh0UmVhZGVyID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZYSW5jbHVkZTEwVGV4dFJlYWRlciA9IG5ldyBYSW5jbHVkZVRleHRSZWFkZXIoaW5jbHVkZWRTb3VyY2UsIHRoaXMsIGZCdWZmZXJTaXplKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZYSW5jbHVkZTEwVGV4dFJlYWRlci5zZXRJbnB1dFNvdXJjZShpbmNsdWRlZFNvdXJjZSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgdGV4dFJlYWRlciA9IGZYSW5jbHVkZTEwVGV4dFJlYWRlcjsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChmWEluY2x1ZGUxMVRleHRSZWFkZXIgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgZlhJbmNsdWRlMTFUZXh0UmVhZGVyID0gbmV3IFhJbmNsdWRlMTFUZXh0UmVhZGVyKGluY2x1ZGVkU291cmNlLCB0aGlzLCBmQnVmZmVyU2l6ZSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmWEluY2x1ZGUxMVRleHRSZWFkZXIuc2V0SW5wdXRTb3VyY2UoaW5jbHVkZWRTb3VyY2UpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIHRleHRSZWFkZXIgPSBmWEluY2x1ZGUxMVRleHRSZWFkZXI7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHRleHRSZWFkZXIuc2V0RXJyb3JSZXBvcnRlcihmRXJyb3JSZXBvcnRlcik7Ci0gICAgICAgICAgICAgICAgdGV4dFJlYWRlci5wYXJzZSgpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gZW5jb2RpbmcgZXJyb3JzCi0gICAgICAgICAgICBjYXRjaCAoTWFsZm9ybWVkQnl0ZVNlcXVlbmNlRXhjZXB0aW9uIGV4KSB7Ci0gICAgICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IoZXguZ2V0RG9tYWluKCksIGV4LmdldEtleSgpLAotICAgICAgICAgICAgICAgICAgICBleC5nZXRBcmd1bWVudHMoKSwgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9GQVRBTF9FUlJPUik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXRjaCAoQ2hhckNvbnZlcnNpb25FeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgIkNoYXJDb252ZXJzaW9uRmFpbHVyZSIsIG51bGwsIFhNTEVycm9yUmVwb3J0ZXIuU0VWRVJJVFlfRkFUQUxfRVJST1IpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICByZXBvcnRSZXNvdXJjZUVycm9yKAotICAgICAgICAgICAgICAgICAgICAiVGV4dFJlc291cmNlRXJyb3IiLAotICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBocmVmLCBlLmdldE1lc3NhZ2UoKX0pOwotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGZpbmFsbHkgewotICAgICAgICAgICAgICAgIGlmICh0ZXh0UmVhZGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHRleHRSZWFkZXIuY2xvc2UoKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0UmVzb3VyY2VFcnJvcigKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVGV4dFJlc291cmNlRXJyb3IiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7IGhyZWYsIGUuZ2V0TWVzc2FnZSgpfSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJJbnZhbGlkUGFyc2VWYWx1ZSIsIG5ldyBPYmplY3RbXSB7IHBhcnNlIH0pOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgZWxlbWVudCBoYXMgdGhlIG5hbWVzcGFjZSAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9YSW5jbHVkZSIKLSAgICAgKiBAcGFyYW0gZWxlbWVudCB0aGUgZWxlbWVudCB0byBjaGVjawotICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgZWxlbWVudCBoYXMgdGhlIG5hbWVzcGFjZSAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9YSW5jbHVkZSIKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBoYXNYSW5jbHVkZU5hbWVzcGFjZShRTmFtZSBlbGVtZW50KSB7Ci0gICAgICAgIC8vIFJFVklTSVQ6IFRoZSBuYW1lc3BhY2Ugb2YgdGhpcyBlbGVtZW50IHNob3VsZCBiZSBib3VuZAotICAgICAgICAvLyBhbHJlYWR5LiBXaHkgYXJlIHdlIGxvb2tpbmcgaXQgdXAgZnJvbSB0aGUgbmFtZXNwYWNlCi0gICAgICAgIC8vIGNvbnRleHQ/IC0tIG1yZ2xhdmFzCi0gICAgICAgIHJldHVybiBlbGVtZW50LnVyaSA9PSBYSU5DTFVERV9OU19VUkkKLSAgICAgICAgICAgIHx8IGZOYW1lc3BhY2VDb250ZXh0LmdldFVSSShlbGVtZW50LnByZWZpeCkgPT0gWElOQ0xVREVfTlNfVVJJOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENoZWNrcyBpZiB0aGUgZWxlbWVudCBpcyBhbiAmbHQ7aW5jbHVkZSZndDsgZWxlbWVudC4gIFRoZSBlbGVtZW50IG11c3QgaGF2ZQotICAgICAqIHRoZSBYSW5jbHVkZSBuYW1lc3BhY2UsIGFuZCBhIGxvY2FsIG5hbWUgb2YgImluY2x1ZGUiLgotICAgICAqCi0gICAgICogQHBhcmFtIGVsZW1lbnQgdGhlIGVsZW1lbnQgdG8gY2hlY2sKLSAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGVsZW1lbnQgaXMgYW4gJmx0O2luY2x1ZGUmZ3Q7IGVsZW1lbnQKLSAgICAgKiBAc2VlICNoYXNYSW5jbHVkZU5hbWVzcGFjZShRTmFtZSkKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBpc0luY2x1ZGVFbGVtZW50KFFOYW1lIGVsZW1lbnQpIHsKLSAgICAgICAgcmV0dXJuIGVsZW1lbnQubG9jYWxwYXJ0LmVxdWFscyhYSU5DTFVERV9JTkNMVURFKSAmJgotICAgICAgICAgICAgaGFzWEluY2x1ZGVOYW1lc3BhY2UoZWxlbWVudCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ2hlY2tzIGlmIHRoZSBlbGVtZW50IGlzIGFuICZsdDtmYWxsYmFjayZndDsgZWxlbWVudC4gIFRoZSBlbGVtZW50IG11c3QgaGF2ZQotICAgICAqIHRoZSBYSW5jbHVkZSBuYW1lc3BhY2UsIGFuZCBhIGxvY2FsIG5hbWUgb2YgImZhbGxiYWNrIi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlbGVtZW50IHRoZSBlbGVtZW50IHRvIGNoZWNrCi0gICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBlbGVtZW50IGlzIGFuICZsdDtmYWxsYmFjazsgZWxlbWVudAotICAgICAqIEBzZWUgI2hhc1hJbmNsdWRlTmFtZXNwYWNlKFFOYW1lKQotICAgICAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIGlzRmFsbGJhY2tFbGVtZW50KFFOYW1lIGVsZW1lbnQpIHsKLSAgICAgICAgcmV0dXJuIGVsZW1lbnQubG9jYWxwYXJ0LmVxdWFscyhYSU5DTFVERV9GQUxMQkFDSykgJiYKLSAgICAgICAgICAgIGhhc1hJbmNsdWRlTmFtZXNwYWNlKGVsZW1lbnQpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgY3VycmVudCBbYmFzZSBVUkldIGlzIHRoZSBzYW1lIGFzIHRoZSBbYmFzZSBVUkldIHRoYXQKLSAgICAgKiB3YXMgaW4gZWZmZWN0IG9uIHRoZSBpbmNsdWRlIHBhcmVudC4gIFRoaXMgbWV0aG9kIHNob3VsZCA8ZW0+b25seTwvZW0+IGJlIGNhbGxlZAotICAgICAqIHdoZW4gdGhlIGN1cnJlbnQgZWxlbWVudCBpcyBhIHRvcCBsZXZlbCBpbmNsdWRlZCBlbGVtZW50LCBpLmUuIHRoZSBkaXJlY3QgY2hpbGQKLSAgICAgKiBvZiBhIGZhbGxiYWNrIGVsZW1lbnQsIG9yIHRoZSByb290IGVsZW1lbnRzIGluIGFuIGluY2x1ZGVkIGRvY3VtZW50LgotICAgICAqIFRoZSAiaW5jbHVkZSBwYXJlbnQiIGlzIHRoZSBlbGVtZW50IHdoaWNoLCBpbiB0aGUgcmVzdWx0IGluZm9zZXQsIHdpbGwgYmUgdGhlCi0gICAgICogZGlyZWN0IHBhcmVudCBvZiB0aGUgY3VycmVudCBlbGVtZW50LgotICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgW2Jhc2UgVVJJc10gYXJlIHRoZSBzYW1lIHN0cmluZwotICAgICAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIHNhbWVCYXNlVVJJQXNJbmNsdWRlUGFyZW50KCkgewotICAgICAgICBTdHJpbmcgcGFyZW50QmFzZVVSSSA9IGdldEluY2x1ZGVQYXJlbnRCYXNlVVJJKCk7Ci0gICAgICAgIFN0cmluZyBiYXNlVVJJID0gZkN1cnJlbnRCYXNlVVJJLmdldEV4cGFuZGVkU3lzdGVtSWQoKTsKLSAgICAgICAgLy8gUkVWSVNJVDogc2hvdWxkIHdlIHVzZSBGaWxlI3NhbWVGaWxlKCkgPwotICAgICAgICAvLyAgICAgICAgICBJIHRoaW5rIHRoZSBiZW5lZml0IG9mIHVzaW5nIGl0IGlzIHRoYXQgaXQgcmVzb2x2ZXMgaG9zdCBuYW1lcwotICAgICAgICAvLyAgICAgICAgICBpbnN0ZWFkIG9mIGp1c3QgZG9pbmcgYSBzdHJpbmcgY29tcGFyaXNvbi4KLSAgICAgICAgLy8gVE9ETzogW2Jhc2UgVVJJXSBpcyBzdGlsbCBhbiBvcGVuIGlzc3VlIHdpdGggdGhlIHdvcmtpbmcgZ3JvdXAuCi0gICAgICAgIC8vICAgICAgIFRoZXkncmUgZGVjaWRpbmcgaWYgeG1sOmJhc2Ugc2hvdWxkIGJlIGFkZGVkIGlmIHRoZSBbYmFzZSBVUkldIGlzIGRpZmZlcmVudCBpbiB0ZXJtcwotICAgICAgICAvLyAgICAgICBvZiByZXNvbHZpbmcgcmVsYXRpdmUgcmVmZXJlbmNlcywgb3IgaWYgaXQgc2hvdWxkIGJlIGFkZGVkIGlmIHRoZXkgYXJlIGRpZmZlcmVudCBhdCBhbGwuCi0gICAgICAgIC8vICAgICAgIFJldmlzaXQgdGhpcyBhZnRlciBhIGZpbmFsIGRlY2lzaW9uIGhhcyBiZWVuIG1hZGUuCi0gICAgICAgIC8vICAgICAgIFRoZSBkZWNpc2lvbiBhbHNvIGFmZmVjdHMgd2hldGhlciB3ZSBvdXRwdXQgdGhlIGZpbGUgbmFtZSBvZiB0aGUgVVJJLCBvciBqdXN0IHRoZSBwYXRoLgotICAgICAgICByZXR1cm4gcGFyZW50QmFzZVVSSSAhPSBudWxsICYmIHBhcmVudEJhc2VVUkkuZXF1YWxzKGJhc2VVUkkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgY3VycmVudCBbbGFuZ3VhZ2VdIGlzIGVxdWl2YWxlbnQgdG8gdGhlIFtsYW5ndWFnZV0gdGhhdAotICAgICAqIHdhcyBpbiBlZmZlY3Qgb24gdGhlIGluY2x1ZGUgcGFyZW50LCB0YWtpbmcgY2FzZS1pbnNlbnNpdGl2aXR5IGludG8gYWNjb3VudAotICAgICAqIGFzIHBlciBbUkZDIDMwNjZdLiAgVGhpcyBtZXRob2Qgc2hvdWxkIDxlbT5vbmx5PC9lbT4gYmUgY2FsbGVkIHdoZW4gdGhlCi0gICAgICogY3VycmVudCBlbGVtZW50IGlzIGEgdG9wIGxldmVsIGluY2x1ZGVkIGVsZW1lbnQsIGkuZS4gdGhlIGRpcmVjdCBjaGlsZAotICAgICAqIG9mIGEgZmFsbGJhY2sgZWxlbWVudCwgb3IgdGhlIHJvb3QgZWxlbWVudHMgaW4gYW4gaW5jbHVkZWQgZG9jdW1lbnQuCi0gICAgICogVGhlICJpbmNsdWRlIHBhcmVudCIgaXMgdGhlIGVsZW1lbnQgd2hpY2gsIGluIHRoZSByZXN1bHQgaW5mb3NldCwgd2lsbCBiZSB0aGUKLSAgICAgKiBkaXJlY3QgcGFyZW50IG9mIHRoZSBjdXJyZW50IGVsZW1lbnQuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIFtsYW5ndWFnZV0gcHJvcGVydGllcyBoYXZlIHRoZSBzYW1lIHZhbHVlCi0gICAgICogdGFraW5nIGNhc2UtaW5zZW5zaXRpdml0eSBpbnRvIGFjY291bnQgYXMgcGVyIFtSRkMgMzA2Nl0uCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gc2FtZUxhbmd1YWdlQXNJbmNsdWRlUGFyZW50KCkgewotICAgICAgICBTdHJpbmcgcGFyZW50TGFuZ3VhZ2UgPSBnZXRJbmNsdWRlUGFyZW50TGFuZ3VhZ2UoKTsKLSAgICAgICAgcmV0dXJuIHBhcmVudExhbmd1YWdlICE9IG51bGwgJiYgcGFyZW50TGFuZ3VhZ2UuZXF1YWxzSWdub3JlQ2FzZShmQ3VycmVudExhbmd1YWdlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDaGVja3MgaWYgdGhlIGZpbGUgaW5kaWNhdGVkIGJ5IHRoZSBnaXZlbiBYTUxMb2NhdG9yIGhhcyBhbHJlYWR5IGJlZW4gaW5jbHVkZWQKLSAgICAgKiBpbiB0aGUgY3VycmVudCBzdGFjay4KLSAgICAgKiBAcGFyYW0gaW5jbHVkZWRTb3VyY2UgdGhlIHNvdXJjZSB0byBjaGVjayBmb3IgaW5jbHVzaW9uCi0gICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBzb3VyY2UgaGFzIGFscmVhZHkgYmVlbiBpbmNsdWRlZAotICAgICAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIHNlYXJjaEZvclJlY3Vyc2l2ZUluY2x1ZGVzKFhNTExvY2F0b3IgaW5jbHVkZWRTb3VyY2UpIHsKLSAgICAgICAgU3RyaW5nIGluY2x1ZGVkU3lzdGVtSWQgPSBpbmNsdWRlZFNvdXJjZS5nZXRFeHBhbmRlZFN5c3RlbUlkKCk7Ci0KLSAgICAgICAgaWYgKGluY2x1ZGVkU3lzdGVtSWQgPT0gbnVsbCkgewotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICBpbmNsdWRlZFN5c3RlbUlkID0KLSAgICAgICAgICAgICAgICAgICAgWE1MRW50aXR5TWFuYWdlci5leHBhbmRTeXN0ZW1JZCgKLSAgICAgICAgICAgICAgICAgICAgICAgIGluY2x1ZGVkU291cmNlLmdldExpdGVyYWxTeXN0ZW1JZCgpLAotICAgICAgICAgICAgICAgICAgICAgICAgaW5jbHVkZWRTb3VyY2UuZ2V0QmFzZVN5c3RlbUlkKCksCi0gICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXRjaCAoTWFsZm9ybWVkVVJJRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICByZXBvcnRGYXRhbEVycm9yKCJFeHBhbmRlZFN5c3RlbUlkIik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoaW5jbHVkZWRTeXN0ZW1JZC5lcXVhbHMoZkN1cnJlbnRCYXNlVVJJLmdldEV4cGFuZGVkU3lzdGVtSWQoKSkpIHsKLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKGZQYXJlbnRYSW5jbHVkZUhhbmRsZXIgPT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmUGFyZW50WEluY2x1ZGVIYW5kbGVyLnNlYXJjaEZvclJlY3Vyc2l2ZUluY2x1ZGVzKAotICAgICAgICAgICAgaW5jbHVkZWRTb3VyY2UpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgY3VycmVudCBlbGVtZW50IGlzIGEgdG9wIGxldmVsIGluY2x1ZGVkIGl0ZW0uICBUaGlzIG1lYW5zCi0gICAgICogaXQncyBlaXRoZXIgdGhlIGNoaWxkIG9mIGEgZmFsbGJhY2sgZWxlbWVudCwgb3IgdGhlIHRvcCBsZXZlbCBpdGVtIGluIGFuCi0gICAgICogaW5jbHVkZWQgZG9jdW1lbnQKLSAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGN1cnJlbnQgZWxlbWVudCBpcyBhIHRvcCBsZXZlbCBpbmNsdWRlZCBpdGVtCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gaXNUb3BMZXZlbEluY2x1ZGVkSXRlbSgpIHsKLSAgICAgICAgcmV0dXJuIGlzVG9wTGV2ZWxJbmNsdWRlZEl0ZW1WaWFJbmNsdWRlKCkKLSAgICAgICAgICAgIHx8IGlzVG9wTGV2ZWxJbmNsdWRlZEl0ZW1WaWFGYWxsYmFjaygpOwotICAgIH0KLQotICAgIHByb3RlY3RlZCBib29sZWFuIGlzVG9wTGV2ZWxJbmNsdWRlZEl0ZW1WaWFJbmNsdWRlKCkgewotICAgICAgICByZXR1cm4gZkRlcHRoID09IDEgJiYgIWlzUm9vdERvY3VtZW50KCk7Ci0gICAgfQotCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gaXNUb3BMZXZlbEluY2x1ZGVkSXRlbVZpYUZhbGxiYWNrKCkgewotICAgICAgICAvLyBUZWNobmljYWxseSwgdGhpcyBkb2Vzbid0IGNoZWNrIGlmIHRoZSBwYXJlbnQgd2FzIGEgZmFsbGJhY2ssIGl0IGFsc28KLSAgICAgICAgLy8gd291bGQgcmV0dXJuIHRydWUgaWYgYW55IG9mIHRoZSBwYXJlbnQncyBzaWJsaW5nIGVsZW1lbnRzIHdlcmUgZmFsbGJhY2tzLgotICAgICAgICAvLyBIb3dldmVyLCB0aGlzIGRvZXNuJ3QgbWF0dGVyLCBzaW5jZSB3ZSB3aWxsIGFsd2F5cyBiZSBpZ25vcmluZyBlbGVtZW50cwotICAgICAgICAvLyB3aG9zZSBwYXJlbnQncyBzaWJsaW5ncyB3ZXJlIGZhbGxiYWNrcy4KLSAgICAgICAgcmV0dXJuIGdldFNhd0ZhbGxiYWNrKGZEZXB0aCAtIDEpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFByb2Nlc3NlcyB0aGUgWE1MQXR0cmlidXRlcyBvYmplY3Qgb2Ygc3RhcnRFbGVtZW50KCkgY2FsbHMuICBQZXJmb3JtcyB0aGUgZm9sbG93aW5nIHRhc2tzOgotICAgICAqIDx1bD4KLSAgICAgKiA8bGk+IElmIHRoZSBlbGVtZW50IGlzIGEgdG9wIGxldmVsIGluY2x1ZGVkIGl0ZW0gd2hvc2UgW2Jhc2UgVVJJXSBpcyBkaWZmZXJlbnQgZnJvbSB0aGUKLSAgICAgKiBbYmFzZSBVUkldIG9mIHRoZSBpbmNsdWRlIHBhcmVudCwgdGhlbiBhbiB4bWw6YmFzZSBhdHRyaWJ1dGUgaXMgYWRkZWQgdG8gc3BlY2lmeSB0aGUKLSAgICAgKiB0cnVlIFtiYXNlIFVSSV0KLSAgICAgKiA8bGk+IEZvciBhbGwgbmFtZXNwYWNlIHByZWZpeGVzIHdoaWNoIGFyZSBpbi1zY29wZSBpbiBhbiBpbmNsdWRlZCBpdGVtLCBidXQgbm90IGluIHNjb3BlCi0gICAgICogaW4gdGhlIGluY2x1ZGUgcGFyZW50LCBhIHhtbG5zOnByZWZpeCBhdHRyaWJ1dGUgaXMgYWRkZWQKLSAgICAgKiA8bGk+IEZvciBhbGwgYXR0cmlidXRlcyB3aXRoIGEgdHlwZSBvZiBFTlRJVFksIEVOVElUSUVTIG9yIE5PVEFUSU9OUywgdGhlIG5vdGF0aW9ucyBhbmQKLSAgICAgKiB1bnBhcnNlZCBlbnRpdGllcyBhcmUgcHJvY2Vzc2VkIGFzIGRlc2NyaWJlZCBpbiB0aGUgc3BlYywgc2VjdGlvbnMgNC41LjEgYW5kIDQuNS4yCi0gICAgICogPC91bD4KLSAgICAgKiBAcGFyYW0gYXR0cmlidXRlcwotICAgICAqIEByZXR1cm4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgWE1MQXR0cmlidXRlcyBwcm9jZXNzQXR0cmlidXRlcyhYTUxBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMpIHsKLSAgICAgICAgaWYgKGlzVG9wTGV2ZWxJbmNsdWRlZEl0ZW0oKSkgewotICAgICAgICAgICAgLy8gTW9kaWZ5IGF0dHJpYnV0ZXMgdG8gZml4IHRoZSBiYXNlIFVSSSAoc3BlYyA0LjUuNSkuCi0gICAgICAgICAgICAvLyBXZSBvbmx5IGRvIGl0IHRvIHRvcCBsZXZlbCBpbmNsdWRlZCBlbGVtZW50cywgd2hpY2ggaGF2ZSBhIGRpZmZlcmVudAotICAgICAgICAgICAgLy8gYmFzZSBVUkkgdGhhbiB0aGVpciBpbmNsdWRlIHBhcmVudC4KLSAgICAgICAgICAgIGlmIChmRml4dXBCYXNlVVJJcyAmJiAhc2FtZUJhc2VVUklBc0luY2x1ZGVQYXJlbnQoKSkgewotICAgICAgICAgICAgICAgIGlmIChhdHRyaWJ1dGVzID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlcyA9IG5ldyBYTUxBdHRyaWJ1dGVzSW1wbCgpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8vIFRoaXMgY2F1c2VzIGVycm9ycyB3aXRoIHNjaGVtYSB2YWxpZGF0aW9uLCBpZiB0aGUgc2NoZW1hIGRvZXNuJ3QKLSAgICAgICAgICAgICAgICAvLyBzcGVjaWZ5IHRoYXQgdGhlc2UgZWxlbWVudHMgY2FuIGhhdmUgYW4geG1sOmJhc2UgYXR0cmlidXRlCi0gICAgICAgICAgICAgICAgU3RyaW5nIHVyaSA9IG51bGw7Ci0gICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgdXJpID0gdGhpcy5nZXRSZWxhdGl2ZUJhc2VVUkkoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgY2F0Y2ggKE1hbGZvcm1lZFVSSUV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIHRoaXMgc2hvdWxkbid0IGV2ZXIgaGFwcGVuLCBzaW5jZSBieSBkZWZpbml0aW9uLCB3ZSBoYWQgdG8gdHJhdmVyc2UKLSAgICAgICAgICAgICAgICAgICAgLy8gdGhlIHNhbWUgVVJJcyB0byBldmVuIGdldCB0byB0aGlzIHBsYWNlCi0gICAgICAgICAgICAgICAgICAgIHVyaSA9IGZDdXJyZW50QmFzZVVSSS5nZXRFeHBhbmRlZFN5c3RlbUlkKCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGludCBpbmRleCA9Ci0gICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXMuYWRkQXR0cmlidXRlKAotICAgICAgICAgICAgICAgICAgICAgICAgWE1MX0JBU0VfUU5BTUUsCi0gICAgICAgICAgICAgICAgICAgICAgICBYTUxTeW1ib2xzLmZDREFUQVN5bWJvbCwKLSAgICAgICAgICAgICAgICAgICAgICAgIHVyaSk7Ci0gICAgICAgICAgICAgICAgYXR0cmlidXRlcy5zZXRTcGVjaWZpZWQoaW5kZXgsIHRydWUpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBNb2RpZnkgYXR0cmlidXRlcyB0byBwZXJmb3JtIGxhbmd1YWdlLWZpeHVwIChzcGVjIDQuNS42KS4KLSAgICAgICAgICAgIC8vIFdlIG9ubHkgZG8gaXQgdG8gdG9wIGxldmVsIGluY2x1ZGVkIGVsZW1lbnRzLCB3aGljaCBoYXZlIGEgZGlmZmVyZW50Ci0gICAgICAgICAgICAvLyBbbGFuZ3VhZ2VdIHRoYW4gdGhlaXIgaW5jbHVkZSBwYXJlbnQuCi0gICAgICAgICAgICBpZiAoZkZpeHVwTGFuZ3VhZ2UgJiYgIXNhbWVMYW5ndWFnZUFzSW5jbHVkZVBhcmVudCgpKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGF0dHJpYnV0ZXMgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzID0gbmV3IFhNTEF0dHJpYnV0ZXNJbXBsKCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGludCBpbmRleCA9Ci0gICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXMuYWRkQXR0cmlidXRlKAotICAgICAgICAgICAgICAgICAgICAgICAgWE1MX0xBTkdfUU5BTUUsCi0gICAgICAgICAgICAgICAgICAgICAgICBYTUxTeW1ib2xzLmZDREFUQVN5bWJvbCwKLSAgICAgICAgICAgICAgICAgICAgICAgIGZDdXJyZW50TGFuZ3VhZ2UpOwotICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXMuc2V0U3BlY2lmaWVkKGluZGV4LCB0cnVlKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gTW9kaWZ5IGF0dHJpYnV0ZXMgb2YgaW5jbHVkZWQgaXRlbXMgdG8gZG8gbmFtZXNwYWNlLWZpeHVwLiAoc3BlYyA0LjUuNCkKLSAgICAgICAgICAgIEVudW1lcmF0aW9uIGluc2NvcGVOUyA9IGZOYW1lc3BhY2VDb250ZXh0LmdldEFsbFByZWZpeGVzKCk7Ci0gICAgICAgICAgICB3aGlsZSAoaW5zY29wZU5TLmhhc01vcmVFbGVtZW50cygpKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIHByZWZpeCA9IChTdHJpbmcpaW5zY29wZU5TLm5leHRFbGVtZW50KCk7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIHBhcmVudFVSSSA9Ci0gICAgICAgICAgICAgICAgICAgIGZOYW1lc3BhY2VDb250ZXh0LmdldFVSSUZyb21JbmNsdWRlUGFyZW50KHByZWZpeCk7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIHVyaSA9IGZOYW1lc3BhY2VDb250ZXh0LmdldFVSSShwcmVmaXgpOwotICAgICAgICAgICAgICAgIGlmIChwYXJlbnRVUkkgIT0gdXJpICYmIGF0dHJpYnV0ZXMgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBpZiAocHJlZml4ID09IFhNTFN5bWJvbHMuRU1QVFlfU1RSSU5HKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXR0cmlidXRlcwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRWYWx1ZSgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmFtZXNwYWNlQ29udGV4dC5YTUxOU19VUkksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTFN5bWJvbHMuUFJFRklYX1hNTE5TKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXR0cmlidXRlcyA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXMgPSBuZXcgWE1MQXR0cmlidXRlc0ltcGwoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBRTmFtZSBucyA9IChRTmFtZSlORVdfTlNfQVRUUl9RTkFNRS5jbG9uZSgpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5zLnByZWZpeCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbnMubG9jYWxwYXJ0ID0gWE1MU3ltYm9scy5QUkVGSVhfWE1MTlM7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbnMucmF3bmFtZSA9IFhNTFN5bWJvbHMuUFJFRklYX1hNTE5TOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBpbmRleCA9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXMuYWRkQXR0cmlidXRlKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxTeW1ib2xzLmZDREFUQVN5bWJvbCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVyaSAhPSBudWxsID8gdXJpIDogWE1MU3ltYm9scy5FTVBUWV9TVFJJTkcpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXMuc2V0U3BlY2lmaWVkKGluZGV4LCB0cnVlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBOZWVkIHRvIHJlLWRlY2xhcmUgdGhpcyBwcmVmaXggaW4gdGhlIGN1cnJlbnQgY29udGV4dAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGluIG9yZGVyIGZvciB0aGUgU0FYIHBhcnNlciB0byByZXBvcnQgdGhlIGFwcHJvcHJpYXRlCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc3RhcnQgYW5kIGVuZCBwcmVmaXggbWFwcGluZyBldmVudHMuIC0tIG1yZ2xhdmFzCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZk5hbWVzcGFjZUNvbnRleHQuZGVjbGFyZVByZWZpeChwcmVmaXgsIHVyaSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoCi0gICAgICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzLmdldFZhbHVlKE5hbWVzcGFjZUNvbnRleHQuWE1MTlNfVVJJLCBwcmVmaXgpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGF0dHJpYnV0ZXMgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXMgPSBuZXcgWE1MQXR0cmlidXRlc0ltcGwoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAgICAgUU5hbWUgbnMgPSAoUU5hbWUpTkVXX05TX0FUVFJfUU5BTUUuY2xvbmUoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIG5zLmxvY2FscGFydCA9IHByZWZpeDsKLSAgICAgICAgICAgICAgICAgICAgICAgIG5zLnJhd25hbWUgKz0gcHJlZml4OwotICAgICAgICAgICAgICAgICAgICAgICAgbnMucmF3bmFtZSA9IChmU3ltYm9sVGFibGUgIT0gbnVsbCkgPwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZTeW1ib2xUYWJsZS5hZGRTeW1ib2wobnMucmF3bmFtZSkgOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5zLnJhd25hbWUuaW50ZXJuKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpbnQgaW5kZXggPQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXMuYWRkQXR0cmlidXRlKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBucywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MU3ltYm9scy5mQ0RBVEFTeW1ib2wsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVyaSAhPSBudWxsID8gdXJpIDogWE1MU3ltYm9scy5FTVBUWV9TVFJJTkcpOwotICAgICAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlcy5zZXRTcGVjaWZpZWQoaW5kZXgsIHRydWUpOwotICAgICAgICAgICAgICAgICAgICAgICAgLy8gTmVlZCB0byByZS1kZWNsYXJlIHRoaXMgcHJlZml4IGluIHRoZSBjdXJyZW50IGNvbnRleHQKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGluIG9yZGVyIGZvciB0aGUgU0FYIHBhcnNlciB0byByZXBvcnQgdGhlIGFwcHJvcHJpYXRlCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBzdGFydCBhbmQgZW5kIHByZWZpeCBtYXBwaW5nIGV2ZW50cy4gLS0gbXJnbGF2YXMKLSAgICAgICAgICAgICAgICAgICAgICAgIGZOYW1lc3BhY2VDb250ZXh0LmRlY2xhcmVQcmVmaXgocHJlZml4LCB1cmkpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKGF0dHJpYnV0ZXMgIT0gbnVsbCkgewotICAgICAgICAgICAgaW50IGxlbmd0aCA9IGF0dHJpYnV0ZXMuZ2V0TGVuZ3RoKCk7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIHR5cGUgPSBhdHRyaWJ1dGVzLmdldFR5cGUoaSk7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIHZhbHVlID0gYXR0cmlidXRlcy5nZXRWYWx1ZShpKTsKLSAgICAgICAgICAgICAgICBpZiAodHlwZSA9PSBYTUxTeW1ib2xzLmZFTlRJVFlTeW1ib2wpIHsKLSAgICAgICAgICAgICAgICAgICAgdGhpcy5jaGVja1VucGFyc2VkRW50aXR5KHZhbHVlKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaWYgKHR5cGUgPT0gWE1MU3ltYm9scy5mRU5USVRJRVNTeW1ib2wpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gNC41LjEgLSBVbnBhcnNlZCBFbnRpdGllcwotICAgICAgICAgICAgICAgICAgICBTdHJpbmdUb2tlbml6ZXIgc3QgPSBuZXcgU3RyaW5nVG9rZW5pemVyKHZhbHVlKTsKLSAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHN0Lmhhc01vcmVUb2tlbnMoKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGVudE5hbWUgPSBzdC5uZXh0VG9rZW4oKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY2hlY2tVbnBhcnNlZEVudGl0eShlbnROYW1lKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIGlmICh0eXBlID09IFhNTFN5bWJvbHMuZk5PVEFUSU9OU3ltYm9sKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIDQuNS4yIC0gTm90YXRpb25zCi0gICAgICAgICAgICAgICAgICAgIHRoaXMuY2hlY2tOb3RhdGlvbih2YWx1ZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIC8qIFdlIGFjdHVhbGx5IGRvbid0IG5lZWQgdG8gZG8gYW55dGhpbmcgZm9yIDQuNS4zLCBiZWNhdXNlIGF0IHRoaXMgc3RhZ2UgdGhlCi0gICAgICAgICAgICAgICAgICogdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZSBpcyBqdXN0IGEgc3RyaW5nLiBJdCB3aWxsIGJlIHRha2VuIGNhcmUgb2YgbGF0ZXIKLSAgICAgICAgICAgICAgICAgKiBpbiB0aGUgcGlwZWxpbmUsIHdoZW4gdGhlIElEUkVGcyBhcmUgYWN0dWFsbHkgcmVzb2x2ZWQgYWdhaW5zdCBJRHMuCi0gICAgICAgICAgICAgICAgICoKLSAgICAgICAgICAgICAgICAgKiBpZiAodHlwZSA9PSBYTUxTeW1ib2xzLmZJRFJFRlN5bWJvbCB8fCB0eXBlID09IFhNTFN5bWJvbHMuZklEUkVGU1N5bWJvbCkgeyB9Ci0gICAgICAgICAgICAgICAgICovCi0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gYXR0cmlidXRlczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGEgVVJJLCByZWxhdGl2ZSB0byB0aGUgaW5jbHVkZSBwYXJlbnQncyBiYXNlIFVSSSwgb2YgdGhlIGN1cnJlbnQKLSAgICAgKiBbYmFzZSBVUkldLiAgRm9yIGluc3RhbmNlLCBpZiB0aGUgY3VycmVudCBbYmFzZSBVUkldIHdhcyAiZGlyMS9kaXIyL2ZpbGUueG1sIgotICAgICAqIGFuZCB0aGUgaW5jbHVkZSBwYXJlbnQncyBbYmFzZSBVUkldIHdhcyAiZGlyLyIsIHRoaXMgd291bGQgcmV0dXJuICJkaXIyL2ZpbGUueG1sIi4KLSAgICAgKiBAcmV0dXJuIHRoZSByZWxhdGl2ZSBVUkkKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgU3RyaW5nIGdldFJlbGF0aXZlQmFzZVVSSSgpIHRocm93cyBNYWxmb3JtZWRVUklFeGNlcHRpb24gewotICAgICAgICBpbnQgaW5jbHVkZVBhcmVudERlcHRoID0gZ2V0SW5jbHVkZVBhcmVudERlcHRoKCk7Ci0gICAgICAgIFN0cmluZyByZWxhdGl2ZVVSSSA9IHRoaXMuZ2V0UmVsYXRpdmVVUkkoaW5jbHVkZVBhcmVudERlcHRoKTsKLSAgICAgICAgaWYgKGlzUm9vdERvY3VtZW50KCkpIHsKLSAgICAgICAgICAgIHJldHVybiByZWxhdGl2ZVVSSTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIGlmIChyZWxhdGl2ZVVSSS5lcXVhbHMoIiIpKSB7Ci0gICAgICAgICAgICAgICAgcmVsYXRpdmVVUkkgPSBmQ3VycmVudEJhc2VVUkkuZ2V0TGl0ZXJhbFN5c3RlbUlkKCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmIChpbmNsdWRlUGFyZW50RGVwdGggPT0gMCkgewotICAgICAgICAgICAgICAgIGlmIChmUGFyZW50UmVsYXRpdmVVUkkgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBmUGFyZW50UmVsYXRpdmVVUkkgPQotICAgICAgICAgICAgICAgICAgICAgICAgZlBhcmVudFhJbmNsdWRlSGFuZGxlci5nZXRSZWxhdGl2ZUJhc2VVUkkoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaWYgKGZQYXJlbnRSZWxhdGl2ZVVSSS5lcXVhbHMoIiIpKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiByZWxhdGl2ZVVSSTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBVUkkgYmFzZSA9IG5ldyBVUkkoZlBhcmVudFJlbGF0aXZlVVJJLCB0cnVlKTsKLSAgICAgICAgICAgICAgICBVUkkgdXJpID0gbmV3IFVSSShiYXNlLCByZWxhdGl2ZVVSSSk7Ci0KLSAgICAgICAgICAgICAgICAvKiogQ2hlY2sgd2hldGhlciB0aGUgc2NoZW1lIGNvbXBvbmVudHMgYXJlIGVxdWFsLiAqLwotICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBiYXNlU2NoZW1lID0gYmFzZS5nZXRTY2hlbWUoKTsKLSAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgbGl0ZXJhbFNjaGVtZSA9IHVyaS5nZXRTY2hlbWUoKTsKLSAgICAgICAgICAgICAgICBpZiAoIU9iamVjdHMuZXF1YWxzKGJhc2VTY2hlbWUsIGxpdGVyYWxTY2hlbWUpKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiByZWxhdGl2ZVVSSTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvKiogQ2hlY2sgd2hldGhlciB0aGUgYXV0aG9yaXR5IGNvbXBvbmVudHMgYXJlIGVxdWFsLiAqLwotICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBiYXNlQXV0aG9yaXR5ID0gYmFzZS5nZXRBdXRob3JpdHkoKTsKLSAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgbGl0ZXJhbEF1dGhvcml0eSA9IHVyaS5nZXRBdXRob3JpdHkoKTsKLSAgICAgICAgICAgICAgICBpZiAoIU9iamVjdHMuZXF1YWxzKGJhc2VBdXRob3JpdHksIGxpdGVyYWxBdXRob3JpdHkpKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiB1cmkuZ2V0U2NoZW1lU3BlY2lmaWNQYXJ0KCk7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgLyoqCi0gICAgICAgICAgICAgICAgICogVGhlIHNjaGVtZSBhbmQgYXV0aG9yaXR5IGNvbXBvbmVudHMgYXJlIGVxdWFsLAotICAgICAgICAgICAgICAgICAqIHJldHVybiB0aGUgcGF0aCBhbmQgdGhlIHBvc3NpYmxlIHF1ZXJ5IGFuZC9vcgotICAgICAgICAgICAgICAgICAqIGZyYWdtZW50IHdoaWNoIGZvbGxvdy4KLSAgICAgICAgICAgICAgICAgKi8KLSAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgbGl0ZXJhbFBhdGggPSB1cmkuZ2V0UGF0aCgpOwotICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBsaXRlcmFsUXVlcnkgPSB1cmkuZ2V0UXVlcnlTdHJpbmcoKTsKLSAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgbGl0ZXJhbEZyYWdtZW50ID0gdXJpLmdldEZyYWdtZW50KCk7Ci0gICAgICAgICAgICAgICAgaWYgKGxpdGVyYWxRdWVyeSAhPSBudWxsIHx8IGxpdGVyYWxGcmFnbWVudCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZ0J1aWxkZXIgYnVmZmVyID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGxpdGVyYWxQYXRoICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQobGl0ZXJhbFBhdGgpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGlmIChsaXRlcmFsUXVlcnkgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgnPycpOwotICAgICAgICAgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZChsaXRlcmFsUXVlcnkpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGlmIChsaXRlcmFsRnJhZ21lbnQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgnIycpOwotICAgICAgICAgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZChsaXRlcmFsRnJhZ21lbnQpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBidWZmZXIudG9TdHJpbmcoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGxpdGVyYWxQYXRoOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHJlbGF0aXZlVVJJOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgW2Jhc2UgVVJJXSBvZiB0aGUgaW5jbHVkZSBwYXJlbnQuCi0gICAgICogQHJldHVybiB0aGUgYmFzZSBVUkkgb2YgdGhlIGluY2x1ZGUgcGFyZW50LgotICAgICAqLwotICAgIHByaXZhdGUgU3RyaW5nIGdldEluY2x1ZGVQYXJlbnRCYXNlVVJJKCkgewotICAgICAgICBpbnQgZGVwdGggPSBnZXRJbmNsdWRlUGFyZW50RGVwdGgoKTsKLSAgICAgICAgaWYgKCFpc1Jvb3REb2N1bWVudCgpICYmIGRlcHRoID09IDApIHsKLSAgICAgICAgICAgIHJldHVybiBmUGFyZW50WEluY2x1ZGVIYW5kbGVyLmdldEluY2x1ZGVQYXJlbnRCYXNlVVJJKCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRCYXNlVVJJKGRlcHRoKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIFtsYW5ndWFnZV0gb2YgdGhlIGluY2x1ZGUgcGFyZW50LgotICAgICAqCi0gICAgICogQHJldHVybiB0aGUgbGFuZ3VhZ2UgcHJvcGVydHkgb2YgdGhlIGluY2x1ZGUgcGFyZW50LgotICAgICAqLwotICAgIHByaXZhdGUgU3RyaW5nIGdldEluY2x1ZGVQYXJlbnRMYW5ndWFnZSgpIHsKLSAgICAgICAgaW50IGRlcHRoID0gZ2V0SW5jbHVkZVBhcmVudERlcHRoKCk7Ci0gICAgICAgIGlmICghaXNSb290RG9jdW1lbnQoKSAmJiBkZXB0aCA9PSAwKSB7Ci0gICAgICAgICAgICByZXR1cm4gZlBhcmVudFhJbmNsdWRlSGFuZGxlci5nZXRJbmNsdWRlUGFyZW50TGFuZ3VhZ2UoKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiBnZXRMYW5ndWFnZShkZXB0aCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBkZXB0aCBvZiB0aGUgaW5jbHVkZSBwYXJlbnQuICBIZXJlLCB0aGUgaW5jbHVkZSBwYXJlbnQgaXMKLSAgICAgKiBjYWxjdWxhdGVkIGFzIHRoZSBsYXN0IG5vbi1pbmNsdWRlIG9yIG5vbi1mYWxsYmFjayBlbGVtZW50LiBJdCBpcyBhc3N1bWVkCi0gICAgICogdGhpcyBtZXRob2QgaXMgY2FsbGVkIHdoZW4gdGhlIGN1cnJlbnQgZWxlbWVudCBpcyBhIHRvcCBsZXZlbCBpbmNsdWRlZCBpdGVtLgotICAgICAqIFJldHVybmluZyAwIGluZGljYXRlcyB0aGF0IHRoZSB0b3AgbGV2ZWwgZWxlbWVudCBpbiB0aGlzIGRvY3VtZW50Ci0gICAgICogd2FzIGFuIGluY2x1ZGUgZWxlbWVudC4KLSAgICAgKiBAcmV0dXJuIHRoZSBkZXB0aCBvZiB0aGUgdG9wIGxldmVsIGluY2x1ZGUgZWxlbWVudAotICAgICAqLwotICAgIHByaXZhdGUgaW50IGdldEluY2x1ZGVQYXJlbnREZXB0aCgpIHsKLSAgICAgICAgLy8gV2UgZG9uJ3Qgc3RhcnQgYXQgZkRlcHRoLCBzaW5jZSBpdCBpcyBlaXRoZXIgdGhlIHRvcCBsZXZlbCBpbmNsdWRlZCBpdGVtLAotICAgICAgICAvLyBvciBhbiBpbmNsdWRlIGVsZW1lbnQsIHdoZW4gdGhpcyBtZXRob2QgaXMgY2FsbGVkLgotICAgICAgICBmb3IgKGludCBpID0gZkRlcHRoIC0gMTsgaSA+PSAwOyBpLS0pIHsKLSAgICAgICAgICAgIC8vIFRoaXMgdGVjaG5pY2FsbHkgbWlnaHQgbm90IGFsd2F5cyByZXR1cm4gdGhlIGZpcnN0IG5vbi1pbmNsdWRlL2ZhbGxiYWNrCi0gICAgICAgICAgICAvLyBlbGVtZW50IHRoYXQgaXQgY29tZXMgdG8sIHNpbmNlIHNhd0ZhbGxiYWNrKCkgcmV0dXJucyB0cnVlIGlmIGEgZmFsbGJhY2sKLSAgICAgICAgICAgIC8vIHdhcyBldmVyIGVuY291bnRlcmVkIGF0IHRoYXQgZGVwdGguICBIb3dldmVyLCBpZiBhIGZhbGxiYWNrIHdhcyBlbmNvdW50ZXJlZAotICAgICAgICAgICAgLy8gYXQgdGhhdCBkZXB0aCwgYW5kIGl0IHdhc24ndCB0aGUgZGlyZWN0IGRlc2NlbmRhbnQgb2YgdGhlIGN1cnJlbnQgZWxlbWVudAotICAgICAgICAgICAgLy8gdGhlbiB3ZSBjYW4ndCBiZSBpbiBhIHNpdHVhdGlvbiB3aGVyZSB3ZSdyZSBjYWxsaW5nIHRoaXMgbWV0aG9kIChiZWNhdXNlCi0gICAgICAgICAgICAvLyB3ZSdsbCBhbHdheXMgYmUgaW4gU1RBVEVfSUdOT1JFKQotICAgICAgICAgICAgaWYgKCFnZXRTYXdJbmNsdWRlKGkpICYmICFnZXRTYXdGYWxsYmFjayhpKSkgewotICAgICAgICAgICAgICAgIHJldHVybiBpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIC8vIHNob3VsZG4ndCBnZXQgaGVyZSwgc2luY2UgZGVwdGggMCBzaG91bGQgbmV2ZXIgaGF2ZSBhbiBpbmNsdWRlIGVsZW1lbnQgb3IKLSAgICAgICAgLy8gYSBmYWxsYmFjayBlbGVtZW50Ci0gICAgICAgIHJldHVybiAwOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIGN1cnJlbnQgZWxlbWVudCBkZXB0aCBvZiB0aGUgcmVzdWx0IGluZm9zZXQuCi0gICAgICovCi0gICAgcHJpdmF0ZSBpbnQgZ2V0UmVzdWx0RGVwdGgoKSB7Ci0gICAgICAgIHJldHVybiBmUmVzdWx0RGVwdGg7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogTW9kaWZ5IHRoZSBhdWdtZW50YXRpb25zLiAgQWRkIGFuIFtpbmNsdWRlZF0gaW5mb3NldCBpdGVtLCBpZiB0aGUgY3VycmVudAotICAgICAqIGVsZW1lbnQgaXMgYSB0b3AgbGV2ZWwgaW5jbHVkZWQgaXRlbS4KLSAgICAgKiBAcGFyYW0gYXVncyB0aGUgQXVnbWVudGF0aW9ucyB0byBtb2RpZnkuCi0gICAgICogQHJldHVybiB0aGUgbW9kaWZpZWQgQXVnbWVudGF0aW9ucwotICAgICAqLwotICAgIHByb3RlY3RlZCBBdWdtZW50YXRpb25zIG1vZGlmeUF1Z21lbnRhdGlvbnMoQXVnbWVudGF0aW9ucyBhdWdzKSB7Ci0gICAgICAgIHJldHVybiBtb2RpZnlBdWdtZW50YXRpb25zKGF1Z3MsIGZhbHNlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBNb2RpZnkgdGhlIGF1Z21lbnRhdGlvbnMuICBBZGQgYW4gW2luY2x1ZGVkXSBpbmZvc2V0IGl0ZW0sIGlmIDxjb2RlPmZvcmNlPC9jb2RlPgotICAgICAqIGlzIHRydWUsIG9yIGlmIHRoZSBjdXJyZW50IGVsZW1lbnQgaXMgYSB0b3AgbGV2ZWwgaW5jbHVkZWQgaXRlbS4KLSAgICAgKiBAcGFyYW0gYXVncyB0aGUgQXVnbWVudGF0aW9ucyB0byBtb2RpZnkuCi0gICAgICogQHBhcmFtIGZvcmNlIHdoZXRoZXIgdG8gZm9yY2UgbW9kaWZpY2F0aW9uCi0gICAgICogQHJldHVybiB0aGUgbW9kaWZpZWQgQXVnbWVudGF0aW9ucwotICAgICAqLwotICAgIHByb3RlY3RlZCBBdWdtZW50YXRpb25zIG1vZGlmeUF1Z21lbnRhdGlvbnMoCi0gICAgICAgIEF1Z21lbnRhdGlvbnMgYXVncywKLSAgICAgICAgYm9vbGVhbiBmb3JjZSkgewotICAgICAgICBpZiAoZm9yY2UgfHwgaXNUb3BMZXZlbEluY2x1ZGVkSXRlbSgpKSB7Ci0gICAgICAgICAgICBpZiAoYXVncyA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgYXVncyA9IG5ldyBBdWdtZW50YXRpb25zSW1wbCgpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgYXVncy5wdXRJdGVtKFhJTkNMVURFX0lOQ0xVREVELCBCb29sZWFuLlRSVUUpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBhdWdzOwotICAgIH0KLQotICAgIHByb3RlY3RlZCBpbnQgZ2V0U3RhdGUoaW50IGRlcHRoKSB7Ci0gICAgICAgIHJldHVybiBmU3RhdGVbZGVwdGhdOwotICAgIH0KLQotICAgIHByb3RlY3RlZCBpbnQgZ2V0U3RhdGUoKSB7Ci0gICAgICAgIHJldHVybiBmU3RhdGVbZkRlcHRoXTsKLSAgICB9Ci0KLSAgICBwcm90ZWN0ZWQgdm9pZCBzZXRTdGF0ZShpbnQgc3RhdGUpIHsKLSAgICAgICAgaWYgKGZEZXB0aCA+PSBmU3RhdGUubGVuZ3RoKSB7Ci0gICAgICAgICAgICBpbnRbXSBuZXdhcnJheSA9IG5ldyBpbnRbZkRlcHRoICogMl07Ci0gICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGZTdGF0ZSwgMCwgbmV3YXJyYXksIDAsIGZTdGF0ZS5sZW5ndGgpOwotICAgICAgICAgICAgZlN0YXRlID0gbmV3YXJyYXk7Ci0gICAgICAgIH0KLSAgICAgICAgZlN0YXRlW2ZEZXB0aF0gPSBzdGF0ZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZWNvcmRzIHRoYXQgYW4gJmx0O2ZhbGxiYWNrJmd0OyB3YXMgZW5jb3VudGVyZWQgYXQgdGhlIHNwZWNpZmllZCBkZXB0aCwKLSAgICAgKiBhcyBhbiBhbmNlc3RvciBvZiB0aGUgY3VycmVudCBlbGVtZW50LCBvciBhcyBhIHNpYmxpbmcgb2YgYW4gYW5jZXN0b3Igb2YgdGhlCi0gICAgICogY3VycmVudCBlbGVtZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIGRlcHRoCi0gICAgICogQHBhcmFtIHZhbAotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIHNldFNhd0ZhbGxiYWNrKGludCBkZXB0aCwgYm9vbGVhbiB2YWwpIHsKLSAgICAgICAgaWYgKGRlcHRoID49IGZTYXdGYWxsYmFjay5sZW5ndGgpIHsKLSAgICAgICAgICAgIGJvb2xlYW5bXSBuZXdhcnJheSA9IG5ldyBib29sZWFuW2RlcHRoICogMl07Ci0gICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGZTYXdGYWxsYmFjaywgMCwgbmV3YXJyYXksIDAsIGZTYXdGYWxsYmFjay5sZW5ndGgpOwotICAgICAgICAgICAgZlNhd0ZhbGxiYWNrID0gbmV3YXJyYXk7Ci0gICAgICAgIH0KLSAgICAgICAgZlNhd0ZhbGxiYWNrW2RlcHRoXSA9IHZhbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHdoZXRoZXIgYW4gJmx0O2ZhbGxiYWNrJmd0OyB3YXMgZW5jb3VudGVyZWQgYXQgdGhlIHNwZWNpZmllZCBkZXB0aCwKLSAgICAgKiBhcyBhbiBhbmNlc3RvciBvZiB0aGUgY3VycmVudCBlbGVtZW50LCBvciBhcyBhIHNpYmxpbmcgb2YgYW4gYW5jZXN0b3Igb2YgdGhlCi0gICAgICogY3VycmVudCBlbGVtZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIGRlcHRoCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZ2V0U2F3RmFsbGJhY2soaW50IGRlcHRoKSB7Ci0gICAgICAgIGlmIChkZXB0aCA+PSBmU2F3RmFsbGJhY2subGVuZ3RoKSB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGZTYXdGYWxsYmFja1tkZXB0aF07Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmVjb3JkcyB0aGF0IGFuICZsdDtpbmNsdWRlJmd0OyB3YXMgZW5jb3VudGVyZWQgYXQgdGhlIHNwZWNpZmllZCBkZXB0aCwKLSAgICAgKiBhcyBhbiBhbmNlc3RvciBvZiB0aGUgY3VycmVudCBpdGVtLgotICAgICAqCi0gICAgICogQHBhcmFtIGRlcHRoCi0gICAgICogQHBhcmFtIHZhbAotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIHNldFNhd0luY2x1ZGUoaW50IGRlcHRoLCBib29sZWFuIHZhbCkgewotICAgICAgICBpZiAoZGVwdGggPj0gZlNhd0luY2x1ZGUubGVuZ3RoKSB7Ci0gICAgICAgICAgICBib29sZWFuW10gbmV3YXJyYXkgPSBuZXcgYm9vbGVhbltkZXB0aCAqIDJdOwotICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShmU2F3SW5jbHVkZSwgMCwgbmV3YXJyYXksIDAsIGZTYXdJbmNsdWRlLmxlbmd0aCk7Ci0gICAgICAgICAgICBmU2F3SW5jbHVkZSA9IG5ld2FycmF5OwotICAgICAgICB9Ci0gICAgICAgIGZTYXdJbmNsdWRlW2RlcHRoXSA9IHZhbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gd2hldGhlciBhbiAmbHQ7aW5jbHVkZSZndDsgd2FzIGVuY291bnRlcmVkIGF0IHRoZSBzcGVjaWZpZWQgZGVwdGgsCi0gICAgICogYXMgYW4gYW5jZXN0b3Igb2YgdGhlIGN1cnJlbnQgaXRlbS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBkZXB0aAotICAgICAqIEByZXR1cm4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBnZXRTYXdJbmNsdWRlKGludCBkZXB0aCkgewotICAgICAgICBpZiAoZGVwdGggPj0gZlNhd0luY2x1ZGUubGVuZ3RoKSB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGZTYXdJbmNsdWRlW2RlcHRoXTsKLSAgICB9Ci0KLSAgICBwcm90ZWN0ZWQgdm9pZCByZXBvcnRSZXNvdXJjZUVycm9yKFN0cmluZyBrZXkpIHsKLSAgICAgICAgdGhpcy5yZXBvcnRGYXRhbEVycm9yKGtleSwgbnVsbCk7Ci0gICAgfQotCi0gICAgcHJvdGVjdGVkIHZvaWQgcmVwb3J0UmVzb3VyY2VFcnJvcihTdHJpbmcga2V5LCBPYmplY3RbXSBhcmdzKSB7Ci0gICAgICAgIHRoaXMucmVwb3J0RXJyb3Ioa2V5LCBhcmdzLCBYTUxFcnJvclJlcG9ydGVyLlNFVkVSSVRZX1dBUk5JTkcpOwotICAgIH0KLQotICAgIHByb3RlY3RlZCB2b2lkIHJlcG9ydEZhdGFsRXJyb3IoU3RyaW5nIGtleSkgewotICAgICAgICB0aGlzLnJlcG9ydEZhdGFsRXJyb3Ioa2V5LCBudWxsKTsKLSAgICB9Ci0KLSAgICBwcm90ZWN0ZWQgdm9pZCByZXBvcnRGYXRhbEVycm9yKFN0cmluZyBrZXksIE9iamVjdFtdIGFyZ3MpIHsKLSAgICAgICAgdGhpcy5yZXBvcnRFcnJvcihrZXksIGFyZ3MsIFhNTEVycm9yUmVwb3J0ZXIuU0VWRVJJVFlfRkFUQUxfRVJST1IpOwotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCByZXBvcnRFcnJvcihTdHJpbmcga2V5LCBPYmplY3RbXSBhcmdzLCBzaG9ydCBzZXZlcml0eSkgewotICAgICAgICBpZiAoZkVycm9yUmVwb3J0ZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IoCi0gICAgICAgICAgICAgICAgWEluY2x1ZGVNZXNzYWdlRm9ybWF0dGVyLlhJTkNMVURFX0RPTUFJTiwKLSAgICAgICAgICAgICAgICBrZXksCi0gICAgICAgICAgICAgICAgYXJncywKLSAgICAgICAgICAgICAgICBzZXZlcml0eSk7Ci0gICAgICAgIH0KLSAgICAgICAgLy8gd2Ugd29uJ3Qgd29ycnkgYWJvdXQgd2hlbiBlcnJvciByZXBvcnRlciBpcyBudWxsLCBzaW5jZSB0aGVyZSBzaG91bGQgYWx3YXlzIGJlCi0gICAgICAgIC8vIGF0IGxlYXN0IHRoZSBkZWZhdWx0IGVycm9yIHJlcG9ydGVyCi0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSBwYXJlbnQgb2YgdGhpcyBYSW5jbHVkZUhhbmRsZXIgaW4gdGhlIHRyZWUKLSAgICAgKiBAcGFyYW0gcGFyZW50Ci0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgc2V0UGFyZW50KFhJbmNsdWRlSGFuZGxlciBwYXJlbnQpIHsKLSAgICAgICAgZlBhcmVudFhJbmNsdWRlSGFuZGxlciA9IHBhcmVudDsKLSAgICB9Ci0KLSAgICAvLyB1c2VkIHRvIGtub3cgd2hldGhlciB0byBwYXNzIGRlY2xhcmF0aW9ucyB0byB0aGUgZG9jdW1lbnQgaGFuZGxlcgotICAgIHByb3RlY3RlZCBib29sZWFuIGlzUm9vdERvY3VtZW50KCkgewotICAgICAgICByZXR1cm4gZlBhcmVudFhJbmNsdWRlSGFuZGxlciA9PSBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENhY2hlcyBhbiB1bnBhcnNlZCBlbnRpdHkuCi0gICAgICogQHBhcmFtIG5hbWUgdGhlIG5hbWUgb2YgdGhlIHVucGFyc2VkIGVudGl0eQotICAgICAqIEBwYXJhbSBpZGVudGlmaWVyIHRoZSBsb2NhdGlvbiBvZiB0aGUgdW5wYXJzZWQgZW50aXR5Ci0gICAgICogQHBhcmFtIGF1Z21lbnRhdGlvbnMgYW55IEF1Z21lbnRhdGlvbnMgdGhhdCB3ZXJlIG9uIHRoZSBvcmlnaW5hbCB1bnBhcnNlZCBlbnRpdHkgZGVjbGFyYXRpb24KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCBhZGRVbnBhcnNlZEVudGl0eSgKLSAgICAgICAgU3RyaW5nIG5hbWUsCi0gICAgICAgIFhNTFJlc291cmNlSWRlbnRpZmllciBpZGVudGlmaWVyLAotICAgICAgICBTdHJpbmcgbm90YXRpb24sCi0gICAgICAgIEF1Z21lbnRhdGlvbnMgYXVnbWVudGF0aW9ucykgewotICAgICAgICBVbnBhcnNlZEVudGl0eSBlbnQgPSBuZXcgVW5wYXJzZWRFbnRpdHkoKTsKLSAgICAgICAgZW50Lm5hbWUgPSBuYW1lOwotICAgICAgICBlbnQuc3lzdGVtSWQgPSBpZGVudGlmaWVyLmdldExpdGVyYWxTeXN0ZW1JZCgpOwotICAgICAgICBlbnQucHVibGljSWQgPSBpZGVudGlmaWVyLmdldFB1YmxpY0lkKCk7Ci0gICAgICAgIGVudC5iYXNlVVJJID0gaWRlbnRpZmllci5nZXRCYXNlU3lzdGVtSWQoKTsKLSAgICAgICAgZW50LmV4cGFuZGVkU3lzdGVtSWQgPSBpZGVudGlmaWVyLmdldEV4cGFuZGVkU3lzdGVtSWQoKTsKLSAgICAgICAgZW50Lm5vdGF0aW9uID0gbm90YXRpb247Ci0gICAgICAgIGVudC5hdWdtZW50YXRpb25zID0gYXVnbWVudGF0aW9uczsKLSAgICAgICAgZlVucGFyc2VkRW50aXRpZXMuYWRkKGVudCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ2FjaGVzIGEgbm90YXRpb24uCi0gICAgICogQHBhcmFtIG5hbWUgdGhlIG5hbWUgb2YgdGhlIG5vdGF0aW9uCi0gICAgICogQHBhcmFtIGlkZW50aWZpZXIgdGhlIGxvY2F0aW9uIG9mIHRoZSBub3RhdGlvbgotICAgICAqIEBwYXJhbSBhdWdtZW50YXRpb25zIGFueSBBdWdtZW50YXRpb25zIHRoYXQgd2VyZSBvbiB0aGUgb3JpZ2luYWwgbm90YXRpb24gZGVjbGFyYXRpb24KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCBhZGROb3RhdGlvbigKLSAgICAgICAgU3RyaW5nIG5hbWUsCi0gICAgICAgIFhNTFJlc291cmNlSWRlbnRpZmllciBpZGVudGlmaWVyLAotICAgICAgICBBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpIHsKLSAgICAgICAgTm90YXRpb24gbm90ID0gbmV3IE5vdGF0aW9uKCk7Ci0gICAgICAgIG5vdC5uYW1lID0gbmFtZTsKLSAgICAgICAgbm90LnN5c3RlbUlkID0gaWRlbnRpZmllci5nZXRMaXRlcmFsU3lzdGVtSWQoKTsKLSAgICAgICAgbm90LnB1YmxpY0lkID0gaWRlbnRpZmllci5nZXRQdWJsaWNJZCgpOwotICAgICAgICBub3QuYmFzZVVSSSA9IGlkZW50aWZpZXIuZ2V0QmFzZVN5c3RlbUlkKCk7Ci0gICAgICAgIG5vdC5leHBhbmRlZFN5c3RlbUlkID0gaWRlbnRpZmllci5nZXRFeHBhbmRlZFN5c3RlbUlkKCk7Ci0gICAgICAgIG5vdC5hdWdtZW50YXRpb25zID0gYXVnbWVudGF0aW9uczsKLSAgICAgICAgZk5vdGF0aW9ucy5hZGQobm90KTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDaGVja3MgaWYgYW4gVW5wYXJzZWRFbnRpdHkgd2l0aCB0aGUgZ2l2ZW4gbmFtZSB3YXMgZGVjbGFyZWQgaW4gdGhlIERURCBvZiB0aGUgZG9jdW1lbnQKLSAgICAgKiBmb3IgdGhlIGN1cnJlbnQgcGlwZWxpbmUuICBJZiBzbywgdGhlbiB0aGUgbm90YXRpb24gZm9yIHRoZSBVbnBhcnNlZEVudGl0eSBpcyBjaGVja2VkLgotICAgICAqIElmIHRoYXQgdHVybnMgb3V0IG9rYXksIHRoZW4gdGhlIFVucGFyc2VkRW50aXR5IGlzIHBhc3NlZCB0byB0aGUgcm9vdCBwaXBlbGluZSB0bwotICAgICAqIGJlIGNoZWNrZWQgZm9yIGNvbmZsaWN0cywgYW5kIHNlbnQgdG8gdGhlIHJvb3QgRFRESGFuZGxlci4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlbnROYW1lIHRoZSBuYW1lIG9mIHRoZSBVbnBhcnNlZEVudGl0eSB0byBjaGVjawotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIGNoZWNrVW5wYXJzZWRFbnRpdHkoU3RyaW5nIGVudE5hbWUpIHsKLSAgICAgICAgVW5wYXJzZWRFbnRpdHkgZW50ID0gbmV3IFVucGFyc2VkRW50aXR5KCk7Ci0gICAgICAgIGVudC5uYW1lID0gZW50TmFtZTsKLSAgICAgICAgaW50IGluZGV4ID0gZlVucGFyc2VkRW50aXRpZXMuaW5kZXhPZihlbnQpOwotICAgICAgICBpZiAoaW5kZXggIT0gLTEpIHsKLSAgICAgICAgICAgIGVudCA9IChVbnBhcnNlZEVudGl0eSlmVW5wYXJzZWRFbnRpdGllcy5nZXQoaW5kZXgpOwotICAgICAgICAgICAgLy8gZmlyc3QgY2hlY2sgdGhlIG5vdGF0aW9uIG9mIHRoZSB1bnBhcnNlZCBlbnRpdHkKLSAgICAgICAgICAgIGNoZWNrTm90YXRpb24oZW50Lm5vdGF0aW9uKTsKLSAgICAgICAgICAgIGNoZWNrQW5kU2VuZFVucGFyc2VkRW50aXR5KGVudCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDaGVja3MgaWYgYSBOb3RhdGlvbiB3aXRoIHRoZSBnaXZlbiBuYW1lIHdhcyBkZWNsYXJlZCBpbiB0aGUgRFREIG9mIHRoZSBkb2N1bWVudAotICAgICAqIGZvciB0aGUgY3VycmVudCBwaXBlbGluZS4gIElmIHNvLCB0aGF0IE5vdGF0aW9uIGlzIHBhc3NlZCB0byB0aGUgcm9vdCBwaXBlbGluZSB0bwotICAgICAqIGJlIGNoZWNrZWQgZm9yIGNvbmZsaWN0cywgYW5kIHNlbnQgdG8gdGhlIHJvb3QgRFRESGFuZGxlcgotICAgICAqCi0gICAgICogQHBhcmFtIG5vdE5hbWUgdGhlIG5hbWUgb2YgdGhlIE5vdGF0aW9uIHRvIGNoZWNrCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgY2hlY2tOb3RhdGlvbihTdHJpbmcgbm90TmFtZSkgewotICAgICAgICBOb3RhdGlvbiBub3QgPSBuZXcgTm90YXRpb24oKTsKLSAgICAgICAgbm90Lm5hbWUgPSBub3ROYW1lOwotICAgICAgICBpbnQgaW5kZXggPSBmTm90YXRpb25zLmluZGV4T2Yobm90KTsKLSAgICAgICAgaWYgKGluZGV4ICE9IC0xKSB7Ci0gICAgICAgICAgICBub3QgPSAoTm90YXRpb24pZk5vdGF0aW9ucy5nZXQoaW5kZXgpOwotICAgICAgICAgICAgY2hlY2tBbmRTZW5kTm90YXRpb24obm90KTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoZSBwdXJwb3NlIG9mIHRoaXMgbWV0aG9kIGlzIHRvIGNoZWNrIGlmIGFuIFVucGFyc2VkRW50aXR5IGNvbmZsaWN0cyB3aXRoIGEgcHJldmlvdXNseQotICAgICAqIGRlY2xhcmVkIGVudGl0eSBpbiB0aGUgY3VycmVudCBwaXBlbGluZSBzdGFjay4gIElmIHRoZXJlIGlzIG5vIGNvbmZsaWN0LCB0aGUKLSAgICAgKiBVbnBhcnNlZEVudGl0eSBpcyBzZW50IGJ5IHRoZSByb290IHBpcGVsaW5lLgotICAgICAqCi0gICAgICogQHBhcmFtIGVudCB0aGUgVW5wYXJzZWRFbnRpdHkgdG8gY2hlY2sgZm9yIGNvbmZsaWN0cwotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIGNoZWNrQW5kU2VuZFVucGFyc2VkRW50aXR5KFVucGFyc2VkRW50aXR5IGVudCkgewotICAgICAgICBpZiAoaXNSb290RG9jdW1lbnQoKSkgewotICAgICAgICAgICAgaW50IGluZGV4ID0gZlVucGFyc2VkRW50aXRpZXMuaW5kZXhPZihlbnQpOwotICAgICAgICAgICAgaWYgKGluZGV4ID09IC0xKSB7Ci0gICAgICAgICAgICAgICAgLy8gVGhlcmUgaXMgbm8gdW5wYXJzZWQgZW50aXR5IHdpdGggdGhlIHNhbWUgbmFtZSB0aGF0IHdlIGhhdmUgc2VudC4KLSAgICAgICAgICAgICAgICAvLyBDYWxsaW5nIHVucGFyc2VkRW50aXR5RGVjbCgpIHdpbGwgYWRkIHRoZSBlbnRpdHkgdG8gb3VyIGxvY2FsIHN0b3JlLAotICAgICAgICAgICAgICAgIC8vIGFuZCBhbHNvIHNlbmQgdGhlIHVucGFyc2VkIGVudGl0eSB0byB0aGUgRFRESGFuZGxlcgotICAgICAgICAgICAgICAgIFhNTFJlc291cmNlSWRlbnRpZmllciBpZCA9Ci0gICAgICAgICAgICAgICAgICAgIG5ldyBYTUxSZXNvdXJjZUlkZW50aWZpZXJJbXBsKAotICAgICAgICAgICAgICAgICAgICAgICAgZW50LnB1YmxpY0lkLAotICAgICAgICAgICAgICAgICAgICAgICAgZW50LnN5c3RlbUlkLAotICAgICAgICAgICAgICAgICAgICAgICAgZW50LmJhc2VVUkksCi0gICAgICAgICAgICAgICAgICAgICAgICBlbnQuZXhwYW5kZWRTeXN0ZW1JZCk7Ci0gICAgICAgICAgICAgICAgYWRkVW5wYXJzZWRFbnRpdHkoCi0gICAgICAgICAgICAgICAgICAgIGVudC5uYW1lLAotICAgICAgICAgICAgICAgICAgICBpZCwKLSAgICAgICAgICAgICAgICAgICAgZW50Lm5vdGF0aW9uLAotICAgICAgICAgICAgICAgICAgICBlbnQuYXVnbWVudGF0aW9ucyk7Ci0gICAgICAgICAgICAgICAgaWYgKGZTZW5kVUVBbmROb3RhdGlvbkV2ZW50cyAmJiBmRFRESGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZEVERIYW5kbGVyLnVucGFyc2VkRW50aXR5RGVjbCgKLSAgICAgICAgICAgICAgICAgICAgICAgIGVudC5uYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgaWQsCi0gICAgICAgICAgICAgICAgICAgICAgICBlbnQubm90YXRpb24sCi0gICAgICAgICAgICAgICAgICAgICAgICBlbnQuYXVnbWVudGF0aW9ucyk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgVW5wYXJzZWRFbnRpdHkgbG9jYWxFbnRpdHkgPQotICAgICAgICAgICAgICAgICAgICAoVW5wYXJzZWRFbnRpdHkpZlVucGFyc2VkRW50aXRpZXMuZ2V0KGluZGV4KTsKLSAgICAgICAgICAgICAgICBpZiAoIWVudC5pc0R1cGxpY2F0ZShsb2NhbEVudGl0eSkpIHsKLSAgICAgICAgICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigKLSAgICAgICAgICAgICAgICAgICAgICAgICJOb25EdXBsaWNhdGVVbnBhcnNlZEVudGl0eSIsCi0gICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBlbnQubmFtZSB9KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBmUGFyZW50WEluY2x1ZGVIYW5kbGVyLmNoZWNrQW5kU2VuZFVucGFyc2VkRW50aXR5KGVudCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgcHVycG9zZSBvZiB0aGlzIG1ldGhvZCBpcyB0byBjaGVjayBpZiBhIE5vdGF0aW9uIGNvbmZsaWN0cyB3aXRoIGEgcHJldmlvdXNseQotICAgICAqIGRlY2xhcmVkIG5vdGF0aW9uIGluIHRoZSBjdXJyZW50IHBpcGVsaW5lIHN0YWNrLiAgSWYgdGhlcmUgaXMgbm8gY29uZmxpY3QsIHRoZQotICAgICAqIE5vdGF0aW9uIGlzIHNlbnQgYnkgdGhlIHJvb3QgcGlwZWxpbmUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbm90IHRoZSBOb3RhdGlvbiB0byBjaGVjayBmb3IgY29uZmxpY3RzCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgY2hlY2tBbmRTZW5kTm90YXRpb24oTm90YXRpb24gbm90KSB7Ci0gICAgICAgIGlmIChpc1Jvb3REb2N1bWVudCgpKSB7Ci0gICAgICAgICAgICBpbnQgaW5kZXggPSBmTm90YXRpb25zLmluZGV4T2Yobm90KTsKLSAgICAgICAgICAgIGlmIChpbmRleCA9PSAtMSkgewotICAgICAgICAgICAgICAgIC8vIFRoZXJlIGlzIG5vIG5vdGF0aW9uIHdpdGggdGhlIHNhbWUgbmFtZSB0aGF0IHdlIGhhdmUgc2VudC4KLSAgICAgICAgICAgICAgICBYTUxSZXNvdXJjZUlkZW50aWZpZXIgaWQgPQotICAgICAgICAgICAgICAgICAgICBuZXcgWE1MUmVzb3VyY2VJZGVudGlmaWVySW1wbCgKLSAgICAgICAgICAgICAgICAgICAgICAgIG5vdC5wdWJsaWNJZCwKLSAgICAgICAgICAgICAgICAgICAgICAgIG5vdC5zeXN0ZW1JZCwKLSAgICAgICAgICAgICAgICAgICAgICAgIG5vdC5iYXNlVVJJLAotICAgICAgICAgICAgICAgICAgICAgICAgbm90LmV4cGFuZGVkU3lzdGVtSWQpOwotICAgICAgICAgICAgICAgIGFkZE5vdGF0aW9uKG5vdC5uYW1lLCBpZCwgbm90LmF1Z21lbnRhdGlvbnMpOwotICAgICAgICAgICAgICAgIGlmIChmU2VuZFVFQW5kTm90YXRpb25FdmVudHMgJiYgZkRUREhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBmRFRESGFuZGxlci5ub3RhdGlvbkRlY2wobm90Lm5hbWUsIGlkLCBub3QuYXVnbWVudGF0aW9ucyk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgTm90YXRpb24gbG9jYWxOb3RhdGlvbiA9IChOb3RhdGlvbilmTm90YXRpb25zLmdldChpbmRleCk7Ci0gICAgICAgICAgICAgICAgaWYgKCFub3QuaXNEdXBsaWNhdGUobG9jYWxOb3RhdGlvbikpIHsKLSAgICAgICAgICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigKLSAgICAgICAgICAgICAgICAgICAgICAgICJOb25EdXBsaWNhdGVOb3RhdGlvbiIsCi0gICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBub3QubmFtZSB9KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBmUGFyZW50WEluY2x1ZGVIYW5kbGVyLmNoZWNrQW5kU2VuZE5vdGF0aW9uKG5vdCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDaGVja3Mgd2hldGhlciB0aGUgc3RyaW5nIG9ubHkgY29udGFpbnMgd2hpdGUgc3BhY2UgY2hhcmFjdGVycy4KLSAgICAgKgotICAgICAqIEBwYXJhbSB2YWx1ZSB0aGUgdGV4dCB0byBjaGVjawotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCBjaGVja1doaXRlc3BhY2UoWE1MU3RyaW5nIHZhbHVlKSB7Ci0gICAgICAgIGludCBlbmQgPSB2YWx1ZS5vZmZzZXQgKyB2YWx1ZS5sZW5ndGg7Ci0gICAgICAgIGZvciAoaW50IGkgPSB2YWx1ZS5vZmZzZXQ7IGkgPCBlbmQ7ICsraSkgewotICAgICAgICAgICAgaWYgKCFYTUxDaGFyLmlzU3BhY2UodmFsdWUuY2hbaV0pKSB7Ci0gICAgICAgICAgICAgICAgcmVwb3J0RmF0YWxFcnJvcigiQ29udGVudElsbGVnYWxBdFRvcExldmVsIik7Ci0gICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ2hlY2tzIHdoZXRoZXIgdGhlIHJvb3QgZWxlbWVudCBoYXMgYWxyZWFkeSBiZWVuIHByb2Nlc3NlZC4KLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgY2hlY2tNdWx0aXBsZVJvb3RFbGVtZW50cygpIHsKLSAgICAgICAgaWYgKGdldFJvb3RFbGVtZW50UHJvY2Vzc2VkKCkpIHsKLSAgICAgICAgICAgIHJlcG9ydEZhdGFsRXJyb3IoIk11bHRpcGxlUm9vdEVsZW1lbnRzIik7Ci0gICAgICAgIH0KLSAgICAgICAgc2V0Um9vdEVsZW1lbnRQcm9jZXNzZWQodHJ1ZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0cyB3aGV0aGVyIHRoZSByb290IGVsZW1lbnQgaGFzIGJlZW4gcHJvY2Vzc2VkLgotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCBzZXRSb290RWxlbWVudFByb2Nlc3NlZChib29sZWFuIHNlZW5Sb290KSB7Ci0gICAgICAgIGlmIChpc1Jvb3REb2N1bWVudCgpKSB7Ci0gICAgICAgICAgICBmU2VlblJvb3RFbGVtZW50ID0gc2VlblJvb3Q7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLSAgICAgICAgZlBhcmVudFhJbmNsdWRlSGFuZGxlci5zZXRSb290RWxlbWVudFByb2Nlc3NlZChzZWVuUm9vdCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB3aGV0aGVyIHRoZSByb290IGVsZW1lbnQgaGFzIGJlZW4gcHJvY2Vzc2VkLgotICAgICAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBnZXRSb290RWxlbWVudFByb2Nlc3NlZCgpIHsKLSAgICAgICAgcmV0dXJuIGlzUm9vdERvY3VtZW50KCkgPyBmU2VlblJvb3RFbGVtZW50IDogZlBhcmVudFhJbmNsdWRlSGFuZGxlci5nZXRSb290RWxlbWVudFByb2Nlc3NlZCgpOwotICAgIH0KLQotICAgIC8vIEl0IHdvdWxkIGJlIG5pY2UgaWYgd2UgZGlkbid0IGhhdmUgdG8gcmVwZWF0IGNvZGUgbGlrZSB0aGlzLCBidXQgdGhlcmUncyBubyBpbnRlcmZhY2UgdGhhdCBoYXMKLSAgICAvLyBzZXRGZWF0dXJlKCkgYW5kIGFkZFJlY29nbml6ZWRGZWF0dXJlcygpIHRoYXQgdGhlIG9iamVjdHMgaGF2ZSBpbiBjb21tb24uCi0gICAgcHJvdGVjdGVkIHZvaWQgY29weUZlYXR1cmVzKAotICAgICAgICBYTUxDb21wb25lbnRNYW5hZ2VyIGZyb20sCi0gICAgICAgIFBhcnNlckNvbmZpZ3VyYXRpb25TZXR0aW5ncyB0bykgewotICAgICAgICBFbnVtZXJhdGlvbiBmZWF0dXJlcyA9IENvbnN0YW50cy5nZXRYZXJjZXNGZWF0dXJlcygpOwotICAgICAgICBjb3B5RmVhdHVyZXMxKGZlYXR1cmVzLCBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYLCBmcm9tLCB0byk7Ci0gICAgICAgIGZlYXR1cmVzID0gQ29uc3RhbnRzLmdldFNBWEZlYXR1cmVzKCk7Ci0gICAgICAgIGNvcHlGZWF0dXJlczEoZmVhdHVyZXMsIENvbnN0YW50cy5TQVhfRkVBVFVSRV9QUkVGSVgsIGZyb20sIHRvKTsKLSAgICB9Ci0KLSAgICBwcm90ZWN0ZWQgdm9pZCBjb3B5RmVhdHVyZXMoCi0gICAgICAgIFhNTENvbXBvbmVudE1hbmFnZXIgZnJvbSwKLSAgICAgICAgWE1MUGFyc2VyQ29uZmlndXJhdGlvbiB0bykgewotICAgICAgICBFbnVtZXJhdGlvbiBmZWF0dXJlcyA9IENvbnN0YW50cy5nZXRYZXJjZXNGZWF0dXJlcygpOwotICAgICAgICBjb3B5RmVhdHVyZXMxKGZlYXR1cmVzLCBDb25zdGFudHMuWEVSQ0VTX0ZFQVRVUkVfUFJFRklYLCBmcm9tLCB0byk7Ci0gICAgICAgIGZlYXR1cmVzID0gQ29uc3RhbnRzLmdldFNBWEZlYXR1cmVzKCk7Ci0gICAgICAgIGNvcHlGZWF0dXJlczEoZmVhdHVyZXMsIENvbnN0YW50cy5TQVhfRkVBVFVSRV9QUkVGSVgsIGZyb20sIHRvKTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgY29weUZlYXR1cmVzMSgKLSAgICAgICAgRW51bWVyYXRpb24gZmVhdHVyZXMsCi0gICAgICAgIFN0cmluZyBmZWF0dXJlUHJlZml4LAotICAgICAgICBYTUxDb21wb25lbnRNYW5hZ2VyIGZyb20sCi0gICAgICAgIFBhcnNlckNvbmZpZ3VyYXRpb25TZXR0aW5ncyB0bykgewotICAgICAgICB3aGlsZSAoZmVhdHVyZXMuaGFzTW9yZUVsZW1lbnRzKCkpIHsKLSAgICAgICAgICAgIFN0cmluZyBmZWF0dXJlSWQgPSBmZWF0dXJlUHJlZml4ICsgKFN0cmluZylmZWF0dXJlcy5uZXh0RWxlbWVudCgpOwotCi0gICAgICAgICAgICB0by5hZGRSZWNvZ25pemVkRmVhdHVyZXMobmV3IFN0cmluZ1tdIHsgZmVhdHVyZUlkIH0pOwotCi0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIHRvLnNldEZlYXR1cmUoZmVhdHVyZUlkLCBmcm9tLmdldEZlYXR1cmUoZmVhdHVyZUlkKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXRjaCAoWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgLy8gY29tcG9uZW50TWFuYWdlciBkb2Vzbid0IHN1cHBvcnQgdGhpcyBmZWF0dXJlLAotICAgICAgICAgICAgICAgIC8vIHNvIHdlIHdvbid0IHdvcnJ5IGFib3V0IGl0Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgY29weUZlYXR1cmVzMSgKLSAgICAgICAgRW51bWVyYXRpb24gZmVhdHVyZXMsCi0gICAgICAgIFN0cmluZyBmZWF0dXJlUHJlZml4LAotICAgICAgICBYTUxDb21wb25lbnRNYW5hZ2VyIGZyb20sCi0gICAgICAgIFhNTFBhcnNlckNvbmZpZ3VyYXRpb24gdG8pIHsKLSAgICAgICAgd2hpbGUgKGZlYXR1cmVzLmhhc01vcmVFbGVtZW50cygpKSB7Ci0gICAgICAgICAgICBTdHJpbmcgZmVhdHVyZUlkID0gZmVhdHVyZVByZWZpeCArIChTdHJpbmcpZmVhdHVyZXMubmV4dEVsZW1lbnQoKTsKLSAgICAgICAgICAgIGJvb2xlYW4gdmFsdWUgPSBmcm9tLmdldEZlYXR1cmUoZmVhdHVyZUlkKTsKLQotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICB0by5zZXRGZWF0dXJlKGZlYXR1cmVJZCwgdmFsdWUpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2F0Y2ggKFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgIC8vIGNvbXBvbmVudE1hbmFnZXIgZG9lc24ndCBzdXBwb3J0IHRoaXMgZmVhdHVyZSwKLSAgICAgICAgICAgICAgICAvLyBzbyB3ZSB3b24ndCB3b3JyeSBhYm91dCBpdAotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgLy8gVGhpcyBpcyBhIHN0b3JhZ2UgY2xhc3MgdG8gaG9sZCBpbmZvcm1hdGlvbiBhYm91dCB0aGUgbm90YXRpb25zLgotICAgIC8vIFdlJ3JlIG5vdCB1c2luZyBYTUxOb3RhdGlvbkRlY2wgYmVjYXVzZSB3ZSBkb24ndCB3YW50IHRvIGxvc2UgdGhlIGF1Z21lbnRhdGlvbnMuCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBjbGFzcyBOb3RhdGlvbiB7Ci0gICAgICAgIHB1YmxpYyBTdHJpbmcgbmFtZTsKLSAgICAgICAgcHVibGljIFN0cmluZyBzeXN0ZW1JZDsKLSAgICAgICAgcHVibGljIFN0cmluZyBiYXNlVVJJOwotICAgICAgICBwdWJsaWMgU3RyaW5nIHB1YmxpY0lkOwotICAgICAgICBwdWJsaWMgU3RyaW5nIGV4cGFuZGVkU3lzdGVtSWQ7Ci0gICAgICAgIHB1YmxpYyBBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnM7Ci0KLSAgICAgICAgLy8gZXF1YWxzKCkgcmV0dXJucyB0cnVlIGlmIHR3byBOb3RhdGlvbnMgaGF2ZSB0aGUgc2FtZSBuYW1lLgotICAgICAgICAvLyBVc2VmdWwgZm9yIHNlYXJjaGluZyBWZWN0b3JzIGZvciBub3RhdGlvbnMgd2l0aCB0aGUgc2FtZSBuYW1lCi0gICAgICAgIEBPdmVycmlkZQotICAgICAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaikgewotICAgICAgICAgICAgcmV0dXJuIG9iaiA9PSB0aGlzIHx8IG9iaiBpbnN0YW5jZW9mIE5vdGF0aW9uCi0gICAgICAgICAgICAgICAgICAgICYmIE9iamVjdHMuZXF1YWxzKG5hbWUsICgoTm90YXRpb24pb2JqKS5uYW1lKTsKLSAgICAgICAgfQotCi0gICAgICAgIEBPdmVycmlkZQotICAgICAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewotICAgICAgICAgICAgcmV0dXJuIE9iamVjdHMuaGFzaENvZGUobmFtZSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBmcm9tIDQuNS4yCi0gICAgICAgIC8vIE5vdGF0aW9uIGl0ZW1zIHdpdGggdGhlIHNhbWUgW25hbWVdLCBbc3lzdGVtIGlkZW50aWZpZXJdLAotICAgICAgICAvLyBbcHVibGljIGlkZW50aWZpZXJdLCBhbmQgW2RlY2xhcmF0aW9uIGJhc2UgVVJJXSBhcmUgY29uc2lkZXJlZAotICAgICAgICAvLyB0byBiZSBkdXBsaWNhdGUuIEFuIGFwcGxpY2F0aW9uIG1heSBhbHNvIGJlIGFibGUgdG8gZGV0ZWN0IHRoYXQKLSAgICAgICAgLy8gbm90YXRpb25zIGFyZSBkdXBsaWNhdGUgdGhyb3VnaCBvdGhlciBtZWFucy4gRm9yIGluc3RhbmNlLCB0aGUgVVJJCi0gICAgICAgIC8vIHJlc3VsdGluZyBmcm9tIGNvbWJpbmluZyB0aGUgc3lzdGVtIGlkZW50aWZpZXIgYW5kIHRoZSBkZWNsYXJhdGlvbgotICAgICAgICAvLyBiYXNlIFVSSSBpcyB0aGUgc2FtZS4KLSAgICAgICAgcHVibGljIGJvb2xlYW4gaXNEdXBsaWNhdGUoT2JqZWN0IG9iaikgewotICAgICAgICAgICAgaWYgKG9iaiAhPSBudWxsICYmIG9iaiBpbnN0YW5jZW9mIE5vdGF0aW9uKSB7Ci0gICAgICAgICAgICAgICAgTm90YXRpb24gb3RoZXIgPSAoTm90YXRpb24pb2JqOwotICAgICAgICAgICAgICAgIHJldHVybiBPYmplY3RzLmVxdWFscyhuYW1lLCBvdGhlci5uYW1lKQotICAgICAgICAgICAgICAgICYmIE9iamVjdHMuZXF1YWxzKHB1YmxpY0lkLCBvdGhlci5wdWJsaWNJZCkKLSAgICAgICAgICAgICAgICAmJiBPYmplY3RzLmVxdWFscyhleHBhbmRlZFN5c3RlbUlkLCBvdGhlci5leHBhbmRlZFN5c3RlbUlkKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8vIFRoaXMgaXMgYSBzdG9yYWdlIGNsYXNzIHRvIGhvbGQgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHVucGFyc2VkIGVudGl0aWVzLgotICAgIC8vIFdlJ3JlIG5vdCB1c2luZyBYTUxFbnRpdHlEZWNsIGJlY2F1c2Ugd2UgZG9uJ3Qgd2FudCB0byBsb3NlIHRoZSBhdWdtZW50YXRpb25zLgotICAgIHByb3RlY3RlZCBzdGF0aWMgY2xhc3MgVW5wYXJzZWRFbnRpdHkgewotICAgICAgICBwdWJsaWMgU3RyaW5nIG5hbWU7Ci0gICAgICAgIHB1YmxpYyBTdHJpbmcgc3lzdGVtSWQ7Ci0gICAgICAgIHB1YmxpYyBTdHJpbmcgYmFzZVVSSTsKLSAgICAgICAgcHVibGljIFN0cmluZyBwdWJsaWNJZDsKLSAgICAgICAgcHVibGljIFN0cmluZyBleHBhbmRlZFN5c3RlbUlkOwotICAgICAgICBwdWJsaWMgU3RyaW5nIG5vdGF0aW9uOwotICAgICAgICBwdWJsaWMgQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zOwotCi0gICAgICAgIC8vIGVxdWFscygpIHJldHVybnMgdHJ1ZSBpZiB0d28gVW5wYXJzZWRFbnRpdGllcyBoYXZlIHRoZSBzYW1lIG5hbWUuCi0gICAgICAgIC8vIFVzZWZ1bCBmb3Igc2VhcmNoaW5nIFZlY3RvcnMgZm9yIGVudGl0aWVzIHdpdGggdGhlIHNhbWUgbmFtZQotICAgICAgICBAT3ZlcnJpZGUKLSAgICAgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmopIHsKLSAgICAgICAgICAgIHJldHVybiBvYmogPT0gdGhpcyB8fCBvYmogaW5zdGFuY2VvZiBVbnBhcnNlZEVudGl0eQotICAgICAgICAgICAgICAgICAgICAmJiBPYmplY3RzLmVxdWFscyhuYW1lLCAoKFVucGFyc2VkRW50aXR5KW9iaikubmFtZSk7Ci0gICAgICAgIH0KLQotICAgICAgICBAT3ZlcnJpZGUKLSAgICAgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKLSAgICAgICAgICAgIHJldHVybiBPYmplY3RzLmhhc2hDb2RlKG5hbWUpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gZnJvbSA0LjUuMToKLSAgICAgICAgLy8gVW5wYXJzZWQgZW50aXR5IGl0ZW1zIHdpdGggdGhlIHNhbWUgW25hbWVdLCBbc3lzdGVtIGlkZW50aWZpZXJdLAotICAgICAgICAvLyBbcHVibGljIGlkZW50aWZpZXJdLCBbZGVjbGFyYXRpb24gYmFzZSBVUkldLCBbbm90YXRpb24gbmFtZV0sIGFuZAotICAgICAgICAvLyBbbm90YXRpb25dIGFyZSBjb25zaWRlcmVkIHRvIGJlIGR1cGxpY2F0ZS4gQW4gYXBwbGljYXRpb24gbWF5IGFsc28KLSAgICAgICAgLy8gYmUgYWJsZSB0byBkZXRlY3QgdGhhdCB1bnBhcnNlZCBlbnRpdGllcyBhcmUgZHVwbGljYXRlIHRocm91Z2ggb3RoZXIKLSAgICAgICAgLy8gbWVhbnMuIEZvciBpbnN0YW5jZSwgdGhlIFVSSSByZXN1bHRpbmcgZnJvbSBjb21iaW5pbmcgdGhlIHN5c3RlbQotICAgICAgICAvLyBpZGVudGlmaWVyIGFuZCB0aGUgZGVjbGFyYXRpb24gYmFzZSBVUkkgaXMgdGhlIHNhbWUuCi0gICAgICAgIHB1YmxpYyBib29sZWFuIGlzRHVwbGljYXRlKE9iamVjdCBvYmopIHsKLSAgICAgICAgICAgIGlmIChvYmogIT0gbnVsbCAmJiBvYmogaW5zdGFuY2VvZiBVbnBhcnNlZEVudGl0eSkgewotICAgICAgICAgICAgICAgIFVucGFyc2VkRW50aXR5IG90aGVyID0gKFVucGFyc2VkRW50aXR5KW9iajsKLSAgICAgICAgICAgICAgICByZXR1cm4gT2JqZWN0cy5lcXVhbHMobmFtZSwgb3RoZXIubmFtZSkKLSAgICAgICAgICAgICAgICAmJiBPYmplY3RzLmVxdWFscyhwdWJsaWNJZCwgb3RoZXIucHVibGljSWQpCi0gICAgICAgICAgICAgICAgJiYgT2JqZWN0cy5lcXVhbHMoZXhwYW5kZWRTeXN0ZW1JZCwgb3RoZXIuZXhwYW5kZWRTeXN0ZW1JZCkKLSAgICAgICAgICAgICAgICAmJiBPYmplY3RzLmVxdWFscyhub3RhdGlvbiwgb3RoZXIubm90YXRpb24pOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLy8gVGhlIGZvbGxvd2luZyBtZXRob2RzIGFyZSB1c2VkIGZvciBYTUwgQmFzZSBwcm9jZXNzaW5nCi0KLSAgICAvKioKLSAgICAgKiBTYXZlcyB0aGUgY3VycmVudCBiYXNlIFVSSSB0byB0aGUgdG9wIG9mIHRoZSBzdGFjay4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCBzYXZlQmFzZVVSSSgpIHsKLSAgICAgICAgZkJhc2VVUklTY29wZS5wdXNoKGZEZXB0aCk7Ci0gICAgICAgIGZCYXNlVVJJLnB1c2goZkN1cnJlbnRCYXNlVVJJLmdldEJhc2VTeXN0ZW1JZCgpKTsKLSAgICAgICAgZkxpdGVyYWxTeXN0ZW1JRC5wdXNoKGZDdXJyZW50QmFzZVVSSS5nZXRMaXRlcmFsU3lzdGVtSWQoKSk7Ci0gICAgICAgIGZFeHBhbmRlZFN5c3RlbUlELnB1c2goZkN1cnJlbnRCYXNlVVJJLmdldEV4cGFuZGVkU3lzdGVtSWQoKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRGlzY2FyZHMgdGhlIFVSSXMgYXQgdGhlIHRvcCBvZiB0aGUgc3RhY2ssIGFuZCByZXN0b3JlcyB0aGUgb25lcyBiZW5lYXRoIGl0LgotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIHJlc3RvcmVCYXNlVVJJKCkgewotICAgICAgICBmQmFzZVVSSS5wb3AoKTsKLSAgICAgICAgZkxpdGVyYWxTeXN0ZW1JRC5wb3AoKTsKLSAgICAgICAgZkV4cGFuZGVkU3lzdGVtSUQucG9wKCk7Ci0gICAgICAgIGZCYXNlVVJJU2NvcGUucG9wKCk7Ci0gICAgICAgIGZDdXJyZW50QmFzZVVSSS5zZXRCYXNlU3lzdGVtSWQoKFN0cmluZylmQmFzZVVSSS5wZWVrKCkpOwotICAgICAgICBmQ3VycmVudEJhc2VVUkkuc2V0TGl0ZXJhbFN5c3RlbUlkKChTdHJpbmcpZkxpdGVyYWxTeXN0ZW1JRC5wZWVrKCkpOwotICAgICAgICBmQ3VycmVudEJhc2VVUkkuc2V0RXhwYW5kZWRTeXN0ZW1JZCgoU3RyaW5nKWZFeHBhbmRlZFN5c3RlbUlELnBlZWsoKSk7Ci0gICAgfQotCi0gICAgLy8gVGhlIGZvbGxvd2luZyBtZXRob2RzIGFyZSB1c2VkIGZvciBsYW5ndWFnZSBwcm9jZXNzaW5nCi0KLSAgICAvKioKLSAgICAgKiBTYXZlcyB0aGUgZ2l2ZW4gbGFuZ3VhZ2Ugb24gdGhlIHRvcCBvZiB0aGUgc3RhY2suCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbGFuYWd1YWdlIHRoZSBsYW5ndWFnZSB0byBwdXNoIG9udG8gdGhlIHN0YWNrLgotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIHNhdmVMYW5ndWFnZShTdHJpbmcgbGFuZ3VhZ2UpIHsKLSAgICAgICAgZkxhbmd1YWdlU2NvcGUucHVzaChmRGVwdGgpOwotICAgICAgICBmTGFuZ3VhZ2VTdGFjay5wdXNoKGxhbmd1YWdlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBEaXNjYXJkcyB0aGUgbGFuZ3VhZ2UgYXQgdGhlIHRvcCBvZiB0aGUgc3RhY2ssIGFuZCByZXR1cm5zIHRoZSBvbmUgYmVuZWF0aCBpdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIHJlc3RvcmVMYW5ndWFnZSgpIHsKLSAgICAgICAgZkxhbmd1YWdlU3RhY2sucG9wKCk7Ci0gICAgICAgIGZMYW5ndWFnZVNjb3BlLnBvcCgpOwotICAgICAgICByZXR1cm4gKFN0cmluZykgZkxhbmd1YWdlU3RhY2sucGVlaygpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldHMgdGhlIGJhc2UgVVJJIHRoYXQgd2FzIGluIHVzZSBhdCB0aGF0IGRlcHRoCi0gICAgICogQHBhcmFtIGRlcHRoCi0gICAgICogQHJldHVybiB0aGUgYmFzZSBVUkkKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEJhc2VVUkkoaW50IGRlcHRoKSB7Ci0gICAgICAgIGludCBzY29wZSA9IHNjb3BlT2ZCYXNlVVJJKGRlcHRoKTsKLSAgICAgICAgcmV0dXJuIChTdHJpbmcpZkV4cGFuZGVkU3lzdGVtSUQuZWxlbWVudEF0KHNjb3BlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXRzIHRoZSBsYW5ndWFnZSB0aGF0IHdhcyBpbiB1c2UgYXQgdGhhdCBkZXB0aC4KLSAgICAgKiBAcGFyYW0gZGVwdGgKLSAgICAgKiBAcmV0dXJuIHRoZSBsYW5ndWFnZQotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TGFuZ3VhZ2UoaW50IGRlcHRoKSB7Ci0gICAgICAgIGludCBzY29wZSA9IHNjb3BlT2ZMYW5ndWFnZShkZXB0aCk7Ci0gICAgICAgIHJldHVybiAoU3RyaW5nKWZMYW5ndWFnZVN0YWNrLmVsZW1lbnRBdChzY29wZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhIHJlbGF0aXZlIFVSSSwgd2hpY2ggd2hlbiByZXNvbHZlZCBhZ2FpbnN0IHRoZSBiYXNlIFVSSSBhdCB0aGUKLSAgICAgKiBzcGVjaWZpZWQgZGVwdGgsIHdpbGwgY3JlYXRlIHRoZSBjdXJyZW50IGJhc2UgVVJJLgotICAgICAqIFRoaXMgaXMgYWNjb21wbGlzaGVkIGJ5IG1lcmdlZCB0aGUgbGl0ZXJhbCBzeXN0ZW0gSURzLgotICAgICAqIEBwYXJhbSBkZXB0aCB0aGUgZGVwdGggYXQgd2hpY2ggdG8gc3RhcnQgY3JlYXRpbmcgdGhlIHJlbGF0aXZlIFVSSQotICAgICAqIEByZXR1cm4gYSByZWxhdGl2ZSBVUkkgdG8gY29udmVydCB0aGUgYmFzZSBVUkkgYXQgdGhlIGdpdmVuIGRlcHRoIHRvIHRoZSBjdXJyZW50Ci0gICAgICogICAgICAgICBiYXNlIFVSSQotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0UmVsYXRpdmVVUkkoaW50IGRlcHRoKSB0aHJvd3MgTWFsZm9ybWVkVVJJRXhjZXB0aW9uIHsKLSAgICAgICAgLy8gVGhlIGxpdGVyYWwgc3lzdGVtIGlkIGF0IHRoZSBsb2NhdGlvbiBnaXZlbiBieSAic3RhcnQiIGlzICppbiBmb2N1cyogYXQKLSAgICAgICAgLy8gdGhlIGdpdmVuIGRlcHRoLiBTbyB3ZSBuZWVkIHRvIGFkanVzdCBpdCB0byB0aGUgbmV4dCBzY29wZSwgc28gdGhhdCB3ZQotICAgICAgICAvLyBvbmx5IHByb2Nlc3Mgb3V0IG9mIGZvY3VzIGxpdGVyYWwgc3lzdGVtIGlkcwotICAgICAgICBpbnQgc3RhcnQgPSBzY29wZU9mQmFzZVVSSShkZXB0aCkgKyAxOwotICAgICAgICBpZiAoc3RhcnQgPT0gZkJhc2VVUklTY29wZS5zaXplKCkpIHsKLSAgICAgICAgICAgIC8vIElmIHRoYXQgaXMgdGhlIGxhc3Qgc3lzdGVtIGlkLCB0aGVuIHdlIGRvbid0IG5lZWQgYSByZWxhdGl2ZSBVUkkKLSAgICAgICAgICAgIHJldHVybiAiIjsKLSAgICAgICAgfQotICAgICAgICBVUkkgdXJpID0gbmV3IFVSSSgiZmlsZSIsIChTdHJpbmcpZkxpdGVyYWxTeXN0ZW1JRC5lbGVtZW50QXQoc3RhcnQpKTsKLSAgICAgICAgZm9yIChpbnQgaSA9IHN0YXJ0ICsgMTsgaSA8IGZCYXNlVVJJU2NvcGUuc2l6ZSgpOyBpKyspIHsKLSAgICAgICAgICAgIHVyaSA9IG5ldyBVUkkodXJpLCAoU3RyaW5nKWZMaXRlcmFsU3lzdGVtSUQuZWxlbWVudEF0KGkpKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gdXJpLmdldFBhdGgoKTsKLSAgICB9Ci0KLSAgICAvLyBXZSBuZWVkIHRvIGZpbmQgdHdvIGNvbnNlY3V0aXZlIGVsZW1lbnRzIGluIHRoZSBzY29wZSBzdGFjaywKLSAgICAvLyBzdWNoIHRoYXQgdGhlIGZpcnN0IGlzIGxvd2VyIHRoYW4gJ2RlcHRoJyAob3IgZXF1YWwpLCBhbmQgdGhlCi0gICAgLy8gc2Vjb25kIGlzIGhpZ2hlci4KLSAgICBwcml2YXRlIGludCBzY29wZU9mQmFzZVVSSShpbnQgZGVwdGgpIHsKLSAgICAgICAgZm9yIChpbnQgaSA9IGZCYXNlVVJJU2NvcGUuc2l6ZSgpIC0gMTsgaSA+PSAwOyBpLS0pIHsKLSAgICAgICAgICAgIGlmIChmQmFzZVVSSVNjb3BlLmVsZW1lbnRBdChpKSA8PSBkZXB0aCkKLSAgICAgICAgICAgICAgICByZXR1cm4gaTsKLSAgICAgICAgfQotICAgICAgICAvLyB3ZSBzaG91bGQgbmV2ZXIgZ2V0IGhlcmUsIGJlY2F1c2UgMCB3YXMgcHV0IG9uIHRoZSBzdGFjayBpbiBzdGFydERvY3VtZW50KCkKLSAgICAgICAgcmV0dXJuIC0xOwotICAgIH0KLQotICAgIHByaXZhdGUgaW50IHNjb3BlT2ZMYW5ndWFnZShpbnQgZGVwdGgpIHsKLSAgICAgICAgZm9yIChpbnQgaSA9IGZMYW5ndWFnZVNjb3BlLnNpemUoKSAtIDE7IGkgPj0gMDsgaS0tKSB7Ci0gICAgICAgICAgICBpZiAoZkxhbmd1YWdlU2NvcGUuZWxlbWVudEF0KGkpIDw9IGRlcHRoKQotICAgICAgICAgICAgICAgIHJldHVybiBpOwotICAgICAgICB9Ci0gICAgICAgIC8vIHdlIHNob3VsZCBuZXZlciBnZXQgaGVyZSwgYmVjYXVzZSAwIHdhcyBwdXQgb24gdGhlIHN0YWNrIGluIHN0YXJ0RG9jdW1lbnQoKQotICAgICAgICByZXR1cm4gLTE7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2VhcmNoIGZvciBhIHhtbDpiYXNlIGF0dHJpYnV0ZSwgYW5kIGlmIG9uZSBpcyBmb3VuZCwgcHV0IHRoZSBuZXcgYmFzZSBVUkkgaW50bwotICAgICAqIGVmZmVjdC4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCBwcm9jZXNzWE1MQmFzZUF0dHJpYnV0ZXMoWE1MQXR0cmlidXRlcyBhdHRyaWJ1dGVzKSB7Ci0gICAgICAgIFN0cmluZyBiYXNlVVJJVmFsdWUgPQotICAgICAgICAgICAgYXR0cmlidXRlcy5nZXRWYWx1ZShOYW1lc3BhY2VDb250ZXh0LlhNTF9VUkksICJiYXNlIik7Ci0gICAgICAgIGlmIChiYXNlVVJJVmFsdWUgIT0gbnVsbCkgewotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgZXhwYW5kZWRWYWx1ZSA9Ci0gICAgICAgICAgICAgICAgICAgIFhNTEVudGl0eU1hbmFnZXIuZXhwYW5kU3lzdGVtSWQoCi0gICAgICAgICAgICAgICAgICAgICAgICBiYXNlVVJJVmFsdWUsCi0gICAgICAgICAgICAgICAgICAgICAgICBmQ3VycmVudEJhc2VVUkkuZ2V0RXhwYW5kZWRTeXN0ZW1JZCgpLAotICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UpOwotICAgICAgICAgICAgICAgIGZDdXJyZW50QmFzZVVSSS5zZXRMaXRlcmFsU3lzdGVtSWQoYmFzZVVSSVZhbHVlKTsKLSAgICAgICAgICAgICAgICBmQ3VycmVudEJhc2VVUkkuc2V0QmFzZVN5c3RlbUlkKAotICAgICAgICAgICAgICAgICAgICBmQ3VycmVudEJhc2VVUkkuZ2V0RXhwYW5kZWRTeXN0ZW1JZCgpKTsKLSAgICAgICAgICAgICAgICBmQ3VycmVudEJhc2VVUkkuc2V0RXhwYW5kZWRTeXN0ZW1JZChleHBhbmRlZFZhbHVlKTsKLQotICAgICAgICAgICAgICAgIC8vIHB1c2ggdGhlIG5ldyB2YWx1ZXMgb24gdGhlIHN0YWNrCi0gICAgICAgICAgICAgICAgc2F2ZUJhc2VVUkkoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhdGNoIChNYWxmb3JtZWRVUklFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgIC8vIFJFVklTSVQ6IHRocm93IGVycm9yIGhlcmUKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNlYXJjaCBmb3IgYSB4bWw6bGFuZyBhdHRyaWJ1dGUsIGFuZCBpZiBvbmUgaXMgZm91bmQsIHB1dCB0aGUgbmV3Ci0gICAgICogW2xhbmd1YWdlXSBpbnRvIGVmZmVjdC4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCBwcm9jZXNzWE1MTGFuZ0F0dHJpYnV0ZXMoWE1MQXR0cmlidXRlcyBhdHRyaWJ1dGVzKSB7Ci0gICAgICAgIFN0cmluZyBsYW5ndWFnZSA9IGF0dHJpYnV0ZXMuZ2V0VmFsdWUoTmFtZXNwYWNlQ29udGV4dC5YTUxfVVJJLCAibGFuZyIpOwotICAgICAgICBpZiAobGFuZ3VhZ2UgIT0gbnVsbCkgewotICAgICAgICAgICAgZkN1cnJlbnRMYW5ndWFnZSA9IGxhbmd1YWdlOwotICAgICAgICAgICAgc2F2ZUxhbmd1YWdlKGZDdXJyZW50TGFuZ3VhZ2UpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgZ2l2ZW4gc3RyaW5nCi0gICAgICogd291bGQgYmUgdmFsaWQgaW4gYW4gSFRUUCBoZWFkZXIuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdmFsdWUgc3RyaW5nIHRvIGNoZWNrCi0gICAgICogQHJldHVybiA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgZ2l2ZW4gc3RyaW5nCi0gICAgICogd291bGQgYmUgdmFsaWQgaW4gYW4gSFRUUCBoZWFkZXIKLSAgICAgKi8KLSAgICBwcml2YXRlIGJvb2xlYW4gaXNWYWxpZEluSFRUUEhlYWRlciAoU3RyaW5nIHZhbHVlKSB7Ci0gICAgICAgIGNoYXIgY2g7Ci0gICAgICAgIGZvciAoaW50IGkgPSB2YWx1ZS5sZW5ndGgoKSAtIDE7IGkgPj0gMDsgLS1pKSB7Ci0gICAgICAgICAgICBjaCA9IHZhbHVlLmNoYXJBdChpKTsKLSAgICAgICAgICAgIGlmIChjaCA8IDB4MjAgfHwgY2ggPiAweDdFKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYSBuZXcgPGNvZGU+WE1MSW5wdXRTb3VyY2U8L2NvZGU+IGZyb20gdGhlIGdpdmVuIHBhcmFtZXRlcnMuCi0gICAgICovCi0gICAgcHJpdmF0ZSBYTUxJbnB1dFNvdXJjZSBjcmVhdGVJbnB1dFNvdXJjZShTdHJpbmcgcHVibGljSWQsCi0gICAgICAgICAgICBTdHJpbmcgc3lzdGVtSWQsIFN0cmluZyBiYXNlU3lzdGVtSWQsCi0gICAgICAgICAgICBTdHJpbmcgYWNjZXB0LCBTdHJpbmcgYWNjZXB0TGFuZ3VhZ2UpIHsKLQotICAgICAgICBIVFRQSW5wdXRTb3VyY2UgaHR0cFNvdXJjZSA9IG5ldyBIVFRQSW5wdXRTb3VyY2UocHVibGljSWQsIHN5c3RlbUlkLCBiYXNlU3lzdGVtSWQpOwotICAgICAgICBpZiAoYWNjZXB0ICE9IG51bGwgJiYgYWNjZXB0Lmxlbmd0aCgpID4gMCkgewotICAgICAgICAgICAgaHR0cFNvdXJjZS5zZXRIVFRQUmVxdWVzdFByb3BlcnR5KFhJbmNsdWRlSGFuZGxlci5IVFRQX0FDQ0VQVCwgYWNjZXB0KTsKLSAgICAgICAgfQotICAgICAgICBpZiAoYWNjZXB0TGFuZ3VhZ2UgIT0gbnVsbCAmJiBhY2NlcHRMYW5ndWFnZS5sZW5ndGgoKSA+IDApIHsKLSAgICAgICAgICAgIGh0dHBTb3VyY2Uuc2V0SFRUUFJlcXVlc3RQcm9wZXJ0eShYSW5jbHVkZUhhbmRsZXIuSFRUUF9BQ0NFUFRfTEFOR1VBR0UsIGFjY2VwdExhbmd1YWdlKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gaHR0cFNvdXJjZTsKLSAgICB9Ci0KLSAgICAvLyB3aGljaCBBU0NJSSBjaGFyYWN0ZXJzIG5lZWQgdG8gYmUgZXNjYXBlZAotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW4gZ05lZWRFc2NhcGluZ1tdID0gbmV3IGJvb2xlYW5bMTI4XTsKLSAgICAvLyB0aGUgZmlyc3QgaGV4IGNoYXJhY3RlciBpZiBhIGNoYXJhY3RlciBuZWVkcyB0byBiZSBlc2NhcGVkCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2hhciBnQWZ0ZXJFc2NhcGluZzFbXSA9IG5ldyBjaGFyWzEyOF07Ci0gICAgLy8gdGhlIHNlY29uZCBoZXggY2hhcmFjdGVyIGlmIGEgY2hhcmFjdGVyIG5lZWRzIHRvIGJlIGVzY2FwZWQKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjaGFyIGdBZnRlckVzY2FwaW5nMltdID0gbmV3IGNoYXJbMTI4XTsKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjaGFyW10gZ0hleENocyA9IHsnMCcsICcxJywgJzInLCAnMycsICc0JywgJzUnLCAnNicsICc3JywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnOCcsICc5JywgJ0EnLCAnQicsICdDJywgJ0QnLCAnRScsICdGJ307Ci0gICAgLy8gaW5pdGlhbGl6ZSB0aGUgYWJvdmUgMyBhcnJheXMKLSAgICBzdGF0aWMgewotICAgICAgICBjaGFyW10gZXNjQ2hzID0geycgJywgJzwnLCAnPicsICciJywgJ3snLCAnfScsICd8JywgJ1xcJywgJ14nLCAnYCd9OwotICAgICAgICBpbnQgbGVuID0gZXNjQ2hzLmxlbmd0aDsKLSAgICAgICAgY2hhciBjaDsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW47IGkrKykgewotICAgICAgICAgICAgY2ggPSBlc2NDaHNbaV07Ci0gICAgICAgICAgICBnTmVlZEVzY2FwaW5nW2NoXSA9IHRydWU7Ci0gICAgICAgICAgICBnQWZ0ZXJFc2NhcGluZzFbY2hdID0gZ0hleENoc1tjaCA+PiA0XTsKLSAgICAgICAgICAgIGdBZnRlckVzY2FwaW5nMltjaF0gPSBnSGV4Q2hzW2NoICYgMHhmXTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8vCi0gICAgLy8gRXNjYXBlIGFuIGhyZWYgdmFsdWUgYWNjb3JkaW5nIHRvICg0LjEuMSk6Ci0gICAgLy8KLSAgICAvLyBUbyBjb252ZXJ0IHRoZSB2YWx1ZSBvZiB0aGUgaHJlZiBhdHRyaWJ1dGUgdG8gYW4gSVJJIHJlZmVyZW5jZSwgdGhlIGZvbGxvd2luZyBjaGFyYWN0ZXJzIG11c3QgYmUgZXNjYXBlZDoKLSAgICAvLyBzcGFjZSAjeDIwCi0gICAgLy8gdGhlIGRlbGltaXRlcnMgPCAjeDNDLCA+ICN4M0UgYW5kICIgI3gyMgotICAgIC8vIHRoZSB1bndpc2UgY2hhcmFjdGVycyB7ICN4N0IsIH0gI3g3RCwgfCAjeDdDLCBcICN4NUMsIF4gI3g1RSBhbmQgYCAjeDYwCi0gICAgLy8KLSAgICAvLyBUbyBjb252ZXJ0IGFuIElSSSByZWZlcmVuY2UgdG8gYSBVUkkgcmVmZXJlbmNlLCB0aGUgZm9sbG93aW5nIGNoYXJhY3RlcnMgbXVzdCBhbHNvIGJlIGVzY2FwZWQ6Ci0gICAgLy8gdGhlIFVuaWNvZGUgcGxhbmUgMCBjaGFyYWN0ZXJzICN4QTAgLSAjeEQ3RkYsICN4RjkwMC0jeEZEQ0YsICN4RkRGMC0jeEZGRUYKLSAgICAvLyB0aGUgVW5pY29kZSBwbGFuZSAxLTE0IGNoYXJhY3RlcnMgI3gxMDAwMC0jeDFGRkZEIC4uLiAjeEUwMDAwLSN4RUZGRkQKLSAgICAvLwotICAgIHByaXZhdGUgU3RyaW5nIGVzY2FwZUhyZWYoU3RyaW5nIGhyZWYpIHsKLSAgICAgICAgaW50IGxlbiA9IGhyZWYubGVuZ3RoKCk7Ci0gICAgICAgIGludCBjaDsKLSAgICAgICAgZmluYWwgU3RyaW5nQnVpbGRlciBidWZmZXIgPSBuZXcgU3RyaW5nQnVpbGRlcihsZW4qMyk7Ci0KLSAgICAgICAgLy8gZm9yIGVhY2ggY2hhcmFjdGVyIGluIHRoZSBocmVmCi0gICAgICAgIGludCBpID0gMDsKLSAgICAgICAgZm9yICg7IGkgPCBsZW47IGkrKykgewotICAgICAgICAgICAgY2ggPSBocmVmLmNoYXJBdChpKTsKLSAgICAgICAgICAgIC8vIGlmIGl0J3Mgbm90IGFuIEFTQ0lJIGNoYXJhY3RlciAoZXhjbHVkaW5nIDB4N0YpLCBicmVhayBoZXJlLCBhbmQgdXNlIFVURi04IGVuY29kaW5nCi0gICAgICAgICAgICBpZiAoY2ggPiAweDdFKSB7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyBhYm9ydDogaHJlZiBkb2VzIG5vdCBhbGxvdyB0aGlzIGNoYXJhY3RlcgotICAgICAgICAgICAgaWYgKGNoIDwgMHgyMCkgewotICAgICAgICAgICAgICAgIHJldHVybiBocmVmOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKGdOZWVkRXNjYXBpbmdbY2hdKSB7Ci0gICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgnJScpOwotICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoZ0FmdGVyRXNjYXBpbmcxW2NoXSk7Ci0gICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZChnQWZ0ZXJFc2NhcGluZzJbY2hdKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoKGNoYXIpY2gpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gd2Ugc2F3IHNvbWUgbm9uLWFzY2lpIGNoYXJhY3RlcgotICAgICAgICBpZiAoaSA8IGxlbikgewotICAgICAgICAgICAgLy8gY2hlY2sgaWYgcmVtYWluZGVyIG9mIGhyZWYgY29udGFpbnMgYW55IGlsbGVnYWwgY2hhcmFjdGVycyBiZWZvcmUgcHJvY2VlZGluZwotICAgICAgICAgICAgZm9yIChpbnQgaiA9IGk7IGogPCBsZW47ICsraikgewotICAgICAgICAgICAgICAgIGNoID0gaHJlZi5jaGFyQXQoaik7Ci0gICAgICAgICAgICAgICAgaWYgKChjaCA+PSAweDIwICYmIGNoIDw9IDB4N0UpIHx8Ci0gICAgICAgICAgICAgICAgICAgIChjaCA+PSAweEEwICYmIGNoIDw9IDB4RDdGRikgfHwKLSAgICAgICAgICAgICAgICAgICAgKGNoID49IDB4RjkwMCAmJiBjaCA8PSAweEZEQ0YpIHx8Ci0gICAgICAgICAgICAgICAgICAgIChjaCA+PSAweEZERjAgJiYgY2ggPD0gMHhGRkVGKSkgewotICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaWYgKFhNTENoYXIuaXNIaWdoU3Vycm9nYXRlKGNoKSAmJiArK2ogPCBsZW4pIHsKLSAgICAgICAgICAgICAgICAgICAgaW50IGNoMiA9IGhyZWYuY2hhckF0KGopOwotICAgICAgICAgICAgICAgICAgICBpZiAoWE1MQ2hhci5pc0xvd1N1cnJvZ2F0ZShjaDIpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBjaDIgPSBYTUxDaGFyLnN1cHBsZW1lbnRhbCgoY2hhciljaCwgKGNoYXIpY2gyKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjaDIgPCAweEYwMDAwICYmIChjaDIgJiAweEZGRkYpIDw9IDB4RkZGRCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIC8vIGFib3J0OiBocmVmIGRvZXMgbm90IGFsbG93IHRoaXMgY2hhcmFjdGVyCi0gICAgICAgICAgICAgICAgcmV0dXJuIGhyZWY7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIGdldCBVVEYtOCBieXRlcyBmb3IgdGhlIHJlbWFpbmluZyBzdWItc3RyaW5nCi0gICAgICAgICAgICBieXRlW10gYnl0ZXMgPSBudWxsOwotICAgICAgICAgICAgYnl0ZSBiOwotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICBieXRlcyA9IGhyZWYuc3Vic3RyaW5nKGkpLmdldEJ5dGVzKCJVVEYtOCIpOwotICAgICAgICAgICAgfSBjYXRjaCAoamF2YS5pby5VbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICAvLyBzaG91bGQgbmV2ZXIgaGFwcGVuCi0gICAgICAgICAgICAgICAgcmV0dXJuIGhyZWY7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBsZW4gPSBieXRlcy5sZW5ndGg7Ci0KLSAgICAgICAgICAgIC8vIGZvciBlYWNoIGJ5dGUKLSAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKykgewotICAgICAgICAgICAgICAgIGIgPSBieXRlc1tpXTsKLSAgICAgICAgICAgICAgICAvLyBmb3Igbm9uLWFzY2lpIGNoYXJhY3RlcjogbWFrZSBpdCBwb3NpdGl2ZSwgdGhlbiBlc2NhcGUKLSAgICAgICAgICAgICAgICBpZiAoYiA8IDApIHsKLSAgICAgICAgICAgICAgICAgICAgY2ggPSBiICsgMjU2OwotICAgICAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCclJyk7Ci0gICAgICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoZ0hleENoc1tjaCA+PiA0XSk7Ci0gICAgICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoZ0hleENoc1tjaCAmIDB4Zl0pOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIGlmIChnTmVlZEVzY2FwaW5nW2JdKSB7Ci0gICAgICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoJyUnKTsKLSAgICAgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZChnQWZ0ZXJFc2NhcGluZzFbYl0pOwotICAgICAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKGdBZnRlckVzY2FwaW5nMltiXSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKChjaGFyKWIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIElmIGVzY2FwaW5nIGhhcHBlbmVkLCBjcmVhdGUgYSBuZXcgc3RyaW5nOwotICAgICAgICAvLyBvdGhlcndpc2UsIHJldHVybiB0aGUgb3JnaW5hbCBvbmUuCi0gICAgICAgIGlmIChidWZmZXIubGVuZ3RoKCkgIT0gbGVuKSB7Ci0gICAgICAgICAgICByZXR1cm4gYnVmZmVyLnRvU3RyaW5nKCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gaHJlZjsKLSAgICAgICAgfQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3hpbmNsdWRlL1hJbmNsdWRlTWVzc2FnZUZvcm1hdHRlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveGluY2x1ZGUvWEluY2x1ZGVNZXNzYWdlRm9ybWF0dGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAyNzU2MTUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveGluY2x1ZGUvWEluY2x1ZGVNZXNzYWdlRm9ybWF0dGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5MCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAzLTIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueGluY2x1ZGU7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuTWVzc2FnZUZvcm1hdHRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWxzLlNlY3VyaXR5U3VwcG9ydDsKLWltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwotaW1wb3J0IGphdmEudXRpbC5NaXNzaW5nUmVzb3VyY2VFeGNlcHRpb247Ci1pbXBvcnQgamF2YS51dGlsLlJlc291cmNlQnVuZGxlOwotCi0vLyBUT0RPOiBmaXggZXJyb3IgbWVzc2FnZXMgaW4gWEluY2x1ZGVNZXNzYWdlcy5wcm9wZXJ0aWVzCi0vKioKLSAqIFhJbmNsdWRlTWVzc2FnZUZvcm1hdHRlciBwcm92aWRlcyBlcnJvciBtZXNzYWdlcyBmb3IgdGhlIFhJbmNsdWRlIDEuMCBDYW5kaWRhdGUgUmVjb21tZW5kYXRpb24KLSAqCi0gKiBAYXV0aG9yIFBldGVyIE1jQ3JhY2tlbiwgSUJNCi0gKgotICogQHZlcnNpb24gJElkOiBYSW5jbHVkZU1lc3NhZ2VGb3JtYXR0ZXIuamF2YSx2IDEuNyAyMDEwLTExLTAxIDA0OjQwOjE4IGpvZWh3IEV4cCAkCi0gKi8KLXB1YmxpYyBjbGFzcyBYSW5jbHVkZU1lc3NhZ2VGb3JtYXR0ZXIgaW1wbGVtZW50cyBNZXNzYWdlRm9ybWF0dGVyIHsKLQotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFhJTkNMVURFX0RPTUFJTiA9ICJodHRwOi8vd3d3LnczLm9yZy9UUi94aW5jbHVkZSI7Ci0KLSAgICAgLy8gcHJpdmF0ZSBvYmplY3RzIHRvIGNhY2hlIHRoZSBsb2NhbGUgYW5kIHJlc291cmNlIGJ1bmRsZQotICAgIHByaXZhdGUgTG9jYWxlIGZMb2NhbGUgPSBudWxsOwotICAgIHByaXZhdGUgUmVzb3VyY2VCdW5kbGUgZlJlc291cmNlQnVuZGxlID0gbnVsbDsKLQotICAgIC8qKgotICAgICAqIEZvcm1hdHMgYSBtZXNzYWdlIHdpdGggdGhlIHNwZWNpZmllZCBhcmd1bWVudHMgdXNpbmcgdGhlIGdpdmVuCi0gICAgICogbG9jYWxlIGluZm9ybWF0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIGxvY2FsZSAgICBUaGUgbG9jYWxlIG9mIHRoZSBtZXNzYWdlLgotICAgICAqIEBwYXJhbSBrZXkgICAgICAgVGhlIG1lc3NhZ2Uga2V5LgotICAgICAqIEBwYXJhbSBhcmd1bWVudHMgVGhlIG1lc3NhZ2UgcmVwbGFjZW1lbnQgdGV4dCBhcmd1bWVudHMuIFRoZSBvcmRlcgotICAgICAqICAgICAgICAgICAgICAgICAgb2YgdGhlIGFyZ3VtZW50cyBtdXN0IG1hdGNoIHRoYXQgb2YgdGhlIHBsYWNlaG9sZGVycwotICAgICAqICAgICAgICAgICAgICAgICAgaW4gdGhlIGFjdHVhbCBtZXNzYWdlLgotICAgICAqCi0gICAgICogQHJldHVybiBSZXR1cm5zIHRoZSBmb3JtYXR0ZWQgbWVzc2FnZS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uIFRocm93biBpZiB0aGUgbWVzc2FnZSB3aXRoIHRoZQotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwZWNpZmllZCBrZXkgY2Fubm90IGJlIGZvdW5kLgotICAgICAqLwotICAgICBwdWJsaWMgU3RyaW5nIGZvcm1hdE1lc3NhZ2UoTG9jYWxlIGxvY2FsZSwgU3RyaW5nIGtleSwgT2JqZWN0W10gYXJndW1lbnRzKQotICAgICAgICB0aHJvd3MgTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uIHsKLQotICAgICAgICBpZiAoZlJlc291cmNlQnVuZGxlID09IG51bGwgfHwgbG9jYWxlICE9IGZMb2NhbGUpIHsKLSAgICAgICAgICAgIGlmIChsb2NhbGUgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZSZXNvdXJjZUJ1bmRsZSA9IFNlY3VyaXR5U3VwcG9ydC5nZXRSZXNvdXJjZUJ1bmRsZSgiY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLm1zZy5YSW5jbHVkZU1lc3NhZ2VzIiwgbG9jYWxlKTsKLSAgICAgICAgICAgICAgICAvLyBtZW1vcml6ZSB0aGUgbW9zdC1yZWNlbnQgbG9jYWxlCi0gICAgICAgICAgICAgICAgZkxvY2FsZSA9IGxvY2FsZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChmUmVzb3VyY2VCdW5kbGUgPT0gbnVsbCkKLSAgICAgICAgICAgICAgICBmUmVzb3VyY2VCdW5kbGUgPSBTZWN1cml0eVN1cHBvcnQuZ2V0UmVzb3VyY2VCdW5kbGUoImNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5tc2cuWEluY2x1ZGVNZXNzYWdlcyIpOwotICAgICAgICB9Ci0KLSAgICAgICAgU3RyaW5nIG1zZyA9IGZSZXNvdXJjZUJ1bmRsZS5nZXRTdHJpbmcoa2V5KTsKLSAgICAgICAgaWYgKGFyZ3VtZW50cyAhPSBudWxsKSB7Ci0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIG1zZyA9IGphdmEudGV4dC5NZXNzYWdlRm9ybWF0LmZvcm1hdChtc2csIGFyZ3VtZW50cyk7Ci0gICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgIG1zZyA9IGZSZXNvdXJjZUJ1bmRsZS5nZXRTdHJpbmcoIkZvcm1hdEZhaWxlZCIpOwotICAgICAgICAgICAgICAgIG1zZyArPSAiICIgKyBmUmVzb3VyY2VCdW5kbGUuZ2V0U3RyaW5nKGtleSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAobXNnID09IG51bGwpIHsKLSAgICAgICAgICAgIG1zZyA9IGZSZXNvdXJjZUJ1bmRsZS5nZXRTdHJpbmcoIkJhZE1lc3NhZ2VLZXkiKTsKLSAgICAgICAgICAgIHRocm93IG5ldyBNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24obXNnLCAiY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLm1zZy5YSW5jbHVkZU1lc3NhZ2VzIiwga2V5KTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBtc2c7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveGluY2x1ZGUvWEluY2x1ZGVOYW1lc3BhY2VTdXBwb3J0LmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94aW5jbHVkZS9YSW5jbHVkZU5hbWVzcGFjZVN1cHBvcnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggM2MzNmQxNC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94aW5jbHVkZS9YSW5jbHVkZU5hbWVzcGFjZVN1cHBvcnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDk1ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDMtMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueGluY2x1ZGU7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5OYW1lc3BhY2VDb250ZXh0OwotCi0vKioKLSAqIFRoaXMgaXMgYW4gaW1wbGVtZW50YXRpb24gb2YgTmFtZXNwYWNlQ29udGV4dCB3aGljaCBpcyBpbnRlbmRlZCB0byBiZSB1c2VkIGZvcgotICogWEluY2x1ZGUgcHJvY2Vzc2luZy4gIEl0IGVuYWJsZXMgZWFjaCBjb250ZXh0IHRvIGJlIG1hcmtlZCBhcyBpbnZhbGlkLCBpZiBuZWNlc3NhcnksCi0gKiB0byBpbmRpY2F0ZSB0aGF0IHRoZSBuYW1lc3BhY2VzIHJlY29yZGVkIG9uIHRob3NlIGNvbnRleHRzIHdvbid0IGJlIGFwcGFyZW50IGluIHRoZQotICogcmVzdWx0aW5nIGluZm9zZXQuCi0gKgotICogQGF1dGhvciBQZXRlciBNY0NyYWNrZW4sIElCTQotICoKLSAqLwotcHVibGljIGNsYXNzIFhJbmNsdWRlTmFtZXNwYWNlU3VwcG9ydCBleHRlbmRzIE11bHRpcGxlU2NvcGVOYW1lc3BhY2VTdXBwb3J0IHsKLQotICAgIC8qKgotICAgICAqIFRoaXMgc3RvcmVzIHdoZXRoZXIgb3Igbm90IHRoZSBjb250ZXh0IGF0IHRoZSBtYXRjaGluZyBkZXB0aCB3YXMgdmFsaWQuCi0gICAgICovCi0gICAgcHJpdmF0ZSBib29sZWFuW10gZlZhbGlkQ29udGV4dCA9IG5ldyBib29sZWFuWzhdOwotCi0gICAgLyoqCi0gICAgICoKLSAgICAgKi8KLSAgICBwdWJsaWMgWEluY2x1ZGVOYW1lc3BhY2VTdXBwb3J0KCkgewotICAgICAgICBzdXBlcigpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBwYXJhbSBjb250ZXh0Ci0gICAgICovCi0gICAgcHVibGljIFhJbmNsdWRlTmFtZXNwYWNlU3VwcG9ydChOYW1lc3BhY2VDb250ZXh0IGNvbnRleHQpIHsKLSAgICAgICAgc3VwZXIoY29udGV4dCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUHVzaGVzIGEgbmV3IGNvbnRleHQgb250byB0aGUgc3RhY2suCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcHVzaENvbnRleHQoKSB7Ci0gICAgICAgIHN1cGVyLnB1c2hDb250ZXh0KCk7Ci0gICAgICAgIGlmIChmQ3VycmVudENvbnRleHQgKyAxID09IGZWYWxpZENvbnRleHQubGVuZ3RoKSB7Ci0gICAgICAgICAgICBib29sZWFuW10gY29udGV4dGFycmF5ID0gbmV3IGJvb2xlYW5bZlZhbGlkQ29udGV4dC5sZW5ndGggKiAyXTsKLSAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZlZhbGlkQ29udGV4dCwgMCwgY29udGV4dGFycmF5LCAwLCBmVmFsaWRDb250ZXh0Lmxlbmd0aCk7Ci0gICAgICAgICAgICBmVmFsaWRDb250ZXh0ID0gY29udGV4dGFycmF5OwotICAgICAgICB9Ci0KLSAgICAgICAgZlZhbGlkQ29udGV4dFtmQ3VycmVudENvbnRleHRdID0gdHJ1ZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBpcyB1c2VkIHRvIHNldCBhIGNvbnRleHQgaW52YWxpZCBmb3IgWEluY2x1ZGUgbmFtZXNwYWNlIHByb2Nlc3NpbmcuCi0gICAgICogQW55IGNvbnRleHQgZGVmaW5lZCBieSBhbiAmbHQ7aW5jbHVkZSZndDsgb3IgJmx0O2ZhbGxiYWNrJmd0OyBlbGVtZW50IGlzIG5vdAotICAgICAqIHZhbGlkIGZvciBwcm9jZXNzaW5nIHRoZSBpbmNsdWRlIHBhcmVudCdzIFtpbi1zY29wZSBuYW1lc3BhY2VzXS4gVGh1cywgY29udGV4dHMKLSAgICAgKiBkZWZpbmVkIGJ5IHRoZXNlIGVsZW1lbnRzIGFyZSBzZXQgdG8gaW52YWxpZCBieSB0aGUgWEluY2x1ZGUgcHJvY2Vzc29yIHVzaW5nCi0gICAgICogdGhpcyBtZXRob2QuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0Q29udGV4dEludmFsaWQoKSB7Ci0gICAgICAgIGZWYWxpZENvbnRleHRbZkN1cnJlbnRDb250ZXh0XSA9IGZhbHNlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgcmV0dXJucyB0aGUgbmFtZXNwYWNlIFVSSSB3aGljaCB3YXMgYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBwcmV0ZXh0LCBpbgotICAgICAqIHRoZSBjb250ZXh0IHRoYXQgZXhpc3RlZCBhdCB0aGUgaW5jbHVkZSBwYXJlbnQgb2YgdGhlIGN1cnJlbnQgZWxlbWVudC4gIFRoZQotICAgICAqIGluY2x1ZGUgcGFyZW50IGlzIHRoZSBsYXN0IGVsZW1lbnQsIGJlZm9yZSB0aGUgY3VycmVudCBvbmUsIHdoaWNoIHdhcyBub3Qgc2V0Ci0gICAgICogdG8gYW4gaW52YWxpZCBjb250ZXh0IHVzaW5nIHNldENvbnRleHRJbnZhbGlkKCkKLSAgICAgKgotICAgICAqIEBwYXJhbSBwcmVmaXggdGhlIHByZWZpeCBvZiB0aGUgZGVzaXJlZCBVUkkKLSAgICAgKiBAcmV0dXJuIHRoZSBVUkkgY29ycmVzcG9uZGluZyB0byB0aGUgcHJlZml4IGluIHRoZSBjb250ZXh0IG9mIHRoZSBpbmNsdWRlIHBhcmVudAotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VVJJRnJvbUluY2x1ZGVQYXJlbnQoU3RyaW5nIHByZWZpeCkgewotICAgICAgICBpbnQgbGFzdFZhbGlkQ29udGV4dCA9IGZDdXJyZW50Q29udGV4dCAtIDE7Ci0gICAgICAgIHdoaWxlIChsYXN0VmFsaWRDb250ZXh0ID4gMCAmJiAhZlZhbGlkQ29udGV4dFtsYXN0VmFsaWRDb250ZXh0XSkgewotICAgICAgICAgICAgbGFzdFZhbGlkQ29udGV4dC0tOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBnZXRVUkkocHJlZml4LCBsYXN0VmFsaWRDb250ZXh0KTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94aW5jbHVkZS9YSW5jbHVkZVRleHRSZWFkZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3hpbmNsdWRlL1hJbmNsdWRlVGV4dFJlYWRlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmNjY3M2I1Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3hpbmNsdWRlL1hJbmNsdWRlVGV4dFJlYWRlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTE2ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDMtMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueGluY2x1ZGU7Ci0KLWltcG9ydCBqYXZhLmlvLkJ1ZmZlcmVkSW5wdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW1SZWFkZXI7Ci1pbXBvcnQgamF2YS5pby5SZWFkZXI7Ci1pbXBvcnQgamF2YS5uZXQuSHR0cFVSTENvbm5lY3Rpb247Ci1pbXBvcnQgamF2YS5uZXQuVVJMOwotaW1wb3J0IGphdmEubmV0LlVSTENvbm5lY3Rpb247Ci1pbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOwotaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7Ci1pbXBvcnQgamF2YS51dGlsLk1hcDsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5YTUxFbnRpdHlNYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5YTUxFcnJvclJlcG9ydGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5pby5BU0NJSVJlYWRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuaW8uVVRGOFJlYWRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwubXNnLlhNTE1lc3NhZ2VGb3JtYXR0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLkVuY29kaW5nTWFwOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5IVFRQSW5wdXRTb3VyY2U7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLk1lc3NhZ2VGb3JtYXR0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlhNTENoYXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MU3RyaW5nOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxJbnB1dFNvdXJjZTsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGlzIHVzZWQgZm9yIHJlYWRpbmcgcmVzb3VyY2VzIHJlcXVlc3RlZCBpbiAmbHQ7aW5jbHVkZSZndDsgZWxlbWVudHMsCi0gKiB3aGVuIHRoZSBwYXJzZSBhdHRyaWJ1dGUgb2YgdGhlICZsdDtpbmNsdWRlJmd0OyBlbGVtZW50IGlzICJ0ZXh0Ii4gIFVzaW5nIHRoaXMKLSAqIGNsYXNzIHdpbGwgb3BlbiB0aGUgbG9jYXRpb24sIGRldGVjdCB0aGUgZW5jb2RpbmcsIGFuZCBkaXNjYXJkIHRoZSBieXRlIG9yZGVyCi0gKiBtYXJrLCBpZiBhcHBsaWNhYmxlLgotICoKLSAqIFJFVklTSVQ6Ci0gKiBNdWNoIG9mIHRoZSBjb2RlIGluIHRoaXMgY2xhc3MgaXMgdGFrZW4gZnJvbSBYTUxFbnRpdHlNYW5hZ2VyLiAgSXQgd291bGQgYmUgbmljZQotICogaWYgdGhpcyBjb2RlIGNvdWxkIGJlIHNoYXJlZCBpbiBzb21lIHdheS4gIEhvd2V2ZXIsIHNpbmNlIFhNTEVudGl0eU1hbmFnZXIgaXMgdXNlZAotICogZm9yIHJlYWRpbmcgZmlsZXMgYXMgWE1MLCBhbmQgdGhpcyBuZWVkcyB0byByZWFkIGZpbGVzIGFzIHRleHQsIHRoZXJlIHdvdWxkIG5lZWQKLSAqIHRvIGJlIHNvbWUgcmVmYWN0b3JpbmcgZG9uZS4KLSAqCi0gKiBAYXV0aG9yIE1pY2hhZWwgR2xhdmFzc2V2aWNoLCBJQk0KLSAqIEBhdXRob3IgUGV0ZXIgTWNDcmFja2VuLCBJQk0KLSAqIEBhdXRob3IgQW5raXQgUGFzcmljaGEsIElCTQotICogQGF1dGhvciBBcnVuIFlhZGF2LCBTdW4gTWljcm9zeXN0ZW1zIEluYy4KLSAqCi0gKgotICogQHNlZSBYSW5jbHVkZUhhbmRsZXIKLSAqLwotcHVibGljIGNsYXNzIFhJbmNsdWRlVGV4dFJlYWRlciB7Ci0KLSAgICBwcml2YXRlIFJlYWRlciBmUmVhZGVyOwotICAgIHByaXZhdGUgWEluY2x1ZGVIYW5kbGVyIGZIYW5kbGVyOwotICAgIHByaXZhdGUgWE1MSW5wdXRTb3VyY2UgZlNvdXJjZTsKLSAgICBwcml2YXRlIFhNTEVycm9yUmVwb3J0ZXIgZkVycm9yUmVwb3J0ZXI7Ci0gICAgcHJpdmF0ZSBYTUxTdHJpbmcgZlRlbXBTdHJpbmcgPSBuZXcgWE1MU3RyaW5nKCk7Ci0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3QgdGhlIFhJbmNsdWRlUmVhZGVyIHVzaW5nIHRoZSBYTUxJbnB1dFNvdXJjZSBhbmQgWEluY2x1ZGVIYW5kbGVyLgotICAgICAqCi0gICAgICogQHBhcmFtIHNvdXJjZSBUaGUgWE1MSW5wdXRTb3VyY2UgdG8gdXNlLgotICAgICAqIEBwYXJhbSBoYW5kbGVyIFRoZSBYSW5jbHVkZUhhbmRsZXIgdG8gdXNlLgotICAgICAqIEBwYXJhbSBidWZmZXJTaXplIFRoZSBzaXplIG9mIHRoaXMgdGV4dCByZWFkZXIncyBidWZmZXIuCi0gICAgICovCi0gICAgcHVibGljIFhJbmNsdWRlVGV4dFJlYWRlcihYTUxJbnB1dFNvdXJjZSBzb3VyY2UsIFhJbmNsdWRlSGFuZGxlciBoYW5kbGVyLCBpbnQgYnVmZmVyU2l6ZSkKLSAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKLSAgICAgICAgZkhhbmRsZXIgPSBoYW5kbGVyOwotICAgICAgICBmU291cmNlID0gc291cmNlOwotICAgICAgICBmVGVtcFN0cmluZyA9IG5ldyBYTUxTdHJpbmcobmV3IGNoYXJbYnVmZmVyU2l6ZSArIDFdLCAwLCAwKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSBYTUxFcnJvclJlcG9ydGVyIHVzZWQgZm9yIHJlcG9ydGluZyBlcnJvcnMgd2hpbGUKLSAgICAgKiByZWFkaW5nIHRoZSB0ZXh0IGluY2x1ZGUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZXJyb3JSZXBvcnRlciB0aGUgWE1MRXJyb3JSZXBvcnRlciB0byBiZSB1c2VkIGZvcgotICAgICAqIHJlcG9ydGluZyBlcnJvcnMuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RXJyb3JSZXBvcnRlcihYTUxFcnJvclJlcG9ydGVyIGVycm9yUmVwb3J0ZXIpIHsKLSAgICAgICAgZkVycm9yUmVwb3J0ZXIgPSBlcnJvclJlcG9ydGVyOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybiB0aGUgUmVhZGVyIGZvciBnaXZlbiBYTUxJbnB1dFNvdXJjZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzb3VyY2UgVGhlIFhNTElucHV0U291cmNlIHRvIHVzZS4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgUmVhZGVyIGdldFJlYWRlcihYTUxJbnB1dFNvdXJjZSBzb3VyY2UpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChzb3VyY2UuZ2V0Q2hhcmFjdGVyU3RyZWFtKCkgIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIHNvdXJjZS5nZXRDaGFyYWN0ZXJTdHJlYW0oKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIElucHV0U3RyZWFtIHN0cmVhbSA9IG51bGw7Ci0KLSAgICAgICAgICAgIFN0cmluZyBlbmNvZGluZyA9IHNvdXJjZS5nZXRFbmNvZGluZygpOwotICAgICAgICAgICAgaWYgKGVuY29kaW5nID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBlbmNvZGluZyA9ICJVVEYtOCI7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoc291cmNlLmdldEJ5dGVTdHJlYW0oKSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgc3RyZWFtID0gc291cmNlLmdldEJ5dGVTdHJlYW0oKTsKLSAgICAgICAgICAgICAgICAvLyBXcmFwIHRoZSBJbnB1dFN0cmVhbSBzbyB0aGF0IGl0IGlzIHBvc3NpYmxlIHRvIHJld2luZCBpdC4KLSAgICAgICAgICAgICAgICBpZiAoIShzdHJlYW0gaW5zdGFuY2VvZiBCdWZmZXJlZElucHV0U3RyZWFtKSkgewotICAgICAgICAgICAgICAgICAgICBzdHJlYW0gPSBuZXcgQnVmZmVyZWRJbnB1dFN0cmVhbShzdHJlYW0sIGZUZW1wU3RyaW5nLmNoLmxlbmd0aCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIGV4cGFuZGVkU3lzdGVtSWQgPSBYTUxFbnRpdHlNYW5hZ2VyLmV4cGFuZFN5c3RlbUlkKHNvdXJjZS5nZXRTeXN0ZW1JZCgpLCBzb3VyY2UuZ2V0QmFzZVN5c3RlbUlkKCksIGZhbHNlKTsKLQotICAgICAgICAgICAgICAgIFVSTCB1cmwgPSBuZXcgVVJMKGV4cGFuZGVkU3lzdGVtSWQpOwotICAgICAgICAgICAgICAgIFVSTENvbm5lY3Rpb24gdXJsQ29uID0gdXJsLm9wZW5Db25uZWN0aW9uKCk7Ci0KLSAgICAgICAgICAgICAgICAvLyBJZiB0aGlzIGlzIGFuIEhUVFAgY29ubmVjdGlvbiBhdHRhY2ggYW55IHJlcXVlc3QgcHJvcGVydGllcyB0byB0aGUgcmVxdWVzdC4KLSAgICAgICAgICAgICAgICBpZiAodXJsQ29uIGluc3RhbmNlb2YgSHR0cFVSTENvbm5lY3Rpb24gJiYgc291cmNlIGluc3RhbmNlb2YgSFRUUElucHV0U291cmNlKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZpbmFsIEh0dHBVUkxDb25uZWN0aW9uIHVybENvbm5lY3Rpb24gPSAoSHR0cFVSTENvbm5lY3Rpb24pIHVybENvbjsKLSAgICAgICAgICAgICAgICAgICAgZmluYWwgSFRUUElucHV0U291cmNlIGh0dHBJbnB1dFNvdXJjZSA9IChIVFRQSW5wdXRTb3VyY2UpIHNvdXJjZTsKLQotICAgICAgICAgICAgICAgICAgICAvLyBzZXQgcmVxdWVzdCBwcm9wZXJ0aWVzCi0gICAgICAgICAgICAgICAgICAgIEl0ZXJhdG9yIHByb3BJdGVyID0gaHR0cElucHV0U291cmNlLmdldEhUVFBSZXF1ZXN0UHJvcGVydGllcygpOwotICAgICAgICAgICAgICAgICAgICB3aGlsZSAocHJvcEl0ZXIuaGFzTmV4dCgpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBNYXAuRW50cnkgZW50cnkgPSAoTWFwLkVudHJ5KSBwcm9wSXRlci5uZXh0KCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB1cmxDb25uZWN0aW9uLnNldFJlcXVlc3RQcm9wZXJ0eSgoU3RyaW5nKSBlbnRyeS5nZXRLZXkoKSwgKFN0cmluZykgZW50cnkuZ2V0VmFsdWUoKSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAvLyBzZXQgcHJlZmVyZW5jZSBmb3IgcmVkaXJlY3Rpb24KLSAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBmb2xsb3dSZWRpcmVjdHMgPSBodHRwSW5wdXRTb3VyY2UuZ2V0Rm9sbG93SFRUUFJlZGlyZWN0cygpOwotICAgICAgICAgICAgICAgICAgICBpZiAoIWZvbGxvd1JlZGlyZWN0cykgewotICAgICAgICAgICAgICAgICAgICAgICAgWE1MRW50aXR5TWFuYWdlci5zZXRJbnN0YW5jZUZvbGxvd1JlZGlyZWN0cyh1cmxDb25uZWN0aW9uLCBmb2xsb3dSZWRpcmVjdHMpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgLy8gV3JhcCB0aGUgSW5wdXRTdHJlYW0gc28gdGhhdCBpdCBpcyBwb3NzaWJsZSB0byByZXdpbmQgaXQuCi0gICAgICAgICAgICAgICAgc3RyZWFtID0gbmV3IEJ1ZmZlcmVkSW5wdXRTdHJlYW0odXJsQ29uLmdldElucHV0U3RyZWFtKCkpOwotCi0gICAgICAgICAgICAgICAgLy8gY29udGVudCB0eXBlIHdpbGwgYmUgc3RyaW5nIGxpa2UgInRleHQveG1sOyBjaGFyc2V0PVVURi04IiBvciAidGV4dC94bWwiCi0gICAgICAgICAgICAgICAgU3RyaW5nIHJhd0NvbnRlbnRUeXBlID0gdXJsQ29uLmdldENvbnRlbnRUeXBlKCk7Ci0KLSAgICAgICAgICAgICAgICAvLyB0ZXh0L3htbCBhbmQgYXBwbGljYXRpb24veG1sIG9mZmVyIG9ubHkgb25lIG9wdGlvbmFsIHBhcmFtZXRlcgotICAgICAgICAgICAgICAgIGludCBpbmRleCA9IChyYXdDb250ZW50VHlwZSAhPSBudWxsKSA/IHJhd0NvbnRlbnRUeXBlLmluZGV4T2YoJzsnKSA6IC0xOwotCi0gICAgICAgICAgICAgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gbnVsbDsKLSAgICAgICAgICAgICAgICBTdHJpbmcgY2hhcnNldCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgaWYgKGluZGV4ICE9IC0xKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIHRoaXMgc2hvdWxkIGJlIHNvbWV0aGluZyBsaWtlICJ0ZXh0L3htbCIKLSAgICAgICAgICAgICAgICAgICAgY29udGVudFR5cGUgPSByYXdDb250ZW50VHlwZS5zdWJzdHJpbmcoMCwgaW5kZXgpLnRyaW0oKTsKLQotICAgICAgICAgICAgICAgICAgICAvLyB0aGlzIHNob3VsZCBiZSBzb21ldGhpbmcgbGlrZSAiY2hhcnNldD1VVEYtOCIsIGJ1dCB3ZSB3YW50IHRvCi0gICAgICAgICAgICAgICAgICAgIC8vIHN0cmlwIGl0IGRvd24gdG8ganVzdCAiVVRGLTgiCi0gICAgICAgICAgICAgICAgICAgIGNoYXJzZXQgPSByYXdDb250ZW50VHlwZS5zdWJzdHJpbmcoaW5kZXggKyAxKS50cmltKCk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChjaGFyc2V0LnN0YXJ0c1dpdGgoImNoYXJzZXQ9IikpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIDggaXMgdGhlIGxlbmd0aCBvZiAiY2hhcnNldD0iCi0gICAgICAgICAgICAgICAgICAgICAgICBjaGFyc2V0ID0gY2hhcnNldC5zdWJzdHJpbmcoOCkudHJpbSgpOwotICAgICAgICAgICAgICAgICAgICAgICAgLy8gc3RyaXAgcXVvdGVzLCBpZiBwcmVzZW50Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoKGNoYXJzZXQuY2hhckF0KDApID09ICciJwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmIGNoYXJzZXQuY2hhckF0KGNoYXJzZXQubGVuZ3RoKCkgLSAxKSA9PSAnIicpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgKGNoYXJzZXQuY2hhckF0KDApID09ICdcJycKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgY2hhcnNldC5jaGFyQXQoY2hhcnNldC5sZW5ndGgoKSAtIDEpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9PSAnXCcnKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYXJzZXQgPQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFyc2V0LnN1YnN0cmluZygxLCBjaGFyc2V0Lmxlbmd0aCgpIC0gMSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBjaGFyc2V0ID0gbnVsbDsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgY29udGVudFR5cGUgPSByYXdDb250ZW50VHlwZS50cmltKCk7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgU3RyaW5nIGRldGVjdGVkRW5jb2RpbmcgPSBudWxsOwotICAgICAgICAgICAgICAgIC8qKiAgVGhlIGVuY29kaW5nIG9mIHN1Y2ggYSByZXNvdXJjZSBpcyBkZXRlcm1pbmVkIGJ5OgotICAgICAgICAgICAgICAgICAgICAxIGV4dGVybmFsIGVuY29kaW5nIGluZm9ybWF0aW9uLCBpZiBhdmFpbGFibGUsIG90aGVyd2lzZQotICAgICAgICAgICAgICAgICAgICAgICAgIC0tIHRoZSBtb3N0IGNvbW1vbiB0eXBlIG9mIGV4dGVybmFsIGluZm9ybWF0aW9uIGlzIHRoZSAiY2hhcnNldCIgcGFyYW1ldGVyIG9mIGEgTUlNRSBwYWNrYWdlCi0gICAgICAgICAgICAgICAgICAgIDIgaWYgdGhlIG1lZGlhIHR5cGUgb2YgdGhlIHJlc291cmNlIGlzIHRleHQveG1sLCBhcHBsaWNhdGlvbi94bWwsIG9yIG1hdGNoZXMgdGhlIGNvbnZlbnRpb25zIHRleHQvKit4bWwgb3IgYXBwbGljYXRpb24vKit4bWwgYXMgZGVzY3JpYmVkIGluIFhNTCBNZWRpYSBUeXBlcyBbSUVURiBSRkMgMzAyM10sIHRoZSBlbmNvZGluZyBpcyByZWNvZ25pemVkIGFzIHNwZWNpZmllZCBpbiBYTUwgMS4wLCBvdGhlcndpc2UKLSAgICAgICAgICAgICAgICAgICAgMyB0aGUgdmFsdWUgb2YgdGhlIGVuY29kaW5nIGF0dHJpYnV0ZSBpZiBvbmUgZXhpc3RzLCBvdGhlcndpc2UKLSAgICAgICAgICAgICAgICAgICAgNCBVVEYtOC4KLSAgICAgICAgICAgICAgICAgKiovCi0gICAgICAgICAgICAgICAgaWYgKGNvbnRlbnRUeXBlLmVxdWFscygidGV4dC94bWwiKSkgewotICAgICAgICAgICAgICAgICAgICBpZiAoY2hhcnNldCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBkZXRlY3RlZEVuY29kaW5nID0gY2hhcnNldDsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNlZSBSRkMyMzc2IG9yIDMwMjMsIHNlY3Rpb24gMy4xCi0gICAgICAgICAgICAgICAgICAgICAgICBkZXRlY3RlZEVuY29kaW5nID0gIlVTLUFTQ0lJIjsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIGlmIChjb250ZW50VHlwZS5lcXVhbHMoImFwcGxpY2F0aW9uL3htbCIpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChjaGFyc2V0ICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGRldGVjdGVkRW5jb2RpbmcgPSBjaGFyc2V0OwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2VlIFJGQzIzNzYgb3IgMzAyMywgc2VjdGlvbiAzLjIKLSAgICAgICAgICAgICAgICAgICAgICAgIGRldGVjdGVkRW5jb2RpbmcgPSBnZXRFbmNvZGluZ05hbWUoc3RyZWFtKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIGlmIChjb250ZW50VHlwZS5lbmRzV2l0aCgiK3htbCIpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGRldGVjdGVkRW5jb2RpbmcgPSBnZXRFbmNvZGluZ05hbWUoc3RyZWFtKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBpZiAoZGV0ZWN0ZWRFbmNvZGluZyAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGVuY29kaW5nID0gZGV0ZWN0ZWRFbmNvZGluZzsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLy8gZWxzZSAzIG9yIDQuCi0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGVuY29kaW5nID0gZW5jb2RpbmcudG9VcHBlckNhc2UoTG9jYWxlLkVOR0xJU0gpOwotCi0gICAgICAgICAgICAvLyBlYXQgdGhlIEJ5dGUgT3JkZXIgTWFyawotICAgICAgICAgICAgZW5jb2RpbmcgPSBjb25zdW1lQk9NKHN0cmVhbSwgZW5jb2RpbmcpOwotCi0gICAgICAgICAgICAvLyBJZiB0aGUgZG9jdW1lbnQgaXMgVVRGLTggb3IgVVMtQVNDSUkgdXNlCi0gICAgICAgICAgICAvLyB0aGUgWGVyY2VzIHJlYWRlcnMgZm9yIHRoZXNlIGVuY29kaW5ncy4gRm9yCi0gICAgICAgICAgICAvLyBVUy1BU0NJSSBjb25zdWx0IHRoZSBlbmNvZGluZyBtYXAgc2luY2UKLSAgICAgICAgICAgIC8vIHRoaXMgZW5jb2RpbmcgaGFzIG1hbnkgYWxpYXNlcy4KLSAgICAgICAgICAgIGlmIChlbmNvZGluZy5lcXVhbHMoIlVURi04IikpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFVURjhSZWFkZXIoc3RyZWFtLAotICAgICAgICAgICAgICAgICAgICBmVGVtcFN0cmluZy5jaC5sZW5ndGgsCi0gICAgICAgICAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLmdldE1lc3NhZ2VGb3JtYXR0ZXIoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOKSwKLSAgICAgICAgICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIuZ2V0TG9jYWxlKCkgKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gVHJ5IHRvIHVzZSBhIEphdmEgcmVhZGVyLgotICAgICAgICAgICAgU3RyaW5nIGphdmFFbmNvZGluZyA9IEVuY29kaW5nTWFwLmdldElBTkEySmF2YU1hcHBpbmcoZW5jb2RpbmcpOwotCi0gICAgICAgICAgICAvLyBJZiB0aGUgc3BlY2lmaWVkIGVuY29kaW5nIHdhc24ndCBhIHJlY29nbml6ZWQgSUFOQSBlbmNvZGluZyB0aHJvdyBhbiBJT0V4Y2VwdGlvbi4KLSAgICAgICAgICAgIC8vIFRoZSBYSW5jbHVkZUhhbmRsZXIgd2lsbCByZXBvcnQgdGhpcyBhcyBhIFJlc291cmNlRXJyb3IgYW5kIHRoZW4gd2lsbAotICAgICAgICAgICAgLy8gYXR0ZW1wdCB0byBpbmNsdWRlIGEgZmFsbGJhY2sgaWYgdGhlcmUgaXMgb25lLgotICAgICAgICAgICAgaWYgKGphdmFFbmNvZGluZyA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgTWVzc2FnZUZvcm1hdHRlciBhRm9ybWF0dGVyID0KLSAgICAgICAgICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIuZ2V0TWVzc2FnZUZvcm1hdHRlcihYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4pOwotICAgICAgICAgICAgICAgIExvY2FsZSBhTG9jYWxlID0gZkVycm9yUmVwb3J0ZXIuZ2V0TG9jYWxlKCk7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCBhRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoIGFMb2NhbGUsCi0gICAgICAgICAgICAgICAgICAgICJFbmNvZGluZ0RlY2xJbnZhbGlkIiwKLSAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHtlbmNvZGluZ30gKSApOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoamF2YUVuY29kaW5nLmVxdWFscygiQVNDSUkiKSkgewotICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQVNDSUlSZWFkZXIoc3RyZWFtLAotICAgICAgICAgICAgICAgICAgICBmVGVtcFN0cmluZy5jaC5sZW5ndGgsCi0gICAgICAgICAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLmdldE1lc3NhZ2VGb3JtYXR0ZXIoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOKSwKLSAgICAgICAgICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIuZ2V0TG9jYWxlKCkgKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgcmV0dXJuIG5ldyBJbnB1dFN0cmVhbVJlYWRlcihzdHJlYW0sIGphdmFFbmNvZGluZyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBYTUxFbnRpdHlNYW5hZ2VyIGNhcmVzIGFib3V0IGVuZGlhbi1uZXNzLCBzaW5jZSBpdCBjcmVhdGVzIGl0cyBvd24gb3B0aW1pemVkCi0gICAgICogcmVhZGVycy4gU2luY2Ugd2UncmUganVzdCB1c2luZyBnZW5lcmljIEphdmEgcmVhZGVycyBmb3Igbm93LCB3ZSdyZSBub3QgY2FyaW5nCi0gICAgICogYWJvdXQgZW5kaWFuLW5lc3MuICBJZiB0aGlzIGNoYW5nZXMsIGV2ZW4gbW9yZSBjb2RlIG5lZWRzIHRvIGJlIGNvcGllZCBmcm9tCi0gICAgICogWE1MRW50aXR5IG1hbmFnZXIuIC0tIFBKTQotICAgICAqLwotICAgIHByb3RlY3RlZCBTdHJpbmcgZ2V0RW5jb2RpbmdOYW1lKElucHV0U3RyZWFtIHN0cmVhbSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLSAgICAgICAgZmluYWwgYnl0ZVtdIGI0ID0gbmV3IGJ5dGVbNF07Ci0gICAgICAgIFN0cmluZyBlbmNvZGluZyA9IG51bGw7Ci0KLSAgICAgICAgLy8gdGhpcyBoYXMgdGhlIHBvdGVudGlhbCB0byB0aHJvdyBhbiBleGNlcHRpb24KLSAgICAgICAgLy8gaXQgd2lsbCBiZSBmaXhlZCB3aGVuIHdlIGVuc3VyZSB0aGUgc3RyZWFtIGlzIHJld2luZGFibGUgKHNlZSBub3RlIGFib3ZlKQotICAgICAgICBzdHJlYW0ubWFyayg0KTsKLSAgICAgICAgaW50IGNvdW50ID0gc3RyZWFtLnJlYWQoYjQsIDAsIDQpOwotICAgICAgICBzdHJlYW0ucmVzZXQoKTsKLSAgICAgICAgaWYgKGNvdW50ID09IDQpIHsKLSAgICAgICAgICAgIGVuY29kaW5nID0gZ2V0RW5jb2RpbmdOYW1lKGI0KTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBlbmNvZGluZzsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZW1vdmVzIHRoZSBieXRlIG9yZGVyIG1hcmsgZnJvbSB0aGUgc3RyZWFtLCBpZgotICAgICAqIGl0IGV4aXN0cyBhbmQgcmV0dXJucyB0aGUgZW5jb2RpbmcgbmFtZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzdHJlYW0KLSAgICAgKiBAcGFyYW0gZW5jb2RpbmcKLSAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0gICAgICovCi0gICAgcHJvdGVjdGVkIFN0cmluZyBjb25zdW1lQk9NKElucHV0U3RyZWFtIHN0cmVhbSwgU3RyaW5nIGVuY29kaW5nKQotICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24gewotCi0gICAgICAgIGJ5dGVbXSBiID0gbmV3IGJ5dGVbM107Ci0gICAgICAgIGludCBjb3VudCA9IDA7Ci0gICAgICAgIHN0cmVhbS5tYXJrKDMpOwotICAgICAgICBpZiAoZW5jb2RpbmcuZXF1YWxzKCJVVEYtOCIpKSB7Ci0gICAgICAgICAgICBjb3VudCA9IHN0cmVhbS5yZWFkKGIsIDAsIDMpOwotICAgICAgICAgICAgaWYgKGNvdW50ID09IDMpIHsKLSAgICAgICAgICAgICAgICBmaW5hbCBpbnQgYjAgPSBiWzBdICYgMHhGRjsKLSAgICAgICAgICAgICAgICBmaW5hbCBpbnQgYjEgPSBiWzFdICYgMHhGRjsKLSAgICAgICAgICAgICAgICBmaW5hbCBpbnQgYjIgPSBiWzJdICYgMHhGRjsKLSAgICAgICAgICAgICAgICBpZiAoYjAgIT0gMHhFRiB8fCBiMSAhPSAweEJCIHx8IGIyICE9IDB4QkYpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gRmlyc3QgdGhyZWUgYnl0ZXMgYXJlIG5vdCBCT00sIHNvIHJlc2V0LgotICAgICAgICAgICAgICAgICAgICBzdHJlYW0ucmVzZXQoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBzdHJlYW0ucmVzZXQoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChlbmNvZGluZy5zdGFydHNXaXRoKCJVVEYtMTYiKSkgewotICAgICAgICAgICAgY291bnQgPSBzdHJlYW0ucmVhZChiLCAwLCAyKTsKLSAgICAgICAgICAgIGlmIChjb3VudCA9PSAyKSB7Ci0gICAgICAgICAgICAgICAgZmluYWwgaW50IGIwID0gYlswXSAmIDB4RkY7Ci0gICAgICAgICAgICAgICAgZmluYWwgaW50IGIxID0gYlsxXSAmIDB4RkY7Ci0gICAgICAgICAgICAgICAgaWYgKGIwID09IDB4RkUgJiYgYjEgPT0gMHhGRikgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gIlVURi0xNkJFIjsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSBpZiAoYjAgPT0gMHhGRiAmJiBiMSA9PSAweEZFKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiAiVVRGLTE2TEUiOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIEZpcnN0IHR3byBieXRlcyBhcmUgbm90IEJPTSwgc28gcmVzZXQuCi0gICAgICAgICAgICBzdHJlYW0ucmVzZXQoKTsKLSAgICAgICAgfQotICAgICAgICAvLyBXZSBjb3VsZCBkbyBVVEYtMzIsIGJ1dCBzaW5jZSB0aGUgZ2V0RW5jb2RpbmdOYW1lKCkgZG9lc24ndCBzdXBwb3J0IHRoYXQKLSAgICAgICAgLy8gd2Ugd29uJ3Qgc3VwcG9ydCBpdCBoZXJlLgotICAgICAgICAvLyBUbyBpbXBsZW1lbnQgVVRGLTMyLCBsb29rIGZvcjogIDAwIDAwIEZFIEZGIGZvciBiaWctZW5kaWFuCi0gICAgICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvciAgRkYgRkUgMDAgMDAgZm9yIGxpdHRsZS1lbmRpYW4KLSAgICAgICAgcmV0dXJuIGVuY29kaW5nOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJFVklTSVQ6IFRoaXMgY29kZSBpcyB0YWtlbiBmcm9tIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5YTUxFbnRpdHlNYW5hZ2VyLgotICAgICAqICAgICAgICAgIElzIHRoZXJlIGFueSB3YXkgd2UgY2FuIHNoYXJlIHRoZSBjb2RlLCB3aXRob3V0IGhhdmluZyBpdCBpbXBsZW1lbnRlZCB0d2ljZT8KLSAgICAgKiAgICAgICAgICBJIHRoaW5rIHdlIHNob3VsZCBtYWtlIGl0IHB1YmxpYyBhbmQgc3RhdGljIGluIFhNTEVudGl0eU1hbmFnZXIuIC0tUEpNCi0gICAgICoKLSAgICAgKiBSZXR1cm5zIHRoZSBJQU5BIGVuY29kaW5nIG5hbWUgdGhhdCBpcyBhdXRvLWRldGVjdGVkIGZyb20KLSAgICAgKiB0aGUgYnl0ZXMgc3BlY2lmaWVkLCB3aXRoIHRoZSBlbmRpYW4tbmVzcyBvZiB0aGF0IGVuY29kaW5nIHdoZXJlIGFwcHJvcHJpYXRlLgotICAgICAqCi0gICAgICogQHBhcmFtIGI0ICAgIFRoZSBmaXJzdCBmb3VyIGJ5dGVzIG9mIHRoZSBpbnB1dC4KLSAgICAgKiBAcmV0dXJuIHRoZSBlbmNvZGluZyBuYW1lLCBvciBudWxsIGlmIG5vIGVuY29kaW5nIGNvdWxkIGJlIGRldGVjdGVkCi0gICAgICovCi0gICAgcHJvdGVjdGVkIFN0cmluZyBnZXRFbmNvZGluZ05hbWUoYnl0ZVtdIGI0KSB7Ci0KLSAgICAgICAgLy8gVVRGLTE2LCB3aXRoIEJPTQotICAgICAgICBpbnQgYjAgPSBiNFswXSAmIDB4RkY7Ci0gICAgICAgIGludCBiMSA9IGI0WzFdICYgMHhGRjsKLSAgICAgICAgaWYgKGIwID09IDB4RkUgJiYgYjEgPT0gMHhGRikgewotICAgICAgICAgICAgLy8gVVRGLTE2LCBiaWctZW5kaWFuCi0gICAgICAgICAgICByZXR1cm4gIlVURi0xNkJFIjsKLSAgICAgICAgfQotICAgICAgICBpZiAoYjAgPT0gMHhGRiAmJiBiMSA9PSAweEZFKSB7Ci0gICAgICAgICAgICAvLyBVVEYtMTYsIGxpdHRsZS1lbmRpYW4KLSAgICAgICAgICAgIHJldHVybiAiVVRGLTE2TEUiOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gVVRGLTggd2l0aCBhIEJPTQotICAgICAgICBpbnQgYjIgPSBiNFsyXSAmIDB4RkY7Ci0gICAgICAgIGlmIChiMCA9PSAweEVGICYmIGIxID09IDB4QkIgJiYgYjIgPT0gMHhCRikgewotICAgICAgICAgICAgcmV0dXJuICJVVEYtOCI7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBvdGhlciBlbmNvZGluZ3MKLSAgICAgICAgaW50IGIzID0gYjRbM10gJiAweEZGOwotICAgICAgICBpZiAoYjAgPT0gMHgwMCAmJiBiMSA9PSAweDAwICYmIGIyID09IDB4MDAgJiYgYjMgPT0gMHgzQykgewotICAgICAgICAgICAgLy8gVUNTLTQsIGJpZyBlbmRpYW4gKDEyMzQpCi0gICAgICAgICAgICByZXR1cm4gIklTTy0xMDY0Ni1VQ1MtNCI7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGIwID09IDB4M0MgJiYgYjEgPT0gMHgwMCAmJiBiMiA9PSAweDAwICYmIGIzID09IDB4MDApIHsKLSAgICAgICAgICAgIC8vIFVDUy00LCBsaXR0bGUgZW5kaWFuICg0MzIxKQotICAgICAgICAgICAgcmV0dXJuICJJU08tMTA2NDYtVUNTLTQiOwotICAgICAgICB9Ci0gICAgICAgIGlmIChiMCA9PSAweDAwICYmIGIxID09IDB4MDAgJiYgYjIgPT0gMHgzQyAmJiBiMyA9PSAweDAwKSB7Ci0gICAgICAgICAgICAvLyBVQ1MtNCwgdW51c3VhbCBvY3RldCBvcmRlciAoMjE0MykKLSAgICAgICAgICAgIHJldHVybiAiSVNPLTEwNjQ2LVVDUy00IjsKLSAgICAgICAgfQotICAgICAgICBpZiAoYjAgPT0gMHgwMCAmJiBiMSA9PSAweDNDICYmIGIyID09IDB4MDAgJiYgYjMgPT0gMHgwMCkgewotICAgICAgICAgICAgLy8gVUNTLTQsIHVudXN1YWwgb2N0ZWN0IG9yZGVyICgzNDEyKQotICAgICAgICAgICAgcmV0dXJuICJJU08tMTA2NDYtVUNTLTQiOwotICAgICAgICB9Ci0gICAgICAgIGlmIChiMCA9PSAweDAwICYmIGIxID09IDB4M0MgJiYgYjIgPT0gMHgwMCAmJiBiMyA9PSAweDNGKSB7Ci0gICAgICAgICAgICAvLyBVVEYtMTYsIGJpZy1lbmRpYW4sIG5vIEJPTQotICAgICAgICAgICAgLy8gKG9yIGNvdWxkIHR1cm4gb3V0IHRvIGJlIFVDUy0yLi4uCi0gICAgICAgICAgICByZXR1cm4gIlVURi0xNkJFIjsKLSAgICAgICAgfQotICAgICAgICBpZiAoYjAgPT0gMHgzQyAmJiBiMSA9PSAweDAwICYmIGIyID09IDB4M0YgJiYgYjMgPT0gMHgwMCkgewotICAgICAgICAgICAgLy8gVVRGLTE2LCBsaXR0bGUtZW5kaWFuLCBubyBCT00KLSAgICAgICAgICAgIC8vIChvciBjb3VsZCB0dXJuIG91dCB0byBiZSBVQ1MtMi4uLgotICAgICAgICAgICAgcmV0dXJuICJVVEYtMTZMRSI7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGIwID09IDB4NEMgJiYgYjEgPT0gMHg2RiAmJiBiMiA9PSAweEE3ICYmIGIzID09IDB4OTQpIHsKLSAgICAgICAgICAgIC8vIEVCQ0RJQwotICAgICAgICAgICAgLy8gYSBsYSB4ZXJjZXMxLCByZXR1cm4gQ1AwMzcgaW5zdGVhZCBvZiBFQkNESUMgaGVyZQotICAgICAgICAgICAgcmV0dXJuICJDUDAzNyI7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyB0aGlzIHNpZ25hbHMgdXMgdG8gdXNlIHRoZSB2YWx1ZSBmcm9tIHRoZSBlbmNvZGluZyBhdHRyaWJ1dGUKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0KLSAgICB9IC8vIGdldEVuY29kaW5nTmFtZShieXRlW10pOk9iamVjdFtdCi0KLSAgICAvKioKLSAgICAgKiBSZWFkIHRoZSBpbnB1dCBzdHJlYW0gYXMgdGV4dCwgYW5kIHBhc3MgdGhlIHRleHQgb24gdG8gdGhlIFhJbmNsdWRlSGFuZGxlcgotICAgICAqIHVzaW5nIGNhbGxzIHRvIGNoYXJhY3RlcnMoKS4gIFRoaXMgd2lsbCByZWFkIGFsbCBvZiB0aGUgdGV4dCBpdCBjYW4gZnJvbSB0aGUKLSAgICAgKiByZXNvdXJjZS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBwYXJzZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0KLSAgICAgICAgZlJlYWRlciA9IGdldFJlYWRlcihmU291cmNlKTsKLSAgICAgICAgZlNvdXJjZSA9IG51bGw7Ci0gICAgICAgIGludCByZWFkU2l6ZSA9IGZSZWFkZXIucmVhZChmVGVtcFN0cmluZy5jaCwgMCwgZlRlbXBTdHJpbmcuY2gubGVuZ3RoIC0gMSk7Ci0gICAgICAgIHdoaWxlIChyZWFkU2l6ZSAhPSAtMSkgewotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZWFkU2l6ZTsgKytpKSB7Ci0gICAgICAgICAgICAgICAgY2hhciBjaCA9IGZUZW1wU3RyaW5nLmNoW2ldOwotICAgICAgICAgICAgICAgIGlmICghaXNWYWxpZChjaCkpIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKFhNTENoYXIuaXNIaWdoU3Vycm9nYXRlKGNoKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgaW50IGNoMjsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIHJldHJpZXZlIG5leHQgY2hhcmFjdGVyCi0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoKytpIDwgcmVhZFNpemUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaDIgPSBmVGVtcFN0cmluZy5jaFtpXTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGhhbmRsZSByYXJlIGJvdW5kYXJ5IGNhc2UKLSAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoMiA9IGZSZWFkZXIucmVhZCgpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjaDIgIT0gLTEpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZlRlbXBTdHJpbmcuY2hbcmVhZFNpemUrK10gPSAoY2hhcikgY2gyOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChYTUxDaGFyLmlzTG93U3Vycm9nYXRlKGNoMikpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjb252ZXJ0IHN1cnJvZ2F0ZXMgdG8gYSBzdXBwbGVtZW50YWwgY2hhcmFjdGVyCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHN1cCA9IFhNTENoYXIuc3VwcGxlbWVudGFsKGNoLCAoY2hhciljaDIpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghaXNWYWxpZChzdXApKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkludmFsaWRDaGFySW5Db250ZW50IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgSW50ZWdlci50b1N0cmluZyhzdXAsIDE2KSB9LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxFcnJvclJlcG9ydGVyLlNFVkVSSVRZX0ZBVEFMX0VSUk9SKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmRXJyb3JSZXBvcnRlci5yZXBvcnRFcnJvcihYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkludmFsaWRDaGFySW5Db250ZW50IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBJbnRlZ2VyLnRvU3RyaW5nKGNoMiwgMTYpIH0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9GQVRBTF9FUlJPUik7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmRXJyb3JSZXBvcnRlci5yZXBvcnRFcnJvcihYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiSW52YWxpZENoYXJJbkNvbnRlbnQiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgSW50ZWdlci50b1N0cmluZyhjaCwgMTYpIH0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxFcnJvclJlcG9ydGVyLlNFVkVSSVRZX0ZBVEFMX0VSUk9SKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChmSGFuZGxlciAhPSBudWxsICYmIHJlYWRTaXplID4gMCkgewotICAgICAgICAgICAgICAgIGZUZW1wU3RyaW5nLm9mZnNldCA9IDA7Ci0gICAgICAgICAgICAgICAgZlRlbXBTdHJpbmcubGVuZ3RoID0gcmVhZFNpemU7Ci0gICAgICAgICAgICAgICAgZkhhbmRsZXIuY2hhcmFjdGVycygKLSAgICAgICAgICAgICAgICAgICAgZlRlbXBTdHJpbmcsCi0gICAgICAgICAgICAgICAgICAgIGZIYW5kbGVyLm1vZGlmeUF1Z21lbnRhdGlvbnMobnVsbCwgdHJ1ZSkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmVhZFNpemUgPSBmUmVhZGVyLnJlYWQoZlRlbXBTdHJpbmcuY2gsIDAsIGZUZW1wU3RyaW5nLmNoLmxlbmd0aCAtIDEpOwotICAgICAgICB9Ci0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSBpbnB1dCBzb3VyY2Ugb24gdGhpcyB0ZXh0IHJlYWRlci4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzb3VyY2UgVGhlIFhNTElucHV0U291cmNlIHRvIHVzZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRJbnB1dFNvdXJjZShYTUxJbnB1dFNvdXJjZSBzb3VyY2UpIHsKLSAgICAgICAgZlNvdXJjZSA9IHNvdXJjZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDbG9zZXMgdGhlIHN0cmVhbS4gIENhbGwgdGhpcyBhZnRlciBwYXJzZSgpLCBvciB3aGVuIHRoZXJlIGlzIG5vIGxvbmdlciBhbnkgbmVlZAotICAgICAqIGZvciB0aGlzIG9iamVjdC4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChmUmVhZGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZSZWFkZXIuY2xvc2UoKTsKLSAgICAgICAgICAgIGZSZWFkZXIgPSBudWxsOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyIGlzIGEgdmFsaWQgWE1MIGNoYXJhY3RlcgotICAgICAqIGFzIHBlciB0aGUgcnVsZXMgb2YgWE1MIDEuMC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjaCBUaGUgY2hhcmFjdGVyIHRvIGNoZWNrLgotICAgICAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIGlzVmFsaWQoaW50IGNoKSB7Ci0gICAgICAgIHJldHVybiBYTUxDaGFyLmlzVmFsaWQoY2gpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIGJ1ZmZlciBzaXplIHByb3BlcnR5IGZvciB0aGUgcmVhZGVyIHdoaWNoIGRlY2lkZXMgdGhlIGNodW5rIHNpemVzIHRoYXQgYXJlIHBhcnNlZAotICAgICAqIGJ5IHRoZSByZWFkZXIgYXQgYSB0aW1lIGFuZCBwYXNzZWQgdG8gdGhlIGhhbmRsZXIKLSAgICAgKgotICAgICAqIEBwYXJhbSBidWZmZXJTaXplIFRoZSBzaXplIG9mIHRoZSBidWZmZXIgZGVzaXJlZAotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIHNldEJ1ZmZlclNpemUoaW50IGJ1ZmZlclNpemUpIHsKLSAgICAgICAgaWYgKGZUZW1wU3RyaW5nLmNoLmxlbmd0aCAhPSArK2J1ZmZlclNpemUpIHsKLSAgICAgICAgICAgIGZUZW1wU3RyaW5nLmNoID0gbmV3IGNoYXJbYnVmZmVyU2l6ZV07Ci0gICAgICAgIH0KLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3hpbmNsdWRlL1hQb2ludGVyRWxlbWVudEhhbmRsZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3hpbmNsdWRlL1hQb2ludGVyRWxlbWVudEhhbmRsZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggY2NjYWZjZi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94aW5jbHVkZS9YUG9pbnRlckVsZW1lbnRIYW5kbGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3NjMgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMS0yMDAzIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGVyY2VzIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBJbnRlcm5hdGlvbmFsCi0gKiBCdXNpbmVzcyBNYWNoaW5lcywgSW5jLiwgaHR0cDovL3d3dy5hcGFjaGUub3JnLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueGluY2x1ZGU7Ci0KLQotaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuU3RyaW5nVG9rZW5pemVyOwotaW1wb3J0IGphdmEudXRpbC5TdGFjazsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5Db25zdGFudHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLlhNTEVycm9yUmVwb3J0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR0ZC5EVERHcmFtbWFyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5QYXJzZXJDb25maWd1cmF0aW9uU2V0dGluZ3M7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuQXVnbWVudGF0aW9uczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5OYW1lc3BhY2VDb250ZXh0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlFOYW1lOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTEF0dHJpYnV0ZXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MRG9jdW1lbnRIYW5kbGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTExvY2F0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MUmVzb3VyY2VJZGVudGlmaWVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTFN0cmluZzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTklFeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuZ3JhbW1hcnMuWE1MR3JhbW1hckRlc2NyaXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLmdyYW1tYXJzLlhNTEdyYW1tYXJQb29sOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxDb21wb25lbnRNYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxEb2N1bWVudFNvdXJjZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MRW50aXR5UmVzb2x2ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR0ZC5YTUxEVERWYWxpZGF0b3I7Ci0vKioKLSAqIEBhdXRob3IgQXJ1biBZYWRhdiwgU3VuIE1pY3Jvc3lzdGVtCi0gKi8KLXB1YmxpYyBjbGFzcyBYUG9pbnRlckVsZW1lbnRIYW5kbGVyIGltcGxlbWVudHMgWFBvaW50ZXJTY2hlbWEgewotCi0KLSAgICAvLyByZWNvZ25pemVkIGZlYXR1cmVzIGFuZCBwcm9wZXJ0aWVzCi0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogZXJyb3IgaGFuZGxlci4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJPUl9SRVBPUlRFUiA9Ci0gICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuRVJST1JfUkVQT1JURVJfUFJPUEVSVFk7Ci0KLSAgICAvKiogUHJvcGVydHkgaWRlbnRpZmllcjogZ3JhbW1hciBwb29sIC4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBHUkFNTUFSX1BPT0wgPQotICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLlhNTEdSQU1NQVJfUE9PTF9QUk9QRVJUWTsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBncmFtbWFyIHBvb2wgLiAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIEVOVElUWV9SRVNPTFZFUiA9Ci0gICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuRU5USVRZX1JFU09MVkVSX1BST1BFUlRZOwotCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgWFBPSU5URVJfU0NIRU1BID0KLSAgICBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5YUE9JTlRFUl9TQ0hFTUFfUFJPUEVSVFk7Ci0KLSAgICAvKiogUmVjb2duaXplZCBmZWF0dXJlcy4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSBSRUNPR05JWkVEX0ZFQVRVUkVTID0gewotICAgIH07Ci0KLSAgICAvKiogRmVhdHVyZSBkZWZhdWx0cy4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBCb29sZWFuW10gRkVBVFVSRV9ERUZBVUxUUyA9IHsKLSAgICB9OwotCi0gICAgLyoqIFJlY29nbml6ZWQgcHJvcGVydGllcy4gKi8KLQotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZ1tdIFJFQ09HTklaRURfUFJPUEVSVElFUyA9Ci0gICAgeyBFUlJPUl9SRVBPUlRFUiwgR1JBTU1BUl9QT09MLCBFTlRJVFlfUkVTT0xWRVIsIFhQT0lOVEVSX1NDSEVNQSB9OwotCi0gICAgLyoqIFByb3BlcnR5IGRlZmF1bHRzLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIE9iamVjdFtdIFBST1BFUlRZX0RFRkFVTFRTID0geyBudWxsLCBudWxsLCBudWxsLG51bGwgfTsKLQotICAgIC8vIERhdGEKLQotICAgIHByb3RlY3RlZCBYTUxEb2N1bWVudEhhbmRsZXIgZkRvY3VtZW50SGFuZGxlcjsKLSAgICBwcm90ZWN0ZWQgWE1MRG9jdW1lbnRTb3VyY2UgZkRvY3VtZW50U291cmNlOwotCi0gICAgcHJvdGVjdGVkIFhJbmNsdWRlSGFuZGxlciBmUGFyZW50WEluY2x1ZGVIYW5kbGVyOwotCi0gICAgcHJvdGVjdGVkIFhNTExvY2F0b3IgZkRvY0xvY2F0aW9uOwotICAgIHByb3RlY3RlZCBYSW5jbHVkZU5hbWVzcGFjZVN1cHBvcnQgZk5hbWVzcGFjZUNvbnRleHQ7Ci0gICAgcHJvdGVjdGVkIFhNTEVycm9yUmVwb3J0ZXIgZkVycm9yUmVwb3J0ZXI7Ci0gICAgcHJvdGVjdGVkIFhNTEdyYW1tYXJQb29sIGZHcmFtbWFyUG9vbDsKLSAgICBwcm90ZWN0ZWQgWE1MR3JhbW1hckRlc2NyaXB0aW9uIGZHcmFtbWFyRGVzYzsKLSAgICBwcm90ZWN0ZWQgRFRER3JhbW1hciBmRFRER3JhbW1hcjsKLSAgICBwcm90ZWN0ZWQgWE1MRW50aXR5UmVzb2x2ZXIgZkVudGl0eVJlc29sdmVyOwotICAgIHByb3RlY3RlZCBQYXJzZXJDb25maWd1cmF0aW9uU2V0dGluZ3MgZlNldHRpbmdzOwotICAgIC8vcHJvdGVjdGVkIFN0cmluZyBmUG9pbnRlclNjaGVtYTsKLSAgICBwcm90ZWN0ZWQgU3RyaW5nQnVmZmVyIGZQb2ludGVyOwotICAgIHByaXZhdGUgaW50IGVsZW1Db3VudCA9IDA7Ci0KLQotICAgIC8vIFRoZSBjdXJyZW50IGVsZW1lbnQgZGVwdGguCi0gICAgLy8gVGhpcyBpcyB1c2VkIHRvIGFjY2VzcyB0aGUgYXBwcm9wcmlhdGUgbGV2ZWwgb2YgdGhlIGZvbGxvd2luZyBzdGFja3MuCi0gICAgcHJpdmF0ZSBpbnQgZkRlcHRoOwotCi0gICAgLy8gVGhlIGRlcHRoIG9mIHRoZSBmaXJzdCBlbGVtZW50IHRvIGFjdHVhbGx5IGJlIHBhcnQgb2YgdGhlIHJlc3VsdCBpbmZvc2V0LgotICAgIC8vIFRoaXMgd2lsbCBub3JtYWxseSBiZSAxLCBidXQgaXQgY291bGQgYmUgbGFyZ2VyIHdoZW4gdGhlIHRvcC1sZXZlbCBpdGVtCi0gICAgLy8gaXMgYW4gaW5jbHVkZSwgYW5kIHByb2Nlc3NpbmcgZ29lcyB0byB0aGUgZmFsbGJhY2suCi0gICAgcHJpdmF0ZSBpbnQgZlJvb3REZXB0aDsKLQotICAgIC8vIHRoaXMgdmFsdWUgbXVzdCBiZSBhdCBsZWFzdCAxCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IElOSVRJQUxfU0laRSA9IDg7Ci0KLQotICAgIC8vIFVzZWQgdG8gZW5zdXJlIHRoYXQgZmFsbGJhY2tzIGFyZSBhbHdheXMgY2hpbGRyZW4gb2YgaW5jbHVkZSBlbGVtZW50cywKLSAgICAvLyBhbmQgdGhhdCBpbmNsdWRlIGVsZW1lbnRzIGFyZSBuZXZlciBjaGlsZHJlbiBvZiBvdGhlciBpbmNsdWRlIGVsZW1lbnRzLgotICAgIC8vIEFuIGluZGV4IGNvbnRhaW5zIHRydWUgaWYgdGhlIGFuY2VzdG9yIG9mIHRoZSBjdXJyZW50IGVsZW1lbnQgd2hpY2ggcmVzaWRlcwotICAgIC8vIGF0IHRoYXQgZGVwdGggd2FzIGFuIGluY2x1ZGUgZWxlbWVudC4KLSAgICBwcml2YXRlIGJvb2xlYW5bXSBmU2F3SW5jbHVkZSA9IG5ldyBib29sZWFuW0lOSVRJQUxfU0laRV07Ci0KLQotICAgIC8vIEVuc3VyZXMgdGhhdCBvbmx5IG9uZSBmYWxsYmFjayBlbGVtZW50IGNhbiBiZSBhdCBhIHNpbmdsZSBkZXB0aC4KLSAgICAvLyBBbiBpbmRleCBjb250YWlucyB0cnVlIGlmIHdlIGhhdmUgc2VlbiBhbnkgZmFsbGJhY2sgZWxlbWVudHMgYXQgdGhhdCBkZXB0aCwKLSAgICAvLyBhbmQgaXQgaXMgb25seSByZXNldCB0byBmYWxzZSB3aGVuIHRoZSBlbmQgdGFnIG9mIHRoZSBwYXJlbnQgaXMgZW5jb3VudGVyZWQuCi0gICAgcHJpdmF0ZSBib29sZWFuW10gZlNhd0ZhbGxiYWNrID0gbmV3IGJvb2xlYW5bSU5JVElBTF9TSVpFXTsKLQotCi0gICAgLy8gVGhlIHN0YXRlIG9mIHRoZSBwcm9jZXNzb3IgYXQgZWFjaCBnaXZlbiBkZXB0aC4KLSAgICBwcml2YXRlIGludFtdIGZTdGF0ZSA9IG5ldyBpbnRbSU5JVElBTF9TSVpFXTsKLQotICAgIFFOYW1lIGZvdW5kRWxlbWVudCA9IG51bGw7Ci0gICAgYm9vbGVhbiBza2lwID0gZmFsc2U7Ci0gICAgLy8gQ29uc3RydWN0b3JzCi0KLSAgICBwdWJsaWMgWFBvaW50ZXJFbGVtZW50SGFuZGxlcigpIHsKLQotCi0gICAgICAgIGZEZXB0aCA9IDA7Ci0gICAgICAgIGZSb290RGVwdGggPSAwOwotICAgICAgICBmU2F3RmFsbGJhY2tbZkRlcHRoXSA9IGZhbHNlOwotICAgICAgICBmU2F3SW5jbHVkZVtmRGVwdGhdID0gZmFsc2U7Ci0gICAgICAgIGZTY2hlbWFOYW1lPSJlbGVtZW50IjsKLQotCi0gICAgfQotCi0gICAgLy8gU1RBUlQgT0YgSU1QTEVNRU5UQVRJT04gT0YgWE1MQ29tcG9uZW50IG1ldGhvZHMgLy8vLy8vCi0KLSAgICBwdWJsaWMgdm9pZCByZXNldCgpewotICAgICAgICBlbGVtQ291bnQgPTA7Ci0gICAgICAgIGZQb2ludGVyVG9rZW4gPSBudWxsOwotICAgICAgICBmQ3VycmVudFRva2VuaW50PTA7Ci0gICAgICAgIGZDdXJyZW50VG9rZW5TdHJpbmc9bnVsbDsKLSAgICAgICAgZkN1cnJlbnRUb2tlblR5cGU9MCA7Ci0gICAgICAgIGZFbGVtZW50Q291bnQgPTA7Ci0gICAgICAgIGZDdXJyZW50VG9rZW4gPTA7Ci0gICAgICAgIGluY2x1ZGVFbGVtZW50ID0gZmFsc2U7Ci0gICAgICAgIGZvdW5kRWxlbWVudCA9IG51bGw7Ci0gICAgICAgIHNraXAgPSBmYWxzZTsKLSAgICAgICAgZlN1YlJlc291cmNlSWRlbnRpZmllZD1mYWxzZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCByZXNldChYTUxDb21wb25lbnRNYW5hZ2VyIGNvbXBvbmVudE1hbmFnZXIpCi0gICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIGZOYW1lc3BhY2VDb250ZXh0ID0gbnVsbDsKLSAgICAgICAgZWxlbUNvdW50ID0wOwotICAgICAgICBmRGVwdGggPSAwOwotICAgICAgICBmUm9vdERlcHRoID0gMDsKLSAgICAgICAgZlBvaW50ZXJUb2tlbiA9IG51bGw7Ci0gICAgICAgIGZDdXJyZW50VG9rZW5pbnQ9MDsKLSAgICAgICAgZkN1cnJlbnRUb2tlblN0cmluZz1udWxsOwotICAgICAgICBmQ3VycmVudFRva2VuVHlwZT0wIDsKLSAgICAgICAgZm91bmRFbGVtZW50ID0gbnVsbDsKLSAgICAgICAgaW5jbHVkZUVsZW1lbnQgPSBmYWxzZTsKLSAgICAgICAgc2tpcCA9IGZhbHNlOwotICAgICAgICBmU3ViUmVzb3VyY2VJZGVudGlmaWVkPWZhbHNlOwotCi0KLQotCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBzZXRFcnJvclJlcG9ydGVyKAotICAgICAgICAgICAgKFhNTEVycm9yUmVwb3J0ZXIpY29tcG9uZW50TWFuYWdlci5nZXRQcm9wZXJ0eShFUlJPUl9SRVBPUlRFUikpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyID0gbnVsbDsKLSAgICAgICAgfQotICAgICAgICB0cnkgewotICAgICAgICAgICAgZkdyYW1tYXJQb29sID0KLSAgICAgICAgICAgIChYTUxHcmFtbWFyUG9vbCljb21wb25lbnRNYW5hZ2VyLmdldFByb3BlcnR5KEdSQU1NQVJfUE9PTCk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gZSkgewotICAgICAgICAgICAgZkdyYW1tYXJQb29sID0gbnVsbDsKLSAgICAgICAgfQotICAgICAgICB0cnkgewotICAgICAgICAgICAgZkVudGl0eVJlc29sdmVyID0KLSAgICAgICAgICAgIChYTUxFbnRpdHlSZXNvbHZlciljb21wb25lbnRNYW5hZ2VyLmdldFByb3BlcnR5KAotICAgICAgICAgICAgRU5USVRZX1JFU09MVkVSKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICBmRW50aXR5UmVzb2x2ZXIgPSBudWxsOwotICAgICAgICB9Ci0KLSAgICAgICAgZlNldHRpbmdzID0gbmV3IFBhcnNlckNvbmZpZ3VyYXRpb25TZXR0aW5ncygpOwotCi0gICAgICAgIEVudW1lcmF0aW9uIHhlcmNlc0ZlYXR1cmVzID0gQ29uc3RhbnRzLmdldFhlcmNlc0ZlYXR1cmVzKCk7Ci0gICAgICAgIHdoaWxlICh4ZXJjZXNGZWF0dXJlcy5oYXNNb3JlRWxlbWVudHMoKSkgewotICAgICAgICAgICAgU3RyaW5nIGZlYXR1cmVJZCA9IChTdHJpbmcpeGVyY2VzRmVhdHVyZXMubmV4dEVsZW1lbnQoKTsKLSAgICAgICAgICAgIGZTZXR0aW5ncy5hZGRSZWNvZ25pemVkRmVhdHVyZXMobmV3IFN0cmluZ1tdIHsgZmVhdHVyZUlkIH0pOwotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICBmU2V0dGluZ3Muc2V0RmVhdHVyZSgKLSAgICAgICAgICAgICAgICBmZWF0dXJlSWQsCi0gICAgICAgICAgICAgICAgY29tcG9uZW50TWFuYWdlci5nZXRGZWF0dXJlKGZlYXR1cmVJZCkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2F0Y2ggKFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgIC8vIGNvbXBvbmVudE1hbmFnZXIgZG9lc24ndCBzdXBwb3J0IHRoaXMgZmVhdHVyZSwKLSAgICAgICAgICAgICAgICAvLyBzbyB3ZSB3b24ndCB3b3JyeSBhYm91dCBpdAotICAgICAgICAgICAgfQotICAgICAgICB9Ci0vKiAgICAgICAgICAgICAgdHJ5ewotICAgICAgICAgIGR0ZFZhbGlkYXRvciA9ICAgKFhNTERURFZhbGlkYXRvciljb21wb25lbnRNYW5hZ2VyLmdldFByb3BlcnR5KCBDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWCArIENvbnN0YW50cy5EVERfVkFMSURBVE9SX1BST1BFUlRZKTsKLSAgICAgICAgICAgICAgICB9Q2F0Y2goRXhjZXB0aW9uIGV4KXsKLSAgICAgICAgICAgICAgICAgICAgICAgIGV4LnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgICAgICAgICAgIH0qLwotCi0gICAgfSAvLyByZXNldChYTUxDb21wb25lbnRNYW5hZ2VyKQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhIGxpc3Qgb2YgZmVhdHVyZSBpZGVudGlmaWVycyB0aGF0IGFyZSByZWNvZ25pemVkIGJ5Ci0gICAgICogdGhpcyBjb21wb25lbnQuIFRoaXMgbWV0aG9kIG1heSByZXR1cm4gbnVsbCBpZiBubyBmZWF0dXJlcwotICAgICAqIGFyZSByZWNvZ25pemVkIGJ5IHRoaXMgY29tcG9uZW50LgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmdbXSBnZXRSZWNvZ25pemVkRmVhdHVyZXMoKSB7Ci0gICAgICAgIHJldHVybiBSRUNPR05JWkVEX0ZFQVRVUkVTOwotICAgIH0gLy8gZ2V0UmVjb2duaXplZEZlYXR1cmVzKCk6U3RyaW5nW10KLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIHN0YXRlIG9mIGEgZmVhdHVyZS4gVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBjb21wb25lbnQKLSAgICAgKiBtYW5hZ2VyIGFueSB0aW1lIGFmdGVyIHJlc2V0IHdoZW4gYSBmZWF0dXJlIGNoYW5nZXMgc3RhdGUuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBDb21wb25lbnRzIHNob3VsZCBzaWxlbnRseSBpZ25vcmUgZmVhdHVyZXMKLSAgICAgKiB0aGF0IGRvIG5vdCBhZmZlY3QgdGhlIG9wZXJhdGlvbiBvZiB0aGUgY29tcG9uZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIGZlYXR1cmVJZCBUaGUgZmVhdHVyZSBpZGVudGlmaWVyLgotICAgICAqIEBwYXJhbSBzdGF0ZSAgICAgVGhlIHN0YXRlIG9mIHRoZSBmZWF0dXJlLgotICAgICAqCi0gICAgICogQHRocm93cyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIFRoZSBjb21wb25lbnQgc2hvdWxkIG5vdCB0aHJvdwotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzIGV4Y2VwdGlvbi4KLSAgICAgKiBAdGhyb3dzIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBUaGUgY29tcG9uZW50IHNob3VsZCBub3QgdGhyb3cKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzIGV4Y2VwdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRGZWF0dXJlKFN0cmluZyBmZWF0dXJlSWQsIGJvb2xlYW4gc3RhdGUpCi0gICAgdGhyb3dzIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gewotICAgICAgICBpZiAoZlNldHRpbmdzICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZTZXR0aW5ncy5zZXRGZWF0dXJlKGZlYXR1cmVJZCwgc3RhdGUpOwotICAgICAgICB9Ci0KLSAgICB9IC8vIHNldEZlYXR1cmUoU3RyaW5nLGJvb2xlYW4pCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGEgbGlzdCBvZiBwcm9wZXJ0eSBpZGVudGlmaWVycyB0aGF0IGFyZSByZWNvZ25pemVkIGJ5Ci0gICAgICogdGhpcyBjb21wb25lbnQuIFRoaXMgbWV0aG9kIG1heSByZXR1cm4gbnVsbCBpZiBubyBwcm9wZXJ0aWVzCi0gICAgICogYXJlIHJlY29nbml6ZWQgYnkgdGhpcyBjb21wb25lbnQuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZ1tdIGdldFJlY29nbml6ZWRQcm9wZXJ0aWVzKCkgewotICAgICAgICByZXR1cm4gUkVDT0dOSVpFRF9QUk9QRVJUSUVTOwotICAgIH0gLy8gZ2V0UmVjb2duaXplZFByb3BlcnRpZXMoKTpTdHJpbmdbXQotCi0gICAgLyoqCi0gICAgICogU2V0cyB0aGUgdmFsdWUgb2YgYSBwcm9wZXJ0eS4gVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBjb21wb25lbnQKLSAgICAgKiBtYW5hZ2VyIGFueSB0aW1lIGFmdGVyIHJlc2V0IHdoZW4gYSBwcm9wZXJ0eSBjaGFuZ2VzIHZhbHVlLgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gQ29tcG9uZW50cyBzaG91bGQgc2lsZW50bHkgaWdub3JlIHByb3BlcnRpZXMKLSAgICAgKiB0aGF0IGRvIG5vdCBhZmZlY3QgdGhlIG9wZXJhdGlvbiBvZiB0aGUgY29tcG9uZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIHByb3BlcnR5SWQgVGhlIHByb3BlcnR5IGlkZW50aWZpZXIuCi0gICAgICogQHBhcmFtIHZhbHVlICAgICAgVGhlIHZhbHVlIG9mIHRoZSBwcm9wZXJ0eS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiBUaGUgY29tcG9uZW50IHNob3VsZCBub3QgdGhyb3cKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcyBleGNlcHRpb24uCi0gICAgICogQHRocm93cyBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gVGhlIGNvbXBvbmVudCBzaG91bGQgbm90IHRocm93Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcyBleGNlcHRpb24uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0UHJvcGVydHkoU3RyaW5nIHByb3BlcnR5SWQsIE9iamVjdCB2YWx1ZSkKLSAgICB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChwcm9wZXJ0eUlkLmVxdWFscyhFUlJPUl9SRVBPUlRFUikpIHsKLSAgICAgICAgICAgIHNldEVycm9yUmVwb3J0ZXIoKFhNTEVycm9yUmVwb3J0ZXIpdmFsdWUpOwotICAgICAgICB9Ci0gICAgICAgIGlmIChwcm9wZXJ0eUlkLmVxdWFscyhHUkFNTUFSX1BPT0wpKSB7Ci0gICAgICAgICAgICBmR3JhbW1hclBvb2wgPSAoWE1MR3JhbW1hclBvb2wpdmFsdWU7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKHByb3BlcnR5SWQuZXF1YWxzKEVOVElUWV9SRVNPTFZFUikpIHsKLSAgICAgICAgICAgIGZFbnRpdHlSZXNvbHZlciA9IChYTUxFbnRpdHlSZXNvbHZlcil2YWx1ZTsKLSAgICAgICAgfQotCi0gICAgfSAvLyBzZXRQcm9wZXJ0eShTdHJpbmcsT2JqZWN0KQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgZGVmYXVsdCBzdGF0ZSBmb3IgYSBmZWF0dXJlLCBvciBudWxsIGlmIHRoaXMKLSAgICAgKiBjb21wb25lbnQgZG9lcyBub3Qgd2FudCB0byByZXBvcnQgYSBkZWZhdWx0IHZhbHVlIGZvciB0aGlzCi0gICAgICogZmVhdHVyZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBmZWF0dXJlSWQgVGhlIGZlYXR1cmUgaWRlbnRpZmllci4KLSAgICAgKgotICAgICAqIEBzaW5jZSBYZXJjZXMgMi4yLjAKLSAgICAgKi8KLSAgICBwdWJsaWMgQm9vbGVhbiBnZXRGZWF0dXJlRGVmYXVsdChTdHJpbmcgZmVhdHVyZUlkKSB7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgUkVDT0dOSVpFRF9GRUFUVVJFUy5sZW5ndGg7IGkrKykgewotICAgICAgICAgICAgaWYgKFJFQ09HTklaRURfRkVBVFVSRVNbaV0uZXF1YWxzKGZlYXR1cmVJZCkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gRkVBVFVSRV9ERUZBVUxUU1tpXTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9IC8vIGdldEZlYXR1cmVEZWZhdWx0KFN0cmluZyk6Qm9vbGVhbgotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgZGVmYXVsdCBzdGF0ZSBmb3IgYSBwcm9wZXJ0eSwgb3IgbnVsbCBpZiB0aGlzCi0gICAgICogY29tcG9uZW50IGRvZXMgbm90IHdhbnQgdG8gcmVwb3J0IGEgZGVmYXVsdCB2YWx1ZSBmb3IgdGhpcwotICAgICAqIHByb3BlcnR5LgotICAgICAqCi0gICAgICogQHBhcmFtIHByb3BlcnR5SWQgVGhlIHByb3BlcnR5IGlkZW50aWZpZXIuCi0gICAgICoKLSAgICAgKiBAc2luY2UgWGVyY2VzIDIuMi4wCi0gICAgICovCi0gICAgcHVibGljIE9iamVjdCBnZXRQcm9wZXJ0eURlZmF1bHQoU3RyaW5nIHByb3BlcnR5SWQpIHsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBSRUNPR05JWkVEX1BST1BFUlRJRVMubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgIGlmIChSRUNPR05JWkVEX1BST1BFUlRJRVNbaV0uZXF1YWxzKHByb3BlcnR5SWQpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIFBST1BFUlRZX0RFRkFVTFRTW2ldOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0gLy8gZ2V0UHJvcGVydHlEZWZhdWx0KFN0cmluZyk6T2JqZWN0Ci0KLSAgICBwcml2YXRlIHZvaWQgc2V0RXJyb3JSZXBvcnRlcihYTUxFcnJvclJlcG9ydGVyIHJlcG9ydGVyKSB7Ci0gICAgICAgIGZFcnJvclJlcG9ydGVyID0gcmVwb3J0ZXI7Ci0gICAgICAgIGlmIChmRXJyb3JSZXBvcnRlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmRXJyb3JSZXBvcnRlci5wdXRNZXNzYWdlRm9ybWF0dGVyKAotICAgICAgICAgICAgWEluY2x1ZGVNZXNzYWdlRm9ybWF0dGVyLlhJTkNMVURFX0RPTUFJTiwKLSAgICAgICAgICAgIG5ldyBYSW5jbHVkZU1lc3NhZ2VGb3JtYXR0ZXIoKSk7Ci0gICAgICAgIH0KLSAgICB9Ci0gICAgLy8vLy8vLy8vIEVORCBPRiBJTVBMRU1FTlRBVElPTiAgT0YgWE1MQ29tcG9uZW50cyBtZXRob2RzLiAvLy8vLy8vLy8vCi0KLQotCi0gICAgLy8vLy8vLy8gU1RBUlQgT0YgIElNUExFTUVOVEFUSU9OIE9GIFhNTERPQ1VNRU5UU09VUkNFIElOVEVSRkFDRSAvLy8vLy8vLy8KLQotICAgIHB1YmxpYyB2b2lkIHNldERvY3VtZW50SGFuZGxlcihYTUxEb2N1bWVudEhhbmRsZXIgaGFuZGxlcikgewotICAgICAgICBmRG9jdW1lbnRIYW5kbGVyID0gaGFuZGxlcjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgWE1MRG9jdW1lbnRIYW5kbGVyIGdldERvY3VtZW50SGFuZGxlcigpIHsKLSAgICAgICAgcmV0dXJuIGZEb2N1bWVudEhhbmRsZXI7Ci0gICAgfQotCi0gICAgLy8vLy8vLyAgIEVORCBPRiBJTVBMRU5UQVRJT04gT0YgWE1MRE9DVU1FTlRTT1VSQ0UgSU5URVJGQUNFIC8vLy8vLy8vLy8vCi0KLQotCi0KLSAgICAvLy8vLy8vLy8vLy8vLy8gSW1wbGVtZW50YXRpb24gb2YgWFBvaW50ZXJTY2hlbWEgTWV0aG9kcyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0KLSAgICBTdHJpbmcgZlNjaGVtYU5hbWU7Ci0gICAgU3RyaW5nIGZTY2hlbWFQb2ludGVyOwotICAgIGJvb2xlYW4gZlN1YlJlc291cmNlSWRlbnRpZmllZDsKLSAgICAvKioKLSAgICAgKiBzZXQgdGhlIFNjaGVtYSBOYW1lICBlZyBlbGVtZW50ICwgeHBvaW50ZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRYUG9pbnRlclNjaGVtYU5hbWUoU3RyaW5nIHNjaGVtYU5hbWUpewotICAgICAgICBmU2NoZW1hTmFtZSA9IHNjaGVtYU5hbWU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuICBTY2hlbWEgTmFtZSAgZWcgZWxlbWVudCAsIHhwb2ludGVyCi0gICAgICoKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFhwb2ludGVyU2NoZW1hTmFtZSgpewotICAgICAgICByZXR1cm4gZlNjaGVtYU5hbWU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUGFyZW50IENvbnRlbmhhbmRsZXIgZm9yIHRoZSB0aGlzIGNvbnRlbnRoYW5kbGVyLgotICAgICAqIC8vIG5vdCBzdXJlIGFib3V0IHRoZSBwYXJhbWV0ZXIgdHlwZS4gSXQgY2FuIGJlIENvbnRlbnRoYW5kbGVyIGluc3RlYWQgb2YgT2JqZWN0IHR5cGUuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0UGFyZW50KE9iamVjdCBwYXJlbnQpewotICAgICAgICBmUGFyZW50WEluY2x1ZGVIYW5kbGVyID0gKFhJbmNsdWRlSGFuZGxlcilwYXJlbnQ7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiByZXR1cm4gdGhlIFBhcmVudCBDb250ZW50aGFuZGxlcgotICAgICAqLwotICAgIHB1YmxpYyBPYmplY3QgZ2V0UGFyZW50KCl7Ci0gICAgICAgIHJldHVybiBmUGFyZW50WEluY2x1ZGVIYW5kbGVyOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbnRlbnQgb2YgdGhlIFhQb2ludGVyIFNjaGVtYS4gWHBhdGggdG8gYmUgcmVzb2x2ZWQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0WFBvaW50ZXJTY2hlbWFQb2ludGVyKFN0cmluZyBjb250ZW50KXsKLSAgICAgICAgZlNjaGVtYVBvaW50ZXIgPSBjb250ZW50OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybiB0aGUgWFBvaW50ZXIgU2NoZW1hLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0WFBvaW50ZXJTY2hlbWFQb2ludGVyKCl7Ci0gICAgICAgIHJldHVybiBmU2NoZW1hUG9pbnRlcjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBpc1N1YlJlc291cmNlSW5kZW50aWZpZWQoKXsKLSAgICAgICAgcmV0dXJuIGZTdWJSZXNvdXJjZUlkZW50aWZpZWQ7Ci0gICAgfQotCi0gICAgLy8vLy8vLy8vLy9FbmQgSW1wbGVtZW50YXRpb24gb2YgWFBvaW50ZXJTY2hlbWEgTWV0aG9kcyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0KLQotCi0gICAgLy8vLy8vLy8vLy8vIFRva2VucyBQbGF5Z3JvdW5kIC8vLy8vLy8vLy8vLy8vLy8vLy8KLQotICAgIFN0YWNrIGZQb2ludGVyVG9rZW4gPSBuZXcgU3RhY2soKTsKLSAgICBpbnQgIGZDdXJyZW50VG9rZW5pbnQ9MDsKLSAgICBTdHJpbmcgZkN1cnJlbnRUb2tlblN0cmluZz1udWxsOwotICAgIGludCBmQ3VycmVudFRva2VuVHlwZT0wIDsvLyAwIE5vdHlwZTsgMSBmb3IgaW50ZWdlcjsgMiBmb3Igc3RyaW5nLgotCi0gICAgcHVibGljIHZvaWQgZ2V0VG9rZW5zKCl7Ci0gICAgICAgIGZTY2hlbWFQb2ludGVyID0gZlNjaGVtYVBvaW50ZXIuc3Vic3RyaW5nKGZTY2hlbWFQb2ludGVyLmluZGV4T2YoIigiKSsxLCBmU2NoZW1hUG9pbnRlci5sZW5ndGgoKSk7Ci0gICAgICAgIFN0cmluZ1Rva2VuaXplciBzdCA9IG5ldyBTdHJpbmdUb2tlbml6ZXIoZlNjaGVtYVBvaW50ZXIsICIvIik7Ci0gICAgICAgIFN0cmluZyB0ZW1wVG9rZW47Ci0gICAgICAgIEludGVnZXIgaW50ZWdlclRva2VuID1udWxsOwotICAgICAgICBTdGFjayB0ZW1wUG9pbnRlclRva2VuID0gbmV3IFN0YWNrKCk7Ci0gICAgICAgIGlmKGZQb2ludGVyVG9rZW4gPT0gbnVsbCl7Ci0gICAgICAgICAgICBmUG9pbnRlclRva2VuID0gbmV3IFN0YWNrKCk7Ci0gICAgICAgIH0KLSAgICAgICAgd2hpbGUoc3QuaGFzTW9yZVRva2VucygpKXsKLSAgICAgICAgICAgIHRlbXBUb2tlbj1zdC5uZXh0VG9rZW4oKTsKLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgaW50ZWdlclRva2VuID0gSW50ZWdlci52YWx1ZU9mKHRlbXBUb2tlbik7Ci0gICAgICAgICAgICAgICAgdGVtcFBvaW50ZXJUb2tlbi5wdXNoKGludGVnZXJUb2tlbik7Ci0gICAgICAgICAgICB9Y2F0Y2goTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGUpewotICAgICAgICAgICAgICAgIHRlbXBQb2ludGVyVG9rZW4ucHVzaCh0ZW1wVG9rZW4pOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHdoaWxlKCF0ZW1wUG9pbnRlclRva2VuLmVtcHR5KCkpewotICAgICAgICAgICAgZlBvaW50ZXJUb2tlbi5wdXNoKHRlbXBQb2ludGVyVG9rZW4ucG9wKCkpOwotICAgICAgICB9Ci0gICAgfS8vZ2V0VG9rZW5zCi0KLQotICAgIHB1YmxpYyBib29sZWFuIGhhc01vcmVUb2tlbigpewotICAgICAgICBpZihmUG9pbnRlclRva2VuLmlzRW1wdHkoKSkKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgZWxzZQotICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0TmV4dFRva2VuKCl7Ci0gICAgICAgIE9iamVjdCBjdXJyZW50VG9rZW47Ci0gICAgICAgIGlmICghZlBvaW50ZXJUb2tlbi5pc0VtcHR5KCkpewotICAgICAgICAgICAgY3VycmVudFRva2VuID0gZlBvaW50ZXJUb2tlbi5wb3AoKTsKLSAgICAgICAgICAgIGlmKGN1cnJlbnRUb2tlbiBpbnN0YW5jZW9mIEludGVnZXIpewotICAgICAgICAgICAgICAgIGZDdXJyZW50VG9rZW5pbnQgPSAoKEludGVnZXIpY3VycmVudFRva2VuKS5pbnRWYWx1ZSgpOwotICAgICAgICAgICAgICAgIGZDdXJyZW50VG9rZW5UeXBlID0gMTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2V7Ci0gICAgICAgICAgICAgICAgZkN1cnJlbnRUb2tlblN0cmluZyA9ICgoU3RyaW5nKWN1cnJlbnRUb2tlbikudG9TdHJpbmcoKTsKLSAgICAgICAgICAgICAgICBmQ3VycmVudFRva2VuVHlwZSA9IDI7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHByaXZhdGUgYm9vbGVhbiBpc0lkQXR0cmlidXRlKFhNTEF0dHJpYnV0ZXMgYXR0cmlidXRlcyxBdWdtZW50YXRpb25zIGF1Z3MsIGludCBpbmRleCkgewotICAgICAgICBPYmplY3QgbyA9IGF1Z3MuZ2V0SXRlbShDb25zdGFudHMuSURfQVRUUklCVVRFKTsKLSAgICAgICAgaWYoIG8gaW5zdGFuY2VvZiBCb29sZWFuICkKLSAgICAgICAgICAgIHJldHVybiAoKEJvb2xlYW4pbykuYm9vbGVhblZhbHVlKCk7Ci0gICAgICAgIHJldHVybiAiSUQiLmVxdWFscyhhdHRyaWJ1dGVzLmdldFR5cGUoaW5kZXgpKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBjaGVja1N0cmluZ1Rva2VuKFFOYW1lIGVsZW1lbnQsIFhNTEF0dHJpYnV0ZXMgYXR0cmlidXRlcyl7Ci0gICAgICAgIFFOYW1lIGNhY2hlUU5hbWUgPSBudWxsOwotICAgICAgICBTdHJpbmcgaWQgPW51bGw7Ci0gICAgICAgIFN0cmluZyByYXduYW1lID1udWxsOwotICAgICAgICBRTmFtZSBhdHRyTmFtZSA9IG5ldyBRTmFtZSgpOwotICAgICAgICBTdHJpbmcgYXR0clR5cGUgPSBudWxsOwotICAgICAgICBTdHJpbmcgYXR0clZhbHVlID0gbnVsbDsKLSAgICAgICAgaW50IGF0dHJDb3VudCA9IGF0dHJpYnV0ZXMuZ2V0TGVuZ3RoKCk7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYXR0ckNvdW50OyBpKyspIHsKLSAgICAgICAgICAgIEF1Z21lbnRhdGlvbnMgYWF1Z3MgPSBhdHRyaWJ1dGVzLmdldEF1Z21lbnRhdGlvbnMoaSk7Ci0gICAgICAgICAgICBhdHRyaWJ1dGVzLmdldE5hbWUoaSxhdHRyTmFtZSk7Ci0gICAgICAgICAgICBhdHRyVHlwZSA9IGF0dHJpYnV0ZXMuZ2V0VHlwZShpKTsKLSAgICAgICAgICAgIGF0dHJWYWx1ZSA9IGF0dHJpYnV0ZXMuZ2V0VmFsdWUoaSk7Ci0gICAgICAgICAgICBpZihhdHRyVHlwZSAhPSBudWxsICYmIGF0dHJWYWx1ZSE9IG51bGwgJiYgaXNJZEF0dHJpYnV0ZShhdHRyaWJ1dGVzLGFhdWdzLGkpICYmIGF0dHJWYWx1ZS5lcXVhbHMoZkN1cnJlbnRUb2tlblN0cmluZykpewotICAgICAgICAgICAgICAgIGlmKGhhc01vcmVUb2tlbigpKXsKLSAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRUb2tlblR5cGUgPSAwOwotICAgICAgICAgICAgICAgICAgICBmQ3VycmVudFRva2VuU3RyaW5nID0gbnVsbDsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2V7Ci0gICAgICAgICAgICAgICAgICAgIGZvdW5kRWxlbWVudCA9IGVsZW1lbnQ7Ci0gICAgICAgICAgICAgICAgICAgIGluY2x1ZGVFbGVtZW50ID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRUb2tlblR5cGUgPSAwOwotICAgICAgICAgICAgICAgICAgICBmQ3VycmVudFRva2VuU3RyaW5nID0gbnVsbDsKLSAgICAgICAgICAgICAgICAgICAgZlN1YlJlc291cmNlSWRlbnRpZmllZCA9IHRydWU7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gY2hlY2tJbnRlZ2VyVG9rZW4oUU5hbWUgZWxlbWVudCl7Ci0gICAgICAgIGlmKCFza2lwKXsKLSAgICAgICAgICAgIGZFbGVtZW50Q291bnQrKzsKLSAgICAgICAgICAgIGlmKGZDdXJyZW50VG9rZW5pbnQgPT0gZkVsZW1lbnRDb3VudCl7Ci0gICAgICAgICAgICAgICAgaWYoaGFzTW9yZVRva2VuKCkpewotICAgICAgICAgICAgICAgICAgICBmRWxlbWVudENvdW50PTA7Ci0gICAgICAgICAgICAgICAgICAgIGZDdXJyZW50VG9rZW5UeXBlID0gMDsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2V7Ci0gICAgICAgICAgICAgICAgICAgIGZvdW5kRWxlbWVudCA9IGVsZW1lbnQ7Ci0gICAgICAgICAgICAgICAgICAgIGluY2x1ZGVFbGVtZW50ID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgZkN1cnJlbnRUb2tlblR5cGUgPSAwOwotICAgICAgICAgICAgICAgICAgICBmRWxlbWVudENvdW50PTA7Ci0gICAgICAgICAgICAgICAgICAgIGZTdWJSZXNvdXJjZUlkZW50aWZpZWQgPXRydWU7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH1lbHNlewotICAgICAgICAgICAgICAgIGFkZFFOYW1lKGVsZW1lbnQpOwotICAgICAgICAgICAgICAgIHNraXAgPSB0cnVlOwotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgYWRkUU5hbWUoUU5hbWUgZWxlbWVudCl7Ci0gICAgICAgIFFOYW1lIGNhY2hlUU5hbWUgPSBuZXcgUU5hbWUoZWxlbWVudCk7Ci0gICAgICAgIGZ0ZW1wQ3VycmVudEVsZW1lbnQucHVzaChjYWNoZVFOYW1lKTsKLSAgICB9Ci0KLSAgICAvLy8vLy8vLy8vLyAgRU5EIFRPS0VOIFBMQVlHUk9VTkQgLy8vLy8vLy8vLy8vLy8vCi0KLQotICAgIC8vLy8vICAgU1RBUlQgT0YgSU1QTEVNVEFUSU9OIE9GIFhNTERvY3VtZW50SGFuZGxlciBtZXRob2RzIC8vLy8vLy8vLy8KLQotCi0gICAgcHVibGljIHZvaWQgc3RhcnREb2N1bWVudChYTUxMb2NhdG9yIGxvY2F0b3IsIFN0cmluZyBlbmNvZGluZywKLSAgICBOYW1lc3BhY2VDb250ZXh0IG5hbWVzcGFjZUNvbnRleHQsIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLQotICAgICAgICBnZXRUb2tlbnMoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBkb2N0eXBlRGVjbChTdHJpbmcgcm9vdEVsZW1lbnQsIFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkLAotICAgIEF1Z21lbnRhdGlvbnMgYXVncyl0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCB4bWxEZWNsKFN0cmluZyB2ZXJzaW9uLCBTdHJpbmcgZW5jb2RpbmcsIFN0cmluZyBzdGFuZGFsb25lLAotICAgIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgdm9pZCBjb21tZW50KFhNTFN0cmluZyB0ZXh0LCBBdWdtZW50YXRpb25zIGF1Z3MpCi0gICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChmRG9jdW1lbnRIYW5kbGVyICE9IG51bGwgJiYgaW5jbHVkZUVsZW1lbnQpIHsKLSAgICAgICAgICAgIGZEb2N1bWVudEhhbmRsZXIuY29tbWVudCh0ZXh0LCBhdWdzKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHByb2Nlc3NpbmdJbnN0cnVjdGlvbihTdHJpbmcgdGFyZ2V0LCBYTUxTdHJpbmcgZGF0YSwKLSAgICBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBpZiAoZkRvY3VtZW50SGFuZGxlciAhPSBudWxsICYmIGluY2x1ZGVFbGVtZW50KSB7Ci0gICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLnByb2Nlc3NpbmdJbnN0cnVjdGlvbih0YXJnZXQsIGRhdGEsIGF1Z3MpOwotCi0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBTdGFjayAgZnRlbXBDdXJyZW50RWxlbWVudCA9IG5ldyBTdGFjaygpOwotICAgIGludCBmRWxlbWVudENvdW50ID0wOwotICAgIGludCBmQ3VycmVudFRva2VuIDsKLSAgICBib29sZWFuIGluY2x1ZGVFbGVtZW50OwotCi0KLSAgICBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQoUU5hbWUgZWxlbWVudCwgWE1MQXR0cmlidXRlcyBhdHRyaWJ1dGVzLAotICAgIEF1Z21lbnRhdGlvbnMgYXVncyl0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLQotICAgICAgICBib29sZWFuIHJlcXVpcmVkVG9rZW49ZmFsc2U7Ci0gICAgICAgIGlmKGZDdXJyZW50VG9rZW5UeXBlID09IDApCi0gICAgICAgICAgICBnZXROZXh0VG9rZW4oKTsKLSAgICAgICAgaWYoZkN1cnJlbnRUb2tlblR5cGUgPT0xKQotICAgICAgICAgICAgcmVxdWlyZWRUb2tlbiA9IGNoZWNrSW50ZWdlclRva2VuKGVsZW1lbnQpOwotICAgICAgICBlbHNlIGlmIChmQ3VycmVudFRva2VuVHlwZSA9PTIpCi0gICAgICAgICAgICByZXF1aXJlZFRva2VuID0gY2hlY2tTdHJpbmdUb2tlbihlbGVtZW50LCBhdHRyaWJ1dGVzKTsKLSAgICAgICAgaWYocmVxdWlyZWRUb2tlbiAmJiBoYXNNb3JlVG9rZW4oKSkKLSAgICAgICAgICAgIGdldE5leHRUb2tlbigpOwotICAgICAgICBpZihmRG9jdW1lbnRIYW5kbGVyICE9IG51bGwgJiYgaW5jbHVkZUVsZW1lbnQpewotICAgICAgICAgICAgZWxlbUNvdW50Kys7Ci0gICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLnN0YXJ0RWxlbWVudChlbGVtZW50LCBhdHRyaWJ1dGVzLCBhdWdzKTsKLSAgICAgICAgfQotCi0gICAgfQotCi0KLSAgICBwdWJsaWMgdm9pZCBlbmRFbGVtZW50KFFOYW1lIGVsZW1lbnQsIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgaWYoaW5jbHVkZUVsZW1lbnQgJiYgZm91bmRFbGVtZW50ICE9IG51bGwgKXsKLSAgICAgICAgICAgIGlmKGVsZW1Db3VudCA+MCApZWxlbUNvdW50IC0tOwotICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci5lbmRFbGVtZW50KGVsZW1lbnQsIGF1Z3MpOwotICAgICAgICAgICAgaWYoZWxlbUNvdW50ID09IDApaW5jbHVkZUVsZW1lbnQgPSBmYWxzZTsKLQotICAgICAgICB9ZWxzZSBpZighZnRlbXBDdXJyZW50RWxlbWVudC5lbXB0eSgpKXsKLSAgICAgICAgICAgIFFOYW1lIG5hbWUgPSAoUU5hbWUpZnRlbXBDdXJyZW50RWxlbWVudC5wZWVrKCk7Ci0gICAgICAgICAgICBpZihuYW1lLmVxdWFscyhlbGVtZW50KSl7Ci0gICAgICAgICAgICAgICAgZnRlbXBDdXJyZW50RWxlbWVudC5wb3AoKTsKLSAgICAgICAgICAgICAgICBza2lwID0gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBlbXB0eUVsZW1lbnQoUU5hbWUgZWxlbWVudCwgWE1MQXR0cmlidXRlcyBhdHRyaWJ1dGVzLAotICAgIEF1Z21lbnRhdGlvbnMgYXVncyl0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgaWYoZkRvY3VtZW50SGFuZGxlciAhPSBudWxsICYmIGluY2x1ZGVFbGVtZW50KXsKLSAgICAgICAgICAgIGZEb2N1bWVudEhhbmRsZXIuZW1wdHlFbGVtZW50KGVsZW1lbnQsIGF0dHJpYnV0ZXMsIGF1Z3MpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc3RhcnRHZW5lcmFsRW50aXR5KFN0cmluZyBuYW1lLCBYTUxSZXNvdXJjZUlkZW50aWZpZXIgcmVzSWQsCi0gICAgU3RyaW5nIGVuY29kaW5nLAotICAgIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKGZEb2N1bWVudEhhbmRsZXIgIT0gbnVsbCAmJiBpbmNsdWRlRWxlbWVudCkgewotICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci5zdGFydEdlbmVyYWxFbnRpdHkobmFtZSwgcmVzSWQsIGVuY29kaW5nLCBhdWdzKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHRleHREZWNsKFN0cmluZyB2ZXJzaW9uLCBTdHJpbmcgZW5jb2RpbmcsIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKGZEb2N1bWVudEhhbmRsZXIgIT0gbnVsbCAmJiBpbmNsdWRlRWxlbWVudCkgewotICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci50ZXh0RGVjbCh2ZXJzaW9uLCBlbmNvZGluZywgYXVncyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBlbmRHZW5lcmFsRW50aXR5KFN0cmluZyBuYW1lLCBBdWdtZW50YXRpb25zIGF1Z3MpCi0gICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChmRG9jdW1lbnRIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZEb2N1bWVudEhhbmRsZXIuZW5kR2VuZXJhbEVudGl0eShuYW1lLCBhdWdzKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGNoYXJhY3RlcnMoWE1MU3RyaW5nIHRleHQsIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKGZEb2N1bWVudEhhbmRsZXIgIT0gbnVsbCAgJiYgaW5jbHVkZUVsZW1lbnQpIHsKLSAgICAgICAgICAgIGZEb2N1bWVudEhhbmRsZXIuY2hhcmFjdGVycyh0ZXh0LCBhdWdzKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGlnbm9yYWJsZVdoaXRlc3BhY2UoWE1MU3RyaW5nIHRleHQsIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKGZEb2N1bWVudEhhbmRsZXIgIT0gbnVsbCAmJiBpbmNsdWRlRWxlbWVudCkgewotICAgICAgICAgICAgZkRvY3VtZW50SGFuZGxlci5pZ25vcmFibGVXaGl0ZXNwYWNlKHRleHQsIGF1Z3MpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc3RhcnRDREFUQShBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBpZiAoZkRvY3VtZW50SGFuZGxlciAhPSBudWxsICYmIGluY2x1ZGVFbGVtZW50KSB7Ci0gICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLnN0YXJ0Q0RBVEEoYXVncyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBlbmRDREFUQShBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBpZiAoZkRvY3VtZW50SGFuZGxlciAhPSBudWxsICYmIGluY2x1ZGVFbGVtZW50KSB7Ci0gICAgICAgICAgICBmRG9jdW1lbnRIYW5kbGVyLmVuZENEQVRBKGF1Z3MpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgZW5kRG9jdW1lbnQoQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXREb2N1bWVudFNvdXJjZShYTUxEb2N1bWVudFNvdXJjZSBzb3VyY2UpIHsKLSAgICAgICAgZkRvY3VtZW50U291cmNlID0gc291cmNlOwotICAgIH0KLQotICAgIHB1YmxpYyBYTUxEb2N1bWVudFNvdXJjZSBnZXREb2N1bWVudFNvdXJjZSgpIHsKLSAgICAgICAgcmV0dXJuIGZEb2N1bWVudFNvdXJjZTsKLSAgICB9Ci0KLQotICAgIHByb3RlY3RlZCB2b2lkIHJlcG9ydEZhdGFsRXJyb3IoU3RyaW5nIGtleSkgewotICAgICAgICB0aGlzLnJlcG9ydEZhdGFsRXJyb3Ioa2V5LCBudWxsKTsKLSAgICB9Ci0KLSAgICBwcm90ZWN0ZWQgdm9pZCByZXBvcnRGYXRhbEVycm9yKFN0cmluZyBrZXksIE9iamVjdFtdIGFyZ3MpIHsKLSAgICAgICAgaWYgKGZFcnJvclJlcG9ydGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKAotICAgICAgICAgICAgZkRvY0xvY2F0aW9uLAotICAgICAgICAgICAgWEluY2x1ZGVNZXNzYWdlRm9ybWF0dGVyLlhJTkNMVURFX0RPTUFJTiwKLSAgICAgICAgICAgIGtleSwKLSAgICAgICAgICAgIGFyZ3MsCi0gICAgICAgICAgICBYTUxFcnJvclJlcG9ydGVyLlNFVkVSSVRZX0ZBVEFMX0VSUk9SKTsKLSAgICAgICAgfQotICAgICAgICAvLyB3ZSB3b24ndCB3b3JyeSBhYm91dCB3aGVuIGVycm9yIHJlcG9ydGVyIGlzIG51bGwsIHNpbmNlIHRoZXJlIHNob3VsZCBhbHdheXMgYmUKLSAgICAgICAgLy8gYXQgbGVhc3QgdGhlIGRlZmF1bHQgZXJyb3IgcmVwb3J0ZXIKLSAgICB9Ci0KLQotCi0gICAgLy8gdXNlZCB0byBrbm93IHdoZXRoZXIgdG8gcGFzcyBkZWNsYXJhdGlvbnMgdG8gdGhlIGRvY3VtZW50IGhhbmRsZXIKLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBpc1Jvb3REb2N1bWVudCgpIHsKLSAgICAgICAgcmV0dXJuIHRoaXMuZlBhcmVudFhJbmNsdWRlSGFuZGxlciA9PSBudWxsOwotICAgIH0KLQotCi19IC8vIGNsYXNzIFhQb2ludGVyRWxlbWVudGhhbmRsZXIKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3hpbmNsdWRlL1hQb2ludGVyRnJhbWV3b3JrLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94aW5jbHVkZS9YUG9pbnRlckZyYW1ld29yay5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhYmU1MTRlLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3hpbmNsdWRlL1hQb2ludGVyRnJhbWV3b3JrLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMDkgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMS0yMDAzIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGVyY2VzIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBJbnRlcm5hdGlvbmFsCi0gKiBCdXNpbmVzcyBNYWNoaW5lcywgSW5jLiwgaHR0cDovL3d3dy5hcGFjaGUub3JnLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueGluY2x1ZGU7Ci0KLWltcG9ydCBqYXZhLnV0aWwuU3RhY2s7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54aW5jbHVkZS5YUG9pbnRlclNjaGVtYTsKLQotcHVibGljIGNsYXNzIFhQb2ludGVyRnJhbWV3b3JrewotCi0gICAgICAgIC8qCi0gICAgICAgICAgICAgICAgVG9kbydzIGJ5IG5leHQgaW50ZWdyYXRpb24uCi0gICAgICAgICAgICAgICAgV2hpbGUgY29uc3RydWN0aW5nIHNjaGVtYSBuYW1lcyBhbmQgdXJpcyB1c2UgYSBkeW5hbWljIGRhdGFzdHJ1Y3R1cmUuCi0gICAgICAgICAqLwotCi0gICAgWFBvaW50ZXJTY2hlbWEgW10gZlhQb2ludGVyU2NoZW1hOwotICAgIFN0cmluZyBbXSBmU2NoZW1hUG9pbnRlck5hbWU7Ci0gICAgU3RyaW5nIFtdIGZTY2hlbWFQb2ludGVyVVJJOwotICAgIFN0cmluZyBmU2NoZW1hUG9pbnRlcjsKLSAgICBTdHJpbmcgZkN1cnJlbnRTY2hlbWFQb2ludGVyOwotICAgIFN0YWNrIGZTY2hlbWFOb3RBdmFpbGFibGU7Ci0gICAgaW50IGZDb3VudFNjaGVtYU5hbWUgPSAwOwotICAgIGludCBzY2hlbWFMZW5ndGggPSAwOwotICAgIFhQb2ludGVyU2NoZW1hIGZEZWZhdWx0WFBvaW50ZXJTY2hlbWE7Ci0KLSAgICBwdWJsaWMgWFBvaW50ZXJGcmFtZXdvcmsoKXsKLSAgICAgICAgdGhpcyhudWxsKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgWFBvaW50ZXJGcmFtZXdvcmsoWFBvaW50ZXJTY2hlbWEgW10geHBvaW50ZXJzY2hlbWEpewotICAgICAgICBmWFBvaW50ZXJTY2hlbWEgPSB4cG9pbnRlcnNjaGVtYTsKLSAgICAgICAgZlNjaGVtYU5vdEF2YWlsYWJsZSA9IG5ldyBTdGFjaygpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHJlc2V0KCl7Ci0gICAgICAgIGZYUG9pbnRlclNjaGVtYSA9IG51bGw7Ci0gICAgICAgIGZYUG9pbnRlclNjaGVtYSA9IG51bGw7Ci0gICAgICAgIGZDb3VudFNjaGVtYU5hbWUgPSAwOwotICAgICAgICBzY2hlbWFMZW5ndGggPSAwOwotICAgICAgICBmU2NoZW1hUG9pbnRlck5hbWUgPSBudWxsOwotICAgICAgICBmU2NoZW1hUG9pbnRlclVSSSA9IG51bGw7Ci0gICAgICAgIGZEZWZhdWx0WFBvaW50ZXJTY2hlbWEgPSBudWxsOwotICAgICAgICBmQ3VycmVudFNjaGVtYVBvaW50ZXIgPSBudWxsOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldFhQb2ludGVyU2NoZW1hKFhQb2ludGVyU2NoZW1hIFtdIHhwb2ludGVyc2NoZW1hKXsKLSAgICAgICAgZlhQb2ludGVyU2NoZW1hID0geHBvaW50ZXJzY2hlbWE7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0U2NoZW1hUG9pbnRlcihTdHJpbmcgc2NoZW1hUG9pbnRlcil7Ci0gICAgICAgIGZTY2hlbWFQb2ludGVyID0gc2NoZW1hUG9pbnRlcjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgWFBvaW50ZXJTY2hlbWEgZ2V0TmV4dFhQb2ludGVyU2NoZW1hKCl7Ci0gICAgICAgIGludCAgaT1mQ291bnRTY2hlbWFOYW1lOwotICAgICAgICBpZihmU2NoZW1hUG9pbnRlck5hbWUgPT0gbnVsbCl7Ci0gICAgICAgICAgICBnZXRTY2hlbWFOYW1lcygpOwotICAgICAgICB9Ci0gICAgICAgIGlmKGZEZWZhdWx0WFBvaW50ZXJTY2hlbWEgPT0gbnVsbCl7Ci0gICAgICAgICAgICBnZXREZWZhdWx0U2NoZW1hKCk7Ci0gICAgICAgIH0KLSAgICAgICAgaWYoZkRlZmF1bHRYUG9pbnRlclNjaGVtYS5nZXRYcG9pbnRlclNjaGVtYU5hbWUoKS5lcXVhbHNJZ25vcmVDYXNlKGZTY2hlbWFQb2ludGVyTmFtZVtpXSkpewotICAgICAgICAgICAgZkRlZmF1bHRYUG9pbnRlclNjaGVtYS5yZXNldCgpOwotICAgICAgICAgICAgZkRlZmF1bHRYUG9pbnRlclNjaGVtYS5zZXRYUG9pbnRlclNjaGVtYVBvaW50ZXIoZlNjaGVtYVBvaW50ZXJVUklbaV0pOwotICAgICAgICAgICAgZkNvdW50U2NoZW1hTmFtZSA9ICsraTsKLSAgICAgICAgICAgIHJldHVybiAgZ2V0RGVmYXVsdFNjaGVtYSgpOwotICAgICAgICB9Ci0gICAgICAgIGlmKGZYUG9pbnRlclNjaGVtYSA9PSBudWxsKXsKLSAgICAgICAgICAgIGZDb3VudFNjaGVtYU5hbWUgPSArK2k7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotCi0gICAgICAgIGludCBmc2NoZW1hbGVuZ3RoID0gZlhQb2ludGVyU2NoZW1hLmxlbmd0aDsKLQotICAgICAgICBmb3IoO2ZTY2hlbWFQb2ludGVyTmFtZVtpXSAhPSBudWxsOyBpKyspewotICAgICAgICAgICAgZm9yKGludCBqPTA7IGo8ZnNjaGVtYWxlbmd0aDsgaisrICl7Ci0gICAgICAgICAgICAgICAgaWYoZlNjaGVtYVBvaW50ZXJOYW1lW2ldLmVxdWFsc0lnbm9yZUNhc2UoZlhQb2ludGVyU2NoZW1hW2pdLmdldFhwb2ludGVyU2NoZW1hTmFtZSgpKSl7Ci0gICAgICAgICAgICAgICAgICAgIGZYUG9pbnRlclNjaGVtYVtqXS5zZXRYUG9pbnRlclNjaGVtYVBvaW50ZXIoZlNjaGVtYVBvaW50ZXJVUklbaV0pOwotICAgICAgICAgICAgICAgICAgICBmQ291bnRTY2hlbWFOYW1lID0gKytpOwotICAgICAgICAgICAgICAgICAgICByZXR1cm4gZlhQb2ludGVyU2NoZW1hW2pdOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYoZlNjaGVtYU5vdEF2YWlsYWJsZSA9PSBudWxsKQotICAgICAgICAgICAgZlNjaGVtYU5vdEF2YWlsYWJsZSA9IG5ldyBTdGFjaygpOwotCi0gICAgICAgICAgICBmU2NoZW1hTm90QXZhaWxhYmxlLnB1c2goZlNjaGVtYVBvaW50ZXJOYW1lW2ldKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgWFBvaW50ZXJTY2hlbWEgZ2V0RGVmYXVsdFNjaGVtYSgpewotICAgICAgICBpZihmRGVmYXVsdFhQb2ludGVyU2NoZW1hID09IG51bGwpCi0gICAgICAgICAgICBmRGVmYXVsdFhQb2ludGVyU2NoZW1hID0gbmV3IFhQb2ludGVyRWxlbWVudEhhbmRsZXIoKTsKLSAgICAgICAgcmV0dXJuIGZEZWZhdWx0WFBvaW50ZXJTY2hlbWE7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgZ2V0U2NoZW1hTmFtZXMoKXsKLSAgICAgICAgaW50IGNvdW50ID0wOwotICAgICAgICBpbnQgaW5kZXggPTAsIGxhc3RpbmRleCA9MDsKLSAgICAgICAgaW50IHNjaGVtYXBvaW50ZXJpbmRleCAgPTAsIHNjaGVtYXBvaW50ZXJVUklpbmRleD0wOwotICAgICAgICBjaGFyIGM7Ci0gICAgICAgIGludCBsZW5ndGggPSBmU2NoZW1hUG9pbnRlci5sZW5ndGgoKTsKLSAgICAgICAgZlNjaGVtYVBvaW50ZXJOYW1lID0gbmV3IFN0cmluZyBbNV07Ci0gICAgICAgIGZTY2hlbWFQb2ludGVyVVJJID0gbmV3IFN0cmluZyBbNV07Ci0KLSAgICAgICAgaW5kZXggPSBmU2NoZW1hUG9pbnRlci5pbmRleE9mKCcoJyk7Ci0gICAgICAgIGlmKCBpbmRleCA8PSAwKQotICAgICAgICAgICAgcmV0dXJuOwotCi0gICAgICAgIGZTY2hlbWFQb2ludGVyTmFtZVtzY2hlbWFwb2ludGVyaW5kZXgrK10gPSBmU2NoZW1hUG9pbnRlci5zdWJzdHJpbmcoMCwgaW5kZXgrKykudHJpbSgpOwotICAgICAgICBsYXN0aW5kZXggPSBpbmRleDsKLSAgICAgICAgU3RyaW5nIHRlbXBVUkkgPSBudWxsOwotICAgICAgICBjb3VudCsrOwotCi0gICAgICAgIHdoaWxlKGluZGV4IDwgbGVuZ3RoKXsKLSAgICAgICAgICAgIGMgPSBmU2NoZW1hUG9pbnRlci5jaGFyQXQoaW5kZXgpOwotICAgICAgICAgICAgaWYoYyA9PSAnKCcpCi0gICAgICAgICAgICAgICAgY291bnQrKzsKLSAgICAgICAgICAgIGlmKGMgPT0gJyknKQotICAgICAgICAgICAgICAgIGNvdW50LS07Ci0gICAgICAgICAgICBpZihjb3VudD09MCApewotICAgICAgICAgICAgICAgIHRlbXBVUkkgPSBmU2NoZW1hUG9pbnRlci5zdWJzdHJpbmcobGFzdGluZGV4LCBpbmRleCkudHJpbSgpOwotICAgICAgICAgICAgICAgIGZTY2hlbWFQb2ludGVyVVJJW3NjaGVtYXBvaW50ZXJVUklpbmRleCsrXSA9IGdldEVzY2FwZWRVUkkodGVtcFVSSSk7Ci0gICAgICAgICAgICAgICAgbGFzdGluZGV4ID0gaW5kZXg7Ci0gICAgICAgICAgICAgICAgaWYoKGluZGV4ID0gZlNjaGVtYVBvaW50ZXIuaW5kZXhPZignKCcsIGxhc3RpbmRleCkpICE9IC0xKXsKLSAgICAgICAgICAgICAgICAgICAgZlNjaGVtYVBvaW50ZXJOYW1lW3NjaGVtYXBvaW50ZXJpbmRleCsrXSA9IGZTY2hlbWFQb2ludGVyLnN1YnN0cmluZyhsYXN0aW5kZXgrMSwgaW5kZXgpLnRyaW0oKTsKLSAgICAgICAgICAgICAgICAgICAgY291bnQrKzsKLSAgICAgICAgICAgICAgICAgICAgbGFzdGluZGV4ID0gaW5kZXgrMTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZXsKLSAgICAgICAgICAgICAgICAgICAgaW5kZXggPSBsYXN0aW5kZXg7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgaW5kZXgrKzsKLSAgICAgICAgfQotICAgICAgICBzY2hlbWFMZW5ndGggPSBzY2hlbWFwb2ludGVyVVJJaW5kZXggLTE7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyAgIGdldEVzY2FwZWRVUkkoU3RyaW5nIFVSSSl7Ci0gICAgICAgIHJldHVybiBVUkk7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBnZXRTY2hlbWFDb3VudCgpewotICAgICAgICByZXR1cm4gc2NoZW1hTGVuZ3RoOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgZ2V0Q3VycmVudFBvaW50ZXIoKXsKLSAgICAgICAgcmV0dXJuIGZDb3VudFNjaGVtYU5hbWU7Ci0gICAgfQotCi19Ly9YUG9pbnRlckZyYW13b3JrCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94aW5jbHVkZS9YUG9pbnRlclNjaGVtYS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveGluY2x1ZGUvWFBvaW50ZXJTY2hlbWEuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggM2I0ZDU4NS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94aW5jbHVkZS9YUG9pbnRlclNjaGVtYS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDUgKzAsMCBAQAotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhpbmNsdWRlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxDb21wb25lbnQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTERvY3VtZW50RmlsdGVyOwotCi0KLQotcHVibGljIGludGVyZmFjZSBYUG9pbnRlclNjaGVtYSBleHRlbmRzIFhNTENvbXBvbmVudCwgWE1MRG9jdW1lbnRGaWx0ZXJ7Ci0KLSAgICAvKioKLSAgICAgKiBzZXQgdGhlIFNjaGVtYSBOYW1lICBlZyBlbGVtZW50ICwgeHBvaW50ZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRYUG9pbnRlclNjaGVtYU5hbWUoU3RyaW5nIHNjaGVtYU5hbWUpOwotCi0gICAgLyoqCi0gICAgICogUmV0dXJuICBTY2hlbWEgTmFtZSAgZWcgZWxlbWVudCAsIHhwb2ludGVyCi0gICAgICoKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFhwb2ludGVyU2NoZW1hTmFtZSgpOwotCi0gICAgLyoqCi0gICAgICogUGFyZW50IENvbnRlbmhhbmRsZXIgZm9yIHRoZSB0aGlzIGNvbnRlbnRoYW5kbGVyLgotICAgICAqIC8vIG5vdCBzdXJlIGFib3V0IHRoZSBwYXJhbWV0ZXIgdHlwZS4gSXQgY2FuIGJlIENvbnRlbnRoYW5kbGVyIGluc3RlYWQgb2YgT2JqZWN0IHR5cGUuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0UGFyZW50KE9iamVjdCBwYXJlbnQpOwotCi0gICAgLyoqCi0gICAgICogcmV0dXJuIHRoZSBQYXJlbnQgQ29udGVudGhhbmRsZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0IGdldFBhcmVudCgpOwotCi0gICAgLyoqCi0gICAgICogQ29udGVudCBvZiB0aGUgWFBvaW50ZXIgU2NoZW1hLiBYcGF0aCB0byBiZSByZXNvbHZlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRYUG9pbnRlclNjaGVtYVBvaW50ZXIoU3RyaW5nIGNvbnRlbnQpOwotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSBYUG9pbnRlciBTY2hlbWEuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRYUG9pbnRlclNjaGVtYVBvaW50ZXIoKTsKLQotICAgIHB1YmxpYyBib29sZWFuIGlzU3ViUmVzb3VyY2VJbmRlbnRpZmllZCgpOwotCi0gICAgcHVibGljIHZvaWQgcmVzZXQoKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveG5pL0F1Z21lbnRhdGlvbnMuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3huaS9BdWdtZW50YXRpb25zLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDBhNDM3ZTIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveG5pL0F1Z21lbnRhdGlvbnMuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDg5ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDAtMjAwMiwyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaTsKLQotaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKLQotLyoqCi0gKiBUaGUgQXVnbWVudGF0aW9ucyBpbnRlcmZhY2UgZGVmaW5lcyBhIHRhYmxlIG9mIGFkZGl0aW9uYWwgZGF0YSB0aGF0IG1heQotICogYmUgcGFzc2VkIGFsb25nIHRoZSBkb2N1bWVudCBwaXBlbGluZS4gVGhlIGluZm9ybWF0aW9uIGNhbiBjb250YWluIGV4dHJhCi0gKiBhcmd1bWVudHMgb3IgaW5mb3NldCBhdWdtZW50YXRpb25zLCBmb3IgZXhhbXBsZSBQU1ZJLiBUaGlzIGFkZGl0aW9uYWwKLSAqIGluZm9ybWF0aW9uIGlzIGlkZW50aWZpZWQgYnkgYSBTdHJpbmcga2V5LgotICogPHA+Ci0gKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+Ci0gKiBNZXRob2RzIHRoYXQgcmVjZWl2ZSBBdWdtZW50YXRpb25zIGFyZSByZXF1aXJlZCB0byBjb3B5IHRoZSBpbmZvcm1hdGlvbgotICogaWYgaXQgaXMgdG8gYmUgc2F2ZWQgZm9yIHVzZSBiZXlvbmQgdGhlIHNjb3BlIG9mIHRoZSBtZXRob2QuCi0gKiBUaGUgQXVnbWVudGF0aW9ucyBjb250ZW50IGlzIHZvbGF0aWxlLCBhbmQgbWF5YmUgbW9kaWZpZWQgYnkgYW55IG1ldGhvZCBpbgotICogYW55IGNvbXBvbmVudCBpbiB0aGUgcGlwZWxpbmUuIFRoZXJlZm9yZSwgbWV0aG9kcyBwYXNzZWQgdGhpcyBzdHJ1Y3R1cmUKLSAqIHNob3VsZCBub3Qgc2F2ZSBhbnkgcmVmZXJlbmNlIHRvIHRoZSBzdHJ1Y3R1cmUuCi0gKgotICogQGF1dGhvciBFbGVuYSBMaXRhbmksIElCTQotICovCi0KLXB1YmxpYyBpbnRlcmZhY2UgQXVnbWVudGF0aW9ucyB7Ci0KLQotICAgIC8qKgotICAgICAqIEFkZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIGlkZW50aWZpZWQgYnkgYSBrZXkgdG8gdGhlIEF1Z21lbnRhdGlvbnMgc3RydWN0dXJlLgotICAgICAqCi0gICAgICogQHBhcmFtIGtleSAgICBJZGVudGlmaWVyLCBjYW4ndCBiZSA8Y29kZT5udWxsPC9jb2RlPgotICAgICAqIEBwYXJhbSBpdGVtICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbgotICAgICAqCi0gICAgICogQHJldHVybiB0aGUgcHJldmlvdXMgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBrZXkgaW4gdGhlIEF1Z21lbnRhdGlvbnMgc3RydWN0dXJlLAotICAgICAqICAgICAgICAgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgaXQgZGlkIG5vdCBoYXZlIG9uZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0IHB1dEl0ZW0gKFN0cmluZyBrZXksIE9iamVjdCBpdGVtKTsKLQotCi0gICAgLyoqCi0gICAgICogR2V0IGluZm9ybWF0aW9uIGlkZW50aWZpZWQgYnkgYSBrZXkgZnJvbSB0aGUgQXVnbWVudGF0aW9ucyBzdHJ1Y3R1cmUKLSAgICAgKgotICAgICAqIEBwYXJhbSBrZXkgICAgSWRlbnRpZmllciwgY2FuJ3QgYmUgPGNvZGU+bnVsbDwvY29kZT4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIHRvIHdoaWNoIHRoZSBrZXkgaXMgbWFwcGVkIGluIHRoZSBBdWdtZW50YXRpb25zIHN0cnVjdHVyZTsKLSAgICAgKiAgICAgICAgIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoZSBrZXkgaXMgbm90IG1hcHBlZCB0byBhbnkgdmFsdWUuCi0gICAgICovCi0gICAgcHVibGljIE9iamVjdCBnZXRJdGVtKFN0cmluZyBrZXkpOwotCi0KLSAgICAvKioKLSAgICAgKiBSZW1vdmUgYWRkaXRpb25hbCBpbmZvIGZyb20gdGhlIEF1Z21lbnRhdGlvbnMgc3RydWN0dXJlCi0gICAgICoKLSAgICAgKiBAcGFyYW0ga2V5ICAgIElkZW50aWZpZXIsIGNhbid0IGJlIDxjb2RlPm51bGw8L2NvZGU+Ci0gICAgICogQHJldHVybiB0aGUgcHJldmlvdXMgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBrZXkgaW4gdGhlIEF1Z21lbnRhdGlvbnMgc3RydWN0dXJlLAotICAgICAqICAgICAgICAgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgaXQgZGlkIG5vdCBoYXZlIG9uZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0IHJlbW92ZUl0ZW0gKFN0cmluZyBrZXkpOwotCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGFuIGVudW1lcmF0aW9uIG9mIHRoZSBrZXlzIGluIHRoZSBBdWdtZW50YXRpb25zIHN0cnVjdHVyZQotICAgICAqCi0gICAgICovCi0gICAgcHVibGljIEVudW1lcmF0aW9uIGtleXMgKCk7Ci0KLQotICAgIC8qKgotICAgICAqIFJlbW92ZSBhbGwgb2JqZWN0cyBmcm9tIHRoZSBBdWdtZW50YXRpb25zIHN0cnVjdHVyZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCByZW1vdmVBbGxJdGVtcyAoKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveG5pL05hbWVzcGFjZUNvbnRleHQuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3huaS9OYW1lc3BhY2VDb250ZXh0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDkxYjg1ZDUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveG5pL05hbWVzcGFjZUNvbnRleHQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE3OSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLCAyMDAyLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pOwotCi1pbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOwotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLS8qKgotICogUmVwcmVzZW50cyBhbiBpbnRlcmZhY2UgdG8gcXVlcnkgbmFtZXNwYWNlIGluZm9ybWF0aW9uLgotICogPHA+Ci0gKiBUaGUgcHJlZml4IGFuZCBuYW1lc3BhY2UgbXVzdCBiZSBpZGVudGljYWwgcmVmZXJlbmNlcyBmb3IgZXF1YWwgc3RyaW5ncywgdGh1cwotICogZWFjaCBzdHJpbmcgc2hvdWxkIGJlIGludGVybmFsaXplZCAoQHNlZSBTdHJpbmcuaW50ZXJuKCkpCi0gKiBvciBhZGRlZCB0byB0aGUgPGNvZGU+U3ltYm9sVGFibGU8L2NvZGU+Ci0gKgotICogQHNlZSA8YSBocmVmPSIuLi8uLi8uLi8uLi8uLi94ZXJjZXMyL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9TeW1ib2xUYWJsZS5odG1sIj4KLSAqIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5TeW1ib2xUYWJsZTwvYT4KLSAqCi0gKiBAYXV0aG9yIEFuZHkgQ2xhcmssIElCTQotICoKLSAqLwotcHVibGljIGludGVyZmFjZSBOYW1lc3BhY2VDb250ZXh0IHsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RhbnRzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFRoZSBYTUwgTmFtZXNwYWNlICgiaHR0cDovL3d3dy53My5vcmcvWE1MLzE5OTgvbmFtZXNwYWNlIikuIFRoaXMgaXMKLSAgICAgKiB0aGUgTmFtZXNwYWNlIFVSSSB0aGF0IGlzIGF1dG9tYXRpY2FsbHkgbWFwcGVkIHRvIHRoZSAieG1sIiBwcmVmaXguCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIHN0YXRpYyBTdHJpbmcgWE1MX1VSSSA9ICJodHRwOi8vd3d3LnczLm9yZy9YTUwvMTk5OC9uYW1lc3BhY2UiLmludGVybigpOwotCi0gICAgLyoqCi0gICAgICogWE1MIEluZm9ybWF0aW9uIFNldCBSRUMKLSAgICAgKiBhbGwgbmFtZXNwYWNlIGF0dHJpYnV0ZXMgKGluY2x1ZGluZyB0aG9zZSBuYW1lZCB4bWxucywKLSAgICAgKiB3aG9zZSBbcHJlZml4XSBwcm9wZXJ0eSBoYXMgbm8gdmFsdWUpIGhhdmUgYSBuYW1lc3BhY2UgVVJJIG9mIGh0dHA6Ly93d3cudzMub3JnLzIwMDAveG1sbnMvCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIHN0YXRpYyBTdHJpbmcgWE1MTlNfVVJJID0gImh0dHA6Ly93d3cudzMub3JnLzIwMDAveG1sbnMvIi5pbnRlcm4oKTsKLQotICAgIC8vCi0gICAgLy8gTmFtZXNwYWNlQ29udGV4dCBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFN0YXJ0IGEgbmV3IE5hbWVzcGFjZSBjb250ZXh0LgotICAgICAqIDxwPgotICAgICAqIEEgbmV3IGNvbnRleHQgc2hvdWxkIGJlIHB1c2hlZCBhdCB0aGUgYmVnaW5uaW5nCi0gICAgICogb2YgZWFjaCBYTUwgZWxlbWVudDogdGhlIG5ldyBjb250ZXh0IHdpbGwgYXV0b21hdGljYWxseSBpbmhlcml0Ci0gICAgICogdGhlIGRlY2xhcmF0aW9ucyBvZiBpdHMgcGFyZW50IGNvbnRleHQsIGJ1dCBpdCB3aWxsIGFsc28ga2VlcAotICAgICAqIHRyYWNrIG9mIHdoaWNoIGRlY2xhcmF0aW9ucyB3ZXJlIG1hZGUgd2l0aGluIHRoaXMgY29udGV4dC4KLSAgICAgKiA8cD4KLSAgICAgKgotICAgICAqIEBzZWUgI3BvcENvbnRleHQKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBwdXNoQ29udGV4dCgpOwotCi0gICAvKioKLSAgICAgKiBSZXZlcnQgdG8gdGhlIHByZXZpb3VzIE5hbWVzcGFjZSBjb250ZXh0LgotICAgICAqIDxwPgotICAgICAqIFRoZSBjb250ZXh0IHNob3VsZCBiZSBwb3BwZWQgYXQgdGhlIGVuZCBvZiBlYWNoCi0gICAgICogWE1MIGVsZW1lbnQuICBBZnRlciBwb3BwaW5nIHRoZSBjb250ZXh0LCBhbGwgTmFtZXNwYWNlIHByZWZpeAotICAgICAqIG1hcHBpbmdzIHRoYXQgd2VyZSBwcmV2aW91c2x5IGluIGZvcmNlIGFyZSByZXN0b3JlZC4KLSAgICAgKiA8cD4KLSAgICAgKiBVc2VycyBtdXN0IG5vdCBhdHRlbXB0IHRvIGRlY2xhcmUgYWRkaXRpb25hbCBOYW1lc3BhY2UKLSAgICAgKiBwcmVmaXhlcyBhZnRlciBwb3BwaW5nIGEgY29udGV4dCwgdW5sZXNzIHlvdSBwdXNoIGFub3RoZXIKLSAgICAgKiBjb250ZXh0IGZpcnN0LgotICAgICAqCi0gICAgICogQHNlZSAjcHVzaENvbnRleHQKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBwb3BDb250ZXh0KCk7Ci0KLSAgICAvKioKLSAgICAgKiBEZWNsYXJlIGEgTmFtZXNwYWNlIHByZWZpeC4KLSAgICAgKiA8cD4KLSAgICAgKiBUaGlzIG1ldGhvZCBkZWNsYXJlcyBhIHByZWZpeCBpbiB0aGUgY3VycmVudCBOYW1lc3BhY2UKLSAgICAgKiBjb250ZXh0OyB0aGUgcHJlZml4IHdpbGwgcmVtYWluIGluIGZvcmNlIHVudGlsIHRoaXMgY29udGV4dAotICAgICAqIGlzIHBvcHBlZCwgdW5sZXNzIGl0IGlzIHNoYWRvd2VkIGluIGEgZGVzY2VuZGFudCBjb250ZXh0LgotICAgICAqIDxwPgotICAgICAqIE5vdGUgdGhhdCB0byBkZWNsYXJlIGEgZGVmYXVsdCBOYW1lc3BhY2UsIHVzZSB0aGUgZW1wdHkgc3RyaW5nLgotICAgICAqIFRoZSBwcmVmaXhlcyAieG1sIiBhbmQgInhtbG5zIiBjYW4ndCBiZSByZWJvdW5kLgotICAgICAqIDxwPgotICAgICAqIE5vdGUgdGhhdCB5b3UgbXVzdCA8ZW0+bm90PC9lbT4gZGVjbGFyZSBhIHByZWZpeCBhZnRlcgotICAgICAqIHlvdSd2ZSBwdXNoZWQgYW5kIHBvcHBlZCBhbm90aGVyIE5hbWVzcGFjZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBwcmVmaXggVGhlIHByZWZpeCB0byBkZWNsYXJlLCBvciBudWxsIGZvciB0aGUgZW1wdHkKLSAgICAgKiAgICAgICAgc3RyaW5nLgotICAgICAqIEBwYXJhbSB1cmkgVGhlIE5hbWVzcGFjZSBVUkkgdG8gYXNzb2NpYXRlIHdpdGggdGhlIHByZWZpeC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgcHJlZml4IHdhcyBsZWdhbCwgZmFsc2Ugb3RoZXJ3aXNlCi0gICAgICoKLSAgICAgKiBAc2VlICNnZXRVUkkKLSAgICAgKiBAc2VlICNnZXREZWNsYXJlZFByZWZpeEF0Ci0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZGVjbGFyZVByZWZpeChTdHJpbmcgcHJlZml4LCBTdHJpbmcgdXJpKTsKLQotCi0gICAgLyoqCi0gICAgICogTG9vayB1cCBhIHByZWZpeCBhbmQgZ2V0IHRoZSBjdXJyZW50bHktbWFwcGVkIE5hbWVzcGFjZSBVUkkuCi0gICAgICogPHA+Ci0gICAgICogVGhpcyBtZXRob2QgbG9va3MgdXAgdGhlIHByZWZpeCBpbiB0aGUgY3VycmVudCBjb250ZXh0LiBJZiBubyBtYXBwaW5nCi0gICAgICogaXMgZm91bmQsIHRoaXMgbWV0aG9kcyB3aWxsIGNvbnRpbnVlIGxvb2t1cCBpbiB0aGUgcGFyZW50IGNvbnRleHQocykuCi0gICAgICogVXNlIHRoZSBlbXB0eSBzdHJpbmcgKCIiKSBmb3IgdGhlIGRlZmF1bHQgTmFtZXNwYWNlLgotICAgICAqCi0gICAgICogQHBhcmFtIHByZWZpeCBUaGUgcHJlZml4IHRvIGxvb2sgdXAuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBhc3NvY2lhdGVkIE5hbWVzcGFjZSBVUkksIG9yIG51bGwgaWYgdGhlIHByZWZpeAotICAgICAqICAgICAgICAgaXMgdW5kZWNsYXJlZCBpbiB0aGlzIGNvbnRleHQuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRVUkkoU3RyaW5nIHByZWZpeCk7Ci0KLSAgICAvKioKLSAgICAgKiBMb29rIHVwIGEgbmFtZXNwYWNlIFVSSSBhbmQgZ2V0IG9uZSBvZiB0aGUgbWFwcGVkIHByZWZpeC4KLSAgICAgKiA8cD4KLSAgICAgKiBUaGlzIG1ldGhvZCBsb29rcyB1cCB0aGUgbmFtZXNwYWNlIFVSSSBpbiB0aGUgY3VycmVudCBjb250ZXh0LgotICAgICAqIElmIG1vcmUgdGhhbiBvbmUgcHJlZml4IGlzIGN1cnJlbnRseSBtYXBwZWQgdG8gdGhlIHNhbWUgVVJJLAotICAgICAqIHRoaXMgbWV0aG9kIHdpbGwgbWFrZSBhbiBhcmJpdHJhcnkgc2VsZWN0aW9uCi0gICAgICogSWYgbm8gbWFwcGluZyBpcyBmb3VuZCwgdGhpcyBtZXRob2RzIHdpbGwgY29udGludWUgbG9va3VwIGluIHRoZQotICAgICAqIHBhcmVudCBjb250ZXh0KHMpLgotICAgICAqCi0gICAgICogQHBhcmFtIHVyaSBUaGUgbmFtZXNwYWNlIFVSSSB0byBsb29rIHVwLgotICAgICAqCi0gICAgICogQHJldHVybiBPbmUgb2YgdGhlIGFzc29jaWF0ZWQgcHJlZml4ZXMsIG9yIG51bGwgaWYgdGhlIHVyaQotICAgICAqICAgICAgICAgZG9lcyBub3QgbWFwIHRvIGFueSBwcmVmaXguCi0gICAgICoKLSAgICAgKiBAc2VlICNnZXRQcmVmaXgKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFByZWZpeChTdHJpbmcgdXJpKTsKLQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIGEgY291bnQgb2YgbG9jYWxseSBkZWNsYXJlZCBwcmVmaXhlcywgaW5jbHVkaW5nCi0gICAgICogdGhlIGRlZmF1bHQgcHJlZml4IGlmIGJvdW5kLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0RGVjbGFyZWRQcmVmaXhDb3VudCgpOwotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgcHJlZml4IGF0IHRoZSBzcGVjaWZpZWQgaW5kZXggaW4gdGhlIGN1cnJlbnQgY29udGV4dC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldERlY2xhcmVkUHJlZml4QXQoaW50IGluZGV4KTsKLQotICAgICAgICAvKioKLSAgICAgICAgICogUmV0dXJuIGFuIGVudW1lcmF0aW9uIG9mIGFsbCBwcmVmaXhlcyB3aG9zZSBkZWNsYXJhdGlvbnMgYXJlIGFjdGl2ZQotICAgICAqIGluIHRoZSBjdXJyZW50IGNvbnRleHQuIFRoaXMgaW5jbHVkZXMgZGVjbGFyYXRpb25zIGZyb20gcGFyZW50IGNvbnRleHRzCi0gICAgICogdGhhdCBoYXZlIG5vdCBiZWVuIG92ZXJyaWRkZW4uCi0gICAgICAgICAqIEByZXR1cm4gRW51bWVyYXRpb24KLSAgICAgICAgICovCi0gICAgcHVibGljIEVudW1lcmF0aW9uIGdldEFsbFByZWZpeGVzKCk7Ci0KLSAgICAvKioKLSAgICAgKiBSZXNldCB0aGlzIE5hbWVzcGFjZSBzdXBwb3J0IG9iamVjdCBmb3IgcmV1c2UuCi0gICAgICoKLSAgICAgKiA8cD5JdCBpcyBuZWNlc3NhcnkgdG8gaW52b2tlIHRoaXMgbWV0aG9kIGJlZm9yZSByZXVzaW5nIHRoZQotICAgICAqIE5hbWVzcGFjZSBzdXBwb3J0IG9iamVjdCBmb3IgYSBuZXcgc2Vzc2lvbi48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5Ob3RlIHRoYXQgaW1wbGVtZW50YXRpb25zIG9mIHRoaXMgbWV0aG9kIG5lZWQgdG8gZW5zdXJlIHRoYXQKLSAgICAgKiB0aGUgZGVjbGFyYXRpb24gb2YgdGhlIHByZWZpeGVzICJ4bWxucyIgYW5kICJ4bWwiIGFyZSBhdmFpbGFibGUuPC9wPgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHJlc2V0KCk7Ci0KLQotfSAvLyBpbnRlcmZhY2UgTmFtZXNwYWNlQ29udGV4dApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveG5pL1FOYW1lLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94bmkvUU5hbWUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNWM0N2I3YS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94bmkvUU5hbWUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI0MyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAwLTIwMDIgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYZXJjZXMiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIEludGVybmF0aW9uYWwKLSAqIEJ1c2luZXNzIE1hY2hpbmVzLCBJbmMuLCBodHRwOi8vd3d3LmFwYWNoZS5vcmcuICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaTsKLQotLyoqCi0gKiBBIHN0cnVjdHVyZSB0aGF0IGhvbGRzIHRoZSBjb21wb25lbnRzIG9mIGFuIFhNTCBOYW1lc3BhY2VzIHF1YWxpZmllZAotICogbmFtZS4KLSAqIDxwPgotICogVG8gYmUgdXNlZCBjb3JyZWN0bHksIHRoZSBzdHJpbmdzIG11c3QgYmUgaWRlbnRpY2FsIHJlZmVyZW5jZXMgZm9yCi0gKiBlcXVhbCBzdHJpbmdzLiBXaXRoaW4gdGhlIHBhcnNlciwgdGhlc2UgdmFsdWVzIGFyZSBjb25zaWRlcmVkIHN5bWJvbHMKLSAqIGFuZCBzaG91bGQgYWx3YXlzIGJlIHJldHJpZXZlZCBmcm9tIHRoZSA8Y29kZT5TeW1ib2xUYWJsZTwvY29kZT4uCi0gKgotICogQHNlZSA8YSBocmVmPSIuLi8uLi8uLi8uLi8uLi94ZXJjZXMyL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwvdXRpbC9TeW1ib2xUYWJsZS5odG1sIj5jb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuU3ltYm9sVGFibGU8L2E+Ci0gKgotICogQGF1dGhvciBBbmR5IENsYXJrLCBJQk0KLSAqCi0gKiBCZXR0ZXIgcGVyZm9ybWFuY2UgcGF0Y2ggZm9yIHRoZSBlcXVhbHMgbWV0aG9kIGJ5IERhbmllbCBQZXRlcnNzb246IHJlZmVyIHRvIGpheHAgaXNzdWUgNjE7Ci0gKiA9PSB3ZXJlIHVzZWQgdG8gY29tcGFyZSBzdHJpbmdzCi0gKiBAYXV0aG9yIEpvZSBXYW5nLCBPcmFjbGUKLSAqCi0gKiBAdmVyc2lvbiAkSWQ6IFFOYW1lLmphdmEsdiAxLjYgMjAxMC8wMy8xOCAxOTozMjozMSBqb2VodyBFeHAgJAotICovCi1wdWJsaWMgY2xhc3MgUU5hbWUKLWltcGxlbWVudHMgQ2xvbmVhYmxlIHsKLQotCi0gICAgLyoqCi0gICAgICogVGhlIHFuYW1lIHByZWZpeC4gRm9yIGV4YW1wbGUsIHRoZSBwcmVmaXggZm9yIHRoZSBxbmFtZSAiYTpmb28iCi0gICAgICogaXMgImEiLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgcHJlZml4OwotCi0gICAgLyoqCi0gICAgICogVGhlIHFuYW1lIGxvY2FscGFydC4gRm9yIGV4YW1wbGUsIHRoZSBsb2NhbHBhcnQgZm9yIHRoZSBxbmFtZSAiYTpmb28iCi0gICAgICogaXMgImZvbyIuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBsb2NhbHBhcnQ7Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgcW5hbWUgcmF3bmFtZS4gRm9yIGV4YW1wbGUsIHRoZSByYXduYW1lIGZvciB0aGUgcW5hbWUgImE6Zm9vIgotICAgICAqIGlzICJhOmZvbyIuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyByYXduYW1lOwotCi0gICAgLyoqCi0gICAgICogVGhlIFVSSSB0byB3aGljaCB0aGUgcW5hbWUgcHJlZml4IGlzIGJvdW5kLiBUaGlzIGJpbmRpbmcgbXVzdCBiZQotICAgICAqIHBlcmZvcm1lZCBieSBhIFhNTCBOYW1lc3BhY2VzIGF3YXJlIHByb2Nlc3Nvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIHVyaTsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKiBEZWZhdWx0IGNvbnN0cnVjdG9yLiAqLwotICAgIHB1YmxpYyBRTmFtZSgpIHsKLSAgICAgICAgY2xlYXIoKTsKLSAgICB9IC8vIDxpbml0PigpCi0KLSAgICAvKiogQ29uc3RydWN0cyBhIFFOYW1lIHdpdGggdGhlIHNwZWNpZmllZCB2YWx1ZXMuICovCi0gICAgcHVibGljIFFOYW1lKFN0cmluZyBwcmVmaXgsIFN0cmluZyBsb2NhbHBhcnQsIFN0cmluZyByYXduYW1lLCBTdHJpbmcgdXJpKSB7Ci0gICAgICAgIHNldFZhbHVlcyhwcmVmaXgsIGxvY2FscGFydCwgcmF3bmFtZSwgdXJpKTsKLSAgICB9IC8vIDxpbml0PihTdHJpbmcsU3RyaW5nLFN0cmluZyxTdHJpbmcpCi0KLSAgICAvKiogQ29uc3RydWN0cyBhIGNvcHkgb2YgdGhlIHNwZWNpZmllZCBRTmFtZS4gKi8KLSAgICBwdWJsaWMgUU5hbWUoUU5hbWUgcW5hbWUpIHsKLSAgICAgICAgc2V0VmFsdWVzKHFuYW1lKTsKLSAgICB9IC8vIDxpbml0PihRTmFtZSkKLQotICAgIC8vCi0gICAgLy8gUHVibGljIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogQ29udmVuaWVuY2UgbWV0aG9kIHRvIHNldCB0aGUgdmFsdWVzIG9mIHRoZSBxbmFtZSBjb21wb25lbnRzLgotICAgICAqCi0gICAgICogQHBhcmFtIFFOYW1lIFRoZSBxdWFsaWZpZWQgbmFtZSB0byBiZSBjb3BpZWQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0VmFsdWVzKFFOYW1lIHFuYW1lKSB7Ci0gICAgICAgIHByZWZpeCA9IHFuYW1lLnByZWZpeDsKLSAgICAgICAgbG9jYWxwYXJ0ID0gcW5hbWUubG9jYWxwYXJ0OwotICAgICAgICByYXduYW1lID0gcW5hbWUucmF3bmFtZTsKLSAgICAgICAgdXJpID0gcW5hbWUudXJpOwotICAgIH0gLy8gc2V0VmFsdWVzKFFOYW1lKQotCi0gICAgLyoqCi0gICAgICogQ29udmVuaWVuY2UgbWV0aG9kIHRvIHNldCB0aGUgdmFsdWVzIG9mIHRoZSBxbmFtZSBjb21wb25lbnRzLgotICAgICAqCi0gICAgICogQHBhcmFtIHByZWZpeCAgICBUaGUgcW5hbWUgcHJlZml4LiAoZS5nLiAiYSIpCi0gICAgICogQHBhcmFtIGxvY2FscGFydCBUaGUgcW5hbWUgbG9jYWxwYXJ0LiAoZS5nLiAiZm9vIikKLSAgICAgKiBAcGFyYW0gcmF3bmFtZSAgIFRoZSBxbmFtZSByYXduYW1lLiAoZS5nLiAiYTpmb28iKQotICAgICAqIEBwYXJhbSB1cmkgICAgICAgVGhlIFVSSSBiaW5kaW5nLiAoZS5nLiAiaHR0cDovL2Zvby5jb20vbXliaW5kaW5nIikKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRWYWx1ZXMoU3RyaW5nIHByZWZpeCwgU3RyaW5nIGxvY2FscGFydCwgU3RyaW5nIHJhd25hbWUsCi0gICAgU3RyaW5nIHVyaSkgewotICAgICAgICB0aGlzLnByZWZpeCA9IHByZWZpeDsKLSAgICAgICAgdGhpcy5sb2NhbHBhcnQgPSBsb2NhbHBhcnQ7Ci0gICAgICAgIHRoaXMucmF3bmFtZSA9IHJhd25hbWU7Ci0gICAgICAgIHRoaXMudXJpID0gdXJpOwotICAgIH0gLy8gc2V0VmFsdWVzKFN0cmluZyxTdHJpbmcsU3RyaW5nLFN0cmluZykKLQotICAgIC8qKiBDbGVhcnMgdGhlIHZhbHVlcyBvZiB0aGUgcW5hbWUgY29tcG9uZW50cy4gKi8KLSAgICBwdWJsaWMgdm9pZCBjbGVhcigpIHsKLSAgICAgICAgcHJlZml4ID0gbnVsbDsKLSAgICAgICAgbG9jYWxwYXJ0ID0gbnVsbDsKLSAgICAgICAgcmF3bmFtZSA9IG51bGw7Ci0gICAgICAgIHVyaSA9IG51bGw7Ci0gICAgfSAvLyBjbGVhcigpCi0KLSAgICAvLwotICAgIC8vIENsb25lYWJsZSBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKiBSZXR1cm5zIGEgY2xvbmUgb2YgdGhpcyBvYmplY3QuICovCi0gICAgcHVibGljIE9iamVjdCBjbG9uZSgpIHsKLSAgICAgICAgcmV0dXJuIG5ldyBRTmFtZSh0aGlzKTsKLSAgICB9IC8vIGNsb25lKCk6T2JqZWN0Ci0KLSAgICAvLwotICAgIC8vIE9iamVjdCBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKiBSZXR1cm5zIHRoZSBoYXNoY29kZSBmb3IgdGhpcyBvYmplY3QuICovCi0gICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKLSAgICAgICAgaWYgKHVyaSAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gdXJpLmhhc2hDb2RlKCkgKwotICAgICAgICAgICAgICAgICgobG9jYWxwYXJ0ICE9IG51bGwpID8gbG9jYWxwYXJ0Lmhhc2hDb2RlKCkgOiAwKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gKHJhd25hbWUgIT0gbnVsbCkgPyByYXduYW1lLmhhc2hDb2RlKCkgOiAwOwotICAgIH0gLy8gaGFzaENvZGUoKTppbnQKLQotICAgIC8qKiBSZXR1cm5zIHRydWUgaWYgdGhlIHR3byBvYmplY3RzIGFyZSBlcXVhbC4gKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iamVjdCkgewotICAgICAgICBpZiAob2JqZWN0ID09IHRoaXMpIHsKLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKG9iamVjdCAhPSBudWxsICYmIG9iamVjdCBpbnN0YW5jZW9mIFFOYW1lKSB7Ci0gICAgICAgICAgICBRTmFtZSBxbmFtZSA9IChRTmFtZSlvYmplY3Q7Ci0gICAgICAgICAgICBpZiAocW5hbWUudXJpICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHFuYW1lLmxvY2FscGFydC5lcXVhbHMobG9jYWxwYXJ0KSAmJiBxbmFtZS51cmkuZXF1YWxzKHVyaSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmICh1cmkgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJldHVybiByYXduYW1lLmVxdWFscyhxbmFtZS5yYXduYW1lKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIGZhbGwgdGhyb3VnaCBhbmQgcmV0dXJuIG5vdCBlcXVhbAotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9IC8vIGVxdWFscyhPYmplY3QpOmJvb2xlYW4KLQotICAgIC8qKiBSZXR1cm5zIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgb2JqZWN0LiAqLwotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0KLSAgICAgICAgU3RyaW5nQnVmZmVyIHN0ciA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLSAgICAgICAgYm9vbGVhbiBjb21tYSA9IGZhbHNlOwotICAgICAgICBpZiAocHJlZml4ICE9IG51bGwpIHsKLSAgICAgICAgICAgIHN0ci5hcHBlbmQoInByZWZpeD1cIiIrcHJlZml4KyciJyk7Ci0gICAgICAgICAgICBjb21tYSA9IHRydWU7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGxvY2FscGFydCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAoY29tbWEpIHsKLSAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKCcsJyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBzdHIuYXBwZW5kKCJsb2NhbHBhcnQ9XCIiK2xvY2FscGFydCsnIicpOwotICAgICAgICAgICAgY29tbWEgPSB0cnVlOwotICAgICAgICB9Ci0gICAgICAgIGlmIChyYXduYW1lICE9IG51bGwpIHsKLSAgICAgICAgICAgIGlmIChjb21tYSkgewotICAgICAgICAgICAgICAgIHN0ci5hcHBlbmQoJywnKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHN0ci5hcHBlbmQoInJhd25hbWU9XCIiK3Jhd25hbWUrJyInKTsKLSAgICAgICAgICAgIGNvbW1hID0gdHJ1ZTsKLSAgICAgICAgfQotICAgICAgICBpZiAodXJpICE9IG51bGwpIHsKLSAgICAgICAgICAgIGlmIChjb21tYSkgewotICAgICAgICAgICAgICAgIHN0ci5hcHBlbmQoJywnKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHN0ci5hcHBlbmQoInVyaT1cIiIrdXJpKyciJyk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHN0ci50b1N0cmluZygpOwotCi0gICAgfSAvLyB0b1N0cmluZygpOlN0cmluZwotCi19IC8vIGNsYXNzIFFOYW1lCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94bmkvWE1MQXR0cmlidXRlcy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveG5pL1hNTEF0dHJpYnV0ZXMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNGQ0YjkzYS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94bmkvWE1MQXR0cmlidXRlcy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDM5ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDAtMjAwMiBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhlcmNlcyIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgSW50ZXJuYXRpb25hbAotICogQnVzaW5lc3MgTWFjaGluZXMsIEluYy4sIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pOwotCi0vKioKLSAqIFRoZSBYTUxBdHRyaWJ1dGVzIGludGVyZmFjZSBkZWZpbmVzIGEgY29sbGVjdGlvbiBvZiBhdHRyaWJ1dGVzIGZvcgotICogYW4gZWxlbWVudC4gSW4gdGhlIHBhcnNlciwgdGhlIGRvY3VtZW50IHNvdXJjZSB3b3VsZCBzY2FuIHRoZSBlbnRpcmUKLSAqIHN0YXJ0IGVsZW1lbnQgYW5kIGNvbGxlY3QgdGhlIGF0dHJpYnV0ZXMuIFRoZSBhdHRyaWJ1dGVzIGFyZQotICogY29tbXVuaWNhdGVkIHRvIHRoZSBkb2N1bWVudCBoYW5kbGVyIGluIHRoZSBzdGFydEVsZW1lbnQgbWV0aG9kLgotICogPHA+Ci0gKiBUaGUgYXR0cmlidXRlcyBhcmUgcmVhZC13cml0ZSBzbyB0aGF0IHN1YnNlcXVlbnQgc3RhZ2VzIGluIHRoZSBkb2N1bWVudAotICogcGlwZWxpbmUgY2FuIG1vZGlmeSB0aGUgdmFsdWVzIG9yIGNoYW5nZSB0aGUgYXR0cmlidXRlcyB0aGF0IGFyZQotICogcHJvcG9nYXRlZCB0byB0aGUgbmV4dCBzdGFnZS4KLSAqCi0gKiBAc2VlIFhNTERvY3VtZW50SGFuZGxlciNzdGFydEVsZW1lbnQKLSAqCi0gKiBAYXV0aG9yIEFuZHkgQ2xhcmssIElCTQotICoKLSAqLwotcHVibGljIGludGVyZmFjZSBYTUxBdHRyaWJ1dGVzIHsKLQotICAgIC8vCi0gICAgLy8gWE1MQXR0cmlidXRlcyBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIEFkZHMgYW4gYXR0cmlidXRlLiBUaGUgYXR0cmlidXRlJ3Mgbm9uLW5vcm1hbGl6ZWQgdmFsdWUgb2YgdGhlCi0gICAgICogYXR0cmlidXRlIHdpbGwgaGF2ZSB0aGUgc2FtZSB2YWx1ZSBhcyB0aGUgYXR0cmlidXRlIHZhbHVlIHVudGlsCi0gICAgICogc2V0IHVzaW5nIHRoZSA8Y29kZT5zZXROb25Ob3JtYWxpemVkVmFsdWU8L2NvZGU+IG1ldGhvZC4gQWxzbywKLSAgICAgKiB0aGUgYWRkZWQgYXR0cmlidXRlIHdpbGwgYmUgbWFya2VkIGFzIHNwZWNpZmllZCBpbiB0aGUgWE1MIGluc3RhbmNlCi0gICAgICogZG9jdW1lbnQgdW5sZXNzIHNldCBvdGhlcndpc2UgdXNpbmcgdGhlIDxjb2RlPnNldFNwZWNpZmllZDwvY29kZT4KLSAgICAgKiBtZXRob2QuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBJZiBhbiBhdHRyaWJ1dGUgb2YgdGhlIHNhbWUgbmFtZSBhbHJlYWR5Ci0gICAgICogZXhpc3RzLCB0aGUgb2xkIHZhbHVlcyBmb3IgdGhlIGF0dHJpYnV0ZSBhcmUgcmVwbGFjZWQgYnkgdGhlIG5ldwotICAgICAqIHZhbHVlcy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBhdHRyTmFtZSAgVGhlIGF0dHJpYnV0ZSBuYW1lLgotICAgICAqIEBwYXJhbSBhdHRyVHlwZSAgVGhlIGF0dHJpYnV0ZSB0eXBlLiBUaGUgdHlwZSBuYW1lIGlzIGRldGVybWluZWQgYnkKLSAgICAgKiAgICAgICAgICAgICAgICAgIHRoZSB0eXBlIHNwZWNpZmllZCBmb3IgdGhpcyBhdHRyaWJ1dGUgaW4gdGhlIERURC4KLSAgICAgKiAgICAgICAgICAgICAgICAgIEZvciBleGFtcGxlOiAiQ0RBVEEiLCAiSUQiLCAiTk1UT0tFTiIsIGV0Yy4gSG93ZXZlciwKLSAgICAgKiAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXMgb2YgdHlwZSBlbnVtZXJhdGlvbiB3aWxsIGhhdmUgdGhlIHR5cGUKLSAgICAgKiAgICAgICAgICAgICAgICAgIHZhbHVlIHNwZWNpZmllZCBhcyB0aGUgcGlwZSAoJ3wnKSBzZXBhcmF0ZWQgbGlzdCBvZgotICAgICAqICAgICAgICAgICAgICAgICAgdGhlIGVudW1lcmF0aW9uIHZhbHVlcyBwcmVmaXhlZCBieSBhbiBvcGVuCi0gICAgICogICAgICAgICAgICAgICAgICBwYXJlbnRoZXNpcyBhbmQgc3VmZml4ZWQgYnkgYSBjbG9zZSBwYXJlbnRoZXNpcy4KLSAgICAgKiAgICAgICAgICAgICAgICAgIEZvciBleGFtcGxlOiAiKHRydWV8ZmFsc2UpIi4KLSAgICAgKiBAcGFyYW0gYXR0clZhbHVlIFRoZSBhdHRyaWJ1dGUgdmFsdWUuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFJldHVybnMgdGhlIGF0dHJpYnV0ZSBpbmRleC4KLSAgICAgKgotICAgICAqIEBzZWUgI3NldE5vbk5vcm1hbGl6ZWRWYWx1ZQotICAgICAqIEBzZWUgI3NldFNwZWNpZmllZAotICAgICAqLwotICAgIHB1YmxpYyBpbnQgYWRkQXR0cmlidXRlKFFOYW1lIGF0dHJOYW1lLCBTdHJpbmcgYXR0clR5cGUsIFN0cmluZyBhdHRyVmFsdWUpOwotCi0gICAgLyoqCi0gICAgICogUmVtb3ZlcyBhbGwgb2YgdGhlIGF0dHJpYnV0ZXMuIFRoaXMgbWV0aG9kIHdpbGwgYWxzbyByZW1vdmUgYWxsCi0gICAgICogZW50aXRpZXMgYXNzb2NpYXRlZCB0byB0aGUgYXR0cmlidXRlcy4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCByZW1vdmVBbGxBdHRyaWJ1dGVzKCk7Ci0KLSAgICAvKioKLSAgICAgKiBSZW1vdmVzIHRoZSBhdHRyaWJ1dGUgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoaXMgb3BlcmF0aW9uIGNoYW5nZXMgdGhlIGluZGV4ZXMgb2YgYWxsCi0gICAgICogYXR0cmlidXRlcyBmb2xsb3dpbmcgdGhlIGF0dHJpYnV0ZSBhdCB0aGUgc3BlY2lmaWVkIGluZGV4LgotICAgICAqCi0gICAgICogQHBhcmFtIGF0dHJJbmRleCBUaGUgYXR0cmlidXRlIGluZGV4LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHJlbW92ZUF0dHJpYnV0ZUF0KGludCBhdHRySW5kZXgpOwotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIGF0dHJpYnV0ZXMgaW4gdGhlIGxpc3QuCi0gICAgICogPHA+Ci0gICAgICogT25jZSB5b3Uga25vdyB0aGUgbnVtYmVyIG9mIGF0dHJpYnV0ZXMsIHlvdSBjYW4gaXRlcmF0ZQotICAgICAqIHRocm91Z2ggdGhlIGxpc3QuCi0gICAgICoKLSAgICAgKiBAc2VlICNnZXRVUkkoaW50KQotICAgICAqIEBzZWUgI2dldExvY2FsTmFtZShpbnQpCi0gICAgICogQHNlZSAjZ2V0UU5hbWUoaW50KQotICAgICAqIEBzZWUgI2dldFR5cGUoaW50KQotICAgICAqIEBzZWUgI2dldFZhbHVlKGludCkKLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldExlbmd0aCgpOwotCi0gICAgLyoqCi0gICAgICogTG9vayB1cCB0aGUgaW5kZXggb2YgYW4gYXR0cmlidXRlIGJ5IFhNTCAxLjAgcXVhbGlmaWVkIG5hbWUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcU5hbWUgVGhlIHF1YWxpZmllZCAocHJlZml4ZWQpIG5hbWUuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBpbmRleCBvZiB0aGUgYXR0cmlidXRlLCBvciAtMSBpZiBpdCBkb2VzIG5vdAotICAgICAqICAgICAgICAgYXBwZWFyIGluIHRoZSBsaXN0LgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0SW5kZXgoU3RyaW5nIHFOYW1lKTsKLQotICAgIC8qKgotICAgICAqIExvb2sgdXAgdGhlIGluZGV4IG9mIGFuIGF0dHJpYnV0ZSBieSBOYW1lc3BhY2UgbmFtZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSB1cmkgICAgICAgVGhlIE5hbWVzcGFjZSBVUkksIG9yIHRoZSBlbXB0eSBzdHJpbmcgaWYKLSAgICAgKiAgICAgICAgICAgICAgICAgIHRoZSBuYW1lIGhhcyBubyBOYW1lc3BhY2UgVVJJLgotICAgICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGF0dHJpYnV0ZSdzIGxvY2FsIG5hbWUuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBpbmRleCBvZiB0aGUgYXR0cmlidXRlLCBvciAtMSBpZiBpdCBkb2VzIG5vdAotICAgICAqICAgICAgICAgYXBwZWFyIGluIHRoZSBsaXN0LgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0SW5kZXgoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsUGFydCk7Ci0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBhdHRySW5kZXggVGhlIGF0dHJpYnV0ZSBpbmRleC4KLSAgICAgKiBAcGFyYW0gYXR0ck5hbWUgIFRoZSBuZXcgYXR0cmlidXRlIG5hbWUuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0TmFtZShpbnQgYXR0ckluZGV4LCBRTmFtZSBhdHRyTmFtZSk7Ci0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSBmaWVsZHMgaW4gdGhlIGdpdmVuIFFOYW1lIHN0cnVjdHVyZSB3aXRoIHRoZSB2YWx1ZXMKLSAgICAgKiBvZiB0aGUgYXR0cmlidXRlIG5hbWUgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBhdHRySW5kZXggVGhlIGF0dHJpYnV0ZSBpbmRleC4KLSAgICAgKiBAcGFyYW0gYXR0ck5hbWUgIFRoZSBhdHRyaWJ1dGUgbmFtZSBzdHJ1Y3R1cmUgdG8gZmlsbCBpbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBnZXROYW1lKGludCBhdHRySW5kZXgsIFFOYW1lIGF0dHJOYW1lKTsKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIHByZWZpeCBvZiB0aGUgYXR0cmlidXRlIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXguCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBhdHRyaWJ1dGUuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRQcmVmaXgoaW50IGluZGV4KTsKLQotICAgIC8qKgotICAgICAqIExvb2sgdXAgYW4gYXR0cmlidXRlJ3MgTmFtZXNwYWNlIFVSSSBieSBpbmRleC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBpbmRleCBUaGUgYXR0cmlidXRlIGluZGV4ICh6ZXJvLWJhc2VkKS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIE5hbWVzcGFjZSBVUkksIG9yIHRoZSBlbXB0eSBzdHJpbmcgaWYgbm9uZQotICAgICAqICAgICAgICAgaXMgYXZhaWxhYmxlLCBvciBudWxsIGlmIHRoZSBpbmRleCBpcyBvdXQgb2YKLSAgICAgKiAgICAgICAgIHJhbmdlLgotICAgICAqCi0gICAgICogQHNlZSAjZ2V0TGVuZ3RoCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRVUkkoaW50IGluZGV4KTsKLQotICAgIC8qKgotICAgICAqIExvb2sgdXAgYW4gYXR0cmlidXRlJ3MgbG9jYWwgbmFtZSBieSBpbmRleC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBpbmRleCBUaGUgYXR0cmlidXRlIGluZGV4ICh6ZXJvLWJhc2VkKS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIGxvY2FsIG5hbWUsIG9yIHRoZSBlbXB0eSBzdHJpbmcgaWYgTmFtZXNwYWNlCi0gICAgICogICAgICAgICBwcm9jZXNzaW5nIGlzIG5vdCBiZWluZyBwZXJmb3JtZWQsIG9yIG51bGwKLSAgICAgKiAgICAgICAgIGlmIHRoZSBpbmRleCBpcyBvdXQgb2YgcmFuZ2UuCi0gICAgICoKLSAgICAgKiBAc2VlICNnZXRMZW5ndGgKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldExvY2FsTmFtZShpbnQgaW5kZXgpOwotCi0gICAgLyoqCi0gICAgICogTG9vayB1cCBhbiBhdHRyaWJ1dGUncyBYTUwgMS4wIHF1YWxpZmllZCBuYW1lIGJ5IGluZGV4LgotICAgICAqCi0gICAgICogQHBhcmFtIGluZGV4IFRoZSBhdHRyaWJ1dGUgaW5kZXggKHplcm8tYmFzZWQpLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgWE1MIDEuMCBxdWFsaWZpZWQgbmFtZSwgb3IgdGhlIGVtcHR5IHN0cmluZwotICAgICAqICAgICAgICAgaWYgbm9uZSBpcyBhdmFpbGFibGUsIG9yIG51bGwgaWYgdGhlIGluZGV4Ci0gICAgICogICAgICAgICBpcyBvdXQgb2YgcmFuZ2UuCi0gICAgICoKLSAgICAgKiBAc2VlICNnZXRMZW5ndGgKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFFOYW1lKGludCBpbmRleCk7Ci0KLSAgICAvL3doeSB0aGUgYWJvdmUgbWV0aG9kIGRvZW5zJ3QgcmV0dXJuIFFOYW1lID8KLSAgICBwdWJsaWMgUU5hbWUgZ2V0UXVhbGlmaWVkTmFtZShpbnQgaW5kZXgpOwotCi0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSB0eXBlIG9mIHRoZSBhdHRyaWJ1dGUgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBhdHRySW5kZXggVGhlIGF0dHJpYnV0ZSBpbmRleC4KLSAgICAgKiBAcGFyYW0gYXR0clR5cGUgIFRoZSBhdHRyaWJ1dGUgdHlwZS4gVGhlIHR5cGUgbmFtZSBpcyBkZXRlcm1pbmVkIGJ5Ci0gICAgICogICAgICAgICAgICAgICAgICB0aGUgdHlwZSBzcGVjaWZpZWQgZm9yIHRoaXMgYXR0cmlidXRlIGluIHRoZSBEVEQuCi0gICAgICogICAgICAgICAgICAgICAgICBGb3IgZXhhbXBsZTogIkNEQVRBIiwgIklEIiwgIk5NVE9LRU4iLCBldGMuIEhvd2V2ZXIsCi0gICAgICogICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzIG9mIHR5cGUgZW51bWVyYXRpb24gd2lsbCBoYXZlIHRoZSB0eXBlCi0gICAgICogICAgICAgICAgICAgICAgICB2YWx1ZSBzcGVjaWZpZWQgYXMgdGhlIHBpcGUgKCd8Jykgc2VwYXJhdGVkIGxpc3Qgb2YKLSAgICAgKiAgICAgICAgICAgICAgICAgIHRoZSBlbnVtZXJhdGlvbiB2YWx1ZXMgcHJlZml4ZWQgYnkgYW4gb3BlbgotICAgICAqICAgICAgICAgICAgICAgICAgcGFyZW50aGVzaXMgYW5kIHN1ZmZpeGVkIGJ5IGEgY2xvc2UgcGFyZW50aGVzaXMuCi0gICAgICogICAgICAgICAgICAgICAgICBGb3IgZXhhbXBsZTogIih0cnVlfGZhbHNlKSIuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0VHlwZShpbnQgYXR0ckluZGV4LCBTdHJpbmcgYXR0clR5cGUpOwotCi0gICAgLyoqCi0gICAgICogTG9vayB1cCBhbiBhdHRyaWJ1dGUncyB0eXBlIGJ5IGluZGV4LgotICAgICAqIDxwPgotICAgICAqIFRoZSBhdHRyaWJ1dGUgdHlwZSBpcyBvbmUgb2YgdGhlIHN0cmluZ3MgIkNEQVRBIiwgIklEIiwKLSAgICAgKiAiSURSRUYiLCAiSURSRUZTIiwgIk5NVE9LRU4iLCAiTk1UT0tFTlMiLCAiRU5USVRZIiwgIkVOVElUSUVTIiwKLSAgICAgKiBvciAiTk9UQVRJT04iIChhbHdheXMgaW4gdXBwZXIgY2FzZSkuCi0gICAgICogPHA+Ci0gICAgICogSWYgdGhlIHBhcnNlciBoYXMgbm90IHJlYWQgYSBkZWNsYXJhdGlvbiBmb3IgdGhlIGF0dHJpYnV0ZSwKLSAgICAgKiBvciBpZiB0aGUgcGFyc2VyIGRvZXMgbm90IHJlcG9ydCBhdHRyaWJ1dGUgdHlwZXMsIHRoZW4gaXQgbXVzdAotICAgICAqIHJldHVybiB0aGUgdmFsdWUgIkNEQVRBIiBhcyBzdGF0ZWQgaW4gdGhlIFhNTCAxLjAgUmVjb21tZW50YXRpb24KLSAgICAgKiAoY2xhdXNlIDMuMy4zLCAiQXR0cmlidXRlLVZhbHVlIE5vcm1hbGl6YXRpb24iKS4KLSAgICAgKiA8cD4KLSAgICAgKiBGb3IgYW4gZW51bWVyYXRlZCBhdHRyaWJ1dGUgdGhhdCBpcyBub3QgYSBub3RhdGlvbiwgdGhlCi0gICAgICogcGFyc2VyIHdpbGwgcmVwb3J0IHRoZSB0eXBlIGFzICJOTVRPS0VOIi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBpbmRleCBUaGUgYXR0cmlidXRlIGluZGV4ICh6ZXJvLWJhc2VkKS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIGF0dHJpYnV0ZSdzIHR5cGUgYXMgYSBzdHJpbmcsIG9yIG51bGwgaWYgdGhlCi0gICAgICogICAgICAgICBpbmRleCBpcyBvdXQgb2YgcmFuZ2UuCi0gICAgICoKLSAgICAgKiBAc2VlICNnZXRMZW5ndGgKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFR5cGUoaW50IGluZGV4KTsKLQotICAgIC8qKgotICAgICAqIExvb2sgdXAgYW4gYXR0cmlidXRlJ3MgdHlwZSBieSBYTUwgMS4wIHF1YWxpZmllZCBuYW1lLgotICAgICAqIDxwPgotICAgICAqIFNlZSB7QGxpbmsgI2dldFR5cGUoaW50KSBnZXRUeXBlKGludCl9IGZvciBhIGRlc2NyaXB0aW9uCi0gICAgICogb2YgdGhlIHBvc3NpYmxlIHR5cGVzLgotICAgICAqCi0gICAgICogQHBhcmFtIHFOYW1lIFRoZSBYTUwgMS4wIHF1YWxpZmllZCBuYW1lLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgYXR0cmlidXRlIHR5cGUgYXMgYSBzdHJpbmcsIG9yIG51bGwgaWYgdGhlCi0gICAgICogICAgICAgICBhdHRyaWJ1dGUgaXMgbm90IGluIHRoZSBsaXN0IG9yIGlmIHF1YWxpZmllZCBuYW1lcwotICAgICAqICAgICAgICAgYXJlIG5vdCBhdmFpbGFibGUuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRUeXBlKFN0cmluZyBxTmFtZSk7Ci0KLSAgICAvKioKLSAgICAgKiBMb29rIHVwIGFuIGF0dHJpYnV0ZSdzIHR5cGUgYnkgTmFtZXNwYWNlIG5hbWUuCi0gICAgICogPHA+Ci0gICAgICogU2VlIHtAbGluayAjZ2V0VHlwZShpbnQpIGdldFR5cGUoaW50KX0gZm9yIGEgZGVzY3JpcHRpb24KLSAgICAgKiBvZiB0aGUgcG9zc2libGUgdHlwZXMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdXJpICAgICAgIFRoZSBOYW1lc3BhY2UgVVJJLCBvciB0aGUgZW1wdHkgU3RyaW5nIGlmIHRoZQotICAgICAqICAgICAgICAgICAgICAgICAgbmFtZSBoYXMgbm8gTmFtZXNwYWNlIFVSSS4KLSAgICAgKiBAcGFyYW0gbG9jYWxOYW1lIFRoZSBsb2NhbCBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBhdHRyaWJ1dGUgdHlwZSBhcyBhIHN0cmluZywgb3IgbnVsbCBpZiB0aGUKLSAgICAgKiAgICAgICAgIGF0dHJpYnV0ZSBpcyBub3QgaW4gdGhlIGxpc3Qgb3IgaWYgTmFtZXNwYWNlCi0gICAgICogICAgICAgICBwcm9jZXNzaW5nIGlzIG5vdCBiZWluZyBwZXJmb3JtZWQuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRUeXBlKFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUpOwotCi0gICAgLyoqCi0gICAgICogU2V0cyB0aGUgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZSBhdCB0aGUgc3BlY2lmaWVkIGluZGV4LiBUaGlzCi0gICAgICogbWV0aG9kIHdpbGwgb3ZlcndyaXRlIHRoZSBub24tbm9ybWFsaXplZCB2YWx1ZSBvZiB0aGUgYXR0cmlidXRlLgotICAgICAqCi0gICAgICogQHBhcmFtIGF0dHJJbmRleCBUaGUgYXR0cmlidXRlIGluZGV4LgotICAgICAqIEBwYXJhbSBhdHRyVmFsdWUgVGhlIG5ldyBhdHRyaWJ1dGUgdmFsdWUuCi0gICAgICoKLSAgICAgKiBAc2VlICNzZXROb25Ob3JtYWxpemVkVmFsdWUKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRWYWx1ZShpbnQgYXR0ckluZGV4LCBTdHJpbmcgYXR0clZhbHVlKTsKLQotICAgIHB1YmxpYyB2b2lkIHNldFZhbHVlKGludCBhdHRySW5kZXgsIFN0cmluZyBhdHRyVmFsdWUsIFhNTFN0cmluZyB2YWx1ZSk7Ci0KLSAgICAvKioKLSAgICAgKiBMb29rIHVwIGFuIGF0dHJpYnV0ZSdzIHZhbHVlIGJ5IGluZGV4LgotICAgICAqIDxwPgotICAgICAqIElmIHRoZSBhdHRyaWJ1dGUgdmFsdWUgaXMgYSBsaXN0IG9mIHRva2VucyAoSURSRUZTLAotICAgICAqIEVOVElUSUVTLCBvciBOTVRPS0VOUyksIHRoZSB0b2tlbnMgd2lsbCBiZSBjb25jYXRlbmF0ZWQKLSAgICAgKiBpbnRvIGEgc2luZ2xlIHN0cmluZyB3aXRoIGVhY2ggdG9rZW4gc2VwYXJhdGVkIGJ5IGEKLSAgICAgKiBzaW5nbGUgc3BhY2UuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGF0dHJpYnV0ZSBpbmRleCAoemVyby1iYXNlZCkuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBhdHRyaWJ1dGUncyB2YWx1ZSBhcyBhIHN0cmluZywgb3IgbnVsbCBpZiB0aGUKLSAgICAgKiAgICAgICAgIGluZGV4IGlzIG91dCBvZiByYW5nZS4KLSAgICAgKgotICAgICAqIEBzZWUgI2dldExlbmd0aAotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VmFsdWUoaW50IGluZGV4KTsKLQotICAgIC8qKgotICAgICAqIExvb2sgdXAgYW4gYXR0cmlidXRlJ3MgdmFsdWUgYnkgWE1MIDEuMCBxdWFsaWZpZWQgbmFtZS4KLSAgICAgKiA8cD4KLSAgICAgKiBTZWUge0BsaW5rICNnZXRWYWx1ZShpbnQpIGdldFZhbHVlKGludCl9IGZvciBhIGRlc2NyaXB0aW9uCi0gICAgICogb2YgdGhlIHBvc3NpYmxlIHZhbHVlcy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBxTmFtZSBUaGUgWE1MIDEuMCBxdWFsaWZpZWQgbmFtZS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIGF0dHJpYnV0ZSB2YWx1ZSBhcyBhIHN0cmluZywgb3IgbnVsbCBpZiB0aGUKLSAgICAgKiAgICAgICAgIGF0dHJpYnV0ZSBpcyBub3QgaW4gdGhlIGxpc3Qgb3IgaWYgcXVhbGlmaWVkIG5hbWVzCi0gICAgICogICAgICAgICBhcmUgbm90IGF2YWlsYWJsZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFZhbHVlKFN0cmluZyBxTmFtZSk7Ci0KLSAgICAvKioKLSAgICAgKiBMb29rIHVwIGFuIGF0dHJpYnV0ZSdzIHZhbHVlIGJ5IE5hbWVzcGFjZSBuYW1lLgotICAgICAqIDxwPgotICAgICAqIFNlZSB7QGxpbmsgI2dldFZhbHVlKGludCkgZ2V0VmFsdWUoaW50KX0gZm9yIGEgZGVzY3JpcHRpb24KLSAgICAgKiBvZiB0aGUgcG9zc2libGUgdmFsdWVzLgotICAgICAqCi0gICAgICogQHBhcmFtIHVyaSAgICAgICBUaGUgTmFtZXNwYWNlIFVSSSwgb3IgdGhlIGVtcHR5IFN0cmluZyBpZiB0aGUKLSAgICAgKiAgICAgICAgICAgICAgICAgIG5hbWUgaGFzIG5vIE5hbWVzcGFjZSBVUkkuCi0gICAgICogQHBhcmFtIGxvY2FsTmFtZSBUaGUgbG9jYWwgbmFtZSBvZiB0aGUgYXR0cmlidXRlLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgYXR0cmlidXRlIHZhbHVlIGFzIGEgc3RyaW5nLCBvciBudWxsIGlmIHRoZQotICAgICAqICAgICAgICAgYXR0cmlidXRlIGlzIG5vdCBpbiB0aGUgbGlzdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFZhbHVlKFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUpOwotCi0gICAgLyoqCi0gICAgICogU2V0cyB0aGUgbm9uLW5vcm1hbGl6ZWQgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZSBhdCB0aGUgc3BlY2lmaWVkCi0gICAgICogaW5kZXguCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYXR0ckluZGV4IFRoZSBhdHRyaWJ1dGUgaW5kZXguCi0gICAgICogQHBhcmFtIGF0dHJWYWx1ZSBUaGUgbmV3IG5vbi1ub3JtYWxpemVkIGF0dHJpYnV0ZSB2YWx1ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXROb25Ob3JtYWxpemVkVmFsdWUoaW50IGF0dHJJbmRleCwgU3RyaW5nIGF0dHJWYWx1ZSk7Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBub24tbm9ybWFsaXplZCB2YWx1ZSBvZiB0aGUgYXR0cmlidXRlIGF0IHRoZSBzcGVjaWZpZWQKLSAgICAgKiBpbmRleC4gSWYgbm8gbm9uLW5vcm1hbGl6ZWQgdmFsdWUgaXMgc2V0LCB0aGlzIG1ldGhvZCB3aWxsIHJldHVybgotICAgICAqIHRoZSBzYW1lIHZhbHVlIGFzIHRoZSA8Y29kZT5nZXRWYWx1ZShpbnQpPC9jb2RlPiBtZXRob2QuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYXR0ckluZGV4IFRoZSBhdHRyaWJ1dGUgaW5kZXguCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXROb25Ob3JtYWxpemVkVmFsdWUoaW50IGF0dHJJbmRleCk7Ci0KLSAgICAvKioKLSAgICAgKiBTZXRzIHdoZXRoZXIgYW4gYXR0cmlidXRlIGlzIHNwZWNpZmllZCBpbiB0aGUgaW5zdGFuY2UgZG9jdW1lbnQKLSAgICAgKiBvciBub3QuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYXR0ckluZGV4IFRoZSBhdHRyaWJ1dGUgaW5kZXguCi0gICAgICogQHBhcmFtIHNwZWNpZmllZCBUcnVlIGlmIHRoZSBhdHRyaWJ1dGUgaXMgc3BlY2lmaWVkIGluIHRoZSBpbnN0YW5jZQotICAgICAqICAgICAgICAgICAgICAgICAgZG9jdW1lbnQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0U3BlY2lmaWVkKGludCBhdHRySW5kZXgsIGJvb2xlYW4gc3BlY2lmaWVkKTsKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgYXR0cmlidXRlIGlzIHNwZWNpZmllZCBpbiB0aGUgaW5zdGFuY2UgZG9jdW1lbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYXR0ckluZGV4IFRoZSBhdHRyaWJ1dGUgaW5kZXguCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNTcGVjaWZpZWQoaW50IGF0dHJJbmRleCk7Ci0KLQotICAgIC8qKgotICAgICAqIExvb2sgdXAgYW4gYXVnbWVudGF0aW9uIGJ5IGF0dHJpYnV0ZSdzIGluZGV4LgotICAgICAqCi0gICAgICogQHBhcmFtIGF0dHJpYnV0ZUluZGV4IFRoZSBhdHRyaWJ1dGUgaW5kZXguCi0gICAgICogQHJldHVybiBBdWdtZW50YXRpb25zCi0gICAgICovCi0gICAgcHVibGljIEF1Z21lbnRhdGlvbnMgZ2V0QXVnbWVudGF0aW9ucyAoaW50IGF0dHJpYnV0ZUluZGV4KTsKLQotICAgIC8qKgotICAgICAqIExvb2sgdXAgYW4gYXVnbWVudGF0aW9uIGJ5IG5hbWVzcGFjZSBuYW1lLgotICAgICAqCi0gICAgICogQHBhcmFtIHVyaSAgICAgICBUaGUgTmFtZXNwYWNlIFVSSSwgb3IgdGhlIGVtcHR5IHN0cmluZyBpZgotICAgICAqICAgICAgICAgICAgICAgICAgdGhlIG5hbWUgaGFzIG5vIE5hbWVzcGFjZSBVUkkuCi0gICAgICogQHBhcmFtIGxvY2FsUGFydAotICAgICAqIEByZXR1cm4gQXVnbWVudGF0aW9ucwotICAgICAqLwotICAgIHB1YmxpYyBBdWdtZW50YXRpb25zIGdldEF1Z21lbnRhdGlvbnMgKFN0cmluZyB1cmksIFN0cmluZyBsb2NhbFBhcnQpOwotCi0KLSAgICAvKioKLSAgICAgKiBMb29rIHVwIGFuIGF1Z21lbnRhdGlvbiBieSBYTUwgMS4wIHF1YWxpZmllZCBuYW1lLgotICAgICAqIDxwPgotICAgICAqCi0gICAgICogQHBhcmFtIHFOYW1lIFRoZSBYTUwgMS4wIHF1YWxpZmllZCBuYW1lLgotICAgICAqCi0gICAgICogQHJldHVybiBBdWdtZW50YXRpb25zCi0gICAgICoKLSAgICAgKi8KLSAgICBwdWJsaWMgQXVnbWVudGF0aW9ucyBnZXRBdWdtZW50YXRpb25zKFN0cmluZyBxTmFtZSk7Ci0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSBhdWdtZW50YXRpb25zIG9mIHRoZSBhdHRyaWJ1dGUgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBhdHRySW5kZXggVGhlIGF0dHJpYnV0ZSBpbmRleC4KLSAgICAgKiBAcGFyYW0gYXVncyAgICAgIFRoZSBhdWdtZW50YXRpb25zLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEF1Z21lbnRhdGlvbnMoaW50IGF0dHJJbmRleCwgQXVnbWVudGF0aW9ucyBhdWdzKTsKLQotCi0KLQotfSAvLyBpbnRlcmZhY2UgWE1MQXR0cmlidXRlcwpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveG5pL1hNTERURENvbnRlbnRNb2RlbEhhbmRsZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3huaS9YTUxEVERDb250ZW50TW9kZWxIYW5kbGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDA2MjgyNWUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveG5pL1hNTERURENvbnRlbnRNb2RlbEhhbmRsZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI3MyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAwLTIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmk7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MRFREQ29udGVudE1vZGVsU291cmNlOwotCi0vKioKLSAqIFRoZSBEVEQgY29udGVudCBtb2RlbCBoYW5kbGVyIGludGVyZmFjZSBkZWZpbmVzIGNhbGxiYWNrIG1ldGhvZHMKLSAqIHRvIHJlcG9ydCBpbmZvcm1hdGlvbiBpdGVtcyBpbiBEVEQgY29udGVudCBtb2RlbHMgb2YgYW4gZWxlbWVudAotICogZGVjbGFyYXRpb24uIFBhcnNlciBjb21wb25lbnRzIGludGVyZXN0ZWQgaW4gRFREIGNvbnRlbnQgbW9kZWwKLSAqIGluZm9ybWF0aW9uIGltcGxlbWVudCB0aGlzIGludGVyZmFjZSBhbmQgYXJlIHJlZ2lzdGVyZWQgYXMgdGhlIERURAotICogY29udGVudCBtb2RlbCBoYW5kbGVyIG9uIHRoZSBEVEQgY29udGVudCBtb2RlbCBzb3VyY2UuCi0gKgotICogQHNlZSBYTUxEVERIYW5kbGVyCi0gKgotICogQGF1dGhvciBBbmR5IENsYXJrLCBJQk0KLSAqCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgWE1MRFREQ29udGVudE1vZGVsSGFuZGxlciB7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0YW50cwotICAgIC8vCi0KLSAgICAvLyBzZXBhcmF0b3JzCi0KLSAgICAvKioKLSAgICAgKiBBIGNob2ljZSBzZXBhcmF0b3IgZm9yIGNoaWxkcmVuIGFuZCBtaXhlZCBjb250ZW50IG1vZGVscy4gVGhpcwotICAgICAqIHNlcGFyYXRvciBpcyB1c2VkIHRvIHNwZWNpZnkgdGhhdCB0aGUgYWxsb3dlZCBjaGlsZCBpcyBvbmUgb2YgYQotICAgICAqIGNvbGxlY3Rpb24uCi0gICAgICogPHA+Ci0gICAgICogRm9yIGV4YW1wbGU6Ci0gICAgICogPHByZT4KLSAgICAgKiAmbHQ7IUVMRU1FTlQgZWxlbSAoZm9vfGJhcikmZ3Q7Ci0gICAgICogJmx0OyFFTEVNRU5UIGVsZW0gKGZvb3xiYXIrKSZndDsKLSAgICAgKiAmbHQ7IUVMRU1FTlQgZWxlbSAoZm9vfGJhcnxiYXopJmd0OwotICAgICAqICZsdDshRUxFTUVOVCBlbGVtICgjUENEQVRBfGZvb3xiYXIpKiZndDsKLSAgICAgKiA8L3ByZT4KLSAgICAgKgotICAgICAqIEBzZWUgI1NFUEFSQVRPUl9TRVFVRU5DRQotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgU0VQQVJBVE9SX0NIT0lDRSA9IDA7Ci0KLSAgICAvKioKLSAgICAgKiBBIHNlcXVlbmNlIHNlcGFyYXRvciBmb3IgY2hpbGRyZW4gY29udGVudCBtb2RlbHMuIFRoaXMgc2VwYXJhdG9yCi0gICAgICogaXMgdXNlZCB0byBzcGVjaWZ5IHRoYXQgdGhlIGFsbG93ZWQgY2hpbGRyZW4gbXVzdCBmb2xsb3cgaW4gdGhlCi0gICAgICogc3BlY2lmaWVkIHNlcXVlbmNlLgotICAgICAqIDxwPgotICAgICAqIDxwcmU+Ci0gICAgICogJmx0OyFFTEVNRU5UIGVsZW0gKGZvbyxiYXIpJmd0OwotICAgICAqICZsdDshRUxFTUVOVCBlbGVtIChmb28sYmFyKikmZ3Q7Ci0gICAgICogJmx0OyFFTEVNRU5UIGVsZW0gKGZvbyxiYXIsYmF6KSZndDsKLSAgICAgKiA8L3ByZT4KLSAgICAgKgotICAgICAqIEBzZWUgI1NFUEFSQVRPUl9DSE9JQ0UKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFNFUEFSQVRPUl9TRVFVRU5DRSA9IDE7Ci0KLSAgICAvLyBvY2N1cnJlbmNlIGNvdW50cwotCi0gICAgLyoqCi0gICAgICogVGhpcyBvY2N1cnJlbmNlIGNvdW50IGxpbWl0cyB0aGUgZWxlbWVudCwgY2hvaWNlLCBvciBzZXF1ZW5jZSBpbiBhCi0gICAgICogY2hpbGRyZW4gY29udGVudCBtb2RlbCB0byB6ZXJvIG9yIG9uZS4gSW4gb3RoZXIgd29yZHMsIHRoZSBjaGlsZAotICAgICAqIGlzIG9wdGlvbmFsLgotICAgICAqIDxwPgotICAgICAqIEZvciBleGFtcGxlOgotICAgICAqIDxwcmU+Ci0gICAgICogJmx0OyFFTEVNRU5UIGVsZW0gKGZvbz8pJmd0OwotICAgICAqIDwvcHJlPgotICAgICAqCi0gICAgICogQHNlZSAjT0NDVVJTX1pFUk9fT1JfTU9SRQotICAgICAqIEBzZWUgI09DQ1VSU19PTkVfT1JfTU9SRQotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgT0NDVVJTX1pFUk9fT1JfT05FID0gMjsKLQotICAgIC8qKgotICAgICAqIFRoaXMgb2NjdXJyZW5jZSBjb3VudCBsaW1pdHMgdGhlIGVsZW1lbnQsIGNob2ljZSwgb3Igc2VxdWVuY2UgaW4gYQotICAgICAqIGNoaWxkcmVuIGNvbnRlbnQgbW9kZWwgdG8gemVybyBvciBtb3JlLiBJbiBvdGhlciB3b3JkcywgdGhlIGNoaWxkCi0gICAgICogbWF5IGFwcGVhciBhbiBhcmJpdHJhcnkgbnVtYmVyIG9mIHRpbWVzLCBvciBub3QgYXQgYWxsLiBUaGlzCi0gICAgICogb2NjdXJyZW5jZSBjb3VudCBpcyBhbHNvIHVzZWQgZm9yIG1peGVkIGNvbnRlbnQgbW9kZWxzLgotICAgICAqIDxwPgotICAgICAqIEZvciBleGFtcGxlOgotICAgICAqIDxwcmU+Ci0gICAgICogJmx0OyFFTEVNRU5UIGVsZW0gKGZvbyopJmd0OwotICAgICAqICZsdDshRUxFTUVOVCBlbGVtICgjUENEQVRBfGZvb3xiYXIpKiZndDsKLSAgICAgKiA8L3ByZT4KLSAgICAgKgotICAgICAqIEBzZWUgI09DQ1VSU19aRVJPX09SX09ORQotICAgICAqIEBzZWUgI09DQ1VSU19PTkVfT1JfTU9SRQotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgT0NDVVJTX1pFUk9fT1JfTU9SRSA9IDM7Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG9jY3VycmVuY2UgY291bnQgbGltaXRzIHRoZSBlbGVtZW50LCBjaG9pY2UsIG9yIHNlcXVlbmNlIGluIGEKLSAgICAgKiBjaGlsZHJlbiBjb250ZW50IG1vZGVsIHRvIG9uZSBvciBtb3JlLiBJbiBvdGhlciB3b3JkcywgdGhlIGNoaWxkCi0gICAgICogbWF5IGFwcGVhciBhbiBhcmJpdHJhcnkgbnVtYmVyIG9mIHRpbWVzLCBidXQgbXVzdCBhcHBlYXIgYXQgbGVhc3QKLSAgICAgKiBvbmNlLgotICAgICAqIDxwPgotICAgICAqIEZvciBleGFtcGxlOgotICAgICAqIDxwcmU+Ci0gICAgICogJmx0OyFFTEVNRU5UIGVsZW0gKGZvbyspJmd0OwotICAgICAqIDwvcHJlPgotICAgICAqCi0gICAgICogQHNlZSAjT0NDVVJTX1pFUk9fT1JfT05FCi0gICAgICogQHNlZSAjT0NDVVJTX1pFUk9fT1JfTU9SRQotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgT0NDVVJTX09ORV9PUl9NT1JFID0gNDsKLQotICAgIC8vCi0gICAgLy8gWE1MRFREQ29udGVudE1vZGVsSGFuZGxlciBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFRoZSBzdGFydCBvZiBhIGNvbnRlbnQgbW9kZWwuIERlcGVuZGluZyBvbiB0aGUgdHlwZSBvZiB0aGUgY29udGVudAotICAgICAqIG1vZGVsLCBzcGVjaWZpYyBtZXRob2RzIG1heSBiZSBjYWxsZWQgYmV0d2VlbiB0aGUgY2FsbCB0byB0aGUKLSAgICAgKiBzdGFydENvbnRlbnRNb2RlbCBtZXRob2QgYW5kIHRoZSBjYWxsIHRvIHRoZSBlbmRDb250ZW50TW9kZWwgbWV0aG9kLgotICAgICAqCi0gICAgICogQHBhcmFtIGVsZW1lbnROYW1lIFRoZSBuYW1lIG9mIHRoZSBlbGVtZW50LgotICAgICAqIEBwYXJhbSBhdWdtZW50YXRpb25zIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydENvbnRlbnRNb2RlbChTdHJpbmcgZWxlbWVudE5hbWUsIEF1Z21lbnRhdGlvbnMgYXVnbWVudGF0aW9ucykKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIEEgY29udGVudCBtb2RlbCBvZiBBTlkuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYXVnbWVudGF0aW9ucyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICoKLSAgICAgKiBAc2VlICNlbXB0eQotICAgICAqIEBzZWUgI3N0YXJ0R3JvdXAKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBhbnkoQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKSB0aHJvd3MgWE5JRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogQSBjb250ZW50IG1vZGVsIG9mIEVNUFRZLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqCi0gICAgICogQHBhcmFtIGF1Z21lbnRhdGlvbnMgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqCi0gICAgICogQHNlZSAjYW55Ci0gICAgICogQHNlZSAjc3RhcnRHcm91cAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVtcHR5KEF1Z21lbnRhdGlvbnMgYXVnbWVudGF0aW9ucykgdGhyb3dzIFhOSUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIEEgc3RhcnQgb2YgZWl0aGVyIGEgbWl4ZWQgb3IgY2hpbGRyZW4gY29udGVudCBtb2RlbC4gQSBtaXhlZAotICAgICAqIGNvbnRlbnQgbW9kZWwgd2lsbCBpbW1lZGlhdGVseSBiZSBmb2xsb3dlZCBieSBhIGNhbGwgdG8gdGhlCi0gICAgICogPGNvZGU+cGNkYXRhKCk8L2NvZGU+IG1ldGhvZC4gQSBjaGlsZHJlbiBjb250ZW50IG1vZGVsIHdpbGwKLSAgICAgKiBjb250YWluIGFkZGl0aW9uYWwgZ3JvdXBzIGFuZC9vciBlbGVtZW50cy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBhdWdtZW50YXRpb25zIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKgotICAgICAqIEBzZWUgI2FueQotICAgICAqIEBzZWUgI2VtcHR5Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnRHcm91cChBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpIHRocm93cyBYTklFeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgYXBwZWFyYW5jZSBvZiAiI1BDREFUQSIgd2l0aGluIGEgZ3JvdXAgc2lnbmlmeWluZyBhCi0gICAgICogbWl4ZWQgY29udGVudCBtb2RlbC4gVGhpcyBtZXRob2Qgd2lsbCBiZSB0aGUgZmlyc3QgY2FsbGVkCi0gICAgICogZm9sbG93aW5nIHRoZSBjb250ZW50IG1vZGVsJ3MgPGNvZGU+c3RhcnRHcm91cCgpPC9jb2RlPi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBhdWdtZW50YXRpb25zIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKgotICAgICAqIEBzZWUgI3N0YXJ0R3JvdXAKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBwY2RhdGEoQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKSB0aHJvd3MgWE5JRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogQSByZWZlcmVuY2VkIGVsZW1lbnQgaW4gYSBtaXhlZCBvciBjaGlsZHJlbiBjb250ZW50IG1vZGVsLgotICAgICAqCi0gICAgICogQHBhcmFtIGVsZW1lbnROYW1lIFRoZSBuYW1lIG9mIHRoZSByZWZlcmVuY2VkIGVsZW1lbnQuCi0gICAgICogQHBhcmFtIGF1Z21lbnRhdGlvbnMgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVsZW1lbnQoU3RyaW5nIGVsZW1lbnROYW1lLCBBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgc2VwYXJhdG9yIGJldHdlZW4gY2hvaWNlcyBvciBzZXF1ZW5jZXMgb2YgYSBtaXhlZCBvciBjaGlsZHJlbgotICAgICAqIGNvbnRlbnQgbW9kZWwuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc2VwYXJhdG9yIFRoZSB0eXBlIG9mIGNoaWxkcmVuIHNlcGFyYXRvci4KLSAgICAgKiBAcGFyYW0gYXVnbWVudGF0aW9ucyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICoKLSAgICAgKiBAc2VlICNTRVBBUkFUT1JfQ0hPSUNFCi0gICAgICogQHNlZSAjU0VQQVJBVE9SX1NFUVVFTkNFCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2VwYXJhdG9yKHNob3J0IHNlcGFyYXRvciwgQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKQotICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogVGhlIG9jY3VycmVuY2UgY291bnQgZm9yIGEgY2hpbGQgaW4gYSBjaGlsZHJlbiBjb250ZW50IG1vZGVsIG9yCi0gICAgICogZm9yIHRoZSBtaXhlZCBjb250ZW50IG1vZGVsIGdyb3VwLgotICAgICAqCi0gICAgICogQHBhcmFtIG9jY3VycmVuY2UgVGhlIG9jY3VycmVuY2UgY291bnQgZm9yIHRoZSBsYXN0IGVsZW1lbnQKLSAgICAgKiAgICAgICAgICAgICAgICAgICBvciBncm91cC4KLSAgICAgKiBAcGFyYW0gYXVnbWVudGF0aW9ucyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICoKLSAgICAgKiBAc2VlICNPQ0NVUlNfWkVST19PUl9PTkUKLSAgICAgKiBAc2VlICNPQ0NVUlNfWkVST19PUl9NT1JFCi0gICAgICogQHNlZSAjT0NDVVJTX09ORV9PUl9NT1JFCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgb2NjdXJyZW5jZShzaG9ydCBvY2N1cnJlbmNlLCBBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgZW5kIG9mIGEgZ3JvdXAgZm9yIG1peGVkIG9yIGNoaWxkcmVuIGNvbnRlbnQgbW9kZWxzLgotICAgICAqCi0gICAgICogQHBhcmFtIGF1Z21lbnRhdGlvbnMgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZEdyb3VwKEF1Z21lbnRhdGlvbnMgYXVnbWVudGF0aW9ucykgdGhyb3dzIFhOSUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIFRoZSBlbmQgb2YgYSBjb250ZW50IG1vZGVsLgotICAgICAqCi0gICAgICogQHBhcmFtIGF1Z21lbnRhdGlvbnMgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZENvbnRlbnRNb2RlbChBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpIHRocm93cyBYTklFeGNlcHRpb247Ci0KLSAgICAvLyBzZXQgY29udGVudCBtb2RlbCBzb3VyY2UKLSAgICBwdWJsaWMgdm9pZCBzZXREVERDb250ZW50TW9kZWxTb3VyY2UoWE1MRFREQ29udGVudE1vZGVsU291cmNlIHNvdXJjZSk7Ci0KLSAgICAvLyBnZXQgY29udGVudCBtb2RlbCBzb3VyY2UKLSAgICBwdWJsaWMgWE1MRFREQ29udGVudE1vZGVsU291cmNlIGdldERURENvbnRlbnRNb2RlbFNvdXJjZSgpOwotCi19IC8vIGludGVyZmFjZSBYTUxEVERDb250ZW50TW9kZWxIYW5kbGVyCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94bmkvWE1MRFRESGFuZGxlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveG5pL1hNTERUREhhbmRsZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNzM4Nzc2Ni4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94bmkvWE1MRFRESGFuZGxlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzc4ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDAtMjAwMiwyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaTsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxEVERTb3VyY2U7Ci0KLS8qKgotICogVGhlIERURCBoYW5kbGVyIGludGVyZmFjZSBkZWZpbmVzIGNhbGxiYWNrIG1ldGhvZHMgdG8gcmVwb3J0Ci0gKiBpbmZvcm1hdGlvbiBpdGVtcyBpbiB0aGUgRFREIG9mIGFuIFhNTCBkb2N1bWVudC4gUGFyc2VyIGNvbXBvbmVudHMKLSAqIGludGVyZXN0ZWQgaW4gRFREIGluZm9ybWF0aW9uIGltcGxlbWVudCB0aGlzIGludGVyZmFjZSBhbmQgYXJlCi0gKiByZWdpc3RlcmVkIGFzIHRoZSBEVEQgaGFuZGxlciBvbiB0aGUgRFREIHNvdXJjZS4KLSAqCi0gKiBAc2VlIFhNTERURENvbnRlbnRNb2RlbEhhbmRsZXIKLSAqCi0gKiBAYXV0aG9yIEFuZHkgQ2xhcmssIElCTQotICoKLSAqLwotcHVibGljIGludGVyZmFjZSBYTUxEVERIYW5kbGVyIHsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RhbnRzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIENvbmRpdGlvbmFsIHNlY3Rpb246IElOQ0xVREUuCi0gICAgICoKLSAgICAgKiBAc2VlICNDT05ESVRJT05BTF9JR05PUkUKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IENPTkRJVElPTkFMX0lOQ0xVREUgPSAwOwotCi0gICAgLyoqCi0gICAgICogQ29uZGl0aW9uYWwgc2VjdGlvbjogSUdOT1JFLgotICAgICAqCi0gICAgICogQHNlZSAjQ09ORElUSU9OQUxfSU5DTFVERQotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgQ09ORElUSU9OQUxfSUdOT1JFID0gMTsKLQotICAgIC8vCi0gICAgLy8gWE1MRFRESGFuZGxlciBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFRoZSBzdGFydCBvZiB0aGUgRFRELgotICAgICAqCi0gICAgICogQHBhcmFtIGxvY2F0b3IgIFRoZSBkb2N1bWVudCBsb2NhdG9yLCBvciBudWxsIGlmIHRoZSBkb2N1bWVudAotICAgICAqICAgICAgICAgICAgICAgICBsb2NhdGlvbiBjYW5ub3QgYmUgcmVwb3J0ZWQgZHVyaW5nIHRoZSBwYXJzaW5nIG9mCi0gICAgICogICAgICAgICAgICAgICAgIHRoZSBkb2N1bWVudCBEVEQuIEhvd2V2ZXIsIGl0IGlzIDxlbT5zdHJvbmdseTwvZW0+Ci0gICAgICogICAgICAgICAgICAgICAgIHJlY29tbWVuZGVkIHRoYXQgYSBsb2NhdG9yIGJlIHN1cHBsaWVkIHRoYXQgY2FuCi0gICAgICogICAgICAgICAgICAgICAgIGF0IGxlYXN0IHJlcG9ydCB0aGUgYmFzZSBzeXN0ZW0gaWRlbnRpZmllciBvZiB0aGUKLSAgICAgKiAgICAgICAgICAgICAgICAgRFRELgotICAgICAqIEBwYXJhbSBhdWdtZW50YXRpb25zIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydERURChYTUxMb2NhdG9yIGxvY2F0b3IsIEF1Z21lbnRhdGlvbnMgYXVnbWVudGF0aW9ucykKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIG5vdGlmaWVzIG9mIHRoZSBzdGFydCBvZiBhIHBhcmFtZXRlciBlbnRpdHkuIFRoZSBwYXJhbWV0ZXIKLSAgICAgKiBlbnRpdHkgbmFtZSBzdGFydCB3aXRoIGEgJyUnIGNoYXJhY3Rlci4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lICAgICBUaGUgbmFtZSBvZiB0aGUgcGFyYW1ldGVyIGVudGl0eS4KLSAgICAgKiBAcGFyYW0gaWRlbnRpZmllciBUaGUgcmVzb3VyY2UgaWRlbnRpZmllci4KLSAgICAgKiBAcGFyYW0gZW5jb2RpbmcgVGhlIGF1dG8tZGV0ZWN0ZWQgSUFOQSBlbmNvZGluZyBuYW1lIG9mIHRoZSBlbnRpdHkKLSAgICAgKiAgICAgICAgICAgICAgICAgc3RyZWFtLiBUaGlzIHZhbHVlIHdpbGwgYmUgbnVsbCBpbiB0aG9zZSBzaXR1YXRpb25zCi0gICAgICogICAgICAgICAgICAgICAgIHdoZXJlIHRoZSBlbnRpdHkgZW5jb2RpbmcgaXMgbm90IGF1dG8tZGV0ZWN0ZWQgKGUuZy4KLSAgICAgKiAgICAgICAgICAgICAgICAgaW50ZXJuYWwgcGFyYW1ldGVyIGVudGl0aWVzKS4KLSAgICAgKiBAcGFyYW0gYXVnbWVudGF0aW9ucyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnRQYXJhbWV0ZXJFbnRpdHkoU3RyaW5nIG5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MUmVzb3VyY2VJZGVudGlmaWVyIGlkZW50aWZpZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGVuY29kaW5nLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF1Z21lbnRhdGlvbnMgYXVnbWVudGF0aW9ucykgdGhyb3dzIFhOSUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIE5vdGlmaWVzIG9mIHRoZSBwcmVzZW5jZSBvZiBhIFRleHREZWNsIGxpbmUgaW4gYW4gZW50aXR5LiBJZiBwcmVzZW50LAotICAgICAqIHRoaXMgbWV0aG9kIHdpbGwgYmUgY2FsbGVkIGltbWVkaWF0ZWx5IGZvbGxvd2luZyB0aGUgc3RhcnRFbnRpdHkgY2FsbC4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoaXMgbWV0aG9kIGlzIG9ubHkgY2FsbGVkIGZvciBleHRlcm5hbAotICAgICAqIHBhcmFtZXRlciBlbnRpdGllcyByZWZlcmVuY2VkIGluIHRoZSBEVEQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdmVyc2lvbiAgVGhlIFhNTCB2ZXJzaW9uLCBvciBudWxsIGlmIG5vdCBzcGVjaWZpZWQuCi0gICAgICogQHBhcmFtIGVuY29kaW5nIFRoZSBJQU5BIGVuY29kaW5nIG5hbWUgb2YgdGhlIGVudGl0eS4KLSAgICAgKiBAcGFyYW0gYXVnbWVudGF0aW9ucyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdGV4dERlY2woU3RyaW5nIHZlcnNpb24sIFN0cmluZyBlbmNvZGluZywKLSAgICAgICAgICAgICAgICAgICAgICAgICBBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpIHRocm93cyBYTklFeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBub3RpZmllcyB0aGUgZW5kIG9mIGEgcGFyYW1ldGVyIGVudGl0eS4gUGFyYW1ldGVyIGVudGl0eQotICAgICAqIG5hbWVzIGJlZ2luIHdpdGggYSAnJScgY2hhcmFjdGVyLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIHBhcmFtZXRlciBlbnRpdHkuCi0gICAgICogQHBhcmFtIGF1Z21lbnRhdGlvbnMgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZFBhcmFtZXRlckVudGl0eShTdHJpbmcgbmFtZSwgQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKQotICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogVGhlIHN0YXJ0IG9mIHRoZSBEVEQgZXh0ZXJuYWwgc3Vic2V0LgotICAgICAqCi0gICAgICogQHBhcmFtIGlkZW50aWZpZXIgVGhlIHJlc291cmNlIGlkZW50aWZpZXIuCi0gICAgICogQHBhcmFtIGF1Z21lbnRhdGlvbnMKLSAgICAgKiAgICAgICAgICAgICAgICAgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICogQGV4Y2VwdGlvbiBYTklFeGNlcHRpb24KLSAgICAgKiAgICAgICAgICAgICAgICAgICBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnRFeHRlcm5hbFN1YnNldChYTUxSZXNvdXJjZUlkZW50aWZpZXIgaWRlbnRpZmllciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF1Z21lbnRhdGlvbnMgYXVnbWVudGF0aW9ucykKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIFRoZSBlbmQgb2YgdGhlIERURCBleHRlcm5hbCBzdWJzZXQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYXVnbWVudGF0aW9ucyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kRXh0ZXJuYWxTdWJzZXQoQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKQotICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogQSBjb21tZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIHRleHQgVGhlIHRleHQgaW4gdGhlIGNvbW1lbnQuCi0gICAgICogQHBhcmFtIGF1Z21lbnRhdGlvbnMgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGFwcGxpY2F0aW9uIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBjb21tZW50KFhNTFN0cmluZyB0ZXh0LCBBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBBIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24uIFByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb25zIGNvbnNpc3Qgb2YgYQotICAgICAqIHRhcmdldCBuYW1lIGFuZCwgb3B0aW9uYWxseSwgdGV4dCBkYXRhLiBUaGUgZGF0YSBpcyBvbmx5IG1lYW5pbmdmdWwKLSAgICAgKiB0byB0aGUgYXBwbGljYXRpb24uCi0gICAgICogPHA+Ci0gICAgICogVHlwaWNhbGx5LCBhIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24ncyBkYXRhIHdpbGwgY29udGFpbiBhIHNlcmllcwotICAgICAqIG9mIHBzZXVkby1hdHRyaWJ1dGVzLiBUaGVzZSBwc2V1ZG8tYXR0cmlidXRlcyBmb2xsb3cgdGhlIGZvcm0gb2YKLSAgICAgKiBlbGVtZW50IGF0dHJpYnV0ZXMgYnV0IGFyZSA8c3Ryb25nPm5vdDwvc3Ryb25nPiBwYXJzZWQgb3IgcHJlc2VudGVkCi0gICAgICogdG8gdGhlIGFwcGxpY2F0aW9uIGFzIGFueXRoaW5nIG90aGVyIHRoYW4gdGV4dC4gVGhlIGFwcGxpY2F0aW9uIGlzCi0gICAgICogcmVzcG9uc2libGUgZm9yIHBhcnNpbmcgdGhlIGRhdGEuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdGFyZ2V0IFRoZSB0YXJnZXQuCi0gICAgICogQHBhcmFtIGRhdGEgICBUaGUgZGF0YSBvciBudWxsIGlmIG5vbmUgc3BlY2lmaWVkLgotICAgICAqIEBwYXJhbSBhdWdtZW50YXRpb25zIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oU3RyaW5nIHRhcmdldCwgWE1MU3RyaW5nIGRhdGEsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF1Z21lbnRhdGlvbnMgYXVnbWVudGF0aW9ucykKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIEFuIGVsZW1lbnQgZGVjbGFyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSAgICAgICAgIFRoZSBuYW1lIG9mIHRoZSBlbGVtZW50LgotICAgICAqIEBwYXJhbSBjb250ZW50TW9kZWwgVGhlIGVsZW1lbnQgY29udGVudCBtb2RlbC4KLSAgICAgKiBAcGFyYW0gYXVnbWVudGF0aW9ucyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZWxlbWVudERlY2woU3RyaW5nIG5hbWUsIFN0cmluZyBjb250ZW50TW9kZWwsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKQotICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogVGhlIHN0YXJ0IG9mIGFuIGF0dHJpYnV0ZSBsaXN0LgotICAgICAqCi0gICAgICogQHBhcmFtIGVsZW1lbnROYW1lIFRoZSBuYW1lIG9mIHRoZSBlbGVtZW50IHRoYXQgdGhpcyBhdHRyaWJ1dGUKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgbGlzdCBpcyBhc3NvY2lhdGVkIHdpdGguCi0gICAgICogQHBhcmFtIGF1Z21lbnRhdGlvbnMgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0QXR0bGlzdChTdHJpbmcgZWxlbWVudE5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF1Z21lbnRhdGlvbnMgYXVnbWVudGF0aW9ucykgdGhyb3dzIFhOSUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIEFuIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlbGVtZW50TmFtZSAgIFRoZSBuYW1lIG9mIHRoZSBlbGVtZW50IHRoYXQgdGhpcyBhdHRyaWJ1dGUKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBpcyBhc3NvY2lhdGVkIHdpdGguCi0gICAgICogQHBhcmFtIGF0dHJpYnV0ZU5hbWUgVGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgKiBAcGFyYW0gdHlwZSAgICAgICAgICBUaGUgYXR0cmlidXRlIHR5cGUuIFRoaXMgdmFsdWUgd2lsbCBiZSBvbmUgb2YKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICB0aGUgZm9sbG93aW5nOiAiQ0RBVEEiLCAiRU5USVRZIiwgIkVOVElUSUVTIiwKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAiRU5VTUVSQVRJT04iLCAiSUQiLCAiSURSRUYiLCAiSURSRUZTIiwKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAiTk1UT0tFTiIsICJOTVRPS0VOUyIsIG9yICJOT1RBVElPTiIuCi0gICAgICogQHBhcmFtIGVudW1lcmF0aW9uICAgSWYgdGhlIHR5cGUgaGFzIHRoZSB2YWx1ZSAiRU5VTUVSQVRJT04iIG9yCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgIk5PVEFUSU9OIiwgdGhpcyBhcnJheSBob2xkcyB0aGUgYWxsb3dlZCBhdHRyaWJ1dGUKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICB2YWx1ZXM7IG90aGVyd2lzZSwgdGhpcyBhcnJheSBpcyBudWxsLgotICAgICAqIEBwYXJhbSBkZWZhdWx0VHlwZSAgIFRoZSBhdHRyaWJ1dGUgZGVmYXVsdCB0eXBlLiBUaGlzIHZhbHVlIHdpbGwgYmUKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBvbmUgb2YgdGhlIGZvbGxvd2luZzogIiNGSVhFRCIsICIjSU1QTElFRCIsCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgIiNSRVFVSVJFRCIsIG9yIG51bGwuCi0gICAgICogQHBhcmFtIGRlZmF1bHRWYWx1ZSAgVGhlIGF0dHJpYnV0ZSBkZWZhdWx0IHZhbHVlLCBvciBudWxsIGlmIG5vCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdCB2YWx1ZSBpcyBzcGVjaWZpZWQuCi0gICAgICogQHBhcmFtIG5vbk5vcm1hbGl6ZWREZWZhdWx0VmFsdWUgIFRoZSBhdHRyaWJ1dGUgZGVmYXVsdCB2YWx1ZSB3aXRoIG5vIG5vcm1hbGl6YXRpb24KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBwZXJmb3JtZWQsIG9yIG51bGwgaWYgbm8gZGVmYXVsdCB2YWx1ZSBpcyBzcGVjaWZpZWQuCi0gICAgICogQHBhcmFtIGF1Z21lbnRhdGlvbnMgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGF0dHJpYnV0ZURlY2woU3RyaW5nIGVsZW1lbnROYW1lLCBTdHJpbmcgYXR0cmlidXRlTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyB0eXBlLCBTdHJpbmdbXSBlbnVtZXJhdGlvbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBkZWZhdWx0VHlwZSwgWE1MU3RyaW5nIGRlZmF1bHRWYWx1ZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTFN0cmluZyBub25Ob3JtYWxpemVkRGVmYXVsdFZhbHVlLCBBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgZW5kIG9mIGFuIGF0dHJpYnV0ZSBsaXN0LgotICAgICAqCi0gICAgICogQHBhcmFtIGF1Z21lbnRhdGlvbnMgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZEF0dGxpc3QoQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKSB0aHJvd3MgWE5JRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogQW4gaW50ZXJuYWwgZW50aXR5IGRlY2xhcmF0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGVudGl0eS4gUGFyYW1ldGVyIGVudGl0eSBuYW1lcyBzdGFydCB3aXRoCi0gICAgICogICAgICAgICAgICAgJyUnLCB3aGVyZWFzIHRoZSBuYW1lIG9mIGEgZ2VuZXJhbCBlbnRpdHkgaXMganVzdCB0aGUKLSAgICAgKiAgICAgICAgICAgICBlbnRpdHkgbmFtZS4KLSAgICAgKiBAcGFyYW0gdGV4dCBUaGUgdmFsdWUgb2YgdGhlIGVudGl0eS4KLSAgICAgKiBAcGFyYW0gbm9uTm9ybWFsaXplZFRleHQgVGhlIG5vbi1ub3JtYWxpemVkIHZhbHVlIG9mIHRoZSBlbnRpdHkuIFRoaXMKLSAgICAgKiAgICAgICAgICAgICB2YWx1ZSBjb250YWlucyB0aGUgc2FtZSBzZXF1ZW5jZSBvZiBjaGFyYWN0ZXJzIHRoYXQgd2FzIGluCi0gICAgICogICAgICAgICAgICAgdGhlIGludGVybmFsIGVudGl0eSBkZWNsYXJhdGlvbiwgd2l0aG91dCBhbnkgZW50aXR5Ci0gICAgICogICAgICAgICAgICAgcmVmZXJlbmNlcyBleHBhbmRlZC4KLSAgICAgKiBAcGFyYW0gYXVnbWVudGF0aW9ucyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgaW50ZXJuYWxFbnRpdHlEZWNsKFN0cmluZyBuYW1lLCBYTUxTdHJpbmcgdGV4dCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MU3RyaW5nIG5vbk5vcm1hbGl6ZWRUZXh0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBBbiBleHRlcm5hbCBlbnRpdHkgZGVjbGFyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSAgICAgVGhlIG5hbWUgb2YgdGhlIGVudGl0eS4gUGFyYW1ldGVyIGVudGl0eSBuYW1lcyBzdGFydAotICAgICAqICAgICAgICAgICAgICAgICB3aXRoICclJywgd2hlcmVhcyB0aGUgbmFtZSBvZiBhIGdlbmVyYWwgZW50aXR5IGlzIGp1c3QKLSAgICAgKiAgICAgICAgICAgICAgICAgdGhlIGVudGl0eSBuYW1lLgotICAgICAqIEBwYXJhbSBpZGVudGlmaWVyICAgIEFuIG9iamVjdCBjb250YWluaW5nIGFsbCBsb2NhdGlvbiBpbmZvcm1hdGlvbgotICAgICAqICAgICAgICAgICAgICAgICAgICAgIHBlcnRpbmVudCB0byB0aGlzIGV4dGVybmFsIGVudGl0eS4KLSAgICAgKiBAcGFyYW0gYXVnbWVudGF0aW9ucyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZXh0ZXJuYWxFbnRpdHlEZWNsKFN0cmluZyBuYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxSZXNvdXJjZUlkZW50aWZpZXIgaWRlbnRpZmllciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKQotICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogQW4gdW5wYXJzZWQgZW50aXR5IGRlY2xhcmF0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgICAgIFRoZSBuYW1lIG9mIHRoZSBlbnRpdHkuCi0gICAgICogQHBhcmFtIGlkZW50aWZpZXIgICAgQW4gb2JqZWN0IGNvbnRhaW5pbmcgYWxsIGxvY2F0aW9uIGluZm9ybWF0aW9uCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgcGVydGluZW50IHRvIHRoaXMgdW5wYXJzZWQgZW50aXR5IGRlY2xhcmF0aW9uLgotICAgICAqIEBwYXJhbSBub3RhdGlvbiBUaGUgbmFtZSBvZiB0aGUgbm90YXRpb24uCi0gICAgICogQHBhcmFtIGF1Z21lbnRhdGlvbnMgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHVucGFyc2VkRW50aXR5RGVjbChTdHJpbmcgbmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MUmVzb3VyY2VJZGVudGlmaWVyIGlkZW50aWZpZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBub3RhdGlvbiwgQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKQotICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogQSBub3RhdGlvbiBkZWNsYXJhdGlvbgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgICAgIFRoZSBuYW1lIG9mIHRoZSBub3RhdGlvbi4KLSAgICAgKiBAcGFyYW0gaWRlbnRpZmllciAgICBBbiBvYmplY3QgY29udGFpbmluZyBhbGwgbG9jYXRpb24gaW5mb3JtYXRpb24KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBwZXJ0aW5lbnQgdG8gdGhpcyBub3RhdGlvbi4KLSAgICAgKiBAcGFyYW0gYXVnbWVudGF0aW9ucyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgbm90YXRpb25EZWNsKFN0cmluZyBuYW1lLCBYTUxSZXNvdXJjZUlkZW50aWZpZXIgaWRlbnRpZmllciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKSB0aHJvd3MgWE5JRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogVGhlIHN0YXJ0IG9mIGEgY29uZGl0aW9uYWwgc2VjdGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSB0eXBlIFRoZSB0eXBlIG9mIHRoZSBjb25kaXRpb25hbCBzZWN0aW9uLiBUaGlzIHZhbHVlIHdpbGwKLSAgICAgKiAgICAgICAgICAgICBlaXRoZXIgYmUgQ09ORElUSU9OQUxfSU5DTFVERSBvciBDT05ESVRJT05BTF9JR05PUkUuCi0gICAgICogQHBhcmFtIGF1Z21lbnRhdGlvbnMgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqCi0gICAgICogQHNlZSAjQ09ORElUSU9OQUxfSU5DTFVERQotICAgICAqIEBzZWUgI0NPTkRJVElPTkFMX0lHTk9SRQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0Q29uZGl0aW9uYWwoc2hvcnQgdHlwZSwgQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKQotICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogQ2hhcmFjdGVycyB3aXRoaW4gYW4gSUdOT1JFIGNvbmRpdGlvbmFsIHNlY3Rpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdGV4dCBUaGUgaWdub3JlZCB0ZXh0LgotICAgICAqIEBwYXJhbSBhdWdtZW50YXRpb25zIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBpZ25vcmVkQ2hhcmFjdGVycyhYTUxTdHJpbmcgdGV4dCwgQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKQotICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogVGhlIGVuZCBvZiBhIGNvbmRpdGlvbmFsIHNlY3Rpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYXVnbWVudGF0aW9ucyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kQ29uZGl0aW9uYWwoQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKSB0aHJvd3MgWE5JRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogVGhlIGVuZCBvZiB0aGUgRFRELgotICAgICAqCi0gICAgICogQHBhcmFtIGF1Z21lbnRhdGlvbnMgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZERURChBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpIHRocm93cyBYTklFeGNlcHRpb247Ci0KLSAgICAvLyBzZXQgdGhlIHNvdXJjZSBvZiB0aGlzIGhhbmRsZXIKLSAgICBwdWJsaWMgdm9pZCBzZXREVERTb3VyY2UoWE1MRFREU291cmNlIHNvdXJjZSk7Ci0KLSAgICAvLyByZXR1cm4gdGhlIHNvdXJjZSBmcm9tIHdoaWNoIHRoaXMgaGFuZGxlciBkZXJpdmVzIGl0cyBldmVudHMKLSAgICBwdWJsaWMgWE1MRFREU291cmNlIGdldERURFNvdXJjZSgpOwotCi19IC8vIGludGVyZmFjZSBYTUxEVERIYW5kbGVyCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94bmkvWE1MRG9jdW1lbnRGcmFnbWVudEhhbmRsZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3huaS9YTUxEb2N1bWVudEZyYWdtZW50SGFuZGxlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1ZWZiZmNhLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3huaS9YTUxEb2N1bWVudEZyYWdtZW50SGFuZGxlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjU5ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEsIDIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmk7Ci0KLS8qKgotICogVGhpcyBoYW5kbGVyIGludGVyZmFjZSBjb250YWlucyBtZXRob2RzIG5lY2Vzc2FyeSB0byByZWNlaXZlCi0gKiBpbmZvcm1hdGlvbiBhYm91dCBkb2N1bWVudCBlbGVtZW50cyBhbmQgY29udGVudC4KLSAqIDxwPgotICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBTb21lIG9mIHRoZXNlIG1ldGhvZHMgb3ZlcmxhcCBtZXRob2RzCi0gKiBmb3VuZCBpbiB0aGUgWE1MRG9jdW1lbnRIYW5kbGVyIGludGVyZmFjZS4KLSAqCi0gKiBAc2VlIFhNTERvY3VtZW50SGFuZGxlcgotICoKLSAqIEBhdXRob3IgQW5keSBDbGFyaywgSUJNCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgWE1MRG9jdW1lbnRGcmFnbWVudEhhbmRsZXIgewotCi0gICAgLy8KLSAgICAvLyBYTUxEb2N1bWVudEZyYWdtZW50SGFuZGxlciBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFRoZSBzdGFydCBvZiB0aGUgZG9jdW1lbnQgZnJhZ21lbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbG9jYXRvciAgICAgICAgICBUaGUgZG9jdW1lbnQgbG9jYXRvciwgb3IgbnVsbCBpZiB0aGUKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBkb2N1bWVudCBsb2NhdGlvbiBjYW5ub3QgYmUgcmVwb3J0ZWQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBkdXJpbmcgdGhlIHBhcnNpbmcgb2YgdGhpcyBmcmFnbWVudC4KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBIb3dldmVyLCBpdCBpcyA8ZW0+c3Ryb25nbHk8L2VtPgotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIHJlY29tbWVuZGVkIHRoYXQgYSBsb2NhdG9yIGJlIHN1cHBsaWVkCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgdGhhdCBjYW4gYXQgbGVhc3QgcmVwb3J0IHRoZSBiYXNlCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgc3lzdGVtIGlkZW50aWZpZXIuCi0gICAgICogQHBhcmFtIG5hbWVzcGFjZUNvbnRleHQgVGhlIG5hbWVzcGFjZSBjb250ZXh0IGluIGVmZmVjdCBhdCB0aGUKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBzdGFydCBvZiB0aGlzIGRvY3VtZW50IGZyYWdtZW50LiBUaGlzCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0IG9ubHkgcmVwcmVzZW50cyB0aGUgY3VycmVudCBjb250ZXh0LgotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIEltcGxlbWVudG9ycyBvZiB0aGlzIGNsYXNzIGFyZSByZXNwb25zaWJsZQotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIGZvciBjb3B5aW5nIHRoZSBuYW1lc3BhY2UgYmluZGluZ3MgZnJvbSB0aGUKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICB0aGUgY3VycmVudCBjb250ZXh0IChhbmQgaXRzIHBhcmVudCBjb250ZXh0cykKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBpZiB0aGF0IGluZm9ybWF0aW9uIGlzIGltcG9ydGFudC4KLSAgICAgKiBAcGFyYW0gYXVnbWVudGF0aW9ucyAgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnREb2N1bWVudEZyYWdtZW50KFhNTExvY2F0b3IgbG9jYXRvciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmFtZXNwYWNlQ29udGV4dCBuYW1lc3BhY2VDb250ZXh0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBub3RpZmllcyB0aGUgc3RhcnQgb2YgYSBnZW5lcmFsIGVudGl0eS4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoaXMgbWV0aG9kIGlzIG5vdCBjYWxsZWQgZm9yIGVudGl0eSByZWZlcmVuY2VzCi0gICAgICogYXBwZWFyaW5nIGFzIHBhcnQgb2YgYXR0cmlidXRlIHZhbHVlcy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lICAgICBUaGUgbmFtZSBvZiB0aGUgZ2VuZXJhbCBlbnRpdHkuCi0gICAgICogQHBhcmFtIGlkZW50aWZpZXIgVGhlIHJlc291cmNlIGlkZW50aWZpZXIuCi0gICAgICogQHBhcmFtIGVuY29kaW5nIFRoZSBhdXRvLWRldGVjdGVkIElBTkEgZW5jb2RpbmcgbmFtZSBvZiB0aGUgZW50aXR5Ci0gICAgICogICAgICAgICAgICAgICAgIHN0cmVhbS4gVGhpcyB2YWx1ZSB3aWxsIGJlIG51bGwgaW4gdGhvc2Ugc2l0dWF0aW9ucwotICAgICAqICAgICAgICAgICAgICAgICB3aGVyZSB0aGUgZW50aXR5IGVuY29kaW5nIGlzIG5vdCBhdXRvLWRldGVjdGVkIChlLmcuCi0gICAgICogICAgICAgICAgICAgICAgIGludGVybmFsIGVudGl0aWVzIG9yIGEgZG9jdW1lbnQgZW50aXR5IHRoYXQgaXMKLSAgICAgKiAgICAgICAgICAgICAgICAgcGFyc2VkIGZyb20gYSBqYXZhLmlvLlJlYWRlcikuCi0gICAgICogQHBhcmFtIGF1Z21lbnRhdGlvbnMgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0R2VuZXJhbEVudGl0eShTdHJpbmcgbmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MUmVzb3VyY2VJZGVudGlmaWVyIGlkZW50aWZpZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBlbmNvZGluZywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKSB0aHJvd3MgWE5JRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogTm90aWZpZXMgb2YgdGhlIHByZXNlbmNlIG9mIGEgVGV4dERlY2wgbGluZSBpbiBhbiBlbnRpdHkuIElmIHByZXNlbnQsCi0gICAgICogdGhpcyBtZXRob2Qgd2lsbCBiZSBjYWxsZWQgaW1tZWRpYXRlbHkgZm9sbG93aW5nIHRoZSBzdGFydEVudGl0eSBjYWxsLgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gVGhpcyBtZXRob2Qgd2lsbCBuZXZlciBiZSBjYWxsZWQgZm9yIHRoZQotICAgICAqIGRvY3VtZW50IGVudGl0eTsgaXQgaXMgb25seSBjYWxsZWQgZm9yIGV4dGVybmFsIGdlbmVyYWwgZW50aXRpZXMKLSAgICAgKiByZWZlcmVuY2VkIGluIGRvY3VtZW50IGNvbnRlbnQuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGlzIG1ldGhvZCBpcyBub3QgY2FsbGVkIGZvciBlbnRpdHkgcmVmZXJlbmNlcwotICAgICAqIGFwcGVhcmluZyBhcyBwYXJ0IG9mIGF0dHJpYnV0ZSB2YWx1ZXMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdmVyc2lvbiAgVGhlIFhNTCB2ZXJzaW9uLCBvciBudWxsIGlmIG5vdCBzcGVjaWZpZWQuCi0gICAgICogQHBhcmFtIGVuY29kaW5nIFRoZSBJQU5BIGVuY29kaW5nIG5hbWUgb2YgdGhlIGVudGl0eS4KLSAgICAgKiBAcGFyYW0gYXVnbWVudGF0aW9ucyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdGV4dERlY2woU3RyaW5nIHZlcnNpb24sIFN0cmluZyBlbmNvZGluZywKLSAgICAgICAgICAgICAgICAgICAgICAgICBBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpIHRocm93cyBYTklFeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBub3RpZmllcyB0aGUgZW5kIG9mIGEgZ2VuZXJhbCBlbnRpdHkuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGlzIG1ldGhvZCBpcyBub3QgY2FsbGVkIGZvciBlbnRpdHkgcmVmZXJlbmNlcwotICAgICAqIGFwcGVhcmluZyBhcyBwYXJ0IG9mIGF0dHJpYnV0ZSB2YWx1ZXMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgZ2VuZXJhbCBlbnRpdHkuCi0gICAgICogQHBhcmFtIGF1Z21lbnRhdGlvbnMgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZEdlbmVyYWxFbnRpdHkoU3RyaW5nIG5hbWUsIEF1Z21lbnRhdGlvbnMgYXVnbWVudGF0aW9ucykKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIEEgY29tbWVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSB0ZXh0IFRoZSB0ZXh0IGluIHRoZSBjb21tZW50LgotICAgICAqIEBwYXJhbSBhdWdtZW50YXRpb25zIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBhcHBsaWNhdGlvbiB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY29tbWVudChYTUxTdHJpbmcgdGV4dCwgQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKQotICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogQSBwcm9jZXNzaW5nIGluc3RydWN0aW9uLiBQcm9jZXNzaW5nIGluc3RydWN0aW9ucyBjb25zaXN0IG9mIGEKLSAgICAgKiB0YXJnZXQgbmFtZSBhbmQsIG9wdGlvbmFsbHksIHRleHQgZGF0YS4gVGhlIGRhdGEgaXMgb25seSBtZWFuaW5nZnVsCi0gICAgICogdG8gdGhlIGFwcGxpY2F0aW9uLgotICAgICAqIDxwPgotICAgICAqIFR5cGljYWxseSwgYSBwcm9jZXNzaW5nIGluc3RydWN0aW9uJ3MgZGF0YSB3aWxsIGNvbnRhaW4gYSBzZXJpZXMKLSAgICAgKiBvZiBwc2V1ZG8tYXR0cmlidXRlcy4gVGhlc2UgcHNldWRvLWF0dHJpYnV0ZXMgZm9sbG93IHRoZSBmb3JtIG9mCi0gICAgICogZWxlbWVudCBhdHRyaWJ1dGVzIGJ1dCBhcmUgPHN0cm9uZz5ub3Q8L3N0cm9uZz4gcGFyc2VkIG9yIHByZXNlbnRlZAotICAgICAqIHRvIHRoZSBhcHBsaWNhdGlvbiBhcyBhbnl0aGluZyBvdGhlciB0aGFuIHRleHQuIFRoZSBhcHBsaWNhdGlvbiBpcwotICAgICAqIHJlc3BvbnNpYmxlIGZvciBwYXJzaW5nIHRoZSBkYXRhLgotICAgICAqCi0gICAgICogQHBhcmFtIHRhcmdldCBUaGUgdGFyZ2V0LgotICAgICAqIEBwYXJhbSBkYXRhICAgVGhlIGRhdGEgb3IgbnVsbCBpZiBub25lIHNwZWNpZmllZC4KLSAgICAgKiBAcGFyYW0gYXVnbWVudGF0aW9ucyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcHJvY2Vzc2luZ0luc3RydWN0aW9uKFN0cmluZyB0YXJnZXQsIFhNTFN0cmluZyBkYXRhLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgc3RhcnQgb2YgYW4gZWxlbWVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlbGVtZW50ICAgIFRoZSBuYW1lIG9mIHRoZSBlbGVtZW50LgotICAgICAqIEBwYXJhbSBhdHRyaWJ1dGVzIFRoZSBlbGVtZW50IGF0dHJpYnV0ZXMuCi0gICAgICogQHBhcmFtIGF1Z21lbnRhdGlvbnMgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudChRTmFtZSBlbGVtZW50LCBYTUxBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF1Z21lbnRhdGlvbnMgYXVnbWVudGF0aW9ucykgdGhyb3dzIFhOSUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIEFuIGVtcHR5IGVsZW1lbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZWxlbWVudCAgICBUaGUgbmFtZSBvZiB0aGUgZWxlbWVudC4KLSAgICAgKiBAcGFyYW0gYXR0cmlidXRlcyBUaGUgZWxlbWVudCBhdHRyaWJ1dGVzLgotICAgICAqIEBwYXJhbSBhdWdtZW50YXRpb25zIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbXB0eUVsZW1lbnQoUU5hbWUgZWxlbWVudCwgWE1MQXR0cmlidXRlcyBhdHRyaWJ1dGVzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpIHRocm93cyBYTklFeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBDaGFyYWN0ZXIgY29udGVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSB0ZXh0IFRoZSBjb250ZW50LgotICAgICAqIEBwYXJhbSBhdWdtZW50YXRpb25zIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBjaGFyYWN0ZXJzKFhNTFN0cmluZyB0ZXh0LCBBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBJZ25vcmFibGUgd2hpdGVzcGFjZS4gRm9yIHRoaXMgbWV0aG9kIHRvIGJlIGNhbGxlZCwgdGhlIGRvY3VtZW50Ci0gICAgICogc291cmNlIG11c3QgaGF2ZSBzb21lIHdheSBvZiBkZXRlcm1pbmluZyB0aGF0IHRoZSB0ZXh0IGNvbnRhaW5pbmcKLSAgICAgKiBvbmx5IHdoaXRlc3BhY2UgY2hhcmFjdGVycyBzaG91bGQgYmUgY29uc2lkZXJlZCBpZ25vcmFibGUuIEZvcgotICAgICAqIGV4YW1wbGUsIHRoZSB2YWxpZGF0b3IgY2FuIGRldGVybWluZSBpZiBhIGxlbmd0aCBvZiB3aGl0ZXNwYWNlCi0gICAgICogY2hhcmFjdGVycyBpbiB0aGUgZG9jdW1lbnQgYXJlIGlnbm9yYWJsZSBiYXNlZCBvbiB0aGUgZWxlbWVudAotICAgICAqIGNvbnRlbnQgbW9kZWwuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdGV4dCBUaGUgaWdub3JhYmxlIHdoaXRlc3BhY2UuCi0gICAgICogQHBhcmFtIGF1Z21lbnRhdGlvbnMgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGlnbm9yYWJsZVdoaXRlc3BhY2UoWE1MU3RyaW5nIHRleHQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgZW5kIG9mIGFuIGVsZW1lbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZWxlbWVudCBUaGUgbmFtZSBvZiB0aGUgZWxlbWVudC4KLSAgICAgKiBAcGFyYW0gYXVnbWVudGF0aW9ucyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kRWxlbWVudChRTmFtZSBlbGVtZW50LCBBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgc3RhcnQgb2YgYSBDREFUQSBzZWN0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIGF1Z21lbnRhdGlvbnMgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0Q0RBVEEoQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKSB0aHJvd3MgWE5JRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogVGhlIGVuZCBvZiBhIENEQVRBIHNlY3Rpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYXVnbWVudGF0aW9ucyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kQ0RBVEEoQXVnbWVudGF0aW9ucyBhdWdtZW50YXRpb25zKSB0aHJvd3MgWE5JRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogVGhlIGVuZCBvZiB0aGUgZG9jdW1lbnQgZnJhZ21lbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYXVnbWVudGF0aW9ucyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGF1Z21lbnRhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kRG9jdW1lbnRGcmFnbWVudChBdWdtZW50YXRpb25zIGF1Z21lbnRhdGlvbnMpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb247Ci0KLX0gLy8gaW50ZXJmYWNlIFhNTERvY3VtZW50RnJhZ21lbnRIYW5kbGVyCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94bmkvWE1MRG9jdW1lbnRIYW5kbGVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94bmkvWE1MRG9jdW1lbnRIYW5kbGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDE4ZDBjMWMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveG5pL1hNTERvY3VtZW50SGFuZGxlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjk2ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDAtMjAwMiwyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaTsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxEb2N1bWVudFNvdXJjZTsKLQotLyoqCi0gKiBUaGUgZG9jdW1lbnQgaGFuZGxlciBpbnRlcmZhY2UgZGVmaW5lcyBjYWxsYmFjayBtZXRob2RzIHRvIHJlcG9ydAotICogaW5mb3JtYXRpb24gaXRlbXMgaW4gWE1MIGRvY3VtZW50cy4gUGFyc2VyIGNvbXBvbmVudHMgaW50ZXJlc3RlZCBpbgotICogZG9jdW1lbnQgaW5mb3JtYXRpb24gaW1wbGVtZW50IHRoaXMgaW50ZXJmYWNlIGFuZCBhcmUgcmVnaXN0ZXJlZAotICogYXMgdGhlIGRvY3VtZW50IGhhbmRsZXIgb24gdGhlIGRvY3VtZW50IHNvdXJjZS4KLSAqCi0gKiBAYXV0aG9yIEFuZHkgQ2xhcmssIElCTQotICoKLSAqLwotcHVibGljIGludGVyZmFjZSBYTUxEb2N1bWVudEhhbmRsZXIgewotCi0gICAgLy8KLSAgICAvLyBYTUxEb2N1bWVudEhhbmRsZXIgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBUaGUgc3RhcnQgb2YgdGhlIGRvY3VtZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIGxvY2F0b3IgIFRoZSBkb2N1bWVudCBsb2NhdG9yLCBvciBudWxsIGlmIHRoZSBkb2N1bWVudAotICAgICAqICAgICAgICAgICAgICAgICBsb2NhdGlvbiBjYW5ub3QgYmUgcmVwb3J0ZWQgZHVyaW5nIHRoZSBwYXJzaW5nCi0gICAgICogICAgICAgICAgICAgICAgIG9mIHRoaXMgZG9jdW1lbnQuIEhvd2V2ZXIsIGl0IGlzIDxlbT5zdHJvbmdseTwvZW0+Ci0gICAgICogICAgICAgICAgICAgICAgIHJlY29tbWVuZGVkIHRoYXQgYSBsb2NhdG9yIGJlIHN1cHBsaWVkIHRoYXQgY2FuCi0gICAgICogICAgICAgICAgICAgICAgIGF0IGxlYXN0IHJlcG9ydCB0aGUgc3lzdGVtIGlkZW50aWZpZXIgb2YgdGhlCi0gICAgICogICAgICAgICAgICAgICAgIGRvY3VtZW50LgotICAgICAqIEBwYXJhbSBlbmNvZGluZyBUaGUgYXV0by1kZXRlY3RlZCBJQU5BIGVuY29kaW5nIG5hbWUgb2YgdGhlIGVudGl0eQotICAgICAqICAgICAgICAgICAgICAgICBzdHJlYW0uIFRoaXMgdmFsdWUgd2lsbCBiZSBudWxsIGluIHRob3NlIHNpdHVhdGlvbnMKLSAgICAgKiAgICAgICAgICAgICAgICAgd2hlcmUgdGhlIGVudGl0eSBlbmNvZGluZyBpcyBub3QgYXV0by1kZXRlY3RlZCAoZS5nLgotICAgICAqICAgICAgICAgICAgICAgICBpbnRlcm5hbCBlbnRpdGllcyBvciBhIGRvY3VtZW50IGVudGl0eSB0aGF0IGlzCi0gICAgICogICAgICAgICAgICAgICAgIHBhcnNlZCBmcm9tIGEgamF2YS5pby5SZWFkZXIpLgotICAgICAqIEBwYXJhbSBuYW1lc3BhY2VDb250ZXh0Ci0gICAgICogICAgICAgICAgICAgICAgIFRoZSBuYW1lc3BhY2UgY29udGV4dCBpbiBlZmZlY3QgYXQgdGhlCi0gICAgICogICAgICAgICAgICAgICAgIHN0YXJ0IG9mIHRoaXMgZG9jdW1lbnQuCi0gICAgICogICAgICAgICAgICAgICAgIFRoaXMgb2JqZWN0IHJlcHJlc2VudHMgdGhlIGN1cnJlbnQgY29udGV4dC4KLSAgICAgKiAgICAgICAgICAgICAgICAgSW1wbGVtZW50b3JzIG9mIHRoaXMgY2xhc3MgYXJlIHJlc3BvbnNpYmxlCi0gICAgICogICAgICAgICAgICAgICAgIGZvciBjb3B5aW5nIHRoZSBuYW1lc3BhY2UgYmluZGluZ3MgZnJvbSB0aGUKLSAgICAgKiAgICAgICAgICAgICAgICAgdGhlIGN1cnJlbnQgY29udGV4dCAoYW5kIGl0cyBwYXJlbnQgY29udGV4dHMpCi0gICAgICogICAgICAgICAgICAgICAgIGlmIHRoYXQgaW5mb3JtYXRpb24gaXMgaW1wb3J0YW50LgotICAgICAqCi0gICAgICogQHBhcmFtIGF1Z3MgICAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKiBAZXhjZXB0aW9uIFhOSUV4Y2VwdGlvbgotICAgICAqICAgICAgICAgICAgICAgICAgIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydERvY3VtZW50KFhNTExvY2F0b3IgbG9jYXRvciwgU3RyaW5nIGVuY29kaW5nLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmFtZXNwYWNlQ29udGV4dCBuYW1lc3BhY2VDb250ZXh0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXVnbWVudGF0aW9ucyBhdWdzKQotICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogTm90aWZpZXMgb2YgdGhlIHByZXNlbmNlIG9mIGFuIFhNTERlY2wgbGluZSBpbiB0aGUgZG9jdW1lbnQuIElmCi0gICAgICogcHJlc2VudCwgdGhpcyBtZXRob2Qgd2lsbCBiZSBjYWxsZWQgaW1tZWRpYXRlbHkgZm9sbG93aW5nIHRoZQotICAgICAqIHN0YXJ0RG9jdW1lbnQgY2FsbC4KLSAgICAgKgotICAgICAqIEBwYXJhbSB2ZXJzaW9uICAgIFRoZSBYTUwgdmVyc2lvbi4KLSAgICAgKiBAcGFyYW0gZW5jb2RpbmcgICBUaGUgSUFOQSBlbmNvZGluZyBuYW1lIG9mIHRoZSBkb2N1bWVudCwgb3IgbnVsbCBpZgotICAgICAqICAgICAgICAgICAgICAgICAgIG5vdCBzcGVjaWZpZWQuCi0gICAgICogQHBhcmFtIHN0YW5kYWxvbmUgVGhlIHN0YW5kYWxvbmUgdmFsdWUsIG9yIG51bGwgaWYgbm90IHNwZWNpZmllZC4KLSAgICAgKiBAcGFyYW0gYXVncyAgICAgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIFhOSUV4Y2VwdGlvbgotICAgICAqICAgICAgICAgICAgICAgICAgIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB4bWxEZWNsKFN0cmluZyB2ZXJzaW9uLCBTdHJpbmcgZW5jb2RpbmcsIFN0cmluZyBzdGFuZGFsb25lLCBBdWdtZW50YXRpb25zIGF1Z3MpCi0gICAgICAgIHRocm93cyBYTklFeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBOb3RpZmllcyBvZiB0aGUgcHJlc2VuY2Ugb2YgdGhlIERPQ1RZUEUgbGluZSBpbiB0aGUgZG9jdW1lbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcm9vdEVsZW1lbnQKLSAgICAgKiAgICAgICAgICAgICAgICAgVGhlIG5hbWUgb2YgdGhlIHJvb3QgZWxlbWVudC4KLSAgICAgKiBAcGFyYW0gcHVibGljSWQgVGhlIHB1YmxpYyBpZGVudGlmaWVyIGlmIGFuIGV4dGVybmFsIERURCBvciBudWxsCi0gICAgICogICAgICAgICAgICAgICAgIGlmIHRoZSBleHRlcm5hbCBEVEQgaXMgc3BlY2lmaWVkIHVzaW5nIFNZU1RFTS4KLSAgICAgKiBAcGFyYW0gc3lzdGVtSWQgVGhlIHN5c3RlbSBpZGVudGlmaWVyIGlmIGFuIGV4dGVybmFsIERURCwgbnVsbAotICAgICAqICAgICAgICAgICAgICAgICBvdGhlcndpc2UuCi0gICAgICogQHBhcmFtIGF1Z3MgICAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKgotICAgICAqIEBleGNlcHRpb24gWE5JRXhjZXB0aW9uCi0gICAgICogICAgICAgICAgICAgICAgICAgVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGRvY3R5cGVEZWNsKFN0cmluZyByb290RWxlbWVudCwgU3RyaW5nIHB1YmxpY0lkLCBTdHJpbmcgc3lzdGVtSWQsIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIEEgY29tbWVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSB0ZXh0ICAgVGhlIHRleHQgaW4gdGhlIGNvbW1lbnQuCi0gICAgICogQHBhcmFtIGF1Z3MgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIFhOSUV4Y2VwdGlvbgotICAgICAqICAgICAgICAgICAgICAgICAgIFRocm93biBieSBhcHBsaWNhdGlvbiB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY29tbWVudChYTUxTdHJpbmcgdGV4dCwgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogQSBwcm9jZXNzaW5nIGluc3RydWN0aW9uLiBQcm9jZXNzaW5nIGluc3RydWN0aW9ucyBjb25zaXN0IG9mIGEKLSAgICAgKiB0YXJnZXQgbmFtZSBhbmQsIG9wdGlvbmFsbHksIHRleHQgZGF0YS4gVGhlIGRhdGEgaXMgb25seSBtZWFuaW5nZnVsCi0gICAgICogdG8gdGhlIGFwcGxpY2F0aW9uLgotICAgICAqIDxwPgotICAgICAqIFR5cGljYWxseSwgYSBwcm9jZXNzaW5nIGluc3RydWN0aW9uJ3MgZGF0YSB3aWxsIGNvbnRhaW4gYSBzZXJpZXMKLSAgICAgKiBvZiBwc2V1ZG8tYXR0cmlidXRlcy4gVGhlc2UgcHNldWRvLWF0dHJpYnV0ZXMgZm9sbG93IHRoZSBmb3JtIG9mCi0gICAgICogZWxlbWVudCBhdHRyaWJ1dGVzIGJ1dCBhcmUgPHN0cm9uZz5ub3Q8L3N0cm9uZz4gcGFyc2VkIG9yIHByZXNlbnRlZAotICAgICAqIHRvIHRoZSBhcHBsaWNhdGlvbiBhcyBhbnl0aGluZyBvdGhlciB0aGFuIHRleHQuIFRoZSBhcHBsaWNhdGlvbiBpcwotICAgICAqIHJlc3BvbnNpYmxlIGZvciBwYXJzaW5nIHRoZSBkYXRhLgotICAgICAqCi0gICAgICogQHBhcmFtIHRhcmdldCBUaGUgdGFyZ2V0LgotICAgICAqIEBwYXJhbSBkYXRhICAgVGhlIGRhdGEgb3IgbnVsbCBpZiBub25lIHNwZWNpZmllZC4KLSAgICAgKiBAcGFyYW0gYXVncyAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKgotICAgICAqIEBleGNlcHRpb24gWE5JRXhjZXB0aW9uCi0gICAgICogICAgICAgICAgICAgICAgICAgVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHByb2Nlc3NpbmdJbnN0cnVjdGlvbihTdHJpbmcgdGFyZ2V0LCBYTUxTdHJpbmcgZGF0YSwgQXVnbWVudGF0aW9ucyBhdWdzKQotICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogVGhlIHN0YXJ0IG9mIGFuIGVsZW1lbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZWxlbWVudCAgICBUaGUgbmFtZSBvZiB0aGUgZWxlbWVudC4KLSAgICAgKiBAcGFyYW0gYXR0cmlidXRlcyBUaGUgZWxlbWVudCBhdHRyaWJ1dGVzLgotICAgICAqIEBwYXJhbSBhdWdzICAgICAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKgotICAgICAqIEBleGNlcHRpb24gWE5JRXhjZXB0aW9uCi0gICAgICogICAgICAgICAgICAgICAgICAgVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudChRTmFtZSBlbGVtZW50LCBYTUxBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMsIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIEFuIGVtcHR5IGVsZW1lbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZWxlbWVudCAgICBUaGUgbmFtZSBvZiB0aGUgZWxlbWVudC4KLSAgICAgKiBAcGFyYW0gYXR0cmlidXRlcyBUaGUgZWxlbWVudCBhdHRyaWJ1dGVzLgotICAgICAqIEBwYXJhbSBhdWdzICAgICAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKgotICAgICAqIEBleGNlcHRpb24gWE5JRXhjZXB0aW9uCi0gICAgICogICAgICAgICAgICAgICAgICAgVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVtcHR5RWxlbWVudChRTmFtZSBlbGVtZW50LCBYTUxBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMsIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIG5vdGlmaWVzIHRoZSBzdGFydCBvZiBhIGdlbmVyYWwgZW50aXR5LgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gVGhpcyBtZXRob2QgaXMgbm90IGNhbGxlZCBmb3IgZW50aXR5IHJlZmVyZW5jZXMKLSAgICAgKiBhcHBlYXJpbmcgYXMgcGFydCBvZiBhdHRyaWJ1dGUgdmFsdWVzLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgICAgIFRoZSBuYW1lIG9mIHRoZSBnZW5lcmFsIGVudGl0eS4KLSAgICAgKiBAcGFyYW0gaWRlbnRpZmllciBUaGUgcmVzb3VyY2UgaWRlbnRpZmllci4KLSAgICAgKiBAcGFyYW0gZW5jb2RpbmcgVGhlIGF1dG8tZGV0ZWN0ZWQgSUFOQSBlbmNvZGluZyBuYW1lIG9mIHRoZSBlbnRpdHkKLSAgICAgKiAgICAgICAgICAgICAgICAgc3RyZWFtLiBUaGlzIHZhbHVlIHdpbGwgYmUgbnVsbCBpbiB0aG9zZSBzaXR1YXRpb25zCi0gICAgICogICAgICAgICAgICAgICAgIHdoZXJlIHRoZSBlbnRpdHkgZW5jb2RpbmcgaXMgbm90IGF1dG8tZGV0ZWN0ZWQgKGUuZy4KLSAgICAgKiAgICAgICAgICAgICAgICAgaW50ZXJuYWwgZW50aXRpZXMgb3IgYSBkb2N1bWVudCBlbnRpdHkgdGhhdCBpcwotICAgICAqICAgICAgICAgICAgICAgICBwYXJzZWQgZnJvbSBhIGphdmEuaW8uUmVhZGVyKS4KLSAgICAgKiBAcGFyYW0gYXVncyAgICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0R2VuZXJhbEVudGl0eShTdHJpbmcgbmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MUmVzb3VyY2VJZGVudGlmaWVyIGlkZW50aWZpZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBlbmNvZGluZywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogTm90aWZpZXMgb2YgdGhlIHByZXNlbmNlIG9mIGEgVGV4dERlY2wgbGluZSBpbiBhbiBlbnRpdHkuIElmIHByZXNlbnQsCi0gICAgICogdGhpcyBtZXRob2Qgd2lsbCBiZSBjYWxsZWQgaW1tZWRpYXRlbHkgZm9sbG93aW5nIHRoZSBzdGFydEVudGl0eSBjYWxsLgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gVGhpcyBtZXRob2Qgd2lsbCBuZXZlciBiZSBjYWxsZWQgZm9yIHRoZQotICAgICAqIGRvY3VtZW50IGVudGl0eTsgaXQgaXMgb25seSBjYWxsZWQgZm9yIGV4dGVybmFsIGdlbmVyYWwgZW50aXRpZXMKLSAgICAgKiByZWZlcmVuY2VkIGluIGRvY3VtZW50IGNvbnRlbnQuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGlzIG1ldGhvZCBpcyBub3QgY2FsbGVkIGZvciBlbnRpdHkgcmVmZXJlbmNlcwotICAgICAqIGFwcGVhcmluZyBhcyBwYXJ0IG9mIGF0dHJpYnV0ZSB2YWx1ZXMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdmVyc2lvbiAgVGhlIFhNTCB2ZXJzaW9uLCBvciBudWxsIGlmIG5vdCBzcGVjaWZpZWQuCi0gICAgICogQHBhcmFtIGVuY29kaW5nIFRoZSBJQU5BIGVuY29kaW5nIG5hbWUgb2YgdGhlIGVudGl0eS4KLSAgICAgKiBAcGFyYW0gYXVncyAgICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBYTklFeGNlcHRpb24KLSAgICAgKiAgICAgICAgICAgICAgICAgICBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdGV4dERlY2woU3RyaW5nIHZlcnNpb24sIFN0cmluZyBlbmNvZGluZywgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2Qgbm90aWZpZXMgdGhlIGVuZCBvZiBhIGdlbmVyYWwgZW50aXR5LgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gVGhpcyBtZXRob2QgaXMgbm90IGNhbGxlZCBmb3IgZW50aXR5IHJlZmVyZW5jZXMKLSAgICAgKiBhcHBlYXJpbmcgYXMgcGFydCBvZiBhdHRyaWJ1dGUgdmFsdWVzLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgICBUaGUgbmFtZSBvZiB0aGUgZW50aXR5LgotICAgICAqIEBwYXJhbSBhdWdzICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBYTklFeGNlcHRpb24KLSAgICAgKiAgICAgICAgICAgICAgICAgICBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kR2VuZXJhbEVudGl0eShTdHJpbmcgbmFtZSwgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogQ2hhcmFjdGVyIGNvbnRlbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdGV4dCAgIFRoZSBjb250ZW50LgotICAgICAqIEBwYXJhbSBhdWdzICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBYTklFeGNlcHRpb24KLSAgICAgKiAgICAgICAgICAgICAgICAgICBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY2hhcmFjdGVycyhYTUxTdHJpbmcgdGV4dCwgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogSWdub3JhYmxlIHdoaXRlc3BhY2UuIEZvciB0aGlzIG1ldGhvZCB0byBiZSBjYWxsZWQsIHRoZSBkb2N1bWVudAotICAgICAqIHNvdXJjZSBtdXN0IGhhdmUgc29tZSB3YXkgb2YgZGV0ZXJtaW5pbmcgdGhhdCB0aGUgdGV4dCBjb250YWluaW5nCi0gICAgICogb25seSB3aGl0ZXNwYWNlIGNoYXJhY3RlcnMgc2hvdWxkIGJlIGNvbnNpZGVyZWQgaWdub3JhYmxlLiBGb3IKLSAgICAgKiBleGFtcGxlLCB0aGUgdmFsaWRhdG9yIGNhbiBkZXRlcm1pbmUgaWYgYSBsZW5ndGggb2Ygd2hpdGVzcGFjZQotICAgICAqIGNoYXJhY3RlcnMgaW4gdGhlIGRvY3VtZW50IGFyZSBpZ25vcmFibGUgYmFzZWQgb24gdGhlIGVsZW1lbnQKLSAgICAgKiBjb250ZW50IG1vZGVsLgotICAgICAqCi0gICAgICogQHBhcmFtIHRleHQgICBUaGUgaWdub3JhYmxlIHdoaXRlc3BhY2UuCi0gICAgICogQHBhcmFtIGF1Z3MgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIFhOSUV4Y2VwdGlvbgotICAgICAqICAgICAgICAgICAgICAgICAgIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBpZ25vcmFibGVXaGl0ZXNwYWNlKFhNTFN0cmluZyB0ZXh0LCBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgZW5kIG9mIGFuIGVsZW1lbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZWxlbWVudCBUaGUgbmFtZSBvZiB0aGUgZWxlbWVudC4KLSAgICAgKiBAcGFyYW0gYXVncyAgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIFhOSUV4Y2VwdGlvbgotICAgICAqICAgICAgICAgICAgICAgICAgIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbmRFbGVtZW50KFFOYW1lIGVsZW1lbnQsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIFRoZSBzdGFydCBvZiBhIENEQVRBIHNlY3Rpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYXVncyAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKgotICAgICAqIEBleGNlcHRpb24gWE5JRXhjZXB0aW9uCi0gICAgICogICAgICAgICAgICAgICAgICAgVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0Q0RBVEEoQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogVGhlIGVuZCBvZiBhIENEQVRBIHNlY3Rpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYXVncyAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKgotICAgICAqIEBleGNlcHRpb24gWE5JRXhjZXB0aW9uCi0gICAgICogICAgICAgICAgICAgICAgICAgVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZENEQVRBKEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIFRoZSBlbmQgb2YgdGhlIGRvY3VtZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIGF1Z3MgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIFhOSUV4Y2VwdGlvbgotICAgICAqICAgICAgICAgICAgICAgICAgIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbmREb2N1bWVudChBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb247Ci0KLQotICAgIC8qKiBTZXRzIHRoZSBkb2N1bWVudCBzb3VyY2UuICovCi0gICAgcHVibGljIHZvaWQgc2V0RG9jdW1lbnRTb3VyY2UoWE1MRG9jdW1lbnRTb3VyY2Ugc291cmNlKTsKLQotCi0gICAgLyoqIFJldHVybnMgdGhlIGRvY3VtZW50IHNvdXJjZS4gKi8KLSAgICBwdWJsaWMgWE1MRG9jdW1lbnRTb3VyY2UgZ2V0RG9jdW1lbnRTb3VyY2UoKTsKLQotfSAvLyBpbnRlcmZhY2UgWE1MRG9jdW1lbnRIYW5kbGVyCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94bmkvWE1MTG9jYXRvci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveG5pL1hNTExvY2F0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggN2FiMGY4Ni4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94bmkvWE1MTG9jYXRvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNzkgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaTsKLQotLyoqCi0gKiBMb2NhdGlvbiBpbmZvcm1hdGlvbi4KLSAqCi0gKiBAYXV0aG9yIEFuZHkgQ2xhcmssIElCTQotICoKLSAqLwotcHVibGljIGludGVyZmFjZSBYTUxMb2NhdG9yIHsKLQotICAgIC8vCi0gICAgLy8gWE1MTG9jYXRvciBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKiBSZXR1cm5zIHRoZSBwdWJsaWMgaWRlbnRpZmllci4gKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFB1YmxpY0lkKCk7Ci0KLSAgICAvKiogUmV0dXJucyB0aGUgbGl0ZXJhbCBzeXN0ZW0gaWRlbnRpZmllci4gKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldExpdGVyYWxTeXN0ZW1JZCgpOwotCi0gICAgLyoqIFJldHVybnMgdGhlIGJhc2Ugc3lzdGVtIGlkZW50aWZpZXIuICovCi0gICAgcHVibGljIFN0cmluZyBnZXRCYXNlU3lzdGVtSWQoKTsKLQotICAgIC8qKiBSZXR1cm5zIHRoZSBleHBhbmRlZCBzeXN0ZW0gaWRlbnRpZmllci4gKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEV4cGFuZGVkU3lzdGVtSWQoKTsKLQotICAgIC8qKiBSZXR1cm5zIHRoZSBsaW5lIG51bWJlciwgb3IgPGNvZGU+LTE8L2NvZGU+IGlmIG5vIGxpbmUgbnVtYmVyIGlzIGF2YWlsYWJsZS4gKi8KLSAgICBwdWJsaWMgaW50IGdldExpbmVOdW1iZXIoKTsKLQotICAgIC8qKiBSZXR1cm5zIHRoZSBjb2x1bW4gbnVtYmVyLCBvciA8Y29kZT4tMTwvY29kZT4gaWYgbm8gY29sdW1uIG51bWJlciBpcyBhdmFpbGFibGUuICovCi0gICAgcHVibGljIGludCBnZXRDb2x1bW5OdW1iZXIoKTsKLQotICAgIC8qKiBSZXR1cm5zIHRoZSBjaGFyYWN0ZXIgb2Zmc2V0LCBvciA8Y29kZT4tMTwvY29kZT4gaWYgbm8gY2hhcmFjdGVyIG9mZnNldCBpcyBhdmFpbGFibGUuICovCi0gICAgcHVibGljIGludCBnZXRDaGFyYWN0ZXJPZmZzZXQoKTsKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIGVuY29kaW5nIG9mIHRoZSBjdXJyZW50IGVudGl0eS4KLSAgICAgKiBOb3RlIHRoYXQsIGZvciBhIGdpdmVuIGVudGl0eSwgdGhpcyB2YWx1ZSBjYW4gb25seSBiZQotICAgICAqIGNvbnNpZGVyZWQgZmluYWwgb25jZSB0aGUgZW5jb2RpbmcgZGVjbGFyYXRpb24gaGFzIGJlZW4gcmVhZCAob3Igb25jZSBpdAotICAgICAqIGhhcyBiZWVuIGRldGVybWluZWQgdGhhdCB0aGVyZSBpcyBubyBzdWNoIGRlY2xhcmF0aW9uKSBzaW5jZSwgbm8gZW5jb2RpbmcKLSAgICAgKiBoYXZpbmcgYmVlbiBzcGVjaWZpZWQgb24gdGhlIFhNTElucHV0U291cmNlLCB0aGUgcGFyc2VyCi0gICAgICogd2lsbCBtYWtlIGFuIGluaXRpYWwgImd1ZXNzIiB3aGljaCBjb3VsZCBiZSBpbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEVuY29kaW5nKCk7Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBYTUwgdmVyc2lvbiBvZiB0aGUgY3VycmVudCBlbnRpdHkuIFRoaXMgd2lsbCBub3JtYWxseSBiZSB0aGUKLSAgICAgKiB2YWx1ZSBmcm9tIHRoZSBYTUwgb3IgdGV4dCBkZWNsYXJhdGlvbiBvciBkZWZhdWx0ZWQgYnkgdGhlIHBhcnNlci4gTm90ZSB0aGF0Ci0gICAgICogdGhhdCB0aGlzIHZhbHVlIG1heSBiZSBkaWZmZXJlbnQgdGhhbiB0aGUgdmVyc2lvbiBvZiB0aGUgcHJvY2Vzc2luZyBydWxlcwotICAgICAqIGFwcGxpZWQgdG8gdGhlIGN1cnJlbnQgZW50aXR5LiBGb3IgaW5zdGFuY2UsIGFuIFhNTCAxLjEgZG9jdW1lbnQgbWF5IHJlZmVyIHRvCi0gICAgICogWE1MIDEuMCBlbnRpdGllcy4gSW4gc3VjaCBhIGNhc2UgdGhlIHJ1bGVzIG9mIFhNTCAxLjEgYXJlIGFwcGxpZWQgdG8gdGhlIGVudGlyZQotICAgICAqIGRvY3VtZW50LiBBbHNvIG5vdGUgdGhhdCwgZm9yIGEgZ2l2ZW4gZW50aXR5LCB0aGlzIHZhbHVlIGNhbiBvbmx5IGJlIGNvbnNpZGVyZWQKLSAgICAgKiBmaW5hbCBvbmNlIHRoZSBYTUwgb3IgdGV4dCBkZWNsYXJhdGlvbiBoYXMgYmVlbiByZWFkIG9yIG9uY2UgaXQgaGFzIGJlZW4KLSAgICAgKiBkZXRlcm1pbmVkIHRoYXQgdGhlcmUgaXMgbm8gc3VjaCBkZWNsYXJhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFhNTFZlcnNpb24oKTsKLQotCi19IC8vIGludGVyZmFjZSBYTUxMb2NhdG9yCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94bmkvWE1MUmVzb3VyY2VJZGVudGlmaWVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94bmkvWE1MUmVzb3VyY2VJZGVudGlmaWVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGY3NDhkNjIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveG5pL1hNTFJlc291cmNlSWRlbnRpZmllci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNjQgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMC0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaTsKLQotLyoqCi0gKiA8cD4gVGhpcyByZXByZXNlbnRzIHRoZSBiYXNpYyBwaHlzaWNhbCBkZXNjcmlwdGlvbiBvZiB0aGUgbG9jYXRpb24gb2YgYW55Ci0gKiBYTUwgcmVzb3VyY2UgKGEgU2NoZW1hIGdyYW1tYXIsIGEgRFRELCBhIGdlbmVyYWwgZW50aXR5IGV0Yy4pIDwvcD4KLSAqCi0gKiBAYXV0aG9yIE5laWwgR3JhaGFtLCBJQk0KLSAqLwotCi1wdWJsaWMgaW50ZXJmYWNlIFhNTFJlc291cmNlSWRlbnRpZmllciB7Ci0KLSAgICAvKiogU2V0cyB0aGUgcHVibGljIGlkZW50aWZpZXIuICovCi0gICAgcHVibGljIHZvaWQgc2V0UHVibGljSWQoU3RyaW5nIHB1YmxpY0lkKTsKLQotICAgIC8qKiBSZXR1cm5zIHRoZSBwdWJsaWMgaWRlbnRpZmllci4gKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFB1YmxpY0lkKCk7Ci0KLSAgICAvKiogU2V0cyB0aGUgZXhwYW5kZWQgc3lzdGVtIGlkZW50aWZpZXIuICovCi0gICAgcHVibGljIHZvaWQgc2V0RXhwYW5kZWRTeXN0ZW1JZChTdHJpbmcgc3lzdGVtSWQpOwotCi0gICAgLyoqIFJldHVybnMgdGhlIGV4cGFuZGVkIHN5c3RlbSBpZGVudGlmaWVyLiAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0RXhwYW5kZWRTeXN0ZW1JZCgpOwotCi0gICAgLyoqIFNldHMgdGhlIGxpdGVyYWwgc3lzdGVtIGlkZW50aWZpZXIuICovCi0gICAgcHVibGljIHZvaWQgc2V0TGl0ZXJhbFN5c3RlbUlkKFN0cmluZyBzeXN0ZW1JZCk7Ci0KLSAgICAvKiogUmV0dXJucyB0aGUgbGl0ZXJhbCBzeXN0ZW0gaWRlbnRpZmllci4gKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldExpdGVyYWxTeXN0ZW1JZCgpOwotCi0gICAgLyoqIFNldHN0aGUgYmFzZSBVUkkgYWdhaW5zdCB3aGljaCB0aGUgbGl0ZXJhbCBTeXN0ZW1JZCBpcyB0byBiZQotICAgICAgICByZXNvbHZlZC4qLwotICAgIHB1YmxpYyB2b2lkIHNldEJhc2VTeXN0ZW1JZChTdHJpbmcgc3lzdGVtSWQpOwotCi0gICAgLyoqIDxwPiBSZXR1cm5zIHRoZSBiYXNlIFVSSSBhZ2FpbnN0IHdoaWNoIHRoZSBsaXRlcmFsIFN5c3RlbUlkIGlzIHRvIGJlCi0gICAgICAgIHJlc29sdmVkLiA8L3A+ICovCi0gICAgcHVibGljIFN0cmluZyBnZXRCYXNlU3lzdGVtSWQoKTsKLQotICAgIC8qKiBTZXRzIHRoZSBuYW1lc3BhY2Ugb2YgdGhlIHJlc291cmNlLiAqLwotICAgIHB1YmxpYyB2b2lkIHNldE5hbWVzcGFjZShTdHJpbmcgbmFtZXNwYWNlKTsKLQotICAgIC8qKiBSZXR1cm5zIHRoZSBuYW1lc3BhY2Ugb2YgdGhlIHJlc291cmNlLiAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZXNwYWNlKCk7Ci0KLX0gLy8gWE1MUmVzb3VyY2VJZGVudGlmaWVyCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94bmkvWE1MU3RyaW5nLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94bmkvWE1MU3RyaW5nLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGRkNDI0MGQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveG5pL1hNTFN0cmluZy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTkxICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDAtMjAwMiwyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaTsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGlzIHVzZWQgYXMgYSBzdHJ1Y3R1cmUgdG8gcGFzcyB0ZXh0IGNvbnRhaW5lZCBpbiB0aGUgdW5kZXJseWluZwotICogY2hhcmFjdGVyIGJ1ZmZlciBvZiB0aGUgc2Nhbm5lci4gVGhlIG9mZnNldCBhbmQgbGVuZ3RoIGZpZWxkcyBhbGxvdyB0aGUKLSAqIGJ1ZmZlciB0byBiZSByZS11c2VkIHdpdGhvdXQgY3JlYXRpbmcgbmV3IGNoYXJhY3RlciBhcnJheXMuCi0gKiA8cD4KLSAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gTWV0aG9kcyB0aGF0IGFyZSBwYXNzZWQgYW4gWE1MU3RyaW5nIHN0cnVjdHVyZQotICogc2hvdWxkIGNvbnNpZGVyIHRoZSBjb250ZW50cyByZWFkLW9ubHkgYW5kIG5vdCBtYWtlIGFueSBtb2RpZmljYXRpb25zCi0gKiB0byB0aGUgY29udGVudHMgb2YgdGhlIGJ1ZmZlci4gVGhlIG1ldGhvZCByZWNlaXZpbmcgdGhpcyBzdHJ1Y3R1cmUKLSAqIHNob3VsZCBhbHNvIG5vdCBtb2RpZnkgdGhlIG9mZnNldCBhbmQgbGVuZ3RoIGlmIHRoaXMgc3RydWN0dXJlIChvcgotICogdGhlIHZhbHVlcyBvZiB0aGlzIHN0cnVjdHVyZSkgYXJlIHBhc3NlZCB0byBhbm90aGVyIG1ldGhvZC4KLSAqIDxwPgotICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBNZXRob2RzIHRoYXQgYXJlIHBhc3NlZCBhbiBYTUxTdHJpbmcgc3RydWN0dXJlCi0gKiBhcmUgcmVxdWlyZWQgdG8gY29weSB0aGUgaW5mb3JtYXRpb24gb3V0IG9mIHRoZSBidWZmZXIgaWYgaXQgaXMgdG8gYmUKLSAqIHNhdmVkIGZvciB1c2UgYmV5b25kIHRoZSBzY29wZSBvZiB0aGUgbWV0aG9kLiBUaGUgY29udGVudHMgb2YgdGhlCi0gKiBzdHJ1Y3R1cmUgYXJlIHZvbGF0aWxlIGFuZCB0aGUgY29udGVudHMgb2YgdGhlIGNoYXJhY3RlciBidWZmZXIgY2Fubm90Ci0gKiBiZSBhc3N1cmVkIG9uY2UgdGhlIG1ldGhvZCB0aGF0IGlzIHBhc3NlZCB0aGlzIHN0cnVjdHVyZSByZXR1cm5zLgotICogVGhlcmVmb3JlLCBtZXRob2RzIHBhc3NlZCB0aGlzIHN0cnVjdHVyZSBzaG91bGQgbm90IHNhdmUgYW55IHJlZmVyZW5jZQotICogdG8gdGhlIHN0cnVjdHVyZSBvciB0aGUgY2hhcmFjdGVyIGFycmF5IGNvbnRhaW5lZCBpbiB0aGUgc3RydWN0dXJlLgotICoKLSAqIEBhdXRob3IgRXJpYyBZZSwgSUJNCi0gKiBAYXV0aG9yIEFuZHkgQ2xhcmssIElCTQotICoKLSAqLwotcHVibGljIGNsYXNzIFhNTFN0cmluZyB7Ci0KLSAgICAvLwotICAgIC8vIERhdGEKLSAgICAvLwotCi0gICAgLyoqIFRoZSBjaGFyYWN0ZXIgYXJyYXkuICovCi0gICAgcHVibGljIGNoYXJbXSBjaDsKLQotICAgIC8qKiBUaGUgb2Zmc2V0IGludG8gdGhlIGNoYXJhY3RlciBhcnJheS4gKi8KLSAgICBwdWJsaWMgaW50IG9mZnNldDsKLQotICAgIC8qKiBUaGUgbGVuZ3RoIG9mIGNoYXJhY3RlcnMgZnJvbSB0aGUgb2Zmc2V0LiAqLwotICAgIHB1YmxpYyBpbnQgbGVuZ3RoOwotCi0gICAgLy8KLSAgICAvLyBDb25zdHJ1Y3RvcnMKLSAgICAvLwotCi0gICAgLyoqIERlZmF1bHQgY29uc3RydWN0b3IuICovCi0gICAgcHVibGljIFhNTFN0cmluZygpIHsKLSAgICB9IC8vIDxpbml0PigpCi0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RzIGFuIFhNTFN0cmluZyBzdHJ1Y3R1cmUgcHJlc2V0IHdpdGggdGhlIHNwZWNpZmllZAotICAgICAqIHZhbHVlcy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjaCAgICAgVGhlIGNoYXJhY3RlciBhcnJheS4KLSAgICAgKiBAcGFyYW0gb2Zmc2V0IFRoZSBvZmZzZXQgaW50byB0aGUgY2hhcmFjdGVyIGFycmF5LgotICAgICAqIEBwYXJhbSBsZW5ndGggVGhlIGxlbmd0aCBvZiBjaGFyYWN0ZXJzIGZyb20gdGhlIG9mZnNldC4KLSAgICAgKi8KLSAgICBwdWJsaWMgWE1MU3RyaW5nKGNoYXJbXSBjaCwgaW50IG9mZnNldCwgaW50IGxlbmd0aCkgewotICAgICAgICBzZXRWYWx1ZXMoY2gsIG9mZnNldCwgbGVuZ3RoKTsKLSAgICB9IC8vIDxpbml0PihjaGFyW10saW50LGludCkKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHMgYW4gWE1MU3RyaW5nIHN0cnVjdHVyZSB3aXRoIGNvcGllcyBvZiB0aGUgdmFsdWVzIGluCi0gICAgICogdGhlIGdpdmVuIHN0cnVjdHVyZS4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoaXMgZG9lcyBub3QgY29weSB0aGUgY2hhcmFjdGVyIGFycmF5OwotICAgICAqIG9ubHkgdGhlIHJlZmVyZW5jZSB0byB0aGUgYXJyYXkgaXMgY29waWVkLgotICAgICAqCi0gICAgICogQHBhcmFtIHN0cmluZyBUaGUgWE1MU3RyaW5nIHRvIGNvcHkuCi0gICAgICovCi0gICAgcHVibGljIFhNTFN0cmluZyhYTUxTdHJpbmcgc3RyaW5nKSB7Ci0gICAgICAgIHNldFZhbHVlcyhzdHJpbmcpOwotICAgIH0gLy8gPGluaXQ+KFhNTFN0cmluZykKLQotICAgIC8vCi0gICAgLy8gUHVibGljIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogSW5pdGlhbGl6ZXMgdGhlIGNvbnRlbnRzIG9mIHRoZSBYTUxTdHJpbmcgc3RydWN0dXJlIHdpdGggdGhlCi0gICAgICogc3BlY2lmaWVkIHZhbHVlcy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjaCAgICAgVGhlIGNoYXJhY3RlciBhcnJheS4KLSAgICAgKiBAcGFyYW0gb2Zmc2V0IFRoZSBvZmZzZXQgaW50byB0aGUgY2hhcmFjdGVyIGFycmF5LgotICAgICAqIEBwYXJhbSBsZW5ndGggVGhlIGxlbmd0aCBvZiBjaGFyYWN0ZXJzIGZyb20gdGhlIG9mZnNldC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRWYWx1ZXMoY2hhcltdIGNoLCBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoKSB7Ci0gICAgICAgIHRoaXMuY2ggPSBjaDsKLSAgICAgICAgdGhpcy5vZmZzZXQgPSBvZmZzZXQ7Ci0gICAgICAgIHRoaXMubGVuZ3RoID0gbGVuZ3RoOwotICAgIH0gLy8gc2V0VmFsdWVzKGNoYXJbXSxpbnQsaW50KQotCi0gICAgLyoqCi0gICAgICogSW5pdGlhbGl6ZXMgdGhlIGNvbnRlbnRzIG9mIHRoZSBYTUxTdHJpbmcgc3RydWN0dXJlIHdpdGggY29waWVzCi0gICAgICogb2YgdGhlIGdpdmVuIHN0cmluZyBzdHJ1Y3R1cmUuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGlzIGRvZXMgbm90IGNvcHkgdGhlIGNoYXJhY3RlciBhcnJheTsKLSAgICAgKiBvbmx5IHRoZSByZWZlcmVuY2UgdG8gdGhlIGFycmF5IGlzIGNvcGllZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0VmFsdWVzKFhNTFN0cmluZyBzKSB7Ci0gICAgICAgIHNldFZhbHVlcyhzLmNoLCBzLm9mZnNldCwgcy5sZW5ndGgpOwotICAgIH0gLy8gc2V0VmFsdWVzKFhNTFN0cmluZykKLQotICAgIC8qKiBSZXNldHMgYWxsIG9mIHRoZSB2YWx1ZXMgdG8gdGhlaXIgZGVmYXVsdHMuICovCi0gICAgcHVibGljIHZvaWQgY2xlYXIoKSB7Ci0gICAgICAgIHRoaXMuY2ggPSBudWxsOwotICAgICAgICB0aGlzLm9mZnNldCA9IDA7Ci0gICAgICAgIHRoaXMubGVuZ3RoID0gLTE7Ci0gICAgfSAvLyBjbGVhcigpCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIGNvbnRlbnRzIG9mIHRoaXMgWE1MU3RyaW5nIHN0cnVjdHVyZSBhbmQKLSAgICAgKiB0aGUgc3BlY2lmaWVkIGFycmF5IGFyZSBlcXVhbC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjaCAgICAgVGhlIGNoYXJhY3RlciBhcnJheS4KLSAgICAgKiBAcGFyYW0gb2Zmc2V0IFRoZSBvZmZzZXQgaW50byB0aGUgY2hhcmFjdGVyIGFycmF5LgotICAgICAqIEBwYXJhbSBsZW5ndGggVGhlIGxlbmd0aCBvZiBjaGFyYWN0ZXJzIGZyb20gdGhlIG9mZnNldC4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoY2hhcltdIGNoLCBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoKSB7Ci0gICAgICAgIGlmIChjaCA9PSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKHRoaXMubGVuZ3RoICE9IGxlbmd0aCkgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0KLSAgICAgICAgZm9yIChpbnQgaT0wOyBpPGxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICBpZiAodGhpcy5jaFt0aGlzLm9mZnNldCtpXSAhPSBjaFtvZmZzZXQraV0gKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiB0cnVlOwotICAgIH0gLy8gZXF1YWxzKGNoYXJbXSxpbnQsaW50KTpib29sZWFuCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIGNvbnRlbnRzIG9mIHRoaXMgWE1MU3RyaW5nIHN0cnVjdHVyZSBhbmQKLSAgICAgKiB0aGUgc3BlY2lmaWVkIHN0cmluZyBhcmUgZXF1YWwuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcyBUaGUgc3RyaW5nIHRvIGNvbXBhcmUuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKFN0cmluZyBzKSB7Ci0gICAgICAgIGlmIChzID09IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotICAgICAgICBpZiAoIGxlbmd0aCAhPSBzLmxlbmd0aCgpICkgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gaXMgdGhpcyBmYXN0ZXIgdGhhbiBjYWxsIHMudG9DaGFyQXJyYXkgZmlyc3QgYW5kIGNvbXBhcmUgdGhlCi0gICAgICAgIC8vIHR3byBhcnJheXMgZGlyZWN0bHksIHdoaWNoIHdpbGwgcG9zc2libHkgaW52b2x2ZSBjcmVhdGluZyBhCi0gICAgICAgIC8vIG5ldyBjaGFyIGFycmF5IG9iamVjdC4KLSAgICAgICAgZm9yIChpbnQgaT0wOyBpPGxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICBpZiAoY2hbb2Zmc2V0K2ldICE9IHMuY2hhckF0KGkpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfSAvLyBlcXVhbHMoU3RyaW5nKTpib29sZWFuCi0KLSAgICAvLwotICAgIC8vIE9iamVjdCBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKiBSZXR1cm5zIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgb2JqZWN0LiAqLwotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0gICAgICAgIHJldHVybiBsZW5ndGggPiAwID8gbmV3IFN0cmluZyhjaCwgb2Zmc2V0LCBsZW5ndGgpIDogIiI7Ci0gICAgfSAvLyB0b1N0cmluZygpOlN0cmluZwotCi19IC8vIGNsYXNzIFhNTFN0cmluZwpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveG5pL1hOSUV4Y2VwdGlvbi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveG5pL1hOSUV4Y2VwdGlvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0MjQ3NTUxLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3huaS9YTklFeGNlcHRpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDk2ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEsIDIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmk7Ci0KLS8qKgotICogVGhpcyBleGNlcHRpb24gaXMgdGhlIGJhc2UgZXhjZXB0aW9uIG9mIGFsbCBYTkkgZXhjZXB0aW9ucy4gSXQKLSAqIGNhbiBiZSBjb25zdHJ1Y3RlZCB3aXRoIGFuIGVycm9yIG1lc3NhZ2Ugb3IgdXNlZCB0byB3cmFwIGFub3RoZXIKLSAqIGV4Y2VwdGlvbiBvYmplY3QuCi0gKiA8cD4KLSAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gQnkgZXh0ZW5kaW5nIHRoZSBKYXZhCi0gKiA8Y29kZT5SdW50aW1lRXhjZXB0aW9uPC9jb2RlPiwgWE5JIGhhbmRsZXJzIGFuZCBjb21wb25lbnRzIGFyZQotICogbm90IHJlcXVpcmVkIHRvIGNhdGNoIFhOSSBleGNlcHRpb25zIGJ1dCBtYXkgZXhwbGljaXRseSBjYXRjaAotICogdGhlbSwgaWYgc28gZGVzaXJlZC4KLSAqCi0gKiBAYXV0aG9yIEFuZHkgQ2xhcmssIElCTQotICoKLSAqIEB2ZXJzaW9uICRJZDogWE5JRXhjZXB0aW9uLmphdmEsdiAxLjYgMjAxMC0xMS0wMSAwNDo0MDoxOSBqb2VodyBFeHAgJAotICovCi1wdWJsaWMgY2xhc3MgWE5JRXhjZXB0aW9uCi0gICAgZXh0ZW5kcyBSdW50aW1lRXhjZXB0aW9uIHsKLQotICAgIC8qKiBTZXJpYWxpemF0aW9uIHZlcnNpb24uICovCi0gICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDkwMTk4MTk3NzI2ODYwNjM3NzVMOwotCi0gICAgLy8KLSAgICAvLyBEYXRhCi0gICAgLy8KLQotICAgIC8qKiBUaGUgd3JhcHBlZCBleGNlcHRpb24uICovCi0gICAgcHJpdmF0ZSBFeGNlcHRpb24gZkV4Y2VwdGlvbjsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHMgYW4gWE5JIGV4Y2VwdGlvbiB3aXRoIGEgbWVzc2FnZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBtZXNzYWdlIFRoZSBleGNlcHRpb24gbWVzc2FnZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgWE5JRXhjZXB0aW9uKFN0cmluZyBtZXNzYWdlKSB7Ci0gICAgICAgIHN1cGVyKG1lc3NhZ2UpOwotICAgIH0gLy8gPGluaXQ+KFN0cmluZykKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHMgYW4gWE5JIGV4Y2VwdGlvbiB3aXRoIGEgd3JhcHBlZCBleGNlcHRpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZXhjZXB0aW9uIFRoZSB3cmFwcGVkIGV4Y2VwdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgWE5JRXhjZXB0aW9uKEV4Y2VwdGlvbiBleGNlcHRpb24pIHsKLSAgICAgICAgc3VwZXIoZXhjZXB0aW9uLmdldE1lc3NhZ2UoKSk7Ci0gICAgICAgIGZFeGNlcHRpb24gPSBleGNlcHRpb247Ci0gICAgfSAvLyA8aW5pdD4oRXhjZXB0aW9uKQotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0cyBhbiBYTkkgZXhjZXB0aW9uIHdpdGggYSBtZXNzYWdlIGFuZCB3cmFwcGVkIGV4Y2VwdGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBtZXNzYWdlIFRoZSBleGNlcHRpb24gbWVzc2FnZS4KLSAgICAgKiBAcGFyYW0gZXhjZXB0aW9uIFRoZSB3cmFwcGVkIGV4Y2VwdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgWE5JRXhjZXB0aW9uKFN0cmluZyBtZXNzYWdlLCBFeGNlcHRpb24gZXhjZXB0aW9uKSB7Ci0gICAgICAgIHN1cGVyKG1lc3NhZ2UpOwotICAgICAgICBmRXhjZXB0aW9uID0gZXhjZXB0aW9uOwotICAgIH0gLy8gPGluaXQ+KEV4Y2VwdGlvbixTdHJpbmcpCi0KLSAgICAvLwotICAgIC8vIFB1YmxpYyBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKiBSZXR1cm5zIHRoZSB3cmFwcGVkIGV4Y2VwdGlvbi4gKi8KLSAgICBwdWJsaWMgRXhjZXB0aW9uIGdldEV4Y2VwdGlvbigpIHsKLSAgICAgICAgcmV0dXJuIGZFeGNlcHRpb247Ci0gICAgfSAvLyBnZXRFeGNlcHRpb24oKTpFeGNlcHRpb24KLQotICAgIHB1YmxpYyBUaHJvd2FibGUgZ2V0Q2F1c2UoKSB7Ci0gICAgICAgcmV0dXJuIGZFeGNlcHRpb247Ci0gICAgfQotfSAvLyBjbGFzcyBRTmFtZQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveG5pL2dyYW1tYXJzL0dyYW1tYXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3huaS9ncmFtbWFycy9HcmFtbWFyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDk1YWRiY2QuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveG5pL2dyYW1tYXJzL0dyYW1tYXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDU1ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDAtMjAwMiwyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5ncmFtbWFyczsKLQotLyoqCi0gKiBBIGdlbmVyaWMgZ3JhbW1hciBmb3IgdXNlIGluIHZhbGlkYXRpbmcgWE1MIGRvY3VtZW50cy4gVGhlIEdyYW1tYXIKLSAqIG9iamVjdCBzdG9yZXMgdGhlIHZhbGlkYXRpb24gaW5mb3JtYXRpb24gaW4gYSBjb21waWxlZCBmb3JtLiBTcGVjaWZpYwotICogc3ViY2xhc3NlcyBleHRlbmQgdGhpcyBjbGFzcyBhbmQgInBvcHVsYXRlIiB0aGUgZ3JhbW1hciBieSBjb21waWxpbmcKLSAqIHRoZSBzcGVjaWZpYyBzeW50YXggKERURCwgU2NoZW1hLCBldGMpIGludG8gdGhlIGRhdGEgc3RydWN0dXJlcyB1c2VkCi0gKiBieSB0aGlzIG9iamVjdC4KLSAqIDxwPgotICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGUgR3JhbW1hciBvYmplY3QgaXMgbm90IHVzZWZ1bCBhcyBhIGdlbmVyaWMKLSAqIGdyYW1tYXIgYWNjZXNzIG9yIHF1ZXJ5IG9iamVjdC4gSW4gb3RoZXIgd29yZHMsIHlvdSBjYW5ub3Qgcm91bmQtdHJpcAotICogc3BlY2lmaWMgZ3JhbW1hciBzeW50YXhlcyB3aXRoIHRoZSBjb21waWxlZCBncmFtbWFyIGluZm9ybWF0aW9uIGluCi0gKiB0aGUgR3JhbW1hciBvYmplY3QuIFlvdSA8ZW0+Y2FuPC9lbT4gY3JlYXRlIGVxdWl2YWxlbnQgdmFsaWRhdGlvbgotICogcnVsZXMgaW4geW91ciBjaG9pY2Ugb2YgZ3JhbW1hciBzeW50YXggYnV0IHRoZXJlIGlzIG5vIGd1YXJhbnRlZSB0aGF0Ci0gKiB0aGUgaW5wdXQgYW5kIG91dHB1dCB3aWxsIGJlIHRoZSBzYW1lLgotICoKLSAqIDxwPiBSaWdodCBub3csIHRoaXMgY2xhc3MgaXMgbGFyZ2VseSBhIHNoZWxsOyBldmVudHVhbGx5LAotICogaXQgd2lsbCBiZSBlbnJpY2hlZCBieSBoYXZpbmcgbW9yZSBleHByZXNzaXZlIG1ldGhvZHMgYWRkZWQuIDwvcD4KLSAqIHdpbGwgYmUgbW92ZWQgZnJvbSBkdGQuR3JhbW1hciBoZXJlLgotICoKLSAqIEBhdXRob3IgSmVmZnJleSBSb2RyaWd1ZXosIElCTQotICogQGF1dGhvciBFcmljIFllLCBJQk0KLSAqIEBhdXRob3IgQW5keSBDbGFyaywgSUJNCi0gKiBAYXV0aG9yIE5laWwgR3JhaGFtLCBJQk0KLSAqCi0gKi8KLQotcHVibGljIGludGVyZmFjZSBHcmFtbWFyIHsKLQotICAgIC8qKgotICAgICAqIGdldCB0aGUgPGNvZGU+WE1MR3JhbW1hckRlc2NyaXB0aW9uPC9jb2RlPiBhc3NvY2lhdGVkIHdpdGggdGhpcwotICAgICAqIG9iamVjdAotICAgICAqLwotICAgIHB1YmxpYyBYTUxHcmFtbWFyRGVzY3JpcHRpb24gZ2V0R3JhbW1hckRlc2NyaXB0aW9uICgpOwotfSAvLyBpbnRlcmZhY2UgR3JhbW1hcgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveG5pL2dyYW1tYXJzL1hNTERURERlc2NyaXB0aW9uLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94bmkvZ3JhbW1hcnMvWE1MRFRERGVzY3JpcHRpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMmI3MjY2OC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94bmkvZ3JhbW1hcnMvWE1MRFRERGVzY3JpcHRpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDM3ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuZ3JhbW1hcnM7Ci0KLS8qKgotICogQWxsIGluZm9ybWF0aW9uIHNwZWNpZmljIHRvIERURCBncmFtbWFycy4KLSAqCi0gKiBAYXV0aG9yIFNhbmR5IEdhbywgSUJNCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgWE1MRFRERGVzY3JpcHRpb24gZXh0ZW5kcyBYTUxHcmFtbWFyRGVzY3JpcHRpb24gewotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSByb290IG5hbWUgb2YgdGhpcyBEVEQuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuICB0aGUgcm9vdCBuYW1lLiBudWxsIGlmIHRoZSBuYW1lIGlzIHVua25vd24uCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRSb290TmFtZSgpOwotCi19IC8vIGludGVyZmFjZSBYTUxEVEREZXNjcmlwdGlvbgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveG5pL2dyYW1tYXJzL1hNTEdyYW1tYXJEZXNjcmlwdGlvbi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveG5pL2dyYW1tYXJzL1hNTEdyYW1tYXJEZXNjcmlwdGlvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlNWM4M2YyLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3huaS9ncmFtbWFycy9YTUxHcmFtbWFyRGVzY3JpcHRpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDU5ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDAtMjAwMiwyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5ncmFtbWFyczsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTFJlc291cmNlSWRlbnRpZmllcjsKLQotLyoqCi0gKiA8cD4gVGhpcyBpbnRlcmZhY2UgZGVzY3JpYmVzIGJhc2ljIGF0dHJpYnV0ZXMgb2YgWE1MIGdyYW1tYXJzLS10aGVpcgotICogcGh5c2ljYWwgbG9jYXRpb24gYW5kIHRoZWlyIHR5cGUuIDwvcD4KLSAqCi0gKiBAYXV0aG9yIE5laWwgR3JhaGFtLCBJQk0KLSAqLwotcHVibGljIGludGVyZmFjZSBYTUxHcmFtbWFyRGVzY3JpcHRpb24gZXh0ZW5kcyBYTUxSZXNvdXJjZUlkZW50aWZpZXIgewotCi0gICAgLy8gaW5pdGlhbCBzZXQgb2YgZ3JhbW1hciBjb25zdGFudHMgdGhhdCBzb21lIGNvbmZpZ3VyYXRpb25zIHdpbGwgcmVjb2duaXplO3VzZXIKLSAgICAvLyBjb21wb25lbnRzIHdoaWNoIGNyZWF0ZSBhbmQvb3IgcmVjb2duaXplIG90aGVyIHR5cGVzIG9mIGdyYW1tYXJzIG1heQotICAgIC8vIGNlcnRhaW5seSB1c2UgdGhlaXIgb3duIGNvbnN0YW50cyBpbiBwbGFjZSBvZiB0aGVzZSAoc28gbG9uZyBhcwotICAgIC8vIHRoZWlyIEdyYW1tYXIgb2JqZWN0cyBpbXBsZW1lbnQgdGhpcyBpbnRlcmZhY2UpLgotCi0gICAgLyoqCi0gICAgICogVGhlIGdyYW1tYXIgdHlwZSBjb25zdGFudCBmb3IgWE1MIFNjaGVtYSBncmFtbWFycy4gV2hlbiBnZXRHcmFtbWFyVHlwZSgpCi0gICAgICogbWV0aG9kIHJldHVybnMgdGhpcyBjb25zdGFudCwgdGhlIG9iamVjdCBzaG91bGQgYmUgYW4gaW5zdGFuY2Ugb2YKLSAgICAgKiB0aGUgWE1MU2NoZW1hRGVzY3JpcHRpb24gaW50ZXJmYWNlLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFhNTF9TQ0hFTUEgPSAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiOwotCi0gICAgLyoqCi0gICAgICogVGhlIGdyYW1tYXIgdHlwZSBjb25zdGFudCBmb3IgRFREIGdyYW1tYXJzLiBXaGVuIGdldEdyYW1tYXJUeXBlKCkKLSAgICAgKiBtZXRob2QgcmV0dXJucyB0aGlzIGNvbnN0YW50LCB0aGUgb2JqZWN0IHNob3VsZCBiZSBhbiBpbnN0YW5jZSBvZgotICAgICAqIHRoZSBYTUxEVEREZXNjcmlwdGlvbiBpbnRlcmZhY2UuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MX0RURCA9ICJodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMteG1sIjsKLQotICAgIC8qKgotICAgICAqIFJldHVybiB0aGUgdHlwZSBvZiB0aGlzIGdyYW1tYXIuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuICB0aGUgdHlwZSBvZiB0aGlzIGdyYW1tYXIKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEdyYW1tYXJUeXBlKCk7Ci0KLX0gLy8gaW50ZXJmYWNlIFhNTEdyYW1tYXJEZXNjcmlwdGlvbgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveG5pL2dyYW1tYXJzL1hNTEdyYW1tYXJMb2FkZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3huaS9ncmFtbWFycy9YTUxHcmFtbWFyTG9hZGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGI4ZDMyMDQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveG5pL2dyYW1tYXJzL1hNTEdyYW1tYXJMb2FkZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE0NyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAwLTIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuZ3JhbW1hcnM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MRXJyb3JIYW5kbGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxFbnRpdHlSZXNvbHZlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MSW5wdXRTb3VyY2U7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE5JRXhjZXB0aW9uOwotCi1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwotCi0vKioKLSAqIFRoZSBpbnRlbnRpb24gb2YgdGhpcyBpbnRlcmZhY2UgaXMgdG8gcHJvdmlkZSBhIGdlbmVyaWMgbWVhbnMKLSAqIGJ5IHdoaWNoIEdyYW1tYXIgb2JqZWN0cyBtYXkgYmUgY3JlYXRlZCB3aXRob3V0IHBhcnNpbmcgaW5zdGFuY2UKLSAqIGRvY3VtZW50cy4gIEltcGxlbWVudGF0aW9ucyBvZiB0aGlzIGludGVyZmFjZSB3aWxsIGtub3cgaG93IHRvIGxvYWQKLSAqIHNwZWNpZmljIHR5cGVzIG9mIGdyYW1tYXJzIChlLmcuLCBEVEQncyBvciBzY2hlbWFzKTsgYSB3cmFwcGVyCi0gKiB3aWxsIGJlIHByb3ZpZGVkIGZvciB1c2VyIGFwcGxpY2F0aW9ucyB0byBpbnRlcmFjdCB3aXRoIHRoZXNlIGltcGxlbWVudGF0aW9ucy4KLSAqCi0gKiBAYXV0aG9yIE5laWwgR3JhaGFtLCBJQk0KLSAqLwotCi1wdWJsaWMgaW50ZXJmYWNlIFhNTEdyYW1tYXJMb2FkZXIgewotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhIGxpc3Qgb2YgZmVhdHVyZSBpZGVudGlmaWVycyB0aGF0IGFyZSByZWNvZ25pemVkIGJ5Ci0gICAgICogdGhpcyBYTUxHcmFtbWFyTG9hZGVyLiAgVGhpcyBtZXRob2QgbWF5IHJldHVybiBudWxsIGlmIG5vIGZlYXR1cmVzCi0gICAgICogYXJlIHJlY29nbml6ZWQuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZ1tdIGdldFJlY29nbml6ZWRGZWF0dXJlcygpOwotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgc3RhdGUgb2YgYSBmZWF0dXJlLgotICAgICAqCi0gICAgICogQHBhcmFtIGZlYXR1cmVJZCBUaGUgZmVhdHVyZSBpZGVudGlmaWVyLgotICAgICAqCi0gICAgICogQHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIFRocm93biBvbiBjb25maWd1cmF0aW9uIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGdldEZlYXR1cmUoU3RyaW5nIGZlYXR1cmVJZCkKLSAgICAgICAgICAgIHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogU2V0cyB0aGUgc3RhdGUgb2YgYSBmZWF0dXJlLgotICAgICAqCi0gICAgICogQHBhcmFtIGZlYXR1cmVJZCBUaGUgZmVhdHVyZSBpZGVudGlmaWVyLgotICAgICAqIEBwYXJhbSBzdGF0ZSAgICAgVGhlIHN0YXRlIG9mIHRoZSBmZWF0dXJlLgotICAgICAqCi0gICAgICogQHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIFRocm93biB3aGVuIGEgZmVhdHVyZSBpcyBub3QKLSAgICAgKiAgICAgICAgICAgICAgICAgIHJlY29nbml6ZWQgb3IgY2Fubm90IGJlIHNldC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRGZWF0dXJlKFN0cmluZyBmZWF0dXJlSWQsCi0gICAgICAgICAgICAgICAgYm9vbGVhbiBzdGF0ZSkgdGhyb3dzIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGEgbGlzdCBvZiBwcm9wZXJ0eSBpZGVudGlmaWVycyB0aGF0IGFyZSByZWNvZ25pemVkIGJ5Ci0gICAgICogdGhpcyBYTUxHcmFtbWFyTG9hZGVyLiAgVGhpcyBtZXRob2QgbWF5IHJldHVybiBudWxsIGlmIG5vIHByb3BlcnRpZXMKLSAgICAgKiBhcmUgcmVjb2duaXplZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nW10gZ2V0UmVjb2duaXplZFByb3BlcnRpZXMoKTsKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIHN0YXRlIG9mIGEgcHJvcGVydHkuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcHJvcGVydHlJZCBUaGUgcHJvcGVydHkgaWRlbnRpZmllci4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBUaHJvd24gb24gY29uZmlndXJhdGlvbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0IGdldFByb3BlcnR5KFN0cmluZyBwcm9wZXJ0eUlkKQotICAgICAgICAgICAgdGhyb3dzIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSBzdGF0ZSBvZiBhIHByb3BlcnR5LgotICAgICAqCi0gICAgICogQHBhcmFtIHByb3BlcnR5SWQgVGhlIHByb3BlcnR5IGlkZW50aWZpZXIuCi0gICAgICogQHBhcmFtIHN0YXRlICAgICBUaGUgc3RhdGUgb2YgdGhlIHByb3BlcnR5LgotICAgICAqCi0gICAgICogQHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIFRocm93biB3aGVuIGEgcHJvcGVydHkgaXMgbm90Ci0gICAgICogICAgICAgICAgICAgICAgICByZWNvZ25pemVkIG9yIGNhbm5vdCBiZSBzZXQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0UHJvcGVydHkoU3RyaW5nIHByb3BlcnR5SWQsCi0gICAgICAgICAgICAgICAgT2JqZWN0IHN0YXRlKSB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIFNldCB0aGUgbG9jYWxlIHRvIHVzZSBmb3IgbWVzc2FnZXMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbG9jYWxlIFRoZSBsb2NhbGUgb2JqZWN0IHRvIHVzZSBmb3IgbG9jYWxpemF0aW9uIG9mIG1lc3NhZ2VzLgotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBYTklFeGNlcHRpb24gVGhyb3duIGlmIHRoZSBwYXJzZXIgZG9lcyBub3Qgc3VwcG9ydCB0aGUKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBzcGVjaWZpZWQgbG9jYWxlLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldExvY2FsZShMb2NhbGUgbG9jYWxlKTsKLQotICAgIC8qKiBSZXR1cm4gdGhlIExvY2FsZSB0aGUgWE1MR3JhbW1hckxvYWRlciBpcyB1c2luZy4gKi8KLSAgICBwdWJsaWMgTG9jYWxlIGdldExvY2FsZSgpOwotCi0gICAgLyoqCi0gICAgICogU2V0cyB0aGUgZXJyb3IgaGFuZGxlci4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlcnJvckhhbmRsZXIgVGhlIGVycm9yIGhhbmRsZXIuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RXJyb3JIYW5kbGVyKFhNTEVycm9ySGFuZGxlciBlcnJvckhhbmRsZXIpOwotCi0gICAgLyoqIFJldHVybnMgdGhlIHJlZ2lzdGVyZWQgZXJyb3IgaGFuZGxlci4gICovCi0gICAgcHVibGljIFhNTEVycm9ySGFuZGxlciBnZXRFcnJvckhhbmRsZXIoKTsKLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIGVudGl0eSByZXNvbHZlci4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlbnRpdHlSZXNvbHZlciBUaGUgbmV3IGVudGl0eSByZXNvbHZlci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRFbnRpdHlSZXNvbHZlcihYTUxFbnRpdHlSZXNvbHZlciBlbnRpdHlSZXNvbHZlcik7Ci0KLSAgICAvKiogUmV0dXJucyB0aGUgcmVnaXN0ZXJlZCBlbnRpdHkgcmVzb2x2ZXIuICAqLwotICAgIHB1YmxpYyBYTUxFbnRpdHlSZXNvbHZlciBnZXRFbnRpdHlSZXNvbHZlcigpOwotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhIEdyYW1tYXIgb2JqZWN0IGJ5IHBhcnNpbmcgdGhlIGNvbnRlbnRzIG9mIHRoZQotICAgICAqIGVudGl0eSBwb2ludGVkIHRvIGJ5IHNvdXJjZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzb3VyY2UgICAgICAgIHRoZSBsb2NhdGlvbiBvZiB0aGUgZW50aXR5IHdoaWNoIGZvcm1zCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSBzdGFydGluZyBwb2ludCBvZiB0aGUgZ3JhbW1hciB0byBiZSBjb25zdHJ1Y3RlZC4KLSAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uICAgICAgV2hlbiBhIHByb2JsZW0gaXMgZW5jb3VudGVyZWQgcmVhZGluZyB0aGUgZW50aXR5Ci0gICAgICogICAgICAgICAgWE5JRXhjZXB0aW9uICAgIFdoZW4gYSBjb25kaXRpb24gYXJpc2VzIChzdWNoIGFzIGEgRmF0YWxFcnJvcikgdGhhdCByZXF1aXJlcyBwYXJzaW5nCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZiB0aGUgZW50aXR5IGJlIHRlcm1pbmF0ZWQuCi0gICAgICovCi0gICAgcHVibGljIEdyYW1tYXIgbG9hZEdyYW1tYXIoWE1MSW5wdXRTb3VyY2Ugc291cmNlKQotICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIFhOSUV4Y2VwdGlvbjsKLX0gLy8gWE1MR3JhbW1hckxvYWRlcgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveG5pL2dyYW1tYXJzL1hNTEdyYW1tYXJQb29sLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94bmkvZ3JhbW1hcnMvWE1MR3JhbW1hclBvb2wuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYmQ5NDdiNS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94bmkvZ3JhbW1hcnMvWE1MR3JhbW1hclBvb2wuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEwNSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAwLTIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLmdyYW1tYXJzOwotCi0vKioKLSAqIDxwPiBUaGlzIGludGVyZmFjZSBzcGVjaWZpZXMgaG93IHRoZSBwYXJzZXIgYW5kIHRoZSBhcHBsaWNhdGlvbgotICogaW50ZXJhY3Qgd2l0aCByZXNwZWN0IHRvIEdyYW1tYXIgb2JqZWN0cyB0aGF0IHRoZSBhcHBsaWNhdGlvbgotICogcG9zc2Vzc2VzLS1laXRoZXIgYnkgaGF2aW5nIHByZWNvbXBpbGVkIHRoZW0gb3IgYnkgaGF2aW5nIHN0b3JlZCB0aGVtCi0gKiBmcm9tIGEgcHJldmlvdXMgdmFsaWRhdGlvbiBvZiBhbiBpbnN0YW5jZSBkb2N1bWVudC4gIEl0IG1ha2VzIG5vCi0gKiBhc3N1bXB0aW9ucyBhYm91dCB0aGUga2luZCBvZiBHcmFtbWFyIGludm9sdmVkLCBvciBhYm91dCBob3cgdGhlCi0gKiBhcHBsaWNhdGlvbidzIHN0b3JhZ2UgbWVjaGFuaXNtIHdvcmtzLjwvcD4KLSAqCi0gKiA8cD5UaGUgaW50ZXJhY3Rpb24gd29ya3MgYXMgZm9sbG93czoKLSAqIDx1bD4KLSAqIDxsaT5XaGVuIGEgdmFsaWRhdG9yIGNvbnNpZGVycyBhIGRvY3VtZW50LCBpdCBpcyBleHBlY3RlZCB0byByZXF1ZXN0Ci0gKiBncmFtbWFycyBvZiB0aGUgdHlwZSBpdCBjYW4gaGFuZGxlIGZyb20gdGhpcyBvYmplY3QgdXNpbmcgdGhlCi0gKiA8Y29kZT5yZXRyaWV2ZUluaXRpYWxHcmFtbWFyU2V0PC9jb2RlPiBtZXRob2QuIDwvbGk+Ci0gKiA8bGk+SWYgaXQgcmVxdWlyZXMgYSBncmFtbWFyCi0gKiBub3QgaW4gdGhpcyBzZXQsIGl0IHdpbGwgcmVxdWVzdCBpdCBmcm9tIHRoaXMgT2JqZWN0IHVzaW5nIHRoZQotICogPGNvZGU+cmV0cmlldmVHcmFtbWFyPC9jb2RlPiBtZXRob2QuICA8L2xpPgotICogPGxpPiBBZnRlciBzdWNjZXNzZnVsbHkgdmFsaWRhdGluZyBhbgotICogaW5zdGFuY2UsIHRoZSB2YWxpZGF0b3Igc2hvdWxkIG1ha2UgYW55IG5ldyBncmFtbWFycyBpdCBoYXMgY29tcGlsZWQKLSAqIGF2YWlsYWJsZSB0byB0aGlzIG9iamVjdCB1c2luZyB0aGUgPGNvZGU+Y2FjaGVHcmFtbWFyczwvY29kZT4KLSAqIG1ldGhvZDsgZm9yIGVhc2Ugb2YgaW1wbGVtZW50YXRpb24gaXQgbWF5IG1ha2Ugb3RoZXIgR3JhbW1hcnMgaXQgaG9sZHMgcmVmZXJlbmNlcyB0byBhcyB3ZWxsIChpLmUuLAotICogaXQgbWF5IHJldHVybiBzb21lIGdyYW1tYXJzIHRoYXQgd2VyZSByZXRyaWV2ZWQgZnJvbSB0aGUgR3JhbW1hclBvb2wgaW4gZWFybGllciBvcGVyYXRpb25zKS4gPC9saT4gPC91bD4gPC9wPgotICoKLSAqIEBhdXRob3IgTmVpbCBHcmFoYW0sIElCTQotICovCi0KLXB1YmxpYyBpbnRlcmZhY2UgWE1MR3JhbW1hclBvb2wgewotCi0gICAgLy8gPHA+d2UgYXJlIHRyeWluZyB0byBtYWtlIHRoaXMgWE1MR3JhbW1hclBvb2wgd29yayBmb3IgYWxsIGtpbmRzIG9mCi0gICAgLy8gZ3JhbW1hcnMsIHNvIHdlIGhhdmUgYSBwYXJhbWV0ZXIgImdyYW1tYXJUeXBlIiBmb3IgZWFjaCBvZiB0aGUKLSAgICAvLyBtZXRob2RzLiA8L3A+Ci0KLSAgICAvKioKLSAgICAgKiA8cD4gcmV0cmlldmUgdGhlIGluaXRpYWwga25vd24gc2V0IG9mIGdyYW1tYXJzLiB0aGlzIG1ldGhvZCBpcwotICAgICAqIGNhbGxlZCBieSBhIHZhbGlkYXRvciBiZWZvcmUgdGhlIHZhbGlkYXRpb24gc3RhcnRzLiB0aGUgYXBwbGljYXRpb24KLSAgICAgKiBjYW4gcHJvdmlkZSBhbiBpbml0aWFsIHNldCBvZiBncmFtbWFycyBhdmFpbGFibGUgdG8gdGhlIGN1cnJlbnQKLSAgICAgKiB2YWxpZGF0aW9uIGF0dGVtcHQuIDwvcD4KLSAgICAgKiBAcGFyYW0gZ3JhbW1hclR5cGUgdGhlIHR5cGUgb2YgdGhlIGdyYW1tYXIsIGZyb20gdGhlCi0gICAgICogIDxjb2RlPmNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLmdyYW1tYXJzLkdyYW1tYXI8L2NvZGU+IGludGVyZmFjZS4KLSAgICAgKiBAcmV0dXJuIHRoZSBzZXQgb2YgZ3JhbW1hcnMgdGhlIHZhbGlkYXRvciBtYXkgcHV0IGluIGl0cyAiYnVja2V0IgotICAgICAqLwotICAgIHB1YmxpYyBHcmFtbWFyW10gcmV0cmlldmVJbml0aWFsR3JhbW1hclNldChTdHJpbmcgZ3JhbW1hclR5cGUpOwotCi0gICAgLyoqCi0gICAgICogPHA+cmV0dXJuIHRoZSBmaW5hbCBzZXQgb2YgZ3JhbW1hcnMgdGhhdCB0aGUgdmFsaWRhdG9yIGVuZGVkIHVwCi0gICAgICogd2l0aC4KLSAgICAgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYWZ0ZXIgdGhlCi0gICAgICogdmFsaWRhdGlvbiBmaW5pc2hlcy4gVGhlIGFwcGxpY2F0aW9uIG1heSB0aGVuIGNob29zZSB0byBjYWNoZSBzb21lCi0gICAgICogb2YgdGhlIHJldHVybmVkIGdyYW1tYXJzLiA8L3A+Ci0gICAgICogQHBhcmFtIGdyYW1tYXJUeXBlIHRoZSB0eXBlIG9mIHRoZSBncmFtbWFycyBiZWluZyByZXR1cm5lZDsKLSAgICAgKiBAcGFyYW0gZ3JhbW1hcnMgYW4gYXJyYXkgY29udGFpbmluZyB0aGUgc2V0IG9mIGdyYW1tYXJzIGJlaW5nCi0gICAgICogIHJldHVybmVkOyBvcmRlciBpcyBub3Qgc2lnbmlmaWNhbnQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY2FjaGVHcmFtbWFycyhTdHJpbmcgZ3JhbW1hclR5cGUsIEdyYW1tYXJbXSBncmFtbWFycyk7Ci0KLSAgICAvKioKLSAgICAgKiA8cD4gVGhpcyBtZXRob2QgcmVxdWVzdHMgdGhhdCB0aGUgYXBwbGljYXRpb24gcmV0cmlldmUgYSBncmFtbWFyCi0gICAgICogY29ycmVzcG9uZGluZyB0byB0aGUgZ2l2ZW4gR3JhbW1hcklkZW50aWZpZXIgZnJvbSBpdHMgY2FjaGUuCi0gICAgICogSWYgaXQgY2Fubm90IGRvIHNvIGl0IG11c3QgcmV0dXJuIG51bGw7IHRoZSBwYXJzZXIgd2lsbCB0aGVuCi0gICAgICogY2FsbCB0aGUgRW50aXR5UmVzb2x2ZXIuICA8c3Ryb25nPkFuIGFwcGxpY2F0aW9uIG11c3Qgbm90IGNhbGwgaXRzCi0gICAgICogRW50aXR5UmVzb2x2ZXIgaXRzZWxmIGZyb20gdGhpcyBtZXRob2Q7IHRoaXMgbWF5IHJlc3VsdCBpbiBpbmZpbml0ZQotICAgICAqIHJlY3Vyc2lvbnMuPC9zdHJvbmc+Ci0gICAgICogQHBhcmFtIGRlc2MgVGhlIGRlc2NyaXB0aW9uIG9mIHRoZSBHcmFtbWFyIGJlaW5nIHJlcXVlc3RlZC4KLSAgICAgKiBAcmV0dXJuIHRoZSBHcmFtbWFyIGNvcnJlc3BvbmRpbmcgdG8gdGhpcyBkZXNjcmlwdGlvbiBvciBudWxsIGlmCi0gICAgICogIG5vIHN1Y2ggR3JhbW1hciBpcyBrbm93bi4KLSAgICAgKi8KLSAgICBwdWJsaWMgR3JhbW1hciByZXRyaWV2ZUdyYW1tYXIoWE1MR3JhbW1hckRlc2NyaXB0aW9uIGRlc2MpOwotCi0gICAgLyoqCi0gICAgICogQ2F1c2VzIHRoZSBYTUxHcmFtbWFyUG9vbCBub3QgdG8gc3RvcmUgYW55IGdyYW1tYXJzIHdoZW4KLSAgICAgKiB0aGUgY2FjaGVHcmFtbWFycyhTdHJpbmcsIEdyYW1tYXJbW10pIG1ldGhvZCBpcyBjYWxsZWQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgbG9ja1Bvb2woKTsKLQotICAgIC8qKgotICAgICAqIEFsbG93cyB0aGUgWE1MR3JhbW1hclBvb2wgdG8gc3RvcmUgZ3JhbW1hcnMgd2hlbiBpdHMgY2FjaGVHcmFtbWFycyhTdHJpbmcsIEdyYW1tYXJbXSkKLSAgICAgKiBtZXRob2QgaXMgY2FsbGVkLiAgVGhpcyBpcyB0aGUgZGVmYXVsdCBzdGF0ZSBvZiB0aGUgb2JqZWN0LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHVubG9ja1Bvb2woKTsKLQotICAgIC8qKgotICAgICAqIFJlbW92ZXMgYWxsIGdyYW1tYXJzIGZyb20gdGhlIHBvb2wuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY2xlYXIoKTsKLX0gLy8gWE1MR3JhbW1hclBvb2wKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3huaS9ncmFtbWFycy9YTUxTY2hlbWFEZXNjcmlwdGlvbi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveG5pL2dyYW1tYXJzL1hNTFNjaGVtYURlc2NyaXB0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGJjMzhhMmYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveG5pL2dyYW1tYXJzL1hNTFNjaGVtYURlc2NyaXB0aW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMzggKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMiwyMDA0LDIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLmdyYW1tYXJzOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuUU5hbWU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MQXR0cmlidXRlczsKLQotLyoqCi0gKiBBbGwgaW5mb3JtYXRpb24gc3BlY2lmaWMgdG8gWE1MIFNjaGVtYSBncmFtbWFycy4KLSAqCi0gKiBAYXV0aG9yIFNhbmR5IEdhbywgSUJNCi0gKgotICovCi1wdWJsaWMgaW50ZXJmYWNlIFhNTFNjaGVtYURlc2NyaXB0aW9uIGV4dGVuZHMgWE1MR3JhbW1hckRlc2NyaXB0aW9uIHsKLQotICAgIC8vIHVzZWQgdG8gaW5kaWNhdGUgd2hhdCB0cmlnZ2VyZWQgdGhlIGNhbGwKLSAgICAvKioKLSAgICAgKiBJbmRpY2F0ZSB0aGF0IHRoZSBjdXJyZW50IHNjaGVtYSBkb2N1bWVudCBpcyAmbHQ7aW5jbHVkZSZndDtkIGJ5IGFub3RoZXIKLSAgICAgKiBzY2hlbWEgZG9jdW1lbnQuCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIHN0YXRpYyBzaG9ydCBDT05URVhUX0lOQ0xVREUgICA9IDA7Ci0gICAgLyoqCi0gICAgICogSW5kaWNhdGUgdGhhdCB0aGUgY3VycmVudCBzY2hlbWEgZG9jdW1lbnQgaXMgJmx0O3JlZGVmaW5lJmd0O2QgYnkgYW5vdGhlcgotICAgICAqIHNjaGVtYSBkb2N1bWVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgZmluYWwgc3RhdGljIHNob3J0IENPTlRFWFRfUkVERUZJTkUgID0gMTsKLSAgICAvKioKLSAgICAgKiBJbmRpY2F0ZSB0aGF0IHRoZSBjdXJyZW50IHNjaGVtYSBkb2N1bWVudCBpcyAmbHQ7aW1wb3J0Jmd0O2VkIGJ5IGFub3RoZXIKLSAgICAgKiBzY2hlbWEgZG9jdW1lbnQuCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIHN0YXRpYyBzaG9ydCBDT05URVhUX0lNUE9SVCAgICA9IDI7Ci0gICAgLyoqCi0gICAgICogSW5kaWNhdGUgdGhhdCB0aGUgY3VycmVudCBzY2hlbWEgZG9jdW1lbnQgaXMgYmVpbmcgcHJlcGFyc2VkLgotICAgICAqLwotICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgc2hvcnQgQ09OVEVYVF9QUkVQQVJTRSAgPSAzOwotICAgIC8qKgotICAgICAqIEluZGljYXRlIHRoYXQgdGhlIHBhcnNlIG9mIHRoZSBjdXJyZW50IHNjaGVtYSBkb2N1bWVudCBpcyB0cmlnZ2VyZWQKLSAgICAgKiBieSB4c2k6c2NoZW1hTG9jYXRpb24vbm9OYW1lc3BhY2VTY2hlbWFMb2NhdGlvbiBhdHRyaWJ1dGUocykgaW4gdGhlCi0gICAgICogaW5zdGFuY2UgZG9jdW1lbnQuIFRoaXMgdmFsdWUgaXMgb25seSB1c2VkIGlmIHdlIGRvbid0IGRlZmVyIHRoZSBsb2FkaW5nCi0gICAgICogb2Ygc2NoZW1hIGRvY3VtZW50cy4KLSAgICAgKi8KLSAgICBwdWJsaWMgZmluYWwgc3RhdGljIHNob3J0IENPTlRFWFRfSU5TVEFOQ0UgID0gNDsKLSAgICAvKioKLSAgICAgKiBJbmRpY2F0ZSB0aGF0IHRoZSBwYXJzZSBvZiB0aGUgY3VycmVudCBzY2hlbWEgZG9jdW1lbnQgaXMgdHJpZ2dlcmVkIGJ5Ci0gICAgICogdGhlIG9jY3VycmVuY2Ugb2YgYW4gZWxlbWVudCB3aG9zZSBuYW1lc3BhY2UgaXMgdGhlIHRhcmdldCBuYW1lc3BhY2UKLSAgICAgKiBvZiB0aGlzIHNjaGVtYSBkb2N1bWVudC4gVGhpcyB2YWx1ZSBpcyBvbmx5IHVzZWQgaWYgd2UgZG8gZGVmZXIgdGhlCi0gICAgICogbG9hZGluZyBvZiBzY2hlbWEgZG9jdW1lbnRzIHVudGlsIGEgY29tcG9uZW50IGZyb20gdGhhdCBuYW1lc3BhY2UgaXMKLSAgICAgKiByZWZlcmVuY2VkIGZyb20gdGhlIGluc3RhbmNlLgotICAgICAqLwotICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgc2hvcnQgQ09OVEVYVF9FTEVNRU5UICAgPSA1OwotICAgIC8qKgotICAgICAqIEluZGljYXRlIHRoYXQgdGhlIHBhcnNlIG9mIHRoZSBjdXJyZW50IHNjaGVtYSBkb2N1bWVudCBpcyB0cmlnZ2VyZWQgYnkKLSAgICAgKiB0aGUgb2NjdXJyZW5jZSBvZiBhbiBhdHRyaWJ1dGUgd2hvc2UgbmFtZXNwYWNlIGlzIHRoZSB0YXJnZXQgbmFtZXNwYWNlCi0gICAgICogb2YgdGhpcyBzY2hlbWEgZG9jdW1lbnQuIFRoaXMgdmFsdWUgaXMgb25seSB1c2VkIGlmIHdlIGRvIGRlZmVyIHRoZQotICAgICAqIGxvYWRpbmcgb2Ygc2NoZW1hIGRvY3VtZW50cyB1bnRpbCBhIGNvbXBvbmVudCBmcm9tIHRoYXQgbmFtZXNwYWNlIGlzCi0gICAgICogcmVmZXJlbmNlZCBmcm9tIHRoZSBpbnN0YW5jZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgZmluYWwgc3RhdGljIHNob3J0IENPTlRFWFRfQVRUUklCVVRFID0gNjsKLSAgICAvKioKLSAgICAgKiBJbmRpY2F0ZSB0aGF0IHRoZSBwYXJzZSBvZiB0aGUgY3VycmVudCBzY2hlbWEgZG9jdW1lbnQgaXMgdHJpZ2dlcmVkIGJ5Ci0gICAgICogdGhlIG9jY3VycmVuY2Ugb2YgYW4gInhzaTp0eXBlIiBhdHRyaWJ1dGUsIHdob3NlIHZhbHVlIChhIFFOYW1lKSBoYXMKLSAgICAgKiB0aGUgdGFyZ2V0IG5hbWVzcGFjZSBvZiB0aGlzIHNjaGVtYSBkb2N1bWVudCBhcyBpdHMgbmFtZXNwYWNlLgotICAgICAqIFRoaXMgdmFsdWUgaXMgb25seSB1c2VkIGlmIHdlIGRvIGRlZmVyIHRoZSBsb2FkaW5nIG9mIHNjaGVtYSBkb2N1bWVudHMKLSAgICAgKiB1bnRpbCBhIGNvbXBvbmVudCBmcm9tIHRoYXQgbmFtZXNwYWNlIGlzIHJlZmVyZW5jZWQgZnJvbSB0aGUgaW5zdGFuY2UuCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIHN0YXRpYyBzaG9ydCBDT05URVhUX1hTSVRZUEUgICA9IDc7Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIGNvbnRleHQuIFRoZSByZXR1cm5lZCB2YWx1ZSBpcyBvbmUgb2YgdGhlIHByZS1kZWZpbmVkCi0gICAgICogQ09OVEVYVF94eHggY29uc3RhbnRzLgotICAgICAqCi0gICAgICogQHJldHVybiAgdGhlIHZhbHVlIGluZGljYXRpbmcgdGhlIGNvbnRleHQKLSAgICAgKi8KLSAgICBwdWJsaWMgc2hvcnQgZ2V0Q29udGV4dFR5cGUoKTsKLQotICAgIC8qKgotICAgICAqIElmIHRoZSBjb250ZXh0IGlzICJpbmNsdWRlIiBvciAicmVkZWZpbmUiLCB0aGVuIHJldHVybiB0aGUgdGFyZ2V0Ci0gICAgICogbmFtZXNwYWNlIG9mIHRoZSBlbmNsb3Npbmcgc2NoZW1hIGRvY3VtZW50OyBvdGhlcndpc2UsIHRoZSBleHBlY3RlZAotICAgICAqIHRhcmdldCBuYW1lc3BhY2Ugb2YgdGhpcyBkb2N1bWVudC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gIHRoZSBleHBlY3RlZC9lbmNsb3NpbmcgdGFyZ2V0IG5hbWVzcGFjZQotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0TmFtZXNwYWNlKCk7Ci0KLSAgICAvKioKLSAgICAgKiBGb3IgaW1wb3J0IGFuZCByZWZlcmVuY2VzIGZyb20gdGhlIGluc3RhbmNlIGRvY3VtZW50LCBpdCdzIHBvc3NpYmxlIHRvCi0gICAgICogaGF2ZSBtdWx0aXBsZSBoaW50cyBmb3Igb25lIG5hbWVzcGFjZS4gU28gdGhpcyBtZXRob2QgcmV0dXJucyBhbiBhcnJheSwKLSAgICAgKiB3aGljaCBjb250YWlucyBhbGwgbG9jYXRpb24gaGludHMuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuICBhbiBhcnJheSBvZiBhbGwgbG9jYXRpb24gaGludHMgYXNzb2NpYXRlZCB0byB0aGUgZXhwZWN0ZWQKLSAgICAgKiAgICAgICAgICB0YXJnZXQgbmFtZXNwYWNlCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZ1tdIGdldExvY2F0aW9uSGludHMoKTsKLQotICAgIC8qKgotICAgICAqIElmIGEgY2FsbCBpcyB0cmlnZ2VyZWQgYnkgYW4gZWxlbWVudC9hdHRyaWJ1dGUveHNpOnR5cGUgaW4gdGhlIGluc3RhbmNlLAotICAgICAqIHRoaXMgY2FsbCByZXR1cm5zIHRoZSBuYW1lIG9mIHN1Y2ggdHJpZ2dlcmluZyBjb21wb25lbnQ6IHRoZSBuYW1lIG9mCi0gICAgICogdGhlIGVsZW1lbnQvYXR0cmlidXRlLCBvciB0aGUgdmFsdWUgb2YgdGhlIHhzaTp0eXBlLgotICAgICAqCi0gICAgICogQHJldHVybiAgdGhlIG5hbWUgb2YgdGhlIHRyaWdnZXJpbmcgY29tcG9uZW50Ci0gICAgICovCi0gICAgcHVibGljIFFOYW1lIGdldFRyaWdnZXJpbmdDb21wb25lbnQoKTsKLQotICAgIC8qKgotICAgICAqIElmIGEgY2FsbCBpcyB0cmlnZ2VyZWQgYnkgYW4gYXR0cmlidXRlIG9yIHhzaTp0eXBlLCB0aGVuIHRoaXMgbWV0aG9kCi0gICAgICogcmV0dXJucyB0aGUgZW5jbG9zaW5nIGVsZW1lbnQgb2Ygc3VjaCBlbGVtZW50LgotICAgICAqCi0gICAgICogQHJldHVybiAgdGhlIG5hbWUgb2YgdGhlIGVuY2xvc2luZyBlbGVtZW50Ci0gICAgICovCi0gICAgcHVibGljIFFOYW1lIGdldEVuY2xvc2luZ0VsZW1lbnROYW1lKCk7Ci0KLSAgICAvKioKLSAgICAgKiBJZiBhIGNhbGwgaXMgdHJpZ2dlcmVkIGJ5IGFuIGVsZW1lbnQvYXR0cmlidXRlL3hzaTp0eXBlIGluIHRoZSBpbnN0YW5jZSwKLSAgICAgKiB0aGlzIGNhbGwgcmV0dXJucyBhbGwgYXR0cmlidXRlIG9mIHN1Y2ggZWxlbWVudCAob3IgZW5jbG9zaW5nIGVsZW1lbnQpLgotICAgICAqCi0gICAgICogQHJldHVybiAgYWxsIGF0dHJpYnV0ZXMgb2YgdGhlIHRpZ2dlcmluZy9lbmNsb3NpbmcgZWxlbWVudAotICAgICAqLwotICAgIHB1YmxpYyBYTUxBdHRyaWJ1dGVzIGdldEF0dHJpYnV0ZXMoKTsKLQotfSAvLyBYU0REZXNjcmlwdGlvbgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveG5pL2dyYW1tYXJzL1hTR3JhbW1hci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveG5pL2dyYW1tYXJzL1hTR3JhbW1hci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0NDU1OTUxLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3huaS9ncmFtbWFycy9YU0dyYW1tYXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDU1ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuZ3JhbW1hcnM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTTW9kZWw7Ci0KLS8qKgotICogUmVwcmVzZW50aW5nIGEgc2NoZW1hIGdyYW1tYXIuIEl0IGNvbnRhaW5zIGRlY2xhcmF0b2luL2RlZmluaXRpb25zIGZyb20KLSAqIGEgY2VydGFpbiBuYW1lc3BhY2UuIFdoZW4gYSBncmFtbWFyIGlzIHByZXBhcnNlZCwgYW5kIGl0cyBncmFtbWFyIHR5cGUgaXMKLSAqIFhNTCBTY2hlbWEsIGl0IGNhbiBiZSBjYXN0ZWQgdG8gdGhpcyBpbnRlcmZhY2UuIE9iamVjdHMgb2YgdGhpcyBpbnRlcmZhY2UKLSAqIGNhbiBiZSBjb252ZXJ0ZWQgdG8gWFNNb2RlbCwgZnJvbSB3aGljaCBmdXJ0aGVyIGluZm9ybWF0aW9uIGFib3V0IGNvbXBvbmVudHMKLSAqIGluIHRoaXMgZ3JhbW1hciBjYW4gYmUgb2J0YWluZWQuCi0gKgotICogQGF1dGhvciBTYW5keSBHYW8sIElCTQotICoKLSAqLwotcHVibGljIGludGVyZmFjZSBYU0dyYW1tYXIgZXh0ZW5kcyBHcmFtbWFyIHsKLQotICAgIC8qKgotICAgICAqIFJldHVybiBhbiA8Y29kZT5YU01vZGVsPC9jb2RlPiB0aGF0IHJlcHJlc2VudHMgY29tcG9uZW50cyBpbiB0aGlzIHNjaGVtYQotICAgICAqIGdyYW1tYXIgYW5kIGFueSBzY2hlbWEgZ3JhbW1hcnMgdGhhdCBhcmUgaW1wb3J0ZWQgYnkgdGhpcyBncmFtbWFyCi0gICAgICogZGlyZWN0bHkgb3IgaW5kaXJlY3RseS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gIGFuIDxjb2RlPlhTTW9kZWw8L2NvZGU+IHJlcHJlc2VudGluZyB0aGlzIHNjaGVtYSBncmFtbWFyCi0gICAgICovCi0gICAgcHVibGljIFhTTW9kZWwgdG9YU01vZGVsKCk7Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gYW4gPGNvZGU+WFNNb2RlbDwvY29kZT4gdGhhdCByZXByZXNlbnRzIGNvbXBvbmVudHMgaW4gdGhpcyBzY2hlbWEKLSAgICAgKiBncmFtbWFyIGFuZCB0aGUgZ3JhbW1hcnMgaW4gdGhlIDxjb2RlPmdyYW1tYXJzPC9jb2RlPnBhcmFtZXRlciwKLSAgICAgKiBhbnkgc2NoZW1hIGdyYW1tYXJzIHRoYXQgYXJlIGltcG9ydGVkIGJ5IHRoZW0gZGlyZWN0bHkgb3IgaW5kaXJlY3RseS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gIGFuIDxjb2RlPlhTTW9kZWw8L2NvZGU+IHJlcHJlc2VudGluZyB0aGVzZSBzY2hlbWEgZ3JhbW1hcnMKLSAgICAgKi8KLSAgICBwdWJsaWMgWFNNb2RlbCB0b1hTTW9kZWwoWFNHcmFtbWFyW10gZ3JhbW1hcnMpOwotCi19IC8vIGludGVyZmFjZSBYU0dyYW1tYXIKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3huaS9wYXJzZXIvWE1MQ29tcG9uZW50LmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94bmkvcGFyc2VyL1hNTENvbXBvbmVudC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2OGIyZmFhLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3huaS9wYXJzZXIvWE1MQ29tcG9uZW50LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMjYgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMC0yMDAyLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlcjsKLQotLyoqCi0gKiBUaGUgY29tcG9uZW50IGludGVyZmFjZSBkZWZpbmVzIG1ldGhvZHMgdGhhdCBtdXN0IGJlIGltcGxlbWVudGVkCi0gKiBieSBjb21wb25lbnRzIGluIGEgcGFyc2VyIGNvbmZpZ3VyYXRpb24uIFRoZSBjb21wb25lbnQgbWV0aG9kcyBhbGxvdwotICogdGhlIGNvbXBvbmVudCBtYW5hZ2VyIHRvIGluaXRpYWxpemUgdGhlIGNvbXBvbmVudCBzdGF0ZSBhbmQgbm90aWZ5Ci0gKiB0aGUgY29tcG9uZW50IHdoZW4gZmVhdHVyZSBhbmQgcHJvcGVydHkgdmFsdWVzIGNoYW5nZS4KLSAqCi0gKiBAc2VlIFhNTENvbXBvbmVudE1hbmFnZXIKLSAqCi0gKiBAYXV0aG9yIEFuZHkgQ2xhcmssIElCTQotICoKLSAqLwotcHVibGljIGludGVyZmFjZSBYTUxDb21wb25lbnQgewotCi0gICAgLy8KLSAgICAvLyBYTUxDb21wb25lbnQgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBSZXNldHMgdGhlIGNvbXBvbmVudC4gVGhlIGNvbXBvbmVudCBjYW4gcXVlcnkgdGhlIGNvbXBvbmVudCBtYW5hZ2VyCi0gICAgICogYWJvdXQgYW55IGZlYXR1cmVzIGFuZCBwcm9wZXJ0aWVzIHRoYXQgYWZmZWN0IHRoZSBvcGVyYXRpb24gb2YgdGhlCi0gICAgICogY29tcG9uZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIGNvbXBvbmVudE1hbmFnZXIgVGhlIGNvbXBvbmVudCBtYW5hZ2VyLgotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGNvbXBvbmVudCBvbiBpbml0aWFsaXphdGlvbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCByZXNldChYTUxDb21wb25lbnRNYW5hZ2VyIGNvbXBvbmVudE1hbmFnZXIpCi0gICAgICAgIHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhIGxpc3Qgb2YgZmVhdHVyZSBpZGVudGlmaWVycyB0aGF0IGFyZSByZWNvZ25pemVkIGJ5Ci0gICAgICogdGhpcyBjb21wb25lbnQuIFRoaXMgbWV0aG9kIG1heSByZXR1cm4gbnVsbCBpZiBubyBmZWF0dXJlcwotICAgICAqIGFyZSByZWNvZ25pemVkIGJ5IHRoaXMgY29tcG9uZW50LgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmdbXSBnZXRSZWNvZ25pemVkRmVhdHVyZXMoKTsKLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIHN0YXRlIG9mIGEgZmVhdHVyZS4gVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBjb21wb25lbnQKLSAgICAgKiBtYW5hZ2VyIGFueSB0aW1lIGFmdGVyIHJlc2V0IHdoZW4gYSBmZWF0dXJlIGNoYW5nZXMgc3RhdGUuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBDb21wb25lbnRzIHNob3VsZCBzaWxlbnRseSBpZ25vcmUgZmVhdHVyZXMKLSAgICAgKiB0aGF0IGRvIG5vdCBhZmZlY3QgdGhlIG9wZXJhdGlvbiBvZiB0aGUgY29tcG9uZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIGZlYXR1cmVJZCBUaGUgZmVhdHVyZSBpZGVudGlmaWVyLgotICAgICAqIEBwYXJhbSBzdGF0ZSAgICAgVGhlIHN0YXRlIG9mIHRoZSBmZWF0dXJlLgotICAgICAqCi0gICAgICogQHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIFRocm93biBmb3IgY29uZmlndXJhdGlvbiBlcnJvci4KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW4gZ2VuZXJhbCwgY29tcG9uZW50cyBzaG91bGQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb25seSB0aHJvdyB0aGlzIGV4Y2VwdGlvbiBpZgotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdCBpcyA8c3Ryb25nPnJlYWxseTwvc3Ryb25nPgotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhIGNyaXRpY2FsIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEZlYXR1cmUoU3RyaW5nIGZlYXR1cmVJZCwgYm9vbGVhbiBzdGF0ZSkKLSAgICAgICAgdGhyb3dzIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGEgbGlzdCBvZiBwcm9wZXJ0eSBpZGVudGlmaWVycyB0aGF0IGFyZSByZWNvZ25pemVkIGJ5Ci0gICAgICogdGhpcyBjb21wb25lbnQuIFRoaXMgbWV0aG9kIG1heSByZXR1cm4gbnVsbCBpZiBubyBwcm9wZXJ0aWVzCi0gICAgICogYXJlIHJlY29nbml6ZWQgYnkgdGhpcyBjb21wb25lbnQuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZ1tdIGdldFJlY29nbml6ZWRQcm9wZXJ0aWVzKCk7Ci0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiBhIHByb3BlcnR5LiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgdGhlIGNvbXBvbmVudAotICAgICAqIG1hbmFnZXIgYW55IHRpbWUgYWZ0ZXIgcmVzZXQgd2hlbiBhIHByb3BlcnR5IGNoYW5nZXMgdmFsdWUuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBDb21wb25lbnRzIHNob3VsZCBzaWxlbnRseSBpZ25vcmUgcHJvcGVydGllcwotICAgICAqIHRoYXQgZG8gbm90IGFmZmVjdCB0aGUgb3BlcmF0aW9uIG9mIHRoZSBjb21wb25lbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcHJvcGVydHlJZCBUaGUgcHJvcGVydHkgaWRlbnRpZmllci4KLSAgICAgKiBAcGFyYW0gdmFsdWUgICAgICBUaGUgdmFsdWUgb2YgdGhlIHByb3BlcnR5LgotICAgICAqCi0gICAgICogQHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIFRocm93biBmb3IgY29uZmlndXJhdGlvbiBlcnJvci4KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW4gZ2VuZXJhbCwgY29tcG9uZW50cyBzaG91bGQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb25seSB0aHJvdyB0aGlzIGV4Y2VwdGlvbiBpZgotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdCBpcyA8c3Ryb25nPnJlYWxseTwvc3Ryb25nPgotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhIGNyaXRpY2FsIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFByb3BlcnR5KFN0cmluZyBwcm9wZXJ0eUlkLCBPYmplY3QgdmFsdWUpCi0gICAgICAgdGhyb3dzIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBkZWZhdWx0IHN0YXRlIGZvciBhIGZlYXR1cmUsIG9yIG51bGwgaWYgdGhpcwotICAgICAqIGNvbXBvbmVudCBkb2VzIG5vdCB3YW50IHRvIHJlcG9ydCBhIGRlZmF1bHQgdmFsdWUgZm9yIHRoaXMKLSAgICAgKiBmZWF0dXJlLgotICAgICAqCi0gICAgICogQHBhcmFtIGZlYXR1cmVJZCBUaGUgZmVhdHVyZSBpZGVudGlmaWVyLgotICAgICAqCi0gICAgICogQHNpbmNlIFhlcmNlcyAyLjIuMAotICAgICAqLwotICAgIHB1YmxpYyBCb29sZWFuIGdldEZlYXR1cmVEZWZhdWx0KFN0cmluZyBmZWF0dXJlSWQpOwotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgZGVmYXVsdCBzdGF0ZSBmb3IgYSBwcm9wZXJ0eSwgb3IgbnVsbCBpZiB0aGlzCi0gICAgICogY29tcG9uZW50IGRvZXMgbm90IHdhbnQgdG8gcmVwb3J0IGEgZGVmYXVsdCB2YWx1ZSBmb3IgdGhpcwotICAgICAqIHByb3BlcnR5LgotICAgICAqCi0gICAgICogQHBhcmFtIHByb3BlcnR5SWQgVGhlIHByb3BlcnR5IGlkZW50aWZpZXIuCi0gICAgICoKLSAgICAgKiBAc2luY2UgWGVyY2VzIDIuMi4wCi0gICAgICovCi0gICAgcHVibGljIE9iamVjdCBnZXRQcm9wZXJ0eURlZmF1bHQoU3RyaW5nIHByb3BlcnR5SWQpOwotCi19IC8vIGludGVyZmFjZSBYTUxDb21wb25lbnQKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3huaS9wYXJzZXIvWE1MQ29tcG9uZW50TWFuYWdlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveG5pL3BhcnNlci9YTUxDb21wb25lbnRNYW5hZ2VyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDgwZmFhNmEuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveG5pL3BhcnNlci9YTUxDb21wb25lbnRNYW5hZ2VyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5MCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAwLTIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLkZlYXR1cmVTdGF0ZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuUHJvcGVydHlTdGF0ZTsKLQotLyoqCi0gKiBUaGUgY29tcG9uZW50IG1hbmFnZXIgbWFuYWdlcyBhIHBhcnNlciBjb25maWd1cmF0aW9uIGFuZCB0aGUgY29tcG9uZW50cwotICogdGhhdCBtYWtlIHVwIHRoYXQgY29uZmlndXJhdGlvbi4gVGhlIG1hbmFnZXIgbm90aWZpZXMgZWFjaCBjb21wb25lbnQKLSAqIGJlZm9yZSBwYXJzaW5nIHRvIGFsbG93IHRoZSBjb21wb25lbnRzIHRvIGluaXRpYWxpemUgdGhlaXIgc3RhdGU7IGFuZAotICogYWxzbyBhbnkgdGltZSB0aGF0IGEgcGFyc2VyIGZlYXR1cmUgb3IgcHJvcGVydHkgY2hhbmdlcy4KLSAqIDxwPgotICogVGhlIG1ldGhvZHMgb2YgdGhlIGNvbXBvbmVudCBtYW5hZ2VyIGFsbG93IGNvbXBvbmVudHMgdG8gcXVlcnkgZmVhdHVyZXMKLSAqIGFuZCBwcm9wZXJ0aWVzIHRoYXQgYWZmZWN0IHRoZSBvcGVyYXRpb24gb2YgdGhlIGNvbXBvbmVudC4KLSAqCi0gKiBAc2VlIFhNTENvbXBvbmVudAotICoKLSAqIEBhdXRob3IgQW5keSBDbGFyaywgSUJNCi0gKgotICogQHZlcnNpb24gJElkOiBYTUxDb21wb25lbnRNYW5hZ2VyLmphdmEsdiAxLjYgMjAxMC0xMS0wMSAwNDo0MDoyMiBqb2VodyBFeHAgJAotICovCi1wdWJsaWMgaW50ZXJmYWNlIFhNTENvbXBvbmVudE1hbmFnZXIgewotCi0gICAgLy8KLSAgICAvLyBYTUxDb21wb25lbnRNYW5hZ2VyIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgc3RhdGUgb2YgYSBmZWF0dXJlLgotICAgICAqCi0gICAgICogQHBhcmFtIGZlYXR1cmVJZCBUaGUgZmVhdHVyZSBpZGVudGlmaWVyLgotICAgICAqCi0gICAgICogQHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIFRocm93biBvbiBjb25maWd1cmF0aW9uIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGdldEZlYXR1cmUoU3RyaW5nIGZlYXR1cmVJZCkKLSAgICAgICAgdGhyb3dzIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBzdGF0ZSBvZiBhIGZlYXR1cmUuCi0gICAgICogRG9lcyBub3QgdGhyb3cgZXhjZXB0aW9ucy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBmZWF0dXJlSWQgVGhlIGZlYXR1cmUgaWRlbnRpZmllci4KLSAgICAgKiBAcGFyYW0gZGVmYXVsdFZhbHVlIERlZmF1bHQgdmFsdWUgaWYgZnV0dXJlIGlzIG5vdCBhdmFpbGFibGUuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0RmVhdHVyZShTdHJpbmcgZmVhdHVyZUlkLCBib29sZWFuIGRlZmF1bHRWYWx1ZSk7Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiBhIHByb3BlcnR5LgotICAgICAqCi0gICAgICogQHBhcmFtIHByb3BlcnR5SWQgVGhlIHByb3BlcnR5IGlkZW50aWZpZXIuCi0gICAgICoKLSAgICAqIEB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBUaHJvd24gb24gY29uZmlndXJhdGlvbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0IGdldFByb3BlcnR5KFN0cmluZyBwcm9wZXJ0eUlkKQotICAgICAgICB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIGEgcHJvcGVydHkuCi0gICAgICogRG9lcyBub3QgdGhyb3cgZXhjZXB0aW9ucy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBwcm9wZXJ0eUlkIFRoZSBwcm9wZXJ0eSBpZGVudGlmaWVyLgotICAgICAqIEBwYXJhbSBkZWZhdWx0T2JqZWN0IFJldHVybiB2YWx1ZSBpZiBwcm9wZXJ0eSBpcyBub3QgYXZhaWxhYmxlLgotICAgICAqCi0gICAgICovCi0gICAgcHVibGljIE9iamVjdCBnZXRQcm9wZXJ0eShTdHJpbmcgcHJvcGVydHlJZCwgT2JqZWN0IGRlZmF1bHRPYmplY3QpOwotCi0gICAgcHVibGljIEZlYXR1cmVTdGF0ZSBnZXRGZWF0dXJlU3RhdGUoU3RyaW5nIGZlYXR1cmVJZCk7Ci0KLSAgICBwdWJsaWMgUHJvcGVydHlTdGF0ZSBnZXRQcm9wZXJ0eVN0YXRlKFN0cmluZyBwcm9wZXJ0eUlkKTsKLQotfSAvLyBpbnRlcmZhY2UgWE1MQ29tcG9uZW50TWFuYWdlcgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveG5pL3BhcnNlci9YTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94bmkvcGFyc2VyL1hNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYjFjZDc3OS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94bmkvcGFyc2VyL1hNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDk5ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEsIDIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlN0YXR1czsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTklFeGNlcHRpb247Ci0KLS8qKgotICogQW4gWE5JIHBhcnNlciBjb25maWd1cmF0aW9uIGV4Y2VwdGlvbi4gVGhpcyBleGNlcHRpb24gY2xhc3MgZXh0ZW5kcwotICogPGNvZGU+WE5JRXhjZXB0aW9uPC9jb2RlPiBpbiBvcmRlciB0byBkaWZmZXJlbnRpYXRlIGJldHdlZW4gZ2VuZXJhbAotICogcGFyc2luZyBlcnJvcnMgYW5kIGNvbmZpZ3VyYXRpb24gZXJyb3JzLgotICoKLSAqIEBhdXRob3IgQW5keSBDbGFyaywgSUJNCi0gKgotICogQHZlcnNpb24gJElkOiBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uLmphdmEsdiAxLjcgMjAxMC0xMS0wMSAwNDo0MDoyMiBqb2VodyBFeHAgJAotICovCi1wdWJsaWMgY2xhc3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbgotICAgIGV4dGVuZHMgWE5JRXhjZXB0aW9uIHsKLQotICAgIC8qKiBTZXJpYWxpemF0aW9uIHZlcnNpb24uICovCi0gICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC01NDM3NDI3NDA0NTQ3NjY5MTg4TDsKLQotICAgIC8vCi0gICAgLy8gRGF0YQotICAgIC8vCi0KLSAgICAvKiogRXhjZXB0aW9uIHR5cGUuICovCi0gICAgcHJvdGVjdGVkIFN0YXR1cyBmVHlwZTsKLQotICAgIC8qKiBJZGVudGlmaWVyLiAqLwotICAgIHByb3RlY3RlZCBTdHJpbmcgZklkZW50aWZpZXI7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0cnVjdG9ycwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RzIGEgY29uZmlndXJhdGlvbiBleGNlcHRpb24gd2l0aCB0aGUgc3BlY2lmaWVkIHR5cGUKLSAgICAgKiBhbmQgZmVhdHVyZS9wcm9wZXJ0eSBpZGVudGlmaWVyLgotICAgICAqCi0gICAgICogQHBhcmFtIHR5cGUgICAgICAgVGhlIHR5cGUgb2YgdGhlIGV4Y2VwdGlvbi4KLSAgICAgKiBAcGFyYW0gaWRlbnRpZmllciBUaGUgZmVhdHVyZSBvciBwcm9wZXJ0eSBpZGVudGlmaWVyLgotICAgICAqLwotICAgIHB1YmxpYyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uKFN0YXR1cyB0eXBlLCBTdHJpbmcgaWRlbnRpZmllcikgewotICAgICAgICBzdXBlcihpZGVudGlmaWVyKTsKLSAgICAgICAgZlR5cGUgPSB0eXBlOwotICAgICAgICBmSWRlbnRpZmllciA9IGlkZW50aWZpZXI7Ci0gICAgfSAvLyA8aW5pdD4oc2hvcnQsU3RyaW5nKQotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0cyBhIGNvbmZpZ3VyYXRpb24gZXhjZXB0aW9uIHdpdGggdGhlIHNwZWNpZmllZCB0eXBlLAotICAgICAqIGZlYXR1cmUvcHJvcGVydHkgaWRlbnRpZmllciwgYW5kIGVycm9yIG1lc3NhZ2UKLSAgICAgKgotICAgICAqIEBwYXJhbSB0eXBlICAgICAgIFRoZSB0eXBlIG9mIHRoZSBleGNlcHRpb24uCi0gICAgICogQHBhcmFtIGlkZW50aWZpZXIgVGhlIGZlYXR1cmUgb3IgcHJvcGVydHkgaWRlbnRpZmllci4KLSAgICAgKiBAcGFyYW0gbWVzc2FnZSAgICBUaGUgZXJyb3IgbWVzc2FnZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbihTdGF0dXMgdHlwZSwgU3RyaW5nIGlkZW50aWZpZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG1lc3NhZ2UpIHsKLSAgICAgICAgc3VwZXIobWVzc2FnZSk7Ci0gICAgICAgIGZUeXBlID0gdHlwZTsKLSAgICAgICAgZklkZW50aWZpZXIgPSBpZGVudGlmaWVyOwotICAgIH0gLy8gPGluaXQ+KHNob3J0LFN0cmluZyxTdHJpbmcpCi0KLSAgICAvLwotICAgIC8vIFB1YmxpYyBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIGV4Y2VwdGlvbiB0eXBlLgotICAgICAqLwotICAgIHB1YmxpYyBTdGF0dXMgZ2V0VHlwZSgpIHsKLSAgICAgICAgcmV0dXJuIGZUeXBlOwotICAgIH0gLy8gZ2V0VHlwZSgpOnNob3J0Ci0KLSAgICAvKiogUmV0dXJucyB0aGUgZmVhdHVyZSBvciBwcm9wZXJ0eSBpZGVudGlmaWVyLiAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0SWRlbnRpZmllcigpIHsKLSAgICAgICAgcmV0dXJuIGZJZGVudGlmaWVyOwotICAgIH0gLy8gZ2V0SWRlbnRpZmllcigpOlN0cmluZwotCi19IC8vIGNsYXNzIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3huaS9wYXJzZXIvWE1MRFREQ29udGVudE1vZGVsRmlsdGVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94bmkvcGFyc2VyL1hNTERURENvbnRlbnRNb2RlbEZpbHRlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3N2U3MWYwLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3huaS9wYXJzZXIvWE1MRFREQ29udGVudE1vZGVsRmlsdGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzNSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLCAyMDAyLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTERURENvbnRlbnRNb2RlbEhhbmRsZXI7Ci0KLS8qKgotICogRGVmaW5lcyBhIERURCBjb250ZW50IG1vZGVsIGZpbHRlciB0aGF0IGFjdHMgYXMgYm90aCBhIHJlY2VpdmVyIGFuZAotICogYW4gZW1pdHRlciBvZiBEVEQgY29udGVudCBtb2RlbCBldmVudHMuCi0gKgotICogQGF1dGhvciBBbmR5IENsYXJrLCBJQk0KLSAqCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgWE1MRFREQ29udGVudE1vZGVsRmlsdGVyCi0gICAgZXh0ZW5kcyBYTUxEVERDb250ZW50TW9kZWxIYW5kbGVyLCBYTUxEVERDb250ZW50TW9kZWxTb3VyY2UgewotCi19IC8vIGludGVyZmFjZSBYTUxEVERDb250ZW50TW9kZWxGaWx0ZXIKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3huaS9wYXJzZXIvWE1MRFREQ29udGVudE1vZGVsU291cmNlLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94bmkvcGFyc2VyL1hNTERURENvbnRlbnRNb2RlbFNvdXJjZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkY2EzYmQ5Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3huaS9wYXJzZXIvWE1MRFREQ29udGVudE1vZGVsU291cmNlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5MCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxLCAyMDAyIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYZXJjZXMiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIEludGVybmF0aW9uYWwKLSAqIEJ1c2luZXNzIE1hY2hpbmVzLCBJbmMuLCBodHRwOi8vd3d3LmFwYWNoZS5vcmcuICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXI7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxEVERDb250ZW50TW9kZWxIYW5kbGVyOwotCi0vKioKLSAqIERlZmluZXMgYSBEVEQgY29udGVudCBtb2RlbCBzb3VyY2UuIEluIG90aGVyIHdvcmRzLCBhbnkgb2JqZWN0IHRoYXQKLSAqIGltcGxlbWVudHMgdGhpcyBpbnRlcmZhY2UgaXMgYWJsZSB0byBlbWl0IERURCBjb250ZW50IG1vZGVsICJldmVudHMiCi0gKiB0byB0aGUgcmVnaXN0ZXJlZCBEVEQgY29udGVudCBtb2RlbCBoYW5kbGVyLiBUaGVzZSBldmVudHMgY291bGQgYmUKLSAqIHByb2R1Y2VkIGJ5IHBhcnNpbmcgYW4gWE1MIGRvY3VtZW50J3MgaW50ZXJuYWwgb3IgZXh0ZXJuYWwgc3Vic2V0LAotICogY291bGQgYmUgZ2VuZXJhdGVkIGZyb20gc29tZSBvdGhlciBzb3VyY2UsIG9yIGNvdWxkIGJlIGNyZWF0ZWQKLSAqIHByb2dyYW1tYXRpY2FsbHkuIFRoaXMgaW50ZXJmYWNlIGRvZXMgbm90IHNheSA8ZW0+aG93PC9lbT4gdGhlIGV2ZW50cwotICogYXJlIGNyZWF0ZWQsIG9ubHkgdGhhdCB0aGUgaW1wbGVtZW50b3IgaXMgYWJsZSB0byBlbWl0IHRoZW0uCi0gKgotICogQGF1dGhvciBBbmR5IENsYXJrLCBJQk0KLSAqCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgWE1MRFREQ29udGVudE1vZGVsU291cmNlIHsKLQotICAgIC8vCi0gICAgLy8gWE1MRFREQ29udGVudE1vZGVsU291cmNlIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqIFNldHMgdGhlIERURCBjb250ZW50IG1vZGVsIGhhbmRsZXIuICovCi0gICAgcHVibGljIHZvaWQgc2V0RFREQ29udGVudE1vZGVsSGFuZGxlcihYTUxEVERDb250ZW50TW9kZWxIYW5kbGVyIGhhbmRsZXIpOwotCi0gICAgLyoqIFJldHVybnMgdGhlIERURCBjb250ZW50IG1vZGVsIGhhbmRsZXIuICovCi0gICAgcHVibGljIFhNTERURENvbnRlbnRNb2RlbEhhbmRsZXIgZ2V0RFREQ29udGVudE1vZGVsSGFuZGxlciggKTsKLQotfSAvLyBpbnRlcmZhY2UgWE1MRFREQ29udGVudE1vZGVsU291cmNlCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94bmkvcGFyc2VyL1hNTERUREZpbHRlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveG5pL3BhcnNlci9YTUxEVERGaWx0ZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZjMwOTMyZi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94bmkvcGFyc2VyL1hNTERUREZpbHRlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzUgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMSwgMjAwMiwyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXI7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxEVERIYW5kbGVyOwotCi0vKioKLSAqIERlZmluZXMgYSBEVEQgZmlsdGVyIHRoYXQgYWN0cyBhcyBib3RoIGEgcmVjZWl2ZXIgYW5kIGFuIGVtaXR0ZXIKLSAqIG9mIERURCBldmVudHMuCi0gKgotICogQGF1dGhvciBBbmR5IENsYXJrLCBJQk0KLSAqCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgWE1MRFRERmlsdGVyCi0gICAgZXh0ZW5kcyBYTUxEVERIYW5kbGVyLCBYTUxEVERTb3VyY2UgewotCi19IC8vIGludGVyZmFjZSBYTUxEVERGaWx0ZXIKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3huaS9wYXJzZXIvWE1MRFREU2Nhbm5lci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveG5pL3BhcnNlci9YTUxEVERTY2FubmVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDE4OTE1MmQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveG5pL3BhcnNlci9YTUxEVERTY2FubmVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMDkgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMSwgMjAwMiwyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXI7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWxzLlhNTExpbWl0QW5hbHl6ZXI7Ci1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTklFeGNlcHRpb247Ci0KLS8qKgotICogVGhpcyBpbnRlcmZhY2UgZGVmaW5lcyBhIGdlbmVyaWMgRFREIHNjYW5uZXIuIFRoaXMgaW50ZXJmYWNlCi0gKiBhbGxvd3MgYSBzY2FubmVyIHRvIGJlIHVzZWQgaW50ZXJjaGFuZ2FibHkgaW4gZXhpc3RpbmcgcGFyc2VyCi0gKiBjb25maWd1cmF0aW9ucy4KLSAqIDxwPgotICogSWYgdGhlIHBhcnNlciBjb25maWd1cmF0aW9uIHVzZXMgYSBEVEQgc2Nhbm5lciB0aGF0IGltcGxlbWVudHMKLSAqIHRoaXMgaW50ZXJmYWNlLCBjb21wb25lbnRzIHNob3VsZCBiZSBhYmxlIHRvIHF1ZXJ5IHRoZSBzY2FubmVyCi0gKiBpbnN0YW5jZSBmcm9tIHRoZSBjb21wb25lbnQgbWFuYWdlciB1c2luZyB0aGUgZm9sbG93aW5nIHByb3BlcnR5Ci0gKiBpZGVudGlmaWVyOgotICogPGJsb2NrcXVvdGU+Ci0gKiAgImh0dHA6Ly9hcGFjaGUub3JnL3htbC9wcm9wZXJ0aWVzL2ludGVybmFsL2R0ZC1zY2FubmVyIgotICogPC9ibG9ja3F1b3RlPgotICoKLSAqIEBhdXRob3IgQW5keSBDbGFyaywgSUJNCi0gKgotICovCi1wdWJsaWMgaW50ZXJmYWNlIFhNTERURFNjYW5uZXIKLSAgICBleHRlbmRzIFhNTERURFNvdXJjZSwgWE1MRFREQ29udGVudE1vZGVsU291cmNlIHsKLQotICAgIC8vCi0gICAgLy8gWE1MRFREU2Nhbm5lciBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIGlucHV0IHNvdXJjZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBpbnB1dFNvdXJjZSBUaGUgaW5wdXQgc291cmNlIG9yIG51bGwuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIFRocm93biBvbiBpL28gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0SW5wdXRTb3VyY2UoWE1MSW5wdXRTb3VyY2UgaW5wdXRTb3VyY2UpIHRocm93cyBJT0V4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIFNjYW5zIHRoZSBpbnRlcm5hbCBzdWJzZXQgb2YgdGhlIGRvY3VtZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIGNvbXBsZXRlIFRydWUgaWYgdGhlIHNjYW5uZXIgc2hvdWxkIHNjYW4gdGhlIGRvY3VtZW50Ci0gICAgICogICAgICAgICAgICAgICAgIGNvbXBsZXRlbHksIHB1c2hpbmcgYWxsIGV2ZW50cyB0byB0aGUgcmVnaXN0ZXJlZAotICAgICAqICAgICAgICAgICAgICAgICBkb2N1bWVudCBoYW5kbGVyLiBBIHZhbHVlIG9mIGZhbHNlIGluZGljYXRlcyB0aGF0Ci0gICAgICogICAgICAgICAgICAgICAgIHRoYXQgdGhlIHNjYW5uZXIgc2hvdWxkIG9ubHkgc2NhbiB0aGUgbmV4dCBwb3J0aW9uCi0gICAgICogICAgICAgICAgICAgICAgIG9mIHRoZSBkb2N1bWVudCBhbmQgcmV0dXJuLiBBIHNjYW5uZXIgaW5zdGFuY2UgaXMKLSAgICAgKiAgICAgICAgICAgICAgICAgcGVybWl0dGVkIHRvIGNvbXBsZXRlbHkgc2NhbiBhIGRvY3VtZW50IGlmIGl0IGRvZXMKLSAgICAgKiAgICAgICAgICAgICAgICAgbm90IHN1cHBvcnQgdGhpcyAicHVsbCIgc2Nhbm5pbmcgbW9kZWwuCi0gICAgICogQHBhcmFtIHN0YW5kYWxvbmUgVHJ1ZSBpZiB0aGUgZG9jdW1lbnQgd2FzIHNwZWNpZmllZCBhcyBzdGFuZGFsb25lLgotICAgICAqICAgICAgICAgICAgICAgICAgIFRoaXMgdmFsdWUgaXMgaW1wb3J0YW50IGZvciB2ZXJpZnlpbmcgY2VydGFpbgotICAgICAqICAgICAgICAgICAgICAgICAgIHdlbGwtZm9ybWVkbmVzcyBjb25zdHJhaW50cy4KLSAgICAgKiBAcGFyYW0gaGFzRXh0ZXJuYWxTdWJzZXQgVHJ1ZSBpZiB0aGUgZG9jdW1lbnQgaGFzIGFuIGV4dGVybmFsIERURC4KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgVGhpcyBhbGxvd3MgdGhlIHNjYW5uZXIgdG8gcHJvcGVybHkgbm90aWZ5Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSBoYW5kbGVyIG9mIHRoZSBlbmQgb2YgdGhlIERURCBpbiB0aGUKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgYWJzZW5jZSBvZiBhbiBleHRlcm5hbCBzdWJzZXQuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRydWUgaWYgdGhlcmUgaXMgbW9yZSB0byBzY2FuLCBmYWxzZSBvdGhlcndpc2UuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gc2NhbkRUREludGVybmFsU3Vic2V0KGJvb2xlYW4gY29tcGxldGUsIGJvb2xlYW4gc3RhbmRhbG9uZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBoYXNFeHRlcm5hbFN1YnNldCkKLSAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBYTklFeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBTY2FucyB0aGUgZXh0ZXJuYWwgc3Vic2V0IG9mIHRoZSBkb2N1bWVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjb21wbGV0ZSBUcnVlIGlmIHRoZSBzY2FubmVyIHNob3VsZCBzY2FuIHRoZSBkb2N1bWVudAotICAgICAqICAgICAgICAgICAgICAgICBjb21wbGV0ZWx5LCBwdXNoaW5nIGFsbCBldmVudHMgdG8gdGhlIHJlZ2lzdGVyZWQKLSAgICAgKiAgICAgICAgICAgICAgICAgZG9jdW1lbnQgaGFuZGxlci4gQSB2YWx1ZSBvZiBmYWxzZSBpbmRpY2F0ZXMgdGhhdAotICAgICAqICAgICAgICAgICAgICAgICB0aGF0IHRoZSBzY2FubmVyIHNob3VsZCBvbmx5IHNjYW4gdGhlIG5leHQgcG9ydGlvbgotICAgICAqICAgICAgICAgICAgICAgICBvZiB0aGUgZG9jdW1lbnQgYW5kIHJldHVybi4gQSBzY2FubmVyIGluc3RhbmNlIGlzCi0gICAgICogICAgICAgICAgICAgICAgIHBlcm1pdHRlZCB0byBjb21wbGV0ZWx5IHNjYW4gYSBkb2N1bWVudCBpZiBpdCBkb2VzCi0gICAgICogICAgICAgICAgICAgICAgIG5vdCBzdXBwb3J0IHRoaXMgInB1bGwiIHNjYW5uaW5nIG1vZGVsLgotICAgICAqCi0gICAgICogQHJldHVybiBUcnVlIGlmIHRoZXJlIGlzIG1vcmUgdG8gc2NhbiwgZmFsc2Ugb3RoZXJ3aXNlLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIHNjYW5EVERFeHRlcm5hbFN1YnNldChib29sZWFuIGNvbXBsZXRlKQotICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIFhOSUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIFNraXAgdGhlIERURCBpZiBqYXZheC54bWwuc3RyZWFtLnN1cHBvcnREVEQgaXMgZmFsc2UuCi0gICAgICogQHBhcmFtIHN1cHBvcnREVEQgVGhlIHZhbHVlIG9mIHRoZSBwcm9wZXJ0eSBqYXZheC54bWwuc3RyZWFtLnN1cHBvcnREVEQuCi0gICAgICogQHJldHVybiB0cnVlIGlmIERURCBpcyBza2lwcGVkLCBmYWxzZSBvdGhlcndpc2UuCi0gICAgICogQHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIGlmIGkvbyBlcnJvciBvY2N1cnMKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBza2lwRFREKGJvb2xlYW4gc3VwcG9ydERURCkKLSAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uOwotCi0gICAgcHVibGljIHZvaWQgc2V0TGltaXRBbmFseXplcihYTUxMaW1pdEFuYWx5emVyIGxpbWl0QW5hbHl6ZXIpOwotfSAvLyBpbnRlcmZhY2UgWE1MRFREU2Nhbm5lcgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveG5pL3BhcnNlci9YTUxEVERTb3VyY2UuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3huaS9wYXJzZXIvWE1MRFREU291cmNlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDFmMmMzMTIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveG5pL3BhcnNlci9YTUxEVERTb3VyY2UuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQ5ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEsIDIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MRFRESGFuZGxlcjsKLQotLyoqCi0gKiBEZWZpbmVzIGEgRFREIHNvdXJjZS4gSW4gb3RoZXIgd29yZHMsIGFueSBvYmplY3QgdGhhdCBpbXBsZW1lbnRzCi0gKiB0aGlzIGludGVyZmFjZSBpcyBhYmxlIHRvIGVtaXQgRFREICJldmVudHMiIHRvIHRoZSByZWdpc3RlcmVkCi0gKiBEVEQgaGFuZGxlci4gVGhlc2UgZXZlbnRzIGNvdWxkIGJlIHByb2R1Y2VkIGJ5IHBhcnNpbmcgYW4gWE1MCi0gKiBkb2N1bWVudCdzIGludGVybmFsIG9yIGV4dGVybmFsIHN1YnNldCwgY291bGQgYmUgZ2VuZXJhdGVkIGZyb20KLSAqIHNvbWUgb3RoZXIgc291cmNlLCBvciBjb3VsZCBiZSBjcmVhdGVkIHByb2dyYW1tYXRpY2FsbHkuIFRoaXMKLSAqIGludGVyZmFjZSBkb2VzIG5vdCBzYXkgPGVtPmhvdzwvZW0+IHRoZSBldmVudHMgYXJlIGNyZWF0ZWQsIG9ubHkKLSAqIHRoYXQgdGhlIGltcGxlbWVudG9yIGlzIGFibGUgdG8gZW1pdCB0aGVtLgotICoKLSAqIEBhdXRob3IgQW5keSBDbGFyaywgSUJNCi0gKgotICovCi1wdWJsaWMgaW50ZXJmYWNlIFhNTERURFNvdXJjZSB7Ci0KLSAgICAvLwotICAgIC8vIFhNTERURFNvdXJjZSBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKiBTZXRzIHRoZSBEVEQgaGFuZGxlci4gKi8KLSAgICBwdWJsaWMgdm9pZCBzZXREVERIYW5kbGVyKFhNTERUREhhbmRsZXIgaGFuZGxlcik7Ci0KLSAgICAvKiogUmV0dXJucyB0aGUgRFREIGhhbmRsZXIuICovCi0gICAgcHVibGljIFhNTERUREhhbmRsZXIgZ2V0RFRESGFuZGxlcigpOwotCi19IC8vIGludGVyZmFjZSBYTUxEVERTb3VyY2UKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3huaS9wYXJzZXIvWE1MRG9jdW1lbnRGaWx0ZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3huaS9wYXJzZXIvWE1MRG9jdW1lbnRGaWx0ZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMWViNTVmNC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94bmkvcGFyc2VyL1hNTERvY3VtZW50RmlsdGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzNiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLCAyMDAyLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTERvY3VtZW50SGFuZGxlcjsKLQotLyoqCi0gKiBEZWZpbmVzIGEgZG9jdW1lbnQgZmlsdGVyIHRoYXQgYWN0cyBhcyBib3RoIGEgcmVjZWl2ZXIgYW5kIGFuIGVtaXR0ZXIKLSAqIG9mIGRvY3VtZW50IGV2ZW50cy4KLSAqCi0gKiBAYXV0aG9yIEFuZHkgQ2xhcmssIElCTQotICoKLSAqLwotcHVibGljIGludGVyZmFjZSBYTUxEb2N1bWVudEZpbHRlcgotICAgIGV4dGVuZHMgWE1MRG9jdW1lbnRIYW5kbGVyLCBYTUxEb2N1bWVudFNvdXJjZSB7Ci0KLQotfSAvLyBpbnRlcmZhY2UgWE1MRG9jdW1lbnRGaWx0ZXIKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3huaS9wYXJzZXIvWE1MRG9jdW1lbnRTY2FubmVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94bmkvcGFyc2VyL1hNTERvY3VtZW50U2Nhbm5lci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA5ZmE1MjQ4Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3huaS9wYXJzZXIvWE1MRG9jdW1lbnRTY2FubmVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3NSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLCAyMDAyLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlcjsKLQotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE5JRXhjZXB0aW9uOwotCi0vKioKLSAqIFRoaXMgaW50ZXJmYWNlIGRlZmluZXMgYSBnZW5lcmljIGRvY3VtZW50IHNjYW5uZXIuIFRoaXMgaW50ZXJmYWNlCi0gKiBhbGxvd3MgYSBzY2FubmVyIHRvIGJlIHVzZWQgaW50ZXJjaGFuZ2FibHkgaW4gZXhpc3RpbmcgcGFyc2VyCi0gKiBjb25maWd1cmF0aW9ucy4KLSAqIDxwPgotICogSWYgdGhlIHBhcnNlciBjb25maWd1cmF0aW9uIHVzZXMgYSBkb2N1bWVudCBzY2FubmVyIHRoYXQgaW1wbGVtZW50cwotICogdGhpcyBpbnRlcmZhY2UsIGNvbXBvbmVudHMgc2hvdWxkIGJlIGFibGUgdG8gcXVlcnkgdGhlIHNjYW5uZXIKLSAqIGluc3RhbmNlIGZyb20gdGhlIGNvbXBvbmVudCBtYW5hZ2VyIHVzaW5nIHRoZSBmb2xsb3dpbmcgcHJvcGVydHkKLSAqIGlkZW50aWZpZXI6Ci0gKiA8YmxvY2txdW90ZT4KLSAqICAiaHR0cDovL2FwYWNoZS5vcmcveG1sL3Byb3BlcnRpZXMvaW50ZXJuYWwvZG9jdW1lbnQtc2Nhbm5lciIKLSAqIDwvYmxvY2txdW90ZT4KLSAqCi0gKiBAYXV0aG9yIEFuZHkgQ2xhcmssIElCTQotICoKLSAqLwotcHVibGljIGludGVyZmFjZSBYTUxEb2N1bWVudFNjYW5uZXIKLSAgICBleHRlbmRzIFhNTERvY3VtZW50U291cmNlIHsKLQotICAgIC8vCi0gICAgLy8gWE1MRG9jdW1lbnRTY2FubmVyIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogU2V0cyB0aGUgaW5wdXQgc291cmNlLgotICAgICAqCi0gICAgICogQHBhcmFtIGlucHV0U291cmNlIFRoZSBpbnB1dCBzb3VyY2UuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIFRocm93biBvbiBpL28gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0SW5wdXRTb3VyY2UoWE1MSW5wdXRTb3VyY2UgaW5wdXRTb3VyY2UpIHRocm93cyBJT0V4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIFNjYW5zIGEgZG9jdW1lbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29tcGxldGUgVHJ1ZSBpZiB0aGUgc2Nhbm5lciBzaG91bGQgc2NhbiB0aGUgZG9jdW1lbnQKLSAgICAgKiAgICAgICAgICAgICAgICAgY29tcGxldGVseSwgcHVzaGluZyBhbGwgZXZlbnRzIHRvIHRoZSByZWdpc3RlcmVkCi0gICAgICogICAgICAgICAgICAgICAgIGRvY3VtZW50IGhhbmRsZXIuIEEgdmFsdWUgb2YgZmFsc2UgaW5kaWNhdGVzIHRoYXQKLSAgICAgKiAgICAgICAgICAgICAgICAgdGhhdCB0aGUgc2Nhbm5lciBzaG91bGQgb25seSBzY2FuIHRoZSBuZXh0IHBvcnRpb24KLSAgICAgKiAgICAgICAgICAgICAgICAgb2YgdGhlIGRvY3VtZW50IGFuZCByZXR1cm4uIEEgc2Nhbm5lciBpbnN0YW5jZSBpcwotICAgICAqICAgICAgICAgICAgICAgICBwZXJtaXR0ZWQgdG8gY29tcGxldGVseSBzY2FuIGEgZG9jdW1lbnQgaWYgaXQgZG9lcwotICAgICAqICAgICAgICAgICAgICAgICBub3Qgc3VwcG9ydCB0aGlzICJwdWxsIiBzY2FubmluZyBtb2RlbC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVHJ1ZSBpZiB0aGVyZSBpcyBtb3JlIHRvIHNjYW4sIGZhbHNlIG90aGVyd2lzZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBzY2FuRG9jdW1lbnQoYm9vbGVhbiBjb21wbGV0ZSkKLSAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBYTklFeGNlcHRpb247Ci0KLSAgICBwdWJsaWMgaW50IG5leHQoKSB0aHJvd3MgWE5JRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbjsKLX0gLy8gaW50ZXJmYWNlIFhNTERvY3VtZW50U2Nhbm5lcgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveG5pL3BhcnNlci9YTUxEb2N1bWVudFNvdXJjZS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveG5pL3BhcnNlci9YTUxEb2N1bWVudFNvdXJjZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyMTdiNTE1Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3huaS9wYXJzZXIvWE1MRG9jdW1lbnRTb3VyY2UuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQ5ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEsIDIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MRG9jdW1lbnRIYW5kbGVyOwotCi0vKioKLSAqIERlZmluZXMgYSBkb2N1bWVudCBzb3VyY2UuIEluIG90aGVyIHdvcmRzLCBhbnkgb2JqZWN0IHRoYXQgaW1wbGVtZW50cwotICogdGhpcyBpbnRlcmZhY2UgaXMgYWJsZSB0byBlbWl0IGRvY3VtZW50ICJldmVudHMiIHRvIHRoZSByZWdpc3RlcmVkCi0gKiBkb2N1bWVudCBoYW5kbGVyLiBUaGVzZSBldmVudHMgY291bGQgYmUgcHJvZHVjZWQgYnkgcGFyc2luZyBhbiBYTUwKLSAqIGRvY3VtZW50LCBjb3VsZCBiZSBnZW5lcmF0ZWQgZnJvbSBzb21lIG90aGVyIHNvdXJjZSwgb3IgY291bGQgYmUKLSAqIGNyZWF0ZWQgcHJvZ3JhbW1hdGljYWxseS4gVGhpcyBpbnRlcmZhY2UgZG9lcyBub3Qgc2F5IDxlbT5ob3c8L2VtPgotICogdGhlIGV2ZW50cyBhcmUgY3JlYXRlZCwgb25seSB0aGF0IHRoZSBpbXBsZW1lbnRvciBpcyBhYmxlIHRvIGVtaXQKLSAqIHRoZW0uCi0gKgotICogQGF1dGhvciBBbmR5IENsYXJrLCBJQk0KLSAqCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgWE1MRG9jdW1lbnRTb3VyY2UgewotCi0gICAgLy8KLSAgICAvLyBYTUxEb2N1bWVudFNvdXJjZSBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKiBTZXRzIHRoZSBkb2N1bWVudCBoYW5kbGVyLiAqLwotICAgIHB1YmxpYyB2b2lkIHNldERvY3VtZW50SGFuZGxlcihYTUxEb2N1bWVudEhhbmRsZXIgaGFuZGxlcik7Ci0KLSAgICAvKiogUmV0dXJucyB0aGUgZG9jdW1lbnQgaGFuZGxlciAqLwotICAgIHB1YmxpYyBYTUxEb2N1bWVudEhhbmRsZXIgZ2V0RG9jdW1lbnRIYW5kbGVyKCk7Ci0KLX0gLy8gaW50ZXJmYWNlIFhNTERvY3VtZW50U291cmNlCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94bmkvcGFyc2VyL1hNTEVudGl0eVJlc29sdmVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94bmkvcGFyc2VyL1hNTEVudGl0eVJlc29sdmVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGMzOTY3MWYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveG5pL3BhcnNlci9YTUxFbnRpdHlSZXNvbHZlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNjEgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMSwgMjAwMiwyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXI7Ci0KLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE5JRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTFJlc291cmNlSWRlbnRpZmllcjsKLQotLyoqCi0gKiBUaGlzIGludGVyZmFjZSBpcyB1c2VkIHRvIHJlc29sdmUgZXh0ZXJuYWwgcGFyc2VkIGVudGl0aWVzLiBUaGUKLSAqIGFwcGxpY2F0aW9uIGNhbiByZWdpc3RlciBhbiBvYmplY3QgdGhhdCBpbXBsZW1lbnRzIHRoaXMgaW50ZXJmYWNlCi0gKiB3aXRoIHRoZSBwYXJzZXIgY29uZmlndXJhdGlvbiBpbiBvcmRlciB0byBpbnRlcmNlcHQgZW50aXRpZXMgYW5kCi0gKiByZXNvbHZlIHRoZW0gZXhwbGljaXRseS4gSWYgdGhlIHJlZ2lzdGVyZWQgZW50aXR5IHJlc29sdmVyIGNhbm5vdAotICogcmVzb2x2ZSB0aGUgZW50aXR5LCBpdCBzaG91bGQgcmV0dXJuIDxjb2RlPm51bGw8L2NvZGU+IHNvIHRoYXQgdGhlCi0gKiBwYXJzZXIgd2lsbCB0cnkgdG8gcmVzb2x2ZSB0aGUgZW50aXR5IHVzaW5nIGEgZGVmYXVsdCBtZWNoYW5pc20uCi0gKgotICogQHNlZSBYTUxQYXJzZXJDb25maWd1cmF0aW9uCi0gKgotICogQGF1dGhvciBBbmR5IENsYXJrLCBJQk0KLSAqCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgWE1MRW50aXR5UmVzb2x2ZXIgewotCi0gICAgLy8KLSAgICAvLyBYTUxFbnRpdHlSZXNvbHZlciBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFJlc29sdmVzIGFuIGV4dGVybmFsIHBhcnNlZCBlbnRpdHkuIElmIHRoZSBlbnRpdHkgY2Fubm90IGJlCi0gICAgICogcmVzb2x2ZWQsIHRoaXMgbWV0aG9kIHNob3VsZCByZXR1cm4gbnVsbC4KLSAgICAgKgotICAgICAqIEBwYXJhbSByZXNvdXJjZUlkZW50aWZpZXIgbG9jYXRpb24gb2YgdGhlIFhNTCByZXNvdXJjZSB0byByZXNvbHZlCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gb24gZ2VuZXJhbCBlcnJvci4KLSAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uICBUaHJvd24gaWYgcmVzb2x2ZWQgZW50aXR5IHN0cmVhbSBjYW5ub3QgYmUKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBvcGVuZWQgb3Igc29tZSBvdGhlciBpL28gZXJyb3Igb2NjdXJzLgotICAgICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MUmVzb3VyY2VJZGVudGlmaWVyCi0gICAgICovCi0gICAgcHVibGljIFhNTElucHV0U291cmNlIHJlc29sdmVFbnRpdHkoWE1MUmVzb3VyY2VJZGVudGlmaWVyIHJlc291cmNlSWRlbnRpZmllcikKLSAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiwgSU9FeGNlcHRpb247Ci0KLX0gLy8gaW50ZXJmYWNlIFhNTEVudGl0eVJlc29sdmVyCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94bmkvcGFyc2VyL1hNTEVycm9ySGFuZGxlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveG5pL3BhcnNlci9YTUxFcnJvckhhbmRsZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNDdiNzdiYS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94bmkvcGFyc2VyL1hNTEVycm9ySGFuZGxlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTA2ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEsIDIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE5JRXhjZXB0aW9uOwotCi0vKioKLSAqIEFuIGludGVyZmFjZSBmb3IgaGFuZGxpbmcgZXJyb3JzLiBJZiB0aGUgYXBwbGljYXRpb24gaXMgaW50ZXJlc3RlZAotICogaW4gZXJyb3Igbm90aWZpY2F0aW9ucywgdGhlbiBpdCBjYW4gcmVnaXN0ZXIgYW4gZXJyb3IgaGFuZGxlciBvYmplY3QKLSAqIHRoYXQgaW1wbGVtZW50cyB0aGlzIGludGVyZmFjZSB3aXRoIHRoZSBwYXJzZXIgY29uZmlndXJhdGlvbi4KLSAqCi0gKiBAc2VlIFhNTFBhcnNlckNvbmZpZ3VyYXRpb24KLSAqCi0gKiBAYXV0aG9yIEFuZHkgQ2xhcmssIElCTQotICoKLSAqLwotcHVibGljIGludGVyZmFjZSBYTUxFcnJvckhhbmRsZXIgewotCi0gICAgLy8KLSAgICAvLyBYTUxFcnJvckhhbmRsZXIgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBSZXBvcnRzIGEgd2FybmluZy4gV2FybmluZ3MgYXJlIG5vbi1mYXRhbCBhbmQgY2FuIGJlIHNhZmVseSBpZ25vcmVkCi0gICAgICogYnkgbW9zdCBhcHBsaWNhdGlvbnMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZG9tYWluICAgIFRoZSBkb21haW4gb2YgdGhlIHdhcm5pbmcuIFRoZSBkb21haW4gY2FuIGJlIGFueQotICAgICAqICAgICAgICAgICAgICAgICAgc3RyaW5nIGJ1dCBpcyBzdWdnZXN0ZWQgdG8gYmUgYSB2YWxpZCBVUkkuIFRoZQotICAgICAqICAgICAgICAgICAgICAgICAgZG9tYWluIGNhbiBiZSB1c2VkIHRvIGNvbnZlbmllbnRseSBzcGVjaWZ5IGEgd2ViCi0gICAgICogICAgICAgICAgICAgICAgICBzaXRlIGxvY2F0aW9uIG9mIHRoZSByZWxldmVudCBzcGVjaWZpY2F0aW9uIG9yCi0gICAgICogICAgICAgICAgICAgICAgICBkb2N1bWVudCBwZXJ0YWluaW5nIHRvIHRoaXMgd2FybmluZy4KLSAgICAgKiBAcGFyYW0ga2V5ICAgICAgIFRoZSB3YXJuaW5nIGtleS4gVGhpcyBrZXkgY2FuIGJlIGFueSBzdHJpbmcgYW5kCi0gICAgICogICAgICAgICAgICAgICAgICBpcyBpbXBsZW1lbnRhdGlvbiBkZXBlbmRlbnQuCi0gICAgICogQHBhcmFtIGV4Y2VwdGlvbiBFeGNlcHRpb24uCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gdG8gc2lnbmFsIHRoYXQgdGhlIHBhcnNlciBzaG91bGQgc3RvcAotICAgICAqICAgICAgICAgICAgICAgICAgICAgIHBhcnNpbmcgdGhlIGRvY3VtZW50LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHdhcm5pbmcoU3RyaW5nIGRvbWFpbiwgU3RyaW5nIGtleSwKLSAgICAgICAgICAgICAgICAgICAgICAgIFhNTFBhcnNlRXhjZXB0aW9uIGV4Y2VwdGlvbikgdGhyb3dzIFhOSUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIFJlcG9ydHMgYW4gZXJyb3IuIEVycm9ycyBhcmUgbm9uLWZhdGFsIGFuZCB1c3VhbGx5IHNpZ25pZnkgdGhhdCB0aGUKLSAgICAgKiBkb2N1bWVudCBpcyBpbnZhbGlkIHdpdGggcmVzcGVjdCB0byBpdHMgZ3JhbW1hcihzKS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBkb21haW4gICAgVGhlIGRvbWFpbiBvZiB0aGUgZXJyb3IuIFRoZSBkb21haW4gY2FuIGJlIGFueQotICAgICAqICAgICAgICAgICAgICAgICAgc3RyaW5nIGJ1dCBpcyBzdWdnZXN0ZWQgdG8gYmUgYSB2YWxpZCBVUkkuIFRoZQotICAgICAqICAgICAgICAgICAgICAgICAgZG9tYWluIGNhbiBiZSB1c2VkIHRvIGNvbnZlbmllbnRseSBzcGVjaWZ5IGEgd2ViCi0gICAgICogICAgICAgICAgICAgICAgICBzaXRlIGxvY2F0aW9uIG9mIHRoZSByZWxldmVudCBzcGVjaWZpY2F0aW9uIG9yCi0gICAgICogICAgICAgICAgICAgICAgICBkb2N1bWVudCBwZXJ0YWluaW5nIHRvIHRoaXMgZXJyb3IuCi0gICAgICogQHBhcmFtIGtleSAgICAgICBUaGUgZXJyb3Iga2V5LiBUaGlzIGtleSBjYW4gYmUgYW55IHN0cmluZyBhbmQKLSAgICAgKiAgICAgICAgICAgICAgICAgIGlzIGltcGxlbWVudGF0aW9uIGRlcGVuZGVudC4KLSAgICAgKiBAcGFyYW0gZXhjZXB0aW9uIEV4Y2VwdGlvbi4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biB0byBzaWduYWwgdGhhdCB0aGUgcGFyc2VyIHNob3VsZCBzdG9wCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgcGFyc2luZyB0aGUgZG9jdW1lbnQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZXJyb3IoU3RyaW5nIGRvbWFpbiwgU3RyaW5nIGtleSwKLSAgICAgICAgICAgICAgICAgICAgICBYTUxQYXJzZUV4Y2VwdGlvbiBleGNlcHRpb24pIHRocm93cyBYTklFeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBSZXBvcnQgYSBmYXRhbCBlcnJvci4gRmF0YWwgZXJyb3JzIHVzdWFsbHkgb2NjdXIgd2hlbiB0aGUgZG9jdW1lbnQKLSAgICAgKiBpcyBub3Qgd2VsbC1mb3JtZWQgYW5kIHNpZ25pZmllcyB0aGF0IHRoZSBwYXJzZXIgY2Fubm90IGNvbnRpbnVlCi0gICAgICogbm9ybWFsIG9wZXJhdGlvbi4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoZSBlcnJvciBoYW5kbGVyIHNob3VsZCA8ZW0+YWx3YXlzPC9lbT4KLSAgICAgKiB0aHJvdyBhbiA8Y29kZT5YTklFeGNlcHRpb248L2NvZGU+IGZyb20gdGhpcyBtZXRob2QuIFRoaXMgZXhjZXB0aW9uCi0gICAgICogY2FuIGVpdGhlciBiZSB0aGUgc2FtZSBleGNlcHRpb24gdGhhdCBpcyBwYXNzZWQgYXMgYSBwYXJhbWV0ZXIgdG8KLSAgICAgKiB0aGUgbWV0aG9kIG9yIGEgbmV3IFhOSSBleGNlcHRpb24gb2JqZWN0LiBJZiB0aGUgcmVnaXN0ZXJlZCBlcnJvcgotICAgICAqIGhhbmRsZXIgZmFpbHMgdG8gdGhyb3cgYW4gZXhjZXB0aW9uLCB0aGUgY29udGludWluZyBvcGVyYXRpb24gb2YKLSAgICAgKiB0aGUgcGFyc2VyIGlzIHVuZGV0ZXJtaW5lZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBkb21haW4gICAgVGhlIGRvbWFpbiBvZiB0aGUgZmF0YWwgZXJyb3IuIFRoZSBkb21haW4gY2FuIGJlCi0gICAgICogICAgICAgICAgICAgICAgICBhbnkgc3RyaW5nIGJ1dCBpcyBzdWdnZXN0ZWQgdG8gYmUgYSB2YWxpZCBVUkkuIFRoZQotICAgICAqICAgICAgICAgICAgICAgICAgZG9tYWluIGNhbiBiZSB1c2VkIHRvIGNvbnZlbmllbnRseSBzcGVjaWZ5IGEgd2ViCi0gICAgICogICAgICAgICAgICAgICAgICBzaXRlIGxvY2F0aW9uIG9mIHRoZSByZWxldmVudCBzcGVjaWZpY2F0aW9uIG9yCi0gICAgICogICAgICAgICAgICAgICAgICBkb2N1bWVudCBwZXJ0YWluaW5nIHRvIHRoaXMgZmF0YWwgZXJyb3IuCi0gICAgICogQHBhcmFtIGtleSAgICAgICBUaGUgZmF0YWwgZXJyb3Iga2V5LiBUaGlzIGtleSBjYW4gYmUgYW55IHN0cmluZwotICAgICAqICAgICAgICAgICAgICAgICAgYW5kIGlzIGltcGxlbWVudGF0aW9uIGRlcGVuZGVudC4KLSAgICAgKiBAcGFyYW0gZXhjZXB0aW9uIEV4Y2VwdGlvbi4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biB0byBzaWduYWwgdGhhdCB0aGUgcGFyc2VyIHNob3VsZCBzdG9wCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgcGFyc2luZyB0aGUgZG9jdW1lbnQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZmF0YWxFcnJvcihTdHJpbmcgZG9tYWluLCBTdHJpbmcga2V5LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MUGFyc2VFeGNlcHRpb24gZXhjZXB0aW9uKSB0aHJvd3MgWE5JRXhjZXB0aW9uOwotCi19IC8vIGludGVyZmFjZSBYTUxFcnJvckhhbmRsZXIKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3huaS9wYXJzZXIvWE1MSW5wdXRTb3VyY2UuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3huaS9wYXJzZXIvWE1MSW5wdXRTb3VyY2UuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMmFlOTlhNi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94bmkvcGFyc2VyL1hNTElucHV0U291cmNlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyNTQgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMC0yMDAyLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTFJlc291cmNlSWRlbnRpZmllcjsKLQotaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5pby5SZWFkZXI7Ci0KLS8qKgotICogVGhpcyBjbGFzcyByZXByZXNlbnRzIGFuIGlucHV0IHNvdXJjZSBmb3IgYW4gWE1MIGRvY3VtZW50LiBUaGUKLSAqIGJhc2ljIHByb3BlcnRpZXMgb2YgYW4gaW5wdXQgc291cmNlIGFyZSB0aGUgZm9sbG93aW5nOgotICogPHVsPgotICogIDxsaT5wdWJsaWMgaWRlbnRpZmllcjwvbGk+Ci0gKiAgPGxpPnN5c3RlbSBpZGVudGlmaWVyPC9saT4KLSAqICA8bGk+Ynl0ZSBzdHJlYW0gb3IgY2hhcmFjdGVyIHN0cmVhbTwvbGk+Ci0gKiAgPGxpPgotICogPC91bD4KLSAqCi0gKiBAYXV0aG9yIEFuZHkgQ2xhcmssIElCTQotICoKLSAqLwotcHVibGljIGNsYXNzIFhNTElucHV0U291cmNlIHsKLQotICAgIC8vCi0gICAgLy8gRGF0YQotICAgIC8vCi0KLSAgICAvKiogUHVibGljIGlkZW50aWZpZXIuICovCi0gICAgcHJvdGVjdGVkIFN0cmluZyBmUHVibGljSWQ7Ci0KLSAgICAvKiogU3lzdGVtIGlkZW50aWZpZXIuICovCi0gICAgcHJvdGVjdGVkIFN0cmluZyBmU3lzdGVtSWQ7Ci0KLSAgICAvKiogQmFzZSBzeXN0ZW0gaWRlbnRpZmllci4gKi8KLSAgICBwcm90ZWN0ZWQgU3RyaW5nIGZCYXNlU3lzdGVtSWQ7Ci0KLSAgICAvKiogQnl0ZSBzdHJlYW0uICovCi0gICAgcHJvdGVjdGVkIElucHV0U3RyZWFtIGZCeXRlU3RyZWFtOwotCi0gICAgLyoqIENoYXJhY3RlciBzdHJlYW0uICovCi0gICAgcHJvdGVjdGVkIFJlYWRlciBmQ2hhclN0cmVhbTsKLQotICAgIC8qKiBFbmNvZGluZy4gKi8KLSAgICBwcm90ZWN0ZWQgU3RyaW5nIGZFbmNvZGluZzsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHMgYW4gaW5wdXQgc291cmNlIGZyb20ganVzdCB0aGUgcHVibGljIGFuZCBzeXN0ZW0KLSAgICAgKiBpZGVudGlmaWVycywgbGVhdmluZyByZXNvbHV0aW9uIG9mIHRoZSBlbnRpdHkgYW5kIG9wZW5pbmcgb2YKLSAgICAgKiB0aGUgaW5wdXQgc3RyZWFtIHVwIHRvIHRoZSBjYWxsZXIuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcHVibGljSWQgICAgIFRoZSBwdWJsaWMgaWRlbnRpZmllciwgaWYga25vd24uCi0gICAgICogQHBhcmFtIHN5c3RlbUlkICAgICBUaGUgc3lzdGVtIGlkZW50aWZpZXIuIFRoaXMgdmFsdWUgc2hvdWxkCi0gICAgICogICAgICAgICAgICAgICAgICAgICBhbHdheXMgYmUgc2V0LCBpZiBwb3NzaWJsZSwgYW5kIGNhbiBiZQotICAgICAqICAgICAgICAgICAgICAgICAgICAgcmVsYXRpdmUgb3IgYWJzb2x1dGUuIElmIHRoZSBzeXN0ZW0gaWRlbnRpZmllcgotICAgICAqICAgICAgICAgICAgICAgICAgICAgaXMgcmVsYXRpdmUsIHRoZW4gdGhlIGJhc2Ugc3lzdGVtIGlkZW50aWZpZXIKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgIHNob3VsZCBiZSBzZXQuCi0gICAgICogQHBhcmFtIGJhc2VTeXN0ZW1JZCBUaGUgYmFzZSBzeXN0ZW0gaWRlbnRpZmllci4gVGhpcyB2YWx1ZSBzaG91bGQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgIGFsd2F5cyBiZSBzZXQgdG8gdGhlIGZ1bGx5IGV4cGFuZGVkIFVSSSBvZiB0aGUKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgIGJhc2Ugc3lzdGVtIGlkZW50aWZpZXIsIGlmIHBvc3NpYmxlLgotICAgICAqLwotICAgIHB1YmxpYyBYTUxJbnB1dFNvdXJjZShTdHJpbmcgcHVibGljSWQsIFN0cmluZyBzeXN0ZW1JZCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGJhc2VTeXN0ZW1JZCkgewotICAgICAgICBmUHVibGljSWQgPSBwdWJsaWNJZDsKLSAgICAgICAgZlN5c3RlbUlkID0gc3lzdGVtSWQ7Ci0gICAgICAgIGZCYXNlU3lzdGVtSWQgPSBiYXNlU3lzdGVtSWQ7Ci0gICAgfSAvLyA8aW5pdD4oU3RyaW5nLFN0cmluZyxTdHJpbmcpCi0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RzIGFuIGlucHV0IHNvdXJjZSBmcm9tIGEgWE1MUmVzb3VyY2VJZGVudGlmaWVyCi0gICAgICogb2JqZWN0LCBsZWF2aW5nIHJlc29sdXRpb24gb2YgdGhlIGVudGl0eSBhbmQgb3BlbmluZyBvZgotICAgICAqIHRoZSBpbnB1dCBzdHJlYW0gdXAgdG8gdGhlIGNhbGxlci4KLSAgICAgKgotICAgICAqIEBwYXJhbSByZXNvdXJjZUlkZW50aWZpZXIgICAgdGhlIFhNTFJlc291cmNlSWRlbnRpZmllciBjb250YWluaW5nIHRoZSBpbmZvcm1hdGlvbgotICAgICAqLwotICAgIHB1YmxpYyBYTUxJbnB1dFNvdXJjZShYTUxSZXNvdXJjZUlkZW50aWZpZXIgcmVzb3VyY2VJZGVudGlmaWVyKSB7Ci0KLSAgICAgICAgZlB1YmxpY0lkID0gcmVzb3VyY2VJZGVudGlmaWVyLmdldFB1YmxpY0lkKCk7Ci0gICAgICAgIGZTeXN0ZW1JZCA9IHJlc291cmNlSWRlbnRpZmllci5nZXRMaXRlcmFsU3lzdGVtSWQoKTsKLSAgICAgICAgZkJhc2VTeXN0ZW1JZCA9IHJlc291cmNlSWRlbnRpZmllci5nZXRCYXNlU3lzdGVtSWQoKTsKLSAgICB9IC8vIDxpbml0PihYTUxSZXNvdXJjZUlkZW50aWZpZXIpCi0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RzIGFuIGlucHV0IHNvdXJjZSBmcm9tIGEgYnl0ZSBzdHJlYW0uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcHVibGljSWQgICAgIFRoZSBwdWJsaWMgaWRlbnRpZmllciwgaWYga25vd24uCi0gICAgICogQHBhcmFtIHN5c3RlbUlkICAgICBUaGUgc3lzdGVtIGlkZW50aWZpZXIuIFRoaXMgdmFsdWUgc2hvdWxkCi0gICAgICogICAgICAgICAgICAgICAgICAgICBhbHdheXMgYmUgc2V0LCBpZiBwb3NzaWJsZSwgYW5kIGNhbiBiZQotICAgICAqICAgICAgICAgICAgICAgICAgICAgcmVsYXRpdmUgb3IgYWJzb2x1dGUuIElmIHRoZSBzeXN0ZW0gaWRlbnRpZmllcgotICAgICAqICAgICAgICAgICAgICAgICAgICAgaXMgcmVsYXRpdmUsIHRoZW4gdGhlIGJhc2Ugc3lzdGVtIGlkZW50aWZpZXIKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgIHNob3VsZCBiZSBzZXQuCi0gICAgICogQHBhcmFtIGJhc2VTeXN0ZW1JZCBUaGUgYmFzZSBzeXN0ZW0gaWRlbnRpZmllci4gVGhpcyB2YWx1ZSBzaG91bGQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgIGFsd2F5cyBiZSBzZXQgdG8gdGhlIGZ1bGx5IGV4cGFuZGVkIFVSSSBvZiB0aGUKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgIGJhc2Ugc3lzdGVtIGlkZW50aWZpZXIsIGlmIHBvc3NpYmxlLgotICAgICAqIEBwYXJhbSBieXRlU3RyZWFtICAgVGhlIGJ5dGUgc3RyZWFtLgotICAgICAqIEBwYXJhbSBlbmNvZGluZyAgICAgVGhlIGVuY29kaW5nIG9mIHRoZSBieXRlIHN0cmVhbSwgaWYga25vd24uCi0gICAgICovCi0gICAgcHVibGljIFhNTElucHV0U291cmNlKFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkLAotICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgYmFzZVN5c3RlbUlkLCBJbnB1dFN0cmVhbSBieXRlU3RyZWFtLAotICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgZW5jb2RpbmcpIHsKLSAgICAgICAgZlB1YmxpY0lkID0gcHVibGljSWQ7Ci0gICAgICAgIGZTeXN0ZW1JZCA9IHN5c3RlbUlkOwotICAgICAgICBmQmFzZVN5c3RlbUlkID0gYmFzZVN5c3RlbUlkOwotICAgICAgICBmQnl0ZVN0cmVhbSA9IGJ5dGVTdHJlYW07Ci0gICAgICAgIGZFbmNvZGluZyA9IGVuY29kaW5nOwotICAgIH0gLy8gPGluaXQ+KFN0cmluZyxTdHJpbmcsU3RyaW5nLElucHV0U3RyZWFtLFN0cmluZykKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHMgYW4gaW5wdXQgc291cmNlIGZyb20gYSBjaGFyYWN0ZXIgc3RyZWFtLgotICAgICAqCi0gICAgICogQHBhcmFtIHB1YmxpY0lkICAgICBUaGUgcHVibGljIGlkZW50aWZpZXIsIGlmIGtub3duLgotICAgICAqIEBwYXJhbSBzeXN0ZW1JZCAgICAgVGhlIHN5c3RlbSBpZGVudGlmaWVyLiBUaGlzIHZhbHVlIHNob3VsZAotICAgICAqICAgICAgICAgICAgICAgICAgICAgYWx3YXlzIGJlIHNldCwgaWYgcG9zc2libGUsIGFuZCBjYW4gYmUKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgIHJlbGF0aXZlIG9yIGFic29sdXRlLiBJZiB0aGUgc3lzdGVtIGlkZW50aWZpZXIKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgIGlzIHJlbGF0aXZlLCB0aGVuIHRoZSBiYXNlIHN5c3RlbSBpZGVudGlmaWVyCi0gICAgICogICAgICAgICAgICAgICAgICAgICBzaG91bGQgYmUgc2V0LgotICAgICAqIEBwYXJhbSBiYXNlU3lzdGVtSWQgVGhlIGJhc2Ugc3lzdGVtIGlkZW50aWZpZXIuIFRoaXMgdmFsdWUgc2hvdWxkCi0gICAgICogICAgICAgICAgICAgICAgICAgICBhbHdheXMgYmUgc2V0IHRvIHRoZSBmdWxseSBleHBhbmRlZCBVUkkgb2YgdGhlCi0gICAgICogICAgICAgICAgICAgICAgICAgICBiYXNlIHN5c3RlbSBpZGVudGlmaWVyLCBpZiBwb3NzaWJsZS4KLSAgICAgKiBAcGFyYW0gY2hhclN0cmVhbSAgIFRoZSBjaGFyYWN0ZXIgc3RyZWFtLgotICAgICAqIEBwYXJhbSBlbmNvZGluZyAgICAgVGhlIG9yaWdpbmFsIGVuY29kaW5nIG9mIHRoZSBieXRlIHN0cmVhbQotICAgICAqICAgICAgICAgICAgICAgICAgICAgdXNlZCBieSB0aGUgcmVhZGVyLCBpZiBrbm93bi4KLSAgICAgKi8KLSAgICBwdWJsaWMgWE1MSW5wdXRTb3VyY2UoU3RyaW5nIHB1YmxpY0lkLCBTdHJpbmcgc3lzdGVtSWQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBiYXNlU3lzdGVtSWQsIFJlYWRlciBjaGFyU3RyZWFtLAotICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgZW5jb2RpbmcpIHsKLSAgICAgICAgZlB1YmxpY0lkID0gcHVibGljSWQ7Ci0gICAgICAgIGZTeXN0ZW1JZCA9IHN5c3RlbUlkOwotICAgICAgICBmQmFzZVN5c3RlbUlkID0gYmFzZVN5c3RlbUlkOwotICAgICAgICBmQ2hhclN0cmVhbSA9IGNoYXJTdHJlYW07Ci0gICAgICAgIGZFbmNvZGluZyA9IGVuY29kaW5nOwotICAgIH0gLy8gPGluaXQ+KFN0cmluZyxTdHJpbmcsU3RyaW5nLFJlYWRlcixTdHJpbmcpCi0KLSAgICAvLwotICAgIC8vIFB1YmxpYyBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIHB1YmxpYyBpZGVudGlmaWVyLgotICAgICAqCi0gICAgICogQHBhcmFtIHB1YmxpY0lkIFRoZSBuZXcgcHVibGljIGlkZW50aWZpZXIuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0UHVibGljSWQoU3RyaW5nIHB1YmxpY0lkKSB7Ci0gICAgICAgIGZQdWJsaWNJZCA9IHB1YmxpY0lkOwotICAgIH0gLy8gc2V0UHVibGljSWQoU3RyaW5nKQotCi0gICAgLyoqIFJldHVybnMgdGhlIHB1YmxpYyBpZGVudGlmaWVyLiAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0UHVibGljSWQoKSB7Ci0gICAgICAgIHJldHVybiBmUHVibGljSWQ7Ci0gICAgfSAvLyBnZXRQdWJsaWNJZCgpOlN0cmluZwotCi0gICAgLyoqCi0gICAgICogU2V0cyB0aGUgc3lzdGVtIGlkZW50aWZpZXIuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc3lzdGVtSWQgVGhlIG5ldyBzeXN0ZW0gaWRlbnRpZmllci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRTeXN0ZW1JZChTdHJpbmcgc3lzdGVtSWQpIHsKLSAgICAgICAgZlN5c3RlbUlkID0gc3lzdGVtSWQ7Ci0gICAgfSAvLyBzZXRTeXN0ZW1JZChTdHJpbmcpCi0KLSAgICAvKiogUmV0dXJucyB0aGUgc3lzdGVtIGlkZW50aWZpZXIuICovCi0gICAgcHVibGljIFN0cmluZyBnZXRTeXN0ZW1JZCgpIHsKLSAgICAgICAgcmV0dXJuIGZTeXN0ZW1JZDsKLSAgICB9IC8vIGdldFN5c3RlbUlkKCk6U3RyaW5nCi0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSBiYXNlIHN5c3RlbSBpZGVudGlmaWVyLgotICAgICAqCi0gICAgICogQHBhcmFtIGJhc2VTeXN0ZW1JZCBUaGUgbmV3IGJhc2Ugc3lzdGVtIGlkZW50aWZpZXIuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0QmFzZVN5c3RlbUlkKFN0cmluZyBiYXNlU3lzdGVtSWQpIHsKLSAgICAgICAgZkJhc2VTeXN0ZW1JZCA9IGJhc2VTeXN0ZW1JZDsKLSAgICB9IC8vIHNldEJhc2VTeXN0ZW1JZChTdHJpbmcpCi0KLSAgICAvKiogUmV0dXJucyB0aGUgYmFzZSBzeXN0ZW0gaWRlbnRpZmllci4gKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEJhc2VTeXN0ZW1JZCgpIHsKLSAgICAgICAgcmV0dXJuIGZCYXNlU3lzdGVtSWQ7Ci0gICAgfSAvLyBnZXRCYXNlU3lzdGVtSWQoKTpTdHJpbmcKLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIGJ5dGUgc3RyZWFtLiBJZiB0aGUgYnl0ZSBzdHJlYW0gaXMgbm90IGFscmVhZHkgb3BlbmVkCi0gICAgICogd2hlbiB0aGlzIG9iamVjdCBpcyBpbnN0YW50aWF0ZWQsIHRoZW4gdGhlIGNvZGUgdGhhdCBvcGVucyB0aGUKLSAgICAgKiBzdHJlYW0gc2hvdWxkIGFsc28gc2V0IHRoZSBieXRlIHN0cmVhbSBvbiB0aGlzIG9iamVjdC4gQWxzbywgaWYKLSAgICAgKiB0aGUgZW5jb2RpbmcgaXMgYXV0by1kZXRlY3RlZCwgdGhlbiB0aGUgZW5jb2Rpbmcgc2hvdWxkIGFsc28gYmUKLSAgICAgKiBzZXQgb24gdGhpcyBvYmplY3QuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYnl0ZVN0cmVhbSBUaGUgbmV3IGJ5dGUgc3RyZWFtLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEJ5dGVTdHJlYW0oSW5wdXRTdHJlYW0gYnl0ZVN0cmVhbSkgewotICAgICAgICBmQnl0ZVN0cmVhbSA9IGJ5dGVTdHJlYW07Ci0gICAgfSAvLyBzZXRCeXRlU3RyZWFtKElucHV0U291cmNlKQotCi0gICAgLyoqIFJldHVybnMgdGhlIGJ5dGUgc3RyZWFtLiAqLwotICAgIHB1YmxpYyBJbnB1dFN0cmVhbSBnZXRCeXRlU3RyZWFtKCkgewotICAgICAgICByZXR1cm4gZkJ5dGVTdHJlYW07Ci0gICAgfSAvLyBnZXRCeXRlU3RyZWFtKCk6SW5wdXRTdHJlYW0KLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIGNoYXJhY3RlciBzdHJlYW0uIElmIHRoZSBjaGFyYWN0ZXIgc3RyZWFtIGlzIG5vdCBhbHJlYWR5Ci0gICAgICogb3BlbmVkIHdoZW4gdGhpcyBvYmplY3QgaXMgaW5zdGFudGlhdGVkLCB0aGVuIHRoZSBjb2RlIHRoYXQgb3BlbnMKLSAgICAgKiB0aGUgc3RyZWFtIHNob3VsZCBhbHNvIHNldCB0aGUgY2hhcmFjdGVyIHN0cmVhbSBvbiB0aGlzIG9iamVjdC4KLSAgICAgKiBBbHNvLCB0aGUgZW5jb2Rpbmcgb2YgdGhlIGJ5dGUgc3RyZWFtIHVzZWQgYnkgdGhlIHJlYWRlciBzaG91bGQKLSAgICAgKiBhbHNvIGJlIHNldCBvbiB0aGlzIG9iamVjdCwgaWYga25vd24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY2hhclN0cmVhbSBUaGUgbmV3IGNoYXJhY3RlciBzdHJlYW0uCi0gICAgICoKLSAgICAgKiBAc2VlICNzZXRFbmNvZGluZwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldENoYXJhY3RlclN0cmVhbShSZWFkZXIgY2hhclN0cmVhbSkgewotICAgICAgICBmQ2hhclN0cmVhbSA9IGNoYXJTdHJlYW07Ci0gICAgfSAvLyBzZXRDaGFyYWN0ZXJTdHJlYW0oUmVhZGVyKQotCi0gICAgLyoqIFJldHVybnMgdGhlIGNoYXJhY3RlciBzdHJlYW0uICovCi0gICAgcHVibGljIFJlYWRlciBnZXRDaGFyYWN0ZXJTdHJlYW0oKSB7Ci0gICAgICAgIHJldHVybiBmQ2hhclN0cmVhbTsKLSAgICB9IC8vIGdldENoYXJhY3RlclN0cmVhbSgpOlJlYWRlcgotCi0gICAgLyoqCi0gICAgICogU2V0cyB0aGUgZW5jb2Rpbmcgb2YgdGhlIHN0cmVhbS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlbmNvZGluZyBUaGUgbmV3IGVuY29kaW5nLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEVuY29kaW5nKFN0cmluZyBlbmNvZGluZykgewotICAgICAgICBmRW5jb2RpbmcgPSBlbmNvZGluZzsKLSAgICB9IC8vIHNldEVuY29kaW5nKFN0cmluZykKLQotICAgIC8qKiBSZXR1cm5zIHRoZSBlbmNvZGluZyBvZiB0aGUgc3RyZWFtLCBvciBudWxsIGlmIG5vdCBrbm93bi4gKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEVuY29kaW5nKCkgewotICAgICAgICByZXR1cm4gZkVuY29kaW5nOwotICAgIH0gLy8gZ2V0RW5jb2RpbmcoKTpTdHJpbmcKLQotfSAvLyBjbGFzcyBYTUxJbnB1dFNvdXJjZQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveG5pL3BhcnNlci9YTUxQYXJzZUV4Y2VwdGlvbi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveG5pL3BhcnNlci9YTUxQYXJzZUV4Y2VwdGlvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxYWJiOWFjLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3huaS9wYXJzZXIvWE1MUGFyc2VFeGNlcHRpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE4MSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLCAyMDAyLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTExvY2F0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE5JRXhjZXB0aW9uOwotCi0vKioKLSAqIEEgcGFyc2luZyBleGNlcHRpb24uIFRoaXMgZXhjZXB0aW9uIGlzIGRpZmZlcmVudCBmcm9tIHRoZSBzdGFuZGFyZAotICogWE5JIGV4Y2VwdGlvbiBpbiB0aGF0IGl0IHN0b3JlcyB0aGUgbG9jYXRpb24gaW4gdGhlIGRvY3VtZW50IChvcgotICogaXRzIGVudGl0aWVzKSB3aGVyZSB0aGUgZXhjZXB0aW9uIG9jY3VycmVkLgotICoKLSAqIEBhdXRob3IgQW5keSBDbGFyaywgSUJNCi0gKgotICovCi1wdWJsaWMgY2xhc3MgWE1MUGFyc2VFeGNlcHRpb24KLSAgICBleHRlbmRzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAvKiogU2VyaWFsaXphdGlvbiB2ZXJzaW9uLiAqLwotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxNzMyOTU5MzU5NDQ4NTQ5OTY3TDsKLQotICAgIC8vCi0gICAgLy8gRGF0YQotICAgIC8vCi0KLSAgICAvKiogUHVibGljIGlkZW50aWZpZXIuICovCi0gICAgcHJvdGVjdGVkIFN0cmluZyBmUHVibGljSWQ7Ci0KLSAgICAvKiogbGl0ZXJhbCBTeXN0ZW0gaWRlbnRpZmllci4gKi8KLSAgICBwcm90ZWN0ZWQgU3RyaW5nIGZMaXRlcmFsU3lzdGVtSWQ7Ci0KLSAgICAvKiogZXhwYW5kZWQgU3lzdGVtIGlkZW50aWZpZXIuICovCi0gICAgcHJvdGVjdGVkIFN0cmluZyBmRXhwYW5kZWRTeXN0ZW1JZDsKLQotICAgIC8qKiBCYXNlIHN5c3RlbSBpZGVudGlmaWVyLiAqLwotICAgIHByb3RlY3RlZCBTdHJpbmcgZkJhc2VTeXN0ZW1JZDsKLQotICAgIC8qKiBMaW5lIG51bWJlci4gKi8KLSAgICBwcm90ZWN0ZWQgaW50IGZMaW5lTnVtYmVyID0gLTE7Ci0KLSAgICAvKiogQ29sdW1uIG51bWJlci4gKi8KLSAgICBwcm90ZWN0ZWQgaW50IGZDb2x1bW5OdW1iZXIgPSAtMTsKLQotICAgIC8qKiBDaGFyYWN0ZXIgb2Zmc2V0LiAqLwotICAgIHByb3RlY3RlZCBpbnQgZkNoYXJhY3Rlck9mZnNldCA9IC0xOwotCi0gICAgLy8KLSAgICAvLyBDb25zdHJ1Y3RvcnMKLSAgICAvLwotCi0gICAgLyoqIENvbnN0cnVjdHMgYSBwYXJzZSBleGNlcHRpb24uICovCi0gICAgcHVibGljIFhNTFBhcnNlRXhjZXB0aW9uKFhNTExvY2F0b3IgbG9jYXRvciwgU3RyaW5nIG1lc3NhZ2UpIHsKLSAgICAgICAgc3VwZXIobWVzc2FnZSk7Ci0gICAgICAgIGlmIChsb2NhdG9yICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZQdWJsaWNJZCA9IGxvY2F0b3IuZ2V0UHVibGljSWQoKTsKLSAgICAgICAgICAgIGZMaXRlcmFsU3lzdGVtSWQgPSBsb2NhdG9yLmdldExpdGVyYWxTeXN0ZW1JZCgpOwotICAgICAgICAgICAgZkV4cGFuZGVkU3lzdGVtSWQgPSBsb2NhdG9yLmdldEV4cGFuZGVkU3lzdGVtSWQoKTsKLSAgICAgICAgICAgIGZCYXNlU3lzdGVtSWQgPSBsb2NhdG9yLmdldEJhc2VTeXN0ZW1JZCgpOwotICAgICAgICAgICAgZkxpbmVOdW1iZXIgPSBsb2NhdG9yLmdldExpbmVOdW1iZXIoKTsKLSAgICAgICAgICAgIGZDb2x1bW5OdW1iZXIgPSBsb2NhdG9yLmdldENvbHVtbk51bWJlcigpOwotICAgICAgICAgICAgZkNoYXJhY3Rlck9mZnNldCA9IGxvY2F0b3IuZ2V0Q2hhcmFjdGVyT2Zmc2V0KCk7Ci0gICAgICAgIH0KLSAgICB9IC8vIDxpbml0PihYTUxMb2NhdG9yLFN0cmluZykKLQotICAgIC8qKiBDb25zdHJ1Y3RzIGEgcGFyc2UgZXhjZXB0aW9uLiAqLwotICAgIHB1YmxpYyBYTUxQYXJzZUV4Y2VwdGlvbihYTUxMb2NhdG9yIGxvY2F0b3IsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBtZXNzYWdlLCBFeGNlcHRpb24gZXhjZXB0aW9uKSB7Ci0gICAgICAgIHN1cGVyKG1lc3NhZ2UsIGV4Y2VwdGlvbik7Ci0gICAgICAgIGlmIChsb2NhdG9yICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZQdWJsaWNJZCA9IGxvY2F0b3IuZ2V0UHVibGljSWQoKTsKLSAgICAgICAgICAgIGZMaXRlcmFsU3lzdGVtSWQgPSBsb2NhdG9yLmdldExpdGVyYWxTeXN0ZW1JZCgpOwotICAgICAgICAgICAgZkV4cGFuZGVkU3lzdGVtSWQgPSBsb2NhdG9yLmdldEV4cGFuZGVkU3lzdGVtSWQoKTsKLSAgICAgICAgICAgIGZCYXNlU3lzdGVtSWQgPSBsb2NhdG9yLmdldEJhc2VTeXN0ZW1JZCgpOwotICAgICAgICAgICAgZkxpbmVOdW1iZXIgPSBsb2NhdG9yLmdldExpbmVOdW1iZXIoKTsKLSAgICAgICAgICAgIGZDb2x1bW5OdW1iZXIgPSBsb2NhdG9yLmdldENvbHVtbk51bWJlcigpOwotICAgICAgICAgICAgZkNoYXJhY3Rlck9mZnNldCA9IGxvY2F0b3IuZ2V0Q2hhcmFjdGVyT2Zmc2V0KCk7Ci0gICAgICAgIH0KLSAgICB9IC8vIDxpbml0PihYTUxMb2NhdG9yLFN0cmluZyxFeGNlcHRpb24pCi0KLSAgICAvLwotICAgIC8vIFB1YmxpYyBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKiBSZXR1cm5zIHRoZSBwdWJsaWMgaWRlbnRpZmllci4gKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFB1YmxpY0lkKCkgewotICAgICAgICByZXR1cm4gZlB1YmxpY0lkOwotICAgIH0gLy8gZ2V0UHVibGljSWQoKTpTdHJpbmcKLQotICAgIC8qKiBSZXR1cm5zIHRoZSBleHBhbmRlZCBzeXN0ZW0gaWRlbnRpZmllci4gKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEV4cGFuZGVkU3lzdGVtSWQoKSB7Ci0gICAgICAgIHJldHVybiBmRXhwYW5kZWRTeXN0ZW1JZDsKLSAgICB9IC8vIGdldEV4cGFuZGVkU3lzdGVtSWQoKTpTdHJpbmcKLQotICAgIC8qKiBSZXR1cm5zIHRoZSBsaXRlcmFsIHN5c3RlbSBpZGVudGlmaWVyLiAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TGl0ZXJhbFN5c3RlbUlkKCkgewotICAgICAgICByZXR1cm4gZkxpdGVyYWxTeXN0ZW1JZDsKLSAgICB9IC8vIGdldExpdGVyYWxTeXN0ZW1JZCgpOlN0cmluZwotCi0gICAgLyoqIFJldHVybnMgdGhlIGJhc2Ugc3lzdGVtIGlkZW50aWZpZXIuICovCi0gICAgcHVibGljIFN0cmluZyBnZXRCYXNlU3lzdGVtSWQoKSB7Ci0gICAgICAgIHJldHVybiBmQmFzZVN5c3RlbUlkOwotICAgIH0gLy8gZ2V0QmFzZVN5c3RlbUlkKCk6U3RyaW5nCi0KLSAgICAvKiogUmV0dXJucyB0aGUgbGluZSBudW1iZXIuICovCi0gICAgcHVibGljIGludCBnZXRMaW5lTnVtYmVyKCkgewotICAgICAgICByZXR1cm4gZkxpbmVOdW1iZXI7Ci0gICAgfSAvLyBnZXRMaW5lTnVtYmVyKCk6aW50Ci0KLSAgICAvKiogUmV0dXJucyB0aGUgcm93IG51bWJlci4gKi8KLSAgICBwdWJsaWMgaW50IGdldENvbHVtbk51bWJlcigpIHsKLSAgICAgICAgcmV0dXJuIGZDb2x1bW5OdW1iZXI7Ci0gICAgfSAvLyBnZXRSb3dOdW1iZXIoKTppbnQKLQotICAgIC8qKiBSZXR1cm5zIHRoZSBjaGFyYWN0ZXIgb2Zmc2V0LiAqLwotICAgIHB1YmxpYyBpbnQgZ2V0Q2hhcmFjdGVyT2Zmc2V0KCkgewotICAgICAgICByZXR1cm4gZkNoYXJhY3Rlck9mZnNldDsKLSAgICB9IC8vIGdldENoYXJhY3Rlck9mZnNldCgpOmludAotCi0gICAgLy8KLSAgICAvLyBPYmplY3QgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKiogUmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIG9iamVjdC4gKi8KLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotCi0gICAgICAgIFN0cmluZ0J1ZmZlciBzdHIgPSBuZXcgU3RyaW5nQnVmZmVyKCk7Ci0gICAgICAgIGlmIChmUHVibGljSWQgIT0gbnVsbCkgewotICAgICAgICAgICAgc3RyLmFwcGVuZChmUHVibGljSWQpOwotICAgICAgICB9Ci0gICAgICAgIHN0ci5hcHBlbmQoJzonKTsKLSAgICAgICAgaWYgKGZMaXRlcmFsU3lzdGVtSWQgIT0gbnVsbCkgewotICAgICAgICAgICAgc3RyLmFwcGVuZChmTGl0ZXJhbFN5c3RlbUlkKTsKLSAgICAgICAgfQotICAgICAgICBzdHIuYXBwZW5kKCc6Jyk7Ci0gICAgICAgIGlmIChmRXhwYW5kZWRTeXN0ZW1JZCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBzdHIuYXBwZW5kKGZFeHBhbmRlZFN5c3RlbUlkKTsKLSAgICAgICAgfQotICAgICAgICBzdHIuYXBwZW5kKCc6Jyk7Ci0gICAgICAgIGlmIChmQmFzZVN5c3RlbUlkICE9IG51bGwpIHsKLSAgICAgICAgICAgIHN0ci5hcHBlbmQoZkJhc2VTeXN0ZW1JZCk7Ci0gICAgICAgIH0KLSAgICAgICAgc3RyLmFwcGVuZCgnOicpOwotICAgICAgICBzdHIuYXBwZW5kKGZMaW5lTnVtYmVyKTsKLSAgICAgICAgc3RyLmFwcGVuZCgnOicpOwotICAgICAgICBzdHIuYXBwZW5kKGZDb2x1bW5OdW1iZXIpOwotICAgICAgICBzdHIuYXBwZW5kKCc6Jyk7Ci0gICAgICAgIHN0ci5hcHBlbmQoZkNoYXJhY3Rlck9mZnNldCk7Ci0gICAgICAgIHN0ci5hcHBlbmQoJzonKTsKLSAgICAgICAgU3RyaW5nIG1lc3NhZ2UgPSBnZXRNZXNzYWdlKCk7Ci0gICAgICAgIGlmIChtZXNzYWdlID09IG51bGwpIHsKLSAgICAgICAgICAgIEV4Y2VwdGlvbiBleGNlcHRpb24gPSBnZXRFeGNlcHRpb24oKTsKLSAgICAgICAgICAgIGlmIChleGNlcHRpb24gIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBleGNlcHRpb24uZ2V0TWVzc2FnZSgpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGlmIChtZXNzYWdlICE9IG51bGwpIHsKLSAgICAgICAgICAgIHN0ci5hcHBlbmQobWVzc2FnZSk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHN0ci50b1N0cmluZygpOwotCi0gICAgfSAvLyB0b1N0cmluZygpOlN0cmluZwotCi19IC8vIFhNTFBhcnNlRXhjZXB0aW9uCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94bmkvcGFyc2VyL1hNTFBhcnNlckNvbmZpZ3VyYXRpb24uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3huaS9wYXJzZXIvWE1MUGFyc2VyQ29uZmlndXJhdGlvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiNDI3MTJlLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3huaS9wYXJzZXIvWE1MUGFyc2VyQ29uZmlndXJhdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjUzICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEsIDIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyOwotCi1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MRG9jdW1lbnRIYW5kbGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTERUREhhbmRsZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MRFREQ29udGVudE1vZGVsSGFuZGxlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTklFeGNlcHRpb247Ci0KLS8qKgotICogUmVwcmVzZW50cyBhIHBhcnNlciBjb25maWd1cmF0aW9uLiBUaGUgcGFyc2VyIGNvbmZpZ3VyYXRpb24gbWFpbnRhaW5zCi0gKiBhIHRhYmxlIG9mIHJlY29nbml6ZWQgZmVhdHVyZXMgYW5kIHByb3BlcnRpZXMsIGFzc2VtYmxlcyBjb21wb25lbnRzCi0gKiBmb3IgdGhlIHBhcnNpbmcgcGlwZWxpbmUsIGFuZCBpcyByZXNwb25zaWJsZSBmb3IgaW5pdGlhdGluZyBwYXJzaW5nCi0gKiBvZiBhbiBYTUwgZG9jdW1lbnQuCi0gKiA8cD4KLSAqIEJ5IHNlcGFyYXRpbmcgdGhlIGNvbmZpZ3VyYXRpb24gb2YgYSBwYXJzZXIgZnJvbSB0aGUgc3BlY2lmaWMgcGFyc2VyCi0gKiBpbnN0YW5jZSwgYXBwbGljYXRpb25zIGNhbiBjcmVhdGUgbmV3IGNvbmZpZ3VyYXRpb25zIGFuZCByZS11c2UgdGhlCi0gKiBleGlzdGluZyBwYXJzZXIgY29tcG9uZW50cyBhbmQgZXh0ZXJuYWwgQVBJIGdlbmVyYXRvcnMgKGUuZy4gdGhlCi0gKiBET01QYXJzZXIgYW5kIFNBWFBhcnNlcikuCi0gKiA8cD4KLSAqIFRoZSBpbnRlcm5hbHMgb2YgYW55IHNwZWNpZmljIHBhcnNlciBjb25maWd1cmF0aW9uIGluc3RhbmNlIGFyZSBoaWRkZW4uCi0gKiBUaGVyZWZvcmUsIGVhY2ggY29uZmlndXJhdGlvbiBtYXkgaW1wbGVtZW50IHRoZSBwYXJzaW5nIG1lY2hhbmlzbSBhbnkKLSAqIHdheSBuZWNlc3NhcnkuIEhvd2V2ZXIsIHRoZSBwYXJzZXIgY29uZmlndXJhdGlvbiBzaG91bGQgZm9sbG93IHRoZXNlCi0gKiBndWlkZWxpbmVzOgotICogPHVsPgotICogIDxsaT4KLSAqICAgQ2FsbCB0aGUgPGNvZGU+cmVzZXQ8L2NvZGU+IG1ldGhvZCBvbiBlYWNoIGNvbXBvbmVudCBiZWZvcmUgcGFyc2luZy4KLSAqICAgVGhpcyBpcyBvbmx5IHJlcXVpcmVkIGlmIHRoZSBjb25maWd1cmF0aW9uIGlzIHJlLXVzaW5nIGV4aXN0aW5nCi0gKiAgIGNvbXBvbmVudHMgdGhhdCBjb25mb3JtIHRvIHRoZSA8Y29kZT5YTUxDb21wb25lbnQ8L2NvZGU+IGludGVyZmFjZS4KLSAqICAgSWYgdGhlIGNvbmZpZ3VyYXRpb24gdXNlcyBhbGwgY3VzdG9tIHBhcnRzLCB0aGVuIGl0IGlzIGZyZWUgdG8KLSAqICAgaW1wbGVtZW50IGV2ZXJ5dGhpbmcgYXMgaXQgc2VlcyBmaXQgYXMgbG9uZyBhcyBpdCBmb2xsb3dzIHRoZQotICogICBvdGhlciBndWlkZWxpbmVzLgotICogIDwvbGk+Ci0gKiAgPGxpPgotICogICBDYWxsIHRoZSA8Y29kZT5zZXRGZWF0dXJlPC9jb2RlPiBhbmQgPGNvZGU+c2V0UHJvcGVydHk8L2NvZGU+IG1ldGhvZAotICogICBvbiBlYWNoIGNvbXBvbmVudCBkdXJpbmcgcGFyc2luZyB0byBwcm9wYWdhdGUgZmVhdHVyZXMgYW5kIHByb3BlcnRpZXMKLSAqICAgdGhhdCBoYXZlIGNoYW5nZWQuIFRoaXMgaXMgb25seSByZXF1aXJlZCBpZiB0aGUgY29uZmlndXJhdGlvbiBpcwotICogICByZS11c2luZyBleGlzdGluZyBjb21wb25lbnRzIHRoYXQgY29uZm9ybSB0byB0aGUgPGNvZGU+WE1MQ29tcG9uZW50PC9jb2RlPgotICogICBpbnRlcmZhY2UuIElmIHRoZSBjb25maWd1cmF0aW9uIHVzZXMgYWxsIGN1c3RvbSBwYXJ0cywgdGhlbiBpdCBpcyBmcmVlCi0gKiAgIHRvIGltcGxlbWVudCBldmVyeXRoaW5nIGFzIGl0IHNlZXMgZml0IGFzIGxvbmcgYXMgaXQgZm9sbG93cyB0aGUgb3RoZXIKLSAqICAgZ3VpZGVsaW5lcy4KLSAqICA8L2xpPgotICogIDxsaT4KLSAqICAgUGFzcyB0aGUgc2FtZSB1bmlxdWUgU3RyaW5nIHJlZmVyZW5jZXMgZm9yIGFsbCBzeW1ib2xzIHRoYXQgYXJlCi0gKiAgIHByb3BhZ2F0ZWQgdG8gdGhlIHJlZ2lzdGVyZWQgaGFuZGxlcnMuIFN5bWJvbHMgaW5jbHVkZSwgYnV0IG1heSBub3QKLSAqICAgYmUgbGltaXRlZCB0bywgdGhlIG5hbWVzIG9mIGVsZW1lbnRzIGFuZCBhdHRyaWJ1dGVzIChpbmNsdWRpbmcgdGhlaXIKLSAqICAgdXJpLCBwcmVmaXgsIGFuZCBsb2NhbHBhcnQpLiBUaGlzIGlzIHN1Z2dlc3RlZCBidXQgbm90IGFuIGFic29sdXRlCi0gKiAgIG11c3QuIEhvd2V2ZXIsIHRoZSBzdGFuZGFyZCBwYXJzZXIgY29tcG9uZW50cyBtYXkgcmVxdWlyZSBhY2Nlc3MgdG8KLSAqICAgdGhlIHNhbWUgc3ltYm9sIHRhYmxlIGZvciBjcmVhdGlvbiBvZiB1bmlxdWUgc3ltYm9sIHJlZmVyZW5jZXMgdG8gYmUKLSAqICAgcHJvcGFnYXRlZCBpbiB0aGUgWE5JIHBpcGVsaW5lLgotICogIDwvbGk+Ci0gKiA8L3VsPgotICoKLSAqIEBhdXRob3IgQXJuYXVkICBMZSBIb3JzLCBJQk0KLSAqIEBhdXRob3IgQW5keSBDbGFyaywgSUJNCi0gKgotICovCi1wdWJsaWMgaW50ZXJmYWNlIFhNTFBhcnNlckNvbmZpZ3VyYXRpb24KLSAgICBleHRlbmRzIFhNTENvbXBvbmVudE1hbmFnZXIgewotCi0gICAgLy8KLSAgICAvLyBYTUxQYXJzZXJDb25maWd1cmF0aW9uIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLy8gcGFyc2luZwotCi0gICAgLyoqCi0gICAgICogUGFyc2UgYW4gWE1MIGRvY3VtZW50LgotICAgICAqIDxwPgotICAgICAqIFRoZSBwYXJzZXIgY2FuIHVzZSB0aGlzIG1ldGhvZCB0byBpbnN0cnVjdCB0aGlzIGNvbmZpZ3VyYXRpb24KLSAgICAgKiB0byBiZWdpbiBwYXJzaW5nIGFuIFhNTCBkb2N1bWVudCBmcm9tIGFueSB2YWxpZCBpbnB1dCBzb3VyY2UKLSAgICAgKiAoYSBjaGFyYWN0ZXIgc3RyZWFtLCBhIGJ5dGUgc3RyZWFtLCBvciBhIFVSSSkuCi0gICAgICogPHA+Ci0gICAgICogUGFyc2VycyBtYXkgbm90IGludm9rZSB0aGlzIG1ldGhvZCB3aGlsZSBhIHBhcnNlIGlzIGluIHByb2dyZXNzLgotICAgICAqIE9uY2UgYSBwYXJzZSBpcyBjb21wbGV0ZSwgdGhlIHBhcnNlciBtYXkgdGhlbiBwYXJzZSBhbm90aGVyIFhNTAotICAgICAqIGRvY3VtZW50LgotICAgICAqIDxwPgotICAgICAqIFRoaXMgbWV0aG9kIGlzIHN5bmNocm9ub3VzOiBpdCB3aWxsIG5vdCByZXR1cm4gdW50aWwgcGFyc2luZwotICAgICAqIGhhcyBlbmRlZC4gIElmIGEgY2xpZW50IGFwcGxpY2F0aW9uIHdhbnRzIHRvIHRlcm1pbmF0ZQotICAgICAqIHBhcnNpbmcgZWFybHksIGl0IHNob3VsZCB0aHJvdyBhbiBleGNlcHRpb24uCi0gICAgICogPHA+Ci0gICAgICogV2hlbiB0aGlzIG1ldGhvZCByZXR1cm5zLCBhbGwgY2hhcmFjdGVycyBzdHJlYW1zIGFuZCBieXRlIHN0cmVhbXMKLSAgICAgKiBvcGVuZWQgYnkgdGhlIHBhcnNlciBhcmUgY2xvc2VkLgotICAgICAqCi0gICAgICogQHBhcmFtIGlucHV0U291cmNlIFRoZSBpbnB1dCBzb3VyY2UgZm9yIHRoZSB0b3AtbGV2ZWwgb2YgdGhlCi0gICAgICogICAgICAgICAgICAgICAgICAgIFhNTCBkb2N1bWVudC4KLSAgICAgKgotICAgICAqIEBleGNlcHRpb24gWE5JRXhjZXB0aW9uIEFueSBYTkkgZXhjZXB0aW9uLCBwb3NzaWJseSB3cmFwcGluZwotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIGFub3RoZXIgZXhjZXB0aW9uLgotICAgICAqIEBleGNlcHRpb24gSU9FeGNlcHRpb24gIEFuIElPIGV4Y2VwdGlvbiBmcm9tIHRoZSBwYXJzZXIsIHBvc3NpYmx5Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgZnJvbSBhIGJ5dGUgc3RyZWFtIG9yIGNoYXJhY3RlciBzdHJlYW0KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBzdXBwbGllZCBieSB0aGUgcGFyc2VyLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHBhcnNlKFhNTElucHV0U291cmNlIGlucHV0U291cmNlKQotICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbjsKLQotICAgIC8vIGdlbmVyaWMgY29uZmlndXJhdGlvbgotCi0gICAgLyoqCi0gICAgICogQWxsb3dzIGEgcGFyc2VyIHRvIGFkZCBwYXJzZXIgc3BlY2lmaWMgZmVhdHVyZXMgdG8gYmUgcmVjb2duaXplZAotICAgICAqIGFuZCBtYW5hZ2VkIGJ5IHRoZSBwYXJzZXIgY29uZmlndXJhdGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBmZWF0dXJlSWRzIEFuIGFycmF5IG9mIHRoZSBhZGRpdGlvbmFsIGZlYXR1cmUgaWRlbnRpZmllcnMKLSAgICAgKiAgICAgICAgICAgICAgICAgICB0byBiZSByZWNvZ25pemVkLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGFkZFJlY29nbml6ZWRGZWF0dXJlcyhTdHJpbmdbXSBmZWF0dXJlSWRzKTsKLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIHN0YXRlIG9mIGEgZmVhdHVyZS4gVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBwYXJzZXIKLSAgICAgKiBhbmQgZ2V0cyBwcm9wYWdhdGVkIHRvIGNvbXBvbmVudHMgaW4gdGhpcyBwYXJzZXIgY29uZmlndXJhdGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBmZWF0dXJlSWQgVGhlIGZlYXR1cmUgaWRlbnRpZmllci4KLSAgICAgKiBAcGFyYW0gc3RhdGUgICAgIFRoZSBzdGF0ZSBvZiB0aGUgZmVhdHVyZS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBUaHJvd24gaWYgdGhlcmUgaXMgYSBjb25maWd1cmF0aW9uCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEZlYXR1cmUoU3RyaW5nIGZlYXR1cmVJZCwgYm9vbGVhbiBzdGF0ZSkKLSAgICAgICAgdGhyb3dzIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBzdGF0ZSBvZiBhIGZlYXR1cmUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZmVhdHVyZUlkIFRoZSBmZWF0dXJlIGlkZW50aWZpZXIuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gVGhyb3duIGlmIHRoZXJlIGlzIGEgY29uZmlndXJhdGlvbgotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXRGZWF0dXJlKFN0cmluZyBmZWF0dXJlSWQpCi0gICAgICAgIHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogQWxsb3dzIGEgcGFyc2VyIHRvIGFkZCBwYXJzZXIgc3BlY2lmaWMgcHJvcGVydGllcyB0byBiZSByZWNvZ25pemVkCi0gICAgICogYW5kIG1hbmFnZWQgYnkgdGhlIHBhcnNlciBjb25maWd1cmF0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIHByb3BlcnR5SWRzIEFuIGFycmF5IG9mIHRoZSBhZGRpdGlvbmFsIHByb3BlcnR5IGlkZW50aWZpZXJzCi0gICAgICogICAgICAgICAgICAgICAgICAgIHRvIGJlIHJlY29nbml6ZWQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgYWRkUmVjb2duaXplZFByb3BlcnRpZXMoU3RyaW5nW10gcHJvcGVydHlJZHMpOwotCi0gICAgLyoqCi0gICAgICogU2V0cyB0aGUgdmFsdWUgb2YgYSBwcm9wZXJ0eS4gVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBwYXJzZXIKLSAgICAgKiBhbmQgZ2V0cyBwcm9wYWdhdGVkIHRvIGNvbXBvbmVudHMgaW4gdGhpcyBwYXJzZXIgY29uZmlndXJhdGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBwcm9wZXJ0eUlkIFRoZSBwcm9wZXJ0eSBpZGVudGlmaWVyLgotICAgICAqIEBwYXJhbSB2YWx1ZSAgICAgIFRoZSB2YWx1ZSBvZiB0aGUgcHJvcGVydHkuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gVGhyb3duIGlmIHRoZXJlIGlzIGEgY29uZmlndXJhdGlvbgotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRQcm9wZXJ0eShTdHJpbmcgcHJvcGVydHlJZCwgT2JqZWN0IHZhbHVlKQotICAgICAgICB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIGEgcHJvcGVydHkuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcHJvcGVydHlJZCBUaGUgcHJvcGVydHkgaWRlbnRpZmllci4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBUaHJvd24gaWYgdGhlcmUgaXMgYSBjb25maWd1cmF0aW9uCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyBPYmplY3QgZ2V0UHJvcGVydHkoU3RyaW5nIHByb3BlcnR5SWQpCi0gICAgICAgIHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uOwotCi0gICAgLy8gaGFuZGxlcnMKLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIGVycm9yIGhhbmRsZXIuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZXJyb3JIYW5kbGVyIFRoZSBlcnJvciByZXNvbHZlci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRFcnJvckhhbmRsZXIoWE1MRXJyb3JIYW5kbGVyIGVycm9ySGFuZGxlcik7Ci0KLSAgICAvKiogUmV0dXJucyB0aGUgcmVnaXN0ZXJlZCBlcnJvciBoYW5kbGVyLiAqLwotICAgIHB1YmxpYyBYTUxFcnJvckhhbmRsZXIgZ2V0RXJyb3JIYW5kbGVyKCk7Ci0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSBkb2N1bWVudCBoYW5kbGVyIHRvIHJlY2VpdmUgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGRvY3VtZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIGRvY3VtZW50SGFuZGxlciBUaGUgZG9jdW1lbnQgaGFuZGxlci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXREb2N1bWVudEhhbmRsZXIoWE1MRG9jdW1lbnRIYW5kbGVyIGRvY3VtZW50SGFuZGxlcik7Ci0KLSAgICAvKiogUmV0dXJucyB0aGUgcmVnaXN0ZXJlZCBkb2N1bWVudCBoYW5kbGVyLiAqLwotICAgIHB1YmxpYyBYTUxEb2N1bWVudEhhbmRsZXIgZ2V0RG9jdW1lbnRIYW5kbGVyKCk7Ci0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSBEVEQgaGFuZGxlci4KLSAgICAgKgotICAgICAqIEBwYXJhbSBkdGRIYW5kbGVyIFRoZSBEVEQgaGFuZGxlci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXREVERIYW5kbGVyKFhNTERUREhhbmRsZXIgZHRkSGFuZGxlcik7Ci0KLSAgICAvKiogUmV0dXJucyB0aGUgcmVnaXN0ZXJlZCBEVEQgaGFuZGxlci4gKi8KLSAgICBwdWJsaWMgWE1MRFRESGFuZGxlciBnZXREVERIYW5kbGVyKCk7Ci0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSBEVEQgY29udGVudCBtb2RlbCBoYW5kbGVyLgotICAgICAqCi0gICAgICogQHBhcmFtIGR0ZENvbnRlbnRNb2RlbEhhbmRsZXIgVGhlIERURCBjb250ZW50IG1vZGVsIGhhbmRsZXIuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RFREQ29udGVudE1vZGVsSGFuZGxlcihYTUxEVERDb250ZW50TW9kZWxIYW5kbGVyIGR0ZENvbnRlbnRNb2RlbEhhbmRsZXIpOwotCi0gICAgLyoqIFJldHVybnMgdGhlIHJlZ2lzdGVyZWQgRFREIGNvbnRlbnQgbW9kZWwgaGFuZGxlci4gKi8KLSAgICBwdWJsaWMgWE1MRFREQ29udGVudE1vZGVsSGFuZGxlciBnZXREVERDb250ZW50TW9kZWxIYW5kbGVyKCk7Ci0KLSAgICAvLyBvdGhlciBzZXR0aW5ncwotCi0gICAgLyoqCi0gICAgICogU2V0cyB0aGUgZW50aXR5IHJlc29sdmVyLgotICAgICAqCi0gICAgICogQHBhcmFtIGVudGl0eVJlc29sdmVyIFRoZSBuZXcgZW50aXR5IHJlc29sdmVyLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEVudGl0eVJlc29sdmVyKFhNTEVudGl0eVJlc29sdmVyIGVudGl0eVJlc29sdmVyKTsKLQotICAgIC8qKiBSZXR1cm5zIHRoZSByZWdpc3RlcmVkIGVudGl0eSByZXNvbHZlci4gKi8KLSAgICBwdWJsaWMgWE1MRW50aXR5UmVzb2x2ZXIgZ2V0RW50aXR5UmVzb2x2ZXIoKTsKLQotICAgIC8qKgotICAgICAqIFNldCB0aGUgbG9jYWxlIHRvIHVzZSBmb3IgbWVzc2FnZXMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbG9jYWxlIFRoZSBsb2NhbGUgb2JqZWN0IHRvIHVzZSBmb3IgbG9jYWxpemF0aW9uIG9mIG1lc3NhZ2VzLgotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBYTklFeGNlcHRpb24gVGhyb3duIGlmIHRoZSBwYXJzZXIgZG9lcyBub3Qgc3VwcG9ydCB0aGUKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBzcGVjaWZpZWQgbG9jYWxlLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldExvY2FsZShMb2NhbGUgbG9jYWxlKSB0aHJvd3MgWE5JRXhjZXB0aW9uOwotCi0gICAgLyoqIFJldHVybnMgdGhlIGxvY2FsZS4gKi8KLSAgICBwdWJsaWMgTG9jYWxlIGdldExvY2FsZSgpOwotCi19IC8vIGludGVyZmFjZSBYTUxQYXJzZXJDb25maWd1cmF0aW9uCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94bmkvcGFyc2VyL1hNTFB1bGxQYXJzZXJDb25maWd1cmF0aW9uLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94bmkvcGFyc2VyL1hNTFB1bGxQYXJzZXJDb25maWd1cmF0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGYzZGIwYTMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveG5pL3BhcnNlci9YTUxQdWxsUGFyc2VyQ29uZmlndXJhdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTcgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMSwgMjAwMiwyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXI7Ci0KLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE5JRXhjZXB0aW9uOwotCi0vKioKLSAqIFJlcHJlc2VudHMgYSBwYXJzZXIgY29uZmlndXJhdGlvbiB0aGF0IGNhbiBiZSB1c2VkIGFzIHRoZQotICogY29uZmlndXJhdGlvbiBmb3IgYSAicHVsbCIgcGFyc2VyLiBBIHB1bGwgcGFyc2VyIGFsbG93cyB0aGUKLSAqIGFwcGxpY2F0aW9uIHRvIGRyaXZlIHRoZSBwYXJzZXIgaW5zdGVhZCBvZiBoYXZpbmcgZG9jdW1lbnQKLSAqIGluZm9ybWF0aW9uIGV2ZW50cyAicHVzaGVkIiB0byB0aGUgcmVnaXN0ZXJlZCBoYW5kbGVycy4KLSAqIDxwPgotICogQSBwdWxsIHBhcnNlciB1c2luZyB0aGlzIHR5cGUgb2YgY29uZmlndXJhdGlvbiBmaXJzdCBjYWxscwotICogdGhlIDxjb2RlPnNldElucHV0U291cmNlPC9jb2RlPiBtZXRob2QuIEFmdGVyIHRoZSBpbnB1dAotICogc291cmNlIGlzIHNldCwgdGhlIHB1bGwgcGFyc2VyIHJlcGVhdGVkbHkgY2FsbHMgdGhlCi0gKiA8Y29kZT5wYXJzZShib29sZWFuKTpib29sZWFuPC9jb2RlPiBtZXRob2QuIFRoaXMgbWV0aG9kCi0gKiByZXR1cm5zIGEgdmFsdWUgb2YgdHJ1ZSBpZiB0aGVyZSBpcyBtb3JlIHRvIHBhcnNlIGluIHRoZQotICogZG9jdW1lbnQuCi0gKiA8cD4KLSAqIENhbGxpbmcgdGhlIDxjb2RlPnBhcnNlKFhNTElucHV0U291cmNlKTwvY29kZT4gaXMgZXF1aXZhbGVudAotICogdG8gc2V0dGluZyB0aGUgaW5wdXQgc291cmNlIGFuZCBjYWxsaW5nIHRoZQotICogPGNvZGU+cGFyc2UoYm9vbGVhbik6Ym9vbGVhbjwvY29kZT4gbWV0aG9kIHdpdGggYSAiY29tcGxldGUiCi0gKiB2YWx1ZSBvZiA8Y29kZT50cnVlPC9jb2RlPi4KLSAqCi0gKiBAYXV0aG9yIEFuZHkgQ2xhcmssIElCTQotICoKLSAqLwotcHVibGljIGludGVyZmFjZSBYTUxQdWxsUGFyc2VyQ29uZmlndXJhdGlvbgotICAgIGV4dGVuZHMgWE1MUGFyc2VyQ29uZmlndXJhdGlvbiB7Ci0KLSAgICAvLwotICAgIC8vIFhNTFB1bGxQYXJzZXJDb25maWd1cmF0aW9uIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLy8gcGFyc2luZwotCi0gICAgLyoqCi0gICAgICogU2V0cyB0aGUgaW5wdXQgc291cmNlIGZvciB0aGUgZG9jdW1lbnQgdG8gcGFyc2UuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaW5wdXRTb3VyY2UgVGhlIGRvY3VtZW50J3MgaW5wdXQgc291cmNlLgotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIFRocm93biBpZiB0aGVyZSBpcyBhCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICBjb25maWd1cmF0aW9uIGVycm9yIHdoZW4gaW5pdGlhbGl6aW5nIHRoZQotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2VyLgotICAgICAqIEBleGNlcHRpb24gSU9FeGNlcHRpb24gVGhyb3duIG9uIEkvTyBlcnJvci4KLSAgICAgKgotICAgICAqIEBzZWUgI3BhcnNlKGJvb2xlYW4pCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0SW5wdXRTb3VyY2UoWE1MSW5wdXRTb3VyY2UgaW5wdXRTb3VyY2UpCi0gICAgICAgIHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIFBhcnNlcyB0aGUgZG9jdW1lbnQgaW4gYSBwdWxsIHBhcnNpbmcgZmFzaGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjb21wbGV0ZSBUcnVlIGlmIHRoZSBwdWxsIHBhcnNlciBzaG91bGQgcGFyc2UgdGhlCi0gICAgICogICAgICAgICAgICAgICAgIHJlbWFpbmluZyBkb2N1bWVudCBjb21wbGV0ZWx5LgotICAgICAqCi0gICAgICogQHJldHVybiBUcnVlIGlmIHRoZXJlIGlzIG1vcmUgZG9jdW1lbnQgdG8gcGFyc2UuCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIFhOSUV4Y2VwdGlvbiBBbnkgWE5JIGV4Y2VwdGlvbiwgcG9zc2libHkgd3JhcHBpbmcKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICAgKiBAZXhjZXB0aW9uIElPRXhjZXB0aW9uICBBbiBJTyBleGNlcHRpb24gZnJvbSB0aGUgcGFyc2VyLCBwb3NzaWJseQotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIGZyb20gYSBieXRlIHN0cmVhbSBvciBjaGFyYWN0ZXIgc3RyZWFtCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgc3VwcGxpZWQgYnkgdGhlIHBhcnNlci4KLSAgICAgKgotICAgICAqIEBzZWUgI3NldElucHV0U291cmNlCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gcGFyc2UoYm9vbGVhbiBjb21wbGV0ZSkgdGhyb3dzIFhOSUV4Y2VwdGlvbiwgSU9FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBJZiB0aGUgYXBwbGljYXRpb24gZGVjaWRlcyB0byB0ZXJtaW5hdGUgcGFyc2luZyBiZWZvcmUgdGhlIHhtbCBkb2N1bWVudAotICAgICAqIGlzIGZ1bGx5IHBhcnNlZCwgdGhlIGFwcGxpY2F0aW9uIHNob3VsZCBjYWxsIHRoaXMgbWV0aG9kIHRvIGZyZWUgYW55Ci0gICAgICogcmVzb3VyY2UgYWxsb2NhdGVkIGR1cmluZyBwYXJzaW5nLiBGb3IgZXhhbXBsZSwgY2xvc2UgYWxsIG9wZW5lZCBzdHJlYW1zLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGNsZWFudXAoKTsKLQotfSAvLyBpbnRlcmZhY2UgWE1MUHVsbFBhcnNlckNvbmZpZ3VyYXRpb24KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3hwb2ludGVyL0VsZW1lbnRTY2hlbWVQb2ludGVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94cG9pbnRlci9FbGVtZW50U2NoZW1lUG9pbnRlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1NDE1Yzk4Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3hwb2ludGVyL0VsZW1lbnRTY2hlbWVQb2ludGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4NzkgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHBvaW50ZXI7Ci0KLWltcG9ydCBqYXZhLnV0aWwuSGFzaHRhYmxlOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLlhNTEVycm9yUmVwb3J0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlN5bWJvbFRhYmxlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5YTUxDaGFyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLkF1Z21lbnRhdGlvbnM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuUU5hbWU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MQXR0cmlidXRlczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTklFeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTEVycm9ySGFuZGxlcjsKLQotLyoqCi0gKiA8cD4KLSAqIEltcGxlbWVudHMgdGhlIFhQb2ludGVyUGFydCBpbnRlcmZhY2UgZm9yIGVsZW1lbnQoKSBzY2hlbWUgc3BlY2lmaWMgcHJvY2Vzc2luZy4KLSAqIDwvcD4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICogQHZlcnNpb24gJElkOiBFbGVtZW50U2NoZW1lUG9pbnRlci5qYXZhLHYgMS40IDIwMDkvMDYvMTEgMjM6NTE6NTAgam9laHcgRXhwICQKLSAqCi0gKi8KLWNsYXNzIEVsZW1lbnRTY2hlbWVQb2ludGVyIGltcGxlbWVudHMgWFBvaW50ZXJQYXJ0IHsKLQotICAgIC8vIEZpZWxkcwotCi0gICAgLy8gVGhlIFNjaGVtZSBOYW1lIGkuZSBlbGVtZW50Ci0gICAgcHJpdmF0ZSBTdHJpbmcgZlNjaGVtZU5hbWU7Ci0KLSAgICAvLyBUaGUgc2NoZW1lIERhdGEKLSAgICBwcml2YXRlIFN0cmluZyBmU2NoZW1lRGF0YTsKLQotICAgIC8vIFRoZSBzY2hlbWUgRGF0YSAmIGNoaWxkIHNlcXVlbmNlCi0gICAgcHJpdmF0ZSBTdHJpbmcgZlNob3J0SGFuZFBvaW50ZXJOYW1lOwotCi0gICAgLy8gU2hvdWxkIHdlIGF0dGVtcHQgdG8gcmVzb2x2ZSB0aGUgQ2hpbGRTZXF1ZW5jZSBmcm9tIHRoZQotICAgIC8vIGN1cnJlbnQgZWxlbWVudCBwb3NpdGlvbi4gSWYgYSBTaG9ydEhhbmQgUG9pbnRlciBpcyBwcmVzZW50Ci0gICAgLy8gYXR0ZW1wdCB0byByZXNvbHZlIHJlbGF0aXZlIHRvIHRoZSBzaG9ydCBoYW5kIHBvaW50ZXIuCi0gICAgcHJpdmF0ZSBib29sZWFuIGZJc1Jlc29sdmVFbGVtZW50ID0gZmFsc2U7Ci0KLSAgICAvLyBIYXMgdGhlIGVsZW1lbnQgYmVlbiBmb3VuZAotICAgIHByaXZhdGUgYm9vbGVhbiBmSXNFbGVtZW50Rm91bmQgPSBmYWxzZTsKLQotICAgIC8vIFdhcyBvbmx5IGFuIGVtcHR5IGVsZW1lbnQgZm91bmQKLSAgICBwcml2YXRlIGJvb2xlYW4gZldhc09ubHlFbXB0eUVsZW1lbnRGb3VuZCA9IGZhbHNlOwotCi0gICAgLy8gSWYgYSBzaG9ydGhhbmQgcG9pbnRlciBpcyBwcmVzZW50IGFuZCByZXNvbHZlZAotICAgIGJvb2xlYW4gZklzU2hvcnRIYW5kID0gZmFsc2U7Ci0KLSAgICAvLyBUaGUgZGVwdGggYXQgd2hpY2ggdGhlIGVsZW1lbnQgd2FzIGZvdW5kCi0gICAgaW50IGZGb3VuZERlcHRoID0gMDsKLQotICAgIC8vIFRoZSBYUG9pbnRlciBlbGVtZW50IGNoaWxkIHNlcXVlbmNlCi0gICAgcHJpdmF0ZSBpbnQgZkNoaWxkU2VxdWVuY2VbXTsKLQotICAgIC8vIFRoZSBjdXJyZW50IGNoaWxkIHBvc2l0aW9uCi0gICAgcHJpdmF0ZSBpbnQgZkN1cnJlbnRDaGlsZFBvc2l0aW9uID0gMTsKLQotICAgIC8vIFRoZSBjdXJyZW50IGNoaWxkIGRlcHRoCi0gICAgcHJpdmF0ZSBpbnQgZkN1cnJlbnRDaGlsZERlcHRoID0gMDsKLQotICAgIC8vIFRoZSBjdXJyZW50IGVsZW1lbnQncyBjaGlsZCBzZXF1ZW5jZQotICAgIHByaXZhdGUgaW50IGZDdXJyZW50Q2hpbGRTZXF1ZW5jZVtdOzsKLQotICAgIC8vIFN0b3JlcyBpZiB0aGUgRnJhZ21lbnQgd2FzIHJlc29sdmVkIGJ5IHRoZSBwb2ludGVyCi0gICAgcHJpdmF0ZSBib29sZWFuIGZJc0ZyYWdtZW50UmVzb2x2ZWQgPSBmYWxzZTsKLQotICAgIC8vIFN0b3JlcyBpZiB0aGUgRnJhZ21lbnQgd2FzIHJlc29sdmVkIGJ5IHRoZSBwb2ludGVyCi0gICAgcHJpdmF0ZSBTaG9ydEhhbmRQb2ludGVyIGZTaG9ydEhhbmRQb2ludGVyOwotCi0gICAgLy8gVGhlIFhQb2ludGVyIEVycm9yIHJlcG9ydGVyCi0gICAgcHJvdGVjdGVkIFhNTEVycm9yUmVwb3J0ZXIgZkVycm9yUmVwb3J0ZXI7Ci0KLSAgICAvLyBUaGUgWFBvaW50ZXIgRXJyb3IgSGFuZGxlcgotICAgIHByb3RlY3RlZCBYTUxFcnJvckhhbmRsZXIgZkVycm9ySGFuZGxlcjsKLQotICAgIC8vCi0gICAgcHJpdmF0ZSBTeW1ib2xUYWJsZSBmU3ltYm9sVGFibGU7Ci0KLSAgICAvLyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLSAgICAvLyBDb25zdHJ1Y3RvcnMKLSAgICAvLyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLSAgICBwdWJsaWMgRWxlbWVudFNjaGVtZVBvaW50ZXIoKSB7Ci0gICAgfQotCi0gICAgcHVibGljIEVsZW1lbnRTY2hlbWVQb2ludGVyKFN5bWJvbFRhYmxlIHN5bWJvbFRhYmxlKSB7Ci0gICAgICAgIGZTeW1ib2xUYWJsZSA9IHN5bWJvbFRhYmxlOwotICAgIH0KLQotICAgIHB1YmxpYyBFbGVtZW50U2NoZW1lUG9pbnRlcihTeW1ib2xUYWJsZSBzeW1ib2xUYWJsZSwKLSAgICAgICAgICAgIFhNTEVycm9yUmVwb3J0ZXIgZXJyb3JSZXBvcnRlcikgewotICAgICAgICBmU3ltYm9sVGFibGUgPSBzeW1ib2xUYWJsZTsKLSAgICAgICAgZkVycm9yUmVwb3J0ZXIgPSBlcnJvclJlcG9ydGVyOwotICAgIH0KLQotICAgIC8vICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgotICAgIC8vIFhQb2ludGVyUGFydCBpbXBsZW1lbnRhdGlvbgotICAgIC8vICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgotCi0gICAgLyoqCi0gICAgICogUGFyc2VzIHRoZSBYUG9pbnRlciBleHByZXNzaW9uIGFuZCB0b2tlbml6ZXMgaXQgaW50byBTdHJpbmdzCi0gICAgICogZGVsaW1pdGVkIGJ5IHdoaXRlc3BhY2UuCi0gICAgICoKLSAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHBvaW50ZXIuWFBvaW50ZXJQcm9jZXNzb3IjcGFyc2VYUG9pbnRlcihqYXZhLmxhbmcuU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHBhcnNlWFBvaW50ZXIoU3RyaW5nIHhwb2ludGVyKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLQotICAgICAgICAvLwotICAgICAgICBpbml0KCk7Ci0KLSAgICAgICAgLy8gdG9rZW5zCi0gICAgICAgIGZpbmFsIFRva2VucyB0b2tlbnMgPSBuZXcgVG9rZW5zKGZTeW1ib2xUYWJsZSk7Ci0KLSAgICAgICAgLy8gc2Nhbm5lcgotICAgICAgICBTY2FubmVyIHNjYW5uZXIgPSBuZXcgU2Nhbm5lcihmU3ltYm9sVGFibGUpIHsKLSAgICAgICAgICAgIHByb3RlY3RlZCB2b2lkIGFkZFRva2VuKFRva2VucyB0b2tlbnMsIGludCB0b2tlbikKLSAgICAgICAgICAgICAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICAgICAgaWYgKHRva2VuID09IFRva2Vucy5YUFRSVE9LRU5fRUxFTV9DSElMRAotICAgICAgICAgICAgICAgICAgICAgICAgfHwgdG9rZW4gPT0gVG9rZW5zLlhQVFJUT0tFTl9FTEVNX05DTkFNRSkgewotICAgICAgICAgICAgICAgICAgICBzdXBlci5hZGRUb2tlbih0b2tlbnMsIHRva2VuKTsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICByZXBvcnRFcnJvcigiSW52YWxpZEVsZW1lbnRTY2hlbWVUb2tlbiIsIG5ldyBPYmplY3RbXSB7IHRva2VucwotICAgICAgICAgICAgICAgICAgICAgICAgLmdldFRva2VuU3RyaW5nKHRva2VuKSB9KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfTsKLQotICAgICAgICAvLyBzY2FuIHRoZSBlbGVtZW50KCkgWFBvaW50ZXIgZXhwcmVzc2lvbgotICAgICAgICBpbnQgbGVuZ3RoID0geHBvaW50ZXIubGVuZ3RoKCk7Ci0gICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IHNjYW5uZXIuc2NhbkV4cHIoZlN5bWJvbFRhYmxlLCB0b2tlbnMsIHhwb2ludGVyLCAwLAotICAgICAgICAgICAgICAgIGxlbmd0aCk7Ci0KLSAgICAgICAgaWYgKCFzdWNjZXNzKSB7Ci0gICAgICAgICAgICByZXBvcnRFcnJvcigiSW52YWxpZEVsZW1lbnRTY2hlbWVYUG9pbnRlciIsCi0gICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7IHhwb2ludGVyIH0pOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gSW5pdGlhbGl6ZSBhIHRlbXAgYXJyYXlzIHRvIHRoZSBzaXplIG9mIHRva2VuIGNvdW50IHdoaWNoIHNob3VsZAotICAgICAgICAvLyBiZSBhdGxlYXN0IHR3aWNlIHRoZSBzaXplIG9mIGNoaWxkIHNlcXVlbmNlLCB0byBob2xkIHRoZSBDaGlsZFNlcXVlbmNlLgotICAgICAgICBpbnQgdG1wQ2hpbGRTZXF1ZW5jZVtdID0gbmV3IGludFt0b2tlbnMuZ2V0VG9rZW5Db3VudCgpIC8gMiArIDFdOwotCi0gICAgICAgIC8vIHRoZSBlbGVtZW50IGRlcHRoCi0gICAgICAgIGludCBpID0gMDsKLQotICAgICAgICAvLyBUcmF2ZXJzZSB0aGUgc2Nhbm5lZCB0b2tlbnMKLSAgICAgICAgd2hpbGUgKHRva2Vucy5oYXNNb3JlKCkpIHsKLSAgICAgICAgICAgIGludCB0b2tlbiA9IHRva2Vucy5uZXh0VG9rZW4oKTsKLQotICAgICAgICAgICAgc3dpdGNoICh0b2tlbikgewotICAgICAgICAgICAgY2FzZSBUb2tlbnMuWFBUUlRPS0VOX0VMRU1fTkNOQU1FOiB7Ci0gICAgICAgICAgICAgICAgLy8gTm90ZTogIE9ubHkgYSBzaW5nbGUgU2hvcnRIYW5kIHBvaW50ZXIgY2FuIGJlIHByZXNlbnQKLQotICAgICAgICAgICAgICAgIC8vIFRoZSBzaG9ydEhhbmQgbmFtZQotICAgICAgICAgICAgICAgIHRva2VuID0gdG9rZW5zLm5leHRUb2tlbigpOwotICAgICAgICAgICAgICAgIGZTaG9ydEhhbmRQb2ludGVyTmFtZSA9IHRva2Vucy5nZXRUb2tlblN0cmluZyh0b2tlbik7Ci0KLSAgICAgICAgICAgICAgICAvLyBDcmVhdGUgYSBuZXcgU2hvcnRIYW5kUG9pbnRlcgotICAgICAgICAgICAgICAgIGZTaG9ydEhhbmRQb2ludGVyID0gbmV3IFNob3J0SGFuZFBvaW50ZXIoZlN5bWJvbFRhYmxlKTsKLSAgICAgICAgICAgICAgICBmU2hvcnRIYW5kUG9pbnRlci5zZXRTY2hlbWVOYW1lKGZTaG9ydEhhbmRQb2ludGVyTmFtZSk7Ci0KLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhc2UgVG9rZW5zLlhQVFJUT0tFTl9FTEVNX0NISUxEOiB7Ci0gICAgICAgICAgICAgICAgdG1wQ2hpbGRTZXF1ZW5jZVtpXSA9IHRva2Vucy5uZXh0VG9rZW4oKTsKLSAgICAgICAgICAgICAgICBpKys7Ci0KLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGRlZmF1bHQ6Ci0gICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoIkludmFsaWRFbGVtZW50U2NoZW1lWFBvaW50ZXIiLAotICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgeHBvaW50ZXIgfSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBJbml0aWFsaXplIHRoZSBhcnJheXMgdG8gdGhlIG51bWJlciBvZiBlbGVtZW50cyBpbiB0aGUgQ2hpbGRTZXF1ZW5jZS4KLSAgICAgICAgZkNoaWxkU2VxdWVuY2UgPSBuZXcgaW50W2ldOwotICAgICAgICBmQ3VycmVudENoaWxkU2VxdWVuY2UgPSBuZXcgaW50W2ldOwotICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHRtcENoaWxkU2VxdWVuY2UsIDAsIGZDaGlsZFNlcXVlbmNlLCAwLCBpKTsKLQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIHNjaGVtZSBuYW1lIGkuZSBlbGVtZW50Ci0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhwb2ludGVyLlhQb2ludGVyUGFydCNnZXRTY2hlbWVOYW1lKCkKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFNjaGVtZU5hbWUoKSB7Ci0gICAgICAgIHJldHVybiBmU2NoZW1lTmFtZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBzY2hlbWUgZGF0YQotICAgICAqCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhwb2ludGVyLlhQb2ludGVyUGFydCNnZXRTY2hlbWVEYXRhKCkKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFNjaGVtZURhdGEoKSB7Ci0gICAgICAgIHJldHVybiBmU2NoZW1lRGF0YTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSBzY2hlbWUgbmFtZQotICAgICAqCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhwb2ludGVyLlhQb2ludGVyUGFydCNzZXRTY2hlbWVOYW1lKGphdmEubGFuZy5TdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0U2NoZW1lTmFtZShTdHJpbmcgc2NoZW1lTmFtZSkgewotICAgICAgICBmU2NoZW1lTmFtZSA9IHNjaGVtZU5hbWU7Ci0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSBzY2hlbWUgZGF0YQotICAgICAqCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhwb2ludGVyLlhQb2ludGVyUGFydCNzZXRTY2hlbWVEYXRhKGphdmEubGFuZy5TdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0U2NoZW1lRGF0YShTdHJpbmcgc2NoZW1lRGF0YSkgewotICAgICAgICBmU2NoZW1lRGF0YSA9IHNjaGVtZURhdGE7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmVzcG9uc2libGUgZm9yIHJlc29sdmluZyB0aGUgZWxlbWVudCgpIHNjaGVtZSBYUG9pbnRlci4gIElmIGEgU2hvcnRIYW5kCi0gICAgICogUG9pbnRlciBpcyBwcmVzZW50IGFuZCBpdCBpcyBzdWNjZXNzZnVsbHkgcmVzb2x2ZWQgYW5kIGlmIGEgY2hpbGQKLSAgICAgKiBzZXF1ZW5jZSBpcyBwcmVzZW50LCB0aGUgY2hpbGQgc2VxdWVuY2UgaXMgcmVzb2x2ZWQgcmVsYXRpdmUgdG8gaXQuCi0gICAgICoKLSAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHBvaW50ZXIuWFBvaW50ZXJQcm9jZXNzb3IjcmVzb2x2ZVhQb2ludGVyKGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlFOYW1lLCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxBdHRyaWJ1dGVzLCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5BdWdtZW50YXRpb25zLCBpbnQgZXZlbnQpCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gcmVzb2x2ZVhQb2ludGVyKFFOYW1lIGVsZW1lbnQsIFhNTEF0dHJpYnV0ZXMgYXR0cmlidXRlcywKLSAgICAgICAgICAgIEF1Z21lbnRhdGlvbnMgYXVncywgaW50IGV2ZW50KSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLQotICAgICAgICBib29sZWFuIGlzU2hvcnRIYW5kUG9pbnRlclJlc29sdmVkID0gZmFsc2U7Ci0KLSAgICAgICAgLy8gaWYgYSBDaGlsZFNlcXVlbmNlIGV4aXNpdHMsIHJlc29sdmUgY2hpbGQgZWxlbWVudHMKLQotICAgICAgICAvLyBpZiBhbiBlbGVtZW50IG5hbWUgZXhpc3RzCi0gICAgICAgIGlmIChmU2hvcnRIYW5kUG9pbnRlck5hbWUgIT0gbnVsbCkgewotICAgICAgICAgICAgLy8gcmVzb2x2ZSBTaG9ydEhhbmQgUG9pbnRlcgotICAgICAgICAgICAgaXNTaG9ydEhhbmRQb2ludGVyUmVzb2x2ZWQgPSBmU2hvcnRIYW5kUG9pbnRlci5yZXNvbHZlWFBvaW50ZXIoCi0gICAgICAgICAgICAgICAgICAgIGVsZW1lbnQsIGF0dHJpYnV0ZXMsIGF1Z3MsIGV2ZW50KTsKLSAgICAgICAgICAgIGlmIChpc1Nob3J0SGFuZFBvaW50ZXJSZXNvbHZlZCkgewotICAgICAgICAgICAgICAgIGZJc1Jlc29sdmVFbGVtZW50ID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICBmSXNTaG9ydEhhbmQgPSB0cnVlOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBmSXNSZXNvbHZlRWxlbWVudCA9IGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgZklzUmVzb2x2ZUVsZW1lbnQgPSB0cnVlOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gQWRkZWQgaGVyZSB0byBza2lwIHRoZSBTaG9ydEhhbmQgcG9pbnRlciBjb3JyZXNwb25kaW5nIHRvCi0gICAgICAgIC8vIGFuIGVsZW1lbnQgaWYgb25lIGV4aXNpdHMgYW5kIHN0YXJ0IHNlYXJjaGluZyBmcm9tIGl0cyBjaGlsZAotICAgICAgICBpZiAoZkNoaWxkU2VxdWVuY2UubGVuZ3RoID4gMCkgewotICAgICAgICAgICAgZklzRnJhZ21lbnRSZXNvbHZlZCA9IG1hdGNoQ2hpbGRTZXF1ZW5jZShlbGVtZW50LCBldmVudCk7Ci0gICAgICAgIH0gZWxzZSBpZiAoaXNTaG9ydEhhbmRQb2ludGVyUmVzb2x2ZWQgJiYgZkNoaWxkU2VxdWVuY2UubGVuZ3RoIDw9IDApIHsKLSAgICAgICAgICAgIC8vIGlmIG9ubHkgYSByZXNvbHZlZCBzaG9ydGhhbmQgcG9pbnRlciBleGlzdHMKLSAgICAgICAgICAgIGZJc0ZyYWdtZW50UmVzb2x2ZWQgPSBpc1Nob3J0SGFuZFBvaW50ZXJSZXNvbHZlZDsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIGZJc0ZyYWdtZW50UmVzb2x2ZWQgPSBmYWxzZTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBmSXNGcmFnbWVudFJlc29sdmVkOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIE1hdGNoZXMgdGhlIGN1cnJlbnQgZWxlbWVudCBwb3NpdGlvbiBpbiB0aGUgZG9jdW1lbnQgdHJlZSB3aXRoIHRoZQotICAgICAqIGVsZW1lbnQgcG9zaXRpb24gc3BlY2lmaWVkIGluIHRoZSBlbGVtZW50IFhQb2ludGVyIHNjaGVtZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBldmVudAotICAgICAqIEByZXR1cm4gYm9vbGVhbiAtIHRydWUgaWYgdGhlIGN1cnJlbnQgZWxlbWVudCBwb3NpdGlvbiBpbiB0aGUgZG9jdW1lbnQKLSAgICAgKiB0cmVlIG1hdGNoZXMgdGhlZWxlbWVudCBwb3NpdGlvbiBzcGVjaWZpZWQgaW4gdGhlIGVsZW1lbnQgWFBvaW50ZXIKLSAgICAgKiBzY2hlbWUuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gbWF0Y2hDaGlsZFNlcXVlbmNlKFFOYW1lIGVsZW1lbnQsIGludCBldmVudCkKLSAgICAgICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotCi0gICAgICAgIC8vIG5lZWQgdG8gcmVzaXplIGZDdXJyZW50Q2hpbGRTZXF1ZW5jZQotICAgICAgICBpZiAoZkN1cnJlbnRDaGlsZERlcHRoID49IGZDdXJyZW50Q2hpbGRTZXF1ZW5jZS5sZW5ndGgpIHsKLSAgICAgICAgICAgIGludCB0bXBDdXJyZW50Q2hpbGRTZXF1ZW5jZVtdID0gbmV3IGludFtmQ3VycmVudENoaWxkU2VxdWVuY2UubGVuZ3RoXTsKLSAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZkN1cnJlbnRDaGlsZFNlcXVlbmNlLCAwLCB0bXBDdXJyZW50Q2hpbGRTZXF1ZW5jZSwKLSAgICAgICAgICAgICAgICAgICAgMCwgZkN1cnJlbnRDaGlsZFNlcXVlbmNlLmxlbmd0aCk7Ci0KLSAgICAgICAgICAgIC8vIEluY3JlYXNlIHRoZSBzaXplIGJ5IGEgZmFjdG9yIG9mIDIgKD8pCi0gICAgICAgICAgICBmQ3VycmVudENoaWxkU2VxdWVuY2UgPSBuZXcgaW50W2ZDdXJyZW50Q2hpbGREZXB0aCAqIDJdOwotICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weSh0bXBDdXJyZW50Q2hpbGRTZXF1ZW5jZSwgMCwgZkN1cnJlbnRDaGlsZFNlcXVlbmNlLAotICAgICAgICAgICAgICAgICAgICAwLCB0bXBDdXJyZW50Q2hpbGRTZXF1ZW5jZS5sZW5ndGgpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8KLSAgICAgICAgaWYgKGZJc1Jlc29sdmVFbGVtZW50KSB7Ci0gICAgICAgICAgICAvLyBzdGFydAotICAgICAgICAgICAgZldhc09ubHlFbXB0eUVsZW1lbnRGb3VuZCA9IGZhbHNlOwotICAgICAgICAgICAgaWYgKGV2ZW50ID09IFhQb2ludGVyUGFydC5FVkVOVF9FTEVNRU5UX1NUQVJUKSB7Ci0gICAgICAgICAgICAgICAgZkN1cnJlbnRDaGlsZFNlcXVlbmNlW2ZDdXJyZW50Q2hpbGREZXB0aF0gPSBmQ3VycmVudENoaWxkUG9zaXRpb247Ci0gICAgICAgICAgICAgICAgZkN1cnJlbnRDaGlsZERlcHRoKys7Ci0KLSAgICAgICAgICAgICAgICAvLyByZXNldCB0aGUgY3VycmVudCBjaGlsZCBwb3NpdGlvbgotICAgICAgICAgICAgICAgIGZDdXJyZW50Q2hpbGRQb3NpdGlvbiA9IDE7Ci0KLSAgICAgICAgICAgICAgICAvL2lmICghZlNjaGVtZU5hbWVGb3VuZCkgewotICAgICAgICAgICAgICAgIGlmICgoZkN1cnJlbnRDaGlsZERlcHRoIDw9IGZGb3VuZERlcHRoKSB8fCAoZkZvdW5kRGVwdGggPT0gMCkpIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGNoZWNrTWF0Y2goKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgZklzRWxlbWVudEZvdW5kID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZGb3VuZERlcHRoID0gZkN1cnJlbnRDaGlsZERlcHRoOwotICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgZklzRWxlbWVudEZvdW5kID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmRm91bmREZXB0aCA9IDA7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIH0gZWxzZSBpZiAoZXZlbnQgPT0gWFBvaW50ZXJQYXJ0LkVWRU5UX0VMRU1FTlRfRU5EKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGZDdXJyZW50Q2hpbGREZXB0aCA9PSBmRm91bmREZXB0aCkgewotICAgICAgICAgICAgICAgICAgICBmSXNFbGVtZW50Rm91bmQgPSB0cnVlOwotICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoKChmQ3VycmVudENoaWxkRGVwdGggPCBmRm91bmREZXB0aCkgJiYgKGZGb3VuZERlcHRoICE9IDApKQotICAgICAgICAgICAgICAgICAgICAgICAgfHwgKChmQ3VycmVudENoaWxkRGVwdGggPiBmRm91bmREZXB0aCkgLy8gb3IgZW1wdHkgZWxlbWVudCBmb3VuZAotICAgICAgICAgICAgICAgICAgICAgICAgJiYgKGZGb3VuZERlcHRoID09IDApKSkgewotICAgICAgICAgICAgICAgICAgICBmSXNFbGVtZW50Rm91bmQgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyByZXNldCBhcnJheSBwb3NpdGlvbiBvZiBsYXN0IGNoaWxkCi0gICAgICAgICAgICAgICAgZkN1cnJlbnRDaGlsZFNlcXVlbmNlW2ZDdXJyZW50Q2hpbGREZXB0aF0gPSAwOwotCi0gICAgICAgICAgICAgICAgZkN1cnJlbnRDaGlsZERlcHRoLS07Ci0gICAgICAgICAgICAgICAgZkN1cnJlbnRDaGlsZFBvc2l0aW9uID0gZkN1cnJlbnRDaGlsZFNlcXVlbmNlW2ZDdXJyZW50Q2hpbGREZXB0aF0gKyAxOwotCi0gICAgICAgICAgICB9IGVsc2UgaWYgKGV2ZW50ID09IFhQb2ludGVyUGFydC5FVkVOVF9FTEVNRU5UX0VNUFRZKSB7Ci0KLSAgICAgICAgICAgICAgICBmQ3VycmVudENoaWxkU2VxdWVuY2VbZkN1cnJlbnRDaGlsZERlcHRoXSA9IGZDdXJyZW50Q2hpbGRQb3NpdGlvbjsKLSAgICAgICAgICAgICAgICBmQ3VycmVudENoaWxkUG9zaXRpb24rKzsKLQotICAgICAgICAgICAgICAgIC8vIERvbm90IGNoZWNrIGZvciBlbXB0eSBlbGVtZW50cyBpZiB0aGUgZW1wdHkgZWxlbWVudCBpcwotICAgICAgICAgICAgICAgIC8vIGEgY2hpbGQgb2YgYSBmb3VuZCBwYXJlbnQgZWxlbWVudAotICAgICAgICAgICAgICAgIC8vaWYgKCFmSXNFbGVtZW50Rm91bmQpIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGNoZWNrTWF0Y2goKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgZklzRWxlbWVudEZvdW5kID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZXYXNPbmx5RW1wdHlFbGVtZW50Rm91bmQgPSB0cnVlOwotICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgZklzRWxlbWVudEZvdW5kID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvL30KLQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIGZJc0VsZW1lbnRGb3VuZDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBNYXRjaGVzIHRoZSBjdXJyZW50IHBvc2l0aW9uIG9mIHRoZSBlbGVtZW50IGJlaW5nIHZpc2l0ZWQgYnkgY2hlY2tpbmcKLSAgICAgKiBpdHMgcG9zaXRpb24gYW5kIHByZXZpb3VzIGVsZW1lbnRzIGFnYWluc3QgdGhlIGVsZW1lbnQgWFBvaW50ZXIgZXhwcmVzc2lvbi4KLSAgICAgKiBJZiBhIG1hdGNoIGlzIGZvdW5kIGl0IHJldHVybiB0cnVlIGVsc2UgZmFsc2UuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIGJvb2xlYW4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBjaGVja01hdGNoKCkgewotICAgICAgICAvLyBJZiB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzIGluIHRoZSBDaGlsZFNlcXVlbmNlIGlzIGdyZWF0ZXIgdGhhbiB0aGUKLSAgICAgICAgLy8gY3VycmVudCBjaGlsZCBkZXB0aCwgdGhlcmUgaXMgbm90IHBvaW50IGluIGNoZWNraW5nIGZ1cnRoZXIKLSAgICAgICAgaWYgKCFmSXNTaG9ydEhhbmQpIHsKLSAgICAgICAgICAgIC8vIElmIGEgc2hvcnRoYW5kIHBvaW50ZXIgaXMgbm90IHByZXNlbnQgdHJhdmVyc2UgdGhlIGNoaWxkcmVuCi0gICAgICAgICAgICAvLyBhbmQgY29tcGFyZQotICAgICAgICAgICAgaWYgKGZDaGlsZFNlcXVlbmNlLmxlbmd0aCA8PSBmQ3VycmVudENoaWxkRGVwdGggKyAxKSB7Ci0KLSAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZDaGlsZFNlcXVlbmNlLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChmQ2hpbGRTZXF1ZW5jZVtpXSAhPSBmQ3VycmVudENoaWxkU2VxdWVuY2VbaV0pIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgLy8gSWYgYSBzaG9ydGhhbmQgcG9pbnRlciBpcyBwcmVzZW50IHRyYXZlcnNlIHRoZSBjaGlsZHJlbgotICAgICAgICAgICAgLy8gaWdub3JpbmcgdGhlIGZpcnN0IGVsZW1lbnQgb2YgdGhlIEN1cnJlbkNoaWxkU2VxdWVuY2Ugd2hpY2gKLSAgICAgICAgICAgIC8vIGNvbnRhaW5zIHRoZSBTaG9ydEhhbmQgcG9pbnRlciBlbGVtZW50IGFuZCBjb21wYXJlCi0gICAgICAgICAgICBpZiAoZkNoaWxkU2VxdWVuY2UubGVuZ3RoIDw9IGZDdXJyZW50Q2hpbGREZXB0aCArIDEpIHsKLQotICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZkNoaWxkU2VxdWVuY2UubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gZW5zdXJlIGZDdXJyZW50Q2hpbGRTZXF1ZW5jZSBpcyBsYXJnZSBlbm91Z2gKLSAgICAgICAgICAgICAgICAgICAgaWYgKGZDdXJyZW50Q2hpbGRTZXF1ZW5jZS5sZW5ndGggPCBpICsgMikgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgLy8gaWdub3JlIHRoZSBmaXJzdCBlbGVtZW50IG9mIGZDdXJyZW50Q2hpbGRTZXF1ZW5jZQotICAgICAgICAgICAgICAgICAgICBpZiAoZkNoaWxkU2VxdWVuY2VbaV0gIT0gZkN1cnJlbnRDaGlsZFNlcXVlbmNlW2kgKyAxXSkgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgbm9kZSBtYXRjaGVzIG9yIGlzIGEgY2hpbGQgb2YgYSBtYXRjaGluZyBlbGVtZW50KCkKLSAgICAgKiBzY2hlbWUgWFBvaW50ZXIuCi0gICAgICoKLSAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHBvaW50ZXIuWFBvaW50ZXJQcm9jZXNzb3IjaXNGcmFnbWVudFJlc29sdmVkKCkKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0ZyYWdtZW50UmVzb2x2ZWQoKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgLy8gUmV0dXJuIHRydWUgaWYgdGhlIEZyYWdtZW50IHdhcyByZXNvbHZlZCBhbmQgdGhlIGN1cnJlbnQgTm9kZSBkZXB0aAotICAgICAgICAvLyBpcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gdGhlIGRlcHRoIGF0IHdoaWNoIHRoZSBlbGVtZW50IHdhcyBmb3VuZAotICAgICAgICByZXR1cm4gZklzRnJhZ21lbnRSZXNvbHZlZCA7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBYUG9pbnRlciBleHByZXNzaW9uIHJlc29sdmVzIHRvIGEgbm9uLWVsZW1lbnQgY2hpbGQKLSAgICAgKiBvZiB0aGUgY3VycmVudCByZXNvdXJjZSBmcmFnbWVudC4KLSAgICAgKgotICAgICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cG9pbnRlci5YUG9pbnRlclBhcnQjaXNDaGlsZEZyYWdtZW50UmVzb2x2ZWQoKQotICAgICAqCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNDaGlsZEZyYWdtZW50UmVzb2x2ZWQoKSB7Ci0gICAgICAgIC8vIGlmIG9ubHkgYSBzaG9ydGhhbmQgcG9pbnRlciB3YXMgcHJlc2VudAotICAgICAgICBpZiAoZklzU2hvcnRIYW5kICYmIGZTaG9ydEhhbmRQb2ludGVyICE9IG51bGwgJiYgZkNoaWxkU2VxdWVuY2UubGVuZ3RoIDw9IDApIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZlNob3J0SGFuZFBvaW50ZXIuaXNDaGlsZEZyYWdtZW50UmVzb2x2ZWQoKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZldhc09ubHlFbXB0eUVsZW1lbnRGb3VuZCA/ICFmV2FzT25seUVtcHR5RWxlbWVudEZvdW5kCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogKGZJc0ZyYWdtZW50UmVzb2x2ZWQgJiYgKGZDdXJyZW50Q2hpbGREZXB0aCA+PSBmRm91bmREZXB0aCkpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICAgICAqIFJlcG9ydHMgYW4gWFBvaW50ZXIgZXJyb3IKLSAgICAgICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgcmVwb3J0RXJyb3IoU3RyaW5nIGtleSwgT2JqZWN0W10gYXJndW1lbnRzKQotICAgICAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIC8qZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IoWFBvaW50ZXJNZXNzYWdlRm9ybWF0dGVyLlhQT0lOVEVSX0RPTUFJTiwKLSAgICAgICAgIGtleSwgYXJndW1lbnRzLCBYTUxFcnJvclJlcG9ydGVyLlNFVkVSSVRZX0VSUk9SKTsKLSAgICAgICAgICovCi0gICAgICAgIHRocm93IG5ldyBYTklFeGNlcHRpb24oKGZFcnJvclJlcG9ydGVyCi0gICAgICAgICAgICAgICAgICAgICAgICAuZ2V0TWVzc2FnZUZvcm1hdHRlcihYUG9pbnRlck1lc3NhZ2VGb3JtYXR0ZXIuWFBPSU5URVJfRE9NQUlOKSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmZvcm1hdE1lc3NhZ2UoZkVycm9yUmVwb3J0ZXIuZ2V0TG9jYWxlKCksIGtleSwgYXJndW1lbnRzKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSW5pdGlhbGl6ZXMgZXJyb3IgaGFuZGxpbmcgb2JqZWN0cwotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIGluaXRFcnJvclJlcG9ydGVyKCkgewotICAgICAgICBpZiAoZkVycm9yUmVwb3J0ZXIgPT0gbnVsbCkgewotICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIgPSBuZXcgWE1MRXJyb3JSZXBvcnRlcigpOwotICAgICAgICB9Ci0gICAgICAgIGlmIChmRXJyb3JIYW5kbGVyID09IG51bGwpIHsKLSAgICAgICAgICAgIGZFcnJvckhhbmRsZXIgPSBuZXcgWFBvaW50ZXJFcnJvckhhbmRsZXIoKTsKLSAgICAgICAgfQotICAgICAgICBmRXJyb3JSZXBvcnRlci5wdXRNZXNzYWdlRm9ybWF0dGVyKAotICAgICAgICAgICAgICAgIFhQb2ludGVyTWVzc2FnZUZvcm1hdHRlci5YUE9JTlRFUl9ET01BSU4sCi0gICAgICAgICAgICAgICAgbmV3IFhQb2ludGVyTWVzc2FnZUZvcm1hdHRlcigpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJbml0aWFsaXplcyB0aGUgZWxlbWVudCBzY2hlbWUgcHJvY2Vzc29yCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgaW5pdCgpIHsKLSAgICAgICAgZlNjaGVtZU5hbWUgPSBudWxsOwotICAgICAgICBmU2NoZW1lRGF0YSA9IG51bGw7Ci0gICAgICAgIGZTaG9ydEhhbmRQb2ludGVyTmFtZSA9IG51bGw7Ci0gICAgICAgIGZJc1Jlc29sdmVFbGVtZW50ID0gZmFsc2U7Ci0gICAgICAgIGZJc0VsZW1lbnRGb3VuZCA9IGZhbHNlOwotICAgICAgICBmV2FzT25seUVtcHR5RWxlbWVudEZvdW5kID0gZmFsc2U7Ci0gICAgICAgIGZGb3VuZERlcHRoID0gMDsKLSAgICAgICAgZkN1cnJlbnRDaGlsZFBvc2l0aW9uID0gMTsKLSAgICAgICAgZkN1cnJlbnRDaGlsZERlcHRoID0gMDsKLSAgICAgICAgZklzRnJhZ21lbnRSZXNvbHZlZCA9IGZhbHNlOwotICAgICAgICBmU2hvcnRIYW5kUG9pbnRlciA9IG51bGw7Ci0KLSAgICAgICAgaW5pdEVycm9yUmVwb3J0ZXIoKTsKLSAgICB9Ci0KLSAgICAvLyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLSAgICAvLyBlbGVtZW50KCkgU2NoZW1lIGV4cHJlc3Npb24gc2Nhbm5lcgotICAgIC8vICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgotCi0gICAgLyoqCi0gICAgICogTGlzdCBvZiBYUG9pbnRlciBGcmFtZXdvcmsgdG9rZW5zLgotICAgICAqCi0gICAgICogQHhlcmNlcy5pbnRlcm5hbAotICAgICAqCi0gICAgICogQGF1dGhvciBOZWlsIERlbGltYSwgSUJNCi0gICAgICogQHZlcnNpb24gJElkOiBFbGVtZW50U2NoZW1lUG9pbnRlci5qYXZhLHYgMS40IDIwMDkvMDYvMTEgMjM6NTE6NTAgam9laHcgRXhwICQKLSAgICAgKgotICAgICAqLwotICAgIHByaXZhdGUgZmluYWwgY2xhc3MgVG9rZW5zIHsKLQotICAgICAgICAvKioKLSAgICAgICAgICogWFBvaW50ZXIgZWxlbWVudCgpIHNjaGVtZQotICAgICAgICAgKiBbMV0gICAgRWxlbWVudFNjaGVtZURhdGEgICAgOjo9ICAgIChOQ05hbWUgQ2hpbGRTZXF1ZW5jZT8pIHwgQ2hpbGRTZXF1ZW5jZQotICAgICAgICAgKiBbMl0gICAgQ2hpbGRTZXF1ZW5jZSAgICA6Oj0gICAgKCcvJyBbMS05XSBbMC05XSopKwotICAgICAgICAgKi8KLSAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFhQVFJUT0tFTl9FTEVNX05DTkFNRSA9IDA7Ci0KLSAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFhQVFJUT0tFTl9FTEVNX0NISUxEID0gMTsKLQotICAgICAgICAvLyBUb2tlbiBuYW1lcwotICAgICAgICBwcml2YXRlIGZpbmFsIFN0cmluZ1tdIGZnVG9rZW5OYW1lcyA9IHsgIlhQVFJUT0tFTl9FTEVNX05DTkFNRSIsCi0gICAgICAgICAgICAgICAgIlhQVFJUT0tFTl9FTEVNX0NISUxEIiB9OwotCi0gICAgICAgIC8vIFRva2VuIGNvdW50Ci0gICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBJTklUSUFMX1RPS0VOX0NPVU5UID0gMSA8PCA4OwotCi0gICAgICAgIHByaXZhdGUgaW50W10gZlRva2VucyA9IG5ldyBpbnRbSU5JVElBTF9UT0tFTl9DT1VOVF07Ci0KLSAgICAgICAgcHJpdmF0ZSBpbnQgZlRva2VuQ291bnQgPSAwOwotCi0gICAgICAgIC8vIEN1cnJlbnQgdG9rZW4gcG9zaXRpb24KLSAgICAgICAgcHJpdmF0ZSBpbnQgZkN1cnJlbnRUb2tlbkluZGV4OwotCi0gICAgICAgIHByaXZhdGUgU3ltYm9sVGFibGUgZlN5bWJvbFRhYmxlOwotCi0gICAgICAgIHByaXZhdGUgSGFzaHRhYmxlIGZUb2tlbk5hbWVzID0gbmV3IEhhc2h0YWJsZSgpOwotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBDb25zdHJ1Y3RvcgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gc3ltYm9sVGFibGUgU3ltYm9sVGFibGUKLSAgICAgICAgICovCi0gICAgICAgIHByaXZhdGUgVG9rZW5zKFN5bWJvbFRhYmxlIHN5bWJvbFRhYmxlKSB7Ci0gICAgICAgICAgICBmU3ltYm9sVGFibGUgPSBzeW1ib2xUYWJsZTsKLQotICAgICAgICAgICAgZlRva2VuTmFtZXMucHV0KG5ldyBJbnRlZ2VyKFhQVFJUT0tFTl9FTEVNX05DTkFNRSksCi0gICAgICAgICAgICAgICAgICAgICJYUFRSVE9LRU5fRUxFTV9OQ05BTUUiKTsKLSAgICAgICAgICAgIGZUb2tlbk5hbWVzLnB1dChuZXcgSW50ZWdlcihYUFRSVE9LRU5fRUxFTV9DSElMRCksCi0gICAgICAgICAgICAgICAgICAgICJYUFRSVE9LRU5fRUxFTV9DSElMRCIpOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoKLSAgICAgICAgICogUmV0dXJucyB0aGUgdG9rZW4gU3RyaW5nCi0gICAgICAgICAqIEBwYXJhbSB0b2tlbiBUaGUgaW5kZXggb2YgdGhlIHRva2VuCi0gICAgICAgICAqIEByZXR1cm4gU3RyaW5nIFRoZSB0b2tlbiBzdHJpbmcKLSAgICAgICAgICovCi0gICAgICAgIHByaXZhdGUgU3RyaW5nIGdldFRva2VuU3RyaW5nKGludCB0b2tlbikgewotICAgICAgICAgICAgcmV0dXJuIChTdHJpbmcpIGZUb2tlbk5hbWVzLmdldChuZXcgSW50ZWdlcih0b2tlbikpOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFJldHVybnMgdGhlIHRva2VuIFN0cmluZwotICAgICAgICAgKiBAcGFyYW0gdG9rZW4gVGhlIGluZGV4IG9mIHRoZSB0b2tlbgotICAgICAgICAgKiBAcmV0dXJuIFN0cmluZyBUaGUgdG9rZW4gc3RyaW5nCi0gICAgICAgICAqLwotICAgICAgICBwcml2YXRlIEludGVnZXIgZ2V0VG9rZW4oaW50IHRva2VuKSB7Ci0gICAgICAgICAgICByZXR1cm4gKEludGVnZXIpIGZUb2tlbk5hbWVzLmdldChuZXcgSW50ZWdlcih0b2tlbikpOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIEFkZCB0aGUgc3BlY2lmaWVkIHN0cmluZyBhcyBhIHRva2VuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSB0b2tlbiBUaGUgdG9rZW4gc3RyaW5nCi0gICAgICAgICAqLwotICAgICAgICBwcml2YXRlIHZvaWQgYWRkVG9rZW4oU3RyaW5nIHRva2VuU3RyKSB7Ci0gICAgICAgICAgICBJbnRlZ2VyIHRva2VuSW50ID0gKEludGVnZXIpIGZUb2tlbk5hbWVzLmdldCh0b2tlblN0cik7Ci0gICAgICAgICAgICBpZiAodG9rZW5JbnQgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHRva2VuSW50ID0gbmV3IEludGVnZXIoZlRva2VuTmFtZXMuc2l6ZSgpKTsKLSAgICAgICAgICAgICAgICBmVG9rZW5OYW1lcy5wdXQodG9rZW5JbnQsIHRva2VuU3RyKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGFkZFRva2VuKHRva2VuSW50LmludFZhbHVlKCkpOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIEFkZCB0aGUgc3BlY2lmaWVkIGludCB0b2tlbgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gdG9rZW4gVGhlIGludCBzcGVjaWZ5aW5nIHRoZSB0b2tlbgotICAgICAgICAgKi8KLSAgICAgICAgcHJpdmF0ZSB2b2lkIGFkZFRva2VuKGludCB0b2tlbikgewotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICBmVG9rZW5zW2ZUb2tlbkNvdW50XSA9IHRva2VuOwotICAgICAgICAgICAgfSBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4KSB7Ci0gICAgICAgICAgICAgICAgaW50W10gb2xkTGlzdCA9IGZUb2tlbnM7Ci0gICAgICAgICAgICAgICAgZlRva2VucyA9IG5ldyBpbnRbZlRva2VuQ291bnQgPDwgMV07Ci0gICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShvbGRMaXN0LCAwLCBmVG9rZW5zLCAwLCBmVG9rZW5Db3VudCk7Ci0gICAgICAgICAgICAgICAgZlRva2Vuc1tmVG9rZW5Db3VudF0gPSB0b2tlbjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGZUb2tlbkNvdW50Kys7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogUmVzZXRzIHRoZSBjdXJyZW50IHBvc2l0aW9uIHRvIHRoZSBoZWFkIG9mIHRoZSB0b2tlbiBsaXN0LgotICAgICAgICAgKi8KLSAgICAgICAgcHJpdmF0ZSB2b2lkIHJld2luZCgpIHsKLSAgICAgICAgICAgIGZDdXJyZW50VG9rZW5JbmRleCA9IDA7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSB7QGxpbmsgI2dldE5leHRUb2tlbigpfSBtZXRob2QKLSAgICAgICAgICogcmV0dXJucyBhIHZhbGlkIHRva2VuLgotICAgICAgICAgKi8KLSAgICAgICAgcHJpdmF0ZSBib29sZWFuIGhhc01vcmUoKSB7Ci0gICAgICAgICAgICByZXR1cm4gZkN1cnJlbnRUb2tlbkluZGV4IDwgZlRva2VuQ291bnQ7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogT2J0YWlucyB0aGUgdG9rZW4gYXQgdGhlIGN1cnJlbnQgcG9zaXRpb24sIHRoZW4gYWR2YW5jZQotICAgICAgICAgKiB0aGUgY3VycmVudCBwb3NpdGlvbiBieSBvbmUuCi0gICAgICAgICAqCi0gICAgICAgICAqIElmIHRoZXJlJ3Mgbm8gc3VjaCBuZXh0IHRva2VuLCB0aGlzIG1ldGhvZCB0aHJvd3MKLSAgICAgICAgICogPHR0Pm5ldyBYTklFeGNlcHRpb24oIkludmFsaWRYUG9pbnRlckV4cHJlc3Npb24iKTs8L3R0Pi4KLSAgICAgICAgICovCi0gICAgICAgIHByaXZhdGUgaW50IG5leHRUb2tlbigpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICAgICAgaWYgKGZDdXJyZW50VG9rZW5JbmRleCA9PSBmVG9rZW5Db3VudCkKLSAgICAgICAgICAgICAgICByZXBvcnRFcnJvcigiWFBvaW50ZXJFbGVtZW50U2NoZW1lUHJvY2Vzc2luZ0Vycm9yIiwgbnVsbCk7Ci0gICAgICAgICAgICByZXR1cm4gZlRva2Vuc1tmQ3VycmVudFRva2VuSW5kZXgrK107Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogT2J0YWlucyB0aGUgdG9rZW4gYXQgdGhlIGN1cnJlbnQgcG9zaXRpb24sIHdpdGhvdXQgYWR2YW5jaW5nCi0gICAgICAgICAqIHRoZSBjdXJyZW50IHBvc2l0aW9uLgotICAgICAgICAgKgotICAgICAgICAgKiBJZiB0aGVyZSdzIG5vIHN1Y2ggbmV4dCB0b2tlbiwgdGhpcyBtZXRob2QgdGhyb3dzCi0gICAgICAgICAqIDx0dD5uZXcgWE5JRXhjZXB0aW9uKCJJbnZhbGlkWFBvaW50ZXJFeHByZXNzaW9uIik7PC90dD4uCi0gICAgICAgICAqLwotICAgICAgICBwcml2YXRlIGludCBwZWVrVG9rZW4oKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgICAgIGlmIChmQ3VycmVudFRva2VuSW5kZXggPT0gZlRva2VuQ291bnQpCi0gICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoIlhQb2ludGVyRWxlbWVudFNjaGVtZVByb2Nlc3NpbmdFcnJvciIsIG51bGwpOwotICAgICAgICAgICAgcmV0dXJuIGZUb2tlbnNbZkN1cnJlbnRUb2tlbkluZGV4XTsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBPYnRhaW5zIHRoZSB0b2tlbiBhdCB0aGUgY3VycmVudCBwb3NpdGlvbiBhcyBhIFN0cmluZy4KLSAgICAgICAgICoKLSAgICAgICAgICogSWYgdGhlcmUncyBubyBjdXJyZW50IHRva2VuIG9yIGlmIHRoZSBjdXJyZW50IHRva2VuCi0gICAgICAgICAqIGlzIG5vdCBhIHN0cmluZyB0b2tlbiwgdGhpcyBtZXRob2QgdGhyb3dzCi0gICAgICAgICAqIElmIHRoZXJlJ3Mgbm8gc3VjaCBuZXh0IHRva2VuLCB0aGlzIG1ldGhvZCB0aHJvd3MKLSAgICAgICAgICogPHR0Pm5ldyBYTklFeGNlcHRpb24oIkludmFsaWRYUG9pbnRlckV4cHJlc3Npb24iKTs8L3R0Pi4KLSAgICAgICAgICovCi0gICAgICAgIHByaXZhdGUgU3RyaW5nIG5leHRUb2tlbkFzU3RyaW5nKCkgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICBTdHJpbmcgcyA9IGdldFRva2VuU3RyaW5nKG5leHRUb2tlbigpKTsKLSAgICAgICAgICAgIGlmIChzID09IG51bGwpCi0gICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoIlhQb2ludGVyRWxlbWVudFNjaGVtZVByb2Nlc3NpbmdFcnJvciIsIG51bGwpOwotICAgICAgICAgICAgcmV0dXJuIHM7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIHRva2Vucy4KLSAgICAgICAgICoKLSAgICAgICAgICovCi0gICAgICAgIHByaXZhdGUgaW50IGdldFRva2VuQ291bnQoKSB7Ci0gICAgICAgICAgICByZXR1cm4gZlRva2VuQ291bnQ7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKgotICAgICAqIFRoZSBYUG9pbnRlciBleHByZXNzaW9uIHNjYW5uZXIuICBTY2FucyB0aGUgWFBvaW50ZXIgZnJhbWV3b3JrIGV4cHJlc3Npb24uCi0gICAgICoKLSAgICAgKiBAeGVyY2VzLmludGVybmFsCi0gICAgICoKLSAgICAgKiBAdmVyc2lvbiAkSWQ6IEVsZW1lbnRTY2hlbWVQb2ludGVyLmphdmEsdiAxLjQgMjAwOS8wNi8xMSAyMzo1MTo1MCBqb2VodyBFeHAgJAotICAgICAqLwotICAgIHByaXZhdGUgY2xhc3MgU2Nhbm5lciB7Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIDctYml0IEFTQ0lJIHN1YnNldAotICAgICAgICAgKgotICAgICAgICAgKiAgMCAgIDEgICAyICAgMyAgIDQgICA1ICAgNiAgIDcgICA4ICAgOSAgIEEgICBCICAgQyAgIEQgICBFICAgRgotICAgICAgICAgKiAgMCwgIDAsICAwLCAgMCwgIDAsICAwLCAgMCwgIDAsICAwLCBIVCwgTEYsICAwLCAgMCwgQ1IsICAwLCAgMCwgIC8vIDAKLSAgICAgICAgICogIDAsICAwLCAgMCwgIDAsICAwLCAgMCwgIDAsICAwLCAgMCwgIDAsICAwLCAgMCwgIDAsICAwLCAgMCwgIDAsICAvLyAxCi0gICAgICAgICAqIFNQLCAgISwgICIsICAjLCAgJCwgICUsICAmLCAgJywgICgsICApLCAgKiwgICssICAsLCAgLSwgIC4sICAvLCAgLy8gMgotICAgICAgICAgKiAgMCwgIDEsICAyLCAgMywgIDQsICA1LCAgNiwgIDcsICA4LCAgOSwgIDosICA7LCAgPCwgID0sICA+LCAgPywgIC8vIDMKLSAgICAgICAgICogIEAsICBBLCAgQiwgIEMsICBELCAgRSwgIEYsICBHLCAgSCwgIEksICBKLCAgSywgIEwsICBNLCAgTiwgIE8sICAvLyA0Ci0gICAgICAgICAqICBQLCAgUSwgIFIsICBTLCAgVCwgIFUsICBWLCAgVywgIFgsICBZLCAgWiwgIFssICBcLCAgXSwgIF4sICBfLCAgLy8gNQotICAgICAgICAgKiAgYCwgIGEsICBiLCAgYywgIGQsICBlLCAgZiwgIGcsICBoLCAgaSwgIGosICBrLCAgbCwgIG0sICBuLCAgbywgIC8vIDYKLSAgICAgICAgICogIHAsICBxLCAgciwgIHMsICB0LCAgdSwgIHYsICB3LCAgeCwgIHksICB6LCAgeywgIHwsICB9LCAgfiwgREVMICAvLyA3Ci0gICAgICAgICAqLwotICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlIENIQVJUWVBFX0lOVkFMSUQgPSAwLCAvLyBpbnZhbGlkIFhNTCBjaGFyYWN0ZXJzLCBjb250cm9sIGNoYXJhY3RlcnMgYW5kIDdGCi0gICAgICAgICAgICAgICAgQ0hBUlRZUEVfT1RIRVIgPSAxLCAvLyBBIHZhbGlkIFhNTCBjaGFyYWN0ZXIgKHBvc3NpYmx5IGludmFsaWQgTkNOYW1lQ2hhcikgdGhhdCBkb2VzIG5vdCBmYWxsIGluIG9uZSBvZiB0aGUgb3RoZXIgY2F0ZWdvcmllcwotICAgICAgICAgICAgICAgIENIQVJUWVBFX01JTlVTID0gMiwgLy8gJy0nICgweDJEKQotICAgICAgICAgICAgICAgIENIQVJUWVBFX1BFUklPRCA9IDMsIC8vICcuJyAoMHgyRSkKLSAgICAgICAgICAgICAgICBDSEFSVFlQRV9TTEFTSCA9IDQsIC8vICcvJyAoMHgyRikKLSAgICAgICAgICAgICAgICBDSEFSVFlQRV9ESUdJVCA9IDUsIC8vICcwJy0nOScgKDB4MzAgdG8gMHgzOSkKLSAgICAgICAgICAgICAgICBDSEFSVFlQRV9MRVRURVIgPSA2LCAvLyAnQSctJ1onIG9yICdhJy0neicgKDB4NDEgdG8gMHg1QSBhbmQgMHg2MSB0byAweDdBKQotICAgICAgICAgICAgICAgIENIQVJUWVBFX1VOREVSU0NPUkUgPSA3LCAvLyAnXycgKDB4NUYpCi0gICAgICAgICAgICAgICAgQ0hBUlRZUEVfTk9OQVNDSUkgPSA4OyAvLyBOb24tQVNDSUkgVW5pY29kZSBjb2RlcG9pbnQgKD49IDB4ODApCi0KLSAgICAgICAgcHJpdmF0ZSBmaW5hbCBieXRlW10gZkFTQ0lJQ2hhck1hcCA9IHsgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMSwgMSwKLSAgICAgICAgICAgICAgICAwLCAwLCAxLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAotICAgICAgICAgICAgICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDIsIDIsIDQsIDUsIDUsIDUsIDUsIDUsCi0gICAgICAgICAgICAgICAgNSwgNSwgNSwgNSwgNSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgNiwgNiwgNiwgNiwgNiwgNiwgNiwgNiwgNiwKLSAgICAgICAgICAgICAgICA2LCA2LCA2LCA2LCA2LCA2LCA2LCA2LCA2LCA2LCA2LCA2LCA2LCA2LCA2LCA2LCA2LCAxLCAxLCAxLCAxLAotICAgICAgICAgICAgICAgIDcsIDEsIDYsIDYsIDYsIDYsIDYsIDYsIDYsIDYsIDYsIDYsIDYsIDYsIDYsIDYsIDYsIDYsIDYsIDYsIDYsCi0gICAgICAgICAgICAgICAgNiwgNiwgNiwgNiwgNiwgNiwgNiwgMSwgMSwgMSwgMSwgMSB9OwotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBTeW1ib2wgbGl0ZXJhbHMKLSAgICAgICAgICovCi0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gRGF0YQotICAgICAgICAvLwotICAgICAgICAvKiogU3ltYm9sIHRhYmxlLiAqLwotICAgICAgICBwcml2YXRlIFN5bWJvbFRhYmxlIGZTeW1ib2xUYWJsZTsKLQotICAgICAgICAvLwotICAgICAgICAvLyBDb25zdHJ1Y3RvcnMKLSAgICAgICAgLy8KLQotICAgICAgICAvKioKLSAgICAgICAgICogQ29uc3RydWN0cyBhbiBYUGF0aCBleHByZXNzaW9uIHNjYW5uZXIuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBzeW1ib2xUYWJsZSBTeW1ib2xUYWJsZQotICAgICAgICAgKi8KLSAgICAgICAgcHJpdmF0ZSBTY2FubmVyKFN5bWJvbFRhYmxlIHN5bWJvbFRhYmxlKSB7Ci0gICAgICAgICAgICAvLyBzYXZlIHBvb2wgYW5kIHRva2VucwotICAgICAgICAgICAgZlN5bWJvbFRhYmxlID0gc3ltYm9sVGFibGU7Ci0KLSAgICAgICAgfSAvLyA8aW5pdD4oU3ltYm9sVGFibGUpCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFNjYW5zIHRoZSBYUG9pbnRlciBFeHByZXNzaW9uCi0gICAgICAgICAqCi0gICAgICAgICAqLwotICAgICAgICBwcml2YXRlIGJvb2xlYW4gc2NhbkV4cHIoU3ltYm9sVGFibGUgc3ltYm9sVGFibGUsIFRva2VucyB0b2tlbnMsCi0gICAgICAgICAgICAgICAgU3RyaW5nIGRhdGEsIGludCBjdXJyZW50T2Zmc2V0LCBpbnQgZW5kT2Zmc2V0KQotICAgICAgICAgICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotCi0gICAgICAgICAgICBpbnQgY2g7Ci0gICAgICAgICAgICBpbnQgbmFtZU9mZnNldDsKLSAgICAgICAgICAgIFN0cmluZyBuYW1lSGFuZGxlID0gbnVsbDsKLQotICAgICAgICAgICAgd2hpbGUgKHRydWUpIHsKLSAgICAgICAgICAgICAgICBpZiAoY3VycmVudE9mZnNldCA9PSBlbmRPZmZzZXQpIHsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgY2ggPSBkYXRhLmNoYXJBdChjdXJyZW50T2Zmc2V0KTsKLSAgICAgICAgICAgICAgICBieXRlIGNoYXJ0eXBlID0gKGNoID49IDB4ODApID8gQ0hBUlRZUEVfTk9OQVNDSUkKLSAgICAgICAgICAgICAgICAgICAgICAgIDogZkFTQ0lJQ2hhck1hcFtjaF07Ci0KLSAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgIC8vIFsxXSAgICBFbGVtZW50U2NoZW1lRGF0YSAgICA6Oj0gICAgKE5DTmFtZSBDaGlsZFNlcXVlbmNlPykgfCBDaGlsZFNlcXVlbmNlCi0gICAgICAgICAgICAgICAgLy8gWzJdICAgIENoaWxkU2VxdWVuY2UgICAgOjo9ICAgICgnLycgWzEtOV0gWzAtOV0qKSsKLSAgICAgICAgICAgICAgICAvLwotCi0gICAgICAgICAgICAgICAgc3dpdGNoIChjaGFydHlwZSkgewotCi0gICAgICAgICAgICAgICAgY2FzZSBDSEFSVFlQRV9TTEFTSDoKLSAgICAgICAgICAgICAgICAgICAgLy8gaWYgbGFzdCBjaGFyYWN0ZXIgaXMgJy8nLCBicmVhayBhbmQgcmVwb3J0IGFuIGVycm9yCi0gICAgICAgICAgICAgICAgICAgIGlmICgrK2N1cnJlbnRPZmZzZXQgPT0gZW5kT2Zmc2V0KSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICBhZGRUb2tlbih0b2tlbnMsIFRva2Vucy5YUFRSVE9LRU5fRUxFTV9DSElMRCk7Ci0gICAgICAgICAgICAgICAgICAgIGNoID0gZGF0YS5jaGFyQXQoY3VycmVudE9mZnNldCk7Ci0KLSAgICAgICAgICAgICAgICAgICAgLy8gQ2hpbGRTZXF1ZW5jZSAgICA6Oj0gICAgKCcvJyBbMS05XSBbMC05XSopKwotICAgICAgICAgICAgICAgICAgICBpbnQgY2hpbGQgPSAwOwotICAgICAgICAgICAgICAgICAgICB3aGlsZSAoY2ggPj0gJzAnICYmIGNoIDw9ICc5JykgewotICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGQgPSAoY2hpbGQgKiAxMCkgKyAoY2ggLSAnMCcpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCsrY3VycmVudE9mZnNldCA9PSBlbmRPZmZzZXQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGNoID0gZGF0YS5jaGFyQXQoY3VycmVudE9mZnNldCk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAvLyBBbiBpbnZhbGlkIGNoaWxkIHNlcXVlbmNlIGNoYXJhY3RlcgotICAgICAgICAgICAgICAgICAgICBpZiAoY2hpbGQgPT0gMCkgewotICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoIkludmFsaWRDaGlsZFNlcXVlbmNlQ2hhcmFjdGVyIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgbmV3IENoYXJhY3RlcigoY2hhcikgY2gpIH0pOwotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgdG9rZW5zLmFkZFRva2VuKGNoaWxkKTsKLQotICAgICAgICAgICAgICAgICAgICBicmVhazsKLQotICAgICAgICAgICAgICAgIGNhc2UgQ0hBUlRZUEVfRElHSVQ6Ci0gICAgICAgICAgICAgICAgY2FzZSBDSEFSVFlQRV9MRVRURVI6Ci0gICAgICAgICAgICAgICAgY2FzZSBDSEFSVFlQRV9NSU5VUzoKLSAgICAgICAgICAgICAgICBjYXNlIENIQVJUWVBFX05PTkFTQ0lJOgotICAgICAgICAgICAgICAgIGNhc2UgQ0hBUlRZUEVfT1RIRVI6Ci0gICAgICAgICAgICAgICAgY2FzZSBDSEFSVFlQRV9QRVJJT0Q6Ci0gICAgICAgICAgICAgICAgY2FzZSBDSEFSVFlQRV9VTkRFUlNDT1JFOgotICAgICAgICAgICAgICAgICAgICAvLyBTY2FuIHRoZSBTaG9ydEhhbmQgUG9pbnRlciBOQ05hbWUKLSAgICAgICAgICAgICAgICAgICAgbmFtZU9mZnNldCA9IGN1cnJlbnRPZmZzZXQ7Ci0gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRPZmZzZXQgPSBzY2FuTkNOYW1lKGRhdGEsIGVuZE9mZnNldCwgY3VycmVudE9mZnNldCk7Ci0KLSAgICAgICAgICAgICAgICAgICAgaWYgKGN1cnJlbnRPZmZzZXQgPT0gbmFtZU9mZnNldCkgewotICAgICAgICAgICAgICAgICAgICAgICAgLy9yZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRFcnJvcigiSW52YWxpZE5DTmFtZUluRWxlbWVudFNjaGVtZURhdGEiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBkYXRhIH0pOwotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgaWYgKGN1cnJlbnRPZmZzZXQgPCBlbmRPZmZzZXQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGNoID0gZGF0YS5jaGFyQXQoY3VycmVudE9mZnNldCk7Ci0gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBjaCA9IC0xOwotICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgbmFtZUhhbmRsZSA9IHN5bWJvbFRhYmxlLmFkZFN5bWJvbChkYXRhLnN1YnN0cmluZygKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lT2Zmc2V0LCBjdXJyZW50T2Zmc2V0KSk7Ci0gICAgICAgICAgICAgICAgICAgIGFkZFRva2VuKHRva2VucywgVG9rZW5zLlhQVFJUT0tFTl9FTEVNX05DTkFNRSk7Ci0gICAgICAgICAgICAgICAgICAgIHRva2Vucy5hZGRUb2tlbihuYW1lSGFuZGxlKTsKLQotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBTY2FucyBhIE5DTmFtZS4KLSAgICAgICAgICogRnJvbSBOYW1lc3BhY2VzIGluIFhNTAotICAgICAgICAgKiBbNV0gTkNOYW1lIDo6PSAoTGV0dGVyIHwgJ18nKSAoTkNOYW1lQ2hhcikqCi0gICAgICAgICAqIFs2XSBOQ05hbWVDaGFyIDo6PSBMZXR0ZXIgfCBEaWdpdCB8ICcuJyB8ICctJyB8ICdfJyB8IENvbWJpbmluZ0NoYXIgfCBFeHRlbmRlcgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gZGF0YSBBIFN0cmluZyBjb250YWluaW5nIHRoZSBYUG9pbnRlciBleHByZXNzaW9uCi0gICAgICAgICAqIEBwYXJhbSBlbmRPZmZzZXQgVGhlIGludCBYUG9pbnRlciBleHByZXNzaW9uIGxlbmd0aAotICAgICAgICAgKiBAcGFyYW0gY3VycmVudE9mZnNldCBBbiBpbnQgcmVwcmVzZW50aW5nIHRoZSBjdXJyZW50IHBvc2l0aW9uIG9mIHRoZSBYUG9pbnRlciBleHByZXNzaW9uIHBvaW50ZXIKLSAgICAgICAgICovCi0gICAgICAgIHByaXZhdGUgaW50IHNjYW5OQ05hbWUoU3RyaW5nIGRhdGEsIGludCBlbmRPZmZzZXQsIGludCBjdXJyZW50T2Zmc2V0KSB7Ci0gICAgICAgICAgICBpbnQgY2ggPSBkYXRhLmNoYXJBdChjdXJyZW50T2Zmc2V0KTsKLSAgICAgICAgICAgIGlmIChjaCA+PSAweDgwKSB7Ci0gICAgICAgICAgICAgICAgaWYgKCFYTUxDaGFyLmlzTmFtZVN0YXJ0KGNoKSkgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gY3VycmVudE9mZnNldDsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIGJ5dGUgY2hhcnR5cGUgPSBmQVNDSUlDaGFyTWFwW2NoXTsKLSAgICAgICAgICAgICAgICBpZiAoY2hhcnR5cGUgIT0gQ0hBUlRZUEVfTEVUVEVSCi0gICAgICAgICAgICAgICAgICAgICAgICAmJiBjaGFydHlwZSAhPSBDSEFSVFlQRV9VTkRFUlNDT1JFKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBjdXJyZW50T2Zmc2V0OwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHdoaWxlICgrK2N1cnJlbnRPZmZzZXQgPCBlbmRPZmZzZXQpIHsKLSAgICAgICAgICAgICAgICBjaCA9IGRhdGEuY2hhckF0KGN1cnJlbnRPZmZzZXQpOwotICAgICAgICAgICAgICAgIGlmIChjaCA+PSAweDgwKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmICghWE1MQ2hhci5pc05hbWUoY2gpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIGJ5dGUgY2hhcnR5cGUgPSBmQVNDSUlDaGFyTWFwW2NoXTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGNoYXJ0eXBlICE9IENIQVJUWVBFX0xFVFRFUgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmIGNoYXJ0eXBlICE9IENIQVJUWVBFX0RJR0lUCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgY2hhcnR5cGUgIT0gQ0hBUlRZUEVfUEVSSU9ECi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgY2hhcnR5cGUgIT0gQ0hBUlRZUEVfTUlOVVMKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiBjaGFydHlwZSAhPSBDSEFSVFlQRV9VTkRFUlNDT1JFKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiBjdXJyZW50T2Zmc2V0OwotICAgICAgICB9Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gUHJvdGVjdGVkIG1ldGhvZHMKLSAgICAgICAgLy8KLQotICAgICAgICAvKioKLSAgICAgICAgICogVGhpcyBtZXRob2QgYWRkcyB0aGUgc3BlY2lmaWVkIHRva2VuIHRvIHRoZSB0b2tlbiBsaXN0LiBCeQotICAgICAgICAgKiBkZWZhdWx0LCB0aGlzIG1ldGhvZCBhbGxvd3MgYWxsIHRva2Vucy4gSG93ZXZlciwgc3ViY2xhc3NlcwotICAgICAgICAgKiBvZiB0aGUgWFBhdGhFeHByU2Nhbm5lciBjYW4gb3ZlcnJpZGUgdGhpcyBtZXRob2QgaW4gb3JkZXIKLSAgICAgICAgICogdG8gZGlzYWxsb3cgY2VydGFpbiB0b2tlbnMgZnJvbSBiZWluZyB1c2VkIGluIHRoZSBzY2FubmVkCi0gICAgICAgICAqIFhQYXRoIGV4cHJlc3Npb24uIFRoaXMgaXMgYSBjb252ZW5pZW50IHdheSBvZiBhbGxvd2luZyBvbmx5Ci0gICAgICAgICAqIGEgc3Vic2V0IG9mIFhQYXRoLgotICAgICAgICAgKi8KLSAgICAgICAgcHJvdGVjdGVkIHZvaWQgYWRkVG9rZW4oVG9rZW5zIHRva2VucywgaW50IHRva2VuKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgICAgIHRva2Vucy5hZGRUb2tlbih0b2tlbik7Ci0gICAgICAgIH0gLy8gYWRkVG9rZW4oaW50KQotCi0gICAgfSAvLyBjbGFzcyBTY2FubmVyCi0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3hwb2ludGVyL1Nob3J0SGFuZFBvaW50ZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3hwb2ludGVyL1Nob3J0SGFuZFBvaW50ZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMTMxN2RlYi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94cG9pbnRlci9TaG9ydEhhbmRQb2ludGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyOTYgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHBvaW50ZXI7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5YU1NpbXBsZVR5cGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlN5bWJvbFRhYmxlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLkF1Z21lbnRhdGlvbnM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuUU5hbWU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MQXR0cmlidXRlczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTklFeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5BdHRyaWJ1dGVQU1ZJOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuWFNUeXBlRGVmaW5pdGlvbjsKLQotLyoqCi0gKiA8cD4KLSAqIEltcGxlbWVudHMgdGhlIFhQb2ludGVyUGFydCBpbnRlcmZhY2UgYW5kIGhhbmRsZXMgcHJvY2Vzc2luZyBvZgotICogU2hvcnRIYW5kIFBvaW50ZXJzLiAgSXQgaWRlbnRpZmllcyBhdCBtb3N0IG9uZSBlbGVtZW50IGluIHRoZQotICogcmVzb3VyY2UncyBpbmZvcm1hdGlvbiBzZXQ7IHNwZWNpZmljYWxseSwgdGhlIGZpcnN0IG9uZSAoaWYgYW55KQotICogaW4gZG9jdW1lbnQgb3JkZXIgdGhhdCBoYXMgYSBtYXRjaGluZyBOQ05hbWUgYXMgYW4gaWRlbnRpZmllci4KLSAqIDwvcD4KLSAqCi0gKgotICovCi1jbGFzcyBTaG9ydEhhbmRQb2ludGVyIGltcGxlbWVudHMgWFBvaW50ZXJQYXJ0IHsKLQotICAgIC8vIFRoZSBuYW1lIG9mIHRoZSBTaG9ydEhhbmQgcG9pbnRlcgotICAgIHByaXZhdGUgU3RyaW5nIGZTaG9ydEhhbmRQb2ludGVyOwotCi0gICAgLy8gVGhlIG5hbWUgb2YgdGhlIFNob3J0SGFuZCBwb2ludGVyCi0gICAgcHJpdmF0ZSBib29sZWFuIGZJc0ZyYWdtZW50UmVzb2x2ZWQgPSBmYWxzZTsKLQotICAgIC8vIFN5bWJvbFRhYmxlCi0gICAgcHJpdmF0ZSBTeW1ib2xUYWJsZSBmU3ltYm9sVGFibGU7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0cnVjdG9ycwotICAgIC8vCi0gICAgcHVibGljIFNob3J0SGFuZFBvaW50ZXIoKSB7Ci0gICAgfQotCi0gICAgcHVibGljIFNob3J0SGFuZFBvaW50ZXIoU3ltYm9sVGFibGUgc3ltYm9sVGFibGUpIHsKLSAgICAgICAgZlN5bWJvbFRhYmxlID0gc3ltYm9sVGFibGU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhlIFhQb2ludGVyUHJvY2Vzc29yIHRha2VzIGNhcmUgb2YgdGhpcy4gIFNpbXBseSBzZXQgdGhlIFNob3J0SGFuZCBQb2ludGVyIGhlcmUuCi0gICAgICoKLSAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHBvaW50ZXIuWFBvaW50ZXJQYXJ0I3BhcnNlWFBvaW50ZXIoamF2YS5sYW5nLlN0cmluZykKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBwYXJzZVhQb2ludGVyKFN0cmluZyBwYXJ0KSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgZlNob3J0SGFuZFBvaW50ZXIgPSBwYXJ0OwotICAgICAgICAvLyByZXNldCBmSXNGcmFnbWVudFJlc29sdmVkCi0gICAgICAgIGZJc0ZyYWdtZW50UmVzb2x2ZWQgPSBmYWxzZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXNvbHZlcyB0aGUgWFBvaW50ZXIgU2hvcnRIYW5kIHBvaW50ZXIgYmFzZWQgb24gdGhlIHJ1bGVzIGRlZmluZWQgaW4KLSAgICAgKiBTZWN0aW9uIDMuMiBvZiB0aGUgWFBvaW50ZXIgRnJhbWV3b3JrIFJlY29tbWVuZGF0aW9uLgotICAgICAqIE5vdGUgdGhhdCBpbiB0aGUgY3VycmVudCBpbXBsZW1lbnRhdGlvbiBvbmx5IHN1cHBvcnRzIERURCBkZXRlcm1pbmVkIElEJ3MuCi0gICAgICoKLSAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHBvaW50ZXIuWFBvaW50ZXJQYXJ0I3Jlc29sdmVYUG9pbnRlcihjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5RTmFtZSwgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MQXR0cmlidXRlcywgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuQXVnbWVudGF0aW9ucywgaW50IGV2ZW50KQotICAgICAqLwotICAgIGludCBmTWF0Y2hpbmdDaGlsZENvdW50ID0gMDsKLSAgICBwdWJsaWMgYm9vbGVhbiByZXNvbHZlWFBvaW50ZXIoUU5hbWUgZWxlbWVudCwgWE1MQXR0cmlidXRlcyBhdHRyaWJ1dGVzLAotICAgICAgICAgICAgQXVnbWVudGF0aW9ucyBhdWdzLCBpbnQgZXZlbnQpIHRocm93cyBYTklFeGNlcHRpb24gewotCi0gICAgICAgIC8vIHJlc2V0IGZJc0ZyYWdtZW50UmVzb2x2ZWQKLSAgICAgICAgaWYgKGZNYXRjaGluZ0NoaWxkQ291bnQgPT0gMCkgewotICAgICAgICAgICAgZklzRnJhZ21lbnRSZXNvbHZlZCA9IGZhbHNlOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gT24gc3RhcnRFbGVtZW50IG9yIGVtcHR5RWxlbWVudCwgaWYgbm8gbWF0Y2hpbmcgZWxlbWVudHMgb3IgcGFyZW50Ci0gICAgICAgIC8vIGVsZW1lbnRzIHdlcmUgZm91bmQsIGNoZWNrIGZvciBhIG1hdGNoaW5nIGlkZW5maXRpZXIuCi0gICAgICAgIGlmIChldmVudCA9PSBYUG9pbnRlclBhcnQuRVZFTlRfRUxFTUVOVF9TVEFSVCkgewotICAgICAgICAgICAgaWYgKGZNYXRjaGluZ0NoaWxkQ291bnQgPT0gMCkgewotICAgICAgICAgICAgICAgIGZJc0ZyYWdtZW50UmVzb2x2ZWQgPSBoYXNNYXRjaGluZ0lkZW50aWZpZXIoZWxlbWVudCwgYXR0cmlidXRlcywgYXVncywKLSAgICAgICAgICAgICAgICAgICAgZXZlbnQpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKGZJc0ZyYWdtZW50UmVzb2x2ZWQpIHsKLSAgICAgICAgICAgICAgIGZNYXRjaGluZ0NoaWxkQ291bnQrKzsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSBlbHNlIGlmIChldmVudCA9PSBYUG9pbnRlclBhcnQuRVZFTlRfRUxFTUVOVF9FTVBUWSkgewotICAgICAgICAgICAgaWYgKGZNYXRjaGluZ0NoaWxkQ291bnQgPT0gMCkgewotICAgICAgICAgICAgICAgIGZJc0ZyYWdtZW50UmVzb2x2ZWQgPSBoYXNNYXRjaGluZ0lkZW50aWZpZXIoZWxlbWVudCwgYXR0cmlidXRlcywgYXVncywKLSAgICAgICAgICAgICAgICAgICAgZXZlbnQpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgLy8gT24gZW5kRWxlbWVudCwgZGVjcmVhc2UgdGhlIG1hdGNoaW5nIGNoaWxkIGNvdW50IGlmIHRoZSBjaGlsZCBvcgotICAgICAgICAgICAgLy8gaXRzIHBhcmVudCB3YXMgcmVzb2x2ZWQuCi0gICAgICAgICAgICBpZiAoZklzRnJhZ21lbnRSZXNvbHZlZCkgewotICAgICAgICAgICAgICAgIGZNYXRjaGluZ0NoaWxkQ291bnQtLTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBmSXNGcmFnbWVudFJlc29sdmVkIDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKgotICAgICAqIEBwYXJhbSBlbGVtZW50Ci0gICAgICogQHBhcmFtIGF0dHJpYnV0ZXMKLSAgICAgKiBAcGFyYW0gYXVncwotICAgICAqIEBwYXJhbSBldmVudAotICAgICAqIEByZXR1cm4KLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbgotICAgICAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBoYXNNYXRjaGluZ0lkZW50aWZpZXIoUU5hbWUgZWxlbWVudCwKLSAgICAgICAgICAgIFhNTEF0dHJpYnV0ZXMgYXR0cmlidXRlcywgQXVnbWVudGF0aW9ucyBhdWdzLCBpbnQgZXZlbnQpCi0gICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIFN0cmluZyBub3JtYWxpemVkVmFsdWUgPSBudWxsOwotCi0gICAgICAgIC8vIFRoZSBpZGVudGlmaWVycyBvZiBhbiBlbGVtZW50IGFyZSBkZXRlcm1pbmVkIGJ5IHRoZQotICAgICAgICAvLyBTaG9ydEhhbmQgUG9pbnRlciBhcyBmb2xsb3dzOgotCi0gICAgICAgIGlmIChhdHRyaWJ1dGVzICE9IG51bGwpIHsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYXR0cmlidXRlcy5nZXRMZW5ndGgoKTsgaSsrKSB7Ci0KLSAgICAgICAgICAgICAgICAvLyAxLiBJZiBhbiBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0gaGFzIGFuIGF0dHJpYnV0ZSBpbmZvcm1hdGlvbiBpdGVtCi0gICAgICAgICAgICAgICAgLy8gYW1vbmcgaXRzIFthdHRyaWJ1dGVzXSB0aGF0IGlzIGEgc2NoZW1hLWRldGVybWluZWQgSUQsIHRoZW4gaXQgaXMKLSAgICAgICAgICAgICAgICAvLyBpZGVudGlmaWVkIGJ5IHRoZSB2YWx1ZSBvZiB0aGF0IGF0dHJpYnV0ZSBpbmZvcm1hdGlvbiBpdGVtJ3MKLSAgICAgICAgICAgICAgICAvLyBbc2NoZW1hIG5vcm1hbGl6ZWQgdmFsdWVdIHByb3BlcnR5OwotICAgICAgICAgICAgICAgIG5vcm1hbGl6ZWRWYWx1ZSA9IGdldFNjaGVtYURldGVybWluZWRJRChhdHRyaWJ1dGVzLCBpKTsKLSAgICAgICAgICAgICAgICBpZiAobm9ybWFsaXplZFZhbHVlICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgLy8gMi4gSWYgYW4gZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIGhhcyBhbiBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0gYW1vbmcKLSAgICAgICAgICAgICAgICAvLyBpdHMgW2NoaWxkcmVuXSB0aGF0IGlzIGEgc2NoZW1hLWRldGVybWluZWQgSUQsIHRoZW4gaXQgaXMgaWRlbnRpZmllZCBieQotICAgICAgICAgICAgICAgIC8vIHRoZSB2YWx1ZSBvZiB0aGF0IGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSdzIFtzY2hlbWEgbm9ybWFsaXplZCB2YWx1ZV0gcHJvcGVydHk7Ci0gICAgICAgICAgICAgICAgLy8gPz8/Ci0gICAgICAgICAgICAgICAgbm9ybWFsaXplZFZhbHVlID0gZ2V0Q2hpbGRyZW5TY2hlbWFEZXRlcm1pbmVkSUQoYXR0cmlidXRlcywgaSk7Ci0gICAgICAgICAgICAgICAgaWYgKG5vcm1hbGl6ZWRWYWx1ZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8vIDMuIElmIGFuIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSBoYXMgYW4gYXR0cmlidXRlIGluZm9ybWF0aW9uIGl0ZW0gYW1vbmcKLSAgICAgICAgICAgICAgICAvLyBpdHMgW2F0dHJpYnV0ZXNdIHRoYXQgaXMgYSBEVEQtZGV0ZXJtaW5lZCBJRCwgdGhlbiBpdCBpcyBpZGVudGlmaWVkIGJ5IHRoZQotICAgICAgICAgICAgICAgIC8vIHZhbHVlIG9mIHRoYXQgYXR0cmlidXRlIGluZm9ybWF0aW9uIGl0ZW0ncyBbbm9ybWFsaXplZCB2YWx1ZV0gcHJvcGVydHkuCi0gICAgICAgICAgICAgICAgLy8gQW4gYXR0cmlidXRlIGluZm9ybWF0aW9uIGl0ZW0gaXMgYSBEVEQtZGV0ZXJtaW5lZCBJRCBpZiBhbmQgb25seSBpZiBpdCBoYXMKLSAgICAgICAgICAgICAgICAvLyBhIFt0eXBlIGRlZmluaXRpb25dIHByb3BlcnR5IHdob3NlIHZhbHVlIGlzIGVxdWFsIHRvIElELgotICAgICAgICAgICAgICAgIG5vcm1hbGl6ZWRWYWx1ZSA9IGdldERURERldGVybWluZWRJRChhdHRyaWJ1dGVzLCBpKTsKLSAgICAgICAgICAgICAgICBpZiAobm9ybWFsaXplZFZhbHVlICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIC8vIDQuIE5vIGV4dGVybmFsbHkgZGV0ZXJtaW5lZCBJRCdzCi0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAobm9ybWFsaXplZFZhbHVlICE9IG51bGwKLSAgICAgICAgICAgICAgICAmJiBub3JtYWxpemVkVmFsdWUuZXF1YWxzKGZTaG9ydEhhbmRQb2ludGVyKSkgewotICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmVydHVybnMgdGhlIERURCBkZXRlcm1pbmUtSUQKLSAgICAgKgotICAgICAqIEBwYXJhbSBhdHRyaWJ1dGVzCi0gICAgICogQHBhcmFtIGluZGV4Ci0gICAgICogQHJldHVybiBTdHJpbmcKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0RFRERGV0ZXJtaW5lZElEKFhNTEF0dHJpYnV0ZXMgYXR0cmlidXRlcywgaW50IGluZGV4KQotICAgIHRocm93cyBYTklFeGNlcHRpb24gewotCi0gICAgICAgIGlmIChhdHRyaWJ1dGVzLmdldFR5cGUoaW5kZXgpLmVxdWFscygiSUQiKSkgewotICAgICAgICAgICAgcmV0dXJuIGF0dHJpYnV0ZXMuZ2V0VmFsdWUoaW5kZXgpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIHNjaGVtYS1kZXRlcm1pbmVkLUlELgotICAgICAqCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYXR0cmlidXRlcwotICAgICAqIEBwYXJhbSBpbmRleAotICAgICAqIEByZXR1cm4gQSBTdHJpbmcgY29udGFpbmluZyB0aGUgc2NoZW1hLWRldGVybWluZWQgSUQuCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFNjaGVtYURldGVybWluZWRJRChYTUxBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMsIGludCBpbmRleCkKLSAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgQXVnbWVudGF0aW9ucyBhdWdzID0gYXR0cmlidXRlcy5nZXRBdWdtZW50YXRpb25zKGluZGV4KTsKLSAgICAgICAgQXR0cmlidXRlUFNWSSBhdHRyUFNWSSA9IChBdHRyaWJ1dGVQU1ZJKSBhdWdzCi0gICAgICAgIC5nZXRJdGVtKENvbnN0YW50cy5BVFRSSUJVVEVfUFNWSSk7Ci0KLSAgICAgICAgaWYgKGF0dHJQU1ZJICE9IG51bGwpIHsKLSAgICAgICAgICAgIC8vIEFuIGVsZW1lbnQgb3IgYXR0cmlidXRlIGluZm9ybWF0aW9uIGl0ZW0gaXMgYSBzY2hlbWEtZGV0ZXJtaW5lZAotICAgICAgICAgICAgLy8gSUQgaWYgYW5kIG9ubHkgaWYgb25lIG9mIHRoZSBmb2xsb3dpbmcgaXMgdHJ1ZTpdCi0KLSAgICAgICAgICAgIC8vIDEuIEl0IGhhcyBhIFttZW1iZXIgdHlwZSBkZWZpbml0aW9uXSBvciBbdHlwZSBkZWZpbml0aW9uXSBwcm9wZXJ0eQotICAgICAgICAgICAgLy8gd2hvc2UgdmFsdWUgaW4gdHVybiBoYXMgW25hbWVdIGVxdWFsIHRvIElEIGFuZCBbdGFyZ2V0IG5hbWVzcGFjZV0KLSAgICAgICAgICAgIC8vIGVxdWFsIHRvIGh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hOwotCi0gICAgICAgICAgICAvLyAyLiBJdCBoYXMgYSBbYmFzZSB0eXBlIGRlZmluaXRpb25dIHdob3NlIHZhbHVlIGhhcyB0aGF0IFtuYW1lXSBhbmQgW3RhcmdldCBuYW1lc3BhY2VdOwotCi0gICAgICAgICAgICAvLyAzLiBJdCBoYXMgYSBbYmFzZSB0eXBlIGRlZmluaXRpb25dIHdob3NlIHZhbHVlIGhhcyBhIFtiYXNlIHR5cGUgZGVmaW5pdGlvbl0KLSAgICAgICAgICAgIC8vIHdob3NlIHZhbHVlIGhhcyB0aGF0IFtuYW1lXSBhbmQgW3RhcmdldCBuYW1lc3BhY2VdLCBhbmQgc28gb24gZm9sbG93aW5nCi0gICAgICAgICAgICAvLyB0aGUgW2Jhc2UgdHlwZSBkZWZpbml0aW9uXSBwcm9wZXJ0eSByZWN1cnNpdmVseTsKLQotICAgICAgICAgICAgWFNUeXBlRGVmaW5pdGlvbiB0eXBlRGVmID0gYXR0clBTVkkuZ2V0TWVtYmVyVHlwZURlZmluaXRpb24oKTsKLSAgICAgICAgICAgIGlmICh0eXBlRGVmICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICB0eXBlRGVmID0gYXR0clBTVkkuZ2V0VHlwZURlZmluaXRpb24oKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIGlmICh0eXBlRGVmICE9IG51bGwgJiYgKChYU1NpbXBsZVR5cGUpIHR5cGVEZWYpLmlzSURUeXBlKCkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gYXR0clBTVkkuZ2V0U2NoZW1hTm9ybWFsaXplZFZhbHVlKCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIDQgJiA1IE5BCi0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBOb3QgcXVpdGUgc3VyZSBob3cgdGhpcyBjYW4gYmUgY29ycmVjdGx5IGltcGxlbWVudGVkLgotICAgICAqCi0gICAgICogQHBhcmFtIGF0dHJpYnV0ZXMKLSAgICAgKiBAcGFyYW0gaW5kZXgKLSAgICAgKiBAcmV0dXJuIFN0cmluZyAtIFdlIHJldHVybiBudWxsIHNpbmNlIHdlIGN1cnJlbmx5IGRvIG5vdCBzdXBwcnQgdGhpcy4KLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q2hpbGRyZW5TY2hlbWFEZXRlcm1pbmVkSUQoWE1MQXR0cmlidXRlcyBhdHRyaWJ1dGVzLAotICAgICAgICAgICAgaW50IGluZGV4KSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICoKLSAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHBvaW50ZXIuWFBvaW50ZXJQYXJ0I2lzRnJhZ21lbnRSZXNvbHZlZCgpCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNGcmFnbWVudFJlc29sdmVkKCkgewotICAgICAgICByZXR1cm4gZklzRnJhZ21lbnRSZXNvbHZlZDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKgotICAgICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cG9pbnRlci5YUG9pbnRlclBhcnQjaXNDaGlsZEZyYWdtZW50UmVzb2x2ZWQoKQotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzQ2hpbGRGcmFnbWVudFJlc29sdmVkKCkgewotICAgICAgICByZXR1cm4gZklzRnJhZ21lbnRSZXNvbHZlZCAmICggZk1hdGNoaW5nQ2hpbGRDb3VudCA+ICAwKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSBTaG9ydEhhbmQgcG9pbnRlcgotICAgICAqCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhwb2ludGVyLlhQb2ludGVyUGFydCNnZXRTY2hlbWVOYW1lKCkKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFNjaGVtZU5hbWUoKSB7Ci0gICAgICAgIHJldHVybiBmU2hvcnRIYW5kUG9pbnRlcjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHBvaW50ZXIuWFBvaW50ZXJQYXJ0I2dldFNjaGVtZURhdGEoKQotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0U2NoZW1lRGF0YSgpIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhwb2ludGVyLlhQb2ludGVyUGFydCNzZXRTY2hlbWVOYW1lKGphdmEubGFuZy5TdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0U2NoZW1lTmFtZShTdHJpbmcgc2NoZW1lTmFtZSkgewotICAgICAgICBmU2hvcnRIYW5kUG9pbnRlciA9IHNjaGVtZU5hbWU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhwb2ludGVyLlhQb2ludGVyUGFydCNzZXRTY2hlbWVEYXRhKGphdmEubGFuZy5TdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0U2NoZW1lRGF0YShTdHJpbmcgc2NoZW1lRGF0YSkgewotICAgICAgICAvLyBOQQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3hwb2ludGVyL1hQb2ludGVyRXJyb3JIYW5kbGVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94cG9pbnRlci9YUG9pbnRlckVycm9ySGFuZGxlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlMWE5NzFmLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3hwb2ludGVyL1hQb2ludGVyRXJyb3JIYW5kbGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMTUgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHBvaW50ZXI7Ci0KLWltcG9ydCBqYXZhLmlvLlByaW50V3JpdGVyOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE5JRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxFcnJvckhhbmRsZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTFBhcnNlRXhjZXB0aW9uOwotCi0vKioKLSAqIFRoZSBEZWZhdWx0IFhQb2ludGVyIGVycm9yIGhhbmRsZXIgdXNlZCBieSB0aGUgWEluY2x1ZGUgaW1wbGVtZW50YXRpb24uCi0gKiBYUG9pbnRlciBlcnJvcidzIGFyZSB0aHJvd24gc28gdGhhdCB0aGV5IG1heSBiZSBjYXVnaHQgYnkgdGhlIFhJbmNsdWRlCi0gKiBpbXBsZW1lbnRhdGlvbiBhbmQgcmVwb3J0ZWQgYXMgcmVzb3VyY2UgZXJyb3JzLgotICoKLSAqLwotY2xhc3MgWFBvaW50ZXJFcnJvckhhbmRsZXIgaW1wbGVtZW50cyBYTUxFcnJvckhhbmRsZXIgewotCi0gICAgLy8KLSAgICAvLyBEYXRhCi0gICAgLy8KLQotICAgIC8qKiBQcmludCB3cml0ZXIuICovCi0gICAgcHJvdGVjdGVkIFByaW50V3JpdGVyIGZPdXQ7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0cnVjdG9ycwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RzIGFuIGVycm9yIGhhbmRsZXIgdGhhdCBwcmludHMgZXJyb3IgbWVzc2FnZXMgdG8KLSAgICAgKiA8Y29kZT5TeXN0ZW0uZXJyPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFBvaW50ZXJFcnJvckhhbmRsZXIoKSB7Ci0gICAgICAgIHRoaXMobmV3IFByaW50V3JpdGVyKFN5c3RlbS5lcnIpKTsKLSAgICB9IC8vIDxpbml0PigpCi0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RzIGFuIGVycm9yIGhhbmRsZXIgdGhhdCBwcmludHMgZXJyb3IgbWVzc2FnZXMgdG8gdGhlCi0gICAgICogc3BlY2lmaWVkIDxjb2RlPlByaW50V3JpdGVyPC9jb2RlLgotICAgICAqLwotICAgIHB1YmxpYyBYUG9pbnRlckVycm9ySGFuZGxlcihQcmludFdyaXRlciBvdXQpIHsKLSAgICAgICAgZk91dCA9IG91dDsKLSAgICB9IC8vIDxpbml0PihQcmludFdyaXRlcikKLQotICAgIC8vCi0gICAgLy8gRXJyb3JIYW5kbGVyIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqIFdhcm5pbmcuICovCi0gICAgcHVibGljIHZvaWQgd2FybmluZyhTdHJpbmcgZG9tYWluLCBTdHJpbmcga2V5LCBYTUxQYXJzZUV4Y2VwdGlvbiBleCkKLSAgICAgICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBwcmludEVycm9yKCJXYXJuaW5nIiwgZXgpOwotICAgIH0gLy8gd2FybmluZyhYTUxQYXJzZUV4Y2VwdGlvbikKLQotICAgIC8qKiBFcnJvci4gKi8KLSAgICBwdWJsaWMgdm9pZCBlcnJvcihTdHJpbmcgZG9tYWluLCBTdHJpbmcga2V5LCBYTUxQYXJzZUV4Y2VwdGlvbiBleCkKLSAgICAgICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBwcmludEVycm9yKCJFcnJvciIsIGV4KTsKLSAgICAgICAgLy90aHJvdyBleDsKLSAgICB9IC8vIGVycm9yKFhNTFBhcnNlRXhjZXB0aW9uKQotCi0gICAgLyoqIEZhdGFsIGVycm9yLiAqLwotICAgIHB1YmxpYyB2b2lkIGZhdGFsRXJyb3IoU3RyaW5nIGRvbWFpbiwgU3RyaW5nIGtleSwgWE1MUGFyc2VFeGNlcHRpb24gZXgpCi0gICAgICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgcHJpbnRFcnJvcigiRmF0YWwgRXJyb3IiLCBleCk7Ci0gICAgICAgIHRocm93IGV4OwotICAgIH0gLy8gZmF0YWxFcnJvcihYTUxQYXJzZUV4Y2VwdGlvbikKLQotICAgIC8vCi0gICAgLy8gUHJpdmF0ZSBtZXRob2RzCi0gICAgLy8KLQotICAgIC8qKiBQcmludHMgdGhlIGVycm9yIG1lc3NhZ2UuICovCi0gICAgcHJpdmF0ZSB2b2lkIHByaW50RXJyb3IoU3RyaW5nIHR5cGUsIFhNTFBhcnNlRXhjZXB0aW9uIGV4KSB7Ci0KLSAgICAgICAgZk91dC5wcmludCgiWyIpOwotICAgICAgICBmT3V0LnByaW50KHR5cGUpOwotICAgICAgICBmT3V0LnByaW50KCJdICIpOwotICAgICAgICBTdHJpbmcgc3lzdGVtSWQgPSBleC5nZXRFeHBhbmRlZFN5c3RlbUlkKCk7Ci0gICAgICAgIGlmIChzeXN0ZW1JZCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpbnQgaW5kZXggPSBzeXN0ZW1JZC5sYXN0SW5kZXhPZignLycpOwotICAgICAgICAgICAgaWYgKGluZGV4ICE9IC0xKQotICAgICAgICAgICAgICAgIHN5c3RlbUlkID0gc3lzdGVtSWQuc3Vic3RyaW5nKGluZGV4ICsgMSk7Ci0gICAgICAgICAgICBmT3V0LnByaW50KHN5c3RlbUlkKTsKLSAgICAgICAgfQotICAgICAgICBmT3V0LnByaW50KCc6Jyk7Ci0gICAgICAgIGZPdXQucHJpbnQoZXguZ2V0TGluZU51bWJlcigpKTsKLSAgICAgICAgZk91dC5wcmludCgnOicpOwotICAgICAgICBmT3V0LnByaW50KGV4LmdldENvbHVtbk51bWJlcigpKTsKLSAgICAgICAgZk91dC5wcmludCgiOiAiKTsKLSAgICAgICAgZk91dC5wcmludChleC5nZXRNZXNzYWdlKCkpOwotICAgICAgICBmT3V0LnByaW50bG4oKTsKLSAgICAgICAgZk91dC5mbHVzaCgpOwotCi0gICAgfSAvLyBwcmludEVycm9yKFN0cmluZyxTQVhQYXJzZUV4Y2VwdGlvbikKLQotfSAvLyBjbGFzcyBEZWZhdWx0RXJyb3JIYW5kbGVyCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94cG9pbnRlci9YUG9pbnRlckhhbmRsZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3hwb2ludGVyL1hQb2ludGVySGFuZGxlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzMGI3NTYzLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3hwb2ludGVyL1hQb2ludGVySGFuZGxlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTI0OCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cG9pbnRlcjsKLQotaW1wb3J0IGphdmEudXRpbC5IYXNodGFibGU7Ci1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5Db25zdGFudHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLlhNTEVycm9yUmVwb3J0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlN5bWJvbFRhYmxlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5YTUxDaGFyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5YTUxTeW1ib2xzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueGluY2x1ZGUuWEluY2x1ZGVIYW5kbGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueGluY2x1ZGUuWEluY2x1ZGVOYW1lc3BhY2VTdXBwb3J0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLkF1Z21lbnRhdGlvbnM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuUU5hbWU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MQXR0cmlidXRlczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxTdHJpbmc7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE5JRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxFcnJvckhhbmRsZXI7Ci0KLS8qKgotICogPHA+Ci0gKiBUaGlzIGlzIGEgcGlwZWxpbmUgY29tcG9uZW50IHdoaWNoIGV4dGVuZHMgdGhlIFhJbmNsdWRlSGFuZGxlciB0byBwZXJmb3JtCi0gKiBYUG9pbnRlciBzcGVjaWZpYyBwcm9jZXNzaW5nIHNwZWNpZmllZCBpbiB0aGUgVzNDIFhQb2ludGVyRnJhbWV3b3JrIGFuZAotICogZWxlbWVudCgpIFNjaGVtZSBSZWNvbW1lbmRhdGlvbnMuCi0gKiA8L3A+Ci0gKgotICogPHA+Ci0gKiBUaGlzIGNvbXBvbmVudCBhbmFseXplcyBlYWNoIGV2ZW50IGluIHRoZSBwaXBlbGluZSwgbG9va2luZyBmb3IgYW4gZWxlbWVudAotICogdGhhdCBtYXRjaGVzIGEgUG9pbnRlclBhcnQgaW4gdGhlIHBhcmVudCBYSW5jbHVkZSBlbGVtZW50J3MgeHBvaW50ZXIgYXR0cmlidXRlCi0gKiB2YWx1ZS4gIElmIHRoZSBtYXRjaCBzdWNjZWVkcywgYWxsIGNoaWxkcmVuIGFyZSBwYXNzZWQgYnkgdGhpcyBjb21wb25lbnQuCi0gKiA8L3A+Ci0gKgotICogPHA+Ci0gKiBTZWUgdGhlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hwdHItZnJhbWV3b3JrLy8iPlhQb2ludGVyIEZyYW1ld29yayBSZWNvbW1lbmRhdGlvbjwvYT4gZm9yCi0gKiBtb3JlIGluZm9ybWF0aW9uIG9uIHRoZSBYUG9pbnRlciBGcmFtZXdvcmsgYW5kIFNob3J0SGFuZCBQb2ludGVycy4KLSAqIFNlZSB0aGUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHB0ci1lbGVtZW50LyI+WFBvaW50ZXIgZWxlbWVudCgpIFNjaGVtZSBSZWNvbW1lbmRhdGlvbjwvYT4gZm9yCi0gKiBtb3JlIGluZm9ybWF0aW9uIG9uIHRoZSBYUG9pbnRlciBlbGVtZW50KCkgU2NoZW1lLgotICogPC9wPgotICoKLSAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAqCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBYUG9pbnRlckhhbmRsZXIgZXh0ZW5kcyBYSW5jbHVkZUhhbmRsZXIgaW1wbGVtZW50cwotICAgICAgICBYUG9pbnRlclByb2Nlc3NvciB7Ci0KLSAgICAvLyBGaWVsZHMKLSAgICAvLyBBIFZlY3RvciBvZiBYUG9pbnRlclBhcnRzCi0gICAgcHJvdGVjdGVkIFZlY3RvciBmWFBvaW50ZXJQYXJ0cyA9IG51bGw7Ci0KLSAgICAvLyBUaGUgY3VycmVudCBYUG9pbnRlclBhcnQKLSAgICBwcm90ZWN0ZWQgWFBvaW50ZXJQYXJ0IGZYUG9pbnRlclBhcnQgPSBudWxsOwotCi0gICAgLy8gSGFzIHRoZSBmWFBvaW50ZXJQYXJ0IHJlc29sdmVkIHN1Y2Nlc3NmdWxseQotICAgIHByb3RlY3RlZCBib29sZWFuIGZGb3VuZE1hdGNoaW5nUHRyUGFydCA9IGZhbHNlOwotCi0gICAgLy8gVGhlIFhQb2ludGVyIEVycm9yIHJlcG9ydGVyCi0gICAgcHJvdGVjdGVkIFhNTEVycm9yUmVwb3J0ZXIgZlhQb2ludGVyRXJyb3JSZXBvcnRlcjsKLQotICAgIC8vIFRoZSBYUG9pbnRlciBFcnJvciBIYW5kbGVyCi0gICAgcHJvdGVjdGVkIFhNTEVycm9ySGFuZGxlciBmRXJyb3JIYW5kbGVyOwotCi0gICAgLy8gWFBvaW50ZXJGcmFtZXdvcmsgc3ltYm9sIHRhYmxlCi0gICAgcHJvdGVjdGVkIFN5bWJvbFRhYmxlIGZTeW1ib2xUYWJsZSA9IG51bGw7Ci0KLSAgICAvLyBTdXBwb3J0ZWQgc2NoZW1lcwotICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIEVMRU1FTlRfU0NIRU1FX05BTUUgPSAiZWxlbWVudCI7Ci0KLSAgIC8vIEhhcyB0aGUgWFBvaW50ZXIgcmVzb2x2ZWQgdGhlIHN1YnJlc291cmNlCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZklzWFBvaW50ZXJSZXNvbHZlZCA9IGZhbHNlOwotCi0gICAgLy8gRml4dXAgeG1sOmJhc2UgYW5kIHhtbDpsYW5nIGF0dHJpYnV0ZXMKLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBmRml4dXBCYXNlID0gZmFsc2U7Ci0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZkZpeHVwTGFuZyA9IGZhbHNlOwotCi0gICAgLy8gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0KLSAgICAvKioKLSAgICAgKgotICAgICAqLwotICAgIHB1YmxpYyBYUG9pbnRlckhhbmRsZXIoKSB7Ci0gICAgICAgIHN1cGVyKCk7Ci0KLSAgICAgICAgZlhQb2ludGVyUGFydHMgPSBuZXcgVmVjdG9yKCk7Ci0gICAgICAgIGZTeW1ib2xUYWJsZSA9IG5ldyBTeW1ib2xUYWJsZSgpOwotICAgIH0KLQotICAgIHB1YmxpYyBYUG9pbnRlckhhbmRsZXIoU3ltYm9sVGFibGUgc3ltYm9sVGFibGUsCi0gICAgICAgICAgICBYTUxFcnJvckhhbmRsZXIgZXJyb3JIYW5kbGVyLCBYTUxFcnJvclJlcG9ydGVyIGVycm9yUmVwb3J0ZXIpIHsKLSAgICAgICAgc3VwZXIoKTsKLQotICAgICAgICBmWFBvaW50ZXJQYXJ0cyA9IG5ldyBWZWN0b3IoKTsKLSAgICAgICAgZlN5bWJvbFRhYmxlID0gc3ltYm9sVGFibGU7Ci0gICAgICAgIGZFcnJvckhhbmRsZXIgPSBlcnJvckhhbmRsZXI7Ci0gICAgICAgIGZYUG9pbnRlckVycm9yUmVwb3J0ZXIgPSBlcnJvclJlcG9ydGVyOwotICAgICAgICAvL2ZFcnJvclJlcG9ydGVyID0gZXJyb3JSZXBvcnRlcjsgLy8gVGhlIFhJbmNsdWRlIEVycm9yUmVwb3J0ZXIKLSAgICB9Ci0KLSAgICAvLyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLSAgICAvLyAgSW1wbGVtZW50YXRpb24gb2YgdGhlIFhQb2ludGVyUHJvY2Vzc29yIGludGVyZmFjZS4KLSAgICAvLyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLQotICAgIC8qKgotICAgICAqIFBhcnNlcyB0aGUgWFBvaW50ZXIgZnJhbWV3b3JrIGV4cHJlc3Npb24gYW5kIGRlbGVnYXRlcyBzY2hlbWUgc3BlY2lmaWMgcGFyc2luZy4KLSAgICAgKgotICAgICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cG9pbnRlci5YUG9pbnRlclByb2Nlc3NvciNwYXJzZVhQb2ludGVyKGphdmEubGFuZy5TdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcGFyc2VYUG9pbnRlcihTdHJpbmcgeHBvaW50ZXIpIHRocm93cyBYTklFeGNlcHRpb24gewotCi0gICAgICAgIC8vIEluaXRpYWxpemUKLSAgICAgICAgaW5pdCgpOwotCi0gICAgICAgIC8vIHRva2VucwotICAgICAgICBmaW5hbCBUb2tlbnMgdG9rZW5zID0gbmV3IFRva2VucyhmU3ltYm9sVGFibGUpOwotCi0gICAgICAgIC8vIHNjYW5uZXIKLSAgICAgICAgU2Nhbm5lciBzY2FubmVyID0gbmV3IFNjYW5uZXIoZlN5bWJvbFRhYmxlKSB7Ci0gICAgICAgICAgICBwcm90ZWN0ZWQgdm9pZCBhZGRUb2tlbihUb2tlbnMgdG9rZW5zLCBpbnQgdG9rZW4pCi0gICAgICAgICAgICAgICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICAgICAgICAgIGlmICh0b2tlbiA9PSBUb2tlbnMuWFBUUlRPS0VOX09QRU5fUEFSRU4KLSAgICAgICAgICAgICAgICAgICAgICAgIHx8IHRva2VuID09IFRva2Vucy5YUFRSVE9LRU5fQ0xPU0VfUEFSRU4KLSAgICAgICAgICAgICAgICAgICAgICAgIHx8IHRva2VuID09IFRva2Vucy5YUFRSVE9LRU5fU0NIRU1FTkFNRQotICAgICAgICAgICAgICAgICAgICAgICAgfHwgdG9rZW4gPT0gVG9rZW5zLlhQVFJUT0tFTl9TQ0hFTUVEQVRBCi0gICAgICAgICAgICAgICAgICAgICAgICB8fCB0b2tlbiA9PSBUb2tlbnMuWFBUUlRPS0VOX1NIT1JUSEFORCkgewotICAgICAgICAgICAgICAgICAgICBzdXBlci5hZGRUb2tlbih0b2tlbnMsIHRva2VuKTsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICByZXBvcnRFcnJvcigiSW52YWxpZFhQb2ludGVyVG9rZW4iLCBuZXcgT2JqZWN0W10geyB0b2tlbnMKLSAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRUb2tlblN0cmluZyh0b2tlbikgfSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH07Ci0KLSAgICAgICAgLy8gc2NhbiB0aGUgWFBvaW50ZXIgZXhwcmVzc2lvbgotICAgICAgICBpbnQgbGVuZ3RoID0geHBvaW50ZXIubGVuZ3RoKCk7Ci0gICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IHNjYW5uZXIuc2NhbkV4cHIoZlN5bWJvbFRhYmxlLCB0b2tlbnMsIHhwb2ludGVyLCAwLAotICAgICAgICAgICAgICAgIGxlbmd0aCk7Ci0KLSAgICAgICAgaWYgKCFzdWNjZXNzKQotICAgICAgICAgICAgcmVwb3J0RXJyb3IoIkludmFsaWRYUG9pbnRlckV4cHJlc3Npb24iLCBuZXcgT2JqZWN0W10geyB4cG9pbnRlciB9KTsKLQotICAgICAgICB3aGlsZSAodG9rZW5zLmhhc01vcmUoKSkgewotICAgICAgICAgICAgaW50IHRva2VuID0gdG9rZW5zLm5leHRUb2tlbigpOwotCi0gICAgICAgICAgICBzd2l0Y2ggKHRva2VuKSB7Ci0gICAgICAgICAgICBjYXNlIFRva2Vucy5YUFRSVE9LRU5fU0hPUlRIQU5EOiB7Ci0KLSAgICAgICAgICAgICAgICAvLyBUaGUgc2hvcnRIYW5kIG5hbWUKLSAgICAgICAgICAgICAgICB0b2tlbiA9IHRva2Vucy5uZXh0VG9rZW4oKTsKLSAgICAgICAgICAgICAgICBTdHJpbmcgc2hvcnRIYW5kUG9pbnRlck5hbWUgPSB0b2tlbnMuZ2V0VG9rZW5TdHJpbmcodG9rZW4pOwotCi0gICAgICAgICAgICAgICAgaWYgKHNob3J0SGFuZFBvaW50ZXJOYW1lID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoIkludmFsaWRYUG9pbnRlckV4cHJlc3Npb24iLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7IHhwb2ludGVyIH0pOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIFhQb2ludGVyUGFydCBzaG9ydEhhbmRQb2ludGVyID0gbmV3IFNob3J0SGFuZFBvaW50ZXIoCi0gICAgICAgICAgICAgICAgICAgICAgICBmU3ltYm9sVGFibGUpOwotICAgICAgICAgICAgICAgIHNob3J0SGFuZFBvaW50ZXIuc2V0U2NoZW1lTmFtZShzaG9ydEhhbmRQb2ludGVyTmFtZSk7Ci0gICAgICAgICAgICAgICAgZlhQb2ludGVyUGFydHMuYWRkKHNob3J0SGFuZFBvaW50ZXIpOwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2FzZSBUb2tlbnMuWFBUUlRPS0VOX1NDSEVNRU5BTUU6IHsKLQotICAgICAgICAgICAgICAgIC8vIFJldHJlaXZlIHRoZSBsb2NhbCBuYW1lIGFuZCBwcmVmaXggdG8gZm9ybSB0aGUgc2NoZW1lIG5hbWUKLSAgICAgICAgICAgICAgICB0b2tlbiA9IHRva2Vucy5uZXh0VG9rZW4oKTsKLSAgICAgICAgICAgICAgICBTdHJpbmcgcHJlZml4ID0gdG9rZW5zLmdldFRva2VuU3RyaW5nKHRva2VuKTsKLSAgICAgICAgICAgICAgICB0b2tlbiA9IHRva2Vucy5uZXh0VG9rZW4oKTsKLSAgICAgICAgICAgICAgICBTdHJpbmcgbG9jYWxOYW1lID0gdG9rZW5zLmdldFRva2VuU3RyaW5nKHRva2VuKTsKLQotICAgICAgICAgICAgICAgIFN0cmluZyBzY2hlbWVOYW1lID0gcHJlZml4ICsgbG9jYWxOYW1lOwotCi0gICAgICAgICAgICAgICAgLy8gVGhlIG5leHQgY2hhcmFjdGVyIHNob3VsZCBiZSBhbiBvcGVuIHBhcmVudGhlc2lzCi0gICAgICAgICAgICAgICAgaW50IG9wZW5QYXJlbkNvdW50ID0gMDsKLSAgICAgICAgICAgICAgICBpbnQgY2xvc2VQYXJlbkNvdW50ID0gMDsKLQotICAgICAgICAgICAgICAgIHRva2VuID0gdG9rZW5zLm5leHRUb2tlbigpOwotICAgICAgICAgICAgICAgIFN0cmluZyBvcGVuUGFyZW4gPSB0b2tlbnMuZ2V0VG9rZW5TdHJpbmcodG9rZW4pOwotICAgICAgICAgICAgICAgIGlmIChvcGVuUGFyZW4gIT0gIlhQVFJUT0tFTl9PUEVOX1BBUkVOIikgewotCi0gICAgICAgICAgICAgICAgICAgIC8vIGNhbiBub3QgaGF2ZSBtb3JlIHRoYW4gb25lIFNob3J0SGFuZCBQb2ludGVyCi0gICAgICAgICAgICAgICAgICAgIGlmICh0b2tlbiA9PSBUb2tlbnMuWFBUUlRPS0VOX1NIT1JUSEFORCkgewotICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoIk11bHRpcGxlU2hvcnRIYW5kUG9pbnRlcnMiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyB4cG9pbnRlciB9KTsKLSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydEVycm9yKCJJbnZhbGlkWFBvaW50ZXJFeHByZXNzaW9uIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgeHBvaW50ZXIgfSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgb3BlblBhcmVuQ291bnQrKzsKLQotICAgICAgICAgICAgICAgIC8vIGZvbGxvd2VkIGJ5IHplcm8gb3IgbW9yZSAoIGFuZCAgdGhlIHNjaGVtZURhdGEKLSAgICAgICAgICAgICAgICBTdHJpbmcgc2NoZW1lRGF0YSA9IG51bGw7Ci0gICAgICAgICAgICAgICAgd2hpbGUgKHRva2Vucy5oYXNNb3JlKCkpIHsKLSAgICAgICAgICAgICAgICAgICAgdG9rZW4gPSB0b2tlbnMubmV4dFRva2VuKCk7Ci0gICAgICAgICAgICAgICAgICAgIHNjaGVtZURhdGEgPSB0b2tlbnMuZ2V0VG9rZW5TdHJpbmcodG9rZW4pOwotICAgICAgICAgICAgICAgICAgICBpZiAoc2NoZW1lRGF0YSAhPSAiWFBUUlRPS0VOX09QRU5fUEFSRU4iKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBvcGVuUGFyZW5Db3VudCsrOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB0b2tlbiA9IHRva2Vucy5uZXh0VG9rZW4oKTsKLSAgICAgICAgICAgICAgICBzY2hlbWVEYXRhID0gdG9rZW5zLmdldFRva2VuU3RyaW5nKHRva2VuKTsKLQotICAgICAgICAgICAgICAgIC8vIGZvbGxvd2VkIGJ5IHRoZSBzYW1lIG51bWJlciBvZiApCi0gICAgICAgICAgICAgICAgdG9rZW4gPSB0b2tlbnMubmV4dFRva2VuKCk7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIGNsb3NlUGFyZW4gPSB0b2tlbnMuZ2V0VG9rZW5TdHJpbmcodG9rZW4pOwotICAgICAgICAgICAgICAgIGlmIChjbG9zZVBhcmVuICE9ICJYUFRSVE9LRU5fQ0xPU0VfUEFSRU4iKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJlcG9ydEVycm9yKCJTY2hlbWVEYXRhTm90Rm9sbG93ZWRCeUNsb3NlUGFyZW50aGVzaXMiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7IHhwb2ludGVyIH0pOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBjbG9zZVBhcmVuQ291bnQrKzsKLQotICAgICAgICAgICAgICAgIHdoaWxlICh0b2tlbnMuaGFzTW9yZSgpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmICh0b2tlbnMuZ2V0VG9rZW5TdHJpbmcodG9rZW5zLnBlZWtUb2tlbigpKSAhPSAiWFBUUlRPS0VOX09QRU5fUEFSRU4iKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBjbG9zZVBhcmVuQ291bnQrKzsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyBjaGVjayBpZiB0aGUgbnVtYmVyIG9mIG9wZW4gcGFyZW50aGVzaXMgYXJlIGVxdWFsIHRvIHRoZSBudW1iZXIgb2YgY2xvc2UgcGFyZW50aGVzaXMKLSAgICAgICAgICAgICAgICBpZiAob3BlblBhcmVuQ291bnQgIT0gY2xvc2VQYXJlbkNvdW50KSB7Ci0gICAgICAgICAgICAgICAgICAgIHJlcG9ydEVycm9yKCJVbmJhbGFuY2VkUGFyZW50aGVzaXNJblhQb2ludGVyRXhwcmVzc2lvbiIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgeHBvaW50ZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgSW50ZWdlcihvcGVuUGFyZW5Db3VudCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgSW50ZWdlcihjbG9zZVBhcmVuQ291bnQpIH0pOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8vIFBlcmZvcm0gc2NoZW1lIHNwZWNpZmljIHBhcnNpbmcgb2YgdGhlIHBvaW50ZXIgcGFydAotICAgICAgICAgICAgICAgIGlmIChzY2hlbWVOYW1lLmVxdWFscyhFTEVNRU5UX1NDSEVNRV9OQU1FKSkgewotICAgICAgICAgICAgICAgICAgICBYUG9pbnRlclBhcnQgZWxlbWVudFNjaGVtZVBvaW50ZXIgPSBuZXcgRWxlbWVudFNjaGVtZVBvaW50ZXIoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZlN5bWJvbFRhYmxlLCBmRXJyb3JSZXBvcnRlcik7Ci0gICAgICAgICAgICAgICAgICAgIGVsZW1lbnRTY2hlbWVQb2ludGVyLnNldFNjaGVtZU5hbWUoc2NoZW1lTmFtZSk7Ci0gICAgICAgICAgICAgICAgICAgIGVsZW1lbnRTY2hlbWVQb2ludGVyLnNldFNjaGVtZURhdGEoc2NoZW1lRGF0YSk7Ci0KLSAgICAgICAgICAgICAgICAgICAgLy8gSWYgYW4gZXhjZXB0aW9uIG9jY3VycyB3aGlsZSBwYXJzaW5nIHRoZSBlbGVtZW50KCkgc2NoZW1lIGV4cHJlc3Npb24KLSAgICAgICAgICAgICAgICAgICAgLy8gaWdub3JlIGl0IGFuZCBtb3ZlIG9uIHRvIHRoZSBuZXh0IHBvaW50ZXIgcGFydAotICAgICAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudFNjaGVtZVBvaW50ZXIucGFyc2VYUG9pbnRlcihzY2hlbWVEYXRhKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZYUG9pbnRlclBhcnRzLmFkZChlbGVtZW50U2NoZW1lUG9pbnRlcik7Ci0gICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFhOSUV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBSZS10aHJvdyB0aGUgWFBvaW50ZXIgZWxlbWVudCgpIHNjaGVtZSBzeW50YXggZXJyb3IuCi0gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWE5JRXhjZXB0aW9uIChlKTsKLSAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gPz8/PwotICAgICAgICAgICAgICAgICAgICByZXBvcnRXYXJuaW5nKCJTY2hlbWVVbnN1cHBvcnRlZCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgc2NoZW1lTmFtZSB9KTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGRlZmF1bHQ6Ci0gICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoIkludmFsaWRYUG9pbnRlckV4cHJlc3Npb24iLAotICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgeHBvaW50ZXIgfSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgIH0KLQotICAgIC8qKgotICAgICAqCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhwb2ludGVyLlhQb2ludGVyUHJvY2Vzc29yI3Jlc29sdmVYUG9pbnRlcihjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5RTmFtZSwgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MQXR0cmlidXRlcywgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuQXVnbWVudGF0aW9ucywgaW50IGV2ZW50KQotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIHJlc29sdmVYUG9pbnRlcihRTmFtZSBlbGVtZW50LCBYTUxBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMsCi0gICAgICAgICAgICBBdWdtZW50YXRpb25zIGF1Z3MsIGludCBldmVudCkgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIGJvb2xlYW4gcmVzb2x2ZWQgPSBmYWxzZTsKLQotICAgICAgICAvLyBUaGUgcmVzdWx0IG9mIHRoZSBmaXJzdCBwb2ludGVyIHBhcnQgd2hvc2UgZXZhbHVhdGlvbiBpZGVudGlmaWVzCi0gICAgICAgIC8vIG9uZSBvciBtb3JlIHN1YnJlc291cmNlcyBpcyByZXBvcnRlZCBieSB0aGUgWFBvaW50ZXIgcHJvY2Vzc29yIGFzIHRoZQotICAgICAgICAvLyByZXN1bHQgb2YgdGhlIHBvaW50ZXIgYXMgYSB3aG9sZSwgYW5kIGV2YWx1YXRpb24gc3RvcHMuCi0gICAgICAgIC8vIEluIG91ciBpbXBsZW1lbnRhdGlvbiwgdHlwaWNhbGx5IHRoZSBmaXJzdCB4cG9pbnRlciBzY2hlbWUgdGhhdAotICAgICAgICAvLyBtYXRjaGVzIGFuIGVsZW1lbnQgaXMgdGhlIGRvY3VtZW50IGlzIGNvbnNpZGVyZWQuCi0gICAgICAgIC8vIElmIHRoZSBwb2ludGVyIHBhcnQgcmVzb2x2ZWQgdGhlbiB1c2UgaXQsIGVsc2Ugc2VhcmNoIGZvciB0aGUgZnJhZ21lbnQKLSAgICAgICAgLy8gdXNpbmcgbmV4dCBwb2ludGVyIHBhcnQgZnJvbSBsZWYtcmlnaHQuCi0gICAgICAgIGlmICghZkZvdW5kTWF0Y2hpbmdQdHJQYXJ0KSB7Ci0KLSAgICAgICAgICAgIC8vIGZvciBlYWNoIGVsZW1lbnQsIGF0dGVtcHQgdG8gcmVzb2x2ZSBpdCBhZ2FpbnN0IGVhY2ggcG9pbnRlciBwYXJ0Ci0gICAgICAgICAgICAvLyBpbiB0aGUgWFBvaW50ZXIgZXhwcmVzc2lvbiB1bnRpbCBhIG1hdGNoaW5nIGVsZW1lbnQgaXMgZm91bmQuCi0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZYUG9pbnRlclBhcnRzLnNpemUoKTsgaSsrKSB7Ci0KLSAgICAgICAgICAgICAgICBmWFBvaW50ZXJQYXJ0ID0gKFhQb2ludGVyUGFydCkgZlhQb2ludGVyUGFydHMuZ2V0KGkpOwotCi0gICAgICAgICAgICAgICAgaWYgKGZYUG9pbnRlclBhcnQucmVzb2x2ZVhQb2ludGVyKGVsZW1lbnQsIGF0dHJpYnV0ZXMsIGF1Z3MsCi0gICAgICAgICAgICAgICAgICAgICAgICBldmVudCkpIHsKLSAgICAgICAgICAgICAgICAgICAgZkZvdW5kTWF0Y2hpbmdQdHJQYXJ0ID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZWQgPSB0cnVlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIGlmIChmWFBvaW50ZXJQYXJ0LnJlc29sdmVYUG9pbnRlcihlbGVtZW50LCBhdHRyaWJ1dGVzLCBhdWdzLCBldmVudCkpIHsKLSAgICAgICAgICAgICAgICByZXNvbHZlZCA9IHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoIWZJc1hQb2ludGVyUmVzb2x2ZWQpIHsKLSAgICAgICAgICAgIGZJc1hQb2ludGVyUmVzb2x2ZWQgPSByZXNvbHZlZDsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiByZXNvbHZlZDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIE5vZGUgZnJhZ21lbnQgaXMgcmVzb2x2ZWQuCi0gICAgICoKLSAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHBvaW50ZXIuWFBvaW50ZXJQcm9jZXNzb3IjaXNGcmFnbWVudFJlc29sdmVkKCkKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0ZyYWdtZW50UmVzb2x2ZWQoKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgYm9vbGVhbiByZXNvbHZlZCA9IChmWFBvaW50ZXJQYXJ0ICE9IG51bGwpID8gZlhQb2ludGVyUGFydC5pc0ZyYWdtZW50UmVzb2x2ZWQoKQotICAgICAgICAgICAgICAgIDogZmFsc2U7Ci0KLSAgICAgICAgaWYgKCFmSXNYUG9pbnRlclJlc29sdmVkKSB7Ci0gICAgICAgICAgICBmSXNYUG9pbnRlclJlc29sdmVkID0gcmVzb2x2ZWQ7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gcmVzb2x2ZWQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBYUG9pbnRlciBleHByZXNzaW9uIHJlc29sdmVzIHRvIGEgbm9uLWVsZW1lbnQgY2hpbGQKLSAgICAgKiBvZiB0aGUgY3VycmVudCByZXNvdXJjZSBmcmFnbWVudC4KLSAgICAgKgotICAgICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cG9pbnRlci5YUG9pbnRlclBhcnQjaXNDaGlsZEZyYWdtZW50UmVzb2x2ZWQoKQotICAgICAqCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNDaGlsZEZyYWdtZW50UmVzb2x2ZWQoKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgYm9vbGVhbiByZXNvbHZlZCA9IChmWFBvaW50ZXJQYXJ0ICE9IG51bGwpID8gZlhQb2ludGVyUGFydAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuaXNDaGlsZEZyYWdtZW50UmVzb2x2ZWQoKSA6IGZhbHNlOwotICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlZDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIFhQb2ludGVyIHN1Y2Nlc3NmdWxseSBmb3VuZCBhIHN1Yi1yZXNvdXJjZSAuCi0gICAgICoKLSAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHBvaW50ZXIuWFBvaW50ZXJQcm9jZXNzb3IjaXNGcmFnbWVudFJlc29sdmVkKCkKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc1hQb2ludGVyUmVzb2x2ZWQoKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgcmV0dXJuIGZJc1hQb2ludGVyUmVzb2x2ZWQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgcG9pbnRlciBwYXJ0IHVzZWQgdG8gcmVzb2x2ZSB0aGUgZG9jdW1lbnQgZnJhZ21lbnQuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFN0cmluZyAtIFRoZSBwb2ludGVyIHBhcnQgdXNlZCB0byByZXNvbHZlIHRoZSBkb2N1bWVudCBmcmFnbWVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFBvaW50ZXJQYXJ0IGdldFhQb2ludGVyUGFydCgpIHsKLSAgICAgICAgcmV0dXJuIGZYUG9pbnRlclBhcnQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmVwb3J0cyBYUG9pbnRlciBFcnJvcnMKLSAgICAgKgotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCByZXBvcnRFcnJvcihTdHJpbmcga2V5LCBPYmplY3RbXSBhcmd1bWVudHMpCi0gICAgICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgLyoKLSAgICAgICAgZlhQb2ludGVyRXJyb3JSZXBvcnRlci5yZXBvcnRFcnJvcigKLSAgICAgICAgICAgICAgICBYUG9pbnRlck1lc3NhZ2VGb3JtYXR0ZXIuWFBPSU5URVJfRE9NQUlOLCBrZXksIGFyZ3VtZW50cywKLSAgICAgICAgICAgICAgICBYTUxFcnJvclJlcG9ydGVyLlNFVkVSSVRZX0VSUk9SKTsKLSAgICAgICAgKi8KLSAgICAgICAgdGhyb3cgbmV3IFhOSUV4Y2VwdGlvbigoZkVycm9yUmVwb3J0ZXIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmdldE1lc3NhZ2VGb3JtYXR0ZXIoWFBvaW50ZXJNZXNzYWdlRm9ybWF0dGVyLlhQT0lOVEVSX0RPTUFJTikpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5mb3JtYXRNZXNzYWdlKGZFcnJvclJlcG9ydGVyLmdldExvY2FsZSgpLCBrZXksIGFyZ3VtZW50cykpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJlcG9ydHMgWFBvaW50ZXIgV2FybmluZ3MKLSAgICAgKgotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCByZXBvcnRXYXJuaW5nKFN0cmluZyBrZXksIE9iamVjdFtdIGFyZ3VtZW50cykKLSAgICAgICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBmWFBvaW50ZXJFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKAotICAgICAgICAgICAgICAgIFhQb2ludGVyTWVzc2FnZUZvcm1hdHRlci5YUE9JTlRFUl9ET01BSU4sIGtleSwgYXJndW1lbnRzLAotICAgICAgICAgICAgICAgIFhNTEVycm9yUmVwb3J0ZXIuU0VWRVJJVFlfV0FSTklORyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSW5pdGlhbGl6ZXMgZXJyb3IgaGFuZGxpbmcgb2JqZWN0cwotICAgICAqCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgaW5pdEVycm9yUmVwb3J0ZXIoKSB7Ci0gICAgICAgIGlmIChmWFBvaW50ZXJFcnJvclJlcG9ydGVyID09IG51bGwpIHsKLSAgICAgICAgICAgIGZYUG9pbnRlckVycm9yUmVwb3J0ZXIgPSBuZXcgWE1MRXJyb3JSZXBvcnRlcigpOwotICAgICAgICB9Ci0gICAgICAgIGlmIChmRXJyb3JIYW5kbGVyID09IG51bGwpIHsKLSAgICAgICAgICAgIGZFcnJvckhhbmRsZXIgPSBuZXcgWFBvaW50ZXJFcnJvckhhbmRsZXIoKTsKLSAgICAgICAgfQotICAgICAgICAvKgotICAgICAgICAgZlhQb2ludGVyRXJyb3JSZXBvcnRlci5zZXRQcm9wZXJ0eShDb25zdGFudHMuWEVSQ0VTX1BST1BFUlRZX1BSRUZJWAotICAgICAgICAgKyBDb25zdGFudHMuRVJST1JfSEFORExFUl9QUk9QRVJUWSwgZkVycm9ySGFuZGxlcik7Ci0gICAgICAgICAqLwotICAgICAgICBmWFBvaW50ZXJFcnJvclJlcG9ydGVyLnB1dE1lc3NhZ2VGb3JtYXR0ZXIoCi0gICAgICAgICAgICAgICAgWFBvaW50ZXJNZXNzYWdlRm9ybWF0dGVyLlhQT0lOVEVSX0RPTUFJTiwKLSAgICAgICAgICAgICAgICBuZXcgWFBvaW50ZXJNZXNzYWdlRm9ybWF0dGVyKCkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEluaXRpYWxpemVzIHRoZSBYUG9pbnRlciBQcm9jZXNzb3I7Ci0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgaW5pdCgpIHsKLSAgICAgICAgZlhQb2ludGVyUGFydHMuY2xlYXIoKTsKLSAgICAgICAgZlhQb2ludGVyUGFydCA9IG51bGw7Ci0gICAgICAgIGZGb3VuZE1hdGNoaW5nUHRyUGFydCA9IGZhbHNlOwotICAgICAgICBmSXNYUG9pbnRlclJlc29sdmVkID0gZmFsc2U7Ci0gICAgICAgIC8vZkZpeHVwQmFzZSA9IGZhbHNlOwotICAgICAgICAvL2ZGaXh1cExhbmcgPSBmYWxzZTsKLQotICAgICAgICBpbml0RXJyb3JSZXBvcnRlcigpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYSBWZWN0b3Igb2YgWFBvaW50ZXJQYXJ0IG9iamVjdHMKLSAgICAgKgotICAgICAqIEByZXR1cm4gQSBWZWN0b3Igb2YgWFBvaW50ZXJQYXJ0IG9iamVjdHMuCi0gICAgICovCi0gICAgcHVibGljIFZlY3RvciBnZXRQb2ludGVyUGFydHMoKSB7Ci0gICAgICAgIHJldHVybiBmWFBvaW50ZXJQYXJ0czsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBMaXN0IG9mIFhQb2ludGVyIEZyYW1ld29yayB0b2tlbnMuCi0gICAgICoKLSAgICAgKiBAeGVyY2VzLmludGVybmFsCi0gICAgICoKLSAgICAgKi8KLSAgICBwcml2YXRlIGZpbmFsIGNsYXNzIFRva2VucyB7Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFhQb2ludGVyIEZyYW1ld29yayB0b2tlbnMKLSAgICAgICAgICogWzFdIFBvaW50ZXIgICAgIDo6PSBTaG9ydGhhbmQgfCBTY2hlbWVCYXNlZAotICAgICAgICAgKiBbMl0gU2hvcnRoYW5kICAgOjo9IE5DTmFtZQotICAgICAgICAgKiBbM10gU2NoZW1lQmFzZWQgOjo9IFBvaW50ZXJQYXJ0IChTPyBQb2ludGVyUGFydCkqCi0gICAgICAgICAqIFs0XSBQb2ludGVyUGFydCA6Oj0gU2NoZW1lTmFtZSAnKCcgU2NoZW1lRGF0YSAnKScKLSAgICAgICAgICogWzVdIFNjaGVtZU5hbWUgIDo6PSBRTmFtZQotICAgICAgICAgKiBbNl0gU2NoZW1lRGF0YSAgOjo9IEVzY2FwZWREYXRhKgotICAgICAgICAgKiBbN10gRXNjYXBlZERhdGEgOjo9IE5vcm1hbENoYXIgfCAnXignIHwgJ14pJyB8ICdeXicgfCAnKCcgU2NoZW1lRGF0YSAnKScKLSAgICAgICAgICogWzhdIE5vcm1hbENoYXIgIDo6PSBVbmljb2RlQ2hhciAtIFsoKV5dCi0gICAgICAgICAqIFs5XSBVbmljb2RlQ2hhciA6Oj0gWyN4MC0jeDEwRkZGRl0KLSAgICAgICAgICoKLSAgICAgICAgICovCi0gICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBYUFRSVE9LRU5fT1BFTl9QQVJFTiA9IDAsCi0gICAgICAgICAgICAgICAgWFBUUlRPS0VOX0NMT1NFX1BBUkVOID0gMSwgWFBUUlRPS0VOX1NIT1JUSEFORCA9IDIsCi0gICAgICAgICAgICAgICAgWFBUUlRPS0VOX1NDSEVNRU5BTUUgPSAzLCBYUFRSVE9LRU5fU0NIRU1FREFUQSA9IDQ7Ci0KLSAgICAgICAgLy8gVG9rZW4gbmFtZXMKLSAgICAgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmdbXSBmZ1Rva2VuTmFtZXMgPSB7ICJYUFRSVE9LRU5fT1BFTl9QQVJFTiIsCi0gICAgICAgICAgICAgICAgIlhQVFJUT0tFTl9DTE9TRV9QQVJFTiIsICJYUFRSVE9LRU5fU0hPUlRIQU5EIiwKLSAgICAgICAgICAgICAgICAiWFBUUlRPS0VOX1NDSEVNRU5BTUUiLCAiWFBUUlRPS0VOX1NDSEVNRURBVEEiIH07Ci0KLSAgICAgICAgLy8gVG9rZW4gY291bnQKLSAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IElOSVRJQUxfVE9LRU5fQ09VTlQgPSAxIDw8IDg7Ci0KLSAgICAgICAgcHJpdmF0ZSBpbnRbXSBmVG9rZW5zID0gbmV3IGludFtJTklUSUFMX1RPS0VOX0NPVU5UXTsKLQotICAgICAgICBwcml2YXRlIGludCBmVG9rZW5Db3VudCA9IDA7Ci0KLSAgICAgICAgLy8gQ3VycmVudCB0b2tlbiBwb3NpdGlvbgotICAgICAgICBwcml2YXRlIGludCBmQ3VycmVudFRva2VuSW5kZXg7Ci0KLSAgICAgICAgcHJpdmF0ZSBTeW1ib2xUYWJsZSBmU3ltYm9sVGFibGU7Ci0KLSAgICAgICAgcHJpdmF0ZSBIYXNodGFibGUgZlRva2VuTmFtZXMgPSBuZXcgSGFzaHRhYmxlKCk7Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIENvbnN0cnVjdG9yCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBzeW1ib2xUYWJsZSBTeW1ib2xUYWJsZQotICAgICAgICAgKi8KLSAgICAgICAgcHJpdmF0ZSBUb2tlbnMoU3ltYm9sVGFibGUgc3ltYm9sVGFibGUpIHsKLSAgICAgICAgICAgIGZTeW1ib2xUYWJsZSA9IHN5bWJvbFRhYmxlOwotCi0gICAgICAgICAgICBmVG9rZW5OYW1lcy5wdXQobmV3IEludGVnZXIoWFBUUlRPS0VOX09QRU5fUEFSRU4pLAotICAgICAgICAgICAgICAgICAgICAiWFBUUlRPS0VOX09QRU5fUEFSRU4iKTsKLSAgICAgICAgICAgIGZUb2tlbk5hbWVzLnB1dChuZXcgSW50ZWdlcihYUFRSVE9LRU5fQ0xPU0VfUEFSRU4pLAotICAgICAgICAgICAgICAgICAgICAiWFBUUlRPS0VOX0NMT1NFX1BBUkVOIik7Ci0gICAgICAgICAgICBmVG9rZW5OYW1lcy5wdXQobmV3IEludGVnZXIoWFBUUlRPS0VOX1NIT1JUSEFORCksCi0gICAgICAgICAgICAgICAgICAgICJYUFRSVE9LRU5fU0hPUlRIQU5EIik7Ci0gICAgICAgICAgICBmVG9rZW5OYW1lcy5wdXQobmV3IEludGVnZXIoWFBUUlRPS0VOX1NDSEVNRU5BTUUpLAotICAgICAgICAgICAgICAgICAgICAiWFBUUlRPS0VOX1NDSEVNRU5BTUUiKTsKLSAgICAgICAgICAgIGZUb2tlbk5hbWVzLnB1dChuZXcgSW50ZWdlcihYUFRSVE9LRU5fU0NIRU1FREFUQSksCi0gICAgICAgICAgICAgICAgICAgICJYUFRSVE9LRU5fU0NIRU1FREFUQSIpOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFJldHVybnMgdGhlIHRva2VuIFN0cmluZwotICAgICAgICAgKiBAcGFyYW0gdG9rZW4gVGhlIGluZGV4IG9mIHRoZSB0b2tlbgotICAgICAgICAgKiBAcmV0dXJuIFN0cmluZyBUaGUgdG9rZW4gc3RyaW5nCi0gICAgICAgICAqLwotICAgICAgICBwcml2YXRlIFN0cmluZyBnZXRUb2tlblN0cmluZyhpbnQgdG9rZW4pIHsKLSAgICAgICAgICAgIHJldHVybiAoU3RyaW5nKSBmVG9rZW5OYW1lcy5nZXQobmV3IEludGVnZXIodG9rZW4pKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBBZGQgdGhlIHNwZWNpZmllZCBzdHJpbmcgYXMgYSB0b2tlbgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gdG9rZW4gVGhlIHRva2VuIHN0cmluZwotICAgICAgICAgKi8KLSAgICAgICAgcHJpdmF0ZSB2b2lkIGFkZFRva2VuKFN0cmluZyB0b2tlblN0cikgewotICAgICAgICAgICAgSW50ZWdlciB0b2tlbkludCA9IChJbnRlZ2VyKSBmVG9rZW5OYW1lcy5nZXQodG9rZW5TdHIpOwotICAgICAgICAgICAgaWYgKHRva2VuSW50ID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICB0b2tlbkludCA9IG5ldyBJbnRlZ2VyKGZUb2tlbk5hbWVzLnNpemUoKSk7Ci0gICAgICAgICAgICAgICAgZlRva2VuTmFtZXMucHV0KHRva2VuSW50LCB0b2tlblN0cik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBhZGRUb2tlbih0b2tlbkludC5pbnRWYWx1ZSgpKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBBZGQgdGhlIHNwZWNpZmllZCBpbnQgdG9rZW4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIHRva2VuIFRoZSBpbnQgc3BlY2lmeWluZyB0aGUgdG9rZW4KLSAgICAgICAgICovCi0gICAgICAgIHByaXZhdGUgdm9pZCBhZGRUb2tlbihpbnQgdG9rZW4pIHsKLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgZlRva2Vuc1tmVG9rZW5Db3VudF0gPSB0b2tlbjsKLSAgICAgICAgICAgIH0gY2F0Y2ggKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleCkgewotICAgICAgICAgICAgICAgIGludFtdIG9sZExpc3QgPSBmVG9rZW5zOwotICAgICAgICAgICAgICAgIGZUb2tlbnMgPSBuZXcgaW50W2ZUb2tlbkNvdW50IDw8IDFdOwotICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkob2xkTGlzdCwgMCwgZlRva2VucywgMCwgZlRva2VuQ291bnQpOwotICAgICAgICAgICAgICAgIGZUb2tlbnNbZlRva2VuQ291bnRdID0gdG9rZW47Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmVG9rZW5Db3VudCsrOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFJlc2V0cyB0aGUgY3VycmVudCBwb3NpdGlvbiB0byB0aGUgaGVhZCBvZiB0aGUgdG9rZW4gbGlzdC4KLSAgICAgICAgICovCi0gICAgICAgIHByaXZhdGUgdm9pZCByZXdpbmQoKSB7Ci0gICAgICAgICAgICBmQ3VycmVudFRva2VuSW5kZXggPSAwOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUge0BsaW5rICNnZXROZXh0VG9rZW4oKX0gbWV0aG9kCi0gICAgICAgICAqIHJldHVybnMgYSB2YWxpZCB0b2tlbi4KLSAgICAgICAgICovCi0gICAgICAgIHByaXZhdGUgYm9vbGVhbiBoYXNNb3JlKCkgewotICAgICAgICAgICAgcmV0dXJuIGZDdXJyZW50VG9rZW5JbmRleCA8IGZUb2tlbkNvdW50OwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIE9idGFpbnMgdGhlIHRva2VuIGF0IHRoZSBjdXJyZW50IHBvc2l0aW9uLCB0aGVuIGFkdmFuY2UKLSAgICAgICAgICogdGhlIGN1cnJlbnQgcG9zaXRpb24gYnkgb25lLgotICAgICAgICAgKgotICAgICAgICAgKiB0aHJvd3MgSWYgdGhlcmUncyBubyBzdWNoIG5leHQgdG9rZW4sIHRoaXMgbWV0aG9kIHRocm93cwotICAgICAgICAgKiA8dHQ+bmV3IFhOSUV4Y2VwdGlvbigiWFBvaW50ZXJQcm9jZXNzaW5nRXJyb3IiKTs8L3R0Pi4KLSAgICAgICAgICovCi0gICAgICAgIHByaXZhdGUgaW50IG5leHRUb2tlbigpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICAgICAgaWYgKGZDdXJyZW50VG9rZW5JbmRleCA9PSBmVG9rZW5Db3VudCkgewotICAgICAgICAgICAgICAgIHJlcG9ydEVycm9yKCJYUG9pbnRlclByb2Nlc3NpbmdFcnJvciIsIG51bGwpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIGZUb2tlbnNbZkN1cnJlbnRUb2tlbkluZGV4KytdOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIE9idGFpbnMgdGhlIHRva2VuIGF0IHRoZSBjdXJyZW50IHBvc2l0aW9uLCB3aXRob3V0IGFkdmFuY2luZwotICAgICAgICAgKiB0aGUgY3VycmVudCBwb3NpdGlvbi4KLSAgICAgICAgICoKLSAgICAgICAgICogSWYgdGhlcmUncyBubyBzdWNoIG5leHQgdG9rZW4sIHRoaXMgbWV0aG9kIHRocm93cwotICAgICAgICAgKiA8dHQ+bmV3IFhOSUV4Y2VwdGlvbigiWFBvaW50ZXJQcm9jZXNzaW5nRXJyb3IiKTs8L3R0Pi4KLSAgICAgICAgICovCi0gICAgICAgIHByaXZhdGUgaW50IHBlZWtUb2tlbigpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICAgICAgaWYgKGZDdXJyZW50VG9rZW5JbmRleCA9PSBmVG9rZW5Db3VudCkgewotICAgICAgICAgICAgICAgIHJlcG9ydEVycm9yKCJYUG9pbnRlclByb2Nlc3NpbmdFcnJvciIsIG51bGwpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIGZUb2tlbnNbZkN1cnJlbnRUb2tlbkluZGV4XTsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBPYnRhaW5zIHRoZSB0b2tlbiBhdCB0aGUgY3VycmVudCBwb3NpdGlvbiBhcyBhIFN0cmluZy4KLSAgICAgICAgICoKLSAgICAgICAgICogSWYgdGhlcmUncyBubyBjdXJyZW50IHRva2VuIG9yIGlmIHRoZSBjdXJyZW50IHRva2VuCi0gICAgICAgICAqIGlzIG5vdCBhIHN0cmluZyB0b2tlbiwgdGhpcyBtZXRob2QgdGhyb3dzCi0gICAgICAgICAqIElmIHRoZXJlJ3Mgbm8gc3VjaCBuZXh0IHRva2VuLCB0aGlzIG1ldGhvZCB0aHJvd3MKLSAgICAgICAgICogPHR0Pm5ldyBYTklFeGNlcHRpb24oIlhQb2ludGVyUHJvY2Vzc2luZ0Vycm9yIik7PC90dD4uCi0gICAgICAgICAqLwotICAgICAgICBwcml2YXRlIFN0cmluZyBuZXh0VG9rZW5Bc1N0cmluZygpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICAgICAgU3RyaW5nIHRva2VuU3RyaW50ID0gZ2V0VG9rZW5TdHJpbmcobmV4dFRva2VuKCkpOwotICAgICAgICAgICAgaWYgKHRva2VuU3RyaW50ID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICByZXBvcnRFcnJvcigiWFBvaW50ZXJQcm9jZXNzaW5nRXJyb3IiLCBudWxsKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiB0b2tlblN0cmludDsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqCi0gICAgICogVGhlIFhQb2ludGVyIGV4cHJlc3Npb24gc2Nhbm5lci4gIFNjYW5zIHRoZSBYUG9pbnRlciBmcmFtZXdvcmsgZXhwcmVzc2lvbi4KLSAgICAgKgotICAgICAqIEB4ZXJjZXMuaW50ZXJuYWwKLSAgICAgKgotICAgICAqLwotICAgIHByaXZhdGUgY2xhc3MgU2Nhbm5lciB7Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIDctYml0IEFTQ0lJIHN1YnNldAotICAgICAgICAgKgotICAgICAgICAgKiAgMCAgIDEgICAyICAgMyAgIDQgICA1ICAgNiAgIDcgICA4ICAgOSAgIEEgICBCICAgQyAgIEQgICBFICAgRgotICAgICAgICAgKiAgMCwgIDAsICAwLCAgMCwgIDAsICAwLCAgMCwgIDAsICAwLCBIVCwgTEYsICAwLCAgMCwgQ1IsICAwLCAgMCwgIC8vIDAKLSAgICAgICAgICogIDAsICAwLCAgMCwgIDAsICAwLCAgMCwgIDAsICAwLCAgMCwgIDAsICAwLCAgMCwgIDAsICAwLCAgMCwgIDAsICAvLyAxCi0gICAgICAgICAqIFNQLCAgISwgICIsICAjLCAgJCwgICUsICAmLCAgJywgICgsICApLCAgKiwgICssICAsLCAgLSwgIC4sICAvLCAgLy8gMgotICAgICAgICAgKiAgMCwgIDEsICAyLCAgMywgIDQsICA1LCAgNiwgIDcsICA4LCAgOSwgIDosICA7LCAgPCwgID0sICA+LCAgPywgIC8vIDMKLSAgICAgICAgICogIEAsICBBLCAgQiwgIEMsICBELCAgRSwgIEYsICBHLCAgSCwgIEksICBKLCAgSywgIEwsICBNLCAgTiwgIE8sICAvLyA0Ci0gICAgICAgICAqICBQLCAgUSwgIFIsICBTLCAgVCwgIFUsICBWLCAgVywgIFgsICBZLCAgWiwgIFssICBcLCAgXSwgIF4sICBfLCAgLy8gNQotICAgICAgICAgKiAgYCwgIGEsICBiLCAgYywgIGQsICBlLCAgZiwgIGcsICBoLCAgaSwgIGosICBrLCAgbCwgIG0sICBuLCAgbywgIC8vIDYKLSAgICAgICAgICogIHAsICBxLCAgciwgIHMsICB0LCAgdSwgIHYsICB3LCAgeCwgIHksICB6LCAgeywgIHwsICB9LCAgfiwgREVMICAvLyA3Ci0gICAgICAgICAqLwotICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlIENIQVJUWVBFX0lOVkFMSUQgPSAwLCAvLyBpbnZhbGlkIFhNTCBjaGFyYWN0ZXIKLSAgICAgICAgICAgICAgICBDSEFSVFlQRV9PVEhFUiA9IDEsIC8vIG5vdCBzcGVjaWFsIC0gb25lIG9mICIjJSY7P1xge31+IiBvciBERUwKLSAgICAgICAgICAgICAgICBDSEFSVFlQRV9XSElURVNQQUNFID0gMiwgLy8gb25lIG9mICJcdFxuXHIgIiAoMHgwOSwgMHgwQSwgMHgwRCwgMHgyMCkKLSAgICAgICAgICAgICAgICBDSEFSVFlQRV9DQVJSRVQgPSAzLCAvLyBeCi0gICAgICAgICAgICAgICAgQ0hBUlRZUEVfT1BFTl9QQVJFTiA9IDQsIC8vICcoJyAoMHgyOCkKLSAgICAgICAgICAgICAgICBDSEFSVFlQRV9DTE9TRV9QQVJFTiA9IDUsIC8vICcpJyAoMHgyOSkKLSAgICAgICAgICAgICAgICBDSEFSVFlQRV9NSU5VUyA9IDYsIC8vICctJyAoMHgyRCkKLSAgICAgICAgICAgICAgICBDSEFSVFlQRV9QRVJJT0QgPSA3LCAvLyAnLicgKDB4MkUpCi0gICAgICAgICAgICAgICAgQ0hBUlRZUEVfU0xBU0ggPSA4LCAvLyAnLycgKDB4MkYpCi0gICAgICAgICAgICAgICAgQ0hBUlRZUEVfRElHSVQgPSA5LCAvLyAnMCctJzknICgweDMwIHRvIDB4MzkpCi0gICAgICAgICAgICAgICAgQ0hBUlRZUEVfQ09MT04gPSAxMCwgLy8gJzonICgweDNBKQotICAgICAgICAgICAgICAgIENIQVJUWVBFX0VRVUFMID0gMTEsIC8vICc9JyAoMHgzRCkKLSAgICAgICAgICAgICAgICBDSEFSVFlQRV9MRVRURVIgPSAxMiwgLy8gJ0EnLSdaJyBvciAnYSctJ3onICgweDQxIHRvIDB4NUEgYW5kIDB4NjEgdG8gMHg3QSkKLSAgICAgICAgICAgICAgICBDSEFSVFlQRV9VTkRFUlNDT1JFID0gMTMsIC8vICdfJyAoMHg1RikKLSAgICAgICAgICAgICAgICBDSEFSVFlQRV9OT05BU0NJSSA9IDE0OyAvLyBOb24tQVNDSUkgVW5pY29kZSBjb2RlcG9pbnQgKD49IDB4ODApCi0KLSAgICAgICAgcHJpdmF0ZSBmaW5hbCBieXRlW10gZkFTQ0lJQ2hhck1hcCA9IHsgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMiwgMiwKLSAgICAgICAgICAgICAgICAwLCAwLCAyLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAotICAgICAgICAgICAgICAgIDIsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDQsIDUsIDEsIDEsIDEsIDYsIDcsIDgsIDksIDksIDksIDksIDksCi0gICAgICAgICAgICAgICAgOSwgOSwgOSwgOSwgOSwgMTAsIDEsIDEsIDExLCAxLCAxLCAxLCAxMiwgMTIsIDEyLCAxMiwgMTIsIDEyLAotICAgICAgICAgICAgICAgIDEyLCAxMiwgMTIsIDEyLCAxMiwgMTIsIDEyLCAxMiwgMTIsIDEyLCAxMiwgMTIsIDEyLCAxMiwgMTIsIDEyLAotICAgICAgICAgICAgICAgIDEyLCAxMiwgMTIsIDEyLCAxLCAxLCAxLCAzLCAxMywgMSwgMTIsIDEyLCAxMiwgMTIsIDEyLCAxMiwgMTIsCi0gICAgICAgICAgICAgICAgMTIsIDEyLCAxMiwgMTIsIDEyLCAxMiwgMTIsIDEyLCAxMiwgMTIsIDEyLCAxMiwgMTIsIDEyLCAxMiwgMTIsCi0gICAgICAgICAgICAgICAgMTIsIDEyLCAxMiwgMSwgMSwgMSwgMSwgMSB9OwotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIERhdGEKLSAgICAgICAgLy8KLSAgICAgICAgLyoqIFN5bWJvbCB0YWJsZS4gKi8KLSAgICAgICAgcHJpdmF0ZSBTeW1ib2xUYWJsZSBmU3ltYm9sVGFibGU7Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIENvbnN0cnVjdHMgYW4gWFBvaW50ZXIgRnJhbWV3b3JrIGV4cHJlc3Npb24gc2Nhbm5lci4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIHN5bWJvbFRhYmxlIFN5bWJvbFRhYmxlCi0gICAgICAgICAqLwotICAgICAgICBwcml2YXRlIFNjYW5uZXIoU3ltYm9sVGFibGUgc3ltYm9sVGFibGUpIHsKLSAgICAgICAgICAgIC8vIHNhdmUgcG9vbCBhbmQgdG9rZW5zCi0gICAgICAgICAgICBmU3ltYm9sVGFibGUgPSBzeW1ib2xUYWJsZTsKLQotICAgICAgICB9IC8vIDxpbml0PihTeW1ib2xUYWJsZSkKLQotICAgICAgICAvKioKLSAgICAgICAgICogU2NhbnMgdGhlIFhQb2ludGVyIEV4cHJlc3Npb24KLSAgICAgICAgICoKLSAgICAgICAgICovCi0gICAgICAgIHByaXZhdGUgYm9vbGVhbiBzY2FuRXhwcihTeW1ib2xUYWJsZSBzeW1ib2xUYWJsZSwgVG9rZW5zIHRva2VucywKLSAgICAgICAgICAgICAgICBTdHJpbmcgZGF0YSwgaW50IGN1cnJlbnRPZmZzZXQsIGludCBlbmRPZmZzZXQpCi0gICAgICAgICAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgICAgIGludCBjaDsKLSAgICAgICAgICAgIGludCBvcGVuUGFyZW4gPSAwOwotICAgICAgICAgICAgaW50IGNsb3NlUGFyZW4gPSAwOwotICAgICAgICAgICAgaW50IG5hbWVPZmZzZXQsIGRhdGFPZmZzZXQ7Ci0gICAgICAgICAgICBib29sZWFuIGlzUU5hbWUgPSBmYWxzZTsKLSAgICAgICAgICAgIFN0cmluZyBuYW1lID0gbnVsbDsKLSAgICAgICAgICAgIFN0cmluZyBwcmVmaXggPSBudWxsOwotICAgICAgICAgICAgU3RyaW5nIHNjaGVtZURhdGEgPSBudWxsOwotICAgICAgICAgICAgU3RyaW5nQnVmZmVyIHNjaGVtZURhdGFCdWZmID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotCi0gICAgICAgICAgICB3aGlsZSAodHJ1ZSkgewotCi0gICAgICAgICAgICAgICAgaWYgKGN1cnJlbnRPZmZzZXQgPT0gZW5kT2Zmc2V0KSB7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBjaCA9IGRhdGEuY2hhckF0KGN1cnJlbnRPZmZzZXQpOwotCi0gICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICB3aGlsZSAoY2ggPT0gJyAnIHx8IGNoID09IDB4MEEgfHwgY2ggPT0gMHgwOSB8fCBjaCA9PSAweDBEKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmICgrK2N1cnJlbnRPZmZzZXQgPT0gZW5kT2Zmc2V0KSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBjaCA9IGRhdGEuY2hhckF0KGN1cnJlbnRPZmZzZXQpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpZiAoY3VycmVudE9mZnNldCA9PSBlbmRPZmZzZXQpIHsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICAvLyBbMV0gICAgUG9pbnRlciAgICAgIDo6PSAgICBTaG9ydGhhbmQgfCBTY2hlbWVCYXNlZAotICAgICAgICAgICAgICAgIC8vIFsyXSAgICBTaG9ydGhhbmQgICAgOjo9ICAgIE5DTmFtZQotICAgICAgICAgICAgICAgIC8vIFszXSAgICBTY2hlbWVCYXNlZCAgOjo9ICAgIFBvaW50ZXJQYXJ0IChTPyBQb2ludGVyUGFydCkqCi0gICAgICAgICAgICAgICAgLy8gWzRdICAgIFBvaW50ZXJQYXJ0ICA6Oj0gICAgU2NoZW1lTmFtZSAnKCcgU2NoZW1lRGF0YSAnKScKLSAgICAgICAgICAgICAgICAvLyBbNV0gICAgU2NoZW1lTmFtZSAgIDo6PSAgICBRTmFtZQotICAgICAgICAgICAgICAgIC8vIFs2XSAgICBTY2hlbWVEYXRhICAgOjo9ICAgIEVzY2FwZWREYXRhKgotICAgICAgICAgICAgICAgIC8vIFs3XSAgICBFc2NhcGVkRGF0YSAgOjo9ICAgIE5vcm1hbENoYXIgfCAnXignIHwgJ14pJyB8ICdeXicgfCAnKCcgU2NoZW1lRGF0YSAnKScKLSAgICAgICAgICAgICAgICAvLyBbOF0gICAgTm9ybWFsQ2hhciAgIDo6PSAgICBVbmljb2RlQ2hhciAtIFsoKV5dCi0gICAgICAgICAgICAgICAgLy8gWzldICAgIFVuaWNvZGVDaGFyICA6Oj0gICAgWyN4MC0jeDEwRkZGRl0KLSAgICAgICAgICAgICAgICAvLyBbP10gICAgUU5hbWUgICAgICAgIDo6PSAgICAoTkNOYW1lICc6Jyk/IE5DTmFtZQotICAgICAgICAgICAgICAgIC8vIFs/XSAgICBOQ05hbWUgICAgICAgOjo9ICAgIChMZXR0ZXIgfCAnXycpIChOQ05hbWVDaGFyKSoKLSAgICAgICAgICAgICAgICAvLyBbP10gICAgTkNOYW1lQ2hhciAgIDo6PSAgICBMZXR0ZXIgfCBEaWdpdCB8ICcuJyB8ICctJyB8ICdfJyAgKGFzY2lpIHN1YnNldCBvZiAnTkNOYW1lQ2hhcicpCi0gICAgICAgICAgICAgICAgLy8gWz9dICAgIExldHRlciAgICAgICA6Oj0gICAgW0EtWmEtel0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYXNjaWkgc3Vic2V0IG9mICdMZXR0ZXInKQotICAgICAgICAgICAgICAgIC8vIFs/XSAgICBEaWdpdCAgICAgICAgOjo9ICAgIFswLTldICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChhc2NpaSBzdWJzZXQgb2YgJ0RpZ2l0JykKLSAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgIGJ5dGUgY2hhcnR5cGUgPSAoY2ggPj0gMHg4MCkgPyBDSEFSVFlQRV9OT05BU0NJSQotICAgICAgICAgICAgICAgICAgICAgICAgOiBmQVNDSUlDaGFyTWFwW2NoXTsKLQotICAgICAgICAgICAgICAgIHN3aXRjaCAoY2hhcnR5cGUpIHsKLQotICAgICAgICAgICAgICAgIGNhc2UgQ0hBUlRZUEVfT1BFTl9QQVJFTjogLy8gJygnCi0gICAgICAgICAgICAgICAgICAgIGFkZFRva2VuKHRva2VucywgVG9rZW5zLlhQVFJUT0tFTl9PUEVOX1BBUkVOKTsKLSAgICAgICAgICAgICAgICAgICAgb3BlblBhcmVuKys7Ci0gICAgICAgICAgICAgICAgICAgICsrY3VycmVudE9mZnNldDsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgICAgICAgICBjYXNlIENIQVJUWVBFX0NMT1NFX1BBUkVOOiAvLyAnKScKLSAgICAgICAgICAgICAgICAgICAgYWRkVG9rZW4odG9rZW5zLCBUb2tlbnMuWFBUUlRPS0VOX0NMT1NFX1BBUkVOKTsKLSAgICAgICAgICAgICAgICAgICAgY2xvc2VQYXJlbisrOwotICAgICAgICAgICAgICAgICAgICArK2N1cnJlbnRPZmZzZXQ7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgICAgICAgICAgY2FzZSBDSEFSVFlQRV9DQVJSRVQ6Ci0gICAgICAgICAgICAgICAgY2FzZSBDSEFSVFlQRV9DT0xPTjoKLSAgICAgICAgICAgICAgICBjYXNlIENIQVJUWVBFX0RJR0lUOgotICAgICAgICAgICAgICAgIGNhc2UgQ0hBUlRZUEVfRVFVQUw6Ci0gICAgICAgICAgICAgICAgY2FzZSBDSEFSVFlQRV9MRVRURVI6Ci0gICAgICAgICAgICAgICAgY2FzZSBDSEFSVFlQRV9NSU5VUzoKLSAgICAgICAgICAgICAgICBjYXNlIENIQVJUWVBFX05PTkFTQ0lJOgotICAgICAgICAgICAgICAgIGNhc2UgQ0hBUlRZUEVfT1RIRVI6Ci0gICAgICAgICAgICAgICAgY2FzZSBDSEFSVFlQRV9QRVJJT0Q6Ci0gICAgICAgICAgICAgICAgY2FzZSBDSEFSVFlQRV9TTEFTSDoKLSAgICAgICAgICAgICAgICBjYXNlIENIQVJUWVBFX1VOREVSU0NPUkU6Ci0gICAgICAgICAgICAgICAgY2FzZSBDSEFSVFlQRV9XSElURVNQQUNFOgotICAgICAgICAgICAgICAgICAgICAvLyBTY2FubmluZyBTY2hlbWVOYW1lIHwgU2hvcnRoYW5kCi0gICAgICAgICAgICAgICAgICAgIGlmIChvcGVuUGFyZW4gPT0gMCkgewotICAgICAgICAgICAgICAgICAgICAgICAgbmFtZU9mZnNldCA9IGN1cnJlbnRPZmZzZXQ7Ci0gICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50T2Zmc2V0ID0gc2Nhbk5DTmFtZShkYXRhLCBlbmRPZmZzZXQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRPZmZzZXQpOwotCi0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY3VycmVudE9mZnNldCA9PSBuYW1lT2Zmc2V0KSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoIkludmFsaWRTaG9ydEhhbmRQb2ludGVyIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7IGRhdGEgfSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY3VycmVudE9mZnNldCA8IGVuZE9mZnNldCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoID0gZGF0YS5jaGFyQXQoY3VycmVudE9mZnNldCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoID0gLTE7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUgPSBzeW1ib2xUYWJsZS5hZGRTeW1ib2woZGF0YS5zdWJzdHJpbmcobmFtZU9mZnNldCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudE9mZnNldCkpOwotICAgICAgICAgICAgICAgICAgICAgICAgcHJlZml4ID0gWE1MU3ltYm9scy5FTVBUWV9TVFJJTkc7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoZSBuYW1lIGlzIGEgUU5hbWUgPT4gYSBTY2hlbWVOYW1lCi0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2ggPT0gJzonKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCsrY3VycmVudE9mZnNldCA9PSBlbmRPZmZzZXQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoID0gZGF0YS5jaGFyQXQoY3VycmVudE9mZnNldCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJlZml4ID0gbmFtZTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lT2Zmc2V0ID0gY3VycmVudE9mZnNldDsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50T2Zmc2V0ID0gc2Nhbk5DTmFtZShkYXRhLCBlbmRPZmZzZXQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50T2Zmc2V0KTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjdXJyZW50T2Zmc2V0ID09IG5hbWVPZmZzZXQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjdXJyZW50T2Zmc2V0IDwgZW5kT2Zmc2V0KSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoID0gZGF0YS5jaGFyQXQoY3VycmVudE9mZnNldCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2ggPSAtMTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc1FOYW1lID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lID0gc3ltYm9sVGFibGUuYWRkU3ltYm9sKGRhdGEuc3Vic3RyaW5nKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZU9mZnNldCwgY3VycmVudE9mZnNldCkpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBSRVZJU0lUOgotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGN1cnJlbnRPZmZzZXQgIT0gZW5kT2Zmc2V0KSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkVG9rZW4odG9rZW5zLCBUb2tlbnMuWFBUUlRPS0VOX1NDSEVNRU5BTUUpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRva2Vucy5hZGRUb2tlbihwcmVmaXgpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRva2Vucy5hZGRUb2tlbihuYW1lKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc1FOYW1lID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGN1cnJlbnRPZmZzZXQgPT0gZW5kT2Zmc2V0KSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTkNOYW1lID0+IFNob3J0aGFuZAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZFRva2VuKHRva2VucywgVG9rZW5zLlhQVFJUT0tFTl9TSE9SVEhBTkQpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRva2Vucy5hZGRUb2tlbihuYW1lKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc1FOYW1lID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIHJlc2V0IG9wZW4vY2xvc2UgcGFyZW4gZm9yIHRoZSBuZXh0IHBvaW50ZXIgcGFydAotICAgICAgICAgICAgICAgICAgICAgICAgY2xvc2VQYXJlbiA9IDA7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAob3BlblBhcmVuID4gMCAmJiBjbG9zZVBhcmVuID09IDAgJiYgbmFtZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBTY2FubmluZyBTY2hlbWVEYXRhCi0gICAgICAgICAgICAgICAgICAgICAgICBkYXRhT2Zmc2V0ID0gY3VycmVudE9mZnNldDsKLSAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRPZmZzZXQgPSBzY2FuRGF0YShkYXRhLCBzY2hlbWVEYXRhQnVmZiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5kT2Zmc2V0LCBjdXJyZW50T2Zmc2V0KTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGN1cnJlbnRPZmZzZXQgPT0gZGF0YU9mZnNldCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydEVycm9yKCJJbnZhbGlkU2NoZW1lRGF0YUluWFBvaW50ZXIiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgZGF0YSB9KTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjdXJyZW50T2Zmc2V0IDwgZW5kT2Zmc2V0KSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2ggPSBkYXRhLmNoYXJBdChjdXJyZW50T2Zmc2V0KTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2ggPSAtMTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAgICAgc2NoZW1lRGF0YSA9IHN5bWJvbFRhYmxlLmFkZFN5bWJvbChzY2hlbWVEYXRhQnVmZgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAudG9TdHJpbmcoKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBhZGRUb2tlbih0b2tlbnMsIFRva2Vucy5YUFRSVE9LRU5fU0NIRU1FREFUQSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB0b2tlbnMuYWRkVG9rZW4oc2NoZW1lRGF0YSk7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIHJlc2V0IG9wZW4vY2xvc2UgcGFyZW4gZm9yIHRoZSBuZXh0IHBvaW50ZXIgcGFydAotICAgICAgICAgICAgICAgICAgICAgICAgb3BlblBhcmVuID0gMDsKLSAgICAgICAgICAgICAgICAgICAgICAgIHNjaGVtZURhdGFCdWZmLmRlbGV0ZSgwLCBzY2hlbWVEYXRhQnVmZi5sZW5ndGgoKSk7Ci0KLSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGV4LiBzY2hlbWVOYW1lKCkKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNob3VsZCB3ZSB0aHJvdyBhbiBleGNlcHRpb24gd2l0aCBhIG1vcmUgc3VpdGFibGUgbWVzc2FnZSBpbnN0ZWFkPz8KLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0gLy8gZW5kIHdoaWxlCi0gICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBTY2FucyBhIE5DTmFtZS4KLSAgICAgICAgICogRnJvbSBOYW1lc3BhY2VzIGluIFhNTAotICAgICAgICAgKiBbNV0gTkNOYW1lIDo6PSAoTGV0dGVyIHwgJ18nKSAoTkNOYW1lQ2hhcikqCi0gICAgICAgICAqIFs2XSBOQ05hbWVDaGFyIDo6PSBMZXR0ZXIgfCBEaWdpdCB8ICcuJyB8ICctJyB8ICdfJyB8IENvbWJpbmluZ0NoYXIgfCBFeHRlbmRlcgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gZGF0YSBBIFN0cmluZyBjb250YWluaW5nIHRoZSBYUG9pbnRlciBleHByZXNzaW9uCi0gICAgICAgICAqIEBwYXJhbSBlbmRPZmZzZXQgVGhlIGludCBYUG9pbnRlciBleHByZXNzaW9uIGxlbmd0aAotICAgICAgICAgKiBAcGFyYW0gY3VycmVudE9mZnNldCBBbiBpbnQgcmVwcmVzZW50aW5nIHRoZSBjdXJyZW50IHBvc2l0aW9uIG9mIHRoZSBYUG9pbnRlciBleHByZXNzaW9uIHBvaW50ZXIKLSAgICAgICAgICovCi0gICAgICAgIHByaXZhdGUgaW50IHNjYW5OQ05hbWUoU3RyaW5nIGRhdGEsIGludCBlbmRPZmZzZXQsIGludCBjdXJyZW50T2Zmc2V0KSB7Ci0gICAgICAgICAgICBpbnQgY2ggPSBkYXRhLmNoYXJBdChjdXJyZW50T2Zmc2V0KTsKLSAgICAgICAgICAgIGlmIChjaCA+PSAweDgwKSB7Ci0gICAgICAgICAgICAgICAgaWYgKCFYTUxDaGFyLmlzTmFtZVN0YXJ0KGNoKSkgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gY3VycmVudE9mZnNldDsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIGJ5dGUgY2hhcnR5cGUgPSBmQVNDSUlDaGFyTWFwW2NoXTsKLSAgICAgICAgICAgICAgICBpZiAoY2hhcnR5cGUgIT0gQ0hBUlRZUEVfTEVUVEVSCi0gICAgICAgICAgICAgICAgICAgICAgICAmJiBjaGFydHlwZSAhPSBDSEFSVFlQRV9VTkRFUlNDT1JFKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBjdXJyZW50T2Zmc2V0OwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy93aGlsZSAoY3VycmVudE9mZnNldCsrIDwgZW5kT2Zmc2V0KSB7Ci0gICAgICAgICAgICB3aGlsZSAoKytjdXJyZW50T2Zmc2V0IDwgZW5kT2Zmc2V0KSB7Ci0gICAgICAgICAgICAgICAgY2ggPSBkYXRhLmNoYXJBdChjdXJyZW50T2Zmc2V0KTsKLSAgICAgICAgICAgICAgICBpZiAoY2ggPj0gMHg4MCkgewotICAgICAgICAgICAgICAgICAgICBpZiAoIVhNTENoYXIuaXNOYW1lKGNoKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICBieXRlIGNoYXJ0eXBlID0gZkFTQ0lJQ2hhck1hcFtjaF07Ci0gICAgICAgICAgICAgICAgICAgIGlmIChjaGFydHlwZSAhPSBDSEFSVFlQRV9MRVRURVIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiBjaGFydHlwZSAhPSBDSEFSVFlQRV9ESUdJVAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmIGNoYXJ0eXBlICE9IENIQVJUWVBFX1BFUklPRAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmIGNoYXJ0eXBlICE9IENIQVJUWVBFX01JTlVTCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgY2hhcnR5cGUgIT0gQ0hBUlRZUEVfVU5ERVJTQ09SRSkgewotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gY3VycmVudE9mZnNldDsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBTY2FucyB0aGUgU2NoZW1lRGF0YS4KLSAgICAgICAgICogWzZdICAgIFNjaGVtZURhdGEgICA6Oj0gICAgRXNjYXBlZERhdGEqCi0gICAgICAgICAqIFs3XSAgICBFc2NhcGVkRGF0YSAgOjo9ICAgIE5vcm1hbENoYXIgfCAnXignIHwgJ14pJyB8ICdeXicgfCAnKCcgU2NoZW1lRGF0YSAnKScKLSAgICAgICAgICogWzhdICAgIE5vcm1hbENoYXIgICA6Oj0gICAgVW5pY29kZUNoYXIgLSBbKCleXQotICAgICAgICAgKiBbOV0gICAgVW5pY29kZUNoYXIgIDo6PSAgICBbI3gwLSN4MTBGRkZGXQotICAgICAgICAgKgotICAgICAgICAgKi8KLSAgICAgICAgcHJpdmF0ZSBpbnQgc2NhbkRhdGEoU3RyaW5nIGRhdGEsIFN0cmluZ0J1ZmZlciBzY2hlbWVEYXRhLAotICAgICAgICAgICAgICAgIGludCBlbmRPZmZzZXQsIGludCBjdXJyZW50T2Zmc2V0KSB7Ci0gICAgICAgICAgICB3aGlsZSAodHJ1ZSkgewotCi0gICAgICAgICAgICAgICAgaWYgKGN1cnJlbnRPZmZzZXQgPT0gZW5kT2Zmc2V0KSB7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIGludCBjaCA9IGRhdGEuY2hhckF0KGN1cnJlbnRPZmZzZXQpOwotICAgICAgICAgICAgICAgIGJ5dGUgY2hhcnR5cGUgPSAoY2ggPj0gMHg4MCkgPyBDSEFSVFlQRV9OT05BU0NJSQotICAgICAgICAgICAgICAgICAgICAgICAgOiBmQVNDSUlDaGFyTWFwW2NoXTsKLQotICAgICAgICAgICAgICAgIGlmIChjaGFydHlwZSA9PSBDSEFSVFlQRV9PUEVOX1BBUkVOKSB7Ci0gICAgICAgICAgICAgICAgICAgIHNjaGVtZURhdGEuYXBwZW5kKGNoKTsKLSAgICAgICAgICAgICAgICAgICAgLy9zY2hlbWVEYXRhLmFwcGVuZChUb2tlbnMuWFBUUlRPS0VOX09QRU5fUEFSRU4pOwotICAgICAgICAgICAgICAgICAgICBjdXJyZW50T2Zmc2V0ID0gc2NhbkRhdGEoZGF0YSwgc2NoZW1lRGF0YSwgZW5kT2Zmc2V0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICsrY3VycmVudE9mZnNldCk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChjdXJyZW50T2Zmc2V0ID09IGVuZE9mZnNldCkgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnRPZmZzZXQ7Ci0gICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICBjaCA9IGRhdGEuY2hhckF0KGN1cnJlbnRPZmZzZXQpOwotICAgICAgICAgICAgICAgICAgICBjaGFydHlwZSA9IChjaCA+PSAweDgwKSA/IENIQVJUWVBFX05PTkFTQ0lJCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBmQVNDSUlDaGFyTWFwW2NoXTsKLQotICAgICAgICAgICAgICAgICAgICBpZiAoY2hhcnR5cGUgIT0gQ0hBUlRZUEVfQ0xPU0VfUEFSRU4pIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBlbmRPZmZzZXQ7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgc2NoZW1lRGF0YS5hcHBlbmQoKGNoYXIpIGNoKTsKLSAgICAgICAgICAgICAgICAgICAgKytjdXJyZW50T2Zmc2V0Oy8vCi0KLSAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNoYXJ0eXBlID09IENIQVJUWVBFX0NMT1NFX1BBUkVOKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBjdXJyZW50T2Zmc2V0OwotCi0gICAgICAgICAgICAgICAgfSBlbHNlICBpZiAoY2hhcnR5cGUgPT0gQ0hBUlRZUEVfQ0FSUkVUKSB7Ci0gICAgICAgICAgICAgICAgICAgIGNoID0gZGF0YS5jaGFyQXQoKytjdXJyZW50T2Zmc2V0KTsKLSAgICAgICAgICAgICAgICAgICAgY2hhcnR5cGUgPSAoY2ggPj0gMHg4MCkgPyBDSEFSVFlQRV9OT05BU0NJSQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogZkFTQ0lJQ2hhck1hcFtjaF07Ci0KLSAgICAgICAgICAgICAgICAgICAgaWYgKGNoYXJ0eXBlICE9IENIQVJUWVBFX0NBUlJFVAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmIGNoYXJ0eXBlICE9IENIQVJUWVBFX09QRU5fUEFSRU4KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiBjaGFydHlwZSAhPSBDSEFSVFlQRV9DTE9TRV9QQVJFTikgewotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgc2NoZW1lRGF0YS5hcHBlbmQoKGNoYXIpIGNoKTsKLSAgICAgICAgICAgICAgICAgICAgKytjdXJyZW50T2Zmc2V0OwotCi0gICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgc2NoZW1lRGF0YS5hcHBlbmQoKGNoYXIpIGNoKTsKLSAgICAgICAgICAgICAgICAgICAgKytjdXJyZW50T2Zmc2V0Oy8vCi0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICByZXR1cm4gY3VycmVudE9mZnNldDsKLSAgICAgICAgfQotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIFByb3RlY3RlZCBtZXRob2RzCi0gICAgICAgIC8vCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFRoaXMgbWV0aG9kIGFkZHMgdGhlIHNwZWNpZmllZCB0b2tlbiB0byB0aGUgdG9rZW4gbGlzdC4gQnkKLSAgICAgICAgICogZGVmYXVsdCwgdGhpcyBtZXRob2QgYWxsb3dzIGFsbCB0b2tlbnMuIEhvd2V2ZXIsIHN1YmNsYXNzZXMKLSAgICAgICAgICogb2YgdGhlIFhQYXRoRXhwclNjYW5uZXIgY2FuIG92ZXJyaWRlIHRoaXMgbWV0aG9kIGluIG9yZGVyCi0gICAgICAgICAqIHRvIGRpc2FsbG93IGNlcnRhaW4gdG9rZW5zIGZyb20gYmVpbmcgdXNlZCBpbiB0aGUgc2Nhbm5lZAotICAgICAgICAgKiBYUGF0aCBleHByZXNzaW9uLiBUaGlzIGlzIGEgY29udmVuaWVudCB3YXkgb2YgYWxsb3dpbmcgb25seQotICAgICAgICAgKiBhIHN1YnNldCBvZiBYUGF0aC4KLSAgICAgICAgICovCi0gICAgICAgIHByb3RlY3RlZCB2b2lkIGFkZFRva2VuKFRva2VucyB0b2tlbnMsIGludCB0b2tlbikgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICB0b2tlbnMuYWRkVG9rZW4odG9rZW4pOwotICAgICAgICB9IC8vIGFkZFRva2VuKGludCkKLQotICAgIH0gLy8gY2xhc3MgU2Nhbm5lcgotCi0gICAgLy8gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0gICAgLy8gIE92ZXJyaWRkZW4gWE1MRG9jdW1lbnRIYW5kbGVyIG1ldGhvZHMKLSAgICAvLyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLSAgICAvKioKLSAgICAgKiBJZiB0aGUgY29tbWVudCBpcyBhIGNoaWxkIG9mIGEgbWF0Y2hlZCBlbGVtZW50LCB0aGVuIHBhc3MgZWxzZSByZXR1cm4uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdGV4dCAgIFRoZSB0ZXh0IGluIHRoZSBjb21tZW50LgotICAgICAqIEBwYXJhbSBhdWdzICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBYTklFeGNlcHRpb24KLSAgICAgKiAgICAgICAgICAgICAgICAgICBUaHJvd24gYnkgYXBwbGljYXRpb24gdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGNvbW1lbnQoWE1MU3RyaW5nIHRleHQsIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmICghaXNDaGlsZEZyYWdtZW50UmVzb2x2ZWQoKSkgewotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0gICAgICAgIHN1cGVyLmNvbW1lbnQodGV4dCwgYXVncyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQSBwcm9jZXNzaW5nIGluc3RydWN0aW9uLiBQcm9jZXNzaW5nIGluc3RydWN0aW9ucyBjb25zaXN0IG9mIGEKLSAgICAgKiB0YXJnZXQgbmFtZSBhbmQsIG9wdGlvbmFsbHksIHRleHQgZGF0YS4gVGhlIGRhdGEgaXMgb25seSBtZWFuaW5nZnVsCi0gICAgICogdG8gdGhlIGFwcGxpY2F0aW9uLgotICAgICAqIDxwPgotICAgICAqIFR5cGljYWxseSwgYSBwcm9jZXNzaW5nIGluc3RydWN0aW9uJ3MgZGF0YSB3aWxsIGNvbnRhaW4gYSBzZXJpZXMKLSAgICAgKiBvZiBwc2V1ZG8tYXR0cmlidXRlcy4gVGhlc2UgcHNldWRvLWF0dHJpYnV0ZXMgZm9sbG93IHRoZSBmb3JtIG9mCi0gICAgICogZWxlbWVudCBhdHRyaWJ1dGVzIGJ1dCBhcmUgPHN0cm9uZz5ub3Q8L3N0cm9uZz4gcGFyc2VkIG9yIHByZXNlbnRlZAotICAgICAqIHRvIHRoZSBhcHBsaWNhdGlvbiBhcyBhbnl0aGluZyBvdGhlciB0aGFuIHRleHQuIFRoZSBhcHBsaWNhdGlvbiBpcwotICAgICAqIHJlc3BvbnNpYmxlIGZvciBwYXJzaW5nIHRoZSBkYXRhLgotICAgICAqCi0gICAgICogQHBhcmFtIHRhcmdldCBUaGUgdGFyZ2V0LgotICAgICAqIEBwYXJhbSBkYXRhICAgVGhlIGRhdGEgb3IgbnVsbCBpZiBub25lIHNwZWNpZmllZC4KLSAgICAgKiBAcGFyYW0gYXVncyAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKgotICAgICAqIEBleGNlcHRpb24gWE5JRXhjZXB0aW9uCi0gICAgICogICAgICAgICAgICAgICAgICAgVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHByb2Nlc3NpbmdJbnN0cnVjdGlvbihTdHJpbmcgdGFyZ2V0LCBYTUxTdHJpbmcgZGF0YSwKLSAgICAgICAgICAgIEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmICghaXNDaGlsZEZyYWdtZW50UmVzb2x2ZWQoKSkgewotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0gICAgICAgIHN1cGVyLnByb2Nlc3NpbmdJbnN0cnVjdGlvbih0YXJnZXQsIGRhdGEsIGF1Z3MpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoZSBzdGFydCBvZiBhbiBlbGVtZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIGVsZW1lbnQgICAgVGhlIG5hbWUgb2YgdGhlIGVsZW1lbnQuCi0gICAgICogQHBhcmFtIGF0dHJpYnV0ZXMgVGhlIGVsZW1lbnQgYXR0cmlidXRlcy4KLSAgICAgKiBAcGFyYW0gYXVncyAgICAgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIFhOSUV4Y2VwdGlvbgotICAgICAqICAgICAgICAgICAgICAgICAgIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQoUU5hbWUgZWxlbWVudCwgWE1MQXR0cmlidXRlcyBhdHRyaWJ1dGVzLAotICAgICAgICAgICAgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKCFyZXNvbHZlWFBvaW50ZXIoZWxlbWVudCwgYXR0cmlidXRlcywgYXVncywKLSAgICAgICAgICAgICAgICBYUG9pbnRlclBhcnQuRVZFTlRfRUxFTUVOVF9TVEFSVCkpIHsKLQotICAgICAgICAgICAgLy8geG1sOmJhc2UgYW5kIHhtbDpsYW5nIHByb2Nlc3NpbmcKLSAgICAgICAgICAgICAgICBpZiAoZkZpeHVwQmFzZSkgewotICAgICAgICAgICAgICAgIHByb2Nlc3NYTUxCYXNlQXR0cmlidXRlcyhhdHRyaWJ1dGVzKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoZkZpeHVwTGFuZykgewotICAgICAgICAgICAgICAgIHByb2Nlc3NYTUxMYW5nQXR0cmlidXRlcyhhdHRyaWJ1dGVzKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gc2V0IHRoZSBjb250ZXh0IGludmFsaWQgaWYgdGhlIGVsZW1lbnQgdGlsbCBhbiBlbGVtZW50IGZyb20gdGhlIHJlc3VsdCBpbmZvc2V0IGlzIGluY2x1ZGVkCi0gICAgICAgICAgICBmTmFtZXNwYWNlQ29udGV4dC5zZXRDb250ZXh0SW52YWxpZCgpOwotCi0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLSAgICAgICAgc3VwZXIuc3RhcnRFbGVtZW50KGVsZW1lbnQsIGF0dHJpYnV0ZXMsIGF1Z3MpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEFuIGVtcHR5IGVsZW1lbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZWxlbWVudCAgICBUaGUgbmFtZSBvZiB0aGUgZWxlbWVudC4KLSAgICAgKiBAcGFyYW0gYXR0cmlidXRlcyBUaGUgZWxlbWVudCBhdHRyaWJ1dGVzLgotICAgICAqIEBwYXJhbSBhdWdzICAgICAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKgotICAgICAqIEBleGNlcHRpb24gWE5JRXhjZXB0aW9uCi0gICAgICogICAgICAgICAgICAgICAgICAgVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVtcHR5RWxlbWVudChRTmFtZSBlbGVtZW50LCBYTUxBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMsCi0gICAgICAgICAgICBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBpZiAoIXJlc29sdmVYUG9pbnRlcihlbGVtZW50LCBhdHRyaWJ1dGVzLCBhdWdzLAotICAgICAgICAgICAgICAgIFhQb2ludGVyUGFydC5FVkVOVF9FTEVNRU5UX0VNUFRZKSkgewotICAgICAgICAgICAgLy8geG1sOmJhc2UgYW5kIHhtbDpsYW5nIHByb2Nlc3NpbmcKLSAgICAgICAgICAgICAgICBpZiAoZkZpeHVwQmFzZSkgewotICAgICAgICAgICAgICAgIHByb2Nlc3NYTUxCYXNlQXR0cmlidXRlcyhhdHRyaWJ1dGVzKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoZkZpeHVwTGFuZykgewotICAgICAgICAgICAgICAgIHByb2Nlc3NYTUxMYW5nQXR0cmlidXRlcyhhdHRyaWJ1dGVzKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIG5vIG5lZWQgdG8gcmVzdG9yZSByZXN0b3JlQmFzZVVSSSgpIGZvciB4bWw6YmFzZSBhbmQgeG1sOmxhbmcgcHJvY2Vzc2luZwotCi0gICAgICAgICAgICAvLyBzZXQgdGhlIGNvbnRleHQgaW52YWxpZCBpZiB0aGUgZWxlbWVudCB0aWxsIGFuIGVsZW1lbnQgZnJvbSB0aGUgcmVzdWx0IGluZm9zZXQgaXMgaW5jbHVkZWQKLSAgICAgICAgICAgIGZOYW1lc3BhY2VDb250ZXh0LnNldENvbnRleHRJbnZhbGlkKCk7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLSAgICAgICAgc3VwZXIuZW1wdHlFbGVtZW50KGVsZW1lbnQsIGF0dHJpYnV0ZXMsIGF1Z3MpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENoYXJhY3RlciBjb250ZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIHRleHQgICBUaGUgY29udGVudC4KLSAgICAgKiBAcGFyYW0gYXVncyAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKgotICAgICAqIEBleGNlcHRpb24gWE5JRXhjZXB0aW9uCi0gICAgICogICAgICAgICAgICAgICAgICAgVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGNoYXJhY3RlcnMoWE1MU3RyaW5nIHRleHQsIEF1Z21lbnRhdGlvbnMgYXVncykKLSAgICAgICAgICAgIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBpZiAoIWlzQ2hpbGRGcmFnbWVudFJlc29sdmVkKCkpIHsKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotICAgICAgICBzdXBlci5jaGFyYWN0ZXJzKHRleHQsIGF1Z3MpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIElnbm9yYWJsZSB3aGl0ZXNwYWNlLiBGb3IgdGhpcyBtZXRob2QgdG8gYmUgY2FsbGVkLCB0aGUgZG9jdW1lbnQKLSAgICAgKiBzb3VyY2UgbXVzdCBoYXZlIHNvbWUgd2F5IG9mIGRldGVybWluaW5nIHRoYXQgdGhlIHRleHQgY29udGFpbmluZwotICAgICAqIG9ubHkgd2hpdGVzcGFjZSBjaGFyYWN0ZXJzIHNob3VsZCBiZSBjb25zaWRlcmVkIGlnbm9yYWJsZS4gRm9yCi0gICAgICogZXhhbXBsZSwgdGhlIHZhbGlkYXRvciBjYW4gZGV0ZXJtaW5lIGlmIGEgbGVuZ3RoIG9mIHdoaXRlc3BhY2UKLSAgICAgKiBjaGFyYWN0ZXJzIGluIHRoZSBkb2N1bWVudCBhcmUgaWdub3JhYmxlIGJhc2VkIG9uIHRoZSBlbGVtZW50Ci0gICAgICogY29udGVudCBtb2RlbC4KLSAgICAgKgotICAgICAqIEBwYXJhbSB0ZXh0ICAgVGhlIGlnbm9yYWJsZSB3aGl0ZXNwYWNlLgotICAgICAqIEBwYXJhbSBhdWdzICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBYTklFeGNlcHRpb24KLSAgICAgKiAgICAgICAgICAgICAgICAgICBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgaWdub3JhYmxlV2hpdGVzcGFjZShYTUxTdHJpbmcgdGV4dCwgQXVnbWVudGF0aW9ucyBhdWdzKQotICAgICAgICAgICAgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmICghaXNDaGlsZEZyYWdtZW50UmVzb2x2ZWQoKSkgewotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0gICAgICAgIHN1cGVyLmlnbm9yYWJsZVdoaXRlc3BhY2UodGV4dCwgYXVncyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhlIGVuZCBvZiBhbiBlbGVtZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIGVsZW1lbnQgVGhlIG5hbWUgb2YgdGhlIGVsZW1lbnQuCi0gICAgICogQHBhcmFtIGF1Z3MgICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBYTklFeGNlcHRpb24KLSAgICAgKiAgICAgICAgICAgICAgICAgICBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kRWxlbWVudChRTmFtZSBlbGVtZW50LCBBdWdtZW50YXRpb25zIGF1Z3MpCi0gICAgICAgICAgICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKCFyZXNvbHZlWFBvaW50ZXIoZWxlbWVudCwgbnVsbCwgYXVncywKLSAgICAgICAgICAgICAgICBYUG9pbnRlclBhcnQuRVZFTlRfRUxFTUVOVF9FTkQpKSB7Ci0KLSAgICAgICAgICAgIC8vIG5vIG5lZWQgdG8gcmVzdG9yZSByZXN0b3JlQmFzZVVSSSgpIGZvciB4bWw6YmFzZSBhbmQgeG1sOmxhbmcgcHJvY2Vzc2luZwotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0gICAgICAgIHN1cGVyLmVuZEVsZW1lbnQoZWxlbWVudCwgYXVncyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhlIHN0YXJ0IG9mIGEgQ0RBVEEgc2VjdGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBhdWdzICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBYTklFeGNlcHRpb24KLSAgICAgKiAgICAgICAgICAgICAgICAgICBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnRDREFUQShBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBpZiAoIWlzQ2hpbGRGcmFnbWVudFJlc29sdmVkKCkpIHsKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotICAgICAgICBzdXBlci5zdGFydENEQVRBKGF1Z3MpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoZSBlbmQgb2YgYSBDREFUQSBzZWN0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIGF1Z3MgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIFhOSUV4Y2VwdGlvbgotICAgICAqICAgICAgICAgICAgICAgICAgIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbmRDREFUQShBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgICAgICBpZiAoIWlzQ2hpbGRGcmFnbWVudFJlc29sdmVkKCkpIHsKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotICAgICAgICBzdXBlci5lbmRDREFUQShhdWdzKTsKLSAgICB9Ci0KLSAgICAvLyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLSAgICAvLyBPdmVycmlkZGVuIFhNTENvbXBvbmVudCBtZXRob2RzCi0gICAgLy8gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0gICAgLyoqCi0gICAgICogPHA+Ci0gICAgICogU2V0cyB0aGUgdmFsdWUgb2YgYSBwcm9wZXJ0eS4gVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBjb21wb25lbnQKLSAgICAgKiBtYW5hZ2VyIGFueSB0aW1lIGFmdGVyIHJlc2V0IHdoZW4gYSBwcm9wZXJ0eSBjaGFuZ2VzIHZhbHVlLgotICAgICAqIDwvcD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IENvbXBvbmVudHMgc2hvdWxkIHNpbGVudGx5IGlnbm9yZSBwcm9wZXJ0aWVzCi0gICAgICogdGhhdCBkbyBub3QgYWZmZWN0IHRoZSBvcGVyYXRpb24gb2YgdGhlIGNvbXBvbmVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBwcm9wZXJ0eUlkIFRoZSBwcm9wZXJ0eSBpZGVudGlmaWVyLgotICAgICAqIEBwYXJhbSB2YWx1ZSAgICAgIFRoZSB2YWx1ZSBvZiB0aGUgcHJvcGVydHkuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gVGhyb3duIGZvciBjb25maWd1cmF0aW9uIGVycm9yLgotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluIGdlbmVyYWwsIGNvbXBvbmVudHMgc2hvdWxkCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb25seSB0aHJvdyB0aGlzIGV4Y2VwdGlvbiBpZgotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0IGlzIDxzdHJvbmc+cmVhbGx5PC9zdHJvbmc+Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYSBjcml0aWNhbCBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRQcm9wZXJ0eShTdHJpbmcgcHJvcGVydHlJZCwgT2JqZWN0IHZhbHVlKQotICAgICAgICAgICAgdGhyb3dzIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gewotCi0gICAgICAgIC8vIEVycm9yIHJlcG9ydGVyCi0gICAgICAgIGlmIChwcm9wZXJ0eUlkID09IENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYCi0gICAgICAgICAgICAgICAgKyBDb25zdGFudHMuRVJST1JfUkVQT1JURVJfUFJPUEVSVFkpIHsKLSAgICAgICAgICAgIGlmICh2YWx1ZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZlhQb2ludGVyRXJyb3JSZXBvcnRlciA9IChYTUxFcnJvclJlcG9ydGVyKSB2YWx1ZTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgZlhQb2ludGVyRXJyb3JSZXBvcnRlciA9IG51bGw7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBFcnJvciBoYW5kbGVyCi0gICAgICAgIGlmIChwcm9wZXJ0eUlkID09IENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYCi0gICAgICAgICAgICAgICAgKyBDb25zdGFudHMuRVJST1JfSEFORExFUl9QUk9QRVJUWSkgewotICAgICAgICAgICAgaWYgKHZhbHVlICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmRXJyb3JIYW5kbGVyID0gKFhNTEVycm9ySGFuZGxlcikgdmFsdWU7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIGZFcnJvckhhbmRsZXIgPSBudWxsOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8geG1sOmxhbmcKLSAgICAgICAgaWYgKHByb3BlcnR5SWQgPT0gQ29uc3RhbnRzLlhFUkNFU19GRUFUVVJFX1BSRUZJWAotICAgICAgICAgICAgICAgICsgQ29uc3RhbnRzLlhJTkNMVURFX0ZJWFVQX0xBTkdVQUdFX0ZFQVRVUkUpIHsKLSAgICAgICAgICAgIGlmICh2YWx1ZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZkZpeHVwTGFuZyA9ICgoQm9vbGVhbil2YWx1ZSkuYm9vbGVhblZhbHVlKCk7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIGZGaXh1cExhbmcgPSBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIHhtbDpiYXNlCi0gICAgICAgIGlmIChwcm9wZXJ0eUlkID09IENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVgKLSAgICAgICAgICAgICAgICArIENvbnN0YW50cy5YSU5DTFVERV9GSVhVUF9CQVNFX1VSSVNfRkVBVFVSRSkgewotICAgICAgICAgICAgaWYgKHZhbHVlICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmRml4dXBCYXNlID0gKChCb29sZWFuKXZhbHVlKS5ib29sZWFuVmFsdWUoKTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgZkZpeHVwQmFzZSA9IGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8KLSAgICAgICAgaWYgKHByb3BlcnR5SWQgPT0gQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVgKLSAgICAgICAgICAgICAgICArIENvbnN0YW50cy5OQU1FU1BBQ0VfQ09OVEVYVF9QUk9QRVJUWSkgewotICAgICAgICAgICAgZk5hbWVzcGFjZUNvbnRleHQgPSAoWEluY2x1ZGVOYW1lc3BhY2VTdXBwb3J0KSB2YWx1ZTsKLSAgICAgICAgfQotCi0gICAgICAgIHN1cGVyLnNldFByb3BlcnR5KHByb3BlcnR5SWQsIHZhbHVlKTsKLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3hwb2ludGVyL1hQb2ludGVyTWVzc2FnZUZvcm1hdHRlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHBvaW50ZXIvWFBvaW50ZXJNZXNzYWdlRm9ybWF0dGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDYzOWJkZWYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHBvaW50ZXIvWFBvaW50ZXJNZXNzYWdlRm9ybWF0dGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5NyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cG9pbnRlcjsKLQotaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7Ci1pbXBvcnQgamF2YS51dGlsLk1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuUmVzb3VyY2VCdW5kbGU7Ci1pbXBvcnQgamF2YS51dGlsLlByb3BlcnR5UmVzb3VyY2VCdW5kbGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLk1lc3NhZ2VGb3JtYXR0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlscy5TZWN1cml0eVN1cHBvcnQ7Ci0KLS8qKgotICogWFBvaW50ZXJNZXNzYWdlRm9ybWF0dGVyIHByb3ZpZGVzIGVycm9yIG1lc3NhZ2VzIGZvciB0aGUgWFBvaW50ZXIgRnJhbWV3b3JrCi0gKiBhbmQgZWxlbWVudCgpIFNjaGVtZSBSZWNvbW1lbmRhdGlvbnMuCi0gKgotICogQHhlcmNlcy5pbnRlcm5hbAotICoKLSAqIEB2ZXJzaW9uICRJZDogWFBvaW50ZXJNZXNzYWdlRm9ybWF0dGVyLmphdmEsdiAxLjUgMjAxMC0xMS0wMSAwNDo0MDoyNiBqb2VodyBFeHAgJAotICovCi1jbGFzcyBYUG9pbnRlck1lc3NhZ2VGb3JtYXR0ZXIgaW1wbGVtZW50cyBNZXNzYWdlRm9ybWF0dGVyIHsKLQotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFhQT0lOVEVSX0RPTUFJTiA9ICJodHRwOi8vd3d3LnczLm9yZy9UUi9YUFRSIjsKLQotICAgIC8vIHByaXZhdGUgb2JqZWN0cyB0byBjYWNoZSB0aGUgbG9jYWxlIGFuZCByZXNvdXJjZSBidW5kbGUKLSAgICBwcml2YXRlIExvY2FsZSBmTG9jYWxlID0gbnVsbDsKLQotICAgIHByaXZhdGUgUmVzb3VyY2VCdW5kbGUgZlJlc291cmNlQnVuZGxlID0gbnVsbDsKLQotICAgIC8qKgotICAgICAqIEZvcm1hdHMgYSBtZXNzYWdlIHdpdGggdGhlIHNwZWNpZmllZCBhcmd1bWVudHMgdXNpbmcgdGhlIGdpdmVuIGxvY2FsZQotICAgICAqIGluZm9ybWF0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIGxvY2FsZQotICAgICAqICAgICAgICAgICAgVGhlIGxvY2FsZSBvZiB0aGUgbWVzc2FnZS4KLSAgICAgKiBAcGFyYW0ga2V5Ci0gICAgICogICAgICAgICAgICBUaGUgbWVzc2FnZSBrZXkuCi0gICAgICogQHBhcmFtIGFyZ3VtZW50cwotICAgICAqICAgICAgICAgICAgVGhlIG1lc3NhZ2UgcmVwbGFjZW1lbnQgdGV4dCBhcmd1bWVudHMuIFRoZSBvcmRlciBvZiB0aGUKLSAgICAgKiAgICAgICAgICAgIGFyZ3VtZW50cyBtdXN0IG1hdGNoIHRoYXQgb2YgdGhlIHBsYWNlaG9sZGVycyBpbiB0aGUgYWN0dWFsCi0gICAgICogICAgICAgICAgICBtZXNzYWdlLgotICAgICAqCi0gICAgICogQHJldHVybiBSZXR1cm5zIHRoZSBmb3JtYXR0ZWQgbWVzc2FnZS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uCi0gICAgICogICAgICAgICAgICAgVGhyb3duIGlmIHRoZSBtZXNzYWdlIHdpdGggdGhlIHNwZWNpZmllZCBrZXkgY2Fubm90IGJlIGZvdW5kLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZm9ybWF0TWVzc2FnZShMb2NhbGUgbG9jYWxlLCBTdHJpbmcga2V5LCBPYmplY3RbXSBhcmd1bWVudHMpCi0gICAgICAgICAgICB0aHJvd3MgTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uIHsKLQotICAgICAgICBpZiAoZlJlc291cmNlQnVuZGxlID09IG51bGwgfHwgbG9jYWxlICE9IGZMb2NhbGUpIHsKLSAgICAgICAgICAgIGlmIChsb2NhbGUgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZSZXNvdXJjZUJ1bmRsZSA9IFNlY3VyaXR5U3VwcG9ydC5nZXRSZXNvdXJjZUJ1bmRsZSgKLSAgICAgICAgICAgICAgICAgICAgICAgICJjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwubXNnLlhQb2ludGVyTWVzc2FnZXMiLCBsb2NhbGUpOwotICAgICAgICAgICAgICAgIC8vIG1lbW9yaXplIHRoZSBtb3N0LXJlY2VudCBsb2NhbGUKLSAgICAgICAgICAgICAgICBmTG9jYWxlID0gbG9jYWxlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKGZSZXNvdXJjZUJ1bmRsZSA9PSBudWxsKQotICAgICAgICAgICAgICAgIGZSZXNvdXJjZUJ1bmRsZSA9IFNlY3VyaXR5U3VwcG9ydC5nZXRSZXNvdXJjZUJ1bmRsZSgKLSAgICAgICAgICAgICAgICAgICAgICAgICJjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwubXNnLlhQb2ludGVyTWVzc2FnZXMiKTsKLSAgICAgICAgfQotCi0gICAgICAgIFN0cmluZyBtc2cgPSBmUmVzb3VyY2VCdW5kbGUuZ2V0U3RyaW5nKGtleSk7Ci0gICAgICAgIGlmIChhcmd1bWVudHMgIT0gbnVsbCkgewotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICBtc2cgPSBqYXZhLnRleHQuTWVzc2FnZUZvcm1hdC5mb3JtYXQobXNnLCBhcmd1bWVudHMpOwotICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICBtc2cgPSBmUmVzb3VyY2VCdW5kbGUuZ2V0U3RyaW5nKCJGb3JtYXRGYWlsZWQiKTsKLSAgICAgICAgICAgICAgICBtc2cgKz0gIiAiICsgZlJlc291cmNlQnVuZGxlLmdldFN0cmluZyhrZXkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKG1zZyA9PSBudWxsKSB7Ci0gICAgICAgICAgICBtc2cgPSBmUmVzb3VyY2VCdW5kbGUuZ2V0U3RyaW5nKCJCYWRNZXNzYWdlS2V5Iik7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uKG1zZywKLSAgICAgICAgICAgICAgICAgICAgImNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5tc2cuWFBvaW50ZXJNZXNzYWdlcyIsIGtleSk7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gbXNnOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3hwb2ludGVyL1hQb2ludGVyUGFydC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHBvaW50ZXIvWFBvaW50ZXJQYXJ0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDY2N2ZhY2UuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHBvaW50ZXIvWFBvaW50ZXJQYXJ0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMzIgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHBvaW50ZXI7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5BdWdtZW50YXRpb25zOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlFOYW1lOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTEF0dHJpYnV0ZXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE5JRXhjZXB0aW9uOwotCi0vKioKLSAqIDxwPgotICogVXNlZCBmb3Igc2NoZW1lIHNwZWNpZmljIHBhcnNpbmcgYW5kIGV2YWx1YXRpb24gb2YgYW4gWFBvaW50ZXIgZXhwcmVzc2lvbi4KLSAqIFRoaXMgaW50ZXJmYWNlIGFwcGxpZXMgdG8gYm90aCBTaG9ydEhhbmQgYW5kIFNjaGVtZUJhc2VkIFhQb2ludGVyCi0gKiBleHByZXNzaW9ucy4KLSAqIDwvcD4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICovCi1wdWJsaWMgaW50ZXJmYWNlIFhQb2ludGVyUGFydCB7Ci0KLSAgICAvLyBUaGUgc3RhcnQgZWxlbWVudCBldmVudAotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVWRU5UX0VMRU1FTlRfU1RBUlQgPSAwOwotCi0gICAgLy8gVGhlIGVuZCBlbGVtZW50IGV2ZW50Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVZFTlRfRUxFTUVOVF9FTkQgPSAxOwotCi0gICAgLy8gVGhlIGVtcHR5IGVsZW1lbnQgZXZlbnQKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFVkVOVF9FTEVNRU5UX0VNUFRZID0gMjsKLQotICAgIC8qKgotICAgICAqIFByb3ZpZGVzIHNjaGVtZSBzcGVjaWZpYyBwYXJzaW5nIG9mIGEgWFBvaW50ZXIgZXhwcmVzc2lvbiBpLmUuCi0gICAgICogdGhlIFBvaW50ZXJQYXJ0IG9yIFNob3J0SGFuZFBvaW50ZXIuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gIHhwb2ludGVyIEEgU3RyaW5nIHJlcHJlc2VudGluZyB0aGUgUG9pbnRlclBhcnQgb3IgU2hvcnRIYW5kUG9pbnRlci4KLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gaWYgdGhlIFBvaW50ZXJQYXJ0IHN0cmluZyBkb2VzIG5vdCBjb25mb3JtIHRvCi0gICAgICogICAgICAgICB0aGUgc3ludGF4IGRlZmluZWQgYnkgaXRzIHNjaGVtZS4KLSAgICAgKgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHBhcnNlWFBvaW50ZXIoU3RyaW5nIHBhcnQpIHRocm93cyBYTklFeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBFdmFsdWF0ZXMgYW4gWE1MIHJlc291cmNlIHdpdGggcmVzcGVjdCB0byBhbiBYUG9pbnRlciBleHByZXNzaW9ucwotICAgICAqIGJ5IGNoZWNraW5nIGlmIGl0J3MgZWxlbWVudCBhbmQgYXR0cmlidXRlcyBwYXJhbWV0ZXJzIG1hdGNoIHRoZQotICAgICAqIGNyaXRlcmlhIHNwZWNpZmllZCBpbiB0aGUgeHBvaW50ZXIgZXhwcmVzc2lvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlbGVtZW50IC0gVGhlIG5hbWUgb2YgdGhlIGVsZW1lbnQuCi0gICAgICogQHBhcmFtIGF0dHJpYnV0ZXMgLSBUaGUgZWxlbWVudCBhdHRyaWJ1dGVzLgotICAgICAqIEBwYXJhbSBhdWdzIC0gQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqIEBwYXJhbSBldmVudCAtIEFuIGludGVnZXIgaW5kaWNhdGluZwotICAgICAqICAgICAgICAgICAgICAgIDAgLSBUaGUgc3RhcnQgb2YgYW4gZWxlbWVudAotICAgICAqICAgICAgICAgICAgICAgIDEgLSBUaGUgZW5kIG9mIGFuIGVsZW1lbnQKLSAgICAgKiAgICAgICAgICAgICAgICAyIC0gQW4gZW1wdHkgZWxlbWVudCBjYWxsCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIHRvIHNpZ25hbCBhbiBlcnJvcgotICAgICAqCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gcmVzb2x2ZVhQb2ludGVyKFFOYW1lIGVsZW1lbnQsIFhNTEF0dHJpYnV0ZXMgYXR0cmlidXRlcywKLSAgICAgICAgICAgIEF1Z21lbnRhdGlvbnMgYXVncywgaW50IGV2ZW50KSB0aHJvd3MgWE5JRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBYUG9pbnRlciBleHByZXNzaW9uIHJlc29sdmVzIHRvIGEgcmVzb3VyY2UgZnJhZ21lbnQKLSAgICAgKiBzcGVjaWZpZWQgYXMgaW5wdXQgZWxzZSByZXR1cm5zIGZhbHNlLgotICAgICAqCi0gICAgICogQHJldHVybiBUcnVlIGlmIHRoZSB4cG9pbnRlciBleHByZXNzaW9uIG1hdGNoZXMgYSBmcmFnbWVudCBpbiB0aGUgcmVzb3VyY2UKLSAgICAgKiAgICAgICAgIGVsc2UgcmV0dXJucyBmYWxzZS4KLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gdG8gc2lnbmFsIGFuIGVycm9yCi0gICAgICoKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0ZyYWdtZW50UmVzb2x2ZWQoKSB0aHJvd3MgWE5JRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBYUG9pbnRlciBleHByZXNzaW9uIHJlc29sdmVzIHRvIGEgbm9uLWVsZW1lbnQgY2hpbGQKLSAgICAgKiBvZiB0aGUgY3VycmVudCByZXNvdXJjZSBmcmFnbWVudC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVHJ1ZSBpZiB0aGUgWFBvaW50ZXIgZXhwcmVzc2lvbiByZXNvbHZlcyB0byBhIG5vbi1lbGVtZW50IGNoaWxkCi0gICAgICogICAgICAgICBvZiB0aGUgY3VycmVudCByZXNvdXJjZSBmcmFnbWVudC4KLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gdG8gc2lnbmFsIGFuIGVycm9yCi0gICAgICoKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0NoaWxkRnJhZ21lbnRSZXNvbHZlZCgpIHRocm93cyBYTklFeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGEgU3RyaW5nIGNvbnRhaW5pbmcgdGhlIHNjaGVtZSBuYW1lIG9mIHRoZSBQb2ludGVyUGFydAotICAgICAqIG9yIHRoZSBuYW1lIG9mIHRoZSBTaG9ydEhhbmQgUG9pbnRlci4KLSAgICAgKgotICAgICAqIEByZXR1cm4gQSBTdHJpbmcgY29udGFpbmluZyB0aGUgc2NoZW1lIG5hbWUgb2YgdGhlIFBvaW50ZXJQYXJ0LgotICAgICAqCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRTY2hlbWVOYW1lKCk7Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGEgU3RyaW5nIGNvbnRhaW5pbmcgdGhlIHNjaGVtZSBkYXRhIG9mIHRoZSBQb2ludGVyUGFydC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gQSBTdHJpbmcgY29udGFpbmluZyB0aGUgc2NoZW1lIGRhdGEgb2YgdGhlIFBvaW50ZXJQYXJ0LgotICAgICAqCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRTY2hlbWVEYXRhKCk7Ci0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSBzY2hlbWUgbmFtZSBvZiB0aGUgUG9pbnRlclBhcnQgb3IgdGhlIFNob3J0SGFuZCBQb2ludGVyIG5hbWUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc2NoZW1lTmFtZSBBIFN0cmluZyBjb250YWluaW5nIHRoZSBzY2hlbWUgbmFtZSBvZiB0aGUgUG9pbnRlclBhcnQuCi0gICAgICoKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRTY2hlbWVOYW1lKFN0cmluZyBzY2hlbWVOYW1lKTsKLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIHNjaGVtZSBkYXRhIG9mIHRoZSBQb2ludGVyUGFydC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzY2hlbWVEYXRhIEEgU3RyaW5nIGNvbnRhaW5pbmcgdGhlIHNjaGVtZSBkYXRhIG9mIHRoZSBQb2ludGVyUGFydC4KLSAgICAgKgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFNjaGVtZURhdGEoU3RyaW5nIHNjaGVtZURhdGEpOwotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94cG9pbnRlci9YUG9pbnRlclByb2Nlc3Nvci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHBvaW50ZXIvWFBvaW50ZXJQcm9jZXNzb3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYzZlNzQ2ZS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94cG9pbnRlci9YUG9pbnRlclByb2Nlc3Nvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTA0ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHBvaW50ZXI7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5BdWdtZW50YXRpb25zOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlFOYW1lOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTEF0dHJpYnV0ZXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE5JRXhjZXB0aW9uOwotCi0vKioKLSAqIDxwPgotICogVGhlIFhQb2ludGVyUHJvY2Vzc29yIGlzIHJlc3BvbnNpYmxlIGZvciBwYXJzaW5nIGFuIFhQb2ludGVyCi0gKiBleHByZXNzaW9uIGFuZCBhbmQgcHJvdmlkaW5nIHNjaGVtZSBzcGVjaWZpYyByZXNvbHV0aW9uIG9mCi0gKiB0aGUgZG9jdW1lbnQgZnJhZ21lbnQgcG9pbnRlZCB0byBiZSB0aGUgcG9pbnRlci4KLSAqIDwvcD4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKgotICoKLSAqLwotcHVibGljIGludGVyZmFjZSBYUG9pbnRlclByb2Nlc3NvciB7Ci0KLSAgICAvLyBUaGUgc3RhcnQgZWxlbWVudCBldmVudAotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVWRU5UX0VMRU1FTlRfU1RBUlQgPSAwOwotCi0gICAgLy8gVGhlIGVuZCBlbGVtZW50IGV2ZW50Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVZFTlRfRUxFTUVOVF9FTkQgPSAxOwotCi0gICAgLy8gVGhlIGVtcHR5IGVsZW1lbnQgZXZlbnQKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFVkVOVF9FTEVNRU5UX0VNUFRZID0gMjsKLQotICAgIC8qKgotICAgICAqIFBhcnNlcyBhbiBYUG9pbnRlciBleHByZXNzaW9uLiAgSXQgcGVyZm9ybXMgc2NoZW1lIHNwZWNpZmljIHByb2Nlc3NpbmcKLSAgICAgKiBkZXBlbmRpbmcgb24gdGhlIHBvaW50ZXIgcGFydHMgYW5kIHNldHMgdXAgYSBWZWN0b3Igb2YgWFBvaW50ZXJQYXJ0cwotICAgICAqIGluIHRoZSBvcmRlciAobGVmdC10by1yaWdodCkgdGhleSBhcHBlYXIgaW4gdGhlIFhQb2ludGVyIGV4cHJlc3Npb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gIHhwb2ludGVyIEEgU3RyaW5nIHJlcHJlc2VudGluZyB0aGUgeHBvaW50ZXIgZXhwcmVzc2lvbi4KLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gaWYgdGhlIHhwb2ludGVyIHN0cmluZyBkb2VzIG5vdCBjb25mb3JtIHRvCi0gICAgICogICAgICAgICB0aGUgWFBvaW50ZXIgRnJhbWV3b3JrIHN5bnRheCBvciB0aGUgc3ludGF4IG9mIHRoZSBwb2ludGVyIHBhcnQgZG9lcwotICAgICAqICAgICAgICAgbm90IGNvbmZvcm0gdG8gaXRzIGRlZmluaXRpb24gZm9yIGl0cyBzY2hlbWUuCi0gICAgICoKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBwYXJzZVhQb2ludGVyKFN0cmluZyB4cG9pbnRlcikgdGhyb3dzIFhOSUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIEV2YWx1YXRlcyBhbiBYTUwgcmVzb3VyY2Ugd2l0aCByZXNwZWN0IHRvIGFuIFhQb2ludGVyIGV4cHJlc3Npb25zCi0gICAgICogYnkgY2hlY2tpbmcgaWYgaXQncyBlbGVtZW50IGFuZCBhdHRyaWJ1dGVzIHBhcmFtZXRlcnMgbWF0Y2ggdGhlCi0gICAgICogY3JpdGVyaWEgc3BlY2lmaWVkIGluIHRoZSB4cG9pbnRlciBleHByZXNzaW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIGVsZW1lbnQgLSBUaGUgbmFtZSBvZiB0aGUgZWxlbWVudC4KLSAgICAgKiBAcGFyYW0gYXR0cmlidXRlcyAtIFRoZSBlbGVtZW50IGF0dHJpYnV0ZXMuCi0gICAgICogQHBhcmFtIGF1Z3MgLSBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICogQHBhcmFtIGV2ZW50IC0gQW4gaW50ZWdlciBpbmRpY2F0aW5nCi0gICAgICogICAgICAgICAgICAgICAgMCAtIFRoZSBzdGFydCBvZiBhbiBlbGVtZW50Ci0gICAgICogICAgICAgICAgICAgICAgMSAtIFRoZSBlbmQgb2YgYW4gZWxlbWVudAotICAgICAqICAgICAgICAgICAgICAgIDIgLSBBbiBlbXB0eSBlbGVtZW50IGNhbGwKLSAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGVsZW1lbnQgd2FzIHJlc29sdmVkIGJ5IHRoZSB4cG9pbnRlcgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biB0byBzaWduYWwgYW4gZXJyb3IKLSAgICAgKgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIHJlc29sdmVYUG9pbnRlcihRTmFtZSBlbGVtZW50LCBYTUxBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMsCi0gICAgICAgICAgICBBdWdtZW50YXRpb25zIGF1Z3MsIGludCBldmVudCkgdGhyb3dzIFhOSUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgWFBvaW50ZXIgZXhwcmVzc2lvbiByZXNvbHZlcyB0byB0aGUgY3VycmVudCByZXNvdXJjZSBmcmFnbWVudAotICAgICAqIG9yIE5vZGUgd2hpY2ggaXMgcGFydCBvZiB0aGUgaW5wdXQgcmVzb3VyY2UgYmVpbmcgc3RyZWFtZWQgZWxzZSByZXR1cm5zIGZhbHNlLgotICAgICAqCi0gICAgICogQHJldHVybiBUcnVlIGlmIHRoZSB4cG9pbnRlciBleHByZXNzaW9uIG1hdGNoZXMgYSBub2RlL2ZyYWdtZW50IGluIHRoZSByZXNvdXJjZQotICAgICAqICAgICAgICAgZWxzZSByZXR1cm5zIGZhbHNlLgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biB0byBzaWduYWwgYW4gZXJyb3IKLSAgICAgKgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzRnJhZ21lbnRSZXNvbHZlZCgpIHRocm93cyBYTklFeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIFhQb2ludGVyIGV4cHJlc3Npb24gcmVzb2x2ZXMgYW55IHN1YnJlc291cmNlIG9mIHRoZQotICAgICAqIGlucHV0IHJlc291cmNlLgotICAgICAqCi0gICAgICogQHJldHVybiBUcnVlIGlmIHRoZSB4cG9pbnRlciBleHByZXNzaW9uIG1hdGNoZXMgYSBmcmFnbWVudCBpbiB0aGUgcmVzb3VyY2UKLSAgICAgKiAgICAgICAgIGVsc2UgcmV0dXJucyBmYWxzZS4KLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gdG8gc2lnbmFsIGFuIGVycm9yCi0gICAgICoKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc1hQb2ludGVyUmVzb2x2ZWQoKSB0aHJvd3MgWE5JRXhjZXB0aW9uOwotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94cy9BdHRyaWJ1dGVQU1ZJLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94cy9BdHRyaWJ1dGVQU1ZJLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDViMDk3OWIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHMvQXR0cmlidXRlUFNWSS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzMgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMywyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzOwotCi0vKioKLSAqICBSZXByZXNlbnRzIGEgUFNWSSBpdGVtIGZvciBvbmUgYXR0cmlidXRlIGluZm9ybWF0aW9uIGl0ZW0uCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgQXR0cmlidXRlUFNWSSBleHRlbmRzIEl0ZW1QU1ZJIHsKLSAgICAvKioKLSAgICAgKiBbYXR0cmlidXRlIGRlY2xhcmF0aW9uXTogQW4gaXRlbSBpc29tb3JwaGljIHRvIHRoZSBkZWNsYXJhdGlvbgotICAgICAqIGNvbXBvbmVudCBpdHNlbGYuCi0gICAgICovCi0gICAgcHVibGljIFhTQXR0cmlidXRlRGVjbGFyYXRpb24gZ2V0QXR0cmlidXRlRGVjbGFyYXRpb24oKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHMvRWxlbWVudFBTVkkuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3hzL0VsZW1lbnRQU1ZJLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGYzYTY4YWMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHMvRWxlbWVudFBTVkkuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDUwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDMsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54czsKLQotLyoqCi0gKiAgUmVwcmVzZW50cyBhIFBTVkkgaXRlbSBmb3Igb25lIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbS4KLSAqLwotcHVibGljIGludGVyZmFjZSBFbGVtZW50UFNWSSBleHRlbmRzIEl0ZW1QU1ZJIHsKLSAgICAvKioKLSAgICAgKiBbZWxlbWVudCBkZWNsYXJhdGlvbl06IGFuIGl0ZW0gaXNvbW9ycGhpYyB0byB0aGUgZWxlbWVudCBkZWNsYXJhdGlvbgotICAgICAqIHVzZWQgdG8gdmFsaWRhdGUgdGhpcyBlbGVtZW50LgotICAgICAqLwotICAgIHB1YmxpYyBYU0VsZW1lbnREZWNsYXJhdGlvbiBnZXRFbGVtZW50RGVjbGFyYXRpb24oKTsKLQotICAgIC8qKgotICAgICAqICBbbm90YXRpb25dOiB0aGUgbm90YXRpb24gZGVjbGFyYXRpb24uCi0gICAgICovCi0gICAgcHVibGljIFhTTm90YXRpb25EZWNsYXJhdGlvbiBnZXROb3RhdGlvbigpOwotCi0gICAgLyoqCi0gICAgICogW25pbF06IHRydWUgaWYgY2xhdXNlIDMuMiBvZiBFbGVtZW50IExvY2FsbHkgVmFsaWQgKEVsZW1lbnQpICgzLjMuNCkgaXMKLSAgICAgKiBzYXRpc2ZpZWQsIG90aGVyd2lzZSBmYWxzZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXROaWwoKTsKLQotICAgIC8qKgotICAgICAqIHNjaGVtYSBpbmZvcm1hdGlvbjogdGhlIHNjaGVtYSBpbmZvcm1hdGlvbiBwcm9wZXJ0eSBpZiBpdCBpcyB0aGUKLSAgICAgKiB2YWxpZGF0aW9uIHJvb3QsIDxjb2RlPm51bGw8L2NvZGU+IG90aGVyd2lzZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFNNb2RlbCBnZXRTY2hlbWFJbmZvcm1hdGlvbigpOwotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94cy9JdGVtUFNWSS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHMvSXRlbVBTVkkuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNDhkODYzZS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94cy9JdGVtUFNWSS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTg5ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDMsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54czsKLQotLyoqCi0gKiAgUmVwcmVzZW50cyBhbiBhYnN0cmFjdCBQU1ZJIGl0ZW0gZm9yIGFuIGVsZW1lbnQgb3IgYW4gYXR0cmlidXRlCi0gKiBpbmZvcm1hdGlvbiBpdGVtLgotICovCi1wdWJsaWMgaW50ZXJmYWNlIEl0ZW1QU1ZJIHsKLSAgICAvKioKLSAgICAgKiBWYWxpZGl0eSB2YWx1ZSBpbmRpY2F0aW5nIHRoYXQgdmFsaWRhdGlvbiBoYXMgZWl0aGVyIG5vdCBiZWVuIHBlcmZvcm1lZAotICAgICAqIG9yIHRoYXQgYSBzdHJpY3QgYXNzZXNzbWVudCBvZiB2YWxpZGl0eSBjb3VsZCBub3QgYmUgcGVyZm9ybWVkLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgVkFMSURJVFlfTk9US05PV04gICAgICAgICA9IDA7Ci0gICAgLyoqCi0gICAgICogIFZhbGlkaXR5IHZhbHVlIGluZGljYXRpbmcgdGhhdCB2YWxpZGF0aW9uIGhhcyBiZWVuIHN0cmljdGx5IGFzc2Vzc2VkCi0gICAgICogYW5kIHRoZSBpdGVtIGluIHF1ZXN0aW9uIGlzIGludmFsaWQgYWNjb3JkaW5nIHRvIHRoZSBydWxlcyBvZiBzY2hlbWEKLSAgICAgKiB2YWxpZGF0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgVkFMSURJVFlfSU5WQUxJRCAgICAgICAgICA9IDE7Ci0gICAgLyoqCi0gICAgICogIFZhbGlkYXRpb24gc3RhdHVzIGluZGljYXRpbmcgdGhhdCBzY2hlbWEgdmFsaWRhdGlvbiBoYXMgYmVlbiBwZXJmb3JtZWQKLSAgICAgKiBhbmQgdGhlIGl0ZW0gaW4gcXVlc3Rpb24gaXMgdmFsaWQgYWNjb3JkaW5nIHRvIHRoZSBydWxlcyBvZiBzY2hlbWEKLSAgICAgKiB2YWxpZGF0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgVkFMSURJVFlfVkFMSUQgICAgICAgICAgICA9IDI7Ci0gICAgLyoqCi0gICAgICogIFZhbGlkYXRpb24gc3RhdHVzIGluZGljYXRpbmcgdGhhdCBzY2hlbWEgdmFsaWRhdGlvbiBoYXMgYmVlbiBwZXJmb3JtZWQKLSAgICAgKiBhbmQgdGhlIGl0ZW0gaW4gcXVlc3Rpb24gaGFzIHNwZWNpZmljYWxseSBiZWVuIHNraXBwZWQuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBWQUxJREFUSU9OX05PTkUgICAgICAgICAgID0gMDsKLSAgICAvKioKLSAgICAgKiBWYWxpZGF0aW9uIHN0YXR1cyBpbmRpY2F0aW5nIHRoYXQgc2NoZW1hIHZhbGlkYXRpb24gaGFzIGJlZW4gcGVyZm9ybWVkCi0gICAgICogb24gdGhlIGl0ZW0gaW4gcXVlc3Rpb24gdW5kZXIgdGhlIHJ1bGVzIG9mIGxheCB2YWxpZGF0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgVkFMSURBVElPTl9QQVJUSUFMICAgICAgICA9IDE7Ci0gICAgLyoqCi0gICAgICogIFZhbGlkYXRpb24gc3RhdHVzIGluZGljYXRpbmcgdGhhdCBmdWxsIHNjaGVtYSB2YWxpZGF0aW9uIGhhcyBiZWVuCi0gICAgICogcGVyZm9ybWVkIG9uIHRoZSBpdGVtLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgVkFMSURBVElPTl9GVUxMICAgICAgICAgICA9IDI7Ci0gICAgLyoqCi0gICAgICogIFRoZSBuZWFyZXN0IGFuY2VzdG9yIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSB3aXRoIGEKLSAgICAgKiA8Y29kZT5bc2NoZW1hIGluZm9ybWF0aW9uXTwvY29kZT4gcHJvcGVydHkgKG9yIHRoaXMgZWxlbWVudCBpdGVtCi0gICAgICogaXRzZWxmIGlmIGl0IGhhcyBzdWNoIGEgcHJvcGVydHkpLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiByZWZlciB0bwotICAgICAqIGVsZW1lbnQgdmFsaWRhdGlvbiBjb250ZXh0IGFuZCBhdHRyaWJ1dGUgdmFsaWRhdGlvbiBjb250ZXh0IC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFZhbGlkYXRpb25Db250ZXh0KCk7Ci0KLSAgICAvKioKLSAgICAgKiAgPGNvZGU+W3ZhbGlkaXR5XTwvY29kZT46IGRldGVybWluZXMgdGhlIHZhbGlkaXR5IG9mIHRoZSBzY2hlbWEgaXRlbQotICAgICAqIHdpdGggcmVzcGVjdCB0byB0aGUgdmFsaWRhdGlvbiBiZWluZyBhdHRlbXB0ZWQuIFRoZSB2YWx1ZSB3aWxsIGJlIG9uZQotICAgICAqIG9mIHRoZSBjb25zdGFudHM6IDxjb2RlPlZBTElESVRZX05PVEtOT1dOPC9jb2RlPiwKLSAgICAgKiA8Y29kZT5WQUxJRElUWV9JTlZBTElEPC9jb2RlPiBvciA8Y29kZT5WQUxJRElUWV9WQUxJRDwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIHNob3J0IGdldFZhbGlkaXR5KCk7Ci0KLSAgICAvKioKLSAgICAgKiAgPGNvZGU+W3ZhbGlkYXRpb24gYXR0ZW1wdGVkXTwvY29kZT46IGRldGVybWluZXMgdGhlIGV4dGVudCB0byB3aGljaAotICAgICAqIHRoZSBzY2hlbWEgaXRlbSBoYXMgYmVlbiB2YWxpZGF0ZWQuIFRoZSB2YWx1ZSB3aWxsIGJlIG9uZSBvZiB0aGUKLSAgICAgKiBjb25zdGFudHM6IDxjb2RlPlZBTElEQVRJT05fTk9ORTwvY29kZT4sCi0gICAgICogPGNvZGU+VkFMSURBVElPTl9QQVJUSUFMPC9jb2RlPiBvciA8Y29kZT5WQUxJREFUSU9OX0ZVTEw8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBzaG9ydCBnZXRWYWxpZGF0aW9uQXR0ZW1wdGVkKCk7Ci0KLSAgICAvKioKLSAgICAgKiAgPGNvZGU+W3NjaGVtYSBlcnJvciBjb2RlXTwvY29kZT46IGEgbGlzdCBvZiBlcnJvciBjb2RlcyBnZW5lcmF0ZWQgZnJvbQotICAgICAqIHRoZSB2YWxpZGF0aW9uIGF0dGVtcHQgb3IgYW4gZW1wdHkgPGNvZGU+U3RyaW5nTGlzdDwvY29kZT4gaWYgbm8KLSAgICAgKiBlcnJvcnMgb2NjdXJyZWQgZHVyaW5nIHRoZSB2YWxpZGF0aW9uIGF0dGVtcHQuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZ0xpc3QgZ2V0RXJyb3JDb2RlcygpOwotCi0gICAgLyoqCi0gICAgICogPGNvZGU+W3NjaGVtYSBub3JtYWxpemVkIHZhbHVlXTwvY29kZT46IHRoZSBub3JtYWxpemVkIHZhbHVlIG9mIHRoaXMKLSAgICAgKiBpdGVtIGFmdGVyIHZhbGlkYXRpb24uCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRTY2hlbWFOb3JtYWxpemVkVmFsdWUoKTsKLQotICAgIC8qKgotICAgICAqIDxjb2RlPltzY2hlbWEgbm9ybWFsaXplZCB2YWx1ZV08L2NvZGU+OiBCaW5kaW5nIHNwZWNpZmljIGFjdHVhbCB2YWx1ZQotICAgICAqIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoZSB2YWx1ZSBpcyBpbiBlcnJvci4KLSAgICAgKiBAZXhjZXB0aW9uIFhTRXhjZXB0aW9uCi0gICAgICogICBOT1RfU1VQUE9SVEVEX0VSUjogUmFpc2VkIGlmIHRoZSBpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdCBzdXBwb3J0IHRoaXMKLSAgICAgKiAgIG1ldGhvZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0IGdldEFjdHVhbE5vcm1hbGl6ZWRWYWx1ZSgpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBYU0V4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIFRoZSBhY3R1YWwgdmFsdWUgYnVpbHQtaW4gZGF0YXR5cGUsIGUuZy4KLSAgICAgKiA8Y29kZT5TVFJJTkdfRFQsIFNIT1JUX0RUPC9jb2RlPi4gSWYgdGhlIHR5cGUgZGVmaW5pdGlvbiBvZiB0aGlzCi0gICAgICogdmFsdWUgaXMgYSBsaXN0IHR5cGUgZGVmaW5pdGlvbiwgdGhpcyBtZXRob2QgcmV0dXJucwotICAgICAqIDxjb2RlPkxJU1RfRFQ8L2NvZGU+LiBJZiB0aGUgdHlwZSBkZWZpbml0aW9uIG9mIHRoaXMgdmFsdWUgaXMgYSBsaXN0Ci0gICAgICogdHlwZSBkZWZpbml0aW9uIHdob3NlIGl0ZW0gdHlwZSBpcyBhIHVuaW9uIHR5cGUgZGVmaW5pdGlvbiwgdGhpcwotICAgICAqIG1ldGhvZCByZXR1cm5zIDxjb2RlPkxJU1RPRlVOSU9OX0RUPC9jb2RlPi4gVG8gcXVlcnkgdGhlIGFjdHVhbCB2YWx1ZQotICAgICAqIG9mIHRoZSBsaXN0IG9yIGxpc3Qgb2YgdW5pb24gdHlwZSBkZWZpbml0aW9ucyB1c2UKLSAgICAgKiA8Y29kZT5pdGVtVmFsdWVUeXBlczwvY29kZT4uIElmIHRoZSA8Y29kZT5hY3R1YWxOb3JtYWxpemVkVmFsdWU8L2NvZGU+Ci0gICAgICogIGlzIDxjb2RlPm51bGw8L2NvZGU+LCB0aGlzIG1ldGhvZCByZXR1cm5zIDxjb2RlPlVOQVZBSUxBQkxFX0RUPC9jb2RlPgotICAgICAqIC4KLSAgICAgKiBAZXhjZXB0aW9uIFhTRXhjZXB0aW9uCi0gICAgICogICBOT1RfU1VQUE9SVEVEX0VSUjogUmFpc2VkIGlmIHRoZSBpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdCBzdXBwb3J0IHRoaXMKLSAgICAgKiAgIG1ldGhvZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgc2hvcnQgZ2V0QWN0dWFsTm9ybWFsaXplZFZhbHVlVHlwZSgpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBYU0V4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIEluIHRoZSBjYXNlIHRoZSBhY3R1YWwgdmFsdWUgcmVwcmVzZW50cyBhIGxpc3QsIGkuZS4gdGhlCi0gICAgICogPGNvZGU+YWN0dWFsTm9ybWFsaXplZFZhbHVlVHlwZTwvY29kZT4gaXMgPGNvZGU+TElTVF9EVDwvY29kZT4sIHRoZQotICAgICAqIHJldHVybmVkIGFycmF5IGNvbnNpc3RzIG9mIG9uZSB0eXBlIGtpbmQgd2hpY2ggcmVwcmVzZW50cyB0aGUgaXRlbVR5cGUKLSAgICAgKiAuIEZvciBleGFtcGxlOgotICAgICAqIDxwcmU+ICZsdDtzaW1wbGVUeXBlIG5hbWU9Imxpc3R0eXBlIiZndDsgJmx0O2xpc3QKLSAgICAgKiBpdGVtVHlwZT0icG9zaXRpdmVJbnRlZ2VyIi8mZ3Q7ICZsdDsvc2ltcGxlVHlwZSZndDsgJmx0O2VsZW1lbnQKLSAgICAgKiBuYW1lPSJsaXN0IiB0eXBlPSJsaXN0dHlwZSIvJmd0OyAuLi4gJmx0O2xpc3QmZ3Q7MSAyIDMmbHQ7L2xpc3QmZ3Q7IDwvcHJlPgotICAgICAqCi0gICAgICogVGhlIDxjb2RlPnNjaGVtYU5vcm1hbGl6ZWRWYWx1ZTwvY29kZT4gdmFsdWUgaXMgIjEgMiAzIiwgdGhlCi0gICAgICogPGNvZGU+YWN0dWFsTm9ybWFsaXplZFZhbHVlVHlwZTwvY29kZT4gdmFsdWUgaXMgPGNvZGU+TElTVF9EVDwvY29kZT4sCi0gICAgICogYW5kIHRoZSA8Y29kZT5pdGVtVmFsdWVUeXBlczwvY29kZT4gaXMgYW4gYXJyYXkgb2Ygc2l6ZSAxIHdpdGggdGhlCi0gICAgICogdmFsdWUgPGNvZGU+UE9TSVRJVkVJTlRFR0VSX0RUPC9jb2RlPi4KLSAgICAgKiA8YnI+IElmIHRoZSBhY3R1YWwgdmFsdWUgcmVwcmVzZW50cyBhIGxpc3QgdHlwZSBkZWZpbml0aW9uIHdob3NlIGl0ZW0KLSAgICAgKiB0eXBlIGlzIGEgdW5pb24gdHlwZSBkZWZpbml0aW9uLCBpLmUuIDxjb2RlPkxJU1RPRlVOSU9OX0RUPC9jb2RlPiwKLSAgICAgKiBmb3IgZWFjaCBhY3R1YWwgdmFsdWUgaW4gdGhlIGxpc3QgdGhlIGFycmF5IGNvbnRhaW5zIHRoZQotICAgICAqIGNvcnJlc3BvbmRpbmcgbWVtYmVyVHlwZSBraW5kLiBGb3IgZXhhbXBsZToKLSAgICAgKiA8cHJlPiAmbHQ7c2ltcGxlVHlwZQotICAgICAqIG5hbWU9J3VuaW9uX3R5cGUnIG1lbWJlclR5cGVzPSJpbnRlZ2VyIHN0cmluZyIvJmd0OyAmbHQ7c2ltcGxlVHlwZQotICAgICAqIG5hbWU9J2xpc3RPZlVuaW9uJyZndDsgJmx0O2xpc3QgaXRlbVR5cGU9J3VuaW9uX3R5cGUnLyZndDsKLSAgICAgKiAmbHQ7L3NpbXBsZVR5cGUmZ3Q7ICZsdDtlbGVtZW50IG5hbWU9Imxpc3QiIHR5cGU9Imxpc3RPZlVuaW9uIi8mZ3Q7Ci0gICAgICogLi4uICZsdDtsaXN0Jmd0OzEgMiBmb28mbHQ7L2xpc3QmZ3Q7IDwvcHJlPgotICAgICAqICBUaGUKLSAgICAgKiA8Y29kZT5zY2hlbWFOb3JtYWxpemVkVmFsdWU8L2NvZGU+IHZhbHVlIGlzICIxIDIgZm9vIiwgdGhlCi0gICAgICogPGNvZGU+YWN0dWFsTm9ybWFsaXplZFZhbHVlVHlwZTwvY29kZT4gaXMgPGNvZGU+TElTVE9GVU5JT05fRFQ8L2NvZGU+Ci0gICAgICogLCBhbmQgdGhlIDxjb2RlPml0ZW1WYWx1ZVR5cGVzPC9jb2RlPiBpcyBhbiBhcnJheSBvZiBzaXplIDMgd2l0aCB0aGUKLSAgICAgKiBmb2xsb3dpbmcgdmFsdWVzOiA8Y29kZT5JTlRFR0VSX0RULCBJTlRFR0VSX0RULCBTVFJJTkdfRFQ8L2NvZGU+LgotICAgICAqIEBleGNlcHRpb24gWFNFeGNlcHRpb24KLSAgICAgKiAgIE5PVF9TVVBQT1JURURfRVJSOiBSYWlzZWQgaWYgdGhlIGltcGxlbWVudGF0aW9uIGRvZXMgbm90IHN1cHBvcnQgdGhpcwotICAgICAqICAgbWV0aG9kLgotICAgICAqLwotICAgIHB1YmxpYyBTaG9ydExpc3QgZ2V0SXRlbVZhbHVlVHlwZXMoKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgWFNFeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiAgPGNvZGU+W3R5cGUgZGVmaW5pdGlvbl08L2NvZGU+OiBhbiBpdGVtIGlzb21vcnBoaWMgdG8gdGhlIHR5cGUKLSAgICAgKiBkZWZpbml0aW9uIHVzZWQgdG8gdmFsaWRhdGUgdGhlIHNjaGVtYSBpdGVtLgotICAgICAqLwotICAgIHB1YmxpYyBYU1R5cGVEZWZpbml0aW9uIGdldFR5cGVEZWZpbml0aW9uKCk7Ci0KLSAgICAvKioKLSAgICAgKiA8Y29kZT5bbWVtYmVyIHR5cGUgZGVmaW5pdGlvbl08L2NvZGU+OiBpZiBhbmQgb25seSBpZiB0aGF0IHR5cGUKLSAgICAgKiBkZWZpbml0aW9uIGlzIGEgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiB3aXRoIHt2YXJpZXR5fSB1bmlvbiwgb3IgYQotICAgICAqIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uIHdob3NlIHtjb250ZW50IHR5cGV9IGlzIGEgc2ltcGxlIHR5cGUKLSAgICAgKiBkZWZpbml0aW9uIHdpdGgge3ZhcmlldHl9IHVuaW9uLCB0aGVuIGFuIGl0ZW0gaXNvbW9ycGhpYyB0byB0aGF0Ci0gICAgICogbWVtYmVyIG9mIHRoZSB1bmlvbidzIHttZW1iZXIgdHlwZSBkZWZpbml0aW9uc30gd2hpY2ggYWN0dWFsbHkKLSAgICAgKiB2YWxpZGF0ZWQgdGhlIHNjaGVtYSBpdGVtJ3Mgbm9ybWFsaXplZCB2YWx1ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFNTaW1wbGVUeXBlRGVmaW5pdGlvbiBnZXRNZW1iZXJUeXBlRGVmaW5pdGlvbigpOwotCi0gICAgLyoqCi0gICAgICogPGNvZGU+W3NjaGVtYSBkZWZhdWx0XTwvY29kZT46IHRoZSBjYW5vbmljYWwgbGV4aWNhbCByZXByZXNlbnRhdGlvbiBvZgotICAgICAqIHRoZSBkZWNsYXJhdGlvbidzIHt2YWx1ZSBjb25zdHJhaW50fSB2YWx1ZS4gRm9yIG1vcmUgaW5mb3JtYXRpb24KLSAgICAgKiByZWZlciB0byBlbGVtZW50IHNjaGVtYSBkZWZhdWx0IGFuZCBhdHRyaWJ1dGUgc2NoZW1hIGRlZmF1bHQuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRTY2hlbWFEZWZhdWx0KCk7Ci0KLSAgICAvKioKLSAgICAgKiA8Y29kZT5bc2NoZW1hIHNwZWNpZmllZF08L2NvZGU+OiBpZiB0cnVlLCB0aGUgdmFsdWUgd2FzIHNwZWNpZmllZCBpbgotICAgICAqIHRoZSBzY2hlbWEuIElmIGZhbHNlLCB0aGUgdmFsdWUgY29tZXMgZnJvbSB0aGUgaW5mb3NldC4gRm9yIG1vcmUKLSAgICAgKiBpbmZvcm1hdGlvbiByZWZlciB0byBlbGVtZW50IHNwZWNpZmllZCBhbmQgYXR0cmlidXRlIHNwZWNpZmllZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXRJc1NjaGVtYVNwZWNpZmllZCgpOwotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94cy9MU0lucHV0TGlzdC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHMvTFNJbnB1dExpc3QuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNjQ1OTYzMS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94cy9MU0lucHV0TGlzdC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTAgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMywyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzOwotCi1pbXBvcnQgamF2YS51dGlsLkxpc3Q7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5scy5MU0lucHV0OwotCi0vKioKLSAqICBUaGUgPGNvZGU+TFNJbnB1dExpc3Q8L2NvZGU+IGludGVyZmFjZSBwcm92aWRlcyB0aGUgYWJzdHJhY3Rpb24gb2YgYW4KLSAqIG9yZGVyZWQgY29sbGVjdGlvbiBvZiA8Y29kZT5MU0lucHV0PC9jb2RlPnMsIHdpdGhvdXQgZGVmaW5pbmcgb3IKLSAqIGNvbnN0cmFpbmluZyBob3cgdGhpcyBjb2xsZWN0aW9uIGlzIGltcGxlbWVudGVkLgotICovCi1wdWJsaWMgaW50ZXJmYWNlIExTSW5wdXRMaXN0IGV4dGVuZHMgTGlzdCB7Ci0gICAgLyoqCi0gICAgICogIFRoZSBudW1iZXIgb2YgPGNvZGU+TFNJbnB1dDwvY29kZT5zIGluIHRoZSBsaXN0LiBUaGUgcmFuZ2Ugb2YgdmFsaWQKLSAgICAgKiBjaGlsZCBvYmplY3QgaW5kaWNlcyBpcyAwIHRvIDxjb2RlPmxlbmd0aC0xPC9jb2RlPiBpbmNsdXNpdmUuCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRMZW5ndGgoKTsKLQotICAgIC8qKgotICAgICAqICBSZXR1cm5zIHRoZSA8Y29kZT5pbmRleDwvY29kZT50aCBpdGVtIGluIHRoZSBjb2xsZWN0aW9uIG9yCi0gICAgICogPGNvZGU+bnVsbDwvY29kZT4gaWYgPGNvZGU+aW5kZXg8L2NvZGU+IGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0bwotICAgICAqIHRoZSBudW1iZXIgb2Ygb2JqZWN0cyBpbiB0aGUgbGlzdC4gVGhlIGluZGV4IHN0YXJ0cyBhdCAwLgotICAgICAqIEBwYXJhbSBpbmRleCAgaW5kZXggaW50byB0aGUgY29sbGVjdGlvbi4KLSAgICAgKiBAcmV0dXJuICBUaGUgPGNvZGU+TFNJbnB1dDwvY29kZT4gYXQgdGhlIDxjb2RlPmluZGV4PC9jb2RlPnRoCi0gICAgICogICBwb3NpdGlvbiBpbiB0aGUgPGNvZGU+TFNJbnB1dExpc3Q8L2NvZGU+LCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZgotICAgICAqICAgdGhlIGluZGV4IHNwZWNpZmllZCBpcyBub3QgdmFsaWQuCi0gICAgICovCi0gICAgcHVibGljIExTSW5wdXQgaXRlbShpbnQgaW5kZXgpOwotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94cy9QU1ZJUHJvdmlkZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3hzL1BTVklQcm92aWRlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxZGNhMGRkLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3hzL1BTVklQcm92aWRlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTMgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMywyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzOwotCi0vKioKLSAqIFRoaXMgaW50ZXJmYWNlIHByb3ZpZGVzIGFjY2VzcyB0byB0aGUgcG9zdCBzY2hlbWEgdmFsaWRhdGlvbiBpbmZvc2V0IGZvciBhbgotICogQVBJIHRoYXQgcHJvdmlkZXMgYSBzdHJlYW1pbmcgZG9jdW1lbnQgaW5mb3NldCwgc3VjaCBhcyBTQVgsIFhOSSwgYW5kCi0gKiBvdGhlcnMuCi0gKiA8cD5Gb3IgaW1wbGVtZW50YXRpb25zIHRoYXQgd291bGQgbGlrZSB0byBwcm92aWRlIGFjY2VzcyB0byB0aGUgUFNWSSBpbiBhCi0gKiBzdHJlYW1pbmcgbW9kZWwsIGEgcGFyc2VyIG9iamVjdCBzaG91bGQgYWxzbyBpbXBsZW1lbnQgdGhlCi0gKiA8Y29kZT5QU1ZJUHJvdmlkZXI8L2NvZGU+IGludGVyZmFjZS4gV2l0aGluIHRoZSBzY29wZSBvZiB0aGUgbWV0aG9kcwotICogaGFuZGxpbmcgdGhlIHN0YXJ0IGFuZCBlbmQgb2YgYW4gZWxlbWVudCwgYXBwbGljYXRpb25zIG1heSB1c2UgdGhlCi0gKiA8Y29kZT5QU1ZJUHJvdmlkZXI8L2NvZGU+IHRvIHJldHJpZXZlIHRoZSBQU1ZJIHJlbGF0ZWQgdG8gdGhlIGVsZW1lbnQgYW5kCi0gKiBpdHMgYXR0cmlidXRlcy4KLSAqLwotcHVibGljIGludGVyZmFjZSBQU1ZJUHJvdmlkZXIgewotICAgIC8qKgotICAgICAqICBQcm92aWRlcyB0aGUgcG9zdCBzY2hlbWEgdmFsaWRhdGlvbiBpdGVtIGZvciB0aGUgY3VycmVudCBlbGVtZW50Ci0gICAgICogaW5mb3JtYXRpb24gaXRlbS4gVGhlIG1ldGhvZCBtdXN0IGJlIGNhbGxlZCBieSBhbiBhcHBsaWNhdGlvbiB3aGlsZQotICAgICAqIGluIHRoZSBzY29wZSBvZiB0aGUgbWV0aG9kcyB3aGljaCByZXBvcnQgdGhlIHN0YXJ0IGFuZCBlbmQgb2YgYW4KLSAgICAgKiBlbGVtZW50LiBGb3IgZXhhbXBsZSwgZm9yIFNBWCB0aGUgbWV0aG9kIG11c3QgYmUgY2FsbGVkIHdpdGhpbiB0aGUKLSAgICAgKiBzY29wZSBvZiB0aGUgZG9jdW1lbnQgaGFuZGxlcidzIDxjb2RlPnN0YXJ0RWxlbWVudDwvY29kZT4gb3IKLSAgICAgKiA8Y29kZT5lbmRFbGVtZW50PC9jb2RlPiBjYWxsLiBJZiB0aGUgbWV0aG9kIGlzIGNhbGxlZCBvdXRzaWRlIG9mIHRoZQotICAgICAqIHNwZWNpZmllZCBzY29wZSwgdGhlIHJldHVybiB2YWx1ZSBpcyB1bmRlZmluZWQuCi0gICAgICogQHJldHVybiBUaGUgcG9zdCBzY2hlbWEgdmFsaWRhdGlvbiBpbmZvc2V0IGZvciB0aGUgY3VycmVudCBlbGVtZW50LiBJZgotICAgICAqICAgYW4gZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIGlzIHZhbGlkLCB0aGVuIGluIHRoZQotICAgICAqICAgcG9zdC1zY2hlbWEtdmFsaWRhdGlvbiBpbmZvc2V0IHRoZSBmb2xsb3dpbmcgcHJvcGVydGllcyBtdXN0IGJlCi0gICAgICogICBhdmFpbGFibGUgZm9yIHRoZSBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW06IFRoZSBmb2xsb3dpbmcKLSAgICAgKiAgIHByb3BlcnRpZXMgYXJlIGF2YWlsYWJsZSBpbiB0aGUgc2NvcGUgb2YgdGhlIG1ldGhvZCB0aGF0IHJlcG9ydHMKLSAgICAgKiAgIHRoZSBzdGFydCBvZiBhbiBlbGVtZW50OiB7ZWxlbWVudCBkZWNsYXJhdGlvbn0sIHt2YWxpZGF0aW9uCi0gICAgICogICBjb250ZXh0fSwge25vdGF0aW9ufS4gVGhlIHtzY2hlbWEgaW5mb3JtYXRpb259IHByb3BlcnR5IGlzCi0gICAgICogICBhdmFpbGFibGUgZm9yIHRoZSB2YWxpZGF0aW9uIHJvb3QuIFRoZSB7ZXJyb3IgY29kZXN9IHByb3BlcnR5IGlzCi0gICAgICogICBhdmFpbGFibGUgaWYgYW55IGVycm9ycyBvY2N1cmVkIGR1cmluZyB2YWxpZGF0aW9uLiAgVGhlIGZvbGxvd2luZwotICAgICAqICAgcHJvcGVydGllcyBhcmUgYXZhaWxhYmxlIGluIHRoZSBzY29wZSBvZiB0aGUgbWV0aG9kIHRoYXQgcmVwb3J0cwotICAgICAqICAgdGhlIGVuZCBvZiBhbiBlbGVtZW50OiB7bmlsfSwge3NjaGVtYSBzcGVjaWZpZWR9LCB7bm9ybWFsaXplZAotICAgICAqICAgdmFsdWV9LHsgbWVtYmVyIHR5cGUgZGVmaW5pdGlvbn0sIHt2YWxpZGl0eX0sIHt2YWxpZGF0aW9uIGF0dGVtcHRlZH0KLSAgICAgKiAgIC4gSWYgdGhlIGRlY2xhcmF0aW9uIGhhcyBhIHZhbHVlIGNvbnN0cmFpbnQsIHRoZSBwcm9wZXJ0eSB7c2NoZW1hCi0gICAgICogICBkZWZhdWx0fSBpcyBhdmFpbGFibGUuIFRoZSB7ZXJyb3IgY29kZXN9IHByb3BlcnR5IGlzIGF2YWlsYWJsZSBpZgotICAgICAqICAgYW55IGVycm9ycyBvY2N1cmVkIGR1cmluZyB2YWxpZGF0aW9uLiBOb3RlOiBzb21lIHByb2Nlc3NvcnMgbWF5Ci0gICAgICogICBjaG9vc2UgdG8gcHJvdmlkZSBhbGwgdGhlIFBTVkkgcHJvcGVydGllcyBpbiB0aGUgc2NvcGUgb2YgdGhlCi0gICAgICogICBtZXRob2QgdGhhdCByZXBvcnRzIHRoZSBlbmQgb2YgYW4gZWxlbWVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgRWxlbWVudFBTVkkgZ2V0RWxlbWVudFBTVkkoKTsKLQotICAgIC8qKgotICAgICAqIFByb3ZpZGVzIDxjb2RlPkF0dHJpYnV0ZVBTVkk8L2NvZGU+IGdpdmVuIHRoZSBpbmRleCBvZiBhbiBhdHRyaWJ1dGUKLSAgICAgKiBpbmZvcm1hdGlvbiBpdGVtIGluIHRoZSBjdXJyZW50IGVsZW1lbnQncyBhdHRyaWJ1dGUgbGlzdC4gVGhlIG1ldGhvZAotICAgICAqIG11c3QgYmUgY2FsbGVkIGJ5IGFuIGFwcGxpY2F0aW9uIHdoaWxlIGluIHRoZSBzY29wZSBvZiB0aGUgbWV0aG9kcwotICAgICAqIHdoaWNoIHJlcG9ydCB0aGUgc3RhcnQgYW5kIGVuZCBvZiBhbiBlbGVtZW50IGF0IGEgcG9pbnQgd2hlcmUgdGhlCi0gICAgICogYXR0cmlidXRlIGxpc3QgaXMgYXZhaWxhYmxlLiBGb3IgZXhhbXBsZSwgZm9yIFNBWCB0aGUgbWV0aG9kIG11c3QgYmUKLSAgICAgKiBjYWxsZWQgd2hpbGUgaW4gdGhlIHNjb3BlIG9mIHRoZSBkb2N1bWVudCBoYW5kbGVyJ3MKLSAgICAgKiA8Y29kZT5zdGFydEVsZW1lbnQ8L2NvZGU+IGNhbGwuIElmIHRoZSBtZXRob2QgaXMgY2FsbGVkIG91dHNpZGUgb2YKLSAgICAgKiB0aGUgc3BlY2lmaWVkIHNjb3BlLCB0aGUgcmV0dXJuIHZhbHVlIGlzIHVuZGVmaW5lZC4KLSAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGF0dHJpYnV0ZSBpbmRleC4KLSAgICAgKiBAcmV0dXJuIFRoZSBwb3N0IHNjaGVtYSB2YWxpZGF0aW9uIHByb3BlcnRpZXMgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgQXR0cmlidXRlUFNWSSBnZXRBdHRyaWJ1dGVQU1ZJKGludCBpbmRleCk7Ci0KLSAgICAvKioKLSAgICAgKiBQcm92aWRlcyA8Y29kZT5BdHRyaWJ1dGVQU1ZJPC9jb2RlPiBnaXZlbiB0aGUgbmFtZXNwYWNlIG5hbWUgYW5kIHRoZQotICAgICAqIGxvY2FsIG5hbWUgb2YgYW4gYXR0cmlidXRlIGluZm9ybWF0aW9uIGl0ZW0gaW4gdGhlIGN1cnJlbnQgZWxlbWVudCdzCi0gICAgICogYXR0cmlidXRlIGxpc3QuIFRoZSBtZXRob2QgbXVzdCBiZSBjYWxsZWQgYnkgYW4gYXBwbGljYXRpb24gd2hpbGUgaW4KLSAgICAgKiB0aGUgc2NvcGUgb2YgdGhlIG1ldGhvZHMgd2hpY2ggcmVwb3J0IHRoZSBzdGFydCBhbmQgZW5kIG9mIGFuIGVsZW1lbnQKLSAgICAgKiBhdCBhIHBvaW50IHdoZXJlIHRoZSBhdHRyaWJ1dGUgbGlzdCBpcyBhdmFpbGFibGUuIEZvciBleGFtcGxlLCBmb3IKLSAgICAgKiBTQVggdGhlIG1ldGhvZCBtdXN0IGJlIGNhbGxlZCB3aGlsZSBpbiB0aGUgc2NvcGUgb2YgdGhlIGRvY3VtZW50Ci0gICAgICogaGFuZGxlcidzIDxjb2RlPnN0YXJ0RWxlbWVudDwvY29kZT4gY2FsbC4gSWYgdGhlIG1ldGhvZCBpcyBjYWxsZWQKLSAgICAgKiBvdXRzaWRlIG9mIHRoZSBzcGVjaWZpZWQgc2NvcGUsIHRoZSByZXR1cm4gdmFsdWUgaXMgdW5kZWZpbmVkLgotICAgICAqIEBwYXJhbSB1cmkgVGhlIG5hbWVzcGFjZSBuYW1lIG9mIGFuIGF0dHJpYnV0ZS4KLSAgICAgKiBAcGFyYW0gbG9jYWxuYW1lIFRoZSBsb2NhbCBuYW1lIG9mIGFuIGF0dHJpYnV0ZS4KLSAgICAgKiBAcmV0dXJuIFRoZSBwb3N0IHNjaGVtYSB2YWxpZGF0aW9uIHByb3BlcnRpZXMgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgQXR0cmlidXRlUFNWSSBnZXRBdHRyaWJ1dGVQU1ZJQnlOYW1lKFN0cmluZyB1cmksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbG9jYWxuYW1lKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHMvU2hvcnRMaXN0LmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94cy9TaG9ydExpc3QuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYTEwZTEyMi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94cy9TaG9ydExpc3QuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDU5ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDMsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54czsKLQotaW1wb3J0IGphdmEudXRpbC5MaXN0OwotCi0vKioKLSAqICBUaGUgPGNvZGU+U2hvcnRMaXN0PC9jb2RlPiBpcyBhbiBpbW11dGFibGUgb3JkZXJlZCBjb2xsZWN0aW9uIG9mCi0gKiA8Y29kZT51bnNpZ25lZCBzaG9ydDwvY29kZT4uCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgU2hvcnRMaXN0IGV4dGVuZHMgTGlzdCB7Ci0gICAgLyoqCi0gICAgICogIFRoZSBudW1iZXIgb2YgPGNvZGU+dW5zaWduZWQgc2hvcnQ8L2NvZGU+cyBpbiB0aGUgbGlzdC4gVGhlIHJhbmdlIG9mCi0gICAgICogdmFsaWQgY2hpbGQgb2JqZWN0IGluZGljZXMgaXMgMCB0byA8Y29kZT5sZW5ndGgtMTwvY29kZT4gaW5jbHVzaXZlLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0TGVuZ3RoKCk7Ci0KLSAgICAvKioKLSAgICAgKiAgQ2hlY2tzIGlmIHRoZSA8Y29kZT51bnNpZ25lZCBzaG9ydDwvY29kZT4gPGNvZGU+aXRlbTwvY29kZT4gaXMgYQotICAgICAqIG1lbWJlciBvZiB0aGlzIGxpc3QuCi0gICAgICogQHBhcmFtIGl0ZW0gIDxjb2RlPnVuc2lnbmVkIHNob3J0PC9jb2RlPiB3aG9zZSBwcmVzZW5jZSBpbiB0aGlzIGxpc3QKLSAgICAgKiAgIGlzIHRvIGJlIHRlc3RlZC4KLSAgICAgKiBAcmV0dXJuICBUcnVlIGlmIHRoaXMgbGlzdCBjb250YWlucyB0aGUgPGNvZGU+dW5zaWduZWQgc2hvcnQ8L2NvZGU+Ci0gICAgICogICA8Y29kZT5pdGVtPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBjb250YWlucyhzaG9ydCBpdGVtKTsKLQotICAgIC8qKgotICAgICAqICBSZXR1cm5zIHRoZSA8Y29kZT5pbmRleDwvY29kZT50aCBpdGVtIGluIHRoZSBjb2xsZWN0aW9uLiBUaGUgaW5kZXgKLSAgICAgKiBzdGFydHMgYXQgMC4KLSAgICAgKiBAcGFyYW0gaW5kZXggIGluZGV4IGludG8gdGhlIGNvbGxlY3Rpb24uCi0gICAgICogQHJldHVybiAgVGhlIDxjb2RlPnVuc2lnbmVkIHNob3J0PC9jb2RlPiBhdCB0aGUgPGNvZGU+aW5kZXg8L2NvZGU+dGgKLSAgICAgKiAgIHBvc2l0aW9uIGluIHRoZSA8Y29kZT5TaG9ydExpc3Q8L2NvZGU+LgotICAgICAqIEBleGNlcHRpb24gWFNFeGNlcHRpb24KLSAgICAgKiAgIElOREVYX1NJWkVfRVJSOiBpZiA8Y29kZT5pbmRleDwvY29kZT4gaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHRoZQotICAgICAqICAgbnVtYmVyIG9mIG9iamVjdHMgaW4gdGhlIGxpc3QuCi0gICAgICovCi0gICAgcHVibGljIHNob3J0IGl0ZW0oaW50IGluZGV4KQotICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBYU0V4Y2VwdGlvbjsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHMvU3RyaW5nTGlzdC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHMvU3RyaW5nTGlzdC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmOGUzNGUxLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3hzL1N0cmluZ0xpc3QuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDU3ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDMsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54czsKLQotaW1wb3J0IGphdmEudXRpbC5MaXN0OwotCi0vKioKLSAqICBUaGUgPGNvZGU+U3RyaW5nTGlzdDwvY29kZT4gaXMgYW4gaW1tdXRhYmxlIG9yZGVyZWQgY29sbGVjdGlvbiBvZgotICogPGNvZGU+R2VuZXJpY1N0cmluZzwvY29kZT4uCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgU3RyaW5nTGlzdCBleHRlbmRzIExpc3QgewotICAgIC8qKgotICAgICAqICBUaGUgbnVtYmVyIG9mIDxjb2RlPkdlbmVyaWNTdHJpbmc8L2NvZGU+cyBpbiB0aGUgbGlzdC4gVGhlIHJhbmdlIG9mCi0gICAgICogdmFsaWQgY2hpbGQgb2JqZWN0IGluZGljZXMgaXMgMCB0byA8Y29kZT5sZW5ndGgtMTwvY29kZT4gaW5jbHVzaXZlLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0TGVuZ3RoKCk7Ci0KLSAgICAvKioKLSAgICAgKiAgQ2hlY2tzIGlmIHRoZSA8Y29kZT5HZW5lcmljU3RyaW5nPC9jb2RlPiA8Y29kZT5pdGVtPC9jb2RlPiBpcyBhIG1lbWJlcgotICAgICAqIG9mIHRoaXMgbGlzdC4KLSAgICAgKiBAcGFyYW0gaXRlbSAgPGNvZGU+R2VuZXJpY1N0cmluZzwvY29kZT4gd2hvc2UgcHJlc2VuY2UgaW4gdGhpcyBsaXN0IGlzCi0gICAgICogICB0byBiZSB0ZXN0ZWQuCi0gICAgICogQHJldHVybiAgVHJ1ZSBpZiB0aGlzIGxpc3QgY29udGFpbnMgdGhlIDxjb2RlPkdlbmVyaWNTdHJpbmc8L2NvZGU+Ci0gICAgICogICA8Y29kZT5pdGVtPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBjb250YWlucyhTdHJpbmcgaXRlbSk7Ci0KLSAgICAvKioKLSAgICAgKiAgUmV0dXJucyB0aGUgPGNvZGU+aW5kZXg8L2NvZGU+dGggaXRlbSBpbiB0aGUgY29sbGVjdGlvbiBvcgotICAgICAqIDxjb2RlPm51bGw8L2NvZGU+IGlmIDxjb2RlPmluZGV4PC9jb2RlPiBpcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8KLSAgICAgKiB0aGUgbnVtYmVyIG9mIG9iamVjdHMgaW4gdGhlIGxpc3QuIFRoZSBpbmRleCBzdGFydHMgYXQgMC4KLSAgICAgKiBAcGFyYW0gaW5kZXggIGluZGV4IGludG8gdGhlIGNvbGxlY3Rpb24uCi0gICAgICogQHJldHVybiAgVGhlIDxjb2RlPkdlbmVyaWNTdHJpbmc8L2NvZGU+IGF0IHRoZSA8Y29kZT5pbmRleDwvY29kZT50aAotICAgICAqICAgcG9zaXRpb24gaW4gdGhlIDxjb2RlPlN0cmluZ0xpc3Q8L2NvZGU+LCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZgotICAgICAqICAgdGhlIGluZGV4IHNwZWNpZmllZCBpcyBub3QgdmFsaWQuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBpdGVtKGludCBpbmRleCk7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3hzL1hTQW5ub3RhdGlvbi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHMvWFNBbm5vdGF0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGQwNGYzMzEuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHMvWFNBbm5vdGF0aW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw2MyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAzLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHM7Ci0KLS8qKgotICogVGhpcyBpbnRlcmZhY2UgcmVwcmVzZW50cyB0aGUgQW5ub3RhdGlvbiBzY2hlbWEgY29tcG9uZW50LgotICovCi1wdWJsaWMgaW50ZXJmYWNlIFhTQW5ub3RhdGlvbiBleHRlbmRzIFhTT2JqZWN0IHsKLSAgICAvLyBUYXJnZXRUeXBlCi0gICAgLyoqCi0gICAgICogVGhlIG9iamVjdCB0eXBlIGlzIDxjb2RlPm9yZy53M2MuZG9tLkVsZW1lbnQ8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgVzNDX0RPTV9FTEVNRU5UICAgICAgICAgICA9IDE7Ci0gICAgLyoqCi0gICAgICogVGhlIG9iamVjdCB0eXBlIGlzIDxjb2RlPm9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFNBWF9DT05URU5USEFORExFUiAgICAgICAgPSAyOwotICAgIC8qKgotICAgICAqIFRoZSBvYmplY3QgdHlwZSBpcyA8Y29kZT5vcmcudzNjLmRvbS5Eb2N1bWVudDwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBXM0NfRE9NX0RPQ1VNRU5UICAgICAgICAgID0gMzsKLQotICAgIC8qKgotICAgICAqICBXcml0ZSBjb250ZW50cyBvZiB0aGUgYW5ub3RhdGlvbiB0byB0aGUgc3BlY2lmaWVkIG9iamVjdC4gSWYgdGhlCi0gICAgICogc3BlY2lmaWVkIDxjb2RlPnRhcmdldDwvY29kZT4gaXMgYSBET00gb2JqZWN0LCBpbi1zY29wZSBuYW1lc3BhY2UKLSAgICAgKiBkZWNsYXJhdGlvbnMgZm9yIDxjb2RlPmFubm90YXRpb248L2NvZGU+IGVsZW1lbnQgYXJlIGFkZGVkIGFzCi0gICAgICogYXR0cmlidXRlIG5vZGVzIG9mIHRoZSBzZXJpYWxpemVkIDxjb2RlPmFubm90YXRpb248L2NvZGU+LCBvdGhlcndpc2UKLSAgICAgKiB0aGUgY29ycmVzcG9uZGluZyBldmVudHMgZm9yIGFsbCBpbi1zY29wZSBuYW1lc3BhY2UgZGVjbGFyYXRpb25zIGFyZQotICAgICAqIHNlbnQgdmlhIHRoZSBzcGVjaWZpZWQgZG9jdW1lbnQgaGFuZGxlci4KLSAgICAgKiBAcGFyYW0gdGFyZ2V0ICBBIHRhcmdldCBwb2ludGVyIHRvIHRoZSBhbm5vdGF0aW9uIHRhcmdldCBvYmplY3QsIGkuZS4KLSAgICAgKiAgIDxjb2RlPm9yZy53M2MuZG9tLkRvY3VtZW50PC9jb2RlPiwgPGNvZGU+b3JnLnczYy5kb20uRWxlbWVudDwvY29kZT4KLSAgICAgKiAgICwgPGNvZGU+b3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXI8L2NvZGU+LgotICAgICAqIEBwYXJhbSB0YXJnZXRUeXBlICBBIHRhcmdldCB0eXBlLgotICAgICAqIEByZXR1cm4gIFRydWUgaWYgdGhlIDxjb2RlPnRhcmdldDwvY29kZT4gaXMgYSByZWNvZ25pemVkIHR5cGUgYW5kCi0gICAgICogICBzdXBwb3J0ZWQgYnkgdGhpcyBpbXBsZW1lbnRhdGlvbiwgb3RoZXJ3aXNlIGZhbHNlLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIHdyaXRlQW5ub3RhdGlvbihPYmplY3QgdGFyZ2V0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaG9ydCB0YXJnZXRUeXBlKTsKLQotICAgIC8qKgotICAgICAqIEEgdGV4dCByZXByZXNlbnRhdGlvbiBvZiB0aGUgYW5ub3RhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEFubm90YXRpb25TdHJpbmcoKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHMvWFNBdHRyaWJ1dGVEZWNsYXJhdGlvbi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHMvWFNBdHRyaWJ1dGVEZWNsYXJhdGlvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzNTBhMTQ4Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3hzL1hTQXR0cmlidXRlRGVjbGFyYXRpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExMSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAzLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHM7Ci0KLS8qKgotICogVGhlIGludGVyZmFjZSByZXByZXNlbnRzIHRoZSBBdHRyaWJ1dGUgRGVjbGFyYXRpb24gc2NoZW1hIGNvbXBvbmVudC4KLSAqLwotcHVibGljIGludGVyZmFjZSBYU0F0dHJpYnV0ZURlY2xhcmF0aW9uIGV4dGVuZHMgWFNPYmplY3QgewotICAgIC8qKgotICAgICAqIFt0eXBlIGRlZmluaXRpb25dOiBBIHNpbXBsZSB0eXBlIGRlZmluaXRpb24uCi0gICAgICovCi0gICAgcHVibGljIFhTU2ltcGxlVHlwZURlZmluaXRpb24gZ2V0VHlwZURlZmluaXRpb24oKTsKLQotICAgIC8qKgotICAgICAqIFtzY29wZV0uIE9uZSBvZiA8Y29kZT5TQ09QRV9HTE9CQUw8L2NvZGU+LCA8Y29kZT5TQ09QRV9MT0NBTDwvY29kZT4sIG9yCi0gICAgICogPGNvZGU+U0NPUEVfQUJTRU5UPC9jb2RlPi4gSWYgdGhlIHNjb3BlIGlzIGxvY2FsLCB0aGVuIHRoZQotICAgICAqIDxjb2RlPmVuY2xvc2luZ0NURGVmaW5pdGlvbjwvY29kZT4gaXMgcHJlc2VudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgc2hvcnQgZ2V0U2NvcGUoKTsKLQotICAgIC8qKgotICAgICAqIFRoZSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbiBmb3IgbG9jYWxseSBzY29wZWQgZGVjbGFyYXRpb25zIChzZWUKLSAgICAgKiA8Y29kZT5zY29wZTwvY29kZT4pLCBvdGhlcndpc2UgPGNvZGU+bnVsbDwvY29kZT4gaWYgbm8gc3VjaAotICAgICAqIGRlZmluaXRpb24gZXhpc3RzLgotICAgICAqLwotICAgIHB1YmxpYyBYU0NvbXBsZXhUeXBlRGVmaW5pdGlvbiBnZXRFbmNsb3NpbmdDVERlZmluaXRpb24oKTsKLQotICAgIC8qKgotICAgICAqIFZhbHVlIGNvbnN0cmFpbnQ6IG9uZSBvZiA8Y29kZT5WQ19OT05FLCBWQ19ERUZBVUxULCBWQ19GSVhFRDwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIHNob3J0IGdldENvbnN0cmFpbnRUeXBlKCk7Ci0KLSAgICAvKioKLSAgICAgKiBWYWx1ZSBjb25zdHJhaW50OiBUaGUgY29uc3RyYWludCB2YWx1ZSB3aXRoIHJlc3BlY3QgdG8gdGhlIFt0eXBlCi0gICAgICogZGVmaW5pdGlvbl0sIG90aGVyd2lzZSA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldENvbnN0cmFpbnRWYWx1ZSgpOwotCi0gICAgLyoqCi0gICAgICogVmFsdWUgQ29uc3RyYWludDogQmluZGluZyBzcGVjaWZpYyBhY3R1YWwgY29uc3RyYWludCB2YWx1ZSBvcgotICAgICAqIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoZSB2YWx1ZSBpcyBpbiBlcnJvciBvciB0aGVyZSBpcyBubyB2YWx1ZQotICAgICAqIGNvbnN0cmFpbnQuCi0gICAgICogQGV4Y2VwdGlvbiBYU0V4Y2VwdGlvbgotICAgICAqICAgTk9UX1NVUFBPUlRFRF9FUlI6IFJhaXNlZCBpZiB0aGUgaW1wbGVtZW50YXRpb24gZG9lcyBub3Qgc3VwcG9ydCB0aGlzCi0gICAgICogICBtZXRob2QuCi0gICAgICovCi0gICAgcHVibGljIE9iamVjdCBnZXRBY3R1YWxWQygpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBYU0V4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIFRoZSBhY3R1YWwgY29uc3RyYWludCB2YWx1ZSBidWlsdC1pbiBkYXRhdHlwZSwgZS5nLgotICAgICAqIDxjb2RlPlNUUklOR19EVCwgU0hPUlRfRFQ8L2NvZGU+LiBJZiB0aGUgdHlwZSBkZWZpbml0aW9uIG9mIHRoaXMKLSAgICAgKiB2YWx1ZSBpcyBhIGxpc3QgdHlwZSBkZWZpbml0aW9uLCB0aGlzIG1ldGhvZCByZXR1cm5zCi0gICAgICogPGNvZGU+TElTVF9EVDwvY29kZT4uIElmIHRoZSB0eXBlIGRlZmluaXRpb24gb2YgdGhpcyB2YWx1ZSBpcyBhIGxpc3QKLSAgICAgKiB0eXBlIGRlZmluaXRpb24gd2hvc2UgaXRlbSB0eXBlIGlzIGEgdW5pb24gdHlwZSBkZWZpbml0aW9uLCB0aGlzCi0gICAgICogbWV0aG9kIHJldHVybnMgPGNvZGU+TElTVE9GVU5JT05fRFQ8L2NvZGU+LiBUbyBxdWVyeSB0aGUgYWN0dWFsCi0gICAgICogY29uc3RyYWludCB2YWx1ZSBvZiB0aGUgbGlzdCBvciBsaXN0IG9mIHVuaW9uIHR5cGUgZGVmaW5pdGlvbnMgdXNlCi0gICAgICogPGNvZGU+aXRlbVZhbHVlVHlwZXM8L2NvZGU+LiBJZiB0aGUgPGNvZGU+YWN0dWFsVmFsdWU8L2NvZGU+IGlzCi0gICAgICogPGNvZGU+bnVsbDwvY29kZT4sIHRoaXMgbWV0aG9kIHJldHVybnMgPGNvZGU+VU5BVkFJTEFCTEVfRFQ8L2NvZGU+LgotICAgICAqIEBleGNlcHRpb24gWFNFeGNlcHRpb24KLSAgICAgKiAgIE5PVF9TVVBQT1JURURfRVJSOiBSYWlzZWQgaWYgdGhlIGltcGxlbWVudGF0aW9uIGRvZXMgbm90IHN1cHBvcnQgdGhpcwotICAgICAqICAgbWV0aG9kLgotICAgICAqLwotICAgIHB1YmxpYyBzaG9ydCBnZXRBY3R1YWxWQ1R5cGUoKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgWFNFeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBJbiB0aGUgY2FzZSB0aGUgYWN0dWFsIGNvbnN0cmFpbnQgdmFsdWUgcmVwcmVzZW50cyBhIGxpc3QsIGkuZS4gdGhlCi0gICAgICogPGNvZGU+YWN0dWFsVmFsdWVUeXBlPC9jb2RlPiBpcyA8Y29kZT5MSVNUX0RUPC9jb2RlPiwgdGhlIHJldHVybmVkCi0gICAgICogYXJyYXkgY29uc2lzdHMgb2Ygb25lIHR5cGUga2luZCB3aGljaCByZXByZXNlbnRzIHRoZSBpdGVtVHlwZS4gSWYgdGhlCi0gICAgICogYWN0dWFsIGNvbnN0cmFpbnQgdmFsdWUgcmVwcmVzZW50cyBhIGxpc3QgdHlwZSBkZWZpbml0aW9uIHdob3NlIGl0ZW0KLSAgICAgKiB0eXBlIGlzIGEgdW5pb24gdHlwZSBkZWZpbml0aW9uLCBpLmUuIDxjb2RlPkxJU1RPRlVOSU9OX0RUPC9jb2RlPiwKLSAgICAgKiBmb3IgZWFjaCBhY3R1YWwgY29uc3RyYWludCB2YWx1ZSBpbiB0aGUgbGlzdCB0aGUgYXJyYXkgY29udGFpbnMgdGhlCi0gICAgICogY29ycmVzcG9uZGluZyBtZW1iZXJUeXBlIGtpbmQuIEZvciBleGFtcGxlcywgc2VlCi0gICAgICogPGNvZGU+SXRlbVBTVkkuaXRlbVZhbHVlVHlwZXM8L2NvZGU+LgotICAgICAqIEBleGNlcHRpb24gWFNFeGNlcHRpb24KLSAgICAgKiAgIE5PVF9TVVBQT1JURURfRVJSOiBSYWlzZWQgaWYgdGhlIGltcGxlbWVudGF0aW9uIGRvZXMgbm90IHN1cHBvcnQgdGhpcwotICAgICAqICAgbWV0aG9kLgotICAgICAqLwotICAgIHB1YmxpYyBTaG9ydExpc3QgZ2V0SXRlbVZhbHVlVHlwZXMoKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgWFNFeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBBbiBhbm5vdGF0aW9uIGlmIGl0IGV4aXN0cywgb3RoZXJ3aXNlIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAqIElmIG5vdCBudWxsIHRoZW4gdGhlIGZpcnN0IFthbm5vdGF0aW9uXSBmcm9tIHRoZSBzZXF1ZW5jZSBvZiBhbm5vdGF0aW9ucy4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFNBbm5vdGF0aW9uIGdldEFubm90YXRpb24oKTsKLQotICAgIC8qKgotICAgICAqIEEgc2VxdWVuY2Ugb2YgW2Fubm90YXRpb25zXSBvciBhbiBlbXB0eSAgPGNvZGU+WFNPYmplY3RMaXN0PC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFNPYmplY3RMaXN0IGdldEFubm90YXRpb25zKCk7Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94cy9YU0F0dHJpYnV0ZUdyb3VwRGVmaW5pdGlvbi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHMvWFNBdHRyaWJ1dGVHcm91cERlZmluaXRpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNzFkOTBiMC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94cy9YU0F0dHJpYnV0ZUdyb3VwRGVmaW5pdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDggKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMywyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzOwotCi0vKioKLSAqIFRoaXMgaW50ZXJmYWNlIHJlcHJlc2VudHMgdGhlIEF0dHJpYnV0ZSBHcm91cCBEZWZpbml0aW9uIHNjaGVtYSBjb21wb25lbnQuCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgWFNBdHRyaWJ1dGVHcm91cERlZmluaXRpb24gZXh0ZW5kcyBYU09iamVjdCB7Ci0gICAgLyoqCi0gICAgICogQSBzZXQgb2YgW2F0dHJpYnV0ZSB1c2VzXSBpZiBpdCBleGlzdHMsIG90aGVyd2lzZSBhbiBlbXB0eQotICAgICAqIDxjb2RlPlhTT2JqZWN0TGlzdDwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIFhTT2JqZWN0TGlzdCBnZXRBdHRyaWJ1dGVVc2VzKCk7Ci0KLSAgICAvKioKLSAgICAgKiBBIFt3aWxkY2FyZF0gaWYgaXQgZXhpc3RzLCBvdGhlcndpc2UgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIFhTV2lsZGNhcmQgZ2V0QXR0cmlidXRlV2lsZGNhcmQoKTsKLQotICAgIC8qKgotICAgICAqIEFuIGFubm90YXRpb24gaWYgaXQgZXhpc3RzLCBvdGhlcndpc2UgPGNvZGU+bnVsbDwvY29kZT4uIElmIG5vdCBudWxsCi0gICAgICogdGhlbiB0aGUgZmlyc3QgW2Fubm90YXRpb25dIGZyb20gdGhlIHNlcXVlbmNlIG9mIGFubm90YXRpb25zLgotICAgICAqLwotICAgIHB1YmxpYyBYU0Fubm90YXRpb24gZ2V0QW5ub3RhdGlvbigpOwotCi0gICAgLyoqCi0gICAgICogQSBzZXF1ZW5jZSBvZiBbYW5ub3RhdGlvbnNdIG9yIGFuIGVtcHR5IDxjb2RlPlhTT2JqZWN0TGlzdDwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIFhTT2JqZWN0TGlzdCBnZXRBbm5vdGF0aW9ucygpOwotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHMvWFNBdHRyaWJ1dGVVc2UuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3hzL1hTQXR0cmlidXRlVXNlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGI1NWU1MzAuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHMvWFNBdHRyaWJ1dGVVc2UuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDk5ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDMsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54czsKLQotLyoqCi0gKiBUaGlzIGludGVyZmFjZSByZXByZXNlbnRzIHRoZSBBdHRyaWJ1dGUgVXNlIHNjaGVtYSBjb21wb25lbnQuCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgWFNBdHRyaWJ1dGVVc2UgZXh0ZW5kcyBYU09iamVjdCB7Ci0gICAgLyoqCi0gICAgICogW3JlcXVpcmVkXTogZGV0ZXJtaW5lcyB3aGV0aGVyIHRoaXMgdXNlIG9mIGFuIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbgotICAgICAqIHJlcXVpcmVzIGFuIGFwcHJvcHJpYXRlIGF0dHJpYnV0ZSBpbmZvcm1hdGlvbiBpdGVtIHRvIGJlIHByZXNlbnQsIG9yCi0gICAgICogbWVyZWx5IGFsbG93cyBpdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXRSZXF1aXJlZCgpOwotCi0gICAgLyoqCi0gICAgICogW2F0dHJpYnV0ZSBkZWNsYXJhdGlvbl06IHByb3ZpZGVzIHRoZSBhdHRyaWJ1dGUgZGVjbGFyYXRpb24gaXRzZWxmLAotICAgICAqIHdoaWNoIHdpbGwgaW4gdHVybiBkZXRlcm1pbmUgdGhlIHNpbXBsZSB0eXBlIGRlZmluaXRpb24gdXNlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFNBdHRyaWJ1dGVEZWNsYXJhdGlvbiBnZXRBdHRyRGVjbGFyYXRpb24oKTsKLQotICAgIC8qKgotICAgICAqIFZhbHVlIENvbnN0cmFpbnQ6IG9uZSBvZiBkZWZhdWx0LCBmaXhlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgc2hvcnQgZ2V0Q29uc3RyYWludFR5cGUoKTsKLQotICAgIC8qKgotICAgICAqIFZhbHVlIENvbnN0cmFpbnQ6IFRoZSBjb25zdHJhaW50IHZhbHVlLCBvdGhlcndpc2UgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRDb25zdHJhaW50VmFsdWUoKTsKLQotICAgIC8qKgotICAgICAqIFZhbHVlIENvbnN0cmFpbnQ6IEJpbmRpbmcgc3BlY2lmaWMgYWN0dWFsIGNvbnN0cmFpbnQgdmFsdWUgb3IKLSAgICAgKiA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGUgdmFsdWUgaXMgaW4gZXJyb3Igb3IgdGhlcmUgaXMgbm8gdmFsdWUKLSAgICAgKiBjb25zdHJhaW50LgotICAgICAqIEBleGNlcHRpb24gWFNFeGNlcHRpb24KLSAgICAgKiAgIE5PVF9TVVBQT1JURURfRVJSOiBSYWlzZWQgaWYgdGhlIGltcGxlbWVudGF0aW9uIGRvZXMgbm90IHN1cHBvcnQgdGhpcwotICAgICAqICAgbWV0aG9kLgotICAgICAqLwotICAgIHB1YmxpYyBPYmplY3QgZ2V0QWN0dWFsVkMoKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIFhTRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogVGhlIGFjdHVhbCBjb25zdHJhaW50IHZhbHVlIGJ1aWx0LWluIGRhdGF0eXBlLCBlLmcuCi0gICAgICogPGNvZGU+U1RSSU5HX0RULCBTSE9SVF9EVDwvY29kZT4uIElmIHRoZSB0eXBlIGRlZmluaXRpb24gb2YgdGhpcwotICAgICAqIHZhbHVlIGlzIGEgbGlzdCB0eXBlIGRlZmluaXRpb24sIHRoaXMgbWV0aG9kIHJldHVybnMKLSAgICAgKiA8Y29kZT5MSVNUX0RUPC9jb2RlPi4gSWYgdGhlIHR5cGUgZGVmaW5pdGlvbiBvZiB0aGlzIHZhbHVlIGlzIGEgbGlzdAotICAgICAqIHR5cGUgZGVmaW5pdGlvbiB3aG9zZSBpdGVtIHR5cGUgaXMgYSB1bmlvbiB0eXBlIGRlZmluaXRpb24sIHRoaXMKLSAgICAgKiBtZXRob2QgcmV0dXJucyA8Y29kZT5MSVNUT0ZVTklPTl9EVDwvY29kZT4uIFRvIHF1ZXJ5IHRoZSBhY3R1YWwKLSAgICAgKiBjb25zdHJhaW50IHZhbHVlIG9mIHRoZSBsaXN0IG9yIGxpc3Qgb2YgdW5pb24gdHlwZSBkZWZpbml0aW9ucyB1c2UKLSAgICAgKiA8Y29kZT5pdGVtVmFsdWVUeXBlczwvY29kZT4uIElmIHRoZSA8Y29kZT5hY3R1YWxOb3JtYWxpemVkVmFsdWU8L2NvZGU+Ci0gICAgICogIGlzIDxjb2RlPm51bGw8L2NvZGU+LCB0aGlzIG1ldGhvZCByZXR1cm5zIDxjb2RlPlVOQVZBSUxBQkxFX0RUPC9jb2RlPgotICAgICAqIC4KLSAgICAgKiBAZXhjZXB0aW9uIFhTRXhjZXB0aW9uCi0gICAgICogICBOT1RfU1VQUE9SVEVEX0VSUjogUmFpc2VkIGlmIHRoZSBpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdCBzdXBwb3J0IHRoaXMKLSAgICAgKiAgIG1ldGhvZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgc2hvcnQgZ2V0QWN0dWFsVkNUeXBlKCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBYU0V4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIEluIHRoZSBjYXNlIHRoZSBhY3R1YWwgY29uc3RyYWludCB2YWx1ZSByZXByZXNlbnRzIGEgbGlzdCwgaS5lLiB0aGUKLSAgICAgKiA8Y29kZT5hY3R1YWxWYWx1ZVR5cGU8L2NvZGU+IGlzIDxjb2RlPkxJU1RfRFQ8L2NvZGU+LCB0aGUgcmV0dXJuZWQKLSAgICAgKiBhcnJheSBjb25zaXN0cyBvZiBvbmUgdHlwZSBraW5kIHdoaWNoIHJlcHJlc2VudHMgdGhlIGl0ZW1UeXBlLiBJZiB0aGUKLSAgICAgKiBhY3R1YWwgY29uc3RyYWludCB2YWx1ZSByZXByZXNlbnRzIGEgbGlzdCB0eXBlIGRlZmluaXRpb24gd2hvc2UgaXRlbQotICAgICAqIHR5cGUgaXMgYSB1bmlvbiB0eXBlIGRlZmluaXRpb24sIGkuZS4gPGNvZGU+TElTVE9GVU5JT05fRFQ8L2NvZGU+LAotICAgICAqIGZvciBlYWNoIGFjdHVhbCBjb25zdHJhaW50IHZhbHVlIGluIHRoZSBsaXN0IHRoZSBhcnJheSBjb250YWlucyB0aGUKLSAgICAgKiBjb3JyZXNwb25kaW5nIG1lbWJlclR5cGUga2luZC4gRm9yIGV4YW1wbGVzLCBzZWUKLSAgICAgKiA8Y29kZT5JdGVtUFNWSS5pdGVtVmFsdWVUeXBlczwvY29kZT4uCi0gICAgICogQGV4Y2VwdGlvbiBYU0V4Y2VwdGlvbgotICAgICAqICAgTk9UX1NVUFBPUlRFRF9FUlI6IFJhaXNlZCBpZiB0aGUgaW1wbGVtZW50YXRpb24gZG9lcyBub3Qgc3VwcG9ydCB0aGlzCi0gICAgICogICBtZXRob2QuCi0gICAgICovCi0gICAgcHVibGljIFNob3J0TGlzdCBnZXRJdGVtVmFsdWVUeXBlcygpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgWFNFeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBBIHNlcXVlbmNlIG9mIFthbm5vdGF0aW9uc10gb3IgYW4gZW1wdHkgPGNvZGU+WFNPYmplY3RMaXN0PC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFNPYmplY3RMaXN0IGdldEFubm90YXRpb25zKCk7Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94cy9YU0NvbXBsZXhUeXBlRGVmaW5pdGlvbi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHMvWFNDb21wbGV4VHlwZURlZmluaXRpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMTA0ZGJiNi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94cy9YU0NvbXBsZXhUeXBlRGVmaW5pdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTE2ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDMsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54czsKLQotLyoqCi0gKiBUaGlzIGludGVyZmFjZSByZXByZXNlbnRzIHRoZSBDb21wbGV4IFR5cGUgRGVmaW5pdGlvbiBzY2hlbWEgY29tcG9uZW50LgotICovCi1wdWJsaWMgaW50ZXJmYWNlIFhTQ29tcGxleFR5cGVEZWZpbml0aW9uIGV4dGVuZHMgWFNUeXBlRGVmaW5pdGlvbiB7Ci0gICAgLy8gQ29udGVudCBNb2RlbCBUeXBlcwotICAgIC8qKgotICAgICAqIFJlcHJlc2VudHMgYW4gZW1wdHkgY29udGVudCB0eXBlLiBBIGNvbnRlbnQgdHlwZSB3aXRoIHRoZSBkaXN0aW5ndWlzaGVkCi0gICAgICogdmFsdWUgZW1wdHkgdmFsaWRhdGVzIGVsZW1lbnRzIHdpdGggbm8gY2hhcmFjdGVyIG9yIGVsZW1lbnQKLSAgICAgKiBpbmZvcm1hdGlvbiBpdGVtIGNoaWxkcmVuLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgQ09OVEVOVFRZUEVfRU1QVFkgICAgICAgICA9IDA7Ci0gICAgLyoqCi0gICAgICogUmVwcmVzZW50cyBhIHNpbXBsZSBjb250ZW50IHR5cGUuIEEgY29udGVudCB0eXBlIHdoaWNoIGlzIHNpbXBsZQotICAgICAqIHZhbGlkYXRlcyBlbGVtZW50cyB3aXRoIGNoYXJhY3Rlci1vbmx5IGNoaWxkcmVuLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgQ09OVEVOVFRZUEVfU0lNUExFICAgICAgICA9IDE7Ci0gICAgLyoqCi0gICAgICogUmVwcmVzZW50cyBhbiBlbGVtZW50LW9ubHkgY29udGVudCB0eXBlLiBBbiBlbGVtZW50LW9ubHkgY29udGVudCB0eXBlCi0gICAgICogdmFsaWRhdGVzIGVsZW1lbnRzIHdpdGggY2hpbGRyZW4gdGhhdCBjb25mb3JtIHRvIHRoZSBzdXBwbGllZCBjb250ZW50Ci0gICAgICogbW9kZWwuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBDT05URU5UVFlQRV9FTEVNRU5UICAgICAgID0gMjsKLSAgICAvKioKLSAgICAgKiBSZXByZXNlbnRzIGEgbWl4ZWQgY29udGVudCB0eXBlLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgQ09OVEVOVFRZUEVfTUlYRUQgICAgICAgICA9IDM7Ci0KLSAgICAvKioKLSAgICAgKiBbZGVyaXZhdGlvbiBtZXRob2RdOiBlaXRoZXIgPGNvZGU+REVSSVZBVElPTl9FWFRFTlNJT048L2NvZGU+LAotICAgICAqIDxjb2RlPkRFUklWQVRJT05fUkVTVFJJQ1RJT048L2NvZGU+LCBvciA8Y29kZT5ERVJJVkFUSU9OX05PTkU8L2NvZGU+Ci0gICAgICogKHNlZSA8Y29kZT5YU0NvbnN0YW50czwvY29kZT4pLgotICAgICAqLwotICAgIHB1YmxpYyBzaG9ydCBnZXREZXJpdmF0aW9uTWV0aG9kKCk7Ci0KLSAgICAvKioKLSAgICAgKiBbYWJzdHJhY3RdOiBhIGJvb2xlYW4uIENvbXBsZXggdHlwZXMgZm9yIHdoaWNoIDxjb2RlPmFic3RyYWN0PC9jb2RlPiBpcwotICAgICAqIHRydWUgbXVzdCBub3QgYmUgdXNlZCBhcyB0aGUgdHlwZSBkZWZpbml0aW9uIGZvciB0aGUgdmFsaWRhdGlvbiBvZgotICAgICAqIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbXMuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0QWJzdHJhY3QoKTsKLQotICAgIC8qKgotICAgICAqICBBIHNldCBvZiBhdHRyaWJ1dGUgdXNlcyBpZiBpdCBleGlzdHMsIG90aGVyd2lzZSBhbiBlbXB0eQotICAgICAqIDxjb2RlPlhTT2JqZWN0TGlzdDwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIFhTT2JqZWN0TGlzdCBnZXRBdHRyaWJ1dGVVc2VzKCk7Ci0KLSAgICAvKioKLSAgICAgKiBBbiBhdHRyaWJ1dGUgd2lsZGNhcmQgaWYgaXQgZXhpc3RzLCBvdGhlcndpc2UgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIFhTV2lsZGNhcmQgZ2V0QXR0cmlidXRlV2lsZGNhcmQoKTsKLQotICAgIC8qKgotICAgICAqIFtjb250ZW50IHR5cGVdOiBvbmUgb2YgZW1wdHkgKDxjb2RlPkNPTlRFTlRUWVBFX0VNUFRZPC9jb2RlPiksIGEgc2ltcGxlCi0gICAgICogdHlwZSBkZWZpbml0aW9uICg8Y29kZT5DT05URU5UVFlQRV9TSU1QTEU8L2NvZGU+KSwgbWl4ZWQgKAotICAgICAqIDxjb2RlPkNPTlRFTlRUWVBFX01JWEVEPC9jb2RlPiksIG9yIGVsZW1lbnQtb25seSAoCi0gICAgICogPGNvZGU+Q09OVEVOVFRZUEVfRUxFTUVOVDwvY29kZT4pLgotICAgICAqLwotICAgIHB1YmxpYyBzaG9ydCBnZXRDb250ZW50VHlwZSgpOwotCi0gICAgLyoqCi0gICAgICogQSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uIGNvcnJlc3BvbmRpbmcgdG8gYSBzaW1wbGUgY29udGVudCBtb2RlbCwKLSAgICAgKiBvdGhlcndpc2UgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIFhTU2ltcGxlVHlwZURlZmluaXRpb24gZ2V0U2ltcGxlVHlwZSgpOwotCi0gICAgLyoqCi0gICAgICogQSBwYXJ0aWNsZSBmb3IgYSBtaXhlZCBvciBlbGVtZW50LW9ubHkgY29udGVudCBtb2RlbCwgb3RoZXJ3aXNlCi0gICAgICogPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIFhTUGFydGljbGUgZ2V0UGFydGljbGUoKTsKLQotICAgIC8qKgotICAgICAqIFtwcm9oaWJpdGVkIHN1YnN0aXR1dGlvbnNdOiBhIHN1YnNldCBvZiB7ZXh0ZW5zaW9uLCByZXN0cmljdGlvbn0KLSAgICAgKiBAcGFyYW0gcmVzdHJpY3Rpb24gIEV4dGVuc2lvbiBvciByZXN0cmljdGlvbiBjb25zdGFudHMgKHNlZQotICAgICAqICAgPGNvZGU+WFNDb25zdGFudHM8L2NvZGU+KS4KLSAgICAgKiBAcmV0dXJuIFRydWUgaWYgPGNvZGU+cmVzdHJpY3Rpb248L2NvZGU+IGlzIGEgcHJvaGliaXRlZCBzdWJzdGl0dXRpb24sCi0gICAgICogICBvdGhlcndpc2UgZmFsc2UuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNQcm9oaWJpdGVkU3Vic3RpdHV0aW9uKHNob3J0IHJlc3RyaWN0aW9uKTsKLQotICAgIC8qKgotICAgICAqICBbcHJvaGliaXRlZCBzdWJzdGl0dXRpb25zXTogQSBzdWJzZXQgb2Yge2V4dGVuc2lvbiwgcmVzdHJpY3Rpb259IG9yCi0gICAgICogPGNvZGU+REVSSVZBVElPTl9OT05FPC9jb2RlPiByZXByZXNlbnRlZCBhcyBhIGJpdCBmbGFnIChzZWUKLSAgICAgKiA8Y29kZT5YU0NvbnN0YW50czwvY29kZT4pLgotICAgICAqLwotICAgIHB1YmxpYyBzaG9ydCBnZXRQcm9oaWJpdGVkU3Vic3RpdHV0aW9ucygpOwotCi0gICAgLyoqCi0gICAgICogQSBzZXF1ZW5jZSBvZiBbYW5ub3RhdGlvbnNdIG9yIGFuIGVtcHR5IDxjb2RlPlhTT2JqZWN0TGlzdDwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIFhTT2JqZWN0TGlzdCBnZXRBbm5vdGF0aW9ucygpOwotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94cy9YU0NvbnN0YW50cy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHMvWFNDb25zdGFudHMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggY2JlMWE0Ni4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94cy9YU0NvbnN0YW50cy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzQ1ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDMtMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54czsKLQotLyoqCi0gKiAgVGhpcyBpbnRlcmZhY2UgZGVmaW5lcyBjb25zdGFudHMgdXNlZCBieSB0aGlzIHNwZWNpZmljYXRpb24uCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgWFNDb25zdGFudHMgewotICAgIC8vIFhNTCBTY2hlbWEgQ29tcG9uZW50cwotICAgIC8qKgotICAgICAqIFRoZSBvYmplY3QgZGVzY3JpYmVzIGFuIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IEFUVFJJQlVURV9ERUNMQVJBVElPTiAgICAgPSAxOwotICAgIC8qKgotICAgICAqIFRoZSBvYmplY3QgZGVzY3JpYmVzIGFuIGVsZW1lbnQgZGVjbGFyYXRpb24uCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBFTEVNRU5UX0RFQ0xBUkFUSU9OICAgICAgID0gMjsKLSAgICAvKioKLSAgICAgKiBUaGUgb2JqZWN0IGRlc2NyaWJlcyBhIGNvbXBsZXggdHlwZSBvciBzaW1wbGUgdHlwZSBkZWZpbml0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgVFlQRV9ERUZJTklUSU9OICAgICAgICAgICA9IDM7Ci0gICAgLyoqCi0gICAgICogVGhlIG9iamVjdCBkZXNjcmliZXMgYW4gYXR0cmlidXRlIHVzZSBkZWZpbml0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgQVRUUklCVVRFX1VTRSAgICAgICAgICAgICA9IDQ7Ci0gICAgLyoqCi0gICAgICogVGhlIG9iamVjdCBkZXNjcmliZXMgYW4gYXR0cmlidXRlIGdyb3VwIGRlZmluaXRpb24uCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBBVFRSSUJVVEVfR1JPVVAgICAgICAgICAgID0gNTsKLSAgICAvKioKLSAgICAgKiBUaGUgb2JqZWN0IGRlc2NyaWJlcyBhIG1vZGVsIGdyb3VwIGRlZmluaXRpb24uCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBNT0RFTF9HUk9VUF9ERUZJTklUSU9OICAgID0gNjsKLSAgICAvKioKLSAgICAgKiBBIG1vZGVsIGdyb3VwLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgTU9ERUxfR1JPVVAgICAgICAgICAgICAgICA9IDc7Ci0gICAgLyoqCi0gICAgICogVGhlIG9iamVjdCBkZXNjcmliZXMgYSBwYXJ0aWNsZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFBBUlRJQ0xFICAgICAgICAgICAgICAgICAgPSA4OwotICAgIC8qKgotICAgICAqIFRoZSBvYmplY3QgZGVzY3JpYmVzIGEgd2lsZGNhcmQuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBXSUxEQ0FSRCAgICAgICAgICAgICAgICAgID0gOTsKLSAgICAvKioKLSAgICAgKiBUaGUgb2JqZWN0IGRlc2NyaWJlcyBhbiBpZGVudGl0eSBjb25zdHJhaW50IGRlZmluaXRpb24uCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBJREVOVElUWV9DT05TVFJBSU5UICAgICAgID0gMTA7Ci0gICAgLyoqCi0gICAgICogVGhlIG9iamVjdCBkZXNjcmliZXMgYSBub3RhdGlvbiBkZWNsYXJhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IE5PVEFUSU9OX0RFQ0xBUkFUSU9OICAgICAgPSAxMTsKLSAgICAvKioKLSAgICAgKiBUaGUgb2JqZWN0IGRlc2NyaWJlcyBhbiBhbm5vdGF0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgQU5OT1RBVElPTiAgICAgICAgICAgICAgICA9IDEyOwotICAgIC8qKgotICAgICAqIFRoZSBvYmplY3QgZGVzY3JpYmVzIGEgY29uc3RyYWluaW5nIGZhY2V0LiBOb3RlOiB0aGlzIG9iamVjdCBkb2VzIG5vdAotICAgICAqIGRlc2NyaWJlIHBhdHRlcm4gYW5kIGVudW1lcmF0aW9uIGZhY2V0cy4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IEZBQ0VUICAgICAgICAgICAgICAgICAgICAgPSAxMzsKLSAgICAvKioKLSAgICAgKiBUaGUgb2JqZWN0IGRlc2NyaWJlcyBlbnVtZXJhdGlvbiBhbmQgcGF0dGVybiBmYWNldHMuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBNVUxUSVZBTFVFX0ZBQ0VUICAgICAgICAgID0gMTQ7Ci0KLSAgICAvLyBEZXJpdmF0aW9uIGNvbnN0YW50cwotICAgIC8qKgotICAgICAqIE5vIGNvbnN0cmFpbnQgaXMgYXZhaWxhYmxlLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgREVSSVZBVElPTl9OT05FICAgICAgICAgICA9IDA7Ci0gICAgLyoqCi0gICAgICogPGNvZGU+WFNUeXBlRGVmaW5pdGlvbjwvY29kZT4gZmluYWwgc2V0IG9yCi0gICAgICogPGNvZGU+WFNFbGVtZW50RGVjbGFyYXRpb248L2NvZGU+IGRpc2FsbG93ZWQgc3Vic3RpdHV0aW9uIGdyb3VwLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgREVSSVZBVElPTl9FWFRFTlNJT04gICAgICA9IDE7Ci0gICAgLyoqCi0gICAgICogPGNvZGU+WFNUeXBlRGVmaW5pdGlvbjwvY29kZT4gZmluYWwgc2V0IG9yCi0gICAgICogPGNvZGU+WFNFbGVtZW50RGVjbGFyYXRpb248L2NvZGU+IGRpc2FsbG93ZWQgc3Vic3RpdHV0aW9uIGdyb3VwLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgREVSSVZBVElPTl9SRVNUUklDVElPTiAgICA9IDI7Ci0gICAgLyoqCi0gICAgICogPGNvZGU+WFNUeXBlRGVmaW5pdGlvbjwvY29kZT4gZmluYWwgc2V0LgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgREVSSVZBVElPTl9TVUJTVElUVVRJT04gICA9IDQ7Ci0gICAgLyoqCi0gICAgICogPGNvZGU+WFNUeXBlRGVmaW5pdGlvbjwvY29kZT4gZmluYWwgc2V0LgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgREVSSVZBVElPTl9VTklPTiAgICAgICAgICA9IDg7Ci0gICAgLyoqCi0gICAgICogPGNvZGU+WFNUeXBlRGVmaW5pdGlvbjwvY29kZT4gZmluYWwgc2V0LgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgREVSSVZBVElPTl9MSVNUICAgICAgICAgICA9IDE2OwotICAgIC8qKgotICAgICAqIDxjb2RlPlhTVHlwZURlZmluaXRpb248L2NvZGU+IGZpbmFsIHNldC4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IERFUklWQVRJT05fRVhURU5TSU9OX1JFU1RSSUNUSU9OX1NVQlNUSVRJT04gPQotICAgICAgICAgICAgWFNDb25zdGFudHMuREVSSVZBVElPTl9FWFRFTlNJT04KLSAgICAgICAgICAgIHwgWFNDb25zdGFudHMuREVSSVZBVElPTl9SRVNUUklDVElPTgotICAgICAgICAgICAgfCBYU0NvbnN0YW50cy5ERVJJVkFUSU9OX1NVQlNUSVRVVElPTjsKLSAgICAvKioKLSAgICAgKiA8Y29kZT5YU1R5cGVEZWZpbml0aW9uPC9jb2RlPiBmaW5hbCBzZXQuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBERVJJVkFUSU9OX0FMTCAgICAgICAgICAgID0KLSAgICAgICAgICAgIFhTQ29uc3RhbnRzLkRFUklWQVRJT05fU1VCU1RJVFVUSU9OCi0gICAgICAgICAgICB8IFhTQ29uc3RhbnRzLkRFUklWQVRJT05fRVhURU5TSU9OCi0gICAgICAgICAgICB8IFhTQ29uc3RhbnRzLkRFUklWQVRJT05fUkVTVFJJQ1RJT04KLSAgICAgICAgICAgIHwgWFNDb25zdGFudHMuREVSSVZBVElPTl9MSVNUCi0gICAgICAgICAgICB8IFhTQ29uc3RhbnRzLkRFUklWQVRJT05fVU5JT047Ci0KLSAgICAvLyBTY29wZQotICAgIC8qKgotICAgICAqIFRoZSBzY29wZSBvZiBhIGRlY2xhcmF0aW9uIHdpdGhpbiBuYW1lZCBtb2RlbCBncm91cHMgb3IgYXR0cmlidXRlCi0gICAgICogZ3JvdXBzIGlzIDxjb2RlPmFic2VudDwvY29kZT4uIFRoZSBzY29wZSBvZiBzdWNoIGEgZGVjbGFyYXRpb24gaXMKLSAgICAgKiBkZXRlcm1pbmVkIHdoZW4gaXQgaXMgdXNlZCBpbiB0aGUgY29uc3RydWN0aW9uIG9mIGNvbXBsZXggdHlwZQotICAgICAqIGRlZmluaXRpb25zLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgU0NPUEVfQUJTRU5UICAgICAgICAgICAgICA9IDA7Ci0gICAgLyoqCi0gICAgICogQSBzY29wZSBvZiA8Y29kZT5nbG9iYWw8L2NvZGU+IGlkZW50aWZpZXMgdG9wLWxldmVsIGRlY2xhcmF0aW9ucy4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFNDT1BFX0dMT0JBTCAgICAgICAgICAgICAgPSAxOwotICAgIC8qKgotICAgICAqIDxjb2RlPkxvY2FsbHkgc2NvcGVkPC9jb2RlPiBkZWNsYXJhdGlvbnMgYXJlIGF2YWlsYWJsZSBmb3IgdXNlIG9ubHkKLSAgICAgKiB3aXRoaW4gdGhlIGNvbXBsZXggdHlwZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFNDT1BFX0xPQ0FMICAgICAgICAgICAgICAgPSAyOwotCi0gICAgLy8gVmFsdWUgQ29uc3RyYWludAotICAgIC8qKgotICAgICAqIEluZGljYXRlcyB0aGF0IHRoZSBjb21wb25lbnQgZG9lcyBub3QgaGF2ZSBhbnkgdmFsdWUgY29uc3RyYWludC4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFZDX05PTkUgICAgICAgICAgICAgICAgICAgPSAwOwotICAgIC8qKgotICAgICAqIEluZGljYXRlcyB0aGF0IHRoZXJlIGlzIGEgZGVmYXVsdCB2YWx1ZSBjb25zdHJhaW50LgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgVkNfREVGQVVMVCAgICAgICAgICAgICAgICA9IDE7Ci0gICAgLyoqCi0gICAgICogSW5kaWNhdGVzIHRoYXQgdGhlcmUgaXMgYSBmaXhlZCB2YWx1ZSBjb25zdHJhaW50IGZvciB0aGlzIGF0dHJpYnV0ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFZDX0ZJWEVEICAgICAgICAgICAgICAgICAgPSAyOwotCi0gICAgLy8gQnVpbHQtaW4gdHlwZXM6IHByaW1pdGl2ZSBhbmQgZGVyaXZlZAotICAgIC8qKgotICAgICAqIGFueVNpbXBsZVR5cGUKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IEFOWVNJTVBMRVRZUEVfRFQgICAgICAgICAgPSAxOwotICAgIC8qKgotICAgICAqIHN0cmluZwotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgU1RSSU5HX0RUICAgICAgICAgICAgICAgICA9IDI7Ci0gICAgLyoqCi0gICAgICogYm9vbGVhbgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgQk9PTEVBTl9EVCAgICAgICAgICAgICAgICA9IDM7Ci0gICAgLyoqCi0gICAgICogZGVjaW1hbAotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgREVDSU1BTF9EVCAgICAgICAgICAgICAgICA9IDQ7Ci0gICAgLyoqCi0gICAgICogZmxvYXQKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IEZMT0FUX0RUICAgICAgICAgICAgICAgICAgPSA1OwotICAgIC8qKgotICAgICAqIGRvdWJsZQotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgRE9VQkxFX0RUICAgICAgICAgICAgICAgICA9IDY7Ci0gICAgLyoqCi0gICAgICogZHVyYXRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IERVUkFUSU9OX0RUICAgICAgICAgICAgICAgPSA3OwotICAgIC8qKgotICAgICAqIGRhdGVUaW1lCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBEQVRFVElNRV9EVCAgICAgICAgICAgICAgID0gODsKLSAgICAvKioKLSAgICAgKiB0aW1lCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBUSU1FX0RUICAgICAgICAgICAgICAgICAgID0gOTsKLSAgICAvKioKLSAgICAgKiBkYXRlCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBEQVRFX0RUICAgICAgICAgICAgICAgICAgID0gMTA7Ci0gICAgLyoqCi0gICAgICogZ1llYXJNb250aAotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgR1lFQVJNT05USF9EVCAgICAgICAgICAgICA9IDExOwotICAgIC8qKgotICAgICAqIGdZZWFyCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBHWUVBUl9EVCAgICAgICAgICAgICAgICAgID0gMTI7Ci0gICAgLyoqCi0gICAgICogZ01vbnRoRGF5Ci0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBHTU9OVEhEQVlfRFQgICAgICAgICAgICAgID0gMTM7Ci0gICAgLyoqCi0gICAgICogZ0RheQotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgR0RBWV9EVCAgICAgICAgICAgICAgICAgICA9IDE0OwotICAgIC8qKgotICAgICAqIGdNb250aAotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgR01PTlRIX0RUICAgICAgICAgICAgICAgICA9IDE1OwotICAgIC8qKgotICAgICAqIGhleEJpbmFyeQotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgSEVYQklOQVJZX0RUICAgICAgICAgICAgICA9IDE2OwotICAgIC8qKgotICAgICAqIGJhc2U2NEJpbmFyeQotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgQkFTRTY0QklOQVJZX0RUICAgICAgICAgICA9IDE3OwotICAgIC8qKgotICAgICAqIGFueVVSSQotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgQU5ZVVJJX0RUICAgICAgICAgICAgICAgICA9IDE4OwotICAgIC8qKgotICAgICAqIFFOYW1lCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBRTkFNRV9EVCAgICAgICAgICAgICAgICAgID0gMTk7Ci0gICAgLyoqCi0gICAgICogTk9UQVRJT04KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IE5PVEFUSU9OX0RUICAgICAgICAgICAgICAgPSAyMDsKLSAgICAvKioKLSAgICAgKiBub3JtYWxpemVkU3RyaW5nCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBOT1JNQUxJWkVEU1RSSU5HX0RUICAgICAgID0gMjE7Ci0gICAgLyoqCi0gICAgICogdG9rZW4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFRPS0VOX0RUICAgICAgICAgICAgICAgICAgPSAyMjsKLSAgICAvKioKLSAgICAgKiBsYW5ndWFnZQotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgTEFOR1VBR0VfRFQgICAgICAgICAgICAgICA9IDIzOwotICAgIC8qKgotICAgICAqIE5NVE9LRU4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IE5NVE9LRU5fRFQgICAgICAgICAgICAgICAgPSAyNDsKLSAgICAvKioKLSAgICAgKiBOYW1lCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBOQU1FX0RUICAgICAgICAgICAgICAgICAgID0gMjU7Ci0gICAgLyoqCi0gICAgICogTkNOYW1lCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBOQ05BTUVfRFQgICAgICAgICAgICAgICAgID0gMjY7Ci0gICAgLyoqCi0gICAgICogSUQKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IElEX0RUICAgICAgICAgICAgICAgICAgICAgPSAyNzsKLSAgICAvKioKLSAgICAgKiBJRFJFRgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgSURSRUZfRFQgICAgICAgICAgICAgICAgICA9IDI4OwotICAgIC8qKgotICAgICAqIEVOVElUWQotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgRU5USVRZX0RUICAgICAgICAgICAgICAgICA9IDI5OwotICAgIC8qKgotICAgICAqIGludGVnZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IElOVEVHRVJfRFQgICAgICAgICAgICAgICAgPSAzMDsKLSAgICAvKioKLSAgICAgKiBub25Qb3NpdGl2ZUludGVnZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IE5PTlBPU0lUSVZFSU5URUdFUl9EVCAgICAgPSAzMTsKLSAgICAvKioKLSAgICAgKiBuZWdhdGl2ZUludGVnZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IE5FR0FUSVZFSU5URUdFUl9EVCAgICAgICAgPSAzMjsKLSAgICAvKioKLSAgICAgKiBsb25nCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBMT05HX0RUICAgICAgICAgICAgICAgICAgID0gMzM7Ci0gICAgLyoqCi0gICAgICogaW50Ci0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBJTlRfRFQgICAgICAgICAgICAgICAgICAgID0gMzQ7Ci0gICAgLyoqCi0gICAgICogc2hvcnQKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFNIT1JUX0RUICAgICAgICAgICAgICAgICAgPSAzNTsKLSAgICAvKioKLSAgICAgKiBieXRlCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBCWVRFX0RUICAgICAgICAgICAgICAgICAgID0gMzY7Ci0gICAgLyoqCi0gICAgICogbm9uTmVnYXRpdmVJbnRlZ2VyCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBOT05ORUdBVElWRUlOVEVHRVJfRFQgICAgID0gMzc7Ci0gICAgLyoqCi0gICAgICogdW5zaWduZWRMb25nCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBVTlNJR05FRExPTkdfRFQgICAgICAgICAgID0gMzg7Ci0gICAgLyoqCi0gICAgICogdW5zaWduZWRJbnQKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFVOU0lHTkVESU5UX0RUICAgICAgICAgICAgPSAzOTsKLSAgICAvKioKLSAgICAgKiB1bnNpZ25lZFNob3J0Ci0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBVTlNJR05FRFNIT1JUX0RUICAgICAgICAgID0gNDA7Ci0gICAgLyoqCi0gICAgICogdW5zaWduZWRCeXRlCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBVTlNJR05FREJZVEVfRFQgICAgICAgICAgID0gNDE7Ci0gICAgLyoqCi0gICAgICogcG9zaXRpdmVJbnRlZ2VyCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBQT1NJVElWRUlOVEVHRVJfRFQgICAgICAgID0gNDI7Ci0gICAgLyoqCi0gICAgICogVGhlIHR5cGUgcmVwcmVzZW50cyBhIGxpc3QgdHlwZSBkZWZpbml0aW9uIHdob3NlIGl0ZW0gdHlwZSAoaXRlbVR5cGUpCi0gICAgICogaXMgYSB1bmlvbiB0eXBlIGRlZmluaXRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IExJU1RPRlVOSU9OX0RUICAgICAgICAgICAgPSA0MzsKLSAgICAvKioKLSAgICAgKiBUaGUgdHlwZSByZXByZXNlbnRzIGEgbGlzdCB0eXBlIGRlZmluaXRpb24uCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBMSVNUX0RUICAgICAgICAgICAgICAgICAgID0gNDQ7Ci0gICAgLyoqCi0gICAgICogVGhlIGJ1aWx0LWluIHR5cGUgY2F0ZWdvcnkgaXMgbm90IGF2YWlsYWJsZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFVOQVZBSUxBQkxFX0RUICAgICAgICAgICAgPSA0NTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHMvWFNFbGVtZW50RGVjbGFyYXRpb24uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3hzL1hTRWxlbWVudERlY2xhcmF0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDQ4YWU5ZGQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHMvWFNFbGVtZW50RGVjbGFyYXRpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE4MCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAzLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHM7Ci0KLS8qKgotICogVGhlIGludGVyZmFjZSByZXByZXNlbnRzIHRoZSBFbGVtZW50IERlY2xhcmF0aW9uIHNjaGVtYSBjb21wb25lbnQuCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgWFNFbGVtZW50RGVjbGFyYXRpb24gZXh0ZW5kcyBYU1Rlcm0gewotICAgIC8qKgotICAgICAqIFt0eXBlIGRlZmluaXRpb25dOiBlaXRoZXIgYSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uIG9yIGEgY29tcGxleCB0eXBlCi0gICAgICogZGVmaW5pdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFNUeXBlRGVmaW5pdGlvbiBnZXRUeXBlRGVmaW5pdGlvbigpOwotCi0gICAgLyoqCi0gICAgICogW3Njb3BlXS4gT25lIG9mIDxjb2RlPlNDT1BFX0dMT0JBTDwvY29kZT4sIDxjb2RlPlNDT1BFX0xPQ0FMPC9jb2RlPiwgb3IKLSAgICAgKiA8Y29kZT5TQ09QRV9BQlNFTlQ8L2NvZGU+LiBJZiB0aGUgc2NvcGUgaXMgbG9jYWwsIHRoZW4gdGhlCi0gICAgICogPGNvZGU+ZW5jbG9zaW5nQ1REZWZpbml0aW9uPC9jb2RlPiBpcyBwcmVzZW50LgotICAgICAqLwotICAgIHB1YmxpYyBzaG9ydCBnZXRTY29wZSgpOwotCi0gICAgLyoqCi0gICAgICogVGhlIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uIGZvciBsb2NhbGx5IHNjb3BlZCBkZWNsYXJhdGlvbnMgKHNlZQotICAgICAqIDxjb2RlPnNjb3BlPC9jb2RlPiksIG90aGVyd2lzZSA8Y29kZT5udWxsPC9jb2RlPiBpZiBubyBzdWNoCi0gICAgICogZGVmaW5pdGlvbiBleGlzdHMuCi0gICAgICovCi0gICAgcHVibGljIFhTQ29tcGxleFR5cGVEZWZpbml0aW9uIGdldEVuY2xvc2luZ0NURGVmaW5pdGlvbigpOwotCi0gICAgLyoqCi0gICAgICogW1ZhbHVlIGNvbnN0cmFpbnRdOiBvbmUgb2YgPGNvZGU+VkNfTk9ORSwgVkNfREVGQVVMVCwgVkNfRklYRUQ8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBzaG9ydCBnZXRDb25zdHJhaW50VHlwZSgpOwotCi0gICAgLyoqCi0gICAgICogW1ZhbHVlIGNvbnN0cmFpbnRdOiB0aGUgY29uc3RyYWludCB2YWx1ZSB3aXRoIHJlc3BlY3QgdG8gdGhlIFt0eXBlCi0gICAgICogZGVmaW5pdGlvbl0sIG90aGVyd2lzZSA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldENvbnN0cmFpbnRWYWx1ZSgpOwotCi0gICAgLyoqCi0gICAgICogVmFsdWUgQ29uc3RyYWludDogQmluZGluZyBzcGVjaWZpYyBhY3R1YWwgY29uc3RyYWludCB2YWx1ZSBvcgotICAgICAqIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoZSB2YWx1ZSBpcyBpbiBlcnJvciBvciB0aGVyZSBpcyBubyB2YWx1ZQotICAgICAqIGNvbnN0cmFpbnQuCi0gICAgICogQGV4Y2VwdGlvbiBYU0V4Y2VwdGlvbgotICAgICAqICAgTk9UX1NVUFBPUlRFRF9FUlI6IFJhaXNlZCBpZiB0aGUgaW1wbGVtZW50YXRpb24gZG9lcyBub3Qgc3VwcG9ydCB0aGlzCi0gICAgICogICBtZXRob2QuCi0gICAgICovCi0gICAgcHVibGljIE9iamVjdCBnZXRBY3R1YWxWQygpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBYU0V4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIFRoZSBhY3R1YWwgY29uc3RyYWludCB2YWx1ZSBidWlsdC1pbiBkYXRhdHlwZSwgZS5nLgotICAgICAqIDxjb2RlPlNUUklOR19EVCwgU0hPUlRfRFQ8L2NvZGU+LiBJZiB0aGUgdHlwZSBkZWZpbml0aW9uIG9mIHRoaXMKLSAgICAgKiB2YWx1ZSBpcyBhIGxpc3QgdHlwZSBkZWZpbml0aW9uLCB0aGlzIG1ldGhvZCByZXR1cm5zCi0gICAgICogPGNvZGU+TElTVF9EVDwvY29kZT4uIElmIHRoZSB0eXBlIGRlZmluaXRpb24gb2YgdGhpcyB2YWx1ZSBpcyBhIGxpc3QKLSAgICAgKiB0eXBlIGRlZmluaXRpb24gd2hvc2UgaXRlbSB0eXBlIGlzIGEgdW5pb24gdHlwZSBkZWZpbml0aW9uLCB0aGlzCi0gICAgICogbWV0aG9kIHJldHVybnMgPGNvZGU+TElTVE9GVU5JT05fRFQ8L2NvZGU+LiBUbyBxdWVyeSB0aGUgYWN0dWFsCi0gICAgICogY29uc3RyYWludCB2YWx1ZSBvZiB0aGUgbGlzdCBvciBsaXN0IG9mIHVuaW9uIHR5cGUgZGVmaW5pdGlvbnMgdXNlCi0gICAgICogPGNvZGU+aXRlbVZhbHVlVHlwZXM8L2NvZGU+LiBJZiB0aGUgPGNvZGU+YWN0dWFsTm9ybWFsaXplZFZhbHVlPC9jb2RlPgotICAgICAqICBpcyA8Y29kZT5udWxsPC9jb2RlPiwgdGhpcyBtZXRob2QgcmV0dXJucyA8Y29kZT5VTkFWQUlMQUJMRV9EVDwvY29kZT4KLSAgICAgKiAuCi0gICAgICogQGV4Y2VwdGlvbiBYU0V4Y2VwdGlvbgotICAgICAqICAgTk9UX1NVUFBPUlRFRF9FUlI6IFJhaXNlZCBpZiB0aGUgaW1wbGVtZW50YXRpb24gZG9lcyBub3Qgc3VwcG9ydCB0aGlzCi0gICAgICogICBtZXRob2QuCi0gICAgICovCi0gICAgcHVibGljIHNob3J0IGdldEFjdHVhbFZDVHlwZSgpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBYU0V4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIEluIHRoZSBjYXNlIHRoZSBhY3R1YWwgY29uc3RyYWludCB2YWx1ZSByZXByZXNlbnRzIGEgbGlzdCwgaS5lLiB0aGUKLSAgICAgKiA8Y29kZT5hY3R1YWxWYWx1ZVR5cGU8L2NvZGU+IGlzIDxjb2RlPkxJU1RfRFQ8L2NvZGU+LCB0aGUgcmV0dXJuZWQKLSAgICAgKiBhcnJheSBjb25zaXN0cyBvZiBvbmUgdHlwZSBraW5kIHdoaWNoIHJlcHJlc2VudHMgdGhlIGl0ZW1UeXBlLiBJZiB0aGUKLSAgICAgKiBhY3R1YWwgY29uc3RyYWludCB2YWx1ZSByZXByZXNlbnRzIGEgbGlzdCB0eXBlIGRlZmluaXRpb24gd2hvc2UgaXRlbQotICAgICAqIHR5cGUgaXMgYSB1bmlvbiB0eXBlIGRlZmluaXRpb24sIGkuZS4gPGNvZGU+TElTVE9GVU5JT05fRFQ8L2NvZGU+LAotICAgICAqIGZvciBlYWNoIGFjdHVhbCBjb25zdHJhaW50IHZhbHVlIGluIHRoZSBsaXN0IHRoZSBhcnJheSBjb250YWlucyB0aGUKLSAgICAgKiBjb3JyZXNwb25kaW5nIG1lbWJlclR5cGUga2luZC4gRm9yIGV4YW1wbGVzLCBzZWUKLSAgICAgKiA8Y29kZT5JdGVtUFNWSS5pdGVtVmFsdWVUeXBlczwvY29kZT4uCi0gICAgICogQGV4Y2VwdGlvbiBYU0V4Y2VwdGlvbgotICAgICAqICAgTk9UX1NVUFBPUlRFRF9FUlI6IFJhaXNlZCBpZiB0aGUgaW1wbGVtZW50YXRpb24gZG9lcyBub3Qgc3VwcG9ydCB0aGlzCi0gICAgICogICBtZXRob2QuCi0gICAgICovCi0gICAgcHVibGljIFNob3J0TGlzdCBnZXRJdGVtVmFsdWVUeXBlcygpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBYU0V4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBJZiBuaWxsYWJsZSBpcyB0cnVlLCB0aGVuIGFuIGVsZW1lbnQgbWF5IGFsc28gYmUgdmFsaWQgaWYgaXQgY2FycmllcwotICAgICAqIHRoZSBuYW1lc3BhY2UgcXVhbGlmaWVkIGF0dHJpYnV0ZSB3aXRoIGxvY2FsIG5hbWUgPGNvZGU+bmlsPC9jb2RlPgotICAgICAqIGZyb20gbmFtZXNwYWNlIDxjb2RlPmh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlPC9jb2RlPgotICAgICAqIGFuZCB2YWx1ZSA8Y29kZT50cnVlPC9jb2RlPiAoeHNpOm5pbCkgZXZlbiBpZiBpdCBoYXMgbm8gdGV4dCBvcgotICAgICAqIGVsZW1lbnQgY29udGVudCBkZXNwaXRlIGEgPGNvZGU+Y29udGVudCB0eXBlPC9jb2RlPiB3aGljaCB3b3VsZAotICAgICAqIG90aGVyd2lzZSByZXF1aXJlIGNvbnRlbnQuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0TmlsbGFibGUoKTsKLQotICAgIC8qKgotICAgICAqIGlkZW50aXR5LWNvbnN0cmFpbnQgZGVmaW5pdGlvbnM6IGEgc2V0IG9mIGNvbnN0cmFpbnQgZGVmaW5pdGlvbnMgaWYgaXQKLSAgICAgKiBleGlzdHMsIG90aGVyd2lzZSBhbiBlbXB0eSA8Y29kZT5YU05hbWVkTWFwPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFNOYW1lZE1hcCBnZXRJZGVudGl0eUNvbnN0cmFpbnRzKCk7Ci0KLSAgICAvKioKLSAgICAgKiBbc3Vic3RpdHV0aW9uIGdyb3VwIGFmZmlsaWF0aW9uXTogYSB0b3AtbGV2ZWwgZWxlbWVudCBkZWZpbml0aW9uIGlmIGl0Ci0gICAgICogZXhpc3RzLCBvdGhlcndpc2UgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIFhTRWxlbWVudERlY2xhcmF0aW9uIGdldFN1YnN0aXR1dGlvbkdyb3VwQWZmaWxpYXRpb24oKTsKLQotICAgIC8qKgotICAgICAqIENvbnZlbmllbmNlIG1ldGhvZCB0aGF0IGNoZWNrcyBpZiA8Y29kZT5leGNsdXNpb248L2NvZGU+IGlzIGEKLSAgICAgKiBzdWJzdGl0dXRpb24gZ3JvdXAgZXhjbHVzaW9uIGZvciB0aGlzIGVsZW1lbnQgZGVjbGFyYXRpb24uCi0gICAgICogQHBhcmFtIGV4Y2x1c2lvbgotICAgICAqICAgPGNvZGU+REVSSVZBVElPTl9FWFRFTlNJT04sIERFUklWQVRJT05fUkVTVFJJQ1RJT048L2NvZGU+IG9yCi0gICAgICogICA8Y29kZT5ERVJJVkFUSU9OX05PTkU8L2NvZGU+LiBSZXByZXNlbnRzIGZpbmFsIHNldCBmb3IgdGhlIGVsZW1lbnQuCi0gICAgICogQHJldHVybiBUcnVlIGlmIDxjb2RlPmV4Y2x1c2lvbjwvY29kZT4gaXMgYSBwYXJ0IG9mIHRoZSBzdWJzdGl0dXRpb24KLSAgICAgKiAgIGdyb3VwIGV4Y2x1c2lvbiBzdWJzZXQuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNTdWJzdGl0dXRpb25Hcm91cEV4Y2x1c2lvbihzaG9ydCBleGNsdXNpb24pOwotCi0gICAgLyoqCi0gICAgICogIFtzdWJzdGl0dXRpb24gZ3JvdXAgZXhjbHVzaW9uc106IHRoZSByZXR1cm5lZCB2YWx1ZSBpcyBhIGJpdAotICAgICAqIGNvbWJpbmF0aW9uIG9mIHRoZSBzdWJzZXQgb2YgewotICAgICAqIDxjb2RlPkRFUklWQVRJT05fRVhURU5TSU9OLCBERVJJVkFUSU9OX1JFU1RSSUNUSU9OPC9jb2RlPn0gb3IKLSAgICAgKiA8Y29kZT5ERVJJVkFUSU9OX05PTkU8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBzaG9ydCBnZXRTdWJzdGl0dXRpb25Hcm91cEV4Y2x1c2lvbnMoKTsKLQotICAgIC8qKgotICAgICAqIENvbnZlbmllbmNlIG1ldGhvZCB0aGF0IGNoZWNrcyBpZiA8Y29kZT5kaXNhbGxvd2VkPC9jb2RlPiBpcyBhCi0gICAgICogZGlzYWxsb3dlZCBzdWJzdGl0dXRpb24gZm9yIHRoaXMgZWxlbWVudCBkZWNsYXJhdGlvbi4KLSAgICAgKiBAcGFyYW0gZGlzYWxsb3dlZCB7Ci0gICAgICogICA8Y29kZT5ERVJJVkFUSU9OX1NVQlNUSVRVVElPTiwgREVSSVZBVElPTl9FWFRFTlNJT04sIERFUklWQVRJT05fUkVTVFJJQ1RJT048L2NvZGU+Ci0gICAgICogICB9IG9yIDxjb2RlPkRFUklWQVRJT05fTk9ORTwvY29kZT4uIFJlcHJlc2VudHMgYSBibG9jayBzZXQgZm9yIHRoZQotICAgICAqICAgZWxlbWVudC4KLSAgICAgKiBAcmV0dXJuIFRydWUgaWYgPGNvZGU+ZGlzYWxsb3dlZDwvY29kZT4gaXMgYSBwYXJ0IG9mIHRoZSBzdWJzdGl0dXRpb24KLSAgICAgKiAgIGdyb3VwIGV4Y2x1c2lvbiBzdWJzZXQuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNEaXNhbGxvd2VkU3Vic3RpdHV0aW9uKHNob3J0IGRpc2FsbG93ZWQpOwotCi0gICAgLyoqCi0gICAgICogIFtkaXNhbGxvd2VkIHN1YnN0aXR1dGlvbnNdOiB0aGUgcmV0dXJuZWQgdmFsdWUgaXMgYSBiaXQgY29tYmluYXRpb24gb2YKLSAgICAgKiB0aGUgc3Vic2V0IG9mIHsKLSAgICAgKiA8Y29kZT5ERVJJVkFUSU9OX1NVQlNUSVRVVElPTiwgREVSSVZBVElPTl9FWFRFTlNJT04sIERFUklWQVRJT05fUkVTVFJJQ1RJT048L2NvZGU+Ci0gICAgICogfSBjb3JyZXNwb25kaW5nIHRvIHN1YnN0aXR1dGlvbnMgZGlzYWxsb3dlZCBieSB0aGlzCi0gICAgICogPGNvZGU+WFNFbGVtZW50RGVjbGFyYXRpb248L2NvZGU+IG9yIDxjb2RlPkRFUklWQVRJT05fTk9ORTwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIHNob3J0IGdldERpc2FsbG93ZWRTdWJzdGl0dXRpb25zKCk7Ci0KLSAgICAvKioKLSAgICAgKiB7YWJzdHJhY3R9IEEgYm9vbGVhbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXRBYnN0cmFjdCgpOwotCi0gICAgLyoqCi0gICAgICogQW4gYW5ub3RhdGlvbiBpZiBpdCBleGlzdHMsIG90aGVyd2lzZSA8Y29kZT5udWxsPC9jb2RlPi4gSWYgbm90IG51bGwKLSAgICAgKiB0aGVuIHRoZSBmaXJzdCBbYW5ub3RhdGlvbl0gZnJvbSB0aGUgc2VxdWVuY2Ugb2YgYW5ub3RhdGlvbnMuCi0gICAgICovCi0gICAgcHVibGljIFhTQW5ub3RhdGlvbiBnZXRBbm5vdGF0aW9uKCk7Ci0KLSAgICAvKioKLSAgICAgKiBBIHNlcXVlbmNlIG9mIFthbm5vdGF0aW9uc10gb3IgYW4gZW1wdHkgPGNvZGU+WFNPYmplY3RMaXN0PC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFNPYmplY3RMaXN0IGdldEFubm90YXRpb25zKCk7Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94cy9YU0V4Y2VwdGlvbi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHMvWFNFeGNlcHRpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZDA5MTgyNS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94cy9YU0V4Y2VwdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTYgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMywyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzOwotCi0vKioKLSAqIFRoZSBYTUwgU2NoZW1hIEFQSSBvcGVyYXRpb25zIG9ubHkgcmFpc2UgZXhjZXB0aW9ucyBpbiAiZXhjZXB0aW9uYWwiCi0gKiBjaXJjdW1zdGFuY2VzLCBpLmUuLCB3aGVuIGFuIG9wZXJhdGlvbiBpcyBpbXBvc3NpYmxlIHRvIHBlcmZvcm0gKGVpdGhlcgotICogZm9yIGxvZ2ljYWwgcmVhc29ucywgYmVjYXVzZSBkYXRhIGlzIGxvc3QsIG9yIGJlY2F1c2UgdGhlIGltcGxlbWVudGF0aW9uCi0gKiBoYXMgYmVjb21lIHVuc3RhYmxlKS4KLSAqIDxwPkltcGxlbWVudGF0aW9ucyBzaG91bGQgcmFpc2Ugb3RoZXIgZXhjZXB0aW9ucyB1bmRlciBvdGhlciBjaXJjdW1zdGFuY2VzLgotICogPHA+U29tZSBsYW5ndWFnZXMgYW5kIG9iamVjdCBzeXN0ZW1zIGRvIG5vdCBzdXBwb3J0IHRoZSBjb25jZXB0IG9mCi0gKiBleGNlcHRpb25zLiBGb3Igc3VjaCBzeXN0ZW1zLCBlcnJvciBjb25kaXRpb25zIG1heSBiZSBpbmRpY2F0ZWQgdXNpbmcKLSAqIG5hdGl2ZSBlcnJvciByZXBvcnRpbmcgbWVjaGFuaXNtcy4gRm9yIHNvbWUgYmluZGluZ3MsIGZvciBleGFtcGxlLAotICogbWV0aG9kcyBtYXkgcmV0dXJuIGVycm9yIGNvZGVzIHNpbWlsYXIgdG8gdGhvc2UgbGlzdGVkIGluIHRoZQotICogY29ycmVzcG9uZGluZyBtZXRob2QgZGVzY3JpcHRpb25zLgotICovCi1wdWJsaWMgY2xhc3MgWFNFeGNlcHRpb24gZXh0ZW5kcyBSdW50aW1lRXhjZXB0aW9uIHsKLQotICAgIC8qKiBTZXJpYWxpemF0aW9uIHZlcnNpb24uICovCi0gICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDMxMTE4OTMwODQ2Nzc5MTc3NDJMOwotCi0gICAgcHVibGljIFhTRXhjZXB0aW9uKHNob3J0IGNvZGUsIFN0cmluZyBtZXNzYWdlKSB7Ci0gICAgICAgc3VwZXIobWVzc2FnZSk7Ci0gICAgICAgdGhpcy5jb2RlID0gY29kZTsKLSAgICB9Ci0gICAgcHVibGljIHNob3J0ICAgY29kZTsKLSAgICAvLyBFeGNlcHRpb25Db2RlCi0gICAgLyoqCi0gICAgICogSWYgdGhlIGltcGxlbWVudGF0aW9uIGRvZXMgbm90IHN1cHBvcnQgdGhlIHJlcXVlc3RlZCB0eXBlIG9mIG9iamVjdCBvcgotICAgICAqIG9wZXJhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IE5PVF9TVVBQT1JURURfRVJSICAgICAgICAgPSAxOwotICAgIC8qKgotICAgICAqIElmIGluZGV4IG9yIHNpemUgaXMgbmVnYXRpdmUsIG9yIGdyZWF0ZXIgdGhhbiB0aGUgYWxsb3dlZCB2YWx1ZQotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgSU5ERVhfU0laRV9FUlIgICAgICAgICAgICA9IDI7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3hzL1hTRmFjZXQuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3hzL1hTRmFjZXQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMmJlZjAyNi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94cy9YU0ZhY2V0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw1NCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAzLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHM7Ci0KLS8qKgotICogRGVzY3JpYmVzIGEgY29uc3RyYWluaW5nIGZhY2V0LiBFbnVtZXJhdGlvbiBhbmQgcGF0dGVybiBmYWNldHMgYXJlIGV4cG9zZWQKLSAqIHZpYSA8Y29kZT5YU011bHRpVmFsdWVGYWNldDwvY29kZT4gaW50ZXJmYWNlLgotICovCi1wdWJsaWMgaW50ZXJmYWNlIFhTRmFjZXQgZXh0ZW5kcyBYU09iamVjdCB7Ci0gICAgLyoqCi0gICAgICogVGhlIG5hbWUgb2YgdGhlIGZhY2V0LCBlLmcuIDxjb2RlPkZBQ0VUX0xFTkdUSCwgRkFDRVRfVE9UQUxESUdJVFM8L2NvZGU+Ci0gICAgICogIChzZWUgPGNvZGU+WFNTaW1wbGVUeXBlRGVmaW5pdGlvbjwvY29kZT4pLgotICAgICAqLwotICAgIHB1YmxpYyBzaG9ydCBnZXRGYWNldEtpbmQoKTsKLQotICAgIC8qKgotICAgICAqIEEgdmFsdWUgb2YgdGhpcyBmYWNldC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldExleGljYWxGYWNldFZhbHVlKCk7Ci0KLSAgICAvKioKLSAgICAgKiBbRmFjZXRzXTogY2hlY2sgd2hldGhlciBhIGZhY2V0IGlzIGZpeGVkLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGdldEZpeGVkKCk7Ci0KLSAgICAvKioKLSAgICAgKiBBbiBhbm5vdGF0aW9uIGlmIGl0IGV4aXN0cywgb3RoZXJ3aXNlIDxjb2RlPm51bGw8L2NvZGU+LiBJZiBub3QgbnVsbAotICAgICAqIHRoZW4gdGhlIGZpcnN0IFthbm5vdGF0aW9uXSBmcm9tIHRoZSBzZXF1ZW5jZSBvZiBhbm5vdGF0aW9ucy4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFNBbm5vdGF0aW9uIGdldEFubm90YXRpb24oKTsKLQotICAgIC8qKgotICAgICAqIEEgc2VxdWVuY2Ugb2YgW2Fubm90YXRpb25zXSBvciBhbiBlbXB0eSA8Y29kZT5YU09iamVjdExpc3Q8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBYU09iamVjdExpc3QgZ2V0QW5ub3RhdGlvbnMoKTsKLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3hzL1hTSURDRGVmaW5pdGlvbi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHMvWFNJRENEZWZpbml0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGMyNmNlYzcuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHMvWFNJRENEZWZpbml0aW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3MiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAzLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHM7Ci0KLS8qKgotICogVGhpcyBpbnRlcmZhY2UgcmVwcmVzZW50cyB0aGUgSWRlbnRpdHktY29uc3RyYWludCBEZWZpbml0aW9uIHNjaGVtYQotICogY29tcG9uZW50LgotICovCi1wdWJsaWMgaW50ZXJmYWNlIFhTSURDRGVmaW5pdGlvbiBleHRlbmRzIFhTT2JqZWN0IHsKLSAgICAvLyBJZGVudGl0eSBDb25zdHJhaW50cwotICAgIC8qKgotICAgICAqIFNlZSB0aGUgZGVmaW5pdGlvbiBvZiA8Y29kZT5rZXk8L2NvZGU+IGluIHRoZSBpZGVudGl0eS1jb25zdHJhaW50Ci0gICAgICogY2F0ZWdvcnkuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBJQ19LRVkgICAgICAgICAgICAgICAgICAgID0gMTsKLSAgICAvKioKLSAgICAgKiBTZWUgdGhlIGRlZmluaXRpb24gb2YgPGNvZGU+a2V5cmVmPC9jb2RlPiBpbiB0aGUgaWRlbnRpdHktY29uc3RyYWludAotICAgICAqIGNhdGVnb3J5LgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgSUNfS0VZUkVGICAgICAgICAgICAgICAgICA9IDI7Ci0gICAgLyoqCi0gICAgICogU2VlIHRoZSBkZWZpbml0aW9uIG9mIDxjb2RlPnVuaXF1ZTwvY29kZT4gaW4gdGhlIGlkZW50aXR5LWNvbnN0cmFpbnQKLSAgICAgKiBjYXRlZ29yeS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IElDX1VOSVFVRSAgICAgICAgICAgICAgICAgPSAzOwotCi0gICAgLyoqCi0gICAgICogW2lkZW50aXR5LWNvbnN0cmFpbnQgY2F0ZWdvcnldOiBvbmUgb2Yga2V5LCBrZXlyZWYgb3IgdW5pcXVlLgotICAgICAqLwotICAgIHB1YmxpYyBzaG9ydCBnZXRDYXRlZ29yeSgpOwotCi0gICAgLyoqCi0gICAgICogW3NlbGVjdG9yXTogYSByZXN0cmljdGVkIFhQYXRoIDEuMCBleHByZXNzaW9uLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0U2VsZWN0b3JTdHIoKTsKLQotICAgIC8qKgotICAgICAqIFtmaWVsZHNdOiBhIG5vbi1lbXB0eSBsaXN0IG9mIHJlc3RyaWN0ZWQgIFhQYXRoIDEuMCBleHByZXNzaW9ucy4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nTGlzdCBnZXRGaWVsZFN0cnMoKTsKLQotICAgIC8qKgotICAgICAqIFtyZWZlcmVuY2VkIGtleV06IHJlcXVpcmVkIGlmIFtpZGVudGl0eS1jb25zdHJhaW50IGNhdGVnb3J5XSBpcyBrZXlyZWYsCi0gICAgICogPGNvZGU+bnVsbDwvY29kZT4gb3RoZXJ3aXNlLiBBbiBpZGVudGl0eS1jb25zdHJhaW50IGRlZmluaXRpb24gd2l0aCBbCi0gICAgICogaWRlbnRpdHktY29uc3RyYWludCBjYXRlZ29yeV0gZXF1YWwgdG8ga2V5IG9yIHVuaXF1ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFNJRENEZWZpbml0aW9uIGdldFJlZktleSgpOwotCi0gICAgLyoqCi0gICAgICogQSBzZXF1ZW5jZSBvZiBbYW5ub3RhdGlvbnNdIG9yIGFuIGVtcHR5ICA8Y29kZT5YU09iamVjdExpc3Q8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBYU09iamVjdExpc3QgZ2V0QW5ub3RhdGlvbnMoKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHMvWFNJbXBsZW1lbnRhdGlvbi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHMvWFNJbXBsZW1lbnRhdGlvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyZDdhMzdmLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3hzL1hTSW1wbGVtZW50YXRpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDUxICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDMsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54czsKLQotLyoqCi0gKiBUaGlzIGludGVyZmFjZSBhbGxvd3Mgb25lIHRvIHJldHJpZXZlIGFuIGluc3RhbmNlIG9mIDxjb2RlPlhTTG9hZGVyPC9jb2RlPi4KLSAqIFRoaXMgaW50ZXJmYWNlIHNob3VsZCBiZSBpbXBsZW1lbnRlZCBvbiB0aGUgc2FtZSBvYmplY3QgdGhhdCBpbXBsZW1lbnRzCi0gKiBET01JbXBsZW1lbnRhdGlvbi4KLSAqLwotcHVibGljIGludGVyZmFjZSBYU0ltcGxlbWVudGF0aW9uIHsKLSAgICAvKioKLSAgICAgKiBBIGxpc3QgY29udGFpbmluZyB0aGUgdmVyc2lvbnMgb2YgWE1MIFNjaGVtYSBkb2N1bWVudHMgcmVjb2duaXplZCBieQotICAgICAqIHRoaXMgPGNvZGU+WFNJbXBsZW1lbmF0aW9uPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nTGlzdCBnZXRSZWNvZ25pemVkVmVyc2lvbnMoKTsKLQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlcyBhIG5ldyBYU0xvYWRlci4gVGhlIG5ld2x5IGNvbnN0cnVjdGVkIGxvYWRlciBtYXkgdGhlbiBiZQotICAgICAqIGNvbmZpZ3VyZWQgYW5kIHVzZWQgdG8gbG9hZCBYTUwgU2NoZW1hcy4KLSAgICAgKiBAcGFyYW0gdmVyc2lvbnMgIEEgbGlzdCBjb250YWluaW5nIHRoZSB2ZXJzaW9ucyBvZiBYTUwgU2NoZW1hCi0gICAgICogICBkb2N1bWVudHMgd2hpY2ggY2FuIGJlIGxvYWRlZCBieSB0aGUgPGNvZGU+WFNMb2FkZXI8L2NvZGU+IG9yCi0gICAgICogICA8Y29kZT5udWxsPC9jb2RlPiB0byBwZXJtaXQgWE1MIFNjaGVtYSBkb2N1bWVudHMgb2YgYW55IHJlY29nbml6ZWQKLSAgICAgKiAgIHZlcnNpb24gdG8gYmUgbG9hZGVkIGJ5IHRoZSBYU0xvYWRlci4KLSAgICAgKiBAcmV0dXJuICBBbiBYTUwgU2NoZW1hIGxvYWRlci4KLSAgICAgKiBAZXhjZXB0aW9uIFhTRXhjZXB0aW9uCi0gICAgICogICBOT1RfU1VQUE9SVEVEX0VSUjogUmFpc2VkIGlmIHRoZSBpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdCBzdXBwb3J0IG9uZQotICAgICAqICAgb2YgdGhlIHNwZWNpZmllZCB2ZXJzaW9ucy4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFNMb2FkZXIgY3JlYXRlWFNMb2FkZXIoU3RyaW5nTGlzdCB2ZXJzaW9ucykKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIFhTRXhjZXB0aW9uOwotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94cy9YU0xvYWRlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHMvWFNMb2FkZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYWFiZjk1Zi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94cy9YU0xvYWRlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTMgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMywyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzOwotCi1pbXBvcnQgb3JnLnczYy5kb20uRE9NQ29uZmlndXJhdGlvbjsKLWltcG9ydCBvcmcudzNjLmRvbS5scy5MU0lucHV0OwotCi0vKioKLSAqIEFuIGludGVyZmFjZSB0aGF0IHByb3ZpZGVzIGEgbWV0aG9kIHRvIGxvYWQgWE1MIFNjaGVtYSBkb2N1bWVudHMuIFRoaXMKLSAqIGludGVyZmFjZSB1c2VzIHRoZSBET00gTGV2ZWwgMyBDb3JlIGFuZCBMb2FkIGFuZCBTYXZlIGludGVyZmFjZXMuCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgWFNMb2FkZXIgewotICAgIC8qKgotICAgICAqICBUaGUgY29uZmlndXJhdGlvbiBvZiBhIGRvY3VtZW50LiBJdCBtYWludGFpbnMgYSB0YWJsZSBvZiByZWNvZ25pemVkCi0gICAgICogcGFyYW1ldGVycy4gVXNpbmcgdGhlIGNvbmZpZ3VyYXRpb24sIGl0IGlzIHBvc3NpYmxlIHRvIGNoYW5nZSB0aGUKLSAgICAgKiBiZWhhdmlvciBvZiB0aGUgbG9hZCBtZXRob2RzLiBUaGUgY29uZmlndXJhdGlvbiBtYXkgc3VwcG9ydCB0aGUKLSAgICAgKiBzZXR0aW5nIG9mIGFuZCB0aGUgcmV0cmlldmFsIG9mIHRoZSBmb2xsb3dpbmcgbm9uLWJvb2xlYW4gcGFyYW1ldGVycwotICAgICAqIGRlZmluZWQgb24gdGhlIDxjb2RlPkRPTUNvbmZpZ3VyYXRpb248L2NvZGU+IGludGVyZmFjZToKLSAgICAgKiA8Y29kZT5lcnJvci1oYW5kbGVyPC9jb2RlPiAoPGNvZGU+RE9NRXJyb3JIYW5kbGVyPC9jb2RlPikgYW5kCi0gICAgICogPGNvZGU+cmVzb3VyY2UtcmVzb2x2ZXI8L2NvZGU+ICg8Y29kZT5MU1Jlc291cmNlUmVzb2x2ZXI8L2NvZGU+KS4KLSAgICAgKiA8YnI+IFRoZSBmb2xsb3dpbmcgbGlzdCBvZiBib29sZWFuIHBhcmFtZXRlcnMgaXMgZGVmaW5lZDoKLSAgICAgKiA8ZGw+Ci0gICAgICogPGR0PgotICAgICAqIDxjb2RlPiJ2YWxpZGF0ZSI8L2NvZGU+PC9kdD4KLSAgICAgKiA8ZGQ+Ci0gICAgICogPGRsPgotICAgICAqIDxkdD48Y29kZT50cnVlPC9jb2RlPjwvZHQ+Ci0gICAgICogPGRkPltyZXF1aXJlZF0gKGRlZmF1bHQpIFZhbGlkYXRlIGFuIFhNTAotICAgICAqIFNjaGVtYSBkdXJpbmcgbG9hZGluZy4gSWYgdmFsaWRhdGlvbiBlcnJvcnMgYXJlIGZvdW5kLCB0aGUgZXJyb3IKLSAgICAgKiBoYW5kbGVyIGlzIG5vdGlmaWVkLiA8L2RkPgotICAgICAqIDxkdD48Y29kZT5mYWxzZTwvY29kZT48L2R0PgotICAgICAqIDxkZD5bb3B0aW9uYWxdIERvIG5vdAotICAgICAqIHJlcG9ydCBlcnJvcnMgZHVyaW5nIHRoZSBsb2FkaW5nIG9mIGFuIFhNTCBTY2hlbWEgZG9jdW1lbnQuIDwvZGQ+Ci0gICAgICogPC9kbD48L2RkPgotICAgICAqIDwvZGw+Ci0gICAgICovCi0gICAgcHVibGljIERPTUNvbmZpZ3VyYXRpb24gZ2V0Q29uZmlnKCk7Ci0KLSAgICAvKioKLSAgICAgKiBQYXJzZXMgdGhlIGNvbnRlbnQgb2YgWE1MIFNjaGVtYSBkb2N1bWVudHMgc3BlY2lmaWVkIGFzIHRoZSBsaXN0IG9mIFVSSQotICAgICAqIHJlZmVyZW5jZXMuIElmIHRoZSBVUkkgY29udGFpbnMgYSBmcmFnbWVudCBpZGVudGlmaWVyLCB0aGUgYmVoYXZpb3IKLSAgICAgKiBpcyBub3QgZGVmaW5lZCBieSB0aGlzIHNwZWNpZmljYXRpb24uCi0gICAgICogQHBhcmFtIHVyaUxpc3QgVGhlIGxpc3Qgb2YgVVJJIGxvY2F0aW9ucy4KLSAgICAgKiBAcmV0dXJuIEFuIFhTTW9kZWwgcmVwcmVzZW50aW5nIHRoZSBzY2hlbWEgZG9jdW1lbnRzLgotICAgICAqLwotICAgIHB1YmxpYyBYU01vZGVsIGxvYWRVUklMaXN0KFN0cmluZ0xpc3QgdXJpTGlzdCk7Ci0KLSAgICAvKioKLSAgICAgKiAgUGFyc2VzIHRoZSBjb250ZW50IG9mIFhNTCBTY2hlbWEgZG9jdW1lbnRzIHNwZWNpZmllZCBhcyBhIGxpc3Qgb2YKLSAgICAgKiA8Y29kZT5MU0lucHV0PC9jb2RlPnMuCi0gICAgICogQHBhcmFtIGlzICBUaGUgbGlzdCBvZiA8Y29kZT5MU0lucHV0PC9jb2RlPnMgZnJvbSB3aGljaCB0aGUgWE1MCi0gICAgICogICBTY2hlbWEgZG9jdW1lbnRzIGFyZSB0byBiZSByZWFkLgotICAgICAqIEByZXR1cm4gQW4gWFNNb2RlbCByZXByZXNlbnRpbmcgdGhlIHNjaGVtYSBkb2N1bWVudHMuCi0gICAgICovCi0gICAgcHVibGljIFhTTW9kZWwgbG9hZElucHV0TGlzdChMU0lucHV0TGlzdCBpcyk7Ci0KLSAgICAvKioKLSAgICAgKiBQYXJzZSBhbiBYTUwgU2NoZW1hIGRvY3VtZW50IGZyb20gYSBsb2NhdGlvbiBpZGVudGlmaWVkIGJ5IGEgVVJJCi0gICAgICogcmVmZXJlbmNlLiBJZiB0aGUgVVJJIGNvbnRhaW5zIGEgZnJhZ21lbnQgaWRlbnRpZmllciwgdGhlIGJlaGF2aW9yIGlzCi0gICAgICogbm90IGRlZmluZWQgYnkgdGhpcyBzcGVjaWZpY2F0aW9uLgotICAgICAqIEBwYXJhbSB1cmkgVGhlIGxvY2F0aW9uIG9mIHRoZSBYTUwgU2NoZW1hIGRvY3VtZW50IHRvIGJlIHJlYWQuCi0gICAgICogQHJldHVybiBBbiBYU01vZGVsIHJlcHJlc2VudGluZyB0aGlzIHNjaGVtYS4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFNNb2RlbCBsb2FkVVJJKFN0cmluZyB1cmkpOwotCi0gICAgLyoqCi0gICAgICogIFBhcnNlIGFuIFhNTCBTY2hlbWEgZG9jdW1lbnQgZnJvbSBhIHJlc291cmNlIGlkZW50aWZpZWQgYnkgYQotICAgICAqIDxjb2RlPkxTSW5wdXQ8L2NvZGU+IC4KLSAgICAgKiBAcGFyYW0gaXMgIFRoZSA8Y29kZT5MU0lucHV0PC9jb2RlPiBmcm9tIHdoaWNoIHRoZSBzb3VyY2UKLSAgICAgKiAgIGRvY3VtZW50IGlzIHRvIGJlIHJlYWQuCi0gICAgICogQHJldHVybiBBbiBYU01vZGVsIHJlcHJlc2VudGluZyB0aGlzIHNjaGVtYS4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFNNb2RlbCBsb2FkKExTSW5wdXQgaXMpOwotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94cy9YU01vZGVsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94cy9YU01vZGVsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDk2YTcwYWUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHMvWFNNb2RlbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTYxICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDMsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54czsKLQotLyoqCi0gKiBUaGlzIGludGVyZmFjZSByZXByZXNlbnRzIGFuIFhNTCBTY2hlbWEuCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgWFNNb2RlbCB7Ci0gICAgLyoqCi0gICAgICogQ29udmVuaWVuY2UgbWV0aG9kLiBSZXR1cm5zIGEgbGlzdCBvZiBhbGwgbmFtZXNwYWNlcyB0aGF0IGJlbG9uZyB0bwotICAgICAqIHRoaXMgc2NoZW1hLiBUaGUgdmFsdWUgPGNvZGU+bnVsbDwvY29kZT4gaXMgbm90IGEgdmFsaWQgbmFtZXNwYWNlCi0gICAgICogbmFtZSwgYnV0IGlmIHRoZXJlIGFyZSBjb21wb25lbnRzIHRoYXQgZG8gbm90IGhhdmUgYSB0YXJnZXQgbmFtZXNwYWNlCi0gICAgICogLCA8Y29kZT5udWxsPC9jb2RlPiBpcyBpbmNsdWRlZCBpbiB0aGlzIGxpc3QuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZ0xpc3QgZ2V0TmFtZXNwYWNlcygpOwotCi0gICAgLyoqCi0gICAgICogQSBzZXQgb2YgbmFtZXNwYWNlIHNjaGVtYSBpbmZvcm1hdGlvbiBpbmZvcm1hdGlvbiBpdGVtcyAob2YgdHlwZQotICAgICAqIDxjb2RlPlhTTmFtZXNwYWNlSXRlbTwvY29kZT4pLCBvbmUgZm9yIGVhY2ggbmFtZXNwYWNlIG5hbWUgd2hpY2gKLSAgICAgKiBhcHBlYXJzIGFzIHRoZSB0YXJnZXQgbmFtZXNwYWNlIG9mIGFueSBzY2hlbWEgY29tcG9uZW50IGluIHRoZSBzY2hlbWEKLSAgICAgKiB1c2VkIGZvciB0aGF0IGFzc2Vzc21lbnQsIGFuZCBvbmUgZm9yIGFic2VudCBpZiBhbnkgc2NoZW1hIGNvbXBvbmVudAotICAgICAqIGluIHRoZSBzY2hlbWEgaGFkIG5vIHRhcmdldCBuYW1lc3BhY2UuIEZvciBtb3JlIGluZm9ybWF0aW9uIHNlZQotICAgICAqIHNjaGVtYSBpbmZvcm1hdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFNOYW1lc3BhY2VJdGVtTGlzdCBnZXROYW1lc3BhY2VJdGVtcygpOwotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhIGxpc3Qgb2YgdG9wLWxldmVsIGNvbXBvbmVudHMsIGkuZS4gZWxlbWVudCBkZWNsYXJhdGlvbnMsCi0gICAgICogYXR0cmlidXRlIGRlY2xhcmF0aW9ucywgZXRjLgotICAgICAqIEBwYXJhbSBvYmplY3RUeXBlIFRoZSB0eXBlIG9mIHRoZSBkZWNsYXJhdGlvbiwgaS5lLgotICAgICAqICAgPGNvZGU+RUxFTUVOVF9ERUNMQVJBVElPTjwvY29kZT4uIE5vdGUgdGhhdAotICAgICAqICAgPGNvZGU+WFNUeXBlRGVmaW5pdGlvbi5TSU1QTEVfVFlQRTwvY29kZT4gYW5kCi0gICAgICogICA8Y29kZT5YU1R5cGVEZWZpbml0aW9uLkNPTVBMRVhfVFlQRTwvY29kZT4gY2FuIGFsc28gYmUgdXNlZCBhcyB0aGUKLSAgICAgKiAgIDxjb2RlPm9iamVjdFR5cGU8L2NvZGU+IHRvIHJldHJpZXZlIG9ubHkgY29tcGxleCB0eXBlcyBvciBzaW1wbGUKLSAgICAgKiAgIHR5cGVzLCBpbnN0ZWFkIG9mIGFsbCB0eXBlcy4KLSAgICAgKiBAcmV0dXJuICBBIGxpc3Qgb2YgdG9wLWxldmVsIGRlZmluaXRpb25zIG9mIHRoZSBzcGVjaWZpZWQgdHlwZSBpbgotICAgICAqICAgPGNvZGU+b2JqZWN0VHlwZTwvY29kZT4gb3IgYW4gZW1wdHkgPGNvZGU+WFNOYW1lZE1hcDwvY29kZT4gaWYgbm8KLSAgICAgKiAgIHN1Y2ggZGVmaW5pdGlvbnMgZXhpc3QuCi0gICAgICovCi0gICAgcHVibGljIFhTTmFtZWRNYXAgZ2V0Q29tcG9uZW50cyhzaG9ydCBvYmplY3RUeXBlKTsKLQotICAgIC8qKgotICAgICAqIENvbnZlbmllbmNlIG1ldGhvZC4gUmV0dXJucyBhIGxpc3Qgb2YgdG9wLWxldmVsIGNvbXBvbmVudCBkZWNsYXJhdGlvbnMKLSAgICAgKiB0aGF0IGFyZSBkZWZpbmVkIHdpdGhpbiB0aGUgc3BlY2lmaWVkIG5hbWVzcGFjZSwgaS5lLiBlbGVtZW50Ci0gICAgICogZGVjbGFyYXRpb25zLCBhdHRyaWJ1dGUgZGVjbGFyYXRpb25zLCBldGMuCi0gICAgICogQHBhcmFtIG9iamVjdFR5cGUgVGhlIHR5cGUgb2YgdGhlIGRlY2xhcmF0aW9uLCBpLmUuCi0gICAgICogICA8Y29kZT5FTEVNRU5UX0RFQ0xBUkFUSU9OPC9jb2RlPi4KLSAgICAgKiBAcGFyYW0gbmFtZXNwYWNlIFRoZSBuYW1lc3BhY2UgdG8gd2hpY2ggdGhlIGRlY2xhcmF0aW9uIGJlbG9uZ3Mgb3IKLSAgICAgKiAgIDxjb2RlPm51bGw8L2NvZGU+IChmb3IgY29tcG9uZW50cyB3aXRoIG5vIHRhcmdldCBuYW1lc3BhY2UpLgotICAgICAqIEByZXR1cm4gIEEgbGlzdCBvZiB0b3AtbGV2ZWwgZGVmaW5pdGlvbnMgb2YgdGhlIHNwZWNpZmllZCB0eXBlIGluCi0gICAgICogICA8Y29kZT5vYmplY3RUeXBlPC9jb2RlPiBhbmQgZGVmaW5lZCBpbiB0aGUgc3BlY2lmaWVkCi0gICAgICogICA8Y29kZT5uYW1lc3BhY2U8L2NvZGU+IG9yIGFuIGVtcHR5IDxjb2RlPlhTTmFtZWRNYXA8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBYU05hbWVkTWFwIGdldENvbXBvbmVudHNCeU5hbWVzcGFjZShzaG9ydCBvYmplY3RUeXBlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbmFtZXNwYWNlKTsKLQotICAgIC8qKgotICAgICAqICBbYW5ub3RhdGlvbnNdOiBhIHNldCBvZiBhbm5vdGF0aW9ucyBpZiBpdCBleGlzdHMsIG90aGVyd2lzZSBhbiBlbXB0eQotICAgICAqIDxjb2RlPlhTT2JqZWN0TGlzdDwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIFhTT2JqZWN0TGlzdCBnZXRBbm5vdGF0aW9ucygpOwotCi0gICAgLyoqCi0gICAgICogQ29udmVuaWVuY2UgbWV0aG9kLiBSZXR1cm5zIGEgdG9wLWxldmVsIGVsZW1lbnQgZGVjbGFyYXRpb24uCi0gICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGRlY2xhcmF0aW9uLgotICAgICAqIEBwYXJhbSBuYW1lc3BhY2UgVGhlIG5hbWVzcGFjZSBvZiB0aGUgZGVjbGFyYXRpb24sIG90aGVyd2lzZQotICAgICAqICAgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICogQHJldHVybiBBIHRvcC1sZXZlbCBlbGVtZW50IGRlY2xhcmF0aW9uIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIHN1Y2ggYQotICAgICAqICAgZGVjbGFyYXRpb24gZG9lcyBub3QgZXhpc3QuCi0gICAgICovCi0gICAgcHVibGljIFhTRWxlbWVudERlY2xhcmF0aW9uIGdldEVsZW1lbnREZWNsYXJhdGlvbihTdHJpbmcgbmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBuYW1lc3BhY2UpOwotCi0gICAgLyoqCi0gICAgICogQ29udmVuaWVuY2UgbWV0aG9kLiBSZXR1cm5zIGEgdG9wLWxldmVsIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbi4KLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgZGVjbGFyYXRpb24uCi0gICAgICogQHBhcmFtIG5hbWVzcGFjZSBUaGUgbmFtZXNwYWNlIG9mIHRoZSBkZWNsYXJhdGlvbiwgb3RoZXJ3aXNlCi0gICAgICogICA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICAgKiBAcmV0dXJuIEEgdG9wLWxldmVsIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbiBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiBzdWNoCi0gICAgICogICBhIGRlY2xhcmF0aW9uIGRvZXMgbm90IGV4aXN0LgotICAgICAqLwotICAgIHB1YmxpYyBYU0F0dHJpYnV0ZURlY2xhcmF0aW9uIGdldEF0dHJpYnV0ZURlY2xhcmF0aW9uKFN0cmluZyBuYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBuYW1lc3BhY2UpOwotCi0gICAgLyoqCi0gICAgICogQ29udmVuaWVuY2UgbWV0aG9kLiBSZXR1cm5zIGEgdG9wLWxldmVsIHNpbXBsZSBvciBjb21wbGV4IHR5cGUKLSAgICAgKiBkZWZpbml0aW9uLgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBkZWZpbml0aW9uLgotICAgICAqIEBwYXJhbSBuYW1lc3BhY2UgVGhlIG5hbWVzcGFjZSBvZiB0aGUgZGVjbGFyYXRpb24sIG90aGVyd2lzZQotICAgICAqICAgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICogQHJldHVybiBBbiA8Y29kZT5YU1R5cGVEZWZpbml0aW9uPC9jb2RlPiBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiBzdWNoCi0gICAgICogICBhIGRlZmluaXRpb24gZG9lcyBub3QgZXhpc3QuCi0gICAgICovCi0gICAgcHVibGljIFhTVHlwZURlZmluaXRpb24gZ2V0VHlwZURlZmluaXRpb24oU3RyaW5nIG5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG5hbWVzcGFjZSk7Ci0KLSAgICAvKioKLSAgICAgKiBDb252ZW5pZW5jZSBtZXRob2QuIFJldHVybnMgYSB0b3AtbGV2ZWwgYXR0cmlidXRlIGdyb3VwIGRlZmluaXRpb24uCi0gICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGRlZmluaXRpb24uCi0gICAgICogQHBhcmFtIG5hbWVzcGFjZSBUaGUgbmFtZXNwYWNlIG9mIHRoZSBkZWZpbml0aW9uLCBvdGhlcndpc2UKLSAgICAgKiAgIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAqIEByZXR1cm4gQSB0b3AtbGV2ZWwgYXR0cmlidXRlIGdyb3VwIGRlZmluaXRpb24gb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYKLSAgICAgKiAgIHN1Y2ggYSBkZWZpbml0aW9uIGRvZXMgbm90IGV4aXN0LgotICAgICAqLwotICAgIHB1YmxpYyBYU0F0dHJpYnV0ZUdyb3VwRGVmaW5pdGlvbiBnZXRBdHRyaWJ1dGVHcm91cChTdHJpbmcgbmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG5hbWVzcGFjZSk7Ci0KLSAgICAvKioKLSAgICAgKiBDb252ZW5pZW5jZSBtZXRob2QuIFJldHVybnMgYSB0b3AtbGV2ZWwgbW9kZWwgZ3JvdXAgZGVmaW5pdGlvbi4KLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgZGVmaW5pdGlvbi4KLSAgICAgKiBAcGFyYW0gbmFtZXNwYWNlIFRoZSBuYW1lc3BhY2Ugb2YgdGhlIGRlZmluaXRpb24sIG90aGVyd2lzZQotICAgICAqICAgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICogQHJldHVybiBBIHRvcC1sZXZlbCBtb2RlbCBncm91cCBkZWZpbml0aW9uIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmCi0gICAgICogICBzdWNoIGEgZGVmaW5pdGlvbiBkb2VzIG5vdCBleGlzdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFNNb2RlbEdyb3VwRGVmaW5pdGlvbiBnZXRNb2RlbEdyb3VwRGVmaW5pdGlvbihTdHJpbmcgbmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbmFtZXNwYWNlKTsKLQotICAgIC8qKgotICAgICAqIENvbnZlbmllbmNlIG1ldGhvZC4gUmV0dXJucyBhIHRvcC1sZXZlbCBub3RhdGlvbiBkZWNsYXJhdGlvbi4KLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgZGVjbGFyYXRpb24uCi0gICAgICogQHBhcmFtIG5hbWVzcGFjZSBUaGUgbmFtZXNwYWNlIG9mIHRoZSBkZWNsYXJhdGlvbiwgb3RoZXJ3aXNlCi0gICAgICogICA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICAgKiBAcmV0dXJuIEEgdG9wLWxldmVsIG5vdGF0aW9uIGRlY2xhcmF0aW9uIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIHN1Y2gKLSAgICAgKiAgIGEgZGVjbGFyYXRpb24gZG9lcyBub3QgZXhpc3QuCi0gICAgICovCi0gICAgcHVibGljIFhTTm90YXRpb25EZWNsYXJhdGlvbiBnZXROb3RhdGlvbkRlY2xhcmF0aW9uKFN0cmluZyBuYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbmFtZXNwYWNlKTsKLQotICAgIC8qKgotICAgICAqIENvbnZlbmllbmNlIG1ldGhvZC4gUmV0dXJucyBhIGxpc3QgY29udGFpbmluZyB0aGUgbWVtYmVycyBvZiB0aGUKLSAgICAgKiBzdWJzdGl0dXRpb24gZ3JvdXAgZm9yIHRoZSBnaXZlbiA8Y29kZT5YU0VsZW1lbnREZWNsYXJhdGlvbjwvY29kZT4KLSAgICAgKiBvciBhbiBlbXB0eSA8Y29kZT5YU09iamVjdExpc3Q8L2NvZGU+IGlmIHRoZSBzdWJzdGl0dXRpb24gZ3JvdXAKLSAgICAgKiBjb250YWlucyBubyBtZW1iZXJzLgotICAgICAqIEBwYXJhbSBoZWFkIFRoZSBzdWJzdGl0dXRpb24gZ3JvdXAgaGVhZC4KLSAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBtZW1iZXJzIG9mIHRoZSBzdWJzdGl0dXRpb24gZ3JvdXAKLSAgICAgKiAgZm9yIHRoZSBnaXZlbiA8Y29kZT5YU0VsZW1lbnREZWNsYXJhdGlvbjwvY29kZT4gb3IgYW4gZW1wdHkKLSAgICAgKiAgPGNvZGU+WFNPYmplY3RMaXN0PC9jb2RlPiBpZiB0aGUgc3Vic3RpdHV0aW9uIGdyb3VwIGNvbnRhaW5zCi0gICAgICogIG5vIG1lbWJlcnMuCi0gICAgICovCi0gICAgcHVibGljIFhTT2JqZWN0TGlzdCBnZXRTdWJzdGl0dXRpb25Hcm91cChYU0VsZW1lbnREZWNsYXJhdGlvbiBoZWFkKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHMvWFNNb2RlbEdyb3VwLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94cy9YU01vZGVsR3JvdXAuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMjY1ZWNmMy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94cy9YU01vZGVsR3JvdXAuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDY2ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDMsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54czsKLQotLyoqCi0gKiBUaGlzIGludGVyZmFjZSByZXByZXNlbnRzIHRoZSBNb2RlbCBHcm91cCBzY2hlbWEgY29tcG9uZW50LgotICovCi1wdWJsaWMgaW50ZXJmYWNlIFhTTW9kZWxHcm91cCBleHRlbmRzIFhTVGVybSB7Ci0gICAgLy8gQ29udGVudCBtb2RlbCBjb21wb3NpdG9ycwotICAgIC8qKgotICAgICAqIFRoaXMgY29uc3RhbnQgdmFsdWUgc2lnbmlmaWVzIGEgc2VxdWVuY2Ugb3BlcmF0b3IuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBDT01QT1NJVE9SX1NFUVVFTkNFICAgICAgID0gMTsKLSAgICAvKioKLSAgICAgKiBUaGlzIGNvbnN0YW50IHZhbHVlIHNpZ25pZmllcyBhIGNob2ljZSBvcGVyYXRvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IENPTVBPU0lUT1JfQ0hPSUNFICAgICAgICAgPSAyOwotICAgIC8qKgotICAgICAqIFRoaXMgY29udGVudCBtb2RlbCByZXByZXNlbnRzIGEgc2ltcGxpZmllZCB2ZXJzaW9uIG9mIHRoZSBTR01MCi0gICAgICogJmFtcDstQ29ubmVjdG9yIGFuZCBpcyBsaW1pdGVkIHRvIHRoZSB0b3AtbGV2ZWwgb2YgYW55IGNvbnRlbnQgbW9kZWwuCi0gICAgICogTm8gZWxlbWVudCBpbiB0aGUgYWxsIGNvbnRlbnQgbW9kZWwgbWF5IGFwcGVhciBtb3JlIHRoYW4gb25jZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IENPTVBPU0lUT1JfQUxMICAgICAgICAgICAgPSAzOwotCi0gICAgLyoqCi0gICAgICogW2NvbXBvc2l0b3JdOiBvbmUgb2YgYWxsLCBjaG9pY2Ugb3Igc2VxdWVuY2UuIFRoZSB2YWxpZCBjb25zdGFudCB2YWx1ZXMKLSAgICAgKiBhcmU6Ci0gICAgICogPGNvZGU+Q09NUE9TSVRPUl9TRVFVRU5DRSwgQ09NUE9TSVRPUl9DSE9JQ0UsIENPTVBPU0lUT1JfQUxMPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgc2hvcnQgZ2V0Q29tcG9zaXRvcigpOwotCi0gICAgLyoqCi0gICAgICogIEEgbGlzdCBvZiBbcGFydGljbGVzXSBpZiBpdCBleGlzdHMsIG90aGVyd2lzZSBhbiBlbXB0eQotICAgICAqIDxjb2RlPlhTT2JqZWN0TGlzdDwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIFhTT2JqZWN0TGlzdCBnZXRQYXJ0aWNsZXMoKTsKLQotICAgIC8qKgotICAgICAqIEFuIGFubm90YXRpb24gaWYgaXQgZXhpc3RzLCBvdGhlcndpc2UgPGNvZGU+bnVsbDwvY29kZT4uIElmIG5vdCBudWxsCi0gICAgICogdGhlbiB0aGUgZmlyc3QgW2Fubm90YXRpb25dIGZyb20gdGhlIHNlcXVlbmNlIG9mIGFubm90YXRpb25zLgotICAgICAqLwotICAgIHB1YmxpYyBYU0Fubm90YXRpb24gZ2V0QW5ub3RhdGlvbigpOwotCi0gICAgLyoqCi0gICAgICogQSBzZXF1ZW5jZSBvZiBbYW5ub3RhdGlvbnNdIG9yIGFuIGVtcHR5IDxjb2RlPlhTT2JqZWN0TGlzdDwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIFhTT2JqZWN0TGlzdCBnZXRBbm5vdGF0aW9ucygpOwotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHMvWFNNb2RlbEdyb3VwRGVmaW5pdGlvbi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHMvWFNNb2RlbEdyb3VwRGVmaW5pdGlvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmYjZkNTk0Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3hzL1hTTW9kZWxHcm91cERlZmluaXRpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQyICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDMsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54czsKLQotLyoqCi0gKiBUaGlzIGludGVyZmFjZSByZXByZXNlbnRzIHRoZSBNb2RlbCBHcm91cCBEZWZpbml0aW9uIHNjaGVtYSBjb21wb25lbnQuCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgWFNNb2RlbEdyb3VwRGVmaW5pdGlvbiBleHRlbmRzIFhTT2JqZWN0IHsKLSAgICAvKioKLSAgICAgKiBBIG1vZGVsIGdyb3VwLgotICAgICAqLwotICAgIHB1YmxpYyBYU01vZGVsR3JvdXAgZ2V0TW9kZWxHcm91cCgpOwotCi0gICAgLyoqCi0gICAgICogQW4gYW5ub3RhdGlvbiBpZiBpdCBleGlzdHMsIG90aGVyd2lzZSA8Y29kZT5udWxsPC9jb2RlPi4gSWYgbm90IG51bGwKLSAgICAgKiB0aGVuIHRoZSBmaXJzdCBbYW5ub3RhdGlvbl0gZnJvbSB0aGUgc2VxdWVuY2Ugb2YgYW5ub3RhdGlvbnMuCi0gICAgICovCi0gICAgcHVibGljIFhTQW5ub3RhdGlvbiBnZXRBbm5vdGF0aW9uKCk7Ci0KLSAgICAvKioKLSAgICAgKiBBIHNlcXVlbmNlIG9mIFthbm5vdGF0aW9uc10gb3IgYW4gZW1wdHkgPGNvZGU+WFNPYmplY3RMaXN0PC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFNPYmplY3RMaXN0IGdldEFubm90YXRpb25zKCk7Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94cy9YU011bHRpVmFsdWVGYWNldC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHMvWFNNdWx0aVZhbHVlRmFjZXQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOTYwZDc5OC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94cy9YU011bHRpVmFsdWVGYWNldC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDMgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMywyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzOwotCi0vKioKLSAqIERlc2NyaWJlcyBhIG11bHRpLXZhbHVlIGNvbnN0cmFpbmluZyBmYWNldHM6IHBhdHRlcm4gYW5kIGVudW1lcmF0aW9uLgotICovCi1wdWJsaWMgaW50ZXJmYWNlIFhTTXVsdGlWYWx1ZUZhY2V0IGV4dGVuZHMgWFNPYmplY3QgewotICAgIC8qKgotICAgICAqIFRoZSBuYW1lIG9mIHRoZSBmYWNldCwgaS5lLiA8Y29kZT5GQUNFVF9FTlVNRVJBVElPTjwvY29kZT4gYW5kCi0gICAgICogPGNvZGU+RkFDRVRfUEFUVEVSTjwvY29kZT4gKHNlZSA8Y29kZT5YU1NpbXBsZVR5cGVEZWZpbml0aW9uPC9jb2RlPikuCi0gICAgICovCi0gICAgcHVibGljIHNob3J0IGdldEZhY2V0S2luZCgpOwotCi0gICAgLyoqCi0gICAgICogVmFsdWVzIG9mIHRoaXMgZmFjZXQuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZ0xpc3QgZ2V0TGV4aWNhbEZhY2V0VmFsdWVzKCk7Ci0KLSAgICAvKioKLSAgICAgKiBBIHNlcXVlbmNlIG9mIFthbm5vdGF0aW9uc10gb3IgYW4gZW1wdHkgPGNvZGU+WFNPYmplY3RMaXN0PC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFNPYmplY3RMaXN0IGdldEFubm90YXRpb25zKCk7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3hzL1hTTmFtZWRNYXAuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3hzL1hTTmFtZWRNYXAuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOTc2NjgwYi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94cy9YU05hbWVkTWFwLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw2OSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAzLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHM7Ci0KLWltcG9ydCBqYXZhLnV0aWwuTWFwOwotCi0vKioKLSAqIE9iamVjdHMgaW1wbGVtZW50aW5nIHRoZSA8Y29kZT5YU05hbWVkTWFwPC9jb2RlPiBpbnRlcmZhY2UgYXJlIHVzZWQgdG8KLSAqIHJlcHJlc2VudCBpbW11dGFibGUgY29sbGVjdGlvbnMgb2YgWE1MIFNjaGVtYSBjb21wb25lbnRzIHRoYXQgY2FuIGJlCi0gKiBhY2Nlc3NlZCBieSBuYW1lLiBOb3RlIHRoYXQgPGNvZGU+WFNOYW1lZE1hcDwvY29kZT4gZG9lcyBub3QgaW5oZXJpdCBmcm9tCi0gKiA8Y29kZT5YU09iamVjdExpc3Q8L2NvZGU+LiBUaGUgPGNvZGU+WFNPYmplY3Q8L2NvZGU+cyBpbgotICogPGNvZGU+WFNOYW1lZE1hcDwvY29kZT5zIGFyZSBub3QgbWFpbnRhaW5lZCBpbiBhbnkgcGFydGljdWxhciBvcmRlci4KLSAqLwotcHVibGljIGludGVyZmFjZSBYU05hbWVkTWFwIGV4dGVuZHMgTWFwIHsKLSAgICAvKioKLSAgICAgKiBUaGUgbnVtYmVyIG9mIDxjb2RlPlhTT2JqZWN0czwvY29kZT4gaW4gdGhlIDxjb2RlPlhTT2JqZWN0TGlzdDwvY29kZT4uCi0gICAgICogVGhlIHJhbmdlIG9mIHZhbGlkIGNoaWxkIG9iamVjdCBpbmRpY2VzIGlzIDAgdG8gPGNvZGU+bGVuZ3RoLTE8L2NvZGU+Ci0gICAgICogaW5jbHVzaXZlLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0TGVuZ3RoKCk7Ci0KLSAgICAvKioKLSAgICAgKiAgUmV0dXJucyB0aGUgPGNvZGU+aW5kZXg8L2NvZGU+dGggaXRlbSBpbiB0aGUgY29sbGVjdGlvbiBvcgotICAgICAqIDxjb2RlPm51bGw8L2NvZGU+IGlmIDxjb2RlPmluZGV4PC9jb2RlPiBpcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8KLSAgICAgKiB0aGUgbnVtYmVyIG9mIG9iamVjdHMgaW4gdGhlIGxpc3QuIFRoZSBpbmRleCBzdGFydHMgYXQgMC4KLSAgICAgKiBAcGFyYW0gaW5kZXggIGluZGV4IGludG8gdGhlIGNvbGxlY3Rpb24uCi0gICAgICogQHJldHVybiAgVGhlIDxjb2RlPlhTT2JqZWN0PC9jb2RlPiBhdCB0aGUgPGNvZGU+aW5kZXg8L2NvZGU+dGgKLSAgICAgKiAgIHBvc2l0aW9uIGluIHRoZSA8Y29kZT5YU09iamVjdExpc3Q8L2NvZGU+LCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZgotICAgICAqICAgdGhlIGluZGV4IHNwZWNpZmllZCBpcyBub3QgdmFsaWQuCi0gICAgICovCi0gICAgcHVibGljIFhTT2JqZWN0IGl0ZW0oaW50IGluZGV4KTsKLQotICAgIC8qKgotICAgICAqIFJldHJpZXZlcyBhbiA8Y29kZT5YU09iamVjdDwvY29kZT4gc3BlY2lmaWVkIGJ5IGxvY2FsIG5hbWUgYW5kCi0gICAgICogbmFtZXNwYWNlIFVSSS4KLSAgICAgKiA8YnI+UGVyIFhNTCBOYW1lc3BhY2VzLCBhcHBsaWNhdGlvbnMgbXVzdCB1c2UgdGhlIHZhbHVlIDxjb2RlPm51bGw8L2NvZGU+IGFzIHRoZQotICAgICAqIDxjb2RlPm5hbWVzcGFjZTwvY29kZT4gcGFyYW1ldGVyIGZvciBtZXRob2RzIGlmIHRoZXkgd2lzaCB0byBzcGVjaWZ5Ci0gICAgICogbm8gbmFtZXNwYWNlLgotICAgICAqIEBwYXJhbSBuYW1lc3BhY2UgVGhlIG5hbWVzcGFjZSBVUkkgb2YgdGhlIDxjb2RlPlhTT2JqZWN0PC9jb2RlPiB0bwotICAgICAqICAgcmV0cmlldmUsIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoZSA8Y29kZT5YU09iamVjdDwvY29kZT4gaGFzIG5vCi0gICAgICogICBuYW1lc3BhY2UuCi0gICAgICogQHBhcmFtIGxvY2FsTmFtZSBUaGUgbG9jYWwgbmFtZSBvZiB0aGUgPGNvZGU+WFNPYmplY3Q8L2NvZGU+IHRvCi0gICAgICogICByZXRyaWV2ZS4KLSAgICAgKiBAcmV0dXJuIEEgPGNvZGU+WFNPYmplY3Q8L2NvZGU+IChvZiBhbnkgdHlwZSkgd2l0aCB0aGUgc3BlY2lmaWVkIGxvY2FsCi0gICAgICogICBuYW1lIGFuZCBuYW1lc3BhY2UgVVJJLCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGV5IGRvIG5vdAotICAgICAqICAgaWRlbnRpZnkgYW55IG9iamVjdCBpbiB0aGlzIG1hcC4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFNPYmplY3QgaXRlbUJ5TmFtZShTdHJpbmcgbmFtZXNwYWNlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBsb2NhbE5hbWUpOwotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94cy9YU05hbWVzcGFjZUl0ZW0uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3hzL1hTTmFtZXNwYWNlSXRlbS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhODNkMWUwLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3hzL1hTTmFtZXNwYWNlSXRlbS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTEwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDMsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54czsKLQotLyoqCi0gKiBUaGUgaW50ZXJmYWNlIHJlcHJlc2VudHMgdGhlIG5hbWVzcGFjZSBzY2hlbWEgaW5mb3JtYXRpb24gaW5mb3JtYXRpb24gaXRlbS4KLSAqIEVhY2ggbmFtZXNwYWNlIHNjaGVtYSBpbmZvcm1hdGlvbiBpbmZvcm1hdGlvbiBpdGVtIGNvcnJlc3BvbmRzIHRvIGFuIFhNTAotICogU2NoZW1hIHdpdGggYSB1bmlxdWUgbmFtZXNwYWNlIG5hbWUuCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgWFNOYW1lc3BhY2VJdGVtIHsKLSAgICAvKioKLSAgICAgKiBbc2NoZW1hIG5hbWVzcGFjZV06IEEgbmFtZXNwYWNlIG5hbWUgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgYWJzZW50LgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0U2NoZW1hTmFtZXNwYWNlKCk7Ci0KLSAgICAvKioKLSAgICAgKiBbc2NoZW1hIGNvbXBvbmVudHNdOiBhIGxpc3Qgb2YgdG9wLWxldmVsIGNvbXBvbmVudHMsIGkuZS4gZWxlbWVudAotICAgICAqIGRlY2xhcmF0aW9ucywgYXR0cmlidXRlIGRlY2xhcmF0aW9ucywgZXRjLgotICAgICAqIEBwYXJhbSBvYmplY3RUeXBlIFRoZSB0eXBlIG9mIHRoZSBkZWNsYXJhdGlvbiwgaS5lLgotICAgICAqICAgPGNvZGU+RUxFTUVOVF9ERUNMQVJBVElPTjwvY29kZT4uIE5vdGUgdGhhdAotICAgICAqICAgPGNvZGU+WFNUeXBlRGVmaW5pdGlvbi5TSU1QTEVfVFlQRTwvY29kZT4gYW5kCi0gICAgICogICA8Y29kZT5YU1R5cGVEZWZpbml0aW9uLkNPTVBMRVhfVFlQRTwvY29kZT4gY2FuIGFsc28gYmUgdXNlZCBhcyB0aGUKLSAgICAgKiAgIDxjb2RlPm9iamVjdFR5cGU8L2NvZGU+IHRvIHJldHJpZXZlIG9ubHkgY29tcGxleCB0eXBlcyBvciBzaW1wbGUKLSAgICAgKiAgIHR5cGVzLCBpbnN0ZWFkIG9mIGFsbCB0eXBlcy4KLSAgICAgKiBAcmV0dXJuICBBIGxpc3Qgb2YgdG9wLWxldmVsIGRlZmluaXRpb24gb2YgdGhlIHNwZWNpZmllZCB0eXBlIGluCi0gICAgICogICA8Y29kZT5vYmplY3RUeXBlPC9jb2RlPiBvciBhbiBlbXB0eSA8Y29kZT5YU05hbWVkTWFwPC9jb2RlPiBpZiBubwotICAgICAqICAgc3VjaCBkZWZpbml0aW9ucyBleGlzdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFNOYW1lZE1hcCBnZXRDb21wb25lbnRzKHNob3J0IG9iamVjdFR5cGUpOwotCi0gICAgLyoqCi0gICAgICogIFthbm5vdGF0aW9uc106IGEgc2V0IG9mIGFubm90YXRpb25zIGlmIGl0IGV4aXN0cywgb3RoZXJ3aXNlIGFuIGVtcHR5Ci0gICAgICogPGNvZGU+WFNPYmplY3RMaXN0PC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFNPYmplY3RMaXN0IGdldEFubm90YXRpb25zKCk7Ci0KLSAgICAvKioKLSAgICAgKiBDb252ZW5pZW5jZSBtZXRob2QuIFJldHVybnMgYSB0b3AtbGV2ZWwgZWxlbWVudCBkZWNsYXJhdGlvbi4KLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgZGVjbGFyYXRpb24uCi0gICAgICogQHJldHVybiBBIHRvcC1sZXZlbCBlbGVtZW50IGRlY2xhcmF0aW9uIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIHN1Y2ggYQotICAgICAqICAgZGVjbGFyYXRpb24gZG9lcyBub3QgZXhpc3QuCi0gICAgICovCi0gICAgcHVibGljIFhTRWxlbWVudERlY2xhcmF0aW9uIGdldEVsZW1lbnREZWNsYXJhdGlvbihTdHJpbmcgbmFtZSk7Ci0KLSAgICAvKioKLSAgICAgKiBDb252ZW5pZW5jZSBtZXRob2QuIFJldHVybnMgYSB0b3AtbGV2ZWwgYXR0cmlidXRlIGRlY2xhcmF0aW9uLgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBkZWNsYXJhdGlvbi4KLSAgICAgKiBAcmV0dXJuIEEgdG9wLWxldmVsIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbiBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiBzdWNoCi0gICAgICogICBhIGRlY2xhcmF0aW9uIGRvZXMgbm90IGV4aXN0LgotICAgICAqLwotICAgIHB1YmxpYyBYU0F0dHJpYnV0ZURlY2xhcmF0aW9uIGdldEF0dHJpYnV0ZURlY2xhcmF0aW9uKFN0cmluZyBuYW1lKTsKLQotICAgIC8qKgotICAgICAqIENvbnZlbmllbmNlIG1ldGhvZC4gUmV0dXJucyBhIHRvcC1sZXZlbCBzaW1wbGUgb3IgY29tcGxleCB0eXBlCi0gICAgICogZGVmaW5pdGlvbi4KLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgZGVmaW5pdGlvbi4KLSAgICAgKiBAcmV0dXJuIEFuIDxjb2RlPlhTVHlwZURlZmluaXRpb248L2NvZGU+IG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIHN1Y2gKLSAgICAgKiAgIGEgZGVmaW5pdGlvbiBkb2VzIG5vdCBleGlzdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFNUeXBlRGVmaW5pdGlvbiBnZXRUeXBlRGVmaW5pdGlvbihTdHJpbmcgbmFtZSk7Ci0KLSAgICAvKioKLSAgICAgKiBDb252ZW5pZW5jZSBtZXRob2QuIFJldHVybnMgYSB0b3AtbGV2ZWwgYXR0cmlidXRlIGdyb3VwIGRlZmluaXRpb24uCi0gICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGRlZmluaXRpb24uCi0gICAgICogQHJldHVybiBBIHRvcC1sZXZlbCBhdHRyaWJ1dGUgZ3JvdXAgZGVmaW5pdGlvbiBvciA8Y29kZT5udWxsPC9jb2RlPiBpZgotICAgICAqICAgc3VjaCBhIGRlZmluaXRpb24gZG9lcyBub3QgZXhpc3QuCi0gICAgICovCi0gICAgcHVibGljIFhTQXR0cmlidXRlR3JvdXBEZWZpbml0aW9uIGdldEF0dHJpYnV0ZUdyb3VwKFN0cmluZyBuYW1lKTsKLQotICAgIC8qKgotICAgICAqIENvbnZlbmllbmNlIG1ldGhvZC4gUmV0dXJucyBhIHRvcC1sZXZlbCBtb2RlbCBncm91cCBkZWZpbml0aW9uLgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBkZWZpbml0aW9uLgotICAgICAqIEByZXR1cm4gQSB0b3AtbGV2ZWwgbW9kZWwgZ3JvdXAgZGVmaW5pdGlvbiBkZWZpbml0aW9uIG9yCi0gICAgICogICA8Y29kZT5udWxsPC9jb2RlPiBpZiBzdWNoIGEgZGVmaW5pdGlvbiBkb2VzIG5vdCBleGlzdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFNNb2RlbEdyb3VwRGVmaW5pdGlvbiBnZXRNb2RlbEdyb3VwRGVmaW5pdGlvbihTdHJpbmcgbmFtZSk7Ci0KLSAgICAvKioKLSAgICAgKiBDb252ZW5pZW5jZSBtZXRob2QuIFJldHVybnMgYSB0b3AtbGV2ZWwgbm90YXRpb24gZGVjbGFyYXRpb24uCi0gICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGRlY2xhcmF0aW9uLgotICAgICAqIEByZXR1cm4gQSB0b3AtbGV2ZWwgbm90YXRpb24gZGVjbGFyYXRpb24gb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgc3VjaAotICAgICAqICAgYSBkZWNsYXJhdGlvbiBkb2VzIG5vdCBleGlzdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFNOb3RhdGlvbkRlY2xhcmF0aW9uIGdldE5vdGF0aW9uRGVjbGFyYXRpb24oU3RyaW5nIG5hbWUpOwotCi0gICAgLyoqCi0gICAgICogW2RvY3VtZW50IGxvY2F0aW9uXSAtIGEgbGlzdCBvZiBsb2NhdGlvbiBVUklzIGZvciB0aGUgZG9jdW1lbnRzIHRoYXQKLSAgICAgKiBjb250cmlidXRlZCB0byB0aGUgPGNvZGU+WFNNb2RlbDwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZ0xpc3QgZ2V0RG9jdW1lbnRMb2NhdGlvbnMoKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHMvWFNOYW1lc3BhY2VJdGVtTGlzdC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHMvWFNOYW1lc3BhY2VJdGVtTGlzdC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4YThlZTk5Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3hzL1hTTmFtZXNwYWNlSXRlbUxpc3QuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQ4ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDMsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54czsKLQotaW1wb3J0IGphdmEudXRpbC5MaXN0OwotCi0vKioKLSAqICBUaGUgPGNvZGU+WFNOYW1lc2FjZUl0ZW1MaXN0PC9jb2RlPiBpbnRlcmZhY2UgcHJvdmlkZXMgdGhlIGFic3RyYWN0aW9uIG9mCi0gKiBhbiBpbW11dGFibGUgb3JkZXJlZCBjb2xsZWN0aW9uIG9mIDxjb2RlPlhTTmFtZXNwYWNlSXRlbTwvY29kZT5zLCB3aXRob3V0Ci0gKiBkZWZpbmluZyBvciBjb25zdHJhaW5pbmcgaG93IHRoaXMgY29sbGVjdGlvbiBpcyBpbXBsZW1lbnRlZC4KLSAqLwotcHVibGljIGludGVyZmFjZSBYU05hbWVzcGFjZUl0ZW1MaXN0IGV4dGVuZHMgTGlzdCB7Ci0gICAgLyoqCi0gICAgICogIFRoZSBudW1iZXIgb2YgPGNvZGU+WFNOYW1lc3BhY2VJdGVtPC9jb2RlPnMgaW4gdGhlIGxpc3QuIFRoZSByYW5nZSBvZgotICAgICAqIHZhbGlkIGNoaWxkIG9iamVjdCBpbmRpY2VzIGlzIDAgdG8gPGNvZGU+bGVuZ3RoLTE8L2NvZGU+IGluY2x1c2l2ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldExlbmd0aCgpOwotCi0gICAgLyoqCi0gICAgICogIFJldHVybnMgdGhlIDxjb2RlPmluZGV4PC9jb2RlPnRoIGl0ZW0gaW4gdGhlIGNvbGxlY3Rpb24gb3IKLSAgICAgKiA8Y29kZT5udWxsPC9jb2RlPiBpZiA8Y29kZT5pbmRleDwvY29kZT4gaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvCi0gICAgICogdGhlIG51bWJlciBvZiBvYmplY3RzIGluIHRoZSBsaXN0LiBUaGUgaW5kZXggc3RhcnRzIGF0IDAuCi0gICAgICogQHBhcmFtIGluZGV4ICBpbmRleCBpbnRvIHRoZSBjb2xsZWN0aW9uLgotICAgICAqIEByZXR1cm4gIFRoZSA8Y29kZT5YU05hbWVzcGFjZUl0ZW08L2NvZGU+IGF0IHRoZSA8Y29kZT5pbmRleDwvY29kZT50aAotICAgICAqICAgcG9zaXRpb24gaW4gdGhlIDxjb2RlPlhTTmFtZXNwYWNlSXRlbUxpc3Q8L2NvZGU+LCBvcgotICAgICAqICAgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlIGluZGV4IHNwZWNpZmllZCBpcyBub3QgdmFsaWQuCi0gICAgICovCi0gICAgcHVibGljIFhTTmFtZXNwYWNlSXRlbSBpdGVtKGludCBpbmRleCk7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3hzL1hTTm90YXRpb25EZWNsYXJhdGlvbi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHMvWFNOb3RhdGlvbkRlY2xhcmF0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGIxYzAzZDIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHMvWFNOb3RhdGlvbkRlY2xhcmF0aW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0OSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAzLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHM7Ci0KLS8qKgotICogIFRoaXMgaW50ZXJmYWNlIHJlcHJlc2VudHMgdGhlIE5vdGF0aW9uIERlY2xhcmF0aW9uIHNjaGVtYSBjb21wb25lbnQuCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgWFNOb3RhdGlvbkRlY2xhcmF0aW9uIGV4dGVuZHMgWFNPYmplY3QgewotICAgIC8qKgotICAgICAqICBUaGUgVVJJIHJlZmVyZW5jZSByZXByZXNlbnRpbmcgdGhlIHN5c3RlbSBpZGVudGlmaWVyIGZvciB0aGUgbm90YXRpb24KLSAgICAgKiBkZWNsYXJhdGlvbiwgaWYgcHJlc2VudCwgPGNvZGU+bnVsbDwvY29kZT4gb3RoZXJ3aXNlLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3lzdGVtSWQoKTsKLQotICAgIC8qKgotICAgICAqICBUaGUgc3RyaW5nIHJlcHJlc2VudGluZyB0aGUgcHVibGljIGlkZW50aWZpZXIgZm9yIHRoaXMgbm90YXRpb24KLSAgICAgKiBkZWNsYXJhdGlvbiwgaWYgcHJlc2VudDsgPGNvZGU+bnVsbDwvY29kZT4gb3RoZXJ3aXNlLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0UHVibGljSWQoKTsKLQotICAgIC8qKgotICAgICAqIEFuIGFubm90YXRpb24gaWYgaXQgZXhpc3RzLCBvdGhlcndpc2UgPGNvZGU+bnVsbDwvY29kZT4uIElmIG5vdCBudWxsCi0gICAgICogdGhlbiB0aGUgZmlyc3QgW2Fubm90YXRpb25dIGZyb20gdGhlIHNlcXVlbmNlIG9mIGFubm90YXRpb25zLgotICAgICAqLwotICAgIHB1YmxpYyBYU0Fubm90YXRpb24gZ2V0QW5ub3RhdGlvbigpOwotCi0gICAgLyoqCi0gICAgICogQSBzZXF1ZW5jZSBvZiBbYW5ub3RhdGlvbnNdIG9yIGFuIGVtcHR5IDxjb2RlPlhTT2JqZWN0TGlzdDwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIFhTT2JqZWN0TGlzdCBnZXRBbm5vdGF0aW9ucygpOwotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHMvWFNPYmplY3QuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3hzL1hTT2JqZWN0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDE3NmFlNzkuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHMvWFNPYmplY3QuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDU4ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDMsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54czsKLQotLyoqCi0gKiBUaGUgPGNvZGU+WFNPYmplY3Q8L2NvZGU+IGlzIGEgYmFzZSBvYmplY3QgZm9yIHRoZSBYTUwgU2NoZW1hIGNvbXBvbmVudAotICogbW9kZWwuCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgWFNPYmplY3QgewotICAgIC8qKgotICAgICAqICBUaGUgPGNvZGU+dHlwZTwvY29kZT4gb2YgdGhpcyBvYmplY3QsIGkuZS4KLSAgICAgKiA8Y29kZT5FTEVNRU5UX0RFQ0xBUkFUSU9OPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgc2hvcnQgZ2V0VHlwZSgpOwotCi0gICAgLyoqCi0gICAgICogVGhlIG5hbWUgb2YgdHlwZSA8Y29kZT5OQ05hbWU8L2NvZGU+LCBhcyBkZWZpbmVkIGluIFhNTCBOYW1lc3BhY2VzLCBvZgotICAgICAqIHRoaXMgZGVjbGFyYXRpb24gc3BlY2lmaWVkIGluIHRoZSA8Y29kZT57bmFtZX08L2NvZGU+IHByb3BlcnR5IG9mIHRoZQotICAgICAqIGNvbXBvbmVudCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGUgZGVmaW5pdGlvbiBvZiB0aGlzIGNvbXBvbmVudAotICAgICAqIGRvZXMgbm90IGhhdmUgYSA8Y29kZT57bmFtZX08L2NvZGU+IHByb3BlcnR5LiBGb3IgYW5vbnltb3VzIHR5cGVzLAotICAgICAqIHRoZSBwcm9jZXNzb3IgbXVzdCBjb25zdHJ1Y3QgYW5kIGV4cG9zZSBhbiBhbm9ueW1vdXMgdHlwZSBuYW1lIHRoYXQKLSAgICAgKiBpcyBkaXN0aW5jdCBmcm9tIHRoZSBuYW1lIG9mIGV2ZXJ5IG5hbWVkIHR5cGUgYW5kIHRoZSBuYW1lIG9mIGV2ZXJ5Ci0gICAgICogb3RoZXIgYW5vbnltb3VzIHR5cGUuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXROYW1lKCk7Ci0KLSAgICAvKioKLSAgICAgKiAgVGhlIFt0YXJnZXQgbmFtZXNwYWNlXSBvZiB0aGlzIG9iamVjdCwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgaXQgaXMKLSAgICAgKiB1bnNwZWNpZmllZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWVzcGFjZSgpOwotCi0gICAgLyoqCi0gICAgICogQSBuYW1lc3BhY2Ugc2NoZW1hIGluZm9ybWF0aW9uIGl0ZW0gY29ycmVzcG9uZGluZyB0byB0aGUgdGFyZ2V0Ci0gICAgICogbmFtZXNwYWNlIG9mIHRoZSBjb21wb25lbnQsIGlmIGl0IGlzIGdsb2JhbGx5IGRlY2xhcmVkOyBvcgotICAgICAqIDxjb2RlPm51bGw8L2NvZGU+IG90aGVyd2lzZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFNOYW1lc3BhY2VJdGVtIGdldE5hbWVzcGFjZUl0ZW0oKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHMvWFNPYmplY3RMaXN0LmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94cy9YU09iamVjdExpc3QuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNWU2MGExZS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94cy9YU09iamVjdExpc3QuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQ4ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDMsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54czsKLQotaW1wb3J0IGphdmEudXRpbC5MaXN0OwotCi0vKioKLSAqICBUaGUgPGNvZGU+WFNPYmplY3RMaXN0PC9jb2RlPiBpbnRlcmZhY2UgcHJvdmlkZXMgdGhlIGFic3RyYWN0aW9uIG9mIGFuCi0gKiBpbW11dGFibGUgb3JkZXJlZCBjb2xsZWN0aW9uIG9mIDxjb2RlPlhTT2JqZWN0PC9jb2RlPnMsIHdpdGhvdXQgZGVmaW5pbmcKLSAqIG9yIGNvbnN0cmFpbmluZyBob3cgdGhpcyBjb2xsZWN0aW9uIGlzIGltcGxlbWVudGVkLgotICovCi1wdWJsaWMgaW50ZXJmYWNlIFhTT2JqZWN0TGlzdCBleHRlbmRzIExpc3QgewotICAgIC8qKgotICAgICAqICBUaGUgbnVtYmVyIG9mIDxjb2RlPlhTT2JqZWN0czwvY29kZT4gaW4gdGhlIGxpc3QuIFRoZSByYW5nZSBvZiB2YWxpZAotICAgICAqIGNoaWxkIG9iamVjdCBpbmRpY2VzIGlzIDAgdG8gPGNvZGU+bGVuZ3RoLTE8L2NvZGU+IGluY2x1c2l2ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldExlbmd0aCgpOwotCi0gICAgLyoqCi0gICAgICogIFJldHVybnMgdGhlIDxjb2RlPmluZGV4PC9jb2RlPnRoIGl0ZW0gaW4gdGhlIGNvbGxlY3Rpb24gb3IKLSAgICAgKiA8Y29kZT5udWxsPC9jb2RlPiBpZiA8Y29kZT5pbmRleDwvY29kZT4gaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvCi0gICAgICogdGhlIG51bWJlciBvZiBvYmplY3RzIGluIHRoZSBsaXN0LiBUaGUgaW5kZXggc3RhcnRzIGF0IDAuCi0gICAgICogQHBhcmFtIGluZGV4ICBpbmRleCBpbnRvIHRoZSBjb2xsZWN0aW9uLgotICAgICAqIEByZXR1cm4gIFRoZSA8Y29kZT5YU09iamVjdDwvY29kZT4gYXQgdGhlIDxjb2RlPmluZGV4PC9jb2RlPnRoCi0gICAgICogICBwb3NpdGlvbiBpbiB0aGUgPGNvZGU+WFNPYmplY3RMaXN0PC9jb2RlPiwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYKLSAgICAgKiAgIHRoZSBpbmRleCBzcGVjaWZpZWQgaXMgbm90IHZhbGlkLgotICAgICAqLwotICAgIHB1YmxpYyBYU09iamVjdCBpdGVtKGludCBpbmRleCk7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3hzL1hTUGFydGljbGUuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3hzL1hTUGFydGljbGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZTY0NTYyNS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94cy9YU1BhcnRpY2xlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw1NSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAzLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHM7Ci0KLS8qKgotICogVGhpcyBpbnRlcmZhY2UgcmVwcmVzZW50cyB0aGUgUGFydGljbGUgc2NoZW1hIGNvbXBvbmVudC4KLSAqLwotcHVibGljIGludGVyZmFjZSBYU1BhcnRpY2xlIGV4dGVuZHMgWFNPYmplY3QgewotICAgIC8qKgotICAgICAqIFttaW4gb2NjdXJzXTogZGV0ZXJtaW5lcyB0aGUgbWluaW11bSBudW1iZXIgb2YgdGVybXMgdGhhdCBjYW4gb2NjdXIuCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRNaW5PY2N1cnMoKTsKLQotICAgIC8qKgotICAgICAqICBbbWF4IG9jY3Vyc106IGRldGVybWluZXMgdGhlIG1heGltdW0gbnVtYmVyIG9mIHRlcm1zIHRoYXQgY2FuIG9jY3VyLgotICAgICAqIFRvIHF1ZXJ5IGZvciB0aGUgdmFsdWUgb2YgdW5ib3VuZGVkIHVzZQotICAgICAqIDxjb2RlPm1heE9jY3Vyc1VuYm91bmRlZDwvY29kZT4uIFdoZW4gdGhlIHZhbHVlIG9mCi0gICAgICogPGNvZGU+bWF4T2NjdXJzVW5ib3VuZGVkPC9jb2RlPiBpcyA8Y29kZT50cnVlPC9jb2RlPiwgdGhlIHZhbHVlIG9mCi0gICAgICogPGNvZGU+bWF4T2NjdXJzPC9jb2RlPiBpcyB1bnNwZWNpZmllZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldE1heE9jY3VycygpOwotCi0gICAgLyoqCi0gICAgICogW21heCBvY2N1cnNdOiB3aGV0aGVyIHRoZSBtYXhPY2N1cnMgdmFsdWUgaXMgdW5ib3VuZGVkLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGdldE1heE9jY3Vyc1VuYm91bmRlZCgpOwotCi0gICAgLyoqCi0gICAgICogW3Rlcm1dOiBvbmUgb2YgYSBtb2RlbCBncm91cCwgYSB3aWxkY2FyZCwgb3IgYW4gZWxlbWVudCBkZWNsYXJhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFNUZXJtIGdldFRlcm0oKTsKLQotICAgIC8qKgotICAgICAqIEEgc2VxdWVuY2Ugb2YgW2Fubm90YXRpb25zXSBvciBhbiBlbXB0eSA8Y29kZT5YU09iamVjdExpc3Q8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBYU09iamVjdExpc3QgZ2V0QW5ub3RhdGlvbnMoKTsKLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3hzL1hTU2ltcGxlVHlwZURlZmluaXRpb24uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3hzL1hTU2ltcGxlVHlwZURlZmluaXRpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggODQ0Mjc4MC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94cy9YU1NpbXBsZVR5cGVEZWZpbml0aW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyNDIgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMywyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzOwotCi0vKioKLSAqIFRoaXMgaW50ZXJmYWNlIHJlcHJlc2VudHMgdGhlIFNpbXBsZSBUeXBlIERlZmluaXRpb24gc2NoZW1hIGNvbXBvbmVudC4gVGhpcwotICogaW50ZXJmYWNlIHByb3ZpZGVzIHNldmVyYWwgcXVlcnkgb3BlcmF0aW9ucyBmb3IgZmFjZXQgY29tcG9uZW50cy4gVXNlcnMKLSAqIGNhbiBlaXRoZXIgcmV0cmlldmUgdGhlIGRlZmluZWQgZmFjZXRzIGFzIFhNTCBTY2hlbWEgY29tcG9uZW50cywgdXNpbmcKLSAqIHRoZSA8Y29kZT5mYWNldHM8L2NvZGU+IGFuZCB0aGUgPGNvZGU+bXVsdGlWYWx1ZUZhY2V0czwvY29kZT4gYXR0cmlidXRlczsKLSAqIG9yIHVzZXJzIGNhbiBzZXBhcmF0ZWx5IHF1ZXJ5IGEgZmFjZXQncyBwcm9wZXJ0aWVzIHVzaW5nIG1ldGhvZHMgc3VjaCBhcwotICogPGNvZGU+Z2V0TGV4aWNhbEZhY2V0VmFsdWU8L2NvZGU+LCA8Y29kZT5pc0ZpeGVkRmFjZXQ8L2NvZGU+LCBldGMuCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgWFNTaW1wbGVUeXBlRGVmaW5pdGlvbiBleHRlbmRzIFhTVHlwZURlZmluaXRpb24gewotICAgIC8vIFZhcmlldHkgZGVmaW5pdGlvbnMKLSAgICAvKioKLSAgICAgKiBUaGUgdmFyaWV0eSBpcyBhYnNlbnQgZm9yIHRoZSBhbnlTaW1wbGVUeXBlIGRlZmluaXRpb24uCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBWQVJJRVRZX0FCU0VOVCAgICAgICAgICAgID0gMDsKLSAgICAvKioKLSAgICAgKiA8Y29kZT5BdG9taWM8L2NvZGU+IHR5cGUuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBWQVJJRVRZX0FUT01JQyAgICAgICAgICAgID0gMTsKLSAgICAvKioKLSAgICAgKiA8Y29kZT5MaXN0PC9jb2RlPiB0eXBlLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgVkFSSUVUWV9MSVNUICAgICAgICAgICAgICA9IDI7Ci0gICAgLyoqCi0gICAgICogPGNvZGU+VW5pb248L2NvZGU+IHR5cGUuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBWQVJJRVRZX1VOSU9OICAgICAgICAgICAgID0gMzsKLQotICAgIC8vIEZhY2V0cwotICAgIC8qKgotICAgICAqIE5vIGZhY2V0cyBkZWZpbmVkLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgRkFDRVRfTk9ORSAgICAgICAgICAgICAgICA9IDA7Ci0gICAgLyoqCi0gICAgICogNC4zLjEgTGVuZ3RoCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBGQUNFVF9MRU5HVEggICAgICAgICAgICAgID0gMTsKLSAgICAvKioKLSAgICAgKiA0LjMuMiBtaW5MZW5ndGguCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBGQUNFVF9NSU5MRU5HVEggICAgICAgICAgID0gMjsKLSAgICAvKioKLSAgICAgKiA0LjMuMyBtYXhMZW5ndGguCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBGQUNFVF9NQVhMRU5HVEggICAgICAgICAgID0gNDsKLSAgICAvKioKLSAgICAgKiA0LjMuNCBwYXR0ZXJuLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgRkFDRVRfUEFUVEVSTiAgICAgICAgICAgICA9IDg7Ci0gICAgLyoqCi0gICAgICogNC4zLjUgd2hpdGVzcGFjZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IEZBQ0VUX1dISVRFU1BBQ0UgICAgICAgICAgPSAxNjsKLSAgICAvKioKLSAgICAgKiA0LjMuNyBtYXhJbmNsdXNpdmUuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBGQUNFVF9NQVhJTkNMVVNJVkUgICAgICAgID0gMzI7Ci0gICAgLyoqCi0gICAgICogNC4zLjkgbWF4RXhjbHVzaXZlLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgRkFDRVRfTUFYRVhDTFVTSVZFICAgICAgICA9IDY0OwotICAgIC8qKgotICAgICAqIDQuMy45IG1pbkV4Y2x1c2l2ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IEZBQ0VUX01JTkVYQ0xVU0lWRSAgICAgICAgPSAxMjg7Ci0gICAgLyoqCi0gICAgICogNC4zLjEwIG1pbkluY2x1c2l2ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IEZBQ0VUX01JTklOQ0xVU0lWRSAgICAgICAgPSAyNTY7Ci0gICAgLyoqCi0gICAgICogNC4zLjExIHRvdGFsRGlnaXRzIC4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IEZBQ0VUX1RPVEFMRElHSVRTICAgICAgICAgPSA1MTI7Ci0gICAgLyoqCi0gICAgICogNC4zLjEyIGZyYWN0aW9uRGlnaXRzLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgRkFDRVRfRlJBQ1RJT05ESUdJVFMgICAgICA9IDEwMjQ7Ci0gICAgLyoqCi0gICAgICogNC4zLjUgZW51bWVyYXRpb24uCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBGQUNFVF9FTlVNRVJBVElPTiAgICAgICAgID0gMjA0ODsKLQotICAgIC8qKgotICAgICAqIEEgY29uc3RhbnQgZGVmaW5lZCBmb3IgdGhlICdvcmRlcmVkJyBmdW5kYW1lbnRhbCBmYWNldDogbm90IG9yZGVyZWQuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBPUkRFUkVEX0ZBTFNFICAgICAgICAgICAgID0gMDsKLSAgICAvKioKLSAgICAgKiBBIGNvbnN0YW50IGRlZmluZWQgZm9yIHRoZSAnb3JkZXJlZCcgZnVuZGFtZW50YWwgZmFjZXQ6IHBhcnRpYWxseQotICAgICAqIG9yZGVyZWQuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBPUkRFUkVEX1BBUlRJQUwgICAgICAgICAgID0gMTsKLSAgICAvKioKLSAgICAgKiBBIGNvbnN0YW50IGRlZmluZWQgZm9yIHRoZSAnb3JkZXJlZCcgZnVuZGFtZW50YWwgZmFjZXQ6IHRvdGFsIG9yZGVyZWQuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBPUkRFUkVEX1RPVEFMICAgICAgICAgICAgID0gMjsKLSAgICAvKioKLSAgICAgKiBbdmFyaWV0eV06IG9uZSBvZiB7YXRvbWljLCBsaXN0LCB1bmlvbn0gb3IgYWJzZW50LgotICAgICAqLwotICAgIHB1YmxpYyBzaG9ydCBnZXRWYXJpZXR5KCk7Ci0KLSAgICAvKioKLSAgICAgKiBJZiB2YXJpZXR5IGlzIDxjb2RlPmF0b21pYzwvY29kZT4gdGhlIHByaW1pdGl2ZSB0eXBlIGRlZmluaXRpb24gKGEKLSAgICAgKiBidWlsdC1pbiBwcmltaXRpdmUgZGF0YXR5cGUgZGVmaW5pdGlvbiBvciB0aGUgc2ltcGxlIHVyLXR5cGUKLSAgICAgKiBkZWZpbml0aW9uKSBpcyBhdmFpbGFibGUsIG90aGVyd2lzZSA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFNTaW1wbGVUeXBlRGVmaW5pdGlvbiBnZXRQcmltaXRpdmVUeXBlKCk7Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBjbG9zZXN0IGJ1aWx0LWluIHR5cGUgY2F0ZWdvcnkgdGhpcyB0eXBlIHJlcHJlc2VudHMgb3IKLSAgICAgKiBkZXJpdmVkIGZyb20uIEZvciBleGFtcGxlLCBpZiB0aGlzIHNpbXBsZSB0eXBlIGlzIGEgYnVpbHQtaW4gZGVyaXZlZAotICAgICAqIHR5cGUgaW50ZWdlciB0aGUgPGNvZGU+SU5URUdFUl9EVjwvY29kZT4gaXMgcmV0dXJuZWQuCi0gICAgICovCi0gICAgcHVibGljIHNob3J0IGdldEJ1aWx0SW5LaW5kKCk7Ci0KLSAgICAvKioKLSAgICAgKiBJZiB2YXJpZXR5IGlzIDxjb2RlPmxpc3Q8L2NvZGU+IHRoZSBpdGVtIHR5cGUgZGVmaW5pdGlvbiAoYW4gYXRvbWljIG9yCi0gICAgICogdW5pb24gc2ltcGxlIHR5cGUgZGVmaW5pdGlvbikgaXMgYXZhaWxhYmxlLCBvdGhlcndpc2UKLSAgICAgKiA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFNTaW1wbGVUeXBlRGVmaW5pdGlvbiBnZXRJdGVtVHlwZSgpOwotCi0gICAgLyoqCi0gICAgICogSWYgdmFyaWV0eSBpcyA8Y29kZT51bmlvbjwvY29kZT4gdGhlIGxpc3Qgb2YgbWVtYmVyIHR5cGUgZGVmaW5pdGlvbnMgKGEKLSAgICAgKiBub24tZW1wdHkgc2VxdWVuY2Ugb2Ygc2ltcGxlIHR5cGUgZGVmaW5pdGlvbnMpIGlzIGF2YWlsYWJsZSwKLSAgICAgKiBvdGhlcndpc2UgYW4gZW1wdHkgPGNvZGU+WFNPYmplY3RMaXN0PC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFNPYmplY3RMaXN0IGdldE1lbWJlclR5cGVzKCk7Ci0KLSAgICAvKioKLSAgICAgKiBbZmFjZXRzXTogYWxsIGZhY2V0cyBkZWZpbmVkIG9uIHRoaXMgdHlwZS4gVGhlIHZhbHVlIGlzIGEgYml0Ci0gICAgICogY29tYmluYXRpb24gb2YgRkFDRVRfWFhYIGNvbnN0YW50cyBvZiBhbGwgZGVmaW5lZCBmYWNldHMuCi0gICAgICovCi0gICAgcHVibGljIHNob3J0IGdldERlZmluZWRGYWNldHMoKTsKLQotICAgIC8qKgotICAgICAqIENvbnZlbmllbmNlIG1ldGhvZC4gW0ZhY2V0c106IGNoZWNrIHdoZXRoZXIgYSBmYWNldCBpcyBkZWZpbmVkIG9uIHRoaXMKLSAgICAgKiB0eXBlLgotICAgICAqIEBwYXJhbSBmYWNldE5hbWUgIFRoZSBuYW1lIG9mIHRoZSBmYWNldC4KLSAgICAgKiBAcmV0dXJuICBUcnVlIGlmIHRoZSBmYWNldCBpcyBkZWZpbmVkLCBmYWxzZSBvdGhlcndpc2UuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNEZWZpbmVkRmFjZXQoc2hvcnQgZmFjZXROYW1lKTsKLQotICAgIC8qKgotICAgICAqIFtmYWNldHNdOiBhbGwgZGVmaW5lZCBmYWNldHMgZm9yIHRoaXMgdHlwZSB3aGljaCBhcmUgZml4ZWQuCi0gICAgICovCi0gICAgcHVibGljIHNob3J0IGdldEZpeGVkRmFjZXRzKCk7Ci0KLSAgICAvKioKLSAgICAgKiBDb252ZW5pZW5jZSBtZXRob2QuIFtGYWNldHNdOiBjaGVjayB3aGV0aGVyIGEgZmFjZXQgaXMgZGVmaW5lZCBhbmQKLSAgICAgKiBmaXhlZCBvbiB0aGlzIHR5cGUuCi0gICAgICogQHBhcmFtIGZhY2V0TmFtZSAgVGhlIG5hbWUgb2YgdGhlIGZhY2V0LgotICAgICAqIEByZXR1cm4gIFRydWUgaWYgdGhlIGZhY2V0IGlzIGZpeGVkLCBmYWxzZSBvdGhlcndpc2UuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNGaXhlZEZhY2V0KHNob3J0IGZhY2V0TmFtZSk7Ci0KLSAgICAvKioKLSAgICAgKiBDb252ZW5pZW5jZSBtZXRob2QuIFJldHVybnMgYSB2YWx1ZSBvZiBhIHNpbmdsZSBjb25zdHJhaW5pbmcgZmFjZXQgZm9yCi0gICAgICogdGhpcyBzaW1wbGUgdHlwZSBkZWZpbml0aW9uLiBUaGlzIG1ldGhvZCBtdXN0IG5vdCBiZSB1c2VkIHRvIHJldHJpZXZlCi0gICAgICogdmFsdWVzIGZvciA8Y29kZT5lbnVtZXJhdGlvbjwvY29kZT4gYW5kIDxjb2RlPnBhdHRlcm48L2NvZGU+IGZhY2V0cy4KLSAgICAgKiBAcGFyYW0gZmFjZXROYW1lIFRoZSBuYW1lIG9mIHRoZSBmYWNldCwgaS5lLgotICAgICAqICAgPGNvZGU+RkFDRVRfTEVOR1RILCBGQUNFVF9UT1RBTERJR0lUUzwvY29kZT4uCi0gICAgICogICBUbyByZXRyaWV2ZSB0aGUgdmFsdWUgZm9yIGEgcGF0dGVybiBvcgotICAgICAqICAgYW4gZW51bWVyYXRpb24sIHNlZSA8Y29kZT5lbnVtZXJhdGlvbjwvY29kZT4gYW5kCi0gICAgICogICA8Y29kZT5wYXR0ZXJuPC9jb2RlPi4KLSAgICAgKiBAcmV0dXJuIEEgdmFsdWUgb2YgdGhlIGZhY2V0IHNwZWNpZmllZCBpbiA8Y29kZT5mYWNldE5hbWU8L2NvZGU+IGZvcgotICAgICAqICAgdGhpcyBzaW1wbGUgdHlwZSBkZWZpbml0aW9uIG9yIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TGV4aWNhbEZhY2V0VmFsdWUoc2hvcnQgZmFjZXROYW1lKTsKLQotICAgIC8qKgotICAgICAqIEEgbGlzdCBvZiBlbnVtZXJhdGlvbiB2YWx1ZXMgaWYgaXQgZXhpc3RzLCBvdGhlcndpc2UgYW4gZW1wdHkKLSAgICAgKiA8Y29kZT5TdHJpbmdMaXN0PC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nTGlzdCBnZXRMZXhpY2FsRW51bWVyYXRpb24oKTsKLQotICAgIC8qKgotICAgICAqIEEgbGlzdCBvZiBwYXR0ZXJuIHZhbHVlcyBpZiBpdCBleGlzdHMsIG90aGVyd2lzZSBhbiBlbXB0eQotICAgICAqIDxjb2RlPlN0cmluZ0xpc3Q8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmdMaXN0IGdldExleGljYWxQYXR0ZXJuKCk7Ci0KLSAgICAvKioKLSAgICAgKiAgRnVuZGFtZW50YWwgRmFjZXQ6IG9yZGVyZWQuCi0gICAgICovCi0gICAgcHVibGljIHNob3J0IGdldE9yZGVyZWQoKTsKLQotICAgIC8qKgotICAgICAqIEZ1bmRhbWVudGFsIEZhY2V0OiBjYXJkaW5hbGl0eS4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXRGaW5pdGUoKTsKLQotICAgIC8qKgotICAgICAqIEZ1bmRhbWVudGFsIEZhY2V0OiBib3VuZGVkLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGdldEJvdW5kZWQoKTsKLQotICAgIC8qKgotICAgICAqIEZ1bmRhbWVudGFsIEZhY2V0OiBudW1lcmljLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGdldE51bWVyaWMoKTsKLQotICAgIC8qKgotICAgICAqICBBIGxpc3Qgb2YgY29uc3RyYWluaW5nIGZhY2V0cyBpZiBpdCBleGlzdHMsIG90aGVyd2lzZSBhbiBlbXB0eQotICAgICAqIDxjb2RlPlhTT2JqZWN0TGlzdDwvY29kZT4uIE5vdGU6IFRoaXMgbWV0aG9kIG11c3Qgbm90IGJlIHVzZWQgdG8KLSAgICAgKiByZXRyaWV2ZSB2YWx1ZXMgZm9yIDxjb2RlPmVudW1lcmF0aW9uPC9jb2RlPiBhbmQgPGNvZGU+cGF0dGVybjwvY29kZT4KLSAgICAgKiBmYWNldHMuCi0gICAgICovCi0gICAgcHVibGljIFhTT2JqZWN0TGlzdCBnZXRGYWNldHMoKTsKLQotICAgIC8qKgotICAgICAqICBBIGxpc3Qgb2YgZW51bWVyYXRpb24gYW5kIHBhdHRlcm4gY29uc3RyYWluaW5nIGZhY2V0cyBpZiBpdCBleGlzdHMsCi0gICAgICogb3RoZXJ3aXNlIGFuIGVtcHR5IDxjb2RlPlhTT2JqZWN0TGlzdDwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIFhTT2JqZWN0TGlzdCBnZXRNdWx0aVZhbHVlRmFjZXRzKCk7Ci0KLSAgICAvKioKLSAgICAgKiBBIHNlcXVlbmNlIG9mIFthbm5vdGF0aW9uc10gb3IgYW4gZW1wdHkgPGNvZGU+WFNPYmplY3RMaXN0PC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFNPYmplY3RMaXN0IGdldEFubm90YXRpb25zKCk7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3hzL1hTVGVybS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHMvWFNUZXJtLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDEyODc4MzkuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHMvWFNUZXJtLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzMCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAzLDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHM7Ci0KLS8qKgotICogRGVzY3JpYmVzIGEgdGVybSB0aGF0IGNhbiBiZSBvbmUgb2YgYSBtb2RlbCBncm91cCwgYSB3aWxkY2FyZCwgb3IgYW4KLSAqIGVsZW1lbnQgZGVjbGFyYXRpb24uIE9iamVjdHMgaW1wbGVtZW50aW5nCi0gKiA8Y29kZT5YU0VsZW1lbnREZWNsYXJhdGlvbjwvY29kZT4sIDxjb2RlPlhTTW9kZWxHcm91cDwvY29kZT4gYW5kCi0gKiA8Y29kZT5YU1dpbGRjYXJkPC9jb2RlPiBpbnRlcmZhY2VzIGFsc28gaW1wbGVtZW50IHRoaXMgaW50ZXJmYWNlLgotICovCi1wdWJsaWMgaW50ZXJmYWNlIFhTVGVybSBleHRlbmRzIFhTT2JqZWN0IHsKLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3hzL1hTVHlwZURlZmluaXRpb24uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3hzL1hTVHlwZURlZmluaXRpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggM2M0Y2M5Ni4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94cy9YU1R5cGVEZWZpbml0aW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMDUgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMywyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzOwotCi0vKioKLSAqIFRoaXMgaW50ZXJmYWNlIHJlcHJlc2VudHMgYSBjb21wbGV4IG9yIHNpbXBsZSB0eXBlIGRlZmluaXRpb24uCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgWFNUeXBlRGVmaW5pdGlvbiBleHRlbmRzIFhTT2JqZWN0IHsKLSAgICAvKioKLSAgICAgKiBUaGUgb2JqZWN0IGRlc2NyaWJlcyBhIGNvbXBsZXggdHlwZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IENPTVBMRVhfVFlQRSAgICAgICAgICAgICAgPSAxNTsKLSAgICAvKioKLSAgICAgKiBUaGUgb2JqZWN0IGRlc2NyaWJlcyBhIHNpbXBsZSB0eXBlLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgU0lNUExFX1RZUEUgICAgICAgICAgICAgICA9IDE2OwotICAgIC8qKgotICAgICAqIFJldHVybiB3aGV0aGVyIHRoaXMgdHlwZSBkZWZpbml0aW9uIGlzIGEgc2ltcGxlIHR5cGUgb3IgY29tcGxleCB0eXBlLgotICAgICAqLwotICAgIHB1YmxpYyBzaG9ydCBnZXRUeXBlQ2F0ZWdvcnkoKTsKLQotICAgIC8qKgotICAgICAqIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn06IGVpdGhlciBhIHNpbXBsZSB0eXBlIGRlZmluaXRpb24gb3IgYSBjb21wbGV4Ci0gICAgICogdHlwZSBkZWZpbml0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBYU1R5cGVEZWZpbml0aW9uIGdldEJhc2VUeXBlKCk7Ci0KLSAgICAvKioKLSAgICAgKiB7ZmluYWx9LiBGb3IgYSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbiBpdCBpcyBhIHN1YnNldCBvZiB7ZXh0ZW5zaW9uLAotICAgICAqIHJlc3RyaWN0aW9ufS4gRm9yIGEgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiBpdCBpcyBhIHN1YnNldCBvZgotICAgICAqIHtleHRlbnNpb24sIGxpc3QsIHJlc3RyaWN0aW9uLCB1bmlvbn0uCi0gICAgICogQHBhcmFtIHJlc3RyaWN0aW9uICBFeHRlbnNpb24sIHJlc3RyaWN0aW9uLCBsaXN0LCB1bmlvbiBjb25zdGFudHMKLSAgICAgKiAgIChkZWZpbmVkIGluIDxjb2RlPlhTQ29uc3RhbnRzPC9jb2RlPikuCi0gICAgICogQHJldHVybiBUcnVlIGlmIDxjb2RlPnJlc3RyaWN0aW9uPC9jb2RlPiBpcyBpbiB0aGUgZmluYWwgc2V0LAotICAgICAqICAgb3RoZXJ3aXNlIGZhbHNlLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzRmluYWwoc2hvcnQgcmVzdHJpY3Rpb24pOwotCi0gICAgLyoqCi0gICAgICogRm9yIGNvbXBsZXggdHlwZXMgdGhlIHJldHVybmVkIHZhbHVlIGlzIGEgYml0IGNvbWJpbmF0aW9uIG9mIHRoZSBzdWJzZXQKLSAgICAgKiBvZiB7PGNvZGU+REVSSVZBVElPTl9FWFRFTlNJT04sIERFUklWQVRJT05fUkVTVFJJQ1RJT048L2NvZGU+fQotICAgICAqIGNvcnJlc3BvbmRpbmcgdG8gPGNvZGU+ZmluYWw8L2NvZGU+IHNldCBvZiB0aGlzIHR5cGUgb3IKLSAgICAgKiA8Y29kZT5ERVJJVkFUSU9OX05PTkU8L2NvZGU+LiBGb3Igc2ltcGxlIHR5cGVzIHRoZSByZXR1cm5lZCB2YWx1ZSBpcwotICAgICAqIGEgYml0IGNvbWJpbmF0aW9uIG9mIHRoZSBzdWJzZXQgb2YgewotICAgICAqIDxjb2RlPkRFUklWQVRJT05fUkVTVFJJQ1RJT04sIERFUklWQVRJT05fRVhURU5TSU9OLCBERVJJVkFUSU9OX1VOSU9OLCBERVJJVkFUSU9OX0xJU1Q8L2NvZGU+Ci0gICAgICogfSBjb3JyZXNwb25kaW5nIHRvIDxjb2RlPmZpbmFsPC9jb2RlPiBzZXQgb2YgdGhpcyB0eXBlIG9yCi0gICAgICogPGNvZGU+REVSSVZBVElPTl9OT05FPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgc2hvcnQgZ2V0RmluYWwoKTsKLQotICAgIC8qKgotICAgICAqICBDb252ZW5pZW5jZSBhdHRyaWJ1dGUuIEEgYm9vbGVhbiB0aGF0IHNwZWNpZmllcyBpZiB0aGUgdHlwZSBkZWZpbml0aW9uCi0gICAgICogaXMgYW5vbnltb3VzLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGdldEFub255bW91cygpOwotCi0gICAgLyoqCi0gICAgICogQ29udmVuaWVuY2UgbWV0aG9kIHdoaWNoIGNoZWNrcyBpZiB0aGlzIHR5cGUgaXMgZGVyaXZlZCBmcm9tIHRoZSBnaXZlbgotICAgICAqIDxjb2RlPmFuY2VzdG9yVHlwZTwvY29kZT4uCi0gICAgICogQHBhcmFtIGFuY2VzdG9yVHlwZSAgQW4gYW5jZXN0b3IgdHlwZSBkZWZpbml0aW9uLgotICAgICAqIEBwYXJhbSBkZXJpdmF0aW9uTWV0aG9kICBBIGJpdCBjb21iaW5hdGlvbiByZXByZXNlbnRpbmcgYSBzdWJzZXQgb2YgewotICAgICAqICAgPGNvZGU+REVSSVZBVElPTl9SRVNUUklDVElPTiwgREVSSVZBVElPTl9FWFRFTlNJT04sIERFUklWQVRJT05fVU5JT04sIERFUklWQVRJT05fTElTVDwvY29kZT4KLSAgICAgKiAgIH0uCi0gICAgICogQHJldHVybiAgVHJ1ZSBpZiB0aGlzIHR5cGUgaXMgZGVyaXZlZCBmcm9tIDxjb2RlPmFuY2VzdG9yVHlwZTwvY29kZT4KLSAgICAgKiAgIHVzaW5nIG9ubHkgZGVyaXZhdGlvbiBtZXRob2RzIGZyb20gdGhlIDxjb2RlPmRlcml2YXRpb25NZXRob2Q8L2NvZGU+Ci0gICAgICogICAuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZGVyaXZlZEZyb21UeXBlKFhTVHlwZURlZmluaXRpb24gYW5jZXN0b3JUeXBlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaG9ydCBkZXJpdmF0aW9uTWV0aG9kKTsKLQotICAgIC8qKgotICAgICAqIENvbnZlbmllbmNlIG1ldGhvZCB3aGljaCBjaGVja3MgaWYgdGhpcyB0eXBlIGlzIGRlcml2ZWQgZnJvbSB0aGUgZ2l2ZW4KLSAgICAgKiBhbmNlc3RvciB0eXBlLgotICAgICAqIEBwYXJhbSBuYW1lc3BhY2UgIEFuIGFuY2VzdG9yIHR5cGUgbmFtZXNwYWNlLgotICAgICAqIEBwYXJhbSBuYW1lICBBbiBhbmNlc3RvciB0eXBlIG5hbWUuCi0gICAgICogQHBhcmFtIGRlcml2YXRpb25NZXRob2QgIEEgYml0IGNvbWJpbmF0aW9uIHJlcHJlc2VudGluZyBhIHN1YnNldCBvZiB7Ci0gICAgICogICA8Y29kZT5ERVJJVkFUSU9OX1JFU1RSSUNUSU9OLCBERVJJVkFUSU9OX0VYVEVOU0lPTiwgREVSSVZBVElPTl9VTklPTiwgREVSSVZBVElPTl9MSVNUPC9jb2RlPgotICAgICAqICAgfS4KLSAgICAgKiBAcmV0dXJuICBUcnVlIGlmIHRoaXMgdHlwZSBpcyBkZXJpdmVkIGZyb20gPGNvZGU+YW5jZXN0b3JUeXBlPC9jb2RlPgotICAgICAqICAgdXNpbmcgb25seSBkZXJpdmF0aW9uIG1ldGhvZHMgZnJvbSB0aGUgPGNvZGU+ZGVyaXZhdGlvbk1ldGhvZDwvY29kZT4KLSAgICAgKiAgIC4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBkZXJpdmVkRnJvbShTdHJpbmcgbmFtZXNwYWNlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBuYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNob3J0IGRlcml2YXRpb25NZXRob2QpOwotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94cy9YU1dpbGRjYXJkLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94cy9YU1dpbGRjYXJkLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGVlNjhmNDkuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHMvWFNXaWxkY2FyZC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTAgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMywyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzOwotCi0vKioKLSAqIFRoaXMgaW50ZXJmYWNlIHJlcHJlc2VudHMgdGhlIFdpbGRjYXJkIHNjaGVtYSBjb21wb25lbnQuCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgWFNXaWxkY2FyZCBleHRlbmRzIFhTVGVybSB7Ci0gICAgLy8gTmFtZXNwYWNlIENvbnN0cmFpbnQKLSAgICAvKioKLSAgICAgKiBOYW1lc3BhY2UgQ29uc3RyYWludDogYW55IG5hbWVzcGFjZSBpcyBhbGxvd2VkLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgTlNDT05TVFJBSU5UX0FOWSAgICAgICAgICA9IDE7Ci0gICAgLyoqCi0gICAgICogTmFtZXNwYWNlIENvbnN0cmFpbnQ6IG5hbWVzcGFjZXMgaW4gdGhlIGxpc3QgYXJlIG5vdCBhbGxvd2VkLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgTlNDT05TVFJBSU5UX05PVCAgICAgICAgICA9IDI7Ci0gICAgLyoqCi0gICAgICogTmFtZXNwYWNlIENvbnN0cmFpbnQ6IG5hbWVzcGFjZXMgaW4gdGhlIGxpc3QgYXJlIGFsbG93ZWQuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBOU0NPTlNUUkFJTlRfTElTVCAgICAgICAgID0gMzsKLQotICAgIC8vIFByb2Nlc3MgY29udGVudHMKLSAgICAvKioKLSAgICAgKiBUaGVyZSBtdXN0IGJlIGEgdG9wLWxldmVsIGRlY2xhcmF0aW9uIGZvciB0aGUgaXRlbSBhdmFpbGFibGUsIG9yIHRoZQotICAgICAqIGl0ZW0gbXVzdCBoYXZlIGFuIHhzaTp0eXBlLCBhbmQgdGhlIGl0ZW0gbXVzdCBiZSB2YWxpZCBhcyBhcHByb3ByaWF0ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFBDX1NUUklDVCAgICAgICAgICAgICAgICAgPSAxOwotICAgIC8qKgotICAgICAqIE5vIGNvbnN0cmFpbnRzIGF0IGFsbDogdGhlIGl0ZW0gbXVzdCBzaW1wbHkgYmUgd2VsbC1mb3JtZWQgWE1MLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgUENfU0tJUCAgICAgICAgICAgICAgICAgICA9IDI7Ci0gICAgLyoqCi0gICAgICogSWYgdGhlIGl0ZW0sIG9yIGFueSBpdGVtcyBhbW9uZyBpdHMgW2NoaWxkcmVuXSBpcyBhbiBlbGVtZW50Ci0gICAgICogaW5mb3JtYXRpb24gaXRlbSwgaGFzIGEgdW5pcXVlbHkgZGV0ZXJtaW5lZCBkZWNsYXJhdGlvbiBhdmFpbGFibGUsIGl0Ci0gICAgICogbXVzdCBiZSB2YWxpZCB3aXRoIHJlc3BlY3QgdG8gdGhhdCBkZWZpbml0aW9uLCB0aGF0IGlzLCB2YWxpZGF0ZQotICAgICAqIHdoZXJlIHlvdSBjYW4gYW5kIGRvIG5vdCB3b3JyeSB3aGVuIHlvdSBjYW5ub3QuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBQQ19MQVggICAgICAgICAgICAgICAgICAgID0gMzsKLQotICAgIC8qKgotICAgICAqIE5hbWVzcGFjZSBjb25zdHJhaW50OiBBIGNvbnN0cmFpbnQgdHlwZTogYW55LCBub3QsIGxpc3QuCi0gICAgICovCi0gICAgcHVibGljIHNob3J0IGdldENvbnN0cmFpbnRUeXBlKCk7Ci0KLSAgICAvKioKLSAgICAgKiBOYW1lc3BhY2UgY29uc3RyYWludDogRm9yIDxjb2RlPmNvbnN0cmFpbnRUeXBlPC9jb2RlPgotICAgICAqIDxjb2RlPk5TQ09OU1RSQUlOVF9MSVNUPC9jb2RlPiwgdGhlIGxpc3QgY29udGFpbnMgYWxsb3dlZCBuYW1lc3BhY2VzLgotICAgICAqIEZvciA8Y29kZT5jb25zdHJhaW50VHlwZTwvY29kZT4gPGNvZGU+TlNDT05TVFJBSU5UX05PVDwvY29kZT4sIHRoZQotICAgICAqIGxpc3QgY29udGFpbnMgZGlzYWxsb3dlZCBuYW1lc3BhY2VzLiBGb3IgPGNvZGU+Y29uc3RyYWludFR5cGU8L2NvZGU+Ci0gICAgICogPGNvZGU+TlNDT05TVFJBSU5UX0FOWTwvY29kZT4sIHRoZSA8Y29kZT5TdHJpbmdMaXN0PC9jb2RlPiBpcyBlbXB0eS4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nTGlzdCBnZXROc0NvbnN0cmFpbnRMaXN0KCk7Ci0KLSAgICAvKioKLSAgICAgKiBbcHJvY2VzcyBjb250ZW50c106IG9uZSBvZiBza2lwLCBsYXggb3Igc3RyaWN0LiBWYWxpZCBjb25zdGFudHMgdmFsdWVzCi0gICAgICogYXJlOiA8Y29kZT5QQ19MQVg8L2NvZGU+LCA8Y29kZT5QQ19TS0lQPC9jb2RlPiBhbmQKLSAgICAgKiA8Y29kZT5QQ19TVFJJQ1Q8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBzaG9ydCBnZXRQcm9jZXNzQ29udGVudHMoKTsKLQotICAgIC8qKgotICAgICAqIEFuIGFubm90YXRpb24gaWYgaXQgZXhpc3RzLCBvdGhlcndpc2UgPGNvZGU+bnVsbDwvY29kZT4uIElmIG5vdCBudWxsCi0gICAgICogdGhlbiB0aGUgZmlyc3QgW2Fubm90YXRpb25dIGZyb20gdGhlIHNlcXVlbmNlIG9mIGFubm90YXRpb25zLgotICAgICAqLwotICAgIHB1YmxpYyBYU0Fubm90YXRpb24gZ2V0QW5ub3RhdGlvbigpOwotCi0gICAgLyoqCi0gICAgICogQSBzZXF1ZW5jZSBvZiBbYW5ub3RhdGlvbnNdIG9yIGFuIGVtcHR5IDxjb2RlPlhTT2JqZWN0TGlzdDwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIFhTT2JqZWN0TGlzdCBnZXRBbm5vdGF0aW9ucygpOwotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHMvZGF0YXR5cGVzL0J5dGVMaXN0LmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94cy9kYXRhdHlwZXMvQnl0ZUxpc3QuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYTExMzg0MC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94cy9kYXRhdHlwZXMvQnl0ZUxpc3QuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDY0ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDQsMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuZGF0YXR5cGVzOwotCi1pbXBvcnQgamF2YS51dGlsLkxpc3Q7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLlhTRXhjZXB0aW9uOwotCi0vKioKLSAqIDxwPlRoZSA8Y29kZT5CeXRlTGlzdDwvY29kZT4gaXMgYW4gaW1tdXRhYmxlIG9yZGVyZWQgY29sbGVjdGlvbiBvZgotICogPGNvZGU+Ynl0ZTwvY29kZT4uPC9wPgotICoKLSAqIEBhdXRob3IgQW5raXQgUGFzcmljaGEsIElCTQotICoKLSAqIEB2ZXJzaW9uICRJZDogQnl0ZUxpc3QuamF2YSx2IDEuNyAyMDEwLTExLTAxIDA0OjQwOjMxIGpvZWh3IEV4cCAkCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgQnl0ZUxpc3QgZXh0ZW5kcyBMaXN0IHsKLQotICAgIC8qKgotICAgICAqIFRoZSBudW1iZXIgb2YgPGNvZGU+Ynl0ZTwvY29kZT5zIGluIHRoZSBsaXN0LiBUaGUgcmFuZ2Ugb2YKLSAgICAgKiB2YWxpZCBjaGlsZCBvYmplY3QgaW5kaWNlcyBpcyAwIHRvIDxjb2RlPmxlbmd0aC0xPC9jb2RlPiBpbmNsdXNpdmUuCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRMZW5ndGgoKTsKLQotICAgIC8qKgotICAgICAqIENoZWNrcyBpZiB0aGUgPGNvZGU+Ynl0ZTwvY29kZT4gPGNvZGU+aXRlbTwvY29kZT4gaXMgYQotICAgICAqIG1lbWJlciBvZiB0aGlzIGxpc3QuCi0gICAgICogQHBhcmFtIGl0ZW0gIDxjb2RlPmJ5dGU8L2NvZGU+IHdob3NlIHByZXNlbmNlIGluIHRoaXMgbGlzdAotICAgICAqICAgaXMgdG8gYmUgdGVzdGVkLgotICAgICAqIEByZXR1cm4gIFRydWUgaWYgdGhpcyBsaXN0IGNvbnRhaW5zIHRoZSA8Y29kZT5ieXRlPC9jb2RlPgotICAgICAqICAgPGNvZGU+aXRlbTwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gY29udGFpbnMoYnl0ZSBpdGVtKTsKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIDxjb2RlPmluZGV4PC9jb2RlPnRoIGl0ZW0gaW4gdGhlIGNvbGxlY3Rpb24uIFRoZSBpbmRleAotICAgICAqIHN0YXJ0cyBhdCAwLgotICAgICAqIEBwYXJhbSBpbmRleCAgaW5kZXggaW50byB0aGUgY29sbGVjdGlvbi4KLSAgICAgKiBAcmV0dXJuICBUaGUgPGNvZGU+Ynl0ZTwvY29kZT4gYXQgdGhlIDxjb2RlPmluZGV4PC9jb2RlPnRoCi0gICAgICogICBwb3NpdGlvbiBpbiB0aGUgPGNvZGU+Qnl0ZUxpc3Q8L2NvZGU+LgotICAgICAqIEBleGNlcHRpb24gWFNFeGNlcHRpb24KLSAgICAgKiAgIElOREVYX1NJWkVfRVJSOiBpZiA8Y29kZT5pbmRleDwvY29kZT4gaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHRoZQotICAgICAqICAgbnVtYmVyIG9mIG9iamVjdHMgaW4gdGhlIGxpc3Qgb3IgbGVzcyB0aGFuIHplcm8uCi0gICAgICovCi0gICAgcHVibGljIGJ5dGUgaXRlbShpbnQgaW5kZXgpIHRocm93cyBYU0V4Y2VwdGlvbjsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHMvZGF0YXR5cGVzL09iamVjdExpc3QuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3hzL2RhdGF0eXBlcy9PYmplY3RMaXN0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGM0Nzg1M2YuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHMvZGF0YXR5cGVzL09iamVjdExpc3QuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDYyICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDQsMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMuZGF0YXR5cGVzOwotCi1pbXBvcnQgamF2YS51dGlsLkxpc3Q7Ci0KLS8qKgotICogPHA+VGhlIDxjb2RlPk9iamVjdExpc3Q8L2NvZGU+IGlzIGFuIGltbXV0YWJsZSBvcmRlcmVkIGNvbGxlY3Rpb24gb2YKLSAqIDxjb2RlPk9iamVjdDwvY29kZT4uPC9wPgotICoKLSAqIEBhdXRob3IgQW5raXQgUGFzcmljaGEsIElCTQotICoKLSAqIEB2ZXJzaW9uICRJZDogT2JqZWN0TGlzdC5qYXZhLHYgMS43IDIwMTAtMTEtMDEgMDQ6NDA6MzEgam9laHcgRXhwICQKLSAqLwotcHVibGljIGludGVyZmFjZSBPYmplY3RMaXN0IGV4dGVuZHMgTGlzdCB7Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgbnVtYmVyIG9mIDxjb2RlPk9iamVjdDwvY29kZT5zIGluIHRoZSBsaXN0LiBUaGUgcmFuZ2Ugb2YKLSAgICAgKiB2YWxpZCBjaGlsZCBvYmplY3QgaW5kaWNlcyBpcyAwIHRvIDxjb2RlPmxlbmd0aC0xPC9jb2RlPiBpbmNsdXNpdmUuCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRMZW5ndGgoKTsKLQotICAgIC8qKgotICAgICAqIENoZWNrcyBpZiB0aGUgPGNvZGU+T2JqZWN0PC9jb2RlPiA8Y29kZT5pdGVtPC9jb2RlPiBpcyBhCi0gICAgICogbWVtYmVyIG9mIHRoaXMgbGlzdC4KLSAgICAgKiBAcGFyYW0gaXRlbSAgPGNvZGU+T2JqZWN0PC9jb2RlPiB3aG9zZSBwcmVzZW5jZSBpbiB0aGlzIGxpc3QKLSAgICAgKiAgIGlzIHRvIGJlIHRlc3RlZC4KLSAgICAgKiBAcmV0dXJuICBUcnVlIGlmIHRoaXMgbGlzdCBjb250YWlucyB0aGUgPGNvZGU+T2JqZWN0PC9jb2RlPgotICAgICAqICAgPGNvZGU+aXRlbTwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gY29udGFpbnMoT2JqZWN0IGl0ZW0pOwotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgPGNvZGU+aW5kZXg8L2NvZGU+dGggaXRlbSBpbiB0aGUgY29sbGVjdGlvbiBvcgotICAgICAqIDxjb2RlPm51bGw8L2NvZGU+IGlmIDxjb2RlPmluZGV4PC9jb2RlPiBpcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8KLSAgICAgKiB0aGUgbnVtYmVyIG9mIG9iamVjdHMgaW4gdGhlIGxpc3QuIFRoZSBpbmRleCBzdGFydHMgYXQgMC4KLSAgICAgKiBAcGFyYW0gaW5kZXggIGluZGV4IGludG8gdGhlIGNvbGxlY3Rpb24uCi0gICAgICogQHJldHVybiAgVGhlIDxjb2RlPk9iamVjdDwvY29kZT4gYXQgdGhlIDxjb2RlPmluZGV4PC9jb2RlPnRoCi0gICAgICogICBwb3NpdGlvbiBpbiB0aGUgPGNvZGU+T2JqZWN0TGlzdDwvY29kZT4sIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmCi0gICAgICogICB0aGUgaW5kZXggc3BlY2lmaWVkIGlzIG5vdCB2YWxpZCAtIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byB0aGUKLSAgICAgKiAgIG51bWJlciBvZiBpdGVtcyBpbiB0aGUgbGlzdCBvciBsZXNzIHRoYW4gemVyby4KLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0IGl0ZW0oaW50IGluZGV4KTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHMvZGF0YXR5cGVzL1hTRGF0ZVRpbWUuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3hzL2RhdGF0eXBlcy9YU0RhdGVUaW1lLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGQwODMyOTAuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHMvZGF0YXR5cGVzL1hTRGF0ZVRpbWUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI5MyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDA0LDIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLmRhdGF0eXBlczsKLQotaW1wb3J0IGphdmF4LnhtbC5kYXRhdHlwZS5EdXJhdGlvbjsKLWltcG9ydCBqYXZheC54bWwuZGF0YXR5cGUuWE1MR3JlZ29yaWFuQ2FsZW5kYXI7Ci0KLS8qKgotICogPHA+SW50ZXJmYWNlIHRvIGV4cG9zZSB0aGUgdmFsdWVzIGZvciBhbGwgZGF0ZS10aW1lIHJlbGF0ZWQgdHlwZXMuIFRoZSBmb2xsb3dpbmcKLSAqIHRhYmxlIHNob3dzIHRoZSBtZXRob2RzIGRlZmluZWQgZm9yIHZhcmlvdXMgWE1MIFNjaGVtYSAxLjAgYnVpbHQtaW4gdHlwZXMuICdYJwotICogbWFya3Mgd2hldGhlciBhIHBhcnRpY3VsYXIgbWV0aG9kIGlzIGRlZmluZWQgZm9yIGEgcGFydGljdWxhciB0eXBlLiBBY2Nlc3NpbmcgdW5kZWZpbmVkCi0gKiBtZXRob2RzIG1heSByZXR1cm4gdW5leHBlY3RlZCB2YWx1ZXMuCi0gKgotICogPHRhYmxlIGJvcmRlcj0iMSI+Ci0gKiA8YnIvPgotICogPHRyPgotICogPHRkPiBYTUwgU2NoZW1hIERhdGF0eXBlIDwvdGQ+Ci0gKiA8dGQ+IGdldFllYXJzKCkgPC90ZD4KLSAqIDx0ZD4gZ2V0TW9udGhzKCkgPC90ZD4KLSAqIDx0ZD4gZ2V0RGF5cygpIDwvdGQ+Ci0gKiA8dGQ+IGdldEhvdXJzKCkgPC90ZD4KLSAqIDx0ZD4gZ2V0TWludXRlcygpIDwvdGQ+Ci0gKiA8dGQ+IGdldFNlY29uZHMoKSA8L3RkPgotICogPHRkPiBnZXRUaW1lWm9uZUhvdXJzKCkgPC90ZD4KLSAqIDx0ZD4gZ2V0VGltZVpvbmVNaW51dGVzKCkgPC90ZD4KLSAqIDx0ZD4gZ2V0WE1MR3JlZ29yaWFuQ2FsZW5kYXIoKSA8L3RkPgotICogPHRkPiBnZXREdXJhdGlvbigpIDwvdGQ+Ci0gKiA8dGQ+IGhhc1RpbWVab25lKCkgPC90ZD4KLSAqIDx0ZD4gbm9ybWFsaXplKCkgPC90ZD4KLSAqIDx0ZD4gaXNOb3JtYWxpemVkKCkgPC90ZD4KLSAqIDx0ZD4gZ2V0TGV4aWNhbFZhbHVlKCkgPC90ZD4KLSAqIDwvdHI+Ci0gKiA8dHI+Ci0gKiA8dGQ+IGdZZWFyIDwvdGQ+Ci0gKiA8dGQ+WDwvdGQ+Ci0gKiA8dGQ+LTwvdGQ+Ci0gKiA8dGQ+LTwvdGQ+Ci0gKiA8dGQ+LTwvdGQ+Ci0gKiA8dGQ+LTwvdGQ+Ci0gKiA8dGQ+LTwvdGQ+Ci0gKiA8dGQ+WDwvdGQ+Ci0gKiA8dGQ+WDwvdGQ+Ci0gKiA8dGQ+WDwvdGQ+Ci0gKiA8dGQ+LTwvdGQ+Ci0gKiA8dGQ+WDwvdGQ+Ci0gKiA8dGQ+WDwvdGQ+Ci0gKiA8dGQ+WDwvdGQ+Ci0gKiA8dGQ+WDwvdGQ+Ci0gKiA8L3RyPgotICogPHRyPgotICogPHRkPiBnTW9udGggPC90ZD4KLSAqIDx0ZD4tPC90ZD4KLSAqIDx0ZD5YPC90ZD4KLSAqIDx0ZD4tPC90ZD4KLSAqIDx0ZD4tPC90ZD4KLSAqIDx0ZD4tPC90ZD4KLSAqIDx0ZD4tPC90ZD4KLSAqIDx0ZD5YPC90ZD4KLSAqIDx0ZD5YPC90ZD4KLSAqIDx0ZD5YPC90ZD4KLSAqIDx0ZD4tPC90ZD4KLSAqIDx0ZD5YPC90ZD4KLSAqIDx0ZD5YPC90ZD4KLSAqIDx0ZD5YPC90ZD4KLSAqIDx0ZD5YPC90ZD4KLSAqIDwvdHI+Ci0gKiA8dHI+Ci0gKiA8dGQ+IGdEYXkgPC90ZD4KLSAqIDx0ZD4tPC90ZD4KLSAqIDx0ZD4tPC90ZD4KLSAqIDx0ZD5YPC90ZD4KLSAqIDx0ZD4tPC90ZD4KLSAqIDx0ZD4tPC90ZD4KLSAqIDx0ZD4tPC90ZD4KLSAqIDx0ZD5YPC90ZD4KLSAqIDx0ZD5YPC90ZD4KLSAqIDx0ZD5YPC90ZD4KLSAqIDx0ZD4tPC90ZD4KLSAqIDx0ZD5YPC90ZD4KLSAqIDx0ZD5YPC90ZD4KLSAqIDx0ZD5YPC90ZD4KLSAqIDx0ZD5YPC90ZD4KLSAqIDwvdHI+Ci0gKiA8dHI+Ci0gKiA8dGQ+IGdZZWFyTW9udGggPC90ZD4KLSAqIDx0ZD5YPC90ZD4KLSAqIDx0ZD5YPC90ZD4KLSAqIDx0ZD4tPC90ZD4KLSAqIDx0ZD4tPC90ZD4KLSAqIDx0ZD4tPC90ZD4KLSAqIDx0ZD4tPC90ZD4KLSAqIDx0ZD5YPC90ZD4KLSAqIDx0ZD5YPC90ZD4KLSAqIDx0ZD5YPC90ZD4KLSAqIDx0ZD4tPC90ZD4KLSAqIDx0ZD5YPC90ZD4KLSAqIDx0ZD5YPC90ZD4KLSAqIDx0ZD5YPC90ZD4KLSAqIDx0ZD5YPC90ZD4KLSAqIDwvdHI+Ci0gKiA8dHI+Ci0gKiA8dGQ+IGdNb250aERheSA8L3RkPgotICogPHRkPi08L3RkPgotICogPHRkPlg8L3RkPgotICogPHRkPlg8L3RkPgotICogPHRkPi08L3RkPgotICogPHRkPi08L3RkPgotICogPHRkPi08L3RkPgotICogPHRkPlg8L3RkPgotICogPHRkPlg8L3RkPgotICogPHRkPlg8L3RkPgotICogPHRkPi08L3RkPgotICogPHRkPlg8L3RkPgotICogPHRkPlg8L3RkPgotICogPHRkPlg8L3RkPgotICogPHRkPlg8L3RkPgotICogPC90cj4KLSAqIDx0cj4KLSAqIDx0ZD4gZGF0ZSA8L3RkPgotICogPHRkPlg8L3RkPgotICogPHRkPlg8L3RkPgotICogPHRkPlg8L3RkPgotICogPHRkPi08L3RkPgotICogPHRkPi08L3RkPgotICogPHRkPi08L3RkPgotICogPHRkPlg8L3RkPgotICogPHRkPlg8L3RkPgotICogPHRkPlg8L3RkPgotICogPHRkPi08L3RkPgotICogPHRkPlg8L3RkPgotICogPHRkPlg8L3RkPgotICogPHRkPlg8L3RkPgotICogPHRkPlg8L3RkPgotICogPC90cj4KLSAqIDx0cj4KLSAqIDx0ZD4gdGltZSA8L3RkPgotICogPHRkPi08L3RkPgotICogPHRkPi08L3RkPgotICogPHRkPi08L3RkPgotICogPHRkPlg8L3RkPgotICogPHRkPlg8L3RkPgotICogPHRkPlg8L3RkPgotICogPHRkPlg8L3RkPgotICogPHRkPlg8L3RkPgotICogPHRkPlg8L3RkPgotICogPHRkPi08L3RkPgotICogPHRkPlg8L3RkPgotICogPHRkPlg8L3RkPgotICogPHRkPlg8L3RkPgotICogPHRkPlg8L3RkPgotICogPC90cj4KLSAqIDx0cj4KLSAqIDx0ZD4gZGF0ZXRpbWUgPC90ZD4KLSAqIDx0ZD5YPC90ZD4KLSAqIDx0ZD5YPC90ZD4KLSAqIDx0ZD5YPC90ZD4KLSAqIDx0ZD5YPC90ZD4KLSAqIDx0ZD5YPC90ZD4KLSAqIDx0ZD5YPC90ZD4KLSAqIDx0ZD5YPC90ZD4KLSAqIDx0ZD5YPC90ZD4KLSAqIDx0ZD5YPC90ZD4KLSAqIDx0ZD4tPC90ZD4KLSAqIDx0ZD5YPC90ZD4KLSAqIDx0ZD5YPC90ZD4KLSAqIDx0ZD5YPC90ZD4KLSAqIDx0ZD5YPC90ZD4KLSAqIDwvdHI+Ci0gKiA8dHI+Ci0gKiA8dGQ+IGR1cmF0aW9uIDwvdGQ+Ci0gKiA8dGQ+LTwvdGQ+Ci0gKiA8dGQ+WDwvdGQ+Ci0gKiA8dGQ+LTwvdGQ+Ci0gKiA8dGQ+LTwvdGQ+Ci0gKiA8dGQ+LTwvdGQ+Ci0gKiA8dGQ+WDwvdGQ+Ci0gKiA8dGQ+LTwvdGQ+Ci0gKiA8dGQ+LTwvdGQ+Ci0gKiA8dGQ+LTwvdGQ+Ci0gKiA8dGQ+WDwvdGQ+Ci0gKiA8dGQ+LTwvdGQ+Ci0gKiA8dGQ+LTwvdGQ+Ci0gKiA8dGQ+LTwvdGQ+Ci0gKiA8dGQ+WDwvdGQ+Ci0gKiA8L3RyPgotICogPC90YWJsZT4KLSAqIDwvcD4KLSAqCi0gKiBAYXV0aG9yIEFua2l0IFBhc3JpY2hhLCBJQk0KLSAqCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgWFNEYXRlVGltZSB7Ci0KLSAgICAvKioKLSAgICAgKiBAcmV0dXJuIHllYXJzIC0gY2FuIGJlIG5lZ2F0aXZlIGZvciBkYXRlLXRpbWUgcmVsYXRlZCB0eXBlczsKLSAgICAgKgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0WWVhcnMoKTsKLQotICAgIC8qKgotICAgICAqIEByZXR1cm4gbW9udGhzIC0gY2FuIGJlIG5lZ2F0aXZlIG9ubHkgZm9yIGR1cmF0aW9uIHR5cGVzOwotICAgICAqICAgICAgICAgICAgICAgICAgRm9yIGR1cmF0aW9uIHR5cGVzLCBpdCByZXR1cm5zIHllYXJzKjEyICsgbW9udGhzCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRNb250aHMoKTsKLQotICAgIC8qKgotICAgICAqIEByZXR1cm4gZGF5cyAtIGNhbm5vdCBiZSBuZWdhdGl2ZTsKLSAgICAgKgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0RGF5cygpOwotCi0gICAgLyoqCi0gICAgICogQHJldHVybiBob3VycyAtIGNhbm5vdCBiZSBuZWdhdGl2ZTsKLSAgICAgKgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0SG91cnMoKTsKLQotICAgIC8qKgotICAgICAqIEByZXR1cm4gbWludXRlcyAtIGNhbm5vdCBiZSBuZWdhdGl2ZTsKLSAgICAgKgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0TWludXRlcygpOwotCi0gICAgLyoqCi0gICAgICogQHJldHVybiBzZWNvbmRzIC0gY2FuIGJlIG5lZ2F0aXZlIG9ubHkgZm9yIGR1cmF0aW9uczsKLSAgICAgKiAgICAgICAgICAgICAgICAgICBGb3IgZHVyYXRpb24gdHlwZXMsIGl0IHJldHVybnMgZGF5cyoyNCozNjAwICsgaG91cnMqMzYwMAotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIG1pbnV0ZXMqNjAgKyBzZWNvbmRzCi0gICAgICovCi0gICAgcHVibGljIGRvdWJsZSBnZXRTZWNvbmRzKCk7Ci0KLSAgICAvKioKLSAgICAgKiBAcmV0dXJuIGJvb2xlYW4gKHRydWUgd2hlbiB0aW1lem9uZSBpcyBzcGVjaWZpZWQgaW4gdGhlIG9yaWdpbmFsIGxleGljYWwgdmFsdWUpCi0gICAgICoKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBoYXNUaW1lWm9uZSgpOwotCi0gICAgLyoqCi0gICAgICogQHJldHVybiB0aW1lem9uZSBob3VycyAoZm9yIEdNVC14eDp4eCB0aGlzIHdpbGwgYmUgbmVnYXRpdmUpLAotICAgICAqCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRUaW1lWm9uZUhvdXJzKCk7Ci0KLSAgICAvKioKLSAgICAgKiBAcmV0dXJuIHRpbWV6b25lIG1pbnV0ZXMgKGZvciBHTVQteHg6eHggdGhpcyB3aWxsIGJlIG5lZ2F0aXZlKSwKLSAgICAgKgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0VGltZVpvbmVNaW51dGVzKCk7Ci0KLSAgICAvKioKLSAgICAgKiBAcmV0dXJuIHRoZSBvcmlnaW5hbCBsZXhpY2FsIHZhbHVlCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRMZXhpY2FsVmFsdWUoKTsKLQotICAgIC8qKgotICAgICAqIEByZXR1cm4gYSBuZXcgZGF0ZS10aW1lIHJlbGF0ZWQgb2JqZWN0IHdpdGggbm9ybWFsaXplZCB2YWx1ZXMKLSAgICAgKiAgICAgICAgIChoYXMgbm8gZWZmZWN0IG9uIG9iamVjdHMgYWxyZWFkeQotICAgICAqICAgICAgICAgIG5vcm1hbGl6ZWQpCi0gICAgICovCi0gICAgcHVibGljIFhTRGF0ZVRpbWUgbm9ybWFsaXplKCk7Ci0KLSAgICAvKioKLSAgICAgKiBAcmV0dXJuIHdoZXRoZXIgYSBkYXRlLXRpbWUgcmVsYXRlZCBvYmplY3QgaXMgbm9ybWFsaXplZCBvciBub3QKLSAgICAgKiAgICAgICAgICh2YWx1ZSBpcyBub3QgdXNlZnVsIGZvciB0eXBlcyB3aGVyZSB0aW1lem9uZSBpcyBub3Qgc3BlY2lmaWVkKQotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzTm9ybWFsaXplZCgpOwotCi0gICAgLyoqCi0gICAgICogQHJldHVybiBhbiB1bi1ub3JtYWxpemVkIFhNTEdyZWdvcmlhbkNhbGVuZGFyIChpZiBhcHBsaWNhYmxlIG90aGVyd2lzZSBudWxsKQotICAgICAqLwotICAgIHB1YmxpYyBYTUxHcmVnb3JpYW5DYWxlbmRhciBnZXRYTUxHcmVnb3JpYW5DYWxlbmRhcigpOwotCi0gICAgLyoqCi0gICAgICogQHJldHVybiBhIER1cmF0aW9uIChpZiBhcHBsaWNhYmxlIG90aGVyd2lzZSBudWxsKQotICAgICAqLwotICAgIHB1YmxpYyBEdXJhdGlvbiBnZXREdXJhdGlvbigpOwotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHMvZGF0YXR5cGVzL1hTRGVjaW1hbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHMvZGF0YXR5cGVzL1hTRGVjaW1hbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyMTcwOTkyLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3hzL2RhdGF0eXBlcy9YU0RlY2ltYWwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDY3ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLmRhdGF0eXBlczsKLQotaW1wb3J0IGphdmEubWF0aC5CaWdEZWNpbWFsOwotaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOwotCi0vKioKLSAqIDxwPkludGVyZmFjZSB0byBleHBvc2UgdGhlIHZhbHVlIG9mICdkZWNpbWFsJyBhbmQgcmVsYXRlZCBkYXRhdHlwZXMuPC9wPgotICoKLSAqIEBhdXRob3IgTmFlbGEgTmlzc2FyLCBJQk0KLSAqCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgWFNEZWNpbWFsIHsKLQotICAgIC8qKgotICAgICAqIEByZXR1cm4gdGhlIDxjb2RlPkJpZ0RlY2ltYWw8L2NvZGU+IHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgb2JqZWN0Ci0gICAgICovCi0gICAgcHVibGljIEJpZ0RlY2ltYWwgZ2V0QmlnRGVjaW1hbCgpOwotCi0gICAgLyoqCi0gICAgICogQHJldHVybiB0aGUgPGNvZGU+QmlnSW50ZWdlcjwvY29kZT4gcmVwcmVzZW50YXRpb24gb2YgdGhpcyBvYmplY3QKLSAgICAgKiBAZXhjZXB0aW9uIE51bWJlckZvcm1hdEV4Y2VwdGlvbiBpZiB0aGUgdmFsdWUgY2Fubm90IGJlIHJlcHJlc2VudGVkIGFzIGEgPGNvZGU+QmlnSW50ZWdlcjwvY29kZT4KLSAgICAgKi8KLSAgICBwdWJsaWMgQmlnSW50ZWdlciBnZXRCaWdJbnRlZ2VyKCkgdGhyb3dzIE51bWJlckZvcm1hdEV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIEByZXR1cm4gdGhlIGxvbmcgdmFsdWUgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBvYmplY3QKLSAgICAgKiBAZXhjZXB0aW9uIE51bWJlckZvcm1hdEV4Y2VwdGlvbiBpZiB0aGUgdmFsdWUgY2Fubm90IGJlIHJlcHJlc2VudGVkIGFzIGEgPGNvZGU+bG9uZzwvY29kZT4KLSAgICAgKi8KLSAgICBwdWJsaWMgbG9uZyBnZXRMb25nKCkgdGhyb3dzIE51bWJlckZvcm1hdEV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIEByZXR1cm4gdGhlIGludCB2YWx1ZSByZXByZXNlbnRhdGlvbiBvZiB0aGlzIG9iamVjdAotICAgICAqIEBleGNlcHRpb24gTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGlmIHRoZSB2YWx1ZSBjYW5ub3QgYmUgcmVwcmVzZW50ZWQgYXMgYSA8Y29kZT5pbnQ8L2NvZGU+Ci0gICAgICovCi0gICAgcHVibGljIGludCBnZXRJbnQoKSB0aHJvd3MgTnVtYmVyRm9ybWF0RXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogQHJldHVybiB0aGUgc2hvcnQgdmFsdWUgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBvYmplY3QKLSAgICAgKiBAZXhjZXB0aW9uIE51bWJlckZvcm1hdEV4Y2VwdGlvbiBpZiB0aGUgdmFsdWUgY2Fubm90IGJlIHJlcHJlc2VudGVkIGFzIGEgPGNvZGU+c2hvcnQ8L2NvZGU+Ci0gICAgICovCi0gICAgcHVibGljIHNob3J0IGdldFNob3J0KCkgdGhyb3dzIE51bWJlckZvcm1hdEV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIEByZXR1cm4gdGhlIGJ5dGUgdmFsdWUgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBvYmplY3QKLSAgICAgKiBAZXhjZXB0aW9uIE51bWJlckZvcm1hdEV4Y2VwdGlvbiBpZiB0aGUgdmFsdWUgY2Fubm90IGJlIHJlcHJlc2VudGVkIGFzIGEgPGNvZGU+Ynl0ZTwvY29kZT4KLSAgICAgKi8KLSAgICBwdWJsaWMgYnl0ZSBnZXRCeXRlKCkgdGhyb3dzIE51bWJlckZvcm1hdEV4Y2VwdGlvbjsKLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3hzL2RhdGF0eXBlcy9YU0RvdWJsZS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHMvZGF0YXR5cGVzL1hTRG91YmxlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGQzY2I3MTUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHMvZGF0YXR5cGVzL1hTRG91YmxlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzNSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDA0LDIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLmRhdGF0eXBlczsKLQotLyoqCi0gKiA8cD5JbnRlcmZhY2UgdG8gZXhwb3NlIHRoZSB2YWx1ZSBvZiB0aGUgJ2RvdWJsZScgZGF0YXR5cGUuPC9wPgotICoKLSAqIEBhdXRob3IgQW5raXQgUGFzcmljaGEsIElCTQotICoKLSAqLwotcHVibGljIGludGVyZmFjZSBYU0RvdWJsZSB7Ci0KLSAgICAvKioKLSAgICAgKiBAcmV0dXJuIGEgZG91YmxlIHZhbHVlCi0gICAgICovCi0gICAgcHVibGljIGRvdWJsZSBnZXRWYWx1ZSgpOwotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94cy9kYXRhdHlwZXMvWFNGbG9hdC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHMvZGF0YXR5cGVzL1hTRmxvYXQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYjdmOGQ2Yi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94cy9kYXRhdHlwZXMvWFNGbG9hdC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzUgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwNCwyMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5kYXRhdHlwZXM7Ci0KLS8qKgotICogPHA+SW50ZXJmYWNlIHRvIGV4cG9zZSB2YWx1ZSBvZiB0aGUgZmxvYXQgZGF0YXR5cGUuPC9wPgotICoKLSAqIEBhdXRob3IgQW5raXQgUGFzcmljaGEsIElCTQotICoKLSAqLwotcHVibGljIGludGVyZmFjZSBYU0Zsb2F0IHsKLQotICAgIC8qKgotICAgICAqIEByZXR1cm4gYSBmbG9hdCB2YWx1ZQotICAgICAqLwotICAgIHB1YmxpYyBmbG9hdCBnZXRWYWx1ZSgpOwotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94cy9kYXRhdHlwZXMvWFNRTmFtZS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94ZXJjZXMvaW50ZXJuYWwveHMvZGF0YXR5cGVzL1hTUU5hbWUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZjc4MGE2MS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94cy9kYXRhdHlwZXMvWFNRTmFtZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzkgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy5kYXRhdHlwZXM7Ci0KLS8qKgotICogSW50ZXJmYWNlIHRvIGV4cG9zZSBRTmFtZSBhY3R1YWwgdmFsdWVzCi0gKgotICogQGF1dGhvciBBbmtpdCBQYXNyaWNoYSwgSUJNCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgWFNRTmFtZSB7Ci0KLSAgICAvKioKLSAgICAgKiBAcmV0dXJuIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlFOYW1lIGNsYXNzIGluc3RhbmNlCi0gICAgICovCi0gICAgcHVibGljIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlFOYW1lIGdldFhOSVFOYW1lKCk7Ci0KLSAgICAvKioKLSAgICAgKiBAcmV0dXJuIGphdmF4LnhtbC5uYW1lc3BhY2UuUU5hbWUgY2xhc3MgaW5zdGFuY2UKLSAgICAgKi8KLSAgICBwdWJsaWMgamF2YXgueG1sLm5hbWVzcGFjZS5RTmFtZSBnZXRKQVhQUU5hbWUoKTsKLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3hzL2RhdGF0eXBlcy9wYWNrYWdlLmh0bWwgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hlcmNlcy9pbnRlcm5hbC94cy9kYXRhdHlwZXMvcGFja2FnZS5odG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2MDIzZjA1Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveGVyY2VzL2ludGVybmFsL3hzL2RhdGF0eXBlcy9wYWNrYWdlLmh0bWwKKysrIC9kZXYvbnVsbApAQCAtMSwzMDkgKzAsMCBAQAotPCEtLQotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLS0tPgotPCFET0NUWVBFIEhUTUwgUFVCTElDICItLy9XM0MvL0RURCBIVE1MIDMuMiBGaW5hbC8vRU4iPgotPGh0bWw+Ci08aGVhZCA+Ci08IS0tCi0KLSAgQ29weXJpZ2h0IDIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICAKLSAgTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gCi0gICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gIAotICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotCi0tLT4KLTwvaGVhZD4KLTxib2R5IGJnY29sb3I9IndoaXRlIj5UaGlzIHBhY2thZ2UgcHJvdmlkZXMgaW50ZXJmYWNlcyBmb3IgYWNjZXNzaW5nIGFjdHVhbCB2YWx1ZSBpbmZvcm1hdGlvbiB0aHJvdWdoIFBTVkkgZm9yIFhNTCBTY2hlbWEgMS4wIGRhdGEgdHlwZXMuCi08QlI+Ci08QlI+Ci1UaGUgdGFibGUgYmVsb3cgZ2l2ZXMgdGhlIGRhdGEgdHlwZSB0byBhcHBsaWNhYmxlIGludGVyZmFjZSBtYXBwaW5nOgotPEJSPgotPEJSPgotPFRBQkxFIGJvcmRlcj0iMSI+Ci0JPFRCT0RZPgotCQk8VFI+Ci0JCQk8VEQgd2lkdGg9IjMzMiIgYWxpZ249ImNlbnRlciI+WE1MIFNjaGVtYSBEYXRhIFR5cGU8L1REPgotCQkJPFREIGFsaWduPSJjZW50ZXIiIHdpZHRoPSIyMDIiPkludGVyZmFjZS9DbGFzczwvVEQ+Ci0JCTwvVFI+Ci0JCTxUUj4KLQkJCTxURCB3aWR0aD0iMzMyIj48L1REPgotCQkJPFREIHdpZHRoPSIyMDIiPjwvVEQ+Ci0JCTwvVFI+Ci0JCTxUUj4KLQkJCTxURCB3aWR0aD0iMzMyIiBhbGlnbj0iY2VudGVyIj5zdHJpbmc8L1REPgotCQkJPFREIHdpZHRoPSIyMDIiIGFsaWduPSJjZW50ZXIiPmphdmEubGFuZy5TdHJpbmc8L1REPgotCQk8L1RSPgotCQk8VFI+Ci0JCQk8VEQgd2lkdGg9IjMzMiIgYWxpZ249ImNlbnRlciI+Ym9vbGVhbjwvVEQ+Ci0JCQk8VEQgd2lkdGg9IjIwMiIgYWxpZ249ImNlbnRlciI+amF2YS5sYW5nLkJvb2xlYW48L1REPgotCQk8L1RSPgotCQk8VFI+Ci0JCQk8VEQgd2lkdGg9IjMzMiIgYWxpZ249ImNlbnRlciI+ZGVjaW1hbDwvVEQ+Ci0JCQk8VEQgd2lkdGg9IjIwMiIgYWxpZ249ImNlbnRlciI+WFNEZWNpbWFsPC9URD4KLQkJPC9UUj4KLQkJPFRSPgotCQkJPFREIHdpZHRoPSIzMzIiIGFsaWduPSJjZW50ZXIiPmZsb2F0PC9URD4KLQkJCTxURCB3aWR0aD0iMjAyIiBhbGlnbj0iY2VudGVyIj5YU0Zsb2F0PC9URD4KLQkJPC9UUj4KLQkJPFRSPgotCQkJPFREIHdpZHRoPSIzMzIiIGFsaWduPSJjZW50ZXIiPmRvdWJsZTwvVEQ+Ci0JCQk8VEQgd2lkdGg9IjIwMiIgYWxpZ249ImNlbnRlciI+WFNEb3VibGU8L1REPgotCQk8L1RSPgotCQk8VFI+Ci0JCQk8VEQgd2lkdGg9IjMzMiIgYWxpZ249ImNlbnRlciI+ZHVyYXRpb248L1REPgotCQkJPFREIHdpZHRoPSIyMDIiIGFsaWduPSJjZW50ZXIiPlhTRGF0ZVRpbWU8L1REPgotCQk8L1RSPgotCQk8VFI+Ci0JCQk8VEQgd2lkdGg9IjMzMiIgYWxpZ249ImNlbnRlciI+ZGF0ZVRpbWU8L1REPgotCQkJPFREIHdpZHRoPSIyMDIiIGFsaWduPSJjZW50ZXIiPlhTRGF0ZVRpbWU8L1REPgotCQk8L1RSPgotCQk8VFI+Ci0JCQk8VEQgd2lkdGg9IjMzMiIgYWxpZ249ImNlbnRlciI+ZGF0ZTwvVEQ+Ci0JCQk8VEQgd2lkdGg9IjIwMiIgYWxpZ249ImNlbnRlciI+WFNEYXRlVGltZTwvVEQ+Ci0JCTwvVFI+Ci0JCTxUUj4KLQkJCTxURCB3aWR0aD0iMzMyIiBhbGlnbj0iY2VudGVyIj50aW1lPC9URD4KLQkJCTxURCB3aWR0aD0iMjAyIiBhbGlnbj0iY2VudGVyIj5YU0RhdGVUaW1lPC9URD4KLQkJPC9UUj4KLQkJPFRSPgotCQkJPFREIHdpZHRoPSIzMzIiIGFsaWduPSJjZW50ZXIiPmdZZWFyPC9URD4KLQkJCTxURCB3aWR0aD0iMjAyIiBhbGlnbj0iY2VudGVyIj5YU0RhdGVUaW1lPC9URD4KLQkJPC9UUj4KLQkJPFRSPgotCQkJPFREIHdpZHRoPSIzMzIiIGFsaWduPSJjZW50ZXIiPmdNb250aDwvVEQ+Ci0JCQk8VEQgd2lkdGg9IjIwMiIgYWxpZ249ImNlbnRlciI+WFNEYXRlVGltZTwvVEQ+Ci0JCTwvVFI+Ci0JCTxUUj4KLQkJCTxURCB3aWR0aD0iMzMyIiBhbGlnbj0iY2VudGVyIj5nRGF5PC9URD4KLQkJCTxURCB3aWR0aD0iMjAyIiBhbGlnbj0iY2VudGVyIj5YU0RhdGVUaW1lPC9URD4KLQkJPC9UUj4KLQkJPFRSPgotCQkJPFREIHdpZHRoPSIzMzIiIGFsaWduPSJjZW50ZXIiPmdZZWFyTW9udGg8L1REPgotCQkJPFREIHdpZHRoPSIyMDIiIGFsaWduPSJjZW50ZXIiPlhTRGF0ZVRpbWU8L1REPgotCQk8L1RSPgotCQk8VFI+Ci0JCQk8VEQgd2lkdGg9IjMzMiIgYWxpZ249ImNlbnRlciI+Z01vbnRoRGF5PC9URD4KLQkJCTxURCB3aWR0aD0iMjAyIiBhbGlnbj0iY2VudGVyIj5YU0RhdGVUaW1lPC9URD4KLQkJPC9UUj4KLQkJPFRSPgotCQkJPFREIHdpZHRoPSIzMzIiIGFsaWduPSJjZW50ZXIiPmhleEJpbmFyeTwvVEQ+Ci0JCQk8VEQgd2lkdGg9IjIwMiIgYWxpZ249ImNlbnRlciI+Qnl0ZUxpc3Q8L1REPgotCQk8L1RSPgotCQk8VFI+Ci0JCQk8VEQgd2lkdGg9IjMzMiIgYWxpZ249ImNlbnRlciI+YmFzZTY0QmluYXJ5PC9URD4KLQkJCTxURCB3aWR0aD0iMjAyIiBhbGlnbj0iY2VudGVyIj5CeXRlTGlzdDwvVEQ+Ci0JCTwvVFI+Ci0JCTxUUj4KLQkJCTxURCB3aWR0aD0iMzMyIiBhbGlnbj0iY2VudGVyIj5hbnlVUkk8L1REPgotCQkJPFREIHdpZHRoPSIyMDIiIGFsaWduPSJjZW50ZXIiPmphdmEubGFuZy5TdHJpbmc8L1REPgotCQk8L1RSPgotCQk8VFI+Ci0JCQk8VEQgd2lkdGg9IjMzMiIgYWxpZ249ImNlbnRlciI+UU5hbWU8L1REPgotCQkJPFREIHdpZHRoPSIyMDIiIGFsaWduPSJjZW50ZXIiPlhTUU5hbWU8L1REPgotCQk8L1RSPgotCQk8VFI+Ci0JCQk8VEQgd2lkdGg9IjMzMiIgYWxpZ249ImNlbnRlciI+Tk9UQVRJT048L1REPgotCQkJPFREIHdpZHRoPSIyMDIiIGFsaWduPSJjZW50ZXIiPlhTUU5hbWU8L1REPgotCQk8L1RSPgotCQk8VFI+Ci0JCQk8VEQgd2lkdGg9IjMzMiIgYWxpZ249ImNlbnRlciI+bm9ybWFsaXplZFN0cmluZzwvVEQ+Ci0JCQk8VEQgd2lkdGg9IjIwMiIgYWxpZ249ImNlbnRlciI+amF2YS5sYW5nLlN0cmluZzwvVEQ+Ci0JCTwvVFI+Ci0JCTxUUj4KLQkJCTxURCB3aWR0aD0iMzMyIiBhbGlnbj0iY2VudGVyIj50b2tlbjwvVEQ+Ci0JCQk8VEQgd2lkdGg9IjIwMiIgYWxpZ249ImNlbnRlciI+amF2YS5sYW5nLlN0cmluZzwvVEQ+Ci0JCTwvVFI+Ci0JCTxUUj4KLQkJCTxURCB3aWR0aD0iMzMyIiBhbGlnbj0iY2VudGVyIj5sYW5ndWFnZTwvVEQ+Ci0JCQk8VEQgd2lkdGg9IjIwMiIgYWxpZ249ImNlbnRlciI+amF2YS5sYW5nLlN0cmluZzwvVEQ+Ci0JCTwvVFI+Ci0JCTxUUj4KLQkJCTxURCB3aWR0aD0iMzMyIiBhbGlnbj0iY2VudGVyIj5OTVRPS0VOPC9URD4KLQkJCTxURCB3aWR0aD0iMjAyIiBhbGlnbj0iY2VudGVyIj5qYXZhLmxhbmcuU3RyaW5nPC9URD4KLQkJPC9UUj4KLQkJPFRSPgotCQkJPFREIHdpZHRoPSIzMzIiIGFsaWduPSJjZW50ZXIiPk5NVE9LRU5TPC9URD4KLQkJCTxURCB3aWR0aD0iMjAyIiBhbGlnbj0iY2VudGVyIj5PYmplY3RMaXN0PC9URD4KLQkJPC9UUj4KLQkJPFRSPgotCQkJPFREIHdpZHRoPSIzMzIiIGFsaWduPSJjZW50ZXIiPk5hbWU8L1REPgotCQkJPFREIHdpZHRoPSIyMDIiIGFsaWduPSJjZW50ZXIiPmphdmEubGFuZy5TdHJpbmc8L1REPgotCQk8L1RSPgotCQk8VFI+Ci0JCQk8VEQgd2lkdGg9IjMzMiIgYWxpZ249ImNlbnRlciI+TkNOYW1lPC9URD4KLQkJCTxURCB3aWR0aD0iMjAyIiBhbGlnbj0iY2VudGVyIj5qYXZhLmxhbmcuU3RyaW5nPC9URD4KLQkJPC9UUj4KLQkJPFRSPgotCQkJPFREIHdpZHRoPSIzMzIiIGFsaWduPSJjZW50ZXIiPklEPC9URD4KLQkJCTxURCB3aWR0aD0iMjAyIiBhbGlnbj0iY2VudGVyIj5qYXZhLmxhbmcuU3RyaW5nPC9URD4KLQkJPC9UUj4KLQkJPFRSPgotCQkJPFREIHdpZHRoPSIzMzIiIGFsaWduPSJjZW50ZXIiPklEUkVGPC9URD4KLQkJCTxURCB3aWR0aD0iMjAyIiBhbGlnbj0iY2VudGVyIj5qYXZhLmxhbmcuU3RyaW5nPC9URD4KLQkJPC9UUj4KLQkJPFRSPgotCQkJPFREIHdpZHRoPSIzMzIiIGFsaWduPSJjZW50ZXIiPklEUkVGUzwvVEQ+Ci0JCQk8VEQgd2lkdGg9IjIwMiIgYWxpZ249ImNlbnRlciI+T2JqZWN0TGlzdDwvVEQ+Ci0JCTwvVFI+Ci0JCTxUUj4KLQkJCTxURCB3aWR0aD0iMzMyIiBhbGlnbj0iY2VudGVyIj5FTlRJVFk8L1REPgotCQkJPFREIHdpZHRoPSIyMDIiIGFsaWduPSJjZW50ZXIiPmphdmEubGFuZy5TdHJpbmc8L1REPgotCQk8L1RSPgotCQk8VFI+Ci0JCQk8VEQgd2lkdGg9IjMzMiIgYWxpZ249ImNlbnRlciI+RU5USVRJRVM8L1REPgotCQkJPFREIHdpZHRoPSIyMDIiIGFsaWduPSJjZW50ZXIiPk9iamVjdExpc3Q8L1REPgotCQk8L1RSPgotCQk8VFI+Ci0JCQk8VEQgd2lkdGg9IjMzMiIgYWxpZ249ImNlbnRlciI+bGlzdDwvVEQ+Ci0JCQk8VEQgd2lkdGg9IjIwMiIgYWxpZ249ImNlbnRlciI+T2JqZWN0TGlzdDwvVEQ+Ci0JCTwvVFI+Ci0JCTxUUj4KLQkJCTxURCB3aWR0aD0iMzMyIiBhbGlnbj0iY2VudGVyIj5pbnRlZ2VyPC9URD4KLQkJCTxURCB3aWR0aD0iMjAyIiBhbGlnbj0iY2VudGVyIj5YU0RlY2ltYWw8L1REPgotCQk8L1RSPgotCQk8VFI+Ci0JCQk8VEQgd2lkdGg9IjMzMiIgYWxpZ249ImNlbnRlciI+cG9zaXRpdmVJbnRlZ2VyPC9URD4KLQkJCTxURCB3aWR0aD0iMjAyIiBhbGlnbj0iY2VudGVyIj5YU0RlY2ltYWw8L1REPgotCQk8L1RSPgotCQk8VFI+Ci0JCQk8VEQgd2lkdGg9IjMzMiIgYWxpZ249ImNlbnRlciI+bmVnYXRpdmVJbnRlZ2VyPC9URD4KLQkJCTxURCB3aWR0aD0iMjAyIiBhbGlnbj0iY2VudGVyIj5YU0RlY2ltYWw8L1REPgotCQk8L1RSPgotCQk8VFI+Ci0JCQk8VEQgd2lkdGg9IjMzMiIgYWxpZ249ImNlbnRlciI+bm9uUG9zaXRpdmVJbnRlZ2VyPC9URD4KLQkJCTxURCB3aWR0aD0iMjAyIiBhbGlnbj0iY2VudGVyIj5YU0RlY2ltYWw8L1REPgotCQk8L1RSPgotCQk8VFI+Ci0JCQk8VEQgd2lkdGg9IjMzMiIgYWxpZ249ImNlbnRlciI+bm9uTmVnYXRpdmVJbnRlZ2VyPC9URD4KLQkJCTxURCB3aWR0aD0iMjAyIiBhbGlnbj0iY2VudGVyIj5YU0RlY2ltYWw8L1REPgotCQk8L1RSPgotCQk8VFI+Ci0JCQk8VEQgd2lkdGg9IjMzMiIgYWxpZ249ImNlbnRlciI+dW5zaWduZWRTaG9ydDwvVEQ+Ci0JCQk8VEQgd2lkdGg9IjIwMiIgYWxpZ249ImNlbnRlciI+WFNEZWNpbWFsPC9URD4KLQkJPC9UUj4KLQkJPFRSPgotCQkJPFREIHdpZHRoPSIzMzIiIGFsaWduPSJjZW50ZXIiPnVuc2lnbmVkTG9uZzwvVEQ+Ci0JCQk8VEQgd2lkdGg9IjIwMiIgYWxpZ249ImNlbnRlciI+WFNEZWNpbWFsPC9URD4KLQkJPC9UUj4KLQkJPFRSPgotCQkJPFREIHdpZHRoPSIzMzIiIGFsaWduPSJjZW50ZXIiPnVuc2lnbmVkQnl0ZTwvVEQ+Ci0JCQk8VEQgd2lkdGg9IjIwMiIgYWxpZ249ImNlbnRlciI+WFNEZWNpbWFsPC9URD4KLQkJPC9UUj4KLQkJPFRSPgotCQkJPFREIHdpZHRoPSIzMzIiIGFsaWduPSJjZW50ZXIiPnVuc2lnbmVkSW50PC9URD4KLQkJCTxURCB3aWR0aD0iMjAyIiBhbGlnbj0iY2VudGVyIj5YU0RlY2ltYWw8L1REPgotCQk8L1RSPgotCQk8VFI+Ci0JCQk8VEQgd2lkdGg9IjMzMiIgYWxpZ249ImNlbnRlciI+bG9uZzwvVEQ+Ci0JCQk8VEQgd2lkdGg9IjIwMiIgYWxpZ249ImNlbnRlciI+WFNEZWNpbWFsPC9URD4KLQkJPC9UUj4KLQkJPFRSPgotCQkJPFREIHdpZHRoPSIzMzIiIGFsaWduPSJjZW50ZXIiPmludDwvVEQ+Ci0JCQk8VEQgd2lkdGg9IjIwMiIgYWxpZ249ImNlbnRlciI+WFNEZWNpbWFsPC9URD4KLQkJPC9UUj4KLQkJPFRSPgotCQkJPFREIHdpZHRoPSIzMzIiIGFsaWduPSJjZW50ZXIiPnNob3J0PC9URD4KLQkJCTxURCB3aWR0aD0iMjAyIiBhbGlnbj0iY2VudGVyIj5YU0RlY2ltYWw8L1REPgotCQk8L1RSPgotCQk8VFI+Ci0JCQk8VEQgd2lkdGg9IjMzMiIgYWxpZ249ImNlbnRlciI+Ynl0ZTwvVEQ+Ci0JCQk8VEQgd2lkdGg9IjIwMiIgYWxpZ249ImNlbnRlciI+WFNEZWNpbWFsPC9URD4KLQkJPC9UUj4KLQk8L1RCT0RZPgotPC9UQUJMRT4KLTxQPjxCUj5BcyBzaG93biBhYm92ZSwgdGhlIFhTRGF0ZVRpbWUgaW50ZXJmYWNlIHByb3ZpZGVzIG1hcHBpbmcgdG8gYSBudW1iZXIgb2YgZGVjaW1hbC9pbnRlZ2VyIGRhdGEgdHlwZXMuIFRoZSBhcHBsaWNhdGlvbiBuZWVkcyB0byBlbnN1cmUgdGhhdCBhcHByb3ByaWF0ZSBtZXRob2RzIGZvciBlYWNoIG9mIHRoZXNlIHR5cGVzIGlzIGludm9rZWQuIFRoZSBtYXBwaW5nIG9mICB0aGVzZSB0eXBlcyB0byBkZWZpbmVkIG1ldGhvZHMgaXMgc2hvd24gaW4gdGhlIHRhYmxlIGJlbG93LiBBY2Nlc3NpbmcgbWV0aG9kcyB0aGF0IGFyZSB1bmRlZmluZWQgZm9yIGEgdHlwZSB3aWxsIGdpdmUgdW5leHBlY3RlZCByZXN1bHRzLgotPC9QPgotCi0KLTxQPjxCUj4KLTwvUD4KLTxUQUJMRSBib3JkZXI9IjEiPgotCTxUQk9EWT4KLQkJPFRSPgotCQkJPFREIHdpZHRoPSIzMDgiIGFsaWduPSJjZW50ZXIiPlhNTCBTY2hlbWEgRGF0YSBUeXBlPC9URD4KLQkJCTxURCB3aWR0aD0iMjI4IiBhbGlnbj0iY2VudGVyIj5BcHBsaWNhYmxlIG1ldGhvZCBpbiBYU0RhdGVUaW1lKjwvVEQ+Ci0JCTwvVFI+Ci0JCTxUUj4KLQkJCTxURCB3aWR0aD0iMzA4Ij48L1REPgotCQkJPFREIHdpZHRoPSIyMjgiPjwvVEQ+Ci0JCTwvVFI+Ci0JCTxUUj4KLQkJCTxURCB3aWR0aD0iMzMyIiBhbGlnbj0iY2VudGVyIj5pbnRlZ2VyPC9URD48VEQgd2lkdGg9IjIwMiIgYWxpZ249ImNlbnRlciI+Z2V0QmlnSW50ZWdlcigpPC9URD4KLQkJCQotCQk8L1RSPgotCQk8VFI+Ci0JCQk8VEQgd2lkdGg9IjMzMiIgYWxpZ249ImNlbnRlciI+cG9zaXRpdmVJbnRlZ2VyPC9URD48VEQgd2lkdGg9IjIwMiIgYWxpZ249ImNlbnRlciI+Z2V0QmlnSW50ZWdlcigpPC9URD4KLQkJCQotCQk8L1RSPgotCQk8VFI+Ci0JCQk8VEQgd2lkdGg9IjMzMiIgYWxpZ249ImNlbnRlciI+bmVnYXRpdmVJbnRlZ2VyPC9URD48VEQgd2lkdGg9IjIwMiIgYWxpZ249ImNlbnRlciI+Z2V0QmlnSW50ZWdlcigpPC9URD4KLQkJCQotCQk8L1RSPgotCQk8VFI+Ci0JCQk8VEQgd2lkdGg9IjMzMiIgYWxpZ249ImNlbnRlciI+bm9uUG9zaXRpdmVJbnRlZ2VyPC9URD48VEQgd2lkdGg9IjIwMiIgYWxpZ249ImNlbnRlciI+Z2V0QmlnSW50ZWdlcigpPC9URD4KLQkJCQotCQk8L1RSPgotCQk8VFI+Ci0JCQk8VEQgd2lkdGg9IjMzMiIgYWxpZ249ImNlbnRlciI+bm9uTmVnYXRpdmVJbnRlZ2VyPC9URD48VEQgd2lkdGg9IjIwMiIgYWxpZ249ImNlbnRlciI+Z2V0QmlnSW50ZWdlcigpPC9URD4KLQkJCQotCQk8L1RSPgotCQk8VFI+Ci0JCQk8VEQgd2lkdGg9IjMzMiIgYWxpZ249ImNlbnRlciI+dW5zaWduZWRTaG9ydDwvVEQ+PFREIHdpZHRoPSIyMDIiIGFsaWduPSJjZW50ZXIiPmdldEludCgpPC9URD4KLQkJCQotCQk8L1RSPgotCQk8VFI+Ci0JCQk8VEQgd2lkdGg9IjMzMiIgYWxpZ249ImNlbnRlciI+dW5zaWduZWRMb25nPC9URD48VEQgd2lkdGg9IjIwMiIgYWxpZ249ImNlbnRlciI+Z2V0QmlnSW50ZWdlcigpPC9URD4KLQkJCQotCQk8L1RSPgotCQk8VFI+Ci0JCQk8VEQgd2lkdGg9IjMzMiIgYWxpZ249ImNlbnRlciI+dW5zaWduZWRCeXRlPC9URD48VEQgd2lkdGg9IjIwMiIgYWxpZ249ImNlbnRlciI+Z2V0U2hvcnQoKTwvVEQ+Ci0JCQkKLQkJPC9UUj4KLQkJPFRSPgotCQkJPFREIHdpZHRoPSIzMzIiIGFsaWduPSJjZW50ZXIiPnVuc2lnbmVkSW50PC9URD48VEQgd2lkdGg9IjIwMiIgYWxpZ249ImNlbnRlciI+Z2V0TG9uZygpPC9URD4KLQkJCQotCQk8L1RSPgotCQk8VFI+Ci0JCQk8VEQgd2lkdGg9IjMzMiIgYWxpZ249ImNlbnRlciI+bG9uZzwvVEQ+PFREIHdpZHRoPSIyMDIiIGFsaWduPSJjZW50ZXIiPmdldExvbmcoKTwvVEQ+Ci0JCQkKLQkJPC9UUj4KLQkJPFRSPgotCQkJPFREIHdpZHRoPSIzMzIiIGFsaWduPSJjZW50ZXIiPmludDwvVEQ+PFREIHdpZHRoPSIyMDIiIGFsaWduPSJjZW50ZXIiPmdldEludCgpPC9URD4KLQkJCQotCQk8L1RSPgotCQk8VFI+Ci0JCQk8VEQgd2lkdGg9IjMzMiIgYWxpZ249ImNlbnRlciI+c2hvcnQ8L1REPjxURCB3aWR0aD0iMjAyIiBhbGlnbj0iY2VudGVyIj5nZXRTaG9ydCgpPC9URD4KLQkJCQotCQk8L1RSPgotCQk8VFI+Ci0JCQk8VEQgd2lkdGg9IjMzMiIgYWxpZ249ImNlbnRlciI+Ynl0ZTwvVEQ+PFREIHdpZHRoPSIyMDIiIGFsaWduPSJjZW50ZXIiPmdldEJ5dGUoKTwvVEQ+Ci0JCQkKLQkJPC9UUj4KLQkJPFRSPgotCQkJPFREIHdpZHRoPSIzMDgiPjwvVEQ+Ci0JCQk8VEQgd2lkdGg9IjIyOCI+PC9URD4KLQkJPC9UUj4KLQk8L1RCT0RZPgotPC9UQUJMRT4KLTxQPjxCUj4qIDxTUEFOCi0Jc3R5bGU9J2ZvbnQtc2l6ZToxMi4wcHQ7Zm9udC1mYW1pbHk6IlRpbWVzIE5ldyBSb21hbiI7Ci1tc28tZmFyZWFzdC1mb250LWZhbWlseToiVGltZXMgTmV3IFJvbWFuIjttc28tYW5zaS1sYW5ndWFnZTpFTi1VUzttc28tZmFyZWFzdC1sYW5ndWFnZToKLUVOLUdCO21zby1iaWRpLWxhbmd1YWdlOkFSLVNBJz5UaGlzCi1zaG93cyB0aGUgYmFzZSBtZXRob2QgdGhhdCBjYW4gYmUgY2FsbGVkLiBUaGF0IGlzLCB1c2VycyBjYW4gY2FsbCB0aGlzCi1tZXRob2QgYW5kIGFsbCBtZXRob2RzIHJldHVybmluZyBiaWdnZXIgdHlwZXMgdGhhbiB0aGUgYmFzZSBtZXRob2QKLWFjY29yZGluZyB0byB0aGUgb3JkZXI6IGJ5dGUgJmx0OyBzaG9ydCAmbHQ7IGludCAmbHQ7IGxvbmcgJmx0OwotQmlnSW50ZWdlciAmbHQ7IEJpZ0RlY2ltYWwuIEZvciBleGFtcGxlLCBpbiB0aGUgY2FzZSBvZiB1bnNpZ25lZFNob3J0LAotdXNlcnMgY2FuIGNhbGwgZ2V0SW50KCksIGdldExvbmcoKSwgZ2V0QmlnSW50ZWdlcigpIGFuZCBnZXRCaWdEZWNpbWFsKCkKLWJ1dCBOT1QgZ2V0U2hvcnQoKSBvciBnZXRCeXRlKCkuPC9TUEFOPgotPC9QPjwvYm9keT4KLTwvaHRtbD4KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9BeGlzLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vQXhpcy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA5MjM5NzE1Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9BeGlzLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMjIgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogQXhpcy5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE1IDA4OjE0OjUxIHN1cmVzaF9lbWFpbGlkIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG07Ci0KLS8qKgotICogU3BlY2lmaWVzIHZhbHVlcyByZWxhdGVkIHRvIFhQYXRoIEF4ZXMuCi0gKiA8cD5UaGUgYW5jZXN0b3IsIGRlc2NlbmRhbnQsIGZvbGxvd2luZywgcHJlY2VkaW5nIGFuZCBzZWxmIGF4ZXMgcGFydGl0aW9uIGEKLSAqIGRvY3VtZW50IChpZ25vcmluZyBhdHRyaWJ1dGUgYW5kIG5hbWVzcGFjZSBub2Rlcyk6IHRoZXkgZG8gbm90IG92ZXJsYXAKLSAqIGFuZCB0b2dldGhlciB0aGV5IGNvbnRhaW4gYWxsIHRoZSBub2RlcyBpbiB0aGUgZG9jdW1lbnQuPC9wPgotICoKLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIEF4aXMKLXsKLQotICAvKioKLSAgICogVGhlIGFuY2VzdG9yIGF4aXMgY29udGFpbnMgdGhlIGFuY2VzdG9ycyBvZiB0aGUgY29udGV4dCBub2RlOwotICAgKiAgdGhlIGFuY2VzdG9ycyBvZiB0aGUgY29udGV4dCBub2RlIGNvbnNpc3Qgb2YgdGhlIHBhcmVudCBvZiBjb250ZXh0Ci0gICAqICBub2RlIGFuZCB0aGUgcGFyZW50J3MgcGFyZW50IGFuZCBzbyBvbjsgdGh1cywgdGhlIGFuY2VzdG9yIGF4aXMgd2lsbAotICAgKiAgYWx3YXlzIGluY2x1ZGUgdGhlIHJvb3Qgbm9kZSwgdW5sZXNzIHRoZSBjb250ZXh0IG5vZGUgaXMgdGhlIHJvb3Qgbm9kZS4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFOQ0VTVE9SID0gMDsKLQotICAvKioKLSAgICogdGhlIGFuY2VzdG9yLW9yLXNlbGYgYXhpcyBjb250YWlucyB0aGUgY29udGV4dCBub2RlIGFuZCB0aGUgYW5jZXN0b3JzIG9mCi0gICAqICB0aGUgY29udGV4dCBub2RlOyB0aHVzLCB0aGUgYW5jZXN0b3IgYXhpcyB3aWxsIGFsd2F5cyBpbmNsdWRlIHRoZQotICAgKiAgcm9vdCBub2RlLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQU5DRVNUT1JPUlNFTEYgPSAxOwotCi0gIC8qKgotICAgKiB0aGUgYXR0cmlidXRlIGF4aXMgY29udGFpbnMgdGhlIGF0dHJpYnV0ZXMgb2YgdGhlIGNvbnRleHQgbm9kZTsgdGhlIGF4aXMKLSAgICogIHdpbGwgYmUgZW1wdHkgdW5sZXNzIHRoZSBjb250ZXh0IG5vZGUgaXMgYW4gZWxlbWVudC4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFUVFJJQlVURSA9IDI7Ci0KLSAgLyoqIFRoZSBjaGlsZCBheGlzIGNvbnRhaW5zIHRoZSBjaGlsZHJlbiBvZiB0aGUgY29udGV4dCBub2RlLiAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDSElMRCA9IDM7Ci0KLSAgLyoqCi0gICAqIFRoZSBkZXNjZW5kYW50IGF4aXMgY29udGFpbnMgdGhlIGRlc2NlbmRhbnRzIG9mIHRoZSBjb250ZXh0IG5vZGU7Ci0gICAqICBhIGRlc2NlbmRhbnQgaXMgYSBjaGlsZCBvciBhIGNoaWxkIG9mIGEgY2hpbGQgYW5kIHNvIG9uOyB0aHVzIHRoZQotICAgKiAgZGVzY2VuZGFudCBheGlzIG5ldmVyIGNvbnRhaW5zIGF0dHJpYnV0ZSBvciBuYW1lc3BhY2Ugbm9kZXMuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBERVNDRU5EQU5UID0gNDsKLQotICAvKioKLSAgICogVGhlIGRlc2NlbmRhbnQtb3Itc2VsZiBheGlzIGNvbnRhaW5zIHRoZSBjb250ZXh0IG5vZGUgYW5kIHRoZQotICAgKiAgZGVzY2VuZGFudHMgb2YgdGhlIGNvbnRleHQgbm9kZS4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFU0NFTkRBTlRPUlNFTEYgPSA1OwotCi0gIC8qKgotICAgKiB0aGUgZm9sbG93aW5nIGF4aXMgY29udGFpbnMgYWxsIG5vZGVzIGluIHRoZSBzYW1lIGRvY3VtZW50IGFzIHRoZQotICAgKiAgY29udGV4dCBub2RlIHRoYXQgYXJlIGFmdGVyIHRoZSBjb250ZXh0IG5vZGUgaW4gZG9jdW1lbnQgb3JkZXIsIGV4Y2x1ZGluZwotICAgKiAgYW55IGRlc2NlbmRhbnRzIGFuZCBleGNsdWRpbmcgYXR0cmlidXRlIG5vZGVzIGFuZCBuYW1lc3BhY2Ugbm9kZXMuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGT0xMT1dJTkcgPSA2OwotCi0gIC8qKgotICAgKiBUaGUgZm9sbG93aW5nLXNpYmxpbmcgYXhpcyBjb250YWlucyBhbGwgdGhlIGZvbGxvd2luZyBzaWJsaW5ncyBvZiB0aGUKLSAgICogIGNvbnRleHQgbm9kZTsgaWYgdGhlIGNvbnRleHQgbm9kZSBpcyBhbiBhdHRyaWJ1dGUgbm9kZSBvciBuYW1lc3BhY2Ugbm9kZSwKLSAgICogIHRoZSBmb2xsb3dpbmctc2libGluZyBheGlzIGlzIGVtcHR5LgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRk9MTE9XSU5HU0lCTElORyA9IDc7Ci0KLSAgLyoqCi0gICAqIFRoZSBuYW1lc3BhY2UgYXhpcyBjb250YWlucyB0aGUgbmFtZXNwYWNlIG5vZGVzIG9mIHRoZSBjb250ZXh0IG5vZGU7IHRoZQotICAgKiAgYXhpcyB3aWxsIGJlIGVtcHR5IHVubGVzcyB0aGUgY29udGV4dCBub2RlIGlzIGFuIGVsZW1lbnQuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBOQU1FU1BBQ0VERUNMUyA9IDg7Ci0KLSAgLyoqCi0gICAqIFRoZSBuYW1lc3BhY2UgYXhpcyBjb250YWlucyB0aGUgbmFtZXNwYWNlIG5vZGVzIG9mIHRoZSBjb250ZXh0IG5vZGU7IHRoZQotICAgKiAgYXhpcyB3aWxsIGJlIGVtcHR5IHVubGVzcyB0aGUgY29udGV4dCBub2RlIGlzIGFuIGVsZW1lbnQuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBOQU1FU1BBQ0UgPSA5OwotCi0gIC8qKgotICAgKiBUaGUgcGFyZW50IGF4aXMgY29udGFpbnMgdGhlIHBhcmVudCBvZiB0aGUgY29udGV4dCBub2RlLAotICAgKiAgaWYgdGhlcmUgaXMgb25lLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUEFSRU5UID0gMTA7Ci0KLSAgLyoqCi0gICAqIFRoZSBwcmVjZWRpbmcgYXhpcyBjb250YWlucyBhbGwgbm9kZXMgaW4gdGhlIHNhbWUgZG9jdW1lbnQgYXMgdGhlIGNvbnRleHQKLSAgICogIG5vZGUgdGhhdCBhcmUgYmVmb3JlIHRoZSBjb250ZXh0IG5vZGUgaW4gZG9jdW1lbnQgb3JkZXIsIGV4Y2x1ZGluZyBhbnkKLSAgICogIGFuY2VzdG9ycyBhbmQgZXhjbHVkaW5nIGF0dHJpYnV0ZSBub2RlcyBhbmQgbmFtZXNwYWNlIG5vZGVzCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQUkVDRURJTkcgPSAxMTsKLQotICAvKioKLSAgICogVGhlIHByZWNlZGluZy1zaWJsaW5nIGF4aXMgY29udGFpbnMgYWxsIHRoZSBwcmVjZWRpbmcgc2libGluZ3Mgb2YgdGhlCi0gICAqICBjb250ZXh0IG5vZGU7IGlmIHRoZSBjb250ZXh0IG5vZGUgaXMgYW4gYXR0cmlidXRlIG5vZGUgb3IgbmFtZXNwYWNlIG5vZGUsCi0gICAqICB0aGUgcHJlY2VkaW5nLXNpYmxpbmcgYXhpcyBpcyBlbXB0eS4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBSRUNFRElOR1NJQkxJTkcgPSAxMjsKLQotICAvKiogVGhlIHNlbGYgYXhpcyBjb250YWlucyBqdXN0IHRoZSBjb250ZXh0IG5vZGUgaXRzZWxmLiAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTRUxGID0gMTM7Ci0KLSAgLyoqCi0gICAqIEEgbm9uLXhwYXRoIGF4aXMsIHRyYXZlcnNpbmcgdGhlIHN1YnRyZWUgaW5jbHVkaW5nIHRoZSBzdWJ0cmVlCi0gICAqICByb290LCBkZXNjZW5kYW50cywgYXR0cmlidXRlcywgYW5kIG5hbWVzcGFjZSBub2RlIGRlY2xzLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQUxMRlJPTU5PREUgPSAxNDsKLQotICAvKioKLSAgICogQSBub24teHBhdGggYXhpcywgdHJhdmVyc2luZyB0aGUgdGhlIHByZWNlZGluZyBhbmQgdGhlIGFuY2VzdG9yIG5vZGVzLAotICAgKiBuZWVkZWQgZm9yIGludmVyc2Vpbmcgc2VsZWN0IHBhdHRlcm5zIHRvIG1hdGNoIHBhdHRlcm5zLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUFJFQ0VESU5HQU5EQU5DRVNUT1IgPSAxNTsKLQotICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gIC8vIEFsbCBheGlzIHBhc3QgdGhpcyBhcmUgYWJzb2x1dGUuCi0KLSAgLyoqCi0gICAqIEEgbm9uLXhwYXRoIGF4aXMsIHJldHVybnMgYWxsIG5vZGVzIGluIHRoZSB0cmVlIGZyb20gYW5kIGluY2x1ZGluZyB0aGUKLSAgICogcm9vdC4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFMTCA9IDE2OwotCi0gIC8qKgotICAgKiBBIG5vbi14cGF0aCBheGlzLCByZXR1cm5zIGFsbCBub2RlcyB0aGF0IGFyZW4ndCBuYW1lc3BhY2VzIG9yIGF0dHJpYnV0ZXMsCi0gICAqIGZyb20gYW5kIGluY2x1ZGluZyB0aGUgcm9vdC4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFU0NFTkRBTlRTRlJPTVJPT1QgPSAxNzsKLQotICAvKioKLSAgICogQSBub24teHBhdGggYXhpcywgcmV0dXJucyBhbGwgbm9kZXMgdGhhdCBhcmVuJ3QgbmFtZXNwYWNlcyBvciBhdHRyaWJ1dGVzLAotICAgKiBmcm9tIGFuZCBpbmNsdWRpbmcgdGhlIHJvb3QuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBERVNDRU5EQU5UU09SU0VMRkZST01ST09UID0gMTg7Ci0KLSAgLyoqCi0gICAqIEEgbm9uLXhwYXRoIGF4aXMsIHJldHVybnMgcm9vdCBvbmx5LgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUk9PVCA9IDE5OwotCi0gIC8qKgotICAgKiBBIG5vbi14cGF0aCBheGlzLCBmb3IgZnVuY3Rpb25zLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklMVEVSRURMSVNUID0gMjA7Ci0KLSAgLyoqCi0gICAqIEEgdGFibGUgdG8gaWRlbnRpZnkgd2hldGhlciBhbiBheGlzIGlzIGEgcmV2ZXJzZSBheGlzOwotICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbltdIGlzUmV2ZXJzZSA9IHsKLSAgICAgIHRydWUsICAvLyBhbmNlc3RvcgotICAgICAgdHJ1ZSwgIC8vIGFuY2VzdG9yLW9yLXNlbGYKLSAgICAgIGZhbHNlLCAvLyBhdHRyaWJ1dGUKLSAgICAgIGZhbHNlLCAvLyBjaGlsZAotICAgICAgZmFsc2UsIC8vIGRlc2NlbmRhbnQKLSAgICAgIGZhbHNlLCAvLyBkZXNjZW5kYW50LW9yLXNlbGYKLSAgICAgIGZhbHNlLCAvLyBmb2xsb3dpbmcKLSAgICAgIGZhbHNlLCAvLyBmb2xsb3dpbmctc2libGluZwotICAgICAgZmFsc2UsIC8vIG5hbWVzcGFjZQotICAgICAgZmFsc2UsIC8vIG5hbWVzcGFjZS1kZWNsYXJhdGlvbnMKLSAgICAgIGZhbHNlLCAvLyBwYXJlbnQgKG9uZSBub2RlLCBoYXMgbm8gb3JkZXIpCi0gICAgICB0cnVlLCAgLy8gcHJlY2VkaW5nCi0gICAgICB0cnVlLCAgLy8gcHJlY2VkaW5nLXNpYmxpbmcKLSAgICAgIGZhbHNlICAvLyBzZWxmIChvbmUgbm9kZSwgaGFzIG5vIG9yZGVyKQotICB9OwotCi0gICAgLyoqIFRoZSBuYW1lcyBvZiB0aGUgYXhlcyBmb3IgZGlhZ25vc3RpYyBwdXJwb3Nlcy4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSBuYW1lcyA9Ci0gICAgewotICAgICAgImFuY2VzdG9yIiwgIC8vIDAKLSAgICAgICJhbmNlc3Rvci1vci1zZWxmIiwgIC8vIDEKLSAgICAgICJhdHRyaWJ1dGUiLCAgLy8gMgotICAgICAgImNoaWxkIiwgIC8vIDMKLSAgICAgICJkZXNjZW5kYW50IiwgIC8vIDQKLSAgICAgICJkZXNjZW5kYW50LW9yLXNlbGYiLCAgLy8gNQotICAgICAgImZvbGxvd2luZyIsICAvLyA2Ci0gICAgICAiZm9sbG93aW5nLXNpYmxpbmciLCAgLy8gNwotICAgICAgIm5hbWVzcGFjZS1kZWNscyIsICAvLyA4Ci0gICAgICAibmFtZXNwYWNlIiwgIC8vIDkKLSAgICAgICJwYXJlbnQiLCAgLy8gMTAKLSAgICAgICJwcmVjZWRpbmciLCAgLy8gMTEKLSAgICAgICJwcmVjZWRpbmctc2libGluZyIsICAvLyAxMgotICAgICAgInNlbGYiLCAgLy8gMTMKLSAgICAgICJhbGwtZnJvbS1ub2RlIiwgIC8vIDE0Ci0gICAgICAicHJlY2VkaW5nLWFuZC1hbmNlc3RvciIsICAvLyAxNQotICAgICAgImFsbCIsICAvLyAxNgotICAgICAgImRlc2NlbmRhbnRzLWZyb20tcm9vdCIsICAvLyAxNwotICAgICAgImRlc2NlbmRhbnRzLW9yLXNlbGYtZnJvbS1yb290IiwgIC8vIDE4Ci0gICAgICAicm9vdCIsICAvLyAxOQotICAgICAgImZpbHRlcmVkLWxpc3QiICAvLyAyMAotICAgIH07Ci0KLSAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzUmV2ZXJzZShpbnQgYXhpcyl7Ci0gICAgICByZXR1cm4gaXNSZXZlcnNlW2F4aXNdOwotICB9Ci0KLSAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBnZXROYW1lcyhpbnQgaW5kZXgpewotICAgICAgICByZXR1cm4gbmFtZXNbaW5kZXhdOwotICAgIH0KLQotICAgIHB1YmxpYyBzdGF0aWMgaW50IGdldE5hbWVzTGVuZ3RoKCl7Ci0gICAgICAgIHJldHVybiBuYW1lcy5sZW5ndGg7Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDkxODI4MzMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTY5ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IERUTS5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE1IDA4OjE0OjUxIHN1cmVzaF9lbWFpbGlkIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG07Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlNvdXJjZUxvY2F0b3I7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLlhNTFN0cmluZzsKLQotLyoqCi0gKiA8Y29kZT5EVE08L2NvZGU+IGlzIGFuIFhNTCBkb2N1bWVudCBtb2RlbCBleHByZXNzZWQgYXMgYSB0YWJsZQotICogcmF0aGVyIHRoYW4gYW4gb2JqZWN0IHRyZWUuIEl0IGF0dGVtcHRzIHRvIHByb3ZpZGUgYW4gaW50ZXJmYWNlIHRvCi0gKiBhIHBhcnNlIHRyZWUgdGhhdCBoYXMgdmVyeSBsaXR0bGUgb2JqZWN0IGNyZWF0aW9uLiAoRFRNCi0gKiBpbXBsZW1lbnRhdGlvbnMgbWF5IGFsc28gc3VwcG9ydCBpbmNyZW1lbnRhbCBjb25zdHJ1Y3Rpb24gb2YgdGhlCi0gKiBtb2RlbCwgYnV0IHRoYXQncyBoaWRkZW4gZnJvbSB0aGUgRFRNIEFQSS4pCi0gKgotICogPHA+Tm9kZXMgaW4gdGhlIERUTSBhcmUgaWRlbnRpZmllZCBieSBpbnRlZ2VyICJoYW5kbGVzIi4gIEEgaGFuZGxlIG11c3QKLSAqIGJlIHVuaXF1ZSB3aXRoaW4gYSBwcm9jZXNzLCBhbmQgY2FycmllcyBib3RoIG5vZGUgaWRlbnRpZmljYXRpb24gYW5kCi0gKiBkb2N1bWVudCBpZGVudGlmaWNhdGlvbi4gIEl0IG11c3QgYmUgcG9zc2libGUgdG8gY29tcGFyZSB0d28gaGFuZGxlcwotICogKGFuZCB0aHVzIHRoZWlyIG5vZGVzKSBmb3IgaWRlbnRpdHkgd2l0aCAiPT0iLjwvcD4KLSAqCi0gKiA8cD5OYW1lc3BhY2UgVVJMcywgbG9jYWwtbmFtZXMsIGFuZCBleHBhbmRlZC1uYW1lcyBjYW4gYWxsIGJlCi0gKiByZXByZXNlbnRlZCBieSBhbmQgdGVzdGVkIGFzIGludGVnZXIgSUQgdmFsdWVzLiAgQW4gZXhwYW5kZWQgbmFtZQotICogcmVwcmVzZW50cyAoYW5kIG1heSBvciBtYXkgbm90IGRpcmVjdGx5IGNvbnRhaW4pIGEgY29tYmluYXRpb24gb2YKLSAqIHRoZSBVUkwgSUQsIGFuZCB0aGUgbG9jYWwtbmFtZSBJRC4gIE5vdGUgdGhhdCB0aGUgbmFtZXNwYWNlIFVSTCBpZAotICogY2FuIGJlIDAsIHdoaWNoIHNob3VsZCBoYXZlIHRoZSBtZWFuaW5nIHRoYXQgdGhlIG5hbWVzcGFjZSBpcyBudWxsLgotICogRm9yIGNvbnNpc3RhbmN5LCB6ZXJvIHNob3VsZCBub3QgYmUgdXNlZCBmb3IgYSBsb2NhbC1uYW1lIGluZGV4LiA8L3A+Ci0gKgotICogPHA+VGV4dCBjb250ZW50IG9mIGEgbm9kZSBpcyByZXByZXNlbnRlZCBieSBhbiBpbmRleCBhbmQgbGVuZ3RoLAotICogcGVybWl0dGluZyBlZmZpY2llbnQgc3RvcmFnZSBzdWNoIGFzIGEgc2hhcmVkIEZhc3RTdHJpbmdCdWZmZXIuPC9wPgotICoKLSAqIDxwPlRoZSBtb2RlbCBvZiB0aGUgdHJlZSwgYXMgd2VsbCBhcyB0aGUgZ2VuZXJhbCBuYXZpZ2F0aW9uIG1vZGVsLAotICogaXMgdGhhdCBvZiBYUGF0aCAxLjAsIGZvciB0aGUgbW9tZW50LiAgVGhlIG1vZGVsIHdpbGwgZXZlbnR1YWxseSBiZQotICogYWRhcHRlZCB0byBtYXRjaCB0aGUgWFBhdGggMi4wIGRhdGEgbW9kZWwsIFhNTCBTY2hlbWEsIGFuZAotICogSW5mb1NldC48L3A+Ci0gKgotICogPHA+RFRNIGRvZXMgX25vdF8gZGlyZWN0bHkgc3VwcG9ydCB0aGUgVzNDJ3MgRG9jdW1lbnQgT2JqZWN0Ci0gKiBNb2RlbC4gSG93ZXZlciwgaXQgYXR0ZW1wdHMgdG8gY29tZSBjbG9zZSBlbm91Z2ggdGhhdCBhbgotICogaW1wbGVtZW50YXRpb24gb2YgRFRNIGNhbiBiZSBjcmVhdGVkIHRoYXQgd3JhcHMgYSBET00gYW5kIHZpY2UKLSAqIHZlcnNhLjwvcD4KLSAqCi0gKiA8cD48c3Ryb25nPlBsZWFzZSBOb3RlOjwvc3Ryb25nPiBUaGUgRFRNIEFQSSBpcyBzdGlsbAotICogPHN0cm9uZz5TdWJqZWN0IFRvIENoYW5nZS48L3N0cm9uZz4gVGhpcyB3b3VsZG4ndCBhZmZlY3QgbW9zdAotICogdXNlcnMsIGJ1dCBtaWdodCByZXF1aXJlIHVwZGF0aW5nIHNvbWUgZXh0ZW5zaW9ucy48L3A+Ci0gKgotICogPHA+IFRoZSBsYXJnZXN0IGNoYW5nZSBiZWluZyBjb250ZW1wbGF0ZWQgaXMgYSByZWNvbnNpZGVyYXRpb24gb2YKLSAqIHRoZSBOb2RlIEhhbmRsZSByZXByZXNlbnRhdGlvbi4gIFdlIGFyZSBzdGlsbCBub3QgZW50aXJlbHkgc3VyZQotICogdGhhdCBhbiBpbnRlZ2VyIHBhY2tlZCB3aXRoIHR3byBudW1lcmljIHN1YmZpZWxkcyBpcyByZWFsbHkgdGhlCi0gKiBiZXN0IHNvbHV0aW9uLiBJdCBoYXMgYmVlbiBzdWdnZXN0ZWQgdGhhdCB3ZSBtb3ZlIHVwIHRvIGEgTG9uZywgdG8KLSAqIHBlcm1pdCBtb3JlIG5vZGVzIHBlciBkb2N1bWVudCB3aXRob3V0IGhhdmluZyB0byByZWR1Y2UgdGhlIG51bWJlcgotICogb2Ygc2xvdHMgaW4gdGhlIERUTU1hbmFnZXIuIFRoZXJlJ3MgZXZlbiBiZWVuIGEgcHJvcG9zYWwgdGhhdCB3ZQotICogcmVwbGFjZSB0aGVzZSBpbnRlZ2VycyB3aXRoICJjdXJzb3IiIG9iamVjdHMgY29udGFpbmluZyB0aGUKLSAqIGludGVybmFsIG5vZGUgaWQgYW5kIGEgcG9pbnRlciB0byB0aGUgYWN0dWFsIERUTSBvYmplY3Q7IHRoaXMgbWlnaHQKLSAqIHJlZHVjZSB0aGUgbmVlZCB0byBjb250aW51b3VzbHkgY29uc3VsdCB0aGUgRFRNTWFuYWdlciB0byByZXRyaWV2ZQotICogdGhlIGxhdHRlciwgYW5kIG1pZ2h0IHByb3ZpZGUgYSB1c2VmdWwgImhvb2siIGJhY2sgaW50byBub3JtYWwgSmF2YQotICogaGVhcCBtYW5hZ2VtZW50LiAgQnV0IGNoYW5naW5nIHRoaXMgZGF0YXR5cGUgd291bGQgaGF2ZSBodWdlIGltcGFjdAotICogb24gWGFsYW4ncyBpbnRlcm5hbHMgLS0gZXNwZWNpYWxseSBnaXZlbiBKYXZhJ3MgbGFjayBvZiBDLXN0eWxlCi0gKiB0eXBlZGVmcyAtLSBzbyB3ZSB3b24ndCBjdXQgb3ZlciB1bmxlc3Mgd2UncmUgY29udmluY2VkIHRoZSBuZXcKLSAqIHNvbHV0aW9uIHJlYWxseSB3b3VsZCBiZSBhbiBpbXByb3ZlbWVudCE8L3A+Ci0gKiAqLwotcHVibGljIGludGVyZmFjZSBEVE0KLXsKLQotICAvKioKLSAgICogTnVsbCBub2RlIGhhbmRsZXMgYXJlIHJlcHJlc2VudGVkIGJ5IHRoaXMgdmFsdWUuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBOVUxMID0gLTE7Ci0KLSAgLy8gVGhlc2Ugbm9kZVR5cGUgbW5lbW9uaWNzIGFuZCB2YWx1ZXMgYXJlIGRlbGliZXJhdGVseSB0aGUgc2FtZSBhcyB0aG9zZQotICAvLyB1c2VkIGJ5IHRoZSBET00sIGZvciBjb252ZW5pZW50IG1hcHBpbmcKLSAgLy8KLSAgLy8gJVJFVklFVyUgU2hvdWxkIHdlIGFjdHVhbGx5IGRlZmluZSB0aGVzZSBhcyBpbml0aWFsaXplZCB0bywKLSAgLy8gZWcuIG9yZy53M2MuZG9tLkRvY3VtZW50LkVMRU1FTlRfTk9ERT8KLQotICAvKioKLSAgICogVGhlIG5vZGUgaXMgYSA8Y29kZT5Sb290PC9jb2RlPi4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgUk9PVF9OT0RFID0gMDsKLQotICAvKioKLSAgICogVGhlIG5vZGUgaXMgYW4gPGNvZGU+RWxlbWVudDwvY29kZT4uCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IEVMRU1FTlRfTk9ERSA9IDE7Ci0KLSAgLyoqCi0gICAqIFRoZSBub2RlIGlzIGFuIDxjb2RlPkF0dHI8L2NvZGU+LgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBBVFRSSUJVVEVfTk9ERSA9IDI7Ci0KLSAgLyoqCi0gICAqIFRoZSBub2RlIGlzIGEgPGNvZGU+VGV4dDwvY29kZT4gbm9kZS4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgVEVYVF9OT0RFID0gMzsKLQotICAvKioKLSAgICogVGhlIG5vZGUgaXMgYSA8Y29kZT5DREFUQVNlY3Rpb248L2NvZGU+LgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBDREFUQV9TRUNUSU9OX05PREUgPSA0OwotCi0gIC8qKgotICAgKiBUaGUgbm9kZSBpcyBhbiA8Y29kZT5FbnRpdHlSZWZlcmVuY2U8L2NvZGU+LgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBFTlRJVFlfUkVGRVJFTkNFX05PREUgPSA1OwotCi0gIC8qKgotICAgKiBUaGUgbm9kZSBpcyBhbiA8Y29kZT5FbnRpdHk8L2NvZGU+LgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBFTlRJVFlfTk9ERSA9IDY7Ci0KLSAgLyoqCi0gICAqIFRoZSBub2RlIGlzIGEgPGNvZGU+UHJvY2Vzc2luZ0luc3RydWN0aW9uPC9jb2RlPi4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFID0gNzsKLQotICAvKioKLSAgICogVGhlIG5vZGUgaXMgYSA8Y29kZT5Db21tZW50PC9jb2RlPi4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgQ09NTUVOVF9OT0RFID0gODsKLQotICAvKioKLSAgICogVGhlIG5vZGUgaXMgYSA8Y29kZT5Eb2N1bWVudDwvY29kZT4uCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IERPQ1VNRU5UX05PREUgPSA5OwotCi0gIC8qKgotICAgKiBUaGUgbm9kZSBpcyBhIDxjb2RlPkRvY3VtZW50VHlwZTwvY29kZT4uCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IERPQ1VNRU5UX1RZUEVfTk9ERSA9IDEwOwotCi0gIC8qKgotICAgKiBUaGUgbm9kZSBpcyBhIDxjb2RlPkRvY3VtZW50RnJhZ21lbnQ8L2NvZGU+LgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBET0NVTUVOVF9GUkFHTUVOVF9OT0RFID0gMTE7Ci0KLSAgLyoqCi0gICAqIFRoZSBub2RlIGlzIGEgPGNvZGU+Tm90YXRpb248L2NvZGU+LgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBOT1RBVElPTl9OT0RFID0gMTI7Ci0KLSAgLyoqCi0gICAqIFRoZSBub2RlIGlzIGEgPGNvZGU+bmFtZXNwYWNlIG5vZGU8L2NvZGU+LiBOb3RlIHRoYXQgdGhpcyBpcyBub3QKLSAgICogY3VycmVudGx5IGEgbm9kZSB0eXBlIGRlZmluZWQgYnkgdGhlIERPTSBBUEkuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IE5BTUVTUEFDRV9OT0RFID0gMTM7Ci0KLSAgLyoqCi0gICAqIFRoZSBudW1iZXIgb2YgdmFsaWQgbm9kZXR5cGVzLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCAgTlRZUEVTID0gMTQ7Ci0KLSAgLy8gPT09PT09PT09IERUTSBJbXBsZW1lbnRhdGlvbiBDb250cm9sIEZ1bmN0aW9ucy4gPT09PT09PT09PT09PT0KLSAgLy8gJVRCRCUgUkVUSVJFRCAtLSBkbyB2aWEgc2V0RmVhdHVyZSBpZiBuZWVkZWQuIFJlbW92ZSBmcm9tIGltcGxzLgotICAvLyBwdWJsaWMgdm9pZCBzZXRQYXJzZUJsb2NrU2l6ZShpbnQgYmxvY2tTaXplU3VnZ2VzdGlvbik7Ci0KLSAgLyoqCi0gICAqIFNldCBhbiBpbXBsZW1lbnRhdGlvbiBkZXBlbmRlbnQgZmVhdHVyZS4KLSAgICogPHA+Ci0gICAqICVSRVZJRVclIERvIHdlIHJlYWxseSBleHBlY3QgdG8gc2V0IGZlYXR1cmVzIG9uIERUTXM/Ci0gICAqCi0gICAqIEBwYXJhbSBmZWF0dXJlSWQgQSBmZWF0dXJlIFVSTC4KLSAgICogQHBhcmFtIHN0YXRlIHRydWUgaWYgdGhpcyBmZWF0dXJlIHNob3VsZCBiZSBvbiwgZmFsc2Ugb3RoZXJ3aXNlLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0RmVhdHVyZShTdHJpbmcgZmVhdHVyZUlkLCBib29sZWFuIHN0YXRlKTsKLQotICAvKioKLSAgICogU2V0IGEgcnVuIHRpbWUgcHJvcGVydHkgZm9yIHRoaXMgRFRNIGluc3RhbmNlLgotICAgKgotICAgKiBAcGFyYW0gcHJvcGVydHkgYSA8Y29kZT5TdHJpbmc8L2NvZGU+IHZhbHVlCi0gICAqIEBwYXJhbSB2YWx1ZSBhbiA8Y29kZT5PYmplY3Q8L2NvZGU+IHZhbHVlCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRQcm9wZXJ0eShTdHJpbmcgcHJvcGVydHksIE9iamVjdCB2YWx1ZSk7Ci0KLSAgLy8gPT09PT09PT09IERvY3VtZW50IE5hdmlnYXRpb24gRnVuY3Rpb25zID09PT09PT09PQotCi0gIC8qKgotICAgKiBUaGlzIHJldHVybnMgYSBzdGF0ZWxlc3MgInRyYXZlcnNlciIsIHRoYXQgY2FuIG5hdmlnYXRlIG92ZXIgYW4KLSAgICogWFBhdGggYXhpcywgdGhvdWdoIG5vdCBpbiBkb2N1bWVudCBvcmRlci4KLSAgICoKLSAgICogQHBhcmFtIGF4aXMgT25lIG9mIEF4ZXMuQU5DRVNUT1JPUlNFTEYsIGV0Yy4KLSAgICoKLSAgICogQHJldHVybiBBIERUTUF4aXNJdGVyYXRvciwgb3IgbnVsbCBpZiB0aGUgZ2l2aW4gYXhpcyBpc24ndCBzdXBwb3J0ZWQuCi0gICAqLwotICBwdWJsaWMgRFRNQXhpc1RyYXZlcnNlciBnZXRBeGlzVHJhdmVyc2VyKGZpbmFsIGludCBheGlzKTsKLQotICAvKioKLSAgICogVGhpcyBpcyBhIHNob3J0Y3V0IHRvIHRoZSBpdGVyYXRvcnMgdGhhdCBpbXBsZW1lbnQKLSAgICogWFBhdGggYXhlcy4KLSAgICogUmV0dXJucyBhIGJhcmUtYm9uZXMgaXRlcmF0b3IgdGhhdCBtdXN0IGJlIGluaXRpYWxpemVkCi0gICAqIHdpdGggYSBzdGFydCBub2RlICh1c2luZyBpdGVyYXRvci5zZXRTdGFydE5vZGUoKSkuCi0gICAqCi0gICAqIEBwYXJhbSBheGlzIE9uZSBvZiBBeGVzLkFOQ0VTVE9ST1JTRUxGLCBldGMuCi0gICAqCi0gICAqIEByZXR1cm4gQSBEVE1BeGlzSXRlcmF0b3IsIG9yIG51bGwgaWYgdGhlIGdpdmluIGF4aXMgaXNuJ3Qgc3VwcG9ydGVkLgotICAgKi8KLSAgcHVibGljIERUTUF4aXNJdGVyYXRvciBnZXRBeGlzSXRlcmF0b3IoZmluYWwgaW50IGF4aXMpOwotCi0gIC8qKgotICAgKiBHZXQgYW4gaXRlcmF0b3IgdGhhdCBjYW4gbmF2aWdhdGUgb3ZlciBhbiBYUGF0aCBBeGlzLCBwcmVkaWNhdGVkIGJ5Ci0gICAqIHRoZSBleHRlbmRlZCB0eXBlIElELgotICAgKgotICAgKiBAcGFyYW0gYXhpcwotICAgKiBAcGFyYW0gdHlwZSBBbiBleHRlbmRlZCB0eXBlIElELgotICAgKgotICAgKiBAcmV0dXJuIEEgRFRNQXhpc0l0ZXJhdG9yLCBvciBudWxsIGlmIHRoZSBnaXZpbiBheGlzIGlzbid0IHN1cHBvcnRlZC4KLSAgICovCi0gIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3IgZ2V0VHlwZWRBeGlzSXRlcmF0b3IoZmluYWwgaW50IGF4aXMsIGZpbmFsIGludCB0eXBlKTsKLQotICAvKioKLSAgICogR2l2ZW4gYSBub2RlIGhhbmRsZSwgdGVzdCBpZiBpdCBoYXMgY2hpbGQgbm9kZXMuCi0gICAqIDxwPiAlUkVWSUVXJSBUaGlzIGlzIG9idmlvdXNseSB1c2VmdWwgYXQgdGhlIERPTSBsYXllciwgd2hlcmUgaXQKLSAgICogd291bGQgcGVybWl0IHRlc3RpbmcgdGhpcyB3aXRob3V0IGhhdmluZyB0byBjcmVhdGUgYSBwcm94eQotICAgKiBub2RlLiBJdCdzIGxlc3MgdXNlZnVsIGluIHRoZSBEVE0gQVBJLCB3aGVyZQotICAgKiAoZHRtLmdldEZpcnN0Q2hpbGQobm9kZUhhbmRsZSkhPURUTS5OVUxMKSBpcyBqdXN0IGFzIGZhc3QgYW5kCi0gICAqIGFsbW9zdCBhcyBzZWxmLWV2aWRlbnQuIEJ1dCBpdCdzIGEgY29udmVuaWVuY2UsIGFuZCBlYXNlcyBwb3J0aW5nCi0gICAqIG9mIERPTSBjb2RlIHRvIERUTS4gIDwvcD4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgaW50IEhhbmRsZSBvZiB0aGUgbm9kZS4KLSAgICogQHJldHVybiBpbnQgdHJ1ZSBpZiB0aGUgZ2l2ZW4gbm9kZSBoYXMgY2hpbGQgbm9kZXMuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBoYXNDaGlsZE5vZGVzKGludCBub2RlSGFuZGxlKTsKLQotICAvKioKLSAgICogR2l2ZW4gYSBub2RlIGhhbmRsZSwgZ2V0IHRoZSBoYW5kbGUgb2YgdGhlIG5vZGUncyBmaXJzdCBjaGlsZC4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgaW50IEhhbmRsZSBvZiB0aGUgbm9kZS4KLSAgICogQHJldHVybiBpbnQgRFRNIG5vZGUtbnVtYmVyIG9mIGZpcnN0IGNoaWxkLAotICAgKiBvciBEVE0uTlVMTCB0byBpbmRpY2F0ZSBub25lIGV4aXN0cy4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0Rmlyc3RDaGlsZChpbnQgbm9kZUhhbmRsZSk7Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIGdldCB0aGUgaGFuZGxlIG9mIHRoZSBub2RlJ3MgbGFzdCBjaGlsZC4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgaW50IEhhbmRsZSBvZiB0aGUgbm9kZS4KLSAgICogQHJldHVybiBpbnQgTm9kZS1udW1iZXIgb2YgbGFzdCBjaGlsZCwKLSAgICogb3IgRFRNLk5VTEwgdG8gaW5kaWNhdGUgbm9uZSBleGlzdHMuCi0gICAqLwotICBwdWJsaWMgaW50IGdldExhc3RDaGlsZChpbnQgbm9kZUhhbmRsZSk7Ci0KLSAgLyoqCi0gICAqIFJldHJpZXZlcyBhbiBhdHRyaWJ1dGUgbm9kZSBieSBsb2NhbCBuYW1lIGFuZCBuYW1lc3BhY2UgVVJJCi0gICAqCi0gICAqICVUQkQlIE5vdGUgdGhhdCB3ZSBjdXJyZW50bHkgaGF2ZSBubyB3YXkgdG8gc3VwcG9ydAotICAgKiB0aGUgRE9NJ3Mgb2xkIGdldEF0dHJpYnV0ZSgpIGNhbGwsIHdoaWNoIGFjY2Vzc2VzIG9ubHkgdGhlIHFuYW1lLgotICAgKgotICAgKiBAcGFyYW0gZWxlbWVudEhhbmRsZSBIYW5kbGUgb2YgdGhlIG5vZGUgdXBvbiB3aGljaCB0byBsb29rIHVwIHRoaXMgYXR0cmlidXRlLgotICAgKiBAcGFyYW0gbmFtZXNwYWNlVVJJIFRoZSBuYW1lc3BhY2UgVVJJIG9mIHRoZSBhdHRyaWJ1dGUgdG8KLSAgICogICByZXRyaWV2ZSwgb3IgbnVsbC4KLSAgICogQHBhcmFtIG5hbWUgVGhlIGxvY2FsIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZSB0bwotICAgKiAgIHJldHJpZXZlLgotICAgKiBAcmV0dXJuIFRoZSBhdHRyaWJ1dGUgbm9kZSBoYW5kbGUgd2l0aCB0aGUgc3BlY2lmaWVkIG5hbWUgKAotICAgKiAgIDxjb2RlPm5vZGVOYW1lPC9jb2RlPikgb3IgPGNvZGU+RFRNLk5VTEw8L2NvZGU+IGlmIHRoZXJlIGlzIG5vIHN1Y2gKLSAgICogICBhdHRyaWJ1dGUuCi0gICAqLwotICBwdWJsaWMgaW50IGdldEF0dHJpYnV0ZU5vZGUoaW50IGVsZW1lbnRIYW5kbGUsIFN0cmluZyBuYW1lc3BhY2VVUkksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbmFtZSk7Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIGdldCB0aGUgaW5kZXggb2YgdGhlIG5vZGUncyBmaXJzdCBhdHRyaWJ1dGUuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIGludCBIYW5kbGUgb2YgdGhlIG5vZGUuCi0gICAqIEByZXR1cm4gSGFuZGxlIG9mIGZpcnN0IGF0dHJpYnV0ZSwgb3IgRFRNLk5VTEwgdG8gaW5kaWNhdGUgbm9uZSBleGlzdHMuCi0gICAqLwotICBwdWJsaWMgaW50IGdldEZpcnN0QXR0cmlidXRlKGludCBub2RlSGFuZGxlKTsKLQotICAvKioKLSAgICogR2l2ZW4gYSBub2RlIGhhbmRsZSwgZ2V0IHRoZSBpbmRleCBvZiB0aGUgbm9kZSdzIGZpcnN0IG5hbWVzcGFjZSBub2RlLgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBoYW5kbGUgdG8gbm9kZSwgd2hpY2ggc2hvdWxkIHByb2JhYmx5IGJlIGFuIGVsZW1lbnQKLSAgICogICAgICAgICAgICAgICAgICAgbm9kZSwgYnV0IG5lZWQgbm90IGJlLgotICAgKgotICAgKiBAcGFyYW0gaW5TY29wZSB0cnVlIGlmIGFsbCBuYW1lc3BhY2VzIGluIHNjb3BlIHNob3VsZCBiZQotICAgKiAgICAgICAgICAgICAgICAgICByZXR1cm5lZCwgZmFsc2UgaWYgb25seSB0aGUgbm9kZSdzIG93bgotICAgKiAgICAgICAgICAgICAgICAgICBuYW1lc3BhY2UgZGVjbGFyYXRpb25zIHNob3VsZCBiZSByZXR1cm5lZC4KLSAgICogQHJldHVybiBoYW5kbGUgb2YgZmlyc3QgbmFtZXNwYWNlLAotICAgKiBvciBEVE0uTlVMTCB0byBpbmRpY2F0ZSBub25lIGV4aXN0cy4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0Rmlyc3ROYW1lc3BhY2VOb2RlKGludCBub2RlSGFuZGxlLCBib29sZWFuIGluU2NvcGUpOwotCi0gIC8qKgotICAgKiBHaXZlbiBhIG5vZGUgaGFuZGxlLCBhZHZhbmNlIHRvIGl0cyBuZXh0IHNpYmxpbmcuCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIGludCBIYW5kbGUgb2YgdGhlIG5vZGUuCi0gICAqIEByZXR1cm4gaW50IE5vZGUtbnVtYmVyIG9mIG5leHQgc2libGluZywKLSAgICogb3IgRFRNLk5VTEwgdG8gaW5kaWNhdGUgbm9uZSBleGlzdHMuCi0gICAqLwotICBwdWJsaWMgaW50IGdldE5leHRTaWJsaW5nKGludCBub2RlSGFuZGxlKTsKLQotICAvKioKLSAgICogR2l2ZW4gYSBub2RlIGhhbmRsZSwgZmluZCBpdHMgcHJlY2VlZGluZyBzaWJsaW5nLgotICAgKiBXQVJOSU5HOiBEVE0gaW1wbGVtZW50YXRpb25zIG1heSBiZSBhc3ltbWV0cmljOyBpbiBzb21lLAotICAgKiB0aGlzIG9wZXJhdGlvbiBoYXMgYmVlbiByZXNvbHZlZCBieSBzZWFyY2gsIGFuZCBpcyByZWxhdGl2ZWx5IGV4cGVuc2l2ZS4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgdGhlIGlkIG9mIHRoZSBub2RlLgotICAgKiBAcmV0dXJuIGludCBOb2RlLW51bWJlciBvZiB0aGUgcHJldmlvdXMgc2liLAotICAgKiBvciBEVE0uTlVMTCB0byBpbmRpY2F0ZSBub25lIGV4aXN0cy4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0UHJldmlvdXNTaWJsaW5nKGludCBub2RlSGFuZGxlKTsKLQotICAvKioKLSAgICogR2l2ZW4gYSBub2RlIGhhbmRsZSwgYWR2YW5jZSB0byB0aGUgbmV4dCBhdHRyaWJ1dGUuIElmIGFuCi0gICAqIGVsZW1lbnQsIHdlIGFkdmFuY2UgdG8gaXRzIGZpcnN0IGF0dHJpYnV0ZTsgaWYgYW4gYXR0ciwgd2UgYWR2YW5jZSB0bwotICAgKiB0aGUgbmV4dCBhdHRyIG9mIHRoZSBzYW1lIGVsZW1lbnQuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIGludCBIYW5kbGUgb2YgdGhlIG5vZGUuCi0gICAqIEByZXR1cm4gaW50IERUTSBub2RlLW51bWJlciBvZiB0aGUgcmVzb2x2ZWQgYXR0ciwKLSAgICogb3IgRFRNLk5VTEwgdG8gaW5kaWNhdGUgbm9uZSBleGlzdHMuCi0gICAqLwotICBwdWJsaWMgaW50IGdldE5leHRBdHRyaWJ1dGUoaW50IG5vZGVIYW5kbGUpOwotCi0gIC8qKgotICAgKiBHaXZlbiBhIG5hbWVzcGFjZSBoYW5kbGUsIGFkdmFuY2UgdG8gdGhlIG5leHQgbmFtZXNwYWNlIGluIHRoZSBzYW1lIHNjb3BlCi0gICAqIChsb2NhbCBvciBsb2NhbC1wbHVzLWluaGVyaXRlZCwgYXMgc2VsZWN0ZWQgYnkgZ2V0Rmlyc3ROYW1lc3BhY2VOb2RlKQotICAgKgotICAgKiBAcGFyYW0gYmFzZUhhbmRsZSBoYW5kbGUgdG8gb3JpZ2luYWwgbm9kZSBmcm9tIHdoZXJlIHRoZSBmaXJzdCBjaGlsZAotICAgKiB3YXMgcmVsYXRpdmUgdG8gKG5lZWRlZCB0byByZXR1cm4gbm9kZXMgaW4gZG9jdW1lbnQgb3JkZXIpLgotICAgKiBAcGFyYW0gbmFtZXNwYWNlSGFuZGxlIGhhbmRsZSB0byBub2RlIHdoaWNoIG11c3QgYmUgb2YgdHlwZQotICAgKiBOQU1FU1BBQ0VfTk9ERS4KLSAgICogTkVFRFNET0MgQHBhcmFtIGluU2NvcGUKLSAgICogQHJldHVybiBoYW5kbGUgb2YgbmV4dCBuYW1lc3BhY2UsCi0gICAqIG9yIERUTS5OVUxMIHRvIGluZGljYXRlIG5vbmUgZXhpc3RzLgotICAgKi8KLSAgcHVibGljIGludCBnZXROZXh0TmFtZXNwYWNlTm9kZShpbnQgYmFzZUhhbmRsZSwgaW50IG5hbWVzcGFjZUhhbmRsZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGluU2NvcGUpOwotCi0gIC8qKgotICAgKiBHaXZlbiBhIG5vZGUgaGFuZGxlLCBmaW5kIGl0cyBwYXJlbnQgbm9kZS4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgdGhlIGlkIG9mIHRoZSBub2RlLgotICAgKiBAcmV0dXJuIGludCBOb2RlIGhhbmRsZSBvZiBwYXJlbnQsCi0gICAqIG9yIERUTS5OVUxMIHRvIGluZGljYXRlIG5vbmUgZXhpc3RzLgotICAgKi8KLSAgcHVibGljIGludCBnZXRQYXJlbnQoaW50IG5vZGVIYW5kbGUpOwotCi0gIC8qKgotICAgKiBHaXZlbiBhIERUTSB3aGljaCBjb250YWlucyBvbmx5IGEgc2luZ2xlIGRvY3VtZW50LAotICAgKiBmaW5kIHRoZSBOb2RlIEhhbmRsZSBvZiB0aGUgIERvY3VtZW50IG5vZGUuIE5vdGUKLSAgICogdGhhdCBpZiB0aGUgRFRNIGlzIGNvbmZpZ3VyZWQgc28gaXQgY2FuIGNvbnRhaW4gbXVsdGlwbGUKLSAgICogZG9jdW1lbnRzLCB0aGlzIGNhbGwgd2lsbCByZXR1cm4gdGhlIERvY3VtZW50IGN1cnJlbnRseQotICAgKiB1bmRlciBjb25zdHJ1Y3Rpb24gLS0gYnV0IG1heSByZXR1cm4gbnVsbCBpZiBpdCdzIGJldHdlZW4KLSAgICogZG9jdW1lbnRzLiBHZW5lcmFsbHksIHlvdSBzaG91bGQgdXNlIGdldE93bmVyRG9jdW1lbnQobm9kZUhhbmRsZSkKLSAgICogb3IgZ2V0RG9jdW1lbnRSb290KG5vZGVIYW5kbGUpIGluc3RlYWQuCi0gICAqCi0gICAqIEByZXR1cm4gaW50IE5vZGUgaGFuZGxlIG9mIGRvY3VtZW50LCBvciBEVE0uTlVMTCBpZiBhIHNoYXJlZCBEVE0KLSAgICogY2FuIG5vdCB0ZWxsIHVzIHdoaWNoIERvY3VtZW50IGlzIGN1cnJlbnRseSBhY3RpdmUuCi0gICAqLwotICBwdWJsaWMgaW50IGdldERvY3VtZW50KCk7Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIGZpbmQgdGhlIG93bmluZyBkb2N1bWVudCBub2RlLiBUaGlzIHZlcnNpb24gbWltaWNzCi0gICAqIHRoZSBiZWhhdmlvciBvZiB0aGUgRE9NIGNhbGwgYnkgdGhlIHNhbWUgbmFtZS4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgdGhlIGlkIG9mIHRoZSBub2RlLgotICAgKiBAcmV0dXJuIGludCBOb2RlIGhhbmRsZSBvZiBvd25pbmcgZG9jdW1lbnQsIG9yIERUTS5OVUxMIGlmIHRoZSBub2RlIHdhcwotICAgKiBhIERvY3VtZW50LgotICAgKiBAc2VlICNnZXREb2N1bWVudFJvb3QoaW50IG5vZGVIYW5kbGUpCi0gICAqLwotICBwdWJsaWMgaW50IGdldE93bmVyRG9jdW1lbnQoaW50IG5vZGVIYW5kbGUpOwotCi0gIC8qKgotICAgKiBHaXZlbiBhIG5vZGUgaGFuZGxlLCBmaW5kIHRoZSBvd25pbmcgZG9jdW1lbnQgbm9kZS4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgdGhlIGlkIG9mIHRoZSBub2RlLgotICAgKiBAcmV0dXJuIGludCBOb2RlIGhhbmRsZSBvZiBvd25pbmcgZG9jdW1lbnQsIG9yIHRoZSBub2RlIGl0c2VsZiBpZiBpdCB3YXMKLSAgICogYSBEb2N1bWVudC4gKE5vdGUgZGlmZmVyZW5jZSBmcm9tIERPTSwgd2hlcmUgZ2V0T3duZXJEb2N1bWVudCByZXR1cm5zCi0gICAqIG51bGwgZm9yIHRoZSBEb2N1bWVudCBub2RlLikKLSAgICogQHNlZSAjZ2V0T3duZXJEb2N1bWVudChpbnQgbm9kZUhhbmRsZSkKLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0RG9jdW1lbnRSb290KGludCBub2RlSGFuZGxlKTsKLQotICAvKioKLSAgICogR2V0IHRoZSBzdHJpbmctdmFsdWUgb2YgYSBub2RlIGFzIGEgU3RyaW5nIG9iamVjdAotICAgKiAoc2VlIGh0dHA6Ly93d3cudzMub3JnL1RSL3hwYXRoI2RhdGEtbW9kZWwKLSAgICogZm9yIHRoZSBkZWZpbml0aW9uIG9mIGEgbm9kZSdzIHN0cmluZy12YWx1ZSkuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIFRoZSBub2RlIElELgotICAgKgotICAgKiBAcmV0dXJuIEEgc3RyaW5nIG9iamVjdCB0aGF0IHJlcHJlc2VudHMgdGhlIHN0cmluZy12YWx1ZSBvZiB0aGUgZ2l2ZW4gbm9kZS4KLSAgICovCi0gIHB1YmxpYyBYTUxTdHJpbmcgZ2V0U3RyaW5nVmFsdWUoaW50IG5vZGVIYW5kbGUpOwotCi0gIC8qKgotICAgKiBHZXQgbnVtYmVyIG9mIGNoYXJhY3RlciBhcnJheSBjaHVua3MgaW4KLSAgICogdGhlIHN0cmluZy12YWx1ZSBvZiBhIG5vZGUuCi0gICAqIChzZWUgaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGgjZGF0YS1tb2RlbAotICAgKiBmb3IgdGhlIGRlZmluaXRpb24gb2YgYSBub2RlJ3Mgc3RyaW5nLXZhbHVlKS4KLSAgICogTm90ZSB0aGF0IGEgc2luZ2xlIHRleHQgbm9kZSBtYXkgaGF2ZSBtdWx0aXBsZSB0ZXh0IGNodW5rcy4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgVGhlIG5vZGUgSUQuCi0gICAqCi0gICAqIEByZXR1cm4gbnVtYmVyIG9mIGNoYXJhY3RlciBhcnJheSBjaHVua3MgaW4KLSAgICogICAgICAgICB0aGUgc3RyaW5nLXZhbHVlIG9mIGEgbm9kZS4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0U3RyaW5nVmFsdWVDaHVua0NvdW50KGludCBub2RlSGFuZGxlKTsKLQotICAvKioKLSAgICogR2V0IGEgY2hhcmFjdGVyIGFycmF5IGNodW5rIGluIHRoZSBzdHJpbmctdmFsdWUgb2YgYSBub2RlLgotICAgKiAoc2VlIGh0dHA6Ly93d3cudzMub3JnL1RSL3hwYXRoI2RhdGEtbW9kZWwKLSAgICogZm9yIHRoZSBkZWZpbml0aW9uIG9mIGEgbm9kZSdzIHN0cmluZy12YWx1ZSkuCi0gICAqIE5vdGUgdGhhdCBhIHNpbmdsZSB0ZXh0IG5vZGUgbWF5IGhhdmUgbXVsdGlwbGUgdGV4dCBjaHVua3MuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIFRoZSBub2RlIElELgotICAgKiBAcGFyYW0gY2h1bmtJbmRleCBXaGljaCBjaHVuayB0byBnZXQuCi0gICAqIEBwYXJhbSBzdGFydEFuZExlbiAgQSB0d28taW50ZWdlciBhcnJheSB3aGljaCwgdXBvbiByZXR1cm4sIFdJTEwKLSAgICogQkUgRklMTEVEIHdpdGggdmFsdWVzIHJlcHJlc2VudGluZyB0aGUgY2h1bmsncyBzdGFydCBwb3NpdGlvbgotICAgKiB3aXRoaW4gdGhlIHJldHVybmVkIGNoYXJhY3RlciBidWZmZXIgYW5kIHRoZSBsZW5ndGggb2YgdGhlIGNodW5rLgotICAgKiBAcmV0dXJuIFRoZSBjaGFyYWN0ZXIgYXJyYXkgYnVmZmVyIHdpdGhpbiB3aGljaCB0aGUgY2h1bmsgb2NjdXJzLAotICAgKiBzZXR0aW5nIHN0YXJ0QW5kTGVuJ3MgY29udGVudHMgYXMgYSBzaWRlLWVmZmVjdC4KLSAgICovCi0gIHB1YmxpYyBjaGFyW10gZ2V0U3RyaW5nVmFsdWVDaHVuayhpbnQgbm9kZUhhbmRsZSwgaW50IGNodW5rSW5kZXgsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnRbXSBzdGFydEFuZExlbik7Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIHJldHVybiBhbiBJRCB0aGF0IHJlcHJlc2VudHMgdGhlIG5vZGUncyBleHBhbmRlZCBuYW1lLgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBUaGUgaGFuZGxlIHRvIHRoZSBub2RlIGluIHF1ZXN0aW9uLgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBleHBhbmRlZC1uYW1lIGlkIG9mIHRoZSBub2RlLgotICAgKi8KLSAgcHVibGljIGludCBnZXRFeHBhbmRlZFR5cGVJRChpbnQgbm9kZUhhbmRsZSk7Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGFuIGV4cGFuZGVkIG5hbWUsIHJldHVybiBhbiBJRC4gIElmIHRoZSBleHBhbmRlZC1uYW1lIGRvZXMgbm90Ci0gICAqIGV4aXN0IGluIHRoZSBpbnRlcm5hbCB0YWJsZXMsIHRoZSBlbnRyeSB3aWxsIGJlIGNyZWF0ZWQsIGFuZCB0aGUgSUQgd2lsbAotICAgKiBiZSByZXR1cm5lZC4gIEFueSBhZGRpdGlvbmFsIG5vZGVzIHRoYXQgYXJlIGNyZWF0ZWQgdGhhdCBoYXZlIHRoaXMKLSAgICogZXhwYW5kZWQgbmFtZSB3aWxsIHVzZSB0aGlzIElELgotICAgKgotICAgKiBORUVEU0RPQyBAcGFyYW0gbmFtZXNwYWNlCi0gICAqIE5FRURTRE9DIEBwYXJhbSBsb2NhbE5hbWUKLSAgICogTkVFRFNET0MgQHBhcmFtIHR5cGUKLSAgICoKLSAgICogQHJldHVybiB0aGUgZXhwYW5kZWQtbmFtZSBpZCBvZiB0aGUgbm9kZS4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0RXhwYW5kZWRUeXBlSUQoU3RyaW5nIG5hbWVzcGFjZSwgU3RyaW5nIGxvY2FsTmFtZSwgaW50IHR5cGUpOwotCi0gIC8qKgotICAgKiBHaXZlbiBhbiBleHBhbmRlZC1uYW1lIElELCByZXR1cm4gdGhlIGxvY2FsIG5hbWUgcGFydC4KLSAgICoKLSAgICogQHBhcmFtIEV4cGFuZGVkTmFtZUlEIGFuIElEIHRoYXQgcmVwcmVzZW50cyBhbiBleHBhbmRlZC1uYW1lLgotICAgKiBAcmV0dXJuIFN0cmluZyBMb2NhbCBuYW1lIG9mIHRoaXMgbm9kZS4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0TG9jYWxOYW1lRnJvbUV4cGFuZGVkTmFtZUlEKGludCBFeHBhbmRlZE5hbWVJRCk7Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGFuIGV4cGFuZGVkLW5hbWUgSUQsIHJldHVybiB0aGUgbmFtZXNwYWNlIFVSSSBwYXJ0LgotICAgKgotICAgKiBAcGFyYW0gRXhwYW5kZWROYW1lSUQgYW4gSUQgdGhhdCByZXByZXNlbnRzIGFuIGV4cGFuZGVkLW5hbWUuCi0gICAqIEByZXR1cm4gU3RyaW5nIFVSSSB2YWx1ZSBvZiB0aGlzIG5vZGUncyBuYW1lc3BhY2UsIG9yIG51bGwgaWYgbm8KLSAgICogbmFtZXNwYWNlIHdhcyByZXNvbHZlZC4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZXNwYWNlRnJvbUV4cGFuZGVkTmFtZUlEKGludCBFeHBhbmRlZE5hbWVJRCk7Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIHJldHVybiBpdHMgRE9NLXN0eWxlIG5vZGUgbmFtZS4gVGhpcyB3aWxsCi0gICAqIGluY2x1ZGUgbmFtZXMgc3VjaCBhcyAjdGV4dCBvciAjZG9jdW1lbnQuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIHRoZSBpZCBvZiB0aGUgbm9kZS4KLSAgICogQHJldHVybiBTdHJpbmcgTmFtZSBvZiB0aGlzIG5vZGUsIHdoaWNoIG1heSBiZSBhbiBlbXB0eSBzdHJpbmcuCi0gICAqICVSRVZJRVclIERvY3VtZW50IHdoZW4gZW1wdHkgc3RyaW5nIGlzIHBvc3NpYmxlLi4uCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldE5vZGVOYW1lKGludCBub2RlSGFuZGxlKTsKLQotICAvKioKLSAgICogR2l2ZW4gYSBub2RlIGhhbmRsZSwgcmV0dXJuIHRoZSBYUGF0aCBub2RlIG5hbWUuICBUaGlzIHNob3VsZCBiZQotICAgKiB0aGUgbmFtZSBhcyBkZXNjcmliZWQgYnkgdGhlIFhQYXRoIGRhdGEgbW9kZWwsIE5PVCB0aGUgRE9NLXN0eWxlCi0gICAqIG5hbWUuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIHRoZSBpZCBvZiB0aGUgbm9kZS4KLSAgICogQHJldHVybiBTdHJpbmcgTmFtZSBvZiB0aGlzIG5vZGUuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldE5vZGVOYW1lWChpbnQgbm9kZUhhbmRsZSk7Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIHJldHVybiBpdHMgRE9NLXN0eWxlIGxvY2FsbmFtZS4KLSAgICogKEFzIGRlZmluZWQgaW4gTmFtZXNwYWNlcywgdGhpcyBpcyB0aGUgcG9ydGlvbiBvZiB0aGUgbmFtZSBhZnRlciB0aGUKLSAgICogcHJlZml4LCBpZiBwcmVzZW50LCBvciB0aGUgd2hvbGUgbm9kZSBuYW1lIGlmIG5vIHByZWZpeCBleGlzdHMpCi0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIHRoZSBpZCBvZiB0aGUgbm9kZS4KLSAgICogQHJldHVybiBTdHJpbmcgTG9jYWwgbmFtZSBvZiB0aGlzIG5vZGUuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldExvY2FsTmFtZShpbnQgbm9kZUhhbmRsZSk7Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgbmFtZXNwYWNlIGhhbmRsZSwgcmV0dXJuIHRoZSBwcmVmaXggdGhhdCB0aGUgbmFtZXNwYWNlIGRlY2wgaXMKLSAgICogbWFwcGluZy4KLSAgICogR2l2ZW4gYSBub2RlIGhhbmRsZSwgcmV0dXJuIHRoZSBwcmVmaXggdXNlZCB0byBtYXAgdG8gdGhlIG5hbWVzcGFjZS4KLSAgICogKEFzIGRlZmluZWQgaW4gTmFtZXNwYWNlcywgdGhpcyBpcyB0aGUgcG9ydGlvbiBvZiB0aGUgbmFtZSBiZWZvcmUgYW55Ci0gICAqIGNvbG9uIGNoYXJhY3RlcikuCi0gICAqCi0gICAqIDxwPiAlUkVWSUVXJSBBcmUgeW91IHN1cmUgeW91IHdhbnQgIiIgZm9yIG5vIHByZWZpeD8gIDwvcD4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgdGhlIGlkIG9mIHRoZSBub2RlLgotICAgKiBAcmV0dXJuIFN0cmluZyBwcmVmaXggb2YgdGhpcyBub2RlJ3MgbmFtZSwgb3IgIiIgaWYgbm8gZXhwbGljaXQKLSAgICogbmFtZXNwYWNlIHByZWZpeCB3YXMgZ2l2ZW4uCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFByZWZpeChpbnQgbm9kZUhhbmRsZSk7Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIHJldHVybiBpdHMgRE9NLXN0eWxlIG5hbWVzcGFjZSBVUkkKLSAgICogKEFzIGRlZmluZWQgaW4gTmFtZXNwYWNlcywgdGhpcyBpcyB0aGUgZGVjbGFyZWQgVVJJIHdoaWNoIHRoaXMgbm9kZSdzCi0gICAqIHByZWZpeCAtLSBvciBkZWZhdWx0IGluIGxpZXUgdGhlcmVvZiAtLSB3YXMgbWFwcGVkIHRvLikKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgdGhlIGlkIG9mIHRoZSBub2RlLgotICAgKiBAcmV0dXJuIFN0cmluZyBVUkkgdmFsdWUgb2YgdGhpcyBub2RlJ3MgbmFtZXNwYWNlLCBvciBudWxsIGlmIG5vCi0gICAqIG5hbWVzcGFjZSB3YXMgcmVzb2x2ZWQuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldE5hbWVzcGFjZVVSSShpbnQgbm9kZUhhbmRsZSk7Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIHJldHVybiBpdHMgbm9kZSB2YWx1ZS4gVGhpcyBpcyBtb3N0bHkKLSAgICogYXMgZGVmaW5lZCBieSB0aGUgRE9NLCBidXQgbWF5IGlnbm9yZSBzb21lIGNvbnZlbmllbmNlcy4KLSAgICogPHA+Ci0gICAqIEBwYXJhbSBub2RlSGFuZGxlIFRoZSBub2RlIGlkLgotICAgKiBAcmV0dXJuIFN0cmluZyBWYWx1ZSBvZiB0aGlzIG5vZGUsIG9yIG51bGwgaWYgbm90Ci0gICAqIG1lYW5pbmdmdWwgZm9yIHRoaXMgbm9kZSB0eXBlLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXROb2RlVmFsdWUoaW50IG5vZGVIYW5kbGUpOwotCi0gIC8qKgotICAgKiBHaXZlbiBhIG5vZGUgaGFuZGxlLCByZXR1cm4gaXRzIERPTS1zdHlsZSBub2RlIHR5cGUuCi0gICAqCi0gICAqIDxwPiVSRVZJRVclIEdlbmVyYWxseSwgcmV0dXJuaW5nIHNob3J0IGlzIGZhbHNlIGVjb25vbXkuIFJldHVybiBpbnQ/PC9wPgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBUaGUgbm9kZSBpZC4KLSAgICogQHJldHVybiBpbnQgTm9kZSB0eXBlLCBhcyBwZXIgdGhlIERPTSdzIE5vZGUuX05PREUgY29uc3RhbnRzLgotICAgKi8KLSAgcHVibGljIHNob3J0IGdldE5vZGVUeXBlKGludCBub2RlSGFuZGxlKTsKLQotICAvKioKLSAgICogR2V0IHRoZSBkZXB0aCBsZXZlbCBvZiB0aGlzIG5vZGUgaW4gdGhlIHRyZWUgKGVxdWFscyAxIGZvcgotICAgKiBhIHBhcmVudGxlc3Mgbm9kZSkuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIFRoZSBub2RlIGlkLgotICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgYW5jZXN0b3JzLCBwbHVzIG9uZQotICAgKiBAeHNsLnVzYWdlIGludGVybmFsCi0gICAqLwotICBwdWJsaWMgc2hvcnQgZ2V0TGV2ZWwoaW50IG5vZGVIYW5kbGUpOwotCi0gIC8vID09PT09PT09PT09PT09IERvY3VtZW50IHF1ZXJ5IGZ1bmN0aW9ucyA9PT09PT09PT09PT09PQotCi0gIC8qKgotICAgKiBUZXN0cyB3aGV0aGVyIERUTSBET00gaW1wbGVtZW50YXRpb24gaW1wbGVtZW50cyBhIHNwZWNpZmljIGZlYXR1cmUgYW5kCi0gICAqIHRoYXQgZmVhdHVyZSBpcyBzdXBwb3J0ZWQgYnkgdGhpcyBub2RlLgotICAgKiBAcGFyYW0gZmVhdHVyZSBUaGUgbmFtZSBvZiB0aGUgZmVhdHVyZSB0byB0ZXN0LgotICAgKiBAcGFyYW0gdmVyc2lvbiBUaGlzIGlzIHRoZSB2ZXJzaW9uIG51bWJlciBvZiB0aGUgZmVhdHVyZSB0byB0ZXN0LgotICAgKiAgIElmIHRoZSB2ZXJzaW9uIGlzIG5vdAotICAgKiAgIHNwZWNpZmllZCwgc3VwcG9ydGluZyBhbnkgdmVyc2lvbiBvZiB0aGUgZmVhdHVyZSB3aWxsIGNhdXNlIHRoZQotICAgKiAgIG1ldGhvZCB0byByZXR1cm4gPGNvZGU+dHJ1ZTwvY29kZT4uCi0gICAqIEByZXR1cm4gUmV0dXJucyA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgc3BlY2lmaWVkIGZlYXR1cmUgaXMKLSAgICogICBzdXBwb3J0ZWQgb24gdGhpcyBub2RlLCA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNTdXBwb3J0ZWQoU3RyaW5nIGZlYXR1cmUsIFN0cmluZyB2ZXJzaW9uKTsKLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBiYXNlIFVSSSBvZiB0aGUgZG9jdW1lbnQgZW50aXR5LiBJZiBpdCBpcyBub3Qga25vd24KLSAgICogKGJlY2F1c2UgdGhlIGRvY3VtZW50IHdhcyBwYXJzZWQgZnJvbSBhIHNvY2tldCBjb25uZWN0aW9uIG9yIGZyb20KLSAgICogc3RhbmRhcmQgaW5wdXQsIGZvciBleGFtcGxlKSwgdGhlIHZhbHVlIG9mIHRoaXMgcHJvcGVydHkgaXMgdW5rbm93bi4KLSAgICoKLSAgICogQHJldHVybiB0aGUgZG9jdW1lbnQgYmFzZSBVUkkgU3RyaW5nIG9iamVjdCBvciBudWxsIGlmIHVua25vd24uCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldERvY3VtZW50QmFzZVVSSSgpOwotCi0gIC8qKgotICAgKiBTZXQgdGhlIGJhc2UgVVJJIG9mIHRoZSBkb2N1bWVudCBlbnRpdHkuCi0gICAqCi0gICAqIEBwYXJhbSBiYXNlVVJJIHRoZSBkb2N1bWVudCBiYXNlIFVSSSBTdHJpbmcgb2JqZWN0IG9yIG51bGwgaWYgdW5rbm93bi4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldERvY3VtZW50QmFzZVVSSShTdHJpbmcgYmFzZVVSSSk7Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgc3lzdGVtIGlkZW50aWZpZXIgb2YgdGhlIGRvY3VtZW50IGVudGl0eS4gSWYKLSAgICogaXQgaXMgbm90IGtub3duLCB0aGUgdmFsdWUgb2YgdGhpcyBwcm9wZXJ0eSBpcyBudWxsLgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBUaGUgbm9kZSBpZCwgd2hpY2ggY2FuIGJlIGFueSB2YWxpZCBub2RlIGhhbmRsZS4KLSAgICogQHJldHVybiB0aGUgc3lzdGVtIGlkZW50aWZpZXIgU3RyaW5nIG9iamVjdCBvciBudWxsIGlmIHVua25vd24uCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldERvY3VtZW50U3lzdGVtSWRlbnRpZmllcihpbnQgbm9kZUhhbmRsZSk7Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgbmFtZSBvZiB0aGUgY2hhcmFjdGVyIGVuY29kaW5nIHNjaGVtZQotICAgKiAgICAgICAgaW4gd2hpY2ggdGhlIGRvY3VtZW50IGVudGl0eSBpcyBleHByZXNzZWQuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIFRoZSBub2RlIGlkLCB3aGljaCBjYW4gYmUgYW55IHZhbGlkIG5vZGUgaGFuZGxlLgotICAgKiBAcmV0dXJuIHRoZSBkb2N1bWVudCBlbmNvZGluZyBTdHJpbmcgb2JqZWN0LgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXREb2N1bWVudEVuY29kaW5nKGludCBub2RlSGFuZGxlKTsKLQotICAvKioKLSAgICogUmV0dXJuIGFuIGluZGljYXRpb24gb2YgdGhlIHN0YW5kYWxvbmUgc3RhdHVzIG9mIHRoZSBkb2N1bWVudCwKLSAgICogICAgICAgIGVpdGhlciAieWVzIiBvciAibm8iLiBUaGlzIHByb3BlcnR5IGlzIGRlcml2ZWQgZnJvbSB0aGUgb3B0aW9uYWwKLSAgICogICAgICAgIHN0YW5kYWxvbmUgZG9jdW1lbnQgZGVjbGFyYXRpb24gaW4gdGhlIFhNTCBkZWNsYXJhdGlvbiBhdCB0aGUKLSAgICogICAgICAgIGJlZ2lubmluZyBvZiB0aGUgZG9jdW1lbnQgZW50aXR5LCBhbmQgaGFzIG5vIHZhbHVlIGlmIHRoZXJlIGlzIG5vCi0gICAqICAgICAgICBzdGFuZGFsb25lIGRvY3VtZW50IGRlY2xhcmF0aW9uLgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBUaGUgbm9kZSBpZCwgd2hpY2ggY2FuIGJlIGFueSB2YWxpZCBub2RlIGhhbmRsZS4KLSAgICogQHJldHVybiB0aGUgZG9jdW1lbnQgc3RhbmRhbG9uZSBTdHJpbmcgb2JqZWN0LCBlaXRoZXIgInllcyIsICJubyIsIG9yIG51bGwuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldERvY3VtZW50U3RhbmRhbG9uZShpbnQgbm9kZUhhbmRsZSk7Ci0KLSAgLyoqCi0gICAqIFJldHVybiBhIHN0cmluZyByZXByZXNlbnRpbmcgdGhlIFhNTCB2ZXJzaW9uIG9mIHRoZSBkb2N1bWVudC4gVGhpcwotICAgKiBwcm9wZXJ0eSBpcyBkZXJpdmVkIGZyb20gdGhlIFhNTCBkZWNsYXJhdGlvbiBvcHRpb25hbGx5IHByZXNlbnQgYXQgdGhlCi0gICAqIGJlZ2lubmluZyBvZiB0aGUgZG9jdW1lbnQgZW50aXR5LCBhbmQgaGFzIG5vIHZhbHVlIGlmIHRoZXJlIGlzIG5vIFhNTAotICAgKiBkZWNsYXJhdGlvbi4KLSAgICoKLSAgICogQHBhcmFtIGRvY3VtZW50SGFuZGxlIHRoZSBkb2N1bWVudCBoYW5kbGUKLSAgICogQHJldHVybiB0aGUgZG9jdW1lbnQgdmVyc2lvbiBTdHJpbmcgb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldERvY3VtZW50VmVyc2lvbihpbnQgZG9jdW1lbnRIYW5kbGUpOwotCi0gIC8qKgotICAgKiBSZXR1cm4gYW4gaW5kaWNhdGlvbiBvZgotICAgKiB3aGV0aGVyIHRoZSBwcm9jZXNzb3IgaGFzIHJlYWQgdGhlIGNvbXBsZXRlIERURC4gSXRzIHZhbHVlIGlzIGEKLSAgICogYm9vbGVhbi4gSWYgaXQgaXMgZmFsc2UsIHRoZW4gY2VydGFpbiBwcm9wZXJ0aWVzIChpbmRpY2F0ZWQgaW4gdGhlaXIKLSAgICogZGVzY3JpcHRpb25zIGJlbG93KSBtYXkgYmUgdW5rbm93bi4gSWYgaXQgaXMgdHJ1ZSwgdGhvc2UgcHJvcGVydGllcwotICAgKiBhcmUgbmV2ZXIgdW5rbm93bi4KLSAgICoKLSAgICogQHJldHVybiA8Y29kZT50cnVlPC9jb2RlPiBpZiBhbGwgZGVjbGFyYXRpb25zIHdlcmUgcHJvY2Vzc2VkOwotICAgKiAgICAgICAgIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBnZXREb2N1bWVudEFsbERlY2xhcmF0aW9uc1Byb2Nlc3NlZCgpOwotCi0gIC8qKgotICAgKiAgIEEgZG9jdW1lbnQgdHlwZSBkZWNsYXJhdGlvbiBpbmZvcm1hdGlvbiBpdGVtIGhhcyB0aGUgZm9sbG93aW5nIHByb3BlcnRpZXM6Ci0gICAqCi0gICAqICAgICAxLiBbc3lzdGVtIGlkZW50aWZpZXJdIFRoZSBzeXN0ZW0gaWRlbnRpZmllciBvZiB0aGUgZXh0ZXJuYWwgc3Vic2V0LCBpZgotICAgKiAgICAgICAgaXQgZXhpc3RzLiBPdGhlcndpc2UgdGhpcyBwcm9wZXJ0eSBoYXMgbm8gdmFsdWUuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIHN5c3RlbSBpZGVudGlmaWVyIFN0cmluZyBvYmplY3QsIG9yIG51bGwgaWYgdGhlcmUgaXMgbm9uZS4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0RG9jdW1lbnRUeXBlRGVjbGFyYXRpb25TeXN0ZW1JZGVudGlmaWVyKCk7Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgcHVibGljIGlkZW50aWZpZXIgb2YgdGhlIGV4dGVybmFsIHN1YnNldCwKLSAgICogbm9ybWFsaXplZCBhcyBkZXNjcmliZWQgaW4gNC4yLjIgRXh0ZXJuYWwgRW50aXRpZXMgW1hNTF0uIElmIHRoZXJlIGlzCi0gICAqIG5vIGV4dGVybmFsIHN1YnNldCBvciBpZiBpdCBoYXMgbm8gcHVibGljIGlkZW50aWZpZXIsIHRoaXMgcHJvcGVydHkKLSAgICogaGFzIG5vIHZhbHVlLgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBwdWJsaWMgaWRlbnRpZmllciBTdHJpbmcgb2JqZWN0LCBvciBudWxsIGlmIHRoZXJlIGlzIG5vbmUuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldERvY3VtZW50VHlwZURlY2xhcmF0aW9uUHVibGljSWRlbnRpZmllcigpOwotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSA8Y29kZT5FbGVtZW50PC9jb2RlPiB3aG9zZSA8Y29kZT5JRDwvY29kZT4gaXMgZ2l2ZW4gYnkKLSAgICogPGNvZGU+ZWxlbWVudElkPC9jb2RlPi4gSWYgbm8gc3VjaCBlbGVtZW50IGV4aXN0cywgcmV0dXJucwotICAgKiA8Y29kZT5EVE0uTlVMTDwvY29kZT4uIEJlaGF2aW9yIGlzIG5vdCBkZWZpbmVkIGlmIG1vcmUgdGhhbiBvbmUgZWxlbWVudAotICAgKiBoYXMgdGhpcyA8Y29kZT5JRDwvY29kZT4uIEF0dHJpYnV0ZXMgKGluY2x1ZGluZyB0aG9zZQotICAgKiB3aXRoIHRoZSBuYW1lICJJRCIpIGFyZSBub3Qgb2YgdHlwZSBJRCB1bmxlc3Mgc28gZGVmaW5lZCBieSBEVEQvU2NoZW1hCi0gICAqIGluZm9ybWF0aW9uIGF2YWlsYWJsZSB0byB0aGUgRFRNIGltcGxlbWVudGF0aW9uLgotICAgKiBJbXBsZW1lbnRhdGlvbnMgdGhhdCBkbyBub3Qga25vdyB3aGV0aGVyIGF0dHJpYnV0ZXMgYXJlIG9mIHR5cGUgSUQgb3IKLSAgICogbm90IGFyZSBleHBlY3RlZCB0byByZXR1cm4gPGNvZGU+RFRNLk5VTEw8L2NvZGU+LgotICAgKgotICAgKiA8cD4lUkVWSUVXJSBQcmVzdW1hYmx5IElEcyBhcmUgc3RpbGwgc2NvcGVkIHRvIGEgc2luZ2xlIGRvY3VtZW50LAotICAgKiBhbmQgdGhpcyBvcGVyYXRpb24gc2VhcmNoZXMgb25seSB3aXRoaW4gYSBzaW5nbGUgZG9jdW1lbnQsIHJpZ2h0PwotICAgKiBXb3VsZG4ndCB3YW50IGNvbGxpc2lvbnMgYmV0d2VlbiBEVE1zIGluIHRoZSBzYW1lIHByb2Nlc3MuPC9wPgotICAgKgotICAgKiBAcGFyYW0gZWxlbWVudElkIFRoZSB1bmlxdWUgPGNvZGU+aWQ8L2NvZGU+IHZhbHVlIGZvciBhbiBlbGVtZW50LgotICAgKiBAcmV0dXJuIFRoZSBoYW5kbGUgb2YgdGhlIG1hdGNoaW5nIGVsZW1lbnQuCi0gICAqLwotICBwdWJsaWMgaW50IGdldEVsZW1lbnRCeUlkKFN0cmluZyBlbGVtZW50SWQpOwotCi0gIC8qKgotICAgKiBUaGUgZ2V0VW5wYXJzZWRFbnRpdHlVUkkgZnVuY3Rpb24gcmV0dXJucyB0aGUgVVJJIG9mIHRoZSB1bnBhcnNlZAotICAgKiBlbnRpdHkgd2l0aCB0aGUgc3BlY2lmaWVkIG5hbWUgaW4gdGhlIHNhbWUgZG9jdW1lbnQgYXMgdGhlIGNvbnRleHQKLSAgICogbm9kZSAoc2VlIFszLjMgVW5wYXJzZWQgRW50aXRpZXNdKS4gSXQgcmV0dXJucyB0aGUgZW1wdHkgc3RyaW5nIGlmCi0gICAqIHRoZXJlIGlzIG5vIHN1Y2ggZW50aXR5LgotICAgKiA8cD4KLSAgICogWE1MIHByb2Nlc3NvcnMgbWF5IGNob29zZSB0byB1c2UgdGhlIFN5c3RlbSBJZGVudGlmaWVyIChpZiBvbmUKLSAgICogaXMgcHJvdmlkZWQpIHRvIHJlc29sdmUgdGhlIGVudGl0eSwgcmF0aGVyIHRoYW4gdGhlIFVSSSBpbiB0aGUKLSAgICogUHVibGljIElkZW50aWZpZXIuIFRoZSBkZXRhaWxzIGFyZSBkZXBlbmRlbnQgb24gdGhlIHByb2Nlc3NvciwgYW5kCi0gICAqIHdlIHdvdWxkIGhhdmUgdG8gc3VwcG9ydCBzb21lIGZvcm0gb2YgcGx1Zy1pbiByZXNvbHZlciB0byBoYW5kbGUKLSAgICogdGhpcyBwcm9wZXJseS4gQ3VycmVudGx5LCB3ZSBzaW1wbHkgcmV0dXJuIHRoZSBTeXN0ZW0gSWRlbnRpZmllciBpZgotICAgKiBwcmVzZW50LCBhbmQgaG9wZSB0aGF0IGl0IGEgdXNhYmxlIFVSSSBvciB0aGF0IG91ciBjYWxsZXIgY2FuCi0gICAqIG1hcCBpdCB0byBvbmUuCi0gICAqICVSRVZJRVclIFJlc29sdmUgUHVibGljIElkZW50aWZpZXJzLi4uIG9yIGNvbnNpZGVyIGNoYW5naW5nIGZ1bmN0aW9uIG5hbWUuCi0gICAqIDxwPgotICAgKiBJZiB3ZSBmaW5kIGEgcmVsYXRpdmUgVVJJCi0gICAqIHJlZmVyZW5jZSwgWE1MIGV4cGVjdHMgaXQgdG8gYmUgcmVzb2x2ZWQgaW4gdGVybXMgb2YgdGhlIGJhc2UgVVJJCi0gICAqIG9mIHRoZSBkb2N1bWVudC4gVGhlIERPTSBkb2Vzbid0IGRvIHRoYXQgZm9yIHVzLCBhbmQgaXQgaXNuJ3QKLSAgICogZW50aXJlbHkgY2xlYXIgd2hldGhlciB0aGF0IHNob3VsZCBiZSBkb25lIGhlcmU7IGN1cnJlbnRseSB0aGF0J3MKLSAgICogcHVzaGVkIHVwIHRvIGEgaGlnaGVyIGxldmVsIG9mIG91ciBhcHBsaWNhdGlvbi4gKE5vdGUgdGhhdCBET00gTGV2ZWwKLSAgICogMSBkaWRuJ3Qgc3RvcmUgdGhlIGRvY3VtZW50J3MgYmFzZSBVUkkuKQotICAgKiAlUkVWSUVXJSBDb25zaWRlciByZXNvbHZpbmcgUmVsYXRpdmUgVVJJcy4KLSAgICogPHA+Ci0gICAqIChUaGUgRE9NJ3Mgc3RhdGVtZW50IHRoYXQgIkFuIFhNTCBwcm9jZXNzb3IgbWF5IGNob29zZSB0bwotICAgKiBjb21wbGV0ZWx5IGV4cGFuZCBlbnRpdGllcyBiZWZvcmUgdGhlIHN0cnVjdHVyZSBtb2RlbCBpcyBwYXNzZWQKLSAgICogdG8gdGhlIERPTSIgcmVmZXJzIG9ubHkgdG8gcGFyc2VkIGVudGl0aWVzLCBub3QgdW5wYXJzZWQsIGFuZCBoZW5jZQotICAgKiBkb2Vzbid0IGFmZmVjdCB0aGlzIGZ1bmN0aW9uLikKLSAgICoKLSAgICogQHBhcmFtIG5hbWUgQSBzdHJpbmcgY29udGFpbmluZyB0aGUgRW50aXR5IE5hbWUgb2YgdGhlIHVucGFyc2VkCi0gICAqIGVudGl0eS4KLSAgICoKLSAgICogQHJldHVybiBTdHJpbmcgY29udGFpbmluZyB0aGUgVVJJIG9mIHRoZSBVbnBhcnNlZCBFbnRpdHksIG9yIGFuCi0gICAqIGVtcHR5IHN0cmluZyBpZiBubyBzdWNoIGVudGl0eSBleGlzdHMuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFVucGFyc2VkRW50aXR5VVJJKFN0cmluZyBuYW1lKTsKLQotICAvLyA9PT09PT09PT09PT09PSBCb29sZWFuIG1ldGhvZHMgPT09PT09PT09PT09PT09PQotCi0gIC8qKgotICAgKiBSZXR1cm4gdHJ1ZSBpZiB0aGUgeHNsOnN0cmlwLXNwYWNlIG9yIHhzbDpwcmVzZXJ2ZS1zcGFjZSB3YXMgcHJvY2Vzc2VkCi0gICAqIGR1cmluZyBjb25zdHJ1Y3Rpb24gb2YgdGhlIGRvY3VtZW50IGNvbnRhaW5lZCBpbiB0aGlzIERUTS4KLSAgICoKLSAgICogTkVFRFNET0MgKCRvYmplY3ROYW1lJCkgQHJldHVybgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gc3VwcG9ydHNQcmVTdHJpcHBpbmcoKTsKLQotICAvKioKLSAgICogRmlndXJlIG91dCB3aGV0aGVyIG5vZGVIYW5kbGUyIHNob3VsZCBiZSBjb25zaWRlcmVkIGFzIGJlaW5nIGxhdGVyCi0gICAqIGluIHRoZSBkb2N1bWVudCB0aGFuIG5vZGVIYW5kbGUxLCBpbiBEb2N1bWVudCBPcmRlciBhcyBkZWZpbmVkCi0gICAqIGJ5IHRoZSBYUGF0aCBtb2RlbC4gVGhpcyBtYXkgbm90IGFncmVlIHdpdGggdGhlIG9yZGVyaW5nIGRlZmluZWQKLSAgICogYnkgb3RoZXIgWE1MIGFwcGxpY2F0aW9ucy4KLSAgICogPHA+Ci0gICAqIFRoZXJlIGFyZSBzb21lIGNhc2VzIHdoZXJlIG9yZGVyaW5nIGlzbid0IGRlZmluZWQsIGFuZCBuZWl0aGVyIGFyZQotICAgKiB0aGUgcmVzdWx0cyBvZiB0aGlzIGZ1bmN0aW9uIC0tIHRob3VnaCB3ZSdsbCBnZW5lcmFsbHkgcmV0dXJuIHRydWUuCi0gICAqIDxwPgotICAgKiAlUkVWSUVXJSBNYWtlIHN1cmUgdGhpcyBkb2VzIHRoZSByaWdodCB0aGluZyB3aXRoIGF0dHJpYnV0ZSBub2RlcyEhIQotICAgKiA8cD4KLSAgICogJVJFVklFVyUgQ29uc2lkZXIgcmVuYW1pbmcgZm9yIGNsYXJpdHkuIFBlcmhhcHMgaXNEb2N1bWVudE9yZGVyKGEsYik/Ci0gICAqCi0gICAqIEBwYXJhbSBmaXJzdE5vZGVIYW5kbGUgRE9NIE5vZGUgdG8gcGVyZm9ybSBwb3NpdGlvbiBjb21wYXJpc29uIG9uLgotICAgKiBAcGFyYW0gc2Vjb25kTm9kZUhhbmRsZSBET00gTm9kZSB0byBwZXJmb3JtIHBvc2l0aW9uIGNvbXBhcmlzb24gb24uCi0gICAqCi0gICAqIEByZXR1cm4gZmFsc2UgaWYgc2Vjb25kTm9kZSBjb21lcyBiZWZvcmUgZmlyc3ROb2RlLCBvdGhlcndpc2UgcmV0dXJuIHRydWUuCi0gICAqIFlvdSBjYW4gdGhpbmsgb2YgdGhpcyBhcwotICAgKiA8Y29kZT4oZmlyc3ROb2RlLmRvY3VtZW50T3JkZXJQb3NpdGlvbiAmbHQ7PSBzZWNvbmROb2RlLmRvY3VtZW50T3JkZXJQb3NpdGlvbik8L2NvZGU+LgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNOb2RlQWZ0ZXIoaW50IGZpcnN0Tm9kZUhhbmRsZSwgaW50IHNlY29uZE5vZGVIYW5kbGUpOwotCi0gIC8qKgotICAgKiAyLiBbZWxlbWVudCBjb250ZW50IHdoaXRlc3BhY2VdIEEgYm9vbGVhbiBpbmRpY2F0aW5nIHdoZXRoZXIgYQotICAgKiB0ZXh0IG5vZGUgcmVwcmVzZW50cyB3aGl0ZSBzcGFjZSBhcHBlYXJpbmcgd2l0aGluIGVsZW1lbnQgY29udGVudAotICAgKiAoc2VlIFtYTUxdLCAyLjEwICJXaGl0ZSBTcGFjZSBIYW5kbGluZyIpLiAgTm90ZSB0aGF0IHZhbGlkYXRpbmcKLSAgICogWE1MIHByb2Nlc3NvcnMgYXJlIHJlcXVpcmVkIGJ5IFhNTCAxLjAgdG8gcHJvdmlkZSB0aGlzCi0gICAqIGluZm9ybWF0aW9uLi4uIGJ1dCB0aGF0IERPTSBMZXZlbCAyIGRpZCBub3Qgc3VwcG9ydCBpdCwgc2luY2UgaXQKLSAgICogZGVwZW5kcyBvbiBrbm93bGVkZ2Ugb2YgdGhlIERURCB3aGljaCBET00yIGNvdWxkIG5vdCBndWFyYW50ZWUKLSAgICogd291bGQgYmUgYXZhaWxhYmxlLgotICAgKiA8cD4KLSAgICogSWYgdGhlcmUgaXMgbm8gZGVjbGFyYXRpb24gZm9yIHRoZSBjb250YWluaW5nIGVsZW1lbnQsIGFuIFhNTAotICAgKiBwcm9jZXNzb3IgbXVzdCBhc3N1bWUgdGhhdCB0aGUgd2hpdGVzcGFjZSBjb3VsZCBiZSBtZWFuaW5nZnVsIGFuZAotICAgKiByZXR1cm4gZmFsc2UuIElmIG5vIGRlY2xhcmF0aW9uIGhhcyBiZWVuIHJlYWQsIGJ1dCB0aGUgW2FsbAotICAgKiBkZWNsYXJhdGlvbnMgcHJvY2Vzc2VkXSBwcm9wZXJ0eSBvZiB0aGUgZG9jdW1lbnQgaW5mb3JtYXRpb24gaXRlbQotICAgKiBpcyBmYWxzZSAoc28gdGhlcmUgbWF5IGJlIGFuIHVucmVhZCBkZWNsYXJhdGlvbiksIHRoZW4gdGhlIHZhbHVlCi0gICAqIG9mIHRoaXMgcHJvcGVydHkgaXMgaW5kZXRlcm1pbmF0ZSBmb3Igd2hpdGUgc3BhY2UgY2hhcmFjdGVycyBhbmQKLSAgICogc2hvdWxkIHByb2JhYmx5IGJlIHJlcG9ydGVkIGFzIGZhbHNlLiBJdCBpcyBhbHdheXMgZmFsc2UgZm9yIHRleHQKLSAgICogbm9kZXMgdGhhdCBjb250YWluIGFueXRoaW5nIG90aGVyIHRoYW4gKG9yIGluIGFkZGl0aW9uIHRvKSB3aGl0ZQotICAgKiBzcGFjZS4KLSAgICogPHA+Ci0gICAqIE5vdGUgdG9vIHRoYXQgaXQgYWx3YXlzIHJldHVybnMgZmFsc2UgZm9yIG5vbi1UZXh0IG5vZGVzLgotICAgKiA8cD4KLSAgICogJVJFVklFVyUgSm9lIHdhbnRzIHRvIHJlbmFtZSB0aGlzIGlzV2hpdGVzcGFjZUluRWxlbWVudENvbnRlbnQoKSBmb3IgY2xhcml0eQotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSB0aGUgbm9kZSBJRC4KLSAgICogQHJldHVybiA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgbm9kZSBkZWZpbml0ZWx5IHJlcHJlc2VudHMgd2hpdGVzcGFjZSBpbgotICAgKiBlbGVtZW50IGNvbnRlbnQ7IDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBpc0NoYXJhY3RlckVsZW1lbnRDb250ZW50V2hpdGVzcGFjZShpbnQgbm9kZUhhbmRsZSk7Ci0KLSAgLyoqCi0gICAqICAgIDEwLiBbYWxsIGRlY2xhcmF0aW9ucyBwcm9jZXNzZWRdIFRoaXMgcHJvcGVydHkgaXMgbm90IHN0cmljdGx5IHNwZWFraW5nCi0gICAqICAgICAgICBwYXJ0IG9mIHRoZSBpbmZvc2V0IG9mIHRoZSBkb2N1bWVudC4gUmF0aGVyIGl0IGlzIGFuIGluZGljYXRpb24gb2YKLSAgICogICAgICAgIHdoZXRoZXIgdGhlIHByb2Nlc3NvciBoYXMgcmVhZCB0aGUgY29tcGxldGUgRFRELiBJdHMgdmFsdWUgaXMgYQotICAgKiAgICAgICAgYm9vbGVhbi4gSWYgaXQgaXMgZmFsc2UsIHRoZW4gY2VydGFpbiBwcm9wZXJ0aWVzIChpbmRpY2F0ZWQgaW4gdGhlaXIKLSAgICogICAgICAgIGRlc2NyaXB0aW9ucyBiZWxvdykgbWF5IGJlIHVua25vd24uIElmIGl0IGlzIHRydWUsIHRob3NlIHByb3BlcnRpZXMKLSAgICogICAgICAgIGFyZSBuZXZlciB1bmtub3duLgotICAgKgotICAgKiBAcGFyYW0gZG9jdW1lbnRIYW5kbGUgQSBub2RlIGhhbmRsZSB0aGF0IG11c3QgaWRlbnRpZnkgYSBkb2N1bWVudC4KLSAgICogQHJldHVybiA8Y29kZT50cnVlPC9jb2RlPiBpZiBhbGwgZGVjbGFyYXRpb25zIHdlcmUgcHJvY2Vzc2VkOwotICAgKiAgICAgICAgIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBpc0RvY3VtZW50QWxsRGVjbGFyYXRpb25zUHJvY2Vzc2VkKGludCBkb2N1bWVudEhhbmRsZSk7Ci0KLSAgLyoqCi0gICAqICAgICA1LiBbc3BlY2lmaWVkXSBBIGZsYWcgaW5kaWNhdGluZyB3aGV0aGVyIHRoaXMgYXR0cmlidXRlIHdhcyBhY3R1YWxseQotICAgKiAgICAgICAgc3BlY2lmaWVkIGluIHRoZSBzdGFydC10YWcgb2YgaXRzIGVsZW1lbnQsIG9yIHdhcyBkZWZhdWx0ZWQgZnJvbSB0aGUKLSAgICogICAgICAgIERURCAob3Igc2NoZW1hKS4KLSAgICoKLSAgICogQHBhcmFtIGF0dHJpYnV0ZUhhbmRsZSBUaGUgYXR0cmlidXRlIGhhbmRsZQotICAgKiBAcmV0dXJuIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBhdHRyaWJ1dGUgd2FzIHNwZWNpZmllZDsKLSAgICogICAgICAgICA8Y29kZT5mYWxzZTwvY29kZT4gaWYgaXQgd2FzIGRlZmF1bHRlZCBvciB0aGUgaGFuZGxlIGRvZXNuJ3QKLSAgICogICAgICAgICAgICByZWZlciB0byBhbiBhdHRyaWJ1dGUgbm9kZS4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzQXR0cmlidXRlU3BlY2lmaWVkKGludCBhdHRyaWJ1dGVIYW5kbGUpOwotCi0gIC8vID09PT09PT09PT0gRGlyZWN0IFNBWCBEaXNwYXRjaCwgZm9yIG9wdGltaXphdGlvbiBwdXJwb3NlcyA9PT09PT09PQotCi0gIC8qKgotICAgKiBEaXJlY3RseSBjYWxsIHRoZQotICAgKiBjaGFyYWN0ZXJzIG1ldGhvZCBvbiB0aGUgcGFzc2VkIENvbnRlbnRIYW5kbGVyIGZvciB0aGUKLSAgICogc3RyaW5nLXZhbHVlIG9mIHRoZSBnaXZlbiBub2RlIChzZWUgaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGgjZGF0YS1tb2RlbAotICAgKiBmb3IgdGhlIGRlZmluaXRpb24gb2YgYSBub2RlJ3Mgc3RyaW5nLXZhbHVlKS4gTXVsdGlwbGUgY2FsbHMgdG8gdGhlCi0gICAqIENvbnRlbnRIYW5kbGVyJ3MgY2hhcmFjdGVycyBtZXRob2RzIG1heSB3ZWxsIG9jY3VyIGZvciBhIHNpbmdsZSBjYWxsIHRvCi0gICAqIHRoaXMgbWV0aG9kLgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBUaGUgbm9kZSBJRC4KLSAgICogQHBhcmFtIGNoIEEgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGEgQ29udGVudEhhbmRsZXIuCi0gICAqIEBwYXJhbSBub3JtYWxpemUgdHJ1ZSBpZiB0aGUgY29udGVudCBzaG91bGQgYmUgbm9ybWFsaXplZCBhY2NvcmRpbmcgdG8KLSAgICogdGhlIHJ1bGVzIGZvciB0aGUgWFBhdGgKLSAgICogPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGgjZnVuY3Rpb24tbm9ybWFsaXplLXNwYWNlIj5ub3JtYWxpemUtc3BhY2U8L2E+Ci0gICAqIGZ1bmN0aW9uLgotICAgKgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgZGlzcGF0Y2hDaGFyYWN0ZXJzRXZlbnRzKAotICAgIGludCBub2RlSGFuZGxlLCBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciBjaCwgYm9vbGVhbiBub3JtYWxpemUpCi0gICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotCi0gIC8qKgotICAgKiBEaXJlY3RseSBjcmVhdGUgU0FYIHBhcnNlciBldmVudHMgcmVwcmVzZW50aW5nIHRoZSBYTUwgY29udGVudCBvZgotICAgKiBhIERUTSBzdWJ0cmVlLiBUaGlzIGlzIGEgInNlcmlhbGl6ZSIgb3BlcmF0aW9uLgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBUaGUgbm9kZSBJRC4KLSAgICogQHBhcmFtIGNoIEEgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGEgQ29udGVudEhhbmRsZXIuCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBkaXNwYXRjaFRvRXZlbnRzKGludCBub2RlSGFuZGxlLCBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciBjaCkKLSAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotCi0gIC8qKgotICAgKiBSZXR1cm4gYW4gRE9NIG5vZGUgZm9yIHRoZSBnaXZlbiBub2RlLgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBUaGUgbm9kZSBJRC4KLSAgICoKLSAgICogQHJldHVybiBBIG5vZGUgcmVwcmVzZW50YXRpb24gb2YgdGhlIERUTSBub2RlLgotICAgKi8KLSAgcHVibGljIG9yZy53M2MuZG9tLk5vZGUgZ2V0Tm9kZShpbnQgbm9kZUhhbmRsZSk7Ci0KLSAgLy8gPT09PSBDb25zdHJ1Y3Rpb24gbWV0aG9kcyAobWF5IG5vdCBiZSBzdXBwb3J0ZWQgYnkgc29tZSBpbXBsZW1lbnRhdGlvbnMhKSA9PT09PQotICAvLyAlUkVWSUVXJSBXaGF0IHJlc3BvbnNlIG9jY3VycyBpZiBub3Qgc3VwcG9ydGVkPwotCi0gIC8qKgotICAgKiBAcmV0dXJuIHRydWUgaWZmIHdlJ3JlIGJ1aWxkaW5nIHRoaXMgbW9kZWwgaW5jcmVtZW50YWxseSAoZWcKLSAgICogd2UncmUgcGFydG5lcmVkIHdpdGggYSBDb3JvdXRpbmVQYXJzZXIpIGFuZCB0aHVzIHJlcXVpcmUgdGhhdCB0aGUKLSAgICogdHJhbnNmb3JtYXRpb24gYW5kIHRoZSBwYXJzZSBydW4gc2ltdWx0YW5lb3VzbHkuIEd1aWRhbmNlIHRvIHRoZQotICAgKiBEVE1NYW5hZ2VyLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gbmVlZHNUd29UaHJlYWRzKCk7Ci0KLSAgLy8gJVJFVklFVyUgRG8gdGhlc2UgYXBwZW5kcyBtYWtlIGFueSBzZW5zZSwgc2hvdWxkIHdlIHN1cHBvcnQgYQotICAvLyB3aWRlciBzZXQgb2YgbWV0aG9kcyAobGlrZSB0aGUgImFwcGVuZCIgbWV0aG9kcyBpbiB0aGUKLSAgLy8gY3VycmVudCBEVE1Eb2N1bWVudEltcGwgZHJhZnQpLCBvciBzaG91bGQgd2UganVzdCBzdXBwb3J0IFNBWAotICAvLyBsaXN0ZW5lciBpbnRlcmZhY2VzPyAgU2hvdWxkIGl0IGJlIGEgc2VwYXJhdGUgaW50ZXJmYWNlIHRvCi0gIC8vIG1ha2UgdGhhdCBkaXN0aW5jdGlvbiBleHBsaWNpdD8KLQotICAvKioKLSAgICogUmV0dXJuIHRoaXMgRFRNJ3MgY29udGVudCBoYW5kbGVyLCBpZiBpdCBoYXMgb25lLgotICAgKgotICAgKiBAcmV0dXJuIG51bGwgaWYgdGhpcyBtb2RlbCBkb2Vzbid0IHJlc3BvbmQgdG8gU0FYIGV2ZW50cy4KLSAgICovCi0gIHB1YmxpYyBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciBnZXRDb250ZW50SGFuZGxlcigpOwotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhpcyBEVE0ncyBsZXhpY2FsIGhhbmRsZXIsIGlmIGl0IGhhcyBvbmUuCi0gICAqCi0gICAqICVSRVZJRVclIFNob3VsZCB0aGlzIHJldHVybiBudWxsIGlmIGNvbnN0cnV0aW9uIGFscmVhZHkgZG9uZS9iZWd1bj8KLSAgICoKLSAgICogQHJldHVybiBudWxsIGlmIHRoaXMgbW9kZWwgZG9lc24ndCByZXNwb25kIHRvIGxleGljYWwgU0FYIGV2ZW50cy4KLSAgICovCi0gIHB1YmxpYyBvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXIgZ2V0TGV4aWNhbEhhbmRsZXIoKTsKLQotICAvKioKLSAgICogUmV0dXJuIHRoaXMgRFRNJ3MgRW50aXR5UmVzb2x2ZXIsIGlmIGl0IGhhcyBvbmUuCi0gICAqCi0gICAqIEByZXR1cm4gbnVsbCBpZiB0aGlzIG1vZGVsIGRvZXNuJ3QgcmVzcG9uZCB0byBTQVggZW50aXR5IHJlZiBldmVudHMuCi0gICAqLwotICBwdWJsaWMgb3JnLnhtbC5zYXguRW50aXR5UmVzb2x2ZXIgZ2V0RW50aXR5UmVzb2x2ZXIoKTsKLQotICAvKioKLSAgICogUmV0dXJuIHRoaXMgRFRNJ3MgRFRESGFuZGxlciwgaWYgaXQgaGFzIG9uZS4KLSAgICoKLSAgICogQHJldHVybiBudWxsIGlmIHRoaXMgbW9kZWwgZG9lc24ndCByZXNwb25kIHRvIFNBWCBkdGQgZXZlbnRzLgotICAgKi8KLSAgcHVibGljIG9yZy54bWwuc2F4LkRUREhhbmRsZXIgZ2V0RFRESGFuZGxlcigpOwotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhpcyBEVE0ncyBFcnJvckhhbmRsZXIsIGlmIGl0IGhhcyBvbmUuCi0gICAqCi0gICAqIEByZXR1cm4gbnVsbCBpZiB0aGlzIG1vZGVsIGRvZXNuJ3QgcmVzcG9uZCB0byBTQVggZXJyb3IgZXZlbnRzLgotICAgKi8KLSAgcHVibGljIG9yZy54bWwuc2F4LkVycm9ySGFuZGxlciBnZXRFcnJvckhhbmRsZXIoKTsKLQotICAvKioKLSAgICogUmV0dXJuIHRoaXMgRFRNJ3MgRGVjbEhhbmRsZXIsIGlmIGl0IGhhcyBvbmUuCi0gICAqCi0gICAqIEByZXR1cm4gbnVsbCBpZiB0aGlzIG1vZGVsIGRvZXNuJ3QgcmVzcG9uZCB0byBTQVggRGVjbCBldmVudHMuCi0gICAqLwotICBwdWJsaWMgb3JnLnhtbC5zYXguZXh0LkRlY2xIYW5kbGVyIGdldERlY2xIYW5kbGVyKCk7Ci0KLSAgLyoqCi0gICAqIEFwcGVuZCBhIGNoaWxkIHRvICJ0aGUgZW5kIG9mIHRoZSBkb2N1bWVudCIuIFBsZWFzZSBub3RlIHRoYXQKLSAgICogdGhlIG5vZGUgaXMgYWx3YXlzIGNsb25lZCBpbiBhIGJhc2UgRFRNLCBzaW5jZSBvdXIgYmFzaWMgYmVoYXZpb3IKLSAgICogaXMgaW1tdXRhYmxlIHNvIG5vZGVzIGNhbid0IGJlIHJlbW92ZWQgZnJvbSB0aGVpciBwcmV2aW91cwotICAgKiBsb2NhdGlvbi4KLSAgICoKLSAgICogPHA+ICVSRVZJRVclICBEVE0gbWFpbnRhaW5zIGFuIGluc2VydGlvbiBjdXJzb3Igd2hpY2gKLSAgICogcGVyZm9ybXMgYSBkZXB0aC1maXJzdCB0cmVlIHdhbGsgYXMgbm9kZXMgY29tZSBpbiwgYW5kIHRoaXMgb3BlcmF0aW9uCi0gICAqIGlzIHJlYWxseSBlcXVpdmFsZW50IHRvOgotICAgKiAgICBpbnNlcnRpb25DdXJzb3IuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuaW1wb3J0Tm9kZShuZXdDaGlsZCkpKQotICAgKiB3aGVyZSB0aGUgaW5zZXJ0IHBvaW50IGlzIHRoZSBsYXN0IGVsZW1lbnQgdGhhdCB3YXMgYXBwZW5kZWQgKG9yCi0gICAqIHRoZSBsYXN0IG9uZSBwb3BwZWQgYmFjayB0byBieSBhbiBlbmQtZWxlbWVudCBvcGVyYXRpb24pLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIG5ld0NoaWxkIE11c3QgYmUgYSB2YWxpZCBuZXcgbm9kZSBoYW5kbGUuCi0gICAqIEBwYXJhbSBjbG9uZSB0cnVlIGlmIHRoZSBjaGlsZCBzaG91bGQgYmUgY2xvbmVkIGludG8gdGhlIGRvY3VtZW50LgotICAgKiBAcGFyYW0gY2xvbmVEZXB0aCBpZiB0aGUgY2xvbmUgYXJndW1lbnQgaXMgdHJ1ZSwgc3BlY2lmaWVzIHRoYXQgdGhlCi0gICAqICAgICAgICAgICAgICAgICAgIGNsb25lIHNob3VsZCBpbmNsdWRlIGFsbCBpdCdzIGNoaWxkcmVuLgotICAgKi8KLSAgcHVibGljIHZvaWQgYXBwZW5kQ2hpbGQoaW50IG5ld0NoaWxkLCBib29sZWFuIGNsb25lLCBib29sZWFuIGNsb25lRGVwdGgpOwotCi0gIC8qKgotICAgKiBBcHBlbmQgYSB0ZXh0IG5vZGUgY2hpbGQgdGhhdCB3aWxsIGJlIGNvbnN0cnVjdGVkIGZyb20gYSBzdHJpbmcsCi0gICAqIHRvIHRoZSBlbmQgb2YgdGhlIGRvY3VtZW50LiBCZWhhdmlvciBpcyBvdGhlcndpc2UgbGlrZSBhcHBlbmRDaGlsZCgpLgotICAgKgotICAgKiBAcGFyYW0gc3RyIE5vbi1udWxsIHJlZmVyZW5jZSB0byBhIHN0cmluZy4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGFwcGVuZFRleHRDaGlsZChTdHJpbmcgc3RyKTsKLQotICAvKioKLSAgICogR2V0IHRoZSBsb2NhdGlvbiBvZiBhIG5vZGUgaW4gdGhlIHNvdXJjZSBkb2N1bWVudC4KLSAgICoKLSAgICogQHBhcmFtIG5vZGUgYW4gPGNvZGU+aW50PC9jb2RlPiB2YWx1ZQotICAgKiBAcmV0dXJuIGEgPGNvZGU+U291cmNlTG9jYXRvcjwvY29kZT4gdmFsdWUgb3IgbnVsbCBpZiBubyBsb2NhdGlvbgotICAgKiBpcyBhdmFpbGFibGUKLSAgICovCi0gIHB1YmxpYyBTb3VyY2VMb2NhdG9yIGdldFNvdXJjZUxvY2F0b3JGb3IoaW50IG5vZGUpOwotCi0gIC8qKgotICAgKiBBcyB0aGUgRFRNIGlzIHJlZ2lzdGVyZWQgd2l0aCB0aGUgRFRNTWFuYWdlciwgdGhpcyBtZXRob2QKLSAgICogd2lsbCBiZSBjYWxsZWQuIFRoaXMgd2lsbCBnaXZlIHRoZSBEVE0gaW1wbGVtZW50YXRpb24gYQotICAgKiBjaGFuY2UgdG8gaW5pdGlhbGl6ZSBhbnkgc3Vic3lzdGVtcyB0aGF0IGFyZSByZXF1aXJlZCB0bwotICAgKiBidWlsZCB0aGUgRFRNCi0gICAqLwotICBwdWJsaWMgdm9pZCBkb2N1bWVudFJlZ2lzdHJhdGlvbigpOwotCi0gIC8qKgotICAgKiBBcyBkb2N1bWVudHMgYXJlIHJlbGVhc2VkIGZyb20gdGhlIERUTU1hbmFnZXIsIHRoZSBEVE0gaW1wbGVtZW50YXRpb24KLSAgICogd2lsbCBiZSBub3RpZmllZCBvZiB0aGUgZXZlbnQuIFRoaXMgd2lsbCBhbGxvdyB0aGUgRFRNIGltcGxlbWVudGF0aW9uCi0gICAqIHRvIHNodXRkb3duIGFueSBzdWJzeXN0ZW0gYWN0aXZpdHkgdGhhdCBtYXkgb2YgYmVlbiBhc3NvaWF0ZWQgd2l0aAotICAgKiB0aGUgYWN0aXZlIERUTSBJbXBsZW1lbnRhdGlvbi4KLSAgICovCi0KLSAgIHB1YmxpYyB2b2lkIGRvY3VtZW50UmVsZWFzZSgpOwotCi0gICAvKioKLSAgICAqIE1pZ3JhdGUgYSBEVE0gYnVpbHQgd2l0aCBhbiBvbGQgRFRNTWFuYWdlciB0byBhIG5ldyBEVE1NYW5hZ2VyLgotICAgICogQWZ0ZXIgdGhlIG1pZ3JhdGlvbiwgdGhlIG5ldyBEVE1NYW5hZ2VyIHdpbGwgdHJlYXQgdGhlIERUTSBhcwotICAgICogb25lIHRoYXQgaXMgYnVpbHQgYnkgaXRzZWxmLgotICAgICogVGhpcyBpcyB1c2VkIHRvIHN1cHBvcnQgRFRNIHNoYXJpbmcgYmV0d2VlbiBtdWx0aXBsZSB0cmFuc2Zvcm1hdGlvbnMuCi0gICAgKiBAcGFyYW0gbWFuYWdlciB0aGUgRFRNTWFuYWdlcgotICAgICovCi0gICBwdWJsaWMgdm9pZCBtaWdyYXRlVG8oRFRNTWFuYWdlciBtYW5hZ2VyKTsKLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3IuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZjI5MzRhZS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMTIgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRFRNQXhpc0l0ZXJhdG9yLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTUgMDg6MTQ6NTIgc3VyZXNoX2VtYWlsaWQgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bTsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGl0ZXJhdGVzIG92ZXIgYSBzaW5nbGUgWFBhdGggQXhpcywgYW5kIHJldHVybnMgbm9kZSBoYW5kbGVzLgotICovCi1wdWJsaWMgaW50ZXJmYWNlIERUTUF4aXNJdGVyYXRvciBleHRlbmRzIENsb25lYWJsZQotewotCi0gIC8qKiBTcGVjaWZpZXMgdGhlIGVuZCBvZiB0aGUgaXRlcmF0aW9uLCBhbmQgaXMgdGhlIHNhbWUgYXMgRFRNLk5VTEwuICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTkQgPSBEVE0uTlVMTDsKLQotICAvKioKLSAgICogR2V0IHRoZSBuZXh0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbi4KLSAgICoKLSAgICogQHJldHVybiBUaGUgbmV4dCBub2RlIGhhbmRsZSBpbiB0aGUgaXRlcmF0aW9uLCBvciBFTkQuCi0gICAqLwotICBwdWJsaWMgaW50IG5leHQoKTsKLQotCi0gIC8qKgotICAgKiBSZXNldHMgdGhlIGl0ZXJhdG9yIHRvIHRoZSBsYXN0IHN0YXJ0IG5vZGUuCi0gICAqCi0gICAqIEByZXR1cm4gQSBEVE1BeGlzSXRlcmF0b3IsIHdoaWNoIG1heSBvciBtYXkgbm90IGJlIHRoZSBzYW1lIGFzIHRoaXMKLSAgICogICAgICAgICBpdGVyYXRvci4KLSAgICovCi0gIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3IgcmVzZXQoKTsKLQotICAvKioKLSAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIG5vZGVzIGluIHRoaXMgaXRlcmF0b3IuICBUaGlzIG1heSBiZSBhbiBleHBlbnNpdmUKLSAgICogb3BlcmF0aW9uIHdoZW4gY2FsbGVkIHRoZSBmaXJzdCB0aW1lLgotICAgKi8KLSAgcHVibGljIGludCBnZXRMYXN0KCk7Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gVGhlIHBvc2l0aW9uIG9mIHRoZSBjdXJyZW50IG5vZGUgaW4gdGhlIHNldCwgYXMgZGVmaW5lZCBieSBYUGF0aC4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0UG9zaXRpb24oKTsKLQotICAvKioKLSAgICogUmVtZW1iZXJzIHRoZSBjdXJyZW50IG5vZGUgZm9yIHRoZSBuZXh0IGNhbGwgdG8gZ290b01hcmsoKS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldE1hcmsoKTsKLQotICAvKioKLSAgICogUmVzdG9yZXMgdGhlIGN1cnJlbnQgbm9kZSByZW1lbWJlcmVkIGJ5IHNldE1hcmsoKS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGdvdG9NYXJrKCk7Ci0KLSAgLyoqCi0gICAqIFNldCBzdGFydCB0byBFTkQgc2hvdWxkICdjbG9zZScgdGhlIGl0ZXJhdG9yLAotICAgKiBpLmUuIHN1YnNlcXVlbnQgY2FsbCB0byBuZXh0KCkgc2hvdWxkIHJldHVybiBFTkQuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlIFNldHMgdGhlIHJvb3Qgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICoKLSAgICogQHJldHVybiBBIERUTUF4aXNJdGVyYXRvciBzZXQgdG8gdGhlIHN0YXJ0IG9mIHRoZSBpdGVyYXRpb24uCi0gICAqLwotICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIHNldFN0YXJ0Tm9kZShpbnQgbm9kZSk7Ci0KLSAgLyoqCi0gICAqIEdldCBzdGFydCB0byBFTkQgc2hvdWxkICdjbG9zZScgdGhlIGl0ZXJhdG9yLAotICAgKiBpLmUuIHN1YnNlcXVlbnQgY2FsbCB0byBuZXh0KCkgc2hvdWxkIHJldHVybiBFTkQuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHJvb3Qgbm9kZSBvZiB0aGUgaXRlcmF0aW9uLgotICAgKi8KLSAgcHVibGljIGludCBnZXRTdGFydE5vZGUoKTsKLQotICAvKioKLSAgICogQHJldHVybiB0cnVlIGlmIHRoaXMgaXRlcmF0b3IgaGFzIGEgcmV2ZXJzZWQgYXhpcywgZWxzZSBmYWxzZS4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzUmV2ZXJzZSgpOwotCi0gIC8qKgotICAgKiBAcmV0dXJuIGEgZGVlcCBjb3B5IG9mIHRoaXMgaXRlcmF0b3IuIFRoZSBjbG9uZSBzaG91bGQgbm90IGJlIHJlc2V0Ci0gICAqIGZyb20gaXRzIGN1cnJlbnQgcG9zaXRpb24uCi0gICAqLwotICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIGNsb25lSXRlcmF0b3IoKTsKLQotICAvKioKLSAgICogU2V0IGlmIHJlc3RhcnRhYmxlLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0UmVzdGFydGFibGUoYm9vbGVhbiBpc1Jlc3RhcnRhYmxlKTsKLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBub2RlIGF0IHRoZSBnaXZlbiBwb3NpdGlvbi4KLSAgICoKLSAgICogQHBhcmFtIHBvc2l0aW9uIFRoZSBwb3NpdGlvbgotICAgKiBAcmV0dXJuIFRoZSBub2RlIGF0IHRoZSBnaXZlbiBwb3NpdGlvbi4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0Tm9kZUJ5UG9zaXRpb24oaW50IHBvc2l0aW9uKTsKLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzVHJhdmVyc2VyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc1RyYXZlcnNlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlNGJhMDg2Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzVHJhdmVyc2VyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMTggKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRFRNQXhpc1RyYXZlcnNlci5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE1IDA4OjE0OjUyIHN1cmVzaF9lbWFpbGlkIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG07Ci0KLS8qKgotICogQSBjbGFzcyB0aGF0IGltcGxlbWVudHMgdHJhdmVyc2VzIERUTUF4aXNUcmF2ZXJzZXIgaW50ZXJmYWNlIGNhbiB0cmF2ZXJzZQotICogYSBzZXQgb2Ygbm9kZXMsIHVzdWFsbHkgYXMgZGVmaW5lZCBieSBhbiBYUGF0aCBheGlzLiAgSXQgaXMgZGlmZmVyZW50IGZyb20KLSAqIGFuIGl0ZXJhdG9yLCBiZWNhdXNlIGl0IGRvZXMgbm90IG5lZWQgdG8gaG9sZCBzdGF0ZSwgYW5kLCBpbiBmYWN0LCBtdXN0IG5vdAotICogaG9sZCBhbnkgaXRlcmF0aW9uLWJhc2VkIHN0YXRlLiAgSXQgaXMgbWVhbnQgdG8gYmUgaW1wbGVtZW50ZWQgYXMgYW4gaW5uZXIKLSAqIGNsYXNzIG9mIGEgRFRNLCBhbmQgcmV0dXJuZWQgYnkgdGhlIGdldEF4aXNUcmF2ZXJzZXIoZmluYWwgaW50IGF4aXMpCi0gKiBmdW5jdGlvbi4KLSAqCi0gKiA8cD5BIERUTUF4aXNUcmF2ZXJzZXIgY2FuIHByb2JhYmx5IG5vdCB0cmF2ZXJzZSBhIHJldmVyc2UgYXhpcyBpbgotICogZG9jdW1lbnQgb3JkZXIuPC9wPgotICoKLSAqIDxwPlR5cGljYWwgdXNhZ2U6PC9wPgotICogPHByZT48Y29kZT4KLSAqIGZvcihpbnQgbm9kZUhhbmRsZT1teVRyYXZlcnNlci5maXJzdChteUNvbnRleHQpOwotICogICAgIG5vZGVIYW5kbGUhPURUTS5OVUxMOwotICogICAgIG5vZGVIYW5kbGU9bXlUcmF2ZXJzZXIubmV4dChteUNvbnRleHQsbm9kZUhhbmRsZSkpCi0gKiB7IC4uLiBwcm9jZXNzaW5nIGZvciBub2RlIGluZGljYXRlZCBieSBub2RlSGFuZGxlIGdvZXMgaGVyZSAuLi4gfQotICogPC9jb2RlPjwvcHJlPgotICoKLSAqIEBhdXRob3IgU2NvdHQgQm9hZwotICovCi1wdWJsaWMgYWJzdHJhY3QgY2xhc3MgRFRNQXhpc1RyYXZlcnNlcgotewotCi0gIC8qKgotICAgKiBCeSB0aGUgbmF0dXJlIG9mIHRoZSBzdGF0ZWxlc3MgdHJhdmVyc2FsLCB0aGUgY29udGV4dCBub2RlIGNhbiBub3QgYmUKLSAgICogcmV0dXJuZWQgb3IgdGhlIGl0ZXJhdGlvbiB3aWxsIGdvIGludG8gYW4gaW5maW5hdGUgbG9vcC4gIFNvIHRvIHRyYXZlcnNlCi0gICAqIGFuIGF4aXMsIHRoZSBmaXJzdCBmdW5jdGlvbiBtdXN0IGJlIHVzZWQgdG8gZ2V0IHRoZSBmaXJzdCBub2RlLgotICAgKgotICAgKiA8cD5UaGlzIG1ldGhvZCBuZWVkcyB0byBiZSBvdmVybG9hZGVkIG9ubHkgYnkgdGhvc2UgYXhpcyB0aGF0IHByb2Nlc3MKLSAgICogdGhlIHNlbGYgbm9kZS4gPFxwPgotICAgKgotICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCBub2RlIG9mIHRoaXMgdHJhdmVyc2FsLiBUaGlzIGlzIHRoZSBwb2ludAotICAgKiB0aGF0IHRoZSB0cmF2ZXJzYWwgc3RhcnRzIGZyb20uCi0gICAqIEByZXR1cm4gdGhlIGZpcnN0IG5vZGUgaW4gdGhlIHRyYXZlcnNhbC4KLSAgICovCi0gIHB1YmxpYyBpbnQgZmlyc3QoaW50IGNvbnRleHQpCi0gIHsKLSAgICByZXR1cm4gbmV4dChjb250ZXh0LCBjb250ZXh0KTsKLSAgfQotCi0gIC8qKgotICAgKiBCeSB0aGUgbmF0dXJlIG9mIHRoZSBzdGF0ZWxlc3MgdHJhdmVyc2FsLCB0aGUgY29udGV4dCBub2RlIGNhbiBub3QgYmUKLSAgICogcmV0dXJuZWQgb3IgdGhlIGl0ZXJhdGlvbiB3aWxsIGdvIGludG8gYW4gaW5maW5hdGUgbG9vcC4gIFNvIHRvIHRyYXZlcnNlCi0gICAqIGFuIGF4aXMsIHRoZSBmaXJzdCBmdW5jdGlvbiBtdXN0IGJlIHVzZWQgdG8gZ2V0IHRoZSBmaXJzdCBub2RlLgotICAgKgotICAgKiA8cD5UaGlzIG1ldGhvZCBuZWVkcyB0byBiZSBvdmVybG9hZGVkIG9ubHkgYnkgdGhvc2UgYXhpcyB0aGF0IHByb2Nlc3MKLSAgICogdGhlIHNlbGYgbm9kZS4gPFxwPgotICAgKgotICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCBub2RlIG9mIHRoaXMgdHJhdmVyc2FsLiBUaGlzIGlzIHRoZSBwb2ludAotICAgKiBvZiBvcmlnaW4gZm9yIHRoZSB0cmF2ZXJzYWwgLS0gaXRzICJyb290IG5vZGUiIG9yIHN0YXJ0aW5nIHBvaW50LgotICAgKiBAcGFyYW0gZXh0ZW5kZWRUeXBlSUQgVGhlIGV4dGVuZGVkIHR5cGUgSUQgdGhhdCBtdXN0IG1hdGNoLgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBmaXJzdCBub2RlIGluIHRoZSB0cmF2ZXJzYWwuCi0gICAqLwotICBwdWJsaWMgaW50IGZpcnN0KGludCBjb250ZXh0LCBpbnQgZXh0ZW5kZWRUeXBlSUQpCi0gIHsKLSAgICByZXR1cm4gbmV4dChjb250ZXh0LCBjb250ZXh0LCBleHRlbmRlZFR5cGVJRCk7Ci0gIH0KLQotICAvKioKLSAgICogVHJhdmVyc2UgdG8gdGhlIG5leHQgbm9kZSBhZnRlciB0aGUgY3VycmVudCBub2RlLgotICAgKgotICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCBub2RlIG9mIHRoaXMgdHJhdmVyc2FsLiBUaGlzIGlzIHRoZSBwb2ludAotICAgKiBvZiBvcmlnaW4gZm9yIHRoZSB0cmF2ZXJzYWwgLS0gaXRzICJyb290IG5vZGUiIG9yIHN0YXJ0aW5nIHBvaW50LgotICAgKiBAcGFyYW0gY3VycmVudCBUaGUgY3VycmVudCBub2RlIG9mIHRoZSB0cmF2ZXJzYWwuIFRoaXMgaXMgdGhlIGxhc3Qga25vd24KLSAgICogbG9jYXRpb24gaW4gdGhlIHRyYXZlcnNhbCwgdHlwaWNhbGx5IHRoZSBub2RlLWhhbmRsZSByZXR1cm5lZCBieSB0aGUKLSAgICogcHJldmlvdXMgdHJhdmVyc2FsIHN0ZXAuIEZvciB0aGUgZmlyc3QgdHJhdmVyc2FsIHN0ZXAsIGNvbnRleHQKLSAgICogc2hvdWxkIGJlIHNldCBlcXVhbCB0byBjdXJyZW50LiBOb3RlIHRoYXQgaW4gb3JkZXIgdG8gdGVzdCB3aGV0aGVyCi0gICAqIGNvbnRleHQgaXMgaW4gdGhlIHNldCwgeW91IG11c3QgdXNlIHRoZSBmaXJzdCgpIG1ldGhvZCBpbnN0ZWFkLgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBuZXh0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbiwgb3IgRFRNLk5VTEwuCi0gICAqIEBzZWUgI2ZpcnN0KGludCkKLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBpbnQgbmV4dChpbnQgY29udGV4dCwgaW50IGN1cnJlbnQpOwotCi0gIC8qKgotICAgKiBUcmF2ZXJzZSB0byB0aGUgbmV4dCBub2RlIGFmdGVyIHRoZSBjdXJyZW50IG5vZGUgdGhhdCBpcyBtYXRjaGVkCi0gICAqIGJ5IHRoZSBleHRlbmRlZCB0eXBlIElELgotICAgKgotICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCBub2RlIG9mIHRoaXMgdHJhdmVyc2FsLiBUaGlzIGlzIHRoZSBwb2ludAotICAgKiBvZiBvcmlnaW4gZm9yIHRoZSB0cmF2ZXJzYWwgLS0gaXRzICJyb290IG5vZGUiIG9yIHN0YXJ0aW5nIHBvaW50LgotICAgKiBAcGFyYW0gY3VycmVudCBUaGUgY3VycmVudCBub2RlIG9mIHRoZSB0cmF2ZXJzYWwuIFRoaXMgaXMgdGhlIGxhc3Qga25vd24KLSAgICogbG9jYXRpb24gaW4gdGhlIHRyYXZlcnNhbCwgdHlwaWNhbGx5IHRoZSBub2RlLWhhbmRsZSByZXR1cm5lZCBieSB0aGUKLSAgICogcHJldmlvdXMgdHJhdmVyc2FsIHN0ZXAuIEZvciB0aGUgZmlyc3QgdHJhdmVyc2FsIHN0ZXAsIGNvbnRleHQKLSAgICogc2hvdWxkIGJlIHNldCBlcXVhbCB0byBjdXJyZW50LiBOb3RlIHRoYXQgaW4gb3JkZXIgdG8gdGVzdCB3aGV0aGVyCi0gICAqIGNvbnRleHQgaXMgaW4gdGhlIHNldCwgeW91IG11c3QgdXNlIHRoZSBmaXJzdCgpIG1ldGhvZCBpbnN0ZWFkLgotICAgKiBAcGFyYW0gZXh0ZW5kZWRUeXBlSUQgVGhlIGV4dGVuZGVkIHR5cGUgSUQgdGhhdCBtdXN0IG1hdGNoLgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBuZXh0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbiwgb3IgRFRNLk5VTEwuCi0gICAqIEBzZWUgI2ZpcnN0KGludCxpbnQpCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgaW50IG5leHQoaW50IGNvbnRleHQsIGludCBjdXJyZW50LCBpbnQgZXh0ZW5kZWRUeXBlSUQpOwotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUNvbmZpZ3VyYXRpb25FeGNlcHRpb24uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1Db25maWd1cmF0aW9uRXhjZXB0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGM1ZGU4YmYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUNvbmZpZ3VyYXRpb25FeGNlcHRpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEwMSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBEVE1Db25maWd1cmF0aW9uRXhjZXB0aW9uLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTUgMDg6MTQ6NTIgc3VyZXNoX2VtYWlsaWQgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bTsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uU291cmNlTG9jYXRvcjsKLQotLyoqCi0gKiBJbmRpY2F0ZXMgYSBzZXJpb3VzIGNvbmZpZ3VyYXRpb24gZXJyb3IuCi0gKi8KLXB1YmxpYyBjbGFzcyBEVE1Db25maWd1cmF0aW9uRXhjZXB0aW9uIGV4dGVuZHMgRFRNRXhjZXB0aW9uIHsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTQ2MDc4NzQwNzg4MTg0MTgwNDZMOwotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlIGEgbmV3IDxjb2RlPkRUTUNvbmZpZ3VyYXRpb25FeGNlcHRpb248L2NvZGU+IHdpdGggbm8KLSAgICAgKiBkZXRhaWwgbWVzYWdlLgotICAgICAqLwotICAgIHB1YmxpYyBEVE1Db25maWd1cmF0aW9uRXhjZXB0aW9uKCkgewotICAgICAgICBzdXBlcigiQ29uZmlndXJhdGlvbiBFcnJvciIpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENyZWF0ZSBhIG5ldyA8Y29kZT5EVE1Db25maWd1cmF0aW9uRXhjZXB0aW9uPC9jb2RlPiB3aXRoCi0gICAgICogdGhlIDxjb2RlPlN0cmluZyA8L2NvZGU+IHNwZWNpZmllZCBhcyBhbiBlcnJvciBtZXNzYWdlLgotICAgICAqCi0gICAgICogQHBhcmFtIG1zZyBUaGUgZXJyb3IgbWVzc2FnZSBmb3IgdGhlIGV4Y2VwdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgRFRNQ29uZmlndXJhdGlvbkV4Y2VwdGlvbihTdHJpbmcgbXNnKSB7Ci0gICAgICAgIHN1cGVyKG1zZyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlIGEgbmV3IDxjb2RlPkRUTUNvbmZpZ3VyYXRpb25FeGNlcHRpb248L2NvZGU+IHdpdGggYQotICAgICAqIGdpdmVuIDxjb2RlPkV4Y2VwdGlvbjwvY29kZT4gYmFzZSBjYXVzZSBvZiB0aGUgZXJyb3IuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZSBUaGUgZXhjZXB0aW9uIHRvIGJlIGVuY2Fwc3VsYXRlZCBpbiBhCi0gICAgICogRFRNQ29uZmlndXJhdGlvbkV4Y2VwdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgRFRNQ29uZmlndXJhdGlvbkV4Y2VwdGlvbihUaHJvd2FibGUgZSkgewotICAgICAgICBzdXBlcihlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGUgYSBuZXcgPGNvZGU+RFRNQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjwvY29kZT4gd2l0aCB0aGUKLSAgICAgKiBnaXZlbiA8Y29kZT5FeGNlcHRpb248L2NvZGU+IGJhc2UgY2F1c2UgYW5kIGRldGFpbCBtZXNzYWdlLgotICAgICAqCi0gICAgICogQHBhcmFtIG1zZyBUaGUgZGV0YWlsIG1lc3NhZ2UuCi0gICAgICogQHBhcmFtIGUgVGhlIGV4Y2VwdGlvbiB0byBiZSB3cmFwcGVkIGluIGEgRFRNQ29uZmlndXJhdGlvbkV4Y2VwdGlvbgotICAgICAqLwotICAgIHB1YmxpYyBEVE1Db25maWd1cmF0aW9uRXhjZXB0aW9uKFN0cmluZyBtc2csIFRocm93YWJsZSBlKSB7Ci0gICAgICAgIHN1cGVyKG1zZywgZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlIGEgbmV3IERUTUNvbmZpZ3VyYXRpb25FeGNlcHRpb24gZnJvbSBhIG1lc3NhZ2UgYW5kIGEgTG9jYXRvci4KLSAgICAgKgotICAgICAqIDxwPlRoaXMgY29uc3RydWN0b3IgaXMgZXNwZWNpYWxseSB1c2VmdWwgd2hlbiBhbiBhcHBsaWNhdGlvbiBpcwotICAgICAqIGNyZWF0aW5nIGl0cyBvd24gZXhjZXB0aW9uIGZyb20gd2l0aGluIGEgRG9jdW1lbnRIYW5kbGVyCi0gICAgICogY2FsbGJhY2suPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIG1lc3NhZ2UgVGhlIGVycm9yIG9yIHdhcm5pbmcgbWVzc2FnZS4KLSAgICAgKiBAcGFyYW0gbG9jYXRvciBUaGUgbG9jYXRvciBvYmplY3QgZm9yIHRoZSBlcnJvciBvciB3YXJuaW5nLgotICAgICAqLwotICAgIHB1YmxpYyBEVE1Db25maWd1cmF0aW9uRXhjZXB0aW9uKFN0cmluZyBtZXNzYWdlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU291cmNlTG9jYXRvciBsb2NhdG9yKSB7Ci0gICAgICAgIHN1cGVyKG1lc3NhZ2UsIGxvY2F0b3IpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFdyYXAgYW4gZXhpc3RpbmcgZXhjZXB0aW9uIGluIGEgRFRNQ29uZmlndXJhdGlvbkV4Y2VwdGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBtZXNzYWdlIFRoZSBlcnJvciBvciB3YXJuaW5nIG1lc3NhZ2UsIG9yIG51bGwgdG8KLSAgICAgKiAgICAgICAgICAgICAgICB1c2UgdGhlIG1lc3NhZ2UgZnJvbSB0aGUgZW1iZWRkZWQgZXhjZXB0aW9uLgotICAgICAqIEBwYXJhbSBsb2NhdG9yIFRoZSBsb2NhdG9yIG9iamVjdCBmb3IgdGhlIGVycm9yIG9yIHdhcm5pbmcuCi0gICAgICogQHBhcmFtIGUgQW55IGV4Y2VwdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgRFRNQ29uZmlndXJhdGlvbkV4Y2VwdGlvbihTdHJpbmcgbWVzc2FnZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNvdXJjZUxvY2F0b3IgbG9jYXRvciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRocm93YWJsZSBlKSB7Ci0gICAgICAgIHN1cGVyKG1lc3NhZ2UsIGxvY2F0b3IsIGUpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1ET01FeGNlcHRpb24uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1ET01FeGNlcHRpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNjE2ZmEwYi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNRE9NRXhjZXB0aW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw1NiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBEVE1ET01FeGNlcHRpb24uamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNSAwODoxNDo1MiBzdXJlc2hfZW1haWxpZCBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtOwotCi0vKioKLSAqIFNpbXBsZSBpbXBsZW1lbnRhdGlvbiBvZiBET01FeGNlcHRpb24uCi0gKgotICogJVJFVklFVyUgU2V2ZXJhbCBjbGFzc2VzIHdlcmUgaW1wbGVtZW50aW5nIHRoaXMgaW50ZXJuYWxseTsKLSAqIGl0IG1ha2VzIG1vcmUgc2Vuc2UgdG8gaGF2ZSBvbmUgc2hhcmVkIHZlcnNpb24uCi0gKiBAeHNsLnVzYWdlIGludGVybmFsCi0gKi8KLXB1YmxpYyBjbGFzcyBEVE1ET01FeGNlcHRpb24gZXh0ZW5kcyBvcmcudzNjLmRvbS5ET01FeGNlcHRpb24KLXsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMTg5NTY1NDI2NjYxMzE5MjQxNEw7Ci0gIC8qKgotICAgKiBDb25zdHJ1Y3RzIGEgRE9NL0RUTSBleGNlcHRpb24uCi0gICAqCi0gICAqIEBwYXJhbSBjb2RlCi0gICAqIEBwYXJhbSBtZXNzYWdlCi0gICAqLwotICBwdWJsaWMgRFRNRE9NRXhjZXB0aW9uKHNob3J0IGNvZGUsIFN0cmluZyBtZXNzYWdlKQotICB7Ci0gICAgc3VwZXIoY29kZSwgbWVzc2FnZSk7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0b3IgRFRNRE9NRXhjZXB0aW9uCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBjb2RlCi0gICAqLwotICBwdWJsaWMgRFRNRE9NRXhjZXB0aW9uKHNob3J0IGNvZGUpCi0gIHsKLSAgICBzdXBlcihjb2RlLCAiIik7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1FeGNlcHRpb24uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1FeGNlcHRpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYjU2NzdmYy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNRXhjZXB0aW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzODUgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRFRNRXhjZXB0aW9uLmphdmEsdiAxLjMgMjAwNS8wOS8yOCAxMzo0ODo1MCBwdmVkdWxhIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG07Ci0KLQotaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lkludm9jYXRpb25UYXJnZXRFeGNlcHRpb247Ci1pbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2VMb2NhdG9yOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXMuWE1MRXJyb3JSZXNvdXJjZXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXMuWE1MTWVzc2FnZXM7Ci0KLQotLyoqCi0gKiBUaGlzIGNsYXNzIHNwZWNpZmllcyBhbiBleGNlcHRpb25hbCBjb25kaXRpb24gdGhhdCBvY2N1cmVkCi0gKiBpbiB0aGUgRFRNIG1vZHVsZS4KLSAqLwotcHVibGljIGNsYXNzIERUTUV4Y2VwdGlvbiBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24gewotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNzc1NTc2NDE5MTgxMzM0NzM0TDsKLQotICAgIC8qKiBGaWVsZCBsb2NhdG9yIHNwZWNpZmllcyB3aGVyZSB0aGUgZXJyb3Igb2NjdXJlZC4KLSAgICAgKiAgQHNlcmlhbCAqLwotICAgIFNvdXJjZUxvY2F0b3IgbG9jYXRvcjsKLQotICAgIC8qKgotICAgICAqIE1ldGhvZCBnZXRMb2NhdG9yIHJldHJpZXZlcyBhbiBpbnN0YW5jZSBvZiBhIFNvdXJjZUxvY2F0b3IKLSAgICAgKiBvYmplY3QgdGhhdCBzcGVjaWZpZXMgd2hlcmUgYW4gZXJyb3Igb2NjdXJlZC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gQSBTb3VyY2VMb2NhdG9yIG9iamVjdCwgb3IgbnVsbCBpZiBub25lIHdhcyBzcGVjaWZpZWQuCi0gICAgICovCi0gICAgcHVibGljIFNvdXJjZUxvY2F0b3IgZ2V0TG9jYXRvcigpIHsKLSAgICAgICAgcmV0dXJuIGxvY2F0b3I7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogTWV0aG9kIHNldExvY2F0b3Igc2V0cyBhbiBpbnN0YW5jZSBvZiBhIFNvdXJjZUxvY2F0b3IKLSAgICAgKiBvYmplY3QgdGhhdCBzcGVjaWZpZXMgd2hlcmUgYW4gZXJyb3Igb2NjdXJlZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBsb2NhdGlvbiBBIFNvdXJjZUxvY2F0b3Igb2JqZWN0LCBvciBudWxsIHRvIGNsZWFyIHRoZSBsb2NhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRMb2NhdG9yKFNvdXJjZUxvY2F0b3IgbG9jYXRpb24pIHsKLSAgICAgICAgbG9jYXRvciA9IGxvY2F0aW9uOwotICAgIH0KLQotICAgIC8qKiBGaWVsZCBjb250YWluZWRFeGNlcHRpb24gc3BlY2lmaWVzIGEgd3JhcHBlZCBleGNlcHRpb24uICBNYXkgYmUgbnVsbC4KLSAgICAgKiAgQHNlcmlhbCAqLwotICAgIFRocm93YWJsZSBjb250YWluZWRFeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCByZXRyaWV2ZXMgYW4gZXhjZXB0aW9uIHRoYXQgdGhpcyBleGNlcHRpb24gd3JhcHMuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIEFuIFRocm93YWJsZSBvYmplY3QsIG9yIG51bGwuCi0gICAgICogQHNlZSAjZ2V0Q2F1c2UKLSAgICAgKi8KLSAgICBwdWJsaWMgVGhyb3dhYmxlIGdldEV4Y2VwdGlvbigpIHsKLSAgICAgICAgcmV0dXJuIGNvbnRhaW5lZEV4Y2VwdGlvbjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBjYXVzZSBvZiB0aGlzIHRocm93YWJsZSBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGUKLSAgICAgKiBjYXVzZSBpcyBub25leGlzdGVudCBvciB1bmtub3duLiAgKFRoZSBjYXVzZSBpcyB0aGUgdGhyb3dhYmxlIHRoYXQKLSAgICAgKiBjYXVzZWQgdGhpcyB0aHJvd2FibGUgdG8gZ2V0IHRocm93bi4pCi0gICAgICovCi0gICAgcHVibGljIFRocm93YWJsZSBnZXRDYXVzZSgpIHsKLQotICAgICAgICByZXR1cm4gKChjb250YWluZWRFeGNlcHRpb24gPT0gdGhpcykKLSAgICAgICAgICAgICAgICA/IG51bGwKLSAgICAgICAgICAgICAgICA6IGNvbnRhaW5lZEV4Y2VwdGlvbik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSW5pdGlhbGl6ZXMgdGhlIDxpPmNhdXNlPC9pPiBvZiB0aGlzIHRocm93YWJsZSB0byB0aGUgc3BlY2lmaWVkIHZhbHVlLgotICAgICAqIChUaGUgY2F1c2UgaXMgdGhlIHRocm93YWJsZSB0aGF0IGNhdXNlZCB0aGlzIHRocm93YWJsZSB0byBnZXQgdGhyb3duLikKLSAgICAgKgotICAgICAqIDxwPlRoaXMgbWV0aG9kIGNhbiBiZSBjYWxsZWQgYXQgbW9zdCBvbmNlLiAgSXQgaXMgZ2VuZXJhbGx5IGNhbGxlZCBmcm9tCi0gICAgICogd2l0aGluIHRoZSBjb25zdHJ1Y3Rvciwgb3IgaW1tZWRpYXRlbHkgYWZ0ZXIgY3JlYXRpbmcgdGhlCi0gICAgICogdGhyb3dhYmxlLiAgSWYgdGhpcyB0aHJvd2FibGUgd2FzIGNyZWF0ZWQKLSAgICAgKiB3aXRoIHtAbGluayAjRFRNRXhjZXB0aW9uKFRocm93YWJsZSl9IG9yCi0gICAgICoge0BsaW5rICNEVE1FeGNlcHRpb24oU3RyaW5nLFRocm93YWJsZSl9LCB0aGlzIG1ldGhvZCBjYW5ub3QgYmUgY2FsbGVkCi0gICAgICogZXZlbiBvbmNlLgotICAgICAqCi0gICAgICogQHBhcmFtICBjYXVzZSB0aGUgY2F1c2UgKHdoaWNoIGlzIHNhdmVkIGZvciBsYXRlciByZXRyaWV2YWwgYnkgdGhlCi0gICAgICogICAgICAgICB7QGxpbmsgI2dldENhdXNlKCl9IG1ldGhvZCkuICAoQSA8dHQ+bnVsbDwvdHQ+IHZhbHVlIGlzCi0gICAgICogICAgICAgICBwZXJtaXR0ZWQsIGFuZCBpbmRpY2F0ZXMgdGhhdCB0aGUgY2F1c2UgaXMgbm9uZXhpc3RlbnQgb3IKLSAgICAgKiAgICAgICAgIHVua25vd24uKQotICAgICAqIEByZXR1cm4gIGEgcmVmZXJlbmNlIHRvIHRoaXMgPGNvZGU+VGhyb3dhYmxlPC9jb2RlPiBpbnN0YW5jZS4KLSAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiA8Y29kZT5jYXVzZTwvY29kZT4gaXMgdGhpcwotICAgICAqICAgICAgICAgdGhyb3dhYmxlLiAgKEEgdGhyb3dhYmxlIGNhbm5vdAotICAgICAqICAgICAgICAgYmUgaXRzIG93biBjYXVzZS4pCi0gICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyB0aHJvd2FibGUgd2FzCi0gICAgICogICAgICAgICBjcmVhdGVkIHdpdGgge0BsaW5rICNEVE1FeGNlcHRpb24oVGhyb3dhYmxlKX0gb3IKLSAgICAgKiAgICAgICAgIHtAbGluayAjRFRNRXhjZXB0aW9uKFN0cmluZyxUaHJvd2FibGUpfSwgb3IgdGhpcyBtZXRob2QgaGFzIGFscmVhZHkKLSAgICAgKiAgICAgICAgIGJlZW4gY2FsbGVkIG9uIHRoaXMgdGhyb3dhYmxlLgotICAgICAqLwotICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgVGhyb3dhYmxlIGluaXRDYXVzZShUaHJvd2FibGUgY2F1c2UpIHsKLQotICAgICAgICBpZiAoKHRoaXMuY29udGFpbmVkRXhjZXB0aW9uID09IG51bGwpICYmIChjYXVzZSAhPSBudWxsKSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbihYTUxNZXNzYWdlcy5jcmVhdGVYTUxNZXNzYWdlKFhNTEVycm9yUmVzb3VyY2VzLkVSX0NBTk5PVF9PVkVSV1JJVEVfQ0FVU0UsIG51bGwpKTsgLy8iQ2FuJ3Qgb3ZlcndyaXRlIGNhdXNlIik7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoY2F1c2UgPT0gdGhpcykgewotICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICBYTUxNZXNzYWdlcy5jcmVhdGVYTUxNZXNzYWdlKFhNTEVycm9yUmVzb3VyY2VzLkVSX1NFTEZfQ0FVU0FUSU9OX05PVF9QRVJNSVRURUQsIG51bGwpKTsgLy8iU2VsZi1jYXVzYXRpb24gbm90IHBlcm1pdHRlZCIpOwotICAgICAgICB9Ci0KLSAgICAgICAgdGhpcy5jb250YWluZWRFeGNlcHRpb24gPSBjYXVzZTsKLQotICAgICAgICByZXR1cm4gdGhpczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGUgYSBuZXcgRFRNRXhjZXB0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIG1lc3NhZ2UgVGhlIGVycm9yIG9yIHdhcm5pbmcgbWVzc2FnZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgRFRNRXhjZXB0aW9uKFN0cmluZyBtZXNzYWdlKSB7Ci0KLSAgICAgICAgc3VwZXIobWVzc2FnZSk7Ci0KLSAgICAgICAgdGhpcy5jb250YWluZWRFeGNlcHRpb24gPSBudWxsOwotICAgICAgICB0aGlzLmxvY2F0b3IgICAgICAgICAgICA9IG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlIGEgbmV3IERUTUV4Y2VwdGlvbiB3cmFwcGluZyBhbiBleGlzdGluZyBleGNlcHRpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZSBUaGUgZXhjZXB0aW9uIHRvIGJlIHdyYXBwZWQuCi0gICAgICovCi0gICAgcHVibGljIERUTUV4Y2VwdGlvbihUaHJvd2FibGUgZSkgewotCi0gICAgICAgIHN1cGVyKGUuZ2V0TWVzc2FnZSgpKTsKLQotICAgICAgICB0aGlzLmNvbnRhaW5lZEV4Y2VwdGlvbiA9IGU7Ci0gICAgICAgIHRoaXMubG9jYXRvciAgICAgICAgICAgID0gbnVsbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBXcmFwIGFuIGV4aXN0aW5nIGV4Y2VwdGlvbiBpbiBhIERUTUV4Y2VwdGlvbi4KLSAgICAgKgotICAgICAqIDxwPlRoaXMgaXMgdXNlZCBmb3IgdGhyb3dpbmcgcHJvY2Vzc29yIGV4Y2VwdGlvbnMgYmVmb3JlCi0gICAgICogdGhlIHByb2Nlc3NpbmcgaGFzIHN0YXJ0ZWQuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIG1lc3NhZ2UgVGhlIGVycm9yIG9yIHdhcm5pbmcgbWVzc2FnZSwgb3IgbnVsbCB0bwotICAgICAqICAgICAgICAgICAgICAgIHVzZSB0aGUgbWVzc2FnZSBmcm9tIHRoZSBlbWJlZGRlZCBleGNlcHRpb24uCi0gICAgICogQHBhcmFtIGUgQW55IGV4Y2VwdGlvbgotICAgICAqLwotICAgIHB1YmxpYyBEVE1FeGNlcHRpb24oU3RyaW5nIG1lc3NhZ2UsIFRocm93YWJsZSBlKSB7Ci0KLSAgICAgICAgc3VwZXIoKChtZXNzYWdlID09IG51bGwpIHx8IChtZXNzYWdlLmxlbmd0aCgpID09IDApKQotICAgICAgICAgICAgICA/IGUuZ2V0TWVzc2FnZSgpCi0gICAgICAgICAgICAgIDogbWVzc2FnZSk7Ci0KLSAgICAgICAgdGhpcy5jb250YWluZWRFeGNlcHRpb24gPSBlOwotICAgICAgICB0aGlzLmxvY2F0b3IgICAgICAgICAgICA9IG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlIGEgbmV3IERUTUV4Y2VwdGlvbiBmcm9tIGEgbWVzc2FnZSBhbmQgYSBMb2NhdG9yLgotICAgICAqCi0gICAgICogPHA+VGhpcyBjb25zdHJ1Y3RvciBpcyBlc3BlY2lhbGx5IHVzZWZ1bCB3aGVuIGFuIGFwcGxpY2F0aW9uIGlzCi0gICAgICogY3JlYXRpbmcgaXRzIG93biBleGNlcHRpb24gZnJvbSB3aXRoaW4gYSBEb2N1bWVudEhhbmRsZXIKLSAgICAgKiBjYWxsYmFjay48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gbWVzc2FnZSBUaGUgZXJyb3Igb3Igd2FybmluZyBtZXNzYWdlLgotICAgICAqIEBwYXJhbSBsb2NhdG9yIFRoZSBsb2NhdG9yIG9iamVjdCBmb3IgdGhlIGVycm9yIG9yIHdhcm5pbmcuCi0gICAgICovCi0gICAgcHVibGljIERUTUV4Y2VwdGlvbihTdHJpbmcgbWVzc2FnZSwgU291cmNlTG9jYXRvciBsb2NhdG9yKSB7Ci0KLSAgICAgICAgc3VwZXIobWVzc2FnZSk7Ci0KLSAgICAgICAgdGhpcy5jb250YWluZWRFeGNlcHRpb24gPSBudWxsOwotICAgICAgICB0aGlzLmxvY2F0b3IgICAgICAgICAgICA9IGxvY2F0b3I7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogV3JhcCBhbiBleGlzdGluZyBleGNlcHRpb24gaW4gYSBEVE1FeGNlcHRpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbWVzc2FnZSBUaGUgZXJyb3Igb3Igd2FybmluZyBtZXNzYWdlLCBvciBudWxsIHRvCi0gICAgICogICAgICAgICAgICAgICAgdXNlIHRoZSBtZXNzYWdlIGZyb20gdGhlIGVtYmVkZGVkIGV4Y2VwdGlvbi4KLSAgICAgKiBAcGFyYW0gbG9jYXRvciBUaGUgbG9jYXRvciBvYmplY3QgZm9yIHRoZSBlcnJvciBvciB3YXJuaW5nLgotICAgICAqIEBwYXJhbSBlIEFueSBleGNlcHRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgRFRNRXhjZXB0aW9uKFN0cmluZyBtZXNzYWdlLCBTb3VyY2VMb2NhdG9yIGxvY2F0b3IsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRocm93YWJsZSBlKSB7Ci0KLSAgICAgICAgc3VwZXIobWVzc2FnZSk7Ci0KLSAgICAgICAgdGhpcy5jb250YWluZWRFeGNlcHRpb24gPSBlOwotICAgICAgICB0aGlzLmxvY2F0b3IgICAgICAgICAgICA9IGxvY2F0b3I7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBlcnJvciBtZXNzYWdlIHdpdGggbG9jYXRpb24gaW5mb3JtYXRpb24KLSAgICAgKiBhcHBlbmRlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE1lc3NhZ2VBbmRMb2NhdGlvbigpIHsKLQotICAgICAgICBTdHJpbmdCdWZmZXIgc2J1ZmZlciA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLSAgICAgICAgU3RyaW5nICAgICAgIG1lc3NhZ2UgPSBzdXBlci5nZXRNZXNzYWdlKCk7Ci0KLSAgICAgICAgaWYgKG51bGwgIT0gbWVzc2FnZSkgewotICAgICAgICAgICAgc2J1ZmZlci5hcHBlbmQobWVzc2FnZSk7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAobnVsbCAhPSBsb2NhdG9yKSB7Ci0gICAgICAgICAgICBTdHJpbmcgc3lzdGVtSUQgPSBsb2NhdG9yLmdldFN5c3RlbUlkKCk7Ci0gICAgICAgICAgICBpbnQgICAgbGluZSAgICAgPSBsb2NhdG9yLmdldExpbmVOdW1iZXIoKTsKLSAgICAgICAgICAgIGludCAgICBjb2x1bW4gICA9IGxvY2F0b3IuZ2V0Q29sdW1uTnVtYmVyKCk7Ci0KLSAgICAgICAgICAgIGlmIChudWxsICE9IHN5c3RlbUlEKSB7Ci0gICAgICAgICAgICAgICAgc2J1ZmZlci5hcHBlbmQoIjsgU3lzdGVtSUQ6ICIpOwotICAgICAgICAgICAgICAgIHNidWZmZXIuYXBwZW5kKHN5c3RlbUlEKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKDAgIT0gbGluZSkgewotICAgICAgICAgICAgICAgIHNidWZmZXIuYXBwZW5kKCI7IExpbmUjOiAiKTsKLSAgICAgICAgICAgICAgICBzYnVmZmVyLmFwcGVuZChsaW5lKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKDAgIT0gY29sdW1uKSB7Ci0gICAgICAgICAgICAgICAgc2J1ZmZlci5hcHBlbmQoIjsgQ29sdW1uIzogIik7Ci0gICAgICAgICAgICAgICAgc2J1ZmZlci5hcHBlbmQoY29sdW1uKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBzYnVmZmVyLnRvU3RyaW5nKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBsb2NhdGlvbiBpbmZvcm1hdGlvbiBhcyBhIHN0cmluZy4KLSAgICAgKgotICAgICAqIEByZXR1cm4gQSBzdHJpbmcgd2l0aCBsb2NhdGlvbiBpbmZvLCBvciBudWxsCi0gICAgICogaWYgdGhlcmUgaXMgbm8gbG9jYXRpb24gaW5mb3JtYXRpb24uCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRMb2NhdGlvbkFzU3RyaW5nKCkgewotCi0gICAgICAgIGlmIChudWxsICE9IGxvY2F0b3IpIHsKLSAgICAgICAgICAgIFN0cmluZ0J1ZmZlciBzYnVmZmVyICA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLSAgICAgICAgICAgIFN0cmluZyAgICAgICBzeXN0ZW1JRCA9IGxvY2F0b3IuZ2V0U3lzdGVtSWQoKTsKLSAgICAgICAgICAgIGludCAgICAgICAgICBsaW5lICAgICA9IGxvY2F0b3IuZ2V0TGluZU51bWJlcigpOwotICAgICAgICAgICAgaW50ICAgICAgICAgIGNvbHVtbiAgID0gbG9jYXRvci5nZXRDb2x1bW5OdW1iZXIoKTsKLQotICAgICAgICAgICAgaWYgKG51bGwgIT0gc3lzdGVtSUQpIHsKLSAgICAgICAgICAgICAgICBzYnVmZmVyLmFwcGVuZCgiOyBTeXN0ZW1JRDogIik7Ci0gICAgICAgICAgICAgICAgc2J1ZmZlci5hcHBlbmQoc3lzdGVtSUQpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAoMCAhPSBsaW5lKSB7Ci0gICAgICAgICAgICAgICAgc2J1ZmZlci5hcHBlbmQoIjsgTGluZSM6ICIpOwotICAgICAgICAgICAgICAgIHNidWZmZXIuYXBwZW5kKGxpbmUpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAoMCAhPSBjb2x1bW4pIHsKLSAgICAgICAgICAgICAgICBzYnVmZmVyLmFwcGVuZCgiOyBDb2x1bW4jOiAiKTsKLSAgICAgICAgICAgICAgICBzYnVmZmVyLmFwcGVuZChjb2x1bW4pOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICByZXR1cm4gc2J1ZmZlci50b1N0cmluZygpOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBQcmludCB0aGUgdGhlIHRyYWNlIG9mIG1ldGhvZHMgZnJvbSB3aGVyZSB0aGUgZXJyb3IKLSAgICAgKiBvcmlnaW5hdGVkLiAgVGhpcyB3aWxsIHRyYWNlIGFsbCBuZXN0ZWQgZXhjZXB0aW9uCi0gICAgICogb2JqZWN0cywgYXMgd2VsbCBhcyB0aGlzIG9iamVjdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBwcmludFN0YWNrVHJhY2UoKSB7Ci0gICAgICAgIHByaW50U3RhY2tUcmFjZShuZXcgamF2YS5pby5QcmludFdyaXRlcihTeXN0ZW0uZXJyLCB0cnVlKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUHJpbnQgdGhlIHRoZSB0cmFjZSBvZiBtZXRob2RzIGZyb20gd2hlcmUgdGhlIGVycm9yCi0gICAgICogb3JpZ2luYXRlZC4gIFRoaXMgd2lsbCB0cmFjZSBhbGwgbmVzdGVkIGV4Y2VwdGlvbgotICAgICAqIG9iamVjdHMsIGFzIHdlbGwgYXMgdGhpcyBvYmplY3QuCi0gICAgICogQHBhcmFtIHMgVGhlIHN0cmVhbSB3aGVyZSB0aGUgZHVtcCB3aWxsIGJlIHNlbnQgdG8uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcHJpbnRTdGFja1RyYWNlKGphdmEuaW8uUHJpbnRTdHJlYW0gcykgewotICAgICAgICBwcmludFN0YWNrVHJhY2UobmV3IGphdmEuaW8uUHJpbnRXcml0ZXIocykpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFByaW50IHRoZSB0aGUgdHJhY2Ugb2YgbWV0aG9kcyBmcm9tIHdoZXJlIHRoZSBlcnJvcgotICAgICAqIG9yaWdpbmF0ZWQuICBUaGlzIHdpbGwgdHJhY2UgYWxsIG5lc3RlZCBleGNlcHRpb24KLSAgICAgKiBvYmplY3RzLCBhcyB3ZWxsIGFzIHRoaXMgb2JqZWN0LgotICAgICAqIEBwYXJhbSBzIFRoZSB3cml0ZXIgd2hlcmUgdGhlIGR1bXAgd2lsbCBiZSBzZW50IHRvLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHByaW50U3RhY2tUcmFjZShqYXZhLmlvLlByaW50V3JpdGVyIHMpIHsKLQotICAgICAgICBpZiAocyA9PSBudWxsKSB7Ci0gICAgICAgICAgICBzID0gbmV3IGphdmEuaW8uUHJpbnRXcml0ZXIoU3lzdGVtLmVyciwgdHJ1ZSk7Ci0gICAgICAgIH0KLQotICAgICAgICB0cnkgewotICAgICAgICAgICAgU3RyaW5nIGxvY0luZm8gPSBnZXRMb2NhdGlvbkFzU3RyaW5nKCk7Ci0KLSAgICAgICAgICAgIGlmIChudWxsICE9IGxvY0luZm8pIHsKLSAgICAgICAgICAgICAgICBzLnByaW50bG4obG9jSW5mbyk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIHN1cGVyLnByaW50U3RhY2tUcmFjZShzKTsKLSAgICAgICAgfSBjYXRjaCAoVGhyb3dhYmxlIGUpIHt9Ci0KLSAgICAgICAgYm9vbGVhbiBpc0pkazE0T3JIaWdoZXIgPSBmYWxzZTsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIFRocm93YWJsZS5jbGFzcy5nZXRNZXRob2QoImdldENhdXNlIiwgKENsYXNzW10pIG51bGwpOwotICAgICAgICAgICAgaXNKZGsxNE9ySGlnaGVyID0gdHJ1ZTsKLSAgICAgICAgfSBjYXRjaCAoTm9TdWNoTWV0aG9kRXhjZXB0aW9uIG5zbWUpIHsKLSAgICAgICAgICAgIC8vIGRvIG5vdGhpbmcKLSAgICAgICAgfQotCi0gICAgICAgIC8vIFRoZSBwcmludFN0YWNrVHJhY2UgbWV0aG9kIG9mIHRoZSBUaHJvd2FibGUgY2xhc3MgaW4gamRrIDEuNAotICAgICAgICAvLyBhbmQgaGlnaGVyIHdpbGwgaW5jbHVkZSB0aGUgY2F1c2Ugd2hlbiBwcmludGluZyB0aGUgYmFja3RyYWNlLgotICAgICAgICAvLyBUaGUgZm9sbG93aW5nIGNvZGUgaXMgb25seSByZXF1aXJlZCB3aGVuIHVzaW5nIGpkayAxLjMgb3IgbG93ZXIKLSAgICAgICAgaWYgKCFpc0pkazE0T3JIaWdoZXIpIHsKLSAgICAgICAgICAgIFRocm93YWJsZSBleGNlcHRpb24gPSBnZXRFeGNlcHRpb24oKTsKLQotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IChpIDwgMTApICYmIChudWxsICE9IGV4Y2VwdGlvbik7IGkrKykgewotICAgICAgICAgICAgICAgIHMucHJpbnRsbigiLS0tLS0tLS0tIik7Ci0KLSAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICBpZiAoZXhjZXB0aW9uIGluc3RhbmNlb2YgRFRNRXhjZXB0aW9uKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbG9jSW5mbyA9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgKChEVE1FeGNlcHRpb24pIGV4Y2VwdGlvbikKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmdldExvY2F0aW9uQXNTdHJpbmcoKTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG51bGwgIT0gbG9jSW5mbykgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMucHJpbnRsbihsb2NJbmZvKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgIGV4Y2VwdGlvbi5wcmludFN0YWNrVHJhY2Uocyk7Ci0gICAgICAgICAgICAgICAgfSBjYXRjaCAoVGhyb3dhYmxlIGUpIHsKLSAgICAgICAgICAgICAgICAgICAgcy5wcmludGxuKCJDb3VsZCBub3QgcHJpbnQgc3RhY2sgdHJhY2UuLi4iKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICBNZXRob2QgbWV0aCA9Ci0gICAgICAgICAgICAgICAgICAgICAgICAoKE9iamVjdCkgZXhjZXB0aW9uKS5nZXRDbGFzcygpLmdldE1ldGhvZCgiZ2V0RXhjZXB0aW9uIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAoQ2xhc3NbXSkgbnVsbCk7Ci0KLSAgICAgICAgICAgICAgICAgICAgaWYgKG51bGwgIT0gbWV0aCkgewotICAgICAgICAgICAgICAgICAgICAgICAgVGhyb3dhYmxlIHByZXYgPSBleGNlcHRpb247Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIGV4Y2VwdGlvbiA9IChUaHJvd2FibGUpIG1ldGguaW52b2tlKGV4Y2VwdGlvbiwgKE9iamVjdFtdKSBudWxsKTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHByZXYgPT0gZXhjZXB0aW9uKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBleGNlcHRpb24gPSBudWxsOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfSBjYXRjaCAoSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbiBpdGUpIHsKLSAgICAgICAgICAgICAgICAgICAgZXhjZXB0aW9uID0gbnVsbDsKLSAgICAgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIGlhZSkgewotICAgICAgICAgICAgICAgICAgICBleGNlcHRpb24gPSBudWxsOwotICAgICAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaE1ldGhvZEV4Y2VwdGlvbiBuc21lKSB7Ci0gICAgICAgICAgICAgICAgICAgIGV4Y2VwdGlvbiA9IG51bGw7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUZpbHRlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUZpbHRlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzMzFlNzUzLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1GaWx0ZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE5MCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBEVE1GaWx0ZXIuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNSAwODoxNDo1MyBzdXJlc2hfZW1haWxpZCBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtOwotCi0vKioKLSAqIFNpbXBsZSBmaWx0ZXIgZm9yIGRvaW5nIG5vZGUgdGVzdHMuICBOb3RlIHRoZSBzZW1hbnRpY3Mgb2YgdGhpcyBhcmUKLSAqIHNvbWV3aGF0IGRpZmZlcmVudCB0aGF0IHRoZSBET00ncyBOb2RlRmlsdGVyLgotICovCi1wdWJsaWMgaW50ZXJmYWNlIERUTUZpbHRlcgotewotCi0gIC8vIENvbnN0YW50cyBmb3Igd2hhdFRvU2hvdy4gIFRoZXNlIGFyZSB1c2VkIHRvIHNldCB0aGUgbm9kZSB0eXBlIHRoYXQgd2lsbAotICAvLyBiZSB0cmF2ZXJzZWQuIFRoZXNlIHZhbHVlcyBtYXkgYmUgT1JlZCB0b2dldGhlciBiZWZvcmUgYmVpbmcgcGFzc2VkIHRvCi0gIC8vIHRoZSBEVE1JdGVyYXRvci4KLQotICAvKioKLSAgICogU2hvdyBhbGwgPGNvZGU+Tm9kZXM8L2NvZGU+LgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0hPV19BTEwgPSAweEZGRkZGRkZGOwotCi0gIC8qKgotICAgKiBTaG93IDxjb2RlPkVsZW1lbnQ8L2NvZGU+IG5vZGVzLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0hPV19FTEVNRU5UID0gMHgwMDAwMDAwMTsKLQotICAvKioKLSAgICogU2hvdyA8Y29kZT5BdHRyPC9jb2RlPiBub2Rlcy4gVGhpcyBpcyBtZWFuaW5nZnVsIG9ubHkgd2hlbiBjcmVhdGluZyBhbgotICAgKiBpdGVyYXRvciBvciB0cmVlLXdhbGtlciB3aXRoIGFuIGF0dHJpYnV0ZSBub2RlIGFzIGl0cwotICAgKiA8Y29kZT5yb290PC9jb2RlPjsgaW4gdGhpcyBjYXNlLCBpdCBtZWFucyB0aGF0IHRoZSBhdHRyaWJ1dGUgbm9kZQotICAgKiB3aWxsIGFwcGVhciBpbiB0aGUgZmlyc3QgcG9zaXRpb24gb2YgdGhlIGl0ZXJhdGlvbiBvciB0cmF2ZXJzYWwuCi0gICAqIFNpbmNlIGF0dHJpYnV0ZXMgYXJlIG5ldmVyIGNoaWxkcmVuIG9mIG90aGVyIG5vZGVzLCB0aGV5IGRvIG5vdAotICAgKiBhcHBlYXIgd2hlbiB0cmF2ZXJzaW5nIG92ZXIgdGhlIG1haW4gZG9jdW1lbnQgdHJlZS4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNIT1dfQVRUUklCVVRFID0gMHgwMDAwMDAwMjsKLQotICAvKioKLSAgICogU2hvdyA8Y29kZT5UZXh0PC9jb2RlPiBub2Rlcy4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNIT1dfVEVYVCA9IDB4MDAwMDAwMDQ7Ci0KLSAgLyoqCi0gICAqIFNob3cgPGNvZGU+Q0RBVEFTZWN0aW9uPC9jb2RlPiBub2Rlcy4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNIT1dfQ0RBVEFfU0VDVElPTiA9IDB4MDAwMDAwMDg7Ci0KLSAgLyoqCi0gICAqIFNob3cgPGNvZGU+RW50aXR5UmVmZXJlbmNlPC9jb2RlPiBub2Rlcy4gTm90ZSB0aGF0IGlmIEVudGl0eSBSZWZlcmVuY2VzCi0gICAqIGhhdmUgYmVlbiBmdWxseSBleHBhbmRlZCB3aGlsZSB0aGUgdHJlZSB3YXMgYmVpbmcgY29uc3RydWN0ZWQsIHRoZXNlCi0gICAqIG5vZGVzIHdpbGwgbm90IGFwcGVhciBhbmQgdGhpcyBtYXNrIGhhcyBubyBlZmZlY3QuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTSE9XX0VOVElUWV9SRUZFUkVOQ0UgPSAweDAwMDAwMDEwOwotCi0gIC8qKgotICAgKiBTaG93IDxjb2RlPkVudGl0eTwvY29kZT4gbm9kZXMuIFRoaXMgaXMgbWVhbmluZ2Z1bCBvbmx5IHdoZW4gY3JlYXRpbmcKLSAgICogYW4gaXRlcmF0b3Igb3IgdHJlZS13YWxrZXIgd2l0aCBhbjxjb2RlPiBFbnRpdHk8L2NvZGU+IG5vZGUgYXMgaXRzCi0gICAqIDxjb2RlPnJvb3Q8L2NvZGU+OyBpbiB0aGlzIGNhc2UsIGl0IG1lYW5zIHRoYXQgdGhlIDxjb2RlPkVudGl0eTwvY29kZT4KLSAgICogIG5vZGUgd2lsbCBhcHBlYXIgaW4gdGhlIGZpcnN0IHBvc2l0aW9uIG9mIHRoZSB0cmF2ZXJzYWwuIFNpbmNlCi0gICAqIGVudGl0aWVzIGFyZSBub3QgcGFydCBvZiB0aGUgZG9jdW1lbnQgdHJlZSwgdGhleSBkbyBub3QgYXBwZWFyIHdoZW4KLSAgICogdHJhdmVyc2luZyBvdmVyIHRoZSBtYWluIGRvY3VtZW50IHRyZWUuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTSE9XX0VOVElUWSA9IDB4MDAwMDAwMjA7Ci0KLSAgLyoqCi0gICAqIFNob3cgPGNvZGU+UHJvY2Vzc2luZ0luc3RydWN0aW9uPC9jb2RlPiBub2Rlcy4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNIT1dfUFJPQ0VTU0lOR19JTlNUUlVDVElPTiA9IDB4MDAwMDAwNDA7Ci0KLSAgLyoqCi0gICAqIFNob3cgPGNvZGU+Q29tbWVudDwvY29kZT4gbm9kZXMuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTSE9XX0NPTU1FTlQgPSAweDAwMDAwMDgwOwotCi0gIC8qKgotICAgKiBTaG93IDxjb2RlPkRvY3VtZW50PC9jb2RlPiBub2Rlcy4gKE9mIGNvdXJzZSwgYXMgd2l0aCBBdHRyaWJ1dGVzCi0gICAqIGFuZCBzdWNoLCB0aGlzIGlzIG1lYW5pbmdmdWwgb25seSB3aGVuIHRoZSBpdGVyYXRpb24gcm9vdCBpcyB0aGUKLSAgICogRG9jdW1lbnQgaXRzZWxmLCBzaW5jZSBEb2N1bWVudCBoYXMgbm8gcGFyZW50LikKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNIT1dfRE9DVU1FTlQgPSAweDAwMDAwMTAwOwotCi0gIC8qKgotICAgKiBTaG93IDxjb2RlPkRvY3VtZW50VHlwZTwvY29kZT4gbm9kZXMuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTSE9XX0RPQ1VNRU5UX1RZUEUgPSAweDAwMDAwMjAwOwotCi0gIC8qKgotICAgKiBTaG93IDxjb2RlPkRvY3VtZW50RnJhZ21lbnQ8L2NvZGU+IG5vZGVzLiAoT2YgY291cnNlLCBhcyB3aXRoCi0gICAqIEF0dHJpYnV0ZXMgYW5kIHN1Y2gsIHRoaXMgaXMgbWVhbmluZ2Z1bCBvbmx5IHdoZW4gdGhlIGl0ZXJhdGlvbgotICAgKiByb290IGlzIHRoZSBEb2N1bWVudCBpdHNlbGYsIHNpbmNlIERvY3VtZW50RnJhZ21lbnQgaGFzIG5vIHBhcmVudC4pCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTSE9XX0RPQ1VNRU5UX0ZSQUdNRU5UID0gMHgwMDAwMDQwMDsKLQotICAvKioKLSAgICogU2hvdyA8Y29kZT5Ob3RhdGlvbjwvY29kZT4gbm9kZXMuIFRoaXMgaXMgbWVhbmluZ2Z1bCBvbmx5IHdoZW4gY3JlYXRpbmcKLSAgICogYW4gaXRlcmF0b3Igb3IgdHJlZS13YWxrZXIgd2l0aCBhIDxjb2RlPk5vdGF0aW9uPC9jb2RlPiBub2RlIGFzIGl0cwotICAgKiA8Y29kZT5yb290PC9jb2RlPjsgaW4gdGhpcyBjYXNlLCBpdCBtZWFucyB0aGF0IHRoZQotICAgKiA8Y29kZT5Ob3RhdGlvbjwvY29kZT4gbm9kZSB3aWxsIGFwcGVhciBpbiB0aGUgZmlyc3QgcG9zaXRpb24gb2YgdGhlCi0gICAqIHRyYXZlcnNhbC4gU2luY2Ugbm90YXRpb25zIGFyZSBub3QgcGFydCBvZiB0aGUgZG9jdW1lbnQgdHJlZSwgdGhleSBkbwotICAgKiBub3QgYXBwZWFyIHdoZW4gdHJhdmVyc2luZyBvdmVyIHRoZSBtYWluIGRvY3VtZW50IHRyZWUuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTSE9XX05PVEFUSU9OID0gMHgwMDAwMDgwMDsKLQotICAvKioKLQotICAgKiBUaGlzIGJpdCBpbnN0cnVjdHMgdGhlIGl0ZXJhdG9yIHRvIHNob3cgbmFtZXNwYWNlIG5vZGVzLCB3aGljaAotICAgKiBhcmUgbW9kZWxlZCBieSBEVE0gYnV0IG5vdCBieSB0aGUgRE9NLiAgTWFrZSBzdXJlIHRoaXMgZG9lcyBub3QKLSAgICogY29uZmxpY3Qgd2l0aCB7QGxpbmsgb3JnLnczYy5kb20udHJhdmVyc2FsLk5vZGVGaWx0ZXJ9LgotICAgKiA8cD4KLSAgICogJVJFVklFVyUgTWlnaHQgYmUgc2FmZXIgdG8gc3RhcnQgZnJvbSBoaWdoZXIgYml0cyBhbmQgd29yayBkb3duLAotICAgKiB0byBsZWF2ZSByb29tIGZvciB0aGUgRE9NIHRvIGV4cGFuZCBpdHMgc2V0IG9mIGNvbnN0YW50cy4uLiBPciwKLSAgICogcG9zc2libHksIHRvIGNyZWF0ZSBhIERUTS1zcGVjaWZpYyBmaWVsZCBmb3IgdGhlc2UgYWRkaXRpb25hbCBiaXRzLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0hPV19OQU1FU1BBQ0UgPSAweDAwMDAxMDAwOwotCi0gIC8qKgotICAgKiBTcGVjaWFsIGJpdCBmb3IgZmlsdGVycyBpbXBsZW1lbnRpbmcgbWF0Y2ggcGF0dGVybnMgc3RhcnRpbmcgd2l0aAotICAgKiBhIGZ1bmN0aW9uLiAgTWFrZSBzdXJlIHRoaXMgZG9lcyBub3QgY29uZmxpY3Qgd2l0aAotICAgKiB7QGxpbmsgb3JnLnczYy5kb20udHJhdmVyc2FsLk5vZGVGaWx0ZXJ9LgotICAgKiA8cD4KLSAgICogJVJFVklFVyUgTWlnaHQgYmUgc2FmZXIgdG8gc3RhcnQgZnJvbSBoaWdoZXIgYml0cyBhbmQgd29yayBkb3duLAotICAgKiB0byBsZWF2ZSByb29tIGZvciB0aGUgRE9NIHRvIGV4cGFuZCBpdHMgc2V0IG9mIGNvbnN0YW50cy4uLiBPciwKLSAgICogcG9zc2libHksIHRvIGNyZWF0ZSBhIERUTS1zcGVjaWZpYyBmaWVsZCBmb3IgdGhlc2UgYWRkaXRpb25hbCBiaXRzLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0hPV19CWUZVTkNUSU9OID0gMHgwMDAxMDAwMDsKLQotICAvKioKLSAgICogVGVzdCB3aGV0aGVyIGEgc3BlY2lmaWVkIG5vZGUgaXMgdmlzaWJsZSBpbiB0aGUgbG9naWNhbCB2aWV3IG9mIGEKLSAgICogPGNvZGU+RFRNSXRlcmF0b3I8L2NvZGU+LiBOb3JtYWxseSwgdGhpcyBmdW5jdGlvbgotICAgKiB3aWxsIGJlIGNhbGxlZCBieSB0aGUgaW1wbGVtZW50YXRpb24gb2YgPGNvZGU+RFRNSXRlcmF0b3I8L2NvZGU+OwotICAgKiBpdCBpcyBub3Qgbm9ybWFsbHkgY2FsbGVkIGRpcmVjdGx5IGZyb20KLSAgICogdXNlciBjb2RlLgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBpbnQgSGFuZGxlIG9mIHRoZSBub2RlLgotICAgKiBAcGFyYW0gd2hhdFRvU2hvdyBvbmUgb2YgU0hPV19YWFggdmFsdWVzLgotICAgKiBAcmV0dXJuIG9uZSBvZiBGSUxURVJfQUNDRVBULCBGSUxURVJfUkVKRUNULCBvciBGSUxURVJfU0tJUC4KLSAgICovCi0gIHB1YmxpYyBzaG9ydCBhY2NlcHROb2RlKGludCBub2RlSGFuZGxlLCBpbnQgd2hhdFRvU2hvdyk7Ci0KLSAgLyoqCi0gICAqIFRlc3Qgd2hldGhlciBhIHNwZWNpZmllZCBub2RlIGlzIHZpc2libGUgaW4gdGhlIGxvZ2ljYWwgdmlldyBvZiBhCi0gICAqIDxjb2RlPkRUTUl0ZXJhdG9yPC9jb2RlPi4gTm9ybWFsbHksIHRoaXMgZnVuY3Rpb24KLSAgICogd2lsbCBiZSBjYWxsZWQgYnkgdGhlIGltcGxlbWVudGF0aW9uIG9mIDxjb2RlPkRUTUl0ZXJhdG9yPC9jb2RlPjsKLSAgICogaXQgaXMgbm90IG5vcm1hbGx5IGNhbGxlZCBkaXJlY3RseSBmcm9tCi0gICAqIHVzZXIgY29kZS4KLSAgICogPHA+Ci0gICAqIFRPRE86IFNob3VsZCB0aGlzIGJlIHNldE5hbWVNYXRjaChleHBhbmRlZE5hbWUpIGZvbGxvd2VkIGJ5IGFjY2VwdCgpPwotICAgKiBPciB3aWxsIHdlIHJlYWxseSBiZSB0ZXN0aW5nIGEgZGlmZmVyZW50IG5hbWUgYXQgZXZlcnkgaW52b2NhdGlvbj8KLSAgICoKLSAgICogPHA+JVJFVklFVyUgVW5kZXIgd2hhdCBjaXJjdW1zdGFuY2VzIHdpbGwgdGhpcyBiZSB1c2VkPyBUaGUgY2FzZXMKLSAgICogSSd2ZSBjb25zaWRlcmVkIGFyZSBqdXN0IGFzIGVhc3kgYW5kIGp1c3QgYWJvdXQgYXMgZWZmaWNpZW50IGlmCi0gICAqIHRoZSBuYW1lIHRlc3QgaXMgcGVyZm9ybWVkIGluIHRoZSBEVE1JdGVyYXRvci4uLiAtLSBKb2U8L3A+Ci0gICAqCi0gICAqIDxwPiVSRVZJRVclIFNob3VsZCB0aGF0IDB4RkZGRiBoYXZlIGEgbW5lbW9uaWMgYXNzaWduZWQgdG8gaXQ/Ci0gICAqIEFsc286IFRoaXMgcmVwcmVzZW50YXRpb24gaXMgYXNzdW1pbmcgdGhlIGV4cGFuZGVkIG5hbWUgaXMgaW5kZWVkCi0gICAqIHNwbGl0IGludG8gaGlnaC9sb3cgMTYtYml0IGhhbGZ3b3Jkcy4gSWYgd2UgZXZlciBjaGFuZ2UgdGhlCi0gICAqIGJhbGFuY2UgYmV0d2VlbiBuYW1lc3BhY2UgYW5kIGxvY2FsbmFtZSBiaXRzIChlZyBiZWNhdXNlIHdlCi0gICAqIGRlY2lkZSB0aGVyZSBhcmUgbWFueSBtb3JlIGxvY2FsbmFtZXMgdGhhbiBuYW1lc3BhY2VzLCB3aGljaCBpcwotICAgKiBmYWlybHkgbGlrZWx5KSwgdGhpcyBpcyBnb2luZyB0byBicmVhay4gSXQgbWlnaHQgYmUgc2FmZXIgdG8KLSAgICogZW5jYXBzdWxhdGUgdGhlIGRldGFpbHMgd2l0aCBhIG1ha2VFeHBhbmRlZE5hbWUgbWV0aG9kIGFuZCBtYWtlCi0gICAqIHRoYXQgcmVzcG9uc2libGUgZm9yIHNldHRpbmcgdXAgdGhlIHdpbGRjYXJkIHZlcnNpb24gYXMgd2VsbC48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIGludCBIYW5kbGUgb2YgdGhlIG5vZGUuCi0gICAqIEBwYXJhbSB3aGF0VG9TaG93IG9uZSBvZiBTSE9XX1hYWCB2YWx1ZXMuCi0gICAqIEBwYXJhbSBleHBhbmRlZE5hbWUgYSB2YWx1ZSBkZWZpbmluZyB0aGUgZXhhbmRlZCBuYW1lIGFzIGRlZmluZWQgaW4KLSAgICogICAgICAgICAgICAgICAgICAgICB0aGUgRFRNIGludGVyZmFjZS4gIFdpbGQgY2FyZHMgd2lsbCBiZSBkZWZpbmVkCi0gICAqICAgICAgICAgICAgICAgICAgICAgYnkgMHhGRkZGIGluIHRoZSBuYW1lc3BhY2UgYW5kL29yIGxvY2FsbmFtZQotICAgKiAgICAgICAgICAgICAgICAgICAgIHBvcnRpb24gb2YgdGhlIGV4cGFuZGVkTmFtZS4KLSAgICogQHJldHVybiBvbmUgb2YgRklMVEVSX0FDQ0VQVCwgRklMVEVSX1JFSkVDVCwgb3IgRklMVEVSX1NLSVAuICAqLwotICBwdWJsaWMgc2hvcnQgYWNjZXB0Tm9kZShpbnQgbm9kZUhhbmRsZSwgaW50IHdoYXRUb1Nob3csIGludCBleHBhbmRlZE5hbWUpOwotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNSXRlcmF0b3IuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1JdGVyYXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2NGQwMWJlLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1JdGVyYXRvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzQ2ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IERUTUl0ZXJhdG9yLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTUgMDg6MTQ6NTQgc3VyZXNoX2VtYWlsaWQgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bTsKLQotLyoqCi0KLSAqIDxjb2RlPkRUTUl0ZXJhdG9yczwvY29kZT4gYXJlIHVzZWQgdG8gc3RlcCB0aHJvdWdoIGEgKHBvc3NpYmx5Ci0gKiBmaWx0ZXJlZCkgc2V0IG9mIG5vZGVzLiAgVGhlaXIgQVBJIGlzIG1vZGVsZWQgbGFyZ2VseSBhZnRlciB0aGUgRE9NCi0gKiBOb2RlSXRlcmF0b3IuCi0gKgotICogPHA+QSBEVE1JdGVyYXRvciBpcyBhIHNvbWV3aGF0IHVudXN1YWwgdHlwZSBvZiBpdGVyYXRvciwgaW4gdGhhdCBpdAotICogY2FuIHNlcnZlIGJvdGggc2luZ2xlIG5vZGUgaXRlcmF0aW9uIGFuZCByYW5kb20gYWNjZXNzLjwvcD4KLSAqCi0gKiA8cD5UaGUgRFRNSXRlcmF0b3IncyB0cmF2ZXJzYWwgc2VtYW50aWNzLCBpLmUuIGhvdyBpdCB3YWxrcyB0aGUgdHJlZSwKLSAqIGFyZSBzcGVjaWZpZWQgd2hlbiBpdCBpcyBjcmVhdGVkLCBwb3NzaWJseSBhbmQgcHJvYmFibHkgYnkgYW4gWFBhdGgKLSAqIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hwYXRoI05ULUxvY2F0aW9uUGF0aD5Mb2NhdGlvblBhdGg8L2E+IG9yCi0gKiBhIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hwYXRoI05ULVVuaW9uRXhwciI+VW5pb25FeHByPC9hPi48L3A+Ci0gKgotICogPHA+QSBEVE1JdGVyYXRvciBpcyBtZWFudCB0byBiZSBjcmVhdGVkIG9uY2UgYXMgYSBtYXN0ZXIgc3RhdGljIG9iamVjdCwgYW5kCi0gKiB0aGVuIGNsb25lZCBtYW55IHRpbWVzIGZvciBydW50aW1lIHVzZS4gIE9yIHRoZSBtYXN0ZXIgb2JqZWN0IGl0c2VsZiBtYXkKLSAqIGJlIHVzZWQgZm9yIHNpbXBsZXIgdXNlIGNhc2VzLjwvcD4KLSAqCi0gKiA8cD5BdCB0aGlzIHRpbWUsIHdlIGRvIG5vdCBleHBlY3QgRFRNSXRlcmF0b3IgdG8gZW11bGF0ZQotICogTm9kZUl0ZXJhdG9yJ3MgIm1haW50YWluIHJlbGF0aXZlIHBvc2l0aW9uIiBzZW1hbnRpY3MgdW5kZXIKLSAqIGRvY3VtZW50IG11dGF0aW9uLiAgSXQncyBsaWtlbHkgdG8gcmVzcG9uZCBtb3JlIGxpa2UgdGhlCi0gKiBUcmVlV2Fsa2VyJ3MgImN1cnJlbnQgbm9kZSIgc2VtYW50aWNzLiBIb3dldmVyLCBzaW5jZSB0aGUgYmFzZSBEVE0KLSAqIGlzIGltbXV0YWJsZSwgdGhpcyBpc3N1ZSBjdXJyZW50bHkgbWFrZXMgbm8gcHJhY3RpY2FsCi0gKiBkaWZmZXJlbmNlLjwvcD4KLSAqCi0gKiA8cD5TdGF0ZTogSW4gcHJvZ3Jlc3MhITwvcD4gKi8KLXB1YmxpYyBpbnRlcmZhY2UgRFRNSXRlcmF0b3IKLXsKLQotICAvLyBDb25zdGFudHMgcmV0dXJuZWQgYnkgYWNjZXB0Tm9kZSwgYm9ycm93ZWQgZnJvbSB0aGUgRE9NIFRyYXZlcnNhbCBjaGFwdGVyCi0gIC8vICVSRVZJRVclIFNob3VsZCB3ZSBleHBsaWNpdGx5IGluaXRpYWxpemUgdGhlbSBmcm9tLCBlZywKLSAgLy8gb3JnLnczYy5kb20udHJhdmVyc2FsLk5vZGVGaWx0ZXIuRklMVEVSX0FDQ0VQVD8KLQotICAvKioKLSAgICogQWNjZXB0IHRoZSBub2RlLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBGSUxURVJfQUNDRVBUID0gMTsKLQotICAvKioKLSAgICogUmVqZWN0IHRoZSBub2RlLiBTYW1lIGJlaGF2aW9yIGFzIEZJTFRFUl9TS0lQLiAoSW4gdGhlIERPTSB0aGVzZQotICAgKiBkaWZmZXIgd2hlbiBhcHBsaWVkIHRvIGEgVHJlZVdhbGtlciBidXQgaGF2ZSB0aGUgc2FtZSByZXN1bHQgd2hlbgotICAgKiBhcHBsaWVkIHRvIGEgTm9kZUl0ZXJhdG9yKS4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgRklMVEVSX1JFSkVDVCA9IDI7Ci0KLSAgLyoqCi0gICAqIFNraXAgdGhpcyBzaW5nbGUgbm9kZS4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgRklMVEVSX1NLSVAgPSAzOwotCi0gIC8qKgotICAgKiBHZXQgYW4gaW5zdGFuY2Ugb2YgYSBEVE0gdGhhdCAib3ducyIgYSBub2RlIGhhbmRsZS4gIFNpbmNlIGEgbm9kZQotICAgKiBpdGVyYXRvciBtYXkgYmUgcGFzc2VkIHdpdGhvdXQgYSBEVE1NYW5hZ2VyLCB0aGlzIGFsbG93cyB0aGUKLSAgICogY2FsbGVyIHRvIGVhc2lseSBnZXQgdGhlIERUTSB1c2luZyBqdXN0IHRoZSBpdGVyYXRvci4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgdGhlIG5vZGVIYW5kbGUuCi0gICAqCi0gICAqIEByZXR1cm4gYSBub24tbnVsbCBEVE0gcmVmZXJlbmNlLgotICAgKi8KLSAgcHVibGljIERUTSBnZXREVE0oaW50IG5vZGVIYW5kbGUpOwotCi0gIC8qKgotICAgKiBHZXQgYW4gaW5zdGFuY2Ugb2YgdGhlIERUTU1hbmFnZXIuICBTaW5jZSBhIG5vZGUKLSAgICogaXRlcmF0b3IgbWF5IGJlIHBhc3NlZCB3aXRob3V0IGEgRFRNTWFuYWdlciwgdGhpcyBhbGxvd3MgdGhlCi0gICAqIGNhbGxlciB0byBlYXNpbHkgZ2V0IHRoZSBEVE1NYW5hZ2VyIHVzaW5nIGp1c3QgdGhlIGl0ZXJhdG9yLgotICAgKgotICAgKiBAcmV0dXJuIGEgbm9uLW51bGwgRFRNTWFuYWdlciByZWZlcmVuY2UuCi0gICAqLwotICBwdWJsaWMgRFRNTWFuYWdlciBnZXREVE1NYW5hZ2VyKCk7Ci0KLSAgLyoqCi0gICAqIFRoZSByb290IG5vZGUgb2YgdGhlIDxjb2RlPkRUTUl0ZXJhdG9yPC9jb2RlPiwgYXMgc3BlY2lmaWVkIHdoZW4gaXQKLSAgICogd2FzIGNyZWF0ZWQuICBOb3RlIHRoZSByb290IG5vZGUgaXMgbm90IHRoZSByb290IG5vZGUgb2YgdGhlCi0gICAqIGRvY3VtZW50IHRyZWUsIGJ1dCB0aGUgY29udGV4dCBub2RlIGZyb20gd2hlcmUgdGhlIGl0ZXJhdGlvbgotICAgKiBiZWdpbnMgYW5kIGVuZHMuCi0gICAqCi0gICAqIEByZXR1cm4gbm9kZUhhbmRsZSBpbnQgSGFuZGxlIG9mIHRoZSBjb250ZXh0IG5vZGUuCi0gICAqLwotICBwdWJsaWMgaW50IGdldFJvb3QoKTsKLQotICAvKioKLSAgICogUmVzZXQgdGhlIHJvb3Qgbm9kZSBvZiB0aGUgPGNvZGU+RFRNSXRlcmF0b3I8L2NvZGU+LCBvdmVycmlkaW5nCi0gICAqIHRoZSB2YWx1ZSBzcGVjaWZpZWQgd2hlbiBpdCB3YXMgY3JlYXRlZC4gIE5vdGUgdGhlIHJvb3Qgbm9kZSBpcwotICAgKiBub3QgdGhlIHJvb3Qgbm9kZSBvZiB0aGUgZG9jdW1lbnQgdHJlZSwgYnV0IHRoZSBjb250ZXh0IG5vZGUgZnJvbQotICAgKiB3aGVyZSB0aGUgaXRlcmF0aW9uIGJlZ2lucy4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgaW50IEhhbmRsZSBvZiB0aGUgY29udGV4dCBub2RlLgotICAgKiBAcGFyYW0gZW52aXJvbm1lbnQgVGhlIGVudmlyb25tZW50IG9iamVjdC4KLSAgICogVGhlIGVudmlyb25tZW50IGluIHdoaWNoIHRoaXMgaXRlcmF0b3Igb3BlcmF0ZXMsIHdoaWNoIHNob3VsZCBwcm92aWRlOgotICAgKiA8dWw+Ci0gICAqIDxsaT5hIG5vZGUgKHRoZSBjb250ZXh0IG5vZGUuLi4gc2FtZSB2YWx1ZSBhcyAicm9vdCIgZGVmaW5lZCBiZWxvdykgPC9saT4KLSAgICogPGxpPmEgcGFpciBvZiBub24temVybyBwb3NpdGl2ZSBpbnRlZ2VycyAodGhlIGNvbnRleHQgcG9zaXRpb24gYW5kIHRoZSBjb250ZXh0IHNpemUpIDwvbGk+Ci0gICAqIDxsaT5hIHNldCBvZiB2YXJpYWJsZSBiaW5kaW5ncyA8L2xpPgotICAgKiA8bGk+YSBmdW5jdGlvbiBsaWJyYXJ5IDwvbGk+Ci0gICAqIDxsaT50aGUgc2V0IG9mIG5hbWVzcGFjZSBkZWNsYXJhdGlvbnMgaW4gc2NvcGUgZm9yIHRoZSBleHByZXNzaW9uLjwvbGk+Ci0gICAqIDx1bD4KLSAgICoKLSAgICogPHA+QXQgdGhpcyB0aW1lIHRoZSBleGFjdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGlzIGVudmlyb25tZW50IGlzIGFwcGxpY2F0aW9uCi0gICAqIGRlcGVuZGVudC4gIFByb2JhYmx5IGEgcHJvcGVyIGludGVyZmFjZSB3aWxsIGJlIGNyZWF0ZWQgZmFpcmx5IHNvb24uPC9wPgotICAgKgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0Um9vdChpbnQgbm9kZUhhbmRsZSwgT2JqZWN0IGVudmlyb25tZW50KTsKLQotICAvKioKLSAgICogUmVzZXQgdGhlIGl0ZXJhdG9yIHRvIHRoZSBzdGFydC4gQWZ0ZXIgcmVzZXR0aW5nLCB0aGUgbmV4dCBub2RlIHJldHVybmVkCi0gICAqIHdpbGwgYmUgdGhlIHJvb3Qgbm9kZSAtLSBvciwgaWYgdGhhdCdzIGZpbHRlcmVkIG91dCwgdGhlIGZpcnN0IG5vZGUKLSAgICogd2l0aGluIHRoZSByb290J3Mgc3VidHJlZSB3aGljaCBpcyBfbm90XyBza2lwcGVkIGJ5IHRoZSBmaWx0ZXJzLgotICAgKi8KLSAgcHVibGljIHZvaWQgcmVzZXQoKTsKLQotICAvKioKLSAgICogVGhpcyBhdHRyaWJ1dGUgZGV0ZXJtaW5lcyB3aGljaCBub2RlIHR5cGVzIGFyZSBwcmVzZW50ZWQgdmlhIHRoZQotICAgKiBpdGVyYXRvci4gVGhlIGF2YWlsYWJsZSBzZXQgb2YgY29uc3RhbnRzIGlzIGRlZmluZWQgYWJvdmUuCi0gICAqIE5vZGVzIG5vdCBhY2NlcHRlZCBieQotICAgKiA8Y29kZT53aGF0VG9TaG93PC9jb2RlPiB3aWxsIGJlIHNraXBwZWQsIGJ1dCB0aGVpciBjaGlsZHJlbiBtYXkgc3RpbGwKLSAgICogYmUgY29uc2lkZXJlZC4KLSAgICoKLSAgICogQHJldHVybiBvbmUgb2YgdGhlIFNIT1dfWFhYIGNvbnN0YW50cywgb3Igc2V2ZXJhbCBPUmVkIHRvZ2V0aGVyLgotICAgKi8KLSAgcHVibGljIGludCBnZXRXaGF0VG9TaG93KCk7Ci0KLSAgLyoqCi0gICAqIDxwPlRoZSB2YWx1ZSBvZiB0aGlzIGZsYWcgZGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBjaGlsZHJlbiBvZiBlbnRpdHkKLSAgICogcmVmZXJlbmNlIG5vZGVzIGFyZSB2aXNpYmxlIHRvIHRoZSBpdGVyYXRvci4gSWYgZmFsc2UsIHRoZXkgIGFuZAotICAgKiB0aGVpciBkZXNjZW5kYW50cyB3aWxsIGJlIHJlamVjdGVkLiBOb3RlIHRoYXQgdGhpcyByZWplY3Rpb24gdGFrZXMKLSAgICogcHJlY2VkZW5jZSBvdmVyIDxjb2RlPndoYXRUb1Nob3c8L2NvZGU+IGFuZCB0aGUgZmlsdGVyLiA8L3A+Ci0gICAqCi0gICAqIDxwPiBUbyBwcm9kdWNlIGEgdmlldyBvZiB0aGUgZG9jdW1lbnQgdGhhdCBoYXMgZW50aXR5IHJlZmVyZW5jZXMKLSAgICogZXhwYW5kZWQgYW5kIGRvZXMgbm90IGV4cG9zZSB0aGUgZW50aXR5IHJlZmVyZW5jZSBub2RlIGl0c2VsZiwgdXNlCi0gICAqIHRoZSA8Y29kZT53aGF0VG9TaG93PC9jb2RlPiBmbGFncyB0byBoaWRlIHRoZSBlbnRpdHkgcmVmZXJlbmNlIG5vZGUKLSAgICogYW5kIHNldCA8Y29kZT5leHBhbmRFbnRpdHlSZWZlcmVuY2VzPC9jb2RlPiB0byB0cnVlIHdoZW4gY3JlYXRpbmcgdGhlCi0gICAqIGl0ZXJhdG9yLiBUbyBwcm9kdWNlIGEgdmlldyBvZiB0aGUgZG9jdW1lbnQgdGhhdCBoYXMgZW50aXR5IHJlZmVyZW5jZQotICAgKiBub2RlcyBidXQgbm8gZW50aXR5IGV4cGFuc2lvbiwgdXNlIHRoZSA8Y29kZT53aGF0VG9TaG93PC9jb2RlPiBmbGFncwotICAgKiB0byBzaG93IHRoZSBlbnRpdHkgcmVmZXJlbmNlIG5vZGUgYW5kIHNldAotICAgKiA8Y29kZT5leHBhbmRFbnRpdHlSZWZlcmVuY2VzPC9jb2RlPiB0byBmYWxzZS48L3A+Ci0gICAqCi0gICAqIDxwPk5PVEU6IEluIFhhbGFuJ3MgdXNlIG9mIERUTSB3ZSB3aWxsIGdlbmVyYWxseSBoYXZlIGZ1bGx5IGV4cGFuZGVkCi0gICAqIGVudGl0eSByZWZlcmVuY2VzIHdoZW4gdGhlIGRvY3VtZW50IHRyZWUgd2FzIGJ1aWx0LCBhbmQgdGh1cyB0aGlzCi0gICAqIGZsYWcgd2lsbCBoYXZlIG5vIGVmZmVjdC48L3A+Ci0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiBlbnRpdHkgcmVmZXJlbmNlcyB3aWxsIGJlIGV4cGFuZGVkLiAgKi8KLSAgcHVibGljIGJvb2xlYW4gZ2V0RXhwYW5kRW50aXR5UmVmZXJlbmNlcygpOwotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBuZXh0IG5vZGUgaW4gdGhlIHNldCBhbmQgYWR2YW5jZXMgdGhlIHBvc2l0aW9uIG9mIHRoZQotICAgKiBpdGVyYXRvciBpbiB0aGUgc2V0LiBBZnRlciBhIDxjb2RlPkRUTUl0ZXJhdG9yPC9jb2RlPiBoYXMgc2V0Um9vdCBjYWxsZWQsCi0gICAqIHRoZSBmaXJzdCBjYWxsIHRvIDxjb2RlPm5leHROb2RlKCk8L2NvZGU+IHJldHVybnMgdGhhdCByb290IG9yIChpZiBpdAotICAgKiBpcyByZWplY3RlZCBieSB0aGUgZmlsdGVycykgdGhlIGZpcnN0IG5vZGUgd2l0aGluIGl0cyBzdWJ0cmVlIHdoaWNoIGlzCi0gICAqIG5vdCBmaWx0ZXJlZCBvdXQuCi0gICAqIEByZXR1cm4gVGhlIG5leHQgbm9kZSBoYW5kbGUgaW4gdGhlIHNldCBiZWluZyBpdGVyYXRlZCBvdmVyLCBvcgotICAgKiAgPGNvZGU+RFRNLk5VTEw8L2NvZGU+IGlmIHRoZXJlIGFyZSBubyBtb3JlIG1lbWJlcnMgaW4gdGhhdCBzZXQuCi0gICAqLwotICBwdWJsaWMgaW50IG5leHROb2RlKCk7Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIHByZXZpb3VzIG5vZGUgaW4gdGhlIHNldCBhbmQgbW92ZXMgdGhlIHBvc2l0aW9uIG9mIHRoZQotICAgKiA8Y29kZT5EVE1JdGVyYXRvcjwvY29kZT4gYmFja3dhcmRzIGluIHRoZSBzZXQuCi0gICAqIEByZXR1cm4gVGhlIHByZXZpb3VzIG5vZGUgaGFuZGxlIGluIHRoZSBzZXQgYmVpbmcgaXRlcmF0ZWQgb3ZlciwKLSAgICogICBvciA8Y29kZT5EVE0uTlVMTDwvY29kZT4gaWYgdGhlcmUgYXJlIG5vIG1vcmUgbWVtYmVycyBpbiB0aGF0IHNldC4KLSAgICovCi0gIHB1YmxpYyBpbnQgcHJldmlvdXNOb2RlKCk7Ci0KLSAgLyoqCi0gICAqIERldGFjaGVzIHRoZSA8Y29kZT5EVE1JdGVyYXRvcjwvY29kZT4gZnJvbSB0aGUgc2V0IHdoaWNoIGl0IGl0ZXJhdGVkCi0gICAqIG92ZXIsIHJlbGVhc2luZyBhbnkgY29tcHV0YXRpb25hbCByZXNvdXJjZXMgYW5kIHBsYWNpbmcgdGhlIGl0ZXJhdG9yCi0gICAqIGluIHRoZSBJTlZBTElEIHN0YXRlLiBBZnRlciA8Y29kZT5kZXRhY2g8L2NvZGU+IGhhcyBiZWVuIGludm9rZWQsCi0gICAqIGNhbGxzIHRvIDxjb2RlPm5leHROb2RlPC9jb2RlPiBvciA8Y29kZT5wcmV2aW91c05vZGU8L2NvZGU+IHdpbGwKLSAgICogcmFpc2UgYSBydW50aW1lIGV4Y2VwdGlvbi4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGRldGFjaCgpOwotCi0gIC8qKgotICAgKiBTcGVjaWZ5IGlmIGl0J3MgT0sgZm9yIGRldGFjaCB0byByZWxlYXNlIHRoZSBpdGVyYXRvciBmb3IgcmV1c2UuCi0gICAqCi0gICAqIEBwYXJhbSBhbGxvd1JlbGVhc2UgdHJ1ZSBpZiBpdCBpcyBPSyBmb3IgZGV0YWNoIHRvIHJlbGVhc2UgdGhpcyBpdGVyYXRvcgotICAgKiBmb3IgcG9vbGluZy4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGFsbG93RGV0YWNoVG9SZWxlYXNlKGJvb2xlYW4gYWxsb3dSZWxlYXNlKTsKLQotICAvKioKLSAgICogR2V0IHRoZSBjdXJyZW50IG5vZGUgaW4gdGhlIGl0ZXJhdG9yLiBOb3RlIHRoYXQgdGhpcyBkaWZmZXJzIGZyb20KLSAgICogdGhlIERPTSdzIE5vZGVJdGVyYXRvciwgd2hlcmUgdGhlIGN1cnJlbnQgcG9zaXRpb24gbGllcyBiZXR3ZWVuIHR3bwotICAgKiBub2RlcyAoYXMgcGFydCBvZiB0aGUgbWFpbnRhaW4tcmVsYXRpdmUtcG9zaXRpb24gc2VtYW50aWMpLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBjdXJyZW50IG5vZGUgaGFuZGxlLCBvciAtMS4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0Q3VycmVudE5vZGUoKTsKLQotICAvKioKLSAgICogVGVsbHMgaWYgdGhpcyBOb2RlU2V0RFRNIGlzICJmcmVzaCIsIGluIG90aGVyIHdvcmRzLCBpZgotICAgKiB0aGUgZmlyc3QgbmV4dE5vZGUoKSB0aGF0IGlzIGNhbGxlZCB3aWxsIHJldHVybiB0aGUKLSAgICogZmlyc3Qgbm9kZSBpbiB0aGUgc2V0LgotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGl0ZXJhdGlvbiBvZiB0aGlzIGxpc3QgaGFzIG5vdCB5ZXQgYmVndW4uCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBpc0ZyZXNoKCk7Ci0KLSAgLy89PT09PT09PT0gUmFuZG9tIEFjY2VzcyA9PT09PT09PT09Ci0KLSAgLyoqCi0gICAqIElmIHNldFNob3VsZENhY2hlTm9kZXModHJ1ZSkgaXMgY2FsbGVkLCB0aGVuIG5vZGVzIHdpbGwKLSAgICogYmUgY2FjaGVkLCBlbmFibGluZyByYW5kb20gYWNjZXNzLCBhbmQgZ2l2aW5nIHRoZSBhYmlsaXR5IHRvIGRvCi0gICAqIHNvcnRzIGFuZCB0aGUgbGlrZS4gIFRoZXkgYXJlIG5vdCBjYWNoZWQgYnkgZGVmYXVsdC4KLSAgICoKLSAgICogJVJFVklFVyUgU2hvdWxkbid0IHRoZSBvdGhlciByYW5kb20tYWNjZXNzIG1ldGhvZHMgdGhyb3cgYW4gZXhjZXB0aW9uCi0gICAqIGlmIHRoZXkncmUgY2FsbGVkIG9uIGEgRFRNSXRlcmF0b3Igd2l0aCB0aGlzIGZsYWcgc2V0IGZhbHNlPwotICAgKgotICAgKiBAcGFyYW0gYiB0cnVlIGlmIHRoZSBub2RlcyBzaG91bGQgYmUgY2FjaGVkLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0U2hvdWxkQ2FjaGVOb2Rlcyhib29sZWFuIGIpOwotCi0gIC8qKgotICAgKiBUZWxscyBpZiB0aGlzIGl0ZXJhdG9yIGNhbiBoYXZlIG5vZGVzIGFkZGVkIHRvIGl0IG9yIHNldCB2aWEKLSAgICogdGhlIDxjb2RlPnNldEl0ZW0oaW50IG5vZGUsIGludCBpbmRleCk8L2NvZGU+IG1ldGhvZC4KLSAgICoKLSAgICogQHJldHVybiBUcnVlIGlmIHRoZSBub2RlbGlzdCBjYW4gYmUgbXV0YXRlZC4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzTXV0YWJsZSgpOwotCi0gIC8qKiBHZXQgdGhlIGN1cnJlbnQgcG9zaXRpb24gd2l0aGluIHRoZSBjYWNoZWQgbGlzdCwgd2hpY2ggaXMgb25lCi0gICAqIGxlc3MgdGhhbiB0aGUgbmV4dCBuZXh0Tm9kZSgpIGNhbGwgd2lsbCByZXRyaWV2ZS4gIGkuZS4gaWYgeW91Ci0gICAqIGNhbGwgZ2V0Q3VycmVudFBvcygpIGFuZCB0aGUgcmV0dXJuIGlzIDAsIHRoZSBuZXh0IGZldGNoIHdpbGwKLSAgICogdGFrZSBwbGFjZSBhdCBpbmRleCAxLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBwb3NpdGlvbiBvZiB0aGUgaXRlcmF0aW9uLgotICAgKi8KLSAgcHVibGljIGludCBnZXRDdXJyZW50UG9zKCk7Ci0KLSAgLyoqCi0gICAqIElmIGFuIGluZGV4IGlzIHJlcXVlc3RlZCwgTm9kZVNldERUTSB3aWxsIGNhbGwgdGhpcyBtZXRob2QKLSAgICogdG8gcnVuIHRoZSBpdGVyYXRvciB0byB0aGUgaW5kZXguICBCeSBkZWZhdWx0IHRoaXMgc2V0cwotICAgKiBtX25leHQgdG8gdGhlIGluZGV4LiAgSWYgdGhlIGluZGV4IGFyZ3VtZW50IGlzIC0xLCB0aGlzCi0gICAqIHNpZ25hbHMgdGhhdCB0aGUgaXRlcmF0b3Igc2hvdWxkIGJlIHJ1biB0byB0aGUgZW5kIGFuZAotICAgKiBjb21wbGV0ZWx5IGZpbGwgdGhlIGNhY2hlLgotICAgKgotICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHJ1biB0bywgb3IgLTEgaWYgdGhlIGl0ZXJhdG9yIHNob3VsZCBiZSBydW4KLSAgICogICAgICAgICAgICAgIHRvIHRoZSBlbmQuCi0gICAqLwotICBwdWJsaWMgdm9pZCBydW5UbyhpbnQgaW5kZXgpOwotCi0gIC8qKgotICAgKiBTZXQgdGhlIGN1cnJlbnQgcG9zaXRpb24gaW4gdGhlIG5vZGUgc2V0LgotICAgKgotICAgKiBAcGFyYW0gaSBNdXN0IGJlIGEgdmFsaWQgaW5kZXguCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRDdXJyZW50UG9zKGludCBpKTsKLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgPGNvZGU+bm9kZSBoYW5kbGU8L2NvZGU+IG9mIGFuIGl0ZW0gaW4gdGhlIGNvbGxlY3Rpb24uIElmCi0gICAqIDxjb2RlPmluZGV4PC9jb2RlPiBpcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gdGhlIG51bWJlciBvZiBub2RlcyBpbgotICAgKiB0aGUgbGlzdCwgdGhpcyByZXR1cm5zIDxjb2RlPm51bGw8L2NvZGU+LgotICAgKgotICAgKiBAcGFyYW0gaW5kZXggb2YgdGhlIGl0ZW0uCi0gICAqIEByZXR1cm4gVGhlIG5vZGUgaGFuZGxlIGF0IHRoZSA8Y29kZT5pbmRleDwvY29kZT50aCBwb3NpdGlvbiBpbiB0aGUKLSAgICogICA8Y29kZT5EVE1JdGVyYXRvcjwvY29kZT4sIG9yIDxjb2RlPi0xPC9jb2RlPiBpZiB0aGF0IGlzIG5vdCBhIHZhbGlkCi0gICAqICAgaW5kZXguCi0gICAqLwotICBwdWJsaWMgaW50IGl0ZW0oaW50IGluZGV4KTsKLQotICAvKioKLSAgICogU2V0cyB0aGUgbm9kZSBhdCB0aGUgc3BlY2lmaWVkIGluZGV4IG9mIHRoaXMgdmVjdG9yIHRvIGJlIHRoZQotICAgKiBzcGVjaWZpZWQgbm9kZS4gVGhlIHByZXZpb3VzIGNvbXBvbmVudCBhdCB0aGF0IHBvc2l0aW9uIGlzIGRpc2NhcmRlZC4KLSAgICoKLSAgICogPHA+VGhlIGluZGV4IG11c3QgYmUgYSB2YWx1ZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gMCBhbmQgbGVzcwotICAgKiB0aGFuIHRoZSBjdXJyZW50IHNpemUgb2YgdGhlIHZlY3Rvci4KLSAgICogVGhlIGl0ZXJhdG9yIG11c3QgYmUgaW4gY2FjaGVkIG1vZGUuPC9wPgotICAgKgotICAgKiA8cD5NZWFudCB0byBiZSB1c2VkIGZvciBzb3J0ZWQgaXRlcmF0b3JzLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIG5vZGUgTm9kZSB0byBzZXQKLSAgICogQHBhcmFtIGluZGV4IEluZGV4IG9mIHdoZXJlIHRvIHNldCB0aGUgbm9kZQotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0SXRlbShpbnQgbm9kZSwgaW50IGluZGV4KTsKLQotICAvKioKLSAgICogVGhlIG51bWJlciBvZiBub2RlcyBpbiB0aGUgbGlzdC4gVGhlIHJhbmdlIG9mIHZhbGlkIGNoaWxkIG5vZGUgaW5kaWNlcwotICAgKiBpcyAwIHRvIDxjb2RlPmxlbmd0aC0xPC9jb2RlPiBpbmNsdXNpdmUuIE5vdGUgdGhhdCB0aGlzIHJlcXVpcmVzIHJ1bm5pbmcKLSAgICogdGhlIGl0ZXJhdG9yIHRvIGNvbXBsZXRpb24sIGFuZCBwcmVzdW1hYmx5IGZpbGxpbmcgdGhlIGNhY2hlLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBudW1iZXIgb2Ygbm9kZXMgaW4gdGhlIGxpc3QuCi0gICAqLwotICBwdWJsaWMgaW50IGdldExlbmd0aCgpOwotCi0gIC8vPT09PT09PT09PT0gQ2xvbmluZyBvcGVyYXRpb25zLiA9PT09PT09PT09PT0KLQotICAvKioKLSAgICogR2V0IGEgY2xvbmVkIEl0ZXJhdG9yIHRoYXQgaXMgcmVzZXQgdG8gdGhlIHN0YXJ0IG9mIHRoZSBpdGVyYXRpb24uCi0gICAqCi0gICAqIEByZXR1cm4gQSBjbG9uZSBvZiB0aGlzIGl0ZXJhdGlvbiB0aGF0IGhhcyBiZWVuIHJlc2V0LgotICAgKgotICAgKiBAdGhyb3dzIENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgRFRNSXRlcmF0b3IgY2xvbmVXaXRoUmVzZXQoKSB0aHJvd3MgQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb247Ci0KLSAgLyoqCi0gICAqIEdldCBhIGNsb25lIG9mIHRoaXMgaXRlcmF0b3IsIGJ1dCBkb24ndCByZXNldCB0aGUgaXRlcmF0aW9uIGluIHRoZQotICAgKiBwcm9jZXNzLCBzbyB0aGF0IGl0IG1heSBiZSB1c2VkIGZyb20gdGhlIGN1cnJlbnQgcG9zaXRpb24uCi0gICAqCi0gICAqIEByZXR1cm4gQSBjbG9uZSBvZiB0aGlzIG9iamVjdC4KLSAgICoKLSAgICogQHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIE9iamVjdCBjbG9uZSgpIHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbjsKLQotICAvKioKLSAgICogUmV0dXJucyB0cnVlIGlmIGFsbCB0aGUgbm9kZXMgaW4gdGhlIGl0ZXJhdGlvbiB3ZWxsIGJlIHJldHVybmVkIGluIGRvY3VtZW50Ci0gICAqIG9yZGVyLgotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYgYWxsIHRoZSBub2RlcyBpbiB0aGUgaXRlcmF0aW9uIHdlbGwgYmUgcmV0dXJuZWQgaW4gZG9jdW1lbnQKLSAgICogb3JkZXIuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBpc0RvY09yZGVyZWQoKTsKLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgYXhpcyBiZWluZyBpdGVyYXRlZCwgaWYgaXQgaXMga25vd24uCi0gICAqCi0gICAqIEByZXR1cm4gQXhpcy5DSElMRCwgZXRjLiwgb3IgLTEgaWYgdGhlIGF4aXMgaXMgbm90IGtub3duIG9yIGlzIG9mIG11bHRpcGxlCi0gICAqIHR5cGVzLgotICAgKi8KLSAgcHVibGljIGludCBnZXRBeGlzKCk7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1NYW5hZ2VyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNTWFuYWdlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkNjI5YjlmLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1NYW5hZ2VyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0NDEgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRFRNTWFuYWdlci5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE1IDA4OjE0OjU0IHN1cmVzaF9lbWFpbGlkIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG07Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnJlcy5YTUxFcnJvclJlc291cmNlczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnJlcy5YTUxNZXNzYWdlczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLlByZWZpeFJlc29sdmVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuWE1MU3RyaW5nRmFjdG9yeTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwudXRpbHMuT2JqZWN0RmFjdG9yeTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwudXRpbHMuU2VjdXJpdHlTdXBwb3J0OwotCi0vKioKLSAqIEEgRFRNTWFuYWdlciBpbnN0YW5jZSBjYW4gYmUgdXNlZCB0byBjcmVhdGUgRFRNIGFuZAotICogRFRNSXRlcmF0b3Igb2JqZWN0cywgYW5kIG1hbmFnZSB0aGUgRFRNIG9iamVjdHMgaW4gdGhlIHN5c3RlbS4KLSAqCi0gKiA8cD5UaGUgc3lzdGVtIHByb3BlcnR5IHRoYXQgZGV0ZXJtaW5lcyB3aGljaCBGYWN0b3J5IGltcGxlbWVudGF0aW9uCi0gKiB0byBjcmVhdGUgaXMgbmFtZWQgImNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuRFRNRmFjdG9yeSIuIFRoaXMKLSAqIHByb3BlcnR5IG5hbWVzIGEgY29uY3JldGUgc3ViY2xhc3Mgb2YgdGhlIERUTUZhY3RvcnkgYWJzdHJhY3QKLSAqICBjbGFzcy4gSWYgdGhlIHByb3BlcnR5IGlzIG5vdCBkZWZpbmVkLCBhIHBsYXRmb3JtIGRlZmF1bHQgaXMgYmUgdXNlZC48L3A+Ci0gKgotICogPHA+QW4gaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcyA8ZW1waD5tdXN0PC9lbXBoPiBiZSBzYWZlIHRvIHVzZSBhY3Jvc3MKLSAqIHRocmVhZCBpbnN0YW5jZXMuICBJdCBpcyBleHBlY3RlZCB0aGF0IGEgY2xpZW50IHdpbGwgY3JlYXRlIGEgc2luZ2xlIGluc3RhbmNlCi0gKiBvZiBhIERUTU1hbmFnZXIgdG8gdXNlIGFjcm9zcyBtdWx0aXBsZSB0aHJlYWRzLiAgVGhpcyB3aWxsIGFsbG93IHNoYXJpbmcKLSAqIG9mIERUTXMgYWNyb3NzIG11bHRpcGxlIHByb2Nlc3Nlcy48L3A+Ci0gKgotICogPHA+Tm90ZTogdGhpcyBjbGFzcyBpcyBpbmNvbXBsZXRlIHJpZ2h0IG5vdy4gIEl0IHdpbGwgYmUgcHJldHR5IG11Y2gKLSAqIG1vZGVsZWQgYWZ0ZXIgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckZhY3RvcnkgaW4gdGVybXMgb2YgaXRzCi0gKiBmYWN0b3J5IHN1cHBvcnQuPC9wPgotICoKLSAqIDxwPlN0YXRlOiBJbiBwcm9ncmVzcyEhPC9wPgotICovCi1wdWJsaWMgYWJzdHJhY3QgY2xhc3MgRFRNTWFuYWdlcgotewotCi0gIC8qKgotICAgKiBGYWN0b3J5IGZvciBjcmVhdGluZyBYTUxTdHJpbmcgb2JqZWN0cy4KLSAgICogICVUQkQlIE1ha2UgdGhpcyBzZXQgYnkgdGhlIGNhbGxlci4KLSAgICovCi0gIHByb3RlY3RlZCBYTUxTdHJpbmdGYWN0b3J5IG1feHNmID0gbnVsbDsKLQotICBwcml2YXRlIGJvb2xlYW4gX3VzZVNlcnZpY2VzTWVjaGFuaXNtOwotICAvKioKLSAgICogRGVmYXVsdCBjb25zdHJ1Y3RvciBpcyBwcm90ZWN0ZWQgb24gcHVycG9zZS4KLSAgICovCi0gIHByb3RlY3RlZCBEVE1NYW5hZ2VyKCl7fQotCi0gIC8qKgotICAgKiBHZXQgdGhlIFhNTFN0cmluZ0ZhY3RvcnkgdXNlZCBmb3IgdGhlIERUTXMuCi0gICAqCi0gICAqCi0gICAqIEByZXR1cm4gYSB2YWxpZCBYTUxTdHJpbmdGYWN0b3J5IG9iamVjdCwgb3IgbnVsbCBpZiBpdCBoYXNuJ3QgYmVlbiBzZXQgeWV0LgotICAgKi8KLSAgcHVibGljIFhNTFN0cmluZ0ZhY3RvcnkgZ2V0WE1MU3RyaW5nRmFjdG9yeSgpCi0gIHsKLSAgICByZXR1cm4gbV94c2Y7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBYTUxTdHJpbmdGYWN0b3J5IHVzZWQgZm9yIHRoZSBEVE1zLgotICAgKgotICAgKgotICAgKiBAcGFyYW0geHNmIGEgdmFsaWQgWE1MU3RyaW5nRmFjdG9yeSBvYmplY3QsIHNob3VsZCBub3QgYmUgbnVsbC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFhNTFN0cmluZ0ZhY3RvcnkoWE1MU3RyaW5nRmFjdG9yeSB4c2YpCi0gIHsKLSAgICBtX3hzZiA9IHhzZjsKLSAgfQotCi0gIC8qKgotICAgKiBPYnRhaW4gYSBuZXcgaW5zdGFuY2Ugb2YgYSA8Y29kZT5EVE1NYW5hZ2VyPC9jb2RlPi4KLSAgICogVGhpcyBzdGF0aWMgbWV0aG9kIGNyZWF0ZXMgYSBuZXcgZmFjdG9yeSBpbnN0YW5jZQotICAgKiB1c2luZyB0aGUgZGVmYXVsdCA8Y29kZT5EVE1NYW5hZ2VyPC9jb2RlPiBpbXBsZW1lbnRhdGlvbiwgd2hpY2ggaXMKLSAgICogPGNvZGU+Y29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0ucmVmLkRUTU1hbmFnZXJEZWZhdWx0PC9jb2RlPi4KLSAgICogPC9saT4KLSAgICogPC91bD4KLSAgICoKLSAgICogT25jZSBhbiBhcHBsaWNhdGlvbiBoYXMgb2J0YWluZWQgYSByZWZlcmVuY2UgdG8gYSA8Y29kZT4KLSAgICogRFRNTWFuYWdlcjwvY29kZT4gaXQgY2FuIHVzZSB0aGUgZmFjdG9yeSB0byBjb25maWd1cmUKLSAgICogYW5kIG9idGFpbiBwYXJzZXIgaW5zdGFuY2VzLgotICAgKgotICAgKiBAcmV0dXJuIG5ldyBEVE1NYW5hZ2VyIGluc3RhbmNlLCBuZXZlciBudWxsLgotICAgKgotICAgKiBAdGhyb3dzIERUTUNvbmZpZ3VyYXRpb25FeGNlcHRpb24KLSAgICogaWYgdGhlIGltcGxlbWVudGF0aW9uIGlzIG5vdCBhdmFpbGFibGUgb3IgY2Fubm90IGJlIGluc3RhbnRpYXRlZC4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgRFRNTWFuYWdlciBuZXdJbnN0YW5jZShYTUxTdHJpbmdGYWN0b3J5IHhzZikKLSAgICAgICAgICAgdGhyb3dzIERUTUNvbmZpZ3VyYXRpb25FeGNlcHRpb24KLSAgewotICAgICAgZmluYWwgRFRNTWFuYWdlciBmYWN0b3J5SW1wbCA9IG5ldyBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5yZWYuRFRNTWFuYWdlckRlZmF1bHQoKTsKLSAgICAgIGZhY3RvcnlJbXBsLnNldFhNTFN0cmluZ0ZhY3RvcnkoeHNmKTsKLQotICAgICAgcmV0dXJuIGZhY3RvcnlJbXBsOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBhbiBpbnN0YW5jZSBvZiBhIERUTSwgbG9hZGVkIHdpdGggdGhlIGNvbnRlbnQgZnJvbSB0aGUKLSAgICogc3BlY2lmaWVkIHNvdXJjZS4gIElmIHRoZSB1bmlxdWUgZmxhZyBpcyB0cnVlLCBhIG5ldyBpbnN0YW5jZSB3aWxsCi0gICAqIGFsd2F5cyBiZSByZXR1cm5lZC4gIE90aGVyd2lzZSBpdCBpcyB1cCB0byB0aGUgRFRNTWFuYWdlciB0byByZXR1cm4gYQotICAgKiBuZXcgaW5zdGFuY2Ugb3IgYW4gaW5zdGFuY2UgdGhhdCBpdCBhbHJlYWR5IGNyZWF0ZWQgYW5kIG1heSBiZSBiZWluZyB1c2VkCi0gICAqIGJ5IHNvbWVvbmUgZWxzZS4KLSAgICoKLSAgICogKE1vcmUgcGFyYW1ldGVycyBtYXkgZXZlbnR1YWxseSBuZWVkIHRvIGJlIGFkZGVkIGZvciBlcnJvciBoYW5kbGluZwotICAgKiBhbmQgZW50aXR5IHJlc29sdXRpb24sIGFuZCB0byBiZXR0ZXIgY29udHJvbCBzZWxlY3Rpb24gb2YgaW1wbGVtZW50YXRpb25zLikKLSAgICoKLSAgICogQHBhcmFtIHNvdXJjZSB0aGUgc3BlY2lmaWNhdGlvbiBvZiB0aGUgc291cmNlIG9iamVjdCwgd2hpY2ggbWF5IGJlIG51bGwsCi0gICAqICAgICAgICAgICAgICAgaW4gd2hpY2ggY2FzZSBpdCBpcyBhc3N1bWVkIHRoYXQgbm9kZSBjb25zdHJ1Y3Rpb24gd2lsbCB0YWtlCi0gICAqICAgICAgICAgICAgICAgYnkgc29tZSBvdGhlciBtZWFucy4KLSAgICogQHBhcmFtIHVuaXF1ZSB0cnVlIGlmIHRoZSByZXR1cm5lZCBEVE0gbXVzdCBiZSB1bmlxdWUsIHByb2JhYmx5IGJlY2F1c2UgaXQKLSAgICogaXMgZ29pbmcgdG8gYmUgbXV0YXRlZC4KLSAgICogQHBhcmFtIHdoaXRlU3BhY2VGaWx0ZXIgRW5hYmxlcyBmaWx0ZXJpbmcgb2Ygd2hpdGVzcGFjZSBub2RlcywgYW5kIG1heQotICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBiZSBudWxsLgotICAgKiBAcGFyYW0gaW5jcmVtZW50YWwgdHJ1ZSBpZiB0aGUgRFRNIHNob3VsZCBiZSBidWlsdCBpbmNyZW1lbnRhbGx5LCBpZgotICAgKiAgICAgICAgICAgICAgICAgICAgcG9zc2libGUuCi0gICAqIEBwYXJhbSBkb0luZGV4aW5nIHRydWUgaWYgdGhlIGNhbGxlciBjb25zaWRlcnMgaXQgd29ydGggaXQgdG8gdXNlCi0gICAqICAgICAgICAgICAgICAgICAgIGluZGV4aW5nIHNjaGVtZXMuCi0gICAqCi0gICAqIEByZXR1cm4gYSBub24tbnVsbCBEVE0gcmVmZXJlbmNlLgotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IERUTSBnZXREVE0oamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2Ugc291cmNlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIHVuaXF1ZSwgRFRNV1NGaWx0ZXIgd2hpdGVTcGFjZUZpbHRlciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBpbmNyZW1lbnRhbCwgYm9vbGVhbiBkb0luZGV4aW5nKTsKLQotICAvKioKLSAgICogR2V0IHRoZSBpbnN0YW5jZSBvZiBEVE0gdGhhdCAib3ducyIgYSBub2RlIGhhbmRsZS4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgdGhlIG5vZGVIYW5kbGUuCi0gICAqCi0gICAqIEByZXR1cm4gYSBub24tbnVsbCBEVE0gcmVmZXJlbmNlLgotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IERUTSBnZXREVE0oaW50IG5vZGVIYW5kbGUpOwotCi0gIC8qKgotICAgKiBHaXZlbiBhIFczQyBET00gbm9kZSwgdHJ5IGFuZCByZXR1cm4gYSBEVE0gaGFuZGxlLgotICAgKiBOb3RlOiBjYWxsaW5nIHRoaXMgbWF5IGJlIG5vbi1vcHRpbWFsLgotICAgKgotICAgKiBAcGFyYW0gbm9kZSBOb24tbnVsbCByZWZlcmVuY2UgdG8gYSBET00gbm9kZS4KLSAgICoKLSAgICogQHJldHVybiBhIHZhbGlkIERUTSBoYW5kbGUuCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgaW50IGdldERUTUhhbmRsZUZyb21Ob2RlKG9yZy53M2MuZG9tLk5vZGUgbm9kZSk7Ci0KLSAgLyoqCi0gICAqIENyZWF0ZXMgYSBEVE0gcmVwcmVzZW50aW5nIGFuIGVtcHR5IDxjb2RlPkRvY3VtZW50RnJhZ21lbnQ8L2NvZGU+IG9iamVjdC4KLSAgICogQHJldHVybiBhIG5vbi1udWxsIERUTSByZWZlcmVuY2UuCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgRFRNIGNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTsKLQotICAvKioKLSAgICogUmVsZWFzZSBhIERUTSBlaXRoZXIgdG8gYSBscnUgcG9vbCwgb3IgY29tcGxldGVseSByZW1vdmUgcmVmZXJlbmNlLgotICAgKiBEVE1zIHdpdGhvdXQgc3lzdGVtIElEcyBhcmUgYWx3YXlzIGhhcmQgZGVsZXRlZC4KLSAgICogU3RhdGU6IGV4cGVyaW1lbnRhbC4KLSAgICoKLSAgICogQHBhcmFtIGR0bSBUaGUgRFRNIHRvIGJlIHJlbGVhc2VkLgotICAgKiBAcGFyYW0gc2hvdWxkSGFyZERlbGV0ZSBUcnVlIGlmIHRoZSBEVE0gc2hvdWxkIGJlIHJlbW92ZWQgbm8gbWF0dGVyIHdoYXQuCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgRFRNIHdhcyByZW1vdmVkLCBmYWxzZSBpZiBpdCB3YXMgcHV0IGJhY2sgaW4gYSBscnUgcG9vbC4KLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIHJlbGVhc2UoRFRNIGR0bSwgYm9vbGVhbiBzaG91bGRIYXJkRGVsZXRlKTsKLQotICAvKioKLSAgICogQ3JlYXRlIGEgbmV3IDxjb2RlPkRUTUl0ZXJhdG9yPC9jb2RlPiBiYXNlZCBvbiBhbiBYUGF0aAotICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aCNOVC1Mb2NhdGlvblBhdGg+TG9jYXRpb25QYXRoPC9hPiBvcgotICAgKiBhIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hwYXRoI05ULVVuaW9uRXhwciI+VW5pb25FeHByPC9hPi4KLSAgICoKLSAgICogQHBhcmFtIHhwYXRoQ29tcGlsZXIgPz8/IFNvbWVob3cgd2UgbmVlZCB0byBwYXNzIGluIGEgc3VicGFydCBvZiB0aGUKLSAgICogZXhwcmVzc2lvbi4gIEkgaGF0ZSB0byBkbyB0aGlzIHdpdGggc3RyaW5ncywgc2luY2UgdGhlIGxhcmdlciBleHByZXNzaW9uCi0gICAqIGhhcyBhbHJlYWR5IGJlZW4gcGFyc2VkLgotICAgKgotICAgKiBAcGFyYW0gcG9zIFRoZSBwb3NpdGlvbiBpbiB0aGUgZXhwcmVzc2lvbi4KLSAgICogQHJldHVybiBUaGUgbmV3bHkgY3JlYXRlZCA8Y29kZT5EVE1JdGVyYXRvcjwvY29kZT4uCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgRFRNSXRlcmF0b3IgY3JlYXRlRFRNSXRlcmF0b3IoT2JqZWN0IHhwYXRoQ29tcGlsZXIsCi0gICAgICAgICAgaW50IHBvcyk7Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIG5ldyA8Y29kZT5EVE1JdGVyYXRvcjwvY29kZT4gYmFzZWQgb24gYW4gWFBhdGgKLSAgICogPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGgjTlQtTG9jYXRpb25QYXRoPkxvY2F0aW9uUGF0aDwvYT4gb3IKLSAgICogYSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aCNOVC1VbmlvbkV4cHIiPlVuaW9uRXhwcjwvYT4uCi0gICAqCi0gICAqIEBwYXJhbSB4cGF0aFN0cmluZyBNdXN0IGJlIGEgdmFsaWQgc3RyaW5nIGV4cHJlc3NpbmcgYQotICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aCNOVC1Mb2NhdGlvblBhdGg+TG9jYXRpb25QYXRoPC9hPiBvcgotICAgKiBhIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hwYXRoI05ULVVuaW9uRXhwciI+VW5pb25FeHByPC9hPi4KLSAgICoKLSAgICogQHBhcmFtIHByZXNvbHZlciBBbiBvYmplY3QgdGhhdCBjYW4gcmVzb2x2ZSBwcmVmaXhlcyB0byBuYW1lc3BhY2UgVVJMcy4KLSAgICoKLSAgICogQHJldHVybiBUaGUgbmV3bHkgY3JlYXRlZCA8Y29kZT5EVE1JdGVyYXRvcjwvY29kZT4uCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgRFRNSXRlcmF0b3IgY3JlYXRlRFRNSXRlcmF0b3IoU3RyaW5nIHhwYXRoU3RyaW5nLAotICAgICAgICAgIFByZWZpeFJlc29sdmVyIHByZXNvbHZlcik7Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIG5ldyA8Y29kZT5EVE1JdGVyYXRvcjwvY29kZT4gYmFzZWQgb25seSBvbiBhIHdoYXRUb1Nob3cKLSAgICogYW5kIGEgRFRNRmlsdGVyLiAgVGhlIHRyYXZlcnNhbCBzZW1hbnRpY3MgYXJlIGRlZmluZWQgYXMgdGhlCi0gICAqIGRlc2NlbmRhbnQgYWNjZXNzLgotICAgKiA8cD4KLSAgICogTm90ZSB0aGF0IERUTUl0ZXJhdG9ycyBtYXkgbm90IGJlIGFuIGV4YWN0IG1hdGNoIHRvIERPTQotICAgKiBOb2RlSXRlcmF0b3JzLiBUaGV5IGFyZSBpbml0aWFsaXplZCBhbmQgdXNlZCBpbiBtdWNoIHRoZSBzYW1lIHdheQotICAgKiBhcyBhIE5vZGVJdGVyYXRvciwgYnV0IHRoZWlyIHJlc3BvbnNlIHRvIGRvY3VtZW50IG11dGF0aW9uIGlzIG5vdAotICAgKiBjdXJyZW50bHkgZGVmaW5lZC4KLSAgICoKLSAgICogQHBhcmFtIHdoYXRUb1Nob3cgVGhpcyBmbGFnIHNwZWNpZmllcyB3aGljaCBub2RlIHR5cGVzIG1heSBhcHBlYXIgaW4KLSAgICogICB0aGUgbG9naWNhbCB2aWV3IG9mIHRoZSB0cmVlIHByZXNlbnRlZCBieSB0aGUgaXRlcmF0b3IuIFNlZSB0aGUKLSAgICogICBkZXNjcmlwdGlvbiBvZiA8Y29kZT5Ob2RlRmlsdGVyPC9jb2RlPiBmb3IgdGhlIHNldCBvZiBwb3NzaWJsZQotICAgKiAgIDxjb2RlPlNIT1dfPC9jb2RlPiB2YWx1ZXMuVGhlc2UgZmxhZ3MgY2FuIGJlIGNvbWJpbmVkIHVzaW5nCi0gICAqICAgPGNvZGU+T1I8L2NvZGU+LgotICAgKiBAcGFyYW0gZmlsdGVyIFRoZSA8Y29kZT5Ob2RlRmlsdGVyPC9jb2RlPiB0byBiZSB1c2VkIHdpdGggdGhpcwotICAgKiAgIDxjb2RlPkRUTUZpbHRlcjwvY29kZT4sIG9yIDxjb2RlPm51bGw8L2NvZGU+IHRvIGluZGljYXRlIG5vIGZpbHRlci4KLSAgICogQHBhcmFtIGVudGl0eVJlZmVyZW5jZUV4cGFuc2lvbiBUaGUgdmFsdWUgb2YgdGhpcyBmbGFnIGRldGVybWluZXMKLSAgICogICB3aGV0aGVyIGVudGl0eSByZWZlcmVuY2Ugbm9kZXMgYXJlIGV4cGFuZGVkLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBuZXdseSBjcmVhdGVkIDxjb2RlPkRUTUl0ZXJhdG9yPC9jb2RlPi4KLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBEVE1JdGVyYXRvciBjcmVhdGVEVE1JdGVyYXRvcihpbnQgd2hhdFRvU2hvdywKLSAgICAgICAgICBEVE1GaWx0ZXIgZmlsdGVyLCBib29sZWFuIGVudGl0eVJlZmVyZW5jZUV4cGFuc2lvbik7Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIG5ldyA8Y29kZT5EVE1JdGVyYXRvcjwvY29kZT4gdGhhdCBob2xkcyBleGFjdGx5IG9uZSBub2RlLgotICAgKgotICAgKiBAcGFyYW0gbm9kZSBUaGUgbm9kZSBoYW5kbGUgdGhhdCB0aGUgRFRNSXRlcmF0b3Igd2lsbCBpdGVyYXRlIHRvLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBuZXdseSBjcmVhdGVkIDxjb2RlPkRUTUl0ZXJhdG9yPC9jb2RlPi4KLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBEVE1JdGVyYXRvciBjcmVhdGVEVE1JdGVyYXRvcihpbnQgbm9kZSk7Ci0KLSAgLyogRmxhZyBpbmRpY2F0aW5nIHdoZXRoZXIgYW4gaW5jcmVtZW50YWwgdHJhbnNmb3JtIGlzIGRlc2lyZWQgKi8KLSAgcHVibGljIGJvb2xlYW4gbV9pbmNyZW1lbnRhbCA9IGZhbHNlOwotCi0gIC8qCi0gICAqIEZsYWcgc2V0IGJ5IEZFQVRVUkVfU09VUkNFX0xPQ0FUSU9OLgotICAgKiBUaGlzIGZlYXR1cmUgc3BlY2lmaWVzIHdoZXRoZXIgdGhlIHRyYW5zZm9ybWF0aW9uIHBoYXNlIHNob3VsZAotICAgKiBrZWVwIHRyYWNrIG9mIGxpbmUgYW5kIGNvbHVtbiBudW1iZXJzIGZvciB0aGUgaW5wdXQgc291cmNlCi0gICAqIGRvY3VtZW50LgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gbV9zb3VyY2VfbG9jYXRpb24gPSBmYWxzZTsKLQotICAvKioKLSAgICogR2V0IGEgZmxhZyBpbmRpY2F0aW5nIHdoZXRoZXIgYW4gaW5jcmVtZW50YWwgdHJhbnNmb3JtIGlzIGRlc2lyZWQKLSAgICogQHJldHVybiBpbmNyZW1lbnRhbCBib29sZWFuLgotICAgKgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZ2V0SW5jcmVtZW50YWwoKQotICB7Ci0gICAgcmV0dXJuIG1faW5jcmVtZW50YWw7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IGEgZmxhZyBpbmRpY2F0aW5nIHdoZXRoZXIgYW4gaW5jcmVtZW50YWwgdHJhbnNmb3JtIGlzIGRlc2lyZWQKLSAgICogVGhpcyBmbGFnIHNob3VsZCBoYXZlIHRoZSBzYW1lIHZhbHVlIGFzIHRoZSBGRUFUVVJFX0lOQ1JFTUVOVEFMIGZlYXR1cmUKLSAgICogd2hpY2ggaXMgc2V0IGJ5IHRoZSBUcmFuc2Zvcm1lckZhY3Rvcnkuc2V0QXR0cmlidXQoKSBtZXRob2QgYmVmb3JlIGEKLSAgICogRFRNTWFuYWdlciBpcyBjcmVhdGVkCi0gICAqIEBwYXJhbSBpbmNyZW1lbnRhbCBib29sZWFuIHRvIHVzZSB0byBzZXQgbV9pbmNyZW1lbnRhbC4KLSAgICoKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldEluY3JlbWVudGFsKGJvb2xlYW4gaW5jcmVtZW50YWwpCi0gIHsKLSAgICBtX2luY3JlbWVudGFsID0gaW5jcmVtZW50YWw7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IGEgZmxhZyBpbmRpY2F0aW5nIHdoZXRoZXIgdGhlIHRyYW5zZm9ybWF0aW9uIHBoYXNlIHNob3VsZAotICAgKiBrZWVwIHRyYWNrIG9mIGxpbmUgYW5kIGNvbHVtbiBudW1iZXJzIGZvciB0aGUgaW5wdXQgc291cmNlCi0gICAqIGRvY3VtZW50LgotICAgKiBAcmV0dXJuIHNvdXJjZSBsb2NhdGlvbiBib29sZWFuCi0gICAqCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBnZXRTb3VyY2VfbG9jYXRpb24oKQotICB7Ci0gICAgcmV0dXJuIG1fc291cmNlX2xvY2F0aW9uOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCBhIGZsYWcgaW5kaWNhdGluZyB3aGV0aGVyIHRoZSB0cmFuc2Zvcm1hdGlvbiBwaGFzZSBzaG91bGQKLSAgICoga2VlcCB0cmFjayBvZiBsaW5lIGFuZCBjb2x1bW4gbnVtYmVycyBmb3IgdGhlIGlucHV0IHNvdXJjZQotICAgKiBkb2N1bWVudC4KLSAgICogVGhpcyBmbGFnIHNob3VsZCBoYXZlIHRoZSBzYW1lIHZhbHVlIGFzIHRoZSBGRUFUVVJFX1NPVVJDRV9MT0NBVElPTiBmZWF0dXJlCi0gICAqIHdoaWNoIGlzIHNldCBieSB0aGUgVHJhbnNmb3JtZXJGYWN0b3J5LnNldEF0dHJpYnV0KCkgbWV0aG9kIGJlZm9yZSBhCi0gICAqIERUTU1hbmFnZXIgaXMgY3JlYXRlZAotICAgKiBAcGFyYW0gc291cmNlTG9jYXRpb24gYm9vbGVhbiB0byB1c2UgdG8gc2V0IG1fc291cmNlX2xvY2F0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRTb3VyY2VfbG9jYXRpb24oYm9vbGVhbiBzb3VyY2VMb2NhdGlvbil7Ci0gICAgbV9zb3VyY2VfbG9jYXRpb24gPSBzb3VyY2VMb2NhdGlvbjsKLSAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSBzdGF0ZSBvZiB0aGUgc2VydmljZXMgbWVjaGFuaXNtIGZlYXR1cmUuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gdXNlU2VydmljZXNNZWNobmlzbSgpIHsKLSAgICAgICAgcmV0dXJuIF91c2VTZXJ2aWNlc01lY2hhbmlzbTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIHN0YXRlIG9mIHRoZSBzZXJ2aWNlcyBtZWNoYW5pc20gZmVhdHVyZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRTZXJ2aWNlc01lY2huaXNtKGJvb2xlYW4gZmxhZykgewotICAgICAgICBfdXNlU2VydmljZXNNZWNoYW5pc20gPSBmbGFnOwotICAgIH0KLQotICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLSBwcml2YXRlIG1ldGhvZHMgLS0tLS0tLS0tLS0tLS0tLS0tLS0KLQotICAgLyoqCi0gICAqIFRlbXAgZGVidWcgY29kZSAtIHRoaXMgd2lsbCBiZSByZW1vdmVkIGFmdGVyIHdlIHRlc3QgZXZlcnl0aGluZwotICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBkZWJ1ZzsKLQotICBzdGF0aWMKLSAgewotICAgIHRyeQotICAgIHsKLSAgICAgIGRlYnVnID0gU2VjdXJpdHlTdXBwb3J0LmdldFN5c3RlbVByb3BlcnR5KCJkdG0uZGVidWciKSAhPSBudWxsOwotICAgIH0KLSAgICBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gZXgpe30KLSAgfQotCi0gIC8qKiBUaGlzIHZhbHVlLCBzZXQgYXQgY29tcGlsZSB0aW1lLCBjb250cm9scyBob3cgbWFueSBiaXRzIG9mIHRoZQotICAgKiBEVE0gbm9kZSBpZGVudGlmaWVyIG51bWJlcnMgYXJlIHVzZWQgdG8gaWRlbnRpZnkgYSBub2RlIHdpdGhpbiBhCi0gICAqIGRvY3VtZW50LCBhbmQgdGh1cyBzZXRzIHRoZSBtYXhpbXVtIG51bWJlciBvZiBub2RlcyBwZXIKLSAgICogZG9jdW1lbnQuIFRoZSByZW1haW5pbmcgYml0cyBhcmUgdXNlZCB0byBpZGVudGlmeSB0aGUgRFRNCi0gICAqIGRvY3VtZW50IHdoaWNoIGNvbnRhaW5zIHRoaXMgbm9kZS4KLSAgICoKLSAgICogSWYgeW91IGNoYW5nZSBJREVOVF9EVE1fTk9ERV9CSVRTLCBiZSBzdXJlIHRvIHJlYnVpbGQgX0FMTF8gdGhlCi0gICAqIGZpbGVzIHdoaWNoIHVzZSBpdC4uLiBpbmNsdWRpbmcgdGhlIElES2V5IHRlc3RjYXNlcy4KLSAgICoKLSAgICogKEZ1bmNHZW5lcmF0ZUtleSBjdXJyZW50bHkgdXNlcyB0aGUgbm9kZSBpZGVudGlmaWVyIGRpcmVjdGx5IGFuZAotICAgKiB0aHVzIGlzIGFmZmVjdGVkIHdoZW4gdGhpcyBjaGFuZ2VzLiBUaGUgSURLRVkgcmVzdWx0cyB3aWxsIHN0aWxsIGJlCi0gICAqIF9jb3JyZWN0XyAocHJlc3VtaW5nIG5vIG90aGVyIGJyZWFrYWdlKSwgYnV0IHNpbXBsZSBlcXVhbGl0eQotICAgKiBjb21wYXJpc29uIGFnYWluc3QgdGhlIHByZXZpb3VzICJnb2xkZW4iIGZpbGVzIHdpbGwgcHJvYmFibHkKLSAgICogY29tcGxhaW4uKQotICAgKiAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJREVOVF9EVE1fTk9ERV9CSVRTID0gMTY7Ci0KLQotICAvKiogV2hlbiB0aGlzIGJpdG1hc2sgaXMgQU5EZWQgd2l0aCBhIERUTSBub2RlIGhhbmRsZSBudW1iZXIsIHRoZSByZXN1bHQKLSAgICogaXMgdGhlIGxvdyBiaXRzIG9mIHRoZSBub2RlJ3MgaW5kZXggbnVtYmVyIHdpdGhpbiB0aGF0IERUTS4gVG8gb2J0YWluCi0gICAqIHRoZSBoaWdoIGJpdHMsIGFkZCB0aGUgRFRNIElEIHBvcnRpb24ncyBvZmZzZXQgYXMgYXNzaWduZWQgaW4gdGhlIERUTQotICAgKiBNYW5hZ2VyLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSURFTlRfTk9ERV9ERUZBVUxUID0gKDE8PElERU5UX0RUTV9OT0RFX0JJVFMpLTE7Ci0KLQotICAvKiogV2hlbiB0aGlzIGJpdG1hc2sgaXMgQU5EZWQgd2l0aCBhIERUTSBub2RlIGhhbmRsZSBudW1iZXIsIHRoZSByZXN1bHQKLSAgICogaXMgdGhlIERUTSdzIGRvY3VtZW50IGlkZW50aXR5IG51bWJlci4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElERU5UX0RUTV9ERUZBVUxUID0gfklERU5UX05PREVfREVGQVVMVDsKLQotICAvKiogVGhpcyBpcyB0aGUgbWF4aW11bSBudW1iZXIgb2YgRFRNcyBhdmFpbGFibGUuICBUaGUgaGlnaGVzdCBEVE0gaXMKLSAgICAqIG9uZSBsZXNzIHRoYW4gdGhpcy4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElERU5UX01BWF9EVE1TID0gKElERU5UX0RUTV9ERUZBVUxUID4+PiBJREVOVF9EVE1fTk9ERV9CSVRTKSArIDE7Ci0KLQotICAvKioKLSAgICogJVRCRCUgRG9jCi0gICAqCi0gICAqIE5FRURTRE9DIEBwYXJhbSBkdG0KLSAgICoKLSAgICogTkVFRFNET0MgKCRvYmplY3ROYW1lJCkgQHJldHVybgotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IGludCBnZXREVE1JZGVudGl0eShEVE0gZHRtKTsKLQotICAvKioKLSAgICogJVRCRCUgRG9jCi0gICAqCi0gICAqIE5FRURTRE9DICgkb2JqZWN0TmFtZSQpIEByZXR1cm4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0RFRNSWRlbnRpdHlNYXNrKCkKLSAgewotICAgIHJldHVybiBJREVOVF9EVE1fREVGQVVMVDsKLSAgfQotCi0gIC8qKgotICAgKiAlVEJEJSBEb2MKLSAgICoKLSAgICogTkVFRFNET0MgKCRvYmplY3ROYW1lJCkgQHJldHVybgotICAgKi8KLSAgcHVibGljIGludCBnZXROb2RlSWRlbnRpdHlNYXNrKCkKLSAgewotICAgIHJldHVybiBJREVOVF9OT0RFX0RFRkFVTFQ7Ci0gIH0KLQotICAgIC8vCi0gICAgLy8gQ2xhc3NlcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBBIGNvbmZpZ3VyYXRpb24gZXJyb3IuCi0gICAgICogT3JpZ2luYWxseSBpbiBPYmplY3RGYWN0b3J5LiBUaGlzIGlzIHRoZSBvbmx5IHBvcnRpb24gdXNlZCBpbiB0aGlzIHBhY2thZ2UKLSAgICAgKi8KLSAgICBzdGF0aWMgY2xhc3MgQ29uZmlndXJhdGlvbkVycm9yCi0gICAgICAgIGV4dGVuZHMgRXJyb3IgewotICAgICAgICAgICAgICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA1MTIyMDU0MDk2NjE1MDY3OTkyTDsKLSAgICAgICAgLy8KLSAgICAgICAgLy8gRGF0YQotICAgICAgICAvLwotCi0gICAgICAgIC8qKiBFeGNlcHRpb24uICovCi0gICAgICAgIHByaXZhdGUgRXhjZXB0aW9uIGV4Y2VwdGlvbjsKLQotICAgICAgICAvLwotICAgICAgICAvLyBDb25zdHJ1Y3RvcnMKLSAgICAgICAgLy8KLQotICAgICAgICAvKioKLSAgICAgICAgICogQ29uc3RydWN0IGEgbmV3IGluc3RhbmNlIHdpdGggdGhlIHNwZWNpZmllZCBkZXRhaWwgc3RyaW5nIGFuZAotICAgICAgICAgKiBleGNlcHRpb24uCi0gICAgICAgICAqLwotICAgICAgICBDb25maWd1cmF0aW9uRXJyb3IoU3RyaW5nIG1zZywgRXhjZXB0aW9uIHgpIHsKLSAgICAgICAgICAgIHN1cGVyKG1zZyk7Ci0gICAgICAgICAgICB0aGlzLmV4Y2VwdGlvbiA9IHg7Ci0gICAgICAgIH0gLy8gPGluaXQ+KFN0cmluZyxFeGNlcHRpb24pCi0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gUHVibGljIG1ldGhvZHMKLSAgICAgICAgLy8KLQotICAgICAgICAvKiogUmV0dXJucyB0aGUgZXhjZXB0aW9uIGFzc29jaWF0ZWQgdG8gdGhpcyBlcnJvci4gKi8KLSAgICAgICAgRXhjZXB0aW9uIGdldEV4Y2VwdGlvbigpIHsKLSAgICAgICAgICAgIHJldHVybiBleGNlcHRpb247Ci0gICAgICAgIH0gLy8gZ2V0RXhjZXB0aW9uKCk6RXhjZXB0aW9uCi0KLSAgICB9IC8vIGNsYXNzIENvbmZpZ3VyYXRpb25FcnJvcgotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNV1NGaWx0ZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1XU0ZpbHRlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyOTg2NGIwLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1XU0ZpbHRlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTggKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRFRNV1NGaWx0ZXIuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNSAwODoxNDo1NSBzdXJlc2hfZW1haWxpZCBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtOwotCi0vKioKLSAqIFRoaXMgaW50ZXJmYWNlIGlzIG1lYW50IHRvIGJlIGltcGxlbWVudGVkIGJ5IGEgY2xpZW50IG9mIHRoZSBEVE0sIGFuZCBhbGxvd3MKLSAqIHN0cmlwcGluZyBvZiB3aGl0ZXNwYWNlIG5vZGVzLgotICovCi1wdWJsaWMgaW50ZXJmYWNlIERUTVdTRmlsdGVyCi17Ci0gIC8qKgotICAgKiBEbyBub3Qgc3RyaXAgd2hpdGVzcGFjZSBjaGlsZCBub2RlcyBvZiB0aGlzIGVsZW1lbnQuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IE5PVFNUUklQID0gMTsKLQotICAvKioKLSAgICogU3RyaXAgd2hpdGVzcGFjZSBjaGlsZCBub2RlcyBvZiB0aGlzIGVsZW1lbnQuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFNUUklQID0gMjsKLQotICAvKioKLSAgICogSW5oZXJpdCB3aGl0ZXNwYWNlIHN0cmlwcGluZyBiZWhhdmlvciBvZiB0aGUgcGFyZW50IG5vZGUuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IElOSEVSSVQgPSAzOwotCi0gIC8qKgotICAgKiBUZXN0IHdoZXRoZXIgd2hpdGVzcGFjZS1vbmx5IHRleHQgbm9kZXMgYXJlIHZpc2libGUgaW4gdGhlIGxvZ2ljYWwKLSAgICogdmlldyBvZiA8Y29kZT5EVE08L2NvZGU+LiBOb3JtYWxseSwgdGhpcyBmdW5jdGlvbgotICAgKiB3aWxsIGJlIGNhbGxlZCBieSB0aGUgaW1wbGVtZW50YXRpb24gb2YgPGNvZGU+RFRNPC9jb2RlPjsKLSAgICogaXQgaXMgbm90IG5vcm1hbGx5IGNhbGxlZCBkaXJlY3RseSBmcm9tCi0gICAqIHVzZXIgY29kZS4KLSAgICoKLSAgICogQHBhcmFtIGVsZW1lbnRIYW5kbGUgaW50IEhhbmRsZSBvZiB0aGUgZWxlbWVudC4KLSAgICogQHJldHVybiBvbmUgb2YgTk9UU1RSSVAsIFNUUklQLCBvciBJTkhFUklULgotICAgKi8KLSAgcHVibGljIHNob3J0IGdldFNob3VsZFN0cmlwU3BhY2UoaW50IGVsZW1lbnRIYW5kbGUsIERUTSBkdG0pOwotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vcmVmL0NodW5rZWRJbnRBcnJheS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL3JlZi9DaHVua2VkSW50QXJyYXkuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggODVhZWJmNy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vcmVmL0NodW5rZWRJbnRBcnJheS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzA4ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IENodW5rZWRJbnRBcnJheS5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE1IDA4OjE0OjU4IHN1cmVzaF9lbWFpbGlkIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0ucmVmOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXMuWE1MRXJyb3JSZXNvdXJjZXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXMuWE1MTWVzc2FnZXM7Ci0KLS8qKgotICogPGNvZGU+Q2h1bmtlZEludEFycmF5PC9jb2RlPiBpcyBhbiBleHRlbnNpYmxlIGFycmF5IG9mIGJsb2NrcyBvZiBpbnRlZ2Vycy4KLSAqIChJJ2QgY29uc2lkZXIgVmVjdG9yLCBidXQgaXQncyB1bmFibGUgdG8gaGFuZGxlIGludGVnZXJzIGV4Y2VwdCBieQotICogdHVybmluZyB0aGVtIGludG8gT2JqZWN0cy4pCi0KLSAqIDxwPk1ha2luZyB0aGlzIGEgc2VwYXJhdGUgY2xhc3MgbWVhbnMgc29tZSBjYWxsLWFuZC1yZXR1cm4gb3ZlcmhlYWQuIEJ1dAotICogZG9pbmcgaXQgYWxsIGlubGluZSB0ZW5kcyB0byBiZSBmcmFnaWxlIGFuZCBleHBlbnNpdmUgaW4gY29kZXIgdGltZSwKLSAqIG5vdCB0byBtZW50aW9uIGRyaXZpbmcgdXAgY29kZSBzaXplLiBJZiB5b3Ugd2FudCB0byBpbmxpbmUgaXQsIGZlZWwgZnJlZS4KLSAqIFRoZSBKYXZhIHRleHQgc3VnZ2VzdCB0aGF0IHByaXZhdGUgYW5kIEZpbmFsIG1ldGhvZHMgbWF5IGJlIGlubGluZWQsCi0gKiBhbmQgb25lIGNhbiBhcmd1ZSB0aGF0IHRoaXMgYmVhc3QgbmVlZCBub3QgYmUgbWFkZSBzdWJjbGFzc2FibGUuLi48L3A+Ci0gKgotICogPHA+JVJFVklFVyUgVGhpcyBoYXMgc3Ryb25nIGNvbmNlcHR1YWwgb3ZlcmxhcCB3aXRoIHRoZSBJbnRWZWN0b3IgY2xhc3MuCi0gKiBJdCB3b3VsZCBwcm9iYWJseSBiZSBhIGdvb2QgdGhpbmcgdG8gbWVyZ2UgdGhlIHR3bywgd2hlbiB0aW1lIHBlcm1pdHMuPHA+Ci0gKi8KLWZpbmFsIGNsYXNzIENodW5rZWRJbnRBcnJheQotewotICBmaW5hbCBpbnQgc2xvdHNpemU9NDsgLy8gTG9ja2VkLCBNVVNUIGJlIHBvd2VyIG9mIHR3byBpbiBjdXJyZW50IGNvZGUKLSAgLy8gRGVidWdnaW5nIHRpcDogQ3JhbmtpbmcgbG93Yml0cyBkb3duIHRvIDQgb3Igc28gaXMgYSBnb29kCi0gIC8vIHdheSB0byBwb3VuZCBvbiB0aGUgYXJyYXkgYWRkcmVzc2luZyBjb2RlLgotICBzdGF0aWMgZmluYWwgaW50IGxvd2JpdHM9MTA7IC8vIEhvdyBtYW55IGJpdHMgYWRkcmVzcyB3aXRoaW4gY2h1bmtzCi0gIHN0YXRpYyBmaW5hbCBpbnQgY2h1bmthbGxvYz0xPDxsb3diaXRzOwotICBzdGF0aWMgZmluYWwgaW50IGxvd21hc2s9Y2h1bmthbGxvYy0xOwotCi0gIENodW5rc1ZlY3RvciBjaHVua3M9bmV3IENodW5rc1ZlY3RvcigpOwotICBmaW5hbCBpbnQgZmFzdEFycmF5W10gPSBuZXcgaW50W2NodW5rYWxsb2NdOwotICBpbnQgbGFzdFVzZWQ9MDsKLQotICAvKioKLSAgICogQ3JlYXRlIGEgbmV3IENJQSB3aXRoIHNwZWNpZmllZCByZWNvcmQgc2l6ZS4gQ3VycmVudGx5IHJlY29yZCBzaXplIE1VU1QKLSAgICogYmUgYSBwb3dlciBvZiB0d28uLi4gYW5kIGluIGZhY3QgaXMgaGFyZGNvZGVkIHRvIDQuCi0gICAqLwotICBDaHVua2VkSW50QXJyYXkoaW50IHNsb3RzaXplKQotICB7Ci0gICAgaWYodGhpcy5zbG90c2l6ZTxzbG90c2l6ZSkKLSAgICAgIHRocm93IG5ldyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oWE1MTWVzc2FnZXMuY3JlYXRlWE1MTWVzc2FnZShYTUxFcnJvclJlc291cmNlcy5FUl9DSFVOS0VESU5UQVJSQVlfTk9UX1NVUFBPUlRFRCwgbmV3IE9iamVjdFtde0ludGVnZXIudG9TdHJpbmcoc2xvdHNpemUpfSkpOyAvLyJDaHVua2VkSW50QXJyYXkoIitzbG90c2l6ZSsiKSBub3QgY3VycmVudGx5IHN1cHBvcnRlZCIpOwotICAgIGVsc2UgaWYgKHRoaXMuc2xvdHNpemU+c2xvdHNpemUpCi0gICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIioqKioqV0FSTklORzogQ2h1bmtlZEludEFycmF5KCIrc2xvdHNpemUrIikgd2FzdGluZyAiKyh0aGlzLnNsb3RzaXplLXNsb3RzaXplKSsiIHdvcmRzIHBlciBzbG90Iik7Ci0gICAgY2h1bmtzLmFkZEVsZW1lbnQoZmFzdEFycmF5KTsKLSAgfQotICAvKioKLSAgICogQXBwZW5kIGEgNC1pbnRlZ2VyIHJlY29yZCB0byB0aGUgQ0lBLCBzdGFydGluZyB3aXRoIHJlY29yZCAxLiAoU2luY2UKLSAgICogYXJyYXlzIGFyZSBpbml0aWFsaXplZCB0byBhbGwtMCwgMCBoYXMgYmVlbiByZXNlcnZlZCBhcyB0aGUgInVua25vd24iCi0gICAqIHZhbHVlIGluIERUTS4pCi0gICAqIEByZXR1cm4gdGhlIGluZGV4IGF0IHdoaWNoIHRoaXMgcmVjb3JkIHdhcyBpbnNlcnRlZC4KLSAgICovCi0gIGludCBhcHBlbmRTbG90KGludCB3MCwgaW50IHcxLCBpbnQgdzIsIGludCB3MykKLSAgewotICAgIC8qCi0gICAgdHJ5Ci0gICAgewotICAgICAgaW50IG5ld29mZnNldCA9IChsYXN0VXNlZCsxKSpzbG90c2l6ZTsKLSAgICAgIGZhc3RBcnJheVtuZXdvZmZzZXRdID0gdzA7Ci0gICAgICBmYXN0QXJyYXlbbmV3b2Zmc2V0KzFdID0gdzE7Ci0gICAgICBmYXN0QXJyYXlbbmV3b2Zmc2V0KzJdID0gdzI7Ci0gICAgICBmYXN0QXJyYXlbbmV3b2Zmc2V0KzNdID0gdzM7Ci0gICAgICByZXR1cm4gKytsYXN0VXNlZDsKLSAgICB9Ci0gICAgY2F0Y2goQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGFpb29iZSkKLSAgICAqLwotICAgIHsKLSAgICAgIGZpbmFsIGludCBzbG90c2l6ZT00OwotICAgICAgaW50IG5ld29mZnNldCA9IChsYXN0VXNlZCsxKSpzbG90c2l6ZTsKLSAgICAgIGludCBjaHVua3BvcyA9IG5ld29mZnNldCA+PiBsb3diaXRzOwotICAgICAgaW50IHNsb3Rwb3MgPSAobmV3b2Zmc2V0ICYgbG93bWFzayk7Ci0KLSAgICAgIC8vIEdyb3cgaWYgbmVlZGVkCi0gICAgICBpZiAoY2h1bmtwb3MgPiBjaHVua3Muc2l6ZSgpIC0gMSkKLSAgICAgICAgY2h1bmtzLmFkZEVsZW1lbnQobmV3IGludFtjaHVua2FsbG9jXSk7Ci0gICAgICBpbnRbXSBjaHVuayA9IGNodW5rcy5lbGVtZW50QXQoY2h1bmtwb3MpOwotICAgICAgY2h1bmtbc2xvdHBvc10gPSB3MDsKLSAgICAgIGNodW5rW3Nsb3Rwb3MrMV0gPSB3MTsKLSAgICAgIGNodW5rW3Nsb3Rwb3MrMl0gPSB3MjsKLSAgICAgIGNodW5rW3Nsb3Rwb3MrM10gPSB3MzsKLQotICAgICAgcmV0dXJuICsrbGFzdFVzZWQ7Ci0gICAgfQotICB9Ci0gIC8qKgotICAgKiBSZXRyaWV2ZSBhbiBpbnRlZ2VyIGZyb20gdGhlIENJQSBieSByZWNvcmQgbnVtYmVyIGFuZCBjb2x1bW4gd2l0aGluCi0gICAqIHRoZSByZWNvcmQsIGJvdGggMC1iYXNlZCAodGhvdWdoIHBvc2l0aW9uIDAgaXMgcmVzZXJ2ZWQgZm9yIHNwZWNpYWwKLSAgICogcHVycG9zZXMpLgotICAgKiBAcGFyYW0gcG9zaXRpb24gaW50IFJlY29yZCBudW1iZXIKLSAgICogQHBhcmFtIHNsb3Rwb3MgaW50IENvbHVtbiBudW1iZXIKLSAgICovCi0gIGludCByZWFkRW50cnkoaW50IHBvc2l0aW9uLCBpbnQgb2Zmc2V0KSB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCi0gIHsKLSAgICAvKgotICAgIHRyeQotICAgIHsKLSAgICAgIHJldHVybiBmYXN0QXJyYXlbKHBvc2l0aW9uKnNsb3RzaXplKStvZmZzZXRdOwotICAgIH0KLSAgICBjYXRjaChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gYWlvb2JlKQotICAgICovCi0gICAgewotICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJVc2luZyBzbG93IHJlYWQgKDEpIik7Ci0gICAgICBpZiAob2Zmc2V0Pj1zbG90c2l6ZSkKLSAgICAgICAgdGhyb3cgbmV3IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihYTUxNZXNzYWdlcy5jcmVhdGVYTUxNZXNzYWdlKFhNTEVycm9yUmVzb3VyY2VzLkVSX09GRlNFVF9CSUdHRVJfVEhBTl9TTE9ULCBudWxsKSk7IC8vIk9mZnNldCBiaWdnZXIgdGhhbiBzbG90Iik7Ci0gICAgICBwb3NpdGlvbio9c2xvdHNpemU7Ci0gICAgICBpbnQgY2h1bmtwb3MgPSBwb3NpdGlvbiA+PiBsb3diaXRzOwotICAgICAgaW50IHNsb3Rwb3MgPSBwb3NpdGlvbiAmIGxvd21hc2s7Ci0gICAgICBpbnRbXSBjaHVuayA9IGNodW5rcy5lbGVtZW50QXQoY2h1bmtwb3MpOwotICAgICAgcmV0dXJuIGNodW5rW3Nsb3Rwb3MgKyBvZmZzZXRdOwotICAgIH0KLSAgfQotCi0gIC8vIENoZWNrIHRoYXQgdGhlIG5vZGUgYXQgaW5kZXggInBvc2l0aW9uIiBpcyBub3QgYW4gYW5jZXN0b3IKLSAgLy8gb2YgdGhlIG5vZGUgYXQgaW5kZXggInN0YXJ0UG9zIi4gSUYgSVQgSVMsIERPIE5PVCBBQ0NFUFQgSVQgQU5ECi0gIC8vIFJFVFVSTiAtMS4gSWYgcG9zaXRpb24gaXMgTk9UIGFuIGFuY2VzdG9yLCByZXR1cm4gcG9zaXRpb24uCi0gIC8vIFNwZWNpYWwgY2FzZTogVGhlIERvY3VtZW50IG5vZGUgKHBvc2l0aW9uPT0wKSBpcyBhY2NlcHRhYmxlLgotICAvLwotICAvLyBUaGlzIHRlc3Qgc3VwcG9ydHMgRFRNLmdldE5leHRQcmVjZWRpbmcuCi0gIGludCBzcGVjaWFsRmluZChpbnQgc3RhcnRQb3MsIGludCBwb3NpdGlvbikKLSAgewotICAgICAgICAgIC8vIFdlIGhhdmUgdG8gbG9vayBhbGwgdGhlIHdheSB1cCB0aGUgYW5jZXN0b3IgY2hhaW4KLSAgICAgICAgICAvLyB0byBtYWtlIHN1cmUgd2UgZG9uJ3QgaGF2ZSBhbiBhbmNlc3Rvci4KLSAgICAgICAgICBpbnQgYW5jZXN0b3IgPSBzdGFydFBvczsKLSAgICAgICAgICB3aGlsZShhbmNlc3RvciA+IDApCi0gICAgICAgICAgewotICAgICAgICAgICAgICAgIC8vIEdldCB0aGUgbm9kZSB3aG9zZSBpbmRleCA9PSBhbmNlc3RvcgotICAgICAgICAgICAgICAgIGFuY2VzdG9yKj1zbG90c2l6ZTsKLSAgICAgICAgICAgICAgICBpbnQgY2h1bmtwb3MgPSBhbmNlc3RvciA+PiBsb3diaXRzOwotICAgICAgICAgICAgICAgIGludCBzbG90cG9zID0gYW5jZXN0b3IgJiBsb3dtYXNrOwotICAgICAgICAgICAgICAgIGludFtdIGNodW5rID0gY2h1bmtzLmVsZW1lbnRBdChjaHVua3Bvcyk7Ci0KLSAgICAgICAgICAgICAgICAvLyBHZXQgdGhhdCBub2RlJ3MgcGFyZW50IChOb3RlIHRoYXQgdGhpcyBhc3N1bWVzIHdbMV0KLSAgICAgICAgICAgICAgICAvLyBpcyB0aGUgcGFyZW50IG5vZGUgaW5kZXguIFRoYXQncyByZWFsbHkgYSBEVE0gZmVhdHVyZQotICAgICAgICAgICAgICAgIC8vIHJhdGhlciB0aGFuIGEgQ2h1bmtlZEludEFycmF5IGZlYXR1cmUuKQotICAgICAgICAgICAgICAgIGFuY2VzdG9yID0gY2h1bmtbc2xvdHBvcyArIDFdOwotCi0gICAgICAgICAgICAgICAgaWYoYW5jZXN0b3IgPT0gcG9zaXRpb24pCi0gICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgfQotCi0gICAgICAgICAgaWYgKGFuY2VzdG9yIDw9IDApCi0gICAgICAgICAgewotICAgICAgICAgICAgICAgICAgcmV0dXJuIHBvc2l0aW9uOwotICAgICAgICAgIH0KLSAgICAgICAgICByZXR1cm4gLTE7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBpbnQgaW5kZXggb2YgaGlnaGVzdC1udW1iZXJlZCByZWNvcmQgY3VycmVudGx5IGluIHVzZQotICAgKi8KLSAgaW50IHNsb3RzVXNlZCgpCi0gIHsKLSAgICByZXR1cm4gbGFzdFVzZWQ7Ci0gIH0KLQotICAvKiogRGlzYXJkIHRoZSBoaWdoZXN0LW51bWJlcmVkIHJlY29yZC4gVGhpcyBpcyB1c2VkIGluIHRoZSBzdHJpbmctYnVmZmVyCi0gICBDSUE7IHdoZW4gb25seSBhIHNpbmdsZSBjaGFyYWN0ZXJzKCkgY2h1bmsgaGFzIGJlZW4gcmVjaWV2ZWQsIGl0cyBpbmRleAotICAgaXMgbW92ZWQgaW50byB0aGUgVGV4dCBub2RlIHJhdGhlciB0aGFuIGJlaW5nIHJlZmVyZW5jZWQgYnkgaW5kaXJlY3Rpb24KLSAgIGludG8gdGhlIHRleHQgYWNjdW11bGF0b3IuCi0gICAqLwotICB2b2lkIGRpc2NhcmRMYXN0KCkKLSAgewotICAgIC0tbGFzdFVzZWQ7Ci0gIH0KLQotICAvKioKLSAgICogT3ZlcndyaXRlIHRoZSBpbnRlZ2VyIGZvdW5kIGF0IGEgc3BlY2lmaWMgcmVjb3JkIGFuZCBjb2x1bW4uCi0gICAqIFVzZWQgdG8gYmFjay1wYXRjaCBleGlzdGluZyByZWNvcmRzLCBtb3N0IG9mdGVuIGNoYW5naW5nIHRoZWlyCi0gICAqICJuZXh0IHNpYmxpbmciIHJlZmVyZW5jZSBmcm9tIDAgKHVua25vd24pIHRvIHNvbWV0aGluZyBtZWFuaW5nZnVsCi0gICAqIEBwYXJhbSBwb3NpdGlvbiBpbnQgUmVjb3JkIG51bWJlcgotICAgKiBAcGFyYW0gb2Zmc2V0IGludCBDb2x1bW4gbnVtYmVyCi0gICAqIEBwYXJhbSB2YWx1ZSBpbnQgTmV3IGNvbnRlbnRzCi0gICAqLwotICB2b2lkIHdyaXRlRW50cnkoaW50IHBvc2l0aW9uLCBpbnQgb2Zmc2V0LCBpbnQgdmFsdWUpIHRocm93cyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KLSAgewotICAgIC8qCi0gICAgdHJ5Ci0gICAgewotICAgICAgZmFzdEFycmF5WyggcG9zaXRpb24qc2xvdHNpemUpK29mZnNldF0gPSB2YWx1ZTsKLSAgICB9Ci0gICAgY2F0Y2goQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGFpb29iZSkKLSAgICAqLwotICAgIHsKLSAgICAgIGlmIChvZmZzZXQgPj0gc2xvdHNpemUpCi0gICAgICAgIHRocm93IG5ldyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oWE1MTWVzc2FnZXMuY3JlYXRlWE1MTWVzc2FnZShYTUxFcnJvclJlc291cmNlcy5FUl9PRkZTRVRfQklHR0VSX1RIQU5fU0xPVCwgbnVsbCkpOyAvLyJPZmZzZXQgYmlnZ2VyIHRoYW4gc2xvdCIpOwotICAgICAgcG9zaXRpb24qPXNsb3RzaXplOwotICAgICAgaW50IGNodW5rcG9zID0gcG9zaXRpb24gPj4gbG93Yml0czsKLSAgICAgIGludCBzbG90cG9zID0gcG9zaXRpb24gJiBsb3dtYXNrOwotICAgICAgaW50W10gY2h1bmsgPSBjaHVua3MuZWxlbWVudEF0KGNodW5rcG9zKTsKLSAgICAgIGNodW5rW3Nsb3Rwb3MgKyBvZmZzZXRdID0gdmFsdWU7IC8vIEFUT01JQyEKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogT3ZlcndyaXRlIGFuIGVudGlyZSAoNC1pbnRlZ2VyKSByZWNvcmQgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4KLSAgICogTW9zdGx5IHVzZWQgdG8gY3JlYXRlIHJlY29yZCAwLCB0aGUgRG9jdW1lbnQgbm9kZS4KLSAgICogQHBhcmFtIHBvc2l0aW9uIGludGVnZXIgUmVjb3JkIG51bWJlcgotICAgKiBAcGFyYW0gdzAgaW50Ci0gICAqIEBwYXJhbSB3MSBpbnQKLSAgICogQHBhcmFtIHcyIGludAotICAgKiBAcGFyYW0gdzMgaW50Ci0gICAqLwotICB2b2lkIHdyaXRlU2xvdChpbnQgcG9zaXRpb24sIGludCB3MCwgaW50IHcxLCBpbnQgdzIsIGludCB3MykKLSAgewotICAgICAgcG9zaXRpb24gKj0gc2xvdHNpemU7Ci0gICAgICBpbnQgY2h1bmtwb3MgPSBwb3NpdGlvbiA+PiBsb3diaXRzOwotICAgICAgaW50IHNsb3Rwb3MgPSAocG9zaXRpb24gJiBsb3dtYXNrKTsKLQotICAgIC8vIEdyb3cgaWYgbmVlZGVkCi0gICAgaWYgKGNodW5rcG9zID4gY2h1bmtzLnNpemUoKSAtIDEpCi0gICAgICBjaHVua3MuYWRkRWxlbWVudChuZXcgaW50W2NodW5rYWxsb2NdKTsKLSAgICBpbnRbXSBjaHVuayA9IGNodW5rcy5lbGVtZW50QXQoY2h1bmtwb3MpOwotICAgIGNodW5rW3Nsb3Rwb3NdID0gdzA7Ci0gICAgY2h1bmtbc2xvdHBvcyArIDFdID0gdzE7Ci0gICAgY2h1bmtbc2xvdHBvcyArIDJdID0gdzI7Ci0gICAgY2h1bmtbc2xvdHBvcyArIDNdID0gdzM7Ci0gIH0KLQotICAvKioKLSAgICogUmV0cmlldmUgdGhlIGNvbnRlbnRzIG9mIGEgcmVjb3JkIGludG8gYSB1c2VyLXN1cHBsaWVkIGJ1ZmZlciBhcnJheS4KLSAgICogVXNlZCB0byByZWR1Y2UgYWRkcmVzc2luZyBvdmVyaGVhZCB3aGVuIGNvZGUgd2lsbCBhY2Nlc3Mgc2V2ZXJhbAotICAgKiBjb2x1bW5zIG9mIHRoZSByZWNvcmQuCi0gICAqIEBwYXJhbSBwb3NpdGlvbiBpbnQgUmVjb3JkIG51bWJlcgotICAgKiBAcGFyYW0gYnVmZmVyIGludFtdIEludGVnZXIgYXJyYXkgcHJvdmlkZWQgYnkgdXNlciwgbXVzdCBiZSBsYXJnZSBlbm91Z2gKLSAgICogdG8gaG9sZCBhIGNvbXBsZXRlIHJlY29yZC4KLSAgICovCi0gIHZvaWQgcmVhZFNsb3QoaW50IHBvc2l0aW9uLCBpbnRbXSBidWZmZXIpCi0gIHsKLSAgICAvKgotICAgIHRyeQotICAgIHsKLSAgICAgIFN5c3RlbS5hcnJheWNvcHkoZmFzdEFycmF5LCBwb3NpdGlvbipzbG90c2l6ZSwgYnVmZmVyLCAwLCBzbG90c2l6ZSk7Ci0gICAgfQotICAgIGNhdGNoKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBhaW9vYmUpCi0gICAgKi8KLSAgICB7Ci0gICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIlVzaW5nIHNsb3cgcmVhZCAoMik6ICIrcG9zaXRpb24pOwotICAgICAgcG9zaXRpb24gKj0gc2xvdHNpemU7Ci0gICAgICBpbnQgY2h1bmtwb3MgPSBwb3NpdGlvbiA+PiBsb3diaXRzOwotICAgICAgaW50IHNsb3Rwb3MgPSAocG9zaXRpb24gJiBsb3dtYXNrKTsKLQotICAgICAgLy8gR3JvdyBpZiBuZWVkZWQKLSAgICAgIGlmIChjaHVua3BvcyA+IGNodW5rcy5zaXplKCkgLSAxKQotICAgICAgICBjaHVua3MuYWRkRWxlbWVudChuZXcgaW50W2NodW5rYWxsb2NdKTsKLSAgICAgIGludFtdIGNodW5rID0gY2h1bmtzLmVsZW1lbnRBdChjaHVua3Bvcyk7Ci0gICAgICBTeXN0ZW0uYXJyYXljb3B5KGNodW5rLHNsb3Rwb3MsYnVmZmVyLDAsc2xvdHNpemUpOwotICAgIH0KLSAgfQotCi0gIGNsYXNzIENodW5rc1ZlY3RvcgotICB7Ci0gICAgZmluYWwgaW50IEJMT0NLU0laRSA9IDY0OwotICAgIGludFtdIG1fbWFwW10gPSBuZXcgaW50W0JMT0NLU0laRV1bXTsKLSAgICBpbnQgbV9tYXBTaXplID0gQkxPQ0tTSVpFOwotICAgIGludCBwb3MgPSAwOwotCi0gICAgQ2h1bmtzVmVjdG9yKCkKLSAgICB7Ci0gICAgfQotCi0gICAgZmluYWwgaW50IHNpemUoKQotICAgIHsKLSAgICAgIHJldHVybiBwb3M7Ci0gICAgfQotCi0gICAgdm9pZCBhZGRFbGVtZW50KGludFtdIHZhbHVlKQotICAgIHsKLSAgICAgIGlmKHBvcyA+PSBtX21hcFNpemUpCi0gICAgICB7Ci0gICAgICAgIGludCBvcmdNYXBTaXplID0gbV9tYXBTaXplOwotICAgICAgICB3aGlsZShwb3MgPj0gbV9tYXBTaXplKQotICAgICAgICAgIG1fbWFwU2l6ZSs9QkxPQ0tTSVpFOwotICAgICAgICBpbnRbXSBuZXdNYXBbXSA9IG5ldyBpbnRbbV9tYXBTaXplXVtdOwotICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KG1fbWFwLCAwLCBuZXdNYXAsIDAsIG9yZ01hcFNpemUpOwotICAgICAgICBtX21hcCA9IG5ld01hcDsKLSAgICAgIH0KLSAgICAgIC8vIEZvciBub3csIGp1c3QgZG8gYSBzaW1wbGUgYXBwZW5kLiAgQSBzb3J0ZWQgaW5zZXJ0IG9ubHkKLSAgICAgIC8vIG1ha2VzIHNlbnNlIGlmIHdlJ3JlIGRvaW5nIGFuIGJpbmFyeSBzZWFyY2ggb3Igc29tZSBzdWNoLgotICAgICAgbV9tYXBbcG9zXSA9IHZhbHVlOwotICAgICAgcG9zKys7Ci0gICAgfQotCi0gICAgZmluYWwgaW50W10gZWxlbWVudEF0KGludCBwb3MpCi0gICAgewotICAgICAgcmV0dXJuIG1fbWFwW3Bvc107Ci0gICAgfQotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vcmVmL0Nvcm91dGluZU1hbmFnZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9yZWYvQ29yb3V0aW5lTWFuYWdlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2MzIzYjAzLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9yZWYvQ29yb3V0aW5lTWFuYWdlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzQ2ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IENvcm91dGluZU1hbmFnZXIuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNSAwODoxNDo1OCBzdXJlc2hfZW1haWxpZCBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLnJlZjsKLQotaW1wb3J0IGphdmEudXRpbC5CaXRTZXQ7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnJlcy5YTUxFcnJvclJlc291cmNlczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnJlcy5YTUxNZXNzYWdlczsKLQotCi0vKioKLSAqIDxwPlN1cHBvcnQgdGhlIGNvcm91dGluZSBkZXNpZ24gcGF0dGVybi48L3A+Ci0gKgotICogPHA+QSBjb3JvdXRpbmUgc2V0IGlzIGEgdmVyeSBzaW1wbGUgY29vcGVyYXRpdmUgbm9uLXByZWVtcHRpdmUKLSAqIG11bHRpdGFza2luZyBtb2RlbCwgd2hlcmUgdGhlIHN3aXRjaCBmcm9tIG9uZSB0YXNrIHRvIGFub3RoZXIgaXMKLSAqIHBlcmZvcm1lZCB2aWEgYW4gZXhwbGljaXQgcmVxdWVzdC4gQ29yb3V0aW5lcyBpbnRlcmFjdCBhY2NvcmRpbmcgdG8KLSAqIHRoZSBmb2xsb3dpbmcgcnVsZXM6PC9wPgotICoKLSAqIDx1bD4KLSAqIDxsaT5PbmUgY29yb3V0aW5lIGluIHRoZSBzZXQgaGFzIGNvbnRyb2wsIHdoaWNoIGl0IHJldGFpbnMgdW50aWwgaXQKLSAqIGVpdGhlciBleGl0cyBvciByZXN1bWVzIGFub3RoZXIgY29yb3V0aW5lLjwvbGk+Ci0gKiA8bGk+QSBjb3JvdXRpbmUgaXMgYWN0aXZhdGVkIHdoZW4gaXQgaXMgcmVzdW1lZCBieSBzb21lIG90aGVyIGNvcm91dGluZQotICogZm9yIHRoZSBmaXJzdCB0aW1lLjwvbGk+Ci0gKiA8bGk+QW4gYWN0aXZlIGNvcm91dGluZSB0aGF0IGdpdmVzIHVwIGNvbnRyb2wgYnkgcmVzdW1pbmcgYW5vdGhlciBpbgotICogdGhlIHNldCByZXRhaW5zIGl0cyBjb250ZXh0IC0tIGluY2x1ZGluZyBjYWxsIHN0YWNrIGFuZCBsb2NhbCB2YXJpYWJsZXMKLSAqIC0tIHNvIHRoYXQgaWYvd2hlbiBpdCBpcyByZXN1bWVkLCBpdCB3aWxsIHByb2NlZWQgZnJvbSB0aGUgcG9pbnQgYXQgd2hpY2gKLSAqIGl0IGxhc3QgZ2F2ZSB1cCBjb250cm9sLjwvbGk+Ci0gKiA8L3VsPgotICoKLSAqIDxwPkNvcm91dGluZXMgY2FuIGJlIHRob3VnaHQgb2YgYXMgZmFsbGluZyBzb21ld2hlcmUgYmV0d2VlbiBwaXBlcyBhbmQKLSAqIHN1YnJvdXRpbmVzLiBMaWtlIGNhbGwvcmV0dXJuLCB0aGVyZSBpcyBhbiBleHBsaWNpdCBmbG93IG9mIGNvbnRyb2wKLSAqIGZyb20gb25lIGNvcm91dGluZSB0byBhbm90aGVyLiBMaWtlIHBpcGVzLCBuZWl0aGVyIGNvcm91dGluZSBpcwotICogYWN0dWFsbHkgImluIGNoYXJnZSIsIGFuZCBuZWl0aGVyIG11c3QgZXhpdCBpbiBvcmRlciB0byB0cmFuc2ZlcgotICogY29udHJvbCB0byB0aGUgb3RoZXIuIDwvcD4KLSAqCi0gKiA8cD5PbmUgY2xhc3NpYyBhcHBsaWNhdGlvbiBvZiBjb3JvdXRpbmVzIGlzIGluIGNvbXBpbGVycywgd2hlcmUgYm90aAotICogdGhlIHBhcnNlciBhbmQgdGhlIGxleGVyIGFyZSBtYWludGFpbmluZyBjb21wbGV4IHN0YXRlCi0gKiBpbmZvcm1hdGlvbi4gVGhlIHBhcnNlciByZXN1bWVzIHRoZSBsZXhlciB0byBwcm9jZXNzIGluY29taW5nCi0gKiBjaGFyYWN0ZXJzIGludG8gbGV4aWNhbCB0b2tlbnMsIGFuZCB0aGUgbGV4ZXIgcmVzdW1lcyB0aGUgcGFyc2VyCi0gKiB3aGVuIGl0IGhhcyByZWFjaGVkIGEgcG9pbnQgYXQgd2hpY2ggaXQgaGFzIGEgcmVsaWFibHkgaW50ZXJwcmV0ZWQKLSAqIHNldCBvZiB0b2tlbnMgYXZhaWxhYmxlIGZvciBzZW1hbnRpYyBwcm9jZXNzaW5nLiBTdHJ1Y3R1cmluZyB0aGlzCi0gKiBhcyBjYWxsLWFuZC1yZXR1cm4gd291bGQgcmVxdWlyZSBzYXZpbmcgYW5kIHJlc3RvcmluZyBhCi0gKiBjb25zaWRlcmFibGUgYW1vdW50IG9mIHN0YXRlIGVhY2ggdGltZS4gU3RydWN0dXJpbmcgaXQgYXMgdHdvIHRhc2tzCi0gKiBjb25uZWN0ZWQgYnkgYSBxdWV1ZSBtYXkgaW52b2x2ZSBoaWdoZXIgb3ZlcmhlYWQgKGluIHN5c3RlbXMgd2hpY2gKLSAqIGNhbiBvcHRpbWl6ZSB0aGUgY29yb3V0aW5lIG1ldGFwaG9yKSwgaXNuJ3QgbmVjZXNzYXJpbHkgYXMgY2xlYXIgaW4KLSAqIGludGVudCwgbWF5IGhhdmUgdHJvdWJsZSBoYW5kbGluZyBjYXNlcyB3aGVyZSBkYXRhIGZsb3dzIGluIGJvdGgKLSAqIGRpcmVjdGlvbnMsIGFuZCBtYXkgbm90IGhhbmRsZSBzb21lIG9mIHRoZSBtb3JlIGNvbXBsZXggY2FzZXMgd2hlcmUKLSAqIG1vcmUgdGhhbiB0d28gY29yb3V0aW5lcyBhcmUgaW52b2x2ZWQuPC9wPgotICoKLSAqIDxwPk1vc3QgY29yb3V0aW5lIHN5c3RlbXMgYWxzbyBwcm92aWRlIGEgd2F5IHRvIHBhc3MgZGF0YSBiZXR3ZWVuIHRoZQotICogc291cmNlIGFuZCB0YXJnZXQgb2YgYSByZXN1bWUgb3BlcmF0aW9uOyB0aGlzIGlzIHNvbWV0aW1lcyByZWZlcnJlZAotICogdG8gYXMgInlpZWxkaW5nIiBhIHZhbHVlLiAgT3RoZXJzIHJlbHkgb24gdGhlIGZhY3QgdGhhdCwgc2luY2Ugb25seQotICogb25lIG1lbWJlciBvZiBhIGNvcm91dGluZSBzZXQgaXMgcnVubmluZyBhdCBhIHRpbWUgYW5kIGRvZXMgbm90Ci0gKiBsb3NlIGNvbnRyb2wgdW50aWwgaXQgY2hvb3NlcyB0byBkbyBzbywgZGF0YSBzdHJ1Y3R1cmVzIG1heSBiZQotICogZGlyZWN0bHkgc2hhcmVkIGJldHdlZW4gdGhlbSB3aXRoIG9ubHkgbWluaW1hbCBwcmVjYXV0aW9ucy48L3A+Ci0gKgotICogPHA+Ik5vdGU6IFRoaXMgc2hvdWxkIG5vdCBiZSB0YWtlbiB0byBtZWFuIHRoYXQgcHJvZHVjZXIvY29uc3VtZXIKLSAqIHByb2JsZW1zIHNob3VsZCBiZSBhbHdheXMgYmUgZG9uZSB3aXRoIGNvcm91dGluZXMuIiBRdWV1ZWluZyBpcwotICogb2Z0ZW4gYSBiZXR0ZXIgc29sdXRpb24gd2hlbiBvbmx5IHR3byB0aHJlYWRzIG9mIGV4ZWN1dGlvbiBhcmUKLSAqIGludm9sdmVkIGFuZCBmdWxsIHR3by13YXkgaGFuZHNoYWtpbmcgaXMgbm90IHJlcXVpcmVkLiBJdCdzIGEgYml0Ci0gKiBkaWZmaWN1bHQgdG8gZmluZCBzaG9ydCBwZWRhZ29naWNhbCBleGFtcGxlcyB0aGF0IHJlcXVpcmUKLSAqIGNvcm91dGluZXMgZm9yIGEgY2xlYXIgc29sdXRpb24uPC9wPgotICoKLSAqIDxwPlRoZSBmYWN0IHRoYXQgb25seSBvbmUgb2YgYSBncm91cCBvZiBjb3JvdXRpbmVzIGlzIHJ1bm5pbmcgYXQgYQotICogdGltZSwgYW5kIHRoZSBjb250cm9sIHRyYW5zZmVyIGJldHdlZW4gdGhlbSBpcyBleHBsaWNpdCwgc2ltcGxpZmllcwotICogdGhlaXIgcG9zc2libGUgaW50ZXJhY3Rpb25zLCBhbmQgaW4gc29tZSBpbXBsZW1lbnRhdGlvbnMgcGVybWl0cwotICogdGhlbSB0byBiZSBpbXBsZW1lbnRlZCBtb3JlIGVmZmljaWVudGx5IHRoYW4gZ2VuZXJhbCBtdWx0aXRhc2tpbmcuCi0gKiBJbiBzb21lIHNpdHVhdGlvbnMsIGNvcm91dGluZXMgY2FuIGJlIGNvbXBpbGVkIG91dCBlbnRpcmVseTsKLSAqIGluIG90aGVycywgdGhleSBtYXkgb25seSByZXF1aXJlIGEgZmV3IGluc3RydWN0aW9ucyBtb3JlIHRoYW4gYQotICogc2ltcGxlIGZ1bmN0aW9uIGNhbGwuPC9wPgotICoKLSAqIDxwPlRoaXMgdmVyc2lvbiBpcyBidWlsdCBvbiB0b3Agb2Ygc3RhbmRhcmQgSmF2YSB0aHJlYWRpbmcsIHNpbmNlCi0gKiB0aGF0J3MgYWxsIHdlIGhhdmUgYXZhaWxhYmxlIHJpZ2h0IG5vdy4gSXQncyBiZWVuIGVuY2Fwc3VsYXRlZCBmb3IKLSAqIGNvZGUgY2xhcml0eSBhbmQgcG9zc2libGUgZnV0dXJlIG9wdGltaXphdGlvbi48L3A+Ci0gKgotICogPHA+KFR3byBwb3NzaWJsZSBhcHByb2FjaGVzOiB3YWl0LW5vdGlmeSBiYXNlZCBhbmQgcXVldWUtYmFzZWQuIFNvbWUKLSAqIGZvbGtzIHRoaW5rIHRoYXQgYSBvbmUtaXRlbSBxdWV1ZSBpcyBhIGNsZWFuZXIgc29sdXRpb24gYmVjYXVzZSBpdCdzCi0gKiBtb3JlIGFic3RyYWN0IC0tIGJ1dCBzaW5jZSBjb3JvdXRpbmUgX2lzXyBhbiBhYnN0cmFjdGlvbiBJJ20gbm90IHJlYWxseQotICogd29ycmllZCBhYm91dCB0aGF0OyBmb2xrcyBzaG91bGQgYmUgYWJsZSB0byBzd2l0Y2ggdGhpcyBjb2RlIHdpdGhvdXQKLSAqIGNvbmNlcm4uKTwvcD4KLSAqCi0gKiA8cD4lVEJEJSBUSElTIFNIT1VMRCBCRSBBTiBJTlRFUkZBQ0UsIHRvIGZhY2lsaXRhdGUgYnVpbGRpbmcgb3RoZXIKLSAqIGltcGxlbWVudGF0aW9ucy4uLiBwZXJoYXBzIGluY2x1ZGluZyBhIHRydWUgY29yb3V0aW5lIHN5c3RlbQotICogc29tZWRheSwgcmF0aGVyIHRoYW4gY29udHJvbGxlZCB0aHJlYWRpbmcuIEFyZ3VhYmx5IENvcm91dGluZQotICogaXRzZWxmIHNob3VsZCBiZSBhbiBpbnRlcmZhY2UgbXVjaCBsaWtlIFJ1bm5hYmxlLCBidXQgSSB0aGluayB0aGF0Ci0gKiBjYW4gYmUgYnVpbHQgb24gdG9wIG9mIHRoaXMuPC9wPgotICogKi8KLXB1YmxpYyBjbGFzcyBDb3JvdXRpbmVNYW5hZ2VyCi17Ci0gIC8qKiAiSXMgdGhpcyBjb3JvdXRpbmUgSUQgbnVtYmVyIGFscmVhZHkgaW4gdXNlIiBsb29rdXAgdGFibGUuCi0gICAqIEN1cnJlbnRseSBpbXBsZW1lbnRlZCBhcyBhIGJpdHNldCBhcyBhIGNvbXByb21pc2UgYmV0d2VlbgotICAgKiBjb21wYWN0bmVzcyBhbmQgc3BlZWQgb2YgYWNjZXNzLCBidXQgb2J2aW91c2x5IG90aGVyIHNvbHV0aW9ucwotICAgKiBjb3VsZCBiZSBhcHBsaWVkLgotICAgKiAqLwotICBCaXRTZXQgbV9hY3RpdmVJRHM9bmV3IEJpdFNldCgpOwotCi0gIC8qKiBMaW1pdCBvbiB0aGUgY29yb3V0aW5lIElEIG51bWJlcnMgYWNjZXB0ZWQuIEkgZGlkbid0IHdhbnQgdGhlCi0gICAqIGluLXVzZSB0YWJsZSB0byBncm93IHdpdGhvdXQgYm91bmQuIElmIHdlIHN3aXRjaCB0byBhIG1vcmUgZWZmaWNpZW50Ci0gICAqIHNwYXJzZS1hcnJheSBtZWNoYW5pc20sIGl0IG1heSBiZSBwb3NzaWJsZSB0byByYWlzZSBvciBlbGltaW5hdGUKLSAgICogdGhpcyBib3VuZGFyeS4KLSAgICogQHhzbC51c2FnZSBpbnRlcm5hbAotICAgKi8KLSAgc3RhdGljIGZpbmFsIGludCBtX3VucmVhc29uYWJsZUlkPTEwMjQ7Ci0KLSAgLyoqIEludGVybmFsIGZpZWxkIHVzZWQgdG8gaG9sZCB0aGUgZGF0YSBiZWluZyBleHBsaWNpdGx5IHBhc3NlZAotICAgKiBmcm9tIG9uZSBjb3JvdXRpbmUgdG8gYW5vdGhlciBkdXJpbmcgYSBjb19yZXN1bWUoKSBvcGVyYXRpb24uCi0gICAqIChPZiBjb3Vyc2UgaW1wbGljaXQgZGF0YSBzaGFyaW5nIG1heSBhbHNvIG9jY3VyOyBvbmUgb2YgdGhlIHJlYXNvbnMKLSAgICogZm9yIHVzaW5nIGNvcm91dGluZXMgaXMgdGhhdCB5b3UncmUgZ3VhcmFudGVlZCB0aGF0IG5vbmUgb2YgdGhlCi0gICAqIG90aGVyIGNvcm91dGluZXMgaW4geW91ciBzZXQgYXJlIHVzaW5nIHNoYXJlZCBzdHJ1Y3R1cmVzIGF0IHRoZSB0aW1lCi0gICAqIHlvdSBhY2Nlc3MgdGhlbS4pCi0gICAqCi0gICAqICVSRVZJRVclIEl0J3MgYmVlbiBwcm9wb3NlZCB0aGF0IHdlIGJlIGFibGUgdG8gcGFzcyB0eXBlcyBvZiBkYXRhCi0gICAqIG90aGVyIHRoYW4gT2JqZWN0IC0tIG1vcmUgc3BlY2lmaWMgb2JqZWN0IHR5cGVzLCBvcgotICAgKiBsaWdodGVyLXdlaWdodCBwcmltaXRpdmVzLiAgVGhpcyB3b3VsZCBzZWVtIHRvIGNyZWF0ZSBhIHBvdGVudGlhbAotICAgKiBleHBsb3Npb24gb2YgInBhc3MgeCByZWNpZXZlIHkgYmFjayIgbWV0aG9kcyAob3IgcmVxdWlyZQotICAgKiBmcmFjdHVyaW5nIHJlc3VtZSBpbnRvIHR3byBjYWxscywgcmVzdW1lLW90aGVyIGFuZAotICAgKiB3YWl0LXRvLWJlLXJlc3VtZWQpLCBhbmQgdGhlIHdlaWdodCBpc3N1ZSBjb3VsZCBiZSBtYW5hZ2VkIGJ5Ci0gICAqIHJldXNpbmcgYSBtdXRhYmxlIGJ1ZmZlciBvYmplY3QgdG8gY29udGFpbiB0aGUgcHJpbWl0aXZlCi0gICAqIChyZW1lbWJlciB0aGF0IG9ubHkgb25lIGNvcm91dGluZSBydW5zIGF0IGEgdGltZSwgc28gb25jZSB0aGUKLSAgICogYnVmZmVyJ3Mgc2V0IGl0IHdvbid0IGJlIHdhbGtlZCBvbikuIFR5cGVjaGVja2luZyBvYmplY3RzIGlzCi0gICAqIGludGVyZXN0aW5nIGZyb20gYSBjb2RlLXJvYnVzdG5lc3MgcG9pbnQgb2YgdmlldywgYnV0IGl0J3MKLSAgICogdW5jbGVhciB3aGV0aGVyIGl0IG1ha2VzIHNlbnNlIHRvIGVuY2Fwc3VsYXRlIHRoYXQgaW4gdGhlCi0gICAqIGNvcm91dGluZSBjb2RlIG9yIGxldCB0aGUgY2FsbGVycyBkbyBpdCwgc2luY2UgaXQgZGVwZW5kcyBvbiBSVFRJCi0gICAqIGVpdGhlciB3YXkuIFJlc3RyaWN0aW5nIHRoZSBwYXJhbWV0ZXJzIHRvIG9iamVjdHMgaW1wbGVtZW50aW5nIGEKLSAgICogc3BlY2lmaWMgQ29yb3V0aW5lUGFyYW1ldGVyIGludGVyZmFjZSBkb2VzIF9ub3RfIHNlZW0gdG8gYmUgYSBuZXQKLSAgICogd2luOyBhcHBsaWNhdGlvbnMgY2FuIGRvIHNvIGlmIHRoZXkgd2FudCB2aWEgZnJvbnQtZW5kIGNvZGUsIGJ1dAotICAgKiB0aGVyZSBzZWVtIHRvIGJlIHRvbyBtYW55IHVzZSBjYXNlcyBpbnZvbHZpbmcgcGFzc2luZyBhbiBleGlzdGluZwotICAgKiBvYmplY3QgdHlwZSB0aGF0IHlvdSBtYXkgbm90IGhhdmUgdGhlIGZyZWVkb20gdG8gYWx0ZXIgYW5kIG1heQotICAgKiBub3Qgd2FudCB0byBzcGVuZCB0aW1lIHdyYXBwaW5nIGFub3RoZXIgb2JqZWN0IGFyb3VuZC4KLSAgICogKi8KLSAgT2JqZWN0IG1feWllbGQ9bnVsbDsKLQotICAvLyBFeHBvc2U/Pz8KLSAgZmluYWwgc3RhdGljIGludCBOT0JPRFk9LTE7Ci0gIGZpbmFsIHN0YXRpYyBpbnQgQU5ZQk9EWT0tMTsKLQotICAvKiogSW50ZXJuYWwgZmllbGQgdXNlZCB0byBjb25maXJtIHRoYXQgdGhlIGNvcm91dGluZSBub3cgd2FraW5nIHVwIGlzCi0gICAqIGluIGZhY3QgdGhlIG9uZSB3ZSBpbnRlbmRlZCB0byByZXN1bWUuIFNvbWUgc3VjaCBzZWxlY3Rpb24gbWVjaGFuaXNtCi0gICAqIGlzIG5lZWRlZCB3aGVuIG1vcmUgdGhhdCB0d28gY29yb3V0aW5lcyBhcmUgb3BlcmF0aW5nIHdpdGhpbiB0aGUgc2FtZQotICAgKiBncm91cC4KLSAgICovCi0gIGludCBtX25leHRDb3JvdXRpbmU9Tk9CT0RZOwotCi0gIC8qKiA8cD5FYWNoIGNvcm91dGluZSBpbiB0aGUgc2V0IG1hbmFnZWQgYnkgYSBzaW5nbGUKLSAgICogQ29yb3V0aW5lTWFuYWdlciBpcyBpZGVudGlmaWVkIGJ5IGEgc21hbGwgcG9zaXRpdmUgaW50ZWdlci4gVGhpcwotICAgKiBicmluZ3MgdXAgdGhlIHF1ZXN0aW9uIG9mIGhvdyB0byBtYW5hZ2UgdGhvc2UgaW50ZWdlcnMgdG8gYXZvaWQKLSAgICogcmV1c2UuLi4gc2luY2UgaWYgdHdvIGNvcm91dGluZXMgdXNlIHRoZSBzYW1lIElEIG51bWJlciwgcmVzdW1pbmcKLSAgICogdGhhdCBJRCBjb3VsZCByZXN1bWUgZWl0aGVyLiBJIGNhbiBzZWUgYXJndW1lbnRzIGZvciBlaXRoZXIKLSAgICogYWxsb3dpbmcgYXBwbGljYXRpb25zIHRvIHNlbGVjdCB0aGVpciBvd24gbnVtYmVycyAodGhleSBtYXkgd2FudAotICAgKiB0byBkZWNsYXJlIG1uZW1vbmljcyB2aWEgbWFuZWZlc3QgY29uc3RhbnRzKSBvciBnZW5lcmF0aW5nCi0gICAqIG51bWJlcnMgb24gZGVtYW5kLiAgVGhpcyByb3V0aW5lJ3MgaW50ZW5kZWQgdG8gc3VwcG9ydCBib3RoCi0gICAqIGFwcHJvYWNoZXMuPC9wPgotICAgKgotICAgKiA8cD4lUkVWSUVXJSBXZSBjb3VsZCB1c2UgYW4gb2JqZWN0IGFzIHRoZSBpZGVudGlmaWVyLiBOb3Qgc3VyZQotICAgKiBpdCdzIGEgbmV0IGdhaW4sIHRob3VnaCBpdCB3b3VsZCBhbGxvdyB0aGUgdGhyZWFkIHRvIGJlIGl0cyBvd24KLSAgICogSUQuIFBvbmRlci48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBjb3JvdXRpbmVJRCAgSWYgPj0wLCByZXF1ZXN0cyB0aGF0IHdlIHJlc2VydmUgdGhpcyBudW1iZXIuCi0gICAqIElmIDwwLCByZXF1ZXN0cyB0aGF0IHdlIGZpbmQsIHJlc2VydmUsIGFuZCByZXR1cm4gYW4gYXZhaWxhYmxlIElECi0gICAqIG51bWJlci4KLSAgICoKLSAgICogQHJldHVybiBJZiA+PTAsIHRoZSBJRCBudW1iZXIgdG8gYmUgdXNlZCBieSB0aGlzIGNvcm91dGluZS4gSWYgPDAsCi0gICAqIGFuIGVycm9yIG9jY3VycmVkIC0tIHRoZSBJRCByZXF1ZXN0ZWQgd2FzIGFscmVhZHkgaW4gdXNlLCBvciB3ZQotICAgKiBjb3VsZG4ndCBhc3NpZ24gb25lIHdpdGhvdXQgZ29pbmcgb3ZlciB0aGUgInVucmVhc29uYWJsZSB2YWx1ZSIgbWFyawotICAgKiAqLwotICBwdWJsaWMgc3luY2hyb25pemVkIGludCBjb19qb2luQ29yb3V0aW5lU2V0KGludCBjb3JvdXRpbmVJRCkKLSAgewotICAgIGlmKGNvcm91dGluZUlEPj0wKQotICAgICAgewotICAgICAgICBpZihjb3JvdXRpbmVJRD49bV91bnJlYXNvbmFibGVJZCB8fCBtX2FjdGl2ZUlEcy5nZXQoY29yb3V0aW5lSUQpKQotICAgICAgICAgIHJldHVybiAtMTsKLSAgICAgIH0KLSAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIC8vIFdoYXQgSSB3YW50IGlzICJGaW5kIGZpcnN0IGNsZWFyIGJpdCIuIFRoYXQgZG9lc24ndCBleGlzdC4KLSAgICAgICAgLy8gSkRLMS4yIGFkZGVkICJmaW5kIGxhc3Qgc2V0IGJpdCIsIGJ1dCB0aGF0IGRvZXNuJ3QgaGVscCBub3cuCi0gICAgICAgIGNvcm91dGluZUlEPTA7Ci0gICAgICAgIHdoaWxlKGNvcm91dGluZUlEPG1fdW5yZWFzb25hYmxlSWQpCi0gICAgICAgICAgewotICAgICAgICAgICAgaWYobV9hY3RpdmVJRHMuZ2V0KGNvcm91dGluZUlEKSkKLSAgICAgICAgICAgICAgKytjb3JvdXRpbmVJRDsKLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgfQotICAgICAgICBpZihjb3JvdXRpbmVJRD49bV91bnJlYXNvbmFibGVJZCkKLSAgICAgICAgICByZXR1cm4gLTE7Ci0gICAgICB9Ci0KLSAgICBtX2FjdGl2ZUlEcy5zZXQoY29yb3V0aW5lSUQpOwotICAgIHJldHVybiBjb3JvdXRpbmVJRDsKLSAgfQotCi0gIC8qKiBJbiB0aGUgc3RhbmRhcmQgY29yb3V0aW5lIGFyY2hpdGVjdHVyZSwgY29yb3V0aW5lcyBhcmUKLSAgICogaWRlbnRpZmllZCBieSB0aGVpciBtZXRob2QgbmFtZXMgYW5kIGFyZSBsYXVuY2hlZCBhbmQgcnVuIHVwIHRvCi0gICAqIHRoZWlyIGZpcnN0IHlpZWxkIGJ5IHNpbXBseSByZXN1bWluZyB0aGVtOyBpdHMncyBwcmVzdW1lZCB0aGF0Ci0gICAqIHRoaXMgcmVjb2duaXplcyB0aGUgbm90LWFscmVhZHktcnVubmluZyBjYXNlIGFuZCBkb2VzIHRoZSByaWdodAotICAgKiB0aGluZy4gV2Ugc2VlbSB0byBuZWVkIGEgd2F5IHRvIGFjaGlldmUgdGhhdCBzYW1lIHRocmVhZHNhZmUKLSAgICogcnVuLXVwLi4uICBlZywgc3RhcnQgdGhlIGNvcm91dGluZSB3aXRoIGEgd2FpdC4KLSAgICoKLSAgICogJVRCRCUgd2hldGhlciB0aGlzIG1ha2VzIGFueSBzZW5zZS4uLgotICAgKgotICAgKiBAcGFyYW0gdGhpc0Nvcm91dGluZSB0aGUgaWRlbnRpZmllciBvZiB0aGlzIGNvcm91dGluZSwgc28gd2UgY2FuCi0gICAqIHJlY29nbml6ZSB3aGVuIHdlIGFyZSBiZWluZyByZXN1bWVkLgotICAgKiBAZXhjZXB0aW9uIGphdmEubGFuZy5Ob1N1Y2hNZXRob2RFeGNlcHRpb24gaWYgdGhpc0Nvcm91dGluZSBpc24ndAotICAgKiBhIHJlZ2lzdGVyZWQgbWVtYmVyIG9mIHRoaXMgZ3JvdXAuICVSRVZJRVclIHdoZXRoZXIgdGhpcyBpcyB0aGUKLSAgICogYmVzdCBjaG9pY2UuCi0gICAqICovCi0gIHB1YmxpYyBzeW5jaHJvbml6ZWQgT2JqZWN0IGNvX2VudHJ5X3BhdXNlKGludCB0aGlzQ29yb3V0aW5lKSB0aHJvd3MgamF2YS5sYW5nLk5vU3VjaE1ldGhvZEV4Y2VwdGlvbgotICB7Ci0gICAgaWYoIW1fYWN0aXZlSURzLmdldCh0aGlzQ29yb3V0aW5lKSkKLSAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTm9TdWNoTWV0aG9kRXhjZXB0aW9uKCk7Ci0KLSAgICB3aGlsZShtX25leHRDb3JvdXRpbmUgIT0gdGhpc0Nvcm91dGluZSkKLSAgICAgIHsKLSAgICAgICAgdHJ5Ci0gICAgICAgICAgewotICAgICAgICAgICAgd2FpdCgpOwotICAgICAgICAgIH0KLSAgICAgICAgY2F0Y2goamF2YS5sYW5nLkludGVycnVwdGVkRXhjZXB0aW9uIGUpCi0gICAgICAgICAgewotICAgICAgICAgICAgLy8gJVRCRCUgLS0gRGVjbGFyZT8gRW5jYXBzdWxhdGU/IElnbm9yZT8gT3IKLSAgICAgICAgICAgIC8vIGRhbmNlIHdpZGRlcnNoaW5zIGFib3V0IHRoZSBpbnN0cnVjdGlvbiBjYWNoZT8KLSAgICAgICAgICB9Ci0gICAgICB9Ci0KLSAgICByZXR1cm4gbV95aWVsZDsKLSAgfQotCi0gIC8qKiBUcmFuc2ZlciBjb250cm9sIHRvIGFub3RoZXIgY29yb3V0aW5lIHdoaWNoIGhhcyBhbHJlYWR5IGJlZW4gc3RhcnRlZCBhbmQKLSAgICogaXMgd2FpdGluZyBvbiB0aGlzIENvcm91dGluZU1hbmFnZXIuIFdlIHdvbid0IHJldHVybiBmcm9tIHRoaXMgY2FsbAotICAgKiB1bnRpbCB0aGF0IHJvdXRpbmUgaGFzIHJlbGlucXVpc2hlZCBjb250cm9sLgotICAgKgotICAgKiAlVEJEJSBXaGF0IHNob3VsZCB3ZSBkbyBpZiB0b0Nvcm91dGluZSBpc24ndCByZWdpc3RlcmVkPyBFeGNlcHRpb24/Ci0gICAqCi0gICAqIEBwYXJhbSBhcmdfb2JqZWN0IEEgdmFsdWUgdG8gYmUgcGFzc2VkIHRvIHRoZSBvdGhlciBjb3JvdXRpbmUuCi0gICAqIEBwYXJhbSB0aGlzQ29yb3V0aW5lIEludGVnZXIgaWRlbnRpZmllciBmb3IgdGhpcyBjb3JvdXRpbmUuIFRoaXMgaXMgdGhlCi0gICAqIElEIHdlIHdhdGNoIGZvciB0byBzZWUgaWYgd2UncmUgdGhlIG9uZXMgYmVpbmcgcmVzdW1lZC4KLSAgICogQHBhcmFtIHRvQ29yb3V0aW5lICBJbnRlZ2VyIGlkZW50aWZpZXIgZm9yIHRoZSBjb3JvdXRpbmUgd2Ugd2lzaCB0bwotICAgKiBpbnZva2UuCi0gICAqIEBleGNlcHRpb24gamF2YS5sYW5nLk5vU3VjaE1ldGhvZEV4Y2VwdGlvbiBpZiB0b0Nvcm91dGluZSBpc24ndCBhCi0gICAqIHJlZ2lzdGVyZWQgbWVtYmVyIG9mIHRoaXMgZ3JvdXAuICVSRVZJRVclIHdoZXRoZXIgdGhpcyBpcyB0aGUgYmVzdCBjaG9pY2UuCi0gICAqICovCi0gIHB1YmxpYyBzeW5jaHJvbml6ZWQgT2JqZWN0IGNvX3Jlc3VtZShPYmplY3QgYXJnX29iamVjdCxpbnQgdGhpc0Nvcm91dGluZSxpbnQgdG9Db3JvdXRpbmUpIHRocm93cyBqYXZhLmxhbmcuTm9TdWNoTWV0aG9kRXhjZXB0aW9uCi0gIHsKLSAgICBpZighbV9hY3RpdmVJRHMuZ2V0KHRvQ29yb3V0aW5lKSkKLSAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTm9TdWNoTWV0aG9kRXhjZXB0aW9uKFhNTE1lc3NhZ2VzLmNyZWF0ZVhNTE1lc3NhZ2UoWE1MRXJyb3JSZXNvdXJjZXMuRVJfQ09ST1VUSU5FX05PVF9BVkFJTCwgbmV3IE9iamVjdFtde0ludGVnZXIudG9TdHJpbmcodG9Db3JvdXRpbmUpfSkpOyAvLyJDb3JvdXRpbmUgbm90IGF2YWlsYWJsZSwgaWQ9Iit0b0Nvcm91dGluZSk7Ci0KLSAgICAvLyBXZSBleHBlY3QgdGhlc2UgdmFsdWVzIHRvIGJlIG92ZXJ3cml0dGVuIGR1cmluZyB0aGUgbm90aWZ5KCkvd2FpdCgpCi0gICAgLy8gcGVyaW9kcywgYXMgb3RoZXIgY29yb3V0aW5lcyBpbiB0aGlzIHNldCBnZXQgdGhlaXIgb3Bwb3J0dW5pdHkgdG8gcnVuLgotICAgIG1feWllbGQ9YXJnX29iamVjdDsKLSAgICBtX25leHRDb3JvdXRpbmU9dG9Db3JvdXRpbmU7Ci0KLSAgICBub3RpZnkoKTsKLSAgICB3aGlsZShtX25leHRDb3JvdXRpbmUgIT0gdGhpc0Nvcm91dGluZSB8fCBtX25leHRDb3JvdXRpbmU9PUFOWUJPRFkgfHwgbV9uZXh0Q29yb3V0aW5lPT1OT0JPRFkpCi0gICAgICB7Ci0gICAgICAgIHRyeQotICAgICAgICAgIHsKLSAgICAgICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigid2FpdGluZy4uLiIpOwotICAgICAgICAgICAgd2FpdCgpOwotICAgICAgICAgIH0KLSAgICAgICAgY2F0Y2goamF2YS5sYW5nLkludGVycnVwdGVkRXhjZXB0aW9uIGUpCi0gICAgICAgICAgewotICAgICAgICAgICAgLy8gJVRCRCUgLS0gRGVjbGFyZT8gRW5jYXBzdWxhdGU/IElnbm9yZT8gT3IKLSAgICAgICAgICAgIC8vIGRhbmNlIGRlYXNpbCBhYm91dCB0aGUgcHJvZ3JhbSBjb3VudGVyPwotICAgICAgICAgIH0KLSAgICAgIH0KLQotICAgIGlmKG1fbmV4dENvcm91dGluZT09Tk9CT0RZKQotICAgICAgewotICAgICAgICAvLyBQYXNzIGl0IGFsb25nCi0gICAgICAgIGNvX2V4aXQodGhpc0Nvcm91dGluZSk7Ci0gICAgICAgIC8vIEFuZCBpbmZvcm0gdGhpcyBjb3JvdXRpbmUgdGhhdCBpdHMgcGFydG5lcnMgYXJlIEdvaW5nIEF3YXkKLSAgICAgICAgLy8gJVJFVklFVyUgU2hvdWxkIHRoaXMgdGhyb3cvcmV0dXJuIHNvbWV0aGluZyBtb3JlIHVzZWZ1bD8KLSAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5Ob1N1Y2hNZXRob2RFeGNlcHRpb24oWE1MTWVzc2FnZXMuY3JlYXRlWE1MTWVzc2FnZShYTUxFcnJvclJlc291cmNlcy5FUl9DT1JPVVRJTkVfQ09fRVhJVCwgbnVsbCkpOyAvLyJDb3JvdXRpbmVNYW5hZ2VyIHJlY2lldmVkIGNvX2V4aXQoKSByZXF1ZXN0Iik7Ci0gICAgICB9Ci0KLSAgICByZXR1cm4gbV95aWVsZDsKLSAgfQotCi0gIC8qKiBUZXJtaW5hdGUgdGhpcyBlbnRpcmUgc2V0IG9mIGNvcm91dGluZXMuIFRoZSBvdGhlcnMgd2lsbCBiZQotICAgKiBkZXJlZ2lzdGVyZWQgYW5kIGhhdmUgZXhjZXB0aW9ucyB0aHJvd24gYXQgdGhlbS4gTm90ZSB0aGF0IHRoaXMKLSAgICogaXMgaW50ZW5kZWQgYXMgYSBwYW5pYy1zaHV0ZG93biBvcGVyYXRpb247IHVuZGVyIG5vcm1hbAotICAgKiBjaXJjdW1zdGFuY2VzIGEgY29yb3V0aW5lIHNob3VsZCBhbHdheXMgZW5kIHdpdGggY29fZXhpdF90bygpIGluCi0gICAqIG9yZGVyIHRvIHBvbGl0ZWx5IGluZm9ybSBhdCBsZWFzdCBvbmUgb2YgaXRzIHBhcnRuZXJzIHRoYXQgaXQgaXMKLSAgICogZ29pbmcgYXdheS4KLSAgICoKLSAgICogJVRCRCUgVGhpcyBtYXkgbmVlZCBzaWduaWZpY2FudGx5IG1vcmUgd29yay4KLSAgICoKLSAgICogJVRCRCUgU2hvdWxkIHRoaXMganVzdCBiZSBjb19leGl0X3RvKCwsQ29yb3V0aW5lTWFuYWdlci5QQU5JQyk/Ci0gICAqCi0gICAqIEBwYXJhbSB0aGlzQ29yb3V0aW5lIEludGVnZXIgaWRlbnRpZmllciBmb3IgdGhlIGNvcm91dGluZSByZXF1ZXN0aW5nIGV4aXQuCi0gICAqICovCi0gIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBjb19leGl0KGludCB0aGlzQ29yb3V0aW5lKQotICB7Ci0gICAgbV9hY3RpdmVJRHMuY2xlYXIodGhpc0Nvcm91dGluZSk7Ci0gICAgbV9uZXh0Q29yb3V0aW5lPU5PQk9EWTsgLy8gJVJFVklFVyUKLSAgICBub3RpZnkoKTsKLSAgfQotCi0gIC8qKiBNYWtlIHRoZSBJRCBhdmFpbGFibGUgZm9yIHJldXNlIGFuZCB0ZXJtaW5hdGUgdGhpcyBjb3JvdXRpbmUsCi0gICAqIHRyYW5zZmVycmluZyBjb250cm9sIHRvIHRoZSBzcGVjaWZpZWQgY29yb3V0aW5lLiBOb3RlIHRoYXQgdGhpcwotICAgKiByZXR1cm5zIGltbWVkaWF0ZWx5IHJhdGhlciB0aGFuIHdhaXRpbmcgZm9yIGFueSBmdXJ0aGVyIGNvcm91dGluZQotICAgKiB0cmFmZmljLCBzbyB0aGUgdGhyZWFkIGNhbiBwcm9jZWVkIHdpdGggb3RoZXIgc2h1dGRvd24gYWN0aXZpdGllcy4KLSAgICoKLSAgICogQHBhcmFtIGFyZ19vYmplY3QgICAgQSB2YWx1ZSB0byBiZSBwYXNzZWQgdG8gdGhlIG90aGVyIGNvcm91dGluZS4KLSAgICogQHBhcmFtIHRoaXNDb3JvdXRpbmUgSW50ZWdlciBpZGVudGlmaWVyIGZvciB0aGUgY29yb3V0aW5lIGxlYXZpbmcgdGhlIHNldC4KLSAgICogQHBhcmFtIHRvQ29yb3V0aW5lICAgSW50ZWdlciBpZGVudGlmaWVyIGZvciB0aGUgY29yb3V0aW5lIHdlIHdpc2ggdG8KLSAgICogaW52b2tlLgotICAgKiBAZXhjZXB0aW9uIGphdmEubGFuZy5Ob1N1Y2hNZXRob2RFeGNlcHRpb24gaWYgdG9Db3JvdXRpbmUgaXNuJ3QgYQotICAgKiByZWdpc3RlcmVkIG1lbWJlciBvZiB0aGlzIGdyb3VwLiAlUkVWSUVXJSB3aGV0aGVyIHRoaXMgaXMgdGhlIGJlc3QgY2hvaWNlLgotICAgKiAqLwotICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgY29fZXhpdF90byhPYmplY3QgYXJnX29iamVjdCxpbnQgdGhpc0Nvcm91dGluZSxpbnQgdG9Db3JvdXRpbmUpIHRocm93cyBqYXZhLmxhbmcuTm9TdWNoTWV0aG9kRXhjZXB0aW9uCi0gIHsKLSAgICBpZighbV9hY3RpdmVJRHMuZ2V0KHRvQ29yb3V0aW5lKSkKLSAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTm9TdWNoTWV0aG9kRXhjZXB0aW9uKFhNTE1lc3NhZ2VzLmNyZWF0ZVhNTE1lc3NhZ2UoWE1MRXJyb3JSZXNvdXJjZXMuRVJfQ09ST1VUSU5FX05PVF9BVkFJTCwgbmV3IE9iamVjdFtde0ludGVnZXIudG9TdHJpbmcodG9Db3JvdXRpbmUpfSkpOyAvLyJDb3JvdXRpbmUgbm90IGF2YWlsYWJsZSwgaWQ9Iit0b0Nvcm91dGluZSk7Ci0KLSAgICAvLyBXZSBleHBlY3QgdGhlc2UgdmFsdWVzIHRvIGJlIG92ZXJ3cml0dGVuIGR1cmluZyB0aGUgbm90aWZ5KCkvd2FpdCgpCi0gICAgLy8gcGVyaW9kcywgYXMgb3RoZXIgY29yb3V0aW5lcyBpbiB0aGlzIHNldCBnZXQgdGhlaXIgb3Bwb3J0dW5pdHkgdG8gcnVuLgotICAgIG1feWllbGQ9YXJnX29iamVjdDsKLSAgICBtX25leHRDb3JvdXRpbmU9dG9Db3JvdXRpbmU7Ci0KLSAgICBtX2FjdGl2ZUlEcy5jbGVhcih0aGlzQ29yb3V0aW5lKTsKLQotICAgIG5vdGlmeSgpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vcmVmL0Nvcm91dGluZVBhcnNlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL3JlZi9Db3JvdXRpbmVQYXJzZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNTdjNzcyNC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vcmVmL0Nvcm91dGluZVBhcnNlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTQyICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IENvcm91dGluZVBhcnNlci5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE1IDA4OjE0OjU5IHN1cmVzaF9lbWFpbGlkIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5yZWY7Ci0KLWltcG9ydCBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKLWltcG9ydCBvcmcueG1sLnNheC5YTUxSZWFkZXI7Ci0KLS8qKiA8cD5Db3JvdXRpbmVQYXJzZXIgaXMgYW4gQVBJIGZvciBwYXJzZXIgdGhyZWFkcyB0aGF0IG9wZXJhdGUgYXMKLSAqIGNvcm91dGluZXMuIFNlZSBDb3JvdXRpbmVTQVhQYXJzZXIgYW5kIENvcm91dGluZVNBWFBhcnNlcl9YZXJjZXMKLSAqIGZvciBleGFtcGxlcy48L3A+Ci0gKgotICogPHA+Jmx0O2dydW1ibGUmZ3Q7IEknZCBsaWtlIHRoZSBpbnRlcmZhY2UgdG8gcmVxdWlyZSBhIHNwZWNpZmljIGZvcm0KLSAqIGZvciBlaXRoZXIgdGhlIGJhc2UgY29uc3RydWN0b3Igb3IgYSBzdGF0aWMgZmFjdG9yeSBtZXRob2QuIEphdmEKLSAqIGRvZXNuJ3QgYWxsb3cgdXMgdG8gc3BlY2lmeSBlaXRoZXIsIHNvIEknbGwganVzdCBkb2N1bWVudCB0aGVtCi0gKiBoZXJlOgotICoKLSAqIDx1bD4KLSAqIDxsaT5wdWJsaWMgQ29yb3V0aW5lUGFyc2VyKENvcm91dGluZU1hbmFnZXIgY28sIGludCBhcHBDb3JvdXRpbmUpOzwvbGk+Ci0gKiA8bGk+cHVibGljIENvcm91dGluZVBhcnNlciBjcmVhdGVDb3JvdXRpbmVQYXJzZXIoQ29yb3V0aW5lTWFuYWdlciBjbywgaW50IGFwcENvcm91dGluZSk7PC9saT4KLSAqIDwvdWw+Ci0gKgotICogJmx0Oy9ncnVtYmxlJmd0OzwvcD4KLSAqCi0gKiBAZGVwcmVjYXRlZCBTaW5jZSB0aGUgYWJpbGl0eSB0byBzdGFydCBhIHBhcnNlIHZpYSB0aGUKLSAqIGNvcm91dGluZSBwcm90b2NvbCB3YXMgbm90IGJlaW5nIHVzZWQgYW5kIHdhcyBjb21wbGljYXRpbmcgZGVzaWduLgotICogU2VlIHtAbGluayBJbmNyZW1lbnRhbFNBWFNvdXJjZX0uCi0gKiAqLwotcHVibGljIGludGVyZmFjZSBDb3JvdXRpbmVQYXJzZXIgewotCi0gICAgLyoqIEByZXR1cm4gdGhlIGNvcm91dGluZSBJRCBudW1iZXIgZm9yIHRoaXMgQ29yb3V0aW5lUGFyc2VyIG9iamVjdC4KLSAgICAgKiBOb3RlIHRoYXQgdGhpcyBpc24ndCB1c2VmdWwgdW5sZXNzIHlvdSBrbm93IHdoaWNoIENvcm91dGluZU1hbmFnZXIKLSAgICAgKiB5b3UncmUgdGFsa2luZyB0by4gQWxzbyBub3RlIHRoYXQgdGhlIGRvLi4uKCkgbWV0aG9kcyBlbmNhcHN1bGF0ZQotICAgICAqIHRoZSBjb21tb24gdHJhbnNhY3Rpb25zIHdpdGggdGhlIENvcm91dGluZVBhcnNlciwgc28geW91IHNob3VsZG4ndAotICAgICAqIG5lZWQgdGhpcyBpbiBtb3N0IGNhc2VzLgotICAgICAqICovCi0gICAgcHVibGljIGludCBnZXRQYXJzZXJDb3JvdXRpbmVJRCgpOwotCi0gICAgLyoqIEByZXR1cm4gdGhlIENvcm91dGluZU1hbmFnZXIgZm9yIHRoaXMgQ29yb3V0aW5lUGFyc2VyIG9iamVjdC4KLSAgICAgKiBJZiB5b3UncmUgdXNpbmcgdGhlIGRvLi4uKCkgbWV0aG9kcywgYXBwbGljYXRpb25zIHNob3VsZCBvbmx5Ci0gICAgICogbmVlZCB0byB0YWxrIHRvIHRoZSBDb3JvdXRpbmVNYW5hZ2VyIG9uY2UsIHRvIG9idGFpbiB0aGUKLSAgICAgKiBhcHBsaWNhdGlvbidzIENvcm91dGluZSBJRC4KLSAgICAgKiAqLwotICAgIHB1YmxpYyBDb3JvdXRpbmVNYW5hZ2VyIGdldENvcm91dGluZU1hbmFnZXIoKTsKLQotICAvKiogUmVnaXN0ZXIgYSBTQVgtc3R5bGUgY29udGVudCBoYW5kbGVyIGZvciB1cyB0byBvdXRwdXQgdG8gKi8KLSAgcHVibGljIHZvaWQgc2V0Q29udGVudEhhbmRsZXIoQ29udGVudEhhbmRsZXIgaGFuZGxlcik7Ci0KLSAgLyoqICBSZWdpc3RlciBhIFNBWC1zdHlsZSBsZXhpY2FsIGhhbmRsZXIgZm9yIHVzIHRvIG91dHB1dCB0bwotICAgKiAgTm90IGFsbCBwYXJzZXJzIHN1cHBvcnQgdGhpcy4uLgotICAgKgotICAgKiAlUkVWSUVXJSBOb3QgY2FsbGVkIHNldExleGljYWxIYW5kbGVyIGJlY2F1c2UgWGFsYW4gdXNlcyB0aGF0IG5hbWUKLSAgICogaW50ZXJuYWxseSwgd2hpY2ggY2F1c2VzIHN1YmNsYXNzaW5nIG51aXNhbmNlcy4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldExleEhhbmRsZXIob3JnLnhtbC5zYXguZXh0LkxleGljYWxIYW5kbGVyIGhhbmRsZXIpOwotCi0gIC8qIFRoZSBydW4oKSBtZXRob2QgaXMgcmVxdWlyZWQgaW4gQ29yb3V0aW5lUGFyc2VycyB0aGF0IHJ1biBhcwotICAgKiB0aHJlYWRzIChvZiBjb3Vyc2UpLi4uIGJ1dCBpdCBpc24ndCBwYXJ0IG9mIG91ciBBUEksIGFuZAotICAgKiBzaG91bGRuJ3QgYmUgZGVjbGFyZWQgaGVyZS4KLSAgICogKi8KLQotICAvLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAgLyoqIGRvUGFyc2UoKSBpcyBhIHNpbXBsZSBBUEkgd2hpY2ggdGVsbHMgdGhlIGNvcm91dGluZSBwYXJzZXIKLSAgICogdG8gYmVnaW4gcmVhZGluZyBmcm9tIGEgZmlsZS4gIFRoaXMgaXMgaW50ZW5kZWQgdG8gYmUgY2FsbGVkIGZyb20gb25lCi0gICAqIG9mIG91ciBwYXJ0bmVyIGNvcm91dGluZXMsIGFuZCBzZXJ2ZXMgYm90aCB0byBlbmNhcHN1bGF0ZSB0aGUKLSAgICogY29tbXVuaWNhdGlvbiBwcm90b2NvbCBhbmQgdG8gYXZvaWQgaGF2aW5nIHRvIGV4cGxpY2l0bHkgdXNlIHRoZQotICAgKiBDb3JvdXRpbmVQYXJzZXIncyBjb3JvdXRpbmUgSUQgbnVtYmVyLgotICAgKgotICAgKiAlUkVWSUVXJSBDYW4vc2hvdWxkIHRoaXMgdW5pZnkgd2l0aCBkb01vcmU/IChpZiBVUkkgaGFzbid0IGNoYW5nZWQsCi0gICAqIHBhcnNlIG1vcmUgZnJvbSBzYW1lIGZpbGUsIGVsc2UgZW5kIGFuZCByZXN0YXJ0IHBhcnNpbmcuLi4/Ci0gICAqCi0gICAqIEBwYXJhbSBzb3VyY2UgVGhlIElucHV0U291cmNlIHRvIHBhcnNlIGZyb20uCi0gICAqIEBwYXJhbSBhcHBDb3JvdXRpbmUgVGhlIGNvcm91dGluZSBJRCBudW1iZXIgb2YgdGhlIGNvcm91dGluZSBpbnZva2luZwotICAgKiB0aGlzIG1ldGhvZCwgc28gaXQgY2FuIGJlIHJlc3VtZWQgYWZ0ZXIgdGhlIHBhcnNlciBoYXMgcmVzcG9uZGVkIHRvIHRoZQotICAgKiByZXF1ZXN0LgotICAgKiBAcmV0dXJuIEJvb2xlYW4uVFJVRSBpZiB0aGUgQ29yb3V0aW5lUGFyc2VyIGJlbGlldmVzIG1vcmUgZGF0YSBtYXkgYmUgYXZhaWxhYmxlCi0gICAqIGZvciBmdXJ0aGVyIHBhcnNpbmcuIEJvb2xlYW4uRkFMU0UgaWYgcGFyc2luZyByYW4gdG8gY29tcGxldGlvbi4KLSAgICogRXhjZXB0aW9uIGlmIHRoZSBwYXJzZXIgb2JqZWN0ZWQgZm9yIHNvbWUgcmVhc29uLgotICAgKiAqLwotICBwdWJsaWMgT2JqZWN0IGRvUGFyc2UoSW5wdXRTb3VyY2Ugc291cmNlLCBpbnQgYXBwQ29yb3V0aW5lKTsKLQotICAvKiogZG9Nb3JlKCkgaXMgYSBzaW1wbGUgQVBJIHdoaWNoIHRlbGxzIHRoZSBjb3JvdXRpbmUgcGFyc2VyCi0gICAqIHRoYXQgd2UgbmVlZCBtb3JlIG5vZGVzLiAgVGhpcyBpcyBpbnRlbmRlZCB0byBiZSBjYWxsZWQgZnJvbSBvbmUKLSAgICogb2Ygb3VyIHBhcnRuZXIgY29yb3V0aW5lcywgYW5kIHNlcnZlcyBib3RoIHRvIGVuY2Fwc3VsYXRlIHRoZQotICAgKiBjb21tdW5pY2F0aW9uIHByb3RvY29sIGFuZCB0byBhdm9pZCBoYXZpbmcgdG8gZXhwbGljaXRseSB1c2UgdGhlCi0gICAqIENvcm91dGluZVBhcnNlcidzIGNvcm91dGluZSBJRCBudW1iZXIuCi0gICAqCi0gICAqIEBwYXJhbSBwYXJzZW1vcmUgSWYgdHJ1ZSwgdGVsbHMgdGhlIGluY3JlbWVudGFsIHBhcnNlciB0byBnZW5lcmF0ZQotICAgKiBhbm90aGVyIGNodW5rIG9mIG91dHB1dC4gSWYgZmFsc2UsIHRlbGxzIHRoZSBwYXJzZXIgdGhhdCB3ZSdyZQotICAgKiBzYXRpc2ZpZWQgYW5kIGl0IGNhbiB0ZXJtaW5hdGUgcGFyc2luZyBvZiB0aGlzIGRvY3VtZW50LgotICAgKiBAcGFyYW0gYXBwQ29yb3V0aW5lIFRoZSBjb3JvdXRpbmUgSUQgbnVtYmVyIG9mIHRoZSBjb3JvdXRpbmUgaW52b2tpbmcKLSAgICogdGhpcyBtZXRob2QsIHNvIGl0IGNhbiBiZSByZXN1bWVkIGFmdGVyIHRoZSBwYXJzZXIgaGFzIHJlc3BvbmRlZCB0byB0aGUKLSAgICogcmVxdWVzdC4KLSAgICogQHJldHVybiBCb29sZWFuLlRSVUUgaWYgdGhlIENvcm91dGluZVBhcnNlciBiZWxpZXZlcyBtb3JlIGRhdGEgbWF5IGJlIGF2YWlsYWJsZQotICAgKiBmb3IgZnVydGhlciBwYXJzaW5nLiBCb29sZWFuLkZBTFNFIGlmIHBhcnNpbmcgcmFuIHRvIGNvbXBsZXRpb24uCi0gICAqIEV4Y2VwdGlvbiBpZiB0aGUgcGFyc2VyIG9iamVjdGVkIGZvciBzb21lIHJlYXNvbi4KLSAgICogKi8KLSAgcHVibGljIE9iamVjdCBkb01vcmUgKGJvb2xlYW4gcGFyc2Vtb3JlLCBpbnQgYXBwQ29yb3V0aW5lKTsKLQotICAvKiogZG9UZXJtaW5hdGUoKSBpcyBhIHNpbXBsZSBBUEkgd2hpY2ggdGVsbHMgdGhlIGNvcm91dGluZQotICAgKiBwYXJzZXIgdG8gdGVybWluYXRlIGl0c2VsZi4gIFRoaXMgaXMgaW50ZW5kZWQgdG8gYmUgY2FsbGVkIGZyb20KLSAgICogb25lIG9mIG91ciBwYXJ0bmVyIGNvcm91dGluZXMsIGFuZCBzZXJ2ZXMgYm90aCB0byBlbmNhcHN1bGF0ZSB0aGUKLSAgICogY29tbXVuaWNhdGlvbiBwcm90b2NvbCBhbmQgdG8gYXZvaWQgaGF2aW5nIHRvIGV4cGxpY2l0bHkgdXNlIHRoZQotICAgKiBDb3JvdXRpbmVQYXJzZXIncyBjb3JvdXRpbmUgSUQgbnVtYmVyLgotICAgKgotICAgKiBSZXR1cm5zIG9ubHkgYWZ0ZXIgdGhlIENvcm91dGluZVBhcnNlciBoYXMgYWNrbm93bGVkZ2VkIHRoZSByZXF1ZXN0LgotICAgKgotICAgKiBAcGFyYW0gYXBwQ29yb3V0aW5lIFRoZSBjb3JvdXRpbmUgSUQgbnVtYmVyIG9mIHRoZSBjb3JvdXRpbmUgaW52b2tpbmcKLSAgICogdGhpcyBtZXRob2QsIHNvIGl0IGNhbiBiZSByZXN1bWVkIGFmdGVyIHRoZSBwYXJzZXIgaGFzIHJlc3BvbmRlZCB0byB0aGUKLSAgICogcmVxdWVzdC4KLSAgICogKi8KLSAgcHVibGljIHZvaWQgZG9UZXJtaW5hdGUoaW50IGFwcENvcm91dGluZSk7Ci0KLSAgLyoqCi0gICAqIEluaXRpYWxpemUgdGhlIGNvcm91dGluZSBwYXJzZXIuIFNhbWUgcGFyYW1ldGVycyBjb3VsZCBiZSBwYXNzZWQKLSAgICogaW4gYSBub24tZGVmYXVsdCBjb25zdHJ1Y3Rvciwgb3IgYnkgdXNpbmcgdXNpbmcgY29udGV4dCBDbGFzc0xvYWRlcgotICAgKiBhbmQgbmV3SW5zdGFuY2UgYW5kIHRoZW4gY2FsbGluZyBpbml0KCkKLSAgICovCi0gIHB1YmxpYyB2b2lkIGluaXQoIENvcm91dGluZU1hbmFnZXIgY28sIGludCBhcHBDb3JvdXRpbmVJRCwgWE1MUmVhZGVyIHBhcnNlciApOwotCi19IC8vIGNsYXNzIENvcm91dGluZVBhcnNlcgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL3JlZi9DdXN0b21TdHJpbmdQb29sLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vcmVmL0N1c3RvbVN0cmluZ1Bvb2wuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZjIwYzE1MS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vcmVmL0N1c3RvbVN0cmluZ1Bvb2wuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDkxICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKi8KLS8qCi0gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKLSAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAotICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgotICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKLSAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCi0gKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IEN1c3RvbVN0cmluZ1Bvb2wuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNSAwODoxNDo1OSBzdXJlc2hfZW1haWxpZCBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLnJlZjsKLQotaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwotaW1wb3J0IGphdmEudXRpbC5NYXA7Ci0KLS8qKgotICogQ3VzdG9tU3RyaW5nUG9vbCBpcyBhbiBleGFtcGxlIG9mIGFuIGFwcGxpY2F0aW9uLXByb3ZpZGVkIGRhdGEgc3RydWN0dXJlIGZvciBhCi0gKiBEVE0gaW1wbGVtZW50YXRpb24gdG8gaG9sZCBzeW1ib2wgcmVmZXJlbmNlcywgZS5nLiBlbGVtZW50IG5hbWVzLiBJdCB3aWxsCi0gKiBmb2xsb3cgdGhlIERUTVN0cmluZ1Bvb2wgaW50ZXJmYWNlIGFuZCB1c2UgdHdvIHNpbXBsZSBtZXRob2RzCi0gKiBpbmRleFRvU3RyaW5nKGludCBpKSBhbmQgc3RyaW5nVG9JbmRleChTdHJpbmcgcykgdG8gbWFwIGJldHdlZW4gYSBzZXQgb2YKLSAqIHN0cmluZyB2YWx1ZXMgYW5kIGEgc2V0IG9mIGludGVnZXIgaW5kZXggdmFsdWVzLiBUaGVyZWZvcmUsIGFuIGFwcGxpY2F0aW9uCi0gKiBtYXkgaW1wcm92ZSBEVE0gcHJvY2Vzc2luZyBzcGVlZCBieSBzdWJzdGl0dXRpbmcgdGhlIERUTSBzeW1ib2wgcmVzb2x1dGlvbgotICogdGFibGVzIHdpdGggYXBwbGljYXRpb24gc3BlY2lmaWMgcXVpY2sgc3ltYm9sIHJlc29sdXRpb24gdGFibGVzLgotICogPHA+Ci0gKiAlUkVWSUVXJSBUaGUgb25seSBkaWZmZXJlbmNlIGJldHdlZW4gdGhpcyBhbiBEVE1TdHJpbmdQb29sIHNlZW1zIHRvIGJlIHRoYXQKLSAqIGl0IHVzZXMgYSBqYXZhLmxhbmcuSGFzaHRhYmxlIGZ1bGwgb2YgSW50ZWdlcnMgcmF0aGVyIHRoYW4gaW1wbGVtZW50aW5nIGl0cwotICogb3duIGhhc2hpbmcuIEpvZSBkZWxpYmVyYXRlbHkgYXZvaWRlZCB0aGF0IGFwcHJvYWNoIHdoZW4gd3JpdGluZwotICogRFRNU3RyaW5nUG9vbCwgc2luY2UgaXQgaXMgYm90aCBtdWNoIG1vcmUgbWVtb3J5LWh1bmdyeSBhbmQgcHJvYmFibHkgc2xvd2VyCi0gKiAtLSBlc3BlY2lhbGx5IGluIEpESyAxLjEueCwgd2hlcmUgSGFzaHRhYmxlIGlzIHN5bmNocm9uaXplZC4gV2UgbmVlZCB0bwotICogZWl0aGVyIGp1c3RpZnkgdGhpcyBpbXBsZW1lbnRhdGlvbiBvciBkaXNjYXJkIGl0LgotICoKLSAqIDxwPgotICogU3RhdHVzOiBJbiBwcm9ncmVzcywgdW5kZXIgZGlzY3Vzc2lvbi4KLSAqCi0gKi8KLXB1YmxpYyBjbGFzcyBDdXN0b21TdHJpbmdQb29sIGV4dGVuZHMgRFRNU3RyaW5nUG9vbCB7Ci0KLSAgICBmaW5hbCBNYXA8U3RyaW5nLCBJbnRlZ2VyPiBtX3N0cmluZ1RvSW50ID0gbmV3IEhhc2hNYXA8PigpOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE5VTEwgPSAtMTsKLQotICAgIHB1YmxpYyBDdXN0b21TdHJpbmdQb29sKCkgewotICAgICAgICBzdXBlcigpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHJlbW92ZUFsbEVsZW1lbnRzKCkgewotICAgICAgICBtX2ludFRvU3RyaW5nLnJlbW92ZUFsbEVsZW1lbnRzKCk7Ci0gICAgICAgIGlmIChtX3N0cmluZ1RvSW50ICE9IG51bGwpIHsKLSAgICAgICAgICAgIG1fc3RyaW5nVG9JbnQuY2xlYXIoKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEByZXR1cm4gc3RyaW5nIHdob3NlIHZhbHVlIGlzIHVuaXF1ZWx5IGlkZW50aWZpZWQgYnkgdGhpcyBpbnRlZ2VyIGluZGV4LgotICAgICAqIEB0aHJvd3MgamF2YS5sYW5nLkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpZiBpbmRleCBkb2Vzbid0IG1hcCB0bwotICAgICAqIGEgc3RyaW5nLgotICAgICAqLwotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyBTdHJpbmcgaW5kZXhUb1N0cmluZyhpbnQgaSkKLSAgICAgICAgICAgIHRocm93cyBqYXZhLmxhbmcuQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIHsKLSAgICAgICAgcmV0dXJuIChTdHJpbmcpIG1faW50VG9TdHJpbmcuZWxlbWVudEF0KGkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEByZXR1cm4gaW50ZWdlciBpbmRleCB1bmlxdWVseSBpZGVudGlmeWluZyB0aGUgdmFsdWUgb2YgdGhpcyBzdHJpbmcuCi0gICAgICovCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIGludCBzdHJpbmdUb0luZGV4KFN0cmluZyBzKSB7Ci0gICAgICAgIGlmIChzID09IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBOVUxMOwotICAgICAgICB9Ci0gICAgICAgIEludGVnZXIgaW9iaiA9IG1fc3RyaW5nVG9JbnQuZ2V0KHMpOwotICAgICAgICBpZiAoaW9iaiA9PSBudWxsKSB7Ci0gICAgICAgICAgICBtX2ludFRvU3RyaW5nLmFkZEVsZW1lbnQocyk7Ci0gICAgICAgICAgICBpb2JqID0gbV9pbnRUb1N0cmluZy5zaXplKCk7Ci0gICAgICAgICAgICBtX3N0cmluZ1RvSW50LnB1dChzLCBpb2JqKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gaW9iajsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vcmVmL0RUTUF4aXNJdGVyTm9kZUxpc3QuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9yZWYvRFRNQXhpc0l0ZXJOb2RlTGlzdC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxOTkzYmQ2Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9yZWYvRFRNQXhpc0l0ZXJOb2RlTGlzdC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTQ0ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IERUTUF4aXNJdGVyTm9kZUxpc3QuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNSAwODoxNDo1OSBzdXJlc2hfZW1haWxpZCBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLnJlZjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1BeGlzSXRlcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5JbnRWZWN0b3I7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotCi0vKioKLSAqIDxjb2RlPkRUTUF4aXNOb2RlTGlzdDwvY29kZT4gZ2l2ZXMgdXMgYW4gaW1wbGVtZW50YXRpb24gb2YgdGhlIERPTSdzCi0gKiBOb2RlTGlzdCBpbnRlcmZhY2Ugd3JhcHBlZCBhcm91bmQgYSBEVE0gSXRlcmF0b3IuIFRoZSBhdXRob3IKLSAqIGNvbnNpZGVycyB0aGlzIHNvbWV0aGluZyBvZiBhbiBhYm9taW5hdGlvbnMsIHNpbmNlIE5vZGVMaXN0IHdhcyBub3QKLSAqIGludGVuZGVkIHRvIGJlIGEgZ2VuZXJhbCBwdXJwb3NlICJsaXN0IG9mIG5vZGVzIiBBUEkgYW5kIGlzCi0gKiBnZW5lcmFsbHkgY29uc2lkZXJlZCBieSB0aGUgRE9NIFdHIHRvIGhhdmUgYmUgYSBtaXN0YWtlLi4uIGJ1dCBJJ20KLSAqIHRvbGQgdGhhdCBzb21lIG9mIHRoZSBYUGF0aC9YU0xUIGZvbGtzIHNheSB0aGV5IG11c3QgaGF2ZSB0aGlzCi0gKiBzb2x1dGlvbi4KLSAqCi0gKiBQbGVhc2Ugbm90ZSB0aGF0IHRoaXMgaXMgbm90IG5lY2Vzc2FyaWx5IGVxdWl2bGFlbnQgdG8gYSBET00KLSAqIE5vZGVMaXN0IG9wZXJhdGluZyBvdmVyIHRoZSBzYW1lIGRvY3VtZW50LiBJbiBwYXJ0aWN1bGFyOgotICogPHVsPgotICoKLSAqIDxsaT5JZiB0aGVyZSBhcmUgc2V2ZXJhbCBUZXh0IG5vZGVzIGluIGxvZ2ljYWwgc3VjY2Vzc2lvbiAoaWUsCi0gKiBhY3Jvc3MgQ0RBVEFTZWN0aW9uIGFuZCBFbnRpdHlSZWZlcmVuY2UgYm91bmRhcmllcyksIHdlIHdpbGwgcmV0dXJuCi0gKiBvbmx5IHRoZSBmaXJzdDsgdGhlIGNhbGxlciBpcyByZXNwb25zaWJsZSBmb3Igc3RlcHBpbmcgdGhyb3VnaAotICogdGhlbS4KLSAqICglUkVWSUVXJSBQcm92aWRlIGEgY29udmVuaWVuY2Ugcm91dGluZSBoZXJlIHRvIGFzc2lzdCwgcGVuZGluZwotICogcHJvcG9zZWQgRE9NIExldmVsIDMgZ2V0QWRqYWNlbnRUZXh0KCkgb3BlcmF0aW9uPykgPC9saT4KLSAqCi0gKiA8bGk+U2luY2UgdGhlIHdob2xlIFhQYXRoL1hTTFQgYXJjaGl0ZWN0dXJlIGFzc3VtZXMgdGhhdCB0aGUgc291cmNlCi0gKiBkb2N1bWVudCBpcyBub3QgYWx0ZXJlZCB3aGlsZSB3ZSdyZSB3b3JraW5nIHdpdGggaXQsIHdlIGRvIG5vdAotICogcHJvbWlzZSB0byBpbXBsZW1lbnQgdGhlIERPTSBOb2RlTGlzdCdzICJsaXZlIHZpZXciIHJlc3BvbnNlIHRvCi0gKiBkb2N1bWVudCBtdXRhdGlvbi4gPC9saT4KLSAqCi0gKiA8L3VsPgotICoKLSAqIDxwPlN0YXRlOiBJbiBwcm9ncmVzcyEhPC9wPgotICogKi8KLXB1YmxpYyBjbGFzcyBEVE1BeGlzSXRlck5vZGVMaXN0IGV4dGVuZHMgRFRNTm9kZUxpc3RCYXNlIHsKLSAgICBwcml2YXRlIERUTSBtX2R0bTsKLSAgICBwcml2YXRlIERUTUF4aXNJdGVyYXRvciBtX2l0ZXI7Ci0gICAgcHJpdmF0ZSBJbnRWZWN0b3IgbV9jYWNoZWROb2RlczsKLSAgICBwcml2YXRlIGludCBtX2xhc3QgPSAtMTsKLSAgICAvLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAgICAvLyBNZXRob2RzIHVuaXF1ZSB0byB0aGlzIGNsYXNzCi0gICAgcHJpdmF0ZSBEVE1BeGlzSXRlck5vZGVMaXN0KCkgewotICAgIH0KLQotICAgIC8qKgotICAgICAqIFB1YmxpYyBjb25zdHJ1Y3RvcjogV3JhcCBhIERUTU5vZGVMaXN0IGFyb3VuZCBhbiBleGlzdGluZwotICAgICAqIGFuZCBwcmVjb25maWd1cmVkIERUTUF4aXNJdGVyYXRvcgotICAgICAqLwotICAgIHB1YmxpYyBEVE1BeGlzSXRlck5vZGVMaXN0KERUTSBkdG0sIERUTUF4aXNJdGVyYXRvciBkdG1BeGlzSXRlcmF0b3IpIHsKLSAgICAgICAgaWYgKGR0bUF4aXNJdGVyYXRvciA9PSBudWxsKSB7Ci0gICAgICAgICAgICBtX2xhc3QgPSAwOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgbV9jYWNoZWROb2RlcyA9IG5ldyBJbnRWZWN0b3IoKTsKLSAgICAgICAgICAgIG1fZHRtID0gZHRtOwotICAgICAgICB9Ci0gICAgICAgIG1faXRlciA9IGR0bUF4aXNJdGVyYXRvcjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBY2Nlc3MgdGhlIHdyYXBwZWQgRFRNSXRlcmF0b3IuIEknbSBub3Qgc3VyZSB3aGV0aGVyIGFueW9uZSB3aWxsCi0gICAgICogbmVlZCB0aGlzIG9yIG5vdCwgYnV0IGxldCdzIHdyaXRlIGl0IGFuZCB0aGluayBhYm91dCBpdC4KLSAgICAgKgotICAgICAqLwotICAgIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3IgZ2V0RFRNQXhpc0l0ZXJhdG9yKCkgewotICAgICAgICByZXR1cm4gbV9pdGVyOwotICAgIH0KLQotCi0gICAgLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gICAgLy8gb3JnLnczYy5kb20uTm9kZUxpc3QgQVBJIGZvbGxvd3MKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIDxjb2RlPmluZGV4PC9jb2RlPnRoIGl0ZW0gaW4gdGhlIGNvbGxlY3Rpb24uIElmCi0gICAgICogPGNvZGU+aW5kZXg8L2NvZGU+IGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byB0aGUgbnVtYmVyIG9mIG5vZGVzIGluCi0gICAgICogdGhlIGxpc3QsIHRoaXMgcmV0dXJucyA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICAgKiBAcGFyYW0gaW5kZXggSW5kZXggaW50byB0aGUgY29sbGVjdGlvbi4KLSAgICAgKiBAcmV0dXJuIFRoZSBub2RlIGF0IHRoZSA8Y29kZT5pbmRleDwvY29kZT50aCBwb3NpdGlvbiBpbiB0aGUKLSAgICAgKiAgIDxjb2RlPk5vZGVMaXN0PC9jb2RlPiwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhhdCBpcyBub3QgYSB2YWxpZAotICAgICAqICAgaW5kZXguCi0gICAgICovCi0gICAgcHVibGljIE5vZGUgaXRlbShpbnQgaW5kZXgpIHsKLSAgICAgICAgaWYgKG1faXRlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpbnQgbm9kZSA9IDA7Ci0gICAgICAgICAgICBpbnQgY291bnQgPSBtX2NhY2hlZE5vZGVzLnNpemUoKTsKLQotICAgICAgICAgICAgaWYgKGNvdW50ID4gaW5kZXgpIHsKLSAgICAgICAgICAgICAgICBub2RlID0gbV9jYWNoZWROb2Rlcy5lbGVtZW50QXQoaW5kZXgpOwotICAgICAgICAgICAgICAgIHJldHVybiBtX2R0bS5nZXROb2RlKG5vZGUpOwotICAgICAgICAgICAgfSBlbHNlIGlmIChtX2xhc3QgPT0gLTEpIHsKLSAgICAgICAgICAgICAgICB3aGlsZSAoY291bnQgPD0gaW5kZXgKLSAgICAgICAgICAgICAgICAgICAgICAgICYmICgobm9kZSA9IG1faXRlci5uZXh0KCkpICE9IERUTUF4aXNJdGVyYXRvci5FTkQpKSB7Ci0gICAgICAgICAgICAgICAgICAgIG1fY2FjaGVkTm9kZXMuYWRkRWxlbWVudChub2RlKTsKLSAgICAgICAgICAgICAgICAgICAgY291bnQrKzsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaWYgKG5vZGUgPT0gRFRNQXhpc0l0ZXJhdG9yLkVORCkgewotICAgICAgICAgICAgICAgICAgICBtX2xhc3QgPSBjb3VudDsKLSAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gbV9kdG0uZ2V0Tm9kZShub2RlKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhlIG51bWJlciBvZiBub2RlcyBpbiB0aGUgbGlzdC4gVGhlIHJhbmdlIG9mIHZhbGlkIGNoaWxkIG5vZGUgaW5kaWNlcwotICAgICAqIGlzIDAgdG8gPGNvZGU+bGVuZ3RoLTE8L2NvZGU+IGluY2x1c2l2ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldExlbmd0aCgpIHsKLSAgICAgICAgaWYgKG1fbGFzdCA9PSAtMSkgewotICAgICAgICAgICAgaW50IG5vZGU7Ci0gICAgICAgICAgICB3aGlsZSAoKG5vZGUgPSBtX2l0ZXIubmV4dCgpKSAhPSBEVE1BeGlzSXRlcmF0b3IuRU5EKSB7Ci0gICAgICAgICAgICAgICAgbV9jYWNoZWROb2Rlcy5hZGRFbGVtZW50KG5vZGUpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgbV9sYXN0ID0gbV9jYWNoZWROb2Rlcy5zaXplKCk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG1fbGFzdDsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vcmVmL0RUTUF4aXNJdGVyYXRvckJhc2UuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9yZWYvRFRNQXhpc0l0ZXJhdG9yQmFzZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiOWVlY2MyLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9yZWYvRFRNQXhpc0l0ZXJhdG9yQmFzZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjgzICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IERUTUF4aXNJdGVyYXRvckJhc2UuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNSAwODoxNDo1OSBzdXJlc2hfZW1haWxpZCBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLnJlZjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTUF4aXNJdGVyYXRvcjsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIHNlcnZlcyBhcyBhIGRlZmF1bHQgYmFzZSBmb3IgaW1wbGVtZW50YXRpb25zIG9mIG11dGFibGUKLSAqIERUTUF4aXNJdGVyYXRvcnMuCi0gKi8KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBEVE1BeGlzSXRlcmF0b3JCYXNlIGltcGxlbWVudHMgRFRNQXhpc0l0ZXJhdG9yCi17Ci0KLSAgLyoqIFRoZSBwb3NpdGlvbiBvZiB0aGUgbGFzdCBub2RlIHdpdGhpbiB0aGUgaXRlcmF0aW9uLCBhcyBkZWZpbmVkIGJ5IFhQYXRoLgotICAgKiBOb3RlIHRoYXQgdGhpcyBpcyBfbm90XyB0aGUgbm9kZSdzIGhhbmRsZSB3aXRoaW4gdGhlIERUTS4gQWxzbywgZG9uJ3QKLSAgICogY29uZnVzZSBpdCB3aXRoIHRoZSBjdXJyZW50IChtb3N0IHJlY2VudGx5IHJldHVybmVkKSBwb3NpdGlvbi4KLSAgICovCi0gIHByb3RlY3RlZCBpbnQgX2xhc3QgPSAtMTsKLQotICAvKiogVGhlIHBvc2l0aW9uIG9mIHRoZSBjdXJyZW50IG5vZGUgd2l0aGluIHRoZSBpdGVyYXRpb24sIGFzIGRlZmluZWQgYnkgWFBhdGguCi0gICAqIE5vdGUgdGhhdCB0aGlzIGlzIF9ub3RfIHRoZSBub2RlJ3MgaGFuZGxlIHdpdGhpbiB0aGUgRFRNIQotICAgKi8KLSAgcHJvdGVjdGVkIGludCBfcG9zaXRpb24gPSAwOwotCi0gIC8qKiBUaGUgcG9zaXRpb24gb2YgdGhlIG1hcmtlZCBub2RlIHdpdGhpbiB0aGUgaXRlcmF0aW9uOwotICAgKiBhIHNhdmVkIGl0YXJhdGlvbiBzdGF0ZSB0aGF0IHdlIG1heSB3YW50IHRvIGNvbWUgYmFjayB0by4KLSAgICogTm90ZSB0aGF0IG9ubHkgb25lIG1hcmsgaXMgbWFpbnRhaW5lZDsgdGhlcmUgaXMgbm8gc3RhY2suCi0gICAqLwotICBwcm90ZWN0ZWQgaW50IF9tYXJrZWROb2RlOwotCi0gIC8qKiBUaGUgaGFuZGxlIHRvIHRoZSBzdGFydCwgb3Igcm9vdCwgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICogU2V0IHRoaXMgdG8gRU5EIHRvIGNvbnN0cnVjdCBhbiBlbXB0eSBpdGVyYXRvci4KLSAgICovCi0gIHByb3RlY3RlZCBpbnQgX3N0YXJ0Tm9kZSA9IERUTUF4aXNJdGVyYXRvci5FTkQ7Ci0KLSAgLyoqIFRydWUgaWYgdGhlIHN0YXJ0IG5vZGUgc2hvdWxkIGJlIGNvbnNpZGVyZWQgcGFydCBvZiB0aGUgaXRlcmF0aW9uLgotICAgKiBGYWxzZSB3aWxsIGNhdXNlIGl0IHRvIGJlIHNraXBwZWQuCi0gICAqLwotICBwcm90ZWN0ZWQgYm9vbGVhbiBfaW5jbHVkZVNlbGYgPSBmYWxzZTsKLQotICAvKiogVHJ1ZSBpZiB0aGlzIGl0ZXJhdGlvbiBjYW4gYmUgcmVzdGFydGVkLiBGYWxzZSBvdGhlcndpc2UgKGVnLCBpZgotICAgKiB3ZSBhcmUgaXRlcmF0aW5nIG92ZXIgYSBzdHJlYW0gdGhhdCBjYW4gbm90IGJlIHJlLXNjYW5uZWQsIG9yIGlmCi0gICAqIHRoZSBpdGVyYXRvciB3YXMgcHJvZHVjZWQgYnkgY2xvbmluZyBhbm90aGVyIGl0ZXJhdG9yLikKLSAgICovCi0gIHByb3RlY3RlZCBib29sZWFuIF9pc1Jlc3RhcnRhYmxlID0gdHJ1ZTsKLQotICAvKioKLSAgICogR2V0IHN0YXJ0IHRvIEVORCBzaG91bGQgJ2Nsb3NlJyB0aGUgaXRlcmF0b3IsCi0gICAqIGkuZS4gc3Vic2VxdWVudCBjYWxsIHRvIG5leHQoKSBzaG91bGQgcmV0dXJuIEVORC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgcm9vdCBub2RlIG9mIHRoZSBpdGVyYXRpb24uCi0gICAqLwotICBwdWJsaWMgaW50IGdldFN0YXJ0Tm9kZSgpCi0gIHsKLSAgICByZXR1cm4gX3N0YXJ0Tm9kZTsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIEEgRFRNQXhpc0l0ZXJhdG9yIHdoaWNoIGhhcyBiZWVuIHJlc2V0IHRvIHRoZSBzdGFydCBub2RlLAotICAgKiB3aGljaCBtYXkgb3IgbWF5IG5vdCBiZSB0aGUgc2FtZSBhcyB0aGlzIGl0ZXJhdG9yLgotICAgKiAqLwotICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIHJlc2V0KCkKLSAgewotCi0gICAgZmluYWwgYm9vbGVhbiB0ZW1wID0gX2lzUmVzdGFydGFibGU7Ci0KLSAgICBfaXNSZXN0YXJ0YWJsZSA9IHRydWU7Ci0KLSAgICBzZXRTdGFydE5vZGUoX3N0YXJ0Tm9kZSk7Ci0KLSAgICBfaXNSZXN0YXJ0YWJsZSA9IHRlbXA7Ci0KLSAgICByZXR1cm4gdGhpczsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIGZsYWcgdG8gaW5jbHVkZSB0aGUgc3RhcnQgbm9kZSBpbiB0aGUgaXRlcmF0aW9uLgotICAgKgotICAgKgotICAgKiBAcmV0dXJuIFRoaXMgZGVmYXVsdCBtZXRob2QgcmV0dXJucyBqdXN0IHJldHVybnMgdGhpcyBEVE1BeGlzSXRlcmF0b3IsCi0gICAqIGFmdGVyIHNldHRpbmcgdGhlIGZsYWcuCi0gICAqIChSZXR1cm5pbmcgInRoaXMiIHBlcm1pdHMgQysrLXN0eWxlIGNoYWluaW5nIG9mCi0gICAqIG1ldGhvZCBjYWxscyBpbnRvIGEgc2luZ2xlIGV4cHJlc3Npb24uKQotICAgKi8KLSAgcHVibGljIERUTUF4aXNJdGVyYXRvciBpbmNsdWRlU2VsZigpCi0gIHsKLQotICAgIF9pbmNsdWRlU2VsZiA9IHRydWU7Ci0KLSAgICByZXR1cm4gdGhpczsKLSAgfQotCi0gIC8qKiBSZXR1cm5zIHRoZSBwb3NpdGlvbiBvZiB0aGUgbGFzdCBub2RlIHdpdGhpbiB0aGUgaXRlcmF0aW9uLCBhcwotICAgKiBkZWZpbmVkIGJ5IFhQYXRoLiAgSW4gYSBmb3J3YXJkIGl0ZXJhdG9yLCBJIGJlbGlldmUgdGhpcyBlcXVhbHMgdGhlIG51bWJlciBvZiBub2RlcyB3aGljaCB0aGlzCi0gICAqIGl0ZXJhdG9yIHdpbGwgeWllbGQuIEluIGEgcmV2ZXJzZSBpdGVyYXRvciwgSSBiZWxpZXZlIGl0IHNob3VsZCByZXR1cm4KLSAgICogMSAoc2luY2UgdGhlICJsYXN0IiBpcyB0aGUgZmlyc3QgcHJvZHVjZWQuKQotICAgKgotICAgKiBUaGlzIG1heSBiZSBhbiBleHBlbnNpdmUgb3BlcmF0aW9uIHdoZW4gY2FsbGVkIHRoZSBmaXJzdCB0aW1lLCBzaW5jZQotICAgKiBpdCBtYXkgaGF2ZSB0byBpdGVyYXRlIHRocm91Z2ggYSBsYXJnZSBwYXJ0IG9mIHRoZSBkb2N1bWVudCB0byBwcm9kdWNlCi0gICAqIGl0cyBhbnN3ZXIuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIG51bWJlciBvZiBub2RlcyBpbiB0aGlzIGl0ZXJhdG9yIChmb3J3YXJkKSBvciAxIChyZXZlcnNlKS4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0TGFzdCgpCi0gIHsKLQotICAgIGlmIChfbGFzdCA9PSAtMSkgICAgICAgICAgICAvLyBOb3QgcHJldmlvdXNseSBlc3RhYmxpc2hlZAotICAgIHsKLSAgICAgIC8vIE5vdGUgdGhhdCB3ZSdyZSBkb2luZyBib3RoIHNldE1hcmsoKSAtLSB3aGljaCBzYXZlcyBfY3VycmVudENoaWxkCi0gICAgICAvLyAtLSBhbmQgZXhwbGljaXRseSBzYXZpbmcgb3VyIHBvc2l0aW9uIGNvdW50ZXIgKG51bWJlciBvZiBub2RlcwotICAgICAgLy8geWllbGRlZCBzbyBmYXIpLgotICAgICAgLy8KLSAgICAgIC8vICVSRVZJRVclIFNob3VsZCBwb3NpdGlvbiBhbHNvIGJlIHNhdmVkIGJ5IHNldE1hcmsoKT8KLSAgICAgIC8vIChJdCB3YXNuJ3QgaW4gdGhlIFhTTFRDIHZlcnNpb24sIGJ1dCBJIGRvbid0IHVuZGVyc3RhbmQgd2h5IG5vdC4pCi0KLSAgICAgIGZpbmFsIGludCB0ZW1wID0gX3Bvc2l0aW9uOyAvLyBTYXZlIHN0YXRlCi0gICAgICBzZXRNYXJrKCk7Ci0KLSAgICAgIHJlc2V0KCk7ICAgICAgICAgICAgICAgICAgLy8gQ291bnQgdGhlIG5vZGVzIGZvdW5kIGJ5IHRoaXMgaXRlcmF0b3IKLSAgICAgIGRvCi0gICAgICB7Ci0gICAgICAgIF9sYXN0Kys7Ci0gICAgICB9Ci0gICAgICB3aGlsZSAobmV4dCgpICE9IEVORCk7Ci0KLSAgICAgIGdvdG9NYXJrKCk7ICAgICAgICAgICAgICAgLy8gUmVzdG9yZSBzYXZlZCBzdGF0ZQotICAgICAgX3Bvc2l0aW9uID0gdGVtcDsKLSAgICB9Ci0KLSAgICByZXR1cm4gX2xhc3Q7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBUaGUgcG9zaXRpb24gb2YgdGhlIGN1cnJlbnQgbm9kZSB3aXRoaW4gdGhlIHNldCwgYXMgZGVmaW5lZCBieQotICAgKiBYUGF0aC4gTm90ZSB0aGF0IHRoaXMgaXMgb25lLWJhc2VkLCBub3QgemVyby1iYXNlZC4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0UG9zaXRpb24oKQotICB7Ci0gICAgcmV0dXJuIF9wb3NpdGlvbiA9PSAwID8gMSA6IF9wb3NpdGlvbjsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhpcyBpdGVyYXRvciBoYXMgYSByZXZlcnNlZCBheGlzLCBlbHNlIGZhbHNlCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBpc1JldmVyc2UoKQotICB7Ci0gICAgcmV0dXJuIGZhbHNlOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgYSBkZWVwIGNvcHkgb2YgdGhpcyBpdGVyYXRvci4gQ2xvbmVkIGl0ZXJhdG9ycyBtYXkgbm90IGJlCi0gICAqIHJlc3RhcnRhYmxlLiBUaGUgaXRlcmF0b3IgYmVpbmcgY2xvbmVkIG1heSBvciBtYXkgbm90IGJlY29tZQotICAgKiBub24tcmVzdGFydGFibGUgYXMgYSBzaWRlIGVmZmVjdCBvZiB0aGlzIG9wZXJhdGlvbi4KLSAgICoKLSAgICogQHJldHVybiBhIGRlZXAgY29weSBvZiB0aGlzIGl0ZXJhdG9yLgotICAgKi8KLSAgcHVibGljIERUTUF4aXNJdGVyYXRvciBjbG9uZUl0ZXJhdG9yKCkKLSAgewotCi0gICAgdHJ5Ci0gICAgewotICAgICAgZmluYWwgRFRNQXhpc0l0ZXJhdG9yQmFzZSBjbG9uZSA9IChEVE1BeGlzSXRlcmF0b3JCYXNlKSBzdXBlci5jbG9uZSgpOwotCi0gICAgICBjbG9uZS5faXNSZXN0YXJ0YWJsZSA9IGZhbHNlOwotCi0gICAgICAvLyByZXR1cm4gY2xvbmUucmVzZXQoKTsKLSAgICAgIHJldHVybiBjbG9uZTsKLSAgICB9Ci0gICAgY2F0Y2ggKENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGUpCi0gICAgewotICAgICAgdGhyb3cgbmV3IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuV3JhcHBlZFJ1bnRpbWVFeGNlcHRpb24oZSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIERvIGFueSBmaW5hbCBjbGVhbnVwIHRoYXQgaXMgcmVxdWlyZWQgYmVmb3JlIHJldHVybmluZyB0aGUgbm9kZSB0aGF0IHdhcwotICAgKiBwYXNzZWQgaW4sIGFuZCB0aGVuIHJldHVybiBpdC4gVGhlIGludGVuZGVkIHVzZSBpcwotICAgKiA8YnIgLz4KLSAgICogPGNvZGU+cmV0dXJuIHJldHVybk5vZGUobm9kZSk7PC9jb2RlPgotICAgKgotICAgKiAlUkVWSUVXJSBJZiB3ZSdyZSBjYWxsaW5nIGl0IHB1cmVseSBmb3Igc2lkZSBlZmZlY3RzLCBzaG91bGQgd2UgcmVhbGx5Ci0gICAqIGJlIGJvdGhlcmluZyB3aXRoIGEgcmV0dXJuIHZhbHVlPyBTb21ldGhpbmcgbGlrZQotICAgKiA8YnIgLz4KLSAgICogPGNvZGU+IGFjY2VwdChub2RlKTsgcmV0dXJuIG5vZGU7IDwvY29kZT4KLSAgICogPGJyIC8+Ci0gICAqIHdvdWxkIHByb2JhYmx5IG9wdGltaXplIGp1c3QgYWJvdXQgYXMgd2VsbCBhbmQgYXZvaWQgcXVlc3Rpb25zCi0gICAqIGFib3V0IHdoZXRoZXIgd2hhdCdzIHJldHVybmVkIGNvdWxkIGV2ZXIgYmUgZGlmZmVyZW50IGZyb20gd2hhdCdzCi0gICAqIHBhc3NlZCBpbi4KLSAgICoKLSAgICogQHBhcmFtIG5vZGUgTm9kZSBoYW5kbGUgd2hpY2ggaXRlcmF0aW9uIGlzIGFib3V0IHRvIHlpZWxkLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBub2RlIGhhbmRsZSBwYXNzZWQgaW4uICAqLwotICBwcm90ZWN0ZWQgZmluYWwgaW50IHJldHVybk5vZGUoZmluYWwgaW50IG5vZGUpCi0gIHsKLSAgICBfcG9zaXRpb24rKzsKLQotICAgIHJldHVybiBub2RlOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlc2V0IHRoZSBwb3NpdGlvbiB0byB6ZXJvLiBOT1RFIHRoYXQgdGhpcyBkb2VzIG5vdCBjaGFuZ2UgdGhlIGl0ZXJhdGlvbgotICAgKiBzdGF0ZSwgb25seSB0aGUgcG9zaXRpb24gbnVtYmVyIGFzc29jaWF0ZWQgd2l0aCB0aGF0IHN0YXRlLgotICAgKgotICAgKiAlUkVWSUVXJSBEb2N1bWVudCB3aGVuIHRoaXMgd291bGQgYmUgdXNlZD8KLSAgICoKLSAgICogQHJldHVybiBUaGlzIGluc3RhbmNlLgotICAgKi8KLSAgcHJvdGVjdGVkIGZpbmFsIERUTUF4aXNJdGVyYXRvciByZXNldFBvc2l0aW9uKCkKLSAgewotCi0gICAgX3Bvc2l0aW9uID0gMDsKLQotICAgIHJldHVybiB0aGlzOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdHJ1ZSBpZiBhbGwgdGhlIG5vZGVzIGluIHRoZSBpdGVyYXRpb24gd2VsbCBiZSByZXR1cm5lZCBpbiBkb2N1bWVudAotICAgKiBvcmRlci4KLSAgICoKLSAgICogQHJldHVybiB0cnVlIGFzIGEgZGVmYXVsdC4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzRG9jT3JkZXJlZCgpCi0gIHsKLSAgICByZXR1cm4gdHJ1ZTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBheGlzIGJlaW5nIGl0ZXJhdGVkLCBpZiBpdCBpcyBrbm93bi4KLSAgICoKLSAgICogQHJldHVybiBBeGlzLkNISUxELCBldGMuLCBvciAtMSBpZiB0aGUgYXhpcyBpcyBub3Qga25vd24gb3IgaXMgb2YgbXVsdGlwbGUKLSAgICogdHlwZXMuCi0gICAqLwotICBwdWJsaWMgaW50IGdldEF4aXMoKQotICB7Ci0gICAgcmV0dXJuIC0xOwotICB9Ci0KLSAgcHVibGljIHZvaWQgc2V0UmVzdGFydGFibGUoYm9vbGVhbiBpc1Jlc3RhcnRhYmxlKSB7Ci0gICAgX2lzUmVzdGFydGFibGUgPSBpc1Jlc3RhcnRhYmxlOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgbm9kZSBhdCB0aGUgZ2l2ZW4gcG9zaXRpb24uCi0gICAqCi0gICAqIEBwYXJhbSBwb3NpdGlvbiBUaGUgcG9zaXRpb24KLSAgICogQHJldHVybiBUaGUgbm9kZSBhdCB0aGUgZ2l2ZW4gcG9zaXRpb24uCi0gICAqLwotICBwdWJsaWMgaW50IGdldE5vZGVCeVBvc2l0aW9uKGludCBwb3NpdGlvbikKLSAgewotICAgIGlmIChwb3NpdGlvbiA+IDApIHsKLSAgICAgIGZpbmFsIGludCBwb3MgPSBpc1JldmVyc2UoKSA/IGdldExhc3QoKSAtIHBvc2l0aW9uICsgMQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IHBvc2l0aW9uOwotICAgICAgaW50IG5vZGU7Ci0gICAgICB3aGlsZSAoKG5vZGUgPSBuZXh0KCkpICE9IERUTUF4aXNJdGVyYXRvci5FTkQpIHsKLSAgICAgICAgaWYgKHBvcyA9PSBnZXRQb3NpdGlvbigpKSB7Ci0gICAgICAgICAgcmV0dXJuIG5vZGU7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICB9Ci0gICAgcmV0dXJuIEVORDsKLSAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vcmVmL0RUTUNoaWxkSXRlck5vZGVMaXN0LmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vcmVmL0RUTUNoaWxkSXRlck5vZGVMaXN0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDNkMjZiNTMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL3JlZi9EVE1DaGlsZEl0ZXJOb2RlTGlzdC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTIxICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IERUTUNoaWxkSXRlck5vZGVMaXN0LmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTUgMDg6MTU6MDAgc3VyZXNoX2VtYWlsaWQgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5yZWY7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE07Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLQotLyoqCi0gKiA8Y29kZT5EVE1Ob2RlTGlzdDwvY29kZT4gZ2l2ZXMgdXMgYW4gaW1wbGVtZW50YXRpb24gb2YgdGhlIERPTSdzCi0gKiBOb2RlTGlzdCBpbnRlcmZhY2Ugd3JhcHBlZCBhcm91bmQgYSBEVE0gSXRlcmF0b3IuIFRoZSBhdXRob3IKLSAqIGNvbnNpZGVycyB0aGlzIHNvbWV0aGluZyBvZiBhbiBhYm9taW5hdGlvbnMsIHNpbmNlIE5vZGVMaXN0IHdhcyBub3QKLSAqIGludGVuZGVkIHRvIGJlIGEgZ2VuZXJhbCBwdXJwb3NlICJsaXN0IG9mIG5vZGVzIiBBUEkgYW5kIGlzCi0gKiBnZW5lcmFsbHkgY29uc2lkZXJlZCBieSB0aGUgRE9NIFdHIHRvIGhhdmUgYmUgYSBtaXN0YWtlLi4uIGJ1dCBJJ20KLSAqIHRvbGQgdGhhdCBzb21lIG9mIHRoZSBYUGF0aC9YU0xUIGZvbGtzIHNheSB0aGV5IG11c3QgaGF2ZSB0aGlzCi0gKiBzb2x1dGlvbi4KLSAqCi0gKiBQbGVhc2Ugbm90ZSB0aGF0IHRoaXMgaXMgbm90IG5lY2Vzc2FyaWx5IGVxdWl2bGFlbnQgdG8gYSBET00KLSAqIE5vZGVMaXN0IG9wZXJhdGluZyBvdmVyIHRoZSBzYW1lIGRvY3VtZW50LiBJbiBwYXJ0aWN1bGFyOgotICogPHVsPgotICoKLSAqIDxsaT5JZiB0aGVyZSBhcmUgc2V2ZXJhbCBUZXh0IG5vZGVzIGluIGxvZ2ljYWwgc3VjY2Vzc2lvbiAoaWUsCi0gKiBhY3Jvc3MgQ0RBVEFTZWN0aW9uIGFuZCBFbnRpdHlSZWZlcmVuY2UgYm91bmRhcmllcyksIHdlIHdpbGwgcmV0dXJuCi0gKiBvbmx5IHRoZSBmaXJzdDsgdGhlIGNhbGxlciBpcyByZXNwb25zaWJsZSBmb3Igc3RlcHBpbmcgdGhyb3VnaAotICogdGhlbS4KLSAqICglUkVWSUVXJSBQcm92aWRlIGEgY29udmVuaWVuY2Ugcm91dGluZSBoZXJlIHRvIGFzc2lzdCwgcGVuZGluZwotICogcHJvcG9zZWQgRE9NIExldmVsIDMgZ2V0QWRqYWNlbnRUZXh0KCkgb3BlcmF0aW9uPykgPC9saT4KLSAqCi0gKiA8bGk+U2luY2UgdGhlIHdob2xlIFhQYXRoL1hTTFQgYXJjaGl0ZWN0dXJlIGFzc3VtZXMgdGhhdCB0aGUgc291cmNlCi0gKiBkb2N1bWVudCBpcyBub3QgYWx0ZXJlZCB3aGlsZSB3ZSdyZSB3b3JraW5nIHdpdGggaXQsIHdlIGRvIG5vdAotICogcHJvbWlzZSB0byBpbXBsZW1lbnQgdGhlIERPTSBOb2RlTGlzdCdzICJsaXZlIHZpZXciIHJlc3BvbnNlIHRvCi0gKiBkb2N1bWVudCBtdXRhdGlvbi4gPC9saT4KLSAqCi0gKiA8L3VsPgotICoKLSAqIDxwPlN0YXRlOiBJbiBwcm9ncmVzcyEhPC9wPgotICogKi8KLXB1YmxpYyBjbGFzcyBEVE1DaGlsZEl0ZXJOb2RlTGlzdCBleHRlbmRzIERUTU5vZGVMaXN0QmFzZSB7Ci0gICAgcHJpdmF0ZSBpbnQgbV9maXJzdENoaWxkOwotICAgIHByaXZhdGUgRFRNIG1fcGFyZW50RFRNOwotCi0gICAgLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gICAgLy8gTWV0aG9kcyB1bmlxdWUgdG8gdGhpcyBjbGFzcwotICAgIHByaXZhdGUgRFRNQ2hpbGRJdGVyTm9kZUxpc3QoKSB7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUHVibGljIGNvbnN0cnVjdG9yOiBDcmVhdGUgYSBOb2RlTGlzdCB0byBzdXBwb3J0Ci0gICAgICogRFRNTm9kZVByb3h5LmdldENoaWxkcmVuKCkuCi0gICAgICoKLSAgICAgKiBVbmZvcnR1bmF0ZWx5IEF4aXNJdGVyYXRvcnMgYW5kIERUTUl0ZXJhdG9ycyBkb24ndCBzaGFyZSBhbiBBUEksCi0gICAgICogc28gSSBjYW4ndCB1c2UgdGhlIGV4aXN0aW5nIEF4aXMuQ0hJTEQgaXRlcmF0b3IuIFJhdGhlciB0aGFuCi0gICAgICogY3JlYXRlIFlldCBBbm90aGVyIENsYXNzLCBsZXQncyBzZXQgdXAgYSBzcGVjaWFsIGNhc2Ugb2YgdGhpcwotICAgICAqIG9uZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBwYXJlbnREVE0gVGhlIERUTSBjb250YWluaW5nIHRoaXMgbm9kZQotICAgICAqIEBwYXJhbSBwYXJlbnRIYW5kbGUgRFRNIG5vZGUtaGFuZGxlIGludGVnZXIKLSAgICAgKgotICAgICAqLwotICAgIHB1YmxpYyBEVE1DaGlsZEl0ZXJOb2RlTGlzdChEVE0gcGFyZW50RFRNLGludCBwYXJlbnRIYW5kbGUpIHsKLSAgICAgICAgbV9wYXJlbnREVE09cGFyZW50RFRNOwotICAgICAgICBtX2ZpcnN0Q2hpbGQ9cGFyZW50RFRNLmdldEZpcnN0Q2hpbGQocGFyZW50SGFuZGxlKTsKLSAgICB9Ci0KLQotICAgIC8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICAgIC8vIG9yZy53M2MuZG9tLk5vZGVMaXN0IEFQSSBmb2xsb3dzCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSA8Y29kZT5pbmRleDwvY29kZT50aCBpdGVtIGluIHRoZSBjb2xsZWN0aW9uLiBJZgotICAgICAqIDxjb2RlPmluZGV4PC9jb2RlPiBpcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gdGhlIG51bWJlciBvZiBub2RlcyBpbgotICAgICAqIHRoZSBsaXN0LCB0aGlzIHJldHVybnMgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICogQHBhcmFtIGluZGV4IEluZGV4IGludG8gdGhlIGNvbGxlY3Rpb24uCi0gICAgICogQHJldHVybiBUaGUgbm9kZSBhdCB0aGUgPGNvZGU+aW5kZXg8L2NvZGU+dGggcG9zaXRpb24gaW4gdGhlCi0gICAgICogICA8Y29kZT5Ob2RlTGlzdDwvY29kZT4sIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoYXQgaXMgbm90IGEgdmFsaWQKLSAgICAgKiAgIGluZGV4LgotICAgICAqLwotICAgIHB1YmxpYyBOb2RlIGl0ZW0oaW50IGluZGV4KSB7Ci0gICAgICAgIGludCBoYW5kbGU9bV9maXJzdENoaWxkOwotICAgICAgICB3aGlsZSgtLWluZGV4Pj0wICYmIGhhbmRsZSE9RFRNLk5VTEwpIHsKLSAgICAgICAgICAgIGhhbmRsZT1tX3BhcmVudERUTS5nZXROZXh0U2libGluZyhoYW5kbGUpOwotICAgICAgICB9Ci0gICAgICAgIGlmIChoYW5kbGUgPT0gRFRNLk5VTEwpIHsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBtX3BhcmVudERUTS5nZXROb2RlKGhhbmRsZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhlIG51bWJlciBvZiBub2RlcyBpbiB0aGUgbGlzdC4gVGhlIHJhbmdlIG9mIHZhbGlkIGNoaWxkIG5vZGUgaW5kaWNlcwotICAgICAqIGlzIDAgdG8gPGNvZGU+bGVuZ3RoLTE8L2NvZGU+IGluY2x1c2l2ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldExlbmd0aCgpIHsKLSAgICAgICAgaW50IGNvdW50PTA7Ci0gICAgICAgIGZvciAoaW50IGhhbmRsZT1tX2ZpcnN0Q2hpbGQ7Ci0gICAgICAgICAgICAgaGFuZGxlIT1EVE0uTlVMTDsKLSAgICAgICAgICAgICBoYW5kbGU9bV9wYXJlbnREVE0uZ2V0TmV4dFNpYmxpbmcoaGFuZGxlKSkgewotICAgICAgICAgICAgKytjb3VudDsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gY291bnQ7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL3JlZi9EVE1EZWZhdWx0QmFzZS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL3JlZi9EVE1EZWZhdWx0QmFzZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1OGZhZTY5Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9yZWYvRFRNRGVmYXVsdEJhc2UuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIzNzEgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRFRNRGVmYXVsdEJhc2UuamF2YSx2IDEuMyAyMDA1LzA5LzI4IDEzOjQ4OjUyIHB2ZWR1bGEgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5yZWY7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS4qOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuU3ViYWxsb2NhdGVkSW50VmVjdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuQm9vbFN0YWNrOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uU291cmNlOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5YTUxTdHJpbmc7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5YTUxTdHJpbmdGYWN0b3J5OwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXMuWE1MTWVzc2FnZXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXMuWE1MRXJyb3JSZXNvdXJjZXM7Ci0KLWltcG9ydCBqYXZhLmlvLio7IC8vIGZvciBkdW1wRFRNCi0KLS8qKgotICogVGhlIDxjb2RlPkRUTURlZmF1bHRCYXNlPC9jb2RlPiBjbGFzcyBzZXJ2ZXMgYXMgYSBoZWxwZXIgYmFzZSBmb3IgRFRNcy4KLSAqIEl0IHNldHMgdXAgc3RydWN0dXJlcyBmb3IgbmF2aWdhdGlvbiBhbmQgdHlwZSwgd2hpbGUgbGVhdmluZyBkYXRhCi0gKiBtYW5hZ2VtZW50IGFuZCBjb25zdHJ1Y3Rpb24gdG8gdGhlIGRlcml2ZWQgY2xhc3Nlcy4KLSAqLwotcHVibGljIGFic3RyYWN0IGNsYXNzIERUTURlZmF1bHRCYXNlIGltcGxlbWVudHMgRFRNCi17Ci0gICAgc3RhdGljIGZpbmFsIGJvb2xlYW4gSkpLX0RFQlVHPWZhbHNlOwotCi0gIC8vIFRoaXMgY29uc3RhbnQgaXMgbGlrZWx5IHRvIGJlIHJlbW92ZWQgaW4gdGhlIGZ1dHVyZS4gVXNlIHRoZQotICAvLyBnZXREb2N1bWVudCgpIG1ldGhvZCBpbnN0ZWFkIG9mIFJPT1ROT0RFIHRvIGdldCBhdCB0aGUgcm9vdAotICAvLyBub2RlIG9mIGEgRFRNLgotICAvKiogVGhlIGlkZW50aXR5IG9mIHRoZSByb290IG5vZGUuICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJPT1ROT0RFID0gMDsKLQotICAvKioKLSAgICogVGhlIG51bWJlciBvZiBub2Rlcywgd2hpY2ggaXMgYWxzbyB1c2VkIHRvIGRldGVybWluZSB0aGUgbmV4dAotICAgKiAgbm9kZSBpbmRleC4KLSAgICovCi0gIHByb3RlY3RlZCBpbnQgbV9zaXplID0gMDsKLQotICAvKiogVGhlIGV4cGFuZGVkIG5hbWVzLCBvbmUgYXJyYXkgZWxlbWVudCBmb3IgZWFjaCBub2RlLiAqLwotICBwcm90ZWN0ZWQgU3ViYWxsb2NhdGVkSW50VmVjdG9yIG1fZXhwdHlwZTsKLQotICAvKiogRmlyc3QgY2hpbGQgdmFsdWVzLCBvbmUgYXJyYXkgZWxlbWVudCBmb3IgZWFjaCBub2RlLiAqLwotICBwcm90ZWN0ZWQgU3ViYWxsb2NhdGVkSW50VmVjdG9yIG1fZmlyc3RjaDsKLQotICAvKiogTmV4dCBzaWJsaW5nIHZhbHVlcywgb25lIGFycmF5IGVsZW1lbnQgZm9yIGVhY2ggbm9kZS4gKi8KLSAgcHJvdGVjdGVkIFN1YmFsbG9jYXRlZEludFZlY3RvciBtX25leHRzaWI7Ci0KLSAgLyoqIFByZXZpb3VzIHNpYmxpbmcgdmFsdWVzLCBvbmUgYXJyYXkgZWxlbWVudCBmb3IgZWFjaCBub2RlLiAqLwotICBwcm90ZWN0ZWQgU3ViYWxsb2NhdGVkSW50VmVjdG9yIG1fcHJldnNpYjsKLQotICAvKiogUHJldmlvdXMgc2libGluZyB2YWx1ZXMsIG9uZSBhcnJheSBlbGVtZW50IGZvciBlYWNoIG5vZGUuICovCi0gIHByb3RlY3RlZCBTdWJhbGxvY2F0ZWRJbnRWZWN0b3IgbV9wYXJlbnQ7Ci0KLSAgLyoqIFZlY3RvciBvZiBTdWJhbGxvY2F0ZWRJbnRWZWN0b3JzIG9mIE5TIGRlY2wgc2V0cyAqLwotICBwcm90ZWN0ZWQgVmVjdG9yIG1fbmFtZXNwYWNlRGVjbFNldHMgPSBudWxsOwotCi0gIC8qKiBTdWJhbGxvY2F0ZWRJbnRWZWN0b3IgIG9mIGVsZW1lbnRzIGF0IHdoaWNoIGNvcnJlc3BvbmRpbmcKLSAgICogbmFtZXNwYWNlRGVjbFNldHMgd2VyZSBkZWZpbmVkICovCi0gIHByb3RlY3RlZCBTdWJhbGxvY2F0ZWRJbnRWZWN0b3IgbV9uYW1lc3BhY2VEZWNsU2V0RWxlbWVudHMgPSBudWxsOwotCi0gIC8qKgotICAgKiBUaGVzZSBob2xkIGluZGV4ZXMgdG8gZWxlbWVudHMgYmFzZWQgb24gbmFtZXNwYWNlIGFuZCBsb2NhbCBuYW1lLgotICAgKiBUaGUgYmFzZSBsb29rdXAgaXMgdGhlIHRoZSBuYW1lc3BhY2UuICBUaGUgc2Vjb25kIGxvb2t1cCBpcyB0aGUgbG9jYWwKLSAgICogbmFtZSwgYW5kIHRoZSBsYXN0IGFycmF5IGNvbnRhaW5zIHRoZSB0aGUgZmlyc3QgZnJlZSBlbGVtZW50Ci0gICAqIGF0IHRoZSBzdGFydCwgYW5kIHRoZSBsaXN0IG9mIGVsZW1lbnQgaGFuZGxlcyBmb2xsb3dpbmcuCi0gICAqLwotICBwcm90ZWN0ZWQgaW50W11bXVtdIG1fZWxlbUluZGV4ZXM7Ci0KLSAgLyoqIFRoZSBkZWZhdWx0IGJsb2NrIHNpemUgb2YgdGhlIG5vZGUgYXJyYXlzICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFRkFVTFRfQkxPQ0tTSVpFID0gNTEyOyAgLy8gZmF2b3Igc21hbGwgZG9jcy4KLQotICAvKiogVGhlIG51bWJlciBvZiBibG9ja3MgZm9yIHRoZSBub2RlIGFycmF5cyAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBERUZBVUxUX05VTUJMT0NLUyA9IDMyOwotCi0gIC8qKiBUaGUgbnVtYmVyIG9mIGJsb2NrcyB1c2VkIGZvciBzbWFsbCBkb2N1bWVudHMgJiBSVEZzICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFRkFVTFRfTlVNQkxPQ0tTX1NNQUxMID0gNDsKLQotICAvKiogVGhlIGJsb2NrIHNpemUgb2YgdGhlIG5vZGUgYXJyYXlzICovCi0gIC8vcHJvdGVjdGVkIGZpbmFsIGludCBtX2Jsb2Nrc2l6ZTsKLQotICAvKioKLSAgICogVGhlIHZhbHVlIHRvIHVzZSB3aGVuIHRoZSBpbmZvcm1hdGlvbiBoYXMgbm90IGJlZW4gYnVpbHQgeWV0LgotICAgKi8KLSAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBpbnQgTk9UUFJPQ0VTU0VEID0gRFRNLk5VTEwgLSAxOwotCi0gIC8qKgotICAgKiBUaGUgRFRNIG1hbmFnZXIgd2hvICJvd25zIiB0aGlzIERUTS4KLSAgICovCi0KLSAgcHVibGljIERUTU1hbmFnZXIgbV9tZ3I7Ci0KLSAgLyoqCi0gICAqIG1fbWdyIGNhc3QgdG8gRFRNTWFuYWdlckRlZmF1bHQsIG9yIG51bGwgaWYgaXQgaXNuJ3QgYW4gaW5zdGFuY2UKLSAgICogKEVmZmljaWVuY3kgaG9vaykKLSAgICovCi0gIHByb3RlY3RlZCBEVE1NYW5hZ2VyRGVmYXVsdCBtX21nckRlZmF1bHQ9bnVsbDsKLQotCi0gIC8qKiBUaGUgZG9jdW1lbnQgaWRlbnRpdHkgbnVtYmVyKHMpLiBJZiB3ZSBoYXZlIG92ZXJmbG93ZWQgdGhlIGFkZHJlc3NpbmcKLSAgICogcmFuZ2Ugb2YgdGhlIGZpcnN0IHRoYXQgd2FzIGFzc2lnbmVkIHRvIHVzLCB3ZSBtYXkgYWRkIG90aGVycy4gKi8KLSAgcHJvdGVjdGVkIFN1YmFsbG9jYXRlZEludFZlY3RvciBtX2R0bUlkZW50OwotCi0gIC8qKiBUaGUgbWFzayBmb3IgdGhlIGlkZW50aXR5LgotICAgICAgJVJFVklFVyUgU2hvdWxkIHRoaXMgcmVhbGx5IGJlIHNldCB0byB0aGUgX0RFRkFVTFQ/IFdoYXQgaWYKLSAgICAgIGEgcGFydGljdWxhciBEVE0gd2FudGVkIHRvIHVzZSBhbm90aGVyIHZhbHVlPyAqLwotICAvL3Byb3RlY3RlZCBmaW5hbCBzdGF0aWMgaW50IG1fbWFzayA9IERUTU1hbmFnZXIuSURFTlRfTk9ERV9ERUZBVUxUOwotCi0gIC8qKiBUaGUgYmFzZSBVUkkgZm9yIHRoaXMgZG9jdW1lbnQuICovCi0gIHByb3RlY3RlZCBTdHJpbmcgbV9kb2N1bWVudEJhc2VVUkk7Ci0KLSAgLyoqCi0gICAqIFRoZSB3aGl0ZXNwYWNlIGZpbHRlciB0aGF0IGVuYWJsZXMgZWxlbWVudHMgdG8gc3RyaXAgd2hpdGVzcGFjZSBvciBub3QuCi0gICAqLwotICBwcm90ZWN0ZWQgRFRNV1NGaWx0ZXIgbV93c2ZpbHRlcjsKLQotICAvKiogRmxhZyBpbmRpY2F0aW5nIHdoZXRoZXIgdG8gc3RyaXAgd2hpdGVzcGFjZSBub2RlcyAqLwotICBwcm90ZWN0ZWQgYm9vbGVhbiBtX3Nob3VsZFN0cmlwV1MgPSBmYWxzZTsKLQotICAvKiogU3RhY2sgb2YgZmxhZ3MgaW5kaWNhdGluZyB3aGV0aGVyIHRvIHN0cmlwIHdoaXRlc3BhY2Ugbm9kZXMgKi8KLSAgcHJvdGVjdGVkIEJvb2xTdGFjayBtX3Nob3VsZFN0cmlwV2hpdGVzcGFjZVN0YWNrOwotCi0gIC8qKiBUaGUgWE1MU3RyaW5nIGZhY3RvcnkgZm9yIGNyZWF0aW5nIFhNTFN0cmluZ3MuICovCi0gIHByb3RlY3RlZCBYTUxTdHJpbmdGYWN0b3J5IG1feHN0cmY7Ci0KLSAgLyoqCi0gICAqIFRoZSB0YWJsZSBmb3IgZXhhbmRlZE5hbWVJRCBsb29rdXBzLiAgVGhpcyBtYXkgb3IgbWF5IG5vdCBiZSB0aGUgc2FtZQotICAgKiB0YWJsZSBhcyBpcyBjb250YWluZWQgaW4gdGhlIERUTU1hbmFnZXJEZWZhdWx0LgotICAgKi8KLSAgcHJvdGVjdGVkIEV4cGFuZGVkTmFtZVRhYmxlIG1fZXhwYW5kZWROYW1lVGFibGU7Ci0KLSAgLyoqIHRydWUgaWYgaW5kZXhpbmcgaXMgdHVybmVkIG9uLiAqLwotICBwcm90ZWN0ZWQgYm9vbGVhbiBtX2luZGV4aW5nOwotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBEVE1EZWZhdWx0QmFzZSBvYmplY3QgdXNpbmcgdGhlIGRlZmF1bHQgYmxvY2sgc2l6ZS4KLSAgICoKLSAgICogQHBhcmFtIG1nciBUaGUgRFRNTWFuYWdlciB3aG8gb3ducyB0aGlzIERUTS4KLSAgICogQHBhcmFtIHNvdXJjZSBUaGUgb2JqZWN0IHRoYXQgaXMgdXNlZCB0byBzcGVjaWZ5IHRoZSBjb25zdHJ1Y3Rpb24gc291cmNlLgotICAgKiBAcGFyYW0gZHRtSWRlbnRpdHkgVGhlIERUTSBpZGVudGl0eSBJRCBmb3IgdGhpcyBEVE0uCi0gICAqIEBwYXJhbSB3aGl0ZVNwYWNlRmlsdGVyIFRoZSB3aGl0ZSBzcGFjZSBmaWx0ZXIgZm9yIHRoaXMgRFRNLCB3aGljaCBtYXkKLSAgICogICAgICAgICAgICAgICAgICAgICAgICAgYmUgbnVsbC4KLSAgICogQHBhcmFtIHhzdHJpbmdmYWN0b3J5IFRoZSBmYWN0b3J5IHRvIHVzZSBmb3IgY3JlYXRpbmcgWE1MU3RyaW5ncy4KLSAgICogQHBhcmFtIGRvSW5kZXhpbmcgdHJ1ZSBpZiB0aGUgY2FsbGVyIGNvbnNpZGVycyBpdCB3b3J0aCBpdCB0byB1c2UKLSAgICogICAgICAgICAgICAgICAgICAgaW5kZXhpbmcgc2NoZW1lcy4KLSAgICovCi0gIHB1YmxpYyBEVE1EZWZhdWx0QmFzZShEVE1NYW5hZ2VyIG1nciwgU291cmNlIHNvdXJjZSwgaW50IGR0bUlkZW50aXR5LAotICAgICAgICAgICAgICAgICAgICAgICAgRFRNV1NGaWx0ZXIgd2hpdGVTcGFjZUZpbHRlciwKLSAgICAgICAgICAgICAgICAgICAgICAgIFhNTFN0cmluZ0ZhY3RvcnkgeHN0cmluZ2ZhY3RvcnksIGJvb2xlYW4gZG9JbmRleGluZykKLSAgewotICAgIHRoaXMobWdyLCBzb3VyY2UsIGR0bUlkZW50aXR5LCB3aGl0ZVNwYWNlRmlsdGVyLCB4c3RyaW5nZmFjdG9yeSwKLSAgICAgICAgIGRvSW5kZXhpbmcsIERFRkFVTFRfQkxPQ0tTSVpFLCB0cnVlLCBmYWxzZSk7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgRFRNRGVmYXVsdEJhc2Ugb2JqZWN0IGZyb20gYSBET00gbm9kZS4KLSAgICoKLSAgICogQHBhcmFtIG1nciBUaGUgRFRNTWFuYWdlciB3aG8gb3ducyB0aGlzIERUTS4KLSAgICogQHBhcmFtIHNvdXJjZSBUaGUgb2JqZWN0IHRoYXQgaXMgdXNlZCB0byBzcGVjaWZ5IHRoZSBjb25zdHJ1Y3Rpb24gc291cmNlLgotICAgKiBAcGFyYW0gZHRtSWRlbnRpdHkgVGhlIERUTSBpZGVudGl0eSBJRCBmb3IgdGhpcyBEVE0uCi0gICAqIEBwYXJhbSB3aGl0ZVNwYWNlRmlsdGVyIFRoZSB3aGl0ZSBzcGFjZSBmaWx0ZXIgZm9yIHRoaXMgRFRNLCB3aGljaCBtYXkKLSAgICogICAgICAgICAgICAgICAgICAgICAgICAgYmUgbnVsbC4KLSAgICogQHBhcmFtIHhzdHJpbmdmYWN0b3J5IFRoZSBmYWN0b3J5IHRvIHVzZSBmb3IgY3JlYXRpbmcgWE1MU3RyaW5ncy4KLSAgICogQHBhcmFtIGRvSW5kZXhpbmcgdHJ1ZSBpZiB0aGUgY2FsbGVyIGNvbnNpZGVycyBpdCB3b3J0aCBpdCB0byB1c2UKLSAgICogICAgICAgICAgICAgICAgICAgaW5kZXhpbmcgc2NoZW1lcy4KLSAgICogQHBhcmFtIGJsb2Nrc2l6ZSBUaGUgYmxvY2sgc2l6ZSBvZiB0aGUgRFRNLgotICAgKiBAcGFyYW0gdXNlUHJldnNpYiB0cnVlIGlmIHdlIHdhbnQgdG8gYnVpbGQgdGhlIHByZXZpb3VzIHNpYmxpbmcgbm9kZSBhcnJheS4KLSAgICogQHBhcmFtIG5ld05hbWVUYWJsZSB0cnVlIGlmIHdlIHdhbnQgdG8gdXNlIGEgbmV3IEV4cGFuZGVkTmFtZVRhYmxlIGZvciB0aGlzIERUTS4KLSAgICovCi0gIHB1YmxpYyBEVE1EZWZhdWx0QmFzZShEVE1NYW5hZ2VyIG1nciwgU291cmNlIHNvdXJjZSwgaW50IGR0bUlkZW50aXR5LAotICAgICAgICAgICAgICAgICAgICAgICAgRFRNV1NGaWx0ZXIgd2hpdGVTcGFjZUZpbHRlciwKLSAgICAgICAgICAgICAgICAgICAgICAgIFhNTFN0cmluZ0ZhY3RvcnkgeHN0cmluZ2ZhY3RvcnksIGJvb2xlYW4gZG9JbmRleGluZywKLSAgICAgICAgICAgICAgICAgICAgICAgIGludCBibG9ja3NpemUsIGJvb2xlYW4gdXNlUHJldnNpYiwKLSAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gbmV3TmFtZVRhYmxlKQotICB7Ci0gICAgLy8gVXNlIHNtYWxsZXIgc2l6ZXMgZm9yIHRoZSBpbnRlcm5hbCBub2RlIGFycmF5cyBpZiB0aGUgYmxvY2sgc2l6ZQotICAgIC8vIGlzIHNtYWxsLgotICAgIGludCBudW1ibG9ja3M7Ci0gICAgaWYgKGJsb2Nrc2l6ZSA8PSA2NCkKLSAgICB7Ci0gICAgICBudW1ibG9ja3MgPSBERUZBVUxUX05VTUJMT0NLU19TTUFMTDsKLSAgICAgIG1fZHRtSWRlbnQ9IG5ldyBTdWJhbGxvY2F0ZWRJbnRWZWN0b3IoNCwgMSk7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBudW1ibG9ja3MgPSBERUZBVUxUX05VTUJMT0NLUzsKLSAgICAgIG1fZHRtSWRlbnQ9IG5ldyBTdWJhbGxvY2F0ZWRJbnRWZWN0b3IoMzIpOwotICAgIH0KLQotICAgIG1fZXhwdHlwZSA9IG5ldyBTdWJhbGxvY2F0ZWRJbnRWZWN0b3IoYmxvY2tzaXplLCBudW1ibG9ja3MpOwotICAgIG1fZmlyc3RjaCA9IG5ldyBTdWJhbGxvY2F0ZWRJbnRWZWN0b3IoYmxvY2tzaXplLCBudW1ibG9ja3MpOwotICAgIG1fbmV4dHNpYiA9IG5ldyBTdWJhbGxvY2F0ZWRJbnRWZWN0b3IoYmxvY2tzaXplLCBudW1ibG9ja3MpOwotICAgIG1fcGFyZW50ICA9IG5ldyBTdWJhbGxvY2F0ZWRJbnRWZWN0b3IoYmxvY2tzaXplLCBudW1ibG9ja3MpOwotCi0gICAgLy8gT25seSBjcmVhdGUgdGhlIG1fcHJldnNpYiBhcnJheSBpZiB0aGUgdXNlUHJldnNpYiBmbGFnIGlzIHRydWUuCi0gICAgLy8gU29tZSBEVE0gaW1wbGVtZW50YXRpb25zIChlLmcuIFNBWEltcGwpIGRvIG5vdCBuZWVkIHRoaXMgYXJyYXkuCi0gICAgLy8gV2UgY2FuIHNhdmUgdGhlIHRpbWUgdG8gYnVpbGQgaXQgaW4gdGhvc2UgY2FzZXMuCi0gICAgaWYgKHVzZVByZXZzaWIpCi0gICAgICBtX3ByZXZzaWIgPSBuZXcgU3ViYWxsb2NhdGVkSW50VmVjdG9yKGJsb2Nrc2l6ZSwgbnVtYmxvY2tzKTsKLQotICAgIG1fbWdyID0gbWdyOwotICAgIGlmKG1nciBpbnN0YW5jZW9mIERUTU1hbmFnZXJEZWZhdWx0KQotICAgICAgbV9tZ3JEZWZhdWx0PShEVE1NYW5hZ2VyRGVmYXVsdCltZ3I7Ci0KLSAgICBtX2RvY3VtZW50QmFzZVVSSSA9IChudWxsICE9IHNvdXJjZSkgPyBzb3VyY2UuZ2V0U3lzdGVtSWQoKSA6IG51bGw7Ci0gICAgbV9kdG1JZGVudC5zZXRFbGVtZW50QXQoZHRtSWRlbnRpdHksMCk7Ci0gICAgbV93c2ZpbHRlciA9IHdoaXRlU3BhY2VGaWx0ZXI7Ci0gICAgbV94c3RyZiA9IHhzdHJpbmdmYWN0b3J5OwotICAgIG1faW5kZXhpbmcgPSBkb0luZGV4aW5nOwotCi0gICAgaWYgKGRvSW5kZXhpbmcpCi0gICAgewotICAgICAgbV9leHBhbmRlZE5hbWVUYWJsZSA9IG5ldyBFeHBhbmRlZE5hbWVUYWJsZSgpOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgLy8gTm90ZSB0aGF0IHRoaXMgZmFpbHMgaWYgd2UgYXJlbid0IHRhbGtpbmcgdG8gYW4gaW5zdGFuY2Ugb2YKLSAgICAgIC8vIERUTU1hbmFnZXJEZWZhdWx0Ci0gICAgICBtX2V4cGFuZGVkTmFtZVRhYmxlID0gbV9tZ3JEZWZhdWx0LmdldEV4cGFuZGVkTmFtZVRhYmxlKHRoaXMpOwotICAgIH0KLQotICAgIGlmIChudWxsICE9IHdoaXRlU3BhY2VGaWx0ZXIpCi0gICAgewotICAgICAgbV9zaG91bGRTdHJpcFdoaXRlc3BhY2VTdGFjayA9IG5ldyBCb29sU3RhY2soKTsKLQotICAgICAgcHVzaFNob3VsZFN0cmlwV2hpdGVzcGFjZShmYWxzZSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEVuc3VyZSB0aGF0IHRoZSBzaXplIG9mIHRoZSBlbGVtZW50IGluZGV4ZXMgY2FuIGhvbGQgdGhlIGluZm9ybWF0aW9uLgotICAgKgotICAgKiBAcGFyYW0gbmFtZXNwYWNlSUQgTmFtZXNwYWNlIElEIGluZGV4LgotICAgKiBAcGFyYW0gTG9jYWxOYW1lSUQgTG9jYWwgbmFtZSBJRC4KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIGVuc3VyZVNpemVPZkluZGV4KGludCBuYW1lc3BhY2VJRCwgaW50IExvY2FsTmFtZUlEKQotICB7Ci0KLSAgICBpZiAobnVsbCA9PSBtX2VsZW1JbmRleGVzKQotICAgIHsKLSAgICAgIG1fZWxlbUluZGV4ZXMgPSBuZXcgaW50W25hbWVzcGFjZUlEICsgMjBdW11bXTsKLSAgICB9Ci0gICAgZWxzZSBpZiAobV9lbGVtSW5kZXhlcy5sZW5ndGggPD0gbmFtZXNwYWNlSUQpCi0gICAgewotICAgICAgaW50W11bXVtdIGluZGV4ZXMgPSBtX2VsZW1JbmRleGVzOwotCi0gICAgICBtX2VsZW1JbmRleGVzID0gbmV3IGludFtuYW1lc3BhY2VJRCArIDIwXVtdW107Ci0KLSAgICAgIFN5c3RlbS5hcnJheWNvcHkoaW5kZXhlcywgMCwgbV9lbGVtSW5kZXhlcywgMCwgaW5kZXhlcy5sZW5ndGgpOwotICAgIH0KLQotICAgIGludFtdW10gbG9jYWxOYW1lSW5kZXggPSBtX2VsZW1JbmRleGVzW25hbWVzcGFjZUlEXTsKLQotICAgIGlmIChudWxsID09IGxvY2FsTmFtZUluZGV4KQotICAgIHsKLSAgICAgIGxvY2FsTmFtZUluZGV4ID0gbmV3IGludFtMb2NhbE5hbWVJRCArIDEwMF1bXTsKLSAgICAgIG1fZWxlbUluZGV4ZXNbbmFtZXNwYWNlSURdID0gbG9jYWxOYW1lSW5kZXg7Ci0gICAgfQotICAgIGVsc2UgaWYgKGxvY2FsTmFtZUluZGV4Lmxlbmd0aCA8PSBMb2NhbE5hbWVJRCkKLSAgICB7Ci0gICAgICBpbnRbXVtdIGluZGV4ZXMgPSBsb2NhbE5hbWVJbmRleDsKLQotICAgICAgbG9jYWxOYW1lSW5kZXggPSBuZXcgaW50W0xvY2FsTmFtZUlEICsgMTAwXVtdOwotCi0gICAgICBTeXN0ZW0uYXJyYXljb3B5KGluZGV4ZXMsIDAsIGxvY2FsTmFtZUluZGV4LCAwLCBpbmRleGVzLmxlbmd0aCk7Ci0KLSAgICAgIG1fZWxlbUluZGV4ZXNbbmFtZXNwYWNlSURdID0gbG9jYWxOYW1lSW5kZXg7Ci0gICAgfQotCi0gICAgaW50W10gZWxlbUhhbmRsZXMgPSBsb2NhbE5hbWVJbmRleFtMb2NhbE5hbWVJRF07Ci0KLSAgICBpZiAobnVsbCA9PSBlbGVtSGFuZGxlcykKLSAgICB7Ci0gICAgICBlbGVtSGFuZGxlcyA9IG5ldyBpbnRbMTI4XTsKLSAgICAgIGxvY2FsTmFtZUluZGV4W0xvY2FsTmFtZUlEXSA9IGVsZW1IYW5kbGVzOwotICAgICAgZWxlbUhhbmRsZXNbMF0gPSAxOwotICAgIH0KLSAgICBlbHNlIGlmIChlbGVtSGFuZGxlcy5sZW5ndGggPD0gZWxlbUhhbmRsZXNbMF0gKyAxKQotICAgIHsKLSAgICAgIGludFtdIGluZGV4ZXMgPSBlbGVtSGFuZGxlczsKLQotICAgICAgZWxlbUhhbmRsZXMgPSBuZXcgaW50W2VsZW1IYW5kbGVzWzBdICsgMTAyNF07Ci0KLSAgICAgIFN5c3RlbS5hcnJheWNvcHkoaW5kZXhlcywgMCwgZWxlbUhhbmRsZXMsIDAsIGluZGV4ZXMubGVuZ3RoKTsKLQotICAgICAgbG9jYWxOYW1lSW5kZXhbTG9jYWxOYW1lSURdID0gZWxlbUhhbmRsZXM7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEFkZCBhIG5vZGUgdG8gdGhlIGVsZW1lbnQgaW5kZXhlcy4gVGhlIG5vZGUgd2lsbCBub3QgYmUgYWRkZWQgdW5sZXNzCi0gICAqIGl0J3MgYW4gZWxlbWVudC4KLSAgICoKLSAgICogQHBhcmFtIGV4cGFuZGVkVHlwZUlEIFRoZSBleHBhbmRlZCB0eXBlIElEIG9mIHRoZSBub2RlLgotICAgKiBAcGFyYW0gaWRlbnRpdHkgVGhlIG5vZGUgaWRlbnRpdHkgaW5kZXguCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBpbmRleE5vZGUoaW50IGV4cGFuZGVkVHlwZUlELCBpbnQgaWRlbnRpdHkpCi0gIHsKLQotICAgIEV4cGFuZGVkTmFtZVRhYmxlIGVudCA9IG1fZXhwYW5kZWROYW1lVGFibGU7Ci0gICAgc2hvcnQgdHlwZSA9IGVudC5nZXRUeXBlKGV4cGFuZGVkVHlwZUlEKTsKLQotICAgIGlmIChEVE0uRUxFTUVOVF9OT0RFID09IHR5cGUpCi0gICAgewotICAgICAgaW50IG5hbWVzcGFjZUlEID0gZW50LmdldE5hbWVzcGFjZUlEKGV4cGFuZGVkVHlwZUlEKTsKLSAgICAgIGludCBsb2NhbE5hbWVJRCA9IGVudC5nZXRMb2NhbE5hbWVJRChleHBhbmRlZFR5cGVJRCk7Ci0KLSAgICAgIGVuc3VyZVNpemVPZkluZGV4KG5hbWVzcGFjZUlELCBsb2NhbE5hbWVJRCk7Ci0KLSAgICAgIGludFtdIGluZGV4ID0gbV9lbGVtSW5kZXhlc1tuYW1lc3BhY2VJRF1bbG9jYWxOYW1lSURdOwotCi0gICAgICBpbmRleFtpbmRleFswXV0gPSBpZGVudGl0eTsKLQotICAgICAgaW5kZXhbMF0rKzsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogRmluZCB0aGUgZmlyc3QgaW5kZXggdGhhdCBvY2N1cnMgaW4gdGhlIGxpc3QgdGhhdCBpcyBncmVhdGVyIHRoYW4gb3IKLSAgICogZXF1YWwgdG8gdGhlIGdpdmVuIHZhbHVlLgotICAgKgotICAgKiBAcGFyYW0gbGlzdCBBIGxpc3Qgb2YgaW50ZWdlcnMuCi0gICAqIEBwYXJhbSBzdGFydCBUaGUgc3RhcnQgaW5kZXggdG8gYmVnaW4gdGhlIHNlYXJjaC4KLSAgICogQHBhcmFtIGxlbiBUaGUgbnVtYmVyIG9mIGl0ZW1zIHRvIHNlYXJjaC4KLSAgICogQHBhcmFtIHZhbHVlIEZpbmQgdGhlIHNsb3QgdGhhdCBoYXMgYSB2YWx1ZSB0aGF0IGlzIGdyZWF0ZXIgdGhhbiBvcgotICAgKiBpZGVudGljYWwgdG8gdGhpcyBhcmd1bWVudC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgaW5kZXggaW4gdGhlIGxpc3Qgb2YgdGhlIHNsb3QgdGhhdCBpcyBoaWdoZXIgb3IgaWRlbnRpY2FsCi0gICAqIHRvIHRoZSBpZGVudGl0eSBhcmd1bWVudCwgb3IgLTEgaWYgbm8gbm9kZSBpcyBoaWdoZXIgb3IgZXF1YWwuCi0gICAqLwotICBwcm90ZWN0ZWQgaW50IGZpbmRHVEUoaW50W10gbGlzdCwgaW50IHN0YXJ0LCBpbnQgbGVuLCBpbnQgdmFsdWUpCi0gIHsKLQotICAgIGludCBsb3cgPSBzdGFydDsKLSAgICBpbnQgaGlnaCA9IHN0YXJ0ICsgKGxlbiAtIDEpOwotICAgIGludCBlbmQgPSBoaWdoOwotCi0gICAgd2hpbGUgKGxvdyA8PSBoaWdoKQotICAgIHsKLSAgICAgIGludCBtaWQgPSAobG93ICsgaGlnaCkgLyAyOwotICAgICAgaW50IGMgPSBsaXN0W21pZF07Ci0KLSAgICAgIGlmIChjID4gdmFsdWUpCi0gICAgICAgIGhpZ2ggPSBtaWQgLSAxOwotICAgICAgZWxzZSBpZiAoYyA8IHZhbHVlKQotICAgICAgICBsb3cgPSBtaWQgKyAxOwotICAgICAgZWxzZQotICAgICAgICByZXR1cm4gbWlkOwotICAgIH0KLQotICAgIHJldHVybiAobG93IDw9IGVuZCAmJiBsaXN0W2xvd10gPiB2YWx1ZSkgPyBsb3cgOiAtMTsKLSAgfQotCi0gIC8qKgotICAgKiBGaW5kIHRoZSBmaXJzdCBtYXRjaGluZyBlbGVtZW50IGZyb20gdGhlIGluZGV4IGF0IG9yIGFmdGVyIHRoZQotICAgKiBnaXZlbiBub2RlLgotICAgKgotICAgKiBAcGFyYW0gbnNJbmRleCBUaGUgbmFtZXNwYWNlIGluZGV4IGxvb2t1cC4KLSAgICogQHBhcmFtIGxuSW5kZXggVGhlIGxvY2FsIG5hbWUgaW5kZXggbG9va3VwLgotICAgKiBAcGFyYW0gZmlyc3RQb3RlbnRpYWwgVGhlIGZpcnN0IHBvdGVudGlhbCBtYXRjaCB0aGF0IGlzIHdvcnRoIGxvb2tpbmcgYXQuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGZpcnN0IG5vZGUgdGhhdCBpcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gdGhlCi0gICAqICAgICAgICAgZmlyc3RQb3RlbnRpYWwgYXJndW1lbnQsIG9yIERUTS5OT1RQUk9DRVNTRUQgaWYgbm90IGZvdW5kLgotICAgKi8KLSAgaW50IGZpbmRFbGVtZW50RnJvbUluZGV4KGludCBuc0luZGV4LCBpbnQgbG5JbmRleCwgaW50IGZpcnN0UG90ZW50aWFsKQotICB7Ci0KLSAgICBpbnRbXVtdW10gaW5kZXhlcyA9IG1fZWxlbUluZGV4ZXM7Ci0KLSAgICBpZiAobnVsbCAhPSBpbmRleGVzICYmIG5zSW5kZXggPCBpbmRleGVzLmxlbmd0aCkKLSAgICB7Ci0gICAgICBpbnRbXVtdIGxuSW5kZXhzID0gaW5kZXhlc1tuc0luZGV4XTsKLQotICAgICAgaWYgKG51bGwgIT0gbG5JbmRleHMgJiYgbG5JbmRleCA8IGxuSW5kZXhzLmxlbmd0aCkKLSAgICAgIHsKLSAgICAgICAgaW50W10gZWxlbXMgPSBsbkluZGV4c1tsbkluZGV4XTsKLQotICAgICAgICBpZiAobnVsbCAhPSBlbGVtcykKLSAgICAgICAgewotICAgICAgICAgIGludCBwb3MgPSBmaW5kR1RFKGVsZW1zLCAxLCBlbGVtc1swXSwgZmlyc3RQb3RlbnRpYWwpOwotCi0gICAgICAgICAgaWYgKHBvcyA+IC0xKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIHJldHVybiBlbGVtc1twb3NdOwotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiBOT1RQUk9DRVNTRUQ7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBuZXh0IG5vZGUgaWRlbnRpdHkgdmFsdWUgaW4gdGhlIGxpc3QsIGFuZCBjYWxsIHRoZSBpdGVyYXRvcgotICAgKiBpZiBpdCBoYXNuJ3QgYmVlbiBhZGRlZCB5ZXQuCi0gICAqCi0gICAqIEBwYXJhbSBpZGVudGl0eSBUaGUgbm9kZSBpZGVudGl0eSAoaW5kZXgpLgotICAgKiBAcmV0dXJuIGlkZW50aXR5KzEsIG9yIERUTS5OVUxMLgotICAgKi8KLSAgcHJvdGVjdGVkIGFic3RyYWN0IGludCBnZXROZXh0Tm9kZUlkZW50aXR5KGludCBpZGVudGl0eSk7Ci0KLSAgLyoqCi0gICAqIFRoaXMgbWV0aG9kIHNob3VsZCB0cnkgYW5kIGJ1aWxkIG9uZSBvciBtb3JlIG5vZGVzIGluIHRoZSB0YWJsZS4KLSAgICoKLSAgICogQHJldHVybiBUaGUgdHJ1ZSBpZiBhIG5leHQgbm9kZSBpcyBmb3VuZCBvciBmYWxzZSBpZgotICAgKiAgICAgICAgIHRoZXJlIGFyZSBubyBtb3JlIG5vZGVzLgotICAgKi8KLSAgcHJvdGVjdGVkIGFic3RyYWN0IGJvb2xlYW4gbmV4dE5vZGUoKTsKLQotICAvKioKLSAgICogR2V0IHRoZSBudW1iZXIgb2Ygbm9kZXMgdGhhdCBoYXZlIGJlZW4gYWRkZWQuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBub2RlcyB0aGF0IGhhdmUgYmVlbiBtYXBwZWQuCi0gICAqLwotICBwcm90ZWN0ZWQgYWJzdHJhY3QgaW50IGdldE51bWJlck9mTm9kZXMoKTsKLQotICAvKiogU3RhdGVsZXNzIGF4aXMgdHJhdmVyc2VycywgbGF6ZWx5IGJ1aWx0LiAqLwotICBwcm90ZWN0ZWQgRFRNQXhpc1RyYXZlcnNlcltdIG1fdHJhdmVyc2VyczsKLQotLy8gICAgLyoqCi0vLyAgICAgKiBFbnN1cmUgdGhhdCB0aGUgc2l6ZSBvZiB0aGUgaW5mb3JtYXRpb24gYXJyYXlzIGNhbiBob2xkIGFub3RoZXIgZW50cnkKLS8vICAgICAqIGF0IHRoZSBnaXZlbiBpbmRleC4KLS8vICAgICAqCi0vLyAgICAgKiBAcGFyYW0gaW5kZXggT24gZXhpdCBmcm9tIHRoaXMgZnVuY3Rpb24sIHRoZSBpbmZvcm1hdGlvbiBhcnJheXMgc2l6ZXMgbXVzdCBiZQotLy8gICAgICogYXQgbGVhc3QgaW5kZXgrMS4KLS8vICAgICAqLwotLy8gICAgcHJvdGVjdGVkIHZvaWQgZW5zdXJlU2l6ZShpbnQgaW5kZXgpCi0vLyAgICB7Ci0vLyAgICAgICAgLy8gV2UndmUgY3V0IG92ZXIgdG8gU3ViYWxsb2NhdGVkKlZlY3Rvciwgd2hpY2ggYXJlIHNlbGYtc2l6aW5nLgotLy8gICAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIHNpbXBsZSB0eXBlIElEIGZvciB0aGUgZ2l2ZW4gbm9kZSBpZGVudGl0eS4KLSAgICoKLSAgICogQHBhcmFtIGlkZW50aXR5IFRoZSBub2RlIGlkZW50aXR5LgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBzaW1wbGUgdHlwZSBJRCwgb3IgRFRNLk5VTEwuCi0gICAqLwotICBwcm90ZWN0ZWQgc2hvcnQgX3R5cGUoaW50IGlkZW50aXR5KQotICB7Ci0KLSAgICBpbnQgaW5mbyA9IF9leHB0eXBlKGlkZW50aXR5KTsKLQotICAgIGlmIChOVUxMICE9IGluZm8pCi0gICAgICByZXR1cm4gbV9leHBhbmRlZE5hbWVUYWJsZS5nZXRUeXBlKGluZm8pOwotICAgIGVsc2UKLSAgICAgIHJldHVybiBOVUxMOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgZXhwYW5kZWQgdHlwZSBJRCBmb3IgdGhlIGdpdmVuIG5vZGUgaWRlbnRpdHkuCi0gICAqCi0gICAqIEBwYXJhbSBpZGVudGl0eSBUaGUgbm9kZSBpZGVudGl0eS4KLSAgICoKLSAgICogQHJldHVybiBUaGUgZXhwYW5kZWQgdHlwZSBJRCwgb3IgRFRNLk5VTEwuCi0gICAqLwotICBwcm90ZWN0ZWQgaW50IF9leHB0eXBlKGludCBpZGVudGl0eSkKLSAgewotICAgICAgICBpZiAoaWRlbnRpdHkgPT0gRFRNLk5VTEwpCi0gICAgICAgIHJldHVybiBOVUxMOwotICAgIC8vIFJlb3JnYW5pemVkIHRlc3QgYW5kIGxvb3AgaW50byBzaW5nbGUgZmxvdwotICAgIC8vIFRpbnkgcGVyZm9ybWFuY2UgaW1wcm92ZW1lbnQsIHNhdmVzIGEgZmV3IGJ5dGVzIG9mIGNvZGUsIGNsZWFyZXIuCi0gICAgLy8gJU9QVCUgT3RoZXIgaW50ZXJuYWwgZ2V0dGVycyBjb3VsZCBiZSB0cmVhdGVkIHNpbWxpYXJseQotICAgIHdoaWxlIChpZGVudGl0eT49bV9zaXplKQotICAgIHsKLSAgICAgIGlmICghbmV4dE5vZGUoKSAmJiBpZGVudGl0eSA+PSBtX3NpemUpCi0gICAgICAgIHJldHVybiBOVUxMOwotICAgIH0KLSAgICByZXR1cm4gbV9leHB0eXBlLmVsZW1lbnRBdChpZGVudGl0eSk7Ci0KLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGxldmVsIGluIHRoZSB0cmVlIGZvciB0aGUgZ2l2ZW4gbm9kZSBpZGVudGl0eS4KLSAgICoKLSAgICogQHBhcmFtIGlkZW50aXR5IFRoZSBub2RlIGlkZW50aXR5LgotICAgKgotICAgKiBAcmV0dXJuIFRoZSB0cmVlIGxldmVsLCBvciBEVE0uTlVMTC4KLSAgICovCi0gIHByb3RlY3RlZCBpbnQgX2xldmVsKGludCBpZGVudGl0eSkKLSAgewotICAgIHdoaWxlIChpZGVudGl0eT49bV9zaXplKQotICAgIHsKLSAgICAgIGJvb2xlYW4gaXNNb3JlID0gbmV4dE5vZGUoKTsKLSAgICAgIGlmICghaXNNb3JlICYmIGlkZW50aXR5ID49IG1fc2l6ZSkKLSAgICAgICAgcmV0dXJuIE5VTEw7Ci0gICAgfQotCi0gICAgaW50IGk9MDsKLSAgICB3aGlsZShOVUxMICE9IChpZGVudGl0eT1fcGFyZW50KGlkZW50aXR5KSkpCi0gICAgICArK2k7Ci0gICAgcmV0dXJuIGk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBmaXJzdCBjaGlsZCBmb3IgdGhlIGdpdmVuIG5vZGUgaWRlbnRpdHkuCi0gICAqCi0gICAqIEBwYXJhbSBpZGVudGl0eSBUaGUgbm9kZSBpZGVudGl0eS4KLSAgICoKLSAgICogQHJldHVybiBUaGUgZmlyc3QgY2hpbGQgaWRlbnRpdHksIG9yIERUTS5OVUxMLgotICAgKi8KLSAgcHJvdGVjdGVkIGludCBfZmlyc3RjaChpbnQgaWRlbnRpdHkpCi0gIHsKLQotICAgIC8vIEJvaWxlci1wbGF0ZSBjb2RlIGZvciBlYWNoIG9mIHRoZSBfeHh4IGZ1bmN0aW9ucywgZXhjZXB0IGZvciB0aGUgYXJyYXkuCi0gICAgaW50IGluZm8gPSAoaWRlbnRpdHkgPj0gbV9zaXplKSA/IE5PVFBST0NFU1NFRCA6IG1fZmlyc3RjaC5lbGVtZW50QXQoaWRlbnRpdHkpOwotCi0gICAgLy8gQ2hlY2sgdG8gc2VlIGlmIHRoZSBpbmZvcm1hdGlvbiByZXF1ZXN0ZWQgaGFzIGJlZW4gcHJvY2Vzc2VkLCBhbmQsCi0gICAgLy8gaWYgbm90LCBhZHZhbmNlIHRoZSBpdGVyYXRvciB1bnRpbCB3ZSB0aGUgaW5mb3JtYXRpb24gaGFzIGJlZW4KLSAgICAvLyBwcm9jZXNzZWQuCi0gICAgd2hpbGUgKGluZm8gPT0gTk9UUFJPQ0VTU0VEKQotICAgIHsKLSAgICAgIGJvb2xlYW4gaXNNb3JlID0gbmV4dE5vZGUoKTsKLQotICAgICAgaWYgKGlkZW50aXR5ID49IG1fc2l6ZSAmJiFpc01vcmUpCi0gICAgICAgIHJldHVybiBOVUxMOwotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBpbmZvID0gbV9maXJzdGNoLmVsZW1lbnRBdChpZGVudGl0eSk7Ci0gICAgICAgIGlmKGluZm8gPT0gTk9UUFJPQ0VTU0VEICYmICFpc01vcmUpCi0gICAgICAgICAgcmV0dXJuIE5VTEw7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgcmV0dXJuIGluZm87Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBuZXh0IHNpYmxpbmcgZm9yIHRoZSBnaXZlbiBub2RlIGlkZW50aXR5LgotICAgKgotICAgKiBAcGFyYW0gaWRlbnRpdHkgVGhlIG5vZGUgaWRlbnRpdHkuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIG5leHQgc2libGluZyBpZGVudGl0eSwgb3IgRFRNLk5VTEwuCi0gICAqLwotICBwcm90ZWN0ZWQgaW50IF9uZXh0c2liKGludCBpZGVudGl0eSkKLSAgewotICAgIC8vIEJvaWxlci1wbGF0ZSBjb2RlIGZvciBlYWNoIG9mIHRoZSBfeHh4IGZ1bmN0aW9ucywgZXhjZXB0IGZvciB0aGUgYXJyYXkuCi0gICAgaW50IGluZm8gPSAoaWRlbnRpdHkgPj0gbV9zaXplKSA/IE5PVFBST0NFU1NFRCA6IG1fbmV4dHNpYi5lbGVtZW50QXQoaWRlbnRpdHkpOwotCi0gICAgLy8gQ2hlY2sgdG8gc2VlIGlmIHRoZSBpbmZvcm1hdGlvbiByZXF1ZXN0ZWQgaGFzIGJlZW4gcHJvY2Vzc2VkLCBhbmQsCi0gICAgLy8gaWYgbm90LCBhZHZhbmNlIHRoZSBpdGVyYXRvciB1bnRpbCB3ZSB0aGUgaW5mb3JtYXRpb24gaGFzIGJlZW4KLSAgICAvLyBwcm9jZXNzZWQuCi0gICAgd2hpbGUgKGluZm8gPT0gTk9UUFJPQ0VTU0VEKQotICAgIHsKLSAgICAgIGJvb2xlYW4gaXNNb3JlID0gbmV4dE5vZGUoKTsKLQotICAgICAgaWYgKGlkZW50aXR5ID49IG1fc2l6ZSAmJiFpc01vcmUpCi0gICAgICAgIHJldHVybiBOVUxMOwotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBpbmZvID0gbV9uZXh0c2liLmVsZW1lbnRBdChpZGVudGl0eSk7Ci0gICAgICAgIGlmKGluZm8gPT0gTk9UUFJPQ0VTU0VEICYmICFpc01vcmUpCi0gICAgICAgICAgcmV0dXJuIE5VTEw7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgcmV0dXJuIGluZm87Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBwcmV2aW91cyBzaWJsaW5nIGZvciB0aGUgZ2l2ZW4gbm9kZSBpZGVudGl0eS4KLSAgICoKLSAgICogQHBhcmFtIGlkZW50aXR5IFRoZSBub2RlIGlkZW50aXR5LgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBwcmV2aW91cyBzaWJsaW5nIGlkZW50aXR5LCBvciBEVE0uTlVMTC4KLSAgICovCi0gIHByb3RlY3RlZCBpbnQgX3ByZXZzaWIoaW50IGlkZW50aXR5KQotICB7Ci0KLSAgICBpZiAoaWRlbnRpdHkgPCBtX3NpemUpCi0gICAgICByZXR1cm4gbV9wcmV2c2liLmVsZW1lbnRBdChpZGVudGl0eSk7Ci0KLSAgICAvLyBDaGVjayB0byBzZWUgaWYgdGhlIGluZm9ybWF0aW9uIHJlcXVlc3RlZCBoYXMgYmVlbiBwcm9jZXNzZWQsIGFuZCwKLSAgICAvLyBpZiBub3QsIGFkdmFuY2UgdGhlIGl0ZXJhdG9yIHVudGlsIHdlIHRoZSBpbmZvcm1hdGlvbiBoYXMgYmVlbgotICAgIC8vIHByb2Nlc3NlZC4KLSAgICB3aGlsZSAodHJ1ZSkKLSAgICB7Ci0gICAgICBib29sZWFuIGlzTW9yZSA9IG5leHROb2RlKCk7Ci0KLSAgICAgIGlmIChpZGVudGl0eSA+PSBtX3NpemUgJiYgIWlzTW9yZSkKLSAgICAgICAgcmV0dXJuIE5VTEw7Ci0gICAgICBlbHNlIGlmIChpZGVudGl0eSA8IG1fc2l6ZSkKLSAgICAgICAgcmV0dXJuIG1fcHJldnNpYi5lbGVtZW50QXQoaWRlbnRpdHkpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIHBhcmVudCBmb3IgdGhlIGdpdmVuIG5vZGUgaWRlbnRpdHkuCi0gICAqCi0gICAqIEBwYXJhbSBpZGVudGl0eSBUaGUgbm9kZSBpZGVudGl0eS4KLSAgICoKLSAgICogQHJldHVybiBUaGUgcGFyZW50IGlkZW50aXR5LCBvciBEVE0uTlVMTC4KLSAgICovCi0gIHByb3RlY3RlZCBpbnQgX3BhcmVudChpbnQgaWRlbnRpdHkpCi0gIHsKLQotICAgIGlmIChpZGVudGl0eSA8IG1fc2l6ZSkKLSAgICAgIHJldHVybiBtX3BhcmVudC5lbGVtZW50QXQoaWRlbnRpdHkpOwotCi0gICAgLy8gQ2hlY2sgdG8gc2VlIGlmIHRoZSBpbmZvcm1hdGlvbiByZXF1ZXN0ZWQgaGFzIGJlZW4gcHJvY2Vzc2VkLCBhbmQsCi0gICAgLy8gaWYgbm90LCBhZHZhbmNlIHRoZSBpdGVyYXRvciB1bnRpbCB3ZSB0aGUgaW5mb3JtYXRpb24gaGFzIGJlZW4KLSAgICAvLyBwcm9jZXNzZWQuCi0gICAgd2hpbGUgKHRydWUpCi0gICAgewotICAgICAgYm9vbGVhbiBpc01vcmUgPSBuZXh0Tm9kZSgpOwotCi0gICAgICBpZiAoaWRlbnRpdHkgPj0gbV9zaXplICYmICFpc01vcmUpCi0gICAgICAgIHJldHVybiBOVUxMOwotICAgICAgZWxzZSBpZiAoaWRlbnRpdHkgPCBtX3NpemUpCi0gICAgICAgIHJldHVybiBtX3BhcmVudC5lbGVtZW50QXQoaWRlbnRpdHkpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBEaWFnbm9zdGljcyBmdW5jdGlvbiB0byBkdW1wIHRoZSBEVE0uCi0gICAqLwotICBwdWJsaWMgdm9pZCBkdW1wRFRNKE91dHB1dFN0cmVhbSBvcykKLSAgewotICAgIHRyeQotICAgIHsKLSAgICAgIGlmKG9zPT1udWxsKQotICAgICAgewotICAgICAgICAgICAgICBGaWxlIGYgPSBuZXcgRmlsZSgiRFRNRHVtcCIrKChPYmplY3QpdGhpcykuaGFzaENvZGUoKSsiLnR4dCIpOwotICAgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIkR1bXBpbmcuLi4gIitmLmdldEFic29sdXRlUGF0aCgpKTsKLSAgICAgICAgICAgICAgb3M9bmV3IEZpbGVPdXRwdXRTdHJlYW0oZik7Ci0gICAgICB9Ci0gICAgICBQcmludFN0cmVhbSBwcyA9IG5ldyBQcmludFN0cmVhbShvcyk7Ci0KLSAgICAgIHdoaWxlIChuZXh0Tm9kZSgpKXt9Ci0KLSAgICAgIGludCBuUmVjb3JkcyA9IG1fc2l6ZTsKLQotICAgICAgcHMucHJpbnRsbigiVG90YWwgbm9kZXM6ICIgKyBuUmVjb3Jkcyk7Ci0KLSAgICAgIGZvciAoaW50IGluZGV4ID0gMDsgaW5kZXggPCBuUmVjb3JkczsgKytpbmRleCkKLSAgICAgIHsKLSAgICAgICAgaW50IGk9bWFrZU5vZGVIYW5kbGUoaW5kZXgpOwotICAgICAgICBwcy5wcmludGxuKCI9PT09PT09PT09PSBpbmRleD0iICsgaW5kZXggKyAiIGhhbmRsZT0iICsgaSArICIgPT09PT09PT09PT0iKTsKLSAgICAgICAgcHMucHJpbnRsbigiTm9kZU5hbWU6ICIgKyBnZXROb2RlTmFtZShpKSk7Ci0gICAgICAgIHBzLnByaW50bG4oIk5vZGVOYW1lWDogIiArIGdldE5vZGVOYW1lWChpKSk7Ci0gICAgICAgIHBzLnByaW50bG4oIkxvY2FsTmFtZTogIiArIGdldExvY2FsTmFtZShpKSk7Ci0gICAgICAgIHBzLnByaW50bG4oIk5hbWVzcGFjZVVSSTogIiArIGdldE5hbWVzcGFjZVVSSShpKSk7Ci0gICAgICAgIHBzLnByaW50bG4oIlByZWZpeDogIiArIGdldFByZWZpeChpKSk7Ci0KLSAgICAgICAgaW50IGV4VHlwZUlEID0gX2V4cHR5cGUoaW5kZXgpOwotCi0gICAgICAgIHBzLnByaW50bG4oIkV4cGFuZGVkIFR5cGUgSUQ6ICIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICsgSW50ZWdlci50b0hleFN0cmluZyhleFR5cGVJRCkpOwotCi0gICAgICAgIGludCB0eXBlID0gX3R5cGUoaW5kZXgpOwotICAgICAgICBTdHJpbmcgdHlwZXN0cmluZzsKLQotICAgICAgICBzd2l0Y2ggKHR5cGUpCi0gICAgICAgIHsKLSAgICAgICAgY2FzZSBEVE0uQVRUUklCVVRFX05PREUgOgotICAgICAgICAgIHR5cGVzdHJpbmcgPSAiQVRUUklCVVRFX05PREUiOwotICAgICAgICAgIGJyZWFrOwotICAgICAgICBjYXNlIERUTS5DREFUQV9TRUNUSU9OX05PREUgOgotICAgICAgICAgIHR5cGVzdHJpbmcgPSAiQ0RBVEFfU0VDVElPTl9OT0RFIjsKLSAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBEVE0uQ09NTUVOVF9OT0RFIDoKLSAgICAgICAgICB0eXBlc3RyaW5nID0gIkNPTU1FTlRfTk9ERSI7Ci0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgRFRNLkRPQ1VNRU5UX0ZSQUdNRU5UX05PREUgOgotICAgICAgICAgIHR5cGVzdHJpbmcgPSAiRE9DVU1FTlRfRlJBR01FTlRfTk9ERSI7Ci0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgRFRNLkRPQ1VNRU5UX05PREUgOgotICAgICAgICAgIHR5cGVzdHJpbmcgPSAiRE9DVU1FTlRfTk9ERSI7Ci0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgRFRNLkRPQ1VNRU5UX1RZUEVfTk9ERSA6Ci0gICAgICAgICAgdHlwZXN0cmluZyA9ICJET0NVTUVOVF9OT0RFIjsKLSAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBEVE0uRUxFTUVOVF9OT0RFIDoKLSAgICAgICAgICB0eXBlc3RyaW5nID0gIkVMRU1FTlRfTk9ERSI7Ci0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgRFRNLkVOVElUWV9OT0RFIDoKLSAgICAgICAgICB0eXBlc3RyaW5nID0gIkVOVElUWV9OT0RFIjsKLSAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBEVE0uRU5USVRZX1JFRkVSRU5DRV9OT0RFIDoKLSAgICAgICAgICB0eXBlc3RyaW5nID0gIkVOVElUWV9SRUZFUkVOQ0VfTk9ERSI7Ci0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgRFRNLk5BTUVTUEFDRV9OT0RFIDoKLSAgICAgICAgICB0eXBlc3RyaW5nID0gIk5BTUVTUEFDRV9OT0RFIjsKLSAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBEVE0uTk9UQVRJT05fTk9ERSA6Ci0gICAgICAgICAgdHlwZXN0cmluZyA9ICJOT1RBVElPTl9OT0RFIjsKLSAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBEVE0uTlVMTCA6Ci0gICAgICAgICAgdHlwZXN0cmluZyA9ICJOVUxMIjsKLSAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBEVE0uUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFIDoKLSAgICAgICAgICB0eXBlc3RyaW5nID0gIlBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERSI7Ci0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgRFRNLlRFWFRfTk9ERSA6Ci0gICAgICAgICAgdHlwZXN0cmluZyA9ICJURVhUX05PREUiOwotICAgICAgICAgIGJyZWFrOwotICAgICAgICBkZWZhdWx0IDoKLSAgICAgICAgICB0eXBlc3RyaW5nID0gIlVua25vd24hIjsKLSAgICAgICAgICBicmVhazsKLSAgICAgICAgfQotCi0gICAgICAgIHBzLnByaW50bG4oIlR5cGU6ICIgKyB0eXBlc3RyaW5nKTsKLQotICAgICAgICBpbnQgZmlyc3RDaGlsZCA9IF9maXJzdGNoKGluZGV4KTsKLQotICAgICAgICBpZiAoRFRNLk5VTEwgPT0gZmlyc3RDaGlsZCkKLSAgICAgICAgICBwcy5wcmludGxuKCJGaXJzdCBjaGlsZDogRFRNLk5VTEwiKTsKLSAgICAgICAgZWxzZSBpZiAoTk9UUFJPQ0VTU0VEID09IGZpcnN0Q2hpbGQpCi0gICAgICAgICAgcHMucHJpbnRsbigiRmlyc3QgY2hpbGQ6IE5PVFBST0NFU1NFRCIpOwotICAgICAgICBlbHNlCi0gICAgICAgICAgcHMucHJpbnRsbigiRmlyc3QgY2hpbGQ6ICIgKyBmaXJzdENoaWxkKTsKLQotICAgICAgICBpZiAobV9wcmV2c2liICE9IG51bGwpCi0gICAgICAgIHsKLSAgICAgICAgICBpbnQgcHJldlNpYmxpbmcgPSBfcHJldnNpYihpbmRleCk7Ci0KLSAgICAgICAgICBpZiAoRFRNLk5VTEwgPT0gcHJldlNpYmxpbmcpCi0gICAgICAgICAgICBwcy5wcmludGxuKCJQcmV2IHNpYmxpbmc6IERUTS5OVUxMIik7Ci0gICAgICAgICAgZWxzZSBpZiAoTk9UUFJPQ0VTU0VEID09IHByZXZTaWJsaW5nKQotICAgICAgICAgICAgcHMucHJpbnRsbigiUHJldiBzaWJsaW5nOiBOT1RQUk9DRVNTRUQiKTsKLSAgICAgICAgICBlbHNlCi0gICAgICAgICAgICBwcy5wcmludGxuKCJQcmV2IHNpYmxpbmc6ICIgKyBwcmV2U2libGluZyk7Ci0gICAgICAgIH0KLQotICAgICAgICBpbnQgbmV4dFNpYmxpbmcgPSBfbmV4dHNpYihpbmRleCk7Ci0KLSAgICAgICAgaWYgKERUTS5OVUxMID09IG5leHRTaWJsaW5nKQotICAgICAgICAgIHBzLnByaW50bG4oIk5leHQgc2libGluZzogRFRNLk5VTEwiKTsKLSAgICAgICAgZWxzZSBpZiAoTk9UUFJPQ0VTU0VEID09IG5leHRTaWJsaW5nKQotICAgICAgICAgIHBzLnByaW50bG4oIk5leHQgc2libGluZzogTk9UUFJPQ0VTU0VEIik7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICBwcy5wcmludGxuKCJOZXh0IHNpYmxpbmc6ICIgKyBuZXh0U2libGluZyk7Ci0KLSAgICAgICAgaW50IHBhcmVudCA9IF9wYXJlbnQoaW5kZXgpOwotCi0gICAgICAgIGlmIChEVE0uTlVMTCA9PSBwYXJlbnQpCi0gICAgICAgICAgcHMucHJpbnRsbigiUGFyZW50OiBEVE0uTlVMTCIpOwotICAgICAgICBlbHNlIGlmIChOT1RQUk9DRVNTRUQgPT0gcGFyZW50KQotICAgICAgICAgIHBzLnByaW50bG4oIlBhcmVudDogTk9UUFJPQ0VTU0VEIik7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICBwcy5wcmludGxuKCJQYXJlbnQ6ICIgKyBwYXJlbnQpOwotCi0gICAgICAgIGludCBsZXZlbCA9IF9sZXZlbChpbmRleCk7Ci0KLSAgICAgICAgcHMucHJpbnRsbigiTGV2ZWw6ICIgKyBsZXZlbCk7Ci0gICAgICAgIHBzLnByaW50bG4oIk5vZGUgVmFsdWU6ICIgKyBnZXROb2RlVmFsdWUoaSkpOwotICAgICAgICBwcy5wcmludGxuKCJTdHJpbmcgVmFsdWU6ICIgKyBnZXRTdHJpbmdWYWx1ZShpKSk7Ci0gICAgICB9Ci0gICAgfQotICAgIGNhdGNoKElPRXhjZXB0aW9uIGlvZSkKLSAgICB7Ci0gICAgICBpb2UucHJpbnRTdGFja1RyYWNlKFN5c3RlbS5lcnIpOwotICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihpb2UuZ2V0TWVzc2FnZSgpKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogRGlhZ25vc3RpY3MgZnVuY3Rpb24gdG8gZHVtcCBhIHNpbmdsZSBub2RlLgotICAgKgotICAgKiAlUkVWSUVXJSBLTk9XTiBHTElUQ0g6IElmIHlvdSBwYXNzIGl0IGEgbm9kZSBpbmRleCByYXRoZXIgdGhhbiBhCi0gICAqIG5vZGUgaGFuZGxlLCBpdCB3b3JrcyBqdXN0IGZpbmUuLi4gYnV0IHRoZSBkaXNwbGF5ZWQgaWRlbnRpdHkKLSAgICogbnVtYmVyIGJlZm9yZSB0aGUgY29sb24gaXMgZGlmZmVyZW50LCB3aGljaCBjb21wbGljYXRlcyBjb21wYXJpbmcKLSAgICogaXQgd2l0aCBub2RlcyBwcmludGVkIHRoZSBvdGhlciB3YXkuIFdlIGNvdWxkIGFsd2F5cyBPUiB0aGUgRFRNIElECi0gICAqIGludG8gdGhlIHZhbHVlLCB0byBzdXBwcmVzcyB0aGF0IGRpc3RpbmN0aW9uLi4uCi0gICAqCi0gICAqICVSRVZJRVclIFRoaXMgbWlnaHQgd2FudCB0byBiZSBtb3ZlZCB1cCB0byBEVE1EZWZhdWx0QmFzZSwgb3IgcG9zc2libHkKLSAgICogRFRNIGl0c2VsZiwgc2luY2UgaXQncyBhIHVzZWZ1bCBkaWFnbm9zdGljIGFuZCB1c2VzIG9ubHkgRFRNJ3MgcHVibGljCi0gICAqIEFQSXMuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGR1bXBOb2RlKGludCBub2RlSGFuZGxlKQotICB7Ci0gICAgICAgICAgaWYobm9kZUhhbmRsZT09RFRNLk5VTEwpCi0gICAgICAgICAgICAgICAgICByZXR1cm4gIltudWxsXSI7Ci0KLSAgICAgICAgU3RyaW5nIHR5cGVzdHJpbmc7Ci0gICAgICAgIHN3aXRjaCAoZ2V0Tm9kZVR5cGUobm9kZUhhbmRsZSkpCi0gICAgICAgIHsKLSAgICAgICAgY2FzZSBEVE0uQVRUUklCVVRFX05PREUgOgotICAgICAgICAgIHR5cGVzdHJpbmcgPSAiQVRUUiI7Ci0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgRFRNLkNEQVRBX1NFQ1RJT05fTk9ERSA6Ci0gICAgICAgICAgdHlwZXN0cmluZyA9ICJDREFUQSI7Ci0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgRFRNLkNPTU1FTlRfTk9ERSA6Ci0gICAgICAgICAgdHlwZXN0cmluZyA9ICJDT01NRU5UIjsKLSAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBEVE0uRE9DVU1FTlRfRlJBR01FTlRfTk9ERSA6Ci0gICAgICAgICAgdHlwZXN0cmluZyA9ICJET0NfRlJBRyI7Ci0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgRFRNLkRPQ1VNRU5UX05PREUgOgotICAgICAgICAgIHR5cGVzdHJpbmcgPSAiRE9DIjsKLSAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBEVE0uRE9DVU1FTlRfVFlQRV9OT0RFIDoKLSAgICAgICAgICB0eXBlc3RyaW5nID0gIkRPQ19UWVBFIjsKLSAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBEVE0uRUxFTUVOVF9OT0RFIDoKLSAgICAgICAgICB0eXBlc3RyaW5nID0gIkVMRU1FTlQiOwotICAgICAgICAgIGJyZWFrOwotICAgICAgICBjYXNlIERUTS5FTlRJVFlfTk9ERSA6Ci0gICAgICAgICAgdHlwZXN0cmluZyA9ICJFTlRJVFkiOwotICAgICAgICAgIGJyZWFrOwotICAgICAgICBjYXNlIERUTS5FTlRJVFlfUkVGRVJFTkNFX05PREUgOgotICAgICAgICAgIHR5cGVzdHJpbmcgPSAiRU5UX1JFRiI7Ci0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgRFRNLk5BTUVTUEFDRV9OT0RFIDoKLSAgICAgICAgICB0eXBlc3RyaW5nID0gIk5BTUVTUEFDRSI7Ci0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgRFRNLk5PVEFUSU9OX05PREUgOgotICAgICAgICAgIHR5cGVzdHJpbmcgPSAiTk9UQVRJT04iOwotICAgICAgICAgIGJyZWFrOwotICAgICAgICBjYXNlIERUTS5OVUxMIDoKLSAgICAgICAgICB0eXBlc3RyaW5nID0gIm51bGwiOwotICAgICAgICAgIGJyZWFrOwotICAgICAgICBjYXNlIERUTS5QUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREUgOgotICAgICAgICAgIHR5cGVzdHJpbmcgPSAiUEkiOwotICAgICAgICAgIGJyZWFrOwotICAgICAgICBjYXNlIERUTS5URVhUX05PREUgOgotICAgICAgICAgIHR5cGVzdHJpbmcgPSAiVEVYVCI7Ci0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGRlZmF1bHQgOgotICAgICAgICAgIHR5cGVzdHJpbmcgPSAiVW5rbm93biEiOwotICAgICAgICAgIGJyZWFrOwotICAgICAgICB9Ci0KLSAgICAgIHJldHVybiAiWyIgKyBub2RlSGFuZGxlICsgIjogIiArIHR5cGVzdHJpbmcgKwotICAgICAgICAgICAgICAiKDB4IiArIEludGVnZXIudG9IZXhTdHJpbmcoZ2V0RXhwYW5kZWRUeXBlSUQobm9kZUhhbmRsZSkpICsgIikgIiArCi0gICAgICAgICAgICAgIGdldE5vZGVOYW1lWChub2RlSGFuZGxlKSArICIgeyIgKyBnZXROYW1lc3BhY2VVUkkobm9kZUhhbmRsZSkgKyAifSIgKwotICAgICAgICAgICAgICAiPVwiIiArIGdldE5vZGVWYWx1ZShub2RlSGFuZGxlKSArICJcIl0iOwotICB9Ci0KLSAgLy8gPT09PT09PT09IERUTSBJbXBsZW1lbnRhdGlvbiBDb250cm9sIEZ1bmN0aW9ucy4gPT09PT09PT09PT09PT0KLQotICAvKioKLSAgICogU2V0IGFuIGltcGxlbWVudGF0aW9uIGRlcGVuZGVudCBmZWF0dXJlLgotICAgKiA8cD4KLSAgICogJVJFVklFVyUgRG8gd2UgcmVhbGx5IGV4cGVjdCB0byBzZXQgZmVhdHVyZXMgb24gRFRNcz8KLSAgICoKLSAgICogQHBhcmFtIGZlYXR1cmVJZCBBIGZlYXR1cmUgVVJMLgotICAgKiBAcGFyYW0gc3RhdGUgdHJ1ZSBpZiB0aGlzIGZlYXR1cmUgc2hvdWxkIGJlIG9uLCBmYWxzZSBvdGhlcndpc2UuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRGZWF0dXJlKFN0cmluZyBmZWF0dXJlSWQsIGJvb2xlYW4gc3RhdGUpe30KLQotICAvLyA9PT09PT09PT0gRG9jdW1lbnQgTmF2aWdhdGlvbiBGdW5jdGlvbnMgPT09PT09PT09Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIHRlc3QgaWYgaXQgaGFzIGNoaWxkIG5vZGVzLgotICAgKiA8cD4gJVJFVklFVyUgVGhpcyBpcyBvYnZpb3VzbHkgdXNlZnVsIGF0IHRoZSBET00gbGF5ZXIsIHdoZXJlIGl0Ci0gICAqIHdvdWxkIHBlcm1pdCB0ZXN0aW5nIHRoaXMgd2l0aG91dCBoYXZpbmcgdG8gY3JlYXRlIGEgcHJveHkKLSAgICogbm9kZS4gSXQncyBsZXNzIHVzZWZ1bCBpbiB0aGUgRFRNIEFQSSwgd2hlcmUKLSAgICogKGR0bS5nZXRGaXJzdENoaWxkKG5vZGVIYW5kbGUpIT1EVE0uTlVMTCkgaXMganVzdCBhcyBmYXN0IGFuZAotICAgKiBhbG1vc3QgYXMgc2VsZi1ldmlkZW50LiBCdXQgaXQncyBhIGNvbnZlbmllbmNlLCBhbmQgZWFzZXMgcG9ydGluZwotICAgKiBvZiBET00gY29kZSB0byBEVE0uICA8L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIGludCBIYW5kbGUgb2YgdGhlIG5vZGUuCi0gICAqIEByZXR1cm4gaW50IHRydWUgaWYgdGhlIGdpdmVuIG5vZGUgaGFzIGNoaWxkIG5vZGVzLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaGFzQ2hpbGROb2RlcyhpbnQgbm9kZUhhbmRsZSkKLSAgewotCi0gICAgaW50IGlkZW50aXR5ID0gbWFrZU5vZGVJZGVudGl0eShub2RlSGFuZGxlKTsKLSAgICBpbnQgZmlyc3RDaGlsZCA9IF9maXJzdGNoKGlkZW50aXR5KTsKLQotICAgIHJldHVybiBmaXJzdENoaWxkICE9IERUTS5OVUxMOwotICB9Ci0KLSAgLyoqIEdpdmVuIGEgbm9kZSBpZGVudGl0eSwgcmV0dXJuIGEgbm9kZSBoYW5kbGUuIElmIGV4dGVuZGVkIGFkZHJlc3NpbmcKLSAgICogaGFzIGJlZW4gdXNlZCAobXVsdGlwbGUgRFRNIElEcyksIHdlIG5lZWQgdG8gbWFwIHRoZSBoaWdoIGJpdHMgb2YgdGhlCi0gICAqIGlkZW50aXR5IGludG8gdGhlIHByb3BlciBEVE0gSUQuCi0gICAqCi0gICAqIFRoaXMgaGFzIGJlZW4gbWFkZSBGSU5BTCB0byBmYWNpbGl0YXRlIGlubGluaW5nLCBzaW5jZSB3ZSBkbyBub3QgZXhwZWN0Ci0gICAqIGFueSBzdWJjbGFzcyBvZiBEVE1EZWZhdWx0QmFzZSB0byBldmVyIGNoYW5nZSB0aGUgYWxnb3JpdGhtLiAoSSBkb24ndAotICAgKiByZWFsbHkgbGlrZSBkb2luZyBzbywgYW5kIHdvdWxkIGxvdmUgdG8gaGF2ZSBhbiBleGN1c2Ugbm90IHRvLi4uKQotICAgKgotICAgKiAlUkVWSUVXJSBJcyBpdCB3b3J0aCB0cnlpbmcgdG8gc3BlY2lhbGNhc2Ugc21hbGwgZG9jdW1lbnRzPwotICAgKiAlUkVWSUVXJSBTaG91bGQgdGhpcyBiZSBleHBvc2VkIGF0IHRoZSBwYWNrYWdlL3B1YmxpYyBsYXllcnM/Ci0gICAqCi0gICAqIEBwYXJhbSBub2RlSWRlbnRpdHkgSW50ZXJuYWwgb2Zmc2V0IHRvIHRoaXMgbm9kZSdzIHJlY29yZHMuCi0gICAqIEByZXR1cm4gTm9kZUhhbmRsZSAoZXh0ZXJuYWwgcmVwcmVzZW50YXRpb24gb2Ygbm9kZSkKLSAgICogKi8KLSAgZmluYWwgcHVibGljIGludCBtYWtlTm9kZUhhbmRsZShpbnQgbm9kZUlkZW50aXR5KQotICB7Ci0gICAgaWYoTlVMTD09bm9kZUlkZW50aXR5KSByZXR1cm4gTlVMTDsKLQotICAgIGlmKEpKS19ERUJVRyAmJiBub2RlSWRlbnRpdHk+RFRNTWFuYWdlci5JREVOVF9OT0RFX0RFRkFVTFQpCi0gICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIkdPTkshIChvbmx5IHVzZWZ1bCBpbiBsaW1pdGVkIHNpdHVhdGlvbnMpIik7Ci0KLSAgICByZXR1cm4gbV9kdG1JZGVudC5lbGVtZW50QXQobm9kZUlkZW50aXR5ID4+PiBEVE1NYW5hZ2VyLklERU5UX0RUTV9OT0RFX0JJVFMpCi0gICAgICArIChub2RlSWRlbnRpdHkgJiBEVE1NYW5hZ2VyLklERU5UX05PREVfREVGQVVMVCkgOwotICB9Ci0KLSAgLyoqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIHJldHVybiBhIG5vZGUgaWRlbnRpdHkuIElmIGV4dGVuZGVkIGFkZHJlc3NpbmcKLSAgICogaGFzIGJlZW4gdXNlZCAobXVsdGlwbGUgRFRNIElEcyksIHdlIG5lZWQgdG8gbWFwIHRoZSBoaWdoIGJpdHMgb2YgdGhlCi0gICAqIGlkZW50aXR5IGludG8gdGhlIHByb3BlciBEVE0gSUQgYW5kIHRoZW5jZSBmaW5kIHRoZSBwcm9wZXIgb2Zmc2V0Ci0gICAqIHRvIGFkZCB0byB0aGUgbG93IGJpdHMgb2YgdGhlIGlkZW50aXR5Ci0gICAqCi0gICAqIFRoaXMgaGFzIGJlZW4gbWFkZSBGSU5BTCB0byBmYWNpbGl0YXRlIGlubGluaW5nLCBzaW5jZSB3ZSBkbyBub3QgZXhwZWN0Ci0gICAqIGFueSBzdWJjbGFzcyBvZiBEVE1EZWZhdWx0QmFzZSB0byBldmVyIGNoYW5nZSB0aGUgYWxnb3JpdGhtLiAoSSBkb24ndAotICAgKiByZWFsbHkgbGlrZSBkb2luZyBzbywgYW5kIHdvdWxkIGxvdmUgdG8gaGF2ZSBhbiBleGN1c2Ugbm90IHRvLi4uKQotICAgKgotICAgKiAlT1BUJSBQZXJmb3JtYW5jZSBpcyBjcml0aWNhbCBmb3IgdGhpcyBvcGVyYXRpb24uCi0gICAqCi0gICAqICVSRVZJRVclIFNob3VsZCB0aGlzIGJlIGV4cG9zZWQgYXQgdGhlIHBhY2thZ2UvcHVibGljIGxheWVycz8KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgKGV4dGVybmFsIHJlcHJlc2VudGF0aW9uIG9mIG5vZGUpCi0gICAqIEByZXR1cm4gbm9kZUlkZW50aXR5IEludGVybmFsIG9mZnNldCB0byB0aGlzIG5vZGUncyByZWNvcmRzLgotICAgKiAqLwotICBmaW5hbCBwdWJsaWMgaW50IG1ha2VOb2RlSWRlbnRpdHkoaW50IG5vZGVIYW5kbGUpCi0gIHsKLSAgICBpZihOVUxMPT1ub2RlSGFuZGxlKSByZXR1cm4gTlVMTDsKLQotICAgIGlmKG1fbWdyRGVmYXVsdCE9bnVsbCkKLSAgICB7Ci0gICAgICAvLyBPcHRpbWl6YXRpb246IHVzZSB0aGUgRFRNTWFuYWdlckRlZmF1bHQncyBmYXN0IERUTUlELXRvLW9mZnNldHMKLSAgICAgIC8vIHRhYmxlLiAgSSdtIG5vdCB3aWxkIGFib3V0IHRoaXMgc29sdXRpb24gYnV0IHRoaXMgb3BlcmF0aW9uCi0gICAgICAvLyBuZWVkcyBuZWVkIGV4dHJlbWUgc3BlZWQuCi0KLSAgICAgIGludCB3aGljaERUTWluZGV4PW5vZGVIYW5kbGU+Pj5EVE1NYW5hZ2VyLklERU5UX0RUTV9OT0RFX0JJVFM7Ci0KLSAgICAgIC8vICVSRVZJRVclIFdpc2ggSSBkaWRuJ3QgaGF2ZSB0byBwZXJmb3JtIHRoZSBwcmUtdGVzdCwgYnV0Ci0gICAgICAvLyBzb21lb25lIGlzIGFwcGFyZW50bHkgYXNraW5nIERUTXMgd2hldGhlciB0aGV5IGNvbnRhaW4gbm9kZXMKLSAgICAgIC8vIHdoaWNoIHJlYWxseSBkb24ndCBiZWxvbmcgdG8gdGhlbS4gVGhhdCdzIHByb2JhYmx5IGEgYnVnCi0gICAgICAvLyB3aGljaCBzaG91bGQgYmUgZml4ZWQsIGJ1dCB1bnRpbCBpdCBpczoKLSAgICAgIGlmKG1fbWdyRGVmYXVsdC5tX2R0bXNbd2hpY2hEVE1pbmRleF0hPXRoaXMpCi0gICAgICAgIHJldHVybiBOVUxMOwotICAgICAgZWxzZQotICAgICAgICByZXR1cm4KLSAgICAgICAgICBtX21nckRlZmF1bHQubV9kdG1fb2Zmc2V0c1t3aGljaERUTWluZGV4XQotICAgICAgICAgIHwgKG5vZGVIYW5kbGUgJiBEVE1NYW5hZ2VyLklERU5UX05PREVfREVGQVVMVCk7Ci0gICAgfQotCi0gICAgaW50IHdoaWNoRFRNaWQ9bV9kdG1JZGVudC5pbmRleE9mKG5vZGVIYW5kbGUgJiBEVE1NYW5hZ2VyLklERU5UX0RUTV9ERUZBVUxUKTsKLSAgICByZXR1cm4gKHdoaWNoRFRNaWQ9PU5VTEwpCi0gICAgICA/IE5VTEwKLSAgICAgIDogKHdoaWNoRFRNaWQgPDwgRFRNTWFuYWdlci5JREVOVF9EVE1fTk9ERV9CSVRTKQotICAgICAgKyAobm9kZUhhbmRsZSAmIERUTU1hbmFnZXIuSURFTlRfTk9ERV9ERUZBVUxUKTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIGdldCB0aGUgaGFuZGxlIG9mIHRoZSBub2RlJ3MgZmlyc3QgY2hpbGQuCi0gICAqIElmIG5vdCB5ZXQgcmVzb2x2ZWQsIHdhaXRzIGZvciBtb3JlIG5vZGVzIHRvIGJlIGFkZGVkIHRvIHRoZSBkb2N1bWVudCBhbmQKLSAgICogdHJpZXMgYWdhaW4uCi0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIGludCBIYW5kbGUgb2YgdGhlIG5vZGUuCi0gICAqIEByZXR1cm4gaW50IERUTSBub2RlLW51bWJlciBvZiBmaXJzdCBjaGlsZCwgb3IgRFRNLk5VTEwgdG8gaW5kaWNhdGUgbm9uZSBleGlzdHMuCi0gICAqLwotICBwdWJsaWMgaW50IGdldEZpcnN0Q2hpbGQoaW50IG5vZGVIYW5kbGUpCi0gIHsKLQotICAgIGludCBpZGVudGl0eSA9IG1ha2VOb2RlSWRlbnRpdHkobm9kZUhhbmRsZSk7Ci0gICAgaW50IGZpcnN0Q2hpbGQgPSBfZmlyc3RjaChpZGVudGl0eSk7Ci0KLSAgICByZXR1cm4gbWFrZU5vZGVIYW5kbGUoZmlyc3RDaGlsZCk7Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYSBub2RlIGhhbmRsZSwgZ2V0IHRoZSBoYW5kbGUgb2YgdGhlIG5vZGUncyBmaXJzdCBjaGlsZC4KLSAgICogSWYgbm90IHlldCByZXNvbHZlZCwgd2FpdHMgZm9yIG1vcmUgbm9kZXMgdG8gYmUgYWRkZWQgdG8gdGhlIGRvY3VtZW50IGFuZAotICAgKiB0cmllcyBhZ2Fpbi4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgaW50IEhhbmRsZSBvZiB0aGUgbm9kZS4KLSAgICogQHJldHVybiBpbnQgRFRNIG5vZGUtbnVtYmVyIG9mIGZpcnN0IGNoaWxkLCBvciBEVE0uTlVMTCB0byBpbmRpY2F0ZSBub25lIGV4aXN0cy4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0VHlwZWRGaXJzdENoaWxkKGludCBub2RlSGFuZGxlLCBpbnQgbm9kZVR5cGUpCi0gIHsKLQotICAgIGludCBmaXJzdENoaWxkLCBlVHlwZTsKLSAgICBpZiAobm9kZVR5cGUgPCBEVE0uTlRZUEVTKSB7Ci0gICAgICBmb3IgKGZpcnN0Q2hpbGQgPSBfZmlyc3RjaChtYWtlTm9kZUlkZW50aXR5KG5vZGVIYW5kbGUpKTsKLSAgICAgICAgICAgZmlyc3RDaGlsZCAhPSBEVE0uTlVMTDsKLSAgICAgICAgICAgZmlyc3RDaGlsZCA9IF9uZXh0c2liKGZpcnN0Q2hpbGQpKSB7Ci0gICAgICAgIGVUeXBlID0gX2V4cHR5cGUoZmlyc3RDaGlsZCk7Ci0gICAgICAgIGlmIChlVHlwZSA9PSBub2RlVHlwZQotICAgICAgICAgICAgICAgfHwgKGVUeXBlID49IERUTS5OVFlQRVMKLSAgICAgICAgICAgICAgICAgICAgICAmJiBtX2V4cGFuZGVkTmFtZVRhYmxlLmdldFR5cGUoZVR5cGUpID09IG5vZGVUeXBlKSkgewotICAgICAgICAgIHJldHVybiBtYWtlTm9kZUhhbmRsZShmaXJzdENoaWxkKTsKLSAgICAgICAgfQotICAgICAgfQotICAgIH0gZWxzZSB7Ci0gICAgICBmb3IgKGZpcnN0Q2hpbGQgPSBfZmlyc3RjaChtYWtlTm9kZUlkZW50aXR5KG5vZGVIYW5kbGUpKTsKLSAgICAgICAgICAgZmlyc3RDaGlsZCAhPSBEVE0uTlVMTDsKLSAgICAgICAgICAgZmlyc3RDaGlsZCA9IF9uZXh0c2liKGZpcnN0Q2hpbGQpKSB7Ci0gICAgICAgIGlmIChfZXhwdHlwZShmaXJzdENoaWxkKSA9PSBub2RlVHlwZSkgewotICAgICAgICAgIHJldHVybiBtYWtlTm9kZUhhbmRsZShmaXJzdENoaWxkKTsKLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLSAgICByZXR1cm4gRFRNLk5VTEw7Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYSBub2RlIGhhbmRsZSwgYWR2YW5jZSB0byBpdHMgbGFzdCBjaGlsZC4KLSAgICogSWYgbm90IHlldCByZXNvbHZlZCwgd2FpdHMgZm9yIG1vcmUgbm9kZXMgdG8gYmUgYWRkZWQgdG8gdGhlIGRvY3VtZW50IGFuZAotICAgKiB0cmllcyBhZ2Fpbi4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgaW50IEhhbmRsZSBvZiB0aGUgbm9kZS4KLSAgICogQHJldHVybiBpbnQgTm9kZS1udW1iZXIgb2YgbGFzdCBjaGlsZCwKLSAgICogb3IgRFRNLk5VTEwgdG8gaW5kaWNhdGUgbm9uZSBleGlzdHMuCi0gICAqLwotICBwdWJsaWMgaW50IGdldExhc3RDaGlsZChpbnQgbm9kZUhhbmRsZSkKLSAgewotCi0gICAgaW50IGlkZW50aXR5ID0gbWFrZU5vZGVJZGVudGl0eShub2RlSGFuZGxlKTsKLSAgICBpbnQgY2hpbGQgPSBfZmlyc3RjaChpZGVudGl0eSk7Ci0gICAgaW50IGxhc3RDaGlsZCA9IERUTS5OVUxMOwotCi0gICAgd2hpbGUgKGNoaWxkICE9IERUTS5OVUxMKQotICAgIHsKLSAgICAgIGxhc3RDaGlsZCA9IGNoaWxkOwotICAgICAgY2hpbGQgPSBfbmV4dHNpYihjaGlsZCk7Ci0gICAgfQotCi0gICAgcmV0dXJuIG1ha2VOb2RlSGFuZGxlKGxhc3RDaGlsZCk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0cmlldmVzIGFuIGF0dHJpYnV0ZSBub2RlIGJ5IGJ5IHF1YWxpZmllZCBuYW1lIGFuZCBuYW1lc3BhY2UgVVJJLgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBpbnQgSGFuZGxlIG9mIHRoZSBub2RlIHVwb24gd2hpY2ggdG8gbG9vayB1cCB0aGlzIGF0dHJpYnV0ZS4uCi0gICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkgVGhlIG5hbWVzcGFjZSBVUkkgb2YgdGhlIGF0dHJpYnV0ZSB0bwotICAgKiAgIHJldHJpZXZlLCBvciBudWxsLgotICAgKiBAcGFyYW0gbmFtZSBUaGUgbG9jYWwgbmFtZSBvZiB0aGUgYXR0cmlidXRlIHRvCi0gICAqICAgcmV0cmlldmUuCi0gICAqIEByZXR1cm4gVGhlIGF0dHJpYnV0ZSBub2RlIGhhbmRsZSB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZSAoCi0gICAqICAgPGNvZGU+bm9kZU5hbWU8L2NvZGU+KSBvciA8Y29kZT5EVE0uTlVMTDwvY29kZT4gaWYgdGhlcmUgaXMgbm8gc3VjaAotICAgKiAgIGF0dHJpYnV0ZS4KLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBpbnQgZ2V0QXR0cmlidXRlTm9kZShpbnQgbm9kZUhhbmRsZSwgU3RyaW5nIG5hbWVzcGFjZVVSSSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBuYW1lKTsKLQotICAvKioKLSAgICogR2l2ZW4gYSBub2RlIGhhbmRsZSwgZ2V0IHRoZSBpbmRleCBvZiB0aGUgbm9kZSdzIGZpcnN0IGF0dHJpYnV0ZS4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgaW50IEhhbmRsZSBvZiB0aGUgbm9kZS4KLSAgICogQHJldHVybiBIYW5kbGUgb2YgZmlyc3QgYXR0cmlidXRlLCBvciBEVE0uTlVMTCB0byBpbmRpY2F0ZSBub25lIGV4aXN0cy4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0Rmlyc3RBdHRyaWJ1dGUoaW50IG5vZGVIYW5kbGUpCi0gIHsKLSAgICBpbnQgbm9kZUlEID0gbWFrZU5vZGVJZGVudGl0eShub2RlSGFuZGxlKTsKLQotICAgIHJldHVybiBtYWtlTm9kZUhhbmRsZShnZXRGaXJzdEF0dHJpYnV0ZUlkZW50aXR5KG5vZGVJRCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgbm9kZSBpZGVudGl0eSwgZ2V0IHRoZSBpbmRleCBvZiB0aGUgbm9kZSdzIGZpcnN0IGF0dHJpYnV0ZS4KLSAgICoKLSAgICogQHBhcmFtIGlkZW50aXR5IGludCBpZGVudGl0eSBvZiB0aGUgbm9kZS4KLSAgICogQHJldHVybiBJZGVudGl0eSBvZiBmaXJzdCBhdHRyaWJ1dGUsIG9yIERUTS5OVUxMIHRvIGluZGljYXRlIG5vbmUgZXhpc3RzLgotICAgKi8KLSAgcHJvdGVjdGVkIGludCBnZXRGaXJzdEF0dHJpYnV0ZUlkZW50aXR5KGludCBpZGVudGl0eSkgewotICAgIGludCB0eXBlID0gX3R5cGUoaWRlbnRpdHkpOwotCi0gICAgaWYgKERUTS5FTEVNRU5UX05PREUgPT0gdHlwZSkKLSAgICB7Ci0gICAgICAvLyBBc3N1bWUgdGhhdCBhdHRyaWJ1dGVzIGFuZCBuYW1lc3BhY2VzIGltbWVkaWF0ZWx5IGZvbGxvdyB0aGUgZWxlbWVudC4KLSAgICAgIHdoaWxlIChEVE0uTlVMTCAhPSAoaWRlbnRpdHkgPSBnZXROZXh0Tm9kZUlkZW50aXR5KGlkZW50aXR5KSkpCi0gICAgICB7Ci0KLSAgICAgICAgLy8gQXNzdW1lIHRoaXMgY2FuIG5vdCBiZSBudWxsLgotICAgICAgICB0eXBlID0gX3R5cGUoaWRlbnRpdHkpOwotCi0gICAgICAgIGlmICh0eXBlID09IERUTS5BVFRSSUJVVEVfTk9ERSkKLSAgICAgICAgewotICAgICAgICAgIHJldHVybiBpZGVudGl0eTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChEVE0uTkFNRVNQQUNFX05PREUgIT0gdHlwZSkKLSAgICAgICAgewotICAgICAgICAgIGJyZWFrOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotCi0gICAgcmV0dXJuIERUTS5OVUxMOwotICB9Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUgYW5kIGFuIGV4cGFuZGVkIHR5cGUgSUQsIGdldCB0aGUgaW5kZXggb2YgdGhlIG5vZGUncwotICAgKiBhdHRyaWJ1dGUgb2YgdGhhdCB0eXBlLCBpZiBhbnkuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIGludCBIYW5kbGUgb2YgdGhlIG5vZGUuCi0gICAqIEBwYXJhbSBhdHRUeXBlIGludCBleHBhbmRlZCB0eXBlIElEIG9mIHRoZSByZXF1aXJlZCBhdHRyaWJ1dGUuCi0gICAqIEByZXR1cm4gSGFuZGxlIG9mIGF0dHJpYnV0ZSBvZiB0aGUgcmVxdWlyZWQgdHlwZSwgb3IgRFRNLk5VTEwgdG8gaW5kaWNhdGUKLSAgICogbm9uZSBleGlzdHMuCi0gICAqLwotICBwcm90ZWN0ZWQgaW50IGdldFR5cGVkQXR0cmlidXRlKGludCBub2RlSGFuZGxlLCBpbnQgYXR0VHlwZSkgewotICAgIGludCB0eXBlID0gZ2V0Tm9kZVR5cGUobm9kZUhhbmRsZSk7Ci0gICAgaWYgKERUTS5FTEVNRU5UX05PREUgPT0gdHlwZSkgewotICAgICAgaW50IGlkZW50aXR5ID0gbWFrZU5vZGVJZGVudGl0eShub2RlSGFuZGxlKTsKLQotICAgICAgd2hpbGUgKERUTS5OVUxMICE9IChpZGVudGl0eSA9IGdldE5leHROb2RlSWRlbnRpdHkoaWRlbnRpdHkpKSkKLSAgICAgIHsKLSAgICAgICAgdHlwZSA9IF90eXBlKGlkZW50aXR5KTsKLQotICAgICAgICBpZiAodHlwZSA9PSBEVE0uQVRUUklCVVRFX05PREUpCi0gICAgICAgIHsKLSAgICAgICAgICBpZiAoX2V4cHR5cGUoaWRlbnRpdHkpID09IGF0dFR5cGUpIHJldHVybiBtYWtlTm9kZUhhbmRsZShpZGVudGl0eSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoRFRNLk5BTUVTUEFDRV9OT0RFICE9IHR5cGUpCi0gICAgICAgIHsKLSAgICAgICAgICBicmVhazsKLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiBEVE0uTlVMTDsKLSAgfQotCi0gIC8qKgotICAgKiBHaXZlbiBhIG5vZGUgaGFuZGxlLCBhZHZhbmNlIHRvIGl0cyBuZXh0IHNpYmxpbmcuCi0gICAqIElmIG5vdCB5ZXQgcmVzb2x2ZWQsIHdhaXRzIGZvciBtb3JlIG5vZGVzIHRvIGJlIGFkZGVkIHRvIHRoZSBkb2N1bWVudCBhbmQKLSAgICogdHJpZXMgYWdhaW4uCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIGludCBIYW5kbGUgb2YgdGhlIG5vZGUuCi0gICAqIEByZXR1cm4gaW50IE5vZGUtbnVtYmVyIG9mIG5leHQgc2libGluZywKLSAgICogb3IgRFRNLk5VTEwgdG8gaW5kaWNhdGUgbm9uZSBleGlzdHMuCi0gICAqLwotICBwdWJsaWMgaW50IGdldE5leHRTaWJsaW5nKGludCBub2RlSGFuZGxlKQotICB7Ci0gICAgICAgIGlmIChub2RlSGFuZGxlID09IERUTS5OVUxMKQotICAgICAgICByZXR1cm4gRFRNLk5VTEw7Ci0gICAgcmV0dXJuIG1ha2VOb2RlSGFuZGxlKF9uZXh0c2liKG1ha2VOb2RlSWRlbnRpdHkobm9kZUhhbmRsZSkpKTsKLSAgfQotCi0gIC8qKgotICAgKiBHaXZlbiBhIG5vZGUgaGFuZGxlLCBhZHZhbmNlIHRvIGl0cyBuZXh0IHNpYmxpbmcuCi0gICAqIElmIG5vdCB5ZXQgcmVzb2x2ZWQsIHdhaXRzIGZvciBtb3JlIG5vZGVzIHRvIGJlIGFkZGVkIHRvIHRoZSBkb2N1bWVudCBhbmQKLSAgICogdHJpZXMgYWdhaW4uCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIGludCBIYW5kbGUgb2YgdGhlIG5vZGUuCi0gICAqIEByZXR1cm4gaW50IE5vZGUtbnVtYmVyIG9mIG5leHQgc2libGluZywKLSAgICogb3IgRFRNLk5VTEwgdG8gaW5kaWNhdGUgbm9uZSBleGlzdHMuCi0gICAqLwotICBwdWJsaWMgaW50IGdldFR5cGVkTmV4dFNpYmxpbmcoaW50IG5vZGVIYW5kbGUsIGludCBub2RlVHlwZSkKLSAgewotICAgICAgICBpZiAobm9kZUhhbmRsZSA9PSBEVE0uTlVMTCkKLSAgICAgICAgcmV0dXJuIERUTS5OVUxMOwotICAgICAgICBpbnQgbm9kZSA9IG1ha2VOb2RlSWRlbnRpdHkobm9kZUhhbmRsZSk7Ci0gICAgICAgIGludCBlVHlwZTsKLSAgICAgICAgd2hpbGUgKChub2RlID0gX25leHRzaWIobm9kZSkpICE9IERUTS5OVUxMICYmCi0gICAgICAgICgoZVR5cGUgPSBfZXhwdHlwZShub2RlKSkgIT0gbm9kZVR5cGUgJiYKLSAgICAgICAgbV9leHBhbmRlZE5hbWVUYWJsZS5nZXRUeXBlKGVUeXBlKSE9IG5vZGVUeXBlKSk7Ci0gICAgICAgIC8vX3R5cGUobm9kZSkgIT0gbm9kZVR5cGUpKTsKLQotICAgIHJldHVybiAobm9kZSA9PSBEVE0uTlVMTCA/IERUTS5OVUxMIDogbWFrZU5vZGVIYW5kbGUobm9kZSkpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIGZpbmQgaXRzIHByZWNlZWRpbmcgc2libGluZy4KLSAgICogV0FSTklORzogRFRNIGlzIGFzeW1tZXRyaWM7IHRoaXMgb3BlcmF0aW9uIGlzIHJlc29sdmVkIGJ5IHNlYXJjaCwgYW5kIGlzCi0gICAqIHJlbGF0aXZlbHkgZXhwZW5zaXZlLgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSB0aGUgaWQgb2YgdGhlIG5vZGUuCi0gICAqIEByZXR1cm4gaW50IE5vZGUtbnVtYmVyIG9mIHRoZSBwcmV2aW91cyBzaWIsCi0gICAqIG9yIERUTS5OVUxMIHRvIGluZGljYXRlIG5vbmUgZXhpc3RzLgotICAgKi8KLSAgcHVibGljIGludCBnZXRQcmV2aW91c1NpYmxpbmcoaW50IG5vZGVIYW5kbGUpCi0gIHsKLSAgICBpZiAobm9kZUhhbmRsZSA9PSBEVE0uTlVMTCkKLSAgICAgIHJldHVybiBEVE0uTlVMTDsKLQotICAgIGlmIChtX3ByZXZzaWIgIT0gbnVsbCkKLSAgICAgIHJldHVybiBtYWtlTm9kZUhhbmRsZShfcHJldnNpYihtYWtlTm9kZUlkZW50aXR5KG5vZGVIYW5kbGUpKSk7Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIC8vIElmIHRoZSBwcmV2aW91cyBzaWJsaW5nIGFycmF5IGlzIG5vdCBidWlsdCwgd2UgZ2V0IGF0Ci0gICAgICAvLyB0aGUgcHJldmlvdXMgc2libGluZyB1c2luZyB0aGUgcGFyZW50LCBmaXJzdGNoIGFuZAotICAgICAgLy8gbmV4dHNpYiBhcnJheXMuCi0gICAgICBpbnQgbm9kZUlEID0gbWFrZU5vZGVJZGVudGl0eShub2RlSGFuZGxlKTsKLSAgICAgIGludCBwYXJlbnQgPSBfcGFyZW50KG5vZGVJRCk7Ci0gICAgICBpbnQgbm9kZSA9IF9maXJzdGNoKHBhcmVudCk7Ci0gICAgICBpbnQgcmVzdWx0ID0gRFRNLk5VTEw7Ci0gICAgICB3aGlsZSAobm9kZSAhPSBub2RlSUQpCi0gICAgICB7Ci0gICAgICAgIHJlc3VsdCA9IG5vZGU7Ci0gICAgICAgIG5vZGUgPSBfbmV4dHNpYihub2RlKTsKLSAgICAgIH0KLSAgICAgIHJldHVybiBtYWtlTm9kZUhhbmRsZShyZXN1bHQpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBHaXZlbiBhIG5vZGUgaGFuZGxlLCBhZHZhbmNlIHRvIHRoZSBuZXh0IGF0dHJpYnV0ZS4KLSAgICogSWYgYW4gYXR0ciwgd2UgYWR2YW5jZSB0bwotICAgKiB0aGUgbmV4dCBhdHRyIG9uIHRoZSBzYW1lIG5vZGUuICBJZiBub3QgYW4gYXR0cmlidXRlLCB3ZSByZXR1cm4gTlVMTC4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgaW50IEhhbmRsZSBvZiB0aGUgbm9kZS4KLSAgICogQHJldHVybiBpbnQgRFRNIG5vZGUtbnVtYmVyIG9mIHRoZSByZXNvbHZlZCBhdHRyLAotICAgKiBvciBEVE0uTlVMTCB0byBpbmRpY2F0ZSBub25lIGV4aXN0cy4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0TmV4dEF0dHJpYnV0ZShpbnQgbm9kZUhhbmRsZSkgewotICAgIGludCBub2RlSUQgPSBtYWtlTm9kZUlkZW50aXR5KG5vZGVIYW5kbGUpOwotCi0gICAgaWYgKF90eXBlKG5vZGVJRCkgPT0gRFRNLkFUVFJJQlVURV9OT0RFKSB7Ci0gICAgICByZXR1cm4gbWFrZU5vZGVIYW5kbGUoZ2V0TmV4dEF0dHJpYnV0ZUlkZW50aXR5KG5vZGVJRCkpOwotICAgIH0KLQotICAgIHJldHVybiBEVE0uTlVMTDsKLSAgfQotCi0gIC8qKgotICAgKiBHaXZlbiBhIG5vZGUgaWRlbnRpdHkgZm9yIGFuIGF0dHJpYnV0ZSwgYWR2YW5jZSB0byB0aGUgbmV4dCBhdHRyaWJ1dGUuCi0gICAqCi0gICAqIEBwYXJhbSBpZGVudGl0eSBpbnQgaWRlbnRpdHkgb2YgdGhlIGF0dHJpYnV0ZSBub2RlLiAgVGhpcwotICAgKiA8c3Ryb25nPm11c3Q8L3N0cm9uZz4gYmUgYW4gYXR0cmlidXRlIG5vZGUuCi0gICAqCi0gICAqIEByZXR1cm4gaW50IERUTSBub2RlLWlkZW50aXR5IG9mIHRoZSByZXNvbHZlZCBhdHRyLAotICAgKiBvciBEVE0uTlVMTCB0byBpbmRpY2F0ZSBub25lIGV4aXN0cy4KLSAgICoKLSAgICovCi0gIHByb3RlY3RlZCBpbnQgZ2V0TmV4dEF0dHJpYnV0ZUlkZW50aXR5KGludCBpZGVudGl0eSkgewotICAgIC8vIEFzc3VtZSB0aGF0IGF0dHJpYnV0ZXMgYW5kIG5hbWVzcGFjZSBub2RlcyBpbW1lZGlhdGVseSBmb2xsb3cgdGhlIGVsZW1lbnQKLSAgICB3aGlsZSAoRFRNLk5VTEwgIT0gKGlkZW50aXR5ID0gZ2V0TmV4dE5vZGVJZGVudGl0eShpZGVudGl0eSkpKSB7Ci0gICAgICBpbnQgdHlwZSA9IF90eXBlKGlkZW50aXR5KTsKLQotICAgICAgaWYgKHR5cGUgPT0gRFRNLkFUVFJJQlVURV9OT0RFKSB7Ci0gICAgICAgIHJldHVybiBpZGVudGl0eTsKLSAgICAgIH0gZWxzZSBpZiAodHlwZSAhPSBEVE0uTkFNRVNQQUNFX05PREUpIHsKLSAgICAgICAgYnJlYWs7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgcmV0dXJuIERUTS5OVUxMOwotICB9Ci0KLSAgLyoqIExhemlseSBjcmVhdGVkIG5hbWVzcGFjZSBsaXN0cy4gKi8KLSAgcHJpdmF0ZSBWZWN0b3IgbV9uYW1lc3BhY2VMaXN0cyA9IG51bGw7ICAvLyBvbiBkZW1hbmQKLQotCi0gIC8qKiBCdWlsZCB0YWJsZSBvZiBuYW1lc3BhY2UgZGVjbGFyYXRpb24KLSAgICogbG9jYXRpb25zIGR1cmluZyBEVE0gY29uc3RydWN0aW9uLiBUYWJsZSBpcyBhIFZlY3RvciBvZgotICAgKiBTdWJhbGxvY2F0ZWRJbnRWZWN0b3JzIGNvbnRhaW5pbmcgdGhlIG5hbWVzcGFjZSBub2RlIEhBTkRMRVMgZGVjbGFyZWQgYXQKLSAgICogdGhhdCBJRCwgcGx1cyBhbiBTdWJhbGxvY2F0ZWRJbnRWZWN0b3Igb2YgdGhlIGVsZW1lbnQgbm9kZSBJTkRFWEVTIGF0IHdoaWNoCi0gICAqIHRoZXNlIGRlY2xhcmF0aW9ucyBhcHBlYXJlZC4KLSAgICoKLSAgICogTk9URTogU2luY2UgdGhpcyBvY2N1cnMgZHVyaW5nIG1vZGVsIGJ1aWxkLCBub2RlcyB3aWxsIGJlIGVuY291bnRlcmVkCi0gICAqIGluIGRvdWNtZW50IG9yZGVyIGFuZCB0aHVzIHRoZSB0YWJsZSB3aWxsIGJlIG9yZGVyZWQgYnkgZWxlbWVudCwKLSAgICogcGVybWl0dGluZyBiaW5hcnktc2VhcmNoIGFzIGEgcG9zc2libGUgcmV0cmlldmFsIG9wdGltaXphdGlvbi4KLSAgICoKLSAgICogJVJFVklFVyUgRGlyZWN0bHkgbWFuYWdlZCBhcnJheXMgcmF0aGVyIHRoYW4gdmVjdG9ycz8KLSAgICogJVJFVklFVyUgSGFuZGxlcyBvciBJRHM/IEdpdmVuIHVzYWdlLCBJIHRoaW5rIGhhbmRsZXMuCi0gICAqICovCi0gIHByb3RlY3RlZCB2b2lkIGRlY2xhcmVOYW1lc3BhY2VJbkNvbnRleHQoaW50IGVsZW1lbnROb2RlSW5kZXgsaW50IG5hbWVzcGFjZU5vZGVJbmRleCkKLSAgewotICAgIFN1YmFsbG9jYXRlZEludFZlY3RvciBuc0xpc3Q9bnVsbDsKLSAgICBpZihtX25hbWVzcGFjZURlY2xTZXRzPT1udWxsKQotICAgICAgewotCi0gICAgICAgIC8vIEZpcnN0Ci0gICAgICAgIG1fbmFtZXNwYWNlRGVjbFNldEVsZW1lbnRzPW5ldyBTdWJhbGxvY2F0ZWRJbnRWZWN0b3IoMzIpOwotICAgICAgICBtX25hbWVzcGFjZURlY2xTZXRFbGVtZW50cy5hZGRFbGVtZW50KGVsZW1lbnROb2RlSW5kZXgpOwotICAgICAgICBtX25hbWVzcGFjZURlY2xTZXRzPW5ldyBWZWN0b3IoKTsKLSAgICAgICAgbnNMaXN0PW5ldyBTdWJhbGxvY2F0ZWRJbnRWZWN0b3IoMzIpOwotICAgICAgICBtX25hbWVzcGFjZURlY2xTZXRzLmFkZEVsZW1lbnQobnNMaXN0KTsKLSAgICAgIH0KLSAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIC8vIE1vc3QgcmVjZW50LiBNYXkgYmUgLTEgKG5vbmUpIGlmIERUTSB3YXMgcHJ1bmVkLgotICAgICAgICAvLyAlT1BUJSBJcyB0aGVyZSBhIGxhc3RFbGVtZW50KCkgbWV0aG9kPyBTaG91bGQgdGhlcmUgYmU/Ci0gICAgICAgIGludCBsYXN0PW1fbmFtZXNwYWNlRGVjbFNldEVsZW1lbnRzLnNpemUoKS0xOwotCi0gICAgICAgIGlmKGxhc3Q+PTAgJiYgZWxlbWVudE5vZGVJbmRleD09bV9uYW1lc3BhY2VEZWNsU2V0RWxlbWVudHMuZWxlbWVudEF0KGxhc3QpKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIG5zTGlzdD0oU3ViYWxsb2NhdGVkSW50VmVjdG9yKW1fbmFtZXNwYWNlRGVjbFNldHMuZWxlbWVudEF0KGxhc3QpOwotICAgICAgICAgIH0KLSAgICAgIH0KLSAgICBpZihuc0xpc3Q9PW51bGwpCi0gICAgICB7Ci0gICAgICAgIG1fbmFtZXNwYWNlRGVjbFNldEVsZW1lbnRzLmFkZEVsZW1lbnQoZWxlbWVudE5vZGVJbmRleCk7Ci0KLSAgICAgICAgU3ViYWxsb2NhdGVkSW50VmVjdG9yIGluaGVyaXRlZCA9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmROYW1lc3BhY2VDb250ZXh0KF9wYXJlbnQoZWxlbWVudE5vZGVJbmRleCkpOwotCi0gICAgICAgIGlmIChpbmhlcml0ZWQhPW51bGwpIHsKLSAgICAgICAgICAgIC8vICVPUFQlIENvdW50LWRvd24gbWlnaHQgYmUgZmFzdGVyLCBidXQgZGVidWdnYWJpbGl0eSBtYXkKLSAgICAgICAgICAgIC8vIGJlIGJldHRlciB0aGlzIHdheSwgYW5kIGlmIHdlIGV2ZXIgZGVjaWRlIHdlIHdhbnQgdG8KLSAgICAgICAgICAgIC8vIGtlZXAgdGhpcyBvcmRlcmVkIGJ5IGV4cGFuZGVkLXR5cGUuLi4KLSAgICAgICAgICAgIGludCBpc2l6ZT1pbmhlcml0ZWQuc2l6ZSgpOwotCi0gICAgICAgICAgICAvLyBCYXNlIHRoZSBzaXplIG9mIGEgbmV3IG5hbWVzcGFjZSBsaXN0IG9uIHRoZQotICAgICAgICAgICAgLy8gc2l6ZSBvZiB0aGUgaW5oZXJpdGVkIGxpc3QgLSBidXQgd2l0aGluIHJlYXNvbiEKLSAgICAgICAgICAgIG5zTGlzdD1uZXcgU3ViYWxsb2NhdGVkSW50VmVjdG9yKE1hdGgubWF4KE1hdGgubWluKGlzaXplKzE2LDIwNDgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMzIpKTsKLQotICAgICAgICAgICAgZm9yKGludCBpPTA7aTxpc2l6ZTsrK2kpCi0gICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBuc0xpc3QuYWRkRWxlbWVudChpbmhlcml0ZWQuZWxlbWVudEF0KGkpKTsKLSAgICAgICAgICAgICAgfQotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgbnNMaXN0PW5ldyBTdWJhbGxvY2F0ZWRJbnRWZWN0b3IoMzIpOwotICAgICAgICB9Ci0KLSAgICAgICAgbV9uYW1lc3BhY2VEZWNsU2V0cy5hZGRFbGVtZW50KG5zTGlzdCk7Ci0gICAgICB9Ci0KLSAgICAvLyBIYW5kbGUgb3ZlcndyaXRpbmcgaW5oZXJpdGVkLgotICAgIC8vICVPUFQlIEtlZXAgc29ydGVkPyAoQnkgZXhwYW5kZWQtbmFtZSByYXRoZXIgdGhhbiBieSBkb2Mgb3JkZXIuLi4pCi0gICAgLy8gRG93bnNpZGU6IFdvdWxkIHJlcXVpcmUgaW5zZXJ0RWxlbWVudEF0IGlmIG5vdCBmb3VuZCwKLSAgICAvLyB3aGljaCBoYXMgcmVjb3B5aW5nIGNvc3RzLiBCdXQgdGhlc2UgYXJlIGdlbmVyYWxseSBzaG9ydCBsaXN0cy4uLgotICAgIGludCBuZXdFVHlwZT1fZXhwdHlwZShuYW1lc3BhY2VOb2RlSW5kZXgpOwotCi0gICAgZm9yKGludCBpPW5zTGlzdC5zaXplKCktMTtpPj0wOy0taSkKLSAgICAgIHsKLSAgICAgICAgaWYobmV3RVR5cGU9PWdldEV4cGFuZGVkVHlwZUlEKG5zTGlzdC5lbGVtZW50QXQoaSkpKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIG5zTGlzdC5zZXRFbGVtZW50QXQobWFrZU5vZGVIYW5kbGUobmFtZXNwYWNlTm9kZUluZGV4KSxpKTsKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICB9Ci0gICAgICB9Ci0gICAgbnNMaXN0LmFkZEVsZW1lbnQobWFrZU5vZGVIYW5kbGUobmFtZXNwYWNlTm9kZUluZGV4KSk7Ci0gIH0KLQotICAvKiogUmV0cmlldmUgbGlzdCBvZiBuYW1lc3BhY2UgZGVjbGFyYXRpb24gbG9jYXRpb25zCi0gICAgICogYWN0aXZlIGF0IHRoaXMgbm9kZS4gTGlzdCBpcyBhbiBTdWJhbGxvY2F0ZWRJbnRWZWN0b3Igd2hvc2UKLSAgICAgKiBlbnRyaWVzIGFyZSB0aGUgbmFtZXNwYWNlIG5vZGUgSEFORExFUyBkZWNsYXJlZCBhdCB0aGF0IElELgotICAgICAqCi0gICAgICogJVJFVklFVyUgRGlyZWN0bHkgbWFuYWdlZCBhcnJheXMgcmF0aGVyIHRoYW4gdmVjdG9ycz8KLSAgICAgKiAlUkVWSUVXJSBIYW5kbGVzIG9yIElEcz8gR2l2ZW4gdXNhZ2UsIEkgdGhpbmsgaGFuZGxlcy4KLSAgICAgKiAqLwotICBwcm90ZWN0ZWQgU3ViYWxsb2NhdGVkSW50VmVjdG9yIGZpbmROYW1lc3BhY2VDb250ZXh0KGludCBlbGVtZW50Tm9kZUluZGV4KQotICB7Ci0gICAgaWYgKG51bGwhPW1fbmFtZXNwYWNlRGVjbFNldEVsZW1lbnRzKQotICAgICAgewotICAgICAgICAvLyAlT1BUJSBJcyBiaW5hcnktc2VhcmNoIHJlYWxseSBzYXZpbmcgdXMgYSBsb3QgdmVyc3VzIGxpbmVhcj8KLSAgICAgICAgLy8gKC4uLiBJdCBtYXkgYmUsIGluIGxhcmdlIGRvY3Mgd2l0aCBtYW55IE5TIGRlY2xzLikKLSAgICAgICAgaW50IHdvdWxkQmVBdD1maW5kSW5Tb3J0ZWRTdWJhbGxvY2F0ZWRJbnRWZWN0b3IobV9uYW1lc3BhY2VEZWNsU2V0RWxlbWVudHMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnROb2RlSW5kZXgpOwotICAgICAgICBpZih3b3VsZEJlQXQ+PTApIC8vIEZvdW5kIGl0Ci0gICAgICAgICAgcmV0dXJuIChTdWJhbGxvY2F0ZWRJbnRWZWN0b3IpIG1fbmFtZXNwYWNlRGVjbFNldHMuZWxlbWVudEF0KHdvdWxkQmVBdCk7Ci0gICAgICAgIGlmKHdvdWxkQmVBdCA9PSAtMSkgLy8gLTEtd291bGRiZWF0ID09IDAKLSAgICAgICAgICByZXR1cm4gbnVsbDsgLy8gTm90IGFmdGVyIGFueXRoaW5nOyBkZWZpbml0ZWx5IG5vdCBmb3VuZAotCi0gICAgICAgIC8vIE5vdCBmb3VuZCwgYnV0IHdlIGtub3cgd2hlcmUgaXQgc2hvdWxkIGhhdmUgYmVlbi4KLSAgICAgICAgLy8gU2VhcmNoIGJhY2sgdW50aWwgd2UgZmluZCBhbiBhbmNlc3RvciBvciBydW4gb3V0LgotICAgICAgICB3b3VsZEJlQXQ9LTEtd291bGRCZUF0OwotCi0gICAgICAgIC8vIERlY3JlbWVudCB3b3VsZEJlQXQgdG8gZmluZCBsYXN0IHBvc3NpYmxlIGFuY2VzdG9yCi0gICAgICAgIGludCBjYW5kaWRhdGU9bV9uYW1lc3BhY2VEZWNsU2V0RWxlbWVudHMuZWxlbWVudEF0KC0tIHdvdWxkQmVBdCk7Ci0gICAgICAgIGludCBhbmNlc3Rvcj1fcGFyZW50KGVsZW1lbnROb2RlSW5kZXgpOwotCi0gICAgICAgIC8vIFNwZWNpYWwgY2FzZTogaWYgdGhlIGNhbmRpZGF0ZSBpcyBiZWZvcmUgdGhlIGdpdmVuIG5vZGUsIGFuZAotICAgICAgICAvLyBpcyBpbiB0aGUgZWFybGllc3QgcG9zc2libGUgcG9zaXRpb24gaW4gdGhlIGRvY3VtZW50LCBpdAotICAgICAgICAvLyBtdXN0IGhhdmUgdGhlIG5hbWVzcGFjZSBkZWNsYXJhdGlvbnMgd2UncmUgaW50ZXJlc3RlZCBpbi4KLSAgICAgICAgaWYgKHdvdWxkQmVBdCA9PSAwICYmIGNhbmRpZGF0ZSA8IGFuY2VzdG9yKSB7Ci0gICAgICAgICAgaW50IHJvb3RIYW5kbGUgPSBnZXREb2N1bWVudFJvb3QobWFrZU5vZGVIYW5kbGUoZWxlbWVudE5vZGVJbmRleCkpOwotICAgICAgICAgIGludCByb290SUQgPSBtYWtlTm9kZUlkZW50aXR5KHJvb3RIYW5kbGUpOwotICAgICAgICAgIGludCB1cHBlcm1vc3ROU0NhbmRpZGF0ZUlEOwotCi0gICAgICAgICAgaWYgKGdldE5vZGVUeXBlKHJvb3RIYW5kbGUpID09IERUTS5ET0NVTUVOVF9OT0RFKSB7Ci0gICAgICAgICAgICBpbnQgY2ggPSBfZmlyc3RjaChyb290SUQpOwotICAgICAgICAgICAgdXBwZXJtb3N0TlNDYW5kaWRhdGVJRCA9IChjaCAhPSBEVE0uTlVMTCkgPyBjaCA6IHJvb3RJRDsKLSAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgdXBwZXJtb3N0TlNDYW5kaWRhdGVJRCA9IHJvb3RJRDsKLSAgICAgICAgICB9Ci0KLSAgICAgICAgICBpZiAoY2FuZGlkYXRlID09IHVwcGVybW9zdE5TQ2FuZGlkYXRlSUQpIHsKLSAgICAgICAgICAgIHJldHVybiAoU3ViYWxsb2NhdGVkSW50VmVjdG9yKW1fbmFtZXNwYWNlRGVjbFNldHMuZWxlbWVudEF0KHdvdWxkQmVBdCk7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgd2hpbGUod291bGRCZUF0Pj0wICYmIGFuY2VzdG9yPjApCi0gICAgICAgICAgewotICAgICAgICAgICAgaWYgKGNhbmRpZGF0ZT09YW5jZXN0b3IpIHsKLSAgICAgICAgICAgICAgICAvLyBGb3VuZCBhbmNlc3RvciBpbiBsaXN0Ci0gICAgICAgICAgICAgICAgcmV0dXJuIChTdWJhbGxvY2F0ZWRJbnRWZWN0b3IpbV9uYW1lc3BhY2VEZWNsU2V0cy5lbGVtZW50QXQod291bGRCZUF0KTsKLSAgICAgICAgICAgIH0gZWxzZSBpZiAoY2FuZGlkYXRlPGFuY2VzdG9yKSB7Ci0gICAgICAgICAgICAgICAgLy8gVG9vIGRlZXAgaW4gdHJlZQotICAgICAgICAgICAgICAgIGRvIHsKLSAgICAgICAgICAgICAgICAgIGFuY2VzdG9yPV9wYXJlbnQoYW5jZXN0b3IpOwotICAgICAgICAgICAgICAgIH0gd2hpbGUgKGNhbmRpZGF0ZSA8IGFuY2VzdG9yKTsKLSAgICAgICAgICAgIH0gZWxzZSBpZih3b3VsZEJlQXQgPiAwKXsKLSAgICAgICAgICAgICAgLy8gVG9vIGxhdGUgaW4gbGlzdAotICAgICAgICAgICAgICBjYW5kaWRhdGU9bV9uYW1lc3BhY2VEZWNsU2V0RWxlbWVudHMuZWxlbWVudEF0KC0td291bGRCZUF0KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICB9Ci0gICAgICB9Ci0KLSAgICByZXR1cm4gbnVsbDsgLy8gTm8gbmFtZXNwYWNlcyBrbm93biBhdCB0aGlzIG5vZGUKLSAgfQotCi0gIC8qKgotICAgICAqIFN1YnJvdXRpbmU6IExvY2F0ZSB0aGUgc3BlY2lmaWVkIG5vZGUgd2l0aGluCi0gICAgICogbV9uYW1lc3BhY2VEZWNsU2V0RWxlbWVudHMsIG9yIHRoZSBsYXN0IGVsZW1lbnQgd2hpY2gKLSAgICAgKiBwcmVjZWVkcyBpdCBpbiBkb2N1bWVudCBvcmRlcgotICAgICAqCi0gICAgICogJVJFVklFVyUgSW5sbmUgdGhpcyBpbnRvIGZpbmROYW1lc3BhY2VDb250ZXh0PyBDcmVhdGUgU29ydGVkU3ViYWxsb2NhdGVkSW50VmVjdG9yIHR5cGU/Ci0gICAgICoKLSAgICAgKiBAcmV0dXJuIElmIHBvc2l0aXZlIG9yIHplcm8sIHRoZSBpbmRleCBvZiB0aGUgZm91bmQgaXRlbS4KLSAgICAgKiBJZiBuZWdhdGl2ZSwgaW5kZXggb2YgdGhlIHBvaW50IGF0IHdoaWNoIGl0IHdvdWxkIGhhdmUgYXBwZWFyZWQsCi0gICAgICogZW5jb2RlZCBhcyAtMS1pbmRleCBhbmQgaGVuY2UgcmVjb252ZXJ0YWJsZSBieSBzdWJ0cmFjdGluZwotICAgICAqIGl0IGZyb20gLTEuIChFbmNvZGluZyBiZWNhdXNlIEkgZG9uJ3Qgd2FudCB0byByZWNvbXBhcmUgdGhlIHN0cmluZ3MKLSAgICAgKiBidXQgZG9uJ3Qgd2FudCB0byBidXJuIGJ5dGVzIG9uIGEgZGF0YXR5cGUgdG8gaG9sZCBhIGZsYWdnZWQgdmFsdWUuKQotICAgICAqLwotICBwcm90ZWN0ZWQgaW50IGZpbmRJblNvcnRlZFN1YmFsbG9jYXRlZEludFZlY3RvcihTdWJhbGxvY2F0ZWRJbnRWZWN0b3IgdmVjdG9yLCBpbnQgbG9va2ZvcikKLSAgewotICAgIC8vIEJpbmFyeSBzZWFyY2gKLSAgICBpbnQgaSA9IDA7Ci0gICAgaWYodmVjdG9yICE9IG51bGwpIHsKLSAgICAgIGludCBmaXJzdCA9IDA7Ci0gICAgICBpbnQgbGFzdCAgPSB2ZWN0b3Iuc2l6ZSgpIC0gMTsKLQotICAgICAgd2hpbGUgKGZpcnN0IDw9IGxhc3QpIHsKLSAgICAgICAgaSA9IChmaXJzdCArIGxhc3QpIC8gMjsKLSAgICAgICAgaW50IHRlc3QgPSBsb29rZm9yLXZlY3Rvci5lbGVtZW50QXQoaSk7Ci0gICAgICAgIGlmKHRlc3QgPT0gMCkgewotICAgICAgICAgIHJldHVybiBpOyAvLyBOYW1lIGZvdW5kCi0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAodGVzdCA8IDApIHsKLSAgICAgICAgICBsYXN0ID0gaSAtIDE7IC8vIGxvb2tlZCB0b28gbGF0ZQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgIGZpcnN0ID0gaSArIDE7IC8vIGxvb2tlZCBvdCBlYXJseQotICAgICAgICB9Ci0gICAgICB9Ci0KLSAgICAgIGlmIChmaXJzdCA+IGkpIHsKLSAgICAgICAgaSA9IGZpcnN0OyAvLyBDbGVhbiB1cCBhdCBsb29wIGVuZAotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiAtMSAtIGk7IC8vIG5vdC1mb3VuZCBoYXMgdG8gYmUgZW5jb2RlZC4KLSAgfQotCi0KLSAgLyoqCi0gICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIGdldCB0aGUgaW5kZXggb2YgdGhlIG5vZGUncyBmaXJzdCBjaGlsZC4KLSAgICogSWYgbm90IHlldCByZXNvbHZlZCwgd2FpdHMgZm9yIG1vcmUgbm9kZXMgdG8gYmUgYWRkZWQgdG8gdGhlIGRvY3VtZW50IGFuZAotICAgKiB0cmllcyBhZ2FpbgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBoYW5kbGUgdG8gbm9kZSwgd2hpY2ggc2hvdWxkIHByb2JhYmx5IGJlIGFuIGVsZW1lbnQKLSAgICogICAgICAgICAgICAgICAgICAgbm9kZSwgYnV0IG5lZWQgbm90IGJlLgotICAgKgotICAgKiBAcGFyYW0gaW5TY29wZSAgICB0cnVlIGlmIGFsbCBuYW1lc3BhY2VzIGluIHNjb3BlIHNob3VsZCBiZSByZXR1cm5lZCwKLSAgICogICAgICAgICAgICAgICAgICAgZmFsc2UgaWYgb25seSB0aGUgbmFtZXNwYWNlIGRlY2xhcmF0aW9ucyBzaG91bGQgYmUKLSAgICogICAgICAgICAgICAgICAgICAgcmV0dXJuZWQuCi0gICAqIEByZXR1cm4gaGFuZGxlIG9mIGZpcnN0IG5hbWVzcGFjZSwgb3IgRFRNLk5VTEwgdG8gaW5kaWNhdGUgbm9uZSBleGlzdHMuCi0gICAqLwotICBwdWJsaWMgaW50IGdldEZpcnN0TmFtZXNwYWNlTm9kZShpbnQgbm9kZUhhbmRsZSwgYm9vbGVhbiBpblNjb3BlKQotICB7Ci0gICAgICAgIGlmKGluU2NvcGUpCi0gICAgICAgIHsKLSAgICAgICAgICAgIGludCBpZGVudGl0eSA9IG1ha2VOb2RlSWRlbnRpdHkobm9kZUhhbmRsZSk7Ci0gICAgICAgICAgICBpZiAoX3R5cGUoaWRlbnRpdHkpID09IERUTS5FTEVNRU5UX05PREUpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIFN1YmFsbG9jYXRlZEludFZlY3RvciBuc0NvbnRleHQ9ZmluZE5hbWVzcGFjZUNvbnRleHQoaWRlbnRpdHkpOwotICAgICAgICAgICAgICBpZihuc0NvbnRleHQ9PW51bGwgfHwgbnNDb250ZXh0LnNpemUoKTwxKQotICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOwotCi0gICAgICAgICAgICAgIHJldHVybiBuc0NvbnRleHQuZWxlbWVudEF0KDApOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKLSAgICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICB7Ci0gICAgICAgICAgICAvLyBBc3N1bWUgdGhhdCBhdHRyaWJ1dGVzIGFuZCBuYW1lc3BhY2VzIGltbWVkaWF0ZWx5Ci0gICAgICAgICAgICAvLyBmb2xsb3cgdGhlIGVsZW1lbnQuCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgLy8gJU9QVCUgV291bGQgdGhpbmdzIGJlIGZhc3RlciBpZiBhbGwgTlMgbm9kZXMgd2VyZSBidWlsdAotICAgICAgICAgICAgLy8gYmVmb3JlIGFsbCBBdHRyIG5vZGVzPyBTb21lIGNvc3RzIGF0IGJ1aWxkIHRpbWUgZm9yIDJuZAotICAgICAgICAgICAgLy8gcGFzcy4uLgotICAgICAgICAgICAgaW50IGlkZW50aXR5ID0gbWFrZU5vZGVJZGVudGl0eShub2RlSGFuZGxlKTsKLSAgICAgICAgICAgIGlmIChfdHlwZShpZGVudGl0eSkgPT0gRFRNLkVMRU1FTlRfTk9ERSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgd2hpbGUgKERUTS5OVUxMICE9IChpZGVudGl0eSA9IGdldE5leHROb2RlSWRlbnRpdHkoaWRlbnRpdHkpKSkKLSAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIGludCB0eXBlID0gX3R5cGUoaWRlbnRpdHkpOwotICAgICAgICAgICAgICAgIGlmICh0eXBlID09IERUTS5OQU1FU1BBQ0VfTk9ERSkKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG1ha2VOb2RlSGFuZGxlKGlkZW50aXR5KTsKLSAgICAgICAgICAgICAgICBlbHNlIGlmIChEVE0uQVRUUklCVVRFX05PREUgIT0gdHlwZSkKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgIHJldHVybiBOVUxMOwotICAgICAgICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBHaXZlbiBhIG5hbWVzcGFjZSBoYW5kbGUsIGFkdmFuY2UgdG8gdGhlIG5leHQgbmFtZXNwYWNlLgotICAgKgotICAgKiBAcGFyYW0gYmFzZUhhbmRsZSBoYW5kbGUgdG8gb3JpZ2luYWwgbm9kZSBmcm9tIHdoZXJlIHRoZSBmaXJzdCBuYW1lc3BhY2UKLSAgICogd2FzIHJlbGF0aXZlIHRvIChuZWVkZWQgdG8gcmV0dXJuIG5vZGVzIGluIGRvY3VtZW50IG9yZGVyKS4KLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgQSBuYW1lc3BhY2UgaGFuZGxlIGZvciB3aGljaCB3ZSB3aWxsIGZpbmQgdGhlIG5leHQgbm9kZS4KLSAgICogQHBhcmFtIGluU2NvcGUgdHJ1ZSBpZiBhbGwgbmFtZXNwYWNlcyB0aGF0IGFyZSBpbiBzY29wZSBzaG91bGQgYmUgcHJvY2Vzc2VkLAotICAgKiBvdGhlcndpc2UganVzdCBwcm9jZXNzIHRoZSBub2RlcyBpbiB0aGUgZ2l2ZW4gZWxlbWVudCBoYW5kbGUuCi0gICAqIEByZXR1cm4gaGFuZGxlIG9mIG5leHQgbmFtZXNwYWNlLCBvciBEVE0uTlVMTCB0byBpbmRpY2F0ZSBub25lIGV4aXN0cy4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0TmV4dE5hbWVzcGFjZU5vZGUoaW50IGJhc2VIYW5kbGUsIGludCBub2RlSGFuZGxlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gaW5TY29wZSkKLSAgewotICAgICAgICBpZihpblNjb3BlKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIC8vU2luY2Ugd2UndmUgYmVlbiBnaXZlbiB0aGUgYmFzZSwgdHJ5IGRpcmVjdCBsb29rdXAKLSAgICAgICAgICAgIC8vKGNvdWxkIGxvb2sgZnJvbSBub2RlSGFuZGxlIGJ1dCB0aGlzIGlzIGF0IGxlYXN0IG9uZQotICAgICAgICAgICAgLy9jb21wYXJpc29uL2dldC1wYXJlbnQgZmFzdGVyKQotICAgICAgICAgICAgLy9TdWJhbGxvY2F0ZWRJbnRWZWN0b3IgbnNDb250ZXh0PWZpbmROYW1lc3BhY2VDb250ZXh0KG5vZGVIYW5kbGUgJiBtX21hc2spOwotCi0gICAgICAgICAgICAgICAgU3ViYWxsb2NhdGVkSW50VmVjdG9yIG5zQ29udGV4dD1maW5kTmFtZXNwYWNlQ29udGV4dChtYWtlTm9kZUlkZW50aXR5KGJhc2VIYW5kbGUpKTsKLQotICAgICAgICAgICAgaWYobnNDb250ZXh0PT1udWxsKQotICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKLSAgICAgICAgICAgIGludCBpPTEgKyBuc0NvbnRleHQuaW5kZXhPZihub2RlSGFuZGxlKTsKLSAgICAgICAgICAgIGlmKGk8PTAgfHwgaT09bnNDb250ZXh0LnNpemUoKSkKLSAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7Ci0KLSAgICAgICAgICAgIHJldHVybiBuc0NvbnRleHQuZWxlbWVudEF0KGkpOwotICAgICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICAgIHsKLSAgICAgICAgICAgIC8vIEFzc3VtZSB0aGF0IGF0dHJpYnV0ZXMgYW5kIG5hbWVzcGFjZSBub2RlcyBpbW1lZGlhdGVseSBmb2xsb3cgdGhlIGVsZW1lbnQuCi0gICAgICAgICAgICBpbnQgaWRlbnRpdHkgPSBtYWtlTm9kZUlkZW50aXR5KG5vZGVIYW5kbGUpOwotICAgICAgICAgICAgd2hpbGUgKERUTS5OVUxMICE9IChpZGVudGl0eSA9IGdldE5leHROb2RlSWRlbnRpdHkoaWRlbnRpdHkpKSkKLSAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIGludCB0eXBlID0gX3R5cGUoaWRlbnRpdHkpOwotICAgICAgICAgICAgICAgIGlmICh0eXBlID09IERUTS5OQU1FU1BBQ0VfTk9ERSkKLSAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG1ha2VOb2RlSGFuZGxlKGlkZW50aXR5KTsKLSAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIGlmICh0eXBlICE9IERUTS5BVFRSSUJVVEVfTk9ERSkKLSAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgIH0KLSAgICAgICAgICB9Ci0gICAgIHJldHVybiBEVE0uTlVMTDsKLSAgfQotCi0gIC8qKgotICAgKiBHaXZlbiBhIG5vZGUgaGFuZGxlLCBmaW5kIGl0cyBwYXJlbnQgbm9kZS4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgdGhlIGlkIG9mIHRoZSBub2RlLgotICAgKiBAcmV0dXJuIGludCBOb2RlLW51bWJlciBvZiBwYXJlbnQsCi0gICAqIG9yIERUTS5OVUxMIHRvIGluZGljYXRlIG5vbmUgZXhpc3RzLgotICAgKi8KLSAgcHVibGljIGludCBnZXRQYXJlbnQoaW50IG5vZGVIYW5kbGUpCi0gIHsKLQotICAgIGludCBpZGVudGl0eSA9IG1ha2VOb2RlSWRlbnRpdHkobm9kZUhhbmRsZSk7Ci0KLSAgICBpZiAoaWRlbnRpdHkgPiAwKQotICAgICAgcmV0dXJuIG1ha2VOb2RlSGFuZGxlKF9wYXJlbnQoaWRlbnRpdHkpKTsKLSAgICBlbHNlCi0gICAgICByZXR1cm4gRFRNLk5VTEw7Ci0gIH0KLQotICAvKioKLSAgICogRmluZCB0aGUgRG9jdW1lbnQgbm9kZSBoYW5kbGUgZm9yIHRoZSBkb2N1bWVudCBjdXJyZW50bHkgdW5kZXIgY29uc3RydWN0aW9uLgotICAgKiBQTEVBU0UgTk9URSB0aGF0IG1vc3QgcGVvcGxlIHNob3VsZCB1c2UgZ2V0T3duZXJEb2N1bWVudChub2RlSGFuZGxlKSBpbnN0ZWFkOwotICAgKiB0aGlzIHZlcnNpb24gb2YgdGhlIG9wZXJhdGlvbiBpcyBwcmltYXJpbHkgaW50ZW5kZWQgZm9yIHVzZSBkdXJpbmcgbmVnb3RpYXRpb24KLSAgICogd2l0aCB0aGUgRFRNIE1hbmFnZXIuCi0gICAqCi0gICAqICBAcmV0dXJuIGludCBOb2RlIGhhbmRsZSBvZiBkb2N1bWVudCwgd2hpY2ggc2hvdWxkIGFsd2F5cyBiZSB2YWxpZC4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0RG9jdW1lbnQoKQotICB7Ci0gICAgcmV0dXJuIG1fZHRtSWRlbnQuZWxlbWVudEF0KDApOyAvLyBtYWtlTm9kZUhhbmRsZSgwKQotICB9Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIGZpbmQgdGhlIG93bmluZyBkb2N1bWVudCBub2RlLiAgVGhpcyBoYXMgdGhlIGV4YWN0Ci0gICAqIHNhbWUgc2VtYW50aWNzIGFzIHRoZSBET00gRG9jdW1lbnQgbWV0aG9kIG9mIHRoZSBzYW1lIG5hbWUsIGluIHRoYXQgaWYKLSAgICogdGhlIG5vZGVIYW5kbGUgaXMgYSBkb2N1bWVudCBub2RlLCBpdCB3aWxsIHJldHVybiBOVUxMLgotICAgKgotICAgKiA8cD4lUkVWSUVXJSBTaW5jZSB0aGlzIGlzIERPTS1zcGVjaWZpYywgaXQgbWF5IGJlbG9uZyBhdCB0aGUgRE9NCi0gICAqIGJpbmRpbmcgbGF5ZXIuIEluY2x1ZGVkIGhlcmUgYXMgYSBjb252ZW5pZW5jZSBmdW5jdGlvbiBhbmQgdG8KLSAgICogYWlkIHBvcnRpbmcgb2YgRE9NIGNvZGUgdG8gRFRNLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgdGhlIGlkIG9mIHRoZSBub2RlLgotICAgKiBAcmV0dXJuIGludCBOb2RlIGhhbmRsZSBvZiBvd25pbmcgZG9jdW1lbnQsIG9yIC0xIGlmIHRoZSBub2RlIHdhcyBhIERvY21lbnQKLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0T3duZXJEb2N1bWVudChpbnQgbm9kZUhhbmRsZSkKLSAgewotCi0gICAgaWYgKERUTS5ET0NVTUVOVF9OT0RFID09IGdldE5vZGVUeXBlKG5vZGVIYW5kbGUpKQotICAgICAgICAgICAgcmV0dXJuIERUTS5OVUxMOwotCi0gICAgcmV0dXJuIGdldERvY3VtZW50Um9vdChub2RlSGFuZGxlKTsKLSAgfQotCi0gIC8qKgotICAgKiBHaXZlbiBhIG5vZGUgaGFuZGxlLCBmaW5kIHRoZSBvd25pbmcgZG9jdW1lbnQgbm9kZS4gIFVubGlrZSB0aGUgRE9NLAotICAgKiB0aGlzIGNvbnNpZGVycyB0aGUgb3duaW5nRG9jdW1lbnQgb2YgYSBEb2N1bWVudCB0byBiZSBpdHNlbGYuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIHRoZSBpZCBvZiB0aGUgbm9kZS4KLSAgICogQHJldHVybiBpbnQgTm9kZSBoYW5kbGUgb2Ygb3duaW5nIGRvY3VtZW50LCBvciB0aGUgbm9kZUhhbmRsZSBpZiBpdCBpcwotICAgKiAgICAgICAgICAgICBhIERvY3VtZW50LgotICAgKi8KLSAgcHVibGljIGludCBnZXREb2N1bWVudFJvb3QoaW50IG5vZGVIYW5kbGUpCi0gIHsKLSAgICByZXR1cm4gZ2V0TWFuYWdlcigpLmdldERUTShub2RlSGFuZGxlKS5nZXREb2N1bWVudCgpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgc3RyaW5nLXZhbHVlIG9mIGEgbm9kZSBhcyBhIFN0cmluZyBvYmplY3QKLSAgICogKHNlZSBodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aCNkYXRhLW1vZGVsCi0gICAqIGZvciB0aGUgZGVmaW5pdGlvbiBvZiBhIG5vZGUncyBzdHJpbmctdmFsdWUpLgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBUaGUgbm9kZSBJRC4KLSAgICoKLSAgICogQHJldHVybiBBIHN0cmluZyBvYmplY3QgdGhhdCByZXByZXNlbnRzIHRoZSBzdHJpbmctdmFsdWUgb2YgdGhlIGdpdmVuIG5vZGUuCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgWE1MU3RyaW5nIGdldFN0cmluZ1ZhbHVlKGludCBub2RlSGFuZGxlKTsKLQotICAvKioKLSAgICogR2V0IG51bWJlciBvZiBjaGFyYWN0ZXIgYXJyYXkgY2h1bmtzIGluCi0gICAqIHRoZSBzdHJpbmctdmFsdWUgb2YgYSBub2RlLgotICAgKiAoc2VlIGh0dHA6Ly93d3cudzMub3JnL1RSL3hwYXRoI2RhdGEtbW9kZWwKLSAgICogZm9yIHRoZSBkZWZpbml0aW9uIG9mIGEgbm9kZSdzIHN0cmluZy12YWx1ZSkuCi0gICAqIE5vdGUgdGhhdCBhIHNpbmdsZSB0ZXh0IG5vZGUgbWF5IGhhdmUgbXVsdGlwbGUgdGV4dCBjaHVua3MuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIFRoZSBub2RlIElELgotICAgKgotICAgKiBAcmV0dXJuIG51bWJlciBvZiBjaGFyYWN0ZXIgYXJyYXkgY2h1bmtzIGluCi0gICAqICAgICAgICAgdGhlIHN0cmluZy12YWx1ZSBvZiBhIG5vZGUuCi0gICAqLwotICBwdWJsaWMgaW50IGdldFN0cmluZ1ZhbHVlQ2h1bmtDb3VudChpbnQgbm9kZUhhbmRsZSkKLSAgewotCi0gICAgLy8gJVRCRCUKLSAgICBlcnJvcihYTUxNZXNzYWdlcy5jcmVhdGVYTUxNZXNzYWdlKFhNTEVycm9yUmVzb3VyY2VzLkVSX01FVEhPRF9OT1RfU1VQUE9SVEVELCBudWxsKSk7Ly8oImdldFN0cmluZ1ZhbHVlQ2h1bmtDb3VudCBub3QgeWV0IHN1cHBvcnRlZCEiKTsKLQotICAgIHJldHVybiAwOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBhIGNoYXJhY3RlciBhcnJheSBjaHVuayBpbiB0aGUgc3RyaW5nLXZhbHVlIG9mIGEgbm9kZS4KLSAgICogKHNlZSBodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aCNkYXRhLW1vZGVsCi0gICAqIGZvciB0aGUgZGVmaW5pdGlvbiBvZiBhIG5vZGUncyBzdHJpbmctdmFsdWUpLgotICAgKiBOb3RlIHRoYXQgYSBzaW5nbGUgdGV4dCBub2RlIG1heSBoYXZlIG11bHRpcGxlIHRleHQgY2h1bmtzLgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBUaGUgbm9kZSBJRC4KLSAgICogQHBhcmFtIGNodW5rSW5kZXggV2hpY2ggY2h1bmsgdG8gZ2V0LgotICAgKiBAcGFyYW0gc3RhcnRBbmRMZW4gQW4gYXJyYXkgb2YgMiB3aGVyZSB0aGUgc3RhcnQgcG9zaXRpb24gYW5kIGxlbmd0aCBvZgotICAgKiAgICAgICAgICAgICAgICAgICAgdGhlIGNodW5rIHdpbGwgYmUgcmV0dXJuZWQuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGNoYXJhY3RlciBhcnJheSByZWZlcmVuY2Ugd2hlcmUgdGhlIGNodW5rIG9jY3Vycy4KLSAgICovCi0gIHB1YmxpYyBjaGFyW10gZ2V0U3RyaW5nVmFsdWVDaHVuayhpbnQgbm9kZUhhbmRsZSwgaW50IGNodW5rSW5kZXgsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnRbXSBzdGFydEFuZExlbikKLSAgewotCi0gICAgLy8gJVRCRCUKLSAgICBlcnJvcihYTUxNZXNzYWdlcy5jcmVhdGVYTUxNZXNzYWdlKFhNTEVycm9yUmVzb3VyY2VzLkVSX01FVEhPRF9OT1RfU1VQUE9SVEVELCBudWxsKSk7Ly8iZ2V0U3RyaW5nVmFsdWVDaHVuayBub3QgeWV0IHN1cHBvcnRlZCEiKTsKLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIHJldHVybiBhbiBJRCB0aGF0IHJlcHJlc2VudHMgdGhlIG5vZGUncyBleHBhbmRlZCBuYW1lLgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBUaGUgaGFuZGxlIHRvIHRoZSBub2RlIGluIHF1ZXN0aW9uLgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBleHBhbmRlZC1uYW1lIGlkIG9mIHRoZSBub2RlLgotICAgKi8KLSAgcHVibGljIGludCBnZXRFeHBhbmRlZFR5cGVJRChpbnQgbm9kZUhhbmRsZSkKLSAgewotICAgIC8vICVSRVZJRVclIFRoaXMgX3Nob3VsZF8gb25seSBiZSBudWxsIGlmIHNvbWVvbmUgYXNrZWQgdGhlIHdyb25nIERUTSBhYm91dCB0aGUgbm9kZS4uLgotICAgIC8vIHdoaWNoIG9uZSB3b3VsZCBob3BlIHdvdWxkIG5ldmVyIGhhcHBlbi4uLgotICAgIGludCBpZD1tYWtlTm9kZUlkZW50aXR5KG5vZGVIYW5kbGUpOwotICAgIGlmKGlkPT1OVUxMKQotICAgICAgcmV0dXJuIE5VTEw7Ci0gICAgcmV0dXJuIF9leHB0eXBlKGlkKTsKLSAgfQotCi0gIC8qKgotICAgKiBHaXZlbiBhbiBleHBhbmRlZCBuYW1lLCByZXR1cm4gYW4gSUQuICBJZiB0aGUgZXhwYW5kZWQtbmFtZSBkb2VzIG5vdAotICAgKiBleGlzdCBpbiB0aGUgaW50ZXJuYWwgdGFibGVzLCB0aGUgZW50cnkgd2lsbCBiZSBjcmVhdGVkLCBhbmQgdGhlIElEIHdpbGwKLSAgICogYmUgcmV0dXJuZWQuICBBbnkgYWRkaXRpb25hbCBub2RlcyB0aGF0IGFyZSBjcmVhdGVkIHRoYXQgaGF2ZSB0aGlzCi0gICAqIGV4cGFuZGVkIG5hbWUgd2lsbCB1c2UgdGhpcyBJRC4KLSAgICoKLSAgICogQHBhcmFtIHR5cGUgVGhlIHNpbXBsZSB0eXBlLCBpLmUuIG9uZSBvZiBFTEVNRU5ULCBBVFRSSUJVVEUsIGV0Yy4KLSAgICoKLSAgICogQHBhcmFtIG5hbWVzcGFjZSBUaGUgbmFtZXNwYWNlIFVSSSwgd2hpY2ggbWF5IGJlIG51bGwsIG1heSBiZSBhbiBlbXB0eQotICAgKiAgICAgICAgICAgICAgICAgIHN0cmluZyAod2hpY2ggd2lsbCBiZSB0aGUgc2FtZSBhcyBudWxsKSwgb3IgbWF5IGJlIGEKLSAgICogICAgICAgICAgICAgICAgICBuYW1lc3BhY2UgVVJJLgotICAgKiBAcGFyYW0gbG9jYWxOYW1lIFRoZSBsb2NhbCBuYW1lIHN0cmluZywgd2hpY2ggbXVzdCBiZSBhIHZhbGlkCi0gICAqICAgICAgICAgICAgICAgICAgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLXhtbC1uYW1lcy8iPk5DTmFtZTwvYT4uCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIGV4cGFuZGVkLW5hbWUgaWQgb2YgdGhlIG5vZGUuCi0gICAqLwotICBwdWJsaWMgaW50IGdldEV4cGFuZGVkVHlwZUlEKFN0cmluZyBuYW1lc3BhY2UsIFN0cmluZyBsb2NhbE5hbWUsIGludCB0eXBlKQotICB7Ci0KLSAgICBFeHBhbmRlZE5hbWVUYWJsZSBlbnQgPSBtX2V4cGFuZGVkTmFtZVRhYmxlOwotCi0gICAgcmV0dXJuIGVudC5nZXRFeHBhbmRlZFR5cGVJRChuYW1lc3BhY2UsIGxvY2FsTmFtZSwgdHlwZSk7Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYW4gZXhwYW5kZWQtbmFtZSBJRCwgcmV0dXJuIHRoZSBsb2NhbCBuYW1lIHBhcnQuCi0gICAqCi0gICAqIEBwYXJhbSBleHBhbmRlZE5hbWVJRCBhbiBJRCB0aGF0IHJlcHJlc2VudHMgYW4gZXhwYW5kZWQtbmFtZS4KLSAgICogQHJldHVybiBTdHJpbmcgTG9jYWwgbmFtZSBvZiB0aGlzIG5vZGUuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldExvY2FsTmFtZUZyb21FeHBhbmRlZE5hbWVJRChpbnQgZXhwYW5kZWROYW1lSUQpCi0gIHsKLSAgICByZXR1cm4gbV9leHBhbmRlZE5hbWVUYWJsZS5nZXRMb2NhbE5hbWUoZXhwYW5kZWROYW1lSUQpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGFuIGV4cGFuZGVkLW5hbWUgSUQsIHJldHVybiB0aGUgbmFtZXNwYWNlIFVSSSBwYXJ0LgotICAgKgotICAgKiBAcGFyYW0gZXhwYW5kZWROYW1lSUQgYW4gSUQgdGhhdCByZXByZXNlbnRzIGFuIGV4cGFuZGVkLW5hbWUuCi0gICAqIEByZXR1cm4gU3RyaW5nIFVSSSB2YWx1ZSBvZiB0aGlzIG5vZGUncyBuYW1lc3BhY2UsIG9yIG51bGwgaWYgbm8KLSAgICogbmFtZXNwYWNlIHdhcyByZXNvbHZlZC4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZXNwYWNlRnJvbUV4cGFuZGVkTmFtZUlEKGludCBleHBhbmRlZE5hbWVJRCkKLSAgewotICAgIHJldHVybiBtX2V4cGFuZGVkTmFtZVRhYmxlLmdldE5hbWVzcGFjZShleHBhbmRlZE5hbWVJRCk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgbmFtZXNwYWNlIHR5cGUgb2YgYSBzcGVjaWZpYyBub2RlCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIHRoZSBpZCBvZiB0aGUgbm9kZS4KLSAgICogQHJldHVybiB0aGUgSUQgb2YgdGhlIG5hbWVzcGFjZS4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0TmFtZXNwYWNlVHlwZShmaW5hbCBpbnQgbm9kZUhhbmRsZSkKLSAgewotCi0gICAgaW50IGlkZW50aXR5ID0gbWFrZU5vZGVJZGVudGl0eShub2RlSGFuZGxlKTsKLSAgICBpbnQgZXhwYW5kZWROYW1lSUQgPSBfZXhwdHlwZShpZGVudGl0eSk7Ci0KLSAgICByZXR1cm4gbV9leHBhbmRlZE5hbWVUYWJsZS5nZXROYW1lc3BhY2VJRChleHBhbmRlZE5hbWVJRCk7Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYSBub2RlIGhhbmRsZSwgcmV0dXJuIGl0cyBET00tc3R5bGUgbm9kZSBuYW1lLiBUaGlzIHdpbGwKLSAgICogaW5jbHVkZSBuYW1lcyBzdWNoIGFzICN0ZXh0IG9yICNkb2N1bWVudC4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgdGhlIGlkIG9mIHRoZSBub2RlLgotICAgKiBAcmV0dXJuIFN0cmluZyBOYW1lIG9mIHRoaXMgbm9kZSwgd2hpY2ggbWF5IGJlIGFuIGVtcHR5IHN0cmluZy4KLSAgICogJVJFVklFVyUgRG9jdW1lbnQgd2hlbiBlbXB0eSBzdHJpbmcgaXMgcG9zc2libGUuLi4KLSAgICogJVJFVklFVy1DT01NRU5UJSBJdCBzaG91bGQgbmV2ZXIgYmUgZW1wdHksIHNob3VsZCBpdD8KLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBTdHJpbmcgZ2V0Tm9kZU5hbWUoaW50IG5vZGVIYW5kbGUpOwotCi0gIC8qKgotICAgKiBHaXZlbiBhIG5vZGUgaGFuZGxlLCByZXR1cm4gdGhlIFhQYXRoIG5vZGUgbmFtZS4gIFRoaXMgc2hvdWxkIGJlCi0gICAqIHRoZSBuYW1lIGFzIGRlc2NyaWJlZCBieSB0aGUgWFBhdGggZGF0YSBtb2RlbCwgTk9UIHRoZSBET00tc3R5bGUKLSAgICogbmFtZS4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgdGhlIGlkIG9mIHRoZSBub2RlLgotICAgKiBAcmV0dXJuIFN0cmluZyBOYW1lIG9mIHRoaXMgbm9kZSwgd2hpY2ggbWF5IGJlIGFuIGVtcHR5IHN0cmluZy4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0Tm9kZU5hbWVYKGludCBub2RlSGFuZGxlKQotICB7Ci0KLSAgICAvKiogQHRvZG86IGltcGxlbWVudCB0aGlzIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTURlZmF1bHRCYXNlIGFic3RyYWN0IG1ldGhvZCAqLwotICAgIGVycm9yKFhNTE1lc3NhZ2VzLmNyZWF0ZVhNTE1lc3NhZ2UoWE1MRXJyb3JSZXNvdXJjZXMuRVJfTUVUSE9EX05PVF9TVVBQT1JURUQsIG51bGwpKTsvLyJOb3QgeWV0IHN1cHBvcnRlZCEiKTsKLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIHJldHVybiBpdHMgWFBhdGgtc3R5bGUgbG9jYWxuYW1lLgotICAgKiAoQXMgZGVmaW5lZCBpbiBOYW1lc3BhY2VzLCB0aGlzIGlzIHRoZSBwb3J0aW9uIG9mIHRoZSBuYW1lIGFmdGVyIGFueQotICAgKiBjb2xvbiBjaGFyYWN0ZXIpLgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSB0aGUgaWQgb2YgdGhlIG5vZGUuCi0gICAqIEByZXR1cm4gU3RyaW5nIExvY2FsIG5hbWUgb2YgdGhpcyBub2RlLgotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IFN0cmluZyBnZXRMb2NhbE5hbWUoaW50IG5vZGVIYW5kbGUpOwotCi0gIC8qKgotICAgKiBHaXZlbiBhIG5hbWVzcGFjZSBoYW5kbGUsIHJldHVybiB0aGUgcHJlZml4IHRoYXQgdGhlIG5hbWVzcGFjZSBkZWNsIGlzCi0gICAqIG1hcHBpbmcuCi0gICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIHJldHVybiB0aGUgcHJlZml4IHVzZWQgdG8gbWFwIHRvIHRoZSBuYW1lc3BhY2UuCi0gICAqCi0gICAqIDxwPiAlUkVWSUVXJSBBcmUgeW91IHN1cmUgeW91IHdhbnQgIiIgZm9yIG5vIHByZWZpeD8gIDwvcD4KLSAgICogPHA+ICVSRVZJRVctQ09NTUVOVCUgSSB0aGluayBzby4uLiBub3QgdG90YWxseSBzdXJlLiAtc2IgIDwvcD4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgdGhlIGlkIG9mIHRoZSBub2RlLgotICAgKiBAcmV0dXJuIFN0cmluZyBwcmVmaXggb2YgdGhpcyBub2RlJ3MgbmFtZSwgb3IgIiIgaWYgbm8gZXhwbGljaXQKLSAgICogbmFtZXNwYWNlIHByZWZpeCB3YXMgZ2l2ZW4uCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nIGdldFByZWZpeChpbnQgbm9kZUhhbmRsZSk7Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIHJldHVybiBpdHMgRE9NLXN0eWxlIG5hbWVzcGFjZSBVUkkKLSAgICogKEFzIGRlZmluZWQgaW4gTmFtZXNwYWNlcywgdGhpcyBpcyB0aGUgZGVjbGFyZWQgVVJJIHdoaWNoIHRoaXMgbm9kZSdzCi0gICAqIHByZWZpeCAtLSBvciBkZWZhdWx0IGluIGxpZXUgdGhlcmVvZiAtLSB3YXMgbWFwcGVkIHRvLikKLSAgICoKLSAgICogPHA+JVJFVklFVyUgTnVsbCBvciAiIj8gLXNiPC9wPgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSB0aGUgaWQgb2YgdGhlIG5vZGUuCi0gICAqIEByZXR1cm4gU3RyaW5nIFVSSSB2YWx1ZSBvZiB0aGlzIG5vZGUncyBuYW1lc3BhY2UsIG9yIG51bGwgaWYgbm8KLSAgICogbmFtZXNwYWNlIHdhcyByZXNvbHZlZC4KLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBTdHJpbmcgZ2V0TmFtZXNwYWNlVVJJKGludCBub2RlSGFuZGxlKTsKLQotICAvKioKLSAgICogR2l2ZW4gYSBub2RlIGhhbmRsZSwgcmV0dXJuIGl0cyBub2RlIHZhbHVlLiBUaGlzIGlzIG1vc3RseQotICAgKiBhcyBkZWZpbmVkIGJ5IHRoZSBET00sIGJ1dCBtYXkgaWdub3JlIHNvbWUgY29udmVuaWVuY2VzLgotICAgKiA8cD4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgVGhlIG5vZGUgaWQuCi0gICAqIEByZXR1cm4gU3RyaW5nIFZhbHVlIG9mIHRoaXMgbm9kZSwgb3IgbnVsbCBpZiBub3QKLSAgICogbWVhbmluZ2Z1bCBmb3IgdGhpcyBub2RlIHR5cGUuCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nIGdldE5vZGVWYWx1ZShpbnQgbm9kZUhhbmRsZSk7Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIHJldHVybiBpdHMgRE9NLXN0eWxlIG5vZGUgdHlwZS4KLSAgICogPHA+Ci0gICAqICVSRVZJRVclIEdlbmVyYWxseSwgcmV0dXJuaW5nIHNob3J0IGlzIGZhbHNlIGVjb25vbXkuIFJldHVybiBpbnQ/Ci0gICAqICVSRVZJRVclIE1ha2UgYXNzdW1wdGlvbiB0aGF0IG5vZGUgaGFzIGFscmVhZHkgYXJyaXZlZC4gIElzIE9LPwotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBUaGUgbm9kZSBpZC4KLSAgICogQHJldHVybiBpbnQgTm9kZSB0eXBlLCBhcyBwZXIgdGhlIERPTSdzIE5vZGUuX05PREUgY29uc3RhbnRzLgotICAgKi8KLSAgcHVibGljIHNob3J0IGdldE5vZGVUeXBlKGludCBub2RlSGFuZGxlKQotICB7Ci0gICAgICAgIGlmIChub2RlSGFuZGxlID09IERUTS5OVUxMKQotICAgICAgICByZXR1cm4gRFRNLk5VTEw7Ci0gICAgcmV0dXJuIG1fZXhwYW5kZWROYW1lVGFibGUuZ2V0VHlwZShfZXhwdHlwZShtYWtlTm9kZUlkZW50aXR5KG5vZGVIYW5kbGUpKSk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBkZXB0aCBsZXZlbCBvZiB0aGlzIG5vZGUgaW4gdGhlIHRyZWUgKGVxdWFscyAxIGZvcgotICAgKiBhIHBhcmVudGxlc3Mgbm9kZSkuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIFRoZSBub2RlIGlkLgotICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgYW5jZXN0b3JzLCBwbHVzIG9uZQotICAgKiBAeHNsLnVzYWdlIGludGVybmFsCi0gICAqLwotICBwdWJsaWMgc2hvcnQgZ2V0TGV2ZWwoaW50IG5vZGVIYW5kbGUpCi0gIHsKLSAgICAvLyBBcHBhcmVudGx5LCB0aGUgYXhpcyB3YWxrZXIgc3R1ZmYgcmVxdWlyZXMgbGV2ZWxzIHRvIGNvdW50IGZyb20gMS4KLSAgICBpbnQgaWRlbnRpdHkgPSBtYWtlTm9kZUlkZW50aXR5KG5vZGVIYW5kbGUpOwotICAgIHJldHVybiAoc2hvcnQpIChfbGV2ZWwoaWRlbnRpdHkpICsgMSk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBpZGVudGl0eSBvZiB0aGlzIG5vZGUgaW4gdGhlIHRyZWUKLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgVGhlIG5vZGUgaGFuZGxlLgotICAgKiBAcmV0dXJuIHRoZSBub2RlIGlkZW50aXR5Ci0gICAqIEB4c2wudXNhZ2UgaW50ZXJuYWwKLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0Tm9kZUlkZW50KGludCBub2RlSGFuZGxlKQotICB7Ci0gICAgLyppZiAobm9kZUhhbmRsZSAhPSBEVE0uTlVMTCkKLSAgICAgIHJldHVybiBub2RlSGFuZGxlICYgbV9tYXNrOwotICAgIGVsc2UKLSAgICAgIHJldHVybiBEVE0uTlVMTDsqLwotCi0gICAgICByZXR1cm4gbWFrZU5vZGVJZGVudGl0eShub2RlSGFuZGxlKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGhhbmRsZSBvZiB0aGlzIG5vZGUgaW4gdGhlIHRyZWUKLSAgICoKLSAgICogQHBhcmFtIG5vZGVJZCBUaGUgbm9kZSBpZGVudGl0eS4KLSAgICogQHJldHVybiB0aGUgbm9kZSBoYW5kbGUKLSAgICogQHhzbC51c2FnZSBpbnRlcm5hbAotICAgKi8KLSAgcHVibGljIGludCBnZXROb2RlSGFuZGxlKGludCBub2RlSWQpCi0gIHsKLSAgICAvKmlmIChub2RlSWQgIT0gRFRNLk5VTEwpCi0gICAgICByZXR1cm4gbm9kZUlkIHwgbV9kdG1JZGVudDsKLSAgICBlbHNlCi0gICAgICByZXR1cm4gRFRNLk5VTEw7Ki8KLQotICAgICAgcmV0dXJuIG1ha2VOb2RlSGFuZGxlKG5vZGVJZCk7Ci0gIH0KLQotICAvLyA9PT09PT09PT09PT09PSBEb2N1bWVudCBxdWVyeSBmdW5jdGlvbnMgPT09PT09PT09PT09PT0KLQotICAvKioKLSAgICogVGVzdHMgd2hldGhlciBEVE0gRE9NIGltcGxlbWVudGF0aW9uIGltcGxlbWVudHMgYSBzcGVjaWZpYyBmZWF0dXJlIGFuZAotICAgKiB0aGF0IGZlYXR1cmUgaXMgc3VwcG9ydGVkIGJ5IHRoaXMgbm9kZS4KLSAgICoKLSAgICogQHBhcmFtIGZlYXR1cmUgVGhlIG5hbWUgb2YgdGhlIGZlYXR1cmUgdG8gdGVzdC4KLSAgICogQHBhcmFtIHZlcnNpb24gVGhpcyBpcyB0aGUgdmVyc2lvbiBudW1iZXIgb2YgdGhlIGZlYXR1cmUgdG8gdGVzdC4KLSAgICogICBJZiB0aGUgdmVyc2lvbiBpcyBub3QKLSAgICogICBzcGVjaWZpZWQsIHN1cHBvcnRpbmcgYW55IHZlcnNpb24gb2YgdGhlIGZlYXR1cmUgd2lsbCBjYXVzZSB0aGUKLSAgICogICBtZXRob2QgdG8gcmV0dXJuIDxjb2RlPnRydWU8L2NvZGU+LgotICAgKiBAcmV0dXJuIFJldHVybnMgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIHNwZWNpZmllZCBmZWF0dXJlIGlzCi0gICAqICAgc3VwcG9ydGVkIG9uIHRoaXMgbm9kZSwgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzU3VwcG9ydGVkKFN0cmluZyBmZWF0dXJlLCBTdHJpbmcgdmVyc2lvbikKLSAgewotCi0gICAgLy8gJVRCRCUKLSAgICByZXR1cm4gZmFsc2U7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBiYXNlIFVSSSBvZiB0aGUgZG9jdW1lbnQgZW50aXR5LiBJZiBpdCBpcyBub3Qga25vd24KLSAgICogKGJlY2F1c2UgdGhlIGRvY3VtZW50IHdhcyBwYXJzZWQgZnJvbSBhIHNvY2tldCBjb25uZWN0aW9uIG9yIGZyb20KLSAgICogc3RhbmRhcmQgaW5wdXQsIGZvciBleGFtcGxlKSwgdGhlIHZhbHVlIG9mIHRoaXMgcHJvcGVydHkgaXMgdW5rbm93bi4KLSAgICoKLSAgICogQHJldHVybiB0aGUgZG9jdW1lbnQgYmFzZSBVUkkgU3RyaW5nIG9iamVjdCBvciBudWxsIGlmIHVua25vd24uCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldERvY3VtZW50QmFzZVVSSSgpCi0gIHsKLSAgICByZXR1cm4gbV9kb2N1bWVudEJhc2VVUkk7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBiYXNlIFVSSSBvZiB0aGUgZG9jdW1lbnQgZW50aXR5LgotICAgKgotICAgKiBAcGFyYW0gYmFzZVVSSSB0aGUgZG9jdW1lbnQgYmFzZSBVUkkgU3RyaW5nIG9iamVjdCBvciBudWxsIGlmIHVua25vd24uCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXREb2N1bWVudEJhc2VVUkkoU3RyaW5nIGJhc2VVUkkpCi0gIHsKLSAgICBtX2RvY3VtZW50QmFzZVVSSSA9IGJhc2VVUkk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBzeXN0ZW0gaWRlbnRpZmllciBvZiB0aGUgZG9jdW1lbnQgZW50aXR5LiBJZgotICAgKiBpdCBpcyBub3Qga25vd24sIHRoZSB2YWx1ZSBvZiB0aGlzIHByb3BlcnR5IGlzIHVua25vd24uCi0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIFRoZSBub2RlIGlkLCB3aGljaCBjYW4gYmUgYW55IHZhbGlkIG5vZGUgaGFuZGxlLgotICAgKiBAcmV0dXJuIHRoZSBzeXN0ZW0gaWRlbnRpZmllciBTdHJpbmcgb2JqZWN0IG9yIG51bGwgaWYgdW5rbm93bi4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0RG9jdW1lbnRTeXN0ZW1JZGVudGlmaWVyKGludCBub2RlSGFuZGxlKQotICB7Ci0KLSAgICAvLyAlUkVWSUVXJSAgT0s/IC1zYgotICAgIHJldHVybiBtX2RvY3VtZW50QmFzZVVSSTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIG5hbWUgb2YgdGhlIGNoYXJhY3RlciBlbmNvZGluZyBzY2hlbWUKLSAgICogICAgICAgIGluIHdoaWNoIHRoZSBkb2N1bWVudCBlbnRpdHkgaXMgZXhwcmVzc2VkLgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBUaGUgbm9kZSBpZCwgd2hpY2ggY2FuIGJlIGFueSB2YWxpZCBub2RlIGhhbmRsZS4KLSAgICogQHJldHVybiB0aGUgZG9jdW1lbnQgZW5jb2RpbmcgU3RyaW5nIG9iamVjdC4KLSAgICogQHhzbC51c2FnZSBpbnRlcm5hbAotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXREb2N1bWVudEVuY29kaW5nKGludCBub2RlSGFuZGxlKQotICB7Ci0KLSAgICAvLyAlUkVWSUVXJSAgT0s/PyAgLXNiCi0gICAgcmV0dXJuICJVVEYtOCI7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIGFuIGluZGljYXRpb24gb2YgdGhlIHN0YW5kYWxvbmUgc3RhdHVzIG9mIHRoZSBkb2N1bWVudCwKLSAgICogICAgICAgIGVpdGhlciAieWVzIiBvciAibm8iLiBUaGlzIHByb3BlcnR5IGlzIGRlcml2ZWQgZnJvbSB0aGUgb3B0aW9uYWwKLSAgICogICAgICAgIHN0YW5kYWxvbmUgZG9jdW1lbnQgZGVjbGFyYXRpb24gaW4gdGhlIFhNTCBkZWNsYXJhdGlvbiBhdCB0aGUKLSAgICogICAgICAgIGJlZ2lubmluZyBvZiB0aGUgZG9jdW1lbnQgZW50aXR5LCBhbmQgaGFzIG5vIHZhbHVlIGlmIHRoZXJlIGlzIG5vCi0gICAqICAgICAgICBzdGFuZGFsb25lIGRvY3VtZW50IGRlY2xhcmF0aW9uLgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBUaGUgbm9kZSBpZCwgd2hpY2ggY2FuIGJlIGFueSB2YWxpZCBub2RlIGhhbmRsZS4KLSAgICogQHJldHVybiB0aGUgZG9jdW1lbnQgc3RhbmRhbG9uZSBTdHJpbmcgb2JqZWN0LCBlaXRoZXIgInllcyIsICJubyIsIG9yIG51bGwuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldERvY3VtZW50U3RhbmRhbG9uZShpbnQgbm9kZUhhbmRsZSkKLSAgewotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiBhIHN0cmluZyByZXByZXNlbnRpbmcgdGhlIFhNTCB2ZXJzaW9uIG9mIHRoZSBkb2N1bWVudC4gVGhpcwotICAgKiBwcm9wZXJ0eSBpcyBkZXJpdmVkIGZyb20gdGhlIFhNTCBkZWNsYXJhdGlvbiBvcHRpb25hbGx5IHByZXNlbnQgYXQgdGhlCi0gICAqIGJlZ2lubmluZyBvZiB0aGUgZG9jdW1lbnQgZW50aXR5LCBhbmQgaGFzIG5vIHZhbHVlIGlmIHRoZXJlIGlzIG5vIFhNTAotICAgKiBkZWNsYXJhdGlvbi4KLSAgICoKLSAgICogQHBhcmFtIGRvY3VtZW50SGFuZGxlIFRoZSBkb2N1bWVudCBoYW5kbGUKLSAgICoKLSAgICogQHJldHVybiB0aGUgZG9jdW1lbnQgdmVyc2lvbiBTdHJpbmcgb2JqZWN0LgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXREb2N1bWVudFZlcnNpb24oaW50IGRvY3VtZW50SGFuZGxlKQotICB7Ci0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIGFuIGluZGljYXRpb24gb2YKLSAgICogd2hldGhlciB0aGUgcHJvY2Vzc29yIGhhcyByZWFkIHRoZSBjb21wbGV0ZSBEVEQuIEl0cyB2YWx1ZSBpcyBhCi0gICAqIGJvb2xlYW4uIElmIGl0IGlzIGZhbHNlLCB0aGVuIGNlcnRhaW4gcHJvcGVydGllcyAoaW5kaWNhdGVkIGluIHRoZWlyCi0gICAqIGRlc2NyaXB0aW9ucyBiZWxvdykgbWF5IGJlIHVua25vd24uIElmIGl0IGlzIHRydWUsIHRob3NlIHByb3BlcnRpZXMKLSAgICogYXJlIG5ldmVyIHVua25vd24uCi0gICAqCi0gICAqIEByZXR1cm4gPGNvZGU+dHJ1ZTwvY29kZT4gaWYgYWxsIGRlY2xhcmF0aW9ucyB3ZXJlIHByb2Nlc3NlZDsKLSAgICogICAgICAgICA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZ2V0RG9jdW1lbnRBbGxEZWNsYXJhdGlvbnNQcm9jZXNzZWQoKQotICB7Ci0KLSAgICAvLyAlUkVWSUVXJSBPSz8KLSAgICByZXR1cm4gdHJ1ZTsKLSAgfQotCi0gIC8qKgotICAgKiAgIEEgZG9jdW1lbnQgdHlwZSBkZWNsYXJhdGlvbiBpbmZvcm1hdGlvbiBpdGVtIGhhcyB0aGUgZm9sbG93aW5nIHByb3BlcnRpZXM6Ci0gICAqCi0gICAqICAgICAxLiBbc3lzdGVtIGlkZW50aWZpZXJdIFRoZSBzeXN0ZW0gaWRlbnRpZmllciBvZiB0aGUgZXh0ZXJuYWwgc3Vic2V0LCBpZgotICAgKiAgICAgICAgaXQgZXhpc3RzLiBPdGhlcndpc2UgdGhpcyBwcm9wZXJ0eSBoYXMgbm8gdmFsdWUuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIHN5c3RlbSBpZGVudGlmaWVyIFN0cmluZyBvYmplY3QsIG9yIG51bGwgaWYgdGhlcmUgaXMgbm9uZS4KLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBTdHJpbmcgZ2V0RG9jdW1lbnRUeXBlRGVjbGFyYXRpb25TeXN0ZW1JZGVudGlmaWVyKCk7Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgcHVibGljIGlkZW50aWZpZXIgb2YgdGhlIGV4dGVybmFsIHN1YnNldCwKLSAgICogbm9ybWFsaXplZCBhcyBkZXNjcmliZWQgaW4gNC4yLjIgRXh0ZXJuYWwgRW50aXRpZXMgW1hNTF0uIElmIHRoZXJlIGlzCi0gICAqIG5vIGV4dGVybmFsIHN1YnNldCBvciBpZiBpdCBoYXMgbm8gcHVibGljIGlkZW50aWZpZXIsIHRoaXMgcHJvcGVydHkKLSAgICogaGFzIG5vIHZhbHVlLgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBwdWJsaWMgaWRlbnRpZmllciBTdHJpbmcgb2JqZWN0LCBvciBudWxsIGlmIHRoZXJlIGlzIG5vbmUuCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nIGdldERvY3VtZW50VHlwZURlY2xhcmF0aW9uUHVibGljSWRlbnRpZmllcigpOwotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSA8Y29kZT5FbGVtZW50PC9jb2RlPiB3aG9zZSA8Y29kZT5JRDwvY29kZT4gaXMgZ2l2ZW4gYnkKLSAgICogPGNvZGU+ZWxlbWVudElkPC9jb2RlPi4gSWYgbm8gc3VjaCBlbGVtZW50IGV4aXN0cywgcmV0dXJucwotICAgKiA8Y29kZT5EVE0uTlVMTDwvY29kZT4uIEJlaGF2aW9yIGlzIG5vdCBkZWZpbmVkIGlmIG1vcmUgdGhhbiBvbmUgZWxlbWVudAotICAgKiBoYXMgdGhpcyA8Y29kZT5JRDwvY29kZT4uIEF0dHJpYnV0ZXMgKGluY2x1ZGluZyB0aG9zZQotICAgKiB3aXRoIHRoZSBuYW1lICJJRCIpIGFyZSBub3Qgb2YgdHlwZSBJRCB1bmxlc3Mgc28gZGVmaW5lZCBieSBEVEQvU2NoZW1hCi0gICAqIGluZm9ybWF0aW9uIGF2YWlsYWJsZSB0byB0aGUgRFRNIGltcGxlbWVudGF0aW9uLgotICAgKiBJbXBsZW1lbnRhdGlvbnMgdGhhdCBkbyBub3Qga25vdyB3aGV0aGVyIGF0dHJpYnV0ZXMgYXJlIG9mIHR5cGUgSUQgb3IKLSAgICogbm90IGFyZSBleHBlY3RlZCB0byByZXR1cm4gPGNvZGU+RFRNLk5VTEw8L2NvZGU+LgotICAgKgotICAgKiA8cD4lUkVWSUVXJSBQcmVzdW1hYmx5IElEcyBhcmUgc3RpbGwgc2NvcGVkIHRvIGEgc2luZ2xlIGRvY3VtZW50LAotICAgKiBhbmQgdGhpcyBvcGVyYXRpb24gc2VhcmNoZXMgb25seSB3aXRoaW4gYSBzaW5nbGUgZG9jdW1lbnQsIHJpZ2h0PwotICAgKiBXb3VsZG4ndCB3YW50IGNvbGxpc2lvbnMgYmV0d2VlbiBEVE1zIGluIHRoZSBzYW1lIHByb2Nlc3MuPC9wPgotICAgKgotICAgKiBAcGFyYW0gZWxlbWVudElkIFRoZSB1bmlxdWUgPGNvZGU+aWQ8L2NvZGU+IHZhbHVlIGZvciBhbiBlbGVtZW50LgotICAgKiBAcmV0dXJuIFRoZSBoYW5kbGUgb2YgdGhlIG1hdGNoaW5nIGVsZW1lbnQuCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgaW50IGdldEVsZW1lbnRCeUlkKFN0cmluZyBlbGVtZW50SWQpOwotCi0gIC8qKgotICAgKiBUaGUgZ2V0VW5wYXJzZWRFbnRpdHlVUkkgZnVuY3Rpb24gcmV0dXJucyB0aGUgVVJJIG9mIHRoZSB1bnBhcnNlZAotICAgKiBlbnRpdHkgd2l0aCB0aGUgc3BlY2lmaWVkIG5hbWUgaW4gdGhlIHNhbWUgZG9jdW1lbnQgYXMgdGhlIGNvbnRleHQKLSAgICogbm9kZSAoc2VlIFszLjMgVW5wYXJzZWQgRW50aXRpZXNdKS4gSXQgcmV0dXJucyB0aGUgZW1wdHkgc3RyaW5nIGlmCi0gICAqIHRoZXJlIGlzIG5vIHN1Y2ggZW50aXR5LgotICAgKiA8cD4KLSAgICogWE1MIHByb2Nlc3NvcnMgbWF5IGNob29zZSB0byB1c2UgdGhlIFN5c3RlbSBJZGVudGlmaWVyIChpZiBvbmUKLSAgICogaXMgcHJvdmlkZWQpIHRvIHJlc29sdmUgdGhlIGVudGl0eSwgcmF0aGVyIHRoYW4gdGhlIFVSSSBpbiB0aGUKLSAgICogUHVibGljIElkZW50aWZpZXIuIFRoZSBkZXRhaWxzIGFyZSBkZXBlbmRlbnQgb24gdGhlIHByb2Nlc3NvciwgYW5kCi0gICAqIHdlIHdvdWxkIGhhdmUgdG8gc3VwcG9ydCBzb21lIGZvcm0gb2YgcGx1Zy1pbiByZXNvbHZlciB0byBoYW5kbGUKLSAgICogdGhpcyBwcm9wZXJseS4gQ3VycmVudGx5LCB3ZSBzaW1wbHkgcmV0dXJuIHRoZSBTeXN0ZW0gSWRlbnRpZmllciBpZgotICAgKiBwcmVzZW50LCBhbmQgaG9wZSB0aGF0IGl0IGEgdXNhYmxlIFVSSSBvciB0aGF0IG91ciBjYWxsZXIgY2FuCi0gICAqIG1hcCBpdCB0byBvbmUuCi0gICAqIFRPRE86IFJlc29sdmUgUHVibGljIElkZW50aWZpZXJzLi4uIG9yIGNvbnNpZGVyIGNoYW5naW5nIGZ1bmN0aW9uIG5hbWUuCi0gICAqIDxwPgotICAgKiBJZiB3ZSBmaW5kIGEgcmVsYXRpdmUgVVJJCi0gICAqIHJlZmVyZW5jZSwgWE1MIGV4cGVjdHMgaXQgdG8gYmUgcmVzb2x2ZWQgaW4gdGVybXMgb2YgdGhlIGJhc2UgVVJJCi0gICAqIG9mIHRoZSBkb2N1bWVudC4gVGhlIERPTSBkb2Vzbid0IGRvIHRoYXQgZm9yIHVzLCBhbmQgaXQgaXNuJ3QKLSAgICogZW50aXJlbHkgY2xlYXIgd2hldGhlciB0aGF0IHNob3VsZCBiZSBkb25lIGhlcmU7IGN1cnJlbnRseSB0aGF0J3MKLSAgICogcHVzaGVkIHVwIHRvIGEgaGlnaGVyIGxldmVsIG9mIG91ciBhcHBsaWNhdGlvbi4gKE5vdGUgdGhhdCBET00gTGV2ZWwKLSAgICogMSBkaWRuJ3Qgc3RvcmUgdGhlIGRvY3VtZW50J3MgYmFzZSBVUkkuKQotICAgKiBUT0RPOiBDb25zaWRlciByZXNvbHZpbmcgUmVsYXRpdmUgVVJJcy4KLSAgICogPHA+Ci0gICAqIChUaGUgRE9NJ3Mgc3RhdGVtZW50IHRoYXQgIkFuIFhNTCBwcm9jZXNzb3IgbWF5IGNob29zZSB0bwotICAgKiBjb21wbGV0ZWx5IGV4cGFuZCBlbnRpdGllcyBiZWZvcmUgdGhlIHN0cnVjdHVyZSBtb2RlbCBpcyBwYXNzZWQKLSAgICogdG8gdGhlIERPTSIgcmVmZXJzIG9ubHkgdG8gcGFyc2VkIGVudGl0aWVzLCBub3QgdW5wYXJzZWQsIGFuZCBoZW5jZQotICAgKiBkb2Vzbid0IGFmZmVjdCB0aGlzIGZ1bmN0aW9uLikKLSAgICoKLSAgICogQHBhcmFtIG5hbWUgQSBzdHJpbmcgY29udGFpbmluZyB0aGUgRW50aXR5IE5hbWUgb2YgdGhlIHVucGFyc2VkCi0gICAqIGVudGl0eS4KLSAgICoKLSAgICogQHJldHVybiBTdHJpbmcgY29udGFpbmluZyB0aGUgVVJJIG9mIHRoZSBVbnBhcnNlZCBFbnRpdHksIG9yIGFuCi0gICAqIGVtcHR5IHN0cmluZyBpZiBubyBzdWNoIGVudGl0eSBleGlzdHMuCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nIGdldFVucGFyc2VkRW50aXR5VVJJKFN0cmluZyBuYW1lKTsKLQotICAvLyA9PT09PT09PT09PT09PSBCb29sZWFuIG1ldGhvZHMgPT09PT09PT09PT09PT09PQotCi0gIC8qKgotICAgKiBSZXR1cm4gdHJ1ZSBpZiB0aGUgeHNsOnN0cmlwLXNwYWNlIG9yIHhzbDpwcmVzZXJ2ZS1zcGFjZSB3YXMgcHJvY2Vzc2VkCi0gICAqIGR1cmluZyBjb25zdHJ1Y3Rpb24gb2YgdGhlIERUTSBkb2N1bWVudC4KLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHRoaXMgRFRNIHN1cHBvcnRzIHByZXN0cmlwcGluZy4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIHN1cHBvcnRzUHJlU3RyaXBwaW5nKCkKLSAgewotICAgIHJldHVybiB0cnVlOwotICB9Ci0KLSAgLyoqCi0gICAqIEZpZ3VyZSBvdXQgd2hldGhlciBub2RlSGFuZGxlMiBzaG91bGQgYmUgY29uc2lkZXJlZCBhcyBiZWluZyBsYXRlcgotICAgKiBpbiB0aGUgZG9jdW1lbnQgdGhhbiBub2RlSGFuZGxlMSwgaW4gRG9jdW1lbnQgT3JkZXIgYXMgZGVmaW5lZAotICAgKiBieSB0aGUgWFBhdGggbW9kZWwuIFRoaXMgbWF5IG5vdCBhZ3JlZSB3aXRoIHRoZSBvcmRlcmluZyBkZWZpbmVkCi0gICAqIGJ5IG90aGVyIFhNTCBhcHBsaWNhdGlvbnMuCi0gICAqIDxwPgotICAgKiBUaGVyZSBhcmUgc29tZSBjYXNlcyB3aGVyZSBvcmRlcmluZyBpc24ndCBkZWZpbmVkLCBhbmQgbmVpdGhlciBhcmUKLSAgICogdGhlIHJlc3VsdHMgb2YgdGhpcyBmdW5jdGlvbiAtLSB0aG91Z2ggd2UnbGwgZ2VuZXJhbGx5IHJldHVybiBmYWxzZS4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUxIE5vZGUgaGFuZGxlIHRvIHBlcmZvcm0gcG9zaXRpb24gY29tcGFyaXNvbiBvbi4KLSAgICogQHBhcmFtIG5vZGVIYW5kbGUyIFNlY29uZCBOb2RlIGhhbmRsZSB0byBwZXJmb3JtIHBvc2l0aW9uIGNvbXBhcmlzb24gb24gLgotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYgbm9kZTEgY29tZXMgYmVmb3JlIG5vZGUyLCBvdGhlcndpc2UgcmV0dXJuIGZhbHNlLgotICAgKiBZb3UgY2FuIHRoaW5rIG9mIHRoaXMgYXMKLSAgICogPGNvZGU+KG5vZGUxLmRvY3VtZW50T3JkZXJQb3NpdGlvbiAmbHQ7PSBub2RlMi5kb2N1bWVudE9yZGVyUG9zaXRpb24pPC9jb2RlPi4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzTm9kZUFmdGVyKGludCBub2RlSGFuZGxlMSwgaW50IG5vZGVIYW5kbGUyKQotICB7Ci0gICAgICAgICAgICAgICAgLy8gVGhlc2UgcmV0dXJuIE5VTEwgaWYgdGhlIG5vZGUgZG9lc24ndCBiZWxvbmcgdG8gdGhpcyBkb2N1bWVudC4KLSAgICBpbnQgaW5kZXgxID0gbWFrZU5vZGVJZGVudGl0eShub2RlSGFuZGxlMSk7Ci0gICAgaW50IGluZGV4MiA9IG1ha2VOb2RlSWRlbnRpdHkobm9kZUhhbmRsZTIpOwotCi0gICAgcmV0dXJuIGluZGV4MSE9TlVMTCAmJiBpbmRleDIhPU5VTEwgJiYgaW5kZXgxIDw9IGluZGV4MjsKLSAgfQotCi0gIC8qKgotICAgKiAgICAgMi4gW2VsZW1lbnQgY29udGVudCB3aGl0ZXNwYWNlXSBBIGJvb2xlYW4gaW5kaWNhdGluZyB3aGV0aGVyIHRoZQotICAgKiAgICAgICAgY2hhcmFjdGVyIGlzIHdoaXRlIHNwYWNlIGFwcGVhcmluZyB3aXRoaW4gZWxlbWVudCBjb250ZW50IChzZWUgW1hNTF0sCi0gICAqICAgICAgICAyLjEwICJXaGl0ZSBTcGFjZSBIYW5kbGluZyIpLiBOb3RlIHRoYXQgdmFsaWRhdGluZyBYTUwgcHJvY2Vzc29ycyBhcmUKLSAgICogICAgICAgIHJlcXVpcmVkIGJ5IFhNTCAxLjAgdG8gcHJvdmlkZSB0aGlzIGluZm9ybWF0aW9uLiBJZiB0aGVyZSBpcyBubwotICAgKiAgICAgICAgZGVjbGFyYXRpb24gZm9yIHRoZSBjb250YWluaW5nIGVsZW1lbnQsIHRoaXMgcHJvcGVydHkgaGFzIG5vIHZhbHVlIGZvcgotICAgKiAgICAgICAgd2hpdGUgc3BhY2UgY2hhcmFjdGVycy4gSWYgbm8gZGVjbGFyYXRpb24gaGFzIGJlZW4gcmVhZCwgYnV0IHRoZSBbYWxsCi0gICAqICAgICAgICBkZWNsYXJhdGlvbnMgcHJvY2Vzc2VkXSBwcm9wZXJ0eSBvZiB0aGUgZG9jdW1lbnQgaW5mb3JtYXRpb24gaXRlbSBpcwotICAgKiAgICAgICAgZmFsc2UgKHNvIHRoZXJlIG1heSBiZSBhbiB1bnJlYWQgZGVjbGFyYXRpb24pLCB0aGVuIHRoZSB2YWx1ZSBvZiB0aGlzCi0gICAqICAgICAgICBwcm9wZXJ0eSBpcyB1bmtub3duIGZvciB3aGl0ZSBzcGFjZSBjaGFyYWN0ZXJzLiBJdCBpcyBhbHdheXMgZmFsc2UgZm9yCi0gICAqICAgICAgICBjaGFyYWN0ZXJzIHRoYXQgYXJlIG5vdCB3aGl0ZSBzcGFjZS4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgdGhlIG5vZGUgSUQuCi0gICAqIEByZXR1cm4gPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIGNoYXJhY3RlciBkYXRhIGlzIHdoaXRlc3BhY2U7Ci0gICAqICAgICAgICAgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzQ2hhcmFjdGVyRWxlbWVudENvbnRlbnRXaGl0ZXNwYWNlKGludCBub2RlSGFuZGxlKQotICB7Ci0KLSAgICAvLyAlVEJEJQotICAgIHJldHVybiBmYWxzZTsKLSAgfQotCi0gIC8qKgotICAgKiAgICAxMC4gW2FsbCBkZWNsYXJhdGlvbnMgcHJvY2Vzc2VkXSBUaGlzIHByb3BlcnR5IGlzIG5vdCBzdHJpY3RseSBzcGVha2luZwotICAgKiAgICAgICAgcGFydCBvZiB0aGUgaW5mb3NldCBvZiB0aGUgZG9jdW1lbnQuIFJhdGhlciBpdCBpcyBhbiBpbmRpY2F0aW9uIG9mCi0gICAqICAgICAgICB3aGV0aGVyIHRoZSBwcm9jZXNzb3IgaGFzIHJlYWQgdGhlIGNvbXBsZXRlIERURC4gSXRzIHZhbHVlIGlzIGEKLSAgICogICAgICAgIGJvb2xlYW4uIElmIGl0IGlzIGZhbHNlLCB0aGVuIGNlcnRhaW4gcHJvcGVydGllcyAoaW5kaWNhdGVkIGluIHRoZWlyCi0gICAqICAgICAgICBkZXNjcmlwdGlvbnMgYmVsb3cpIG1heSBiZSB1bmtub3duLiBJZiBpdCBpcyB0cnVlLCB0aG9zZSBwcm9wZXJ0aWVzCi0gICAqICAgICAgICBhcmUgbmV2ZXIgdW5rbm93bi4KLSAgICoKLSAgICogQHBhcmFtIGRvY3VtZW50SGFuZGxlIEEgbm9kZSBoYW5kbGUgdGhhdCBtdXN0IGlkZW50aWZ5IGEgZG9jdW1lbnQuCi0gICAqIEByZXR1cm4gPGNvZGU+dHJ1ZTwvY29kZT4gaWYgYWxsIGRlY2xhcmF0aW9ucyB3ZXJlIHByb2Nlc3NlZDsKLSAgICogICAgICAgICA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNEb2N1bWVudEFsbERlY2xhcmF0aW9uc1Byb2Nlc3NlZChpbnQgZG9jdW1lbnRIYW5kbGUpCi0gIHsKLSAgICByZXR1cm4gdHJ1ZTsKLSAgfQotCi0gIC8qKgotICAgKiAgICAgNS4gW3NwZWNpZmllZF0gQSBmbGFnIGluZGljYXRpbmcgd2hldGhlciB0aGlzIGF0dHJpYnV0ZSB3YXMgYWN0dWFsbHkKLSAgICogICAgICAgIHNwZWNpZmllZCBpbiB0aGUgc3RhcnQtdGFnIG9mIGl0cyBlbGVtZW50LCBvciB3YXMgZGVmYXVsdGVkIGZyb20gdGhlCi0gICAqICAgICAgICBEVEQuCi0gICAqCi0gICAqIEBwYXJhbSBhdHRyaWJ1dGVIYW5kbGUgVGhlIGF0dHJpYnV0ZSBoYW5kbGUgaW4gcXVlc3Rpb24uCi0gICAqCi0gICAqIEByZXR1cm4gPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIGF0dHJpYnV0ZSB3YXMgc3BlY2lmaWVkOwotICAgKiAgICAgICAgIDxjb2RlPmZhbHNlPC9jb2RlPiBpZiBpdCB3YXMgZGVmYXVsdGVkLgotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gaXNBdHRyaWJ1dGVTcGVjaWZpZWQoaW50IGF0dHJpYnV0ZUhhbmRsZSk7Ci0KLSAgLy8gPT09PT09PT09PSBEaXJlY3QgU0FYIERpc3BhdGNoLCBmb3Igb3B0aW1pemF0aW9uIHB1cnBvc2VzID09PT09PT09Ci0KLSAgLyoqCi0gICAqIERpcmVjdGx5IGNhbGwgdGhlCi0gICAqIGNoYXJhY3RlcnMgbWV0aG9kIG9uIHRoZSBwYXNzZWQgQ29udGVudEhhbmRsZXIgZm9yIHRoZQotICAgKiBzdHJpbmctdmFsdWUgb2YgdGhlIGdpdmVuIG5vZGUgKHNlZSBodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aCNkYXRhLW1vZGVsCi0gICAqIGZvciB0aGUgZGVmaW5pdGlvbiBvZiBhIG5vZGUncyBzdHJpbmctdmFsdWUpLiBNdWx0aXBsZSBjYWxscyB0byB0aGUKLSAgICogQ29udGVudEhhbmRsZXIncyBjaGFyYWN0ZXJzIG1ldGhvZHMgbWF5IHdlbGwgb2NjdXIgZm9yIGEgc2luZ2xlIGNhbGwgdG8KLSAgICogdGhpcyBtZXRob2QuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIFRoZSBub2RlIElELgotICAgKiBAcGFyYW0gY2ggQSBub24tbnVsbCByZWZlcmVuY2UgdG8gYSBDb250ZW50SGFuZGxlci4KLSAgICogQHBhcmFtIG5vcm1hbGl6ZSB0cnVlIGlmIHRoZSBjb250ZW50IHNob3VsZCBiZSBub3JtYWxpemVkIGFjY29yZGluZyB0bwotICAgKiB0aGUgcnVsZXMgZm9yIHRoZSBYUGF0aAotICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aCNmdW5jdGlvbi1ub3JtYWxpemUtc3BhY2UiPm5vcm1hbGl6ZS1zcGFjZTwvYT4KLSAgICogZnVuY3Rpb24uCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBkaXNwYXRjaENoYXJhY3RlcnNFdmVudHMoCi0gICAgaW50IG5vZGVIYW5kbGUsIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyIGNoLCBib29sZWFuIG5vcm1hbGl6ZSkKLSAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci0KLSAgLyoqCi0gICAqIERpcmVjdGx5IGNyZWF0ZSBTQVggcGFyc2VyIGV2ZW50cyBmcm9tIGEgc3VidHJlZS4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgVGhlIG5vZGUgSUQuCi0gICAqIEBwYXJhbSBjaCBBIG5vbi1udWxsIHJlZmVyZW5jZSB0byBhIENvbnRlbnRIYW5kbGVyLgotICAgKgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IHZvaWQgZGlzcGF0Y2hUb0V2ZW50cygKLSAgICBpbnQgbm9kZUhhbmRsZSwgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIgY2gpCi0gICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotCi0gIC8qKgotICAgKiBSZXR1cm4gYW4gRE9NIG5vZGUgZm9yIHRoZSBnaXZlbiBub2RlLgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBUaGUgbm9kZSBJRC4KLSAgICoKLSAgICogQHJldHVybiBBIG5vZGUgcmVwcmVzZW50YXRpb24gb2YgdGhlIERUTSBub2RlLgotICAgKi8KLSAgcHVibGljIG9yZy53M2MuZG9tLk5vZGUgZ2V0Tm9kZShpbnQgbm9kZUhhbmRsZSkKLSAgewotICAgIHJldHVybiBuZXcgRFRNTm9kZVByb3h5KHRoaXMsIG5vZGVIYW5kbGUpOwotICB9Ci0KLSAgLy8gPT09PSBDb25zdHJ1Y3Rpb24gbWV0aG9kcyAobWF5IG5vdCBiZSBzdXBwb3J0ZWQgYnkgc29tZSBpbXBsZW1lbnRhdGlvbnMhKSA9PT09PQotCi0gIC8qKgotICAgKiBBcHBlbmQgYSBjaGlsZCB0byB0aGUgZW5kIG9mIHRoZSBkb2N1bWVudC4gUGxlYXNlIG5vdGUgdGhhdCB0aGUgbm9kZQotICAgKiBpcyBhbHdheXMgY2xvbmVkIGlmIGl0IGlzIG93bmVkIGJ5IGFub3RoZXIgZG9jdW1lbnQuCi0gICAqCi0gICAqIDxwPiVSRVZJRVclICJFbmQgb2YgdGhlIGRvY3VtZW50IiBuZWVkcyB0byBiZSBkZWZpbmVkIG1vcmUgY2xlYXJseS4KLSAgICogRG9lcyBpdCBiZWNvbWUgdGhlIGxhc3QgY2hpbGQgb2YgdGhlIERvY3VtZW50PyBPZiB0aGUgcm9vdCBlbGVtZW50PzwvcD4KLSAgICoKLSAgICogQHBhcmFtIG5ld0NoaWxkIE11c3QgYmUgYSB2YWxpZCBuZXcgbm9kZSBoYW5kbGUuCi0gICAqIEBwYXJhbSBjbG9uZSB0cnVlIGlmIHRoZSBjaGlsZCBzaG91bGQgYmUgY2xvbmVkIGludG8gdGhlIGRvY3VtZW50LgotICAgKiBAcGFyYW0gY2xvbmVEZXB0aCBpZiB0aGUgY2xvbmUgYXJndW1lbnQgaXMgdHJ1ZSwgc3BlY2lmaWVzIHRoYXQgdGhlCi0gICAqICAgICAgICAgICAgICAgICAgIGNsb25lIHNob3VsZCBpbmNsdWRlIGFsbCBpdCdzIGNoaWxkcmVuLgotICAgKi8KLSAgcHVibGljIHZvaWQgYXBwZW5kQ2hpbGQoaW50IG5ld0NoaWxkLCBib29sZWFuIGNsb25lLCBib29sZWFuIGNsb25lRGVwdGgpCi0gIHsKLSAgICBlcnJvcihYTUxNZXNzYWdlcy5jcmVhdGVYTUxNZXNzYWdlKFhNTEVycm9yUmVzb3VyY2VzLkVSX01FVEhPRF9OT1RfU1VQUE9SVEVELCBudWxsKSk7Ly8iYXBwZW5kQ2hpbGQgbm90IHlldCBzdXBwb3J0ZWQhIik7Ci0gIH0KLQotICAvKioKLSAgICogQXBwZW5kIGEgdGV4dCBub2RlIGNoaWxkIHRoYXQgd2lsbCBiZSBjb25zdHJ1Y3RlZCBmcm9tIGEgc3RyaW5nLAotICAgKiB0byB0aGUgZW5kIG9mIHRoZSBkb2N1bWVudC4KLSAgICoKLSAgICogPHA+JVJFVklFVyUgIkVuZCBvZiB0aGUgZG9jdW1lbnQiIG5lZWRzIHRvIGJlIGRlZmluZWQgbW9yZSBjbGVhcmx5LgotICAgKiBEb2VzIGl0IGJlY29tZSB0aGUgbGFzdCBjaGlsZCBvZiB0aGUgRG9jdW1lbnQ/IE9mIHRoZSByb290IGVsZW1lbnQ/PC9wPgotICAgKgotICAgKiBAcGFyYW0gc3RyIE5vbi1udWxsIHJldmVyZW5jZSB0byBhIHN0cmluZy4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGFwcGVuZFRleHRDaGlsZChTdHJpbmcgc3RyKQotICB7Ci0gICAgZXJyb3IoWE1MTWVzc2FnZXMuY3JlYXRlWE1MTWVzc2FnZShYTUxFcnJvclJlc291cmNlcy5FUl9NRVRIT0RfTk9UX1NVUFBPUlRFRCwgbnVsbCkpOy8vImFwcGVuZFRleHRDaGlsZCBub3QgeWV0IHN1cHBvcnRlZCEiKTsKLSAgfQotCi0gIC8qKgotICAgKiBTaW1wbGUgZXJyb3IgZm9yIGFzc2VydHMgYW5kIHRoZSBsaWtlLgotICAgKgotICAgKiBAcGFyYW0gbXNnIEVycm9yIG1lc3NhZ2UgdG8gcmVwb3J0LgotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgZXJyb3IoU3RyaW5nIG1zZykKLSAgewotICAgIHRocm93IG5ldyBEVE1FeGNlcHRpb24obXNnKTsKLSAgfQotCi0gIC8qKgotICAgKiBGaW5kIG91dCB3aGV0aGVyIG9yIG5vdCB0byBzdHJpcCB3aGlzcGFjZSBub2Rlcy4KLSAgICoKLSAgICoKLSAgICogQHJldHVybiB3aGV0aGVyIG9yIG5vdCB0byBzdHJpcCB3aGlzcGFjZSBub2Rlcy4KLSAgICovCi0gIHByb3RlY3RlZCBib29sZWFuIGdldFNob3VsZFN0cmlwV2hpdGVzcGFjZSgpCi0gIHsKLSAgICByZXR1cm4gbV9zaG91bGRTdHJpcFdTOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB3aGV0aGVyIHRvIHN0cmlwIHdoaXRlc3BhY2VzIGFuZCBwdXNoIGluIGN1cnJlbnQgdmFsdWUgb2YKLSAgICogbV9zaG91bGRTdHJpcFdTIGluIG1fc2hvdWxkU3RyaXBXaGl0ZXNwYWNlU3RhY2suCi0gICAqCi0gICAqIEBwYXJhbSBzaG91bGRTdHJpcCBGbGFnIGluZGljYXRpbmcgd2hldGhlciB0byBzdHJpcCB3aGl0ZXNwYWNlIG5vZGVzCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBwdXNoU2hvdWxkU3RyaXBXaGl0ZXNwYWNlKGJvb2xlYW4gc2hvdWxkU3RyaXApCi0gIHsKLQotICAgIG1fc2hvdWxkU3RyaXBXUyA9IHNob3VsZFN0cmlwOwotCi0gICAgaWYgKG51bGwgIT0gbV9zaG91bGRTdHJpcFdoaXRlc3BhY2VTdGFjaykKLSAgICAgIG1fc2hvdWxkU3RyaXBXaGl0ZXNwYWNlU3RhY2sucHVzaChzaG91bGRTdHJpcCk7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHdoZXRoZXIgdG8gc3RyaXAgd2hpdGVzcGFjZXMgYXQgdGhpcyBwb2ludCBieSBwb3BwaW5nIG91dAotICAgKiBtX3Nob3VsZFN0cmlwV2hpdGVzcGFjZVN0YWNrLgotICAgKgotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgcG9wU2hvdWxkU3RyaXBXaGl0ZXNwYWNlKCkKLSAgewotICAgIGlmIChudWxsICE9IG1fc2hvdWxkU3RyaXBXaGl0ZXNwYWNlU3RhY2spCi0gICAgICBtX3Nob3VsZFN0cmlwV1MgPSBtX3Nob3VsZFN0cmlwV2hpdGVzcGFjZVN0YWNrLnBvcEFuZFRvcCgpOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB3aGV0aGVyIHRvIHN0cmlwIHdoaXRlc3BhY2VzIGFuZCBzZXQgdGhlIHRvcCBvZiB0aGUgc3RhY2sgdG8KLSAgICogdGhlIGN1cnJlbnQgdmFsdWUgb2YgbV9zaG91bGRTdHJpcFdTLgotICAgKgotICAgKgotICAgKiBAcGFyYW0gc2hvdWxkU3RyaXAgRmxhZyBpbmRpY2F0aW5nIHdoZXRoZXIgdG8gc3RyaXAgd2hpdGVzcGFjZSBub2RlcwotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgc2V0U2hvdWxkU3RyaXBXaGl0ZXNwYWNlKGJvb2xlYW4gc2hvdWxkU3RyaXApCi0gIHsKLQotICAgIG1fc2hvdWxkU3RyaXBXUyA9IHNob3VsZFN0cmlwOwotCi0gICAgaWYgKG51bGwgIT0gbV9zaG91bGRTdHJpcFdoaXRlc3BhY2VTdGFjaykKLSAgICAgIG1fc2hvdWxkU3RyaXBXaGl0ZXNwYWNlU3RhY2suc2V0VG9wKHNob3VsZFN0cmlwKTsKLSAgfQotCi0gIC8qKgotICAgKiBBIGR1bW15IHJvdXRpbmUgdG8gc2F0aXNpZnkgdGhlIGFic3RyYWN0IGludGVyZmFjZS4gSWYgdGhlIERUTQotICAgKiBpbXBsZW1lbXRhdGlvbiB0aGF0IGV4dGVuZHMgdGhlIGRlZmF1bHQgYmFzZSByZXF1aXJlcyBub3RpZmljYXRpb24KLSAgICogb2YgcmVnaXN0cmF0aW9uLCB0aGV5IGNhbiBvdmVycmlkZSB0aGlzIG1ldGhvZC4KLSAgICovCi0gICBwdWJsaWMgdm9pZCBkb2N1bWVudFJlZ2lzdHJhdGlvbigpCi0gICB7Ci0gICB9Ci0KLSAgLyoqCi0gICAqIEEgZHVtbXkgcm91dGluZSB0byBzYXRpc2lmeSB0aGUgYWJzdHJhY3QgaW50ZXJmYWNlLiBJZiB0aGUgRFRNCi0gICAqIGltcGxlbWVtdGF0aW9uIHRoYXQgZXh0ZW5kcyB0aGUgZGVmYXVsdCBiYXNlIHJlcXVpcmVzIG5vdGlmaWNhdGlvbgotICAgKiB3aGVuIHRoZSBkb2N1bWVudCBpcyBiZWluZyByZWxlYXNlZCwgdGhleSBjYW4gb3ZlcnJpZGUgdGhpcyBtZXRob2QKLSAgICovCi0gICBwdWJsaWMgdm9pZCBkb2N1bWVudFJlbGVhc2UoKQotICAgewotICAgfQotCi0gICAvKioKLSAgICAqIE1pZ3JhdGUgYSBEVE0gYnVpbHQgd2l0aCBhbiBvbGQgRFRNTWFuYWdlciB0byBhIG5ldyBEVE1NYW5hZ2VyLgotICAgICogQWZ0ZXIgdGhlIG1pZ3JhdGlvbiwgdGhlIG5ldyBEVE1NYW5hZ2VyIHdpbGwgdHJlYXQgdGhlIERUTSBhcwotICAgICogb25lIHRoYXQgaXMgYnVpbHQgYnkgaXRzZWxmLgotICAgICogVGhpcyBpcyB1c2VkIHRvIHN1cHBvcnQgRFRNIHNoYXJpbmcgYmV0d2VlbiBtdWx0aXBsZSB0cmFuc2Zvcm1hdGlvbnMuCi0gICAgKiBAcGFyYW0gbWdyIHRoZSBEVE1NYW5hZ2VyCi0gICAgKi8KLSAgIHB1YmxpYyB2b2lkIG1pZ3JhdGVUbyhEVE1NYW5hZ2VyIG1ncikKLSAgIHsKLSAgICAgbV9tZ3IgPSBtZ3I7Ci0gICAgIGlmKG1nciBpbnN0YW5jZW9mIERUTU1hbmFnZXJEZWZhdWx0KQotICAgICAgIG1fbWdyRGVmYXVsdD0oRFRNTWFuYWdlckRlZmF1bHQpbWdyOwotICAgfQotCi0gICAgICAgICAvKiogUXVlcnkgd2hpY2ggRFRNTWFuYWdlciB0aGlzIERUTSBpcyBjdXJyZW50bHkgYmVpbmcgaGFuZGxlZCBieS4KLSAgICAgICAgICAqCi0gICAgICAgICAgKiAlUkVWRVclIFNob3VsZCB0aGlzIGJlY29tZSBwYXJ0IG9mIHRoZSBiYXNlIERUTSBBUEk/Ci0gICAgICAgICAgKgotICAgICAgICAgICogQHJldHVybiBhIERUTU1hbmFnZXIsIG9yIG51bGwgaWYgdGhpcyBpcyBhICJzdGFuZC1hbG9uZSIgRFRNLgotICAgICAgICAgICovCi0gICAgICAgICBwdWJsaWMgRFRNTWFuYWdlciBnZXRNYW5hZ2VyKCkKLSAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgcmV0dXJuIG1fbWdyOwotICAgICAgICAgfQotCi0gICAgICAgICAvKiogUXVlcnkgd2hpY2ggRFRNSURzIHRoaXMgRFRNIGlzIGN1cnJlbnRseSB1c2luZyB3aXRoaW4gdGhlIERUTU1hbmFnZXIuCi0gICAgICAgICAgKgotICAgICAgICAgICogJVJFVkVXJSBTaG91bGQgdGhpcyBiZWNvbWUgcGFydCBvZiB0aGUgYmFzZSBEVE0gQVBJPwotICAgICAgICAgICoKLSAgICAgICAgICAqIEByZXR1cm4gYW4gSW50VmVjdG9yLCBvciBudWxsIGlmIHRoaXMgaXMgYSAic3RhbmQtYWxvbmUiIERUTS4KLSAgICAgICAgICAqLwotICAgICAgICAgcHVibGljIFN1YmFsbG9jYXRlZEludFZlY3RvciBnZXREVE1JRHMoKQotICAgICAgICAgewotICAgICAgICAgICAgICAgICBpZihtX21ncj09bnVsbCkgcmV0dXJuIG51bGw7Ci0gICAgICAgICAgICAgICAgIHJldHVybiBtX2R0bUlkZW50OwotICAgICAgICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL3JlZi9EVE1EZWZhdWx0QmFzZUl0ZXJhdG9ycy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL3JlZi9EVE1EZWZhdWx0QmFzZUl0ZXJhdG9ycy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzMWMwNTljLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9yZWYvRFRNRGVmYXVsdEJhc2VJdGVyYXRvcnMuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIxOTUgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRFRNRGVmYXVsdEJhc2VJdGVyYXRvcnMuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNSAwODoxNTowMCBzdXJlc2hfZW1haWxpZCBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLnJlZjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLio7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlNvdXJjZTsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuWE1MU3RyaW5nRmFjdG9yeTsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzLlhNTEVycm9yUmVzb3VyY2VzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzLlhNTE1lc3NhZ2VzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5kb20uTm9kZUNvdW50ZXI7Ci0KLS8qKgotICogVGhpcyBjbGFzcyBpbXBsZW1lbnRzIHRoZSB0cmF2ZXJzZXJzIGZvciBEVE1EZWZhdWx0QmFzZS4KLSAqLwotcHVibGljIGFic3RyYWN0IGNsYXNzIERUTURlZmF1bHRCYXNlSXRlcmF0b3JzIGV4dGVuZHMgRFRNRGVmYXVsdEJhc2VUcmF2ZXJzZXJzCi17Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhIERUTURlZmF1bHRCYXNlVHJhdmVyc2VycyBvYmplY3QgZnJvbSBhIERPTSBub2RlLgotICAgKgotICAgKiBAcGFyYW0gbWdyIFRoZSBEVE1NYW5hZ2VyIHdobyBvd25zIHRoaXMgRFRNLgotICAgKiBAcGFyYW0gc291cmNlIFRoZSBvYmplY3QgdGhhdCBpcyB1c2VkIHRvIHNwZWNpZnkgdGhlIGNvbnN0cnVjdGlvbiBzb3VyY2UuCi0gICAqIEBwYXJhbSBkdG1JZGVudGl0eSBUaGUgRFRNIGlkZW50aXR5IElEIGZvciB0aGlzIERUTS4KLSAgICogQHBhcmFtIHdoaXRlU3BhY2VGaWx0ZXIgVGhlIHdoaXRlIHNwYWNlIGZpbHRlciBmb3IgdGhpcyBEVE0sIHdoaWNoIG1heQotICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBiZSBudWxsLgotICAgKiBAcGFyYW0geHN0cmluZ2ZhY3RvcnkgVGhlIGZhY3RvcnkgdG8gdXNlIGZvciBjcmVhdGluZyBYTUxTdHJpbmdzLgotICAgKiBAcGFyYW0gZG9JbmRleGluZyB0cnVlIGlmIHRoZSBjYWxsZXIgY29uc2lkZXJzIGl0IHdvcnRoIGl0IHRvIHVzZQotICAgKiAgICAgICAgICAgICAgICAgICBpbmRleGluZyBzY2hlbWVzLgotICAgKi8KLSAgcHVibGljIERUTURlZmF1bHRCYXNlSXRlcmF0b3JzKERUTU1hbmFnZXIgbWdyLCBTb3VyY2Ugc291cmNlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGR0bUlkZW50aXR5LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFRNV1NGaWx0ZXIgd2hpdGVTcGFjZUZpbHRlciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTFN0cmluZ0ZhY3RvcnkgeHN0cmluZ2ZhY3RvcnksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGRvSW5kZXhpbmcpCi0gIHsKLSAgICBzdXBlcihtZ3IsIHNvdXJjZSwgZHRtSWRlbnRpdHksIHdoaXRlU3BhY2VGaWx0ZXIsCi0gICAgICAgICAgeHN0cmluZ2ZhY3RvcnksIGRvSW5kZXhpbmcpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhIERUTURlZmF1bHRCYXNlVHJhdmVyc2VycyBvYmplY3QgZnJvbSBhIERPTSBub2RlLgotICAgKgotICAgKiBAcGFyYW0gbWdyIFRoZSBEVE1NYW5hZ2VyIHdobyBvd25zIHRoaXMgRFRNLgotICAgKiBAcGFyYW0gc291cmNlIFRoZSBvYmplY3QgdGhhdCBpcyB1c2VkIHRvIHNwZWNpZnkgdGhlIGNvbnN0cnVjdGlvbiBzb3VyY2UuCi0gICAqIEBwYXJhbSBkdG1JZGVudGl0eSBUaGUgRFRNIGlkZW50aXR5IElEIGZvciB0aGlzIERUTS4KLSAgICogQHBhcmFtIHdoaXRlU3BhY2VGaWx0ZXIgVGhlIHdoaXRlIHNwYWNlIGZpbHRlciBmb3IgdGhpcyBEVE0sIHdoaWNoIG1heQotICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBiZSBudWxsLgotICAgKiBAcGFyYW0geHN0cmluZ2ZhY3RvcnkgVGhlIGZhY3RvcnkgdG8gdXNlIGZvciBjcmVhdGluZyBYTUxTdHJpbmdzLgotICAgKiBAcGFyYW0gZG9JbmRleGluZyB0cnVlIGlmIHRoZSBjYWxsZXIgY29uc2lkZXJzIGl0IHdvcnRoIGl0IHRvIHVzZQotICAgKiAgICAgICAgICAgICAgICAgICBpbmRleGluZyBzY2hlbWVzLgotICAgKiBAcGFyYW0gYmxvY2tzaXplIFRoZSBibG9jayBzaXplIG9mIHRoZSBEVE0uCi0gICAqIEBwYXJhbSB1c2VQcmV2c2liIHRydWUgaWYgd2Ugd2FudCB0byBidWlsZCB0aGUgcHJldmlvdXMgc2libGluZyBub2RlIGFycmF5LgotICAgKiBAcGFyYW0gbmV3TmFtZVRhYmxlIHRydWUgaWYgd2Ugd2FudCB0byB1c2UgYSBuZXcgRXhwYW5kZWROYW1lVGFibGUgZm9yIHRoaXMgRFRNLgotICAgKi8KLSAgcHVibGljIERUTURlZmF1bHRCYXNlSXRlcmF0b3JzKERUTU1hbmFnZXIgbWdyLCBTb3VyY2Ugc291cmNlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGR0bUlkZW50aXR5LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFRNV1NGaWx0ZXIgd2hpdGVTcGFjZUZpbHRlciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTFN0cmluZ0ZhY3RvcnkgeHN0cmluZ2ZhY3RvcnksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGRvSW5kZXhpbmcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgYmxvY2tzaXplLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiB1c2VQcmV2c2liLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBuZXdOYW1lVGFibGUpCi0gIHsKLSAgICBzdXBlcihtZ3IsIHNvdXJjZSwgZHRtSWRlbnRpdHksIHdoaXRlU3BhY2VGaWx0ZXIsCi0gICAgICAgICAgeHN0cmluZ2ZhY3RvcnksIGRvSW5kZXhpbmcsIGJsb2Nrc2l6ZSwgdXNlUHJldnNpYiwgbmV3TmFtZVRhYmxlKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgYW4gaXRlcmF0b3IgdGhhdCBjYW4gbmF2aWdhdGUgb3ZlciBhbiBYUGF0aCBBeGlzLCBwcmVkaWNhdGVkIGJ5Ci0gICAqIHRoZSBleHRlbmRlZCB0eXBlIElELgotICAgKiBSZXR1cm5zIGFuIGl0ZXJhdG9yIHRoYXQgbXVzdCBiZSBpbml0aWFsaXplZAotICAgKiB3aXRoIGEgc3RhcnQgbm9kZSAodXNpbmcgaXRlcmF0b3Iuc2V0U3RhcnROb2RlKCkpLgotICAgKgotICAgKiBAcGFyYW0gYXhpcyBPbmUgb2YgQXhlcy5BTkNFU1RPUk9SU0VMRiwgZXRjLgotICAgKiBAcGFyYW0gdHlwZSBBbiBleHRlbmRlZCB0eXBlIElELgotICAgKgotICAgKiBAcmV0dXJuIEEgRFRNQXhpc0l0ZXJhdG9yLCBvciBudWxsIGlmIHRoZSBnaXZlbiBheGlzIGlzbid0IHN1cHBvcnRlZC4KLSAgICovCi0gIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3IgZ2V0VHlwZWRBeGlzSXRlcmF0b3IoaW50IGF4aXMsIGludCB0eXBlKQotICB7Ci0KLSAgICBEVE1BeGlzSXRlcmF0b3IgaXRlcmF0b3IgPSBudWxsOwotCi0gICAgLyogVGhpcyBjYXVzZXMgYW4gZXJyb3Igd2hlbiB1c2luZyBwYXR0ZXJucyBmb3IgZWxlbWVudHMgdGhhdAotICAgICAgIGRvIG5vdCBleGlzdCBpbiB0aGUgRE9NICh0cmFuc2xldCB0eXBlcyB3aGljaCBkbyBub3QgY29ycmVzcG9uZAotICAgICAgIHRvIGEgRE9NIHR5cGUgYXJlIG1hcHBlZCB0byB0aGUgRE9NLkVMRU1FTlQgdHlwZSkuCi0gICAgKi8KLQotICAgIC8vICAgICAgICBpZiAodHlwZSA9PSBOT19UWVBFKSB7Ci0gICAgLy8gICAgICAgICAgICByZXR1cm4oRU1QVFlJVEVSQVRPUik7Ci0gICAgLy8gICAgICAgIH0KLSAgICAvLyAgICAgICAgZWxzZSBpZiAodHlwZSA9PSBFTEVNRU5UKSB7Ci0gICAgLy8gICAgICAgICAgICBpdGVyYXRvciA9IG5ldyBGaWx0ZXJJdGVyYXRvcihnZXRBeGlzSXRlcmF0b3IoYXhpcyksCi0gICAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRFbGVtZW50RmlsdGVyKCkpOwotICAgIC8vICAgICAgICB9Ci0gICAgLy8gICAgICAgIGVsc2UKLSAgICB7Ci0gICAgICBzd2l0Y2ggKGF4aXMpCi0gICAgICB7Ci0gICAgICBjYXNlIEF4aXMuU0VMRiA6Ci0gICAgICAgIGl0ZXJhdG9yID0gbmV3IFR5cGVkU2luZ2xldG9uSXRlcmF0b3IodHlwZSk7Ci0gICAgICAgIGJyZWFrOwotICAgICAgY2FzZSBBeGlzLkNISUxEIDoKLSAgICAgICAgaXRlcmF0b3IgPSBuZXcgVHlwZWRDaGlsZHJlbkl0ZXJhdG9yKHR5cGUpOwotICAgICAgICBicmVhazsKLSAgICAgIGNhc2UgQXhpcy5QQVJFTlQgOgotICAgICAgICByZXR1cm4gKG5ldyBQYXJlbnRJdGVyYXRvcigpLnNldE5vZGVUeXBlKHR5cGUpKTsKLSAgICAgIGNhc2UgQXhpcy5BTkNFU1RPUiA6Ci0gICAgICAgIHJldHVybiAobmV3IFR5cGVkQW5jZXN0b3JJdGVyYXRvcih0eXBlKSk7Ci0gICAgICBjYXNlIEF4aXMuQU5DRVNUT1JPUlNFTEYgOgotICAgICAgICByZXR1cm4gKChuZXcgVHlwZWRBbmNlc3Rvckl0ZXJhdG9yKHR5cGUpKS5pbmNsdWRlU2VsZigpKTsKLSAgICAgIGNhc2UgQXhpcy5BVFRSSUJVVEUgOgotICAgICAgICByZXR1cm4gKG5ldyBUeXBlZEF0dHJpYnV0ZUl0ZXJhdG9yKHR5cGUpKTsKLSAgICAgIGNhc2UgQXhpcy5ERVNDRU5EQU5UIDoKLSAgICAgICAgaXRlcmF0b3IgPSBuZXcgVHlwZWREZXNjZW5kYW50SXRlcmF0b3IodHlwZSk7Ci0gICAgICAgIGJyZWFrOwotICAgICAgY2FzZSBBeGlzLkRFU0NFTkRBTlRPUlNFTEYgOgotICAgICAgICBpdGVyYXRvciA9IChuZXcgVHlwZWREZXNjZW5kYW50SXRlcmF0b3IodHlwZSkpLmluY2x1ZGVTZWxmKCk7Ci0gICAgICAgIGJyZWFrOwotICAgICAgY2FzZSBBeGlzLkZPTExPV0lORyA6Ci0gICAgICAgIGl0ZXJhdG9yID0gbmV3IFR5cGVkRm9sbG93aW5nSXRlcmF0b3IodHlwZSk7Ci0gICAgICAgIGJyZWFrOwotICAgICAgY2FzZSBBeGlzLlBSRUNFRElORyA6Ci0gICAgICAgIGl0ZXJhdG9yID0gbmV3IFR5cGVkUHJlY2VkaW5nSXRlcmF0b3IodHlwZSk7Ci0gICAgICAgIGJyZWFrOwotICAgICAgY2FzZSBBeGlzLkZPTExPV0lOR1NJQkxJTkcgOgotICAgICAgICBpdGVyYXRvciA9IG5ldyBUeXBlZEZvbGxvd2luZ1NpYmxpbmdJdGVyYXRvcih0eXBlKTsKLSAgICAgICAgYnJlYWs7Ci0gICAgICBjYXNlIEF4aXMuUFJFQ0VESU5HU0lCTElORyA6Ci0gICAgICAgIGl0ZXJhdG9yID0gbmV3IFR5cGVkUHJlY2VkaW5nU2libGluZ0l0ZXJhdG9yKHR5cGUpOwotICAgICAgICBicmVhazsKLSAgICAgIGNhc2UgQXhpcy5OQU1FU1BBQ0UgOgotICAgICAgICBpdGVyYXRvciA9IG5ldyBUeXBlZE5hbWVzcGFjZUl0ZXJhdG9yKHR5cGUpOwotICAgICAgICBicmVhazsKLSAgICAgIGNhc2UgQXhpcy5ST09UIDoKLSAgICAgICAgaXRlcmF0b3IgPSBuZXcgVHlwZWRSb290SXRlcmF0b3IodHlwZSk7Ci0gICAgICAgIGJyZWFrOwotICAgICAgZGVmYXVsdCA6Ci0gICAgICAgIHRocm93IG5ldyBEVE1FeGNlcHRpb24oWE1MTWVzc2FnZXMuY3JlYXRlWE1MTWVzc2FnZSgKLSAgICAgICAgICAgIFhNTEVycm9yUmVzb3VyY2VzLkVSX1RZUEVEX0lURVJBVE9SX0FYSVNfTk9UX0lNUExFTUVOVEVELAotICAgICAgICAgICAgbmV3IE9iamVjdFtde0F4aXMuZ2V0TmFtZXMoYXhpcyl9KSk7Ci0gICAgICAgICAgICAvLyJFcnJvcjogdHlwZWQgaXRlcmF0b3IgZm9yIGF4aXMgIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vKyBBeGlzLm5hbWVzW2F4aXNdICsgIm5vdCBpbXBsZW1lbnRlZCIpOwotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiAoaXRlcmF0b3IpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoaXMgaXMgYSBzaG9ydGN1dCB0byB0aGUgaXRlcmF0b3JzIHRoYXQgaW1wbGVtZW50IHRoZQotICAgKiBYUGF0aCBheGVzLgotICAgKiBSZXR1cm5zIGEgYmFyZS1ib25lcyBpdGVyYXRvciB0aGF0IG11c3QgYmUgaW5pdGlhbGl6ZWQKLSAgICogd2l0aCBhIHN0YXJ0IG5vZGUgKHVzaW5nIGl0ZXJhdG9yLnNldFN0YXJ0Tm9kZSgpKS4KLSAgICoKLSAgICogQHBhcmFtIGF4aXMgT25lIG9mIEF4ZXMuQU5DRVNUT1JPUlNFTEYsIGV0Yy4KLSAgICoKLSAgICogQHJldHVybiBBIERUTUF4aXNJdGVyYXRvciwgb3IgbnVsbCBpZiB0aGUgZ2l2ZW4gYXhpcyBpc24ndCBzdXBwb3J0ZWQuCi0gICAqLwotICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIGdldEF4aXNJdGVyYXRvcihmaW5hbCBpbnQgYXhpcykKLSAgewotCi0gICAgRFRNQXhpc0l0ZXJhdG9yIGl0ZXJhdG9yID0gbnVsbDsKLQotICAgIHN3aXRjaCAoYXhpcykKLSAgICB7Ci0gICAgY2FzZSBBeGlzLlNFTEYgOgotICAgICAgaXRlcmF0b3IgPSBuZXcgU2luZ2xldG9uSXRlcmF0b3IoKTsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgQXhpcy5DSElMRCA6Ci0gICAgICBpdGVyYXRvciA9IG5ldyBDaGlsZHJlbkl0ZXJhdG9yKCk7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIEF4aXMuUEFSRU5UIDoKLSAgICAgIHJldHVybiAobmV3IFBhcmVudEl0ZXJhdG9yKCkpOwotICAgIGNhc2UgQXhpcy5BTkNFU1RPUiA6Ci0gICAgICByZXR1cm4gKG5ldyBBbmNlc3Rvckl0ZXJhdG9yKCkpOwotICAgIGNhc2UgQXhpcy5BTkNFU1RPUk9SU0VMRiA6Ci0gICAgICByZXR1cm4gKChuZXcgQW5jZXN0b3JJdGVyYXRvcigpKS5pbmNsdWRlU2VsZigpKTsKLSAgICBjYXNlIEF4aXMuQVRUUklCVVRFIDoKLSAgICAgIHJldHVybiAobmV3IEF0dHJpYnV0ZUl0ZXJhdG9yKCkpOwotICAgIGNhc2UgQXhpcy5ERVNDRU5EQU5UIDoKLSAgICAgIGl0ZXJhdG9yID0gbmV3IERlc2NlbmRhbnRJdGVyYXRvcigpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBBeGlzLkRFU0NFTkRBTlRPUlNFTEYgOgotICAgICAgaXRlcmF0b3IgPSAobmV3IERlc2NlbmRhbnRJdGVyYXRvcigpKS5pbmNsdWRlU2VsZigpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBBeGlzLkZPTExPV0lORyA6Ci0gICAgICBpdGVyYXRvciA9IG5ldyBGb2xsb3dpbmdJdGVyYXRvcigpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBBeGlzLlBSRUNFRElORyA6Ci0gICAgICBpdGVyYXRvciA9IG5ldyBQcmVjZWRpbmdJdGVyYXRvcigpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBBeGlzLkZPTExPV0lOR1NJQkxJTkcgOgotICAgICAgaXRlcmF0b3IgPSBuZXcgRm9sbG93aW5nU2libGluZ0l0ZXJhdG9yKCk7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIEF4aXMuUFJFQ0VESU5HU0lCTElORyA6Ci0gICAgICBpdGVyYXRvciA9IG5ldyBQcmVjZWRpbmdTaWJsaW5nSXRlcmF0b3IoKTsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgQXhpcy5OQU1FU1BBQ0UgOgotICAgICAgaXRlcmF0b3IgPSBuZXcgTmFtZXNwYWNlSXRlcmF0b3IoKTsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgQXhpcy5ST09UIDoKLSAgICAgIGl0ZXJhdG9yID0gbmV3IFJvb3RJdGVyYXRvcigpOwotICAgICAgYnJlYWs7Ci0gICAgZGVmYXVsdCA6Ci0gICAgICB0aHJvdyBuZXcgRFRNRXhjZXB0aW9uKFhNTE1lc3NhZ2VzLmNyZWF0ZVhNTE1lc3NhZ2UoCi0gICAgICAgIFhNTEVycm9yUmVzb3VyY2VzLkVSX0lURVJBVE9SX0FYSVNfTk9UX0lNUExFTUVOVEVELAotICAgICAgICBuZXcgT2JqZWN0W117QXhpcy5nZXROYW1lcyhheGlzKX0pKTsKLSAgICAgICAgLy8iRXJyb3I6IGl0ZXJhdG9yIGZvciBheGlzICciICsgQXhpcy5uYW1lc1theGlzXQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLysgIicgbm90IGltcGxlbWVudGVkIik7Ci0gICAgfQotCi0gICAgcmV0dXJuIChpdGVyYXRvcik7Ci0gIH0KLQotICAvKioKLSAgICogQWJzdHJhY3Qgc3VwZXJjbGFzcyBkZWZpbmluZyBiZWhhdmlvcnMgc2hhcmVkIGJ5IGFsbCBEVE1EZWZhdWx0J3MKLSAgICogaW50ZXJuYWwgaW1wbGVtZW50YXRpb25zIG9mIERUTUF4aXNJdGVyYXRvci4gU3ViY2xhc3MgdGhpcyAoYW5kCi0gICAqIG92ZXJyaWRlLCBpZiBuZWNlc3NhcnkpIHRvIGltcGxlbWVudCB0aGUgc3BlY2lmaWNzIG9mIGFuCi0gICAqIGluZGl2aWR1YWwgYXhpcyBpdGVyYXRvci4KLSAgICoKLSAgICogQ3VycmVudGx5IHRoZXJlIGlzbid0IGEgbG90IGhlcmUKLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBjbGFzcyBJbnRlcm5hbEF4aXNJdGVyYXRvckJhc2UgZXh0ZW5kcyBEVE1BeGlzSXRlcmF0b3JCYXNlCi0gIHsKLQotICAgIC8vICVSRVZJRVclIFdlIGNvdWxkIG9wdCB0byBzaGFyZSBfbm9kZVR5cGUgYW5kIHNldE5vZGVUeXBlKCkgYXMKLSAgICAvLyB3ZWxsLCBhbmQgc2ltcGx5IGlnbm9yZSB0aGVtIGluIGl0ZXJhdG9ycyB3aGljaCBkb24ndCB1c2UgdGhlbS4KLSAgICAvLyBCdXQgU2NvdHQncyB3b3JyaWVkIGFib3V0IHRoZSBvdmVyaGVhZCBpbnZvbHZlZCBpbiBjbG9uaW5nCi0gICAgLy8gdGhlc2UsIGFuZCB3YW50cyB0aGVtIHRvIGhhdmUgYXMgZmV3IGZpZWxkcyBhcyBwb3NzaWJsZS4gTm90ZQotICAgIC8vIHRoYXQgd2UgY2FuJ3QgY3JlYXRlIGEgVHlwZWRJbnRlcm5hbEF4aXNJdGVyYXRvckJhc2UgYmVjYXVzZQotICAgIC8vIHRob3NlIGFyZSBvZnRlbiBiYXNlZCBvbiB0aGUgdW50eXBlZCB2ZXJzaW9ucyBhbmQgSmF2YSBkb2Vzbid0Ci0gICAgLy8gc3VwcG9ydCBtdWx0aXBsZSBpbmhlcml0YW5jZS4gPHNpZ2gvPgotCi0gICAgLyoqCi0gICAgICogQ3VycmVudCBpdGVyYXRpb24gbG9jYXRpb24uIFVzdWFsbHkgdGhpcyBpcyB0aGUgbGFzdCBsb2NhdGlvbgotICAgICAqIHJldHVybmVkIChzdGFydGluZyBwb2ludCBmb3IgdGhlIG5leHQoKSBzZWFyY2gpOyBmb3Igc2luZ2xlLW5vZGUKLSAgICAgKiBpdGVyYXRvcnMgaXQgbWF5IGluc3RlYWQgYmUgaW5pdGlhbGl6ZWQgdG8gcG9pbnQgdG8gdGhhdCBzaW5nbGUgbm9kZS4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgaW50IF9jdXJyZW50Tm9kZTsKLQotICAgIC8qKgotICAgICAqIFJlbWVtYmVycyB0aGUgY3VycmVudCBub2RlIGZvciB0aGUgbmV4dCBjYWxsIHRvIGdvdG9NYXJrKCkuCi0gICAgICoKLSAgICAgKiAlUkVWSUVXJSBTaG91bGQgdGhpcyBzYXZlIF9wb3NpdGlvbiB0b28/Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0TWFyaygpCi0gICAgewotICAgICAgX21hcmtlZE5vZGUgPSBfY3VycmVudE5vZGU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmVzdG9yZXMgdGhlIGN1cnJlbnQgbm9kZSByZW1lbWJlcmVkIGJ5IHNldE1hcmsoKS4KLSAgICAgKgotICAgICAqICVSRVZFSVclIFNob3VsZCB0aGlzIHJlc3RvcmUgX3Bvc2l0aW9uIHRvbz8KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBnb3RvTWFyaygpCi0gICAgewotICAgICAgX2N1cnJlbnROb2RlID0gX21hcmtlZE5vZGU7Ci0gICAgfQotCi0gIH0gIC8vIGVuZCBvZiBJbnRlcm5hbEF4aXNJdGVyYXRvckJhc2UKLQotICAvKioKLSAgICogSXRlcmF0b3IgdGhhdCByZXR1cm5zIGFsbCBpbW1lZGlhdGUgY2hpbGRyZW4gb2YgYSBnaXZlbiBub2RlCi0gICAqLwotICBwdWJsaWMgZmluYWwgY2xhc3MgQ2hpbGRyZW5JdGVyYXRvciBleHRlbmRzIEludGVybmFsQXhpc0l0ZXJhdG9yQmFzZQotICB7Ci0KLSAgICAvKioKLSAgICAgKiBTZXR0aW5nIHN0YXJ0IHRvIEVORCBzaG91bGQgJ2Nsb3NlJyB0aGUgaXRlcmF0b3IsCi0gICAgICogaS5lLiBzdWJzZXF1ZW50IGNhbGwgdG8gbmV4dCgpIHNob3VsZCByZXR1cm4gRU5ELgotICAgICAqCi0gICAgICogSWYgdGhlIGl0ZXJhdG9yIGlzIG5vdCByZXN0YXJ0YWJsZSwgdGhpcyBoYXMgbm8gZWZmZWN0LgotICAgICAqICVSRVZJRVclIFNob3VsZCBpdCByZXR1cm4vdGhyb3cgc29tZXRoaW5nIGluIHRoYXQgY2FzZSwKLSAgICAgKiBvciBzZXQgY3VycmVudCBub2RlIHRvIEVORCwgdG8gaW5kaWNhdGUgcmVxdWVzdC1ub3QtaG9ub3JlZD8KLSAgICAgKgotICAgICAqIEBwYXJhbSBub2RlIFNldHMgdGhlIHJvb3Qgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gQSBEVE1BeGlzSXRlcmF0b3Igc2V0IHRvIHRoZSBzdGFydCBvZiB0aGUgaXRlcmF0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3Igc2V0U3RhcnROb2RlKGludCBub2RlKQotICAgIHsKLS8vJUhaJTogQWRkZWQgcmVmZXJlbmNlIHRvIERUTURlZmF1bHRCYXNlLlJPT1ROT0RFIGJhY2sgaW4sIHRlbXBvcmFyaWx5Ci0gICAgICBpZiAobm9kZSA9PSBEVE1EZWZhdWx0QmFzZS5ST09UTk9ERSkKLSAgICAgICAgbm9kZSA9IGdldERvY3VtZW50KCk7Ci0gICAgICBpZiAoX2lzUmVzdGFydGFibGUpCi0gICAgICB7Ci0gICAgICAgIF9zdGFydE5vZGUgPSBub2RlOwotICAgICAgICBfY3VycmVudE5vZGUgPSAobm9kZSA9PSBEVE0uTlVMTCkgPyBEVE0uTlVMTAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBfZmlyc3RjaChtYWtlTm9kZUlkZW50aXR5KG5vZGUpKTsKLQotICAgICAgICByZXR1cm4gcmVzZXRQb3NpdGlvbigpOwotICAgICAgfQotCi0gICAgICByZXR1cm4gdGhpczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIG5leHQgbm9kZSBpbiB0aGUgaXRlcmF0aW9uLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgbmV4dCBub2RlIGhhbmRsZSBpbiB0aGUgaXRlcmF0aW9uLCBvciBFTkQgaWYgbm8gbW9yZQotICAgICAqIGFyZSBhdmFpbGFibGUuCi0gICAgICovCi0gICAgcHVibGljIGludCBuZXh0KCkKLSAgICB7Ci0gICAgICBpZiAoX2N1cnJlbnROb2RlICE9IE5VTEwpIHsKLSAgICAgICAgaW50IG5vZGUgPSBfY3VycmVudE5vZGU7Ci0gICAgICAgIF9jdXJyZW50Tm9kZSA9IF9uZXh0c2liKG5vZGUpOwotICAgICAgICByZXR1cm4gcmV0dXJuTm9kZShtYWtlTm9kZUhhbmRsZShub2RlKSk7Ci0gICAgICB9Ci0KLSAgICAgIHJldHVybiBFTkQ7Ci0gICAgfQotICB9ICAvLyBlbmQgb2YgQ2hpbGRyZW5JdGVyYXRvcgotCi0gIC8qKgotICAgKiBJdGVyYXRvciB0aGF0IHJldHVybnMgdGhlIHBhcmVudCBvZiBhIGdpdmVuIG5vZGUuIE5vdGUgdGhhdAotICAgKiB0aGlzIGRlbGl2ZXJzIG9ubHkgYSBzaW5nbGUgbm9kZTsgaWYgeW91IHdhbnQgYWxsIHRoZSBhbmNlc3RvcnMsCi0gICAqIHNlZSBBbmNlc3Rvckl0ZXJhdG9yLgotICAgKi8KLSAgcHVibGljIGZpbmFsIGNsYXNzIFBhcmVudEl0ZXJhdG9yIGV4dGVuZHMgSW50ZXJuYWxBeGlzSXRlcmF0b3JCYXNlCi0gIHsKLQotICAgIC8qKiBUaGUgZXh0ZW5kZWQgdHlwZSBJRCB0aGF0IHdhcyByZXF1ZXN0ZWQuICovCi0gICAgcHJpdmF0ZSBpbnQgX25vZGVUeXBlID0gLTE7Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgc3RhcnQgdG8gRU5EIHNob3VsZCAnY2xvc2UnIHRoZSBpdGVyYXRvciwKLSAgICAgKiBpLmUuIHN1YnNlcXVlbnQgY2FsbCB0byBuZXh0KCkgc2hvdWxkIHJldHVybiBFTkQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbm9kZSBTZXRzIHRoZSByb290IG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIEEgRFRNQXhpc0l0ZXJhdG9yIHNldCB0byB0aGUgc3RhcnQgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIHNldFN0YXJ0Tm9kZShpbnQgbm9kZSkKLSAgICB7Ci0vLyVIWiU6IEFkZGVkIHJlZmVyZW5jZSB0byBEVE1EZWZhdWx0QmFzZS5ST09UTk9ERSBiYWNrIGluLCB0ZW1wb3JhcmlseQotICAgICAgaWYgKG5vZGUgPT0gRFRNRGVmYXVsdEJhc2UuUk9PVE5PREUpCi0gICAgICAgIG5vZGUgPSBnZXREb2N1bWVudCgpOwotICAgICAgaWYgKF9pc1Jlc3RhcnRhYmxlKQotICAgICAgewotICAgICAgICBfc3RhcnROb2RlID0gbm9kZTsKLSAgICAgICAgX2N1cnJlbnROb2RlID0gZ2V0UGFyZW50KG5vZGUpOwotCi0gICAgICAgIHJldHVybiByZXNldFBvc2l0aW9uKCk7Ci0gICAgICB9Ci0KLSAgICAgIHJldHVybiB0aGlzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldCB0aGUgbm9kZSB0eXBlIG9mIHRoZSBwYXJlbnQgdGhhdCB3ZSdyZSBsb29raW5nIGZvci4KLSAgICAgKiBOb3RlIHRoYXQgdGhpcyBkb2VzIF9ub3RfIG1lYW4gImZpbmQgdGhlIG5lYXJlc3QgYW5jZXN0b3Igb2YKLSAgICAgKiB0aGlzIHR5cGUiLCBidXQgInlpZWxkIHRoZSBwYXJlbnQgaWYgaXQgaXMgb2YgdGhpcyB0eXBlIi4KLSAgICAgKgotICAgICAqCi0gICAgICogQHBhcmFtIHR5cGUgZXh0ZW5kZWQgdHlwZSBJRC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gUGFyZW50SXRlcmF0b3IgY29uZmlndXJlZCB3aXRoIHRoZSB0eXBlIGZpbHRlciBzZXQuCi0gICAgICovCi0gICAgcHVibGljIERUTUF4aXNJdGVyYXRvciBzZXROb2RlVHlwZShmaW5hbCBpbnQgdHlwZSkKLSAgICB7Ci0KLSAgICAgIF9ub2RlVHlwZSA9IHR5cGU7Ci0KLSAgICAgIHJldHVybiB0aGlzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgbmV4dCBub2RlIGluIHRoZSBpdGVyYXRpb24uIEluIHRoaXMgY2FzZSwgd2UgcmV0dXJuCi0gICAgICogb25seSB0aGUgaW1tZWRpYXRlIHBhcmVudCwgX2lmXyBpdCBtYXRjaGVzIHRoZSByZXF1ZXN0ZWQgbm9kZVR5cGUuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBuZXh0IG5vZGUgaGFuZGxlIGluIHRoZSBpdGVyYXRpb24sIG9yIEVORC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IG5leHQoKQotICAgIHsKLSAgICAgIGludCByZXN1bHQgPSBfY3VycmVudE5vZGU7Ci0KLSAgICAgIGlmIChfbm9kZVR5cGUgPj0gRFRNLk5UWVBFUykgewotICAgICAgICBpZiAoX25vZGVUeXBlICE9IGdldEV4cGFuZGVkVHlwZUlEKF9jdXJyZW50Tm9kZSkpIHsKLSAgICAgICAgICByZXN1bHQgPSBFTkQ7Ci0gICAgICAgIH0KLSAgICAgIH0gZWxzZSBpZiAoX25vZGVUeXBlICE9IE5VTEwpIHsKLSAgICAgICAgaWYgKF9ub2RlVHlwZSAhPSBnZXROb2RlVHlwZShfY3VycmVudE5vZGUpKSB7Ci0gICAgICAgICAgcmVzdWx0ID0gRU5EOwotICAgICAgICB9Ci0gICAgICB9Ci0KLSAgICAgIF9jdXJyZW50Tm9kZSA9IEVORDsKLQotICAgICAgcmV0dXJuIHJldHVybk5vZGUocmVzdWx0KTsKLSAgICB9Ci0gIH0gIC8vIGVuZCBvZiBQYXJlbnRJdGVyYXRvcgotCi0gIC8qKgotICAgKiBJdGVyYXRvciB0aGF0IHJldHVybnMgY2hpbGRyZW4gb2YgYSBnaXZlbiB0eXBlIGZvciBhIGdpdmVuIG5vZGUuCi0gICAqIFRoZSBmdW5jdGlvbmFsaXR5IGNob3VsZCBiZSBhY2hpZXZlZCBieSBwdXR0aW5nIGEgZmlsdGVyIG9uIHRvcAotICAgKiBvZiBhIGJhc2ljIGNoaWxkIGl0ZXJhdG9yLCBidXQgYSBzcGVjaWFsaXNlZCBpdGVyYXRvciBpcyB1c2VkCi0gICAqIGZvciBlZmZpY2llbmN5IChib3RoIHNwZWVkIGFuZCBzaXplIG9mIHRyYW5zbGV0KS4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBjbGFzcyBUeXBlZENoaWxkcmVuSXRlcmF0b3IgZXh0ZW5kcyBJbnRlcm5hbEF4aXNJdGVyYXRvckJhc2UKLSAgewotCi0gICAgLyoqIFRoZSBleHRlbmRlZCB0eXBlIElEIHRoYXQgd2FzIHJlcXVlc3RlZC4gKi8KLSAgICBwcml2YXRlIGZpbmFsIGludCBfbm9kZVR5cGU7Ci0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RvciBUeXBlZENoaWxkcmVuSXRlcmF0b3IKLSAgICAgKgotICAgICAqCi0gICAgICogQHBhcmFtIG5vZGVUeXBlIFRoZSBleHRlbmRlZCB0eXBlIElEIGJlaW5nIHJlcXVlc3RlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgVHlwZWRDaGlsZHJlbkl0ZXJhdG9yKGludCBub2RlVHlwZSkKLSAgICB7Ci0gICAgICBfbm9kZVR5cGUgPSBub2RlVHlwZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgc3RhcnQgdG8gRU5EIHNob3VsZCAnY2xvc2UnIHRoZSBpdGVyYXRvciwKLSAgICAgKiBpLmUuIHN1YnNlcXVlbnQgY2FsbCB0byBuZXh0KCkgc2hvdWxkIHJldHVybiBFTkQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbm9kZSBTZXRzIHRoZSByb290IG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIEEgRFRNQXhpc0l0ZXJhdG9yIHNldCB0byB0aGUgc3RhcnQgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIHNldFN0YXJ0Tm9kZShpbnQgbm9kZSkKLSAgICB7Ci0vLyVIWiU6IEFkZGVkIHJlZmVyZW5jZSB0byBEVE1EZWZhdWx0QmFzZS5ST09UTk9ERSBiYWNrIGluLCB0ZW1wb3JhcmlseQotICAgICAgaWYgKG5vZGUgPT0gRFRNRGVmYXVsdEJhc2UuUk9PVE5PREUpCi0gICAgICAgIG5vZGUgPSBnZXREb2N1bWVudCgpOwotICAgICAgaWYgKF9pc1Jlc3RhcnRhYmxlKQotICAgICAgewotICAgICAgICBfc3RhcnROb2RlID0gbm9kZTsKLSAgICAgICAgX2N1cnJlbnROb2RlID0gKG5vZGUgPT0gRFRNLk5VTEwpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gRFRNLk5VTEwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBfZmlyc3RjaChtYWtlTm9kZUlkZW50aXR5KF9zdGFydE5vZGUpKTsKLQotICAgICAgICByZXR1cm4gcmVzZXRQb3NpdGlvbigpOwotICAgICAgfQotCi0gICAgICByZXR1cm4gdGhpczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIG5leHQgbm9kZSBpbiB0aGUgaXRlcmF0aW9uLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgbmV4dCBub2RlIGhhbmRsZSBpbiB0aGUgaXRlcmF0aW9uLCBvciBFTkQuCi0gICAgICovCi0gICAgcHVibGljIGludCBuZXh0KCkKLSAgICB7Ci0gICAgICBpbnQgZVR5cGU7Ci0gICAgICBpbnQgbm9kZSA9IF9jdXJyZW50Tm9kZTsKLQotICAgICAgaW50IG5vZGVUeXBlID0gX25vZGVUeXBlOwotCi0gICAgICBpZiAobm9kZVR5cGUgPj0gRFRNLk5UWVBFUykgewotICAgICAgICB3aGlsZSAobm9kZSAhPSBEVE0uTlVMTCAmJiBfZXhwdHlwZShub2RlKSAhPSBub2RlVHlwZSkgewotICAgICAgICAgIG5vZGUgPSBfbmV4dHNpYihub2RlKTsKLSAgICAgICAgfQotICAgICAgfSBlbHNlIHsKLSAgICAgICAgd2hpbGUgKG5vZGUgIT0gRFRNLk5VTEwpIHsKLSAgICAgICAgICBlVHlwZSA9IF9leHB0eXBlKG5vZGUpOwotICAgICAgICAgIGlmIChlVHlwZSA8IERUTS5OVFlQRVMpIHsKLSAgICAgICAgICAgIGlmIChlVHlwZSA9PSBub2RlVHlwZSkgewotICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICB9IGVsc2UgaWYgKG1fZXhwYW5kZWROYW1lVGFibGUuZ2V0VHlwZShlVHlwZSkgPT0gbm9kZVR5cGUpIHsKLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgIH0KLSAgICAgICAgICBub2RlID0gX25leHRzaWIobm9kZSk7Ci0gICAgICAgIH0KLSAgICAgIH0KLQotICAgICAgaWYgKG5vZGUgPT0gRFRNLk5VTEwpIHsKLSAgICAgICAgX2N1cnJlbnROb2RlID0gRFRNLk5VTEw7Ci0gICAgICAgIHJldHVybiBEVE0uTlVMTDsKLSAgICAgIH0gZWxzZSB7Ci0gICAgICAgIF9jdXJyZW50Tm9kZSA9IF9uZXh0c2liKG5vZGUpOwotICAgICAgICByZXR1cm4gcmV0dXJuTm9kZShtYWtlTm9kZUhhbmRsZShub2RlKSk7Ci0gICAgICB9Ci0KLSAgICB9Ci0gIH0gIC8vIGVuZCBvZiBUeXBlZENoaWxkcmVuSXRlcmF0b3IKLQotICAvKioKLSAgICogSXRlcmF0b3IgdGhhdCByZXR1cm5zIGNoaWxkcmVuIHdpdGhpbiBhIGdpdmVuIG5hbWVzcGFjZSBmb3IgYQotICAgKiBnaXZlbiBub2RlLiBUaGUgZnVuY3Rpb25hbGl0eSBjaG91bGQgYmUgYWNoaWV2ZWQgYnkgcHV0dGluZyBhCi0gICAqIGZpbHRlciBvbiB0b3Agb2YgYSBiYXNpYyBjaGlsZCBpdGVyYXRvciwgYnV0IGEgc3BlY2lhbGlzZWQKLSAgICogaXRlcmF0b3IgaXMgdXNlZCBmb3IgZWZmaWNpZW5jeSAoYm90aCBzcGVlZCBhbmQgc2l6ZSBvZiB0cmFuc2xldCkuCi0gICAqLwotICBwdWJsaWMgZmluYWwgY2xhc3MgTmFtZXNwYWNlQ2hpbGRyZW5JdGVyYXRvcgotICAgICAgICAgIGV4dGVuZHMgSW50ZXJuYWxBeGlzSXRlcmF0b3JCYXNlCi0gIHsKLQotICAgIC8qKiBUaGUgZXh0ZW5kZWQgdHlwZSBJRCBiZWluZyByZXF1ZXN0ZWQuICovCi0gICAgcHJpdmF0ZSBmaW5hbCBpbnQgX25zVHlwZTsKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdG9yIE5hbWVzcGFjZUNoaWxkcmVuSXRlcmF0b3IKLSAgICAgKgotICAgICAqCi0gICAgICogQHBhcmFtIHR5cGUgVGhlIGV4dGVuZGVkIHR5cGUgSUQgYmVpbmcgcmVxdWVzdGVkLgotICAgICAqLwotICAgIHB1YmxpYyBOYW1lc3BhY2VDaGlsZHJlbkl0ZXJhdG9yKGZpbmFsIGludCB0eXBlKQotICAgIHsKLSAgICAgIF9uc1R5cGUgPSB0eXBlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldCBzdGFydCB0byBFTkQgc2hvdWxkICdjbG9zZScgdGhlIGl0ZXJhdG9yLAotICAgICAqIGkuZS4gc3Vic2VxdWVudCBjYWxsIHRvIG5leHQoKSBzaG91bGQgcmV0dXJuIEVORC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBub2RlIFNldHMgdGhlIHJvb3Qgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gQSBEVE1BeGlzSXRlcmF0b3Igc2V0IHRvIHRoZSBzdGFydCBvZiB0aGUgaXRlcmF0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3Igc2V0U3RhcnROb2RlKGludCBub2RlKQotICAgIHsKLS8vJUhaJTogQWRkZWQgcmVmZXJlbmNlIHRvIERUTURlZmF1bHRCYXNlLlJPT1ROT0RFIGJhY2sgaW4sIHRlbXBvcmFyaWx5Ci0gICAgICBpZiAobm9kZSA9PSBEVE1EZWZhdWx0QmFzZS5ST09UTk9ERSkKLSAgICAgICAgbm9kZSA9IGdldERvY3VtZW50KCk7Ci0gICAgICBpZiAoX2lzUmVzdGFydGFibGUpCi0gICAgICB7Ci0gICAgICAgIF9zdGFydE5vZGUgPSBub2RlOwotICAgICAgICBfY3VycmVudE5vZGUgPSAobm9kZSA9PSBEVE0uTlVMTCkgPyBEVE0uTlVMTCA6IE5PVFBST0NFU1NFRDsKLQotICAgICAgICByZXR1cm4gcmVzZXRQb3NpdGlvbigpOwotICAgICAgfQotCi0gICAgICByZXR1cm4gdGhpczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIG5leHQgbm9kZSBpbiB0aGUgaXRlcmF0aW9uLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgbmV4dCBub2RlIGhhbmRsZSBpbiB0aGUgaXRlcmF0aW9uLCBvciBFTkQuCi0gICAgICovCi0gICAgcHVibGljIGludCBuZXh0KCkKLSAgICB7Ci0gICAgICBpZiAoX2N1cnJlbnROb2RlICE9IERUTS5OVUxMKSB7Ci0gICAgICAgIGZvciAoaW50IG5vZGUgPSAoTk9UUFJPQ0VTU0VEID09IF9jdXJyZW50Tm9kZSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IF9maXJzdGNoKG1ha2VOb2RlSWRlbnRpdHkoX3N0YXJ0Tm9kZSkpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBfbmV4dHNpYihfY3VycmVudE5vZGUpOwotICAgICAgICAgICAgIG5vZGUgIT0gRU5EOwotICAgICAgICAgICAgIG5vZGUgPSBfbmV4dHNpYihub2RlKSkgewotICAgICAgICAgIGlmIChtX2V4cGFuZGVkTmFtZVRhYmxlLmdldE5hbWVzcGFjZUlEKF9leHB0eXBlKG5vZGUpKSA9PSBfbnNUeXBlKSB7Ci0gICAgICAgICAgICBfY3VycmVudE5vZGUgPSBub2RlOwotCi0gICAgICAgICAgICByZXR1cm4gcmV0dXJuTm9kZShub2RlKTsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgIH0KLQotICAgICAgcmV0dXJuIEVORDsKLSAgICB9Ci0gIH0gIC8vIGVuZCBvZiBOYW1lc3BhY2VDaGlsZHJlbkl0ZXJhdG9yCi0KLSAgLyoqCi0gICAqIEl0ZXJhdG9yIHRoYXQgcmV0dXJucyB0aGUgbmFtZXNwYWNlIG5vZGVzIGFzIGRlZmluZWQgYnkgdGhlIFhQYXRoIGRhdGEgbW9kZWwKLSAgICogZm9yIGEgZ2l2ZW4gbm9kZS4KLSAgICovCi0gIHB1YmxpYyBjbGFzcyBOYW1lc3BhY2VJdGVyYXRvcgotICAgICAgICAgIGV4dGVuZHMgSW50ZXJuYWxBeGlzSXRlcmF0b3JCYXNlCi0gIHsKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdG9yIE5hbWVzcGFjZUF0dHJpYnV0ZUl0ZXJhdG9yCi0gICAgICovCi0gICAgcHVibGljIE5hbWVzcGFjZUl0ZXJhdG9yKCkKLSAgICB7Ci0KLSAgICAgIHN1cGVyKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0IHN0YXJ0IHRvIEVORCBzaG91bGQgJ2Nsb3NlJyB0aGUgaXRlcmF0b3IsCi0gICAgICogaS5lLiBzdWJzZXF1ZW50IGNhbGwgdG8gbmV4dCgpIHNob3VsZCByZXR1cm4gRU5ELgotICAgICAqCi0gICAgICogQHBhcmFtIG5vZGUgU2V0cyB0aGUgcm9vdCBvZiB0aGUgaXRlcmF0aW9uLgotICAgICAqCi0gICAgICogQHJldHVybiBBIERUTUF4aXNJdGVyYXRvciBzZXQgdG8gdGhlIHN0YXJ0IG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICovCi0gICAgcHVibGljIERUTUF4aXNJdGVyYXRvciBzZXRTdGFydE5vZGUoaW50IG5vZGUpCi0gICAgewotLy8lSFolOiBBZGRlZCByZWZlcmVuY2UgdG8gRFRNRGVmYXVsdEJhc2UuUk9PVE5PREUgYmFjayBpbiwgdGVtcG9yYXJpbHkKLSAgICAgIGlmIChub2RlID09IERUTURlZmF1bHRCYXNlLlJPT1ROT0RFKQotICAgICAgICBub2RlID0gZ2V0RG9jdW1lbnQoKTsKLSAgICAgIGlmIChfaXNSZXN0YXJ0YWJsZSkKLSAgICAgIHsKLSAgICAgICAgX3N0YXJ0Tm9kZSA9IG5vZGU7Ci0gICAgICAgIF9jdXJyZW50Tm9kZSA9IGdldEZpcnN0TmFtZXNwYWNlTm9kZShub2RlLCB0cnVlKTsKLQotICAgICAgICByZXR1cm4gcmVzZXRQb3NpdGlvbigpOwotICAgICAgfQotCi0gICAgICByZXR1cm4gdGhpczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIG5leHQgbm9kZSBpbiB0aGUgaXRlcmF0aW9uLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgbmV4dCBub2RlIGhhbmRsZSBpbiB0aGUgaXRlcmF0aW9uLCBvciBFTkQuCi0gICAgICovCi0gICAgcHVibGljIGludCBuZXh0KCkKLSAgICB7Ci0KLSAgICAgIGludCBub2RlID0gX2N1cnJlbnROb2RlOwotCi0gICAgICBpZiAoRFRNLk5VTEwgIT0gbm9kZSkKLSAgICAgICAgX2N1cnJlbnROb2RlID0gZ2V0TmV4dE5hbWVzcGFjZU5vZGUoX3N0YXJ0Tm9kZSwgbm9kZSwgdHJ1ZSk7Ci0KLSAgICAgIHJldHVybiByZXR1cm5Ob2RlKG5vZGUpOwotICAgIH0KLSAgfSAgLy8gZW5kIG9mIE5hbWVzcGFjZUl0ZXJhdG9yCi0KLSAgLyoqCi0gICAqIEl0ZXJhdG9yIHRoYXQgcmV0dXJucyB0aGUgbmFtZXNwYWNlIG5vZGVzIGFzIGRlZmluZWQgYnkgdGhlIFhQYXRoIGRhdGEgbW9kZWwKLSAgICogZm9yIGEgZ2l2ZW4gbm9kZSwgZmlsdGVyZWQgYnkgZXh0ZW5kZWQgdHlwZSBJRC4KLSAgICovCi0gIHB1YmxpYyBjbGFzcyBUeXBlZE5hbWVzcGFjZUl0ZXJhdG9yIGV4dGVuZHMgTmFtZXNwYWNlSXRlcmF0b3IKLSAgewotCi0gICAgLyoqIFRoZSBleHRlbmRlZCB0eXBlIElEIHRoYXQgd2FzIHJlcXVlc3RlZC4gKi8KLSAgICBwcml2YXRlIGZpbmFsIGludCBfbm9kZVR5cGU7Ci0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RvciBUeXBlZE5hbWVzcGFjZUl0ZXJhdG9yCi0gICAgICoKLSAgICAgKgotICAgICAqIEBwYXJhbSBub2RlVHlwZSBUaGUgZXh0ZW5kZWQgdHlwZSBJRCBiZWluZyByZXF1ZXN0ZWQuCi0gICAgICovCi0gICAgcHVibGljIFR5cGVkTmFtZXNwYWNlSXRlcmF0b3IoaW50IG5vZGVUeXBlKQotICAgIHsKLSAgICAgIHN1cGVyKCk7Ci0gICAgICBfbm9kZVR5cGUgPSBub2RlVHlwZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIG5leHQgbm9kZSBpbiB0aGUgaXRlcmF0aW9uLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgbmV4dCBub2RlIGhhbmRsZSBpbiB0aGUgaXRlcmF0aW9uLCBvciBFTkQuCi0gICAgICovCi0gICAgcHVibGljIGludCBuZXh0KCkKLSAgICB7Ci0gICAgICAgIGludCBub2RlOwotCi0gICAgICBmb3IgKG5vZGUgPSBfY3VycmVudE5vZGU7Ci0gICAgICAgICAgIG5vZGUgIT0gRU5EOwotICAgICAgICAgICBub2RlID0gZ2V0TmV4dE5hbWVzcGFjZU5vZGUoX3N0YXJ0Tm9kZSwgbm9kZSwgdHJ1ZSkpIHsKLSAgICAgICAgaWYgKGdldEV4cGFuZGVkVHlwZUlEKG5vZGUpID09IF9ub2RlVHlwZQotICAgICAgICAgICAgfHwgZ2V0Tm9kZVR5cGUobm9kZSkgPT0gX25vZGVUeXBlCi0gICAgICAgICAgICB8fCBnZXROYW1lc3BhY2VUeXBlKG5vZGUpID09IF9ub2RlVHlwZSkgewotICAgICAgICAgIF9jdXJyZW50Tm9kZSA9IG5vZGU7Ci0KLSAgICAgICAgICByZXR1cm4gcmV0dXJuTm9kZShub2RlKTsKLSAgICAgICAgfQotICAgICAgfQotCi0gICAgICByZXR1cm4gKF9jdXJyZW50Tm9kZSA9RU5EKTsKLSAgICB9Ci0gIH0gIC8vIGVuZCBvZiBUeXBlZE5hbWVzcGFjZUl0ZXJhdG9yCi0KLSAgLyoqCi0gICAqIEl0ZXJhdG9yIHRoYXQgcmV0dXJucyB0aGUgdGhlIHJvb3Qgbm9kZSBhcyBkZWZpbmVkIGJ5IHRoZSBYUGF0aCBkYXRhIG1vZGVsCi0gICAqIGZvciBhIGdpdmVuIG5vZGUuCi0gICAqLwotICBwdWJsaWMgY2xhc3MgUm9vdEl0ZXJhdG9yCi0gICAgICAgICAgZXh0ZW5kcyBJbnRlcm5hbEF4aXNJdGVyYXRvckJhc2UKLSAgewotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0b3IgUm9vdEl0ZXJhdG9yCi0gICAgICovCi0gICAgcHVibGljIFJvb3RJdGVyYXRvcigpCi0gICAgewotCi0gICAgICBzdXBlcigpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldCBzdGFydCB0byBFTkQgc2hvdWxkICdjbG9zZScgdGhlIGl0ZXJhdG9yLAotICAgICAqIGkuZS4gc3Vic2VxdWVudCBjYWxsIHRvIG5leHQoKSBzaG91bGQgcmV0dXJuIEVORC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBub2RlIFNldHMgdGhlIHJvb3Qgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gQSBEVE1BeGlzSXRlcmF0b3Igc2V0IHRvIHRoZSBzdGFydCBvZiB0aGUgaXRlcmF0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3Igc2V0U3RhcnROb2RlKGludCBub2RlKQotICAgIHsKLQotICAgICAgaWYgKF9pc1Jlc3RhcnRhYmxlKQotICAgICAgewotICAgICAgICBfc3RhcnROb2RlID0gZ2V0RG9jdW1lbnRSb290KG5vZGUpOwotICAgICAgICBfY3VycmVudE5vZGUgPSBOVUxMOwotCi0gICAgICAgIHJldHVybiByZXNldFBvc2l0aW9uKCk7Ci0gICAgICB9Ci0KLSAgICAgIHJldHVybiB0aGlzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgbmV4dCBub2RlIGluIHRoZSBpdGVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBuZXh0IG5vZGUgaGFuZGxlIGluIHRoZSBpdGVyYXRpb24sIG9yIEVORC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IG5leHQoKQotICAgIHsKLSAgICAgIGlmKF9zdGFydE5vZGUgPT0gX2N1cnJlbnROb2RlKQotICAgICAgICByZXR1cm4gTlVMTDsKLQotICAgICAgX2N1cnJlbnROb2RlID0gX3N0YXJ0Tm9kZTsKLQotICAgICAgcmV0dXJuIHJldHVybk5vZGUoX3N0YXJ0Tm9kZSk7Ci0gICAgfQotICB9ICAvLyBlbmQgb2YgUm9vdEl0ZXJhdG9yCi0KLSAgLyoqCi0gICAqIEl0ZXJhdG9yIHRoYXQgcmV0dXJucyB0aGUgbmFtZXNwYWNlIG5vZGVzIGFzIGRlZmluZWQgYnkgdGhlIFhQYXRoIGRhdGEgbW9kZWwKLSAgICogZm9yIGEgZ2l2ZW4gbm9kZSwgZmlsdGVyZWQgYnkgZXh0ZW5kZWQgdHlwZSBJRC4KLSAgICovCi0gIHB1YmxpYyBjbGFzcyBUeXBlZFJvb3RJdGVyYXRvciBleHRlbmRzIFJvb3RJdGVyYXRvcgotICB7Ci0KLSAgICAvKiogVGhlIGV4dGVuZGVkIHR5cGUgSUQgdGhhdCB3YXMgcmVxdWVzdGVkLiAqLwotICAgIHByaXZhdGUgZmluYWwgaW50IF9ub2RlVHlwZTsKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdG9yIFR5cGVkUm9vdEl0ZXJhdG9yCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbm9kZVR5cGUgVGhlIGV4dGVuZGVkIHR5cGUgSUQgYmVpbmcgcmVxdWVzdGVkLgotICAgICAqLwotICAgIHB1YmxpYyBUeXBlZFJvb3RJdGVyYXRvcihpbnQgbm9kZVR5cGUpCi0gICAgewotICAgICAgc3VwZXIoKTsKLSAgICAgIF9ub2RlVHlwZSA9IG5vZGVUeXBlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgbmV4dCBub2RlIGluIHRoZSBpdGVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBuZXh0IG5vZGUgaGFuZGxlIGluIHRoZSBpdGVyYXRpb24sIG9yIEVORC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IG5leHQoKQotICAgIHsKLSAgICAgICAgaWYoX3N0YXJ0Tm9kZSA9PSBfY3VycmVudE5vZGUpCi0gICAgICAgIHJldHVybiBOVUxMOwotCi0gICAgICBpbnQgbm9kZVR5cGUgPSBfbm9kZVR5cGU7Ci0gICAgICBpbnQgbm9kZSA9IF9zdGFydE5vZGU7Ci0gICAgICBpbnQgZXhwVHlwZSA9IGdldEV4cGFuZGVkVHlwZUlEKG5vZGUpOwotCi0gICAgICBfY3VycmVudE5vZGUgPSBub2RlOwotCi0gICAgICBpZiAobm9kZVR5cGUgPj0gRFRNLk5UWVBFUykgewotICAgICAgICBpZiAobm9kZVR5cGUgPT0gZXhwVHlwZSkgewotICAgICAgICAgIHJldHVybiByZXR1cm5Ob2RlKG5vZGUpOwotICAgICAgICB9Ci0gICAgICB9IGVsc2UgewotICAgICAgICBpZiAoZXhwVHlwZSA8IERUTS5OVFlQRVMpIHsKLSAgICAgICAgICBpZiAoZXhwVHlwZSA9PSBub2RlVHlwZSkgewotICAgICAgICAgICAgcmV0dXJuIHJldHVybk5vZGUobm9kZSk7Ci0gICAgICAgICAgfQotICAgICAgICB9IGVsc2UgewotICAgICAgICAgIGlmIChtX2V4cGFuZGVkTmFtZVRhYmxlLmdldFR5cGUoZXhwVHlwZSkgPT0gbm9kZVR5cGUpIHsKLSAgICAgICAgICAgIHJldHVybiByZXR1cm5Ob2RlKG5vZGUpOwotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgfQotCi0gICAgICByZXR1cm4gRU5EOwotICAgIH0KLSAgfSAgLy8gZW5kIG9mIFR5cGVkUm9vdEl0ZXJhdG9yCi0KLSAgLyoqCi0gICAqIEl0ZXJhdG9yIHRoYXQgcmV0dXJucyBhdHRyaWJ1dGVzIHdpdGhpbiBhIGdpdmVuIG5hbWVzcGFjZSBmb3IgYSBub2RlLgotICAgKi8KLSAgcHVibGljIGZpbmFsIGNsYXNzIE5hbWVzcGFjZUF0dHJpYnV0ZUl0ZXJhdG9yCi0gICAgICAgICAgZXh0ZW5kcyBJbnRlcm5hbEF4aXNJdGVyYXRvckJhc2UKLSAgewotCi0gICAgLyoqIFRoZSBleHRlbmRlZCB0eXBlIElEIGJlaW5nIHJlcXVlc3RlZC4gKi8KLSAgICBwcml2YXRlIGZpbmFsIGludCBfbnNUeXBlOwotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0b3IgTmFtZXNwYWNlQXR0cmlidXRlSXRlcmF0b3IKLSAgICAgKgotICAgICAqCi0gICAgICogQHBhcmFtIG5zVHlwZSBUaGUgZXh0ZW5kZWQgdHlwZSBJRCBiZWluZyByZXF1ZXN0ZWQuCi0gICAgICovCi0gICAgcHVibGljIE5hbWVzcGFjZUF0dHJpYnV0ZUl0ZXJhdG9yKGludCBuc1R5cGUpCi0gICAgewotCi0gICAgICBzdXBlcigpOwotCi0gICAgICBfbnNUeXBlID0gbnNUeXBlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldCBzdGFydCB0byBFTkQgc2hvdWxkICdjbG9zZScgdGhlIGl0ZXJhdG9yLAotICAgICAqIGkuZS4gc3Vic2VxdWVudCBjYWxsIHRvIG5leHQoKSBzaG91bGQgcmV0dXJuIEVORC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBub2RlIFNldHMgdGhlIHJvb3Qgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gQSBEVE1BeGlzSXRlcmF0b3Igc2V0IHRvIHRoZSBzdGFydCBvZiB0aGUgaXRlcmF0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3Igc2V0U3RhcnROb2RlKGludCBub2RlKQotICAgIHsKLS8vJUhaJTogQWRkZWQgcmVmZXJlbmNlIHRvIERUTURlZmF1bHRCYXNlLlJPT1ROT0RFIGJhY2sgaW4sIHRlbXBvcmFyaWx5Ci0gICAgICBpZiAobm9kZSA9PSBEVE1EZWZhdWx0QmFzZS5ST09UTk9ERSkKLSAgICAgICAgbm9kZSA9IGdldERvY3VtZW50KCk7Ci0gICAgICBpZiAoX2lzUmVzdGFydGFibGUpCi0gICAgICB7Ci0gICAgICAgIF9zdGFydE5vZGUgPSBub2RlOwotICAgICAgICBfY3VycmVudE5vZGUgPSBnZXRGaXJzdE5hbWVzcGFjZU5vZGUobm9kZSwgZmFsc2UpOwotCi0gICAgICAgIHJldHVybiByZXNldFBvc2l0aW9uKCk7Ci0gICAgICB9Ci0KLSAgICAgIHJldHVybiB0aGlzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgbmV4dCBub2RlIGluIHRoZSBpdGVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBuZXh0IG5vZGUgaGFuZGxlIGluIHRoZSBpdGVyYXRpb24sIG9yIEVORC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IG5leHQoKQotICAgIHsKLQotICAgICAgaW50IG5vZGUgPSBfY3VycmVudE5vZGU7Ci0KLSAgICAgIGlmIChEVE0uTlVMTCAhPSBub2RlKQotICAgICAgICBfY3VycmVudE5vZGUgPSBnZXROZXh0TmFtZXNwYWNlTm9kZShfc3RhcnROb2RlLCBub2RlLCBmYWxzZSk7Ci0KLSAgICAgIHJldHVybiByZXR1cm5Ob2RlKG5vZGUpOwotICAgIH0KLSAgfSAgLy8gZW5kIG9mIE5hbWVzcGFjZUF0dHJpYnV0ZUl0ZXJhdG9yCi0KLSAgLyoqCi0gICAqIEl0ZXJhdG9yIHRoYXQgcmV0dXJucyBhbGwgc2libGluZ3Mgb2YgYSBnaXZlbiBub2RlLgotICAgKi8KLSAgcHVibGljIGNsYXNzIEZvbGxvd2luZ1NpYmxpbmdJdGVyYXRvciBleHRlbmRzIEludGVybmFsQXhpc0l0ZXJhdG9yQmFzZQotICB7Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgc3RhcnQgdG8gRU5EIHNob3VsZCAnY2xvc2UnIHRoZSBpdGVyYXRvciwKLSAgICAgKiBpLmUuIHN1YnNlcXVlbnQgY2FsbCB0byBuZXh0KCkgc2hvdWxkIHJldHVybiBFTkQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbm9kZSBTZXRzIHRoZSByb290IG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIEEgRFRNQXhpc0l0ZXJhdG9yIHNldCB0byB0aGUgc3RhcnQgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIHNldFN0YXJ0Tm9kZShpbnQgbm9kZSkKLSAgICB7Ci0vLyVIWiU6IEFkZGVkIHJlZmVyZW5jZSB0byBEVE1EZWZhdWx0QmFzZS5ST09UTk9ERSBiYWNrIGluLCB0ZW1wb3JhcmlseQotICAgICAgaWYgKG5vZGUgPT0gRFRNRGVmYXVsdEJhc2UuUk9PVE5PREUpCi0gICAgICAgIG5vZGUgPSBnZXREb2N1bWVudCgpOwotICAgICAgaWYgKF9pc1Jlc3RhcnRhYmxlKQotICAgICAgewotICAgICAgICBfc3RhcnROb2RlID0gbm9kZTsKLSAgICAgICAgX2N1cnJlbnROb2RlID0gbWFrZU5vZGVJZGVudGl0eShub2RlKTsKLQotICAgICAgICByZXR1cm4gcmVzZXRQb3NpdGlvbigpOwotICAgICAgfQotCi0gICAgICByZXR1cm4gdGhpczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIG5leHQgbm9kZSBpbiB0aGUgaXRlcmF0aW9uLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgbmV4dCBub2RlIGhhbmRsZSBpbiB0aGUgaXRlcmF0aW9uLCBvciBFTkQuCi0gICAgICovCi0gICAgcHVibGljIGludCBuZXh0KCkKLSAgICB7Ci0gICAgICBfY3VycmVudE5vZGUgPSAoX2N1cnJlbnROb2RlID09IERUTS5OVUxMKSA/IERUTS5OVUxMCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IF9uZXh0c2liKF9jdXJyZW50Tm9kZSk7Ci0gICAgICByZXR1cm4gcmV0dXJuTm9kZShtYWtlTm9kZUhhbmRsZShfY3VycmVudE5vZGUpKTsKLSAgICB9Ci0gIH0gIC8vIGVuZCBvZiBGb2xsb3dpbmdTaWJsaW5nSXRlcmF0b3IKLQotICAvKioKLSAgICogSXRlcmF0b3IgdGhhdCByZXR1cm5zIGFsbCBmb2xsb3dpbmcgc2libGluZ3Mgb2YgYSBnaXZlbiBub2RlLgotICAgKi8KLSAgcHVibGljIGZpbmFsIGNsYXNzIFR5cGVkRm9sbG93aW5nU2libGluZ0l0ZXJhdG9yCi0gICAgICAgICAgZXh0ZW5kcyBGb2xsb3dpbmdTaWJsaW5nSXRlcmF0b3IKLSAgewotCi0gICAgLyoqIFRoZSBleHRlbmRlZCB0eXBlIElEIHRoYXQgd2FzIHJlcXVlc3RlZC4gKi8KLSAgICBwcml2YXRlIGZpbmFsIGludCBfbm9kZVR5cGU7Ci0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RvciBUeXBlZEZvbGxvd2luZ1NpYmxpbmdJdGVyYXRvcgotICAgICAqCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdHlwZSBUaGUgZXh0ZW5kZWQgdHlwZSBJRCBiZWluZyByZXF1ZXN0ZWQuCi0gICAgICovCi0gICAgcHVibGljIFR5cGVkRm9sbG93aW5nU2libGluZ0l0ZXJhdG9yKGludCB0eXBlKQotICAgIHsKLSAgICAgIF9ub2RlVHlwZSA9IHR5cGU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBuZXh0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIG5leHQgbm9kZSBoYW5kbGUgaW4gdGhlIGl0ZXJhdGlvbiwgb3IgRU5ELgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgbmV4dCgpCi0gICAgewotICAgICAgaWYgKF9jdXJyZW50Tm9kZSA9PSBEVE0uTlVMTCkgewotICAgICAgICByZXR1cm4gRFRNLk5VTEw7Ci0gICAgICB9Ci0KLSAgICAgIGludCBub2RlID0gX2N1cnJlbnROb2RlOwotICAgICAgaW50IGVUeXBlOwotICAgICAgaW50IG5vZGVUeXBlID0gX25vZGVUeXBlOwotCi0gICAgICBpZiAobm9kZVR5cGUgPj0gRFRNLk5UWVBFUykgewotICAgICAgICBkbyB7Ci0gICAgICAgICAgbm9kZSA9IF9uZXh0c2liKG5vZGUpOwotICAgICAgICB9IHdoaWxlIChub2RlICE9IERUTS5OVUxMICYmIF9leHB0eXBlKG5vZGUpICE9IG5vZGVUeXBlKTsKLSAgICAgIH0gZWxzZSB7Ci0gICAgICAgIHdoaWxlICgobm9kZSA9IF9uZXh0c2liKG5vZGUpKSAhPSBEVE0uTlVMTCkgewotICAgICAgICAgIGVUeXBlID0gX2V4cHR5cGUobm9kZSk7Ci0gICAgICAgICAgaWYgKGVUeXBlIDwgRFRNLk5UWVBFUykgewotICAgICAgICAgICAgaWYgKGVUeXBlID09IG5vZGVUeXBlKSB7Ci0gICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotICAgICAgICAgIH0gZWxzZSBpZiAobV9leHBhbmRlZE5hbWVUYWJsZS5nZXRUeXBlKGVUeXBlKSA9PSBub2RlVHlwZSkgewotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICB9Ci0KLSAgICAgIF9jdXJyZW50Tm9kZSA9IG5vZGU7Ci0KLSAgICAgIHJldHVybiAoX2N1cnJlbnROb2RlID09IERUTS5OVUxMKQotICAgICAgICAgICAgICAgICAgICAgID8gRFRNLk5VTEwKLSAgICAgICAgICAgICAgICAgICAgICA6IHJldHVybk5vZGUobWFrZU5vZGVIYW5kbGUoX2N1cnJlbnROb2RlKSk7Ci0gICAgfQotICB9ICAvLyBlbmQgb2YgVHlwZWRGb2xsb3dpbmdTaWJsaW5nSXRlcmF0b3IKLQotICAvKioKLSAgICogSXRlcmF0b3IgdGhhdCByZXR1cm5zIGF0dHJpYnV0ZSBub2RlcyAob2Ygd2hhdCBub2Rlcz8pCi0gICAqLwotICBwdWJsaWMgZmluYWwgY2xhc3MgQXR0cmlidXRlSXRlcmF0b3IgZXh0ZW5kcyBJbnRlcm5hbEF4aXNJdGVyYXRvckJhc2UKLSAgewotCi0gICAgLy8gYXNzdW1lcyBjYWxsZXIgd2lsbCBwYXNzIGVsZW1lbnQgbm9kZXMKLQotICAgIC8qKgotICAgICAqIFNldCBzdGFydCB0byBFTkQgc2hvdWxkICdjbG9zZScgdGhlIGl0ZXJhdG9yLAotICAgICAqIGkuZS4gc3Vic2VxdWVudCBjYWxsIHRvIG5leHQoKSBzaG91bGQgcmV0dXJuIEVORC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBub2RlIFNldHMgdGhlIHJvb3Qgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gQSBEVE1BeGlzSXRlcmF0b3Igc2V0IHRvIHRoZSBzdGFydCBvZiB0aGUgaXRlcmF0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3Igc2V0U3RhcnROb2RlKGludCBub2RlKQotICAgIHsKLS8vJUhaJTogQWRkZWQgcmVmZXJlbmNlIHRvIERUTURlZmF1bHRCYXNlLlJPT1ROT0RFIGJhY2sgaW4sIHRlbXBvcmFyaWx5Ci0gICAgICBpZiAobm9kZSA9PSBEVE1EZWZhdWx0QmFzZS5ST09UTk9ERSkKLSAgICAgICAgbm9kZSA9IGdldERvY3VtZW50KCk7Ci0gICAgICBpZiAoX2lzUmVzdGFydGFibGUpCi0gICAgICB7Ci0gICAgICAgIF9zdGFydE5vZGUgPSBub2RlOwotICAgICAgICBfY3VycmVudE5vZGUgPSBnZXRGaXJzdEF0dHJpYnV0ZUlkZW50aXR5KG1ha2VOb2RlSWRlbnRpdHkobm9kZSkpOwotCi0gICAgICAgIHJldHVybiByZXNldFBvc2l0aW9uKCk7Ci0gICAgICB9Ci0KLSAgICAgIHJldHVybiB0aGlzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgbmV4dCBub2RlIGluIHRoZSBpdGVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBuZXh0IG5vZGUgaGFuZGxlIGluIHRoZSBpdGVyYXRpb24sIG9yIEVORC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IG5leHQoKQotICAgIHsKLQotICAgICAgZmluYWwgaW50IG5vZGUgPSBfY3VycmVudE5vZGU7Ci0KLSAgICAgIGlmIChub2RlICE9IE5VTEwpIHsKLSAgICAgICAgX2N1cnJlbnROb2RlID0gZ2V0TmV4dEF0dHJpYnV0ZUlkZW50aXR5KG5vZGUpOwotICAgICAgICByZXR1cm4gcmV0dXJuTm9kZShtYWtlTm9kZUhhbmRsZShub2RlKSk7Ci0gICAgICB9Ci0KLSAgICAgIHJldHVybiBOVUxMOwotICAgIH0KLSAgfSAgLy8gZW5kIG9mIEF0dHJpYnV0ZUl0ZXJhdG9yCi0KLSAgLyoqCi0gICAqIEl0ZXJhdG9yIHRoYXQgcmV0dXJucyBhdHRyaWJ1dGUgbm9kZXMgb2YgYSBnaXZlbiB0eXBlCi0gICAqLwotICBwdWJsaWMgZmluYWwgY2xhc3MgVHlwZWRBdHRyaWJ1dGVJdGVyYXRvciBleHRlbmRzIEludGVybmFsQXhpc0l0ZXJhdG9yQmFzZQotICB7Ci0KLSAgICAvKiogVGhlIGV4dGVuZGVkIHR5cGUgSUQgdGhhdCB3YXMgcmVxdWVzdGVkLiAqLwotICAgIHByaXZhdGUgZmluYWwgaW50IF9ub2RlVHlwZTsKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdG9yIFR5cGVkQXR0cmlidXRlSXRlcmF0b3IKLSAgICAgKgotICAgICAqCi0gICAgICogQHBhcmFtIG5vZGVUeXBlIFRoZSBleHRlbmRlZCB0eXBlIElEIHRoYXQgaXMgcmVxdWVzdGVkLgotICAgICAqLwotICAgIHB1YmxpYyBUeXBlZEF0dHJpYnV0ZUl0ZXJhdG9yKGludCBub2RlVHlwZSkKLSAgICB7Ci0gICAgICBfbm9kZVR5cGUgPSBub2RlVHlwZTsKLSAgICB9Ci0KLSAgICAvLyBhc3N1bWVzIGNhbGxlciB3aWxsIHBhc3MgZWxlbWVudCBub2RlcwotCi0gICAgLyoqCi0gICAgICogU2V0IHN0YXJ0IHRvIEVORCBzaG91bGQgJ2Nsb3NlJyB0aGUgaXRlcmF0b3IsCi0gICAgICogaS5lLiBzdWJzZXF1ZW50IGNhbGwgdG8gbmV4dCgpIHNob3VsZCByZXR1cm4gRU5ELgotICAgICAqCi0gICAgICogQHBhcmFtIG5vZGUgU2V0cyB0aGUgcm9vdCBvZiB0aGUgaXRlcmF0aW9uLgotICAgICAqCi0gICAgICogQHJldHVybiBBIERUTUF4aXNJdGVyYXRvciBzZXQgdG8gdGhlIHN0YXJ0IG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICovCi0gICAgcHVibGljIERUTUF4aXNJdGVyYXRvciBzZXRTdGFydE5vZGUoaW50IG5vZGUpCi0gICAgewotICAgICAgaWYgKF9pc1Jlc3RhcnRhYmxlKQotICAgICAgewotICAgICAgICBfc3RhcnROb2RlID0gbm9kZTsKLQotICAgICAgICBfY3VycmVudE5vZGUgPSBnZXRUeXBlZEF0dHJpYnV0ZShub2RlLCBfbm9kZVR5cGUpOwotCi0gICAgICAgIHJldHVybiByZXNldFBvc2l0aW9uKCk7Ci0gICAgICB9Ci0KLSAgICAgIHJldHVybiB0aGlzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgbmV4dCBub2RlIGluIHRoZSBpdGVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBuZXh0IG5vZGUgaGFuZGxlIGluIHRoZSBpdGVyYXRpb24sIG9yIEVORC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IG5leHQoKQotICAgIHsKLQotICAgICAgZmluYWwgaW50IG5vZGUgPSBfY3VycmVudE5vZGU7Ci0KLSAgICAgIC8vIHNpbmdsZXRvbiBpdGVyYXRvciwgc2luY2UgdGhlcmUgY2FuIG9ubHkgYmUgb25lIGF0dHJpYnV0ZSBvZgotICAgICAgLy8gYSBnaXZlbiB0eXBlLgotICAgICAgX2N1cnJlbnROb2RlID0gTlVMTDsKLQotICAgICAgcmV0dXJuIHJldHVybk5vZGUobm9kZSk7Ci0gICAgfQotICB9ICAvLyBlbmQgb2YgVHlwZWRBdHRyaWJ1dGVJdGVyYXRvcgotCi0gIC8qKgotICAgKiBJdGVyYXRvciB0aGF0IHJldHVybnMgcHJlY2VkaW5nIHNpYmxpbmdzIG9mIGEgZ2l2ZW4gbm9kZQotICAgKi8KLSAgcHVibGljIGNsYXNzIFByZWNlZGluZ1NpYmxpbmdJdGVyYXRvciBleHRlbmRzIEludGVybmFsQXhpc0l0ZXJhdG9yQmFzZQotICB7Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgbm9kZSBpZGVudGl0eSBvZiBfc3RhcnROb2RlIGZvciB0aGlzIGl0ZXJhdG9yCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGludCBfc3RhcnROb2RlSUQ7Ci0KLSAgICAvKioKLSAgICAgKiBUcnVlIGlmIHRoaXMgaXRlcmF0b3IgaGFzIGEgcmV2ZXJzZWQgYXhpcy4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdHJ1ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc1JldmVyc2UoKQotICAgIHsKLSAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldCBzdGFydCB0byBFTkQgc2hvdWxkICdjbG9zZScgdGhlIGl0ZXJhdG9yLAotICAgICAqIGkuZS4gc3Vic2VxdWVudCBjYWxsIHRvIG5leHQoKSBzaG91bGQgcmV0dXJuIEVORC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBub2RlIFNldHMgdGhlIHJvb3Qgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gQSBEVE1BeGlzSXRlcmF0b3Igc2V0IHRvIHRoZSBzdGFydCBvZiB0aGUgaXRlcmF0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3Igc2V0U3RhcnROb2RlKGludCBub2RlKQotICAgIHsKLS8vJUhaJTogQWRkZWQgcmVmZXJlbmNlIHRvIERUTURlZmF1bHRCYXNlLlJPT1ROT0RFIGJhY2sgaW4sIHRlbXBvcmFyaWx5Ci0gICAgICBpZiAobm9kZSA9PSBEVE1EZWZhdWx0QmFzZS5ST09UTk9ERSkKLSAgICAgICAgbm9kZSA9IGdldERvY3VtZW50KCk7Ci0gICAgICBpZiAoX2lzUmVzdGFydGFibGUpCi0gICAgICB7Ci0gICAgICAgIF9zdGFydE5vZGUgPSBub2RlOwotICAgICAgICBub2RlID0gX3N0YXJ0Tm9kZUlEID0gbWFrZU5vZGVJZGVudGl0eShub2RlKTsKLQotICAgICAgICBpZihub2RlID09IE5VTEwpCi0gICAgICAgIHsKLSAgICAgICAgICBfY3VycmVudE5vZGUgPSBub2RlOwotICAgICAgICAgIHJldHVybiByZXNldFBvc2l0aW9uKCk7Ci0gICAgICAgIH0KLQotICAgICAgICBpbnQgdHlwZSA9IG1fZXhwYW5kZWROYW1lVGFibGUuZ2V0VHlwZShfZXhwdHlwZShub2RlKSk7Ci0gICAgICAgIGlmKEV4cGFuZGVkTmFtZVRhYmxlLkFUVFJJQlVURSA9PSB0eXBlCi0gICAgICAgICAgIHx8IEV4cGFuZGVkTmFtZVRhYmxlLk5BTUVTUEFDRSA9PSB0eXBlICkKLSAgICAgICAgewotICAgICAgICAgIF9jdXJyZW50Tm9kZSA9IG5vZGU7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICB7Ci0gICAgICAgICAgLy8gQmUgY2FyZWZ1bCB0byBoYW5kbGUgdGhlIERvY3VtZW50IG5vZGUgcHJvcGVybHkKLSAgICAgICAgICBfY3VycmVudE5vZGUgPSBfcGFyZW50KG5vZGUpOwotICAgICAgICAgIGlmKE5VTEwhPV9jdXJyZW50Tm9kZSkKLSAgICAgICAgICAgIF9jdXJyZW50Tm9kZSA9IF9maXJzdGNoKF9jdXJyZW50Tm9kZSk7Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgICAgX2N1cnJlbnROb2RlID0gbm9kZTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiByZXNldFBvc2l0aW9uKCk7Ci0gICAgICB9Ci0KLSAgICAgIHJldHVybiB0aGlzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgbmV4dCBub2RlIGluIHRoZSBpdGVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBuZXh0IG5vZGUgaGFuZGxlIGluIHRoZSBpdGVyYXRpb24sIG9yIEVORC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IG5leHQoKQotICAgIHsKLQotICAgICAgaWYgKF9jdXJyZW50Tm9kZSA9PSBfc3RhcnROb2RlSUQgfHwgX2N1cnJlbnROb2RlID09IERUTS5OVUxMKQotICAgICAgewotICAgICAgICByZXR1cm4gTlVMTDsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgZmluYWwgaW50IG5vZGUgPSBfY3VycmVudE5vZGU7Ci0gICAgICAgIF9jdXJyZW50Tm9kZSA9IF9uZXh0c2liKG5vZGUpOwotCi0gICAgICAgIHJldHVybiByZXR1cm5Ob2RlKG1ha2VOb2RlSGFuZGxlKG5vZGUpKTsKLSAgICAgIH0KLSAgICB9Ci0gIH0gIC8vIGVuZCBvZiBQcmVjZWRpbmdTaWJsaW5nSXRlcmF0b3IKLQotICAvKioKLSAgICogSXRlcmF0b3IgdGhhdCByZXR1cm5zIHByZWNlZGluZyBzaWJsaW5ncyBvZiBhIGdpdmVuIHR5cGUgZm9yCi0gICAqIGEgZ2l2ZW4gbm9kZQotICAgKi8KLSAgcHVibGljIGZpbmFsIGNsYXNzIFR5cGVkUHJlY2VkaW5nU2libGluZ0l0ZXJhdG9yCi0gICAgICAgICAgZXh0ZW5kcyBQcmVjZWRpbmdTaWJsaW5nSXRlcmF0b3IKLSAgewotCi0gICAgLyoqIFRoZSBleHRlbmRlZCB0eXBlIElEIHRoYXQgd2FzIHJlcXVlc3RlZC4gKi8KLSAgICBwcml2YXRlIGZpbmFsIGludCBfbm9kZVR5cGU7Ci0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RvciBUeXBlZFByZWNlZGluZ1NpYmxpbmdJdGVyYXRvcgotICAgICAqCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdHlwZSBUaGUgZXh0ZW5kZWQgdHlwZSBJRCBiZWluZyByZXF1ZXN0ZWQuCi0gICAgICovCi0gICAgcHVibGljIFR5cGVkUHJlY2VkaW5nU2libGluZ0l0ZXJhdG9yKGludCB0eXBlKQotICAgIHsKLSAgICAgIF9ub2RlVHlwZSA9IHR5cGU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBuZXh0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIG5leHQgbm9kZSBoYW5kbGUgaW4gdGhlIGl0ZXJhdGlvbiwgb3IgRU5ELgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgbmV4dCgpCi0gICAgewotICAgICAgaW50IG5vZGUgPSBfY3VycmVudE5vZGU7Ci0gICAgICBpbnQgZXhwVHlwZTsKLQotICAgICAgaW50IG5vZGVUeXBlID0gX25vZGVUeXBlOwotICAgICAgaW50IHN0YXJ0SUQgPSBfc3RhcnROb2RlSUQ7Ci0KLSAgICAgIGlmIChub2RlVHlwZSA+PSBEVE0uTlRZUEVTKSB7Ci0gICAgICAgIHdoaWxlIChub2RlICE9IE5VTEwgJiYgbm9kZSAhPSBzdGFydElEICYmIF9leHB0eXBlKG5vZGUpICE9IG5vZGVUeXBlKSB7Ci0gICAgICAgICAgbm9kZSA9IF9uZXh0c2liKG5vZGUpOwotICAgICAgICB9Ci0gICAgICB9IGVsc2UgewotICAgICAgICB3aGlsZSAobm9kZSAhPSBOVUxMICYmIG5vZGUgIT0gc3RhcnRJRCkgewotICAgICAgICAgIGV4cFR5cGUgPSBfZXhwdHlwZShub2RlKTsKLSAgICAgICAgICBpZiAoZXhwVHlwZSA8IERUTS5OVFlQRVMpIHsKLSAgICAgICAgICAgIGlmIChleHBUeXBlID09IG5vZGVUeXBlKSB7Ci0gICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBpZiAobV9leHBhbmRlZE5hbWVUYWJsZS5nZXRUeXBlKGV4cFR5cGUpID09IG5vZGVUeXBlKSB7Ci0gICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotICAgICAgICAgIH0KLSAgICAgICAgICBub2RlID0gX25leHRzaWIobm9kZSk7Ci0gICAgICAgIH0KLSAgICAgIH0KLQotICAgICAgaWYgKG5vZGUgPT0gRFRNLk5VTEwgfHwgbm9kZSA9PSBfc3RhcnROb2RlSUQpIHsKLSAgICAgICAgX2N1cnJlbnROb2RlID0gTlVMTDsKLSAgICAgICAgcmV0dXJuIE5VTEw7Ci0gICAgICB9IGVsc2UgewotICAgICAgICBfY3VycmVudE5vZGUgPSBfbmV4dHNpYihub2RlKTsKLSAgICAgICAgcmV0dXJuIHJldHVybk5vZGUobWFrZU5vZGVIYW5kbGUobm9kZSkpOwotICAgICAgfQotICAgIH0KLSAgfSAgLy8gZW5kIG9mIFR5cGVkUHJlY2VkaW5nU2libGluZ0l0ZXJhdG9yCi0KLSAgLyoqCi0gICAqIEl0ZXJhdG9yIHRoYXQgcmV0dXJucyBwcmVjZWRpbmcgbm9kZXMgb2YgYSBnaXZlbiBub2RlLgotICAgKiBUaGlzIGluY2x1ZGVzIHRoZSBub2RlIHNldCB7cm9vdCsxLCBzdGFydC0xfSwgYnV0IGV4Y2x1ZGVzCi0gICAqIGFsbCBhbmNlc3RvcnMsIGF0dHJpYnV0ZXMsIGFuZCBuYW1lc3BhY2Ugbm9kZXMuCi0gICAqLwotICBwdWJsaWMgY2xhc3MgUHJlY2VkaW5nSXRlcmF0b3IgZXh0ZW5kcyBJbnRlcm5hbEF4aXNJdGVyYXRvckJhc2UKLSAgewotCi0gICAgLyoqIFRoZSBtYXggYW5jZXN0b3JzLCBidXQgaXQgY2FuIGdyb3cuLi4gKi8KLSAgICBwcml2YXRlIGZpbmFsIGludCBfbWF4QW5jZXN0b3JzID0gODsKLQotICAgIC8qKgotICAgICAqIFRoZSBzdGFjayBvZiBzdGFydCBub2RlICsgYW5jZXN0b3JzIHVwIHRvIHRoZSByb290IG9mIHRoZSB0cmVlLAotICAgICAqICB3aGljaCB3ZSBtdXN0IGF2b2lkLgotICAgICAqLwotICAgIHByb3RlY3RlZCBpbnRbXSBfc3RhY2sgPSBuZXcgaW50W19tYXhBbmNlc3RvcnNdOwotCi0gICAgLyoqIChub3Qgc3VyZSB5ZXQuLi4gLXNiKSAqLwotICAgIHByb3RlY3RlZCBpbnQgX3NwLCBfb2xkc3A7Ci0KLSAgICBwcm90ZWN0ZWQgaW50IF9tYXJrZWRzcCwgX21hcmtlZE5vZGUsIF9tYXJrZWREZXNjZW5kYW50OwotCi0gICAgLyogX2N1cnJlbnROb2RlIHByZWNlZGVzIGNhbmRpZGF0ZXMuICBUaGlzIGlzIHRoZSBpZGVudGl0eSwgbm90IHRoZSBoYW5kbGUhICovCi0KLSAgICAvKioKLSAgICAgKiBUcnVlIGlmIHRoaXMgaXRlcmF0b3IgaGFzIGEgcmV2ZXJzZWQgYXhpcy4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdHJ1ZSBzaW5jZSB0aGlzIGl0ZXJhdG9yIGlzIGEgcmV2ZXJzZWQgYXhpcy4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc1JldmVyc2UoKQotICAgIHsKLSAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYSBkZWVwIGNvcHkgb2YgdGhpcyBpdGVyYXRvci4gICBUaGUgY2xvbmVkIGl0ZXJhdG9yIGlzIG5vdCByZXNldC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gYSBkZWVwIGNvcHkgb2YgdGhpcyBpdGVyYXRvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIGNsb25lSXRlcmF0b3IoKQotICAgIHsKLSAgICAgIF9pc1Jlc3RhcnRhYmxlID0gZmFsc2U7Ci0KLSAgICAgIHRyeQotICAgICAgewotICAgICAgICBmaW5hbCBQcmVjZWRpbmdJdGVyYXRvciBjbG9uZSA9IChQcmVjZWRpbmdJdGVyYXRvcikgc3VwZXIuY2xvbmUoKTsKLSAgICAgICAgZmluYWwgaW50W10gc3RhY2tDb3B5ID0gbmV3IGludFtfc3RhY2subGVuZ3RoXTsKLSAgICAgICAgU3lzdGVtLmFycmF5Y29weShfc3RhY2ssIDAsIHN0YWNrQ29weSwgMCwgX3N0YWNrLmxlbmd0aCk7Ci0KLSAgICAgICAgY2xvbmUuX3N0YWNrID0gc3RhY2tDb3B5OwotCi0gICAgICAgIC8vIHJldHVybiBjbG9uZS5yZXNldCgpOwotICAgICAgICByZXR1cm4gY2xvbmU7Ci0gICAgICB9Ci0gICAgICBjYXRjaCAoQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gZSkKLSAgICAgIHsKLSAgICAgICAgdGhyb3cgbmV3IERUTUV4Y2VwdGlvbihYTUxNZXNzYWdlcy5jcmVhdGVYTUxNZXNzYWdlKFhNTEVycm9yUmVzb3VyY2VzLkVSX0lURVJBVE9SX0NMT05FX05PVF9TVVBQT1JURUQsIG51bGwpKTsgLy8iSXRlcmF0b3IgY2xvbmUgbm90IHN1cHBvcnRlZC4iKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgc3RhcnQgdG8gRU5EIHNob3VsZCAnY2xvc2UnIHRoZSBpdGVyYXRvciwKLSAgICAgKiBpLmUuIHN1YnNlcXVlbnQgY2FsbCB0byBuZXh0KCkgc2hvdWxkIHJldHVybiBFTkQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbm9kZSBTZXRzIHRoZSByb290IG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIEEgRFRNQXhpc0l0ZXJhdG9yIHNldCB0byB0aGUgc3RhcnQgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIHNldFN0YXJ0Tm9kZShpbnQgbm9kZSkKLSAgICB7Ci0vLyVIWiU6IEFkZGVkIHJlZmVyZW5jZSB0byBEVE1EZWZhdWx0QmFzZS5ST09UTk9ERSBiYWNrIGluLCB0ZW1wb3JhcmlseQotICAgICAgaWYgKG5vZGUgPT0gRFRNRGVmYXVsdEJhc2UuUk9PVE5PREUpCi0gICAgICAgIG5vZGUgPSBnZXREb2N1bWVudCgpOwotICAgICAgaWYgKF9pc1Jlc3RhcnRhYmxlKQotICAgICAgewotICAgICAgICBub2RlID0gbWFrZU5vZGVJZGVudGl0eShub2RlKTsKLQotICAgICAgICAvLyBpdGVyYXRvciBpcyBub3QgYSBjbG9uZQotICAgICAgICBpbnQgcGFyZW50LCBpbmRleDsKLQotICAgICAgIGlmIChfdHlwZShub2RlKSA9PSBEVE0uQVRUUklCVVRFX05PREUpCi0gICAgICAgIG5vZGUgPSBfcGFyZW50KG5vZGUpOwotCi0gICAgICAgIF9zdGFydE5vZGUgPSBub2RlOwotICAgICAgICBfc3RhY2tbaW5kZXggPSAwXSA9IG5vZGU7Ci0KLQotCi0gICAgICAgICAgICAgICAgcGFyZW50PW5vZGU7Ci0gICAgICAgICAgICAgICAgd2hpbGUgKChwYXJlbnQgPSBfcGFyZW50KHBhcmVudCkpICE9IE5VTEwpCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCsraW5kZXggPT0gX3N0YWNrLmxlbmd0aCkKLSAgICAgICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50W10gc3RhY2sgPSBuZXcgaW50W2luZGV4ICsgNF07Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoX3N0YWNrLCAwLCBzdGFjaywgMCwgaW5kZXgpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfc3RhY2sgPSBzdGFjazsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIF9zdGFja1tpbmRleF0gPSBwYXJlbnQ7Ci0gICAgICAgIH0KLSAgICAgICAgaWYoaW5kZXg+MCkKLSAgICAgICAgICAgICAgICAtLWluZGV4OyAvLyBQb3AgYWN0dWFsIHJvb3Qgbm9kZSAoaWYgbm90IHN0YXJ0KSBiYWNrIG9mZiB0aGUgc3RhY2sKLQotICAgICAgICBfY3VycmVudE5vZGU9X3N0YWNrW2luZGV4XTsgLy8gTGFzdCBwYXJlbnQgYmVmb3JlIHJvb3Qgbm9kZQotCi0gICAgICAgIF9vbGRzcCA9IF9zcCA9IGluZGV4OwotCi0gICAgICAgIHJldHVybiByZXNldFBvc2l0aW9uKCk7Ci0gICAgICB9Ci0KLSAgICAgIHJldHVybiB0aGlzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgbmV4dCBub2RlIGluIHRoZSBpdGVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBuZXh0IG5vZGUgaGFuZGxlIGluIHRoZSBpdGVyYXRpb24sIG9yIEVORC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IG5leHQoKQotICAgIHsKLSAgICAgICAgLy8gQnVnemlsbGEgODMyNDogV2Ugd2VyZSBmb3JnZXR0aW5nIHRvIHNraXAgQXR0cnMgYW5kIE5TIG5vZGVzLgotICAgICAgICAvLyBBbHNvIHJlY29kZWQgdGhlIGxvb3AgY29udHJvbHMgZm9yIGNsYXJpdHkgYW5kIHRvIGZsYXR0ZW4gb3V0Ci0gICAgICAgIC8vIHRoZSB0YWlsLXJlY3Vyc2lvbi4KLSAgICAgICAgICAgICAgICBmb3IoKytfY3VycmVudE5vZGU7Ci0gICAgICAgICAgICAgICAgICAgICAgICBfc3A+PTA7Ci0gICAgICAgICAgICAgICAgICAgICAgICArK19jdXJyZW50Tm9kZSkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZihfY3VycmVudE5vZGUgPCBfc3RhY2tbX3NwXSkKLSAgICAgICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoX3R5cGUoX2N1cnJlbnROb2RlKSAhPSBBVFRSSUJVVEVfTk9ERSAmJgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF90eXBlKF9jdXJyZW50Tm9kZSkgIT0gTkFNRVNQQUNFX05PREUpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJldHVybk5vZGUobWFrZU5vZGVIYW5kbGUoX2N1cnJlbnROb2RlKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0tX3NwOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKLSAgICB9Ci0KLSAgICAvLyByZWRlZmluZSBEVE1BeGlzSXRlcmF0b3JCYXNlJ3MgcmVzZXQKLQotICAgIC8qKgotICAgICAqIFJlc2V0cyB0aGUgaXRlcmF0b3IgdG8gdGhlIGxhc3Qgc3RhcnQgbm9kZS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gQSBEVE1BeGlzSXRlcmF0b3IsIHdoaWNoIG1heSBvciBtYXkgbm90IGJlIHRoZSBzYW1lIGFzIHRoaXMKLSAgICAgKiAgICAgICAgIGl0ZXJhdG9yLgotICAgICAqLwotICAgIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3IgcmVzZXQoKQotICAgIHsKLQotICAgICAgX3NwID0gX29sZHNwOwotCi0gICAgICByZXR1cm4gcmVzZXRQb3NpdGlvbigpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldE1hcmsoKSB7Ci0gICAgICAgIF9tYXJrZWRzcCA9IF9zcDsKLSAgICAgICAgX21hcmtlZE5vZGUgPSBfY3VycmVudE5vZGU7Ci0gICAgICAgIF9tYXJrZWREZXNjZW5kYW50ID0gX3N0YWNrWzBdOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGdvdG9NYXJrKCkgewotICAgICAgICBfc3AgPSBfbWFya2Vkc3A7Ci0gICAgICAgIF9jdXJyZW50Tm9kZSA9IF9tYXJrZWROb2RlOwotICAgIH0KLSAgfSAgLy8gZW5kIG9mIFByZWNlZGluZ0l0ZXJhdG9yCi0KLSAgLyoqCi0gICAqIEl0ZXJhdG9yIHRoYXQgcmV0dXJucyBwcmVjZWRpbmcgbm9kZXMgb2YgYWdpdmVuIHR5cGUgZm9yIGEKLSAgICogZ2l2ZW4gbm9kZS4gVGhpcyBpbmNsdWRlcyB0aGUgbm9kZSBzZXQge3Jvb3QrMSwgc3RhcnQtMX0sIGJ1dAotICAgKiBleGNsdWRlcyBhbGwgYW5jZXN0b3JzLgotICAgKi8KLSAgcHVibGljIGZpbmFsIGNsYXNzIFR5cGVkUHJlY2VkaW5nSXRlcmF0b3IgZXh0ZW5kcyBQcmVjZWRpbmdJdGVyYXRvcgotICB7Ci0KLSAgICAvKiogVGhlIGV4dGVuZGVkIHR5cGUgSUQgdGhhdCB3YXMgcmVxdWVzdGVkLiAqLwotICAgIHByaXZhdGUgZmluYWwgaW50IF9ub2RlVHlwZTsKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdG9yIFR5cGVkUHJlY2VkaW5nSXRlcmF0b3IKLSAgICAgKgotICAgICAqCi0gICAgICogQHBhcmFtIHR5cGUgVGhlIGV4dGVuZGVkIHR5cGUgSUQgYmVpbmcgcmVxdWVzdGVkLgotICAgICAqLwotICAgIHB1YmxpYyBUeXBlZFByZWNlZGluZ0l0ZXJhdG9yKGludCB0eXBlKQotICAgIHsKLSAgICAgIF9ub2RlVHlwZSA9IHR5cGU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBuZXh0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIG5leHQgbm9kZSBoYW5kbGUgaW4gdGhlIGl0ZXJhdGlvbiwgb3IgRU5ELgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgbmV4dCgpCi0gICAgewotICAgICAgaW50IG5vZGUgPSBfY3VycmVudE5vZGU7Ci0gICAgICBpbnQgbm9kZVR5cGUgPSBfbm9kZVR5cGU7Ci0KLSAgICAgIGlmIChub2RlVHlwZSA+PSBEVE0uTlRZUEVTKSB7Ci0gICAgICAgIHdoaWxlICh0cnVlKSB7Ci0gICAgICAgICAgbm9kZSA9IG5vZGUgKyAxOwotCi0gICAgICAgICAgaWYgKF9zcCA8IDApIHsKLSAgICAgICAgICAgIG5vZGUgPSBOVUxMOwotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgfSBlbHNlIGlmIChub2RlID49IF9zdGFja1tfc3BdKSB7Ci0gICAgICAgICAgICBpZiAoLS1fc3AgPCAwKSB7Ci0gICAgICAgICAgICAgIG5vZGUgPSBOVUxMOwotICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICB9IGVsc2UgaWYgKF9leHB0eXBlKG5vZGUpID09IG5vZGVUeXBlKSB7Ci0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgIH0gZWxzZSB7Ci0gICAgICAgIGludCBleHBUeXBlOwotCi0gICAgICAgIHdoaWxlICh0cnVlKSB7Ci0gICAgICAgICAgbm9kZSA9IG5vZGUgKyAxOwotCi0gICAgICAgICAgaWYgKF9zcCA8IDApIHsKLSAgICAgICAgICAgIG5vZGUgPSBOVUxMOwotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgfSBlbHNlIGlmIChub2RlID49IF9zdGFja1tfc3BdKSB7Ci0gICAgICAgICAgICBpZiAoLS1fc3AgPCAwKSB7Ci0gICAgICAgICAgICAgIG5vZGUgPSBOVUxMOwotICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgZXhwVHlwZSA9IF9leHB0eXBlKG5vZGUpOwotICAgICAgICAgICAgaWYgKGV4cFR5cGUgPCBEVE0uTlRZUEVTKSB7Ci0gICAgICAgICAgICAgIGlmIChleHBUeXBlID09IG5vZGVUeXBlKSB7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgIGlmIChtX2V4cGFuZGVkTmFtZVRhYmxlLmdldFR5cGUoZXhwVHlwZSkgPT0gbm9kZVR5cGUpIHsKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgfQotCi0gICAgICBfY3VycmVudE5vZGUgPSBub2RlOwotCi0gICAgICByZXR1cm4gKG5vZGUgPT0gTlVMTCkgPyBOVUxMIDogcmV0dXJuTm9kZShtYWtlTm9kZUhhbmRsZShub2RlKSk7Ci0gICAgfQotICB9ICAvLyBlbmQgb2YgVHlwZWRQcmVjZWRpbmdJdGVyYXRvcgotCi0gIC8qKgotICAgKiBJdGVyYXRvciB0aGF0IHJldHVybnMgZm9sbG93aW5nIG5vZGVzIG9mIGZvciBhIGdpdmVuIG5vZGUuCi0gICAqLwotICBwdWJsaWMgY2xhc3MgRm9sbG93aW5nSXRlcmF0b3IgZXh0ZW5kcyBJbnRlcm5hbEF4aXNJdGVyYXRvckJhc2UKLSAgewotICAgIERUTUF4aXNUcmF2ZXJzZXIgbV90cmF2ZXJzZXI7IC8vIGVhc2llciBmb3Igbm93Ci0KLSAgICBwdWJsaWMgRm9sbG93aW5nSXRlcmF0b3IoKQotICAgIHsKLSAgICAgIG1fdHJhdmVyc2VyID0gZ2V0QXhpc1RyYXZlcnNlcihBeGlzLkZPTExPV0lORyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0IHN0YXJ0IHRvIEVORCBzaG91bGQgJ2Nsb3NlJyB0aGUgaXRlcmF0b3IsCi0gICAgICogaS5lLiBzdWJzZXF1ZW50IGNhbGwgdG8gbmV4dCgpIHNob3VsZCByZXR1cm4gRU5ELgotICAgICAqCi0gICAgICogQHBhcmFtIG5vZGUgU2V0cyB0aGUgcm9vdCBvZiB0aGUgaXRlcmF0aW9uLgotICAgICAqCi0gICAgICogQHJldHVybiBBIERUTUF4aXNJdGVyYXRvciBzZXQgdG8gdGhlIHN0YXJ0IG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICovCi0gICAgcHVibGljIERUTUF4aXNJdGVyYXRvciBzZXRTdGFydE5vZGUoaW50IG5vZGUpCi0gICAgewotLy8lSFolOiBBZGRlZCByZWZlcmVuY2UgdG8gRFRNRGVmYXVsdEJhc2UuUk9PVE5PREUgYmFjayBpbiwgdGVtcG9yYXJpbHkKLSAgICAgIGlmIChub2RlID09IERUTURlZmF1bHRCYXNlLlJPT1ROT0RFKQotICAgICAgICBub2RlID0gZ2V0RG9jdW1lbnQoKTsKLSAgICAgIGlmIChfaXNSZXN0YXJ0YWJsZSkKLSAgICAgIHsKLSAgICAgICAgX3N0YXJ0Tm9kZSA9IG5vZGU7Ci0KLSAgICAgICAgLy8gPz8gLXNiCi0gICAgICAgIC8vIGZpbmQgcmlnaHRtb3N0IGRlc2NlbmRhbnQgKG9yIHNlbGYpCi0gICAgICAgIC8vIGludCBjdXJyZW50OwotICAgICAgICAvLyB3aGlsZSAoKG5vZGUgPSBnZXRMYXN0Q2hpbGQoY3VycmVudCA9IG5vZGUpKSAhPSBOVUxMKXt9Ci0gICAgICAgIC8vIF9jdXJyZW50Tm9kZSA9IGN1cnJlbnQ7Ci0gICAgICAgIF9jdXJyZW50Tm9kZSA9IG1fdHJhdmVyc2VyLmZpcnN0KG5vZGUpOwotCi0gICAgICAgIC8vIF9jdXJyZW50Tm9kZSBwcmVjZWRlcyBwb3NzaWJsZSBmb2xsb3dpbmcobm9kZSkgbm9kZXMKLSAgICAgICAgcmV0dXJuIHJlc2V0UG9zaXRpb24oKTsKLSAgICAgIH0KLQotICAgICAgcmV0dXJuIHRoaXM7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBuZXh0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIG5leHQgbm9kZSBoYW5kbGUgaW4gdGhlIGl0ZXJhdGlvbiwgb3IgRU5ELgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgbmV4dCgpCi0gICAgewotCi0gICAgICBpbnQgbm9kZSA9IF9jdXJyZW50Tm9kZTsKLQotICAgICAgX2N1cnJlbnROb2RlID0gbV90cmF2ZXJzZXIubmV4dChfc3RhcnROb2RlLCBfY3VycmVudE5vZGUpOwotCi0gICAgICByZXR1cm4gcmV0dXJuTm9kZShub2RlKTsKLSAgICB9Ci0gIH0gIC8vIGVuZCBvZiBGb2xsb3dpbmdJdGVyYXRvcgotCi0gIC8qKgotICAgKiBJdGVyYXRvciB0aGF0IHJldHVybnMgZm9sbG93aW5nIG5vZGVzIG9mIGEgZ2l2ZW4gdHlwZSBmb3IgYSBnaXZlbiBub2RlLgotICAgKi8KLSAgcHVibGljIGZpbmFsIGNsYXNzIFR5cGVkRm9sbG93aW5nSXRlcmF0b3IgZXh0ZW5kcyBGb2xsb3dpbmdJdGVyYXRvcgotICB7Ci0KLSAgICAvKiogVGhlIGV4dGVuZGVkIHR5cGUgSUQgdGhhdCB3YXMgcmVxdWVzdGVkLiAqLwotICAgIHByaXZhdGUgZmluYWwgaW50IF9ub2RlVHlwZTsKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdG9yIFR5cGVkRm9sbG93aW5nSXRlcmF0b3IKLSAgICAgKgotICAgICAqCi0gICAgICogQHBhcmFtIHR5cGUgVGhlIGV4dGVuZGVkIHR5cGUgSUQgYmVpbmcgcmVxdWVzdGVkLgotICAgICAqLwotICAgIHB1YmxpYyBUeXBlZEZvbGxvd2luZ0l0ZXJhdG9yKGludCB0eXBlKQotICAgIHsKLSAgICAgIF9ub2RlVHlwZSA9IHR5cGU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBuZXh0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIG5leHQgbm9kZSBoYW5kbGUgaW4gdGhlIGl0ZXJhdGlvbiwgb3IgRU5ELgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgbmV4dCgpCi0gICAgewotCi0gICAgICBpbnQgbm9kZTsKLQotICAgICAgZG97Ci0gICAgICAgbm9kZSA9IF9jdXJyZW50Tm9kZTsKLQotICAgICAgX2N1cnJlbnROb2RlID0gbV90cmF2ZXJzZXIubmV4dChfc3RhcnROb2RlLCBfY3VycmVudE5vZGUpOwotCi0gICAgICB9Ci0gICAgICB3aGlsZSAobm9kZSAhPSBEVE0uTlVMTAotICAgICAgICAgICAgICYmIChnZXRFeHBhbmRlZFR5cGVJRChub2RlKSAhPSBfbm9kZVR5cGUgJiYgZ2V0Tm9kZVR5cGUobm9kZSkgIT0gX25vZGVUeXBlKSk7Ci0KLSAgICAgIHJldHVybiAobm9kZSA9PSBEVE0uTlVMTCA/IERUTS5OVUxMIDpyZXR1cm5Ob2RlKG5vZGUpKTsKLSAgICB9Ci0gIH0gIC8vIGVuZCBvZiBUeXBlZEZvbGxvd2luZ0l0ZXJhdG9yCi0KLSAgLyoqCi0gICAqIEl0ZXJhdG9yIHRoYXQgcmV0dXJucyB0aGUgYW5jZXN0b3JzIG9mIGEgZ2l2ZW4gbm9kZSBpbiBkb2N1bWVudAotICAgKiBvcmRlci4gIChOT1RFISAgVGhpcyB3YXMgY2hhbmdlZCBmcm9tIHRoZSBYU0xUQyBjb2RlISkKLSAgICovCi0gIHB1YmxpYyBjbGFzcyBBbmNlc3Rvckl0ZXJhdG9yIGV4dGVuZHMgSW50ZXJuYWxBeGlzSXRlcmF0b3JCYXNlCi0gIHsKLSAgICBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLk5vZGVWZWN0b3IgbV9hbmNlc3RvcnMgPQotICAgICAgICAgbmV3IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuTm9kZVZlY3RvcigpOwotCi0gICAgaW50IG1fYW5jZXN0b3JzUG9zOwotCi0gICAgaW50IG1fbWFya2VkUG9zOwotCi0gICAgLyoqIFRoZSByZWFsIHN0YXJ0IG5vZGUgZm9yIHRoaXMgYXhlcywgc2luY2UgX3N0YXJ0Tm9kZSB3aWxsIGJlIGFkanVzdGVkLiAqLwotICAgIGludCBtX3JlYWxTdGFydE5vZGU7Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgc3RhcnQgdG8gRU5EIHNob3VsZCAnY2xvc2UnIHRoZSBpdGVyYXRvciwKLSAgICAgKiBpLmUuIHN1YnNlcXVlbnQgY2FsbCB0byBuZXh0KCkgc2hvdWxkIHJldHVybiBFTkQuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSByb290IG5vZGUgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldFN0YXJ0Tm9kZSgpCi0gICAgewotICAgICAgcmV0dXJuIG1fcmVhbFN0YXJ0Tm9kZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcnVlIGlmIHRoaXMgaXRlcmF0b3IgaGFzIGEgcmV2ZXJzZWQgYXhpcy4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdHJ1ZSBzaW5jZSB0aGlzIGl0ZXJhdG9yIGlzIGEgcmV2ZXJzZWQgYXhpcy4KLSAgICAgKi8KLSAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc1JldmVyc2UoKQotICAgIHsKLSAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYSBkZWVwIGNvcHkgb2YgdGhpcyBpdGVyYXRvci4gIFRoZSBjbG9uZWQgaXRlcmF0b3IgaXMgbm90IHJlc2V0LgotICAgICAqCi0gICAgICogQHJldHVybiBhIGRlZXAgY29weSBvZiB0aGlzIGl0ZXJhdG9yLgotICAgICAqLwotICAgIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3IgY2xvbmVJdGVyYXRvcigpCi0gICAgewotICAgICAgX2lzUmVzdGFydGFibGUgPSBmYWxzZTsgIC8vIG11c3Qgc2V0IHRvIGZhbHNlIGZvciBhbnkgY2xvbmUKLQotICAgICAgdHJ5Ci0gICAgICB7Ci0gICAgICAgIGZpbmFsIEFuY2VzdG9ySXRlcmF0b3IgY2xvbmUgPSAoQW5jZXN0b3JJdGVyYXRvcikgc3VwZXIuY2xvbmUoKTsKLQotICAgICAgICBjbG9uZS5fc3RhcnROb2RlID0gX3N0YXJ0Tm9kZTsKLQotICAgICAgICAvLyByZXR1cm4gY2xvbmUucmVzZXQoKTsKLSAgICAgICAgcmV0dXJuIGNsb25lOwotICAgICAgfQotICAgICAgY2F0Y2ggKENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGUpCi0gICAgICB7Ci0gICAgICAgIHRocm93IG5ldyBEVE1FeGNlcHRpb24oWE1MTWVzc2FnZXMuY3JlYXRlWE1MTWVzc2FnZShYTUxFcnJvclJlc291cmNlcy5FUl9JVEVSQVRPUl9DTE9ORV9OT1RfU1VQUE9SVEVELCBudWxsKSk7IC8vIkl0ZXJhdG9yIGNsb25lIG5vdCBzdXBwb3J0ZWQuIik7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0IHN0YXJ0IHRvIEVORCBzaG91bGQgJ2Nsb3NlJyB0aGUgaXRlcmF0b3IsCi0gICAgICogaS5lLiBzdWJzZXF1ZW50IGNhbGwgdG8gbmV4dCgpIHNob3VsZCByZXR1cm4gRU5ELgotICAgICAqCi0gICAgICogQHBhcmFtIG5vZGUgU2V0cyB0aGUgcm9vdCBvZiB0aGUgaXRlcmF0aW9uLgotICAgICAqCi0gICAgICogQHJldHVybiBBIERUTUF4aXNJdGVyYXRvciBzZXQgdG8gdGhlIHN0YXJ0IG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICovCi0gICAgcHVibGljIERUTUF4aXNJdGVyYXRvciBzZXRTdGFydE5vZGUoaW50IG5vZGUpCi0gICAgewotLy8lSFolOiBBZGRlZCByZWZlcmVuY2UgdG8gRFRNRGVmYXVsdEJhc2UuUk9PVE5PREUgYmFjayBpbiwgdGVtcG9yYXJpbHkKLSAgICAgIGlmIChub2RlID09IERUTURlZmF1bHRCYXNlLlJPT1ROT0RFKQotICAgICAgICBub2RlID0gZ2V0RG9jdW1lbnQoKTsKLSAgICAgIG1fcmVhbFN0YXJ0Tm9kZSA9IG5vZGU7Ci0KLSAgICAgIGlmIChfaXNSZXN0YXJ0YWJsZSkKLSAgICAgIHsKLSAgICAgICAgaW50IG5vZGVJRCA9IG1ha2VOb2RlSWRlbnRpdHkobm9kZSk7Ci0KLSAgICAgICAgaWYgKCFfaW5jbHVkZVNlbGYgJiYgbm9kZSAhPSBEVE0uTlVMTCkgewotICAgICAgICAgIG5vZGVJRCA9IF9wYXJlbnQobm9kZUlEKTsKLSAgICAgICAgICBub2RlID0gbWFrZU5vZGVIYW5kbGUobm9kZUlEKTsKLSAgICAgICAgfQotCi0gICAgICAgIF9zdGFydE5vZGUgPSBub2RlOwotCi0gICAgICAgIHdoaWxlIChub2RlSUQgIT0gRU5EKSB7Ci0gICAgICAgICAgbV9hbmNlc3RvcnMuYWRkRWxlbWVudChub2RlKTsKLSAgICAgICAgICBub2RlSUQgPSBfcGFyZW50KG5vZGVJRCk7Ci0gICAgICAgICAgbm9kZSA9IG1ha2VOb2RlSGFuZGxlKG5vZGVJRCk7Ci0gICAgICAgIH0KLSAgICAgICAgbV9hbmNlc3RvcnNQb3MgPSBtX2FuY2VzdG9ycy5zaXplKCktMTsKLQotICAgICAgICBfY3VycmVudE5vZGUgPSAobV9hbmNlc3RvcnNQb3M+PTApCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBtX2FuY2VzdG9ycy5lbGVtZW50QXQobV9hbmNlc3RvcnNQb3MpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBEVE0uTlVMTDsKLQotICAgICAgICByZXR1cm4gcmVzZXRQb3NpdGlvbigpOwotICAgICAgfQotCi0gICAgICByZXR1cm4gdGhpczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXNldHMgdGhlIGl0ZXJhdG9yIHRvIHRoZSBsYXN0IHN0YXJ0IG5vZGUuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIEEgRFRNQXhpc0l0ZXJhdG9yLCB3aGljaCBtYXkgb3IgbWF5IG5vdCBiZSB0aGUgc2FtZSBhcyB0aGlzCi0gICAgICogICAgICAgICBpdGVyYXRvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIHJlc2V0KCkKLSAgICB7Ci0KLSAgICAgIG1fYW5jZXN0b3JzUG9zID0gbV9hbmNlc3RvcnMuc2l6ZSgpLTE7Ci0KLSAgICAgIF9jdXJyZW50Tm9kZSA9IChtX2FuY2VzdG9yc1Bvcz49MCkgPyBtX2FuY2VzdG9ycy5lbGVtZW50QXQobV9hbmNlc3RvcnNQb3MpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogRFRNLk5VTEw7Ci0KLSAgICAgIHJldHVybiByZXNldFBvc2l0aW9uKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBuZXh0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIG5leHQgbm9kZSBoYW5kbGUgaW4gdGhlIGl0ZXJhdGlvbiwgb3IgRU5ELgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgbmV4dCgpCi0gICAgewotCi0gICAgICBpbnQgbmV4dCA9IF9jdXJyZW50Tm9kZTsKLQotICAgICAgaW50IHBvcyA9IC0tbV9hbmNlc3RvcnNQb3M7Ci0KLSAgICAgIF9jdXJyZW50Tm9kZSA9IChwb3MgPj0gMCkgPyBtX2FuY2VzdG9ycy5lbGVtZW50QXQobV9hbmNlc3RvcnNQb3MpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogRFRNLk5VTEw7Ci0KLSAgICAgIHJldHVybiByZXR1cm5Ob2RlKG5leHQpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldE1hcmsoKSB7Ci0gICAgICAgIG1fbWFya2VkUG9zID0gbV9hbmNlc3RvcnNQb3M7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgZ290b01hcmsoKSB7Ci0gICAgICAgIG1fYW5jZXN0b3JzUG9zID0gbV9tYXJrZWRQb3M7Ci0gICAgICAgIF9jdXJyZW50Tm9kZSA9IG1fYW5jZXN0b3JzUG9zPj0wID8gbV9hbmNlc3RvcnMuZWxlbWVudEF0KG1fYW5jZXN0b3JzUG9zKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IERUTS5OVUxMOwotICAgIH0KLSAgfSAgLy8gZW5kIG9mIEFuY2VzdG9ySXRlcmF0b3IKLQotICAvKioKLSAgICogVHlwZWQgaXRlcmF0b3IgdGhhdCByZXR1cm5zIHRoZSBhbmNlc3RvcnMgb2YgYSBnaXZlbiBub2RlLgotICAgKi8KLSAgcHVibGljIGZpbmFsIGNsYXNzIFR5cGVkQW5jZXN0b3JJdGVyYXRvciBleHRlbmRzIEFuY2VzdG9ySXRlcmF0b3IKLSAgewotCi0gICAgLyoqIFRoZSBleHRlbmRlZCB0eXBlIElEIHRoYXQgd2FzIHJlcXVlc3RlZC4gKi8KLSAgICBwcml2YXRlIGZpbmFsIGludCBfbm9kZVR5cGU7Ci0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RvciBUeXBlZEFuY2VzdG9ySXRlcmF0b3IKLSAgICAgKgotICAgICAqCi0gICAgICogQHBhcmFtIHR5cGUgVGhlIGV4dGVuZGVkIHR5cGUgSUQgYmVpbmcgcmVxdWVzdGVkLgotICAgICAqLwotICAgIHB1YmxpYyBUeXBlZEFuY2VzdG9ySXRlcmF0b3IoaW50IHR5cGUpCi0gICAgewotICAgICAgX25vZGVUeXBlID0gdHlwZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgc3RhcnQgdG8gRU5EIHNob3VsZCAnY2xvc2UnIHRoZSBpdGVyYXRvciwKLSAgICAgKiBpLmUuIHN1YnNlcXVlbnQgY2FsbCB0byBuZXh0KCkgc2hvdWxkIHJldHVybiBFTkQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbm9kZSBTZXRzIHRoZSByb290IG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIEEgRFRNQXhpc0l0ZXJhdG9yIHNldCB0byB0aGUgc3RhcnQgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIHNldFN0YXJ0Tm9kZShpbnQgbm9kZSkKLSAgICB7Ci0vLyVIWiU6IEFkZGVkIHJlZmVyZW5jZSB0byBEVE1EZWZhdWx0QmFzZS5ST09UTk9ERSBiYWNrIGluLCB0ZW1wb3JhcmlseQotICAgICAgaWYgKG5vZGUgPT0gRFRNRGVmYXVsdEJhc2UuUk9PVE5PREUpCi0gICAgICAgIG5vZGUgPSBnZXREb2N1bWVudCgpOwotICAgICAgbV9yZWFsU3RhcnROb2RlID0gbm9kZTsKLQotICAgICAgaWYgKF9pc1Jlc3RhcnRhYmxlKQotICAgICAgewotICAgICAgICBpbnQgbm9kZUlEID0gbWFrZU5vZGVJZGVudGl0eShub2RlKTsKLSAgICAgICAgaW50IG5vZGVUeXBlID0gX25vZGVUeXBlOwotCi0gICAgICAgIGlmICghX2luY2x1ZGVTZWxmICYmIG5vZGUgIT0gRFRNLk5VTEwpIHsKLSAgICAgICAgICBub2RlSUQgPSBfcGFyZW50KG5vZGVJRCk7Ci0gICAgICAgIH0KLQotICAgICAgICBfc3RhcnROb2RlID0gbm9kZTsKLQotICAgICAgICBpZiAobm9kZVR5cGUgPj0gRFRNLk5UWVBFUykgewotICAgICAgICAgIHdoaWxlIChub2RlSUQgIT0gRU5EKSB7Ci0gICAgICAgICAgICBpbnQgZVR5cGUgPSBfZXhwdHlwZShub2RlSUQpOwotCi0gICAgICAgICAgICBpZiAoZVR5cGUgPT0gbm9kZVR5cGUpIHsKLSAgICAgICAgICAgICAgbV9hbmNlc3RvcnMuYWRkRWxlbWVudChtYWtlTm9kZUhhbmRsZShub2RlSUQpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIG5vZGVJRCA9IF9wYXJlbnQobm9kZUlEKTsKLSAgICAgICAgICB9Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgd2hpbGUgKG5vZGVJRCAhPSBFTkQpIHsKLSAgICAgICAgICAgIGludCBlVHlwZSA9IF9leHB0eXBlKG5vZGVJRCk7Ci0KLSAgICAgICAgICAgIGlmICgoZVR5cGUgPj0gRFRNLk5UWVBFUwotICAgICAgICAgICAgICAgICAgICAmJiBtX2V4cGFuZGVkTmFtZVRhYmxlLmdldFR5cGUoZVR5cGUpID09IG5vZGVUeXBlKQotICAgICAgICAgICAgICAgIHx8IChlVHlwZSA8IERUTS5OVFlQRVMgJiYgZVR5cGUgPT0gbm9kZVR5cGUpKSB7Ci0gICAgICAgICAgICAgIG1fYW5jZXN0b3JzLmFkZEVsZW1lbnQobWFrZU5vZGVIYW5kbGUobm9kZUlEKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBub2RlSUQgPSBfcGFyZW50KG5vZGVJRCk7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIG1fYW5jZXN0b3JzUG9zID0gbV9hbmNlc3RvcnMuc2l6ZSgpLTE7Ci0KLSAgICAgICAgX2N1cnJlbnROb2RlID0gKG1fYW5jZXN0b3JzUG9zPj0wKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gbV9hbmNlc3RvcnMuZWxlbWVudEF0KG1fYW5jZXN0b3JzUG9zKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogRFRNLk5VTEw7Ci0KLSAgICAgICAgcmV0dXJuIHJlc2V0UG9zaXRpb24oKTsKLSAgICAgIH0KLQotICAgICAgcmV0dXJuIHRoaXM7Ci0gICAgfQotICB9ICAvLyBlbmQgb2YgVHlwZWRBbmNlc3Rvckl0ZXJhdG9yCi0KLSAgLyoqCi0gICAqIEl0ZXJhdG9yIHRoYXQgcmV0dXJucyB0aGUgZGVzY2VuZGFudHMgb2YgYSBnaXZlbiBub2RlLgotICAgKi8KLSAgcHVibGljIGNsYXNzIERlc2NlbmRhbnRJdGVyYXRvciBleHRlbmRzIEludGVybmFsQXhpc0l0ZXJhdG9yQmFzZQotICB7Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgc3RhcnQgdG8gRU5EIHNob3VsZCAnY2xvc2UnIHRoZSBpdGVyYXRvciwKLSAgICAgKiBpLmUuIHN1YnNlcXVlbnQgY2FsbCB0byBuZXh0KCkgc2hvdWxkIHJldHVybiBFTkQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbm9kZSBTZXRzIHRoZSByb290IG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIEEgRFRNQXhpc0l0ZXJhdG9yIHNldCB0byB0aGUgc3RhcnQgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIHNldFN0YXJ0Tm9kZShpbnQgbm9kZSkKLSAgICB7Ci0vLyVIWiU6IEFkZGVkIHJlZmVyZW5jZSB0byBEVE1EZWZhdWx0QmFzZS5ST09UTk9ERSBiYWNrIGluLCB0ZW1wb3JhcmlseQotICAgICAgaWYgKG5vZGUgPT0gRFRNRGVmYXVsdEJhc2UuUk9PVE5PREUpCi0gICAgICAgIG5vZGUgPSBnZXREb2N1bWVudCgpOwotICAgICAgaWYgKF9pc1Jlc3RhcnRhYmxlKQotICAgICAgewotICAgICAgICBub2RlID0gbWFrZU5vZGVJZGVudGl0eShub2RlKTsKLSAgICAgICAgX3N0YXJ0Tm9kZSA9IG5vZGU7Ci0KLSAgICAgICAgaWYgKF9pbmNsdWRlU2VsZikKLSAgICAgICAgICBub2RlLS07Ci0KLSAgICAgICAgX2N1cnJlbnROb2RlID0gbm9kZTsKLQotICAgICAgICByZXR1cm4gcmVzZXRQb3NpdGlvbigpOwotICAgICAgfQotCi0gICAgICByZXR1cm4gdGhpczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUZWxsIGlmIHRoaXMgbm9kZSBpZGVudGl0eSBpcyBhIGRlc2NlbmRhbnQuICBBc3N1bWVzIHRoYXQKLSAgICAgKiB0aGUgbm9kZSBpbmZvIGZvciB0aGUgZWxlbWVudCBoYXMgYWxyZWFkeSBiZWVuIG9idGFpbmVkLgotICAgICAqCi0gICAgICogVGhpcyBvbmUtc2lkZWQgdGVzdCB3b3JrcyBvbmx5IGlmIHRoZSBwYXJlbnQgaGFzIGJlZW4KLSAgICAgKiBwcmV2aW91c2x5IHRlc3RlZCBhbmQgaXMga25vd24gdG8gYmUgYSBkZXNjZW5kZW50LiBJdCBmYWlscyBpZgotICAgICAqIHRoZSBwYXJlbnQgaXMgdGhlIF9zdGFydE5vZGUncyBuZXh0IHNpYmxpbmcsIG9yIGluZGVlZCBhbnkgbm9kZQotICAgICAqIHRoYXQgZm9sbG93cyBfc3RhcnROb2RlIGluIGRvY3VtZW50IG9yZGVyLiAgVGhhdCBtYXkgc3VmZmljZQotICAgICAqIGZvciB0aGlzIGl0ZXJhdG9yLCBidXQgaXQncyBub3QgcmVhbGx5IGFuIGlzRGVzY2VuZGVudCgpIHRlc3QuCi0gICAgICogJVJFVklFVyUgcmVuYW1lPwotICAgICAqCi0gICAgICogQHBhcmFtIGlkZW50aXR5IFRoZSBpbmRleCBudW1iZXIgb2YgdGhlIG5vZGUgaW4gcXVlc3Rpb24uCi0gICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBpbmRleCBpcyBhIGRlc2NlbmRhbnQgb2YgX3N0YXJ0Tm9kZS4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBpc0Rlc2NlbmRhbnQoaW50IGlkZW50aXR5KQotICAgIHsKLSAgICAgIHJldHVybiAoX3BhcmVudChpZGVudGl0eSkgPj0gX3N0YXJ0Tm9kZSkgfHwgKF9zdGFydE5vZGUgPT0gaWRlbnRpdHkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgbmV4dCBub2RlIGluIHRoZSBpdGVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBuZXh0IG5vZGUgaGFuZGxlIGluIHRoZSBpdGVyYXRpb24sIG9yIEVORC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IG5leHQoKQotICAgIHsKLSAgICAgIGlmIChfc3RhcnROb2RlID09IE5VTEwpIHsKLSAgICAgICAgcmV0dXJuIE5VTEw7Ci0gICAgICB9Ci0KLSAgICAgIGlmIChfaW5jbHVkZVNlbGYgJiYgKF9jdXJyZW50Tm9kZSArIDEpID09IF9zdGFydE5vZGUpCi0gICAgICAgICAgcmV0dXJuIHJldHVybk5vZGUobWFrZU5vZGVIYW5kbGUoKytfY3VycmVudE5vZGUpKTsgLy8gfCBtX2R0bUlkZW50KTsKLQotICAgICAgaW50IG5vZGUgPSBfY3VycmVudE5vZGU7Ci0gICAgICBpbnQgdHlwZTsKLQotICAgICAgZG8gewotICAgICAgICBub2RlKys7Ci0gICAgICAgIHR5cGUgPSBfdHlwZShub2RlKTsKLQotICAgICAgICBpZiAoTlVMTCA9PSB0eXBlIHx8IWlzRGVzY2VuZGFudChub2RlKSkgewotICAgICAgICAgIF9jdXJyZW50Tm9kZSA9IE5VTEw7Ci0gICAgICAgICAgcmV0dXJuIEVORDsKLSAgICAgICAgfQotICAgICAgfSB3aGlsZShBVFRSSUJVVEVfTk9ERSA9PSB0eXBlIHx8IFRFWFRfTk9ERSA9PSB0eXBlCi0gICAgICAgICAgICAgICAgIHx8IE5BTUVTUEFDRV9OT0RFID09IHR5cGUpOwotCi0gICAgICBfY3VycmVudE5vZGUgPSBub2RlOwotICAgICAgcmV0dXJuIHJldHVybk5vZGUobWFrZU5vZGVIYW5kbGUobm9kZSkpOyAgLy8gbWFrZSBoYW5kbGUuCi0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmVzZXQuCi0gICAgICoKLSAgICAgKi8KLSAgcHVibGljIERUTUF4aXNJdGVyYXRvciByZXNldCgpCi0gIHsKLQotICAgIGZpbmFsIGJvb2xlYW4gdGVtcCA9IF9pc1Jlc3RhcnRhYmxlOwotCi0gICAgX2lzUmVzdGFydGFibGUgPSB0cnVlOwotCi0gICAgc2V0U3RhcnROb2RlKG1ha2VOb2RlSGFuZGxlKF9zdGFydE5vZGUpKTsKLQotICAgIF9pc1Jlc3RhcnRhYmxlID0gdGVtcDsKLQotICAgIHJldHVybiB0aGlzOwotICB9Ci0KLSAgfSAgLy8gZW5kIG9mIERlc2NlbmRhbnRJdGVyYXRvcgotCi0gIC8qKgotICAgKiBUeXBlZCBpdGVyYXRvciB0aGF0IHJldHVybnMgdGhlIGRlc2NlbmRhbnRzIG9mIGEgZ2l2ZW4gbm9kZS4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBjbGFzcyBUeXBlZERlc2NlbmRhbnRJdGVyYXRvciBleHRlbmRzIERlc2NlbmRhbnRJdGVyYXRvcgotICB7Ci0KLSAgICAvKiogVGhlIGV4dGVuZGVkIHR5cGUgSUQgdGhhdCB3YXMgcmVxdWVzdGVkLiAqLwotICAgIHByaXZhdGUgZmluYWwgaW50IF9ub2RlVHlwZTsKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdG9yIFR5cGVkRGVzY2VuZGFudEl0ZXJhdG9yCi0gICAgICoKLSAgICAgKgotICAgICAqIEBwYXJhbSBub2RlVHlwZSBFeHRlbmRlZCB0eXBlIElEIGJlaW5nIHJlcXVlc3RlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgVHlwZWREZXNjZW5kYW50SXRlcmF0b3IoaW50IG5vZGVUeXBlKQotICAgIHsKLSAgICAgIF9ub2RlVHlwZSA9IG5vZGVUeXBlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgbmV4dCBub2RlIGluIHRoZSBpdGVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBuZXh0IG5vZGUgaGFuZGxlIGluIHRoZSBpdGVyYXRpb24sIG9yIEVORC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IG5leHQoKQotICAgIHsKLSAgICAgIGludCBub2RlOwotICAgICAgaW50IHR5cGU7Ci0KLSAgICAgIGlmIChfc3RhcnROb2RlID09IE5VTEwpIHsKLSAgICAgICAgcmV0dXJuIE5VTEw7Ci0gICAgICB9Ci0KLSAgICAgIG5vZGUgPSBfY3VycmVudE5vZGU7Ci0KLSAgICAgIGRvCi0gICAgICB7Ci0gICAgICAgIG5vZGUrKzsKLSAgICAgICAgdHlwZSA9IF90eXBlKG5vZGUpOwotCi0gICAgICAgIGlmIChOVUxMID09IHR5cGUgfHwhaXNEZXNjZW5kYW50KG5vZGUpKSB7Ci0gICAgICAgICAgX2N1cnJlbnROb2RlID0gTlVMTDsKLSAgICAgICAgICByZXR1cm4gRU5EOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgICB3aGlsZSAodHlwZSAhPSBfbm9kZVR5cGUgJiYgX2V4cHR5cGUobm9kZSkgIT0gX25vZGVUeXBlKTsKLQotICAgICAgX2N1cnJlbnROb2RlID0gbm9kZTsKLSAgICAgIHJldHVybiByZXR1cm5Ob2RlKG1ha2VOb2RlSGFuZGxlKG5vZGUpKTsKLSAgICB9Ci0gIH0gIC8vIGVuZCBvZiBUeXBlZERlc2NlbmRhbnRJdGVyYXRvcgotCi0gIC8qKgotICAgKiBJdGVyYXRvciB0aGF0IHJldHVybnMgdGhlIGRlc2NlbmRhbnRzIG9mIGEgZ2l2ZW4gbm9kZS4KLSAgICogSSdtIG5vdCBleGFjdGx5IGNsZWFyIGFib3V0IHRoaXMgb25lLi4uIC1zYgotICAgKi8KLSAgcHVibGljIGNsYXNzIE50aERlc2NlbmRhbnRJdGVyYXRvciBleHRlbmRzIERlc2NlbmRhbnRJdGVyYXRvcgotICB7Ci0KLSAgICAvKiogVGhlIGN1cnJlbnQgbnRoIHBvc2l0aW9uLiAqLwotICAgIGludCBfcG9zOwotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0b3IgTnRoRGVzY2VuZGFudEl0ZXJhdG9yCi0gICAgICoKLSAgICAgKgotICAgICAqIEBwYXJhbSBwb3MgVGhlIG50aCBwb3NpdGlvbiBiZWluZyByZXF1ZXN0ZWQuCi0gICAgICovCi0gICAgcHVibGljIE50aERlc2NlbmRhbnRJdGVyYXRvcihpbnQgcG9zKQotICAgIHsKLSAgICAgIF9wb3MgPSBwb3M7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBuZXh0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIG5leHQgbm9kZSBoYW5kbGUgaW4gdGhlIGl0ZXJhdGlvbiwgb3IgRU5ELgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgbmV4dCgpCi0gICAgewotCi0gICAgICAvLyBJJ20gbm90IGV4YWN0bHkgY2xlYXIgeWV0IHdoYXQgdGhpcyBpcyBkb2luZy4uLiAtc2IKLSAgICAgIGludCBub2RlOwotCi0gICAgICB3aGlsZSAoKG5vZGUgPSBzdXBlci5uZXh0KCkpICE9IEVORCkKLSAgICAgIHsKLSAgICAgICAgbm9kZSA9IG1ha2VOb2RlSWRlbnRpdHkobm9kZSk7Ci0KLSAgICAgICAgaW50IHBhcmVudCA9IF9wYXJlbnQobm9kZSk7Ci0gICAgICAgIGludCBjaGlsZCA9IF9maXJzdGNoKHBhcmVudCk7Ci0gICAgICAgIGludCBwb3MgPSAwOwotCi0gICAgICAgIGRvCi0gICAgICAgIHsKLSAgICAgICAgICBpbnQgdHlwZSA9IF90eXBlKGNoaWxkKTsKLQotICAgICAgICAgIGlmIChFTEVNRU5UX05PREUgPT0gdHlwZSkKLSAgICAgICAgICAgIHBvcysrOwotICAgICAgICB9Ci0gICAgICAgIHdoaWxlICgocG9zIDwgX3BvcykgJiYgKGNoaWxkID0gX25leHRzaWIoY2hpbGQpKSAhPSBFTkQpOwotCi0gICAgICAgIGlmIChub2RlID09IGNoaWxkKQotICAgICAgICAgIHJldHVybiBub2RlOwotICAgICAgfQotCi0gICAgICByZXR1cm4gKEVORCk7Ci0gICAgfQotICB9ICAvLyBlbmQgb2YgTnRoRGVzY2VuZGFudEl0ZXJhdG9yCi0KLSAgLyoqCi0gICAqIENsYXNzIFNpbmdsZXRvbkl0ZXJhdG9yLgotICAgKi8KLSAgcHVibGljIGNsYXNzIFNpbmdsZXRvbkl0ZXJhdG9yIGV4dGVuZHMgSW50ZXJuYWxBeGlzSXRlcmF0b3JCYXNlCi0gIHsKLQotICAgIC8qKiAobm90IHN1cmUgeWV0IHdoYXQgdGhpcyBpcy4gIC1zYikgIChzYyAmIHNiIHJlbW92ZSBmaW5hbCB0byBjb21waWxlIGluIEpESyAxLjEuOCkgKi8KLSAgICBwcml2YXRlIGJvb2xlYW4gX2lzQ29uc3RhbnQ7Ci0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RvciBTaW5nbGV0b25JdGVyYXRvcgotICAgICAqCi0gICAgICovCi0gICAgcHVibGljIFNpbmdsZXRvbkl0ZXJhdG9yKCkKLSAgICB7Ci0gICAgICB0aGlzKEludGVnZXIuTUlOX1ZBTFVFLCBmYWxzZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0b3IgU2luZ2xldG9uSXRlcmF0b3IKLSAgICAgKgotICAgICAqCi0gICAgICogQHBhcmFtIG5vZGUgVGhlIG5vZGUgaGFuZGxlIHRvIHJldHVybi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU2luZ2xldG9uSXRlcmF0b3IoaW50IG5vZGUpCi0gICAgewotICAgICAgdGhpcyhub2RlLCBmYWxzZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0b3IgU2luZ2xldG9uSXRlcmF0b3IKLSAgICAgKgotICAgICAqCi0gICAgICogQHBhcmFtIG5vZGUgdGhlIG5vZGUgaGFuZGxlIHRvIHJldHVybi4KLSAgICAgKiBAcGFyYW0gY29uc3RhbnQgKE5vdCBzdXJlIHdoYXQgdGhpcyBpcyB5ZXQuICAtc2IpCi0gICAgICovCi0gICAgcHVibGljIFNpbmdsZXRvbkl0ZXJhdG9yKGludCBub2RlLCBib29sZWFuIGNvbnN0YW50KQotICAgIHsKLSAgICAgIF9jdXJyZW50Tm9kZSA9IF9zdGFydE5vZGUgPSBub2RlOwotICAgICAgX2lzQ29uc3RhbnQgPSBjb25zdGFudDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgc3RhcnQgdG8gRU5EIHNob3VsZCAnY2xvc2UnIHRoZSBpdGVyYXRvciwKLSAgICAgKiBpLmUuIHN1YnNlcXVlbnQgY2FsbCB0byBuZXh0KCkgc2hvdWxkIHJldHVybiBFTkQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbm9kZSBTZXRzIHRoZSByb290IG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIEEgRFRNQXhpc0l0ZXJhdG9yIHNldCB0byB0aGUgc3RhcnQgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIHNldFN0YXJ0Tm9kZShpbnQgbm9kZSkKLSAgICB7Ci0vLyVIWiU6IEFkZGVkIHJlZmVyZW5jZSB0byBEVE1EZWZhdWx0QmFzZS5ST09UTk9ERSBiYWNrIGluLCB0ZW1wb3JhcmlseQotICAgICAgaWYgKG5vZGUgPT0gRFRNRGVmYXVsdEJhc2UuUk9PVE5PREUpCi0gICAgICAgIG5vZGUgPSBnZXREb2N1bWVudCgpOwotICAgICAgaWYgKF9pc0NvbnN0YW50KQotICAgICAgewotICAgICAgICBfY3VycmVudE5vZGUgPSBfc3RhcnROb2RlOwotCi0gICAgICAgIHJldHVybiByZXNldFBvc2l0aW9uKCk7Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmIChfaXNSZXN0YXJ0YWJsZSkKLSAgICAgIHsKLSAgICAgICAgICBfY3VycmVudE5vZGUgPSBfc3RhcnROb2RlID0gbm9kZTsKLQotICAgICAgICByZXR1cm4gcmVzZXRQb3NpdGlvbigpOwotICAgICAgfQotCi0gICAgICByZXR1cm4gdGhpczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXNldHMgdGhlIGl0ZXJhdG9yIHRvIHRoZSBsYXN0IHN0YXJ0IG5vZGUuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIEEgRFRNQXhpc0l0ZXJhdG9yLCB3aGljaCBtYXkgb3IgbWF5IG5vdCBiZSB0aGUgc2FtZSBhcyB0aGlzCi0gICAgICogICAgICAgICBpdGVyYXRvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIHJlc2V0KCkKLSAgICB7Ci0KLSAgICAgIGlmIChfaXNDb25zdGFudCkKLSAgICAgIHsKLSAgICAgICAgX2N1cnJlbnROb2RlID0gX3N0YXJ0Tm9kZTsKLQotICAgICAgICByZXR1cm4gcmVzZXRQb3NpdGlvbigpOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBmaW5hbCBib29sZWFuIHRlbXAgPSBfaXNSZXN0YXJ0YWJsZTsKLQotICAgICAgICBfaXNSZXN0YXJ0YWJsZSA9IHRydWU7Ci0KLSAgICAgICAgc2V0U3RhcnROb2RlKF9zdGFydE5vZGUpOwotCi0gICAgICAgIF9pc1Jlc3RhcnRhYmxlID0gdGVtcDsKLSAgICAgIH0KLQotICAgICAgcmV0dXJuIHRoaXM7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBuZXh0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIG5leHQgbm9kZSBoYW5kbGUgaW4gdGhlIGl0ZXJhdGlvbiwgb3IgRU5ELgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgbmV4dCgpCi0gICAgewotCi0gICAgICBmaW5hbCBpbnQgcmVzdWx0ID0gX2N1cnJlbnROb2RlOwotCi0gICAgICBfY3VycmVudE5vZGUgPSBFTkQ7Ci0KLSAgICAgIHJldHVybiByZXR1cm5Ob2RlKHJlc3VsdCk7Ci0gICAgfQotICB9ICAvLyBlbmQgb2YgU2luZ2xldG9uSXRlcmF0b3IKLQotICAvKioKLSAgICogSXRlcmF0b3IgdGhhdCByZXR1cm5zIGEgZ2l2ZW4gbm9kZSBvbmx5IGlmIGl0IGlzIG9mIGEgZ2l2ZW4gdHlwZS4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBjbGFzcyBUeXBlZFNpbmdsZXRvbkl0ZXJhdG9yIGV4dGVuZHMgU2luZ2xldG9uSXRlcmF0b3IKLSAgewotCi0gICAgLyoqIFRoZSBleHRlbmRlZCB0eXBlIElEIHRoYXQgd2FzIHJlcXVlc3RlZC4gKi8KLSAgICBwcml2YXRlIGZpbmFsIGludCBfbm9kZVR5cGU7Ci0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RvciBUeXBlZFNpbmdsZXRvbkl0ZXJhdG9yCi0gICAgICoKLSAgICAgKgotICAgICAqIEBwYXJhbSBub2RlVHlwZSBUaGUgZXh0ZW5kZWQgdHlwZSBJRCBiZWluZyByZXF1ZXN0ZWQuCi0gICAgICovCi0gICAgcHVibGljIFR5cGVkU2luZ2xldG9uSXRlcmF0b3IoaW50IG5vZGVUeXBlKQotICAgIHsKLSAgICAgIF9ub2RlVHlwZSA9IG5vZGVUeXBlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgbmV4dCBub2RlIGluIHRoZSBpdGVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBuZXh0IG5vZGUgaGFuZGxlIGluIHRoZSBpdGVyYXRpb24sIG9yIEVORC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IG5leHQoKQotICAgIHsKLQotICAgICAgLy9maW5hbCBpbnQgcmVzdWx0ID0gc3VwZXIubmV4dCgpOwotICAgICAgZmluYWwgaW50IHJlc3VsdCA9IF9jdXJyZW50Tm9kZTsKLSAgICAgIGludCBub2RlVHlwZSA9IF9ub2RlVHlwZTsKLQotICAgICAgX2N1cnJlbnROb2RlID0gRU5EOwotCi0gICAgICBpZiAobm9kZVR5cGUgPj0gRFRNLk5UWVBFUykgewotICAgICAgICBpZiAoZ2V0RXhwYW5kZWRUeXBlSUQocmVzdWx0KSA9PSBub2RlVHlwZSkgewotICAgICAgICAgIHJldHVybiByZXR1cm5Ob2RlKHJlc3VsdCk7Ci0gICAgICAgIH0KLSAgICAgIH0gZWxzZSB7Ci0gICAgICAgIGlmIChnZXROb2RlVHlwZShyZXN1bHQpID09IG5vZGVUeXBlKSB7Ci0gICAgICAgICAgcmV0dXJuIHJldHVybk5vZGUocmVzdWx0KTsKLSAgICAgICAgfQotICAgICAgfQotCi0gICAgICByZXR1cm4gTlVMTDsKLSAgICB9Ci0gIH0gIC8vIGVuZCBvZiBUeXBlZFNpbmdsZXRvbkl0ZXJhdG9yCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vcmVmL0RUTURlZmF1bHRCYXNlVHJhdmVyc2Vycy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL3JlZi9EVE1EZWZhdWx0QmFzZVRyYXZlcnNlcnMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYzMzNTQ1NC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vcmVmL0RUTURlZmF1bHRCYXNlVHJhdmVyc2Vycy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTc0NyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBEVE1EZWZhdWx0QmFzZVRyYXZlcnNlcnMuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNSAwODoxNTowMCBzdXJlc2hfZW1haWxpZCBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLnJlZjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLio7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlNvdXJjZTsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuWE1MU3RyaW5nRmFjdG9yeTsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzLlhNTEVycm9yUmVzb3VyY2VzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzLlhNTE1lc3NhZ2VzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5kb20uTm9kZUNvdW50ZXI7Ci0KLS8qKgotICogVGhpcyBjbGFzcyBpbXBsZW1lbnRzIHRoZSB0cmF2ZXJzZXJzIGZvciBEVE1EZWZhdWx0QmFzZS4KLSAqCi0gKiBQTEVBU0UgTk9URSB0aGF0IHRoZSBwdWJsaWMgaW50ZXJmYWNlIGZvciBhbGwgdHJhdmVyc2VycyBzaG91bGQgYmUKLSAqIGluIHRlcm1zIG9mIERUTSBOb2RlIEhhbmRsZXMuLi4gYnV0IHRoZXkgbWF5IHVzZSB0aGUgaW50ZXJuYWwgbm9kZQotICogaWRlbnRpdHkgaW5kaWNlcyB3aXRoaW4gdGhlaXIgbG9naWMsIGZvciBlZmZpY2llbmN5J3Mgc2FrZS4gQmUgdmVyeQotICogY2FyZWZ1bCB0byBhdm9pZCBjb25mdXNpbmcgdGhlc2Ugd2hlbiBtYWludGFpbmluZyB0aGlzIGNvZGUuCi0gKiAqLwotcHVibGljIGFic3RyYWN0IGNsYXNzIERUTURlZmF1bHRCYXNlVHJhdmVyc2VycyBleHRlbmRzIERUTURlZmF1bHRCYXNlCi17Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhIERUTURlZmF1bHRCYXNlVHJhdmVyc2VycyBvYmplY3QgZnJvbSBhIERPTSBub2RlLgotICAgKgotICAgKiBAcGFyYW0gbWdyIFRoZSBEVE1NYW5hZ2VyIHdobyBvd25zIHRoaXMgRFRNLgotICAgKiBAcGFyYW0gc291cmNlIFRoZSBvYmplY3QgdGhhdCBpcyB1c2VkIHRvIHNwZWNpZnkgdGhlIGNvbnN0cnVjdGlvbiBzb3VyY2UuCi0gICAqIEBwYXJhbSBkdG1JZGVudGl0eSBUaGUgRFRNIGlkZW50aXR5IElEIGZvciB0aGlzIERUTS4KLSAgICogQHBhcmFtIHdoaXRlU3BhY2VGaWx0ZXIgVGhlIHdoaXRlIHNwYWNlIGZpbHRlciBmb3IgdGhpcyBEVE0sIHdoaWNoIG1heQotICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBiZSBudWxsLgotICAgKiBAcGFyYW0geHN0cmluZ2ZhY3RvcnkgVGhlIGZhY3RvcnkgdG8gdXNlIGZvciBjcmVhdGluZyBYTUxTdHJpbmdzLgotICAgKiBAcGFyYW0gZG9JbmRleGluZyB0cnVlIGlmIHRoZSBjYWxsZXIgY29uc2lkZXJzIGl0IHdvcnRoIGl0IHRvIHVzZQotICAgKiAgICAgICAgICAgICAgICAgICBpbmRleGluZyBzY2hlbWVzLgotICAgKi8KLSAgcHVibGljIERUTURlZmF1bHRCYXNlVHJhdmVyc2VycyhEVE1NYW5hZ2VyIG1nciwgU291cmNlIHNvdXJjZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgZHRtSWRlbnRpdHksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFRNV1NGaWx0ZXIgd2hpdGVTcGFjZUZpbHRlciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxTdHJpbmdGYWN0b3J5IHhzdHJpbmdmYWN0b3J5LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gZG9JbmRleGluZykKLSAgewotICAgIHN1cGVyKG1nciwgc291cmNlLCBkdG1JZGVudGl0eSwgd2hpdGVTcGFjZUZpbHRlciwgeHN0cmluZ2ZhY3RvcnksCi0gICAgICAgICAgZG9JbmRleGluZyk7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgRFRNRGVmYXVsdEJhc2VUcmF2ZXJzZXJzIG9iamVjdCBmcm9tIGEgRE9NIG5vZGUuCi0gICAqCi0gICAqIEBwYXJhbSBtZ3IgVGhlIERUTU1hbmFnZXIgd2hvIG93bnMgdGhpcyBEVE0uCi0gICAqIEBwYXJhbSBzb3VyY2UgVGhlIG9iamVjdCB0aGF0IGlzIHVzZWQgdG8gc3BlY2lmeSB0aGUgY29uc3RydWN0aW9uIHNvdXJjZS4KLSAgICogQHBhcmFtIGR0bUlkZW50aXR5IFRoZSBEVE0gaWRlbnRpdHkgSUQgZm9yIHRoaXMgRFRNLgotICAgKiBAcGFyYW0gd2hpdGVTcGFjZUZpbHRlciBUaGUgd2hpdGUgc3BhY2UgZmlsdGVyIGZvciB0aGlzIERUTSwgd2hpY2ggbWF5Ci0gICAqICAgICAgICAgICAgICAgICAgICAgICAgIGJlIG51bGwuCi0gICAqIEBwYXJhbSB4c3RyaW5nZmFjdG9yeSBUaGUgZmFjdG9yeSB0byB1c2UgZm9yIGNyZWF0aW5nIFhNTFN0cmluZ3MuCi0gICAqIEBwYXJhbSBkb0luZGV4aW5nIHRydWUgaWYgdGhlIGNhbGxlciBjb25zaWRlcnMgaXQgd29ydGggaXQgdG8gdXNlCi0gICAqICAgICAgICAgICAgICAgICAgIGluZGV4aW5nIHNjaGVtZXMuCi0gICAqIEBwYXJhbSBibG9ja3NpemUgVGhlIGJsb2NrIHNpemUgb2YgdGhlIERUTS4KLSAgICogQHBhcmFtIHVzZVByZXZzaWIgdHJ1ZSBpZiB3ZSB3YW50IHRvIGJ1aWxkIHRoZSBwcmV2aW91cyBzaWJsaW5nIG5vZGUgYXJyYXkuCi0gICAqIEBwYXJhbSBuZXdOYW1lVGFibGUgdHJ1ZSBpZiB3ZSB3YW50IHRvIHVzZSBhIG5ldyBFeHBhbmRlZE5hbWVUYWJsZSBmb3IgdGhpcyBEVE0uCi0gICAqLwotICBwdWJsaWMgRFRNRGVmYXVsdEJhc2VUcmF2ZXJzZXJzKERUTU1hbmFnZXIgbWdyLCBTb3VyY2Ugc291cmNlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBkdG1JZGVudGl0eSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEVE1XU0ZpbHRlciB3aGl0ZVNwYWNlRmlsdGVyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTFN0cmluZ0ZhY3RvcnkgeHN0cmluZ2ZhY3RvcnksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBkb0luZGV4aW5nLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBibG9ja3NpemUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiB1c2VQcmV2c2liLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gbmV3TmFtZVRhYmxlKQotICB7Ci0gICAgc3VwZXIobWdyLCBzb3VyY2UsIGR0bUlkZW50aXR5LCB3aGl0ZVNwYWNlRmlsdGVyLCB4c3RyaW5nZmFjdG9yeSwKLSAgICAgICAgICBkb0luZGV4aW5nLCBibG9ja3NpemUsIHVzZVByZXZzaWIsIG5ld05hbWVUYWJsZSk7Ci0gIH0KLQotICAvKioKLSAgICogVGhpcyByZXR1cm5zIGEgc3RhdGVsZXNzICJ0cmF2ZXJzZXIiLCB0aGF0IGNhbiBuYXZpZ2F0ZQotICAgKiBvdmVyIGFuIFhQYXRoIGF4aXMsIHRob3VnaCBwZXJoYXBzIG5vdCBpbiBkb2N1bWVudCBvcmRlci4KLSAgICoKLSAgICogQHBhcmFtIGF4aXMgT25lIG9mIEF4ZXMuQU5DRVNUT1JPUlNFTEYsIGV0Yy4KLSAgICoKLSAgICogQHJldHVybiBBIERUTUF4aXNUcmF2ZXJzZXIsIG9yIG51bGwgaWYgdGhlIGdpdmVuIGF4aXMgaXNuJ3Qgc3VwcG9ydGVkLgotICAgKi8KLSAgcHVibGljIERUTUF4aXNUcmF2ZXJzZXIgZ2V0QXhpc1RyYXZlcnNlcihmaW5hbCBpbnQgYXhpcykKLSAgewotCi0gICAgRFRNQXhpc1RyYXZlcnNlciB0cmF2ZXJzZXI7Ci0KLSAgICBpZiAobnVsbCA9PSBtX3RyYXZlcnNlcnMpICAvLyBDYWNoZSBvZiBzdGF0ZWxlc3MgdHJhdmVyc2VycyBmb3IgdGhpcyBEVE0KLSAgICB7Ci0gICAgICBtX3RyYXZlcnNlcnMgPSBuZXcgRFRNQXhpc1RyYXZlcnNlcltBeGlzLmdldE5hbWVzTGVuZ3RoKCldOwotICAgICAgdHJhdmVyc2VyID0gbnVsbDsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIHRyYXZlcnNlciA9IG1fdHJhdmVyc2Vyc1theGlzXTsgIC8vIFNoYXJlL3JldXNlIGV4aXN0aW5nIHRyYXZlcnNlcgotCi0gICAgICBpZiAodHJhdmVyc2VyICE9IG51bGwpCi0gICAgICAgIHJldHVybiB0cmF2ZXJzZXI7Ci0gICAgfQotCi0gICAgc3dpdGNoIChheGlzKSAgLy8gR2VuZXJhdGUgbmV3IHRyYXZlcnNlcgotICAgIHsKLSAgICBjYXNlIEF4aXMuQU5DRVNUT1IgOgotICAgICAgdHJhdmVyc2VyID0gbmV3IEFuY2VzdG9yVHJhdmVyc2VyKCk7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIEF4aXMuQU5DRVNUT1JPUlNFTEYgOgotICAgICAgdHJhdmVyc2VyID0gbmV3IEFuY2VzdG9yT3JTZWxmVHJhdmVyc2VyKCk7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIEF4aXMuQVRUUklCVVRFIDoKLSAgICAgIHRyYXZlcnNlciA9IG5ldyBBdHRyaWJ1dGVUcmF2ZXJzZXIoKTsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgQXhpcy5DSElMRCA6Ci0gICAgICB0cmF2ZXJzZXIgPSBuZXcgQ2hpbGRUcmF2ZXJzZXIoKTsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgQXhpcy5ERVNDRU5EQU5UIDoKLSAgICAgIHRyYXZlcnNlciA9IG5ldyBEZXNjZW5kYW50VHJhdmVyc2VyKCk7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIEF4aXMuREVTQ0VOREFOVE9SU0VMRiA6Ci0gICAgICB0cmF2ZXJzZXIgPSBuZXcgRGVzY2VuZGFudE9yU2VsZlRyYXZlcnNlcigpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBBeGlzLkZPTExPV0lORyA6Ci0gICAgICB0cmF2ZXJzZXIgPSBuZXcgRm9sbG93aW5nVHJhdmVyc2VyKCk7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIEF4aXMuRk9MTE9XSU5HU0lCTElORyA6Ci0gICAgICB0cmF2ZXJzZXIgPSBuZXcgRm9sbG93aW5nU2libGluZ1RyYXZlcnNlcigpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBBeGlzLk5BTUVTUEFDRSA6Ci0gICAgICB0cmF2ZXJzZXIgPSBuZXcgTmFtZXNwYWNlVHJhdmVyc2VyKCk7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIEF4aXMuTkFNRVNQQUNFREVDTFMgOgotICAgICAgdHJhdmVyc2VyID0gbmV3IE5hbWVzcGFjZURlY2xzVHJhdmVyc2VyKCk7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIEF4aXMuUEFSRU5UIDoKLSAgICAgIHRyYXZlcnNlciA9IG5ldyBQYXJlbnRUcmF2ZXJzZXIoKTsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgQXhpcy5QUkVDRURJTkcgOgotICAgICAgdHJhdmVyc2VyID0gbmV3IFByZWNlZGluZ1RyYXZlcnNlcigpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBBeGlzLlBSRUNFRElOR1NJQkxJTkcgOgotICAgICAgdHJhdmVyc2VyID0gbmV3IFByZWNlZGluZ1NpYmxpbmdUcmF2ZXJzZXIoKTsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgQXhpcy5TRUxGIDoKLSAgICAgIHRyYXZlcnNlciA9IG5ldyBTZWxmVHJhdmVyc2VyKCk7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIEF4aXMuQUxMIDoKLSAgICAgIHRyYXZlcnNlciA9IG5ldyBBbGxGcm9tUm9vdFRyYXZlcnNlcigpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBBeGlzLkFMTEZST01OT0RFIDoKLSAgICAgIHRyYXZlcnNlciA9IG5ldyBBbGxGcm9tTm9kZVRyYXZlcnNlcigpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBBeGlzLlBSRUNFRElOR0FOREFOQ0VTVE9SIDoKLSAgICAgIHRyYXZlcnNlciA9IG5ldyBQcmVjZWRpbmdBbmRBbmNlc3RvclRyYXZlcnNlcigpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBBeGlzLkRFU0NFTkRBTlRTRlJPTVJPT1QgOgotICAgICAgdHJhdmVyc2VyID0gbmV3IERlc2NlbmRhbnRGcm9tUm9vdFRyYXZlcnNlcigpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBBeGlzLkRFU0NFTkRBTlRTT1JTRUxGRlJPTVJPT1QgOgotICAgICAgdHJhdmVyc2VyID0gbmV3IERlc2NlbmRhbnRPclNlbGZGcm9tUm9vdFRyYXZlcnNlcigpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBBeGlzLlJPT1QgOgotICAgICAgdHJhdmVyc2VyID0gbmV3IFJvb3RUcmF2ZXJzZXIoKTsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgQXhpcy5GSUxURVJFRExJU1QgOgotICAgICAgcmV0dXJuIG51bGw7IC8vIERvbid0IHdhbnQgdG8gdGhyb3cgYW4gZXhjZXB0aW9uIGZvciB0aGlzIG9uZS4KLSAgICBkZWZhdWx0IDoKLSAgICAgIHRocm93IG5ldyBEVE1FeGNlcHRpb24oWE1MTWVzc2FnZXMuY3JlYXRlWE1MTWVzc2FnZShYTUxFcnJvclJlc291cmNlcy5FUl9VTktOT1dOX0FYSVNfVFlQRSwgbmV3IE9iamVjdFtde0ludGVnZXIudG9TdHJpbmcoYXhpcyl9KSk7IC8vIlVua25vd24gYXhpcyB0cmF2ZXJzYWwgdHlwZTogIitheGlzKTsKLSAgICB9Ci0KLSAgICBpZiAobnVsbCA9PSB0cmF2ZXJzZXIpCi0gICAgICB0aHJvdyBuZXcgRFRNRXhjZXB0aW9uKFhNTE1lc3NhZ2VzLmNyZWF0ZVhNTE1lc3NhZ2UoWE1MRXJyb3JSZXNvdXJjZXMuRVJfQVhJU19UUkFWRVJTRVJfTk9UX1NVUFBPUlRFRCwgbmV3IE9iamVjdFtde0F4aXMuZ2V0TmFtZXMoYXhpcyl9KSk7Ci0gICAgICAvLyAiQXhpcyB0cmF2ZXJzZXIgbm90IHN1cHBvcnRlZDogIgotICAgICAgLy8gICAgICAgICAgICAgICAgICAgICAgICsgQXhpcy5uYW1lc1theGlzXSk7Ci0KLSAgICBtX3RyYXZlcnNlcnNbYXhpc10gPSB0cmF2ZXJzZXI7Ci0KLSAgICByZXR1cm4gdHJhdmVyc2VyOwotICB9Ci0KLSAgLyoqCi0gICAqIEltcGxlbWVudHMgdHJhdmVyc2FsIG9mIHRoZSBBbmNlc3RvciBhY2Nlc3MsIGluIHJldmVyc2UgZG9jdW1lbnQgb3JkZXIuCi0gICAqLwotICBwcml2YXRlIGNsYXNzIEFuY2VzdG9yVHJhdmVyc2VyIGV4dGVuZHMgRFRNQXhpc1RyYXZlcnNlcgotICB7Ci0KLSAgICAvKioKLSAgICAgKiBUcmF2ZXJzZSB0byB0aGUgbmV4dCBub2RlIGFmdGVyIHRoZSBjdXJyZW50IG5vZGUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCBub2RlIGlmIHRoaXMgaXRlcmF0aW9uLgotICAgICAqIEBwYXJhbSBjdXJyZW50IFRoZSBjdXJyZW50IG5vZGUgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdGhlIG5leHQgbm9kZSBpbiB0aGUgaXRlcmF0aW9uLCBvciBEVE0uTlVMTC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IG5leHQoaW50IGNvbnRleHQsIGludCBjdXJyZW50KQotICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBnZXRQYXJlbnQoY3VycmVudCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhdmVyc2UgdG8gdGhlIG5leHQgbm9kZSBhZnRlciB0aGUgY3VycmVudCBub2RlIHRoYXQgaXMgbWF0Y2hlZAotICAgICAqIGJ5IHRoZSBleHBhbmRlZCB0eXBlIElELgotICAgICAqCi0gICAgICogQHBhcmFtIGNvbnRleHQgVGhlIGNvbnRleHQgbm9kZSBvZiB0aGlzIGl0ZXJhdGlvbi4KLSAgICAgKiBAcGFyYW0gY3VycmVudCBUaGUgY3VycmVudCBub2RlIG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICogQHBhcmFtIGV4cGFuZGVkVHlwZUlEIFRoZSBleHBhbmRlZCB0eXBlIElEIHRoYXQgbXVzdCBtYXRjaC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdGhlIG5leHQgbm9kZSBpbiB0aGUgaXRlcmF0aW9uLCBvciBEVE0uTlVMTC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IG5leHQoaW50IGNvbnRleHQsIGludCBjdXJyZW50LCBpbnQgZXhwYW5kZWRUeXBlSUQpCi0gICAgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gUHJvY2VzcyB1c2luZyBpZGVudGl0aWVzCi0gICAgICBjdXJyZW50ID0gbWFrZU5vZGVJZGVudGl0eShjdXJyZW50KTsKLQotICAgICAgd2hpbGUgKERUTS5OVUxMICE9IChjdXJyZW50ID0gbV9wYXJlbnQuZWxlbWVudEF0KGN1cnJlbnQpKSkKLSAgICAgIHsKLSAgICAgICAgaWYgKG1fZXhwdHlwZS5lbGVtZW50QXQoY3VycmVudCkgPT0gZXhwYW5kZWRUeXBlSUQpCi0gICAgICAgICAgcmV0dXJuIG1ha2VOb2RlSGFuZGxlKGN1cnJlbnQpOwotICAgICAgfQotCi0gICAgICByZXR1cm4gTlVMTDsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogSW1wbGVtZW50cyB0cmF2ZXJzYWwgb2YgdGhlIEFuY2VzdG9yIGFjY2VzcywgaW4gcmV2ZXJzZSBkb2N1bWVudCBvcmRlci4KLSAgICovCi0gIHByaXZhdGUgY2xhc3MgQW5jZXN0b3JPclNlbGZUcmF2ZXJzZXIgZXh0ZW5kcyBBbmNlc3RvclRyYXZlcnNlcgotICB7Ci0KLSAgICAvKioKLSAgICAgKiBCeSB0aGUgbmF0dXJlIG9mIHRoZSBzdGF0ZWxlc3MgdHJhdmVyc2FsLCB0aGUgY29udGV4dCBub2RlIGNhbiBub3QgYmUKLSAgICAgKiByZXR1cm5lZCBvciB0aGUgaXRlcmF0aW9uIHdpbGwgZ28gaW50byBhbiBpbmZpbmF0ZSBsb29wLiAgVG8gc2VlIGlmCi0gICAgICogdGhlIHNlbGYgbm9kZSBzaG91bGQgYmUgcHJvY2Vzc2VkLCB1c2UgdGhpcyBmdW5jdGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjb250ZXh0IFRoZSBjb250ZXh0IG5vZGUgb2YgdGhpcyB0cmF2ZXJzYWwuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRoZSBmaXJzdCBub2RlIGluIHRoZSB0cmF2ZXJzYWwuCi0gICAgICovCi0gICAgcHVibGljIGludCBmaXJzdChpbnQgY29udGV4dCkKLSAgICB7Ci0gICAgICByZXR1cm4gY29udGV4dDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBCeSB0aGUgbmF0dXJlIG9mIHRoZSBzdGF0ZWxlc3MgdHJhdmVyc2FsLCB0aGUgY29udGV4dCBub2RlIGNhbiBub3QgYmUKLSAgICAgKiByZXR1cm5lZCBvciB0aGUgaXRlcmF0aW9uIHdpbGwgZ28gaW50byBhbiBpbmZpbmF0ZSBsb29wLiAgVG8gc2VlIGlmCi0gICAgICogdGhlIHNlbGYgbm9kZSBzaG91bGQgYmUgcHJvY2Vzc2VkLCB1c2UgdGhpcyBmdW5jdGlvbi4gIElmIHRoZSBjb250ZXh0Ci0gICAgICogbm9kZSBkb2VzIG5vdCBtYXRjaCB0aGUgZXhwYW5kZWQgdHlwZSBJRCwgdGhpcyBmdW5jdGlvbiB3aWxsIHJldHVybgotICAgICAqIGZhbHNlLgotICAgICAqCi0gICAgICogQHBhcmFtIGNvbnRleHQgVGhlIGNvbnRleHQgbm9kZSBvZiB0aGlzIHRyYXZlcnNhbC4KLSAgICAgKiBAcGFyYW0gZXhwYW5kZWRUeXBlSUQgVGhlIGV4cGFuZGVkIHR5cGUgSUQgdGhhdCBtdXN0IG1hdGNoLgotICAgICAqCi0gICAgICogQHJldHVybiB0aGUgZmlyc3Qgbm9kZSBpbiB0aGUgdHJhdmVyc2FsLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZmlyc3QoaW50IGNvbnRleHQsIGludCBleHBhbmRlZFR5cGVJRCkKLSAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKGdldEV4cGFuZGVkVHlwZUlEKGNvbnRleHQpID09IGV4cGFuZGVkVHlwZUlEKQotICAgICAgICAgICAgID8gY29udGV4dCA6IG5leHQoY29udGV4dCwgY29udGV4dCwgZXhwYW5kZWRUeXBlSUQpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBJbXBsZW1lbnRzIHRyYXZlcnNhbCBvZiB0aGUgQXR0cmlidXRlIGFjY2VzcwotICAgKi8KLSAgcHJpdmF0ZSBjbGFzcyBBdHRyaWJ1dGVUcmF2ZXJzZXIgZXh0ZW5kcyBEVE1BeGlzVHJhdmVyc2VyCi0gIHsKLQotICAgIC8qKgotICAgICAqIFRyYXZlcnNlIHRvIHRoZSBuZXh0IG5vZGUgYWZ0ZXIgdGhlIGN1cnJlbnQgbm9kZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjb250ZXh0IFRoZSBjb250ZXh0IG5vZGUgb2YgdGhpcyBpdGVyYXRpb24uCi0gICAgICogQHBhcmFtIGN1cnJlbnQgVGhlIGN1cnJlbnQgbm9kZSBvZiB0aGUgaXRlcmF0aW9uLgotICAgICAqCi0gICAgICogQHJldHVybiB0aGUgbmV4dCBub2RlIGluIHRoZSBpdGVyYXRpb24sIG9yIERUTS5OVUxMLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgbmV4dChpbnQgY29udGV4dCwgaW50IGN1cnJlbnQpCi0gICAgewotICAgICAgcmV0dXJuIChjb250ZXh0ID09IGN1cnJlbnQpCi0gICAgICAgICAgICAgPyBnZXRGaXJzdEF0dHJpYnV0ZShjb250ZXh0KSA6IGdldE5leHRBdHRyaWJ1dGUoY3VycmVudCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhdmVyc2UgdG8gdGhlIG5leHQgbm9kZSBhZnRlciB0aGUgY3VycmVudCBub2RlIHRoYXQgaXMgbWF0Y2hlZAotICAgICAqIGJ5IHRoZSBleHBhbmRlZCB0eXBlIElELgotICAgICAqCi0gICAgICogQHBhcmFtIGNvbnRleHQgVGhlIGNvbnRleHQgbm9kZSBvZiB0aGlzIGl0ZXJhdGlvbi4KLSAgICAgKiBAcGFyYW0gY3VycmVudCBUaGUgY3VycmVudCBub2RlIG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICogQHBhcmFtIGV4cGFuZGVkVHlwZUlEIFRoZSBleHBhbmRlZCB0eXBlIElEIHRoYXQgbXVzdCBtYXRjaC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdGhlIG5leHQgbm9kZSBpbiB0aGUgaXRlcmF0aW9uLCBvciBEVE0uTlVMTC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IG5leHQoaW50IGNvbnRleHQsIGludCBjdXJyZW50LCBpbnQgZXhwYW5kZWRUeXBlSUQpCi0gICAgewotCi0gICAgICBjdXJyZW50ID0gKGNvbnRleHQgPT0gY3VycmVudCkKLSAgICAgICAgICAgICAgICA/IGdldEZpcnN0QXR0cmlidXRlKGNvbnRleHQpIDogZ2V0TmV4dEF0dHJpYnV0ZShjdXJyZW50KTsKLQotICAgICAgZG8KLSAgICAgIHsKLSAgICAgICAgaWYgKGdldEV4cGFuZGVkVHlwZUlEKGN1cnJlbnQpID09IGV4cGFuZGVkVHlwZUlEKQotICAgICAgICAgIHJldHVybiBjdXJyZW50OwotICAgICAgfQotICAgICAgd2hpbGUgKERUTS5OVUxMICE9IChjdXJyZW50ID0gZ2V0TmV4dEF0dHJpYnV0ZShjdXJyZW50KSkpOwotCi0gICAgICByZXR1cm4gTlVMTDsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogSW1wbGVtZW50cyB0cmF2ZXJzYWwgb2YgdGhlIEFuY2VzdG9yIGFjY2VzcywgaW4gcmV2ZXJzZSBkb2N1bWVudCBvcmRlci4KLSAgICovCi0gIHByaXZhdGUgY2xhc3MgQ2hpbGRUcmF2ZXJzZXIgZXh0ZW5kcyBEVE1BeGlzVHJhdmVyc2VyCi0gIHsKLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgbmV4dCBpbmRleGVkIG5vZGUgdGhhdCBtYXRjaGVzIHRoZSBleHBhbmRlZCB0eXBlIElELiAgQmVmb3JlCi0gICAgICogY2FsbGluZyB0aGlzIGZ1bmN0aW9uLCBvbmUgc2hvdWxkIGZpcnN0IGNhbGwKLSAgICAgKiB7QGxpbmsgI2lzSW5kZXhlZChpbnQpIGlzSW5kZXhlZH0gdG8gbWFrZSBzdXJlIHRoYXQgdGhlIGluZGV4IGNhbgotICAgICAqIGNvbnRhaW4gbm9kZXMgdGhhdCBtYXRjaCB0aGUgZ2l2ZW4gZXhwYW5kZWQgdHlwZSBJRC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBheGlzUm9vdCBUaGUgcm9vdCBpZGVudGl0eSBvZiB0aGUgYXhpcy4KLSAgICAgKiBAcGFyYW0gbmV4dFBvdGVudGlhbCBUaGUgbm9kZSBmb3VuZCBtdXN0IG1hdGNoIG9yIG9jY3VyIGFmdGVyIHRoaXMgbm9kZS4KLSAgICAgKiBAcGFyYW0gZXhwYW5kZWRUeXBlSUQgVGhlIGV4cGFuZGVkIHR5cGUgSUQgZm9yIHRoZSByZXF1ZXN0LgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgbm9kZSBJRCBvciBOVUxMIGlmIG5vdCBmb3VuZC4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgaW50IGdldE5leHRJbmRleGVkKGludCBheGlzUm9vdCwgaW50IG5leHRQb3RlbnRpYWwsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgZXhwYW5kZWRUeXBlSUQpCi0gICAgewotCi0gICAgICBpbnQgbnNJbmRleCA9IG1fZXhwYW5kZWROYW1lVGFibGUuZ2V0TmFtZXNwYWNlSUQoZXhwYW5kZWRUeXBlSUQpOwotICAgICAgaW50IGxuSW5kZXggPSBtX2V4cGFuZGVkTmFtZVRhYmxlLmdldExvY2FsTmFtZUlEKGV4cGFuZGVkVHlwZUlEKTsKLQotICAgICAgZm9yICg7IDsgKQotICAgICAgewotICAgICAgICBpbnQgbmV4dElEID0gZmluZEVsZW1lbnRGcm9tSW5kZXgobnNJbmRleCwgbG5JbmRleCwgbmV4dFBvdGVudGlhbCk7Ci0KLSAgICAgICAgaWYgKE5PVFBST0NFU1NFRCAhPSBuZXh0SUQpCi0gICAgICAgIHsKLSAgICAgICAgICBpbnQgcGFyZW50SUQgPSBtX3BhcmVudC5lbGVtZW50QXQobmV4dElEKTsKLQotICAgICAgICAgIC8vIElzIGl0IGEgY2hpbGQ/Ci0gICAgICAgICAgaWYocGFyZW50SUQgPT0gYXhpc1Jvb3QpCi0gICAgICAgICAgICByZXR1cm4gbmV4dElEOwotCi0gICAgICAgICAgLy8gSWYgdGhlIHBhcmVudCBvY2N1cmVkIGJlZm9yZSB0aGUgc3VidHJlZSByb290LCB0aGVuCi0gICAgICAgICAgLy8gd2Uga25vdyBpdCBpcyBwYXN0IHRoZSBjaGlsZCBheGlzLgotICAgICAgICAgIGlmKHBhcmVudElEIDwgYXhpc1Jvb3QpCi0gICAgICAgICAgICAgIHJldHVybiBOVUxMOwotCi0gICAgICAgICAgLy8gT3RoZXJ3aXNlLCBpdCBjb3VsZCBiZSBhIGRlc2NlbmRhbnQgYmVsb3cgdGhlIHN1YnRyZWUgcm9vdAotICAgICAgICAgIC8vIGNoaWxkcmVuLCBvciBpdCBjb3VsZCBiZSBhZnRlciB0aGUgc3VidHJlZSByb290LiAgU28gd2UgaGF2ZQotICAgICAgICAgIC8vIHRvIGNsaW1iIHVwIHVudGlsIHRoZSBwYXJlbnQgaXMgbGVzcyB0aGFuIHRoZSBzdWJ0cmVlIHJvb3QsIGluCi0gICAgICAgICAgLy8gd2hpY2ggY2FzZSB3ZSByZXR1cm4gTlVMTCwgb3IgdW50aWwgaXQgaXMgZXF1YWwgdG8gdGhlIHN1YnRyZWUKLSAgICAgICAgICAvLyByb290LCBpbiB3aGljaCBjYXNlIHdlIGNvbnRpbnVlIHRvIGxvb2suCi0gICAgICAgICAgZG8KLSAgICAgICAgICB7Ci0gICAgICAgICAgICBwYXJlbnRJRCA9IG1fcGFyZW50LmVsZW1lbnRBdChwYXJlbnRJRCk7Ci0gICAgICAgICAgICBpZihwYXJlbnRJRCA8IGF4aXNSb290KQotICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKLSAgICAgICAgICB9Ci0gICAgICAgICAgICB3aGlsZShwYXJlbnRJRCA+IGF4aXNSb290KTsKLQotICAgICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiRm91bmQgbm9kZSB2aWEgaW5kZXg6ICIrZmlyc3QpOwotICAgICAgICAgIG5leHRQb3RlbnRpYWwgPSBuZXh0SUQrMTsKLSAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgfQotCi0gICAgICAgIG5leHROb2RlKCk7Ci0KLSAgICAgICAgaWYoIShtX25leHRzaWIuZWxlbWVudEF0KGF4aXNSb290KSA9PSBOT1RQUk9DRVNTRUQpKQotICAgICAgICAgIGJyZWFrOwotICAgICAgfQotCi0gICAgICByZXR1cm4gRFRNLk5VTEw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQnkgdGhlIG5hdHVyZSBvZiB0aGUgc3RhdGVsZXNzIHRyYXZlcnNhbCwgdGhlIGNvbnRleHQgbm9kZSBjYW4gbm90IGJlCi0gICAgICogcmV0dXJuZWQgb3IgdGhlIGl0ZXJhdGlvbiB3aWxsIGdvIGludG8gYW4gaW5maW5hdGUgbG9vcC4gIFNvIHRvIHRyYXZlcnNlCi0gICAgICogYW4gYXhpcywgdGhlIGZpcnN0IGZ1bmN0aW9uIG11c3QgYmUgdXNlZCB0byBnZXQgdGhlIGZpcnN0IG5vZGUuCi0gICAgICoKLSAgICAgKiA8cD5UaGlzIG1ldGhvZCBuZWVkcyB0byBiZSBvdmVybG9hZGVkIG9ubHkgYnkgdGhvc2UgYXhpcyB0aGF0IHByb2Nlc3MKLSAgICAgKiB0aGUgc2VsZiBub2RlLiA8XHA+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCBub2RlIG9mIHRoaXMgdHJhdmVyc2FsLiBUaGlzIGlzIHRoZSBwb2ludAotICAgICAqIHRoYXQgdGhlIHRyYXZlcnNhbCBzdGFydHMgZnJvbS4KLSAgICAgKiBAcmV0dXJuIHRoZSBmaXJzdCBub2RlIGluIHRoZSB0cmF2ZXJzYWwuCi0gICAgICovCi0gICAgcHVibGljIGludCBmaXJzdChpbnQgY29udGV4dCkKLSAgICB7Ci0gICAgICByZXR1cm4gZ2V0Rmlyc3RDaGlsZChjb250ZXh0KTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBCeSB0aGUgbmF0dXJlIG9mIHRoZSBzdGF0ZWxlc3MgdHJhdmVyc2FsLCB0aGUgY29udGV4dCBub2RlIGNhbiBub3QgYmUKLSAgICAgKiByZXR1cm5lZCBvciB0aGUgaXRlcmF0aW9uIHdpbGwgZ28gaW50byBhbiBpbmZpbmF0ZSBsb29wLiAgU28gdG8gdHJhdmVyc2UKLSAgICAgKiBhbiBheGlzLCB0aGUgZmlyc3QgZnVuY3Rpb24gbXVzdCBiZSB1c2VkIHRvIGdldCB0aGUgZmlyc3Qgbm9kZS4KLSAgICAgKgotICAgICAqIDxwPlRoaXMgbWV0aG9kIG5lZWRzIHRvIGJlIG92ZXJsb2FkZWQgb25seSBieSB0aG9zZSBheGlzIHRoYXQgcHJvY2VzcwotICAgICAqIHRoZSBzZWxmIG5vZGUuIDxccD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjb250ZXh0IFRoZSBjb250ZXh0IG5vZGUgb2YgdGhpcyB0cmF2ZXJzYWwuIFRoaXMgaXMgdGhlIHBvaW50Ci0gICAgICogb2Ygb3JpZ2luIGZvciB0aGUgdHJhdmVyc2FsIC0tIGl0cyAicm9vdCBub2RlIiBvciBzdGFydGluZyBwb2ludC4KLSAgICAgKiBAcGFyYW0gZXhwYW5kZWRUeXBlSUQgVGhlIGV4cGFuZGVkIHR5cGUgSUQgdGhhdCBtdXN0IG1hdGNoLgotICAgICAqCi0gICAgICogQHJldHVybiB0aGUgZmlyc3Qgbm9kZSBpbiB0aGUgdHJhdmVyc2FsLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZmlyc3QoaW50IGNvbnRleHQsIGludCBleHBhbmRlZFR5cGVJRCkKLSAgICB7Ci0gICAgICBpZih0cnVlKQotICAgICAgewotICAgICAgICBpbnQgaWRlbnRpdHkgPSBtYWtlTm9kZUlkZW50aXR5KGNvbnRleHQpOwotCi0gICAgICAgIGludCBmaXJzdE1hdGNoID0gZ2V0TmV4dEluZGV4ZWQoaWRlbnRpdHksIF9maXJzdGNoKGlkZW50aXR5KSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cGFuZGVkVHlwZUlEKTsKLQotICAgICAgICByZXR1cm4gbWFrZU5vZGVIYW5kbGUoZmlyc3RNYXRjaCk7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICVSRVZJRVclIERlYWQgY29kZS4gRWxpbWluYXRlPwotICAgICAgICBmb3IgKGludCBjdXJyZW50ID0gX2ZpcnN0Y2gobWFrZU5vZGVJZGVudGl0eShjb250ZXh0KSk7Ci0gICAgICAgICAgICAgRFRNLk5VTEwgIT0gY3VycmVudDsKLSAgICAgICAgICAgICBjdXJyZW50ID0gX25leHRzaWIoY3VycmVudCkpCi0gICAgICAgIHsKLSAgICAgICAgICBpZiAobV9leHB0eXBlLmVsZW1lbnRBdChjdXJyZW50KSA9PSBleHBhbmRlZFR5cGVJRCkKLSAgICAgICAgICAgICAgcmV0dXJuIG1ha2VOb2RlSGFuZGxlKGN1cnJlbnQpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBOVUxMOwotICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYXZlcnNlIHRvIHRoZSBuZXh0IG5vZGUgYWZ0ZXIgdGhlIGN1cnJlbnQgbm9kZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjb250ZXh0IFRoZSBjb250ZXh0IG5vZGUgb2YgdGhpcyBpdGVyYXRpb24uCi0gICAgICogQHBhcmFtIGN1cnJlbnQgVGhlIGN1cnJlbnQgbm9kZSBvZiB0aGUgaXRlcmF0aW9uLgotICAgICAqCi0gICAgICogQHJldHVybiB0aGUgbmV4dCBub2RlIGluIHRoZSBpdGVyYXRpb24sIG9yIERUTS5OVUxMLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgbmV4dChpbnQgY29udGV4dCwgaW50IGN1cnJlbnQpCi0gICAgewotICAgICAgcmV0dXJuIGdldE5leHRTaWJsaW5nKGN1cnJlbnQpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYXZlcnNlIHRvIHRoZSBuZXh0IG5vZGUgYWZ0ZXIgdGhlIGN1cnJlbnQgbm9kZSB0aGF0IGlzIG1hdGNoZWQKLSAgICAgKiBieSB0aGUgZXhwYW5kZWQgdHlwZSBJRC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjb250ZXh0IFRoZSBjb250ZXh0IG5vZGUgb2YgdGhpcyBpdGVyYXRpb24uCi0gICAgICogQHBhcmFtIGN1cnJlbnQgVGhlIGN1cnJlbnQgbm9kZSBvZiB0aGUgaXRlcmF0aW9uLgotICAgICAqIEBwYXJhbSBleHBhbmRlZFR5cGVJRCBUaGUgZXhwYW5kZWQgdHlwZSBJRCB0aGF0IG11c3QgbWF0Y2guCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRoZSBuZXh0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbiwgb3IgRFRNLk5VTEwuCi0gICAgICovCi0gICAgcHVibGljIGludCBuZXh0KGludCBjb250ZXh0LCBpbnQgY3VycmVudCwgaW50IGV4cGFuZGVkVHlwZUlEKQotICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIFByb2Nlc3MgaW4gSWRlbnRpZmllciBzcGFjZQotICAgICAgZm9yIChjdXJyZW50ID0gX25leHRzaWIobWFrZU5vZGVJZGVudGl0eShjdXJyZW50KSk7Ci0gICAgICAgICAgIERUTS5OVUxMICE9IGN1cnJlbnQ7Ci0gICAgICAgICAgIGN1cnJlbnQgPSBfbmV4dHNpYihjdXJyZW50KSkKLSAgICAgIHsKLSAgICAgICAgaWYgKG1fZXhwdHlwZS5lbGVtZW50QXQoY3VycmVudCkgPT0gZXhwYW5kZWRUeXBlSUQpCi0gICAgICAgICAgICByZXR1cm4gbWFrZU5vZGVIYW5kbGUoY3VycmVudCk7Ci0gICAgICB9Ci0KLSAgICAgIHJldHVybiBOVUxMOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBTdXBlciBjbGFzcyBmb3IgZGVyaXZlZCBjbGFzc2VzIHRoYXQgd2FudCBhIGNvbnZlbmllbnQgd2F5IHRvIGFjY2VzcwotICAgKiB0aGUgaW5kZXhpbmcgbWVjaGFuaXNtLgotICAgKi8KLSAgcHJpdmF0ZSBhYnN0cmFjdCBjbGFzcyBJbmRleGVkRFRNQXhpc1RyYXZlcnNlciBleHRlbmRzIERUTUF4aXNUcmF2ZXJzZXIKLSAgewotCi0gICAgLyoqCi0gICAgICogVGVsbCBpZiB0aGUgaW5kZXhpbmcgaXMgb24gYW5kIHRoZSBnaXZlbiBleHBhbmRlZCB0eXBlIElEIG1hdGNoZXMKLSAgICAgKiB3aGF0IGlzIGluIHRoZSBpbmRleGVzLiAgRGVyaXZlZCBjbGFzc2VzIHNob3VsZCBjYWxsIHRoaXMgYmVmb3JlCi0gICAgICogY2FsbGluZyB7QGxpbmsgI2dldE5leHRJbmRleGVkKGludCwgaW50LCBpbnQpIGdldE5leHRJbmRleGVkfSBtZXRob2QuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZXhwYW5kZWRUeXBlSUQgVGhlIGV4cGFuZGVkIHR5cGUgSUQgYmVpbmcgcmVxdWVzdGVkLgotICAgICAqCi0gICAgICogQHJldHVybiB0cnVlIGlmIGl0IGlzIE9LIHRvIGNhbGwgdGhlCi0gICAgICogICAgICAgICB7QGxpbmsgI2dldE5leHRJbmRleGVkKGludCwgaW50LCBpbnQpIGdldE5leHRJbmRleGVkfSBtZXRob2QuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGZpbmFsIGJvb2xlYW4gaXNJbmRleGVkKGludCBleHBhbmRlZFR5cGVJRCkKLSAgICB7Ci0gICAgICByZXR1cm4gKG1faW5kZXhpbmcKLSAgICAgICAgICAgICAgJiYgRXhwYW5kZWROYW1lVGFibGUuRUxFTUVOVAotICAgICAgICAgICAgICAgICA9PSBtX2V4cGFuZGVkTmFtZVRhYmxlLmdldFR5cGUoZXhwYW5kZWRUeXBlSUQpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUZWxsIGlmIGEgbm9kZSBpcyBvdXRzaWRlIHRoZSBheGlzIGJlaW5nIHRyYXZlcnNlZC4gIFRoaXMgbWV0aG9kIG11c3QgYmUKLSAgICAgKiBpbXBsZW1lbnRlZCBieSBkZXJpdmVkIGNsYXNzZXMsIGFuZCBtdXN0IGJlIHJvYnVzdCBlbm91Z2ggdG8gaGFuZGxlIGFueQotICAgICAqIG5vZGUgdGhhdCBvY2N1cnMgYWZ0ZXIgdGhlIGF4aXMgcm9vdC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBheGlzUm9vdCBUaGUgcm9vdCBpZGVudGl0eSBvZiB0aGUgYXhpcy4KLSAgICAgKiBAcGFyYW0gaWRlbnRpdHkgVGhlIG5vZGUgaW4gcXVlc3Rpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGdpdmVuIG5vZGUgZmFsbHMgb3V0c2lkZSB0aGUgYXhpcyBiZWluZyB0cmF2ZXJzZWQuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGFic3RyYWN0IGJvb2xlYW4gaXNBZnRlckF4aXMoaW50IGF4aXNSb290LCBpbnQgaWRlbnRpdHkpOwotCi0gICAgLyoqCi0gICAgICogVGVsbCBpZiB0aGUgYXhpcyBoYXMgYmVlbiBmdWxseSBwcm9jZXNzZWQgdG8gdGVsbCBpZiBhIHRoZSB3YWl0IGZvcgotICAgICAqIGFuIGFycml2aW5nIG5vZGUgc2hvdWxkIHRlcm1pbmF0ZS4gIFRoaXMgbWV0aG9kIG11c3QgYmUgaW1wbGVtZW50ZWQKLSAgICAgKiBiZSBhIGRlcml2ZWQgY2xhc3MuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYXhpc1Jvb3QgVGhlIHJvb3QgaWRlbnRpdHkgb2YgdGhlIGF4aXMuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGF4aXMgaGFzIGJlZW4gZnVsbHkgcHJvY2Vzc2VkLgotICAgICAqLwotICAgIHByb3RlY3RlZCBhYnN0cmFjdCBib29sZWFuIGF4aXNIYXNCZWVuUHJvY2Vzc2VkKGludCBheGlzUm9vdCk7Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIG5leHQgaW5kZXhlZCBub2RlIHRoYXQgbWF0Y2hlcyB0aGUgZXhwYW5kZWQgdHlwZSBJRC4gIEJlZm9yZQotICAgICAqIGNhbGxpbmcgdGhpcyBmdW5jdGlvbiwgb25lIHNob3VsZCBmaXJzdCBjYWxsCi0gICAgICoge0BsaW5rICNpc0luZGV4ZWQoaW50KSBpc0luZGV4ZWR9IHRvIG1ha2Ugc3VyZSB0aGF0IHRoZSBpbmRleCBjYW4KLSAgICAgKiBjb250YWluIG5vZGVzIHRoYXQgbWF0Y2ggdGhlIGdpdmVuIGV4cGFuZGVkIHR5cGUgSUQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYXhpc1Jvb3QgVGhlIHJvb3QgaWRlbnRpdHkgb2YgdGhlIGF4aXMuCi0gICAgICogQHBhcmFtIG5leHRQb3RlbnRpYWwgVGhlIG5vZGUgZm91bmQgbXVzdCBtYXRjaCBvciBvY2N1ciBhZnRlciB0aGlzIG5vZGUuCi0gICAgICogQHBhcmFtIGV4cGFuZGVkVHlwZUlEIFRoZSBleHBhbmRlZCB0eXBlIElEIGZvciB0aGUgcmVxdWVzdC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIG5vZGUgSUQgb3IgTlVMTCBpZiBub3QgZm91bmQuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGludCBnZXROZXh0SW5kZXhlZChpbnQgYXhpc1Jvb3QsIGludCBuZXh0UG90ZW50aWFsLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGV4cGFuZGVkVHlwZUlEKQotICAgIHsKLQotICAgICAgaW50IG5zSW5kZXggPSBtX2V4cGFuZGVkTmFtZVRhYmxlLmdldE5hbWVzcGFjZUlEKGV4cGFuZGVkVHlwZUlEKTsKLSAgICAgIGludCBsbkluZGV4ID0gbV9leHBhbmRlZE5hbWVUYWJsZS5nZXRMb2NhbE5hbWVJRChleHBhbmRlZFR5cGVJRCk7Ci0KLSAgICAgIHdoaWxlKHRydWUpCi0gICAgICB7Ci0gICAgICAgIGludCBuZXh0ID0gZmluZEVsZW1lbnRGcm9tSW5kZXgobnNJbmRleCwgbG5JbmRleCwgbmV4dFBvdGVudGlhbCk7Ci0KLSAgICAgICAgaWYgKE5PVFBST0NFU1NFRCAhPSBuZXh0KQotICAgICAgICB7Ci0gICAgICAgICAgaWYgKGlzQWZ0ZXJBeGlzKGF4aXNSb290LCBuZXh0KSkKLSAgICAgICAgICAgIHJldHVybiBOVUxMOwotCi0gICAgICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJGb3VuZCBub2RlIHZpYSBpbmRleDogIitmaXJzdCk7Ci0gICAgICAgICAgcmV0dXJuIG5leHQ7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZihheGlzSGFzQmVlblByb2Nlc3NlZChheGlzUm9vdCkpCi0gICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgbmV4dE5vZGUoKTsKLSAgICAgIH0KLQotICAgICAgcmV0dXJuIERUTS5OVUxMOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBJbXBsZW1lbnRzIHRyYXZlcnNhbCBvZiB0aGUgQW5jZXN0b3IgYWNjZXNzLCBpbiByZXZlcnNlIGRvY3VtZW50IG9yZGVyLgotICAgKi8KLSAgcHJpdmF0ZSBjbGFzcyBEZXNjZW5kYW50VHJhdmVyc2VyIGV4dGVuZHMgSW5kZXhlZERUTUF4aXNUcmF2ZXJzZXIKLSAgewotICAgIC8qKgotICAgICAqIEdldCB0aGUgZmlyc3QgcG90ZW50aWFsIGlkZW50aXR5IHRoYXQgY2FuIGJlIHJldHVybmVkLiAgVGhpcyBzaG91bGQKLSAgICAgKiBiZSBvdmVycmlkZGVkIGJ5IGNsYXNzZXMgdGhhdCBuZWVkIHRvIHJldHVybiB0aGUgc2VsZiBub2RlLgotICAgICAqCi0gICAgICogQHBhcmFtIGlkZW50aXR5IFRoZSBub2RlIGlkZW50aXR5IG9mIHRoZSByb290IGNvbnRleHQgb2YgdGhlIHRyYXZlcnNhbC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIGZpcnN0IHBvdGVudGlhbCBub2RlIHRoYXQgY2FuIGJlIGluIHRoZSB0cmF2ZXJzYWwuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGludCBnZXRGaXJzdFBvdGVudGlhbChpbnQgaWRlbnRpdHkpCi0gICAgewotICAgICAgcmV0dXJuIGlkZW50aXR5ICsgMTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUZWxsIGlmIHRoZSBheGlzIGhhcyBiZWVuIGZ1bGx5IHByb2Nlc3NlZCB0byB0ZWxsIGlmIGEgdGhlIHdhaXQgZm9yCi0gICAgICogYW4gYXJyaXZpbmcgbm9kZSBzaG91bGQgdGVybWluYXRlLgotICAgICAqCi0gICAgICogQHBhcmFtIGF4aXNSb290IFRoZSByb290IGlkZW50aXR5IG9mIHRoZSBheGlzLgotICAgICAqCi0gICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBheGlzIGhhcyBiZWVuIGZ1bGx5IHByb2Nlc3NlZC4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBheGlzSGFzQmVlblByb2Nlc3NlZChpbnQgYXhpc1Jvb3QpCi0gICAgewotICAgICAgcmV0dXJuICEobV9uZXh0c2liLmVsZW1lbnRBdChheGlzUm9vdCkgPT0gTk9UUFJPQ0VTU0VEKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIHN1YnRyZWUgcm9vdCBpZGVudGl0eSBmcm9tIHRoZSBoYW5kbGUgdGhhdCB3YXMgcGFzc2VkIGluIGJ5Ci0gICAgICogdGhlIGNhbGxlci4gIERlcml2ZWQgY2xhc3NlcyBtYXkgb3ZlcnJpZGUgdGhpcyB0byBjaGFuZ2UgdGhlIHJvb3QKLSAgICAgKiBjb250ZXh0IG9mIHRoZSB0cmF2ZXJzYWwuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaGFuZGxlIGhhbmRsZSB0byB0aGUgcm9vdCBjb250ZXh0LgotICAgICAqIEByZXR1cm4gaWRlbnRpdHkgb2YgdGhlIHJvb3Qgb2YgdGhlIHN1YnRyZWUuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGludCBnZXRTdWJ0cmVlUm9vdChpbnQgaGFuZGxlKQotICAgIHsKLSAgICAgIHJldHVybiBtYWtlTm9kZUlkZW50aXR5KGhhbmRsZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGVsbCBpZiB0aGlzIG5vZGUgaWRlbnRpdHkgaXMgYSBkZXNjZW5kYW50LiAgQXNzdW1lcyB0aGF0Ci0gICAgICogdGhlIG5vZGUgaW5mbyBmb3IgdGhlIGVsZW1lbnQgaGFzIGFscmVhZHkgYmVlbiBvYnRhaW5lZC4KLSAgICAgKgotICAgICAqICVSRVZJRVclIFRoaXMgaXMgcmVhbGx5IHBhcmVudEZvbGxvd3NSb290SW5Eb2N1bWVudE9yZGVyIC4uLgotICAgICAqIHdoaWNoIGZhaWxzIGlmIHRoZSBwYXJlbnQgc3RhcnRzIGFmdGVyIHRoZSByb290IGVuZHMuCi0gICAgICogTWF5IGJlIHN1ZmZpY2llbnQgZm9yIHRoaXMgY2xhc3MncyBsb2dpYywgYnV0IG1pc2xlYWRpbmdseSBuYW1lZCEKLSAgICAgKgotICAgICAqIEBwYXJhbSBzdWJ0cmVlUm9vdElkZW50aXR5IFRoZSByb290IGNvbnRleHQgb2YgdGhlIHN1YnRyZWUgaW4gcXVlc3Rpb24uCi0gICAgICogQHBhcmFtIGlkZW50aXR5IFRoZSBpbmRleCBudW1iZXIgb2YgdGhlIG5vZGUgaW4gcXVlc3Rpb24uCi0gICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBpbmRleCBpcyBhIGRlc2NlbmRhbnQgb2YgX3N0YXJ0Tm9kZS4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBpc0Rlc2NlbmRhbnQoaW50IHN1YnRyZWVSb290SWRlbnRpdHksIGludCBpZGVudGl0eSkKLSAgICB7Ci0gICAgICByZXR1cm4gX3BhcmVudChpZGVudGl0eSkgPj0gc3VidHJlZVJvb3RJZGVudGl0eTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUZWxsIGlmIGEgbm9kZSBpcyBvdXRzaWRlIHRoZSBheGlzIGJlaW5nIHRyYXZlcnNlZC4gIFRoaXMgbWV0aG9kIG11c3QgYmUKLSAgICAgKiBpbXBsZW1lbnRlZCBieSBkZXJpdmVkIGNsYXNzZXMsIGFuZCBtdXN0IGJlIHJvYnVzdCBlbm91Z2ggdG8gaGFuZGxlIGFueQotICAgICAqIG5vZGUgdGhhdCBvY2N1cnMgYWZ0ZXIgdGhlIGF4aXMgcm9vdC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBheGlzUm9vdCBUaGUgcm9vdCBpZGVudGl0eSBvZiB0aGUgYXhpcy4KLSAgICAgKiBAcGFyYW0gaWRlbnRpdHkgVGhlIG5vZGUgaW4gcXVlc3Rpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGdpdmVuIG5vZGUgZmFsbHMgb3V0c2lkZSB0aGUgYXhpcyBiZWluZyB0cmF2ZXJzZWQuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gaXNBZnRlckF4aXMoaW50IGF4aXNSb290LCBpbnQgaWRlbnRpdHkpCi0gICAgewotICAgICAgLy8gJVJFVklFVyUgSXMgdGhlcmUgKmFueSogY2hlYXBlciB3YXkgdG8gZG8gdGhpcz8KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIFllcy4gSW4gSUQgc3BhY2UsIGNvbXBhcmUgdG8gYXhpc1Jvb3QncyBzdWNjZXNzb3IKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIChuZXh0LXNpYiBvciBhbmNlc3RvcidzLW5leHQtc2liKS4gUHJvYmFibHkgc2hhbGxvd2VyIHNlYXJjaC4KLSAgICAgIGRvCi0gICAgICB7Ci0gICAgICAgIGlmKGlkZW50aXR5ID09IGF4aXNSb290KQotICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgaWRlbnRpdHkgPSBtX3BhcmVudC5lbGVtZW50QXQoaWRlbnRpdHkpOwotICAgICAgfQotICAgICAgICB3aGlsZShpZGVudGl0eSA+PSBheGlzUm9vdCk7Ci0KLSAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEJ5IHRoZSBuYXR1cmUgb2YgdGhlIHN0YXRlbGVzcyB0cmF2ZXJzYWwsIHRoZSBjb250ZXh0IG5vZGUgY2FuIG5vdCBiZQotICAgICAqIHJldHVybmVkIG9yIHRoZSBpdGVyYXRpb24gd2lsbCBnbyBpbnRvIGFuIGluZmluYXRlIGxvb3AuICBTbyB0byB0cmF2ZXJzZQotICAgICAqIGFuIGF4aXMsIHRoZSBmaXJzdCBmdW5jdGlvbiBtdXN0IGJlIHVzZWQgdG8gZ2V0IHRoZSBmaXJzdCBub2RlLgotICAgICAqCi0gICAgICogPHA+VGhpcyBtZXRob2QgbmVlZHMgdG8gYmUgb3ZlcmxvYWRlZCBvbmx5IGJ5IHRob3NlIGF4aXMgdGhhdCBwcm9jZXNzCi0gICAgICogdGhlIHNlbGYgbm9kZS4gPFxwPgotICAgICAqCi0gICAgICogQHBhcmFtIGNvbnRleHQgVGhlIGNvbnRleHQgbm9kZSBvZiB0aGlzIHRyYXZlcnNhbC4gVGhpcyBpcyB0aGUgcG9pbnQKLSAgICAgKiBvZiBvcmlnaW4gZm9yIHRoZSB0cmF2ZXJzYWwgLS0gaXRzICJyb290IG5vZGUiIG9yIHN0YXJ0aW5nIHBvaW50LgotICAgICAqIEBwYXJhbSBleHBhbmRlZFR5cGVJRCBUaGUgZXhwYW5kZWQgdHlwZSBJRCB0aGF0IG11c3QgbWF0Y2guCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRoZSBmaXJzdCBub2RlIGluIHRoZSB0cmF2ZXJzYWwuCi0gICAgICovCi0gICAgcHVibGljIGludCBmaXJzdChpbnQgY29udGV4dCwgaW50IGV4cGFuZGVkVHlwZUlEKQotICAgIHsKLQotICAgICAgaWYgKGlzSW5kZXhlZChleHBhbmRlZFR5cGVJRCkpCi0gICAgICB7Ci0gICAgICAgIGludCBpZGVudGl0eSA9IGdldFN1YnRyZWVSb290KGNvbnRleHQpOwotICAgICAgICBpbnQgZmlyc3RQb3RlbnRpYWwgPSBnZXRGaXJzdFBvdGVudGlhbChpZGVudGl0eSk7Ci0KLSAgICAgICAgcmV0dXJuIG1ha2VOb2RlSGFuZGxlKGdldE5leHRJbmRleGVkKGlkZW50aXR5LCBmaXJzdFBvdGVudGlhbCwgZXhwYW5kZWRUeXBlSUQpKTsKLSAgICAgIH0KLQotICAgICAgcmV0dXJuIG5leHQoY29udGV4dCwgY29udGV4dCwgZXhwYW5kZWRUeXBlSUQpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYXZlcnNlIHRvIHRoZSBuZXh0IG5vZGUgYWZ0ZXIgdGhlIGN1cnJlbnQgbm9kZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjb250ZXh0IFRoZSBjb250ZXh0IG5vZGUgb2YgdGhpcyBpdGVyYXRpb24uCi0gICAgICogQHBhcmFtIGN1cnJlbnQgVGhlIGN1cnJlbnQgbm9kZSBvZiB0aGUgaXRlcmF0aW9uLgotICAgICAqCi0gICAgICogQHJldHVybiB0aGUgbmV4dCBub2RlIGluIHRoZSBpdGVyYXRpb24sIG9yIERUTS5OVUxMLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgbmV4dChpbnQgY29udGV4dCwgaW50IGN1cnJlbnQpCi0gICAgewotCi0gICAgICBpbnQgc3VidHJlZVJvb3RJZGVudCA9IGdldFN1YnRyZWVSb290KGNvbnRleHQpOwotCi0gICAgICBmb3IgKGN1cnJlbnQgPSBtYWtlTm9kZUlkZW50aXR5KGN1cnJlbnQpICsgMTsgOyBjdXJyZW50KyspCi0gICAgICB7Ci0gICAgICAgIGludCB0eXBlID0gX3R5cGUoY3VycmVudCk7ICAvLyBtYXkgY2FsbCBuZXh0Tm9kZSgpCi0KLSAgICAgICAgaWYgKCFpc0Rlc2NlbmRhbnQoc3VidHJlZVJvb3RJZGVudCwgY3VycmVudCkpCi0gICAgICAgICAgcmV0dXJuIE5VTEw7Ci0KLSAgICAgICAgaWYgKEFUVFJJQlVURV9OT0RFID09IHR5cGUgfHwgTkFNRVNQQUNFX05PREUgPT0gdHlwZSkKLSAgICAgICAgICBjb250aW51ZTsKLQotICAgICAgICByZXR1cm4gbWFrZU5vZGVIYW5kbGUoY3VycmVudCk7ICAvLyBtYWtlIGhhbmRsZS4KLSAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmF2ZXJzZSB0byB0aGUgbmV4dCBub2RlIGFmdGVyIHRoZSBjdXJyZW50IG5vZGUgdGhhdCBpcyBtYXRjaGVkCi0gICAgICogYnkgdGhlIGV4cGFuZGVkIHR5cGUgSUQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCBub2RlIG9mIHRoaXMgaXRlcmF0aW9uLgotICAgICAqIEBwYXJhbSBjdXJyZW50IFRoZSBjdXJyZW50IG5vZGUgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgKiBAcGFyYW0gZXhwYW5kZWRUeXBlSUQgVGhlIGV4cGFuZGVkIHR5cGUgSUQgdGhhdCBtdXN0IG1hdGNoLgotICAgICAqCi0gICAgICogQHJldHVybiB0aGUgbmV4dCBub2RlIGluIHRoZSBpdGVyYXRpb24sIG9yIERUTS5OVUxMLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgbmV4dChpbnQgY29udGV4dCwgaW50IGN1cnJlbnQsIGludCBleHBhbmRlZFR5cGVJRCkKLSAgICB7Ci0KLSAgICAgIGludCBzdWJ0cmVlUm9vdElkZW50ID0gZ2V0U3VidHJlZVJvb3QoY29udGV4dCk7Ci0KLSAgICAgIGN1cnJlbnQgPSBtYWtlTm9kZUlkZW50aXR5KGN1cnJlbnQpICsgMTsKLQotICAgICAgaWYgKGlzSW5kZXhlZChleHBhbmRlZFR5cGVJRCkpCi0gICAgICB7Ci0gICAgICAgIHJldHVybiBtYWtlTm9kZUhhbmRsZShnZXROZXh0SW5kZXhlZChzdWJ0cmVlUm9vdElkZW50LCBjdXJyZW50LCBleHBhbmRlZFR5cGVJRCkpOwotICAgICAgfQotCi0gICAgICBmb3IgKDsgOyBjdXJyZW50KyspCi0gICAgICB7Ci0gICAgICAgIGludCBleHB0eXBlID0gX2V4cHR5cGUoY3VycmVudCk7ICAvLyBtYXkgY2FsbCBuZXh0Tm9kZSgpCi0KLSAgICAgICAgaWYgKCFpc0Rlc2NlbmRhbnQoc3VidHJlZVJvb3RJZGVudCwgY3VycmVudCkpCi0gICAgICAgICAgcmV0dXJuIE5VTEw7Ci0KLSAgICAgICAgaWYgKGV4cHR5cGUgIT0gZXhwYW5kZWRUeXBlSUQpCi0gICAgICAgICAgY29udGludWU7Ci0KLSAgICAgICAgcmV0dXJuIG1ha2VOb2RlSGFuZGxlKGN1cnJlbnQpOyAgLy8gbWFrZSBoYW5kbGUuCi0gICAgICB9Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEltcGxlbWVudHMgdHJhdmVyc2FsIG9mIHRoZSBBbmNlc3RvciBhY2Nlc3MsIGluIHJldmVyc2UgZG9jdW1lbnQgb3JkZXIuCi0gICAqLwotICBwcml2YXRlIGNsYXNzIERlc2NlbmRhbnRPclNlbGZUcmF2ZXJzZXIgZXh0ZW5kcyBEZXNjZW5kYW50VHJhdmVyc2VyCi0gIHsKLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgZmlyc3QgcG90ZW50aWFsIGlkZW50aXR5IHRoYXQgY2FuIGJlIHJldHVybmVkLCB3aGljaCBpcyB0aGUKLSAgICAgKiBheGlzIGNvbnRleHQsIGluIHRoaXMgY2FzZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBpZGVudGl0eSBUaGUgbm9kZSBpZGVudGl0eSBvZiB0aGUgcm9vdCBjb250ZXh0IG9mIHRoZSB0cmF2ZXJzYWwuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBheGlzIGNvbnRleHQuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGludCBnZXRGaXJzdFBvdGVudGlhbChpbnQgaWRlbnRpdHkpCi0gICAgewotICAgICAgcmV0dXJuIGlkZW50aXR5OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEJ5IHRoZSBuYXR1cmUgb2YgdGhlIHN0YXRlbGVzcyB0cmF2ZXJzYWwsIHRoZSBjb250ZXh0IG5vZGUgY2FuIG5vdCBiZQotICAgICAqIHJldHVybmVkIG9yIHRoZSBpdGVyYXRpb24gd2lsbCBnbyBpbnRvIGFuIGluZmluYXRlIGxvb3AuICBUbyBzZWUgaWYKLSAgICAgKiB0aGUgc2VsZiBub2RlIHNob3VsZCBiZSBwcm9jZXNzZWQsIHVzZSB0aGlzIGZ1bmN0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIGNvbnRleHQgVGhlIGNvbnRleHQgbm9kZSBvZiB0aGlzIHRyYXZlcnNhbC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdGhlIGZpcnN0IG5vZGUgaW4gdGhlIHRyYXZlcnNhbC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGZpcnN0KGludCBjb250ZXh0KQotICAgIHsKLSAgICAgIHJldHVybiBjb250ZXh0OwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBJbXBsZW1lbnRzIHRyYXZlcnNhbCBvZiB0aGUgZW50aXJlIHN1YnRyZWUsIGluY2x1ZGluZyB0aGUgcm9vdCBub2RlLgotICAgKi8KLSAgcHJpdmF0ZSBjbGFzcyBBbGxGcm9tTm9kZVRyYXZlcnNlciBleHRlbmRzIERlc2NlbmRhbnRPclNlbGZUcmF2ZXJzZXIKLSAgewotCi0gICAgLyoqCi0gICAgICogVHJhdmVyc2UgdG8gdGhlIG5leHQgbm9kZSBhZnRlciB0aGUgY3VycmVudCBub2RlLgotICAgICAqCi0gICAgICogQHBhcmFtIGNvbnRleHQgVGhlIGNvbnRleHQgbm9kZSBvZiB0aGlzIGl0ZXJhdGlvbi4KLSAgICAgKiBAcGFyYW0gY3VycmVudCBUaGUgY3VycmVudCBub2RlIG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRoZSBuZXh0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbiwgb3IgRFRNLk5VTEwuCi0gICAgICovCi0gICAgcHVibGljIGludCBuZXh0KGludCBjb250ZXh0LCBpbnQgY3VycmVudCkKLSAgICB7Ci0KLSAgICAgIGludCBzdWJ0cmVlUm9vdElkZW50ID0gbWFrZU5vZGVJZGVudGl0eShjb250ZXh0KTsKLQotICAgICAgZm9yIChjdXJyZW50ID0gbWFrZU5vZGVJZGVudGl0eShjdXJyZW50KSArIDE7IDsgY3VycmVudCsrKQotICAgICAgewotICAgICAgICAvLyBUcmlja29sb2dpY2FsIGNvZGU6IF9leHB0eXBlKCkgaGFzIHRoZSBzaWRlLWVmZmVjdCBvZgotICAgICAgICAvLyBydW5uaW5nIG5leHROb2RlIHVudGlsIHRoZSBzcGVjaWZpZWQgbm9kZSBoYXMgYmVlbiBsb2FkZWQsCi0gICAgICAgIC8vIGFuZCB0aHVzIGNhbiBiZSB1c2VkIHRvIGVuc3VyZSB0aGF0IGluY3JlbWVudGFsIGNvbnN0cnVjdGlvbiBvZgotICAgICAgICAvLyB0aGUgRFRNIGhhcyBnb3R0ZW4gdGhpcyBmYXIuIFVzaW5nIGl0IGp1c3QgZm9yIHRoYXQgc2lkZS1lZmZlY3QKLSAgICAgICAgLy8gaXMgcXVpdGUgYSBrbHVnZS4uLgotICAgICAgICBfZXhwdHlwZShjdXJyZW50KTsgIC8vIG1ha2Ugc3VyZSBpdCdzIGhlcmUuCi0KLSAgICAgICAgaWYgKCFpc0Rlc2NlbmRhbnQoc3VidHJlZVJvb3RJZGVudCwgY3VycmVudCkpCi0gICAgICAgICAgcmV0dXJuIE5VTEw7Ci0KLSAgICAgICAgcmV0dXJuIG1ha2VOb2RlSGFuZGxlKGN1cnJlbnQpOyAgLy8gbWFrZSBoYW5kbGUuCi0gICAgICB9Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEltcGxlbWVudHMgdHJhdmVyc2FsIG9mIHRoZSBmb2xsb3dpbmcgYWNjZXNzLCBpbiBkb2N1bWVudCBvcmRlci4KLSAgICovCi0gIHByaXZhdGUgY2xhc3MgRm9sbG93aW5nVHJhdmVyc2VyIGV4dGVuZHMgRGVzY2VuZGFudFRyYXZlcnNlcgotICB7Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIGZpcnN0IG9mIHRoZSBmb2xsb3dpbmcuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCBub2RlIG9mIHRoaXMgdHJhdmVyc2FsLiBUaGlzIGlzIHRoZSBwb2ludAotICAgICAqIHRoYXQgdGhlIHRyYXZlcnNhbCBzdGFydHMgZnJvbS4KLSAgICAgKiBAcmV0dXJuIHRoZSBmaXJzdCBub2RlIGluIHRoZSB0cmF2ZXJzYWwuCi0gICAgICovCi0gICAgcHVibGljIGludCBmaXJzdChpbnQgY29udGV4dCkKLSAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBDb21wdXRlIGluIElEIHNwYWNlCi0gICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0PW1ha2VOb2RlSWRlbnRpdHkoY29udGV4dCk7Ci0KLSAgICAgIGludCBmaXJzdDsKLSAgICAgIGludCB0eXBlID0gX3R5cGUoY29udGV4dCk7Ci0KLSAgICAgIGlmICgoRFRNLkFUVFJJQlVURV9OT0RFID09IHR5cGUpIHx8IChEVE0uTkFNRVNQQUNFX05PREUgPT0gdHlwZSkpCi0gICAgICB7Ci0gICAgICAgIGNvbnRleHQgPSBfcGFyZW50KGNvbnRleHQpOwotICAgICAgICBmaXJzdCA9IF9maXJzdGNoKGNvbnRleHQpOwotCi0gICAgICAgIGlmIChOVUxMICE9IGZpcnN0KQotICAgICAgICAgIHJldHVybiBtYWtlTm9kZUhhbmRsZShmaXJzdCk7Ci0gICAgICB9Ci0KLSAgICAgIGRvCi0gICAgICB7Ci0gICAgICAgIGZpcnN0ID0gX25leHRzaWIoY29udGV4dCk7Ci0KLSAgICAgICAgaWYgKE5VTEwgPT0gZmlyc3QpCi0gICAgICAgICAgY29udGV4dCA9IF9wYXJlbnQoY29udGV4dCk7Ci0gICAgICB9Ci0gICAgICB3aGlsZSAoTlVMTCA9PSBmaXJzdCAmJiBOVUxMICE9IGNvbnRleHQpOwotCi0gICAgICByZXR1cm4gbWFrZU5vZGVIYW5kbGUoZmlyc3QpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgZmlyc3Qgb2YgdGhlIGZvbGxvd2luZy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjb250ZXh0IFRoZSBjb250ZXh0IG5vZGUgb2YgdGhpcyB0cmF2ZXJzYWwuIFRoaXMgaXMgdGhlIHBvaW50Ci0gICAgICogb2Ygb3JpZ2luIGZvciB0aGUgdHJhdmVyc2FsIC0tIGl0cyAicm9vdCBub2RlIiBvciBzdGFydGluZyBwb2ludC4KLSAgICAgKiBAcGFyYW0gZXhwYW5kZWRUeXBlSUQgVGhlIGV4cGFuZGVkIHR5cGUgSUQgdGhhdCBtdXN0IG1hdGNoLgotICAgICAqCi0gICAgICogQHJldHVybiB0aGUgZmlyc3Qgbm9kZSBpbiB0aGUgdHJhdmVyc2FsLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZmlyc3QoaW50IGNvbnRleHQsIGludCBleHBhbmRlZFR5cGVJRCkKLSAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyAlUkVWSUVXJSBUaGlzIGxvb2tzIGxpa2UgaXQgbWlnaHQgd2FudCBzaGlmdCBpbnRvIGlkZW50aXR5IHNwYWNlCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyB0byBhdm9pZCByZXBlYXRlZCBjb252ZXJzaW9uIGluIHRoZSBpbmRpdmlkdWFsIGZ1bmN0aW9ucwotICAgICAgaW50IGZpcnN0OwotICAgICAgaW50IHR5cGUgPSBnZXROb2RlVHlwZShjb250ZXh0KTsKLQotICAgICAgaWYgKChEVE0uQVRUUklCVVRFX05PREUgPT0gdHlwZSkgfHwgKERUTS5OQU1FU1BBQ0VfTk9ERSA9PSB0eXBlKSkKLSAgICAgIHsKLSAgICAgICAgY29udGV4dCA9IGdldFBhcmVudChjb250ZXh0KTsKLSAgICAgICAgZmlyc3QgPSBnZXRGaXJzdENoaWxkKGNvbnRleHQpOwotCi0gICAgICAgIGlmIChOVUxMICE9IGZpcnN0KQotICAgICAgICB7Ci0gICAgICAgICAgaWYgKGdldEV4cGFuZGVkVHlwZUlEKGZpcnN0KSA9PSBleHBhbmRlZFR5cGVJRCkKLSAgICAgICAgICAgIHJldHVybiBmaXJzdDsKLSAgICAgICAgICBlbHNlCi0gICAgICAgICAgICByZXR1cm4gbmV4dChjb250ZXh0LCBmaXJzdCwgZXhwYW5kZWRUeXBlSUQpOwotICAgICAgICB9Ci0gICAgICB9Ci0KLSAgICAgIGRvCi0gICAgICB7Ci0gICAgICAgIGZpcnN0ID0gZ2V0TmV4dFNpYmxpbmcoY29udGV4dCk7Ci0KLSAgICAgICAgaWYgKE5VTEwgPT0gZmlyc3QpCi0gICAgICAgICAgY29udGV4dCA9IGdldFBhcmVudChjb250ZXh0KTsKLSAgICAgICAgZWxzZQotICAgICAgICB7Ci0gICAgICAgICAgaWYgKGdldEV4cGFuZGVkVHlwZUlEKGZpcnN0KSA9PSBleHBhbmRlZFR5cGVJRCkKLSAgICAgICAgICAgIHJldHVybiBmaXJzdDsKLSAgICAgICAgICBlbHNlCi0gICAgICAgICAgICByZXR1cm4gbmV4dChjb250ZXh0LCBmaXJzdCwgZXhwYW5kZWRUeXBlSUQpOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgICB3aGlsZSAoTlVMTCA9PSBmaXJzdCAmJiBOVUxMICE9IGNvbnRleHQpOwotCi0gICAgICByZXR1cm4gZmlyc3Q7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhdmVyc2UgdG8gdGhlIG5leHQgbm9kZSBhZnRlciB0aGUgY3VycmVudCBub2RlLgotICAgICAqCi0gICAgICogQHBhcmFtIGNvbnRleHQgVGhlIGNvbnRleHQgbm9kZSBvZiB0aGlzIGl0ZXJhdGlvbi4KLSAgICAgKiBAcGFyYW0gY3VycmVudCBUaGUgY3VycmVudCBub2RlIG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRoZSBuZXh0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbiwgb3IgRFRNLk5VTEwuCi0gICAgICovCi0gICAgcHVibGljIGludCBuZXh0KGludCBjb250ZXh0LCBpbnQgY3VycmVudCkKLSAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBDb21wdXRlIGluIGlkZW50aXR5IHNwYWNlCi0gICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50PW1ha2VOb2RlSWRlbnRpdHkoY3VycmVudCk7Ci0KLSAgICAgIHdoaWxlICh0cnVlKQotICAgICAgewotICAgICAgICBjdXJyZW50Kys7IC8vIE9ubHkgd29ya3Mgb24gSURzLCBub3QgaGFuZGxlcy4KLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAlUkVWSUVXJSBBcmUgd2UgdXNpbmcgaGFuZGxlcyBvciBpbmRleGVzPwotICAgICAgICBpbnQgdHlwZSA9IF90eXBlKGN1cnJlbnQpOyAgLy8gbWF5IGNhbGwgbmV4dE5vZGUoKQotCi0gICAgICAgIGlmIChOVUxMID09IHR5cGUpCi0gICAgICAgICAgcmV0dXJuIE5VTEw7Ci0KLSAgICAgICAgaWYgKEFUVFJJQlVURV9OT0RFID09IHR5cGUgfHwgTkFNRVNQQUNFX05PREUgPT0gdHlwZSkKLSAgICAgICAgICBjb250aW51ZTsKLQotICAgICAgICByZXR1cm4gbWFrZU5vZGVIYW5kbGUoY3VycmVudCk7ICAvLyBtYWtlIGhhbmRsZS4KLSAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmF2ZXJzZSB0byB0aGUgbmV4dCBub2RlIGFmdGVyIHRoZSBjdXJyZW50IG5vZGUgdGhhdCBpcyBtYXRjaGVkCi0gICAgICogYnkgdGhlIGV4cGFuZGVkIHR5cGUgSUQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCBub2RlIG9mIHRoaXMgaXRlcmF0aW9uLgotICAgICAqIEBwYXJhbSBjdXJyZW50IFRoZSBjdXJyZW50IG5vZGUgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgKiBAcGFyYW0gZXhwYW5kZWRUeXBlSUQgVGhlIGV4cGFuZGVkIHR5cGUgSUQgdGhhdCBtdXN0IG1hdGNoLgotICAgICAqCi0gICAgICogQHJldHVybiB0aGUgbmV4dCBub2RlIGluIHRoZSBpdGVyYXRpb24sIG9yIERUTS5OVUxMLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgbmV4dChpbnQgY29udGV4dCwgaW50IGN1cnJlbnQsIGludCBleHBhbmRlZFR5cGVJRCkKLSAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBDb21wdXRlIGluIElEIHNwYWNlCi0gICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50PW1ha2VOb2RlSWRlbnRpdHkoY3VycmVudCk7Ci0KLSAgICAgIHdoaWxlICh0cnVlKQotICAgICAgewotICAgICAgICBjdXJyZW50Kys7Ci0KLSAgICAgICAgaW50IGV0eXBlID0gX2V4cHR5cGUoY3VycmVudCk7ICAvLyBtYXkgY2FsbCBuZXh0Tm9kZSgpCi0KLSAgICAgICAgaWYgKE5VTEwgPT0gZXR5cGUpCi0gICAgICAgICAgcmV0dXJuIE5VTEw7Ci0KLSAgICAgICAgaWYgKGV0eXBlICE9IGV4cGFuZGVkVHlwZUlEKQotICAgICAgICAgIGNvbnRpbnVlOwotCi0gICAgICAgIHJldHVybiBtYWtlTm9kZUhhbmRsZShjdXJyZW50KTsgIC8vIG1ha2UgaGFuZGxlLgotICAgICAgfQotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBJbXBsZW1lbnRzIHRyYXZlcnNhbCBvZiB0aGUgQW5jZXN0b3IgYWNjZXNzLCBpbiByZXZlcnNlIGRvY3VtZW50IG9yZGVyLgotICAgKi8KLSAgcHJpdmF0ZSBjbGFzcyBGb2xsb3dpbmdTaWJsaW5nVHJhdmVyc2VyIGV4dGVuZHMgRFRNQXhpc1RyYXZlcnNlcgotICB7Ci0KLSAgICAvKioKLSAgICAgKiBUcmF2ZXJzZSB0byB0aGUgbmV4dCBub2RlIGFmdGVyIHRoZSBjdXJyZW50IG5vZGUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCBub2RlIG9mIHRoaXMgaXRlcmF0aW9uLgotICAgICAqIEBwYXJhbSBjdXJyZW50IFRoZSBjdXJyZW50IG5vZGUgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdGhlIG5leHQgbm9kZSBpbiB0aGUgaXRlcmF0aW9uLCBvciBEVE0uTlVMTC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IG5leHQoaW50IGNvbnRleHQsIGludCBjdXJyZW50KQotICAgIHsKLSAgICAgIHJldHVybiBnZXROZXh0U2libGluZyhjdXJyZW50KTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmF2ZXJzZSB0byB0aGUgbmV4dCBub2RlIGFmdGVyIHRoZSBjdXJyZW50IG5vZGUgdGhhdCBpcyBtYXRjaGVkCi0gICAgICogYnkgdGhlIGV4cGFuZGVkIHR5cGUgSUQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCBub2RlIG9mIHRoaXMgaXRlcmF0aW9uLgotICAgICAqIEBwYXJhbSBjdXJyZW50IFRoZSBjdXJyZW50IG5vZGUgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgKiBAcGFyYW0gZXhwYW5kZWRUeXBlSUQgVGhlIGV4cGFuZGVkIHR5cGUgSUQgdGhhdCBtdXN0IG1hdGNoLgotICAgICAqCi0gICAgICogQHJldHVybiB0aGUgbmV4dCBub2RlIGluIHRoZSBpdGVyYXRpb24sIG9yIERUTS5OVUxMLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgbmV4dChpbnQgY29udGV4dCwgaW50IGN1cnJlbnQsIGludCBleHBhbmRlZFR5cGVJRCkKLSAgICB7Ci0KLSAgICAgIHdoaWxlIChEVE0uTlVMTCAhPSAoY3VycmVudCA9IGdldE5leHRTaWJsaW5nKGN1cnJlbnQpKSkKLSAgICAgIHsKLSAgICAgICAgaWYgKGdldEV4cGFuZGVkVHlwZUlEKGN1cnJlbnQpID09IGV4cGFuZGVkVHlwZUlEKQotICAgICAgICAgIHJldHVybiBjdXJyZW50OwotICAgICAgfQotCi0gICAgICByZXR1cm4gTlVMTDsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogSW1wbGVtZW50cyB0cmF2ZXJzYWwgb2YgdGhlIEFuY2VzdG9yIGFjY2VzcywgaW4gcmV2ZXJzZSBkb2N1bWVudCBvcmRlci4KLSAgICovCi0gIHByaXZhdGUgY2xhc3MgTmFtZXNwYWNlRGVjbHNUcmF2ZXJzZXIgZXh0ZW5kcyBEVE1BeGlzVHJhdmVyc2VyCi0gIHsKLQotICAgIC8qKgotICAgICAqIFRyYXZlcnNlIHRvIHRoZSBuZXh0IG5vZGUgYWZ0ZXIgdGhlIGN1cnJlbnQgbm9kZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjb250ZXh0IFRoZSBjb250ZXh0IG5vZGUgb2YgdGhpcyBpdGVyYXRpb24uCi0gICAgICogQHBhcmFtIGN1cnJlbnQgVGhlIGN1cnJlbnQgbm9kZSBvZiB0aGUgaXRlcmF0aW9uLgotICAgICAqCi0gICAgICogQHJldHVybiB0aGUgbmV4dCBub2RlIGluIHRoZSBpdGVyYXRpb24sIG9yIERUTS5OVUxMLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgbmV4dChpbnQgY29udGV4dCwgaW50IGN1cnJlbnQpCi0gICAgewotCi0gICAgICByZXR1cm4gKGNvbnRleHQgPT0gY3VycmVudCkKLSAgICAgICAgICAgICA/IGdldEZpcnN0TmFtZXNwYWNlTm9kZShjb250ZXh0LCBmYWxzZSkKLSAgICAgICAgICAgICA6IGdldE5leHROYW1lc3BhY2VOb2RlKGNvbnRleHQsIGN1cnJlbnQsIGZhbHNlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmF2ZXJzZSB0byB0aGUgbmV4dCBub2RlIGFmdGVyIHRoZSBjdXJyZW50IG5vZGUgdGhhdCBpcyBtYXRjaGVkCi0gICAgICogYnkgdGhlIGV4cGFuZGVkIHR5cGUgSUQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCBub2RlIG9mIHRoaXMgaXRlcmF0aW9uLgotICAgICAqIEBwYXJhbSBjdXJyZW50IFRoZSBjdXJyZW50IG5vZGUgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgKiBAcGFyYW0gZXhwYW5kZWRUeXBlSUQgVGhlIGV4cGFuZGVkIHR5cGUgSUQgdGhhdCBtdXN0IG1hdGNoLgotICAgICAqCi0gICAgICogQHJldHVybiB0aGUgbmV4dCBub2RlIGluIHRoZSBpdGVyYXRpb24sIG9yIERUTS5OVUxMLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgbmV4dChpbnQgY29udGV4dCwgaW50IGN1cnJlbnQsIGludCBleHBhbmRlZFR5cGVJRCkKLSAgICB7Ci0KLSAgICAgIGN1cnJlbnQgPSAoY29udGV4dCA9PSBjdXJyZW50KQotICAgICAgICAgICAgICAgID8gZ2V0Rmlyc3ROYW1lc3BhY2VOb2RlKGNvbnRleHQsIGZhbHNlKQotICAgICAgICAgICAgICAgIDogZ2V0TmV4dE5hbWVzcGFjZU5vZGUoY29udGV4dCwgY3VycmVudCwgZmFsc2UpOwotCi0gICAgICBkbwotICAgICAgewotICAgICAgICBpZiAoZ2V0RXhwYW5kZWRUeXBlSUQoY3VycmVudCkgPT0gZXhwYW5kZWRUeXBlSUQpCi0gICAgICAgICAgcmV0dXJuIGN1cnJlbnQ7Ci0gICAgICB9Ci0gICAgICB3aGlsZSAoRFRNLk5VTEwKLSAgICAgICAgICAgICAhPSAoY3VycmVudCA9IGdldE5leHROYW1lc3BhY2VOb2RlKGNvbnRleHQsIGN1cnJlbnQsIGZhbHNlKSkpOwotCi0gICAgICByZXR1cm4gTlVMTDsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogSW1wbGVtZW50cyB0cmF2ZXJzYWwgb2YgdGhlIEFuY2VzdG9yIGFjY2VzcywgaW4gcmV2ZXJzZSBkb2N1bWVudCBvcmRlci4KLSAgICovCi0gIHByaXZhdGUgY2xhc3MgTmFtZXNwYWNlVHJhdmVyc2VyIGV4dGVuZHMgRFRNQXhpc1RyYXZlcnNlcgotICB7Ci0KLSAgICAvKioKLSAgICAgKiBUcmF2ZXJzZSB0byB0aGUgbmV4dCBub2RlIGFmdGVyIHRoZSBjdXJyZW50IG5vZGUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCBub2RlIG9mIHRoaXMgaXRlcmF0aW9uLgotICAgICAqIEBwYXJhbSBjdXJyZW50IFRoZSBjdXJyZW50IG5vZGUgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdGhlIG5leHQgbm9kZSBpbiB0aGUgaXRlcmF0aW9uLCBvciBEVE0uTlVMTC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IG5leHQoaW50IGNvbnRleHQsIGludCBjdXJyZW50KQotICAgIHsKLQotICAgICAgcmV0dXJuIChjb250ZXh0ID09IGN1cnJlbnQpCi0gICAgICAgICAgICAgPyBnZXRGaXJzdE5hbWVzcGFjZU5vZGUoY29udGV4dCwgdHJ1ZSkKLSAgICAgICAgICAgICA6IGdldE5leHROYW1lc3BhY2VOb2RlKGNvbnRleHQsIGN1cnJlbnQsIHRydWUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYXZlcnNlIHRvIHRoZSBuZXh0IG5vZGUgYWZ0ZXIgdGhlIGN1cnJlbnQgbm9kZSB0aGF0IGlzIG1hdGNoZWQKLSAgICAgKiBieSB0aGUgZXhwYW5kZWQgdHlwZSBJRC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjb250ZXh0IFRoZSBjb250ZXh0IG5vZGUgb2YgdGhpcyBpdGVyYXRpb24uCi0gICAgICogQHBhcmFtIGN1cnJlbnQgVGhlIGN1cnJlbnQgbm9kZSBvZiB0aGUgaXRlcmF0aW9uLgotICAgICAqIEBwYXJhbSBleHBhbmRlZFR5cGVJRCBUaGUgZXhwYW5kZWQgdHlwZSBJRCB0aGF0IG11c3QgbWF0Y2guCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRoZSBuZXh0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbiwgb3IgRFRNLk5VTEwuCi0gICAgICovCi0gICAgcHVibGljIGludCBuZXh0KGludCBjb250ZXh0LCBpbnQgY3VycmVudCwgaW50IGV4cGFuZGVkVHlwZUlEKQotICAgIHsKLQotICAgICAgY3VycmVudCA9IChjb250ZXh0ID09IGN1cnJlbnQpCi0gICAgICAgICAgICAgICAgPyBnZXRGaXJzdE5hbWVzcGFjZU5vZGUoY29udGV4dCwgdHJ1ZSkKLSAgICAgICAgICAgICAgICA6IGdldE5leHROYW1lc3BhY2VOb2RlKGNvbnRleHQsIGN1cnJlbnQsIHRydWUpOwotCi0gICAgICBkbwotICAgICAgewotICAgICAgICBpZiAoZ2V0RXhwYW5kZWRUeXBlSUQoY3VycmVudCkgPT0gZXhwYW5kZWRUeXBlSUQpCi0gICAgICAgICAgcmV0dXJuIGN1cnJlbnQ7Ci0gICAgICB9Ci0gICAgICB3aGlsZSAoRFRNLk5VTEwKLSAgICAgICAgICAgICAhPSAoY3VycmVudCA9IGdldE5leHROYW1lc3BhY2VOb2RlKGNvbnRleHQsIGN1cnJlbnQsIHRydWUpKSk7Ci0KLSAgICAgIHJldHVybiBOVUxMOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBJbXBsZW1lbnRzIHRyYXZlcnNhbCBvZiB0aGUgQW5jZXN0b3IgYWNjZXNzLCBpbiByZXZlcnNlIGRvY3VtZW50IG9yZGVyLgotICAgKi8KLSAgcHJpdmF0ZSBjbGFzcyBQYXJlbnRUcmF2ZXJzZXIgZXh0ZW5kcyBEVE1BeGlzVHJhdmVyc2VyCi0gIHsKLSAgICAvKioKLSAgICAgKiBCeSB0aGUgbmF0dXJlIG9mIHRoZSBzdGF0ZWxlc3MgdHJhdmVyc2FsLCB0aGUgY29udGV4dCBub2RlIGNhbiBub3QgYmUKLSAgICAgKiByZXR1cm5lZCBvciB0aGUgaXRlcmF0aW9uIHdpbGwgZ28gaW50byBhbiBpbmZpbmF0ZSBsb29wLiAgU28gdG8gdHJhdmVyc2UKLSAgICAgKiBhbiBheGlzLCB0aGUgZmlyc3QgZnVuY3Rpb24gbXVzdCBiZSB1c2VkIHRvIGdldCB0aGUgZmlyc3Qgbm9kZS4KLSAgICAgKgotICAgICAqIDxwPlRoaXMgbWV0aG9kIG5lZWRzIHRvIGJlIG92ZXJsb2FkZWQgb25seSBieSB0aG9zZSBheGlzIHRoYXQgcHJvY2VzcwotICAgICAqIHRoZSBzZWxmIG5vZGUuIDxccD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjb250ZXh0IFRoZSBjb250ZXh0IG5vZGUgb2YgdGhpcyB0cmF2ZXJzYWwuIFRoaXMgaXMgdGhlIHBvaW50Ci0gICAgICogdGhhdCB0aGUgdHJhdmVyc2FsIHN0YXJ0cyBmcm9tLgotICAgICAqIEByZXR1cm4gdGhlIGZpcnN0IG5vZGUgaW4gdGhlIHRyYXZlcnNhbC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGZpcnN0KGludCBjb250ZXh0KQotICAgIHsKLSAgICAgIHJldHVybiBnZXRQYXJlbnQoY29udGV4dCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQnkgdGhlIG5hdHVyZSBvZiB0aGUgc3RhdGVsZXNzIHRyYXZlcnNhbCwgdGhlIGNvbnRleHQgbm9kZSBjYW4gbm90IGJlCi0gICAgICogcmV0dXJuZWQgb3IgdGhlIGl0ZXJhdGlvbiB3aWxsIGdvIGludG8gYW4gaW5maW5hdGUgbG9vcC4gIFNvIHRvIHRyYXZlcnNlCi0gICAgICogYW4gYXhpcywgdGhlIGZpcnN0IGZ1bmN0aW9uIG11c3QgYmUgdXNlZCB0byBnZXQgdGhlIGZpcnN0IG5vZGUuCi0gICAgICoKLSAgICAgKiA8cD5UaGlzIG1ldGhvZCBuZWVkcyB0byBiZSBvdmVybG9hZGVkIG9ubHkgYnkgdGhvc2UgYXhpcyB0aGF0IHByb2Nlc3MKLSAgICAgKiB0aGUgc2VsZiBub2RlLiA8XHA+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCBub2RlIG9mIHRoaXMgdHJhdmVyc2FsLiBUaGlzIGlzIHRoZSBwb2ludAotICAgICAqIG9mIG9yaWdpbiBmb3IgdGhlIHRyYXZlcnNhbCAtLSBpdHMgInJvb3Qgbm9kZSIgb3Igc3RhcnRpbmcgcG9pbnQuCi0gICAgICogQHBhcmFtIGV4cGFuZGVkVHlwZUlEIFRoZSBleHBhbmRlZCB0eXBlIElEIHRoYXQgbXVzdCBtYXRjaC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdGhlIGZpcnN0IG5vZGUgaW4gdGhlIHRyYXZlcnNhbC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGZpcnN0KGludCBjdXJyZW50LCBpbnQgZXhwYW5kZWRUeXBlSUQpCi0gICAgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ29tcHV0ZSBpbiBJRCBzcGFjZQotICAgICAgY3VycmVudCA9IG1ha2VOb2RlSWRlbnRpdHkoY3VycmVudCk7Ci0KLSAgICAgIHdoaWxlIChOVUxMICE9IChjdXJyZW50ID0gbV9wYXJlbnQuZWxlbWVudEF0KGN1cnJlbnQpKSkKLSAgICAgIHsKLSAgICAgICAgaWYgKG1fZXhwdHlwZS5lbGVtZW50QXQoY3VycmVudCkgPT0gZXhwYW5kZWRUeXBlSUQpCi0gICAgICAgICAgcmV0dXJuIG1ha2VOb2RlSGFuZGxlKGN1cnJlbnQpOwotICAgICAgfQotCi0gICAgICByZXR1cm4gTlVMTDsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFRyYXZlcnNlIHRvIHRoZSBuZXh0IG5vZGUgYWZ0ZXIgdGhlIGN1cnJlbnQgbm9kZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjb250ZXh0IFRoZSBjb250ZXh0IG5vZGUgb2YgdGhpcyBpdGVyYXRpb24uCi0gICAgICogQHBhcmFtIGN1cnJlbnQgVGhlIGN1cnJlbnQgbm9kZSBvZiB0aGUgaXRlcmF0aW9uLgotICAgICAqCi0gICAgICogQHJldHVybiB0aGUgbmV4dCBub2RlIGluIHRoZSBpdGVyYXRpb24sIG9yIERUTS5OVUxMLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgbmV4dChpbnQgY29udGV4dCwgaW50IGN1cnJlbnQpCi0gICAgewotCi0gICAgICByZXR1cm4gTlVMTDsKLSAgICB9Ci0KLQotCi0gICAgLyoqCi0gICAgICogVHJhdmVyc2UgdG8gdGhlIG5leHQgbm9kZSBhZnRlciB0aGUgY3VycmVudCBub2RlIHRoYXQgaXMgbWF0Y2hlZAotICAgICAqIGJ5IHRoZSBleHBhbmRlZCB0eXBlIElELgotICAgICAqCi0gICAgICogQHBhcmFtIGNvbnRleHQgVGhlIGNvbnRleHQgbm9kZSBvZiB0aGlzIGl0ZXJhdGlvbi4KLSAgICAgKiBAcGFyYW0gY3VycmVudCBUaGUgY3VycmVudCBub2RlIG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICogQHBhcmFtIGV4cGFuZGVkVHlwZUlEIFRoZSBleHBhbmRlZCB0eXBlIElEIHRoYXQgbXVzdCBtYXRjaC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdGhlIG5leHQgbm9kZSBpbiB0aGUgaXRlcmF0aW9uLCBvciBEVE0uTlVMTC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IG5leHQoaW50IGNvbnRleHQsIGludCBjdXJyZW50LCBpbnQgZXhwYW5kZWRUeXBlSUQpCi0gICAgewotCi0gICAgICByZXR1cm4gTlVMTDsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogSW1wbGVtZW50cyB0cmF2ZXJzYWwgb2YgdGhlIEFuY2VzdG9yIGFjY2VzcywgaW4gcmV2ZXJzZSBkb2N1bWVudCBvcmRlci4KLSAgICovCi0gIHByaXZhdGUgY2xhc3MgUHJlY2VkaW5nVHJhdmVyc2VyIGV4dGVuZHMgRFRNQXhpc1RyYXZlcnNlcgotICB7Ci0KLSAgICAvKioKLSAgICAgKiBUZWxsIGlmIHRoZSBjdXJyZW50IGlkZW50aXR5IGlzIGFuIGFuY2VzdG9yIG9mIHRoZSBjb250ZXh0IGlkZW50aXR5LgotICAgICAqIFRoaXMgaXMgYW4gZXhwZW5zaXZlIG9wZXJhdGlvbiwgbWFkZSB3b3JzZSBieSB0aGUgc3RhdGVsZXNzIHRyYXZlcnNhbC4KLSAgICAgKiBCdXQgdGhlIHByZWNlZGluZyBheGlzIGlzIHVzZWQgZmFpcmx5IGluZnJlcXVlbnRseS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjb250ZXh0SWRlbnQgVGhlIGNvbnRleHQgbm9kZSBvZiB0aGUgYXhpcyB0cmF2ZXJzYWwuCi0gICAgICogQHBhcmFtIGN1cnJlbnRJZGVudCBUaGUgbm9kZSBpbiBxdWVzdGlvbi4KLSAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGN1cnJlbnRJZGVudCBub2RlIGlzIGFuIGFuY2VzdG9yIG9mIGNvbnRleHRJZGVudC4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBpc0FuY2VzdG9yKGludCBjb250ZXh0SWRlbnQsIGludCBjdXJyZW50SWRlbnQpCi0gICAgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gJVJFVklFVyUgU2VlIGNvbW1lbnRzIGluIElzQWZ0ZXJBeGlzOyB1c2luZyB0aGUgInN1Y2Nlc3NvciIgb2YKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNvbnRleHRJZGVudCBpcyBwcm9iYWJseSBtb3JlIGVmZmljaWVudC4KLSAgICAgIGZvciAoY29udGV4dElkZW50ID0gbV9wYXJlbnQuZWxlbWVudEF0KGNvbnRleHRJZGVudCk7IERUTS5OVUxMICE9IGNvbnRleHRJZGVudDsKLSAgICAgICAgICAgICAgY29udGV4dElkZW50ID0gbV9wYXJlbnQuZWxlbWVudEF0KGNvbnRleHRJZGVudCkpCi0gICAgICB7Ci0gICAgICAgIGlmIChjb250ZXh0SWRlbnQgPT0gY3VycmVudElkZW50KQotICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgfQotCi0gICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhdmVyc2UgdG8gdGhlIG5leHQgbm9kZSBhZnRlciB0aGUgY3VycmVudCBub2RlLgotICAgICAqCi0gICAgICogQHBhcmFtIGNvbnRleHQgVGhlIGNvbnRleHQgbm9kZSBvZiB0aGlzIGl0ZXJhdGlvbi4KLSAgICAgKiBAcGFyYW0gY3VycmVudCBUaGUgY3VycmVudCBub2RlIG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRoZSBuZXh0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbiwgb3IgRFRNLk5VTEwuCi0gICAgICovCi0gICAgcHVibGljIGludCBuZXh0KGludCBjb250ZXh0LCBpbnQgY3VycmVudCkKLSAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBjb21wdXRlIGluIElEIHNwYWNlCi0gICAgICBpbnQgc3VidHJlZVJvb3RJZGVudCA9IG1ha2VOb2RlSWRlbnRpdHkoY29udGV4dCk7Ci0KLSAgICAgIGZvciAoY3VycmVudCA9IG1ha2VOb2RlSWRlbnRpdHkoY3VycmVudCkgLSAxOyBjdXJyZW50ID49IDA7IGN1cnJlbnQtLSkKLSAgICAgIHsKLSAgICAgICAgc2hvcnQgdHlwZSA9IF90eXBlKGN1cnJlbnQpOwotCi0gICAgICAgIGlmIChBVFRSSUJVVEVfTk9ERSA9PSB0eXBlIHx8IE5BTUVTUEFDRV9OT0RFID09IHR5cGUKLSAgICAgICAgICAgICAgICB8fCBpc0FuY2VzdG9yKHN1YnRyZWVSb290SWRlbnQsIGN1cnJlbnQpKQotICAgICAgICAgIGNvbnRpbnVlOwotCi0gICAgICAgIHJldHVybiBtYWtlTm9kZUhhbmRsZShjdXJyZW50KTsgIC8vIG1ha2UgaGFuZGxlLgotICAgICAgfQotCi0gICAgICByZXR1cm4gTlVMTDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmF2ZXJzZSB0byB0aGUgbmV4dCBub2RlIGFmdGVyIHRoZSBjdXJyZW50IG5vZGUgdGhhdCBpcyBtYXRjaGVkCi0gICAgICogYnkgdGhlIGV4cGFuZGVkIHR5cGUgSUQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCBub2RlIG9mIHRoaXMgaXRlcmF0aW9uLgotICAgICAqIEBwYXJhbSBjdXJyZW50IFRoZSBjdXJyZW50IG5vZGUgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgKiBAcGFyYW0gZXhwYW5kZWRUeXBlSUQgVGhlIGV4cGFuZGVkIHR5cGUgSUQgdGhhdCBtdXN0IG1hdGNoLgotICAgICAqCi0gICAgICogQHJldHVybiB0aGUgbmV4dCBub2RlIGluIHRoZSBpdGVyYXRpb24sIG9yIERUTS5OVUxMLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgbmV4dChpbnQgY29udGV4dCwgaW50IGN1cnJlbnQsIGludCBleHBhbmRlZFR5cGVJRCkKLSAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBDb21wdXRlIGluIElEIHNwYWNlCi0gICAgICBpbnQgc3VidHJlZVJvb3RJZGVudCA9IG1ha2VOb2RlSWRlbnRpdHkoY29udGV4dCk7Ci0KLSAgICAgIGZvciAoY3VycmVudCA9IG1ha2VOb2RlSWRlbnRpdHkoY3VycmVudCkgLSAxOyBjdXJyZW50ID49IDA7IGN1cnJlbnQtLSkKLSAgICAgIHsKLSAgICAgICAgaW50IGV4cHR5cGUgPSBtX2V4cHR5cGUuZWxlbWVudEF0KGN1cnJlbnQpOwotCi0gICAgICAgIGlmIChleHB0eXBlICE9IGV4cGFuZGVkVHlwZUlECi0gICAgICAgICAgICAgICAgfHwgaXNBbmNlc3RvcihzdWJ0cmVlUm9vdElkZW50LCBjdXJyZW50KSkKLSAgICAgICAgICBjb250aW51ZTsKLQotICAgICAgICByZXR1cm4gbWFrZU5vZGVIYW5kbGUoY3VycmVudCk7ICAvLyBtYWtlIGhhbmRsZS4KLSAgICAgIH0KLQotICAgICAgcmV0dXJuIE5VTEw7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEltcGxlbWVudHMgdHJhdmVyc2FsIG9mIHRoZSBBbmNlc3RvciBhbmQgdGhlIFByZWNlZGluZyBheGlzLAotICAgKiBpbiByZXZlcnNlIGRvY3VtZW50IG9yZGVyLgotICAgKi8KLSAgcHJpdmF0ZSBjbGFzcyBQcmVjZWRpbmdBbmRBbmNlc3RvclRyYXZlcnNlciBleHRlbmRzIERUTUF4aXNUcmF2ZXJzZXIKLSAgewotCi0gICAgLyoqCi0gICAgICogVHJhdmVyc2UgdG8gdGhlIG5leHQgbm9kZSBhZnRlciB0aGUgY3VycmVudCBub2RlLgotICAgICAqCi0gICAgICogQHBhcmFtIGNvbnRleHQgVGhlIGNvbnRleHQgbm9kZSBvZiB0aGlzIGl0ZXJhdGlvbi4KLSAgICAgKiBAcGFyYW0gY3VycmVudCBUaGUgY3VycmVudCBub2RlIG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRoZSBuZXh0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbiwgb3IgRFRNLk5VTEwuCi0gICAgICovCi0gICAgcHVibGljIGludCBuZXh0KGludCBjb250ZXh0LCBpbnQgY3VycmVudCkKLSAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBDb21wdXRlIGluIElEIHNwYWNlCi0gICAgICBpbnQgc3VidHJlZVJvb3RJZGVudCA9IG1ha2VOb2RlSWRlbnRpdHkoY29udGV4dCApOwotCi0gICAgICBmb3IgKGN1cnJlbnQgPSBtYWtlTm9kZUlkZW50aXR5KGN1cnJlbnQpIC0gMTsgY3VycmVudCA+PSAwOyBjdXJyZW50LS0pCi0gICAgICB7Ci0gICAgICAgIHNob3J0IHR5cGUgPSBfdHlwZShjdXJyZW50KTsKLQotICAgICAgICBpZiAoQVRUUklCVVRFX05PREUgPT0gdHlwZSB8fCBOQU1FU1BBQ0VfTk9ERSA9PSB0eXBlKQotICAgICAgICAgIGNvbnRpbnVlOwotCi0gICAgICAgIHJldHVybiBtYWtlTm9kZUhhbmRsZShjdXJyZW50KTsgIC8vIG1ha2UgaGFuZGxlLgotICAgICAgfQotCi0gICAgICByZXR1cm4gTlVMTDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmF2ZXJzZSB0byB0aGUgbmV4dCBub2RlIGFmdGVyIHRoZSBjdXJyZW50IG5vZGUgdGhhdCBpcyBtYXRjaGVkCi0gICAgICogYnkgdGhlIGV4cGFuZGVkIHR5cGUgSUQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCBub2RlIG9mIHRoaXMgaXRlcmF0aW9uLgotICAgICAqIEBwYXJhbSBjdXJyZW50IFRoZSBjdXJyZW50IG5vZGUgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgKiBAcGFyYW0gZXhwYW5kZWRUeXBlSUQgVGhlIGV4cGFuZGVkIHR5cGUgSUQgdGhhdCBtdXN0IG1hdGNoLgotICAgICAqCi0gICAgICogQHJldHVybiB0aGUgbmV4dCBub2RlIGluIHRoZSBpdGVyYXRpb24sIG9yIERUTS5OVUxMLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgbmV4dChpbnQgY29udGV4dCwgaW50IGN1cnJlbnQsIGludCBleHBhbmRlZFR5cGVJRCkKLSAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBDb21wdXRlIGluIElEIHNwYWNlCi0gICAgICBpbnQgc3VidHJlZVJvb3RJZGVudCA9IG1ha2VOb2RlSWRlbnRpdHkoY29udGV4dCk7Ci0KLSAgICAgIGZvciAoY3VycmVudCA9IG1ha2VOb2RlSWRlbnRpdHkoY3VycmVudCkgLSAxOyBjdXJyZW50ID49IDA7IGN1cnJlbnQtLSkKLSAgICAgIHsKLSAgICAgICAgaW50IGV4cHR5cGUgPSBtX2V4cHR5cGUuZWxlbWVudEF0KGN1cnJlbnQpOwotCi0gICAgICAgIGlmIChleHB0eXBlICE9IGV4cGFuZGVkVHlwZUlEKQotICAgICAgICAgIGNvbnRpbnVlOwotCi0gICAgICAgIHJldHVybiBtYWtlTm9kZUhhbmRsZShjdXJyZW50KTsgIC8vIG1ha2UgaGFuZGxlLgotICAgICAgfQotCi0gICAgICByZXR1cm4gTlVMTDsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogSW1wbGVtZW50cyB0cmF2ZXJzYWwgb2YgdGhlIEFuY2VzdG9yIGFjY2VzcywgaW4gcmV2ZXJzZSBkb2N1bWVudCBvcmRlci4KLSAgICovCi0gIHByaXZhdGUgY2xhc3MgUHJlY2VkaW5nU2libGluZ1RyYXZlcnNlciBleHRlbmRzIERUTUF4aXNUcmF2ZXJzZXIKLSAgewotCi0gICAgLyoqCi0gICAgICogVHJhdmVyc2UgdG8gdGhlIG5leHQgbm9kZSBhZnRlciB0aGUgY3VycmVudCBub2RlLgotICAgICAqCi0gICAgICogQHBhcmFtIGNvbnRleHQgVGhlIGNvbnRleHQgbm9kZSBvZiB0aGlzIGl0ZXJhdGlvbi4KLSAgICAgKiBAcGFyYW0gY3VycmVudCBUaGUgY3VycmVudCBub2RlIG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRoZSBuZXh0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbiwgb3IgRFRNLk5VTEwuCi0gICAgICovCi0gICAgcHVibGljIGludCBuZXh0KGludCBjb250ZXh0LCBpbnQgY3VycmVudCkKLSAgICB7Ci0gICAgICByZXR1cm4gZ2V0UHJldmlvdXNTaWJsaW5nKGN1cnJlbnQpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYXZlcnNlIHRvIHRoZSBuZXh0IG5vZGUgYWZ0ZXIgdGhlIGN1cnJlbnQgbm9kZSB0aGF0IGlzIG1hdGNoZWQKLSAgICAgKiBieSB0aGUgZXhwYW5kZWQgdHlwZSBJRC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjb250ZXh0IFRoZSBjb250ZXh0IG5vZGUgb2YgdGhpcyBpdGVyYXRpb24uCi0gICAgICogQHBhcmFtIGN1cnJlbnQgVGhlIGN1cnJlbnQgbm9kZSBvZiB0aGUgaXRlcmF0aW9uLgotICAgICAqIEBwYXJhbSBleHBhbmRlZFR5cGVJRCBUaGUgZXhwYW5kZWQgdHlwZSBJRCB0aGF0IG11c3QgbWF0Y2guCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRoZSBuZXh0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbiwgb3IgRFRNLk5VTEwuCi0gICAgICovCi0gICAgcHVibGljIGludCBuZXh0KGludCBjb250ZXh0LCBpbnQgY3VycmVudCwgaW50IGV4cGFuZGVkVHlwZUlEKQotICAgIHsKLQotICAgICAgd2hpbGUgKERUTS5OVUxMICE9IChjdXJyZW50ID0gZ2V0UHJldmlvdXNTaWJsaW5nKGN1cnJlbnQpKSkKLSAgICAgIHsKLSAgICAgICAgaWYgKGdldEV4cGFuZGVkVHlwZUlEKGN1cnJlbnQpID09IGV4cGFuZGVkVHlwZUlEKQotICAgICAgICAgIHJldHVybiBjdXJyZW50OwotICAgICAgfQotCi0gICAgICByZXR1cm4gTlVMTDsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogSW1wbGVtZW50cyB0cmF2ZXJzYWwgb2YgdGhlIFNlbGYgYXhpcy4KLSAgICovCi0gIHByaXZhdGUgY2xhc3MgU2VsZlRyYXZlcnNlciBleHRlbmRzIERUTUF4aXNUcmF2ZXJzZXIKLSAgewotCi0gICAgLyoqCi0gICAgICogQnkgdGhlIG5hdHVyZSBvZiB0aGUgc3RhdGVsZXNzIHRyYXZlcnNhbCwgdGhlIGNvbnRleHQgbm9kZSBjYW4gbm90IGJlCi0gICAgICogcmV0dXJuZWQgb3IgdGhlIGl0ZXJhdGlvbiB3aWxsIGdvIGludG8gYW4gaW5maW5hdGUgbG9vcC4gIFRvIHNlZSBpZgotICAgICAqIHRoZSBzZWxmIG5vZGUgc2hvdWxkIGJlIHByb2Nlc3NlZCwgdXNlIHRoaXMgZnVuY3Rpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCBub2RlIG9mIHRoaXMgdHJhdmVyc2FsLgotICAgICAqCi0gICAgICogQHJldHVybiB0aGUgZmlyc3Qgbm9kZSBpbiB0aGUgdHJhdmVyc2FsLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZmlyc3QoaW50IGNvbnRleHQpCi0gICAgewotICAgICAgcmV0dXJuIGNvbnRleHQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQnkgdGhlIG5hdHVyZSBvZiB0aGUgc3RhdGVsZXNzIHRyYXZlcnNhbCwgdGhlIGNvbnRleHQgbm9kZSBjYW4gbm90IGJlCi0gICAgICogcmV0dXJuZWQgb3IgdGhlIGl0ZXJhdGlvbiB3aWxsIGdvIGludG8gYW4gaW5maW5hdGUgbG9vcC4gIFRvIHNlZSBpZgotICAgICAqIHRoZSBzZWxmIG5vZGUgc2hvdWxkIGJlIHByb2Nlc3NlZCwgdXNlIHRoaXMgZnVuY3Rpb24uICBJZiB0aGUgY29udGV4dAotICAgICAqIG5vZGUgZG9lcyBub3QgbWF0Y2ggdGhlIGV4cGFuZGVkIHR5cGUgSUQsIHRoaXMgZnVuY3Rpb24gd2lsbCByZXR1cm4KLSAgICAgKiBmYWxzZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjb250ZXh0IFRoZSBjb250ZXh0IG5vZGUgb2YgdGhpcyB0cmF2ZXJzYWwuCi0gICAgICogQHBhcmFtIGV4cGFuZGVkVHlwZUlEIFRoZSBleHBhbmRlZCB0eXBlIElEIHRoYXQgbXVzdCBtYXRjaC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdGhlIGZpcnN0IG5vZGUgaW4gdGhlIHRyYXZlcnNhbC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGZpcnN0KGludCBjb250ZXh0LCBpbnQgZXhwYW5kZWRUeXBlSUQpCi0gICAgewotICAgICAgcmV0dXJuIChnZXRFeHBhbmRlZFR5cGVJRChjb250ZXh0KSA9PSBleHBhbmRlZFR5cGVJRCkgPyBjb250ZXh0IDogTlVMTDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmF2ZXJzZSB0byB0aGUgbmV4dCBub2RlIGFmdGVyIHRoZSBjdXJyZW50IG5vZGUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCBub2RlIG9mIHRoaXMgaXRlcmF0aW9uLgotICAgICAqIEBwYXJhbSBjdXJyZW50IFRoZSBjdXJyZW50IG5vZGUgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gQWx3YXlzIHJldHVybiBOVUxMIGZvciB0aGlzIGF4aXMuCi0gICAgICovCi0gICAgcHVibGljIGludCBuZXh0KGludCBjb250ZXh0LCBpbnQgY3VycmVudCkKLSAgICB7Ci0gICAgICByZXR1cm4gTlVMTDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmF2ZXJzZSB0byB0aGUgbmV4dCBub2RlIGFmdGVyIHRoZSBjdXJyZW50IG5vZGUgdGhhdCBpcyBtYXRjaGVkCi0gICAgICogYnkgdGhlIGV4cGFuZGVkIHR5cGUgSUQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCBub2RlIG9mIHRoaXMgaXRlcmF0aW9uLgotICAgICAqIEBwYXJhbSBjdXJyZW50IFRoZSBjdXJyZW50IG5vZGUgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgKiBAcGFyYW0gZXhwYW5kZWRUeXBlSUQgVGhlIGV4cGFuZGVkIHR5cGUgSUQgdGhhdCBtdXN0IG1hdGNoLgotICAgICAqCi0gICAgICogQHJldHVybiB0aGUgbmV4dCBub2RlIGluIHRoZSBpdGVyYXRpb24sIG9yIERUTS5OVUxMLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgbmV4dChpbnQgY29udGV4dCwgaW50IGN1cnJlbnQsIGludCBleHBhbmRlZFR5cGVJRCkKLSAgICB7Ci0gICAgICByZXR1cm4gTlVMTDsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogSW1wbGVtZW50cyB0cmF2ZXJzYWwgb2YgdGhlIEFuY2VzdG9yIGFjY2VzcywgaW4gcmV2ZXJzZSBkb2N1bWVudCBvcmRlci4KLSAgICovCi0gIHByaXZhdGUgY2xhc3MgQWxsRnJvbVJvb3RUcmF2ZXJzZXIgZXh0ZW5kcyBBbGxGcm9tTm9kZVRyYXZlcnNlcgotICB7Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIHJvb3QuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCBub2RlIG9mIHRoaXMgdHJhdmVyc2FsLgotICAgICAqCi0gICAgICogQHJldHVybiB0aGUgZmlyc3Qgbm9kZSBpbiB0aGUgdHJhdmVyc2FsLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZmlyc3QoaW50IGNvbnRleHQpCi0gICAgewotICAgICAgcmV0dXJuIGdldERvY3VtZW50Um9vdChjb250ZXh0KTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIHJvb3QgaWYgaXQgbWF0Y2hlcyB0aGUgZXhwYW5kZWQgdHlwZSBJRC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjb250ZXh0IFRoZSBjb250ZXh0IG5vZGUgb2YgdGhpcyB0cmF2ZXJzYWwuCi0gICAgICogQHBhcmFtIGV4cGFuZGVkVHlwZUlEIFRoZSBleHBhbmRlZCB0eXBlIElEIHRoYXQgbXVzdCBtYXRjaC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdGhlIGZpcnN0IG5vZGUgaW4gdGhlIHRyYXZlcnNhbC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGZpcnN0KGludCBjb250ZXh0LCBpbnQgZXhwYW5kZWRUeXBlSUQpCi0gICAgewotICAgICAgcmV0dXJuIChnZXRFeHBhbmRlZFR5cGVJRChnZXREb2N1bWVudFJvb3QoY29udGV4dCkpID09IGV4cGFuZGVkVHlwZUlEKQotICAgICAgICAgICAgID8gY29udGV4dCA6IG5leHQoY29udGV4dCwgY29udGV4dCwgZXhwYW5kZWRUeXBlSUQpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYXZlcnNlIHRvIHRoZSBuZXh0IG5vZGUgYWZ0ZXIgdGhlIGN1cnJlbnQgbm9kZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjb250ZXh0IFRoZSBjb250ZXh0IG5vZGUgb2YgdGhpcyBpdGVyYXRpb24uCi0gICAgICogQHBhcmFtIGN1cnJlbnQgVGhlIGN1cnJlbnQgbm9kZSBvZiB0aGUgaXRlcmF0aW9uLgotICAgICAqCi0gICAgICogQHJldHVybiB0aGUgbmV4dCBub2RlIGluIHRoZSBpdGVyYXRpb24sIG9yIERUTS5OVUxMLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgbmV4dChpbnQgY29udGV4dCwgaW50IGN1cnJlbnQpCi0gICAgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ29tcHV0ZSBpbiBJRCBzcGFjZQotICAgICAgaW50IHN1YnRyZWVSb290SWRlbnQgPSBtYWtlTm9kZUlkZW50aXR5KGNvbnRleHQpOwotCi0gICAgICBmb3IgKGN1cnJlbnQgPSBtYWtlTm9kZUlkZW50aXR5KGN1cnJlbnQpICsgMTsgOyBjdXJyZW50KyspCi0gICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEtsdWdlIHRlc3Q6IEp1c3QgbWFrZSBzdXJlICsxIHlpZWxkZWQgYSByZWFsIG5vZGUKLSAgICAgICAgaW50IHR5cGUgPSBfdHlwZShjdXJyZW50KTsgIC8vIG1heSBjYWxsIG5leHROb2RlKCkKLSAgICAgICAgaWYgKHR5cGUgPT0gTlVMTCkKLSAgICAgICAgICByZXR1cm4gTlVMTDsKLQotICAgICAgICByZXR1cm4gbWFrZU5vZGVIYW5kbGUoY3VycmVudCk7ICAvLyBtYWtlIGhhbmRsZS4KLSAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmF2ZXJzZSB0byB0aGUgbmV4dCBub2RlIGFmdGVyIHRoZSBjdXJyZW50IG5vZGUgdGhhdCBpcyBtYXRjaGVkCi0gICAgICogYnkgdGhlIGV4cGFuZGVkIHR5cGUgSUQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCBub2RlIG9mIHRoaXMgaXRlcmF0aW9uLgotICAgICAqIEBwYXJhbSBjdXJyZW50IFRoZSBjdXJyZW50IG5vZGUgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgKiBAcGFyYW0gZXhwYW5kZWRUeXBlSUQgVGhlIGV4cGFuZGVkIHR5cGUgSUQgdGhhdCBtdXN0IG1hdGNoLgotICAgICAqCi0gICAgICogQHJldHVybiB0aGUgbmV4dCBub2RlIGluIHRoZSBpdGVyYXRpb24sIG9yIERUTS5OVUxMLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgbmV4dChpbnQgY29udGV4dCwgaW50IGN1cnJlbnQsIGludCBleHBhbmRlZFR5cGVJRCkKLSAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBDb21wdXRlIGluIElEIHNwYWNlCi0gICAgICBpbnQgc3VidHJlZVJvb3RJZGVudCA9IG1ha2VOb2RlSWRlbnRpdHkoY29udGV4dCk7Ci0KLSAgICAgIGZvciAoY3VycmVudCA9IG1ha2VOb2RlSWRlbnRpdHkoY3VycmVudCkgKyAxOyA7IGN1cnJlbnQrKykKLSAgICAgIHsKLSAgICAgICAgaW50IGV4cHR5cGUgPSBfZXhwdHlwZShjdXJyZW50KTsgIC8vIG1heSBjYWxsIG5leHROb2RlKCkKLQotICAgICAgICBpZiAoZXhwdHlwZSA9PSBOVUxMKQotICAgICAgICAgIHJldHVybiBOVUxMOwotCi0gICAgICAgIGlmIChleHB0eXBlICE9IGV4cGFuZGVkVHlwZUlEKQotICAgICAgICAgIGNvbnRpbnVlOwotCi0gICAgICAgIHJldHVybiBtYWtlTm9kZUhhbmRsZShjdXJyZW50KTsgIC8vIG1ha2UgaGFuZGxlLgotICAgICAgfQotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBJbXBsZW1lbnRzIHRyYXZlcnNhbCBvZiB0aGUgU2VsZiBheGlzLgotICAgKi8KLSAgcHJpdmF0ZSBjbGFzcyBSb290VHJhdmVyc2VyIGV4dGVuZHMgQWxsRnJvbVJvb3RUcmF2ZXJzZXIKLSAgewotICAgIC8qKgotICAgICAqIFJldHVybiB0aGUgcm9vdCBpZiBpdCBtYXRjaGVzIHRoZSBleHBhbmRlZCB0eXBlIElELAotICAgICAqIGVsc2UgcmV0dXJuIG51bGwgKG5vdGhpbmcgZm91bmQpCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCBub2RlIG9mIHRoaXMgdHJhdmVyc2FsLgotICAgICAqIEBwYXJhbSBleHBhbmRlZFR5cGVJRCBUaGUgZXhwYW5kZWQgdHlwZSBJRCB0aGF0IG11c3QgbWF0Y2guCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRoZSBmaXJzdCBub2RlIGluIHRoZSB0cmF2ZXJzYWwuCi0gICAgICovCi0gICAgcHVibGljIGludCBmaXJzdChpbnQgY29udGV4dCwgaW50IGV4cGFuZGVkVHlwZUlEKQotICAgIHsKLSAgICAgIGludCByb290PWdldERvY3VtZW50Um9vdChjb250ZXh0KTsKLSAgICAgIHJldHVybiAoZ2V0RXhwYW5kZWRUeXBlSUQocm9vdCkgPT0gZXhwYW5kZWRUeXBlSUQpCi0gICAgICAgID8gcm9vdCA6IE5VTEw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhdmVyc2UgdG8gdGhlIG5leHQgbm9kZSBhZnRlciB0aGUgY3VycmVudCBub2RlLgotICAgICAqCi0gICAgICogQHBhcmFtIGNvbnRleHQgVGhlIGNvbnRleHQgbm9kZSBvZiB0aGlzIGl0ZXJhdGlvbi4KLSAgICAgKiBAcGFyYW0gY3VycmVudCBUaGUgY3VycmVudCBub2RlIG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIEFsd2F5cyByZXR1cm4gTlVMTCBmb3IgdGhpcyBheGlzLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgbmV4dChpbnQgY29udGV4dCwgaW50IGN1cnJlbnQpCi0gICAgewotICAgICAgcmV0dXJuIE5VTEw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhdmVyc2UgdG8gdGhlIG5leHQgbm9kZSBhZnRlciB0aGUgY3VycmVudCBub2RlIHRoYXQgaXMgbWF0Y2hlZAotICAgICAqIGJ5IHRoZSBleHBhbmRlZCB0eXBlIElELgotICAgICAqCi0gICAgICogQHBhcmFtIGNvbnRleHQgVGhlIGNvbnRleHQgbm9kZSBvZiB0aGlzIGl0ZXJhdGlvbi4KLSAgICAgKiBAcGFyYW0gY3VycmVudCBUaGUgY3VycmVudCBub2RlIG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICogQHBhcmFtIGV4cGFuZGVkVHlwZUlEIFRoZSBleHBhbmRlZCB0eXBlIElEIHRoYXQgbXVzdCBtYXRjaC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdGhlIG5leHQgbm9kZSBpbiB0aGUgaXRlcmF0aW9uLCBvciBEVE0uTlVMTC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IG5leHQoaW50IGNvbnRleHQsIGludCBjdXJyZW50LCBpbnQgZXhwYW5kZWRUeXBlSUQpCi0gICAgewotICAgICAgcmV0dXJuIE5VTEw7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEEgbm9uLXhwYXRoIGF4aXMsIHJldHVybnMgYWxsIG5vZGVzIHRoYXQgYXJlbid0IG5hbWVzcGFjZXMgb3IgYXR0cmlidXRlcywKLSAgICogZnJvbSBhbmQgaW5jbHVkaW5nIHRoZSByb290LgotICAgKi8KLSAgcHJpdmF0ZSBjbGFzcyBEZXNjZW5kYW50T3JTZWxmRnJvbVJvb3RUcmF2ZXJzZXIgZXh0ZW5kcyBEZXNjZW5kYW50VHJhdmVyc2VyCi0gIHsKLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgZmlyc3QgcG90ZW50aWFsIGlkZW50aXR5IHRoYXQgY2FuIGJlIHJldHVybmVkLCB3aGljaCBpcyB0aGUgYXhpcwotICAgICAqIHJvb3QgY29udGV4dCBpbiB0aGlzIGNhc2UuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaWRlbnRpdHkgVGhlIG5vZGUgaWRlbnRpdHkgb2YgdGhlIHJvb3QgY29udGV4dCBvZiB0aGUgdHJhdmVyc2FsLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgaWRlbnRpdHkgYXJndW1lbnQuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGludCBnZXRGaXJzdFBvdGVudGlhbChpbnQgaWRlbnRpdHkpCi0gICAgewotICAgICAgcmV0dXJuIGlkZW50aXR5OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgZmlyc3QgcG90ZW50aWFsIGlkZW50aXR5IHRoYXQgY2FuIGJlIHJldHVybmVkLgotICAgICAqIEBwYXJhbSBoYW5kbGUgaGFuZGxlIHRvIHRoZSByb290IGNvbnRleHQuCi0gICAgICogQHJldHVybiBpZGVudGl0eSBvZiB0aGUgcm9vdCBvZiB0aGUgc3VidHJlZS4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgaW50IGdldFN1YnRyZWVSb290KGludCBoYW5kbGUpCi0gICAgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gJVJFVklFVyUgU2hvdWxkbid0IHRoaXMgYWx3YXlzIGJlIDA/Ci0gICAgICByZXR1cm4gbWFrZU5vZGVJZGVudGl0eShnZXREb2N1bWVudCgpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIHJvb3QuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCBub2RlIG9mIHRoaXMgdHJhdmVyc2FsLgotICAgICAqCi0gICAgICogQHJldHVybiB0aGUgZmlyc3Qgbm9kZSBpbiB0aGUgdHJhdmVyc2FsLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZmlyc3QoaW50IGNvbnRleHQpCi0gICAgewotICAgICAgcmV0dXJuIGdldERvY3VtZW50Um9vdChjb250ZXh0KTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBCeSB0aGUgbmF0dXJlIG9mIHRoZSBzdGF0ZWxlc3MgdHJhdmVyc2FsLCB0aGUgY29udGV4dCBub2RlIGNhbiBub3QgYmUKLSAgICAgKiByZXR1cm5lZCBvciB0aGUgaXRlcmF0aW9uIHdpbGwgZ28gaW50byBhbiBpbmZpbmF0ZSBsb29wLiAgU28gdG8gdHJhdmVyc2UKLSAgICAgKiBhbiBheGlzLCB0aGUgZmlyc3QgZnVuY3Rpb24gbXVzdCBiZSB1c2VkIHRvIGdldCB0aGUgZmlyc3Qgbm9kZS4KLSAgICAgKgotICAgICAqIDxwPlRoaXMgbWV0aG9kIG5lZWRzIHRvIGJlIG92ZXJsb2FkZWQgb25seSBieSB0aG9zZSBheGlzIHRoYXQgcHJvY2VzcwotICAgICAqIHRoZSBzZWxmIG5vZGUuIDxccD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjb250ZXh0IFRoZSBjb250ZXh0IG5vZGUgb2YgdGhpcyB0cmF2ZXJzYWwuIFRoaXMgaXMgdGhlIHBvaW50Ci0gICAgICogb2Ygb3JpZ2luIGZvciB0aGUgdHJhdmVyc2FsIC0tIGl0cyAicm9vdCBub2RlIiBvciBzdGFydGluZyBwb2ludC4KLSAgICAgKiBAcGFyYW0gZXhwYW5kZWRUeXBlSUQgVGhlIGV4cGFuZGVkIHR5cGUgSUQgdGhhdCBtdXN0IG1hdGNoLgotICAgICAqCi0gICAgICogQHJldHVybiB0aGUgZmlyc3Qgbm9kZSBpbiB0aGUgdHJhdmVyc2FsLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZmlyc3QoaW50IGNvbnRleHQsIGludCBleHBhbmRlZFR5cGVJRCkKLSAgICB7Ci0gICAgICBpZiAoaXNJbmRleGVkKGV4cGFuZGVkVHlwZUlEKSkKLSAgICAgIHsKLSAgICAgICAgaW50IGlkZW50aXR5ID0gMDsKLSAgICAgICAgaW50IGZpcnN0UG90ZW50aWFsID0gZ2V0Rmlyc3RQb3RlbnRpYWwoaWRlbnRpdHkpOwotCi0gICAgICAgIHJldHVybiBtYWtlTm9kZUhhbmRsZShnZXROZXh0SW5kZXhlZChpZGVudGl0eSwgZmlyc3RQb3RlbnRpYWwsIGV4cGFuZGVkVHlwZUlEKSk7Ci0gICAgICB9Ci0KLSAgICAgIGludCByb290ID0gZmlyc3QoY29udGV4dCk7Ci0gICAgICByZXR1cm4gbmV4dChyb290LCByb290LCBleHBhbmRlZFR5cGVJRCk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEEgbm9uLXhwYXRoIGF4aXMsIHJldHVybnMgYWxsIG5vZGVzIHRoYXQgYXJlbid0IG5hbWVzcGFjZXMgb3IgYXR0cmlidXRlcywKLSAgICogZnJvbSBidXQgbm90IGluY2x1ZGluZyB0aGUgcm9vdC4KLSAgICovCi0gIHByaXZhdGUgY2xhc3MgRGVzY2VuZGFudEZyb21Sb290VHJhdmVyc2VyIGV4dGVuZHMgRGVzY2VuZGFudFRyYXZlcnNlcgotICB7Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIGZpcnN0IHBvdGVudGlhbCBpZGVudGl0eSB0aGF0IGNhbiBiZSByZXR1cm5lZCwgd2hpY2ggaXMgdGhlIGF4aXMKLSAgICAgKiByb290IGNvbnRleHQgaW4gdGhpcyBjYXNlLgotICAgICAqCi0gICAgICogQHBhcmFtIGlkZW50aXR5IFRoZSBub2RlIGlkZW50aXR5IG9mIHRoZSByb290IGNvbnRleHQgb2YgdGhlIHRyYXZlcnNhbC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIGlkZW50aXR5IGFyZ3VtZW50LgotICAgICAqLwotICAgIHByb3RlY3RlZCBpbnQgZ2V0Rmlyc3RQb3RlbnRpYWwoaW50IGlkZW50aXR5KQotICAgIHsKLSAgICAgIHJldHVybiBfZmlyc3RjaCgwKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIGZpcnN0IHBvdGVudGlhbCBpZGVudGl0eSB0aGF0IGNhbiBiZSByZXR1cm5lZC4KLSAgICAgKiBAcGFyYW0gaGFuZGxlIGhhbmRsZSB0byB0aGUgcm9vdCBjb250ZXh0LgotICAgICAqIEByZXR1cm4gaWRlbnRpdHkgb2YgdGhlIHJvb3Qgb2YgdGhlIHN1YnRyZWUuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGludCBnZXRTdWJ0cmVlUm9vdChpbnQgaGFuZGxlKQotICAgIHsKLSAgICAgIHJldHVybiAwOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybiB0aGUgcm9vdC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjb250ZXh0IFRoZSBjb250ZXh0IG5vZGUgb2YgdGhpcyB0cmF2ZXJzYWwuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRoZSBmaXJzdCBub2RlIGluIHRoZSB0cmF2ZXJzYWwuCi0gICAgICovCi0gICAgcHVibGljIGludCBmaXJzdChpbnQgY29udGV4dCkKLSAgICB7Ci0gICAgICByZXR1cm4gbWFrZU5vZGVIYW5kbGUoX2ZpcnN0Y2goMCkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEJ5IHRoZSBuYXR1cmUgb2YgdGhlIHN0YXRlbGVzcyB0cmF2ZXJzYWwsIHRoZSBjb250ZXh0IG5vZGUgY2FuIG5vdCBiZQotICAgICAqIHJldHVybmVkIG9yIHRoZSBpdGVyYXRpb24gd2lsbCBnbyBpbnRvIGFuIGluZmluYXRlIGxvb3AuICBTbyB0byB0cmF2ZXJzZQotICAgICAqIGFuIGF4aXMsIHRoZSBmaXJzdCBmdW5jdGlvbiBtdXN0IGJlIHVzZWQgdG8gZ2V0IHRoZSBmaXJzdCBub2RlLgotICAgICAqCi0gICAgICogPHA+VGhpcyBtZXRob2QgbmVlZHMgdG8gYmUgb3ZlcmxvYWRlZCBvbmx5IGJ5IHRob3NlIGF4aXMgdGhhdCBwcm9jZXNzCi0gICAgICogdGhlIHNlbGYgbm9kZS4gPFxwPgotICAgICAqCi0gICAgICogQHBhcmFtIGNvbnRleHQgVGhlIGNvbnRleHQgbm9kZSBvZiB0aGlzIHRyYXZlcnNhbC4gVGhpcyBpcyB0aGUgcG9pbnQKLSAgICAgKiBvZiBvcmlnaW4gZm9yIHRoZSB0cmF2ZXJzYWwgLS0gaXRzICJyb290IG5vZGUiIG9yIHN0YXJ0aW5nIHBvaW50LgotICAgICAqIEBwYXJhbSBleHBhbmRlZFR5cGVJRCBUaGUgZXhwYW5kZWQgdHlwZSBJRCB0aGF0IG11c3QgbWF0Y2guCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRoZSBmaXJzdCBub2RlIGluIHRoZSB0cmF2ZXJzYWwuCi0gICAgICovCi0gICAgcHVibGljIGludCBmaXJzdChpbnQgY29udGV4dCwgaW50IGV4cGFuZGVkVHlwZUlEKQotICAgIHsKLSAgICAgIGlmIChpc0luZGV4ZWQoZXhwYW5kZWRUeXBlSUQpKQotICAgICAgewotICAgICAgICBpbnQgaWRlbnRpdHkgPSAwOwotICAgICAgICBpbnQgZmlyc3RQb3RlbnRpYWwgPSBnZXRGaXJzdFBvdGVudGlhbChpZGVudGl0eSk7Ci0KLSAgICAgICAgcmV0dXJuIG1ha2VOb2RlSGFuZGxlKGdldE5leHRJbmRleGVkKGlkZW50aXR5LCBmaXJzdFBvdGVudGlhbCwgZXhwYW5kZWRUeXBlSUQpKTsKLSAgICAgIH0KLQotICAgICAgaW50IHJvb3QgPSBnZXREb2N1bWVudFJvb3QoY29udGV4dCk7Ci0gICAgICByZXR1cm4gbmV4dChyb290LCByb290LCBleHBhbmRlZFR5cGVJRCk7Ci0gICAgfQotCi0gIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL3JlZi9EVE1Eb2N1bWVudEltcGwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9yZWYvRFRNRG9jdW1lbnRJbXBsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGI5YmIzYWMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL3JlZi9EVE1Eb2N1bWVudEltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI0MTMgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRFRNRG9jdW1lbnRJbXBsLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTUgMDg6MTU6MDEgc3VyZXNoX2VtYWlsaWQgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5yZWY7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlNvdXJjZUxvY2F0b3I7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE07Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNQXhpc0l0ZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTUF4aXNUcmF2ZXJzZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNTWFuYWdlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1XU0ZpbHRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLkZhc3RTdHJpbmdCdWZmZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5YTUxTdHJpbmc7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5YTUxTdHJpbmdGYWN0b3J5OwotCi1pbXBvcnQgb3JnLnhtbC5zYXguQXR0cmlidXRlczsKLWltcG9ydCBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5Mb2NhdG9yOwotaW1wb3J0IG9yZy54bWwuc2F4LmV4dC5MZXhpY2FsSGFuZGxlcjsKLQotLyoqCi0gKiBUaGlzIGlzIHRoZSBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgRFRNIGRvY3VtZW50IGludGVyZmFjZS4gIEl0IHJlY2VpdmVzCi0gKiByZXF1ZXN0cyBmcm9tIGFuIFhNTCBjb250ZW50IGhhbmRsZXIgc2ltaWxhciB0byB0aGF0IG9mIGFuIFhNTCBET00gb3IgU0FYIHBhcnNlcgotICogdG8gc3RvcmUgaW5mb3JtYXRpb24gZnJvbSB0aGUgeG1sIGRvY3VtZW50IGluIGFuIGFycmF5IGJhc2VkCi0gKiBkdG0gdGFibGUgc3RydWN0dXJlLiAgVGhpcyBpbmZvcm10aW9uIGlzIHVzZWQgbGF0ZXIgZm9yIGRvY3VtZW50IG5hdmlnYXRpb24sCi0gKiBxdWVyeSwgYW5kIFNBWCBldmVudCBkaXNwYXRjaCBmdW5jdGlvbnMuIFRoZSBEVE0gY2FuIGFsc28gYmUgdXNlZCBkaXJlY3RseSBhcyBhCi0gKiBkb2N1bWVudCBjb21wb3NpdGlvbiBtb2RlbCBmb3IgYW4gYXBwbGljYXRpb24uICBUaGUgcmVxdWVzdHMgcmVjZWl2ZWQgYXJlOgotICogPHVsPgotICogPGxpPmluaXRpYXRpbmcgRFRNIHRvIHNldCB0aGUgZG9jIGhhbmRsZTwvbGk+Ci0gKiA8bGk+cmVzZXR0aW5nIERUTSBmb3IgZGF0YSBzdHJ1Y3R1cmUgcmV1c2U8L2xpPgotICogPGxpPmhpbnRpbmcgdGhlIGVuZCBvZiBkb2N1bWVudCB0byBhZGp1c3QgdGhlIGVuZCBvZiBkYXRhIHN0cnVjdHVyZSBwb2ludGVyczwvbGk+Ci0gKiA8bGk+Y3JlYXRlbm9kZXMgKGVsZW1lbnQsIGNvbW1lbnQsIHRleHQsIGF0dHJpYnV0ZSwgLi4uLik8L2xpPgotICogPGxpPmhpbnRpbmcgdGhlIGVuZCBvZiBhbiBlbGVtZW50IHRvIHBhdGNoIHBhcmVudCBhbmQgc2libGluZ3M8bGk+Ci0gKiA8bGk+c2V0dGluZyBhcHBsaWNhdGlvbiBwcm92aWRlZCBzeW1ib2wgbmFtZSBzdHJpbmdwb29sIGRhdGEgc3RydWN0dXJlczwvbGk+Ci0gKiA8L3VsPgotICogPHA+U3RhdGU6IEluIHByb2dyZXNzISE8L3A+Ci0gKgotICogJVJFVklFVyUgSSBfdGhpbmtfIHRoZSBTQVggY29udmVudGlvbiBpcyB0aGF0ICJubyBuYW1lc3BhY2UiIGlzIGV4cHJlc3NlZAotICogYXMgIiIgcmF0aGVyIHRoYW4gYXMgbnVsbCAod2hpY2ggaXMgdGhlIERPTSdzIGNvbnZlbnRpb24pLiBXaGF0IHNob3VsZAotICogRFRNIGV4cGVjdD8gV2hhdCBzaG91bGQgaXQgZG8gd2l0aCB0aGUgb3RoZXI/Ci0gKgotICogPHA+T3JpZ2luOiB0aGUgaW1wbGVtZW50aW9uIGlzIGEgY29tcG9zaXRlIGxvZ2ljIGJhc2VkIG9uIHRoZSBEVE0gb2YgWGFsYW5KMSBhbmQKLSAqICAgICBEb2NJbXBsLCBEb2N1bWVudEltcGwsIEVsZW1lbnRJbXBsLCBUZXh0SW1wbCwgZXRjLiBvZiBYYWxhbkoyPC9wPgotICovCi1wdWJsaWMgY2xhc3MgRFRNRG9jdW1lbnRJbXBsCi1pbXBsZW1lbnRzIERUTSwgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIsIG9yZy54bWwuc2F4LmV4dC5MZXhpY2FsSGFuZGxlcgotewotCi0gICAgICAgIC8vIE51bWJlciBvZiBsb3dlciBiaXRzIHVzZWQgdG8gcmVwcmVzZW50IG5vZGUgaW5kZXguCi0gICAgICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgYnl0ZSBET0NIQU5ETEVfU0hJRlQgPSAyMjsKLSAgICAgICAgLy8gTWFza3MgdGhlIGxvd2VyIG9yZGVyIG9mIG5vZGUgaGFuZGxlLgotICAgICAgICAvLyBTYW1lIGFzIHtAbGluayBEVE1Db25zdHJ1Y3Rvci5JREVOVF9OT0RFX0RFRkFVTFR9Ci0gICAgICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgaW50IE5PREVIQU5ETEVfTUFTSyA9ICgxIDw8IChET0NIQU5ETEVfU0hJRlQgKyAxKSkgLSAxOwotICAgICAgICAvLyBNYXNrcyB0aGUgaGlnaGVyIG9yZGVyIERvY3VtZW50IGhhbmRsZQotICAgICAgICAvLyBTYW1lIGFzIHtAbGluayBEVE1Db25zdHJ1Y3Rvci5JREVOVF9ET0NfREVGQVVMVH0KLSAgICAgICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBpbnQgRE9DSEFORExFX01BU0sgPSAtMSAtIE5PREVIQU5ETEVfTUFTSzsKLQotICAgICAgICBpbnQgbV9kb2NIYW5kbGUgPSBOVUxMOyAgICAgICAgICAvLyBtYXNrZWQgZG9jdW1lbnQgaGFuZGxlIGZvciB0aGlzIGR0bSBkb2N1bWVudAotICAgICAgICBpbnQgbV9kb2NFbGVtZW50ID0gTlVMTDsgICAgICAgICAvLyBub2RlSGFuZGxlIHRvIHRoZSByb290IG9mIHRoZSBhY3R1YWwgZHRtIGRvYyBjb250ZW50Ci0KLSAgICAgICAgLy8gQ29udGV4dCBmb3IgcGFyc2UtYW5kLWFwcGVuZCBvcGVyYXRpb25zCi0gICAgICAgIGludCBjdXJyZW50UGFyZW50ID0gMDsgICAgICAgICAgICAgICAgICAvLyBjdXJyZW50IHBhcmVudCAtIGRlZmF1bHQgaXMgZG9jdW1lbnQgcm9vdAotICAgICAgICBpbnQgcHJldmlvdXNTaWJsaW5nID0gMDsgICAgICAgICAgICAgICAgLy8gcHJldmlvdXMgc2libGluZyAtIG5vIHByZXZpb3VzIHNpYmxpbmcKLSAgICAgICAgcHJvdGVjdGVkIGludCBtX2N1cnJlbnROb2RlID0gLTE7ICAgICAgICAgICAgICAgLy8gY3VycmVudCBub2RlCi0KLSAgICAgICAgLy8gVGhlIHRyZWUgdW5kZXIgY29uc3RydWN0aW9uIGNhbiBpdHNlbGYgYmUgdXNlZCBhcwotICAgICAgICAvLyB0aGUgZWxlbWVudCBzdGFjaywgc28gbV9lbGVtU3RhY2sgaXNuJ3QgbmVlZGVkLgotICAgICAgICAvL3Byb3RlY3RlZCBTdGFjayBtX2VsZW1TdGFjayA9IG5ldyBTdGFjaygpOyAgICAgLy8gZWxlbWVudCBzdGFjawotCi0gICAgICAgIHByaXZhdGUgYm9vbGVhbiBwcmV2aW91c1NpYmxpbmdXYXNQYXJlbnQgPSBmYWxzZTsKLSAgICAgICAgLy8gTG9jYWwgY2FjaGUgZm9yIHJlY29yZC1hdC1hLXRpbWUgZmV0Y2gKLSAgICAgICAgaW50IGdvdHNsb3RbXSA9IG5ldyBpbnRbNF07Ci0KLSAgICAgICAgLy8gZW5kRG9jdW1lbnQgcmVjaWV2ZWQ/Ci0gICAgICAgIHByaXZhdGUgYm9vbGVhbiBkb25lID0gZmFsc2U7Ci0gICAgICAgIGJvb2xlYW4gbV9pc0Vycm9yID0gZmFsc2U7Ci0KLSAgICAgICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIERFQlVHID0gZmFsc2U7Ci0KLSAgICAgICAgLyoqIFRoZSBkb2N1bWVudCBiYXNlIFVSSS4gKi8KLSAgICAgICAgcHJvdGVjdGVkIFN0cmluZyBtX2RvY3VtZW50QmFzZVVSSTsKLQotICAvKiogSWYgd2UncmUgYnVpbGRpbmcgdGhlIG1vZGVsIGluY3JlbWVudGFsbHkgb24gZGVtYW5kLCB3ZSBuZWVkIHRvCi0gICAqIGJlIGFibGUgdG8gdGVsbCB0aGUgc291cmNlIHdoZW4gdG8gc2VuZCB1cyBtb3JlIGRhdGEuCi0gICAqCi0gICAqIE5vdGUgdGhhdCBpZiB0aGlzIGhhcyBub3QgYmVlbiBzZXQsIGFuZCB5b3UgYXR0ZW1wdCB0byByZWFkIGFoZWFkCi0gICAqIG9mIHRoZSBjdXJyZW50IGJ1aWxkIHBvaW50LCB3ZSdsbCBwcm9iYWJseSB0aHJvdyBhIG51bGwtcG9pbnRlcgotICAgKiBleGNlcHRpb24uIFdlIGNvdWxkIHRyeSB0byB3YWl0LWFuZC1yZXRyeSBpbnN0ZWFkLCBhcyBhIHZlcnkgcG9vcgotICAgKiBmYWxsYmFjaywgYnV0IHRoYXQgaGFzIGFsbCB0aGUga25vd24gcHJvYmxlbXMgd2l0aCBtdWx0aXRocmVhZGluZwotICAgKiBvbiBtdWx0aXByb2Nlc3NvcnMgYW5kIHdlIERvbid0IFdhbnQgdG8gR28gVGhlcmUuCi0gICAqCi0gICAqIEBzZWUgc2V0SW5jcmVtZW50YWxTQVhTb3VyY2UKLSAgICovCi0gIHByaXZhdGUgSW5jcmVtZW50YWxTQVhTb3VyY2UgbV9pbmNyU0FYU291cmNlPW51bGw7Ci0KLQotICAgICAgICAvLyA9PT09PT09PT0gRFRNIGRhdGEgc3RydWN0dXJlIGRlY2xhcmF0aW9ucy4gPT09PT09PT09PT09PT0KLQotICAgICAgICAvLyBub2RlcyBhcnJheTogaW50ZWdlciBhcnJheSBibG9ja3MgdG8gaG9sZCB0aGUgZmlyc3QgbGV2ZWwgcmVmZXJlbmNlIG9mIHRoZSBub2RlcywKLSAgICAgICAgLy8gZWFjaCByZWZlcmVuY2Ugc2xvdCBpcyBhZGRyZXNzZWQgYnkgYSBub2RlSGFuZGxlIGluZGV4IHZhbHVlLgotICAgICAgICAvLyBBc3N1bWVzIGluZGljZXMgYXJlIG5vdCBsYXJnZXIgdGhhbiB7QGxpbmsgTk9ERUhBTkRMRV9NQVNLfQotICAgICAgICAvLyAoe0BsaW5rIERPQ0hBTkRMRV9TSElGVH0gYml0cykuCi0gICAgICAgIENodW5rZWRJbnRBcnJheSBub2RlcyA9IG5ldyBDaHVua2VkSW50QXJyYXkoNCk7Ci0KLSAgICAgICAgLy8gdGV4dC9jb21tZW50IHRhYmxlOiBzdHJpbmcgYnVmZmVyIHRvIGhvbGQgdGhlIHRleHQgc3RyaW5nIHZhbHVlcyBvZiB0aGUgZG9jdW1lbnQsCi0gICAgICAgIC8vIGVhY2ggb2Ygd2hpY2ggaXMgYWRkcmVzc2VkIGJ5IHRoZSBhYnNvbHV0ZSBvZmZzZXQgYW5kIGxlbmd0aCBpbiB0aGUgYnVmZmVyCi0gICAgICAgIHByaXZhdGUgRmFzdFN0cmluZ0J1ZmZlciBtX2NoYXIgPSBuZXcgRmFzdFN0cmluZ0J1ZmZlcigpOwotICAgICAgICAvLyBTdGFydCBvZiBzdHJpbmcgY3VycmVudGx5IGJlaW5nIGFjY3VtdWxhdGVkIGludG8gbV9jaGFyOwotICAgICAgICAvLyBuZWVkZWQgYmVjYXVzZSB0aGUgc3RyaW5nIG1heSBiZSBhcHBlbmRlZCBpbiBzZXZlcmFsIGNodW5rcy4KLSAgICAgICAgcHJpdmF0ZSBpbnQgbV9jaGFyX2N1cnJlbnRfc3RhcnQ9MDsKLQotICAgICAgICAvLyAlVEJEJSBJTklUSUFMSVpBVElPTi9TVEFSVFVQIElTU1VFUwotICAgICAgICAvLyAtLSBTaG91bGQgd2UgcmVhbGx5IGJlIGNyZWF0aW5nIHRoZXNlLCBvciBzaG91bGQgdGhleSBiZQotICAgICAgICAvLyBwYXNzZWQgaW4gZnJvbSBvdXRzaWRlPyBTY290dCB3YW50IHRvIGJlIGFibGUgdG8gc2hhcmUKLSAgICAgICAgLy8gcG9vbHMgYWNyb3NzIG11bHRpcGxlIGRvY3VtZW50cywgc28gc2V0dGluZyB0aGVtIGhlcmUgaXMKLSAgICAgICAgLy8gcHJvYmFibHkgbm90IHRoZSByaWdodCBkZWZhdWx0LgotICAgICAgICBwcml2YXRlIERUTVN0cmluZ1Bvb2wgbV9sb2NhbE5hbWVzID0gbmV3IERUTVN0cmluZ1Bvb2woKTsKLSAgICAgICAgcHJpdmF0ZSBEVE1TdHJpbmdQb29sIG1fbnNOYW1lcyA9IG5ldyBEVE1TdHJpbmdQb29sKCk7Ci0gICAgICAgIHByaXZhdGUgRFRNU3RyaW5nUG9vbCBtX3ByZWZpeE5hbWVzID0gbmV3IERUTVN0cmluZ1Bvb2woKTsKLQotICAgICAgICAvLyAlVEJEJSBJZiB3ZSB1c2UgdGhlIGN1cnJlbnQgRXhwYW5kZWROYW1lVGFibGUgbWFwcGVyLCBpdAotICAgICAgICAvLyBuZWVkcyB0byBiZSBib3VuZCB0byB0aGUgTlMgYW5kIGxvY2FsIG5hbWUgcG9vbHMuIFdoaWNoCi0gICAgICAgIC8vIG1lYW5zIGl0IG5lZWRzIHRvIGF0dGFjaCB0byB0aGVtIEFGVEVSIHdlJ3ZlIHJlc29sdmVkIHRoZWlyCi0gICAgICAgIC8vIHN0YXJ0dXAuIE9yIGl0IG5lZWRzIHRvIGF0dGFjaCB0byB0aGlzIGRvY3VtZW50IGFuZAotICAgICAgICAvLyByZXRyaWV2ZSB0aGVtIGVhY2ggdGltZS4gT3IgdGhpcyBuZWVkcyB0byBiZQotICAgICAgICAvLyBhbiBpbnRlcmZhY2UgX2ltcGxlbWVudGVkXyBieSB0aGlzIGNsYXNzLi4uIHdoaWNoIG1pZ2h0IGJlIHNpbXBsZXN0IQotICAgICAgICBwcml2YXRlIEV4cGFuZGVkTmFtZVRhYmxlIG1fZXhwYW5kZWROYW1lcz0KLSAgICAgICAgICAgICAgICBuZXcgRXhwYW5kZWROYW1lVGFibGUoKTsKLQotICAgICAgICBwcml2YXRlIFhNTFN0cmluZ0ZhY3RvcnkgbV94c2Y7Ci0KLQotICAgICAgICAvKioKLSAgICAgICAgICogQ29uc3RydWN0IGEgRFRNLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gZG9jdW1lbnROdW1iZXIgdGhlIElEIG51bWJlciBhc3NpZ25lZCB0byB0aGlzIGRvY3VtZW50LgotICAgICAgICAgKiBJdCB3aWxsIGJlIHNoaWZ0ZWQgdXAgaW50byB0aGUgaGlnaCBiaXRzIGFuZCByZXR1cm5lZCBhcyBwYXJ0IG9mCi0gICAgICAgICAqIGFsbCBub2RlIElEIG51bWJlcnMsIHNvIHRob3NlIElEcyBpbmRpY2F0ZSB3aGljaCBkb2N1bWVudCB0aGV5Ci0gICAgICAgICAqIGNhbWUgZnJvbSBhcyB3ZWxsIGFzIGEgbG9jYXRpb24gd2l0aGluIHRoZSBkb2N1bWVudC4gSXQgaXMgdGhlCi0gICAgICAgICAqIERUTU1hbmFnZXIncyByZXNwb25zaWJpbGl0eSB0byBhc3NpZ24gYSB1bmlxdWUgbnVtYmVyIHRvIGVhY2gKLSAgICAgICAgICogZG9jdW1lbnQuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgRFRNRG9jdW1lbnRJbXBsKERUTU1hbmFnZXIgbWdyLCBpbnQgZG9jdW1lbnROdW1iZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFRNV1NGaWx0ZXIgd2hpdGVTcGFjZUZpbHRlciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxTdHJpbmdGYWN0b3J5IHhzdHJpbmdmYWN0b3J5KXsKLSAgICAgICAgICAgICAgICBpbml0RG9jdW1lbnQoZG9jdW1lbnROdW1iZXIpOyAgICAvLyBjbGVhciBub2RlcyBhbmQgZG9jdW1lbnQgaGFuZGxlCi0gICAgICAgICAgICAgICAgbV94c2YgPSB4c3RyaW5nZmFjdG9yeTsKLSAgICAgICAgfQotCi0gIC8qKiBCaW5kIGEgSW5jcmVtZW50YWxTQVhTb3VyY2UgdG8gdGhpcyBEVE0uIElmIHdlIGRpc2NvdmVyIHdlIG5lZWQgbm9kZXMKLSAgICogdGhhdCBoYXZlIG5vdCB5ZXQgYmVlbiBidWlsdCwgd2Ugd2lsbCBhc2sgdGhpcyBvYmplY3QgdG8gc2VuZCB1cyBtb3JlCi0gICAqIGV2ZW50cywgYW5kIGl0IHdpbGwgbWFuYWdlIGludGVyYWN0aW9ucyB3aXRoIGl0cyBkYXRhIHNvdXJjZXMuCi0gICAqCi0gICAqIE5vdGUgdGhhdCB3ZSBkbyBub3QgYWN0dWFsbHkgYnVpbGQgdGhlIEluY3JlbWVudGFsU0FYU291cmNlLCBzaW5jZSB3ZSBkb24ndAotICAgKiBrbm93IHdoYXQgc291cmNlIGl0J3MgcmVhZGluZyBmcm9tLCB3aGF0IHRocmVhZCB0aGF0IHNvdXJjZSB3aWxsIHJ1biBpbiwKLSAgICogb3Igd2hlbiBpdCB3aWxsIHJ1bi4KLSAgICoKLSAgICogQHBhcmFtIHNvdXJjZSBUaGUgSW5jcmVtZW50YWxTQVhTb3VyY2UgdGhhdCB3ZSB3YW50IHRvIHJlY2lldmUgZXZlbnRzIGZyb20KLSAgICogb24gZGVtYW5kLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0SW5jcmVtZW50YWxTQVhTb3VyY2UoSW5jcmVtZW50YWxTQVhTb3VyY2Ugc291cmNlKQotICB7Ci0gICAgbV9pbmNyU0FYU291cmNlPXNvdXJjZTsKLQotICAgIC8vIEVzdGFibGlzaCBTQVgtc3RyZWFtIGxpbmsgc28gd2UgY2FuIHJlY2VpdmUgdGhlIHJlcXVlc3RlZCBkYXRhCi0gICAgc291cmNlLnNldENvbnRlbnRIYW5kbGVyKHRoaXMpOwotICAgIHNvdXJjZS5zZXRMZXhpY2FsSGFuZGxlcih0aGlzKTsKLQotICAgIC8vIEFyZSB0aGUgZm9sbG93aW5nIHJlYWxseSBuZWVkZWQ/IEluY3JlbWVudGFsU0FYU291cmNlIGRvZXNuJ3QgeWV0Ci0gICAgLy8gc3VwcG9ydCB0aGVtLCBhbmQgdGhleSdyZSBtb3N0bHkgbm8tb3BzIGhlcmUuLi4KLSAgICAvL3NvdXJjZS5zZXRFcnJvckhhbmRsZXIodGhpcyk7Ci0gICAgLy9zb3VyY2Uuc2V0RFRESGFuZGxlcih0aGlzKTsKLSAgICAvL3NvdXJjZS5zZXREZWNsSGFuZGxlcih0aGlzKTsKLSAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBXcmFwcGVyIGZvciBDaHVua2VkSW50QXJyYXkuYXBwZW5kLCB0byBhdXRvbWF0aWNhbGx5IHVwZGF0ZSB0aGUKLSAgICAgICAgICogcHJldmlvdXMgc2libGluZydzICJuZXh0IiByZWZlcmVuY2UgKGlmIG5lY2Vzc2FyeSkgYW5kIHBlcmlvZGljYWxseQotICAgICAgICAgKiB3YWtlIGEgcmVhZGVyIHdobyBtYXkgaGF2ZSBlbmNvdW50ZXJlZCBpbmNvbXBsZXRlIGRhdGEgYW5kIGVudGVyZWQKLSAgICAgICAgICogYSB3YWl0IHN0YXRlLgotICAgICAgICAgKiBAcGFyYW0gdzAgaW50IEFzIGluIENodW5rZWRJbnRBcnJheS5hcHBlbmQKLSAgICAgICAgICogQHBhcmFtIHcxIGludCBBcyBpbiBDaHVua2VkSW50QXJyYXkuYXBwZW5kCi0gICAgICAgICAqIEBwYXJhbSB3MiBpbnQgQXMgaW4gQ2h1bmtlZEludEFycmF5LmFwcGVuZAotICAgICAgICAgKiBAcGFyYW0gdzMgaW50IEFzIGluIENodW5rZWRJbnRBcnJheS5hcHBlbmQKLSAgICAgICAgICogQHJldHVybiBpbnQgQXMgaW4gQ2h1bmtlZEludEFycmF5LmFwcGVuZAotICAgICAgICAgKiBAc2VlIENodW5rZWRJbnRBcnJheS5hcHBlbmQKLSAgICAgICAgICovCi0gICAgICAgIHByaXZhdGUgZmluYWwgaW50IGFwcGVuZE5vZGUoaW50IHcwLCBpbnQgdzEsIGludCB3MiwgaW50IHczKQotICAgICAgICB7Ci0gICAgICAgICAgICAgICAgLy8gQSBkZWNlbnQgY29tcGlsZXIgbWF5IGlubGluZSB0aGlzLgotICAgICAgICAgICAgICAgIGludCBzbG90bnVtYmVyID0gbm9kZXMuYXBwZW5kU2xvdCh3MCwgdzEsIHcyLCB3Myk7Ci0KLSAgICAgICAgICAgICAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbihzbG90bnVtYmVyKyI6ICIrdzArIiAiK3cxKyIgIit3MisiICIrdzMpOwotCi0gICAgICAgICAgICAgICAgaWYgKHByZXZpb3VzU2libGluZ1dhc1BhcmVudCkKLSAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVzLndyaXRlRW50cnkocHJldmlvdXNTaWJsaW5nLDIsc2xvdG51bWJlcik7Ci0KLSAgICAgICAgICAgICAgICBwcmV2aW91c1NpYmxpbmdXYXNQYXJlbnQgPSBmYWxzZTsgICAgICAgLy8gU2V0IHRoZSBkZWZhdWx0OyBlbmRFbGVtZW50IG92ZXJyaWRlcwotCi0gICAgICAgICAgICAgICAgcmV0dXJuIHNsb3RudW1iZXI7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyA9PT09PT09PT0gRFRNIEltcGxlbWVudGF0aW9uIENvbnRyb2wgRnVuY3Rpb25zLiA9PT09PT09PT09PT09PQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBTZXQgYW4gaW1wbGVtZW50YXRpb24gZGVwZW5kZW50IGZlYXR1cmUuCi0gICAgICAgICAqIDxwPgotICAgICAgICAgKiAlUkVWSUVXJSBEbyB3ZSByZWFsbHkgZXhwZWN0IHRvIHNldCBmZWF0dXJlcyBvbiBEVE1zPwotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gZmVhdHVyZUlkIEEgZmVhdHVyZSBVUkwuCi0gICAgICAgICAqIEBwYXJhbSBzdGF0ZSB0cnVlIGlmIHRoaXMgZmVhdHVyZSBzaG91bGQgYmUgb24sIGZhbHNlIG90aGVyd2lzZS4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyB2b2lkIHNldEZlYXR1cmUoU3RyaW5nIGZlYXR1cmVJZCwgYm9vbGVhbiBzdGF0ZSkge307Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFNldCBhIHJlZmVyZW5jZSBwb2ludGVyIHRvIHRoZSBlbGVtZW50IG5hbWUgc3ltYm9sIHRhYmxlLgotICAgICAgICAgKiAlUkVWSUVXJSBTaG91bGQgdGhpcyByZWFsbHkgYmUgUHVibGljPyBDaGFuZ2luZyBpdCB3aGlsZQotICAgICAgICAgKiBEVE0gaXMgaW4gdXNlIHdvdWxkIGJlIGEgZGlzYXN0ZXIuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBwb29sUmVmIERUTVN0cmluZ1Bvb2wgcmVmZXJlbmNlIHRvIGFuIGluc3RhbmNlIG9mIHRhYmxlLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIHZvaWQgc2V0TG9jYWxOYW1lVGFibGUoRFRNU3RyaW5nUG9vbCBwb29sUmVmKSB7Ci0gICAgICAgICAgICAgICAgbV9sb2NhbE5hbWVzID0gcG9vbFJlZjsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBHZXQgYSByZWZlcmVuY2UgcG9pbnRlciB0byB0aGUgZWxlbWVudCBuYW1lIHN5bWJvbCB0YWJsZS4KLSAgICAgICAgICoKLSAgICAgICAgICogQHJldHVybiBEVE1TdHJpbmdQb29sIHJlZmVyZW5jZSB0byBhbiBpbnN0YW5jZSBvZiB0YWJsZS4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBEVE1TdHJpbmdQb29sIGdldExvY2FsTmFtZVRhYmxlKCkgewotICAgICAgICAgICAgICAgICByZXR1cm4gbV9sb2NhbE5hbWVzOwotICAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBTZXQgYSByZWZlcmVuY2UgcG9pbnRlciB0byB0aGUgbmFtZXNwYWNlIFVSSSBzeW1ib2wgdGFibGUuCi0gICAgICAgICAqICVSRVZJRVclIFNob3VsZCB0aGlzIHJlYWxseSBiZSBQdWJsaWM/IENoYW5naW5nIGl0IHdoaWxlCi0gICAgICAgICAqIERUTSBpcyBpbiB1c2Ugd291bGQgYmUgYSBkaXNhc3Rlci4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIHBvb2xSZWYgRFRNU3RyaW5nUG9vbCByZWZlcmVuY2UgdG8gYW4gaW5zdGFuY2Ugb2YgdGFibGUuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgdm9pZCBzZXROc05hbWVUYWJsZShEVE1TdHJpbmdQb29sIHBvb2xSZWYpIHsKLSAgICAgICAgICAgICAgICBtX25zTmFtZXMgPSBwb29sUmVmOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIEdldCBhIHJlZmVyZW5jZSBwb2ludGVyIHRvIHRoZSBuYW1lc3BhY2UgVVJJIHN5bWJvbCB0YWJsZS4KLSAgICAgICAgICoKLSAgICAgICAgICogQHJldHVybiBEVE1TdHJpbmdQb29sIHJlZmVyZW5jZSB0byBhbiBpbnN0YW5jZSBvZiB0YWJsZS4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBEVE1TdHJpbmdQb29sIGdldE5zTmFtZVRhYmxlKCkgewotICAgICAgICAgICAgICAgICByZXR1cm4gbV9uc05hbWVzOwotICAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBTZXQgYSByZWZlcmVuY2UgcG9pbnRlciB0byB0aGUgcHJlZml4IG5hbWUgc3ltYm9sIHRhYmxlLgotICAgICAgICAgKiAlUkVWSUVXJSBTaG91bGQgdGhpcyByZWFsbHkgYmUgUHVibGljPyBDaGFuZ2luZyBpdCB3aGlsZQotICAgICAgICAgKiBEVE0gaXMgaW4gdXNlIHdvdWxkIGJlIGEgZGlzYXN0ZXIuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBwb29sUmVmIERUTVN0cmluZ1Bvb2wgcmVmZXJlbmNlIHRvIGFuIGluc3RhbmNlIG9mIHRhYmxlLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIHZvaWQgc2V0UHJlZml4TmFtZVRhYmxlKERUTVN0cmluZ1Bvb2wgcG9vbFJlZikgewotICAgICAgICAgICAgICAgIG1fcHJlZml4TmFtZXMgPSBwb29sUmVmOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIEdldCBhIHJlZmVyZW5jZSBwb2ludGVyIHRvIHRoZSBwcmVmaXggbmFtZSBzeW1ib2wgdGFibGUuCi0gICAgICAgICAqCi0gICAgICAgICAqIEByZXR1cm4gRFRNU3RyaW5nUG9vbCByZWZlcmVuY2UgdG8gYW4gaW5zdGFuY2Ugb2YgdGFibGUuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgRFRNU3RyaW5nUG9vbCBnZXRQcmVmaXhOYW1lVGFibGUoKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIG1fcHJlZml4TmFtZXM7Ci0gICAgICAgIH0KLQotICAgICAgICAgLyoqCi0gICAgICAgICAgKiBTZXQgYSByZWZlcmVuY2UgcG9pbnRlciB0byB0aGUgY29udGVudC10ZXh0IHJlcG9zaXRvcnkKLSAgICAgICAgICAqCi0gICAgICAgICAgKiBAcGFyYW0gYnVmZmVyIEZhc3RTdHJpbmdCdWZmZXIgcmVmZXJlbmNlIHRvIGFuIGluc3RhbmNlIG9mCi0gICAgICAgICAgKiBidWZmZXIKLSAgICAgICAgICAqLwotICAgICAgICAgdm9pZCBzZXRDb250ZW50QnVmZmVyKEZhc3RTdHJpbmdCdWZmZXIgYnVmZmVyKSB7Ci0gICAgICAgICAgICAgICAgIG1fY2hhciA9IGJ1ZmZlcjsKLSAgICAgICAgIH0KLQotICAgICAgICAgLyoqCi0gICAgICAgICAgKiBHZXQgYSByZWZlcmVuY2UgcG9pbnRlciB0byB0aGUgY29udGVudC10ZXh0IHJlcG9zaXRvcnkKLSAgICAgICAgICAqCi0gICAgICAgICAgKiBAcmV0dXJuIEZhc3RTdHJpbmdCdWZmZXIgcmVmZXJlbmNlIHRvIGFuIGluc3RhbmNlIG9mIGJ1ZmZlcgotICAgICAgICAgICovCi0gICAgICAgICBGYXN0U3RyaW5nQnVmZmVyIGdldENvbnRlbnRCdWZmZXIoKSB7Ci0gICAgICAgICAgICAgICAgIHJldHVybiBtX2NoYXI7Ci0gICAgICAgICB9Ci0KLSAgLyoqIGdldENvbnRlbnRIYW5kbGVyIHJldHVybnMgIm91ciBTQVggYnVpbGRlciIgLS0gdGhlIHRoaW5nIHRoYXQKLSAgICogc29tZW9uZSBlbHNlIHNob3VsZCBzZW5kIFNBWCBldmVudHMgdG8gaW4gb3JkZXIgdG8gZXh0ZW5kIHRoaXMKLSAgICogRFRNIG1vZGVsLgotICAgKgotICAgKiBAcmV0dXJuIG51bGwgaWYgdGhpcyBtb2RlbCBkb2Vzbid0IHJlc3BvbmQgdG8gU0FYIGV2ZW50cywKLSAgICogInRoaXMiIGlmIHRoZSBEVE0gb2JqZWN0IGhhcyBhIGJ1aWx0LWluIFNBWCBDb250ZW50SGFuZGxlciwKLSAgICogdGhlIEluY3JlbWVudGFsU0FYU291cmNlIGlmIHdlJ3JlIGJvdW5kIHRvIG9uZSBhbmQgc2hvdWxkIHJlY2VpdmUKLSAgICogdGhlIFNBWCBzdHJlYW0gdmlhIGl0IGZvciBpbmNyZW1lbnRhbCBidWlsZCBwdXJwb3Nlcy4uLgotICAgKiAqLwotICBwdWJsaWMgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIgZ2V0Q29udGVudEhhbmRsZXIoKQotICB7Ci0gICAgaWYgKG1faW5jclNBWFNvdXJjZSBpbnN0YW5jZW9mIEluY3JlbWVudGFsU0FYU291cmNlX0ZpbHRlcikKLSAgICAgIHJldHVybiAoQ29udGVudEhhbmRsZXIpIG1faW5jclNBWFNvdXJjZTsKLSAgICBlbHNlCi0gICAgICByZXR1cm4gdGhpczsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhpcyBEVE0ncyBsZXhpY2FsIGhhbmRsZXIuCi0gICAqCi0gICAqICVSRVZJRVclIFNob3VsZCB0aGlzIHJldHVybiBudWxsIGlmIGNvbnN0cnV0aW9uIGFscmVhZHkgZG9uZS9iZWd1bj8KLSAgICoKLSAgICogQHJldHVybiBudWxsIGlmIHRoaXMgbW9kZWwgZG9lc24ndCByZXNwb25kIHRvIGxleGljYWwgU0FYIGV2ZW50cywKLSAgICogInRoaXMiIGlmIHRoZSBEVE0gb2JqZWN0IGhhcyBhIGJ1aWx0LWluIFNBWCBDb250ZW50SGFuZGxlciwKLSAgICogdGhlIEluY3JlbWVudGFsU0FYU291cmNlIGlmIHdlJ3JlIGJvdW5kIHRvIG9uZSBhbmQgc2hvdWxkIHJlY2VpdmUKLSAgICogdGhlIFNBWCBzdHJlYW0gdmlhIGl0IGZvciBpbmNyZW1lbnRhbCBidWlsZCBwdXJwb3Nlcy4uLgotICAgKi8KLSAgcHVibGljIExleGljYWxIYW5kbGVyIGdldExleGljYWxIYW5kbGVyKCkKLSAgewotCi0gICAgaWYgKG1faW5jclNBWFNvdXJjZSBpbnN0YW5jZW9mIEluY3JlbWVudGFsU0FYU291cmNlX0ZpbHRlcikKLSAgICAgIHJldHVybiAoTGV4aWNhbEhhbmRsZXIpIG1faW5jclNBWFNvdXJjZTsKLSAgICBlbHNlCi0gICAgICByZXR1cm4gdGhpczsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhpcyBEVE0ncyBFbnRpdHlSZXNvbHZlci4KLSAgICoKLSAgICogQHJldHVybiBudWxsIGlmIHRoaXMgbW9kZWwgZG9lc24ndCByZXNwb25kIHRvIFNBWCBlbnRpdHkgcmVmIGV2ZW50cy4KLSAgICovCi0gIHB1YmxpYyBvcmcueG1sLnNheC5FbnRpdHlSZXNvbHZlciBnZXRFbnRpdHlSZXNvbHZlcigpCi0gIHsKLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGlzIERUTSdzIERUREhhbmRsZXIuCi0gICAqCi0gICAqIEByZXR1cm4gbnVsbCBpZiB0aGlzIG1vZGVsIGRvZXNuJ3QgcmVzcG9uZCB0byBTQVggZHRkIGV2ZW50cy4KLSAgICovCi0gIHB1YmxpYyBvcmcueG1sLnNheC5EVERIYW5kbGVyIGdldERUREhhbmRsZXIoKQotICB7Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhpcyBEVE0ncyBFcnJvckhhbmRsZXIuCi0gICAqCi0gICAqIEByZXR1cm4gbnVsbCBpZiB0aGlzIG1vZGVsIGRvZXNuJ3QgcmVzcG9uZCB0byBTQVggZXJyb3IgZXZlbnRzLgotICAgKi8KLSAgcHVibGljIG9yZy54bWwuc2F4LkVycm9ySGFuZGxlciBnZXRFcnJvckhhbmRsZXIoKQotICB7Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhpcyBEVE0ncyBEZWNsSGFuZGxlci4KLSAgICoKLSAgICogQHJldHVybiBudWxsIGlmIHRoaXMgbW9kZWwgZG9lc24ndCByZXNwb25kIHRvIFNBWCBEZWNsIGV2ZW50cy4KLSAgICovCi0gIHB1YmxpYyBvcmcueG1sLnNheC5leHQuRGVjbEhhbmRsZXIgZ2V0RGVjbEhhbmRsZXIoKQotICB7Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKiBAcmV0dXJuIHRydWUgaWZmIHdlJ3JlIGJ1aWxkaW5nIHRoaXMgbW9kZWwgaW5jcmVtZW50YWxseSAoZWcKLSAgICogd2UncmUgcGFydG5lcmVkIHdpdGggYSBJbmNyZW1lbnRhbFNBWFNvdXJjZSkgYW5kIHRodXMgcmVxdWlyZSB0aGF0IHRoZQotICAgKiB0cmFuc2Zvcm1hdGlvbiBhbmQgdGhlIHBhcnNlIHJ1biBzaW11bHRhbmVvdXNseS4gR3VpZGFuY2UgdG8gdGhlCi0gICAqIERUTU1hbmFnZXIuCi0gICAqICovCi0gIHB1YmxpYyBib29sZWFuIG5lZWRzVHdvVGhyZWFkcygpCi0gIHsKLSAgICByZXR1cm4gbnVsbCE9bV9pbmNyU0FYU291cmNlOwotICB9Ci0KLSAgLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gIC8vID09PT09PT09PSBTQVgyIENvbnRlbnRIYW5kbGVyIG1ldGhvZHMgPT09PT09PT09Ci0gIC8vIEFjY2VwdCBTQVggZXZlbnRzLCB1c2UgdGhlbSB0byBidWlsZC9leHRlbmQgdGhlIERUTSB0cmVlLgotICAvLyBSZXBsYWNlcyB0aGUgZGVwcmVjYXRlZCBEb2N1bWVudEhhbmRsZXIgaW50ZXJmYWNlLgotCi0gIHB1YmxpYyB2b2lkIGNoYXJhY3RlcnMoY2hhcltdIGNoLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpCi0gICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgLy8gQWN0dWFsbHkgY3JlYXRpbmcgdGhlIHRleHQgbm9kZSBpcyBoYW5kbGVkIGJ5Ci0gICAgLy8gcHJvY2Vzc0FjY3VtdWxhdGVkVGV4dCgpOyBoZXJlIHdlIGp1c3QgYWNjdW11bGF0ZSB0aGUKLSAgICAvLyBjaGFyYWN0ZXJzIGludG8gdGhlIGJ1ZmZlci4KLSAgICBtX2NoYXIuYXBwZW5kKGNoLHN0YXJ0LGxlbmd0aCk7Ci0gIH0KLQotICAvLyBGbHVzaCBzdHJpbmcgYWNjdW11bGF0aW9uIGludG8gYSB0ZXh0IG5vZGUKLSAgcHJpdmF0ZSB2b2lkIHByb2Nlc3NBY2N1bXVsYXRlZFRleHQoKQotICB7Ci0gICAgaW50IGxlbj1tX2NoYXIubGVuZ3RoKCk7Ci0gICAgaWYobGVuIT1tX2NoYXJfY3VycmVudF9zdGFydCkKLSAgICAgIHsKLSAgICAgICAgLy8gVGhlIEZhc3RTdHJpbmdCdWZmZXIgaGFzIGJlZW4gcHJldmlvdXNseSBhZ3JlZWQgdXBvbgotICAgICAgICBhcHBlbmRUZXh0Q2hpbGQobV9jaGFyX2N1cnJlbnRfc3RhcnQsbGVuLW1fY2hhcl9jdXJyZW50X3N0YXJ0KTsKLSAgICAgICAgbV9jaGFyX2N1cnJlbnRfc3RhcnQ9bGVuOwotICAgICAgfQotICB9Ci0gIHB1YmxpYyB2b2lkIGVuZERvY3VtZW50KCkKLSAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICAvLyBNYXkgbmVlZCB0byB0ZWxsIHRoZSBsb3ctbGV2ZWwgYnVpbGRlciBjb2RlIHRvIHBvcCB1cCBhIGxldmVsLgotICAgIC8vIFRoZXJlIF9zaG91bGQndF8gYmUgYW55IHNpZ25pZmljYW50IHBlbmRpbmcgdGV4dCBhdCB0aGlzIHBvaW50LgotICAgIGFwcGVuZEVuZERvY3VtZW50KCk7Ci0gIH0KLSAgcHVibGljIHZvaWQgZW5kRWxlbWVudChqYXZhLmxhbmcuU3RyaW5nIG5hbWVzcGFjZVVSSSwgamF2YS5sYW5nLlN0cmluZyBsb2NhbE5hbWUsCi0gICAgICBqYXZhLmxhbmcuU3RyaW5nIHFOYW1lKQotICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIHByb2Nlc3NBY2N1bXVsYXRlZFRleHQoKTsKLSAgICAvLyBObyBhcmdzIGJ1dCB3ZSBkbyBuZWVkIHRvIHRlbGwgdGhlIGxvdy1sZXZlbCBidWlsZGVyIGNvZGUgdG8KLSAgICAvLyBwb3AgdXAgYSBsZXZlbC4KLSAgICBhcHBlbmRFbmRFbGVtZW50KCk7Ci0gIH0KLSAgcHVibGljIHZvaWQgZW5kUHJlZml4TWFwcGluZyhqYXZhLmxhbmcuU3RyaW5nIHByZWZpeCkKLSAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICAvLyBOby1vcAotICB9Ci0gIHB1YmxpYyB2b2lkIGlnbm9yYWJsZVdoaXRlc3BhY2UoY2hhcltdIGNoLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpCi0gICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgLy8gJVRCRCUgSSBiZWxpZXZlIGlnbm9yYWJsZSB0ZXh0IGlzbid0IHBhcnQgb2YgdGhlIERUTSBtb2RlbC4uLj8KLSAgfQotICBwdWJsaWMgdm9pZCBwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oamF2YS5sYW5nLlN0cmluZyB0YXJnZXQsIGphdmEubGFuZy5TdHJpbmcgZGF0YSkKLSAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBwcm9jZXNzQWNjdW11bGF0ZWRUZXh0KCk7Ci0gICAgLy8gJVRCRCUgV2hpY2ggcG9vbHMgZG8gdGFyZ2V0IGFuZCBkYXRhIGdvIGludG8/Ci0gIH0KLSAgcHVibGljIHZvaWQgc2V0RG9jdW1lbnRMb2NhdG9yKExvY2F0b3IgbG9jYXRvcikKLSAgewotICAgIC8vIE5vLW9wIGZvciBEVE0KLSAgfQotICBwdWJsaWMgdm9pZCBza2lwcGVkRW50aXR5KGphdmEubGFuZy5TdHJpbmcgbmFtZSkKLSAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBwcm9jZXNzQWNjdW11bGF0ZWRUZXh0KCk7Ci0gICAgLy8lVEJEJQotICB9Ci0gIHB1YmxpYyB2b2lkIHN0YXJ0RG9jdW1lbnQoKQotICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIGFwcGVuZFN0YXJ0RG9jdW1lbnQoKTsKLSAgfQotICBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQoamF2YS5sYW5nLlN0cmluZyBuYW1lc3BhY2VVUkksIGphdmEubGFuZy5TdHJpbmcgbG9jYWxOYW1lLAotICAgICAgamF2YS5sYW5nLlN0cmluZyBxTmFtZSwgQXR0cmlidXRlcyBhdHRzKQotICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIHByb2Nlc3NBY2N1bXVsYXRlZFRleHQoKTsKLQotICAgIC8vICVUQkQlIFNwbGl0IHByZWZpeCBvZmYgcW5hbWUKLSAgICBTdHJpbmcgcHJlZml4PW51bGw7Ci0gICAgaW50IGNvbG9uPXFOYW1lLmluZGV4T2YoJzonKTsKLSAgICBpZihjb2xvbj4wKQotICAgICAgcHJlZml4PXFOYW1lLnN1YnN0cmluZygwLGNvbG9uKTsKLQotICAgIC8vICVUQkQlIFdoZXJlIGRvIHdlIHBvb2wgZXhwYW5kZWROYW1lLCBvciBpcyBpdCBqdXN0IHRoZSB1bmlvbiwgb3IuLi4KLSAgICAvKiovU3lzdGVtLm91dC5wcmludGxuKCJQcmVmaXg9IitwcmVmaXgrIiBpbmRleD0iK21fcHJlZml4TmFtZXMuc3RyaW5nVG9JbmRleChwcmVmaXgpKTsKLSAgICBhcHBlbmRTdGFydEVsZW1lbnQobV9uc05hbWVzLnN0cmluZ1RvSW5kZXgobmFtZXNwYWNlVVJJKSwKLSAgICAgICAgICAgICAgICAgICAgIG1fbG9jYWxOYW1lcy5zdHJpbmdUb0luZGV4KGxvY2FsTmFtZSksCi0gICAgICAgICAgICAgICAgICAgICBtX3ByZWZpeE5hbWVzLnN0cmluZ1RvSW5kZXgocHJlZml4KSk7IC8vLy8vLy8gJVRCRCUKLQotICAgIC8vICVUQkQlIEknbSBhc3N1bWluZyB0aGF0IERUTSB3aWxsIHJlcXVpcmUgcmVzZXF1ZW5jaW5nIG9mCi0gICAgLy8gTlMgZGVjbHMgYmVmb3JlIG90aGVyIGF0dHJzLCBoZW5jZSB0d28gcGFzc2VzIGFyZSB0YWtlbi4KLSAgICAvLyAlVEJEJSBJcyB0aGVyZSBhbiBlYXNpZXIgd2F5IHRvIHRlc3QgZm9yIE5TRGVjbD8KLSAgICBpbnQgbkF0dHM9KGF0dHM9PW51bGwpID8gMCA6IGF0dHMuZ2V0TGVuZ3RoKCk7Ci0gICAgLy8gJVRCRCUgQ291bnRkb3duIGlzIG1vcmUgZWZmaWNpZW50IGlmIG5vYm9keSBjYXJlcyBhYm91dCBzZXF1ZW5jZS4KLSAgICBmb3IoaW50IGk9bkF0dHMtMTtpPj0wOy0taSkKLSAgICAgIHsKLSAgICAgICAgcU5hbWU9YXR0cy5nZXRRTmFtZShpKTsKLSAgICAgICAgaWYocU5hbWUuc3RhcnRzV2l0aCgieG1sbnM6IikgfHwgInhtbG5zIi5lcXVhbHMocU5hbWUpKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIHByZWZpeD1udWxsOwotICAgICAgICAgICAgY29sb249cU5hbWUuaW5kZXhPZignOicpOwotICAgICAgICAgICAgaWYoY29sb24+MCkKLSAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIHByZWZpeD1xTmFtZS5zdWJzdHJpbmcoMCxjb2xvbik7Ci0gICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIC8vICVSRVZFSVclIE51bGwgb3IgIiI/Ci0gICAgICAgICAgICAgICAgcHJlZml4PW51bGw7IC8vIERlZmF1bHQgcHJlZml4Ci0gICAgICAgICAgICAgIH0KLQotCi0gICAgICAgICAgICBhcHBlbmROU0RlY2xhcmF0aW9uKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbV9wcmVmaXhOYW1lcy5zdHJpbmdUb0luZGV4KHByZWZpeCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX25zTmFtZXMuc3RyaW5nVG9JbmRleChhdHRzLmdldFZhbHVlKGkpKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHMuZ2V0VHlwZShpKS5lcXVhbHNJZ25vcmVDYXNlKCJJRCIpKTsKLSAgICAgICAgICB9Ci0gICAgICB9Ci0KLSAgICBmb3IoaW50IGk9bkF0dHMtMTtpPj0wOy0taSkKLSAgICAgIHsKLSAgICAgICAgcU5hbWU9YXR0cy5nZXRRTmFtZShpKTsKLSAgICAgICAgaWYoIShxTmFtZS5zdGFydHNXaXRoKCJ4bWxuczoiKSB8fCAieG1sbnMiLmVxdWFscyhxTmFtZSkpKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIC8vICVUQkQlIEkgaGF0ZSBoYXZpbmcgdG8gZXh0cmFjdCB0aGUgcHJlZml4IGludG8gYSBuZXcKLSAgICAgICAgICAgIC8vIHN0cmluZyB3aGVuIHdlIG1heSBuZXZlciB1c2UgaXQuIENvbnNpZGVyIHBvb2xpbmcgd2hvbGUKLSAgICAgICAgICAgIC8vIHFOYW1lcywgd2hpY2ggYXJlIGFscmVhZHkgc3RyaW5ncz8KLSAgICAgICAgICAgIHByZWZpeD1udWxsOwotICAgICAgICAgICAgY29sb249cU5hbWUuaW5kZXhPZignOicpOwotICAgICAgICAgICAgaWYoY29sb24+MCkKLSAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIHByZWZpeD1xTmFtZS5zdWJzdHJpbmcoMCxjb2xvbik7Ci0gICAgICAgICAgICAgICAgbG9jYWxOYW1lPXFOYW1lLnN1YnN0cmluZyhjb2xvbisxKTsKLSAgICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgcHJlZml4PSIiOyAvLyBEZWZhdWx0IHByZWZpeAotICAgICAgICAgICAgICAgIGxvY2FsTmFtZT1xTmFtZTsKLSAgICAgICAgICAgICAgfQotCi0KLSAgICAgICAgICAgIG1fY2hhci5hcHBlbmQoYXR0cy5nZXRWYWx1ZShpKSk7IC8vIFNpbmdsZS1zdHJpbmcgdmFsdWUKLSAgICAgICAgICAgIGludCBjb250ZW50RW5kPW1fY2hhci5sZW5ndGgoKTsKLQotICAgICAgICAgICAgaWYoISgieG1sbnMiLmVxdWFscyhwcmVmaXgpIHx8ICJ4bWxucyIuZXF1YWxzKHFOYW1lKSkpCi0gICAgICAgICAgICAgIGFwcGVuZEF0dHJpYnV0ZShtX25zTmFtZXMuc3RyaW5nVG9JbmRleChhdHRzLmdldFVSSShpKSksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbV9sb2NhbE5hbWVzLnN0cmluZ1RvSW5kZXgobG9jYWxOYW1lKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX3ByZWZpeE5hbWVzLnN0cmluZ1RvSW5kZXgocHJlZml4KSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRzLmdldFR5cGUoaSkuZXF1YWxzSWdub3JlQ2FzZSgiSUQiKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX2NoYXJfY3VycmVudF9zdGFydCwgY29udGVudEVuZC1tX2NoYXJfY3VycmVudF9zdGFydCk7Ci0gICAgICAgICAgICBtX2NoYXJfY3VycmVudF9zdGFydD1jb250ZW50RW5kOwotICAgICAgICAgIH0KLSAgICAgIH0KLSAgfQotICBwdWJsaWMgdm9pZCBzdGFydFByZWZpeE1hcHBpbmcoamF2YS5sYW5nLlN0cmluZyBwcmVmaXgsIGphdmEubGFuZy5TdHJpbmcgdXJpKQotICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIC8vIE5vLW9wIGluIERUTSwgaGFuZGxlZCBkdXJpbmcgZWxlbWVudC9hdHRyIHByb2Nlc3Npbmc/Ci0gIH0KLQotICAvLwotICAvLyBMZXhpY2FsSGFuZGxlciBzdXBwb3J0LiBOb3QgYWxsIFNBWDIgcGFyc2VycyBzdXBwb3J0IHRoZXNlIGV2ZW50cwotICAvLyBidXQgd2UgbWF5IHdhbnQgdG8gcGFzcyB0aGVtIHRocm91Z2ggd2hlbiB0aGV5IGV4aXN0Li4uCi0gIC8vCi0gIHB1YmxpYyB2b2lkIGNvbW1lbnQoY2hhcltdIGNoLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpCi0gICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgcHJvY2Vzc0FjY3VtdWxhdGVkVGV4dCgpOwotCi0gICAgbV9jaGFyLmFwcGVuZChjaCxzdGFydCxsZW5ndGgpOyAvLyBTaW5nbGUtc3RyaW5nIHZhbHVlCi0gICAgYXBwZW5kQ29tbWVudChtX2NoYXJfY3VycmVudF9zdGFydCxsZW5ndGgpOwotICAgIG1fY2hhcl9jdXJyZW50X3N0YXJ0Kz1sZW5ndGg7Ci0gIH0KLSAgcHVibGljIHZvaWQgZW5kQ0RBVEEoKQotICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIC8vIE5vLW9wIGluIERUTQotICB9Ci0gIHB1YmxpYyB2b2lkIGVuZERURCgpCi0gICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgLy8gTm8tb3AgaW4gRFRNCi0gIH0KLSAgcHVibGljIHZvaWQgZW5kRW50aXR5KGphdmEubGFuZy5TdHJpbmcgbmFtZSkKLSAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICAvLyBOby1vcCBpbiBEVE0KLSAgfQotICBwdWJsaWMgdm9pZCBzdGFydENEQVRBKCkKLSAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICAvLyBOby1vcCBpbiBEVE0KLSAgfQotICBwdWJsaWMgdm9pZCBzdGFydERURChqYXZhLmxhbmcuU3RyaW5nIG5hbWUsIGphdmEubGFuZy5TdHJpbmcgcHVibGljSWQsCi0gICAgICBqYXZhLmxhbmcuU3RyaW5nIHN5c3RlbUlkKQotICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIC8vIE5vLW9wIGluIERUTQotICB9Ci0gIHB1YmxpYyB2b2lkIHN0YXJ0RW50aXR5KGphdmEubGFuZy5TdHJpbmcgbmFtZSkKLSAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICAvLyBOby1vcCBpbiBEVE0KLSAgfQotCi0KLSAgLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gIC8vID09PT09PT09PSBEb2N1bWVudCBIYW5kbGVyIEZ1bmN0aW9ucyA9PT09PT09PT0KLSAgLy8gJVJFVklFVyUgamprIC0tIERvY3VtZW50SGFuZGxlciBpcyAgU0FYIExldmVsIDEsIGFuZCBkZXByZWNhdGVkLi4uLgotICAvLyBhbmQgdGhpcyB3YXNuJ3QgYSBmdWxseSBjb21wbGlhbnQgb3IgZGVjbGFyZWQgaW1wbGVtZW50YXRpb24gb2YgdGhhdCBBUEkKLSAgLy8gaW4gYW55IGNhc2UuIFBoYXNlIG91dCBpbiBmYXZvciBvZiBTQVgyIENvbnRlbnRIYW5kbGVyL0xleGljYWxIYW5kbGVyCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFJlc2V0IGEgZHRtIGRvY3VtZW50IHRvIGl0cyBpbml0aWFsIChlbXB0eSkgc3RhdGUuCi0gICAgICAgICAqCi0gICAgICAgICAqIFRoZSBEVE1NYW5hZ2VyIHdpbGwgaW52b2tlIHRoaXMgbWV0aG9kIHdoZW4gdGhlIGR0bSBpcyBjcmVhdGVkLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gZG9jdW1lbnROdW1iZXIgdGhlIGhhbmRsZSBmb3IgdGhlIERUTSBkb2N1bWVudC4KLSAgICAgICAgICovCi0gICAgICAgIGZpbmFsIHZvaWQgaW5pdERvY3VtZW50KGludCBkb2N1bWVudE51bWJlcikKLSAgICAgICAgewotICAgICAgICAgICAgICAgIC8vIHNhdmUgbWFza2VkIERUTSBkb2N1bWVudCBoYW5kbGUKLSAgICAgICAgICAgICAgICBtX2RvY0hhbmRsZSA9IGRvY3VtZW50TnVtYmVyPDxET0NIQU5ETEVfU0hJRlQ7Ci0KLSAgICAgICAgICAgICAgICAvLyBJbml0aWFsaXplIHRoZSBkb2MgLS0gbm8gcGFyZW50LCBubyBuZXh0LXNpYgotICAgICAgICAgICAgICAgIG5vZGVzLndyaXRlU2xvdCgwLERPQ1VNRU5UX05PREUsLTEsLTEsMCk7Ci0gICAgICAgICAgICAgICAgLy8gd2FpdCBmb3IgdGhlIGZpcnN0IHN0YXJ0RWxlbWVudCB0byBjcmVhdGUgdGhlIGRvYyByb290IG5vZGUKLSAgICAgICAgICAgICAgICBkb25lID0gZmFsc2U7Ci0gICAgICAgIH0KLQotLy8gICAgICAvKioKLS8vICAgICAgICogUmVjZWl2ZSBoaW50IG9mIHRoZSBlbmQgb2YgYSBkb2N1bWVudC4KLS8vICAgICAgICoKLS8vICAgICAgICogPHA+VGhlIGNvbnRlbnQgaGFuZGxlciB3aWxsIGludm9rZSB0aGlzIG1ldGhvZCBvbmx5IG9uY2UsIGFuZCBpdCB3aWxsCi0vLyAgICAgICAqIGJlIHRoZSBsYXN0IG1ldGhvZCBpbnZva2VkIGR1cmluZyB0aGUgcGFyc2UuICBUaGUgaGFuZGxlciBzaGFsbCBub3QKLS8vICAgICAgICogbm90IGludm9rZSB0aGlzIG1ldGhvZCB1bnRpbCBpdCBoYXMgZWl0aGVyIGFiYW5kb25lZCBwYXJzaW5nCi0vLyAgICAgICAqIChiZWNhdXNlIG9mIGFuIHVucmVjb3ZlcmFibGUgZXJyb3IpIG9yIHJlYWNoZWQgdGhlIGVuZCBvZgotLy8gICAgICAgKiBpbnB1dC48L3A+Ci0vLyAgICAgICAqLwotLy8gICAgICBwdWJsaWMgdm9pZCBkb2N1bWVudEVuZCgpCi0vLyAgICAgIHsKLS8vICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKLS8vICAgICAgICAgICAgICAvLyAlVEJEJSBtYXkgbmVlZCB0byBub3RpY2UgdGhlIGxhc3Qgc2xvdCBudW1iZXIgYW5kIHNsb3QgY291bnQgdG8gYXZvaWQKLS8vICAgICAgICAgICAgICAvLyByZXNpZHVhbCBkYXRhIGZyb20gcHJvdmlvdXMgdXNlIG9mIHRoaXMgRFRNCi0vLyAgICAgIH0KLQotLy8gICAgICAvKioKLS8vICAgICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIGJlZ2lubmluZyBvZiBhIGRvY3VtZW50LgotLy8gICAgICAgKgotLy8gICAgICAgKiA8cD5UaGUgU0FYIHBhcnNlciB3aWxsIGludm9rZSB0aGlzIG1ldGhvZCBvbmx5IG9uY2UsIGJlZm9yZSBhbnkKLS8vICAgICAgICogb3RoZXIgbWV0aG9kcyBpbiB0aGlzIGludGVyZmFjZS48L3A+Ci0vLyAgICAgICAqLwotLy8gICAgICBwdWJsaWMgdm9pZCByZXNldCgpCi0vLyAgICAgIHsKLQotLy8gICAgICAgICAgICAgIC8vICVUQkQlIHJlc2V0IHNsb3QgMCB0byBpbmRpY2F0ZSBDaHVua2VkSW50QXJyYXkgcmV1c2Ugb3Igd2FpdCBmb3IKLS8vICAgICAgICAgICAgICAvLyAgICAgICB0aGUgbmV4dCBpbml0RG9jdW1lbnQoKS4KLS8vICAgICAgICAgICAgICBtX2RvY0VsZW1lbnQgPSBOVUxMOyAgICAgLy8gcmVzZXQgbm9kZUhhbmRsZSB0byB0aGUgcm9vdCBvZiB0aGUgYWN0dWFsIGR0bSBkb2MgY29udGVudAotLy8gICAgICAgICAgICAgIGluaXREb2N1bWVudCgwKTsKLS8vICAgICAgfQotCi0vLyAgICAgIC8qKgotLy8gICAgICAgKiBGYWN0b3J5IG1ldGhvZDsgY3JlYXRlcyBhbiBFbGVtZW50IG5vZGUgaW4gdGhpcyBkb2N1bWVudC4KLS8vICAgICAgICoKLS8vICAgICAgICogVGhlIG5vZGUgY3JlYXRlZCB3aWxsIGJlIGNoYWluZWQgYWNjb3JkaW5nIHRvIGl0cyBuYXR1cmFsIG9yZGVyIG9mIHJlcXVlc3QKLS8vICAgICAgICogcmVjZWl2ZWQuICAlVEJEJSBJdCBjYW4gYmUgcmVjaGFpbmVkIGxhdGVyIHZpYSB0aGUgb3B0aW9uYWwgRFRNIHdyaXRhYmxlIGludGVyZmFjZS4KLS8vICAgICAgICoKLS8vICAgICAgICogPHA+VGhlIFhNTCBjb250ZW50IGhhbmRsZXIgd2lsbCBpbnZva2UgZW5kRWxlbWVudCgpIG1ldGhvZCBhZnRlciBhbGwKLS8vICAgICAgICogb2YgdGhlIGVsZW1lbnQncyBjb250ZW50IGFyZSBwcm9jZXNzZWQgaW4gb3JkZXIgdG8gZ2l2ZSBEVE0gdGhlIGluZGljYXRpb24KLS8vICAgICAgICogdG8gcHJlcGFyZSBhbmQgcGF0Y2ggdXAgcGFyZW50IGFuZCBzaWJsaW5nIG5vZGUgcG9pbnRlcnMuPC9wPgotLy8gICAgICAgKgotLy8gICAgICAgKiA8cD5UaGUgZm9sbG93aW5nIGludGVyZmFjZSBmb3IgY3JlYXRlRWxlbWVudCB3aWxsIHVzZSBhbiBpbmRleCB2YWx1ZSBjb3JyZXNwb25kcwotLy8gICAgICAgKiB0byB0aGUgc3ltYm9sIGVudHJ5IGluIHRoZSBEVE1EU3RyaW5nUG9vbCBiYXNlZCBzeW1ib2wgdGFibGVzLjwvcD4KLS8vICAgICAgICoKLS8vICAgICAgICogQHBhcmFtIG5zSW5kZXggVGhlIG5hbWVzcGFjZSBvZiB0aGUgbm9kZQotLy8gICAgICAgKiBAcGFyYW0gbmFtZUluZGV4IFRoZSBlbGVtZW50IG5hbWUuCi0vLyAgICAgICAqIEBzZWUgI2VuZEVsZW1lbnQKLS8vICAgICAgICogQHNlZSBvcmcueG1sLnNheC5BdHRyaWJ1dGVzCi0vLyAgICAgICAqIEByZXR1cm4gbm9kZUhhbmRsZSBpbnQgb2YgdGhlIGVsZW1lbnQgY3JlYXRlZAotLy8gICAgICAgKi8KLS8vICAgICAgcHVibGljIGludCBjcmVhdGVFbGVtZW50KGludCBuc0luZGV4LCBpbnQgbmFtZUluZGV4LCBBdHRyaWJ1dGVzIGF0dHMpCi0vLyAgICAgIHsKLS8vICAgICAgICAgICAgICAvLyBkbyBkb2N1bWVudCByb290IG5vZGUgY3JlYXRpb24gaGVyZSBvbiB0aGUgZmlyc3QgZWxlbWVudCwgY3JlYXRlIG5vZGVzIGZvcgotLy8gICAgICAgICAgICAgIC8vIHRoaXMgZWxlbWVudCBhbmQgaXRzIGF0dHJpYnV0ZXMsIHN0b3JlIHRoZSBlbGVtZW50LCBuYW1lc3BhY2UsIGFuZCBhdHRyaXR1dGUKLS8vICAgICAgICAgICAgICAvLyBuYW1lIGluZGV4ZXMgdG8gdGhlIG5vZGVzIGFycmF5LCBrZWVwIHRyYWNrIG9mIHRoZSBjdXJyZW50IG5vZGUgYW5kIHBhcmVudAotLy8gICAgICAgICAgICAgIC8vIGVsZW1lbnQgdXNlZAotCi0vLyAgICAgICAgICAgICAgLy8gVzAgIEhpZ2g6ICBOYW1lc3BhY2UgIExvdzogIE5vZGUgVHlwZQotLy8gICAgICAgICAgICAgIGludCB3MCA9IChuc0luZGV4IDw8IDE2KSB8IEVMRU1FTlRfTk9ERTsKLS8vICAgICAgICAgICAgICAvLyBXMTogUGFyZW50Ci0vLyAgICAgICAgICAgICAgaW50IHcxID0gY3VycmVudFBhcmVudDsKLS8vICAgICAgICAgICAgICAvLyBXMjogTmV4dCAgKGluaXRpYWxpemVkIGFzIDApCi0vLyAgICAgICAgICAgICAgaW50IHcyID0gMDsKLS8vICAgICAgICAgICAgICAvLyBXMzogVGFnbmFtZQotLy8gICAgICAgICAgICAgIGludCB3MyA9IG5hbWVJbmRleDsKLS8vICAgICAgICAgICAgICAvL2ludCBvdXJzbG90ID0gbm9kZXMuYXBwZW5kU2xvdCh3MCwgdzEsIHcyLCB3Myk7Ci0vLyAgICAgICAgICAgICAgaW50IG91cnNsb3QgPSBhcHBlbmROb2RlKHcwLCB3MSwgdzIsIHczKTsKLS8vICAgICAgICAgICAgICBjdXJyZW50UGFyZW50ID0gb3Vyc2xvdDsKLS8vICAgICAgICAgICAgICBwcmV2aW91c1NpYmxpbmcgPSAwOwotLy8gICAgICAgICAgICAgIHNldEF0dHJpYnV0ZXMoYXR0cyk7Ci0KLS8vICAgICAgICAgICAgICAvLyBzZXQgdGhlIHJvb3QgZWxlbWVudCBwb2ludGVyIHdoZW4gY3JlYXRpbmcgdGhlIGZpcnN0IGVsZW1lbnQgbm9kZQotLy8gICAgICAgICAgICAgIGlmIChtX2RvY0VsZW1lbnQgPT0gTlVMTCkKLS8vICAgICAgICAgICAgICAgICAgICAgIG1fZG9jRWxlbWVudCA9IG91cnNsb3Q7Ci0vLyAgICAgICAgICAgICAgcmV0dXJuIChtX2RvY0hhbmRsZSB8IG91cnNsb3QpOwotLy8gICAgICB9Ci0KLS8vICAgICAgLy8gRmFjdG9yeSBtZXRob2QgdG8gY3JlYXRlIGFuIEVsZW1lbnQgbm9kZSBub3QgYXNzb2NpYXRlZCB3aXRoIGEgZ2l2ZW4gbmFtZSBzcGFjZQotLy8gICAgICAvLyB1c2luZyBTdHJpbmcgdmFsdWUgcGFyYW1ldGVycyBwYXNzZWQgaW4gZnJvbSBhIGNvbnRlbnQgaGFuZGxlciBvciBhcHBsaWNhdGlvbgotLy8gICAgICAvKioKLS8vICAgICAgICogRmFjdG9yeSBtZXRob2Q7IGNyZWF0ZXMgYW4gRWxlbWVudCBub2RlIG5vdCBhc3NvY2lhdGVkIHdpdGggYSBnaXZlbiBuYW1lIHNwYWNlIGluIHRoaXMgZG9jdW1lbnQuCi0vLyAgICAgICAqCi0vLyAgICAgICAqIFRoZSBub2RlIGNyZWF0ZWQgd2lsbCBiZSBjaGFpbmVkIGFjY29yZGluZyB0byBpdHMgbmF0dXJhbCBvcmRlciBvZiByZXF1ZXN0Ci0vLyAgICAgICAqIHJlY2VpdmVkLiAgJVRCRCUgSXQgY2FuIGJlIHJlY2hhaW5lZCBsYXRlciB2aWEgdGhlIG9wdGlvbmFsIERUTSB3cml0YWJsZSBpbnRlcmZhY2UuCi0vLyAgICAgICAqCi0vLyAgICAgICAqIDxwPlRoZSBYTUwgY29udGVudCBoYW5kbGVyIG9yIGFwcGxpY2F0aW9uIHdpbGwgaW52b2tlIGVuZEVsZW1lbnQoKSBtZXRob2QgYWZ0ZXIgYWxsCi0vLyAgICAgICAqIG9mIHRoZSBlbGVtZW50J3MgY29udGVudCBhcmUgcHJvY2Vzc2VkIGluIG9yZGVyIHRvIGdpdmUgRFRNIHRoZSBpbmRpY2F0aW9uCi0vLyAgICAgICAqIHRvIHByZXBhcmUgYW5kIHBhdGNoIHVwIHBhcmVudCBhbmQgc2libGluZyBub2RlIHBvaW50ZXJzLjwvcD4KLS8vICAgICAgICoKLS8vICAgICAgICogPHA+VGhlIGZvbGxvd2luZyBwYXJhbWV0ZXJzIGZvciBjcmVhdGVFbGVtZW50IGNvbnRhaW5zIHJhdyBzdHJpbmcgdmFsdWVzIGZvciBuYW1lCi0vLyAgICAgICAqIHN5bWJvbHMgdXNlZCBpbiBhbiBFbGVtZW50IG5vZGUuPC9wPgotLy8gICAgICAgKgotLy8gICAgICAgKiBAcGFyYW0gbmFtZSBTdHJpbmcgdGhlIGVsZW1lbnQgbmFtZSwgaW5jbHVkaW5nIHRoZSBwcmVmaXggaWYgYW55LgotLy8gICAgICAgKiBAcGFyYW0gYXR0cyBUaGUgYXR0cmlidXRlcyBhdHRhY2hlZCB0byB0aGUgZWxlbWVudCwgaWYgYW55LgotLy8gICAgICAgKiBAc2VlICNlbmRFbGVtZW50Ci0vLyAgICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQXR0cmlidXRlcwotLy8gICAgICAgKi8KLS8vICAgICAgcHVibGljIGludCBjcmVhdGVFbGVtZW50KFN0cmluZyBuYW1lLCBBdHRyaWJ1dGVzIGF0dHMpCi0vLyAgICAgIHsKLS8vICAgICAgICAgICAgICAvLyBUaGlzIG1ldGhvZCB3cmFwcyBhcm91bmQgdGhlIGluZGV4IHZhbHVlZCBpbnRlcmZhY2Ugb2YgdGhlIGNyZWF0ZUVsZW1lbnQgaW50ZXJmYWNlLgotLy8gICAgICAgICAgICAgIC8vIFRoZSByYXcgc3RyaW5nIHZhbHVlcyBhcmUgc3RvcmVkIGludG8gdGhlIGN1cnJlbnQgRFRNIG5hbWUgc3ltYm9sIHRhYmxlcy4gIFRoZSBtZXRob2QKLS8vICAgICAgICAgICAgICAvLyBtZXRob2Qgd2lsbCB0aGVuIHVzZSB0aGUgaW5kZXggdmFsdWVzIHJldHVybmVkIHRvIGludm9rZSB0aGUgb3RoZXIgY3JlYXRlRWxlbWVudCgpCi0vLyAgICAgICAgICAgICAgLy8gb252ZXJ0ZWQgdG8gaW5kZXggdmFsdWVzIG1vZGlmaWVkIHRvIG1hdGNoIGEKLS8vICAgICAgICAgICAgICAvLyBtZXRob2QuCi0vLyAgICAgICAgICAgICAgaW50IG5zSW5kZXggPSBOVUxMOwotLy8gICAgICAgICAgICAgIGludCBuYW1lSW5kZXggPSBtX2xvY2FsTmFtZXMuc3RyaW5nVG9JbmRleChuYW1lKTsKLS8vICAgICAgICAgICAgICAvLyBub3RlIC0gdGhlcmUgc2hvdWxkIGJlIG5vIHByZWZpeCBzZXBhcmF0b3IgaW4gdGhlIG5hbWUgYmVjYXVzZSBpdCBpcyBub3QgYXNzb2NpYXRlZAotLy8gICAgICAgICAgICAgIC8vIHdpdGggYSBuYW1lIHNwYWNlCi0KLS8vICAgICAgICAgICAgICByZXR1cm4gY3JlYXRlRWxlbWVudChuc0luZGV4LCBuYW1lSW5kZXgsIGF0dHMpOwotLy8gICAgICB9Ci0KLS8vICAgICAgLy8gRmFjdG9yeSBtZXRob2QgdG8gY3JlYXRlIGFuIEVsZW1lbnQgbm9kZSBhc3NvY2lhdGVkIHdpdGggYSBnaXZlbiBuYW1lIHNwYWNlCi0vLyAgICAgIC8vIHVzaW5nIFN0cmluZyB2YWx1ZSBwYXJhbWV0ZXJzIHBhc3NlZCBpbiBmcm9tIGEgY29udGVudCBoYW5kbGVyIG9yIGFwcGxpY2F0aW9uCi0vLyAgICAgIC8qKgotLy8gICAgICAgKiBGYWN0b3J5IG1ldGhvZDsgY3JlYXRlcyBhbiBFbGVtZW50IG5vZGUgYXNzb2NpYXRlZCB3aXRoIGEgZ2l2ZW4gbmFtZSBzcGFjZSBpbiB0aGlzIGRvY3VtZW50LgotLy8gICAgICAgKgotLy8gICAgICAgKiBUaGUgbm9kZSBjcmVhdGVkIHdpbGwgYmUgY2hhaW5lZCBhY2NvcmRpbmcgdG8gaXRzIG5hdHVyYWwgb3JkZXIgb2YgcmVxdWVzdAotLy8gICAgICAgKiByZWNlaXZlZC4gICVUQkQlIEl0IGNhbiBiZSByZWNoYWluZWQgbGF0ZXIgdmlhIHRoZSBvcHRpb25hbCBEVE0gd3JpdGFibGUgaW50ZXJmYWNlLgotLy8gICAgICAgKgotLy8gICAgICAgKiA8cD5UaGUgWE1MIGNvbnRlbnQgaGFuZGxlciBvciBhcHBsaWNhdGlvbiB3aWxsIGludm9rZSBlbmRFbGVtZW50KCkgbWV0aG9kIGFmdGVyIGFsbAotLy8gICAgICAgKiBvZiB0aGUgZWxlbWVudCdzIGNvbnRlbnQgYXJlIHByb2Nlc3NlZCBpbiBvcmRlciB0byBnaXZlIERUTSB0aGUgaW5kaWNhdGlvbgotLy8gICAgICAgKiB0byBwcmVwYXJlIGFuZCBwYXRjaCB1cCBwYXJlbnQgYW5kIHNpYmxpbmcgbm9kZSBwb2ludGVycy48L3A+Ci0vLyAgICAgICAqCi0vLyAgICAgICAqIDxwPlRoZSBmb2xsb3dpbmcgcGFyYW1ldGVycyBmb3IgY3JlYXRlRWxlbWVudE5TIGNvbnRhaW5zIHJhdyBzdHJpbmcgdmFsdWVzIGZvciBuYW1lCi0vLyAgICAgICAqIHN5bWJvbHMgdXNlZCBpbiBhbiBFbGVtZW50IG5vZGUuPC9wPgotLy8gICAgICAgKgotLy8gICAgICAgKiBAcGFyYW0gbnMgU3RyaW5nIHRoZSBuYW1lc3BhY2Ugb2YgdGhlIG5vZGUKLS8vICAgICAgICogQHBhcmFtIG5hbWUgU3RyaW5nIHRoZSBlbGVtZW50IG5hbWUsIGluY2x1ZGluZyB0aGUgcHJlZml4IGlmIGFueS4KLS8vICAgICAgICogQHBhcmFtIGF0dHMgVGhlIGF0dHJpYnV0ZXMgYXR0YWNoZWQgdG8gdGhlIGVsZW1lbnQsIGlmIGFueS4KLS8vICAgICAgICogQHNlZSAjZW5kRWxlbWVudAotLy8gICAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkF0dHJpYnV0ZXMKLS8vICAgICAgICovCi0vLyAgICAgIHB1YmxpYyBpbnQgY3JlYXRlRWxlbWVudE5TKFN0cmluZyBucywgU3RyaW5nIG5hbWUsIEF0dHJpYnV0ZXMgYXR0cykKLS8vICAgICAgewotLy8gICAgICAgICAgICAgIC8vIFRoaXMgbWV0aG9kIHdyYXBzIGFyb3VuZCB0aGUgaW5kZXggdmFsdWVkIGludGVyZmFjZSBvZiB0aGUgY3JlYXRlRWxlbWVudCBpbnRlcmZhY2UuCi0vLyAgICAgICAgICAgICAgLy8gVGhlIHJhdyBzdHJpbmcgdmFsdWVzIGFyZSBzdG9yZWQgaW50byB0aGUgY3VycmVudCBEVE0gbmFtZSBzeW1ib2wgdGFibGVzLiAgVGhlIG1ldGhvZAotLy8gICAgICAgICAgICAgIC8vIG1ldGhvZCB3aWxsIHRoZW4gdXNlIHRoZSBpbmRleCB2YWx1ZXMgcmV0dXJuZWQgdG8gaW52b2tlIHRoZSBvdGhlciBjcmVhdGVFbGVtZW50KCkKLS8vICAgICAgICAgICAgICAvLyBvbnZlcnRlZCB0byBpbmRleCB2YWx1ZXMgbW9kaWZpZWQgdG8gbWF0Y2ggYQotLy8gICAgICAgICAgICAgIC8vIG1ldGhvZC4KLS8vICAgICAgICAgICAgICBpbnQgbnNJbmRleCA9IG1fbnNOYW1lcy5zdHJpbmdUb0luZGV4KG5zKTsKLS8vICAgICAgICAgICAgICBpbnQgbmFtZUluZGV4ID0gbV9sb2NhbE5hbWVzLnN0cmluZ1RvSW5kZXgobmFtZSk7Ci0vLyAgICAgICAgICAgICAgLy8gVGhlIHByZWZpeEluZGV4IGlzIG5vdCBuZWVkZWQgYnkgdGhlIGluZGV4ZWQgaW50ZXJmYWNlIG9mIHRoZSBjcmVhdGVFbGVtZW50IG1ldGhvZAotLy8gICAgICAgICAgICAgIGludCBwcmVmaXhTZXAgPSBuYW1lLmluZGV4T2YoIjoiKTsKLS8vICAgICAgICAgICAgICBpbnQgcHJlZml4SW5kZXggPSBtX3ByZWZpeE5hbWVzLnN0cmluZ1RvSW5kZXgobmFtZS5zdWJzdHJpbmcoMCwgcHJlZml4U2VwKSk7Ci0vLyAgICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUVsZW1lbnQobnNJbmRleCwgbmFtZUluZGV4LCBhdHRzKTsKLS8vICAgICAgfQotCi0vLyAgICAgIC8qKgotLy8gICAgICAgKiBSZWNlaXZlIGFuIGluZGljYXRpb24gZm9yIHRoZSBlbmQgb2YgYW4gZWxlbWVudC4KLS8vICAgICAgICoKLS8vICAgICAgICogPHA+VGhlIFhNTCBjb250ZW50IGhhbmRsZXIgd2lsbCBpbnZva2UgdGhpcyBtZXRob2QgYXQgdGhlIGVuZCBvZiBldmVyeQotLy8gICAgICAgKiBlbGVtZW50IGluIHRoZSBYTUwgZG9jdW1lbnQgdG8gZ2l2ZSBoaW50IGl0cyB0aW1lIHRvIHBvcCB1cCB0aGUgY3VycmVudAotLy8gICAgICAgKiBlbGVtZW50IGFuZCBwYXJlbnQgYW5kIHBhdGNoIHVwIHBhcmVudCBhbmQgc2libGluZyBwb2ludGVycyBpZiBuZWNlc3NhcnkKLS8vICAgICAgICoKLS8vICAgICAgICogPHA+JXRiZCUgVGhlIGZvbGxvd2luZyBpbnRlcmZhY2UgbWF5IG5lZWQgdG8gYmUgbW9kaWZpZWQgdG8gbWF0Y2ggYQotLy8gICAgICAgKiBjb29yZGluYXRlZCBhY2Nlc3MgdG8gdGhlIERUTURTdHJpbmdQb29sIGJhc2VkIHN5bWJvbCB0YWJsZXMuPC9wPgotLy8gICAgICAgICAgICAgICAqCi0vLyAgICAgICAqIEBwYXJhbSBucyB0aGUgbmFtZXNwYWNlIG9mIHRoZSBlbGVtZW50Ci0vLyAgICAgICAqIEBwYXJhbSBuYW1lIFRoZSBlbGVtZW50IG5hbWUKLS8vICAgICAgICovCi0vLyAgICAgIHB1YmxpYyB2b2lkIGVuZEVsZW1lbnQoU3RyaW5nIG5zLCBTdHJpbmcgbmFtZSkKLS8vICAgICAgewotLy8gICAgICAgICAgICAgIC8vIHBvcCB1cCB0aGUgc3RhY2tzCi0KLS8vICAgICAgICAgICAgICAvLwotLy8gICAgICAgICAgICAgIGlmIChwcmV2aW91c1NpYmxpbmdXYXNQYXJlbnQpCi0vLyAgICAgICAgICAgICAgICAgICAgICBub2Rlcy53cml0ZUVudHJ5KHByZXZpb3VzU2libGluZywgMiwgTlVMTCk7Ci0KLS8vICAgICAgICAgICAgICAvLyBQb3AgcGFyZW50YWdlCi0vLyAgICAgICAgICAgICAgcHJldmlvdXNTaWJsaW5nID0gY3VycmVudFBhcmVudDsKLS8vICAgICAgICAgICAgICBub2Rlcy5yZWFkU2xvdChjdXJyZW50UGFyZW50LCBnb3RzbG90KTsKLS8vICAgICAgICAgICAgICBjdXJyZW50UGFyZW50ID0gZ290c2xvdFsxXSAmIDB4RkZGRjsKLQotLy8gICAgICAgICAgICAgIC8vIFRoZSBlbGVtZW50IGp1c3QgYmVpbmcgZmluaXNoZWQgd2lsbCBiZQotLy8gICAgICAgICAgICAgIC8vIHRoZSBwcmV2aW91cyBzaWJsaW5nIGZvciB0aGUgbmV4dCBvcGVyYXRpb24KLS8vICAgICAgICAgICAgICBwcmV2aW91c1NpYmxpbmdXYXNQYXJlbnQgPSB0cnVlOwotCi0vLyAgICAgICAgICAgICAgLy8gUG9wIGEgbGV2ZWwgb2YgbmFtZXNwYWNlIHRhYmxlCi0vLyAgICAgICAgICAgICAgLy8gbmFtZXNwYWNlVGFibGUucmVtb3ZlTGFzdEVsZW0oKTsKLS8vICAgICAgfQotCi0vLyAgICAgIC8qKgotLy8gICAgICAgKiBDcmVhdGVzIGF0dHJpYnV0ZXMgZm9yIHRoZSBjdXJyZW50IG5vZGUuCi0vLyAgICAgICAqCi0vLyAgICAgICAqIEBwYXJhbSBhdHRzIEF0dHJpYnV0ZXMgdG8gYmUgY3JlYXRlZC4KLS8vICAgICAgICovCi0vLyAgICAgIHZvaWQgc2V0QXR0cmlidXRlcyhBdHRyaWJ1dGVzIGF0dHMpIHsKLS8vICAgICAgICAgICAgICBpbnQgYXRMZW5ndGggPSAobnVsbCA9PSBhdHRzKSA/IDAgOiBhdHRzLmdldExlbmd0aCgpOwotLy8gICAgICAgICAgICAgIGZvciAoaW50IGk9MDsgaSA8IGF0TGVuZ3RoOyBpKyspIHsKLS8vICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBxbmFtZSA9IGF0dHMuZ2V0UU5hbWUoaSk7Ci0vLyAgICAgICAgICAgICAgICAgICAgICBjcmVhdGVBdHRyaWJ1dGUoYXR0cy5nZXRRTmFtZShpKSwgYXR0cy5nZXRWYWx1ZShpKSk7Ci0vLyAgICAgICAgICAgICAgfQotLy8gICAgICB9Ci0KLS8vICAgICAgLyoqCi0vLyAgICAgICAqIEFwcGVuZHMgYW4gYXR0cmlidXRlIHRvIHRoZSBkb2N1bWVudC4KLS8vICAgICAgICogQHBhcmFtIHFuYW1lIFF1YWxpZmllZCBOYW1lIG9mIHRoZSBhdHRyaWJ1dGUKLS8vICAgICAgICogQHBhcmFtIHZhbHVlIFZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUKLS8vICAgICAgICogQHJldHVybiBIYW5kbGUgb2Ygbm9kZQotLy8gICAgICAgKi8KLS8vICAgICAgcHVibGljIGludCBjcmVhdGVBdHRyaWJ1dGUoU3RyaW5nIHFuYW1lLCBTdHJpbmcgdmFsdWUpIHsKLS8vICAgICAgICAgICAgICBpbnQgY29sb25wb3MgPSBxbmFtZS5pbmRleE9mKCI6Iik7Ci0vLyAgICAgICAgICAgICAgU3RyaW5nIGF0dE5hbWUgPSBxbmFtZS5zdWJzdHJpbmcoY29sb25wb3MrMSk7Ci0vLyAgICAgICAgICAgICAgaW50IHcwID0gMDsKLS8vICAgICAgICAgICAgICBpZiAoY29sb25wb3MgPiAwKSB7Ci0vLyAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcHJlZml4ID0gcW5hbWUuc3Vic3RyaW5nKDAsIGNvbG9ucG9zKTsKLS8vICAgICAgICAgICAgICAgICAgICAgIGlmIChwcmVmaXguZXF1YWxzKCJ4bWwiKSkgewotLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3cwID0gQVRUUklCVVRFX05PREUgfAotLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgICAgIChjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwudGVtcGxhdGVzLkNvbnN0YW50cy5TX1hNTE5BTUVTUEFDRVVSSSA8PCAxNik7Ci0vLyAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3cwID0gQVRUUklCVVRFX05PREUgfAotLy8gICAgICAgICAgICAgICAgICAgICAgfQotLy8gICAgICAgICAgICAgIH0gZWxzZSB7Ci0vLyAgICAgICAgICAgICAgICAgICAgICB3MCA9IEFUVFJJQlVURV9OT0RFOwotLy8gICAgICAgICAgICAgIH0KLS8vICAgICAgICAgICAgICAvLyBXMTogIFBhcmVudAotLy8gICAgICAgICAgICAgIGludCB3MSA9IGN1cnJlbnRQYXJlbnQ7Ci0vLyAgICAgICAgICAgICAgLy8gVzI6ICBOZXh0IChub3QgeWV0IHJlc29sdmVkKQotLy8gICAgICAgICAgICAgIGludCB3MiA9IDA7Ci0vLyAgICAgICAgICAgICAgLy8gVzM6ICBUYWcgbmFtZQotLy8gICAgICAgICAgICAgIGludCB3MyA9IG1fbG9jYWxOYW1lcy5zdHJpbmdUb0luZGV4KGF0dE5hbWUpOwotLy8gICAgICAgICAgICAgIC8vIEFkZCBub2RlCi0vLyAgICAgICAgICAgICAgaW50IG91cnNsb3QgPSBhcHBlbmROb2RlKHcwLCB3MSwgdzIsIHczKTsKLS8vICAgICAgICAgICAgICBwcmV2aW91c1NpYmxpbmcgPSBvdXJzbG90OyAgICAgIC8vIFNob3VsZCBhdHRyaWJ1dGVzIGJlIHByZXZpb3VzIHNpYmxpbmdzCi0KLS8vICAgICAgICAgICAgICAvLyBXMDogTm9kZSBUeXBlCi0vLyAgICAgICAgICAgICAgdzAgPSBURVhUX05PREU7Ci0vLyAgICAgICAgICAgICAgLy8gVzE6IFBhcmVudAotLy8gICAgICAgICAgICAgIHcxID0gb3Vyc2xvdDsKLS8vICAgICAgICAgICAgICAvLyBXMjogU3RhcnQgUG9zaXRpb24gd2l0aGluIGJ1ZmZlcgotLy8gICAgICAgICAgICAgIHcyID0gbV9jaGFyLmxlbmd0aCgpOwotLy8gICAgICAgICAgICAgIG1fY2hhci5hcHBlbmQodmFsdWUpOwotLy8gICAgICAgICAgICAgIC8vIFczOiBMZW5ndGgKLS8vICAgICAgICAgICAgICB3MyA9IG1fY2hhci5sZW5ndGgoKSAtIHcyOwotLy8gICAgICAgICAgICAgIGFwcGVuZE5vZGUodzAsIHcxLCB3MiwgdzMpOwotLy8gICAgICAgICAgICAgIGNoYXJTdHJpbmdTdGFydD1tX2NoYXIubGVuZ3RoKCk7Ci0vLyAgICAgICAgICAgICAgY2hhclN0cmluZ0xlbmd0aCA9IDA7Ci0vLyAgICAgICAgICAgICAgLy9wcmV2aW91c1NpYmxpbmcgPSBvdXJzbG90OwotLy8gICAgICAgICAgICAgIC8vIEF0dHJzIGFyZSBQYXJlbnRzCi0vLyAgICAgICAgICAgICAgcHJldmlvdXNTaWJsaW5nV2FzUGFyZW50ID0gdHJ1ZTsKLS8vICAgICAgICAgICAgICByZXR1cm4gKG1fZG9jSGFuZGxlIHwgb3Vyc2xvdCk7Ci0vLyAgICAgIH0KLQotLy8gICAgICAvKioKLS8vICAgICAgICogRmFjdG9yeSBtZXRob2Q7IGNyZWF0ZXMgYSBUZXh0IG5vZGUgaW4gdGhpcyBkb2N1bWVudC4KLS8vICAgICAgICoKLS8vICAgICAgICogVGhlIG5vZGUgY3JlYXRlZCB3aWxsIGJlIGNoYWluZWQgYWNjb3JkaW5nIHRvIGl0cyBuYXR1cmFsIG9yZGVyIG9mIHJlcXVlc3QKLS8vICAgICAgICogcmVjZWl2ZWQuICAlVEJEJSBJdCBjYW4gYmUgcmVjaGFpbmVkIGxhdGVyIHZpYSB0aGUgb3B0aW9uYWwgRFRNIHdyaXRhYmxlIGludGVyZmFjZS4KLS8vICAgICAgICoKLS8vICAgICAgICogQHBhcmFtIHRleHQgU3RyaW5nIFRoZSBjaGFyYWN0ZXJzIHRleHQgc3RyaW5nIGZyb20gdGhlIFhNTCBkb2N1bWVudC4KLS8vICAgICAgICogQHJldHVybiBpbnQgRFRNIG5vZGUtbnVtYmVyIG9mIHRoZSB0ZXh0IG5vZGUgY3JlYXRlZAotLy8gICAgICAgKi8KLS8vICAgICAgcHVibGljIGludCBjcmVhdGVUZXh0Tm9kZShTdHJpbmcgdGV4dCkKLS8vICAgICAgdGhyb3dzIERUTUV4Y2VwdGlvbgotLy8gICAgICB7Ci0vLyAgICAgICAgICAgICAgLy8gd3JhcHMgYXJvdW5kIHRoZSBpbmRleCB2YWx1ZSBiYXNlZCBjcmVhdGVUZXh0Tm9kZSBtZXRob2QKLS8vICAgICAgICAgICAgICByZXR1cm4gY3JlYXRlVGV4dE5vZGUodGV4dC50b0NoYXJBcnJheSgpLCAwLCB0ZXh0Lmxlbmd0aCgpKTsKLS8vICAgICAgfQotCi0vLyAgICAgIC8qKgotLy8gICAgICAgKiBGYWN0b3J5IG1ldGhvZDsgY3JlYXRlcyBhIFRleHQgbm9kZSBpbiB0aGlzIGRvY3VtZW50LgotLy8gICAgICAgKgotLy8gICAgICAgKiBUaGUgbm9kZSBjcmVhdGVkIHdpbGwgYmUgY2hhaW5lZCBhY2NvcmRpbmcgdG8gaXRzIG5hdHVyYWwgb3JkZXIgb2YgcmVxdWVzdAotLy8gICAgICAgKiByZWNlaXZlZC4gICVUQkQlIEl0IGNhbiBiZSByZWNoYWluZWQgbGF0ZXIgdmlhIHRoZSBvcHRpb25hbCBEVE0gd3JpdGFibGUgaW50ZXJmYWNlLgotLy8gICAgICAgKgotLy8gICAgICAgKiAlUkVWSUVXJSBmb3IgdGV4dCBub3JtYWxpemF0aW9uIGlzc3VlcywgdW5sZXNzIHdlIGFyZSB3aWxsaW5nIHRvCi0vLyAgICAgICAqIGluc2lzdCB0aGF0IGFsbCBhZGphY2VudCB0ZXh0IG11c3QgYmUgbWVyZ2VkIGJlZm9yZSB0aGlzIG1ldGhvZAotLy8gICAgICAgKiBpcyBjYWxsZWQuCi0vLyAgICAgICAqCi0vLyAgICAgICAqIEBwYXJhbSBjaCBUaGUgY2hhcmFjdGVycyBmcm9tIHRoZSBYTUwgZG9jdW1lbnQuCi0vLyAgICAgICAqIEBwYXJhbSBzdGFydCBUaGUgc3RhcnQgcG9zaXRpb24gaW4gdGhlIGFycmF5LgotLy8gICAgICAgKiBAcGFyYW0gbGVuZ3RoIFRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyB0byByZWFkIGZyb20gdGhlIGFycmF5LgotLy8gICAgICAgKi8KLS8vICAgICAgcHVibGljIGludCBjcmVhdGVUZXh0Tm9kZShjaGFyIGNoW10sIGludCBzdGFydCwgaW50IGxlbmd0aCkKLS8vICAgICAgdGhyb3dzIERUTUV4Y2VwdGlvbgotLy8gICAgICB7Ci0vLyAgICAgICAgICAgICAgbV9jaGFyLmFwcGVuZChjaCwgc3RhcnQsIGxlbmd0aCk7ICAgICAgICAgICAgICAgLy8gc3RvcmUgdGhlIGNodW5rIHRvIHRoZSB0ZXh0L2NvbW1lbnQgc3RyaW5nIHRhYmxlCi0KLS8vICAgICAgICAgICAgICAvLyBjcmVhdGUgYSBUZXh0IE5vZGUKLS8vICAgICAgICAgICAgICAvLyAlVEJEJSBtYXkgYmUgcG9zc2libGUgdG8gY29tYmluZSB3aXRoIGFwcGVuZE5vZGUoKXRvIHJlcGxhY2UgdGhlIG5leHQgY2h1bmsgb2YgY29kZQotLy8gICAgICAgICAgICAgIGludCB3MCA9IFRFWFRfTk9ERTsKLS8vICAgICAgICAgICAgICAvLyBXMTogUGFyZW50Ci0vLyAgICAgICAgICAgICAgaW50IHcxID0gY3VycmVudFBhcmVudDsKLS8vICAgICAgICAgICAgICAvLyBXMjogU3RhcnQgcG9zaXRpb24gd2l0aGluIG1fY2hhcgotLy8gICAgICAgICAgICAgIGludCB3MiA9IGNoYXJTdHJpbmdTdGFydDsKLS8vICAgICAgICAgICAgICAvLyBXMzogTGVuZ3RoIG9mIHRoZSBmdWxsIHN0cmluZwotLy8gICAgICAgICAgICAgIGludCB3MyA9IGxlbmd0aDsKLS8vICAgICAgICAgICAgICBpbnQgb3Vyc2xvdCA9IGFwcGVuZE5vZGUodzAsIHcxLCB3MiwgdzMpOwotLy8gICAgICAgICAgICAgIHByZXZpb3VzU2libGluZyA9IG91cnNsb3Q7Ci0KLS8vICAgICAgICAgICAgICBjaGFyU3RyaW5nU3RhcnQ9bV9jaGFyLmxlbmd0aCgpOwotLy8gICAgICAgICAgICAgIGNoYXJTdHJpbmdMZW5ndGggPSAwOwotLy8gICAgICAgICAgICAgIHJldHVybiAobV9kb2NIYW5kbGUgfCBvdXJzbG90KTsKLS8vICAgICAgfQotCi0vLyAgICAgIC8qKgotLy8gICAgICAgKiBGYWN0b3J5IG1ldGhvZDsgY3JlYXRlcyBhIENvbW1lbnQgbm9kZSBpbiB0aGlzIGRvY3VtZW50LgotLy8gICAgICAgKgotLy8gICAgICAgKiBUaGUgbm9kZSBjcmVhdGVkIHdpbGwgYmUgY2hhaW5lZCBhY2NvcmRpbmcgdG8gaXRzIG5hdHVyYWwgb3JkZXIgb2YgcmVxdWVzdAotLy8gICAgICAgKiByZWNlaXZlZC4gICVUQkQlIEl0IGNhbiBiZSByZWNoYWluZWQgbGF0ZXIgdmlhIHRoZSBvcHRpb25hbCBEVE0gd3JpdGFibGUgaW50ZXJmYWNlLgotLy8gICAgICAgKgotLy8gICAgICAgKiBAcGFyYW0gdGV4dCBTdHJpbmcgVGhlIGNoYXJhY3RlcnMgdGV4dCBzdHJpbmcgZnJvbSB0aGUgWE1MIGRvY3VtZW50LgotLy8gICAgICAgKiBAcmV0dXJuIGludCBEVE0gbm9kZS1udW1iZXIgb2YgdGhlIHRleHQgbm9kZSBjcmVhdGVkCi0vLyAgICAgICAqLwotLy8gICAgICBwdWJsaWMgaW50IGNyZWF0ZUNvbW1lbnQoU3RyaW5nIHRleHQpCi0vLyAgICAgIHRocm93cyBEVE1FeGNlcHRpb24KLS8vICAgICAgewotLy8gICAgICAgICAgICAgIC8vIHdyYXBzIGFyb3VuZCB0aGUgaW5kZXggdmFsdWUgYmFzZWQgY3JlYXRlVGV4dE5vZGUgbWV0aG9kCi0vLyAgICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUNvbW1lbnQodGV4dC50b0NoYXJBcnJheSgpLCAwLCB0ZXh0Lmxlbmd0aCgpKTsKLS8vICAgICAgfQotCi0vLyAgICAgIC8qKgotLy8gICAgICAgKiBGYWN0b3J5IG1ldGhvZDsgY3JlYXRlcyBhIENvbW1lbnQgbm9kZSBpbiB0aGlzIGRvY3VtZW50LgotLy8gICAgICAgKgotLy8gICAgICAgKiBUaGUgbm9kZSBjcmVhdGVkIHdpbGwgYmUgY2hhaW5lZCBhY2NvcmRpbmcgdG8gaXRzIG5hdHVyYWwgb3JkZXIgb2YgcmVxdWVzdAotLy8gICAgICAgKiByZWNlaXZlZC4gICVUQkQlIEl0IGNhbiBiZSByZWNoYWluZWQgbGF0ZXIgdmlhIHRoZSBvcHRpb25hbCBEVE0gd3JpdGFibGUgaW50ZXJmYWNlLgotLy8gICAgICAgKgotLy8gICAgICAgKiBAcGFyYW0gY2ggQW4gYXJyYXkgaG9sZGluZyB0aGUgY2hhcmFjdGVycyBpbiB0aGUgY29tbWVudC4KLS8vICAgICAgICogQHBhcmFtIHN0YXJ0IFRoZSBzdGFydGluZyBwb3NpdGlvbiBpbiB0aGUgYXJyYXkuCi0vLyAgICAgICAqIEBwYXJhbSBsZW5ndGggVGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHVzZSBmcm9tIHRoZSBhcnJheS4KLS8vICAgICAgICogQHNlZSBEVE1FeGNlcHRpb24KLS8vICAgICAgICovCi0vLyAgICAgIHB1YmxpYyBpbnQgY3JlYXRlQ29tbWVudChjaGFyIGNoW10sIGludCBzdGFydCwgaW50IGxlbmd0aCkKLS8vICAgICAgdGhyb3dzIERUTUV4Y2VwdGlvbgotLy8gICAgICB7Ci0vLyAgICAgICAgICAgICAgbV9jaGFyLmFwcGVuZChjaCwgc3RhcnQsIGxlbmd0aCk7ICAgICAgICAgICAgICAgLy8gc3RvcmUgdGhlIGNvbW1lbnQgc3RyaW5nIHRvIHRoZSB0ZXh0L2NvbW1lbnQgc3RyaW5nIHRhYmxlCi0KLS8vICAgICAgICAgICAgICAvLyBjcmVhdGUgYSBDb21tZW50IE5vZGUKLS8vICAgICAgICAgICAgICAvLyAlVEJEJSBtYXkgYmUgcG9zc2libGUgdG8gY29tYmluZSB3aXRoIGFwcGVuZE5vZGUoKXRvIHJlcGxhY2UgdGhlIG5leHQgY2h1bmsgb2YgY29kZQotLy8gICAgICAgICAgICAgIGludCB3MCA9IENPTU1FTlRfTk9ERTsKLS8vICAgICAgICAgICAgICAvLyBXMTogUGFyZW50Ci0vLyAgICAgICAgICAgICAgaW50IHcxID0gY3VycmVudFBhcmVudDsKLS8vICAgICAgICAgICAgICAvLyBXMjogU3RhcnQgcG9zaXRpb24gd2l0aGluIG1fY2hhcgotLy8gICAgICAgICAgICAgIGludCB3MiA9IGNoYXJTdHJpbmdTdGFydDsKLS8vICAgICAgICAgICAgICAvLyBXMzogTGVuZ3RoIG9mIHRoZSBmdWxsIHN0cmluZwotLy8gICAgICAgICAgICAgIGludCB3MyA9IGxlbmd0aDsKLS8vICAgICAgICAgICAgICBpbnQgb3Vyc2xvdCA9IGFwcGVuZE5vZGUodzAsIHcxLCB3MiwgdzMpOwotLy8gICAgICAgICAgICAgIHByZXZpb3VzU2libGluZyA9IG91cnNsb3Q7Ci0KLS8vICAgICAgICAgICAgICBjaGFyU3RyaW5nU3RhcnQ9bV9jaGFyLmxlbmd0aCgpOwotLy8gICAgICAgICAgICAgIGNoYXJTdHJpbmdMZW5ndGggPSAwOwotLy8gICAgICAgICAgICAgIHJldHVybiAobV9kb2NIYW5kbGUgfCBvdXJzbG90KTsKLS8vICAgICAgfQotCi0vLyAgICAgIC8vIENvdW50ZXJzIHRvIGtlZXAgdHJhY2sgb2YgdGhlIGN1cnJlbnQgdGV4dCBzdHJpbmcgYmVpbmcgYWNjdW11bGF0ZWQgd2l0aCByZXNwZWN0Ci0vLyAgICAgIC8vIHRvIHRoZSB0ZXh0L2NvbW1lbnQgc3RyaW5nIHRhYmxlOiBjaGFyU3RyaW5nU3RhcnQgc2hvdWxkIHBvaW50IHRvIHRoZSBzdGFydGluZwotLy8gICAgICAvLyBvZmZzZXQgb2YgdGhlIHN0cmluZyBpbiB0aGUgdGFibGUgYW5kIGNoYXJTdHJpbmdMZW5ndGggdGhlIGFjY2N1bXVsYXRlZCBsZW5ndGggd2hlbgotLy8gICAgICAvLyBhcHBlbmRBY2N1bXVsYXRlZFRleHQgc3RhcnRzLCBhbmQgcmVzZXQgdG8gdGhlIGVuZCBvZiB0aGUgdGFibGUgYW5kIDAgYXQgdGhlIGVuZAotLy8gICAgICAvLyBvZiBhcHBlbmRBY2N1bXVsYXRlZFRleHQgZm9yIHRoZSBuZXh0IHNldCBvZiBjaGFyYWN0ZXJzIHJlY2VpdmVzCi0vLyAgICAgIGludCBjaGFyU3RyaW5nU3RhcnQ9MCxjaGFyU3RyaW5nTGVuZ3RoPTA7Ci0KLSAgICAgICAgLy8gPT09PT09PT09IERvY3VtZW50IE5hdmlnYXRpb24gRnVuY3Rpb25zID09PT09PT09PQotCi0gICAgICAgIC8qKiBHaXZlbiBhIG5vZGUgaGFuZGxlLCB0ZXN0IGlmIGl0IGhhcyBjaGlsZCBub2Rlcy4KLSAgICAgICAgICogPHA+ICVSRVZJRVclIFRoaXMgaXMgb2J2aW91c2x5IHVzZWZ1bCBhdCB0aGUgRE9NIGxheWVyLCB3aGVyZSBpdAotICAgICAgICAgKiB3b3VsZCBwZXJtaXQgdGVzdGluZyB0aGlzIHdpdGhvdXQgaGF2aW5nIHRvIGNyZWF0ZSBhIHByb3h5Ci0gICAgICAgICAqIG5vZGUuIEl0J3MgbGVzcyB1c2VmdWwgaW4gdGhlIERUTSBBUEksIHdoZXJlCi0gICAgICAgICAqIChkdG0uZ2V0Rmlyc3RDaGlsZChub2RlSGFuZGxlKSE9RFRNLk5VTEwpIGlzIGp1c3QgYXMgZmFzdCBhbmQKLSAgICAgICAgICogYWxtb3N0IGFzIHNlbGYtZXZpZGVudC4gQnV0IGl0J3MgYSBjb252ZW5pZW5jZSwgYW5kIGVhc2VzIHBvcnRpbmcKLSAgICAgICAgICogb2YgRE9NIGNvZGUgdG8gRFRNLiAgPC9wPgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBpbnQgSGFuZGxlIG9mIHRoZSBub2RlLgotICAgICAgICAgKiBAcmV0dXJuIGludCB0cnVlIGlmIHRoZSBnaXZlbiBub2RlIGhhcyBjaGlsZCBub2Rlcy4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBib29sZWFuIGhhc0NoaWxkTm9kZXMoaW50IG5vZGVIYW5kbGUpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4oZ2V0Rmlyc3RDaGlsZChub2RlSGFuZGxlKSAhPSBOVUxMKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBHaXZlbiBhIG5vZGUgaGFuZGxlLCBnZXQgdGhlIGhhbmRsZSBvZiB0aGUgbm9kZSdzIGZpcnN0IGNoaWxkLgotICAgICAgICAgKiBJZiBub3QgeWV0IHJlc29sdmVkLCB3YWl0cyBmb3IgbW9yZSBub2RlcyB0byBiZSBhZGRlZCB0byB0aGUgZG9jdW1lbnQgYW5kCi0gICAgICAgICAqIHRyaWVzIGFnYWluLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBpbnQgSGFuZGxlIG9mIHRoZSBub2RlLgotICAgICAgICAgKiBAcmV0dXJuIGludCBEVE0gbm9kZS1udW1iZXIgb2YgZmlyc3QgY2hpbGQsIG9yIERUTS5OVUxMIHRvIGluZGljYXRlIG5vbmUgZXhpc3RzLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIGludCBnZXRGaXJzdENoaWxkKGludCBub2RlSGFuZGxlKSB7Ci0KLSAgICAgICAgICAgICAgICAvLyAjIyNzaHMgd29ycnkgYWJvdXQgdHJhY2luZy9kZWJ1ZyBsYXRlcgotICAgICAgICAgICAgICAgIG5vZGVIYW5kbGUgJj0gTk9ERUhBTkRMRV9NQVNLOwotICAgICAgICAgICAgICAgIC8vIFJlYWQgbm9kZSBpbnRvIHZhcmlhYmxlCi0gICAgICAgICAgICAgICAgbm9kZXMucmVhZFNsb3Qobm9kZUhhbmRsZSwgZ290c2xvdCk7Ci0KLSAgICAgICAgICAgICAgICAvLyB0eXBlIGlzIHRoZSBsYXN0IGhhbGYgb2YgZmlyc3Qgc2xvdAotICAgICAgICAgICAgICAgIHNob3J0IHR5cGUgPSAoc2hvcnQpIChnb3RzbG90WzBdICYgMHhGRkZGKTsKLQotICAgICAgICAgICAgICAgIC8vIENoZWNrIHRvIHNlZSBpZiBFbGVtZW50IG9yIERvY3VtZW50IG5vZGUKLSAgICAgICAgICAgICAgICBpZiAoKHR5cGUgPT0gRUxFTUVOVF9OT0RFKSB8fCAodHlwZSA9PSBET0NVTUVOVF9OT0RFKSB8fAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodHlwZSA9PSBFTlRJVFlfUkVGRVJFTkNFX05PREUpKSB7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIEluIGNhc2Ugd2hlbiBEb2N1bWVudCByb290IGlzIGdpdmVuCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyAgICAgIGlmIChub2RlSGFuZGxlID09IDApIG5vZGVIYW5kbGUgPSAxOwotICAgICAgICAgICAgICAgICAgICAgICAgLy8gJVRCRCUgUHJvYmFibHkgd2FzIGEgbWlzdGFrZS4KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIElmIHNvbWVvbmUgZXhwbGljaXRseSBhc2tzIGZvciBmaXJzdCBjaGlsZAotICAgICAgICAgICAgICAgICAgICAgICAgLy8gb2YgRG9jdW1lbnQsIEkgd291bGQgZXhwZWN0IHRoZW0gdG8gd2FudAotICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhhdCBhbmQgb25seSB0aGF0LgotCi0gICAgICAgICAgICAgICAgICAgICAgICBpbnQga2lkID0gbm9kZUhhbmRsZSArIDE7Ci0gICAgICAgICAgICAgICAgICAgICAgICBub2Rlcy5yZWFkU2xvdChraWQsIGdvdHNsb3QpOwotICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKEFUVFJJQlVURV9OT0RFID09IChnb3RzbG90WzBdICYgMHhGRkZGKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBwb2ludHMgdG8gbmV4dCBzaWJsaW5nCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtpZCA9IGdvdHNsb3RbMl07Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJldHVybiBOVUxMIGlmIG5vZGUgaGFzIG9ubHkgYXR0cmlidXRlcwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoa2lkID09IE5VTEwpIHJldHVybiBOVUxMOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2Rlcy5yZWFkU2xvdChraWQsIGdvdHNsb3QpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gSWYgcGFyZW50IHNsb3QgbWF0Y2hlcyBnaXZlbiBwYXJlbnQsIHJldHVybiBraWQKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChnb3RzbG90WzFdID09IG5vZGVIYW5kbGUpCi0gICAgICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgIGludCBmaXJzdENoaWxkID0ga2lkIHwgbV9kb2NIYW5kbGU7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZpcnN0Q2hpbGQ7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIC8vIE5vIGNoaWxkIGZvdW5kCi0KLSAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIGFkdmFuY2UgdG8gaXRzIGxhc3QgY2hpbGQuCi0gICAgICAgICogSWYgbm90IHlldCByZXNvbHZlZCwgd2FpdHMgZm9yIG1vcmUgbm9kZXMgdG8gYmUgYWRkZWQgdG8gdGhlIGRvY3VtZW50IGFuZAotICAgICAgICAqIHRyaWVzIGFnYWluLgotICAgICAgICAqCi0gICAgICAgICogQHBhcmFtIG5vZGVIYW5kbGUgaW50IEhhbmRsZSBvZiB0aGUgbm9kZS4KLSAgICAgICAgKiBAcmV0dXJuIGludCBOb2RlLW51bWJlciBvZiBsYXN0IGNoaWxkLAotICAgICAgICAqIG9yIERUTS5OVUxMIHRvIGluZGljYXRlIG5vbmUgZXhpc3RzLgotICAgICAgICAqLwotICAgICAgICBwdWJsaWMgaW50IGdldExhc3RDaGlsZChpbnQgbm9kZUhhbmRsZSkgewotICAgICAgICAgICAgICAgIC8vICMjI3NocyBwdXQgdHJhY2UvZGVidWcgbGF0ZXIKLSAgICAgICAgICAgICAgICBub2RlSGFuZGxlICY9IE5PREVIQU5ETEVfTUFTSzsKLSAgICAgICAgICAgICAgICAvLyBkbyBub3QgbmVlZCB0byB0ZXN0IG5vZGUgdHlwZSBzaW5jZSBnZXRGaXJzdENoaWxkIGRvZXMgdGhhdAotICAgICAgICAgICAgICAgIGludCBsYXN0Q2hpbGQgPSBOVUxMOwotICAgICAgICAgICAgICAgIGZvciAoaW50IG5leHRraWQgPSBnZXRGaXJzdENoaWxkKG5vZGVIYW5kbGUpOyBuZXh0a2lkICE9IE5VTEw7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5leHRraWQgPSBnZXROZXh0U2libGluZyhuZXh0a2lkKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgbGFzdENoaWxkID0gbmV4dGtpZDsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGxhc3RDaGlsZCB8IG1fZG9jSGFuZGxlOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFJldHJpZXZlcyBhbiBhdHRyaWJ1dGUgbm9kZSBieSBieSBxdWFsaWZpZWQgbmFtZSBhbmQgbmFtZXNwYWNlIFVSSS4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIG5vZGVIYW5kbGUgaW50IEhhbmRsZSBvZiB0aGUgbm9kZSB1cG9uIHdoaWNoIHRvIGxvb2sgdXAgdGhpcyBhdHRyaWJ1dGUuCi0gICAgICAgICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkgVGhlIG5hbWVzcGFjZSBVUkkgb2YgdGhlIGF0dHJpYnV0ZSB0bwotICAgICAgICAgKiAgIHJldHJpZXZlLCBvciBudWxsLgotICAgICAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbG9jYWwgbmFtZSBvZiB0aGUgYXR0cmlidXRlIHRvCi0gICAgICAgICAqICAgcmV0cmlldmUuCi0gICAgICAgICAqIEByZXR1cm4gVGhlIGF0dHJpYnV0ZSBub2RlIGhhbmRsZSB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZSAoCi0gICAgICAgICAqICAgPGNvZGU+bm9kZU5hbWU8L2NvZGU+KSBvciA8Y29kZT5EVE0uTlVMTDwvY29kZT4gaWYgdGhlcmUgaXMgbm8gc3VjaAotICAgICAgICAgKiAgIGF0dHJpYnV0ZS4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBpbnQgZ2V0QXR0cmlidXRlTm9kZShpbnQgbm9kZUhhbmRsZSwgU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIG5hbWUpIHsKLSAgICAgICAgICAgICAgICBpbnQgbnNJbmRleCA9IG1fbnNOYW1lcy5zdHJpbmdUb0luZGV4KG5hbWVzcGFjZVVSSSksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lSW5kZXggPSBtX2xvY2FsTmFtZXMuc3RyaW5nVG9JbmRleChuYW1lKTsKLSAgICAgICAgICAgICAgICBub2RlSGFuZGxlICY9IE5PREVIQU5ETEVfTUFTSzsKLSAgICAgICAgICAgICAgICBub2Rlcy5yZWFkU2xvdChub2RlSGFuZGxlLCBnb3RzbG90KTsKLSAgICAgICAgICAgICAgICBzaG9ydCB0eXBlID0gKHNob3J0KSAoZ290c2xvdFswXSAmIDB4RkZGRik7Ci0gICAgICAgICAgICAgICAgLy8gSWYgbm9kZUhhbmRsZSBwb2ludHMgdG8gZWxlbWVudCBuZXh0IHNsb3Qgd291bGQgYmUgZmlyc3QgYXR0cmlidXRlCi0gICAgICAgICAgICAgICAgaWYgKHR5cGUgPT0gRUxFTUVOVF9OT0RFKQotICAgICAgICAgICAgICAgICAgICAgICAgbm9kZUhhbmRsZSsrOwotICAgICAgICAgICAgICAgIC8vIEl0ZXJhdGUgdGhyb3VnaCBBdHRyaWJ1dGUgTm9kZXMKLSAgICAgICAgICAgICAgICB3aGlsZSAodHlwZSA9PSBBVFRSSUJVVEVfTk9ERSkgewotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChuc0luZGV4ID09IChnb3RzbG90WzBdIDw8IDE2KSkgJiYgKGdvdHNsb3RbM10gPT0gbmFtZUluZGV4KSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5vZGVIYW5kbGUgfCBtX2RvY0hhbmRsZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIEdvdG8gbmV4dCBzaWJsaW5nCi0gICAgICAgICAgICAgICAgICAgICAgICBub2RlSGFuZGxlID0gZ290c2xvdFsyXTsKLSAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVzLnJlYWRTbG90KG5vZGVIYW5kbGUsIGdvdHNsb3QpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBHaXZlbiBhIG5vZGUgaGFuZGxlLCBnZXQgdGhlIGluZGV4IG9mIHRoZSBub2RlJ3MgZmlyc3QgYXR0cmlidXRlLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBpbnQgSGFuZGxlIG9mIHRoZSBFbGVtZW50IG5vZGUuCi0gICAgICAgICAqIEByZXR1cm4gSGFuZGxlIG9mIGZpcnN0IGF0dHJpYnV0ZSwgb3IgRFRNLk5VTEwgdG8gaW5kaWNhdGUgbm9uZSBleGlzdHMuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgaW50IGdldEZpcnN0QXR0cmlidXRlKGludCBub2RlSGFuZGxlKSB7Ci0gICAgICAgICAgICAgICAgbm9kZUhhbmRsZSAmPSBOT0RFSEFORExFX01BU0s7Ci0KLSAgICAgICAgICAgICAgICAvLyAlUkVWSUVXJSBqams6IEp1c3QgYSBxdWljayBvYnNlcnZhdGlvbjogSWYgeW91J3JlIGdvaW5nIHRvCi0gICAgICAgICAgICAgICAgLy8gY2FsbCByZWFkRW50cnkgcmVwZWF0ZWRseSBvbiB0aGUgc2FtZSBub2RlLCBpdCBtYXkgYmUKLSAgICAgICAgICAgICAgICAvLyBtb3JlIGVmZmljaWVudGx5IHRvIGRvIGEgcmVhZFNsb3QgdG8gZ2V0IHRoZSBkYXRhIGxvY2FsbHksCi0gICAgICAgICAgICAgICAgLy8gcmVkdWNpbmcgdGhlIGFkZHJlc3NpbmcgYW5kIGNhbGwtYW5kLXJldHVybiBvdmVyaGVhZC4KLQotICAgICAgICAgICAgICAgIC8vIFNob3VsZCB3ZSBjaGVjayBpZiBoYW5kbGUgaXMgZWxlbWVudCAoZG8gd2Ugd2FudCBzYW5pdHkgY2hlY2tzPykKLSAgICAgICAgICAgICAgICBpZiAoRUxFTUVOVF9OT0RFICE9IChub2Rlcy5yZWFkRW50cnkobm9kZUhhbmRsZSwgMCkgJiAweEZGRkYpKQotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7Ci0gICAgICAgICAgICAgICAgLy8gRmlyc3QgQXR0cmlidXRlIChpZiBhbnkpIHNob3VsZCBiZSBhdCBuZXh0IHBvc2l0aW9uIGluIHRhYmxlCi0gICAgICAgICAgICAgICAgbm9kZUhhbmRsZSsrOwotICAgICAgICAgICAgICAgIHJldHVybihBVFRSSUJVVEVfTk9ERSA9PSAobm9kZXMucmVhZEVudHJ5KG5vZGVIYW5kbGUsIDApICYgMHhGRkZGKSkgPwotICAgICAgICAgICAgICAgIG5vZGVIYW5kbGUgfCBtX2RvY0hhbmRsZSA6IE5VTEw7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogR2l2ZW4gYSBub2RlIGhhbmRsZSwgZ2V0IHRoZSBpbmRleCBvZiB0aGUgbm9kZSdzIGZpcnN0IGNoaWxkLgotICAgICAgICAgKiBJZiBub3QgeWV0IHJlc29sdmVkLCB3YWl0cyBmb3IgbW9yZSBub2RlcyB0byBiZSBhZGRlZCB0byB0aGUgZG9jdW1lbnQgYW5kCi0gICAgICAgICAqIHRyaWVzIGFnYWluCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBub2RlSGFuZGxlIGhhbmRsZSB0byBub2RlLCB3aGljaCBzaG91bGQgcHJvYmFibHkgYmUgYW4gZWxlbWVudAotICAgICAgICAgKiAgICAgICAgICAgICAgICAgICBub2RlLCBidXQgbmVlZCBub3QgYmUuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBpblNjb3BlICAgIHRydWUgaWYgYWxsIG5hbWVzcGFjZXMgaW4gc2NvcGUgc2hvdWxkIGJlIHJldHVybmVkLAotICAgICAgICAgKiAgICAgICAgICAgICAgICAgICBmYWxzZSBpZiBvbmx5IHRoZSBuYW1lc3BhY2UgZGVjbGFyYXRpb25zIHNob3VsZCBiZQotICAgICAgICAgKiAgICAgICAgICAgICAgICAgICByZXR1cm5lZC4KLSAgICAgICAgICogQHJldHVybiBoYW5kbGUgb2YgZmlyc3QgbmFtZXNwYWNlLCBvciBEVE0uTlVMTCB0byBpbmRpY2F0ZSBub25lIGV4aXN0cy4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBpbnQgZ2V0Rmlyc3ROYW1lc3BhY2VOb2RlKGludCBub2RlSGFuZGxlLCBib29sZWFuIGluU2NvcGUpIHsKLQotICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIGFkdmFuY2UgdG8gaXRzIG5leHQgc2libGluZy4KLSAgICAgICAgICoKLSAgICAgICAgICogJVRCRCUgVGhpcyBjdXJyZW50bHkgdXNlcyB0aGUgRFRNLWludGVybmFsIGRlZmluaXRpb24gb2YKLSAgICAgICAgICogc2libGluZzsgZWcsIHRoZSBsYXN0IGF0dHIncyBuZXh0IHNpYiBpcyB0aGUgZmlyc3QKLSAgICAgICAgICogY2hpbGQuIEluIHRoZSBvbGQgRFRNLCB0aGUgRE9NIHByb3h5IGxheWVyIHByb3ZpZGVkIHRoZQotICAgICAgICAgKiBhZGRpdGlvbmFsIGxvZ2ljIGZvciB0aGUgcHVibGljIHZpZXcuICBJZiB3ZSdyZSByZXdyaXRpbmcKLSAgICAgICAgICogZm9yIFhQYXRoIGVtdWxhdGlvbiwgdGhhdCB0ZXN0IG11c3QgYmUgZG9uZSBoZXJlLgotICAgICAgICAgKgotICAgICAgICAgKiAlVEJEJSBDT0RFIElOVEVSQUNUSU9OIFdJVEggSU5DUkVNRU5UQUwgUEFSU0UgLSBJZiBub3QgeWV0Ci0gICAgICAgICAqIHJlc29sdmVkLCBzaG91bGQgd2FpdCBmb3IgbW9yZSBub2RlcyB0byBiZSBhZGRlZCB0byB0aGUgZG9jdW1lbnQKLSAgICAgICAgICogYW5kIHRyaWVzIGFnYWluLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBpbnQgSGFuZGxlIG9mIHRoZSBub2RlLgotICAgICAgICAgKiBAcmV0dXJuIGludCBOb2RlLW51bWJlciBvZiBuZXh0IHNpYmxpbmcsCi0gICAgICAgICAqIG9yIERUTS5OVUxMIHRvIGluZGljYXRlIG5vbmUgZXhpc3RzLgotICAgICAgICAgKiAqLwotICAgICAgICBwdWJsaWMgaW50IGdldE5leHRTaWJsaW5nKGludCBub2RlSGFuZGxlKSB7Ci0gICAgICAgICAgICAgICAgbm9kZUhhbmRsZSAmPSBOT0RFSEFORExFX01BU0s7Ci0gICAgICAgICAgICAgICAgLy8gRG9jdW1lbnQgcm9vdCBoYXMgbm8gbmV4dCBzaWJsaW5nCi0gICAgICAgICAgICAgICAgaWYgKG5vZGVIYW5kbGUgPT0gMCkKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOwotCi0gICAgICAgICAgICAgICAgc2hvcnQgdHlwZSA9IChzaG9ydCkgKG5vZGVzLnJlYWRFbnRyeShub2RlSGFuZGxlLCAwKSAmIDB4RkZGRik7Ci0gICAgICAgICAgICAgICAgaWYgKCh0eXBlID09IEVMRU1FTlRfTk9ERSkgfHwgKHR5cGUgPT0gQVRUUklCVVRFX05PREUpIHx8Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh0eXBlID09IEVOVElUWV9SRUZFUkVOQ0VfTk9ERSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGludCBuZXh0U2liID0gbm9kZXMucmVhZEVudHJ5KG5vZGVIYW5kbGUsIDIpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5leHRTaWIgPT0gTlVMTCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAobmV4dFNpYiAhPSAwKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKG1fZG9jSGFuZGxlIHwgbmV4dFNpYik7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyAjIyNzaHMgc2hvdWxkIGN5Y2xlL3dhaXQgaWYgbmV4dFNpYiBpcyAwPyBXb3JraW5nIG9uIHRocmVhZGluZyBuZXh0Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIC8vIE5leHQgU2libGluZyBpcyBpbiB0aGUgbmV4dCBwb3NpdGlvbiBpZiBpdCBzaGFyZXMgdGhlIHNhbWUgcGFyZW50Ci0gICAgICAgICAgICAgICAgaW50IHRoaXNQYXJlbnQgPSBub2Rlcy5yZWFkRW50cnkobm9kZUhhbmRsZSwgMSk7Ci0KLSAgICAgICAgICAgICAgICBpZiAobm9kZXMucmVhZEVudHJ5KCsrbm9kZUhhbmRsZSwgMSkgPT0gdGhpc1BhcmVudCkKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAobV9kb2NIYW5kbGUgfCBub2RlSGFuZGxlKTsKLQotICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIGZpbmQgaXRzIHByZWNlZWRpbmcgc2libGluZy4KLSAgICAgICAgICogV0FSTklORzogRFRNIGlzIGFzeW1tZXRyaWM7IHRoaXMgb3BlcmF0aW9uIGlzIHJlc29sdmVkIGJ5IHNlYXJjaCwgYW5kIGlzCi0gICAgICAgICAqIHJlbGF0aXZlbHkgZXhwZW5zaXZlLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gbm9kZUhhbmRsZSB0aGUgaWQgb2YgdGhlIG5vZGUuCi0gICAgICAgICAqIEByZXR1cm4gaW50IE5vZGUtbnVtYmVyIG9mIHRoZSBwcmV2aW91cyBzaWIsCi0gICAgICAgICAqIG9yIERUTS5OVUxMIHRvIGluZGljYXRlIG5vbmUgZXhpc3RzLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIGludCBnZXRQcmV2aW91c1NpYmxpbmcoaW50IG5vZGVIYW5kbGUpIHsKLSAgICAgICAgICAgICAgICBub2RlSGFuZGxlICY9IE5PREVIQU5ETEVfTUFTSzsKLSAgICAgICAgICAgICAgICAvLyBEb2N1bWVudCByb290IGhhcyBubyBwcmV2aW91cyBzaWJsaW5nCi0gICAgICAgICAgICAgICAgaWYgKG5vZGVIYW5kbGUgPT0gMCkKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOwotCi0gICAgICAgICAgICAgICAgaW50IHBhcmVudCA9IG5vZGVzLnJlYWRFbnRyeShub2RlSGFuZGxlLCAxKTsKLSAgICAgICAgICAgICAgICBpbnQga2lkID0gTlVMTDsKLSAgICAgICAgICAgICAgICBmb3IgKGludCBuZXh0a2lkID0gZ2V0Rmlyc3RDaGlsZChwYXJlbnQpOyBuZXh0a2lkICE9IG5vZGVIYW5kbGU7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5leHRraWQgPSBnZXROZXh0U2libGluZyhuZXh0a2lkKSkgewotICAgICAgICAgICAgICAgICAgICAgICAga2lkID0gbmV4dGtpZDsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGtpZCB8IG1fZG9jSGFuZGxlOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIGFkdmFuY2UgdG8gdGhlIG5leHQgYXR0cmlidXRlLiBJZiBhbgotICAgICAgICAgKiBlbGVtZW50LCB3ZSBhZHZhbmNlIHRvIGl0cyBmaXJzdCBhdHRyaWJ1dGU7IGlmIGFuIGF0dHIsIHdlIGFkdmFuY2UgdG8KLSAgICAgICAgICogdGhlIG5leHQgYXR0ciBvbiB0aGUgc2FtZSBub2RlLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBpbnQgSGFuZGxlIG9mIHRoZSBub2RlLgotICAgICAgICAgKiBAcmV0dXJuIGludCBEVE0gbm9kZS1udW1iZXIgb2YgdGhlIHJlc29sdmVkIGF0dHIsCi0gICAgICAgICAqIG9yIERUTS5OVUxMIHRvIGluZGljYXRlIG5vbmUgZXhpc3RzLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIGludCBnZXROZXh0QXR0cmlidXRlKGludCBub2RlSGFuZGxlKSB7Ci0gICAgICAgICAgICAgICAgbm9kZUhhbmRsZSAmPSBOT0RFSEFORExFX01BU0s7Ci0gICAgICAgICAgICAgICAgbm9kZXMucmVhZFNsb3Qobm9kZUhhbmRsZSwgZ290c2xvdCk7Ci0KLSAgICAgICAgICAgICAgICAvLyVSRVZJRVclIFdoeSBhcmUgd2UgdXNpbmcgc2hvcnQgaGVyZT8gVGhlcmUncyBubyBzdG9yYWdlCi0gICAgICAgICAgICAgICAgLy9yZWR1Y3Rpb24gZm9yIGFuIGF1dG9tYXRpYyB2YXJpYWJsZSwgZXNwZWNpYWxseSBvbmUgdXNlZAotICAgICAgICAgICAgICAgIC8vc28gYnJpZWZseSwgYW5kIGl0IHR5cGljYWxseSBjb3N0cyBtb3JlIGN5Y2xlcyB0byBwcm9jZXNzCi0gICAgICAgICAgICAgICAgLy90aGFuIGFuIGludCB3b3VsZC4KLSAgICAgICAgICAgICAgICBzaG9ydCB0eXBlID0gKHNob3J0KSAoZ290c2xvdFswXSAmIDB4RkZGRik7Ci0KLSAgICAgICAgICAgICAgICBpZiAodHlwZSA9PSBFTEVNRU5UX05PREUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBnZXRGaXJzdEF0dHJpYnV0ZShub2RlSGFuZGxlKTsKLSAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT0gQVRUUklCVVRFX05PREUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChnb3RzbG90WzJdICE9IE5VTEwpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAobV9kb2NIYW5kbGUgfCBnb3RzbG90WzJdKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogR2l2ZW4gYSBuYW1lc3BhY2UgaGFuZGxlLCBhZHZhbmNlIHRvIHRoZSBuZXh0IG5hbWVzcGFjZS4KLSAgICAgICAgICoKLSAgICAgICAgICogJVRCRCUgVEhJUyBNRVRIT0QgRE9FUyBOT1QgTUFUQ0ggVEhFIENVUlJFTlQgU0lHTkFUVVJFIElOCi0gICAgICAgICAqIFRIRSBEVE0gSU5URVJGQUNFLiAgRklYIElULCBPUiBKVVNUSUZZIENIQU5HSU5HIFRIRSBEVE0KLSAgICAgICAgICogQVBJLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gbmFtZXNwYWNlSGFuZGxlIGhhbmRsZSB0byBub2RlIHdoaWNoIG11c3QgYmUgb2YgdHlwZSBOQU1FU1BBQ0VfTk9ERS4KLSAgICAgICAgICogQHJldHVybiBoYW5kbGUgb2YgbmV4dCBuYW1lc3BhY2UsIG9yIERUTS5OVUxMIHRvIGluZGljYXRlIG5vbmUgZXhpc3RzLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIGludCBnZXROZXh0TmFtZXNwYWNlTm9kZShpbnQgYmFzZUhhbmRsZSxpbnQgbmFtZXNwYWNlSGFuZGxlLCBib29sZWFuIGluU2NvcGUpIHsKLSAgICAgICAgICAgICAgICAvLyAjIyNzaHMgbmVlZCB0byB3b3JrIG9uIG5hbWVzcGFjZQotICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIGFkdmFuY2UgdG8gaXRzIG5leHQgZGVzY2VuZGFudC4KLSAgICAgICAgICogSWYgbm90IHlldCByZXNvbHZlZCwgd2FpdHMgZm9yIG1vcmUgbm9kZXMgdG8gYmUgYWRkZWQgdG8gdGhlIGRvY3VtZW50IGFuZAotICAgICAgICAgKiB0cmllcyBhZ2Fpbi4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIHN1YnRyZWVSb290SGFuZGxlCi0gICAgICAgICAqIEBwYXJhbSBub2RlSGFuZGxlIGludCBIYW5kbGUgb2YgdGhlIG5vZGUuCi0gICAgICAgICAqIEByZXR1cm4gaGFuZGxlIG9mIG5leHQgZGVzY2VuZGFudCwKLSAgICAgICAgICogb3IgRFRNLk5VTEwgdG8gaW5kaWNhdGUgbm9uZSBleGlzdHMuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgaW50IGdldE5leHREZXNjZW5kYW50KGludCBzdWJ0cmVlUm9vdEhhbmRsZSwgaW50IG5vZGVIYW5kbGUpIHsKLSAgICAgICAgICAgICAgICBzdWJ0cmVlUm9vdEhhbmRsZSAmPSBOT0RFSEFORExFX01BU0s7Ci0gICAgICAgICAgICAgICAgbm9kZUhhbmRsZSAmPSBOT0RFSEFORExFX01BU0s7Ci0gICAgICAgICAgICAgICAgLy8gRG9jdW1lbnQgcm9vdCBbRG9jdW1lbnQgTm9kZT8gLS0gamprXSAtIG5vIG5leHQtc2liCi0gICAgICAgICAgICAgICAgaWYgKG5vZGVIYW5kbGUgPT0gMCkKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOwotICAgICAgICAgICAgICAgIHdoaWxlICghbV9pc0Vycm9yKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBEb2N1bWVudCBkb25lIGFuZCBub2RlIG91dCBvZiBib3VuZHMKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkb25lICYmIChub2RlSGFuZGxlID4gbm9kZXMuc2xvdHNVc2VkKCkpKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChub2RlSGFuZGxlID4gc3VidHJlZVJvb3RIYW5kbGUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZXMucmVhZFNsb3Qobm9kZUhhbmRsZSsxLCBnb3RzbG90KTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGdvdHNsb3RbMl0gIT0gMCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNob3J0IHR5cGUgPSAoc2hvcnQpIChnb3RzbG90WzBdICYgMHhGRkZGKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZSA9PSBBVFRSSUJVVEVfTk9ERSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZUhhbmRsZSArPTI7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBuZXh0UGFyZW50UG9zID0gZ290c2xvdFsxXTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuZXh0UGFyZW50UG9zID49IHN1YnRyZWVSb290SGFuZGxlKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKG1fZG9jSGFuZGxlIHwgKG5vZGVIYW5kbGUrMSkpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIWRvbmUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBBZGQgd2FpdCBsb2dpYyBoZXJlCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZUhhbmRsZSsrOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvLyBQcm9iYWJseSBzaG91bGQgdGhyb3cgZXJyb3IgaGVyZSBsaWtlIG9yaWdpbmFsIGluc3RlYWQgb2YgcmV0dXJuaW5nCi0gICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogR2l2ZW4gYSBub2RlIGhhbmRsZSwgYWR2YW5jZSB0byB0aGUgbmV4dCBub2RlIG9uIHRoZSBmb2xsb3dpbmcgYXhpcy4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIGF4aXNDb250ZXh0SGFuZGxlIHRoZSBzdGFydCBvZiB0aGUgYXhpcyB0aGF0IGlzIGJlaW5nIHRyYXZlcnNlZC4KLSAgICAgICAgICogQHBhcmFtIG5vZGVIYW5kbGUKLSAgICAgICAgICogQHJldHVybiBoYW5kbGUgb2YgbmV4dCBzaWJsaW5nLAotICAgICAgICAgKiBvciBEVE0uTlVMTCB0byBpbmRpY2F0ZSBub25lIGV4aXN0cy4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBpbnQgZ2V0TmV4dEZvbGxvd2luZyhpbnQgYXhpc0NvbnRleHRIYW5kbGUsIGludCBub2RlSGFuZGxlKSB7Ci0gICAgICAgICAgICAgICAgLy8jIyNzaHMgc3RpbGwgd29ya2luZyBvbgotICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIGFkdmFuY2UgdG8gdGhlIG5leHQgbm9kZSBvbiB0aGUgcHJlY2VkaW5nIGF4aXMuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBheGlzQ29udGV4dEhhbmRsZSB0aGUgc3RhcnQgb2YgdGhlIGF4aXMgdGhhdCBpcyBiZWluZyB0cmF2ZXJzZWQuCi0gICAgICAgICAqIEBwYXJhbSBub2RlSGFuZGxlIHRoZSBpZCBvZiB0aGUgbm9kZS4KLSAgICAgICAgICogQHJldHVybiBpbnQgTm9kZS1udW1iZXIgb2YgcHJlY2VkaW5nIHNpYmxpbmcsCi0gICAgICAgICAqIG9yIERUTS5OVUxMIHRvIGluZGljYXRlIG5vbmUgZXhpc3RzLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIGludCBnZXROZXh0UHJlY2VkaW5nKGludCBheGlzQ29udGV4dEhhbmRsZSwgaW50IG5vZGVIYW5kbGUpIHsKLSAgICAgICAgICAgICAgICAvLyAjIyNzaHMgY29waWVkIGZyb20gWGFsYW4gMSwgd2hhdCBpcyB0aGlzIHN1cHBvc2UgdG8gZG8/Ci0gICAgICAgICAgICAgICAgbm9kZUhhbmRsZSAmPSBOT0RFSEFORExFX01BU0s7Ci0gICAgICAgICAgICAgICAgd2hpbGUgKG5vZGVIYW5kbGUgPiAxKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBub2RlSGFuZGxlLS07Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoQVRUUklCVVRFX05PREUgPT0gKG5vZGVzLnJlYWRFbnRyeShub2RlSGFuZGxlLCAwKSAmIDB4RkZGRikpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBpZiBub2RlSGFuZGxlIGlzIF9ub3RfIGFuIGFuY2VzdG9yIG9mCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBheGlzQ29udGV4dEhhbmRsZSwgc3BlY2lhbEZpbmQgd2lsbCByZXR1cm4gaXQuCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBJZiBpdCBfaXNfIGFuIGFuY2VzdG9yLCBzcGVjaWFsRmluZCB3aWxsIHJldHVybiAtMQotCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyAlUkVWSUVXJSB1bmNvbmRpdGlvbmFsIHJldHVybiBkZWZlYXRzIHRoZQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gcHVycG9zZSBvZiB0aGUgd2hpbGUgbG9vcCAtLSBkb2VzIHRoaXMKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGxvZ2ljIG1ha2UgYW55IHNlbnNlPwotCi0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKG1fZG9jSGFuZGxlIHwgbm9kZXMuc3BlY2lhbEZpbmQoYXhpc0NvbnRleHRIYW5kbGUsIG5vZGVIYW5kbGUpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogR2l2ZW4gYSBub2RlIGhhbmRsZSwgZmluZCBpdHMgcGFyZW50IG5vZGUuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBub2RlSGFuZGxlIHRoZSBpZCBvZiB0aGUgbm9kZS4KLSAgICAgICAgICogQHJldHVybiBpbnQgTm9kZS1udW1iZXIgb2YgcGFyZW50LAotICAgICAgICAgKiBvciBEVE0uTlVMTCB0byBpbmRpY2F0ZSBub25lIGV4aXN0cy4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBpbnQgZ2V0UGFyZW50KGludCBub2RlSGFuZGxlKSB7Ci0gICAgICAgICAgICAgICAgLy8gU2hvdWxkIGNoZWNrIHRvIHNlZSB3aXRoaW4gcmFuZ2U/Ci0KLSAgICAgICAgICAgICAgICAvLyBEb2N1bWVudCBSb290IHNob3VsZCBub3QgaGF2ZSB0byBiZSBoYW5kbGVkIGRpZmZlcmVudGx5Ci0gICAgICAgICAgICAgICAgcmV0dXJuIChtX2RvY0hhbmRsZSB8IG5vZGVzLnJlYWRFbnRyeShub2RlSGFuZGxlLCAxKSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogUmV0dXJucyB0aGUgcm9vdCBlbGVtZW50IG9mIHRoZSBkb2N1bWVudC4KLSAgICAgICAgICogQHJldHVybiBub2RlSGFuZGxlIHRvIHRoZSBEb2N1bWVudCBSb290LgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIGludCBnZXREb2N1bWVudFJvb3QoKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIChtX2RvY0hhbmRsZSB8IG1fZG9jRWxlbWVudCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogR2l2ZW4gYSBub2RlIGhhbmRsZSwgZmluZCB0aGUgb3duaW5nIGRvY3VtZW50IG5vZGUuCi0gICAgICAgICAqCi0gICAgICAgICAqIEByZXR1cm4gaW50IE5vZGUgaGFuZGxlIG9mIGRvY3VtZW50LCB3aGljaCBzaG91bGQgYWx3YXlzIGJlIHZhbGlkLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIGludCBnZXREb2N1bWVudCgpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gbV9kb2NIYW5kbGU7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogR2l2ZW4gYSBub2RlIGhhbmRsZSwgZmluZCB0aGUgb3duaW5nIGRvY3VtZW50IG5vZGUuICBUaGlzIGhhcyB0aGUgZXhhY3QKLSAgICAgICAgICogc2FtZSBzZW1hbnRpY3MgYXMgdGhlIERPTSBEb2N1bWVudCBtZXRob2Qgb2YgdGhlIHNhbWUgbmFtZSwgaW4gdGhhdCBpZgotICAgICAgICAgKiB0aGUgbm9kZUhhbmRsZSBpcyBhIGRvY3VtZW50IG5vZGUsIGl0IHdpbGwgcmV0dXJuIE5VTEwuCi0gICAgICAgICAqCi0gICAgICAgICAqIDxwPiVSRVZJRVclIFNpbmNlIHRoaXMgaXMgRE9NLXNwZWNpZmljLCBpdCBtYXkgYmVsb25nIGF0IHRoZSBET00KLSAgICAgICAgICogYmluZGluZyBsYXllci4gSW5jbHVkZWQgaGVyZSBhcyBhIGNvbnZlbmllbmNlIGZ1bmN0aW9uIGFuZCB0bwotICAgICAgICAgKiBhaWQgcG9ydGluZyBvZiBET00gY29kZSB0byBEVE0uPC9wPgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gbm9kZUhhbmRsZSB0aGUgaWQgb2YgdGhlIG5vZGUuCi0gICAgICAgICAqIEByZXR1cm4gaW50IE5vZGUgaGFuZGxlIG9mIG93bmluZyBkb2N1bWVudCwgb3IgTlVMTCBpZiB0aGUgbm9kZUhhbmRsZSBpcwotICAgICAgICAgKiAgICAgICAgICAgICBhIGRvY3VtZW50LgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIGludCBnZXRPd25lckRvY3VtZW50KGludCBub2RlSGFuZGxlKSB7Ci0gICAgICAgICAgICAgICAgLy8gQXNzdW1wdGlvbiB0aGF0IERvY3VtZW50IE5vZGUgaXMgYWx3YXlzIGluIDAgc2xvdAotICAgICAgICAgICAgICAgIGlmICgobm9kZUhhbmRsZSAmIE5PREVIQU5ETEVfTUFTSykgPT0gMCkKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOwotICAgICAgICAgICAgICAgIHJldHVybiAobm9kZUhhbmRsZSAmIERPQ0hBTkRMRV9NQVNLKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBHaXZlbiBhIG5vZGUgaGFuZGxlLCBmaW5kIHRoZSBvd25pbmcgZG9jdW1lbnQgbm9kZS4gIFRoaXMgaGFzIHRoZSBEVE0KLSAgICAgICAgICogc2VtYW50aWNzOyBhIERvY3VtZW50IG5vZGUgaXMgaXRzIG93biBvd25lci4KLSAgICAgICAgICoKLSAgICAgICAgICogPHA+JVJFVklFVyUgU2luY2UgdGhpcyBpcyBET00tc3BlY2lmaWMsIGl0IG1heSBiZWxvbmcgYXQgdGhlIERPTQotICAgICAgICAgKiBiaW5kaW5nIGxheWVyLiBJbmNsdWRlZCBoZXJlIGFzIGEgY29udmVuaWVuY2UgZnVuY3Rpb24gYW5kIHRvCi0gICAgICAgICAqIGFpZCBwb3J0aW5nIG9mIERPTSBjb2RlIHRvIERUTS48L3A+Ci0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBub2RlSGFuZGxlIHRoZSBpZCBvZiB0aGUgbm9kZS4KLSAgICAgICAgICogQHJldHVybiBpbnQgTm9kZSBoYW5kbGUgb2Ygb3duaW5nIGRvY3VtZW50LCBvciBOVUxMIGlmIHRoZSBub2RlSGFuZGxlIGlzCi0gICAgICAgICAqICAgICAgICAgICAgIGEgZG9jdW1lbnQuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgaW50IGdldERvY3VtZW50Um9vdChpbnQgbm9kZUhhbmRsZSkgewotICAgICAgICAgICAgICAgIC8vIEFzc3VtcHRpb24gdGhhdCBEb2N1bWVudCBOb2RlIGlzIGFsd2F5cyBpbiAwIHNsb3QKLSAgICAgICAgICAgICAgICBpZiAoKG5vZGVIYW5kbGUgJiBOT0RFSEFORExFX01BU0spID09IDApCi0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKLSAgICAgICAgICAgICAgICByZXR1cm4gKG5vZGVIYW5kbGUgJiBET0NIQU5ETEVfTUFTSyk7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogR2V0IHRoZSBzdHJpbmctdmFsdWUgb2YgYSBub2RlIGFzIGEgU3RyaW5nIG9iamVjdAotICAgICAgICAgKiAoc2VlIGh0dHA6Ly93d3cudzMub3JnL1RSL3hwYXRoI2RhdGEtbW9kZWwKLSAgICAgICAgICogZm9yIHRoZSBkZWZpbml0aW9uIG9mIGEgbm9kZSdzIHN0cmluZy12YWx1ZSkuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBub2RlSGFuZGxlIFRoZSBub2RlIElELgotICAgICAgICAgKgotICAgICAgICAgKiBAcmV0dXJuIEEgc3RyaW5nIG9iamVjdCB0aGF0IHJlcHJlc2VudHMgdGhlIHN0cmluZy12YWx1ZSBvZiB0aGUgZ2l2ZW4gbm9kZS4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBYTUxTdHJpbmcgZ2V0U3RyaW5nVmFsdWUoaW50IG5vZGVIYW5kbGUpIHsKLSAgICAgICAgLy8gIyMjemFqIC0gcmVzZWFyY2hpbmcKLSAgICAgICAgbm9kZXMucmVhZFNsb3Qobm9kZUhhbmRsZSwgZ290c2xvdCk7Ci0gICAgICAgIGludCBub2RldHlwZT1nb3RzbG90WzBdICYgMHhGRjsKLSAgICAgICAgU3RyaW5nIHZhbHVlPW51bGw7Ci0KLSAgICAgICAgc3dpdGNoIChub2RldHlwZSkgewotICAgICAgICBjYXNlIFRFWFRfTk9ERToKLSAgICAgICAgY2FzZSBDT01NRU5UX05PREU6Ci0gICAgICAgIGNhc2UgQ0RBVEFfU0VDVElPTl9OT0RFOgotICAgICAgICAgICAgICAgIHZhbHVlPSBtX2NoYXIuZ2V0U3RyaW5nKGdvdHNsb3RbMl0sIGdvdHNsb3RbM10pOwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICBjYXNlIFBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERToKLSAgICAgICAgY2FzZSBBVFRSSUJVVEVfTk9ERToKLSAgICAgICAgY2FzZSBFTEVNRU5UX05PREU6Ci0gICAgICAgIGNhc2UgRU5USVRZX1JFRkVSRU5DRV9OT0RFOgotICAgICAgICBkZWZhdWx0OgotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBtX3hzZi5uZXdzdHIoIHZhbHVlICk7Ci0KLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBHZXQgbnVtYmVyIG9mIGNoYXJhY3RlciBhcnJheSBjaHVua3MgaW4KLSAgICAgICAgICogdGhlIHN0cmluZy12YWx1ZSBvZiBhIG5vZGUuCi0gICAgICAgICAqIChzZWUgaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGgjZGF0YS1tb2RlbAotICAgICAgICAgKiBmb3IgdGhlIGRlZmluaXRpb24gb2YgYSBub2RlJ3Mgc3RyaW5nLXZhbHVlKS4KLSAgICAgICAgICogTm90ZSB0aGF0IGEgc2luZ2xlIHRleHQgbm9kZSBtYXkgaGF2ZSBtdWx0aXBsZSB0ZXh0IGNodW5rcy4KLSAgICAgICAgICoKLSAgICAgICAgICogRVhQTEFOQVRJT046IFRoaXMgbWV0aG9kIGlzIGFuIGFydGlmYWN0IG9mIHRoZSBmYWN0IHRoYXQgdGhlCi0gICAgICAgICAqIHVuZGVybHlpbmcgbV9jaGFycyBvYmplY3QgbWF5IG5vdCBzdG9yZSBjaGFyYWN0ZXJzIGluIGEKLSAgICAgICAgICogc2luZ2xlIGNvbnRpZ3VvdXMgYXJyYXkgLS0gZm9yIGV4YW1wbGUsdGhlIGN1cnJlbnQKLSAgICAgICAgICogRmFzdFN0cmluZ0J1ZmZlciBtYXkgc3BsaXQgYSBzaW5nbGUgbm9kZSdzIHRleHQgYWNyb3NzCi0gICAgICAgICAqIG11bHRpcGxlIGFsbG9jYXRpb24gdW5pdHMuICBUaGlzIGNhbGwgdGVsbHMgdXMgaG93IG1hbnkKLSAgICAgICAgICogc2VwYXJhdGUgYWNjZXNzZXMgd2lsbCBiZSByZXF1aXJlZCB0byByZXRyaWV2ZSB0aGUgZW50aXJlCi0gICAgICAgICAqIGNvbnRlbnQuIFBMRUFTRSBOT1RFIHRoYXQgdGhpcyBtYXkgbm90IGJlIHRoZSBzYW1lIGFzIHRoZQotICAgICAgICAgKiBudW1iZXIgb2YgU0FYIGNoYXJhY3RlcnMoKSBldmVudHMgdGhhdCBjYXVzZWQgdGhlIHRleHQgbm9kZQotICAgICAgICAgKiB0byBiZSBidWlsdCBpbiB0aGUgZmlyc3QgcGxhY2UsIHNpbmNlIG1fY2hhcnMgYnVmZmVyaW5nIG1heQotICAgICAgICAgKiBiZSBvbiBkaWZmZXJlbnQgYm91bmRhcmllcyB0aGFuIHRoZSBwYXJzZXIncyBidWZmZXJzLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBUaGUgbm9kZSBJRC4KLSAgICAgICAgICoKLSAgICAgICAgICogQHJldHVybiBudW1iZXIgb2YgY2hhcmFjdGVyIGFycmF5IGNodW5rcyBpbgotICAgICAgICAgKiAgICAgICAgIHRoZSBzdHJpbmctdmFsdWUgb2YgYSBub2RlLgotICAgICAgICAgKiAqLwotICAgICAgICAvLyMjI3phaiAtIHRiZAotICAgICAgICBwdWJsaWMgaW50IGdldFN0cmluZ1ZhbHVlQ2h1bmtDb3VudChpbnQgbm9kZUhhbmRsZSkKLSAgICAgICAgewotICAgICAgICAgICAgICAgIC8vIyMjemFqICAgIHJldHVybiB2YWx1ZQotICAgICAgICAgICAgICAgIHJldHVybiAwOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIEdldCBhIGNoYXJhY3RlciBhcnJheSBjaHVuayBpbiB0aGUgc3RyaW5nLXZhbHVlIG9mIGEgbm9kZS4KLSAgICAgICAgICogKHNlZSBodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aCNkYXRhLW1vZGVsCi0gICAgICAgICAqIGZvciB0aGUgZGVmaW5pdGlvbiBvZiBhIG5vZGUncyBzdHJpbmctdmFsdWUpLgotICAgICAgICAgKiBOb3RlIHRoYXQgYSBzaW5nbGUgdGV4dCBub2RlIG1heSBoYXZlIG11bHRpcGxlIHRleHQgY2h1bmtzLgotICAgICAgICAgKgotICAgICAgICAgKiBFWFBMQU5BVElPTjogVGhpcyBtZXRob2QgaXMgYW4gYXJ0aWZhY3Qgb2YgdGhlIGZhY3QgdGhhdAotICAgICAgICAgKiB0aGUgdW5kZXJseWluZyBtX2NoYXJzIG9iamVjdCBtYXkgbm90IHN0b3JlIGNoYXJhY3RlcnMgaW4gYQotICAgICAgICAgKiBzaW5nbGUgY29udGlndW91cyBhcnJheSAtLSBmb3IgZXhhbXBsZSx0aGUgY3VycmVudAotICAgICAgICAgKiBGYXN0U3RyaW5nQnVmZmVyIG1heSBzcGxpdCBhIHNpbmdsZSBub2RlJ3MgdGV4dCBhY3Jvc3MKLSAgICAgICAgICogbXVsdGlwbGUgYWxsb2NhdGlvbiB1bml0cy4gIFRoaXMgY2FsbCByZXRyaWV2ZXMgYSBzaW5nbGUKLSAgICAgICAgICogY29udGlndW91cyBwb3J0aW9uIG9mIHRoZSB0ZXh0IC0tIGFzIG11Y2ggYXMgbS1jaGFycyB3YXMKLSAgICAgICAgICogYWJsZSB0byBzdG9yZSBpbiBhIHNpbmdsZSBhbGxvY2F0aW9uIHVuaXQuICBQTEVBU0UgTk9URQotICAgICAgICAgKiB0aGF0IHRoaXMgbWF5IG5vdCBiZSB0aGUgc2FtZSBncmFudWxhcml0eWFzIHRoZSBTQVgKLSAgICAgICAgICogY2hhcmFjdGVycygpIGV2ZW50cyB0aGF0IGNhdXNlZCB0aGUgdGV4dCBub2RlIHRvIGJlIGJ1aWx0Ci0gICAgICAgICAqIGluIHRoZSBmaXJzdCBwbGFjZSwgc2luY2UgbV9jaGFycyBidWZmZXJpbmcgbWF5IGJlIG9uCi0gICAgICAgICAqIGRpZmZlcmVudCBib3VuZGFyaWVzIHRoYW4gdGhlIHBhcnNlcidzIGJ1ZmZlcnMuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBub2RlSGFuZGxlIFRoZSBub2RlIElELgotICAgICAgICAgKiBAcGFyYW0gY2h1bmtJbmRleCBXaGljaCBjaHVuayB0byBnZXQuCi0gICAgICAgICAqIEBwYXJhbSBzdGFydEFuZExlbiBBbiBhcnJheSBvZiAyIHdoZXJlIHRoZSBzdGFydCBwb3NpdGlvbiBhbmQgbGVuZ3RoIG9mCi0gICAgICAgICAqICAgICAgICAgICAgICAgICAgICB0aGUgY2h1bmsgd2lsbCBiZSByZXR1cm5lZC4KLSAgICAgICAgICoKLSAgICAgICAgICogQHJldHVybiBUaGUgY2hhcmFjdGVyIGFycmF5IHJlZmVyZW5jZSB3aGVyZSB0aGUgY2h1bmsgb2NjdXJzLiAgKi8KLSAgICAgICAgLy8jIyN6YWogLSB0YmQKLSAgICAgICAgcHVibGljIGNoYXJbXSBnZXRTdHJpbmdWYWx1ZUNodW5rKGludCBub2RlSGFuZGxlLCBpbnQgY2h1bmtJbmRleCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludFtdIHN0YXJ0QW5kTGVuKSB7cmV0dXJuIG5ldyBjaGFyWzBdO30KLQotICAgICAgICAvKioKLSAgICAgICAgICogR2l2ZW4gYSBub2RlIGhhbmRsZSwgcmV0dXJuIGFuIElEIHRoYXQgcmVwcmVzZW50cyB0aGUgbm9kZSdzIGV4cGFuZGVkIG5hbWUuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBub2RlSGFuZGxlIFRoZSBoYW5kbGUgdG8gdGhlIG5vZGUgaW4gcXVlc3Rpb24uCi0gICAgICAgICAqCi0gICAgICAgICAqIEByZXR1cm4gdGhlIGV4cGFuZGVkLW5hbWUgaWQgb2YgdGhlIG5vZGUuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgaW50IGdldEV4cGFuZGVkVHlwZUlEKGludCBub2RlSGFuZGxlKSB7Ci0gICAgICAgICAgIG5vZGVzLnJlYWRTbG90KG5vZGVIYW5kbGUsIGdvdHNsb3QpOwotICAgICAgICAgICBTdHJpbmcgcU5hbWUgPSBtX2xvY2FsTmFtZXMuaW5kZXhUb1N0cmluZyhnb3RzbG90WzNdKTsKLSAgICAgICAgICAgLy8gUmVtb3ZlIHByZWZpeCBmcm9tIHFOYW1lCi0gICAgICAgICAgIC8vICVUQkQlIGpqayBUaGlzIGlzIGFzc3VtaW5nIHRoZSBlbGVtZW50TmFtZSBpcyB0aGUgcU5hbWUuCi0gICAgICAgICAgIGludCBjb2xvbnBvcyA9IHFOYW1lLmluZGV4T2YoIjoiKTsKLSAgICAgICAgICAgU3RyaW5nIGxvY2FsTmFtZSA9IHFOYW1lLnN1YnN0cmluZyhjb2xvbnBvcysxKTsKLSAgICAgICAgICAgLy8gR2V0IE5TCi0gICAgICAgICAgIFN0cmluZyBuYW1lc3BhY2UgPSBtX25zTmFtZXMuaW5kZXhUb1N0cmluZyhnb3RzbG90WzBdIDw8IDE2KTsKLSAgICAgICAgICAgLy8gQ3JlYXRlIGV4cGFuZGVkIG5hbWUKLSAgICAgICAgICAgU3RyaW5nIGV4cGFuZGVkTmFtZSA9IG5hbWVzcGFjZSArICI6IiArIGxvY2FsTmFtZTsKLSAgICAgICAgICAgaW50IGV4cGFuZGVkTmFtZUlEID0gbV9uc05hbWVzLnN0cmluZ1RvSW5kZXgoZXhwYW5kZWROYW1lKTsKLQotICAgICAgICByZXR1cm4gZXhwYW5kZWROYW1lSUQ7Ci0gICAgICAgIH0KLQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBHaXZlbiBhbiBleHBhbmRlZCBuYW1lLCByZXR1cm4gYW4gSUQuICBJZiB0aGUgZXhwYW5kZWQtbmFtZSBkb2VzIG5vdAotICAgICAgICAgKiBleGlzdCBpbiB0aGUgaW50ZXJuYWwgdGFibGVzLCB0aGUgZW50cnkgd2lsbCBiZSBjcmVhdGVkLCBhbmQgdGhlIElEIHdpbGwKLSAgICAgICAgICogYmUgcmV0dXJuZWQuICBBbnkgYWRkaXRpb25hbCBub2RlcyB0aGF0IGFyZSBjcmVhdGVkIHRoYXQgaGF2ZSB0aGlzCi0gICAgICAgICAqIGV4cGFuZGVkIG5hbWUgd2lsbCB1c2UgdGhpcyBJRC4KLSAgICAgICAgICoKLSAgICAgICAgICogQHJldHVybiB0aGUgZXhwYW5kZWQtbmFtZSBpZCBvZiB0aGUgbm9kZS4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBpbnQgZ2V0RXhwYW5kZWRUeXBlSUQoU3RyaW5nIG5hbWVzcGFjZSwgU3RyaW5nIGxvY2FsTmFtZSwgaW50IHR5cGUpIHsKLSAgICAgICAgICAgLy8gQ3JlYXRlIGV4cGFuZGVkIG5hbWUKLSAgICAgICAgICAvLyAlVEJEJSBqamsgRXhwYW5kZWQgbmFtZSBpcyBiaXRmaWVsZC1lbmNvZGVkIGFzCi0gICAgICAgICAgLy8gdHlwZUlEWzZdbnN1cmlJRFsxMF1sb2NhbElEWzE2XS4gU3dpdGNoIHRvIHRoYXQgZm9ybSwgYW5kIHRvCi0gICAgICAgICAgLy8gYWNjZXNzaW5nIHRoZSBucy9sb2NhbCB2aWEgdGhlaXIgdGFibGVzIHJhdGhlciB0aGFuIGNvbmZ1c2luZwotICAgICAgICAgIC8vIG5zbmFtZXMgYW5kIGV4cGFuZGVkbmFtZXMuCi0gICAgICAgICAgIFN0cmluZyBleHBhbmRlZE5hbWUgPSBuYW1lc3BhY2UgKyAiOiIgKyBsb2NhbE5hbWU7Ci0gICAgICAgICAgIGludCBleHBhbmRlZE5hbWVJRCA9IG1fbnNOYW1lcy5zdHJpbmdUb0luZGV4KGV4cGFuZGVkTmFtZSk7Ci0KLSAgICAgICAgICAgcmV0dXJuIGV4cGFuZGVkTmFtZUlEOwotICAgICAgICB9Ci0KLQotICAgICAgICAvKioKLSAgICAgICAgICogR2l2ZW4gYW4gZXhwYW5kZWQtbmFtZSBJRCwgcmV0dXJuIHRoZSBsb2NhbCBuYW1lIHBhcnQuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBFeHBhbmRlZE5hbWVJRCBhbiBJRCB0aGF0IHJlcHJlc2VudHMgYW4gZXhwYW5kZWQtbmFtZS4KLSAgICAgICAgICogQHJldHVybiBTdHJpbmcgTG9jYWwgbmFtZSBvZiB0aGlzIG5vZGUuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgU3RyaW5nIGdldExvY2FsTmFtZUZyb21FeHBhbmRlZE5hbWVJRChpbnQgRXhwYW5kZWROYW1lSUQpIHsKLQotICAgICAgICAgICAvLyBHZXQgZXhwYW5kZWQgbmFtZQotICAgICAgICAgICBTdHJpbmcgZXhwYW5kZWROYW1lID0gbV9sb2NhbE5hbWVzLmluZGV4VG9TdHJpbmcoRXhwYW5kZWROYW1lSUQpOwotICAgICAgICAgICAvLyBSZW1vdmUgcHJlZml4IGZyb20gZXhwYW5kZWQgbmFtZQotICAgICAgICAgICBpbnQgY29sb25wb3MgPSBleHBhbmRlZE5hbWUuaW5kZXhPZigiOiIpOwotICAgICAgICAgICBTdHJpbmcgbG9jYWxOYW1lID0gZXhwYW5kZWROYW1lLnN1YnN0cmluZyhjb2xvbnBvcysxKTsKLSAgICAgICAgICAgcmV0dXJuIGxvY2FsTmFtZTsKLSAgICAgICAgfQotCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIEdpdmVuIGFuIGV4cGFuZGVkLW5hbWUgSUQsIHJldHVybiB0aGUgbmFtZXNwYWNlIFVSSSBwYXJ0LgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gRXhwYW5kZWROYW1lSUQgYW4gSUQgdGhhdCByZXByZXNlbnRzIGFuIGV4cGFuZGVkLW5hbWUuCi0gICAgICAgICAqIEByZXR1cm4gU3RyaW5nIFVSSSB2YWx1ZSBvZiB0aGlzIG5vZGUncyBuYW1lc3BhY2UsIG9yIG51bGwgaWYgbm8KLSAgICAgICAgICogbmFtZXNwYWNlIHdhcyByZXNvbHZlZC4KLSAgICAgICAgKi8KLSAgICAgICAgcHVibGljIFN0cmluZyBnZXROYW1lc3BhY2VGcm9tRXhwYW5kZWROYW1lSUQoaW50IEV4cGFuZGVkTmFtZUlEKSB7Ci0KLSAgICAgICAgICAgU3RyaW5nIGV4cGFuZGVkTmFtZSA9IG1fbG9jYWxOYW1lcy5pbmRleFRvU3RyaW5nKEV4cGFuZGVkTmFtZUlEKTsKLSAgICAgICAgICAgLy8gUmVtb3ZlIGxvY2FsIG5hbWUgZnJvbSBleHBhbmRlZCBuYW1lCi0gICAgICAgICAgIGludCBjb2xvbnBvcyA9IGV4cGFuZGVkTmFtZS5pbmRleE9mKCI6Iik7Ci0gICAgICAgICAgIFN0cmluZyBuc05hbWUgPSBleHBhbmRlZE5hbWUuc3Vic3RyaW5nKDAsIGNvbG9ucG9zKTsKLQotICAgICAgICByZXR1cm4gbnNOYW1lOwotICAgICAgICB9Ci0KLQotICAgICAgICAvKioKLSAgICAgICAgICogZml4ZWRuYW1lcwotICAgICAgICAqLwotICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSBmaXhlZG5hbWVzPQotICAgICAgICB7Ci0gICAgICAgICAgICAgICAgbnVsbCxudWxsLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG5vdGhpbmcsIEVsZW1lbnQKLSAgICAgICAgICAgICAgICBudWxsLCIjdGV4dCIsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEF0dHIsIFRleHQKLSAgICAgICAgICAgICAgICAiI2NkYXRhX3NlY3Rpb24iLG51bGwsICAvLyBDREFUQSwgRW50aXR5UmVmZXJlbmNlCi0gICAgICAgICAgICAgICAgbnVsbCxudWxsLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEVudGl0eSwgUEkKLSAgICAgICAgICAgICAgICAiI2NvbW1lbnQiLCIjZG9jdW1lbnQiLCAvLyBDb21tZW50LCBEb2N1bWVudAotICAgICAgICAgICAgICAgIG51bGwsIiNkb2N1bWVudC1mcmFnbWVudCIsIC8vIERvY3R5cGUsIERvY3VtZW50RnJhZ21lbnQKLSAgICAgICAgICAgICAgICBudWxsfTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBOb3RhdGlvbgotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBHaXZlbiBhIG5vZGUgaGFuZGxlLCByZXR1cm4gaXRzIERPTS1zdHlsZSBub2RlIG5hbWUuIFRoaXMgd2lsbAotICAgICAgICAgKiBpbmNsdWRlIG5hbWVzIHN1Y2ggYXMgI3RleHQgb3IgI2RvY3VtZW50LgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gbm9kZUhhbmRsZSB0aGUgaWQgb2YgdGhlIG5vZGUuCi0gICAgICAgICAqIEByZXR1cm4gU3RyaW5nIE5hbWUgb2YgdGhpcyBub2RlLCB3aGljaCBtYXkgYmUgYW4gZW1wdHkgc3RyaW5nLgotICAgICAgICAgKiAlUkVWSUVXJSBEb2N1bWVudCB3aGVuIGVtcHR5IHN0cmluZyBpcyBwb3NzaWJsZS4uLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIFN0cmluZyBnZXROb2RlTmFtZShpbnQgbm9kZUhhbmRsZSkgewotICAgICAgICAgICAgICAgIG5vZGVzLnJlYWRTbG90KG5vZGVIYW5kbGUsIGdvdHNsb3QpOwotICAgICAgICAgICAgICAgIHNob3J0IHR5cGUgPSAoc2hvcnQpIChnb3RzbG90WzBdICYgMHhGRkZGKTsKLSAgICAgICAgICAgICAgICBTdHJpbmcgbmFtZSA9IGZpeGVkbmFtZXNbdHlwZV07Ci0gICAgICAgICAgICAgICAgaWYgKG51bGwgPT0gbmFtZSkgewotICAgICAgICAgICAgICAgICAgaW50IGk9Z290c2xvdFszXTsKLSAgICAgICAgICAgICAgICAgIC8qKi9TeXN0ZW0ub3V0LnByaW50bG4oImdvdCBpPSIraSsiICIrKGk+PjE2KSsiLyIrKGkmMHhmZmZmKSk7Ci0KLSAgICAgICAgICAgICAgICAgIG5hbWU9bV9sb2NhbE5hbWVzLmluZGV4VG9TdHJpbmcoaSAmIDB4RkZGRik7Ci0gICAgICAgICAgICAgICAgICBTdHJpbmcgcHJlZml4PW1fcHJlZml4TmFtZXMuaW5kZXhUb1N0cmluZyhpID4+MTYpOwotICAgICAgICAgICAgICAgICAgaWYocHJlZml4IT1udWxsICYmIHByZWZpeC5sZW5ndGgoKT4wKQotICAgICAgICAgICAgICAgICAgICBuYW1lPXByZWZpeCsiOiIrbmFtZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgcmV0dXJuIG5hbWU7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogR2l2ZW4gYSBub2RlIGhhbmRsZSwgcmV0dXJuIHRoZSBYUGF0aCBub2RlIG5hbWUuICBUaGlzIHNob3VsZCBiZQotICAgICAgICAgKiB0aGUgbmFtZSBhcyBkZXNjcmliZWQgYnkgdGhlIFhQYXRoIGRhdGEgbW9kZWwsIE5PVCB0aGUgRE9NLXN0eWxlCi0gICAgICAgICAqIG5hbWUuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBub2RlSGFuZGxlIHRoZSBpZCBvZiB0aGUgbm9kZS4KLSAgICAgICAgICogQHJldHVybiBTdHJpbmcgTmFtZSBvZiB0aGlzIG5vZGUuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgU3RyaW5nIGdldE5vZGVOYW1lWChpbnQgbm9kZUhhbmRsZSkge3JldHVybiBudWxsO30KLQotICAgICAgICAvKioKLSAgICAgICAgICogR2l2ZW4gYSBub2RlIGhhbmRsZSwgcmV0dXJuIGl0cyBET00tc3R5bGUgbG9jYWxuYW1lLgotICAgICAgICAgKiAoQXMgZGVmaW5lZCBpbiBOYW1lc3BhY2VzLCB0aGlzIGlzIHRoZSBwb3J0aW9uIG9mIHRoZSBuYW1lIGFmdGVyIGFueQotICAgICAgICAgKiBjb2xvbiBjaGFyYWN0ZXIpCi0gICAgICAgICAqCi0gICAgICAgICAqICVSRVZJRVclIFdoYXQncyB0aGUgbG9jYWwgbmFtZSBvZiBzb21ldGhpbmcgb3RoZXIgdGhhbiBFbGVtZW50L0F0dHI/Ci0gICAgICAgICAqIFNob3VsZCB0aGlzIGJlIERPTS1zdHlsZSAodW5kZWZpbmVkIHVubGVzcyBuYW1lc3BhY2VkKSwgb3Igb3RoZXI/Ci0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBub2RlSGFuZGxlIHRoZSBpZCBvZiB0aGUgbm9kZS4KLSAgICAgICAgICogQHJldHVybiBTdHJpbmcgTG9jYWwgbmFtZSBvZiB0aGlzIG5vZGUuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgU3RyaW5nIGdldExvY2FsTmFtZShpbnQgbm9kZUhhbmRsZSkgewotICAgICAgICAgICAgICAgIG5vZGVzLnJlYWRTbG90KG5vZGVIYW5kbGUsIGdvdHNsb3QpOwotICAgICAgICAgICAgICAgIHNob3J0IHR5cGUgPSAoc2hvcnQpIChnb3RzbG90WzBdICYgMHhGRkZGKTsKLSAgICAgICAgICAgICAgICBTdHJpbmcgbmFtZSA9ICIiOwotICAgICAgICAgICAgICAgIGlmICgodHlwZT09RUxFTUVOVF9OT0RFKSB8fCAodHlwZT09QVRUUklCVVRFX05PREUpKSB7Ci0gICAgICAgICAgICAgICAgICBpbnQgaT1nb3RzbG90WzNdOwotICAgICAgICAgICAgICAgICAgbmFtZT1tX2xvY2FsTmFtZXMuaW5kZXhUb1N0cmluZyhpICYgMHhGRkZGKTsKLSAgICAgICAgICAgICAgICAgIGlmKG5hbWU9PW51bGwpIG5hbWU9IiI7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHJldHVybiBuYW1lOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIEdpdmVuIGEgbmFtZXNwYWNlIGhhbmRsZSwgcmV0dXJuIHRoZSBwcmVmaXggdGhhdCB0aGUgbmFtZXNwYWNlIGRlY2wgaXMKLSAgICAgICAgICogbWFwcGluZy4KLSAgICAgICAgICogR2l2ZW4gYSBub2RlIGhhbmRsZSwgcmV0dXJuIHRoZSBwcmVmaXggdXNlZCB0byBtYXAgdG8gdGhlIG5hbWVzcGFjZS4KLSAgICAgICAgICoKLSAgICAgICAgICogPHA+ICVSRVZJRVclIEFyZSB5b3Ugc3VyZSB5b3Ugd2FudCAiIiBmb3Igbm8gcHJlZml4PyAgPC9wPgotICAgICAgICAgKgotICAgICAgICAgKiAlUkVWSUVXJSAgU2hvdWxkIHRoaXMgYmUgRE9NLXN0eWxlICh1bmRlZmluZWQgdW5sZXNzIG5hbWVzcGFjZWQpLAotICAgICAgICAgKiBvciBvdGhlcj8KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIG5vZGVIYW5kbGUgdGhlIGlkIG9mIHRoZSBub2RlLgotICAgICAgICAgKiBAcmV0dXJuIFN0cmluZyBwcmVmaXggb2YgdGhpcyBub2RlJ3MgbmFtZSwgb3IgIiIgaWYgbm8gZXhwbGljaXQKLSAgICAgICAgICogbmFtZXNwYWNlIHByZWZpeCB3YXMgZ2l2ZW4uCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFByZWZpeChpbnQgbm9kZUhhbmRsZSkgewotICAgICAgICAgICAgICAgIG5vZGVzLnJlYWRTbG90KG5vZGVIYW5kbGUsIGdvdHNsb3QpOwotICAgICAgICAgICAgICAgIHNob3J0IHR5cGUgPSAoc2hvcnQpIChnb3RzbG90WzBdICYgMHhGRkZGKTsKLSAgICAgICAgICAgICAgICBTdHJpbmcgbmFtZSA9ICIiOwotICAgICAgICAgICAgICAgIGlmKCh0eXBlPT1FTEVNRU5UX05PREUpIHx8ICh0eXBlPT1BVFRSSUJVVEVfTk9ERSkpIHsKLSAgICAgICAgICAgICAgICAgIGludCBpPWdvdHNsb3RbM107Ci0gICAgICAgICAgICAgICAgICBuYW1lPW1fcHJlZml4TmFtZXMuaW5kZXhUb1N0cmluZyhpID4+MTYpOwotICAgICAgICAgICAgICAgICAgaWYobmFtZT09bnVsbCkgbmFtZT0iIjsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgcmV0dXJuIG5hbWU7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogR2l2ZW4gYSBub2RlIGhhbmRsZSwgcmV0dXJuIGl0cyBET00tc3R5bGUgbmFtZXNwYWNlIFVSSQotICAgICAgICAgKiAoQXMgZGVmaW5lZCBpbiBOYW1lc3BhY2VzLCB0aGlzIGlzIHRoZSBkZWNsYXJlZCBVUkkgd2hpY2ggdGhpcyBub2RlJ3MKLSAgICAgICAgICogcHJlZml4IC0tIG9yIGRlZmF1bHQgaW4gbGlldSB0aGVyZW9mIC0tIHdhcyBtYXBwZWQgdG8uKQotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gbm9kZUhhbmRsZSB0aGUgaWQgb2YgdGhlIG5vZGUuCi0gICAgICAgICAqIEByZXR1cm4gU3RyaW5nIFVSSSB2YWx1ZSBvZiB0aGlzIG5vZGUncyBuYW1lc3BhY2UsIG9yIG51bGwgaWYgbm8KLSAgICAgICAgICogbmFtZXNwYWNlIHdhcyByZXNvbHZlZC4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZXNwYWNlVVJJKGludCBub2RlSGFuZGxlKSB7cmV0dXJuIG51bGw7fQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBHaXZlbiBhIG5vZGUgaGFuZGxlLCByZXR1cm4gaXRzIG5vZGUgdmFsdWUuIFRoaXMgaXMgbW9zdGx5Ci0gICAgICAgICAqIGFzIGRlZmluZWQgYnkgdGhlIERPTSwgYnV0IG1heSBpZ25vcmUgc29tZSBjb252ZW5pZW5jZXMuCi0gICAgICAgICAqIDxwPgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBUaGUgbm9kZSBpZC4KLSAgICAgICAgICogQHJldHVybiBTdHJpbmcgVmFsdWUgb2YgdGhpcyBub2RlLCBvciBudWxsIGlmIG5vdAotICAgICAgICAgKiBtZWFuaW5nZnVsIGZvciB0aGlzIG5vZGUgdHlwZS4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0Tm9kZVZhbHVlKGludCBub2RlSGFuZGxlKQotICAgICAgICB7Ci0gICAgICAgICAgICAgICAgbm9kZXMucmVhZFNsb3Qobm9kZUhhbmRsZSwgZ290c2xvdCk7Ci0gICAgICAgICAgICAgICAgaW50IG5vZGV0eXBlPWdvdHNsb3RbMF0gJiAweEZGOyAgICAgICAgIC8vICMjI3phaiB1c2UgbWFzayB0byBnZXQgbm9kZSB0eXBlCi0gICAgICAgICAgICAgICAgU3RyaW5nIHZhbHVlPW51bGw7Ci0KLSAgICAgICAgICAgICAgICBzd2l0Y2ggKG5vZGV0eXBlKSB7ICAgICAgICAgICAgICAgICAgICAgLy8gIyMjemFqIHRvZG8gLSBkb2N1bWVudCBub2RldHlwZXMKLSAgICAgICAgICAgICAgICBjYXNlIEFUVFJJQlVURV9OT0RFOgotICAgICAgICAgICAgICAgICAgICAgICAgbm9kZXMucmVhZFNsb3Qobm9kZUhhbmRsZSsxLCBnb3RzbG90KTsKLSAgICAgICAgICAgICAgICBjYXNlIFRFWFRfTk9ERToKLSAgICAgICAgICAgICAgICBjYXNlIENPTU1FTlRfTk9ERToKLSAgICAgICAgICAgICAgICBjYXNlIENEQVRBX1NFQ1RJT05fTk9ERToKLSAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlPW1fY2hhci5nZXRTdHJpbmcoZ290c2xvdFsyXSwgZ290c2xvdFszXSk7ICAgICAgICAgLy8jIyN6YWoKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGNhc2UgUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFOgotICAgICAgICAgICAgICAgIGNhc2UgRUxFTUVOVF9OT0RFOgotICAgICAgICAgICAgICAgIGNhc2UgRU5USVRZX1JFRkVSRU5DRV9OT0RFOgotICAgICAgICAgICAgICAgIGRlZmF1bHQ6Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIHJldHVybiBpdHMgRE9NLXN0eWxlIG5vZGUgdHlwZS4KLSAgICAgICAgICogPHA+Ci0gICAgICAgICAqICVSRVZJRVclIEdlbmVyYWxseSwgcmV0dXJuaW5nIHNob3J0IGlzIGZhbHNlIGVjb25vbXkuIFJldHVybiBpbnQ/Ci0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBub2RlSGFuZGxlIFRoZSBub2RlIGlkLgotICAgICAgICAgKiBAcmV0dXJuIGludCBOb2RlIHR5cGUsIGFzIHBlciB0aGUgRE9NJ3MgTm9kZS5fTk9ERSBjb25zdGFudHMuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgc2hvcnQgZ2V0Tm9kZVR5cGUoaW50IG5vZGVIYW5kbGUpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4oc2hvcnQpIChub2Rlcy5yZWFkRW50cnkobm9kZUhhbmRsZSwgMCkgJiAweEZGRkYpOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIEdldCB0aGUgZGVwdGggbGV2ZWwgb2YgdGhpcyBub2RlIGluIHRoZSB0cmVlIChlcXVhbHMgMSBmb3IKLSAgICAgICAgICogYSBwYXJlbnRsZXNzIG5vZGUpLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBUaGUgbm9kZSBpZC4KLSAgICAgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGFuY2VzdG9ycywgcGx1cyBvbmUKLSAgICAgICAgICogQHhzbC51c2FnZSBpbnRlcm5hbAotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIHNob3J0IGdldExldmVsKGludCBub2RlSGFuZGxlKSB7Ci0gICAgICAgICAgICAgICAgc2hvcnQgY291bnQgPSAwOwotICAgICAgICAgICAgICAgIHdoaWxlIChub2RlSGFuZGxlICE9IDApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50Kys7Ci0gICAgICAgICAgICAgICAgICAgICAgICBub2RlSGFuZGxlID0gbm9kZXMucmVhZEVudHJ5KG5vZGVIYW5kbGUsIDEpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICByZXR1cm4gY291bnQ7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyA9PT09PT09PT09PT09PSBEb2N1bWVudCBxdWVyeSBmdW5jdGlvbnMgPT09PT09PT09PT09PT0KLQotICAgICAgICAvKioKLSAgICAgICAgICogVGVzdHMgd2hldGhlciBEVE0gRE9NIGltcGxlbWVudGF0aW9uIGltcGxlbWVudHMgYSBzcGVjaWZpYyBmZWF0dXJlIGFuZAotICAgICAgICAgKiB0aGF0IGZlYXR1cmUgaXMgc3VwcG9ydGVkIGJ5IHRoaXMgbm9kZS4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIGZlYXR1cmUgVGhlIG5hbWUgb2YgdGhlIGZlYXR1cmUgdG8gdGVzdC4KLSAgICAgICAgICogQHBhcmFtIHZlcnNpb24gVGhpcyBpcyB0aGUgdmVyc2lvbiBudW1iZXIgb2YgdGhlIGZlYXR1cmUgdG8gdGVzdC4KLSAgICAgICAgICogICBJZiB0aGUgdmVyc2lvbiBpcyBub3QKLSAgICAgICAgICogICBzcGVjaWZpZWQsIHN1cHBvcnRpbmcgYW55IHZlcnNpb24gb2YgdGhlIGZlYXR1cmUgd2lsbCBjYXVzZSB0aGUKLSAgICAgICAgICogICBtZXRob2QgdG8gcmV0dXJuIDxjb2RlPnRydWU8L2NvZGU+LgotICAgICAgICAgKiBAcmV0dXJuIFJldHVybnMgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIHNwZWNpZmllZCBmZWF0dXJlIGlzCi0gICAgICAgICAqICAgc3VwcG9ydGVkIG9uIHRoaXMgbm9kZSwgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBib29sZWFuIGlzU3VwcG9ydGVkKFN0cmluZyBmZWF0dXJlLCBTdHJpbmcgdmVyc2lvbikge3JldHVybiBmYWxzZTt9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFJldHVybiB0aGUgYmFzZSBVUkkgb2YgdGhlIGRvY3VtZW50IGVudGl0eS4gSWYgaXQgaXMgbm90IGtub3duCi0gICAgICAgICAqIChiZWNhdXNlIHRoZSBkb2N1bWVudCB3YXMgcGFyc2VkIGZyb20gYSBzb2NrZXQgY29ubmVjdGlvbiBvciBmcm9tCi0gICAgICAgICAqIHN0YW5kYXJkIGlucHV0LCBmb3IgZXhhbXBsZSksIHRoZSB2YWx1ZSBvZiB0aGlzIHByb3BlcnR5IGlzIHVua25vd24uCi0gICAgICAgICAqCi0gICAgICAgICAqIEByZXR1cm4gdGhlIGRvY3VtZW50IGJhc2UgVVJJIFN0cmluZyBvYmplY3Qgb3IgbnVsbCBpZiB1bmtub3duLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIFN0cmluZyBnZXREb2N1bWVudEJhc2VVUkkoKQotICAgICAgICB7Ci0KLSAgICAgICAgICByZXR1cm4gbV9kb2N1bWVudEJhc2VVUkk7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogU2V0IHRoZSBiYXNlIFVSSSBvZiB0aGUgZG9jdW1lbnQgZW50aXR5LgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gYmFzZVVSSSB0aGUgZG9jdW1lbnQgYmFzZSBVUkkgU3RyaW5nIG9iamVjdCBvciBudWxsIGlmIHVua25vd24uCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgdm9pZCBzZXREb2N1bWVudEJhc2VVUkkoU3RyaW5nIGJhc2VVUkkpCi0gICAgICAgIHsKLQotICAgICAgICAgIG1fZG9jdW1lbnRCYXNlVVJJID0gYmFzZVVSSTsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBSZXR1cm4gdGhlIHN5c3RlbSBpZGVudGlmaWVyIG9mIHRoZSBkb2N1bWVudCBlbnRpdHkuIElmCi0gICAgICAgICAqIGl0IGlzIG5vdCBrbm93biwgdGhlIHZhbHVlIG9mIHRoaXMgcHJvcGVydHkgaXMgdW5rbm93bi4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIG5vZGVIYW5kbGUgVGhlIG5vZGUgaWQsIHdoaWNoIGNhbiBiZSBhbnkgdmFsaWQgbm9kZSBoYW5kbGUuCi0gICAgICAgICAqIEByZXR1cm4gdGhlIHN5c3RlbSBpZGVudGlmaWVyIFN0cmluZyBvYmplY3Qgb3IgbnVsbCBpZiB1bmtub3duLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIFN0cmluZyBnZXREb2N1bWVudFN5c3RlbUlkZW50aWZpZXIoaW50IG5vZGVIYW5kbGUpIHtyZXR1cm4gbnVsbDt9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFJldHVybiB0aGUgbmFtZSBvZiB0aGUgY2hhcmFjdGVyIGVuY29kaW5nIHNjaGVtZQotICAgICAgICAgKiAgICAgICAgaW4gd2hpY2ggdGhlIGRvY3VtZW50IGVudGl0eSBpcyBleHByZXNzZWQuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBub2RlSGFuZGxlIFRoZSBub2RlIGlkLCB3aGljaCBjYW4gYmUgYW55IHZhbGlkIG5vZGUgaGFuZGxlLgotICAgICAgICAgKiBAcmV0dXJuIHRoZSBkb2N1bWVudCBlbmNvZGluZyBTdHJpbmcgb2JqZWN0LgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIFN0cmluZyBnZXREb2N1bWVudEVuY29kaW5nKGludCBub2RlSGFuZGxlKSB7cmV0dXJuIG51bGw7fQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBSZXR1cm4gYW4gaW5kaWNhdGlvbiBvZiB0aGUgc3RhbmRhbG9uZSBzdGF0dXMgb2YgdGhlIGRvY3VtZW50LAotICAgICAgICAgKiAgICAgICAgZWl0aGVyICJ5ZXMiIG9yICJubyIuIFRoaXMgcHJvcGVydHkgaXMgZGVyaXZlZCBmcm9tIHRoZSBvcHRpb25hbAotICAgICAgICAgKiAgICAgICAgc3RhbmRhbG9uZSBkb2N1bWVudCBkZWNsYXJhdGlvbiBpbiB0aGUgWE1MIGRlY2xhcmF0aW9uIGF0IHRoZQotICAgICAgICAgKiAgICAgICAgYmVnaW5uaW5nIG9mIHRoZSBkb2N1bWVudCBlbnRpdHksIGFuZCBoYXMgbm8gdmFsdWUgaWYgdGhlcmUgaXMgbm8KLSAgICAgICAgICogICAgICAgIHN0YW5kYWxvbmUgZG9jdW1lbnQgZGVjbGFyYXRpb24uCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBub2RlSGFuZGxlIFRoZSBub2RlIGlkLCB3aGljaCBjYW4gYmUgYW55IHZhbGlkIG5vZGUgaGFuZGxlLgotICAgICAgICAgKiBAcmV0dXJuIHRoZSBkb2N1bWVudCBzdGFuZGFsb25lIFN0cmluZyBvYmplY3QsIGVpdGhlciAieWVzIiwgIm5vIiwgb3IgbnVsbC4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0RG9jdW1lbnRTdGFuZGFsb25lKGludCBub2RlSGFuZGxlKSB7cmV0dXJuIG51bGw7fQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBSZXR1cm4gYSBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBYTUwgdmVyc2lvbiBvZiB0aGUgZG9jdW1lbnQuIFRoaXMKLSAgICAgICAgICogcHJvcGVydHkgaXMgZGVyaXZlZCBmcm9tIHRoZSBYTUwgZGVjbGFyYXRpb24gb3B0aW9uYWxseSBwcmVzZW50IGF0IHRoZQotICAgICAgICAgKiBiZWdpbm5pbmcgb2YgdGhlIGRvY3VtZW50IGVudGl0eSwgYW5kIGhhcyBubyB2YWx1ZSBpZiB0aGVyZSBpcyBubyBYTUwKLSAgICAgICAgICogZGVjbGFyYXRpb24uCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBkb2N1bWVudEhhbmRsZSB0aGUgZG9jdW1lbnQgaGFuZGxlCi0gICAgICAgICAqCi0gICAgICAgICAqIEByZXR1cm4gdGhlIGRvY3VtZW50IHZlcnNpb24gU3RyaW5nIG9iamVjdAotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIFN0cmluZyBnZXREb2N1bWVudFZlcnNpb24oaW50IGRvY3VtZW50SGFuZGxlKSB7cmV0dXJuIG51bGw7fQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBSZXR1cm4gYW4gaW5kaWNhdGlvbiBvZgotICAgICAgICAgKiB3aGV0aGVyIHRoZSBwcm9jZXNzb3IgaGFzIHJlYWQgdGhlIGNvbXBsZXRlIERURC4gSXRzIHZhbHVlIGlzIGEKLSAgICAgICAgICogYm9vbGVhbi4gSWYgaXQgaXMgZmFsc2UsIHRoZW4gY2VydGFpbiBwcm9wZXJ0aWVzIChpbmRpY2F0ZWQgaW4gdGhlaXIKLSAgICAgICAgICogZGVzY3JpcHRpb25zIGJlbG93KSBtYXkgYmUgdW5rbm93bi4gSWYgaXQgaXMgdHJ1ZSwgdGhvc2UgcHJvcGVydGllcwotICAgICAgICAgKiBhcmUgbmV2ZXIgdW5rbm93bi4KLSAgICAgICAgICoKLSAgICAgICAgICogQHJldHVybiA8Y29kZT50cnVlPC9jb2RlPiBpZiBhbGwgZGVjbGFyYXRpb25zIHdlcmUgcHJvY2Vzc2VkIHt9OwotICAgICAgICAgKiAgICAgICAgIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgYm9vbGVhbiBnZXREb2N1bWVudEFsbERlY2xhcmF0aW9uc1Byb2Nlc3NlZCgpIHtyZXR1cm4gZmFsc2U7fQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiAgIEEgZG9jdW1lbnQgdHlwZSBkZWNsYXJhdGlvbiBpbmZvcm1hdGlvbiBpdGVtIGhhcyB0aGUgZm9sbG93aW5nIHByb3BlcnRpZXM6Ci0gICAgICAgICAqCi0gICAgICAgICAqICAgICAxLiBbc3lzdGVtIGlkZW50aWZpZXJdIFRoZSBzeXN0ZW0gaWRlbnRpZmllciBvZiB0aGUgZXh0ZXJuYWwgc3Vic2V0LCBpZgotICAgICAgICAgKiAgICAgICAgaXQgZXhpc3RzLiBPdGhlcndpc2UgdGhpcyBwcm9wZXJ0eSBoYXMgbm8gdmFsdWUuCi0gICAgICAgICAqCi0gICAgICAgICAqIEByZXR1cm4gdGhlIHN5c3RlbSBpZGVudGlmaWVyIFN0cmluZyBvYmplY3QsIG9yIG51bGwgaWYgdGhlcmUgaXMgbm9uZS4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0RG9jdW1lbnRUeXBlRGVjbGFyYXRpb25TeXN0ZW1JZGVudGlmaWVyKCkge3JldHVybiBudWxsO30KLQotICAgICAgICAvKioKLSAgICAgICAgICogUmV0dXJuIHRoZSBwdWJsaWMgaWRlbnRpZmllciBvZiB0aGUgZXh0ZXJuYWwgc3Vic2V0LAotICAgICAgICAgKiBub3JtYWxpemVkIGFzIGRlc2NyaWJlZCBpbiA0LjIuMiBFeHRlcm5hbCBFbnRpdGllcyBbWE1MXS4gSWYgdGhlcmUgaXMKLSAgICAgICAgICogbm8gZXh0ZXJuYWwgc3Vic2V0IG9yIGlmIGl0IGhhcyBubyBwdWJsaWMgaWRlbnRpZmllciwgdGhpcyBwcm9wZXJ0eQotICAgICAgICAgKiBoYXMgbm8gdmFsdWUuCi0gICAgICAgICAqCi0gICAgICAgICAqIEByZXR1cm4gdGhlIHB1YmxpYyBpZGVudGlmaWVyIFN0cmluZyBvYmplY3QsIG9yIG51bGwgaWYgdGhlcmUgaXMgbm9uZS4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0RG9jdW1lbnRUeXBlRGVjbGFyYXRpb25QdWJsaWNJZGVudGlmaWVyKCkge3JldHVybiBudWxsO30KLQotICAgICAgICAvKioKLSAgICAgICAgICogUmV0dXJucyB0aGUgPGNvZGU+RWxlbWVudDwvY29kZT4gd2hvc2UgPGNvZGU+SUQ8L2NvZGU+IGlzIGdpdmVuIGJ5Ci0gICAgICAgICAqIDxjb2RlPmVsZW1lbnRJZDwvY29kZT4uIElmIG5vIHN1Y2ggZWxlbWVudCBleGlzdHMsIHJldHVybnMKLSAgICAgICAgICogPGNvZGU+RFRNLk5VTEw8L2NvZGU+LiBCZWhhdmlvciBpcyBub3QgZGVmaW5lZCBpZiBtb3JlIHRoYW4gb25lIGVsZW1lbnQKLSAgICAgICAgICogaGFzIHRoaXMgPGNvZGU+SUQ8L2NvZGU+LiBBdHRyaWJ1dGVzIChpbmNsdWRpbmcgdGhvc2UKLSAgICAgICAgICogd2l0aCB0aGUgbmFtZSAiSUQiKSBhcmUgbm90IG9mIHR5cGUgSUQgdW5sZXNzIHNvIGRlZmluZWQgYnkgRFREL1NjaGVtYQotICAgICAgICAgKiBpbmZvcm1hdGlvbiBhdmFpbGFibGUgdG8gdGhlIERUTSBpbXBsZW1lbnRhdGlvbi4KLSAgICAgICAgICogSW1wbGVtZW50YXRpb25zIHRoYXQgZG8gbm90IGtub3cgd2hldGhlciBhdHRyaWJ1dGVzIGFyZSBvZiB0eXBlIElEIG9yCi0gICAgICAgICAqIG5vdCBhcmUgZXhwZWN0ZWQgdG8gcmV0dXJuIDxjb2RlPkRUTS5OVUxMPC9jb2RlPi4KLSAgICAgICAgICoKLSAgICAgICAgICogPHA+JVJFVklFVyUgUHJlc3VtYWJseSBJRHMgYXJlIHN0aWxsIHNjb3BlZCB0byBhIHNpbmdsZSBkb2N1bWVudCwKLSAgICAgICAgICogYW5kIHRoaXMgb3BlcmF0aW9uIHNlYXJjaGVzIG9ubHkgd2l0aGluIGEgc2luZ2xlIGRvY3VtZW50LCByaWdodD8KLSAgICAgICAgICogV291bGRuJ3Qgd2FudCBjb2xsaXNpb25zIGJldHdlZW4gRFRNcyBpbiB0aGUgc2FtZSBwcm9jZXNzLjwvcD4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIGVsZW1lbnRJZCBUaGUgdW5pcXVlIDxjb2RlPmlkPC9jb2RlPiB2YWx1ZSBmb3IgYW4gZWxlbWVudC4KLSAgICAgICAgICogQHJldHVybiBUaGUgaGFuZGxlIG9mIHRoZSBtYXRjaGluZyBlbGVtZW50LgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIGludCBnZXRFbGVtZW50QnlJZChTdHJpbmcgZWxlbWVudElkKSB7cmV0dXJuIDA7fQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBUaGUgZ2V0VW5wYXJzZWRFbnRpdHlVUkkgZnVuY3Rpb24gcmV0dXJucyB0aGUgVVJJIG9mIHRoZSB1bnBhcnNlZAotICAgICAgICAgKiBlbnRpdHkgd2l0aCB0aGUgc3BlY2lmaWVkIG5hbWUgaW4gdGhlIHNhbWUgZG9jdW1lbnQgYXMgdGhlIGNvbnRleHQKLSAgICAgICAgICogbm9kZSAoc2VlIFszLjMgVW5wYXJzZWQgRW50aXRpZXNdKS4gSXQgcmV0dXJucyB0aGUgZW1wdHkgc3RyaW5nIGlmCi0gICAgICAgICAqIHRoZXJlIGlzIG5vIHN1Y2ggZW50aXR5LgotICAgICAgICAgKiA8cD4KLSAgICAgICAgICogWE1MIHByb2Nlc3NvcnMgbWF5IGNob29zZSB0byB1c2UgdGhlIFN5c3RlbSBJZGVudGlmaWVyIChpZiBvbmUKLSAgICAgICAgICogaXMgcHJvdmlkZWQpIHRvIHJlc29sdmUgdGhlIGVudGl0eSwgcmF0aGVyIHRoYW4gdGhlIFVSSSBpbiB0aGUKLSAgICAgICAgICogUHVibGljIElkZW50aWZpZXIuIFRoZSBkZXRhaWxzIGFyZSBkZXBlbmRlbnQgb24gdGhlIHByb2Nlc3NvciwgYW5kCi0gICAgICAgICAqIHdlIHdvdWxkIGhhdmUgdG8gc3VwcG9ydCBzb21lIGZvcm0gb2YgcGx1Zy1pbiByZXNvbHZlciB0byBoYW5kbGUKLSAgICAgICAgICogdGhpcyBwcm9wZXJseS4gQ3VycmVudGx5LCB3ZSBzaW1wbHkgcmV0dXJuIHRoZSBTeXN0ZW0gSWRlbnRpZmllciBpZgotICAgICAgICAgKiBwcmVzZW50LCBhbmQgaG9wZSB0aGF0IGl0IGEgdXNhYmxlIFVSSSBvciB0aGF0IG91ciBjYWxsZXIgY2FuCi0gICAgICAgICAqIG1hcCBpdCB0byBvbmUuCi0gICAgICAgICAqIFRPRE86IFJlc29sdmUgUHVibGljIElkZW50aWZpZXJzLi4uIG9yIGNvbnNpZGVyIGNoYW5naW5nIGZ1bmN0aW9uIG5hbWUuCi0gICAgICAgICAqIDxwPgotICAgICAgICAgKiBJZiB3ZSBmaW5kIGEgcmVsYXRpdmUgVVJJCi0gICAgICAgICAqIHJlZmVyZW5jZSwgWE1MIGV4cGVjdHMgaXQgdG8gYmUgcmVzb2x2ZWQgaW4gdGVybXMgb2YgdGhlIGJhc2UgVVJJCi0gICAgICAgICAqIG9mIHRoZSBkb2N1bWVudC4gVGhlIERPTSBkb2Vzbid0IGRvIHRoYXQgZm9yIHVzLCBhbmQgaXQgaXNuJ3QKLSAgICAgICAgICogZW50aXJlbHkgY2xlYXIgd2hldGhlciB0aGF0IHNob3VsZCBiZSBkb25lIGhlcmU7IGN1cnJlbnRseSB0aGF0J3MKLSAgICAgICAgICogcHVzaGVkIHVwIHRvIGEgaGlnaGVyIGxldmVsIG9mIG91ciBhcHBsaWNhdGlvbi4gKE5vdGUgdGhhdCBET00gTGV2ZWwKLSAgICAgICAgICogMSBkaWRuJ3Qgc3RvcmUgdGhlIGRvY3VtZW50J3MgYmFzZSBVUkkuKQotICAgICAgICAgKiBUT0RPOiBDb25zaWRlciByZXNvbHZpbmcgUmVsYXRpdmUgVVJJcy4KLSAgICAgICAgICogPHA+Ci0gICAgICAgICAqIChUaGUgRE9NJ3Mgc3RhdGVtZW50IHRoYXQgIkFuIFhNTCBwcm9jZXNzb3IgbWF5IGNob29zZSB0bwotICAgICAgICAgKiBjb21wbGV0ZWx5IGV4cGFuZCBlbnRpdGllcyBiZWZvcmUgdGhlIHN0cnVjdHVyZSBtb2RlbCBpcyBwYXNzZWQKLSAgICAgICAgICogdG8gdGhlIERPTSIgcmVmZXJzIG9ubHkgdG8gcGFyc2VkIGVudGl0aWVzLCBub3QgdW5wYXJzZWQsIGFuZCBoZW5jZQotICAgICAgICAgKiBkb2Vzbid0IGFmZmVjdCB0aGlzIGZ1bmN0aW9uLikKLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIG5hbWUgQSBzdHJpbmcgY29udGFpbmluZyB0aGUgRW50aXR5IE5hbWUgb2YgdGhlIHVucGFyc2VkCi0gICAgICAgICAqIGVudGl0eS4KLSAgICAgICAgICoKLSAgICAgICAgICogQHJldHVybiBTdHJpbmcgY29udGFpbmluZyB0aGUgVVJJIG9mIHRoZSBVbnBhcnNlZCBFbnRpdHksIG9yIGFuCi0gICAgICAgICAqIGVtcHR5IHN0cmluZyBpZiBubyBzdWNoIGVudGl0eSBleGlzdHMuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFVucGFyc2VkRW50aXR5VVJJKFN0cmluZyBuYW1lKSB7cmV0dXJuIG51bGw7fQotCi0KLSAgICAgICAgLy8gPT09PT09PT09PT09PT0gQm9vbGVhbiBtZXRob2RzID09PT09PT09PT09PT09PT0KLQotICAgICAgICAvKioKLSAgICAgICAgICogUmV0dXJuIHRydWUgaWYgdGhlIHhzbDpzdHJpcC1zcGFjZSBvciB4c2w6cHJlc2VydmUtc3BhY2Ugd2FzIHByb2Nlc3NlZAotICAgICAgICAgKiBkdXJpbmcgY29uc3RydWN0aW9uIG9mIHRoZSBEVE0gZG9jdW1lbnQuCi0gICAgICAgICAqCi0gICAgICAgICAqIDxwPiVSRVZFSVclIFByZXN1bWVzIGEgMToxIG1hcHBpbmcgZnJvbSBEVE0gdG8gRG9jdW1lbnQsIHNpbmNlCi0gICAgICAgICAqIHdlIGFyZW4ndCBzYXlpbmcgd2hpY2ggRG9jdW1lbnQgdG8gcXVlcnkuLi4/PC9wPgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIGJvb2xlYW4gc3VwcG9ydHNQcmVTdHJpcHBpbmcoKSB7cmV0dXJuIGZhbHNlO30KLQotICAgICAgICAvKioKLSAgICAgICAgICogRmlndXJlIG91dCB3aGV0aGVyIG5vZGVIYW5kbGUyIHNob3VsZCBiZSBjb25zaWRlcmVkIGFzIGJlaW5nIGxhdGVyCi0gICAgICAgICAqIGluIHRoZSBkb2N1bWVudCB0aGFuIG5vZGVIYW5kbGUxLCBpbiBEb2N1bWVudCBPcmRlciBhcyBkZWZpbmVkCi0gICAgICAgICAqIGJ5IHRoZSBYUGF0aCBtb2RlbC4gVGhpcyBtYXkgbm90IGFncmVlIHdpdGggdGhlIG9yZGVyaW5nIGRlZmluZWQKLSAgICAgICAgICogYnkgb3RoZXIgWE1MIGFwcGxpY2F0aW9ucy4KLSAgICAgICAgICogPHA+Ci0gICAgICAgICAqIFRoZXJlIGFyZSBzb21lIGNhc2VzIHdoZXJlIG9yZGVyaW5nIGlzbid0IGRlZmluZWQsIGFuZCBuZWl0aGVyIGFyZQotICAgICAgICAgKiB0aGUgcmVzdWx0cyBvZiB0aGlzIGZ1bmN0aW9uIC0tIHRob3VnaCB3ZSdsbCBnZW5lcmFsbHkgcmV0dXJuIHRydWUuCi0gICAgICAgICAqCi0gICAgICAgICAqIFRPRE86IE1ha2Ugc3VyZSB0aGlzIGRvZXMgdGhlIHJpZ2h0IHRoaW5nIHdpdGggYXR0cmlidXRlIG5vZGVzISEhCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBub2RlSGFuZGxlMSBET00gTm9kZSB0byBwZXJmb3JtIHBvc2l0aW9uIGNvbXBhcmlzb24gb24uCi0gICAgICAgICAqIEBwYXJhbSBub2RlSGFuZGxlMiBET00gTm9kZSB0byBwZXJmb3JtIHBvc2l0aW9uIGNvbXBhcmlzb24gb24gLgotICAgICAgICAgKgotICAgICAgICAgKiBAcmV0dXJuIGZhbHNlIGlmIG5vZGUyIGNvbWVzIGJlZm9yZSBub2RlMSwgb3RoZXJ3aXNlIHJldHVybiB0cnVlLgotICAgICAgICAgKiBZb3UgY2FuIHRoaW5rIG9mIHRoaXMgYXMKLSAgICAgICAgICogPGNvZGU+KG5vZGUxLmRvY3VtZW50T3JkZXJQb3NpdGlvbiAmbHQ7PSBub2RlMi5kb2N1bWVudE9yZGVyUG9zaXRpb24pPC9jb2RlPi4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBib29sZWFuIGlzTm9kZUFmdGVyKGludCBub2RlSGFuZGxlMSwgaW50IG5vZGVIYW5kbGUyKSB7cmV0dXJuIGZhbHNlO30KLQotICAgICAgICAvKioKLSAgICAgICAgICogICAgIDIuIFtlbGVtZW50IGNvbnRlbnQgd2hpdGVzcGFjZV0gQSBib29sZWFuIGluZGljYXRpbmcgd2hldGhlciB0aGUKLSAgICAgICAgICogICAgICAgIGNoYXJhY3RlciBpcyB3aGl0ZSBzcGFjZSBhcHBlYXJpbmcgd2l0aGluIGVsZW1lbnQgY29udGVudCAoc2VlIFtYTUxdLAotICAgICAgICAgKiAgICAgICAgMi4xMCAiV2hpdGUgU3BhY2UgSGFuZGxpbmciKS4gTm90ZSB0aGF0IHZhbGlkYXRpbmcgWE1MIHByb2Nlc3NvcnMgYXJlCi0gICAgICAgICAqICAgICAgICByZXF1aXJlZCBieSBYTUwgMS4wIHRvIHByb3ZpZGUgdGhpcyBpbmZvcm1hdGlvbi4gSWYgdGhlcmUgaXMgbm8KLSAgICAgICAgICogICAgICAgIGRlY2xhcmF0aW9uIGZvciB0aGUgY29udGFpbmluZyBlbGVtZW50LCB0aGlzIHByb3BlcnR5IGhhcyBubyB2YWx1ZSBmb3IKLSAgICAgICAgICogICAgICAgIHdoaXRlIHNwYWNlIGNoYXJhY3RlcnMuIElmIG5vIGRlY2xhcmF0aW9uIGhhcyBiZWVuIHJlYWQsIGJ1dCB0aGUgW2FsbAotICAgICAgICAgKiAgICAgICAgZGVjbGFyYXRpb25zIHByb2Nlc3NlZF0gcHJvcGVydHkgb2YgdGhlIGRvY3VtZW50IGluZm9ybWF0aW9uIGl0ZW0gaXMKLSAgICAgICAgICogICAgICAgIGZhbHNlIChzbyB0aGVyZSBtYXkgYmUgYW4gdW5yZWFkIGRlY2xhcmF0aW9uKSwgdGhlbiB0aGUgdmFsdWUgb2YgdGhpcwotICAgICAgICAgKiAgICAgICAgcHJvcGVydHkgaXMgdW5rbm93biBmb3Igd2hpdGUgc3BhY2UgY2hhcmFjdGVycy4gSXQgaXMgYWx3YXlzIGZhbHNlIGZvcgotICAgICAgICAgKiAgICAgICAgY2hhcmFjdGVycyB0aGF0IGFyZSBub3Qgd2hpdGUgc3BhY2UuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBub2RlSGFuZGxlIHRoZSBub2RlIElELgotICAgICAgICAgKiBAcmV0dXJuIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBjaGFyYWN0ZXIgZGF0YSBpcyB3aGl0ZXNwYWNlOwotICAgICAgICAgKiAgICAgICAgIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc0NoYXJhY3RlckVsZW1lbnRDb250ZW50V2hpdGVzcGFjZShpbnQgbm9kZUhhbmRsZSkge3JldHVybiBmYWxzZTt9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqICAgIDEwLiBbYWxsIGRlY2xhcmF0aW9ucyBwcm9jZXNzZWRdIFRoaXMgcHJvcGVydHkgaXMgbm90IHN0cmljdGx5IHNwZWFraW5nCi0gICAgICAgICAqICAgICAgICBwYXJ0IG9mIHRoZSBpbmZvc2V0IG9mIHRoZSBkb2N1bWVudC4gUmF0aGVyIGl0IGlzIGFuIGluZGljYXRpb24gb2YKLSAgICAgICAgICogICAgICAgIHdoZXRoZXIgdGhlIHByb2Nlc3NvciBoYXMgcmVhZCB0aGUgY29tcGxldGUgRFRELiBJdHMgdmFsdWUgaXMgYQotICAgICAgICAgKiAgICAgICAgYm9vbGVhbi4gSWYgaXQgaXMgZmFsc2UsIHRoZW4gY2VydGFpbiBwcm9wZXJ0aWVzIChpbmRpY2F0ZWQgaW4gdGhlaXIKLSAgICAgICAgICogICAgICAgIGRlc2NyaXB0aW9ucyBiZWxvdykgbWF5IGJlIHVua25vd24uIElmIGl0IGlzIHRydWUsIHRob3NlIHByb3BlcnRpZXMKLSAgICAgICAgICogICAgICAgIGFyZSBuZXZlciB1bmtub3duLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gZG9jdW1lbnRIYW5kbGUgQSBub2RlIGhhbmRsZSB0aGF0IG11c3QgaWRlbnRpZnkgYSBkb2N1bWVudC4KLSAgICAgICAgICogQHJldHVybiA8Y29kZT50cnVlPC9jb2RlPiBpZiBhbGwgZGVjbGFyYXRpb25zIHdlcmUgcHJvY2Vzc2VkOwotICAgICAgICAgKiAgICAgICAgIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc0RvY3VtZW50QWxsRGVjbGFyYXRpb25zUHJvY2Vzc2VkKGludCBkb2N1bWVudEhhbmRsZSkge3JldHVybiBmYWxzZTt9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqICAgICA1LiBbc3BlY2lmaWVkXSBBIGZsYWcgaW5kaWNhdGluZyB3aGV0aGVyIHRoaXMgYXR0cmlidXRlIHdhcyBhY3R1YWxseQotICAgICAgICAgKiAgICAgICAgc3BlY2lmaWVkIGluIHRoZSBzdGFydC10YWcgb2YgaXRzIGVsZW1lbnQsIG9yIHdhcyBkZWZhdWx0ZWQgZnJvbSB0aGUKLSAgICAgICAgICogICAgICAgIERURC4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIGF0dHJpYnV0ZUhhbmRsZSB0aGUgYXR0cmlidXRlIGhhbmRsZQotICAgICAgICAgKiBAcmV0dXJuIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBhdHRyaWJ1dGUgd2FzIHNwZWNpZmllZDsKLSAgICAgICAgICogICAgICAgICA8Y29kZT5mYWxzZTwvY29kZT4gaWYgaXQgd2FzIGRlZmF1bHRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBib29sZWFuIGlzQXR0cmlidXRlU3BlY2lmaWVkKGludCBhdHRyaWJ1dGVIYW5kbGUpIHtyZXR1cm4gZmFsc2U7fQotCi0gICAgICAgIC8vID09PT09PT09PT0gRGlyZWN0IFNBWCBEaXNwYXRjaCwgZm9yIG9wdGltaXphdGlvbiBwdXJwb3NlcyA9PT09PT09PQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBEaXJlY3RseSBjYWxsIHRoZQotICAgICAgICAgKiBjaGFyYWN0ZXJzIG1ldGhvZCBvbiB0aGUgcGFzc2VkIENvbnRlbnRIYW5kbGVyIGZvciB0aGUKLSAgICAgICAgICogc3RyaW5nLXZhbHVlIG9mIHRoZSBnaXZlbiBub2RlIChzZWUgaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGgjZGF0YS1tb2RlbAotICAgICAgICAgKiBmb3IgdGhlIGRlZmluaXRpb24gb2YgYSBub2RlJ3Mgc3RyaW5nLXZhbHVlKS4gTXVsdGlwbGUgY2FsbHMgdG8gdGhlCi0gICAgICAgICAqIENvbnRlbnRIYW5kbGVyJ3MgY2hhcmFjdGVycyBtZXRob2RzIG1heSB3ZWxsIG9jY3VyIGZvciBhIHNpbmdsZSBjYWxsIHRvCi0gICAgICAgICAqIHRoaXMgbWV0aG9kLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBUaGUgbm9kZSBJRC4KLSAgICAgICAgICogQHBhcmFtIGNoIEEgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGEgQ29udGVudEhhbmRsZXIuCi0gICAgICAgICAqCi0gICAgICAgICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgdm9pZCBkaXNwYXRjaENoYXJhY3RlcnNFdmVudHMoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBub2RlSGFuZGxlLCBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciBjaCwgYm9vbGVhbiBub3JtYWxpemUpCi0gICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24ge30KLQotICAgICAgICAvKioKLSAgICAgICAgICogRGlyZWN0bHkgY3JlYXRlIFNBWCBwYXJzZXIgZXZlbnRzIGZyb20gYSBzdWJ0cmVlLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBUaGUgbm9kZSBJRC4KLSAgICAgICAgICogQHBhcmFtIGNoIEEgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGEgQ29udGVudEhhbmRsZXIuCi0gICAgICAgICAqCi0gICAgICAgICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAgICAgICAqLwotCi0gICAgICAgIHB1YmxpYyB2b2lkIGRpc3BhdGNoVG9FdmVudHMoaW50IG5vZGVIYW5kbGUsIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyIGNoKQotICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIHt9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFJldHVybiBhbiBET00gbm9kZSBmb3IgdGhlIGdpdmVuIG5vZGUuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBub2RlSGFuZGxlIFRoZSBub2RlIElELgotICAgICAgICAgKgotICAgICAgICAgKiBAcmV0dXJuIEEgbm9kZSByZXByZXNlbnRhdGlvbiBvZiB0aGUgRFRNIG5vZGUuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgb3JnLnczYy5kb20uTm9kZSBnZXROb2RlKGludCBub2RlSGFuZGxlKQotICAgICAgICB7Ci0gICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyA9PT09IENvbnN0cnVjdGlvbiBtZXRob2RzIChtYXkgbm90IGJlIHN1cHBvcnRlZCBieSBzb21lIGltcGxlbWVudGF0aW9ucyEpID09PT09Ci0gICAgICAgIC8vICVSRVZJRVclIGpqazogVGhlc2UgcHJvYmFibHkgYXJlbid0IHRoZSByaWdodCBBUEkuIEF0IHRoZSB2ZXJ5IGxlYXN0Ci0gICAgICAgIC8vIHRoZXkgbmVlZCB0byBkZWFsIHdpdGggY3VycmVudC1pbnNlcnRpb24tbG9jYXRpb24gYW5kIGVuZC1lbGVtZW50Ci0gICAgICAgIC8vIGlzc3Vlcy4KLQotICAgICAgICAvKioKLSAgICAgICAgICogQXBwZW5kIGEgY2hpbGQgdG8gdGhlIGVuZCBvZiB0aGUgY2hpbGQgbGlzdCBvZiB0aGUgY3VycmVudCBub2RlLiBQbGVhc2Ugbm90ZSB0aGF0IHRoZSBub2RlCi0gICAgICAgICAqIGlzIGFsd2F5cyBjbG9uZWQgaWYgaXQgaXMgb3duZWQgYnkgYW5vdGhlciBkb2N1bWVudC4KLSAgICAgICAgICoKLSAgICAgICAgICogPHA+JVJFVklFVyUgIkVuZCBvZiB0aGUgZG9jdW1lbnQiIG5lZWRzIHRvIGJlIGRlZmluZWQgbW9yZSBjbGVhcmx5LgotICAgICAgICAgKiBEb2VzIGl0IGJlY29tZSB0aGUgbGFzdCBjaGlsZCBvZiB0aGUgRG9jdW1lbnQ/IE9mIHRoZSByb290IGVsZW1lbnQ/PC9wPgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gbmV3Q2hpbGQgTXVzdCBiZSBhIHZhbGlkIG5ldyBub2RlIGhhbmRsZS4KLSAgICAgICAgICogQHBhcmFtIGNsb25lIHRydWUgaWYgdGhlIGNoaWxkIHNob3VsZCBiZSBjbG9uZWQgaW50byB0aGUgZG9jdW1lbnQuCi0gICAgICAgICAqIEBwYXJhbSBjbG9uZURlcHRoIGlmIHRoZSBjbG9uZSBhcmd1bWVudCBpcyB0cnVlLCBzcGVjaWZpZXMgdGhhdCB0aGUKLSAgICAgICAgICogICAgICAgICAgICAgICAgICAgY2xvbmUgc2hvdWxkIGluY2x1ZGUgYWxsIGl0J3MgY2hpbGRyZW4uCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgdm9pZCBhcHBlbmRDaGlsZChpbnQgbmV3Q2hpbGQsIGJvb2xlYW4gY2xvbmUsIGJvb2xlYW4gY2xvbmVEZXB0aCkgewotICAgICAgICAgICAgICAgIGJvb2xlYW4gc2FtZURvYyA9ICgobmV3Q2hpbGQgJiBET0NIQU5ETEVfTUFTSykgPT0gbV9kb2NIYW5kbGUpOwotICAgICAgICAgICAgICAgIGlmIChjbG9uZSB8fCAhc2FtZURvYykgewotCi0gICAgICAgICAgICAgICAgfSBlbHNlIHsKLQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBBcHBlbmQgYSB0ZXh0IG5vZGUgY2hpbGQgdGhhdCB3aWxsIGJlIGNvbnN0cnVjdGVkIGZyb20gYSBzdHJpbmcsCi0gICAgICAgICAqIHRvIHRoZSBlbmQgb2YgdGhlIGRvY3VtZW50LgotICAgICAgICAgKgotICAgICAgICAgKiA8cD4lUkVWSUVXJSAiRW5kIG9mIHRoZSBkb2N1bWVudCIgbmVlZHMgdG8gYmUgZGVmaW5lZCBtb3JlIGNsZWFybHkuCi0gICAgICAgICAqIERvZXMgaXQgYmVjb21lIHRoZSBsYXN0IGNoaWxkIG9mIHRoZSBEb2N1bWVudD8gT2YgdGhlIHJvb3QgZWxlbWVudD88L3A+Ci0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBzdHIgTm9uLW51bGwgcmVmZXJlbmNlIHRvIGEgc3RyaW5nLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIHZvaWQgYXBwZW5kVGV4dENoaWxkKFN0cmluZyBzdHIpIHsKLSAgICAgICAgICAgICAgICAvLyAjIyNzaHMgVGhpbmsgbW9yZSBhYm91dCBob3cgdGhpcyBkaWZmZXJzIGZyb20gY3JlYXRlVGV4dE5vZGUKLSAgICAgICAgICAvLyVUQkQlCi0gICAgICAgIH0KLQotCi0gIC8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICAvLyA9PT09IEJVSUxERVIgbWV0aG9kcyA9PT09Ci0gIC8vICVUQkQlIGpqazogU0hPVUxEIFBST0JBQkxZIEJFIElOTElORUQsIHVubGVzcyB3ZSB3YW50IHRvIHN1cHBvcnQKLSAgLy8gYm90aCBTQVgxIGFuZCBTQVgyIGFuZCBzaGFyZSB0aGlzIGxvZ2ljIGJldHdlZW4gdGhlbS4KLQotICAvKiogQXBwZW5kIGEgdGV4dCBjaGlsZCBhdCB0aGUgY3VycmVudCBpbnNlcnRpb24gcG9pbnQuIEFzc3VtZXMgdGhhdCB0aGUKLSAgICogYWN0dWFsIGNvbnRlbnQgb2YgdGhlIHRleHQgaGFzIHByZXZpb3VzbHkgYmVlbiBhcHBlbmRlZCB0byB0aGUgbV9jaGFyCi0gICAqIGJ1ZmZlciAoc2hhcmVkIHdpdGggdGhlIGJ1aWxkZXIpLgotICAgKgotICAgKiBAcGFyYW0gbV9jaGFyX2N1cnJlbnRfc3RhcnQgaW50IFN0YXJ0aW5nIG9mZnNldCBvZiBub2RlJ3MgY29udGVudCBpbiBtX2NoYXIuCi0gICAqIEBwYXJhbSBjb250ZW50TGVuZ3RoIGludCBMZW5ndGggb2Ygbm9kZSdzIGNvbnRlbnQgaW4gbV9jaGFyLgotICAgKiAqLwotICB2b2lkIGFwcGVuZFRleHRDaGlsZChpbnQgbV9jaGFyX2N1cnJlbnRfc3RhcnQsaW50IGNvbnRlbnRMZW5ndGgpCi0gIHsKLSAgICAvLyBjcmVhdGUgYSBUZXh0IE5vZGUKLSAgICAvLyAlVEJEJSBtYXkgYmUgcG9zc2libGUgdG8gY29tYmluZSB3aXRoIGFwcGVuZE5vZGUoKXRvIHJlcGxhY2UgdGhlIG5leHQgY2h1bmsgb2YgY29kZQotICAgIGludCB3MCA9IFRFWFRfTk9ERTsKLSAgICAvLyBXMTogUGFyZW50Ci0gICAgaW50IHcxID0gY3VycmVudFBhcmVudDsKLSAgICAvLyBXMjogU3RhcnQgcG9zaXRpb24gd2l0aGluIG1fY2hhcgotICAgIGludCB3MiA9IG1fY2hhcl9jdXJyZW50X3N0YXJ0OwotICAgIC8vIFczOiBMZW5ndGggb2YgdGhlIGZ1bGwgc3RyaW5nCi0gICAgaW50IHczID0gY29udGVudExlbmd0aDsKLQotICAgIGludCBvdXJzbG90ID0gYXBwZW5kTm9kZSh3MCwgdzEsIHcyLCB3Myk7Ci0gICAgcHJldmlvdXNTaWJsaW5nID0gb3Vyc2xvdDsKLSAgfQotCi0gIC8qKiBBcHBlbmQgYSBjb21tZW50IGNoaWxkIGF0IHRoZSBjdXJyZW50IGluc2VydGlvbiBwb2ludC4gQXNzdW1lcyB0aGF0IHRoZQotICAgKiBhY3R1YWwgY29udGVudCBvZiB0aGUgY29tbWVudCBoYXMgcHJldmlvdXNseSBiZWVuIGFwcGVuZGVkIHRvIHRoZSBtX2NoYXIKLSAgICogYnVmZmVyIChzaGFyZWQgd2l0aCB0aGUgYnVpbGRlcikuCi0gICAqCi0gICAqIEBwYXJhbSBtX2NoYXJfY3VycmVudF9zdGFydCBpbnQgU3RhcnRpbmcgb2Zmc2V0IG9mIG5vZGUncyBjb250ZW50IGluIG1fY2hhci4KLSAgICogQHBhcmFtIGNvbnRlbnRMZW5ndGggaW50IExlbmd0aCBvZiBub2RlJ3MgY29udGVudCBpbiBtX2NoYXIuCi0gICAqICovCi0gIHZvaWQgYXBwZW5kQ29tbWVudChpbnQgbV9jaGFyX2N1cnJlbnRfc3RhcnQsaW50IGNvbnRlbnRMZW5ndGgpCi0gIHsKLSAgICAvLyBjcmVhdGUgYSBDb21tZW50IE5vZGUKLSAgICAvLyAlVEJEJSBtYXkgYmUgcG9zc2libGUgdG8gY29tYmluZSB3aXRoIGFwcGVuZE5vZGUoKXRvIHJlcGxhY2UgdGhlIG5leHQgY2h1bmsgb2YgY29kZQotICAgIGludCB3MCA9IENPTU1FTlRfTk9ERTsKLSAgICAvLyBXMTogUGFyZW50Ci0gICAgaW50IHcxID0gY3VycmVudFBhcmVudDsKLSAgICAvLyBXMjogU3RhcnQgcG9zaXRpb24gd2l0aGluIG1fY2hhcgotICAgIGludCB3MiA9IG1fY2hhcl9jdXJyZW50X3N0YXJ0OwotICAgIC8vIFczOiBMZW5ndGggb2YgdGhlIGZ1bGwgc3RyaW5nCi0gICAgaW50IHczID0gY29udGVudExlbmd0aDsKLQotICAgIGludCBvdXJzbG90ID0gYXBwZW5kTm9kZSh3MCwgdzEsIHcyLCB3Myk7Ci0gICAgcHJldmlvdXNTaWJsaW5nID0gb3Vyc2xvdDsKLSAgfQotCi0KLSAgLyoqIEFwcGVuZCBhbiBFbGVtZW50IGNoaWxkIGF0IHRoZSBjdXJyZW50IGluc2VydGlvbiBwb2ludC4gVGhpcwotICAgKiBFbGVtZW50IHRoZW4gX2JlY29tZXNfIHRoZSBpbnNlcnRpb24gcG9pbnQ7IHN1YnNlcXVlbnQgYXBwZW5kcwotICAgKiBiZWNvbWUgaXRzIGxhc3RDaGlsZCB1bnRpbCBhbiBhcHBlbmRFbmRFbGVtZW50KCkgY2FsbCBpcyBtYWRlLgotICAgKgotICAgKiBBc3N1bWVzIHRoYXQgdGhlIHN5bWJvbHMgKGxvY2FsIG5hbWUsIG5hbWVzcGFjZSBVUkkgYW5kIHByZWZpeCkKLSAgICogaGF2ZSBhbHJlYWR5IGJlZW4gYWRkZWQgdG8gdGhlIHBvb2xzCi0gICAqCi0gICAqIE5vdGUgdGhhdCB0aGlzIF9vbmx5XyBoYW5kbGVzIHRoZSBFbGVtZW50IG5vZGUgaXRzZWxmLiBBdHRycyBhbmQKLSAgICogbmFtZXNwYWNlIG5vZGVzIGFyZSB1bmJ1bmRsZWQgaW4gdGhlIENvbnRlbnRIYW5kbGVyIGxheWVyCi0gICAqIGFuZCBhcHBlbmRlZCBzZXBhcmF0ZWx5LgotICAgKgotICAgKiBAcGFyYW0gbmFtZXNwYWNlSW5kZXg6IEluZGV4IHdpdGhpbiB0aGUgbmFtZXNwYWNlVVJJIHN0cmluZyBwb29sCi0gICAqIEBwYXJhbSBsb2NhbE5hbWVJbmRleCBJbmRleCB3aXRoaW4gdGhlIGxvY2FsIG5hbWUgc3RyaW5nIHBvb2wKLSAgICogQHBhcmFtIHByZWZpeEluZGV4OiBJbmRleCB3aXRoaW4gdGhlIHByZWZpeCBzdHJpbmcgcG9vbAotICAgKiAqLwotICB2b2lkIGFwcGVuZFN0YXJ0RWxlbWVudChpbnQgbmFtZXNwYWNlSW5kZXgsaW50IGxvY2FsTmFtZUluZGV4LCBpbnQgcHJlZml4SW5kZXgpCi0gIHsKLSAgICAgICAgICAgICAgICAvLyBkbyBkb2N1bWVudCByb290IG5vZGUgY3JlYXRpb24gaGVyZSBvbiB0aGUgZmlyc3QgZWxlbWVudCwgY3JlYXRlIG5vZGVzIGZvcgotICAgICAgICAgICAgICAgIC8vIHRoaXMgZWxlbWVudCBhbmQgaXRzIGF0dHJpYnV0ZXMsIHN0b3JlIHRoZSBlbGVtZW50LCBuYW1lc3BhY2UsIGFuZCBhdHRyaXR1dGUKLSAgICAgICAgICAgICAgICAvLyBuYW1lIGluZGV4ZXMgdG8gdGhlIG5vZGVzIGFycmF5LCBrZWVwIHRyYWNrIG9mIHRoZSBjdXJyZW50IG5vZGUgYW5kIHBhcmVudAotICAgICAgICAgICAgICAgIC8vIGVsZW1lbnQgdXNlZAotCi0gICAgICAgICAgICAgICAgLy8gVzAgIEhpZ2g6ICBOYW1lc3BhY2UgIExvdzogIE5vZGUgVHlwZQotICAgICAgICAgICAgICAgIGludCB3MCA9IChuYW1lc3BhY2VJbmRleCA8PCAxNikgfCBFTEVNRU5UX05PREU7Ci0gICAgICAgICAgICAgICAgLy8gVzE6IFBhcmVudAotICAgICAgICAgICAgICAgIGludCB3MSA9IGN1cnJlbnRQYXJlbnQ7Ci0gICAgICAgICAgICAgICAgLy8gVzI6IE5leHQgIChpbml0aWFsaXplZCBhcyAwKQotICAgICAgICAgICAgICAgIGludCB3MiA9IDA7Ci0gICAgICAgICAgICAgICAgLy8gVzM6IFRhZ25hbWUgaGlnaDogcHJlZml4IExvdzogbG9jYWwgbmFtZQotICAgICAgICAgICAgICAgIGludCB3MyA9IGxvY2FsTmFtZUluZGV4IHwgcHJlZml4SW5kZXg8PDE2OwotICAgICAgICAgICAgICAgIC8qKi9TeXN0ZW0ub3V0LnByaW50bG4oInNldCB3Mz0iK3czKyIgIisodzM+PjE2KSsiLyIrKHczJjB4ZmZmZikpOwotCi0gICAgICAgICAgICAgICAgLy9pbnQgb3Vyc2xvdCA9IG5vZGVzLmFwcGVuZFNsb3QodzAsIHcxLCB3MiwgdzMpOwotICAgICAgICAgICAgICAgIGludCBvdXJzbG90ID0gYXBwZW5kTm9kZSh3MCwgdzEsIHcyLCB3Myk7Ci0gICAgICAgICAgICAgICAgY3VycmVudFBhcmVudCA9IG91cnNsb3Q7Ci0gICAgICAgICAgICAgICAgcHJldmlvdXNTaWJsaW5nID0gMDsKLQotICAgICAgICAgICAgICAgIC8vIHNldCB0aGUgcm9vdCBlbGVtZW50IHBvaW50ZXIgd2hlbiBjcmVhdGluZyB0aGUgZmlyc3QgZWxlbWVudCBub2RlCi0gICAgICAgICAgICAgICAgaWYgKG1fZG9jRWxlbWVudCA9PSBOVUxMKQotICAgICAgICAgICAgICAgICAgICAgICAgbV9kb2NFbGVtZW50ID0gb3Vyc2xvdDsKLSAgfQotCi0gIC8qKiBBcHBlbmQgYSBOYW1lc3BhY2UgRGVjbGFyYXRpb24gY2hpbGQgYXQgdGhlIGN1cnJlbnQgaW5zZXJ0aW9uIHBvaW50LgotICAgKiBBc3N1bWVzIHRoYXQgdGhlIHN5bWJvbHMgKG5hbWVzcGFjZSBVUkkgYW5kIHByZWZpeCkgaGF2ZSBhbHJlYWR5IGJlZW4KLSAgICogYWRkZWQgdG8gdGhlIHBvb2xzCi0gICAqCi0gICAqIEBwYXJhbSBwcmVmaXhJbmRleDogSW5kZXggd2l0aGluIHRoZSBwcmVmaXggc3RyaW5nIHBvb2wKLSAgICogQHBhcmFtIG5hbWVzcGFjZUluZGV4OiBJbmRleCB3aXRoaW4gdGhlIG5hbWVzcGFjZVVSSSBzdHJpbmcgcG9vbAotICAgKiBAcGFyYW0gaXNJRDogSWYgc29tZW9uZSByZWFsbHkgaW5zaXN0cyBvbiB3cml0aW5nIGEgYmFkIERURCwgaXQgaXMKLSAgICogdGhlb3JldGljYWxseSBwb3NzaWJsZSBmb3IgYSBuYW1lc3BhY2UgZGVjbGFyYXRpb24gdG8gYWxzbyBiZSBkZWNsYXJlZAotICAgKiBhcyBiZWluZyBhIG5vZGUgSUQuIEkgZG9uJ3QgcmVhbGx5IHdhbnQgdG8gc3VwcG9ydCB0aGF0IHN0dXBpZGl0eSwKLSAgICogYnV0IEknbSBub3Qgc3VyZSB3ZSBjYW4gcmVmdXNlIHRvIGFjY2VwdCBpdC4KLSAgICogKi8KLSAgdm9pZCBhcHBlbmROU0RlY2xhcmF0aW9uKGludCBwcmVmaXhJbmRleCwgaW50IG5hbWVzcGFjZUluZGV4LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBpc0lEKQotICB7Ci0gICAgLy8gJVJFVklFVyUgSSdtIGFzc2lnbmluZyB0aGlzIG5vZGUgdGhlICJuYW1lc3BhY2UgZm9yIG5hbWVzcGFjZXMiCi0gICAgLy8gd2hpY2ggdGhlIERPTSBkZWZpbmVkLiBJdCBpcyBleHBlY3RlZCB0aGF0IHRoZSBOYW1lc3BhY2Ugc3BlYyB3aWxsCi0gICAgLy8gYWRvcHQgdGhpcyBhcyBvZmZpY2lhbC4gSXQgaXNuJ3Qgc3RyaWN0bHkgbmVlZGVkIHNpbmNlIGl0J3MgaW1wbGllZAotICAgIC8vIGJ5IHRoZSBub2RldHlwZSwgYnV0IGZvciBub3cuLi4KLQotICAgIC8vICVSRVZJRVclIFByZWZpeCBuZWVkIG5vdCBiZSByZWNvcmRlZDsgaXQncyBpbXBsaWVkIHRvby4gQnV0Ci0gICAgLy8gcmVjb3JkaW5nIGl0IG1pZ2h0IHNpbXBsaWZ5IHRoZSBkZXNpZ24uCi0KLSAgICAvLyAlVEJEJSBpc0lEIGlzIG5vdCBjdXJyZW50bHkgaG9ub3JlZC4KLQotICAgIGZpbmFsIGludCBuYW1lc3BhY2VGb3JOYW1lc3BhY2VzPW1fbnNOYW1lcy5zdHJpbmdUb0luZGV4KCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3htbG5zLyIpOwotCi0gICAgLy8gVzAgIEhpZ2g6ICBOYW1lc3BhY2UgIExvdzogIE5vZGUgVHlwZQotICAgIGludCB3MCA9IE5BTUVTUEFDRV9OT0RFIHwgKG1fbnNOYW1lcy5zdHJpbmdUb0luZGV4KCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3htbG5zLyIpPDwxNik7Ci0KLSAgICAvLyBXMTogIFBhcmVudAotICAgIGludCB3MSA9IGN1cnJlbnRQYXJlbnQ7Ci0gICAgLy8gVzI6ICBDVVJSRU5UTFkgVU5VU0VEIC0tIEl0J3MgbmV4dC1zaWIgaW4gYXR0cnMsIGJ1dCB3ZSBoYXZlIG5vIGtpZHMuCi0gICAgaW50IHcyID0gMDsKLSAgICAvLyBXMzogIG5hbWVzcGFjZSBuYW1lCi0gICAgaW50IHczID0gbmFtZXNwYWNlSW5kZXg7Ci0gICAgLy8gQWRkIG5vZGUKLSAgICBpbnQgb3Vyc2xvdCA9IGFwcGVuZE5vZGUodzAsIHcxLCB3MiwgdzMpOwotICAgIHByZXZpb3VzU2libGluZyA9IG91cnNsb3Q7ICAvLyBTaG91bGQgYXR0cmlidXRlcyBiZSBwcmV2aW91cyBzaWJsaW5ncwotICAgIHByZXZpb3VzU2libGluZ1dhc1BhcmVudCA9IGZhbHNlOwotICAgIHJldHVybiA7Ly8obV9kb2NIYW5kbGUgfCBvdXJzbG90KTsKLSAgfQotCi0gIC8qKiBBcHBlbmQgYW4gQXR0cmlidXRlIGNoaWxkIGF0IHRoZSBjdXJyZW50IGluc2VydGlvbgotICAgKiBwb2ludC4gIEFzc3VtZXMgdGhhdCB0aGUgc3ltYm9scyAobmFtZXNwYWNlIFVSSSwgbG9jYWwgbmFtZSwgYW5kCi0gICAqIHByZWZpeCkgaGF2ZSBhbHJlYWR5IGJlZW4gYWRkZWQgdG8gdGhlIHBvb2xzLCBhbmQgdGhhdCB0aGUgY29udGVudCBoYXMKLSAgICogYWxyZWFkeSBiZWVuIGFwcGVuZGVkIHRvIG1fY2hhci4gTm90ZSB0aGF0IHRoZSBhdHRyaWJ1dGUncyBjb250ZW50IGhhcwotICAgKiBiZWVuIGZsYXR0ZW5lZCBpbnRvIGEgc2luZ2xlIHN0cmluZzsgRFRNIGRvZXMgX05PVF8gYXR0ZW1wdCB0byBtb2RlbAotICAgKiB0aGUgZGV0YWlscyBvZiBlbnRpdHkgcmVmZXJlbmNlcyB3aXRoaW4gYXR0cmlidXRlIHZhbHVlcy4KLSAgICoKLSAgICogQHBhcmFtIG5hbWVzcGFjZUluZGV4IGludCBJbmRleCB3aXRoaW4gdGhlIG5hbWVzcGFjZVVSSSBzdHJpbmcgcG9vbAotICAgKiBAcGFyYW0gbG9jYWxOYW1lSW5kZXggaW50IEluZGV4IHdpdGhpbiB0aGUgbG9jYWwgbmFtZSBzdHJpbmcgcG9vbAotICAgKiBAcGFyYW0gcHJlZml4SW5kZXggaW50IEluZGV4IHdpdGhpbiB0aGUgcHJlZml4IHN0cmluZyBwb29sCi0gICAqIEBwYXJhbSBpc0lEIGJvb2xlYW4gVHJ1ZSBpZiB0aGlzIGF0dHJpYnV0ZSB3YXMgZGVjbGFyZWQgYXMgYW4gSUQKLSAgICogKGZvciB1c2UgaW4gc3VwcG9ydGluZyBnZXRFbGVtZW50QnlJRCkuCi0gICAqIEBwYXJhbSBtX2NoYXJfY3VycmVudF9zdGFydCBpbnQgU3RhcnRpbmcgb2Zmc2V0IG9mIG5vZGUncyBjb250ZW50IGluIG1fY2hhci4KLSAgICogQHBhcmFtIGNvbnRlbnRMZW5ndGggaW50IExlbmd0aCBvZiBub2RlJ3MgY29udGVudCBpbiBtX2NoYXIuCi0gICAqICovCi0gIHZvaWQgYXBwZW5kQXR0cmlidXRlKGludCBuYW1lc3BhY2VJbmRleCwgaW50IGxvY2FsTmFtZUluZGV4LCBpbnQgcHJlZml4SW5kZXgsCi0gICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gaXNJRCwKLSAgICAgICAgICAgICAgICAgICAgICAgaW50IG1fY2hhcl9jdXJyZW50X3N0YXJ0LCBpbnQgY29udGVudExlbmd0aCkKLSAgewotICAgIC8vICVUQkQlIGlzSUQgaXMgbm90IGN1cnJlbnRseSBob25vcmVkLgotCi0gICAgLy8gVzAgIEhpZ2g6ICBOYW1lc3BhY2UgIExvdzogIE5vZGUgVHlwZQotICAgIGludCB3MCA9IEFUVFJJQlVURV9OT0RFIHwgbmFtZXNwYWNlSW5kZXg8PDE2OwotCi0gICAgLy8gVzE6ICBQYXJlbnQKLSAgICBpbnQgdzEgPSBjdXJyZW50UGFyZW50OwotICAgIC8vIFcyOiAgTmV4dCAobm90IHlldCByZXNvbHZlZCkKLSAgICBpbnQgdzIgPSAwOwotICAgIC8vIFczOiAgVGFnbmFtZSBoaWdoOiBwcmVmaXggTG93OiBsb2NhbCBuYW1lCi0gICAgaW50IHczID0gbG9jYWxOYW1lSW5kZXggfCBwcmVmaXhJbmRleDw8MTY7Ci0gICAgLyoqL1N5c3RlbS5vdXQucHJpbnRsbigic2V0IHczPSIrdzMrIiAiKyh3Mz4+MTYpKyIvIisodzMmMHhmZmZmKSk7Ci0gICAgLy8gQWRkIG5vZGUKLSAgICBpbnQgb3Vyc2xvdCA9IGFwcGVuZE5vZGUodzAsIHcxLCB3MiwgdzMpOwotICAgIHByZXZpb3VzU2libGluZyA9IG91cnNsb3Q7ICAvLyBTaG91bGQgYXR0cmlidXRlcyBiZSBwcmV2aW91cyBzaWJsaW5ncwotCi0gICAgLy8gQXR0cmlidXRlJ3MgY29udGVudCBpcyBjdXJyZW50bHkgYXBwZW5kZWQgYXMgYSBUZXh0IE5vZGUKLQotICAgIC8vIFcwOiBOb2RlIFR5cGUKLSAgICB3MCA9IFRFWFRfTk9ERTsKLSAgICAvLyBXMTogUGFyZW50Ci0gICAgdzEgPSBvdXJzbG90OwotICAgIC8vIFcyOiBTdGFydCBQb3NpdGlvbiB3aXRoaW4gYnVmZmVyCi0gICAgdzIgPSBtX2NoYXJfY3VycmVudF9zdGFydDsKLSAgICAvLyBXMzogTGVuZ3RoCi0gICAgdzMgPSBjb250ZW50TGVuZ3RoOwotICAgIGFwcGVuZE5vZGUodzAsIHcxLCB3MiwgdzMpOwotCi0gICAgLy8gQXR0cnMgYXJlIFBhcmVudHMKLSAgICBwcmV2aW91c1NpYmxpbmdXYXNQYXJlbnQgPSB0cnVlOwotICAgIHJldHVybiA7Ly8obV9kb2NIYW5kbGUgfCBvdXJzbG90KTsKLSAgfQotCi0gIC8qKgotICAgKiBUaGlzIHJldHVybnMgYSBzdGF0ZWxlc3MgInRyYXZlcnNlciIsIHRoYXQgY2FuIG5hdmlnYXRlIG92ZXIgYW4KLSAgICogWFBhdGggYXhpcywgdGhvdWdoIG5vdCBpbiBkb2N1bWVudCBvcmRlci4KLSAgICoKLSAgICogQHBhcmFtIGF4aXMgT25lIG9mIEF4ZXMuQU5DRVNUT1JPUlNFTEYsIGV0Yy4KLSAgICoKLSAgICogQHJldHVybiBBIERUTUF4aXNJdGVyYXRvciwgb3IgbnVsbCBpZiB0aGUgZ2l2ZW4gYXhpcyBpc24ndCBzdXBwb3J0ZWQuCi0gICAqLwotICBwdWJsaWMgRFRNQXhpc1RyYXZlcnNlciBnZXRBeGlzVHJhdmVyc2VyKGZpbmFsIGludCBheGlzKQotICB7Ci0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogVGhpcyBpcyBhIHNob3J0Y3V0IHRvIHRoZSBpdGVyYXRvcnMgdGhhdCBpbXBsZW1lbnQgdGhlCi0gICAqIHN1cHBvcnRlZCBYUGF0aCBheGVzIChvbmx5IG5hbWVzcGFjZTo6KSBpcyBub3Qgc3VwcG9ydGVkLgotICAgKiBSZXR1cm5zIGEgYmFyZS1ib25lcyBpdGVyYXRvciB0aGF0IG11c3QgYmUgaW5pdGlhbGl6ZWQKLSAgICogd2l0aCBhIHN0YXJ0IG5vZGUgKHVzaW5nIGl0ZXJhdG9yLnNldFN0YXJ0Tm9kZSgpKS4KLSAgICoKLSAgICogQHBhcmFtIGF4aXMgT25lIG9mIEF4ZXMuQU5DRVNUT1JPUlNFTEYsIGV0Yy4KLSAgICoKLSAgICogQHJldHVybiBBIERUTUF4aXNJdGVyYXRvciwgb3IgbnVsbCBpZiB0aGUgZ2l2ZW4gYXhpcyBpc24ndCBzdXBwb3J0ZWQuCi0gICAqLwotICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIGdldEF4aXNJdGVyYXRvcihmaW5hbCBpbnQgYXhpcykKLSAgewotICAgIC8vICVUQkQlCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IGFuIGl0ZXJhdG9yIHRoYXQgY2FuIG5hdmlnYXRlIG92ZXIgYW4gWFBhdGggQXhpcywgcHJlZGljYXRlZCBieQotICAgKiB0aGUgZXh0ZW5kZWQgdHlwZSBJRC4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIGF4aXMKLSAgICogQHBhcmFtIHR5cGUgQW4gZXh0ZW5kZWQgdHlwZSBJRC4KLSAgICoKLSAgICogQHJldHVybiBBIERUTUF4aXNJdGVyYXRvciwgb3IgbnVsbCBpZiB0aGUgZ2l2ZW4gYXhpcyBpc24ndCBzdXBwb3J0ZWQuCi0gICAqLwotICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIGdldFR5cGVkQXhpc0l0ZXJhdG9yKGZpbmFsIGludCBheGlzLCBmaW5hbCBpbnQgdHlwZSkKLSAgewotICAgIC8vICVUQkQlCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotCi0gIC8qKiBUZXJtaW5hdGUgdGhlIGVsZW1lbnQgY3VycmVudGx5IGFjdGluZyBhcyBhbiBpbnNlcnRpb24gcG9pbnQuIFN1YnNlcXVlbnQKLSAgICogaW5zZXJ0aW9ucyB3aWxsIG9jY3VyIGFzIHRoZSBsYXN0IGNoaWxkIG9mIHRoaXMgZWxlbWVudCdzIHBhcmVudC4KLSAgICogKi8KLSAgdm9pZCBhcHBlbmRFbmRFbGVtZW50KCkKLSAgewotICAgIC8vIHBvcCB1cCB0aGUgc3RhY2tzCi0KLSAgICBpZiAocHJldmlvdXNTaWJsaW5nV2FzUGFyZW50KQotICAgICAgbm9kZXMud3JpdGVFbnRyeShwcmV2aW91c1NpYmxpbmcsIDIsIE5VTEwpOwotCi0gICAgLy8gUG9wIHBhcmVudGFnZQotICAgIHByZXZpb3VzU2libGluZyA9IGN1cnJlbnRQYXJlbnQ7Ci0gICAgbm9kZXMucmVhZFNsb3QoY3VycmVudFBhcmVudCwgZ290c2xvdCk7Ci0gICAgY3VycmVudFBhcmVudCA9IGdvdHNsb3RbMV0gJiAweEZGRkY7Ci0KLSAgICAvLyBUaGUgZWxlbWVudCBqdXN0IGJlaW5nIGZpbmlzaGVkIHdpbGwgYmUKLSAgICAvLyB0aGUgcHJldmlvdXMgc2libGluZyBmb3IgdGhlIG5leHQgb3BlcmF0aW9uCi0gICAgcHJldmlvdXNTaWJsaW5nV2FzUGFyZW50ID0gdHJ1ZTsKLQotICAgIC8vIFBvcCBhIGxldmVsIG9mIG5hbWVzcGFjZSB0YWJsZQotICAgIC8vIG5hbWVzcGFjZVRhYmxlLnJlbW92ZUxhc3RFbGVtKCk7Ci0gIH0KLQotICAvKiogIFN0YXJ0aW5nIGEgbmV3IGRvY3VtZW50LiBQZXJmb3JtIGFueSByZXNldHMvaW5pdGlhbGl6YXRpb24KLSAgICogbm90IGFscmVhZHkgaGFuZGxlZC4KLSAgICogKi8KLSAgdm9pZCBhcHBlbmRTdGFydERvY3VtZW50KCkKLSAgewotCi0gICAgLy8gJVRCRCUgcmVzZXQgc2xvdCAwIHRvIGluZGljYXRlIENodW5rZWRJbnRBcnJheSByZXVzZSBvciB3YWl0IGZvcgotICAgIC8vICAgICAgIHRoZSBuZXh0IGluaXREb2N1bWVudCgpLgotICAgIG1fZG9jRWxlbWVudCA9IE5VTEw7ICAgICAgICAgLy8gcmVzZXQgbm9kZUhhbmRsZSB0byB0aGUgcm9vdCBvZiB0aGUgYWN0dWFsIGR0bSBkb2MgY29udGVudAotICAgIGluaXREb2N1bWVudCgwKTsKLSAgfQotCi0gIC8qKiAgQWxsIGFwcGVuZHMgdG8gdGhpcyBkb2N1bWVudCBoYXZlIGZpbmlzaGVkOyBkbyB3aGF0ZXZlciBmaW5hbAotICAgKiBjbGVhbnVwIGlzIG5lZWRlZC4KLSAgICogKi8KLSAgdm9pZCBhcHBlbmRFbmREb2N1bWVudCgpCi0gIHsKLSAgICBkb25lID0gdHJ1ZTsKLSAgICAvLyAlVEJEJSBtYXkgbmVlZCB0byBub3RpY2UgdGhlIGxhc3Qgc2xvdCBudW1iZXIgYW5kIHNsb3QgY291bnQgdG8gYXZvaWQKLSAgICAvLyByZXNpZHVhbCBkYXRhIGZyb20gcHJvdmlvdXMgdXNlIG9mIHRoaXMgRFRNCi0gIH0KLQotICAvKioKLSAgICogRm9yIHRoZSBtb21lbnQgYWxsIHRoZSBydW4gdGltZSBwcm9wZXJ0aWVzIGFyZSBpZ25vcmVkIGJ5IHRoaXMKLSAgICogY2xhc3MuCi0gICAqCi0gICAqIEBwYXJhbSBwcm9wZXJ0eSBhIDxjb2RlPlN0cmluZzwvY29kZT4gdmFsdWUKLSAgICogQHBhcmFtIHZhbHVlIGFuIDxjb2RlPk9iamVjdDwvY29kZT4gdmFsdWUKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFByb3BlcnR5KFN0cmluZyBwcm9wZXJ0eSwgT2JqZWN0IHZhbHVlKQotICB7Ci0gIH0KLQotICAvKioKLSAgICogU291cmNlIGluZm9ybWF0aW9uIGlzIG5vdCBoYW5kbGVkIHlldCwgc28gcmV0dXJuCi0gICAqIDxjb2RlPm51bGw8L2NvZGU+IGhlcmUuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlIGFuIDxjb2RlPmludDwvY29kZT4gdmFsdWUKLSAgICogQHJldHVybiBudWxsCi0gICAqLwotICBwdWJsaWMgU291cmNlTG9jYXRvciBnZXRTb3VyY2VMb2NhdG9yRm9yKGludCBub2RlKQotICB7Ci0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBBIGR1bW15IHJvdXRpbmUgdG8gc2F0aXNpZnkgdGhlIGFic3RyYWN0IGludGVyZmFjZS4gSWYgdGhlIERUTQotICAgKiBpbXBsZW1lbXRhdGlvbiB0aGF0IGV4dGVuZHMgdGhlIGRlZmF1bHQgYmFzZSByZXF1aXJlcyBub3RpZmljYXRpb24KLSAgICogb2YgcmVnaXN0cmF0aW9uLCB0aGV5IGNhbiBvdmVycmlkZSB0aGlzIG1ldGhvZC4KLSAgICovCi0gICBwdWJsaWMgdm9pZCBkb2N1bWVudFJlZ2lzdHJhdGlvbigpCi0gICB7Ci0gICB9Ci0KLSAgLyoqCi0gICAqIEEgZHVtbXkgcm91dGluZSB0byBzYXRpc2lmeSB0aGUgYWJzdHJhY3QgaW50ZXJmYWNlLiBJZiB0aGUgRFRNCi0gICAqIGltcGxlbWVtdGF0aW9uIHRoYXQgZXh0ZW5kcyB0aGUgZGVmYXVsdCBiYXNlIHJlcXVpcmVzIG5vdGlmaWNhdGlvbgotICAgKiB3aGVuIHRoZSBkb2N1bWVudCBpcyBiZWluZyByZWxlYXNlZCwgdGhleSBjYW4gb3ZlcnJpZGUgdGhpcyBtZXRob2QKLSAgICovCi0gICBwdWJsaWMgdm9pZCBkb2N1bWVudFJlbGVhc2UoKQotICAgewotICAgfQotCi0gICAvKioKLSAgICAqIE1pZ3JhdGUgYSBEVE0gYnVpbHQgd2l0aCBhbiBvbGQgRFRNTWFuYWdlciB0byBhIG5ldyBEVE1NYW5hZ2VyLgotICAgICogQWZ0ZXIgdGhlIG1pZ3JhdGlvbiwgdGhlIG5ldyBEVE1NYW5hZ2VyIHdpbGwgdHJlYXQgdGhlIERUTSBhcwotICAgICogb25lIHRoYXQgaXMgYnVpbHQgYnkgaXRzZWxmLgotICAgICogVGhpcyBpcyB1c2VkIHRvIHN1cHBvcnQgRFRNIHNoYXJpbmcgYmV0d2VlbiBtdWx0aXBsZSB0cmFuc2Zvcm1hdGlvbnMuCi0gICAgKiBAcGFyYW0gbWFuYWdlciB0aGUgRFRNTWFuYWdlcgotICAgICovCi0gICBwdWJsaWMgdm9pZCBtaWdyYXRlVG8oRFRNTWFuYWdlciBtYW5hZ2VyKQotICAgewotICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vcmVmL0RUTU1hbmFnZXJEZWZhdWx0LmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vcmVmL0RUTU1hbmFnZXJEZWZhdWx0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDlmOTNmODAuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL3JlZi9EVE1NYW5hZ2VyRGVmYXVsdC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsODYxICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IERUTU1hbmFnZXJEZWZhdWx0LmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTUgMDg6MTU6MDIgc3VyZXNoX2VtYWlsaWQgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5yZWY7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwudXRpbHMuRmFjdG9yeUltcGw7Ci1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyOwotaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlckZhY3Rvcnk7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2U7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5kb20uRE9NU291cmNlOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlNBWFNvdXJjZTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbS5TdHJlYW1Tb3VyY2U7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE07Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTUZpbHRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1JdGVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1NYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTVdTRmlsdGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLnJlZi5kb20yZHRtLkRPTTJEVE07Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0ucmVmLnNheDJkdG0uU0FYMkRUTTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5yZWYuc2F4MmR0bS5TQVgyUlRGRFRNOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzLlhNTEVycm9yUmVzb3VyY2VzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzLlhNTE1lc3NhZ2VzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuUHJlZml4UmVzb2x2ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5TeXN0ZW1JRFJlc29sdmVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuWE1MUmVhZGVyTWFuYWdlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLlhNTFN0cmluZ0ZhY3Rvcnk7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotCi1pbXBvcnQgb3JnLnhtbC5zYXguSW5wdXRTb3VyY2U7Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LlhNTFJlYWRlcjsKLWltcG9ydCBvcmcueG1sLnNheC5oZWxwZXJzLkRlZmF1bHRIYW5kbGVyOwotCi0vKioKLSAqIFRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIGZvciB0aGUgRFRNTWFuYWdlci4KLSAqCi0gKiAlUkVWSUVXJSBUaGVyZSBpcyBjdXJyZW50bHkgYSByZWVudHJhbmN5IGlzc3VlLCBzaW5jZSB0aGUgZmluYWxpemVyCi0gKiBmb3IgWFJUcmVlRnJhZyAod2hpY2ggcnVucyBpbiB0aGUgR0MgdGhyZWFkKSB3YW50cyB0byBjYWxsCi0gKiBEVE1NYW5hZ2VyLnJlbGVhc2UoKSwgYW5kIG1heSBkbyBzbyBhdCB0aGUgc2FtZSB0aW1lIHRoYXQgdGhlIG1haW4KLSAqIHRyYW5zZm9ybWF0aW9uIHRocmVhZCBpcyBhY2Nlc3NpbmcgdGhlIG1hbmFnZXIuIE91ciBjdXJyZW50IHNvbHV0aW9uIGlzCi0gKiB0byBtYWtlIG1vc3Qgb2YgdGhlIG1hbmFnZXIncyBtZXRob2RzIDxjb2RlPnN5bmNocm9uaXplZDwvY29kZT4uCi0gKiBFYXJseSB0ZXN0cyBzdWdnZXN0IHRoYXQgZG9pbmcgc28gaXMgbm90IGNhdXNpbmcgYSBzaWduaWZpY2FudAotICogcGVyZm9ybWFuY2UgaGl0IGluIFhhbGFuLiBIb3dldmVyLCBpdCBzaG91bGQgYmUgbm90ZWQgdGhhdCB0aGVyZQotICogaXMgYSBwb3NzaWJsZSBhbHRlcm5hdGl2ZSBzb2x1dGlvbjogcmV3cml0ZSByZWxlYXNlKCkgc28gaXQgbWVyZWx5Ci0gKiBwb3N0cyBhIHJlcXVlc3QgZm9yIHJlbGVhc2Ugb250byBhIHRocmVhZHNhZmUgcXVldWUsIGFuZCBleHBsaWNpdGx5Ci0gKiBwcm9jZXNzIHRoYXQgcXVldWUgb24gYW4gaW5mcmVxdWVudCBiYXNpcyBkdXJpbmcgbWFpbi10aHJlYWQKLSAqIGFjdGl2aXR5IChlZywgd2hlbiBnZXREVE0oKSBpcyBpbnZva2VkKS4gVGhlIGRvd25zaWRlIG9mIHRoYXQgc29sdXRpb24KLSAqIHdvdWxkIGJlIGEgZ3JlYXRlciBkZWxheSBiZWZvcmUgdGhlIERUTSdzIHN0b3JhZ2UgaXMgYWN0dWFsbHkgcmVsZWFzZWQKLSAqIGZvciByZXVzZS4KLSAqICovCi1wdWJsaWMgY2xhc3MgRFRNTWFuYWdlckRlZmF1bHQgZXh0ZW5kcyBEVE1NYW5hZ2VyCi17Ci0gIC8vc3RhdGljIGZpbmFsIGJvb2xlYW4gSktFU1NfWE5JX0VYUEVSSU1FTlQ9dHJ1ZTsKLQotICAvKiogU2V0IHRoaXMgdG8gdHJ1ZSBpZiB5b3Ugd2FudCBhIGR1bXAgb2YgdGhlIERUTSBhZnRlciBjcmVhdGlvbi4gKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbiBEVU1QVFJFRSA9IGZhbHNlOwotCi0gIC8qKiBTZXQgdGhpcyB0byB0cnVlIGlmIHlvdSB3YW50IGEgYmFzaWMgZGlhZ25vc3RpY3MuICovCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW4gREVCVUcgPSBmYWxzZTsKLQotICAvKioKLSAgICogTWFwIGZyb20gRFRNIGlkZW50aWZpZXIgbnVtYmVycyB0byBEVE0gb2JqZWN0cyB0aGF0IHRoaXMgbWFuYWdlciBtYW5hZ2VzLgotICAgKiBPbmUgRFRNIG1heSBoYXZlIHNldmVyYWwgcHJlZml4IG51bWJlcnMsIGlmIGV4dGVuZGVkIG5vZGUgaW5kZXhpbmcKLSAgICogaXMgaW4gdXNlOyBpbiB0aGF0IGNhc2UsIG1fZHRtX29mZnNldHNbXSB3aWxsIHVzZWQgdG8gY29udHJvbCB3aGljaAotICAgKiBwcmVmaXggbWFwcyB0byB3aGljaCBzZWN0aW9uIG9mIHRoZSBEVE0uCi0gICAqCi0gICAqIFRoaXMgYXJyYXkgZ3Jvd3MgYXMgbmVjZXNzYXJ5OyBzZWUgYWRkRFRNKCkuCi0gICAqCi0gICAqIFRoaXMgYXJyYXkgZ3Jvd3MgYXMgbmVjZXNzYXJ5OyBzZWUgYWRkRFRNKCkuIEdyb3d0aCBpcyB1bmNvbW1vbi4uLiBidXQKLSAgICogYWNjZXNzIG5lZWRzIHRvIGJlIGJsaW5kaW5nbHkgZmFzdCBzaW5jZSBpdCdzIHVzZWQgaW4gbm9kZSBhZGRyZXNzaW5nLgotICAgKi8KLSAgcHJvdGVjdGVkIERUTSBtX2R0bXNbXSA9IG5ldyBEVE1bMjU2XTsKLQotICAvKiogTWFwIGZyb20gRFRNIGlkZW50aWZpZXIgbnVtYmVycyB0byBvZmZzZXRzLiBGb3Igc21hbGwgRFRNcyB3aXRoIGEKLSAgICogc2luZ2xlIGlkZW50aWZpZXIsIHRoaXMgd2lsbCBhbHdheXMgYmUgMC4gSW4gb3ZlcmZsb3cgYWRkcmVzc2luZywgd2hlcmUKLSAgICogYWRkaXRpb25hbCBpZGVudGlmaWVycyBhcmUgYWxsb2NhdGVkIHRvIGFjY2VzcyBub2RlcyBiZXlvbmQgdGhlIHJhbmdlIG9mCi0gICAqIGEgc2luZ2xlIE5vZGUgSGFuZGxlLCB0aGlzIHRhYmxlIGlzIHVzZWQgdG8gbWFwIHRoZSBoYW5kbGUncyBub2RlIGZpZWxkCi0gICAqIGludG8gdGhlIGFjdHVhbCBub2RlIGlkZW50aWZpZXIuCi0gICAqCi0gICAqIFRoaXMgYXJyYXkgZ3Jvd3MgYXMgbmVjZXNzYXJ5OyBzZWUgYWRkRFRNKCkuCi0gICAqCi0gICAqIFRoaXMgYXJyYXkgZ3Jvd3MgYXMgbmVjZXNzYXJ5OyBzZWUgYWRkRFRNKCkuIEdyb3d0aCBpcyB1bmNvbW1vbi4uLiBidXQKLSAgICogYWNjZXNzIG5lZWRzIHRvIGJlIGJsaW5kaW5nbHkgZmFzdCBzaW5jZSBpdCdzIHVzZWQgaW4gbm9kZSBhZGRyZXNzaW5nLgotICAgKiAoQW5kIGF0IHRoZSBtb21lbnQsIHRoYXQgaW5jbHVkZXMgYWNjZXNzaW5nIGl0IGZyb20gRFRNRGVmYXVsdEJhc2UsCi0gICAqIHdoaWNoIGlzIHdoeSB0aGlzIGlzIG5vdCBQcm90ZWN0ZWQgb3IgUHJpdmF0ZS4pCi0gICAqLwotICBpbnQgbV9kdG1fb2Zmc2V0c1tdID0gbmV3IGludFsyNTZdOwotCi0gIC8qKgotICAgKiBUaGUgY2FjaGUgZm9yIFhNTFJlYWRlciBvYmplY3RzIHRvIGJlIHVzZWQgaWYgdGhlIHVzZXIgZGlkIG5vdAotICAgKiBzdXBwbHkgYW4gWE1MUmVhZGVyIGZvciBhIFNBWFNvdXJjZSBvciBzdXBwbGllZCBhIFN0cmVhbVNvdXJjZS4KLSAgICovCi0gIHByb3RlY3RlZCBYTUxSZWFkZXJNYW5hZ2VyIG1fcmVhZGVyTWFuYWdlciA9IG51bGw7Ci0KLSAgLyoqCi0gICAqIFRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIG9mIENvbnRlbnRIYW5kbGVyLCBEVERIYW5kbGVyIGFuZCBFcnJvckhhbmRsZXIuCi0gICAqLwotICBwcm90ZWN0ZWQgRGVmYXVsdEhhbmRsZXIgbV9kZWZhdWx0SGFuZGxlciA9IG5ldyBEZWZhdWx0SGFuZGxlcigpOwotCi0gIC8qKgotICAgKiBBZGQgYSBEVE0gdG8gdGhlIERUTSB0YWJsZS4gVGhpcyBjb252ZW5pZW5jZSBjYWxsIGFkZHMgaXQgYXMgdGhlCi0gICAqICJiYXNlIERUTSBJRCIsIHdpdGggb2Zmc2V0IDAuIFRoZSBvdGhlciB2ZXJzaW9uIG9mIGFkZERUTSBzaG91bGQKLSAgICogYmUgdXNlZCBpZiB5b3Ugd2FudCB0byBhZGQgImV4dGVuZGVkIiBEVE0gSURzIHdpdGggbm9uemVybyBvZmZzZXRzLgotICAgKgotICAgKiBAcGFyYW0gZHRtIFNob3VsZCBiZSBhIHZhbGlkIHJlZmVyZW5jZSB0byBhIERUTS4KLSAgICogQHBhcmFtIGlkIEludGVnZXIgRFRNIElEIHRvIGJlIGJvdW5kIHRvIHRoaXMgRFRNCi0gICAqLwotICBzeW5jaHJvbml6ZWQgcHVibGljIHZvaWQgYWRkRFRNKERUTSBkdG0sIGludCBpZCkgeyAgICBhZGREVE0oZHRtLGlkLDApOyB9Ci0KLQotICAvKioKLSAgICogQWRkIGEgRFRNIHRvIHRoZSBEVE0gdGFibGUuCi0gICAqCi0gICAqIEBwYXJhbSBkdG0gU2hvdWxkIGJlIGEgdmFsaWQgcmVmZXJlbmNlIHRvIGEgRFRNLgotICAgKiBAcGFyYW0gaWQgSW50ZWdlciBEVE0gSUQgdG8gYmUgYm91bmQgdG8gdGhpcyBEVE0uCi0gICAqIEBwYXJhbSBvZmZzZXQgSW50ZWdlciBhZGRyZXNzaW5nIG9mZnNldC4gVGhlIGludGVybmFsIERUTSBOb2RlIElEIGlzCi0gICAqIG9idGFpbmVkIGJ5IGFkZGluZyB0aGlzIG9mZnNldCB0byB0aGUgbm9kZS1udW1iZXIgZmllbGQgb2YgdGhlCi0gICAqIHB1YmxpYyBEVE0gSGFuZGxlLiBGb3IgdGhlIGZpcnN0IERUTSBJRCBhY2Nlc3NpbmcgZWFjaCBEVE0sIHRoaXMgaXMgMDsKLSAgICogZm9yIG92ZXJmbG93IGFkZHJlc3NpbmcgaXQgd2lsbCBiZSBhIG11bHRpcGxlIG9mIDE8PElERU5UX0RUTV9OT0RFX0JJVFMuCi0gICAqLwotICBzeW5jaHJvbml6ZWQgcHVibGljIHZvaWQgYWRkRFRNKERUTSBkdG0sIGludCBpZCwgaW50IG9mZnNldCkKLSAgewotICAgICAgICAgICAgICAgIGlmKGlkPj1JREVOVF9NQVhfRFRNUykKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBUT0RPOiAlUkVWSUVXJSBOb3QgcmVhbGx5IHRoZSByaWdodCBlcnJvciBtZXNzYWdlLgotICAgICAgICAgICAgdGhyb3cgbmV3IERUTUV4Y2VwdGlvbihYTUxNZXNzYWdlcy5jcmVhdGVYTUxNZXNzYWdlKFhNTEVycm9yUmVzb3VyY2VzLkVSX05PX0RUTUlEU19BVkFJTCwgbnVsbCkpOyAvLyJObyBtb3JlIERUTSBJRHMgYXJlIGF2YWlsYWJsZSEiKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyBXZSB1c2VkIHRvIGp1c3QgYWxsb2NhdGUgdGhlIGFycmF5IHNpemUgdG8gSURFTlRfTUFYX0RUTVMuCi0gICAgICAgICAgICAgICAgLy8gQnV0IHdlIGV4cGVjdCB0byBpbmNyZWFzZSB0aGF0IHRvIDE2IGJpdHMsIGFuZCBJJ20gbm90IHdpbGxpbmcKLSAgICAgICAgICAgICAgICAvLyB0byBhbGxvY2F0ZSB0aGF0IG11Y2ggc3BhY2UgdW5sZXNzIG5lZWRlZC4gV2UgY291bGQgdXNlIG9uZSBvZiBvdXIKLSAgICAgICAgICAgICAgICAvLyBoYW5keS1kYW5keSBGYXN0KlZlY3RvcnMsIGJ1dCB0aGlzIHdpbGwgZG8gZm9yIG5vdy4KLSAgICAgICAgICAgICAgICAvLyAlUkVWSUVXJQotICAgICAgICAgICAgICAgIGludCBvbGRsZW49bV9kdG1zLmxlbmd0aDsKLSAgICAgICAgICAgICAgICBpZihvbGRsZW48PWlkKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIFZhcmlvdXMgZ3Jvd3RoIHN0cmF0ZWdpZXMgYXJlIHBvc3NpYmxlLiBJIHRoaW5rIHdlIGRvbid0IHdhbnQKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRvIG92ZXItYWxsb2NhdGUgZXhjZXNzaXZlbHksIGFuZCBJJ20gd2lsbGluZyB0byByZWFsbG9jYXRlCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBtb3JlIG9mdGVuIHRvIGdldCB0aGF0LiBTZWUgYWxzbyBGYXN0KlZlY3RvciBjbGFzc2VzLgotICAgICAgICAgICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vICVSRVZJRVclIFNob3VsZCB0aHJvdyBhIG1vcmUgZGlhZ25vc3RpYyBlcnJvciBpZiB3ZSBnbyBvdmVyIHRoZSBtYXguLi4KLSAgICAgICAgICAgICAgICAgICAgICAgIGludCBuZXdsZW49TWF0aC5taW4oKGlkKzI1NiksSURFTlRfTUFYX0RUTVMpOwotCi0gICAgICAgICAgICAgICAgICAgICAgICBEVE0gbmV3X21fZHRtc1tdID0gbmV3IERUTVtuZXdsZW5dOwotICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShtX2R0bXMsMCxuZXdfbV9kdG1zLDAsb2xkbGVuKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIG1fZHRtcz1uZXdfbV9kdG1zOwotICAgICAgICAgICAgICAgICAgICAgICAgaW50IG5ld19tX2R0bV9vZmZzZXRzW10gPSBuZXcgaW50W25ld2xlbl07Ci0gICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KG1fZHRtX29mZnNldHMsMCxuZXdfbV9kdG1fb2Zmc2V0cywwLG9sZGxlbik7Ci0gICAgICAgICAgICAgICAgICAgICAgICBtX2R0bV9vZmZzZXRzPW5ld19tX2R0bV9vZmZzZXRzOwotICAgICAgICAgICAgICAgIH0KLQotICAgIG1fZHRtc1tpZF0gPSBkdG07Ci0gICAgICAgICAgICAgICAgbV9kdG1fb2Zmc2V0c1tpZF09b2Zmc2V0OwotICAgIGR0bS5kb2N1bWVudFJlZ2lzdHJhdGlvbigpOwotICAgICAgICAgICAgICAgIC8vIFRoZSBEVE0gc2hvdWxkIGhhdmUgYmVlbiB0b2xkIHdobyBpdHMgbWFuYWdlciB3YXMgd2hlbiB3ZSBjcmVhdGVkIGl0LgotICAgICAgICAgICAgICAgIC8vIERvIHdlIG5lZWQgdG8gYWxsb3cgZm9yIGFkb3B0aW5nIERUTXMgX25vdF8gY3JlYXRlZCBieSB0aGlzIG1hbmFnZXI/Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBmaXJzdCBmcmVlIERUTSBJRCBhdmFpbGFibGUuICVPUFQlIExpbmVhciBzZWFyY2ggaXMgaW5lZmZpY2llbnQhCi0gICAqLwotICBzeW5jaHJvbml6ZWQgcHVibGljIGludCBnZXRGaXJzdEZyZWVEVE1JRCgpCi0gIHsKLSAgICBpbnQgbiA9IG1fZHRtcy5sZW5ndGg7Ci0gICAgZm9yIChpbnQgaSA9IDE7IGkgPCBuOyBpKyspCi0gICAgewotICAgICAgaWYobnVsbCA9PSBtX2R0bXNbaV0pCi0gICAgICB7Ci0gICAgICAgIHJldHVybiBpOwotICAgICAgfQotICAgIH0KLSAgICAgICAgICAgICAgICByZXR1cm4gbjsgLy8gY291bnQgb24gYWRkRFRNKCkgdG8gdGhyb3cgZXhjZXB0aW9uIGlmIG91dCBvZiByYW5nZQotICB9Ci0KLSAgLyoqCi0gICAqIFRoZSBkZWZhdWx0IHRhYmxlIGZvciBleGFuZGVkTmFtZUlEIGxvb2t1cHMuCi0gICAqLwotICBwcml2YXRlIEV4cGFuZGVkTmFtZVRhYmxlIG1fZXhwYW5kZWROYW1lVGFibGUgPQotICAgIG5ldyBFeHBhbmRlZE5hbWVUYWJsZSgpOwotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3RvciBEVE1NYW5hZ2VyRGVmYXVsdAotICAgKgotICAgKi8KLSAgcHVibGljIERUTU1hbmFnZXJEZWZhdWx0KCl7fQotCi0KLSAgLyoqCi0gICAqIEdldCBhbiBpbnN0YW5jZSBvZiBhIERUTSwgbG9hZGVkIHdpdGggdGhlIGNvbnRlbnQgZnJvbSB0aGUKLSAgICogc3BlY2lmaWVkIHNvdXJjZS4gIElmIHRoZSB1bmlxdWUgZmxhZyBpcyB0cnVlLCBhIG5ldyBpbnN0YW5jZSB3aWxsCi0gICAqIGFsd2F5cyBiZSByZXR1cm5lZC4gIE90aGVyd2lzZSBpdCBpcyB1cCB0byB0aGUgRFRNTWFuYWdlciB0byByZXR1cm4gYQotICAgKiBuZXcgaW5zdGFuY2Ugb3IgYW4gaW5zdGFuY2UgdGhhdCBpdCBhbHJlYWR5IGNyZWF0ZWQgYW5kIG1heSBiZSBiZWluZyB1c2VkCi0gICAqIGJ5IHNvbWVvbmUgZWxzZS4KLSAgICoKLSAgICogQSBiaXQgb2YgbWFnaWMgaW4gdGhpcyBpbXBsZW1lbnRhdGlvbjogSWYgdGhlIHNvdXJjZSBpcyBudWxsLCB1bmlxdWUgaXMgdHJ1ZSwKLSAgICogYW5kIGluY3JlbWVudGFsIGFuZCBkb0luZGV4aW5nIGFyZSBib3RoIGZhbHNlLCB3ZSByZXR1cm4gYW4gaW5zdGFuY2Ugb2YKLSAgICogU0FYMlJURkRUTSwgd2hpY2ggc2VlLgotICAgKgotICAgKiAoSSB0aGluayBtb3JlIHBhcmFtZXRlcnMgd2lsbCBuZWVkIHRvIGJlIGFkZGVkIGZvciBlcnJvciBoYW5kbGluZywgYW5kIGVudGl0eQotICAgKiByZXNvbHV0aW9uLCBhbmQgbW9yZSBleHBsaWNpdCBjb250cm9sIG9mIHRoZSBSVEYgc2l0dWF0aW9uKS4KLSAgICoKLSAgICogQHBhcmFtIHNvdXJjZSB0aGUgc3BlY2lmaWNhdGlvbiBvZiB0aGUgc291cmNlIG9iamVjdC4KLSAgICogQHBhcmFtIHVuaXF1ZSB0cnVlIGlmIHRoZSByZXR1cm5lZCBEVE0gbXVzdCBiZSB1bmlxdWUsIHByb2JhYmx5IGJlY2F1c2UgaXQKLSAgICogaXMgZ29pbmcgdG8gYmUgbXV0YXRlZC4KLSAgICogQHBhcmFtIHdoaXRlU3BhY2VGaWx0ZXIgRW5hYmxlcyBmaWx0ZXJpbmcgb2Ygd2hpdGVzcGFjZSBub2RlcywgYW5kIG1heQotICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBiZSBudWxsLgotICAgKiBAcGFyYW0gaW5jcmVtZW50YWwgdHJ1ZSBpZiB0aGUgRFRNIHNob3VsZCBiZSBidWlsdCBpbmNyZW1lbnRhbGx5LCBpZgotICAgKiAgICAgICAgICAgICAgICAgICAgcG9zc2libGUuCi0gICAqIEBwYXJhbSBkb0luZGV4aW5nIHRydWUgaWYgdGhlIGNhbGxlciBjb25zaWRlcnMgaXQgd29ydGggaXQgdG8gdXNlCi0gICAqICAgICAgICAgICAgICAgICAgIGluZGV4aW5nIHNjaGVtZXMuCi0gICAqCi0gICAqIEByZXR1cm4gYSBub24tbnVsbCBEVE0gcmVmZXJlbmNlLgotICAgKi8KLSAgc3luY2hyb25pemVkIHB1YmxpYyBEVE0gZ2V0RFRNKFNvdXJjZSBzb3VyY2UsIGJvb2xlYW4gdW5pcXVlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFRNV1NGaWx0ZXIgd2hpdGVTcGFjZUZpbHRlciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gaW5jcmVtZW50YWwsIGJvb2xlYW4gZG9JbmRleGluZykKLSAgewotCi0gICAgaWYoREVCVUcgJiYgbnVsbCAhPSBzb3VyY2UpCi0gICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlN0YXJ0aW5nICIrCi0gICAgICAgICAgICAgICAgICAgICAgICAgKHVuaXF1ZSA/ICJVTklRVUUiIDogInNoYXJlZCIpKwotICAgICAgICAgICAgICAgICAgICAgICAgICIgc291cmNlOiAiK3NvdXJjZS5nZXRTeXN0ZW1JZCgpCi0gICAgICAgICAgICAgICAgICAgICAgICAgKTsKLQotICAgIFhNTFN0cmluZ0ZhY3RvcnkgeHN0cmluZ0ZhY3RvcnkgPSBtX3hzZjsKLSAgICBpbnQgZHRtUG9zID0gZ2V0Rmlyc3RGcmVlRFRNSUQoKTsKLSAgICBpbnQgZG9jdW1lbnRJRCA9IGR0bVBvcyA8PCBJREVOVF9EVE1fTk9ERV9CSVRTOwotCi0gICAgaWYgKChudWxsICE9IHNvdXJjZSkgJiYgc291cmNlIGluc3RhbmNlb2YgRE9NU291cmNlKQotICAgIHsKLSAgICAgIERPTTJEVE0gZHRtID0gbmV3IERPTTJEVE0odGhpcywgKERPTVNvdXJjZSkgc291cmNlLCBkb2N1bWVudElELAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGl0ZVNwYWNlRmlsdGVyLCB4c3RyaW5nRmFjdG9yeSwgZG9JbmRleGluZyk7Ci0KLSAgICAgIGFkZERUTShkdG0sIGR0bVBvcywgMCk7Ci0KLSAgICAgIC8vICAgICAgaWYgKERVTVBUUkVFKQotICAgICAgLy8gICAgICB7Ci0gICAgICAvLyAgICAgICAgZHRtLmR1bXBEVE0oKTsKLSAgICAgIC8vICAgICAgfQotCi0gICAgICByZXR1cm4gZHRtOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgYm9vbGVhbiBpc1NBWFNvdXJjZSA9IChudWxsICE9IHNvdXJjZSkKLSAgICAgICAgPyAoc291cmNlIGluc3RhbmNlb2YgU0FYU291cmNlKSA6IHRydWU7Ci0gICAgICBib29sZWFuIGlzU3RyZWFtU291cmNlID0gKG51bGwgIT0gc291cmNlKQotICAgICAgICA/IChzb3VyY2UgaW5zdGFuY2VvZiBTdHJlYW1Tb3VyY2UpIDogZmFsc2U7Ci0KLSAgICAgIGlmIChpc1NBWFNvdXJjZSB8fCBpc1N0cmVhbVNvdXJjZSkgewotICAgICAgICBYTUxSZWFkZXIgcmVhZGVyID0gbnVsbDsKLSAgICAgICAgU0FYMkRUTSBkdG07Ci0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICBJbnB1dFNvdXJjZSB4bWxTb3VyY2U7Ci0KLSAgICAgICAgICBpZiAobnVsbCA9PSBzb3VyY2UpIHsKLSAgICAgICAgICAgIHhtbFNvdXJjZSA9IG51bGw7Ci0gICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIHJlYWRlciA9IGdldFhNTFJlYWRlcihzb3VyY2UpOwotICAgICAgICAgICAgeG1sU291cmNlID0gU0FYU291cmNlLnNvdXJjZVRvSW5wdXRTb3VyY2Uoc291cmNlKTsKLQotICAgICAgICAgICAgU3RyaW5nIHVybE9mU291cmNlID0geG1sU291cmNlLmdldFN5c3RlbUlkKCk7Ci0KLSAgICAgICAgICAgIGlmIChudWxsICE9IHVybE9mU291cmNlKSB7Ci0gICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgdXJsT2ZTb3VyY2UgPSBTeXN0ZW1JRFJlc29sdmVyLmdldEFic29sdXRlVVJJKHVybE9mU291cmNlKTsKLSAgICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICAvLyAlUkVWSUVXJSBJcyB0aGVyZSBhIGJldHRlciB3YXkgdG8gc2VuZCBhIHdhcm5pbmc/Ci0gICAgICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJDYW4gbm90IGFic29sdXRpemUgVVJMOiAiICsgdXJsT2ZTb3VyY2UpOwotICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgeG1sU291cmNlLnNldFN5c3RlbUlkKHVybE9mU291cmNlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICB9Ci0KLSAgICAgICAgICBpZiAoc291cmNlPT1udWxsICYmIHVuaXF1ZSAmJiAhaW5jcmVtZW50YWwgJiYgIWRvSW5kZXhpbmcpIHsKLSAgICAgICAgICAgIC8vIFNwZWNpYWwgY2FzZSB0byBzdXBwb3J0IFJURiBjb25zdHJ1Y3Rpb24gaW50byBzaGFyZWQgRFRNLgotICAgICAgICAgICAgLy8gSXQgc2hvdWxkIGFjdHVhbGx5IHN0aWxsIHdvcmsgZm9yIG90aGVyIHVzZXMsCi0gICAgICAgICAgICAvLyBidXQgbWF5IGJlIHNsaWdodGx5IGRlb3B0aW1pemVkIHJlbGF0aXZlIHRvIHRoZSBiYXNlCi0gICAgICAgICAgICAvLyB0byBhbGxvdyBpdCB0byBkZWFsIHdpdGggY2FycnlpbmcgbXVsdGlwbGUgZG9jdW1lbnRzLgotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIC8vICVSRVZJRVclIFRoaXMgaXMgYSBzbG9wcHkgd2F5IHRvIHJlcXVlc3QgdGhpcyBtb2RlOwotICAgICAgICAgICAgLy8gd2UgbmVlZCB0byBjb25zaWRlciBhcmNoaXRlY3R1cmFsIGltcHJvdmVtZW50cy4KLSAgICAgICAgICAgIGR0bSA9IG5ldyBTQVgyUlRGRFRNKHRoaXMsIHNvdXJjZSwgZG9jdW1lbnRJRCwgd2hpdGVTcGFjZUZpbHRlciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhzdHJpbmdGYWN0b3J5LCBkb0luZGV4aW5nKTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0gICAgICAgICAgLy8gRVhQRVJJTUVOVEFMIDMvMjIvMDIKLSAgICAgICAgICBlbHNlIGlmKEpLRVNTX1hOSV9FWFBFUklNRU5UICYmIG1faW5jcmVtZW50YWwpIHsKLSAgICAgICAgICAgIGR0bSA9IG5ldyBYTkkyRFRNKHRoaXMsIHNvdXJjZSwgZG9jdW1lbnRJRCwgd2hpdGVTcGFjZUZpbHRlciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhzdHJpbmdGYWN0b3J5LCBkb0luZGV4aW5nKTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi0gICAgICAgICAgLy8gQ3JlYXRlIHRoZSBiYXNpYyBTQVgyRFRNLgotICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgZHRtID0gbmV3IFNBWDJEVE0odGhpcywgc291cmNlLCBkb2N1bWVudElELCB3aGl0ZVNwYWNlRmlsdGVyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeHN0cmluZ0ZhY3RvcnksIGRvSW5kZXhpbmcpOwotICAgICAgICAgIH0KLQotICAgICAgICAgIC8vIEdvIGFoZWFkIGFuZCBhZGQgdGhlIERUTSB0byB0aGUgbG9va3VwIHRhYmxlLiAgVGhpcyBuZWVkcyB0byBiZQotICAgICAgICAgIC8vIGRvbmUgYmVmb3JlIGFueSBwYXJzaW5nIG9jY3Vycy4gTm90ZSBvZmZzZXQgMCwgc2luY2Ugd2UndmUganVzdAotICAgICAgICAgIC8vIGNyZWF0ZWQgYSBuZXcgRFRNLgotICAgICAgICAgIGFkZERUTShkdG0sIGR0bVBvcywgMCk7Ci0KLQotICAgICAgICAgIGJvb2xlYW4gaGF2ZVhlcmNlc1BhcnNlciA9Ci0gICAgICAgICAgICAgICAgICAgICAobnVsbCAhPSByZWFkZXIpCi0gICAgICAgICAgICAgICAgICAgICAmJiAocmVhZGVyLmdldENsYXNzKCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0TmFtZSgpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmVxdWFscygiY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5wYXJzZXJzLlNBWFBhcnNlciIpICk7Ci0KLSAgICAgICAgICBpZiAoaGF2ZVhlcmNlc1BhcnNlcikgewotICAgICAgICAgICAgaW5jcmVtZW50YWwgPSB0cnVlOyAgLy8gTm8gbWF0dGVyIHdoYXQuICAlUkVWSUVXJQotICAgICAgICAgIH0KLQotICAgICAgICAgIC8vIElmIHRoZSByZWFkZXIgaXMgbnVsbCwgYnV0IHRoZXkgc3RpbGwgcmVxdWVzdGVkIGFuIGluY3JlbWVudGFsCi0gICAgICAgICAgLy8gYnVpbGQsIHRoZW4gd2Ugc3RpbGwgd2FudCB0byBzZXQgdXAgdGhlIEluY3JlbWVudGFsU0FYU291cmNlIHN0dWZmLgotICAgICAgICAgIGlmIChtX2luY3JlbWVudGFsICYmIGluY3JlbWVudGFsCi0gICAgICAgICAgICAgICAvKiB8fCAoKG51bGwgPT0gcmVhZGVyKSAmJiBpbmNyZW1lbnRhbCkgKi8pIHsKLSAgICAgICAgICAgIEluY3JlbWVudGFsU0FYU291cmNlIGNvUGFyc2VyPW51bGw7Ci0KLSAgICAgICAgICAgIGlmIChoYXZlWGVyY2VzUGFyc2VyKSB7Ci0gICAgICAgICAgICAgIC8vIEluY3JlbWVudGFsU0FYU291cmNlX1hlcmNlcyB0byBhdm9pZCB0aHJlYWRpbmcuCi0gICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgY29QYXJzZXIgPShJbmNyZW1lbnRhbFNBWFNvdXJjZSkKLSAgICAgICAgICAgICAgICAgIENsYXNzLmZvck5hbWUoImNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLnJlZi5JbmNyZW1lbnRhbFNBWFNvdXJjZV9YZXJjZXMiKS5uZXdJbnN0YW5jZSgpOwotICAgICAgICAgICAgICB9ICBjYXRjaCggRXhjZXB0aW9uIGV4ICkgewotICAgICAgICAgICAgICAgIGV4LnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgICAgICAgICAgIGNvUGFyc2VyPW51bGw7Ci0gICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKGNvUGFyc2VyPT1udWxsICkgewotICAgICAgICAgICAgICAvLyBDcmVhdGUgYSBJbmNyZW1lbnRhbFNBWFNvdXJjZSB0byBydW4gb24gdGhlIHNlY29uZGFyeSB0aHJlYWQuCi0gICAgICAgICAgICAgIGlmIChudWxsID09IHJlYWRlcikgewotICAgICAgICAgICAgICAgIGNvUGFyc2VyID0gbmV3IEluY3JlbWVudGFsU0FYU291cmNlX0ZpbHRlcigpOwotICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIEluY3JlbWVudGFsU0FYU291cmNlX0ZpbHRlciBmaWx0ZXIgPQotICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBJbmNyZW1lbnRhbFNBWFNvdXJjZV9GaWx0ZXIoKTsKLSAgICAgICAgICAgICAgICBmaWx0ZXIuc2V0WE1MUmVhZGVyKHJlYWRlcik7Ci0gICAgICAgICAgICAgICAgY29QYXJzZXI9ZmlsdGVyOwotICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLQotICAgICAgICAgICAgLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0gICAgICAgICAgICAvLyBFWFBFUklNRU5UQUwgMy8yMi8wMgotICAgICAgICAgICAgaWYgKEpLRVNTX1hOSV9FWFBFUklNRU5UICYmIG1faW5jcmVtZW50YWwgJiYKLSAgICAgICAgICAgICAgICAgIGR0bSBpbnN0YW5jZW9mIFhOSTJEVE0gJiYKLSAgICAgICAgICAgICAgICAgIGNvUGFyc2VyIGluc3RhbmNlb2YgSW5jcmVtZW50YWxTQVhTb3VyY2VfWGVyY2VzKSB7Ci0gICAgICAgICAgICAgICAgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTFB1bGxQYXJzZXJDb25maWd1cmF0aW9uIHhwYz0KLSAgICAgICAgICAgICAgICAgICAgICAoKEluY3JlbWVudGFsU0FYU291cmNlX1hlcmNlcyljb1BhcnNlcikKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0WE5JUGFyc2VyQ29uZmlndXJhdGlvbigpOwotICAgICAgICAgICAgICBpZiAoeHBjIT1udWxsKSB7Ci0gICAgICAgICAgICAgICAgLy8gQnlwYXNzIFNBWDsgbGlzdGVuIHRvIHRoZSBYTkkgc3RyZWFtCi0gICAgICAgICAgICAgICAgKChYTkkyRFRNKWR0bSkuc2V0SW5jcmVtZW50YWxYTklTb3VyY2UoeHBjKTsKLSAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgIC8vIExpc3RlbiB0byB0aGUgU0FYIHN0cmVhbSAod2lsbCBmYWlsLCBkaWFnbm9zdGljYWxseS4uLikKLSAgICAgICAgICAgICAgICBkdG0uc2V0SW5jcmVtZW50YWxTQVhTb3VyY2UoY29QYXJzZXIpOwotICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9IGVsc2UKLSAgICAgICAgICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLQotICAgICAgICAgICAgLy8gSGF2ZSB0aGUgRFRNIHNldCBpdHNlbGYgdXAgYXMgSW5jcmVtZW50YWxTQVhTb3VyY2UncyBsaXN0ZW5lci4KLSAgICAgICAgICAgIGR0bS5zZXRJbmNyZW1lbnRhbFNBWFNvdXJjZShjb1BhcnNlcik7Ci0KLSAgICAgICAgICAgIGlmIChudWxsID09IHhtbFNvdXJjZSkgewotCi0gICAgICAgICAgICAgIC8vIFRoZW4gdGhlIHVzZXIgd2lsbCBjb25zdHJ1Y3QgaXQgdGhlbXNlbHZlcy4KLSAgICAgICAgICAgICAgcmV0dXJuIGR0bTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKG51bGwgPT0gcmVhZGVyLmdldEVycm9ySGFuZGxlcigpKSB7Ci0gICAgICAgICAgICAgIHJlYWRlci5zZXRFcnJvckhhbmRsZXIoZHRtKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJlYWRlci5zZXREVERIYW5kbGVyKGR0bSk7Ci0KLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgIC8vIExhdW5jaCBwYXJzaW5nIGNvcm91dGluZS4gIExhdW5jaGVzIGEgc2Vjb25kIHRocmVhZCwKLSAgICAgICAgICAgICAgLy8gaWYgd2UncmUgdXNpbmcgSW5jcmVtZW50YWxTQVhTb3VyY2UuZmlsdGVyKCkuCi0KLSAgICAgICAgICAgICAgY29QYXJzZXIuc3RhcnRQYXJzZSh4bWxTb3VyY2UpOwotICAgICAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiByZSkgewotCi0gICAgICAgICAgICAgIGR0bS5jbGVhckNvUm91dGluZSgpOwotCi0gICAgICAgICAgICAgIHRocm93IHJlOwotICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKLQotICAgICAgICAgICAgICBkdG0uY2xlYXJDb1JvdXRpbmUoKTsKLQotICAgICAgICAgICAgICB0aHJvdyBuZXcgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5XcmFwcGVkUnVudGltZUV4Y2VwdGlvbihlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgaWYgKG51bGwgPT0gcmVhZGVyKSB7Ci0KLSAgICAgICAgICAgICAgLy8gVGhlbiB0aGUgdXNlciB3aWxsIGNvbnN0cnVjdCBpdCB0aGVtc2VsdmVzLgotICAgICAgICAgICAgICByZXR1cm4gZHRtOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBub3QgaW5jcmVtZW50YWwKLSAgICAgICAgICAgIHJlYWRlci5zZXRDb250ZW50SGFuZGxlcihkdG0pOwotICAgICAgICAgICAgcmVhZGVyLnNldERUREhhbmRsZXIoZHRtKTsKLSAgICAgICAgICAgIGlmIChudWxsID09IHJlYWRlci5nZXRFcnJvckhhbmRsZXIoKSkgewotICAgICAgICAgICAgICByZWFkZXIuc2V0RXJyb3JIYW5kbGVyKGR0bSk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgIHJlYWRlci5zZXRQcm9wZXJ0eSgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiaHR0cDovL3htbC5vcmcvc2F4L3Byb3BlcnRpZXMvbGV4aWNhbC1oYW5kbGVyIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkdG0pOwotICAgICAgICAgICAgfSBjYXRjaCAoU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiBlKXt9Ci0gICAgICAgICAgICAgIGNhdGNoIChTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gZSl7fQotCi0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICByZWFkZXIucGFyc2UoeG1sU291cmNlKTsKLSAgICAgICAgICAgIH0gY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gcmUpIHsKLSAgICAgICAgICAgICAgZHRtLmNsZWFyQ29Sb3V0aW5lKCk7Ci0KLSAgICAgICAgICAgICAgdGhyb3cgcmU7Ci0gICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICBkdG0uY2xlYXJDb1JvdXRpbmUoKTsKLQotICAgICAgICAgICAgICB0aHJvdyBuZXcgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5XcmFwcGVkUnVudGltZUV4Y2VwdGlvbihlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICB9Ci0KLSAgICAgICAgICBpZiAoRFVNUFRSRUUpIHsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiRHVtcGluZyBTQVgyRE9NIik7Ci0gICAgICAgICAgICBkdG0uZHVtcERUTShTeXN0ZW0uZXJyKTsKLSAgICAgICAgICB9Ci0KLSAgICAgICAgICByZXR1cm4gZHRtOwotICAgICAgICB9IGZpbmFsbHkgewotICAgICAgICAgIC8vIFJlc2V0IHRoZSBDb250ZW50SGFuZGxlciwgRFRESGFuZGxlciwgRXJyb3JIYW5kbGVyIHRvIHRoZSBEZWZhdWx0SGFuZGxlcgotICAgICAgICAgIC8vIGFmdGVyIGNyZWF0aW5nIHRoZSBEVE0uCi0gICAgICAgICAgaWYgKHJlYWRlciAhPSBudWxsICYmICEobV9pbmNyZW1lbnRhbCAmJiBpbmNyZW1lbnRhbCkpIHsKLSAgICAgICAgICAgIHJlYWRlci5zZXRDb250ZW50SGFuZGxlcihtX2RlZmF1bHRIYW5kbGVyKTsKLSAgICAgICAgICAgIHJlYWRlci5zZXREVERIYW5kbGVyKG1fZGVmYXVsdEhhbmRsZXIpOwotICAgICAgICAgICAgcmVhZGVyLnNldEVycm9ySGFuZGxlcihtX2RlZmF1bHRIYW5kbGVyKTsKLQotICAgICAgICAgICAgLy8gUmVzZXQgdGhlIExleGljYWxIYW5kbGVyIHRvIG51bGwgYWZ0ZXIgY3JlYXRpbmcgdGhlIERUTS4KLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgIHJlYWRlci5zZXRQcm9wZXJ0eSgiaHR0cDovL3htbC5vcmcvc2F4L3Byb3BlcnRpZXMvbGV4aWNhbC1oYW5kbGVyIiwgbnVsbCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGUpIHt9Ci0gICAgICAgICAgfQotICAgICAgICAgIHJlbGVhc2VYTUxSZWFkZXIocmVhZGVyKTsKLSAgICAgICAgfQotICAgICAgfSBlbHNlIHsKLQotICAgICAgICAvLyBJdCBzaG91bGQgaGF2ZSBiZWVuIGhhbmRsZWQgYnkgYSBkZXJpdmVkIGNsYXNzIG9yIHRoZSBjYWxsZXIKLSAgICAgICAgLy8gbWFkZSBhIG1pc3Rha2UuCi0gICAgICAgIHRocm93IG5ldyBEVE1FeGNlcHRpb24oWE1MTWVzc2FnZXMuY3JlYXRlWE1MTWVzc2FnZShYTUxFcnJvclJlc291cmNlcy5FUl9OT1RfU1VQUE9SVEVELCBuZXcgT2JqZWN0W117c291cmNlfSkpOyAvLyJOb3Qgc3VwcG9ydGVkOiAiICsgc291cmNlKTsKLSAgICAgIH0KLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYSBXM0MgRE9NIG5vZGUsIHRyeSBhbmQgcmV0dXJuIGEgRFRNIGhhbmRsZS4KLSAgICogTm90ZTogY2FsbGluZyB0aGlzIG1heSBiZSBub24tb3B0aW1hbCwgYW5kIHRoZXJlIGlzIG5vIGd1YXJhbnRlZSB0aGF0Ci0gICAqIHRoZSBub2RlIHdpbGwgYmUgZm91bmQgaW4gYW55IHBhcnRpY3VsYXIgRFRNLgotICAgKgotICAgKiBAcGFyYW0gbm9kZSBOb24tbnVsbCByZWZlcmVuY2UgdG8gYSBET00gbm9kZS4KLSAgICoKLSAgICogQHJldHVybiBhIHZhbGlkIERUTSBoYW5kbGUuCi0gICAqLwotICBzeW5jaHJvbml6ZWQgcHVibGljIGludCBnZXREVE1IYW5kbGVGcm9tTm9kZShvcmcudzNjLmRvbS5Ob2RlIG5vZGUpCi0gIHsKLSAgICBpZihudWxsID09IG5vZGUpCi0gICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKFhNTE1lc3NhZ2VzLmNyZWF0ZVhNTE1lc3NhZ2UoWE1MRXJyb3JSZXNvdXJjZXMuRVJfTk9ERV9OT05fTlVMTCwgbnVsbCkpOyAvLyJub2RlIG11c3QgYmUgbm9uLW51bGwgZm9yIGdldERUTUhhbmRsZUZyb21Ob2RlISIpOwotCi0gICAgaWYgKG5vZGUgaW5zdGFuY2VvZiBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5yZWYuRFRNTm9kZVByb3h5KQotICAgICAgcmV0dXJuICgoY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0ucmVmLkRUTU5vZGVQcm94eSkgbm9kZSkuZ2V0RFRNTm9kZU51bWJlcigpOwotCi0gICAgZWxzZQotICAgIHsKLSAgICAgIC8vIEZpbmQgdGhlIERPTTJEVE1zIHdyYXBwZWQgYXJvdW5kIHRoaXMgRG9jdW1lbnQgKGlmIGFueSkKLSAgICAgIC8vIGFuZCBjaGVjayB3aGV0aGVyIHRoZXkgY29udGFpbiB0aGUgTm9kZSBpbiBxdWVzdGlvbi4KLSAgICAgIC8vCi0gICAgICAvLyBOT1RFIHRoYXQgc2luY2UgYSBET00yRFRNIG1heSByZXByZXNlbnQgYSBzdWJ0cmVlIHJhdGhlcgotICAgICAgLy8gdGhhbiBhIGZ1bGwgZG9jdW1lbnQsIHdlIGhhdmUgdG8gYmUgcHJlcGFyZWQgdG8gY2hlY2sgbW9yZQotICAgICAgLy8gdGhhbiBvbmUgLS0gYW5kIHRoZXJlIGlzIG5vIGd1YXJhbnRlZSB0aGF0IHdlIHdpbGwgZmluZAotICAgICAgLy8gb25lIHRoYXQgY29udGFpbnMgYW5jZXN0b3JzIG9yIHNpYmxpbmdzIG9mIHRoZSBub2RlIHdlJ3JlCi0gICAgICAvLyBzZWVraW5nLgotICAgICAgLy8KLSAgICAgIC8vICVSRVZJRVclIFdlIGNvdWxkIHNlYXJjaCBmb3IgdGhlIG9uZSB3aGljaCBjb250YWlucyB0aGlzCi0gICAgICAvLyBub2RlIGF0IHRoZSBkZWVwZXN0IGxldmVsLCBhbmQgdGh1cyBjb3ZlcnMgdGhlIHdpZGVzdAotICAgICAgLy8gc3VidHJlZSwgYnV0IHRoYXQncyBnb2luZyB0byBlbnRhaWwgYWRkaXRpb25hbCB3b3JrCi0gICAgICAvLyBjaGVja2luZyBtb3JlIERUTXMuLi4gYW5kIGdldEhhbmRsZU9mTm9kZSBpcyBub3QgYQotICAgICAgLy8gY2hlYXAgb3BlcmF0aW9uIGluIG1vc3QgaW1wbGVtZW50YXRpb25zLgotICAgICAgICAgICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRPRE86ICVSRVZJRVclIElmIG92ZXJmbG93IGFkZHJlc3NpbmcsIHdlIG1heSByZWNoZWNrIGEgRFRNCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBhbHJlYWR5IGV4YW1pbmVkLiBPdWNoLiBCdXQgd2l0aCB0aGUgaW5jcmVhc2VkIG51bWJlciBvZiBEVE1zLAotICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2Nhbm5pbmcgYmFjayB0byBjaGVjayB0aGlzIGlzIHBhaW5mdWwuCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBQT1NTSUJMRSBTT0xVVElPTlM6Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyAgIEdlbmVyYXRlIGEgbGlzdCBvZiBfdW5pcXVlXyBEVE0gb2JqZWN0cz8KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgSGF2ZSBlYWNoIERUTSBjYWNoZSBsYXN0IERPTSBub2RlIHNlYXJjaD8KLSAgICAgICAgICAgICAgICAgICAgICAgIGludCBtYXggPSBtX2R0bXMubGVuZ3RoOwotICAgICAgZm9yKGludCBpID0gMDsgaSA8IG1heDsgaSsrKQotICAgICAgICB7Ci0gICAgICAgICAgRFRNIHRoaXNEVE09bV9kdG1zW2ldOwotICAgICAgICAgIGlmKChudWxsICE9IHRoaXNEVE0pICYmIHRoaXNEVE0gaW5zdGFuY2VvZiBET00yRFRNKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGludCBoYW5kbGU9KChET00yRFRNKXRoaXNEVE0pLmdldEhhbmRsZU9mTm9kZShub2RlKTsKLSAgICAgICAgICAgIGlmKGhhbmRsZSE9RFRNLk5VTEwpIHJldHVybiBoYW5kbGU7Ci0gICAgICAgICAgfQotICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBOb3QgZm91bmQ7IGdlbmVyYXRlIGEgbmV3IERUTS4KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyAlUkVWSUVXJSBJcyB0aGlzIHJlYWxseSBkZXNpcmFibGUsIG9yIHNob3VsZCB3ZSByZXR1cm4gbnVsbAotICAgICAgICAgICAgICAgICAgICAgICAgLy8gYW5kIG1ha2UgZm9sa3MgZXhwbGljaXRseSBpbnN0YW50aWF0ZSBmcm9tIGEgRE9NU291cmNlPyBUaGUKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGxhdHRlciBpcyBtb3JlIHdvcmsgYnV0IGdpdmVzIHRoZSBjYWxsZXIgdGhlIG9wcG9ydHVuaXR5IHRvCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBleHBsaWNpdGx5IGFkZCB0aGUgRFRNIHRvIGEgRFRNTWFuYWdlci4uLiBhbmQgdGh1cyB0byBrbm93IHdoZW4KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGl0IGNhbiBiZSBkaXNjYXJkZWQgYWdhaW4sIHdoaWNoIGlzIHNvbWV0aGluZyB3ZSBuZWVkIHRvIHBheSBtdWNoCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBtb3JlIGF0dGVudGlvbiB0by4gKEVzcGVjaWFsbHkgc2luY2Ugb25seSBEVE1zIHdoaWNoIGFyZSBhc3NpZ25lZAotICAgICAgICAgICAgICAgICAgICAgICAgLy8gdG8gYSBtYW5hZ2VyIGNhbiB1c2UgdGhlIG92ZXJmbG93IGFkZHJlc3Npbmcgc2NoZW1lLikKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyAlQlVHJSBJZiB0aGUgc291cmNlIG5vZGUgd2FzIGEgRE9NMkRUTSRkZWZhdWx0TmFtZXNwYWNlRGVjbGFyYXRpb25Ob2RlCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBhbmQgdGhlIERUTSB3YXNuJ3QgcmVnaXN0ZXJlZCB3aXRoIHRoaXMgRFRNTWFuYWdlciwgd2Ugd2lsbCBjcmVhdGUKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGEgbmV3IERUTSBhbmQgX3N0aWxsXyBub3QgYmUgYWJsZSB0byBmaW5kIHRoZSBub2RlIChzaW5jZSBpdCB3aWxsCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBiZSByZXN5bnRoZXNpemVkKS4gQW5vdGhlciByZWFzb24gdG8gcHVzaCBoYXJkIG9uIG1ha2luZyBhbGwgRFRNcwotICAgICAgICAgICAgICAgICAgICAgICAgLy8gYmUgbWFuYWdlZCBEVE1zLgotCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBTaW5jZSB0aGUgcmVhbCByb290IG9mIG91ciB0cmVlIG1heSBiZSBhIERvY3VtZW50RnJhZ21lbnQsIHdlIG5lZWQgdG8KLSAgICAgIC8vIHVzZSBnZXRQYXJlbnQgdG8gZmluZCB0aGUgcm9vdCwgaW5zdGVhZCBvZiBnZXRPd25lckRvY3VtZW50LiAgT3RoZXJ3aXNlCi0gICAgICAvLyBET00yRFRNI2dldEhhbmRsZU9mTm9kZSB3aWxsIGJlIHZlcnkgdW5oYXBweS4KLSAgICAgIE5vZGUgcm9vdCA9IG5vZGU7Ci0gICAgICBOb2RlIHAgPSAocm9vdC5nZXROb2RlVHlwZSgpID09IE5vZGUuQVRUUklCVVRFX05PREUpID8gKChvcmcudzNjLmRvbS5BdHRyKXJvb3QpLmdldE93bmVyRWxlbWVudCgpIDogcm9vdC5nZXRQYXJlbnROb2RlKCk7Ci0gICAgICBmb3IgKDsgcCAhPSBudWxsOyBwID0gcC5nZXRQYXJlbnROb2RlKCkpCi0gICAgICB7Ci0gICAgICAgIHJvb3QgPSBwOwotICAgICAgfQotCi0gICAgICBET00yRFRNIGR0bSA9IChET00yRFRNKSBnZXREVE0obmV3IGphdmF4LnhtbC50cmFuc2Zvcm0uZG9tLkRPTVNvdXJjZShyb290KSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSwgbnVsbCwgdHJ1ZSwgdHJ1ZSk7Ci0KLSAgICAgIGludCBoYW5kbGU7Ci0KLSAgICAgIGlmKG5vZGUgaW5zdGFuY2VvZiBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5yZWYuZG9tMmR0bS5ET00yRFRNZGVmYXVsdE5hbWVzcGFjZURlY2xhcmF0aW9uTm9kZSkKLSAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ2FuJ3QgcmV0dXJuIHRoZSBzYW1lIG5vZGUgc2luY2UgaXQncyB1bmlxdWUgdG8gYSBzcGVjaWZpYyBEVE0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGJ1dCBjYW4gcmV0dXJuIHRoZSBlcXVpdmFsZW50IG5vZGUgLS0gZmluZCB0aGUgY29ycmVzcG9uZGluZwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBEb2N1bWVudCBFbGVtZW50LCB0aGVuIGFzayBpdCBmb3IgdGhlIHhtbDogbmFtZXNwYWNlIGRlY2wuCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZT1kdG0uZ2V0SGFuZGxlT2ZOb2RlKCgob3JnLnczYy5kb20uQXR0cilub2RlKS5nZXRPd25lckVsZW1lbnQoKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZT1kdG0uZ2V0QXR0cmlidXRlTm9kZShoYW5kbGUsbm9kZS5nZXROYW1lc3BhY2VVUkkoKSxub2RlLmdldExvY2FsTmFtZSgpKTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlID0gKChET00yRFRNKWR0bSkuZ2V0SGFuZGxlT2ZOb2RlKG5vZGUpOwotCi0gICAgICBpZihEVE0uTlVMTCA9PSBoYW5kbGUpCi0gICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKFhNTE1lc3NhZ2VzLmNyZWF0ZVhNTE1lc3NhZ2UoWE1MRXJyb3JSZXNvdXJjZXMuRVJfQ09VTERfTk9UX1JFU09MVkVfTk9ERSwgbnVsbCkpOyAvLyJDb3VsZCBub3QgcmVzb2x2ZSB0aGUgbm9kZSB0byBhIGhhbmRsZSEiKTsKLQotICAgICAgcmV0dXJuIGhhbmRsZTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogVGhpcyBtZXRob2QgcmV0dXJucyB0aGUgU0FYMiBwYXJzZXIgdG8gdXNlIHdpdGggdGhlIElucHV0U291cmNlCi0gICAqIG9idGFpbmVkIGZyb20gdGhpcyBVUkkuCi0gICAqIEl0IG1heSByZXR1cm4gbnVsbCBpZiBhbnkgU0FYMi1jb25mb3JtYW50IFhNTCBwYXJzZXIgY2FuIGJlIHVzZWQsCi0gICAqIG9yIGlmIGdldElucHV0U291cmNlKCkgd2lsbCBhbHNvIHJldHVybiBudWxsLiBUaGUgcGFyc2VyIG11c3QKLSAgICogYmUgZnJlZSBmb3IgdXNlIChpLmUuLCBub3QgY3VycmVudGx5IGluIHVzZSBmb3IgYW5vdGhlciBwYXJzZSgpLgotICAgKiBBZnRlciB1c2Ugb2YgdGhlIHBhcnNlciBpcyBjb21wbGV0ZWQsIHRoZSByZWxlYXNlWE1MUmVhZGVyKFhNTFJlYWRlcikKLSAgICogbXVzdCBiZSBjYWxsZWQuCi0gICAqCi0gICAqIEBwYXJhbSBpbnB1dFNvdXJjZSBUaGUgdmFsdWUgcmV0dXJuZWQgZnJvbSB0aGUgVVJJUmVzb2x2ZXIuCi0gICAqIEByZXR1cm4gIGEgU0FYMiBYTUxSZWFkZXIgdG8gdXNlIHRvIHJlc29sdmUgdGhlIGlucHV0U291cmNlIGFyZ3VtZW50LgotICAgKgotICAgKiBAcmV0dXJuIG5vbi1udWxsIFhNTFJlYWRlciByZWZlcmVuY2UgcmVhZHkgdG8gcGFyc2UuCi0gICAqLwotICBzeW5jaHJvbml6ZWQgcHVibGljIFhNTFJlYWRlciBnZXRYTUxSZWFkZXIoU291cmNlIGlucHV0U291cmNlKQotICB7Ci0KLSAgICB0cnkKLSAgICB7Ci0gICAgICBYTUxSZWFkZXIgcmVhZGVyID0gKGlucHV0U291cmNlIGluc3RhbmNlb2YgU0FYU291cmNlKQotICAgICAgICAgICAgICAgICAgICAgICAgID8gKChTQVhTb3VyY2UpIGlucHV0U291cmNlKS5nZXRYTUxSZWFkZXIoKSA6IG51bGw7Ci0KLSAgICAgIC8vIElmIHVzZXIgZGlkIG5vdCBzdXBwbHkgYSByZWFkZXIsIGFzayBmb3Igb25lIGZyb20gdGhlIHJlYWRlciBtYW5hZ2VyCi0gICAgICBpZiAobnVsbCA9PSByZWFkZXIpIHsKLSAgICAgICAgaWYgKG1fcmVhZGVyTWFuYWdlciA9PSBudWxsKSB7Ci0gICAgICAgICAgICBtX3JlYWRlck1hbmFnZXIgPSBYTUxSZWFkZXJNYW5hZ2VyLmdldEluc3RhbmNlKHN1cGVyLnVzZVNlcnZpY2VzTWVjaG5pc20oKSk7Ci0gICAgICAgIH0KLQotICAgICAgICByZWFkZXIgPSBtX3JlYWRlck1hbmFnZXIuZ2V0WE1MUmVhZGVyKCk7Ci0gICAgICB9Ci0KLSAgICAgIHJldHVybiByZWFkZXI7Ci0KLSAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gc2UpIHsKLSAgICAgIHRocm93IG5ldyBEVE1FeGNlcHRpb24oc2UuZ2V0TWVzc2FnZSgpLCBzZSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEluZGljYXRlcyB0aGF0IHRoZSBYTUxSZWFkZXIgb2JqZWN0IGlzIG5vIGxvbmdlciBpbiB1c2UgZm9yIHRoZSB0cmFuc2Zvcm0uCi0gICAqCi0gICAqIE5vdGUgdGhhdCB0aGUgZ2V0WE1MUmVhZGVyIG1ldGhvZCBtYXkgcmV0dXJuIGFuIFhNTFJlYWRlciB0aGF0IHdhcwotICAgKiBzcGVjaWZpZWQgb24gdGhlIFNBWFNvdXJjZSBvYmplY3QgYnkgdGhlIGFwcGxpY2F0aW9uIGNvZGUuICBTdWNoIGEKLSAgICogcmVhZGVyIHNob3VsZCBzdGlsbCBiZSBwYXNzZWQgdG8gcmVsZWFzZVhNTFJlYWRlciwgYnV0IHRoZSByZWFkZXIgbWFuYWdlcgotICAgKiB3aWxsIG9ubHkgcmUtdXNlIFhNTFJlYWRlcnMgdGhhdCBpdCBjcmVhdGVkLgotICAgKgotICAgKiBAcGFyYW0gcmVhZGVyIFRoZSBYTUxSZWFkZXIgdG8gYmUgcmVsZWFzZWQuCi0gICAqLwotICBzeW5jaHJvbml6ZWQgcHVibGljIHZvaWQgcmVsZWFzZVhNTFJlYWRlcihYTUxSZWFkZXIgcmVhZGVyKSB7Ci0gICAgaWYgKG1fcmVhZGVyTWFuYWdlciAhPSBudWxsKSB7Ci0gICAgICBtX3JlYWRlck1hbmFnZXIucmVsZWFzZVhNTFJlYWRlcihyZWFkZXIpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIERUTSBvYmplY3QgY29udGFpbmluZyBhIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgbm9kZS4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgRFRNIEhhbmRsZSBpbmRpY2F0aW5nIHdoaWNoIG5vZGUgdG8gcmV0cmlldmUKLSAgICoKLSAgICogQHJldHVybiBhIHJlZmVyZW5jZSB0byB0aGUgRFRNIG9iamVjdCBjb250YWluaW5nIHRoaXMgbm9kZS4KLSAgICovCi0gIHN5bmNocm9uaXplZCBwdWJsaWMgRFRNIGdldERUTShpbnQgbm9kZUhhbmRsZSkKLSAgewotICAgIHRyeQotICAgIHsKLSAgICAgIC8vIFBlcmZvcm1hbmNlIGNyaXRpY2FsIGZ1bmN0aW9uLgotICAgICAgcmV0dXJuIG1fZHRtc1tub2RlSGFuZGxlID4+PiBJREVOVF9EVE1fTk9ERV9CSVRTXTsKLSAgICB9Ci0gICAgY2F0Y2goamF2YS5sYW5nLkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKQotICAgIHsKLSAgICAgIGlmKG5vZGVIYW5kbGU9PURUTS5OVUxMKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsgICAgICAgICAgICAvLyBBY2NlcHQgYXMgYSBzcGVjaWFsIGNhc2UuCi0gICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGU7ICAgICAgICAgICAgICAgIC8vIFByb2dyYW1taW5nIGVycm9yOyB3YW50IHRvIGtub3cgYWJvdXQgaXQuCi0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgRFRNLCBmaW5kIHRoZSBJRCBudW1iZXIgaW4gdGhlIERUTSB0YWJsZXMgd2hpY2ggYWRkcmVzc2VzCi0gICAqIHRoZSBzdGFydCBvZiB0aGUgZG9jdW1lbnQuIElmIG92ZXJmbG93IGFkZHJlc3NpbmcgaXMgaW4gdXNlLCBvdGhlcgotICAgKiBEVE0gSURzIG1heSBhbHNvIGJlIGFzc2lnbmVkIHRvIHRoaXMgRFRNLgotICAgKgotICAgKiBAcGFyYW0gZHRtIFRoZSBEVE0gd2hpY2ggKGhvcGVmdWxseSkgY29udGFpbnMgdGhpcyBub2RlLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBEVE0gSUQgKGFzIHRoZSBoaWdoIGJpdHMgb2YgYSBOb2RlSGFuZGxlLCBub3QgYXMgb3VyCi0gICAqIGludGVybmFsIGluZGV4KSwgb3IgLTEgaWYgdGhlIERUTSBkb2Vzbid0IGJlbG9uZyB0byB0aGlzIG1hbmFnZXIuCi0gICAqLwotICBzeW5jaHJvbml6ZWQgcHVibGljIGludCBnZXREVE1JZGVudGl0eShEVE0gZHRtKQotICB7Ci0gICAgICAgIC8vIFNob3J0Y3V0IHVzaW5nIERUTURlZmF1bHRCYXNlJ3MgZXh0ZW5zaW9uIGhvb2tzCi0gICAgICAgIC8vICVSRVZJRVclIFNob3VsZCB0aGUgbG9va3VwIGJlIHBhcnQgb2YgdGhlIGJhc2ljIERUTSBBUEk/Ci0gICAgICAgIGlmKGR0bSBpbnN0YW5jZW9mIERUTURlZmF1bHRCYXNlKQotICAgICAgICB7Ci0gICAgICAgICAgICAgICAgRFRNRGVmYXVsdEJhc2UgZHRtZGI9KERUTURlZmF1bHRCYXNlKWR0bTsKLSAgICAgICAgICAgICAgICBpZihkdG1kYi5nZXRNYW5hZ2VyKCk9PXRoaXMpCi0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZHRtZGIuZ2V0RFRNSURzKCkuZWxlbWVudEF0KDApOwotICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAtMTsKLSAgICAgICAgfQotCi0gICAgaW50IG4gPSBtX2R0bXMubGVuZ3RoOwotCi0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspCi0gICAgewotICAgICAgRFRNIHRkdG0gPSBtX2R0bXNbaV07Ci0KLSAgICAgIGlmICh0ZHRtID09IGR0bSAmJiBtX2R0bV9vZmZzZXRzW2ldPT0wKQotICAgICAgICByZXR1cm4gaSA8PCBJREVOVF9EVE1fTk9ERV9CSVRTOwotICAgIH0KLQotICAgIHJldHVybiAtMTsKLSAgfQotCi0gIC8qKgotICAgKiBSZWxlYXNlIHRoZSBEVE1NYW5hZ2VyJ3MgcmVmZXJlbmNlKHMpIHRvIGEgRFRNLCBtYWtpbmcgaXQgdW5tYW5hZ2VkLgotICAgKiBUaGlzIGlzIHR5cGljYWxseSBkb25lIGFzIHBhcnQgb2YgcmV0dXJuaW5nIHRoZSBEVE0gdG8gdGhlIGhlYXAgYWZ0ZXIKLSAgICogd2UncmUgZG9uZSB3aXRoIGl0LgotICAgKgotICAgKiBAcGFyYW0gZHRtIHRoZSBEVE0gdG8gYmUgcmVsZWFzZWQuCi0gICAqCi0gICAqIEBwYXJhbSBzaG91bGRIYXJkRGVsZXRlIElmIGZhbHNlLCB0aGlzIGNhbGwgaXMgYSBzdWdnZXN0aW9uIHJhdGhlciB0aGFuIGFuCi0gICAqIG9yZGVyLCBhbmQgd2UgbWF5IG5vdCBhY3R1YWxseSByZWxlYXNlIHRoZSBEVE0uIFRoaXMgaXMgaW50ZW5kZWQgdG8KLSAgICogc3VwcG9ydCBpbnRlbGxpZ2VudCBjYWNoaW5nIG9mIGRvY3VtZW50cy4uLiB3aGljaCBpcyBub3QgaW1wbGVtZW50ZWQKLSAgICogaW4gdGhpcyB2ZXJzaW9uIG9mIHRoZSBEVE0gbWFuYWdlci4KLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHRoZSBEVE0gd2FzIHJlbGVhc2VkLCBmYWxzZSBpZiBzaG91bGRIYXJkRGVsZXRlIHdhcyBzZXQKLSAgICogYW5kIHdlIGRlY2lkZWQgbm90IHRvLgotICAgKi8KLSAgc3luY2hyb25pemVkIHB1YmxpYyBib29sZWFuIHJlbGVhc2UoRFRNIGR0bSwgYm9vbGVhbiBzaG91bGRIYXJkRGVsZXRlKQotICB7Ci0gICAgaWYoREVCVUcpCi0gICAgewotICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJSZWxlYXNpbmcgIisKLSAgICAgICAgICAgICAgICAgICAgICAgICAoc2hvdWxkSGFyZERlbGV0ZSA/ICJIQVJEIiA6ICJzb2Z0IikrCi0gICAgICAgICAgICAgICAgICAgICAgICAgIiBkdG09IisKLSAgICAgICAgICAgICAgICAgICAgICAgICAvLyBGb2xsb3dpbmcgc2hvdWxkbid0IG5lZWQgYSBub2RlSGFuZGxlLCBidXQgZG9lcy4uLgotICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFuZCBkb2Vzbid0IHNlZW0gdG8gcmVwb3J0IHRoZSBpbnRlbmRlZCB2YWx1ZQotICAgICAgICAgICAgICAgICAgICAgICAgIGR0bS5nZXREb2N1bWVudEJhc2VVUkkoKQotICAgICAgICAgICAgICAgICAgICAgICAgICk7Ci0gICAgfQotCi0gICAgaWYgKGR0bSBpbnN0YW5jZW9mIFNBWDJEVE0pCi0gICAgewotICAgICAgKChTQVgyRFRNKSBkdG0pLmNsZWFyQ29Sb3V0aW5lKCk7Ci0gICAgfQotCi0gICAgICAgICAgICAgICAgLy8gTXVsdGlwbGUgRFRNIElEcyBtYXkgYmUgYXNzaWduZWQgdG8gYSBzaW5nbGUgRFRNLgotICAgICAgICAgICAgICAgIC8vIFRoZSBSaWdodCBBbnN3ZXIgaXMgdG8gYXNrIHdoaWNoIChpZiBpdCBzdXBwb3J0cwotICAgICAgICAgICAgICAgIC8vIGV4dGVuc2lvbiwgdGhlIERUTSB3aWxsIG5lZWQgYSBsaXN0IGFueXdheSkuIFRoZQotICAgICAgICAgICAgICAgIC8vIFdyb25nIEFuc3dlciwgYXBwbGllZCBpZiB0aGUgRFRNIGNhbid0IGhlbHAgdXMsCi0gICAgICAgICAgICAgICAgLy8gaXMgdG8gbGluZWFybHkgc2VhcmNoIHRoZW0gYWxsOyB0aGlzIG1heSBiZSB2ZXJ5Ci0gICAgICAgICAgICAgICAgLy8gcGFpbmZ1bC4KLSAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgIC8vICVSRVZJRVclIFNob3VsZCB0aGUgbG9va3VwIG1vdmUgdXAgaW50byB0aGUgYmFzaWMgRFRNIEFQST8KLSAgICAgICAgICAgICAgICBpZihkdG0gaW5zdGFuY2VvZiBEVE1EZWZhdWx0QmFzZSkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLlN1YmFsbG9jYXRlZEludFZlY3RvciBpZHM9KChEVE1EZWZhdWx0QmFzZSlkdG0pLmdldERUTUlEcygpOwotICAgICAgICAgICAgICAgICAgICAgICAgZm9yKGludCBpPWlkcy5zaXplKCktMTtpPj0wOy0taSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbV9kdG1zW2lkcy5lbGVtZW50QXQoaSk+Pj5EVE1NYW5hZ2VyLklERU5UX0RUTV9OT0RFX0JJVFNdPW51bGw7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpbnQgaSA9IGdldERUTUlkZW50aXR5KGR0bSk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChpID49IDApCi0gICAgICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fZHRtc1tpID4+PiBEVE1NYW5hZ2VyLklERU5UX0RUTV9OT0RFX0JJVFNdID0gbnVsbDsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0KLSAgICBkdG0uZG9jdW1lbnRSZWxlYXNlKCk7Ci0gICAgcmV0dXJuIHRydWU7Ci0gIH0KLQotICAvKioKLSAgICogTWV0aG9kIGNyZWF0ZURvY3VtZW50RnJhZ21lbnQKLSAgICoKLSAgICoKLSAgICogTkVFRFNET0MgKGNyZWF0ZURvY3VtZW50RnJhZ21lbnQpIEByZXR1cm4KLSAgICovCi0gIHN5bmNocm9uaXplZCBwdWJsaWMgRFRNIGNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKQotICB7Ci0KLSAgICB0cnkKLSAgICB7Ci0gICAgICBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGRiZiA9IEZhY3RvcnlJbXBsLmdldERPTUZhY3Rvcnkoc3VwZXIudXNlU2VydmljZXNNZWNobmlzbSgpKTsKLSAgICAgIGRiZi5zZXROYW1lc3BhY2VBd2FyZSh0cnVlKTsKLQotICAgICAgRG9jdW1lbnRCdWlsZGVyIGRiID0gZGJmLm5ld0RvY3VtZW50QnVpbGRlcigpOwotICAgICAgRG9jdW1lbnQgZG9jID0gZGIubmV3RG9jdW1lbnQoKTsKLSAgICAgIE5vZGUgZGYgPSBkb2MuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpOwotCi0gICAgICByZXR1cm4gZ2V0RFRNKG5ldyBET01Tb3VyY2UoZGYpLCB0cnVlLCBudWxsLCBmYWxzZSwgZmFsc2UpOwotICAgIH0KLSAgICBjYXRjaCAoRXhjZXB0aW9uIGUpCi0gICAgewotICAgICAgdGhyb3cgbmV3IERUTUV4Y2VwdGlvbihlKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogTkVFRFNET0MgTWV0aG9kIGNyZWF0ZURUTUl0ZXJhdG9yCi0gICAqCi0gICAqCi0gICAqIE5FRURTRE9DIEBwYXJhbSB3aGF0VG9TaG93Ci0gICAqIE5FRURTRE9DIEBwYXJhbSBmaWx0ZXIKLSAgICogTkVFRFNET0MgQHBhcmFtIGVudGl0eVJlZmVyZW5jZUV4cGFuc2lvbgotICAgKgotICAgKiBORUVEU0RPQyAoY3JlYXRlRFRNSXRlcmF0b3IpIEByZXR1cm4KLSAgICovCi0gIHN5bmNocm9uaXplZCBwdWJsaWMgRFRNSXRlcmF0b3IgY3JlYXRlRFRNSXRlcmF0b3IoaW50IHdoYXRUb1Nob3csIERUTUZpbHRlciBmaWx0ZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGVudGl0eVJlZmVyZW5jZUV4cGFuc2lvbikKLSAgewotCi0gICAgLyoqIEB0b2RvOiBpbXBsZW1lbnQgdGhpcyBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1NYW5hZ2VyIGFic3RyYWN0IG1ldGhvZCAqLwotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIE5FRURTRE9DIE1ldGhvZCBjcmVhdGVEVE1JdGVyYXRvcgotICAgKgotICAgKgotICAgKiBORUVEU0RPQyBAcGFyYW0geHBhdGhTdHJpbmcKLSAgICogTkVFRFNET0MgQHBhcmFtIHByZXNvbHZlcgotICAgKgotICAgKiBORUVEU0RPQyAoY3JlYXRlRFRNSXRlcmF0b3IpIEByZXR1cm4KLSAgICovCi0gIHN5bmNocm9uaXplZCBwdWJsaWMgRFRNSXRlcmF0b3IgY3JlYXRlRFRNSXRlcmF0b3IoU3RyaW5nIHhwYXRoU3RyaW5nLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHJlZml4UmVzb2x2ZXIgcHJlc29sdmVyKQotICB7Ci0KLSAgICAvKiogQHRvZG86IGltcGxlbWVudCB0aGlzIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTU1hbmFnZXIgYWJzdHJhY3QgbWV0aG9kICovCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogTkVFRFNET0MgTWV0aG9kIGNyZWF0ZURUTUl0ZXJhdG9yCi0gICAqCi0gICAqCi0gICAqIE5FRURTRE9DIEBwYXJhbSBub2RlCi0gICAqCi0gICAqIE5FRURTRE9DIChjcmVhdGVEVE1JdGVyYXRvcikgQHJldHVybgotICAgKi8KLSAgc3luY2hyb25pemVkIHB1YmxpYyBEVE1JdGVyYXRvciBjcmVhdGVEVE1JdGVyYXRvcihpbnQgbm9kZSkKLSAgewotCi0gICAgLyoqIEB0b2RvOiBpbXBsZW1lbnQgdGhpcyBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1NYW5hZ2VyIGFic3RyYWN0IG1ldGhvZCAqLwotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIE5FRURTRE9DIE1ldGhvZCBjcmVhdGVEVE1JdGVyYXRvcgotICAgKgotICAgKgotICAgKiBORUVEU0RPQyBAcGFyYW0geHBhdGhDb21waWxlcgotICAgKiBORUVEU0RPQyBAcGFyYW0gcG9zCi0gICAqCi0gICAqIE5FRURTRE9DIChjcmVhdGVEVE1JdGVyYXRvcikgQHJldHVybgotICAgKi8KLSAgc3luY2hyb25pemVkIHB1YmxpYyBEVE1JdGVyYXRvciBjcmVhdGVEVE1JdGVyYXRvcihPYmplY3QgeHBhdGhDb21waWxlciwgaW50IHBvcykKLSAgewotCi0gICAgLyoqIEB0b2RvOiBpbXBsZW1lbnQgdGhpcyBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1NYW5hZ2VyIGFic3RyYWN0IG1ldGhvZCAqLwotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIHJldHVybiB0aGUgZXhwYW5kZWQgbmFtZSB0YWJsZS4KLSAgICoKLSAgICogTkVFRFNET0MgQHBhcmFtIGR0bQotICAgKgotICAgKiBORUVEU0RPQyAoJG9iamVjdE5hbWUkKSBAcmV0dXJuCi0gICAqLwotICBwdWJsaWMgRXhwYW5kZWROYW1lVGFibGUgZ2V0RXhwYW5kZWROYW1lVGFibGUoRFRNIGR0bSkKLSAgewotICAgIHJldHVybiBtX2V4cGFuZGVkTmFtZVRhYmxlOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vcmVmL0RUTU5hbWVkTm9kZU1hcC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL3JlZi9EVE1OYW1lZE5vZGVNYXAuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOGM4ZDFkOS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vcmVmL0RUTU5hbWVkTm9kZU1hcC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzAyICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IERUTU5hbWVkTm9kZU1hcC5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE1IDA4OjE1OjAzIHN1cmVzaF9lbWFpbGlkIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0ucmVmOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNOwotCi1pbXBvcnQgb3JnLnczYy5kb20uRE9NRXhjZXB0aW9uOwotaW1wb3J0IG9yZy53M2MuZG9tLk5hbWVkTm9kZU1hcDsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotCi0vKioKLSAqIERUTU5hbWVkTm9kZU1hcCBpcyBhIHF1aWNraWUgKGFzIG9wcG9zZWQgdG8gcXVpY2spIGltcGxlbWVudGF0aW9uIG9mIHRoZSBET00ncwotICogTmFtZWROb2RlTWFwIGludGVyZmFjZSwgaW50ZW5kZWQgdG8gc3VwcG9ydCBEVE1Qcm94eSdzIGdldEF0dHJpYnV0ZXMoKQotICogY2FsbC4KLSAqIDxwPgotICogKioqKiogTm90ZTogdGhpcyBkb2VzIF9ub3RfIGN1cnJlbnQgYXR0ZW1wdCB0byBjYWNoZSBhbnkgb2YgdGhlIGRhdGE7Ci0gKiBpZiB5b3UgYXNrIGZvciBhdHRyaWJ1dGUgMjcgYW5kIHRoZW4gMjgsIHlvdSdsbCBoYXZlIHRvIHJlc2NhbiB0aGUgZmlyc3QKLSAqIDI3LiBJdCBzaG91bGQgcHJvYmFibHkgYXQgbGVhc3Qga2VlcCB0cmFjayBvZiB0aGUgbGFzdCBvbmUgcmV0cmlldmVkLAotICogYW5kIHBvc3NpYmx5IGJ1ZmZlciB0aGUgd2hvbGUgYXJyYXkuCi0gKiA8cD4KLSAqICoqKioqIEFsc28gbm90ZSB0aGF0IHRoZXJlJ3Mgbm8gZmFzdHBhdGggZm9yIHRoZSBieS1uYW1lIHF1ZXJ5OyB3ZSBzZWFyY2gKLSAqIGxpbmVhcmx5IHVudGlsIHdlIGZpbmQgaXQgb3IgZmFpbCB0byBmaW5kIGl0LiBBZ2FpbiwgdGhhdCBjb3VsZCBiZQotICogb3B0aW1pemVkIGF0IHNvbWUgY29zdCBpbiBvYmplY3QgY3JlYXRpb24vc3RvcmFnZS4KLSAqIEB4c2wudXNhZ2UgaW50ZXJuYWwKLSAqLwotcHVibGljIGNsYXNzIERUTU5hbWVkTm9kZU1hcCBpbXBsZW1lbnRzIE5hbWVkTm9kZU1hcAotewotCi0gIC8qKiBUaGUgRFRNIGZvciB0aGlzIG5vZGUuICovCi0gIERUTSBkdG07Ci0KLSAgLyoqIFRoZSBEVE0gZWxlbWVudCBoYW5kbGUuICovCi0gIGludCBlbGVtZW50OwotCi0gIC8qKiBUaGUgbnVtYmVyIG9mIG5vZGVzIGluIHRoaXMgbWFwLiAqLwotICBzaG9ydCBtX2NvdW50ID0gLTE7Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIGdldEF0dHJpYnV0ZXMgTmFtZWROb2RlTWFwIGZvciBhIGdpdmVuIERUTSBlbGVtZW50IG5vZGUKLSAgICoKLSAgICogQHBhcmFtIGR0bSBUaGUgRFRNIFJlZmVyZW5jZSwgbXVzdCBiZSBub24tbnVsbC4KLSAgICogQHBhcmFtIGVsZW1lbnQgVGhlIERUTSBlbGVtZW50IGhhbmRsZS4KLSAgICovCi0gIHB1YmxpYyBEVE1OYW1lZE5vZGVNYXAoRFRNIGR0bSwgaW50IGVsZW1lbnQpCi0gIHsKLSAgICB0aGlzLmR0bSA9IGR0bTsKLSAgICB0aGlzLmVsZW1lbnQgPSBlbGVtZW50OwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgbnVtYmVyIG9mIEF0dHJpYnV0ZXMgb24gdGhpcyBFbGVtZW50Ci0gICAqCi0gICAqIEByZXR1cm4gVGhlIG51bWJlciBvZiBub2RlcyBpbiB0aGlzIG1hcC4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0TGVuZ3RoKCkKLSAgewotCi0gICAgaWYgKG1fY291bnQgPT0gLTEpCi0gICAgewotICAgICAgc2hvcnQgY291bnQgPSAwOwotCi0gICAgICBmb3IgKGludCBuID0gZHRtLmdldEZpcnN0QXR0cmlidXRlKGVsZW1lbnQpOyBuICE9IC0xOwotICAgICAgICAgICAgICBuID0gZHRtLmdldE5leHRBdHRyaWJ1dGUobikpCi0gICAgICB7Ci0gICAgICAgICsrY291bnQ7Ci0gICAgICB9Ci0KLSAgICAgIG1fY291bnQgPSBjb3VudDsKLSAgICB9Ci0KLSAgICByZXR1cm4gKGludCkgbV9jb3VudDsKLSAgfQotCi0gIC8qKgotICAgKiBSZXRyaWV2ZXMgYSBub2RlIHNwZWNpZmllZCBieSBuYW1lLgotICAgKiBAcGFyYW0gbmFtZSBUaGUgPGNvZGU+bm9kZU5hbWU8L2NvZGU+IG9mIGEgbm9kZSB0byByZXRyaWV2ZS4KLSAgICogQHJldHVybiBBIDxjb2RlPk5vZGU8L2NvZGU+IChvZiBhbnkgdHlwZSkgd2l0aCB0aGUgc3BlY2lmaWVkCi0gICAqICAgPGNvZGU+bm9kZU5hbWU8L2NvZGU+LCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiBpdCBkb2VzIG5vdCBpZGVudGlmeQotICAgKiAgIGFueSBub2RlIGluIHRoaXMgbWFwLgotICAgKi8KLSAgcHVibGljIE5vZGUgZ2V0TmFtZWRJdGVtKFN0cmluZyBuYW1lKQotICB7Ci0KLSAgICBmb3IgKGludCBuID0gZHRtLmdldEZpcnN0QXR0cmlidXRlKGVsZW1lbnQpOyBuICE9IERUTS5OVUxMOwotICAgICAgICAgICAgbiA9IGR0bS5nZXROZXh0QXR0cmlidXRlKG4pKQotICAgIHsKLSAgICAgIGlmIChkdG0uZ2V0Tm9kZU5hbWUobikuZXF1YWxzKG5hbWUpKQotICAgICAgICByZXR1cm4gZHRtLmdldE5vZGUobik7Ci0gICAgfQotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgPGNvZGU+aW5kZXg8L2NvZGU+dGggaXRlbSBpbiB0aGUgbWFwLiBJZiA8Y29kZT5pbmRleDwvY29kZT4KLSAgICogaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHRoZSBudW1iZXIgb2Ygbm9kZXMgaW4gdGhpcyBtYXAsIHRoaXMKLSAgICogcmV0dXJucyA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICogQHBhcmFtIGkgVGhlIGluZGV4IG9mIHRoZSByZXF1ZXN0ZWQgaXRlbS4KLSAgICogQHJldHVybiBUaGUgbm9kZSBhdCB0aGUgPGNvZGU+aW5kZXg8L2NvZGU+dGggcG9zaXRpb24gaW4gdGhlIG1hcCwgb3IKLSAgICogICA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGF0IGlzIG5vdCBhIHZhbGlkIGluZGV4LgotICAgKi8KLSAgcHVibGljIE5vZGUgaXRlbShpbnQgaSkKLSAgewotCi0gICAgaW50IGNvdW50ID0gMDsKLQotICAgIGZvciAoaW50IG4gPSBkdG0uZ2V0Rmlyc3RBdHRyaWJ1dGUoZWxlbWVudCk7IG4gIT0gLTE7Ci0gICAgICAgICAgICBuID0gZHRtLmdldE5leHRBdHRyaWJ1dGUobikpCi0gICAgewotICAgICAgaWYgKGNvdW50ID09IGkpCi0gICAgICAgIHJldHVybiBkdG0uZ2V0Tm9kZShuKTsKLSAgICAgIGVsc2UKLSAgICAgICAgKytjb3VudDsKLSAgICB9Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBBZGRzIGEgbm9kZSB1c2luZyBpdHMgPGNvZGU+bm9kZU5hbWU8L2NvZGU+IGF0dHJpYnV0ZS4gSWYgYSBub2RlIHdpdGgKLSAgICogdGhhdCBuYW1lIGlzIGFscmVhZHkgcHJlc2VudCBpbiB0aGlzIG1hcCwgaXQgaXMgcmVwbGFjZWQgYnkgdGhlIG5ldwotICAgKiBvbmUuCi0gICAqIDxicj5BcyB0aGUgPGNvZGU+bm9kZU5hbWU8L2NvZGU+IGF0dHJpYnV0ZSBpcyB1c2VkIHRvIGRlcml2ZSB0aGUgbmFtZQotICAgKiB3aGljaCB0aGUgbm9kZSBtdXN0IGJlIHN0b3JlZCB1bmRlciwgbXVsdGlwbGUgbm9kZXMgb2YgY2VydGFpbiB0eXBlcwotICAgKiAodGhvc2UgdGhhdCBoYXZlIGEgInNwZWNpYWwiIHN0cmluZyB2YWx1ZSkgY2Fubm90IGJlIHN0b3JlZCBhcyB0aGUKLSAgICogbmFtZXMgd291bGQgY2xhc2guIFRoaXMgaXMgc2VlbiBhcyBwcmVmZXJhYmxlIHRvIGFsbG93aW5nIG5vZGVzIHRvIGJlCi0gICAqIGFsaWFzZWQuCi0gICAqIEBwYXJhbSBuZXdOb2RlIG5vZGUgdG8gc3RvcmUgaW4gdGhpcyBtYXAuIFRoZSBub2RlIHdpbGwgbGF0ZXIgYmUKLSAgICogICBhY2Nlc3NpYmxlIHVzaW5nIHRoZSB2YWx1ZSBvZiBpdHMgPGNvZGU+bm9kZU5hbWU8L2NvZGU+IGF0dHJpYnV0ZS4KLSAgICoKLSAgICogQHJldHVybiBJZiB0aGUgbmV3IDxjb2RlPk5vZGU8L2NvZGU+IHJlcGxhY2VzIGFuIGV4aXN0aW5nIG5vZGUgdGhlCi0gICAqICAgcmVwbGFjZWQgPGNvZGU+Tm9kZTwvY29kZT4gaXMgcmV0dXJuZWQsIG90aGVyd2lzZSA8Y29kZT5udWxsPC9jb2RlPgotICAgKiAgIGlzIHJldHVybmVkLgotICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgKiAgIFdST05HX0RPQ1VNRU5UX0VSUjogUmFpc2VkIGlmIDxjb2RlPmFyZzwvY29kZT4gd2FzIGNyZWF0ZWQgZnJvbSBhCi0gICAqICAgZGlmZmVyZW50IGRvY3VtZW50IHRoYW4gdGhlIG9uZSB0aGF0IGNyZWF0ZWQgdGhpcyBtYXAuCi0gICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgbWFwIGlzIHJlYWRvbmx5LgotICAgKiAgIDxicj5JTlVTRV9BVFRSSUJVVEVfRVJSOiBSYWlzZWQgaWYgPGNvZGU+YXJnPC9jb2RlPiBpcyBhbgotICAgKiAgIDxjb2RlPkF0dHI8L2NvZGU+IHRoYXQgaXMgYWxyZWFkeSBhbiBhdHRyaWJ1dGUgb2YgYW5vdGhlcgotICAgKiAgIDxjb2RlPkVsZW1lbnQ8L2NvZGU+IG9iamVjdC4gVGhlIERPTSB1c2VyIG11c3QgZXhwbGljaXRseSBjbG9uZQotICAgKiAgIDxjb2RlPkF0dHI8L2NvZGU+IG5vZGVzIHRvIHJlLXVzZSB0aGVtIGluIG90aGVyIGVsZW1lbnRzLgotICAgKi8KLSAgcHVibGljIE5vZGUgc2V0TmFtZWRJdGVtKE5vZGUgbmV3Tm9kZSkKLSAgewotICAgIHRocm93IG5ldyBEVE1FeGNlcHRpb24oRFRNRXhjZXB0aW9uLk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUik7Ci0gIH0KLQotICAvKioKLSAgICogUmVtb3ZlcyBhIG5vZGUgc3BlY2lmaWVkIGJ5IG5hbWUuIFdoZW4gdGhpcyBtYXAgY29udGFpbnMgdGhlIGF0dHJpYnV0ZXMKLSAgICogYXR0YWNoZWQgdG8gYW4gZWxlbWVudCwgaWYgdGhlIHJlbW92ZWQgYXR0cmlidXRlIGlzIGtub3duIHRvIGhhdmUgYQotICAgKiBkZWZhdWx0IHZhbHVlLCBhbiBhdHRyaWJ1dGUgaW1tZWRpYXRlbHkgYXBwZWFycyBjb250YWluaW5nIHRoZQotICAgKiBkZWZhdWx0IHZhbHVlIGFzIHdlbGwgYXMgdGhlIGNvcnJlc3BvbmRpbmcgbmFtZXNwYWNlIFVSSSwgbG9jYWwgbmFtZSwKLSAgICogYW5kIHByZWZpeCB3aGVuIGFwcGxpY2FibGUuCi0gICAqIEBwYXJhbSBuYW1lIFRoZSA8Y29kZT5ub2RlTmFtZTwvY29kZT4gb2YgdGhlIG5vZGUgdG8gcmVtb3ZlLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBub2RlIHJlbW92ZWQgZnJvbSB0aGlzIG1hcCBpZiBhIG5vZGUgd2l0aCBzdWNoIGEgbmFtZQotICAgKiAgIGV4aXN0cy4KLSAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICogICBOT1RfRk9VTkRfRVJSOiBSYWlzZWQgaWYgdGhlcmUgaXMgbm8gbm9kZSBuYW1lZCA8Y29kZT5uYW1lPC9jb2RlPiBpbgotICAgKiAgIHRoaXMgbWFwLgotICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIG1hcCBpcyByZWFkb25seS4KLSAgICovCi0gIHB1YmxpYyBOb2RlIHJlbW92ZU5hbWVkSXRlbShTdHJpbmcgbmFtZSkKLSAgewotICAgIHRocm93IG5ldyBEVE1FeGNlcHRpb24oRFRNRXhjZXB0aW9uLk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUik7Ci0gIH0KLQotICAvKioKLSAgICogUmV0cmlldmVzIGEgbm9kZSBzcGVjaWZpZWQgYnkgbG9jYWwgbmFtZSBhbmQgbmFtZXNwYWNlIFVSSS4gSFRNTC1vbmx5Ci0gICAqIERPTSBpbXBsZW1lbnRhdGlvbnMgZG8gbm90IG5lZWQgdG8gaW1wbGVtZW50IHRoaXMgbWV0aG9kLgotICAgKiBAcGFyYW0gbmFtZXNwYWNlVVJJIFRoZSBuYW1lc3BhY2UgVVJJIG9mIHRoZSBub2RlIHRvIHJldHJpZXZlLgotICAgKiBAcGFyYW0gbG9jYWxOYW1lIFRoZSBsb2NhbCBuYW1lIG9mIHRoZSBub2RlIHRvIHJldHJpZXZlLgotICAgKgotICAgKiBAcmV0dXJuIEEgPGNvZGU+Tm9kZTwvY29kZT4gKG9mIGFueSB0eXBlKSB3aXRoIHRoZSBzcGVjaWZpZWQgbG9jYWwKLSAgICogICBuYW1lIGFuZCBuYW1lc3BhY2UgVVJJLCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGV5IGRvIG5vdAotICAgKiAgIGlkZW50aWZ5IGFueSBub2RlIGluIHRoaXMgbWFwLgotICAgKiBAc2luY2UgRE9NIExldmVsIDIKLSAgICovCi0gIHB1YmxpYyBOb2RlIGdldE5hbWVkSXRlbU5TKFN0cmluZyBuYW1lc3BhY2VVUkksIFN0cmluZyBsb2NhbE5hbWUpCi0gIHsKLSAgICAgICBOb2RlIHJldE5vZGUgPSBudWxsOwotICAgICAgIGZvciAoaW50IG4gPSBkdG0uZ2V0Rmlyc3RBdHRyaWJ1dGUoZWxlbWVudCk7IG4gIT0gRFRNLk5VTEw7Ci0gICAgICAgICAgICAgICAgICAgICAgIG4gPSBkdG0uZ2V0TmV4dEF0dHJpYnV0ZShuKSkKLSAgICAgICB7Ci0gICAgICAgICBpZiAobG9jYWxOYW1lLmVxdWFscyhkdG0uZ2V0TG9jYWxOYW1lKG4pKSkKLSAgICAgICAgIHsKLSAgICAgICAgICAgU3RyaW5nIG5zVVJJID0gZHRtLmdldE5hbWVzcGFjZVVSSShuKTsKLSAgICAgICAgICAgaWYgKChuYW1lc3BhY2VVUkkgPT0gbnVsbCAmJiBuc1VSSSA9PSBudWxsKQotICAgICAgICAgICAgICAgICAgfHwgKG5hbWVzcGFjZVVSSSAhPSBudWxsICYmIG5hbWVzcGFjZVVSSS5lcXVhbHMobnNVUkkpKSkKLSAgICAgICAgICAgewotICAgICAgICAgICAgIHJldE5vZGUgPSBkdG0uZ2V0Tm9kZShuKTsKLSAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgfQotICAgICAgICAgfQotICAgICAgIH0KLSAgICAgICByZXR1cm4gcmV0Tm9kZTsKLSAgfQotCi0gIC8qKgotICAgKiBBZGRzIGEgbm9kZSB1c2luZyBpdHMgPGNvZGU+bmFtZXNwYWNlVVJJPC9jb2RlPiBhbmQKLSAgICogPGNvZGU+bG9jYWxOYW1lPC9jb2RlPi4gSWYgYSBub2RlIHdpdGggdGhhdCBuYW1lc3BhY2UgVVJJIGFuZCB0aGF0Ci0gICAqIGxvY2FsIG5hbWUgaXMgYWxyZWFkeSBwcmVzZW50IGluIHRoaXMgbWFwLCBpdCBpcyByZXBsYWNlZCBieSB0aGUgbmV3Ci0gICAqIG9uZS4KLSAgICogPGJyPkhUTUwtb25seSBET00gaW1wbGVtZW50YXRpb25zIGRvIG5vdCBuZWVkIHRvIGltcGxlbWVudCB0aGlzIG1ldGhvZC4KLSAgICogQHBhcmFtIGFyZyBBIG5vZGUgdG8gc3RvcmUgaW4gdGhpcyBtYXAuIFRoZSBub2RlIHdpbGwgbGF0ZXIgYmUKLSAgICogICBhY2Nlc3NpYmxlIHVzaW5nIHRoZSB2YWx1ZSBvZiBpdHMgPGNvZGU+bmFtZXNwYWNlVVJJPC9jb2RlPiBhbmQKLSAgICogICA8Y29kZT5sb2NhbE5hbWU8L2NvZGU+IGF0dHJpYnV0ZXMuCi0gICAqCi0gICAqIEByZXR1cm4gSWYgdGhlIG5ldyA8Y29kZT5Ob2RlPC9jb2RlPiByZXBsYWNlcyBhbiBleGlzdGluZyBub2RlIHRoZQotICAgKiAgIHJlcGxhY2VkIDxjb2RlPk5vZGU8L2NvZGU+IGlzIHJldHVybmVkLCBvdGhlcndpc2UgPGNvZGU+bnVsbDwvY29kZT4KLSAgICogICBpcyByZXR1cm5lZC4KLSAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICogICBXUk9OR19ET0NVTUVOVF9FUlI6IFJhaXNlZCBpZiA8Y29kZT5hcmc8L2NvZGU+IHdhcyBjcmVhdGVkIGZyb20gYQotICAgKiAgIGRpZmZlcmVudCBkb2N1bWVudCB0aGFuIHRoZSBvbmUgdGhhdCBjcmVhdGVkIHRoaXMgbWFwLgotICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIG1hcCBpcyByZWFkb25seS4KLSAgICogICA8YnI+SU5VU0VfQVRUUklCVVRFX0VSUjogUmFpc2VkIGlmIDxjb2RlPmFyZzwvY29kZT4gaXMgYW4KLSAgICogICA8Y29kZT5BdHRyPC9jb2RlPiB0aGF0IGlzIGFscmVhZHkgYW4gYXR0cmlidXRlIG9mIGFub3RoZXIKLSAgICogICA8Y29kZT5FbGVtZW50PC9jb2RlPiBvYmplY3QuIFRoZSBET00gdXNlciBtdXN0IGV4cGxpY2l0bHkgY2xvbmUKLSAgICogICA8Y29kZT5BdHRyPC9jb2RlPiBub2RlcyB0byByZS11c2UgdGhlbSBpbiBvdGhlciBlbGVtZW50cy4KLSAgICogQHNpbmNlIERPTSBMZXZlbCAyCi0gICAqLwotICBwdWJsaWMgTm9kZSBzZXROYW1lZEl0ZW1OUyhOb2RlIGFyZykgdGhyb3dzIERPTUV4Y2VwdGlvbgotICB7Ci0gICAgdGhyb3cgbmV3IERUTUV4Y2VwdGlvbihEVE1FeGNlcHRpb24uTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZW1vdmVzIGEgbm9kZSBzcGVjaWZpZWQgYnkgbG9jYWwgbmFtZSBhbmQgbmFtZXNwYWNlIFVSSS4gQSByZW1vdmVkCi0gICAqIGF0dHJpYnV0ZSBtYXkgYmUga25vd24gdG8gaGF2ZSBhIGRlZmF1bHQgdmFsdWUgd2hlbiB0aGlzIG1hcCBjb250YWlucwotICAgKiB0aGUgYXR0cmlidXRlcyBhdHRhY2hlZCB0byBhbiBlbGVtZW50LCBhcyByZXR1cm5lZCBieSB0aGUgYXR0cmlidXRlcwotICAgKiBhdHRyaWJ1dGUgb2YgdGhlIDxjb2RlPk5vZGU8L2NvZGU+IGludGVyZmFjZS4gSWYgc28sIGFuIGF0dHJpYnV0ZQotICAgKiBpbW1lZGlhdGVseSBhcHBlYXJzIGNvbnRhaW5pbmcgdGhlIGRlZmF1bHQgdmFsdWUgYXMgd2VsbCBhcyB0aGUKLSAgICogY29ycmVzcG9uZGluZyBuYW1lc3BhY2UgVVJJLCBsb2NhbCBuYW1lLCBhbmQgcHJlZml4IHdoZW4gYXBwbGljYWJsZS4KLSAgICogPGJyPkhUTUwtb25seSBET00gaW1wbGVtZW50YXRpb25zIGRvIG5vdCBuZWVkIHRvIGltcGxlbWVudCB0aGlzIG1ldGhvZC4KLSAgICoKLSAgICogQHBhcmFtIG5hbWVzcGFjZVVSSSBUaGUgbmFtZXNwYWNlIFVSSSBvZiB0aGUgbm9kZSB0byByZW1vdmUuCi0gICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGxvY2FsIG5hbWUgb2YgdGhlIG5vZGUgdG8gcmVtb3ZlLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBub2RlIHJlbW92ZWQgZnJvbSB0aGlzIG1hcCBpZiBhIG5vZGUgd2l0aCBzdWNoIGEgbG9jYWwKLSAgICogICBuYW1lIGFuZCBuYW1lc3BhY2UgVVJJIGV4aXN0cy4KLSAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICogICBOT1RfRk9VTkRfRVJSOiBSYWlzZWQgaWYgdGhlcmUgaXMgbm8gbm9kZSB3aXRoIHRoZSBzcGVjaWZpZWQKLSAgICogICA8Y29kZT5uYW1lc3BhY2VVUkk8L2NvZGU+IGFuZCA8Y29kZT5sb2NhbE5hbWU8L2NvZGU+IGluIHRoaXMgbWFwLgotICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIG1hcCBpcyByZWFkb25seS4KLSAgICogQHNpbmNlIERPTSBMZXZlbCAyCi0gICAqLwotICBwdWJsaWMgTm9kZSByZW1vdmVOYW1lZEl0ZW1OUyhTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgbG9jYWxOYW1lKQotICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb24KLSAgewotICAgIHRocm93IG5ldyBEVE1FeGNlcHRpb24oRFRNRXhjZXB0aW9uLk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUik7Ci0gIH0KLQotICAvKioKLSAgICogU2ltcGxlIGltcGxlbWVudGF0aW9uIG9mIERPTUV4Y2VwdGlvbi4KLSAgICogQHhzbC51c2FnZSBpbnRlcm5hbAotICAgKi8KLSAgcHVibGljIGNsYXNzIERUTUV4Y2VwdGlvbiBleHRlbmRzIG9yZy53M2MuZG9tLkRPTUV4Y2VwdGlvbgotICB7Ci0gICAgICAgICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC04MjkwMjM4MTE3MTYyNDM3Njc4TDsKLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RzIGEgRE9NL0RUTSBleGNlcHRpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29kZQotICAgICAqIEBwYXJhbSBtZXNzYWdlCi0gICAgICovCi0gICAgcHVibGljIERUTUV4Y2VwdGlvbihzaG9ydCBjb2RlLCBTdHJpbmcgbWVzc2FnZSkKLSAgICB7Ci0gICAgICBzdXBlcihjb2RlLCBtZXNzYWdlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RvciBEVE1FeGNlcHRpb24KLSAgICAgKgotICAgICAqCi0gICAgICogQHBhcmFtIGNvZGUKLSAgICAgKi8KLSAgICBwdWJsaWMgRFRNRXhjZXB0aW9uKHNob3J0IGNvZGUpCi0gICAgewotICAgICAgc3VwZXIoY29kZSwgIiIpOwotICAgIH0KLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL3JlZi9EVE1Ob2RlSXRlcmF0b3IuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9yZWYvRFRNTm9kZUl0ZXJhdG9yLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGI1YTdiYjYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL3JlZi9EVE1Ob2RlSXRlcmF0b3IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE4OCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBEVE1Ob2RlSXRlcmF0b3IuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNSAwODoxNTowMyBzdXJlc2hfZW1haWxpZCBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLnJlZjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1ET01FeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNSXRlcmF0b3I7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5ET01FeGNlcHRpb247Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcudzNjLmRvbS50cmF2ZXJzYWwuTm9kZUZpbHRlcjsKLQotLyoqCi0gKiA8Y29kZT5EVE1Ob2RlSXRlcmF0b3I8L2NvZGU+IGdpdmVzIHVzIGFuIGltcGxlbWVudGF0aW9uIG9mIHRoZQotICogRFRNTm9kZUl0ZXJhdG9yIHdoaWNoIHJldHVybnMgRE9NIG5vZGVzLgotICoKLSAqIFBsZWFzZSBub3RlIHRoYXQgdGhpcyBpcyBub3QgbmVjZXNzYXJpbHkgZXF1aXZsYWVudCB0byBhIERPTQotICogTm9kZUl0ZXJhdG9yIG9wZXJhdGluZyBvdmVyIHRoZSBzYW1lIGRvY3VtZW50LiBJbiBwYXJ0aWN1bGFyOgotICogPHVsPgotICoKLSAqIDxsaT5JZiB0aGVyZSBhcmUgc2V2ZXJhbCBUZXh0IG5vZGVzIGluIGxvZ2ljYWwgc3VjY2Vzc2lvbiAoaWUsCi0gKiBhY3Jvc3MgQ0RBVEFTZWN0aW9uIGFuZCBFbnRpdHlSZWZlcmVuY2UgYm91bmRhcmllcyksIHdlIHdpbGwgcmV0dXJuCi0gKiBvbmx5IHRoZSBmaXJzdDsgdGhlIGNhbGxlciBpcyByZXNwb25zaWJsZSBmb3Igc3RlcHBpbmcgdGhyb3VnaAotICogdGhlbS4KLSAqICglUkVWSUVXJSBQcm92aWRlIGEgY29udmVuaWVuY2Ugcm91dGluZSBoZXJlIHRvIGFzc2lzdCwgcGVuZGluZwotICogcHJvcG9zZWQgRE9NIExldmVsIDMgZ2V0QWRqYWNlbnRUZXh0KCkgb3BlcmF0aW9uPykgPC9saT4KLSAqCi0gKiA8bGk+U2luY2UgdGhlIHdob2xlIFhQYXRoL1hTTFQgYXJjaGl0ZWN0dXJlIGFzc3VtZXMgdGhhdCB0aGUgc291cmNlCi0gKiBkb2N1bWVudCBpcyBub3QgYWx0ZXJlZCB3aGlsZSB3ZSdyZSB3b3JraW5nIHdpdGggaXQsIHdlIGRvIG5vdAotICogcHJvbWlzZSB0byBpbXBsZW1lbnQgdGhlIERPTSBOb2RlSXRlcmF0b3IncyAibWFpbnRhaW4gY3VycmVudAotICogcG9zaXRpb24iIHJlc3BvbnNlIHRvIGRvY3VtZW50IG11dGF0aW9uLiA8L2xpPgotICoKLSAqIDxsaT5TaW5jZSBvdXIgZGVzaWduIGZvciBYUGF0aCBOb2RlSXRlcmF0b3JzIGJ1aWxkcyBhIHN0YXRlZnVsCi0gKiBmaWx0ZXIgZGlyZWN0bHkgaW50byB0aGUgdHJhdmVyc2FsIG9iamVjdCwgZ2V0Tm9kZUZpbHRlcigpIGlzIG5vdAotICogc3VwcG9ydGVkLjwvbGk+Ci0gKgotICogPC91bD4KLSAqCi0gKiA8cD5TdGF0ZTogSW4gcHJvZ3Jlc3MhITwvcD4KLSAqICovCi1wdWJsaWMgY2xhc3MgRFRNTm9kZUl0ZXJhdG9yIGltcGxlbWVudHMgb3JnLnczYy5kb20udHJhdmVyc2FsLk5vZGVJdGVyYXRvcgotewotICBwcml2YXRlIERUTUl0ZXJhdG9yIGR0bV9pdGVyOwotICBwcml2YXRlIGJvb2xlYW4gdmFsaWQ9dHJ1ZTsKLQotICAvLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAgLy8gTWV0aG9kcyB1bmlxdWUgdG8gdGhpcyBjbGFzcwotCi0gIC8qKiBQdWJsaWMgY29uc3RydWN0b3I6IFdyYXAgYSBEVE1Ob2RlSXRlcmF0b3IgYXJvdW5kIGFuIGV4aXN0aW5nCi0gICAqIGFuZCBwcmVjb25maWd1cmVkIERUTUl0ZXJhdG9yCi0gICAqICovCi0gIHB1YmxpYyBEVE1Ob2RlSXRlcmF0b3IoRFRNSXRlcmF0b3IgZHRtSXRlcmF0b3IpCi0gICAgewotICAgICAgdHJ5Ci0gICAgICB7Ci0gICAgICAgIGR0bV9pdGVyPShEVE1JdGVyYXRvcilkdG1JdGVyYXRvci5jbG9uZSgpOwotICAgICAgfQotICAgICAgY2F0Y2goQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gY25zZSkKLSAgICAgIHsKLSAgICAgICAgdGhyb3cgbmV3IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuV3JhcHBlZFJ1bnRpbWVFeGNlcHRpb24oY25zZSk7Ci0gICAgICB9Ci0gICAgfQotCi0gIC8qKiBBY2Nlc3MgdGhlIHdyYXBwZWQgRFRNSXRlcmF0b3IuIEknbSBub3Qgc3VyZSB3aGV0aGVyIGFueW9uZSB3aWxsCi0gICAqIG5lZWQgdGhpcyBvciBub3QsIGJ1dCBsZXQncyB3cml0ZSBpdCBhbmQgdGhpbmsgYWJvdXQgaXQuCi0gICAqICovCi0gIHB1YmxpYyBEVE1JdGVyYXRvciBnZXREVE1JdGVyYXRvcigpCi0gICAgewotICAgICAgcmV0dXJuIGR0bV9pdGVyOwotICAgIH0KLQotCi0gIC8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICAvLyBvcmcudzNjLmRvbS50cmF2ZXJzYWwuTm9kZUZpbHRlciBBUEkgZm9sbG93cwotCi0gIC8qKiBEZXRhY2hlcyB0aGUgTm9kZUl0ZXJhdG9yIGZyb20gdGhlIHNldCB3aGljaCBpdCBpdGVyYXRlZCBvdmVyLAotICAgKiByZWxlYXNpbmcgYW55IGNvbXB1dGF0aW9uYWwgcmVzb3VyY2VzIGFuZCBwbGFjaW5nIHRoZSBpdGVyYXRvciBpbgotICAgKiB0aGUgSU5WQUxJRCBzdGF0ZS4KLSAgICogKi8KLSAgcHVibGljIHZvaWQgZGV0YWNoKCkKLSAgICB7Ci0gICAgICAvLyBUaGVvcmV0aWNhbGx5LCB3ZSBjb3VsZCByZWxlYXNlIGR0bV9pdGVyIGF0IHRoaXMgcG9pbnQuIEJ1dAotICAgICAgLy8gc29tZSBvZiB0aGUgb3BlcmF0aW9ucyBtYXkgc3RpbGwgd2FudCB0byBjb25zdWx0IGl0IGV2ZW4gdGhvdWdoCi0gICAgICAvLyBuYXZpZ2F0aW9uIGlzIG5vdyBpbnZhbGlkLgotICAgICAgdmFsaWQ9ZmFsc2U7Ci0gICAgfQotCi0gIC8qKiBUaGUgdmFsdWUgb2YgdGhpcyBmbGFnIGRldGVybWluZXMgd2hldGhlciB0aGUgY2hpbGRyZW4KLSAgICogb2YgZW50aXR5IHJlZmVyZW5jZSBub2RlcyBhcmUgdmlzaWJsZSB0byB0aGUgaXRlcmF0b3IuCi0gICAqCi0gICAqIEByZXR1cm4gZmFsc2UsIGFsd2F5cyAodGhlIERUTSBtb2RlbCBmbGF0dGVucyBlbnRpdHkgcmVmZXJlbmNlcykKLSAgICogKi8KLSAgcHVibGljIGJvb2xlYW4gZ2V0RXhwYW5kRW50aXR5UmVmZXJlbmNlcygpCi0gICAgewotICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAvKiogUmV0dXJuIGEgaGFuZGxlIHRvIHRoZSBmaWx0ZXIgdXNlZCB0byBzY3JlZW4gbm9kZXMuCi0gICAqCi0gICAqIFRoaXMgaXMgaWxsLWRlZmluZWQgaW4gWGFsYW4ncyB1c2FnZSBvZiBOb2RlaXRlcmF0b3IsIHdoZXJlIHdlIGhhdmUKLSAgICogYnVpbHQgc3RhdGVmdWwgWFBhdGgtYmFzZWQgZmlsdGVyaW5nIGRpcmVjdGx5IGludG8gdGhlIHRyYXZlcnNhbAotICAgKiBvYmplY3QuIFdlIGNvdWxkIHJldHVybiBzb21ldGhpbmcgd2hpY2ggc3VwcG9ydHMgdGhlIE5vZGVGaWx0ZXIgaW50ZXJmYWNlCi0gICAqIGFuZCBhbGxvd3MgcXVlcnlpbmcgd2hldGhlciBhIGdpdmVuIG5vZGUgd291bGQgYmUgcGVybWl0dGVkIGlmIGl0IGFwcGVhcmVkCi0gICAqIGFzIG91ciBuZXh0IG5vZGUsIGJ1dCBpbiB0aGUgY3VycmVudCBpbXBsZW1lbnRhdGlvbiB0aGF0IHdvdWxkIGJlIHZlcnkKLSAgICogY29tcGxleCAtLSBhbmQganVzdCBpc24ndCBhbGwgdGhhdCB1c2VmdWwuCi0gICAqCi0gICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uIC0tIE5PVF9TVVBQT1JURURfRVJST1IgYmVjYXVzZSBJIGNhbid0IHRoaW5rCi0gICAqIG9mIGFueXRoaW5nIG1vcmUgdXNlZnVsIHRvIGRvIGluIHRoaXMgY2FzZQotICAgKiAqLwotICBwdWJsaWMgTm9kZUZpbHRlciBnZXRGaWx0ZXIoKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBEVE1ET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSKTsKLSAgICB9Ci0KLQotICAvKiogQHJldHVybiBUaGUgcm9vdCBub2RlIG9mIHRoZSBOb2RlSXRlcmF0b3IsIGFzIHNwZWNpZmllZAotICAgKiB3aGVuIGl0IHdhcyBjcmVhdGVkLgotICAgKiAqLwotICBwdWJsaWMgTm9kZSBnZXRSb290KCkKLSAgICB7Ci0gICAgICBpbnQgaGFuZGxlPWR0bV9pdGVyLmdldFJvb3QoKTsKLSAgICAgIHJldHVybiBkdG1faXRlci5nZXREVE0oaGFuZGxlKS5nZXROb2RlKGhhbmRsZSk7Ci0gICAgfQotCi0KLSAgLyoqIFJldHVybiBhIG1hc2sgZGVzY3JpYmluZyB3aGljaCBub2RlIHR5cGVzIGFyZSBwcmVzZW50ZWQgdmlhIHRoZQotICAgKiBpdGVyYXRvci4KLSAgICoqLwotICBwdWJsaWMgaW50IGdldFdoYXRUb1Nob3coKQotICAgIHsKLSAgICAgIHJldHVybiBkdG1faXRlci5nZXRXaGF0VG9TaG93KCk7Ci0gICAgfQotCi0gIC8qKiBAcmV0dXJuIHRoZSBuZXh0IG5vZGUgaW4gdGhlIHNldCBhbmQgYWR2YW5jZSB0aGUgcG9zaXRpb24gb2YgdGhlCi0gICAqIGl0ZXJhdG9yIGluIHRoZSBzZXQuCi0gICAqCi0gICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uIC0gSU5WQUxJRF9TVEFURV9FUlIgUmFpc2VkIGlmIHRoaXMgbWV0aG9kIGlzCi0gICAqIGNhbGxlZCBhZnRlciB0aGUgZGV0YWNoIG1ldGhvZCB3YXMgaW52b2tlZC4KLSAgICogICovCi0gIHB1YmxpYyBOb2RlIG5leHROb2RlKCkgdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgIHsKLSAgICAgIGlmKCF2YWxpZCkKLSAgICAgICAgdGhyb3cgbmV3IERUTURPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uSU5WQUxJRF9TVEFURV9FUlIpOwotCi0gICAgICBpbnQgaGFuZGxlPWR0bV9pdGVyLm5leHROb2RlKCk7Ci0gICAgICBpZiAoaGFuZGxlPT1EVE0uTlVMTCkKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICByZXR1cm4gZHRtX2l0ZXIuZ2V0RFRNKGhhbmRsZSkuZ2V0Tm9kZShoYW5kbGUpOwotICAgIH0KLQotCi0gIC8qKiBAcmV0dXJuIHRoZSBuZXh0IHByZXZpb3VzIGluIHRoZSBzZXQgYW5kIGFkdmFuY2UgdGhlIHBvc2l0aW9uIG9mIHRoZQotICAgKiBpdGVyYXRvciBpbiB0aGUgc2V0LgotICAgKgotICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbiAtIElOVkFMSURfU1RBVEVfRVJSIFJhaXNlZCBpZiB0aGlzIG1ldGhvZCBpcwotICAgKiBjYWxsZWQgYWZ0ZXIgdGhlIGRldGFjaCBtZXRob2Qgd2FzIGludm9rZWQuCi0gICAqICAqLwotICBwdWJsaWMgTm9kZSBwcmV2aW91c05vZGUoKQotICAgIHsKLSAgICAgIGlmKCF2YWxpZCkKLSAgICAgICAgdGhyb3cgbmV3IERUTURPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uSU5WQUxJRF9TVEFURV9FUlIpOwotCi0gICAgICBpbnQgaGFuZGxlPWR0bV9pdGVyLnByZXZpb3VzTm9kZSgpOwotICAgICAgaWYgKGhhbmRsZT09RFRNLk5VTEwpCi0gICAgICAgIHJldHVybiBudWxsOwotICAgICAgcmV0dXJuIGR0bV9pdGVyLmdldERUTShoYW5kbGUpLmdldE5vZGUoaGFuZGxlKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vcmVmL0RUTU5vZGVMaXN0LmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vcmVmL0RUTU5vZGVMaXN0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDNhOTMzYzguLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL3JlZi9EVE1Ob2RlTGlzdC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTI5ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IERUTU5vZGVMaXN0LmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTUgMDg6MTU6MDQgc3VyZXNoX2VtYWlsaWQgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5yZWY7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE07Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNSXRlcmF0b3I7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLQotLyoqCi0gKiA8Y29kZT5EVE1Ob2RlTGlzdDwvY29kZT4gZ2l2ZXMgdXMgYW4gaW1wbGVtZW50YXRpb24gb2YgdGhlIERPTSdzCi0gKiBOb2RlTGlzdCBpbnRlcmZhY2Ugd3JhcHBlZCBhcm91bmQgYSBEVE0gSXRlcmF0b3IuIFRoZSBhdXRob3IKLSAqIGNvbnNpZGVycyB0aGlzIHNvbWV0aGluZyBvZiBhbiBhYm9taW5hdGlvbnMsIHNpbmNlIE5vZGVMaXN0IHdhcyBub3QKLSAqIGludGVuZGVkIHRvIGJlIGEgZ2VuZXJhbCBwdXJwb3NlICJsaXN0IG9mIG5vZGVzIiBBUEkgYW5kIGlzCi0gKiBnZW5lcmFsbHkgY29uc2lkZXJlZCBieSB0aGUgRE9NIFdHIHRvIGhhdmUgYmUgYSBtaXN0YWtlLi4uIGJ1dCBJJ20KLSAqIHRvbGQgdGhhdCBzb21lIG9mIHRoZSBYUGF0aC9YU0xUIGZvbGtzIHNheSB0aGV5IG11c3QgaGF2ZSB0aGlzCi0gKiBzb2x1dGlvbi4KLSAqCi0gKiBQbGVhc2Ugbm90ZSB0aGF0IHRoaXMgaXMgbm90IG5lY2Vzc2FyaWx5IGVxdWl2bGFlbnQgdG8gYSBET00KLSAqIE5vZGVMaXN0IG9wZXJhdGluZyBvdmVyIHRoZSBzYW1lIGRvY3VtZW50LiBJbiBwYXJ0aWN1bGFyOgotICogPHVsPgotICoKLSAqIDxsaT5JZiB0aGVyZSBhcmUgc2V2ZXJhbCBUZXh0IG5vZGVzIGluIGxvZ2ljYWwgc3VjY2Vzc2lvbiAoaWUsCi0gKiBhY3Jvc3MgQ0RBVEFTZWN0aW9uIGFuZCBFbnRpdHlSZWZlcmVuY2UgYm91bmRhcmllcyksIHdlIHdpbGwgcmV0dXJuCi0gKiBvbmx5IHRoZSBmaXJzdDsgdGhlIGNhbGxlciBpcyByZXNwb25zaWJsZSBmb3Igc3RlcHBpbmcgdGhyb3VnaAotICogdGhlbS4KLSAqICglUkVWSUVXJSBQcm92aWRlIGEgY29udmVuaWVuY2Ugcm91dGluZSBoZXJlIHRvIGFzc2lzdCwgcGVuZGluZwotICogcHJvcG9zZWQgRE9NIExldmVsIDMgZ2V0QWRqYWNlbnRUZXh0KCkgb3BlcmF0aW9uPykgPC9saT4KLSAqCi0gKiA8bGk+U2luY2UgdGhlIHdob2xlIFhQYXRoL1hTTFQgYXJjaGl0ZWN0dXJlIGFzc3VtZXMgdGhhdCB0aGUgc291cmNlCi0gKiBkb2N1bWVudCBpcyBub3QgYWx0ZXJlZCB3aGlsZSB3ZSdyZSB3b3JraW5nIHdpdGggaXQsIHdlIGRvIG5vdAotICogcHJvbWlzZSB0byBpbXBsZW1lbnQgdGhlIERPTSBOb2RlTGlzdCdzICJsaXZlIHZpZXciIHJlc3BvbnNlIHRvCi0gKiBkb2N1bWVudCBtdXRhdGlvbi4gPC9saT4KLSAqCi0gKiA8L3VsPgotICoKLSAqIDxwPlN0YXRlOiBJbiBwcm9ncmVzcyEhPC9wPgotICogKi8KLXB1YmxpYyBjbGFzcyBEVE1Ob2RlTGlzdCBleHRlbmRzIERUTU5vZGVMaXN0QmFzZSB7Ci0gICAgcHJpdmF0ZSBEVE1JdGVyYXRvciBtX2l0ZXI7Ci0KLSAgICAvLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAgICAvLyBNZXRob2RzIHVuaXF1ZSB0byB0aGlzIGNsYXNzCi0gICAgcHJpdmF0ZSBEVE1Ob2RlTGlzdCgpIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBQdWJsaWMgY29uc3RydWN0b3I6IFdyYXAgYSBEVE1Ob2RlTGlzdCBhcm91bmQgYW4gZXhpc3RpbmcKLSAgICAgKiBhbmQgcHJlY29uZmlndXJlZCBEVE1JdGVyYXRvcgotICAgICAqCi0gICAgICogV0FSTklORzogVEhJUyBIQVMgVEhFIFNJREUgRUZGRUNUIE9GIElTU1VJTkcgc2V0U2hvdWxkQ2FjaGVOb2Rlcyh0cnVlKQotICAgICAqIEFHQUlOU1QgVEhFIERUTUl0ZXJhdG9yLgotICAgICAqCi0gICAgICovCi0gICAgcHVibGljIERUTU5vZGVMaXN0KERUTUl0ZXJhdG9yIGR0bUl0ZXJhdG9yKSB7Ci0gICAgICAgIGlmIChkdG1JdGVyYXRvciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpbnQgcG9zID0gZHRtSXRlcmF0b3IuZ2V0Q3VycmVudFBvcygpOwotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICBtX2l0ZXI9KERUTUl0ZXJhdG9yKWR0bUl0ZXJhdG9yLmNsb25lV2l0aFJlc2V0KCk7Ci0gICAgICAgICAgICB9IGNhdGNoKENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGNuc2UpIHsKLSAgICAgICAgICAgICAgICBtX2l0ZXIgPSBkdG1JdGVyYXRvcjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIG1faXRlci5zZXRTaG91bGRDYWNoZU5vZGVzKHRydWUpOwotICAgICAgICAgICAgbV9pdGVyLnJ1blRvKC0xKTsKLSAgICAgICAgICAgIG1faXRlci5zZXRDdXJyZW50UG9zKHBvcyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBY2Nlc3MgdGhlIHdyYXBwZWQgRFRNSXRlcmF0b3IuIEknbSBub3Qgc3VyZSB3aGV0aGVyIGFueW9uZSB3aWxsCi0gICAgICogbmVlZCB0aGlzIG9yIG5vdCwgYnV0IGxldCdzIHdyaXRlIGl0IGFuZCB0aGluayBhYm91dCBpdC4KLSAgICAgKgotICAgICAqLwotICAgIHB1YmxpYyBEVE1JdGVyYXRvciBnZXREVE1JdGVyYXRvcigpIHsKLSAgICAgICAgcmV0dXJuIG1faXRlcjsKLSAgICB9Ci0KLSAgICAvLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAgICAvLyBvcmcudzNjLmRvbS5Ob2RlTGlzdCBBUEkgZm9sbG93cwotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgPGNvZGU+aW5kZXg8L2NvZGU+dGggaXRlbSBpbiB0aGUgY29sbGVjdGlvbi4gSWYKLSAgICAgKiA8Y29kZT5pbmRleDwvY29kZT4gaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHRoZSBudW1iZXIgb2Ygbm9kZXMgaW4KLSAgICAgKiB0aGUgbGlzdCwgdGhpcyByZXR1cm5zIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAqIEBwYXJhbSBpbmRleCBJbmRleCBpbnRvIHRoZSBjb2xsZWN0aW9uLgotICAgICAqIEByZXR1cm4gVGhlIG5vZGUgYXQgdGhlIDxjb2RlPmluZGV4PC9jb2RlPnRoIHBvc2l0aW9uIGluIHRoZQotICAgICAqICAgPGNvZGU+Tm9kZUxpc3Q8L2NvZGU+LCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGF0IGlzIG5vdCBhIHZhbGlkCi0gICAgICogICBpbmRleC4KLSAgICAgKi8KLSAgICBwdWJsaWMgTm9kZSBpdGVtKGludCBpbmRleCkKLSAgICB7Ci0gICAgICAgIGlmIChtX2l0ZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgaW50IGhhbmRsZT1tX2l0ZXIuaXRlbShpbmRleCk7Ci0gICAgICAgICAgICBpZiAoaGFuZGxlID09IERUTS5OVUxMKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gbV9pdGVyLmdldERUTShoYW5kbGUpLmdldE5vZGUoaGFuZGxlKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhlIG51bWJlciBvZiBub2RlcyBpbiB0aGUgbGlzdC4gVGhlIHJhbmdlIG9mIHZhbGlkIGNoaWxkIG5vZGUgaW5kaWNlcwotICAgICAqIGlzIDAgdG8gPGNvZGU+bGVuZ3RoLTE8L2NvZGU+IGluY2x1c2l2ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldExlbmd0aCgpIHsKLSAgICAgICAgcmV0dXJuIChtX2l0ZXIgIT0gbnVsbCkgPyBtX2l0ZXIuZ2V0TGVuZ3RoKCkgOiAwOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9yZWYvRFRNTm9kZUxpc3RCYXNlLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vcmVmL0RUTU5vZGVMaXN0QmFzZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkMjFmMDkwLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9yZWYvRFRNTm9kZUxpc3RCYXNlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4MyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBEVE1Ob2RlTGlzdEJhc2UuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNSAwODoxNTowNCBzdXJlc2hfZW1haWxpZCBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLnJlZjsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotCi0vKioKLSAqIDxjb2RlPkRUTU5vZGVMaXN0PC9jb2RlPiBnaXZlcyB1cyBhbiBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgRE9NJ3MKLSAqIE5vZGVMaXN0IGludGVyZmFjZSB3cmFwcGVkIGFyb3VuZCBhIERUTSBJdGVyYXRvci4gVGhlIGF1dGhvcgotICogY29uc2lkZXJzIHRoaXMgc29tZXRoaW5nIG9mIGFuIGFib21pbmF0aW9ucywgc2luY2UgTm9kZUxpc3Qgd2FzIG5vdAotICogaW50ZW5kZWQgdG8gYmUgYSBnZW5lcmFsIHB1cnBvc2UgImxpc3Qgb2Ygbm9kZXMiIEFQSSBhbmQgaXMKLSAqIGdlbmVyYWxseSBjb25zaWRlcmVkIGJ5IHRoZSBET00gV0cgdG8gaGF2ZSBiZSBhIG1pc3Rha2UuLi4gYnV0IEknbQotICogdG9sZCB0aGF0IHNvbWUgb2YgdGhlIFhQYXRoL1hTTFQgZm9sa3Mgc2F5IHRoZXkgbXVzdCBoYXZlIHRoaXMKLSAqIHNvbHV0aW9uLgotICoKLSAqIFBsZWFzZSBub3RlIHRoYXQgdGhpcyBpcyBub3QgbmVjZXNzYXJpbHkgZXF1aXZsYWVudCB0byBhIERPTQotICogTm9kZUxpc3Qgb3BlcmF0aW5nIG92ZXIgdGhlIHNhbWUgZG9jdW1lbnQuIEluIHBhcnRpY3VsYXI6Ci0gKiA8dWw+Ci0gKgotICogPGxpPklmIHRoZXJlIGFyZSBzZXZlcmFsIFRleHQgbm9kZXMgaW4gbG9naWNhbCBzdWNjZXNzaW9uIChpZSwKLSAqIGFjcm9zcyBDREFUQVNlY3Rpb24gYW5kIEVudGl0eVJlZmVyZW5jZSBib3VuZGFyaWVzKSwgd2Ugd2lsbCByZXR1cm4KLSAqIG9ubHkgdGhlIGZpcnN0OyB0aGUgY2FsbGVyIGlzIHJlc3BvbnNpYmxlIGZvciBzdGVwcGluZyB0aHJvdWdoCi0gKiB0aGVtLgotICogKCVSRVZJRVclIFByb3ZpZGUgYSBjb252ZW5pZW5jZSByb3V0aW5lIGhlcmUgdG8gYXNzaXN0LCBwZW5kaW5nCi0gKiBwcm9wb3NlZCBET00gTGV2ZWwgMyBnZXRBZGphY2VudFRleHQoKSBvcGVyYXRpb24/KSA8L2xpPgotICoKLSAqIDxsaT5TaW5jZSB0aGUgd2hvbGUgWFBhdGgvWFNMVCBhcmNoaXRlY3R1cmUgYXNzdW1lcyB0aGF0IHRoZSBzb3VyY2UKLSAqIGRvY3VtZW50IGlzIG5vdCBhbHRlcmVkIHdoaWxlIHdlJ3JlIHdvcmtpbmcgd2l0aCBpdCwgd2UgZG8gbm90Ci0gKiBwcm9taXNlIHRvIGltcGxlbWVudCB0aGUgRE9NIE5vZGVMaXN0J3MgImxpdmUgdmlldyIgcmVzcG9uc2UgdG8KLSAqIGRvY3VtZW50IG11dGF0aW9uLiA8L2xpPgotICoKLSAqIDwvdWw+Ci0gKgotICogPHA+U3RhdGU6IEluIHByb2dyZXNzISE8L3A+Ci0gKgotICovCi1wdWJsaWMgY2xhc3MgRFRNTm9kZUxpc3RCYXNlIGltcGxlbWVudHMgb3JnLnczYy5kb20uTm9kZUxpc3QgewotICAgIHB1YmxpYyBEVE1Ob2RlTGlzdEJhc2UoKSB7Ci0gICAgfQotCi0gICAgLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gICAgLy8gb3JnLnczYy5kb20uTm9kZUxpc3QgQVBJIGZvbGxvd3MKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIDxjb2RlPmluZGV4PC9jb2RlPnRoIGl0ZW0gaW4gdGhlIGNvbGxlY3Rpb24uIElmCi0gICAgICogPGNvZGU+aW5kZXg8L2NvZGU+IGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byB0aGUgbnVtYmVyIG9mIG5vZGVzIGluCi0gICAgICogdGhlIGxpc3QsIHRoaXMgcmV0dXJucyA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICAgKiBAcGFyYW0gaW5kZXggSW5kZXggaW50byB0aGUgY29sbGVjdGlvbi4KLSAgICAgKiBAcmV0dXJuIFRoZSBub2RlIGF0IHRoZSA8Y29kZT5pbmRleDwvY29kZT50aCBwb3NpdGlvbiBpbiB0aGUKLSAgICAgKiAgIDxjb2RlPk5vZGVMaXN0PC9jb2RlPiwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhhdCBpcyBub3QgYSB2YWxpZAotICAgICAqICAgaW5kZXguCi0gICAgICovCi0gICAgcHVibGljIE5vZGUgaXRlbShpbnQgaW5kZXgpIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhlIG51bWJlciBvZiBub2RlcyBpbiB0aGUgbGlzdC4gVGhlIHJhbmdlIG9mIHZhbGlkIGNoaWxkIG5vZGUgaW5kaWNlcwotICAgICAqIGlzIDAgdG8gPGNvZGU+bGVuZ3RoLTE8L2NvZGU+IGluY2x1c2l2ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldExlbmd0aCgpIHsKLSAgICAgICAgcmV0dXJuIDA7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL3JlZi9EVE1Ob2RlUHJveHkuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9yZWYvRFRNTm9kZVByb3h5LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDVmZGY2NTMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL3JlZi9EVE1Ob2RlUHJveHkuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI0MTUgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRFRNTm9kZVByb3h5LmphdmEsdgotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLnJlZjsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE07Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNRE9NRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5Ob2RlU2V0OwotaW1wb3J0IGphdmEudXRpbC5PYmplY3RzOwotCi1pbXBvcnQgb3JnLnczYy5kb20uQXR0cjsKLWltcG9ydCBvcmcudzNjLmRvbS5DREFUQVNlY3Rpb247Ci1pbXBvcnQgb3JnLnczYy5kb20uQ29tbWVudDsKLWltcG9ydCBvcmcudzNjLmRvbS5ET01FeGNlcHRpb247Ci1pbXBvcnQgb3JnLnczYy5kb20uRE9NSW1wbGVtZW50YXRpb247Ci1pbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7Ci1pbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnRGcmFnbWVudDsKLWltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudFR5cGU7Ci1pbXBvcnQgb3JnLnczYy5kb20uRWxlbWVudDsKLWltcG9ydCBvcmcudzNjLmRvbS5FbnRpdHlSZWZlcmVuY2U7Ci1pbXBvcnQgb3JnLnczYy5kb20uTmFtZWROb2RlTWFwOwotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZUxpc3Q7Ci1pbXBvcnQgb3JnLnczYy5kb20uUHJvY2Vzc2luZ0luc3RydWN0aW9uOwotaW1wb3J0IG9yZy53M2MuZG9tLlRleHQ7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5Vc2VyRGF0YUhhbmRsZXI7Ci1pbXBvcnQgb3JnLnczYy5kb20uRE9NQ29uZmlndXJhdGlvbjsKLWltcG9ydCBvcmcudzNjLmRvbS5UeXBlSW5mbzsKLQotLyoqCi0gKiA8Y29kZT5EVE1Ob2RlUHJveHk8L2NvZGU+IHByZXNlbnRzIGEgRE9NIE5vZGUgQVBJIGZyb250LWVuZCB0byB0aGUgRFRNIG1vZGVsLgotICogPHA+Ci0gKiBJdCBkb2VzIF9ub3RfIGF0dGVtcHQgdG8gYWRkcmVzcyB0aGUgIm5vZGUgaWRlbnRpdHkiIHF1ZXN0aW9uOyBubyBlZmZvcnQKLSAqIGlzIG1hZGUgdG8gcHJldmVudCB0aGUgY3JlYXRpb24gb2YgbXVsdGlwbGUgcHJveGllcyByZWZlcnJpbmcgdG8gYSBzaW5nbGUKLSAqIERUTSBub2RlLiBVc2VycyBjYW4gY3JlYXRlIGEgbWVjaGFuaXNtIGZvciBtYW5hZ2luZyB0aGlzLCBvciByZWxpbnF1aXNoIHRoZQotICogdXNlIG9mICI9PSIgYW5kIHVzZSB0aGUgLnNhbWVOb2RlQXMoKSBtZWNoYW5pc20sIHdoaWNoIGlzIHVuZGVyCi0gKiBjb25zaWRlcmF0aW9uIGZvciBmdXR1cmUgdmVyc2lvbnMgb2YgdGhlIERPTS4KLSAqIDxwPgotICogRFRNTm9kZVByb3h5IG1heSBiZSBzdWJjbGFzc2VkIGZ1cnRoZXIgdG8gcHJlc2VudCBzcGVjaWZpYyBET00gbm9kZSB0eXBlcy4KLSAqCi0gKiBAc2VlIG9yZy53M2MuZG9tCi0gKi8KLXB1YmxpYyBjbGFzcyBEVE1Ob2RlUHJveHkKLSAgaW1wbGVtZW50cyBOb2RlLCBEb2N1bWVudCwgVGV4dCwgRWxlbWVudCwgQXR0ciwKLSAgICAgICAgICAgICAgICAgICBQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24sIENvbW1lbnQsIERvY3VtZW50RnJhZ21lbnQKLXsKLQotICAvKiogVGhlIERUTSBmb3IgdGhpcyBub2RlLiAqLwotICBwdWJsaWMgRFRNIGR0bTsKLQotICAvKiogVGhlIERUTSBub2RlIGhhbmRsZS4gKi8KLSAgaW50IG5vZGU7Ci0KLSAgLyoqIFRoZSByZXR1cm4gdmFsdWUgYXMgRW1wdHkgU3RyaW5nLiAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRU1QVFlTVFJJTkcgPSAiIjsKLQotICAvKiogVGhlIERPTUltcGxlbWVudGF0aW9uIG9iamVjdCAqLwotICBzdGF0aWMgZmluYWwgRE9NSW1wbGVtZW50YXRpb24gaW1wbGVtZW50YXRpb249bmV3IERUTU5vZGVQcm94eUltcGxlbWVudGF0aW9uKCk7Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIERUTU5vZGVQcm94eSBOb2RlIHJlcHJlc2VudGluZyBhIHNwZWNpZmljIE5vZGUgaW4gYSBEVE0KLSAgICoKLSAgICogQHBhcmFtIGR0bSBUaGUgRFRNIFJlZmVyZW5jZSwgbXVzdCBiZSBub24tbnVsbC4KLSAgICogQHBhcmFtIG5vZGUgVGhlIERUTSBub2RlIGhhbmRsZS4KLSAgICovCi0gIHB1YmxpYyBEVE1Ob2RlUHJveHkoRFRNIGR0bSwgaW50IG5vZGUpCi0gIHsKLSAgICB0aGlzLmR0bSA9IGR0bTsKLSAgICB0aGlzLm5vZGUgPSBub2RlOwotICB9Ci0KLSAgLyoqCi0gICAqIE5PTi1ET006IFJldHVybiB0aGUgRFRNIG1vZGVsCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIERUTSB0aGF0IHRoaXMgcHJveHkgaXMgYSByZXByZXNlbnRhdGl2ZSBmb3IuCi0gICAqLwotICBwdWJsaWMgZmluYWwgRFRNIGdldERUTSgpCi0gIHsKLSAgICByZXR1cm4gZHRtOwotICB9Ci0KLSAgLyoqCi0gICAqIE5PTi1ET006IFJldHVybiB0aGUgRFRNIG5vZGUgbnVtYmVyCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIERUTSBub2RlIGhhbmRsZS4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBpbnQgZ2V0RFRNTm9kZU51bWJlcigpCi0gIHsKLSAgICByZXR1cm4gbm9kZTsKLSAgfQotCi0gIC8qKgotICAgKiBUZXN0IGZvciBlcXVhbGl0eSBiYXNlZCBvbiBub2RlIG51bWJlci4KLSAgICoKLSAgICogQHBhcmFtIG5vZGUgQSBEVE0gbm9kZSBwcm94eSByZWZlcmVuY2UuCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgZ2l2ZW4gbm9kZSBoYXMgdGhlIHNhbWUgaGFuZGxlIGFzIHRoaXMgbm9kZS4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBib29sZWFuIGVxdWFscyhOb2RlIG5vZGUpCi0gIHsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIERUTU5vZGVQcm94eSBkdG1wID0gKERUTU5vZGVQcm94eSkgbm9kZTsKLQotICAgICAgLy8gcmV0dXJuIChkdG1wLm5vZGUgPT0gdGhpcy5ub2RlKTsKLSAgICAgIC8vIFBhdGNoIGF0dHJpYnV0ZWQgdG8gR2FyeSBMIFBlc2tpbiA8Z2FyeXBAZmlyc3RlY2guY29tPgotICAgICAgcmV0dXJuIChkdG1wLm5vZGUgPT0gdGhpcy5ub2RlKSAmJiAoZHRtcC5kdG0gPT0gdGhpcy5kdG0pOwotICAgIH0KLSAgICBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGNjZSkKLSAgICB7Ci0gICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFRlc3QgZm9yIGVxdWFsaXR5IGJhc2VkIG9uIG5vZGUgbnVtYmVyLgotICAgKgotICAgKiBAcGFyYW0gbm9kZSBBIERUTSBub2RlIHByb3h5IHJlZmVyZW5jZS4KLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHRoZSBnaXZlbiBub2RlIGhhcyB0aGUgc2FtZSBoYW5kbGUgYXMgdGhpcyBub2RlLgotICAgKi8KLSAgQE92ZXJyaWRlCi0gIHB1YmxpYyBmaW5hbCBib29sZWFuIGVxdWFscyhPYmplY3Qgbm9kZSkKLSAgewotICAgICAgLy8gRFRNTm9kZVByb3h5IGR0bXAgPSAoRFRNTm9kZVByb3h5KW5vZGU7Ci0gICAgICAvLyByZXR1cm4gKGR0bXAubm9kZSA9PSB0aGlzLm5vZGUpOwotICAgICAgLy8gUGF0Y2ggYXR0cmlidXRlZCB0byBHYXJ5IEwgUGVza2luIDxnYXJ5cEBmaXJzdGVjaC5jb20+Ci0gICAgICByZXR1cm4gbm9kZSBpbnN0YW5jZW9mIE5vZGUgJiYgZXF1YWxzKChOb2RlKSBub2RlKTsKLSAgfQotCi0gIEBPdmVycmlkZQotICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewotICAgICAgaW50IGhhc2ggPSA3OwotICAgICAgaGFzaCA9IDI5ICogaGFzaCArIE9iamVjdHMuaGFzaENvZGUodGhpcy5kdG0pOwotICAgICAgaGFzaCA9IDI5ICogaGFzaCArIHRoaXMubm9kZTsKLSAgICAgIHJldHVybiBoYXNoOwotICB9Ci0KLSAgLyoqCi0gICAqIEZVVFVSRSBET006IFRlc3Qgbm9kZSBpZGVudGl0eSwgaW4gbGlldSBvZiBOb2RlPT1Ob2RlCi0gICAqCi0gICAqIEBwYXJhbSBvdGhlcgotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGdpdmVuIG5vZGUgaGFzIHRoZSBzYW1lIGhhbmRsZSBhcyB0aGlzIG5vZGUuCi0gICAqLwotICBwdWJsaWMgZmluYWwgYm9vbGVhbiBzYW1lTm9kZUFzKE5vZGUgb3RoZXIpCi0gIHsKLQotICAgIGlmICghKG90aGVyIGluc3RhbmNlb2YgRFRNTm9kZVByb3h5KSkKLSAgICAgIHJldHVybiBmYWxzZTsKLQotICAgIERUTU5vZGVQcm94eSB0aGF0ID0gKERUTU5vZGVQcm94eSkgb3RoZXI7Ci0KLSAgICByZXR1cm4gdGhpcy5kdG0gPT0gdGhhdC5kdG0gJiYgdGhpcy5ub2RlID09IHRoYXQubm9kZTsKLSAgfQotCi0gIC8qKgotICAgKgotICAgKgotICAgKiBAc2VlIG9yZy53M2MuZG9tLk5vZGUKLSAgICovCi0gIEBPdmVycmlkZQotICBwdWJsaWMgZmluYWwgU3RyaW5nIGdldE5vZGVOYW1lKCkKLSAgewotICAgIHJldHVybiBkdG0uZ2V0Tm9kZU5hbWUobm9kZSk7Ci0gIH0KLQotICAvKioKLSAgICogQSBQSSdzICJ0YXJnZXQiIHN0YXRlcyB3aGF0IHByb2Nlc3NvciBjaGFubmVsIHRoZSBQSSdzIGRhdGEKLSAgICogc2hvdWxkIGJlIGRpcmVjdGVkIHRvLiBJdCBpcyBkZWZpbmVkIGRpZmZlcmVudGx5IGluIEhUTUwgYW5kIFhNTC4KLSAgICogPHA+Ci0gICAqIEluIFhNTCwgYSBQSSdzICJ0YXJnZXQiIGlzIHRoZSBmaXJzdCAod2hpdGVzcGFjZS1kZWxpbWl0ZWQpIHRva2VuCi0gICAqIGZvbGxvd2luZyB0aGUgIjw/IiB0b2tlbiB0aGF0IGJlZ2lucyB0aGUgUEkuCi0gICAqIDxwPgotICAgKiBJbiBIVE1MLCB0YXJnZXQgaXMgYWx3YXlzIG51bGwuCi0gICAqIDxwPgotICAgKiBOb3RlIHRoYXQgZ2V0Tm9kZU5hbWUgaXMgYWxpYXNlZCB0byBnZXRUYXJnZXQuCi0gICAqCi0gICAqCi0gICAqLwotICBAT3ZlcnJpZGUKLSAgcHVibGljIGZpbmFsIFN0cmluZyBnZXRUYXJnZXQoKQotICB7Ci0gICAgcmV0dXJuIGR0bS5nZXROb2RlTmFtZShub2RlKTsKLSAgfSAgLy8gZ2V0VGFyZ2V0KCk6U3RyaW5nCi0KLSAgLyoqCi0gICAqCi0gICAqCi0gICAqIEBzZWUgb3JnLnczYy5kb20uTm9kZSBhcyBvZiBET00gTGV2ZWwgMgotICAgKi8KLSAgQE92ZXJyaWRlCi0gIHB1YmxpYyBmaW5hbCBTdHJpbmcgZ2V0TG9jYWxOYW1lKCkKLSAgewotICAgIHJldHVybiBkdG0uZ2V0TG9jYWxOYW1lKG5vZGUpOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gVGhlIHByZWZpeCBmb3IgdGhpcyBub2RlLgotICAgKiBAc2VlIG9yZy53M2MuZG9tLk5vZGUgYXMgb2YgRE9NIExldmVsIDIKLSAgICovCi0gIEBPdmVycmlkZQotICBwdWJsaWMgZmluYWwgU3RyaW5nIGdldFByZWZpeCgpCi0gIHsKLSAgICByZXR1cm4gZHRtLmdldFByZWZpeChub2RlKTsKLSAgfQotCi0gIC8qKgotICAgKgotICAgKiBAcGFyYW0gcHJlZml4Ci0gICAqCi0gICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gICAqIEBzZWUgb3JnLnczYy5kb20uTm9kZSBhcyBvZiBET00gTGV2ZWwgMiAtLSBEVE1Ob2RlUHJveHkgaXMgcmVhZC1vbmx5Ci0gICAqLwotICBAT3ZlcnJpZGUKLSAgcHVibGljIGZpbmFsIHZvaWQgc2V0UHJlZml4KFN0cmluZyBwcmVmaXgpIHRocm93cyBET01FeGNlcHRpb24KLSAgewotICAgIHRocm93IG5ldyBEVE1ET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUik7Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICoKLSAgICogQHNlZSBvcmcudzNjLmRvbS5Ob2RlIGFzIG9mIERPTSBMZXZlbCAyCi0gICAqLwotICBAT3ZlcnJpZGUKLSAgcHVibGljIGZpbmFsIFN0cmluZyBnZXROYW1lc3BhY2VVUkkoKQotICB7Ci0gICAgcmV0dXJuIGR0bS5nZXROYW1lc3BhY2VVUkkobm9kZSk7Ci0gIH0KLQotICAvKiogQXNrIHdoZXRoZXIgd2Ugc3VwcG9ydCBhIGdpdmVuIERPTSBmZWF0dXJlLgotICAgKiBJbiBmYWN0LCB3ZSBkbyBub3QgX2Z1bGx5XyBzdXBwb3J0IGFueSBET00gZmVhdHVyZSAtLSB3ZSdyZSBhCi0gICAqIHJlYWQtb25seSBzdWJzZXQgLS0gc28gYXJndWFibHkgd2Ugc2hvdWxkIGFsd2F5cyByZXR1cm4gZmFsc2UuCi0gICAqIE9yIHdlIGNvdWxkIHNheSB0aGF0IHdlIHN1cHBvcnQgRE9NIENvcmUgTGV2ZWwgMiBidXQgYWxsIG5vZGVzCi0gICAqIGFyZSByZWFkLW9ubHkuIFVuY2xlYXIgd2hpY2ggYW5zd2VyIGlzIGxlYXN0IG1pc2xlYWRpbmcuCi0gICAqCi0gICAqIE5PTi1ET00gbWV0aG9kLiBUaGlzIHdhcyBwcmVzZW50IGluIGVhcmx5IGRyYWZ0cyBvZiBET00gTGV2ZWwgMiwKLSAgICogYnV0IHdhcyByZW5hbWVkIGlzU3VwcG9ydGVkLiBJdCdzIHByZXNlbnQgaGVyZSBvbmx5IGJlY2F1c2UgaXQncwotICAgKiBjaGVhcCwgaGFybWxlc3MsIGFuZCBtaWdodCBoZWxwIHNvbWUgcG9vciBmb29sIHdobyBpcyBzdGlsbCB0cnlpbmcKLSAgICogdG8gdXNlIGFuIGVhcmx5IFdvcmtpbmcgRHJhZnQgb2YgdGhlIERPTS4KLSAgICoKLSAgICogQHBhcmFtIGZlYXR1cmUKLSAgICogQHBhcmFtIHZlcnNpb24KLSAgICoKLSAgICogQHJldHVybiBmYWxzZQotICAgKi8KLSAgcHVibGljIGZpbmFsIGJvb2xlYW4gc3VwcG9ydHMoU3RyaW5nIGZlYXR1cmUsIFN0cmluZyB2ZXJzaW9uKQotICB7Ci0gICAgcmV0dXJuIGltcGxlbWVudGF0aW9uLmhhc0ZlYXR1cmUoZmVhdHVyZSx2ZXJzaW9uKTsKLSAgICAvL3Rocm93IG5ldyBEVE1ET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSKTsKLSAgfQotCi0gIC8qKiBBc2sgd2hldGhlciB3ZSBzdXBwb3J0IGEgZ2l2ZW4gRE9NIGZlYXR1cmUuCi0gICAqIEluIGZhY3QsIHdlIGRvIG5vdCBfZnVsbHlfIHN1cHBvcnQgYW55IERPTSBmZWF0dXJlIC0tIHdlJ3JlIGEKLSAgICogcmVhZC1vbmx5IHN1YnNldCAtLSBzbyBhcmd1YWJseSB3ZSBzaG91bGQgYWx3YXlzIHJldHVybiBmYWxzZS4KLSAgICoKLSAgICogQHBhcmFtIGZlYXR1cmUKLSAgICogQHBhcmFtIHZlcnNpb24KLSAgICoKLSAgICogQHJldHVybiBmYWxzZQotICAgKiBAc2VlIG9yZy53M2MuZG9tLk5vZGUgYXMgb2YgRE9NIExldmVsIDIKLSAgICovCi0gIEBPdmVycmlkZQotICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc1N1cHBvcnRlZChTdHJpbmcgZmVhdHVyZSwgU3RyaW5nIHZlcnNpb24pCi0gIHsKLSAgICByZXR1cm4gaW1wbGVtZW50YXRpb24uaGFzRmVhdHVyZShmZWF0dXJlLHZlcnNpb24pOwotICAgIC8vIHRocm93IG5ldyBEVE1ET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSKTsKLSAgfQotCi0gIC8qKgotICAgKgotICAgKgotICAgKgotICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgKiBAc2VlIG9yZy53M2MuZG9tLk5vZGUKLSAgICovCi0gIEBPdmVycmlkZQotICBwdWJsaWMgZmluYWwgU3RyaW5nIGdldE5vZGVWYWx1ZSgpIHRocm93cyBET01FeGNlcHRpb24KLSAgewotICAgIHJldHVybiBkdG0uZ2V0Tm9kZVZhbHVlKG5vZGUpOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gVGhlIHN0cmluZyB2YWx1ZSBvZiB0aGUgbm9kZQotICAgKgotICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGZpbmFsIFN0cmluZyBnZXRTdHJpbmdWYWx1ZSgpIHRocm93cyBET01FeGNlcHRpb24KLSAgewotICAgICAgICByZXR1cm4gZHRtLmdldFN0cmluZ1ZhbHVlKG5vZGUpLnRvU3RyaW5nKCk7Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICogQHBhcmFtIG5vZGVWYWx1ZQotICAgKgotICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgKiBAc2VlIG9yZy53M2MuZG9tLk5vZGUgLS0gRFRNTm9kZVByb3h5IGlzIHJlYWQtb25seQotICAgKi8KLSAgQE92ZXJyaWRlCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHNldE5vZGVWYWx1ZShTdHJpbmcgbm9kZVZhbHVlKSB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gIHsKLSAgICB0aHJvdyBuZXcgRFRNRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIpOwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqCi0gICAqIEBzZWUgb3JnLnczYy5kb20uTm9kZQotICAgKi8KLSAgQE92ZXJyaWRlCi0gIHB1YmxpYyBmaW5hbCBzaG9ydCBnZXROb2RlVHlwZSgpCi0gIHsKLSAgICByZXR1cm4gKHNob3J0KSBkdG0uZ2V0Tm9kZVR5cGUobm9kZSk7Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICoKLSAgICogQHNlZSBvcmcudzNjLmRvbS5Ob2RlCi0gICAqLwotICBAT3ZlcnJpZGUKLSAgcHVibGljIGZpbmFsIE5vZGUgZ2V0UGFyZW50Tm9kZSgpCi0gIHsKLQotICAgIGlmIChnZXROb2RlVHlwZSgpID09IE5vZGUuQVRUUklCVVRFX05PREUpCi0gICAgICByZXR1cm4gbnVsbDsKLQotICAgIGludCBuZXdub2RlID0gZHRtLmdldFBhcmVudChub2RlKTsKLQotICAgIHJldHVybiAobmV3bm9kZSA9PSBEVE0uTlVMTCkgPyBudWxsIDogZHRtLmdldE5vZGUobmV3bm9kZSk7Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICoKLSAgICogQHNlZSBvcmcudzNjLmRvbS5Ob2RlCi0gICAqLwotICBwdWJsaWMgZmluYWwgTm9kZSBnZXRPd25lck5vZGUoKQotICB7Ci0KLSAgICBpbnQgbmV3bm9kZSA9IGR0bS5nZXRQYXJlbnQobm9kZSk7Ci0KLSAgICByZXR1cm4gKG5ld25vZGUgPT0gRFRNLk5VTEwpID8gbnVsbCA6IGR0bS5nZXROb2RlKG5ld25vZGUpOwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqCi0gICAqIEBzZWUgb3JnLnczYy5kb20uTm9kZQotICAgKi8KLSAgQE92ZXJyaWRlCi0gIHB1YmxpYyBmaW5hbCBOb2RlTGlzdCBnZXRDaGlsZE5vZGVzKCkKLSAgewotCi0gICAgLy8gQW5ub3lpbmdseSwgQXhpc0l0ZXJhdG9ycyBkbyBub3QgY3VycmVudGx5IGltcGxlbWVudCBEVE1JdGVyYXRvciwgc28KLSAgICAvLyB3ZSBjYW4ndCBqdXN0IHdhcCBEVE1Ob2RlTGlzdCBhcm91bmQgYW4gQXhpcy5DSElMRCBpdGVyYXRvci4KLSAgICAvLyBJbnN0ZWFkLCB3ZSd2ZSBjcmVhdGVkIGEgc3BlY2lhbC1jYXNlIG9wZXJhdGluZyBtb2RlIGZvciB0aGF0IG9iamVjdC4KLSAgICByZXR1cm4gbmV3IERUTUNoaWxkSXRlck5vZGVMaXN0KGR0bSxub2RlKTsKLQotICAgIC8vIHRocm93IG5ldyBEVE1ET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSKTsKLSAgfQotCi0gIC8qKgotICAgKgotICAgKgotICAgKiBAc2VlIG9yZy53M2MuZG9tLk5vZGUKLSAgICovCi0gIEBPdmVycmlkZQotICBwdWJsaWMgZmluYWwgTm9kZSBnZXRGaXJzdENoaWxkKCkKLSAgewotCi0gICAgaW50IG5ld25vZGUgPSBkdG0uZ2V0Rmlyc3RDaGlsZChub2RlKTsKLQotICAgIHJldHVybiAobmV3bm9kZSA9PSBEVE0uTlVMTCkgPyBudWxsIDogZHRtLmdldE5vZGUobmV3bm9kZSk7Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICoKLSAgICogQHNlZSBvcmcudzNjLmRvbS5Ob2RlCi0gICAqLwotICBAT3ZlcnJpZGUKLSAgcHVibGljIGZpbmFsIE5vZGUgZ2V0TGFzdENoaWxkKCkKLSAgewotCi0gICAgaW50IG5ld25vZGUgPSBkdG0uZ2V0TGFzdENoaWxkKG5vZGUpOwotCi0gICAgcmV0dXJuIChuZXdub2RlID09IERUTS5OVUxMKSA/IG51bGwgOiBkdG0uZ2V0Tm9kZShuZXdub2RlKTsKLSAgfQotCi0gIC8qKgotICAgKgotICAgKgotICAgKiBAc2VlIG9yZy53M2MuZG9tLk5vZGUKLSAgICovCi0gIEBPdmVycmlkZQotICBwdWJsaWMgZmluYWwgTm9kZSBnZXRQcmV2aW91c1NpYmxpbmcoKQotICB7Ci0KLSAgICBpbnQgbmV3bm9kZSA9IGR0bS5nZXRQcmV2aW91c1NpYmxpbmcobm9kZSk7Ci0KLSAgICByZXR1cm4gKG5ld25vZGUgPT0gRFRNLk5VTEwpID8gbnVsbCA6IGR0bS5nZXROb2RlKG5ld25vZGUpOwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqCi0gICAqIEBzZWUgb3JnLnczYy5kb20uTm9kZQotICAgKi8KLSAgQE92ZXJyaWRlCi0gIHB1YmxpYyBmaW5hbCBOb2RlIGdldE5leHRTaWJsaW5nKCkKLSAgewotCi0gICAgLy8gQXR0cidzIE5leHQgaXMgZGVmaW5lZCBhdCBEVE0gbGV2ZWwsIGJ1dCBub3QgYXQgRE9NIGxldmVsLgotICAgIGlmIChkdG0uZ2V0Tm9kZVR5cGUobm9kZSkgPT0gTm9kZS5BVFRSSUJVVEVfTk9ERSkKLSAgICAgIHJldHVybiBudWxsOwotCi0gICAgaW50IG5ld25vZGUgPSBkdG0uZ2V0TmV4dFNpYmxpbmcobm9kZSk7Ci0KLSAgICByZXR1cm4gKG5ld25vZGUgPT0gRFRNLk5VTEwpID8gbnVsbCA6IGR0bS5nZXROb2RlKG5ld25vZGUpOwotICB9Ci0KLSAgLy8gRFRNTmFtZWROb2RlTWFwIG1fYXR0cnM7Ci0KLSAgLyoqCi0gICAqCi0gICAqCi0gICAqIEBzZWUgb3JnLnczYy5kb20uTm9kZQotICAgKi8KLSAgQE92ZXJyaWRlCi0gIHB1YmxpYyBmaW5hbCBOYW1lZE5vZGVNYXAgZ2V0QXR0cmlidXRlcygpCi0gIHsKLQotICAgIHJldHVybiBuZXcgRFRNTmFtZWROb2RlTWFwKGR0bSwgbm9kZSk7Ci0gIH0KLQotICAvKioKLSAgICogTWV0aG9kIGhhc0F0dHJpYnV0ZQotICAgKgotICAgKgotICAgKiBAcGFyYW0gbmFtZQotICAgKgotICAgKi8KLSAgQE92ZXJyaWRlCi0gIHB1YmxpYyBib29sZWFuIGhhc0F0dHJpYnV0ZShTdHJpbmcgbmFtZSkKLSAgewotICAgIHJldHVybiBEVE0uTlVMTCAhPSBkdG0uZ2V0QXR0cmlidXRlTm9kZShub2RlLG51bGwsbmFtZSk7Ci0gIH0KLQotICAvKioKLSAgICogTWV0aG9kIGhhc0F0dHJpYnV0ZU5TCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkKLSAgICogQHBhcmFtIGxvY2FsTmFtZQotICAgKgotICAgKgotICAgKi8KLSAgQE92ZXJyaWRlCi0gIHB1YmxpYyBib29sZWFuIGhhc0F0dHJpYnV0ZU5TKFN0cmluZyBuYW1lc3BhY2VVUkksIFN0cmluZyBsb2NhbE5hbWUpCi0gIHsKLSAgICByZXR1cm4gRFRNLk5VTEwgIT0gZHRtLmdldEF0dHJpYnV0ZU5vZGUobm9kZSxuYW1lc3BhY2VVUkksbG9jYWxOYW1lKTsKLSAgfQotCi0gIC8qKgotICAgKgotICAgKgotICAgKiBAc2VlIG9yZy53M2MuZG9tLk5vZGUKLSAgICovCi0gIEBPdmVycmlkZQotICBwdWJsaWMgZmluYWwgRG9jdW1lbnQgZ2V0T3duZXJEb2N1bWVudCgpCi0gIHsKLSAgICAgICAgLy8gTm90ZSB0aGF0IHRoaXMgdXNlcyB0aGUgRE9NLWNvbXBhdGFibGUgdmVyc2lvbiBvZiB0aGUgY2FsbAotICAgICAgICByZXR1cm4gKERvY3VtZW50KShkdG0uZ2V0Tm9kZShkdG0uZ2V0T3duZXJEb2N1bWVudChub2RlKSkpOwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqIEBwYXJhbSBuZXdDaGlsZAotICAgKiBAcGFyYW0gcmVmQ2hpbGQKLSAgICoKLSAgICoKLSAgICoKLSAgICogQHRocm93cyBET01FeGNlcHRpb24KLSAgICogQHNlZSBvcmcudzNjLmRvbS5Ob2RlIC0tIERUTU5vZGVQcm94eSBpcyByZWFkLW9ubHkKLSAgICovCi0gIEBPdmVycmlkZQotICBwdWJsaWMgZmluYWwgTm9kZSBpbnNlcnRCZWZvcmUoTm9kZSBuZXdDaGlsZCwgTm9kZSByZWZDaGlsZCkKLSAgICB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gIHsKLSAgICB0aHJvdyBuZXcgRFRNRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIpOwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqIEBwYXJhbSBuZXdDaGlsZAotICAgKiBAcGFyYW0gb2xkQ2hpbGQKLSAgICoKLSAgICoKLSAgICoKLSAgICogQHRocm93cyBET01FeGNlcHRpb24KLSAgICogQHNlZSBvcmcudzNjLmRvbS5Ob2RlIC0tIERUTU5vZGVQcm94eSBpcyByZWFkLW9ubHkKLSAgICovCi0gIEBPdmVycmlkZQotICBwdWJsaWMgZmluYWwgTm9kZSByZXBsYWNlQ2hpbGQoTm9kZSBuZXdDaGlsZCwgTm9kZSBvbGRDaGlsZCkKLSAgICB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gIHsKLSAgICB0aHJvdyBuZXcgRFRNRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIpOwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqIEBwYXJhbSBvbGRDaGlsZAotICAgKgotICAgKgotICAgKgotICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgKiBAc2VlIG9yZy53M2MuZG9tLk5vZGUgLS0gRFRNTm9kZVByb3h5IGlzIHJlYWQtb25seQotICAgKi8KLSAgQE92ZXJyaWRlCi0gIHB1YmxpYyBmaW5hbCBOb2RlIHJlbW92ZUNoaWxkKE5vZGUgb2xkQ2hpbGQpIHRocm93cyBET01FeGNlcHRpb24KLSAgewotICAgIHRocm93IG5ldyBEVE1ET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUik7Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICogQHBhcmFtIG5ld0NoaWxkCi0gICAqCi0gICAqCi0gICAqCi0gICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gICAqIEBzZWUgb3JnLnczYy5kb20uTm9kZSAtLSBEVE1Ob2RlUHJveHkgaXMgcmVhZC1vbmx5Ci0gICAqLwotICBAT3ZlcnJpZGUKLSAgcHVibGljIGZpbmFsIE5vZGUgYXBwZW5kQ2hpbGQoTm9kZSBuZXdDaGlsZCkgdGhyb3dzIERPTUV4Y2VwdGlvbgotICB7Ci0gICAgdGhyb3cgbmV3IERUTURPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSKTsKLSAgfQotCi0gIC8qKgotICAgKgotICAgKgotICAgKiBAc2VlIG9yZy53M2MuZG9tLk5vZGUKLSAgICovCi0gIEBPdmVycmlkZQotICBwdWJsaWMgZmluYWwgYm9vbGVhbiBoYXNDaGlsZE5vZGVzKCkKLSAgewotICAgIHJldHVybiAoRFRNLk5VTEwgIT0gZHRtLmdldEZpcnN0Q2hpbGQobm9kZSkpOwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqIEBwYXJhbSBkZWVwCi0gICAqCi0gICAqCi0gICAqIEBzZWUgb3JnLnczYy5kb20uTm9kZSAtLSBEVE1Ob2RlUHJveHkgaXMgcmVhZC1vbmx5Ci0gICAqLwotICBAT3ZlcnJpZGUKLSAgcHVibGljIGZpbmFsIE5vZGUgY2xvbmVOb2RlKGJvb2xlYW4gZGVlcCkKLSAgewotICAgIHRocm93IG5ldyBEVE1ET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSKTsKLSAgfQotCi0gIC8qKgotICAgKgotICAgKgotICAgKiBAc2VlIG9yZy53M2MuZG9tLkRvY3VtZW50Ci0gICAqLwotICBAT3ZlcnJpZGUKLSAgcHVibGljIGZpbmFsIERvY3VtZW50VHlwZSBnZXREb2N0eXBlKCkKLSAgewotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqCi0gICAqIEBzZWUgb3JnLnczYy5kb20uRG9jdW1lbnQKLSAgICovCi0gIEBPdmVycmlkZQotICBwdWJsaWMgZmluYWwgRE9NSW1wbGVtZW50YXRpb24gZ2V0SW1wbGVtZW50YXRpb24oKQotICB7Ci0gICAgcmV0dXJuIGltcGxlbWVudGF0aW9uOwotICB9Ci0KLSAgLyoqIFRoaXMgaXMgYSBiaXQgb2YgYSBwcm9ibGVtIGluIERUTSwgc2luY2UgYSBEVE0gbWF5IGJlIGEgRG9jdW1lbnQKLSAgICogRnJhZ21lbnQgYW5kIGhlbmNlIG5vdCBoYXZlIGEgY2xlYXItY3V0IERvY3VtZW50IEVsZW1lbnQuIFdlIGNhbgotICAgKiBtYWtlIGl0IHdvcmsgaW4gdGhlIHdlbGwtZm9ybWVkIGNhc2VzIGJ1dCB3b3VsZCB0aGF0IGJlIGNvbmZ1c2luZyBmb3Igb3RoZXJzPwotICAgKgotICAgKgotICAgKiBAc2VlIG9yZy53M2MuZG9tLkRvY3VtZW50Ci0gICAqLwotICBAT3ZlcnJpZGUKLSAgcHVibGljIGZpbmFsIEVsZW1lbnQgZ2V0RG9jdW1lbnRFbGVtZW50KCkKLSAgewotICAgICAgICAgICAgICAgIGludCBkb2NoYW5kbGU9ZHRtLmdldERvY3VtZW50KCk7Ci0gICAgICAgICAgICAgICAgaW50IGVsZW1lbnRoYW5kbGU9RFRNLk5VTEw7Ci0gICAgICAgICAgICAgICAgZm9yKGludCBraWRoYW5kbGU9ZHRtLmdldEZpcnN0Q2hpbGQoZG9jaGFuZGxlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2lkaGFuZGxlIT1EVE0uTlVMTDsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2lkaGFuZGxlPWR0bS5nZXROZXh0U2libGluZyhraWRoYW5kbGUpKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHN3aXRjaChkdG0uZ2V0Tm9kZVR5cGUoa2lkaGFuZGxlKSkKLSAgICAgICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgTm9kZS5FTEVNRU5UX05PREU6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKGVsZW1lbnRoYW5kbGUhPURUTS5OVUxMKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudGhhbmRsZT1EVE0uTlVMTDsgLy8gTW9yZSB0aGFuIG9uZTsgaWxsLWZvcm1lZC4KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBraWRoYW5kbGU9ZHRtLmdldExhc3RDaGlsZChkb2NoYW5kbGUpOyAvLyBFbmQgbG9vcAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50aGFuZGxlPWtpZGhhbmRsZTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoZXNlIGFyZSBoYXJtbGVzczsgZG9jdW1lbnQgaXMgc3RpbGwgd2VsbGZvcm1lZAotICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBOb2RlLkNPTU1FTlRfTk9ERToKLSAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgTm9kZS5QUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREU6Ci0gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIE5vZGUuRE9DVU1FTlRfVFlQRV9OT0RFOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLQotICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudGhhbmRsZT1EVE0uTlVMTDsgLy8gaWxsLWZvcm1lZAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBraWRoYW5kbGU9ZHRtLmdldExhc3RDaGlsZChkb2NoYW5kbGUpOyAvLyBFbmQgbG9vcAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaWYoZWxlbWVudGhhbmRsZT09RFRNLk5VTEwpCi0gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRFRNRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUik7Ci0gICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChFbGVtZW50KShkdG0uZ2V0Tm9kZShlbGVtZW50aGFuZGxlKSk7Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICogQHBhcmFtIHRhZ05hbWUKLSAgICoKLSAgICoKLSAgICoKLSAgICogQHRocm93cyBET01FeGNlcHRpb24KLSAgICogQHNlZSBvcmcudzNjLmRvbS5Eb2N1bWVudAotICAgKi8KLSAgQE92ZXJyaWRlCi0gIHB1YmxpYyBmaW5hbCBFbGVtZW50IGNyZWF0ZUVsZW1lbnQoU3RyaW5nIHRhZ05hbWUpIHRocm93cyBET01FeGNlcHRpb24KLSAgewotICAgIHRocm93IG5ldyBEVE1ET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSKTsKLSAgfQotCi0gIC8qKgotICAgKgotICAgKgotICAgKiBAc2VlIG9yZy53M2MuZG9tLkRvY3VtZW50Ci0gICAqLwotICBAT3ZlcnJpZGUKLSAgcHVibGljIGZpbmFsIERvY3VtZW50RnJhZ21lbnQgY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpCi0gIHsKLSAgICB0aHJvdyBuZXcgRFRNRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUik7Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICogQHBhcmFtIGRhdGEKLSAgICoKLSAgICoKLSAgICogQHNlZSBvcmcudzNjLmRvbS5Eb2N1bWVudAotICAgKi8KLSAgQE92ZXJyaWRlCi0gIHB1YmxpYyBmaW5hbCBUZXh0IGNyZWF0ZVRleHROb2RlKFN0cmluZyBkYXRhKQotICB7Ci0gICAgdGhyb3cgbmV3IERUTURPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIpOwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqIEBwYXJhbSBkYXRhCi0gICAqCi0gICAqCi0gICAqIEBzZWUgb3JnLnczYy5kb20uRG9jdW1lbnQKLSAgICovCi0gIEBPdmVycmlkZQotICBwdWJsaWMgZmluYWwgQ29tbWVudCBjcmVhdGVDb21tZW50KFN0cmluZyBkYXRhKQotICB7Ci0gICAgdGhyb3cgbmV3IERUTURPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIpOwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqIEBwYXJhbSBkYXRhCi0gICAqCi0gICAqCi0gICAqCi0gICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gICAqIEBzZWUgb3JnLnczYy5kb20uRG9jdW1lbnQKLSAgICovCi0gIEBPdmVycmlkZQotICBwdWJsaWMgZmluYWwgQ0RBVEFTZWN0aW9uIGNyZWF0ZUNEQVRBU2VjdGlvbihTdHJpbmcgZGF0YSkKLSAgICB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gIHsKLSAgICB0aHJvdyBuZXcgRFRNRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUik7Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICogQHBhcmFtIHRhcmdldAotICAgKiBAcGFyYW0gZGF0YQotICAgKgotICAgKgotICAgKgotICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgKiBAc2VlIG9yZy53M2MuZG9tLkRvY3VtZW50Ci0gICAqLwotICBAT3ZlcnJpZGUKLSAgcHVibGljIGZpbmFsIFByb2Nlc3NpbmdJbnN0cnVjdGlvbiBjcmVhdGVQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyB0YXJnZXQsIFN0cmluZyBkYXRhKSB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gIHsKLSAgICB0aHJvdyBuZXcgRFRNRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUik7Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICogQHBhcmFtIG5hbWUKLSAgICoKLSAgICoKLSAgICoKLSAgICogQHRocm93cyBET01FeGNlcHRpb24KLSAgICogQHNlZSBvcmcudzNjLmRvbS5Eb2N1bWVudAotICAgKi8KLSAgQE92ZXJyaWRlCi0gIHB1YmxpYyBmaW5hbCBBdHRyIGNyZWF0ZUF0dHJpYnV0ZShTdHJpbmcgbmFtZSkgdGhyb3dzIERPTUV4Y2VwdGlvbgotICB7Ci0gICAgdGhyb3cgbmV3IERUTURPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIpOwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lCi0gICAqCi0gICAqCi0gICAqCi0gICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gICAqIEBzZWUgb3JnLnczYy5kb20uRG9jdW1lbnQKLSAgICovCi0gIEBPdmVycmlkZQotICBwdWJsaWMgZmluYWwgRW50aXR5UmVmZXJlbmNlIGNyZWF0ZUVudGl0eVJlZmVyZW5jZShTdHJpbmcgbmFtZSkKLSAgICB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gIHsKLSAgICB0aHJvdyBuZXcgRFRNRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUik7Ci0gIH0KLSAvKioKLSAgICoKLSAgICogQHBhcmFtIHRhZ25hbWUKLSAgICoKLSAgICoKLSAgICogQHNlZSBvcmcudzNjLmRvbS5Eb2N1bWVudAotICAgKi8KLSAgQE92ZXJyaWRlCi0gIHB1YmxpYyBmaW5hbCBOb2RlTGlzdCBnZXRFbGVtZW50c0J5VGFnTmFtZShTdHJpbmcgdGFnbmFtZSkKLSAgewotICAgICAgIFZlY3RvciBsaXN0VmVjdG9yID0gbmV3IFZlY3RvcigpOwotICAgICAgIE5vZGUgcmV0Tm9kZSA9IGR0bS5nZXROb2RlKG5vZGUpOwotICAgICAgIGlmIChyZXROb2RlICE9IG51bGwpCi0gICAgICAgewotICAgICAgICAgYm9vbGVhbiBpc1RhZ05hbWVXaWxkQ2FyZCA9ICIqIi5lcXVhbHModGFnbmFtZSk7Ci0gICAgICAgICBpZiAoRFRNLkVMRU1FTlRfTk9ERSA9PSByZXROb2RlLmdldE5vZGVUeXBlKCkpCi0gICAgICAgICB7Ci0gICAgICAgICAgIE5vZGVMaXN0IG5vZGVMaXN0ID0gcmV0Tm9kZS5nZXRDaGlsZE5vZGVzKCk7Ci0gICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbm9kZUxpc3QuZ2V0TGVuZ3RoKCk7IGkrKykKLSAgICAgICAgICAgewotICAgICAgICAgICAgIHRyYXZlcnNlQ2hpbGRyZW4obGlzdFZlY3Rvciwgbm9kZUxpc3QuaXRlbShpKSwgdGFnbmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzVGFnTmFtZVdpbGRDYXJkKTsKLSAgICAgICAgICAgfQotICAgICAgICAgfSBlbHNlIGlmIChEVE0uRE9DVU1FTlRfTk9ERSA9PSByZXROb2RlLmdldE5vZGVUeXBlKCkpIHsKLSAgICAgICAgICAgdHJhdmVyc2VDaGlsZHJlbihsaXN0VmVjdG9yLCBkdG0uZ2V0Tm9kZShub2RlKSwgdGFnbmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc1RhZ05hbWVXaWxkQ2FyZCk7Ci0gICAgICAgICB9Ci0gICAgICAgfQotICAgICAgIGludCBzaXplID0gbGlzdFZlY3Rvci5zaXplKCk7Ci0gICAgICAgTm9kZVNldCBub2RlU2V0ID0gbmV3IE5vZGVTZXQoc2l6ZSk7Ci0gICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspCi0gICAgICAgewotICAgICAgICAgbm9kZVNldC5hZGROb2RlKChOb2RlKSBsaXN0VmVjdG9yLmVsZW1lbnRBdChpKSk7Ci0gICAgICAgfQotICAgICAgIHJldHVybiAoTm9kZUxpc3QpIG5vZGVTZXQ7Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICogQHBhcmFtIGxpc3RWZWN0b3IKLSAgICogQHBhcmFtIHRlbXBOb2RlCi0gICAqIEBwYXJhbSB0YWduYW1lCi0gICAqIEBwYXJhbSBpc1RhZ05hbWVXaWxkQ2FyZAotICAgKgotICAgKgotICAgKiBQcml2YXRlIG1ldGhvZCB0byBiZSB1c2VkIGZvciByZWN1cnNpdmUgaXRlcmF0aW9ucyB0byBvYnRhaW4gZWxlbWVudHMgYnkgdGFnIG5hbWUuCi0gICAqLwotICBwcml2YXRlIGZpbmFsIHZvaWQgdHJhdmVyc2VDaGlsZHJlbgotICAoCi0gICAgVmVjdG9yIGxpc3RWZWN0b3IsCi0gICAgTm9kZSB0ZW1wTm9kZSwKLSAgICBTdHJpbmcgdGFnbmFtZSwKLSAgICBib29sZWFuIGlzVGFnTmFtZVdpbGRDYXJkKSB7Ci0gICAgaWYgKHRlbXBOb2RlID09IG51bGwpCi0gICAgewotICAgICAgcmV0dXJuOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgaWYgKHRlbXBOb2RlLmdldE5vZGVUeXBlKCkgPT0gRFRNLkVMRU1FTlRfTk9ERQotICAgICAgICAgICAgJiYgKGlzVGFnTmFtZVdpbGRDYXJkIHx8IHRlbXBOb2RlLmdldE5vZGVOYW1lKCkuZXF1YWxzKHRhZ25hbWUpKSkKLSAgICAgIHsKLSAgICAgICAgbGlzdFZlY3Rvci5hZGQodGVtcE5vZGUpOwotICAgICAgfQotICAgICAgaWYodGVtcE5vZGUuaGFzQ2hpbGROb2RlcygpKQotICAgICAgewotICAgICAgICBOb2RlTGlzdCBub2RlTGlzdCA9IHRlbXBOb2RlLmdldENoaWxkTm9kZXMoKTsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBub2RlTGlzdC5nZXRMZW5ndGgoKTsgaSsrKQotICAgICAgICB7Ci0gICAgICAgICAgdHJhdmVyc2VDaGlsZHJlbihsaXN0VmVjdG9yLCBub2RlTGlzdC5pdGVtKGkpLCB0YWduYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNUYWdOYW1lV2lsZENhcmQpOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotICB9Ci0KLQotCi0gIC8qKgotICAgKgotICAgKiBAcGFyYW0gaW1wb3J0ZWROb2RlCi0gICAqIEBwYXJhbSBkZWVwCi0gICAqCi0gICAqCi0gICAqCi0gICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gICAqIEBzZWUgb3JnLnczYy5kb20uRG9jdW1lbnQgYXMgb2YgRE9NIExldmVsIDIgLS0gRFRNTm9kZVByb3h5IGlzIHJlYWQtb25seQotICAgKi8KLSAgQE92ZXJyaWRlCi0gIHB1YmxpYyBmaW5hbCBOb2RlIGltcG9ydE5vZGUoTm9kZSBpbXBvcnRlZE5vZGUsIGJvb2xlYW4gZGVlcCkKLSAgICB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gIHsKLSAgICB0aHJvdyBuZXcgRFRNRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIpOwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkKLSAgICogQHBhcmFtIHF1YWxpZmllZE5hbWUKLSAgICoKLSAgICoKLSAgICoKLSAgICogQHRocm93cyBET01FeGNlcHRpb24KLSAgICogQHNlZSBvcmcudzNjLmRvbS5Eb2N1bWVudCBhcyBvZiBET00gTGV2ZWwgMgotICAgKi8KLSAgQE92ZXJyaWRlCi0gIHB1YmxpYyBmaW5hbCBFbGVtZW50IGNyZWF0ZUVsZW1lbnROUygKLSAgICAgICAgICAgICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIHF1YWxpZmllZE5hbWUpIHRocm93cyBET01FeGNlcHRpb24KLSAgewotICAgIHRocm93IG5ldyBEVE1ET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSKTsKLSAgfQotCi0gIC8qKgotICAgKgotICAgKiBAcGFyYW0gbmFtZXNwYWNlVVJJCi0gICAqIEBwYXJhbSBxdWFsaWZpZWROYW1lCi0gICAqCi0gICAqCi0gICAqCi0gICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gICAqIEBzZWUgb3JnLnczYy5kb20uRG9jdW1lbnQgYXMgb2YgRE9NIExldmVsIDIKLSAgICovCi0gIEBPdmVycmlkZQotICBwdWJsaWMgZmluYWwgQXR0ciBjcmVhdGVBdHRyaWJ1dGVOUygKLSAgICAgICAgICAgICAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkksIFN0cmluZyBxdWFsaWZpZWROYW1lKSB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gIHsKLSAgICB0aHJvdyBuZXcgRFRNRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUik7Ci0gIH0KLQotICAgLyoqCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkKLSAgICogQHBhcmFtIGxvY2FsTmFtZQotICAgKgotICAgKgotICAgKiBAc2VlIG9yZy53M2MuZG9tLkRvY3VtZW50IGFzIG9mIERPTSBMZXZlbCAyCi0gICAqLwotICBAT3ZlcnJpZGUKLSAgcHVibGljIGZpbmFsIE5vZGVMaXN0IGdldEVsZW1lbnRzQnlUYWdOYW1lTlMoU3RyaW5nIG5hbWVzcGFjZVVSSSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGxvY2FsTmFtZSkKLSAgewotICAgIFZlY3RvciBsaXN0VmVjdG9yID0gbmV3IFZlY3RvcigpOwotICAgIE5vZGUgcmV0Tm9kZSA9IGR0bS5nZXROb2RlKG5vZGUpOwotICAgIGlmIChyZXROb2RlICE9IG51bGwpCi0gICAgewotICAgICAgYm9vbGVhbiBpc05hbWVzcGFjZVVSSVdpbGRDYXJkID0gIioiLmVxdWFscyhuYW1lc3BhY2VVUkkpOwotICAgICAgYm9vbGVhbiBpc0xvY2FsTmFtZVdpbGRDYXJkICAgID0gIioiLmVxdWFscyhsb2NhbE5hbWUpOwotICAgICAgaWYgKERUTS5FTEVNRU5UX05PREUgPT0gcmV0Tm9kZS5nZXROb2RlVHlwZSgpKQotICAgICAgewotICAgICAgICBOb2RlTGlzdCBub2RlTGlzdCA9IHJldE5vZGUuZ2V0Q2hpbGROb2RlcygpOwotICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgbm9kZUxpc3QuZ2V0TGVuZ3RoKCk7IGkrKykKLSAgICAgICAgewotICAgICAgICAgIHRyYXZlcnNlQ2hpbGRyZW4obGlzdFZlY3Rvciwgbm9kZUxpc3QuaXRlbShpKSwgbmFtZXNwYWNlVVJJLCBsb2NhbE5hbWUsIGlzTmFtZXNwYWNlVVJJV2lsZENhcmQsIGlzTG9jYWxOYW1lV2lsZENhcmQpOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmKERUTS5ET0NVTUVOVF9OT0RFID09IHJldE5vZGUuZ2V0Tm9kZVR5cGUoKSkKLSAgICAgIHsKLSAgICAgICAgdHJhdmVyc2VDaGlsZHJlbihsaXN0VmVjdG9yLCBkdG0uZ2V0Tm9kZShub2RlKSwgbmFtZXNwYWNlVVJJLCBsb2NhbE5hbWUsIGlzTmFtZXNwYWNlVVJJV2lsZENhcmQsIGlzTG9jYWxOYW1lV2lsZENhcmQpOwotICAgICAgfQotICAgIH0KLSAgICBpbnQgc2l6ZSA9IGxpc3RWZWN0b3Iuc2l6ZSgpOwotICAgIE5vZGVTZXQgbm9kZVNldCA9IG5ldyBOb2RlU2V0KHNpemUpOwotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKQotICAgIHsKLSAgICAgIG5vZGVTZXQuYWRkTm9kZSgoTm9kZSlsaXN0VmVjdG9yLmVsZW1lbnRBdChpKSk7Ci0gICAgfQotICAgIHJldHVybiAoTm9kZUxpc3QpIG5vZGVTZXQ7Ci0gIH0KLSAgLyoqCi0gICAqCi0gICAqIEBwYXJhbSBsaXN0VmVjdG9yCi0gICAqIEBwYXJhbSB0ZW1wTm9kZQotICAgKiBAcGFyYW0gbmFtZXNwYWNlVVJJCi0gICAqIEBwYXJhbSBsb2NhbG5hbWUKLSAgICogQHBhcmFtIGlzTmFtZXNwYWNlVVJJV2lsZENhcmQKLSAgICogQHBhcmFtIGlzTG9jYWxOYW1lV2lsZENhcmQKLSAgICoKLSAgICogUHJpdmF0ZSBtZXRob2QgdG8gYmUgdXNlZCBmb3IgcmVjdXJzaXZlIGl0ZXJhdGlvbnMgdG8gb2J0YWluIGVsZW1lbnRzIGJ5IHRhZyBuYW1lCi0gICAqIGFuZCBuYW1lc3BhY2VVUkkuCi0gICAqLwotICBwcml2YXRlIGZpbmFsIHZvaWQgdHJhdmVyc2VDaGlsZHJlbgotICAoCi0gICBWZWN0b3IgbGlzdFZlY3RvciwKLSAgIE5vZGUgdGVtcE5vZGUsCi0gICBTdHJpbmcgbmFtZXNwYWNlVVJJLAotICAgU3RyaW5nIGxvY2FsbmFtZSwKLSAgIGJvb2xlYW4gaXNOYW1lc3BhY2VVUklXaWxkQ2FyZCwKLSAgIGJvb2xlYW4gaXNMb2NhbE5hbWVXaWxkQ2FyZCkKLSAgIHsKLSAgICBpZiAodGVtcE5vZGUgPT0gbnVsbCkKLSAgICB7Ci0gICAgICByZXR1cm47Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBpZiAodGVtcE5vZGUuZ2V0Tm9kZVR5cGUoKSA9PSBEVE0uRUxFTUVOVF9OT0RFCi0gICAgICAgICAgICAgICYmIChpc0xvY2FsTmFtZVdpbGRDYXJkCi0gICAgICAgICAgICAgICAgICAgICAgfHwgdGVtcE5vZGUuZ2V0TG9jYWxOYW1lKCkuZXF1YWxzKGxvY2FsbmFtZSkpKQotICAgICAgewotICAgICAgICBTdHJpbmcgbnNVUkkgPSB0ZW1wTm9kZS5nZXROYW1lc3BhY2VVUkkoKTsKLSAgICAgICAgaWYgKChuYW1lc3BhY2VVUkkgPT0gbnVsbCAmJiBuc1VSSSA9PSBudWxsKQotICAgICAgICAgICAgICAgfHwgaXNOYW1lc3BhY2VVUklXaWxkQ2FyZAotICAgICAgICAgICAgICAgfHwgKG5hbWVzcGFjZVVSSSAhPSBudWxsICYmIG5hbWVzcGFjZVVSSS5lcXVhbHMobnNVUkkpKSkKLSAgICAgICAgewotICAgICAgICAgIGxpc3RWZWN0b3IuYWRkKHRlbXBOb2RlKTsKLSAgICAgICAgfQotICAgICAgfQotICAgICAgaWYodGVtcE5vZGUuaGFzQ2hpbGROb2RlcygpKQotICAgICAgewotICAgICAgICBOb2RlTGlzdCBubCA9IHRlbXBOb2RlLmdldENoaWxkTm9kZXMoKTsKLSAgICAgICAgZm9yKGludCBpID0gMDsgaSA8IG5sLmdldExlbmd0aCgpOyBpKyspCi0gICAgICAgIHsKLSAgICAgICAgICB0cmF2ZXJzZUNoaWxkcmVuKGxpc3RWZWN0b3IsIG5sLml0ZW0oaSksIG5hbWVzcGFjZVVSSSwgbG9jYWxuYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNOYW1lc3BhY2VVUklXaWxkQ2FyZCwgaXNMb2NhbE5hbWVXaWxkQ2FyZCk7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICB9Ci0gIH0KLSAgLyoqCi0gICAqCi0gICAqIEBwYXJhbSBlbGVtZW50SWQKLSAgICoKLSAgICoKLSAgICogQHNlZSBvcmcudzNjLmRvbS5Eb2N1bWVudCBhcyBvZiBET00gTGV2ZWwgMgotICAgKi8KLSAgQE92ZXJyaWRlCi0gIHB1YmxpYyBmaW5hbCBFbGVtZW50IGdldEVsZW1lbnRCeUlkKFN0cmluZyBlbGVtZW50SWQpCi0gIHsKLSAgICAgICByZXR1cm4gKEVsZW1lbnQpIGR0bS5nZXROb2RlKGR0bS5nZXRFbGVtZW50QnlJZChlbGVtZW50SWQpKTsKLSAgfQotCi0gIC8qKgotICAgKgotICAgKiBAcGFyYW0gb2Zmc2V0Ci0gICAqCi0gICAqCi0gICAqCi0gICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gICAqIEBzZWUgb3JnLnczYy5kb20uVGV4dAotICAgKi8KLSAgQE92ZXJyaWRlCi0gIHB1YmxpYyBmaW5hbCBUZXh0IHNwbGl0VGV4dChpbnQgb2Zmc2V0KSB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gIHsKLSAgICB0aHJvdyBuZXcgRFRNRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUik7Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICoKLSAgICoKLSAgICogQHRocm93cyBET01FeGNlcHRpb24KLSAgICogQHNlZSBvcmcudzNjLmRvbS5DaGFyYWN0ZXJEYXRhCi0gICAqLwotICBAT3ZlcnJpZGUKLSAgcHVibGljIGZpbmFsIFN0cmluZyBnZXREYXRhKCkgdGhyb3dzIERPTUV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIGR0bS5nZXROb2RlVmFsdWUobm9kZSk7Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICogQHBhcmFtIGRhdGEKLSAgICoKLSAgICogQHRocm93cyBET01FeGNlcHRpb24KLSAgICogQHNlZSBvcmcudzNjLmRvbS5DaGFyYWN0ZXJEYXRhCi0gICAqLwotICBAT3ZlcnJpZGUKLSAgcHVibGljIGZpbmFsIHZvaWQgc2V0RGF0YShTdHJpbmcgZGF0YSkgdGhyb3dzIERPTUV4Y2VwdGlvbgotICB7Ci0gICAgdGhyb3cgbmV3IERUTURPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIpOwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqCi0gICAqIEBzZWUgb3JnLnczYy5kb20uQ2hhcmFjdGVyRGF0YQotICAgKi8KLSAgQE92ZXJyaWRlCi0gIHB1YmxpYyBmaW5hbCBpbnQgZ2V0TGVuZ3RoKCkKLSAgewotICAgIC8vICVPUFQlIFRoaXMgc2hvdWxkIGRvIHNvbWV0aGluZyBzbWFydGVyPwotICAgIHJldHVybiBkdG0uZ2V0Tm9kZVZhbHVlKG5vZGUpLmxlbmd0aCgpOwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqIEBwYXJhbSBvZmZzZXQKLSAgICogQHBhcmFtIGNvdW50Ci0gICAqCi0gICAqCi0gICAqCi0gICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gICAqIEBzZWUgb3JnLnczYy5kb20uQ2hhcmFjdGVyRGF0YQotICAgKi8KLSAgQE92ZXJyaWRlCi0gIHB1YmxpYyBmaW5hbCBTdHJpbmcgc3Vic3RyaW5nRGF0YShpbnQgb2Zmc2V0LCBpbnQgY291bnQpIHRocm93cyBET01FeGNlcHRpb24KLSAgewotICAgIHJldHVybiBnZXREYXRhKCkuc3Vic3RyaW5nKG9mZnNldCxvZmZzZXQrY291bnQpOwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqIEBwYXJhbSBhcmcKLSAgICoKLSAgICogQHRocm93cyBET01FeGNlcHRpb24KLSAgICogQHNlZSBvcmcudzNjLmRvbS5DaGFyYWN0ZXJEYXRhCi0gICAqLwotICBAT3ZlcnJpZGUKLSAgcHVibGljIGZpbmFsIHZvaWQgYXBwZW5kRGF0YShTdHJpbmcgYXJnKSB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gIHsKLSAgICB0aHJvdyBuZXcgRFRNRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUik7Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICogQHBhcmFtIG9mZnNldAotICAgKiBAcGFyYW0gYXJnCi0gICAqCi0gICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gICAqIEBzZWUgb3JnLnczYy5kb20uQ2hhcmFjdGVyRGF0YQotICAgKi8KLSAgQE92ZXJyaWRlCi0gIHB1YmxpYyBmaW5hbCB2b2lkIGluc2VydERhdGEoaW50IG9mZnNldCwgU3RyaW5nIGFyZykgdGhyb3dzIERPTUV4Y2VwdGlvbgotICB7Ci0gICAgdGhyb3cgbmV3IERUTURPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIpOwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqIEBwYXJhbSBvZmZzZXQKLSAgICogQHBhcmFtIGNvdW50Ci0gICAqCi0gICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gICAqIEBzZWUgb3JnLnczYy5kb20uQ2hhcmFjdGVyRGF0YQotICAgKi8KLSAgQE92ZXJyaWRlCi0gIHB1YmxpYyBmaW5hbCB2b2lkIGRlbGV0ZURhdGEoaW50IG9mZnNldCwgaW50IGNvdW50KSB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gIHsKLSAgICB0aHJvdyBuZXcgRFRNRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUik7Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICogQHBhcmFtIG9mZnNldAotICAgKiBAcGFyYW0gY291bnQKLSAgICogQHBhcmFtIGFyZwotICAgKgotICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgKiBAc2VlIG9yZy53M2MuZG9tLkNoYXJhY3RlckRhdGEKLSAgICovCi0gIEBPdmVycmlkZQotICBwdWJsaWMgZmluYWwgdm9pZCByZXBsYWNlRGF0YShpbnQgb2Zmc2V0LCBpbnQgY291bnQsIFN0cmluZyBhcmcpCi0gICAgdGhyb3dzIERPTUV4Y2VwdGlvbgotICB7Ci0gICAgdGhyb3cgbmV3IERUTURPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIpOwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqCi0gICAqIEBzZWUgb3JnLnczYy5kb20uRWxlbWVudAotICAgKi8KLSAgQE92ZXJyaWRlCi0gIHB1YmxpYyBmaW5hbCBTdHJpbmcgZ2V0VGFnTmFtZSgpCi0gIHsKLSAgICByZXR1cm4gZHRtLmdldE5vZGVOYW1lKG5vZGUpOwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lCi0gICAqCi0gICAqCi0gICAqIEBzZWUgb3JnLnczYy5kb20uRWxlbWVudAotICAgKi8KLSAgQE92ZXJyaWRlCi0gIHB1YmxpYyBmaW5hbCBTdHJpbmcgZ2V0QXR0cmlidXRlKFN0cmluZyBuYW1lKQotICB7Ci0gICAgRFRNTmFtZWROb2RlTWFwICBtYXAgPSBuZXcgRFRNTmFtZWROb2RlTWFwKGR0bSwgbm9kZSk7Ci0gICAgTm9kZSBuID0gbWFwLmdldE5hbWVkSXRlbShuYW1lKTsKLSAgICByZXR1cm4gKG51bGwgPT0gbikgPyBFTVBUWVNUUklORyA6IG4uZ2V0Tm9kZVZhbHVlKCk7Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICogQHBhcmFtIG5hbWUKLSAgICogQHBhcmFtIHZhbHVlCi0gICAqCi0gICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gICAqIEBzZWUgb3JnLnczYy5kb20uRWxlbWVudAotICAgKi8KLSAgQE92ZXJyaWRlCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHNldEF0dHJpYnV0ZShTdHJpbmcgbmFtZSwgU3RyaW5nIHZhbHVlKQotICAgIHRocm93cyBET01FeGNlcHRpb24KLSAgewotICAgIHRocm93IG5ldyBEVE1ET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSKTsKLSAgfQotCi0gIC8qKgotICAgKgotICAgKiBAcGFyYW0gbmFtZQotICAgKgotICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgKiBAc2VlIG9yZy53M2MuZG9tLkVsZW1lbnQKLSAgICovCi0gIEBPdmVycmlkZQotICBwdWJsaWMgZmluYWwgdm9pZCByZW1vdmVBdHRyaWJ1dGUoU3RyaW5nIG5hbWUpIHRocm93cyBET01FeGNlcHRpb24KLSAgewotICAgIHRocm93IG5ldyBEVE1ET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSKTsKLSAgfQotCi0gIC8qKgotICAgKgotICAgKiBAcGFyYW0gbmFtZQotICAgKgotICAgKgotICAgKiBAc2VlIG9yZy53M2MuZG9tLkVsZW1lbnQKLSAgICovCi0gIEBPdmVycmlkZQotICBwdWJsaWMgZmluYWwgQXR0ciBnZXRBdHRyaWJ1dGVOb2RlKFN0cmluZyBuYW1lKQotICB7Ci0gICAgRFRNTmFtZWROb2RlTWFwICBtYXAgPSBuZXcgRFRNTmFtZWROb2RlTWFwKGR0bSwgbm9kZSk7Ci0gICAgcmV0dXJuIChBdHRyKW1hcC5nZXROYW1lZEl0ZW0obmFtZSk7Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICogQHBhcmFtIG5ld0F0dHIKLSAgICoKLSAgICoKLSAgICoKLSAgICogQHRocm93cyBET01FeGNlcHRpb24KLSAgICogQHNlZSBvcmcudzNjLmRvbS5FbGVtZW50Ci0gICAqLwotICBAT3ZlcnJpZGUKLSAgcHVibGljIGZpbmFsIEF0dHIgc2V0QXR0cmlidXRlTm9kZShBdHRyIG5ld0F0dHIpIHRocm93cyBET01FeGNlcHRpb24KLSAgewotICAgIHRocm93IG5ldyBEVE1ET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSKTsKLSAgfQotCi0gIC8qKgotICAgKgotICAgKiBAcGFyYW0gb2xkQXR0cgotICAgKgotICAgKgotICAgKgotICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgKiBAc2VlIG9yZy53M2MuZG9tLkVsZW1lbnQKLSAgICovCi0gIEBPdmVycmlkZQotICBwdWJsaWMgZmluYWwgQXR0ciByZW1vdmVBdHRyaWJ1dGVOb2RlKEF0dHIgb2xkQXR0cikgdGhyb3dzIERPTUV4Y2VwdGlvbgotICB7Ci0gICAgdGhyb3cgbmV3IERUTURPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIpOwotICB9Ci0KLSAgLyoqCi0gICAqIEludHJvZHVjZWQgaW4gRE9NIExldmVsIDIuCi0gICAqCi0gICAqCi0gICAqLwotICBAT3ZlcnJpZGUKLSAgcHVibGljIGJvb2xlYW4gaGFzQXR0cmlidXRlcygpCi0gIHsKLSAgICByZXR1cm4gRFRNLk5VTEwgIT0gZHRtLmdldEZpcnN0QXR0cmlidXRlKG5vZGUpOwotICB9Ci0KLSAgLyoqIEBzZWUgb3JnLnczYy5kb20uRWxlbWVudCAqLwotICBAT3ZlcnJpZGUKLSAgcHVibGljIGZpbmFsIHZvaWQgbm9ybWFsaXplKCkKLSAgewotICAgIHRocm93IG5ldyBEVE1ET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSKTsKLSAgfQotCi0gIC8qKgotICAgKgotICAgKiBAcGFyYW0gbmFtZXNwYWNlVVJJCi0gICAqIEBwYXJhbSBsb2NhbE5hbWUKLSAgICoKLSAgICoKLSAgICogQHNlZSBvcmcudzNjLmRvbS5FbGVtZW50Ci0gICAqLwotICBAT3ZlcnJpZGUKLSAgcHVibGljIGZpbmFsIFN0cmluZyBnZXRBdHRyaWJ1dGVOUyhTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgbG9jYWxOYW1lKQotICB7Ci0gICAgTm9kZSByZXROb2RlID0gbnVsbDsKLSAgICBpbnQgbiA9IGR0bS5nZXRBdHRyaWJ1dGVOb2RlKG5vZGUsbmFtZXNwYWNlVVJJLGxvY2FsTmFtZSk7Ci0gICAgaWYobiAhPSBEVE0uTlVMTCkKLSAgICAgICAgICAgIHJldE5vZGUgPSBkdG0uZ2V0Tm9kZShuKTsKLSAgICByZXR1cm4gKG51bGwgPT0gcmV0Tm9kZSkgPyBFTVBUWVNUUklORyA6IHJldE5vZGUuZ2V0Tm9kZVZhbHVlKCk7Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICogQHBhcmFtIG5hbWVzcGFjZVVSSQotICAgKiBAcGFyYW0gcXVhbGlmaWVkTmFtZQotICAgKiBAcGFyYW0gdmFsdWUKLSAgICoKLSAgICogQHRocm93cyBET01FeGNlcHRpb24KLSAgICogQHNlZSBvcmcudzNjLmRvbS5FbGVtZW50Ci0gICAqLwotICBAT3ZlcnJpZGUKLSAgcHVibGljIGZpbmFsIHZvaWQgc2V0QXR0cmlidXRlTlMoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkksIFN0cmluZyBxdWFsaWZpZWROYW1lLCBTdHJpbmcgdmFsdWUpCi0gICAgdGhyb3dzIERPTUV4Y2VwdGlvbgotICB7Ci0gICAgdGhyb3cgbmV3IERUTURPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIpOwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkKLSAgICogQHBhcmFtIGxvY2FsTmFtZQotICAgKgotICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgKiBAc2VlIG9yZy53M2MuZG9tLkVsZW1lbnQKLSAgICovCi0gIEBPdmVycmlkZQotICBwdWJsaWMgZmluYWwgdm9pZCByZW1vdmVBdHRyaWJ1dGVOUyhTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgbG9jYWxOYW1lKQotICAgIHRocm93cyBET01FeGNlcHRpb24KLSAgewotICAgIHRocm93IG5ldyBEVE1ET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSKTsKLSAgfQotCi0gIC8qKgotICAgKgotICAgKiBAcGFyYW0gbmFtZXNwYWNlVVJJCi0gICAqIEBwYXJhbSBsb2NhbE5hbWUKLSAgICoKLSAgICoKLSAgICogQHNlZSBvcmcudzNjLmRvbS5FbGVtZW50Ci0gICAqLwotICBAT3ZlcnJpZGUKLSAgcHVibGljIGZpbmFsIEF0dHIgZ2V0QXR0cmlidXRlTm9kZU5TKFN0cmluZyBuYW1lc3BhY2VVUkksIFN0cmluZyBsb2NhbE5hbWUpCi0gIHsKLSAgICAgICBBdHRyIHJldEF0dHIgPSBudWxsOwotICAgICAgIGludCBuID0gZHRtLmdldEF0dHJpYnV0ZU5vZGUobm9kZSxuYW1lc3BhY2VVUkksbG9jYWxOYW1lKTsKLSAgICAgICBpZihuICE9IERUTS5OVUxMKQotICAgICAgICAgICAgICAgcmV0QXR0ciA9IChBdHRyKSBkdG0uZ2V0Tm9kZShuKTsKLSAgICAgICByZXR1cm4gcmV0QXR0cjsKLQotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqIEBwYXJhbSBuZXdBdHRyCi0gICAqCi0gICAqCi0gICAqCi0gICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gICAqIEBzZWUgb3JnLnczYy5kb20uRWxlbWVudAotICAgKi8KLSAgQE92ZXJyaWRlCi0gIHB1YmxpYyBmaW5hbCBBdHRyIHNldEF0dHJpYnV0ZU5vZGVOUyhBdHRyIG5ld0F0dHIpIHRocm93cyBET01FeGNlcHRpb24KLSAgewotICAgIHRocm93IG5ldyBEVE1ET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSKTsKLSAgfQotCi0gIC8qKgotICAgKgotICAgKgotICAgKiBAc2VlIG9yZy53M2MuZG9tLkF0dHIKLSAgICovCi0gIEBPdmVycmlkZQotICBwdWJsaWMgZmluYWwgU3RyaW5nIGdldE5hbWUoKQotICB7Ci0gICAgcmV0dXJuIGR0bS5nZXROb2RlTmFtZShub2RlKTsKLSAgfQotCi0gIC8qKgotICAgKgotICAgKgotICAgKiBAc2VlIG9yZy53M2MuZG9tLkF0dHIKLSAgICovCi0gIEBPdmVycmlkZQotICBwdWJsaWMgZmluYWwgYm9vbGVhbiBnZXRTcGVjaWZpZWQoKQotICB7Ci0gICAgLy8gV2UgcmVhbGx5IGRvbid0IGtub3cgd2hpY2ggYXR0cmlidXRlcyBtaWdodCBoYXZlIGNvbWUgZnJvbSB0aGUKLSAgICAvLyBzb3VyY2UgZG9jdW1lbnQgdmVyc3VzIGZyb20gdGhlIERURC4gVHJlYXQgdGhlbSBhbGwgYXMgaGF2aW5nCi0gICAgLy8gYmVlbiBwcm92aWRlZCBieSB0aGUgdXNlci4KLSAgICAvLyAlUkVWSUVXJSBpZi93aGVuIHdlIGJlY29tZSBhd2FyZSBvZiBEVERzL3NjaGVtYWUuCi0gICAgcmV0dXJuIHRydWU7Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICoKLSAgICogQHNlZSBvcmcudzNjLmRvbS5BdHRyCi0gICAqLwotICBAT3ZlcnJpZGUKLSAgcHVibGljIGZpbmFsIFN0cmluZyBnZXRWYWx1ZSgpCi0gIHsKLSAgICByZXR1cm4gZHRtLmdldE5vZGVWYWx1ZShub2RlKTsKLSAgfQotCi0gIC8qKgotICAgKgotICAgKiBAcGFyYW0gdmFsdWUKLSAgICogQHNlZSBvcmcudzNjLmRvbS5BdHRyCi0gICAqLwotICBAT3ZlcnJpZGUKLSAgcHVibGljIGZpbmFsIHZvaWQgc2V0VmFsdWUoU3RyaW5nIHZhbHVlKQotICB7Ci0gICAgdGhyb3cgbmV3IERUTURPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgb3duZXIgZWxlbWVudCBvZiBhbiBhdHRyaWJ1dGUuCi0gICAqCi0gICAqCi0gICAqIEBzZWUgb3JnLnczYy5kb20uQXR0ciBhcyBvZiBET00gTGV2ZWwgMgotICAgKi8KLSAgQE92ZXJyaWRlCi0gIHB1YmxpYyBmaW5hbCBFbGVtZW50IGdldE93bmVyRWxlbWVudCgpCi0gIHsKLSAgICBpZiAoZ2V0Tm9kZVR5cGUoKSAhPSBOb2RlLkFUVFJJQlVURV9OT0RFKQotICAgICAgcmV0dXJuIG51bGw7Ci0gICAgLy8gSW4gWFBhdGggYW5kIERUTSBkYXRhIG1vZGVscywgdW5saWtlIERPTSwgYW4gQXR0cidzIHBhcmVudCBpcyBpdHMKLSAgICAvLyBvd25lciBlbGVtZW50LgotICAgIGludCBuZXdub2RlID0gZHRtLmdldFBhcmVudChub2RlKTsKLSAgICByZXR1cm4gKG5ld25vZGUgPT0gRFRNLk5VTEwpID8gbnVsbCA6IChFbGVtZW50KShkdG0uZ2V0Tm9kZShuZXdub2RlKSk7Ci0gIH0KLQotICAvKioKLSAgICogTkVFRFNET0MgTWV0aG9kIGFkb3B0Tm9kZQotICAgKgotICAgKgotICAgKiBORUVEU0RPQyBAcGFyYW0gc291cmNlCi0gICAqCi0gICAqIE5FRURTRE9DIChhZG9wdE5vZGUpIEByZXR1cm4KLSAgICoKLSAgICogQHRocm93cyBET01FeGNlcHRpb24KLSAgICovCi0gIEBPdmVycmlkZQotICBwdWJsaWMgTm9kZSBhZG9wdE5vZGUoTm9kZSBzb3VyY2UpIHRocm93cyBET01FeGNlcHRpb24KLSAgewotICAgIHRocm93IG5ldyBEVE1ET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSKTsKLSAgfQotCi0gIC8qKgotICAgKiA8cD5FWFBFUklNRU5UQUwhIEJhc2VkIG9uIHRoZSA8YQotICAgKiBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAxL1dELURPTS1MZXZlbC0zLUNvcmUtMjAwMTA2MDUnPkRvY3VtZW50Ci0gICAqIE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAzIENvcmUgV29ya2luZyBEcmFmdCBvZiA1IEp1bmUgMjAwMS48L2E+LgotICAgKiA8cD4KLSAgICogQW4gYXR0cmlidXRlIHNwZWNpZnlpbmcsIGFzIHBhcnQgb2YgdGhlIFhNTCBkZWNsYXJhdGlvbiwgdGhlIGVuY29kaW5nCi0gICAqIG9mIHRoaXMgZG9jdW1lbnQuIFRoaXMgaXMgPGNvZGU+bnVsbDwvY29kZT4gd2hlbiB1bnNwZWNpZmllZC4KLSAgICogQHNpbmNlIERPTSBMZXZlbCAzCi0gICAqCi0gICAqIE5FRURTRE9DICgkb2JqZWN0TmFtZSQpIEByZXR1cm4KLSAgICovCi0gIEBPdmVycmlkZQotICBwdWJsaWMgU3RyaW5nIGdldElucHV0RW5jb2RpbmcoKQotICB7Ci0gICAgdGhyb3cgbmV3IERUTURPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIpOwotICB9Ci0KLSAgLyoqCi0gICAqIDxwPkVYUEVSSU1FTlRBTCEgQmFzZWQgb24gdGhlIDxhCi0gICAqIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDEvV0QtRE9NLUxldmVsLTMtQ29yZS0yMDAxMDYwNSc+RG9jdW1lbnQKLSAgICogT2JqZWN0IE1vZGVsIChET00pIExldmVsIDMgQ29yZSBXb3JraW5nIERyYWZ0IG9mIDUgSnVuZSAyMDAxLjwvYT4uCi0gICAqIDxwPgotICAgKiBBbiBhdHRyaWJ1dGUgc3BlY2lmeWluZywgYXMgcGFydCBvZiB0aGUgWE1MIGRlY2xhcmF0aW9uLCB0aGUgZW5jb2RpbmcKLSAgICogb2YgdGhpcyBkb2N1bWVudC4gVGhpcyBpcyA8Y29kZT5udWxsPC9jb2RlPiB3aGVuIHVuc3BlY2lmaWVkLgotICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICoKLSAgICogTkVFRFNET0MgQHBhcmFtIGVuY29kaW5nCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRFbmNvZGluZyhTdHJpbmcgZW5jb2RpbmcpCi0gIHsKLSAgICB0aHJvdyBuZXcgRFRNRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUik7Ci0gIH0KLQotICAvKioKLSAgICogPHA+RVhQRVJJTUVOVEFMISBCYXNlZCBvbiB0aGUgPGEKLSAgICogaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMS9XRC1ET00tTGV2ZWwtMy1Db3JlLTIwMDEwNjA1Jz5Eb2N1bWVudAotICAgKiBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMyBDb3JlIFdvcmtpbmcgRHJhZnQgb2YgNSBKdW5lIDIwMDEuPC9hPi4KLSAgICogPHA+Ci0gICAqIEFuIGF0dHJpYnV0ZSBzcGVjaWZ5aW5nLCBhcyBwYXJ0IG9mIHRoZSBYTUwgZGVjbGFyYXRpb24sIHdoZXRoZXIgdGhpcwotICAgKiBkb2N1bWVudCBpcyBzdGFuZGFsb25lLgotICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICoKLSAgICogTkVFRFNET0MgKCRvYmplY3ROYW1lJCkgQHJldHVybgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZ2V0U3RhbmRhbG9uZSgpCi0gIHsKLSAgICB0aHJvdyBuZXcgRFRNRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUik7Ci0gIH0KLQotICAvKioKLSAgICogPHA+RVhQRVJJTUVOVEFMISBCYXNlZCBvbiB0aGUgPGEKLSAgICogaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMS9XRC1ET00tTGV2ZWwtMy1Db3JlLTIwMDEwNjA1Jz5Eb2N1bWVudAotICAgKiBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMyBDb3JlIFdvcmtpbmcgRHJhZnQgb2YgNSBKdW5lIDIwMDEuPC9hPi4KLSAgICogPHA+Ci0gICAqIEFuIGF0dHJpYnV0ZSBzcGVjaWZ5aW5nLCBhcyBwYXJ0IG9mIHRoZSBYTUwgZGVjbGFyYXRpb24sIHdoZXRoZXIgdGhpcwotICAgKiBkb2N1bWVudCBpcyBzdGFuZGFsb25lLgotICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICoKLSAgICogTkVFRFNET0MgQHBhcmFtIHN0YW5kYWxvbmUKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFN0YW5kYWxvbmUoYm9vbGVhbiBzdGFuZGFsb25lKQotICB7Ci0gICAgdGhyb3cgbmV3IERUTURPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIpOwotICB9Ci0KLSAgLyoqCi0gICAqIDxwPkVYUEVSSU1FTlRBTCEgQmFzZWQgb24gdGhlIDxhCi0gICAqIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDEvV0QtRE9NLUxldmVsLTMtQ29yZS0yMDAxMDYwNSc+RG9jdW1lbnQKLSAgICogT2JqZWN0IE1vZGVsIChET00pIExldmVsIDMgQ29yZSBXb3JraW5nIERyYWZ0IG9mIDUgSnVuZSAyMDAxLjwvYT4uCi0gICAqIDxwPgotICAgKiBBbiBhdHRyaWJ1dGUgc3BlY2lmeWluZyB3aGV0aGVyIGVycm9ycyBjaGVja2luZyBpcyBlbmZvcmNlZCBvciBub3QuCi0gICAqIFdoZW4gc2V0IHRvIDxjb2RlPmZhbHNlPC9jb2RlPiwgdGhlIGltcGxlbWVudGF0aW9uIGlzIGZyZWUgdG8gbm90Ci0gICAqIHRlc3QgZXZlcnkgcG9zc2libGUgZXJyb3IgY2FzZSBub3JtYWxseSBkZWZpbmVkIG9uIERPTSBvcGVyYXRpb25zLAotICAgKiBhbmQgbm90IHJhaXNlIGFueSA8Y29kZT5ET01FeGNlcHRpb248L2NvZGU+LiBJbiBjYXNlIG9mIGVycm9yLCB0aGUKLSAgICogYmVoYXZpb3IgaXMgdW5kZWZpbmVkLiBUaGlzIGF0dHJpYnV0ZSBpcyA8Y29kZT50cnVlPC9jb2RlPiBieQotICAgKiBkZWZhdWx0cy4KLSAgICogQHNpbmNlIERPTSBMZXZlbCAzCi0gICAqCi0gICAqIE5FRURTRE9DICgkb2JqZWN0TmFtZSQpIEByZXR1cm4KLSAgICovCi0gIEBPdmVycmlkZQotICBwdWJsaWMgYm9vbGVhbiBnZXRTdHJpY3RFcnJvckNoZWNraW5nKCkKLSAgewotICAgIHRocm93IG5ldyBEVE1ET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSKTsKLSAgfQotCi0gIC8qKgotICAgKiA8cD5FWFBFUklNRU5UQUwhIEJhc2VkIG9uIHRoZSA8YQotICAgKiBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAxL1dELURPTS1MZXZlbC0zLUNvcmUtMjAwMTA2MDUnPkRvY3VtZW50Ci0gICAqIE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAzIENvcmUgV29ya2luZyBEcmFmdCBvZiA1IEp1bmUgMjAwMS48L2E+LgotICAgKiA8cD4KLSAgICogQW4gYXR0cmlidXRlIHNwZWNpZnlpbmcgd2hldGhlciBlcnJvcnMgY2hlY2tpbmcgaXMgZW5mb3JjZWQgb3Igbm90LgotICAgKiBXaGVuIHNldCB0byA8Y29kZT5mYWxzZTwvY29kZT4sIHRoZSBpbXBsZW1lbnRhdGlvbiBpcyBmcmVlIHRvIG5vdAotICAgKiB0ZXN0IGV2ZXJ5IHBvc3NpYmxlIGVycm9yIGNhc2Ugbm9ybWFsbHkgZGVmaW5lZCBvbiBET00gb3BlcmF0aW9ucywKLSAgICogYW5kIG5vdCByYWlzZSBhbnkgPGNvZGU+RE9NRXhjZXB0aW9uPC9jb2RlPi4gSW4gY2FzZSBvZiBlcnJvciwgdGhlCi0gICAqIGJlaGF2aW9yIGlzIHVuZGVmaW5lZC4gVGhpcyBhdHRyaWJ1dGUgaXMgPGNvZGU+dHJ1ZTwvY29kZT4gYnkKLSAgICogZGVmYXVsdHMuCi0gICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgKgotICAgKiBORUVEU0RPQyBAcGFyYW0gc3RyaWN0RXJyb3JDaGVja2luZwotICAgKi8KLSAgQE92ZXJyaWRlCi0gIHB1YmxpYyB2b2lkIHNldFN0cmljdEVycm9yQ2hlY2tpbmcoYm9vbGVhbiBzdHJpY3RFcnJvckNoZWNraW5nKQotICB7Ci0gICAgdGhyb3cgbmV3IERUTURPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIpOwotICB9Ci0KLSAgLyoqCi0gICAqIDxwPkVYUEVSSU1FTlRBTCEgQmFzZWQgb24gdGhlIDxhCi0gICAqIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDEvV0QtRE9NLUxldmVsLTMtQ29yZS0yMDAxMDYwNSc+RG9jdW1lbnQKLSAgICogT2JqZWN0IE1vZGVsIChET00pIExldmVsIDMgQ29yZSBXb3JraW5nIERyYWZ0IG9mIDUgSnVuZSAyMDAxLjwvYT4uCi0gICAqIDxwPgotICAgKiBBbiBhdHRyaWJ1dGUgc3BlY2lmeWluZywgYXMgcGFydCBvZiB0aGUgWE1MIGRlY2xhcmF0aW9uLCB0aGUgdmVyc2lvbgotICAgKiBudW1iZXIgb2YgdGhpcyBkb2N1bWVudC4gVGhpcyBpcyA8Y29kZT5udWxsPC9jb2RlPiB3aGVuIHVuc3BlY2lmaWVkLgotICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICoKLSAgICogTkVFRFNET0MgKCRvYmplY3ROYW1lJCkgQHJldHVybgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRWZXJzaW9uKCkKLSAgewotICAgIHRocm93IG5ldyBEVE1ET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSKTsKLSAgfQotCi0gIC8qKgotICAgKiA8cD5FWFBFUklNRU5UQUwhIEJhc2VkIG9uIHRoZSA8YQotICAgKiBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAxL1dELURPTS1MZXZlbC0zLUNvcmUtMjAwMTA2MDUnPkRvY3VtZW50Ci0gICAqIE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAzIENvcmUgV29ya2luZyBEcmFmdCBvZiA1IEp1bmUgMjAwMS48L2E+LgotICAgKiA8cD4KLSAgICogQW4gYXR0cmlidXRlIHNwZWNpZnlpbmcsIGFzIHBhcnQgb2YgdGhlIFhNTCBkZWNsYXJhdGlvbiwgdGhlIHZlcnNpb24KLSAgICogbnVtYmVyIG9mIHRoaXMgZG9jdW1lbnQuIFRoaXMgaXMgPGNvZGU+bnVsbDwvY29kZT4gd2hlbiB1bnNwZWNpZmllZC4KLSAgICogQHNpbmNlIERPTSBMZXZlbCAzCi0gICAqCi0gICAqIE5FRURTRE9DIEBwYXJhbSB2ZXJzaW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRWZXJzaW9uKFN0cmluZyB2ZXJzaW9uKQotICB7Ci0gICAgdGhyb3cgbmV3IERUTURPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIpOwotICB9Ci0KLQotICAvKiogSW5uZXIgY2xhc3MgdG8gc3VwcG9ydCBnZXRET01JbXBsZW1lbnRhdGlvbi4KLSAgICovCi0gIHN0YXRpYyBjbGFzcyBEVE1Ob2RlUHJveHlJbXBsZW1lbnRhdGlvbiBpbXBsZW1lbnRzIERPTUltcGxlbWVudGF0aW9uCi0gIHsKLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgRG9jdW1lbnRUeXBlIGNyZWF0ZURvY3VtZW50VHlwZShTdHJpbmcgcXVhbGlmaWVkTmFtZSxTdHJpbmcgcHVibGljSWQsIFN0cmluZyBzeXN0ZW1JZCkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgRFRNRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUik7Ci0gICAgfQotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyBEb2N1bWVudCBjcmVhdGVEb2N1bWVudChTdHJpbmcgbmFtZXNwYWNlVVJJLFN0cmluZyBxdWFsZmllZE5hbWUsRG9jdW1lbnRUeXBlIGRvY3R5cGUpCi0gICAgewotICAgICAgLy8gQ291bGQgY3JlYXRlIGEgRFRNLi4uIGJ1dCB3aHksIHdoZW4gaXQnZCBoYXZlIHRvIGJlIHBlcm1hbmFudGx5IGVtcHR5PwotICAgICAgdGhyb3cgbmV3IERUTURPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIpOwotICAgIH0KLSAgICAvKiogQXNrIHdoZXRoZXIgd2Ugc3VwcG9ydCBhIGdpdmVuIERPTSBmZWF0dXJlLgotICAgICAqCi0gICAgICogSW4gZmFjdCwgd2UgZG8gbm90IF9mdWxseV8gc3VwcG9ydCBhbnkgRE9NIGZlYXR1cmUgLS0gd2UncmUgYQotICAgICAqIHJlYWQtb25seSBzdWJzZXQgLS0gc28gYXJndWFibHkgd2Ugc2hvdWxkIGFsd2F5cyByZXR1cm4gZmFsc2UuCi0gICAgICogT24gdGhlIG90aGVyIGhhbmQsIGl0IG1heSBiZSBtb3JlIHByYWN0aWNhbGx5IHVzZWZ1bCB0byByZXR1cm4KLSAgICAgKiB0cnVlIGFuZCBzaW1wbHkgdHJlYXQgdGhlIHdob2xlIERPTSBhcyByZWFkLW9ubHksIGZhaWxpbmcgb24gdGhlCi0gICAgICogbWV0aG9kcyB3ZSBjYW4ndCBzdXBwb3J0LiBJJ20gbm90IHN1cmUgd2hpY2ggd291bGQgYmUgbW9yZSB1c2VmdWwKLSAgICAgKiB0byB0aGUgY2FsbGVyLgotICAgICAqLwotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyBib29sZWFuIGhhc0ZlYXR1cmUoU3RyaW5nIGZlYXR1cmUsU3RyaW5nIHZlcnNpb24pCi0gICAgewotICAgICAgaWYoICgiQ09SRSIuZXF1YWxzKGZlYXR1cmUudG9VcHBlckNhc2UoKSkgfHwgIlhNTCIuZXF1YWxzKGZlYXR1cmUudG9VcHBlckNhc2UoKSkpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYKLSAgICAgICAgICAoIjEuMCIuZXF1YWxzKHZlcnNpb24pIHx8ICIyLjAiLmVxdWFscyh2ZXJzaW9uKSkpCi0gICAgICAgIHJldHVybiB0cnVlOwotICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqICBUaGlzIG1ldGhvZCByZXR1cm5zIGEgc3BlY2lhbGl6ZWQgb2JqZWN0IHdoaWNoIGltcGxlbWVudHMgdGhlCi0gICAgICogc3BlY2lhbGl6ZWQgQVBJcyBvZiB0aGUgc3BlY2lmaWVkIGZlYXR1cmUgYW5kIHZlcnNpb24uIFRoZQotICAgICAqIHNwZWNpYWxpemVkIG9iamVjdCBtYXkgYWxzbyBiZSBvYnRhaW5lZCBieSB1c2luZyBiaW5kaW5nLXNwZWNpZmljCi0gICAgICogY2FzdGluZyBtZXRob2RzIGJ1dCBpcyBub3QgbmVjZXNzYXJpbHkgZXhwZWN0ZWQgdG8sIGFzIGRpc2N1c3NlZCBpbiBNaXhlZCBET00gaW1wbGVtZW50YXRpb25zCi0uCi0gICAgICogQHBhcmFtIGZlYXR1cmUgVGhlIG5hbWUgb2YgdGhlIGZlYXR1cmUgcmVxdWVzdGVkIChjYXNlLWluc2Vuc2l0aXZlKS4KLSAgICAgKiBAcGFyYW0gdmVyc2lvbiAgVGhpcyBpcyB0aGUgdmVyc2lvbiBudW1iZXIgb2YgdGhlIGZlYXR1cmUgdG8gdGVzdC4gSWYKLSAgICAgKiAgIHRoZSB2ZXJzaW9uIGlzIDxjb2RlPm51bGw8L2NvZGU+IG9yIHRoZSBlbXB0eSBzdHJpbmcsIHN1cHBvcnRpbmcKLSAgICAgKiAgIGFueSB2ZXJzaW9uIG9mIHRoZSBmZWF0dXJlIHdpbGwgY2F1c2UgdGhlIG1ldGhvZCB0byByZXR1cm4gYW4KLSAgICAgKiAgIG9iamVjdCB0aGF0IHN1cHBvcnRzIGF0IGxlYXN0IG9uZSB2ZXJzaW9uIG9mIHRoZSBmZWF0dXJlLgotICAgICAqIEByZXR1cm4gIFJldHVybnMgYW4gb2JqZWN0IHdoaWNoIGltcGxlbWVudHMgdGhlIHNwZWNpYWxpemVkIEFQSXMgb2YKLSAgICAgKiAgIHRoZSBzcGVjaWZpZWQgZmVhdHVyZSBhbmQgdmVyc2lvbiwgaWYgYW55LCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZgotICAgICAqICAgdGhlcmUgaXMgbm8gb2JqZWN0IHdoaWNoIGltcGxlbWVudHMgaW50ZXJmYWNlcyBhc3NvY2lhdGVkIHdpdGggdGhhdAotICAgICAqICAgZmVhdHVyZS4gSWYgdGhlIDxjb2RlPkRPTU9iamVjdDwvY29kZT4gcmV0dXJuZWQgYnkgdGhpcyBtZXRob2QKLSAgICAgKiAgIGltcGxlbWVudHMgdGhlIDxjb2RlPk5vZGU8L2NvZGU+IGludGVyZmFjZSwgaXQgbXVzdCBkZWxlZ2F0ZSB0byB0aGUKLSAgICAgKiAgIHByaW1hcnkgY29yZSA8Y29kZT5Ob2RlPC9jb2RlPiBhbmQgbm90IHJldHVybiByZXN1bHRzIGluY29uc2lzdGVudAotICAgICAqICAgd2l0aCB0aGUgcHJpbWFyeSBjb3JlIDxjb2RlPk5vZGU8L2NvZGU+IHN1Y2ggYXMgYXR0cmlidXRlcywKLSAgICAgKiAgIGNoaWxkTm9kZXMsIGV0Yy4KLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICAgKi8KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgT2JqZWN0IGdldEZlYXR1cmUoU3RyaW5nIGZlYXR1cmUsIFN0cmluZyB2ZXJzaW9uKSB7Ci0gICAgICAgIC8vIHdlIGRvbid0IGhhdmUgYW55IGFsdGVybmF0ZSBub2RlLCBlaXRoZXIgdGhpcyBub2RlIGRvZXMgdGhlIGpvYgotICAgICAgICAvLyBvciB3ZSBkb24ndCBoYXZlIGFueXRoaW5nIHRoYXQgZG9lcwotICAgICAgICAvL3JldHVybiBoYXNGZWF0dXJlKGZlYXR1cmUsIHZlcnNpb24pID8gdGhpcyA6IG51bGw7Ci0gICAgICAgIHJldHVybiBudWxsOyAvL1BFTkRJTkcKLSAgICB9Ci0KLSAgfQotCi0KLS8vUkFNRVNIIDogUGVuZGluZyBwcm9wZXIgaW1wbGVtZW50YXRpb24gb2YgRE9NIExldmVsIDMKLQotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyBPYmplY3Qgc2V0VXNlckRhdGEoU3RyaW5nIGtleSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9iamVjdCBkYXRhLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVXNlckRhdGFIYW5kbGVyIGhhbmRsZXIpIHsKLSAgICAgICAgcmV0dXJuIGdldE93bmVyRG9jdW1lbnQoKS5zZXRVc2VyRGF0YSgga2V5LCBkYXRhLCBoYW5kbGVyKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXRyaWV2ZXMgdGhlIG9iamVjdCBhc3NvY2lhdGVkIHRvIGEga2V5IG9uIGEgdGhpcyBub2RlLiBUaGUgb2JqZWN0Ci0gICAgICogbXVzdCBmaXJzdCBoYXZlIGJlZW4gc2V0IHRvIHRoaXMgbm9kZSBieSBjYWxsaW5nCi0gICAgICogPGNvZGU+c2V0VXNlckRhdGE8L2NvZGU+IHdpdGggdGhlIHNhbWUga2V5LgotICAgICAqIEBwYXJhbSBrZXkgVGhlIGtleSB0aGUgb2JqZWN0IGlzIGFzc29jaWF0ZWQgdG8uCi0gICAgICogQHJldHVybiBSZXR1cm5zIHRoZSA8Y29kZT5ET01PYmplY3Q8L2NvZGU+IGFzc29jaWF0ZWQgdG8gdGhlIGdpdmVuIGtleQotICAgICAqICAgb24gdGhpcyBub2RlLCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGVyZSB3YXMgbm9uZS4KLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICAgKi8KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgT2JqZWN0IGdldFVzZXJEYXRhKFN0cmluZyBrZXkpIHsKLSAgICAgICAgcmV0dXJuIGdldE93bmVyRG9jdW1lbnQoKS5nZXRVc2VyRGF0YSgga2V5KTsKLSAgICB9Ci0KLSAgICAgIC8qKgotICAgICAqICBUaGlzIG1ldGhvZCByZXR1cm5zIGEgc3BlY2lhbGl6ZWQgb2JqZWN0IHdoaWNoIGltcGxlbWVudHMgdGhlCi0gICAgICogc3BlY2lhbGl6ZWQgQVBJcyBvZiB0aGUgc3BlY2lmaWVkIGZlYXR1cmUgYW5kIHZlcnNpb24uIFRoZQotICAgICAqIHNwZWNpYWxpemVkIG9iamVjdCBtYXkgYWxzbyBiZSBvYnRhaW5lZCBieSB1c2luZyBiaW5kaW5nLXNwZWNpZmljCi0gICAgICogY2FzdGluZyBtZXRob2RzIGJ1dCBpcyBub3QgbmVjZXNzYXJpbHkgZXhwZWN0ZWQgdG8sIGFzIGRpc2N1c3NlZCBpbiBNaXhlZCBET00gaW1wbGVtZW50YXRpb25zLgotICAgICAqIEBwYXJhbSBmZWF0dXJlIFRoZSBuYW1lIG9mIHRoZSBmZWF0dXJlIHJlcXVlc3RlZCAoY2FzZS1pbnNlbnNpdGl2ZSkuCi0gICAgICogQHBhcmFtIHZlcnNpb24gIFRoaXMgaXMgdGhlIHZlcnNpb24gbnVtYmVyIG9mIHRoZSBmZWF0dXJlIHRvIHRlc3QuIElmCi0gICAgICogICB0aGUgdmVyc2lvbiBpcyA8Y29kZT5udWxsPC9jb2RlPiBvciB0aGUgZW1wdHkgc3RyaW5nLCBzdXBwb3J0aW5nCi0gICAgICogICBhbnkgdmVyc2lvbiBvZiB0aGUgZmVhdHVyZSB3aWxsIGNhdXNlIHRoZSBtZXRob2QgdG8gcmV0dXJuIGFuCi0gICAgICogICBvYmplY3QgdGhhdCBzdXBwb3J0cyBhdCBsZWFzdCBvbmUgdmVyc2lvbiBvZiB0aGUgZmVhdHVyZS4KLSAgICAgKiBAcmV0dXJuICBSZXR1cm5zIGFuIG9iamVjdCB3aGljaCBpbXBsZW1lbnRzIHRoZSBzcGVjaWFsaXplZCBBUElzIG9mCi0gICAgICogICB0aGUgc3BlY2lmaWVkIGZlYXR1cmUgYW5kIHZlcnNpb24sIGlmIGFueSwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYKLSAgICAgKiAgIHRoZXJlIGlzIG5vIG9iamVjdCB3aGljaCBpbXBsZW1lbnRzIGludGVyZmFjZXMgYXNzb2NpYXRlZCB3aXRoIHRoYXQKLSAgICAgKiAgIGZlYXR1cmUuIElmIHRoZSA8Y29kZT5ET01PYmplY3Q8L2NvZGU+IHJldHVybmVkIGJ5IHRoaXMgbWV0aG9kCi0gICAgICogICBpbXBsZW1lbnRzIHRoZSA8Y29kZT5Ob2RlPC9jb2RlPiBpbnRlcmZhY2UsIGl0IG11c3QgZGVsZWdhdGUgdG8gdGhlCi0gICAgICogICBwcmltYXJ5IGNvcmUgPGNvZGU+Tm9kZTwvY29kZT4gYW5kIG5vdCByZXR1cm4gcmVzdWx0cyBpbmNvbnNpc3RlbnQKLSAgICAgKiAgIHdpdGggdGhlIHByaW1hcnkgY29yZSA8Y29kZT5Ob2RlPC9jb2RlPiBzdWNoIGFzIGF0dHJpYnV0ZXMsCi0gICAgICogICBjaGlsZE5vZGVzLCBldGMuCi0gICAgICogQHNpbmNlIERPTSBMZXZlbCAzCi0gICAgICovCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIE9iamVjdCBnZXRGZWF0dXJlKFN0cmluZyBmZWF0dXJlLCBTdHJpbmcgdmVyc2lvbikgewotICAgICAgICAvLyB3ZSBkb24ndCBoYXZlIGFueSBhbHRlcm5hdGUgbm9kZSwgZWl0aGVyIHRoaXMgbm9kZSBkb2VzIHRoZSBqb2IKLSAgICAgICAgLy8gb3Igd2UgZG9uJ3QgaGF2ZSBhbnl0aGluZyB0aGF0IGRvZXMKLSAgICAgICAgcmV0dXJuIGlzU3VwcG9ydGVkKGZlYXR1cmUsIHZlcnNpb24pID8gdGhpcyA6IG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGVzdHMgd2hldGhlciB0d28gbm9kZXMgYXJlIGVxdWFsLgotICAgICAqIDxicj5UaGlzIG1ldGhvZCB0ZXN0cyBmb3IgZXF1YWxpdHkgb2Ygbm9kZXMsIG5vdCBzYW1lbmVzcyAoaS5lLiwKLSAgICAgKiB3aGV0aGVyIHRoZSB0d28gbm9kZXMgYXJlIHJlZmVyZW5jZXMgdG8gdGhlIHNhbWUgb2JqZWN0KSB3aGljaCBjYW4gYmUKLSAgICAgKiB0ZXN0ZWQgd2l0aCA8Y29kZT5Ob2RlLmlzU2FtZU5vZGU8L2NvZGU+LiBBbGwgbm9kZXMgdGhhdCBhcmUgdGhlIHNhbWUKLSAgICAgKiB3aWxsIGFsc28gYmUgZXF1YWwsIHRob3VnaCB0aGUgcmV2ZXJzZSBtYXkgbm90IGJlIHRydWUuCi0gICAgICogPGJyPlR3byBub2RlcyBhcmUgZXF1YWwgaWYgYW5kIG9ubHkgaWYgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQotICAgICAqIHNhdGlzZmllZDogVGhlIHR3byBub2RlcyBhcmUgb2YgdGhlIHNhbWUgdHlwZS5UaGUgZm9sbG93aW5nIHN0cmluZwotICAgICAqIGF0dHJpYnV0ZXMgYXJlIGVxdWFsOiA8Y29kZT5ub2RlTmFtZTwvY29kZT4sIDxjb2RlPmxvY2FsTmFtZTwvY29kZT4sCi0gICAgICogPGNvZGU+bmFtZXNwYWNlVVJJPC9jb2RlPiwgPGNvZGU+cHJlZml4PC9jb2RlPiwgPGNvZGU+bm9kZVZhbHVlPC9jb2RlPgotICAgICAqICwgPGNvZGU+YmFzZVVSSTwvY29kZT4uIFRoaXMgaXM6IHRoZXkgYXJlIGJvdGggPGNvZGU+bnVsbDwvY29kZT4sIG9yCi0gICAgICogdGhleSBoYXZlIHRoZSBzYW1lIGxlbmd0aCBhbmQgYXJlIGNoYXJhY3RlciBmb3IgY2hhcmFjdGVyIGlkZW50aWNhbC4KLSAgICAgKiBUaGUgPGNvZGU+YXR0cmlidXRlczwvY29kZT4gPGNvZGU+TmFtZWROb2RlTWFwczwvY29kZT4gYXJlIGVxdWFsLgotICAgICAqIFRoaXMgaXM6IHRoZXkgYXJlIGJvdGggPGNvZGU+bnVsbDwvY29kZT4sIG9yIHRoZXkgaGF2ZSB0aGUgc2FtZQotICAgICAqIGxlbmd0aCBhbmQgZm9yIGVhY2ggbm9kZSB0aGF0IGV4aXN0cyBpbiBvbmUgbWFwIHRoZXJlIGlzIGEgbm9kZSB0aGF0Ci0gICAgICogZXhpc3RzIGluIHRoZSBvdGhlciBtYXAgYW5kIGlzIGVxdWFsLCBhbHRob3VnaCBub3QgbmVjZXNzYXJpbHkgYXQgdGhlCi0gICAgICogc2FtZSBpbmRleC5UaGUgPGNvZGU+Y2hpbGROb2RlczwvY29kZT4gPGNvZGU+Tm9kZUxpc3RzPC9jb2RlPiBhcmUKLSAgICAgKiBlcXVhbC4gVGhpcyBpczogdGhleSBhcmUgYm90aCA8Y29kZT5udWxsPC9jb2RlPiwgb3IgdGhleSBoYXZlIHRoZQotICAgICAqIHNhbWUgbGVuZ3RoIGFuZCBjb250YWluIGVxdWFsIG5vZGVzIGF0IHRoZSBzYW1lIGluZGV4LiBUaGlzIGlzIHRydWUKLSAgICAgKiBmb3IgPGNvZGU+QXR0cjwvY29kZT4gbm9kZXMgYXMgZm9yIGFueSBvdGhlciB0eXBlIG9mIG5vZGUuIE5vdGUgdGhhdAotICAgICAqIG5vcm1hbGl6YXRpb24gY2FuIGFmZmVjdCBlcXVhbGl0eTsgdG8gYXZvaWQgdGhpcywgbm9kZXMgc2hvdWxkIGJlCi0gICAgICogbm9ybWFsaXplZCBiZWZvcmUgYmVpbmcgY29tcGFyZWQuCi0gICAgICogPGJyPkZvciB0d28gPGNvZGU+RG9jdW1lbnRUeXBlPC9jb2RlPiBub2RlcyB0byBiZSBlcXVhbCwgdGhlIGZvbGxvd2luZwotICAgICAqIGNvbmRpdGlvbnMgbXVzdCBhbHNvIGJlIHNhdGlzZmllZDogVGhlIGZvbGxvd2luZyBzdHJpbmcgYXR0cmlidXRlcwotICAgICAqIGFyZSBlcXVhbDogPGNvZGU+cHVibGljSWQ8L2NvZGU+LCA8Y29kZT5zeXN0ZW1JZDwvY29kZT4sCi0gICAgICogPGNvZGU+aW50ZXJuYWxTdWJzZXQ8L2NvZGU+LlRoZSA8Y29kZT5lbnRpdGllczwvY29kZT4KLSAgICAgKiA8Y29kZT5OYW1lZE5vZGVNYXBzPC9jb2RlPiBhcmUgZXF1YWwuVGhlIDxjb2RlPm5vdGF0aW9uczwvY29kZT4KLSAgICAgKiA8Y29kZT5OYW1lZE5vZGVNYXBzPC9jb2RlPiBhcmUgZXF1YWwuCi0gICAgICogPGJyPk9uIHRoZSBvdGhlciBoYW5kLCB0aGUgZm9sbG93aW5nIGRvIG5vdCBhZmZlY3QgZXF1YWxpdHk6IHRoZQotICAgICAqIDxjb2RlPm93bmVyRG9jdW1lbnQ8L2NvZGU+IGF0dHJpYnV0ZSwgdGhlIDxjb2RlPnNwZWNpZmllZDwvY29kZT4KLSAgICAgKiBhdHRyaWJ1dGUgZm9yIDxjb2RlPkF0dHI8L2NvZGU+IG5vZGVzLCB0aGUKLSAgICAgKiA8Y29kZT5pc1doaXRlc3BhY2VJbkVsZW1lbnRDb250ZW50PC9jb2RlPiBhdHRyaWJ1dGUgZm9yCi0gICAgICogPGNvZGU+VGV4dDwvY29kZT4gbm9kZXMsIGFzIHdlbGwgYXMgYW55IHVzZXIgZGF0YSBvciBldmVudCBsaXN0ZW5lcnMKLSAgICAgKiByZWdpc3RlcmVkIG9uIHRoZSBub2Rlcy4KLSAgICAgKiBAcGFyYW0gYXJnIFRoZSBub2RlIHRvIGNvbXBhcmUgZXF1YWxpdHkgd2l0aC4KLSAgICAgKiBAcGFyYW0gZGVlcCBJZiA8Y29kZT50cnVlPC9jb2RlPiwgcmVjdXJzaXZlbHkgY29tcGFyZSB0aGUgc3VidHJlZXM7IGlmCi0gICAgICogICA8Y29kZT5mYWxzZTwvY29kZT4sIGNvbXBhcmUgb25seSB0aGUgbm9kZXMgdGhlbXNlbHZlcyAoYW5kIGl0cwotICAgICAqICAgYXR0cmlidXRlcywgaWYgaXQgaXMgYW4gPGNvZGU+RWxlbWVudDwvY29kZT4pLgotICAgICAqIEByZXR1cm4gSWYgdGhlIG5vZGVzLCBhbmQgcG9zc2libHkgc3VidHJlZXMgYXJlIGVxdWFsLAotICAgICAqICAgPGNvZGU+dHJ1ZTwvY29kZT4gb3RoZXJ3aXNlIDxjb2RlPmZhbHNlPC9jb2RlPi4KLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICAgKi8KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgYm9vbGVhbiBpc0VxdWFsTm9kZShOb2RlIGFyZykgewotICAgICAgICBpZiAoYXJnID09IHRoaXMpIHsKLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0gICAgICAgIGlmIChhcmcuZ2V0Tm9kZVR5cGUoKSAhPSBnZXROb2RlVHlwZSgpKSB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLSAgICAgICAgLy8gaW4gdGhlb3J5IG5vZGVOYW1lIGNhbid0IGJlIG51bGwgYnV0IGJldHRlciBiZSBjYXJlZnVsCi0gICAgICAgIC8vIHdobyBrbm93cyB3aGF0IG90aGVyIGltcGxlbWVudGF0aW9ucyBtYXkgYmUgZG9pbmc/Li4uCi0gICAgICAgIGlmIChnZXROb2RlTmFtZSgpID09IG51bGwpIHsKLSAgICAgICAgICAgIGlmIChhcmcuZ2V0Tm9kZU5hbWUoKSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKCFnZXROb2RlTmFtZSgpLmVxdWFscyhhcmcuZ2V0Tm9kZU5hbWUoKSkpIHsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChnZXRMb2NhbE5hbWUoKSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAoYXJnLmdldExvY2FsTmFtZSgpICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoIWdldExvY2FsTmFtZSgpLmVxdWFscyhhcmcuZ2V0TG9jYWxOYW1lKCkpKSB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoZ2V0TmFtZXNwYWNlVVJJKCkgPT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKGFyZy5nZXROYW1lc3BhY2VVUkkoKSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKCFnZXROYW1lc3BhY2VVUkkoKS5lcXVhbHMoYXJnLmdldE5hbWVzcGFjZVVSSSgpKSkgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKGdldFByZWZpeCgpID09IG51bGwpIHsKLSAgICAgICAgICAgIGlmIChhcmcuZ2V0UHJlZml4KCkgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICghZ2V0UHJlZml4KCkuZXF1YWxzKGFyZy5nZXRQcmVmaXgoKSkpIHsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChnZXROb2RlVmFsdWUoKSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAoYXJnLmdldE5vZGVWYWx1ZSgpICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoIWdldE5vZGVWYWx1ZSgpLmVxdWFscyhhcmcuZ2V0Tm9kZVZhbHVlKCkpKSB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLSAgICAvKgotICAgICAgICBpZiAoZ2V0QmFzZVVSSSgpID09IG51bGwpIHsKLSAgICAgICAgICAgIGlmICgoKE5vZGVJbXBsKSBhcmcpLmdldEJhc2VVUkkoKSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKCFnZXRCYXNlVVJJKCkuZXF1YWxzKCgoTm9kZUltcGwpIGFyZykuZ2V0QmFzZVVSSSgpKSkgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0qLwotCi0gICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotCi0gICAgICAvKioKLSAgICAgKiBET00gTGV2ZWwgMwotICAgICAqIExvb2sgdXAgdGhlIG5hbWVzcGFjZSBVUkkgYXNzb2NpYXRlZCB0byB0aGUgZ2l2ZW4gcHJlZml4LCBzdGFydGluZyBmcm9tIHRoaXMgbm9kZS4KLSAgICAgKiBVc2UgbG9va3VwTmFtZXNwYWNlVVJJKG51bGwpIHRvIGxvb2t1cCB0aGUgZGVmYXVsdCBuYW1lc3BhY2UKLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkKLSAgICAgKiBAcmV0dXJuIHRoIFVSSSBmb3IgdGhlIG5hbWVzcGFjZQotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgICAqLwotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyBTdHJpbmcgbG9va3VwTmFtZXNwYWNlVVJJKFN0cmluZyBzcGVjaWZpZWRQcmVmaXgpIHsKLSAgICAgICAgc2hvcnQgdHlwZSA9IHRoaXMuZ2V0Tm9kZVR5cGUoKTsKLSAgICAgICAgc3dpdGNoICh0eXBlKSB7Ci0gICAgICAgIGNhc2UgTm9kZS5FTEVNRU5UX05PREUgOiB7Ci0KLSAgICAgICAgICAgICAgICBTdHJpbmcgbmFtZXNwYWNlID0gdGhpcy5nZXROYW1lc3BhY2VVUkkoKTsKLSAgICAgICAgICAgICAgICBTdHJpbmcgcHJlZml4ID0gdGhpcy5nZXRQcmVmaXgoKTsKLSAgICAgICAgICAgICAgICBpZiAobmFtZXNwYWNlICE9bnVsbCkgewotICAgICAgICAgICAgICAgICAgICAvLyBSRVZJU0lUOiBpcyBpdCBwb3NzaWJsZSB0aGF0IHByZWZpeCBpcyBlbXB0eSBzdHJpbmc/Ci0gICAgICAgICAgICAgICAgICAgIGlmIChzcGVjaWZpZWRQcmVmaXg9PSBudWxsICYmIHByZWZpeD09c3BlY2lmaWVkUHJlZml4KSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBsb29raW5nIGZvciBkZWZhdWx0IG5hbWVzcGFjZQotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5hbWVzcGFjZTsKLSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChwcmVmaXggIT0gbnVsbCAmJiBwcmVmaXguZXF1YWxzKHNwZWNpZmllZFByZWZpeCkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIG5vbiBkZWZhdWx0IG5hbWVzcGFjZQotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5hbWVzcGFjZTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpZiAodGhpcy5oYXNBdHRyaWJ1dGVzKCkpIHsKLSAgICAgICAgICAgICAgICAgICAgTmFtZWROb2RlTWFwIG1hcCA9IHRoaXMuZ2V0QXR0cmlidXRlcygpOwotICAgICAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gbWFwLmdldExlbmd0aCgpOwotICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpPTA7aTxsZW5ndGg7aSsrKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBOb2RlIGF0dHIgPSBtYXAuaXRlbShpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBhdHRyUHJlZml4ID0gYXR0ci5nZXRQcmVmaXgoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyB2YWx1ZSA9IGF0dHIuZ2V0Tm9kZVZhbHVlKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBuYW1lc3BhY2UgPSBhdHRyLmdldE5hbWVzcGFjZVVSSSgpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5hbWVzcGFjZSAhPW51bGwgJiYgbmFtZXNwYWNlLmVxdWFscygiaHR0cDovL3d3dy53My5vcmcvMjAwMC94bWxucy8iKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGF0IHRoaXMgcG9pbnQgd2UgYXJlIGRlYWxpbmcgd2l0aCBET00gTGV2ZWwgMiBub2RlcyBvbmx5Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNwZWNpZmllZFByZWZpeCA9PSBudWxsICYmCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHIuZ2V0Tm9kZU5hbWUoKS5lcXVhbHMoInhtbG5zIikpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZGVmYXVsdCBuYW1lc3BhY2UKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYXR0clByZWZpeCAhPW51bGwgJiYKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJQcmVmaXguZXF1YWxzKCJ4bWxucyIpICYmCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyLmdldExvY2FsTmFtZSgpLmVxdWFscyhzcGVjaWZpZWRQcmVmaXgpKSB7Ci0gICAgICAgICAgICAgICAgIC8vIG5vbiBkZWZhdWx0IG5hbWVzcGFjZQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIC8qCi0gICAgICAgICAgICAgICAgTm9kZUltcGwgYW5jZXN0b3IgPSAoTm9kZUltcGwpZ2V0RWxlbWVudEFuY2VzdG9yKHRoaXMpOwotICAgICAgICAgICAgICAgIGlmIChhbmNlc3RvciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBhbmNlc3Rvci5sb29rdXBOYW1lc3BhY2VVUkkoc3BlY2lmaWVkUHJlZml4KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgKi8KLQotICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwotCi0KLSAgICAgICAgICAgIH0KLS8qCi0gICAgICAgIGNhc2UgTm9kZS5ET0NVTUVOVF9OT0RFIDogewotICAgICAgICAgICAgICAgIHJldHVybigoTm9kZUltcGwpKChEb2N1bWVudCl0aGlzKS5nZXREb2N1bWVudEVsZW1lbnQoKSkubG9va3VwTmFtZXNwYWNlVVJJKHNwZWNpZmllZFByZWZpeCkgOwotICAgICAgICAgICAgfQotKi8KLSAgICAgICAgY2FzZSBOb2RlLkVOVElUWV9OT0RFIDoKLSAgICAgICAgY2FzZSBOb2RlLk5PVEFUSU9OX05PREU6Ci0gICAgICAgIGNhc2UgTm9kZS5ET0NVTUVOVF9GUkFHTUVOVF9OT0RFOgotICAgICAgICBjYXNlIE5vZGUuRE9DVU1FTlRfVFlQRV9OT0RFOgotICAgICAgICAgICAgLy8gdHlwZSBpcyB1bmtub3duCi0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgY2FzZSBOb2RlLkFUVFJJQlVURV9OT0RFOnsKLSAgICAgICAgICAgICAgICBpZiAodGhpcy5nZXRPd25lckVsZW1lbnQoKS5nZXROb2RlVHlwZSgpID09IE5vZGUuRUxFTUVOVF9OT0RFKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBnZXRPd25lckVsZW1lbnQoKS5sb29rdXBOYW1lc3BhY2VVUkkoc3BlY2lmaWVkUHJlZml4KTsKLQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgZGVmYXVsdDp7Ci0gICAgICAgICAgIC8qCi0gICAgICAgICAgICAgICAgTm9kZUltcGwgYW5jZXN0b3IgPSAoTm9kZUltcGwpZ2V0RWxlbWVudEFuY2VzdG9yKHRoaXMpOwotICAgICAgICAgICAgICAgIGlmIChhbmNlc3RvciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBhbmNlc3Rvci5sb29rdXBOYW1lc3BhY2VVUkkoc3BlY2lmaWVkUHJlZml4KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgKi8KLSAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgICAgIH0KLQotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiAgRE9NIExldmVsIDMKLSAgICAgKiAgVGhpcyBtZXRob2QgY2hlY2tzIGlmIHRoZSBzcGVjaWZpZWQgPGNvZGU+bmFtZXNwYWNlVVJJPC9jb2RlPiBpcyB0aGUKLSAgICAgKiAgZGVmYXVsdCBuYW1lc3BhY2Ugb3Igbm90LgotICAgICAqICBAcGFyYW0gbmFtZXNwYWNlVVJJIFRoZSBuYW1lc3BhY2UgVVJJIHRvIGxvb2sgZm9yLgotICAgICAqICBAcmV0dXJuICA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgc3BlY2lmaWVkIDxjb2RlPm5hbWVzcGFjZVVSSTwvY29kZT4KLSAgICAgKiAgIGlzIHRoZSBkZWZhdWx0IG5hbWVzcGFjZSwgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4KLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICAgKi8KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgYm9vbGVhbiBpc0RlZmF1bHROYW1lc3BhY2UoU3RyaW5nIG5hbWVzcGFjZVVSSSl7Ci0gICAgICAgLyoKLSAgICAgICAgLy8gUkVWSVNJVDogcmVtb3ZlIGNhc3RzIHdoZW4gRE9NIEwzIGJlY29tZXMgUkVDLgotICAgICAgICBzaG9ydCB0eXBlID0gdGhpcy5nZXROb2RlVHlwZSgpOwotICAgICAgICBzd2l0Y2ggKHR5cGUpIHsKLSAgICAgICAgY2FzZSBOb2RlLkVMRU1FTlRfTk9ERTogewotICAgICAgICAgICAgU3RyaW5nIG5hbWVzcGFjZSA9IHRoaXMuZ2V0TmFtZXNwYWNlVVJJKCk7Ci0gICAgICAgICAgICBTdHJpbmcgcHJlZml4ID0gdGhpcy5nZXRQcmVmaXgoKTsKLQotICAgICAgICAgICAgLy8gUkVWSVNJVDogaXMgaXQgcG9zc2libGUgdGhhdCBwcmVmaXggaXMgZW1wdHkgc3RyaW5nPwotICAgICAgICAgICAgaWYgKHByZWZpeCA9PSBudWxsIHx8IHByZWZpeC5sZW5ndGgoKSA9PSAwKSB7Ci0gICAgICAgICAgICAgICAgaWYgKG5hbWVzcGFjZVVSSSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiAobmFtZXNwYWNlID09IG5hbWVzcGFjZVVSSSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHJldHVybiBuYW1lc3BhY2VVUkkuZXF1YWxzKG5hbWVzcGFjZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAodGhpcy5oYXNBdHRyaWJ1dGVzKCkpIHsKLSAgICAgICAgICAgICAgICBFbGVtZW50SW1wbCBlbGVtID0gKEVsZW1lbnRJbXBsKXRoaXM7Ci0gICAgICAgICAgICAgICAgTm9kZUltcGwgYXR0ciA9IChOb2RlSW1wbCllbGVtLmdldEF0dHJpYnV0ZU5vZGVOUygiaHR0cDovL3d3dy53My5vcmcvMjAwMC94bWxucy8iLCAieG1sbnMiKTsKLSAgICAgICAgICAgICAgICBpZiAoYXR0ciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIFN0cmluZyB2YWx1ZSA9IGF0dHIuZ2V0Tm9kZVZhbHVlKCk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChuYW1lc3BhY2VVUkkgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChuYW1lc3BhY2UgPT0gdmFsdWUpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBuYW1lc3BhY2VVUkkuZXF1YWxzKHZhbHVlKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIE5vZGVJbXBsIGFuY2VzdG9yID0gKE5vZGVJbXBsKWdldEVsZW1lbnRBbmNlc3Rvcih0aGlzKTsKLSAgICAgICAgICAgIGlmIChhbmNlc3RvciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGFuY2VzdG9yLmlzRGVmYXVsdE5hbWVzcGFjZShuYW1lc3BhY2VVUkkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0gICAgICAgIGNhc2UgTm9kZS5ET0NVTUVOVF9OT0RFOnsKLSAgICAgICAgICAgICAgICByZXR1cm4oKE5vZGVJbXBsKSgoRG9jdW1lbnQpdGhpcykuZ2V0RG9jdW1lbnRFbGVtZW50KCkpLmlzRGVmYXVsdE5hbWVzcGFjZShuYW1lc3BhY2VVUkkpOwotICAgICAgICAgICAgfQotCi0gICAgICAgIGNhc2UgTm9kZS5FTlRJVFlfTk9ERSA6Ci0gICAgICAgICAgY2FzZSBOb2RlLk5PVEFUSU9OX05PREU6Ci0gICAgICAgIGNhc2UgTm9kZS5ET0NVTUVOVF9GUkFHTUVOVF9OT0RFOgotICAgICAgICBjYXNlIE5vZGUuRE9DVU1FTlRfVFlQRV9OT0RFOgotICAgICAgICAgICAgLy8gdHlwZSBpcyB1bmtub3duCi0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIGNhc2UgTm9kZS5BVFRSSUJVVEVfTk9ERTp7Ci0gICAgICAgICAgICAgICAgaWYgKHRoaXMub3duZXJOb2RlLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5FTEVNRU5UX05PREUpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG93bmVyTm9kZS5pc0RlZmF1bHROYW1lc3BhY2UobmFtZXNwYWNlVVJJKTsKLQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIGRlZmF1bHQ6ewotICAgICAgICAgICAgICAgIE5vZGVJbXBsIGFuY2VzdG9yID0gKE5vZGVJbXBsKWdldEVsZW1lbnRBbmNlc3Rvcih0aGlzKTsKLSAgICAgICAgICAgICAgICBpZiAoYW5jZXN0b3IgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gYW5jZXN0b3IuaXNEZWZhdWx0TmFtZXNwYWNlKG5hbWVzcGFjZVVSSSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICB9Ci0qLwotICAgICAgICByZXR1cm4gZmFsc2U7Ci0KLQotICAgIH0KLQotICAgICAgLyoqCi0gICAgICoKLSAgICAgKiBET00gTGV2ZWwgMwotICAgICAqIExvb2sgdXAgdGhlIHByZWZpeCBhc3NvY2lhdGVkIHRvIHRoZSBnaXZlbiBuYW1lc3BhY2UgVVJJLCBzdGFydGluZyBmcm9tIHRoaXMgbm9kZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkKLSAgICAgKiBAcmV0dXJuIHRoZSBwcmVmaXggZm9yIHRoZSBuYW1lc3BhY2UKLSAgICAgKi8KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgU3RyaW5nIGxvb2t1cFByZWZpeChTdHJpbmcgbmFtZXNwYWNlVVJJKXsKLQotICAgICAgICAvLyBSRVZJU0lUOiBXaGVuIE5hbWVzcGFjZXMgMS4xIGNvbWVzIG91dCB0aGlzIG1heSBub3QgYmUgdHJ1ZQotICAgICAgICAvLyBQcmVmaXggY2FuJ3QgYmUgYm91bmQgdG8gbnVsbCBuYW1lc3BhY2UKLSAgICAgICAgaWYgKG5hbWVzcGFjZVVSSSA9PSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotCi0gICAgICAgIHNob3J0IHR5cGUgPSB0aGlzLmdldE5vZGVUeXBlKCk7Ci0KLSAgICAgICAgc3dpdGNoICh0eXBlKSB7Ci0vKgotICAgICAgICBjYXNlIE5vZGUuRUxFTUVOVF9OT0RFOiB7Ci0KLSAgICAgICAgICAgICAgICBTdHJpbmcgbmFtZXNwYWNlID0gdGhpcy5nZXROYW1lc3BhY2VVUkkoKTsgLy8gdG8gZmxpcCBvdXQgY2hpbGRyZW4KLSAgICAgICAgICAgICAgICByZXR1cm4gbG9va3VwTmFtZXNwYWNlUHJlZml4KG5hbWVzcGFjZVVSSSwgKEVsZW1lbnRJbXBsKXRoaXMpOwotICAgICAgICAgICAgfQotCi0gICAgICAgIGNhc2UgTm9kZS5ET0NVTUVOVF9OT0RFOnsKLSAgICAgICAgICAgICAgICByZXR1cm4oKE5vZGVJbXBsKSgoRG9jdW1lbnQpdGhpcykuZ2V0RG9jdW1lbnRFbGVtZW50KCkpLmxvb2t1cFByZWZpeChuYW1lc3BhY2VVUkkpOwotICAgICAgICAgICAgfQotKi8KLSAgICAgICAgY2FzZSBOb2RlLkVOVElUWV9OT0RFIDoKLSAgICAgICAgY2FzZSBOb2RlLk5PVEFUSU9OX05PREU6Ci0gICAgICAgIGNhc2UgTm9kZS5ET0NVTUVOVF9GUkFHTUVOVF9OT0RFOgotICAgICAgICBjYXNlIE5vZGUuRE9DVU1FTlRfVFlQRV9OT0RFOgotICAgICAgICAgICAgLy8gdHlwZSBpcyB1bmtub3duCi0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgY2FzZSBOb2RlLkFUVFJJQlVURV9OT0RFOnsKLSAgICAgICAgICAgICAgICBpZiAodGhpcy5nZXRPd25lckVsZW1lbnQoKS5nZXROb2RlVHlwZSgpID09IE5vZGUuRUxFTUVOVF9OT0RFKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBnZXRPd25lckVsZW1lbnQoKS5sb29rdXBQcmVmaXgobmFtZXNwYWNlVVJJKTsKLQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgZGVmYXVsdDp7Ci0vKgotICAgICAgICAgICAgICAgIE5vZGVJbXBsIGFuY2VzdG9yID0gKE5vZGVJbXBsKWdldEVsZW1lbnRBbmNlc3Rvcih0aGlzKTsKLSAgICAgICAgICAgICAgICBpZiAoYW5jZXN0b3IgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gYW5jZXN0b3IubG9va3VwUHJlZml4KG5hbWVzcGFjZVVSSSk7Ci0gICAgICAgICAgICAgICAgfQotKi8KLSAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgIH0KLSAgICB9Ci0KLSAgICAgLyoqCi0gICAgICogUmV0dXJucyB3aGV0aGVyIHRoaXMgbm9kZSBpcyB0aGUgc2FtZSBub2RlIGFzIHRoZSBnaXZlbiBvbmUuCi0gICAgICogPGJyPlRoaXMgbWV0aG9kIHByb3ZpZGVzIGEgd2F5IHRvIGRldGVybWluZSB3aGV0aGVyIHR3bwotICAgICAqIDxjb2RlPk5vZGU8L2NvZGU+IHJlZmVyZW5jZXMgcmV0dXJuZWQgYnkgdGhlIGltcGxlbWVudGF0aW9uIHJlZmVyZW5jZQotICAgICAqIHRoZSBzYW1lIG9iamVjdC4gV2hlbiB0d28gPGNvZGU+Tm9kZTwvY29kZT4gcmVmZXJlbmNlcyBhcmUgcmVmZXJlbmNlcwotICAgICAqIHRvIHRoZSBzYW1lIG9iamVjdCwgZXZlbiBpZiB0aHJvdWdoIGEgcHJveHksIHRoZSByZWZlcmVuY2VzIG1heSBiZQotICAgICAqIHVzZWQgY29tcGxldGVseSBpbnRlcmNoYW5nYWJseSwgc3VjaCB0aGF0IGFsbCBhdHRyaWJ1dGVzIGhhdmUgdGhlCi0gICAgICogc2FtZSB2YWx1ZXMgYW5kIGNhbGxpbmcgdGhlIHNhbWUgRE9NIG1ldGhvZCBvbiBlaXRoZXIgcmVmZXJlbmNlCi0gICAgICogYWx3YXlzIGhhcyBleGFjdGx5IHRoZSBzYW1lIGVmZmVjdC4KLSAgICAgKiBAcGFyYW0gb3RoZXIgVGhlIG5vZGUgdG8gdGVzdCBhZ2FpbnN0LgotICAgICAqIEByZXR1cm4gUmV0dXJucyA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgbm9kZXMgYXJlIHRoZSBzYW1lLAotICAgICAqICAgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4KLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICAgKi8KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgYm9vbGVhbiBpc1NhbWVOb2RlKE5vZGUgb3RoZXIpIHsKLSAgICAgICAgLy8gd2UgZG8gbm90IHVzZSBhbnkgd3JhcHBlciBzbyB0aGUgYW5zd2VyIGlzIG9idmlvdXMKLSAgICAgICAgcmV0dXJuIHRoaXMgPT0gb3RoZXI7Ci0gICAgfQotCi0gICAgICAvKioKLSAgICAgKiBUaGlzIGF0dHJpYnV0ZSByZXR1cm5zIHRoZSB0ZXh0IGNvbnRlbnQgb2YgdGhpcyBub2RlIGFuZCBpdHMKLSAgICAgKiBkZXNjZW5kYW50cy4gV2hlbiBpdCBpcyBkZWZpbmVkIHRvIGJlIG51bGwsIHNldHRpbmcgaXQgaGFzIG5vIGVmZmVjdC4KLSAgICAgKiBXaGVuIHNldCwgYW55IHBvc3NpYmxlIGNoaWxkcmVuIHRoaXMgbm9kZSBtYXkgaGF2ZSBhcmUgcmVtb3ZlZCBhbmQKLSAgICAgKiByZXBsYWNlZCBieSBhIHNpbmdsZSA8Y29kZT5UZXh0PC9jb2RlPiBub2RlIGNvbnRhaW5pbmcgdGhlIHN0cmluZwotICAgICAqIHRoaXMgYXR0cmlidXRlIGlzIHNldCB0by4gT24gZ2V0dGluZywgbm8gc2VyaWFsaXphdGlvbiBpcyBwZXJmb3JtZWQsCi0gICAgICogdGhlIHJldHVybmVkIHN0cmluZyBkb2VzIG5vdCBjb250YWluIGFueSBtYXJrdXAuIE5vIHdoaXRlc3BhY2UKLSAgICAgKiBub3JtYWxpemF0aW9uIGlzIHBlcmZvcm1lZCwgdGhlIHJldHVybmVkIHN0cmluZyBkb2VzIG5vdCBjb250YWluIHRoZQotICAgICAqIGVsZW1lbnQgY29udGVudCB3aGl0ZXNwYWNlcyAuIFNpbWlsYXJseSwgb24gc2V0dGluZywgbm8gcGFyc2luZyBpcwotICAgICAqIHBlcmZvcm1lZCBlaXRoZXIsIHRoZSBpbnB1dCBzdHJpbmcgaXMgdGFrZW4gYXMgcHVyZSB0ZXh0dWFsIGNvbnRlbnQuCi0gICAgICogPGJyPlRoZSBzdHJpbmcgcmV0dXJuZWQgaXMgbWFkZSBvZiB0aGUgdGV4dCBjb250ZW50IG9mIHRoaXMgbm9kZQotICAgICAqIGRlcGVuZGluZyBvbiBpdHMgdHlwZSwgYXMgZGVmaW5lZCBiZWxvdzoKLSAgICAgKiA8dGFibGUgYm9yZGVyPScxJz4KLSAgICAgKiA8dHI+Ci0gICAgICogPHRoPk5vZGUgdHlwZTwvdGg+Ci0gICAgICogPHRoPkNvbnRlbnQ8L3RoPgotICAgICAqIDwvdHI+Ci0gICAgICogPHRyPgotICAgICAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+Ci0gICAgICogRUxFTUVOVF9OT0RFLCBFTlRJVFlfTk9ERSwgRU5USVRZX1JFRkVSRU5DRV9OT0RFLAotICAgICAqIERPQ1VNRU5UX0ZSQUdNRU5UX05PREU8L3RkPgotICAgICAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+Y29uY2F0ZW5hdGlvbiBvZiB0aGUgPGNvZGU+dGV4dENvbnRlbnQ8L2NvZGU+Ci0gICAgICogYXR0cmlidXRlIHZhbHVlIG9mIGV2ZXJ5IGNoaWxkIG5vZGUsIGV4Y2x1ZGluZyBDT01NRU5UX05PREUgYW5kCi0gICAgICogUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFIG5vZGVzPC90ZD4KLSAgICAgKiA8L3RyPgotICAgICAqIDx0cj4KLSAgICAgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPkFUVFJJQlVURV9OT0RFLCBURVhUX05PREUsCi0gICAgICogQ0RBVEFfU0VDVElPTl9OT0RFLCBDT01NRU5UX05PREUsIFBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERTwvdGQ+Ci0gICAgICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz4KLSAgICAgKiA8Y29kZT5ub2RlVmFsdWU8L2NvZGU+PC90ZD4KLSAgICAgKiA8L3RyPgotICAgICAqIDx0cj4KLSAgICAgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPkRPQ1VNRU5UX05PREUsIERPQ1VNRU5UX1RZUEVfTk9ERSwgTk9UQVRJT05fTk9ERTwvdGQ+Ci0gICAgICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz4KLSAgICAgKiBudWxsPC90ZD4KLSAgICAgKiA8L3RyPgotICAgICAqIDwvdGFibGU+Ci0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIHdoZW4gdGhlIG5vZGUgaXMgcmVhZG9ubHkuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIERPTVNUUklOR19TSVpFX0VSUjogUmFpc2VkIHdoZW4gaXQgd291bGQgcmV0dXJuIG1vcmUgY2hhcmFjdGVycyB0aGFuCi0gICAgICogICBmaXQgaW4gYSA8Y29kZT5ET01TdHJpbmc8L2NvZGU+IHZhcmlhYmxlIG9uIHRoZSBpbXBsZW1lbnRhdGlvbgotICAgICAqICAgcGxhdGZvcm0uCi0gICAgICogQHNpbmNlIERPTSBMZXZlbCAzCi0gICAgICovCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIHZvaWQgc2V0VGV4dENvbnRlbnQoU3RyaW5nIHRleHRDb250ZW50KQotICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKLSAgICAgICAgc2V0Tm9kZVZhbHVlKHRleHRDb250ZW50KTsKLSAgICB9Ci0gICAgLyoqCi0gICAgICogVGhpcyBhdHRyaWJ1dGUgcmV0dXJucyB0aGUgdGV4dCBjb250ZW50IG9mIHRoaXMgbm9kZSBhbmQgaXRzCi0gICAgICogZGVzY2VuZGFudHMuIFdoZW4gaXQgaXMgZGVmaW5lZCB0byBiZSBudWxsLCBzZXR0aW5nIGl0IGhhcyBubyBlZmZlY3QuCi0gICAgICogV2hlbiBzZXQsIGFueSBwb3NzaWJsZSBjaGlsZHJlbiB0aGlzIG5vZGUgbWF5IGhhdmUgYXJlIHJlbW92ZWQgYW5kCi0gICAgICogcmVwbGFjZWQgYnkgYSBzaW5nbGUgPGNvZGU+VGV4dDwvY29kZT4gbm9kZSBjb250YWluaW5nIHRoZSBzdHJpbmcKLSAgICAgKiB0aGlzIGF0dHJpYnV0ZSBpcyBzZXQgdG8uIE9uIGdldHRpbmcsIG5vIHNlcmlhbGl6YXRpb24gaXMgcGVyZm9ybWVkLAotICAgICAqIHRoZSByZXR1cm5lZCBzdHJpbmcgZG9lcyBub3QgY29udGFpbiBhbnkgbWFya3VwLiBObyB3aGl0ZXNwYWNlCi0gICAgICogbm9ybWFsaXphdGlvbiBpcyBwZXJmb3JtZWQsIHRoZSByZXR1cm5lZCBzdHJpbmcgZG9lcyBub3QgY29udGFpbiB0aGUKLSAgICAgKiBlbGVtZW50IGNvbnRlbnQgd2hpdGVzcGFjZXMgLiBTaW1pbGFybHksIG9uIHNldHRpbmcsIG5vIHBhcnNpbmcgaXMKLSAgICAgKiBwZXJmb3JtZWQgZWl0aGVyLCB0aGUgaW5wdXQgc3RyaW5nIGlzIHRha2VuIGFzIHB1cmUgdGV4dHVhbCBjb250ZW50LgotICAgICAqIDxicj5UaGUgc3RyaW5nIHJldHVybmVkIGlzIG1hZGUgb2YgdGhlIHRleHQgY29udGVudCBvZiB0aGlzIG5vZGUKLSAgICAgKiBkZXBlbmRpbmcgb24gaXRzIHR5cGUsIGFzIGRlZmluZWQgYmVsb3c6Ci0gICAgICogPHRhYmxlIGJvcmRlcj0nMSc+Ci0gICAgICogPHRyPgotICAgICAqIDx0aD5Ob2RlIHR5cGU8L3RoPgotICAgICAqIDx0aD5Db250ZW50PC90aD4KLSAgICAgKiA8L3RyPgotICAgICAqIDx0cj4KLSAgICAgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPgotICAgICAqIEVMRU1FTlRfTk9ERSwgRU5USVRZX05PREUsIEVOVElUWV9SRUZFUkVOQ0VfTk9ERSwKLSAgICAgKiBET0NVTUVOVF9GUkFHTUVOVF9OT0RFPC90ZD4KLSAgICAgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPmNvbmNhdGVuYXRpb24gb2YgdGhlIDxjb2RlPnRleHRDb250ZW50PC9jb2RlPgotICAgICAqIGF0dHJpYnV0ZSB2YWx1ZSBvZiBldmVyeSBjaGlsZCBub2RlLCBleGNsdWRpbmcgQ09NTUVOVF9OT0RFIGFuZAotICAgICAqIFBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERSBub2RlczwvdGQ+Ci0gICAgICogPC90cj4KLSAgICAgKiA8dHI+Ci0gICAgICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz5BVFRSSUJVVEVfTk9ERSwgVEVYVF9OT0RFLAotICAgICAqIENEQVRBX1NFQ1RJT05fTk9ERSwgQ09NTUVOVF9OT0RFLCBQUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREU8L3RkPgotICAgICAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+Ci0gICAgICogPGNvZGU+bm9kZVZhbHVlPC9jb2RlPjwvdGQ+Ci0gICAgICogPC90cj4KLSAgICAgKiA8dHI+Ci0gICAgICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz5ET0NVTUVOVF9OT0RFLCBET0NVTUVOVF9UWVBFX05PREUsIE5PVEFUSU9OX05PREU8L3RkPgotICAgICAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+Ci0gICAgICogbnVsbDwvdGQ+Ci0gICAgICogPC90cj4KLSAgICAgKiA8L3RhYmxlPgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCB3aGVuIHRoZSBub2RlIGlzIHJlYWRvbmx5LgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBET01TVFJJTkdfU0laRV9FUlI6IFJhaXNlZCB3aGVuIGl0IHdvdWxkIHJldHVybiBtb3JlIGNoYXJhY3RlcnMgdGhhbgotICAgICAqICAgZml0IGluIGEgPGNvZGU+RE9NU3RyaW5nPC9jb2RlPiB2YXJpYWJsZSBvbiB0aGUgaW1wbGVtZW50YXRpb24KLSAgICAgKiAgIHBsYXRmb3JtLgotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgICAqLwotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VGV4dENvbnRlbnQoKSB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKLSAgICAgICAgcmV0dXJuIGR0bS5nZXRTdHJpbmdWYWx1ZShub2RlKS50b1N0cmluZygpOwotICAgIH0KLQotICAgICAvKioKLSAgICAgKiBDb21wYXJlcyBhIG5vZGUgd2l0aCB0aGlzIG5vZGUgd2l0aCByZWdhcmQgdG8gdGhlaXIgcG9zaXRpb24gaW4gdGhlCi0gICAgICogZG9jdW1lbnQuCi0gICAgICogQHBhcmFtIG90aGVyIFRoZSBub2RlIHRvIGNvbXBhcmUgYWdhaW5zdCB0aGlzIG5vZGUuCi0gICAgICogQHJldHVybiBSZXR1cm5zIGhvdyB0aGUgZ2l2ZW4gbm9kZSBpcyBwb3NpdGlvbmVkIHJlbGF0aXZlbHkgdG8gdGhpcwotICAgICAqICAgbm9kZS4KLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICAgKi8KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgc2hvcnQgY29tcGFyZURvY3VtZW50UG9zaXRpb24oTm9kZSBvdGhlcikgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0gICAgICAgIHJldHVybiAwOwotICAgIH0KLQotICAgICAvKioKLSAgICAgKiBUaGUgYWJzb2x1dGUgYmFzZSBVUkkgb2YgdGhpcyBub2RlIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIHVuZGVmaW5lZC4KLSAgICAgKiBUaGlzIHZhbHVlIGlzIGNvbXB1dGVkIGFjY29yZGluZyB0byAuIEhvd2V2ZXIsIHdoZW4gdGhlCi0gICAgICogPGNvZGU+RG9jdW1lbnQ8L2NvZGU+IHN1cHBvcnRzIHRoZSBmZWF0dXJlICJIVE1MIiAsIHRoZSBiYXNlIFVSSSBpcwotICAgICAqIGNvbXB1dGVkIHVzaW5nIGZpcnN0IHRoZSB2YWx1ZSBvZiB0aGUgaHJlZiBhdHRyaWJ1dGUgb2YgdGhlIEhUTUwgQkFTRQotICAgICAqIGVsZW1lbnQgaWYgYW55LCBhbmQgdGhlIHZhbHVlIG9mIHRoZSA8Y29kZT5kb2N1bWVudFVSSTwvY29kZT4KLSAgICAgKiBhdHRyaWJ1dGUgZnJvbSB0aGUgPGNvZGU+RG9jdW1lbnQ8L2NvZGU+IGludGVyZmFjZSBvdGhlcndpc2UuCi0gICAgICogPGJyPiBXaGVuIHRoZSBub2RlIGlzIGFuIDxjb2RlPkVsZW1lbnQ8L2NvZGU+LCBhIDxjb2RlPkRvY3VtZW50PC9jb2RlPgotICAgICAqIG9yIGEgYSA8Y29kZT5Qcm9jZXNzaW5nSW5zdHJ1Y3Rpb248L2NvZGU+LCB0aGlzIGF0dHJpYnV0ZSByZXByZXNlbnRzCi0gICAgICogdGhlIHByb3BlcnRpZXMgW2Jhc2UgVVJJXSBkZWZpbmVkIGluIC4gV2hlbiB0aGUgbm9kZSBpcyBhCi0gICAgICogPGNvZGU+Tm90YXRpb248L2NvZGU+LCBhbiA8Y29kZT5FbnRpdHk8L2NvZGU+LCBvciBhbgotICAgICAqIDxjb2RlPkVudGl0eVJlZmVyZW5jZTwvY29kZT4sIHRoaXMgYXR0cmlidXRlIHJlcHJlc2VudHMgdGhlCi0gICAgICogcHJvcGVydGllcyBbZGVjbGFyYXRpb24gYmFzZSBVUkldIGluIHRoZSAuIEhvdyB3aWxsIHRoaXMgYmUgYWZmZWN0ZWQKLSAgICAgKiBieSByZXNvbHV0aW9uIG9mIHJlbGF0aXZlIG5hbWVzcGFjZSBVUklzIGlzc3VlP0l0J3Mgbm90LlNob3VsZCB0aGlzCi0gICAgICogb25seSBiZSBvbiBEb2N1bWVudCwgRWxlbWVudCwgUHJvY2Vzc2luZ0luc3RydWN0aW9uLCBFbnRpdHksIGFuZAotICAgICAqIE5vdGF0aW9uIG5vZGVzLCBhY2NvcmRpbmcgdG8gdGhlIGluZm9zZXQ/IElmIG5vdCwgd2hhdCBpcyBpdCBlcXVhbCB0bwotICAgICAqIG9uIG90aGVyIG5vZGVzPyBOdWxsPyBBbiBlbXB0eSBzdHJpbmc/IEkgdGhpbmsgaXQgc2hvdWxkIGJlIHRoZQotICAgICAqIHBhcmVudCdzLk5vLlNob3VsZCB0aGlzIGJlIHJlYWQtb25seSBhbmQgY29tcHV0ZWQgb3IgYW5kIGFjdHVhbAotICAgICAqIHJlYWQtd3JpdGUgYXR0cmlidXRlP1JlYWQtb25seSBhbmQgY29tcHV0ZWQgKEYyRiAxOSBKdW4gMjAwMCBhbmQKLSAgICAgKiB0ZWxlY29uZmVyZW5jZSAzMCBNYXkgMjAwMSkuSWYgdGhlIGJhc2UgSFRNTCBlbGVtZW50IGlzIG5vdCB5ZXQKLSAgICAgKiBhdHRhY2hlZCB0byBhIGRvY3VtZW50LCBkb2VzIHRoZSBpbnNlcnQgY2hhbmdlIHRoZSBEb2N1bWVudC5iYXNlVVJJPwotICAgICAqIFllcy4gKEYyRiAyNiBTZXAgMjAwMSkKLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICAgKi8KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgU3RyaW5nIGdldEJhc2VVUkkoKSB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIERPTSBMZXZlbCAzCi0gICAgICogUmVuYW1pbmcgbm9kZQotICAgICAqLwotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyBOb2RlIHJlbmFtZU5vZGUoTm9kZSBuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBuYW1lKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbnsKLSAgICAgICAgcmV0dXJuIG47Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiAgRE9NIExldmVsIDMKLSAgICAgKiAgTm9ybWFsaXplIGRvY3VtZW50LgotICAgICAqLwotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyB2b2lkIG5vcm1hbGl6ZURvY3VtZW50KCl7Ci0KLSAgICB9Ci0gICAgLyoqCi0gICAgICogVGhlIGNvbmZpZ3VyYXRpb24gdXNlZCB3aGVuIDxjb2RlPkRvY3VtZW50Lm5vcm1hbGl6ZURvY3VtZW50PC9jb2RlPiBpcwotICAgICAqIGludm9rZWQuCi0gICAgICogQHNpbmNlIERPTSBMZXZlbCAzCi0gICAgICovCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIERPTUNvbmZpZ3VyYXRpb24gZ2V0RG9tQ29uZmlnKCl7Ci0gICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0KLSAgICAvKiogRE9NIExldmVsIDMgZmVhdHVyZTogZG9jdW1lbnRVUkkgKi8KLSAgICBwcm90ZWN0ZWQgU3RyaW5nIGZEb2N1bWVudFVSSTsKLQotICAgIC8qKgotICAgICAqIERPTSBMZXZlbCAzCi0gICAgICovCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIHZvaWQgc2V0RG9jdW1lbnRVUkkoU3RyaW5nIGRvY3VtZW50VVJJKXsKLSAgICAgICAgZkRvY3VtZW50VVJJPSBkb2N1bWVudFVSSTsKLSAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICogRE9NIExldmVsIDMKLSAgICAgKiBUaGUgbG9jYXRpb24gb2YgdGhlIGRvY3VtZW50IG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIHVuZGVmaW5lZC4KLSAgICAgKiA8YnI+QmV3YXJlIHRoYXQgd2hlbiB0aGUgPGNvZGU+RG9jdW1lbnQ8L2NvZGU+IHN1cHBvcnRzIHRoZSBmZWF0dXJlCi0gICAgICogIkhUTUwiICwgdGhlIGhyZWYgYXR0cmlidXRlIG9mIHRoZSBIVE1MIEJBU0UgZWxlbWVudCB0YWtlcyBwcmVjZWRlbmNlCi0gICAgICogb3ZlciB0aGlzIGF0dHJpYnV0ZS4KLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICAgKi8KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgU3RyaW5nIGdldERvY3VtZW50VVJJKCl7Ci0gICAgICAgIHJldHVybiBmRG9jdW1lbnRVUkk7Ci0gICAgfQotCi0gICAgICAgIC8qKkRPTSBMZXZlbCAzIGZlYXR1cmU6IERvY3VtZW50IGFjdHVhbEVuY29kaW5nICovCi0gICAgcHJvdGVjdGVkIFN0cmluZyBhY3R1YWxFbmNvZGluZzsKLQotICAgICAvKioKLSAgICAgKiBET00gTGV2ZWwgMwotICAgICAqIEFuIGF0dHJpYnV0ZSBzcGVjaWZ5aW5nIHRoZSBhY3R1YWwgZW5jb2Rpbmcgb2YgdGhpcyBkb2N1bWVudC4gVGhpcyBpcwotICAgICAqIDxjb2RlPm51bGw8L2NvZGU+IG90aGVyd2lzZS4KLSAgICAgKiA8YnI+IFRoaXMgYXR0cmlidXRlIHJlcHJlc2VudHMgdGhlIHByb3BlcnR5IFtjaGFyYWN0ZXIgZW5jb2Rpbmcgc2NoZW1lXQotICAgICAqIGRlZmluZWQgaW4gLgotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0QWN0dWFsRW5jb2RpbmcoKSB7Ci0gICAgICAgIHJldHVybiBhY3R1YWxFbmNvZGluZzsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBET00gTGV2ZWwgMwotICAgICAqIEFuIGF0dHJpYnV0ZSBzcGVjaWZ5aW5nIHRoZSBhY3R1YWwgZW5jb2Rpbmcgb2YgdGhpcyBkb2N1bWVudC4gVGhpcyBpcwotICAgICAqIDxjb2RlPm51bGw8L2NvZGU+IG90aGVyd2lzZS4KLSAgICAgKiA8YnI+IFRoaXMgYXR0cmlidXRlIHJlcHJlc2VudHMgdGhlIHByb3BlcnR5IFtjaGFyYWN0ZXIgZW5jb2Rpbmcgc2NoZW1lXQotICAgICAqIGRlZmluZWQgaW4gLgotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEFjdHVhbEVuY29kaW5nKFN0cmluZyB2YWx1ZSkgewotICAgICAgICBhY3R1YWxFbmNvZGluZyA9IHZhbHVlOwotICAgIH0KLQotICAgLyoqCi0gICAgKiBET00gTGV2ZWwgMwotICAgICovCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIFRleHQgcmVwbGFjZVdob2xlVGV4dChTdHJpbmcgY29udGVudCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb257Ci0vKgotCi0gICAgICAgIGlmIChuZWVkc1N5bmNEYXRhKCkpIHsKLSAgICAgICAgICAgIHN5bmNocm9uaXplRGF0YSgpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gbWFrZSBzdXJlIHdlIGNhbiBtYWtlIHRoZSByZXBsYWNlbWVudAotICAgICAgICBpZiAoIWNhbk1vZGlmeShuZXh0U2libGluZykpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiwKLSAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLCAiTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIiwgbnVsbCkpOwotICAgICAgICB9Ci0KLSAgICAgICAgTm9kZSBwYXJlbnQgPSB0aGlzLmdldFBhcmVudE5vZGUoKTsKLSAgICAgICAgaWYgKGNvbnRlbnQgPT0gbnVsbCB8fCBjb250ZW50Lmxlbmd0aCgpID09IDApIHsKLSAgICAgICAgICAgIC8vIHJlbW92ZSBjdXJyZW50IG5vZGUKLSAgICAgICAgICAgIGlmIChwYXJlbnQgIT1udWxsKSB7IC8vIGNoZWNrIGlmIG5vZGUgaW4gdGhlIHRyZWUKLSAgICAgICAgICAgICAgICBwYXJlbnQucmVtb3ZlQ2hpbGQodGhpcyk7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgVGV4dCBjdXJyZW50Tm9kZSA9IG51bGw7Ci0gICAgICAgIGlmIChpc1JlYWRPbmx5KCkpewotICAgICAgICAgICAgVGV4dCBuZXdOb2RlID0gdGhpcy5vd25lckRvY3VtZW50KCkuY3JlYXRlVGV4dE5vZGUoY29udGVudCk7Ci0gICAgICAgICAgICBpZiAocGFyZW50ICE9bnVsbCkgeyAvLyBjaGVjayBpZiBub2RlIGluIHRoZSB0cmVlCi0gICAgICAgICAgICAgICAgcGFyZW50Lmluc2VydEJlZm9yZShuZXdOb2RlLCB0aGlzKTsKLSAgICAgICAgICAgICAgICBwYXJlbnQucmVtb3ZlQ2hpbGQodGhpcyk7Ci0gICAgICAgICAgICAgICAgY3VycmVudE5vZGUgPSBuZXdOb2RlOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gbmV3Tm9kZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSAgZWxzZSB7Ci0gICAgICAgICAgICB0aGlzLnNldERhdGEoY29udGVudCk7Ci0gICAgICAgICAgICBjdXJyZW50Tm9kZSA9IHRoaXM7Ci0gICAgICAgIH0KLSAgICAgICAgTm9kZSBzaWJsaW5nID0gIGN1cnJlbnROb2RlLmdldE5leHRTaWJsaW5nKCk7Ci0gICAgICAgIHdoaWxlICggc2libGluZyAhPW51bGwpIHsKLSAgICAgICAgICAgIHBhcmVudC5yZW1vdmVDaGlsZChzaWJsaW5nKTsKLSAgICAgICAgICAgIHNpYmxpbmcgPSBjdXJyZW50Tm9kZS5nZXROZXh0U2libGluZygpOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIGN1cnJlbnROb2RlOwotKi8KLSAgICAgICAgcmV0dXJuIG51bGw7IC8vUGVuZGluZwotICAgIH0KLQotICAgICAvKioKLSAgICAgKiBET00gTGV2ZWwgMwotICAgICAqIFJldHVybnMgYWxsIHRleHQgb2YgPGNvZGU+VGV4dDwvY29kZT4gbm9kZXMgbG9naWNhbGx5LWFkamFjZW50IHRleHQKLSAgICAgKiBub2RlcyB0byB0aGlzIG5vZGUsIGNvbmNhdGVuYXRlZCBpbiBkb2N1bWVudCBvcmRlci4KLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICAgKi8KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgU3RyaW5nIGdldFdob2xlVGV4dCgpewotCi0vKgotICAgICAgICBpZiAobmVlZHNTeW5jRGF0YSgpKSB7Ci0gICAgICAgICAgICBzeW5jaHJvbml6ZURhdGEoKTsKLSAgICAgICAgfQotICAgICAgICBpZiAobmV4dFNpYmxpbmcgPT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIGRhdGE7Ci0gICAgICAgIH0KLSAgICAgICAgU3RyaW5nQnVmZmVyIGJ1ZmZlciA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLSAgICAgICAgaWYgKGRhdGEgIT0gbnVsbCAmJiBkYXRhLmxlbmd0aCgpICE9IDApIHsKLSAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoZGF0YSk7Ci0gICAgICAgIH0KLSAgICAgICAgZ2V0V2hvbGVUZXh0KG5leHRTaWJsaW5nLCBidWZmZXIpOwotICAgICAgICByZXR1cm4gYnVmZmVyLnRvU3RyaW5nKCk7Ci0qLwotICAgICAgICByZXR1cm4gbnVsbDsgLy8gUEVORElORwotCi0gICAgfQotCi0gICAgICAvKioKLSAgICAqIERPTSBMZXZlbCAzCi0gICAgICogUmV0dXJucyB3aGV0aGVyIHRoaXMgdGV4dCBub2RlIGNvbnRhaW5zIHdoaXRlc3BhY2UgaW4gZWxlbWVudCBjb250ZW50LAotICAgICAqIG9mdGVuIGFidXNpdmVseSBjYWxsZWQgImlnbm9yYWJsZSB3aGl0ZXNwYWNlIi4KLSAgICAgKi8KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgYm9vbGVhbiBpc0VsZW1lbnRDb250ZW50V2hpdGVzcGFjZSgpewotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgIC8qKgotICAgICAqIE5PTi1ET006IHNldCB0aGUgdHlwZSBvZiB0aGlzIGF0dHJpYnV0ZSB0byBiZSBJRCB0eXBlLgotICAgICAqCi0gICAgICogQHBhcmFtIGlkCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0SWRBdHRyaWJ1dGUoYm9vbGVhbiBpZCl7Ci0gICAgICAgIC8vUEVORElORwotICAgIH0KLQotICAgICAvKioKLSAgICAgKiBET00gTGV2ZWwgMzogcmVnaXN0ZXIgdGhlIGdpdmVuIGF0dHJpYnV0ZSBub2RlIGFzIGFuIElEIGF0dHJpYnV0ZQotICAgICAqLwotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyB2b2lkIHNldElkQXR0cmlidXRlKFN0cmluZyBuYW1lLCBib29sZWFuIG1ha2VJZCkgewotICAgICAgICAvL1BFTkRJTkcKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIERPTSBMZXZlbCAzOiByZWdpc3RlciB0aGUgZ2l2ZW4gYXR0cmlidXRlIG5vZGUgYXMgYW4gSUQgYXR0cmlidXRlCi0gICAgICovCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIHZvaWQgc2V0SWRBdHRyaWJ1dGVOb2RlKEF0dHIgYXQsIGJvb2xlYW4gbWFrZUlkKSB7Ci0gICAgICAgIC8vUEVORElORwotICAgIH0KLQotICAgIC8qKgotICAgICAqIERPTSBMZXZlbCAzOiByZWdpc3RlciB0aGUgZ2l2ZW4gYXR0cmlidXRlIG5vZGUgYXMgYW4gSUQgYXR0cmlidXRlCi0gICAgICovCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIHZvaWQgc2V0SWRBdHRyaWJ1dGVOUyhTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgbG9jYWxOYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBtYWtlSWQpIHsKLSAgICAgICAgLy9QRU5ESU5HCi0gICAgfQotICAgICAgICAgLyoqCi0gICAgICAgICAqIE1ldGhvZCBnZXRTY2hlbWFUeXBlSW5mby4KLSAgICAgICAgICogQHJldHVybiBUeXBlSW5mbwotICAgICAgICAgKi8KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgVHlwZUluZm8gZ2V0U2NoZW1hVHlwZUluZm8oKXsKLSAgICAgIHJldHVybiBudWxsOyAvL1BFTkRJTkcKLSAgICB9Ci0KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgYm9vbGVhbiBpc0lkKCkgewotICAgICAgICByZXR1cm4gZmFsc2U7IC8vUEVORElORwotICAgIH0KLQotCi0gICAgcHJpdmF0ZSBTdHJpbmcgeG1sRW5jb2Rpbmc7Ci0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIFN0cmluZyBnZXRYbWxFbmNvZGluZyggKSB7Ci0gICAgICAgIHJldHVybiB4bWxFbmNvZGluZzsKLSAgICB9Ci0gICAgcHVibGljIHZvaWQgc2V0WG1sRW5jb2RpbmcoIFN0cmluZyB4bWxFbmNvZGluZyApIHsKLSAgICAgICAgdGhpcy54bWxFbmNvZGluZyA9IHhtbEVuY29kaW5nOwotICAgIH0KLQotICAgIHByaXZhdGUgYm9vbGVhbiB4bWxTdGFuZGFsb25lOwotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyBib29sZWFuIGdldFhtbFN0YW5kYWxvbmUoKSB7Ci0gICAgICAgIHJldHVybiB4bWxTdGFuZGFsb25lOwotICAgIH0KLQotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyB2b2lkIHNldFhtbFN0YW5kYWxvbmUoYm9vbGVhbiB4bWxTdGFuZGFsb25lKSB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKLSAgICAgICAgdGhpcy54bWxTdGFuZGFsb25lID0geG1sU3RhbmRhbG9uZTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIFN0cmluZyB4bWxWZXJzaW9uOwotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0WG1sVmVyc2lvbigpIHsKLSAgICAgICAgcmV0dXJuIHhtbFZlcnNpb247Ci0gICAgfQotCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIHZvaWQgc2V0WG1sVmVyc2lvbihTdHJpbmcgeG1sVmVyc2lvbikgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0gICAgICAgIHRoaXMueG1sVmVyc2lvbiA9IHhtbFZlcnNpb247Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vcmVmL0RUTVNhZmVTdHJpbmdQb29sLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vcmVmL0RUTVNhZmVTdHJpbmdQb29sLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGUyMjQwMmQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL3JlZi9EVE1TYWZlU3RyaW5nUG9vbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTEyICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IERUTVNhZmVTdHJpbmdQb29sLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTUgMDg6MTU6MDQgc3VyZXNoX2VtYWlsaWQgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLnJlZjsKLQotCi0vKiogPHA+TGlrZSBEVE1TdHJpbmdQb29sLCBidXQgdGhyZWFkc2FmZS4gSXQncyBiZWVuIHByb3Bvc2VkIHRoYXQgRFRNcwotICogc2hhcmUgdGhlaXIgc3RyaW5nIHBvb2wocyk7IHRoYXQgcmFpc2VzIHRocmVhZHNhZmV0eSBpc3N1ZXMgd2hpY2gKLSAqIHRoaXMgYWRkcmVzc2VzLiBPZiBjb3Vyc2UgcGVyZm9ybWFuY2UgaXMgaW5mZXJpb3IgdG8gdGhhdCBvZiB0aGUKLSAqIGJhcmUtYm9uZXMgdmVyc2lvbi48L3A+Ci0gKgotICogPHA+U3RhdHVzOiBQYXNzZWQgYmFzaWMgdGVzdCBpbiBtYWluKCkuPC9wPgotICogKi8KLXB1YmxpYyBjbGFzcyBEVE1TYWZlU3RyaW5nUG9vbAotZXh0ZW5kcyBEVE1TdHJpbmdQb29sCi17Ci0gIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCByZW1vdmVBbGxFbGVtZW50cygpCi0gICAgewotICAgICAgc3VwZXIucmVtb3ZlQWxsRWxlbWVudHMoKTsKLSAgICB9Ci0KLSAgLyoqIEByZXR1cm4gc3RyaW5nIHdob3NlIHZhbHVlIGlzIHVuaXF1ZWx5IGlkZW50aWZpZWQgYnkgdGhpcyBpbnRlZ2VyIGluZGV4LgotICAgKiBAdGhyb3dzIGphdmEubGFuZy5BcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KLSAgICogIGlmIGluZGV4IGRvZXNuJ3QgbWFwIHRvIGEgc3RyaW5nLgotICAgKiAqLwotICBwdWJsaWMgc3luY2hyb25pemVkIFN0cmluZyBpbmRleFRvU3RyaW5nKGludCBpKQotICAgIHRocm93cyBqYXZhLmxhbmcuQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCi0gICAgewotICAgICAgcmV0dXJuIHN1cGVyLmluZGV4VG9TdHJpbmcoaSk7Ci0gICAgfQotCi0gIC8qKiBAcmV0dXJuIGludGVnZXIgaW5kZXggdW5pcXVlbHkgaWRlbnRpZnlpbmcgdGhlIHZhbHVlIG9mIHRoaXMgc3RyaW5nLiAqLwotICBwdWJsaWMgc3luY2hyb25pemVkIGludCBzdHJpbmdUb0luZGV4KFN0cmluZyBzKQotICAgIHsKLSAgICAgIHJldHVybiBzdXBlci5zdHJpbmdUb0luZGV4KHMpOwotICAgIH0KLQotICAvKiogQ29tbWFuZC1saW5lIHVuaXQgdGVzdCBkcml2ZXIuIFRoaXMgdGVzdCByZWxpZXMgb24gdGhlIGZhY3QgdGhhdAotICAgKiB0aGlzIHZlcnNpb24gb2YgdGhlIHBvb2wgYXNzaWducyBpbmRpY2VzIGNvbnNlY3V0aXZlbHksIHN0YXJ0aW5nCi0gICAqIGZyb20gemVybywgYXMgbmV3IHVuaXF1ZSBzdHJpbmdzIGFyZSBlbmNvdW50ZXJlZC4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgdm9pZCBfbWFpbihTdHJpbmdbXSBhcmdzKQotICB7Ci0gICAgU3RyaW5nW10gd29yZD17Ci0gICAgICAiWmVybyIsIk9uZSIsIlR3byIsIlRocmVlIiwiRm91ciIsIkZpdmUiLAotICAgICAgIlNpeCIsIlNldmVuIiwiRWlnaHQiLCJOaW5lIiwiVGVuIiwKLSAgICAgICJFbGV2ZW4iLCJUd2VsdmUiLCJUaGlydGVlbiIsIkZvdXJ0ZWVuIiwiRmlmdGVlbiIsCi0gICAgICAiU2l4dGVlbiIsIlNldmVudGVlbiIsIkVpZ2h0ZWVuIiwiTmluZXRlZW4iLCJUd2VudHkiLAotICAgICAgIlR3ZW50eS1PbmUiLCJUd2VudHktVHdvIiwiVHdlbnR5LVRocmVlIiwiVHdlbnR5LUZvdXIiLAotICAgICAgIlR3ZW50eS1GaXZlIiwiVHdlbnR5LVNpeCIsIlR3ZW50eS1TZXZlbiIsIlR3ZW50eS1FaWdodCIsCi0gICAgICAiVHdlbnR5LU5pbmUiLCJUaGlydHkiLCJUaGlydHktT25lIiwiVGhpcnR5LVR3byIsCi0gICAgICAiVGhpcnR5LVRocmVlIiwiVGhpcnR5LUZvdXIiLCJUaGlydHktRml2ZSIsIlRoaXJ0eS1TaXgiLAotICAgICAgIlRoaXJ0eS1TZXZlbiIsIlRoaXJ0eS1FaWdodCIsIlRoaXJ0eS1OaW5lIn07Ci0KLSAgICBEVE1TdHJpbmdQb29sIHBvb2w9bmV3IERUTVNhZmVTdHJpbmdQb29sKCk7Ci0KLSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIklmIG5vIGNvbXBsYWludHMgYXJlIHByaW50ZWQgYmVsb3csIHdlIHBhc3NlZCBpbml0aWFsIHRlc3QuIik7Ci0KLSAgICBmb3IoaW50IHBhc3M9MDtwYXNzPD0xOysrcGFzcykKLSAgICAgIHsKLSAgICAgICAgaW50IGk7Ci0KLSAgICAgICAgZm9yKGk9MDtpPHdvcmQubGVuZ3RoOysraSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBpbnQgaj1wb29sLnN0cmluZ1RvSW5kZXgod29yZFtpXSk7Ci0gICAgICAgICAgICBpZihqIT1pKQotICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlx0TWlzbWF0Y2ggcG9wdWxhdGluZyBwb29sOiBhc3NpZ25lZCAiKwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaisiIGZvciBjcmVhdGUgIitpKTsKLSAgICAgICAgICB9Ci0KLSAgICAgICAgZm9yKGk9MDtpPHdvcmQubGVuZ3RoOysraSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBpbnQgaj1wb29sLnN0cmluZ1RvSW5kZXgod29yZFtpXSk7Ci0gICAgICAgICAgICBpZihqIT1pKQotICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlx0TWlzbWF0Y2ggaW4gc3RyaW5nVG9JbmRleDogcmV0dXJuZWQgIisKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGorIiBmb3IgbG9va3VwICIraSk7Ci0gICAgICAgICAgfQotCi0gICAgICAgIGZvcihpPTA7aTx3b3JkLmxlbmd0aDsrK2kpCi0gICAgICAgICAgewotICAgICAgICAgICAgU3RyaW5nIHc9cG9vbC5pbmRleFRvU3RyaW5nKGkpOwotICAgICAgICAgICAgaWYoIXdvcmRbaV0uZXF1YWxzKHcpKQotICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlx0TWlzbWF0Y2ggaW4gaW5kZXhUb1N0cmluZzogcmV0dXJuZWQiKwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdysiIGZvciBsb29rdXAgIitpKTsKLSAgICAgICAgICB9Ci0KLSAgICAgICAgcG9vbC5yZW1vdmVBbGxFbGVtZW50cygpOwotCi0gICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXG5QYXNzICIrcGFzcysiIGNvbXBsZXRlXG4iKTsKLSAgICAgIH0gLy8gZW5kIHBhc3MgbG9vcAotICB9Ci19IC8vIERUTVNhZmVTdHJpbmdQb29sCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vcmVmL0RUTVN0cmluZ1Bvb2wuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9yZWYvRFRNU3RyaW5nUG9vbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkNDliNjJhLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9yZWYvRFRNU3RyaW5nUG9vbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTkzICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IERUTVN0cmluZ1Bvb2wuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNSAwODoxNTowNSBzdXJlc2hfZW1haWxpZCBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0ucmVmOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuSW50VmVjdG9yOwotCi0vKiogPHA+RFRNU3RyaW5nUG9vbCBpcyBhbiAiaW50ZXJuaW5nIiBtZWNoYW5pc20gZm9yIHN0cmluZ3MuIEl0IHdpbGwKLSAqIGNyZWF0ZSBhIHN0YWJsZSAxOjEgbWFwcGluZyBiZXR3ZWVuIGEgc2V0IG9mIHN0cmluZyB2YWx1ZXMgYW5kIGEgc2V0IG9mCi0gKiBpbnRlZ2VyIGluZGV4IHZhbHVlcywgc28gdGhlIGludGVnZXJzIGNhbiBiZSB1c2VkIHRvIHJlbGlhYmx5IGFuZAotICogdW5pcXVlbHkgaWRlbnRpZnkgKGFuZCB3aGVuIG5lY2Vzc2FyeSByZXRyaWV2ZSkgdGhlIHN0cmluZ3MuPC9wPgotICoKLSAqIDxwPkRlc2lnbiBQcmlvcml0aWVzOgotICogPHVsPgotICogPGxpPlN0cmluZy10by1pbmRleCBsb29rdXAgc3BlZWQgaXMgY3JpdGljYWwuPC9saT4KLSAqIDxsaT5JbmRleC10by1TdHJpbmcgbG9va3VwIHNwZWVkIGlzIHNsaWdodGx5IGxlc3Mgc28uPC9saT4KLSAqIDxsaT5UaHJlYWRzYWZldHkgaXMgbm90IGd1YXJhbnRlZWQgYXQgdGhpcyBsZXZlbC4KLSAqIEVuZm9yY2UgdGhhdCBpbiB0aGUgYXBwbGljYXRpb24gaWYgbmVlZGVkLjwvbGk+Ci0gKiA8bGk+U3RvcmFnZSBlZmZpY2llbmN5IGlzIGFuIGlzc3VlIGJ1dCBub3QgYSBodWdlIG9uZS4KLSAqIEl0IGlzIGV4cGVjdGVkIHRoYXQgc3RyaW5nIHBvb2xzIHdvbid0IGV4Y2VlZCBhYm91dCAyMDAwIGVudHJpZXMuPC9saT4KLSAqIDwvdWw+Ci0gKiA8L3A+Ci0gKgotICogPHA+SW1wbGVtZW50YXRpb24gZGV0YWlsOiBBIHN0YW5kYXJkIEhhc2h0YWJsZSBpcyByZWxhdGl2ZWx5Ci0gKiBpbmVmZmljaWVudCB3aGVuIGxvb2tpbmcgdXAgcHJpbWl0aXZlIGludCB2YWx1ZXMsIGVzcGVjaWFsbHkgd2hlbgotICogd2UncmUgYWxyZWFkeSBtYWludGFpbmluZyBhbiBpbnQtdG8tc3RyaW5nIHZlY3Rvci4gIFNvIEknbQotICogbWFpbnRhaW5pbmcgYSBzaW1wbGUgaGFzaCBjaGFpbiB3aXRoaW4gdGhpcyBjbGFzcy48L3A+Ci0gKgotICogPHA+Tk9URTogVGhlcmUgaXMgbm90aGluZyBpbiB0aGUgY29kZSB0aGF0IGhhcyBhIHJlYWwgZGVwZW5kZW5jeSB1cG9uCi0gKiBTdHJpbmcuIEl0IHdvdWxkIHdvcmsgd2l0aCBhbnkgb2JqZWN0IHR5cGUgdGhhdCBpbXBsZW1lbnRzIHJlbGlhYmxlCi0gKiAuaGFzaENvZGUoKSBhbmQgLmVxdWFscygpIG9wZXJhdGlvbnMuIFRoZSBBUEkgZW5mb3JjZXMgU3RyaW5ncyBiZWNhdXNlCi0gKiBpdCdzIHNhZmVyIHRoYXQgd2F5LCBidXQgdGhpcyBjb3VsZCB0cml2aWFsbHkgYmUgdHVybmVkIGludG8gYSBnZW5lcmFsCi0gKiBPYmplY3RQb29sIGlmIG9uZSB3YXMgbmVlZGVkLjwvcD4KLSAqCi0gKiA8cD5TdGF0dXM6IFBhc3NlZCBiYXNpYyB0ZXN0IGluIG1haW4oKS48L3A+Ci0gKiAqLwotcHVibGljIGNsYXNzIERUTVN0cmluZ1Bvb2wKLXsKLSAgVmVjdG9yIG1faW50VG9TdHJpbmc7Ci0gIHN0YXRpYyBmaW5hbCBpbnQgSEFTSFBSSU1FPTEwMTsKLSAgaW50W10gbV9oYXNoU3RhcnQ9bmV3IGludFtIQVNIUFJJTUVdOwotICBJbnRWZWN0b3IgbV9oYXNoQ2hhaW47Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE5VTEw9LTE7Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIERUTVN0cmluZ1Bvb2wgdXNpbmcgdGhlIGdpdmVuIGNoYWluIHNpemUKLSAgICoKLSAgICogQHBhcmFtIGNoYWluU2l6ZSBUaGUgc2l6ZSBvZiB0aGUgaGFzaCBjaGFpbiB2ZWN0b3IKLSAgICovCi0gIHB1YmxpYyBEVE1TdHJpbmdQb29sKGludCBjaGFpblNpemUpCi0gICAgewotICAgICAgbV9pbnRUb1N0cmluZz1uZXcgVmVjdG9yKCk7Ci0gICAgICBtX2hhc2hDaGFpbj1uZXcgSW50VmVjdG9yKGNoYWluU2l6ZSk7Ci0gICAgICByZW1vdmVBbGxFbGVtZW50cygpOwotCi0gICAgICAvLyAtc2IgQWRkIHRoaXMgdG8gZm9yY2UgZW1wdHkgc3RyaW5ncyB0byBiZSBpbmRleCAwLgotICAgICAgc3RyaW5nVG9JbmRleCgiIik7Ci0gICAgfQotCi0gIHB1YmxpYyBEVE1TdHJpbmdQb29sKCkKLSAgICB7Ci0gICAgICB0aGlzKDUxMik7Ci0gICAgfQotCi0gIHB1YmxpYyB2b2lkIHJlbW92ZUFsbEVsZW1lbnRzKCkKLSAgICB7Ci0gICAgICBtX2ludFRvU3RyaW5nLnJlbW92ZUFsbEVsZW1lbnRzKCk7Ci0gICAgICBmb3IoaW50IGk9MDtpPEhBU0hQUklNRTsrK2kpCi0gICAgICAgIG1faGFzaFN0YXJ0W2ldPU5VTEw7Ci0gICAgICBtX2hhc2hDaGFpbi5yZW1vdmVBbGxFbGVtZW50cygpOwotICAgIH0KLQotICAvKiogQHJldHVybiBzdHJpbmcgd2hvc2UgdmFsdWUgaXMgdW5pcXVlbHkgaWRlbnRpZmllZCBieSB0aGlzIGludGVnZXIgaW5kZXguCi0gICAqIEB0aHJvd3MgamF2YS5sYW5nLkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgotICAgKiAgaWYgaW5kZXggZG9lc24ndCBtYXAgdG8gYSBzdHJpbmcuCi0gICAqICovCi0gIHB1YmxpYyBTdHJpbmcgaW5kZXhUb1N0cmluZyhpbnQgaSkKLSAgICB0aHJvd3MgamF2YS5sYW5nLkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgotICAgIHsKLSAgICAgIGlmKGk9PU5VTEwpIHJldHVybiBudWxsOwotICAgICAgcmV0dXJuIChTdHJpbmcpIG1faW50VG9TdHJpbmcuZWxlbWVudEF0KGkpOwotICAgIH0KLQotICAvKiogQHJldHVybiBpbnRlZ2VyIGluZGV4IHVuaXF1ZWx5IGlkZW50aWZ5aW5nIHRoZSB2YWx1ZSBvZiB0aGlzIHN0cmluZy4gKi8KLSAgcHVibGljIGludCBzdHJpbmdUb0luZGV4KFN0cmluZyBzKQotICAgIHsKLSAgICAgIGlmKHM9PW51bGwpIHJldHVybiBOVUxMOwotCi0gICAgICBpbnQgaGFzaHNsb3Q9cy5oYXNoQ29kZSgpJUhBU0hQUklNRTsKLSAgICAgIGlmKGhhc2hzbG90PDApIGhhc2hzbG90PS1oYXNoc2xvdDsKLQotICAgICAgLy8gSXMgaXQgb25lIHdlIGFscmVhZHkga25vdz8KLSAgICAgIGludCBoYXNobGFzdD1tX2hhc2hTdGFydFtoYXNoc2xvdF07Ci0gICAgICBpbnQgaGFzaGNhbmRpZGF0ZT1oYXNobGFzdDsKLSAgICAgIHdoaWxlKGhhc2hjYW5kaWRhdGUhPU5VTEwpCi0gICAgICAgIHsKLSAgICAgICAgICBpZihtX2ludFRvU3RyaW5nLmVsZW1lbnRBdChoYXNoY2FuZGlkYXRlKS5lcXVhbHMocykpCi0gICAgICAgICAgICByZXR1cm4gaGFzaGNhbmRpZGF0ZTsKLQotICAgICAgICAgIGhhc2hsYXN0PWhhc2hjYW5kaWRhdGU7Ci0gICAgICAgICAgaGFzaGNhbmRpZGF0ZT1tX2hhc2hDaGFpbi5lbGVtZW50QXQoaGFzaGNhbmRpZGF0ZSk7Ci0gICAgICAgIH0KLQotICAgICAgLy8gTmV3IHZhbHVlLiBBZGQgdG8gdGFibGVzLgotICAgICAgaW50IG5ld0luZGV4PW1faW50VG9TdHJpbmcuc2l6ZSgpOwotICAgICAgbV9pbnRUb1N0cmluZy5hZGRFbGVtZW50KHMpOwotCi0gICAgICBtX2hhc2hDaGFpbi5hZGRFbGVtZW50KE5VTEwpOyAgICAgLy8gSW5pdGlhbGl6ZSB0byBuby1mb2xsb3dpbmctc2FtZS1oYXNoCi0gICAgICBpZihoYXNobGFzdD09TlVMTCkgIC8vIEZpcnN0IGZvciB0aGlzIGhhc2gKLSAgICAgICAgbV9oYXNoU3RhcnRbaGFzaHNsb3RdPW5ld0luZGV4OwotICAgICAgZWxzZSAvLyBMaW5rIGZyb20gcHJldmlvdXMgd2l0aCBzYW1lIGhhc2gKLSAgICAgICAgbV9oYXNoQ2hhaW4uc2V0RWxlbWVudEF0KG5ld0luZGV4LGhhc2hsYXN0KTsKLQotICAgICAgcmV0dXJuIG5ld0luZGV4OwotICAgIH0KLQotICAvKiogQ29tbWFuZC1saW5lIHVuaXQgdGVzdCBkcml2ZXIuIFRoaXMgdGVzdCByZWxpZXMgb24gdGhlIGZhY3QgdGhhdAotICAgKiB0aGlzIHZlcnNpb24gb2YgdGhlIHBvb2wgYXNzaWducyBpbmRpY2VzIGNvbnNlY3V0aXZlbHksIHN0YXJ0aW5nCi0gICAqIGZyb20gemVybywgYXMgbmV3IHVuaXF1ZSBzdHJpbmdzIGFyZSBlbmNvdW50ZXJlZC4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgdm9pZCBfbWFpbihTdHJpbmdbXSBhcmdzKQotICB7Ci0gICAgU3RyaW5nW10gd29yZD17Ci0gICAgICAiWmVybyIsIk9uZSIsIlR3byIsIlRocmVlIiwiRm91ciIsIkZpdmUiLAotICAgICAgIlNpeCIsIlNldmVuIiwiRWlnaHQiLCJOaW5lIiwiVGVuIiwKLSAgICAgICJFbGV2ZW4iLCJUd2VsdmUiLCJUaGlydGVlbiIsIkZvdXJ0ZWVuIiwiRmlmdGVlbiIsCi0gICAgICAiU2l4dGVlbiIsIlNldmVudGVlbiIsIkVpZ2h0ZWVuIiwiTmluZXRlZW4iLCJUd2VudHkiLAotICAgICAgIlR3ZW50eS1PbmUiLCJUd2VudHktVHdvIiwiVHdlbnR5LVRocmVlIiwiVHdlbnR5LUZvdXIiLAotICAgICAgIlR3ZW50eS1GaXZlIiwiVHdlbnR5LVNpeCIsIlR3ZW50eS1TZXZlbiIsIlR3ZW50eS1FaWdodCIsCi0gICAgICAiVHdlbnR5LU5pbmUiLCJUaGlydHkiLCJUaGlydHktT25lIiwiVGhpcnR5LVR3byIsCi0gICAgICAiVGhpcnR5LVRocmVlIiwiVGhpcnR5LUZvdXIiLCJUaGlydHktRml2ZSIsIlRoaXJ0eS1TaXgiLAotICAgICAgIlRoaXJ0eS1TZXZlbiIsIlRoaXJ0eS1FaWdodCIsIlRoaXJ0eS1OaW5lIn07Ci0KLSAgICBEVE1TdHJpbmdQb29sIHBvb2w9bmV3IERUTVN0cmluZ1Bvb2woKTsKLQotICAgIFN5c3RlbS5vdXQucHJpbnRsbigiSWYgbm8gY29tcGxhaW50cyBhcmUgcHJpbnRlZCBiZWxvdywgd2UgcGFzc2VkIGluaXRpYWwgdGVzdC4iKTsKLQotICAgIGZvcihpbnQgcGFzcz0wO3Bhc3M8PTE7KytwYXNzKQotICAgICAgewotICAgICAgICBpbnQgaTsKLQotICAgICAgICBmb3IoaT0wO2k8d29yZC5sZW5ndGg7KytpKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGludCBqPXBvb2wuc3RyaW5nVG9JbmRleCh3b3JkW2ldKTsKLSAgICAgICAgICAgIGlmKGohPWkpCi0gICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXHRNaXNtYXRjaCBwb3B1bGF0aW5nIHBvb2w6IGFzc2lnbmVkICIrCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqKyIgZm9yIGNyZWF0ZSAiK2kpOwotICAgICAgICAgIH0KLQotICAgICAgICBmb3IoaT0wO2k8d29yZC5sZW5ndGg7KytpKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGludCBqPXBvb2wuc3RyaW5nVG9JbmRleCh3b3JkW2ldKTsKLSAgICAgICAgICAgIGlmKGohPWkpCi0gICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXHRNaXNtYXRjaCBpbiBzdHJpbmdUb0luZGV4OiByZXR1cm5lZCAiKwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaisiIGZvciBsb29rdXAgIitpKTsKLSAgICAgICAgICB9Ci0KLSAgICAgICAgZm9yKGk9MDtpPHdvcmQubGVuZ3RoOysraSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBTdHJpbmcgdz1wb29sLmluZGV4VG9TdHJpbmcoaSk7Ci0gICAgICAgICAgICBpZighd29yZFtpXS5lcXVhbHModykpCi0gICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXHRNaXNtYXRjaCBpbiBpbmRleFRvU3RyaW5nOiByZXR1cm5lZCIrCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3KyIgZm9yIGxvb2t1cCAiK2kpOwotICAgICAgICAgIH0KLQotICAgICAgICBwb29sLnJlbW92ZUFsbEVsZW1lbnRzKCk7Ci0KLSAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJcblBhc3MgIitwYXNzKyIgY29tcGxldGVcbiIpOwotICAgICAgfSAvLyBlbmQgcGFzcyBsb29wCi0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9yZWYvRFRNVHJlZVdhbGtlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL3JlZi9EVE1UcmVlV2Fsa2VyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDM3YzcyZDEuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL3JlZi9EVE1UcmVlV2Fsa2VyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0MDUgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRFRNVHJlZVdhbGtlci5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE1IDA4OjE1OjA1IHN1cmVzaF9lbWFpbGlkIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0ucmVmOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuTm9kZUNvbnN1bWVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuWE1MU3RyaW5nOwotCi1pbXBvcnQgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguZXh0LkxleGljYWxIYW5kbGVyOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgZG9lcyBhIHByZS1vcmRlciB3YWxrIG9mIHRoZSBEVE0gdHJlZSwgY2FsbGluZyBhIENvbnRlbnRIYW5kbGVyCi0gKiBpbnRlcmZhY2UgYXMgaXQgZ29lcy4gQXMgc3VjaCwgaXQncyBtb3JlIGxpa2UgdGhlIFZpc2l0b3IgZGVzaWduIHBhdHRlcm4KLSAqIHRoYW4gbGlrZSB0aGUgRE9NJ3MgVHJlZVdhbGtlci4KLSAqCi0gKiBJIHRoaW5rIG5vcm1hbGx5IHRoaXMgY2xhc3Mgc2hvdWxkIG5vdCBiZSBuZWVkZWQsIGJlY2F1c2UKLSAqIG9mIERUTSNkaXNwYXRjaFRvRXZlbnRzLgotICogQHhzbC51c2FnZSBhZHZhbmNlZAotICovCi1wdWJsaWMgY2xhc3MgRFRNVHJlZVdhbGtlcgotewotCi0gIC8qKiBMb2NhbCByZWZlcmVuY2UgdG8gYSBDb250ZW50SGFuZGxlciAgICAgICAgICAqLwotICBwcml2YXRlIENvbnRlbnRIYW5kbGVyIG1fY29udGVudEhhbmRsZXIgPSBudWxsOwotCi0gIC8qKiBEb21IZWxwZXIgZm9yIHRoaXMgVHJlZVdhbGtlciAgICAgICAgICAqLwotICBwcm90ZWN0ZWQgRFRNIG1fZHRtOwotCi0gIC8qKgotICAgKiBTZXQgdGhlIERUTSB0byBiZSB0cmF2ZXJzZWQuCi0gICAqCi0gICAqIEBwYXJhbSBkdG0gVGhlIERvY3VtZW50IFRhYmxlIE1vZGVsIHRvIGJlIHVzZWQuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXREVE0oRFRNIGR0bSkKLSAgewotICAgIG1fZHRtID0gZHRtOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgQ29udGVudEhhbmRsZXIgdXNlZCBmb3IgdGhlIHRyZWUgd2Fsay4KLSAgICoKLSAgICogQHJldHVybiB0aGUgQ29udGVudEhhbmRsZXIgdXNlZCBmb3IgdGhlIHRyZWUgd2FsawotICAgKi8KLSAgcHVibGljIENvbnRlbnRIYW5kbGVyIGdldGNvbnRlbnRIYW5kbGVyKCkKLSAgewotICAgIHJldHVybiBtX2NvbnRlbnRIYW5kbGVyOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgQ29udGVudEhhbmRsZXIgdXNlZCBmb3IgdGhlIHRyZWUgd2Fsay4KLSAgICoKLSAgICogQHBhcmFtIGNoIHRoZSBDb250ZW50SGFuZGxlciB0byBiZSB0aGUgcmVzdWx0IG9mIHRoZSB0cmVlIHdhbGsuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRjb250ZW50SGFuZGxlcihDb250ZW50SGFuZGxlciBjaCkKLSAgewotICAgIG1fY29udGVudEhhbmRsZXIgPSBjaDsKLSAgfQotCi0KLSAgLyoqCi0gICAqIENvbnN0cnVjdG9yLgotICAgKi8KLSAgcHVibGljIERUTVRyZWVXYWxrZXIoKQotICB7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0b3IuCi0gICAqIEBwYXJhbSAgIGNvbnRlbnRIYW5kbGVyIFRoZSBpbXBsZW1lbnRpb24gb2YgdGhlCi0gICAqIGNvbnRlbnRIYW5kbGVyIG9wZXJhdGlvbiAodG9YTUxTdHJpbmcsIGRpZ2VzdCwgLi4uKQotICAgKi8KLSAgcHVibGljIERUTVRyZWVXYWxrZXIoQ29udGVudEhhbmRsZXIgY29udGVudEhhbmRsZXIsIERUTSBkdG0pCi0gIHsKLSAgICB0aGlzLm1fY29udGVudEhhbmRsZXIgPSBjb250ZW50SGFuZGxlcjsKLSAgICBtX2R0bSA9IGR0bTsKLSAgfQotCi0gIC8qKiBQZXJmb3JtIGEgbm9uLXJlY3Vyc2l2ZSBwcmUtb3JkZXIvcG9zdC1vcmRlciB0cmF2ZXJzYWwsCi0gICAqIG9wZXJhdGluZyBhcyBhIFZpc2l0b3IuIHN0YXJ0Tm9kZSAocHJlb3JkZXIpIGFuZCBlbmROb2RlCi0gICAqIChwb3N0b3JkZXIpIGFyZSBpbnZva2VkIGZvciBlYWNoIG5vZGUgYXMgd2UgdHJhdmVyc2Ugb3ZlciB0aGVtLAotICAgKiB3aXRoIHRoZSByZXN1bHQgdGhhdCB0aGUgbm9kZSBpcyB3cml0dGVuIG91dCB0byBtX2NvbnRlbnRIYW5kbGVyLgotICAgKgotICAgKiBAcGFyYW0gcG9zIE5vZGUgaW4gdGhlIHRyZWUgYXQgd2hpY2ggdG8gc3RhcnQgKGFuZCBlbmQpIHRyYXZlcnNhbCAtLQotICAgKiBpbiBvdGhlciB3b3JkcywgdGhlIHJvb3Qgb2YgdGhlIHN1YnRyZWUgdG8gdHJhdmVyc2Ugb3Zlci4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiAqLwotICBwdWJsaWMgdm9pZCB0cmF2ZXJzZShpbnQgcG9zKSB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICAvLyAlUkVWSUVXJSBXaHkgaXNuJ3QgdGhpcyBqdXN0IHRyYXZlcnNlKHBvcyxwb3MpPwotCi0gICAgaW50IHRvcCA9IHBvczsgICAgICAgICAgICAgIC8vIFJlbWVtYmVyIHRoZSByb290IG9mIHRoaXMgc3VidHJlZQotCi0gICAgd2hpbGUgKERUTS5OVUxMICE9IHBvcykKLSAgICB7Ci0gICAgICBzdGFydE5vZGUocG9zKTsKLSAgICAgIGludCBuZXh0Tm9kZSA9IG1fZHRtLmdldEZpcnN0Q2hpbGQocG9zKTsKLSAgICAgIHdoaWxlIChEVE0uTlVMTCA9PSBuZXh0Tm9kZSkKLSAgICAgIHsKLSAgICAgICAgZW5kTm9kZShwb3MpOwotCi0gICAgICAgIGlmICh0b3AgPT0gcG9zKQotICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgIG5leHROb2RlID0gbV9kdG0uZ2V0TmV4dFNpYmxpbmcocG9zKTsKLQotICAgICAgICBpZiAoRFRNLk5VTEwgPT0gbmV4dE5vZGUpCi0gICAgICAgIHsKLSAgICAgICAgICBwb3MgPSBtX2R0bS5nZXRQYXJlbnQocG9zKTsKLQotICAgICAgICAgIGlmICgoRFRNLk5VTEwgPT0gcG9zKSB8fCAodG9wID09IHBvcykpCi0gICAgICAgICAgewotICAgICAgICAgICAgLy8gJVJFVklFVyUgVGhpcyBjb25kaXRpb24gaXNuJ3QgdGVzdGVkIGluIHRyYXZlcnNlKHBvcyx0b3ApCi0gICAgICAgICAgICAvLyAtLSBidWc/Ci0gICAgICAgICAgICBpZiAoRFRNLk5VTEwgIT0gcG9zKQotICAgICAgICAgICAgICBlbmROb2RlKHBvcyk7Ci0KLSAgICAgICAgICAgIG5leHROb2RlID0gRFRNLk5VTEw7Ci0KLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgfQotCi0gICAgICBwb3MgPSBuZXh0Tm9kZTsKLSAgICB9Ci0gIH0KLQotICAvKiogUGVyZm9ybSBhIG5vbi1yZWN1cnNpdmUgcHJlLW9yZGVyL3Bvc3Qtb3JkZXIgdHJhdmVyc2FsLAotICAgKiBvcGVyYXRpbmcgYXMgYSBWaXNpdG9yLiBzdGFydE5vZGUgKHByZW9yZGVyKSBhbmQgZW5kTm9kZQotICAgKiAocG9zdG9yZGVyKSBhcmUgaW52b2tlZCBmb3IgZWFjaCBub2RlIGFzIHdlIHRyYXZlcnNlIG92ZXIgdGhlbSwKLSAgICogd2l0aCB0aGUgcmVzdWx0IHRoYXQgdGhlIG5vZGUgaXMgd3JpdHRlbiBvdXQgdG8gbV9jb250ZW50SGFuZGxlci4KLSAgICoKLSAgICogQHBhcmFtIHBvcyBOb2RlIGluIHRoZSB0cmVlIHdoZXJlIHRvIHN0YXJ0IHRyYXZlcnNhbAotICAgKiBAcGFyYW0gdG9wIE5vZGUgaW4gdGhlIHRyZWUgd2hlcmUgdG8gZW5kIHRyYXZlcnNhbC4KLSAgICogSWYgdG9wPT1EVE0uTlVMTCwgcnVuIHRocm91Z2ggZW5kIG9mIGRvY3VtZW50LgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCB0cmF2ZXJzZShpbnQgcG9zLCBpbnQgdG9wKSB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICAvLyAlT1BUJSBDYW4gd2Ugc2ltcGxpZnkgdGhlIGxvb3AgY29uZGl0aW9uYWxzIGJ5IGFkZGluZzoKLSAgICAvLyAgICAgICAgICBpZih0b3A9PURUTS5OVUxMKSB0b3A9MAotICAgIC8vIC0tIG9yIGJ5IHNpbXBseSBpZ25vcmluZyB0aGlzIGNhc2UgYW5kIHJlbHlpbmcgb24gdGhlIGZhY3QgdGhhdAotICAgIC8vIHBvcyB3aWxsIG5ldmVyIGVxdWFsIERUTS5OVUxMIHVudGlsIHdlJ3JlIHJlYWR5IHRvIGV4aXQ/Ci0KLSAgICB3aGlsZSAoRFRNLk5VTEwgIT0gcG9zKQotICAgIHsKLSAgICAgIHN0YXJ0Tm9kZShwb3MpOwotICAgICAgaW50IG5leHROb2RlID0gbV9kdG0uZ2V0Rmlyc3RDaGlsZChwb3MpOwotICAgICAgd2hpbGUgKERUTS5OVUxMID09IG5leHROb2RlKQotICAgICAgewotICAgICAgICBlbmROb2RlKHBvcyk7Ci0KLSAgICAgICAgaWYgKChEVE0uTlVMTCAhPSB0b3ApICYmIHRvcCA9PSBwb3MpCi0gICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgbmV4dE5vZGUgPSBtX2R0bS5nZXROZXh0U2libGluZyhwb3MpOwotCi0gICAgICAgIGlmIChEVE0uTlVMTCA9PSBuZXh0Tm9kZSkKLSAgICAgICAgewotICAgICAgICAgIHBvcyA9IG1fZHRtLmdldFBhcmVudChwb3MpOwotCi0gICAgICAgICAgaWYgKChEVE0uTlVMTCA9PSBwb3MpIHx8ICgoRFRNLk5VTEwgIT0gdG9wKSAmJiAodG9wID09IHBvcykpKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIG5leHROb2RlID0gRFRNLk5VTEw7Ci0KLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgfQotCi0gICAgICBwb3MgPSBuZXh0Tm9kZTsKLSAgICB9Ci0gIH0KLQotICAvKiogRmxhZyBpbmRpY2F0aW5nIHdoZXRoZXIgZm9sbG93aW5nIHRleHQgdG8gYmUgcHJvY2Vzc2VkIGlzIHJhdyB0ZXh0ICAgICAgICAgICovCi0gIGJvb2xlYW4gbmV4dElzUmF3ID0gZmFsc2U7Ci0KLSAgLyoqCi0gICAqIE9wdGltaXplZCBkaXNwYXRjaCBvZiBjaGFyYWN0ZXJzLgotICAgKi8KLSAgcHJpdmF0ZSBmaW5hbCB2b2lkIGRpc3BhdGFjaENoYXJzKGludCBub2RlKQotICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBtX2R0bS5kaXNwYXRjaENoYXJhY3RlcnNFdmVudHMobm9kZSwgbV9jb250ZW50SGFuZGxlciwgZmFsc2UpOwotICB9Ci0KLSAgLyoqCi0gICAqIFN0YXJ0IHByb2Nlc3NpbmcgZ2l2ZW4gbm9kZQotICAgKgotICAgKgotICAgKiBAcGFyYW0gbm9kZSBOb2RlIHRvIHByb2Nlc3MKLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIHN0YXJ0Tm9kZShpbnQgbm9kZSkgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAobV9jb250ZW50SGFuZGxlciBpbnN0YW5jZW9mIE5vZGVDb25zdW1lcikKLSAgICB7Ci0gICAgICAvLyAlVEJEJQotLy8gICAgICAoKE5vZGVDb25zdW1lcikgbV9jb250ZW50SGFuZGxlcikuc2V0T3JpZ2luYXRpbmdOb2RlKG5vZGUpOwotICAgIH0KLQotICAgIHN3aXRjaCAobV9kdG0uZ2V0Tm9kZVR5cGUobm9kZSkpCi0gICAgewotICAgIGNhc2UgRFRNLkNPTU1FTlRfTk9ERSA6Ci0gICAgewotICAgICAgWE1MU3RyaW5nIGRhdGEgPSBtX2R0bS5nZXRTdHJpbmdWYWx1ZShub2RlKTsKLQotICAgICAgaWYgKG1fY29udGVudEhhbmRsZXIgaW5zdGFuY2VvZiBMZXhpY2FsSGFuZGxlcikKLSAgICAgIHsKLSAgICAgICAgTGV4aWNhbEhhbmRsZXIgbGggPSAoKExleGljYWxIYW5kbGVyKSB0aGlzLm1fY29udGVudEhhbmRsZXIpOwotICAgICAgICBkYXRhLmRpc3BhdGNoQXNDb21tZW50KGxoKTsKLSAgICAgIH0KLSAgICB9Ci0gICAgYnJlYWs7Ci0gICAgY2FzZSBEVE0uRE9DVU1FTlRfRlJBR01FTlRfTk9ERSA6Ci0KLSAgICAgIC8vID8/OwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBEVE0uRE9DVU1FTlRfTk9ERSA6Ci0gICAgICB0aGlzLm1fY29udGVudEhhbmRsZXIuc3RhcnREb2N1bWVudCgpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBEVE0uRUxFTUVOVF9OT0RFIDoKLSAgICAgIERUTSBkdG0gPSBtX2R0bTsKLQotICAgICAgZm9yIChpbnQgbnNuID0gZHRtLmdldEZpcnN0TmFtZXNwYWNlTm9kZShub2RlLCB0cnVlKTsgRFRNLk5VTEwgIT0gbnNuOwotICAgICAgICAgICBuc24gPSBkdG0uZ2V0TmV4dE5hbWVzcGFjZU5vZGUobm9kZSwgbnNuLCB0cnVlKSkKLSAgICAgIHsKLSAgICAgICAgLy8gU3RyaW5nIHByZWZpeCA9IGR0bS5nZXRQcmVmaXgobnNuKTsKLSAgICAgICAgU3RyaW5nIHByZWZpeCA9IGR0bS5nZXROb2RlTmFtZVgobnNuKTsKLQotICAgICAgICB0aGlzLm1fY29udGVudEhhbmRsZXIuc3RhcnRQcmVmaXhNYXBwaW5nKHByZWZpeCwgZHRtLmdldE5vZGVWYWx1ZShuc24pKTsKLQotICAgICAgfQotCi0gICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIm1fZGguZ2V0TmFtZXNwYWNlT2ZOb2RlKG5vZGUpOiAiK21fZGguZ2V0TmFtZXNwYWNlT2ZOb2RlKG5vZGUpKTsKLSAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigibV9kaC5nZXRMb2NhbE5hbWVPZk5vZGUobm9kZSk6ICIrbV9kaC5nZXRMb2NhbE5hbWVPZk5vZGUobm9kZSkpOwotICAgICAgU3RyaW5nIG5zID0gZHRtLmdldE5hbWVzcGFjZVVSSShub2RlKTsKLSAgICAgIGlmKG51bGwgPT0gbnMpCi0gICAgICAgIG5zID0gIiI7Ci0KLSAgICAgIC8vICVPUFQlICEhCi0gICAgICBvcmcueG1sLnNheC5oZWxwZXJzLkF0dHJpYnV0ZXNJbXBsIGF0dHJzID0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgb3JnLnhtbC5zYXguaGVscGVycy5BdHRyaWJ1dGVzSW1wbCgpOwotCi0gICAgICBmb3IgKGludCBpID0gZHRtLmdldEZpcnN0QXR0cmlidXRlKG5vZGUpOwotICAgICAgICAgICBpICE9IERUTS5OVUxMOwotICAgICAgICAgICBpID0gZHRtLmdldE5leHRBdHRyaWJ1dGUoaSkpCi0gICAgICB7Ci0gICAgICAgIGF0dHJzLmFkZEF0dHJpYnV0ZShkdG0uZ2V0TmFtZXNwYWNlVVJJKGkpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgZHRtLmdldExvY2FsTmFtZShpKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgIGR0bS5nZXROb2RlTmFtZShpKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICJDREFUQSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICBkdG0uZ2V0Tm9kZVZhbHVlKGkpKTsKLSAgICAgIH0KLQotCi0gICAgICB0aGlzLm1fY29udGVudEhhbmRsZXIuc3RhcnRFbGVtZW50KG5zLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX2R0bS5nZXRMb2NhbE5hbWUobm9kZSksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fZHRtLmdldE5vZGVOYW1lKG5vZGUpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRycyk7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIERUTS5QUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREUgOgotICAgIHsKLSAgICAgIFN0cmluZyBuYW1lID0gbV9kdG0uZ2V0Tm9kZU5hbWUobm9kZSk7Ci0KLSAgICAgIC8vIFN0cmluZyBkYXRhID0gcGkuZ2V0RGF0YSgpOwotICAgICAgaWYgKG5hbWUuZXF1YWxzKCJ4c2x0LW5leHQtaXMtcmF3IikpCi0gICAgICB7Ci0gICAgICAgIG5leHRJc1JhdyA9IHRydWU7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIHRoaXMubV9jb250ZW50SGFuZGxlci5wcm9jZXNzaW5nSW5zdHJ1Y3Rpb24obmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX2R0bS5nZXROb2RlVmFsdWUobm9kZSkpOwotICAgICAgfQotICAgIH0KLSAgICBicmVhazsKLSAgICBjYXNlIERUTS5DREFUQV9TRUNUSU9OX05PREUgOgotICAgIHsKLSAgICAgIGJvb2xlYW4gaXNMZXhIID0gKG1fY29udGVudEhhbmRsZXIgaW5zdGFuY2VvZiBMZXhpY2FsSGFuZGxlcik7Ci0gICAgICBMZXhpY2FsSGFuZGxlciBsaCA9IGlzTGV4SAotICAgICAgICAgICAgICAgICAgICAgICAgICA/ICgoTGV4aWNhbEhhbmRsZXIpIHRoaXMubV9jb250ZW50SGFuZGxlcikgOiBudWxsOwotCi0gICAgICBpZiAoaXNMZXhIKQotICAgICAgewotICAgICAgICBsaC5zdGFydENEQVRBKCk7Ci0gICAgICB9Ci0KLSAgICAgIGRpc3BhdGFjaENoYXJzKG5vZGUpOwotCi0gICAgICB7Ci0gICAgICAgIGlmIChpc0xleEgpCi0gICAgICAgIHsKLSAgICAgICAgICBsaC5lbmRDREFUQSgpOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotICAgIGJyZWFrOwotICAgIGNhc2UgRFRNLlRFWFRfTk9ERSA6Ci0gICAgewotICAgICAgaWYgKG5leHRJc1JhdykKLSAgICAgIHsKLSAgICAgICAgbmV4dElzUmF3ID0gZmFsc2U7Ci0KLSAgICAgICAgbV9jb250ZW50SGFuZGxlci5wcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oamF2YXgueG1sLnRyYW5zZm9ybS5SZXN1bHQuUElfRElTQUJMRV9PVVRQVVRfRVNDQVBJTkcsICIiKTsKLSAgICAgICAgZGlzcGF0YWNoQ2hhcnMobm9kZSk7Ci0gICAgICAgIG1fY29udGVudEhhbmRsZXIucHJvY2Vzc2luZ0luc3RydWN0aW9uKGphdmF4LnhtbC50cmFuc2Zvcm0uUmVzdWx0LlBJX0VOQUJMRV9PVVRQVVRfRVNDQVBJTkcsICIiKTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgZGlzcGF0YWNoQ2hhcnMobm9kZSk7Ci0gICAgICB9Ci0gICAgfQotICAgIGJyZWFrOwotICAgIGNhc2UgRFRNLkVOVElUWV9SRUZFUkVOQ0VfTk9ERSA6Ci0gICAgewotICAgICAgaWYgKG1fY29udGVudEhhbmRsZXIgaW5zdGFuY2VvZiBMZXhpY2FsSGFuZGxlcikKLSAgICAgIHsKLSAgICAgICAgKChMZXhpY2FsSGFuZGxlcikgdGhpcy5tX2NvbnRlbnRIYW5kbGVyKS5zdGFydEVudGl0eSgKLSAgICAgICAgICBtX2R0bS5nZXROb2RlTmFtZShub2RlKSk7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0KLSAgICAgICAgLy8gd2FybmluZygiQ2FuIG5vdCBvdXRwdXQgZW50aXR5IHRvIGEgcHVyZSBTQVggQ29udGVudEhhbmRsZXIiKTsKLSAgICAgIH0KLSAgICB9Ci0gICAgYnJlYWs7Ci0gICAgZGVmYXVsdCA6Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEVuZCBwcm9jZXNzaW5nIG9mIGdpdmVuIG5vZGUKLSAgICoKLSAgICoKLSAgICogQHBhcmFtIG5vZGUgTm9kZSB3ZSBqdXN0IGZpbmlzaGVkIHByb2Nlc3NpbmcKLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIGVuZE5vZGUoaW50IG5vZGUpIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgc3dpdGNoIChtX2R0bS5nZXROb2RlVHlwZShub2RlKSkKLSAgICB7Ci0gICAgY2FzZSBEVE0uRE9DVU1FTlRfTk9ERSA6Ci0gICAgICB0aGlzLm1fY29udGVudEhhbmRsZXIuZW5kRG9jdW1lbnQoKTsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgRFRNLkVMRU1FTlRfTk9ERSA6Ci0gICAgICBTdHJpbmcgbnMgPSBtX2R0bS5nZXROYW1lc3BhY2VVUkkobm9kZSk7Ci0gICAgICBpZihudWxsID09IG5zKQotICAgICAgICBucyA9ICIiOwotICAgICAgdGhpcy5tX2NvbnRlbnRIYW5kbGVyLmVuZEVsZW1lbnQobnMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fZHRtLmdldExvY2FsTmFtZShub2RlKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbV9kdG0uZ2V0Tm9kZU5hbWUobm9kZSkpOwotCi0gICAgICBmb3IgKGludCBuc24gPSBtX2R0bS5nZXRGaXJzdE5hbWVzcGFjZU5vZGUobm9kZSwgdHJ1ZSk7IERUTS5OVUxMICE9IG5zbjsKLSAgICAgICAgICAgbnNuID0gbV9kdG0uZ2V0TmV4dE5hbWVzcGFjZU5vZGUobm9kZSwgbnNuLCB0cnVlKSkKLSAgICAgIHsKLSAgICAgICAgLy8gU3RyaW5nIHByZWZpeCA9IG1fZHRtLmdldFByZWZpeChuc24pOwotICAgICAgICBTdHJpbmcgcHJlZml4ID0gbV9kdG0uZ2V0Tm9kZU5hbWVYKG5zbik7Ci0KLSAgICAgICAgdGhpcy5tX2NvbnRlbnRIYW5kbGVyLmVuZFByZWZpeE1hcHBpbmcocHJlZml4KTsKLSAgICAgIH0KLSAgICAgIGJyZWFrOwotICAgIGNhc2UgRFRNLkNEQVRBX1NFQ1RJT05fTk9ERSA6Ci0gICAgICBicmVhazsKLSAgICBjYXNlIERUTS5FTlRJVFlfUkVGRVJFTkNFX05PREUgOgotICAgIHsKLSAgICAgIGlmIChtX2NvbnRlbnRIYW5kbGVyIGluc3RhbmNlb2YgTGV4aWNhbEhhbmRsZXIpCi0gICAgICB7Ci0gICAgICAgIExleGljYWxIYW5kbGVyIGxoID0gKChMZXhpY2FsSGFuZGxlcikgdGhpcy5tX2NvbnRlbnRIYW5kbGVyKTsKLQotICAgICAgICBsaC5lbmRFbnRpdHkobV9kdG0uZ2V0Tm9kZU5hbWUobm9kZSkpOwotICAgICAgfQotICAgIH0KLSAgICBicmVhazsKLSAgICBkZWZhdWx0IDoKLSAgICB9Ci0gIH0KLX0gIC8vVHJlZVdhbGtlcgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL3JlZi9FbXB0eUl0ZXJhdG9yLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vcmVmL0VtcHR5SXRlcmF0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOTc4ZWQ5Mi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vcmVmL0VtcHR5SXRlcmF0b3IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDY0ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRW1wdHlJdGVyYXRvci5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE1IDA4OjE1OjA1IHN1cmVzaF9lbWFpbGlkIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0ucmVmOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNQXhpc0l0ZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTTsKLQotCi0vKioKLSAqIERUTSBFbXB0eSBBeGlzIEl0ZXJhdG9yLiBUaGUgY2xhc3MgaXMgaW1tdXRhYmxlCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBFbXB0eUl0ZXJhdG9yIGltcGxlbWVudHMgRFRNQXhpc0l0ZXJhdG9yCi17Ci0gIHByaXZhdGUgc3RhdGljIGZpbmFsIEVtcHR5SXRlcmF0b3IgSU5TVEFOQ0UgPSAgbmV3IEVtcHR5SXRlcmF0b3IoKTsKLQotICBwdWJsaWMgc3RhdGljIERUTUF4aXNJdGVyYXRvciAgZ2V0SW5zdGFuY2UoKSB7cmV0dXJuIElOU1RBTkNFO30KLQotICBwcml2YXRlIEVtcHR5SXRlcmF0b3IoKXt9Ci0KLSAgcHVibGljIGZpbmFsICBpbnQgIG5leHQoKXsgcmV0dXJuIEVORDsgfQotCi0gIHB1YmxpYyBmaW5hbCBEVE1BeGlzSXRlcmF0b3IgcmVzZXQoKXsgcmV0dXJuIHRoaXM7IH0KLQotICBwdWJsaWMgZmluYWwgaW50IGdldExhc3QoKXsgcmV0dXJuIDA7IH0KLQotICBwdWJsaWMgZmluYWwgaW50IGdldFBvc2l0aW9uKCl7IHJldHVybiAxOyB9Ci0KLSAgcHVibGljIGZpbmFsIHZvaWQgc2V0TWFyaygpe30KLQotICBwdWJsaWMgZmluYWwgdm9pZCBnb3RvTWFyaygpe30KLQotICBwdWJsaWMgZmluYWwgRFRNQXhpc0l0ZXJhdG9yIHNldFN0YXJ0Tm9kZShpbnQgbm9kZSl7IHJldHVybiB0aGlzOyB9Ci0KLSAgcHVibGljIGZpbmFsIGludCBnZXRTdGFydE5vZGUoKXsgcmV0dXJuIEVORDsgfQotCi0gIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzUmV2ZXJzZSgpe3JldHVybiBmYWxzZTt9Ci0KLSAgcHVibGljIGZpbmFsIERUTUF4aXNJdGVyYXRvciBjbG9uZUl0ZXJhdG9yKCl7IHJldHVybiB0aGlzOyB9Ci0KLSAgcHVibGljIGZpbmFsIHZvaWQgc2V0UmVzdGFydGFibGUoYm9vbGVhbiBpc1Jlc3RhcnRhYmxlKSB7fQotCi0gIHB1YmxpYyBmaW5hbCBpbnQgZ2V0Tm9kZUJ5UG9zaXRpb24oaW50IHBvc2l0aW9uKXsgcmV0dXJuIEVORDsgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL3JlZi9FeHBhbmRlZE5hbWVUYWJsZS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL3JlZi9FeHBhbmRlZE5hbWVUYWJsZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4ZDRjN2EzLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9yZWYvRXhwYW5kZWROYW1lVGFibGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDM5MyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBFeHBhbmRlZE5hbWVUYWJsZS5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE1IDA4OjE1OjA2IHN1cmVzaF9lbWFpbGlkIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0ucmVmOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNOwotCi0vKioKLSAqIFRoaXMgaXMgYSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIG9mIGEgdGFibGUgdGhhdCBtYW5hZ2VzIG1hcHBpbmdzIGZyb20KLSAqIGV4cGFuZGVkIG5hbWVzIHRvIGV4cGFuZGVkTmFtZUlEcy4KLSAqCi0gKiAlT1BUJSBUaGUgcGVyZm9ybWFuY2Ugb2YgdGhlIGdldEV4cGFuZGVkVHlwZUlEKCkgbWV0aG9kIGlzIHZlcnkgaW1wb3J0YW50Ci0gKiB0byBEVE0gYnVpbGRpbmcuIFRvIGdldCB0aGUgYmVzdCBwZXJmb3JtYW5jZSBvdXQgb2YgdGhpcyBjbGFzcywgd2UgaW1wbGVtZW50Ci0gKiBhIHNpbXBsZSBoYXNoIGFsZ29yaXRobSBkaXJlY3RseSBpbnRvIHRoaXMgY2xhc3MsIGluc3RlYWQgb2YgdXNpbmcgdGhlCi0gKiBpbmVmZmljaWVudCBqYXZhLnV0aWwuSGFzaHRhYmxlLiBUaGUgY29kZSBmb3IgdGhlIGdldCBhbmQgcHV0IG9wZXJhdGlvbnMKLSAqIGFyZSBjb21iaW5lZCBpbiBnZXRFeHBhbmRlZFR5cGVJRCgpIG1ldGhvZCB0byBzaGFyZSB0aGUgc2FtZSBoYXNoIGNhbGN1bGF0aW9uCi0gKiBjb2RlLiBXZSBvbmx5IG5lZWQgdG8gaW1wbGVtZW50IHRoZSByZWhhc2goKSBpbnRlcmZhY2Ugd2hpY2ggaXMgdXNlZCB0bwotICogZXhwYW5kIHRoZSBoYXNoIHRhYmxlLgotICovCi1wdWJsaWMgY2xhc3MgRXhwYW5kZWROYW1lVGFibGUKLXsKLQotICAvKiogQXJyYXkgb2YgZXh0ZW5kZWQgdHlwZXMgZm9yIHRoaXMgZG9jdW1lbnQgICAqLwotICBwcml2YXRlIEV4dGVuZGVkVHlwZVtdIG1fZXh0ZW5kZWRUeXBlczsKLQotICAvKiogVGhlIGluaXRpYWwgc2l6ZSBvZiB0aGUgbV9leHRlbmRlZFR5cGVzIGFycmF5ICovCi0gIHByaXZhdGUgc3RhdGljIGludCBtX2luaXRpYWxTaXplID0gMTI4OwotCi0gIC8qKiBOZXh0IGF2YWlsYWJsZSBleHRlbmRlZCB0eXBlICAgKi8KLSAgLy8gJVJFVklFVyUgU2luY2UgdGhpcyBpcyAoc2hvdWxkIGJlKSBhbHdheXMgZXF1YWwKLSAgLy8gdG8gdGhlIGxlbmd0aCBvZiBtX2V4dGVuZGVkVHlwZXMsIGRvIHdlIG5lZWQgdGhpcz8KLSAgcHJpdmF0ZSBpbnQgbV9uZXh0VHlwZTsKLQotICAvLyBUaGVzZSBhcmUgYWxsIHRoZSB0eXBlcyBwcmVyb3RhdGVkLCBmb3IgY2FsbGVyIGNvbnZlbmllbmNlLgotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTEVNRU5UID0gKChpbnQpRFRNLkVMRU1FTlRfTk9ERSkgOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBVFRSSUJVVEUgPSAoKGludClEVE0uQVRUUklCVVRFX05PREUpIDsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVEVYVCA9ICgoaW50KURUTS5URVhUX05PREUpIDsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ0RBVEFfU0VDVElPTiA9ICgoaW50KURUTS5DREFUQV9TRUNUSU9OX05PREUpIDsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5USVRZX1JFRkVSRU5DRSA9ICgoaW50KURUTS5FTlRJVFlfUkVGRVJFTkNFX05PREUpIDsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5USVRZID0gKChpbnQpRFRNLkVOVElUWV9OT0RFKSA7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBST0NFU1NJTkdfSU5TVFJVQ1RJT04gPSAoKGludClEVE0uUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFKSA7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENPTU1FTlQgPSAoKGludClEVE0uQ09NTUVOVF9OT0RFKSA7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERPQ1VNRU5UID0gKChpbnQpRFRNLkRPQ1VNRU5UX05PREUpIDsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRE9DVU1FTlRfVFlQRSA9ICgoaW50KURUTS5ET0NVTUVOVF9UWVBFX05PREUpIDsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRE9DVU1FTlRfRlJBR01FTlQgPSgoaW50KURUTS5ET0NVTUVOVF9GUkFHTUVOVF9OT0RFKSA7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE5PVEFUSU9OID0gKChpbnQpRFRNLk5PVEFUSU9OX05PREUpIDsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTkFNRVNQQUNFID0gKChpbnQpRFRNLk5BTUVTUEFDRV9OT0RFKSA7Ci0KLSAgLyoqIFdvcmtzcGFjZSBmb3IgbG9va3VwLiBOT1QgVEhSRUFEIFNBRkUhCi0gICAqICovCi0gIEV4dGVuZGVkVHlwZSBoYXNoRVQgPSBuZXcgRXh0ZW5kZWRUeXBlKC0xLCAiIiwgIiIpOwotCi0gIC8qKiBUaGUgYXJyYXkgdG8gc3RvcmUgdGhlIGRlZmF1bHQgZXh0ZW5kZWQgdHlwZXMuICovCi0gIHByaXZhdGUgc3RhdGljIEV4dGVuZGVkVHlwZVtdIG1fZGVmYXVsdEV4dGVuZGVkVHlwZXM7Ci0KLSAgLyoqCi0gICAqIFRoZSBkZWZhdWx0IGxvYWQgZmFjdG9yIG9mIHRoZSBIYXNodGFibGUuCi0gICAqIFRoaXMgaXMgdXNlZCB0byBjYWxjdWFsdGUgdGhlIHRocmVzaG9sZC4KLSAgICovCi0gIHByaXZhdGUgc3RhdGljIGZsb2F0IG1fbG9hZEZhY3RvciA9IDAuNzVmOwotCi0gIC8qKgotICAgKiBUaGUgaW5pdGlhbCBjYXBhY2l0eSBvZiB0aGUgaGFzaCB0YWJsZS4gVXNlIGEgYmlnZ2VyIG51bWJlcgotICAgKiB0byBhdm9pZCB0aGUgY29zdCBvZiBleHBhbmRpbmcgdGhlIHRhYmxlLgotICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgaW50IG1faW5pdGlhbENhcGFjaXR5ID0gMjAzOwotCi0gIC8qKgotICAgKiBUaGUgY2FwYWNpdHkgb2YgdGhlIGhhc2ggdGFibGUsIGkuZS4gdGhlIHNpemUgb2YgdGhlCi0gICAqIGludGVybmFsIEhhc2hFbnRyeSBhcnJheS4KLSAgICovCi0gIHByaXZhdGUgaW50IG1fY2FwYWNpdHk7Ci0KLSAgLyoqCi0gICAqIFRoZSB0aHJlc2hvbGQgb2YgdGhlIGhhc2ggdGFibGUsIHdoaWNoIGlzIGVxdWFsIHRvIGNhcGFjaXR5ICogbG9hZEZhY3Rvci4KLSAgICogSWYgdGhlIG51bWJlciBvZiBlbnRyaWVzIGluIHRoZSBoYXNoIHRhYmxlIGlzIGJpZ2dlciB0aGFuIHRoZSB0aHJlc2hvbGQsCi0gICAqIHRoZSBoYXNoIHRhYmxlIG5lZWRzIHRvIGJlIGV4cGFuZGVkLgotICAgKi8KLSAgcHJpdmF0ZSBpbnQgbV90aHJlc2hvbGQ7Ci0KLSAgLyoqCi0gICAqIFRoZSBpbnRlcm5hbCBhcnJheSB0byBzdG9yZSB0aGUgaGFzaCBlbnRyaWVzLgotICAgKiBFYWNoIGFycmF5IG1lbWJlciBpcyBhIHNsb3QgZm9yIGEgaGFzaCBidWNrZXQuCi0gICAqLwotICBwcml2YXRlIEhhc2hFbnRyeVtdIG1fdGFibGU7Ci0KLSAgLyoqCi0gICAqIEluaXQgZGVmYXVsdCB2YWx1ZXMKLSAgICovCi0gIHN0YXRpYyB7Ci0gICAgbV9kZWZhdWx0RXh0ZW5kZWRUeXBlcyA9IG5ldyBFeHRlbmRlZFR5cGVbRFRNLk5UWVBFU107Ci0KLSAgICBmb3IgKGludCBpID0gMDsgaSA8IERUTS5OVFlQRVM7IGkrKykKLSAgICB7Ci0gICAgICBtX2RlZmF1bHRFeHRlbmRlZFR5cGVzW2ldID0gbmV3IEV4dGVuZGVkVHlwZShpLCAiIiwgIiIpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBDcmVhdGUgYW4gZXhwYW5kZWQgbmFtZSB0YWJsZS4KLSAgICovCi0gIHB1YmxpYyBFeHBhbmRlZE5hbWVUYWJsZSgpCi0gIHsKLSAgICBtX2NhcGFjaXR5ID0gbV9pbml0aWFsQ2FwYWNpdHk7Ci0gICAgbV90aHJlc2hvbGQgPSAoaW50KShtX2NhcGFjaXR5ICogbV9sb2FkRmFjdG9yKTsKLSAgICBtX3RhYmxlID0gbmV3IEhhc2hFbnRyeVttX2NhcGFjaXR5XTsKLQotICAgIGluaXRFeHRlbmRlZFR5cGVzKCk7Ci0gIH0KLQotCi0gIC8qKgotICAgKiAgSW5pdGlhbGl6ZSB0aGUgdmVjdG9yIG9mIGV4dGVuZGVkIHR5cGVzIHdpdGggdGhlCi0gICAqICBiYXNpYyBET00gbm9kZSB0eXBlcy4KLSAgICovCi0gIHByaXZhdGUgdm9pZCBpbml0RXh0ZW5kZWRUeXBlcygpCi0gIHsKLSAgICBtX2V4dGVuZGVkVHlwZXMgPSBuZXcgRXh0ZW5kZWRUeXBlW21faW5pdGlhbFNpemVdOwotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgRFRNLk5UWVBFUzsgaSsrKSB7Ci0gICAgICAgIG1fZXh0ZW5kZWRUeXBlc1tpXSA9IG1fZGVmYXVsdEV4dGVuZGVkVHlwZXNbaV07Ci0gICAgICAgIG1fdGFibGVbaV0gPSBuZXcgSGFzaEVudHJ5KG1fZGVmYXVsdEV4dGVuZGVkVHlwZXNbaV0sIGksIGksIG51bGwpOwotICAgIH0KLQotICAgIG1fbmV4dFR5cGUgPSBEVE0uTlRZUEVTOwotICB9Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGFuIGV4cGFuZGVkIG5hbWUgcmVwcmVzZW50ZWQgYnkgbmFtZXNwYWNlLCBsb2NhbCBuYW1lIGFuZCBub2RlIHR5cGUsCi0gICAqIHJldHVybiBhbiBJRC4gIElmIHRoZSBleHBhbmRlZC1uYW1lIGRvZXMgbm90IGV4aXN0IGluIHRoZSBpbnRlcm5hbCB0YWJsZXMsCi0gICAqIHRoZSBlbnRyeSB3aWxsIGJlIGNyZWF0ZWQsIGFuZCB0aGUgSUQgd2lsbCBiZSByZXR1cm5lZC4gIEFueSBhZGRpdGlvbmFsCi0gICAqIG5vZGVzIHRoYXQgYXJlIGNyZWF0ZWQgdGhhdCBoYXZlIHRoaXMgZXhwYW5kZWQgbmFtZSB3aWxsIHVzZSB0aGlzIElELgotICAgKgotICAgKiBAcGFyYW0gbmFtZXNwYWNlIFRoZSBuYW1lc3BhY2UKLSAgICogQHBhcmFtIGxvY2FsTmFtZSBUaGUgbG9jYWwgbmFtZQotICAgKiBAcGFyYW0gdHlwZSBUaGUgbm9kZSB0eXBlCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIGV4cGFuZGVkLW5hbWUgaWQgb2YgdGhlIG5vZGUuCi0gICAqLwotICBwdWJsaWMgaW50IGdldEV4cGFuZGVkVHlwZUlEKFN0cmluZyBuYW1lc3BhY2UsIFN0cmluZyBsb2NhbE5hbWUsIGludCB0eXBlKQotICB7Ci0gICAgcmV0dXJuIGdldEV4cGFuZGVkVHlwZUlEKG5hbWVzcGFjZSwgbG9jYWxOYW1lLCB0eXBlLCBmYWxzZSk7Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYW4gZXhwYW5kZWQgbmFtZSByZXByZXNlbnRlZCBieSBuYW1lc3BhY2UsIGxvY2FsIG5hbWUgYW5kIG5vZGUgdHlwZSwKLSAgICogcmV0dXJuIGFuIElELiAgSWYgdGhlIGV4cGFuZGVkLW5hbWUgZG9lcyBub3QgZXhpc3QgaW4gdGhlIGludGVybmFsIHRhYmxlcywKLSAgICogdGhlIGVudHJ5IHdpbGwgYmUgY3JlYXRlZCwgYW5kIHRoZSBJRCB3aWxsIGJlIHJldHVybmVkLiAgQW55IGFkZGl0aW9uYWwKLSAgICogbm9kZXMgdGhhdCBhcmUgY3JlYXRlZCB0aGF0IGhhdmUgdGhpcyBleHBhbmRlZCBuYW1lIHdpbGwgdXNlIHRoaXMgSUQuCi0gICAqIDxwPgotICAgKiBJZiBzZWFyY2hPbmx5IGlzIHRydWUsIHdlIHdpbGwgcmV0dXJuIC0xIGlmIHRoZSBuYW1lIGlzIG5vdCBmb3VuZCBpbiB0aGUKLSAgICogdGFibGUsIG90aGVyd2lzZSB0aGUgbmFtZSBpcyBhZGRlZCB0byB0aGUgdGFibGUgYW5kIHRoZSBleHBhbmRlZCBuYW1lIGlkCi0gICAqIG9mIHRoZSBuZXcgZW50cnkgaXMgcmV0dXJuZWQuCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lc3BhY2UgVGhlIG5hbWVzcGFjZQotICAgKiBAcGFyYW0gbG9jYWxOYW1lIFRoZSBsb2NhbCBuYW1lCi0gICAqIEBwYXJhbSB0eXBlIFRoZSBub2RlIHR5cGUKLSAgICogQHBhcmFtIHNlYXJjaE9ubHkgSWYgaXQgaXMgdHJ1ZSwgd2Ugd2lsbCBvbmx5IHNlYXJjaCBmb3IgdGhlIGV4cGFuZGVkIG5hbWUuCi0gICAqIC0xIGlzIHJldHVybiBpcyB0aGUgbmFtZSBpcyBub3QgZm91bmQuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIGV4cGFuZGVkLW5hbWUgaWQgb2YgdGhlIG5vZGUuCi0gICAqLwotICBwdWJsaWMgaW50IGdldEV4cGFuZGVkVHlwZUlEKFN0cmluZyBuYW1lc3BhY2UsIFN0cmluZyBsb2NhbE5hbWUsIGludCB0eXBlLCBib29sZWFuIHNlYXJjaE9ubHkpCi0gIHsKLSAgICBpZiAobnVsbCA9PSBuYW1lc3BhY2UpCi0gICAgICBuYW1lc3BhY2UgPSAiIjsKLSAgICBpZiAobnVsbCA9PSBsb2NhbE5hbWUpCi0gICAgICBsb2NhbE5hbWUgPSAiIjsKLQotICAgIC8vIENhbGN1bGF0ZSB0aGUgaGFzaCBjb2RlCi0gICAgaW50IGhhc2ggPSB0eXBlICsgbmFtZXNwYWNlLmhhc2hDb2RlKCkgKyBsb2NhbE5hbWUuaGFzaENvZGUoKTsKLQotICAgIC8vIFJlZGVmaW5lIHRoZSBoYXNoRVQgb2JqZWN0IHRvIHJlcHJlc2VudCB0aGUgbmV3IGV4cGFuZGVkIG5hbWUuCi0gICAgaGFzaEVULnJlZGVmaW5lKHR5cGUsIG5hbWVzcGFjZSwgbG9jYWxOYW1lLCBoYXNoKTsKLQotICAgIC8vIENhbGN1bGF0ZSB0aGUgaW5kZXggaW50byB0aGUgSGFzaEVudHJ5IHRhYmxlLgotICAgIGludCBpbmRleCA9IGhhc2ggJSBtX2NhcGFjaXR5OwotICAgIGlmIChpbmRleCA8IDApCi0gICAgICBpbmRleCA9IC1pbmRleDsKLQotICAgIC8vIExvb2sgdXAgdGhlIGV4cGFuZGVkIG5hbWUgaW4gdGhlIGhhc2ggdGFibGUuIFJldHVybiB0aGUgaWQgaWYKLSAgICAvLyB0aGUgZXhwYW5kZWQgbmFtZSBpcyBhbHJlYWR5IGluIHRoZSBoYXNoIHRhYmxlLgotICAgIGZvciAoSGFzaEVudHJ5IGUgPSBtX3RhYmxlW2luZGV4XTsgZSAhPSBudWxsOyBlID0gZS5uZXh0KQotICAgIHsKLSAgICAgIGlmIChlLmhhc2ggPT0gaGFzaCAmJiBlLmtleS5lcXVhbHMoaGFzaEVUKSkKLSAgICAgICAgcmV0dXJuIGUudmFsdWU7Ci0gICAgfQotCi0gICAgaWYgKHNlYXJjaE9ubHkpCi0gICAgewotICAgICAgcmV0dXJuIERUTS5OVUxMOwotICAgIH0KLQotICAgIC8vIEV4cGFuZCB0aGUgaW50ZXJuYWwgSGFzaEVudHJ5IGFycmF5IGlmIG5lY2Vzc2FyeS4KLSAgICBpZiAobV9uZXh0VHlwZSA+IG1fdGhyZXNob2xkKSB7Ci0gICAgICByZWhhc2goKTsKLSAgICAgIGluZGV4ID0gaGFzaCAlIG1fY2FwYWNpdHk7Ci0gICAgICBpZiAoaW5kZXggPCAwKQotICAgICAgICBpbmRleCA9IC1pbmRleDsKLSAgICB9Ci0KLSAgICAvLyBDcmVhdGUgYSBuZXcgRXh0ZW5kZWRUeXBlIG9iamVjdAotICAgIEV4dGVuZGVkVHlwZSBuZXdFVCA9IG5ldyBFeHRlbmRlZFR5cGUodHlwZSwgbmFtZXNwYWNlLCBsb2NhbE5hbWUsIGhhc2gpOwotCi0gICAgLy8gRXhwYW5kIHRoZSBtX2V4dGVuZGVkVHlwZXMgYXJyYXkgaWYgbmVjZXNzYXJ5LgotICAgIGlmIChtX2V4dGVuZGVkVHlwZXMubGVuZ3RoID09IG1fbmV4dFR5cGUpIHsKLSAgICAgICAgRXh0ZW5kZWRUeXBlW10gbmV3QXJyYXkgPSBuZXcgRXh0ZW5kZWRUeXBlW21fZXh0ZW5kZWRUeXBlcy5sZW5ndGggKiAyXTsKLSAgICAgICAgU3lzdGVtLmFycmF5Y29weShtX2V4dGVuZGVkVHlwZXMsIDAsIG5ld0FycmF5LCAwLAotICAgICAgICAgICAgICAgICAgICAgICAgIG1fZXh0ZW5kZWRUeXBlcy5sZW5ndGgpOwotICAgICAgICBtX2V4dGVuZGVkVHlwZXMgPSBuZXdBcnJheTsKLSAgICB9Ci0KLSAgICBtX2V4dGVuZGVkVHlwZXNbbV9uZXh0VHlwZV0gPSBuZXdFVDsKLQotICAgIC8vIENyZWF0ZSBhIG5ldyBoYXNoIGVudHJ5IGZvciB0aGUgbmV3IEV4dGVuZGVkVHlwZSBhbmQgcHV0IGl0IGludG8KLSAgICAvLyB0aGUgdGFibGUuCi0gICAgSGFzaEVudHJ5IGVudHJ5ID0gbmV3IEhhc2hFbnRyeShuZXdFVCwgbV9uZXh0VHlwZSwgaGFzaCwgbV90YWJsZVtpbmRleF0pOwotICAgIG1fdGFibGVbaW5kZXhdID0gZW50cnk7Ci0KLSAgICByZXR1cm4gbV9uZXh0VHlwZSsrOwotICB9Ci0KLSAgLyoqCi0gICAqIEluY3JlYXNlcyB0aGUgY2FwYWNpdHkgb2YgYW5kIGludGVybmFsbHkgcmVvcmdhbml6ZXMgdGhlIGhhc2h0YWJsZSwKLSAgICogaW4gb3JkZXIgdG8gYWNjb21tb2RhdGUgYW5kIGFjY2VzcyBpdHMgZW50cmllcyBtb3JlIGVmZmljaWVudGx5LgotICAgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgd2hlbiB0aGUgbnVtYmVyIG9mIGtleXMgaW4gdGhlIGhhc2h0YWJsZSBleGNlZWRzCi0gICAqIHRoaXMgaGFzaHRhYmxlJ3MgY2FwYWNpdHkgYW5kIGxvYWQgZmFjdG9yLgotICAgKi8KLSAgcHJpdmF0ZSB2b2lkIHJlaGFzaCgpCi0gIHsKLSAgICBpbnQgb2xkQ2FwYWNpdHkgPSBtX2NhcGFjaXR5OwotICAgIEhhc2hFbnRyeVtdIG9sZFRhYmxlID0gbV90YWJsZTsKLQotICAgIGludCBuZXdDYXBhY2l0eSA9IDIgKiBvbGRDYXBhY2l0eSArIDE7Ci0gICAgbV9jYXBhY2l0eSA9IG5ld0NhcGFjaXR5OwotICAgIG1fdGhyZXNob2xkID0gKGludCkobmV3Q2FwYWNpdHkgKiBtX2xvYWRGYWN0b3IpOwotCi0gICAgbV90YWJsZSA9IG5ldyBIYXNoRW50cnlbbmV3Q2FwYWNpdHldOwotICAgIGZvciAoaW50IGkgPSBvbGRDYXBhY2l0eS0xOyBpID49MCA7IGktLSkKLSAgICB7Ci0gICAgICBmb3IgKEhhc2hFbnRyeSBvbGQgPSBvbGRUYWJsZVtpXTsgb2xkICE9IG51bGw7ICkKLSAgICAgIHsKLSAgICAgICAgSGFzaEVudHJ5IGUgPSBvbGQ7Ci0gICAgICAgIG9sZCA9IG9sZC5uZXh0OwotCi0gICAgICAgIGludCBuZXdJbmRleCA9IGUuaGFzaCAlIG5ld0NhcGFjaXR5OwotICAgICAgICBpZiAobmV3SW5kZXggPCAwKQotICAgICAgICAgIG5ld0luZGV4ID0gLW5ld0luZGV4OwotCi0gICAgICAgIGUubmV4dCA9IG1fdGFibGVbbmV3SW5kZXhdOwotICAgICAgICBtX3RhYmxlW25ld0luZGV4XSA9IGU7Ci0gICAgICB9Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgdHlwZSwgcmV0dXJuIGFuIGV4cGFuZGVkIG5hbWUgSUQuQW55IGFkZGl0aW9uYWwgbm9kZXMgdGhhdCBhcmUKLSAgICogY3JlYXRlZCB0aGF0IGhhdmUgdGhpcyBleHBhbmRlZCBuYW1lIHdpbGwgdXNlIHRoaXMgSUQuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIGV4cGFuZGVkLW5hbWUgaWQgb2YgdGhlIG5vZGUuCi0gICAqLwotICBwdWJsaWMgaW50IGdldEV4cGFuZGVkVHlwZUlEKGludCB0eXBlKQotICB7Ci0gICAgcmV0dXJuIHR5cGU7Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYW4gZXhwYW5kZWQtbmFtZSBJRCwgcmV0dXJuIHRoZSBsb2NhbCBuYW1lIHBhcnQuCi0gICAqCi0gICAqIEBwYXJhbSBFeHBhbmRlZE5hbWVJRCBhbiBJRCB0aGF0IHJlcHJlc2VudHMgYW4gZXhwYW5kZWQtbmFtZS4KLSAgICogQHJldHVybiBTdHJpbmcgTG9jYWwgbmFtZSBvZiB0aGlzIG5vZGUsIG9yIG51bGwgaWYgdGhlIG5vZGUgaGFzIG5vIG5hbWUuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldExvY2FsTmFtZShpbnQgRXhwYW5kZWROYW1lSUQpCi0gIHsKLSAgICByZXR1cm4gbV9leHRlbmRlZFR5cGVzW0V4cGFuZGVkTmFtZUlEXS5nZXRMb2NhbE5hbWUoKTsKLSAgfQotCi0gIC8qKgotICAgKiBHaXZlbiBhbiBleHBhbmRlZC1uYW1lIElELCByZXR1cm4gdGhlIGxvY2FsIG5hbWUgSUQuCi0gICAqCi0gICAqIEBwYXJhbSBFeHBhbmRlZE5hbWVJRCBhbiBJRCB0aGF0IHJlcHJlc2VudHMgYW4gZXhwYW5kZWQtbmFtZS4KLSAgICogQHJldHVybiBUaGUgaWQgb2YgdGhpcyBsb2NhbCBuYW1lLgotICAgKi8KLSAgcHVibGljIGZpbmFsIGludCBnZXRMb2NhbE5hbWVJRChpbnQgRXhwYW5kZWROYW1lSUQpCi0gIHsKLSAgICAvLyBFeHRlbmRlZFR5cGUgZXR5cGUgPSBtX2V4dGVuZGVkVHlwZXNbRXhwYW5kZWROYW1lSURdOwotICAgIGlmIChtX2V4dGVuZGVkVHlwZXNbRXhwYW5kZWROYW1lSURdLmdldExvY2FsTmFtZSgpLmVxdWFscygiIikpCi0gICAgICByZXR1cm4gMDsKLSAgICBlbHNlCi0gICAgcmV0dXJuIEV4cGFuZGVkTmFtZUlEOwotICB9Ci0KLQotICAvKioKLSAgICogR2l2ZW4gYW4gZXhwYW5kZWQtbmFtZSBJRCwgcmV0dXJuIHRoZSBuYW1lc3BhY2UgVVJJIHBhcnQuCi0gICAqCi0gICAqIEBwYXJhbSBFeHBhbmRlZE5hbWVJRCBhbiBJRCB0aGF0IHJlcHJlc2VudHMgYW4gZXhwYW5kZWQtbmFtZS4KLSAgICogQHJldHVybiBTdHJpbmcgVVJJIHZhbHVlIG9mIHRoaXMgbm9kZSdzIG5hbWVzcGFjZSwgb3IgbnVsbCBpZiBubwotICAgKiBuYW1lc3BhY2Ugd2FzIHJlc29sdmVkLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXROYW1lc3BhY2UoaW50IEV4cGFuZGVkTmFtZUlEKQotICB7Ci0gICAgU3RyaW5nIG5hbWVzcGFjZSA9IG1fZXh0ZW5kZWRUeXBlc1tFeHBhbmRlZE5hbWVJRF0uZ2V0TmFtZXNwYWNlKCk7Ci0gICAgcmV0dXJuIChuYW1lc3BhY2UuZXF1YWxzKCIiKSA/IG51bGwgOiBuYW1lc3BhY2UpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGFuIGV4cGFuZGVkLW5hbWUgSUQsIHJldHVybiB0aGUgbmFtZXNwYWNlIFVSSSBJRC4KLSAgICoKLSAgICogQHBhcmFtIEV4cGFuZGVkTmFtZUlEIGFuIElEIHRoYXQgcmVwcmVzZW50cyBhbiBleHBhbmRlZC1uYW1lLgotICAgKiBAcmV0dXJuIFRoZSBpZCBvZiB0aGlzIG5hbWVzcGFjZS4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBpbnQgZ2V0TmFtZXNwYWNlSUQoaW50IEV4cGFuZGVkTmFtZUlEKQotICB7Ci0gICAgLy9FeHRlbmRlZFR5cGUgZXR5cGUgPSBtX2V4dGVuZGVkVHlwZXNbRXhwYW5kZWROYW1lSURdOwotICAgIGlmIChtX2V4dGVuZGVkVHlwZXNbRXhwYW5kZWROYW1lSURdLmdldE5hbWVzcGFjZSgpLmVxdWFscygiIikpCi0gICAgICByZXR1cm4gMDsKLSAgICBlbHNlCi0gICAgcmV0dXJuIEV4cGFuZGVkTmFtZUlEOwotICB9Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGFuIGV4cGFuZGVkLW5hbWUgSUQsIHJldHVybiB0aGUgbG9jYWwgbmFtZSBJRC4KLSAgICoKLSAgICogQHBhcmFtIEV4cGFuZGVkTmFtZUlEIGFuIElEIHRoYXQgcmVwcmVzZW50cyBhbiBleHBhbmRlZC1uYW1lLgotICAgKiBAcmV0dXJuIFRoZSBpZCBvZiB0aGlzIGxvY2FsIG5hbWUuCi0gICAqLwotICBwdWJsaWMgZmluYWwgc2hvcnQgZ2V0VHlwZShpbnQgRXhwYW5kZWROYW1lSUQpCi0gIHsKLSAgICAvL0V4dGVuZGVkVHlwZSBldHlwZSA9IG1fZXh0ZW5kZWRUeXBlc1tFeHBhbmRlZE5hbWVJRF07Ci0gICAgcmV0dXJuIChzaG9ydCltX2V4dGVuZGVkVHlwZXNbRXhwYW5kZWROYW1lSURdLmdldE5vZGVUeXBlKCk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBzaXplIG9mIHRoZSBFeHBhbmRlZE5hbWVUYWJsZQotICAgKgotICAgKiBAcmV0dXJuIFRoZSBzaXplIG9mIHRoZSBFeHBhbmRlZE5hbWVUYWJsZQotICAgKi8KLSAgcHVibGljIGludCBnZXRTaXplKCkKLSAgewotICAgIHJldHVybiBtX25leHRUeXBlOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgYXJyYXkgb2YgZXh0ZW5kZWQgdHlwZXMKLSAgICoKLSAgICogQHJldHVybiBUaGUgYXJyYXkgb2YgZXh0ZW5kZWQgdHlwZXMKLSAgICovCi0gIHB1YmxpYyBFeHRlbmRlZFR5cGVbXSBnZXRFeHRlbmRlZFR5cGVzKCkKLSAgewotICAgIHJldHVybiBtX2V4dGVuZGVkVHlwZXM7Ci0gIH0KLQotICAvKioKLSAgICogSW5uZXIgY2xhc3Mgd2hpY2ggcmVwcmVzZW50cyBhIGhhc2ggdGFibGUgZW50cnkuCi0gICAqIFRoZSBmaWVsZCBuZXh0IHBvaW50cyB0byB0aGUgbmV4dCBlbnRyeSB3aGljaCBpcyBoYXNoZWQgaW50bwotICAgKiB0aGUgc2FtZSBidWNrZXQgaW4gdGhlIGNhc2Ugb2YgImhhc2ggY29sbGlzaW9uIi4KLSAgICovCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEhhc2hFbnRyeQotICB7Ci0gICAgRXh0ZW5kZWRUeXBlIGtleTsKLSAgICBpbnQgdmFsdWU7Ci0gICAgaW50IGhhc2g7Ci0gICAgSGFzaEVudHJ5IG5leHQ7Ci0KLSAgICBwcm90ZWN0ZWQgSGFzaEVudHJ5KEV4dGVuZGVkVHlwZSBrZXksIGludCB2YWx1ZSwgaW50IGhhc2gsIEhhc2hFbnRyeSBuZXh0KQotICAgIHsKLSAgICAgIHRoaXMua2V5ID0ga2V5OwotICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOwotICAgICAgdGhpcy5oYXNoID0gaGFzaDsKLSAgICAgIHRoaXMubmV4dCA9IG5leHQ7Ci0gICAgfQotICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9yZWYvRXh0ZW5kZWRUeXBlLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vcmVmL0V4dGVuZGVkVHlwZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2ODI5ODZjLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9yZWYvRXh0ZW5kZWRUeXBlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNDcgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRXh0ZW5kZWRUeXBlLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTUgMDg6MTU6MDYgc3VyZXNoX2VtYWlsaWQgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5yZWY7Ci0KLS8qKgotICogVGhlIGNsYXNzIEV4dGVuZGVkVHlwZSByZXByZXNlbnRzIGFuIGV4dGVuZGVkIHR5cGUgb2JqZWN0IHVzZWQgYnkKLSAqIEV4cGFuZGVkTmFtZVRhYmxlLgotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgRXh0ZW5kZWRUeXBlCi17Ci0gICAgcHJpdmF0ZSBpbnQgbm9kZXR5cGU7Ci0gICAgcHJpdmF0ZSBTdHJpbmcgbmFtZXNwYWNlOwotICAgIHByaXZhdGUgU3RyaW5nIGxvY2FsTmFtZTsKLSAgICBwcml2YXRlIGludCBoYXNoOwotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlIGFuIEV4dGVuZGVkVHlwZSBvYmplY3QgZnJvbSBub2RlIHR5cGUsIG5hbWVzcGFjZSBhbmQgbG9jYWwgbmFtZS4KLSAgICAgKiBUaGUgaGFzaCBjb2RlIGlzIGNhbGN1bGF0ZWQgZnJvbSB0aGUgbm9kZSB0eXBlLCBuYW1lc3BhY2UgYW5kIGxvY2FsIG5hbWUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbm9kZXR5cGUgVHlwZSBvZiB0aGUgbm9kZQotICAgICAqIEBwYXJhbSBuYW1lc3BhY2UgTmFtZXNwYWNlIG9mIHRoZSBub2RlCi0gICAgICogQHBhcmFtIGxvY2FsTmFtZSBMb2NhbCBuYW1lIG9mIHRoZSBub2RlCi0gICAgICovCi0gICAgcHVibGljIEV4dGVuZGVkVHlwZSAoaW50IG5vZGV0eXBlLCBTdHJpbmcgbmFtZXNwYWNlLCBTdHJpbmcgbG9jYWxOYW1lKQotICAgIHsKLSAgICAgIHRoaXMubm9kZXR5cGUgPSBub2RldHlwZTsKLSAgICAgIHRoaXMubmFtZXNwYWNlID0gbmFtZXNwYWNlOwotICAgICAgdGhpcy5sb2NhbE5hbWUgPSBsb2NhbE5hbWU7Ci0gICAgICB0aGlzLmhhc2ggPSBub2RldHlwZSArIG5hbWVzcGFjZS5oYXNoQ29kZSgpICsgbG9jYWxOYW1lLmhhc2hDb2RlKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlIGFuIEV4dGVuZGVkVHlwZSBvYmplY3QgZnJvbSBub2RlIHR5cGUsIG5hbWVzcGFjZSwgbG9jYWwgbmFtZQotICAgICAqIGFuZCBhIGdpdmVuIGhhc2ggY29kZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBub2RldHlwZSBUeXBlIG9mIHRoZSBub2RlCi0gICAgICogQHBhcmFtIG5hbWVzcGFjZSBOYW1lc3BhY2Ugb2YgdGhlIG5vZGUKLSAgICAgKiBAcGFyYW0gbG9jYWxOYW1lIExvY2FsIG5hbWUgb2YgdGhlIG5vZGUKLSAgICAgKiBAcGFyYW0gaGFzaCBUaGUgZ2l2ZW4gaGFzaCBjb2RlCi0gICAgICovCi0gICAgcHVibGljIEV4dGVuZGVkVHlwZSAoaW50IG5vZGV0eXBlLCBTdHJpbmcgbmFtZXNwYWNlLCBTdHJpbmcgbG9jYWxOYW1lLCBpbnQgaGFzaCkKLSAgICB7Ci0gICAgICB0aGlzLm5vZGV0eXBlID0gbm9kZXR5cGU7Ci0gICAgICB0aGlzLm5hbWVzcGFjZSA9IG5hbWVzcGFjZTsKLSAgICAgIHRoaXMubG9jYWxOYW1lID0gbG9jYWxOYW1lOwotICAgICAgdGhpcy5oYXNoID0gaGFzaDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZWRlZmluZSB0aGlzIEV4dGVuZGVkVHlwZSBvYmplY3QgdG8gcmVwcmVzZW50IGEgZGlmZmVyZW50IGV4dGVuZGVkIHR5cGUuCi0gICAgICogVGhpcyBpcyBpbnRlbmRlZCB0byBiZSB1c2VkIE9OTFkgb24gdGhlIGhhc2hFVCBvYmplY3QuIFVzaW5nIGl0IGVsc2V3aGVyZQotICAgICAqIHdpbGwgbWVzcyB1cCBleGlzdGluZyBoYXNodGFibGUgZW50cmllcyEKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCByZWRlZmluZShpbnQgbm9kZXR5cGUsIFN0cmluZyBuYW1lc3BhY2UsIFN0cmluZyBsb2NhbE5hbWUpCi0gICAgewotICAgICAgdGhpcy5ub2RldHlwZSA9IG5vZGV0eXBlOwotICAgICAgdGhpcy5uYW1lc3BhY2UgPSBuYW1lc3BhY2U7Ci0gICAgICB0aGlzLmxvY2FsTmFtZSA9IGxvY2FsTmFtZTsKLSAgICAgIHRoaXMuaGFzaCA9IG5vZGV0eXBlICsgbmFtZXNwYWNlLmhhc2hDb2RlKCkgKyBsb2NhbE5hbWUuaGFzaENvZGUoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZWRlZmluZSB0aGlzIEV4dGVuZGVkVHlwZSBvYmplY3QgdG8gcmVwcmVzZW50IGEgZGlmZmVyZW50IGV4dGVuZGVkIHR5cGUuCi0gICAgICogVGhpcyBpcyBpbnRlbmRlZCB0byBiZSB1c2VkIE9OTFkgb24gdGhlIGhhc2hFVCBvYmplY3QuIFVzaW5nIGl0IGVsc2V3aGVyZQotICAgICAqIHdpbGwgbWVzcyB1cCBleGlzdGluZyBoYXNodGFibGUgZW50cmllcyEKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCByZWRlZmluZShpbnQgbm9kZXR5cGUsIFN0cmluZyBuYW1lc3BhY2UsIFN0cmluZyBsb2NhbE5hbWUsIGludCBoYXNoKQotICAgIHsKLSAgICAgIHRoaXMubm9kZXR5cGUgPSBub2RldHlwZTsKLSAgICAgIHRoaXMubmFtZXNwYWNlID0gbmFtZXNwYWNlOwotICAgICAgdGhpcy5sb2NhbE5hbWUgPSBsb2NhbE5hbWU7Ci0gICAgICB0aGlzLmhhc2ggPSBoYXNoOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIE92ZXJyaWRlIHRoZSBoYXNoQ29kZSgpIG1ldGhvZCBpbiB0aGUgT2JqZWN0IGNsYXNzCi0gICAgICovCi0gICAgcHVibGljIGludCBoYXNoQ29kZSgpCi0gICAgewotICAgICAgcmV0dXJuIGhhc2g7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGVzdCBpZiB0aGlzIEV4dGVuZGVkVHlwZSBvYmplY3QgaXMgZXF1YWwgdG8gdGhlIGdpdmVuIEV4dGVuZGVkVHlwZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBvdGhlciBUaGUgb3RoZXIgRXh0ZW5kZWRUeXBlIG9iamVjdCB0byB0ZXN0IGZvciBlcXVhbGl0eQotICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgdHdvIEV4dGVuZGVkVHlwZSBvYmplY3RzIGFyZSBlcXVhbC4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoRXh0ZW5kZWRUeXBlIG90aGVyKQotICAgIHsKLSAgICAgIHRyeQotICAgICAgewotICAgICAgICByZXR1cm4gb3RoZXIubm9kZXR5cGUgPT0gdGhpcy5ub2RldHlwZSAmJgotICAgICAgICAgICAgICAgIG90aGVyLmxvY2FsTmFtZS5lcXVhbHModGhpcy5sb2NhbE5hbWUpICYmCi0gICAgICAgICAgICAgICAgb3RoZXIubmFtZXNwYWNlLmVxdWFscyh0aGlzLm5hbWVzcGFjZSk7Ci0gICAgICB9Ci0gICAgICBjYXRjaChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKQotICAgICAgewotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSBub2RlIHR5cGUKLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldE5vZGVUeXBlKCkKLSAgICB7Ci0gICAgICByZXR1cm4gbm9kZXR5cGU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSBsb2NhbCBuYW1lCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRMb2NhbE5hbWUoKQotICAgIHsKLSAgICAgIHJldHVybiBsb2NhbE5hbWU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSBuYW1lc3BhY2UKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWVzcGFjZSgpCi0gICAgewotICAgICAgcmV0dXJuIG5hbWVzcGFjZTsKLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9yZWYvSW5jcmVtZW50YWxTQVhTb3VyY2UuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9yZWYvSW5jcmVtZW50YWxTQVhTb3VyY2UuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNDE3NDU0Zi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vcmVmL0luY3JlbWVudGFsU0FYU291cmNlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5MSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBJbmNyZW1lbnRhbFNBWFNvdXJjZS5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE1IDA4OjE1OjA2IHN1cmVzaF9lbWFpbGlkIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5yZWY7Ci0KLWltcG9ydCBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci0KLS8qKiA8cD5JbmNyZW1lbnRhbFNBWFNvdXJjZSBpcyBhbiBBUEkgdGhhdCBkZWxpdmVycyBhIHNtYWxsIG51bWJlciBvZgotICogU0FYIGV2ZW50cyBlYWNoIHRpbWUgYSByZXF1ZXN0IGlzIG1hZGUgZnJvbSBhICJjb250cm9sbGVyIgotICogY29yb3V0aW5lLiAgU2VlIEluY3JlbWVudGFsU0FYRmlsdGVyIGFuZCBJbmNyZW1lbnRhbFNBWEZpbHRlcl9YZXJjZXMKLSAqIGZvciBleGFtcGxlcy4KLSAqCi0gKiBOb3RlIHRoYXQgaW50ZXJhY3Rpb24gaXMgdmlhIHRoZSBkZWxpdmVyTW9yZU5vZGVzCi0gKiBtZXRob2QsIGFuZCB0aGVyZWZvcmUgY29yb3V0aW5lIHN1cHBvcnQgaXMgbm90IGV4cG9zZWQKLSAqIGhlcmUuPC9wPgotICogKi8KLXB1YmxpYyBpbnRlcmZhY2UgSW5jcmVtZW50YWxTQVhTb3VyY2UKLXsKLSAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gIC8vIFNBWCBPdXRwdXQgQVBJCi0gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotCi0gIC8qKiBSZWdpc3RlciBhIFNBWC1zdHlsZSBjb250ZW50IGhhbmRsZXIgZm9yIHVzIHRvIG91dHB1dCB0bwotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0Q29udGVudEhhbmRsZXIoQ29udGVudEhhbmRsZXIgaGFuZGxlcik7Ci0KLSAgLyoqICBSZWdpc3RlciBhIFNBWC1zdHlsZSBsZXhpY2FsIGhhbmRsZXIgZm9yIHVzIHRvIG91dHB1dCB0bwotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0TGV4aWNhbEhhbmRsZXIob3JnLnhtbC5zYXguZXh0LkxleGljYWxIYW5kbGVyIGhhbmRsZXIpOwotCi0gIC8qKiAgUmVnaXN0ZXIgYSBTQVgtc3R5bGUgRFREIGhhbmRsZXIgZm9yIHVzIHRvIG91dHB1dCB0bwotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0RFRESGFuZGxlcihvcmcueG1sLnNheC5EVERIYW5kbGVyIGhhbmRsZXIpOwotCi0gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAvLyBDb21tYW5kIElucHV0IEFQSQotICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLQotICAvKiogZGVsaXZlck1vcmVOb2RlcygpIGlzIGEgc2ltcGxlIEFQSSB3aGljaCB0ZWxscyB0aGUgdGhyZWFkIGluIHdoaWNoIHRoZQotICAgKiBJbmNyZW1lbnRhbFNBWFNvdXJjZSBpcyBydW5uaW5nIHRvIGRlbGl2ZXIgbW9yZSBldmVudHMgKHRydWUpLAotICAgKiBvciBzdG9wIGRlbGl2ZXJpbmcgZXZlbnRzIGFuZCBjbG9zZSBvdXQgaXRzIGlucHV0IChmYWxzZSkuCi0gICAqCi0gICAqIFRoaXMgaXMgaW50ZW5kZWQgdG8gYmUgY2FsbGVkIGZyb20gb25lIG9mIG91ciBwYXJ0bmVyIGNvcm91dGluZXMsCi0gICAqIGFuZCBzZXJ2ZXMgdG8gZW5jYXBzdWxhdGUgdGhlIGNvcm91dGluZSBjb21tdW5pY2F0aW9uIHByb3RvY29sLgotICAgKgotICAgKiBAcGFyYW0gcGFyc2Vtb3JlIElmIHRydWUsIHRlbGxzIHRoZSBpbmNyZW1lbnRhbCBTQVggc3RyZWFtIHRvIGRlbGl2ZXIKLSAgICogYW5vdGhlciBjaHVuayBvZiBldmVudHMuIElmIGZhbHNlLCBmaW5pc2hlcyBvdXQgdGhlIHN0cmVhbS4KLSAgICoKLSAgICogQHJldHVybiBCb29sZWFuLlRSVUUgaWYgdGhlIEluY3JlbWVudGFsU0FYU291cmNlIGJlbGlldmVzIG1vcmUgZGF0YQotICAgKiBtYXkgYmUgYXZhaWxhYmxlIGZvciBmdXJ0aGVyIHBhcnNpbmcuIEJvb2xlYW4uRkFMU0UgaWYgcGFyc2luZwotICAgKiByYW4gdG8gY29tcGxldGlvbiwgb3Igd2FzIGVuZGVkIGJ5IGRlbGl2ZXJNb3JlTm9kZXMoZmFsc2UpLgotICAgKiAqLwotICBwdWJsaWMgT2JqZWN0IGRlbGl2ZXJNb3JlTm9kZXMgKGJvb2xlYW4gcGFyc2Vtb3JlKTsKLQotICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgLy8gUGFyc2UgVGhyZWFkIENvbnZlbmllbmNlIEFQSQotICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLQotICAvKiogTGF1bmNoIGFuIFhNTFJlYWRlcidzIHBhcnNpbmcgb3BlcmF0aW9uLCBmZWVkaW5nIGV2ZW50cyB0byB0aGlzCi0gICAqIEluY3JlbWVudGFsU0FYU291cmNlLiBJbiBzb21lIGltcGxlbWVudGF0aW9ucywgdGhpcyBtYXkgbGF1bmNoIGEKLSAgICogdGhyZWFkIHdoaWNoIHJ1bnMgdGhlIHByZXZpb3VzbHkgc3VwcGxpZWQgWE1MUmVhZGVyJ3MgcGFyc2UoKSBvcGVyYXRpb24uCi0gICAqIEluIG90aGVycywgaXQgbWF5IGRvIG90aGVyIGZvcm1zIG9mIGluaXRpYWxpemF0aW9uLgotICAgKgotICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBpcyBwYXJzZSB0aHJlYWQgaXMgYWxyZWFkeSBpbiBwcm9ncmVzcwotICAgKiBvciBwYXJzaW5nIGNhbiBub3QgYmUgc3RhcnRlZC4KLSAgICogKi8KLSAgcHVibGljIHZvaWQgc3RhcnRQYXJzZShJbnB1dFNvdXJjZSBzb3VyY2UpIHRocm93cyBTQVhFeGNlcHRpb247Ci0KLX0gLy8gY2xhc3MgSW5jcmVtZW50YWxTQVhTb3VyY2UKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9yZWYvSW5jcmVtZW50YWxTQVhTb3VyY2VfRmlsdGVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vcmVmL0luY3JlbWVudGFsU0FYU291cmNlX0ZpbHRlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyZDk3NDUxLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9yZWYvSW5jcmVtZW50YWxTQVhTb3VyY2VfRmlsdGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4MTMgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogSW5jcmVtZW50YWxTQVhTb3VyY2VfRmlsdGVyLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTUgMDg6MTU6MDcgc3VyZXNoX2VtYWlsaWQgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLnJlZjsKLQotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnJlcy5YTUxFcnJvclJlc291cmNlczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnJlcy5YTUxNZXNzYWdlczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLlRocmVhZENvbnRyb2xsZXJXcmFwcGVyOwotCi1pbXBvcnQgb3JnLnhtbC5zYXguQXR0cmlidXRlczsKLWltcG9ydCBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5EVERIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LkVycm9ySGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKLWltcG9ydCBvcmcueG1sLnNheC5Mb2NhdG9yOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhQYXJzZUV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5YTUxSZWFkZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguZXh0LkxleGljYWxIYW5kbGVyOwotCi0vKiogPHA+SW5jcmVtZW50YWxTQVhTb3VyY2VfRmlsdGVyIGltcGxlbWVudHMgSW5jcmVtZW50YWxTQVhTb3VyY2UsIHVzaW5nIGEKLSAqIHN0YW5kYXJkIFNBWDIgZXZlbnQgc291cmNlIGFzIGl0cyBpbnB1dCBhbmQgcGFyY2VsbGluZyBvdXQgdGhvc2UKLSAqIGV2ZW50cyBncmFkdWFsbHkgaW4gcmVwb25zZSB0byBkZWxpdmVyTW9yZU5vZGVzKCkgcmVxdWVzdHMuICBPdXRwdXQgZnJvbSB0aGUKLSAqIGZpbHRlciB3aWxsIGJlIHBhc3NlZCBhbG9uZyB0byBhIFNBWCBoYW5kbGVyIHJlZ2lzdGVyZWQgYXMgb3VyCi0gKiBsaXN0ZW5lciwgYnV0IHRob3NlIGNhbGxiYWNrcyB3aWxsIHBhc3MgdGhyb3VnaCBhIGNvdW50aW5nIHN0YWdlCi0gKiB3aGljaCBwZXJpb2RpY2FsbHkgeWllbGRzIGNvbnRyb2wgYmFjayB0byB0aGUgY29udHJvbGxlciBjb3JvdXRpbmUuCi0gKiA8L3A+Ci0gKgotICogPHA+JVJFVklFVyU6IFRoaXMgZmlsdGVyIGlzIG5vdCBjdXJyZW5seSBpbnRlbmRlZCB0byBiZSByZXVzYWJsZQotICogZm9yIHBhcnNpbmcgYWRkaXRpb25hbCBzdHJlYW1zL2RvY3VtZW50cy4gV2UgbWF5IHdhbnQgdG8gY29uc2lkZXIKLSAqIG1ha2luZyBpdCByZXNldHRhYmxlIGF0IHNvbWUgcG9pbnQgaW4gdGhlIGZ1dHVyZS4gQnV0IGl0J3MgYQotICogc21hbGwgb2JqZWN0LCBzbyB0aGF0J2QgYmUgbW9zdGx5IGEgY29udmVuaWVuY2UgaXNzdWU7IHRoZSBjb3N0Ci0gKiBvZiBhbGxvY2F0aW5nIGVhY2ggdGltZSBpcyB0cml2aWFsIGNvbXBhcmVkIHRvIHRoZSBjb3N0IG9mIHByb2Nlc3NpbmcKLSAqIGFueSBub250cml2YWwgc3RyZWFtLjwvcD4KLSAqCi0gKiA8cD5Gb3IgYSBicmllZiB1c2FnZSBleGFtcGxlLCBzZWUgdGhlIHVuaXQtdGVzdCBtYWluKCkgbWV0aG9kLjwvcD4KLSAqCi0gKiA8cD5UaGlzIGlzIGEgc2ltcGxpZmljYXRpb24gb2YgdGhlIG9sZCBDb3JvdXRpbmVTQVhQYXJzZXIsIGZvY3VzaW5nCi0gKiBzcGVjaWZpY2FsbHkgb24gZmlsdGVyaW5nLiBUaGUgcmVzdWx0aW5nIGNvbnRyb2xsZXIgcHJvdG9jb2wgaXMgX2Zhcl8KLSAqIHNpbXBsZXIgYW5kIGxlc3MgZXJyb3ItcHJvbmU7IHRoZSBvbmx5IGNvbnRyb2xsZXIgb3BlcmF0aW9uIGlzIGRlbGl2ZXJNb3JlTm9kZXMoKSwKLSAqIGFuZCB0aGUgb25seSByZXF1aXJlbWVudCBpcyB0aGF0IGRlbGl2ZXJNb3JlTm9kZXMoZmFsc2UpIGJlIGNhbGxlZCBpZiB5b3Ugd2FudCB0bwotICogZGlzY2FyZCB0aGUgcmVzdCBvZiB0aGUgc3RyZWFtIGFuZCB0aGUgcHJldmlvdXMgZGVsaXZlck1vcmVOb2RlcygpIGRpZG4ndCByZXR1cm4KLSAqIGZhbHNlLgotICoKLSAqIFRoaXMgY2xhc3MgaXMgZmluYWwgYW5kIHBhY2thZ2UgcHJpdmF0ZSBmb3Igc2VjdXJpdHkgcmVhc29ucy4gUGxlYXNlCi0gKiBzZWUgQ1IgNjUzNzkxMiBmb3IgZnVydGhlciBkZXRhaWxzLgotICoKLSAqICovCi1maW5hbCBjbGFzcyBJbmNyZW1lbnRhbFNBWFNvdXJjZV9GaWx0ZXIKLWltcGxlbWVudHMgSW5jcmVtZW50YWxTQVhTb3VyY2UsIENvbnRlbnRIYW5kbGVyLCBEVERIYW5kbGVyLCBMZXhpY2FsSGFuZGxlciwgRXJyb3JIYW5kbGVyLCBSdW5uYWJsZQotewotICBib29sZWFuIERFQlVHPWZhbHNlOyAvL0ludGVybmFsIHN0YXR1cyByZXBvcnQKLQotICAvLwotICAvLyBEYXRhCi0gIC8vCi0gIHByaXZhdGUgQ29yb3V0aW5lTWFuYWdlciBmQ29yb3V0aW5lTWFuYWdlciA9IG51bGw7Ci0gIHByaXZhdGUgaW50IGZDb250cm9sbGVyQ29yb3V0aW5lSUQgPSAtMTsKLSAgcHJpdmF0ZSBpbnQgZlNvdXJjZUNvcm91dGluZUlEID0gLTE7Ci0KLSAgcHJpdmF0ZSBDb250ZW50SGFuZGxlciBjbGllbnRDb250ZW50SGFuZGxlcj1udWxsOyAvLyAlUkVWSUVXJSBzdXBwb3J0IG11bHRpcGxlPwotICBwcml2YXRlIExleGljYWxIYW5kbGVyIGNsaWVudExleGljYWxIYW5kbGVyPW51bGw7IC8vICVSRVZJRVclIHN1cHBvcnQgbXVsdGlwbGU/Ci0gIHByaXZhdGUgRFRESGFuZGxlciBjbGllbnREVERIYW5kbGVyPW51bGw7IC8vICVSRVZJRVclIHN1cHBvcnQgbXVsdGlwbGU/Ci0gIHByaXZhdGUgRXJyb3JIYW5kbGVyIGNsaWVudEVycm9ySGFuZGxlcj1udWxsOyAvLyAlUkVWSUVXJSBzdXBwb3J0IG11bHRpcGxlPwotICBwcml2YXRlIGludCBldmVudGNvdW50ZXI7Ci0gIHByaXZhdGUgaW50IGZyZXF1ZW5jeT01OwotCi0gIC8vIEZsYWcgaW5kaWNhdGluZyB0aGF0IG5vIG1vcmUgZXZlbnRzIHNob3VsZCBiZSBkZWxpdmVyZWQgLS0gZWl0aGVyCi0gIC8vIGJlY2F1c2UgaW5wdXQgc3RyZWFtIHJhbiB0byBjb21wbGV0aW9uIChlbmREb2N1bWVudCksIG9yIGJlY2F1c2UKLSAgLy8gdGhlIHVzZXIgcmVxdWVzdGVkIGFuIGVhcmx5IHN0b3AgdmlhIGRlbGl2ZXJNb3JlTm9kZXMoZmFsc2UpLgotICBwcml2YXRlIGJvb2xlYW4gZk5vTW9yZUV2ZW50cz1mYWxzZTsKLQotICAvLyBTdXBwb3J0IGZvciBzdGFydFBhcnNlKCkKLSAgcHJpdmF0ZSBYTUxSZWFkZXIgZlhNTFJlYWRlcj1udWxsOwotICBwcml2YXRlIElucHV0U291cmNlIGZYTUxSZWFkZXJJbnB1dFNvdXJjZT1udWxsOwotCi0gIC8vCi0gIC8vIENvbnN0cnVjdG9ycwotICAvLwotCi0gIHB1YmxpYyBJbmNyZW1lbnRhbFNBWFNvdXJjZV9GaWx0ZXIoKSB7Ci0gICAgdGhpcy5pbml0KCBuZXcgQ29yb3V0aW5lTWFuYWdlcigpLCAtMSwgLTEpOwotICB9Ci0KLSAgLyoqIENyZWF0ZSBhIEluY3JlbWVudGFsU0FYU291cmNlX0ZpbHRlciB3aGljaCBpcyBub3QgeWV0IGJvdW5kIHRvIGEgc3BlY2lmaWMKLSAgICogU0FYIGV2ZW50IHNvdXJjZS4KLSAgICogKi8KLSAgcHVibGljIEluY3JlbWVudGFsU0FYU291cmNlX0ZpbHRlcihDb3JvdXRpbmVNYW5hZ2VyIGNvLCBpbnQgY29udHJvbGxlckNvcm91dGluZUlEKQotICB7Ci0gICAgdGhpcy5pbml0KCBjbywgY29udHJvbGxlckNvcm91dGluZUlELCAtMSApOwotICB9Ci0KLSAgLy8KLSAgLy8gRmFjdG9yaWVzCi0gIC8vCi0gIHN0YXRpYyBwdWJsaWMgSW5jcmVtZW50YWxTQVhTb3VyY2UgY3JlYXRlSW5jcmVtZW50YWxTQVhTb3VyY2UoQ29yb3V0aW5lTWFuYWdlciBjbywgaW50IGNvbnRyb2xsZXJDb3JvdXRpbmVJRCkgewotICAgIHJldHVybiBuZXcgSW5jcmVtZW50YWxTQVhTb3VyY2VfRmlsdGVyKGNvLCBjb250cm9sbGVyQ29yb3V0aW5lSUQpOwotICB9Ci0KLSAgLy8KLSAgLy8gUHVibGljIG1ldGhvZHMKLSAgLy8KLQotICBwdWJsaWMgdm9pZCBpbml0KCBDb3JvdXRpbmVNYW5hZ2VyIGNvLCBpbnQgY29udHJvbGxlckNvcm91dGluZUlELAotICAgICAgICAgICAgICAgICAgICBpbnQgc291cmNlQ29yb3V0aW5lSUQpCi0gIHsKLSAgICBpZihjbz09bnVsbCkKLSAgICAgIGNvID0gbmV3IENvcm91dGluZU1hbmFnZXIoKTsKLSAgICBmQ29yb3V0aW5lTWFuYWdlciA9IGNvOwotICAgIGZDb250cm9sbGVyQ29yb3V0aW5lSUQgPSBjby5jb19qb2luQ29yb3V0aW5lU2V0KGNvbnRyb2xsZXJDb3JvdXRpbmVJRCk7Ci0gICAgZlNvdXJjZUNvcm91dGluZUlEID0gY28uY29fam9pbkNvcm91dGluZVNldChzb3VyY2VDb3JvdXRpbmVJRCk7Ci0gICAgaWYgKGZDb250cm9sbGVyQ29yb3V0aW5lSUQgPT0gLTEgfHwgZlNvdXJjZUNvcm91dGluZUlEID09IC0xKQotICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oWE1MTWVzc2FnZXMuY3JlYXRlWE1MTWVzc2FnZShYTUxFcnJvclJlc291cmNlcy5FUl9DT0pPSU5ST1VUSU5FU0VUX0ZBSUxFRCwgbnVsbCkpOyAvLyJjb19qb2luQ29yb3V0aW5lU2V0KCkgZmFpbGVkIik7Ci0KLSAgICBmTm9Nb3JlRXZlbnRzPWZhbHNlOwotICAgIGV2ZW50Y291bnRlcj1mcmVxdWVuY3k7Ci0gIH0KLQotICAvKiogQmluZCBvdXIgaW5wdXQgc3RyZWFtcyB0byBhbiBYTUxSZWFkZXIuCi0gICAqCi0gICAqIEp1c3QgYSBjb252ZW5pZW5jZSByb3V0aW5lOyBvYnZpb3VzbHkgeW91IGNhbiBleHBsaWNpdGx5IHJlZ2lzdGVyCi0gICAqIHRoaXMgYXMgYSBsaXN0ZW5lciB3aXRoIHRoZSBzYW1lIGVmZmVjdC4KLSAgICogKi8KLSAgcHVibGljIHZvaWQgc2V0WE1MUmVhZGVyKFhNTFJlYWRlciBldmVudHNvdXJjZSkKLSAgewotICAgIGZYTUxSZWFkZXI9ZXZlbnRzb3VyY2U7Ci0gICAgZXZlbnRzb3VyY2Uuc2V0Q29udGVudEhhbmRsZXIodGhpcyk7Ci0gICAgZXZlbnRzb3VyY2Uuc2V0RFRESGFuZGxlcih0aGlzKTsKLSAgICBldmVudHNvdXJjZS5zZXRFcnJvckhhbmRsZXIodGhpcyk7IC8vIHRvIHJlcG9ydCBmYXRhbCBlcnJvcnMgaW4gZmlsdGVyaW5nIG1vZGUKLQotICAgIC8vIE5vdCBzdXBwb3J0ZWQgYnkgYWxsIFNBWDIgZmlsdGVyczoKLSAgICB0cnkKLSAgICB7Ci0gICAgICBldmVudHNvdXJjZS4KLSAgICAgICAgc2V0UHJvcGVydHkoImh0dHA6Ly94bWwub3JnL3NheC9wcm9wZXJ0aWVzL2xleGljYWwtaGFuZGxlciIsCi0gICAgICAgICAgICAgICAgICAgIHRoaXMpOwotICAgIH0KLSAgICBjYXRjaChTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIGUpCi0gICAgewotICAgICAgLy8gTm90aGluZyB3ZSBjYW4gZG8gYWJvdXQgaXQKLSAgICB9Ci0gICAgY2F0Y2goU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIGUpCi0gICAgewotICAgICAgLy8gTm90aGluZyB3ZSBjYW4gZG8gYWJvdXQgaXQKLSAgICB9Ci0KLSAgICAvLyBTaG91bGQgd2UgYWxzbyBiaW5kIGFzIG90aGVyIHZhcmlldGllcyBvZiBoYW5kbGVyPwotICAgIC8vIChEVERIYW5kbGVyIGFuZCBzbyBvbikKLSAgfQotCi0gIC8vIFJlZ2lzdGVyIGEgY29udGVudCBoYW5kbGVyIGZvciB1cyB0byBvdXRwdXQgdG8KLSAgcHVibGljIHZvaWQgc2V0Q29udGVudEhhbmRsZXIoQ29udGVudEhhbmRsZXIgaGFuZGxlcikKLSAgewotICAgIGNsaWVudENvbnRlbnRIYW5kbGVyPWhhbmRsZXI7Ci0gIH0KLSAgLy8gUmVnaXN0ZXIgYSBEVEQgaGFuZGxlciBmb3IgdXMgdG8gb3V0cHV0IHRvCi0gIHB1YmxpYyB2b2lkIHNldERUREhhbmRsZXIoRFRESGFuZGxlciBoYW5kbGVyKQotICB7Ci0gICAgY2xpZW50RFRESGFuZGxlcj1oYW5kbGVyOwotICB9Ci0gIC8vIFJlZ2lzdGVyIGEgbGV4aWNhbCBoYW5kbGVyIGZvciB1cyB0byBvdXRwdXQgdG8KLSAgLy8gTm90IGFsbCBmaWx0ZXJzIHN1cHBvcnQgdGhpcy4uLgotICAvLyA/Pz8gU2hvdWxkIHdlIHJlZ2lzdGVyIGRpcmVjdGx5IG9uIHRoZSBmaWx0ZXI/Ci0gIC8vIE5PVEUgTkFNRSAtLSBzdWJjbGFzc2luZyBpc3N1ZSBpbiB0aGUgWGVyY2VzIHZlcnNpb24KLSAgcHVibGljIHZvaWQgc2V0TGV4aWNhbEhhbmRsZXIoTGV4aWNhbEhhbmRsZXIgaGFuZGxlcikKLSAgewotICAgIGNsaWVudExleGljYWxIYW5kbGVyPWhhbmRsZXI7Ci0gIH0KLSAgLy8gUmVnaXN0ZXIgYW4gZXJyb3IgaGFuZGxlciBmb3IgdXMgdG8gb3V0cHV0IHRvCi0gIC8vIE5PVEUgTkFNRSAtLSBzdWJjbGFzc2luZyBpc3N1ZSBpbiB0aGUgWGVyY2VzIHZlcnNpb24KLSAgcHVibGljIHZvaWQgc2V0RXJySGFuZGxlcihFcnJvckhhbmRsZXIgaGFuZGxlcikKLSAgewotICAgIGNsaWVudEVycm9ySGFuZGxlcj1oYW5kbGVyOwotICB9Ci0KLSAgLy8gU2V0IHRoZSBudW1iZXIgb2YgZXZlbnRzIGJldHdlZW4gcmVzdW1lcyBvZiBvdXIgY29yb3V0aW5lCi0gIC8vIEltbWVkaWF0ZWx5IHJlc2V0cyBudW1iZXIgb2YgZXZlbnRzIGJlZm9yZSBfbmV4dF8gcmVzdW1lIGFzIHdlbGwuCi0gIHB1YmxpYyB2b2lkIHNldFJldHVybkZyZXF1ZW5jeShpbnQgZXZlbnRzKQotICB7Ci0gICAgaWYoZXZlbnRzPDEpIGV2ZW50cz0xOwotICAgIGZyZXF1ZW5jeT1ldmVudGNvdW50ZXI9ZXZlbnRzOwotICB9Ci0KLSAgLy8KLSAgLy8gQ29udGVudEhhbmRsZXIgbWV0aG9kcwotICAvLyBUaGVzZSAgcGFzcyB0aGUgZGF0YSB0byBvdXIgY2xpZW50IENvbnRlbnRIYW5kbGVyLi4uCi0gIC8vIGJ1dCB0aGV5IGFsc28gY291bnQgdGhlIG51bWJlciBvZiBldmVudHMgcGFzc2luZyB0aHJvdWdoLAotICAvLyBhbmQgcmVzdW1lIG91ciBjb3JvdXRpbmUgZWFjaCB0aW1lIHRoYXQgY291bnRlciBoaXRzIHplcm8gYW5kCi0gIC8vIGlzIHJlc2V0LgotICAvLwotICAvLyBOb3RlIHRoYXQgZm9yIGV2ZXJ5dGhpbmcgZXhjZXB0IGVuZERvY3VtZW50IGFuZCBmYXRhbEVycm9yLCB3ZSBkbyB0aGUgY291bnQtYW5kLXlpZWxkCi0gIC8vIEJFRk9SRSBwYXNzaW5nIHRoZSBjYWxsIGFsb25nLiBJJ20gaG9waW5nIHRoYXQgdGhpcyB3aWxsIGVuY291cmFnZSBKSVQKLSAgLy8gY29tcGlsZXJzIHRvIHJlYWxpemUgdGhhdCB0aGVzZSBhcmUgdGFpbC1jYWxscywgcmVkdWNpbmcgdGhlIGV4cGVuc2Ugb2YKLSAgLy8gdGhlIGFkZGl0aW9uYWwgbGF5ZXIgb2YgZGF0YSBmbG93LgotICAvLwotICAvLyAlUkVWSUVXJSBHbGVubiBzdWdnZXN0cyB0aGF0IHBhdXNpbmcgYWZ0ZXIgZW5kRWxlbWVudCwgZW5kRG9jdW1lbnQsCi0gIC8vIGFuZCBjaGFyYWN0ZXJzIG1heSBiZSBzdWZmaWNpZW50LiBJIGFjdHVhbGx5IG1heSBub3Qgd2FudCB0bwotICAvLyBzdG9wIGFmdGVyIGNoYXJhY3RlcnMsIHNpbmNlIGluIG91ciBhcHBsaWNhdGlvbiB0aGVzZSB3aW5kIHVwIGJlaW5nCi0gIC8vIGNvbmNhdGVuYXRlZCBiZWZvcmUgdGhleSdyZSBwcm9jZXNzZWQuLi4gYnV0IHRoYXQgcmlza3MgaHVnZSBibG9ja3Mgb2YKLSAgLy8gdGV4dCBjYXVzaW5nIGdyZWF0ZXIgdGhhbiB1c3VhbCByZWFkYWhlYWQuIChVbmxpa2VseT8gQ29uc2lkZXIgdGhlCi0gIC8vIHBvc3NpYmlsaXR5IG9mIGEgbGFyZ2UgYmFzZS02NCBibG9jayBpbiBhIFNPQVAgc3RyZWFtLikKLSAgLy8KLSAgcHVibGljIHZvaWQgY2hhcmFjdGVycyhjaGFyW10gY2gsIGludCBzdGFydCwgaW50IGxlbmd0aCkKLSAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBpZigtLWV2ZW50Y291bnRlcjw9MCkKLSAgICAgIHsKLSAgICAgICAgY29feWllbGQodHJ1ZSk7Ci0gICAgICAgIGV2ZW50Y291bnRlcj1mcmVxdWVuY3k7Ci0gICAgICB9Ci0gICAgaWYoY2xpZW50Q29udGVudEhhbmRsZXIhPW51bGwpCi0gICAgICBjbGllbnRDb250ZW50SGFuZGxlci5jaGFyYWN0ZXJzKGNoLHN0YXJ0LGxlbmd0aCk7Ci0gIH0KLSAgcHVibGljIHZvaWQgZW5kRG9jdW1lbnQoKQotICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIC8vIEVYQ0VQVElPTjogSW4gdGhpcyBjYXNlIHdlIG5lZWQgdG8gcnVuIHRoZSBldmVudCBCRUZPUkUgd2UgeWllbGQuCi0gICAgaWYoY2xpZW50Q29udGVudEhhbmRsZXIhPW51bGwpCi0gICAgICBjbGllbnRDb250ZW50SGFuZGxlci5lbmREb2N1bWVudCgpOwotCi0gICAgZXZlbnRjb3VudGVyPTA7Ci0gICAgY29feWllbGQoZmFsc2UpOwotICB9Ci0gIHB1YmxpYyB2b2lkIGVuZEVsZW1lbnQoamF2YS5sYW5nLlN0cmluZyBuYW1lc3BhY2VVUkksIGphdmEubGFuZy5TdHJpbmcgbG9jYWxOYW1lLAotICAgICAgamF2YS5sYW5nLlN0cmluZyBxTmFtZSkKLSAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBpZigtLWV2ZW50Y291bnRlcjw9MCkKLSAgICAgIHsKLSAgICAgICAgY29feWllbGQodHJ1ZSk7Ci0gICAgICAgIGV2ZW50Y291bnRlcj1mcmVxdWVuY3k7Ci0gICAgICB9Ci0gICAgaWYoY2xpZW50Q29udGVudEhhbmRsZXIhPW51bGwpCi0gICAgICBjbGllbnRDb250ZW50SGFuZGxlci5lbmRFbGVtZW50KG5hbWVzcGFjZVVSSSxsb2NhbE5hbWUscU5hbWUpOwotICB9Ci0gIHB1YmxpYyB2b2lkIGVuZFByZWZpeE1hcHBpbmcoamF2YS5sYW5nLlN0cmluZyBwcmVmaXgpCi0gICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgaWYoLS1ldmVudGNvdW50ZXI8PTApCi0gICAgICB7Ci0gICAgICAgIGNvX3lpZWxkKHRydWUpOwotICAgICAgICBldmVudGNvdW50ZXI9ZnJlcXVlbmN5OwotICAgICAgfQotICAgIGlmKGNsaWVudENvbnRlbnRIYW5kbGVyIT1udWxsKQotICAgICAgY2xpZW50Q29udGVudEhhbmRsZXIuZW5kUHJlZml4TWFwcGluZyhwcmVmaXgpOwotICB9Ci0gIHB1YmxpYyB2b2lkIGlnbm9yYWJsZVdoaXRlc3BhY2UoY2hhcltdIGNoLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpCi0gICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgaWYoLS1ldmVudGNvdW50ZXI8PTApCi0gICAgICB7Ci0gICAgICAgIGNvX3lpZWxkKHRydWUpOwotICAgICAgICBldmVudGNvdW50ZXI9ZnJlcXVlbmN5OwotICAgICAgfQotICAgIGlmKGNsaWVudENvbnRlbnRIYW5kbGVyIT1udWxsKQotICAgICAgY2xpZW50Q29udGVudEhhbmRsZXIuaWdub3JhYmxlV2hpdGVzcGFjZShjaCxzdGFydCxsZW5ndGgpOwotICB9Ci0gIHB1YmxpYyB2b2lkIHByb2Nlc3NpbmdJbnN0cnVjdGlvbihqYXZhLmxhbmcuU3RyaW5nIHRhcmdldCwgamF2YS5sYW5nLlN0cmluZyBkYXRhKQotICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIGlmKC0tZXZlbnRjb3VudGVyPD0wKQotICAgICAgewotICAgICAgICBjb195aWVsZCh0cnVlKTsKLSAgICAgICAgZXZlbnRjb3VudGVyPWZyZXF1ZW5jeTsKLSAgICAgIH0KLSAgICBpZihjbGllbnRDb250ZW50SGFuZGxlciE9bnVsbCkKLSAgICAgIGNsaWVudENvbnRlbnRIYW5kbGVyLnByb2Nlc3NpbmdJbnN0cnVjdGlvbih0YXJnZXQsZGF0YSk7Ci0gIH0KLSAgcHVibGljIHZvaWQgc2V0RG9jdW1lbnRMb2NhdG9yKExvY2F0b3IgbG9jYXRvcikKLSAgewotICAgIGlmKC0tZXZlbnRjb3VudGVyPD0wKQotICAgICAgewotICAgICAgICAvLyBUaGlzIGNhbiBjYXVzZSBhIGhhbmcuICAtc2IKLSAgICAgICAgLy8gY29feWllbGQodHJ1ZSk7Ci0gICAgICAgIGV2ZW50Y291bnRlcj1mcmVxdWVuY3k7Ci0gICAgICB9Ci0gICAgaWYoY2xpZW50Q29udGVudEhhbmRsZXIhPW51bGwpCi0gICAgICBjbGllbnRDb250ZW50SGFuZGxlci5zZXREb2N1bWVudExvY2F0b3IobG9jYXRvcik7Ci0gIH0KLSAgcHVibGljIHZvaWQgc2tpcHBlZEVudGl0eShqYXZhLmxhbmcuU3RyaW5nIG5hbWUpCi0gICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgaWYoLS1ldmVudGNvdW50ZXI8PTApCi0gICAgICB7Ci0gICAgICAgIGNvX3lpZWxkKHRydWUpOwotICAgICAgICBldmVudGNvdW50ZXI9ZnJlcXVlbmN5OwotICAgICAgfQotICAgIGlmKGNsaWVudENvbnRlbnRIYW5kbGVyIT1udWxsKQotICAgICAgY2xpZW50Q29udGVudEhhbmRsZXIuc2tpcHBlZEVudGl0eShuYW1lKTsKLSAgfQotICBwdWJsaWMgdm9pZCBzdGFydERvY3VtZW50KCkKLSAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBjb19lbnRyeV9wYXVzZSgpOwotCi0gICAgLy8gT3RoZXJ3aXNlLCBiZWdpbiBub3JtYWwgZXZlbnQgZGVsaXZlcnkKLSAgICBpZigtLWV2ZW50Y291bnRlcjw9MCkKLSAgICAgIHsKLSAgICAgICAgY29feWllbGQodHJ1ZSk7Ci0gICAgICAgIGV2ZW50Y291bnRlcj1mcmVxdWVuY3k7Ci0gICAgICB9Ci0gICAgaWYoY2xpZW50Q29udGVudEhhbmRsZXIhPW51bGwpCi0gICAgICBjbGllbnRDb250ZW50SGFuZGxlci5zdGFydERvY3VtZW50KCk7Ci0gIH0KLSAgcHVibGljIHZvaWQgc3RhcnRFbGVtZW50KGphdmEubGFuZy5TdHJpbmcgbmFtZXNwYWNlVVJJLCBqYXZhLmxhbmcuU3RyaW5nIGxvY2FsTmFtZSwKLSAgICAgIGphdmEubGFuZy5TdHJpbmcgcU5hbWUsIEF0dHJpYnV0ZXMgYXR0cykKLSAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBpZigtLWV2ZW50Y291bnRlcjw9MCkKLSAgICAgIHsKLSAgICAgICAgY29feWllbGQodHJ1ZSk7Ci0gICAgICAgIGV2ZW50Y291bnRlcj1mcmVxdWVuY3k7Ci0gICAgICB9Ci0gICAgaWYoY2xpZW50Q29udGVudEhhbmRsZXIhPW51bGwpCi0gICAgICBjbGllbnRDb250ZW50SGFuZGxlci5zdGFydEVsZW1lbnQobmFtZXNwYWNlVVJJLCBsb2NhbE5hbWUsIHFOYW1lLCBhdHRzKTsKLSAgfQotICBwdWJsaWMgdm9pZCBzdGFydFByZWZpeE1hcHBpbmcoamF2YS5sYW5nLlN0cmluZyBwcmVmaXgsIGphdmEubGFuZy5TdHJpbmcgdXJpKQotICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIGlmKC0tZXZlbnRjb3VudGVyPD0wKQotICAgICAgewotICAgICAgICBjb195aWVsZCh0cnVlKTsKLSAgICAgICAgZXZlbnRjb3VudGVyPWZyZXF1ZW5jeTsKLSAgICAgIH0KLSAgICBpZihjbGllbnRDb250ZW50SGFuZGxlciE9bnVsbCkKLSAgICAgIGNsaWVudENvbnRlbnRIYW5kbGVyLnN0YXJ0UHJlZml4TWFwcGluZyhwcmVmaXgsdXJpKTsKLSAgfQotCi0gIC8vCi0gIC8vIExleGljYWxIYW5kbGVyIHN1cHBvcnQuIE5vdCBhbGwgU0FYMiBmaWx0ZXJzIHN1cHBvcnQgdGhlc2UgZXZlbnRzCi0gIC8vIGJ1dCB3ZSBtYXkgd2FudCB0byBwYXNzIHRoZW0gdGhyb3VnaCB3aGVuIHRoZXkgZXhpc3QuLi4KLSAgLy8KLSAgLy8gJVJFVklFVyUgVGhlc2UgZG8gTk9UIGN1cnJlbnRseSBhZmZlY3QgdGhlIGV2ZW50Y291bnRlcjsgSSdtIGFzc2VydGluZwotICAvLyB0aGF0IHRoZXkncmUgcmFyZSBlbm91Z2ggdGhhdCBpdCBtYWtlcyBsaXR0bGUgb3Igbm8gc2Vuc2UgdG8KLSAgLy8gcGF1c2UgYWZ0ZXIgdGhlbS4gQXMgc3VjaCwgaXQgbWF5IG1ha2UgbW9yZSBzZW5zZSBmb3IgZm9sa3Mgd2hvCi0gIC8vIGFjdHVhbGx5IHdhbnQgdG8gdXNlIHRoZW0gdG8gcmVnaXN0ZXIgZGlyZWN0bHkgd2l0aCB0aGUgZmlsdGVyLgotICAvLyBCdXQgSSB3YW50ICdlbSBoZXJlIGZvciBub3csIHRvIHJlbWluZCB1cyB0byByZWNoZWNrIHRoaXMgYXNzZXJ0aW9uIQotICAvLwotICBwdWJsaWMgdm9pZCBjb21tZW50KGNoYXJbXSBjaCwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKQotICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIGlmKG51bGwhPWNsaWVudExleGljYWxIYW5kbGVyKQotICAgICAgY2xpZW50TGV4aWNhbEhhbmRsZXIuY29tbWVudChjaCxzdGFydCxsZW5ndGgpOwotICB9Ci0gIHB1YmxpYyB2b2lkIGVuZENEQVRBKCkKLSAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBpZihudWxsIT1jbGllbnRMZXhpY2FsSGFuZGxlcikKLSAgICAgIGNsaWVudExleGljYWxIYW5kbGVyLmVuZENEQVRBKCk7Ci0gIH0KLSAgcHVibGljIHZvaWQgZW5kRFREKCkKLSAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBpZihudWxsIT1jbGllbnRMZXhpY2FsSGFuZGxlcikKLSAgICAgIGNsaWVudExleGljYWxIYW5kbGVyLmVuZERURCgpOwotICB9Ci0gIHB1YmxpYyB2b2lkIGVuZEVudGl0eShqYXZhLmxhbmcuU3RyaW5nIG5hbWUpCi0gICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgaWYobnVsbCE9Y2xpZW50TGV4aWNhbEhhbmRsZXIpCi0gICAgICBjbGllbnRMZXhpY2FsSGFuZGxlci5lbmRFbnRpdHkobmFtZSk7Ci0gIH0KLSAgcHVibGljIHZvaWQgc3RhcnRDREFUQSgpCi0gICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgaWYobnVsbCE9Y2xpZW50TGV4aWNhbEhhbmRsZXIpCi0gICAgICBjbGllbnRMZXhpY2FsSGFuZGxlci5zdGFydENEQVRBKCk7Ci0gIH0KLSAgcHVibGljIHZvaWQgc3RhcnREVEQoamF2YS5sYW5nLlN0cmluZyBuYW1lLCBqYXZhLmxhbmcuU3RyaW5nIHB1YmxpY0lkLAotICAgICAgamF2YS5sYW5nLlN0cmluZyBzeXN0ZW1JZCkKLSAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBpZihudWxsIT1jbGllbnRMZXhpY2FsSGFuZGxlcikKLSAgICAgIGNsaWVudExleGljYWxIYW5kbGVyLiBzdGFydERURChuYW1lLCBwdWJsaWNJZCwgc3lzdGVtSWQpOwotICB9Ci0gIHB1YmxpYyB2b2lkIHN0YXJ0RW50aXR5KGphdmEubGFuZy5TdHJpbmcgbmFtZSkKLSAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBpZihudWxsIT1jbGllbnRMZXhpY2FsSGFuZGxlcikKLSAgICAgIGNsaWVudExleGljYWxIYW5kbGVyLnN0YXJ0RW50aXR5KG5hbWUpOwotICB9Ci0KLSAgLy8KLSAgLy8gRFRESGFuZGxlciBzdXBwb3J0LgotCi0gIHB1YmxpYyB2b2lkIG5vdGF0aW9uRGVjbChTdHJpbmcgYSwgU3RyaW5nIGIsIFN0cmluZyBjKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLSAgICAgICAgaWYobnVsbCE9Y2xpZW50RFRESGFuZGxlcikKLSAgICAgICAgICAgICAgICBjbGllbnREVERIYW5kbGVyLm5vdGF0aW9uRGVjbChhLGIsYyk7Ci0gIH0KLSAgcHVibGljIHZvaWQgdW5wYXJzZWRFbnRpdHlEZWNsKFN0cmluZyBhLCBTdHJpbmcgYiwgU3RyaW5nIGMsIFN0cmluZyBkKSAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICB7Ci0gICAgICAgIGlmKG51bGwhPWNsaWVudERUREhhbmRsZXIpCi0gICAgICAgICAgICAgICAgY2xpZW50RFRESGFuZGxlci51bnBhcnNlZEVudGl0eURlY2woYSxiLGMsZCk7Ci0gIH0KLQotICAvLwotICAvLyBFcnJvckhhbmRsZXIgc3VwcG9ydC4KLSAgLy8KLSAgLy8gUFJPQkxFTTogWGVyY2VzIGlzIGFwcGFyZW50bHkgX25vdF8gY2FsbGluZyB0aGUgRXJyb3JIYW5kbGVyIGZvcgotICAvLyBleGNlcHRpb25zIHRocm93biBieSB0aGUgQ29udGVudEhhbmRsZXIsIHdoaWNoIHByZXZlbnRzIHVzIGZyb20KLSAgLy8gaGFuZGxpbmcgdGhpcyBwcm9wZXJseSB3aGVuIHJ1bm5pbmcgaW4gZmlsdGVyaW5nIG1vZGUgd2l0aCBYZXJjZXMKLSAgLy8gYXMgb3VyIGV2ZW50IHNvdXJjZS4gIEl0J3MgdW5jbGVhciB3aGV0aGVyIHRoaXMgaXMgYSBYZXJjZXMgYnVnCi0gIC8vIG9yIGEgU0FYIGRlc2lnbiBmbGF3LgotICAvLwotICAvLyAlUkVWSUVXJSBDdXJyZW50IHNvbHV0aW9uOiBJbiBmaWx0ZXJpbmcgbW9kZSwgaXQgaXMgUkVRVUlSRUQgdGhhdAotICAvLyBldmVudCBzb3VyY2UgbWFrZSBzdXJlIHRoaXMgbWV0aG9kIGlzIGludm9rZWQgaWYgdGhlIGV2ZW50IHN0cmVhbQotICAvLyBhYmVuZHMgYmVmb3JlIGVuZERvY3VtZW50IGlzIGRlbGl2ZXJlZC4gSWYgdGhhdCBtZWFucyBleHBsaWNpdGx5IGNhbGxpbmcKLSAgLy8gdXMgaW4gdGhlIGV4Y2VwdGlvbiBoYW5kbGluZyBjb2RlIGJlY2F1c2UgaXQgd29uJ3QgYmUgZGVsaXZlcmVkIGFzIHBhcnQKLSAgLy8gb2YgdGhlIG5vcm1hbCBTQVggRXJyb3JIYW5kbGVyIHN0cmVhbSwgdGhhdCdzIGZpbmU7IE5vdCBPdXIgUHJvYmxlbS4KLSAgLy8KLSAgcHVibGljIHZvaWQgZXJyb3IoU0FYUGFyc2VFeGNlcHRpb24gZXhjZXB0aW9uKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBpZihudWxsIT1jbGllbnRFcnJvckhhbmRsZXIpCi0gICAgICBjbGllbnRFcnJvckhhbmRsZXIuZXJyb3IoZXhjZXB0aW9uKTsKLSAgfQotCi0gIHB1YmxpYyB2b2lkIGZhdGFsRXJyb3IoU0FYUGFyc2VFeGNlcHRpb24gZXhjZXB0aW9uKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLSAgICAvLyBFWENFUFRJT046IEluIHRoaXMgY2FzZSB3ZSBuZWVkIHRvIHJ1biB0aGUgZXZlbnQgQkVGT1JFIHdlIHlpZWxkIC0tCi0gICAgLy8ganVzdCBhcyB3aXRoIGVuZERvY3VtZW50LCB0aGlzIHRlcm1pbmF0ZXMgdGhlIGV2ZW50IHN0cmVhbS4KLSAgICBpZihudWxsIT1jbGllbnRFcnJvckhhbmRsZXIpCi0gICAgICBjbGllbnRFcnJvckhhbmRsZXIuZXJyb3IoZXhjZXB0aW9uKTsKLQotICAgIGV2ZW50Y291bnRlcj0wOwotICAgIGNvX3lpZWxkKGZhbHNlKTsKLQotICB9Ci0KLSAgcHVibGljIHZvaWQgd2FybmluZyhTQVhQYXJzZUV4Y2VwdGlvbiBleGNlcHRpb24pIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotICAgIGlmKG51bGwhPWNsaWVudEVycm9ySGFuZGxlcikKLSAgICAgIGNsaWVudEVycm9ySGFuZGxlci5lcnJvcihleGNlcHRpb24pOwotICB9Ci0KLQotICAvLwotICAvLyBjb3JvdXRpbmUgc3VwcG9ydAotICAvLwotCi0gIHB1YmxpYyBpbnQgZ2V0U291cmNlQ29yb3V0aW5lSUQoKSB7Ci0gICAgcmV0dXJuIGZTb3VyY2VDb3JvdXRpbmVJRDsKLSAgfQotICBwdWJsaWMgaW50IGdldENvbnRyb2xsZXJDb3JvdXRpbmVJRCgpIHsKLSAgICByZXR1cm4gZkNvbnRyb2xsZXJDb3JvdXRpbmVJRDsKLSAgfQotCi0gIC8qKiBAcmV0dXJuIHRoZSBDb3JvdXRpbmVNYW5hZ2VyIHRoaXMgQ29yb3V0aW5lRmlsdGVyIG9iamVjdCBpcyBib3VuZCB0by4KLSAgICogSWYgeW91J3JlIHVzaW5nIHRoZSBkby4uLigpIG1ldGhvZHMsIGFwcGxpY2F0aW9ucyBzaG91bGQgb25seQotICAgKiBuZWVkIHRvIHRhbGsgdG8gdGhlIENvcm91dGluZU1hbmFnZXIgb25jZSwgdG8gb2J0YWluIHRoZQotICAgKiBhcHBsaWNhdGlvbidzIENvcm91dGluZSBJRC4KLSAgICogKi8KLSAgcHVibGljIENvcm91dGluZU1hbmFnZXIgZ2V0Q29yb3V0aW5lTWFuYWdlcigpCi0gIHsKLSAgICByZXR1cm4gZkNvcm91dGluZU1hbmFnZXI7Ci0gIH0KLQotICAvKiogPHA+SW4gdGhlIFNBWCBkZWxlZ2F0aW9uIGNvZGUsIEkndmUgaW5saW5lZCB0aGUgY291bnQtZG93biBpbgotICAgKiB0aGUgaG9wZSBvZiBlbmNvdXJhZ2luZyBjb21waWxlcnMgdG8gZGVsaXZlciBiZXR0ZXIKLSAgICogcGVyZm9ybWFuY2UuIEhvd2V2ZXIsIGlmIHdlIHN1YmNsYXNzIChlZyB0byBkaXJlY3RseSBjb25uZWN0IHRoZQotICAgKiBvdXRwdXQgdG8gYSBEVE0gYnVpbGRlciksIHRoYXQgd291bGQgcmVxdWlyZSBjYWxsaW5nIHN1cGVyIGluCi0gICAqIG9yZGVyIHRvIHJ1biB0aGF0IGxvZ2ljLi4uIHdoaWNoIHNlZW1zIGluZWxlZ2FudC4gIEhlbmNlIHRoaXMKLSAgICogcm91dGluZSBmb3IgdGhlIGNvbnZlbmllbmNlIG9mIHN1YmNsYXNzZXM6IGV2ZXJ5IFtmcmVxdWVuY3ldCi0gICAqIGludm9jYXRpb25zLCBpc3N1ZSBhIGNvX3lpZWxkLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIG1vcmVFeGVwZWN0ZWQgU2hvdWxkIGFsd2F5cyBiZSB0cnVlIHVubGVzcyB0aGlzIGlzIGJlaW5nIGNhbGxlZAotICAgKiBhdCB0aGUgZW5kIG9mIGVuZERvY3VtZW50KCkgaGFuZGxpbmcuCi0gICAqICovCi0gIHByb3RlY3RlZCB2b2lkIGNvdW50X2FuZF95aWVsZChib29sZWFuIG1vcmVFeHBlY3RlZCkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICB7Ci0gICAgaWYoIW1vcmVFeHBlY3RlZCkgZXZlbnRjb3VudGVyPTA7Ci0KLSAgICBpZigtLWV2ZW50Y291bnRlcjw9MCkKLSAgICAgIHsKLSAgICAgICAgY29feWllbGQodHJ1ZSk7Ci0gICAgICAgIGV2ZW50Y291bnRlcj1mcmVxdWVuY3k7Ci0gICAgICB9Ci0gIH0KLQotICAvKioKLSAgICogY29fZW50cnlfcGF1c2UgaXMgY2FsbGVkIGluIHN0YXJ0RG9jdW1lbnQoKSBiZWZvcmUgYW55dGhpbmcgZWxzZQotICAgKiBoYXBwZW5zLiBJdCBjYXVzZXMgdGhlIGZpbHRlciB0byB3YWl0IGZvciBhICJnbyBhaGVhZCIgcmVxdWVzdAotICAgKiBmcm9tIHRoZSBjb250cm9sbGVyIGJlZm9yZSBkZWxpdmVyaW5nIGFueSBldmVudHMuIE5vdGUgdGhhdAotICAgKiB0aGUgdmVyeSBmaXJzdCB0aGluZyB0aGUgY29udHJvbGxlciB0ZWxscyB1cyBtYXkgYmUgIkkgZG9uJ3QKLSAgICogbmVlZCBldmVudHMgYWZ0ZXIgYWxsIiEKLSAgICovCi0gIHByaXZhdGUgdm9pZCBjb19lbnRyeV9wYXVzZSgpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotICAgIGlmKGZDb3JvdXRpbmVNYW5hZ2VyPT1udWxsKQotICAgIHsKLSAgICAgIC8vIE5vYm9keSBjYWxsZWQgaW5pdCgpPyBEbyBpdCBub3cuLi4KLSAgICAgIGluaXQobnVsbCwtMSwtMSk7Ci0gICAgfQotCi0gICAgdHJ5Ci0gICAgewotICAgICAgT2JqZWN0IGFyZz1mQ29yb3V0aW5lTWFuYWdlci5jb19lbnRyeV9wYXVzZShmU291cmNlQ29yb3V0aW5lSUQpOwotICAgICAgaWYoYXJnPT1Cb29sZWFuLkZBTFNFKQotICAgICAgICBjb195aWVsZChmYWxzZSk7Ci0gICAgfQotICAgIGNhdGNoKE5vU3VjaE1ldGhvZEV4Y2VwdGlvbiBlKQotICAgIHsKLSAgICAgIC8vIENvcm91dGluZSBzeXN0ZW0gc2F5cyB3ZSBoYXZlbid0IHJlZ2lzdGVyZWQuIFRoYXQncyBhbgotICAgICAgLy8gYXBwbGljYXRpb24gY29kaW5nIGVycm9yLCBhbmQgaXMgdW5yZWNvdmVyYWJsZS4KLSAgICAgIGlmKERFQlVHKSBlLnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbihlKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogQ29fWWllbGQgaGFuZGxlcyBjb3JvdXRpbmUgaW50ZXJhY3Rpb25zIHdoaWxlIGEgcGFyc2UgaXMgaW4gcHJvZ3Jlc3MuCi0gICAqCi0gICAqIFdoZW4gbW9yZVJlbWFpbnM9PXRydWUsIHdlIGFyZSBwYXVzaW5nIGFmdGVyIGRlbGl2ZXJpbmcgZXZlbnRzLCB0bwotICAgKiBhc2sgaWYgbW9yZSBhcmUgbmVlZGVkLiBXZSB3aWxsIHJlc3VtZSB0aGUgY29udHJvbGxlciB0aHJlYWQgd2l0aAotICAgKiAgIGNvX3Jlc3VtZShCb29sZWFuLlRSVUUsIC4uLikKLSAgICogV2hlbiBjb250cm9sIGlzIHBhc3NlZCBiYWNrIGl0IG1heSBpbmRpY2F0ZQotICAgKiAgICAgIEJvb2xlYW4uVFJVRSAgICBpbmRpY2F0aW9uIHRvIGNvbnRpbnVlIGRlbGl2ZXJpbmcgZXZlbnRzCi0gICAqICAgICAgQm9vbGVhbi5GQUxTRSAgIGluZGljYXRpb24gdG8gZGlzY29udGludWUgZXZlbnRzIGFuZCBzaHV0IGRvd24uCi0gICAqCi0gICAqIFdoZW4gbW9yZVJlbWFpbnM9PWZhbHNlLCB3ZSBzaHV0IGRvd24gaW1tZWRpYXRlbHkgd2l0aG91dCBhc2tpbmcgdGhlCi0gICAqIGNvbnRyb2xsZXIncyBwZXJtaXNzaW9uLiBOb3JtYWxseSB0aGlzIG1lYW5zIGVuZCBvZiBkb2N1bWVudCBoYXMgYmVlbgotICAgKiByZWFjaGVkLgotICAgKgotICAgKiBTaHV0dGluZyBkb3duIGEgSW5jcmVtZW50YWxTQVhTb3VyY2VfRmlsdGVyIHJlcXVpcmVzIHRlcm1pbmF0aW5nIHRoZSBpbmNvbWluZwotICAgKiBTQVggZXZlbnQgc3RyZWFtLiBJZiB3ZSBhcmUgaW4gY29udHJvbCBvZiB0aGF0IHN0cmVhbSAoaWYgaXQgY2FtZQotICAgKiBmcm9tIGFuIFhNTFJlYWRlciBwYXNzZWQgdG8gb3VyIHN0YXJ0UmVhZGVyKCkgbWV0aG9kKSwgd2UgY2FuIGRvIHNvCi0gICAqIHZlcnkgcXVpY2tseSBieSB0aHJvd2luZyBhIHJlc2VydmVkIGV4Y2VwdGlvbiB0byBpdC4gSWYgdGhlIHN0cmVhbSBpcwotICAgKiBjb21pbmcgZnJvbSBhbm90aGVyIHNvdXJjZSwgd2UgY2FuJ3QgZG8gdGhhdCBiZWNhdXNlIGl0cyBjYWxsZXIgbWF5Ci0gICAqIG5vdCBiZSBwcmVwYXJlZCBmb3IgdGhpcyAibm9ybWFsIGFibm9ybWFsIGV4aXQiLCBhbmQgaW5zdGVhZCB3ZSBwdXQKLSAgICogb3Vyc2VsdmVzIGluIGEgInNwaW4iIG1vZGUgd2hlcmUgZXZlbnRzIGFyZSBkaXNjYXJkZWQuCi0gICAqLwotICBwcml2YXRlIHZvaWQgY29feWllbGQoYm9vbGVhbiBtb3JlUmVtYWlucykgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICB7Ci0gICAgLy8gSG9ycmVuZG91cyBrbHVnZSB0byBydW4gZmlsdGVyIHRvIGNvbXBsZXRpb24uIFNlZSBiZWxvdy4KLSAgICBpZihmTm9Nb3JlRXZlbnRzKQotICAgICAgcmV0dXJuOwotCi0gICAgdHJ5IC8vIENvcm91dGluZSBtYW5hZ2VyIG1pZ2h0IHRocm93IG5vLXN1Y2guCi0gICAgewotICAgICAgT2JqZWN0IGFyZz1Cb29sZWFuLkZBTFNFOwotICAgICAgaWYobW9yZVJlbWFpbnMpCi0gICAgICB7Ci0gICAgICAgIC8vIFlpZWxkIGNvbnRyb2wsIHJlc3VtZSBwYXJzaW5nIHdoZW4gZG9uZQotICAgICAgICBhcmcgPSBmQ29yb3V0aW5lTWFuYWdlci5jb19yZXN1bWUoQm9vbGVhbi5UUlVFLCBmU291cmNlQ29yb3V0aW5lSUQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmQ29udHJvbGxlckNvcm91dGluZUlEKTsKLQotICAgICAgfQotCi0gICAgICAvLyBJZiB3ZSdyZSBhdCBlbmQgb2YgZG9jdW1lbnQgb3Igd2VyZSB0b2xkIHRvIHN0b3AgZWFybHkKLSAgICAgIGlmKGFyZz09Qm9vbGVhbi5GQUxTRSkKLSAgICAgIHsKLSAgICAgICAgZk5vTW9yZUV2ZW50cz10cnVlOwotCi0gICAgICAgIGlmKGZYTUxSZWFkZXIhPW51bGwpICAgIC8vIFJ1bm5pbmcgdW5kZXIgc3RhcnRQYXJzZVRocmVhZCgpCi0gICAgICAgICAgdGhyb3cgbmV3IFN0b3BFeGNlcHRpb24oKTsgLy8gV2UnbGwgY29fZXhpdCBmcm9tIHRoZXJlLgotCi0gICAgICAgIC8vIFlpZWxkIGNvbnRyb2wuIFdlIGRvIE5PVCBleHBlY3QgYW55b25lIHRvIGV2ZXIgYXNrIHVzIGFnYWluLgotICAgICAgICBmQ29yb3V0aW5lTWFuYWdlci5jb19leGl0X3RvKEJvb2xlYW4uRkFMU0UsIGZTb3VyY2VDb3JvdXRpbmVJRCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmQ29udHJvbGxlckNvcm91dGluZUlEKTsKLSAgICAgIH0KLSAgICB9Ci0gICAgY2F0Y2goTm9TdWNoTWV0aG9kRXhjZXB0aW9uIGUpCi0gICAgewotICAgICAgLy8gU2hvdWxkbid0IGhhcHBlbiB1bmxlc3Mgd2UndmUgbWlzY29kZWQgb3VyIGNvcm91dGluZSBsb2dpYwotICAgICAgLy8gIlNodXQgZG93biB0aGUgZ2FyYmFnZSBzbWFzaGVycyBvbiB0aGUgZGV0ZW50aW9uIGxldmVsISIKLSAgICAgIGZOb01vcmVFdmVudHM9dHJ1ZTsKLSAgICAgIGZDb3JvdXRpbmVNYW5hZ2VyLmNvX2V4aXQoZlNvdXJjZUNvcm91dGluZUlEKTsKLSAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oZSk7Ci0gICAgfQotICB9Ci0KLSAgLy8KLSAgLy8gQ29udmVuaWVuY2U6IFJ1biBhbiBYTUxSZWFkZXIgaW4gYSB0aHJlYWQKLSAgLy8KLQotICAvKiogTGF1bmNoIGEgdGhyZWFkIHRoYXQgd2lsbCBydW4gYW4gWE1MUmVhZGVyJ3MgcGFyc2UoKSBvcGVyYXRpb24gd2l0aGluCi0gICAqICBhIHRocmVhZCwgZmVlZGluZyBldmVudHMgdG8gdGhpcyBJbmNyZW1lbnRhbFNBWFNvdXJjZV9GaWx0ZXIuIE1vc3RseSBhIGNvbnZlbmllbmNlCi0gICAqICByb3V0aW5lLCBidXQgaGFzIHRoZSBhZHZhbnRhZ2UgdGhhdCAtLSBzaW5jZSB3ZSBpbnZva2VkIHBhcnNlKCkgLS0KLSAgICogIHdlIGNhbiBoYWx0IHBhcnNpbmcgcXVpY2tseSB2aWEgYSBTdG9wRXhjZXB0aW9uIHJhdGhlciB0aGFuIHdhaXRpbmcKLSAgICogIGZvciB0aGUgU0FYIHN0cmVhbSB0byBlbmQgYnkgaXRzZWxmLgotICAgKgotICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBpcyBwYXJzZSB0aHJlYWQgaXMgYWxyZWFkeSBpbiBwcm9ncmVzcwotICAgKiBvciBwYXJzaW5nIGNhbiBub3QgYmUgc3RhcnRlZC4KLSAgICogKi8KLSAgcHVibGljIHZvaWQgc3RhcnRQYXJzZShJbnB1dFNvdXJjZSBzb3VyY2UpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotICAgIGlmKGZOb01vcmVFdmVudHMpCi0gICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKFhNTE1lc3NhZ2VzLmNyZWF0ZVhNTE1lc3NhZ2UoWE1MRXJyb3JSZXNvdXJjZXMuRVJfSU5DUlNBWFNSQ0ZJTFRFUl9OT1RfUkVTVEFSVEFCTEUsIG51bGwpKTsgLy8iSW5jcm1lbnRhbFNBWFNvdXJjZV9GaWx0ZXIgbm90IGN1cnJlbnRseSByZXN0YXJ0YWJsZS4iKTsKLSAgICBpZihmWE1MUmVhZGVyPT1udWxsKQotICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbihYTUxNZXNzYWdlcy5jcmVhdGVYTUxNZXNzYWdlKFhNTEVycm9yUmVzb3VyY2VzLkVSX1hNTFJEUl9OT1RfQkVGT1JFX1NUQVJUUEFSU0UsIG51bGwpKTsgLy8iWE1MUmVhZGVyIG5vdCBiZWZvcmUgc3RhcnRQYXJzZSByZXF1ZXN0Iik7Ci0KLSAgICBmWE1MUmVhZGVySW5wdXRTb3VyY2U9c291cmNlOwotCi0gICAgLy8gWGFsYW4gdGhyZWFkIHBvb2xpbmcuLi4KLSAgICAvLyBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwudHJhbnNmb3JtZXIuVHJhbnNmb3JtZXJJbXBsLnJ1blRyYW5zZm9ybVRocmVhZCh0aGlzKTsKLSAgICBUaHJlYWRDb250cm9sbGVyV3JhcHBlci5ydW5UaHJlYWQodGhpcywgLTEpOwotICB9Ci0KLSAgLyogVGhyZWFkIGxvZ2ljIHRvIHN1cHBvcnQgc3RhcnRQYXJzZVRocmVhZCgpCi0gICAqLwotICBwdWJsaWMgdm9pZCBydW4oKQotICB7Ci0gICAgLy8gR3VhcmQgYWdhaW5zdCBkaXJlY3QgaW52b2NhdGlvbiBvZiBzdGFydCgpLgotICAgIGlmKGZYTUxSZWFkZXI9PW51bGwpIHJldHVybjsKLQotICAgIGlmKERFQlVHKVN5c3RlbS5vdXQucHJpbnRsbigiSW5jcmVtZW50YWxTQVhTb3VyY2VfRmlsdGVyIHBhcnNlIHRocmVhZCBsYXVuY2hlZCIpOwotCi0gICAgLy8gSW5pdGlhbGx5IGFzc3VtZSB3ZSdsbCBydW4gc3VjY2Vzc2Z1bGx5LgotICAgIE9iamVjdCBhcmc9Qm9vbGVhbi5GQUxTRTsKLQotICAgIC8vIEZvciB0aGUgZHVyYXRpb24gb2YgdGhpcyBvcGVyYXRpb24sIGFsbCBjb3JvdXRpbmUgaGFuZHNoYWtpbmcKLSAgICAvLyB3aWxsIG9jY3VyIGluIHRoZSBjb195aWVsZCBtZXRob2QuIFRoYXQncyB0aGUgbmljZSB0aGluZyBhYm91dAotICAgIC8vIGNvcm91dGluZXM7IHRoZXkgZ2l2ZSB1cyBhIHdheSB0byBoYW5kIG9mZiBjb250cm9sIGZyb20gdGhlCi0gICAgLy8gbWlkZGxlIG9mIGEgc3luY2hyb25vdXMgbWV0aG9kLgotICAgIHRyeQotICAgIHsKLSAgICAgIGZYTUxSZWFkZXIucGFyc2UoZlhNTFJlYWRlcklucHV0U291cmNlKTsKLSAgICB9Ci0gICAgY2F0Y2goSU9FeGNlcHRpb24gZXgpCi0gICAgewotICAgICAgYXJnPWV4OwotICAgIH0KLSAgICBjYXRjaChTdG9wRXhjZXB0aW9uIGV4KQotICAgIHsKLSAgICAgIC8vIEV4cGVjdGVkIGFuZCBoYXJtbGVzcwotICAgICAgaWYoREVCVUcpU3lzdGVtLm91dC5wcmludGxuKCJBY3RpdmUgSW5jcmVtZW50YWxTQVhTb3VyY2VfRmlsdGVyIG5vcm1hbCBzdG9wIGV4Y2VwdGlvbiIpOwotICAgIH0KLSAgICBjYXRjaCAoU0FYRXhjZXB0aW9uIGV4KQotICAgIHsKLSAgICAgIEV4Y2VwdGlvbiBpbm5lcj1leC5nZXRFeGNlcHRpb24oKTsKLSAgICAgIGlmKGlubmVyIGluc3RhbmNlb2YgU3RvcEV4Y2VwdGlvbil7Ci0gICAgICAgIC8vIEV4cGVjdGVkIGFuZCBoYXJtbGVzcwotICAgICAgICBpZihERUJVRylTeXN0ZW0ub3V0LnByaW50bG4oIkFjdGl2ZSBJbmNyZW1lbnRhbFNBWFNvdXJjZV9GaWx0ZXIgbm9ybWFsIHN0b3AgZXhjZXB0aW9uIik7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIC8vIFVuZXhwZWN0ZWQgbWFsZnVuY3Rpb24KLSAgICAgICAgaWYoREVCVUcpCi0gICAgICAgIHsKLSAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkFjdGl2ZSBJbmNyZW1lbnRhbFNBWFNvdXJjZV9GaWx0ZXIgVU5FWFBFQ1RFRCBTQVggZXhjZXB0aW9uOiAiK2lubmVyKTsKLSAgICAgICAgICBpbm5lci5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgICAgfQotICAgICAgICBhcmc9ZXg7Ci0gICAgICB9Ci0gICAgfSAvLyBlbmQgcGFyc2UKLQotICAgIC8vIE1hcmsgYXMgbm8gbG9uZ2VyIHJ1bm5pbmcgaW4gdGhyZWFkLgotICAgIGZYTUxSZWFkZXI9bnVsbDsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIC8vIE1hcmsgYXMgZG9uZSBhbmQgeWllbGQgY29udHJvbCB0byB0aGUgY29udHJvbGxlciBjb3JvdXRpbmUKLSAgICAgIGZOb01vcmVFdmVudHM9dHJ1ZTsKLSAgICAgIGZDb3JvdXRpbmVNYW5hZ2VyLmNvX2V4aXRfdG8oYXJnLCBmU291cmNlQ29yb3V0aW5lSUQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZDb250cm9sbGVyQ29yb3V0aW5lSUQpOwotICAgIH0KLSAgICBjYXRjaChqYXZhLmxhbmcuTm9TdWNoTWV0aG9kRXhjZXB0aW9uIGUpCi0gICAgewotICAgICAgLy8gU2hvdWxkbid0IGhhcHBlbiB1bmxlc3Mgd2UndmUgbWlzY29kZWQgb3VyIGNvcm91dGluZSBsb2dpYwotICAgICAgLy8gIkNQTywgc2h1dCBkb3duIHRoZSBnYXJiYWdlIHNtYXNoZXJzIG9uIHRoZSBkZXRlbnRpb24gbGV2ZWwhIgotICAgICAgZS5wcmludFN0YWNrVHJhY2UoU3lzdGVtLmVycik7Ci0gICAgICBmQ29yb3V0aW5lTWFuYWdlci5jb19leGl0KGZTb3VyY2VDb3JvdXRpbmVJRCk7Ci0gICAgfQotICB9Ci0KLSAgLyoqIFVzZWQgdG8gcXVpY2tseSB0ZXJtaW5hdGUgcGFyc2Ugd2hlbiBydW5uaW5nIHVuZGVyIGEKLSAgICAgIHN0YXJ0UGFyc2UoKSB0aHJlYWQuIE9ubHkgaXRzIHR5cGUgaXMgaW1wb3J0YW50LiAqLwotICBjbGFzcyBTdG9wRXhjZXB0aW9uIGV4dGVuZHMgUnVudGltZUV4Y2VwdGlvbgotICB7Ci0gICAgICAgICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC0xMTI5MjQ1Nzk2MTg1NzU0OTU2TDsKLSAgfQotCi0gIC8qKiBkZWxpdmVyTW9yZU5vZGVzKCkgaXMgYSBzaW1wbGUgQVBJIHdoaWNoIHRlbGxzIHRoZSBjb3JvdXRpbmUKLSAgICogcGFyc2VyIHRoYXQgd2UgbmVlZCBtb3JlIG5vZGVzLiAgVGhpcyBpcyBpbnRlbmRlZCB0byBiZSBjYWxsZWQKLSAgICogZnJvbSBvbmUgb2Ygb3VyIHBhcnRuZXIgcm91dGluZXMsIGFuZCBzZXJ2ZXMgdG8gZW5jYXBzdWxhdGUgdGhlCi0gICAqIGRldGFpbHMgb2YgaG93IGluY3JlbWVudGFsIHBhcnNpbmcgaGFzIGJlZW4gYWNoaWV2ZWQuCi0gICAqCi0gICAqIEBwYXJhbSBwYXJzZW1vcmUgSWYgdHJ1ZSwgdGVsbHMgdGhlIGluY3JlbWVudGFsIGZpbHRlciB0byBnZW5lcmF0ZQotICAgKiBhbm90aGVyIGNodW5rIG9mIG91dHB1dC4gSWYgZmFsc2UsIHRlbGxzIHRoZSBmaWx0ZXIgdGhhdCB3ZSdyZQotICAgKiBzYXRpc2ZpZWQgYW5kIGl0IGNhbiB0ZXJtaW5hdGUgcGFyc2luZyBvZiB0aGlzIGRvY3VtZW50LgotICAgKgotICAgKiBAcmV0dXJuIEJvb2xlYW4uVFJVRSBpZiB0aGVyZSBtYXkgYmUgbW9yZSBldmVudHMgYXZhaWxhYmxlIGJ5IGludm9raW5nCi0gICAqIGRlbGl2ZXJNb3JlTm9kZXMoKSBhZ2Fpbi4gQm9vbGVhbi5GQUxTRSBpZiBwYXJzaW5nIGhhcyBydW4gdG8gY29tcGxldGlvbiAob3IgYmVlbgotICAgKiB0ZXJtaW5hdGVkIGJ5IGRlbGl2ZXJNb3JlTm9kZXMoZmFsc2UpLiBPciBhbiBleGNlcHRpb24gb2JqZWN0IGlmIHNvbWV0aGluZwotICAgKiBtYWxmdW5jdGlvbmVkLiAlUkVWSUVXJSBXZSBfY291bGRfIGFjdHVhbGx5IHRocm93IHRoZSBleGNlcHRpb24sIGJ1dAotICAgKiB0aGF0IHdvdWxkIHJlcXVpcmUgcnVuaW5uZyBkZWxpdmVyTW9yZU5vZGVzKCkgaW4gYSB0cnkvY2F0Y2guLi4gYW5kIGZvciBtYW55Ci0gICAqIGFwcGxpY2F0aW9ucywgZXhjZXB0aW9uIHdpbGwgYmUgc2ltcGx5IGJlIHRyZWF0ZWQgYXMgIm5vdCBUUlVFIiBpbgotICAgKiBhbnkgY2FzZS4KLSAgICogKi8KLSAgcHVibGljIE9iamVjdCBkZWxpdmVyTW9yZU5vZGVzKGJvb2xlYW4gcGFyc2Vtb3JlKQotICB7Ci0gICAgLy8gSWYgcGFyc2luZyBpcyBhbHJlYWR5IGRvbmUsIHdlIGNhbiBpbW1lZGlhdGVseSBzYXkgc28KLSAgICBpZihmTm9Nb3JlRXZlbnRzKQotICAgICAgcmV0dXJuIEJvb2xlYW4uRkFMU0U7Ci0KLSAgICB0cnkKLSAgICB7Ci0gICAgICBPYmplY3QgcmVzdWx0ID0KLSAgICAgICAgZkNvcm91dGluZU1hbmFnZXIuY29fcmVzdW1lKHBhcnNlbW9yZT9Cb29sZWFuLlRSVUU6Qm9vbGVhbi5GQUxTRSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZDb250cm9sbGVyQ29yb3V0aW5lSUQsIGZTb3VyY2VDb3JvdXRpbmVJRCk7Ci0gICAgICBpZihyZXN1bHQ9PUJvb2xlYW4uRkFMU0UpCi0gICAgICAgIGZDb3JvdXRpbmVNYW5hZ2VyLmNvX2V4aXQoZkNvbnRyb2xsZXJDb3JvdXRpbmVJRCk7Ci0KLSAgICAgIHJldHVybiByZXN1bHQ7Ci0gICAgfQotCi0gICAgLy8gU0hPVUxEIE5FVkVSIE9DQ1VSLCBzaW5jZSB0aGUgY29yb3V0aW5lIG51bWJlciBhbmQgY29yb3V0aW5lIG1hbmFnZXIKLSAgICAvLyBhcmUgdGhvc2UgcHJldmlvdXNseSBlc3RhYmxpc2hlZCBmb3IgdGhpcyBJbmNyZW1lbnRhbFNBWFNvdXJjZV9GaWx0ZXIuLi4KLSAgICAvLyBTbyBJJ20ganVzdCBnb2luZyB0byByZXR1cm4gaXQgYXMgYSBwYXJzaW5nIGV4Y2VwdGlvbiwgZm9yIG5vdy4KLSAgICBjYXRjaChOb1N1Y2hNZXRob2RFeGNlcHRpb24gZSkKLSAgICAgIHsKLSAgICAgICAgcmV0dXJuIGU7Ci0gICAgICB9Ci0gIH0KLQotCi0gIC8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICAvKiogU2ltcGxlIHVuaXQgdGVzdC4gQXR0ZW1wdCBjb3JvdXRpbmUgcGFyc2luZyBvZiBkb2N1bWVudCBpbmRpY2F0ZWQKLSAgICogYnkgZmlyc3QgYXJndW1lbnQgKGFzIGEgVVJJKSwgcmVwb3J0IHByb2dyZXNzLgotICAgKi8KLSAgICAvKgotICBwdWJsaWMgc3RhdGljIHZvaWQgX21haW4oU3RyaW5nIGFyZ3NbXSkKLSAgewotICAgIFN5c3RlbS5vdXQucHJpbnRsbigiU3RhcnRpbmcuLi4iKTsKLQotICAgIG9yZy54bWwuc2F4LlhNTFJlYWRlciB0aGVTQVhQYXJzZXI9Ci0gICAgICBuZXcgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5wYXJzZXJzLlNBWFBhcnNlcigpOwotCi0KLSAgICBmb3IoaW50IGFyZz0wO2FyZzxhcmdzLmxlbmd0aDsrK2FyZykKLSAgICB7Ci0gICAgICAvLyBUaGUgZmlsdGVyIGlzIG5vdCBjdXJyZW50bHkgZGVzaWduZWQgdG8gYmUgcmVzdGFydGFibGUKLSAgICAgIC8vIGFmdGVyIGEgcGFyc2UgaGFzIGVuZGVkLiBHZW5lcmF0ZSBhIG5ldyBvbmUgZWFjaCB0aW1lLgotICAgICAgSW5jcmVtZW50YWxTQVhTb3VyY2VfRmlsdGVyIGZpbHRlcj0KLSAgICAgICAgbmV3IEluY3JlbWVudGFsU0FYU291cmNlX0ZpbHRlcigpOwotICAgICAgLy8gVXNlIGEgc2VyaWFsaXplciBhcyBvdXIgc2FtcGxlIG91dHB1dAotICAgICAgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemUuWE1MU2VyaWFsaXplciB0cmFjZTsKLSAgICAgIHRyYWNlPW5ldyBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZS5YTUxTZXJpYWxpemVyKFN5c3RlbS5vdXQsbnVsbCk7Ci0gICAgICBmaWx0ZXIuc2V0Q29udGVudEhhbmRsZXIodHJhY2UpOwotICAgICAgZmlsdGVyLnNldExleGljYWxIYW5kbGVyKHRyYWNlKTsKLQotICAgICAgdHJ5Ci0gICAgICB7Ci0gICAgICAgIElucHV0U291cmNlIHNvdXJjZSA9IG5ldyBJbnB1dFNvdXJjZShhcmdzW2FyZ10pOwotICAgICAgICBPYmplY3QgcmVzdWx0PW51bGw7Ci0gICAgICAgIGJvb2xlYW4gbW9yZT10cnVlOwotCi0gICAgICAgIC8vIGluaXQgbm90IGlzc3VlZDsgd2UgX3Nob3VsZF8gYXV0b21hZ2ljYWxseSBEbyBUaGUgUmlnaHQgVGhpbmcKLQotICAgICAgICAvLyBCaW5kIHBhcnNlciwga2ljayBvZmYgcGFyc2luZyBpbiBhIHRocmVhZAotICAgICAgICBmaWx0ZXIuc2V0WE1MUmVhZGVyKHRoZVNBWFBhcnNlcik7Ci0gICAgICAgIGZpbHRlci5zdGFydFBhcnNlKHNvdXJjZSk7Ci0KLSAgICAgICAgZm9yKHJlc3VsdCA9IGZpbHRlci5kZWxpdmVyTW9yZU5vZGVzKG1vcmUpOwotICAgICAgICAgICAgKHJlc3VsdCBpbnN0YW5jZW9mIEJvb2xlYW4gJiYgKChCb29sZWFuKXJlc3VsdCk9PUJvb2xlYW4uVFJVRSk7Ci0gICAgICAgICAgICByZXN1bHQgPSBmaWx0ZXIuZGVsaXZlck1vcmVOb2Rlcyhtb3JlKSkKLSAgICAgICAgewotICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXG5Tb21lIHBhcnNpbmcgc3VjY2Vzc2Z1bCwgdHJ5aW5nIG1vcmUuXG4iKTsKLQotICAgICAgICAgIC8vIFNwZWNpYWwgdGVzdDogVGVybWluYXRlIHBhcnNpbmcgZWFybHkuCi0gICAgICAgICAgaWYoYXJnKzE8YXJncy5sZW5ndGggJiYgIiEiLmVxdWFscyhhcmdzW2FyZysxXSkpCi0gICAgICAgICAgewotICAgICAgICAgICAgKythcmc7Ci0gICAgICAgICAgICBtb3JlPWZhbHNlOwotICAgICAgICAgIH0KLQotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIEJvb2xlYW4gJiYgKChCb29sZWFuKXJlc3VsdCk9PUJvb2xlYW4uRkFMU0UpCi0gICAgICAgIHsKLSAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlxuRmlsdGVyIGVuZGVkIChFT0Ygb3Igb24gcmVxdWVzdCkuXG4iKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChyZXN1bHQgPT0gbnVsbCkgewotICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXG5VTkVYUEVDVEVEOiBGaWx0ZXIgc2F5cyBzaHV0IGRvd24gcHJlbWF0dXJlbHkuXG4iKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBFeGNlcHRpb24pIHsKLSAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlxuRmlsdGVyIHRocmV3IGV4Y2VwdGlvbjoiKTsKLSAgICAgICAgICAoKEV4Y2VwdGlvbilyZXN1bHQpLnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgICB9Ci0KLSAgICAgIH0KLSAgICAgIGNhdGNoKFNBWEV4Y2VwdGlvbiBlKQotICAgICAgewotICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgfQotICAgIH0gLy8gZW5kIGZvcgotICB9Ci0gICAgKi8KLX0gLy8gY2xhc3MgSW5jcmVtZW50YWxTQVhTb3VyY2VfRmlsdGVyCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vcmVmL0luY3JlbWVudGFsU0FYU291cmNlX1hlcmNlcy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL3JlZi9JbmNyZW1lbnRhbFNBWFNvdXJjZV9YZXJjZXMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMjk4ODFlYi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vcmVmL0luY3JlbWVudGFsU0FYU291cmNlX1hlcmNlcy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDU3ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IEluY3JlbWVudGFsU0FYU291cmNlX1hlcmNlcy5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE1IDA4OjE1OjA4IHN1cmVzaF9lbWFpbGlkIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5yZWY7Ci0KLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkNvbnN0cnVjdG9yOwotaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lk1ldGhvZDsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwucGFyc2Vycy5TQVhQYXJzZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXMuWE1MRXJyb3JSZXNvdXJjZXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXMuWE1MTWVzc2FnZXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnV0aWxzLk9iamVjdEZhY3Rvcnk7Ci0KLWltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguWE1MUmVhZGVyOwotCi0KLS8qKiA8cD5JbmNyZW1lbnRhbFNBWFNvdXJjZV9YZXJjZXMgdGFrZXMgYWR2YW50YWdlIG9mIHRoZSBmYWN0IHRoYXQgWGVyY2VzMQotICogaW5jcmVtZW50YWwgbW9kZSBpcyBhbHJlYWR5IGEgY29yb3V0aW5lIG9mIHNvcnRzLCBhbmQganVzdCB3cmFwcyBvdXIKLSAqIEluY3JlbWVudGFsU0FYU291cmNlIEFQSSBhcm91bmQgaXQuPC9wPgotICoKLSAqIDxwPlVzYWdlIGV4YW1wbGU6IFNlZSBtYWluKCkuPC9wPgotICoKLSAqIDxwPlN0YXR1czogUGFzc2VzIHNpbXBsZSBtYWluKCkgdW5pdC10ZXN0LiBORUVEUyBKQVZBRE9DLjwvcD4KLSAqICovCi1wdWJsaWMgY2xhc3MgSW5jcmVtZW50YWxTQVhTb3VyY2VfWGVyY2VzCi0gIGltcGxlbWVudHMgSW5jcmVtZW50YWxTQVhTb3VyY2UKLXsKLSAgLy8KLSAgLy8gUmVmbGVjdGlvbi4gVG8gYWxsb3cgdGhpcyB0byBjb21waWxlIHdpdGggYm90aCBYZXJjZXMxIGFuZCBYZXJjZXMyLCB3aGljaAotICAvLyByZXF1aXJlIHZlcnkgZGlmZmVyZW50IG1ldGhvZHMgYW5kIG9iamVjdHMsIHdlIG5lZWQgdG8gYXZvaWQgc3RhdGljCi0gIC8vIHJlZmVyZW5jZXMgdG8gdGhvc2UgQVBJcy4gU28gdW50aWwgWGVyY2VzMiBpcyBwZXJ2YXNpdmUgYW5kIHdlJ3JlIHdpbGxpbmcKLSAgLy8gdG8gbWFrZSBpdCBhIHByZXJlcXVpc2l0ZSwgd2Ugd2lsbCByZWx5IHVwb24gcmVsZWN0aW9uLgotICAvLwotICBNZXRob2QgZlBhcnNlU29tZVNldHVwPW51bGw7IC8vIFhlcmNlczEgbWV0aG9kCi0gIE1ldGhvZCBmUGFyc2VTb21lPW51bGw7IC8vIFhlcmNlczEgbWV0aG9kCi0gIE9iamVjdCBmUHVsbFBhcnNlckNvbmZpZz1udWxsOyAvLyBYZXJjZXMyIHB1bGwgY29udHJvbCBvYmplY3QKLSAgTWV0aG9kIGZDb25maWdTZXRJbnB1dD1udWxsOyAvLyBYZXJjZXMyIG1ldGhvZAotICBNZXRob2QgZkNvbmZpZ1BhcnNlPW51bGw7IC8vIFhlcmNlczIgbWV0aG9kCi0gIE1ldGhvZCBmU2V0SW5wdXRTb3VyY2U9bnVsbDsgLy8gWGVyY2VzMiBwdWxsIGNvbnRyb2wgbWV0aG9kCi0gIENvbnN0cnVjdG9yIGZDb25maWdJbnB1dFNvdXJjZUN0b3I9bnVsbDsgLy8gWGVyY2VzMiBpbml0aWFsaXphdGlvbiBtZXRob2QKLSAgTWV0aG9kIGZDb25maWdTZXRCeXRlU3RyZWFtPW51bGw7IC8vIFhlcmNlczIgaW5pdGlhbGl6YXRpb24gbWV0aG9kCi0gIE1ldGhvZCBmQ29uZmlnU2V0Q2hhclN0cmVhbT1udWxsOyAvLyBYZXJjZXMyIGluaXRpYWxpemF0aW9uIG1ldGhvZAotICBNZXRob2QgZkNvbmZpZ1NldEVuY29kaW5nPW51bGw7IC8vIFhlcmNlczIgaW5pdGlhbGl6YXRpb24gbWV0aG9kCi0gIE1ldGhvZCBmUmVzZXQ9bnVsbDsgLy8gQm90aCBYZXJjZXMxIGFuZCBYZXJjZXMyLCBidXQgZGlmZi4gc2lnbmF0dXJlcwotCi0gIC8vCi0gIC8vIERhdGEKLSAgLy8KLSAgU0FYUGFyc2VyIGZJbmNyZW1lbnRhbFBhcnNlcjsKLSAgcHJpdmF0ZSBib29sZWFuIGZQYXJzZUluUHJvZ3Jlc3M9ZmFsc2U7Ci0KLSAgLy8KLSAgLy8gQ29uc3RydWN0b3JzCi0gIC8vCi0KLSAgLyoqIENyZWF0ZSBhIEluY3JlbWVudGFsU0FYU291cmNlX1hlcmNlcywgYW5kIGNyZWF0ZSBhIFNBWFBhcnNlcgotICAgKiB0byBnbyB3aXRoIGl0LiBYZXJjZXMyIGluY3JlbWVudGFsIHBhcnNpbmcgaXMgb25seSBzdXBwb3J0ZWQgaWYKLSAgICogdGhpcyBjb25zdHJ1Y3RvciBpcyB1c2VkLCBkdWUgdG8gbGltaXRhdGlvbnMgaW4gdGhlIFhlcmNlczIgQVBJIChhcyBvZgotICAgKiBCZXRhIDMpLiBJZiB5b3UgZG9uJ3QgbGlrZSB0aGF0IHJlc3RyaWN0aW9uLCB0ZWxsIHRoZSBYZXJjZXMgZm9sa3MgdGhhdAotICAgKiB0aGVyZSBzaG91bGQgYmUgYSBzaW1wbGVyIHdheSB0byByZXF1ZXN0IGluY3JlbWVudGFsIFNBWCBwYXJzaW5nLgotICAgKiAqLwotICBwdWJsaWMgSW5jcmVtZW50YWxTQVhTb3VyY2VfWGVyY2VzKCkKLSAgICAgICAgICAgICAgICB0aHJvd3MgTm9TdWNoTWV0aG9kRXhjZXB0aW9uCi0gICAgICAgIHsKLSAgICAgICAgICAgICAgICB0cnkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBYZXJjZXMtMiBpbmNyZW1lbnRhbCBwYXJzaW5nIHN1cHBvcnQgKGFzIG9mIEJldGEgMykKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIENvbnRlbnRIYW5kbGVycyBzdGlsbCBnZXQgc2V0IG9uIGZJbmNyZW1lbnRhbFBhcnNlciAodG8gZ2V0Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBjb252ZXJzaW9uIGZyb20gWE5JIGV2ZW50cyB0byBTQVggZXZlbnRzKSwgYnV0Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBfY29udHJvbF8gZm9yIGluY3JlbWVudGFsIHBhcnNpbmcgbXVzdCBiZSBleGVyY2lzZWQgdmlhIHRoZSBjb25maWcuCi0gICAgICAgICAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgICAgICAgICAgLy8gQXQgdGhpcyB0aW1lIHRoZXJlJ3Mgbm8gd2F5IHRvIHJlYWQgdGhlIGV4aXN0aW5nIGNvbmZpZywgb25seQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gdG8gYXNzZXJ0IGEgbmV3IG9uZS4uLiBhbmQgb25seSB3aGVuIGNyZWF0aW5nIGEgYnJhbmQtbmV3IHBhcnNlci4KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBSZWZsZWN0aW9uIGlzIHVzZWQgdG8gYWxsb3cgdXMgdG8gY29udGludWUgdG8gY29tcGlsZSBhZ2FpbnN0Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBYZXJjZXMxLiBJZi93aGVuIHdlIGNhbiBhYmFuZG9uIHRoZSBvbGRlciB2ZXJzaW9ucyBvZiB0aGUgcGFyc2VyLAotICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhpcyB3aWxsIHNpbXBsaWZ5IHNpZ25pZmljYW50bHkuCi0KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIElmIHdlIGNhbid0IGdldCB0aGUgbWFnaWMgY29uc3RydWN0b3IsIG5vIG5lZWQgdG8gbG9vayBmdXJ0aGVyLgotICAgICAgICAgICAgICAgICAgICAgICAgQ2xhc3MgeG5pQ29uZmlnQ2xhc3M9T2JqZWN0RmFjdG9yeS5maW5kUHJvdmlkZXJDbGFzcygKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAiY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTFBhcnNlckNvbmZpZ3VyYXRpb24iLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUpOwotICAgICAgICAgICAgICAgICAgICAgICAgQ2xhc3NbXSBhcmdzMT17eG5pQ29uZmlnQ2xhc3N9OwotICAgICAgICAgICAgICAgICAgICAgICAgQ29uc3RydWN0b3IgY3Rvcj1TQVhQYXJzZXIuY2xhc3MuZ2V0Q29uc3RydWN0b3IoYXJnczEpOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBCdWlsZCB0aGUgcGFyc2VyIGNvbmZpZ3VyYXRpb24gb2JqZWN0LiBTdGFuZGFyZFBhcnNlckNvbmZpZ3VyYXRpb24KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGhhcHBlbnMgdG8gaW1wbGVtZW50IFhNTFB1bGxQYXJzZXJDb25maWd1cmF0aW9uLCB3aGljaCBpcyB0aGUgQVBJCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyB3ZSdyZSBnb2luZyB0byB3YW50IHRvIHVzZS4KLSAgICAgICAgICAgICAgICAgICAgICAgIENsYXNzIHhuaVN0ZENvbmZpZ0NsYXNzPU9iamVjdEZhY3RvcnkuZmluZFByb3ZpZGVyQ2xhc3MoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgImNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwucGFyc2Vycy5TdGFuZGFyZFBhcnNlckNvbmZpZ3VyYXRpb24iLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUpOwotICAgICAgICAgICAgICAgICAgICAgICAgZlB1bGxQYXJzZXJDb25maWc9eG5pU3RkQ29uZmlnQ2xhc3MubmV3SW5zdGFuY2UoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIE9iamVjdFtdIGFyZ3MyPXtmUHVsbFBhcnNlckNvbmZpZ307Ci0gICAgICAgICAgICAgICAgICAgICAgICBmSW5jcmVtZW50YWxQYXJzZXIgPSAoU0FYUGFyc2VyKWN0b3IubmV3SW5zdGFuY2UoYXJnczIpOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBQcmVsb2FkIGFsbCB0aGUgbmVlZGVkIHRoZSBjb25maWd1cmF0aW9uIG1ldGhvZHMuLi4gSSB3YW50IHRvIGtub3cgdGhleSdyZQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gYWxsIGhlcmUgYmVmb3JlIHdlIGNvbW1pdCB0byB0cnlpbmcgdG8gdXNlIHRoZW0sIGp1c3QgaW4gY2FzZSB0aGUKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIEFQSSBjaGFuZ2VzIGFnYWluLgotICAgICAgICAgICAgICAgICAgICAgICAgQ2xhc3MgZlhuaUlucHV0U291cmNlQ2xhc3M9T2JqZWN0RmFjdG9yeS5maW5kUHJvdmlkZXJDbGFzcygKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAiY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTElucHV0U291cmNlIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIENsYXNzW10gYXJnczM9e2ZYbmlJbnB1dFNvdXJjZUNsYXNzfTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZDb25maWdTZXRJbnB1dD14bmlTdGRDb25maWdDbGFzcy5nZXRNZXRob2QoInNldElucHV0U291cmNlIixhcmdzMyk7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIENsYXNzW10gYXJnczQ9e1N0cmluZy5jbGFzcyxTdHJpbmcuY2xhc3MsU3RyaW5nLmNsYXNzfTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZDb25maWdJbnB1dFNvdXJjZUN0b3I9ZlhuaUlucHV0U291cmNlQ2xhc3MuZ2V0Q29uc3RydWN0b3IoYXJnczQpOwotICAgICAgICAgICAgICAgICAgICAgICAgQ2xhc3NbXSBhcmdzNT17amF2YS5pby5JbnB1dFN0cmVhbS5jbGFzc307Ci0gICAgICAgICAgICAgICAgICAgICAgICBmQ29uZmlnU2V0Qnl0ZVN0cmVhbT1mWG5pSW5wdXRTb3VyY2VDbGFzcy5nZXRNZXRob2QoInNldEJ5dGVTdHJlYW0iLGFyZ3M1KTsKLSAgICAgICAgICAgICAgICAgICAgICAgIENsYXNzW10gYXJnczY9e2phdmEuaW8uUmVhZGVyLmNsYXNzfTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZDb25maWdTZXRDaGFyU3RyZWFtPWZYbmlJbnB1dFNvdXJjZUNsYXNzLmdldE1ldGhvZCgic2V0Q2hhcmFjdGVyU3RyZWFtIixhcmdzNik7Ci0gICAgICAgICAgICAgICAgICAgICAgICBDbGFzc1tdIGFyZ3M3PXtTdHJpbmcuY2xhc3N9OwotICAgICAgICAgICAgICAgICAgICAgICAgZkNvbmZpZ1NldEVuY29kaW5nPWZYbmlJbnB1dFNvdXJjZUNsYXNzLmdldE1ldGhvZCgic2V0RW5jb2RpbmciLGFyZ3M3KTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgQ2xhc3NbXSBhcmdzYj17Qm9vbGVhbi5UWVBFfTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZDb25maWdQYXJzZT14bmlTdGRDb25maWdDbGFzcy5nZXRNZXRob2QoInBhcnNlIixhcmdzYik7Ci0gICAgICAgICAgICAgICAgICAgICAgICBDbGFzc1tdIG5vYXJncz1uZXcgQ2xhc3NbMF07Ci0gICAgICAgICAgICAgICAgICAgICAgICBmUmVzZXQ9ZkluY3JlbWVudGFsUGFyc2VyLmdldENsYXNzKCkuZ2V0TWV0aG9kKCJyZXNldCIsbm9hcmdzKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgY2F0Y2goRXhjZXB0aW9uIGUpCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgLy8gRmFsbGJhY2sgaWYgdGhpcyBmYWlscyAoaW1wbGVtZW50ZWQgaW4gY3JlYXRlSW5jcmVtZW50YWxTQVhTb3VyY2UpIGlzCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyB0byBhdHRlbXB0IFhlcmNlcy0xIGluY3JlbWVudGFsIHNldHVwLiBDYW4ndCBkbyB0YWlsLWNhbGwgaW4KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNvbnN0cnVjdG9yLCBzbyBjcmVhdGUgbmV3LCBjb3B5IFhlcmNlcy0xIGluaXRpYWxpemF0aW9uLAotICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhlbiB0aHJvdyBpdCBhd2F5Li4uIFVnaC4KLSAgICAgICAgICAgICAgICAgICAgICAgIEluY3JlbWVudGFsU0FYU291cmNlX1hlcmNlcyBkdW1teT1uZXcgSW5jcmVtZW50YWxTQVhTb3VyY2VfWGVyY2VzKG5ldyBTQVhQYXJzZXIoKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmZQYXJzZVNvbWVTZXR1cD1kdW1teS5mUGFyc2VTb21lU2V0dXA7Ci0gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmZQYXJzZVNvbWU9ZHVtbXkuZlBhcnNlU29tZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZkluY3JlbWVudGFsUGFyc2VyPWR1bW15LmZJbmNyZW1lbnRhbFBhcnNlcjsKLSAgICAgICAgICAgICAgICB9Ci0gIH0KLQotICAvKiogQ3JlYXRlIGEgSW5jcmVtZW50YWxTQVhTb3VyY2VfWGVyY2VzIHdyYXBwZWQgYXJvdW5kCi0gICAqIGFuIGV4aXN0aW5nIFNBWFBhcnNlci4gQ3VycmVudGx5IHRoaXMgd29ya3Mgb25seSBmb3IgcmVjZW50Ci0gICAqIHJlbGVhc2VzIG9mIFhlcmNlcy0xLiAgWGVyY2VzLTIgaW5jcmVtZW50YWwgaXMgY3VycmVudGx5IHBvc3NpYmxlCi0gICAqIG9ubHkgaWYgd2UgYXJlIGFsbG93ZWQgdG8gY3JlYXRlIHRoZSBwYXJzZXIgaW5zdGFuY2UsIGR1ZSB0bwotICAgKiBsaW1pdGF0aW9ucyBpbiB0aGUgQVBJIGV4cG9zZWQgYnkgWGVyY2VzLTIgQmV0YSAzOyBzZWUgdGhlCi0gICAqIG5vLWFyZ3MgY29uc3RydWN0b3IgZm9yIHRoYXQgY29kZS4KLSAgICoKLSAgICogQGV4Y2VwdGlvbiBpZiB0aGUgU0FYUGFyc2VyIGNsYXNzIGRvZXNuJ3Qgc3VwcG9ydCB0aGUgWGVyY2VzCi0gICAqIGluY3JlbWVudGFsIHBhcnNlIG9wZXJhdGlvbnMuIEluIHRoYXQgY2FzZSwgY2FsbGVyIHNob3VsZAotICAgKiBmYWxsIGJhY2sgdXBvbiB0aGUgSW5jcmVtZW50YWxTQVhTb3VyY2VfRmlsdGVyIGFwcHJvYWNoLgotICAgKiAqLwotICBwdWJsaWMgSW5jcmVtZW50YWxTQVhTb3VyY2VfWGVyY2VzKFNBWFBhcnNlciBwYXJzZXIpCi0gICAgdGhyb3dzIE5vU3VjaE1ldGhvZEV4Y2VwdGlvbgotICB7Ci0gICAgICAgICAgICAgICAgLy8gUmVmbGVjdGlvbiBpcyB1c2VkIHRvIGFsbG93IHVzIHRvIGNvbXBpbGUgYWdhaW5zdAotICAgICAgICAgICAgICAgIC8vIFhlcmNlczIuIElmL3doZW4gd2UgY2FuIGFiYW5kb24gdGhlIG9sZGVyIHZlcnNpb25zIG9mIHRoZSBwYXJzZXIsCi0gICAgICAgICAgICAgICAgLy8gdGhpcyBjb25zdHJ1Y3RvciB3aWxsIHNpbXBseSBoYXZlIHRvIGZhaWwgdW50aWwvdW5sZXNzIHRoZQotICAgICAgICAgICAgICAgIC8vIFhlcmNlczIgaW5jcmVtZW50YWwgc3VwcG9ydCBpcyBtYWRlIGF2YWlsYWJsZSBvbiBwcmV2aW91c2x5Ci0gICAgICAgICAgICAgICAgLy8gY29uc3RydWN0ZWQgU0FYUGFyc2VyIGluc3RhbmNlcy4KLSAgICBmSW5jcmVtZW50YWxQYXJzZXI9cGFyc2VyOwotICAgICAgICAgICAgICAgIENsYXNzIG1lPXBhcnNlci5nZXRDbGFzcygpOwotICAgIENsYXNzW10gcGFybXM9e0lucHV0U291cmNlLmNsYXNzfTsKLSAgICBmUGFyc2VTb21lU2V0dXA9bWUuZ2V0TWV0aG9kKCJwYXJzZVNvbWVTZXR1cCIscGFybXMpOwotICAgIHBhcm1zPW5ldyBDbGFzc1swXTsKLSAgICBmUGFyc2VTb21lPW1lLmdldE1ldGhvZCgicGFyc2VTb21lIixwYXJtcyk7Ci0gICAgLy8gRmFsbGJhY2sgaWYgdGhpcyBmYWlscyAoaW1wbGVtZW50ZWQgaW4gY3JlYXRlSW5jcmVtZW50YWxTQVhTb3VyY2UpIGlzCi0gICAgLy8gdG8gdXNlIEluY3JlbWVudGFsU0FYU291cmNlX0ZpbHRlciByYXRoZXIgdGhhbiBYZXJjZXMtc3BlY2lmaWMgY29kZS4KLSAgfQotCi0gIC8vCi0gIC8vIEZhY3RvcmllcwotICAvLwotICBzdGF0aWMgcHVibGljIEluY3JlbWVudGFsU0FYU291cmNlIGNyZWF0ZUluY3JlbWVudGFsU0FYU291cmNlKCkKLSAgICAgICAgewotICAgICAgICAgICAgICAgIHRyeQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgSW5jcmVtZW50YWxTQVhTb3VyY2VfWGVyY2VzKCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGNhdGNoKE5vU3VjaE1ldGhvZEV4Y2VwdGlvbiBlKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIFhlcmNlcyB2ZXJzaW9uIG1pc21hdGNoOyBuZWl0aGVyIFhlcmNlczEgbm9yIFhlcmNlczIgc3VjY2VlZGVkLgotICAgICAgICAgICAgICAgICAgICAgICAgLy8gRmFsbCBiYWNrIG9uIGZpbHRlcmluZyBzb2x1dGlvbi4KLSAgICAgICAgICAgICAgICAgICAgICAgIEluY3JlbWVudGFsU0FYU291cmNlX0ZpbHRlciBpc3M9bmV3IEluY3JlbWVudGFsU0FYU291cmNlX0ZpbHRlcigpOwotICAgICAgICAgICAgICAgICAgICAgICAgaXNzLnNldFhNTFJlYWRlcihuZXcgU0FYUGFyc2VyKCkpOwotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGlzczsKLSAgICAgICAgICAgICAgICB9Ci0gIH0KLQotICBzdGF0aWMgcHVibGljIEluY3JlbWVudGFsU0FYU291cmNlCi0gIGNyZWF0ZUluY3JlbWVudGFsU0FYU291cmNlKFNBWFBhcnNlciBwYXJzZXIpIHsKLSAgICAgICAgICAgICAgICB0cnkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEluY3JlbWVudGFsU0FYU291cmNlX1hlcmNlcyhwYXJzZXIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBjYXRjaChOb1N1Y2hNZXRob2RFeGNlcHRpb24gZSkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBYZXJjZXMgdmVyc2lvbiBtaXNtYXRjaDsgbmVpdGhlciBYZXJjZXMxIG5vciBYZXJjZXMyIHN1Y2NlZWRlZC4KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIEZhbGwgYmFjayBvbiBmaWx0ZXJpbmcgc29sdXRpb24uCi0gICAgICAgICAgICAgICAgICAgICAgICBJbmNyZW1lbnRhbFNBWFNvdXJjZV9GaWx0ZXIgaXNzPW5ldyBJbmNyZW1lbnRhbFNBWFNvdXJjZV9GaWx0ZXIoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlzcy5zZXRYTUxSZWFkZXIocGFyc2VyKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpc3M7Ci0gICAgICAgICAgICAgICAgfQotICB9Ci0KLSAgLy8KLSAgLy8gUHVibGljIG1ldGhvZHMKLSAgLy8KLQotICAvLyBSZWdpc3RlciBoYW5kbGVyIGRpcmVjdGx5IHdpdGggdGhlIGluY3JlbWVudGFsIHBhcnNlcgotICBwdWJsaWMgdm9pZCBzZXRDb250ZW50SGFuZGxlcihvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciBoYW5kbGVyKQotICB7Ci0gICAgLy8gVHlwZWNhc3QgcmVxdWlyZWQgaW4gWGVyY2VzMjsgU0FYUGFyc2VyIGRvZXNuJ3QgaW5oZXJldCBYTUxSZWFkZXIKLSAgICAvLyAlT1BUJSBDYXN0IGF0IGFzaWdubWVudD8KLSAgICAoKFhNTFJlYWRlcilmSW5jcmVtZW50YWxQYXJzZXIpLnNldENvbnRlbnRIYW5kbGVyKGhhbmRsZXIpOwotICB9Ci0KLSAgLy8gUmVnaXN0ZXIgaGFuZGxlciBkaXJlY3RseSB3aXRoIHRoZSBpbmNyZW1lbnRhbCBwYXJzZXIKLSAgcHVibGljIHZvaWQgc2V0TGV4aWNhbEhhbmRsZXIob3JnLnhtbC5zYXguZXh0LkxleGljYWxIYW5kbGVyIGhhbmRsZXIpCi0gIHsKLSAgICAvLyBOb3Qgc3VwcG9ydGVkIGJ5IGFsbCBTQVgyIHBhcnNlcnMgYnV0IHNob3VsZCB3b3JrIGluIFhlcmNlczoKLSAgICB0cnkKLSAgICB7Ci0gICAgICAvLyBUeXBlY2FzdCByZXF1aXJlZCBpbiBYZXJjZXMyOyBTQVhQYXJzZXIgZG9lc24ndCBpbmhlcmV0IFhNTFJlYWRlcgotICAgICAgLy8gJU9QVCUgQ2FzdCBhdCBhc2lnbm1lbnQ/Ci0gICAgICAoKFhNTFJlYWRlcilmSW5jcmVtZW50YWxQYXJzZXIpLnNldFByb3BlcnR5KCJodHRwOi8veG1sLm9yZy9zYXgvcHJvcGVydGllcy9sZXhpY2FsLWhhbmRsZXIiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZXIpOwotICAgIH0KLSAgICBjYXRjaChvcmcueG1sLnNheC5TQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIGUpCi0gICAgewotICAgICAgLy8gTm90aGluZyB3ZSBjYW4gZG8gYWJvdXQgaXQKLSAgICB9Ci0gICAgY2F0Y2gob3JnLnhtbC5zYXguU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIGUpCi0gICAgewotICAgICAgLy8gTm90aGluZyB3ZSBjYW4gZG8gYWJvdXQgaXQKLSAgICB9Ci0gIH0KLQotICAvLyBSZWdpc3RlciBoYW5kbGVyIGRpcmVjdGx5IHdpdGggdGhlIGluY3JlbWVudGFsIHBhcnNlcgotICBwdWJsaWMgdm9pZCBzZXREVERIYW5kbGVyKG9yZy54bWwuc2F4LkRUREhhbmRsZXIgaGFuZGxlcikKLSAgewotICAgIC8vIFR5cGVjYXN0IHJlcXVpcmVkIGluIFhlcmNlczI7IFNBWFBhcnNlciBkb2Vzbid0IGluaGVyZXQgWE1MUmVhZGVyCi0gICAgLy8gJU9QVCUgQ2FzdCBhdCBhc2lnbm1lbnQ/Ci0gICAgKChYTUxSZWFkZXIpZkluY3JlbWVudGFsUGFyc2VyKS5zZXREVERIYW5kbGVyKGhhbmRsZXIpOwotICB9Ci0KLSAgLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gIC8qKiBzdGFydFBhcnNlKCkgaXMgYSBzaW1wbGUgQVBJIHdoaWNoIHRlbGxzIHRoZSBJbmNyZW1lbnRhbFNBWFNvdXJjZQotICAgKiB0byBiZWdpbiByZWFkaW5nIGEgZG9jdW1lbnQuCi0gICAqCi0gICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uIGlzIHBhcnNlIHRocmVhZCBpcyBhbHJlYWR5IGluIHByb2dyZXNzCi0gICAqIG9yIHBhcnNpbmcgY2FuIG5vdCBiZSBzdGFydGVkLgotICAgKiAqLwotICBwdWJsaWMgdm9pZCBzdGFydFBhcnNlKElucHV0U291cmNlIHNvdXJjZSkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICB7Ci0gICAgaWYgKGZJbmNyZW1lbnRhbFBhcnNlcj09bnVsbCkKLSAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oWE1MTWVzc2FnZXMuY3JlYXRlWE1MTWVzc2FnZShYTUxFcnJvclJlc291cmNlcy5FUl9TVEFSVFBBUlNFX05FRURTX1NBWFBBUlNFUiwgbnVsbCkpOyAvLyJzdGFydFBhcnNlIG5lZWRzIGEgbm9uLW51bGwgU0FYUGFyc2VyLiIpOwotICAgIGlmIChmUGFyc2VJblByb2dyZXNzKQotICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbihYTUxNZXNzYWdlcy5jcmVhdGVYTUxNZXNzYWdlKFhNTEVycm9yUmVzb3VyY2VzLkVSX1NUQVJUUEFSU0VfV0hJTEVfUEFSU0lORywgbnVsbCkpOyAvLyJzdGFydFBhcnNlIG1heSBub3QgYmUgY2FsbGVkIHdoaWxlIHBhcnNpbmcuIik7Ci0KLSAgICBib29sZWFuIG9rPWZhbHNlOwotCi0gICAgdHJ5Ci0gICAgewotICAgICAgb2sgPSBwYXJzZVNvbWVTZXR1cChzb3VyY2UpOwotICAgIH0KLSAgICBjYXRjaChFeGNlcHRpb24gZXgpCi0gICAgewotICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbihleCk7Ci0gICAgfQotCi0gICAgaWYoIW9rKQotICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbihYTUxNZXNzYWdlcy5jcmVhdGVYTUxNZXNzYWdlKFhNTEVycm9yUmVzb3VyY2VzLkVSX0NPVUxEX05PVF9JTklUX1BBUlNFUiwgbnVsbCkpOyAvLyJjb3VsZCBub3QgaW5pdGlhbGl6ZSBwYXJzZXIgd2l0aCIpOwotICB9Ci0KLQotICAvKiogZGVsaXZlck1vcmVOb2RlcygpIGlzIGEgc2ltcGxlIEFQSSB3aGljaCB0ZWxscyB0aGUgY29yb3V0aW5lCi0gICAqIHBhcnNlciB0aGF0IHdlIG5lZWQgbW9yZSBub2Rlcy4gIFRoaXMgaXMgaW50ZW5kZWQgdG8gYmUgY2FsbGVkCi0gICAqIGZyb20gb25lIG9mIG91ciBwYXJ0bmVyIHJvdXRpbmVzLCBhbmQgc2VydmVzIHRvIGVuY2Fwc3VsYXRlIHRoZQotICAgKiBkZXRhaWxzIG9mIGhvdyBpbmNyZW1lbnRhbCBwYXJzaW5nIGhhcyBiZWVuIGFjaGlldmVkLgotICAgKgotICAgKiBAcGFyYW0gcGFyc2Vtb3JlIElmIHRydWUsIHRlbGxzIHRoZSBpbmNyZW1lbnRhbCBwYXJzZXIgdG8gZ2VuZXJhdGUKLSAgICogYW5vdGhlciBjaHVuayBvZiBvdXRwdXQuIElmIGZhbHNlLCB0ZWxscyB0aGUgcGFyc2VyIHRoYXQgd2UncmUKLSAgICogc2F0aXNmaWVkIGFuZCBpdCBjYW4gdGVybWluYXRlIHBhcnNpbmcgb2YgdGhpcyBkb2N1bWVudC4KLSAgICogQHJldHVybiBCb29sZWFuLlRSVUUgaWYgdGhlIENvcm91dGluZVBhcnNlciBiZWxpZXZlcyBtb3JlIGRhdGEgbWF5IGJlIGF2YWlsYWJsZQotICAgKiBmb3IgZnVydGhlciBwYXJzaW5nLiBCb29sZWFuLkZBTFNFIGlmIHBhcnNpbmcgcmFuIHRvIGNvbXBsZXRpb24uCi0gICAqIEV4Y2VwdGlvbiBpZiB0aGUgcGFyc2VyIG9iamVjdGVkIGZvciBzb21lIHJlYXNvbi4KLSAgICogKi8KLSAgcHVibGljIE9iamVjdCBkZWxpdmVyTW9yZU5vZGVzIChib29sZWFuIHBhcnNlbW9yZSkKLSAgewotICAgIGlmKCFwYXJzZW1vcmUpCi0gICAgewotICAgICAgZlBhcnNlSW5Qcm9ncmVzcz1mYWxzZTsKLSAgICAgIHJldHVybiBCb29sZWFuLkZBTFNFOwotICAgIH0KLQotICAgIE9iamVjdCBhcmc7Ci0gICAgdHJ5IHsKLSAgICAgIGJvb2xlYW4ga2VlcGdvaW5nID0gcGFyc2VTb21lKCk7Ci0gICAgICBhcmcgPSBrZWVwZ29pbmcgPyBCb29sZWFuLlRSVUUgOiBCb29sZWFuLkZBTFNFOwotICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBleCkgewotICAgICAgYXJnID0gZXg7Ci0gICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKLSAgICAgIGFyZyA9IGV4OwotICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgewotICAgICAgYXJnID0gbmV3IFNBWEV4Y2VwdGlvbihleCk7Ci0gICAgfQotICAgIHJldHVybiBhcmc7Ci0gIH0KLQotICAgICAgICAvLyBQcml2YXRlIG1ldGhvZHMgLS0gY29udmVuaWVuY2VzIHRvIGhpZGUgdGhlIHJlZmxlY3Rpb24gZGV0YWlscwotICAgICAgICBwcml2YXRlIGJvb2xlYW4gcGFyc2VTb21lU2V0dXAoSW5wdXRTb3VyY2Ugc291cmNlKQotICAgICAgICAgICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24sIElPRXhjZXB0aW9uLCBJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqYXZhLmxhbmcucmVmbGVjdC5JbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqYXZhLmxhbmcuSW5zdGFudGlhdGlvbkV4Y2VwdGlvbgotICAgICAgICB7Ci0gICAgICAgICAgICAgICAgaWYoZkNvbmZpZ1NldElucHV0IT1udWxsKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9idGFpbiBpbnB1dCBmcm9tIFNBWCBpbnB1dFNvdXJjZSBvYmplY3QsIGNvbnN0cnVjdCBYTkkgdmVyc2lvbiBvZgotICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhhdCBvYmplY3QuIExvZ2ljIGFkYXB0ZWQgZnJvbSBYZXJjZXMyLgotICAgICAgICAgICAgICAgICAgICAgICAgT2JqZWN0W10gcGFybXMxPXtzb3VyY2UuZ2V0UHVibGljSWQoKSxzb3VyY2UuZ2V0U3lzdGVtSWQoKSxudWxsfTsKLSAgICAgICAgICAgICAgICAgICAgICAgIE9iamVjdCB4bWxzb3VyY2U9ZkNvbmZpZ0lucHV0U291cmNlQ3Rvci5uZXdJbnN0YW5jZShwYXJtczEpOwotICAgICAgICAgICAgICAgICAgICAgICAgT2JqZWN0W10gcGFybXNhPXtzb3VyY2UuZ2V0Qnl0ZVN0cmVhbSgpfTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZDb25maWdTZXRCeXRlU3RyZWFtLmludm9rZSh4bWxzb3VyY2UscGFybXNhKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHBhcm1zYVswXT1zb3VyY2UuZ2V0Q2hhcmFjdGVyU3RyZWFtKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmQ29uZmlnU2V0Q2hhclN0cmVhbS5pbnZva2UoeG1sc291cmNlLHBhcm1zYSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBwYXJtc2FbMF09c291cmNlLmdldEVuY29kaW5nKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmQ29uZmlnU2V0RW5jb2RpbmcuaW52b2tlKHhtbHNvdXJjZSxwYXJtc2EpOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBCdWd6aWxsYTUyNzIgcGF0Y2ggc3VnZ2VzdGVkIGJ5IFNhbmR5IEdhby4KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIEhhcyB0byBiZSByZWZsZWN0aW9uIHRvIHJ1biB3aXRoIFhlcmNlczIKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFmdGVyIGNvbXBpbGF0aW9uIGFnYWluc3QgWGVyY2VzMS4gb3IgdmljZQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gdmVyc2EsIGR1ZSB0byByZXR1cm4gdHlwZSBtaXNtYXRjaGVzLgotICAgICAgICAgICAgICAgICAgICAgICAgT2JqZWN0W10gbm9wYXJtcz1uZXcgT2JqZWN0WzBdOwotICAgICAgICAgICAgICAgICAgICAgICAgZlJlc2V0Lmludm9rZShmSW5jcmVtZW50YWxQYXJzZXIsbm9wYXJtcyk7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIHBhcm1zYVswXT14bWxzb3VyY2U7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmQ29uZmlnU2V0SW5wdXQuaW52b2tlKGZQdWxsUGFyc2VyQ29uZmlnLHBhcm1zYSk7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vICVSRVZJRVclIERvIGZpcnN0IHB1bGwuIFNob3VsZCB3ZSBpbnN0ZWFkIGp1c3QgcmV0dXJuIHRydWU/Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2VTb21lKCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBPYmplY3RbXSBwYXJtPXtzb3VyY2V9OwotICAgICAgICAgICAgICAgICAgICAgICAgT2JqZWN0IHJldD1mUGFyc2VTb21lU2V0dXAuaW52b2tlKGZJbmNyZW1lbnRhbFBhcnNlcixwYXJtKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoKEJvb2xlYW4pcmV0KS5ib29sZWFuVmFsdWUoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgIH0KLS8vICBXb3VsZCBudWxsIHdvcms/Pz8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBPYmplY3RbXSBub3Bhcm1zPW5ldyBPYmplY3RbMF07Ci0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgT2JqZWN0W10gcGFybXNmYWxzZT17Qm9vbGVhbi5GQUxTRX07Ci0gICAgcHJpdmF0ZSBib29sZWFuIHBhcnNlU29tZSgpCi0gICAgICAgICAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24sIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGphdmEubGFuZy5yZWZsZWN0Lkludm9jYXRpb25UYXJnZXRFeGNlcHRpb24KLSAgICAgICAgewotICAgICAgICAgICAgICAgIC8vIFRha2UgbmV4dCBwYXJzaW5nIHN0ZXAsIHJldHVybiBmYWxzZSBpZmYgcGFyc2luZyBjb21wbGV0ZToKLSAgICAgICAgICAgICAgICBpZihmQ29uZmlnU2V0SW5wdXQhPW51bGwpCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgT2JqZWN0IHJldD0oQm9vbGVhbikoZkNvbmZpZ1BhcnNlLmludm9rZShmUHVsbFBhcnNlckNvbmZpZyxwYXJtc2ZhbHNlKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKChCb29sZWFuKXJldCkuYm9vbGVhblZhbHVlKCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBPYmplY3QgcmV0PWZQYXJzZVNvbWUuaW52b2tlKGZJbmNyZW1lbnRhbFBhcnNlcixub3Bhcm1zKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoKEJvb2xlYW4pcmV0KS5ib29sZWFuVmFsdWUoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotCi0gIC8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICAvKiogU2ltcGxlIHVuaXQgdGVzdC4gQXR0ZW1wdCBjb3JvdXRpbmUgcGFyc2luZyBvZiBkb2N1bWVudCBpbmRpY2F0ZWQKLSAgICogYnkgZmlyc3QgYXJndW1lbnQgKGFzIGEgVVJJKSwgcmVwb3J0IHByb2dyZXNzLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyB2b2lkIF9tYWluKFN0cmluZyBhcmdzW10pCi0gIHsKLSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlN0YXJ0aW5nLi4uIik7Ci0KLSAgICBDb3JvdXRpbmVNYW5hZ2VyIGNvID0gbmV3IENvcm91dGluZU1hbmFnZXIoKTsKLSAgICBpbnQgYXBwQ29yb3V0aW5lSUQgPSBjby5jb19qb2luQ29yb3V0aW5lU2V0KC0xKTsKLSAgICBpZiAoYXBwQ29yb3V0aW5lSUQgPT0gLTEpCi0gICAgewotICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJFUlJPUjogQ291bGRuJ3QgYWxsb2NhdGUgY29yb3V0aW5lIG51bWJlci5cbiIpOwotICAgICAgcmV0dXJuOwotICAgIH0KLSAgICBJbmNyZW1lbnRhbFNBWFNvdXJjZSBwYXJzZXI9Ci0gICAgICBjcmVhdGVJbmNyZW1lbnRhbFNBWFNvdXJjZSgpOwotCi0gICAgLy8gVXNlIGEgc2VyaWFsaXplciBhcyBvdXIgc2FtcGxlIG91dHB1dAotICAgIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplLlhNTFNlcmlhbGl6ZXIgdHJhY2U7Ci0gICAgdHJhY2U9bmV3IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplLlhNTFNlcmlhbGl6ZXIoU3lzdGVtLm91dCxudWxsKTsKLSAgICBwYXJzZXIuc2V0Q29udGVudEhhbmRsZXIodHJhY2UpOwotICAgIHBhcnNlci5zZXRMZXhpY2FsSGFuZGxlcih0cmFjZSk7Ci0KLSAgICAvLyBUZWxsIGNvcm91dGluZSB0byBiZWdpbiBwYXJzaW5nLCBydW4gd2hpbGUgcGFyc2luZyBpcyBpbiBwcm9ncmVzcwotCi0gICAgZm9yKGludCBhcmc9MDthcmc8YXJncy5sZW5ndGg7KythcmcpCi0gICAgewotICAgICAgdHJ5Ci0gICAgICB7Ci0gICAgICAgIElucHV0U291cmNlIHNvdXJjZSA9IG5ldyBJbnB1dFNvdXJjZShhcmdzW2FyZ10pOwotICAgICAgICBPYmplY3QgcmVzdWx0PW51bGw7Ci0gICAgICAgIGJvb2xlYW4gbW9yZT10cnVlOwotICAgICAgICBwYXJzZXIuc3RhcnRQYXJzZShzb3VyY2UpOwotICAgICAgICBmb3IocmVzdWx0ID0gcGFyc2VyLmRlbGl2ZXJNb3JlTm9kZXMobW9yZSk7Ci0gICAgICAgICAgICByZXN1bHQ9PUJvb2xlYW4uVFJVRTsKLSAgICAgICAgICAgIHJlc3VsdCA9IHBhcnNlci5kZWxpdmVyTW9yZU5vZGVzKG1vcmUpKQotICAgICAgICB7Ci0gICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJcblNvbWUgcGFyc2luZyBzdWNjZXNzZnVsLCB0cnlpbmcgbW9yZS5cbiIpOwotCi0gICAgICAgICAgLy8gU3BlY2lhbCB0ZXN0OiBUZXJtaW5hdGUgcGFyc2luZyBlYXJseS4KLSAgICAgICAgICBpZihhcmcrMTxhcmdzLmxlbmd0aCAmJiAiISIuZXF1YWxzKGFyZ3NbYXJnKzFdKSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICArK2FyZzsKLSAgICAgICAgICAgIG1vcmU9ZmFsc2U7Ci0gICAgICAgICAgfQotCi0gICAgICAgIH0KLQotICAgICAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgQm9vbGVhbiAmJiAoKEJvb2xlYW4pcmVzdWx0KT09Qm9vbGVhbi5GQUxTRSkKLSAgICAgICAgewotICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXG5QYXJzZXIgZW5kZWQgKEVPRiBvciBvbiByZXF1ZXN0KS5cbiIpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKHJlc3VsdCA9PSBudWxsKSB7Ci0gICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJcblVORVhQRUNURUQ6IFBhcnNlciBzYXlzIHNodXQgZG93biBwcmVtYXR1cmVseS5cbiIpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIEV4Y2VwdGlvbikgewotICAgICAgICAgIHRocm93IG5ldyBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLldyYXBwZWRSdW50aW1lRXhjZXB0aW9uKChFeGNlcHRpb24pcmVzdWx0KTsKLSAgICAgICAgICAvLyAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlxuUGFyc2VyIHRocmV3IGV4Y2VwdGlvbjoiKTsKLSAgICAgICAgICAvLyAgICAgICAgICAoKEV4Y2VwdGlvbilyZXN1bHQpLnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgICB9Ci0KLSAgICAgIH0KLQotICAgICAgY2F0Y2goU0FYRXhjZXB0aW9uIGUpCi0gICAgICB7Ci0gICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICB9Ci0gICAgfQotCi0gIH0KLQotCi19IC8vIGNsYXNzIEluY3JlbWVudGFsU0FYU291cmNlX1hlcmNlcwpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL3JlZi9Ob2RlTG9jYXRvci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL3JlZi9Ob2RlTG9jYXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyOTg3ZGZkLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9yZWYvTm9kZUxvY2F0b3IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExMiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBOb2RlTG9jYXRvci5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE1IDA4OjE1OjA4IHN1cmVzaF9lbWFpbGlkIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5yZWY7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlNvdXJjZUxvY2F0b3I7Ci0KLS8qKgotICogPGNvZGU+Tm9kZUxvY2F0b3I8L2NvZGU+IG1haW50YWlucyBpbmZvcm1hdGlvbiBvbiBhbiBYTUwgc291cmNlCi0gKiBub2RlLgotICoKLSAqIEBhdXRob3IgPGEgaHJlZj0ibWFpbHRvOm92aWRpdUBjdXAuaHAuY29tIj5PdmlkaXUgUHJlZGVzY3U8L2E+Ci0gKiBAc2luY2UgTWF5IDIzLCAyMDAxCi0gKi8KLXB1YmxpYyBjbGFzcyBOb2RlTG9jYXRvciBpbXBsZW1lbnRzIFNvdXJjZUxvY2F0b3IKLXsKLSAgcHJvdGVjdGVkIFN0cmluZyBtX3B1YmxpY0lkOwotICBwcm90ZWN0ZWQgU3RyaW5nIG1fc3lzdGVtSWQ7Ci0gIHByb3RlY3RlZCBpbnQgbV9saW5lTnVtYmVyOwotICBwcm90ZWN0ZWQgaW50IG1fY29sdW1uTnVtYmVyOwotCi0gIC8qKgotICAgKiBDcmVhdGVzIGEgbmV3IDxjb2RlPk5vZGVMb2NhdG9yPC9jb2RlPiBpbnN0YW5jZS4KLSAgICoKLSAgICogQHBhcmFtIHB1YmxpY0lkIGEgPGNvZGU+U3RyaW5nPC9jb2RlPiB2YWx1ZQotICAgKiBAcGFyYW0gc3lzdGVtSWQgYSA8Y29kZT5TdHJpbmc8L2NvZGU+IHZhbHVlCi0gICAqIEBwYXJhbSBsaW5lTnVtYmVyIGFuIDxjb2RlPmludDwvY29kZT4gdmFsdWUKLSAgICogQHBhcmFtIGNvbHVtbk51bWJlciBhbiA8Y29kZT5pbnQ8L2NvZGU+IHZhbHVlCi0gICAqLwotICBwdWJsaWMgTm9kZUxvY2F0b3IoU3RyaW5nIHB1YmxpY0lkLCBTdHJpbmcgc3lzdGVtSWQsCi0gICAgICAgICAgICAgICAgICAgICBpbnQgbGluZU51bWJlciwgaW50IGNvbHVtbk51bWJlcikKLSAgewotICAgIHRoaXMubV9wdWJsaWNJZCA9IHB1YmxpY0lkOwotICAgIHRoaXMubV9zeXN0ZW1JZCA9IHN5c3RlbUlkOwotICAgIHRoaXMubV9saW5lTnVtYmVyID0gbGluZU51bWJlcjsKLSAgICB0aGlzLm1fY29sdW1uTnVtYmVyID0gY29sdW1uTnVtYmVyOwotICB9Ci0KLSAgLyoqCi0gICAqIDxjb2RlPmdldFB1YmxpY0lkPC9jb2RlPiByZXR1cm5zIHRoZSBwdWJsaWMgSUQgb2YgdGhlIG5vZGUuCi0gICAqCi0gICAqIEByZXR1cm4gYSA8Y29kZT5TdHJpbmc8L2NvZGU+IHZhbHVlCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFB1YmxpY0lkKCkKLSAgewotICAgIHJldHVybiBtX3B1YmxpY0lkOwotICB9Ci0KLSAgLyoqCi0gICAqIDxjb2RlPmdldFN5c3RlbUlkPC9jb2RlPiByZXR1cm5zIHRoZSBzeXN0ZW0gSUQgb2YgdGhlIG5vZGUuCi0gICAqCi0gICAqIEByZXR1cm4gYSA8Y29kZT5TdHJpbmc8L2NvZGU+IHZhbHVlCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFN5c3RlbUlkKCkKLSAgewotICAgIHJldHVybiBtX3N5c3RlbUlkOwotICB9Ci0KLSAgLyoqCi0gICAqIDxjb2RlPmdldExpbmVOdW1iZXI8L2NvZGU+IHJldHVybnMgdGhlIGxpbmUgbnVtYmVyIG9mIHRoZSBub2RlLgotICAgKgotICAgKiBAcmV0dXJuIGFuIDxjb2RlPmludDwvY29kZT4gdmFsdWUKLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0TGluZU51bWJlcigpCi0gIHsKLSAgICByZXR1cm4gbV9saW5lTnVtYmVyOwotICB9Ci0KLSAgLyoqCi0gICAqIDxjb2RlPmdldENvbHVtbk51bWJlcjwvY29kZT4gcmV0dXJucyB0aGUgY29sdW1uIG51bWJlciBvZiB0aGUKLSAgICogbm9kZS4KLSAgICoKLSAgICogQHJldHVybiBhbiA8Y29kZT5pbnQ8L2NvZGU+IHZhbHVlCi0gICAqLwotICBwdWJsaWMgaW50IGdldENvbHVtbk51bWJlcigpCi0gIHsKLSAgICByZXR1cm4gbV9jb2x1bW5OdW1iZXI7Ci0gIH0KLQotICAvKioKLSAgICogPGNvZGU+dG9TdHJpbmc8L2NvZGU+IHJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcwotICAgKiBOb2RlTG9jYXRvciBpbnN0YW5jZS4KLSAgICoKLSAgICogQHJldHVybiBhIDxjb2RlPlN0cmluZzwvY29kZT4gdmFsdWUKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKQotICB7Ci0gICAgcmV0dXJuICJmaWxlICciICsgbV9zeXN0ZW1JZAotICAgICAgKyAiJywgbGluZSAjIiArIG1fbGluZU51bWJlcgotICAgICAgKyAiLCBjb2x1bW4gIyIgKyBtX2NvbHVtbk51bWJlcjsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL3JlZi9kb20yZHRtL0RPTTJEVE0uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9yZWYvZG9tMmR0bS9ET00yRFRNLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDBlODcxZTAuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL3JlZi9kb20yZHRtL0RPTTJEVE0uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE3NjUgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRE9NMkRUTS5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE1IDA4OjE1OjEwIHN1cmVzaF9lbWFpbGlkIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0ucmVmLmRvbTJkdG07Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2VMb2NhdG9yOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uZG9tLkRPTVNvdXJjZTsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1NYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTVdTRmlsdGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLnJlZi5EVE1EZWZhdWx0QmFzZUl0ZXJhdG9yczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5yZWYuRFRNTWFuYWdlckRlZmF1bHQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0ucmVmLkV4cGFuZGVkTmFtZVRhYmxlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLnJlZi5JbmNyZW1lbnRhbFNBWFNvdXJjZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnJlcy5YTUxFcnJvclJlc291cmNlczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnJlcy5YTUxNZXNzYWdlczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLkZhc3RTdHJpbmdCdWZmZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5RTmFtZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLlN0cmluZ0J1ZmZlclBvb2w7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5UcmVlV2Fsa2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuWE1MQ2hhcmFjdGVyUmVjb2duaXplcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLlhNTFN0cmluZzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLlhNTFN0cmluZ0ZhY3Rvcnk7Ci1pbXBvcnQgb3JnLnczYy5kb20uQXR0cjsKLWltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKLWltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudFR5cGU7Ci1pbXBvcnQgb3JnLnczYy5kb20uRWxlbWVudDsKLWltcG9ydCBvcmcudzNjLmRvbS5FbnRpdHk7Ci1pbXBvcnQgb3JnLnczYy5kb20uTmFtZWROb2RlTWFwOwotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci1pbXBvcnQgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXI7Ci0KLS8qKiBUaGUgPGNvZGU+RE9NMkRUTTwvY29kZT4gY2xhc3Mgc2VydmVzIHVwIGEgRE9NJ3MgY29udGVudHMgdmlhIHRoZQotICogRFRNIEFQSS4KLSAqCi0gKiBOb3RlIHRoYXQgaXQgZG9lc24ndCBuZWNlc3NhcmlseSByZXByZXNlbnQgYSBmdWxsIERvY3VtZW50Ci0gKiB0cmVlLiBZb3UgY2FuIHdyYXAgYSBET00yRFRNIGFyb3VuZCBhIHNwZWNpZmljIG5vZGUgYW5kIGl0cyBzdWJ0cmVlCi0gKiBhbmQgdGhlIHJpZ2h0IHRoaW5ncyBzaG91bGQgaGFwcGVuLiAoSSBkb24ndCBfdGhpbmtfIHdlIGN1cnJlbnRseQotICogc3VwcG9ydCBEb2N1bWVudEZyZ21lbnQgbm9kZXMgYXMgcm9vdHMsIHRob3VnaCB0aGF0IG1pZ2h0IGJlIHdvcnRoCi0gKiBjb25zaWRlcmluZy4pCi0gKgotICogTm90ZSB0b28gdGhhdCB3ZSBkbyBub3QgY3VycmVudGx5IGF0dGVtcHQgdG8gdHJhY2sgZG9jdW1lbnQKLSAqIG11dGF0aW9uLiBJZiB5b3UgYWx0ZXIgdGhlIERPTSBhZnRlciB3cmFwcGluZyBET00yRFRNIGFyb3VuZCBpdCwKLSAqIGFsbCBiZXRzIGFyZSBvZmYuCi0gKiAqLwotcHVibGljIGNsYXNzIERPTTJEVE0gZXh0ZW5kcyBEVE1EZWZhdWx0QmFzZUl0ZXJhdG9ycwotewotICBzdGF0aWMgZmluYWwgYm9vbGVhbiBKSktfREVCVUc9ZmFsc2U7Ci0gIHN0YXRpYyBmaW5hbCBib29sZWFuIEpKS19ORVdDT0RFPXRydWU7Ci0KLSAgLyoqIE1hbmVmZXN0IGNvbnN0YW50Ci0gICAqLwotICBzdGF0aWMgZmluYWwgU3RyaW5nIE5BTUVTUEFDRV9ERUNMX05TPSJodHRwOi8vd3d3LnczLm9yZy9YTUwvMTk5OC9uYW1lc3BhY2UiOwotCi0gIC8qKiBUaGUgY3VycmVudCBwb3NpdGlvbiBpbiB0aGUgRE9NIHRyZWUuIExhc3Qgbm9kZSBleGFtaW5lZCBmb3IKLSAgICogcG9zc2libGUgY29weWluZyB0byBEVE0uICovCi0gIHRyYW5zaWVudCBwcml2YXRlIE5vZGUgbV9wb3M7Ci0gIC8qKiBUaGUgY3VycmVudCBwb3NpdGlvbiBpbiB0aGUgRFRNIHRyZWUuIFdobyBjaGlsZHJlbiBnZXQgYXBwZW5kZWQgdG8uICovCi0gIHByaXZhdGUgaW50IG1fbGFzdF9wYXJlbnQ9MDsKLSAgLyoqIFRoZSBjdXJyZW50IHBvc2l0aW9uIGluIHRoZSBEVE0gdHJlZS4gV2hvIGNoaWxkcmVuIHJlZmVyZW5jZSBhcyB0aGVpcgotICAgKiBwcmV2aW91cyBzaWIuICovCi0gIHByaXZhdGUgaW50IG1fbGFzdF9raWQ9TlVMTDsKLQotICAvKiogVGhlIHRvcCBvZiB0aGUgc3VidHJlZS4KLSAgICogJVJFVklFVyU6ICdtYXkgbm90IGJlIHRoZSBzYW1lIGFzIG1fY29udGV4dCBpZiAiLy9mb28iIHBhdHRlcm4uJwotICAgKiAqLwotICB0cmFuc2llbnQgcHJpdmF0ZSBOb2RlIG1fcm9vdDsKLQotICAvKiogVHJ1ZSBpZmYgdGhlIGZpcnN0IGVsZW1lbnQgaGFzIGJlZW4gcHJvY2Vzc2VkLiBUaGlzIGlzIHVzZWQgdG8gY29udHJvbAotICAgICAgc3ludGhlc2lzIG9mIHRoZSBpbXBsaWVkIHhtbDogbmFtZXNwYWNlIGRlY2xhcmF0aW9uIG5vZGUuICovCi0gIGJvb2xlYW4gbV9wcm9jZXNzZWRGaXJzdEVsZW1lbnQ9ZmFsc2U7Ci0KLSAgLyoqIHRydWUgaWYgQUxMIHRoZSBub2RlcyBpbiB0aGUgbV9yb290IHN1YnRyZWUgaGF2ZSBiZWVuIHByb2Nlc3NlZDsKLSAgICogZmFsc2UgaWYgb3VyIGluY3JlbWVudGFsIGJ1aWxkIGhhcyBub3QgeWV0IGZpbmlzaGVkIHNjYW5uaW5nIHRoZQotICAgKiBET00gdHJlZS4gICovCi0gIHRyYW5zaWVudCBwcml2YXRlIGJvb2xlYW4gbV9ub2Rlc0FyZVByb2Nlc3NlZDsKLQotICAvKiogVGhlIG5vZGUgb2JqZWN0cy4gIFRoZSBpbnN0YW5jZSBwYXJ0IG9mIHRoZSBoYW5kbGUgaW5kZXhlcwotICAgKiBkaXJlY3RseSBpbnRvIHRoaXMgdmVjdG9yLiAgRWFjaCBEVE0gbm9kZSBtYXkgYWN0dWFsbHkgYmUKLSAgICogY29tcG9zZWQgb2Ygc2V2ZXJhbCBET00gbm9kZXMgKGZvciBleGFtcGxlLCBpZiBsb2dpY2FsbHktYWRqYWNlbnQKLSAgICogVGV4dC9DREFUQVNlY3Rpb24gbm9kZXMgaW4gdGhlIERPTSBoYXZlIGJlZW4gY29hbGVzY2VkIGludG8gYQotICAgKiBzaW5nbGUgRFRNIFRleHQgbm9kZSk7IHRoaXMgdGFibGUgcG9pbnRzIG9ubHkgdG8gdGhlIGZpcnN0IGluCi0gICAqIHRoYXQgc2VxdWVuY2UuICovCi0gIHByb3RlY3RlZCBWZWN0b3IgbV9ub2RlcyA9IG5ldyBWZWN0b3IoKTsKLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgRE9NMkRUTSBvYmplY3QgZnJvbSBhIERPTSBub2RlLgotICAgKgotICAgKiBAcGFyYW0gbWdyIFRoZSBEVE1NYW5hZ2VyIHdobyBvd25zIHRoaXMgRFRNLgotICAgKiBAcGFyYW0gZG9tU291cmNlIHRoZSBET00gc291cmNlIHRoYXQgdGhpcyBEVE0gd2lsbCB3cmFwLgotICAgKiBAcGFyYW0gZHRtSWRlbnRpdHkgVGhlIERUTSBpZGVudGl0eSBJRCBmb3IgdGhpcyBEVE0uCi0gICAqIEBwYXJhbSB3aGl0ZVNwYWNlRmlsdGVyIFRoZSB3aGl0ZSBzcGFjZSBmaWx0ZXIgZm9yIHRoaXMgRFRNLCB3aGljaCBtYXkKLSAgICogICAgICAgICAgICAgICAgICAgICAgICAgYmUgbnVsbC4KLSAgICogQHBhcmFtIHhzdHJpbmdmYWN0b3J5IFhNTFN0cmluZyBmYWN0b3J5IGZvciBjcmVhdGluZyBjaGFyYWN0ZXIgY29udGVudC4KLSAgICogQHBhcmFtIGRvSW5kZXhpbmcgdHJ1ZSBpZiB0aGUgY2FsbGVyIGNvbnNpZGVycyBpdCB3b3J0aCBpdCB0byB1c2UKLSAgICogICAgICAgICAgICAgICAgICAgaW5kZXhpbmcgc2NoZW1lcy4KLSAgICovCi0gIHB1YmxpYyBET00yRFRNKERUTU1hbmFnZXIgbWdyLCBET01Tb3VyY2UgZG9tU291cmNlLAotICAgICAgICAgICAgICAgICBpbnQgZHRtSWRlbnRpdHksIERUTVdTRmlsdGVyIHdoaXRlU3BhY2VGaWx0ZXIsCi0gICAgICAgICAgICAgICAgIFhNTFN0cmluZ0ZhY3RvcnkgeHN0cmluZ2ZhY3RvcnksCi0gICAgICAgICAgICAgICAgIGJvb2xlYW4gZG9JbmRleGluZykKLSAgewotICAgIHN1cGVyKG1nciwgZG9tU291cmNlLCBkdG1JZGVudGl0eSwgd2hpdGVTcGFjZUZpbHRlciwKLSAgICAgICAgICB4c3RyaW5nZmFjdG9yeSwgZG9JbmRleGluZyk7Ci0KLSAgICAvLyBJbml0aWFsaXplIERPTSBuYXZpZ2F0aW9uCi0gICAgbV9wb3M9bV9yb290ID0gZG9tU291cmNlLmdldE5vZGUoKTsKLSAgICAvLyBJbml0aWFsaXplIERUTSBuYXZpZ2F0aW9uCi0gICAgbV9sYXN0X3BhcmVudD1tX2xhc3Rfa2lkPU5VTEw7Ci0gICAgbV9sYXN0X2tpZD1hZGROb2RlKG1fcm9vdCwgbV9sYXN0X3BhcmVudCxtX2xhc3Rfa2lkLCBOVUxMKTsKLQotICAgIC8vIEFwcGFyZW50bHkgdGhlIGRvbVNvdXJjZSByb290IG1heSBub3QgYWN0dWFsbHkgYmUgdGhlCi0gICAgLy8gRG9jdW1lbnQgbm9kZS4gSWYgaXQncyBhbiBFbGVtZW50IG5vZGUsIHdlIG5lZWQgdG8gaW1tZWRpYXRlbHkKLSAgICAvLyBhZGQgaXRzIGF0dHJpYnV0ZXMuIEFkYXB0ZWQgZnJvbSBuZXh0Tm9kZSgpLgotICAgIC8vICVSRVZJRVclIE1vdmUgdGhpcyBsb2dpYyBpbnRvIGFkZE5vZGUgYW5kIHJlY3Vyc2U/IENsZWFuZXIhCi0gICAgLy8KLSAgICAvLyAoSWYgaXQncyBhbiBFbnRpdHlSZWZlcmVuY2Ugbm9kZSwgd2UncmUgcHJvYmFibHkgc2Nyb2QuIEZvciBub3cKLSAgICAvLyBJJ20ganVzdCBob3Bpbmcgbm9ib2R5IGlzIGV2ZXIgcXVpdGUgdGhhdCBmb29saXNoLi4uICVSRVZJRVclKQotICAgICAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAgICAgLy8gJUlTU1VFJSBXaGF0IGFib3V0IGluaGVyaXRlZCBuYW1lc3BhY2VzIGluIHRoaXMgY2FzZT8KLSAgICAgICAgICAgICAgICAvLyBEbyB3ZSBuZWVkIHRvIHNwZWNpYWwtY2FzZSBpbml0aWFsaXplIHRoZW0gaW50byB0aGUgRFRNIG1vZGVsPwotICAgIGlmKEVMRU1FTlRfTk9ERSA9PSBtX3Jvb3QuZ2V0Tm9kZVR5cGUoKSkKLSAgICB7Ci0gICAgICBOYW1lZE5vZGVNYXAgYXR0cnM9bV9yb290LmdldEF0dHJpYnV0ZXMoKTsKLSAgICAgIGludCBhdHRyc2l6ZT0oYXR0cnM9PW51bGwpID8gMCA6IGF0dHJzLmdldExlbmd0aCgpOwotICAgICAgaWYoYXR0cnNpemU+MCkKLSAgICAgIHsKLSAgICAgICAgaW50IGF0dHJJbmRleD1OVUxMOyAvLyBzdGFydCB3aXRoIG5vIHByZXZpb3VzIHNpYgotICAgICAgICBmb3IoaW50IGk9MDtpPGF0dHJzaXplOysraSkKLSAgICAgICAgewotICAgICAgICAgIC8vIE5vIG5lZWQgdG8gZm9yY2Ugbm9kZXR5cGUgaW4gdGhpcyBjYXNlOwotICAgICAgICAgIC8vIGFkZE5vZGUoKSB3aWxsIHRha2UgY2FyZSBvZiBzd2l0Y2hpbmcgaXQgZnJvbQotICAgICAgICAgIC8vIEF0dHIgdG8gTmFtZXNwYWNlIGlmIG5lY2Vzc2FyeS4KLSAgICAgICAgICBhdHRySW5kZXg9YWRkTm9kZShhdHRycy5pdGVtKGkpLDAsYXR0ckluZGV4LE5VTEwpOwotICAgICAgICAgIG1fZmlyc3RjaC5zZXRFbGVtZW50QXQoRFRNLk5VTEwsYXR0ckluZGV4KTsKLSAgICAgICAgfQotICAgICAgICAvLyBUZXJtaW5hdGUgbGlzdCBvZiBhdHRycywgYW5kIG1ha2Ugc3VyZSB0aGV5IGFyZW4ndAotICAgICAgICAvLyBjb25zaWRlcmVkIGNoaWxkcmVuIG9mIHRoZSBlbGVtZW50Ci0gICAgICAgIG1fbmV4dHNpYi5zZXRFbGVtZW50QXQoRFRNLk5VTEwsYXR0ckluZGV4KTsKLQotICAgICAgICAvLyBJTVBPUlRBTlQ6IFRoaXMgZG9lcyBOT1QgY2hhbmdlIG1fbGFzdF9wYXJlbnQgb3IgbV9sYXN0X2tpZCEKLSAgICAgIH0gLy8gaWYgYXR0cnMgZXhpc3QKLSAgICB9IC8vaWYoRUxFTUVOVF9OT0RFKQotCi0gICAgLy8gSW5pdGlhbGl6ZSBEVE0tY29tcGxldGVkIHN0YXR1cwotICAgIG1fbm9kZXNBcmVQcm9jZXNzZWQgPSBmYWxzZTsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgdGhlIG5vZGUgbWFwIGZyb20gdGhlIG5vZGUuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlIFRoZSBub2RlIHRoYXQgaXMgdG8gYmUgYWRkZWQgdG8gdGhlIERUTS4KLSAgICogQHBhcmFtIHBhcmVudEluZGV4IFRoZSBjdXJyZW50IHBhcmVudCBpbmRleC4KLSAgICogQHBhcmFtIHByZXZpb3VzU2libGluZyBUaGUgcHJldmlvdXMgc2libGluZyBpbmRleC4KLSAgICogQHBhcmFtIGZvcmNlTm9kZVR5cGUgSWYgbm90IERUTS5OVUxMLCBvdmVycmlkZXMgdGhlIERPTSBub2RlIHR5cGUuCi0gICAqICAgIFVzZWQgdG8gZm9yY2Ugbm9kZXMgdG8gVGV4dCByYXRoZXIgdGhhbiBDREFUQVNlY3Rpb24gd2hlbiB0aGVpcgotICAgKiAgICBjb2FsZXNjZWQgdmFsdWUgaW5jbHVkZXMgb3JkaW5hcnkgVGV4dCBub2RlcyAoY3VycmVudCBEVE0gYmVoYXZpb3IpLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBpbmRleCBpZGVudGl0eSBvZiB0aGUgbm9kZSB0aGF0IHdhcyBhZGRlZC4KLSAgICovCi0gIHByb3RlY3RlZCBpbnQgYWRkTm9kZShOb2RlIG5vZGUsIGludCBwYXJlbnRJbmRleCwKLSAgICAgICAgICAgICAgICAgICAgICAgIGludCBwcmV2aW91c1NpYmxpbmcsIGludCBmb3JjZU5vZGVUeXBlKQotICB7Ci0gICAgaW50IG5vZGVJbmRleCA9IG1fbm9kZXMuc2l6ZSgpOwotCi0gICAgLy8gSGF2ZSB3ZSBvdmVyZmxvd2VkIGEgRFRNIElkZW50aXR5J3MgYWRkcmVzc2luZyByYW5nZT8KLSAgICBpZihtX2R0bUlkZW50LnNpemUoKSA9PSAobm9kZUluZGV4Pj4+RFRNTWFuYWdlci5JREVOVF9EVE1fTk9ERV9CSVRTKSkKLSAgICB7Ci0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgaWYobV9tZ3I9PW51bGwpCi0gICAgICAgICAgdGhyb3cgbmV3IENsYXNzQ2FzdEV4Y2VwdGlvbigpOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEhhbmRsZSBhcyBFeHRlbmRlZCBBZGRyZXNzaW5nCi0gICAgICAgIERUTU1hbmFnZXJEZWZhdWx0IG1nckQ9KERUTU1hbmFnZXJEZWZhdWx0KW1fbWdyOwotICAgICAgICBpbnQgaWQ9bWdyRC5nZXRGaXJzdEZyZWVEVE1JRCgpOwotICAgICAgICBtZ3JELmFkZERUTSh0aGlzLGlkLG5vZGVJbmRleCk7Ci0gICAgICAgIG1fZHRtSWRlbnQuYWRkRWxlbWVudChpZDw8RFRNTWFuYWdlci5JREVOVF9EVE1fTk9ERV9CSVRTKTsKLSAgICAgIH0KLSAgICAgIGNhdGNoKENsYXNzQ2FzdEV4Y2VwdGlvbiBlKQotICAgICAgewotICAgICAgICAvLyAlUkVWSUVXJSBXcm9uZyBlcnJvciBtZXNzYWdlLCBidXQgSSd2ZSBiZWVuIHRvbGQgd2UncmUgdHJ5aW5nCi0gICAgICAgIC8vIG5vdCB0byBhZGQgbWVzc2FnZXMgcmlnaHQgbm90IGZvciBJMThOIHJlYXNvbnMuCi0gICAgICAgIC8vICVSRVZJRVclIFNob3VsZCB0aGlzIGJlIGEgRmF0YWwgRXJyb3I/Ci0gICAgICAgIGVycm9yKFhNTE1lc3NhZ2VzLmNyZWF0ZVhNTE1lc3NhZ2UoWE1MRXJyb3JSZXNvdXJjZXMuRVJfTk9fRFRNSURTX0FWQUlMLCBudWxsKSk7Ly8iTm8gbW9yZSBEVE0gSURzIGFyZSBhdmFpbGFibGUiOwotICAgICAgfQotICAgIH0KLQotICAgIG1fc2l6ZSsrOwotICAgIC8vIGVuc3VyZVNpemUobm9kZUluZGV4KTsKLQotICAgIGludCB0eXBlOwotICAgIGlmKE5VTEw9PWZvcmNlTm9kZVR5cGUpCi0gICAgICAgIHR5cGUgPSBub2RlLmdldE5vZGVUeXBlKCk7Ci0gICAgZWxzZQotICAgICAgICB0eXBlPWZvcmNlTm9kZVR5cGU7Ci0KLSAgICAvLyAlUkVWSUVXJSBUaGUgTmFtZXNwYWNlIFNwZWMgY3VycmVudGx5IHNheXMgdGhhdCBOYW1lc3BhY2VzIGFyZQotICAgIC8vIHByb2Nlc3NlZCBpbiBhIG5vbi1uYW1lc3BhY2UtYXdhcmUgbWFubmVyLCBieSBtYXRjaGluZyB0aGUKLSAgICAvLyBRTmFtZSwgZXZlbiB0aG91Z2ggdGhlcmUgaXMgaW4gZmFjdCBhIG5hbWVzcGFjZSBhc3NpZ25lZCB0bwotICAgIC8vIHRoZXNlIG5vZGVzIGluIHRoZSBET00uIElmIGFuZCB3aGVuIHRoYXQgY2hhbmdlcywgd2Ugd2lsbCBoYXZlCi0gICAgLy8gdG8gY29uc2lkZXIgd2hldGhlciB3ZSBjaGVjayB0aGUgbmFtZXNwYWNlLWZvci1uYW1lc3BhY2VzCi0gICAgLy8gcmF0aGVyIHRoYW4gdGhlIG5vZGUgbmFtZS4KLSAgICAvLwotICAgIC8vICVUQkQlIE5vdGUgdGhhdCB0aGUgRE9NIGRvZXMgbm90IG5lY2Vzc2FyaWx5IGV4cGxpY2l0bHkgZGVjbGFyZQotICAgIC8vIGFsbCB0aGUgbmFtZXNwYWNlcyBpdCB1c2VzLiBET00gTGV2ZWwgMyB3aWxsIGludHJvZHVjZSBhCi0gICAgLy8gbmFtZXNwYWNlLW5vcm1hbGl6YXRpb24gb3BlcmF0aW9uIHdoaWNoIHJlY29uY2lsZXMgdGhhdCwgYW5kIHdlCi0gICAgLy8gY2FuIHJlcXVlc3QgdGhhdCB1c2VycyBpbnZva2UgaXQgb3Igb3RoZXJ3aXNlIGVuc3VyZSB0aGF0IHRoZQotICAgIC8vIHRyZWUgaXMgbmFtZXNwYWNlLXdlbGwtZm9ybWVkIGJlZm9yZSBwYXNzaW5nIHRoZSBET00gdG8gWGFsYW4uCi0gICAgLy8gQnV0IGlmIHRoZXkgZG9uJ3QsIHdoYXQgc2hvdWxkIHdlIGRvIGFib3V0IGl0PyBXZSBwcm9iYWJseQotICAgIC8vIGRvbid0IHdhbnQgdG8gYWx0ZXIgdGhlIHNvdXJjZSBET00gKGFuZCBtYXkgbm90IGJlIGFibGUgdG8gZG8KLSAgICAvLyBzbyBpZiBpdCdzIHJlYWQtb25seSkuIFRoZSBiZXN0IGF2YWlsYWJsZSBhbnN3ZXIgbWlnaHQgYmUgdG8KLSAgICAvLyBzeW50aGVzaXplIGFkZGl0aW9uYWwgRFRNIE5hbWVzcGFjZSBOb2RlcyB0aGF0IGRvbid0IGNvcnJlc3BvbmQKLSAgICAvLyB0byBET00gQXR0ciBOb2Rlcy4KLSAgICBpZiAoTm9kZS5BVFRSSUJVVEVfTk9ERSA9PSB0eXBlKQotICAgIHsKLSAgICAgIFN0cmluZyBuYW1lID0gbm9kZS5nZXROb2RlTmFtZSgpOwotCi0gICAgICBpZiAobmFtZS5zdGFydHNXaXRoKCJ4bWxuczoiKSB8fCBuYW1lLmVxdWFscygieG1sbnMiKSkKLSAgICAgIHsKLSAgICAgICAgdHlwZSA9IERUTS5OQU1FU1BBQ0VfTk9ERTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICBtX25vZGVzLmFkZEVsZW1lbnQobm9kZSk7Ci0KLSAgICBtX2ZpcnN0Y2guc2V0RWxlbWVudEF0KE5PVFBST0NFU1NFRCxub2RlSW5kZXgpOwotICAgIG1fbmV4dHNpYi5zZXRFbGVtZW50QXQoTk9UUFJPQ0VTU0VELG5vZGVJbmRleCk7Ci0gICAgbV9wcmV2c2liLnNldEVsZW1lbnRBdChwcmV2aW91c1NpYmxpbmcsbm9kZUluZGV4KTsKLSAgICBtX3BhcmVudC5zZXRFbGVtZW50QXQocGFyZW50SW5kZXgsbm9kZUluZGV4KTsKLQotICAgIGlmKERUTS5OVUxMICE9IHBhcmVudEluZGV4ICYmCi0gICAgICAgdHlwZSAhPSBEVE0uQVRUUklCVVRFX05PREUgJiYKLSAgICAgICB0eXBlICE9IERUTS5OQU1FU1BBQ0VfTk9ERSkKLSAgICB7Ci0gICAgICAvLyBJZiB0aGUgRFRNIHBhcmVudCBoYWQgbm8gY2hpbGRyZW4sIHRoaXMgYmVjb21lcyBpdHMgZmlyc3QgY2hpbGQuCi0gICAgICBpZihOT1RQUk9DRVNTRUQgPT0gbV9maXJzdGNoLmVsZW1lbnRBdChwYXJlbnRJbmRleCkpCi0gICAgICAgIG1fZmlyc3RjaC5zZXRFbGVtZW50QXQobm9kZUluZGV4LHBhcmVudEluZGV4KTsKLSAgICB9Ci0KLSAgICBTdHJpbmcgbnNVUkkgPSBub2RlLmdldE5hbWVzcGFjZVVSSSgpOwotCi0gICAgLy8gRGVhbCB3aXRoIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gTmFtZXNwYWNlIHNwZWMgYW5kIFhTTFQKLSAgICAvLyBkZWZpbml0aW9ucyBvZiBsb2NhbCBuYW1lLiAoVGhlIGZvcm1lciBzYXlzIFBJcyBkb24ndCBoYXZlCi0gICAgLy8gbG9jYWxuYW1lczsgdGhlIGxhdHRlciBzYXlzIHRoZXkgZG8uKQotICAgIFN0cmluZyBsb2NhbE5hbWUgPSAgKHR5cGUgPT0gTm9kZS5QUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREUpID8KLSAgICAgICAgICAgICAgICAgICAgICAgICBub2RlLmdldE5vZGVOYW1lKCkgOgotICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUuZ2V0TG9jYWxOYW1lKCk7Ci0KLSAgICAvLyBIYWNrIHRvIG1ha2UgRE9NMSBzb3J0IG9mIHdvcmsuLi4KLSAgICBpZigoKHR5cGUgPT0gTm9kZS5FTEVNRU5UX05PREUpIHx8ICh0eXBlID09IE5vZGUuQVRUUklCVVRFX05PREUpKQotICAgICAgICAmJiBudWxsID09IGxvY2FsTmFtZSkKLSAgICAgIGxvY2FsTmFtZSA9IG5vZGUuZ2V0Tm9kZU5hbWUoKTsgLy8gLXNiCi0KLSAgICBFeHBhbmRlZE5hbWVUYWJsZSBleG50ID0gbV9leHBhbmRlZE5hbWVUYWJsZTsKLQotICAgIC8vICVUQkQlIE5vZGVzIGNyZWF0ZWQgd2l0aCB0aGUgb2xkIG5vbi1uYW1lc3BhY2UtYXdhcmUgRE9NCi0gICAgLy8gY2FsbHMgY3JlYXRlRWxlbWVudCgpIGFuZCBjcmVhdGVBdHRyaWJ1dGUoKSB3aWxsIG5ldmVyIGhhdmUgYQotICAgIC8vIGxvY2FsbmFtZS4gVGhhdCB3aWxsIGNhdXNlIHRoZWlyIGV4cGFuZGVkTmFtZUlEIHRvIGJlIGp1c3QgdGhlCi0gICAgLy8gbm9kZVR5cGUuLi4gd2hpY2ggd2lsbCBrZWVwIHRoZW0gZnJvbSBiZWluZyBtYXRjaGVkCi0gICAgLy8gc3VjY2Vzc2Z1bGx5IGJ5IG5hbWUuIFNpbmNlIHRoZSBET00gbWFrZXMgbm8gcHJvbWlzZSB0aGF0Ci0gICAgLy8gdGhvc2Ugd2lsbCBwYXJ0aWNpcGF0ZSBpbiBuYW1lc3BhY2UgcHJvY2Vzc2luZywgdGhpcyBpcwotICAgIC8vIG9mZmljaWFsbHkgYWNjZXB0ZWQgYXMgTm90IE91ciBGYXVsdC4gQnV0IGl0IG1pZ2h0IGJlIG5pY2UgdG8KLSAgICAvLyBpc3N1ZSBhIGRpYWdub3N0aWMgbWVzc2FnZSEKLSAgICBpZihub2RlLmdldExvY2FsTmFtZSgpPT1udWxsICYmCi0gICAgICAgKHR5cGU9PU5vZGUuRUxFTUVOVF9OT0RFIHx8IHR5cGU9PU5vZGUuQVRUUklCVVRFX05PREUpKQotICAgICAgewotICAgICAgICAvLyB3YXJuaW5nKCJET00gJ2xldmVsIDEnIG5vZGUgIitub2RlLmdldE5vZGVOYW1lKCkrIiB3b24ndCBiZSBtYXBwZWQgcHJvcGVybHkgaW4gRE9NMkRUTS4iKTsKLSAgICAgIH0KLQotICAgIGludCBleHBhbmRlZE5hbWVJRCA9IChudWxsICE9IGxvY2FsTmFtZSkKLSAgICAgICA/IGV4bnQuZ2V0RXhwYW5kZWRUeXBlSUQobnNVUkksIGxvY2FsTmFtZSwgdHlwZSkgOgotICAgICAgICAgZXhudC5nZXRFeHBhbmRlZFR5cGVJRCh0eXBlKTsKLQotICAgIG1fZXhwdHlwZS5zZXRFbGVtZW50QXQoZXhwYW5kZWROYW1lSUQsbm9kZUluZGV4KTsKLQotICAgIGluZGV4Tm9kZShleHBhbmRlZE5hbWVJRCwgbm9kZUluZGV4KTsKLQotICAgIGlmIChEVE0uTlVMTCAhPSBwcmV2aW91c1NpYmxpbmcpCi0gICAgICBtX25leHRzaWIuc2V0RWxlbWVudEF0KG5vZGVJbmRleCxwcmV2aW91c1NpYmxpbmcpOwotCi0gICAgLy8gVGhpcyBzaG91bGQgYmUgZG9uZSBhZnRlciBtX2V4cHR5cGUgaGFzIGJlZW4gc2V0LCBhbmQgcHJvYmFibHkgc2hvdWxkCi0gICAgLy8gYWx3YXlzIGJlIHRoZSBsYXN0IHRoaW5nIHdlIGRvCi0gICAgaWYgKHR5cGUgPT0gRFRNLk5BTUVTUEFDRV9OT0RFKQotICAgICAgICBkZWNsYXJlTmFtZXNwYWNlSW5Db250ZXh0KHBhcmVudEluZGV4LG5vZGVJbmRleCk7Ci0KLSAgICByZXR1cm4gbm9kZUluZGV4OwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbnVtYmVyIG9mIG5vZGVzIHRoYXQgaGF2ZSBiZWVuIGFkZGVkLgotICAgKi8KLSAgcHVibGljIGludCBnZXROdW1iZXJPZk5vZGVzKCkKLSAgewotICAgIHJldHVybiBtX25vZGVzLnNpemUoKTsKLSAgfQotCi0gLyoqCi0gICAqIFRoaXMgbWV0aG9kIGl0ZXJhdGVzIHRvIHRoZSBuZXh0IG5vZGUgdGhhdCB3aWxsIGJlIGFkZGVkIHRvIHRoZSB0YWJsZS4KLSAgICogRWFjaCBjYWxsIHRvIHRoaXMgbWV0aG9kIGFkZHMgYSBuZXcgbm9kZSB0byB0aGUgdGFibGUsIHVubGVzcyB0aGUgZW5kCi0gICAqIGlzIHJlYWNoZWQsIGluIHdoaWNoIGNhc2UgaXQgcmV0dXJucyBudWxsLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSB0cnVlIGlmIGEgbmV4dCBub2RlIGlzIGZvdW5kIG9yIGZhbHNlIGlmCi0gICAqICAgICAgICAgdGhlcmUgYXJlIG5vIG1vcmUgbm9kZXMuCi0gICAqLwotICBwcm90ZWN0ZWQgYm9vbGVhbiBuZXh0Tm9kZSgpCi0gIHsKLSAgICAvLyBOb24tcmVjdXJzaXZlIG9uZS1mZXRjaC1hdC1hLXRpbWUgZGVwdGgtZmlyc3QgdHJhdmVyc2FsIHdpdGgKLSAgICAvLyBhdHRyaWJ1dGUvbmFtZXNwYWNlIG5vZGVzIGFuZCB3aGl0ZS1zcGFjZSBzdHJpcHBpbmcuCi0gICAgLy8gTmF2aWdhdGluZyB0aGUgRE9NIGlzIHNpbXBsZSwgbmF2aWdhdGluZyB0aGUgRFRNIGlzIHNpbXBsZTsKLSAgICAvLyBrZWVwaW5nIHRyYWNrIG9mIGJvdGggYXQgb25jZSBpcyBhIHRyaWZsZSBiYXJvcXVlIGJ1dCBhdCBsZWFzdAotICAgIC8vIHdlJ3ZlIGF2b2lkZWQgbW9zdCBvZiB0aGUgc3BlY2lhbCBjYXNlcy4KLSAgICBpZiAobV9ub2Rlc0FyZVByb2Nlc3NlZCkKLSAgICAgIHJldHVybiBmYWxzZTsKLQotICAgIC8vICVSRVZJRVclIElzIHRoaXMgbG9jYWwgY29weSBSZWFsbHkgVXNlZnVsIGZyb20gYSBwZXJmb3JtYW5jZQotICAgIC8vIHBvaW50IG9mIHZpZXc/ICBPciBpcyB0aGlzIGEgZmFsc2UgbWljcm9vcHRpbWl6YXRpb24/Ci0gICAgTm9kZSBwb3M9bV9wb3M7Ci0gICAgTm9kZSBuZXh0PW51bGw7Ci0gICAgaW50IG5leHR0eXBlPU5VTEw7Ci0KLSAgICAvLyBOYXZpZ2F0ZSBET00gdHJlZQotICAgIGRvCi0gICAgICB7Ci0gICAgICAgIC8vIExvb2sgZG93biB0byBmaXJzdCBjaGlsZC4KLSAgICAgICAgaWYgKHBvcy5oYXNDaGlsZE5vZGVzKCkpCi0gICAgICAgICAgewotICAgICAgICAgICAgbmV4dCA9IHBvcy5nZXRGaXJzdENoaWxkKCk7Ci0KLSAgICAgICAgICAgIC8vICVSRVZJRVclIFRoZXJlJ3MgcHJvYmFibHkgYSBtb3JlIGVsZWdhbnQgd2F5IHRvIHNraXAKLSAgICAgICAgICAgIC8vIHRoZSBkb2N0eXBlLiAoSnVzdCBsZXQgaXQgZ28gYW5kIFN1cHByZXNzIGl0PwotICAgICAgICAgICAgaWYobmV4dCE9bnVsbCAmJiBET0NVTUVOVF9UWVBFX05PREU9PW5leHQuZ2V0Tm9kZVR5cGUoKSkKLSAgICAgICAgICAgICAgbmV4dD1uZXh0LmdldE5leHRTaWJsaW5nKCk7Ci0KLSAgICAgICAgICAgIC8vIFB1c2ggRFRNIGNvbnRleHQgLS0gZXhjZXB0IGZvciBjaGlsZHJlbiBvZiBFbnRpdHkgUmVmZXJlbmNlcywKLSAgICAgICAgICAgIC8vIHdoaWNoIGhhdmUgbm8gRFRNIGVxdWl2YWxlbnQgYW5kIGNhdXNlIG5vIERUTSBuYXZpZ2F0aW9uLgotICAgICAgICAgICAgaWYoRU5USVRZX1JFRkVSRU5DRV9OT0RFIT1wb3MuZ2V0Tm9kZVR5cGUoKSkKLSAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIG1fbGFzdF9wYXJlbnQ9bV9sYXN0X2tpZDsKLSAgICAgICAgICAgICAgICBtX2xhc3Rfa2lkPU5VTEw7Ci0gICAgICAgICAgICAgICAgLy8gV2hpdGVzcGFjZS1oYW5kbGVyIGNvbnRleHQgc3RhY2tpbmcKLSAgICAgICAgICAgICAgICBpZihudWxsICE9IG1fd3NmaWx0ZXIpCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgc2hvcnQgd3N2ID0KLSAgICAgICAgICAgICAgICAgICAgbV93c2ZpbHRlci5nZXRTaG91bGRTdHJpcFNwYWNlKG1ha2VOb2RlSGFuZGxlKG1fbGFzdF9wYXJlbnQpLHRoaXMpOwotICAgICAgICAgICAgICAgICAgYm9vbGVhbiBzaG91bGRTdHJpcCA9IChEVE1XU0ZpbHRlci5JTkhFUklUID09IHdzdikKLSAgICAgICAgICAgICAgICAgICAgPyBnZXRTaG91bGRTdHJpcFdoaXRlc3BhY2UoKQotICAgICAgICAgICAgICAgICAgICA6IChEVE1XU0ZpbHRlci5TVFJJUCA9PSB3c3YpOwotICAgICAgICAgICAgICAgICAgcHVzaFNob3VsZFN0cmlwV2hpdGVzcGFjZShzaG91bGRTdHJpcCk7Ci0gICAgICAgICAgICAgICAgfSAvLyBpZihtX3dzZmlsdGVyKQotICAgICAgICAgICAgICB9Ci0gICAgICAgICAgfQotCi0gICAgICAgIC8vIElmIHRoYXQgZmFpbHMsIGxvb2sgdXAgYW5kIHJpZ2h0IChidXQgbm90IHBhc3Qgcm9vdCEpCi0gICAgICAgIGVsc2UKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBpZihtX2xhc3Rfa2lkIT1OVUxMKQotICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgLy8gTGFzdCBub2RlIHBvc3RlZCBhdCB0aGlzIGxldmVsIGhhZCBubyBtb3JlIGNoaWxkcmVuCi0gICAgICAgICAgICAgICAgLy8gSWYgaXQgaGFzIF9ub18gY2hpbGRyZW4sIHdlIG5lZWQgdG8gcmVjb3JkIHRoYXQuCi0gICAgICAgICAgICAgICAgaWYobV9maXJzdGNoLmVsZW1lbnRBdChtX2xhc3Rfa2lkKT09Tk9UUFJPQ0VTU0VEKQotICAgICAgICAgICAgICAgICAgbV9maXJzdGNoLnNldEVsZW1lbnRBdChOVUxMLG1fbGFzdF9raWQpOwotICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIHdoaWxlKG1fbGFzdF9wYXJlbnQgIT0gTlVMTCkKLSAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIC8vICVSRVZJRVclIFRoZXJlJ3MgcHJvYmFibHkgYSBtb3JlIGVsZWdhbnQgd2F5IHRvCi0gICAgICAgICAgICAgICAgLy8gc2tpcCB0aGUgZG9jdHlwZS4gKEp1c3QgbGV0IGl0IGdvIGFuZCBTdXBwcmVzcyBpdD8KLSAgICAgICAgICAgICAgICBuZXh0ID0gcG9zLmdldE5leHRTaWJsaW5nKCk7Ci0gICAgICAgICAgICAgICAgaWYobmV4dCE9bnVsbCAmJiBET0NVTUVOVF9UWVBFX05PREU9PW5leHQuZ2V0Tm9kZVR5cGUoKSkKLSAgICAgICAgICAgICAgICAgIG5leHQ9bmV4dC5nZXROZXh0U2libGluZygpOwotCi0gICAgICAgICAgICAgICAgaWYobmV4dCE9bnVsbCkKLSAgICAgICAgICAgICAgICAgIGJyZWFrOyAvLyBGb3VuZCBpdCEKLQotICAgICAgICAgICAgICAgIC8vIE5vIG5leHQtc2libGluZyBmb3VuZC4gUG9wIHRoZSBET00uCi0gICAgICAgICAgICAgICAgcG9zPXBvcy5nZXRQYXJlbnROb2RlKCk7Ci0gICAgICAgICAgICAgICAgaWYocG9zPT1udWxsKQotICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAvLyAlVEJEJSBTaG91bGQgbmV2ZXIgYXJpc2UsIGJ1dCBJIHdhbnQgdG8gYmUgc3VyZSBvZiB0aGF0Li4uCi0gICAgICAgICAgICAgICAgICAgIGlmKEpKS19ERUJVRykKLSAgICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIioqKioqIERPTTJEVE0gUG9wIENvbnRyb2wgRmxvdyBwcm9ibGVtIik7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmb3IoOzspOyAvLyBGcmVlemUgcmlnaHQgaGVyZSEKLSAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyBUaGUgb25seSBwYXJlbnRzIGluIHRoZSBEVE0gYXJlIEVsZW1lbnRzLiAgSG93ZXZlciwKLSAgICAgICAgICAgICAgICAvLyB0aGUgRE9NIGNvdWxkIGNvbnRhaW4gRW50aXR5UmVmZXJlbmNlcy4gIElmIHdlCi0gICAgICAgICAgICAgICAgLy8gZW5jb3VudGVyIG9uZSwgcG9wIGl0IF93aXRob3V0XyBwb3BwaW5nIERUTS4KLSAgICAgICAgICAgICAgICBpZihwb3MhPW51bGwgJiYgRU5USVRZX1JFRkVSRU5DRV9OT0RFID09IHBvcy5nZXROb2RlVHlwZSgpKQotICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAvLyBOb3RoaW5nIG5lZWRzIGRvaW5nCi0gICAgICAgICAgICAgICAgICAgIGlmKEpKS19ERUJVRykKLSAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIioqKioqIERPTTJEVE0gcG9wcGluZyBFbnRSZWYiKTsKLSAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIHBvcFNob3VsZFN0cmlwV2hpdGVzcGFjZSgpOwotICAgICAgICAgICAgICAgICAgICAvLyBGaXggYW5kIHBvcCBEVE0KLSAgICAgICAgICAgICAgICAgICAgaWYobV9sYXN0X2tpZD09TlVMTCkKLSAgICAgICAgICAgICAgICAgICAgICBtX2ZpcnN0Y2guc2V0RWxlbWVudEF0KE5VTEwsbV9sYXN0X3BhcmVudCk7IC8vIFBvcHBpbmcgZnJvbSBhbiBlbGVtZW50Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgICAgICBtX25leHRzaWIuc2V0RWxlbWVudEF0KE5VTEwsbV9sYXN0X2tpZCk7IC8vIFBvcHBpbmcgZnJvbSBhbnl0aGluZyBlbHNlCi0gICAgICAgICAgICAgICAgICAgIG1fbGFzdF9wYXJlbnQ9bV9wYXJlbnQuZWxlbWVudEF0KG1fbGFzdF9raWQ9bV9sYXN0X3BhcmVudCk7Ci0gICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmKG1fbGFzdF9wYXJlbnQ9PU5VTEwpCi0gICAgICAgICAgICAgIG5leHQ9bnVsbDsKLSAgICAgICAgICB9Ci0KLSAgICAgICAgaWYobmV4dCE9bnVsbCkKLSAgICAgICAgICBuZXh0dHlwZT1uZXh0LmdldE5vZGVUeXBlKCk7Ci0KLSAgICAgICAgLy8gSWYgaXQncyBhbiBlbnRpdHkgcmVmLCBhZHZhbmNlIHBhc3QgaXQuCi0gICAgICAgIC8vCi0gICAgICAgIC8vICVSRVZJRVclIFNob3VsZCB3ZSBsZXQgdGhpcyBvdXQgdGhlIGRvb3IgYW5kIGp1c3Qgc3VwcHJlc3MgaXQ/Ci0gICAgICAgIC8vIE1vcmUgd29yaywgYnV0IHNpbXBsZXIgY29kZSwgbW9yZSBsaWtlbHkgdG8gYmUgY29ycmVjdCwgYW5kCi0gICAgICAgIC8vIGl0IGRvZXNuJ3QgaGFwcGVuIHZlcnkgb2Z0ZW4uIFdlJ2QgZ2V0IHJpZCBvZiB0aGUgbG9vcCB0b28uCi0gICAgICAgIGlmIChFTlRJVFlfUkVGRVJFTkNFX05PREUgPT0gbmV4dHR5cGUpCi0gICAgICAgICAgcG9zPW5leHQ7Ci0gICAgICB9Ci0gICAgd2hpbGUgKEVOVElUWV9SRUZFUkVOQ0VfTk9ERSA9PSBuZXh0dHlwZSk7Ci0KLSAgICAvLyBEaWQgd2UgcnVuIG91dCBvZiB0aGUgdHJlZT8KLSAgICBpZihuZXh0PT1udWxsKQotICAgICAgewotICAgICAgICBtX25leHRzaWIuc2V0RWxlbWVudEF0KE5VTEwsMCk7Ci0gICAgICAgIG1fbm9kZXNBcmVQcm9jZXNzZWQgPSB0cnVlOwotICAgICAgICBtX3Bvcz1udWxsOwotCi0gICAgICAgIGlmKEpKS19ERUJVRykKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIioqKioqIERPTTJEVE0gQ3Jvc3NjaGVjazoiKTsKLSAgICAgICAgICAgIGZvcihpbnQgaT0wO2k8bV9ub2Rlcy5zaXplKCk7KytpKQotICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oaSsiOlx0IittX2ZpcnN0Y2guZWxlbWVudEF0KGkpKyJcdCIrbV9uZXh0c2liLmVsZW1lbnRBdChpKSk7Ci0gICAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgIH0KLQotICAgIC8vIFRleHQgbmVlZHMgc29tZSBzcGVjaWFsIGhhbmRsaW5nOgotICAgIC8vCi0gICAgLy8gRFRNIG1heSBza2lwIHdoaXRlc3BhY2UuIFRoaXMgaXMgaGFuZGxlZCBieSB0aGUgc3VwcHJlc3NOb2RlIGZsYWcsIHdoaWNoCi0gICAgLy8gd2hlbiB0cnVlIHdpbGwga2VlcCB0aGUgRFRNIG5vZGUgZnJvbSBiZWluZyBjcmVhdGVkLgotICAgIC8vCi0gICAgLy8gRFRNIG9ubHkgZGlyZWN0bHkgcmVjb3JkcyB0aGUgZmlyc3QgRE9NIG5vZGUgb2YgYW55IGxvZ2ljYWxseS1jb250aWd1b3VzCi0gICAgLy8gc2VxdWVuY2UuIFRoZSBsYXN0VGV4dE5vZGUgdmFsdWUgd2lsbCBiZSBzZXQgdG8gdGhlIGxhc3Qgbm9kZSBpbiB0aGUKLSAgICAvLyBjb250aWd1b3VzIHNlcXVlbmNlLCBhbmQgLS0gQUZURVIgdGhlIERUTSBhZGROb2RlIC0tIGNhbiBiZSB1c2VkIHRvCi0gICAgLy8gYWR2YW5jZSBuZXh0IG92ZXIgdGhpcyB3aG9sZSBibG9jay4gU2hvdWxkIGJlIHNpbXBsZXIgdGhhbiBzcGVjaWFsLWNhc2luZwotICAgIC8vIHRoZSBhYm92ZSBsb29wIGZvciAiV2FzIHRoZSBsb2dpY2FsbHktcHJlY2VlZGluZyBzaWJsaW5nIGEgdGV4dCBub2RlIi4KLSAgICAvLwotICAgIC8vIEZpbmFsbHksIGEgRFRNIG5vZGUgc2hvdWxkIGJlIGNvbnNpZGVyZWQgYSBDREFUQVNlY3Rpb24gb25seSBpZiBhbGwgdGhlCi0gICAgLy8gY29udGlndW91cyB0ZXh0IGl0IGNvdmVycyBpcyBDREFUQVNlY3Rpb25zLiBUaGUgZmlyc3QgVGV4dCBzaG91bGQKLSAgICAvLyBmb3JjZSBEVE0gdG8gVGV4dC4KLQotICAgIGJvb2xlYW4gc3VwcHJlc3NOb2RlPWZhbHNlOwotICAgIE5vZGUgbGFzdFRleHROb2RlPW51bGw7Ci0KLSAgICBuZXh0dHlwZT1uZXh0LmdldE5vZGVUeXBlKCk7Ci0KLSAgICAvLyBuZXh0dHlwZT1wb3MuZ2V0Tm9kZVR5cGUoKTsKLSAgICBpZihURVhUX05PREUgPT0gbmV4dHR5cGUgfHwgQ0RBVEFfU0VDVElPTl9OT0RFID09IG5leHR0eXBlKQotICAgICAgewotICAgICAgICAvLyBJZiBmaWx0ZXJpbmcsIGluaXRpYWxseSBhc3N1bWUgd2UncmUgZ29pbmcgdG8gc3VwcHJlc3MgdGhlIG5vZGUKLSAgICAgICAgc3VwcHJlc3NOb2RlPSgobnVsbCAhPSBtX3dzZmlsdGVyKSAmJiBnZXRTaG91bGRTdHJpcFdoaXRlc3BhY2UoKSk7Ci0KLSAgICAgICAgLy8gU2NhbiBsb2dpY2FsbHkgY29udGlndW91cyB0ZXh0IChzaWJsaW5ncywgcGx1cyAiZmxhdHRlbmluZyIKLSAgICAgICAgLy8gb2YgZW50aXR5IHJlZmVyZW5jZSBib3VuZGFyaWVzKS4KLSAgICAgICAgTm9kZSBuPW5leHQ7Ci0gICAgICAgIHdoaWxlKG4hPW51bGwpCi0gICAgICAgICAgewotICAgICAgICAgICAgbGFzdFRleHROb2RlPW47Ci0gICAgICAgICAgICAvLyBBbnkgVGV4dCBub2RlIG1lYW5zIERUTSBjb25zaWRlcnMgaXQgYWxsIFRleHQKLSAgICAgICAgICAgIGlmKFRFWFRfTk9ERSA9PSBuLmdldE5vZGVUeXBlKCkpCi0gICAgICAgICAgICAgIG5leHR0eXBlPVRFWFRfTk9ERTsKLSAgICAgICAgICAgIC8vIEFueSBub24td2hpdGVzcGFjZSBpbiB0aGlzIHNlcXVlbmNlIGJsb2NrcyB3aGl0ZXNwYWNlCi0gICAgICAgICAgICAvLyBzdXBwcmVzc2lvbgotICAgICAgICAgICAgc3VwcHJlc3NOb2RlICY9Ci0gICAgICAgICAgICAgIFhNTENoYXJhY3RlclJlY29nbml6ZXIuaXNXaGl0ZVNwYWNlKG4uZ2V0Tm9kZVZhbHVlKCkpOwotCi0gICAgICAgICAgICBuPWxvZ2ljYWxOZXh0RE9NVGV4dE5vZGUobik7Ci0gICAgICAgICAgfQotICAgICAgfQotCi0gICAgLy8gU3BlY2lhbCBoYW5kbGluZyBmb3IgUElzOiBTb21lIERPTXMgcmVwcmVzZW50IHRoZSBYTUwKLSAgICAvLyBEZWNsYXJhdGlvbiBhcyBhIFBJLiBUaGlzIGlzIG9mZmljaWFsbHkgaW5jb3JyZWN0LCBwZXIgdGhlIERPTQotICAgIC8vIHNwZWMsIGJ1dCBpcyBjb25zaWRlcmVkIGEgIndyb25nIGJ1dCB0b2xlcmFibGUiIHRlbXBvcmFyeQotICAgIC8vIHdvcmthcm91bmQgcGVuZGluZyBwcm9wZXIgaGFuZGxpbmcgb2YgdGhlc2UgZmllbGRzIGluIERPTSBMZXZlbAotICAgIC8vIDMuIFdlIHdhbnQgdG8gcmVjb2duaXplIGFuZCByZWplY3QgdGhhdCBjYXNlLgotICAgIGVsc2UgaWYoUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFPT1uZXh0dHlwZSkKLSAgICAgIHsKLSAgICAgICAgc3VwcHJlc3NOb2RlID0gKHBvcy5nZXROb2RlTmFtZSgpLnRvTG93ZXJDYXNlKCkuZXF1YWxzKCJ4bWwiKSk7Ci0gICAgICB9Ci0KLQotICAgIGlmKCFzdXBwcmVzc05vZGUpCi0gICAgICB7Ci0gICAgICAgIC8vIEluc2VydGluZyBuZXh0LiBOT1RFIHRoYXQgd2UgZm9yY2UgdGhlIG5vZGUgdHlwZTsgZm9yCi0gICAgICAgIC8vIGNvYWxlc2NlZCBUZXh0LCB0aGlzIHJlY29yZHMgQ0RBVEFTZWN0aW9ucyBhZGphY2VudCB0bwotICAgICAgICAvLyBvcmRpbmFyeSBUZXh0IGFzIFRleHQuCi0gICAgICAgIGludCBuZXh0aW5kZXg9YWRkTm9kZShuZXh0LG1fbGFzdF9wYXJlbnQsbV9sYXN0X2tpZCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5leHR0eXBlKTsKLQotICAgICAgICBtX2xhc3Rfa2lkPW5leHRpbmRleDsKLQotICAgICAgICBpZihFTEVNRU5UX05PREUgPT0gbmV4dHR5cGUpCi0gICAgICAgICAgewotICAgICAgICAgICAgaW50IGF0dHJJbmRleD1OVUxMOyAvLyBzdGFydCB3aXRoIG5vIHByZXZpb3VzIHNpYgotICAgICAgICAgICAgLy8gUHJvY2VzcyBhdHRyaWJ1dGVzIF9ub3dfLCByYXRoZXIgdGhhbiB3YWl0aW5nLgotICAgICAgICAgICAgLy8gU2ltcGxlciBjb250cm9sIGZsb3csIG1ha2VzIE5TIGNhY2hlIGF2YWlsYWJsZSBpbW1lZGlhdGVseS4KLSAgICAgICAgICAgIE5hbWVkTm9kZU1hcCBhdHRycz1uZXh0LmdldEF0dHJpYnV0ZXMoKTsKLSAgICAgICAgICAgIGludCBhdHRyc2l6ZT0oYXR0cnM9PW51bGwpID8gMCA6IGF0dHJzLmdldExlbmd0aCgpOwotICAgICAgICAgICAgaWYoYXR0cnNpemU+MCkKLSAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIGZvcihpbnQgaT0wO2k8YXR0cnNpemU7KytpKQotICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAvLyBObyBuZWVkIHRvIGZvcmNlIG5vZGV0eXBlIGluIHRoaXMgY2FzZTsKLSAgICAgICAgICAgICAgICAgICAgLy8gYWRkTm9kZSgpIHdpbGwgdGFrZSBjYXJlIG9mIHN3aXRjaGluZyBpdCBmcm9tCi0gICAgICAgICAgICAgICAgICAgIC8vIEF0dHIgdG8gTmFtZXNwYWNlIGlmIG5lY2Vzc2FyeS4KLSAgICAgICAgICAgICAgICAgICAgYXR0ckluZGV4PWFkZE5vZGUoYXR0cnMuaXRlbShpKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV4dGluZGV4LGF0dHJJbmRleCxOVUxMKTsKLSAgICAgICAgICAgICAgICAgICAgbV9maXJzdGNoLnNldEVsZW1lbnRBdChEVE0uTlVMTCxhdHRySW5kZXgpOwotCi0gICAgICAgICAgICAgICAgICAgIC8vIElmIHRoZSB4bWw6IHByZWZpeCBpcyBleHBsaWNpdGx5IGRlY2xhcmVkCi0gICAgICAgICAgICAgICAgICAgIC8vIHdlIGRvbid0IG5lZWQgdG8gc3ludGhlc2l6ZSBvbmUuCi0gICAgICAgICAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAgICAgICAgIC8vIE5PVEUgdGhhdCBYTUwgTmFtZXNwYWNlcyB3ZXJlIG5vdCBvcmlnaW5hbGx5Ci0gICAgICAgICAgICAgICAgICAgIC8vIGRlZmluZWQgYXMgYmVpbmcgbmFtZXNwYWNlLWF3YXJlIChncnJyKSwgYW5kCi0gICAgICAgICAgICAgICAgICAgIC8vIHdoaWxlIHRoZSBXM0MgaXMgcGxhbm5pbmcgdG8gZml4IHRoaXMgaXQncwotICAgICAgICAgICAgICAgICAgICAvLyBzYWZlciBmb3Igbm93IHRvIHRlc3QgdGhlIFFOYW1lIGFuZCB0cnVzdCB0aGUKLSAgICAgICAgICAgICAgICAgICAgLy8gcGFyc2VycyB0byBwcmV2ZW50IGFueW9uZSBmcm9tIHJlZGVmaW5pbmcgdGhlCi0gICAgICAgICAgICAgICAgICAgIC8vIHJlc2VydmVkIHhtbG5zOiBwcmVmaXgKLSAgICAgICAgICAgICAgICAgICAgaWYoIW1fcHJvY2Vzc2VkRmlyc3RFbGVtZW50Ci0gICAgICAgICAgICAgICAgICAgICAgICYmICJ4bWxuczp4bWwiLmVxdWFscyhhdHRycy5pdGVtKGkpLmdldE5vZGVOYW1lKCkpKQotICAgICAgICAgICAgICAgICAgICAgIG1fcHJvY2Vzc2VkRmlyc3RFbGVtZW50PXRydWU7Ci0gICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLy8gVGVybWluYXRlIGxpc3Qgb2YgYXR0cnMsIGFuZCBtYWtlIHN1cmUgdGhleSBhcmVuJ3QKLSAgICAgICAgICAgICAgICAvLyBjb25zaWRlcmVkIGNoaWxkcmVuIG9mIHRoZSBlbGVtZW50Ci0gICAgICAgICAgICAgIH0gLy8gaWYgYXR0cnMgZXhpc3QKLSAgICAgICAgICAgIGlmKCFtX3Byb2Nlc3NlZEZpcnN0RWxlbWVudCkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgLy8gVGhlIERPTSBtaWdodCBub3QgaGF2ZSBhbiBleHBsaWNpdCBkZWNsYXJhdGlvbiBmb3IgdGhlCi0gICAgICAgICAgICAgIC8vIGltcGxpY2l0ICJ4bWw6IiBwcmVmaXgsIGJ1dCB0aGUgWFBhdGggZGF0YSBtb2RlbAotICAgICAgICAgICAgICAvLyByZXF1aXJlcyB0aGF0IHRoaXMgYXBwZWFyIGFzIGEgTmFtZXNwYWNlIE5vZGUgc28gd2UKLSAgICAgICAgICAgICAgLy8gaGF2ZSB0byBzeW50aGVzaXplIG9uZS4gWW91IGNhbiB0aGluayBvZiB0aGlzIGFzCi0gICAgICAgICAgICAgIC8vIGJlaW5nIGEgZGVmYXVsdCBhdHRyaWJ1dGUgZGVmaW5lZCBieSB0aGUgWE1MCi0gICAgICAgICAgICAgIC8vIE5hbWVzcGFjZXMgc3BlYyByYXRoZXIgdGhhbiBieSB0aGUgRFRELgotICAgICAgICAgICAgICBhdHRySW5kZXg9YWRkTm9kZShuZXcgRE9NMkRUTWRlZmF1bHROYW1lc3BhY2VEZWNsYXJhdGlvbk5vZGUoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKEVsZW1lbnQpbmV4dCwieG1sIixOQU1FU1BBQ0VfREVDTF9OUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYWtlTm9kZUhhbmRsZSgoKGF0dHJJbmRleD09TlVMTCk/bmV4dGluZGV4OmF0dHJJbmRleCkrMSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXh0aW5kZXgsYXR0ckluZGV4LE5VTEwpOwotICAgICAgICAgICAgICBtX2ZpcnN0Y2guc2V0RWxlbWVudEF0KERUTS5OVUxMLGF0dHJJbmRleCk7Ci0gICAgICAgICAgICAgIG1fcHJvY2Vzc2VkRmlyc3RFbGVtZW50PXRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZihhdHRySW5kZXghPU5VTEwpCi0gICAgICAgICAgICAgIG1fbmV4dHNpYi5zZXRFbGVtZW50QXQoRFRNLk5VTEwsYXR0ckluZGV4KTsKLSAgICAgICAgICB9IC8vaWYoRUxFTUVOVF9OT0RFKQotICAgICAgfSAvLyAoaWYgIXN1cHByZXNzTm9kZSkKLQotICAgIC8vIFRleHQgcG9zdHByb2Nlc3Npbmc6IEFjdCBvbiB2YWx1ZXMgc3RvcmVkIGFib3ZlCi0gICAgaWYoVEVYVF9OT0RFID09IG5leHR0eXBlIHx8IENEQVRBX1NFQ1RJT05fTk9ERSA9PSBuZXh0dHlwZSkKLSAgICAgIHsKLSAgICAgICAgLy8gJVRCRCUgSWYgbmV4dHR5cGUgd2FzIGZvcmNlZCB0byBURVhULCBwYXRjaCB0aGUgRFRNIG5vZGUKLQotICAgICAgICBuZXh0PWxhc3RUZXh0Tm9kZTsgICAgICAvLyBBZHZhbmNlIHRoZSBET00gY3Vyc29yIG92ZXIgY29udGlndW91cyB0ZXh0Ci0gICAgICB9Ci0KLSAgICAvLyBSZW1lbWJlciB3aGVyZSB3ZSBsZWZ0IG9mZi4KLSAgICBtX3Bvcz1uZXh0OwotICAgIHJldHVybiB0cnVlOwotICB9Ci0KLQotICAvKioKLSAgICogUmV0dXJuIGFuIERPTSBub2RlIGZvciB0aGUgZ2l2ZW4gbm9kZS4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgVGhlIG5vZGUgSUQuCi0gICAqCi0gICAqIEByZXR1cm4gQSBub2RlIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBEVE0gbm9kZS4KLSAgICovCi0gIHB1YmxpYyBOb2RlIGdldE5vZGUoaW50IG5vZGVIYW5kbGUpCi0gIHsKLQotICAgIGludCBpZGVudGl0eSA9IG1ha2VOb2RlSWRlbnRpdHkobm9kZUhhbmRsZSk7Ci0KLSAgICByZXR1cm4gKE5vZGUpIG1fbm9kZXMuZWxlbWVudEF0KGlkZW50aXR5KTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgYSBOb2RlIGZyb20gYW4gaWRlbnRpdHkgaW5kZXguCi0gICAqCi0gICAqIE5FRURTRE9DIEBwYXJhbSBub2RlSWRlbnRpdHkKLSAgICoKLSAgICogTkVFRFNET0MgKCRvYmplY3ROYW1lJCkgQHJldHVybgotICAgKi8KLSAgcHJvdGVjdGVkIE5vZGUgbG9va3VwTm9kZShpbnQgbm9kZUlkZW50aXR5KQotICB7Ci0gICAgcmV0dXJuIChOb2RlKSBtX25vZGVzLmVsZW1lbnRBdChub2RlSWRlbnRpdHkpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbmV4dCBub2RlIGlkZW50aXR5IHZhbHVlIGluIHRoZSBsaXN0LCBhbmQgY2FsbCB0aGUgaXRlcmF0b3IKLSAgICogaWYgaXQgaGFzbid0IGJlZW4gYWRkZWQgeWV0LgotICAgKgotICAgKiBAcGFyYW0gaWRlbnRpdHkgVGhlIG5vZGUgaWRlbnRpdHkgKGluZGV4KS4KLSAgICogQHJldHVybiBpZGVudGl0eSsxLCBvciBEVE0uTlVMTC4KLSAgICovCi0gIHByb3RlY3RlZCBpbnQgZ2V0TmV4dE5vZGVJZGVudGl0eShpbnQgaWRlbnRpdHkpCi0gIHsKLQotICAgIGlkZW50aXR5ICs9IDE7Ci0KLSAgICBpZiAoaWRlbnRpdHkgPj0gbV9ub2Rlcy5zaXplKCkpCi0gICAgewotICAgICAgaWYgKCFuZXh0Tm9kZSgpKQotICAgICAgICBpZGVudGl0eSA9IERUTS5OVUxMOwotICAgIH0KLQotICAgIHJldHVybiBpZGVudGl0eTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGhhbmRsZSBmcm9tIGEgTm9kZS4KLSAgICogPHA+JU9QVCUgVGhpcyB3aWxsIGJlIHByZXR0eSBzbG93LjwvcD4KLSAgICoKLSAgICogPHA+JU9QVCUgQW4gWFBhdGgtbGlrZSBzZWFyY2ggKHdhbGsgdXAgRE9NIHRvIHJvb3QsIHRyYWNraW5nIHBhdGg7Ci0gICAqIHdhbGsgZG93biBEVE0gcmVjb25zdHJ1Y3RpbmcgcGF0aCkgbWlnaHQgYmUgY29uc2lkZXJhYmx5IGZhc3RlcgotICAgKiBvbiBsYXRlciBub2RlcyBpbiBsYXJnZSBkb2N1bWVudHMuIFRoYXQgbWlnaHQgYWxzbyBpbXBseSBpbXByb3ZpbmcKLSAgICogdGhpcyBjYWxsIHRvIGhhbmRsZSBub2RlcyB3aGljaCB3b3VsZCBiZSBpbiB0aGlzIERUTSBidXQKLSAgICogaGF2ZSBub3QgeWV0IGJlZW4gYnVpbHQsIHdoaWNoIG1pZ2h0IG9yIG1pZ2h0IG5vdCBiZSBhIEdvb2QgVGhpbmcuPC9wPgotICAgKgotICAgKiAlUkVWSUVXJSBUaGlzIHJlbGllcyBvbiBiZWluZyBhYmxlIHRvIHRlc3Qgbm9kZS1pZGVudGl0eSB2aWEKLSAgICogb2JqZWN0LWlkZW50aXR5LiBEVE0yRE9NIHByb3h5aW5nIGlzIGEgZ3JlYXQgZXhhbXBsZSBvZiBhIGNhc2Ugd2hlcmUKLSAgICogdGhhdCBkb2Vzbid0IHdvcmsuIERPTSBMZXZlbCAzIHdpbGwgcHJvdmlkZSB0aGUgaXNTYW1lTm9kZSgpIG1ldGhvZAotICAgKiB0byBmaXggdGhhdCwgYnV0IHVudGlsIHRoZW4gdGhpcyBpcyBnb2luZyB0byBiZSBmbGFreS4KLSAgICoKLSAgICogQHBhcmFtIG5vZGUgQSBub2RlLCB3aGljaCBtYXkgYmUgbnVsbC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgbm9kZSBoYW5kbGUgb3IgPGNvZGU+RFRNLk5VTEw8L2NvZGU+LgotICAgKi8KLSAgcHJpdmF0ZSBpbnQgZ2V0SGFuZGxlRnJvbU5vZGUoTm9kZSBub2RlKQotICB7Ci0gICAgaWYgKG51bGwgIT0gbm9kZSkKLSAgICB7Ci0gICAgICBpbnQgbGVuID0gbV9ub2Rlcy5zaXplKCk7Ci0gICAgICBib29sZWFuIGlzTW9yZTsKLSAgICAgIGludCBpID0gMDsKLSAgICAgIGRvCi0gICAgICB7Ci0gICAgICAgIGZvciAoOyBpIDwgbGVuOyBpKyspCi0gICAgICAgIHsKLSAgICAgICAgICBpZiAobV9ub2Rlcy5lbGVtZW50QXQoaSkgPT0gbm9kZSkKLSAgICAgICAgICAgIHJldHVybiBtYWtlTm9kZUhhbmRsZShpKTsKLSAgICAgICAgfQotCi0gICAgICAgIGlzTW9yZSA9IG5leHROb2RlKCk7Ci0KLSAgICAgICAgbGVuID0gbV9ub2Rlcy5zaXplKCk7Ci0KLSAgICAgIH0KLSAgICAgIHdoaWxlKGlzTW9yZSB8fCBpIDwgbGVuKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gRFRNLk5VTEw7Ci0gIH0KLQotICAvKiogR2V0IHRoZSBoYW5kbGUgZnJvbSBhIE5vZGUuIFRoaXMgaXMgYSBtb3JlIHJvYnVzdCB2ZXJzaW9uIG9mCi0gICAqIGdldEhhbmRsZUZyb21Ob2RlLCBpbnRlbmRlZCB0byBiZSB1c2FibGUgYnkgdGhlIHB1YmxpYy4KLSAgICoKLSAgICogPHA+JU9QVCUgVGhpcyB3aWxsIGJlIHByZXR0eSBzbG93LjwvcD4KLSAgICoKLSAgICogJVJFVklFVyUgVGhpcyByZWxpZXMgb24gYmVpbmcgYWJsZSB0byB0ZXN0IG5vZGUtaWRlbnRpdHkgdmlhCi0gICAqIG9iamVjdC1pZGVudGl0eS4gRFRNMkRPTSBwcm94eWluZyBpcyBhIGdyZWF0IGV4YW1wbGUgb2YgYSBjYXNlIHdoZXJlCi0gICAqIHRoYXQgZG9lc24ndCB3b3JrLiBET00gTGV2ZWwgMyB3aWxsIHByb3ZpZGUgdGhlIGlzU2FtZU5vZGUoKSBtZXRob2QKLSAgICogdG8gZml4IHRoYXQsIGJ1dCB1bnRpbCB0aGVuIHRoaXMgaXMgZ29pbmcgdG8gYmUgZmxha3kuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlIEEgbm9kZSwgd2hpY2ggbWF5IGJlIG51bGwuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIG5vZGUgaGFuZGxlIG9yIDxjb2RlPkRUTS5OVUxMPC9jb2RlPi4gICovCi0gIHB1YmxpYyBpbnQgZ2V0SGFuZGxlT2ZOb2RlKE5vZGUgbm9kZSkKLSAgewotICAgIGlmIChudWxsICE9IG5vZGUpCi0gICAgewotICAgICAgLy8gSXMgTm9kZSBhY3R1YWxseSB3aXRoaW4gdGhlIHNhbWUgZG9jdW1lbnQ/IElmIG5vdCwgZG9uJ3Qgc2VhcmNoIQotICAgICAgLy8gVGhpcyB3b3VsZCBiZSBlYXNpZXIgaWYgbV9yb290IHdhcyBhbHdheXMgdGhlIERvY3VtZW50IG5vZGUsIGJ1dAotICAgICAgLy8gd2UgZGVjaWRlZCB0byBhbGxvdyB3cmFwcGluZyBhIERUTSBhcm91bmQgYSBzdWJ0cmVlLgotICAgICAgaWYoKG1fcm9vdD09bm9kZSkgfHwKLSAgICAgICAgIChtX3Jvb3QuZ2V0Tm9kZVR5cGUoKT09RE9DVU1FTlRfTk9ERSAmJgotICAgICAgICAgIG1fcm9vdD09bm9kZS5nZXRPd25lckRvY3VtZW50KCkpIHx8Ci0gICAgICAgICAobV9yb290LmdldE5vZGVUeXBlKCkhPURPQ1VNRU5UX05PREUgJiYKLSAgICAgICAgICBtX3Jvb3QuZ2V0T3duZXJEb2N1bWVudCgpPT1ub2RlLmdldE93bmVyRG9jdW1lbnQoKSkKLSAgICAgICAgICkKLSAgICAgICAgewotICAgICAgICAgIC8vIElmIG5vZGUgX2lzXyBpbiBtX3Jvb3QncyB0cmVlLCBmaW5kIGl0cyBoYW5kbGUKLSAgICAgICAgICAvLwotICAgICAgICAgIC8vICVPUFQlIFRoaXMgY2hlY2sgbWF5IGJlIGltcHJvdmVkIHNpZ25pZmljYW50bHkgd2hlbiBET00KLSAgICAgICAgICAvLyBMZXZlbCAzIG5vZGVLZXkgYW5kIHJlbGF0aXZlLW9yZGVyIHRlc3RzIGJlY29tZQotICAgICAgICAgIC8vIGF2YWlsYWJsZSEKLSAgICAgICAgICBmb3IoTm9kZSBjdXJzb3I9bm9kZTsKLSAgICAgICAgICAgICAgY3Vyc29yIT1udWxsOwotICAgICAgICAgICAgICBjdXJzb3I9Ci0gICAgICAgICAgICAgICAgKGN1cnNvci5nZXROb2RlVHlwZSgpIT1BVFRSSUJVVEVfTk9ERSkKLSAgICAgICAgICAgICAgICA/IGN1cnNvci5nZXRQYXJlbnROb2RlKCkKLSAgICAgICAgICAgICAgICA6ICgob3JnLnczYy5kb20uQXR0ciljdXJzb3IpLmdldE93bmVyRWxlbWVudCgpKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICBpZihjdXJzb3I9PW1fcm9vdCkKLSAgICAgICAgICAgICAgICAvLyBXZSBrbm93IHRoaXMgbm9kZTsgZmluZCBpdHMgaGFuZGxlLgotICAgICAgICAgICAgICAgIHJldHVybiBnZXRIYW5kbGVGcm9tTm9kZShub2RlKTsKLSAgICAgICAgICAgIH0gLy8gZm9yIGFuY2VzdG9ycyBvZiBub2RlCi0gICAgICAgIH0gLy8gaWYgbm9kZSBhbmQgbV9yb290IGluIHNhbWUgRG9jdW1lbnQKLSAgICB9IC8vIGlmIG5vZGUhPW51bGwKLQotICAgIHJldHVybiBEVE0uTlVMTDsKLSAgfQotCi0gIC8qKgotICAgKiBSZXRyaWV2ZXMgYW4gYXR0cmlidXRlIG5vZGUgYnkgYnkgcXVhbGlmaWVkIG5hbWUgYW5kIG5hbWVzcGFjZSBVUkkuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIGludCBIYW5kbGUgb2YgdGhlIG5vZGUgdXBvbiB3aGljaCB0byBsb29rIHVwIHRoaXMgYXR0cmlidXRlLi4KLSAgICogQHBhcmFtIG5hbWVzcGFjZVVSSSBUaGUgbmFtZXNwYWNlIFVSSSBvZiB0aGUgYXR0cmlidXRlIHRvCi0gICAqICAgcmV0cmlldmUsIG9yIG51bGwuCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBsb2NhbCBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUgdG8KLSAgICogICByZXRyaWV2ZS4KLSAgICogQHJldHVybiBUaGUgYXR0cmlidXRlIG5vZGUgaGFuZGxlIHdpdGggdGhlIHNwZWNpZmllZCBuYW1lICgKLSAgICogICA8Y29kZT5ub2RlTmFtZTwvY29kZT4pIG9yIDxjb2RlPkRUTS5OVUxMPC9jb2RlPiBpZiB0aGVyZSBpcyBubyBzdWNoCi0gICAqICAgYXR0cmlidXRlLgotICAgKi8KLSAgcHVibGljIGludCBnZXRBdHRyaWJ1dGVOb2RlKGludCBub2RlSGFuZGxlLCBTdHJpbmcgbmFtZXNwYWNlVVJJLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG5hbWUpCi0gIHsKLQotICAgIC8vICVPUFQlIFRoaXMgaXMgcHJvYmFibHkgc2xvd2VyIHRoYW4gaXQgbmVlZHMgdG8gYmUuCi0gICAgaWYgKG51bGwgPT0gbmFtZXNwYWNlVVJJKQotICAgICAgbmFtZXNwYWNlVVJJID0gIiI7Ci0KLSAgICBpbnQgdHlwZSA9IGdldE5vZGVUeXBlKG5vZGVIYW5kbGUpOwotCi0gICAgaWYgKERUTS5FTEVNRU5UX05PREUgPT0gdHlwZSkKLSAgICB7Ci0KLSAgICAgIC8vIEFzc3VtZSB0aGF0IGF0dHJpYnV0ZXMgaW1tZWRpYXRlbHkgZm9sbG93IHRoZSBlbGVtZW50LgotICAgICAgaW50IGlkZW50aXR5ID0gbWFrZU5vZGVJZGVudGl0eShub2RlSGFuZGxlKTsKLQotICAgICAgd2hpbGUgKERUTS5OVUxMICE9IChpZGVudGl0eSA9IGdldE5leHROb2RlSWRlbnRpdHkoaWRlbnRpdHkpKSkKLSAgICAgIHsKLSAgICAgICAgLy8gQXNzdW1lIHRoaXMgY2FuIG5vdCBiZSBudWxsLgotICAgICAgICB0eXBlID0gX3R5cGUoaWRlbnRpdHkpOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICVSRVZJRVclCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNob3VsZCBuYW1lc3BhY2Ugbm9kZXMgYmUgcmV0cmlldmFibGUgRE9NLXN0eWxlIGFzIGF0dHJzPwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJZiBub3Qgd2UgbmVlZCBhIHNlcGFyYXRlIGZ1bmN0aW9uLi4uIHdoaWNoIG1heSBiZSBkZXNpcmFibGUKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYXJjaGl0ZWN0dXJhbGx5LCBidXQgd2hpY2ggaXMgdWdseSBmcm9tIGEgY29kZSBwb2ludCBvZiB2aWV3LgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAoSWYgd2UgUkVBTExZIGluc2lzdCBvbiBpdCwgdGhpcyBjb2RlIHNob3VsZCBiZWNvbWUgYSBzdWJyb3V0aW5lCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG9mIGJvdGggLS0gcmV0cmlldmUgdGhlIG5vZGUsIHRoZW4gdGVzdCBpZiB0aGUgdHlwZSBtYXRjaGVzCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHdoYXQgeW91J3JlIGxvb2tpbmcgZm9yLikKLSAgICAgICAgaWYgKHR5cGUgPT0gRFRNLkFUVFJJQlVURV9OT0RFIHx8IHR5cGU9PURUTS5OQU1FU1BBQ0VfTk9ERSkKLSAgICAgICAgewotICAgICAgICAgIE5vZGUgbm9kZSA9IGxvb2t1cE5vZGUoaWRlbnRpdHkpOwotICAgICAgICAgIFN0cmluZyBub2RldXJpID0gbm9kZS5nZXROYW1lc3BhY2VVUkkoKTsKLQotICAgICAgICAgIGlmIChudWxsID09IG5vZGV1cmkpCi0gICAgICAgICAgICBub2RldXJpID0gIiI7Ci0KLSAgICAgICAgICBTdHJpbmcgbm9kZWxvY2FsbmFtZSA9IG5vZGUuZ2V0TG9jYWxOYW1lKCk7Ci0KLSAgICAgICAgICBpZiAobm9kZXVyaS5lcXVhbHMobmFtZXNwYWNlVVJJKSAmJiBuYW1lLmVxdWFscyhub2RlbG9jYWxuYW1lKSkKLSAgICAgICAgICAgIHJldHVybiBtYWtlTm9kZUhhbmRsZShpZGVudGl0eSk7Ci0gICAgICAgIH0KLQotICAgICAgICBlbHNlIC8vIGlmIChEVE0uTkFNRVNQQUNFX05PREUgIT0gdHlwZSkKLSAgICAgICAgewotICAgICAgICAgIGJyZWFrOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotCi0gICAgcmV0dXJuIERUTS5OVUxMOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgc3RyaW5nLXZhbHVlIG9mIGEgbm9kZSBhcyBhIFN0cmluZyBvYmplY3QKLSAgICogKHNlZSBodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aCNkYXRhLW1vZGVsCi0gICAqIGZvciB0aGUgZGVmaW5pdGlvbiBvZiBhIG5vZGUncyBzdHJpbmctdmFsdWUpLgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBUaGUgbm9kZSBJRC4KLSAgICoKLSAgICogQHJldHVybiBBIHN0cmluZyBvYmplY3QgdGhhdCByZXByZXNlbnRzIHRoZSBzdHJpbmctdmFsdWUgb2YgdGhlIGdpdmVuIG5vZGUuCi0gICAqLwotICBwdWJsaWMgWE1MU3RyaW5nIGdldFN0cmluZ1ZhbHVlKGludCBub2RlSGFuZGxlKQotICB7Ci0KLSAgICBpbnQgdHlwZSA9IGdldE5vZGVUeXBlKG5vZGVIYW5kbGUpOwotICAgIE5vZGUgbm9kZSA9IGdldE5vZGUobm9kZUhhbmRsZSk7Ci0gICAgLy8gJVRCRCUgSWYgYW4gZWxlbWVudCBvbmx5IGhhcyBvbmUgdGV4dCBub2RlLCB3ZSBzaG91bGQganVzdCB1c2UgaXQKLSAgICAvLyBkaXJlY3RseS4KLSAgICBpZihEVE0uRUxFTUVOVF9OT0RFID09IHR5cGUgfHwgRFRNLkRPQ1VNRU5UX05PREUgPT0gdHlwZQotICAgIHx8IERUTS5ET0NVTUVOVF9GUkFHTUVOVF9OT0RFID09IHR5cGUpCi0gICAgewotICAgICAgRmFzdFN0cmluZ0J1ZmZlciBidWYgPSBTdHJpbmdCdWZmZXJQb29sLmdldCgpOwotICAgICAgU3RyaW5nIHM7Ci0KLSAgICAgIHRyeQotICAgICAgewotICAgICAgICBnZXROb2RlRGF0YShub2RlLCBidWYpOwotCi0gICAgICAgIHMgPSAoYnVmLmxlbmd0aCgpID4gMCkgPyBidWYudG9TdHJpbmcoKSA6ICIiOwotICAgICAgfQotICAgICAgZmluYWxseQotICAgICAgewotICAgICAgICBTdHJpbmdCdWZmZXJQb29sLmZyZWUoYnVmKTsKLSAgICAgIH0KLQotICAgICAgcmV0dXJuIG1feHN0cmYubmV3c3RyKCBzICk7Ci0gICAgfQotICAgIGVsc2UgaWYoVEVYVF9OT0RFID09IHR5cGUgfHwgQ0RBVEFfU0VDVElPTl9OT0RFID09IHR5cGUpCi0gICAgewotICAgICAgLy8gSWYgdGhpcyBpcyBhIERUTSB0ZXh0IG5vZGUsIGl0IG1heSBiZSBtYWRlIG9mIG11bHRpcGxlIERPTSB0ZXh0Ci0gICAgICAvLyBub2RlcyAtLSBpbmNsdWRpbmcgbmF2aWdhdGluZyBpbnRvIEVudGl0eSBSZWZlcmVuY2VzLiBET00yRFRNCi0gICAgICAvLyByZWNvcmRzIHRoZSBmaXJzdCBub2RlIGluIHRoZSBzZXF1ZW5jZSBhbmQgcmVxdWlyZXMgdGhhdCB3ZQotICAgICAgLy8gcGljayB1cCB0aGUgb3RoZXJzIHdoZW4gd2UgcmV0cmlldmUgdGhlIERUTSBub2RlJ3MgdmFsdWUuCi0gICAgICAvLwotICAgICAgLy8gJVJFVklFVyUgRE9NIExldmVsIDMgaXMgZXhwZWN0ZWQgdG8gYWRkIGEgIndob2xlIHRleHQiCi0gICAgICAvLyByZXRyaWV2YWwgbWV0aG9kIHdoaWNoIHBlcmZvcm1zIHRoaXMgZnVuY3Rpb24gZm9yIHVzLgotICAgICAgRmFzdFN0cmluZ0J1ZmZlciBidWYgPSBTdHJpbmdCdWZmZXJQb29sLmdldCgpOwotICAgICAgd2hpbGUobm9kZSE9bnVsbCkKLSAgICAgIHsKLSAgICAgICAgYnVmLmFwcGVuZChub2RlLmdldE5vZGVWYWx1ZSgpKTsKLSAgICAgICAgbm9kZT1sb2dpY2FsTmV4dERPTVRleHROb2RlKG5vZGUpOwotICAgICAgfQotICAgICAgU3RyaW5nIHM9KGJ1Zi5sZW5ndGgoKSA+IDApID8gYnVmLnRvU3RyaW5nKCkgOiAiIjsKLSAgICAgIFN0cmluZ0J1ZmZlclBvb2wuZnJlZShidWYpOwotICAgICAgcmV0dXJuIG1feHN0cmYubmV3c3RyKCBzICk7Ci0gICAgfQotICAgIGVsc2UKLSAgICAgIHJldHVybiBtX3hzdHJmLm5ld3N0ciggbm9kZS5nZXROb2RlVmFsdWUoKSApOwotICB9Ci0KLSAgLyoqCi0gICAqIERldGVybWluZSBpZiB0aGUgc3RyaW5nLXZhbHVlIG9mIGEgbm9kZSBpcyB3aGl0ZXNwYWNlCi0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIFRoZSBub2RlIEhhbmRsZS4KLSAgICoKLSAgICogQHJldHVybiBSZXR1cm4gdHJ1ZSBpZiB0aGUgZ2l2ZW4gbm9kZSBpcyB3aGl0ZXNwYWNlLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNXaGl0ZXNwYWNlKGludCBub2RlSGFuZGxlKQotICB7Ci0gICAgICAgIGludCB0eXBlID0gZ2V0Tm9kZVR5cGUobm9kZUhhbmRsZSk7Ci0gICAgTm9kZSBub2RlID0gZ2V0Tm9kZShub2RlSGFuZGxlKTsKLSAgICAgICAgaWYoVEVYVF9OT0RFID09IHR5cGUgfHwgQ0RBVEFfU0VDVElPTl9OT0RFID09IHR5cGUpCi0gICAgewotICAgICAgLy8gSWYgdGhpcyBpcyBhIERUTSB0ZXh0IG5vZGUsIGl0IG1heSBiZSBtYWRlIG9mIG11bHRpcGxlIERPTSB0ZXh0Ci0gICAgICAvLyBub2RlcyAtLSBpbmNsdWRpbmcgbmF2aWdhdGluZyBpbnRvIEVudGl0eSBSZWZlcmVuY2VzLiBET00yRFRNCi0gICAgICAvLyByZWNvcmRzIHRoZSBmaXJzdCBub2RlIGluIHRoZSBzZXF1ZW5jZSBhbmQgcmVxdWlyZXMgdGhhdCB3ZQotICAgICAgLy8gcGljayB1cCB0aGUgb3RoZXJzIHdoZW4gd2UgcmV0cmlldmUgdGhlIERUTSBub2RlJ3MgdmFsdWUuCi0gICAgICAvLwotICAgICAgLy8gJVJFVklFVyUgRE9NIExldmVsIDMgaXMgZXhwZWN0ZWQgdG8gYWRkIGEgIndob2xlIHRleHQiCi0gICAgICAvLyByZXRyaWV2YWwgbWV0aG9kIHdoaWNoIHBlcmZvcm1zIHRoaXMgZnVuY3Rpb24gZm9yIHVzLgotICAgICAgRmFzdFN0cmluZ0J1ZmZlciBidWYgPSBTdHJpbmdCdWZmZXJQb29sLmdldCgpOwotICAgICAgd2hpbGUobm9kZSE9bnVsbCkKLSAgICAgIHsKLSAgICAgICAgYnVmLmFwcGVuZChub2RlLmdldE5vZGVWYWx1ZSgpKTsKLSAgICAgICAgbm9kZT1sb2dpY2FsTmV4dERPTVRleHROb2RlKG5vZGUpOwotICAgICAgfQotICAgICBib29sZWFuIGIgPSBidWYuaXNXaGl0ZXNwYWNlKDAsIGJ1Zi5sZW5ndGgoKSk7Ci0gICAgICBTdHJpbmdCdWZmZXJQb29sLmZyZWUoYnVmKTsKLSAgICAgcmV0dXJuIGI7Ci0gICAgfQotICAgIHJldHVybiBmYWxzZTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXRyaWV2ZSB0aGUgdGV4dCBjb250ZW50IG9mIGEgRE9NIHN1YnRyZWUsIGFwcGVuZGluZyBpdCBpbnRvIGEKLSAgICogdXNlci1zdXBwbGllZCBGYXN0U3RyaW5nQnVmZmVyIG9iamVjdC4gTm90ZSB0aGF0IGF0dHJpYnV0ZXMgYXJlCi0gICAqIG5vdCBjb25zaWRlcmVkIHBhcnQgb2YgdGhlIGNvbnRlbnQgb2YgYW4gZWxlbWVudC4KLSAgICogPHA+Ci0gICAqIFRoZXJlIGFyZSBvcGVuIHF1ZXN0aW9ucyByZWdhcmRpbmcgd2hpdGVzcGFjZSBzdHJpcHBpbmcuCi0gICAqIEN1cnJlbnRseSB3ZSBtYWtlIG5vIHNwZWNpYWwgZWZmb3J0IGluIHRoYXQgcmVnYXJkLCBzaW5jZSB0aGUgc3RhbmRhcmQKLSAgICogRE9NIGRvZXNuJ3QgeWV0IHByb3ZpZGUgRFRELWJhc2VkIGluZm9ybWF0aW9uIHRvIGRpc3Rpbmd1aXNoCi0gICAqIHdoaXRlc3BhY2UtaW4tZWxlbWVudC1jb250ZXh0IGZyb20gZ2VudWluZSAjUENEQVRBLiBOb3RlIHRoYXQgd2UKLSAgICogc2hvdWxkIHByb2JhYmx5IGFsc28gY29uc2lkZXIgeG1sOnNwYWNlIGlmL3doZW4gd2UgYWRkcmVzcyB0aGlzLgotICAgKiBET00gTGV2ZWwgMyBtYXkgc29sdmUgdGhlIHByb2JsZW0gZm9yIHVzLgotICAgKiA8cD4KLSAgICogJVJFVklFVyUgQWN0dWFsbHksIHNpbmNlIHRoaXMgbWV0aG9kIG9wZXJhdGVzIG9uIHRoZSBET00gc2lkZSBvZiB0aGUKLSAgICogZmVuY2UgcmF0aGVyIHRoYW4gdGhlIERUTSBzaWRlLCBpdCBTSE9VTEROJ1QgZG8KLSAgICogYW55IHNwZWNpYWwgaGFuZGxpbmcuIFRoZSBET00gZG9lcyB3aGF0IHRoZSBET00gZG9lczsgaWYgeW91IHdhbnQKLSAgICogRFRNLWxldmVsIGFic3RyYWN0aW9ucywgdXNlIERUTS1sZXZlbCBtZXRob2RzLgotICAgKgotICAgKiBAcGFyYW0gbm9kZSBOb2RlIHdob3NlIHN1YnRyZWUgaXMgdG8gYmUgd2Fsa2VkLCBnYXRoZXJpbmcgdGhlCi0gICAqIGNvbnRlbnRzIG9mIGFsbCBUZXh0IG9yIENEQVRBU2VjdGlvbiBub2Rlcy4KLSAgICogQHBhcmFtIGJ1ZiBGYXN0U3RyaW5nQnVmZmVyIGludG8gd2hpY2ggdGhlIGNvbnRlbnRzIG9mIHRoZSB0ZXh0Ci0gICAqIG5vZGVzIGFyZSB0byBiZSBjb25jYXRlbmF0ZWQuCi0gICAqLwotICBwcm90ZWN0ZWQgc3RhdGljIHZvaWQgZ2V0Tm9kZURhdGEoTm9kZSBub2RlLCBGYXN0U3RyaW5nQnVmZmVyIGJ1ZikKLSAgewotCi0gICAgc3dpdGNoIChub2RlLmdldE5vZGVUeXBlKCkpCi0gICAgewotICAgIGNhc2UgTm9kZS5ET0NVTUVOVF9GUkFHTUVOVF9OT0RFIDoKLSAgICBjYXNlIE5vZGUuRE9DVU1FTlRfTk9ERSA6Ci0gICAgY2FzZSBOb2RlLkVMRU1FTlRfTk9ERSA6Ci0gICAgewotICAgICAgZm9yIChOb2RlIGNoaWxkID0gbm9kZS5nZXRGaXJzdENoaWxkKCk7IG51bGwgIT0gY2hpbGQ7Ci0gICAgICAgICAgICAgIGNoaWxkID0gY2hpbGQuZ2V0TmV4dFNpYmxpbmcoKSkKLSAgICAgIHsKLSAgICAgICAgZ2V0Tm9kZURhdGEoY2hpbGQsIGJ1Zik7Ci0gICAgICB9Ci0gICAgfQotICAgIGJyZWFrOwotICAgIGNhc2UgTm9kZS5URVhUX05PREUgOgotICAgIGNhc2UgTm9kZS5DREFUQV9TRUNUSU9OX05PREUgOgotICAgIGNhc2UgTm9kZS5BVFRSSUJVVEVfTk9ERSA6ICAvLyBOZXZlciBhIGNoaWxkIGJ1dCBtaWdodCBiZSBvdXIgc3RhcnRpbmcgbm9kZQotICAgICAgYnVmLmFwcGVuZChub2RlLmdldE5vZGVWYWx1ZSgpKTsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgTm9kZS5QUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREUgOgotICAgICAgLy8gd2FybmluZyhYUEFUSEVycm9yUmVzb3VyY2VzLldHX1BBUlNJTkdfQU5EX1BSRVBBUklORyk7Ci0gICAgICBicmVhazsKLSAgICBkZWZhdWx0IDoKLSAgICAgIC8vIGlnbm9yZQotICAgICAgYnJlYWs7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIHJldHVybiBpdHMgRE9NLXN0eWxlIG5vZGUgbmFtZS4gVGhpcyB3aWxsCi0gICAqIGluY2x1ZGUgbmFtZXMgc3VjaCBhcyAjdGV4dCBvciAjZG9jdW1lbnQuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIHRoZSBpZCBvZiB0aGUgbm9kZS4KLSAgICogQHJldHVybiBTdHJpbmcgTmFtZSBvZiB0aGlzIG5vZGUsIHdoaWNoIG1heSBiZSBhbiBlbXB0eSBzdHJpbmcuCi0gICAqICVSRVZJRVclIERvY3VtZW50IHdoZW4gZW1wdHkgc3RyaW5nIGlzIHBvc3NpYmxlLi4uCi0gICAqICVSRVZJRVctQ09NTUVOVCUgSXQgc2hvdWxkIG5ldmVyIGJlIGVtcHR5LCBzaG91bGQgaXQ/Ci0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldE5vZGVOYW1lKGludCBub2RlSGFuZGxlKQotICB7Ci0KLSAgICBOb2RlIG5vZGUgPSBnZXROb2RlKG5vZGVIYW5kbGUpOwotCi0gICAgLy8gQXNzdW1lIG5vbi1udWxsLgotICAgIHJldHVybiBub2RlLmdldE5vZGVOYW1lKCk7Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYSBub2RlIGhhbmRsZSwgcmV0dXJuIHRoZSBYUGF0aCBub2RlIG5hbWUuICBUaGlzIHNob3VsZCBiZQotICAgKiB0aGUgbmFtZSBhcyBkZXNjcmliZWQgYnkgdGhlIFhQYXRoIGRhdGEgbW9kZWwsIE5PVCB0aGUgRE9NLXN0eWxlCi0gICAqIG5hbWUuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIHRoZSBpZCBvZiB0aGUgbm9kZS4KLSAgICogQHJldHVybiBTdHJpbmcgTmFtZSBvZiB0aGlzIG5vZGUsIHdoaWNoIG1heSBiZSBhbiBlbXB0eSBzdHJpbmcuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldE5vZGVOYW1lWChpbnQgbm9kZUhhbmRsZSkKLSAgewotCi0gICAgU3RyaW5nIG5hbWU7Ci0gICAgc2hvcnQgdHlwZSA9IGdldE5vZGVUeXBlKG5vZGVIYW5kbGUpOwotCi0gICAgc3dpdGNoICh0eXBlKQotICAgIHsKLSAgICBjYXNlIERUTS5OQU1FU1BBQ0VfTk9ERSA6Ci0gICAgewotICAgICAgTm9kZSBub2RlID0gZ2V0Tm9kZShub2RlSGFuZGxlKTsKLQotICAgICAgLy8gYXNzdW1lIG5vdCBudWxsLgotICAgICAgbmFtZSA9IG5vZGUuZ2V0Tm9kZU5hbWUoKTsKLSAgICAgIGlmKG5hbWUuc3RhcnRzV2l0aCgieG1sbnM6IikpCi0gICAgICB7Ci0gICAgICAgIG5hbWUgPSBRTmFtZS5nZXRMb2NhbFBhcnQobmFtZSk7Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmKG5hbWUuZXF1YWxzKCJ4bWxucyIpKQotICAgICAgewotICAgICAgICBuYW1lID0gIiI7Ci0gICAgICB9Ci0gICAgfQotICAgIGJyZWFrOwotICAgIGNhc2UgRFRNLkFUVFJJQlVURV9OT0RFIDoKLSAgICBjYXNlIERUTS5FTEVNRU5UX05PREUgOgotICAgIGNhc2UgRFRNLkVOVElUWV9SRUZFUkVOQ0VfTk9ERSA6Ci0gICAgY2FzZSBEVE0uUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFIDoKLSAgICB7Ci0gICAgICBOb2RlIG5vZGUgPSBnZXROb2RlKG5vZGVIYW5kbGUpOwotCi0gICAgICAvLyBhc3N1bWUgbm90IG51bGwuCi0gICAgICBuYW1lID0gbm9kZS5nZXROb2RlTmFtZSgpOwotICAgIH0KLSAgICBicmVhazsKLSAgICBkZWZhdWx0IDoKLSAgICAgIG5hbWUgPSAiIjsKLSAgICB9Ci0KLSAgICByZXR1cm4gbmFtZTsKLSAgfQotCi0gIC8qKgotICAgKiBHaXZlbiBhIG5vZGUgaGFuZGxlLCByZXR1cm4gaXRzIFhQYXRoLXN0eWxlIGxvY2FsbmFtZS4KLSAgICogKEFzIGRlZmluZWQgaW4gTmFtZXNwYWNlcywgdGhpcyBpcyB0aGUgcG9ydGlvbiBvZiB0aGUgbmFtZSBhZnRlciBhbnkKLSAgICogY29sb24gY2hhcmFjdGVyKS4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgdGhlIGlkIG9mIHRoZSBub2RlLgotICAgKiBAcmV0dXJuIFN0cmluZyBMb2NhbCBuYW1lIG9mIHRoaXMgbm9kZS4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0TG9jYWxOYW1lKGludCBub2RlSGFuZGxlKQotICB7Ci0gICAgaWYoSkpLX05FV0NPREUpCi0gICAgewotICAgICAgaW50IGlkPW1ha2VOb2RlSWRlbnRpdHkobm9kZUhhbmRsZSk7Ci0gICAgICBpZihOVUxMPT1pZCkgcmV0dXJuIG51bGw7Ci0gICAgICBOb2RlIG5ld25vZGU9KE5vZGUpbV9ub2Rlcy5lbGVtZW50QXQoaWQpOwotICAgICAgU3RyaW5nIG5ld25hbWU9bmV3bm9kZS5nZXRMb2NhbE5hbWUoKTsKLSAgICAgIGlmIChudWxsID09IG5ld25hbWUpCi0gICAgICB7Ci0gICAgICAgIC8vIFhTTFQgdHJlYXRzIFBJcywgYW5kIHBvc3NpYmx5IG90aGVyIHRoaW5ncywgYXMgaGF2aW5nIFFOYW1lcy4KLSAgICAgICAgU3RyaW5nIHFuYW1lID0gbmV3bm9kZS5nZXROb2RlTmFtZSgpOwotICAgICAgICBpZignIyc9PXFuYW1lLmNoYXJBdCgwKSkKLSAgICAgICAgewotICAgICAgICAgIC8vICBNYXRjaCBvbGQgZGVmYXVsdCBmb3IgdGhpcyBmdW5jdGlvbgotICAgICAgICAgIC8vIFRoaXMgY29udmVyc2lvbiBtYXkgb3IgbWF5IG5vdCBiZSBuZWNlc3NhcnkKLSAgICAgICAgICBuZXduYW1lPSIiOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotICAgICAgICAgIGludCBpbmRleCA9IHFuYW1lLmluZGV4T2YoJzonKTsKLSAgICAgICAgICBuZXduYW1lID0gKGluZGV4IDwgMCkgPyBxbmFtZSA6IHFuYW1lLnN1YnN0cmluZyhpbmRleCArIDEpOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgICByZXR1cm4gbmV3bmFtZTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIFN0cmluZyBuYW1lOwotICAgICAgc2hvcnQgdHlwZSA9IGdldE5vZGVUeXBlKG5vZGVIYW5kbGUpOwotICAgICAgc3dpdGNoICh0eXBlKQotICAgICAgewotICAgICAgY2FzZSBEVE0uQVRUUklCVVRFX05PREUgOgotICAgICAgY2FzZSBEVE0uRUxFTUVOVF9OT0RFIDoKLSAgICAgIGNhc2UgRFRNLkVOVElUWV9SRUZFUkVOQ0VfTk9ERSA6Ci0gICAgICBjYXNlIERUTS5OQU1FU1BBQ0VfTk9ERSA6Ci0gICAgICBjYXNlIERUTS5QUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREUgOgotICAgICAgICB7Ci0gICAgICAgICAgTm9kZSBub2RlID0gZ2V0Tm9kZShub2RlSGFuZGxlKTsKLQotICAgICAgICAgIC8vIGFzc3VtZSBub3QgbnVsbC4KLSAgICAgICAgICBuYW1lID0gbm9kZS5nZXRMb2NhbE5hbWUoKTsKLQotICAgICAgICAgIGlmIChudWxsID09IG5hbWUpCi0gICAgICAgICAgewotICAgICAgICAgICAgU3RyaW5nIHFuYW1lID0gbm9kZS5nZXROb2RlTmFtZSgpOwotICAgICAgICAgICAgaW50IGluZGV4ID0gcW5hbWUuaW5kZXhPZignOicpOwotCi0gICAgICAgICAgICBuYW1lID0gKGluZGV4IDwgMCkgPyBxbmFtZSA6IHFuYW1lLnN1YnN0cmluZyhpbmRleCArIDEpOwotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBicmVhazsKLSAgICAgIGRlZmF1bHQgOgotICAgICAgICBuYW1lID0gIiI7Ci0gICAgICB9Ci0gICAgICByZXR1cm4gbmFtZTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYSBuYW1lc3BhY2UgaGFuZGxlLCByZXR1cm4gdGhlIHByZWZpeCB0aGF0IHRoZSBuYW1lc3BhY2UgZGVjbCBpcwotICAgKiBtYXBwaW5nLgotICAgKiBHaXZlbiBhIG5vZGUgaGFuZGxlLCByZXR1cm4gdGhlIHByZWZpeCB1c2VkIHRvIG1hcCB0byB0aGUgbmFtZXNwYWNlLgotICAgKgotICAgKiA8cD4gJVJFVklFVyUgQXJlIHlvdSBzdXJlIHlvdSB3YW50ICIiIGZvciBubyBwcmVmaXg/ICA8L3A+Ci0gICAqIDxwPiAlUkVWSUVXLUNPTU1FTlQlIEkgdGhpbmsgc28uLi4gbm90IHRvdGFsbHkgc3VyZS4gLXNiICA8L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIHRoZSBpZCBvZiB0aGUgbm9kZS4KLSAgICogQHJldHVybiBTdHJpbmcgcHJlZml4IG9mIHRoaXMgbm9kZSdzIG5hbWUsIG9yICIiIGlmIG5vIGV4cGxpY2l0Ci0gICAqIG5hbWVzcGFjZSBwcmVmaXggd2FzIGdpdmVuLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRQcmVmaXgoaW50IG5vZGVIYW5kbGUpCi0gIHsKLQotICAgIFN0cmluZyBwcmVmaXg7Ci0gICAgc2hvcnQgdHlwZSA9IGdldE5vZGVUeXBlKG5vZGVIYW5kbGUpOwotCi0gICAgc3dpdGNoICh0eXBlKQotICAgIHsKLSAgICBjYXNlIERUTS5OQU1FU1BBQ0VfTk9ERSA6Ci0gICAgewotICAgICAgTm9kZSBub2RlID0gZ2V0Tm9kZShub2RlSGFuZGxlKTsKLQotICAgICAgLy8gYXNzdW1lIG5vdCBudWxsLgotICAgICAgU3RyaW5nIHFuYW1lID0gbm9kZS5nZXROb2RlTmFtZSgpOwotICAgICAgaW50IGluZGV4ID0gcW5hbWUuaW5kZXhPZignOicpOwotCi0gICAgICBwcmVmaXggPSAoaW5kZXggPCAwKSA/ICIiIDogcW5hbWUuc3Vic3RyaW5nKGluZGV4ICsgMSk7Ci0gICAgfQotICAgIGJyZWFrOwotICAgIGNhc2UgRFRNLkFUVFJJQlVURV9OT0RFIDoKLSAgICBjYXNlIERUTS5FTEVNRU5UX05PREUgOgotICAgIHsKLSAgICAgIE5vZGUgbm9kZSA9IGdldE5vZGUobm9kZUhhbmRsZSk7Ci0KLSAgICAgIC8vIGFzc3VtZSBub3QgbnVsbC4KLSAgICAgIFN0cmluZyBxbmFtZSA9IG5vZGUuZ2V0Tm9kZU5hbWUoKTsKLSAgICAgIGludCBpbmRleCA9IHFuYW1lLmluZGV4T2YoJzonKTsKLQotICAgICAgcHJlZml4ID0gKGluZGV4IDwgMCkgPyAiIiA6IHFuYW1lLnN1YnN0cmluZygwLCBpbmRleCk7Ci0gICAgfQotICAgIGJyZWFrOwotICAgIGRlZmF1bHQgOgotICAgICAgcHJlZml4ID0gIiI7Ci0gICAgfQotCi0gICAgcmV0dXJuIHByZWZpeDsKLSAgfQotCi0gIC8qKgotICAgKiBHaXZlbiBhIG5vZGUgaGFuZGxlLCByZXR1cm4gaXRzIERPTS1zdHlsZSBuYW1lc3BhY2UgVVJJCi0gICAqIChBcyBkZWZpbmVkIGluIE5hbWVzcGFjZXMsIHRoaXMgaXMgdGhlIGRlY2xhcmVkIFVSSSB3aGljaCB0aGlzIG5vZGUncwotICAgKiBwcmVmaXggLS0gb3IgZGVmYXVsdCBpbiBsaWV1IHRoZXJlb2YgLS0gd2FzIG1hcHBlZCB0by4pCi0gICAqCi0gICAqIDxwPiVSRVZJRVclIE51bGwgb3IgIiI/IC1zYjwvcD4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgdGhlIGlkIG9mIHRoZSBub2RlLgotICAgKiBAcmV0dXJuIFN0cmluZyBVUkkgdmFsdWUgb2YgdGhpcyBub2RlJ3MgbmFtZXNwYWNlLCBvciBudWxsIGlmIG5vCi0gICAqIG5hbWVzcGFjZSB3YXMgcmVzb2x2ZWQuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldE5hbWVzcGFjZVVSSShpbnQgbm9kZUhhbmRsZSkKLSAgewotICAgIGlmKEpKS19ORVdDT0RFKQotICAgIHsKLSAgICAgIGludCBpZD1tYWtlTm9kZUlkZW50aXR5KG5vZGVIYW5kbGUpOwotICAgICAgaWYoaWQ9PU5VTEwpIHJldHVybiBudWxsOwotICAgICAgTm9kZSBub2RlPShOb2RlKW1fbm9kZXMuZWxlbWVudEF0KGlkKTsKLSAgICAgIHJldHVybiBub2RlLmdldE5hbWVzcGFjZVVSSSgpOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgU3RyaW5nIG5zdXJpOwotICAgICAgc2hvcnQgdHlwZSA9IGdldE5vZGVUeXBlKG5vZGVIYW5kbGUpOwotCi0gICAgICBzd2l0Y2ggKHR5cGUpCi0gICAgICB7Ci0gICAgICBjYXNlIERUTS5BVFRSSUJVVEVfTk9ERSA6Ci0gICAgICBjYXNlIERUTS5FTEVNRU5UX05PREUgOgotICAgICAgY2FzZSBEVE0uRU5USVRZX1JFRkVSRU5DRV9OT0RFIDoKLSAgICAgIGNhc2UgRFRNLk5BTUVTUEFDRV9OT0RFIDoKLSAgICAgIGNhc2UgRFRNLlBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERSA6Ci0gICAgICAgIHsKLSAgICAgICAgICBOb2RlIG5vZGUgPSBnZXROb2RlKG5vZGVIYW5kbGUpOwotCi0gICAgICAgICAgLy8gYXNzdW1lIG5vdCBudWxsLgotICAgICAgICAgIG5zdXJpID0gbm9kZS5nZXROYW1lc3BhY2VVUkkoKTsKLQotICAgICAgICAgIC8vICVUQkQlIEhhbmRsZSBET00xPwotICAgICAgICB9Ci0gICAgICAgIGJyZWFrOwotICAgICAgZGVmYXVsdCA6Ci0gICAgICAgIG5zdXJpID0gbnVsbDsKLSAgICAgIH0KLQotICAgICAgcmV0dXJuIG5zdXJpOwotICAgIH0KLQotICB9Ci0KLSAgLyoqIFV0aWxpdHkgZnVuY3Rpb246IEdpdmVuIGEgRE9NIFRleHQgbm9kZSwgZGV0ZXJtaW5lIHdoZXRoZXIgaXQgaXMKLSAgICogbG9naWNhbGx5IGZvbGxvd2VkIGJ5IGFub3RoZXIgVGV4dCBvciBDREFUQVNlY3Rpb24gbm9kZS4gVGhpcyBtYXkKLSAgICogaW52b2x2ZSB0cmF2ZXJzaW5nIGludG8gRW50aXR5IFJlZmVyZW5jZXMuCi0gICAqCi0gICAqICVSRVZJRVclIERPTSBMZXZlbCAzIGlzIGV4cGVjdGVkIHRvIGFkZCBmdW5jdGlvbmFsaXR5IHdoaWNoIG1heQotICAgKiBhbGxvdyB1cyB0byByZXRpcmUgdGhpcy4KLSAgICovCi0gIHByaXZhdGUgTm9kZSBsb2dpY2FsTmV4dERPTVRleHROb2RlKE5vZGUgbikKLSAgewotICAgICAgICBOb2RlIHA9bi5nZXROZXh0U2libGluZygpOwotICAgICAgICBpZihwPT1udWxsKQotICAgICAgICB7Ci0gICAgICAgICAgICAgICAgLy8gV2FsayBvdXQgb2YgYW55IEVudGl0eVJlZmVyZW5jZU5vZGVzIHRoYXQgZW5kZWQgd2l0aCB0ZXh0Ci0gICAgICAgICAgICAgICAgZm9yKG49bi5nZXRQYXJlbnROb2RlKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBuIT1udWxsICYmIEVOVElUWV9SRUZFUkVOQ0VfTk9ERSA9PSBuLmdldE5vZGVUeXBlKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBuPW4uZ2V0UGFyZW50Tm9kZSgpKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHA9bi5nZXROZXh0U2libGluZygpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYocCE9bnVsbCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIG49cDsKLSAgICAgICAgd2hpbGUobiE9bnVsbCAmJiBFTlRJVFlfUkVGRVJFTkNFX05PREUgPT0gbi5nZXROb2RlVHlwZSgpKQotICAgICAgICB7Ci0gICAgICAgICAgICAgICAgLy8gV2FsayBpbnRvIGFueSBFbnRpdHlSZWZlcmVuY2VOb2RlcyB0aGF0IHN0YXJ0IHdpdGggdGV4dAotICAgICAgICAgICAgICAgIGlmKG4uaGFzQ2hpbGROb2RlcygpKQotICAgICAgICAgICAgICAgICAgICAgICAgbj1uLmdldEZpcnN0Q2hpbGQoKTsKLSAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgICAgICBuPW4uZ2V0TmV4dFNpYmxpbmcoKTsKLSAgICAgICAgfQotICAgICAgICBpZihuIT1udWxsKQotICAgICAgICB7Ci0gICAgICAgICAgICAgICAgLy8gRm91bmQgYSBsb2dpY2FsIG5leHQgc2libGluZy4gSXMgaXQgdGV4dD8KLSAgICAgICAgICAgICAgICBpbnQgbnR5cGU9bi5nZXROb2RlVHlwZSgpOwotICAgICAgICAgICAgICAgIGlmKFRFWFRfTk9ERSAhPSBudHlwZSAmJiBDREFUQV9TRUNUSU9OX05PREUgIT0gbnR5cGUpCi0gICAgICAgICAgICAgICAgICAgICAgICBuPW51bGw7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG47Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYSBub2RlIGhhbmRsZSwgcmV0dXJuIGl0cyBub2RlIHZhbHVlLiBUaGlzIGlzIG1vc3RseQotICAgKiBhcyBkZWZpbmVkIGJ5IHRoZSBET00sIGJ1dCBtYXkgaWdub3JlIHNvbWUgY29udmVuaWVuY2VzLgotICAgKiA8cD4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgVGhlIG5vZGUgaWQuCi0gICAqIEByZXR1cm4gU3RyaW5nIFZhbHVlIG9mIHRoaXMgbm9kZSwgb3IgbnVsbCBpZiBub3QKLSAgICogbWVhbmluZ2Z1bCBmb3IgdGhpcyBub2RlIHR5cGUuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldE5vZGVWYWx1ZShpbnQgbm9kZUhhbmRsZSkKLSAgewotICAgIC8vIFRoZSBfdHlwZShub2RlSGFuZGxlKSBjYWxsIHdhcyB0YWtpbmcgdGhlIGxpb24ncyBzaGFyZSBvZiBvdXIKLSAgICAvLyB0aW1lLCBhbmQgd2FzIHdyb25nIGFueXdheSBzaW5jZSBpdCB3YXNuJ3QgY292ZXJ0aW5nIGhhbmRsZSB0bwotICAgIC8vIGlkZW50aXR5LiBJbmxpbmVkIGl0LgotICAgIGludCB0eXBlID0gX2V4cHR5cGUobWFrZU5vZGVJZGVudGl0eShub2RlSGFuZGxlKSk7Ci0gICAgdHlwZT0oTlVMTCAhPSB0eXBlKSA/IGdldE5vZGVUeXBlKG5vZGVIYW5kbGUpIDogTlVMTDsKLQotICAgIGlmKFRFWFRfTk9ERSE9dHlwZSAmJiBDREFUQV9TRUNUSU9OX05PREUhPXR5cGUpCi0gICAgICByZXR1cm4gZ2V0Tm9kZShub2RlSGFuZGxlKS5nZXROb2RlVmFsdWUoKTsKLQotICAgIC8vIElmIHRoaXMgaXMgYSBEVE0gdGV4dCBub2RlLCBpdCBtYXkgYmUgbWFkZSBvZiBtdWx0aXBsZSBET00gdGV4dAotICAgIC8vIG5vZGVzIC0tIGluY2x1ZGluZyBuYXZpZ2F0aW5nIGludG8gRW50aXR5IFJlZmVyZW5jZXMuIERPTTJEVE0KLSAgICAvLyByZWNvcmRzIHRoZSBmaXJzdCBub2RlIGluIHRoZSBzZXF1ZW5jZSBhbmQgcmVxdWlyZXMgdGhhdCB3ZQotICAgIC8vIHBpY2sgdXAgdGhlIG90aGVycyB3aGVuIHdlIHJldHJpZXZlIHRoZSBEVE0gbm9kZSdzIHZhbHVlLgotICAgIC8vCi0gICAgLy8gJVJFVklFVyUgRE9NIExldmVsIDMgaXMgZXhwZWN0ZWQgdG8gYWRkIGEgIndob2xlIHRleHQiCi0gICAgLy8gcmV0cmlldmFsIG1ldGhvZCB3aGljaCBwZXJmb3JtcyB0aGlzIGZ1bmN0aW9uIGZvciB1cy4KLSAgICBOb2RlIG5vZGUgPSBnZXROb2RlKG5vZGVIYW5kbGUpOwotICAgIE5vZGUgbj1sb2dpY2FsTmV4dERPTVRleHROb2RlKG5vZGUpOwotICAgIGlmKG49PW51bGwpCi0gICAgICByZXR1cm4gbm9kZS5nZXROb2RlVmFsdWUoKTsKLQotICAgIEZhc3RTdHJpbmdCdWZmZXIgYnVmID0gU3RyaW5nQnVmZmVyUG9vbC5nZXQoKTsKLSAgICAgICAgYnVmLmFwcGVuZChub2RlLmdldE5vZGVWYWx1ZSgpKTsKLSAgICB3aGlsZShuIT1udWxsKQotICAgIHsKLSAgICAgIGJ1Zi5hcHBlbmQobi5nZXROb2RlVmFsdWUoKSk7Ci0gICAgICBuPWxvZ2ljYWxOZXh0RE9NVGV4dE5vZGUobik7Ci0gICAgfQotICAgIFN0cmluZyBzID0gKGJ1Zi5sZW5ndGgoKSA+IDApID8gYnVmLnRvU3RyaW5nKCkgOiAiIjsKLSAgICBTdHJpbmdCdWZmZXJQb29sLmZyZWUoYnVmKTsKLSAgICByZXR1cm4gczsKLSAgfQotCi0gIC8qKgotICAgKiAgIEEgZG9jdW1lbnQgdHlwZSBkZWNsYXJhdGlvbiBpbmZvcm1hdGlvbiBpdGVtIGhhcyB0aGUgZm9sbG93aW5nIHByb3BlcnRpZXM6Ci0gICAqCi0gICAqICAgICAxLiBbc3lzdGVtIGlkZW50aWZpZXJdIFRoZSBzeXN0ZW0gaWRlbnRpZmllciBvZiB0aGUgZXh0ZXJuYWwgc3Vic2V0LCBpZgotICAgKiAgICAgICAgaXQgZXhpc3RzLiBPdGhlcndpc2UgdGhpcyBwcm9wZXJ0eSBoYXMgbm8gdmFsdWUuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIHN5c3RlbSBpZGVudGlmaWVyIFN0cmluZyBvYmplY3QsIG9yIG51bGwgaWYgdGhlcmUgaXMgbm9uZS4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0RG9jdW1lbnRUeXBlRGVjbGFyYXRpb25TeXN0ZW1JZGVudGlmaWVyKCkKLSAgewotCi0gICAgRG9jdW1lbnQgZG9jOwotCi0gICAgaWYgKG1fcm9vdC5nZXROb2RlVHlwZSgpID09IE5vZGUuRE9DVU1FTlRfTk9ERSkKLSAgICAgIGRvYyA9IChEb2N1bWVudCkgbV9yb290OwotICAgIGVsc2UKLSAgICAgIGRvYyA9IG1fcm9vdC5nZXRPd25lckRvY3VtZW50KCk7Ci0KLSAgICBpZiAobnVsbCAhPSBkb2MpCi0gICAgewotICAgICAgRG9jdW1lbnRUeXBlIGR0ZCA9IGRvYy5nZXREb2N0eXBlKCk7Ci0KLSAgICAgIGlmIChudWxsICE9IGR0ZCkKLSAgICAgIHsKLSAgICAgICAgcmV0dXJuIGR0ZC5nZXRTeXN0ZW1JZCgpOwotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgcHVibGljIGlkZW50aWZpZXIgb2YgdGhlIGV4dGVybmFsIHN1YnNldCwKLSAgICogbm9ybWFsaXplZCBhcyBkZXNjcmliZWQgaW4gNC4yLjIgRXh0ZXJuYWwgRW50aXRpZXMgW1hNTF0uIElmIHRoZXJlIGlzCi0gICAqIG5vIGV4dGVybmFsIHN1YnNldCBvciBpZiBpdCBoYXMgbm8gcHVibGljIGlkZW50aWZpZXIsIHRoaXMgcHJvcGVydHkKLSAgICogaGFzIG5vIHZhbHVlLgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBwdWJsaWMgaWRlbnRpZmllciBTdHJpbmcgb2JqZWN0LCBvciBudWxsIGlmIHRoZXJlIGlzIG5vbmUuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldERvY3VtZW50VHlwZURlY2xhcmF0aW9uUHVibGljSWRlbnRpZmllcigpCi0gIHsKLQotICAgIERvY3VtZW50IGRvYzsKLQotICAgIGlmIChtX3Jvb3QuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLkRPQ1VNRU5UX05PREUpCi0gICAgICBkb2MgPSAoRG9jdW1lbnQpIG1fcm9vdDsKLSAgICBlbHNlCi0gICAgICBkb2MgPSBtX3Jvb3QuZ2V0T3duZXJEb2N1bWVudCgpOwotCi0gICAgaWYgKG51bGwgIT0gZG9jKQotICAgIHsKLSAgICAgIERvY3VtZW50VHlwZSBkdGQgPSBkb2MuZ2V0RG9jdHlwZSgpOwotCi0gICAgICBpZiAobnVsbCAhPSBkdGQpCi0gICAgICB7Ci0gICAgICAgIHJldHVybiBkdGQuZ2V0UHVibGljSWQoKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSA8Y29kZT5FbGVtZW50PC9jb2RlPiB3aG9zZSA8Y29kZT5JRDwvY29kZT4gaXMgZ2l2ZW4gYnkKLSAgICogPGNvZGU+ZWxlbWVudElkPC9jb2RlPi4gSWYgbm8gc3VjaCBlbGVtZW50IGV4aXN0cywgcmV0dXJucwotICAgKiA8Y29kZT5EVE0uTlVMTDwvY29kZT4uIEJlaGF2aW9yIGlzIG5vdCBkZWZpbmVkIGlmIG1vcmUgdGhhbiBvbmUgZWxlbWVudAotICAgKiBoYXMgdGhpcyA8Y29kZT5JRDwvY29kZT4uIEF0dHJpYnV0ZXMgKGluY2x1ZGluZyB0aG9zZQotICAgKiB3aXRoIHRoZSBuYW1lICJJRCIpIGFyZSBub3Qgb2YgdHlwZSBJRCB1bmxlc3Mgc28gZGVmaW5lZCBieSBEVEQvU2NoZW1hCi0gICAqIGluZm9ybWF0aW9uIGF2YWlsYWJsZSB0byB0aGUgRFRNIGltcGxlbWVudGF0aW9uLgotICAgKiBJbXBsZW1lbnRhdGlvbnMgdGhhdCBkbyBub3Qga25vdyB3aGV0aGVyIGF0dHJpYnV0ZXMgYXJlIG9mIHR5cGUgSUQgb3IKLSAgICogbm90IGFyZSBleHBlY3RlZCB0byByZXR1cm4gPGNvZGU+RFRNLk5VTEw8L2NvZGU+LgotICAgKgotICAgKiA8cD4lUkVWSUVXJSBQcmVzdW1hYmx5IElEcyBhcmUgc3RpbGwgc2NvcGVkIHRvIGEgc2luZ2xlIGRvY3VtZW50LAotICAgKiBhbmQgdGhpcyBvcGVyYXRpb24gc2VhcmNoZXMgb25seSB3aXRoaW4gYSBzaW5nbGUgZG9jdW1lbnQsIHJpZ2h0PwotICAgKiBXb3VsZG4ndCB3YW50IGNvbGxpc2lvbnMgYmV0d2VlbiBEVE1zIGluIHRoZSBzYW1lIHByb2Nlc3MuPC9wPgotICAgKgotICAgKiBAcGFyYW0gZWxlbWVudElkIFRoZSB1bmlxdWUgPGNvZGU+aWQ8L2NvZGU+IHZhbHVlIGZvciBhbiBlbGVtZW50LgotICAgKiBAcmV0dXJuIFRoZSBoYW5kbGUgb2YgdGhlIG1hdGNoaW5nIGVsZW1lbnQuCi0gICAqLwotICBwdWJsaWMgaW50IGdldEVsZW1lbnRCeUlkKFN0cmluZyBlbGVtZW50SWQpCi0gIHsKLQotICAgIERvY3VtZW50IGRvYyA9IChtX3Jvb3QuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLkRPQ1VNRU5UX05PREUpCi0gICAgICAgID8gKERvY3VtZW50KSBtX3Jvb3QgOiBtX3Jvb3QuZ2V0T3duZXJEb2N1bWVudCgpOwotCi0gICAgaWYobnVsbCAhPSBkb2MpCi0gICAgewotICAgICAgTm9kZSBlbGVtID0gZG9jLmdldEVsZW1lbnRCeUlkKGVsZW1lbnRJZCk7Ci0gICAgICBpZihudWxsICE9IGVsZW0pCi0gICAgICB7Ci0gICAgICAgIGludCBlbGVtSGFuZGxlID0gZ2V0SGFuZGxlRnJvbU5vZGUoZWxlbSk7Ci0KLSAgICAgICAgaWYoRFRNLk5VTEwgPT0gZWxlbUhhbmRsZSkKLSAgICAgICAgewotICAgICAgICAgIGludCBpZGVudGl0eSA9IG1fbm9kZXMuc2l6ZSgpLTE7Ci0gICAgICAgICAgd2hpbGUgKERUTS5OVUxMICE9IChpZGVudGl0eSA9IGdldE5leHROb2RlSWRlbnRpdHkoaWRlbnRpdHkpKSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBOb2RlIG5vZGUgPSBnZXROb2RlKGlkZW50aXR5KTsKLSAgICAgICAgICAgIGlmKG5vZGUgPT0gZWxlbSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgZWxlbUhhbmRsZSA9IGdldEhhbmRsZUZyb21Ob2RlKGVsZW0pOwotICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIGVsZW1IYW5kbGU7Ci0gICAgICB9Ci0KLSAgICB9Ci0gICAgcmV0dXJuIERUTS5OVUxMOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoZSBnZXRVbnBhcnNlZEVudGl0eVVSSSBmdW5jdGlvbiByZXR1cm5zIHRoZSBVUkkgb2YgdGhlIHVucGFyc2VkCi0gICAqIGVudGl0eSB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZSBpbiB0aGUgc2FtZSBkb2N1bWVudCBhcyB0aGUgY29udGV4dAotICAgKiBub2RlIChzZWUgWzMuMyBVbnBhcnNlZCBFbnRpdGllc10pLiBJdCByZXR1cm5zIHRoZSBlbXB0eSBzdHJpbmcgaWYKLSAgICogdGhlcmUgaXMgbm8gc3VjaCBlbnRpdHkuCi0gICAqIDxwPgotICAgKiBYTUwgcHJvY2Vzc29ycyBtYXkgY2hvb3NlIHRvIHVzZSB0aGUgU3lzdGVtIElkZW50aWZpZXIgKGlmIG9uZQotICAgKiBpcyBwcm92aWRlZCkgdG8gcmVzb2x2ZSB0aGUgZW50aXR5LCByYXRoZXIgdGhhbiB0aGUgVVJJIGluIHRoZQotICAgKiBQdWJsaWMgSWRlbnRpZmllci4gVGhlIGRldGFpbHMgYXJlIGRlcGVuZGVudCBvbiB0aGUgcHJvY2Vzc29yLCBhbmQKLSAgICogd2Ugd291bGQgaGF2ZSB0byBzdXBwb3J0IHNvbWUgZm9ybSBvZiBwbHVnLWluIHJlc29sdmVyIHRvIGhhbmRsZQotICAgKiB0aGlzIHByb3Blcmx5LiBDdXJyZW50bHksIHdlIHNpbXBseSByZXR1cm4gdGhlIFN5c3RlbSBJZGVudGlmaWVyIGlmCi0gICAqIHByZXNlbnQsIGFuZCBob3BlIHRoYXQgaXQgYSB1c2FibGUgVVJJIG9yIHRoYXQgb3VyIGNhbGxlciBjYW4KLSAgICogbWFwIGl0IHRvIG9uZS4KLSAgICogVE9ETzogUmVzb2x2ZSBQdWJsaWMgSWRlbnRpZmllcnMuLi4gb3IgY29uc2lkZXIgY2hhbmdpbmcgZnVuY3Rpb24gbmFtZS4KLSAgICogPHA+Ci0gICAqIElmIHdlIGZpbmQgYSByZWxhdGl2ZSBVUkkKLSAgICogcmVmZXJlbmNlLCBYTUwgZXhwZWN0cyBpdCB0byBiZSByZXNvbHZlZCBpbiB0ZXJtcyBvZiB0aGUgYmFzZSBVUkkKLSAgICogb2YgdGhlIGRvY3VtZW50LiBUaGUgRE9NIGRvZXNuJ3QgZG8gdGhhdCBmb3IgdXMsIGFuZCBpdCBpc24ndAotICAgKiBlbnRpcmVseSBjbGVhciB3aGV0aGVyIHRoYXQgc2hvdWxkIGJlIGRvbmUgaGVyZTsgY3VycmVudGx5IHRoYXQncwotICAgKiBwdXNoZWQgdXAgdG8gYSBoaWdoZXIgbGV2ZWwgb2Ygb3VyIGFwcGxpY2F0aW9uLiAoTm90ZSB0aGF0IERPTSBMZXZlbAotICAgKiAxIGRpZG4ndCBzdG9yZSB0aGUgZG9jdW1lbnQncyBiYXNlIFVSSS4pCi0gICAqIFRPRE86IENvbnNpZGVyIHJlc29sdmluZyBSZWxhdGl2ZSBVUklzLgotICAgKiA8cD4KLSAgICogKFRoZSBET00ncyBzdGF0ZW1lbnQgdGhhdCAiQW4gWE1MIHByb2Nlc3NvciBtYXkgY2hvb3NlIHRvCi0gICAqIGNvbXBsZXRlbHkgZXhwYW5kIGVudGl0aWVzIGJlZm9yZSB0aGUgc3RydWN0dXJlIG1vZGVsIGlzIHBhc3NlZAotICAgKiB0byB0aGUgRE9NIiByZWZlcnMgb25seSB0byBwYXJzZWQgZW50aXRpZXMsIG5vdCB1bnBhcnNlZCwgYW5kIGhlbmNlCi0gICAqIGRvZXNuJ3QgYWZmZWN0IHRoaXMgZnVuY3Rpb24uKQotICAgKgotICAgKiBAcGFyYW0gbmFtZSBBIHN0cmluZyBjb250YWluaW5nIHRoZSBFbnRpdHkgTmFtZSBvZiB0aGUgdW5wYXJzZWQKLSAgICogZW50aXR5LgotICAgKgotICAgKiBAcmV0dXJuIFN0cmluZyBjb250YWluaW5nIHRoZSBVUkkgb2YgdGhlIFVucGFyc2VkIEVudGl0eSwgb3IgYW4KLSAgICogZW1wdHkgc3RyaW5nIGlmIG5vIHN1Y2ggZW50aXR5IGV4aXN0cy4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0VW5wYXJzZWRFbnRpdHlVUkkoU3RyaW5nIG5hbWUpCi0gIHsKLQotICAgIFN0cmluZyB1cmwgPSAiIjsKLSAgICBEb2N1bWVudCBkb2MgPSAobV9yb290LmdldE5vZGVUeXBlKCkgPT0gTm9kZS5ET0NVTUVOVF9OT0RFKQotICAgICAgICA/IChEb2N1bWVudCkgbV9yb290IDogbV9yb290LmdldE93bmVyRG9jdW1lbnQoKTsKLQotICAgIGlmIChudWxsICE9IGRvYykKLSAgICB7Ci0gICAgICBEb2N1bWVudFR5cGUgZG9jdHlwZSA9IGRvYy5nZXREb2N0eXBlKCk7Ci0KLSAgICAgIGlmIChudWxsICE9IGRvY3R5cGUpCi0gICAgICB7Ci0gICAgICAgIE5hbWVkTm9kZU1hcCBlbnRpdGllcyA9IGRvY3R5cGUuZ2V0RW50aXRpZXMoKTsKLSAgICAgICAgaWYobnVsbCA9PSBlbnRpdGllcykKLSAgICAgICAgICByZXR1cm4gdXJsOwotICAgICAgICBFbnRpdHkgZW50aXR5ID0gKEVudGl0eSkgZW50aXRpZXMuZ2V0TmFtZWRJdGVtKG5hbWUpOwotICAgICAgICBpZihudWxsID09IGVudGl0eSkKLSAgICAgICAgICByZXR1cm4gdXJsOwotCi0gICAgICAgIFN0cmluZyBub3RhdGlvbk5hbWUgPSBlbnRpdHkuZ2V0Tm90YXRpb25OYW1lKCk7Ci0KLSAgICAgICAgaWYgKG51bGwgIT0gbm90YXRpb25OYW1lKSAgLy8gdGhlbiBpdCdzIHVucGFyc2VkCi0gICAgICAgIHsKLSAgICAgICAgICAvLyBUaGUgZHJhZnQgc2F5czogIlRoZSBYU0xUIHByb2Nlc3NvciBtYXkgdXNlIHRoZSBwdWJsaWMKLSAgICAgICAgICAvLyBpZGVudGlmaWVyIHRvIGdlbmVyYXRlIGEgVVJJIGZvciB0aGUgZW50aXR5IGluc3RlYWQgb2YgdGhlIFVSSQotICAgICAgICAgIC8vIHNwZWNpZmllZCBpbiB0aGUgc3lzdGVtIGlkZW50aWZpZXIuIElmIHRoZSBYU0xUIHByb2Nlc3NvciBkb2VzCi0gICAgICAgICAgLy8gbm90IHVzZSB0aGUgcHVibGljIGlkZW50aWZpZXIgdG8gZ2VuZXJhdGUgdGhlIFVSSSwgaXQgbXVzdCB1c2UKLSAgICAgICAgICAvLyB0aGUgc3lzdGVtIGlkZW50aWZpZXI7IGlmIHRoZSBzeXN0ZW0gaWRlbnRpZmllciBpcyBhIHJlbGF0aXZlCi0gICAgICAgICAgLy8gVVJJLCBpdCBtdXN0IGJlIHJlc29sdmVkIGludG8gYW4gYWJzb2x1dGUgVVJJIHVzaW5nIHRoZSBVUkkgb2YKLSAgICAgICAgICAvLyB0aGUgcmVzb3VyY2UgY29udGFpbmluZyB0aGUgZW50aXR5IGRlY2xhcmF0aW9uIGFzIHRoZSBiYXNlCi0gICAgICAgICAgLy8gVVJJIFtSRkMyMzk2XS4iCi0gICAgICAgICAgLy8gU28gSSdtIGZhbGxpbmcgYSBiaXQgc2hvcnQgaGVyZS4KLSAgICAgICAgICB1cmwgPSBlbnRpdHkuZ2V0U3lzdGVtSWQoKTsKLQotICAgICAgICAgIGlmIChudWxsID09IHVybCkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICB1cmwgPSBlbnRpdHkuZ2V0UHVibGljSWQoKTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgIHsKLSAgICAgICAgICAgIC8vIFRoaXMgc2hvdWxkIGJlIHJlc29sdmVkIHRvIGFuIGFic29sdXRlIFVSTCwgYnV0IHRoYXQncyBoYXJkCi0gICAgICAgICAgICAvLyB0byBkbyBmcm9tIGhlcmUuCi0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotCi0gICAgcmV0dXJuIHVybDsKLSAgfQotCi0gIC8qKgotICAgKiAgICAgNS4gW3NwZWNpZmllZF0gQSBmbGFnIGluZGljYXRpbmcgd2hldGhlciB0aGlzIGF0dHJpYnV0ZSB3YXMgYWN0dWFsbHkKLSAgICogICAgICAgIHNwZWNpZmllZCBpbiB0aGUgc3RhcnQtdGFnIG9mIGl0cyBlbGVtZW50LCBvciB3YXMgZGVmYXVsdGVkIGZyb20gdGhlCi0gICAqICAgICAgICBEVEQuCi0gICAqCi0gICAqIEBwYXJhbSBhdHRyaWJ1dGVIYW5kbGUgdGhlIGF0dHJpYnV0ZSBoYW5kbGUKLSAgICogQHJldHVybiA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgYXR0cmlidXRlIHdhcyBzcGVjaWZpZWQ7Ci0gICAqICAgICAgICAgPGNvZGU+ZmFsc2U8L2NvZGU+IGlmIGl0IHdhcyBkZWZhdWx0ZWQuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBpc0F0dHJpYnV0ZVNwZWNpZmllZChpbnQgYXR0cmlidXRlSGFuZGxlKQotICB7Ci0gICAgaW50IHR5cGUgPSBnZXROb2RlVHlwZShhdHRyaWJ1dGVIYW5kbGUpOwotCi0gICAgaWYgKERUTS5BVFRSSUJVVEVfTk9ERSA9PSB0eXBlKQotICAgIHsKLSAgICAgIEF0dHIgYXR0ciA9IChBdHRyKWdldE5vZGUoYXR0cmlidXRlSGFuZGxlKTsKLSAgICAgIHJldHVybiBhdHRyLmdldFNwZWNpZmllZCgpOwotICAgIH0KLSAgICByZXR1cm4gZmFsc2U7Ci0gIH0KLQotICAvKiogQmluZCBhbiBJbmNyZW1lbnRhbFNBWFNvdXJjZSB0byB0aGlzIERUTS4gTk9UIFJFTEVWQU5UIGZvciBET00yRFRNLCBzaW5jZQotICAgKiB3ZSdyZSB3cmFwcGVkIGFyb3VuZCBhbiBleGlzdGluZyBET00uCi0gICAqCi0gICAqIEBwYXJhbSBzb3VyY2UgVGhlIEluY3JlbWVudGFsU0FYU291cmNlIHRoYXQgd2Ugd2FudCB0byByZWNpZXZlIGV2ZW50cyBmcm9tCi0gICAqIG9uIGRlbWFuZC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldEluY3JlbWVudGFsU0FYU291cmNlKEluY3JlbWVudGFsU0FYU291cmNlIHNvdXJjZSkKLSAgewotICB9Ci0KLSAgLyoqIGdldENvbnRlbnRIYW5kbGVyIHJldHVybnMgIm91ciBTQVggYnVpbGRlciIgLS0gdGhlIHRoaW5nIHRoYXQKLSAgICogc29tZW9uZSBlbHNlIHNob3VsZCBzZW5kIFNBWCBldmVudHMgdG8gaW4gb3JkZXIgdG8gZXh0ZW5kIHRoaXMKLSAgICogRFRNIG1vZGVsLgotICAgKgotICAgKiBAcmV0dXJuIG51bGwgaWYgdGhpcyBtb2RlbCBkb2Vzbid0IHJlc3BvbmQgdG8gU0FYIGV2ZW50cywKLSAgICogInRoaXMiIGlmIHRoZSBEVE0gb2JqZWN0IGhhcyBhIGJ1aWx0LWluIFNBWCBDb250ZW50SGFuZGxlciwKLSAgICogdGhlIEluY3JtZW50YWxTQVhTb3VyY2UgaWYgd2UncmUgYm91bmQgdG8gb25lIGFuZCBzaG91bGQgcmVjZWl2ZQotICAgKiB0aGUgU0FYIHN0cmVhbSB2aWEgaXQgZm9yIGluY3JlbWVudGFsIGJ1aWxkIHB1cnBvc2VzLi4uCi0gICAqICovCi0gIHB1YmxpYyBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciBnZXRDb250ZW50SGFuZGxlcigpCi0gIHsKLSAgICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGlzIERUTSdzIGxleGljYWwgaGFuZGxlci4KLSAgICoKLSAgICogJVJFVklFVyUgU2hvdWxkIHRoaXMgcmV0dXJuIG51bGwgaWYgY29uc3RydXRpb24gYWxyZWFkeSBkb25lL2JlZ3VuPwotICAgKgotICAgKiBAcmV0dXJuIG51bGwgaWYgdGhpcyBtb2RlbCBkb2Vzbid0IHJlc3BvbmQgdG8gbGV4aWNhbCBTQVggZXZlbnRzLAotICAgKiAidGhpcyIgaWYgdGhlIERUTSBvYmplY3QgaGFzIGEgYnVpbHQtaW4gU0FYIENvbnRlbnRIYW5kbGVyLAotICAgKiB0aGUgSW5jcmVtZW50YWxTQVhTb3VyY2UgaWYgd2UncmUgYm91bmQgdG8gb25lIGFuZCBzaG91bGQgcmVjZWl2ZQotICAgKiB0aGUgU0FYIHN0cmVhbSB2aWEgaXQgZm9yIGluY3JlbWVudGFsIGJ1aWxkIHB1cnBvc2VzLi4uCi0gICAqLwotICBwdWJsaWMgb3JnLnhtbC5zYXguZXh0LkxleGljYWxIYW5kbGVyIGdldExleGljYWxIYW5kbGVyKCkKLSAgewotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhpcyBEVE0ncyBFbnRpdHlSZXNvbHZlci4KLSAgICoKLSAgICogQHJldHVybiBudWxsIGlmIHRoaXMgbW9kZWwgZG9lc24ndCByZXNwb25kIHRvIFNBWCBlbnRpdHkgcmVmIGV2ZW50cy4KLSAgICovCi0gIHB1YmxpYyBvcmcueG1sLnNheC5FbnRpdHlSZXNvbHZlciBnZXRFbnRpdHlSZXNvbHZlcigpCi0gIHsKLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGlzIERUTSdzIERUREhhbmRsZXIuCi0gICAqCi0gICAqIEByZXR1cm4gbnVsbCBpZiB0aGlzIG1vZGVsIGRvZXNuJ3QgcmVzcG9uZCB0byBTQVggZHRkIGV2ZW50cy4KLSAgICovCi0gIHB1YmxpYyBvcmcueG1sLnNheC5EVERIYW5kbGVyIGdldERUREhhbmRsZXIoKQotICB7Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhpcyBEVE0ncyBFcnJvckhhbmRsZXIuCi0gICAqCi0gICAqIEByZXR1cm4gbnVsbCBpZiB0aGlzIG1vZGVsIGRvZXNuJ3QgcmVzcG9uZCB0byBTQVggZXJyb3IgZXZlbnRzLgotICAgKi8KLSAgcHVibGljIG9yZy54bWwuc2F4LkVycm9ySGFuZGxlciBnZXRFcnJvckhhbmRsZXIoKQotICB7Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhpcyBEVE0ncyBEZWNsSGFuZGxlci4KLSAgICoKLSAgICogQHJldHVybiBudWxsIGlmIHRoaXMgbW9kZWwgZG9lc24ndCByZXNwb25kIHRvIFNBWCBEZWNsIGV2ZW50cy4KLSAgICovCi0gIHB1YmxpYyBvcmcueG1sLnNheC5leHQuRGVjbEhhbmRsZXIgZ2V0RGVjbEhhbmRsZXIoKQotICB7Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKiBAcmV0dXJuIHRydWUgaWZmIHdlJ3JlIGJ1aWxkaW5nIHRoaXMgbW9kZWwgaW5jcmVtZW50YWxseSAoZWcKLSAgICogd2UncmUgcGFydG5lcmVkIHdpdGggYSBJbmNyZW1lbnRhbFNBWFNvdXJjZSkgYW5kIHRodXMgcmVxdWlyZSB0aGF0IHRoZQotICAgKiB0cmFuc2Zvcm1hdGlvbiBhbmQgdGhlIHBhcnNlIHJ1biBzaW11bHRhbmVvdXNseS4gR3VpZGFuY2UgdG8gdGhlCi0gICAqIERUTU1hbmFnZXIuCi0gICAqICovCi0gIHB1YmxpYyBib29sZWFuIG5lZWRzVHdvVGhyZWFkcygpCi0gIHsKLSAgICByZXR1cm4gZmFsc2U7Ci0gIH0KLQotICAvLyA9PT09PT09PT09IERpcmVjdCBTQVggRGlzcGF0Y2gsIGZvciBvcHRpbWl6YXRpb24gcHVycG9zZXMgPT09PT09PT0KLQotICAvKioKLSAgICogUmV0dXJucyB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgPHZhcj5jaDwvdmFyPiBjb25mb3JtcyB0byB0aGUgWE1MIDEuMCBkZWZpbml0aW9uCi0gICAqIG9mIHdoaXRlc3BhY2UuICBSZWZlciB0byA8QSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy14bWwtMTk5ODAyMTAjTlQtUyI+Ci0gICAqIHRoZSBkZWZpbml0aW9uIG9mIDxDT0RFPlM8L0NPREU+PC9BPiBmb3IgZGV0YWlscy4KLSAgICogQHBhcmFtICAgY2ggICAgICBDaGFyYWN0ZXIgdG8gY2hlY2sgYXMgWE1MIHdoaXRlc3BhY2UuCi0gICAqIEByZXR1cm4gICAgICAgICAgPXRydWUgaWYgPHZhcj5jaDwvdmFyPiBpcyBYTUwgd2hpdGVzcGFjZTsgb3RoZXJ3aXNlID1mYWxzZS4KLSAgICovCi0gIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNTcGFjZShjaGFyIGNoKQotICB7Ci0gICAgcmV0dXJuIFhNTENoYXJhY3RlclJlY29nbml6ZXIuaXNXaGl0ZVNwYWNlKGNoKTsgIC8vIFRha2UgdGhlIGVhc3kgd2F5IG91dCBmb3Igbm93LgotICB9Ci0KLSAgLyoqCi0gICAqIERpcmVjdGx5IGNhbGwgdGhlCi0gICAqIGNoYXJhY3RlcnMgbWV0aG9kIG9uIHRoZSBwYXNzZWQgQ29udGVudEhhbmRsZXIgZm9yIHRoZQotICAgKiBzdHJpbmctdmFsdWUgb2YgdGhlIGdpdmVuIG5vZGUgKHNlZSBodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aCNkYXRhLW1vZGVsCi0gICAqIGZvciB0aGUgZGVmaW5pdGlvbiBvZiBhIG5vZGUncyBzdHJpbmctdmFsdWUpLiBNdWx0aXBsZSBjYWxscyB0byB0aGUKLSAgICogQ29udGVudEhhbmRsZXIncyBjaGFyYWN0ZXJzIG1ldGhvZHMgbWF5IHdlbGwgb2NjdXIgZm9yIGEgc2luZ2xlIGNhbGwgdG8KLSAgICogdGhpcyBtZXRob2QuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIFRoZSBub2RlIElELgotICAgKiBAcGFyYW0gY2ggQSBub24tbnVsbCByZWZlcmVuY2UgdG8gYSBDb250ZW50SGFuZGxlci4KLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGRpc3BhdGNoQ2hhcmFjdGVyc0V2ZW50cygKLSAgICAgICAgICBpbnQgbm9kZUhhbmRsZSwgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIgY2gsCi0gICAgICAgICAgYm9vbGVhbiBub3JtYWxpemUpCi0gICAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBpZihub3JtYWxpemUpCi0gICAgewotICAgICAgWE1MU3RyaW5nIHN0ciA9IGdldFN0cmluZ1ZhbHVlKG5vZGVIYW5kbGUpOwotICAgICAgc3RyID0gc3RyLmZpeFdoaXRlU3BhY2UodHJ1ZSwgdHJ1ZSwgZmFsc2UpOwotICAgICAgc3RyLmRpc3BhdGNoQ2hhcmFjdGVyc0V2ZW50cyhjaCk7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBpbnQgdHlwZSA9IGdldE5vZGVUeXBlKG5vZGVIYW5kbGUpOwotICAgICAgTm9kZSBub2RlID0gZ2V0Tm9kZShub2RlSGFuZGxlKTsKLSAgICAgIGRpc3BhdGNoTm9kZURhdGEobm9kZSwgY2gsIDApOwotICAgICAgICAgIC8vIFRleHQgY29hbGl0aW9uIC0tIGEgRFRNIHRleHQgbm9kZSBtYXkgcmVwcmVzZW50IG11bHRpcGxlCi0gICAgICAgICAgLy8gRE9NIG5vZGVzLgotICAgICAgICAgIGlmKFRFWFRfTk9ERSA9PSB0eXBlIHx8IENEQVRBX1NFQ1RJT05fTk9ERSA9PSB0eXBlKQotICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgIHdoaWxlKCBudWxsICE9IChub2RlPWxvZ2ljYWxOZXh0RE9NVGV4dE5vZGUobm9kZSkpICkKLSAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICBkaXNwYXRjaE5vZGVEYXRhKG5vZGUsIGNoLCAwKTsKLSAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICB9Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFJldHJpZXZlIHRoZSB0ZXh0IGNvbnRlbnQgb2YgYSBET00gc3VidHJlZSwgYXBwZW5kaW5nIGl0IGludG8gYQotICAgKiB1c2VyLXN1cHBsaWVkIEZhc3RTdHJpbmdCdWZmZXIgb2JqZWN0LiBOb3RlIHRoYXQgYXR0cmlidXRlcyBhcmUKLSAgICogbm90IGNvbnNpZGVyZWQgcGFydCBvZiB0aGUgY29udGVudCBvZiBhbiBlbGVtZW50LgotICAgKiA8cD4KLSAgICogVGhlcmUgYXJlIG9wZW4gcXVlc3Rpb25zIHJlZ2FyZGluZyB3aGl0ZXNwYWNlIHN0cmlwcGluZy4KLSAgICogQ3VycmVudGx5IHdlIG1ha2Ugbm8gc3BlY2lhbCBlZmZvcnQgaW4gdGhhdCByZWdhcmQsIHNpbmNlIHRoZSBzdGFuZGFyZAotICAgKiBET00gZG9lc24ndCB5ZXQgcHJvdmlkZSBEVEQtYmFzZWQgaW5mb3JtYXRpb24gdG8gZGlzdGluZ3Vpc2gKLSAgICogd2hpdGVzcGFjZS1pbi1lbGVtZW50LWNvbnRleHQgZnJvbSBnZW51aW5lICNQQ0RBVEEuIE5vdGUgdGhhdCB3ZQotICAgKiBzaG91bGQgcHJvYmFibHkgYWxzbyBjb25zaWRlciB4bWw6c3BhY2UgaWYvd2hlbiB3ZSBhZGRyZXNzIHRoaXMuCi0gICAqIERPTSBMZXZlbCAzIG1heSBzb2x2ZSB0aGUgcHJvYmxlbSBmb3IgdXMuCi0gICAqIDxwPgotICAgKiAlUkVWSUVXJSBOb3RlIHRoYXQgYXMgYSBET00tbGV2ZWwgb3BlcmF0aW9uLCBpdCBjYW4gYmUgYXJndWVkIHRoYXQgdGhpcwotICAgKiByb3V0aW5lIF9zaG91bGRuJ3RfIHBlcmZvcm0gYW55IHByb2Nlc3NpbmcgYmV5b25kIHdoYXQgdGhlIERPTSBhbHJlYWR5Ci0gICAqIGRvZXMsIGFuZCB0aGF0IHdoaXRlc3BhY2Ugc3RyaXBwaW5nIGFuZCBzbyBvbiBiZWxvbmcgYXQgdGhlIERUTSBsZXZlbC4KLSAgICogSWYgeW91IHdhbnQgYSBzdHJpcHBlZCBET00gdmlldywgd3JhcCBEVE0yRE9NIGFyb3VuZCBET00yRFRNLgotICAgKgotICAgKiBAcGFyYW0gbm9kZSBOb2RlIHdob3NlIHN1YnRyZWUgaXMgdG8gYmUgd2Fsa2VkLCBnYXRoZXJpbmcgdGhlCi0gICAqIGNvbnRlbnRzIG9mIGFsbCBUZXh0IG9yIENEQVRBU2VjdGlvbiBub2Rlcy4KLSAgICovCi0gIHByb3RlY3RlZCBzdGF0aWMgdm9pZCBkaXNwYXRjaE5vZGVEYXRhKE5vZGUgbm9kZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIgY2gsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBkZXB0aCkKLSAgICAgICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgc3dpdGNoIChub2RlLmdldE5vZGVUeXBlKCkpCi0gICAgewotICAgIGNhc2UgTm9kZS5ET0NVTUVOVF9GUkFHTUVOVF9OT0RFIDoKLSAgICBjYXNlIE5vZGUuRE9DVU1FTlRfTk9ERSA6Ci0gICAgY2FzZSBOb2RlLkVMRU1FTlRfTk9ERSA6Ci0gICAgewotICAgICAgZm9yIChOb2RlIGNoaWxkID0gbm9kZS5nZXRGaXJzdENoaWxkKCk7IG51bGwgIT0gY2hpbGQ7Ci0gICAgICAgICAgICAgIGNoaWxkID0gY2hpbGQuZ2V0TmV4dFNpYmxpbmcoKSkKLSAgICAgIHsKLSAgICAgICAgZGlzcGF0Y2hOb2RlRGF0YShjaGlsZCwgY2gsIGRlcHRoKzEpOwotICAgICAgfQotICAgIH0KLSAgICBicmVhazsKLSAgICBjYXNlIE5vZGUuUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFIDogLy8gJVJFVklFVyUKLSAgICBjYXNlIE5vZGUuQ09NTUVOVF9OT0RFIDoKLSAgICAgIGlmKDAgIT0gZGVwdGgpCi0gICAgICAgIGJyZWFrOwotICAgICAgICAvLyBOT1RFOiBCZWNhdXNlIHRoaXMgb3BlcmF0aW9uIHdvcmtzIGluIHRoZSBET00gc3BhY2UsIGl0IGRvZXMgX25vdF8gYXR0ZW1wdAotICAgICAgICAvLyB0byBwZXJmb3JtIFRleHQgQ29hbGl0aW9uLiBUaGF0IHNob3VsZCBvbmx5IGJlIGRvbmUgaW4gRFRNIHNwYWNlLgotICAgIGNhc2UgTm9kZS5URVhUX05PREUgOgotICAgIGNhc2UgTm9kZS5DREFUQV9TRUNUSU9OX05PREUgOgotICAgIGNhc2UgTm9kZS5BVFRSSUJVVEVfTk9ERSA6Ci0gICAgICBTdHJpbmcgc3RyID0gbm9kZS5nZXROb2RlVmFsdWUoKTsKLSAgICAgIGlmKGNoIGluc3RhbmNlb2YgQ2hhcmFjdGVyTm9kZUhhbmRsZXIpCi0gICAgICB7Ci0gICAgICAgICgoQ2hhcmFjdGVyTm9kZUhhbmRsZXIpY2gpLmNoYXJhY3RlcnMobm9kZSk7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIGNoLmNoYXJhY3RlcnMoc3RyLnRvQ2hhckFycmF5KCksIDAsIHN0ci5sZW5ndGgoKSk7Ci0gICAgICB9Ci0gICAgICBicmVhazsKLS8vICAgIC8qIGNhc2UgTm9kZS5QUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREUgOgotLy8gICAgICAvLyB3YXJuaW5nKFhQQVRIRXJyb3JSZXNvdXJjZXMuV0dfUEFSU0lOR19BTkRfUFJFUEFSSU5HKTsKLS8vICAgICAgYnJlYWs7ICovCi0gICAgZGVmYXVsdCA6Ci0gICAgICAvLyBpZ25vcmUKLSAgICAgIGJyZWFrOwotICAgIH0KLSAgfQotCi0gIFRyZWVXYWxrZXIgbV93YWxrZXIgPSBuZXcgVHJlZVdhbGtlcihudWxsKTsKLQotICAvKioKLSAgICogRGlyZWN0bHkgY3JlYXRlIFNBWCBwYXJzZXIgZXZlbnRzIGZyb20gYSBzdWJ0cmVlLgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBUaGUgbm9kZSBJRC4KLSAgICogQHBhcmFtIGNoIEEgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGEgQ29udGVudEhhbmRsZXIuCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBkaXNwYXRjaFRvRXZlbnRzKGludCBub2RlSGFuZGxlLCBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciBjaCkKLSAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBUcmVlV2Fsa2VyIHRyZWVXYWxrZXIgPSBtX3dhbGtlcjsKLSAgICBDb250ZW50SGFuZGxlciBwcmV2Q0ggPSB0cmVlV2Fsa2VyLmdldENvbnRlbnRIYW5kbGVyKCk7Ci0KLSAgICBpZihudWxsICE9IHByZXZDSCkKLSAgICB7Ci0gICAgICB0cmVlV2Fsa2VyID0gbmV3IFRyZWVXYWxrZXIobnVsbCk7Ci0gICAgfQotICAgIHRyZWVXYWxrZXIuc2V0Q29udGVudEhhbmRsZXIoY2gpOwotCi0gICAgdHJ5Ci0gICAgewotICAgICAgTm9kZSBub2RlID0gZ2V0Tm9kZShub2RlSGFuZGxlKTsKLSAgICAgIHRyZWVXYWxrZXIudHJhdmVyc2VGcmFnbWVudChub2RlKTsKLSAgICB9Ci0gICAgZmluYWxseQotICAgIHsKLSAgICAgIHRyZWVXYWxrZXIuc2V0Q29udGVudEhhbmRsZXIobnVsbCk7Ci0gICAgfQotICB9Ci0KLSAgcHVibGljIGludGVyZmFjZSBDaGFyYWN0ZXJOb2RlSGFuZGxlcgotICB7Ci0gICAgcHVibGljIHZvaWQgY2hhcmFjdGVycyhOb2RlIG5vZGUpCi0gICAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotICB9Ci0KLSAgLyoqCi0gICAqIEZvciB0aGUgbW9tZW50IGFsbCB0aGUgcnVuIHRpbWUgcHJvcGVydGllcyBhcmUgaWdub3JlZCBieSB0aGlzCi0gICAqIGNsYXNzLgotICAgKgotICAgKiBAcGFyYW0gcHJvcGVydHkgYSA8Y29kZT5TdHJpbmc8L2NvZGU+IHZhbHVlCi0gICAqIEBwYXJhbSB2YWx1ZSBhbiA8Y29kZT5PYmplY3Q8L2NvZGU+IHZhbHVlCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRQcm9wZXJ0eShTdHJpbmcgcHJvcGVydHksIE9iamVjdCB2YWx1ZSkKLSAgewotICB9Ci0KLSAgLyoqCi0gICAqIE5vIHNvdXJjZSBpbmZvcm1hdGlvbiBpcyBhdmFpbGFibGUgZm9yIERPTTJEVE0sIHNvIHJldHVybgotICAgKiA8Y29kZT5udWxsPC9jb2RlPiBoZXJlLgotICAgKgotICAgKiBAcGFyYW0gbm9kZSBhbiA8Y29kZT5pbnQ8L2NvZGU+IHZhbHVlCi0gICAqIEByZXR1cm4gbnVsbAotICAgKi8KLSAgcHVibGljIFNvdXJjZUxvY2F0b3IgZ2V0U291cmNlTG9jYXRvckZvcihpbnQgbm9kZSkKLSAgewotICAgIHJldHVybiBudWxsOwotICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9yZWYvZG9tMmR0bS9ET00yRFRNZGVmYXVsdE5hbWVzcGFjZURlY2xhcmF0aW9uTm9kZS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL3JlZi9kb20yZHRtL0RPTTJEVE1kZWZhdWx0TmFtZXNwYWNlRGVjbGFyYXRpb25Ob2RlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDY4Y2FmZGQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL3JlZi9kb20yZHRtL0RPTTJEVE1kZWZhdWx0TmFtZXNwYWNlRGVjbGFyYXRpb25Ob2RlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw2ODAgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRE9NMkRUTWRlZmF1bHROYW1lc3BhY2VEZWNsYXJhdGlvbk5vZGUuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNSAwODoxNToxMSBzdXJlc2hfZW1haWxpZCBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0ucmVmLmRvbTJkdG07Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1FeGNlcHRpb247Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5BdHRyOwotaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLkVsZW1lbnQ7Ci1pbXBvcnQgb3JnLnczYy5kb20uTmFtZWROb2RlTWFwOwotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZUxpc3Q7Ci1pbXBvcnQgb3JnLnczYy5kb20uVHlwZUluZm87Ci1pbXBvcnQgb3JnLnczYy5kb20uVXNlckRhdGFIYW5kbGVyOwotaW1wb3J0IG9yZy53M2MuZG9tLkRPTUV4Y2VwdGlvbjsKLQotLyoqIFRoaXMgaXMgYSBrbHVnZSB0byBsZXQgdXMgc2hvdmUgYSBkZWNsYXJhdGlvbiBmb3IgeG1sOiBpbnRvIHRoZQotICogRE9NMkRUTSBtb2RlbC4gIEJhc2ljYWxseSwgaXQgY3JlYXRlcyBhIHByb3h5IG5vZGUgaW4gRE9NIHNwYWNlIHRvCi0gKiBjYXJyeSB0aGUgYWRkaXRpb25hbCBpbmZvcm1hdGlvbi4gVGhpcyBpcyBfTk9UXyBhIGZ1bGwgRE9NCi0gKiBpbXBsZW1lbnRhdGlvbiwgYW5kIHNob3VsZG4ndCBiZSBvbmUgc2luY2UgaXQgc2l0cyBhbG9uZ3NpZGUgdGhlCi0gKiBET00gcmF0aGVyIHRoYW4gYmVjb21pbmcgcGFydCBvZiB0aGUgRE9NIG1vZGVsLgotICoKLSAqIChUaGlzIHVzZWQgdG8gYmUgYW4gaW50ZXJuYWwgY2xhc3Mgd2l0aGluIERPTTJEVE0uIE1vdmVkIG91dCBiZWNhdXNlCi0gKiBJIG5lZWQgdG8gcGVyZm9ybSBhbiBpbnN0YW5jZW9mIG9wZXJhdGlvbiBvbiBpdCB0byBzdXBwb3J0IGEgdGVtcG9yYXJ5Ci0gKiB3b3JrYXJvdW5kIGluIERUTU1hbmFnZXJEZWZhdWx0LikKLSAqCi0gKiAlUkVWSUVXJSBXaGF0IGlmIHRoZSBET00yRFRNIHdhcyBidWlsdCBhcm91bmQgYSBEb2N1bWVudEZyYWdtZW50IGFuZAotICogdGhlcmUgaXNuJ3QgYSBzaW5nbGUgcm9vdCBlbGVtZW50PyBJIHRoaW5rIHRoaXMgZmFpbHMgdGhhdCBjYXNlLi4uCi0gKgotICogJVJFVklFVyUgQW4gYWx0ZXJuYXRpdmUgc29sdXRpb24gd291bGQgYmUgdG8gY3JlYXRlIHRoZSBub2RlIF9vbmx5XwotICogaW4gRFRNIHNwYWNlLCBidXQgZ2l2ZW4gaG93IERPTTJEVE0gaXMgY3VycmVudGx5IHdyaXR0ZW4gSSB0aGluawotICogdGhpcyBpcyBzaW1wbGVzdC4KLSAqICovCi1wdWJsaWMgY2xhc3MgRE9NMkRUTWRlZmF1bHROYW1lc3BhY2VEZWNsYXJhdGlvbk5vZGUgaW1wbGVtZW50cyBBdHRyLFR5cGVJbmZvCi17Ci0gIGZpbmFsIFN0cmluZyBOT1RfU1VQUE9SVEVEX0VSUj0iVW5zdXBwb3J0ZWQgb3BlcmF0aW9uIG9uIHBzZXVkb25vZGUiOwotCi0gIEVsZW1lbnQgcHNldWRvcGFyZW50OwotICBTdHJpbmcgcHJlZml4LHVyaSxub2RlbmFtZTsKLSAgaW50IGhhbmRsZTsKLSAgRE9NMkRUTWRlZmF1bHROYW1lc3BhY2VEZWNsYXJhdGlvbk5vZGUoRWxlbWVudCBwc2V1ZG9wYXJlbnQsU3RyaW5nIHByZWZpeCxTdHJpbmcgdXJpLGludCBoYW5kbGUpCi0gIHsKLSAgICB0aGlzLnBzZXVkb3BhcmVudD1wc2V1ZG9wYXJlbnQ7Ci0gICAgdGhpcy5wcmVmaXg9cHJlZml4OwotICAgIHRoaXMudXJpPXVyaTsKLSAgICB0aGlzLmhhbmRsZT1oYW5kbGU7Ci0gICAgdGhpcy5ub2RlbmFtZT0ieG1sbnM6IitwcmVmaXg7Ci0gIH0KLSAgcHVibGljIFN0cmluZyBnZXROb2RlTmFtZSgpIHtyZXR1cm4gbm9kZW5hbWU7fQotICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKSB7cmV0dXJuIG5vZGVuYW1lO30KLSAgcHVibGljIFN0cmluZyBnZXROYW1lc3BhY2VVUkkoKSB7cmV0dXJuICJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3htbG5zLyI7fQotICBwdWJsaWMgU3RyaW5nIGdldFByZWZpeCgpIHtyZXR1cm4gcHJlZml4O30KLSAgcHVibGljIFN0cmluZyBnZXRMb2NhbE5hbWUoKSB7cmV0dXJuIHByZWZpeDt9Ci0gIHB1YmxpYyBTdHJpbmcgZ2V0Tm9kZVZhbHVlKCkge3JldHVybiB1cmk7fQotICBwdWJsaWMgU3RyaW5nIGdldFZhbHVlKCkge3JldHVybiB1cmk7fQotICBwdWJsaWMgRWxlbWVudCBnZXRPd25lckVsZW1lbnQoKSB7cmV0dXJuIHBzZXVkb3BhcmVudDt9Ci0KLSAgcHVibGljIGJvb2xlYW4gaXNTdXBwb3J0ZWQoU3RyaW5nIGZlYXR1cmUsIFN0cmluZyB2ZXJzaW9uKSB7cmV0dXJuIGZhbHNlO30KLSAgcHVibGljIGJvb2xlYW4gaGFzQ2hpbGROb2RlcygpIHtyZXR1cm4gZmFsc2U7fQotICBwdWJsaWMgYm9vbGVhbiBoYXNBdHRyaWJ1dGVzKCkge3JldHVybiBmYWxzZTt9Ci0gIHB1YmxpYyBOb2RlIGdldFBhcmVudE5vZGUoKSB7cmV0dXJuIG51bGw7fQotICBwdWJsaWMgTm9kZSBnZXRGaXJzdENoaWxkKCkge3JldHVybiBudWxsO30KLSAgcHVibGljIE5vZGUgZ2V0TGFzdENoaWxkKCkge3JldHVybiBudWxsO30KLSAgcHVibGljIE5vZGUgZ2V0UHJldmlvdXNTaWJsaW5nKCkge3JldHVybiBudWxsO30KLSAgcHVibGljIE5vZGUgZ2V0TmV4dFNpYmxpbmcoKSB7cmV0dXJuIG51bGw7fQotICBwdWJsaWMgYm9vbGVhbiBnZXRTcGVjaWZpZWQoKSB7cmV0dXJuIGZhbHNlO30KLSAgcHVibGljIHZvaWQgbm9ybWFsaXplKCkge3JldHVybjt9Ci0gIHB1YmxpYyBOb2RlTGlzdCBnZXRDaGlsZE5vZGVzKCkge3JldHVybiBudWxsO30KLSAgcHVibGljIE5hbWVkTm9kZU1hcCBnZXRBdHRyaWJ1dGVzKCkge3JldHVybiBudWxsO30KLSAgcHVibGljIHNob3J0IGdldE5vZGVUeXBlKCkge3JldHVybiBOb2RlLkFUVFJJQlVURV9OT0RFO30KLSAgcHVibGljIHZvaWQgc2V0Tm9kZVZhbHVlKFN0cmluZyB2YWx1ZSkge3Rocm93IG5ldyBEVE1FeGNlcHRpb24oTk9UX1NVUFBPUlRFRF9FUlIpO30KLSAgcHVibGljIHZvaWQgc2V0VmFsdWUoU3RyaW5nIHZhbHVlKSB7dGhyb3cgbmV3IERUTUV4Y2VwdGlvbihOT1RfU1VQUE9SVEVEX0VSUik7fQotICBwdWJsaWMgdm9pZCBzZXRQcmVmaXgoU3RyaW5nIHZhbHVlKSB7dGhyb3cgbmV3IERUTUV4Y2VwdGlvbihOT1RfU1VQUE9SVEVEX0VSUik7fQotICBwdWJsaWMgTm9kZSBpbnNlcnRCZWZvcmUoTm9kZSBhLCBOb2RlIGIpIHt0aHJvdyBuZXcgRFRNRXhjZXB0aW9uKE5PVF9TVVBQT1JURURfRVJSKTt9Ci0gIHB1YmxpYyBOb2RlIHJlcGxhY2VDaGlsZChOb2RlIGEsIE5vZGUgYikge3Rocm93IG5ldyBEVE1FeGNlcHRpb24oTk9UX1NVUFBPUlRFRF9FUlIpO30KLSAgcHVibGljIE5vZGUgYXBwZW5kQ2hpbGQoTm9kZSBhKSB7dGhyb3cgbmV3IERUTUV4Y2VwdGlvbihOT1RfU1VQUE9SVEVEX0VSUik7fQotICBwdWJsaWMgTm9kZSByZW1vdmVDaGlsZChOb2RlIGEpIHt0aHJvdyBuZXcgRFRNRXhjZXB0aW9uKE5PVF9TVVBQT1JURURfRVJSKTt9Ci0gIHB1YmxpYyBEb2N1bWVudCBnZXRPd25lckRvY3VtZW50KCkge3JldHVybiBwc2V1ZG9wYXJlbnQuZ2V0T3duZXJEb2N1bWVudCgpO30KLSAgcHVibGljIE5vZGUgY2xvbmVOb2RlKGJvb2xlYW4gZGVlcCkge3Rocm93IG5ldyBEVE1FeGNlcHRpb24oTk9UX1NVUFBPUlRFRF9FUlIpO30KLQotICAgIC8qKiBOb24tRE9NIG1ldGhvZCwgcGFydCBvZiB0aGUgdGVtcG9yYXJ5IGtsdWdlCi0gICAgICogJVJFVklFVyUgVGhpcyB3b3VsZCBiZSBhIHBydW5pbmcgcHJvYmxlbSwgYnV0IHNpbmNlIGl0IHdpbGwgYWx3YXlzIGJlCi0gICAgICogYWRkZWQgdG8gdGhlIHJvb3QgZWxlbWVudCBhbmQgd2UgcHJ1bmUgb24gZWxlbWVudHMsIHdlIHNob3VsZG4ndCBoYXZlCi0gICAgICogdG8gd29ycnkuCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRIYW5kbGVPZk5vZGUoKQotICAgIHsKLSAgICAgICAgcmV0dXJuIGhhbmRsZTsKLSAgICB9Ci0KLSAgICAvL1JBTUVTSDogUEVORElORz0+IEFkZCBwcm9wZXIgaW1wbGVtZW50YXRpb24gZm9yIHRoZSBiZWxvdyBET00gTDMgYWRkaXRpb25zCi0KLSAgICAvKioKLSAgICAgKiBAc2VlIG9yZy53M2MuZG9tLlR5cGVJbmZvI2dldFR5cGVOYW1lKCkKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFR5cGVOYW1lKCkge3JldHVybiBudWxsOyB9Ci0KLSAgICAvKioKLSAgICAgKiBAc2VlIG9yZy53M2MuZG9tLlR5cGVJbmZvI2dldFR5cGVOYW1lc3BhY2UoKQotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VHlwZU5hbWVzcGFjZSgpIHsgcmV0dXJuIG51bGw7fQotCi0gICAgLyoqCi0gICAgICogQHNlZSBvci5ndzNjLmRvbS5UeXBlSW5mbyNpc0Rlcml2ZWRGcm9tKFN0cmluZyxTdHJpbmcsaW50KQotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzRGVyaXZlZEZyb20oIFN0cmluZyBucywgU3RyaW5nIGxvY2FsTmFtZSwgaW50IGRlcml2YXRpb25NZXRob2QgKSB7Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgVHlwZUluZm8gZ2V0U2NoZW1hVHlwZUluZm8oKSB7IHJldHVybiB0aGlzOyB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0lkKCApIHsgcmV0dXJuIGZhbHNlOyB9Ci0KLSAgICAvKioKLSAgICAgKiBBc3NvY2lhdGUgYW4gb2JqZWN0IHRvIGEga2V5IG9uIHRoaXMgbm9kZS4gVGhlIG9iamVjdCBjYW4gbGF0ZXIgYmUKLSAgICAgKiByZXRyaWV2ZWQgZnJvbSB0aGlzIG5vZGUgYnkgY2FsbGluZyA8Y29kZT5nZXRVc2VyRGF0YTwvY29kZT4gd2l0aCB0aGUKLSAgICAgKiBzYW1lIGtleS4KLSAgICAgKiBAcGFyYW0ga2V5IFRoZSBrZXkgdG8gYXNzb2NpYXRlIHRoZSBvYmplY3QgdG8uCi0gICAgICogQHBhcmFtIGRhdGEgVGhlIG9iamVjdCB0byBhc3NvY2lhdGUgdG8gdGhlIGdpdmVuIGtleSwgb3IKLSAgICAgKiAgIDxjb2RlPm51bGw8L2NvZGU+IHRvIHJlbW92ZSBhbnkgZXhpc3RpbmcgYXNzb2NpYXRpb24gdG8gdGhhdCBrZXkuCi0gICAgICogQHBhcmFtIGhhbmRsZXIgVGhlIGhhbmRsZXIgdG8gYXNzb2NpYXRlIHRvIHRoYXQga2V5LCBvcgotICAgICAqICAgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICogQHJldHVybiBSZXR1cm5zIHRoZSA8Y29kZT5ET01PYmplY3Q8L2NvZGU+IHByZXZpb3VzbHkgYXNzb2NpYXRlZCB0bwotICAgICAqICAgdGhlIGdpdmVuIGtleSBvbiB0aGlzIG5vZGUsIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoZXJlIHdhcyBub25lLgotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgICAqLwotICAgIHB1YmxpYyBPYmplY3Qgc2V0VXNlckRhdGEoU3RyaW5nIGtleSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9iamVjdCBkYXRhLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVXNlckRhdGFIYW5kbGVyIGhhbmRsZXIpIHsKLSAgICAgICAgcmV0dXJuIGdldE93bmVyRG9jdW1lbnQoKS5zZXRVc2VyRGF0YSgga2V5LCBkYXRhLCBoYW5kbGVyKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXRyaWV2ZXMgdGhlIG9iamVjdCBhc3NvY2lhdGVkIHRvIGEga2V5IG9uIGEgdGhpcyBub2RlLiBUaGUgb2JqZWN0Ci0gICAgICogbXVzdCBmaXJzdCBoYXZlIGJlZW4gc2V0IHRvIHRoaXMgbm9kZSBieSBjYWxsaW5nCi0gICAgICogPGNvZGU+c2V0VXNlckRhdGE8L2NvZGU+IHdpdGggdGhlIHNhbWUga2V5LgotICAgICAqIEBwYXJhbSBrZXkgVGhlIGtleSB0aGUgb2JqZWN0IGlzIGFzc29jaWF0ZWQgdG8uCi0gICAgICogQHJldHVybiBSZXR1cm5zIHRoZSA8Y29kZT5ET01PYmplY3Q8L2NvZGU+IGFzc29jaWF0ZWQgdG8gdGhlIGdpdmVuIGtleQotICAgICAqICAgb24gdGhpcyBub2RlLCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGVyZSB3YXMgbm9uZS4KLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0IGdldFVzZXJEYXRhKFN0cmluZyBrZXkpIHsKLSAgICAgICAgcmV0dXJuIGdldE93bmVyRG9jdW1lbnQoKS5nZXRVc2VyRGF0YSgga2V5KTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiAgVGhpcyBtZXRob2QgcmV0dXJucyBhIHNwZWNpYWxpemVkIG9iamVjdCB3aGljaCBpbXBsZW1lbnRzIHRoZQotICAgICAqIHNwZWNpYWxpemVkIEFQSXMgb2YgdGhlIHNwZWNpZmllZCBmZWF0dXJlIGFuZCB2ZXJzaW9uLiBUaGUKLSAgICAgKiBzcGVjaWFsaXplZCBvYmplY3QgbWF5IGFsc28gYmUgb2J0YWluZWQgYnkgdXNpbmcgYmluZGluZy1zcGVjaWZpYwotICAgICAqIGNhc3RpbmcgbWV0aG9kcyBidXQgaXMgbm90IG5lY2Vzc2FyaWx5IGV4cGVjdGVkIHRvLCBhcyBkaXNjdXNzZWQgaW4gTWl4ZWQgRE9NIGltcGxlbWVudGF0aW9ucy4KLSAgICAgKiBAcGFyYW0gZmVhdHVyZSBUaGUgbmFtZSBvZiB0aGUgZmVhdHVyZSByZXF1ZXN0ZWQgKGNhc2UtaW5zZW5zaXRpdmUpLgotICAgICAqIEBwYXJhbSB2ZXJzaW9uICBUaGlzIGlzIHRoZSB2ZXJzaW9uIG51bWJlciBvZiB0aGUgZmVhdHVyZSB0byB0ZXN0LiBJZgotICAgICAqICAgdGhlIHZlcnNpb24gaXMgPGNvZGU+bnVsbDwvY29kZT4gb3IgdGhlIGVtcHR5IHN0cmluZywgc3VwcG9ydGluZwotICAgICAqICAgYW55IHZlcnNpb24gb2YgdGhlIGZlYXR1cmUgd2lsbCBjYXVzZSB0aGUgbWV0aG9kIHRvIHJldHVybiBhbgotICAgICAqICAgb2JqZWN0IHRoYXQgc3VwcG9ydHMgYXQgbGVhc3Qgb25lIHZlcnNpb24gb2YgdGhlIGZlYXR1cmUuCi0gICAgICogQHJldHVybiAgUmV0dXJucyBhbiBvYmplY3Qgd2hpY2ggaW1wbGVtZW50cyB0aGUgc3BlY2lhbGl6ZWQgQVBJcyBvZgotICAgICAqICAgdGhlIHNwZWNpZmllZCBmZWF0dXJlIGFuZCB2ZXJzaW9uLCBpZiBhbnksIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmCi0gICAgICogICB0aGVyZSBpcyBubyBvYmplY3Qgd2hpY2ggaW1wbGVtZW50cyBpbnRlcmZhY2VzIGFzc29jaWF0ZWQgd2l0aCB0aGF0Ci0gICAgICogICBmZWF0dXJlLiBJZiB0aGUgPGNvZGU+RE9NT2JqZWN0PC9jb2RlPiByZXR1cm5lZCBieSB0aGlzIG1ldGhvZAotICAgICAqICAgaW1wbGVtZW50cyB0aGUgPGNvZGU+Tm9kZTwvY29kZT4gaW50ZXJmYWNlLCBpdCBtdXN0IGRlbGVnYXRlIHRvIHRoZQotICAgICAqICAgcHJpbWFyeSBjb3JlIDxjb2RlPk5vZGU8L2NvZGU+IGFuZCBub3QgcmV0dXJuIHJlc3VsdHMgaW5jb25zaXN0ZW50Ci0gICAgICogICB3aXRoIHRoZSBwcmltYXJ5IGNvcmUgPGNvZGU+Tm9kZTwvY29kZT4gc3VjaCBhcyBhdHRyaWJ1dGVzLAotICAgICAqICAgY2hpbGROb2RlcywgZXRjLgotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgICAqLwotICAgIHB1YmxpYyBPYmplY3QgZ2V0RmVhdHVyZShTdHJpbmcgZmVhdHVyZSwgU3RyaW5nIHZlcnNpb24pIHsKLSAgICAgICAgLy8gd2UgZG9uJ3QgaGF2ZSBhbnkgYWx0ZXJuYXRlIG5vZGUsIGVpdGhlciB0aGlzIG5vZGUgZG9lcyB0aGUgam9iCi0gICAgICAgIC8vIG9yIHdlIGRvbid0IGhhdmUgYW55dGhpbmcgdGhhdCBkb2VzCi0gICAgICAgIHJldHVybiBpc1N1cHBvcnRlZChmZWF0dXJlLCB2ZXJzaW9uKSA/IHRoaXMgOiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRlc3RzIHdoZXRoZXIgdHdvIG5vZGVzIGFyZSBlcXVhbC4KLSAgICAgKiA8YnI+VGhpcyBtZXRob2QgdGVzdHMgZm9yIGVxdWFsaXR5IG9mIG5vZGVzLCBub3Qgc2FtZW5lc3MgKGkuZS4sCi0gICAgICogd2hldGhlciB0aGUgdHdvIG5vZGVzIGFyZSByZWZlcmVuY2VzIHRvIHRoZSBzYW1lIG9iamVjdCkgd2hpY2ggY2FuIGJlCi0gICAgICogdGVzdGVkIHdpdGggPGNvZGU+Tm9kZS5pc1NhbWVOb2RlPC9jb2RlPi4gQWxsIG5vZGVzIHRoYXQgYXJlIHRoZSBzYW1lCi0gICAgICogd2lsbCBhbHNvIGJlIGVxdWFsLCB0aG91Z2ggdGhlIHJldmVyc2UgbWF5IG5vdCBiZSB0cnVlLgotICAgICAqIDxicj5Ud28gbm9kZXMgYXJlIGVxdWFsIGlmIGFuZCBvbmx5IGlmIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKLSAgICAgKiBzYXRpc2ZpZWQ6IFRoZSB0d28gbm9kZXMgYXJlIG9mIHRoZSBzYW1lIHR5cGUuVGhlIGZvbGxvd2luZyBzdHJpbmcKLSAgICAgKiBhdHRyaWJ1dGVzIGFyZSBlcXVhbDogPGNvZGU+bm9kZU5hbWU8L2NvZGU+LCA8Y29kZT5sb2NhbE5hbWU8L2NvZGU+LAotICAgICAqIDxjb2RlPm5hbWVzcGFjZVVSSTwvY29kZT4sIDxjb2RlPnByZWZpeDwvY29kZT4sIDxjb2RlPm5vZGVWYWx1ZTwvY29kZT4KLSAgICAgKiAsIDxjb2RlPmJhc2VVUkk8L2NvZGU+LiBUaGlzIGlzOiB0aGV5IGFyZSBib3RoIDxjb2RlPm51bGw8L2NvZGU+LCBvcgotICAgICAqIHRoZXkgaGF2ZSB0aGUgc2FtZSBsZW5ndGggYW5kIGFyZSBjaGFyYWN0ZXIgZm9yIGNoYXJhY3RlciBpZGVudGljYWwuCi0gICAgICogVGhlIDxjb2RlPmF0dHJpYnV0ZXM8L2NvZGU+IDxjb2RlPk5hbWVkTm9kZU1hcHM8L2NvZGU+IGFyZSBlcXVhbC4KLSAgICAgKiBUaGlzIGlzOiB0aGV5IGFyZSBib3RoIDxjb2RlPm51bGw8L2NvZGU+LCBvciB0aGV5IGhhdmUgdGhlIHNhbWUKLSAgICAgKiBsZW5ndGggYW5kIGZvciBlYWNoIG5vZGUgdGhhdCBleGlzdHMgaW4gb25lIG1hcCB0aGVyZSBpcyBhIG5vZGUgdGhhdAotICAgICAqIGV4aXN0cyBpbiB0aGUgb3RoZXIgbWFwIGFuZCBpcyBlcXVhbCwgYWx0aG91Z2ggbm90IG5lY2Vzc2FyaWx5IGF0IHRoZQotICAgICAqIHNhbWUgaW5kZXguVGhlIDxjb2RlPmNoaWxkTm9kZXM8L2NvZGU+IDxjb2RlPk5vZGVMaXN0czwvY29kZT4gYXJlCi0gICAgICogZXF1YWwuIFRoaXMgaXM6IHRoZXkgYXJlIGJvdGggPGNvZGU+bnVsbDwvY29kZT4sIG9yIHRoZXkgaGF2ZSB0aGUKLSAgICAgKiBzYW1lIGxlbmd0aCBhbmQgY29udGFpbiBlcXVhbCBub2RlcyBhdCB0aGUgc2FtZSBpbmRleC4gVGhpcyBpcyB0cnVlCi0gICAgICogZm9yIDxjb2RlPkF0dHI8L2NvZGU+IG5vZGVzIGFzIGZvciBhbnkgb3RoZXIgdHlwZSBvZiBub2RlLiBOb3RlIHRoYXQKLSAgICAgKiBub3JtYWxpemF0aW9uIGNhbiBhZmZlY3QgZXF1YWxpdHk7IHRvIGF2b2lkIHRoaXMsIG5vZGVzIHNob3VsZCBiZQotICAgICAqIG5vcm1hbGl6ZWQgYmVmb3JlIGJlaW5nIGNvbXBhcmVkLgotICAgICAqIDxicj5Gb3IgdHdvIDxjb2RlPkRvY3VtZW50VHlwZTwvY29kZT4gbm9kZXMgdG8gYmUgZXF1YWwsIHRoZSBmb2xsb3dpbmcKLSAgICAgKiBjb25kaXRpb25zIG11c3QgYWxzbyBiZSBzYXRpc2ZpZWQ6IFRoZSBmb2xsb3dpbmcgc3RyaW5nIGF0dHJpYnV0ZXMKLSAgICAgKiBhcmUgZXF1YWw6IDxjb2RlPnB1YmxpY0lkPC9jb2RlPiwgPGNvZGU+c3lzdGVtSWQ8L2NvZGU+LAotICAgICAqIDxjb2RlPmludGVybmFsU3Vic2V0PC9jb2RlPi5UaGUgPGNvZGU+ZW50aXRpZXM8L2NvZGU+Ci0gICAgICogPGNvZGU+TmFtZWROb2RlTWFwczwvY29kZT4gYXJlIGVxdWFsLlRoZSA8Y29kZT5ub3RhdGlvbnM8L2NvZGU+Ci0gICAgICogPGNvZGU+TmFtZWROb2RlTWFwczwvY29kZT4gYXJlIGVxdWFsLgotICAgICAqIDxicj5PbiB0aGUgb3RoZXIgaGFuZCwgdGhlIGZvbGxvd2luZyBkbyBub3QgYWZmZWN0IGVxdWFsaXR5OiB0aGUKLSAgICAgKiA8Y29kZT5vd25lckRvY3VtZW50PC9jb2RlPiBhdHRyaWJ1dGUsIHRoZSA8Y29kZT5zcGVjaWZpZWQ8L2NvZGU+Ci0gICAgICogYXR0cmlidXRlIGZvciA8Y29kZT5BdHRyPC9jb2RlPiBub2RlcywgdGhlCi0gICAgICogPGNvZGU+aXNXaGl0ZXNwYWNlSW5FbGVtZW50Q29udGVudDwvY29kZT4gYXR0cmlidXRlIGZvcgotICAgICAqIDxjb2RlPlRleHQ8L2NvZGU+IG5vZGVzLCBhcyB3ZWxsIGFzIGFueSB1c2VyIGRhdGEgb3IgZXZlbnQgbGlzdGVuZXJzCi0gICAgICogcmVnaXN0ZXJlZCBvbiB0aGUgbm9kZXMuCi0gICAgICogQHBhcmFtIGFyZyBUaGUgbm9kZSB0byBjb21wYXJlIGVxdWFsaXR5IHdpdGguCi0gICAgICogQHBhcmFtIGRlZXAgSWYgPGNvZGU+dHJ1ZTwvY29kZT4sIHJlY3Vyc2l2ZWx5IGNvbXBhcmUgdGhlIHN1YnRyZWVzOyBpZgotICAgICAqICAgPGNvZGU+ZmFsc2U8L2NvZGU+LCBjb21wYXJlIG9ubHkgdGhlIG5vZGVzIHRoZW1zZWx2ZXMgKGFuZCBpdHMKLSAgICAgKiAgIGF0dHJpYnV0ZXMsIGlmIGl0IGlzIGFuIDxjb2RlPkVsZW1lbnQ8L2NvZGU+KS4KLSAgICAgKiBAcmV0dXJuIElmIHRoZSBub2RlcywgYW5kIHBvc3NpYmx5IHN1YnRyZWVzIGFyZSBlcXVhbCwKLSAgICAgKiAgIDxjb2RlPnRydWU8L2NvZGU+IG90aGVyd2lzZSA8Y29kZT5mYWxzZTwvY29kZT4uCi0gICAgICogQHNpbmNlIERPTSBMZXZlbCAzCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNFcXVhbE5vZGUoTm9kZSBhcmcpIHsKLSAgICAgICAgaWYgKGFyZyA9PSB0aGlzKSB7Ci0gICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgfQotICAgICAgICBpZiAoYXJnLmdldE5vZGVUeXBlKCkgIT0gZ2V0Tm9kZVR5cGUoKSkgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0gICAgICAgIC8vIGluIHRoZW9yeSBub2RlTmFtZSBjYW4ndCBiZSBudWxsIGJ1dCBiZXR0ZXIgYmUgY2FyZWZ1bAotICAgICAgICAvLyB3aG8ga25vd3Mgd2hhdCBvdGhlciBpbXBsZW1lbnRhdGlvbnMgbWF5IGJlIGRvaW5nPy4uLgotICAgICAgICBpZiAoZ2V0Tm9kZU5hbWUoKSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAoYXJnLmdldE5vZGVOYW1lKCkgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICghZ2V0Tm9kZU5hbWUoKS5lcXVhbHMoYXJnLmdldE5vZGVOYW1lKCkpKSB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoZ2V0TG9jYWxOYW1lKCkgPT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKGFyZy5nZXRMb2NhbE5hbWUoKSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKCFnZXRMb2NhbE5hbWUoKS5lcXVhbHMoYXJnLmdldExvY2FsTmFtZSgpKSkgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKGdldE5hbWVzcGFjZVVSSSgpID09IG51bGwpIHsKLSAgICAgICAgICAgIGlmIChhcmcuZ2V0TmFtZXNwYWNlVVJJKCkgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICghZ2V0TmFtZXNwYWNlVVJJKCkuZXF1YWxzKGFyZy5nZXROYW1lc3BhY2VVUkkoKSkpIHsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChnZXRQcmVmaXgoKSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAoYXJnLmdldFByZWZpeCgpICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoIWdldFByZWZpeCgpLmVxdWFscyhhcmcuZ2V0UHJlZml4KCkpKSB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoZ2V0Tm9kZVZhbHVlKCkgPT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKGFyZy5nZXROb2RlVmFsdWUoKSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKCFnZXROb2RlVmFsdWUoKS5lcXVhbHMoYXJnLmdldE5vZGVWYWx1ZSgpKSkgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0gICAgLyoKLSAgICAgICAgaWYgKGdldEJhc2VVUkkoKSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAoKChOb2RlSW1wbCkgYXJnKS5nZXRCYXNlVVJJKCkgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICghZ2V0QmFzZVVSSSgpLmVxdWFscygoKE5vZGVJbXBsKSBhcmcpLmdldEJhc2VVUkkoKSkpIHsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotKi8KLQotICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIERPTSBMZXZlbCAzIC0gRXhwZXJpbWVudGFsOgotICAgICAqIExvb2sgdXAgdGhlIG5hbWVzcGFjZSBVUkkgYXNzb2NpYXRlZCB0byB0aGUgZ2l2ZW4gcHJlZml4LCBzdGFydGluZyBmcm9tIHRoaXMgbm9kZS4KLSAgICAgKiBVc2UgbG9va3VwTmFtZXNwYWNlVVJJKG51bGwpIHRvIGxvb2t1cCB0aGUgZGVmYXVsdCBuYW1lc3BhY2UKLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkKLSAgICAgKiBAcmV0dXJuIHRoIFVSSSBmb3IgdGhlIG5hbWVzcGFjZQotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgbG9va3VwTmFtZXNwYWNlVVJJKFN0cmluZyBzcGVjaWZpZWRQcmVmaXgpIHsKLSAgICAgICAgc2hvcnQgdHlwZSA9IHRoaXMuZ2V0Tm9kZVR5cGUoKTsKLSAgICAgICAgc3dpdGNoICh0eXBlKSB7Ci0gICAgICAgIGNhc2UgTm9kZS5FTEVNRU5UX05PREUgOiB7Ci0KLSAgICAgICAgICAgICAgICBTdHJpbmcgbmFtZXNwYWNlID0gdGhpcy5nZXROYW1lc3BhY2VVUkkoKTsKLSAgICAgICAgICAgICAgICBTdHJpbmcgcHJlZml4ID0gdGhpcy5nZXRQcmVmaXgoKTsKLSAgICAgICAgICAgICAgICBpZiAobmFtZXNwYWNlICE9bnVsbCkgewotICAgICAgICAgICAgICAgICAgICAvLyBSRVZJU0lUOiBpcyBpdCBwb3NzaWJsZSB0aGF0IHByZWZpeCBpcyBlbXB0eSBzdHJpbmc/Ci0gICAgICAgICAgICAgICAgICAgIGlmIChzcGVjaWZpZWRQcmVmaXg9PSBudWxsICYmIHByZWZpeD09c3BlY2lmaWVkUHJlZml4KSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBsb29raW5nIGZvciBkZWZhdWx0IG5hbWVzcGFjZQotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5hbWVzcGFjZTsKLSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChwcmVmaXggIT0gbnVsbCAmJiBwcmVmaXguZXF1YWxzKHNwZWNpZmllZFByZWZpeCkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIG5vbiBkZWZhdWx0IG5hbWVzcGFjZQotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5hbWVzcGFjZTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpZiAodGhpcy5oYXNBdHRyaWJ1dGVzKCkpIHsKLSAgICAgICAgICAgICAgICAgICAgTmFtZWROb2RlTWFwIG1hcCA9IHRoaXMuZ2V0QXR0cmlidXRlcygpOwotICAgICAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gbWFwLmdldExlbmd0aCgpOwotICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpPTA7aTxsZW5ndGg7aSsrKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBOb2RlIGF0dHIgPSBtYXAuaXRlbShpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBhdHRyUHJlZml4ID0gYXR0ci5nZXRQcmVmaXgoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyB2YWx1ZSA9IGF0dHIuZ2V0Tm9kZVZhbHVlKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBuYW1lc3BhY2UgPSBhdHRyLmdldE5hbWVzcGFjZVVSSSgpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5hbWVzcGFjZSAhPW51bGwgJiYgbmFtZXNwYWNlLmVxdWFscygiaHR0cDovL3d3dy53My5vcmcvMjAwMC94bWxucy8iKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGF0IHRoaXMgcG9pbnQgd2UgYXJlIGRlYWxpbmcgd2l0aCBET00gTGV2ZWwgMiBub2RlcyBvbmx5Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNwZWNpZmllZFByZWZpeCA9PSBudWxsICYmCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHIuZ2V0Tm9kZU5hbWUoKS5lcXVhbHMoInhtbG5zIikpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZGVmYXVsdCBuYW1lc3BhY2UKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYXR0clByZWZpeCAhPW51bGwgJiYKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJQcmVmaXguZXF1YWxzKCJ4bWxucyIpICYmCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyLmdldExvY2FsTmFtZSgpLmVxdWFscyhzcGVjaWZpZWRQcmVmaXgpKSB7Ci0gICAgICAgICAgICAgICAgIC8vIG5vbiBkZWZhdWx0IG5hbWVzcGFjZQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIC8qCi0gICAgICAgICAgICAgICAgTm9kZUltcGwgYW5jZXN0b3IgPSAoTm9kZUltcGwpZ2V0RWxlbWVudEFuY2VzdG9yKHRoaXMpOwotICAgICAgICAgICAgICAgIGlmIChhbmNlc3RvciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBhbmNlc3Rvci5sb29rdXBOYW1lc3BhY2VVUkkoc3BlY2lmaWVkUHJlZml4KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgKi8KLQotICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwotCi0KLSAgICAgICAgICAgIH0KLS8qCi0gICAgICAgIGNhc2UgTm9kZS5ET0NVTUVOVF9OT0RFIDogewotICAgICAgICAgICAgICAgIHJldHVybigoTm9kZUltcGwpKChEb2N1bWVudCl0aGlzKS5nZXREb2N1bWVudEVsZW1lbnQoKSkubG9va3VwTmFtZXNwYWNlVVJJKHNwZWNpZmllZFByZWZpeCkgOwotICAgICAgICAgICAgfQotKi8KLSAgICAgICAgY2FzZSBOb2RlLkVOVElUWV9OT0RFIDoKLSAgICAgICAgY2FzZSBOb2RlLk5PVEFUSU9OX05PREU6Ci0gICAgICAgIGNhc2UgTm9kZS5ET0NVTUVOVF9GUkFHTUVOVF9OT0RFOgotICAgICAgICBjYXNlIE5vZGUuRE9DVU1FTlRfVFlQRV9OT0RFOgotICAgICAgICAgICAgLy8gdHlwZSBpcyB1bmtub3duCi0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgY2FzZSBOb2RlLkFUVFJJQlVURV9OT0RFOnsKLSAgICAgICAgICAgICAgICBpZiAodGhpcy5nZXRPd25lckVsZW1lbnQoKS5nZXROb2RlVHlwZSgpID09IE5vZGUuRUxFTUVOVF9OT0RFKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBnZXRPd25lckVsZW1lbnQoKS5sb29rdXBOYW1lc3BhY2VVUkkoc3BlY2lmaWVkUHJlZml4KTsKLQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgZGVmYXVsdDp7Ci0gICAgICAgICAgIC8qCi0gICAgICAgICAgICAgICAgTm9kZUltcGwgYW5jZXN0b3IgPSAoTm9kZUltcGwpZ2V0RWxlbWVudEFuY2VzdG9yKHRoaXMpOwotICAgICAgICAgICAgICAgIGlmIChhbmNlc3RvciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBhbmNlc3Rvci5sb29rdXBOYW1lc3BhY2VVUkkoc3BlY2lmaWVkUHJlZml4KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgKi8KLSAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgICAgIH0KLQotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogIERPTSBMZXZlbCAzOiBFeHBlcmltZW50YWwKLSAgICAgKiAgVGhpcyBtZXRob2QgY2hlY2tzIGlmIHRoZSBzcGVjaWZpZWQgPGNvZGU+bmFtZXNwYWNlVVJJPC9jb2RlPiBpcyB0aGUKLSAgICAgKiAgZGVmYXVsdCBuYW1lc3BhY2Ugb3Igbm90LgotICAgICAqICBAcGFyYW0gbmFtZXNwYWNlVVJJIFRoZSBuYW1lc3BhY2UgVVJJIHRvIGxvb2sgZm9yLgotICAgICAqICBAcmV0dXJuICA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgc3BlY2lmaWVkIDxjb2RlPm5hbWVzcGFjZVVSSTwvY29kZT4KLSAgICAgKiAgIGlzIHRoZSBkZWZhdWx0IG5hbWVzcGFjZSwgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4KLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0RlZmF1bHROYW1lc3BhY2UoU3RyaW5nIG5hbWVzcGFjZVVSSSl7Ci0gICAgICAgLyoKLSAgICAgICAgLy8gUkVWSVNJVDogcmVtb3ZlIGNhc3RzIHdoZW4gRE9NIEwzIGJlY29tZXMgUkVDLgotICAgICAgICBzaG9ydCB0eXBlID0gdGhpcy5nZXROb2RlVHlwZSgpOwotICAgICAgICBzd2l0Y2ggKHR5cGUpIHsKLSAgICAgICAgY2FzZSBOb2RlLkVMRU1FTlRfTk9ERTogewotICAgICAgICAgICAgU3RyaW5nIG5hbWVzcGFjZSA9IHRoaXMuZ2V0TmFtZXNwYWNlVVJJKCk7Ci0gICAgICAgICAgICBTdHJpbmcgcHJlZml4ID0gdGhpcy5nZXRQcmVmaXgoKTsKLQotICAgICAgICAgICAgLy8gUkVWSVNJVDogaXMgaXQgcG9zc2libGUgdGhhdCBwcmVmaXggaXMgZW1wdHkgc3RyaW5nPwotICAgICAgICAgICAgaWYgKHByZWZpeCA9PSBudWxsIHx8IHByZWZpeC5sZW5ndGgoKSA9PSAwKSB7Ci0gICAgICAgICAgICAgICAgaWYgKG5hbWVzcGFjZVVSSSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiAobmFtZXNwYWNlID09IG5hbWVzcGFjZVVSSSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHJldHVybiBuYW1lc3BhY2VVUkkuZXF1YWxzKG5hbWVzcGFjZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAodGhpcy5oYXNBdHRyaWJ1dGVzKCkpIHsKLSAgICAgICAgICAgICAgICBFbGVtZW50SW1wbCBlbGVtID0gKEVsZW1lbnRJbXBsKXRoaXM7Ci0gICAgICAgICAgICAgICAgTm9kZUltcGwgYXR0ciA9IChOb2RlSW1wbCllbGVtLmdldEF0dHJpYnV0ZU5vZGVOUygiaHR0cDovL3d3dy53My5vcmcvMjAwMC94bWxucy8iLCAieG1sbnMiKTsKLSAgICAgICAgICAgICAgICBpZiAoYXR0ciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIFN0cmluZyB2YWx1ZSA9IGF0dHIuZ2V0Tm9kZVZhbHVlKCk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChuYW1lc3BhY2VVUkkgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChuYW1lc3BhY2UgPT0gdmFsdWUpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBuYW1lc3BhY2VVUkkuZXF1YWxzKHZhbHVlKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIE5vZGVJbXBsIGFuY2VzdG9yID0gKE5vZGVJbXBsKWdldEVsZW1lbnRBbmNlc3Rvcih0aGlzKTsKLSAgICAgICAgICAgIGlmIChhbmNlc3RvciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGFuY2VzdG9yLmlzRGVmYXVsdE5hbWVzcGFjZShuYW1lc3BhY2VVUkkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0gICAgICAgIGNhc2UgTm9kZS5ET0NVTUVOVF9OT0RFOnsKLSAgICAgICAgICAgICAgICByZXR1cm4oKE5vZGVJbXBsKSgoRG9jdW1lbnQpdGhpcykuZ2V0RG9jdW1lbnRFbGVtZW50KCkpLmlzRGVmYXVsdE5hbWVzcGFjZShuYW1lc3BhY2VVUkkpOwotICAgICAgICAgICAgfQotCi0gICAgICAgIGNhc2UgTm9kZS5FTlRJVFlfTk9ERSA6Ci0gICAgICAgICAgY2FzZSBOb2RlLk5PVEFUSU9OX05PREU6Ci0gICAgICAgIGNhc2UgTm9kZS5ET0NVTUVOVF9GUkFHTUVOVF9OT0RFOgotICAgICAgICBjYXNlIE5vZGUuRE9DVU1FTlRfVFlQRV9OT0RFOgotICAgICAgICAgICAgLy8gdHlwZSBpcyB1bmtub3duCi0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIGNhc2UgTm9kZS5BVFRSSUJVVEVfTk9ERTp7Ci0gICAgICAgICAgICAgICAgaWYgKHRoaXMub3duZXJOb2RlLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5FTEVNRU5UX05PREUpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG93bmVyTm9kZS5pc0RlZmF1bHROYW1lc3BhY2UobmFtZXNwYWNlVVJJKTsKLQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIGRlZmF1bHQ6ewotICAgICAgICAgICAgICAgIE5vZGVJbXBsIGFuY2VzdG9yID0gKE5vZGVJbXBsKWdldEVsZW1lbnRBbmNlc3Rvcih0aGlzKTsKLSAgICAgICAgICAgICAgICBpZiAoYW5jZXN0b3IgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gYW5jZXN0b3IuaXNEZWZhdWx0TmFtZXNwYWNlKG5hbWVzcGFjZVVSSSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICB9Ci0qLwotICAgICAgICByZXR1cm4gZmFsc2U7Ci0KLQotICAgIH0KLQotICAgIC8qKgotICAgICAqCi0gICAgICogRE9NIExldmVsIDMgLSBFeHBlcmltZW50YWw6Ci0gICAgICogTG9vayB1cCB0aGUgcHJlZml4IGFzc29jaWF0ZWQgdG8gdGhlIGdpdmVuIG5hbWVzcGFjZSBVUkksIHN0YXJ0aW5nIGZyb20gdGhpcyBub2RlLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWVzcGFjZVVSSQotICAgICAqIEByZXR1cm4gdGhlIHByZWZpeCBmb3IgdGhlIG5hbWVzcGFjZQotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgbG9va3VwUHJlZml4KFN0cmluZyBuYW1lc3BhY2VVUkkpewotCi0gICAgICAgIC8vIFJFVklTSVQ6IFdoZW4gTmFtZXNwYWNlcyAxLjEgY29tZXMgb3V0IHRoaXMgbWF5IG5vdCBiZSB0cnVlCi0gICAgICAgIC8vIFByZWZpeCBjYW4ndCBiZSBib3VuZCB0byBudWxsIG5hbWVzcGFjZQotICAgICAgICBpZiAobmFtZXNwYWNlVVJJID09IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0KLSAgICAgICAgc2hvcnQgdHlwZSA9IHRoaXMuZ2V0Tm9kZVR5cGUoKTsKLQotICAgICAgICBzd2l0Y2ggKHR5cGUpIHsKLS8qCi0gICAgICAgIGNhc2UgTm9kZS5FTEVNRU5UX05PREU6IHsKLQotICAgICAgICAgICAgICAgIFN0cmluZyBuYW1lc3BhY2UgPSB0aGlzLmdldE5hbWVzcGFjZVVSSSgpOyAvLyB0byBmbGlwIG91dCBjaGlsZHJlbgotICAgICAgICAgICAgICAgIHJldHVybiBsb29rdXBOYW1lc3BhY2VQcmVmaXgobmFtZXNwYWNlVVJJLCAoRWxlbWVudEltcGwpdGhpcyk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgY2FzZSBOb2RlLkRPQ1VNRU5UX05PREU6ewotICAgICAgICAgICAgICAgIHJldHVybigoTm9kZUltcGwpKChEb2N1bWVudCl0aGlzKS5nZXREb2N1bWVudEVsZW1lbnQoKSkubG9va3VwUHJlZml4KG5hbWVzcGFjZVVSSSk7Ci0gICAgICAgICAgICB9Ci0qLwotICAgICAgICBjYXNlIE5vZGUuRU5USVRZX05PREUgOgotICAgICAgICBjYXNlIE5vZGUuTk9UQVRJT05fTk9ERToKLSAgICAgICAgY2FzZSBOb2RlLkRPQ1VNRU5UX0ZSQUdNRU5UX05PREU6Ci0gICAgICAgIGNhc2UgTm9kZS5ET0NVTUVOVF9UWVBFX05PREU6Ci0gICAgICAgICAgICAvLyB0eXBlIGlzIHVua25vd24KLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICBjYXNlIE5vZGUuQVRUUklCVVRFX05PREU6ewotICAgICAgICAgICAgICAgIGlmICh0aGlzLmdldE93bmVyRWxlbWVudCgpLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5FTEVNRU5UX05PREUpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGdldE93bmVyRWxlbWVudCgpLmxvb2t1cFByZWZpeChuYW1lc3BhY2VVUkkpOwotCi0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICAgICAgfQotICAgICAgICBkZWZhdWx0OnsKLS8qCi0gICAgICAgICAgICAgICAgTm9kZUltcGwgYW5jZXN0b3IgPSAoTm9kZUltcGwpZ2V0RWxlbWVudEFuY2VzdG9yKHRoaXMpOwotICAgICAgICAgICAgICAgIGlmIChhbmNlc3RvciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBhbmNlc3Rvci5sb29rdXBQcmVmaXgobmFtZXNwYWNlVVJJKTsKLSAgICAgICAgICAgICAgICB9Ci0qLwotICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICAgICAgfQotICAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgd2hldGhlciB0aGlzIG5vZGUgaXMgdGhlIHNhbWUgbm9kZSBhcyB0aGUgZ2l2ZW4gb25lLgotICAgICAqIDxicj5UaGlzIG1ldGhvZCBwcm92aWRlcyBhIHdheSB0byBkZXRlcm1pbmUgd2hldGhlciB0d28KLSAgICAgKiA8Y29kZT5Ob2RlPC9jb2RlPiByZWZlcmVuY2VzIHJldHVybmVkIGJ5IHRoZSBpbXBsZW1lbnRhdGlvbiByZWZlcmVuY2UKLSAgICAgKiB0aGUgc2FtZSBvYmplY3QuIFdoZW4gdHdvIDxjb2RlPk5vZGU8L2NvZGU+IHJlZmVyZW5jZXMgYXJlIHJlZmVyZW5jZXMKLSAgICAgKiB0byB0aGUgc2FtZSBvYmplY3QsIGV2ZW4gaWYgdGhyb3VnaCBhIHByb3h5LCB0aGUgcmVmZXJlbmNlcyBtYXkgYmUKLSAgICAgKiB1c2VkIGNvbXBsZXRlbHkgaW50ZXJjaGFuZ2FibHksIHN1Y2ggdGhhdCBhbGwgYXR0cmlidXRlcyBoYXZlIHRoZQotICAgICAqIHNhbWUgdmFsdWVzIGFuZCBjYWxsaW5nIHRoZSBzYW1lIERPTSBtZXRob2Qgb24gZWl0aGVyIHJlZmVyZW5jZQotICAgICAqIGFsd2F5cyBoYXMgZXhhY3RseSB0aGUgc2FtZSBlZmZlY3QuCi0gICAgICogQHBhcmFtIG90aGVyIFRoZSBub2RlIHRvIHRlc3QgYWdhaW5zdC4KLSAgICAgKiBAcmV0dXJuIFJldHVybnMgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIG5vZGVzIGFyZSB0aGUgc2FtZSwKLSAgICAgKiAgIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuCi0gICAgICogQHNpbmNlIERPTSBMZXZlbCAzCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNTYW1lTm9kZShOb2RlIG90aGVyKSB7Ci0gICAgICAgIC8vIHdlIGRvIG5vdCB1c2UgYW55IHdyYXBwZXIgc28gdGhlIGFuc3dlciBpcyBvYnZpb3VzCi0gICAgICAgIHJldHVybiB0aGlzID09IG90aGVyOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgYXR0cmlidXRlIHJldHVybnMgdGhlIHRleHQgY29udGVudCBvZiB0aGlzIG5vZGUgYW5kIGl0cwotICAgICAqIGRlc2NlbmRhbnRzLiBXaGVuIGl0IGlzIGRlZmluZWQgdG8gYmUgbnVsbCwgc2V0dGluZyBpdCBoYXMgbm8gZWZmZWN0LgotICAgICAqIFdoZW4gc2V0LCBhbnkgcG9zc2libGUgY2hpbGRyZW4gdGhpcyBub2RlIG1heSBoYXZlIGFyZSByZW1vdmVkIGFuZAotICAgICAqIHJlcGxhY2VkIGJ5IGEgc2luZ2xlIDxjb2RlPlRleHQ8L2NvZGU+IG5vZGUgY29udGFpbmluZyB0aGUgc3RyaW5nCi0gICAgICogdGhpcyBhdHRyaWJ1dGUgaXMgc2V0IHRvLiBPbiBnZXR0aW5nLCBubyBzZXJpYWxpemF0aW9uIGlzIHBlcmZvcm1lZCwKLSAgICAgKiB0aGUgcmV0dXJuZWQgc3RyaW5nIGRvZXMgbm90IGNvbnRhaW4gYW55IG1hcmt1cC4gTm8gd2hpdGVzcGFjZQotICAgICAqIG5vcm1hbGl6YXRpb24gaXMgcGVyZm9ybWVkLCB0aGUgcmV0dXJuZWQgc3RyaW5nIGRvZXMgbm90IGNvbnRhaW4gdGhlCi0gICAgICogZWxlbWVudCBjb250ZW50IHdoaXRlc3BhY2VzIC4gU2ltaWxhcmx5LCBvbiBzZXR0aW5nLCBubyBwYXJzaW5nIGlzCi0gICAgICogcGVyZm9ybWVkIGVpdGhlciwgdGhlIGlucHV0IHN0cmluZyBpcyB0YWtlbiBhcyBwdXJlIHRleHR1YWwgY29udGVudC4KLSAgICAgKiA8YnI+VGhlIHN0cmluZyByZXR1cm5lZCBpcyBtYWRlIG9mIHRoZSB0ZXh0IGNvbnRlbnQgb2YgdGhpcyBub2RlCi0gICAgICogZGVwZW5kaW5nIG9uIGl0cyB0eXBlLCBhcyBkZWZpbmVkIGJlbG93OgotICAgICAqIDx0YWJsZSBib3JkZXI9JzEnPgotICAgICAqIDx0cj4KLSAgICAgKiA8dGg+Tm9kZSB0eXBlPC90aD4KLSAgICAgKiA8dGg+Q29udGVudDwvdGg+Ci0gICAgICogPC90cj4KLSAgICAgKiA8dHI+Ci0gICAgICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz4KLSAgICAgKiBFTEVNRU5UX05PREUsIEVOVElUWV9OT0RFLCBFTlRJVFlfUkVGRVJFTkNFX05PREUsCi0gICAgICogRE9DVU1FTlRfRlJBR01FTlRfTk9ERTwvdGQ+Ci0gICAgICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz5jb25jYXRlbmF0aW9uIG9mIHRoZSA8Y29kZT50ZXh0Q29udGVudDwvY29kZT4KLSAgICAgKiBhdHRyaWJ1dGUgdmFsdWUgb2YgZXZlcnkgY2hpbGQgbm9kZSwgZXhjbHVkaW5nIENPTU1FTlRfTk9ERSBhbmQKLSAgICAgKiBQUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREUgbm9kZXM8L3RkPgotICAgICAqIDwvdHI+Ci0gICAgICogPHRyPgotICAgICAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+QVRUUklCVVRFX05PREUsIFRFWFRfTk9ERSwKLSAgICAgKiBDREFUQV9TRUNUSU9OX05PREUsIENPTU1FTlRfTk9ERSwgUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFPC90ZD4KLSAgICAgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPgotICAgICAqIDxjb2RlPm5vZGVWYWx1ZTwvY29kZT48L3RkPgotICAgICAqIDwvdHI+Ci0gICAgICogPHRyPgotICAgICAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+RE9DVU1FTlRfTk9ERSwgRE9DVU1FTlRfVFlQRV9OT0RFLCBOT1RBVElPTl9OT0RFPC90ZD4KLSAgICAgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPgotICAgICAqIG51bGw8L3RkPgotICAgICAqIDwvdHI+Ci0gICAgICogPC90YWJsZT4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgd2hlbiB0aGUgbm9kZSBpcyByZWFkb25seS4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgRE9NU1RSSU5HX1NJWkVfRVJSOiBSYWlzZWQgd2hlbiBpdCB3b3VsZCByZXR1cm4gbW9yZSBjaGFyYWN0ZXJzIHRoYW4KLSAgICAgKiAgIGZpdCBpbiBhIDxjb2RlPkRPTVN0cmluZzwvY29kZT4gdmFyaWFibGUgb24gdGhlIGltcGxlbWVudGF0aW9uCi0gICAgICogICBwbGF0Zm9ybS4KLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRUZXh0Q29udGVudChTdHJpbmcgdGV4dENvbnRlbnQpCi0gICAgICAgIHRocm93cyBET01FeGNlcHRpb24gewotICAgICAgICBzZXROb2RlVmFsdWUodGV4dENvbnRlbnQpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgYXR0cmlidXRlIHJldHVybnMgdGhlIHRleHQgY29udGVudCBvZiB0aGlzIG5vZGUgYW5kIGl0cwotICAgICAqIGRlc2NlbmRhbnRzLiBXaGVuIGl0IGlzIGRlZmluZWQgdG8gYmUgbnVsbCwgc2V0dGluZyBpdCBoYXMgbm8gZWZmZWN0LgotICAgICAqIFdoZW4gc2V0LCBhbnkgcG9zc2libGUgY2hpbGRyZW4gdGhpcyBub2RlIG1heSBoYXZlIGFyZSByZW1vdmVkIGFuZAotICAgICAqIHJlcGxhY2VkIGJ5IGEgc2luZ2xlIDxjb2RlPlRleHQ8L2NvZGU+IG5vZGUgY29udGFpbmluZyB0aGUgc3RyaW5nCi0gICAgICogdGhpcyBhdHRyaWJ1dGUgaXMgc2V0IHRvLiBPbiBnZXR0aW5nLCBubyBzZXJpYWxpemF0aW9uIGlzIHBlcmZvcm1lZCwKLSAgICAgKiB0aGUgcmV0dXJuZWQgc3RyaW5nIGRvZXMgbm90IGNvbnRhaW4gYW55IG1hcmt1cC4gTm8gd2hpdGVzcGFjZQotICAgICAqIG5vcm1hbGl6YXRpb24gaXMgcGVyZm9ybWVkLCB0aGUgcmV0dXJuZWQgc3RyaW5nIGRvZXMgbm90IGNvbnRhaW4gdGhlCi0gICAgICogZWxlbWVudCBjb250ZW50IHdoaXRlc3BhY2VzIC4gU2ltaWxhcmx5LCBvbiBzZXR0aW5nLCBubyBwYXJzaW5nIGlzCi0gICAgICogcGVyZm9ybWVkIGVpdGhlciwgdGhlIGlucHV0IHN0cmluZyBpcyB0YWtlbiBhcyBwdXJlIHRleHR1YWwgY29udGVudC4KLSAgICAgKiA8YnI+VGhlIHN0cmluZyByZXR1cm5lZCBpcyBtYWRlIG9mIHRoZSB0ZXh0IGNvbnRlbnQgb2YgdGhpcyBub2RlCi0gICAgICogZGVwZW5kaW5nIG9uIGl0cyB0eXBlLCBhcyBkZWZpbmVkIGJlbG93OgotICAgICAqIDx0YWJsZSBib3JkZXI9JzEnPgotICAgICAqIDx0cj4KLSAgICAgKiA8dGg+Tm9kZSB0eXBlPC90aD4KLSAgICAgKiA8dGg+Q29udGVudDwvdGg+Ci0gICAgICogPC90cj4KLSAgICAgKiA8dHI+Ci0gICAgICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz4KLSAgICAgKiBFTEVNRU5UX05PREUsIEVOVElUWV9OT0RFLCBFTlRJVFlfUkVGRVJFTkNFX05PREUsCi0gICAgICogRE9DVU1FTlRfRlJBR01FTlRfTk9ERTwvdGQ+Ci0gICAgICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz5jb25jYXRlbmF0aW9uIG9mIHRoZSA8Y29kZT50ZXh0Q29udGVudDwvY29kZT4KLSAgICAgKiBhdHRyaWJ1dGUgdmFsdWUgb2YgZXZlcnkgY2hpbGQgbm9kZSwgZXhjbHVkaW5nIENPTU1FTlRfTk9ERSBhbmQKLSAgICAgKiBQUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREUgbm9kZXM8L3RkPgotICAgICAqIDwvdHI+Ci0gICAgICogPHRyPgotICAgICAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+QVRUUklCVVRFX05PREUsIFRFWFRfTk9ERSwKLSAgICAgKiBDREFUQV9TRUNUSU9OX05PREUsIENPTU1FTlRfTk9ERSwgUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFPC90ZD4KLSAgICAgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPgotICAgICAqIDxjb2RlPm5vZGVWYWx1ZTwvY29kZT48L3RkPgotICAgICAqIDwvdHI+Ci0gICAgICogPHRyPgotICAgICAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+RE9DVU1FTlRfTk9ERSwgRE9DVU1FTlRfVFlQRV9OT0RFLCBOT1RBVElPTl9OT0RFPC90ZD4KLSAgICAgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPgotICAgICAqIG51bGw8L3RkPgotICAgICAqIDwvdHI+Ci0gICAgICogPC90YWJsZT4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgd2hlbiB0aGUgbm9kZSBpcyByZWFkb25seS4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgRE9NU1RSSU5HX1NJWkVfRVJSOiBSYWlzZWQgd2hlbiBpdCB3b3VsZCByZXR1cm4gbW9yZSBjaGFyYWN0ZXJzIHRoYW4KLSAgICAgKiAgIGZpdCBpbiBhIDxjb2RlPkRPTVN0cmluZzwvY29kZT4gdmFyaWFibGUgb24gdGhlIGltcGxlbWVudGF0aW9uCi0gICAgICogICBwbGF0Zm9ybS4KLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFRleHRDb250ZW50KCkgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0gICAgICAgIHJldHVybiBnZXROb2RlVmFsdWUoKTsgIC8vIG92ZXJyaWRlbiBpbiBzb21lIHN1YmNsYXNzZXMKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb21wYXJlcyBhIG5vZGUgd2l0aCB0aGlzIG5vZGUgd2l0aCByZWdhcmQgdG8gdGhlaXIgcG9zaXRpb24gaW4gdGhlCi0gICAgICogZG9jdW1lbnQuCi0gICAgICogQHBhcmFtIG90aGVyIFRoZSBub2RlIHRvIGNvbXBhcmUgYWdhaW5zdCB0aGlzIG5vZGUuCi0gICAgICogQHJldHVybiBSZXR1cm5zIGhvdyB0aGUgZ2l2ZW4gbm9kZSBpcyBwb3NpdGlvbmVkIHJlbGF0aXZlbHkgdG8gdGhpcwotICAgICAqICAgbm9kZS4KLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICAgKi8KLSAgICBwdWJsaWMgc2hvcnQgY29tcGFyZURvY3VtZW50UG9zaXRpb24oTm9kZSBvdGhlcikgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0gICAgICAgIHJldHVybiAwOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoZSBhYnNvbHV0ZSBiYXNlIFVSSSBvZiB0aGlzIG5vZGUgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdW5kZWZpbmVkLgotICAgICAqIFRoaXMgdmFsdWUgaXMgY29tcHV0ZWQgYWNjb3JkaW5nIHRvIC4gSG93ZXZlciwgd2hlbiB0aGUKLSAgICAgKiA8Y29kZT5Eb2N1bWVudDwvY29kZT4gc3VwcG9ydHMgdGhlIGZlYXR1cmUgIkhUTUwiICwgdGhlIGJhc2UgVVJJIGlzCi0gICAgICogY29tcHV0ZWQgdXNpbmcgZmlyc3QgdGhlIHZhbHVlIG9mIHRoZSBocmVmIGF0dHJpYnV0ZSBvZiB0aGUgSFRNTCBCQVNFCi0gICAgICogZWxlbWVudCBpZiBhbnksIGFuZCB0aGUgdmFsdWUgb2YgdGhlIDxjb2RlPmRvY3VtZW50VVJJPC9jb2RlPgotICAgICAqIGF0dHJpYnV0ZSBmcm9tIHRoZSA8Y29kZT5Eb2N1bWVudDwvY29kZT4gaW50ZXJmYWNlIG90aGVyd2lzZS4KLSAgICAgKiA8YnI+IFdoZW4gdGhlIG5vZGUgaXMgYW4gPGNvZGU+RWxlbWVudDwvY29kZT4sIGEgPGNvZGU+RG9jdW1lbnQ8L2NvZGU+Ci0gICAgICogb3IgYSBhIDxjb2RlPlByb2Nlc3NpbmdJbnN0cnVjdGlvbjwvY29kZT4sIHRoaXMgYXR0cmlidXRlIHJlcHJlc2VudHMKLSAgICAgKiB0aGUgcHJvcGVydGllcyBbYmFzZSBVUkldIGRlZmluZWQgaW4gLiBXaGVuIHRoZSBub2RlIGlzIGEKLSAgICAgKiA8Y29kZT5Ob3RhdGlvbjwvY29kZT4sIGFuIDxjb2RlPkVudGl0eTwvY29kZT4sIG9yIGFuCi0gICAgICogPGNvZGU+RW50aXR5UmVmZXJlbmNlPC9jb2RlPiwgdGhpcyBhdHRyaWJ1dGUgcmVwcmVzZW50cyB0aGUKLSAgICAgKiBwcm9wZXJ0aWVzIFtkZWNsYXJhdGlvbiBiYXNlIFVSSV0gaW4gdGhlIC4gSG93IHdpbGwgdGhpcyBiZSBhZmZlY3RlZAotICAgICAqIGJ5IHJlc29sdXRpb24gb2YgcmVsYXRpdmUgbmFtZXNwYWNlIFVSSXMgaXNzdWU/SXQncyBub3QuU2hvdWxkIHRoaXMKLSAgICAgKiBvbmx5IGJlIG9uIERvY3VtZW50LCBFbGVtZW50LCBQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24sIEVudGl0eSwgYW5kCi0gICAgICogTm90YXRpb24gbm9kZXMsIGFjY29yZGluZyB0byB0aGUgaW5mb3NldD8gSWYgbm90LCB3aGF0IGlzIGl0IGVxdWFsIHRvCi0gICAgICogb24gb3RoZXIgbm9kZXM/IE51bGw/IEFuIGVtcHR5IHN0cmluZz8gSSB0aGluayBpdCBzaG91bGQgYmUgdGhlCi0gICAgICogcGFyZW50J3MuTm8uU2hvdWxkIHRoaXMgYmUgcmVhZC1vbmx5IGFuZCBjb21wdXRlZCBvciBhbmQgYWN0dWFsCi0gICAgICogcmVhZC13cml0ZSBhdHRyaWJ1dGU/UmVhZC1vbmx5IGFuZCBjb21wdXRlZCAoRjJGIDE5IEp1biAyMDAwIGFuZAotICAgICAqIHRlbGVjb25mZXJlbmNlIDMwIE1heSAyMDAxKS5JZiB0aGUgYmFzZSBIVE1MIGVsZW1lbnQgaXMgbm90IHlldAotICAgICAqIGF0dGFjaGVkIHRvIGEgZG9jdW1lbnQsIGRvZXMgdGhlIGluc2VydCBjaGFuZ2UgdGhlIERvY3VtZW50LmJhc2VVUkk/Ci0gICAgICogWWVzLiAoRjJGIDI2IFNlcCAyMDAxKQotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0QmFzZVVSSSgpIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL3JlZi9zYXgyZHRtL1NBWDJEVE0uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9yZWYvc2F4MmR0bS9TQVgyRFRNLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDQ4NjM2NjYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL3JlZi9zYXgyZHRtL1NBWDJEVE0uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI1NDAgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwNywgMjAxNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqLwotLyoKLSAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQotICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCi0gKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCi0gKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAotICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKLSAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBTQVgyRFRNLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTUgMDg6MTU6MTEgc3VyZXNoX2VtYWlsaWQgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5yZWYuc2F4MmR0bTsKLQotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTU1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNV1NGaWx0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0ucmVmLkRUTURlZmF1bHRCYXNlSXRlcmF0b3JzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLnJlZi5EVE1NYW5hZ2VyRGVmYXVsdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5yZWYuRFRNU3RyaW5nUG9vbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5yZWYuRFRNVHJlZVdhbGtlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5yZWYuSW5jcmVtZW50YWxTQVhTb3VyY2U7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0ucmVmLk5vZGVMb2NhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzLlhNTEVycm9yUmVzb3VyY2VzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzLlhNTE1lc3NhZ2VzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuRmFzdFN0cmluZ0J1ZmZlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLkludFN0YWNrOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuSW50VmVjdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuU3RyaW5nVmVjdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuU3ViYWxsb2NhdGVkSW50VmVjdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuU3lzdGVtSURSZXNvbHZlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLldyYXBwZWRSdW50aW1lRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuWE1MU3RyaW5nOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuWE1MU3RyaW5nRmFjdG9yeTsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKLWltcG9ydCBqYXZhLnV0aWwuTWFwOwotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2U7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2VMb2NhdG9yOwotaW1wb3J0IG9yZy54bWwuc2F4LkF0dHJpYnV0ZXM7Ci1pbXBvcnQgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguRFRESGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5FbnRpdHlSZXNvbHZlcjsKLWltcG9ydCBvcmcueG1sLnNheC5FcnJvckhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguSW5wdXRTb3VyY2U7Ci1pbXBvcnQgb3JnLnhtbC5zYXguTG9jYXRvcjsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguZXh0LkRlY2xIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LmV4dC5MZXhpY2FsSGFuZGxlcjsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGltcGxlbWVudHMgYSBEVE0gdGhhdCB0ZW5kcyB0byBiZSBvcHRpbWl6ZWQgbW9yZSBmb3Igc3BlZWQgdGhhbgotICogZm9yIGNvbXBhY3RuZXNzLCB0aGF0IGlzIGNvbnN0cnVjdGVkIHZpYSBTQVgyIENvbnRlbnRIYW5kbGVyIGV2ZW50cy4KLSAqLwotcHVibGljIGNsYXNzIFNBWDJEVE0gZXh0ZW5kcyBEVE1EZWZhdWx0QmFzZUl0ZXJhdG9ycwotICAgICAgICBpbXBsZW1lbnRzIEVudGl0eVJlc29sdmVyLCBEVERIYW5kbGVyLCBDb250ZW50SGFuZGxlciwgRXJyb3JIYW5kbGVyLAotICAgICAgICAgICAgICAgICAgIERlY2xIYW5kbGVyLCBMZXhpY2FsSGFuZGxlcgotewotICAvKiogU2V0IHRydWUgdG8gbW9uaXRvciBTQVggZXZlbnRzIGFuZCBzaW1pbGFyIGRpYWdub3N0aWMgaW5mby4gKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbiBERUJVRyA9IGZhbHNlOwotCi0gIC8qKgotICAgKiBJZiB3ZSdyZSBidWlsZGluZyB0aGUgbW9kZWwgaW5jcmVtZW50YWxseSBvbiBkZW1hbmQsIHdlIG5lZWQgdG8KLSAgICogYmUgYWJsZSB0byB0ZWxsIHRoZSBzb3VyY2Ugd2hlbiB0byBzZW5kIHVzIG1vcmUgZGF0YS4KLSAgICoKLSAgICogTm90ZSB0aGF0IGlmIHRoaXMgaGFzIG5vdCBiZWVuIHNldCwgYW5kIHlvdSBhdHRlbXB0IHRvIHJlYWQgYWhlYWQKLSAgICogb2YgdGhlIGN1cnJlbnQgYnVpbGQgcG9pbnQsIHdlJ2xsIHByb2JhYmx5IHRocm93IGEgbnVsbC1wb2ludGVyCi0gICAqIGV4Y2VwdGlvbi4gV2UgY291bGQgdHJ5IHRvIHdhaXQtYW5kLXJldHJ5IGluc3RlYWQsIGFzIGEgdmVyeSBwb29yCi0gICAqIGZhbGxiYWNrLCBidXQgdGhhdCBoYXMgYWxsIHRoZSBrbm93biBwcm9ibGVtcyB3aXRoIG11bHRpdGhyZWFkaW5nCi0gICAqIG9uIG11bHRpcHJvY2Vzc29ycyBhbmQgd2UgRG9uJ3QgV2FudCB0byBHbyBUaGVyZS4KLSAgICoKLSAgICogQHNlZSBzZXRJbmNyZW1lbnRhbFNBWFNvdXJjZQotICAgKi8KLSAgcHJpdmF0ZSBJbmNyZW1lbnRhbFNBWFNvdXJjZSBtX2luY3JlbWVudGFsU0FYU291cmNlID0gbnVsbDsKLQotICAvKioKLSAgICogQWxsIHRoZSBjaGFyYWN0ZXIgY29udGVudCwgaW5jbHVkaW5nIGF0dHJpYnV0ZSB2YWx1ZXMsIGFyZSBzdG9yZWQgaW4KLSAgICogdGhpcyBidWZmZXIuCi0gICAqCi0gICAqICVSRVZJRVclIFNob3VsZCB0aGlzIGhhdmUgYW4gb3B0aW9uIG9mIGJlaW5nIHNoYXJlZCBhY3Jvc3MgRFRNcz8KLSAgICogU2VxdWVudGlhbGx5IG9ubHk7IG5vdCB0aHJlYWRzYWZlLi4uIEN1cnJlbnRseSwgSSB0aGluayBub3QuCi0gICAqCi0gICAqICVSRVZJRVclIEluaXRpYWwgc2l6ZSB3YXMgcHVzaGVkIHdheSBkb3duIHRvIHJlZHVjZSB3ZWlnaHQgb2YgUlRGcy4KLSAgICogcGVuZGluZyByZWR1Y3Rpb24gaW4gbnVtYmVyIG9mIFJURiBEVE1zLiBOb3cgdGhhdCB3ZSdyZSBzaGFyaW5nIGEgRFRNCi0gICAqIGJldHdlZW4gUlRGcywgYW5kIHRhaWwtcHJ1bmluZy4uLiBjb25zaWRlciBnb2luZyBiYWNrIHRvIHRoZSBsYXJnZXIvZmFzdGVyLgotICAgKgotICAgKiBNYWRlIHByb3RlY3RlZCByYXRoZXIgdGhhbiBwcml2YXRlIHNvIFNBWDJSVEZEVE0gY2FuIGFjY2VzcyBpdC4KLSAgICovCi0gIC8vcHJpdmF0ZSBGYXN0U3RyaW5nQnVmZmVyIG1fY2hhcnMgPSBuZXcgRmFzdFN0cmluZ0J1ZmZlcigxMywgMTMpOwotICBwcm90ZWN0ZWQgRmFzdFN0cmluZ0J1ZmZlciBtX2NoYXJzOwotCi0gIC8qKiBUaGlzIHZlY3RvciBob2xkcyBvZmZzZXQgYW5kIGxlbmd0aCBkYXRhLgotICAgKi8KLSAgcHJvdGVjdGVkIFN1YmFsbG9jYXRlZEludFZlY3RvciBtX2RhdGE7Ci0KLSAgLyoqIFRoZSBwYXJlbnQgc3RhY2ssIG5lZWRlZCBvbmx5IGZvciBjb25zdHJ1Y3Rpb24uCi0gICAqIE1hZGUgcHJvdGVjdGVkIHJhdGhlciB0aGFuIHByaXZhdGUgc28gU0FYMlJURkRUTSBjYW4gYWNjZXNzIGl0LgotICAgKi8KLSAgdHJhbnNpZW50IHByb3RlY3RlZCBJbnRTdGFjayBtX3BhcmVudHM7Ci0KLSAgLyoqIFRoZSBjdXJyZW50IHByZXZpb3VzIG5vZGUsIG5lZWRlZCBvbmx5IGZvciBjb25zdHJ1Y3Rpb24gdGltZS4KLSAgICogTWFkZSBwcm90ZWN0ZWQgcmF0aGVyIHRoYW4gcHJpdmF0ZSBzbyBTQVgyUlRGRFRNIGNhbiBhY2Nlc3MgaXQuCi0gICAqLwotICB0cmFuc2llbnQgcHJvdGVjdGVkIGludCBtX3ByZXZpb3VzID0gMDsKLQotICAvKiogTmFtZXNwYWNlIHN1cHBvcnQsIG9ubHkgcmVsZXZlbnQgYXQgY29uc3RydWN0aW9uIHRpbWUuCi0gICAqIE1hZGUgcHJvdGVjdGVkIHJhdGhlciB0aGFuIHByaXZhdGUgc28gU0FYMlJURkRUTSBjYW4gYWNjZXNzIGl0LgotICAgKi8KLSAgdHJhbnNpZW50IHByb3RlY3RlZCBqYXZhLnV0aWwuVmVjdG9yIG1fcHJlZml4TWFwcGluZ3MgPQotICAgIG5ldyBqYXZhLnV0aWwuVmVjdG9yKCk7Ci0KLSAgLyoqIE5hbWVzcGFjZSBzdXBwb3J0LCBvbmx5IHJlbGV2ZW50IGF0IGNvbnN0cnVjdGlvbiB0aW1lLgotICAgKiBNYWRlIHByb3RlY3RlZCByYXRoZXIgdGhhbiBwcml2YXRlIHNvIFNBWDJSVEZEVE0gY2FuIGFjY2VzcyBpdC4KLSAgICovCi0gIHRyYW5zaWVudCBwcm90ZWN0ZWQgSW50U3RhY2sgbV9jb250ZXh0SW5kZXhlczsKLQotICAvKiogVHlwZSBvZiBuZXh0IGNoYXJhY3RlcnMoKSBldmVudCB3aXRoaW4gdGV4dCBibG9jayBpbiBwcmdyZXNzLiAqLwotICB0cmFuc2llbnQgcHJvdGVjdGVkIGludCBtX3RleHRUeXBlID0gRFRNLlRFWFRfTk9ERTsKLQotICAvKioKLSAgICogVHlwZSBvZiBjb2FsZXNjZWQgdGV4dCBibG9jay4gU2VlIGxvZ2ljIGluIHRoZSBjaGFyYWN0ZXJzKCkKLSAgICogbWV0aG9kLgotICAgKi8KLSAgdHJhbnNpZW50IHByb3RlY3RlZCBpbnQgbV9jb2FsZXNjZWRUZXh0VHlwZSA9IERUTS5URVhUX05PREU7Ci0KLSAgLyoqIFRoZSBTQVggRG9jdW1lbnQgbG9jYXRvciAqLwotICB0cmFuc2llbnQgcHJvdGVjdGVkIExvY2F0b3IgbV9sb2NhdG9yID0gbnVsbDsKLQotICAvKiogVGhlIFNBWCBEb2N1bWVudCBzeXN0ZW0taWQgKi8KLSAgdHJhbnNpZW50IHByaXZhdGUgU3RyaW5nIG1fc3lzdGVtSWQgPSBudWxsOwotCi0gIC8qKiBXZSBhcmUgaW5zaWRlIHRoZSBEVEQuICBUaGlzIGlzIHVzZWQgZm9yIGlnbm9yaW5nIGNvbW1lbnRzLiAgKi8KLSAgdHJhbnNpZW50IHByb3RlY3RlZCBib29sZWFuIG1faW5zaWRlRFREID0gZmFsc2U7Ci0KLSAgLyoqIFRyZWUgV2Fsa2VyIGZvciBkaXNwYXRjaFRvRXZlbnRzLiAqLwotICBwcm90ZWN0ZWQgRFRNVHJlZVdhbGtlciBtX3dhbGtlciA9IG5ldyBEVE1UcmVlV2Fsa2VyKCk7Ci0KLSAgLyoqIHBvb2wgb2Ygc3RyaW5nIHZhbHVlcyB0aGF0IGNvbWUgYXMgc3RyaW5ncy4gKi8KLSAgcHJvdGVjdGVkIERUTVN0cmluZ1Bvb2wgbV92YWx1ZXNPclByZWZpeGVzOwotCi0gIC8qKiBFbmQgZG9jdW1lbnQgaGFzIGJlZW4gcmVhY2hlZC4KLSAgICogTWFkZSBwcm90ZWN0ZWQgcmF0aGVyIHRoYW4gcHJpdmF0ZSBzbyBTQVgyUlRGRFRNIGNhbiBhY2Nlc3MgaXQuCi0gICAqLwotICBwcm90ZWN0ZWQgYm9vbGVhbiBtX2VuZERvY3VtZW50T2NjdXJlZCA9IGZhbHNlOwotCi0gIC8qKiBEYXRhIG9yIHF1YWxpZmllZCBuYW1lIHZhbHVlcywgb25lIGFycmF5IGVsZW1lbnQgZm9yIGVhY2ggbm9kZS4gKi8KLSAgcHJvdGVjdGVkIFN1YmFsbG9jYXRlZEludFZlY3RvciBtX2RhdGFPclFOYW1lOwotCi0gIC8qKgotICAgKiBUaGlzIHRhYmxlIGhvbGRzIHRoZSBJRCBzdHJpbmcgdG8gbm9kZSBhc3NvY2lhdGlvbnMsIGZvcgotICAgKiBYTUwgSURzLgotICAgKi8KLSAgcHJvdGVjdGVkIE1hcDxTdHJpbmcsIEludGVnZXI+IG1faWRBdHRyaWJ1dGVzID0gbmV3IEhhc2hNYXA8PigpOwotCi0gIC8qKgotICAgKiBmaXhlZCBkb20tc3R5bGUgbmFtZXMuCi0gICAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSBtX2ZpeGVkbmFtZXMgPSB7IG51bGwsCi0gICAgICAgICAgICAgICAgICAgIG51bGwsICAvLyBub3RoaW5nLCBFbGVtZW50Ci0gICAgICAgICAgICAgICAgICAgIG51bGwsICIjdGV4dCIsICAvLyBBdHRyLCBUZXh0Ci0gICAgICAgICAgICAgICAgICAgICIjY2RhdGFfc2VjdGlvbiIsIG51bGwsICAvLyBDREFUQSwgRW50aXR5UmVmZXJlbmNlCi0gICAgICAgICAgICAgICAgICAgIG51bGwsIG51bGwsICAvLyBFbnRpdHksIFBJCi0gICAgICAgICAgICAgICAgICAgICIjY29tbWVudCIsICIjZG9jdW1lbnQiLCAgLy8gQ29tbWVudCwgRG9jdW1lbnQKLSAgICAgICAgICAgICAgICAgICAgbnVsbCwgIiNkb2N1bWVudC1mcmFnbWVudCIsICAvLyBEb2N0eXBlLCBEb2N1bWVudEZyYWdtZW50Ci0gICAgICAgICAgICAgICAgICAgIG51bGwgfTsgIC8vIE5vdGF0aW9uCi0KLSAgLyoqCi0gICAqIFZlY3RvciBvZiBlbnRpdGllcy4gIEVhY2ggcmVjb3JkIGlzIGNvbXBvc2VkIG9mIGZvdXIgU3RyaW5nczoKLSAgICogIHB1YmxpY0lkLCBzeXN0ZW1JRCwgbm90YXRpb25OYW1lLCBhbmQgbmFtZS4KLSAgICovCi0gIHByaXZhdGUgVmVjdG9yIG1fZW50aXRpZXMgPSBudWxsOwotCi0gIC8qKiBtX2VudGl0aWVzIHB1YmxpYyBJRCBvZmZzZXQuICovCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBFTlRJVFlfRklFTERfUFVCTElDSUQgPSAwOwotCi0gIC8qKiBtX2VudGl0aWVzIHN5c3RlbSBJRCBvZmZzZXQuICovCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBFTlRJVFlfRklFTERfU1lTVEVNSUQgPSAxOwotCi0gIC8qKiBtX2VudGl0aWVzIG5vdGF0aW9uIG5hbWUgb2Zmc2V0LiAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgRU5USVRZX0ZJRUxEX05PVEFUSU9OTkFNRSA9IDI7Ci0KLSAgLyoqIG1fZW50aXRpZXMgbmFtZSBvZmZzZXQuICovCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBFTlRJVFlfRklFTERfTkFNRSA9IDM7Ci0KLSAgLyoqIE51bWJlciBvZiBlbnRyaWVzIHBlciByZWNvcmQgZm9yIG1fZW50aXRpZXMuICovCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBFTlRJVFlfRklFTERTX1BFUiA9IDQ7Ci0KLSAgLyoqCi0gICAqIFRoZSBzdGFydGluZyBvZmZzZXQgd2l0aGluIG1fY2hhcnMgZm9yIHRoZSB0ZXh0IG9yCi0gICAqIENEQVRBX1NFQ1RJT04gbm9kZSBjdXJyZW50bHkgYmVpbmcgYWN1bXVsYXRlZCwKLSAgICogb3IgLTEgaWYgdGhlcmUgaXMgbm8gdGV4dCBub2RlIGluIHByb2dyZXNzCi0gICAqLwotICBwcm90ZWN0ZWQgaW50IG1fdGV4dFBlbmRpbmdTdGFydCA9IC0xOwotCi0gIC8qKgotICAgKiBEZXNjcmliZXMgd2hldGhlciBpbmZvcm1hdGlvbiBhYm91dCBkb2N1bWVudCBzb3VyY2UgbG9jYXRpb24KLSAgICogc2hvdWxkIGJlIG1haW50YWluZWQgb3Igbm90LgotICAgKgotICAgKiBNYWRlIHByb3RlY3RlZCBmb3IgYWNjZXNzIGJ5IFNBWDJSVEZEVE0uCi0gICAqLwotICBwcm90ZWN0ZWQgYm9vbGVhbiBtX3VzZVNvdXJjZUxvY2F0aW9uUHJvcGVydHkgPSBmYWxzZTsKLQotICAgLyoqIE1hZGUgcHJvdGVjdGVkIGZvciBhY2Nlc3MgYnkgU0FYMlJURkRUTS4KLSAgICovCi0gIHByb3RlY3RlZCBTdHJpbmdWZWN0b3IgbV9zb3VyY2VTeXN0ZW1JZDsKLSAgIC8qKiBNYWRlIHByb3RlY3RlZCBmb3IgYWNjZXNzIGJ5IFNBWDJSVEZEVE0uCi0gICAqLwotICBwcm90ZWN0ZWQgSW50VmVjdG9yIG1fc291cmNlTGluZTsKLSAgIC8qKiBNYWRlIHByb3RlY3RlZCBmb3IgYWNjZXNzIGJ5IFNBWDJSVEZEVE0uCi0gICAqLwotICBwcm90ZWN0ZWQgSW50VmVjdG9yIG1fc291cmNlQ29sdW1uOwotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBTQVgyRFRNIG9iamVjdCB1c2luZyB0aGUgZGVmYXVsdCBibG9jayBzaXplLgotICAgKgotICAgKiBAcGFyYW0gbWdyIFRoZSBEVE1NYW5hZ2VyIHdobyBvd25zIHRoaXMgRFRNLgotICAgKiBAcGFyYW0gc291cmNlIHRoZSBKQVhQIDEuMSBTb3VyY2Ugb2JqZWN0IGZvciB0aGlzIERUTS4KLSAgICogQHBhcmFtIGR0bUlkZW50aXR5IFRoZSBEVE0gaWRlbnRpdHkgSUQgZm9yIHRoaXMgRFRNLgotICAgKiBAcGFyYW0gd2hpdGVTcGFjZUZpbHRlciBUaGUgd2hpdGUgc3BhY2UgZmlsdGVyIGZvciB0aGlzIERUTSwgd2hpY2ggbWF5Ci0gICAqICAgICAgICAgICAgICAgICAgICAgICAgIGJlIG51bGwuCi0gICAqIEBwYXJhbSB4c3RyaW5nZmFjdG9yeSBYTUxTdHJpbmcgZmFjdG9yeSBmb3IgY3JlYXRpbmcgY2hhcmFjdGVyIGNvbnRlbnQuCi0gICAqIEBwYXJhbSBkb0luZGV4aW5nIHRydWUgaWYgdGhlIGNhbGxlciBjb25zaWRlcnMgaXQgd29ydGggaXQgdG8gdXNlCi0gICAqICAgICAgICAgICAgICAgICAgIGluZGV4aW5nIHNjaGVtZXMuCi0gICAqLwotICBwdWJsaWMgU0FYMkRUTShEVE1NYW5hZ2VyIG1nciwgU291cmNlIHNvdXJjZSwgaW50IGR0bUlkZW50aXR5LAotICAgICAgICAgICAgICAgICBEVE1XU0ZpbHRlciB3aGl0ZVNwYWNlRmlsdGVyLAotICAgICAgICAgICAgICAgICBYTUxTdHJpbmdGYWN0b3J5IHhzdHJpbmdmYWN0b3J5LAotICAgICAgICAgICAgICAgICBib29sZWFuIGRvSW5kZXhpbmcpCi0gIHsKLQotICAgIHRoaXMobWdyLCBzb3VyY2UsIGR0bUlkZW50aXR5LCB3aGl0ZVNwYWNlRmlsdGVyLAotICAgICAgICAgIHhzdHJpbmdmYWN0b3J5LCBkb0luZGV4aW5nLCBERUZBVUxUX0JMT0NLU0laRSwgdHJ1ZSwgZmFsc2UpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhIFNBWDJEVE0gb2JqZWN0IHJlYWR5IHRvIGJlIGNvbnN0cnVjdGVkIGZyb20gU0FYMgotICAgKiBDb250ZW50SGFuZGxlciBldmVudHMuCi0gICAqCi0gICAqIEBwYXJhbSBtZ3IgVGhlIERUTU1hbmFnZXIgd2hvIG93bnMgdGhpcyBEVE0uCi0gICAqIEBwYXJhbSBzb3VyY2UgdGhlIEpBWFAgMS4xIFNvdXJjZSBvYmplY3QgZm9yIHRoaXMgRFRNLgotICAgKiBAcGFyYW0gZHRtSWRlbnRpdHkgVGhlIERUTSBpZGVudGl0eSBJRCBmb3IgdGhpcyBEVE0uCi0gICAqIEBwYXJhbSB3aGl0ZVNwYWNlRmlsdGVyIFRoZSB3aGl0ZSBzcGFjZSBmaWx0ZXIgZm9yIHRoaXMgRFRNLCB3aGljaCBtYXkKLSAgICogICAgICAgICAgICAgICAgICAgICAgICAgYmUgbnVsbC4KLSAgICogQHBhcmFtIHhzdHJpbmdmYWN0b3J5IFhNTFN0cmluZyBmYWN0b3J5IGZvciBjcmVhdGluZyBjaGFyYWN0ZXIgY29udGVudC4KLSAgICogQHBhcmFtIGRvSW5kZXhpbmcgdHJ1ZSBpZiB0aGUgY2FsbGVyIGNvbnNpZGVycyBpdCB3b3J0aCBpdCB0byB1c2UKLSAgICogICAgICAgICAgICAgICAgICAgaW5kZXhpbmcgc2NoZW1lcy4KLSAgICogQHBhcmFtIGJsb2Nrc2l6ZSBUaGUgYmxvY2sgc2l6ZSBvZiB0aGUgRFRNLgotICAgKiBAcGFyYW0gdXNlUHJldnNpYiB0cnVlIGlmIHdlIHdhbnQgdG8gYnVpbGQgdGhlIHByZXZpb3VzIHNpYmxpbmcgbm9kZSBhcnJheS4KLSAgICogQHBhcmFtIG5ld05hbWVUYWJsZSB0cnVlIGlmIHdlIHdhbnQgdG8gdXNlIGEgbmV3IEV4cGFuZGVkTmFtZVRhYmxlIGZvciB0aGlzIERUTS4KLSAgICovCi0gIHB1YmxpYyBTQVgyRFRNKERUTU1hbmFnZXIgbWdyLCBTb3VyY2Ugc291cmNlLCBpbnQgZHRtSWRlbnRpdHksCi0gICAgICAgICAgICAgICAgIERUTVdTRmlsdGVyIHdoaXRlU3BhY2VGaWx0ZXIsCi0gICAgICAgICAgICAgICAgIFhNTFN0cmluZ0ZhY3RvcnkgeHN0cmluZ2ZhY3RvcnksCi0gICAgICAgICAgICAgICAgIGJvb2xlYW4gZG9JbmRleGluZywKLSAgICAgICAgICAgICAgICAgaW50IGJsb2Nrc2l6ZSwKLSAgICAgICAgICAgICAgICAgYm9vbGVhbiB1c2VQcmV2c2liLAotICAgICAgICAgICAgICAgICBib29sZWFuIG5ld05hbWVUYWJsZSkKLSAgewotCi0gICAgc3VwZXIobWdyLCBzb3VyY2UsIGR0bUlkZW50aXR5LCB3aGl0ZVNwYWNlRmlsdGVyLAotICAgICAgICAgIHhzdHJpbmdmYWN0b3J5LCBkb0luZGV4aW5nLCBibG9ja3NpemUsIHVzZVByZXZzaWIsIG5ld05hbWVUYWJsZSk7Ci0KLSAgICAvLyAlT1BUJSBVc2Ugc21hbGxlciBzaXplcyBmb3IgYWxsIGludGVybmFsIHN0b3JhZ2UgdW5pdHMgd2hlbgotICAgIC8vIHRoZSBibG9ja3NpemUgaXMgc21hbGwuIFRoaXMgcmVkdWNlcyB0aGUgY29zdCBvZiBjcmVhdGluZyBhbiBSVEYuCi0gICAgaWYgKGJsb2Nrc2l6ZSA8PSA2NCkKLSAgICB7Ci0gICAgICBtX2RhdGEgPSBuZXcgU3ViYWxsb2NhdGVkSW50VmVjdG9yKGJsb2Nrc2l6ZSwgREVGQVVMVF9OVU1CTE9DS1NfU01BTEwpOwotICAgICAgbV9kYXRhT3JRTmFtZSA9IG5ldyBTdWJhbGxvY2F0ZWRJbnRWZWN0b3IoYmxvY2tzaXplLCBERUZBVUxUX05VTUJMT0NLU19TTUFMTCk7Ci0gICAgICBtX3ZhbHVlc09yUHJlZml4ZXMgPSBuZXcgRFRNU3RyaW5nUG9vbCgxNik7Ci0gICAgICBtX2NoYXJzID0gbmV3IEZhc3RTdHJpbmdCdWZmZXIoNywgMTApOwotICAgICAgbV9jb250ZXh0SW5kZXhlcyA9IG5ldyBJbnRTdGFjayg0KTsKLSAgICAgIG1fcGFyZW50cyA9IG5ldyBJbnRTdGFjayg0KTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIG1fZGF0YSA9IG5ldyBTdWJhbGxvY2F0ZWRJbnRWZWN0b3IoYmxvY2tzaXplLCBERUZBVUxUX05VTUJMT0NLUyk7Ci0gICAgICBtX2RhdGFPclFOYW1lID0gbmV3IFN1YmFsbG9jYXRlZEludFZlY3RvcihibG9ja3NpemUsIERFRkFVTFRfTlVNQkxPQ0tTKTsKLSAgICAgIG1fdmFsdWVzT3JQcmVmaXhlcyA9IG5ldyBEVE1TdHJpbmdQb29sKCk7Ci0gICAgICBtX2NoYXJzID0gbmV3IEZhc3RTdHJpbmdCdWZmZXIoMTAsIDEzKTsKLSAgICAgIG1fY29udGV4dEluZGV4ZXMgPSBuZXcgSW50U3RhY2soKTsKLSAgICAgIG1fcGFyZW50cyA9IG5ldyBJbnRTdGFjaygpOwotICAgIH0KLQotICAgIC8vICVSRVZJRVclICBJbml0aWFsIHNpemUgcHVzaGVkIHdheSBkb3duIHRvIHJlZHVjZSB3ZWlnaHQgb2YgUlRGcwotICAgIC8vIChJJ20gbm90IGVudGlyZWx5IHN1cmUgMCB3b3VsZCB3b3JrLCBzbyBJJ20gcGxheWluZyBpdCBzYWZlIGZvciBub3cuKQotICAgIC8vbV9kYXRhID0gbmV3IFN1YmFsbG9jYXRlZEludFZlY3Rvcihkb0luZGV4aW5nID8gKDEwMjQqMikgOiA1MTIsIDEwMjQpOwotICAgIC8vbV9kYXRhID0gbmV3IFN1YmFsbG9jYXRlZEludFZlY3RvcihibG9ja3NpemUpOwotCi0gICAgbV9kYXRhLmFkZEVsZW1lbnQoMCk7ICAgLy8gTmVlZCBwbGFjZWhvbGRlciBpbiBjYXNlIGluZGV4IGludG8gaGVyZSBtdXN0IGJlIDwwLgotCi0gICAgLy9tX2RhdGFPclFOYW1lID0gbmV3IFN1YmFsbG9jYXRlZEludFZlY3RvcihibG9ja3NpemUpOwotCi0gICAgLy8gbV91c2VTb3VyY2VMb2NhdGlvblByb3BlcnR5PWNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC5wcm9jZXNzb3IuVHJhbnNmb3JtZXJGYWN0b3J5SW1wbC5tX3NvdXJjZV9sb2NhdGlvbjsKLSAgICBtX3VzZVNvdXJjZUxvY2F0aW9uUHJvcGVydHkgPSBtZ3IuZ2V0U291cmNlX2xvY2F0aW9uKCk7Ci0gICAgbV9zb3VyY2VTeXN0ZW1JZCA9IChtX3VzZVNvdXJjZUxvY2F0aW9uUHJvcGVydHkpID8gbmV3IFN0cmluZ1ZlY3RvcigpIDogbnVsbDsKLSAgICAgICAgbV9zb3VyY2VMaW5lID0gKG1fdXNlU291cmNlTG9jYXRpb25Qcm9wZXJ0eSkgPyAgbmV3IEludFZlY3RvcigpIDogbnVsbDsKLSAgICBtX3NvdXJjZUNvbHVtbiA9IChtX3VzZVNvdXJjZUxvY2F0aW9uUHJvcGVydHkpID8gIG5ldyBJbnRWZWN0b3IoKSA6IG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHdoZXRoZXIgaW5mb3JtYXRpb24gYWJvdXQgZG9jdW1lbnQgc291cmNlIGxvY2F0aW9uCi0gICAqIHNob3VsZCBiZSBtYWludGFpbmVkIG9yIG5vdC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFVzZVNvdXJjZUxvY2F0aW9uKGJvb2xlYW4gdXNlU291cmNlTG9jYXRpb24pCi0gIHsKLSAgICBtX3VzZVNvdXJjZUxvY2F0aW9uUHJvcGVydHkgPSB1c2VTb3VyY2VMb2NhdGlvbjsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGRhdGEgb3IgcXVhbGlmaWVkIG5hbWUgZm9yIHRoZSBnaXZlbiBub2RlIGlkZW50aXR5LgotICAgKgotICAgKiBAcGFyYW0gaWRlbnRpdHkgVGhlIG5vZGUgaWRlbnRpdHkuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGRhdGEgb3IgcXVhbGlmaWVkIG5hbWUsIG9yIERUTS5OVUxMLgotICAgKi8KLSAgcHJvdGVjdGVkIGludCBfZGF0YU9yUU5hbWUoaW50IGlkZW50aXR5KQotICB7Ci0KLSAgICBpZiAoaWRlbnRpdHkgPCBtX3NpemUpCi0gICAgICByZXR1cm4gbV9kYXRhT3JRTmFtZS5lbGVtZW50QXQoaWRlbnRpdHkpOwotCi0gICAgLy8gQ2hlY2sgdG8gc2VlIGlmIHRoZSBpbmZvcm1hdGlvbiByZXF1ZXN0ZWQgaGFzIGJlZW4gcHJvY2Vzc2VkLCBhbmQsCi0gICAgLy8gaWYgbm90LCBhZHZhbmNlIHRoZSBpdGVyYXRvciB1bnRpbCB3ZSB0aGUgaW5mb3JtYXRpb24gaGFzIGJlZW4KLSAgICAvLyBwcm9jZXNzZWQuCi0gICAgd2hpbGUgKHRydWUpCi0gICAgewotICAgICAgYm9vbGVhbiBpc01vcmUgPSBuZXh0Tm9kZSgpOwotCi0gICAgICBpZiAoIWlzTW9yZSkKLSAgICAgICAgcmV0dXJuIE5VTEw7Ci0gICAgICBlbHNlIGlmIChpZGVudGl0eSA8IG1fc2l6ZSkKLSAgICAgICAgcmV0dXJuIG1fZGF0YU9yUU5hbWUuZWxlbWVudEF0KGlkZW50aXR5KTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogQXNrIHRoZSBDb1JvdXRpbmUgcGFyc2VyIHRvIGRvVGVybWluYXRlIGFuZCBjbGVhciB0aGUgcmVmZXJlbmNlLgotICAgKi8KLSAgcHVibGljIHZvaWQgY2xlYXJDb1JvdXRpbmUoKQotICB7Ci0gICAgY2xlYXJDb1JvdXRpbmUodHJ1ZSk7Ci0gIH0KLQotICAvKioKLSAgICogQXNrIHRoZSBDb1JvdXRpbmUgcGFyc2VyIHRvIGRvVGVybWluYXRlIGFuZCBjbGVhciB0aGUgcmVmZXJlbmNlLiBJZgotICAgKiB0aGUgQ29Sb3V0aW5lIHBhcnNlciBoYXMgYWxyZWFkeSBiZWVuIGNsZWFyZWQsIHRoaXMgd2lsbCBoYXZlIG5vIGVmZmVjdC4KLSAgICoKLSAgICogQHBhcmFtIGNhbGxEb1Rlcm1pbmF0ZSB0cnVlIG9mIGRvVGVybWluYXRlIHNob3VsZCBiZSBjYWxsZWQgb24gdGhlCi0gICAqIGNvUm91dGluZSBwYXJzZXIuCi0gICAqLwotICBwdWJsaWMgdm9pZCBjbGVhckNvUm91dGluZShib29sZWFuIGNhbGxEb1Rlcm1pbmF0ZSkKLSAgewotCi0gICAgaWYgKG51bGwgIT0gbV9pbmNyZW1lbnRhbFNBWFNvdXJjZSkKLSAgICB7Ci0gICAgICBpZiAoY2FsbERvVGVybWluYXRlKQotICAgICAgICBtX2luY3JlbWVudGFsU0FYU291cmNlLmRlbGl2ZXJNb3JlTm9kZXMoZmFsc2UpOwotCi0gICAgICBtX2luY3JlbWVudGFsU0FYU291cmNlID0gbnVsbDsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogQmluZCBhIEluY3JlbWVudGFsU0FYU291cmNlIHRvIHRoaXMgRFRNLiBJZiB3ZSBkaXNjb3ZlciB3ZSBuZWVkIG5vZGVzCi0gICAqIHRoYXQgaGF2ZSBub3QgeWV0IGJlZW4gYnVpbHQsIHdlIHdpbGwgYXNrIHRoaXMgb2JqZWN0IHRvIHNlbmQgdXMgbW9yZQotICAgKiBldmVudHMsIGFuZCBpdCB3aWxsIG1hbmFnZSBpbnRlcmFjdGlvbnMgd2l0aCBpdHMgZGF0YSBzb3VyY2VzLgotICAgKgotICAgKiBOb3RlIHRoYXQgd2UgZG8gbm90IGFjdHVhbGx5IGJ1aWxkIHRoZSBJbmNyZW1lbnRhbFNBWFNvdXJjZSwgc2luY2Ugd2UgZG9uJ3QKLSAgICoga25vdyB3aGF0IHNvdXJjZSBpdCdzIHJlYWRpbmcgZnJvbSwgd2hhdCB0aHJlYWQgdGhhdCBzb3VyY2Ugd2lsbCBydW4gaW4sCi0gICAqIG9yIHdoZW4gaXQgd2lsbCBydW4uCi0gICAqCi0gICAqIEBwYXJhbSBpbmNyZW1lbnRhbFNBWFNvdXJjZSBUaGUgcGFyc2VyIHRoYXQgd2Ugd2FudCB0byByZWNpZXZlIGV2ZW50cyBmcm9tCi0gICAqIG9uIGRlbWFuZC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldEluY3JlbWVudGFsU0FYU291cmNlKEluY3JlbWVudGFsU0FYU291cmNlIGluY3JlbWVudGFsU0FYU291cmNlKQotICB7Ci0KLSAgICAvLyBFc3RhYmxpc2ggY29yb3V0aW5lIGxpbmsgc28gd2UgY2FuIHJlcXVlc3QgbW9yZSBkYXRhCi0gICAgLy8KLSAgICAvLyBOb3RlOiBJdCdzIHBvc3NpYmxlIHRoYXQgc29tZSB2ZXJzaW9ucyBvZiBJbmNyZW1lbnRhbFNBWFNvdXJjZSBtYXkKLSAgICAvLyBub3QgYWN0dWFsbHkgdXNlIGEgQ29yb3V0aW5lTWFuYWdlciwgYW5kIGhlbmNlIG1heSBub3QgcmVxdWlyZQotICAgIC8vIHRoYXQgd2Ugb2J0YWluIGFuIEFwcGxpY2F0aW9uIENvcm91dGluZSBJRC4gKFRoaXMgcmVsaWVzIG9uIHRoZQotICAgIC8vIGNvcm91dGluZSB0cmFuc2FjdGlvbiBkZXRhaWxzIGhhdmluZyBiZWVuIGVuY2Fwc3VsYXRlZCBpbiB0aGUKLSAgICAvLyBJbmNyZW1lbnRhbFNBWFNvdXJjZS5kby4uLigpIG1ldGhvZHMuKQotICAgIG1faW5jcmVtZW50YWxTQVhTb3VyY2UgPSBpbmNyZW1lbnRhbFNBWFNvdXJjZTsKLQotICAgIC8vIEVzdGFibGlzaCBTQVgtc3RyZWFtIGxpbmsgc28gd2UgY2FuIHJlY2VpdmUgdGhlIHJlcXVlc3RlZCBkYXRhCi0gICAgaW5jcmVtZW50YWxTQVhTb3VyY2Uuc2V0Q29udGVudEhhbmRsZXIodGhpcyk7Ci0gICAgaW5jcmVtZW50YWxTQVhTb3VyY2Uuc2V0TGV4aWNhbEhhbmRsZXIodGhpcyk7Ci0gICAgaW5jcmVtZW50YWxTQVhTb3VyY2Uuc2V0RFRESGFuZGxlcih0aGlzKTsKLQotICAgIC8vIEFyZSB0aGUgZm9sbG93aW5nIHJlYWxseSBuZWVkZWQ/IGluY3JlbWVudGFsU0FYU291cmNlIGRvZXNuJ3QgeWV0Ci0gICAgLy8gc3VwcG9ydCB0aGVtLCBhbmQgdGhleSdyZSBtb3N0bHkgbm8tb3BzIGhlcmUuLi4KLSAgICAvL2luY3JlbWVudGFsU0FYU291cmNlLnNldEVycm9ySGFuZGxlcih0aGlzKTsKLSAgICAvL2luY3JlbWVudGFsU0FYU291cmNlLnNldERlY2xIYW5kbGVyKHRoaXMpOwotICB9Ci0KLSAgLyoqCi0gICAqIGdldENvbnRlbnRIYW5kbGVyIHJldHVybnMgIm91ciBTQVggYnVpbGRlciIgLS0gdGhlIHRoaW5nIHRoYXQKLSAgICogc29tZW9uZSBlbHNlIHNob3VsZCBzZW5kIFNBWCBldmVudHMgdG8gaW4gb3JkZXIgdG8gZXh0ZW5kIHRoaXMKLSAgICogRFRNIG1vZGVsLgotICAgKgotICAgKiAlUkVWSUVXJSBTaG91bGQgdGhpcyByZXR1cm4gbnVsbCBpZiBjb25zdHJ1dGlvbiBhbHJlYWR5IGRvbmUvYmVndW4/Ci0gICAqCi0gICAqIEByZXR1cm4gbnVsbCBpZiB0aGlzIG1vZGVsIGRvZXNuJ3QgcmVzcG9uZCB0byBTQVggZXZlbnRzLAotICAgKiAidGhpcyIgaWYgdGhlIERUTSBvYmplY3QgaGFzIGEgYnVpbHQtaW4gU0FYIENvbnRlbnRIYW5kbGVyLAotICAgKiB0aGUgSW5jcmVtZW50YWxTQVhTb3VyY2UgaWYgd2UncmUgYm91bmQgdG8gb25lIGFuZCBzaG91bGQgcmVjZWl2ZQotICAgKiB0aGUgU0FYIHN0cmVhbSB2aWEgaXQgZm9yIGluY3JlbWVudGFsIGJ1aWxkIHB1cnBvc2VzLi4uCi0gICAqCi0gICAqIE5vdGUgdGhhdCBJbmNyZW1lbnRhbFNBWFNvdXJjZV9GaWx0ZXIgaXMgcGFja2FnZSBwcml2YXRlLCBoZW5jZQotICAgKiBpdCBjYW4gYmUgc3RhdGljYWxseSByZWZlcmVuY2VkIHVzaW5nIGluc3RhbmNlb2YgKENSIDY1Mzc5MTIpLgotICAgKi8KLSAgcHVibGljIENvbnRlbnRIYW5kbGVyIGdldENvbnRlbnRIYW5kbGVyKCkKLSAgewotCi0gICAgaWYgKG1faW5jcmVtZW50YWxTQVhTb3VyY2UuZ2V0Q2xhc3MoKQotICAgICAgICAuZ2V0TmFtZSgpLmVxdWFscygiY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0ucmVmLkluY3JlbWVudGFsU0FYU291cmNlX0ZpbHRlciIpKQotICAgICAgcmV0dXJuIChDb250ZW50SGFuZGxlcikgbV9pbmNyZW1lbnRhbFNBWFNvdXJjZTsKLSAgICBlbHNlCi0gICAgICByZXR1cm4gdGhpczsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhpcyBEVE0ncyBsZXhpY2FsIGhhbmRsZXIuCi0gICAqCi0gICAqICVSRVZJRVclIFNob3VsZCB0aGlzIHJldHVybiBudWxsIGlmIGNvbnN0cnV0aW9uIGFscmVhZHkgZG9uZS9iZWd1bj8KLSAgICoKLSAgICogQHJldHVybiBudWxsIGlmIHRoaXMgbW9kZWwgZG9lc24ndCByZXNwb25kIHRvIGxleGljYWwgU0FYIGV2ZW50cywKLSAgICogInRoaXMiIGlmIHRoZSBEVE0gb2JqZWN0IGhhcyBhIGJ1aWx0LWluIFNBWCBDb250ZW50SGFuZGxlciwKLSAgICogdGhlIEluY3JlbWVudGFsU0FYU291cmNlIGlmIHdlJ3JlIGJvdW5kIHRvIG9uZSBhbmQgc2hvdWxkIHJlY2VpdmUKLSAgICogdGhlIFNBWCBzdHJlYW0gdmlhIGl0IGZvciBpbmNyZW1lbnRhbCBidWlsZCBwdXJwb3Nlcy4uLgotICAgKgotICAgKiBOb3RlIHRoYXQgSW5jcmVtZW50YWxTQVhTb3VyY2VfRmlsdGVyIGlzIHBhY2thZ2UgcHJpdmF0ZSwgaGVuY2UKLSAgICogaXQgY2FuIGJlIHN0YXRpY2FsbHkgcmVmZXJlbmNlZCB1c2luZyBpbnN0YW5jZW9mIChDUiA2NTM3OTEyKS4KLSAgICovCi0gIHB1YmxpYyBMZXhpY2FsSGFuZGxlciBnZXRMZXhpY2FsSGFuZGxlcigpCi0gIHsKLQotICAgIGlmIChtX2luY3JlbWVudGFsU0FYU291cmNlLmdldENsYXNzKCkKLSAgICAgICAgLmdldE5hbWUoKS5lcXVhbHMoImNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLnJlZi5JbmNyZW1lbnRhbFNBWFNvdXJjZV9GaWx0ZXIiKSkKLSAgICAgIHJldHVybiAoTGV4aWNhbEhhbmRsZXIpIG1faW5jcmVtZW50YWxTQVhTb3VyY2U7Ci0gICAgZWxzZQotICAgICAgcmV0dXJuIHRoaXM7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoaXMgRFRNJ3MgRW50aXR5UmVzb2x2ZXIuCi0gICAqCi0gICAqIEByZXR1cm4gbnVsbCBpZiB0aGlzIG1vZGVsIGRvZXNuJ3QgcmVzcG9uZCB0byBTQVggZW50aXR5IHJlZiBldmVudHMuCi0gICAqLwotICBwdWJsaWMgRW50aXR5UmVzb2x2ZXIgZ2V0RW50aXR5UmVzb2x2ZXIoKQotICB7Ci0gICAgcmV0dXJuIHRoaXM7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoaXMgRFRNJ3MgRFRESGFuZGxlci4KLSAgICoKLSAgICogQHJldHVybiBudWxsIGlmIHRoaXMgbW9kZWwgZG9lc24ndCByZXNwb25kIHRvIFNBWCBkdGQgZXZlbnRzLgotICAgKi8KLSAgcHVibGljIERUREhhbmRsZXIgZ2V0RFRESGFuZGxlcigpCi0gIHsKLSAgICByZXR1cm4gdGhpczsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhpcyBEVE0ncyBFcnJvckhhbmRsZXIuCi0gICAqCi0gICAqIEByZXR1cm4gbnVsbCBpZiB0aGlzIG1vZGVsIGRvZXNuJ3QgcmVzcG9uZCB0byBTQVggZXJyb3IgZXZlbnRzLgotICAgKi8KLSAgcHVibGljIEVycm9ySGFuZGxlciBnZXRFcnJvckhhbmRsZXIoKQotICB7Ci0gICAgcmV0dXJuIHRoaXM7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoaXMgRFRNJ3MgRGVjbEhhbmRsZXIuCi0gICAqCi0gICAqIEByZXR1cm4gbnVsbCBpZiB0aGlzIG1vZGVsIGRvZXNuJ3QgcmVzcG9uZCB0byBTQVggRGVjbCBldmVudHMuCi0gICAqLwotICBwdWJsaWMgRGVjbEhhbmRsZXIgZ2V0RGVjbEhhbmRsZXIoKQotICB7Ci0gICAgcmV0dXJuIHRoaXM7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiB0cnVlIGlmZiB3ZSdyZSBidWlsZGluZyB0aGlzIG1vZGVsIGluY3JlbWVudGFsbHkgKGVnCi0gICAqIHdlJ3JlIHBhcnRuZXJlZCB3aXRoIGEgSW5jcmVtZW50YWxTQVhTb3VyY2UpIGFuZCB0aHVzIHJlcXVpcmUgdGhhdCB0aGUKLSAgICogdHJhbnNmb3JtYXRpb24gYW5kIHRoZSBwYXJzZSBydW4gc2ltdWx0YW5lb3VzbHkuIEd1aWRhbmNlIHRvIHRoZQotICAgKiBEVE1NYW5hZ2VyLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gbmVlZHNUd29UaHJlYWRzKCkKLSAgewotICAgIHJldHVybiBudWxsICE9IG1faW5jcmVtZW50YWxTQVhTb3VyY2U7Ci0gIH0KLQotICAvKioKLSAgICogRGlyZWN0bHkgY2FsbCB0aGUKLSAgICogY2hhcmFjdGVycyBtZXRob2Qgb24gdGhlIHBhc3NlZCBDb250ZW50SGFuZGxlciBmb3IgdGhlCi0gICAqIHN0cmluZy12YWx1ZSBvZiB0aGUgZ2l2ZW4gbm9kZSAoc2VlIGh0dHA6Ly93d3cudzMub3JnL1RSL3hwYXRoI2RhdGEtbW9kZWwKLSAgICogZm9yIHRoZSBkZWZpbml0aW9uIG9mIGEgbm9kZSdzIHN0cmluZy12YWx1ZSkuIE11bHRpcGxlIGNhbGxzIHRvIHRoZQotICAgKiBDb250ZW50SGFuZGxlcidzIGNoYXJhY3RlcnMgbWV0aG9kcyBtYXkgd2VsbCBvY2N1ciBmb3IgYSBzaW5nbGUgY2FsbCB0bwotICAgKiB0aGlzIG1ldGhvZC4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgVGhlIG5vZGUgSUQuCi0gICAqIEBwYXJhbSBjaCBBIG5vbi1udWxsIHJlZmVyZW5jZSB0byBhIENvbnRlbnRIYW5kbGVyLgotICAgKiBAcGFyYW0gbm9ybWFsaXplIHRydWUgaWYgdGhlIGNvbnRlbnQgc2hvdWxkIGJlIG5vcm1hbGl6ZWQgYWNjb3JkaW5nIHRvCi0gICAqIHRoZSBydWxlcyBmb3IgdGhlIFhQYXRoCi0gICAqIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hwYXRoI2Z1bmN0aW9uLW5vcm1hbGl6ZS1zcGFjZSI+bm9ybWFsaXplLXNwYWNlPC9hPgotICAgKiBmdW5jdGlvbi4KLSAgICoKLSAgICogQHRocm93cyBTQVhFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGRpc3BhdGNoQ2hhcmFjdGVyc0V2ZW50cyhpbnQgbm9kZUhhbmRsZSwgQ29udGVudEhhbmRsZXIgY2gsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIG5vcm1hbGl6ZSkKLSAgICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIGludCBpZGVudGl0eSA9IG1ha2VOb2RlSWRlbnRpdHkobm9kZUhhbmRsZSk7Ci0KLSAgICBpZiAoaWRlbnRpdHkgPT0gRFRNLk5VTEwpCi0gICAgICByZXR1cm47Ci0KLSAgICBpbnQgdHlwZSA9IF90eXBlKGlkZW50aXR5KTsKLQotICAgIGlmIChpc1RleHRUeXBlKHR5cGUpKQotICAgIHsKLSAgICAgIGludCBkYXRhSW5kZXggPSBtX2RhdGFPclFOYW1lLmVsZW1lbnRBdChpZGVudGl0eSk7Ci0gICAgICBpbnQgb2Zmc2V0ID0gbV9kYXRhLmVsZW1lbnRBdChkYXRhSW5kZXgpOwotICAgICAgaW50IGxlbmd0aCA9IG1fZGF0YS5lbGVtZW50QXQoZGF0YUluZGV4ICsgMSk7Ci0KLSAgICAgIGlmKG5vcm1hbGl6ZSkKLSAgICAgICAgbV9jaGFycy5zZW5kTm9ybWFsaXplZFNBWGNoYXJhY3RlcnMoY2gsIG9mZnNldCwgbGVuZ3RoKTsKLSAgICAgIGVsc2UKLSAgICAgICAgbV9jaGFycy5zZW5kU0FYY2hhcmFjdGVycyhjaCwgb2Zmc2V0LCBsZW5ndGgpOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgaW50IGZpcnN0Q2hpbGQgPSBfZmlyc3RjaChpZGVudGl0eSk7Ci0KLSAgICAgIGlmIChEVE0uTlVMTCAhPSBmaXJzdENoaWxkKQotICAgICAgewotICAgICAgICBpbnQgb2Zmc2V0ID0gLTE7Ci0gICAgICAgIGludCBsZW5ndGggPSAwOwotICAgICAgICBpbnQgc3RhcnROb2RlID0gaWRlbnRpdHk7Ci0KLSAgICAgICAgaWRlbnRpdHkgPSBmaXJzdENoaWxkOwotCi0gICAgICAgIGRvIHsKLSAgICAgICAgICB0eXBlID0gX3R5cGUoaWRlbnRpdHkpOwotCi0gICAgICAgICAgaWYgKGlzVGV4dFR5cGUodHlwZSkpCi0gICAgICAgICAgewotICAgICAgICAgICAgaW50IGRhdGFJbmRleCA9IF9kYXRhT3JRTmFtZShpZGVudGl0eSk7Ci0KLSAgICAgICAgICAgIGlmICgtMSA9PSBvZmZzZXQpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIG9mZnNldCA9IG1fZGF0YS5lbGVtZW50QXQoZGF0YUluZGV4KTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgbGVuZ3RoICs9IG1fZGF0YS5lbGVtZW50QXQoZGF0YUluZGV4ICsgMSk7Ci0gICAgICAgICAgfQotCi0gICAgICAgICAgaWRlbnRpdHkgPSBnZXROZXh0Tm9kZUlkZW50aXR5KGlkZW50aXR5KTsKLSAgICAgICAgfSB3aGlsZSAoRFRNLk5VTEwgIT0gaWRlbnRpdHkgJiYgKF9wYXJlbnQoaWRlbnRpdHkpID49IHN0YXJ0Tm9kZSkpOwotCi0gICAgICAgIGlmIChsZW5ndGggPiAwKQotICAgICAgICB7Ci0gICAgICAgICAgaWYobm9ybWFsaXplKQotICAgICAgICAgICAgbV9jaGFycy5zZW5kTm9ybWFsaXplZFNBWGNoYXJhY3RlcnMoY2gsIG9mZnNldCwgbGVuZ3RoKTsKLSAgICAgICAgICBlbHNlCi0gICAgICAgICAgICBtX2NoYXJzLnNlbmRTQVhjaGFyYWN0ZXJzKGNoLCBvZmZzZXQsIGxlbmd0aCk7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICAgIGVsc2UgaWYodHlwZSAhPSBEVE0uRUxFTUVOVF9OT0RFKQotICAgICAgewotICAgICAgICBpbnQgZGF0YUluZGV4ID0gX2RhdGFPclFOYW1lKGlkZW50aXR5KTsKLQotICAgICAgICBpZiAoZGF0YUluZGV4IDwgMCkKLSAgICAgICAgewotICAgICAgICAgIGRhdGFJbmRleCA9IC1kYXRhSW5kZXg7Ci0gICAgICAgICAgZGF0YUluZGV4ID0gbV9kYXRhLmVsZW1lbnRBdChkYXRhSW5kZXggKyAxKTsKLSAgICAgICAgfQotCi0gICAgICAgIFN0cmluZyBzdHIgPSBtX3ZhbHVlc09yUHJlZml4ZXMuaW5kZXhUb1N0cmluZyhkYXRhSW5kZXgpOwotCi0gICAgICAgICAgaWYobm9ybWFsaXplKQotICAgICAgICAgICAgRmFzdFN0cmluZ0J1ZmZlci5zZW5kTm9ybWFsaXplZFNBWGNoYXJhY3RlcnMoc3RyLnRvQ2hhckFycmF5KCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCBzdHIubGVuZ3RoKCksIGNoKTsKLSAgICAgICAgICBlbHNlCi0gICAgICAgICAgICBjaC5jaGFyYWN0ZXJzKHN0ci50b0NoYXJBcnJheSgpLCAwLCBzdHIubGVuZ3RoKCkpOwotICAgICAgfQotICAgIH0KLSAgfQotCi0KLSAgLyoqCi0gICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIHJldHVybiBpdHMgRE9NLXN0eWxlIG5vZGUgbmFtZS4gVGhpcyB3aWxsCi0gICAqIGluY2x1ZGUgbmFtZXMgc3VjaCBhcyAjdGV4dCBvciAjZG9jdW1lbnQuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIHRoZSBpZCBvZiB0aGUgbm9kZS4KLSAgICogQHJldHVybiBTdHJpbmcgTmFtZSBvZiB0aGlzIG5vZGUsIHdoaWNoIG1heSBiZSBhbiBlbXB0eSBzdHJpbmcuCi0gICAqICVSRVZJRVclIERvY3VtZW50IHdoZW4gZW1wdHkgc3RyaW5nIGlzIHBvc3NpYmxlLi4uCi0gICAqICVSRVZJRVctQ09NTUVOVCUgSXQgc2hvdWxkIG5ldmVyIGJlIGVtcHR5LCBzaG91bGQgaXQ/Ci0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldE5vZGVOYW1lKGludCBub2RlSGFuZGxlKQotICB7Ci0KLSAgICBpbnQgZXhwYW5kZWRUeXBlSUQgPSBnZXRFeHBhbmRlZFR5cGVJRChub2RlSGFuZGxlKTsKLSAgICAvLyBJZiBqdXN0IHRlc3Rpbmcgbm9uemVybywgbm8gbmVlZCB0byBzaGlmdC4uLgotICAgIGludCBuYW1lc3BhY2VJRCA9IG1fZXhwYW5kZWROYW1lVGFibGUuZ2V0TmFtZXNwYWNlSUQoZXhwYW5kZWRUeXBlSUQpOwotCi0gICAgaWYgKDAgPT0gbmFtZXNwYWNlSUQpCi0gICAgewotICAgICAgLy8gRG9uJ3QgcmV0cmlldmUgbmFtZSB1bnRpbC91bmxlc3MgbmVlZGVkCi0gICAgICAvLyBTdHJpbmcgbmFtZSA9IG1fZXhwYW5kZWROYW1lVGFibGUuZ2V0TG9jYWxOYW1lKGV4cGFuZGVkVHlwZUlEKTsKLSAgICAgIGludCB0eXBlID0gZ2V0Tm9kZVR5cGUobm9kZUhhbmRsZSk7Ci0KLSAgICAgIGlmICh0eXBlID09IERUTS5OQU1FU1BBQ0VfTk9ERSkKLSAgICAgIHsKLSAgICAgICAgaWYgKG51bGwgPT0gbV9leHBhbmRlZE5hbWVUYWJsZS5nZXRMb2NhbE5hbWUoZXhwYW5kZWRUeXBlSUQpKQotICAgICAgICAgIHJldHVybiAieG1sbnMiOwotICAgICAgICBlbHNlCi0gICAgICAgICAgcmV0dXJuICJ4bWxuczoiICsgbV9leHBhbmRlZE5hbWVUYWJsZS5nZXRMb2NhbE5hbWUoZXhwYW5kZWRUeXBlSUQpOwotICAgICAgfQotICAgICAgZWxzZSBpZiAoMCA9PSBtX2V4cGFuZGVkTmFtZVRhYmxlLmdldExvY2FsTmFtZUlEKGV4cGFuZGVkVHlwZUlEKSkKLSAgICAgIHsKLSAgICAgICAgcmV0dXJuIG1fZml4ZWRuYW1lc1t0eXBlXTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgICAgcmV0dXJuIG1fZXhwYW5kZWROYW1lVGFibGUuZ2V0TG9jYWxOYW1lKGV4cGFuZGVkVHlwZUlEKTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIGludCBxbmFtZUluZGV4ID0gbV9kYXRhT3JRTmFtZS5lbGVtZW50QXQobWFrZU5vZGVJZGVudGl0eShub2RlSGFuZGxlKSk7Ci0KLSAgICAgIGlmIChxbmFtZUluZGV4IDwgMCkKLSAgICAgIHsKLSAgICAgICAgcW5hbWVJbmRleCA9IC1xbmFtZUluZGV4OwotICAgICAgICBxbmFtZUluZGV4ID0gbV9kYXRhLmVsZW1lbnRBdChxbmFtZUluZGV4KTsKLSAgICAgIH0KLQotICAgICAgcmV0dXJuIG1fdmFsdWVzT3JQcmVmaXhlcy5pbmRleFRvU3RyaW5nKHFuYW1lSW5kZXgpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBHaXZlbiBhIG5vZGUgaGFuZGxlLCByZXR1cm4gdGhlIFhQYXRoIG5vZGUgbmFtZS4gIFRoaXMgc2hvdWxkIGJlCi0gICAqIHRoZSBuYW1lIGFzIGRlc2NyaWJlZCBieSB0aGUgWFBhdGggZGF0YSBtb2RlbCwgTk9UIHRoZSBET00tc3R5bGUKLSAgICogbmFtZS4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgdGhlIGlkIG9mIHRoZSBub2RlLgotICAgKiBAcmV0dXJuIFN0cmluZyBOYW1lIG9mIHRoaXMgbm9kZSwgd2hpY2ggbWF5IGJlIGFuIGVtcHR5IHN0cmluZy4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0Tm9kZU5hbWVYKGludCBub2RlSGFuZGxlKQotICB7Ci0KLSAgICBpbnQgZXhwYW5kZWRUeXBlSUQgPSBnZXRFeHBhbmRlZFR5cGVJRChub2RlSGFuZGxlKTsKLSAgICBpbnQgbmFtZXNwYWNlSUQgPSBtX2V4cGFuZGVkTmFtZVRhYmxlLmdldE5hbWVzcGFjZUlEKGV4cGFuZGVkVHlwZUlEKTsKLQotICAgIGlmICgwID09IG5hbWVzcGFjZUlEKQotICAgIHsKLSAgICAgIFN0cmluZyBuYW1lID0gbV9leHBhbmRlZE5hbWVUYWJsZS5nZXRMb2NhbE5hbWUoZXhwYW5kZWRUeXBlSUQpOwotCi0gICAgICBpZiAobmFtZSA9PSBudWxsKQotICAgICAgICByZXR1cm4gIiI7Ci0gICAgICBlbHNlCi0gICAgICAgIHJldHVybiBuYW1lOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgaW50IHFuYW1lSW5kZXggPSBtX2RhdGFPclFOYW1lLmVsZW1lbnRBdChtYWtlTm9kZUlkZW50aXR5KG5vZGVIYW5kbGUpKTsKLQotICAgICAgaWYgKHFuYW1lSW5kZXggPCAwKQotICAgICAgewotICAgICAgICBxbmFtZUluZGV4ID0gLXFuYW1lSW5kZXg7Ci0gICAgICAgIHFuYW1lSW5kZXggPSBtX2RhdGEuZWxlbWVudEF0KHFuYW1lSW5kZXgpOwotICAgICAgfQotCi0gICAgICByZXR1cm4gbV92YWx1ZXNPclByZWZpeGVzLmluZGV4VG9TdHJpbmcocW5hbWVJbmRleCk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqICAgICA1LiBbc3BlY2lmaWVkXSBBIGZsYWcgaW5kaWNhdGluZyB3aGV0aGVyIHRoaXMgYXR0cmlidXRlIHdhcyBhY3R1YWxseQotICAgKiAgICAgICAgc3BlY2lmaWVkIGluIHRoZSBzdGFydC10YWcgb2YgaXRzIGVsZW1lbnQsIG9yIHdhcyBkZWZhdWx0ZWQgZnJvbSB0aGUKLSAgICogICAgICAgIERURC4KLSAgICoKLSAgICogQHBhcmFtIGF0dHJpYnV0ZUhhbmRsZSBNdXN0IGJlIGEgdmFsaWQgaGFuZGxlIHRvIGFuIGF0dHJpYnV0ZSBub2RlLgotICAgKiBAcmV0dXJuIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBhdHRyaWJ1dGUgd2FzIHNwZWNpZmllZDsKLSAgICogICAgICAgICA8Y29kZT5mYWxzZTwvY29kZT4gaWYgaXQgd2FzIGRlZmF1bHRlZC4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzQXR0cmlidXRlU3BlY2lmaWVkKGludCBhdHRyaWJ1dGVIYW5kbGUpCi0gIHsKLQotICAgIC8vIEknbSBub3Qgc3VyZSBpZiBJIHdhbnQgdG8gZG8gYW55dGhpbmcgd2l0aCB0aGlzLi4uCi0gICAgcmV0dXJuIHRydWU7ICAvLyA/PwotICB9Ci0KLSAgLyoqCi0gICAqICAgQSBkb2N1bWVudCB0eXBlIGRlY2xhcmF0aW9uIGluZm9ybWF0aW9uIGl0ZW0gaGFzIHRoZSBmb2xsb3dpbmcgcHJvcGVydGllczoKLSAgICoKLSAgICogICAgIDEuIFtzeXN0ZW0gaWRlbnRpZmllcl0gVGhlIHN5c3RlbSBpZGVudGlmaWVyIG9mIHRoZSBleHRlcm5hbCBzdWJzZXQsIGlmCi0gICAqICAgICAgICBpdCBleGlzdHMuIE90aGVyd2lzZSB0aGlzIHByb3BlcnR5IGhhcyBubyB2YWx1ZS4KLSAgICoKLSAgICogQHJldHVybiB0aGUgc3lzdGVtIGlkZW50aWZpZXIgU3RyaW5nIG9iamVjdCwgb3IgbnVsbCBpZiB0aGVyZSBpcyBub25lLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXREb2N1bWVudFR5cGVEZWNsYXJhdGlvblN5c3RlbUlkZW50aWZpZXIoKQotICB7Ci0KLSAgICAvKiogQHRvZG86IGltcGxlbWVudCB0aGlzIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTURlZmF1bHRCYXNlIGFic3RyYWN0IG1ldGhvZCAqLwotICAgIGVycm9yKFhNTE1lc3NhZ2VzLmNyZWF0ZVhNTE1lc3NhZ2UoWE1MRXJyb3JSZXNvdXJjZXMuRVJfTUVUSE9EX05PVF9TVVBQT1JURUQsIG51bGwpKTsvLyJOb3QgeWV0IHN1cHBvcnRlZCEiKTsKLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbmV4dCBub2RlIGlkZW50aXR5IHZhbHVlIGluIHRoZSBsaXN0LCBhbmQgY2FsbCB0aGUgaXRlcmF0b3IKLSAgICogaWYgaXQgaGFzbid0IGJlZW4gYWRkZWQgeWV0LgotICAgKgotICAgKiBAcGFyYW0gaWRlbnRpdHkgVGhlIG5vZGUgaWRlbnRpdHkgKGluZGV4KS4KLSAgICogQHJldHVybiBpZGVudGl0eSsxLCBvciBEVE0uTlVMTC4KLSAgICovCi0gIHByb3RlY3RlZCBpbnQgZ2V0TmV4dE5vZGVJZGVudGl0eShpbnQgaWRlbnRpdHkpCi0gIHsKLQotICAgIGlkZW50aXR5ICs9IDE7Ci0KLSAgICB3aGlsZSAoaWRlbnRpdHkgPj0gbV9zaXplKQotICAgIHsKLSAgICAgIGlmIChudWxsID09IG1faW5jcmVtZW50YWxTQVhTb3VyY2UpCi0gICAgICAgIHJldHVybiBEVE0uTlVMTDsKLQotICAgICAgbmV4dE5vZGUoKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gaWRlbnRpdHk7Ci0gIH0KLQotICAvKioKLSAgICogRGlyZWN0bHkgY3JlYXRlIFNBWCBwYXJzZXIgZXZlbnRzIGZyb20gYSBzdWJ0cmVlLgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBUaGUgbm9kZSBJRC4KLSAgICogQHBhcmFtIGNoIEEgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGEgQ29udGVudEhhbmRsZXIuCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBkaXNwYXRjaFRvRXZlbnRzKGludCBub2RlSGFuZGxlLCBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciBjaCkKLSAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIERUTVRyZWVXYWxrZXIgdHJlZVdhbGtlciA9IG1fd2Fsa2VyOwotICAgIENvbnRlbnRIYW5kbGVyIHByZXZDSCA9IHRyZWVXYWxrZXIuZ2V0Y29udGVudEhhbmRsZXIoKTsKLQotICAgIGlmIChudWxsICE9IHByZXZDSCkKLSAgICB7Ci0gICAgICB0cmVlV2Fsa2VyID0gbmV3IERUTVRyZWVXYWxrZXIoKTsKLSAgICB9Ci0KLSAgICB0cmVlV2Fsa2VyLnNldGNvbnRlbnRIYW5kbGVyKGNoKTsKLSAgICB0cmVlV2Fsa2VyLnNldERUTSh0aGlzKTsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIHRyZWVXYWxrZXIudHJhdmVyc2Uobm9kZUhhbmRsZSk7Ci0gICAgfQotICAgIGZpbmFsbHkKLSAgICB7Ci0gICAgICB0cmVlV2Fsa2VyLnNldGNvbnRlbnRIYW5kbGVyKG51bGwpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIG51bWJlciBvZiBub2RlcyB0aGF0IGhhdmUgYmVlbiBhZGRlZC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgbnVtYmVyIG9mIHRoYXQgYXJlIGN1cnJlbnRseSBpbiB0aGUgdHJlZS4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0TnVtYmVyT2ZOb2RlcygpCi0gIHsKLSAgICByZXR1cm4gbV9zaXplOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoaXMgbWV0aG9kIHNob3VsZCB0cnkgYW5kIGJ1aWxkIG9uZSBvciBtb3JlIG5vZGVzIGluIHRoZSB0YWJsZS4KLSAgICoKLSAgICogQHJldHVybiBUaGUgdHJ1ZSBpZiBhIG5leHQgbm9kZSBpcyBmb3VuZCBvciBmYWxzZSBpZgotICAgKiAgICAgICAgIHRoZXJlIGFyZSBubyBtb3JlIG5vZGVzLgotICAgKi8KLSAgcHJvdGVjdGVkIGJvb2xlYW4gbmV4dE5vZGUoKQotICB7Ci0KLSAgICBpZiAobnVsbCA9PSBtX2luY3JlbWVudGFsU0FYU291cmNlKQotICAgICAgcmV0dXJuIGZhbHNlOwotCi0gICAgaWYgKG1fZW5kRG9jdW1lbnRPY2N1cmVkKQotICAgIHsKLSAgICAgIGNsZWFyQ29Sb3V0aW5lKCk7Ci0KLSAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICBPYmplY3QgZ290TW9yZSA9IG1faW5jcmVtZW50YWxTQVhTb3VyY2UuZGVsaXZlck1vcmVOb2Rlcyh0cnVlKTsKLQotICAgIC8vIGdvdE1vcmUgbWF5IGJlIGEgQm9vbGVhbiAoVFJVRSBpZiBzdGlsbCBwYXJzaW5nLCBGQUxTRSBpZgotICAgIC8vIEVPRikgb3IgYW4gZXhjZXB0aW9uIGlmIEluY3JlbWVudGFsU0FYU291cmNlIG1hbGZ1bmN0aW9uZWQKLSAgICAvLyAoY29kZSBlcnJvciByYXRoZXIgdGhhbiB1c2VyIGVycm9yKS4KLSAgICAvLwotICAgIC8vICVSRVZJRVclIEN1cnJlbnRseSB0aGUgRXJyb3JIYW5kbGVycyBza2V0Y2hlZCBoZXJlaW4gYXJlCi0gICAgLy8gbm8tb3BzLCBzbyBJJ20gZ29pbmcgdG8gaW5pdGlhbGx5IGxlYXZlIHRoaXMgYWxzbyBhcyBhCi0gICAgLy8gbm8tb3AuCi0gICAgaWYgKCEoZ290TW9yZSBpbnN0YW5jZW9mIEJvb2xlYW4pKQotICAgIHsKLSAgICAgIGlmKGdvdE1vcmUgaW5zdGFuY2VvZiBSdW50aW1lRXhjZXB0aW9uKQotICAgICAgewotICAgICAgICB0aHJvdyAoUnVudGltZUV4Y2VwdGlvbilnb3RNb3JlOwotICAgICAgfQotICAgICAgZWxzZSBpZihnb3RNb3JlIGluc3RhbmNlb2YgRXhjZXB0aW9uKQotICAgICAgewotICAgICAgICB0aHJvdyBuZXcgV3JhcHBlZFJ1bnRpbWVFeGNlcHRpb24oKEV4Y2VwdGlvbilnb3RNb3JlKTsKLSAgICAgIH0KLSAgICAgIC8vIGZvciBub3cuLi4KLSAgICAgIGNsZWFyQ29Sb3V0aW5lKCk7Ci0KLSAgICAgIHJldHVybiBmYWxzZTsKLQotICAgICAgLy8gJVRCRCUKLSAgICB9Ci0KLSAgICBpZiAoZ290TW9yZSAhPSBCb29sZWFuLlRSVUUpCi0gICAgewotCi0gICAgICAvLyBFT0YgcmVhY2hlZCB3aXRob3V0IHNhdGlzZnlpbmcgdGhlIHJlcXVlc3QKLSAgICAgIGNsZWFyQ29Sb3V0aW5lKCk7ICAvLyBEcm9wIGNvbm5lY3Rpb24sIHN0b3AgdHJ5aW5nCi0KLSAgICAgIC8vICVUQkQlIGRlcmVnaXN0ZXIgYXMgaXRzIGxpc3RlbmVyPwotICAgIH0KLQotICAgIHJldHVybiB0cnVlOwotICB9Ci0KLSAgLyoqCi0gICAqIEJvdHRsZW5lY2sgZGV0ZXJtaW5hdGlvbiBvZiB0ZXh0IHR5cGUuCi0gICAqCi0gICAqIEBwYXJhbSB0eXBlIG9uZW9mIERUTS5YWFhfTk9ERS4KLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHRoaXMgaXMgYSB0ZXh0IG9yIGNkYXRhIHNlY3Rpb24uCi0gICAqLwotICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gaXNUZXh0VHlwZShpbnQgdHlwZSkKLSAgewotICAgIHJldHVybiAoRFRNLlRFWFRfTk9ERSA9PSB0eXBlIHx8IERUTS5DREFUQV9TRUNUSU9OX05PREUgPT0gdHlwZSk7Ci0gIH0KLQotLy8gICAgLyoqCi0vLyAgICAgKiBFbnN1cmUgdGhhdCB0aGUgc2l6ZSBvZiB0aGUgaW5mb3JtYXRpb24gYXJyYXlzIGNhbiBob2xkIGFub3RoZXIgZW50cnkKLS8vICAgICAqIGF0IHRoZSBnaXZlbiBpbmRleC4KLS8vICAgICAqCi0vLyAgICAgKiBAcGFyYW0gb24gZXhpdCBmcm9tIHRoaXMgZnVuY3Rpb24sIHRoZSBpbmZvcm1hdGlvbiBhcnJheXMgc2l6ZXMgbXVzdCBiZQotLy8gICAgICogYXQgbGVhc3QgaW5kZXgrMS4KLS8vICAgICAqCi0vLyAgICAgKiBORUVEU0RPQyBAcGFyYW0gaW5kZXgKLS8vICAgICAqLwotLy8gICAgcHJvdGVjdGVkIHZvaWQgZW5zdXJlU2l6ZShpbnQgaW5kZXgpCi0vLyAgICB7Ci0vLyAgICAgICAgICAvLyBkYXRhT3JRTmFtZSBpcyBhbiBTdWJhbGxvY2F0ZWRJbnRWZWN0b3IgYW5kIGhlbmNlIHNlbGYtc2l6aW5nLgotLy8gICAgICAgICAgLy8gQnV0IERUTURlZmF1bHRCYXNlIG1heSBuZWVkIGZpeHVwLgotLy8gICAgICAgIHN1cGVyLmVuc3VyZVNpemUoaW5kZXgpOwotLy8gICAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgdGhlIG5vZGUgbWFwIGZyb20gdGhlIG5vZGUuCi0gICAqCi0gICAqIEBwYXJhbSB0eXBlIHJhdyB0eXBlIElELCBvbmUgb2YgRFRNLlhYWF9OT0RFLgotICAgKiBAcGFyYW0gZXhwYW5kZWRUeXBlSUQgVGhlIGV4cGVuZGVkIHR5cGUgSUQuCi0gICAqIEBwYXJhbSBwYXJlbnRJbmRleCBUaGUgY3VycmVudCBwYXJlbnQgaW5kZXguCi0gICAqIEBwYXJhbSBwcmV2aW91c1NpYmxpbmcgVGhlIHByZXZpb3VzIHNpYmxpbmcgaW5kZXguCi0gICAqIEBwYXJhbSBkYXRhT3JQcmVmaXggaW5kZXggaW50byBtX2RhdGEgdGFibGUsIG9yIHN0cmluZyBoYW5kbGUuCi0gICAqIEBwYXJhbSBjYW5IYXZlRmlyc3RDaGlsZCB0cnVlIGlmIHRoZSBub2RlIGNhbiBoYXZlIGEgZmlyc3QgY2hpbGQsIGZhbHNlCi0gICAqICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBpdCBpcyBhdG9taWMuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGluZGV4IGlkZW50aXR5IG9mIHRoZSBub2RlIHRoYXQgd2FzIGFkZGVkLgotICAgKi8KLSAgcHJvdGVjdGVkIGludCBhZGROb2RlKGludCB0eXBlLCBpbnQgZXhwYW5kZWRUeXBlSUQsCi0gICAgICAgICAgICAgICAgICAgICAgICBpbnQgcGFyZW50SW5kZXgsIGludCBwcmV2aW91c1NpYmxpbmcsCi0gICAgICAgICAgICAgICAgICAgICAgICBpbnQgZGF0YU9yUHJlZml4LCBib29sZWFuIGNhbkhhdmVGaXJzdENoaWxkKQotICB7Ci0gICAgLy8gQ29tbW9uIHRvIGFsbCBub2RlczoKLSAgICBpbnQgbm9kZUluZGV4ID0gbV9zaXplKys7Ci0KLSAgICAvLyBIYXZlIHdlIG92ZXJmbG93ZWQgYSBEVE0gSWRlbnRpdHkncyBhZGRyZXNzaW5nIHJhbmdlPwotICAgIGlmKG1fZHRtSWRlbnQuc2l6ZSgpID09IChub2RlSW5kZXg+Pj5EVE1NYW5hZ2VyLklERU5UX0RUTV9OT0RFX0JJVFMpKQotICAgIHsKLSAgICAgIGFkZE5ld0RUTUlEKG5vZGVJbmRleCk7Ci0gICAgfQotCi0gICAgbV9maXJzdGNoLmFkZEVsZW1lbnQoY2FuSGF2ZUZpcnN0Q2hpbGQgPyBOT1RQUk9DRVNTRUQgOiBEVE0uTlVMTCk7Ci0gICAgbV9uZXh0c2liLmFkZEVsZW1lbnQoTk9UUFJPQ0VTU0VEKTsKLSAgICBtX3BhcmVudC5hZGRFbGVtZW50KHBhcmVudEluZGV4KTsKLSAgICBtX2V4cHR5cGUuYWRkRWxlbWVudChleHBhbmRlZFR5cGVJRCk7Ci0gICAgbV9kYXRhT3JRTmFtZS5hZGRFbGVtZW50KGRhdGFPclByZWZpeCk7Ci0KLSAgICBpZiAobV9wcmV2c2liICE9IG51bGwpIHsKLSAgICAgIG1fcHJldnNpYi5hZGRFbGVtZW50KHByZXZpb3VzU2libGluZyk7Ci0gICAgfQotCi0gICAgaWYgKERUTS5OVUxMICE9IHByZXZpb3VzU2libGluZykgewotICAgICAgbV9uZXh0c2liLnNldEVsZW1lbnRBdChub2RlSW5kZXgscHJldmlvdXNTaWJsaW5nKTsKLSAgICB9Ci0KLSAgICBpZiAobV9sb2NhdG9yICE9IG51bGwgJiYgbV91c2VTb3VyY2VMb2NhdGlvblByb3BlcnR5KSB7Ci0gICAgICBzZXRTb3VyY2VMb2NhdGlvbigpOwotICAgIH0KLQotICAgIC8vIE5vdGUgdGhhdCBuZXh0U2libGluZyBpcyBub3QgcHJvY2Vzc2VkIHVudGlsIGNoYXJhY3RlcnNGbHVzaCgpCi0gICAgLy8gaXMgY2FsbGVkLCB0byBoYW5kbGUgc3VjY2Vzc2l2ZSBjaGFyYWN0ZXJzKCkgZXZlbnRzLgotCi0gICAgLy8gU3BlY2lhbCBoYW5kbGluZyBieSB0eXBlOiBEZWNsYXJlIG5hbWVzcGFjZXMsIGF0dGFjaCBmaXJzdCBjaGlsZAotICAgIHN3aXRjaCh0eXBlKQotICAgIHsKLSAgICBjYXNlIERUTS5OQU1FU1BBQ0VfTk9ERToKLSAgICAgIGRlY2xhcmVOYW1lc3BhY2VJbkNvbnRleHQocGFyZW50SW5kZXgsbm9kZUluZGV4KTsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgRFRNLkFUVFJJQlVURV9OT0RFOgotICAgICAgYnJlYWs7Ci0gICAgZGVmYXVsdDoKLSAgICAgIGlmIChEVE0uTlVMTCA9PSBwcmV2aW91c1NpYmxpbmcgJiYgRFRNLk5VTEwgIT0gcGFyZW50SW5kZXgpIHsKLSAgICAgICAgbV9maXJzdGNoLnNldEVsZW1lbnRBdChub2RlSW5kZXgscGFyZW50SW5kZXgpOwotICAgICAgfQotICAgICAgYnJlYWs7Ci0gICAgfQotCi0gICAgcmV0dXJuIG5vZGVJbmRleDsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgYSBuZXcgRFRNIElEIGJlZ2lubmluZyBhdCB0aGUgc3BlY2lmaWVkIG5vZGUgaW5kZXguCi0gICAqIEBwYXJhbSAgbm9kZUluZGV4IFRoZSBub2RlIGlkZW50aXR5IGF0IHdoaWNoIHRoZSBuZXcgRFRNIElEIHdpbGwgYmVnaW4KLSAgICogYWRkcmVzc2luZy4KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIGFkZE5ld0RUTUlEKGludCBub2RlSW5kZXgpIHsKLSAgICB0cnkKLSAgICB7Ci0gICAgICBpZihtX21ncj09bnVsbCkKLSAgICAgICAgdGhyb3cgbmV3IENsYXNzQ2FzdEV4Y2VwdGlvbigpOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBIYW5kbGUgYXMgRXh0ZW5kZWQgQWRkcmVzc2luZwotICAgICAgRFRNTWFuYWdlckRlZmF1bHQgbWdyRD0oRFRNTWFuYWdlckRlZmF1bHQpbV9tZ3I7Ci0gICAgICBpbnQgaWQ9bWdyRC5nZXRGaXJzdEZyZWVEVE1JRCgpOwotICAgICAgbWdyRC5hZGREVE0odGhpcyxpZCxub2RlSW5kZXgpOwotICAgICAgbV9kdG1JZGVudC5hZGRFbGVtZW50KGlkPDxEVE1NYW5hZ2VyLklERU5UX0RUTV9OT0RFX0JJVFMpOwotICAgIH0KLSAgICBjYXRjaChDbGFzc0Nhc3RFeGNlcHRpb24gZSkKLSAgICB7Ci0gICAgICAvLyAlUkVWSUVXJSBXcm9uZyBlcnJvciBtZXNzYWdlLCBidXQgSSd2ZSBiZWVuIHRvbGQgd2UncmUgdHJ5aW5nCi0gICAgICAvLyBub3QgdG8gYWRkIG1lc3NhZ2VzIHJpZ2h0IG5vdCBmb3IgSTE4TiByZWFzb25zLgotICAgICAgLy8gJVJFVklFVyUgU2hvdWxkIHRoaXMgYmUgYSBGYXRhbCBFcnJvcj8KLSAgICAgIGVycm9yKFhNTE1lc3NhZ2VzLmNyZWF0ZVhNTE1lc3NhZ2UoWE1MRXJyb3JSZXNvdXJjZXMuRVJfTk9fRFRNSURTX0FWQUlMLCBudWxsKSk7Ly8iTm8gbW9yZSBEVE0gSURzIGFyZSBhdmFpbGFibGUiOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgICogTWlncmF0ZSBhIERUTSBidWlsdCB3aXRoIGFuIG9sZCBEVE1NYW5hZ2VyIHRvIGEgbmV3IERUTU1hbmFnZXIuCi0gICAgKiBBZnRlciB0aGUgbWlncmF0aW9uLCB0aGUgbmV3IERUTU1hbmFnZXIgd2lsbCB0cmVhdCB0aGUgRFRNIGFzCi0gICAgKiBvbmUgdGhhdCBpcyBidWlsdCBieSBpdHNlbGYuCi0gICAgKiBUaGlzIGlzIHVzZWQgdG8gc3VwcG9ydCBEVE0gc2hhcmluZyBiZXR3ZWVuIG11bHRpcGxlIHRyYW5zZm9ybWF0aW9ucy4KLSAgICAqIEBwYXJhbSBtYW5hZ2VyIHRoZSBEVE1NYW5hZ2VyCi0gICAgKi8KLSAgcHVibGljIHZvaWQgbWlncmF0ZVRvKERUTU1hbmFnZXIgbWFuYWdlcikgewotICAgIHN1cGVyLm1pZ3JhdGVUbyhtYW5hZ2VyKTsKLQotICAgIC8vIFdlIGhhdmUgdG8gcmVzZXQgdGhlIGluZm9ybWF0aW9uIGluIG1fZHRtSWRlbnQgYW5kCi0gICAgLy8gcmVnaXN0ZXIgdGhlIERUTSB3aXRoIHRoZSBuZXcgbWFuYWdlci4KLSAgICBpbnQgbnVtRFRNcyA9IG1fZHRtSWRlbnQuc2l6ZSgpOwotICAgIGludCBkdG1JZCA9IG1fbWdyRGVmYXVsdC5nZXRGaXJzdEZyZWVEVE1JRCgpOwotICAgIGludCBub2RlSW5kZXggPSAwOwotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtRFRNczsgaSsrKQotICAgIHsKLSAgICAgIG1fZHRtSWRlbnQuc2V0RWxlbWVudEF0KGR0bUlkIDw8IERUTU1hbmFnZXIuSURFTlRfRFRNX05PREVfQklUUywgaSk7Ci0gICAgICBtX21nckRlZmF1bHQuYWRkRFRNKHRoaXMsIGR0bUlkLCBub2RlSW5kZXgpOwotICAgICAgZHRtSWQrKzsKLSAgICAgIG5vZGVJbmRleCArPSAoMSA8PCBEVE1NYW5hZ2VyLklERU5UX0RUTV9OT0RFX0JJVFMpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBTdG9yZSB0aGUgc291cmNlIGxvY2F0aW9uIG9mIHRoZSBjdXJyZW50IG5vZGUuICBUaGlzIG1ldGhvZCBtdXN0IGJlIGNhbGxlZAotICAgKiBhcyBldmVyeSBub2RlIGlzIGFkZGVkIHRvIHRoZSBEVE0gb3IgZm9yIG5vIG5vZGUuCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBzZXRTb3VyY2VMb2NhdGlvbigpIHsKLSAgICBtX3NvdXJjZVN5c3RlbUlkLmFkZEVsZW1lbnQobV9sb2NhdG9yLmdldFN5c3RlbUlkKCkpOwotICAgIG1fc291cmNlTGluZS5hZGRFbGVtZW50KG1fbG9jYXRvci5nZXRMaW5lTnVtYmVyKCkpOwotICAgIG1fc291cmNlQ29sdW1uLmFkZEVsZW1lbnQobV9sb2NhdG9yLmdldENvbHVtbk51bWJlcigpKTsKLQotICAgIC8vJVJFVklFVyUgJUJVRyUgUHJldmVudCB0aGlzIGZyb20gYXJpc2luZyBpbiB0aGUgZmlyc3QgcGxhY2UKLSAgICAvLyBieSBub3QgYWxsb3dpbmcgdGhlIGVuYWJsaW5nIGNvbmRpdGlvbnMgdG8gY2hhbmdlIGFmdGVyIHdlIHN0YXJ0Ci0gICAgLy8gYnVpbGRpbmcgdGhlIGRvY3VtZW50LgotICAgIGlmIChtX3NvdXJjZVN5c3RlbUlkLnNpemUoKSAhPSBtX3NpemUpIHsKLSAgICAgICAgU3RyaW5nIG1zZyA9ICJDT0RJTkcgRVJST1IgaW4gU291cmNlIExvY2F0aW9uOiAiICsgbV9zaXplICsgIiAhPSAiCi0gICAgICAgICAgICAgICAgICAgICsgbV9zb3VyY2VTeXN0ZW1JZC5zaXplKCk7Ci0gICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbihtc2cpOwotICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihtc2cpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBHaXZlbiBhIG5vZGUgaGFuZGxlLCByZXR1cm4gaXRzIG5vZGUgdmFsdWUuIFRoaXMgaXMgbW9zdGx5Ci0gICAqIGFzIGRlZmluZWQgYnkgdGhlIERPTSwgYnV0IG1heSBpZ25vcmUgc29tZSBjb252ZW5pZW5jZXMuCi0gICAqIDxwPgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBUaGUgbm9kZSBpZC4KLSAgICogQHJldHVybiBTdHJpbmcgVmFsdWUgb2YgdGhpcyBub2RlLCBvciBudWxsIGlmIG5vdAotICAgKiBtZWFuaW5nZnVsIGZvciB0aGlzIG5vZGUgdHlwZS4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0Tm9kZVZhbHVlKGludCBub2RlSGFuZGxlKQotICB7Ci0KLSAgICBpbnQgaWRlbnRpdHkgPSBtYWtlTm9kZUlkZW50aXR5KG5vZGVIYW5kbGUpOwotICAgIGludCB0eXBlID0gX3R5cGUoaWRlbnRpdHkpOwotCi0gICAgaWYgKGlzVGV4dFR5cGUodHlwZSkpCi0gICAgewotICAgICAgaW50IGRhdGFJbmRleCA9IF9kYXRhT3JRTmFtZShpZGVudGl0eSk7Ci0gICAgICBpbnQgb2Zmc2V0ID0gbV9kYXRhLmVsZW1lbnRBdChkYXRhSW5kZXgpOwotICAgICAgaW50IGxlbmd0aCA9IG1fZGF0YS5lbGVtZW50QXQoZGF0YUluZGV4ICsgMSk7Ci0KLSAgICAgIC8vICVPUFQlIFdlIHNob3VsZCBjYWNoZSB0aGlzLCBJIGd1ZXNzLgotICAgICAgcmV0dXJuIG1fY2hhcnMuZ2V0U3RyaW5nKG9mZnNldCwgbGVuZ3RoKTsKLSAgICB9Ci0gICAgZWxzZSBpZiAoRFRNLkVMRU1FTlRfTk9ERSA9PSB0eXBlIHx8IERUTS5ET0NVTUVOVF9GUkFHTUVOVF9OT0RFID09IHR5cGUKLSAgICAgICAgICAgICB8fCBEVE0uRE9DVU1FTlRfTk9ERSA9PSB0eXBlKQotICAgIHsKLSAgICAgIHJldHVybiBudWxsOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgaW50IGRhdGFJbmRleCA9IF9kYXRhT3JRTmFtZShpZGVudGl0eSk7Ci0KLSAgICAgIGlmIChkYXRhSW5kZXggPCAwKQotICAgICAgewotICAgICAgICBkYXRhSW5kZXggPSAtZGF0YUluZGV4OwotICAgICAgICBkYXRhSW5kZXggPSBtX2RhdGEuZWxlbWVudEF0KGRhdGFJbmRleCArIDEpOwotICAgICAgfQotCi0gICAgICByZXR1cm4gbV92YWx1ZXNPclByZWZpeGVzLmluZGV4VG9TdHJpbmcoZGF0YUluZGV4KTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYSBub2RlIGhhbmRsZSwgcmV0dXJuIGl0cyBYUGF0aC1zdHlsZSBsb2NhbG5hbWUuCi0gICAqIChBcyBkZWZpbmVkIGluIE5hbWVzcGFjZXMsIHRoaXMgaXMgdGhlIHBvcnRpb24gb2YgdGhlIG5hbWUgYWZ0ZXIgYW55Ci0gICAqIGNvbG9uIGNoYXJhY3RlcikuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIHRoZSBpZCBvZiB0aGUgbm9kZS4KLSAgICogQHJldHVybiBTdHJpbmcgTG9jYWwgbmFtZSBvZiB0aGlzIG5vZGUuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldExvY2FsTmFtZShpbnQgbm9kZUhhbmRsZSkKLSAgewotICAgIHJldHVybiBtX2V4cGFuZGVkTmFtZVRhYmxlLmdldExvY2FsTmFtZShfZXhwdHlwZShtYWtlTm9kZUlkZW50aXR5KG5vZGVIYW5kbGUpKSk7Ci0gIH0KLQotICAvKioKLSAgICogVGhlIGdldFVucGFyc2VkRW50aXR5VVJJIGZ1bmN0aW9uIHJldHVybnMgdGhlIFVSSSBvZiB0aGUgdW5wYXJzZWQKLSAgICogZW50aXR5IHdpdGggdGhlIHNwZWNpZmllZCBuYW1lIGluIHRoZSBzYW1lIGRvY3VtZW50IGFzIHRoZSBjb250ZXh0Ci0gICAqIG5vZGUgKHNlZSBbMy4zIFVucGFyc2VkIEVudGl0aWVzXSkuIEl0IHJldHVybnMgdGhlIGVtcHR5IHN0cmluZyBpZgotICAgKiB0aGVyZSBpcyBubyBzdWNoIGVudGl0eS4KLSAgICogPHA+Ci0gICAqIFhNTCBwcm9jZXNzb3JzIG1heSBjaG9vc2UgdG8gdXNlIHRoZSBTeXN0ZW0gSWRlbnRpZmllciAoaWYgb25lCi0gICAqIGlzIHByb3ZpZGVkKSB0byByZXNvbHZlIHRoZSBlbnRpdHksIHJhdGhlciB0aGFuIHRoZSBVUkkgaW4gdGhlCi0gICAqIFB1YmxpYyBJZGVudGlmaWVyLiBUaGUgZGV0YWlscyBhcmUgZGVwZW5kZW50IG9uIHRoZSBwcm9jZXNzb3IsIGFuZAotICAgKiB3ZSB3b3VsZCBoYXZlIHRvIHN1cHBvcnQgc29tZSBmb3JtIG9mIHBsdWctaW4gcmVzb2x2ZXIgdG8gaGFuZGxlCi0gICAqIHRoaXMgcHJvcGVybHkuIEN1cnJlbnRseSwgd2Ugc2ltcGx5IHJldHVybiB0aGUgU3lzdGVtIElkZW50aWZpZXIgaWYKLSAgICogcHJlc2VudCwgYW5kIGhvcGUgdGhhdCBpdCBhIHVzYWJsZSBVUkkgb3IgdGhhdCBvdXIgY2FsbGVyIGNhbgotICAgKiBtYXAgaXQgdG8gb25lLgotICAgKiBUT0RPOiBSZXNvbHZlIFB1YmxpYyBJZGVudGlmaWVycy4uLiBvciBjb25zaWRlciBjaGFuZ2luZyBmdW5jdGlvbiBuYW1lLgotICAgKiA8cD4KLSAgICogSWYgd2UgZmluZCBhIHJlbGF0aXZlIFVSSQotICAgKiByZWZlcmVuY2UsIFhNTCBleHBlY3RzIGl0IHRvIGJlIHJlc29sdmVkIGluIHRlcm1zIG9mIHRoZSBiYXNlIFVSSQotICAgKiBvZiB0aGUgZG9jdW1lbnQuIFRoZSBET00gZG9lc24ndCBkbyB0aGF0IGZvciB1cywgYW5kIGl0IGlzbid0Ci0gICAqIGVudGlyZWx5IGNsZWFyIHdoZXRoZXIgdGhhdCBzaG91bGQgYmUgZG9uZSBoZXJlOyBjdXJyZW50bHkgdGhhdCdzCi0gICAqIHB1c2hlZCB1cCB0byBhIGhpZ2hlciBsZXZlbCBvZiBvdXIgYXBwbGljYXRpb24uIChOb3RlIHRoYXQgRE9NIExldmVsCi0gICAqIDEgZGlkbid0IHN0b3JlIHRoZSBkb2N1bWVudCdzIGJhc2UgVVJJLikKLSAgICogVE9ETzogQ29uc2lkZXIgcmVzb2x2aW5nIFJlbGF0aXZlIFVSSXMuCi0gICAqIDxwPgotICAgKiAoVGhlIERPTSdzIHN0YXRlbWVudCB0aGF0ICJBbiBYTUwgcHJvY2Vzc29yIG1heSBjaG9vc2UgdG8KLSAgICogY29tcGxldGVseSBleHBhbmQgZW50aXRpZXMgYmVmb3JlIHRoZSBzdHJ1Y3R1cmUgbW9kZWwgaXMgcGFzc2VkCi0gICAqIHRvIHRoZSBET00iIHJlZmVycyBvbmx5IHRvIHBhcnNlZCBlbnRpdGllcywgbm90IHVucGFyc2VkLCBhbmQgaGVuY2UKLSAgICogZG9lc24ndCBhZmZlY3QgdGhpcyBmdW5jdGlvbi4pCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lIEEgc3RyaW5nIGNvbnRhaW5pbmcgdGhlIEVudGl0eSBOYW1lIG9mIHRoZSB1bnBhcnNlZAotICAgKiBlbnRpdHkuCi0gICAqCi0gICAqIEByZXR1cm4gU3RyaW5nIGNvbnRhaW5pbmcgdGhlIFVSSSBvZiB0aGUgVW5wYXJzZWQgRW50aXR5LCBvciBhbgotICAgKiBlbXB0eSBzdHJpbmcgaWYgbm8gc3VjaCBlbnRpdHkgZXhpc3RzLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRVbnBhcnNlZEVudGl0eVVSSShTdHJpbmcgbmFtZSkKLSAgewotCi0gICAgU3RyaW5nIHVybCA9ICIiOwotCi0gICAgaWYgKG51bGwgPT0gbV9lbnRpdGllcykKLSAgICAgIHJldHVybiB1cmw7Ci0KLSAgICBpbnQgbiA9IG1fZW50aXRpZXMuc2l6ZSgpOwotCi0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpICs9IEVOVElUWV9GSUVMRFNfUEVSKQotICAgIHsKLSAgICAgIFN0cmluZyBlbmFtZSA9IChTdHJpbmcpIG1fZW50aXRpZXMuZWxlbWVudEF0KGkgKyBFTlRJVFlfRklFTERfTkFNRSk7Ci0KLSAgICAgIGlmIChudWxsICE9IGVuYW1lICYmIGVuYW1lLmVxdWFscyhuYW1lKSkKLSAgICAgIHsKLSAgICAgICAgU3RyaW5nIG5uYW1lID0gKFN0cmluZykgbV9lbnRpdGllcy5lbGVtZW50QXQoaQotICAgICAgICAgICAgICAgICAgICAgICAgICsgRU5USVRZX0ZJRUxEX05PVEFUSU9OTkFNRSk7Ci0KLSAgICAgICAgaWYgKG51bGwgIT0gbm5hbWUpCi0gICAgICAgIHsKLQotICAgICAgICAgIC8vIFRoZSBkcmFmdCBzYXlzOiAiVGhlIFhTTFQgcHJvY2Vzc29yIG1heSB1c2UgdGhlIHB1YmxpYwotICAgICAgICAgIC8vIGlkZW50aWZpZXIgdG8gZ2VuZXJhdGUgYSBVUkkgZm9yIHRoZSBlbnRpdHkgaW5zdGVhZCBvZiB0aGUgVVJJCi0gICAgICAgICAgLy8gc3BlY2lmaWVkIGluIHRoZSBzeXN0ZW0gaWRlbnRpZmllci4gSWYgdGhlIFhTTFQgcHJvY2Vzc29yIGRvZXMKLSAgICAgICAgICAvLyBub3QgdXNlIHRoZSBwdWJsaWMgaWRlbnRpZmllciB0byBnZW5lcmF0ZSB0aGUgVVJJLCBpdCBtdXN0IHVzZQotICAgICAgICAgIC8vIHRoZSBzeXN0ZW0gaWRlbnRpZmllcjsgaWYgdGhlIHN5c3RlbSBpZGVudGlmaWVyIGlzIGEgcmVsYXRpdmUKLSAgICAgICAgICAvLyBVUkksIGl0IG11c3QgYmUgcmVzb2x2ZWQgaW50byBhbiBhYnNvbHV0ZSBVUkkgdXNpbmcgdGhlIFVSSSBvZgotICAgICAgICAgIC8vIHRoZSByZXNvdXJjZSBjb250YWluaW5nIHRoZSBlbnRpdHkgZGVjbGFyYXRpb24gYXMgdGhlIGJhc2UKLSAgICAgICAgICAvLyBVUkkgW1JGQzIzOTZdLiIKLSAgICAgICAgICAvLyBTbyBJJ20gZmFsbGluZyBhIGJpdCBzaG9ydCBoZXJlLgotICAgICAgICAgIHVybCA9IChTdHJpbmcpIG1fZW50aXRpZXMuZWxlbWVudEF0KGkgKyBFTlRJVFlfRklFTERfU1lTVEVNSUQpOwotCi0gICAgICAgICAgaWYgKG51bGwgPT0gdXJsKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIHVybCA9IChTdHJpbmcpIG1fZW50aXRpZXMuZWxlbWVudEF0KGkgKyBFTlRJVFlfRklFTERfUFVCTElDSUQpOwotICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGJyZWFrOwotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiB1cmw7Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYSBuYW1lc3BhY2UgaGFuZGxlLCByZXR1cm4gdGhlIHByZWZpeCB0aGF0IHRoZSBuYW1lc3BhY2UgZGVjbCBpcwotICAgKiBtYXBwaW5nLgotICAgKiBHaXZlbiBhIG5vZGUgaGFuZGxlLCByZXR1cm4gdGhlIHByZWZpeCB1c2VkIHRvIG1hcCB0byB0aGUgbmFtZXNwYWNlLgotICAgKgotICAgKiA8cD4gJVJFVklFVyUgQXJlIHlvdSBzdXJlIHlvdSB3YW50ICIiIGZvciBubyBwcmVmaXg/ICA8L3A+Ci0gICAqIDxwPiAlUkVWSUVXLUNPTU1FTlQlIEkgdGhpbmsgc28uLi4gbm90IHRvdGFsbHkgc3VyZS4gLXNiICA8L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIHRoZSBpZCBvZiB0aGUgbm9kZS4KLSAgICogQHJldHVybiBTdHJpbmcgcHJlZml4IG9mIHRoaXMgbm9kZSdzIG5hbWUsIG9yICIiIGlmIG5vIGV4cGxpY2l0Ci0gICAqIG5hbWVzcGFjZSBwcmVmaXggd2FzIGdpdmVuLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRQcmVmaXgoaW50IG5vZGVIYW5kbGUpCi0gIHsKLQotICAgIGludCBpZGVudGl0eSA9IG1ha2VOb2RlSWRlbnRpdHkobm9kZUhhbmRsZSk7Ci0gICAgaW50IHR5cGUgPSBfdHlwZShpZGVudGl0eSk7Ci0KLSAgICBpZiAoRFRNLkVMRU1FTlRfTk9ERSA9PSB0eXBlKQotICAgIHsKLSAgICAgIGludCBwcmVmaXhJbmRleCA9IF9kYXRhT3JRTmFtZShpZGVudGl0eSk7Ci0KLSAgICAgIGlmICgwID09IHByZWZpeEluZGV4KQotICAgICAgICByZXR1cm4gIiI7Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIFN0cmluZyBxbmFtZSA9IG1fdmFsdWVzT3JQcmVmaXhlcy5pbmRleFRvU3RyaW5nKHByZWZpeEluZGV4KTsKLQotICAgICAgICByZXR1cm4gZ2V0UHJlZml4KHFuYW1lLCBudWxsKTsKLSAgICAgIH0KLSAgICB9Ci0gICAgZWxzZSBpZiAoRFRNLkFUVFJJQlVURV9OT0RFID09IHR5cGUpCi0gICAgewotICAgICAgaW50IHByZWZpeEluZGV4ID0gX2RhdGFPclFOYW1lKGlkZW50aXR5KTsKLQotICAgICAgaWYgKHByZWZpeEluZGV4IDwgMCkKLSAgICAgIHsKLSAgICAgICAgcHJlZml4SW5kZXggPSBtX2RhdGEuZWxlbWVudEF0KC1wcmVmaXhJbmRleCk7Ci0KLSAgICAgICAgU3RyaW5nIHFuYW1lID0gbV92YWx1ZXNPclByZWZpeGVzLmluZGV4VG9TdHJpbmcocHJlZml4SW5kZXgpOwotCi0gICAgICAgIHJldHVybiBnZXRQcmVmaXgocW5hbWUsIG51bGwpOwotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiAiIjsKLSAgfQotCi0gIC8qKgotICAgKiBSZXRyaWV2ZXMgYW4gYXR0cmlidXRlIG5vZGUgYnkgYnkgcXVhbGlmaWVkIG5hbWUgYW5kIG5hbWVzcGFjZSBVUkkuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIGludCBIYW5kbGUgb2YgdGhlIG5vZGUgdXBvbiB3aGljaCB0byBsb29rIHVwIHRoaXMgYXR0cmlidXRlLi4KLSAgICogQHBhcmFtIG5hbWVzcGFjZVVSSSBUaGUgbmFtZXNwYWNlIFVSSSBvZiB0aGUgYXR0cmlidXRlIHRvCi0gICAqICAgcmV0cmlldmUsIG9yIG51bGwuCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBsb2NhbCBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUgdG8KLSAgICogICByZXRyaWV2ZS4KLSAgICogQHJldHVybiBUaGUgYXR0cmlidXRlIG5vZGUgaGFuZGxlIHdpdGggdGhlIHNwZWNpZmllZCBuYW1lICgKLSAgICogICA8Y29kZT5ub2RlTmFtZTwvY29kZT4pIG9yIDxjb2RlPkRUTS5OVUxMPC9jb2RlPiBpZiB0aGVyZSBpcyBubyBzdWNoCi0gICAqICAgYXR0cmlidXRlLgotICAgKi8KLSAgcHVibGljIGludCBnZXRBdHRyaWJ1dGVOb2RlKGludCBub2RlSGFuZGxlLCBTdHJpbmcgbmFtZXNwYWNlVVJJLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG5hbWUpCi0gIHsKLQotICAgIGZvciAoaW50IGF0dHJIID0gZ2V0Rmlyc3RBdHRyaWJ1dGUobm9kZUhhbmRsZSk7IERUTS5OVUxMICE9IGF0dHJIOwotICAgICAgICAgICAgYXR0ckggPSBnZXROZXh0QXR0cmlidXRlKGF0dHJIKSkKLSAgICB7Ci0gICAgICBTdHJpbmcgYXR0ck5TID0gZ2V0TmFtZXNwYWNlVVJJKGF0dHJIKTsKLSAgICAgIFN0cmluZyBhdHRyTmFtZSA9IGdldExvY2FsTmFtZShhdHRySCk7Ci0gICAgICBib29sZWFuIG5zTWF0Y2ggPSBuYW1lc3BhY2VVUkkgPT0gYXR0ck5TCi0gICAgICAgICAgICAgICAgICAgICAgICB8fCAobmFtZXNwYWNlVVJJICE9IG51bGwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiBuYW1lc3BhY2VVUkkuZXF1YWxzKGF0dHJOUykpOwotCi0gICAgICBpZiAobnNNYXRjaCAmJiBuYW1lLmVxdWFscyhhdHRyTmFtZSkpCi0gICAgICAgIHJldHVybiBhdHRySDsKLSAgICB9Ci0KLSAgICByZXR1cm4gRFRNLk5VTEw7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBwdWJsaWMgaWRlbnRpZmllciBvZiB0aGUgZXh0ZXJuYWwgc3Vic2V0LAotICAgKiBub3JtYWxpemVkIGFzIGRlc2NyaWJlZCBpbiA0LjIuMiBFeHRlcm5hbCBFbnRpdGllcyBbWE1MXS4gSWYgdGhlcmUgaXMKLSAgICogbm8gZXh0ZXJuYWwgc3Vic2V0IG9yIGlmIGl0IGhhcyBubyBwdWJsaWMgaWRlbnRpZmllciwgdGhpcyBwcm9wZXJ0eQotICAgKiBoYXMgbm8gdmFsdWUuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIHB1YmxpYyBpZGVudGlmaWVyIFN0cmluZyBvYmplY3QsIG9yIG51bGwgaWYgdGhlcmUgaXMgbm9uZS4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0RG9jdW1lbnRUeXBlRGVjbGFyYXRpb25QdWJsaWNJZGVudGlmaWVyKCkKLSAgewotCi0gICAgLyoqIEB0b2RvOiBpbXBsZW1lbnQgdGhpcyBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1EZWZhdWx0QmFzZSBhYnN0cmFjdCBtZXRob2QgKi8KLSAgICBlcnJvcihYTUxNZXNzYWdlcy5jcmVhdGVYTUxNZXNzYWdlKFhNTEVycm9yUmVzb3VyY2VzLkVSX01FVEhPRF9OT1RfU1VQUE9SVEVELCBudWxsKSk7Ly8iTm90IHlldCBzdXBwb3J0ZWQhIik7Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBHaXZlbiBhIG5vZGUgaGFuZGxlLCByZXR1cm4gaXRzIERPTS1zdHlsZSBuYW1lc3BhY2UgVVJJCi0gICAqIChBcyBkZWZpbmVkIGluIE5hbWVzcGFjZXMsIHRoaXMgaXMgdGhlIGRlY2xhcmVkIFVSSSB3aGljaCB0aGlzIG5vZGUncwotICAgKiBwcmVmaXggLS0gb3IgZGVmYXVsdCBpbiBsaWV1IHRoZXJlb2YgLS0gd2FzIG1hcHBlZCB0by4pCi0gICAqCi0gICAqIDxwPiVSRVZJRVclIE51bGwgb3IgIiI/IC1zYjwvcD4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgdGhlIGlkIG9mIHRoZSBub2RlLgotICAgKiBAcmV0dXJuIFN0cmluZyBVUkkgdmFsdWUgb2YgdGhpcyBub2RlJ3MgbmFtZXNwYWNlLCBvciBudWxsIGlmIG5vCi0gICAqIG5hbWVzcGFjZSB3YXMgcmVzb2x2ZWQuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldE5hbWVzcGFjZVVSSShpbnQgbm9kZUhhbmRsZSkKLSAgewotCi0gICAgcmV0dXJuIG1fZXhwYW5kZWROYW1lVGFibGUuZ2V0TmFtZXNwYWNlKF9leHB0eXBlKG1ha2VOb2RlSWRlbnRpdHkobm9kZUhhbmRsZSkpKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIHN0cmluZy12YWx1ZSBvZiBhIG5vZGUgYXMgYSBTdHJpbmcgb2JqZWN0Ci0gICAqIChzZWUgaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGgjZGF0YS1tb2RlbAotICAgKiBmb3IgdGhlIGRlZmluaXRpb24gb2YgYSBub2RlJ3Mgc3RyaW5nLXZhbHVlKS4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgVGhlIG5vZGUgSUQuCi0gICAqCi0gICAqIEByZXR1cm4gQSBzdHJpbmcgb2JqZWN0IHRoYXQgcmVwcmVzZW50cyB0aGUgc3RyaW5nLXZhbHVlIG9mIHRoZSBnaXZlbiBub2RlLgotICAgKi8KLSAgcHVibGljIFhNTFN0cmluZyBnZXRTdHJpbmdWYWx1ZShpbnQgbm9kZUhhbmRsZSkKLSAgewotICAgIGludCBpZGVudGl0eSA9IG1ha2VOb2RlSWRlbnRpdHkobm9kZUhhbmRsZSk7Ci0gICAgaW50IHR5cGU7Ci0gICAgaWYoaWRlbnRpdHk9PURUTS5OVUxMKSAvLyBTZXBhcmF0ZSBsaW5lcyBiZWNhdXNlIEkgd2FudGVkIHRvIGJyZWFrcG9pbnQgaXQKLSAgICAgIHR5cGUgPSBEVE0uTlVMTDsKLSAgICBlbHNlCi0gICAgICB0eXBlPSBfdHlwZShpZGVudGl0eSk7Ci0KLSAgICBpZiAoaXNUZXh0VHlwZSh0eXBlKSkKLSAgICB7Ci0gICAgICBpbnQgZGF0YUluZGV4ID0gX2RhdGFPclFOYW1lKGlkZW50aXR5KTsKLSAgICAgIGludCBvZmZzZXQgPSBtX2RhdGEuZWxlbWVudEF0KGRhdGFJbmRleCk7Ci0gICAgICBpbnQgbGVuZ3RoID0gbV9kYXRhLmVsZW1lbnRBdChkYXRhSW5kZXggKyAxKTsKLQotICAgICAgcmV0dXJuIG1feHN0cmYubmV3c3RyKG1fY2hhcnMsIG9mZnNldCwgbGVuZ3RoKTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIGludCBmaXJzdENoaWxkID0gX2ZpcnN0Y2goaWRlbnRpdHkpOwotCi0gICAgICBpZiAoRFRNLk5VTEwgIT0gZmlyc3RDaGlsZCkKLSAgICAgIHsKLSAgICAgICAgaW50IG9mZnNldCA9IC0xOwotICAgICAgICBpbnQgbGVuZ3RoID0gMDsKLSAgICAgICAgaW50IHN0YXJ0Tm9kZSA9IGlkZW50aXR5OwotCi0gICAgICAgIGlkZW50aXR5ID0gZmlyc3RDaGlsZDsKLQotICAgICAgICBkbyB7Ci0gICAgICAgICAgdHlwZSA9IF90eXBlKGlkZW50aXR5KTsKLQotICAgICAgICAgIGlmIChpc1RleHRUeXBlKHR5cGUpKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGludCBkYXRhSW5kZXggPSBfZGF0YU9yUU5hbWUoaWRlbnRpdHkpOwotCi0gICAgICAgICAgICBpZiAoLTEgPT0gb2Zmc2V0KQotICAgICAgICAgICAgewotICAgICAgICAgICAgICBvZmZzZXQgPSBtX2RhdGEuZWxlbWVudEF0KGRhdGFJbmRleCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGxlbmd0aCArPSBtX2RhdGEuZWxlbWVudEF0KGRhdGFJbmRleCArIDEpOwotICAgICAgICAgIH0KLQotICAgICAgICAgIGlkZW50aXR5ID0gZ2V0TmV4dE5vZGVJZGVudGl0eShpZGVudGl0eSk7Ci0gICAgICAgIH0gd2hpbGUgKERUTS5OVUxMICE9IGlkZW50aXR5ICYmIChfcGFyZW50KGlkZW50aXR5KSA+PSBzdGFydE5vZGUpKTsKLQotICAgICAgICBpZiAobGVuZ3RoID4gMCkKLSAgICAgICAgewotICAgICAgICAgIHJldHVybiBtX3hzdHJmLm5ld3N0cihtX2NoYXJzLCBvZmZzZXQsIGxlbmd0aCk7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICAgIGVsc2UgaWYodHlwZSAhPSBEVE0uRUxFTUVOVF9OT0RFKQotICAgICAgewotICAgICAgICBpbnQgZGF0YUluZGV4ID0gX2RhdGFPclFOYW1lKGlkZW50aXR5KTsKLQotICAgICAgICBpZiAoZGF0YUluZGV4IDwgMCkKLSAgICAgICAgewotICAgICAgICAgIGRhdGFJbmRleCA9IC1kYXRhSW5kZXg7Ci0gICAgICAgICAgZGF0YUluZGV4ID0gbV9kYXRhLmVsZW1lbnRBdChkYXRhSW5kZXggKyAxKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbV94c3RyZi5uZXdzdHIobV92YWx1ZXNPclByZWZpeGVzLmluZGV4VG9TdHJpbmcoZGF0YUluZGV4KSk7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgcmV0dXJuIG1feHN0cmYuZW1wdHlzdHIoKTsKLSAgfQotCi0gIC8qKgotICAgKiBEZXRlcm1pbmUgaWYgdGhlIHN0cmluZy12YWx1ZSBvZiBhIG5vZGUgaXMgd2hpdGVzcGFjZQotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBUaGUgbm9kZSBIYW5kbGUuCi0gICAqCi0gICAqIEByZXR1cm4gUmV0dXJuIHRydWUgaWYgdGhlIGdpdmVuIG5vZGUgaXMgd2hpdGVzcGFjZS4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzV2hpdGVzcGFjZShpbnQgbm9kZUhhbmRsZSkKLSAgewotICAgIGludCBpZGVudGl0eSA9IG1ha2VOb2RlSWRlbnRpdHkobm9kZUhhbmRsZSk7Ci0gICAgaW50IHR5cGU7Ci0gICAgaWYoaWRlbnRpdHk9PURUTS5OVUxMKSAvLyBTZXBhcmF0ZSBsaW5lcyBiZWNhdXNlIEkgd2FudGVkIHRvIGJyZWFrcG9pbnQgaXQKLSAgICAgIHR5cGUgPSBEVE0uTlVMTDsKLSAgICBlbHNlCi0gICAgICB0eXBlPSBfdHlwZShpZGVudGl0eSk7Ci0KLSAgICBpZiAoaXNUZXh0VHlwZSh0eXBlKSkKLSAgICB7Ci0gICAgICBpbnQgZGF0YUluZGV4ID0gX2RhdGFPclFOYW1lKGlkZW50aXR5KTsKLSAgICAgIGludCBvZmZzZXQgPSBtX2RhdGEuZWxlbWVudEF0KGRhdGFJbmRleCk7Ci0gICAgICBpbnQgbGVuZ3RoID0gbV9kYXRhLmVsZW1lbnRBdChkYXRhSW5kZXggKyAxKTsKLQotICAgICAgcmV0dXJuIG1fY2hhcnMuaXNXaGl0ZXNwYWNlKG9mZnNldCwgbGVuZ3RoKTsKLSAgICB9Ci0gICAgcmV0dXJuIGZhbHNlOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIDxjb2RlPkVsZW1lbnQ8L2NvZGU+IHdob3NlIDxjb2RlPklEPC9jb2RlPiBpcyBnaXZlbiBieQotICAgKiA8Y29kZT5lbGVtZW50SWQ8L2NvZGU+LiBJZiBubyBzdWNoIGVsZW1lbnQgZXhpc3RzLCByZXR1cm5zCi0gICAqIDxjb2RlPkRUTS5OVUxMPC9jb2RlPi4gQmVoYXZpb3IgaXMgbm90IGRlZmluZWQgaWYgbW9yZSB0aGFuIG9uZSBlbGVtZW50Ci0gICAqIGhhcyB0aGlzIDxjb2RlPklEPC9jb2RlPi4gQXR0cmlidXRlcyAoaW5jbHVkaW5nIHRob3NlCi0gICAqIHdpdGggdGhlIG5hbWUgIklEIikgYXJlIG5vdCBvZiB0eXBlIElEIHVubGVzcyBzbyBkZWZpbmVkIGJ5IERURC9TY2hlbWEKLSAgICogaW5mb3JtYXRpb24gYXZhaWxhYmxlIHRvIHRoZSBEVE0gaW1wbGVtZW50YXRpb24uCi0gICAqIEltcGxlbWVudGF0aW9ucyB0aGF0IGRvIG5vdCBrbm93IHdoZXRoZXIgYXR0cmlidXRlcyBhcmUgb2YgdHlwZSBJRCBvcgotICAgKiBub3QgYXJlIGV4cGVjdGVkIHRvIHJldHVybiA8Y29kZT5EVE0uTlVMTDwvY29kZT4uCi0gICAqCi0gICAqIDxwPiVSRVZJRVclIFByZXN1bWFibHkgSURzIGFyZSBzdGlsbCBzY29wZWQgdG8gYSBzaW5nbGUgZG9jdW1lbnQsCi0gICAqIGFuZCB0aGlzIG9wZXJhdGlvbiBzZWFyY2hlcyBvbmx5IHdpdGhpbiBhIHNpbmdsZSBkb2N1bWVudCwgcmlnaHQ/Ci0gICAqIFdvdWxkbid0IHdhbnQgY29sbGlzaW9ucyBiZXR3ZWVuIERUTXMgaW4gdGhlIHNhbWUgcHJvY2Vzcy48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBlbGVtZW50SWQgVGhlIHVuaXF1ZSA8Y29kZT5pZDwvY29kZT4gdmFsdWUgZm9yIGFuIGVsZW1lbnQuCi0gICAqIEByZXR1cm4gVGhlIGhhbmRsZSBvZiB0aGUgbWF0Y2hpbmcgZWxlbWVudC4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0RWxlbWVudEJ5SWQoU3RyaW5nIGVsZW1lbnRJZCkKLSAgewotCi0gICAgSW50ZWdlciBpbnRPYmo7Ci0gICAgYm9vbGVhbiBpc01vcmUgPSB0cnVlOwotCi0gICAgZG8KLSAgICB7Ci0gICAgICBpbnRPYmogPSBtX2lkQXR0cmlidXRlcy5nZXQoZWxlbWVudElkKTsKLQotICAgICAgaWYgKG51bGwgIT0gaW50T2JqKQotICAgICAgICByZXR1cm4gbWFrZU5vZGVIYW5kbGUoaW50T2JqLmludFZhbHVlKCkpOwotCi0gICAgICBpZiAoIWlzTW9yZSB8fCBtX2VuZERvY3VtZW50T2NjdXJlZCkKLSAgICAgICAgYnJlYWs7Ci0KLSAgICAgIGlzTW9yZSA9IG5leHROb2RlKCk7Ci0gICAgfQotICAgIHdoaWxlIChudWxsID09IGludE9iaik7Ci0KLSAgICByZXR1cm4gRFRNLk5VTEw7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IGEgcHJlZml4IGVpdGhlciBmcm9tIHRoZSBxbmFtZSBvciBmcm9tIHRoZSB1cmkgbWFwcGluZywgb3IganVzdCBtYWtlCi0gICAqIG9uZSB1cCEKLSAgICoKLSAgICogQHBhcmFtIHFuYW1lIFRoZSBxdWFsaWZpZWQgbmFtZSwgd2hpY2ggbWF5IGJlIG51bGwuCi0gICAqIEBwYXJhbSB1cmkgVGhlIG5hbWVzcGFjZSBVUkksIHdoaWNoIG1heSBiZSBudWxsLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBwcmVmaXggaWYgdGhlcmUgaXMgb25lLCBvciBudWxsLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRQcmVmaXgoU3RyaW5nIHFuYW1lLCBTdHJpbmcgdXJpKQotICB7Ci0KLSAgICBTdHJpbmcgcHJlZml4OwotICAgIGludCB1cmlJbmRleCA9IC0xOwotCi0gICAgaWYgKG51bGwgIT0gdXJpICYmIHVyaS5sZW5ndGgoKSA+IDApCi0gICAgewotCi0gICAgICBkbwotICAgICAgewotICAgICAgICB1cmlJbmRleCA9IG1fcHJlZml4TWFwcGluZ3MuaW5kZXhPZih1cmksICsrdXJpSW5kZXgpOwotICAgICAgfSB3aGlsZSAoICh1cmlJbmRleCAmIDB4MDEpID09IDApOwotCi0gICAgICBpZiAodXJpSW5kZXggPj0gMCkKLSAgICAgIHsKLSAgICAgICAgcHJlZml4ID0gKFN0cmluZykgbV9wcmVmaXhNYXBwaW5ncy5lbGVtZW50QXQodXJpSW5kZXggLSAxKTsKLSAgICAgIH0KLSAgICAgIGVsc2UgaWYgKG51bGwgIT0gcW5hbWUpCi0gICAgICB7Ci0gICAgICAgIGludCBpbmRleE9mTlNTZXAgPSBxbmFtZS5pbmRleE9mKCc6Jyk7Ci0KLSAgICAgICAgaWYgKHFuYW1lLmVxdWFscygieG1sbnMiKSkKLSAgICAgICAgICBwcmVmaXggPSAiIjsKLSAgICAgICAgZWxzZSBpZiAocW5hbWUuc3RhcnRzV2l0aCgieG1sbnM6IikpCi0gICAgICAgICAgcHJlZml4ID0gcW5hbWUuc3Vic3RyaW5nKGluZGV4T2ZOU1NlcCArIDEpOwotICAgICAgICBlbHNlCi0gICAgICAgICAgcHJlZml4ID0gKGluZGV4T2ZOU1NlcCA+IDApCi0gICAgICAgICAgICAgICAgICAgPyBxbmFtZS5zdWJzdHJpbmcoMCwgaW5kZXhPZk5TU2VwKSA6IG51bGw7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIHByZWZpeCA9IG51bGw7Ci0gICAgICB9Ci0gICAgfQotICAgIGVsc2UgaWYgKG51bGwgIT0gcW5hbWUpCi0gICAgewotICAgICAgaW50IGluZGV4T2ZOU1NlcCA9IHFuYW1lLmluZGV4T2YoJzonKTsKLQotICAgICAgaWYgKGluZGV4T2ZOU1NlcCA+IDApCi0gICAgICB7Ci0gICAgICAgIGlmIChxbmFtZS5zdGFydHNXaXRoKCJ4bWxuczoiKSkKLSAgICAgICAgICBwcmVmaXggPSBxbmFtZS5zdWJzdHJpbmcoaW5kZXhPZk5TU2VwICsgMSk7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICBwcmVmaXggPSBxbmFtZS5zdWJzdHJpbmcoMCwgaW5kZXhPZk5TU2VwKTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgaWYgKHFuYW1lLmVxdWFscygieG1sbnMiKSkKLSAgICAgICAgICBwcmVmaXggPSAiIjsKLSAgICAgICAgZWxzZQotICAgICAgICAgIHByZWZpeCA9IG51bGw7Ci0gICAgICB9Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBwcmVmaXggPSBudWxsOwotICAgIH0KLQotICAgIHJldHVybiBwcmVmaXg7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IGEgcHJlZml4IGVpdGhlciBmcm9tIHRoZSB1cmkgbWFwcGluZywgb3IganVzdCBtYWtlCi0gICAqIG9uZSB1cCEKLSAgICoKLSAgICogQHBhcmFtIHVyaSBUaGUgbmFtZXNwYWNlIFVSSSwgd2hpY2ggbWF5IGJlIG51bGwuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHByZWZpeCBpZiB0aGVyZSBpcyBvbmUsIG9yIG51bGwuCi0gICAqLwotICBwdWJsaWMgaW50IGdldElkRm9yTmFtZXNwYWNlKFN0cmluZyB1cmkpCi0gIHsKLQotICAgICByZXR1cm4gbV92YWx1ZXNPclByZWZpeGVzLnN0cmluZ1RvSW5kZXgodXJpKTsKLQotICB9Ci0KLSAgICAvKioKLSAgICogR2V0IGEgcHJlZml4IGVpdGhlciBmcm9tIHRoZSBxbmFtZSBvciBmcm9tIHRoZSB1cmkgbWFwcGluZywgb3IganVzdCBtYWtlCi0gICAqIG9uZSB1cCEKLSAgICoKLSAgICogQHJldHVybiBUaGUgcHJlZml4IGlmIHRoZXJlIGlzIG9uZSwgb3IgbnVsbC4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZXNwYWNlVVJJKFN0cmluZyBwcmVmaXgpCi0gIHsKLQotICAgIFN0cmluZyB1cmkgPSAiIjsKLSAgICBpbnQgcHJlZml4SW5kZXggPSBtX2NvbnRleHRJbmRleGVzLnBlZWsoKSAtIDEgOwotCi0gICAgaWYobnVsbCA9PSBwcmVmaXgpCi0gICAgICBwcmVmaXggPSAiIjsKLQotICAgICAgZG8KLSAgICAgIHsKLSAgICAgICAgcHJlZml4SW5kZXggPSBtX3ByZWZpeE1hcHBpbmdzLmluZGV4T2YocHJlZml4LCArK3ByZWZpeEluZGV4KTsKLSAgICAgIH0gd2hpbGUgKCAocHJlZml4SW5kZXggPj0gMCkgJiYgKHByZWZpeEluZGV4ICYgMHgwMSkgPT0gMHgwMSk7Ci0KLSAgICAgIGlmIChwcmVmaXhJbmRleCA+IC0xKQotICAgICAgewotICAgICAgICB1cmkgPSAoU3RyaW5nKSBtX3ByZWZpeE1hcHBpbmdzLmVsZW1lbnRBdChwcmVmaXhJbmRleCArIDEpOwotICAgICAgfQotCi0KLSAgICByZXR1cm4gdXJpOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCBhbiBJRCBzdHJpbmcgdG8gbm9kZSBhc3NvY2lhdGlvbiBpbiB0aGUgSUQgdGFibGUuCi0gICAqCi0gICAqIEBwYXJhbSBpZCBUaGUgSUQgc3RyaW5nLgotICAgKiBAcGFyYW0gZWxlbSBUaGUgYXNzb2NpYXRlZCBlbGVtZW50IGhhbmRsZS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldElEQXR0cmlidXRlKFN0cmluZyBpZCwgaW50IGVsZW0pCi0gIHsKLSAgICBtX2lkQXR0cmlidXRlcy5wdXQoaWQsIGVsZW0pOwotICB9Ci0KLSAgLyoqCi0gICAqIENoZWNrIHdoZXRoZXIgYWNjdW11bGF0ZWQgdGV4dCBzaG91bGQgYmUgc3RyaXBwZWQ7IGlmIG5vdCwKLSAgICogYXBwZW5kIHRoZSBhcHByb3ByaWF0ZSBmbGF2b3Igb2YgdGV4dC9jZGF0YSBub2RlLgotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgY2hhcmFjdGVyc0ZsdXNoKCkKLSAgewotCi0gICAgaWYgKG1fdGV4dFBlbmRpbmdTdGFydCA+PSAwKSAgLy8gLTEgaW5kaWNhdGVzIG5vLXRleHQtaW4tcHJvZ3Jlc3MKLSAgICB7Ci0gICAgICBpbnQgbGVuZ3RoID0gbV9jaGFycy5zaXplKCkgLSBtX3RleHRQZW5kaW5nU3RhcnQ7Ci0gICAgICBib29sZWFuIGRvU3RyaXAgPSBmYWxzZTsKLQotICAgICAgaWYgKGdldFNob3VsZFN0cmlwV2hpdGVzcGFjZSgpKQotICAgICAgewotICAgICAgICBkb1N0cmlwID0gbV9jaGFycy5pc1doaXRlc3BhY2UobV90ZXh0UGVuZGluZ1N0YXJ0LCBsZW5ndGgpOwotICAgICAgfQotCi0gICAgICBpZiAoZG9TdHJpcCkgewotICAgICAgICBtX2NoYXJzLnNldExlbmd0aChtX3RleHRQZW5kaW5nU3RhcnQpOyAgLy8gRGlzY2FyZCBhY2N1bXVsYXRlZCB0ZXh0Ci0gICAgICB9IGVsc2UgewotICAgICAgICAvLyBHdWFyZCBhZ2FpbnN0IGNoYXJhY3RlcnMvaWdub3JhYmxlV2hpdGVzcGFjZSBldmVudHMgdGhhdAotICAgICAgICAvLyBjb250YWluZWQgbm8gY2hhcmFjdGVycy4gIFRoZXkgc2hvdWxkIG5vdCByZXN1bHQgaW4gYSBub2RlLgotICAgICAgICBpZiAobGVuZ3RoID4gMCkgewotICAgICAgICAgIGludCBleE5hbWUgPSBtX2V4cGFuZGVkTmFtZVRhYmxlLmdldEV4cGFuZGVkVHlwZUlEKERUTS5URVhUX05PREUpOwotICAgICAgICAgIGludCBkYXRhSW5kZXggPSBtX2RhdGEuc2l6ZSgpOwotCi0gICAgICAgICAgbV9wcmV2aW91cyA9IGFkZE5vZGUobV9jb2FsZXNjZWRUZXh0VHlwZSwgZXhOYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fcGFyZW50cy5wZWVrKCksIG1fcHJldmlvdXMsIGRhdGFJbmRleCwgZmFsc2UpOwotCi0gICAgICAgICAgbV9kYXRhLmFkZEVsZW1lbnQobV90ZXh0UGVuZGluZ1N0YXJ0KTsKLSAgICAgICAgICBtX2RhdGEuYWRkRWxlbWVudChsZW5ndGgpOwotICAgICAgICB9Ci0gICAgICB9Ci0KLSAgICAgIC8vIFJlc2V0IGZvciBuZXh0IHRleHQgYmxvY2sKLSAgICAgIG1fdGV4dFBlbmRpbmdTdGFydCA9IC0xOwotICAgICAgbV90ZXh0VHlwZSA9IG1fY29hbGVzY2VkVGV4dFR5cGUgPSBEVE0uVEVYVF9OT0RFOwotICAgIH0KLSAgfQotCi0gIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0gIC8vIEltcGxlbWVudGF0aW9uIG9mIHRoZSBFbnRpdHlSZXNvbHZlciBpbnRlcmZhY2UuCi0gIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0KLSAgLyoqCi0gICAqIFJlc29sdmUgYW4gZXh0ZXJuYWwgZW50aXR5LgotICAgKgotICAgKiA8cD5BbHdheXMgcmV0dXJuIG51bGwsIHNvIHRoYXQgdGhlIHBhcnNlciB3aWxsIHVzZSB0aGUgc3lzdGVtCi0gICAqIGlkZW50aWZpZXIgcHJvdmlkZWQgaW4gdGhlIFhNTCBkb2N1bWVudC4gIFRoaXMgbWV0aG9kIGltcGxlbWVudHMKLSAgICogdGhlIFNBWCBkZWZhdWx0IGJlaGF2aW91cjogYXBwbGljYXRpb24gd3JpdGVycyBjYW4gb3ZlcnJpZGUgaXQKLSAgICogaW4gYSBzdWJjbGFzcyB0byBkbyBzcGVjaWFsIHRyYW5zbGF0aW9ucyBzdWNoIGFzIGNhdGFsb2cgbG9va3VwcwotICAgKiBvciBVUkkgcmVkaXJlY3Rpb24uPC9wPgotICAgKgotICAgKiBAcGFyYW0gcHVibGljSWQgVGhlIHB1YmxpYyBpZGVudGlmZXIsIG9yIG51bGwgaWYgbm9uZSBpcwotICAgKiAgICAgICAgICAgICAgICAgYXZhaWxhYmxlLgotICAgKiBAcGFyYW0gc3lzdGVtSWQgVGhlIHN5c3RlbSBpZGVudGlmaWVyIHByb3ZpZGVkIGluIHRoZSBYTUwKLSAgICogICAgICAgICAgICAgICAgIGRvY3VtZW50LgotICAgKiBAcmV0dXJuIFRoZSBuZXcgaW5wdXQgc291cmNlLCBvciBudWxsIHRvIHJlcXVpcmUgdGhlCi0gICAqICAgICAgICAgZGVmYXVsdCBiZWhhdmlvdXIuCi0gICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgKiBAc2VlIG9yZy54bWwuc2F4LkVudGl0eVJlc29sdmVyI3Jlc29sdmVFbnRpdHkKLSAgICoKLSAgICogQHRocm93cyBTQVhFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBJbnB1dFNvdXJjZSByZXNvbHZlRW50aXR5KFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkKQotICAgICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLSAgLy8gSW1wbGVtZW50YXRpb24gb2YgRFRESGFuZGxlciBpbnRlcmZhY2UuCi0gIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0KLSAgLyoqCi0gICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGEgbm90YXRpb24gZGVjbGFyYXRpb24uCi0gICAqCi0gICAqIDxwPkJ5IGRlZmF1bHQsIGRvIG5vdGhpbmcuICBBcHBsaWNhdGlvbiB3cml0ZXJzIG1heSBvdmVycmlkZSB0aGlzCi0gICAqIG1ldGhvZCBpbiBhIHN1YmNsYXNzIGlmIHRoZXkgd2lzaCB0byBrZWVwIHRyYWNrIG9mIHRoZSBub3RhdGlvbnMKLSAgICogZGVjbGFyZWQgaW4gYSBkb2N1bWVudC48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBub3RhdGlvbiBuYW1lLgotICAgKiBAcGFyYW0gcHVibGljSWQgVGhlIG5vdGF0aW9uIHB1YmxpYyBpZGVudGlmaWVyLCBvciBudWxsIGlmIG5vdAotICAgKiAgICAgICAgICAgICAgICAgYXZhaWxhYmxlLgotICAgKiBAcGFyYW0gc3lzdGVtSWQgVGhlIG5vdGF0aW9uIHN5c3RlbSBpZGVudGlmaWVyLgotICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICogQHNlZSBvcmcueG1sLnNheC5EVERIYW5kbGVyI25vdGF0aW9uRGVjbAotICAgKgotICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgbm90YXRpb25EZWNsKFN0cmluZyBuYW1lLCBTdHJpbmcgcHVibGljSWQsIFN0cmluZyBzeXN0ZW1JZCkKLSAgICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIC8vIG5vIG9wCi0gIH0KLQotICAvKioKLSAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgYW4gdW5wYXJzZWQgZW50aXR5IGRlY2xhcmF0aW9uLgotICAgKgotICAgKiA8cD5CeSBkZWZhdWx0LCBkbyBub3RoaW5nLiAgQXBwbGljYXRpb24gd3JpdGVycyBtYXkgb3ZlcnJpZGUgdGhpcwotICAgKiBtZXRob2QgaW4gYSBzdWJjbGFzcyB0byBrZWVwIHRyYWNrIG9mIHRoZSB1bnBhcnNlZCBlbnRpdGllcwotICAgKiBkZWNsYXJlZCBpbiBhIGRvY3VtZW50LjwvcD4KLSAgICoKLSAgICogQHBhcmFtIG5hbWUgVGhlIGVudGl0eSBuYW1lLgotICAgKiBAcGFyYW0gcHVibGljSWQgVGhlIGVudGl0eSBwdWJsaWMgaWRlbnRpZmllciwgb3IgbnVsbCBpZiBub3QKLSAgICogICAgICAgICAgICAgICAgIGF2YWlsYWJsZS4KLSAgICogQHBhcmFtIHN5c3RlbUlkIFRoZSBlbnRpdHkgc3lzdGVtIGlkZW50aWZpZXIuCi0gICAqIEBwYXJhbSBub3RhdGlvbk5hbWUgVGhlIG5hbWUgb2YgdGhlIGFzc29jaWF0ZWQgbm90YXRpb24uCi0gICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgKiBAc2VlIG9yZy54bWwuc2F4LkRUREhhbmRsZXIjdW5wYXJzZWRFbnRpdHlEZWNsCi0gICAqCi0gICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCB1bnBhcnNlZEVudGl0eURlY2woCi0gICAgICAgICAgU3RyaW5nIG5hbWUsIFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkLCBTdHJpbmcgbm90YXRpb25OYW1lKQotICAgICAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAobnVsbCA9PSBtX2VudGl0aWVzKQotICAgIHsKLSAgICAgIG1fZW50aXRpZXMgPSBuZXcgVmVjdG9yKCk7Ci0gICAgfQotCi0gICAgdHJ5Ci0gICAgewotICAgICAgc3lzdGVtSWQgPSBTeXN0ZW1JRFJlc29sdmVyLmdldEFic29sdXRlVVJJKHN5c3RlbUlkLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldERvY3VtZW50QmFzZVVSSSgpKTsKLSAgICB9Ci0gICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24oZSk7Ci0gICAgfQotCi0gICAgLy8gIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBFTlRJVFlfRklFTERfUFVCTElDSUQgPSAwOwotICAgIG1fZW50aXRpZXMuYWRkRWxlbWVudChwdWJsaWNJZCk7Ci0KLSAgICAvLyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEVOVElUWV9GSUVMRF9TWVNURU1JRCA9IDE7Ci0gICAgbV9lbnRpdGllcy5hZGRFbGVtZW50KHN5c3RlbUlkKTsKLQotICAgIC8vICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgRU5USVRZX0ZJRUxEX05PVEFUSU9OTkFNRSA9IDI7Ci0gICAgbV9lbnRpdGllcy5hZGRFbGVtZW50KG5vdGF0aW9uTmFtZSk7Ci0KLSAgICAvLyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEVOVElUWV9GSUVMRF9OQU1FID0gMzsKLSAgICBtX2VudGl0aWVzLmFkZEVsZW1lbnQobmFtZSk7Ci0gIH0KLQotICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotICAvLyBJbXBsZW1lbnRhdGlvbiBvZiBDb250ZW50SGFuZGxlciBpbnRlcmZhY2UuCi0gIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0KLSAgLyoqCi0gICAqIFJlY2VpdmUgYSBMb2NhdG9yIG9iamVjdCBmb3IgZG9jdW1lbnQgZXZlbnRzLgotICAgKgotICAgKiA8cD5CeSBkZWZhdWx0LCBkbyBub3RoaW5nLiAgQXBwbGljYXRpb24gd3JpdGVycyBtYXkgb3ZlcnJpZGUgdGhpcwotICAgKiBtZXRob2QgaW4gYSBzdWJjbGFzcyBpZiB0aGV5IHdpc2ggdG8gc3RvcmUgdGhlIGxvY2F0b3IgZm9yIHVzZQotICAgKiB3aXRoIG90aGVyIGRvY3VtZW50IGV2ZW50cy48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBsb2NhdG9yIEEgbG9jYXRvciBmb3IgYWxsIFNBWCBkb2N1bWVudCBldmVudHMuCi0gICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjc2V0RG9jdW1lbnRMb2NhdG9yCi0gICAqIEBzZWUgb3JnLnhtbC5zYXguTG9jYXRvcgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0RG9jdW1lbnRMb2NhdG9yKExvY2F0b3IgbG9jYXRvcikKLSAgewotICAgIG1fbG9jYXRvciA9IGxvY2F0b3I7Ci0gICAgbV9zeXN0ZW1JZCA9IGxvY2F0b3IuZ2V0U3lzdGVtSWQoKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiB0aGUgYmVnaW5uaW5nIG9mIHRoZSBkb2N1bWVudC4KLSAgICoKLSAgICogQHRocm93cyBTQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjc3RhcnREb2N1bWVudAotICAgKi8KLSAgcHVibGljIHZvaWQgc3RhcnREb2N1bWVudCgpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotICAgIGlmIChERUJVRykKLSAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigic3RhcnREb2N1bWVudCIpOwotCi0KLSAgICBpbnQgZG9jID0gYWRkTm9kZShEVE0uRE9DVU1FTlRfTk9ERSwKLSAgICAgICAgICAgICAgICAgICAgICBtX2V4cGFuZGVkTmFtZVRhYmxlLmdldEV4cGFuZGVkVHlwZUlEKERUTS5ET0NVTUVOVF9OT0RFKSwKLSAgICAgICAgICAgICAgICAgICAgICBEVE0uTlVMTCwgRFRNLk5VTEwsIDAsIHRydWUpOwotCi0gICAgbV9wYXJlbnRzLnB1c2goZG9jKTsKLSAgICBtX3ByZXZpb3VzID0gRFRNLk5VTEw7Ci0KLSAgICBtX2NvbnRleHRJbmRleGVzLnB1c2gobV9wcmVmaXhNYXBwaW5ncy5zaXplKCkpOyAgLy8gZm9yIHRoZSBuZXh0IGVsZW1lbnQuCi0gIH0KLQotICAvKioKLSAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIGVuZCBvZiB0aGUgZG9jdW1lbnQuCi0gICAqCi0gICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI2VuZERvY3VtZW50Ci0gICAqLwotICBwdWJsaWMgdm9pZCBlbmREb2N1bWVudCgpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotICAgIGlmIChERUJVRykKLSAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiZW5kRG9jdW1lbnQiKTsKLQotICAgICAgICAgICAgICAgIGNoYXJhY3RlcnNGbHVzaCgpOwotCi0gICAgbV9uZXh0c2liLnNldEVsZW1lbnRBdChOVUxMLDApOwotCi0gICAgaWYgKG1fZmlyc3RjaC5lbGVtZW50QXQoMCkgPT0gTk9UUFJPQ0VTU0VEKQotICAgICAgbV9maXJzdGNoLnNldEVsZW1lbnRBdChOVUxMLDApOwotCi0gICAgaWYgKERUTS5OVUxMICE9IG1fcHJldmlvdXMpCi0gICAgICBtX25leHRzaWIuc2V0RWxlbWVudEF0KERUTS5OVUxMLG1fcHJldmlvdXMpOwotCi0gICAgbV9wYXJlbnRzID0gbnVsbDsKLSAgICBtX3ByZWZpeE1hcHBpbmdzID0gbnVsbDsKLSAgICBtX2NvbnRleHRJbmRleGVzID0gbnVsbDsKLQotICAgIG1fZW5kRG9jdW1lbnRPY2N1cmVkID0gdHJ1ZTsKLQotICAgIC8vIEJ1Z3ppbGxhIDQ4NTg6IHRocm93IGF3YXkgbV9sb2NhdG9yLiB3ZSBjYWNoZSBtX3N5c3RlbUlkCi0gICAgbV9sb2NhdG9yID0gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiB0aGUgc3RhcnQgb2YgYSBOYW1lc3BhY2UgbWFwcGluZy4KLSAgICoKLSAgICogPHA+QnkgZGVmYXVsdCwgZG8gbm90aGluZy4gIEFwcGxpY2F0aW9uIHdyaXRlcnMgbWF5IG92ZXJyaWRlIHRoaXMKLSAgICogbWV0aG9kIGluIGEgc3ViY2xhc3MgdG8gdGFrZSBzcGVjaWZpYyBhY3Rpb25zIGF0IHRoZSBzdGFydCBvZgotICAgKiBlYWNoIE5hbWVzcGFjZSBwcmVmaXggc2NvcGUgKHN1Y2ggYXMgc3RvcmluZyB0aGUgcHJlZml4IG1hcHBpbmcpLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIHByZWZpeCBUaGUgTmFtZXNwYWNlIHByZWZpeCBiZWluZyBkZWNsYXJlZC4KLSAgICogQHBhcmFtIHVyaSBUaGUgTmFtZXNwYWNlIFVSSSBtYXBwZWQgdG8gdGhlIHByZWZpeC4KLSAgICogQHRocm93cyBTQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjc3RhcnRQcmVmaXhNYXBwaW5nCi0gICAqLwotICBwdWJsaWMgdm9pZCBzdGFydFByZWZpeE1hcHBpbmcoU3RyaW5nIHByZWZpeCwgU3RyaW5nIHVyaSkKLSAgICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChERUJVRykKLSAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigic3RhcnRQcmVmaXhNYXBwaW5nOiBwcmVmaXg6ICIgKyBwcmVmaXggKyAiLCB1cmk6ICIKLSAgICAgICAgICAgICAgICAgICAgICAgICArIHVyaSk7Ci0KLSAgICBpZihudWxsID09IHByZWZpeCkKLSAgICAgIHByZWZpeCA9ICIiOwotICAgIG1fcHJlZml4TWFwcGluZ3MuYWRkRWxlbWVudChwcmVmaXgpOyAgLy8gSkRLIDEuMS54IGNvbXBhdCAtc2MKLSAgICBtX3ByZWZpeE1hcHBpbmdzLmFkZEVsZW1lbnQodXJpKTsgIC8vIEpESyAxLjEueCBjb21wYXQgLXNjCi0gIH0KLQotICAvKioKLSAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIGVuZCBvZiBhIE5hbWVzcGFjZSBtYXBwaW5nLgotICAgKgotICAgKiA8cD5CeSBkZWZhdWx0LCBkbyBub3RoaW5nLiAgQXBwbGljYXRpb24gd3JpdGVycyBtYXkgb3ZlcnJpZGUgdGhpcwotICAgKiBtZXRob2QgaW4gYSBzdWJjbGFzcyB0byB0YWtlIHNwZWNpZmljIGFjdGlvbnMgYXQgdGhlIGVuZCBvZgotICAgKiBlYWNoIHByZWZpeCBtYXBwaW5nLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIHByZWZpeCBUaGUgTmFtZXNwYWNlIHByZWZpeCBiZWluZyBkZWNsYXJlZC4KLSAgICogQHRocm93cyBTQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjZW5kUHJlZml4TWFwcGluZwotICAgKi8KLSAgcHVibGljIHZvaWQgZW5kUHJlZml4TWFwcGluZyhTdHJpbmcgcHJlZml4KSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBpZiAoREVCVUcpCi0gICAgICBTeXN0ZW0ub3V0LnByaW50bG4oImVuZFByZWZpeE1hcHBpbmc6IHByZWZpeDogIiArIHByZWZpeCk7Ci0KLSAgICBpZihudWxsID09IHByZWZpeCkKLSAgICAgIHByZWZpeCA9ICIiOwotCi0gICAgaW50IGluZGV4ID0gbV9jb250ZXh0SW5kZXhlcy5wZWVrKCkgLSAxOwotCi0gICAgZG8KLSAgICB7Ci0gICAgICBpbmRleCA9IG1fcHJlZml4TWFwcGluZ3MuaW5kZXhPZihwcmVmaXgsICsraW5kZXgpOwotICAgIH0gd2hpbGUgKCAoaW5kZXggPj0gMCkgJiYgKChpbmRleCAmIDB4MDEpID09IDB4MDEpICk7Ci0KLQotICAgIGlmIChpbmRleCA+IC0xKQotICAgIHsKLSAgICAgIG1fcHJlZml4TWFwcGluZ3Muc2V0RWxlbWVudEF0KCIlQCQjXkAjIiwgaW5kZXgpOwotICAgICAgbV9wcmVmaXhNYXBwaW5ncy5zZXRFbGVtZW50QXQoIiVAJCNeQCMiLCBpbmRleCArIDEpOwotICAgIH0KLQotICAgIC8vIG5vIG9wCi0gIH0KLQotICAvKioKLSAgICogQ2hlY2sgaWYgYSBkZWNsYXJhdGlvbiBoYXMgYWxyZWFkeSBiZWVuIG1hZGUgZm9yIGEgZ2l2ZW4gcHJlZml4LgotICAgKgotICAgKiBAcGFyYW0gcHJlZml4IG5vbi1udWxsIHByZWZpeCBzdHJpbmcuCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgZGVjbGFyYXRpb24gaGFzIGFscmVhZHkgYmVlbiBkZWNsYXJlZCBpbiB0aGUKLSAgICogICAgICAgICBjdXJyZW50IGNvbnRleHQuCi0gICAqLwotICBwcm90ZWN0ZWQgYm9vbGVhbiBkZWNsQWxyZWFkeURlY2xhcmVkKFN0cmluZyBwcmVmaXgpCi0gIHsKLQotICAgIGludCBzdGFydERlY2xzID0gbV9jb250ZXh0SW5kZXhlcy5wZWVrKCk7Ci0gICAgamF2YS51dGlsLlZlY3RvciBwcmVmaXhNYXBwaW5ncyA9IG1fcHJlZml4TWFwcGluZ3M7Ci0gICAgaW50IG5EZWNscyA9IHByZWZpeE1hcHBpbmdzLnNpemUoKTsKLQotICAgIGZvciAoaW50IGkgPSBzdGFydERlY2xzOyBpIDwgbkRlY2xzOyBpICs9IDIpCi0gICAgewotICAgICAgU3RyaW5nIHByZWZpeERlY2wgPSAoU3RyaW5nKSBwcmVmaXhNYXBwaW5ncy5lbGVtZW50QXQoaSk7Ci0KLSAgICAgIGlmIChwcmVmaXhEZWNsID09IG51bGwpCi0gICAgICAgIGNvbnRpbnVlOwotCi0gICAgICBpZiAocHJlZml4RGVjbC5lcXVhbHMocHJlZml4KSkKLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotCi0gICAgcmV0dXJuIGZhbHNlOwotICB9Ci0KLSAgICAgICAgYm9vbGVhbiBtX3Bhc3RGaXJzdEVsZW1lbnQ9ZmFsc2U7Ci0KLSAgLyoqCi0gICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIHRoZSBzdGFydCBvZiBhbiBlbGVtZW50LgotICAgKgotICAgKiA8cD5CeSBkZWZhdWx0LCBkbyBub3RoaW5nLiAgQXBwbGljYXRpb24gd3JpdGVycyBtYXkgb3ZlcnJpZGUgdGhpcwotICAgKiBtZXRob2QgaW4gYSBzdWJjbGFzcyB0byB0YWtlIHNwZWNpZmljIGFjdGlvbnMgYXQgdGhlIHN0YXJ0IG9mCi0gICAqIGVhY2ggZWxlbWVudCAoc3VjaCBhcyBhbGxvY2F0aW5nIGEgbmV3IHRyZWUgbm9kZSBvciB3cml0aW5nCi0gICAqIG91dHB1dCB0byBhIGZpbGUpLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIHVyaSBUaGUgTmFtZXNwYWNlIFVSSSwgb3IgdGhlIGVtcHR5IHN0cmluZyBpZiB0aGUKLSAgICogICAgICAgIGVsZW1lbnQgaGFzIG5vIE5hbWVzcGFjZSBVUkkgb3IgaWYgTmFtZXNwYWNlCi0gICAqICAgICAgICBwcm9jZXNzaW5nIGlzIG5vdCBiZWluZyBwZXJmb3JtZWQuCi0gICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGxvY2FsIG5hbWUgKHdpdGhvdXQgcHJlZml4KSwgb3IgdGhlCi0gICAqICAgICAgICBlbXB0eSBzdHJpbmcgaWYgTmFtZXNwYWNlIHByb2Nlc3NpbmcgaXMgbm90IGJlaW5nCi0gICAqICAgICAgICBwZXJmb3JtZWQuCi0gICAqIEBwYXJhbSBxTmFtZSBUaGUgcXVhbGlmaWVkIG5hbWUgKHdpdGggcHJlZml4KSwgb3IgdGhlCi0gICAqICAgICAgICBlbXB0eSBzdHJpbmcgaWYgcXVhbGlmaWVkIG5hbWVzIGFyZSBub3QgYXZhaWxhYmxlLgotICAgKiBAcGFyYW0gYXR0cmlidXRlcyBUaGUgc3BlY2lmaWVkIG9yIGRlZmF1bHRlZCBhdHRyaWJ1dGVzLgotICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNzdGFydEVsZW1lbnQKLSAgICovCi0gIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudCgKLSAgICAgICAgICBTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxOYW1lLCBTdHJpbmcgcU5hbWUsIEF0dHJpYnV0ZXMgYXR0cmlidXRlcykKLSAgICAgICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotICAgaWYgKERFQlVHKQotICAgICAgICAgewotICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJzdGFydEVsZW1lbnQ6IHVyaTogIiArIHVyaSArICIsIGxvY2FsbmFtZTogIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgbG9jYWxOYW1lICsgIiwgcW5hbWU6ICIrcU5hbWUrIiwgYXR0czogIiArIGF0dHJpYnV0ZXMpOwotCi0gICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIERFQlVHX0FUVFJTPXRydWU7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZihERUJVR19BVFRSUyAmIGF0dHJpYnV0ZXMhPW51bGwpCi0gICAgICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBuID0gYXR0cmlidXRlcy5nZXRMZW5ndGgoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYobj09MCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlx0ZW1wdHkgYXR0cmlidXRlIGxpc3QiKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlx0IGF0dHI6IHVyaTogIiArIGF0dHJpYnV0ZXMuZ2V0VVJJKGkpICsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiwgbG9jYWxuYW1lOiAiICsgYXR0cmlidXRlcy5nZXRMb2NhbE5hbWUoaSkgKwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiLCBxbmFtZTogIiArIGF0dHJpYnV0ZXMuZ2V0UU5hbWUoaSkgKwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiLCB0eXBlOiAiICsgYXR0cmlidXRlcy5nZXRUeXBlKGkpICsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiwgdmFsdWU6ICIgKyBhdHRyaWJ1dGVzLmdldFZhbHVlKGkpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICB9Ci0KLSAgICBjaGFyYWN0ZXJzRmx1c2goKTsKLQotICAgIGludCBleE5hbWUgPSBtX2V4cGFuZGVkTmFtZVRhYmxlLmdldEV4cGFuZGVkVHlwZUlEKHVyaSwgbG9jYWxOYW1lLCBEVE0uRUxFTUVOVF9OT0RFKTsKLSAgICBTdHJpbmcgcHJlZml4ID0gZ2V0UHJlZml4KHFOYW1lLCB1cmkpOwotICAgIGludCBwcmVmaXhJbmRleCA9IChudWxsICE9IHByZWZpeCkKLSAgICAgICAgICAgICAgICAgICAgICA/IG1fdmFsdWVzT3JQcmVmaXhlcy5zdHJpbmdUb0luZGV4KHFOYW1lKSA6IDA7Ci0KLSAgICBpbnQgZWxlbU5vZGUgPSBhZGROb2RlKERUTS5FTEVNRU5UX05PREUsIGV4TmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fcGFyZW50cy5wZWVrKCksIG1fcHJldmlvdXMsIHByZWZpeEluZGV4LCB0cnVlKTsKLQotICAgIGlmKG1faW5kZXhpbmcpCi0gICAgICBpbmRleE5vZGUoZXhOYW1lLCBlbGVtTm9kZSk7Ci0KLQotICAgIG1fcGFyZW50cy5wdXNoKGVsZW1Ob2RlKTsKLQotICAgIGludCBzdGFydERlY2xzID0gbV9jb250ZXh0SW5kZXhlcy5wZWVrKCk7Ci0gICAgaW50IG5EZWNscyA9IG1fcHJlZml4TWFwcGluZ3Muc2l6ZSgpOwotICAgIGludCBwcmV2ID0gRFRNLk5VTEw7Ci0KLSAgICBpZighbV9wYXN0Rmlyc3RFbGVtZW50KQotICAgIHsKLSAgICAgIC8vIFNQRUNJQUwgQ0FTRTogSW1wbGllZCBkZWNsYXJhdGlvbiBhdCByb290IGVsZW1lbnQKLSAgICAgIHByZWZpeD0ieG1sIjsKLSAgICAgIFN0cmluZyBkZWNsVVJMID0gImh0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZSI7Ci0gICAgICBleE5hbWUgPSBtX2V4cGFuZGVkTmFtZVRhYmxlLmdldEV4cGFuZGVkVHlwZUlEKG51bGwsIHByZWZpeCwgRFRNLk5BTUVTUEFDRV9OT0RFKTsKLSAgICAgIGludCB2YWwgPSBtX3ZhbHVlc09yUHJlZml4ZXMuc3RyaW5nVG9JbmRleChkZWNsVVJMKTsKLSAgICAgIHByZXYgPSBhZGROb2RlKERUTS5OQU1FU1BBQ0VfTk9ERSwgZXhOYW1lLCBlbGVtTm9kZSwKLSAgICAgICAgICAgICAgICAgICAgIHByZXYsIHZhbCwgZmFsc2UpOwotICAgICAgbV9wYXN0Rmlyc3RFbGVtZW50PXRydWU7Ci0gICAgfQotCi0gICAgZm9yIChpbnQgaSA9IHN0YXJ0RGVjbHM7IGkgPCBuRGVjbHM7IGkgKz0gMikKLSAgICB7Ci0gICAgICBwcmVmaXggPSAoU3RyaW5nKSBtX3ByZWZpeE1hcHBpbmdzLmVsZW1lbnRBdChpKTsKLQotICAgICAgaWYgKHByZWZpeCA9PSBudWxsKQotICAgICAgICBjb250aW51ZTsKLQotICAgICAgU3RyaW5nIGRlY2xVUkwgPSAoU3RyaW5nKSBtX3ByZWZpeE1hcHBpbmdzLmVsZW1lbnRBdChpICsgMSk7Ci0KLSAgICAgIGV4TmFtZSA9IG1fZXhwYW5kZWROYW1lVGFibGUuZ2V0RXhwYW5kZWRUeXBlSUQobnVsbCwgcHJlZml4LCBEVE0uTkFNRVNQQUNFX05PREUpOwotCi0gICAgICBpbnQgdmFsID0gbV92YWx1ZXNPclByZWZpeGVzLnN0cmluZ1RvSW5kZXgoZGVjbFVSTCk7Ci0KLSAgICAgIHByZXYgPSBhZGROb2RlKERUTS5OQU1FU1BBQ0VfTk9ERSwgZXhOYW1lLCBlbGVtTm9kZSwKLSAgICAgICAgICAgICAgICAgICAgIHByZXYsIHZhbCwgZmFsc2UpOwotICAgIH0KLQotICAgIGludCBuID0gYXR0cmlidXRlcy5nZXRMZW5ndGgoKTsKLQotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKQotICAgIHsKLSAgICAgIFN0cmluZyBhdHRyVXJpID0gYXR0cmlidXRlcy5nZXRVUkkoaSk7Ci0gICAgICBTdHJpbmcgYXR0clFOYW1lID0gYXR0cmlidXRlcy5nZXRRTmFtZShpKTsKLSAgICAgIFN0cmluZyB2YWxTdHJpbmcgPSBhdHRyaWJ1dGVzLmdldFZhbHVlKGkpOwotCi0gICAgICBwcmVmaXggPSBnZXRQcmVmaXgoYXR0clFOYW1lLCBhdHRyVXJpKTsKLQotICAgICAgaW50IG5vZGVUeXBlOwotCi0gICAgICAgU3RyaW5nIGF0dHJMb2NhbE5hbWUgPSBhdHRyaWJ1dGVzLmdldExvY2FsTmFtZShpKTsKLQotICAgICAgaWYgKChudWxsICE9IGF0dHJRTmFtZSkKLSAgICAgICAgICAgICAgJiYgKGF0dHJRTmFtZS5lcXVhbHMoInhtbG5zIikKLSAgICAgICAgICAgICAgICAgIHx8IGF0dHJRTmFtZS5zdGFydHNXaXRoKCJ4bWxuczoiKSkpCi0gICAgICB7Ci0gICAgICAgIGlmIChkZWNsQWxyZWFkeURlY2xhcmVkKHByZWZpeCkpCi0gICAgICAgICAgY29udGludWU7ICAvLyBnbyB0byB0aGUgbmV4dCBhdHRyaWJ1dGUuCi0KLSAgICAgICAgbm9kZVR5cGUgPSBEVE0uTkFNRVNQQUNFX05PREU7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIG5vZGVUeXBlID0gRFRNLkFUVFJJQlVURV9OT0RFOwotCi0gICAgICAgIGlmIChhdHRyaWJ1dGVzLmdldFR5cGUoaSkuZXF1YWxzSWdub3JlQ2FzZSgiSUQiKSkKLSAgICAgICAgICBzZXRJREF0dHJpYnV0ZSh2YWxTdHJpbmcsIGVsZW1Ob2RlKTsKLSAgICAgIH0KLQotICAgICAgLy8gQml0IG9mIGEgaGFjay4uLiBpZiBzb21laG93IHZhbFN0cmluZyBpcyBudWxsLCBzdHJpbmdUb0luZGV4IHdpbGwKLSAgICAgIC8vIHJldHVybiAtMSwgd2hpY2ggd2lsbCBtYWtlIHRoaW5ncyB2ZXJ5IHVuaGFwcHkuCi0gICAgICBpZihudWxsID09IHZhbFN0cmluZykKLSAgICAgICAgdmFsU3RyaW5nID0gIiI7Ci0KLSAgICAgIGludCB2YWwgPSBtX3ZhbHVlc09yUHJlZml4ZXMuc3RyaW5nVG9JbmRleCh2YWxTdHJpbmcpOwotICAgICAgLy9TdHJpbmcgYXR0ckxvY2FsTmFtZSA9IGF0dHJpYnV0ZXMuZ2V0TG9jYWxOYW1lKGkpOwotCi0gICAgICBpZiAobnVsbCAhPSBwcmVmaXgpCi0gICAgICB7Ci0KLSAgICAgICAgcHJlZml4SW5kZXggPSBtX3ZhbHVlc09yUHJlZml4ZXMuc3RyaW5nVG9JbmRleChhdHRyUU5hbWUpOwotCi0gICAgICAgIGludCBkYXRhSW5kZXggPSBtX2RhdGEuc2l6ZSgpOwotCi0gICAgICAgIG1fZGF0YS5hZGRFbGVtZW50KHByZWZpeEluZGV4KTsKLSAgICAgICAgbV9kYXRhLmFkZEVsZW1lbnQodmFsKTsKLQotICAgICAgICB2YWwgPSAtZGF0YUluZGV4OwotICAgICAgfQotCi0gICAgICBleE5hbWUgPSBtX2V4cGFuZGVkTmFtZVRhYmxlLmdldEV4cGFuZGVkVHlwZUlEKGF0dHJVcmksIGF0dHJMb2NhbE5hbWUsIG5vZGVUeXBlKTsKLSAgICAgIHByZXYgPSBhZGROb2RlKG5vZGVUeXBlLCBleE5hbWUsIGVsZW1Ob2RlLCBwcmV2LCB2YWwsCi0gICAgICAgICAgICAgICAgICAgICBmYWxzZSk7Ci0gICAgfQotCi0gICAgaWYgKERUTS5OVUxMICE9IHByZXYpCi0gICAgICBtX25leHRzaWIuc2V0RWxlbWVudEF0KERUTS5OVUxMLHByZXYpOwotCi0gICAgaWYgKG51bGwgIT0gbV93c2ZpbHRlcikKLSAgICB7Ci0gICAgICBzaG9ydCB3c3YgPSBtX3dzZmlsdGVyLmdldFNob3VsZFN0cmlwU3BhY2UobWFrZU5vZGVIYW5kbGUoZWxlbU5vZGUpLCB0aGlzKTsKLSAgICAgIGJvb2xlYW4gc2hvdWxkU3RyaXAgPSAoRFRNV1NGaWx0ZXIuSU5IRVJJVCA9PSB3c3YpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBnZXRTaG91bGRTdHJpcFdoaXRlc3BhY2UoKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogKERUTVdTRmlsdGVyLlNUUklQID09IHdzdik7Ci0KLSAgICAgIHB1c2hTaG91bGRTdHJpcFdoaXRlc3BhY2Uoc2hvdWxkU3RyaXApOwotICAgIH0KLQotICAgIG1fcHJldmlvdXMgPSBEVE0uTlVMTDsKLQotICAgIG1fY29udGV4dEluZGV4ZXMucHVzaChtX3ByZWZpeE1hcHBpbmdzLnNpemUoKSk7ICAvLyBmb3IgdGhlIGNoaWxkcmVuLgotICB9Ci0KLSAgLyoqCi0gICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIHRoZSBlbmQgb2YgYW4gZWxlbWVudC4KLSAgICoKLSAgICogPHA+QnkgZGVmYXVsdCwgZG8gbm90aGluZy4gIEFwcGxpY2F0aW9uIHdyaXRlcnMgbWF5IG92ZXJyaWRlIHRoaXMKLSAgICogbWV0aG9kIGluIGEgc3ViY2xhc3MgdG8gdGFrZSBzcGVjaWZpYyBhY3Rpb25zIGF0IHRoZSBlbmQgb2YKLSAgICogZWFjaCBlbGVtZW50IChzdWNoIGFzIGZpbmFsaXNpbmcgYSB0cmVlIG5vZGUgb3Igd3JpdGluZwotICAgKiBvdXRwdXQgdG8gYSBmaWxlKS48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSB1cmkgVGhlIE5hbWVzcGFjZSBVUkksIG9yIHRoZSBlbXB0eSBzdHJpbmcgaWYgdGhlCi0gICAqICAgICAgICBlbGVtZW50IGhhcyBubyBOYW1lc3BhY2UgVVJJIG9yIGlmIE5hbWVzcGFjZQotICAgKiAgICAgICAgcHJvY2Vzc2luZyBpcyBub3QgYmVpbmcgcGVyZm9ybWVkLgotICAgKiBAcGFyYW0gbG9jYWxOYW1lIFRoZSBsb2NhbCBuYW1lICh3aXRob3V0IHByZWZpeCksIG9yIHRoZQotICAgKiAgICAgICAgZW1wdHkgc3RyaW5nIGlmIE5hbWVzcGFjZSBwcm9jZXNzaW5nIGlzIG5vdCBiZWluZwotICAgKiAgICAgICAgcGVyZm9ybWVkLgotICAgKiBAcGFyYW0gcU5hbWUgVGhlIHF1YWxpZmllZCBYTUwgMS4wIG5hbWUgKHdpdGggcHJlZml4KSwgb3IgdGhlCi0gICAqICAgICAgICBlbXB0eSBzdHJpbmcgaWYgcXVhbGlmaWVkIG5hbWVzIGFyZSBub3QgYXZhaWxhYmxlLgotICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNlbmRFbGVtZW50Ci0gICAqLwotICBwdWJsaWMgdm9pZCBlbmRFbGVtZW50KFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUsIFN0cmluZyBxTmFtZSkKLSAgICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLSAgIGlmIChERUJVRykKLSAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiZW5kRWxlbWVudDogdXJpOiAiICsgdXJpICsgIiwgbG9jYWxuYW1lOiAiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBsb2NhbE5hbWUgKyAiLCBxbmFtZTogIitxTmFtZSk7Ci0KLSAgICBjaGFyYWN0ZXJzRmx1c2goKTsKLQotICAgIC8vIElmIG5vIG9uZSBub3RpY2VkLCBzdGFydFByZWZpeE1hcHBpbmcgaXMgYSBkcmFnLgotICAgIC8vIFBvcCB0aGUgY29udGV4dCBmb3IgdGhlIGxhc3QgY2hpbGQgKHRoZSBvbmUgcHVzaGVkIGJ5IHN0YXJ0RWxlbWVudCkKLSAgICBtX2NvbnRleHRJbmRleGVzLnF1aWNrUG9wKDEpOwotCi0gICAgLy8gRG8gaXQgYWdhaW4gZm9yIHRoaXMgb25lICh0aGUgb25lIHB1c2hlZCBieSB0aGUgbGFzdCBlbmRFbGVtZW50KS4KLSAgICBpbnQgdG9wQ29udGV4dEluZGV4ID0gbV9jb250ZXh0SW5kZXhlcy5wZWVrKCk7Ci0gICAgaWYgKHRvcENvbnRleHRJbmRleCAhPSBtX3ByZWZpeE1hcHBpbmdzLnNpemUoKSkgewotICAgICAgbV9wcmVmaXhNYXBwaW5ncy5zZXRTaXplKHRvcENvbnRleHRJbmRleCk7Ci0gICAgfQotCi0gICAgaW50IGxhc3ROb2RlID0gbV9wcmV2aW91czsKLQotICAgIG1fcHJldmlvdXMgPSBtX3BhcmVudHMucG9wKCk7Ci0KLSAgICAvLyBJZiBsYXN0Tm9kZSBpcyBzdGlsbCBEVE0uTlVMTCwgdGhpcyBlbGVtZW50IGhhZCBubyBjaGlsZHJlbgotICAgIGlmIChEVE0uTlVMTCA9PSBsYXN0Tm9kZSkKLSAgICAgIG1fZmlyc3RjaC5zZXRFbGVtZW50QXQoRFRNLk5VTEwsbV9wcmV2aW91cyk7Ci0gICAgZWxzZQotICAgICAgbV9uZXh0c2liLnNldEVsZW1lbnRBdChEVE0uTlVMTCxsYXN0Tm9kZSk7Ci0KLSAgICBwb3BTaG91bGRTdHJpcFdoaXRlc3BhY2UoKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBjaGFyYWN0ZXIgZGF0YSBpbnNpZGUgYW4gZWxlbWVudC4KLSAgICoKLSAgICogPHA+QnkgZGVmYXVsdCwgZG8gbm90aGluZy4gIEFwcGxpY2F0aW9uIHdyaXRlcnMgbWF5IG92ZXJyaWRlIHRoaXMKLSAgICogbWV0aG9kIHRvIHRha2Ugc3BlY2lmaWMgYWN0aW9ucyBmb3IgZWFjaCBjaHVuayBvZiBjaGFyYWN0ZXIgZGF0YQotICAgKiAoc3VjaCBhcyBhZGRpbmcgdGhlIGRhdGEgdG8gYSBub2RlIG9yIGJ1ZmZlciwgb3IgcHJpbnRpbmcgaXQgdG8KLSAgICogYSBmaWxlKS48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBjaCBUaGUgY2hhcmFjdGVycy4KLSAgICogQHBhcmFtIHN0YXJ0IFRoZSBzdGFydCBwb3NpdGlvbiBpbiB0aGUgY2hhcmFjdGVyIGFycmF5LgotICAgKiBAcGFyYW0gbGVuZ3RoIFRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyB0byB1c2UgZnJvbSB0aGUKLSAgICogICAgICAgICAgICAgICBjaGFyYWN0ZXIgYXJyYXkuCi0gICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI2NoYXJhY3RlcnMKLSAgICovCi0gIHB1YmxpYyB2b2lkIGNoYXJhY3RlcnMoY2hhciBjaFtdLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotICAgIGlmIChtX3RleHRQZW5kaW5nU3RhcnQgPT0gLTEpICAvLyBGaXJzdCBvbmUgaW4gdGhpcyBibG9jawotICAgIHsKLSAgICAgIG1fdGV4dFBlbmRpbmdTdGFydCA9IG1fY2hhcnMuc2l6ZSgpOwotICAgICAgbV9jb2FsZXNjZWRUZXh0VHlwZSA9IG1fdGV4dFR5cGU7Ci0gICAgfQotICAgIC8vIFR5cGUgbG9naWM6IElmIGFsbCBhZGphY2VudCB0ZXh0IGlzIENEQVRBU2VjdGlvbnMsIHRoZQotICAgIC8vIGNvbmNhdGVudGF0ZWQgdGV4dCBpcyB0cmVhdGVkIGFzIGEgc2luZ2xlIENEQVRBU2VjdGlvbiAoc2VlCi0gICAgLy8gaW5pdGlhbGl6YXRpb24gYWJvdmUpLiAgSWYgYW55IHdlcmUgb3JkaW5hcnkgVGV4dCwgdGhlIHdob2xlCi0gICAgLy8gdGhpbmcgaXMgdHJlYXRlZCBhcyBUZXh0LiBUaGlzIG1heSBiZSB3b3J0aCAlUkVWSUVXJWluZy4KLSAgICBlbHNlIGlmIChtX3RleHRUeXBlID09IERUTS5URVhUX05PREUpCi0gICAgewotICAgICAgbV9jb2FsZXNjZWRUZXh0VHlwZSA9IERUTS5URVhUX05PREU7Ci0gICAgfQotCi0gICAgbV9jaGFycy5hcHBlbmQoY2gsIHN0YXJ0LCBsZW5ndGgpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGlnbm9yYWJsZSB3aGl0ZXNwYWNlIGluIGVsZW1lbnQgY29udGVudC4KLSAgICoKLSAgICogPHA+QnkgZGVmYXVsdCwgZG8gbm90aGluZy4gIEFwcGxpY2F0aW9uIHdyaXRlcnMgbWF5IG92ZXJyaWRlIHRoaXMKLSAgICogbWV0aG9kIHRvIHRha2Ugc3BlY2lmaWMgYWN0aW9ucyBmb3IgZWFjaCBjaHVuayBvZiBpZ25vcmFibGUKLSAgICogd2hpdGVzcGFjZSAoc3VjaCBhcyBhZGRpbmcgZGF0YSB0byBhIG5vZGUgb3IgYnVmZmVyLCBvciBwcmludGluZwotICAgKiBpdCB0byBhIGZpbGUpLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIGNoIFRoZSB3aGl0ZXNwYWNlIGNoYXJhY3RlcnMuCi0gICAqIEBwYXJhbSBzdGFydCBUaGUgc3RhcnQgcG9zaXRpb24gaW4gdGhlIGNoYXJhY3RlciBhcnJheS4KLSAgICogQHBhcmFtIGxlbmd0aCBUaGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gdXNlIGZyb20gdGhlCi0gICAqICAgICAgICAgICAgICAgY2hhcmFjdGVyIGFycmF5LgotICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNpZ25vcmFibGVXaGl0ZXNwYWNlCi0gICAqLwotICBwdWJsaWMgdm9pZCBpZ25vcmFibGVXaGl0ZXNwYWNlKGNoYXIgY2hbXSwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKQotICAgICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotCi0gICAgLy8gJU9QVCUgV2UgY2FuIHByb2JhYmx5IHRha2UgYWR2YW50YWdlIG9mIHRoZSBmYWN0IHRoYXQgd2Uga25vdyB0aGlzCi0gICAgLy8gaXMgd2hpdGVzcGFjZS4KLSAgICBjaGFyYWN0ZXJzKGNoLCBzdGFydCwgbGVuZ3RoKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBhIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24uCi0gICAqCi0gICAqIDxwPkJ5IGRlZmF1bHQsIGRvIG5vdGhpbmcuICBBcHBsaWNhdGlvbiB3cml0ZXJzIG1heSBvdmVycmlkZSB0aGlzCi0gICAqIG1ldGhvZCBpbiBhIHN1YmNsYXNzIHRvIHRha2Ugc3BlY2lmaWMgYWN0aW9ucyBmb3IgZWFjaAotICAgKiBwcm9jZXNzaW5nIGluc3RydWN0aW9uLCBzdWNoIGFzIHNldHRpbmcgc3RhdHVzIHZhcmlhYmxlcyBvcgotICAgKiBpbnZva2luZyBvdGhlciBtZXRob2RzLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIHRhcmdldCBUaGUgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiB0YXJnZXQuCi0gICAqIEBwYXJhbSBkYXRhIFRoZSBwcm9jZXNzaW5nIGluc3RydWN0aW9uIGRhdGEsIG9yIG51bGwgaWYKLSAgICogICAgICAgICAgICAgbm9uZSBpcyBzdXBwbGllZC4KLSAgICogQHRocm93cyBTQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjcHJvY2Vzc2luZ0luc3RydWN0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oU3RyaW5nIHRhcmdldCwgU3RyaW5nIGRhdGEpCi0gICAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICB7Ci0gICAgaWYgKERFQlVHKQotICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oInByb2Nlc3NpbmdJbnN0cnVjdGlvbjogdGFyZ2V0OiAiICsgdGFyZ2V0ICsiLCBkYXRhOiAiK2RhdGEpOwotCi0gICAgY2hhcmFjdGVyc0ZsdXNoKCk7Ci0KLSAgICBpbnQgZXhOYW1lID0gbV9leHBhbmRlZE5hbWVUYWJsZS5nZXRFeHBhbmRlZFR5cGVJRChudWxsLCB0YXJnZXQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERUTS5QUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREUpOwotICAgIGludCBkYXRhSW5kZXggPSBtX3ZhbHVlc09yUHJlZml4ZXMuc3RyaW5nVG9JbmRleChkYXRhKTsKLQotICAgIG1fcHJldmlvdXMgPSBhZGROb2RlKERUTS5QUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREUsIGV4TmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICBtX3BhcmVudHMucGVlaygpLCBtX3ByZXZpb3VzLAotICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFJbmRleCwgZmFsc2UpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGEgc2tpcHBlZCBlbnRpdHkuCi0gICAqCi0gICAqIDxwPkJ5IGRlZmF1bHQsIGRvIG5vdGhpbmcuICBBcHBsaWNhdGlvbiB3cml0ZXJzIG1heSBvdmVycmlkZSB0aGlzCi0gICAqIG1ldGhvZCBpbiBhIHN1YmNsYXNzIHRvIHRha2Ugc3BlY2lmaWMgYWN0aW9ucyBmb3IgZWFjaAotICAgKiBwcm9jZXNzaW5nIGluc3RydWN0aW9uLCBzdWNoIGFzIHNldHRpbmcgc3RhdHVzIHZhcmlhYmxlcyBvcgotICAgKiBpbnZva2luZyBvdGhlciBtZXRob2RzLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIHNraXBwZWQgZW50aXR5LgotICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNraXBwZWRFbnRpdHkoU3RyaW5nIG5hbWUpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotCi0gICAgLy8gJVJFVklFVyUgV2hhdCBzaG91bGQgYmUgZG9uZSBoZXJlPwotICAgIC8vIG5vIG9wCi0gIH0KLQotICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotICAvLyBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgRXJyb3JIYW5kbGVyIGludGVyZmFjZS4KLSAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLQotICAvKioKLSAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgYSBwYXJzZXIgd2FybmluZy4KLSAgICoKLSAgICogPHA+VGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gZG9lcyBub3RoaW5nLiAgQXBwbGljYXRpb24gd3JpdGVycwotICAgKiBtYXkgb3ZlcnJpZGUgdGhpcyBtZXRob2QgaW4gYSBzdWJjbGFzcyB0byB0YWtlIHNwZWNpZmljIGFjdGlvbnMKLSAgICogZm9yIGVhY2ggd2FybmluZywgc3VjaCBhcyBpbnNlcnRpbmcgdGhlIG1lc3NhZ2UgaW4gYSBsb2cgZmlsZSBvcgotICAgKiBwcmludGluZyBpdCB0byB0aGUgY29uc29sZS48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBlIFRoZSB3YXJuaW5nIGluZm9ybWF0aW9uIGVuY29kZWQgYXMgYW4gZXhjZXB0aW9uLgotICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICogQHNlZSBvcmcueG1sLnNheC5FcnJvckhhbmRsZXIjd2FybmluZwotICAgKiBAc2VlIG9yZy54bWwuc2F4LlNBWFBhcnNlRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCB3YXJuaW5nKFNBWFBhcnNlRXhjZXB0aW9uIGUpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotCi0gICAgLy8gJVJFVklFVyUgSXMgdGhlcmUgYW55d2F5IHRvIGdldCB0aGUgSkFYUCBlcnJvciBsaXN0ZW5lciBoZXJlPwotICAgIFN5c3RlbS5lcnIucHJpbnRsbihlLmdldE1lc3NhZ2UoKSk7Ci0gIH0KLQotICAvKioKLSAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgYSByZWNvdmVyYWJsZSBwYXJzZXIgZXJyb3IuCi0gICAqCi0gICAqIDxwPlRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIGRvZXMgbm90aGluZy4gIEFwcGxpY2F0aW9uIHdyaXRlcnMKLSAgICogbWF5IG92ZXJyaWRlIHRoaXMgbWV0aG9kIGluIGEgc3ViY2xhc3MgdG8gdGFrZSBzcGVjaWZpYyBhY3Rpb25zCi0gICAqIGZvciBlYWNoIGVycm9yLCBzdWNoIGFzIGluc2VydGluZyB0aGUgbWVzc2FnZSBpbiBhIGxvZyBmaWxlIG9yCi0gICAqIHByaW50aW5nIGl0IHRvIHRoZSBjb25zb2xlLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIGUgVGhlIHdhcm5pbmcgaW5mb3JtYXRpb24gZW5jb2RlZCBhcyBhbiBleGNlcHRpb24uCi0gICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgKiBAc2VlIG9yZy54bWwuc2F4LkVycm9ySGFuZGxlciN3YXJuaW5nCi0gICAqIEBzZWUgb3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGVycm9yKFNBWFBhcnNlRXhjZXB0aW9uIGUpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotICAgIHRocm93IGU7Ci0gIH0KLQotICAvKioKLSAgICogUmVwb3J0IGEgZmF0YWwgWE1MIHBhcnNpbmcgZXJyb3IuCi0gICAqCi0gICAqIDxwPlRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIHRocm93cyBhIFNBWFBhcnNlRXhjZXB0aW9uLgotICAgKiBBcHBsaWNhdGlvbiB3cml0ZXJzIG1heSBvdmVycmlkZSB0aGlzIG1ldGhvZCBpbiBhIHN1YmNsYXNzIGlmCi0gICAqIHRoZXkgbmVlZCB0byB0YWtlIHNwZWNpZmljIGFjdGlvbnMgZm9yIGVhY2ggZmF0YWwgZXJyb3IgKHN1Y2ggYXMKLSAgICogY29sbGVjdGluZyBhbGwgb2YgdGhlIGVycm9ycyBpbnRvIGEgc2luZ2xlIHJlcG9ydCk6IGluIGFueSBjYXNlLAotICAgKiB0aGUgYXBwbGljYXRpb24gbXVzdCBzdG9wIGFsbCByZWd1bGFyIHByb2Nlc3Npbmcgd2hlbiB0aGlzCi0gICAqIG1ldGhvZCBpcyBpbnZva2VkLCBzaW5jZSB0aGUgZG9jdW1lbnQgaXMgbm8gbG9uZ2VyIHJlbGlhYmxlLCBhbmQKLSAgICogdGhlIHBhcnNlciBtYXkgbm8gbG9uZ2VyIHJlcG9ydCBwYXJzaW5nIGV2ZW50cy48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBlIFRoZSBlcnJvciBpbmZvcm1hdGlvbiBlbmNvZGVkIGFzIGFuIGV4Y2VwdGlvbi4KLSAgICogQHRocm93cyBTQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAqIEBzZWUgb3JnLnhtbC5zYXguRXJyb3JIYW5kbGVyI2ZhdGFsRXJyb3IKLSAgICogQHNlZSBvcmcueG1sLnNheC5TQVhQYXJzZUV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgZmF0YWxFcnJvcihTQVhQYXJzZUV4Y2VwdGlvbiBlKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLSAgICB0aHJvdyBlOwotICB9Ci0KLSAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLSAgLy8gSW1wbGVtZW50YXRpb24gb2YgdGhlIERlY2xIYW5kbGVyIGludGVyZmFjZS4KLSAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLQotICAvKioKLSAgICogUmVwb3J0IGFuIGVsZW1lbnQgdHlwZSBkZWNsYXJhdGlvbi4KLSAgICoKLSAgICogPHA+VGhlIGNvbnRlbnQgbW9kZWwgd2lsbCBjb25zaXN0IG9mIHRoZSBzdHJpbmcgIkVNUFRZIiwgdGhlCi0gICAqIHN0cmluZyAiQU5ZIiwgb3IgYSBwYXJlbnRoZXNpc2VkIGdyb3VwLCBvcHRpb25hbGx5IGZvbGxvd2VkCi0gICAqIGJ5IGFuIG9jY3VycmVuY2UgaW5kaWNhdG9yLiAgVGhlIG1vZGVsIHdpbGwgYmUgbm9ybWFsaXplZCBzbwotICAgKiB0aGF0IGFsbCB3aGl0ZXNwYWNlIGlzIHJlbW92ZWQsYW5kIHdpbGwgaW5jbHVkZSB0aGUgZW5jbG9zaW5nCi0gICAqIHBhcmVudGhlc2VzLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIG5hbWUgVGhlIGVsZW1lbnQgdHlwZSBuYW1lLgotICAgKiBAcGFyYW0gbW9kZWwgVGhlIGNvbnRlbnQgbW9kZWwgYXMgYSBub3JtYWxpemVkIHN0cmluZy4KLSAgICogQHRocm93cyBTQVhFeGNlcHRpb24gVGhlIGFwcGxpY2F0aW9uIG1heSByYWlzZSBhbiBleGNlcHRpb24uCi0gICAqLwotICBwdWJsaWMgdm9pZCBlbGVtZW50RGVjbChTdHJpbmcgbmFtZSwgU3RyaW5nIG1vZGVsKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIC8vIG5vIG9wCi0gIH0KLQotICAvKioKLSAgICogUmVwb3J0IGFuIGF0dHJpYnV0ZSB0eXBlIGRlY2xhcmF0aW9uLgotICAgKgotICAgKiA8cD5Pbmx5IHRoZSBlZmZlY3RpdmUgKGZpcnN0KSBkZWNsYXJhdGlvbiBmb3IgYW4gYXR0cmlidXRlIHdpbGwKLSAgICogYmUgcmVwb3J0ZWQuICBUaGUgdHlwZSB3aWxsIGJlIG9uZSBvZiB0aGUgc3RyaW5ncyAiQ0RBVEEiLAotICAgKiAiSUQiLCAiSURSRUYiLCAiSURSRUZTIiwgIk5NVE9LRU4iLCAiTk1UT0tFTlMiLCAiRU5USVRZIiwKLSAgICogIkVOVElUSUVTIiwgb3IgIk5PVEFUSU9OIiwgb3IgYSBwYXJlbnRoZXNpemVkIHRva2VuIGdyb3VwIHdpdGgKLSAgICogdGhlIHNlcGFyYXRvciAifCIgYW5kIGFsbCB3aGl0ZXNwYWNlIHJlbW92ZWQuPC9wPgotICAgKgotICAgKiBAcGFyYW0gZU5hbWUgVGhlIG5hbWUgb2YgdGhlIGFzc29jaWF0ZWQgZWxlbWVudC4KLSAgICogQHBhcmFtIGFOYW1lIFRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUuCi0gICAqIEBwYXJhbSB0eXBlIEEgc3RyaW5nIHJlcHJlc2VudGluZyB0aGUgYXR0cmlidXRlIHR5cGUuCi0gICAqIEBwYXJhbSB2YWx1ZURlZmF1bHQgQSBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBhdHRyaWJ1dGUgZGVmYXVsdAotICAgKiAgICAgICAgKCIjSU1QTElFRCIsICIjUkVRVUlSRUQiLCBvciAiI0ZJWEVEIikgb3IgbnVsbCBpZgotICAgKiAgICAgICAgbm9uZSBvZiB0aGVzZSBhcHBsaWVzLgotICAgKiBAcGFyYW0gdmFsdWUgQSBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBhdHRyaWJ1dGUncyBkZWZhdWx0IHZhbHVlLAotICAgKiAgICAgICAgb3IgbnVsbCBpZiB0aGVyZSBpcyBub25lLgotICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBUaGUgYXBwbGljYXRpb24gbWF5IHJhaXNlIGFuIGV4Y2VwdGlvbi4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGF0dHJpYnV0ZURlY2woCi0gICAgICAgICAgU3RyaW5nIGVOYW1lLCBTdHJpbmcgYU5hbWUsIFN0cmluZyB0eXBlLCBTdHJpbmcgdmFsdWVEZWZhdWx0LCBTdHJpbmcgdmFsdWUpCi0gICAgICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIC8vIG5vIG9wCi0gIH0KLQotICAvKioKLSAgICogUmVwb3J0IGFuIGludGVybmFsIGVudGl0eSBkZWNsYXJhdGlvbi4KLSAgICoKLSAgICogPHA+T25seSB0aGUgZWZmZWN0aXZlIChmaXJzdCkgZGVjbGFyYXRpb24gZm9yIGVhY2ggZW50aXR5Ci0gICAqIHdpbGwgYmUgcmVwb3J0ZWQuPC9wPgotICAgKgotICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgZW50aXR5LiAgSWYgaXQgaXMgYSBwYXJhbWV0ZXIKLSAgICogICAgICAgIGVudGl0eSwgdGhlIG5hbWUgd2lsbCBiZWdpbiB3aXRoICclJy4KLSAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBsYWNlbWVudCB0ZXh0IG9mIHRoZSBlbnRpdHkuCi0gICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uIFRoZSBhcHBsaWNhdGlvbiBtYXkgcmFpc2UgYW4gZXhjZXB0aW9uLgotICAgKiBAc2VlICNleHRlcm5hbEVudGl0eURlY2wKLSAgICogQHNlZSBvcmcueG1sLnNheC5EVERIYW5kbGVyI3VucGFyc2VkRW50aXR5RGVjbAotICAgKi8KLSAgcHVibGljIHZvaWQgaW50ZXJuYWxFbnRpdHlEZWNsKFN0cmluZyBuYW1lLCBTdHJpbmcgdmFsdWUpCi0gICAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICAvLyBubyBvcAotICB9Ci0KLSAgLyoqCi0gICAqIFJlcG9ydCBhIHBhcnNlZCBleHRlcm5hbCBlbnRpdHkgZGVjbGFyYXRpb24uCi0gICAqCi0gICAqIDxwPk9ubHkgdGhlIGVmZmVjdGl2ZSAoZmlyc3QpIGRlY2xhcmF0aW9uIGZvciBlYWNoIGVudGl0eQotICAgKiB3aWxsIGJlIHJlcG9ydGVkLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGVudGl0eS4gIElmIGl0IGlzIGEgcGFyYW1ldGVyCi0gICAqICAgICAgICBlbnRpdHksIHRoZSBuYW1lIHdpbGwgYmVnaW4gd2l0aCAnJScuCi0gICAqIEBwYXJhbSBwdWJsaWNJZCBUaGUgZGVjbGFyZWQgcHVibGljIGlkZW50aWZpZXIgb2YgdGhlIGVudGl0eSwgb3IKLSAgICogICAgICAgIG51bGwgaWYgbm9uZSB3YXMgZGVjbGFyZWQuCi0gICAqIEBwYXJhbSBzeXN0ZW1JZCBUaGUgZGVjbGFyZWQgc3lzdGVtIGlkZW50aWZpZXIgb2YgdGhlIGVudGl0eS4KLSAgICogQHRocm93cyBTQVhFeGNlcHRpb24gVGhlIGFwcGxpY2F0aW9uIG1heSByYWlzZSBhbiBleGNlcHRpb24uCi0gICAqIEBzZWUgI2ludGVybmFsRW50aXR5RGVjbAotICAgKiBAc2VlIG9yZy54bWwuc2F4LkRUREhhbmRsZXIjdW5wYXJzZWRFbnRpdHlEZWNsCi0gICAqLwotICBwdWJsaWMgdm9pZCBleHRlcm5hbEVudGl0eURlY2woCi0gICAgICAgICAgU3RyaW5nIG5hbWUsIFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIC8vIG5vIG9wCi0gIH0KLQotICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotICAvLyBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgTGV4aWNhbEhhbmRsZXIgaW50ZXJmYWNlLgotICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotCi0gIC8qKgotICAgKiBSZXBvcnQgdGhlIHN0YXJ0IG9mIERURCBkZWNsYXJhdGlvbnMsIGlmIGFueS4KLSAgICoKLSAgICogPHA+QW55IGRlY2xhcmF0aW9ucyBhcmUgYXNzdW1lZCB0byBiZSBpbiB0aGUgaW50ZXJuYWwgc3Vic2V0Ci0gICAqIHVubGVzcyBvdGhlcndpc2UgaW5kaWNhdGVkIGJ5IGEge0BsaW5rICNzdGFydEVudGl0eSBzdGFydEVudGl0eX0KLSAgICogZXZlbnQuPC9wPgotICAgKgotICAgKiA8cD5Ob3RlIHRoYXQgdGhlIHN0YXJ0L2VuZERURCBldmVudHMgd2lsbCBhcHBlYXIgd2l0aGluCi0gICAqIHRoZSBzdGFydC9lbmREb2N1bWVudCBldmVudHMgZnJvbSBDb250ZW50SGFuZGxlciBhbmQKLSAgICogYmVmb3JlIHRoZSBmaXJzdCBzdGFydEVsZW1lbnQgZXZlbnQuPC9wPgotICAgKgotICAgKiBAcGFyYW0gbmFtZSBUaGUgZG9jdW1lbnQgdHlwZSBuYW1lLgotICAgKiBAcGFyYW0gcHVibGljSWQgVGhlIGRlY2xhcmVkIHB1YmxpYyBpZGVudGlmaWVyIGZvciB0aGUKLSAgICogICAgICAgIGV4dGVybmFsIERURCBzdWJzZXQsIG9yIG51bGwgaWYgbm9uZSB3YXMgZGVjbGFyZWQuCi0gICAqIEBwYXJhbSBzeXN0ZW1JZCBUaGUgZGVjbGFyZWQgc3lzdGVtIGlkZW50aWZpZXIgZm9yIHRoZQotICAgKiAgICAgICAgZXh0ZXJuYWwgRFREIHN1YnNldCwgb3IgbnVsbCBpZiBub25lIHdhcyBkZWNsYXJlZC4KLSAgICogQHRocm93cyBTQVhFeGNlcHRpb24gVGhlIGFwcGxpY2F0aW9uIG1heSByYWlzZSBhbgotICAgKiAgICAgICAgICAgIGV4Y2VwdGlvbi4KLSAgICogQHNlZSAjZW5kRFRECi0gICAqIEBzZWUgI3N0YXJ0RW50aXR5Ci0gICAqLwotICBwdWJsaWMgdm9pZCBzdGFydERURChTdHJpbmcgbmFtZSwgU3RyaW5nIHB1YmxpY0lkLCBTdHJpbmcgc3lzdGVtSWQpCi0gICAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICBtX2luc2lkZURURCA9IHRydWU7Ci0gIH0KLQotICAvKioKLSAgICogUmVwb3J0IHRoZSBlbmQgb2YgRFREIGRlY2xhcmF0aW9ucy4KLSAgICoKLSAgICogQHRocm93cyBTQVhFeGNlcHRpb24gVGhlIGFwcGxpY2F0aW9uIG1heSByYWlzZSBhbiBleGNlcHRpb24uCi0gICAqIEBzZWUgI3N0YXJ0RFRECi0gICAqLwotICBwdWJsaWMgdm9pZCBlbmREVEQoKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIG1faW5zaWRlRFREID0gZmFsc2U7Ci0gIH0KLQotICAvKioKLSAgICogUmVwb3J0IHRoZSBiZWdpbm5pbmcgb2YgYW4gZW50aXR5IGluIGNvbnRlbnQuCi0gICAqCi0gICAqIDxwPjxzdHJvbmc+Tk9URTo8L2VudGl0eT4gZW50aXR5IHJlZmVyZW5jZXMgaW4gYXR0cmlidXRlCi0gICAqIHZhbHVlcyAtLSBhbmQgdGhlIHN0YXJ0IGFuZCBlbmQgb2YgdGhlIGRvY3VtZW50IGVudGl0eSAtLQotICAgKiBhcmUgbmV2ZXIgcmVwb3J0ZWQuPC9wPgotICAgKgotICAgKiA8cD5UaGUgc3RhcnQgYW5kIGVuZCBvZiB0aGUgZXh0ZXJuYWwgRFREIHN1YnNldCBhcmUgcmVwb3J0ZWQKLSAgICogdXNpbmcgdGhlIHBzZXVkby1uYW1lICJbZHRkXSIuICBBbGwgb3RoZXIgZXZlbnRzIG11c3QgYmUKLSAgICogcHJvcGVybHkgbmVzdGVkIHdpdGhpbiBzdGFydC9lbmQgZW50aXR5IGV2ZW50cy48L3A+Ci0gICAqCi0gICAqIDxwPk5vdGUgdGhhdCBza2lwcGVkIGVudGl0aWVzIHdpbGwgYmUgcmVwb3J0ZWQgdGhyb3VnaCB0aGUKLSAgICoge0BsaW5rIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI3NraXBwZWRFbnRpdHkgc2tpcHBlZEVudGl0eX0KLSAgICogZXZlbnQsIHdoaWNoIGlzIHBhcnQgb2YgdGhlIENvbnRlbnRIYW5kbGVyIGludGVyZmFjZS48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBlbnRpdHkuICBJZiBpdCBpcyBhIHBhcmFtZXRlcgotICAgKiAgICAgICAgZW50aXR5LCB0aGUgbmFtZSB3aWxsIGJlZ2luIHdpdGggJyUnLgotICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBUaGUgYXBwbGljYXRpb24gbWF5IHJhaXNlIGFuIGV4Y2VwdGlvbi4KLSAgICogQHNlZSAjZW5kRW50aXR5Ci0gICAqIEBzZWUgb3JnLnhtbC5zYXguZXh0LkRlY2xIYW5kbGVyI2ludGVybmFsRW50aXR5RGVjbAotICAgKiBAc2VlIG9yZy54bWwuc2F4LmV4dC5EZWNsSGFuZGxlciNleHRlcm5hbEVudGl0eURlY2wKLSAgICovCi0gIHB1YmxpYyB2b2lkIHN0YXJ0RW50aXR5KFN0cmluZyBuYW1lKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIC8vIG5vIG9wCi0gIH0KLQotICAvKioKLSAgICogUmVwb3J0IHRoZSBlbmQgb2YgYW4gZW50aXR5LgotICAgKgotICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgZW50aXR5IHRoYXQgaXMgZW5kaW5nLgotICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBUaGUgYXBwbGljYXRpb24gbWF5IHJhaXNlIGFuIGV4Y2VwdGlvbi4KLSAgICogQHNlZSAjc3RhcnRFbnRpdHkKLSAgICovCi0gIHB1YmxpYyB2b2lkIGVuZEVudGl0eShTdHJpbmcgbmFtZSkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICAvLyBubyBvcAotICB9Ci0KLSAgLyoqCi0gICAqIFJlcG9ydCB0aGUgc3RhcnQgb2YgYSBDREFUQSBzZWN0aW9uLgotICAgKgotICAgKiA8cD5UaGUgY29udGVudHMgb2YgdGhlIENEQVRBIHNlY3Rpb24gd2lsbCBiZSByZXBvcnRlZCB0aHJvdWdoCi0gICAqIHRoZSByZWd1bGFyIHtAbGluayBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNjaGFyYWN0ZXJzCi0gICAqIGNoYXJhY3RlcnN9IGV2ZW50LjwvcD4KLSAgICoKLSAgICogQHRocm93cyBTQVhFeGNlcHRpb24gVGhlIGFwcGxpY2F0aW9uIG1heSByYWlzZSBhbiBleGNlcHRpb24uCi0gICAqIEBzZWUgI2VuZENEQVRBCi0gICAqLwotICBwdWJsaWMgdm9pZCBzdGFydENEQVRBKCkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICB7Ci0gICAgbV90ZXh0VHlwZSA9IERUTS5DREFUQV9TRUNUSU9OX05PREU7Ci0gIH0KLQotICAvKioKLSAgICogUmVwb3J0IHRoZSBlbmQgb2YgYSBDREFUQSBzZWN0aW9uLgotICAgKgotICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBUaGUgYXBwbGljYXRpb24gbWF5IHJhaXNlIGFuIGV4Y2VwdGlvbi4KLSAgICogQHNlZSAjc3RhcnRDREFUQQotICAgKi8KLSAgcHVibGljIHZvaWQgZW5kQ0RBVEEoKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBtX3RleHRUeXBlID0gRFRNLlRFWFRfTk9ERTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXBvcnQgYW4gWE1MIGNvbW1lbnQgYW55d2hlcmUgaW4gdGhlIGRvY3VtZW50LgotICAgKgotICAgKiA8cD5UaGlzIGNhbGxiYWNrIHdpbGwgYmUgdXNlZCBmb3IgY29tbWVudHMgaW5zaWRlIG9yIG91dHNpZGUgdGhlCi0gICAqIGRvY3VtZW50IGVsZW1lbnQsIGluY2x1ZGluZyBjb21tZW50cyBpbiB0aGUgZXh0ZXJuYWwgRFRECi0gICAqIHN1YnNldCAoaWYgcmVhZCkuPC9wPgotICAgKgotICAgKiBAcGFyYW0gY2ggQW4gYXJyYXkgaG9sZGluZyB0aGUgY2hhcmFjdGVycyBpbiB0aGUgY29tbWVudC4KLSAgICogQHBhcmFtIHN0YXJ0IFRoZSBzdGFydGluZyBwb3NpdGlvbiBpbiB0aGUgYXJyYXkuCi0gICAqIEBwYXJhbSBsZW5ndGggVGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHVzZSBmcm9tIHRoZSBhcnJheS4KLSAgICogQHRocm93cyBTQVhFeGNlcHRpb24gVGhlIGFwcGxpY2F0aW9uIG1heSByYWlzZSBhbiBleGNlcHRpb24uCi0gICAqLwotICBwdWJsaWMgdm9pZCBjb21tZW50KGNoYXIgY2hbXSwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChtX2luc2lkZURURCkgICAgICAvLyBpZ25vcmUgY29tbWVudHMgaWYgd2UncmUgaW5zaWRlIHRoZSBEVEQKLSAgICAgIHJldHVybjsKLQotICAgIGNoYXJhY3RlcnNGbHVzaCgpOwotCi0gICAgaW50IGV4TmFtZSA9IG1fZXhwYW5kZWROYW1lVGFibGUuZ2V0RXhwYW5kZWRUeXBlSUQoRFRNLkNPTU1FTlRfTk9ERSk7Ci0KLSAgICAvLyBGb3Igbm93LCB0cmVhdCBjb21tZW50cyBhcyBzdHJpbmdzLi4uICBJIGd1ZXNzIHdlIHNob3VsZCBkbyBhCi0gICAgLy8gc2VwZXJhdGUgRlNCIGJ1ZmZlciBpbnN0ZWFkLgotICAgIGludCBkYXRhSW5kZXggPSBtX3ZhbHVlc09yUHJlZml4ZXMuc3RyaW5nVG9JbmRleChuZXcgU3RyaW5nKGNoLCBzdGFydCwKLSAgICAgICAgICAgICAgICAgICAgICBsZW5ndGgpKTsKLQotCi0gICAgbV9wcmV2aW91cyA9IGFkZE5vZGUoRFRNLkNPTU1FTlRfTk9ERSwgZXhOYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgIG1fcGFyZW50cy5wZWVrKCksIG1fcHJldmlvdXMsIGRhdGFJbmRleCwgZmFsc2UpOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCBhIHJ1biB0aW1lIHByb3BlcnR5IGZvciB0aGlzIERUTSBpbnN0YW5jZS4KLSAgICoKLSAgICogJVJFVklFVyUgTm93IHRoYXQgd2Ugbm8gbG9uZ2VyIHVzZSB0aGlzIG1ldGhvZCB0byBzdXBwb3J0Ci0gICAqIGdldFNvdXJjZUxvY2F0b3JGb3IsIGNhbiB3ZSByZW1vdmUgaXQ/Ci0gICAqCi0gICAqIEBwYXJhbSBwcm9wZXJ0eSBhIDxjb2RlPlN0cmluZzwvY29kZT4gdmFsdWUKLSAgICogQHBhcmFtIHZhbHVlIGFuIDxjb2RlPk9iamVjdDwvY29kZT4gdmFsdWUKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFByb3BlcnR5KFN0cmluZyBwcm9wZXJ0eSwgT2JqZWN0IHZhbHVlKQotICB7Ci0gIH0KLQotICAvKiogUmV0cmlldmUgdGhlIFNvdXJjZUxvY2F0b3IgYXNzb2NpYXRlZCB3aXRoIGEgc3BlY2lmaWMgbm9kZS4KLSAgICogVGhpcyBpcyBvbmx5IG1lYW5pbmdmdWwgaWYgdGhlIFhhbGFuUHJvcGVydGllcy5TT1VSQ0VfTE9DQVRJT04gZmxhZyB3YXMKLSAgICogc2V0IFRydWUgdXNpbmcgc2V0UHJvcGVydHk7IGlmIGl0IHdhcyBuZXZlciBzZXQsIG9yIHdhcyBzZXQgZmFsc2UsIHdlCi0gICAqIHdpbGwgcmV0dXJuIG51bGwuCi0gICAqCi0gICAqIChXZSBfY291bGRfIHJldHVybiBhIGxvY2F0b3Igd2l0aCB0aGUgZG9jdW1lbnQncyBiYXNlIFVSSSBhbmQgYm9ndXMKLSAgICogbGluZS9jb2x1bW4gaW5mb3JtYXRpb24uIFRyeWluZyB0aGF0OyBzZWUgdGhlIGVsc2UgY2xhdXNlLikKLSAgICogKi8KLSAgcHVibGljIFNvdXJjZUxvY2F0b3IgZ2V0U291cmNlTG9jYXRvckZvcihpbnQgbm9kZSkKLSAgewotICAgIGlmIChtX3VzZVNvdXJjZUxvY2F0aW9uUHJvcGVydHkpCi0gICAgewotCi0gICAgICBub2RlID0gbWFrZU5vZGVJZGVudGl0eShub2RlKTsKLQotCi0gICAgICByZXR1cm4gbmV3IE5vZGVMb2NhdG9yKG51bGwsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fc291cmNlU3lzdGVtSWQuZWxlbWVudEF0KG5vZGUpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX3NvdXJjZUxpbmUuZWxlbWVudEF0KG5vZGUpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX3NvdXJjZUNvbHVtbi5lbGVtZW50QXQobm9kZSkpOwotICAgIH0KLSAgICBlbHNlIGlmKG1fbG9jYXRvciE9bnVsbCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBuZXcgTm9kZUxvY2F0b3IobnVsbCxtX2xvY2F0b3IuZ2V0U3lzdGVtSWQoKSwtMSwtMSk7Ci0gICAgfQotICAgIGVsc2UgaWYobV9zeXN0ZW1JZCE9bnVsbCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBuZXcgTm9kZUxvY2F0b3IobnVsbCxtX3N5c3RlbUlkLC0xLC0xKTsKLSAgICB9Ci0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICBwdWJsaWMgU3RyaW5nIGdldEZpeGVkTmFtZXMoaW50IHR5cGUpewotICAgIHJldHVybiBtX2ZpeGVkbmFtZXNbdHlwZV07Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9yZWYvc2F4MmR0bS9TQVgyRFRNMi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL3JlZi9zYXgyZHRtL1NBWDJEVE0yLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDUyNmY1ZTEuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL3JlZi9zYXgyZHRtL1NBWDJEVE0yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzMzg1ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFNBWDJEVE0yLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTUgMDg6MTU6MTIgc3VyZXNoX2VtYWlsaWQgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5yZWYuc2F4MmR0bTsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLio7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0ucmVmLio7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5GYXN0U3RyaW5nQnVmZmVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuWE1MU3RyaW5nOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuWE1MU3RyaW5nRGVmYXVsdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLlhNTFN0cmluZ0ZhY3Rvcnk7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXMuWE1MTWVzc2FnZXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXMuWE1MRXJyb3JSZXNvdXJjZXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyLlNlcmlhbGl6YXRpb25IYW5kbGVyOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2U7Ci1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLlN1YmFsbG9jYXRlZEludFZlY3RvcjsKLWltcG9ydCBvcmcueG1sLnNheC4qOwotCi0vKioKLSAqIFNBWDJEVE0yIGlzIGFuIG9wdGltaXplZCB2ZXJzaW9uIG9mIFNBWDJEVE0gd2hpY2ggaXMgdXNlZCBpbiBub24taW5jcmVtZW50YWwgc2l0dWF0aW9uLgotICogSXQgaXMgdXNlZCBhcyB0aGUgc3VwZXIgY2xhc3Mgb2YgdGhlIFhTTFRDIFNBWEltcGwuIE1hbnkgb2YgdGhlIGludGVyZmFjZXMgaW4gU0FYMkRUTQotICogYW5kIERUTURlZmF1bHRCYXNlIGFyZSBvdmVycmlkZGVuIGluIFNBWDJEVE0yIGluIG9yZGVyIHRvIGFsbG93IGZhc3QsIGVmZmljaWVudAotICogYWNjZXNzIHRvIHRoZSBEVE0gbW9kZWwuIFNvbWUgbmVzdGVkIGl0ZXJhdG9ycyBpbiBEVE1EZWZhdWx0QmFzZUl0ZXJhdG9ycwotICogYXJlIGFsc28gb3ZlcnJpZGRlbiBpbiBTQVgyRFRNMiBmb3IgcGVyZm9ybWFuY2UgcmVhc29ucy4KLSAqIDxwPgotICogUGVyZm9ybWFuY2UgaXMgdGhlIGJpZ2dlc3QgY29uc2lkZXJhdGlvbiBpbiB0aGUgZGVzaWduIG9mIFNBWDJEVE0yLiBUbyBtYWtlIHRoZSBjb2RlIG1vc3QKLSAqIGVmZmljaWVudCwgdGhlIGluY3JlbWVudGFsIHN1cHBvcnQgaXMgZHJvcHBlZCBpbiBTQVgyRFRNMiwgd2hpY2ggbWVhbnMgdGhhdCB5b3Ugc2hvdWxkIG5vdAotICogdXNlIGl0IGluIGluY3JlbWVudGFsIHNpdHVhdGlvbi4gVG8gcmVkdWNlIHRoZSBvdmVyaGVhZCBvZiBwdWxsaW5nIGRhdGEgZnJvbSB0aGUgRFRNIG1vZGVsLAotICogYSBmZXcgY29yZSBpbnRlcmZhY2VzIGluIFNBWDJEVE0yIGhhdmUgZGlyZWN0IGFjY2VzcyB0byB0aGUgaW50ZXJuYWwgYXJyYXlzIG9mIHRoZQotICogU3ViYWxsb2NhdGVkSW50VmVjdG9ycy4KLSAqIDxwPgotICogVGhlIGRlc2lnbiBvZiBTQVgyRFRNMiBtYXkgbGltaXQgaXRzIGV4dGVuc2liaWx0eS4gSWYgeW91IGhhdmUgYSByZWFzb24gdG8gZXh0ZW5kIHRoZQotICogU0FYMkRUTSBtb2RlbCwgcGxlYXNlIGV4dGVuZCBmcm9tIFNBWDJEVE0gaW5zdGVhZCBvZiB0aGlzIGNsYXNzLgotICogPHA+Ci0gKiBUT0RPOiBUaGlzIGNsYXNzIGlzIGN1cnJlbnRseSBvbmx5IHVzZWQgYnkgWFNMVEMuIFdlIG5lZWQgdG8gaW52ZXN0aWdhdGUgdGhlIHBvc3NpYmlsaXR5Ci0gKiBvZiBhbHNvIHVzaW5nIGl0IGluIFhhbGFuLUogSW50ZXJwcmV0aXZlLiBYYWxhbidzIHBlcmZvcm1hbmNlIGlzIGxpa2VseSB0byBnZXQgYW4gaW5zdGFudAotICogYm9vc3QgaWYgd2UgdXNlIFNBWDJEVE0yIGluc3RlYWQgb2YgU0FYMkRUTSBpbiBub24taW5jcmVtZW50YWwgY2FzZS4KLSAqIDxwPgotICogJU1LJSBUaGUgY29kZSBpbiB0aGlzIGNsYXNzIGlzIGNyaXRpY2FsIHRvIHRoZSBYU0xUQ19EVE0gcGVyZm9ybWFuY2UuIEJlIHZlcnkgY2FyZWZ1bAotICogd2hlbiBtYWtpbmcgY2hhbmdlcyBoZXJlIQotICovCi1wdWJsaWMgY2xhc3MgU0FYMkRUTTIgZXh0ZW5kcyBTQVgyRFRNCi17Ci0KLSAgLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLSAgICogICAgICAgT3B0aW1pemVkIHZlcnNpb24gb2YgdGhlIG5lc3RlZCBpdGVyYXRvcnMKLSAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi0KLSAgLyoqCi0gICAqIEl0ZXJhdG9yIHRoYXQgcmV0dXJucyBhbGwgaW1tZWRpYXRlIGNoaWxkcmVuIG9mIGEgZ2l2ZW4gbm9kZQotICAgKi8KLSAgcHVibGljIGZpbmFsIGNsYXNzIENoaWxkcmVuSXRlcmF0b3IgZXh0ZW5kcyBJbnRlcm5hbEF4aXNJdGVyYXRvckJhc2UKLSAgewotCi0gICAgLyoqCi0gICAgICogU2V0dGluZyBzdGFydCB0byBFTkQgc2hvdWxkICdjbG9zZScgdGhlIGl0ZXJhdG9yLAotICAgICAqIGkuZS4gc3Vic2VxdWVudCBjYWxsIHRvIG5leHQoKSBzaG91bGQgcmV0dXJuIEVORC4KLSAgICAgKiA8cD4KLSAgICAgKiBJZiB0aGUgaXRlcmF0b3IgaXMgbm90IHJlc3RhcnRhYmxlLCB0aGlzIGhhcyBubyBlZmZlY3QuCi0gICAgICogJVJFVklFVyUgU2hvdWxkIGl0IHJldHVybi90aHJvdyBzb21ldGhpbmcgaW4gdGhhdCBjYXNlLAotICAgICAqIG9yIHNldCBjdXJyZW50IG5vZGUgdG8gRU5ELCB0byBpbmRpY2F0ZSByZXF1ZXN0LW5vdC1ob25vcmVkPwotICAgICAqCi0gICAgICogQHBhcmFtIG5vZGUgU2V0cyB0aGUgcm9vdCBvZiB0aGUgaXRlcmF0aW9uLgotICAgICAqCi0gICAgICogQHJldHVybiBBIERUTUF4aXNJdGVyYXRvciBzZXQgdG8gdGhlIHN0YXJ0IG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICovCi0gICAgcHVibGljIERUTUF4aXNJdGVyYXRvciBzZXRTdGFydE5vZGUoaW50IG5vZGUpCi0gICAgewotLy8lSFolOiBBZGRlZCByZWZlcmVuY2UgdG8gRFRNRGVmYXVsdEJhc2UuUk9PVE5PREUgYmFjayBpbiwgdGVtcG9yYXJpbHkKLSAgICAgIGlmIChub2RlID09IERUTURlZmF1bHRCYXNlLlJPT1ROT0RFKQotICAgICAgICBub2RlID0gZ2V0RG9jdW1lbnQoKTsKLSAgICAgIGlmIChfaXNSZXN0YXJ0YWJsZSkKLSAgICAgIHsKLSAgICAgICAgX3N0YXJ0Tm9kZSA9IG5vZGU7Ci0gICAgICAgIF9jdXJyZW50Tm9kZSA9IChub2RlID09IERUTS5OVUxMKSA/IERUTS5OVUxMCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IF9maXJzdGNoMihtYWtlTm9kZUlkZW50aXR5KG5vZGUpKTsKLQotICAgICAgICByZXR1cm4gcmVzZXRQb3NpdGlvbigpOwotICAgICAgfQotCi0gICAgICByZXR1cm4gdGhpczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIG5leHQgbm9kZSBpbiB0aGUgaXRlcmF0aW9uLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgbmV4dCBub2RlIGhhbmRsZSBpbiB0aGUgaXRlcmF0aW9uLCBvciBFTkQgaWYgbm8gbW9yZQotICAgICAqIGFyZSBhdmFpbGFibGUuCi0gICAgICovCi0gICAgcHVibGljIGludCBuZXh0KCkKLSAgICB7Ci0gICAgICBpZiAoX2N1cnJlbnROb2RlICE9IE5VTEwpIHsKLSAgICAgICAgaW50IG5vZGUgPSBfY3VycmVudE5vZGU7Ci0gICAgICAgIF9jdXJyZW50Tm9kZSA9IF9uZXh0c2liMihub2RlKTsKLSAgICAgICAgcmV0dXJuIHJldHVybk5vZGUobWFrZU5vZGVIYW5kbGUobm9kZSkpOwotICAgICAgfQotCi0gICAgICByZXR1cm4gRU5EOwotICAgIH0KLSAgfSAgLy8gZW5kIG9mIENoaWxkcmVuSXRlcmF0b3IKLQotICAvKioKLSAgICogSXRlcmF0b3IgdGhhdCByZXR1cm5zIHRoZSBwYXJlbnQgb2YgYSBnaXZlbiBub2RlLiBOb3RlIHRoYXQKLSAgICogdGhpcyBkZWxpdmVycyBvbmx5IGEgc2luZ2xlIG5vZGU7IGlmIHlvdSB3YW50IGFsbCB0aGUgYW5jZXN0b3JzLAotICAgKiBzZWUgQW5jZXN0b3JJdGVyYXRvci4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBjbGFzcyBQYXJlbnRJdGVyYXRvciBleHRlbmRzIEludGVybmFsQXhpc0l0ZXJhdG9yQmFzZQotICB7Ci0KLSAgICAvKiogVGhlIGV4dGVuZGVkIHR5cGUgSUQgdGhhdCB3YXMgcmVxdWVzdGVkLiAqLwotICAgIHByaXZhdGUgaW50IF9ub2RlVHlwZSA9IERUTS5OVUxMOwotCi0gICAgLyoqCi0gICAgICogU2V0IHN0YXJ0IHRvIEVORCBzaG91bGQgJ2Nsb3NlJyB0aGUgaXRlcmF0b3IsCi0gICAgICogaS5lLiBzdWJzZXF1ZW50IGNhbGwgdG8gbmV4dCgpIHNob3VsZCByZXR1cm4gRU5ELgotICAgICAqCi0gICAgICogQHBhcmFtIG5vZGUgU2V0cyB0aGUgcm9vdCBvZiB0aGUgaXRlcmF0aW9uLgotICAgICAqCi0gICAgICogQHJldHVybiBBIERUTUF4aXNJdGVyYXRvciBzZXQgdG8gdGhlIHN0YXJ0IG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICovCi0gICAgcHVibGljIERUTUF4aXNJdGVyYXRvciBzZXRTdGFydE5vZGUoaW50IG5vZGUpCi0gICAgewotLy8lSFolOiBBZGRlZCByZWZlcmVuY2UgdG8gRFRNRGVmYXVsdEJhc2UuUk9PVE5PREUgYmFjayBpbiwgdGVtcG9yYXJpbHkKLSAgICAgIGlmIChub2RlID09IERUTURlZmF1bHRCYXNlLlJPT1ROT0RFKQotICAgICAgICBub2RlID0gZ2V0RG9jdW1lbnQoKTsKLSAgICAgIGlmIChfaXNSZXN0YXJ0YWJsZSkKLSAgICAgIHsKLSAgICAgICAgX3N0YXJ0Tm9kZSA9IG5vZGU7Ci0KLSAgICAgICAgaWYgKG5vZGUgIT0gRFRNLk5VTEwpCi0gICAgICAgICAgX2N1cnJlbnROb2RlID0gX3BhcmVudDIobWFrZU5vZGVJZGVudGl0eShub2RlKSk7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICBfY3VycmVudE5vZGUgPSBEVE0uTlVMTDsKLQotICAgICAgICByZXR1cm4gcmVzZXRQb3NpdGlvbigpOwotICAgICAgfQotCi0gICAgICByZXR1cm4gdGhpczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIG5vZGUgdHlwZSBvZiB0aGUgcGFyZW50IHRoYXQgd2UncmUgbG9va2luZyBmb3IuCi0gICAgICogTm90ZSB0aGF0IHRoaXMgZG9lcyBfbm90XyBtZWFuICJmaW5kIHRoZSBuZWFyZXN0IGFuY2VzdG9yIG9mCi0gICAgICogdGhpcyB0eXBlIiwgYnV0ICJ5aWVsZCB0aGUgcGFyZW50IGlmIGl0IGlzIG9mIHRoaXMgdHlwZSIuCi0gICAgICoKLSAgICAgKgotICAgICAqIEBwYXJhbSB0eXBlIGV4dGVuZGVkIHR5cGUgSUQuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFBhcmVudEl0ZXJhdG9yIGNvbmZpZ3VyZWQgd2l0aCB0aGUgdHlwZSBmaWx0ZXIgc2V0LgotICAgICAqLwotICAgIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3Igc2V0Tm9kZVR5cGUoZmluYWwgaW50IHR5cGUpCi0gICAgewotCi0gICAgICBfbm9kZVR5cGUgPSB0eXBlOwotCi0gICAgICByZXR1cm4gdGhpczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIG5leHQgbm9kZSBpbiB0aGUgaXRlcmF0aW9uLiBJbiB0aGlzIGNhc2UsIHdlIHJldHVybgotICAgICAqIG9ubHkgdGhlIGltbWVkaWF0ZSBwYXJlbnQsIF9pZl8gaXQgbWF0Y2hlcyB0aGUgcmVxdWVzdGVkIG5vZGVUeXBlLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgbmV4dCBub2RlIGhhbmRsZSBpbiB0aGUgaXRlcmF0aW9uLCBvciBFTkQuCi0gICAgICovCi0gICAgcHVibGljIGludCBuZXh0KCkKLSAgICB7Ci0gICAgICBpbnQgcmVzdWx0ID0gX2N1cnJlbnROb2RlOwotICAgICAgaWYgKHJlc3VsdCA9PSBFTkQpCi0gICAgICAgIHJldHVybiBEVE0uTlVMTDsKLQotICAgICAgLy8gJU9QVCUgVGhlIG1vc3QgY29tbW9uIGNhc2UgaXMgaGFuZGxlZCBmaXJzdC4KLSAgICAgIGlmIChfbm9kZVR5cGUgPT0gTlVMTCkgewotICAgICAgICBfY3VycmVudE5vZGUgPSBFTkQ7Ci0gICAgICAgIHJldHVybiByZXR1cm5Ob2RlKG1ha2VOb2RlSGFuZGxlKHJlc3VsdCkpOwotICAgICAgfQotICAgICAgZWxzZSBpZiAoX25vZGVUeXBlID49IERUTS5OVFlQRVMpIHsKLSAgICAgICAgaWYgKF9ub2RlVHlwZSA9PSBfZXhwdHlwZTIocmVzdWx0KSkgewotICAgICAgICAgIF9jdXJyZW50Tm9kZSA9IEVORDsKLSAgICAgICAgICByZXR1cm4gcmV0dXJuTm9kZShtYWtlTm9kZUhhbmRsZShyZXN1bHQpKTsKLSAgICAgICAgfQotICAgICAgfQotICAgICAgZWxzZSB7Ci0gICAgICAgIGlmIChfbm9kZVR5cGUgPT0gX3R5cGUyKHJlc3VsdCkpIHsKLSAgICAgICAgICBfY3VycmVudE5vZGUgPSBFTkQ7Ci0gICAgICAgICAgcmV0dXJuIHJldHVybk5vZGUobWFrZU5vZGVIYW5kbGUocmVzdWx0KSk7Ci0gICAgICAgIH0KLSAgICAgIH0KLQotICAgICAgcmV0dXJuIERUTS5OVUxMOwotICAgIH0KLSAgfSAgLy8gZW5kIG9mIFBhcmVudEl0ZXJhdG9yCi0KLSAgLyoqCi0gICAqIEl0ZXJhdG9yIHRoYXQgcmV0dXJucyBjaGlsZHJlbiBvZiBhIGdpdmVuIHR5cGUgZm9yIGEgZ2l2ZW4gbm9kZS4KLSAgICogVGhlIGZ1bmN0aW9uYWxpdHkgY2hvdWxkIGJlIGFjaGlldmVkIGJ5IHB1dHRpbmcgYSBmaWx0ZXIgb24gdG9wCi0gICAqIG9mIGEgYmFzaWMgY2hpbGQgaXRlcmF0b3IsIGJ1dCBhIHNwZWNpYWxpc2VkIGl0ZXJhdG9yIGlzIHVzZWQKLSAgICogZm9yIGVmZmljaWVuY3kgKGJvdGggc3BlZWQgYW5kIHNpemUgb2YgdHJhbnNsZXQpLgotICAgKi8KLSAgcHVibGljIGZpbmFsIGNsYXNzIFR5cGVkQ2hpbGRyZW5JdGVyYXRvciBleHRlbmRzIEludGVybmFsQXhpc0l0ZXJhdG9yQmFzZQotICB7Ci0KLSAgICAvKiogVGhlIGV4dGVuZGVkIHR5cGUgSUQgdGhhdCB3YXMgcmVxdWVzdGVkLiAqLwotICAgIHByaXZhdGUgZmluYWwgaW50IF9ub2RlVHlwZTsKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdG9yIFR5cGVkQ2hpbGRyZW5JdGVyYXRvcgotICAgICAqCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbm9kZVR5cGUgVGhlIGV4dGVuZGVkIHR5cGUgSUQgYmVpbmcgcmVxdWVzdGVkLgotICAgICAqLwotICAgIHB1YmxpYyBUeXBlZENoaWxkcmVuSXRlcmF0b3IoaW50IG5vZGVUeXBlKQotICAgIHsKLSAgICAgIF9ub2RlVHlwZSA9IG5vZGVUeXBlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldCBzdGFydCB0byBFTkQgc2hvdWxkICdjbG9zZScgdGhlIGl0ZXJhdG9yLAotICAgICAqIGkuZS4gc3Vic2VxdWVudCBjYWxsIHRvIG5leHQoKSBzaG91bGQgcmV0dXJuIEVORC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBub2RlIFNldHMgdGhlIHJvb3Qgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gQSBEVE1BeGlzSXRlcmF0b3Igc2V0IHRvIHRoZSBzdGFydCBvZiB0aGUgaXRlcmF0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3Igc2V0U3RhcnROb2RlKGludCBub2RlKQotICAgIHsKLS8vJUhaJTogQWRkZWQgcmVmZXJlbmNlIHRvIERUTURlZmF1bHRCYXNlLlJPT1ROT0RFIGJhY2sgaW4sIHRlbXBvcmFyaWx5Ci0gICAgICBpZiAobm9kZSA9PSBEVE1EZWZhdWx0QmFzZS5ST09UTk9ERSkKLSAgICAgICAgbm9kZSA9IGdldERvY3VtZW50KCk7Ci0gICAgICBpZiAoX2lzUmVzdGFydGFibGUpCi0gICAgICB7Ci0gICAgICAgIF9zdGFydE5vZGUgPSBub2RlOwotICAgICAgICBfY3VycmVudE5vZGUgPSAobm9kZSA9PSBEVE0uTlVMTCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBEVE0uTlVMTAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IF9maXJzdGNoMihtYWtlTm9kZUlkZW50aXR5KF9zdGFydE5vZGUpKTsKLQotICAgICAgICByZXR1cm4gcmVzZXRQb3NpdGlvbigpOwotICAgICAgfQotCi0gICAgICByZXR1cm4gdGhpczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIG5leHQgbm9kZSBpbiB0aGUgaXRlcmF0aW9uLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgbmV4dCBub2RlIGhhbmRsZSBpbiB0aGUgaXRlcmF0aW9uLCBvciBFTkQuCi0gICAgICovCi0gICAgcHVibGljIGludCBuZXh0KCkKLSAgICB7Ci0gICAgICBpbnQgbm9kZSA9IF9jdXJyZW50Tm9kZTsKLSAgICAgIGlmIChub2RlID09IERUTS5OVUxMKQotICAgICAgICByZXR1cm4gRFRNLk5VTEw7Ci0KLSAgICAgIGZpbmFsIGludCBub2RlVHlwZSA9IF9ub2RlVHlwZTsKLQotICAgICAgaWYgKG5vZGVUeXBlICE9IERUTS5FTEVNRU5UX05PREUpIHsKLSAgICAgICAgd2hpbGUgKG5vZGUgIT0gRFRNLk5VTEwgJiYgX2V4cHR5cGUyKG5vZGUpICE9IG5vZGVUeXBlKSB7Ci0gICAgICAgICAgbm9kZSA9IF9uZXh0c2liMihub2RlKTsKLSAgICAgICAgfQotICAgICAgfQotICAgICAgLy8gJU9QVCUgSWYgdGhlIG5vZGVUeXBlIGlzIGVsZW1lbnQgKG1hdGNoaW5nIGNoaWxkOjoqKSwgd2Ugb25seQotICAgICAgLy8gbmVlZCB0byBjb21wYXJlIHRoZSBleHBUeXBlIHdpdGggRFRNLk5UWVBFUy4gQSBjaGlsZCBub2RlIG9mCi0gICAgICAvLyBhbiBlbGVtZW50IGNhbiBiZSBlaXRoZXIgYW4gZWxlbWVudCwgdGV4dCwgY29tbWVudCBvcgotICAgICAgLy8gcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiBub2RlLiBPbmx5IGVsZW1lbnQgbm9kZSBoYXMgYW4gZXh0ZW5kZWQKLSAgICAgIC8vIHR5cGUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIERUTS5OVFlQRVMuCi0gICAgICBlbHNlIHsKLSAgICAgICAgaW50IGVUeXBlOwotICAgICAgICB3aGlsZSAobm9kZSAhPSBEVE0uTlVMTCkgewotICAgICAgICAgIGVUeXBlID0gX2V4cHR5cGUyKG5vZGUpOwotICAgICAgICAgIGlmIChlVHlwZSA+PSBEVE0uTlRZUEVTKQotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgICAgbm9kZSA9IF9uZXh0c2liMihub2RlKTsKLSAgICAgICAgfQotICAgICAgfQotCi0gICAgICBpZiAobm9kZSA9PSBEVE0uTlVMTCkgewotICAgICAgICBfY3VycmVudE5vZGUgPSBEVE0uTlVMTDsKLSAgICAgICAgcmV0dXJuIERUTS5OVUxMOwotICAgICAgfSBlbHNlIHsKLSAgICAgICAgX2N1cnJlbnROb2RlID0gX25leHRzaWIyKG5vZGUpOwotICAgICAgICByZXR1cm4gcmV0dXJuTm9kZShtYWtlTm9kZUhhbmRsZShub2RlKSk7Ci0gICAgICB9Ci0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIG5vZGUgYXQgdGhlIGdpdmVuIHBvc2l0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0Tm9kZUJ5UG9zaXRpb24oaW50IHBvc2l0aW9uKQotICAgIHsKLSAgICAgIGlmIChwb3NpdGlvbiA8PSAwKQotICAgICAgICByZXR1cm4gRFRNLk5VTEw7Ci0KLSAgICAgIGludCBub2RlID0gX2N1cnJlbnROb2RlOwotICAgICAgaW50IHBvcyA9IDA7Ci0KLSAgICAgIGZpbmFsIGludCBub2RlVHlwZSA9IF9ub2RlVHlwZTsKLSAgICAgIGlmIChub2RlVHlwZSAhPSBEVE0uRUxFTUVOVF9OT0RFKSB7Ci0gICAgICAgIHdoaWxlIChub2RlICE9IERUTS5OVUxMKSB7Ci0gICAgICAgICAgaWYgKF9leHB0eXBlMihub2RlKSA9PSBub2RlVHlwZSkgewotICAgICAgICAgICAgcG9zKys7Ci0gICAgICAgICAgICBpZiAocG9zID09IHBvc2l0aW9uKQotICAgICAgICAgICAgICByZXR1cm4gbWFrZU5vZGVIYW5kbGUobm9kZSk7Ci0gICAgICAgICAgfQotCi0gICAgICAgICAgbm9kZSA9IF9uZXh0c2liMihub2RlKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gTlVMTDsKLSAgICAgIH0KLSAgICAgIGVsc2UgewotICAgICAgICB3aGlsZSAobm9kZSAhPSBEVE0uTlVMTCkgewotICAgICAgICAgIGlmIChfZXhwdHlwZTIobm9kZSkgPj0gRFRNLk5UWVBFUykgewotICAgICAgICAgICAgcG9zKys7Ci0gICAgICAgICAgICBpZiAocG9zID09IHBvc2l0aW9uKQotICAgICAgICAgICAgICByZXR1cm4gbWFrZU5vZGVIYW5kbGUobm9kZSk7Ci0gICAgICAgICAgfQotICAgICAgICAgIG5vZGUgPSBfbmV4dHNpYjIobm9kZSk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIE5VTEw7Ci0gICAgICB9Ci0gICAgfQotCi0gIH0gIC8vIGVuZCBvZiBUeXBlZENoaWxkcmVuSXRlcmF0b3IKLQotICAvKioKLSAgICogSXRlcmF0b3IgdGhhdCByZXR1cm5zIHRoZSBuYW1lc3BhY2Ugbm9kZXMgYXMgZGVmaW5lZCBieSB0aGUgWFBhdGggZGF0YSBtb2RlbAotICAgKiBmb3IgYSBnaXZlbiBub2RlLCBmaWx0ZXJlZCBieSBleHRlbmRlZCB0eXBlIElELgotICAgKi8KLSAgcHVibGljIGNsYXNzIFR5cGVkUm9vdEl0ZXJhdG9yIGV4dGVuZHMgUm9vdEl0ZXJhdG9yCi0gIHsKLQotICAgIC8qKiBUaGUgZXh0ZW5kZWQgdHlwZSBJRCB0aGF0IHdhcyByZXF1ZXN0ZWQuICovCi0gICAgcHJpdmF0ZSBmaW5hbCBpbnQgX25vZGVUeXBlOwotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0b3IgVHlwZWRSb290SXRlcmF0b3IKLSAgICAgKgotICAgICAqIEBwYXJhbSBub2RlVHlwZSBUaGUgZXh0ZW5kZWQgdHlwZSBJRCBiZWluZyByZXF1ZXN0ZWQuCi0gICAgICovCi0gICAgcHVibGljIFR5cGVkUm9vdEl0ZXJhdG9yKGludCBub2RlVHlwZSkKLSAgICB7Ci0gICAgICBzdXBlcigpOwotICAgICAgX25vZGVUeXBlID0gbm9kZVR5cGU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBuZXh0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIG5leHQgbm9kZSBoYW5kbGUgaW4gdGhlIGl0ZXJhdGlvbiwgb3IgRU5ELgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgbmV4dCgpCi0gICAgewotICAgICAgaWYoX3N0YXJ0Tm9kZSA9PSBfY3VycmVudE5vZGUpCi0gICAgICAgIHJldHVybiBOVUxMOwotCi0gICAgICBmaW5hbCBpbnQgbm9kZSA9IF9zdGFydE5vZGU7Ci0gICAgICBpbnQgZXhwVHlwZSA9IF9leHB0eXBlMihtYWtlTm9kZUlkZW50aXR5KG5vZGUpKTsKLQotICAgICAgX2N1cnJlbnROb2RlID0gbm9kZTsKLQotICAgICAgaWYgKF9ub2RlVHlwZSA+PSBEVE0uTlRZUEVTKSB7Ci0gICAgICAgIGlmIChfbm9kZVR5cGUgPT0gZXhwVHlwZSkgewotICAgICAgICAgIHJldHVybiByZXR1cm5Ob2RlKG5vZGUpOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgICBlbHNlIHsKLSAgICAgICAgaWYgKGV4cFR5cGUgPCBEVE0uTlRZUEVTKSB7Ci0gICAgICAgICAgaWYgKGV4cFR5cGUgPT0gX25vZGVUeXBlKSB7Ci0gICAgICAgICAgICByZXR1cm4gcmV0dXJuTm9kZShub2RlKTsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgaWYgKG1fZXh0ZW5kZWRUeXBlc1tleHBUeXBlXS5nZXROb2RlVHlwZSgpID09IF9ub2RlVHlwZSkgewotICAgICAgICAgICAgcmV0dXJuIHJldHVybk5vZGUobm9kZSk7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICB9Ci0KLSAgICAgIHJldHVybiBOVUxMOwotICAgIH0KLSAgfSAgLy8gZW5kIG9mIFR5cGVkUm9vdEl0ZXJhdG9yCi0KLSAgLyoqCi0gICAqIEl0ZXJhdG9yIHRoYXQgcmV0dXJucyBhbGwgc2libGluZ3Mgb2YgYSBnaXZlbiBub2RlLgotICAgKi8KLSAgcHVibGljIGNsYXNzIEZvbGxvd2luZ1NpYmxpbmdJdGVyYXRvciBleHRlbmRzIEludGVybmFsQXhpc0l0ZXJhdG9yQmFzZQotICB7Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgc3RhcnQgdG8gRU5EIHNob3VsZCAnY2xvc2UnIHRoZSBpdGVyYXRvciwKLSAgICAgKiBpLmUuIHN1YnNlcXVlbnQgY2FsbCB0byBuZXh0KCkgc2hvdWxkIHJldHVybiBFTkQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbm9kZSBTZXRzIHRoZSByb290IG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIEEgRFRNQXhpc0l0ZXJhdG9yIHNldCB0byB0aGUgc3RhcnQgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIHNldFN0YXJ0Tm9kZShpbnQgbm9kZSkKLSAgICB7Ci0vLyVIWiU6IEFkZGVkIHJlZmVyZW5jZSB0byBEVE1EZWZhdWx0QmFzZS5ST09UTk9ERSBiYWNrIGluLCB0ZW1wb3JhcmlseQotICAgICAgaWYgKG5vZGUgPT0gRFRNRGVmYXVsdEJhc2UuUk9PVE5PREUpCi0gICAgICAgIG5vZGUgPSBnZXREb2N1bWVudCgpOwotICAgICAgaWYgKF9pc1Jlc3RhcnRhYmxlKQotICAgICAgewotICAgICAgICBfc3RhcnROb2RlID0gbm9kZTsKLSAgICAgICAgX2N1cnJlbnROb2RlID0gbWFrZU5vZGVJZGVudGl0eShub2RlKTsKLQotICAgICAgICByZXR1cm4gcmVzZXRQb3NpdGlvbigpOwotICAgICAgfQotCi0gICAgICByZXR1cm4gdGhpczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIG5leHQgbm9kZSBpbiB0aGUgaXRlcmF0aW9uLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgbmV4dCBub2RlIGhhbmRsZSBpbiB0aGUgaXRlcmF0aW9uLCBvciBFTkQuCi0gICAgICovCi0gICAgcHVibGljIGludCBuZXh0KCkKLSAgICB7Ci0gICAgICBfY3VycmVudE5vZGUgPSAoX2N1cnJlbnROb2RlID09IERUTS5OVUxMKSA/IERUTS5OVUxMCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IF9uZXh0c2liMihfY3VycmVudE5vZGUpOwotICAgICAgcmV0dXJuIHJldHVybk5vZGUobWFrZU5vZGVIYW5kbGUoX2N1cnJlbnROb2RlKSk7Ci0gICAgfQotICB9ICAvLyBlbmQgb2YgRm9sbG93aW5nU2libGluZ0l0ZXJhdG9yCi0KLSAgLyoqCi0gICAqIEl0ZXJhdG9yIHRoYXQgcmV0dXJucyBhbGwgZm9sbG93aW5nIHNpYmxpbmdzIG9mIGEgZ2l2ZW4gbm9kZS4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBjbGFzcyBUeXBlZEZvbGxvd2luZ1NpYmxpbmdJdGVyYXRvcgotICAgICAgICAgIGV4dGVuZHMgRm9sbG93aW5nU2libGluZ0l0ZXJhdG9yCi0gIHsKLQotICAgIC8qKiBUaGUgZXh0ZW5kZWQgdHlwZSBJRCB0aGF0IHdhcyByZXF1ZXN0ZWQuICovCi0gICAgcHJpdmF0ZSBmaW5hbCBpbnQgX25vZGVUeXBlOwotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0b3IgVHlwZWRGb2xsb3dpbmdTaWJsaW5nSXRlcmF0b3IKLSAgICAgKgotICAgICAqCi0gICAgICogQHBhcmFtIHR5cGUgVGhlIGV4dGVuZGVkIHR5cGUgSUQgYmVpbmcgcmVxdWVzdGVkLgotICAgICAqLwotICAgIHB1YmxpYyBUeXBlZEZvbGxvd2luZ1NpYmxpbmdJdGVyYXRvcihpbnQgdHlwZSkKLSAgICB7Ci0gICAgICBfbm9kZVR5cGUgPSB0eXBlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgbmV4dCBub2RlIGluIHRoZSBpdGVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBuZXh0IG5vZGUgaGFuZGxlIGluIHRoZSBpdGVyYXRpb24sIG9yIEVORC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IG5leHQoKQotICAgIHsKLSAgICAgIGlmIChfY3VycmVudE5vZGUgPT0gRFRNLk5VTEwpIHsKLSAgICAgICAgcmV0dXJuIERUTS5OVUxMOwotICAgICAgfQotCi0gICAgICBpbnQgbm9kZSA9IF9jdXJyZW50Tm9kZTsKLSAgICAgIGZpbmFsIGludCBub2RlVHlwZSA9IF9ub2RlVHlwZTsKLQotICAgICAgaWYgKG5vZGVUeXBlICE9IERUTS5FTEVNRU5UX05PREUpIHsKLSAgICAgICAgd2hpbGUgKChub2RlID0gX25leHRzaWIyKG5vZGUpKSAhPSBEVE0uTlVMTCAmJiBfZXhwdHlwZTIobm9kZSkgIT0gbm9kZVR5cGUpIHt9Ci0gICAgICB9Ci0gICAgICBlbHNlIHsKLSAgICAgICAgd2hpbGUgKChub2RlID0gX25leHRzaWIyKG5vZGUpKSAhPSBEVE0uTlVMTCAmJiBfZXhwdHlwZTIobm9kZSkgPCBEVE0uTlRZUEVTKSB7fQotICAgICAgfQotCi0gICAgICBfY3VycmVudE5vZGUgPSBub2RlOwotCi0gICAgICByZXR1cm4gKG5vZGUgPT0gRFRNLk5VTEwpCi0gICAgICAgICAgICAgICAgICAgICAgPyBEVE0uTlVMTAotICAgICAgICAgICAgICAgICAgICAgIDogcmV0dXJuTm9kZShtYWtlTm9kZUhhbmRsZShub2RlKSk7Ci0gICAgfQotCi0gIH0gIC8vIGVuZCBvZiBUeXBlZEZvbGxvd2luZ1NpYmxpbmdJdGVyYXRvcgotCi0gIC8qKgotICAgKiBJdGVyYXRvciB0aGF0IHJldHVybnMgYXR0cmlidXRlIG5vZGVzIChvZiB3aGF0IG5vZGVzPykKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBjbGFzcyBBdHRyaWJ1dGVJdGVyYXRvciBleHRlbmRzIEludGVybmFsQXhpc0l0ZXJhdG9yQmFzZQotICB7Ci0KLSAgICAvLyBhc3N1bWVzIGNhbGxlciB3aWxsIHBhc3MgZWxlbWVudCBub2RlcwotCi0gICAgLyoqCi0gICAgICogU2V0IHN0YXJ0IHRvIEVORCBzaG91bGQgJ2Nsb3NlJyB0aGUgaXRlcmF0b3IsCi0gICAgICogaS5lLiBzdWJzZXF1ZW50IGNhbGwgdG8gbmV4dCgpIHNob3VsZCByZXR1cm4gRU5ELgotICAgICAqCi0gICAgICogQHBhcmFtIG5vZGUgU2V0cyB0aGUgcm9vdCBvZiB0aGUgaXRlcmF0aW9uLgotICAgICAqCi0gICAgICogQHJldHVybiBBIERUTUF4aXNJdGVyYXRvciBzZXQgdG8gdGhlIHN0YXJ0IG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICovCi0gICAgcHVibGljIERUTUF4aXNJdGVyYXRvciBzZXRTdGFydE5vZGUoaW50IG5vZGUpCi0gICAgewotLy8lSFolOiBBZGRlZCByZWZlcmVuY2UgdG8gRFRNRGVmYXVsdEJhc2UuUk9PVE5PREUgYmFjayBpbiwgdGVtcG9yYXJpbHkKLSAgICAgIGlmIChub2RlID09IERUTURlZmF1bHRCYXNlLlJPT1ROT0RFKQotICAgICAgICBub2RlID0gZ2V0RG9jdW1lbnQoKTsKLSAgICAgIGlmIChfaXNSZXN0YXJ0YWJsZSkKLSAgICAgIHsKLSAgICAgICAgX3N0YXJ0Tm9kZSA9IG5vZGU7Ci0gICAgICAgIF9jdXJyZW50Tm9kZSA9IGdldEZpcnN0QXR0cmlidXRlSWRlbnRpdHkobWFrZU5vZGVJZGVudGl0eShub2RlKSk7Ci0KLSAgICAgICAgcmV0dXJuIHJlc2V0UG9zaXRpb24oKTsKLSAgICAgIH0KLQotICAgICAgcmV0dXJuIHRoaXM7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBuZXh0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIG5leHQgbm9kZSBoYW5kbGUgaW4gdGhlIGl0ZXJhdGlvbiwgb3IgRU5ELgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgbmV4dCgpCi0gICAgewotCi0gICAgICBmaW5hbCBpbnQgbm9kZSA9IF9jdXJyZW50Tm9kZTsKLQotICAgICAgaWYgKG5vZGUgIT0gTlVMTCkgewotICAgICAgICBfY3VycmVudE5vZGUgPSBnZXROZXh0QXR0cmlidXRlSWRlbnRpdHkobm9kZSk7Ci0gICAgICAgIHJldHVybiByZXR1cm5Ob2RlKG1ha2VOb2RlSGFuZGxlKG5vZGUpKTsKLSAgICAgIH0KLQotICAgICAgcmV0dXJuIE5VTEw7Ci0gICAgfQotICB9ICAvLyBlbmQgb2YgQXR0cmlidXRlSXRlcmF0b3IKLQotICAvKioKLSAgICogSXRlcmF0b3IgdGhhdCByZXR1cm5zIGF0dHJpYnV0ZSBub2RlcyBvZiBhIGdpdmVuIHR5cGUKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBjbGFzcyBUeXBlZEF0dHJpYnV0ZUl0ZXJhdG9yIGV4dGVuZHMgSW50ZXJuYWxBeGlzSXRlcmF0b3JCYXNlCi0gIHsKLQotICAgIC8qKiBUaGUgZXh0ZW5kZWQgdHlwZSBJRCB0aGF0IHdhcyByZXF1ZXN0ZWQuICovCi0gICAgcHJpdmF0ZSBmaW5hbCBpbnQgX25vZGVUeXBlOwotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0b3IgVHlwZWRBdHRyaWJ1dGVJdGVyYXRvcgotICAgICAqCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbm9kZVR5cGUgVGhlIGV4dGVuZGVkIHR5cGUgSUQgdGhhdCBpcyByZXF1ZXN0ZWQuCi0gICAgICovCi0gICAgcHVibGljIFR5cGVkQXR0cmlidXRlSXRlcmF0b3IoaW50IG5vZGVUeXBlKQotICAgIHsKLSAgICAgIF9ub2RlVHlwZSA9IG5vZGVUeXBlOwotICAgIH0KLQotICAgIC8vIGFzc3VtZXMgY2FsbGVyIHdpbGwgcGFzcyBlbGVtZW50IG5vZGVzCi0KLSAgICAvKioKLSAgICAgKiBTZXQgc3RhcnQgdG8gRU5EIHNob3VsZCAnY2xvc2UnIHRoZSBpdGVyYXRvciwKLSAgICAgKiBpLmUuIHN1YnNlcXVlbnQgY2FsbCB0byBuZXh0KCkgc2hvdWxkIHJldHVybiBFTkQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbm9kZSBTZXRzIHRoZSByb290IG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIEEgRFRNQXhpc0l0ZXJhdG9yIHNldCB0byB0aGUgc3RhcnQgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIHNldFN0YXJ0Tm9kZShpbnQgbm9kZSkKLSAgICB7Ci0gICAgICBpZiAoX2lzUmVzdGFydGFibGUpCi0gICAgICB7Ci0gICAgICAgIF9zdGFydE5vZGUgPSBub2RlOwotCi0gICAgICAgIF9jdXJyZW50Tm9kZSA9IGdldFR5cGVkQXR0cmlidXRlKG5vZGUsIF9ub2RlVHlwZSk7Ci0KLSAgICAgICAgcmV0dXJuIHJlc2V0UG9zaXRpb24oKTsKLSAgICAgIH0KLQotICAgICAgcmV0dXJuIHRoaXM7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBuZXh0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIG5leHQgbm9kZSBoYW5kbGUgaW4gdGhlIGl0ZXJhdGlvbiwgb3IgRU5ELgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgbmV4dCgpCi0gICAgewotCi0gICAgICBmaW5hbCBpbnQgbm9kZSA9IF9jdXJyZW50Tm9kZTsKLQotICAgICAgLy8gc2luZ2xldG9uIGl0ZXJhdG9yLCBzaW5jZSB0aGVyZSBjYW4gb25seSBiZSBvbmUgYXR0cmlidXRlIG9mCi0gICAgICAvLyBhIGdpdmVuIHR5cGUuCi0gICAgICBfY3VycmVudE5vZGUgPSBOVUxMOwotCi0gICAgICByZXR1cm4gcmV0dXJuTm9kZShub2RlKTsKLSAgICB9Ci0gIH0gIC8vIGVuZCBvZiBUeXBlZEF0dHJpYnV0ZUl0ZXJhdG9yCi0KLSAgLyoqCi0gICAqIEl0ZXJhdG9yIHRoYXQgcmV0dXJucyBwcmVjZWRpbmcgc2libGluZ3Mgb2YgYSBnaXZlbiBub2RlCi0gICAqLwotICBwdWJsaWMgY2xhc3MgUHJlY2VkaW5nU2libGluZ0l0ZXJhdG9yIGV4dGVuZHMgSW50ZXJuYWxBeGlzSXRlcmF0b3JCYXNlCi0gIHsKLQotICAgIC8qKgotICAgICAqIFRoZSBub2RlIGlkZW50aXR5IG9mIF9zdGFydE5vZGUgZm9yIHRoaXMgaXRlcmF0b3IKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgaW50IF9zdGFydE5vZGVJRDsKLQotICAgIC8qKgotICAgICAqIFRydWUgaWYgdGhpcyBpdGVyYXRvciBoYXMgYSByZXZlcnNlZCBheGlzLgotICAgICAqCi0gICAgICogQHJldHVybiB0cnVlLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzUmV2ZXJzZSgpCi0gICAgewotICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0IHN0YXJ0IHRvIEVORCBzaG91bGQgJ2Nsb3NlJyB0aGUgaXRlcmF0b3IsCi0gICAgICogaS5lLiBzdWJzZXF1ZW50IGNhbGwgdG8gbmV4dCgpIHNob3VsZCByZXR1cm4gRU5ELgotICAgICAqCi0gICAgICogQHBhcmFtIG5vZGUgU2V0cyB0aGUgcm9vdCBvZiB0aGUgaXRlcmF0aW9uLgotICAgICAqCi0gICAgICogQHJldHVybiBBIERUTUF4aXNJdGVyYXRvciBzZXQgdG8gdGhlIHN0YXJ0IG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICovCi0gICAgcHVibGljIERUTUF4aXNJdGVyYXRvciBzZXRTdGFydE5vZGUoaW50IG5vZGUpCi0gICAgewotLy8lSFolOiBBZGRlZCByZWZlcmVuY2UgdG8gRFRNRGVmYXVsdEJhc2UuUk9PVE5PREUgYmFjayBpbiwgdGVtcG9yYXJpbHkKLSAgICAgIGlmIChub2RlID09IERUTURlZmF1bHRCYXNlLlJPT1ROT0RFKQotICAgICAgICBub2RlID0gZ2V0RG9jdW1lbnQoKTsKLSAgICAgIGlmIChfaXNSZXN0YXJ0YWJsZSkKLSAgICAgIHsKLSAgICAgICAgX3N0YXJ0Tm9kZSA9IG5vZGU7Ci0gICAgICAgIG5vZGUgPSBfc3RhcnROb2RlSUQgPSBtYWtlTm9kZUlkZW50aXR5KG5vZGUpOwotCi0gICAgICAgIGlmKG5vZGUgPT0gTlVMTCkKLSAgICAgICAgewotICAgICAgICAgIF9jdXJyZW50Tm9kZSA9IG5vZGU7Ci0gICAgICAgICAgcmV0dXJuIHJlc2V0UG9zaXRpb24oKTsKLSAgICAgICAgfQotCi0gICAgICAgIGludCB0eXBlID0gX3R5cGUyKG5vZGUpOwotICAgICAgICBpZihFeHBhbmRlZE5hbWVUYWJsZS5BVFRSSUJVVEUgPT0gdHlwZQotICAgICAgICAgICB8fCBFeHBhbmRlZE5hbWVUYWJsZS5OQU1FU1BBQ0UgPT0gdHlwZSApCi0gICAgICAgIHsKLSAgICAgICAgICBfY3VycmVudE5vZGUgPSBub2RlOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotICAgICAgICAgIC8vIEJlIGNhcmVmdWwgdG8gaGFuZGxlIHRoZSBEb2N1bWVudCBub2RlIHByb3Blcmx5Ci0gICAgICAgICAgX2N1cnJlbnROb2RlID0gX3BhcmVudDIobm9kZSk7Ci0gICAgICAgICAgaWYoTlVMTCE9X2N1cnJlbnROb2RlKQotICAgICAgICAgICAgX2N1cnJlbnROb2RlID0gX2ZpcnN0Y2gyKF9jdXJyZW50Tm9kZSk7Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgICAgX2N1cnJlbnROb2RlID0gbm9kZTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiByZXNldFBvc2l0aW9uKCk7Ci0gICAgICB9Ci0KLSAgICAgIHJldHVybiB0aGlzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgbmV4dCBub2RlIGluIHRoZSBpdGVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBuZXh0IG5vZGUgaGFuZGxlIGluIHRoZSBpdGVyYXRpb24sIG9yIEVORC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IG5leHQoKQotICAgIHsKLQotICAgICAgaWYgKF9jdXJyZW50Tm9kZSA9PSBfc3RhcnROb2RlSUQgfHwgX2N1cnJlbnROb2RlID09IERUTS5OVUxMKQotICAgICAgewotICAgICAgICByZXR1cm4gTlVMTDsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgZmluYWwgaW50IG5vZGUgPSBfY3VycmVudE5vZGU7Ci0gICAgICAgIF9jdXJyZW50Tm9kZSA9IF9uZXh0c2liMihub2RlKTsKLQotICAgICAgICByZXR1cm4gcmV0dXJuTm9kZShtYWtlTm9kZUhhbmRsZShub2RlKSk7Ci0gICAgICB9Ci0gICAgfQotICB9ICAvLyBlbmQgb2YgUHJlY2VkaW5nU2libGluZ0l0ZXJhdG9yCi0KLSAgLyoqCi0gICAqIEl0ZXJhdG9yIHRoYXQgcmV0dXJucyBwcmVjZWRpbmcgc2libGluZ3Mgb2YgYSBnaXZlbiB0eXBlIGZvcgotICAgKiBhIGdpdmVuIG5vZGUKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBjbGFzcyBUeXBlZFByZWNlZGluZ1NpYmxpbmdJdGVyYXRvcgotICAgICAgICAgIGV4dGVuZHMgUHJlY2VkaW5nU2libGluZ0l0ZXJhdG9yCi0gIHsKLQotICAgIC8qKiBUaGUgZXh0ZW5kZWQgdHlwZSBJRCB0aGF0IHdhcyByZXF1ZXN0ZWQuICovCi0gICAgcHJpdmF0ZSBmaW5hbCBpbnQgX25vZGVUeXBlOwotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0b3IgVHlwZWRQcmVjZWRpbmdTaWJsaW5nSXRlcmF0b3IKLSAgICAgKgotICAgICAqCi0gICAgICogQHBhcmFtIHR5cGUgVGhlIGV4dGVuZGVkIHR5cGUgSUQgYmVpbmcgcmVxdWVzdGVkLgotICAgICAqLwotICAgIHB1YmxpYyBUeXBlZFByZWNlZGluZ1NpYmxpbmdJdGVyYXRvcihpbnQgdHlwZSkKLSAgICB7Ci0gICAgICBfbm9kZVR5cGUgPSB0eXBlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgbmV4dCBub2RlIGluIHRoZSBpdGVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBuZXh0IG5vZGUgaGFuZGxlIGluIHRoZSBpdGVyYXRpb24sIG9yIEVORC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IG5leHQoKQotICAgIHsKLSAgICAgIGludCBub2RlID0gX2N1cnJlbnROb2RlOwotCi0gICAgICBmaW5hbCBpbnQgbm9kZVR5cGUgPSBfbm9kZVR5cGU7Ci0gICAgICBmaW5hbCBpbnQgc3RhcnROb2RlSUQgPSBfc3RhcnROb2RlSUQ7Ci0KLSAgICAgIGlmIChub2RlVHlwZSAhPSBEVE0uRUxFTUVOVF9OT0RFKSB7Ci0gICAgICAgIHdoaWxlIChub2RlICE9IE5VTEwgJiYgbm9kZSAhPSBzdGFydE5vZGVJRCAmJiBfZXhwdHlwZTIobm9kZSkgIT0gbm9kZVR5cGUpIHsKLSAgICAgICAgICBub2RlID0gX25leHRzaWIyKG5vZGUpOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgICBlbHNlIHsKLSAgICAgICAgd2hpbGUgKG5vZGUgIT0gTlVMTCAmJiBub2RlICE9IHN0YXJ0Tm9kZUlEICYmIF9leHB0eXBlMihub2RlKSA8IERUTS5OVFlQRVMpIHsKLSAgICAgICAgICBub2RlID0gX25leHRzaWIyKG5vZGUpOwotICAgICAgICB9Ci0gICAgICB9Ci0KLSAgICAgIGlmIChub2RlID09IERUTS5OVUxMIHx8IG5vZGUgPT0gc3RhcnROb2RlSUQpIHsKLSAgICAgICAgX2N1cnJlbnROb2RlID0gTlVMTDsKLSAgICAgICAgcmV0dXJuIE5VTEw7Ci0gICAgICB9Ci0gICAgICBlbHNlIHsKLSAgICAgICAgX2N1cnJlbnROb2RlID0gX25leHRzaWIyKG5vZGUpOwotICAgICAgICByZXR1cm4gcmV0dXJuTm9kZShtYWtlTm9kZUhhbmRsZShub2RlKSk7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSBpbmRleCBvZiB0aGUgbGFzdCBub2RlIGluIHRoaXMgaXRlcmF0b3IuCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRMYXN0KCkKLSAgICB7Ci0gICAgICBpZiAoX2xhc3QgIT0gLTEpCi0gICAgICAgIHJldHVybiBfbGFzdDsKLQotICAgICAgc2V0TWFyaygpOwotCi0gICAgICBpbnQgbm9kZSA9IF9jdXJyZW50Tm9kZTsKLSAgICAgIGZpbmFsIGludCBub2RlVHlwZSA9IF9ub2RlVHlwZTsKLSAgICAgIGZpbmFsIGludCBzdGFydE5vZGVJRCA9IF9zdGFydE5vZGVJRDsKLQotICAgICAgaW50IGxhc3QgPSAwOwotICAgICAgaWYgKG5vZGVUeXBlICE9IERUTS5FTEVNRU5UX05PREUpIHsKLSAgICAgICAgd2hpbGUgKG5vZGUgIT0gTlVMTCAmJiBub2RlICE9IHN0YXJ0Tm9kZUlEKSB7Ci0gICAgICAgICAgaWYgKF9leHB0eXBlMihub2RlKSA9PSBub2RlVHlwZSkgewotICAgICAgICAgICAgbGFzdCsrOwotICAgICAgICAgIH0KLSAgICAgICAgICBub2RlID0gX25leHRzaWIyKG5vZGUpOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgICBlbHNlIHsKLSAgICAgICAgd2hpbGUgKG5vZGUgIT0gTlVMTCAmJiBub2RlICE9IHN0YXJ0Tm9kZUlEKSB7Ci0gICAgICAgICAgaWYgKF9leHB0eXBlMihub2RlKSA+PSBEVE0uTlRZUEVTKSB7Ci0gICAgICAgICAgICBsYXN0Kys7Ci0gICAgICAgICAgfQotICAgICAgICAgIG5vZGUgPSBfbmV4dHNpYjIobm9kZSk7Ci0gICAgICAgIH0KLSAgICAgIH0KLQotICAgICAgZ290b01hcmsoKTsKLQotICAgICAgcmV0dXJuIChfbGFzdCA9IGxhc3QpOwotICAgIH0KLSAgfSAgLy8gZW5kIG9mIFR5cGVkUHJlY2VkaW5nU2libGluZ0l0ZXJhdG9yCi0KLSAgLyoqCi0gICAqIEl0ZXJhdG9yIHRoYXQgcmV0dXJucyBwcmVjZWRpbmcgbm9kZXMgb2YgYSBnaXZlbiBub2RlLgotICAgKiBUaGlzIGluY2x1ZGVzIHRoZSBub2RlIHNldCB7cm9vdCsxLCBzdGFydC0xfSwgYnV0IGV4Y2x1ZGVzCi0gICAqIGFsbCBhbmNlc3RvcnMsIGF0dHJpYnV0ZXMsIGFuZCBuYW1lc3BhY2Ugbm9kZXMuCi0gICAqLwotICBwdWJsaWMgY2xhc3MgUHJlY2VkaW5nSXRlcmF0b3IgZXh0ZW5kcyBJbnRlcm5hbEF4aXNJdGVyYXRvckJhc2UKLSAgewotCi0gICAgLyoqIFRoZSBtYXggYW5jZXN0b3JzLCBidXQgaXQgY2FuIGdyb3cuLi4gKi8KLSAgICBwcml2YXRlIGZpbmFsIGludCBfbWF4QW5jZXN0b3JzID0gODsKLQotICAgIC8qKgotICAgICAqIFRoZSBzdGFjayBvZiBzdGFydCBub2RlICsgYW5jZXN0b3JzIHVwIHRvIHRoZSByb290IG9mIHRoZSB0cmVlLAotICAgICAqICB3aGljaCB3ZSBtdXN0IGF2b2lkLgotICAgICAqLwotICAgIHByb3RlY3RlZCBpbnRbXSBfc3RhY2sgPSBuZXcgaW50W19tYXhBbmNlc3RvcnNdOwotCi0gICAgLyoqIChub3Qgc3VyZSB5ZXQuLi4gLXNiKSAqLwotICAgIHByb3RlY3RlZCBpbnQgX3NwLCBfb2xkc3A7Ci0KLSAgICBwcm90ZWN0ZWQgaW50IF9tYXJrZWRzcCwgX21hcmtlZE5vZGUsIF9tYXJrZWREZXNjZW5kYW50OwotCi0gICAgLyogX2N1cnJlbnROb2RlIHByZWNlZGVzIGNhbmRpZGF0ZXMuICBUaGlzIGlzIHRoZSBpZGVudGl0eSwgbm90IHRoZSBoYW5kbGUhICovCi0KLSAgICAvKioKLSAgICAgKiBUcnVlIGlmIHRoaXMgaXRlcmF0b3IgaGFzIGEgcmV2ZXJzZWQgYXhpcy4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdHJ1ZSBzaW5jZSB0aGlzIGl0ZXJhdG9yIGlzIGEgcmV2ZXJzZWQgYXhpcy4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc1JldmVyc2UoKQotICAgIHsKLSAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYSBkZWVwIGNvcHkgb2YgdGhpcyBpdGVyYXRvci4gICBUaGUgY2xvbmVkIGl0ZXJhdG9yIGlzIG5vdCByZXNldC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gYSBkZWVwIGNvcHkgb2YgdGhpcyBpdGVyYXRvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIGNsb25lSXRlcmF0b3IoKQotICAgIHsKLSAgICAgIF9pc1Jlc3RhcnRhYmxlID0gZmFsc2U7Ci0KLSAgICAgIHRyeQotICAgICAgewotICAgICAgICBmaW5hbCBQcmVjZWRpbmdJdGVyYXRvciBjbG9uZSA9IChQcmVjZWRpbmdJdGVyYXRvcikgc3VwZXIuY2xvbmUoKTsKLSAgICAgICAgZmluYWwgaW50W10gc3RhY2tDb3B5ID0gbmV3IGludFtfc3RhY2subGVuZ3RoXTsKLSAgICAgICAgU3lzdGVtLmFycmF5Y29weShfc3RhY2ssIDAsIHN0YWNrQ29weSwgMCwgX3N0YWNrLmxlbmd0aCk7Ci0KLSAgICAgICAgY2xvbmUuX3N0YWNrID0gc3RhY2tDb3B5OwotCi0gICAgICAgIC8vIHJldHVybiBjbG9uZS5yZXNldCgpOwotICAgICAgICByZXR1cm4gY2xvbmU7Ci0gICAgICB9Ci0gICAgICBjYXRjaCAoQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gZSkKLSAgICAgIHsKLSAgICAgICAgdGhyb3cgbmV3IERUTUV4Y2VwdGlvbihYTUxNZXNzYWdlcy5jcmVhdGVYTUxNZXNzYWdlKFhNTEVycm9yUmVzb3VyY2VzLkVSX0lURVJBVE9SX0NMT05FX05PVF9TVVBQT1JURUQsIG51bGwpKTsgLy8iSXRlcmF0b3IgY2xvbmUgbm90IHN1cHBvcnRlZC4iKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgc3RhcnQgdG8gRU5EIHNob3VsZCAnY2xvc2UnIHRoZSBpdGVyYXRvciwKLSAgICAgKiBpLmUuIHN1YnNlcXVlbnQgY2FsbCB0byBuZXh0KCkgc2hvdWxkIHJldHVybiBFTkQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbm9kZSBTZXRzIHRoZSByb290IG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIEEgRFRNQXhpc0l0ZXJhdG9yIHNldCB0byB0aGUgc3RhcnQgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIHNldFN0YXJ0Tm9kZShpbnQgbm9kZSkKLSAgICB7Ci0vLyVIWiU6IEFkZGVkIHJlZmVyZW5jZSB0byBEVE1EZWZhdWx0QmFzZS5ST09UTk9ERSBiYWNrIGluLCB0ZW1wb3JhcmlseQotICAgICAgaWYgKG5vZGUgPT0gRFRNRGVmYXVsdEJhc2UuUk9PVE5PREUpCi0gICAgICAgIG5vZGUgPSBnZXREb2N1bWVudCgpOwotICAgICAgaWYgKF9pc1Jlc3RhcnRhYmxlKQotICAgICAgewotICAgICAgICBub2RlID0gbWFrZU5vZGVJZGVudGl0eShub2RlKTsKLQotICAgICAgICAvLyBpdGVyYXRvciBpcyBub3QgYSBjbG9uZQotICAgICAgICBpbnQgcGFyZW50LCBpbmRleDsKLQotICAgICAgIGlmIChfdHlwZTIobm9kZSkgPT0gRFRNLkFUVFJJQlVURV9OT0RFKQotICAgICAgICAgbm9kZSA9IF9wYXJlbnQyKG5vZGUpOwotCi0gICAgICAgIF9zdGFydE5vZGUgPSBub2RlOwotICAgICAgICBfc3RhY2tbaW5kZXggPSAwXSA9IG5vZGU7Ci0KLSAgICAgICAgcGFyZW50PW5vZGU7Ci0gICAgICAgIHdoaWxlICgocGFyZW50ID0gX3BhcmVudDIocGFyZW50KSkgIT0gTlVMTCkKLSAgICAgICAgewotICAgICAgICAgIGlmICgrK2luZGV4ID09IF9zdGFjay5sZW5ndGgpCi0gICAgICAgICAgewotICAgICAgICAgICAgZmluYWwgaW50W10gc3RhY2sgPSBuZXcgaW50W2luZGV4KjJdOwotICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShfc3RhY2ssIDAsIHN0YWNrLCAwLCBpbmRleCk7Ci0gICAgICAgICAgICBfc3RhY2sgPSBzdGFjazsKLSAgICAgICAgICB9Ci0gICAgICAgICAgX3N0YWNrW2luZGV4XSA9IHBhcmVudDsKLSAgICAgICAgfQotCi0gICAgICAgIGlmKGluZGV4PjApCi0gICAgICAgICAgLS1pbmRleDsgLy8gUG9wIGFjdHVhbCByb290IG5vZGUgKGlmIG5vdCBzdGFydCkgYmFjayBvZmYgdGhlIHN0YWNrCi0KLSAgICAgICAgX2N1cnJlbnROb2RlPV9zdGFja1tpbmRleF07IC8vIExhc3QgcGFyZW50IGJlZm9yZSByb290IG5vZGUKLQotICAgICAgICBfb2xkc3AgPSBfc3AgPSBpbmRleDsKLQotICAgICAgICByZXR1cm4gcmVzZXRQb3NpdGlvbigpOwotICAgICAgfQotCi0gICAgICByZXR1cm4gdGhpczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIG5leHQgbm9kZSBpbiB0aGUgaXRlcmF0aW9uLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgbmV4dCBub2RlIGhhbmRsZSBpbiB0aGUgaXRlcmF0aW9uLCBvciBFTkQuCi0gICAgICovCi0gICAgcHVibGljIGludCBuZXh0KCkKLSAgICB7Ci0gICAgICAgIC8vIEJ1Z3ppbGxhIDgzMjQ6IFdlIHdlcmUgZm9yZ2V0dGluZyB0byBza2lwIEF0dHJzIGFuZCBOUyBub2Rlcy4KLSAgICAgICAgLy8gQWxzbyByZWNvZGVkIHRoZSBsb29wIGNvbnRyb2xzIGZvciBjbGFyaXR5IGFuZCB0byBmbGF0dGVuIG91dAotICAgICAgICAvLyB0aGUgdGFpbC1yZWN1cnNpb24uCi0gICAgICAgIGZvcigrK19jdXJyZW50Tm9kZTsgX3NwPj0wOyArK19jdXJyZW50Tm9kZSkKLSAgICAgICAgewotICAgICAgICAgIGlmKF9jdXJyZW50Tm9kZSA8IF9zdGFja1tfc3BdKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGludCB0eXBlID0gX3R5cGUyKF9jdXJyZW50Tm9kZSk7Ci0gICAgICAgICAgICBpZih0eXBlICE9IEFUVFJJQlVURV9OT0RFICYmIHR5cGUgIT0gTkFNRVNQQUNFX05PREUpCi0gICAgICAgICAgICAgIHJldHVybiByZXR1cm5Ob2RlKG1ha2VOb2RlSGFuZGxlKF9jdXJyZW50Tm9kZSkpOwotICAgICAgICAgIH0KLSAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAtLV9zcDsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gTlVMTDsKLSAgICB9Ci0KLSAgICAvLyByZWRlZmluZSBEVE1BeGlzSXRlcmF0b3JCYXNlJ3MgcmVzZXQKLQotICAgIC8qKgotICAgICAqIFJlc2V0cyB0aGUgaXRlcmF0b3IgdG8gdGhlIGxhc3Qgc3RhcnQgbm9kZS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gQSBEVE1BeGlzSXRlcmF0b3IsIHdoaWNoIG1heSBvciBtYXkgbm90IGJlIHRoZSBzYW1lIGFzIHRoaXMKLSAgICAgKiAgICAgICAgIGl0ZXJhdG9yLgotICAgICAqLwotICAgIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3IgcmVzZXQoKQotICAgIHsKLQotICAgICAgX3NwID0gX29sZHNwOwotCi0gICAgICByZXR1cm4gcmVzZXRQb3NpdGlvbigpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldE1hcmsoKSB7Ci0gICAgICAgIF9tYXJrZWRzcCA9IF9zcDsKLSAgICAgICAgX21hcmtlZE5vZGUgPSBfY3VycmVudE5vZGU7Ci0gICAgICAgIF9tYXJrZWREZXNjZW5kYW50ID0gX3N0YWNrWzBdOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGdvdG9NYXJrKCkgewotICAgICAgICBfc3AgPSBfbWFya2Vkc3A7Ci0gICAgICAgIF9jdXJyZW50Tm9kZSA9IF9tYXJrZWROb2RlOwotICAgIH0KLSAgfSAgLy8gZW5kIG9mIFByZWNlZGluZ0l0ZXJhdG9yCi0KLSAgLyoqCi0gICAqIEl0ZXJhdG9yIHRoYXQgcmV0dXJucyBwcmVjZWRpbmcgbm9kZXMgb2YgYWdpdmVuIHR5cGUgZm9yIGEKLSAgICogZ2l2ZW4gbm9kZS4gVGhpcyBpbmNsdWRlcyB0aGUgbm9kZSBzZXQge3Jvb3QrMSwgc3RhcnQtMX0sIGJ1dAotICAgKiBleGNsdWRlcyBhbGwgYW5jZXN0b3JzLgotICAgKi8KLSAgcHVibGljIGZpbmFsIGNsYXNzIFR5cGVkUHJlY2VkaW5nSXRlcmF0b3IgZXh0ZW5kcyBQcmVjZWRpbmdJdGVyYXRvcgotICB7Ci0KLSAgICAvKiogVGhlIGV4dGVuZGVkIHR5cGUgSUQgdGhhdCB3YXMgcmVxdWVzdGVkLiAqLwotICAgIHByaXZhdGUgZmluYWwgaW50IF9ub2RlVHlwZTsKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdG9yIFR5cGVkUHJlY2VkaW5nSXRlcmF0b3IKLSAgICAgKgotICAgICAqCi0gICAgICogQHBhcmFtIHR5cGUgVGhlIGV4dGVuZGVkIHR5cGUgSUQgYmVpbmcgcmVxdWVzdGVkLgotICAgICAqLwotICAgIHB1YmxpYyBUeXBlZFByZWNlZGluZ0l0ZXJhdG9yKGludCB0eXBlKQotICAgIHsKLSAgICAgIF9ub2RlVHlwZSA9IHR5cGU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBuZXh0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIG5leHQgbm9kZSBoYW5kbGUgaW4gdGhlIGl0ZXJhdGlvbiwgb3IgRU5ELgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgbmV4dCgpCi0gICAgewotICAgICAgaW50IG5vZGUgPSBfY3VycmVudE5vZGU7Ci0gICAgICBmaW5hbCBpbnQgbm9kZVR5cGUgPSBfbm9kZVR5cGU7Ci0KLSAgICAgIGlmIChub2RlVHlwZSA+PSBEVE0uTlRZUEVTKSB7Ci0gICAgICAgIHdoaWxlICh0cnVlKSB7Ci0gICAgICAgICAgbm9kZSsrOwotCi0gICAgICAgICAgaWYgKF9zcCA8IDApIHsKLSAgICAgICAgICAgIG5vZGUgPSBOVUxMOwotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UgaWYgKG5vZGUgPj0gX3N0YWNrW19zcF0pIHsKLSAgICAgICAgICAgIGlmICgtLV9zcCA8IDApIHsKLSAgICAgICAgICAgICAgbm9kZSA9IE5VTEw7Ci0gICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotICAgICAgICAgIH0KLSAgICAgICAgICBlbHNlIGlmIChfZXhwdHlwZTIobm9kZSkgPT0gbm9kZVR5cGUpIHsKLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgfQotICAgICAgZWxzZSB7Ci0gICAgICAgIGludCBleHBUeXBlOwotCi0gICAgICAgIHdoaWxlICh0cnVlKSB7Ci0gICAgICAgICAgbm9kZSsrOwotCi0gICAgICAgICAgaWYgKF9zcCA8IDApIHsKLSAgICAgICAgICAgIG5vZGUgPSBOVUxMOwotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UgaWYgKG5vZGUgPj0gX3N0YWNrW19zcF0pIHsKLSAgICAgICAgICAgIGlmICgtLV9zcCA8IDApIHsKLSAgICAgICAgICAgICAgbm9kZSA9IE5VTEw7Ci0gICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotICAgICAgICAgIH0KLSAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIGV4cFR5cGUgPSBfZXhwdHlwZTIobm9kZSk7Ci0gICAgICAgICAgICBpZiAoZXhwVHlwZSA8IERUTS5OVFlQRVMpIHsKLSAgICAgICAgICAgICAgaWYgKGV4cFR5cGUgPT0gbm9kZVR5cGUpIHsKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgIGlmIChtX2V4dGVuZGVkVHlwZXNbZXhwVHlwZV0uZ2V0Tm9kZVR5cGUoKSA9PSBub2RlVHlwZSkgewotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICB9Ci0KLSAgICAgIF9jdXJyZW50Tm9kZSA9IG5vZGU7Ci0KLSAgICAgIHJldHVybiAobm9kZSA9PSBOVUxMKSA/IE5VTEwgOiByZXR1cm5Ob2RlKG1ha2VOb2RlSGFuZGxlKG5vZGUpKTsKLSAgICB9Ci0gIH0gIC8vIGVuZCBvZiBUeXBlZFByZWNlZGluZ0l0ZXJhdG9yCi0KLSAgLyoqCi0gICAqIEl0ZXJhdG9yIHRoYXQgcmV0dXJucyBmb2xsb3dpbmcgbm9kZXMgb2YgZm9yIGEgZ2l2ZW4gbm9kZS4KLSAgICovCi0gIHB1YmxpYyBjbGFzcyBGb2xsb3dpbmdJdGVyYXRvciBleHRlbmRzIEludGVybmFsQXhpc0l0ZXJhdG9yQmFzZQotICB7Ci0gICAgLy9EVE1BeGlzVHJhdmVyc2VyIG1fdHJhdmVyc2VyOyAvLyBlYXNpZXIgZm9yIG5vdwotCi0gICAgcHVibGljIEZvbGxvd2luZ0l0ZXJhdG9yKCkKLSAgICB7Ci0gICAgICAvL21fdHJhdmVyc2VyID0gZ2V0QXhpc1RyYXZlcnNlcihBeGlzLkZPTExPV0lORyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0IHN0YXJ0IHRvIEVORCBzaG91bGQgJ2Nsb3NlJyB0aGUgaXRlcmF0b3IsCi0gICAgICogaS5lLiBzdWJzZXF1ZW50IGNhbGwgdG8gbmV4dCgpIHNob3VsZCByZXR1cm4gRU5ELgotICAgICAqCi0gICAgICogQHBhcmFtIG5vZGUgU2V0cyB0aGUgcm9vdCBvZiB0aGUgaXRlcmF0aW9uLgotICAgICAqCi0gICAgICogQHJldHVybiBBIERUTUF4aXNJdGVyYXRvciBzZXQgdG8gdGhlIHN0YXJ0IG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICovCi0gICAgcHVibGljIERUTUF4aXNJdGVyYXRvciBzZXRTdGFydE5vZGUoaW50IG5vZGUpCi0gICAgewotLy8lSFolOiBBZGRlZCByZWZlcmVuY2UgdG8gRFRNRGVmYXVsdEJhc2UuUk9PVE5PREUgYmFjayBpbiwgdGVtcG9yYXJpbHkKLSAgICAgIGlmIChub2RlID09IERUTURlZmF1bHRCYXNlLlJPT1ROT0RFKQotICAgICAgICBub2RlID0gZ2V0RG9jdW1lbnQoKTsKLSAgICAgIGlmIChfaXNSZXN0YXJ0YWJsZSkKLSAgICAgIHsKLSAgICAgICAgX3N0YXJ0Tm9kZSA9IG5vZGU7Ci0KLSAgICAgICAgLy9fY3VycmVudE5vZGUgPSBtX3RyYXZlcnNlci5maXJzdChub2RlKTsKLQotICAgICAgICBub2RlID0gbWFrZU5vZGVJZGVudGl0eShub2RlKTsKLQotICAgICAgICBpbnQgZmlyc3Q7Ci0gICAgICAgIGludCB0eXBlID0gX3R5cGUyKG5vZGUpOwotCi0gICAgICAgIGlmICgoRFRNLkFUVFJJQlVURV9OT0RFID09IHR5cGUpIHx8IChEVE0uTkFNRVNQQUNFX05PREUgPT0gdHlwZSkpCi0gICAgICAgIHsKLSAgICAgICAgICBub2RlID0gX3BhcmVudDIobm9kZSk7Ci0gICAgICAgICAgZmlyc3QgPSBfZmlyc3RjaDIobm9kZSk7Ci0KLSAgICAgICAgICBpZiAoTlVMTCAhPSBmaXJzdCkgewotICAgICAgICAgICAgX2N1cnJlbnROb2RlID0gbWFrZU5vZGVIYW5kbGUoZmlyc3QpOwotICAgICAgICAgICAgcmV0dXJuIHJlc2V0UG9zaXRpb24oKTsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBkbwotICAgICAgICB7Ci0gICAgICAgICAgZmlyc3QgPSBfbmV4dHNpYjIobm9kZSk7Ci0KLSAgICAgICAgICBpZiAoTlVMTCA9PSBmaXJzdCkKLSAgICAgICAgICAgIG5vZGUgPSBfcGFyZW50Mihub2RlKTsKLSAgICAgICAgfQotICAgICAgICB3aGlsZSAoTlVMTCA9PSBmaXJzdCAmJiBOVUxMICE9IG5vZGUpOwotCi0gICAgICAgIF9jdXJyZW50Tm9kZSA9IG1ha2VOb2RlSGFuZGxlKGZpcnN0KTsKLQotICAgICAgICAvLyBfY3VycmVudE5vZGUgcHJlY2VkZXMgcG9zc2libGUgZm9sbG93aW5nKG5vZGUpIG5vZGVzCi0gICAgICAgIHJldHVybiByZXNldFBvc2l0aW9uKCk7Ci0gICAgICB9Ci0KLSAgICAgIHJldHVybiB0aGlzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgbmV4dCBub2RlIGluIHRoZSBpdGVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBuZXh0IG5vZGUgaGFuZGxlIGluIHRoZSBpdGVyYXRpb24sIG9yIEVORC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IG5leHQoKQotICAgIHsKLQotICAgICAgaW50IG5vZGUgPSBfY3VycmVudE5vZGU7Ci0KLSAgICAgIC8vX2N1cnJlbnROb2RlID0gbV90cmF2ZXJzZXIubmV4dChfc3RhcnROb2RlLCBfY3VycmVudE5vZGUpOwotICAgICAgaW50IGN1cnJlbnQgPSBtYWtlTm9kZUlkZW50aXR5KG5vZGUpOwotCi0gICAgICB3aGlsZSAodHJ1ZSkKLSAgICAgIHsKLSAgICAgICAgY3VycmVudCsrOwotCi0gICAgICAgIGludCB0eXBlID0gX3R5cGUyKGN1cnJlbnQpOwotICAgICAgICBpZiAoTlVMTCA9PSB0eXBlKSB7Ci0gICAgICAgICAgX2N1cnJlbnROb2RlID0gTlVMTDsKLSAgICAgICAgICByZXR1cm4gcmV0dXJuTm9kZShub2RlKTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChBVFRSSUJVVEVfTk9ERSA9PSB0eXBlIHx8IE5BTUVTUEFDRV9OT0RFID09IHR5cGUpCi0gICAgICAgICAgY29udGludWU7Ci0KLSAgICAgICAgX2N1cnJlbnROb2RlID0gbWFrZU5vZGVIYW5kbGUoY3VycmVudCk7Ci0gICAgICAgIHJldHVybiByZXR1cm5Ob2RlKG5vZGUpOwotICAgICAgfQotICAgIH0KLQotICB9ICAvLyBlbmQgb2YgRm9sbG93aW5nSXRlcmF0b3IKLQotICAvKioKLSAgICogSXRlcmF0b3IgdGhhdCByZXR1cm5zIGZvbGxvd2luZyBub2RlcyBvZiBhIGdpdmVuIHR5cGUgZm9yIGEgZ2l2ZW4gbm9kZS4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBjbGFzcyBUeXBlZEZvbGxvd2luZ0l0ZXJhdG9yIGV4dGVuZHMgRm9sbG93aW5nSXRlcmF0b3IKLSAgewotCi0gICAgLyoqIFRoZSBleHRlbmRlZCB0eXBlIElEIHRoYXQgd2FzIHJlcXVlc3RlZC4gKi8KLSAgICBwcml2YXRlIGZpbmFsIGludCBfbm9kZVR5cGU7Ci0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RvciBUeXBlZEZvbGxvd2luZ0l0ZXJhdG9yCi0gICAgICoKLSAgICAgKgotICAgICAqIEBwYXJhbSB0eXBlIFRoZSBleHRlbmRlZCB0eXBlIElEIGJlaW5nIHJlcXVlc3RlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgVHlwZWRGb2xsb3dpbmdJdGVyYXRvcihpbnQgdHlwZSkKLSAgICB7Ci0gICAgICBfbm9kZVR5cGUgPSB0eXBlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgbmV4dCBub2RlIGluIHRoZSBpdGVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBuZXh0IG5vZGUgaGFuZGxlIGluIHRoZSBpdGVyYXRpb24sIG9yIEVORC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IG5leHQoKQotICAgIHsKLSAgICAgIGludCBjdXJyZW50OwotICAgICAgaW50IG5vZGU7Ci0gICAgICBpbnQgdHlwZTsKLQotICAgICAgZmluYWwgaW50IG5vZGVUeXBlID0gX25vZGVUeXBlOwotICAgICAgaW50IGN1cnJlbnROb2RlSUQgPSBtYWtlTm9kZUlkZW50aXR5KF9jdXJyZW50Tm9kZSk7Ci0KLSAgICAgIGlmIChub2RlVHlwZSA+PSBEVE0uTlRZUEVTKSB7Ci0gICAgICAgIGRvIHsKLSAgICAgICAgICBub2RlID0gY3VycmVudE5vZGVJRDsKLSAgICAgICAgICBjdXJyZW50ID0gbm9kZTsKLQotICAgICAgICAgIGRvIHsKLSAgICAgICAgICAgIGN1cnJlbnQrKzsKLSAgICAgICAgICAgIHR5cGUgPSBfdHlwZTIoY3VycmVudCk7Ci0gICAgICAgICAgfQotICAgICAgICAgIHdoaWxlICh0eXBlICE9IE5VTEwgJiYgKEFUVFJJQlVURV9OT0RFID09IHR5cGUgfHwgTkFNRVNQQUNFX05PREUgPT0gdHlwZSkpOwotCi0gICAgICAgICAgY3VycmVudE5vZGVJRCA9ICh0eXBlICE9IE5VTEwpID8gY3VycmVudCA6IE5VTEw7Ci0gICAgICAgIH0KLSAgICAgICAgd2hpbGUgKG5vZGUgIT0gRFRNLk5VTEwgJiYgX2V4cHR5cGUyKG5vZGUpICE9IG5vZGVUeXBlKTsKLSAgICAgIH0KLSAgICAgIGVsc2UgewotICAgICAgICBkbyB7Ci0gICAgICAgICAgbm9kZSA9IGN1cnJlbnROb2RlSUQ7Ci0gICAgICAgICAgY3VycmVudCA9IG5vZGU7Ci0KLSAgICAgICAgICBkbyB7Ci0gICAgICAgICAgICBjdXJyZW50Kys7Ci0gICAgICAgICAgICB0eXBlID0gX3R5cGUyKGN1cnJlbnQpOwotICAgICAgICAgIH0KLSAgICAgICAgICB3aGlsZSAodHlwZSAhPSBOVUxMICYmIChBVFRSSUJVVEVfTk9ERSA9PSB0eXBlIHx8IE5BTUVTUEFDRV9OT0RFID09IHR5cGUpKTsKLQotICAgICAgICAgIGN1cnJlbnROb2RlSUQgPSAodHlwZSAhPSBOVUxMKSA/IGN1cnJlbnQgOiBOVUxMOwotICAgICAgICB9Ci0gICAgICAgIHdoaWxlIChub2RlICE9IERUTS5OVUxMCi0gICAgICAgICAgICAgICAmJiAoX2V4cHR5cGUyKG5vZGUpICE9IG5vZGVUeXBlICYmIF90eXBlMihub2RlKSAhPSBub2RlVHlwZSkpOwotICAgICAgfQotCi0gICAgICBfY3VycmVudE5vZGUgPSBtYWtlTm9kZUhhbmRsZShjdXJyZW50Tm9kZUlEKTsKLSAgICAgIHJldHVybiAobm9kZSA9PSBEVE0uTlVMTCA/IERUTS5OVUxMIDpyZXR1cm5Ob2RlKG1ha2VOb2RlSGFuZGxlKG5vZGUpKSk7Ci0gICAgfQotICB9ICAvLyBlbmQgb2YgVHlwZWRGb2xsb3dpbmdJdGVyYXRvcgotCi0gIC8qKgotICAgKiBJdGVyYXRvciB0aGF0IHJldHVybnMgdGhlIGFuY2VzdG9ycyBvZiBhIGdpdmVuIG5vZGUgaW4gZG9jdW1lbnQKLSAgICogb3JkZXIuICAoTk9URSEgIFRoaXMgd2FzIGNoYW5nZWQgZnJvbSB0aGUgWFNMVEMgY29kZSEpCi0gICAqLwotICBwdWJsaWMgY2xhc3MgQW5jZXN0b3JJdGVyYXRvciBleHRlbmRzIEludGVybmFsQXhpc0l0ZXJhdG9yQmFzZQotICB7Ci0gICAgLy8gVGhlIGluaXRpYWwgc2l6ZSBvZiB0aGUgYW5jZXN0b3IgYXJyYXkKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgbV9ibG9ja3NpemUgPSAzMjsKLQotICAgIC8vIFRoZSBhcnJheSBmb3IgYW5jZXN0b3Igbm9kZXMuIFRoaXMgYXJyYXkgd2lsbCBncm93IGR5bmFtaWNhbGx5LgotICAgIGludFtdIG1fYW5jZXN0b3JzID0gbmV3IGludFttX2Jsb2Nrc2l6ZV07Ci0KLSAgICAvLyBOdW1iZXIgb2YgYW5jZXN0b3Igbm9kZXMgaW4gdGhlIGFycmF5Ci0gICAgaW50IG1fc2l6ZSA9IDA7Ci0KLSAgICBpbnQgbV9hbmNlc3RvcnNQb3M7Ci0KLSAgICBpbnQgbV9tYXJrZWRQb3M7Ci0KLSAgICAvKiogVGhlIHJlYWwgc3RhcnQgbm9kZSBmb3IgdGhpcyBheGVzLCBzaW5jZSBfc3RhcnROb2RlIHdpbGwgYmUgYWRqdXN0ZWQuICovCi0gICAgaW50IG1fcmVhbFN0YXJ0Tm9kZTsKLQotICAgIC8qKgotICAgICAqIEdldCBzdGFydCB0byBFTkQgc2hvdWxkICdjbG9zZScgdGhlIGl0ZXJhdG9yLAotICAgICAqIGkuZS4gc3Vic2VxdWVudCBjYWxsIHRvIG5leHQoKSBzaG91bGQgcmV0dXJuIEVORC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIHJvb3Qgbm9kZSBvZiB0aGUgaXRlcmF0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0U3RhcnROb2RlKCkKLSAgICB7Ci0gICAgICByZXR1cm4gbV9yZWFsU3RhcnROb2RlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRydWUgaWYgdGhpcyBpdGVyYXRvciBoYXMgYSByZXZlcnNlZCBheGlzLgotICAgICAqCi0gICAgICogQHJldHVybiB0cnVlIHNpbmNlIHRoaXMgaXRlcmF0b3IgaXMgYSByZXZlcnNlZCBheGlzLgotICAgICAqLwotICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzUmV2ZXJzZSgpCi0gICAgewotICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhIGRlZXAgY29weSBvZiB0aGlzIGl0ZXJhdG9yLiAgVGhlIGNsb25lZCBpdGVyYXRvciBpcyBub3QgcmVzZXQuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIGEgZGVlcCBjb3B5IG9mIHRoaXMgaXRlcmF0b3IuCi0gICAgICovCi0gICAgcHVibGljIERUTUF4aXNJdGVyYXRvciBjbG9uZUl0ZXJhdG9yKCkKLSAgICB7Ci0gICAgICBfaXNSZXN0YXJ0YWJsZSA9IGZhbHNlOyAgLy8gbXVzdCBzZXQgdG8gZmFsc2UgZm9yIGFueSBjbG9uZQotCi0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgZmluYWwgQW5jZXN0b3JJdGVyYXRvciBjbG9uZSA9IChBbmNlc3Rvckl0ZXJhdG9yKSBzdXBlci5jbG9uZSgpOwotCi0gICAgICAgIGNsb25lLl9zdGFydE5vZGUgPSBfc3RhcnROb2RlOwotCi0gICAgICAgIC8vIHJldHVybiBjbG9uZS5yZXNldCgpOwotICAgICAgICByZXR1cm4gY2xvbmU7Ci0gICAgICB9Ci0gICAgICBjYXRjaCAoQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gZSkKLSAgICAgIHsKLSAgICAgICAgdGhyb3cgbmV3IERUTUV4Y2VwdGlvbihYTUxNZXNzYWdlcy5jcmVhdGVYTUxNZXNzYWdlKFhNTEVycm9yUmVzb3VyY2VzLkVSX0lURVJBVE9SX0NMT05FX05PVF9TVVBQT1JURUQsIG51bGwpKTsgLy8iSXRlcmF0b3IgY2xvbmUgbm90IHN1cHBvcnRlZC4iKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgc3RhcnQgdG8gRU5EIHNob3VsZCAnY2xvc2UnIHRoZSBpdGVyYXRvciwKLSAgICAgKiBpLmUuIHN1YnNlcXVlbnQgY2FsbCB0byBuZXh0KCkgc2hvdWxkIHJldHVybiBFTkQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbm9kZSBTZXRzIHRoZSByb290IG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIEEgRFRNQXhpc0l0ZXJhdG9yIHNldCB0byB0aGUgc3RhcnQgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIHNldFN0YXJ0Tm9kZShpbnQgbm9kZSkKLSAgICB7Ci0vLyVIWiU6IEFkZGVkIHJlZmVyZW5jZSB0byBEVE1EZWZhdWx0QmFzZS5ST09UTk9ERSBiYWNrIGluLCB0ZW1wb3JhcmlseQotICAgICAgaWYgKG5vZGUgPT0gRFRNRGVmYXVsdEJhc2UuUk9PVE5PREUpCi0gICAgICAgIG5vZGUgPSBnZXREb2N1bWVudCgpOwotICAgICAgbV9yZWFsU3RhcnROb2RlID0gbm9kZTsKLQotICAgICAgaWYgKF9pc1Jlc3RhcnRhYmxlKQotICAgICAgewotICAgICAgICBpbnQgbm9kZUlEID0gbWFrZU5vZGVJZGVudGl0eShub2RlKTsKLSAgICAgICAgbV9zaXplID0gMDsKLQotICAgICAgICBpZiAobm9kZUlEID09IERUTS5OVUxMKSB7Ci0gICAgICAgICAgX2N1cnJlbnROb2RlID0gRFRNLk5VTEw7Ci0gICAgICAgICAgbV9hbmNlc3RvcnNQb3MgPSAwOwotICAgICAgICAgIHJldHVybiB0aGlzOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gU3RhcnQgZnJvbSB0aGUgY3VycmVudCBub2RlJ3MgcGFyZW50IGlmCi0gICAgICAgIC8vIF9pbmNsdWRlU2VsZiBpcyBmYWxzZS4KLSAgICAgICAgaWYgKCFfaW5jbHVkZVNlbGYpIHsKLSAgICAgICAgICBub2RlSUQgPSBfcGFyZW50Mihub2RlSUQpOwotICAgICAgICAgIG5vZGUgPSBtYWtlTm9kZUhhbmRsZShub2RlSUQpOwotICAgICAgICB9Ci0KLSAgICAgICAgX3N0YXJ0Tm9kZSA9IG5vZGU7Ci0KLSAgICAgICAgd2hpbGUgKG5vZGVJRCAhPSBFTkQpIHsKLSAgICAgICAgICAvL21fYW5jZXN0b3JzLmFkZEVsZW1lbnQobm9kZSk7Ci0gICAgICAgICAgaWYgKG1fc2l6ZSA+PSBtX2FuY2VzdG9ycy5sZW5ndGgpCi0gICAgICAgICAgewotICAgICAgICAgICAgaW50W10gbmV3QW5jZXN0b3JzID0gbmV3IGludFttX3NpemUgKiAyXTsKLSAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkobV9hbmNlc3RvcnMsIDAsIG5ld0FuY2VzdG9ycywgMCwgbV9hbmNlc3RvcnMubGVuZ3RoKTsKLSAgICAgICAgICAgIG1fYW5jZXN0b3JzID0gbmV3QW5jZXN0b3JzOwotICAgICAgICAgIH0KLQotICAgICAgICAgIG1fYW5jZXN0b3JzW21fc2l6ZSsrXSA9IG5vZGU7Ci0gICAgICAgICAgbm9kZUlEID0gX3BhcmVudDIobm9kZUlEKTsKLSAgICAgICAgICBub2RlID0gbWFrZU5vZGVIYW5kbGUobm9kZUlEKTsKLSAgICAgICAgfQotCi0gICAgICAgIG1fYW5jZXN0b3JzUG9zID0gbV9zaXplIC0gMTsKLQotICAgICAgICBfY3VycmVudE5vZGUgPSAobV9hbmNlc3RvcnNQb3M+PTApCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBtX2FuY2VzdG9yc1ttX2FuY2VzdG9yc1Bvc10KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IERUTS5OVUxMOwotCi0gICAgICAgIHJldHVybiByZXNldFBvc2l0aW9uKCk7Ci0gICAgICB9Ci0KLSAgICAgIHJldHVybiB0aGlzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJlc2V0cyB0aGUgaXRlcmF0b3IgdG8gdGhlIGxhc3Qgc3RhcnQgbm9kZS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gQSBEVE1BeGlzSXRlcmF0b3IsIHdoaWNoIG1heSBvciBtYXkgbm90IGJlIHRoZSBzYW1lIGFzIHRoaXMKLSAgICAgKiAgICAgICAgIGl0ZXJhdG9yLgotICAgICAqLwotICAgIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3IgcmVzZXQoKQotICAgIHsKLQotICAgICAgbV9hbmNlc3RvcnNQb3MgPSBtX3NpemUgLSAxOwotCi0gICAgICBfY3VycmVudE5vZGUgPSAobV9hbmNlc3RvcnNQb3MgPj0gMCkgPyBtX2FuY2VzdG9yc1ttX2FuY2VzdG9yc1Bvc10KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBEVE0uTlVMTDsKLQotICAgICAgcmV0dXJuIHJlc2V0UG9zaXRpb24oKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIG5leHQgbm9kZSBpbiB0aGUgaXRlcmF0aW9uLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgbmV4dCBub2RlIGhhbmRsZSBpbiB0aGUgaXRlcmF0aW9uLCBvciBFTkQuCi0gICAgICovCi0gICAgcHVibGljIGludCBuZXh0KCkKLSAgICB7Ci0KLSAgICAgIGludCBuZXh0ID0gX2N1cnJlbnROb2RlOwotCi0gICAgICBpbnQgcG9zID0gLS1tX2FuY2VzdG9yc1BvczsKLQotICAgICAgX2N1cnJlbnROb2RlID0gKHBvcyA+PSAwKSA/IG1fYW5jZXN0b3JzW21fYW5jZXN0b3JzUG9zXQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IERUTS5OVUxMOwotCi0gICAgICByZXR1cm4gcmV0dXJuTm9kZShuZXh0KTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRNYXJrKCkgewotICAgICAgICBtX21hcmtlZFBvcyA9IG1fYW5jZXN0b3JzUG9zOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGdvdG9NYXJrKCkgewotICAgICAgICBtX2FuY2VzdG9yc1BvcyA9IG1fbWFya2VkUG9zOwotICAgICAgICBfY3VycmVudE5vZGUgPSBtX2FuY2VzdG9yc1Bvcz49MCA/IG1fYW5jZXN0b3JzW21fYW5jZXN0b3JzUG9zXQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IERUTS5OVUxMOwotICAgIH0KLSAgfSAgLy8gZW5kIG9mIEFuY2VzdG9ySXRlcmF0b3IKLQotICAvKioKLSAgICogVHlwZWQgaXRlcmF0b3IgdGhhdCByZXR1cm5zIHRoZSBhbmNlc3RvcnMgb2YgYSBnaXZlbiBub2RlLgotICAgKi8KLSAgcHVibGljIGZpbmFsIGNsYXNzIFR5cGVkQW5jZXN0b3JJdGVyYXRvciBleHRlbmRzIEFuY2VzdG9ySXRlcmF0b3IKLSAgewotCi0gICAgLyoqIFRoZSBleHRlbmRlZCB0eXBlIElEIHRoYXQgd2FzIHJlcXVlc3RlZC4gKi8KLSAgICBwcml2YXRlIGZpbmFsIGludCBfbm9kZVR5cGU7Ci0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RvciBUeXBlZEFuY2VzdG9ySXRlcmF0b3IKLSAgICAgKgotICAgICAqCi0gICAgICogQHBhcmFtIHR5cGUgVGhlIGV4dGVuZGVkIHR5cGUgSUQgYmVpbmcgcmVxdWVzdGVkLgotICAgICAqLwotICAgIHB1YmxpYyBUeXBlZEFuY2VzdG9ySXRlcmF0b3IoaW50IHR5cGUpCi0gICAgewotICAgICAgX25vZGVUeXBlID0gdHlwZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgc3RhcnQgdG8gRU5EIHNob3VsZCAnY2xvc2UnIHRoZSBpdGVyYXRvciwKLSAgICAgKiBpLmUuIHN1YnNlcXVlbnQgY2FsbCB0byBuZXh0KCkgc2hvdWxkIHJldHVybiBFTkQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbm9kZSBTZXRzIHRoZSByb290IG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIEEgRFRNQXhpc0l0ZXJhdG9yIHNldCB0byB0aGUgc3RhcnQgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIHNldFN0YXJ0Tm9kZShpbnQgbm9kZSkKLSAgICB7Ci0vLyVIWiU6IEFkZGVkIHJlZmVyZW5jZSB0byBEVE1EZWZhdWx0QmFzZS5ST09UTk9ERSBiYWNrIGluLCB0ZW1wb3JhcmlseQotICAgICAgaWYgKG5vZGUgPT0gRFRNRGVmYXVsdEJhc2UuUk9PVE5PREUpCi0gICAgICAgIG5vZGUgPSBnZXREb2N1bWVudCgpOwotICAgICAgbV9yZWFsU3RhcnROb2RlID0gbm9kZTsKLQotICAgICAgaWYgKF9pc1Jlc3RhcnRhYmxlKQotICAgICAgewotICAgICAgICBpbnQgbm9kZUlEID0gbWFrZU5vZGVJZGVudGl0eShub2RlKTsKLSAgICAgICAgbV9zaXplID0gMDsKLQotICAgICAgICBpZiAobm9kZUlEID09IERUTS5OVUxMKSB7Ci0gICAgICAgICAgX2N1cnJlbnROb2RlID0gRFRNLk5VTEw7Ci0gICAgICAgICAgbV9hbmNlc3RvcnNQb3MgPSAwOwotICAgICAgICAgIHJldHVybiB0aGlzOwotICAgICAgICB9Ci0KLSAgICAgICAgZmluYWwgaW50IG5vZGVUeXBlID0gX25vZGVUeXBlOwotCi0gICAgICAgIGlmICghX2luY2x1ZGVTZWxmKSB7Ci0gICAgICAgICAgbm9kZUlEID0gX3BhcmVudDIobm9kZUlEKTsKLSAgICAgICAgICBub2RlID0gbWFrZU5vZGVIYW5kbGUobm9kZUlEKTsKLSAgICAgICAgfQotCi0gICAgICAgIF9zdGFydE5vZGUgPSBub2RlOwotCi0gICAgICAgIGlmIChub2RlVHlwZSA+PSBEVE0uTlRZUEVTKSB7Ci0gICAgICAgICAgd2hpbGUgKG5vZGVJRCAhPSBFTkQpIHsKLSAgICAgICAgICAgIGludCBlVHlwZSA9IF9leHB0eXBlMihub2RlSUQpOwotCi0gICAgICAgICAgICBpZiAoZVR5cGUgPT0gbm9kZVR5cGUpIHsKLSAgICAgICAgICAgICAgaWYgKG1fc2l6ZSA+PSBtX2FuY2VzdG9ycy5sZW5ndGgpCi0gICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBpbnRbXSBuZXdBbmNlc3RvcnMgPSBuZXcgaW50W21fc2l6ZSAqIDJdOwotICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkobV9hbmNlc3RvcnMsIDAsIG5ld0FuY2VzdG9ycywgMCwgbV9hbmNlc3RvcnMubGVuZ3RoKTsKLSAgICAgICAgICAgICAgICBtX2FuY2VzdG9ycyA9IG5ld0FuY2VzdG9yczsKLSAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICBtX2FuY2VzdG9yc1ttX3NpemUrK10gPSBtYWtlTm9kZUhhbmRsZShub2RlSUQpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgbm9kZUlEID0gX3BhcmVudDIobm9kZUlEKTsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgd2hpbGUgKG5vZGVJRCAhPSBFTkQpIHsKLSAgICAgICAgICAgIGludCBlVHlwZSA9IF9leHB0eXBlMihub2RlSUQpOwotCi0gICAgICAgICAgICBpZiAoKGVUeXBlIDwgRFRNLk5UWVBFUyAmJiBlVHlwZSA9PSBub2RlVHlwZSkKLSAgICAgICAgICAgICAgICB8fCAoZVR5cGUgPj0gRFRNLk5UWVBFUwotICAgICAgICAgICAgICAgICAgICAmJiBtX2V4dGVuZGVkVHlwZXNbZVR5cGVdLmdldE5vZGVUeXBlKCkgPT0gbm9kZVR5cGUpKSB7Ci0gICAgICAgICAgICAgIGlmIChtX3NpemUgPj0gbV9hbmNlc3RvcnMubGVuZ3RoKQotICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgaW50W10gbmV3QW5jZXN0b3JzID0gbmV3IGludFttX3NpemUgKiAyXTsKLSAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KG1fYW5jZXN0b3JzLCAwLCBuZXdBbmNlc3RvcnMsIDAsIG1fYW5jZXN0b3JzLmxlbmd0aCk7Ci0gICAgICAgICAgICAgICAgbV9hbmNlc3RvcnMgPSBuZXdBbmNlc3RvcnM7Ci0gICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgbV9hbmNlc3RvcnNbbV9zaXplKytdID0gbWFrZU5vZGVIYW5kbGUobm9kZUlEKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIG5vZGVJRCA9IF9wYXJlbnQyKG5vZGVJRCk7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIG1fYW5jZXN0b3JzUG9zID0gbV9zaXplIC0gMTsKLQotICAgICAgICBfY3VycmVudE5vZGUgPSAobV9hbmNlc3RvcnNQb3M+PTApCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBtX2FuY2VzdG9yc1ttX2FuY2VzdG9yc1Bvc10KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IERUTS5OVUxMOwotCi0gICAgICAgIHJldHVybiByZXNldFBvc2l0aW9uKCk7Ci0gICAgICB9Ci0KLSAgICAgIHJldHVybiB0aGlzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybiB0aGUgbm9kZSBhdCB0aGUgZ2l2ZW4gcG9zaXRpb24uCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXROb2RlQnlQb3NpdGlvbihpbnQgcG9zaXRpb24pCi0gICAgewotICAgICAgaWYgKHBvc2l0aW9uID4gMCAmJiBwb3NpdGlvbiA8PSBtX3NpemUpIHsKLSAgICAgICAgcmV0dXJuIG1fYW5jZXN0b3JzW3Bvc2l0aW9uLTFdOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgICByZXR1cm4gRFRNLk5VTEw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgcG9zaXRpb24gb2YgdGhlIGxhc3Qgbm9kZSB3aXRoaW4gdGhlIGl0ZXJhdGlvbiwgYXMKLSAgICAgKiBkZWZpbmVkIGJ5IFhQYXRoLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0TGFzdCgpIHsKLSAgICAgIHJldHVybiBtX3NpemU7Ci0gICAgfQotICB9ICAvLyBlbmQgb2YgVHlwZWRBbmNlc3Rvckl0ZXJhdG9yCi0KLSAgLyoqCi0gICAqIEl0ZXJhdG9yIHRoYXQgcmV0dXJucyB0aGUgZGVzY2VuZGFudHMgb2YgYSBnaXZlbiBub2RlLgotICAgKi8KLSAgcHVibGljIGNsYXNzIERlc2NlbmRhbnRJdGVyYXRvciBleHRlbmRzIEludGVybmFsQXhpc0l0ZXJhdG9yQmFzZQotICB7Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgc3RhcnQgdG8gRU5EIHNob3VsZCAnY2xvc2UnIHRoZSBpdGVyYXRvciwKLSAgICAgKiBpLmUuIHN1YnNlcXVlbnQgY2FsbCB0byBuZXh0KCkgc2hvdWxkIHJldHVybiBFTkQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbm9kZSBTZXRzIHRoZSByb290IG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIEEgRFRNQXhpc0l0ZXJhdG9yIHNldCB0byB0aGUgc3RhcnQgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIHNldFN0YXJ0Tm9kZShpbnQgbm9kZSkKLSAgICB7Ci0vLyVIWiU6IEFkZGVkIHJlZmVyZW5jZSB0byBEVE1EZWZhdWx0QmFzZS5ST09UTk9ERSBiYWNrIGluLCB0ZW1wb3JhcmlseQotICAgICAgaWYgKG5vZGUgPT0gRFRNRGVmYXVsdEJhc2UuUk9PVE5PREUpCi0gICAgICAgIG5vZGUgPSBnZXREb2N1bWVudCgpOwotICAgICAgaWYgKF9pc1Jlc3RhcnRhYmxlKQotICAgICAgewotICAgICAgICBub2RlID0gbWFrZU5vZGVJZGVudGl0eShub2RlKTsKLSAgICAgICAgX3N0YXJ0Tm9kZSA9IG5vZGU7Ci0KLSAgICAgICAgaWYgKF9pbmNsdWRlU2VsZikKLSAgICAgICAgICBub2RlLS07Ci0KLSAgICAgICAgX2N1cnJlbnROb2RlID0gbm9kZTsKLQotICAgICAgICByZXR1cm4gcmVzZXRQb3NpdGlvbigpOwotICAgICAgfQotCi0gICAgICByZXR1cm4gdGhpczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUZWxsIGlmIHRoaXMgbm9kZSBpZGVudGl0eSBpcyBhIGRlc2NlbmRhbnQuICBBc3N1bWVzIHRoYXQKLSAgICAgKiB0aGUgbm9kZSBpbmZvIGZvciB0aGUgZWxlbWVudCBoYXMgYWxyZWFkeSBiZWVuIG9idGFpbmVkLgotICAgICAqCi0gICAgICogVGhpcyBvbmUtc2lkZWQgdGVzdCB3b3JrcyBvbmx5IGlmIHRoZSBwYXJlbnQgaGFzIGJlZW4KLSAgICAgKiBwcmV2aW91c2x5IHRlc3RlZCBhbmQgaXMga25vd24gdG8gYmUgYSBkZXNjZW5kZW50LiBJdCBmYWlscyBpZgotICAgICAqIHRoZSBwYXJlbnQgaXMgdGhlIF9zdGFydE5vZGUncyBuZXh0IHNpYmxpbmcsIG9yIGluZGVlZCBhbnkgbm9kZQotICAgICAqIHRoYXQgZm9sbG93cyBfc3RhcnROb2RlIGluIGRvY3VtZW50IG9yZGVyLiAgVGhhdCBtYXkgc3VmZmljZQotICAgICAqIGZvciB0aGlzIGl0ZXJhdG9yLCBidXQgaXQncyBub3QgcmVhbGx5IGFuIGlzRGVzY2VuZGVudCgpIHRlc3QuCi0gICAgICogJVJFVklFVyUgcmVuYW1lPwotICAgICAqCi0gICAgICogQHBhcmFtIGlkZW50aXR5IFRoZSBpbmRleCBudW1iZXIgb2YgdGhlIG5vZGUgaW4gcXVlc3Rpb24uCi0gICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBpbmRleCBpcyBhIGRlc2NlbmRhbnQgb2YgX3N0YXJ0Tm9kZS4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgZmluYWwgYm9vbGVhbiBpc0Rlc2NlbmRhbnQoaW50IGlkZW50aXR5KQotICAgIHsKLSAgICAgIHJldHVybiAoX3BhcmVudDIoaWRlbnRpdHkpID49IF9zdGFydE5vZGUpIHx8IChfc3RhcnROb2RlID09IGlkZW50aXR5KTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIG5leHQgbm9kZSBpbiB0aGUgaXRlcmF0aW9uLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgbmV4dCBub2RlIGhhbmRsZSBpbiB0aGUgaXRlcmF0aW9uLCBvciBFTkQuCi0gICAgICovCi0gICAgcHVibGljIGludCBuZXh0KCkKLSAgICB7Ci0gICAgICBmaW5hbCBpbnQgc3RhcnROb2RlID0gX3N0YXJ0Tm9kZTsKLSAgICAgIGlmIChzdGFydE5vZGUgPT0gTlVMTCkgewotICAgICAgICByZXR1cm4gTlVMTDsKLSAgICAgIH0KLQotICAgICAgaWYgKF9pbmNsdWRlU2VsZiAmJiAoX2N1cnJlbnROb2RlICsgMSkgPT0gc3RhcnROb2RlKQotICAgICAgICAgIHJldHVybiByZXR1cm5Ob2RlKG1ha2VOb2RlSGFuZGxlKCsrX2N1cnJlbnROb2RlKSk7IC8vIHwgbV9kdG1JZGVudCk7Ci0KLSAgICAgIGludCBub2RlID0gX2N1cnJlbnROb2RlOwotICAgICAgaW50IHR5cGU7Ci0KLSAgICAgIC8vICVPUFQlIElmIHRoZSBzdGFydE5vZGUgaXMgdGhlIHJvb3Qgbm9kZSwgZG8gbm90IG5lZWQKLSAgICAgIC8vIHRvIGRvIHRoZSBpc0Rlc2NlbmRhbnQoKSBjaGVjay4KLSAgICAgIGlmIChzdGFydE5vZGUgPT0gUk9PVE5PREUpIHsKLSAgICAgICAgaW50IGVUeXBlOwotICAgICAgICBkbyB7Ci0gICAgICAgICAgbm9kZSsrOwotICAgICAgICAgIGVUeXBlID0gX2V4cHR5cGUyKG5vZGUpOwotCi0gICAgICAgICAgaWYgKE5VTEwgPT0gZVR5cGUpIHsKLSAgICAgICAgICAgIF9jdXJyZW50Tm9kZSA9IE5VTEw7Ci0gICAgICAgICAgICByZXR1cm4gRU5EOwotICAgICAgICAgIH0KLSAgICAgICAgfSB3aGlsZSAoZVR5cGUgPT0gVEVYVF9OT0RFCi0gICAgICAgICAgICAgICAgIHx8ICh0eXBlID0gbV9leHRlbmRlZFR5cGVzW2VUeXBlXS5nZXROb2RlVHlwZSgpKSA9PSBBVFRSSUJVVEVfTk9ERQotICAgICAgICAgICAgICAgICB8fCB0eXBlID09IE5BTUVTUEFDRV9OT0RFKTsKLSAgICAgIH0KLSAgICAgIGVsc2UgewotICAgICAgICBkbyB7Ci0gICAgICAgICAgbm9kZSsrOwotICAgICAgICAgIHR5cGUgPSBfdHlwZTIobm9kZSk7Ci0KLSAgICAgICAgICBpZiAoTlVMTCA9PSB0eXBlIHx8IWlzRGVzY2VuZGFudChub2RlKSkgewotICAgICAgICAgICAgX2N1cnJlbnROb2RlID0gTlVMTDsKLSAgICAgICAgICAgIHJldHVybiBFTkQ7Ci0gICAgICAgICAgfQotICAgICAgICB9IHdoaWxlKEFUVFJJQlVURV9OT0RFID09IHR5cGUgfHwgVEVYVF9OT0RFID09IHR5cGUKLSAgICAgICAgICAgICAgICAgfHwgTkFNRVNQQUNFX05PREUgPT0gdHlwZSk7Ci0gICAgICB9Ci0KLSAgICAgIF9jdXJyZW50Tm9kZSA9IG5vZGU7Ci0gICAgICByZXR1cm4gcmV0dXJuTm9kZShtYWtlTm9kZUhhbmRsZShub2RlKSk7ICAvLyBtYWtlIGhhbmRsZS4KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXNldC4KLSAgICAgKgotICAgICAqLwotICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIHJlc2V0KCkKLSAgewotCi0gICAgZmluYWwgYm9vbGVhbiB0ZW1wID0gX2lzUmVzdGFydGFibGU7Ci0KLSAgICBfaXNSZXN0YXJ0YWJsZSA9IHRydWU7Ci0KLSAgICBzZXRTdGFydE5vZGUobWFrZU5vZGVIYW5kbGUoX3N0YXJ0Tm9kZSkpOwotCi0gICAgX2lzUmVzdGFydGFibGUgPSB0ZW1wOwotCi0gICAgcmV0dXJuIHRoaXM7Ci0gIH0KLQotICB9ICAvLyBlbmQgb2YgRGVzY2VuZGFudEl0ZXJhdG9yCi0KLSAgLyoqCi0gICAqIFR5cGVkIGl0ZXJhdG9yIHRoYXQgcmV0dXJucyB0aGUgZGVzY2VuZGFudHMgb2YgYSBnaXZlbiBub2RlLgotICAgKi8KLSAgcHVibGljIGZpbmFsIGNsYXNzIFR5cGVkRGVzY2VuZGFudEl0ZXJhdG9yIGV4dGVuZHMgRGVzY2VuZGFudEl0ZXJhdG9yCi0gIHsKLQotICAgIC8qKiBUaGUgZXh0ZW5kZWQgdHlwZSBJRCB0aGF0IHdhcyByZXF1ZXN0ZWQuICovCi0gICAgcHJpdmF0ZSBmaW5hbCBpbnQgX25vZGVUeXBlOwotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0b3IgVHlwZWREZXNjZW5kYW50SXRlcmF0b3IKLSAgICAgKgotICAgICAqCi0gICAgICogQHBhcmFtIG5vZGVUeXBlIEV4dGVuZGVkIHR5cGUgSUQgYmVpbmcgcmVxdWVzdGVkLgotICAgICAqLwotICAgIHB1YmxpYyBUeXBlZERlc2NlbmRhbnRJdGVyYXRvcihpbnQgbm9kZVR5cGUpCi0gICAgewotICAgICAgX25vZGVUeXBlID0gbm9kZVR5cGU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBuZXh0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIG5leHQgbm9kZSBoYW5kbGUgaW4gdGhlIGl0ZXJhdGlvbiwgb3IgRU5ELgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgbmV4dCgpCi0gICAgewotICAgICAgZmluYWwgaW50IHN0YXJ0Tm9kZSA9IF9zdGFydE5vZGU7Ci0gICAgICBpZiAoX3N0YXJ0Tm9kZSA9PSBOVUxMKSB7Ci0gICAgICAgIHJldHVybiBOVUxMOwotICAgICAgfQotCi0gICAgICBpbnQgbm9kZSA9IF9jdXJyZW50Tm9kZTsKLQotICAgICAgaW50IGV4cFR5cGU7Ci0gICAgICBmaW5hbCBpbnQgbm9kZVR5cGUgPSBfbm9kZVR5cGU7Ci0KLSAgICAgIGlmIChub2RlVHlwZSAhPSBEVE0uRUxFTUVOVF9OT0RFKQotICAgICAgewotICAgICAgICBkbwotICAgICAgICB7Ci0gICAgICAgICAgbm9kZSsrOwotICAgICAgICAgIGV4cFR5cGUgPSBfZXhwdHlwZTIobm9kZSk7Ci0KLSAgICAgICAgICBpZiAoTlVMTCA9PSBleHBUeXBlIHx8IF9wYXJlbnQyKG5vZGUpIDwgc3RhcnROb2RlICYmIHN0YXJ0Tm9kZSAhPSBub2RlKSB7Ci0gICAgICAgICAgICBfY3VycmVudE5vZGUgPSBOVUxMOwotICAgICAgICAgICAgcmV0dXJuIEVORDsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgd2hpbGUgKGV4cFR5cGUgIT0gbm9kZVR5cGUpOwotICAgICAgfQotICAgICAgLy8gJU9QVCUgSWYgdGhlIHN0YXJ0IG5vZGUgaXMgcm9vdCAoZS5nLiBpbiB0aGUgY2FzZSBvZiAvL25vZGUpLAotICAgICAgLy8gd2UgY2FuIHNhdmUgdGhlIGlzRGVzY2VuZGFudCgpIGNoZWNrLCBiZWNhdXNlIGFsbCBub2RlcyBhcmUKLSAgICAgIC8vIGRlc2NlbmRhbnRzIG9mIHJvb3QuCi0gICAgICBlbHNlIGlmIChzdGFydE5vZGUgPT0gRFRNRGVmYXVsdEJhc2UuUk9PVE5PREUpCi0gICAgICB7Ci0gICAgICAgIGRvCi0gICAgICAgIHsKLSAgICAgICAgICBub2RlKys7Ci0gICAgICAgICAgZXhwVHlwZSA9IF9leHB0eXBlMihub2RlKTsKLQotICAgICAgICAgIGlmIChOVUxMID09IGV4cFR5cGUpIHsKLSAgICAgICAgICAgIF9jdXJyZW50Tm9kZSA9IE5VTEw7Ci0gICAgICAgICAgICByZXR1cm4gRU5EOwotICAgICAgICAgIH0KLSAgICAgICAgfSB3aGlsZSAoZXhwVHlwZSA8IERUTS5OVFlQRVMKLSAgICAgICAgICAgICAgICB8fCBtX2V4dGVuZGVkVHlwZXNbZXhwVHlwZV0uZ2V0Tm9kZVR5cGUoKSAhPSBEVE0uRUxFTUVOVF9OT0RFKTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgZG8KLSAgICAgICAgewotICAgICAgICAgIG5vZGUrKzsKLSAgICAgICAgICBleHBUeXBlID0gX2V4cHR5cGUyKG5vZGUpOwotCi0gICAgICAgICAgaWYgKE5VTEwgPT0gZXhwVHlwZSB8fCBfcGFyZW50Mihub2RlKSA8IHN0YXJ0Tm9kZSAmJiBzdGFydE5vZGUgIT0gbm9kZSkgewotICAgICAgICAgICAgX2N1cnJlbnROb2RlID0gTlVMTDsKLSAgICAgICAgICAgIHJldHVybiBFTkQ7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHdoaWxlIChleHBUeXBlIDwgRFRNLk5UWVBFUwotICAgICAgICAgICAgICAgfHwgbV9leHRlbmRlZFR5cGVzW2V4cFR5cGVdLmdldE5vZGVUeXBlKCkgIT0gRFRNLkVMRU1FTlRfTk9ERSk7Ci0gICAgICB9Ci0KLSAgICAgIF9jdXJyZW50Tm9kZSA9IG5vZGU7Ci0gICAgICByZXR1cm4gcmV0dXJuTm9kZShtYWtlTm9kZUhhbmRsZShub2RlKSk7Ci0gICAgfQotICB9ICAvLyBlbmQgb2YgVHlwZWREZXNjZW5kYW50SXRlcmF0b3IKLQotICAvKioKLSAgICogSXRlcmF0b3IgdGhhdCByZXR1cm5zIGEgZ2l2ZW4gbm9kZSBvbmx5IGlmIGl0IGlzIG9mIGEgZ2l2ZW4gdHlwZS4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBjbGFzcyBUeXBlZFNpbmdsZXRvbkl0ZXJhdG9yIGV4dGVuZHMgU2luZ2xldG9uSXRlcmF0b3IKLSAgewotCi0gICAgLyoqIFRoZSBleHRlbmRlZCB0eXBlIElEIHRoYXQgd2FzIHJlcXVlc3RlZC4gKi8KLSAgICBwcml2YXRlIGZpbmFsIGludCBfbm9kZVR5cGU7Ci0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RvciBUeXBlZFNpbmdsZXRvbkl0ZXJhdG9yCi0gICAgICoKLSAgICAgKgotICAgICAqIEBwYXJhbSBub2RlVHlwZSBUaGUgZXh0ZW5kZWQgdHlwZSBJRCBiZWluZyByZXF1ZXN0ZWQuCi0gICAgICovCi0gICAgcHVibGljIFR5cGVkU2luZ2xldG9uSXRlcmF0b3IoaW50IG5vZGVUeXBlKQotICAgIHsKLSAgICAgIF9ub2RlVHlwZSA9IG5vZGVUeXBlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgbmV4dCBub2RlIGluIHRoZSBpdGVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBuZXh0IG5vZGUgaGFuZGxlIGluIHRoZSBpdGVyYXRpb24sIG9yIEVORC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IG5leHQoKQotICAgIHsKLQotICAgICAgZmluYWwgaW50IHJlc3VsdCA9IF9jdXJyZW50Tm9kZTsKLSAgICAgIGlmIChyZXN1bHQgPT0gRU5EKQotICAgICAgICByZXR1cm4gRFRNLk5VTEw7Ci0KLSAgICAgIF9jdXJyZW50Tm9kZSA9IEVORDsKLQotICAgICAgaWYgKF9ub2RlVHlwZSA+PSBEVE0uTlRZUEVTKSB7Ci0gICAgICAgIGlmIChfZXhwdHlwZTIobWFrZU5vZGVJZGVudGl0eShyZXN1bHQpKSA9PSBfbm9kZVR5cGUpIHsKLSAgICAgICAgICByZXR1cm4gcmV0dXJuTm9kZShyZXN1bHQpOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgICBlbHNlIHsKLSAgICAgICAgaWYgKF90eXBlMihtYWtlTm9kZUlkZW50aXR5KHJlc3VsdCkpID09IF9ub2RlVHlwZSkgewotICAgICAgICAgIHJldHVybiByZXR1cm5Ob2RlKHJlc3VsdCk7Ci0gICAgICAgIH0KLSAgICAgIH0KLQotICAgICAgcmV0dXJuIE5VTEw7Ci0gICAgfQotICB9ICAvLyBlbmQgb2YgVHlwZWRTaW5nbGV0b25JdGVyYXRvcgotCi0gIC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0gICAqICAgICAgICAgICAgICAgIEVuZCBvZiBuZXN0ZWQgaXRlcmF0b3JzCi0gICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwotCi0KLSAgLy8gJU9QVCUgQXJyYXkgcmVmZXJlbmNlcyB3aGljaCBhcmUgdXNlZCB0byBjYWNoZSB0aGUgbWFwMCBhcnJheXMgaW4KLSAgLy8gU3ViYWxsb2NhdGVkSW50VmVjdG9ycy4gVXNpbmcgdGhlIGNhY2hlZCBhcnJheXMgcmVkdWNlcyB0aGUgbGV2ZWwKLSAgLy8gb2YgaW5kaXJlY3Rpb24gYW5kIHJlc3VsdHMgaW4gYmV0dGVyIHBlcmZvcm1hbmNlIHRoYW4ganVzdCBjYWxsaW5nCi0gIC8vIFN1YmFsbG9jYXRlZEludFZlY3Rvci5lbGVtZW50QXQoKS4KLSAgcHJpdmF0ZSBpbnRbXSBtX2V4cHR5cGVfbWFwMDsKLSAgcHJpdmF0ZSBpbnRbXSBtX25leHRzaWJfbWFwMDsKLSAgcHJpdmF0ZSBpbnRbXSBtX2ZpcnN0Y2hfbWFwMDsKLSAgcHJpdmF0ZSBpbnRbXSBtX3BhcmVudF9tYXAwOwotCi0gIC8vIERvdWJsZSBhcnJheSByZWZlcmVuY2VzIHRvIHRoZSBtYXAgYXJyYXlzIGluIFN1YmFsbG9jYXRlZEludFZlY3RvcnMuCi0gIHByaXZhdGUgaW50W11bXSBtX2V4cHR5cGVfbWFwOwotICBwcml2YXRlIGludFtdW10gbV9uZXh0c2liX21hcDsKLSAgcHJpdmF0ZSBpbnRbXVtdIG1fZmlyc3RjaF9tYXA7Ci0gIHByaXZhdGUgaW50W11bXSBtX3BhcmVudF9tYXA7Ci0KLSAgLy8gJU9QVCUgQ2FjaGUgdGhlIGFycmF5IG9mIGV4dGVuZGVkIHR5cGVzIGluIHRoaXMgY2xhc3MKLSAgcHJvdGVjdGVkIEV4dGVuZGVkVHlwZVtdIG1fZXh0ZW5kZWRUeXBlczsKLQotICAvLyBBIFZlY3RvciB3aGljaCBpcyB1c2VkIHRvIHN0b3JlIHRoZSB2YWx1ZXMgb2YgYXR0cmlidXRlLCBuYW1lc3BhY2UsCi0gIC8vIGNvbW1lbnQgYW5kIFBJIG5vZGVzLgotICAvLwotICAvLyAlT1BUJSBUaGVzZSB2YWx1ZXMgYXJlIHVubGlrZWx5IHRvIGJlIGVxdWFsLiBTdG9yaW5nCi0gIC8vIHRoZW0gaW4gYSBwbGFpbiBWZWN0b3IgaXMgbW9yZSBlZmZpY2llbnQgdGhhbiBzdG9yaW5nIGluIHRoZQotICAvLyBEVE1TdHJpbmdQb29sIGJlY2F1c2Ugd2UgY2FuIHNhdmUgdGhlIGNvc3QgZm9yIGhhc2ggY2FsY3VsYXRpb24uCi0gIC8vCi0gIC8vICVSRVZJU0lUJSBEbyB3ZSBuZWVkIGEgY3VzdG9tIGNsYXNzIChlLmcuIFN0cmluZ1ZlY3RvcikgaGVyZT8KLSAgcHJvdGVjdGVkIFZlY3RvciBtX3ZhbHVlczsKLQotICAvLyBUaGUgY3VycmVudCBpbmRleCBpbnRvIHRoZSBtX3ZhbHVlcyBWZWN0b3IuCi0gIHByaXZhdGUgaW50IG1fdmFsdWVJbmRleCA9IDA7Ci0KLSAgLy8gVGhlIG1heGltdW0gdmFsdWUgb2YgdGhlIGN1cnJlbnQgbm9kZSBpbmRleC4KLSAgcHJpdmF0ZSBpbnQgbV9tYXhOb2RlSW5kZXg7Ci0KLSAgLy8gQ2FjaGUgdGhlIHNoaWZ0IGFuZCBtYXNrIHZhbHVlcyBmb3IgdGhlIFN1YmFsbG9jYXRlZEludFZlY3RvcnMuCi0gIHByb3RlY3RlZCBpbnQgbV9TSElGVDsKLSAgcHJvdGVjdGVkIGludCBtX01BU0s7Ci0gIHByb3RlY3RlZCBpbnQgbV9ibG9ja3NpemU7Ci0KLSAgLyoqICVPUFQlIElmIHRoZSBvZmZzZXQgYW5kIGxlbmd0aCBvZiBhIFRleHQgbm9kZSBhcmUgd2l0aGluIGNlcnRhaW4gbGltaXRzLAotICAgKiB3ZSBzdG9yZSBhIGJpdHdpc2UgZW5jb2RlZCB2YWx1ZSBpbnRvIGFuIGludCwgdXNpbmcgMTAgYml0cyAobWF4LiAxMDI0KQotICAgKiBmb3IgbGVuZ3RoIGFuZCAyMSBiaXRzIGZvciBvZmZzZXQuIFdlIGNhbiBzYXZlIHR3byBTdWJhbGxvY2F0ZWRJbnRWZWN0b3IKLSAgICogY2FsbHMgZm9yIGVhY2ggZ2V0U3RyaW5nVmFsdWVYKCkgYW5kIGRpc3BhdGNoQ2hhcmFjdGVyRXZlbnRzKCkgY2FsbCBieQotICAgKiBkb2luZyB0aGlzLgotICAgKi8KLSAgLy8gVGhlIG51bWJlciBvZiBiaXRzIGZvciB0aGUgbGVuZ3RoIG9mIGEgVGV4dCBub2RlLgotICBwcm90ZWN0ZWQgZmluYWwgc3RhdGljIGludCBURVhUX0xFTkdUSF9CSVRTID0gMTA7Ci0KLSAgLy8gVGhlIG51bWJlciBvZiBiaXRzIGZvciB0aGUgb2Zmc2V0IG9mIGEgVGV4dCBub2RlLgotICBwcm90ZWN0ZWQgZmluYWwgc3RhdGljIGludCBURVhUX09GRlNFVF9CSVRTID0gMjE7Ci0KLSAgLy8gVGhlIG1heGltdW0gbGVuZ3RoIHZhbHVlCi0gIHByb3RlY3RlZCBmaW5hbCBzdGF0aWMgaW50IFRFWFRfTEVOR1RIX01BWCA9ICgxPDxURVhUX0xFTkdUSF9CSVRTKSAtIDE7Ci0KLSAgLy8gVGhlIG1heGltdW0gb2Zmc2V0IHZhbHVlCi0gIHByb3RlY3RlZCBmaW5hbCBzdGF0aWMgaW50IFRFWFRfT0ZGU0VUX01BWCA9ICgxPDxURVhUX09GRlNFVF9CSVRTKSAtIDE7Ci0KLSAgLy8gVHJ1ZSBpZiB3ZSB3YW50IHRvIGJ1aWxkIHRoZSBJRCBpbmRleCB0YWJsZS4KLSAgcHJvdGVjdGVkIGJvb2xlYW4gbV9idWlsZElkSW5kZXggPSB0cnVlOwotCi0gIC8vIENvbnN0YW50IGZvciBlbXB0eSBTdHJpbmcKLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEVNUFRZX1NUUiA9ICIiOwotCi0gIC8vIENvbnN0YW50IGZvciBlbXB0eSBYTUxTdHJpbmcKLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgWE1MU3RyaW5nIEVNUFRZX1hNTF9TVFIgPSBuZXcgWE1MU3RyaW5nRGVmYXVsdCgiIik7Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhIFNBWDJEVE0yIG9iamVjdCB1c2luZyB0aGUgZGVmYXVsdCBibG9jayBzaXplLgotICAgKi8KLSAgcHVibGljIFNBWDJEVE0yKERUTU1hbmFnZXIgbWdyLCBTb3VyY2Ugc291cmNlLCBpbnQgZHRtSWRlbnRpdHksCi0gICAgICAgICAgICAgICAgIERUTVdTRmlsdGVyIHdoaXRlU3BhY2VGaWx0ZXIsCi0gICAgICAgICAgICAgICAgIFhNTFN0cmluZ0ZhY3RvcnkgeHN0cmluZ2ZhY3RvcnksCi0gICAgICAgICAgICAgICAgIGJvb2xlYW4gZG9JbmRleGluZykKLSAgewotCi0gICAgdGhpcyhtZ3IsIHNvdXJjZSwgZHRtSWRlbnRpdHksIHdoaXRlU3BhY2VGaWx0ZXIsCi0gICAgICAgICAgeHN0cmluZ2ZhY3RvcnksIGRvSW5kZXhpbmcsIERFRkFVTFRfQkxPQ0tTSVpFLCB0cnVlLCB0cnVlLCBmYWxzZSk7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgU0FYMkRUTTIgb2JqZWN0IHVzaW5nIHRoZSBnaXZlbiBibG9jayBzaXplLgotICAgKi8KLSAgcHVibGljIFNBWDJEVE0yKERUTU1hbmFnZXIgbWdyLCBTb3VyY2Ugc291cmNlLCBpbnQgZHRtSWRlbnRpdHksCi0gICAgICAgICAgICAgICAgIERUTVdTRmlsdGVyIHdoaXRlU3BhY2VGaWx0ZXIsCi0gICAgICAgICAgICAgICAgIFhNTFN0cmluZ0ZhY3RvcnkgeHN0cmluZ2ZhY3RvcnksCi0gICAgICAgICAgICAgICAgIGJvb2xlYW4gZG9JbmRleGluZywKLSAgICAgICAgICAgICAgICAgaW50IGJsb2Nrc2l6ZSwKLSAgICAgICAgICAgICAgICAgYm9vbGVhbiB1c2VQcmV2c2liLAotICAgICAgICAgICAgICAgICBib29sZWFuIGJ1aWxkSWRJbmRleCwKLSAgICAgICAgICAgICAgICAgYm9vbGVhbiBuZXdOYW1lVGFibGUpCi0gIHsKLQotICAgIHN1cGVyKG1nciwgc291cmNlLCBkdG1JZGVudGl0eSwgd2hpdGVTcGFjZUZpbHRlciwKLSAgICAgICAgICB4c3RyaW5nZmFjdG9yeSwgZG9JbmRleGluZywgYmxvY2tzaXplLCB1c2VQcmV2c2liLCBuZXdOYW1lVGFibGUpOwotCi0gICAgLy8gSW5pdGlhbGl6ZSB0aGUgdmFsdWVzIG9mIG1fU0hJRlQgYW5kIG1fTUFTSy4KLSAgICBpbnQgc2hpZnQ7Ci0gICAgZm9yKHNoaWZ0PTA7IChibG9ja3NpemU+Pj49MSkgIT0gMDsgKytzaGlmdCk7Ci0KLSAgICBtX2Jsb2Nrc2l6ZSA9IDE8PHNoaWZ0OwotICAgIG1fU0hJRlQgPSBzaGlmdDsKLSAgICBtX01BU0sgPSBtX2Jsb2Nrc2l6ZSAtIDE7Ci0KLSAgICBtX2J1aWxkSWRJbmRleCA9IGJ1aWxkSWRJbmRleDsKLQotICAgIC8vIFNvbWUgZG9jdW1lbnRzIGRvIG5vdCBoYXZlIGF0dHJpYnV0ZSBub2Rlcy4gVGhhdCBpcyB3aHkKLSAgICAvLyB3ZSBzZXQgdGhlIGluaXRpYWwgc2l6ZSBvZiB0aGlzIFZlY3RvciB0byBiZSBzbWFsbCBhbmQgc2V0Ci0gICAgLy8gdGhlIGluY3JlbWVudCB0byBhIGJpZ2dlciBudW1iZXIuCi0gICAgbV92YWx1ZXMgPSBuZXcgVmVjdG9yKDMyLCA1MTIpOwotCi0gICAgbV9tYXhOb2RlSW5kZXggPSAxIDw8IERUTU1hbmFnZXIuSURFTlRfRFRNX05PREVfQklUUzsKLQotICAgIC8vIFNldCB0aGUgbWFwMCB2YWx1ZXMgaW4gdGhlIGNvbnN0cnVjdG9yLgotICAgIG1fZXhwdHlwZV9tYXAwID0gbV9leHB0eXBlLmdldE1hcDAoKTsKLSAgICBtX25leHRzaWJfbWFwMCA9IG1fbmV4dHNpYi5nZXRNYXAwKCk7Ci0gICAgbV9maXJzdGNoX21hcDAgPSBtX2ZpcnN0Y2guZ2V0TWFwMCgpOwotICAgIG1fcGFyZW50X21hcDAgID0gbV9wYXJlbnQuZ2V0TWFwMCgpOwotICB9Ci0KLSAgLyoqCi0gICAqIE92ZXJyaWRlIERUTURlZmF1bHRCYXNlLl9leHB0eXBlKCkgYnkgZHJvcHBpbmcgdGhlIGluY3JlbWVudGFsIGNvZGUuCi0gICAqCi0gICAqIDxwPlRoaXMgb25lIGlzIGxlc3MgZWZmaWNpZW50IHRoYW4gX2V4cHR5cGUyLiBJdCBpcyBvbmx5IHVzZWQgZHVyaW5nCi0gICAqIERUTSBidWlsZGluZy4gX2V4cHR5cGUyIGlzIHVzZWQgYWZ0ZXIgdGhlIGRvY3VtZW50IGlzIGZ1bGx5IGJ1aWx0LgotICAgKi8KLSAgcHVibGljIGZpbmFsIGludCBfZXhwdHlwZShpbnQgaWRlbnRpdHkpCi0gIHsKLSAgICByZXR1cm4gbV9leHB0eXBlLmVsZW1lbnRBdChpZGVudGl0eSk7Ci0gIH0KLQotICAvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0gICAqICAgICAgICAgICAgIERUTSBiYXNlIGFjY2Vzc29yIGludGVyZmFjZXMKLSAgICoKLSAgICogJU9QVCUgVGhlIGNvZGUgaW4gdGhlIGZvbGxvd2luZyBpbnRlcmZhY2VzIChlLmcuIF9leHB0eXBlMiwgZXRjLikgYXJlCi0gICAqIHZlcnkgaW1wb3J0YW50IHRvIHRoZSBEVE0gcGVyZm9ybWFuY2UuIFRvIGhhdmUgdGhlIGJlc3QgcGVyZm9ybWFjZSwKLSAgICogdGhlc2Ugc2V2ZXJhbCBpbnRlcmZhY2VzIGhhdmUgZGlyZWN0IGFjY2VzcyB0byB0aGUgaW50ZXJuYWwgYXJyYXlzIG9mCi0gICAqIHRoZSBTdWJhbGxvY2F0ZWRJbnRWZWN0b3JzLiBUaGUgZmluYWwgbW9kaWZpZXIgYWxzbyBoYXMgYSBub3RpY2VhYmxlCi0gICAqIGltcGFjdCBvbiBwZXJmb3JtYW5jZS4KLSAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwotCi0gIC8qKgotICAgKiBUaGUgb3B0aW1pemVkIHZlcnNpb24gb2YgRFRNRGVmYXVsdEJhc2UuX2V4cHR5cGUoKS4KLSAgICoKLSAgICogQHBhcmFtIGlkZW50aXR5IEEgbm9kZSBpZGVudGl0eSwgd2hpY2ggPGVtPm11c3Qgbm90PC9lbT4gYmUgZXF1YWwgdG8KLSAgICogICAgICAgIDxjb2RlPkRUTS5OVUxMPC9jb2RlPgotICAgKi8KLSAgcHVibGljIGZpbmFsIGludCBfZXhwdHlwZTIoaW50IGlkZW50aXR5KQotICB7Ci0gICAgLy9yZXR1cm4gbV9leHB0eXBlLmVsZW1lbnRBdChpZGVudGl0eSk7Ci0KLSAgICBpZiAoaWRlbnRpdHkgPCBtX2Jsb2Nrc2l6ZSkKLSAgICAgIHJldHVybiBtX2V4cHR5cGVfbWFwMFtpZGVudGl0eV07Ci0gICAgZWxzZQotICAgICAgcmV0dXJuIG1fZXhwdHlwZV9tYXBbaWRlbnRpdHk+Pj5tX1NISUZUXVtpZGVudGl0eSZtX01BU0tdOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoZSBvcHRpbWl6ZWQgdmVyc2lvbiBvZiBEVE1EZWZhdWx0QmFzZS5fbmV4dHNpYigpLgotICAgKgotICAgKiBAcGFyYW0gaWRlbnRpdHkgQSBub2RlIGlkZW50aXR5LCB3aGljaCA8ZW0+bXVzdCBub3Q8L2VtPiBiZSBlcXVhbCB0bwotICAgKiAgICAgICAgPGNvZGU+RFRNLk5VTEw8L2NvZGU+Ci0gICAqLwotICBwdWJsaWMgZmluYWwgaW50IF9uZXh0c2liMihpbnQgaWRlbnRpdHkpCi0gIHsKLSAgICAvL3JldHVybiBtX25leHRzaWIuZWxlbWVudEF0KGlkZW50aXR5KTsKLQotICAgIGlmIChpZGVudGl0eSA8IG1fYmxvY2tzaXplKQotICAgICAgcmV0dXJuIG1fbmV4dHNpYl9tYXAwW2lkZW50aXR5XTsKLSAgICBlbHNlCi0gICAgICByZXR1cm4gbV9uZXh0c2liX21hcFtpZGVudGl0eT4+Pm1fU0hJRlRdW2lkZW50aXR5Jm1fTUFTS107Ci0gIH0KLQotICAvKioKLSAgICogVGhlIG9wdGltaXplZCB2ZXJzaW9uIG9mIERUTURlZmF1bHRCYXNlLl9maXJzdGNoKCkuCi0gICAqCi0gICAqIEBwYXJhbSBpZGVudGl0eSBBIG5vZGUgaWRlbnRpdHksIHdoaWNoIDxlbT5tdXN0IG5vdDwvZW0+IGJlIGVxdWFsIHRvCi0gICAqICAgICAgICA8Y29kZT5EVE0uTlVMTDwvY29kZT4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBpbnQgX2ZpcnN0Y2gyKGludCBpZGVudGl0eSkKLSAgewotICAgIC8vcmV0dXJuIG1fZmlyc3RjaC5lbGVtZW50QXQoaWRlbnRpdHkpOwotCi0gICAgaWYgKGlkZW50aXR5IDwgbV9ibG9ja3NpemUpCi0gICAgICByZXR1cm4gbV9maXJzdGNoX21hcDBbaWRlbnRpdHldOwotICAgIGVsc2UKLSAgICAgIHJldHVybiBtX2ZpcnN0Y2hfbWFwW2lkZW50aXR5Pj4+bV9TSElGVF1baWRlbnRpdHkmbV9NQVNLXTsKLSAgfQotCi0gIC8qKgotICAgKiBUaGUgb3B0aW1pemVkIHZlcnNpb24gb2YgRFRNRGVmYXVsdEJhc2UuX3BhcmVudCgpLgotICAgKgotICAgKiBAcGFyYW0gaWRlbnRpdHkgQSBub2RlIGlkZW50aXR5LCB3aGljaCA8ZW0+bXVzdCBub3Q8L2VtPiBiZSBlcXVhbCB0bwotICAgKiAgICAgICAgPGNvZGU+RFRNLk5VTEw8L2NvZGU+Ci0gICAqLwotICBwdWJsaWMgZmluYWwgaW50IF9wYXJlbnQyKGludCBpZGVudGl0eSkKLSAgewotICAgIC8vcmV0dXJuIG1fcGFyZW50LmVsZW1lbnRBdChpZGVudGl0eSk7Ci0KLSAgICBpZiAoaWRlbnRpdHkgPCBtX2Jsb2Nrc2l6ZSkKLSAgICAgIHJldHVybiBtX3BhcmVudF9tYXAwW2lkZW50aXR5XTsKLSAgICBlbHNlCi0gICAgICByZXR1cm4gbV9wYXJlbnRfbWFwW2lkZW50aXR5Pj4+bV9TSElGVF1baWRlbnRpdHkmbV9NQVNLXTsKLSAgfQotCi0gIC8qKgotICAgKiBUaGUgb3B0aW1pemVkIHZlcnNpb24gb2YgRFRNRGVmYXVsdEJhc2UuX3R5cGUoKS4KLSAgICoKLSAgICogQHBhcmFtIGlkZW50aXR5IEEgbm9kZSBpZGVudGl0eSwgd2hpY2ggPGVtPm11c3Qgbm90PC9lbT4gYmUgZXF1YWwgdG8KLSAgICogICAgICAgIDxjb2RlPkRUTS5OVUxMPC9jb2RlPgotICAgKi8KLSAgcHVibGljIGZpbmFsIGludCBfdHlwZTIoaW50IGlkZW50aXR5KQotICB7Ci0gICAgLy9pbnQgZVR5cGUgPSBfZXhwdHlwZTIoaWRlbnRpdHkpOwotICAgIGludCBlVHlwZTsKLSAgICBpZiAoaWRlbnRpdHkgPCBtX2Jsb2Nrc2l6ZSkKLSAgICAgIGVUeXBlID0gbV9leHB0eXBlX21hcDBbaWRlbnRpdHldOwotICAgIGVsc2UKLSAgICAgIGVUeXBlID0gbV9leHB0eXBlX21hcFtpZGVudGl0eT4+Pm1fU0hJRlRdW2lkZW50aXR5Jm1fTUFTS107Ci0KLSAgICBpZiAoTlVMTCAhPSBlVHlwZSkKLSAgICAgIHJldHVybiBtX2V4dGVuZGVkVHlwZXNbZVR5cGVdLmdldE5vZGVUeXBlKCk7Ci0gICAgZWxzZQotICAgICAgcmV0dXJuIE5VTEw7Ci0gIH0KLQotICAvKioKLSAgICogVGhlIG9wdGltaXplZCB2ZXJzaW9uIG9mIERUTURlZmF1bHRCYXNlLmdldEV4cGFuZGVkVHlwZUlEKGludCkuCi0gICAqCi0gICAqIDxwPlRoaXMgb25lIGlzIG9ubHkgdXNlZCBieSBET01BZGFwdGVyLmdldEV4cGFuZGVkVHlwZUlEKGludCksIHdoaWNoCi0gICAqIGlzIG1vc3RseSBjYWxsZWQgZnJvbSB0aGUgY29tcGlsZWQgdHJhbnNsZXRzLgotICAgKi8KLSAgcHVibGljIGZpbmFsIGludCBnZXRFeHBhbmRlZFR5cGVJRDIoaW50IG5vZGVIYW5kbGUpCi0gIHsKLSAgICBpbnQgbm9kZUlEID0gbWFrZU5vZGVJZGVudGl0eShub2RlSGFuZGxlKTsKLQotICAgIC8vcmV0dXJuIChub2RlSUQgIT0gTlVMTCkgPyBfZXhwdHlwZTIobm9kZUlEKSA6IE5VTEw7Ci0KLSAgICBpZiAobm9kZUlEICE9IE5VTEwpIHsKLSAgICAgIGlmIChub2RlSUQgPCBtX2Jsb2Nrc2l6ZSkKLSAgICAgICAgcmV0dXJuIG1fZXhwdHlwZV9tYXAwW25vZGVJRF07Ci0gICAgICBlbHNlCi0gICAgICAgIHJldHVybiBtX2V4cHR5cGVfbWFwW25vZGVJRD4+Pm1fU0hJRlRdW25vZGVJRCZtX01BU0tdOwotICAgIH0KLSAgICBlbHNlCi0gICAgICByZXR1cm4gTlVMTDsKLSAgfQotCi0gIC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0gICAqICAgICAgICAgICAgICAgICBFTkQgb2YgRFRNIGJhc2UgYWNjZXNzb3IgaW50ZXJmYWNlcwotICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIG5vZGUgdHlwZSBmcm9tIHRoZSBleHBhbmRlZCB0eXBlCi0gICAqLwotICBwdWJsaWMgZmluYWwgaW50IF9leHB0eXBlMlR5cGUoaW50IGV4cHR5cGUpCi0gIHsKLSAgICBpZiAoTlVMTCAhPSBleHB0eXBlKQotICAgICAgcmV0dXJuIG1fZXh0ZW5kZWRUeXBlc1tleHB0eXBlXS5nZXROb2RlVHlwZSgpOwotICAgIGVsc2UKLSAgICAgIHJldHVybiBOVUxMOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBhIHByZWZpeCBlaXRoZXIgZnJvbSB0aGUgdXJpIG1hcHBpbmcsIG9yIGp1c3QgbWFrZQotICAgKiBvbmUgdXAhCi0gICAqCi0gICAqIEBwYXJhbSB1cmkgVGhlIG5hbWVzcGFjZSBVUkksIHdoaWNoIG1heSBiZSBudWxsLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBwcmVmaXggaWYgdGhlcmUgaXMgb25lLCBvciBudWxsLgotICAgKi8KLSAgcHVibGljIGludCBnZXRJZEZvck5hbWVzcGFjZShTdHJpbmcgdXJpKQotICB7Ci0gICAgIGludCBpbmRleCA9IG1fdmFsdWVzLmluZGV4T2YodXJpKTsKLSAgICAgaWYgKGluZGV4IDwgMCkKLSAgICAgewotICAgICAgIG1fdmFsdWVzLmFkZEVsZW1lbnQodXJpKTsKLSAgICAgICByZXR1cm4gbV92YWx1ZUluZGV4Kys7Ci0gICAgIH0KLSAgICAgZWxzZQotICAgICAgIHJldHVybiBpbmRleDsKLSAgfQotCi0gIC8qKgotICAgKiBPdmVycmlkZSBTQVgyRFRNLnN0YXJ0RWxlbWVudCgpCi0gICAqCi0gICAqIDxwPlJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIHRoZSBzdGFydCBvZiBhbiBlbGVtZW50LgotICAgKgotICAgKiA8cD5CeSBkZWZhdWx0LCBkbyBub3RoaW5nLiAgQXBwbGljYXRpb24gd3JpdGVycyBtYXkgb3ZlcnJpZGUgdGhpcwotICAgKiBtZXRob2QgaW4gYSBzdWJjbGFzcyB0byB0YWtlIHNwZWNpZmljIGFjdGlvbnMgYXQgdGhlIHN0YXJ0IG9mCi0gICAqIGVhY2ggZWxlbWVudCAoc3VjaCBhcyBhbGxvY2F0aW5nIGEgbmV3IHRyZWUgbm9kZSBvciB3cml0aW5nCi0gICAqIG91dHB1dCB0byBhIGZpbGUpLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIHVyaSBUaGUgTmFtZXNwYWNlIFVSSSwgb3IgdGhlIGVtcHR5IHN0cmluZyBpZiB0aGUKLSAgICogICAgICAgIGVsZW1lbnQgaGFzIG5vIE5hbWVzcGFjZSBVUkkgb3IgaWYgTmFtZXNwYWNlCi0gICAqICAgICAgICBwcm9jZXNzaW5nIGlzIG5vdCBiZWluZyBwZXJmb3JtZWQuCi0gICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGxvY2FsIG5hbWUgKHdpdGhvdXQgcHJlZml4KSwgb3IgdGhlCi0gICAqICAgICAgICBlbXB0eSBzdHJpbmcgaWYgTmFtZXNwYWNlIHByb2Nlc3NpbmcgaXMgbm90IGJlaW5nCi0gICAqICAgICAgICBwZXJmb3JtZWQuCi0gICAqIEBwYXJhbSBxTmFtZSBUaGUgcXVhbGlmaWVkIG5hbWUgKHdpdGggcHJlZml4KSwgb3IgdGhlCi0gICAqICAgICAgICBlbXB0eSBzdHJpbmcgaWYgcXVhbGlmaWVkIG5hbWVzIGFyZSBub3QgYXZhaWxhYmxlLgotICAgKiBAcGFyYW0gYXR0cmlidXRlcyBUaGUgc3BlY2lmaWVkIG9yIGRlZmF1bHRlZCBhdHRyaWJ1dGVzLgotICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNzdGFydEVsZW1lbnQKLSAgICovCi0gIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudChTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxOYW1lLCBTdHJpbmcgcU5hbWUsIEF0dHJpYnV0ZXMgYXR0cmlidXRlcykKLSAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotCi0gICAgY2hhcmFjdGVyc0ZsdXNoKCk7Ci0KLSAgICBpbnQgZXhOYW1lID0gbV9leHBhbmRlZE5hbWVUYWJsZS5nZXRFeHBhbmRlZFR5cGVJRCh1cmksIGxvY2FsTmFtZSwgRFRNLkVMRU1FTlRfTk9ERSk7Ci0KLSAgICBpbnQgcHJlZml4SW5kZXggPSAocU5hbWUubGVuZ3RoKCkgIT0gbG9jYWxOYW1lLmxlbmd0aCgpKQotICAgICAgICAgICAgICAgICAgICAgID8gbV92YWx1ZXNPclByZWZpeGVzLnN0cmluZ1RvSW5kZXgocU5hbWUpIDogMDsKLQotICAgIGludCBlbGVtTm9kZSA9IGFkZE5vZGUoRFRNLkVMRU1FTlRfTk9ERSwgZXhOYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgbV9wYXJlbnRzLnBlZWsoKSwgbV9wcmV2aW91cywgcHJlZml4SW5kZXgsIHRydWUpOwotCi0gICAgaWYobV9pbmRleGluZykKLSAgICAgIGluZGV4Tm9kZShleE5hbWUsIGVsZW1Ob2RlKTsKLQotICAgIG1fcGFyZW50cy5wdXNoKGVsZW1Ob2RlKTsKLQotICAgIGludCBzdGFydERlY2xzID0gbV9jb250ZXh0SW5kZXhlcy5wZWVrKCk7Ci0gICAgaW50IG5EZWNscyA9IG1fcHJlZml4TWFwcGluZ3Muc2l6ZSgpOwotICAgIFN0cmluZyBwcmVmaXg7Ci0KLSAgICBpZighbV9wYXN0Rmlyc3RFbGVtZW50KQotICAgIHsKLSAgICAgIC8vIFNQRUNJQUwgQ0FTRTogSW1wbGllZCBkZWNsYXJhdGlvbiBhdCByb290IGVsZW1lbnQKLSAgICAgIHByZWZpeD0ieG1sIjsKLSAgICAgIFN0cmluZyBkZWNsVVJMID0gImh0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZSI7Ci0gICAgICBleE5hbWUgPSBtX2V4cGFuZGVkTmFtZVRhYmxlLmdldEV4cGFuZGVkVHlwZUlEKG51bGwsIHByZWZpeCwgRFRNLk5BTUVTUEFDRV9OT0RFKTsKLSAgICAgIG1fdmFsdWVzLmFkZEVsZW1lbnQoZGVjbFVSTCk7Ci0gICAgICBpbnQgdmFsID0gbV92YWx1ZUluZGV4Kys7Ci0gICAgICBhZGROb2RlKERUTS5OQU1FU1BBQ0VfTk9ERSwgZXhOYW1lLCBlbGVtTm9kZSwKLSAgICAgICAgICAgICAgICAgICAgIERUTS5OVUxMLCB2YWwsIGZhbHNlKTsKLSAgICAgIG1fcGFzdEZpcnN0RWxlbWVudD10cnVlOwotICAgIH0KLQotICAgIGZvciAoaW50IGkgPSBzdGFydERlY2xzOyBpIDwgbkRlY2xzOyBpICs9IDIpCi0gICAgewotICAgICAgcHJlZml4ID0gKFN0cmluZykgbV9wcmVmaXhNYXBwaW5ncy5lbGVtZW50QXQoaSk7Ci0KLSAgICAgIGlmIChwcmVmaXggPT0gbnVsbCkKLSAgICAgICAgY29udGludWU7Ci0KLSAgICAgIFN0cmluZyBkZWNsVVJMID0gKFN0cmluZykgbV9wcmVmaXhNYXBwaW5ncy5lbGVtZW50QXQoaSArIDEpOwotCi0gICAgICBleE5hbWUgPSBtX2V4cGFuZGVkTmFtZVRhYmxlLmdldEV4cGFuZGVkVHlwZUlEKG51bGwsIHByZWZpeCwgRFRNLk5BTUVTUEFDRV9OT0RFKTsKLQotICAgICAgbV92YWx1ZXMuYWRkRWxlbWVudChkZWNsVVJMKTsKLSAgICAgIGludCB2YWwgPSBtX3ZhbHVlSW5kZXgrKzsKLQotICAgICAgYWRkTm9kZShEVE0uTkFNRVNQQUNFX05PREUsIGV4TmFtZSwgZWxlbU5vZGUsIERUTS5OVUxMLCB2YWwsIGZhbHNlKTsKLSAgICB9Ci0KLSAgICBpbnQgbiA9IGF0dHJpYnV0ZXMuZ2V0TGVuZ3RoKCk7Ci0KLSAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykKLSAgICB7Ci0gICAgICBTdHJpbmcgYXR0clVyaSA9IGF0dHJpYnV0ZXMuZ2V0VVJJKGkpOwotICAgICAgU3RyaW5nIGF0dHJRTmFtZSA9IGF0dHJpYnV0ZXMuZ2V0UU5hbWUoaSk7Ci0gICAgICBTdHJpbmcgdmFsU3RyaW5nID0gYXR0cmlidXRlcy5nZXRWYWx1ZShpKTsKLQotICAgICAgaW50IG5vZGVUeXBlOwotCi0gICAgICBTdHJpbmcgYXR0ckxvY2FsTmFtZSA9IGF0dHJpYnV0ZXMuZ2V0TG9jYWxOYW1lKGkpOwotCi0gICAgICBpZiAoKG51bGwgIT0gYXR0clFOYW1lKQotICAgICAgICAgICAgICAmJiAoYXR0clFOYW1lLmVxdWFscygieG1sbnMiKQotICAgICAgICAgICAgICAgICAgfHwgYXR0clFOYW1lLnN0YXJ0c1dpdGgoInhtbG5zOiIpKSkKLSAgICAgIHsKLSAgICAgICAgcHJlZml4ID0gZ2V0UHJlZml4KGF0dHJRTmFtZSwgYXR0clVyaSk7Ci0gICAgICAgIGlmIChkZWNsQWxyZWFkeURlY2xhcmVkKHByZWZpeCkpCi0gICAgICAgICAgY29udGludWU7ICAvLyBnbyB0byB0aGUgbmV4dCBhdHRyaWJ1dGUuCi0KLSAgICAgICAgbm9kZVR5cGUgPSBEVE0uTkFNRVNQQUNFX05PREU7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIG5vZGVUeXBlID0gRFRNLkFUVFJJQlVURV9OT0RFOwotCi0gICAgICAgIGlmIChtX2J1aWxkSWRJbmRleCAmJiBhdHRyaWJ1dGVzLmdldFR5cGUoaSkuZXF1YWxzSWdub3JlQ2FzZSgiSUQiKSkKLSAgICAgICAgICBzZXRJREF0dHJpYnV0ZSh2YWxTdHJpbmcsIGVsZW1Ob2RlKTsKLSAgICAgIH0KLQotICAgICAgLy8gQml0IG9mIGEgaGFjay4uLiBpZiBzb21laG93IHZhbFN0cmluZyBpcyBudWxsLCBzdHJpbmdUb0luZGV4IHdpbGwKLSAgICAgIC8vIHJldHVybiAtMSwgd2hpY2ggd2lsbCBtYWtlIHRoaW5ncyB2ZXJ5IHVuaGFwcHkuCi0gICAgICBpZihudWxsID09IHZhbFN0cmluZykKLSAgICAgICAgdmFsU3RyaW5nID0gIiI7Ci0KLSAgICAgIG1fdmFsdWVzLmFkZEVsZW1lbnQodmFsU3RyaW5nKTsKLSAgICAgIGludCB2YWwgPSBtX3ZhbHVlSW5kZXgrKzsKLQotICAgICAgaWYgKGF0dHJMb2NhbE5hbWUubGVuZ3RoKCkgIT0gYXR0clFOYW1lLmxlbmd0aCgpKQotICAgICAgewotCi0gICAgICAgIHByZWZpeEluZGV4ID0gbV92YWx1ZXNPclByZWZpeGVzLnN0cmluZ1RvSW5kZXgoYXR0clFOYW1lKTsKLQotICAgICAgICBpbnQgZGF0YUluZGV4ID0gbV9kYXRhLnNpemUoKTsKLQotICAgICAgICBtX2RhdGEuYWRkRWxlbWVudChwcmVmaXhJbmRleCk7Ci0gICAgICAgIG1fZGF0YS5hZGRFbGVtZW50KHZhbCk7Ci0KLSAgICAgICAgdmFsID0gLWRhdGFJbmRleDsKLSAgICAgIH0KLQotICAgICAgZXhOYW1lID0gbV9leHBhbmRlZE5hbWVUYWJsZS5nZXRFeHBhbmRlZFR5cGVJRChhdHRyVXJpLCBhdHRyTG9jYWxOYW1lLCBub2RlVHlwZSk7Ci0gICAgICBhZGROb2RlKG5vZGVUeXBlLCBleE5hbWUsIGVsZW1Ob2RlLCBEVE0uTlVMTCwgdmFsLAotICAgICAgICAgICAgICAgICAgICAgZmFsc2UpOwotICAgIH0KLQotICAgIGlmIChudWxsICE9IG1fd3NmaWx0ZXIpCi0gICAgewotICAgICAgc2hvcnQgd3N2ID0gbV93c2ZpbHRlci5nZXRTaG91bGRTdHJpcFNwYWNlKG1ha2VOb2RlSGFuZGxlKGVsZW1Ob2RlKSwgdGhpcyk7Ci0gICAgICBib29sZWFuIHNob3VsZFN0cmlwID0gKERUTVdTRmlsdGVyLklOSEVSSVQgPT0gd3N2KQotICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gZ2V0U2hvdWxkU3RyaXBXaGl0ZXNwYWNlKCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IChEVE1XU0ZpbHRlci5TVFJJUCA9PSB3c3YpOwotCi0gICAgICBwdXNoU2hvdWxkU3RyaXBXaGl0ZXNwYWNlKHNob3VsZFN0cmlwKTsKLSAgICB9Ci0KLSAgICBtX3ByZXZpb3VzID0gRFRNLk5VTEw7Ci0KLSAgICBtX2NvbnRleHRJbmRleGVzLnB1c2gobV9wcmVmaXhNYXBwaW5ncy5zaXplKCkpOyAgLy8gZm9yIHRoZSBjaGlsZHJlbi4KLSAgfQotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiB0aGUgZW5kIG9mIGFuIGVsZW1lbnQuCi0gICAqCi0gICAqIDxwPkJ5IGRlZmF1bHQsIGRvIG5vdGhpbmcuICBBcHBsaWNhdGlvbiB3cml0ZXJzIG1heSBvdmVycmlkZSB0aGlzCi0gICAqIG1ldGhvZCBpbiBhIHN1YmNsYXNzIHRvIHRha2Ugc3BlY2lmaWMgYWN0aW9ucyBhdCB0aGUgZW5kIG9mCi0gICAqIGVhY2ggZWxlbWVudCAoc3VjaCBhcyBmaW5hbGlzaW5nIGEgdHJlZSBub2RlIG9yIHdyaXRpbmcKLSAgICogb3V0cHV0IHRvIGEgZmlsZSkuPC9wPgotICAgKgotICAgKiBAcGFyYW0gdXJpIFRoZSBOYW1lc3BhY2UgVVJJLCBvciB0aGUgZW1wdHkgc3RyaW5nIGlmIHRoZQotICAgKiAgICAgICAgZWxlbWVudCBoYXMgbm8gTmFtZXNwYWNlIFVSSSBvciBpZiBOYW1lc3BhY2UKLSAgICogICAgICAgIHByb2Nlc3NpbmcgaXMgbm90IGJlaW5nIHBlcmZvcm1lZC4KLSAgICogQHBhcmFtIGxvY2FsTmFtZSBUaGUgbG9jYWwgbmFtZSAod2l0aG91dCBwcmVmaXgpLCBvciB0aGUKLSAgICogICAgICAgIGVtcHR5IHN0cmluZyBpZiBOYW1lc3BhY2UgcHJvY2Vzc2luZyBpcyBub3QgYmVpbmcKLSAgICogICAgICAgIHBlcmZvcm1lZC4KLSAgICogQHBhcmFtIHFOYW1lIFRoZSBxdWFsaWZpZWQgWE1MIDEuMCBuYW1lICh3aXRoIHByZWZpeCksIG9yIHRoZQotICAgKiAgICAgICAgZW1wdHkgc3RyaW5nIGlmIHF1YWxpZmllZCBuYW1lcyBhcmUgbm90IGF2YWlsYWJsZS4KLSAgICogQHRocm93cyBTQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjZW5kRWxlbWVudAotICAgKi8KLSAgcHVibGljIHZvaWQgZW5kRWxlbWVudChTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxOYW1lLCBTdHJpbmcgcU5hbWUpCi0gICAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICB7Ci0gICAgY2hhcmFjdGVyc0ZsdXNoKCk7Ci0KLSAgICAvLyBJZiBubyBvbmUgbm90aWNlZCwgc3RhcnRQcmVmaXhNYXBwaW5nIGlzIGEgZHJhZy4KLSAgICAvLyBQb3AgdGhlIGNvbnRleHQgZm9yIHRoZSBsYXN0IGNoaWxkICh0aGUgb25lIHB1c2hlZCBieSBzdGFydEVsZW1lbnQpCi0gICAgbV9jb250ZXh0SW5kZXhlcy5xdWlja1BvcCgxKTsKLQotICAgIC8vIERvIGl0IGFnYWluIGZvciB0aGlzIG9uZSAodGhlIG9uZSBwdXNoZWQgYnkgdGhlIGxhc3QgZW5kRWxlbWVudCkuCi0gICAgaW50IHRvcENvbnRleHRJbmRleCA9IG1fY29udGV4dEluZGV4ZXMucGVlaygpOwotICAgIGlmICh0b3BDb250ZXh0SW5kZXggIT0gbV9wcmVmaXhNYXBwaW5ncy5zaXplKCkpIHsKLSAgICAgIG1fcHJlZml4TWFwcGluZ3Muc2V0U2l6ZSh0b3BDb250ZXh0SW5kZXgpOwotICAgIH0KLQotICAgIG1fcHJldmlvdXMgPSBtX3BhcmVudHMucG9wKCk7Ci0KLSAgICBwb3BTaG91bGRTdHJpcFdoaXRlc3BhY2UoKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXBvcnQgYW4gWE1MIGNvbW1lbnQgYW55d2hlcmUgaW4gdGhlIGRvY3VtZW50LgotICAgKgotICAgKiA8cD5UaGlzIGNhbGxiYWNrIHdpbGwgYmUgdXNlZCBmb3IgY29tbWVudHMgaW5zaWRlIG9yIG91dHNpZGUgdGhlCi0gICAqIGRvY3VtZW50IGVsZW1lbnQsIGluY2x1ZGluZyBjb21tZW50cyBpbiB0aGUgZXh0ZXJuYWwgRFRECi0gICAqIHN1YnNldCAoaWYgcmVhZCkuPC9wPgotICAgKgotICAgKiBAcGFyYW0gY2ggQW4gYXJyYXkgaG9sZGluZyB0aGUgY2hhcmFjdGVycyBpbiB0aGUgY29tbWVudC4KLSAgICogQHBhcmFtIHN0YXJ0IFRoZSBzdGFydGluZyBwb3NpdGlvbiBpbiB0aGUgYXJyYXkuCi0gICAqIEBwYXJhbSBsZW5ndGggVGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHVzZSBmcm9tIHRoZSBhcnJheS4KLSAgICogQHRocm93cyBTQVhFeGNlcHRpb24gVGhlIGFwcGxpY2F0aW9uIG1heSByYWlzZSBhbiBleGNlcHRpb24uCi0gICAqLwotICBwdWJsaWMgdm9pZCBjb21tZW50KGNoYXIgY2hbXSwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChtX2luc2lkZURURCkgICAgICAvLyBpZ25vcmUgY29tbWVudHMgaWYgd2UncmUgaW5zaWRlIHRoZSBEVEQKLSAgICAgIHJldHVybjsKLQotICAgIGNoYXJhY3RlcnNGbHVzaCgpOwotCi0gICAgLy8gJU9QVCUgU2F2aW5nIHRoZSBjb21tZW50IHN0cmluZyBpbiBhIFZlY3RvciBoYXMgYSBsb3dlciBjb3N0IHRoYW4KLSAgICAvLyBzYXZpbmcgaXQgaW4gRFRNU3RyaW5nUG9vbC4KLSAgICBtX3ZhbHVlcy5hZGRFbGVtZW50KG5ldyBTdHJpbmcoY2gsIHN0YXJ0LCBsZW5ndGgpKTsKLSAgICBpbnQgZGF0YUluZGV4ID0gbV92YWx1ZUluZGV4Kys7Ci0KLSAgICBtX3ByZXZpb3VzID0gYWRkTm9kZShEVE0uQ09NTUVOVF9OT0RFLCBEVE0uQ09NTUVOVF9OT0RFLAotICAgICAgICAgICAgICAgICAgICAgICAgIG1fcGFyZW50cy5wZWVrKCksIG1fcHJldmlvdXMsIGRhdGFJbmRleCwgZmFsc2UpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIHRoZSBiZWdpbm5pbmcgb2YgdGhlIGRvY3VtZW50LgotICAgKgotICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNzdGFydERvY3VtZW50Ci0gICAqLwotICBwdWJsaWMgdm9pZCBzdGFydERvY3VtZW50KCkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICBpbnQgZG9jID0gYWRkTm9kZShEVE0uRE9DVU1FTlRfTk9ERSwKLSAgICAgICAgICAgICAgICAgICAgICBEVE0uRE9DVU1FTlRfTk9ERSwKLSAgICAgICAgICAgICAgICAgICAgICBEVE0uTlVMTCwgRFRNLk5VTEwsIDAsIHRydWUpOwotCi0gICAgbV9wYXJlbnRzLnB1c2goZG9jKTsKLSAgICBtX3ByZXZpb3VzID0gRFRNLk5VTEw7Ci0KLSAgICBtX2NvbnRleHRJbmRleGVzLnB1c2gobV9wcmVmaXhNYXBwaW5ncy5zaXplKCkpOyAgLy8gZm9yIHRoZSBuZXh0IGVsZW1lbnQuCi0gIH0KLQotICAvKioKLSAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIGVuZCBvZiB0aGUgZG9jdW1lbnQuCi0gICAqCi0gICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI2VuZERvY3VtZW50Ci0gICAqLwotICBwdWJsaWMgdm9pZCBlbmREb2N1bWVudCgpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotICAgIHN1cGVyLmVuZERvY3VtZW50KCk7Ci0KLSAgICAvLyBBZGQgYSBOVUxMIGVudHJ5IHRvIHRoZSBlbmQgb2YgdGhlIG5vZGUgYXJyYXlzIGFzCi0gICAgLy8gdGhlIGVuZCBpbmRpY2F0aW9uLgotICAgIG1fZXhwdHlwZS5hZGRFbGVtZW50KE5VTEwpOwotICAgIG1fcGFyZW50LmFkZEVsZW1lbnQoTlVMTCk7Ci0gICAgbV9uZXh0c2liLmFkZEVsZW1lbnQoTlVMTCk7Ci0gICAgbV9maXJzdGNoLmFkZEVsZW1lbnQoTlVMTCk7Ci0KLSAgICAvLyBTZXQgdGhlIGNhY2hlZCByZWZlcmVuY2VzIGFmdGVyIHRoZSBkb2N1bWVudCBpcyBidWlsdC4KLSAgICBtX2V4dGVuZGVkVHlwZXMgPSBtX2V4cGFuZGVkTmFtZVRhYmxlLmdldEV4dGVuZGVkVHlwZXMoKTsKLSAgICBtX2V4cHR5cGVfbWFwID0gbV9leHB0eXBlLmdldE1hcCgpOwotICAgIG1fbmV4dHNpYl9tYXAgPSBtX25leHRzaWIuZ2V0TWFwKCk7Ci0gICAgbV9maXJzdGNoX21hcCA9IG1fZmlyc3RjaC5nZXRNYXAoKTsKLSAgICBtX3BhcmVudF9tYXAgID0gbV9wYXJlbnQuZ2V0TWFwKCk7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IHRoZSBub2RlIG1hcCBmcm9tIHRoZSBub2RlLgotICAgKgotICAgKiBAcGFyYW0gdHlwZSByYXcgdHlwZSBJRCwgb25lIG9mIERUTS5YWFhfTk9ERS4KLSAgICogQHBhcmFtIGV4cGFuZGVkVHlwZUlEIFRoZSBleHBlbmRlZCB0eXBlIElELgotICAgKiBAcGFyYW0gcGFyZW50SW5kZXggVGhlIGN1cnJlbnQgcGFyZW50IGluZGV4LgotICAgKiBAcGFyYW0gcHJldmlvdXNTaWJsaW5nIFRoZSBwcmV2aW91cyBzaWJsaW5nIGluZGV4LgotICAgKiBAcGFyYW0gZGF0YU9yUHJlZml4IGluZGV4IGludG8gbV9kYXRhIHRhYmxlLCBvciBzdHJpbmcgaGFuZGxlLgotICAgKiBAcGFyYW0gY2FuSGF2ZUZpcnN0Q2hpbGQgdHJ1ZSBpZiB0aGUgbm9kZSBjYW4gaGF2ZSBhIGZpcnN0IGNoaWxkLCBmYWxzZQotICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgaXQgaXMgYXRvbWljLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBpbmRleCBpZGVudGl0eSBvZiB0aGUgbm9kZSB0aGF0IHdhcyBhZGRlZC4KLSAgICovCi0gIHByb3RlY3RlZCBmaW5hbCBpbnQgYWRkTm9kZShpbnQgdHlwZSwgaW50IGV4cGFuZGVkVHlwZUlELAotICAgICAgICAgICAgICAgICAgICAgICAgaW50IHBhcmVudEluZGV4LCBpbnQgcHJldmlvdXNTaWJsaW5nLAotICAgICAgICAgICAgICAgICAgICAgICAgaW50IGRhdGFPclByZWZpeCwgYm9vbGVhbiBjYW5IYXZlRmlyc3RDaGlsZCkKLSAgewotICAgIC8vIENvbW1vbiB0byBhbGwgbm9kZXM6Ci0gICAgaW50IG5vZGVJbmRleCA9IG1fc2l6ZSsrOwotCi0gICAgLy8gSGF2ZSB3ZSBvdmVyZmxvd2VkIGEgRFRNIElkZW50aXR5J3MgYWRkcmVzc2luZyByYW5nZT8KLSAgICAvL2lmKG1fZHRtSWRlbnQuc2l6ZSgpID09IChub2RlSW5kZXg+Pj5EVE1NYW5hZ2VyLklERU5UX0RUTV9OT0RFX0JJVFMpKQotICAgIGlmIChub2RlSW5kZXggPT0gbV9tYXhOb2RlSW5kZXgpCi0gICAgewotICAgICAgYWRkTmV3RFRNSUQobm9kZUluZGV4KTsKLSAgICAgIG1fbWF4Tm9kZUluZGV4ICs9ICgxIDw8IERUTU1hbmFnZXIuSURFTlRfRFRNX05PREVfQklUUyk7Ci0gICAgfQotCi0gICAgbV9maXJzdGNoLmFkZEVsZW1lbnQoRFRNLk5VTEwpOwotICAgIG1fbmV4dHNpYi5hZGRFbGVtZW50KERUTS5OVUxMKTsKLSAgICBtX3BhcmVudC5hZGRFbGVtZW50KHBhcmVudEluZGV4KTsKLSAgICBtX2V4cHR5cGUuYWRkRWxlbWVudChleHBhbmRlZFR5cGVJRCk7Ci0gICAgbV9kYXRhT3JRTmFtZS5hZGRFbGVtZW50KGRhdGFPclByZWZpeCk7Ci0KLSAgICBpZiAobV9wcmV2c2liICE9IG51bGwpIHsKLSAgICAgIG1fcHJldnNpYi5hZGRFbGVtZW50KHByZXZpb3VzU2libGluZyk7Ci0gICAgfQotCi0gICAgaWYgKG1fbG9jYXRvciAhPSBudWxsICYmIG1fdXNlU291cmNlTG9jYXRpb25Qcm9wZXJ0eSkgewotICAgICAgc2V0U291cmNlTG9jYXRpb24oKTsKLSAgICB9Ci0KLSAgICAvLyBOb3RlIHRoYXQgbmV4dFNpYmxpbmcgaXMgbm90IHByb2Nlc3NlZCB1bnRpbCBjaGFyYWN0ZXJzRmx1c2goKQotICAgIC8vIGlzIGNhbGxlZCwgdG8gaGFuZGxlIHN1Y2Nlc3NpdmUgY2hhcmFjdGVycygpIGV2ZW50cy4KLQotICAgIC8vIFNwZWNpYWwgaGFuZGxpbmcgYnkgdHlwZTogRGVjbGFyZSBuYW1lc3BhY2VzLCBhdHRhY2ggZmlyc3QgY2hpbGQKLSAgICBzd2l0Y2godHlwZSkKLSAgICB7Ci0gICAgY2FzZSBEVE0uTkFNRVNQQUNFX05PREU6Ci0gICAgICBkZWNsYXJlTmFtZXNwYWNlSW5Db250ZXh0KHBhcmVudEluZGV4LG5vZGVJbmRleCk7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIERUTS5BVFRSSUJVVEVfTk9ERToKLSAgICAgIGJyZWFrOwotICAgIGRlZmF1bHQ6Ci0gICAgICBpZiAoRFRNLk5VTEwgIT0gcHJldmlvdXNTaWJsaW5nKSB7Ci0gICAgICAgIG1fbmV4dHNpYi5zZXRFbGVtZW50QXQobm9kZUluZGV4LHByZXZpb3VzU2libGluZyk7Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmIChEVE0uTlVMTCAhPSBwYXJlbnRJbmRleCkgewotICAgICAgICBtX2ZpcnN0Y2guc2V0RWxlbWVudEF0KG5vZGVJbmRleCxwYXJlbnRJbmRleCk7Ci0gICAgICB9Ci0gICAgICBicmVhazsKLSAgICB9Ci0KLSAgICByZXR1cm4gbm9kZUluZGV4OwotICB9Ci0KLSAgLyoqCi0gICAqIENoZWNrIHdoZXRoZXIgYWNjdW11bGF0ZWQgdGV4dCBzaG91bGQgYmUgc3RyaXBwZWQ7IGlmIG5vdCwKLSAgICogYXBwZW5kIHRoZSBhcHByb3ByaWF0ZSBmbGF2b3Igb2YgdGV4dC9jZGF0YSBub2RlLgotICAgKi8KLSAgcHJvdGVjdGVkIGZpbmFsIHZvaWQgY2hhcmFjdGVyc0ZsdXNoKCkKLSAgewotCi0gICAgaWYgKG1fdGV4dFBlbmRpbmdTdGFydCA+PSAwKSAgLy8gLTEgaW5kaWNhdGVzIG5vLXRleHQtaW4tcHJvZ3Jlc3MKLSAgICB7Ci0gICAgICBpbnQgbGVuZ3RoID0gbV9jaGFycy5zaXplKCkgLSBtX3RleHRQZW5kaW5nU3RhcnQ7Ci0gICAgICBib29sZWFuIGRvU3RyaXAgPSBmYWxzZTsKLQotICAgICAgaWYgKGdldFNob3VsZFN0cmlwV2hpdGVzcGFjZSgpKQotICAgICAgewotICAgICAgICBkb1N0cmlwID0gbV9jaGFycy5pc1doaXRlc3BhY2UobV90ZXh0UGVuZGluZ1N0YXJ0LCBsZW5ndGgpOwotICAgICAgfQotCi0gICAgICBpZiAoZG9TdHJpcCkgewotICAgICAgICBtX2NoYXJzLnNldExlbmd0aChtX3RleHRQZW5kaW5nU3RhcnQpOyAgLy8gRGlzY2FyZCBhY2N1bXVsYXRlZCB0ZXh0Ci0gICAgICB9IGVsc2UgewotICAgICAgICAvLyBHdWFyZCBhZ2FpbnN0IGNoYXJhY3RlcnMvaWdub3JhYmxlV2hpdGVzcGFjZSBldmVudHMgdGhhdAotICAgICAgICAvLyBjb250YWluZWQgbm8gY2hhcmFjdGVycy4gIFRoZXkgc2hvdWxkIG5vdCByZXN1bHQgaW4gYSBub2RlLgotICAgICAgICBpZiAobGVuZ3RoID4gMCkgewotICAgICAgICAgIC8vIElmIHRoZSBvZmZzZXQgYW5kIGxlbmd0aCBkbyBub3QgZXhjZWVkIHRoZSBnaXZlbiBsaW1pdHMKLSAgICAgICAgICAvLyAob2Zmc2V0IDwgMl4yMSBhbmQgbGVuZ3RoIDwgMl4xMCksIHRoZW4gc2F2ZSBib3RoIHRoZSBvZmZzZXQKLSAgICAgICAgICAvLyBhbmQgbGVuZ3RoIGluIGEgYml0d2lzZSBlbmNvZGVkIHZhbHVlLgotICAgICAgICAgIGlmIChsZW5ndGggPD0gVEVYVF9MRU5HVEhfTUFYCi0gICAgICAgICAgICAgICAgICAmJiBtX3RleHRQZW5kaW5nU3RhcnQgPD0gVEVYVF9PRkZTRVRfTUFYKSB7Ci0gICAgICAgICAgICBtX3ByZXZpb3VzID0gYWRkTm9kZShtX2NvYWxlc2NlZFRleHRUeXBlLCBEVE0uVEVYVF9OT0RFLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX3BhcmVudHMucGVlaygpLCBtX3ByZXZpb3VzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZW5ndGggKyAobV90ZXh0UGVuZGluZ1N0YXJ0IDw8IFRFWFRfTEVOR1RIX0JJVFMpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSk7Ci0KLSAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgLy8gU3RvcmUgb2Zmc2V0IGFuZCBsZW5ndGggaW4gdGhlIG1fZGF0YSBhcnJheSBpZiBvbmUgZXhjZWVkcwotICAgICAgICAgICAgLy8gdGhlIGdpdmVuIGxpbWl0cy4gVXNlIGEgbmVnYXRpdmUgZGF0YUluZGV4IGFzIGFuIGluZGljYXRpb24uCi0gICAgICAgICAgICBpbnQgZGF0YUluZGV4ID0gbV9kYXRhLnNpemUoKTsKLSAgICAgICAgICAgIG1fcHJldmlvdXMgPSBhZGROb2RlKG1fY29hbGVzY2VkVGV4dFR5cGUsIERUTS5URVhUX05PREUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbV9wYXJlbnRzLnBlZWsoKSwgbV9wcmV2aW91cywgLWRhdGFJbmRleCwgZmFsc2UpOwotCi0gICAgICAgICAgICBtX2RhdGEuYWRkRWxlbWVudChtX3RleHRQZW5kaW5nU3RhcnQpOwotICAgICAgICAgICAgbV9kYXRhLmFkZEVsZW1lbnQobGVuZ3RoKTsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgIH0KLQotICAgICAgLy8gUmVzZXQgZm9yIG5leHQgdGV4dCBibG9jawotICAgICAgbV90ZXh0UGVuZGluZ1N0YXJ0ID0gLTE7Ci0gICAgICBtX3RleHRUeXBlID0gbV9jb2FsZXNjZWRUZXh0VHlwZSA9IERUTS5URVhUX05PREU7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIE92ZXJyaWRlIHRoZSBwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oKSBpbnRlcmZhY2UgaW4gU0FYMkRUTTIuCi0gICAqIDxwPgotICAgKiAlT1BUJSBUaGlzIG9uZSBpcyBkaWZmZXJlbnQgZnJvbSBTQVgyRFRNLnByb2Nlc3NpbmdJbnN0cnVjdGlvbigpCi0gICAqIGluIHRoYXQgd2UgZG8gbm90IHVzZSBleHRlbmRlZCB0eXBlcyBmb3IgUEkgbm9kZXMuIFRoZSBuYW1lIG9mCi0gICAqIHRoZSBQSSBpcyBzYXZlZCBpbiB0aGUgRFRNU3RyaW5nUG9vbC4KLSAgICoKLSAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgYSBwcm9jZXNzaW5nIGluc3RydWN0aW9uLgotICAgKgotICAgKiBAcGFyYW0gdGFyZ2V0IFRoZSBwcm9jZXNzaW5nIGluc3RydWN0aW9uIHRhcmdldC4KLSAgICogQHBhcmFtIGRhdGEgVGhlIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gZGF0YSwgb3IgbnVsbCBpZgotICAgKiAgICAgICAgICAgICBub25lIGlzIHN1cHBsaWVkLgotICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHByb2Nlc3NpbmdJbnN0cnVjdGlvbihTdHJpbmcgdGFyZ2V0LCBTdHJpbmcgZGF0YSkKLSAgICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIGNoYXJhY3RlcnNGbHVzaCgpOwotCi0gICAgaW50IGRhdGFJbmRleCA9IG1fZGF0YS5zaXplKCk7Ci0gICAgbV9wcmV2aW91cyA9IGFkZE5vZGUoRFRNLlBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERSwKLSAgICAgICAgICAgICAgICAgICAgICAgICBEVE0uUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFLAotICAgICAgICAgICAgICAgICAgICAgICAgIG1fcGFyZW50cy5wZWVrKCksIG1fcHJldmlvdXMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgLWRhdGFJbmRleCwgZmFsc2UpOwotCi0gICAgbV9kYXRhLmFkZEVsZW1lbnQobV92YWx1ZXNPclByZWZpeGVzLnN0cmluZ1RvSW5kZXgodGFyZ2V0KSk7Ci0gICAgbV92YWx1ZXMuYWRkRWxlbWVudChkYXRhKTsKLSAgICBtX2RhdGEuYWRkRWxlbWVudChtX3ZhbHVlSW5kZXgrKyk7Ci0KLSAgfQotCi0gIC8qKgotICAgKiBUaGUgb3B0aW1pemVkIHZlcnNpb24gb2YgRFRNRGVmYXVsdEJhc2UuZ2V0Rmlyc3RBdHRyaWJ1dGUoKS4KLSAgICogPHA+Ci0gICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIGdldCB0aGUgaW5kZXggb2YgdGhlIG5vZGUncyBmaXJzdCBhdHRyaWJ1dGUuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIGludCBIYW5kbGUgb2YgdGhlIG5vZGUuCi0gICAqIEByZXR1cm4gSGFuZGxlIG9mIGZpcnN0IGF0dHJpYnV0ZSwgb3IgRFRNLk5VTEwgdG8gaW5kaWNhdGUgbm9uZSBleGlzdHMuCi0gICAqLwotICBwdWJsaWMgZmluYWwgaW50IGdldEZpcnN0QXR0cmlidXRlKGludCBub2RlSGFuZGxlKQotICB7Ci0gICAgaW50IG5vZGVJRCA9IG1ha2VOb2RlSWRlbnRpdHkobm9kZUhhbmRsZSk7Ci0KLSAgICBpZiAobm9kZUlEID09IERUTS5OVUxMKQotICAgICAgcmV0dXJuIERUTS5OVUxMOwotCi0gICAgaW50IHR5cGUgPSBfdHlwZTIobm9kZUlEKTsKLQotICAgIGlmIChEVE0uRUxFTUVOVF9OT0RFID09IHR5cGUpCi0gICAgewotICAgICAgLy8gQXNzdW1lIHRoYXQgYXR0cmlidXRlcyBhbmQgbmFtZXNwYWNlcyBpbW1lZGlhdGVseSBmb2xsb3cgdGhlIGVsZW1lbnQuCi0gICAgICB3aGlsZSAodHJ1ZSkKLSAgICAgIHsKLSAgICAgICAgbm9kZUlEKys7Ci0gICAgICAgIC8vIEFzc3VtZSB0aGlzIGNhbiBub3QgYmUgbnVsbC4KLSAgICAgICAgdHlwZSA9IF90eXBlMihub2RlSUQpOwotCi0gICAgICAgIGlmICh0eXBlID09IERUTS5BVFRSSUJVVEVfTk9ERSkKLSAgICAgICAgewotICAgICAgICAgIHJldHVybiBtYWtlTm9kZUhhbmRsZShub2RlSUQpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKERUTS5OQU1FU1BBQ0VfTk9ERSAhPSB0eXBlKQotICAgICAgICB7Ci0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gRFRNLk5VTEw7Ci0gIH0KLQotICAvKioKLSAgICogVGhlIG9wdGltaXplZCB2ZXJzaW9uIG9mIERUTURlZmF1bHRCYXNlLmdldEZpcnN0QXR0cmlidXRlSWRlbnRpdHkoaW50KS4KLSAgICogPHA+Ci0gICAqIEdpdmVuIGEgbm9kZSBpZGVudGl0eSwgZ2V0IHRoZSBpbmRleCBvZiB0aGUgbm9kZSdzIGZpcnN0IGF0dHJpYnV0ZS4KLSAgICoKLSAgICogQHBhcmFtIGlkZW50aXR5IGludCBpZGVudGl0eSBvZiB0aGUgbm9kZS4KLSAgICogQHJldHVybiBJZGVudGl0eSBvZiBmaXJzdCBhdHRyaWJ1dGUsIG9yIERUTS5OVUxMIHRvIGluZGljYXRlIG5vbmUgZXhpc3RzLgotICAgKi8KLSAgcHJvdGVjdGVkIGludCBnZXRGaXJzdEF0dHJpYnV0ZUlkZW50aXR5KGludCBpZGVudGl0eSkgewotICAgIGlmIChpZGVudGl0eSA9PSBOVUxMKSB7Ci0gICAgICAgIHJldHVybiBOVUxMOwotICAgIH0KLSAgICBpbnQgdHlwZSA9IF90eXBlMihpZGVudGl0eSk7Ci0KLSAgICBpZiAoRFRNLkVMRU1FTlRfTk9ERSA9PSB0eXBlKQotICAgIHsKLSAgICAgIC8vIEFzc3VtZSB0aGF0IGF0dHJpYnV0ZXMgYW5kIG5hbWVzcGFjZXMgaW1tZWRpYXRlbHkgZm9sbG93IHRoZSBlbGVtZW50LgotICAgICAgd2hpbGUgKHRydWUpCi0gICAgICB7Ci0gICAgICAgIGlkZW50aXR5Kys7Ci0KLSAgICAgICAgLy8gQXNzdW1lIHRoaXMgY2FuIG5vdCBiZSBudWxsLgotICAgICAgICB0eXBlID0gX3R5cGUyKGlkZW50aXR5KTsKLQotICAgICAgICBpZiAodHlwZSA9PSBEVE0uQVRUUklCVVRFX05PREUpCi0gICAgICAgIHsKLSAgICAgICAgICByZXR1cm4gaWRlbnRpdHk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoRFRNLk5BTUVTUEFDRV9OT0RFICE9IHR5cGUpCi0gICAgICAgIHsKLSAgICAgICAgICBicmVhazsKLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiBEVE0uTlVMTDsKLSAgfQotCi0gIC8qKgotICAgKiBUaGUgb3B0aW1pemVkIHZlcnNpb24gb2YgRFRNRGVmYXVsdEJhc2UuZ2V0TmV4dEF0dHJpYnV0ZUlkZW50aXR5KGludCkuCi0gICAqIDxwPgotICAgKiBHaXZlbiBhIG5vZGUgaWRlbnRpdHkgZm9yIGFuIGF0dHJpYnV0ZSwgYWR2YW5jZSB0byB0aGUgbmV4dCBhdHRyaWJ1dGUuCi0gICAqCi0gICAqIEBwYXJhbSBpZGVudGl0eSBpbnQgaWRlbnRpdHkgb2YgdGhlIGF0dHJpYnV0ZSBub2RlLiAgVGhpcwotICAgKiA8c3Ryb25nPm11c3Q8L3N0cm9uZz4gYmUgYW4gYXR0cmlidXRlIG5vZGUuCi0gICAqCi0gICAqIEByZXR1cm4gaW50IERUTSBub2RlLWlkZW50aXR5IG9mIHRoZSByZXNvbHZlZCBhdHRyLAotICAgKiBvciBEVE0uTlVMTCB0byBpbmRpY2F0ZSBub25lIGV4aXN0cy4KLSAgICoKLSAgICovCi0gIHByb3RlY3RlZCBpbnQgZ2V0TmV4dEF0dHJpYnV0ZUlkZW50aXR5KGludCBpZGVudGl0eSkgewotICAgIC8vIEFzc3VtZSB0aGF0IGF0dHJpYnV0ZXMgYW5kIG5hbWVzcGFjZSBub2RlcyBpbW1lZGlhdGVseSBmb2xsb3cgdGhlIGVsZW1lbnQKLSAgICB3aGlsZSAodHJ1ZSkgewotICAgICAgaWRlbnRpdHkrKzsKLSAgICAgIGludCB0eXBlID0gX3R5cGUyKGlkZW50aXR5KTsKLQotICAgICAgaWYgKHR5cGUgPT0gRFRNLkFUVFJJQlVURV9OT0RFKSB7Ci0gICAgICAgIHJldHVybiBpZGVudGl0eTsKLSAgICAgIH0gZWxzZSBpZiAodHlwZSAhPSBEVE0uTkFNRVNQQUNFX05PREUpIHsKLSAgICAgICAgYnJlYWs7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgcmV0dXJuIERUTS5OVUxMOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoZSBvcHRpbWl6ZWQgdmVyc2lvbiBvZiBEVE1EZWZhdWx0QmFzZS5nZXRUeXBlZEF0dHJpYnV0ZShpbnQsIGludCkuCi0gICAqIDxwPgotICAgKiBHaXZlbiBhIG5vZGUgaGFuZGxlIGFuZCBhbiBleHBhbmRlZCB0eXBlIElELCBnZXQgdGhlIGluZGV4IG9mIHRoZSBub2RlJ3MKLSAgICogYXR0cmlidXRlIG9mIHRoYXQgdHlwZSwgaWYgYW55LgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBpbnQgSGFuZGxlIG9mIHRoZSBub2RlLgotICAgKiBAcGFyYW0gYXR0VHlwZSBpbnQgZXhwYW5kZWQgdHlwZSBJRCBvZiB0aGUgcmVxdWlyZWQgYXR0cmlidXRlLgotICAgKiBAcmV0dXJuIEhhbmRsZSBvZiBhdHRyaWJ1dGUgb2YgdGhlIHJlcXVpcmVkIHR5cGUsIG9yIERUTS5OVUxMIHRvIGluZGljYXRlCi0gICAqIG5vbmUgZXhpc3RzLgotICAgKi8KLSAgcHJvdGVjdGVkIGZpbmFsIGludCBnZXRUeXBlZEF0dHJpYnV0ZShpbnQgbm9kZUhhbmRsZSwgaW50IGF0dFR5cGUpCi0gIHsKLQotICAgIGludCBub2RlSUQgPSBtYWtlTm9kZUlkZW50aXR5KG5vZGVIYW5kbGUpOwotCi0gICAgaWYgKG5vZGVJRCA9PSBEVE0uTlVMTCkKLSAgICAgIHJldHVybiBEVE0uTlVMTDsKLQotICAgIGludCB0eXBlID0gX3R5cGUyKG5vZGVJRCk7Ci0KLSAgICBpZiAoRFRNLkVMRU1FTlRfTk9ERSA9PSB0eXBlKQotICAgIHsKLSAgICAgIGludCBleHBUeXBlOwotICAgICAgd2hpbGUgKHRydWUpCi0gICAgICB7Ci0gICAgICAgIG5vZGVJRCsrOwotICAgICAgICBleHBUeXBlID0gX2V4cHR5cGUyKG5vZGVJRCk7Ci0KLSAgICAgICAgaWYgKGV4cFR5cGUgIT0gRFRNLk5VTEwpCi0gICAgICAgICAgdHlwZSA9IG1fZXh0ZW5kZWRUeXBlc1tleHBUeXBlXS5nZXROb2RlVHlwZSgpOwotICAgICAgICBlbHNlCi0gICAgICAgICAgcmV0dXJuIERUTS5OVUxMOwotCi0gICAgICAgIGlmICh0eXBlID09IERUTS5BVFRSSUJVVEVfTk9ERSkKLSAgICAgICAgewotICAgICAgICAgIGlmIChleHBUeXBlID09IGF0dFR5cGUpIHJldHVybiBtYWtlTm9kZUhhbmRsZShub2RlSUQpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKERUTS5OQU1FU1BBQ0VfTk9ERSAhPSB0eXBlKQotICAgICAgICB7Ci0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gRFRNLk5VTEw7Ci0gIH0KLQotICAvKioKLSAgICogT3ZlcnJpZGUgU0FYMkRUTS5nZXRMb2NhbE5hbWUoKSBpbiBTQVgyRFRNMi4KLSAgICogPHA+UHJvY2Vzc2luZyBmb3IgUElzIGlzIGRpZmZlcmVudC4KLSAgICoKLSAgICogR2l2ZW4gYSBub2RlIGhhbmRsZSwgcmV0dXJuIGl0cyBYUGF0aC0gc3R5bGUgbG9jYWxuYW1lLiAoQXMgZGVmaW5lZCBpbgotICAgKiBOYW1lc3BhY2VzLCB0aGlzIGlzIHRoZSBwb3J0aW9uIG9mIHRoZSBuYW1lIGFmdGVyIGFueSBjb2xvbiBjaGFyYWN0ZXIpLgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSB0aGUgaWQgb2YgdGhlIG5vZGUuCi0gICAqIEByZXR1cm4gU3RyaW5nIExvY2FsIG5hbWUgb2YgdGhpcyBub2RlLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRMb2NhbE5hbWUoaW50IG5vZGVIYW5kbGUpCi0gIHsKLSAgICBpbnQgZXhwVHlwZSA9IF9leHB0eXBlKG1ha2VOb2RlSWRlbnRpdHkobm9kZUhhbmRsZSkpOwotCi0gICAgaWYgKGV4cFR5cGUgPT0gRFRNLlBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERSkKLSAgICB7Ci0gICAgICBpbnQgZGF0YUluZGV4ID0gX2RhdGFPclFOYW1lKG1ha2VOb2RlSWRlbnRpdHkobm9kZUhhbmRsZSkpOwotICAgICAgZGF0YUluZGV4ID0gbV9kYXRhLmVsZW1lbnRBdCgtZGF0YUluZGV4KTsKLSAgICAgIHJldHVybiBtX3ZhbHVlc09yUHJlZml4ZXMuaW5kZXhUb1N0cmluZyhkYXRhSW5kZXgpOwotICAgIH0KLSAgICBlbHNlCi0gICAgICByZXR1cm4gbV9leHBhbmRlZE5hbWVUYWJsZS5nZXRMb2NhbE5hbWUoZXhwVHlwZSk7Ci0gIH0KLQotICAvKioKLSAgICogVGhlIG9wdGltaXplZCB2ZXJzaW9uIG9mIFNBWDJEVE0uZ2V0Tm9kZU5hbWVYKCkuCi0gICAqIDxwPgotICAgKiBHaXZlbiBhIG5vZGUgaGFuZGxlLCByZXR1cm4gdGhlIFhQYXRoIG5vZGUgbmFtZS4gVGhpcyBzaG91bGQgYmUgdGhlIG5hbWUKLSAgICogYXMgZGVzY3JpYmVkIGJ5IHRoZSBYUGF0aCBkYXRhIG1vZGVsLCBOT1QgdGhlIERPTS0gc3R5bGUgbmFtZS4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgdGhlIGlkIG9mIHRoZSBub2RlLgotICAgKiBAcmV0dXJuIFN0cmluZyBOYW1lIG9mIHRoaXMgbm9kZSwgd2hpY2ggbWF5IGJlIGFuIGVtcHR5IHN0cmluZy4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBTdHJpbmcgZ2V0Tm9kZU5hbWVYKGludCBub2RlSGFuZGxlKQotICB7Ci0KLSAgICBpbnQgbm9kZUlEID0gbWFrZU5vZGVJZGVudGl0eShub2RlSGFuZGxlKTsKLSAgICBpbnQgZVR5cGUgPSBfZXhwdHlwZTIobm9kZUlEKTsKLQotICAgIGlmIChlVHlwZSA9PSBEVE0uUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFKQotICAgIHsKLSAgICAgIGludCBkYXRhSW5kZXggPSBfZGF0YU9yUU5hbWUobm9kZUlEKTsKLSAgICAgIGRhdGFJbmRleCA9IG1fZGF0YS5lbGVtZW50QXQoLWRhdGFJbmRleCk7Ci0gICAgICByZXR1cm4gbV92YWx1ZXNPclByZWZpeGVzLmluZGV4VG9TdHJpbmcoZGF0YUluZGV4KTsKLSAgICB9Ci0KLSAgICBmaW5hbCBFeHRlbmRlZFR5cGUgZXh0VHlwZSA9IG1fZXh0ZW5kZWRUeXBlc1tlVHlwZV07Ci0KLSAgICBpZiAoZXh0VHlwZS5nZXROYW1lc3BhY2UoKS5sZW5ndGgoKSA9PSAwKQotICAgIHsKLSAgICAgIHJldHVybiBleHRUeXBlLmdldExvY2FsTmFtZSgpOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgaW50IHFuYW1lSW5kZXggPSBtX2RhdGFPclFOYW1lLmVsZW1lbnRBdChub2RlSUQpOwotCi0gICAgICBpZiAocW5hbWVJbmRleCA9PSAwKQotICAgICAgICByZXR1cm4gZXh0VHlwZS5nZXRMb2NhbE5hbWUoKTsKLQotICAgICAgaWYgKHFuYW1lSW5kZXggPCAwKQotICAgICAgewotICAgICAgICBxbmFtZUluZGV4ID0gLXFuYW1lSW5kZXg7Ci0gICAgICAgIHFuYW1lSW5kZXggPSBtX2RhdGEuZWxlbWVudEF0KHFuYW1lSW5kZXgpOwotICAgICAgfQotCi0gICAgICByZXR1cm4gbV92YWx1ZXNPclByZWZpeGVzLmluZGV4VG9TdHJpbmcocW5hbWVJbmRleCk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFRoZSBvcHRpbWl6ZWQgdmVyc2lvbiBvZiBTQVgyRFRNLmdldE5vZGVOYW1lKCkuCi0gICAqIDxwPgotICAgKiBHaXZlbiBhIG5vZGUgaGFuZGxlLCByZXR1cm4gaXRzIERPTS1zdHlsZSBub2RlIG5hbWUuIFRoaXMgd2lsbCBpbmNsdWRlCi0gICAqIG5hbWVzIHN1Y2ggYXMgI3RleHQgb3IgI2RvY3VtZW50LgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSB0aGUgaWQgb2YgdGhlIG5vZGUuCi0gICAqIEByZXR1cm4gU3RyaW5nIE5hbWUgb2YgdGhpcyBub2RlLCB3aGljaCBtYXkgYmUgYW4gZW1wdHkgc3RyaW5nLgotICAgKiAlUkVWSUVXJSBEb2N1bWVudCB3aGVuIGVtcHR5IHN0cmluZyBpcyBwb3NzaWJsZS4uLgotICAgKiAlUkVWSUVXLUNPTU1FTlQlIEl0IHNob3VsZCBuZXZlciBiZSBlbXB0eSwgc2hvdWxkIGl0PwotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXROb2RlTmFtZShpbnQgbm9kZUhhbmRsZSkKLSAgewotCi0gICAgaW50IG5vZGVJRCA9IG1ha2VOb2RlSWRlbnRpdHkobm9kZUhhbmRsZSk7Ci0gICAgaW50IGVUeXBlID0gX2V4cHR5cGUyKG5vZGVJRCk7Ci0KLSAgICBmaW5hbCBFeHRlbmRlZFR5cGUgZXh0VHlwZSA9IG1fZXh0ZW5kZWRUeXBlc1tlVHlwZV07Ci0gICAgaWYgKGV4dFR5cGUuZ2V0TmFtZXNwYWNlKCkubGVuZ3RoKCkgPT0gMCkKLSAgICB7Ci0gICAgICBpbnQgdHlwZSA9IGV4dFR5cGUuZ2V0Tm9kZVR5cGUoKTsKLQotICAgICAgU3RyaW5nIGxvY2FsTmFtZSA9IGV4dFR5cGUuZ2V0TG9jYWxOYW1lKCk7Ci0gICAgICBpZiAodHlwZSA9PSBEVE0uTkFNRVNQQUNFX05PREUpCi0gICAgICB7Ci0gICAgICAgIGlmIChsb2NhbE5hbWUubGVuZ3RoKCkgPT0gMCkKLSAgICAgICAgICByZXR1cm4gInhtbG5zIjsKLSAgICAgICAgZWxzZQotICAgICAgICAgIHJldHVybiAieG1sbnM6IiArIGxvY2FsTmFtZTsKLSAgICAgIH0KLSAgICAgIGVsc2UgaWYgKHR5cGUgPT0gRFRNLlBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERSkKLSAgICAgIHsKLSAgICAgICAgaW50IGRhdGFJbmRleCA9IF9kYXRhT3JRTmFtZShub2RlSUQpOwotICAgICAgICBkYXRhSW5kZXggPSBtX2RhdGEuZWxlbWVudEF0KC1kYXRhSW5kZXgpOwotICAgICAgICByZXR1cm4gbV92YWx1ZXNPclByZWZpeGVzLmluZGV4VG9TdHJpbmcoZGF0YUluZGV4KTsKLSAgICAgIH0KLSAgICAgIGVsc2UgaWYgKGxvY2FsTmFtZS5sZW5ndGgoKSA9PSAwKQotICAgICAgewotICAgICAgICByZXR1cm4gZ2V0Rml4ZWROYW1lcyh0eXBlKTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgICAgcmV0dXJuIGxvY2FsTmFtZTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIGludCBxbmFtZUluZGV4ID0gbV9kYXRhT3JRTmFtZS5lbGVtZW50QXQobm9kZUlEKTsKLQotICAgICAgaWYgKHFuYW1lSW5kZXggPT0gMCkKLSAgICAgICAgcmV0dXJuIGV4dFR5cGUuZ2V0TG9jYWxOYW1lKCk7Ci0KLSAgICAgIGlmIChxbmFtZUluZGV4IDwgMCkKLSAgICAgIHsKLSAgICAgICAgcW5hbWVJbmRleCA9IC1xbmFtZUluZGV4OwotICAgICAgICBxbmFtZUluZGV4ID0gbV9kYXRhLmVsZW1lbnRBdChxbmFtZUluZGV4KTsKLSAgICAgIH0KLQotICAgICAgcmV0dXJuIG1fdmFsdWVzT3JQcmVmaXhlcy5pbmRleFRvU3RyaW5nKHFuYW1lSW5kZXgpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBPdmVycmlkZSBTQVgyRFRNLmdldFN0cmluZ1ZhbHVlKGludCkKLSAgICogPHA+Ci0gICAqIFRoaXMgbWV0aG9kIGlzIG9ubHkgdXNlZCBieSBYYWxhbi1KIEludGVycHJldGl2ZS4gSXQgaXMgbm90IHVzZWQgYnkgWFNMVEMuCi0gICAqIDxwPgotICAgKiBJZiB0aGUgY2FsbGVyIHN1cHBsaWVzIGFuIFhNTFN0cmluZ0ZhY3RvcnksIHRoZSBnZXRTdHJpbmdWYWx1ZSgpIGludGVyZmFjZQotICAgKiBpbiBTQVgyRFRNIHdpbGwgYmUgY2FsbGVkLiBPdGhlcndpc2UganVzdCBjYWxscyBnZXRTdHJpbmdWYWx1ZVgoKSBhbmQKLSAgICogd3JhcHMgdGhlIHJldHVybmVkIFN0cmluZyBpbiBhbiBYTUxTdHJpbmcuCi0gICAqCi0gICAqIEdldCB0aGUgc3RyaW5nLXZhbHVlIG9mIGEgbm9kZSBhcyBhIFN0cmluZyBvYmplY3QKLSAgICogKHNlZSBodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aCNkYXRhLW1vZGVsCi0gICAqIGZvciB0aGUgZGVmaW5pdGlvbiBvZiBhIG5vZGUncyBzdHJpbmctdmFsdWUpLgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBUaGUgbm9kZSBJRC4KLSAgICoKLSAgICogQHJldHVybiBBIHN0cmluZyBvYmplY3QgdGhhdCByZXByZXNlbnRzIHRoZSBzdHJpbmctdmFsdWUgb2YgdGhlIGdpdmVuIG5vZGUuCi0gICAqLwotICBwdWJsaWMgWE1MU3RyaW5nIGdldFN0cmluZ1ZhbHVlKGludCBub2RlSGFuZGxlKQotICB7Ci0gICAgaW50IGlkZW50aXR5ID0gbWFrZU5vZGVJZGVudGl0eShub2RlSGFuZGxlKTsKLSAgICBpZiAoaWRlbnRpdHkgPT0gRFRNLk5VTEwpCi0gICAgICByZXR1cm4gRU1QVFlfWE1MX1NUUjsKLQotICAgIGludCB0eXBlPSBfdHlwZTIoaWRlbnRpdHkpOwotCi0gICAgaWYgKHR5cGUgPT0gRFRNLkVMRU1FTlRfTk9ERSB8fCB0eXBlID09IERUTS5ET0NVTUVOVF9OT0RFKQotICAgIHsKLSAgICAgIGludCBzdGFydE5vZGUgPSBpZGVudGl0eTsKLSAgICAgIGlkZW50aXR5ID0gX2ZpcnN0Y2gyKGlkZW50aXR5KTsKLSAgICAgIGlmIChEVE0uTlVMTCAhPSBpZGVudGl0eSkKLSAgICAgIHsKLSAgICAgICAgaW50IG9mZnNldCA9IC0xOwotICAgICAgICBpbnQgbGVuZ3RoID0gMDsKLQotICAgICAgICBkbwotICAgICAgICB7Ci0gICAgICAgICAgdHlwZSA9IF9leHB0eXBlMihpZGVudGl0eSk7Ci0KLSAgICAgICAgICBpZiAodHlwZSA9PSBEVE0uVEVYVF9OT0RFIHx8IHR5cGUgPT0gRFRNLkNEQVRBX1NFQ1RJT05fTk9ERSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBpbnQgZGF0YUluZGV4ID0gbV9kYXRhT3JRTmFtZS5lbGVtZW50QXQoaWRlbnRpdHkpOwotICAgICAgICAgICAgaWYgKGRhdGFJbmRleCA+PSAwKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICBpZiAoLTEgPT0gb2Zmc2V0KQotICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgb2Zmc2V0ID0gZGF0YUluZGV4ID4+PiBURVhUX0xFTkdUSF9CSVRTOwotICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgbGVuZ3RoICs9IGRhdGFJbmRleCAmIFRFWFRfTEVOR1RIX01BWDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgaWYgKC0xID09IG9mZnNldCkKLSAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIG9mZnNldCA9IG1fZGF0YS5lbGVtZW50QXQoLWRhdGFJbmRleCk7Ci0gICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICBsZW5ndGggKz0gbV9kYXRhLmVsZW1lbnRBdCgtZGF0YUluZGV4ICsgMSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgfQotCi0gICAgICAgICAgaWRlbnRpdHkrKzsKLSAgICAgICAgfSB3aGlsZSAoX3BhcmVudDIoaWRlbnRpdHkpID49IHN0YXJ0Tm9kZSk7Ci0KLSAgICAgICAgaWYgKGxlbmd0aCA+IDApCi0gICAgICAgIHsKLSAgICAgICAgICBpZiAobV94c3RyZiAhPSBudWxsKQotICAgICAgICAgICAgcmV0dXJuIG1feHN0cmYubmV3c3RyKG1fY2hhcnMsIG9mZnNldCwgbGVuZ3RoKTsKLSAgICAgICAgICBlbHNlCi0gICAgICAgICAgICByZXR1cm4gbmV3IFhNTFN0cmluZ0RlZmF1bHQobV9jaGFycy5nZXRTdHJpbmcob2Zmc2V0LCBsZW5ndGgpKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgICAgcmV0dXJuIEVNUFRZX1hNTF9TVFI7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICAgIHJldHVybiBFTVBUWV9YTUxfU1RSOwotICAgIH0KLSAgICBlbHNlIGlmIChEVE0uVEVYVF9OT0RFID09IHR5cGUgfHwgRFRNLkNEQVRBX1NFQ1RJT05fTk9ERSA9PSB0eXBlKQotICAgIHsKLSAgICAgIGludCBkYXRhSW5kZXggPSBtX2RhdGFPclFOYW1lLmVsZW1lbnRBdChpZGVudGl0eSk7Ci0gICAgICBpZiAoZGF0YUluZGV4ID49IDApCi0gICAgICB7Ci0gICAgICAgIGlmIChtX3hzdHJmICE9IG51bGwpCi0gICAgICAgICAgcmV0dXJuIG1feHN0cmYubmV3c3RyKG1fY2hhcnMsIGRhdGFJbmRleCA+Pj4gVEVYVF9MRU5HVEhfQklUUywKLSAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhSW5kZXggJiBURVhUX0xFTkdUSF9NQVgpOwotICAgICAgICBlbHNlCi0gICAgICAgICAgcmV0dXJuIG5ldyBYTUxTdHJpbmdEZWZhdWx0KG1fY2hhcnMuZ2V0U3RyaW5nKGRhdGFJbmRleCA+Pj4gVEVYVF9MRU5HVEhfQklUUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YUluZGV4ICYgVEVYVF9MRU5HVEhfTUFYKSk7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIGlmIChtX3hzdHJmICE9IG51bGwpCi0gICAgICAgICAgcmV0dXJuIG1feHN0cmYubmV3c3RyKG1fY2hhcnMsIG1fZGF0YS5lbGVtZW50QXQoLWRhdGFJbmRleCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fZGF0YS5lbGVtZW50QXQoLWRhdGFJbmRleCsxKSk7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICByZXR1cm4gbmV3IFhNTFN0cmluZ0RlZmF1bHQobV9jaGFycy5nZXRTdHJpbmcobV9kYXRhLmVsZW1lbnRBdCgtZGF0YUluZGV4KSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbV9kYXRhLmVsZW1lbnRBdCgtZGF0YUluZGV4KzEpKSk7Ci0gICAgICB9Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBpbnQgZGF0YUluZGV4ID0gbV9kYXRhT3JRTmFtZS5lbGVtZW50QXQoaWRlbnRpdHkpOwotCi0gICAgICBpZiAoZGF0YUluZGV4IDwgMCkKLSAgICAgIHsKLSAgICAgICAgZGF0YUluZGV4ID0gLWRhdGFJbmRleDsKLSAgICAgICAgZGF0YUluZGV4ID0gbV9kYXRhLmVsZW1lbnRBdChkYXRhSW5kZXggKyAxKTsKLSAgICAgIH0KLQotICAgICAgaWYgKG1feHN0cmYgIT0gbnVsbCkKLSAgICAgICAgcmV0dXJuIG1feHN0cmYubmV3c3RyKChTdHJpbmcpbV92YWx1ZXMuZWxlbWVudEF0KGRhdGFJbmRleCkpOwotICAgICAgZWxzZQotICAgICAgICByZXR1cm4gbmV3IFhNTFN0cmluZ0RlZmF1bHQoKFN0cmluZyltX3ZhbHVlcy5lbGVtZW50QXQoZGF0YUluZGV4KSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFRoZSBvcHRpbWl6ZWQgdmVyc2lvbiBvZiBTQVgyRFRNLmdldFN0cmluZ1ZhbHVlKGludCkuCi0gICAqIDxwPgotICAgKiAlT1BUJSBUaGlzIGlzIG9uZSBvZiB0aGUgbW9zdCBvZnRlbiB1c2VkIGludGVyZmFjZXMuIFBlcmZvcm1hbmNlIGlzCi0gICAqIGNyaXRpY2FsIGhlcmUuIFRoaXMgb25lIGlzIGRpZmZlcmVudCBmcm9tIFNBWDJEVE0uZ2V0U3RyaW5nVmFsdWUoaW50KSBpbgotICAgKiB0aGF0IGl0IHJldHVybnMgYSBTdHJpbmcgaW5zdGVhZCBvZiBhIFhNTFN0cmluZy4KLSAgICoKLSAgICogR2V0IHRoZSBzdHJpbmctIHZhbHVlIG9mIGEgbm9kZSBhcyBhIFN0cmluZyBvYmplY3QgKHNlZSBodHRwOiAvL3d3dy4gdzMuCi0gICAqIG9yZy9UUi94cGF0aCNkYXRhLSBtb2RlbCBmb3IgdGhlIGRlZmluaXRpb24gb2YgYSBub2RlJ3Mgc3RyaW5nLSB2YWx1ZSkuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIFRoZSBub2RlIElELgotICAgKgotICAgKiBAcmV0dXJuIEEgc3RyaW5nIG9iamVjdCB0aGF0IHJlcHJlc2VudHMgdGhlIHN0cmluZy12YWx1ZSBvZiB0aGUgZ2l2ZW4gbm9kZS4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBTdHJpbmcgZ2V0U3RyaW5nVmFsdWVYKGZpbmFsIGludCBub2RlSGFuZGxlKQotICB7Ci0gICAgaW50IGlkZW50aXR5ID0gbWFrZU5vZGVJZGVudGl0eShub2RlSGFuZGxlKTsKLSAgICBpZiAoaWRlbnRpdHkgPT0gRFRNLk5VTEwpCi0gICAgICByZXR1cm4gRU1QVFlfU1RSOwotCi0gICAgaW50IHR5cGU9IF90eXBlMihpZGVudGl0eSk7Ci0KLSAgICBpZiAodHlwZSA9PSBEVE0uRUxFTUVOVF9OT0RFIHx8IHR5cGUgPT0gRFRNLkRPQ1VNRU5UX05PREUpCi0gICAgewotICAgICAgaW50IHN0YXJ0Tm9kZSA9IGlkZW50aXR5OwotICAgICAgaWRlbnRpdHkgPSBfZmlyc3RjaDIoaWRlbnRpdHkpOwotICAgICAgaWYgKERUTS5OVUxMICE9IGlkZW50aXR5KQotICAgICAgewotICAgICAgICBpbnQgb2Zmc2V0ID0gLTE7Ci0gICAgICAgIGludCBsZW5ndGggPSAwOwotCi0gICAgICAgIGRvCi0gICAgICAgIHsKLSAgICAgICAgICB0eXBlID0gX2V4cHR5cGUyKGlkZW50aXR5KTsKLQotICAgICAgICAgIGlmICh0eXBlID09IERUTS5URVhUX05PREUgfHwgdHlwZSA9PSBEVE0uQ0RBVEFfU0VDVElPTl9OT0RFKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGludCBkYXRhSW5kZXggPSBtX2RhdGFPclFOYW1lLmVsZW1lbnRBdChpZGVudGl0eSk7Ci0gICAgICAgICAgICBpZiAoZGF0YUluZGV4ID49IDApCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIGlmICgtMSA9PSBvZmZzZXQpCi0gICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBvZmZzZXQgPSBkYXRhSW5kZXggPj4+IFRFWFRfTEVOR1RIX0JJVFM7Ci0gICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICBsZW5ndGggKz0gZGF0YUluZGV4ICYgVEVYVF9MRU5HVEhfTUFYOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgewotICAgICAgICAgICAgICBpZiAoLTEgPT0gb2Zmc2V0KQotICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgb2Zmc2V0ID0gbV9kYXRhLmVsZW1lbnRBdCgtZGF0YUluZGV4KTsKLSAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgIGxlbmd0aCArPSBtX2RhdGEuZWxlbWVudEF0KC1kYXRhSW5kZXggKyAxKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICB9Ci0KLSAgICAgICAgICBpZGVudGl0eSsrOwotICAgICAgICB9IHdoaWxlIChfcGFyZW50MihpZGVudGl0eSkgPj0gc3RhcnROb2RlKTsKLQotICAgICAgICBpZiAobGVuZ3RoID4gMCkKLSAgICAgICAgewotICAgICAgICAgIHJldHVybiBtX2NoYXJzLmdldFN0cmluZyhvZmZzZXQsIGxlbmd0aCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICAgIHJldHVybiBFTVBUWV9TVFI7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICAgIHJldHVybiBFTVBUWV9TVFI7Ci0gICAgfQotICAgIGVsc2UgaWYgKERUTS5URVhUX05PREUgPT0gdHlwZSB8fCBEVE0uQ0RBVEFfU0VDVElPTl9OT0RFID09IHR5cGUpCi0gICAgewotICAgICAgaW50IGRhdGFJbmRleCA9IG1fZGF0YU9yUU5hbWUuZWxlbWVudEF0KGlkZW50aXR5KTsKLSAgICAgIGlmIChkYXRhSW5kZXggPj0gMCkKLSAgICAgIHsKLSAgICAgICAgcmV0dXJuIG1fY2hhcnMuZ2V0U3RyaW5nKGRhdGFJbmRleCA+Pj4gVEVYVF9MRU5HVEhfQklUUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhSW5kZXggJiBURVhUX0xFTkdUSF9NQVgpOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICByZXR1cm4gbV9jaGFycy5nZXRTdHJpbmcobV9kYXRhLmVsZW1lbnRBdCgtZGF0YUluZGV4KSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX2RhdGEuZWxlbWVudEF0KC1kYXRhSW5kZXgrMSkpOwotICAgICAgfQotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgaW50IGRhdGFJbmRleCA9IG1fZGF0YU9yUU5hbWUuZWxlbWVudEF0KGlkZW50aXR5KTsKLQotICAgICAgaWYgKGRhdGFJbmRleCA8IDApCi0gICAgICB7Ci0gICAgICAgIGRhdGFJbmRleCA9IC1kYXRhSW5kZXg7Ci0gICAgICAgIGRhdGFJbmRleCA9IG1fZGF0YS5lbGVtZW50QXQoZGF0YUluZGV4ICsgMSk7Ci0gICAgICB9Ci0KLSAgICAgIHJldHVybiAoU3RyaW5nKW1fdmFsdWVzLmVsZW1lbnRBdChkYXRhSW5kZXgpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBzdHJpbmcgdmFsdWUgb2YgdGhlIGVudGlyZSB0cmVlCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFN0cmluZ1ZhbHVlKCkKLSAgewotICAgIGludCBjaGlsZCA9IF9maXJzdGNoMihST09UTk9ERSk7Ci0gICAgaWYgKGNoaWxkID09IERUTS5OVUxMKSByZXR1cm4gRU1QVFlfU1RSOwotCi0gICAgLy8gb3B0aW1pemF0aW9uOiBvbmx5IGNyZWF0ZSBTdHJpbmdCdWZmZXIgaWYgPiAxIGNoaWxkCi0gICAgaWYgKChfZXhwdHlwZTIoY2hpbGQpID09IERUTS5URVhUX05PREUpICYmIChfbmV4dHNpYjIoY2hpbGQpID09IERUTS5OVUxMKSkKLSAgICB7Ci0gICAgICBpbnQgZGF0YUluZGV4ID0gbV9kYXRhT3JRTmFtZS5lbGVtZW50QXQoY2hpbGQpOwotICAgICAgaWYgKGRhdGFJbmRleCA+PSAwKQotICAgICAgICByZXR1cm4gbV9jaGFycy5nZXRTdHJpbmcoZGF0YUluZGV4ID4+PiBURVhUX0xFTkdUSF9CSVRTLCBkYXRhSW5kZXggJiBURVhUX0xFTkdUSF9NQVgpOwotICAgICAgZWxzZQotICAgICAgICByZXR1cm4gbV9jaGFycy5nZXRTdHJpbmcobV9kYXRhLmVsZW1lbnRBdCgtZGF0YUluZGV4KSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX2RhdGEuZWxlbWVudEF0KC1kYXRhSW5kZXggKyAxKSk7Ci0gICAgfQotICAgIGVsc2UKLSAgICAgIHJldHVybiBnZXRTdHJpbmdWYWx1ZVgoZ2V0RG9jdW1lbnQoKSk7Ci0KLSAgfQotCi0gIC8qKgotICAgKiBUaGUgb3B0aW1pemVkIHZlcnNpb24gb2YgU0FYMkRUTS5kaXNwYXRjaENoYXJhY3RlcnNFdmVudHMoaW50LCBDb250ZW50SGFuZGxlciwgYm9vbGVhbikuCi0gICAqIDxwPgotICAgKiBEaXJlY3RseSBjYWxsIHRoZQotICAgKiBjaGFyYWN0ZXJzIG1ldGhvZCBvbiB0aGUgcGFzc2VkIENvbnRlbnRIYW5kbGVyIGZvciB0aGUKLSAgICogc3RyaW5nLXZhbHVlIG9mIHRoZSBnaXZlbiBub2RlIChzZWUgaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGgjZGF0YS1tb2RlbAotICAgKiBmb3IgdGhlIGRlZmluaXRpb24gb2YgYSBub2RlJ3Mgc3RyaW5nLXZhbHVlKS4gTXVsdGlwbGUgY2FsbHMgdG8gdGhlCi0gICAqIENvbnRlbnRIYW5kbGVyJ3MgY2hhcmFjdGVycyBtZXRob2RzIG1heSB3ZWxsIG9jY3VyIGZvciBhIHNpbmdsZSBjYWxsIHRvCi0gICAqIHRoaXMgbWV0aG9kLgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBUaGUgbm9kZSBJRC4KLSAgICogQHBhcmFtIGNoIEEgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGEgQ29udGVudEhhbmRsZXIuCi0gICAqIEBwYXJhbSBub3JtYWxpemUgdHJ1ZSBpZiB0aGUgY29udGVudCBzaG91bGQgYmUgbm9ybWFsaXplZCBhY2NvcmRpbmcgdG8KLSAgICogdGhlIHJ1bGVzIGZvciB0aGUgWFBhdGgKLSAgICogPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGgjZnVuY3Rpb24tbm9ybWFsaXplLXNwYWNlIj5ub3JtYWxpemUtc3BhY2U8L2E+Ci0gICAqIGZ1bmN0aW9uLgotICAgKgotICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgZGlzcGF0Y2hDaGFyYWN0ZXJzRXZlbnRzKGludCBub2RlSGFuZGxlLCBDb250ZW50SGFuZGxlciBjaCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gbm9ybWFsaXplKQotICAgICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotCi0gICAgaW50IGlkZW50aXR5ID0gbWFrZU5vZGVJZGVudGl0eShub2RlSGFuZGxlKTsKLQotICAgIGlmIChpZGVudGl0eSA9PSBEVE0uTlVMTCkKLSAgICAgIHJldHVybjsKLQotICAgIGludCB0eXBlID0gX3R5cGUyKGlkZW50aXR5KTsKLQotICAgIGlmICh0eXBlID09IERUTS5FTEVNRU5UX05PREUgfHwgdHlwZSA9PSBEVE0uRE9DVU1FTlRfTk9ERSkKLSAgICB7Ci0gICAgICBpbnQgc3RhcnROb2RlID0gaWRlbnRpdHk7Ci0gICAgICBpZGVudGl0eSA9IF9maXJzdGNoMihpZGVudGl0eSk7Ci0gICAgICBpZiAoRFRNLk5VTEwgIT0gaWRlbnRpdHkpCi0gICAgICB7Ci0gICAgICAgIGludCBvZmZzZXQgPSAtMTsKLSAgICAgICAgaW50IGxlbmd0aCA9IDA7Ci0KLSAgICAgICAgZG8KLSAgICAgICAgewotICAgICAgICAgIHR5cGUgPSBfZXhwdHlwZTIoaWRlbnRpdHkpOwotCi0gICAgICAgICAgaWYgKHR5cGUgPT0gRFRNLlRFWFRfTk9ERSB8fCB0eXBlID09IERUTS5DREFUQV9TRUNUSU9OX05PREUpCi0gICAgICAgICAgewotICAgICAgICAgICAgaW50IGRhdGFJbmRleCA9IG1fZGF0YU9yUU5hbWUuZWxlbWVudEF0KGlkZW50aXR5KTsKLQotICAgICAgICAgICAgaWYgKGRhdGFJbmRleCA+PSAwKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICBpZiAoLTEgPT0gb2Zmc2V0KQotICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgb2Zmc2V0ID0gZGF0YUluZGV4ID4+PiBURVhUX0xFTkdUSF9CSVRTOwotICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgbGVuZ3RoICs9IGRhdGFJbmRleCAmIFRFWFRfTEVOR1RIX01BWDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgaWYgKC0xID09IG9mZnNldCkKLSAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIG9mZnNldCA9IG1fZGF0YS5lbGVtZW50QXQoLWRhdGFJbmRleCk7Ci0gICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICBsZW5ndGggKz0gbV9kYXRhLmVsZW1lbnRBdCgtZGF0YUluZGV4ICsgMSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgfQotCi0gICAgICAgICAgaWRlbnRpdHkrKzsKLSAgICAgICAgfSB3aGlsZSAoX3BhcmVudDIoaWRlbnRpdHkpID49IHN0YXJ0Tm9kZSk7Ci0KLSAgICAgICAgaWYgKGxlbmd0aCA+IDApCi0gICAgICAgIHsKLSAgICAgICAgICBpZihub3JtYWxpemUpCi0gICAgICAgICAgICBtX2NoYXJzLnNlbmROb3JtYWxpemVkU0FYY2hhcmFjdGVycyhjaCwgb2Zmc2V0LCBsZW5ndGgpOwotICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgIG1fY2hhcnMuc2VuZFNBWGNoYXJhY3RlcnMoY2gsIG9mZnNldCwgbGVuZ3RoKTsKLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLSAgICBlbHNlIGlmIChEVE0uVEVYVF9OT0RFID09IHR5cGUgfHwgRFRNLkNEQVRBX1NFQ1RJT05fTk9ERSA9PSB0eXBlKQotICAgIHsKLSAgICAgIGludCBkYXRhSW5kZXggPSBtX2RhdGFPclFOYW1lLmVsZW1lbnRBdChpZGVudGl0eSk7Ci0KLSAgICAgIGlmIChkYXRhSW5kZXggPj0gMCkKLSAgICAgIHsKLSAgICAgICAgaWYgKG5vcm1hbGl6ZSkKLSAgICAgICAgICBtX2NoYXJzLnNlbmROb3JtYWxpemVkU0FYY2hhcmFjdGVycyhjaCwgZGF0YUluZGV4ID4+PiBURVhUX0xFTkdUSF9CSVRTLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFJbmRleCAmIFRFWFRfTEVOR1RIX01BWCk7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICBtX2NoYXJzLnNlbmRTQVhjaGFyYWN0ZXJzKGNoLCBkYXRhSW5kZXggPj4+IFRFWFRfTEVOR1RIX0JJVFMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhSW5kZXggJiBURVhUX0xFTkdUSF9NQVgpOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBpZiAobm9ybWFsaXplKQotICAgICAgICAgIG1fY2hhcnMuc2VuZE5vcm1hbGl6ZWRTQVhjaGFyYWN0ZXJzKGNoLCBtX2RhdGEuZWxlbWVudEF0KC1kYXRhSW5kZXgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fZGF0YS5lbGVtZW50QXQoLWRhdGFJbmRleCsxKSk7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICBtX2NoYXJzLnNlbmRTQVhjaGFyYWN0ZXJzKGNoLCBtX2RhdGEuZWxlbWVudEF0KC1kYXRhSW5kZXgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbV9kYXRhLmVsZW1lbnRBdCgtZGF0YUluZGV4KzEpKTsKLSAgICAgIH0KLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIGludCBkYXRhSW5kZXggPSBtX2RhdGFPclFOYW1lLmVsZW1lbnRBdChpZGVudGl0eSk7Ci0KLSAgICAgIGlmIChkYXRhSW5kZXggPCAwKQotICAgICAgewotICAgICAgICBkYXRhSW5kZXggPSAtZGF0YUluZGV4OwotICAgICAgICBkYXRhSW5kZXggPSBtX2RhdGEuZWxlbWVudEF0KGRhdGFJbmRleCArIDEpOwotICAgICAgfQotCi0gICAgICBTdHJpbmcgc3RyID0gKFN0cmluZyltX3ZhbHVlcy5lbGVtZW50QXQoZGF0YUluZGV4KTsKLQotICAgICAgaWYobm9ybWFsaXplKQotICAgICAgICBGYXN0U3RyaW5nQnVmZmVyLnNlbmROb3JtYWxpemVkU0FYY2hhcmFjdGVycyhzdHIudG9DaGFyQXJyYXkoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgc3RyLmxlbmd0aCgpLCBjaCk7Ci0gICAgICBlbHNlCi0gICAgICAgIGNoLmNoYXJhY3RlcnMoc3RyLnRvQ2hhckFycmF5KCksIDAsIHN0ci5sZW5ndGgoKSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIHJldHVybiBpdHMgbm9kZSB2YWx1ZS4gVGhpcyBpcyBtb3N0bHkKLSAgICogYXMgZGVmaW5lZCBieSB0aGUgRE9NLCBidXQgbWF5IGlnbm9yZSBzb21lIGNvbnZlbmllbmNlcy4KLSAgICogPHA+Ci0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIFRoZSBub2RlIGlkLgotICAgKiBAcmV0dXJuIFN0cmluZyBWYWx1ZSBvZiB0aGlzIG5vZGUsIG9yIG51bGwgaWYgbm90Ci0gICAqIG1lYW5pbmdmdWwgZm9yIHRoaXMgbm9kZSB0eXBlLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXROb2RlVmFsdWUoaW50IG5vZGVIYW5kbGUpCi0gIHsKLQotICAgIGludCBpZGVudGl0eSA9IG1ha2VOb2RlSWRlbnRpdHkobm9kZUhhbmRsZSk7Ci0gICAgaW50IHR5cGUgPSBfdHlwZTIoaWRlbnRpdHkpOwotCi0gICAgaWYgKHR5cGUgPT0gRFRNLlRFWFRfTk9ERSB8fCB0eXBlID09IERUTS5DREFUQV9TRUNUSU9OX05PREUpCi0gICAgewotICAgICAgaW50IGRhdGFJbmRleCA9IF9kYXRhT3JRTmFtZShpZGVudGl0eSk7Ci0gICAgICBpZiAoZGF0YUluZGV4ID4gMCkKLSAgICAgIHsKLSAgICAgICAgcmV0dXJuIG1fY2hhcnMuZ2V0U3RyaW5nKGRhdGFJbmRleCA+Pj4gVEVYVF9MRU5HVEhfQklUUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhSW5kZXggJiBURVhUX0xFTkdUSF9NQVgpOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICByZXR1cm4gbV9jaGFycy5nZXRTdHJpbmcobV9kYXRhLmVsZW1lbnRBdCgtZGF0YUluZGV4KSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX2RhdGEuZWxlbWVudEF0KC1kYXRhSW5kZXgrMSkpOwotICAgICAgfQotICAgIH0KLSAgICBlbHNlIGlmIChEVE0uRUxFTUVOVF9OT0RFID09IHR5cGUgfHwgRFRNLkRPQ1VNRU5UX0ZSQUdNRU5UX05PREUgPT0gdHlwZQotICAgICAgICAgICAgIHx8IERUTS5ET0NVTUVOVF9OT0RFID09IHR5cGUpCi0gICAgewotICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBpbnQgZGF0YUluZGV4ID0gbV9kYXRhT3JRTmFtZS5lbGVtZW50QXQoaWRlbnRpdHkpOwotCi0gICAgICBpZiAoZGF0YUluZGV4IDwgMCkKLSAgICAgIHsKLSAgICAgICAgZGF0YUluZGV4ID0gLWRhdGFJbmRleDsKLSAgICAgICAgZGF0YUluZGV4ID0gbV9kYXRhLmVsZW1lbnRBdChkYXRhSW5kZXggKyAxKTsKLSAgICAgIH0KLQotICAgICAgcmV0dXJuIChTdHJpbmcpbV92YWx1ZXMuZWxlbWVudEF0KGRhdGFJbmRleCk7Ci0gICAgfQotICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb3B5IHRoZSBTdHJpbmcgdmFsdWUgb2YgYSBUZXh0IG5vZGUgdG8gYSBTZXJpYWxpemF0aW9uSGFuZGxlcgotICAgICAqLwotICAgIHByb3RlY3RlZCBmaW5hbCB2b2lkIGNvcHlUZXh0Tm9kZShmaW5hbCBpbnQgbm9kZUlELCBTZXJpYWxpemF0aW9uSGFuZGxlciBoYW5kbGVyKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAobm9kZUlEICE9IERUTS5OVUxMKSB7Ci0gICAgICAgICAgICBpbnQgZGF0YUluZGV4ID0gbV9kYXRhT3JRTmFtZS5lbGVtZW50QXQobm9kZUlEKTsKLSAgICAgICAgICAgIGlmIChkYXRhSW5kZXggPj0gMCkgewotICAgICAgICAgICAgICAgIG1fY2hhcnMuc2VuZFNBWGNoYXJhY3RlcnMoaGFuZGxlciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFJbmRleCA+Pj4gVEVYVF9MRU5HVEhfQklUUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFJbmRleCAmIFRFWFRfTEVOR1RIX01BWCk7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIG1fY2hhcnMuc2VuZFNBWGNoYXJhY3RlcnMoaGFuZGxlciwgbV9kYXRhLmVsZW1lbnRBdCgtZGF0YUluZGV4KSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fZGF0YS5lbGVtZW50QXQoLWRhdGFJbmRleCsxKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb3B5IGFuIEVsZW1lbnQgbm9kZSB0byBhIFNlcmlhbGl6YXRpb25IYW5kbGVyLgotICAgICAqCi0gICAgICogQHBhcmFtIG5vZGVJRCBUaGUgbm9kZSBpZGVudGl0eQotICAgICAqIEBwYXJhbSBleHB0eXBlIFRoZSBleHBhbmRlZCB0eXBlIG9mIHRoZSBFbGVtZW50IG5vZGUKLSAgICAgKiBAcGFyYW0gaGFuZGxlciBUaGUgU2VyaWFsaXphdGlvbkhhbmRsZXIKLSAgICAgKiBAcmV0dXJuIFRoZSBxdWFsaWZpZWQgbmFtZSBvZiB0aGUgRWxlbWVudCBub2RlLgotICAgICAqLwotICAgIHByb3RlY3RlZCBmaW5hbCBTdHJpbmcgY29weUVsZW1lbnQoaW50IG5vZGVJRCwgaW50IGV4cHR5cGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU2VyaWFsaXphdGlvbkhhbmRsZXIgaGFuZGxlcikKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgZmluYWwgRXh0ZW5kZWRUeXBlIGV4dFR5cGUgPSBtX2V4dGVuZGVkVHlwZXNbZXhwdHlwZV07Ci0gICAgICAgIFN0cmluZyB1cmkgPSBleHRUeXBlLmdldE5hbWVzcGFjZSgpOwotICAgICAgICBTdHJpbmcgbmFtZSA9IGV4dFR5cGUuZ2V0TG9jYWxOYW1lKCk7Ci0KLSAgICAgICAgaWYgKHVyaS5sZW5ndGgoKSA9PSAwKSB7Ci0gICAgICAgICAgICBoYW5kbGVyLnN0YXJ0RWxlbWVudChuYW1lKTsKLSAgICAgICAgICAgIHJldHVybiBuYW1lOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgaW50IHFuYW1lSW5kZXggPSBtX2RhdGFPclFOYW1lLmVsZW1lbnRBdChub2RlSUQpOwotCi0gICAgICAgICAgICBpZiAocW5hbWVJbmRleCA9PSAwKSB7Ci0gICAgICAgICAgICAgICAgaGFuZGxlci5zdGFydEVsZW1lbnQobmFtZSk7Ci0gICAgICAgICAgICAgICAgaGFuZGxlci5uYW1lc3BhY2VBZnRlclN0YXJ0RWxlbWVudChFTVBUWV9TVFIsIHVyaSk7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIG5hbWU7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmIChxbmFtZUluZGV4IDwgMCkgewotICAgICAgICAgICAgICAgIHFuYW1lSW5kZXggPSAtcW5hbWVJbmRleDsKLSAgICAgICAgICAgICAgICBxbmFtZUluZGV4ID0gbV9kYXRhLmVsZW1lbnRBdChxbmFtZUluZGV4KTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgU3RyaW5nIHFOYW1lID0gbV92YWx1ZXNPclByZWZpeGVzLmluZGV4VG9TdHJpbmcocW5hbWVJbmRleCk7Ci0gICAgICAgICAgICBoYW5kbGVyLnN0YXJ0RWxlbWVudChxTmFtZSk7Ci0gICAgICAgICAgICBpbnQgcHJlZml4SW5kZXggPSBxTmFtZS5pbmRleE9mKCc6Jyk7Ci0gICAgICAgICAgICBTdHJpbmcgcHJlZml4OwotICAgICAgICAgICAgaWYgKHByZWZpeEluZGV4ID4gMCkgewotICAgICAgICAgICAgICAgIHByZWZpeCA9IHFOYW1lLnN1YnN0cmluZygwLCBwcmVmaXhJbmRleCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBwcmVmaXggPSBudWxsOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaGFuZGxlci5uYW1lc3BhY2VBZnRlclN0YXJ0RWxlbWVudChwcmVmaXgsIHVyaSk7Ci0gICAgICAgICAgICByZXR1cm4gcU5hbWU7Ci0gICAgICAgIH0KLQotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvcHkgIG5hbWVzcGFjZSBub2Rlcy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBub2RlSUQgVGhlIEVsZW1lbnQgbm9kZSBpZGVudGl0eQotICAgICAqIEBwYXJhbSBoYW5kbGVyIFRoZSBTZXJpYWxpemF0aW9uSGFuZGxlcgotICAgICAqIEBwYXJhbSBpblNjb3BlICB0cnVlIGlmIGFsbCBuYW1lc3BhY2VzIGluIHNjb3BlIHNob3VsZCBiZSBjb3BpZWQsCi0gICAgICogIGZhbHNlIGlmIG9ubHkgdGhlIG5hbWVzcGFjZSBkZWNsYXJhdGlvbnMgc2hvdWxkIGJlIGNvcGllZC4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgZmluYWwgdm9pZCBjb3B5TlMoZmluYWwgaW50IG5vZGVJRCwgU2VyaWFsaXphdGlvbkhhbmRsZXIgaGFuZGxlciwgYm9vbGVhbiBpblNjb3BlKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICAvLyAlT1BUJSBPcHRpbWl6YXRpb24gZm9yIGRvY3VtZW50cyB3aGljaCBkb2VzIG5vdCBoYXZlIGFueSBleHBsaWNpdAotICAgICAgICAvLyBuYW1lc3BhY2Ugbm9kZXMuIEZvciB0aGVzZSBkb2N1bWVudHMsIHRoZXJlIGlzIGFuIGltcGxpY2l0Ci0gICAgICAgIC8vIG5hbWVzcGFjZSBub2RlICh4bWxuczp4bWw9Imh0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZSIpCi0gICAgICAgIC8vIGRlY2xhcmVkIG9uIHRoZSByb290IGVsZW1lbnQgbm9kZS4gSW4gdGhpcyBjYXNlLCB0aGVyZSBpcyBubwotICAgICAgICAvLyBuZWVkIHRvIGRvIG5hbWVzcGFjZSBjb3B5aW5nLiBXZSBjYW4gc2FmZWx5IHJldHVybiB3aXRob3V0Ci0gICAgICAgIC8vIGRvaW5nIGFueXRoaW5nLgotICAgICAgICBpZiAobV9uYW1lc3BhY2VEZWNsU2V0RWxlbWVudHMgIT0gbnVsbCAmJgotICAgICAgICAgICAgbV9uYW1lc3BhY2VEZWNsU2V0RWxlbWVudHMuc2l6ZSgpID09IDEgJiYKLSAgICAgICAgICAgIG1fbmFtZXNwYWNlRGVjbFNldHMgIT0gbnVsbCAmJgotICAgICAgICAgICAgKChTdWJhbGxvY2F0ZWRJbnRWZWN0b3IpbV9uYW1lc3BhY2VEZWNsU2V0cy5lbGVtZW50QXQoMCkpCi0gICAgICAgICAgICAuc2l6ZSgpID09IDEpCi0gICAgICAgICAgICByZXR1cm47Ci0KLSAgICAgICAgU3ViYWxsb2NhdGVkSW50VmVjdG9yIG5zQ29udGV4dCA9IG51bGw7Ci0gICAgICAgIGludCBuZXh0TlNOb2RlOwotCi0gICAgICAgIC8vIEZpbmQgdGhlIGZpcnN0IG5hbWVzcGFjZSBub2RlCi0gICAgICAgIGlmIChpblNjb3BlKSB7Ci0gICAgICAgICAgICBuc0NvbnRleHQgPSBmaW5kTmFtZXNwYWNlQ29udGV4dChub2RlSUQpOwotICAgICAgICAgICAgaWYgKG5zQ29udGV4dCA9PSBudWxsIHx8IG5zQ29udGV4dC5zaXplKCkgPCAxKQotICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICBuZXh0TlNOb2RlID0gbWFrZU5vZGVJZGVudGl0eShuc0NvbnRleHQuZWxlbWVudEF0KDApKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgICAgICBuZXh0TlNOb2RlID0gZ2V0TmV4dE5hbWVzcGFjZU5vZGUyKG5vZGVJRCk7Ci0KLSAgICAgICAgaW50IG5zSW5kZXggPSAxOwotICAgICAgICB3aGlsZSAobmV4dE5TTm9kZSAhPSBEVE0uTlVMTCkgewotICAgICAgICAgICAgLy8gUmV0cmlldmUgdGhlIG5hbWUgb2YgdGhlIG5hbWVzcGFjZSBub2RlCi0gICAgICAgICAgICBpbnQgZVR5cGUgPSBfZXhwdHlwZTIobmV4dE5TTm9kZSk7Ci0gICAgICAgICAgICBTdHJpbmcgbm9kZU5hbWUgPSBtX2V4dGVuZGVkVHlwZXNbZVR5cGVdLmdldExvY2FsTmFtZSgpOwotCi0gICAgICAgICAgICAvLyBSZXRyaWV2ZSB0aGUgbm9kZSB2YWx1ZSBvZiB0aGUgbmFtZXNwYWNlIG5vZGUKLSAgICAgICAgICAgIGludCBkYXRhSW5kZXggPSBtX2RhdGFPclFOYW1lLmVsZW1lbnRBdChuZXh0TlNOb2RlKTsKLQotICAgICAgICAgICAgaWYgKGRhdGFJbmRleCA8IDApIHsKLSAgICAgICAgICAgICAgICBkYXRhSW5kZXggPSAtZGF0YUluZGV4OwotICAgICAgICAgICAgICAgIGRhdGFJbmRleCA9IG1fZGF0YS5lbGVtZW50QXQoZGF0YUluZGV4ICsgMSk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIFN0cmluZyBub2RlVmFsdWUgPSAoU3RyaW5nKW1fdmFsdWVzLmVsZW1lbnRBdChkYXRhSW5kZXgpOwotCi0gICAgICAgICAgICBoYW5kbGVyLm5hbWVzcGFjZUFmdGVyU3RhcnRFbGVtZW50KG5vZGVOYW1lLCBub2RlVmFsdWUpOwotCi0gICAgICAgICAgICBpZiAoaW5TY29wZSkgewotICAgICAgICAgICAgICAgIGlmIChuc0luZGV4IDwgbnNDb250ZXh0LnNpemUoKSkgewotICAgICAgICAgICAgICAgICAgICBuZXh0TlNOb2RlID0gbWFrZU5vZGVJZGVudGl0eShuc0NvbnRleHQuZWxlbWVudEF0KG5zSW5kZXgpKTsKLSAgICAgICAgICAgICAgICAgICAgbnNJbmRleCsrOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICBuZXh0TlNOb2RlID0gZ2V0TmV4dE5hbWVzcGFjZU5vZGUyKG5leHROU05vZGUpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSBuZXh0IG5hbWVzcGFjZSBub2RlIGZvbGxvd2luZyB0aGUgZ2l2ZW4gYmFzZSBub2RlLgotICAgICAqCi0gICAgICogQGJhc2VJRCBUaGUgbm9kZSBpZGVudGl0eSBvZiB0aGUgYmFzZSBub2RlLCB3aGljaCBjYW4gYmUgYW4KLSAgICAgKiBlbGVtZW50LCBhdHRyaWJ1dGUgb3IgbmFtZXNwYWNlIG5vZGUuCi0gICAgICogQHJldHVybiBUaGUgbmFtZXNwYWNlIG5vZGUgaW1tZWRpYXRlbHkgZm9sbG93aW5nIHRoZSBiYXNlIG5vZGUuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGZpbmFsIGludCBnZXROZXh0TmFtZXNwYWNlTm9kZTIoaW50IGJhc2VJRCkgewotICAgICAgICBpbnQgdHlwZTsKLSAgICAgICAgd2hpbGUgKCh0eXBlID0gX3R5cGUyKCsrYmFzZUlEKSkgPT0gRFRNLkFUVFJJQlVURV9OT0RFKTsKLQotICAgICAgICBpZiAodHlwZSA9PSBEVE0uTkFNRVNQQUNFX05PREUpCi0gICAgICAgICAgICByZXR1cm4gYmFzZUlEOwotICAgICAgICBlbHNlCi0gICAgICAgICAgICByZXR1cm4gTlVMTDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb3B5ICBhdHRyaWJ1dGUgbm9kZXMgZnJvbSBhbiBlbGVtZW50IC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBub2RlSUQgVGhlIEVsZW1lbnQgbm9kZSBpZGVudGl0eQotICAgICAqIEBwYXJhbSBoYW5kbGVyIFRoZSBTZXJpYWxpemF0aW9uSGFuZGxlcgotICAgICAqLwotICAgIHByb3RlY3RlZCBmaW5hbCB2b2lkIGNvcHlBdHRyaWJ1dGVzKGZpbmFsIGludCBub2RlSUQsIFNlcmlhbGl6YXRpb25IYW5kbGVyIGhhbmRsZXIpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb257Ci0KLSAgICAgICBmb3IoaW50IGN1cnJlbnQgPSBnZXRGaXJzdEF0dHJpYnV0ZUlkZW50aXR5KG5vZGVJRCk7IGN1cnJlbnQgIT0gRFRNLk5VTEw7IGN1cnJlbnQgPSBnZXROZXh0QXR0cmlidXRlSWRlbnRpdHkoY3VycmVudCkpewotICAgICAgICAgICAgaW50IGVUeXBlID0gX2V4cHR5cGUyKGN1cnJlbnQpOwotICAgICAgICAgICAgY29weUF0dHJpYnV0ZShjdXJyZW50LCBlVHlwZSwgaGFuZGxlcik7Ci0gICAgICAgfQotICAgIH0KLQotCi0KLSAgICAvKioKLSAgICAgKiBDb3B5IGFuIEF0dHJpYnV0ZSBub2RlIHRvIGEgU2VyaWFsaXphdGlvbkhhbmRsZXIKLSAgICAgKgotICAgICAqIEBwYXJhbSBub2RlSUQgVGhlIG5vZGUgaWRlbnRpdHkKLSAgICAgKiBAcGFyYW0gZXhwdHlwZSBUaGUgZXhwYW5kZWQgdHlwZSBvZiB0aGUgRWxlbWVudCBub2RlCi0gICAgICogQHBhcmFtIGhhbmRsZXIgVGhlIFNlcmlhbGl6YXRpb25IYW5kbGVyCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGZpbmFsIHZvaWQgY29weUF0dHJpYnV0ZShpbnQgbm9kZUlELCBpbnQgZXhwdHlwZSwKLSAgICAgICAgU2VyaWFsaXphdGlvbkhhbmRsZXIgaGFuZGxlcikKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgLyoKLSAgICAgICAgICAgIGZpbmFsIFN0cmluZyB1cmkgPSBnZXROYW1lc3BhY2VOYW1lKG5vZGUpOwotICAgICAgICAgICAgaWYgKHVyaS5sZW5ndGgoKSAhPSAwKSB7Ci0gICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIHByZWZpeCA9IGdldFByZWZpeChub2RlKTsKLSAgICAgICAgICAgICAgICBoYW5kbGVyLm5hbWVzcGFjZUFmdGVyU3RhcnRFbGVtZW50KHByZWZpeCwgdXJpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGhhbmRsZXIuYWRkQXR0cmlidXRlKGdldE5vZGVOYW1lKG5vZGUpLCBnZXROb2RlVmFsdWUobm9kZSkpOwotICAgICAgICAqLwotICAgICAgICBmaW5hbCBFeHRlbmRlZFR5cGUgZXh0VHlwZSA9IG1fZXh0ZW5kZWRUeXBlc1tleHB0eXBlXTsKLSAgICAgICAgZmluYWwgU3RyaW5nIHVyaSA9IGV4dFR5cGUuZ2V0TmFtZXNwYWNlKCk7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBsb2NhbE5hbWUgPSBleHRUeXBlLmdldExvY2FsTmFtZSgpOwotCi0gICAgICAgIFN0cmluZyBwcmVmaXggPSBudWxsOwotICAgICAgICBTdHJpbmcgcW5hbWUgPSBudWxsOwotICAgICAgICBpbnQgZGF0YUluZGV4ID0gX2RhdGFPclFOYW1lKG5vZGVJRCk7Ci0gICAgICAgIGludCB2YWx1ZUluZGV4ID0gZGF0YUluZGV4OwotICAgICAgICAgICAgaWYgKGRhdGFJbmRleCA8PSAwKSB7Ci0gICAgICAgICAgICAgICAgaW50IHByZWZpeEluZGV4ID0gbV9kYXRhLmVsZW1lbnRBdCgtZGF0YUluZGV4KTsKLSAgICAgICAgICAgICAgICB2YWx1ZUluZGV4ID0gbV9kYXRhLmVsZW1lbnRBdCgtZGF0YUluZGV4KzEpOwotICAgICAgICAgICAgICAgIHFuYW1lID0gbV92YWx1ZXNPclByZWZpeGVzLmluZGV4VG9TdHJpbmcocHJlZml4SW5kZXgpOwotICAgICAgICAgICAgICAgIGludCBjb2xvbkluZGV4ID0gcW5hbWUuaW5kZXhPZignOicpOwotICAgICAgICAgICAgICAgIGlmIChjb2xvbkluZGV4ID4gMCkgewotICAgICAgICAgICAgICAgICAgICBwcmVmaXggPSBxbmFtZS5zdWJzdHJpbmcoMCwgY29sb25JbmRleCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKHVyaS5sZW5ndGgoKSAhPSAwKSB7Ci0gICAgICAgICAgICAgICAgaGFuZGxlci5uYW1lc3BhY2VBZnRlclN0YXJ0RWxlbWVudChwcmVmaXgsIHVyaSk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgU3RyaW5nIG5vZGVOYW1lID0gKHByZWZpeCAhPSBudWxsKSA/IHFuYW1lIDogbG9jYWxOYW1lOwotICAgICAgICBTdHJpbmcgbm9kZVZhbHVlID0gKFN0cmluZyltX3ZhbHVlcy5lbGVtZW50QXQodmFsdWVJbmRleCk7Ci0KLSAgICAgICAgaGFuZGxlci5hZGRBdHRyaWJ1dGUodXJpLCBsb2NhbE5hbWUsIG5vZGVOYW1lLCAiQ0RBVEEiLCBub2RlVmFsdWUpOwotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL3JlZi9zYXgyZHRtL1NBWDJSVEZEVE0uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9yZWYvc2F4MmR0bS9TQVgyUlRGRFRNLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGMwOTk2OGYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL3JlZi9zYXgyZHRtL1NBWDJSVEZEVE0uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDM2NCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBTQVgyUlRGRFRNLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTUgMDg6MTU6MTMgc3VyZXNoX2VtYWlsaWQgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5yZWYuc2F4MmR0bTsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uU291cmNlOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTU1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNV1NGaWx0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5JbnRTdGFjazsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLkludFZlY3RvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLlN0cmluZ1ZlY3RvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLlhNTFN0cmluZ0ZhY3Rvcnk7Ci0KLWltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci0KLS8qKgotICogVGhpcyBpcyBhIHN1YmNsYXNzIG9mIFNBWDJEVE0gd2hpY2ggaGFzIGJlZW4gbW9kaWZpZWQgdG8gbWVldCB0aGUgbmVlZHMgb2YKLSAqIFJlc3VsdCBUcmVlIEZyYW1ld29ya3MgKFJURnMpLiBUaGUgZGlmZmVyZW5jZXMgYXJlOgotICoKLSAqIDEpIE11bHRpcGxlIFhNTCB0cmVlcyBtYXkgYmUgYXBwZW5kZWQgdG8gdGhlIHNpbmdsZSBEVE0uIFRoaXMgbWVhbnMKLSAqIHRoYXQgdGhlIHJvb3Qgbm9kZSBvZiBlYWNoIGRvY3VtZW50IGlzIF9ub3RfIG5vZGUgMC4gU29tZSBjb2RlIGhhcwotICogaGFkIHRvIGJlIGRlb3B0aW1pemVkIHRvIHN1cHBvcnQgdGhpcyBtb2RlIG9mIG9wZXJhdGlvbiwgYW5kIGFuCi0gKiBleHBsaWNpdCBtZWNoYW5pc20gZm9yIG9idGFpbmluZyB0aGUgTm9kZSBIYW5kbGUgb2YgdGhlIHJvb3Qgbm9kZQotICogaGFzIGJlZW4gcHJvdmlkZWQuCi0gKgotICogMikgQSBzdGFjayBvZiB0aGVzZSBkb2N1bWVudHMgaXMgbWFpbnRhaW5lZCwgYWxsb3dpbmcgdXMgdG8gInRhaWwtcHJ1bmUiIHRoZQotICogbW9zdCByZWNlbnRseSBhZGRlZCB0cmVlcyBvZmYgdGhlIGVuZCBvZiB0aGUgRFRNIGFzIHN0eWxlc2hlZXQgZWxlbWVudHMKLSAqIChhbmQgdGh1cyB2YXJpYWJsZSBjb250ZXh0cykgYXJlIGV4aXRlZC4KLSAqCi0gKiBQTEVBU0UgTk9URSB0aGF0IHRoaXMgY2xhc3MgbWF5IGJlIF9oZWF2aWx5XyBkZXBlbmRlbnQgdXBvbiB0aGUKLSAqIGludGVybmFscyBvZiB0aGUgU0FYMkRUTSBzdXBlcmNsYXNzLCBhbmQgbXVzdCBiZSBtYWludGFpbmVkIGluCi0gKiBwYXJhbGxlbCB3aXRoIHRoYXQgY29kZS4gIEFyZ3VhYmx5LCB0aGV5IHNob3VsZCBiZSBjb25kaXRpb25hbHMKLSAqIHdpdGhpbiBhIHNpbmdsZSBjbGFzcy4uLiBidXQgdGhleSBoYXZlIGRlZW4gc2VwYXJhdGVkIGZvcgotICogcGVyZm9ybWFuY2UgcmVhc29ucy4gKEluIGZhY3QsIG9uZSBjb3VsZCBldmVuIGFyZ3VlIGFib3V0IHdoaWNoIGlzCi0gKiB0aGUgc3VwZXJjbGFzcyBhbmQgd2hpY2ggaXMgdGhlIHN1YmNsYXNzOyB0aGUgY3VycmVudCBhcnJhbmdlbWVudAotICogaXMgYXMgbXVjaCBhYm91dCBwcmVzZXJ2aW5nIHN0YWJpbGl0eSBvZiBleGlzdGluZyBjb2RlIGR1cmluZwotICogZGV2ZWxvcG1lbnQgYXMgYW55dGhpbmcgZWxzZS4pCi0gKgotICogJVJFVklFVyUgSW4gZmFjdCwgc2luY2UgdGhlIGRpZmZlcmVuY2VzIGFyZSBzbyBtaW5vciwgSSB0aGluayBpdAotICogbWF5IGJlIHBvc3NpYmxlL3ByYWN0aWNhbCB0byBmb2xkIHRoZW0gYmFjayBpbnRvIHRoZSBiYXNlCi0gKiBTQVgyRFRNLiBDb25zaWRlciB0aGF0IGFzIGEgZnV0dXJlIGNvZGUtc2l6ZSBvcHRpbWl6YXRpb24uCi0gKiAqLwotcHVibGljIGNsYXNzIFNBWDJSVEZEVE0gZXh0ZW5kcyBTQVgyRFRNCi17Ci0gIC8qKiBTZXQgdHJ1ZSB0byBtb25pdG9yIFNBWCBldmVudHMgYW5kIHNpbWlsYXIgZGlhZ25vc3RpYyBpbmZvLiAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIERFQlVHID0gZmFsc2U7Ci0KLSAgLyoqIE1vc3QgcmVjZW50bHkgc3RhcnRlZCBEb2N1bWVudCwgb3IgbnVsbCBpZiB0aGUgRFRNIGlzIGVtcHR5LiAgKi8KLSAgcHJpdmF0ZSBpbnQgbV9jdXJyZW50RG9jdW1lbnROb2RlPU5VTEw7Ci0KLSAgLyoqIFRhaWwtcHJ1bmluZyBtYXJrOiBOdW1iZXIgb2Ygbm9kZXMgaW4gdXNlICovCi0gIEludFN0YWNrIG1hcmtfc2l6ZT1uZXcgSW50U3RhY2soKTsKLSAgLyoqIFRhaWwtcHJ1bmluZyBtYXJrOiBOdW1iZXIgb2YgZGF0YSBpdGVtcyBpbiB1c2UgKi8KLSAgSW50U3RhY2sgbWFya19kYXRhX3NpemU9bmV3IEludFN0YWNrKCk7Ci0gIC8qKiBUYWlsLXBydW5pbmcgbWFyazogTnVtYmVyIG9mIHNpemUtb2YtZGF0YSBmaWVsZHMgaW4gdXNlICovCi0gIEludFN0YWNrIG1hcmtfY2hhcl9zaXplPW5ldyBJbnRTdGFjaygpOwotICAvKiogVGFpbC1wcnVuaW5nIG1hcms6IE51bWJlciBvZiBkYXRhT3JRTmFtZSBzbG90cyBpbiB1c2UgKi8KLSAgSW50U3RhY2sgbWFya19kb3Ffc2l6ZT1uZXcgSW50U3RhY2soKTsKLSAgLyoqIFRhaWwtcHJ1bmluZyBtYXJrOiBOdW1iZXIgb2YgbmFtZXNwYWNlIGRlY2xhcmF0aW9uIHNldHMgaW4gdXNlCi0gICAqICVSRVZJRVclIEkgZG9uJ3QgdGhpbmsgbnVtYmVyIG9mIE5TIHNldHMgaXMgZXZlciBkaWZmZXJlbnQgZnJvbSBudW1iZXIKLSAgICogb2YgTlMgZWxlbWVudHMuIFdlIGNhbiBwcm9iYWJhYmx5IHJlZHVjZSB0aGVzZSB0byBhIHNpbmdsZSBzdGFjayBhbmQgc2F2ZQotICAgKiBzb21lIHN0b3JhZ2UuCi0gICAqICovCi0gIEludFN0YWNrIG1hcmtfbnNkZWNsc2V0X3NpemU9bmV3IEludFN0YWNrKCk7Ci0gIC8qKiBUYWlsLXBydW5pbmcgbWFyazogTnVtYmVyIG9mIG5hZXNwYWNlIGRlY2xhcmF0aW9uIGVsZW1lbnRzIGluIHVzZQotICAgKiAlUkVWSUVXJSBJIGRvbid0IHRoaW5rIG51bWJlciBvZiBOUyBzZXRzIGlzIGV2ZXIgZGlmZmVyZW50IGZyb20gbnVtYmVyCi0gICAqIG9mIE5TIGVsZW1lbnRzLiBXZSBjYW4gcHJvYmFiYWJseSByZWR1Y2UgdGhlc2UgdG8gYSBzaW5nbGUgc3RhY2sgYW5kIHNhdmUKLSAgICogc29tZSBzdG9yYWdlLgotICAgKi8KLSAgSW50U3RhY2sgbWFya19uc2RlY2xlbGVtX3NpemU9bmV3IEludFN0YWNrKCk7Ci0KLSAgLyoqCi0gICAqIFRhaWwtcHJ1bmluZyBtYXJrOiAgaW5pdGlhbCBudW1iZXIgb2Ygbm9kZXMgaW4gdXNlCi0gICAqLwotICBpbnQgbV9lbXB0eU5vZGVDb3VudDsKLQotICAvKioKLSAgICogVGFpbC1wcnVuaW5nIG1hcms6ICBpbml0aWFsIG51bWJlciBvZiBuYW1lc3BhY2UgZGVjbGFyYXRpb24gc2V0cwotICAgKi8KLSAgaW50IG1fZW1wdHlOU0RlY2xTZXRDb3VudDsKLQotICAvKioKLSAgICogVGFpbC1wcnVuaW5nIG1hcms6ICBpbml0aWFsIG51bWJlciBvZiBuYW1lc3BhY2UgZGVjbGFyYXRpb24gZWxlbWVudHMKLSAgICovCi0gIGludCBtX2VtcHR5TlNEZWNsU2V0RWxlbXNDb3VudDsKLQotICAvKioKLSAgICogVGFpbC1wcnVuaW5nIG1hcms6ICBpbml0aWFsIG51bWJlciBvZiBkYXRhIGl0ZW1zIGluIHVzZQotICAgKi8KLSAgaW50IG1fZW1wdHlEYXRhQ291bnQ7Ci0KLSAgLyoqCi0gICAqIFRhaWwtcHJ1bmluZyBtYXJrOiAgaW5pdGlhbCBudW1iZXIgb2YgY2hhcmFjdGVycyBpbiB1c2UKLSAgICovCi0gIGludCBtX2VtcHR5Q2hhcnNDb3VudDsKLQotICAvKioKLSAgICogVGFpbC1wcnVuaW5nIG1hcms6ICBkZWZhdWx0IGluaXRpYWwgbnVtYmVyIG9mIGRhdGFPclFOYW1lIHNsb3RzIGluIHVzZQotICAgKi8KLSAgaW50IG1fZW1wdHlEYXRhUU5Db3VudDsKLQotICBwdWJsaWMgU0FYMlJURkRUTShEVE1NYW5hZ2VyIG1nciwgU291cmNlIHNvdXJjZSwgaW50IGR0bUlkZW50aXR5LAotICAgICAgICAgICAgICAgICBEVE1XU0ZpbHRlciB3aGl0ZVNwYWNlRmlsdGVyLAotICAgICAgICAgICAgICAgICBYTUxTdHJpbmdGYWN0b3J5IHhzdHJpbmdmYWN0b3J5LAotICAgICAgICAgICAgICAgICBib29sZWFuIGRvSW5kZXhpbmcpCi0gIHsKLSAgICBzdXBlcihtZ3IsIHNvdXJjZSwgZHRtSWRlbnRpdHksIHdoaXRlU3BhY2VGaWx0ZXIsCi0gICAgICAgICAgeHN0cmluZ2ZhY3RvcnksIGRvSW5kZXhpbmcpOwotCi0gICAgLy8gTkVWRVIgdHJhY2sgc291cmNlIGxvY2F0b3JzIGZvciBSVEZzOyB0aGV5IGFyZW4ndCBtZWFuaW5nZnVsLiBJIHRoaW5rLgotICAgIC8vIChJZiB3ZSBkaWQgdHJhY2sgdGhlbSwgd2UnZCBuZWVkIHRvIHRhaWwtcHJ1bmUgdGhlc2UgdG9vLikKLSAgICAvL2NvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC5wcm9jZXNzb3IuVHJhbnNmb3JtZXJGYWN0b3J5SW1wbC5tX3NvdXJjZV9sb2NhdGlvbjsKLSAgICBtX3VzZVNvdXJjZUxvY2F0aW9uUHJvcGVydHk9ZmFsc2U7Ci0gICAgbV9zb3VyY2VTeXN0ZW1JZCA9IChtX3VzZVNvdXJjZUxvY2F0aW9uUHJvcGVydHkpID8gbmV3IFN0cmluZ1ZlY3RvcigpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogbnVsbDsKLSAgICBtX3NvdXJjZUxpbmUgPSAobV91c2VTb3VyY2VMb2NhdGlvblByb3BlcnR5KSA/IG5ldyBJbnRWZWN0b3IoKSA6IG51bGw7Ci0gICAgbV9zb3VyY2VDb2x1bW4gPSAobV91c2VTb3VyY2VMb2NhdGlvblByb3BlcnR5KSA/IG5ldyBJbnRWZWN0b3IoKSA6IG51bGw7Ci0KLSAgICAvLyBSZWNvcmQgaW5pdGlhbCBzaXplcyBvZiBmaWVsZHMgdGhhdCBhcmUgcHVzaGVkIGFuZCByZXN0b3JlZAotICAgIC8vIGZvciBSVEYgdGFpbC1wcnVuaW5nLiAgTW9yZSBlbnRyaWVzIGNhbiBiZSBwb3BwZWQgdGhhbiBwdXNoZWQsIHNvCi0gICAgLy8gd2UgbmVlZCB0aGlzIHRvIG1hcmsgdGhlIHByaW1vcmRpYWwgc3RhdGUgb2YgdGhlIERUTS4KLSAgICBtX2VtcHR5Tm9kZUNvdW50ID0gbV9zaXplOwotICAgIG1fZW1wdHlOU0RlY2xTZXRDb3VudCA9IChtX25hbWVzcGFjZURlY2xTZXRzID09IG51bGwpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IDAgOiBtX25hbWVzcGFjZURlY2xTZXRzLnNpemUoKTsKLSAgICBtX2VtcHR5TlNEZWNsU2V0RWxlbXNDb3VudCA9IChtX25hbWVzcGFjZURlY2xTZXRFbGVtZW50cyA9PSBudWxsKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IDAgOiBtX25hbWVzcGFjZURlY2xTZXRFbGVtZW50cy5zaXplKCk7Ci0gICAgbV9lbXB0eURhdGFDb3VudCA9IG1fZGF0YS5zaXplKCk7Ci0gICAgbV9lbXB0eUNoYXJzQ291bnQgPSBtX2NoYXJzLnNpemUoKTsKLSAgICBtX2VtcHR5RGF0YVFOQ291bnQgPSBtX2RhdGFPclFOYW1lLnNpemUoKTsKLSAgfQotCi0gIC8qKgotICAgKiBHaXZlbiBhIERUTSwgZmluZCB0aGUgb3duaW5nIGRvY3VtZW50IG5vZGUuIEluIHRoZSBjYXNlIG9mCi0gICAqIFNBWDJSVEZEVE0sIHdoaWNoIG1heSBjb250YWluIG11bHRpcGxlIGRvY3VtZW50cywgdGhpcyByZXR1cm5zCi0gICAqIHRoZSA8Yj5tb3N0IHJlY2VudGx5IHN0YXJ0ZWQ8L2I+IGRvY3VtZW50LCBvciBudWxsIGlmIHRoZSBEVE0gaXMKLSAgICogZW1wdHkgb3Igbm8gZG9jdW1lbnQgaXMgY3VycmVudGx5IHVuZGVyIGNvbnN0cnVjdGlvbi4KLSAgICoKLSAgICogJVJFVklFVyUgU2hvdWxkIHdlIGNvbnRpbnVlIHRvIHJlcG9ydCB0aGUgbW9zdCByZWNlbnQgYWZ0ZXIKLSAgICogY29uc3RydWN0aW9uIGhhcyBlbmRlZD8gSSB0aGluayBub3QsIGdpdmVuIHRoYXQgaXQgbWF5IGhhdmUgYmVlbgotICAgKiB0YWlsLXBydW5lZC4KLSAgICoKLSAgICogIEByZXR1cm4gaW50IE5vZGUgaGFuZGxlIG9mIERvY3VtZW50IG5vZGUsIG9yIG51bGwgaWYgdGhpcyBEVE0gZG9lcyBub3QKLSAgICogIGNvbnRhaW4gYW4gImFjdGl2ZSIgZG9jdW1lbnQuCi0gICAqICovCi0gIHB1YmxpYyBpbnQgZ2V0RG9jdW1lbnQoKQotICB7Ci0gICAgcmV0dXJuIG1ha2VOb2RlSGFuZGxlKG1fY3VycmVudERvY3VtZW50Tm9kZSk7Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYSBub2RlIGhhbmRsZSwgZmluZCB0aGUgb3duaW5nIGRvY3VtZW50IG5vZGUsIHVzaW5nIERUTSBzZW1hbnRpY3MKLSAgICogKERvY3VtZW50IG93bnMgaXRzZWxmKSByYXRoZXIgdGhhbiBET00gc2VtYW50aWNzIChEb2N1bWVudCBoYXMgbm8gb3duZXIpLgotICAgKgotICAgKiAoSSdtIGNvdW50aW5nIG9uIHRoZSBmYWN0IHRoYXQgZ2V0T3duZXJEb2N1bWVudCgpIGlzIGltcGxlbWVudGVkIG9uIHRvcAotICAgKiBvZiB0aGlzIGNhbGwsIGluIHRoZSBzdXBlcmNsYXNzLCB0byBhdm9pZCBoYXZpbmcgdG8gcmV3cml0ZSB0aGF0IG9uZS4KLSAgICogQmUgY2FyZWZ1bCBpZiB0aGF0IGNvZGUgY2hhbmdlcyEpCi0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIHRoZSBpZCBvZiB0aGUgbm9kZS4KLSAgICogQHJldHVybiBpbnQgTm9kZSBoYW5kbGUgb2Ygb3duaW5nIGRvY3VtZW50Ci0gICAqLwotICBwdWJsaWMgaW50IGdldERvY3VtZW50Um9vdChpbnQgbm9kZUhhbmRsZSkKLSAgewotICAgIGZvciAoaW50IGlkPW1ha2VOb2RlSWRlbnRpdHkobm9kZUhhbmRsZSk7IGlkIT1OVUxMOyBpZD1fcGFyZW50KGlkKSkgewotICAgICAgaWYgKF90eXBlKGlkKT09RFRNLkRPQ1VNRU5UX05PREUpIHsKLSAgICAgICAgcmV0dXJuIG1ha2VOb2RlSGFuZGxlKGlkKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gRFRNLk5VTEw7IC8vIFNhZmV0eSBuZXQ7IHNob3VsZCBuZXZlciBoYXBwZW4KLSAgfQotCi0gIC8qKgotICAgKiBHaXZlbiBhIG5vZGUgaWRlbnRpZmllciwgZmluZCB0aGUgb3duaW5nIGRvY3VtZW50IG5vZGUuICBVbmxpa2UgdGhlIERPTSwKLSAgICogdGhpcyBjb25zaWRlcnMgdGhlIG93bmluZ0RvY3VtZW50IG9mIGEgRG9jdW1lbnQgdG8gYmUgaXRzZWxmLiBOb3RlIHRoYXQKLSAgICogaW4gc2hhcmVkIERUTXMgdGhpcyBtYXkgbm90IGJlIHplcm8uCi0gICAqCi0gICAqIEBwYXJhbSBub2RlSWRlbnRpZmllciB0aGUgaWQgb2YgdGhlIHN0YXJ0aW5nIG5vZGUuCi0gICAqIEByZXR1cm4gaW50IE5vZGUgaWRlbnRpZmllciBvZiB0aGUgcm9vdCBvZiB0aGlzIERUTSB0cmVlCi0gICAqLwotICBwcm90ZWN0ZWQgaW50IF9kb2N1bWVudFJvb3QoaW50IG5vZGVJZGVudGlmaWVyKQotICB7Ci0gICAgaWYobm9kZUlkZW50aWZpZXI9PU5VTEwpIHJldHVybiBOVUxMOwotCi0gICAgZm9yIChpbnQgcGFyZW50PV9wYXJlbnQobm9kZUlkZW50aWZpZXIpOwotICAgICAgICAgcGFyZW50IT1OVUxMOwotICAgICAgICAgbm9kZUlkZW50aWZpZXI9cGFyZW50LHBhcmVudD1fcGFyZW50KG5vZGVJZGVudGlmaWVyKSkKLSAgICAgIDsKLQotICAgIHJldHVybiBub2RlSWRlbnRpZmllcjsKLSAgfQotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiB0aGUgYmVnaW5uaW5nIG9mIGEgbmV3IFJURiBkb2N1bWVudC4KLSAgICoKLSAgICogJVJFVklFVyUgWSdrbm93LCB0aGlzIGlzbid0IGFsbCB0aGF0IG11Y2ggb2YgYSBkZW9wdGltaXphdGlvbi4gV2UKLSAgICogbWlnaHQgd2FudCB0byBjb25zaWRlciBmb2xkaW5nIHRoZSBzdGFydC9lbmREb2N1bWVudCBjaGFuZ2VzIGJhY2sKLSAgICogaW50byB0aGUgbWFpbiBTQVgyRFRNIHNvIHdlIGRvbid0IGhhdmUgdG8gZXhwb3NlIHNvIG1hbnkgZmllbGRzCi0gICAqIChldmVuIGFzIFByb3RlY3RlZCkgYW5kIGNhcnJ5IHRoZSBhZGRpdGlvbmFsIGNvZGUuCi0gICAqCi0gICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI3N0YXJ0RG9jdW1lbnQKLSAgICogKi8KLSAgcHVibGljIHZvaWQgc3RhcnREb2N1bWVudCgpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotICAgIC8vIFJlLWluaXRpYWxpemUgdGhlIHRyZWUgYXBwZW5kIHByb2Nlc3MKLSAgICBtX2VuZERvY3VtZW50T2NjdXJlZCA9IGZhbHNlOwotICAgIG1fcHJlZml4TWFwcGluZ3MgPSBuZXcgamF2YS51dGlsLlZlY3RvcigpOwotICAgIG1fY29udGV4dEluZGV4ZXMgPSBuZXcgSW50U3RhY2soKTsKLSAgICBtX3BhcmVudHMgPSBuZXcgSW50U3RhY2soKTsKLQotICAgIG1fY3VycmVudERvY3VtZW50Tm9kZT1tX3NpemU7Ci0gICAgc3VwZXIuc3RhcnREb2N1bWVudCgpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIHRoZSBlbmQgb2YgdGhlIGRvY3VtZW50LgotICAgKgotICAgKiAlUkVWSUVXJSBZJ2tub3csIHRoaXMgaXNuJ3QgYWxsIHRoYXQgbXVjaCBvZiBhIGRlb3B0aW1pemF0aW9uLiBXZQotICAgKiBtaWdodCB3YW50IHRvIGNvbnNpZGVyIGZvbGRpbmcgdGhlIHN0YXJ0L2VuZERvY3VtZW50IGNoYW5nZXMgYmFjawotICAgKiBpbnRvIHRoZSBtYWluIFNBWDJEVE0gc28gd2UgZG9uJ3QgaGF2ZSB0byBleHBvc2Ugc28gbWFueSBmaWVsZHMKLSAgICogKGV2ZW4gYXMgUHJvdGVjdGVkKS4KLSAgICoKLSAgICogQHRocm93cyBTQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjZW5kRG9jdW1lbnQKLSAgICogKi8KLSAgcHVibGljIHZvaWQgZW5kRG9jdW1lbnQoKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBjaGFyYWN0ZXJzRmx1c2goKTsKLQotICAgIG1fbmV4dHNpYi5zZXRFbGVtZW50QXQoTlVMTCxtX2N1cnJlbnREb2N1bWVudE5vZGUpOwotCi0gICAgaWYgKG1fZmlyc3RjaC5lbGVtZW50QXQobV9jdXJyZW50RG9jdW1lbnROb2RlKSA9PSBOT1RQUk9DRVNTRUQpCi0gICAgICBtX2ZpcnN0Y2guc2V0RWxlbWVudEF0KE5VTEwsbV9jdXJyZW50RG9jdW1lbnROb2RlKTsKLQotICAgIGlmIChEVE0uTlVMTCAhPSBtX3ByZXZpb3VzKQotICAgICAgbV9uZXh0c2liLnNldEVsZW1lbnRBdChEVE0uTlVMTCxtX3ByZXZpb3VzKTsKLQotICAgIG1fcGFyZW50cyA9IG51bGw7Ci0gICAgbV9wcmVmaXhNYXBwaW5ncyA9IG51bGw7Ci0gICAgbV9jb250ZXh0SW5kZXhlcyA9IG51bGw7Ci0KLSAgICBtX2N1cnJlbnREb2N1bWVudE5vZGU9IE5VTEw7IC8vIG5vIGxvbmdlciBvcGVuCi0gICAgbV9lbmREb2N1bWVudE9jY3VyZWQgPSB0cnVlOwotICB9Ci0KLQotICAvKiogIlRhaWwtcHJ1bmluZyIgc3VwcG9ydCBmb3IgUlRGcy4KLSAgICoKLSAgICogVGhpcyBmdW5jdGlvbiBwdXNoZXMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGN1cnJlbnQgc2l6ZSBvZiB0aGUKLSAgICogRFRNJ3MgZGF0YSBzdHJ1Y3R1cmVzIG9udG8gYSBzdGFjaywgZm9yIHVzZSBieSBwb3BSZXdpbmRNYXJrKCkKLSAgICogKHdoaWNoIHNlZSkuCi0gICAqCi0gICAqICVSRVZJRVclIEkgaGF2ZSBubyBpZGVhIGhvdyB0byByZXdpbmQgbV9lbGVtSW5kZXhlcy4gSG93ZXZlciwKLSAgICogUlRGcyB3aWxsIG5vdCBiZSBpbmRleGVkLCBzbyBJIGNhbiBzaW1wbHkgcGFuaWMgaWYgdGhhdCBjYXNlCi0gICAqIGFyaXNlcy4gSGV5LCBpdCB3b3Jrcy4uLgotICAgKiAqLwotICBwdWJsaWMgdm9pZCBwdXNoUmV3aW5kTWFyaygpCi0gIHsKLSAgICBpZihtX2luZGV4aW5nIHx8IG1fZWxlbUluZGV4ZXMhPW51bGwpCi0gICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCJDb2RpbmcgZXJyb3I7IERvbid0IHRyeSB0byBtYXJrL3Jld2luZCBhbiBpbmRleGVkIERUTSIpOwotCi0gICAgLy8gVmFsdWVzIGZyb20gRFRNRGVmYXVsdEJhc2UKLSAgICAvLyAlUkVWSUVXJSBDYW4gdGhlIG5hbWVzcGFjZSBzdGFjayBzaXplcyBldmVyIGRpZmZlcj8gSWYgbm90LCBzYXZlIHNwYWNlIQotICAgIG1hcmtfc2l6ZS5wdXNoKG1fc2l6ZSk7Ci0gICAgbWFya19uc2RlY2xzZXRfc2l6ZS5wdXNoKChtX25hbWVzcGFjZURlY2xTZXRzPT1udWxsKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IDAKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBtX25hbWVzcGFjZURlY2xTZXRzLnNpemUoKSk7Ci0gICAgbWFya19uc2RlY2xlbGVtX3NpemUucHVzaCgobV9uYW1lc3BhY2VEZWNsU2V0RWxlbWVudHM9PW51bGwpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gMAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IG1fbmFtZXNwYWNlRGVjbFNldEVsZW1lbnRzLnNpemUoKSk7Ci0KLSAgICAvLyBWYWx1ZXMgZnJvbSBTQVgyRFRNCi0gICAgbWFya19kYXRhX3NpemUucHVzaChtX2RhdGEuc2l6ZSgpKTsKLSAgICBtYXJrX2NoYXJfc2l6ZS5wdXNoKG1fY2hhcnMuc2l6ZSgpKTsKLSAgICBtYXJrX2RvcV9zaXplLnB1c2gobV9kYXRhT3JRTmFtZS5zaXplKCkpOwotICB9Ci0KLSAgLyoqICJUYWlsLXBydW5pbmciIHN1cHBvcnQgZm9yIFJURnMuCi0gICAqCi0gICAqIFRoaXMgZnVuY3Rpb24gcG9wcyB0aGUgaW5mb3JtYXRpb24gcHJldmlvdXNseSBzYXZlZCBieQotICAgKiBwdXNoUmV3aW5kTWFyayAod2hpY2ggc2VlKSBhbmQgdXNlcyBpdCB0byBkaXNjYXJkIGFsbCBub2RlcyBhZGRlZAotICAgKiB0byB0aGUgRFRNIGFmdGVyIHRoYXQgdGltZS4gV2UgZXhwZWN0IHRoYXQgdGhpcyB3aWxsIGFsbG93IHVzIHRvCi0gICAqIHJldXNlIHN0b3JhZ2UgbW9yZSBlZmZlY3RpdmVseS4KLSAgICoKLSAgICogVGhpcyBpcyBfbm90XyBpbnRlbmRlZCB0byBiZSBjYWxsZWQgd2hpbGUgYSBkb2N1bWVudCBpcyBzdGlsbCBiZWluZwotICAgKiBjb25zdHJ1Y3RlZCAtLSBvbmx5IGJldHdlZW4gZW5kRG9jdW1lbnQgYW5kIHRoZSBuZXh0IHN0YXJ0RG9jdW1lbnQKLSAgICoKLSAgICogJVJFVklFVyUgV0FSTklORzogVGhpcyBpcyB0aGUgZmlyc3QgdXNlIG9mIHNvbWUgb2YgdGhlIHRydW5jYXRpb24KLSAgICogbWV0aG9kcy4gIElmIFhhbGFuIGJsb3dzIHVwIGFmdGVyIHRoaXMgaXMgY2FsbGVkLCB0aGF0J3MgYSBsaWtlbHkKLSAgICogcGxhY2UgdG8gY2hlY2suCi0gICAqCi0gICAqICVSRVZJRVclIE91ciBvcmlnaW5hbCBkZXNpZ24gZm9yIERUTXMgcGVybWl0dGVkIHRoZW0gdG8gc2hhcmUKLSAgICogc3RyaW5nIHBvb2xzLiAgSWYgdGhlcmUgYW55IHJpc2sgdGhhdCB0aGlzIG1pZ2h0IGJlIGhhcHBlbmluZywgd2UKLSAgICogY2FuIF9ub3RfIHJld2luZCBhbmQgcmVjb3ZlciB0aGUgc3RyaW5nIHN0b3JhZ2UuIE9uZSBzb2x1dGlvbgotICAgKiBtaWdodCB0byBhc3NlcnQgdGhhdCBEVE1zIHVzZWQgZm9yIFJURnMgTXVzdCBOb3QgdGFrZSBhZHZhbnRhZ2UKLSAgICogb2YgdGhhdCBmZWF0dXJlLCBidXQgdGhpcyBzZWVtcyBleGNlc3NpdmVseSBmcmFnaWxlLiBBbm90aGVyLCBtdWNoCi0gICAqIGxlc3MgYXR0cmFjdGl2ZSwgd291bGQgYmUgdG8ganVzdCBsZXQgdGhlbSBsZWFrLi4uIE5haC4KLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIGFuZCBvbmx5IGlmIHRoZSBwb3AgY29tcGxldGVseSBlbXB0aWVkIHRoZQotICAgKiBSVEYuIFRoYXQgcmVzcG9uc2UgaXMgdXNlZCB3aGVuIGRldGVybWluaW5nIGhvdyB0byB1bnNwb29sCi0gICAqIFJURi1zdGFydGVkLXdoaWxlLVJURi1vcGVuIHNpdHVhdGlvbnMuCi0gICAqICovCi0gIHB1YmxpYyBib29sZWFuIHBvcFJld2luZE1hcmsoKQotICB7Ci0gICAgYm9vbGVhbiB0b3A9bWFya19zaXplLmVtcHR5KCk7Ci0KLSAgICBtX3NpemU9dG9wID8gbV9lbXB0eU5vZGVDb3VudCA6IG1hcmtfc2l6ZS5wb3AoKTsKLSAgICBtX2V4cHR5cGUuc2V0U2l6ZShtX3NpemUpOwotICAgIG1fZmlyc3RjaC5zZXRTaXplKG1fc2l6ZSk7Ci0gICAgbV9uZXh0c2liLnNldFNpemUobV9zaXplKTsKLSAgICBtX3ByZXZzaWIuc2V0U2l6ZShtX3NpemUpOwotICAgIG1fcGFyZW50LnNldFNpemUobV9zaXplKTsKLQotICAgIG1fZWxlbUluZGV4ZXM9bnVsbDsKLQotICAgIGludCBkcz0gdG9wID8gbV9lbXB0eU5TRGVjbFNldENvdW50IDogbWFya19uc2RlY2xzZXRfc2l6ZS5wb3AoKTsKLSAgICBpZiAobV9uYW1lc3BhY2VEZWNsU2V0cyE9bnVsbCkgewotICAgICAgbV9uYW1lc3BhY2VEZWNsU2V0cy5zZXRTaXplKGRzKTsKLSAgICB9Ci0KLSAgICBpbnQgZHMxPSB0b3AgPyBtX2VtcHR5TlNEZWNsU2V0RWxlbXNDb3VudCA6IG1hcmtfbnNkZWNsZWxlbV9zaXplLnBvcCgpOwotICAgIGlmIChtX25hbWVzcGFjZURlY2xTZXRFbGVtZW50cyE9bnVsbCkgewotICAgICAgbV9uYW1lc3BhY2VEZWNsU2V0RWxlbWVudHMuc2V0U2l6ZShkczEpOwotICAgIH0KLQotICAgIC8vIFZhbHVlcyBmcm9tIFNBWDJEVE0gLSBtX2RhdGEgYWx3YXlzIGhhcyBhIHJlc2VydmVkIGVudHJ5Ci0gICAgbV9kYXRhLnNldFNpemUodG9wID8gbV9lbXB0eURhdGFDb3VudCA6IG1hcmtfZGF0YV9zaXplLnBvcCgpKTsKLSAgICBtX2NoYXJzLnNldExlbmd0aCh0b3AgPyBtX2VtcHR5Q2hhcnNDb3VudCA6IG1hcmtfY2hhcl9zaXplLnBvcCgpKTsKLSAgICBtX2RhdGFPclFOYW1lLnNldFNpemUodG9wID8gbV9lbXB0eURhdGFRTkNvdW50IDogbWFya19kb3Ffc2l6ZS5wb3AoKSk7Ci0KLSAgICAvLyBSZXR1cm4gdHJ1ZSBpZmYgRFRNIG5vdyBlbXB0eQotICAgIHJldHVybiBtX3NpemU9PTA7Ci0gIH0KLQotICAvKiogQHJldHVybiB0cnVlIGlmIGEgRFRNIHRyZWUgaXMgY3VycmVudGx5IHVuZGVyIGNvbnN0cnVjdGlvbi4KLSAgICogKi8KLSAgcHVibGljIGJvb2xlYW4gaXNUcmVlSW5jb21wbGV0ZSgpCi0gIHsKLSAgICByZXR1cm4gIW1fZW5kRG9jdW1lbnRPY2N1cmVkOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9yZXMvWE1MRXJyb3JSZXNvdXJjZXMuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3Jlcy9YTUxFcnJvclJlc291cmNlcy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxYzgzYmM1Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3Jlcy9YTUxFcnJvclJlc291cmNlcy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDUwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXM7Ci0KLQotaW1wb3J0IGphdmEudXRpbC5MaXN0UmVzb3VyY2VCdW5kbGU7Ci0KLS8qKgotICogU2V0IHVwIGVycm9yIG1lc3NhZ2VzLgotICogV2UgYnVpbGQgYSB0d28gZGltZW5zaW9uYWwgYXJyYXkgb2YgbWVzc2FnZSBrZXlzIGFuZAotICogbWVzc2FnZSBzdHJpbmdzLiBJbiBvcmRlciB0byBhZGQgYSBuZXcgbWVzc2FnZSBoZXJlLAotICogeW91IG5lZWQgdG8gZmlyc3QgYWRkIGEgU3RyaW5nIGNvbnN0YW50LiBBbmQgeW91IG5lZWQKLSAqIHRvIGVudGVyIGtleSwgdmFsdWUgcGFpciBhcyBwYXJ0IG9mIHRoZSBjb250ZW50cwotICogYXJyYXkuIFlvdSBhbHNvIG5lZWQgdG8gdXBkYXRlIE1BWF9DT0RFIGZvciBlcnJvciBzdHJpbmdzCi0gKiBhbmQgTUFYX1dBUk5JTkcgZm9yIHdhcm5pbmdzICggTmVlZGVkIGZvciBvbmx5IGluZm9ybWF0aW9uCi0gKiBwdXJwb3NlICkKLSAqLwotcHVibGljIGNsYXNzIFhNTEVycm9yUmVzb3VyY2VzIGV4dGVuZHMgTGlzdFJlc291cmNlQnVuZGxlCi17Ci0KLS8qCi0gKiBUaGlzIGZpbGUgY29udGFpbnMgZXJyb3IgYW5kIHdhcm5pbmcgbWVzc2FnZXMgcmVsYXRlZCB0byBYYWxhbiBFcnJvcgotICogSGFuZGxpbmcuCi0gKgotICogIEdlbmVyYWwgbm90ZXMgdG8gdHJhbnNsYXRvcnM6Ci0gKgotICogIDEpIFhhbGFuIChvciBtb3JlIHByb3Blcmx5LCBYYWxhbi1pbnRlcnByZXRpdmUpIGFuZCBYU0xUQyBhcmUgbmFtZXMgb2YKLSAqICAgICBjb21wb25lbnRzLgotICogICAgIFhTTFQgaXMgYW4gYWNyb255bSBmb3IgIlhNTCBTdHlsZXNoZWV0IExhbmd1YWdlOiBUcmFuc2Zvcm1hdGlvbnMiLgotICogICAgIFhTTFRDIGlzIGFuIGFjcm9ueW0gZm9yIFhTTFQgQ29tcGlsZXIuCi0gKgotICogIDIpIEEgc3R5bGVzaGVldCBpcyBhIGRlc2NyaXB0aW9uIG9mIGhvdyB0byB0cmFuc2Zvcm0gYW4gaW5wdXQgWE1MIGRvY3VtZW50Ci0gKiAgICAgaW50byBhIHJlc3VsdGFudCBYTUwgZG9jdW1lbnQgKG9yIEhUTUwgZG9jdW1lbnQgb3IgdGV4dCkuICBUaGUKLSAqICAgICBzdHlsZXNoZWV0IGl0c2VsZiBpcyBkZXNjcmliZWQgaW4gdGhlIGZvcm0gb2YgYW4gWE1MIGRvY3VtZW50LgotICoKLSAqICAzKSBBIHRlbXBsYXRlIGlzIGEgY29tcG9uZW50IG9mIGEgc3R5bGVzaGVldCB0aGF0IGlzIHVzZWQgdG8gbWF0Y2ggYQotICogICAgIHBhcnRpY3VsYXIgcG9ydGlvbiBvZiBhbiBpbnB1dCBkb2N1bWVudCBhbmQgc3BlY2lmaWVzIHRoZSBmb3JtIG9mIHRoZQotICogICAgIGNvcnJlc3BvbmRpbmcgcG9ydGlvbiBvZiB0aGUgb3V0cHV0IGRvY3VtZW50LgotICoKLSAqICA0KSBBbiBlbGVtZW50IGlzIGEgbWFyay11cCB0YWcgaW4gYW4gWE1MIGRvY3VtZW50OyBhbiBhdHRyaWJ1dGUgaXMgYQotICogICAgIG1vZGlmaWVyIG9uIHRoZSB0YWcuICBGb3IgZXhhbXBsZSwgaW4gPGVsZW0gYXR0cj0ndmFsJyBhdHRyMj0ndmFsMic+Ci0gKiAgICAgImVsZW0iIGlzIGFuIGVsZW1lbnQgbmFtZSwgImF0dHIiIGFuZCAiYXR0cjIiIGFyZSBhdHRyaWJ1dGUgbmFtZXMgd2l0aAotICogICAgIHRoZSB2YWx1ZXMgInZhbCIgYW5kICJ2YWwyIiwgcmVzcGVjdGl2ZWx5LgotICoKLSAqICA1KSBBIG5hbWVzcGFjZSBkZWNsYXJhdGlvbiBpcyBhIHNwZWNpYWwgYXR0cmlidXRlIHRoYXQgaXMgdXNlZCB0byBhc3NvY2lhdGUKLSAqICAgICBhIHByZWZpeCB3aXRoIGEgVVJJICh0aGUgbmFtZXNwYWNlKS4gIFRoZSBtZWFuaW5ncyBvZiBlbGVtZW50IG5hbWVzIGFuZAotICogICAgIGF0dHJpYnV0ZSBuYW1lcyB0aGF0IHVzZSB0aGF0IHByZWZpeCBhcmUgZGVmaW5lZCB3aXRoIHJlc3BlY3QgdG8gdGhhdAotICogICAgIG5hbWVzcGFjZS4KLSAqCi0gKiAgNikgIlRyYW5zbGV0IiBpcyBhbiBpbnZlbnRlZCB0ZXJtIHRoYXQgZGVzY3JpYmVzIHRoZSBjbGFzcyBmaWxlIHRoYXQKLSAqICAgICByZXN1bHRzIGZyb20gY29tcGlsaW5nIGFuIFhNTCBzdHlsZXNoZWV0IGludG8gYSBKYXZhIGNsYXNzLgotICoKLSAqICA3KSBYUGF0aCBpcyBhIHNwZWNpZmljYXRpb24gdGhhdCBkZXNjcmliZXMgYSBub3RhdGlvbiBmb3IgaWRlbnRpZnlpbmcKLSAqICAgICBub2RlcyBpbiBhIHRyZWUtc3RydWN0dXJlZCByZXByZXNlbnRhdGlvbiBvZiBhbiBYTUwgZG9jdW1lbnQuICBBbgotICogICAgIGluc3RhbmNlIG9mIHRoYXQgbm90YXRpb24gaXMgcmVmZXJyZWQgdG8gYXMgYW4gWFBhdGggZXhwcmVzc2lvbi4KLSAqCi0gKi8KLQotICAvKiogTWF4aW11bSBlcnJvciBtZXNzYWdlcywgdGhpcyBpcyBuZWVkZWQgdG8ga2VlcCB0cmFjayBvZiB0aGUgbnVtYmVyIG9mIG1lc3NhZ2VzLiAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVhfQ09ERSA9IDYxOwotCi0gIC8qKiBNYXhpbXVtIHdhcm5pbmdzLCB0aGlzIGlzIG5lZWRlZCB0byBrZWVwIHRyYWNrIG9mIHRoZSBudW1iZXIgb2Ygd2FybmluZ3MuICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BWF9XQVJOSU5HID0gMDsKLQotICAvKiogTWF4aW11bSBtaXNjIHN0cmluZ3MuICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFYX09USEVSUyA9IDQ7Ci0KLSAgLyoqIE1heGltdW0gdG90YWwgd2FybmluZ3MgYW5kIGVycm9yIG1lc3NhZ2VzLiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVhfTUVTU0FHRVMgPSBNQVhfQ09ERSArIE1BWF9XQVJOSU5HICsgMTsKLQotCi0gIC8qCi0gICAqIE1lc3NhZ2Uga2V5cwotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCA9ICJFUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX09WRVJXUklURV9DQVVTRSA9ICJFUl9DQU5OT1RfT1ZFUldSSVRFX0NBVVNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fREVGQVVMVF9JTVBMID0gIkVSX05PX0RFRkFVTFRfSU1QTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NIVU5LRURJTlRBUlJBWV9OT1RfU1VQUE9SVEVEID0gIkVSX0NIVU5LRURJTlRBUlJBWV9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfT0ZGU0VUX0JJR0dFUl9USEFOX1NMT1QgPSAiRVJfT0ZGU0VUX0JJR0dFUl9USEFOX1NMT1QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1JPVVRJTkVfTk9UX0FWQUlMID0gIkVSX0NPUk9VVElORV9OT1RfQVZBSUwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1JPVVRJTkVfQ09fRVhJVCA9ICJFUl9DT1JPVVRJTkVfQ09fRVhJVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPSk9JTlJPVVRJTkVTRVRfRkFJTEVEID0gIkVSX0NPSk9JTlJPVVRJTkVTRVRfRkFJTEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09ST1VUSU5FX1BBUkFNID0gIkVSX0NPUk9VVElORV9QQVJBTSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BBUlNFUl9ET1RFUk1JTkFURV9BTlNXRVJTID0gIkVSX1BBUlNFUl9ET1RFUk1JTkFURV9BTlNXRVJTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fUEFSU0VfQ0FMTF9XSElMRV9QQVJTSU5HID0gIkVSX05PX1BBUlNFX0NBTExfV0hJTEVfUEFSU0lORyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1RZUEVEX0lURVJBVE9SX0FYSVNfTk9UX0lNUExFTUVOVEVEID0gIkVSX1RZUEVEX0lURVJBVE9SX0FYSVNfTk9UX0lNUExFTUVOVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSVRFUkFUT1JfQVhJU19OT1RfSU1QTEVNRU5URUQgPSAiRVJfSVRFUkFUT1JfQVhJU19OT1RfSU1QTEVNRU5URUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JVEVSQVRPUl9DTE9ORV9OT1RfU1VQUE9SVEVEID0gIkVSX0lURVJBVE9SX0NMT05FX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTktOT1dOX0FYSVNfVFlQRSA9ICJFUl9VTktOT1dOX0FYSVNfVFlQRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FYSVNfTk9UX1NVUFBPUlRFRCA9ICJFUl9BWElTX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19EVE1JRFNfQVZBSUwgPSAiRVJfTk9fRFRNSURTX0FWQUlMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9UX1NVUFBPUlRFRCA9ICJFUl9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9ERV9OT05fTlVMTCA9ICJFUl9OT0RFX05PTl9OVUxMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTERfTk9UX1JFU09MVkVfTk9ERSA9ICJFUl9DT1VMRF9OT1RfUkVTT0xWRV9OT0RFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU1RBUlRQQVJTRV9XSElMRV9QQVJTSU5HID0gIkVSX1NUQVJUUEFSU0VfV0hJTEVfUEFSU0lORyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NUQVJUUEFSU0VfTkVFRFNfU0FYUEFSU0VSID0gIkVSX1NUQVJUUEFSU0VfTkVFRFNfU0FYUEFSU0VSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTERfTk9UX0lOSVRfUEFSU0VSID0gIkVSX0NPVUxEX05PVF9JTklUX1BBUlNFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYQ0VQVElPTl9DUkVBVElOR19QT09MID0gIkVSX0VYQ0VQVElPTl9DUkVBVElOR19QT09MIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUEFUSF9DT05UQUlOU19JTlZBTElEX0VTQ0FQRV9TRVFVRU5DRSA9ICJFUl9QQVRIX0NPTlRBSU5TX0lOVkFMSURfRVNDQVBFX1NFUVVFTkNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU0NIRU1FX1JFUVVJUkVEID0gIkVSX1NDSEVNRV9SRVFVSVJFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1NDSEVNRV9JTl9VUkkgPSAiRVJfTk9fU0NIRU1FX0lOX1VSSSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1NDSEVNRV9JTlVSSSA9ICJFUl9OT19TQ0hFTUVfSU5VUkkiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QQVRIX0lOVkFMSURfQ0hBUiA9ICJFUl9QQVRIX0lOVkFMSURfQ0hBUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NDSEVNRV9GUk9NX05VTExfU1RSSU5HID0gIkVSX1NDSEVNRV9GUk9NX05VTExfU1RSSU5HIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU0NIRU1FX05PVF9DT05GT1JNQU5UID0gIkVSX1NDSEVNRV9OT1RfQ09ORk9STUFOVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0hPU1RfQUREUkVTU19OT1RfV0VMTEZPUk1FRCA9ICJFUl9IT1NUX0FERFJFU1NfTk9UX1dFTExGT1JNRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QT1JUX1dIRU5fSE9TVF9OVUxMID0gIkVSX1BPUlRfV0hFTl9IT1NUX05VTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX1BPUlQgPSAiRVJfSU5WQUxJRF9QT1JUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRlJBR19GT1JfR0VORVJJQ19VUkkgPSJFUl9GUkFHX0ZPUl9HRU5FUklDX1VSSSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZSQUdfV0hFTl9QQVRIX05VTEwgPSAiRVJfRlJBR19XSEVOX1BBVEhfTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZSQUdfSU5WQUxJRF9DSEFSID0gIkVSX0ZSQUdfSU5WQUxJRF9DSEFSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUEFSU0VSX0lOX1VTRSA9ICJFUl9QQVJTRVJfSU5fVVNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX0NIQU5HRV9XSElMRV9QQVJTSU5HID0gIkVSX0NBTk5PVF9DSEFOR0VfV0hJTEVfUEFSU0lORyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NFTEZfQ0FVU0FUSU9OX05PVF9QRVJNSVRURUQgPSAiRVJfU0VMRl9DQVVTQVRJT05fTk9UX1BFUk1JVFRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1VTRVJJTkZPX0lGX05PX0hPU1QgPSAiRVJfTk9fVVNFUklORk9fSUZfTk9fSE9TVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1BPUlRfSUZfTk9fSE9TVCA9ICJFUl9OT19QT1JUX0lGX05PX0hPU1QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19RVUVSWV9TVFJJTkdfSU5fUEFUSCA9ICJFUl9OT19RVUVSWV9TVFJJTkdfSU5fUEFUSCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX0ZSQUdNRU5UX1NUUklOR19JTl9QQVRIID0gIkVSX05PX0ZSQUdNRU5UX1NUUklOR19JTl9QQVRIIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX0lOSVRfVVJJX0VNUFRZX1BBUk1TID0gIkVSX0NBTk5PVF9JTklUX1VSSV9FTVBUWV9QQVJNUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01FVEhPRF9OT1RfU1VQUE9SVEVEID0iRVJfTUVUSE9EX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTkNSU0FYU1JDRklMVEVSX05PVF9SRVNUQVJUQUJMRSA9ICJFUl9JTkNSU0FYU1JDRklMVEVSX05PVF9SRVNUQVJUQUJMRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hNTFJEUl9OT1RfQkVGT1JFX1NUQVJUUEFSU0UgPSAiRVJfWE1MUkRSX05PVF9CRUZPUkVfU1RBUlRQQVJTRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FYSVNfVFJBVkVSU0VSX05PVF9TVVBQT1JURUQgPSAiRVJfQVhJU19UUkFWRVJTRVJfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VSUk9SSEFORExFUl9DUkVBVEVEX1dJVEhfTlVMTF9QUklOVFdSSVRFUiA9ICJFUl9FUlJPUkhBTkRMRVJfQ1JFQVRFRF9XSVRIX05VTExfUFJJTlRXUklURVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TWVNURU1JRF9VTktOT1dOID0gIkVSX1NZU1RFTUlEX1VOS05PV04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9MT0NBVElPTl9VTktOT1dOID0gIkVSX0xPQ0FUSU9OX1VOS05PV04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUkVGSVhfTVVTVF9SRVNPTFZFID0gIkVSX1BSRUZJWF9NVVNUX1JFU09MVkUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DUkVBVEVET0NVTUVOVF9OT1RfU1VQUE9SVEVEID0gIkVSX0NSRUFURURPQ1VNRU5UX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DSElMRF9IQVNfTk9fT1dORVJfRE9DVU1FTlQgPSAiRVJfQ0hJTERfSEFTX05PX09XTkVSX0RPQ1VNRU5UIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0hJTERfSEFTX05PX09XTkVSX0RPQ1VNRU5UX0VMRU1FTlQgPSAiRVJfQ0hJTERfSEFTX05PX09XTkVSX0RPQ1VNRU5UX0VMRU1FTlQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX09VVFBVVF9URVhUX0JFRk9SRV9ET0MgPSAiRVJfQ0FOVF9PVVRQVVRfVEVYVF9CRUZPUkVfRE9DIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9IQVZFX01PUkVfVEhBTl9PTkVfUk9PVCA9ICJFUl9DQU5UX0hBVkVfTU9SRV9USEFOX09ORV9ST09UIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQVJHX0xPQ0FMTkFNRV9OVUxMID0gIkVSX0FSR19MT0NBTE5BTUVfTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FSR19MT0NBTE5BTUVfSU5WQUxJRCA9ICJFUl9BUkdfTE9DQUxOQU1FX0lOVkFMSUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9BUkdfUFJFRklYX0lOVkFMSUQgPSAiRVJfQVJHX1BSRUZJWF9JTlZBTElEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTkFNRV9DQU5UX1NUQVJUX1dJVEhfQ09MT04gPSAiRVJfTkFNRV9DQU5UX1NUQVJUX1dJVEhfQ09MT04iOwotCi0gIC8vIE1lc3NhZ2Uga2V5cyB1c2VkIGJ5IHRoZSBzZXJpYWxpemVyCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1JFU09VUkNFX0NPVUxEX05PVF9GSU5EID0gIkVSX1JFU09VUkNFX0NPVUxEX05PVF9GSU5EIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUkVTT1VSQ0VfQ09VTERfTk9UX0xPQUQgPSAiRVJfUkVTT1VSQ0VfQ09VTERfTk9UX0xPQUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9CVUZGRVJfU0laRV9MRVNTVEhBTl9aRVJPID0gIkVSX0JVRkZFUl9TSVpFX0xFU1NUSEFOX1pFUk8iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX1VURjE2X1NVUlJPR0FURSA9ICJFUl9JTlZBTElEX1VURjE2X1NVUlJPR0FURSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX09JRVJST1IgPSAiRVJfT0lFUlJPUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05BTUVTUEFDRV9QUkVGSVggPSAiRVJfTkFNRVNQQUNFX1BSRUZJWCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NUUkFZX0FUVFJJQlVURSA9ICJFUl9TVFJBWV9BVFRJUkJVVEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TVFJBWV9OQU1FU1BBQ0UgPSAiRVJfU1RSQVlfTkFNRVNQQUNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTERfTk9UX0xPQURfUkVTT1VSQ0UgPSAiRVJfQ09VTERfTk9UX0xPQURfUkVTT1VSQ0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRF9OT1RfTE9BRF9NRVRIT0RfUFJPUEVSVFkgPSAiRVJfQ09VTERfTk9UX0xPQURfTUVUSE9EX1BST1BFUlRZIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU0VSSUFMSVpFUl9OT1RfQ09OVEVOVEhBTkRMRVIgPSAiRVJfU0VSSUFMSVpFUl9OT1RfQ09OVEVOVEhBTkRMRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTExFR0FMX0FUVFJJQlVURV9QT1NJVElPTiA9ICJFUl9JTExFR0FMX0FUVFJJQlVURV9QT1NJVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lMTEVHQUxfQ0hBUkFDVEVSID0gIkVSX0lMTEVHQUxfQ0hBUkFDVEVSIjsKLQotICAvKgotICAgKiBOb3cgZmlsbCBpbiB0aGUgbWVzc2FnZSB0ZXh0LgotICAgKiBUaGVuIGZpbGwgaW4gdGhlIG1lc3NhZ2UgdGV4dCBmb3IgdGhhdCBtZXNzYWdlIGNvZGUgaW4gdGhlCi0gICAqIGFycmF5LiBVc2UgdGhlIG5ldyBlcnJvciBjb2RlIGFzIHRoZSBpbmRleCBpbnRvIHRoZSBhcnJheS4KLSAgICovCi0KLSAgLy8gRXJyb3IgbWVzc2FnZXMuLi4KLQotICAvKiogVGhlIGxvb2t1cCB0YWJsZSBmb3IgZXJyb3IgbWVzc2FnZXMuICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgT2JqZWN0W11bXSBjb250ZW50cyA9IHsKLQotICAvKiogRXJyb3IgbWVzc2FnZSBJRCB0aGF0IGhhcyBhIG51bGwgbWVzc2FnZSwgYnV0IHRha2VzIGluIGEgc2luZ2xlIG9iamVjdC4gICAgKi8KLSAgICB7IkVSMDAwMCIgLCAiezB9IiB9LAotCi0gICAgeyBFUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVELAotICAgICAgIkZ1bmN0aW9uIG5vdCBzdXBwb3J0ZWQhIn0sCi0KLSAgICB7IEVSX0NBTk5PVF9PVkVSV1JJVEVfQ0FVU0UsCi0gICAgICAiQ2Fubm90IG92ZXJ3cml0ZSBjYXVzZSJ9LAotCi0gICAgeyBFUl9OT19ERUZBVUxUX0lNUEwsCi0gICAgICAiTm8gZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBmb3VuZCAifSwKLQotICAgIHsgRVJfQ0hVTktFRElOVEFSUkFZX05PVF9TVVBQT1JURUQsCi0gICAgICAiQ2h1bmtlZEludEFycmF5KHswfSkgbm90IGN1cnJlbnRseSBzdXBwb3J0ZWQifSwKLQotICAgIHsgRVJfT0ZGU0VUX0JJR0dFUl9USEFOX1NMT1QsCi0gICAgICAiT2Zmc2V0IGJpZ2dlciB0aGFuIHNsb3QifSwKLQotICAgIHsgRVJfQ09ST1VUSU5FX05PVF9BVkFJTCwKLSAgICAgICJDb3JvdXRpbmUgbm90IGF2YWlsYWJsZSwgaWQ9ezB9In0sCi0KLSAgICB7IEVSX0NPUk9VVElORV9DT19FWElULAotICAgICAgIkNvcm91dGluZU1hbmFnZXIgcmVjZWl2ZWQgY29fZXhpdCgpIHJlcXVlc3QifSwKLQotICAgIHsgRVJfQ09KT0lOUk9VVElORVNFVF9GQUlMRUQsCi0gICAgICAiY29fam9pbkNvcm91dGluZVNldCgpIGZhaWxlZCJ9LAotCi0gICAgeyBFUl9DT1JPVVRJTkVfUEFSQU0sCi0gICAgICAiQ29yb3V0aW5lIHBhcmFtZXRlciBlcnJvciAoezB9KSJ9LAotCi0gICAgeyBFUl9QQVJTRVJfRE9URVJNSU5BVEVfQU5TV0VSUywKLSAgICAgICJcblVORVhQRUNURUQ6IFBhcnNlciBkb1Rlcm1pbmF0ZSBhbnN3ZXJzIHswfSJ9LAotCi0gICAgeyBFUl9OT19QQVJTRV9DQUxMX1dISUxFX1BBUlNJTkcsCi0gICAgICAicGFyc2UgbWF5IG5vdCBiZSBjYWxsZWQgd2hpbGUgcGFyc2luZyJ9LAotCi0gICAgeyBFUl9UWVBFRF9JVEVSQVRPUl9BWElTX05PVF9JTVBMRU1FTlRFRCwKLSAgICAgICJFcnJvcjogdHlwZWQgaXRlcmF0b3IgZm9yIGF4aXMgIHswfSBub3QgaW1wbGVtZW50ZWQifSwKLQotICAgIHsgRVJfSVRFUkFUT1JfQVhJU19OT1RfSU1QTEVNRU5URUQsCi0gICAgICAiRXJyb3I6IGl0ZXJhdG9yIGZvciBheGlzIHswfSBub3QgaW1wbGVtZW50ZWQgIn0sCi0KLSAgICB7IEVSX0lURVJBVE9SX0NMT05FX05PVF9TVVBQT1JURUQsCi0gICAgICAiSXRlcmF0b3IgY2xvbmUgbm90IHN1cHBvcnRlZCJ9LAotCi0gICAgeyBFUl9VTktOT1dOX0FYSVNfVFlQRSwKLSAgICAgICJVbmtub3duIGF4aXMgdHJhdmVyc2FsIHR5cGU6IHswfSJ9LAotCi0gICAgeyBFUl9BWElTX05PVF9TVVBQT1JURUQsCi0gICAgICAiQXhpcyB0cmF2ZXJzZXIgbm90IHN1cHBvcnRlZDogezB9In0sCi0KLSAgICB7IEVSX05PX0RUTUlEU19BVkFJTCwKLSAgICAgICJObyBtb3JlIERUTSBJRHMgYXJlIGF2YWlsYWJsZSJ9LAotCi0gICAgeyBFUl9OT1RfU1VQUE9SVEVELAotICAgICAgIk5vdCBzdXBwb3J0ZWQ6IHswfSJ9LAotCi0gICAgeyBFUl9OT0RFX05PTl9OVUxMLAotICAgICAgIk5vZGUgbXVzdCBiZSBub24tbnVsbCBmb3IgZ2V0RFRNSGFuZGxlRnJvbU5vZGUifSwKLQotICAgIHsgRVJfQ09VTERfTk9UX1JFU09MVkVfTk9ERSwKLSAgICAgICJDb3VsZCBub3QgcmVzb2x2ZSB0aGUgbm9kZSB0byBhIGhhbmRsZSJ9LAotCi0gICAgeyBFUl9TVEFSVFBBUlNFX1dISUxFX1BBUlNJTkcsCi0gICAgICAgInN0YXJ0UGFyc2UgbWF5IG5vdCBiZSBjYWxsZWQgd2hpbGUgcGFyc2luZyJ9LAotCi0gICAgeyBFUl9TVEFSVFBBUlNFX05FRURTX1NBWFBBUlNFUiwKLSAgICAgICAic3RhcnRQYXJzZSBuZWVkcyBhIG5vbi1udWxsIFNBWFBhcnNlciJ9LAotCi0gICAgeyBFUl9DT1VMRF9OT1RfSU5JVF9QQVJTRVIsCi0gICAgICAgImNvdWxkIG5vdCBpbml0aWFsaXplIHBhcnNlciB3aXRoIn0sCi0KLSAgICB7IEVSX0VYQ0VQVElPTl9DUkVBVElOR19QT09MLAotICAgICAgICJleGNlcHRpb24gY3JlYXRpbmcgbmV3IGluc3RhbmNlIGZvciBwb29sIn0sCi0KLSAgICB7IEVSX1BBVEhfQ09OVEFJTlNfSU5WQUxJRF9FU0NBUEVfU0VRVUVOQ0UsCi0gICAgICAgIlBhdGggY29udGFpbnMgaW52YWxpZCBlc2NhcGUgc2VxdWVuY2UifSwKLQotICAgIHsgRVJfU0NIRU1FX1JFUVVJUkVELAotICAgICAgICJTY2hlbWUgaXMgcmVxdWlyZWQhIn0sCi0KLSAgICB7IEVSX05PX1NDSEVNRV9JTl9VUkksCi0gICAgICAgIk5vIHNjaGVtZSBmb3VuZCBpbiBVUkk6IHswfSJ9LAotCi0gICAgeyBFUl9OT19TQ0hFTUVfSU5VUkksCi0gICAgICAgIk5vIHNjaGVtZSBmb3VuZCBpbiBVUkkifSwKLQotICAgIHsgRVJfUEFUSF9JTlZBTElEX0NIQVIsCi0gICAgICAgIlBhdGggY29udGFpbnMgaW52YWxpZCBjaGFyYWN0ZXI6IHswfSJ9LAotCi0gICAgeyBFUl9TQ0hFTUVfRlJPTV9OVUxMX1NUUklORywKLSAgICAgICAiQ2Fubm90IHNldCBzY2hlbWUgZnJvbSBudWxsIHN0cmluZyJ9LAotCi0gICAgeyBFUl9TQ0hFTUVfTk9UX0NPTkZPUk1BTlQsCi0gICAgICAgIlRoZSBzY2hlbWUgaXMgbm90IGNvbmZvcm1hbnQuIn0sCi0KLSAgICB7IEVSX0hPU1RfQUREUkVTU19OT1RfV0VMTEZPUk1FRCwKLSAgICAgICAiSG9zdCBpcyBub3QgYSB3ZWxsIGZvcm1lZCBhZGRyZXNzIn0sCi0KLSAgICB7IEVSX1BPUlRfV0hFTl9IT1NUX05VTEwsCi0gICAgICAgIlBvcnQgY2Fubm90IGJlIHNldCB3aGVuIGhvc3QgaXMgbnVsbCJ9LAotCi0gICAgeyBFUl9JTlZBTElEX1BPUlQsCi0gICAgICAgIkludmFsaWQgcG9ydCBudW1iZXIifSwKLQotICAgIHsgRVJfRlJBR19GT1JfR0VORVJJQ19VUkksCi0gICAgICAgIkZyYWdtZW50IGNhbiBvbmx5IGJlIHNldCBmb3IgYSBnZW5lcmljIFVSSSJ9LAotCi0gICAgeyBFUl9GUkFHX1dIRU5fUEFUSF9OVUxMLAotICAgICAgICJGcmFnbWVudCBjYW5ub3QgYmUgc2V0IHdoZW4gcGF0aCBpcyBudWxsIn0sCi0KLSAgICB7IEVSX0ZSQUdfSU5WQUxJRF9DSEFSLAotICAgICAgICJGcmFnbWVudCBjb250YWlucyBpbnZhbGlkIGNoYXJhY3RlciJ9LAotCi0gICAgeyBFUl9QQVJTRVJfSU5fVVNFLAotICAgICAgIlBhcnNlciBpcyBhbHJlYWR5IGluIHVzZSJ9LAotCi0gICAgeyBFUl9DQU5OT1RfQ0hBTkdFX1dISUxFX1BBUlNJTkcsCi0gICAgICAiQ2Fubm90IGNoYW5nZSB7MH0gezF9IHdoaWxlIHBhcnNpbmcifSwKLQotICAgIHsgRVJfU0VMRl9DQVVTQVRJT05fTk9UX1BFUk1JVFRFRCwKLSAgICAgICJTZWxmLWNhdXNhdGlvbiBub3QgcGVybWl0dGVkIn0sCi0KLSAgICB7IEVSX05PX1VTRVJJTkZPX0lGX05PX0hPU1QsCi0gICAgICAiVXNlcmluZm8gbWF5IG5vdCBiZSBzcGVjaWZpZWQgaWYgaG9zdCBpcyBub3Qgc3BlY2lmaWVkIn0sCi0KLSAgICB7IEVSX05PX1BPUlRfSUZfTk9fSE9TVCwKLSAgICAgICJQb3J0IG1heSBub3QgYmUgc3BlY2lmaWVkIGlmIGhvc3QgaXMgbm90IHNwZWNpZmllZCJ9LAotCi0gICAgeyBFUl9OT19RVUVSWV9TVFJJTkdfSU5fUEFUSCwKLSAgICAgICJRdWVyeSBzdHJpbmcgY2Fubm90IGJlIHNwZWNpZmllZCBpbiBwYXRoIGFuZCBxdWVyeSBzdHJpbmcifSwKLQotICAgIHsgRVJfTk9fRlJBR01FTlRfU1RSSU5HX0lOX1BBVEgsCi0gICAgICAiRnJhZ21lbnQgY2Fubm90IGJlIHNwZWNpZmllZCBpbiBib3RoIHRoZSBwYXRoIGFuZCBmcmFnbWVudCJ9LAotCi0gICAgeyBFUl9DQU5OT1RfSU5JVF9VUklfRU1QVFlfUEFSTVMsCi0gICAgICAiQ2Fubm90IGluaXRpYWxpemUgVVJJIHdpdGggZW1wdHkgcGFyYW1ldGVycyJ9LAotCi0gICAgeyBFUl9NRVRIT0RfTk9UX1NVUFBPUlRFRCwKLSAgICAgICJNZXRob2Qgbm90IHlldCBzdXBwb3J0ZWQgIn0sCi0KLSAgICB7IEVSX0lOQ1JTQVhTUkNGSUxURVJfTk9UX1JFU1RBUlRBQkxFLAotICAgICAgIkluY3JlbWVudGFsU0FYU291cmNlX0ZpbHRlciBub3QgY3VycmVudGx5IHJlc3RhcnRhYmxlIn0sCi0KLSAgICB7IEVSX1hNTFJEUl9OT1RfQkVGT1JFX1NUQVJUUEFSU0UsCi0gICAgICAiWE1MUmVhZGVyIG5vdCBiZWZvcmUgc3RhcnRQYXJzZSByZXF1ZXN0In0sCi0KLSAgICB7IEVSX0FYSVNfVFJBVkVSU0VSX05PVF9TVVBQT1JURUQsCi0gICAgICAiQXhpcyB0cmF2ZXJzZXIgbm90IHN1cHBvcnRlZDogezB9In0sCi0KLSAgICB7IEVSX0VSUk9SSEFORExFUl9DUkVBVEVEX1dJVEhfTlVMTF9QUklOVFdSSVRFUiwKLSAgICAgICJMaXN0aW5nRXJyb3JIYW5kbGVyIGNyZWF0ZWQgd2l0aCBudWxsIFByaW50V3JpdGVyISJ9LAotCi0gICAgeyBFUl9TWVNURU1JRF9VTktOT1dOLAotICAgICAgIlN5c3RlbUlkIFVua25vd24ifSwKLQotICAgIHsgRVJfTE9DQVRJT05fVU5LTk9XTiwKLSAgICAgICJMb2NhdGlvbiBvZiBlcnJvciB1bmtub3duIn0sCi0KLSAgICB7IEVSX1BSRUZJWF9NVVNUX1JFU09MVkUsCi0gICAgICAiUHJlZml4IG11c3QgcmVzb2x2ZSB0byBhIG5hbWVzcGFjZTogezB9In0sCi0KLSAgICB7IEVSX0NSRUFURURPQ1VNRU5UX05PVF9TVVBQT1JURUQsCi0gICAgICAiY3JlYXRlRG9jdW1lbnQoKSBub3Qgc3VwcG9ydGVkIGluIFhQYXRoQ29udGV4dCEifSwKLQotICAgIHsgRVJfQ0hJTERfSEFTX05PX09XTkVSX0RPQ1VNRU5ULAotICAgICAgIkF0dHJpYnV0ZSBjaGlsZCBkb2VzIG5vdCBoYXZlIGFuIG93bmVyIGRvY3VtZW50ISJ9LAotCi0gICAgeyBFUl9DSElMRF9IQVNfTk9fT1dORVJfRE9DVU1FTlRfRUxFTUVOVCwKLSAgICAgICJBdHRyaWJ1dGUgY2hpbGQgZG9lcyBub3QgaGF2ZSBhbiBvd25lciBkb2N1bWVudCBlbGVtZW50ISJ9LAotCi0gICAgeyBFUl9DQU5UX09VVFBVVF9URVhUX0JFRk9SRV9ET0MsCi0gICAgICAiV2FybmluZzogY2FuJ3Qgb3V0cHV0IHRleHQgYmVmb3JlIGRvY3VtZW50IGVsZW1lbnQhICBJZ25vcmluZy4uLiJ9LAotCi0gICAgeyBFUl9DQU5UX0hBVkVfTU9SRV9USEFOX09ORV9ST09ULAotICAgICAgIkNhbid0IGhhdmUgbW9yZSB0aGFuIG9uZSByb290IG9uIGEgRE9NISJ9LAotCi0gICAgeyBFUl9BUkdfTE9DQUxOQU1FX05VTEwsCi0gICAgICAgIkFyZ3VtZW50ICdsb2NhbE5hbWUnIGlzIG51bGwifSwKLQotICAgIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBIFFOQU1FIGhhcyB0aGUgc3ludGFjdGljIGZvcm0gW05DTmFtZTpdTkNOYW1lCi0gICAgLy8gVGhlIGxvY2FsbmFtZSBpcyB0aGUgcG9ydGlvbiBhZnRlciB0aGUgb3B0aW9uYWwgY29sb247IHRoZSBtZXNzYWdlIGluZGljYXRlcwotICAgIC8vIHRoYXQgdGhlcmUgaXMgYSBwcm9ibGVtIHdpdGggdGhhdCBwYXJ0IG9mIHRoZSBRTkFNRS4KLSAgICB7IEVSX0FSR19MT0NBTE5BTUVfSU5WQUxJRCwKLSAgICAgICAiTG9jYWxuYW1lIGluIFFOQU1FIHNob3VsZCBiZSBhIHZhbGlkIE5DTmFtZSJ9LAotCi0gICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIEEgUU5BTUUgaGFzIHRoZSBzeW50YWN0aWMgZm9ybSBbTkNOYW1lOl1OQ05hbWUKLSAgICAvLyBUaGUgcHJlZml4IGlzIHRoZSBwb3J0aW9uIGJlZm9yZSB0aGUgb3B0aW9uYWwgY29sb247IHRoZSBtZXNzYWdlIGluZGljYXRlcwotICAgIC8vIHRoYXQgdGhlcmUgaXMgYSBwcm9ibGVtIHdpdGggdGhhdCBwYXJ0IG9mIHRoZSBRTkFNRS4KLSAgICB7IEVSX0FSR19QUkVGSVhfSU5WQUxJRCwKLSAgICAgICAiUHJlZml4IGluIFFOQU1FIHNob3VsZCBiZSBhIHZhbGlkIE5DTmFtZSJ9LAotCi0gICAgeyBFUl9OQU1FX0NBTlRfU1RBUlRfV0lUSF9DT0xPTiwKLSAgICAgICJOYW1lIGNhbm5vdCBzdGFydCB3aXRoIGEgY29sb24ifSwKLQotICAgIHsgIkJBRF9DT0RFIiwgIlBhcmFtZXRlciB0byBjcmVhdGVNZXNzYWdlIHdhcyBvdXQgb2YgYm91bmRzIn0sCi0gICAgeyAiRk9STUFUX0ZBSUxFRCIsICJFeGNlcHRpb24gdGhyb3duIGR1cmluZyBtZXNzYWdlRm9ybWF0IGNhbGwifSwKLSAgICB7ICJsaW5lIiwgIkxpbmUgIyJ9LAotICAgIHsgImNvbHVtbiIsIkNvbHVtbiAjIn0sCi0KLSAgICB7RVJfU0VSSUFMSVpFUl9OT1RfQ09OVEVOVEhBTkRMRVIsCi0gICAgICAiVGhlIHNlcmlhbGl6ZXIgY2xhc3MgJyd7MH0nJyBkb2VzIG5vdCBpbXBsZW1lbnQgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIuIn0sCi0KLSAgICB7RVJfUkVTT1VSQ0VfQ09VTERfTk9UX0ZJTkQsCi0gICAgICAiVGhlIHJlc291cmNlIFsgezB9IF0gY291bGQgbm90IGJlIGZvdW5kLlxuIHsxfSIgfSwKLQotICAgIHtFUl9SRVNPVVJDRV9DT1VMRF9OT1RfTE9BRCwKLSAgICAgICJUaGUgcmVzb3VyY2UgWyB7MH0gXSBjb3VsZCBub3QgbG9hZDogezF9IFxuIHsyfSBcdCB7M30iIH0sCi0KLSAgICB7RVJfQlVGRkVSX1NJWkVfTEVTU1RIQU5fWkVSTywKLSAgICAgICJCdWZmZXIgc2l6ZSA8PTAiIH0sCi0KLSAgICB7RVJfSU5WQUxJRF9VVEYxNl9TVVJST0dBVEUsCi0gICAgICAiSW52YWxpZCBVVEYtMTYgc3Vycm9nYXRlIGRldGVjdGVkOiB7MH0gPyIgfSwKLQotICAgIHtFUl9PSUVSUk9SLAotICAgICAgIklPIGVycm9yIiB9LAotCi0gICAge0VSX0lMTEVHQUxfQVRUUklCVVRFX1BPU0lUSU9OLAotICAgICAgIkNhbm5vdCBhZGQgYXR0cmlidXRlIHswfSBhZnRlciBjaGlsZCBub2RlcyBvciBiZWZvcmUgYW4gZWxlbWVudCBpcyBwcm9kdWNlZC4gIEF0dHJpYnV0ZSB3aWxsIGJlIGlnbm9yZWQuIn0sCi0KLSAgICAgIC8qCi0gICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN0eWxlc2hlZXQgY29udGFpbmVkIGEgcmVmZXJlbmNlIHRvIGEKLSAgICAgICAqIG5hbWVzcGFjZSBwcmVmaXggdGhhdCB3YXMgdW5kZWZpbmVkLiAgVGhlIHZhbHVlIG9mIHRoZSBzdWJzdGl0dXRpb24KLSAgICAgICAqIHRleHQgaXMgdGhlIG5hbWUgb2YgdGhlIHByZWZpeC4KLSAgICAgICAqLwotICAgIHtFUl9OQU1FU1BBQ0VfUFJFRklYLAotICAgICAgIk5hbWVzcGFjZSBmb3IgcHJlZml4ICcnezB9JycgaGFzIG5vdCBiZWVuIGRlY2xhcmVkLiIgfSwKLSAgICAgIC8qCi0gICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIHJlcG9ydGVkIGlmIHRoZSBzdHlsZXNoZWV0Ci0gICAgICAgKiBiZWluZyBwcm9jZXNzZWQgYXR0ZW1wdGVkIHRvIGNvbnN0cnVjdCBhbiBYTUwgZG9jdW1lbnQgd2l0aCBhbgotICAgICAgICogYXR0cmlidXRlIGluIGEgcGxhY2Ugb3RoZXIgdGhhbiBvbiBhbiBlbGVtZW50LiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgKiBzcGVjaWZpZXMgdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgICAqLwotICAgIHtFUl9TVFJBWV9BVFRSSUJVVEUsCi0gICAgICAiQXR0cmlidXRlICcnezB9Jycgb3V0c2lkZSBvZiBlbGVtZW50LiIgfSwKLQotICAgICAgLyoKLSAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBcyB3aXRoIHRoZSBwcmVjZWRpbmcgbWVzc2FnZSwgYSBuYW1lc3BhY2UKLSAgICAgICAqIGRlY2xhcmF0aW9uIGhhcyB0aGUgZm9ybSBvZiBhbiBhdHRyaWJ1dGUgYW5kIGlzIG9ubHkgcGVybWl0dGVkIHRvCi0gICAgICAgKiBhcHBlYXIgb24gYW4gZWxlbWVudC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCB7MH0gaXMgdGhlIG5hbWVzcGFjZQotICAgICAgICogcHJlZml4IGFuZCB7MX0gaXMgdGhlIFVSSSB0aGF0IHdhcyBiZWluZyB1c2VkIGluIHRoZSBlcnJvbmVvdXMKLSAgICAgICAqIG5hbWVzcGFjZSBkZWNsYXJhdGlvbi4KLSAgICAgICAqLwotICAgIHtFUl9TVFJBWV9OQU1FU1BBQ0UsCi0gICAgICAiTmFtZXNwYWNlIGRlY2xhcmF0aW9uICcnezB9Jyc9Jyd7MX0nJyBvdXRzaWRlIG9mIGVsZW1lbnQuIiB9LAotCi0gICAge0VSX0NPVUxEX05PVF9MT0FEX1JFU09VUkNFLAotICAgICAgIkNvdWxkIG5vdCBsb2FkICcnezB9JycgKGNoZWNrIENMQVNTUEFUSCksIG5vdyB1c2luZyBqdXN0IHRoZSBkZWZhdWx0cyJ9LAotCi0gICAgeyBFUl9JTExFR0FMX0NIQVJBQ1RFUiwKLSAgICAgICAiQXR0ZW1wdCB0byBvdXRwdXQgY2hhcmFjdGVyIG9mIGludGVncmFsIHZhbHVlIHswfSB0aGF0IGlzIG5vdCByZXByZXNlbnRlZCBpbiBzcGVjaWZpZWQgb3V0cHV0IGVuY29kaW5nIG9mIHsxfS4ifSwKLQotICAgIHtFUl9DT1VMRF9OT1RfTE9BRF9NRVRIT0RfUFJPUEVSVFksCi0gICAgICAiQ291bGQgbm90IGxvYWQgdGhlIHByb3BlcnkgZmlsZSAnJ3swfScnIGZvciBvdXRwdXQgbWV0aG9kICcnezF9JycgKGNoZWNrIENMQVNTUEFUSCkiIH0KLQotCi0gIH07Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgYXNzb2NpYXRpb24gbGlzdC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgYXNzb2NpYXRpb24gbGlzdC4KLSAgICovCi0KLSAgICBwcm90ZWN0ZWQgT2JqZWN0W11bXSBnZXRDb250ZW50cygpIHsKLSAgICAgICAgcmV0dXJuIGNvbnRlbnRzOwotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvcmVzL1hNTEVycm9yUmVzb3VyY2VzX2NhLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9yZXMvWE1MRXJyb3JSZXNvdXJjZXNfY2EuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNWRjYjI3Yy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9yZXMvWE1MRXJyb3JSZXNvdXJjZXNfY2EuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQ0MyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBYTUxFcnJvclJlc291cmNlc19jYS5qYXZhLHYgMS4xLjYuMiAyMDA1LzA5LzE1IDA3OjQ1OjM3IHN1cmVzaF9lbWFpbGlkIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXM7Ci0KLQotaW1wb3J0IGphdmEudXRpbC5MaXN0UmVzb3VyY2VCdW5kbGU7Ci0KLS8qKgotICogU2V0IHVwIGVycm9yIG1lc3NhZ2VzLgotICogV2UgYnVpbGQgYSB0d28gZGltZW5zaW9uYWwgYXJyYXkgb2YgbWVzc2FnZSBrZXlzIGFuZAotICogbWVzc2FnZSBzdHJpbmdzLiBJbiBvcmRlciB0byBhZGQgYSBuZXcgbWVzc2FnZSBoZXJlLAotICogeW91IG5lZWQgdG8gZmlyc3QgYWRkIGEgU3RyaW5nIGNvbnN0YW50LiBBbmQgeW91IG5lZWQKLSAqIHRvIGVudGVyIGtleSwgdmFsdWUgcGFpciBhcyBwYXJ0IG9mIHRoZSBjb250ZW50cwotICogYXJyYXkuIFlvdSBhbHNvIG5lZWQgdG8gdXBkYXRlIE1BWF9DT0RFIGZvciBlcnJvciBzdHJpbmdzCi0gKiBhbmQgTUFYX1dBUk5JTkcgZm9yIHdhcm5pbmdzICggTmVlZGVkIGZvciBvbmx5IGluZm9ybWF0aW9uCi0gKiBwdXJwb3NlICkKLSAqLwotcHVibGljIGNsYXNzIFhNTEVycm9yUmVzb3VyY2VzX2NhIGV4dGVuZHMgTGlzdFJlc291cmNlQnVuZGxlCi17Ci0KLS8qCi0gKiBUaGlzIGZpbGUgY29udGFpbnMgZXJyb3IgYW5kIHdhcm5pbmcgbWVzc2FnZXMgcmVsYXRlZCB0byBYYWxhbiBFcnJvcgotICogSGFuZGxpbmcuCi0gKgotICogIEdlbmVyYWwgbm90ZXMgdG8gdHJhbnNsYXRvcnM6Ci0gKgotICogIDEpIFhhbGFuIChvciBtb3JlIHByb3Blcmx5LCBYYWxhbi1pbnRlcnByZXRpdmUpIGFuZCBYU0xUQyBhcmUgbmFtZXMgb2YKLSAqICAgICBjb21wb25lbnRzLgotICogICAgIFhTTFQgaXMgYW4gYWNyb255bSBmb3IgIlhNTCBTdHlsZXNoZWV0IExhbmd1YWdlOiBUcmFuc2Zvcm1hdGlvbnMiLgotICogICAgIFhTTFRDIGlzIGFuIGFjcm9ueW0gZm9yIFhTTFQgQ29tcGlsZXIuCi0gKgotICogIDIpIEEgc3R5bGVzaGVldCBpcyBhIGRlc2NyaXB0aW9uIG9mIGhvdyB0byB0cmFuc2Zvcm0gYW4gaW5wdXQgWE1MIGRvY3VtZW50Ci0gKiAgICAgaW50byBhIHJlc3VsdGFudCBYTUwgZG9jdW1lbnQgKG9yIEhUTUwgZG9jdW1lbnQgb3IgdGV4dCkuICBUaGUKLSAqICAgICBzdHlsZXNoZWV0IGl0c2VsZiBpcyBkZXNjcmliZWQgaW4gdGhlIGZvcm0gb2YgYW4gWE1MIGRvY3VtZW50LgotICoKLSAqICAzKSBBIHRlbXBsYXRlIGlzIGEgY29tcG9uZW50IG9mIGEgc3R5bGVzaGVldCB0aGF0IGlzIHVzZWQgdG8gbWF0Y2ggYQotICogICAgIHBhcnRpY3VsYXIgcG9ydGlvbiBvZiBhbiBpbnB1dCBkb2N1bWVudCBhbmQgc3BlY2lmaWVzIHRoZSBmb3JtIG9mIHRoZQotICogICAgIGNvcnJlc3BvbmRpbmcgcG9ydGlvbiBvZiB0aGUgb3V0cHV0IGRvY3VtZW50LgotICoKLSAqICA0KSBBbiBlbGVtZW50IGlzIGEgbWFyay11cCB0YWcgaW4gYW4gWE1MIGRvY3VtZW50OyBhbiBhdHRyaWJ1dGUgaXMgYQotICogICAgIG1vZGlmaWVyIG9uIHRoZSB0YWcuICBGb3IgZXhhbXBsZSwgaW4gPGVsZW0gYXR0cj0ndmFsJyBhdHRyMj0ndmFsMic+Ci0gKiAgICAgImVsZW0iIGlzIGFuIGVsZW1lbnQgbmFtZSwgImF0dHIiIGFuZCAiYXR0cjIiIGFyZSBhdHRyaWJ1dGUgbmFtZXMgd2l0aAotICogICAgIHRoZSB2YWx1ZXMgInZhbCIgYW5kICJ2YWwyIiwgcmVzcGVjdGl2ZWx5LgotICoKLSAqICA1KSBBIG5hbWVzcGFjZSBkZWNsYXJhdGlvbiBpcyBhIHNwZWNpYWwgYXR0cmlidXRlIHRoYXQgaXMgdXNlZCB0byBhc3NvY2lhdGUKLSAqICAgICBhIHByZWZpeCB3aXRoIGEgVVJJICh0aGUgbmFtZXNwYWNlKS4gIFRoZSBtZWFuaW5ncyBvZiBlbGVtZW50IG5hbWVzIGFuZAotICogICAgIGF0dHJpYnV0ZSBuYW1lcyB0aGF0IHVzZSB0aGF0IHByZWZpeCBhcmUgZGVmaW5lZCB3aXRoIHJlc3BlY3QgdG8gdGhhdAotICogICAgIG5hbWVzcGFjZS4KLSAqCi0gKiAgNikgIlRyYW5zbGV0IiBpcyBhbiBpbnZlbnRlZCB0ZXJtIHRoYXQgZGVzY3JpYmVzIHRoZSBjbGFzcyBmaWxlIHRoYXQKLSAqICAgICByZXN1bHRzIGZyb20gY29tcGlsaW5nIGFuIFhNTCBzdHlsZXNoZWV0IGludG8gYSBKYXZhIGNsYXNzLgotICoKLSAqICA3KSBYUGF0aCBpcyBhIHNwZWNpZmljYXRpb24gdGhhdCBkZXNjcmliZXMgYSBub3RhdGlvbiBmb3IgaWRlbnRpZnlpbmcKLSAqICAgICBub2RlcyBpbiBhIHRyZWUtc3RydWN0dXJlZCByZXByZXNlbnRhdGlvbiBvZiBhbiBYTUwgZG9jdW1lbnQuICBBbgotICogICAgIGluc3RhbmNlIG9mIHRoYXQgbm90YXRpb24gaXMgcmVmZXJyZWQgdG8gYXMgYW4gWFBhdGggZXhwcmVzc2lvbi4KLSAqCi0gKi8KLQotICAvKiogTWF4aW11bSBlcnJvciBtZXNzYWdlcywgdGhpcyBpcyBuZWVkZWQgdG8ga2VlcCB0cmFjayBvZiB0aGUgbnVtYmVyIG9mIG1lc3NhZ2VzLiAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVhfQ09ERSA9IDYxOwotCi0gIC8qKiBNYXhpbXVtIHdhcm5pbmdzLCB0aGlzIGlzIG5lZWRlZCB0byBrZWVwIHRyYWNrIG9mIHRoZSBudW1iZXIgb2Ygd2FybmluZ3MuICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BWF9XQVJOSU5HID0gMDsKLQotICAvKiogTWF4aW11bSBtaXNjIHN0cmluZ3MuICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFYX09USEVSUyA9IDQ7Ci0KLSAgLyoqIE1heGltdW0gdG90YWwgd2FybmluZ3MgYW5kIGVycm9yIG1lc3NhZ2VzLiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVhfTUVTU0FHRVMgPSBNQVhfQ09ERSArIE1BWF9XQVJOSU5HICsgMTsKLQotCi0gIC8qCi0gICAqIE1lc3NhZ2Uga2V5cwotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCA9ICJFUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX09WRVJXUklURV9DQVVTRSA9ICJFUl9DQU5OT1RfT1ZFUldSSVRFX0NBVVNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fREVGQVVMVF9JTVBMID0gIkVSX05PX0RFRkFVTFRfSU1QTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NIVU5LRURJTlRBUlJBWV9OT1RfU1VQUE9SVEVEID0gIkVSX0NIVU5LRURJTlRBUlJBWV9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfT0ZGU0VUX0JJR0dFUl9USEFOX1NMT1QgPSAiRVJfT0ZGU0VUX0JJR0dFUl9USEFOX1NMT1QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1JPVVRJTkVfTk9UX0FWQUlMID0gIkVSX0NPUk9VVElORV9OT1RfQVZBSUwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1JPVVRJTkVfQ09fRVhJVCA9ICJFUl9DT1JPVVRJTkVfQ09fRVhJVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPSk9JTlJPVVRJTkVTRVRfRkFJTEVEID0gIkVSX0NPSk9JTlJPVVRJTkVTRVRfRkFJTEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09ST1VUSU5FX1BBUkFNID0gIkVSX0NPUk9VVElORV9QQVJBTSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BBUlNFUl9ET1RFUk1JTkFURV9BTlNXRVJTID0gIkVSX1BBUlNFUl9ET1RFUk1JTkFURV9BTlNXRVJTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fUEFSU0VfQ0FMTF9XSElMRV9QQVJTSU5HID0gIkVSX05PX1BBUlNFX0NBTExfV0hJTEVfUEFSU0lORyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1RZUEVEX0lURVJBVE9SX0FYSVNfTk9UX0lNUExFTUVOVEVEID0gIkVSX1RZUEVEX0lURVJBVE9SX0FYSVNfTk9UX0lNUExFTUVOVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSVRFUkFUT1JfQVhJU19OT1RfSU1QTEVNRU5URUQgPSAiRVJfSVRFUkFUT1JfQVhJU19OT1RfSU1QTEVNRU5URUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JVEVSQVRPUl9DTE9ORV9OT1RfU1VQUE9SVEVEID0gIkVSX0lURVJBVE9SX0NMT05FX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTktOT1dOX0FYSVNfVFlQRSA9ICJFUl9VTktOT1dOX0FYSVNfVFlQRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FYSVNfTk9UX1NVUFBPUlRFRCA9ICJFUl9BWElTX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19EVE1JRFNfQVZBSUwgPSAiRVJfTk9fRFRNSURTX0FWQUlMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9UX1NVUFBPUlRFRCA9ICJFUl9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9ERV9OT05fTlVMTCA9ICJFUl9OT0RFX05PTl9OVUxMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTERfTk9UX1JFU09MVkVfTk9ERSA9ICJFUl9DT1VMRF9OT1RfUkVTT0xWRV9OT0RFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU1RBUlRQQVJTRV9XSElMRV9QQVJTSU5HID0gIkVSX1NUQVJUUEFSU0VfV0hJTEVfUEFSU0lORyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NUQVJUUEFSU0VfTkVFRFNfU0FYUEFSU0VSID0gIkVSX1NUQVJUUEFSU0VfTkVFRFNfU0FYUEFSU0VSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTERfTk9UX0lOSVRfUEFSU0VSID0gIkVSX0NPVUxEX05PVF9JTklUX1BBUlNFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYQ0VQVElPTl9DUkVBVElOR19QT09MID0gIkVSX0VYQ0VQVElPTl9DUkVBVElOR19QT09MIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUEFUSF9DT05UQUlOU19JTlZBTElEX0VTQ0FQRV9TRVFVRU5DRSA9ICJFUl9QQVRIX0NPTlRBSU5TX0lOVkFMSURfRVNDQVBFX1NFUVVFTkNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU0NIRU1FX1JFUVVJUkVEID0gIkVSX1NDSEVNRV9SRVFVSVJFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1NDSEVNRV9JTl9VUkkgPSAiRVJfTk9fU0NIRU1FX0lOX1VSSSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1NDSEVNRV9JTlVSSSA9ICJFUl9OT19TQ0hFTUVfSU5VUkkiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QQVRIX0lOVkFMSURfQ0hBUiA9ICJFUl9QQVRIX0lOVkFMSURfQ0hBUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NDSEVNRV9GUk9NX05VTExfU1RSSU5HID0gIkVSX1NDSEVNRV9GUk9NX05VTExfU1RSSU5HIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU0NIRU1FX05PVF9DT05GT1JNQU5UID0gIkVSX1NDSEVNRV9OT1RfQ09ORk9STUFOVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0hPU1RfQUREUkVTU19OT1RfV0VMTEZPUk1FRCA9ICJFUl9IT1NUX0FERFJFU1NfTk9UX1dFTExGT1JNRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QT1JUX1dIRU5fSE9TVF9OVUxMID0gIkVSX1BPUlRfV0hFTl9IT1NUX05VTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX1BPUlQgPSAiRVJfSU5WQUxJRF9QT1JUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRlJBR19GT1JfR0VORVJJQ19VUkkgPSJFUl9GUkFHX0ZPUl9HRU5FUklDX1VSSSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZSQUdfV0hFTl9QQVRIX05VTEwgPSAiRVJfRlJBR19XSEVOX1BBVEhfTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZSQUdfSU5WQUxJRF9DSEFSID0gIkVSX0ZSQUdfSU5WQUxJRF9DSEFSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUEFSU0VSX0lOX1VTRSA9ICJFUl9QQVJTRVJfSU5fVVNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX0NIQU5HRV9XSElMRV9QQVJTSU5HID0gIkVSX0NBTk5PVF9DSEFOR0VfV0hJTEVfUEFSU0lORyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NFTEZfQ0FVU0FUSU9OX05PVF9QRVJNSVRURUQgPSAiRVJfU0VMRl9DQVVTQVRJT05fTk9UX1BFUk1JVFRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1VTRVJJTkZPX0lGX05PX0hPU1QgPSAiRVJfTk9fVVNFUklORk9fSUZfTk9fSE9TVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1BPUlRfSUZfTk9fSE9TVCA9ICJFUl9OT19QT1JUX0lGX05PX0hPU1QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19RVUVSWV9TVFJJTkdfSU5fUEFUSCA9ICJFUl9OT19RVUVSWV9TVFJJTkdfSU5fUEFUSCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX0ZSQUdNRU5UX1NUUklOR19JTl9QQVRIID0gIkVSX05PX0ZSQUdNRU5UX1NUUklOR19JTl9QQVRIIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX0lOSVRfVVJJX0VNUFRZX1BBUk1TID0gIkVSX0NBTk5PVF9JTklUX1VSSV9FTVBUWV9QQVJNUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01FVEhPRF9OT1RfU1VQUE9SVEVEID0iRVJfTUVUSE9EX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTkNSU0FYU1JDRklMVEVSX05PVF9SRVNUQVJUQUJMRSA9ICJFUl9JTkNSU0FYU1JDRklMVEVSX05PVF9SRVNUQVJUQUJMRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hNTFJEUl9OT1RfQkVGT1JFX1NUQVJUUEFSU0UgPSAiRVJfWE1MUkRSX05PVF9CRUZPUkVfU1RBUlRQQVJTRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FYSVNfVFJBVkVSU0VSX05PVF9TVVBQT1JURUQgPSAiRVJfQVhJU19UUkFWRVJTRVJfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VSUk9SSEFORExFUl9DUkVBVEVEX1dJVEhfTlVMTF9QUklOVFdSSVRFUiA9ICJFUl9FUlJPUkhBTkRMRVJfQ1JFQVRFRF9XSVRIX05VTExfUFJJTlRXUklURVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TWVNURU1JRF9VTktOT1dOID0gIkVSX1NZU1RFTUlEX1VOS05PV04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9MT0NBVElPTl9VTktOT1dOID0gIkVSX0xPQ0FUSU9OX1VOS05PV04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUkVGSVhfTVVTVF9SRVNPTFZFID0gIkVSX1BSRUZJWF9NVVNUX1JFU09MVkUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DUkVBVEVET0NVTUVOVF9OT1RfU1VQUE9SVEVEID0gIkVSX0NSRUFURURPQ1VNRU5UX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DSElMRF9IQVNfTk9fT1dORVJfRE9DVU1FTlQgPSAiRVJfQ0hJTERfSEFTX05PX09XTkVSX0RPQ1VNRU5UIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0hJTERfSEFTX05PX09XTkVSX0RPQ1VNRU5UX0VMRU1FTlQgPSAiRVJfQ0hJTERfSEFTX05PX09XTkVSX0RPQ1VNRU5UX0VMRU1FTlQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX09VVFBVVF9URVhUX0JFRk9SRV9ET0MgPSAiRVJfQ0FOVF9PVVRQVVRfVEVYVF9CRUZPUkVfRE9DIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9IQVZFX01PUkVfVEhBTl9PTkVfUk9PVCA9ICJFUl9DQU5UX0hBVkVfTU9SRV9USEFOX09ORV9ST09UIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQVJHX0xPQ0FMTkFNRV9OVUxMID0gIkVSX0FSR19MT0NBTE5BTUVfTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FSR19MT0NBTE5BTUVfSU5WQUxJRCA9ICJFUl9BUkdfTE9DQUxOQU1FX0lOVkFMSUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9BUkdfUFJFRklYX0lOVkFMSUQgPSAiRVJfQVJHX1BSRUZJWF9JTlZBTElEIjsKLQotICAvLyBNZXNzYWdlIGtleXMgdXNlZCBieSB0aGUgc2VyaWFsaXplcgotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SRVNPVVJDRV9DT1VMRF9OT1RfRklORCA9ICJFUl9SRVNPVVJDRV9DT1VMRF9OT1RfRklORCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1JFU09VUkNFX0NPVUxEX05PVF9MT0FEID0gIkVSX1JFU09VUkNFX0NPVUxEX05PVF9MT0FEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQlVGRkVSX1NJWkVfTEVTU1RIQU5fWkVSTyA9ICJFUl9CVUZGRVJfU0laRV9MRVNTVEhBTl9aRVJPIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9VVEYxNl9TVVJST0dBVEUgPSAiRVJfSU5WQUxJRF9VVEYxNl9TVVJST0dBVEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9PSUVSUk9SID0gIkVSX09JRVJST1IiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OQU1FU1BBQ0VfUFJFRklYID0gIkVSX05BTUVTUEFDRV9QUkVGSVgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TVFJBWV9BVFRSSUJVVEUgPSAiRVJfU1RSQVlfQVRUSVJCVVRFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU1RSQVlfTkFNRVNQQUNFID0gIkVSX1NUUkFZX05BTUVTUEFDRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxEX05PVF9MT0FEX1JFU09VUkNFID0gIkVSX0NPVUxEX05PVF9MT0FEX1JFU09VUkNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTERfTk9UX0xPQURfTUVUSE9EX1BST1BFUlRZID0gIkVSX0NPVUxEX05PVF9MT0FEX01FVEhPRF9QUk9QRVJUWSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NFUklBTElaRVJfTk9UX0NPTlRFTlRIQU5ETEVSID0gIkVSX1NFUklBTElaRVJfTk9UX0NPTlRFTlRIQU5ETEVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSUxMRUdBTF9BVFRSSUJVVEVfUE9TSVRJT04gPSAiRVJfSUxMRUdBTF9BVFRSSUJVVEVfUE9TSVRJT04iOwotCi0gIC8qCi0gICAqIE5vdyBmaWxsIGluIHRoZSBtZXNzYWdlIHRleHQuCi0gICAqIFRoZW4gZmlsbCBpbiB0aGUgbWVzc2FnZSB0ZXh0IGZvciB0aGF0IG1lc3NhZ2UgY29kZSBpbiB0aGUKLSAgICogYXJyYXkuIFVzZSB0aGUgbmV3IGVycm9yIGNvZGUgYXMgdGhlIGluZGV4IGludG8gdGhlIGFycmF5LgotICAgKi8KLQotICAvLyBFcnJvciBtZXNzYWdlcy4uLgotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBPYmplY3RbXVtdIF9jb250ZW50cyA9IG5ldyBPYmplY3RbXVtdIHsKLQotICAvKiogRXJyb3IgbWVzc2FnZSBJRCB0aGF0IGhhcyBhIG51bGwgbWVzc2FnZSwgYnV0IHRha2VzIGluIGEgc2luZ2xlIG9iamVjdC4gICAgKi8KLSAgICB7IkVSMDAwMCIgLCAiezB9IiB9LAotCi0gICAgeyBFUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVELAotICAgICAgIkFxdWVzdGEgZnVuY2lcdTAwZjMgbm8gdFx1MDBlOSBzdXBvcnQuICJ9LAotCi0gICAgeyBFUl9DQU5OT1RfT1ZFUldSSVRFX0NBVVNFLAotICAgICAgIk5vIGVzIHBvdCBzb2JyZWVzY3JpdXJlIHVuYSBjYXVzYSAifSwKLQotICAgIHsgRVJfTk9fREVGQVVMVF9JTVBMLAotICAgICAgIk5vIHMnaGEgdHJvYmF0IGNhcCBpbXBsZW1lbnRhY2lcdTAwZjMgcGVyIGRlZmVjdGUgIn0sCi0KLSAgICB7IEVSX0NIVU5LRURJTlRBUlJBWV9OT1RfU1VQUE9SVEVELAotICAgICAgIkVuIGwnJ2FjdHVhbGl0YXQgQ2h1bmtlZEludEFycmF5KHswfSkgbm8gdFx1MDBlOSBzdXBvcnQgIn0sCi0KLSAgICB7IEVSX09GRlNFVF9CSUdHRVJfVEhBTl9TTE9ULAotICAgICAgIkVsIGRlc3BsYVx1MDBlN2FtZW50IFx1MDBlOXMgbVx1MDBlOXMgZ3JhbiBxdWUgbGEgcmFudXJhICJ9LAotCi0gICAgeyBFUl9DT1JPVVRJTkVfTk9UX0FWQUlMLAotICAgICAgIkNvcm91dGluZSBubyBlc3RcdTAwZTAgZGlzcG9uaWJsZSwgaWQ9ezB9ICJ9LAotCi0gICAgeyBFUl9DT1JPVVRJTkVfQ09fRVhJVCwKLSAgICAgICJDb3JvdXRpbmVNYW5hZ2VyIGhhIHJlYnV0IHVuYSBwZXRpY2lcdTAwZjMgY29fZXhpdCgpICJ9LAotCi0gICAgeyBFUl9DT0pPSU5ST1VUSU5FU0VUX0ZBSUxFRCwKLSAgICAgICJTJ2hhIHByb2R1XHUwMGVmdCB1biBlcnJvciBhIGNvX2pvaW5Db3JvdXRpbmVTZXQoKSAifSwKLQotICAgIHsgRVJfQ09ST1VUSU5FX1BBUkFNLAotICAgICAgIkVycm9yIGRlIHBhclx1MDBlMG1ldHJlIGNvcm91dGluZSAoezB9KSAifSwKLQotICAgIHsgRVJfUEFSU0VSX0RPVEVSTUlOQVRFX0FOU1dFUlMsCi0gICAgICAiXG5VTkVYUEVDVEVEOiBkb1Rlcm1pbmF0ZSBkZSBsJydhbmFsaXR6YWRvciByZXNwb24gezB9In0sCi0KLSAgICB7IEVSX05PX1BBUlNFX0NBTExfV0hJTEVfUEFSU0lORywKLSAgICAgICJMJ2FuXHUwMGUwbGlzaSBubyBlcyBwb3QgY3JpZGFyIG1lbnRyZSBzJ2VzdFx1MDBlMCBkdWVudCBhIHRlcm1lICJ9LAotCi0gICAgeyBFUl9UWVBFRF9JVEVSQVRPUl9BWElTX05PVF9JTVBMRU1FTlRFRCwKLSAgICAgICJFcnJvcjogbCcnaXRlcmFkb3IgZGUgdGlwdXMgZGUgbCcnZWl4IHswfSBubyBzJydoYSBpbXBsZW1lbnRhdCAifSwKLQotICAgIHsgRVJfSVRFUkFUT1JfQVhJU19OT1RfSU1QTEVNRU5URUQsCi0gICAgICAiRXJyb3I6IGwnJ2l0ZXJhZG9yIGRlIGwnJ2VpeCB7MH0gbm8gcycnaGEgaW1wbGVtZW50YXQgIn0sCi0KLSAgICB7IEVSX0lURVJBVE9SX0NMT05FX05PVF9TVVBQT1JURUQsCi0gICAgICAiRWwgY2xvbmF0Z2UgZGUgbCdpdGVyYWRvciBubyB0XHUwMGU5IHN1cG9ydCAifSwKLQotICAgIHsgRVJfVU5LTk9XTl9BWElTX1RZUEUsCi0gICAgICAiVGlwdXMgZGUgY29tbXV0YWNpXHUwMGYzIGRlIGwnJ2VpeCBkZXNjb25lZ3VkYTogezB9ICJ9LAotCi0gICAgeyBFUl9BWElTX05PVF9TVVBQT1JURUQsCi0gICAgICAiTGEgY29tbXV0YWNpXHUwMGYzIGRlIGwnJ2VpeCBubyB0XHUwMGU5IHN1cG9ydDogezB9ICJ9LAotCi0gICAgeyBFUl9OT19EVE1JRFNfQVZBSUwsCi0gICAgICAiTm8gaGkgaGEgbVx1MDBlOXMgSUQgZGUgRFRNIGRpc3BvbmlibGVzICJ9LAotCi0gICAgeyBFUl9OT1RfU1VQUE9SVEVELAotICAgICAgIk5vIHRcdTAwZTkgc3Vwb3J0OiB7MH0gIn0sCi0KLSAgICB7IEVSX05PREVfTk9OX05VTEwsCi0gICAgICAiRWwgbm9kZSBubyBoYSBkZSBzZXIgbnVsIHBlciBhIGdldERUTUhhbmRsZUZyb21Ob2RlICJ9LAotCi0gICAgeyBFUl9DT1VMRF9OT1RfUkVTT0xWRV9OT0RFLAotICAgICAgIk5vIHMnaGEgcG9ndXQgcmVzb2xkcmUgZWwgbm9kZSBlbiB1biBtYW5lamFkb3IgIn0sCi0KLSAgICB7IEVSX1NUQVJUUEFSU0VfV0hJTEVfUEFSU0lORywKLSAgICAgICAic3RhcnRQYXJzZSBubyBlcyBwb3QgY3JpZGFyIG1lbnRyZSBzJ2VzdFx1MDBlMCBkdWVudCBhIHRlcm1lIGwnYW5cdTAwZTBsaXNpICJ9LAotCi0gICAgeyBFUl9TVEFSVFBBUlNFX05FRURTX1NBWFBBUlNFUiwKLSAgICAgICAic3RhcnRQYXJzZSBuZWNlc3NpdGEgdW4gU0FYUGFyc2VyIHF1ZSBubyBzaWd1aSBudWwgIn0sCi0KLSAgICB7IEVSX0NPVUxEX05PVF9JTklUX1BBUlNFUiwKLSAgICAgICAiTm8gcydoYSBwb2d1dCBpbmljaWFsaXR6YXIgbCdhbmFsaXR6YWRvciBhbWIgIn0sCi0KLSAgICB7IEVSX0VYQ0VQVElPTl9DUkVBVElOR19QT09MLAotICAgICAgICJTJ2hhIHByb2R1XHUwMGVmdCB1bmEgZXhjZXBjaVx1MDBmMyBlbiBjcmVhciB1bmEgbm92YSBpbnN0XHUwMGUwbmNpYSBkZSBsJ2FncnVwYWNpXHUwMGYzICJ9LAotCi0gICAgeyBFUl9QQVRIX0NPTlRBSU5TX0lOVkFMSURfRVNDQVBFX1NFUVVFTkNFLAotICAgICAgICJMYSB2aWEgZCdhY2NcdTAwZTlzIGNvbnRcdTAwZTkgdW5hIHNlcVx1MDBmY1x1MDBlOG5jaWEgZCdlc2NhcGFtZW50IG5vIHZcdTAwZTBsaWRhICJ9LAotCi0gICAgeyBFUl9TQ0hFTUVfUkVRVUlSRUQsCi0gICAgICAgIkVzIG5lY2Vzc2l0YSBsJ2VzcXVlbWEgIn0sCi0KLSAgICB7IEVSX05PX1NDSEVNRV9JTl9VUkksCi0gICAgICAgIk5vIHMnJ2hhIHRyb2JhdCBjYXAgZXNxdWVtYSBhIGwnJ1VSSTogezB9ICJ9LAotCi0gICAgeyBFUl9OT19TQ0hFTUVfSU5VUkksCi0gICAgICAgIk5vIHMnaGEgdHJvYmF0IGNhcCBlc3F1ZW1hIGEgbCdVUkkgIn0sCi0KLSAgICB7IEVSX1BBVEhfSU5WQUxJRF9DSEFSLAotICAgICAgICJMYSB2aWEgZCdhY2NcdTAwZTlzIGNvbnRcdTAwZTkgdW4gY2FyXHUwMGUwY3RlciBubyB2XHUwMGUwbGlkIHswfSAifSwKLQotICAgIHsgRVJfU0NIRU1FX0ZST01fTlVMTF9TVFJJTkcsCi0gICAgICAgIk5vIGVzIHBvdCBlc3RhYmxpciB1biBlc3F1ZW1hIGRlcyBkJ3VuYSBjYWRlbmEgbnVsXHUwMGI3bGEgIn0sCi0KLSAgICB7IEVSX1NDSEVNRV9OT1RfQ09ORk9STUFOVCwKLSAgICAgICAiTCdlc3F1ZW1hIG5vIHRcdTAwZTkgY29uZm9ybWl0YXQuICJ9LAotCi0gICAgeyBFUl9IT1NUX0FERFJFU1NfTk9UX1dFTExGT1JNRUQsCi0gICAgICAgIkVsIHNpc3RlbWEgcHJpbmNpcGFsIG5vIHRcdTAwZTkgdW5hIGFkcmVcdTAwZTdhIGJlbiBmb3JtYWRhICJ9LAotCi0gICAgeyBFUl9QT1JUX1dIRU5fSE9TVF9OVUxMLAotICAgICAgICJFbCBwb3J0IG5vIGVzIHBvdCBlc3RhYmxpciBxdWFuIGVsIHNpc3RlbWEgcHJpbmNpcGFsIFx1MDBlOXMgbnVsICJ9LAotCi0gICAgeyBFUl9JTlZBTElEX1BPUlQsCi0gICAgICAgIk5cdTAwZmFtZXJvIGRlIHBvcnQgbm8gdlx1MDBlMGxpZCAifSwKLQotICAgIHsgRVJfRlJBR19GT1JfR0VORVJJQ19VUkksCi0gICAgICAgIkVsIGZyYWdtZW50IG5vbVx1MDBlOXMgZXMgcG90IGVzdGFibGlyIHBlciBhIHVuIFVSSSBnZW5cdTAwZThyaWMgIn0sCi0KLSAgICB7IEVSX0ZSQUdfV0hFTl9QQVRIX05VTEwsCi0gICAgICAgIkVsIGZyYWdtZW50IG5vIGVzIHBvdCBlc3RhYmxpciBzaSBsYSB2aWEgZCdhY2NcdTAwZTlzIFx1MDBlOXMgbnVsXHUwMGI3bGEgIn0sCi0KLSAgICB7IEVSX0ZSQUdfSU5WQUxJRF9DSEFSLAotICAgICAgICJFbCBmcmFnbWVudCBjb250XHUwMGU5IHVuIGNhclx1MDBlMGN0ZXIgbm8gdlx1MDBlMGxpZCAifSwKLQotICAgIHsgRVJfUEFSU0VSX0lOX1VTRSwKLSAgICAgICJMJ2FuYWxpdHphZG9yIGphIHMnZXN0XHUwMGUwIHV0aWxpdHphbnQgIn0sCi0KLSAgICB7IEVSX0NBTk5PVF9DSEFOR0VfV0hJTEVfUEFSU0lORywKLSAgICAgICJObyBlcyBwb3QgbW9kaWZpY2FyIHswfSB7MX0gbWVudHJlIGVzIGR1IGEgdGVybWUgbCcnYW5cdTAwZTBsaXNpICJ9LAotCi0gICAgeyBFUl9TRUxGX0NBVVNBVElPTl9OT1RfUEVSTUlUVEVELAotICAgICAgIkxhIGNhdXNhbGl0YXQgcHJcdTAwZjJwaWEgbm8gZXN0XHUwMGUwIHBlcm1lc2EuICJ9LAotCi0gICAgeyBFUl9OT19VU0VSSU5GT19JRl9OT19IT1NULAotICAgICAgIk5vIGVzIHBvdCBlc3BlY2lmaWNhciBpbmZvcm1hY2lcdTAwZjMgZGUgbCd1c3Vhcmkgc2kgbm8gcydlc3BlY2lmaWNhIGVsIHNpc3RlbWEgcHJpbmNpcGFsICJ9LAotCi0gICAgeyBFUl9OT19QT1JUX0lGX05PX0hPU1QsCi0gICAgICAiTm8gZXMgcG90IGVzcGVjaWZpY2FyIGVsIHBvcnQgc2kgbm8gcydlc3BlY2lmaWNhIGVsIHNpc3RlbWEgcHJpbmNpcGFsICJ9LAotCi0gICAgeyBFUl9OT19RVUVSWV9TVFJJTkdfSU5fUEFUSCwKLSAgICAgICJObyBlcyBwb3QgZXNwZWNpZmljYXIgdW5hIGNhZGVuYSBkZSBjb25zdWx0YSBlbiBsYSB2aWEgZCdhY2NcdTAwZTlzIGkgbGEgY2FkZW5hIGRlIGNvbnN1bHRhICJ9LAotCi0gICAgeyBFUl9OT19GUkFHTUVOVF9TVFJJTkdfSU5fUEFUSCwKLSAgICAgICJObyBlcyBwb3QgZXNwZWNpZmljYXIgdW4gZnJhZ21lbnQgdGFudCBlbiBsYSB2aWEgZCdhY2NcdTAwZTlzIGNvbSBlbiBlbCBmcmFnbWVudCAifSwKLQotICAgIHsgRVJfQ0FOTk9UX0lOSVRfVVJJX0VNUFRZX1BBUk1TLAotICAgICAgIk5vIGVzIHBvdCBpbmljaWFsaXR6YXIgbCdVUkkgYW1iIHBhclx1MDBlMG1ldHJlcyBidWl0cyAifSwKLQotICAgIHsgRVJfTUVUSE9EX05PVF9TVVBQT1JURUQsCi0gICAgICAiQXF1ZXN0IG1cdTAwZTh0b2RlIGVuY2FyYSBubyB0XHUwMGU5IHN1cG9ydCAifSwKLQotICAgIHsgRVJfSU5DUlNBWFNSQ0ZJTFRFUl9OT1RfUkVTVEFSVEFCTEUsCi0gICAgICAiQXJhIG1hdGVpeCBubyBlcyBwb3QgcmVpbmljaWFyIEluY3JlbWVudGFsU0FYU291cmNlX0ZpbHRlciAifSwKLQotICAgIHsgRVJfWE1MUkRSX05PVF9CRUZPUkVfU1RBUlRQQVJTRSwKLSAgICAgICJYTUxSZWFkZXIgbm8gZXMgcG90IHByb2R1aXIgYWJhbnMgZGUgbGEgcGV0aWNpXHUwMGYzIGQnc3RhcnRQYXJzZSAifSwKLQotICAgIHsgRVJfQVhJU19UUkFWRVJTRVJfTk9UX1NVUFBPUlRFRCwKLSAgICAgICJMYSBjb21tdXRhY2lcdTAwZjMgZGUgbCcnZWl4IG5vIHRcdTAwZTkgc3Vwb3J0OiB7MH0gIn0sCi0KLSAgICB7IEVSX0VSUk9SSEFORExFUl9DUkVBVEVEX1dJVEhfTlVMTF9QUklOVFdSSVRFUiwKLSAgICAgICJTJydoYSBjcmVhdCBMaXN0aW5nRXJyb3JIYW5kbGVyIGFtYiBQcmludFdyaXRlciBudWwgIn0sCi0KLSAgICB7IEVSX1NZU1RFTUlEX1VOS05PV04sCi0gICAgICAiSUQgZGVsIHNpc3RlbWEgKFN5c3RlbUlkKSBkZXNjb25lZ3V0ICJ9LAotCi0gICAgeyBFUl9MT0NBVElPTl9VTktOT1dOLAotICAgICAgIlViaWNhY2lcdTAwZjMgZGUgbCdlcnJvciBkZXNjb25lZ3VkYSJ9LAotCi0gICAgeyBFUl9QUkVGSVhfTVVTVF9SRVNPTFZFLAotICAgICAgIkVsIHByZWZpeCBzJydoYSBkZSByZXNvbGRyZSBlbiB1biBlc3BhaSBkZSBub21zOiB7MH0gIn0sCi0KLSAgICB7IEVSX0NSRUFURURPQ1VNRU5UX05PVF9TVVBQT1JURUQsCi0gICAgICAiY3JlYXRlRG9jdW1lbnQoKSBubyB0XHUwMGU5IHN1cG9ydCBhIFhQYXRoQ29udGV4dCAifSwKLQotICAgIHsgRVJfQ0hJTERfSEFTX05PX09XTkVSX0RPQ1VNRU5ULAotICAgICAgIkVsIHN1Ym9yZGluYXQgZGUgbCdhdHJpYnV0IG5vIHRcdTAwZTkgdW4gZG9jdW1lbnQgZGUgcHJvcGlldGFyaS4gIn0sCi0KLSAgICB7IEVSX0NISUxEX0hBU19OT19PV05FUl9ET0NVTUVOVF9FTEVNRU5ULAotICAgICAgIkVsIHN1Ym9yZGluYXQgZGUgbCdhdHJpYnV0IG5vIHRcdTAwZTkgdW4gZWxlbWVudCBkZSBkb2N1bWVudCBkZSBwcm9waWV0YXJpLiAifSwKLQotICAgIHsgRVJfQ0FOVF9PVVRQVVRfVEVYVF9CRUZPUkVfRE9DLAotICAgICAgIkF2XHUwMGVkczogbm8gZXMgcG90IHByb2R1aXIgdGV4dCBhYmFucyBkZSBsJ2VsZW1lbnQgZGUgZG9jdW1lbnQuIEVzIHBhc3NhIHBlciBhbHQuICJ9LAotCi0gICAgeyBFUl9DQU5UX0hBVkVfTU9SRV9USEFOX09ORV9ST09ULAotICAgICAgIk5vIGhpIHBvdCBoYXZlciBtXHUwMGU5cyBkJ3VuYSBhcnJlbCBlbiB1biBET00uICJ9LAotCi0gICAgeyBFUl9BUkdfTE9DQUxOQU1FX05VTEwsCi0gICAgICAgIkwnYXJndW1lbnQgJ2xvY2FsTmFtZScgXHUwMGU5cyBudWwuICJ9LAotCi0gICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIEEgUU5BTUUgaGFzIHRoZSBzeW50YWN0aWMgZm9ybSBbTkNOYW1lOl1OQ05hbWUKLSAgICAvLyBUaGUgbG9jYWxuYW1lIGlzIHRoZSBwb3J0aW9uIGFmdGVyIHRoZSBvcHRpb25hbCBjb2xvbjsgdGhlIG1lc3NhZ2UgaW5kaWNhdGVzCi0gICAgLy8gdGhhdCB0aGVyZSBpcyBhIHByb2JsZW0gd2l0aCB0aGF0IHBhcnQgb2YgdGhlIFFOQU1FLgotICAgIHsgRVJfQVJHX0xPQ0FMTkFNRV9JTlZBTElELAotICAgICAgICJFbCBub20gbG9jYWwgZGUgUU5BTUUgaGEgZGUgc2VyIHVuIE5DTmFtZSB2XHUwMGUwbGlkLiAifSwKLQotICAgIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBIFFOQU1FIGhhcyB0aGUgc3ludGFjdGljIGZvcm0gW05DTmFtZTpdTkNOYW1lCi0gICAgLy8gVGhlIHByZWZpeCBpcyB0aGUgcG9ydGlvbiBiZWZvcmUgdGhlIG9wdGlvbmFsIGNvbG9uOyB0aGUgbWVzc2FnZSBpbmRpY2F0ZXMKLSAgICAvLyB0aGF0IHRoZXJlIGlzIGEgcHJvYmxlbSB3aXRoIHRoYXQgcGFydCBvZiB0aGUgUU5BTUUuCi0gICAgeyBFUl9BUkdfUFJFRklYX0lOVkFMSUQsCi0gICAgICAgIkVsIHByZWZpeCBkZSBRTkFNRSBoYSBkZSBzZXIgdW4gTkNOYW1lIHZcdTAwZTBsaWQuICJ9LAotCi0gICAgeyAiQkFEX0NPREUiLCAiRWwgcGFyXHUwMGUwbWV0cmUgZGUgY3JlYXRlTWVzc2FnZSBlc3RhdmEgZm9yYSBkZWxzIGxcdTAwZWRtaXRzLiAifSwKLSAgICB7ICJGT1JNQVRfRkFJTEVEIiwgIlMnaGEgZ2VuZXJhdCB1bmEgZXhjZXBjaVx1MDBmMyBkdXJhbnQgbGEgY3JpZGEgbWVzc2FnZUZvcm1hdC4gIn0sCi0gICAgeyAibGluZSIsICJMXHUwMGVkbmlhIG5cdTAwZmFtLiAifSwKLSAgICB7ICJjb2x1bW4iLCJDb2x1bW5hIG5cdTAwZmFtLiAifSwKLQotICAgIHtFUl9TRVJJQUxJWkVSX05PVF9DT05URU5USEFORExFUiwKLSAgICAgICJMYSBjbGFzc2UgZGUgc2VyaWFsaXR6YWRvciAnJ3swfScnIG5vIGltcGxlbWVudGEgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIuIn0sCi0KLSAgICB7RVJfUkVTT1VSQ0VfQ09VTERfTk9UX0ZJTkQsCi0gICAgICAiTm8gcycnaGEgdHJvYmF0IGVsIHJlY3VycyBbIHswfSBdLlxuIHsxfSIgfSwKLQotICAgIHtFUl9SRVNPVVJDRV9DT1VMRF9OT1RfTE9BRCwKLSAgICAgICJFbCByZWN1cnMgWyB7MH0gXSBubyBzJydoYSBwb2d1dCBjYXJyZWdhcjogezF9IFxuIHsyfSBcdCB7M30iIH0sCi0KLSAgICB7RVJfQlVGRkVSX1NJWkVfTEVTU1RIQU5fWkVSTywKLSAgICAgICJHcmFuZFx1MDBlMHJpYSBkZWwgYnVmZmVyIDw9MCAiIH0sCi0KLSAgICB7RVJfSU5WQUxJRF9VVEYxNl9TVVJST0dBVEUsCi0gICAgICAiUycnaGEgZGV0ZWN0YXQgdW4gc3VwbGVudCBVVEYtMTYgbm8gdlx1MDBlMGxpZDogezB9ID8gIiB9LAotCi0gICAge0VSX09JRVJST1IsCi0gICAgICAiRXJyb3IgZCdFL1MgIiB9LAotCi0gICAge0VSX0lMTEVHQUxfQVRUUklCVVRFX1BPU0lUSU9OLAotICAgICAgIk5vIGVzIHBvdCBhZmVnaXIgbCcnYXRyaWJ1dCB7MH0gZGVzcHJcdTAwZTlzIGRlbHMgbm9kZXMgc3Vib3JkaW5hdHMgbyBhYmFucyBxdWUgZXMgcHJvZHVlaXhpIHVuIGVsZW1lbnQuIEVzIHBhc3Nhclx1MDBlMCBwZXIgYWx0IGwnJ2F0cmlidXQuICJ9LAotCi0gICAgICAvKgotICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IGNvbnRhaW5lZCBhIHJlZmVyZW5jZSB0byBhCi0gICAgICAgKiBuYW1lc3BhY2UgcHJlZml4IHRoYXQgd2FzIHVuZGVmaW5lZC4gIFRoZSB2YWx1ZSBvZiB0aGUgc3Vic3RpdHV0aW9uCi0gICAgICAgKiB0ZXh0IGlzIHRoZSBuYW1lIG9mIHRoZSBwcmVmaXguCi0gICAgICAgKi8KLSAgICB7RVJfTkFNRVNQQUNFX1BSRUZJWCwKLSAgICAgICJMJydlc3BhaSBkZSBub21zIGRlbCBwcmVmaXggJyd7MH0nJyBubyBzJydoYSBkZWNsYXJhdC4iIH0sCi0gICAgICAvKgotICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyByZXBvcnRlZCBpZiB0aGUgc3R5bGVzaGVldAotICAgICAgICogYmVpbmcgcHJvY2Vzc2VkIGF0dGVtcHRlZCB0byBjb25zdHJ1Y3QgYW4gWE1MIGRvY3VtZW50IHdpdGggYW4KLSAgICAgICAqIGF0dHJpYnV0ZSBpbiBhIHBsYWNlIG90aGVyIHRoYW4gb24gYW4gZWxlbWVudC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICogc3BlY2lmaWVzIHRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUuCi0gICAgICAgKi8KLSAgICB7RVJfU1RSQVlfQVRUUklCVVRFLAotICAgICAgIkwnJ2F0cmlidXQgJyd7MH0nJyBlcyB0cm9iYSBmb3JhIGRlIGwnJ2VsZW1lbnQuIiB9LAotCi0gICAgICAvKgotICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFzIHdpdGggdGhlIHByZWNlZGluZyBtZXNzYWdlLCBhIG5hbWVzcGFjZQotICAgICAgICogZGVjbGFyYXRpb24gaGFzIHRoZSBmb3JtIG9mIGFuIGF0dHJpYnV0ZSBhbmQgaXMgb25seSBwZXJtaXR0ZWQgdG8KLSAgICAgICAqIGFwcGVhciBvbiBhbiBlbGVtZW50LiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHswfSBpcyB0aGUgbmFtZXNwYWNlCi0gICAgICAgKiBwcmVmaXggYW5kIHsxfSBpcyB0aGUgVVJJIHRoYXQgd2FzIGJlaW5nIHVzZWQgaW4gdGhlIGVycm9uZW91cwotICAgICAgICogbmFtZXNwYWNlIGRlY2xhcmF0aW9uLgotICAgICAgICovCi0gICAge0VSX1NUUkFZX05BTUVTUEFDRSwKLSAgICAgICJMYSBkZWNsYXJhY2lcdTAwZjMgZCcnZXNwYWkgZGUgbm9tcyAnJ3swfScnPScnezF9JycgZXMgdHJvYmEgZm9yYSBkZSBsJydlbGVtZW50LiIgfSwKLQotICAgIHtFUl9DT1VMRF9OT1RfTE9BRF9SRVNPVVJDRSwKLSAgICAgICJObyBzJydoYSBwb2d1dCBjYXJyZWdhciAnJ3swfScnIChjb21wcm92ZXUgbGEgQ0xBU1NQQVRIKTsgYXJhIHMnJ2VzdGFuIGZlbnQgc2VydmlyIGVscyB2YWxvcnMgcGVyIGRlZmVjdGUuIn0sCi0KLSAgICB7RVJfQ09VTERfTk9UX0xPQURfTUVUSE9EX1BST1BFUlRZLAotICAgICAgIk5vIHMnJ2hhIHBvZ3V0IGNhcnJlZ2FyIGVsIGZpdHhlciBkZSBwcm9waWV0YXRzICcnezB9JycgZGVsIG1cdTAwZTh0b2RlIGRlIHNvcnRpZGEgJyd7MX0nJyAoY29tcHJvdmV1IGxhIENMQVNTUEFUSCkiIH0KLQotCi0gIH07Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbG9va3VwIHRhYmxlIGZvciBlcnJvciBtZXNzYWdlcwotICAgKgotICAgKiBAcmV0dXJuIFRoZSBhc3NvY2lhdGlvbiBsaXN0LgotICAgKi8KLSAgcHVibGljIE9iamVjdFtdW10gZ2V0Q29udGVudHMoKQotICB7Ci0gICAgcmV0dXJuIF9jb250ZW50czsKLSAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9yZXMvWE1MRXJyb3JSZXNvdXJjZXNfY3MuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3Jlcy9YTUxFcnJvclJlc291cmNlc19jcy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmM2UzYzNlLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3Jlcy9YTUxFcnJvclJlc291cmNlc19jcy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDQzICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFhNTEVycm9yUmVzb3VyY2VzX2NzLmphdmEsdiAxLjEuNi4yIDIwMDUvMDkvMTUgMDc6NDU6Mzggc3VyZXNoX2VtYWlsaWQgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnJlczsKLQotCi1pbXBvcnQgamF2YS51dGlsLkxpc3RSZXNvdXJjZUJ1bmRsZTsKLQotLyoqCi0gKiBTZXQgdXAgZXJyb3IgbWVzc2FnZXMuCi0gKiBXZSBidWlsZCBhIHR3byBkaW1lbnNpb25hbCBhcnJheSBvZiBtZXNzYWdlIGtleXMgYW5kCi0gKiBtZXNzYWdlIHN0cmluZ3MuIEluIG9yZGVyIHRvIGFkZCBhIG5ldyBtZXNzYWdlIGhlcmUsCi0gKiB5b3UgbmVlZCB0byBmaXJzdCBhZGQgYSBTdHJpbmcgY29uc3RhbnQuIEFuZCB5b3UgbmVlZAotICogdG8gZW50ZXIga2V5LCB2YWx1ZSBwYWlyIGFzIHBhcnQgb2YgdGhlIGNvbnRlbnRzCi0gKiBhcnJheS4gWW91IGFsc28gbmVlZCB0byB1cGRhdGUgTUFYX0NPREUgZm9yIGVycm9yIHN0cmluZ3MKLSAqIGFuZCBNQVhfV0FSTklORyBmb3Igd2FybmluZ3MgKCBOZWVkZWQgZm9yIG9ubHkgaW5mb3JtYXRpb24KLSAqIHB1cnBvc2UgKQotICovCi1wdWJsaWMgY2xhc3MgWE1MRXJyb3JSZXNvdXJjZXNfY3MgZXh0ZW5kcyBMaXN0UmVzb3VyY2VCdW5kbGUKLXsKLQotLyoKLSAqIFRoaXMgZmlsZSBjb250YWlucyBlcnJvciBhbmQgd2FybmluZyBtZXNzYWdlcyByZWxhdGVkIHRvIFhhbGFuIEVycm9yCi0gKiBIYW5kbGluZy4KLSAqCi0gKiAgR2VuZXJhbCBub3RlcyB0byB0cmFuc2xhdG9yczoKLSAqCi0gKiAgMSkgWGFsYW4gKG9yIG1vcmUgcHJvcGVybHksIFhhbGFuLWludGVycHJldGl2ZSkgYW5kIFhTTFRDIGFyZSBuYW1lcyBvZgotICogICAgIGNvbXBvbmVudHMuCi0gKiAgICAgWFNMVCBpcyBhbiBhY3JvbnltIGZvciAiWE1MIFN0eWxlc2hlZXQgTGFuZ3VhZ2U6IFRyYW5zZm9ybWF0aW9ucyIuCi0gKiAgICAgWFNMVEMgaXMgYW4gYWNyb255bSBmb3IgWFNMVCBDb21waWxlci4KLSAqCi0gKiAgMikgQSBzdHlsZXNoZWV0IGlzIGEgZGVzY3JpcHRpb24gb2YgaG93IHRvIHRyYW5zZm9ybSBhbiBpbnB1dCBYTUwgZG9jdW1lbnQKLSAqICAgICBpbnRvIGEgcmVzdWx0YW50IFhNTCBkb2N1bWVudCAob3IgSFRNTCBkb2N1bWVudCBvciB0ZXh0KS4gIFRoZQotICogICAgIHN0eWxlc2hlZXQgaXRzZWxmIGlzIGRlc2NyaWJlZCBpbiB0aGUgZm9ybSBvZiBhbiBYTUwgZG9jdW1lbnQuCi0gKgotICogIDMpIEEgdGVtcGxhdGUgaXMgYSBjb21wb25lbnQgb2YgYSBzdHlsZXNoZWV0IHRoYXQgaXMgdXNlZCB0byBtYXRjaCBhCi0gKiAgICAgcGFydGljdWxhciBwb3J0aW9uIG9mIGFuIGlucHV0IGRvY3VtZW50IGFuZCBzcGVjaWZpZXMgdGhlIGZvcm0gb2YgdGhlCi0gKiAgICAgY29ycmVzcG9uZGluZyBwb3J0aW9uIG9mIHRoZSBvdXRwdXQgZG9jdW1lbnQuCi0gKgotICogIDQpIEFuIGVsZW1lbnQgaXMgYSBtYXJrLXVwIHRhZyBpbiBhbiBYTUwgZG9jdW1lbnQ7IGFuIGF0dHJpYnV0ZSBpcyBhCi0gKiAgICAgbW9kaWZpZXIgb24gdGhlIHRhZy4gIEZvciBleGFtcGxlLCBpbiA8ZWxlbSBhdHRyPSd2YWwnIGF0dHIyPSd2YWwyJz4KLSAqICAgICAiZWxlbSIgaXMgYW4gZWxlbWVudCBuYW1lLCAiYXR0ciIgYW5kICJhdHRyMiIgYXJlIGF0dHJpYnV0ZSBuYW1lcyB3aXRoCi0gKiAgICAgdGhlIHZhbHVlcyAidmFsIiBhbmQgInZhbDIiLCByZXNwZWN0aXZlbHkuCi0gKgotICogIDUpIEEgbmFtZXNwYWNlIGRlY2xhcmF0aW9uIGlzIGEgc3BlY2lhbCBhdHRyaWJ1dGUgdGhhdCBpcyB1c2VkIHRvIGFzc29jaWF0ZQotICogICAgIGEgcHJlZml4IHdpdGggYSBVUkkgKHRoZSBuYW1lc3BhY2UpLiAgVGhlIG1lYW5pbmdzIG9mIGVsZW1lbnQgbmFtZXMgYW5kCi0gKiAgICAgYXR0cmlidXRlIG5hbWVzIHRoYXQgdXNlIHRoYXQgcHJlZml4IGFyZSBkZWZpbmVkIHdpdGggcmVzcGVjdCB0byB0aGF0Ci0gKiAgICAgbmFtZXNwYWNlLgotICoKLSAqICA2KSAiVHJhbnNsZXQiIGlzIGFuIGludmVudGVkIHRlcm0gdGhhdCBkZXNjcmliZXMgdGhlIGNsYXNzIGZpbGUgdGhhdAotICogICAgIHJlc3VsdHMgZnJvbSBjb21waWxpbmcgYW4gWE1MIHN0eWxlc2hlZXQgaW50byBhIEphdmEgY2xhc3MuCi0gKgotICogIDcpIFhQYXRoIGlzIGEgc3BlY2lmaWNhdGlvbiB0aGF0IGRlc2NyaWJlcyBhIG5vdGF0aW9uIGZvciBpZGVudGlmeWluZwotICogICAgIG5vZGVzIGluIGEgdHJlZS1zdHJ1Y3R1cmVkIHJlcHJlc2VudGF0aW9uIG9mIGFuIFhNTCBkb2N1bWVudC4gIEFuCi0gKiAgICAgaW5zdGFuY2Ugb2YgdGhhdCBub3RhdGlvbiBpcyByZWZlcnJlZCB0byBhcyBhbiBYUGF0aCBleHByZXNzaW9uLgotICoKLSAqLwotCi0gIC8qKiBNYXhpbXVtIGVycm9yIG1lc3NhZ2VzLCB0aGlzIGlzIG5lZWRlZCB0byBrZWVwIHRyYWNrIG9mIHRoZSBudW1iZXIgb2YgbWVzc2FnZXMuICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BWF9DT0RFID0gNjE7Ci0KLSAgLyoqIE1heGltdW0gd2FybmluZ3MsIHRoaXMgaXMgbmVlZGVkIHRvIGtlZXAgdHJhY2sgb2YgdGhlIG51bWJlciBvZiB3YXJuaW5ncy4gICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFYX1dBUk5JTkcgPSAwOwotCi0gIC8qKiBNYXhpbXVtIG1pc2Mgc3RyaW5ncy4gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVhfT1RIRVJTID0gNDsKLQotICAvKiogTWF4aW11bSB0b3RhbCB3YXJuaW5ncyBhbmQgZXJyb3IgbWVzc2FnZXMuICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BWF9NRVNTQUdFUyA9IE1BWF9DT0RFICsgTUFYX1dBUk5JTkcgKyAxOwotCi0KLSAgLyoKLSAgICogTWVzc2FnZSBrZXlzCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEID0gIkVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfT1ZFUldSSVRFX0NBVVNFID0gIkVSX0NBTk5PVF9PVkVSV1JJVEVfQ0FVU0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19ERUZBVUxUX0lNUEwgPSAiRVJfTk9fREVGQVVMVF9JTVBMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0hVTktFRElOVEFSUkFZX05PVF9TVVBQT1JURUQgPSAiRVJfQ0hVTktFRElOVEFSUkFZX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9PRkZTRVRfQklHR0VSX1RIQU5fU0xPVCA9ICJFUl9PRkZTRVRfQklHR0VSX1RIQU5fU0xPVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPUk9VVElORV9OT1RfQVZBSUwgPSAiRVJfQ09ST1VUSU5FX05PVF9BVkFJTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPUk9VVElORV9DT19FWElUID0gIkVSX0NPUk9VVElORV9DT19FWElUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09KT0lOUk9VVElORVNFVF9GQUlMRUQgPSAiRVJfQ09KT0lOUk9VVElORVNFVF9GQUlMRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1JPVVRJTkVfUEFSQU0gPSAiRVJfQ09ST1VUSU5FX1BBUkFNIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUEFSU0VSX0RPVEVSTUlOQVRFX0FOU1dFUlMgPSAiRVJfUEFSU0VSX0RPVEVSTUlOQVRFX0FOU1dFUlMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19QQVJTRV9DQUxMX1dISUxFX1BBUlNJTkcgPSAiRVJfTk9fUEFSU0VfQ0FMTF9XSElMRV9QQVJTSU5HIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVFlQRURfSVRFUkFUT1JfQVhJU19OT1RfSU1QTEVNRU5URUQgPSAiRVJfVFlQRURfSVRFUkFUT1JfQVhJU19OT1RfSU1QTEVNRU5URUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JVEVSQVRPUl9BWElTX05PVF9JTVBMRU1FTlRFRCA9ICJFUl9JVEVSQVRPUl9BWElTX05PVF9JTVBMRU1FTlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lURVJBVE9SX0NMT05FX05PVF9TVVBQT1JURUQgPSAiRVJfSVRFUkFUT1JfQ0xPTkVfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1VOS05PV05fQVhJU19UWVBFID0gIkVSX1VOS05PV05fQVhJU19UWVBFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQVhJU19OT1RfU1VQUE9SVEVEID0gIkVSX0FYSVNfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX0RUTUlEU19BVkFJTCA9ICJFUl9OT19EVE1JRFNfQVZBSUwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT1RfU1VQUE9SVEVEID0gIkVSX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT0RFX05PTl9OVUxMID0gIkVSX05PREVfTk9OX05VTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRF9OT1RfUkVTT0xWRV9OT0RFID0gIkVSX0NPVUxEX05PVF9SRVNPTFZFX05PREUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TVEFSVFBBUlNFX1dISUxFX1BBUlNJTkcgPSAiRVJfU1RBUlRQQVJTRV9XSElMRV9QQVJTSU5HIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU1RBUlRQQVJTRV9ORUVEU19TQVhQQVJTRVIgPSAiRVJfU1RBUlRQQVJTRV9ORUVEU19TQVhQQVJTRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRF9OT1RfSU5JVF9QQVJTRVIgPSAiRVJfQ09VTERfTk9UX0lOSVRfUEFSU0VSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhDRVBUSU9OX0NSRUFUSU5HX1BPT0wgPSAiRVJfRVhDRVBUSU9OX0NSRUFUSU5HX1BPT0wiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QQVRIX0NPTlRBSU5TX0lOVkFMSURfRVNDQVBFX1NFUVVFTkNFID0gIkVSX1BBVEhfQ09OVEFJTlNfSU5WQUxJRF9FU0NBUEVfU0VRVUVOQ0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TQ0hFTUVfUkVRVUlSRUQgPSAiRVJfU0NIRU1FX1JFUVVJUkVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fU0NIRU1FX0lOX1VSSSA9ICJFUl9OT19TQ0hFTUVfSU5fVVJJIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fU0NIRU1FX0lOVVJJID0gIkVSX05PX1NDSEVNRV9JTlVSSSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BBVEhfSU5WQUxJRF9DSEFSID0gIkVSX1BBVEhfSU5WQUxJRF9DSEFSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU0NIRU1FX0ZST01fTlVMTF9TVFJJTkcgPSAiRVJfU0NIRU1FX0ZST01fTlVMTF9TVFJJTkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TQ0hFTUVfTk9UX0NPTkZPUk1BTlQgPSAiRVJfU0NIRU1FX05PVF9DT05GT1JNQU5UIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSE9TVF9BRERSRVNTX05PVF9XRUxMRk9STUVEID0gIkVSX0hPU1RfQUREUkVTU19OT1RfV0VMTEZPUk1FRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BPUlRfV0hFTl9IT1NUX05VTEwgPSAiRVJfUE9SVF9XSEVOX0hPU1RfTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfUE9SVCA9ICJFUl9JTlZBTElEX1BPUlQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GUkFHX0ZPUl9HRU5FUklDX1VSSSA9IkVSX0ZSQUdfRk9SX0dFTkVSSUNfVVJJIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRlJBR19XSEVOX1BBVEhfTlVMTCA9ICJFUl9GUkFHX1dIRU5fUEFUSF9OVUxMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRlJBR19JTlZBTElEX0NIQVIgPSAiRVJfRlJBR19JTlZBTElEX0NIQVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QQVJTRVJfSU5fVVNFID0gIkVSX1BBUlNFUl9JTl9VU0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfQ0hBTkdFX1dISUxFX1BBUlNJTkcgPSAiRVJfQ0FOTk9UX0NIQU5HRV9XSElMRV9QQVJTSU5HIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU0VMRl9DQVVTQVRJT05fTk9UX1BFUk1JVFRFRCA9ICJFUl9TRUxGX0NBVVNBVElPTl9OT1RfUEVSTUlUVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fVVNFUklORk9fSUZfTk9fSE9TVCA9ICJFUl9OT19VU0VSSU5GT19JRl9OT19IT1NUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fUE9SVF9JRl9OT19IT1NUID0gIkVSX05PX1BPUlRfSUZfTk9fSE9TVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1FVRVJZX1NUUklOR19JTl9QQVRIID0gIkVSX05PX1FVRVJZX1NUUklOR19JTl9QQVRIIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fRlJBR01FTlRfU1RSSU5HX0lOX1BBVEggPSAiRVJfTk9fRlJBR01FTlRfU1RSSU5HX0lOX1BBVEgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfSU5JVF9VUklfRU1QVFlfUEFSTVMgPSAiRVJfQ0FOTk9UX0lOSVRfVVJJX0VNUFRZX1BBUk1TIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTUVUSE9EX05PVF9TVVBQT1JURUQgPSJFUl9NRVRIT0RfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOQ1JTQVhTUkNGSUxURVJfTk9UX1JFU1RBUlRBQkxFID0gIkVSX0lOQ1JTQVhTUkNGSUxURVJfTk9UX1JFU1RBUlRBQkxFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWE1MUkRSX05PVF9CRUZPUkVfU1RBUlRQQVJTRSA9ICJFUl9YTUxSRFJfTk9UX0JFRk9SRV9TVEFSVFBBUlNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQVhJU19UUkFWRVJTRVJfTk9UX1NVUFBPUlRFRCA9ICJFUl9BWElTX1RSQVZFUlNFUl9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVJST1JIQU5ETEVSX0NSRUFURURfV0lUSF9OVUxMX1BSSU5UV1JJVEVSID0gIkVSX0VSUk9SSEFORExFUl9DUkVBVEVEX1dJVEhfTlVMTF9QUklOVFdSSVRFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NZU1RFTUlEX1VOS05PV04gPSAiRVJfU1lTVEVNSURfVU5LTk9XTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0xPQ0FUSU9OX1VOS05PV04gPSAiRVJfTE9DQVRJT05fVU5LTk9XTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BSRUZJWF9NVVNUX1JFU09MVkUgPSAiRVJfUFJFRklYX01VU1RfUkVTT0xWRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NSRUFURURPQ1VNRU5UX05PVF9TVVBQT1JURUQgPSAiRVJfQ1JFQVRFRE9DVU1FTlRfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NISUxEX0hBU19OT19PV05FUl9ET0NVTUVOVCA9ICJFUl9DSElMRF9IQVNfTk9fT1dORVJfRE9DVU1FTlQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DSElMRF9IQVNfTk9fT1dORVJfRE9DVU1FTlRfRUxFTUVOVCA9ICJFUl9DSElMRF9IQVNfTk9fT1dORVJfRE9DVU1FTlRfRUxFTUVOVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfT1VUUFVUX1RFWFRfQkVGT1JFX0RPQyA9ICJFUl9DQU5UX09VVFBVVF9URVhUX0JFRk9SRV9ET0MiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX0hBVkVfTU9SRV9USEFOX09ORV9ST09UID0gIkVSX0NBTlRfSEFWRV9NT1JFX1RIQU5fT05FX1JPT1QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9BUkdfTE9DQUxOQU1FX05VTEwgPSAiRVJfQVJHX0xPQ0FMTkFNRV9OVUxMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQVJHX0xPQ0FMTkFNRV9JTlZBTElEID0gIkVSX0FSR19MT0NBTE5BTUVfSU5WQUxJRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FSR19QUkVGSVhfSU5WQUxJRCA9ICJFUl9BUkdfUFJFRklYX0lOVkFMSUQiOwotCi0gIC8vIE1lc3NhZ2Uga2V5cyB1c2VkIGJ5IHRoZSBzZXJpYWxpemVyCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1JFU09VUkNFX0NPVUxEX05PVF9GSU5EID0gIkVSX1JFU09VUkNFX0NPVUxEX05PVF9GSU5EIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUkVTT1VSQ0VfQ09VTERfTk9UX0xPQUQgPSAiRVJfUkVTT1VSQ0VfQ09VTERfTk9UX0xPQUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9CVUZGRVJfU0laRV9MRVNTVEhBTl9aRVJPID0gIkVSX0JVRkZFUl9TSVpFX0xFU1NUSEFOX1pFUk8iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX1VURjE2X1NVUlJPR0FURSA9ICJFUl9JTlZBTElEX1VURjE2X1NVUlJPR0FURSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX09JRVJST1IgPSAiRVJfT0lFUlJPUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05BTUVTUEFDRV9QUkVGSVggPSAiRVJfTkFNRVNQQUNFX1BSRUZJWCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NUUkFZX0FUVFJJQlVURSA9ICJFUl9TVFJBWV9BVFRJUkJVVEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TVFJBWV9OQU1FU1BBQ0UgPSAiRVJfU1RSQVlfTkFNRVNQQUNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTERfTk9UX0xPQURfUkVTT1VSQ0UgPSAiRVJfQ09VTERfTk9UX0xPQURfUkVTT1VSQ0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRF9OT1RfTE9BRF9NRVRIT0RfUFJPUEVSVFkgPSAiRVJfQ09VTERfTk9UX0xPQURfTUVUSE9EX1BST1BFUlRZIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU0VSSUFMSVpFUl9OT1RfQ09OVEVOVEhBTkRMRVIgPSAiRVJfU0VSSUFMSVpFUl9OT1RfQ09OVEVOVEhBTkRMRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTExFR0FMX0FUVFJJQlVURV9QT1NJVElPTiA9ICJFUl9JTExFR0FMX0FUVFJJQlVURV9QT1NJVElPTiI7Ci0KLSAgLyoKLSAgICogTm93IGZpbGwgaW4gdGhlIG1lc3NhZ2UgdGV4dC4KLSAgICogVGhlbiBmaWxsIGluIHRoZSBtZXNzYWdlIHRleHQgZm9yIHRoYXQgbWVzc2FnZSBjb2RlIGluIHRoZQotICAgKiBhcnJheS4gVXNlIHRoZSBuZXcgZXJyb3IgY29kZSBhcyB0aGUgaW5kZXggaW50byB0aGUgYXJyYXkuCi0gICAqLwotCi0gIC8vIEVycm9yIG1lc3NhZ2VzLi4uCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIE9iamVjdFtdW10gX2NvbnRlbnRzID0gbmV3IE9iamVjdFtdW10gewotCi0gIC8qKiBFcnJvciBtZXNzYWdlIElEIHRoYXQgaGFzIGEgbnVsbCBtZXNzYWdlLCBidXQgdGFrZXMgaW4gYSBzaW5nbGUgb2JqZWN0LiAgICAqLwotICAgIHsiRVIwMDAwIiAsICJ7MH0iIH0sCi0KLSAgICB7IEVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQsCi0gICAgICAiTmVwb2Rwb3JvdmFuXHUwMGUxIGZ1bmtjZSEifSwKLQotICAgIHsgRVJfQ0FOTk9UX09WRVJXUklURV9DQVVTRSwKLSAgICAgICJQXHUwMTU5XHUwMGVkXHUwMTBkaW51IG5lbHplIHBcdTAxNTllcHNhdCJ9LAotCi0gICAgeyBFUl9OT19ERUZBVUxUX0lNUEwsCi0gICAgICAiTmVieWxhIG5hbGV6ZW5hIHZcdTAwZmRjaG96XHUwMGVkIGltcGxlbWVudGFjZS4gIn0sCi0KLSAgICB7IEVSX0NIVU5LRURJTlRBUlJBWV9OT1RfU1VQUE9SVEVELAotICAgICAgIkZ1bmtjZSBDaHVua2VkSW50QXJyYXkoezB9KSBuZW5cdTAwZWQgYWt0dVx1MDBlMWxuXHUwMTFiIHBvZHBvcm92XHUwMGUxbmEuIn0sCi0KLSAgICB7IEVSX09GRlNFVF9CSUdHRVJfVEhBTl9TTE9ULAotICAgICAgIk9mZnNldCBqZSB2XHUwMTFidFx1MDE2MVx1MDBlZCBuZVx1MDE3ZSBzbG90LiJ9LAotCi0gICAgeyBFUl9DT1JPVVRJTkVfTk9UX0FWQUlMLAotICAgICAgIlNwb2xlXHUwMTBkblx1MDBlMSBydXRpbmEgbmVuXHUwMGVkIGsgZGlzcG96aWNpLCBpZD17MH0ifSwKLQotICAgIHsgRVJfQ09ST1VUSU5FX0NPX0VYSVQsCi0gICAgICAiRnVua2NlIENvcm91dGluZU1hbmFnZXIgb2Jkclx1MDE3ZWVsYSBwb1x1MDE3ZWFkYXZlayBjb19leGl0KCkifSwKLQotICAgIHsgRVJfQ09KT0lOUk9VVElORVNFVF9GQUlMRUQsCi0gICAgICAiU2VsaGFsYSBmdW5rY2UgY29fam9pbkNvcm91dGluZVNldCgpIn0sCi0KLSAgICB7IEVSX0NPUk9VVElORV9QQVJBTSwKLSAgICAgICJDaHliYSBwYXJhbWV0cnUgc3BvbGVcdTAxMGRuXHUwMGU5IHJ1dGlueSAoezB9KSJ9LAotCi0gICAgeyBFUl9QQVJTRVJfRE9URVJNSU5BVEVfQU5TV0VSUywKLSAgICAgICJcbk5lb1x1MDEwZGVrXHUwMGUxdmFuXHUwMGU5OiBvZHBvdlx1MDExYmRpIGZ1bmtjZSBhbmFseXpcdTAwZTF0b3J1IGRvVGVybWluYXRlIHswfSJ9LAotCi0gICAgeyBFUl9OT19QQVJTRV9DQUxMX1dISUxFX1BBUlNJTkcsCi0gICAgICAiYlx1MDExYmhlbSBhbmFsXHUwMGZkenkgbmVsemUgdm9sYXQgYW5hbHl6XHUwMGUxdG9yIn0sCi0KLSAgICB7IEVSX1RZUEVEX0lURVJBVE9SX0FYSVNfTk9UX0lNUExFTUVOVEVELAotICAgICAgIkNoeWJhOiB6YWRhblx1MDBmZCBpdGVyXHUwMGUxdG9yIG9zeSB7MH0gbmVuXHUwMGVkIGltcGxlbWVudG92XHUwMGUxbiJ9LAotCi0gICAgeyBFUl9JVEVSQVRPUl9BWElTX05PVF9JTVBMRU1FTlRFRCwKLSAgICAgICJDaHliYTogemFkYW5cdTAwZmQgaXRlclx1MDBlMXRvciBvc3kgezB9IG5lblx1MDBlZCBpbXBsZW1lbnRvdlx1MDBlMW4gIn0sCi0KLSAgICB7IEVSX0lURVJBVE9SX0NMT05FX05PVF9TVVBQT1JURUQsCi0gICAgICAiTmVwb2Rwb3JvdmFuXHUwMGZkIGtsb24gaXRlclx1MDBlMXRvcnUuIn0sCi0KLSAgICB7IEVSX1VOS05PV05fQVhJU19UWVBFLAotICAgICAgIk5lem5cdTAwZTFtXHUwMGZkIHR5cCBvc3kgcHJcdTAxNmZjaG9kdTogezB9In0sCi0KLSAgICB7IEVSX0FYSVNfTk9UX1NVUFBPUlRFRCwKLSAgICAgICJOZXBvZHBvcm92YW5cdTAwZTEgb3NhIHByXHUwMTZmY2hvZHU6IHswfSJ9LAotCi0gICAgeyBFUl9OT19EVE1JRFNfQVZBSUwsCi0gICAgICAiXHUwMTdkXHUwMGUxZG5cdTAwZTEgZGFsXHUwMTYxXHUwMGVkIElEIERUTSBuZWpzb3UgayBkaXNwb3ppY2kifSwKLQotICAgIHsgRVJfTk9UX1NVUFBPUlRFRCwKLSAgICAgICJOZXBvZHBvcm92XHUwMGUxbm86IHswfSJ9LAotCi0gICAgeyBFUl9OT0RFX05PTl9OVUxMLAotICAgICAgIlV6ZWwgcG91XHUwMTdlaXRcdTAwZmQgdmUgZnVua2NpIGdldERUTUhhbmRsZUZyb21Ob2RlIG11c1x1MDBlZCBtXHUwMGVkdCBob2Rub3R1IG5vdC1udWxsIn0sCi0KLSAgICB7IEVSX0NPVUxEX05PVF9SRVNPTFZFX05PREUsCi0gICAgICAiVXplbCBuZWx6ZSBwXHUwMTU5ZWxvXHUwMTdlaXQgZG8gbWFuaXB1bFx1MDBlMXRvcnUifSwKLQotICAgIHsgRVJfU1RBUlRQQVJTRV9XSElMRV9QQVJTSU5HLAotICAgICAgICJCXHUwMTFiaGVtIGFuYWxcdTAwZmR6eSBuZWx6ZSB2b2xhdCBmdW5rY2kgc3RhcnRQYXJzZS4ifSwKLQotICAgIHsgRVJfU1RBUlRQQVJTRV9ORUVEU19TQVhQQVJTRVIsCi0gICAgICAgIkZ1bmtjZSBzdGFydFBhcnNlIHZ5XHUwMTdlYWR1amUgU0FYUGFyc2VyIHMgaG9kbm90b3Ugbm90LW51bGwuIn0sCi0KLSAgICB7IEVSX0NPVUxEX05PVF9JTklUX1BBUlNFUiwKLSAgICAgICAibmVsemUgaW5pY2lhbGl6b3ZhdCBhbmFseXpcdTAwZTF0b3IgczogIn0sCi0KLSAgICB7IEVSX0VYQ0VQVElPTl9DUkVBVElOR19QT09MLAotICAgICAgICJ2XHUwMGZkamlta2EgcFx1MDE1OWkgdnl0dlx1MDBlMVx1MDE1OWVuXHUwMGVkIG5vdlx1MDBlOSBpbnN0YW5jZSBzcG9sZVx1MDEwZG5cdTAwZTkgb2JsYXN0aSJ9LAotCi0gICAgeyBFUl9QQVRIX0NPTlRBSU5TX0lOVkFMSURfRVNDQVBFX1NFUVVFTkNFLAotICAgICAgICJDZXN0YSBvYnNhaHVqZSBuZXBsYXRub3UgZXNjYXBlIHNla3ZlbmNpIn0sCi0KLSAgICB7IEVSX1NDSEVNRV9SRVFVSVJFRCwKLSAgICAgICAiSmUgdnlcdTAxN2VhZG92XHUwMGUxbm8gc2NoXHUwMGU5bWEhIn0sCi0KLSAgICB7IEVSX05PX1NDSEVNRV9JTl9VUkksCi0gICAgICAgIlYgVVJJIG5lYnlsbyBuYWxlemVubyBcdTAxN2VcdTAwZTFkblx1MDBlOSBzY2hcdTAwZTltYTogezB9In0sCi0KLSAgICB7IEVSX05PX1NDSEVNRV9JTlVSSSwKLSAgICAgICAiViBVUkkgbmVieWxvIG5hbGV6ZW5vIFx1MDE3ZVx1MDBlMWRuXHUwMGU5IHNjaFx1MDBlOW1hIn0sCi0KLSAgICB7IEVSX1BBVEhfSU5WQUxJRF9DSEFSLAotICAgICAgICJDZXN0YSBvYnNhaHVqZSBuZXBsYXRuXHUwMGZkIHpuYWs6IHswfSJ9LAotCi0gICAgeyBFUl9TQ0hFTUVfRlJPTV9OVUxMX1NUUklORywKLSAgICAgICAiTmVsemUgbmFzdGF2aXQgc2NoXHUwMGU5bWEgXHUwMTU5ZXRcdTAxMWJ6Y2UgcyBob2Rub3RvdSBudWxsLiJ9LAotCi0gICAgeyBFUl9TQ0hFTUVfTk9UX0NPTkZPUk1BTlQsCi0gICAgICAgIlNjaFx1MDBlOW1hIG5ldnlob3Z1amUuIn0sCi0KLSAgICB7IEVSX0hPU1RfQUREUkVTU19OT1RfV0VMTEZPUk1FRCwKLSAgICAgICAiQWRyZXNhIGhvc3RpdGVsZSBtXHUwMGUxIG5lc3ByXHUwMGUxdm5cdTAwZmQgZm9ybVx1MDBlMXQuIn0sCi0KLSAgICB7IEVSX1BPUlRfV0hFTl9IT1NUX05VTEwsCi0gICAgICAgIk1cdTAwZTEtbGkgaG9zdGl0ZWwgaG9kbm90dSBudWxsLCBuZWx6ZSBuYXN0YXZpdCBwb3J0LiJ9LAotCi0gICAgeyBFUl9JTlZBTElEX1BPUlQsCi0gICAgICAgIk5lcGxhdG5cdTAwZTkgXHUwMTBkXHUwMGVkc2xvIHBvcnR1LiJ9LAotCi0gICAgeyBFUl9GUkFHX0ZPUl9HRU5FUklDX1VSSSwKLSAgICAgICAiRnJhZ21lbnQgbHplIG5hc3Rhdml0IGplbiB1IGdlbmVyaWNrXHUwMGU5aG8gVVJJLiJ9LAotCi0gICAgeyBFUl9GUkFHX1dIRU5fUEFUSF9OVUxMLAotICAgICAgICJNXHUwMGUxLWxpIGNlc3RhIGhvZG5vdHUgbnVsbCwgbmVsemUgbmFzdGF2aXQgZnJhZ21lbnQuIn0sCi0KLSAgICB7IEVSX0ZSQUdfSU5WQUxJRF9DSEFSLAotICAgICAgICJGcmFnbWVudCBvYnNhaHVqZSBuZXBsYXRuXHUwMGZkIHpuYWsuIn0sCi0KLSAgICB7IEVSX1BBUlNFUl9JTl9VU0UsCi0gICAgICAiQW5hbHl6XHUwMGUxdG9yIHNlIGppXHUwMTdlIHBvdVx1MDE3ZVx1MDBlZHZcdTAwZTEuIn0sCi0KLSAgICB7IEVSX0NBTk5PVF9DSEFOR0VfV0hJTEVfUEFSU0lORywKLSAgICAgICJCXHUwMTFiaGVtIGFuYWxcdTAwZmR6eSBuZWx6ZSBtXHUwMTFibml0IHswfSB7MX0uIn0sCi0KLSAgICB7IEVSX1NFTEZfQ0FVU0FUSU9OX05PVF9QRVJNSVRURUQsCi0gICAgICAiWnBcdTAxNmZzb2Jlblx1MDBlZCBzYW1hIHNlYmUgKHNlbGYtY2F1c2F0aW9uKSBuZW5cdTAwZWQgcG92b2xlbm8ifSwKLQotICAgIHsgRVJfTk9fVVNFUklORk9fSUZfTk9fSE9TVCwKLSAgICAgICJOZW5cdTAwZWQtbGkgdXJcdTAxMGRlbiBob3N0aXRlbCwgbmVsemUgemFkYXQgXHUwMGZhZGFqZSBvIHVcdTAxN2VpdmF0ZWxpLiJ9LAotCi0gICAgeyBFUl9OT19QT1JUX0lGX05PX0hPU1QsCi0gICAgICAiTmVuXHUwMGVkLWxpIHVyXHUwMTBkZW4gaG9zdGl0ZWwsIG5lbHplIHphZGF0IHBvcnQuIn0sCi0KLSAgICB7IEVSX05PX1FVRVJZX1NUUklOR19JTl9QQVRILAotICAgICAgIlYgXHUwMTU5ZXRcdTAxMWJ6Y2kgY2VzdHkgYSBkb3RhenUgbmVsemUgemFkYXQgXHUwMTU5ZXRcdTAxMWJ6ZWMgZG90YXp1LiJ9LAotCi0gICAgeyBFUl9OT19GUkFHTUVOVF9TVFJJTkdfSU5fUEFUSCwKLSAgICAgICJGcmFnbWVudCBuZWx6ZSB1clx1MDEwZGl0IHpcdTAwZTFyb3ZlXHUwMTQ4IHYgY2VzdFx1MDExYiBpIHZlIGZyYWdtZW50dS4ifSwKLQotICAgIHsgRVJfQ0FOTk9UX0lOSVRfVVJJX0VNUFRZX1BBUk1TLAotICAgICAgIlVSSSBuZWx6ZSBpbmljaWFsaXpvdmF0IHMgcHJcdTAwZTF6ZG5cdTAwZmRtaSBwYXJhbWV0cnkuIn0sCi0KLSAgICB7IEVSX01FVEhPRF9OT1RfU1VQUE9SVEVELAotICAgICAgIlByb3phdFx1MDBlZG0gbmVwb2Rwb3JvdmFuXHUwMGUxIG1ldG9kYS4gIn0sCi0KLSAgICB7IEVSX0lOQ1JTQVhTUkNGSUxURVJfTk9UX1JFU1RBUlRBQkxFLAotICAgICAgIkZpbHRyIEluY3JlbWVudGFsU0FYU291cmNlX0ZpbHRlciBuZWx6ZSBha3R1XHUwMGUxbG5cdTAxMWIgem5vdnUgc3B1c3RpdC4ifSwKLQotICAgIHsgRVJfWE1MUkRSX05PVF9CRUZPUkVfU1RBUlRQQVJTRSwKLSAgICAgICJQXHUwMTU5ZWQgcG9cdTAxN2VhZGF2a2VtIHN0YXJ0UGFyc2UgbmVuXHUwMGVkIFhNTFJlYWRlci4ifSwKLQotICAgIHsgRVJfQVhJU19UUkFWRVJTRVJfTk9UX1NVUFBPUlRFRCwKLSAgICAgICJOZXBvZHBvcm92YW5cdTAwZTEgb3NhIHByXHUwMTZmY2hvZHU6IHswfSJ9LAotCi0gICAgeyBFUl9FUlJPUkhBTkRMRVJfQ1JFQVRFRF9XSVRIX05VTExfUFJJTlRXUklURVIsCi0gICAgICAiUHJ2ZWsgTGlzdGluZ0Vycm9ySGFuZGxlciBieWwgdnl0dm9cdTAxNTllbiBzIGZ1bmtjXHUwMGVkIFByaW50V3JpdGVyIHMgaG9kbm90b3UgbnVsbCEifSwKLQotICAgIHsgRVJfU1lTVEVNSURfVU5LTk9XTiwKLSAgICAgICJOZXpuXHUwMGUxbVx1MDBmZCBpZGVudGlmaWtcdTAwZTF0b3IgU3lzdGVtSWQifSwKLQotICAgIHsgRVJfTE9DQVRJT05fVU5LTk9XTiwKLSAgICAgICJDaHliYSBzZSB2eXNreXRsYSBuYSBuZXpuXHUwMGUxbVx1MDBlOW0gbVx1MDBlZHN0XHUwMTFiIn0sCi0KLSAgICB7IEVSX1BSRUZJWF9NVVNUX1JFU09MVkUsCi0gICAgICAiUFx1MDE1OWVkcG9udSBtdXNcdTAwZWQgYlx1MDBmZHQgbW9cdTAxN2VubyBwXHUwMTU5ZWxvXHUwMTdlaXQgZG8gb2JvcnUgblx1MDBlMXp2XHUwMTZmOiB7MH0ifSwKLQotICAgIHsgRVJfQ1JFQVRFRE9DVU1FTlRfTk9UX1NVUFBPUlRFRCwKLSAgICAgICJGdW5rY2UgWFBhdGhDb250ZXh0IG5lcG9kcG9ydWplIGZ1bmtjaSBjcmVhdGVEb2N1bWVudCgpISJ9LAotCi0gICAgeyBFUl9DSElMRF9IQVNfTk9fT1dORVJfRE9DVU1FTlQsCi0gICAgICAiUG90b21layBhdHJpYnV0dSBuZW1cdTAwZTEgZG9rdW1lbnQgdmxhc3RuXHUwMGVka2EhIn0sCi0KLSAgICB7IEVSX0NISUxEX0hBU19OT19PV05FUl9ET0NVTUVOVF9FTEVNRU5ULAotICAgICAgIlBvdG9tZWsgYXRyaWJ1dHUgbmVtXHUwMGUxIHBydmVrIGRva3VtZW50dSB2bGFzdG5cdTAwZWRrYSEifSwKLQotICAgIHsgRVJfQ0FOVF9PVVRQVVRfVEVYVF9CRUZPUkVfRE9DLAotICAgICAgIlZhcm92XHUwMGUxblx1MDBlZDogdlx1MDBmZHN0dXAgdGV4dHUgbmVtXHUwMTZmXHUwMTdlZSBwXHUwMTU5ZWRjaFx1MDBlMXpldCBwcnZrdSBkb2t1bWVudHUhIElnbm9yb3ZcdTAwZTFuby4uLiJ9LAotCi0gICAgeyBFUl9DQU5UX0hBVkVfTU9SRV9USEFOX09ORV9ST09ULAotICAgICAgIkRPTSBuZW1cdTAxNmZcdTAxN2VlIG1cdTAwZWR0IG5cdTAxMWJrb2xpayBrb1x1MDE1OWVuXHUwMTZmISJ9LAotCi0gICAgeyBFUl9BUkdfTE9DQUxOQU1FX05VTEwsCi0gICAgICAgIkFyZ3VtZW50ICdsb2NhbE5hbWUnIG1cdTAwZTEgaG9kbm90dSBudWxsIn0sCi0KLSAgICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQSBRTkFNRSBoYXMgdGhlIHN5bnRhY3RpYyBmb3JtIFtOQ05hbWU6XU5DTmFtZQotICAgIC8vIFRoZSBsb2NhbG5hbWUgaXMgdGhlIHBvcnRpb24gYWZ0ZXIgdGhlIG9wdGlvbmFsIGNvbG9uOyB0aGUgbWVzc2FnZSBpbmRpY2F0ZXMKLSAgICAvLyB0aGF0IHRoZXJlIGlzIGEgcHJvYmxlbSB3aXRoIHRoYXQgcGFydCBvZiB0aGUgUU5BTUUuCi0gICAgeyBFUl9BUkdfTE9DQUxOQU1FX0lOVkFMSUQsCi0gICAgICAgIkhvZG5vdGEgTG9jYWxuYW1lIHZlIGZ1bmtjaSBRTkFNRSBieSBtXHUwMTFibGEgYlx1MDBmZHQgcGxhdG5cdTAwZmRtIHBydmtlbSBOQ05hbWUifSwKLQotICAgIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBIFFOQU1FIGhhcyB0aGUgc3ludGFjdGljIGZvcm0gW05DTmFtZTpdTkNOYW1lCi0gICAgLy8gVGhlIHByZWZpeCBpcyB0aGUgcG9ydGlvbiBiZWZvcmUgdGhlIG9wdGlvbmFsIGNvbG9uOyB0aGUgbWVzc2FnZSBpbmRpY2F0ZXMKLSAgICAvLyB0aGF0IHRoZXJlIGlzIGEgcHJvYmxlbSB3aXRoIHRoYXQgcGFydCBvZiB0aGUgUU5BTUUuCi0gICAgeyBFUl9BUkdfUFJFRklYX0lOVkFMSUQsCi0gICAgICAgIlBcdTAxNTllZHBvbmEgdmUgZnVua2NpIFFOQU1FIGJ5IG1cdTAxMWJsYSBiXHUwMGZkdCBwbGF0blx1MDBmZG0gcHJ2a2VtIE5DTmFtZSJ9LAotCi0gICAgeyAiQkFEX0NPREUiLCAiUGFyYW1ldHIgZnVua2NlIGNyZWF0ZU1lc3NhZ2UgamUgbWltbyBsaW1pdCJ9LAotICAgIHsgIkZPUk1BVF9GQUlMRUQiLCAiUFx1MDE1OWkgdm9sXHUwMGUxblx1MDBlZCBmdW5rY2UgbWVzc2FnZUZvcm1hdCBkb1x1MDE2MWxvIGsgdlx1MDBmZGppbWNlIn0sCi0gICAgeyAibGluZSIsICJcdTAxNThcdTAwZTFkZWsgIyJ9LAotICAgIHsgImNvbHVtbiIsIlNsb3VwZWMgIyJ9LAotCi0gICAge0VSX1NFUklBTElaRVJfTk9UX0NPTlRFTlRIQU5ETEVSLAotICAgICAgIlRcdTAxNTlcdTAwZWRkYSBzZXJpYWxpemFjZSAnJ3swfScnIG5laW1wbGVtZW50dWplIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyLiJ9LAotCi0gICAge0VSX1JFU09VUkNFX0NPVUxEX05PVF9GSU5ELAotICAgICAgIk5lbHplIG5halx1MDBlZHQgemRyb2ogWyB7MH0gXS5cbiB7MX0iIH0sCi0KLSAgICB7RVJfUkVTT1VSQ0VfQ09VTERfTk9UX0xPQUQsCi0gICAgICAiTmVsemUgemF2XHUwMGU5c3QgemRyb2ogWyB7MH0gXTogezF9IFxuIHsyfSBcdCB7M30iIH0sCi0KLSAgICB7RVJfQlVGRkVSX1NJWkVfTEVTU1RIQU5fWkVSTywKLSAgICAgICJWZWxpa29zdCB2eXJvdm5cdTAwZTF2YWNcdTAwZWQgcGFtXHUwMTFidGkgPD0wIiB9LAotCi0gICAge0VSX0lOVkFMSURfVVRGMTZfU1VSUk9HQVRFLAotICAgICAgIkJ5bGEgemppXHUwMTYxdFx1MDExYm5hIG5lcGxhdG5cdTAwZTEgblx1MDBlMWhyYWRhIFVURi0xNjogezB9ID8iIH0sCi0KLSAgICB7RVJfT0lFUlJPUiwKLSAgICAgICJDaHliYSB2c3R1cHUvdlx1MDBmZHN0dXB1IiB9LAotCi0gICAge0VSX0lMTEVHQUxfQVRUUklCVVRFX1BPU0lUSU9OLAotICAgICAgIk5lbHplIHBcdTAxNTlpZGF0IGF0cmlidXQgezB9IHBvIHV6bGVjaCBwb3RvbWtcdTAxNmYgYW5pIHBcdTAxNTllZCB0XHUwMGVkbSwgbmVcdTAxN2UgamUgdnl0dm9cdTAxNTllbiBwcnZlay4gQXRyaWJ1dCBidWRlIGlnbm9yb3ZcdTAwZTFuLiJ9LAotCi0gICAgICAvKgotICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IGNvbnRhaW5lZCBhIHJlZmVyZW5jZSB0byBhCi0gICAgICAgKiBuYW1lc3BhY2UgcHJlZml4IHRoYXQgd2FzIHVuZGVmaW5lZC4gIFRoZSB2YWx1ZSBvZiB0aGUgc3Vic3RpdHV0aW9uCi0gICAgICAgKiB0ZXh0IGlzIHRoZSBuYW1lIG9mIHRoZSBwcmVmaXguCi0gICAgICAgKi8KLSAgICB7RVJfTkFNRVNQQUNFX1BSRUZJWCwKLSAgICAgICJPYm9yIG5cdTAwZTF6dlx1MDE2ZiBwcm8gcFx1MDE1OWVkcG9udSAnJ3swfScnIG5lYnlsIGRla2xhcm92XHUwMGUxbi4iIH0sCi0gICAgICAvKgotICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyByZXBvcnRlZCBpZiB0aGUgc3R5bGVzaGVldAotICAgICAgICogYmVpbmcgcHJvY2Vzc2VkIGF0dGVtcHRlZCB0byBjb25zdHJ1Y3QgYW4gWE1MIGRvY3VtZW50IHdpdGggYW4KLSAgICAgICAqIGF0dHJpYnV0ZSBpbiBhIHBsYWNlIG90aGVyIHRoYW4gb24gYW4gZWxlbWVudC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICogc3BlY2lmaWVzIHRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUuCi0gICAgICAgKi8KLSAgICB7RVJfU1RSQVlfQVRUUklCVVRFLAotICAgICAgIkF0cmlidXQgJyd7MH0nJyBqZSB2blx1MDExYiBwcnZrdS4iIH0sCi0KLSAgICAgIC8qCi0gICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQXMgd2l0aCB0aGUgcHJlY2VkaW5nIG1lc3NhZ2UsIGEgbmFtZXNwYWNlCi0gICAgICAgKiBkZWNsYXJhdGlvbiBoYXMgdGhlIGZvcm0gb2YgYW4gYXR0cmlidXRlIGFuZCBpcyBvbmx5IHBlcm1pdHRlZCB0bwotICAgICAgICogYXBwZWFyIG9uIGFuIGVsZW1lbnQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgezB9IGlzIHRoZSBuYW1lc3BhY2UKLSAgICAgICAqIHByZWZpeCBhbmQgezF9IGlzIHRoZSBVUkkgdGhhdCB3YXMgYmVpbmcgdXNlZCBpbiB0aGUgZXJyb25lb3VzCi0gICAgICAgKiBuYW1lc3BhY2UgZGVjbGFyYXRpb24uCi0gICAgICAgKi8KLSAgICB7RVJfU1RSQVlfTkFNRVNQQUNFLAotICAgICAgIkRla2xhcmFjZSBvYm9ydSBuXHUwMGUxenZcdTAxNmYgJyd7MH0nJz0nJ3sxfScnIGplIHZuXHUwMTFiIHBydmt1LiIgfSwKLQotICAgIHtFUl9DT1VMRF9OT1RfTE9BRF9SRVNPVVJDRSwKLSAgICAgICJOZWx6ZSB6YXZcdTAwZTlzdCAnJ3swfScnICh6a29udHJvbHVqdGUgcHJvbVx1MDExYm5ub3UgQ0xBU1NQQVRIKSwgcHJvdG8gc2UgcG91XHUwMTdlXHUwMGVkdmFqXHUwMGVkIHBvdXplIHZcdTAwZmRjaG96XHUwMGVkIGhvZG5vdHkifSwKLQotICAgIHtFUl9DT1VMRF9OT1RfTE9BRF9NRVRIT0RfUFJPUEVSVFksCi0gICAgICAiTmVsemUgbmFcdTAxMGRcdTAwZWRzdCBzb3Vib3Igdmxhc3Rub3N0XHUwMGVkICcnezB9JycgcHJvIHZcdTAwZmRzdHVwblx1MDBlZCBtZXRvZHUgJyd7MX0nJyAoemtvbnRyb2x1anRlIHByb21cdTAxMWJubm91IENMQVNTUEFUSCkuIiB9Ci0KLQotICB9OwotCi0gIC8qKgotICAgKiBHZXQgdGhlIGxvb2t1cCB0YWJsZSBmb3IgZXJyb3IgbWVzc2FnZXMKLSAgICoKLSAgICogQHJldHVybiBUaGUgYXNzb2NpYXRpb24gbGlzdC4KLSAgICovCi0gIHB1YmxpYyBPYmplY3RbXVtdIGdldENvbnRlbnRzKCkKLSAgewotICAgIHJldHVybiBfY29udGVudHM7Ci0gIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvcmVzL1hNTEVycm9yUmVzb3VyY2VzX2RlLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9yZXMvWE1MRXJyb3JSZXNvdXJjZXNfZGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMzQ5MmFlZi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9yZXMvWE1MRXJyb3JSZXNvdXJjZXNfZGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQ1MCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzOwotCi0KLWltcG9ydCBqYXZhLnV0aWwuTGlzdFJlc291cmNlQnVuZGxlOwotCi0vKioKLSAqIFNldCB1cCBlcnJvciBtZXNzYWdlcy4KLSAqIFdlIGJ1aWxkIGEgdHdvIGRpbWVuc2lvbmFsIGFycmF5IG9mIG1lc3NhZ2Uga2V5cyBhbmQKLSAqIG1lc3NhZ2Ugc3RyaW5ncy4gSW4gb3JkZXIgdG8gYWRkIGEgbmV3IG1lc3NhZ2UgaGVyZSwKLSAqIHlvdSBuZWVkIHRvIGZpcnN0IGFkZCBhIFN0cmluZyBjb25zdGFudC4gQW5kIHlvdSBuZWVkCi0gKiB0byBlbnRlciBrZXksIHZhbHVlIHBhaXIgYXMgcGFydCBvZiB0aGUgY29udGVudHMKLSAqIGFycmF5LiBZb3UgYWxzbyBuZWVkIHRvIHVwZGF0ZSBNQVhfQ09ERSBmb3IgZXJyb3Igc3RyaW5ncwotICogYW5kIE1BWF9XQVJOSU5HIGZvciB3YXJuaW5ncyAoIE5lZWRlZCBmb3Igb25seSBpbmZvcm1hdGlvbgotICogcHVycG9zZSApCi0gKi8KLXB1YmxpYyBjbGFzcyBYTUxFcnJvclJlc291cmNlc19kZSBleHRlbmRzIExpc3RSZXNvdXJjZUJ1bmRsZQotewotCi0vKgotICogVGhpcyBmaWxlIGNvbnRhaW5zIGVycm9yIGFuZCB3YXJuaW5nIG1lc3NhZ2VzIHJlbGF0ZWQgdG8gWGFsYW4gRXJyb3IKLSAqIEhhbmRsaW5nLgotICoKLSAqICBHZW5lcmFsIG5vdGVzIHRvIHRyYW5zbGF0b3JzOgotICoKLSAqICAxKSBYYWxhbiAob3IgbW9yZSBwcm9wZXJseSwgWGFsYW4taW50ZXJwcmV0aXZlKSBhbmQgWFNMVEMgYXJlIG5hbWVzIG9mCi0gKiAgICAgY29tcG9uZW50cy4KLSAqICAgICBYU0xUIGlzIGFuIGFjcm9ueW0gZm9yICJYTUwgU3R5bGVzaGVldCBMYW5ndWFnZTogVHJhbnNmb3JtYXRpb25zIi4KLSAqICAgICBYU0xUQyBpcyBhbiBhY3JvbnltIGZvciBYU0xUIENvbXBpbGVyLgotICoKLSAqICAyKSBBIHN0eWxlc2hlZXQgaXMgYSBkZXNjcmlwdGlvbiBvZiBob3cgdG8gdHJhbnNmb3JtIGFuIGlucHV0IFhNTCBkb2N1bWVudAotICogICAgIGludG8gYSByZXN1bHRhbnQgWE1MIGRvY3VtZW50IChvciBIVE1MIGRvY3VtZW50IG9yIHRleHQpLiAgVGhlCi0gKiAgICAgc3R5bGVzaGVldCBpdHNlbGYgaXMgZGVzY3JpYmVkIGluIHRoZSBmb3JtIG9mIGFuIFhNTCBkb2N1bWVudC4KLSAqCi0gKiAgMykgQSB0ZW1wbGF0ZSBpcyBhIGNvbXBvbmVudCBvZiBhIHN0eWxlc2hlZXQgdGhhdCBpcyB1c2VkIHRvIG1hdGNoIGEKLSAqICAgICBwYXJ0aWN1bGFyIHBvcnRpb24gb2YgYW4gaW5wdXQgZG9jdW1lbnQgYW5kIHNwZWNpZmllcyB0aGUgZm9ybSBvZiB0aGUKLSAqICAgICBjb3JyZXNwb25kaW5nIHBvcnRpb24gb2YgdGhlIG91dHB1dCBkb2N1bWVudC4KLSAqCi0gKiAgNCkgQW4gZWxlbWVudCBpcyBhIG1hcmstdXAgdGFnIGluIGFuIFhNTCBkb2N1bWVudDsgYW4gYXR0cmlidXRlIGlzIGEKLSAqICAgICBtb2RpZmllciBvbiB0aGUgdGFnLiAgRm9yIGV4YW1wbGUsIGluIDxlbGVtIGF0dHI9J3ZhbCcgYXR0cjI9J3ZhbDInPgotICogICAgICJlbGVtIiBpcyBhbiBlbGVtZW50IG5hbWUsICJhdHRyIiBhbmQgImF0dHIyIiBhcmUgYXR0cmlidXRlIG5hbWVzIHdpdGgKLSAqICAgICB0aGUgdmFsdWVzICJ2YWwiIGFuZCAidmFsMiIsIHJlc3BlY3RpdmVseS4KLSAqCi0gKiAgNSkgQSBuYW1lc3BhY2UgZGVjbGFyYXRpb24gaXMgYSBzcGVjaWFsIGF0dHJpYnV0ZSB0aGF0IGlzIHVzZWQgdG8gYXNzb2NpYXRlCi0gKiAgICAgYSBwcmVmaXggd2l0aCBhIFVSSSAodGhlIG5hbWVzcGFjZSkuICBUaGUgbWVhbmluZ3Mgb2YgZWxlbWVudCBuYW1lcyBhbmQKLSAqICAgICBhdHRyaWJ1dGUgbmFtZXMgdGhhdCB1c2UgdGhhdCBwcmVmaXggYXJlIGRlZmluZWQgd2l0aCByZXNwZWN0IHRvIHRoYXQKLSAqICAgICBuYW1lc3BhY2UuCi0gKgotICogIDYpICJUcmFuc2xldCIgaXMgYW4gaW52ZW50ZWQgdGVybSB0aGF0IGRlc2NyaWJlcyB0aGUgY2xhc3MgZmlsZSB0aGF0Ci0gKiAgICAgcmVzdWx0cyBmcm9tIGNvbXBpbGluZyBhbiBYTUwgc3R5bGVzaGVldCBpbnRvIGEgSmF2YSBjbGFzcy4KLSAqCi0gKiAgNykgWFBhdGggaXMgYSBzcGVjaWZpY2F0aW9uIHRoYXQgZGVzY3JpYmVzIGEgbm90YXRpb24gZm9yIGlkZW50aWZ5aW5nCi0gKiAgICAgbm9kZXMgaW4gYSB0cmVlLXN0cnVjdHVyZWQgcmVwcmVzZW50YXRpb24gb2YgYW4gWE1MIGRvY3VtZW50LiAgQW4KLSAqICAgICBpbnN0YW5jZSBvZiB0aGF0IG5vdGF0aW9uIGlzIHJlZmVycmVkIHRvIGFzIGFuIFhQYXRoIGV4cHJlc3Npb24uCi0gKgotICovCi0KLSAgLyoqIE1heGltdW0gZXJyb3IgbWVzc2FnZXMsIHRoaXMgaXMgbmVlZGVkIHRvIGtlZXAgdHJhY2sgb2YgdGhlIG51bWJlciBvZiBtZXNzYWdlcy4gICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFYX0NPREUgPSA2MTsKLQotICAvKiogTWF4aW11bSB3YXJuaW5ncywgdGhpcyBpcyBuZWVkZWQgdG8ga2VlcCB0cmFjayBvZiB0aGUgbnVtYmVyIG9mIHdhcm5pbmdzLiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVhfV0FSTklORyA9IDA7Ci0KLSAgLyoqIE1heGltdW0gbWlzYyBzdHJpbmdzLiAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BWF9PVEhFUlMgPSA0OwotCi0gIC8qKiBNYXhpbXVtIHRvdGFsIHdhcm5pbmdzIGFuZCBlcnJvciBtZXNzYWdlcy4gICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFYX01FU1NBR0VTID0gTUFYX0NPREUgKyBNQVhfV0FSTklORyArIDE7Ci0KLQotICAvKgotICAgKiBNZXNzYWdlIGtleXMKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQgPSAiRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9PVkVSV1JJVEVfQ0FVU0UgPSAiRVJfQ0FOTk9UX09WRVJXUklURV9DQVVTRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX0RFRkFVTFRfSU1QTCA9ICJFUl9OT19ERUZBVUxUX0lNUEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DSFVOS0VESU5UQVJSQVlfTk9UX1NVUFBPUlRFRCA9ICJFUl9DSFVOS0VESU5UQVJSQVlfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX09GRlNFVF9CSUdHRVJfVEhBTl9TTE9UID0gIkVSX09GRlNFVF9CSUdHRVJfVEhBTl9TTE9UIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09ST1VUSU5FX05PVF9BVkFJTCA9ICJFUl9DT1JPVVRJTkVfTk9UX0FWQUlMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09ST1VUSU5FX0NPX0VYSVQgPSAiRVJfQ09ST1VUSU5FX0NPX0VYSVQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT0pPSU5ST1VUSU5FU0VUX0ZBSUxFRCA9ICJFUl9DT0pPSU5ST1VUSU5FU0VUX0ZBSUxFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPUk9VVElORV9QQVJBTSA9ICJFUl9DT1JPVVRJTkVfUEFSQU0iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QQVJTRVJfRE9URVJNSU5BVEVfQU5TV0VSUyA9ICJFUl9QQVJTRVJfRE9URVJNSU5BVEVfQU5TV0VSUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1BBUlNFX0NBTExfV0hJTEVfUEFSU0lORyA9ICJFUl9OT19QQVJTRV9DQUxMX1dISUxFX1BBUlNJTkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9UWVBFRF9JVEVSQVRPUl9BWElTX05PVF9JTVBMRU1FTlRFRCA9ICJFUl9UWVBFRF9JVEVSQVRPUl9BWElTX05PVF9JTVBMRU1FTlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lURVJBVE9SX0FYSVNfTk9UX0lNUExFTUVOVEVEID0gIkVSX0lURVJBVE9SX0FYSVNfTk9UX0lNUExFTUVOVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSVRFUkFUT1JfQ0xPTkVfTk9UX1NVUFBPUlRFRCA9ICJFUl9JVEVSQVRPUl9DTE9ORV9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5LTk9XTl9BWElTX1RZUEUgPSAiRVJfVU5LTk9XTl9BWElTX1RZUEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9BWElTX05PVF9TVVBQT1JURUQgPSAiRVJfQVhJU19OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fRFRNSURTX0FWQUlMID0gIkVSX05PX0RUTUlEU19BVkFJTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PVF9TVVBQT1JURUQgPSAiRVJfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PREVfTk9OX05VTEwgPSAiRVJfTk9ERV9OT05fTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxEX05PVF9SRVNPTFZFX05PREUgPSAiRVJfQ09VTERfTk9UX1JFU09MVkVfTk9ERSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NUQVJUUEFSU0VfV0hJTEVfUEFSU0lORyA9ICJFUl9TVEFSVFBBUlNFX1dISUxFX1BBUlNJTkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TVEFSVFBBUlNFX05FRURTX1NBWFBBUlNFUiA9ICJFUl9TVEFSVFBBUlNFX05FRURTX1NBWFBBUlNFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxEX05PVF9JTklUX1BBUlNFUiA9ICJFUl9DT1VMRF9OT1RfSU5JVF9QQVJTRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FWENFUFRJT05fQ1JFQVRJTkdfUE9PTCA9ICJFUl9FWENFUFRJT05fQ1JFQVRJTkdfUE9PTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BBVEhfQ09OVEFJTlNfSU5WQUxJRF9FU0NBUEVfU0VRVUVOQ0UgPSAiRVJfUEFUSF9DT05UQUlOU19JTlZBTElEX0VTQ0FQRV9TRVFVRU5DRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NDSEVNRV9SRVFVSVJFRCA9ICJFUl9TQ0hFTUVfUkVRVUlSRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19TQ0hFTUVfSU5fVVJJID0gIkVSX05PX1NDSEVNRV9JTl9VUkkiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19TQ0hFTUVfSU5VUkkgPSAiRVJfTk9fU0NIRU1FX0lOVVJJIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUEFUSF9JTlZBTElEX0NIQVIgPSAiRVJfUEFUSF9JTlZBTElEX0NIQVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TQ0hFTUVfRlJPTV9OVUxMX1NUUklORyA9ICJFUl9TQ0hFTUVfRlJPTV9OVUxMX1NUUklORyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NDSEVNRV9OT1RfQ09ORk9STUFOVCA9ICJFUl9TQ0hFTUVfTk9UX0NPTkZPUk1BTlQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9IT1NUX0FERFJFU1NfTk9UX1dFTExGT1JNRUQgPSAiRVJfSE9TVF9BRERSRVNTX05PVF9XRUxMRk9STUVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUE9SVF9XSEVOX0hPU1RfTlVMTCA9ICJFUl9QT1JUX1dIRU5fSE9TVF9OVUxMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9QT1JUID0gIkVSX0lOVkFMSURfUE9SVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZSQUdfRk9SX0dFTkVSSUNfVVJJID0iRVJfRlJBR19GT1JfR0VORVJJQ19VUkkiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GUkFHX1dIRU5fUEFUSF9OVUxMID0gIkVSX0ZSQUdfV0hFTl9QQVRIX05VTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GUkFHX0lOVkFMSURfQ0hBUiA9ICJFUl9GUkFHX0lOVkFMSURfQ0hBUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BBUlNFUl9JTl9VU0UgPSAiRVJfUEFSU0VSX0lOX1VTRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9DSEFOR0VfV0hJTEVfUEFSU0lORyA9ICJFUl9DQU5OT1RfQ0hBTkdFX1dISUxFX1BBUlNJTkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TRUxGX0NBVVNBVElPTl9OT1RfUEVSTUlUVEVEID0gIkVSX1NFTEZfQ0FVU0FUSU9OX05PVF9QRVJNSVRURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19VU0VSSU5GT19JRl9OT19IT1NUID0gIkVSX05PX1VTRVJJTkZPX0lGX05PX0hPU1QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19QT1JUX0lGX05PX0hPU1QgPSAiRVJfTk9fUE9SVF9JRl9OT19IT1NUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fUVVFUllfU1RSSU5HX0lOX1BBVEggPSAiRVJfTk9fUVVFUllfU1RSSU5HX0lOX1BBVEgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19GUkFHTUVOVF9TVFJJTkdfSU5fUEFUSCA9ICJFUl9OT19GUkFHTUVOVF9TVFJJTkdfSU5fUEFUSCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9JTklUX1VSSV9FTVBUWV9QQVJNUyA9ICJFUl9DQU5OT1RfSU5JVF9VUklfRU1QVFlfUEFSTVMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9NRVRIT0RfTk9UX1NVUFBPUlRFRCA9IkVSX01FVEhPRF9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5DUlNBWFNSQ0ZJTFRFUl9OT1RfUkVTVEFSVEFCTEUgPSAiRVJfSU5DUlNBWFNSQ0ZJTFRFUl9OT1RfUkVTVEFSVEFCTEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YTUxSRFJfTk9UX0JFRk9SRV9TVEFSVFBBUlNFID0gIkVSX1hNTFJEUl9OT1RfQkVGT1JFX1NUQVJUUEFSU0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9BWElTX1RSQVZFUlNFUl9OT1RfU1VQUE9SVEVEID0gIkVSX0FYSVNfVFJBVkVSU0VSX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FUlJPUkhBTkRMRVJfQ1JFQVRFRF9XSVRIX05VTExfUFJJTlRXUklURVIgPSAiRVJfRVJST1JIQU5ETEVSX0NSRUFURURfV0lUSF9OVUxMX1BSSU5UV1JJVEVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU1lTVEVNSURfVU5LTk9XTiA9ICJFUl9TWVNURU1JRF9VTktOT1dOIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTE9DQVRJT05fVU5LTk9XTiA9ICJFUl9MT0NBVElPTl9VTktOT1dOIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJFRklYX01VU1RfUkVTT0xWRSA9ICJFUl9QUkVGSVhfTVVTVF9SRVNPTFZFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ1JFQVRFRE9DVU1FTlRfTk9UX1NVUFBPUlRFRCA9ICJFUl9DUkVBVEVET0NVTUVOVF9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0hJTERfSEFTX05PX09XTkVSX0RPQ1VNRU5UID0gIkVSX0NISUxEX0hBU19OT19PV05FUl9ET0NVTUVOVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NISUxEX0hBU19OT19PV05FUl9ET0NVTUVOVF9FTEVNRU5UID0gIkVSX0NISUxEX0hBU19OT19PV05FUl9ET0NVTUVOVF9FTEVNRU5UIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9PVVRQVVRfVEVYVF9CRUZPUkVfRE9DID0gIkVSX0NBTlRfT1VUUFVUX1RFWFRfQkVGT1JFX0RPQyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfSEFWRV9NT1JFX1RIQU5fT05FX1JPT1QgPSAiRVJfQ0FOVF9IQVZFX01PUkVfVEhBTl9PTkVfUk9PVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FSR19MT0NBTE5BTUVfTlVMTCA9ICJFUl9BUkdfTE9DQUxOQU1FX05VTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9BUkdfTE9DQUxOQU1FX0lOVkFMSUQgPSAiRVJfQVJHX0xPQ0FMTkFNRV9JTlZBTElEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQVJHX1BSRUZJWF9JTlZBTElEID0gIkVSX0FSR19QUkVGSVhfSU5WQUxJRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05BTUVfQ0FOVF9TVEFSVF9XSVRIX0NPTE9OID0gIkVSX05BTUVfQ0FOVF9TVEFSVF9XSVRIX0NPTE9OIjsKLQotICAvLyBNZXNzYWdlIGtleXMgdXNlZCBieSB0aGUgc2VyaWFsaXplcgotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SRVNPVVJDRV9DT1VMRF9OT1RfRklORCA9ICJFUl9SRVNPVVJDRV9DT1VMRF9OT1RfRklORCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1JFU09VUkNFX0NPVUxEX05PVF9MT0FEID0gIkVSX1JFU09VUkNFX0NPVUxEX05PVF9MT0FEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQlVGRkVSX1NJWkVfTEVTU1RIQU5fWkVSTyA9ICJFUl9CVUZGRVJfU0laRV9MRVNTVEhBTl9aRVJPIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9VVEYxNl9TVVJST0dBVEUgPSAiRVJfSU5WQUxJRF9VVEYxNl9TVVJST0dBVEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9PSUVSUk9SID0gIkVSX09JRVJST1IiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OQU1FU1BBQ0VfUFJFRklYID0gIkVSX05BTUVTUEFDRV9QUkVGSVgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TVFJBWV9BVFRSSUJVVEUgPSAiRVJfU1RSQVlfQVRUSVJCVVRFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU1RSQVlfTkFNRVNQQUNFID0gIkVSX1NUUkFZX05BTUVTUEFDRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxEX05PVF9MT0FEX1JFU09VUkNFID0gIkVSX0NPVUxEX05PVF9MT0FEX1JFU09VUkNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTERfTk9UX0xPQURfTUVUSE9EX1BST1BFUlRZID0gIkVSX0NPVUxEX05PVF9MT0FEX01FVEhPRF9QUk9QRVJUWSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NFUklBTElaRVJfTk9UX0NPTlRFTlRIQU5ETEVSID0gIkVSX1NFUklBTElaRVJfTk9UX0NPTlRFTlRIQU5ETEVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSUxMRUdBTF9BVFRSSUJVVEVfUE9TSVRJT04gPSAiRVJfSUxMRUdBTF9BVFRSSUJVVEVfUE9TSVRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTExFR0FMX0NIQVJBQ1RFUiA9ICJFUl9JTExFR0FMX0NIQVJBQ1RFUiI7Ci0KLSAgLyoKLSAgICogTm93IGZpbGwgaW4gdGhlIG1lc3NhZ2UgdGV4dC4KLSAgICogVGhlbiBmaWxsIGluIHRoZSBtZXNzYWdlIHRleHQgZm9yIHRoYXQgbWVzc2FnZSBjb2RlIGluIHRoZQotICAgKiBhcnJheS4gVXNlIHRoZSBuZXcgZXJyb3IgY29kZSBhcyB0aGUgaW5kZXggaW50byB0aGUgYXJyYXkuCi0gICAqLwotCi0gIC8vIEVycm9yIG1lc3NhZ2VzLi4uCi0KLSAgLyoqIFRoZSBsb29rdXAgdGFibGUgZm9yIGVycm9yIG1lc3NhZ2VzLiAgICovCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIE9iamVjdFtdW10gY29udGVudHMgPSB7Ci0KLSAgLyoqIEVycm9yIG1lc3NhZ2UgSUQgdGhhdCBoYXMgYSBudWxsIG1lc3NhZ2UsIGJ1dCB0YWtlcyBpbiBhIHNpbmdsZSBvYmplY3QuICAgICovCi0gICAgeyJFUjAwMDAiICwgInswfSIgfSwKLQotICAgIHsgRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCwKLSAgICAgICJGdW5rdGlvbiBuaWNodCB1bnRlcnN0XHUwMEZDdHp0LiJ9LAotCi0gICAgeyBFUl9DQU5OT1RfT1ZFUldSSVRFX0NBVVNFLAotICAgICAgIlVyc2FjaGUga2FubiBuaWNodCBcdTAwRkNiZXJzY2hyaWViZW4gd2VyZGVuIn0sCi0KLSAgICB7IEVSX05PX0RFRkFVTFRfSU1QTCwKLSAgICAgICJLZWluZSBTdGFuZGFyZGltcGxlbWVudGllcnVuZyBnZWZ1bmRlbiAifSwKLQotICAgIHsgRVJfQ0hVTktFRElOVEFSUkFZX05PVF9TVVBQT1JURUQsCi0gICAgICAiQ2h1bmtlZEludEFycmF5KHswfSkgZGVyemVpdCBuaWNodCB1bnRlcnN0XHUwMEZDdHp0In0sCi0KLSAgICB7IEVSX09GRlNFVF9CSUdHRVJfVEhBTl9TTE9ULAotICAgICAgIk9mZnNldCBnclx1MDBGNlx1MDBERmVyIGFscyBTbG90In0sCi0KLSAgICB7IEVSX0NPUk9VVElORV9OT1RfQVZBSUwsCi0gICAgICAiQ29yb3V0aW5lIG5pY2h0IHZlcmZcdTAwRkNnYmFyOyBJRD17MH0ifSwKLQotICAgIHsgRVJfQ09ST1VUSU5FX0NPX0VYSVQsCi0gICAgICAiQ29yb3V0aW5lTWFuYWdlciBoYXQgY29fZXhpdCgpLUFuZm9yZGVydW5nIGVyaGFsdGVuIn0sCi0KLSAgICB7IEVSX0NPSk9JTlJPVVRJTkVTRVRfRkFJTEVELAotICAgICAgImNvX2pvaW5Db3JvdXRpbmVTZXQoKSBuaWNodCBlcmZvbGdyZWljaCJ9LAotCi0gICAgeyBFUl9DT1JPVVRJTkVfUEFSQU0sCi0gICAgICAiQ29yb3V0aW5lLVBhcmFtZXRlcmZlaGxlciAoezB9KSJ9LAotCi0gICAgeyBFUl9QQVJTRVJfRE9URVJNSU5BVEVfQU5TV0VSUywKLSAgICAgICJcblVORVhQRUNURUQ6IFBhcnNlciBkb1Rlcm1pbmF0ZSBhbnR3b3J0ZXQgezB9In0sCi0KLSAgICB7IEVSX05PX1BBUlNFX0NBTExfV0hJTEVfUEFSU0lORywKLSAgICAgICJcInBhcnNlXCIgZGFyZiB3XHUwMEU0aHJlbmQgZGVzIFBhcnNpbmcgbmljaHQgYXVmZ2VydWZlbiB3ZXJkZW4ifSwKLQotICAgIHsgRVJfVFlQRURfSVRFUkFUT1JfQVhJU19OT1RfSU1QTEVNRU5URUQsCi0gICAgICAiRmVobGVyOiBUeXBpc2llcnRlciBJdGVyYXRvciBmXHUwMEZDciBBY2hzZSB7MH0gbmljaHQgaW1wbGVtZW50aWVydCJ9LAotCi0gICAgeyBFUl9JVEVSQVRPUl9BWElTX05PVF9JTVBMRU1FTlRFRCwKLSAgICAgICJGZWhsZXI6IEl0ZXJhdG9yIGZcdTAwRkNyIEFjaHNlIHswfSBuaWNodCBpbXBsZW1lbnRpZXJ0ICJ9LAotCi0gICAgeyBFUl9JVEVSQVRPUl9DTE9ORV9OT1RfU1VQUE9SVEVELAotICAgICAgIkl0ZXJhdG9yY2xvbmUgbmljaHQgdW50ZXJzdFx1MDBGQ3R6dCJ9LAotCi0gICAgeyBFUl9VTktOT1dOX0FYSVNfVFlQRSwKLSAgICAgICJVbmJla2FubnRlciBBY2hzZW5kdXJjaGxhdWZ0eXA6IHswfSJ9LAotCi0gICAgeyBFUl9BWElTX05PVF9TVVBQT1JURUQsCi0gICAgICAiQWNoc2VuLVRyYXZlcnNlciBuaWNodCB1bnRlcnN0XHUwMEZDdHp0OiB7MH0ifSwKLQotICAgIHsgRVJfTk9fRFRNSURTX0FWQUlMLAotICAgICAgIktlaW5lIHdlaXRlcmVuIERUTS1JRHMgdmVyZlx1MDBGQ2diYXIifSwKLQotICAgIHsgRVJfTk9UX1NVUFBPUlRFRCwKLSAgICAgICJOaWNodCB1bnRlcnN0XHUwMEZDdHp0OiB7MH0ifSwKLQotICAgIHsgRVJfTk9ERV9OT05fTlVMTCwKLSAgICAgICJLbm90ZW4gZGFyZiBuaWNodCBudWxsIHNlaW4gZlx1MDBGQ3IgZ2V0RFRNSGFuZGxlRnJvbU5vZGUifSwKLQotICAgIHsgRVJfQ09VTERfTk9UX1JFU09MVkVfTk9ERSwKLSAgICAgICJLbm90ZW4ga29ubnRlIG5pY2h0IGluIEhhbmRsZSBhdWZnZWxcdTAwRjZzdCB3ZXJkZW4ifSwKLQotICAgIHsgRVJfU1RBUlRQQVJTRV9XSElMRV9QQVJTSU5HLAotICAgICAgICJcInN0YXJ0UGFyc2VcIiBkYXJmIHdcdTAwRTRocmVuZCBkZXMgUGFyc2luZyBuaWNodCBhdWZnZXJ1ZmVuIHdlcmRlbiJ9LAotCi0gICAgeyBFUl9TVEFSVFBBUlNFX05FRURTX1NBWFBBUlNFUiwKLSAgICAgICAic3RhcnRQYXJzZSBlcmZvcmRlcnQgZWluZW4gU0FYUGFyc2VyIHVuZ2xlaWNoIG51bGwifSwKLQotICAgIHsgRVJfQ09VTERfTk9UX0lOSVRfUEFSU0VSLAotICAgICAgICJQYXJzZXIga29ubnRlIG5pY2h0IGluaXRpYWxpc2llcnQgd2VyZGVuIG1pdCJ9LAotCi0gICAgeyBFUl9FWENFUFRJT05fQ1JFQVRJTkdfUE9PTCwKLSAgICAgICAiQXVzbmFobWUgYmVpbSBFcnN0ZWxsZW4gZWluZXIgbmV1ZW4gSW5zdGFueiBmXHUwMEZDciBQb29sIn0sCi0KLSAgICB7IEVSX1BBVEhfQ09OVEFJTlNfSU5WQUxJRF9FU0NBUEVfU0VRVUVOQ0UsCi0gICAgICAgIlBmYWQgZW50aFx1MDBFNGx0IGVpbmUgdW5nXHUwMEZDbHRpZ2UgRXNjYXBlc2VxdWVueiJ9LAotCi0gICAgeyBFUl9TQ0hFTUVfUkVRVUlSRUQsCi0gICAgICAgIlNjaGVtYSBpc3QgZXJmb3JkZXJsaWNoLiJ9LAotCi0gICAgeyBFUl9OT19TQ0hFTUVfSU5fVVJJLAotICAgICAgICJLZWluIFNjaGVtYSBnZWZ1bmRlbiBpbiBVUkk6IHswfSJ9LAotCi0gICAgeyBFUl9OT19TQ0hFTUVfSU5VUkksCi0gICAgICAgIktlaW4gU2NoZW1hIGdlZnVuZGVuIGluIFVSSSJ9LAotCi0gICAgeyBFUl9QQVRIX0lOVkFMSURfQ0hBUiwKLSAgICAgICAiUGZhZCBlbnRoXHUwMEU0bHQgdW5nXHUwMEZDbHRpZ2VzIFplaWNoZW46IHswfSJ9LAotCi0gICAgeyBFUl9TQ0hFTUVfRlJPTV9OVUxMX1NUUklORywKLSAgICAgICAiU2NoZW1hIGthbm4gbmljaHQgdm9uIE51bGx6ZWljaGVuZm9sZ2UgZmVzdGdlbGVndCB3ZXJkZW4ifSwKLQotICAgIHsgRVJfU0NIRU1FX05PVF9DT05GT1JNQU5ULAotICAgICAgICJTY2hlbWEgaXN0IG5pY2h0IGtvbmZvcm0uIn0sCi0KLSAgICB7IEVSX0hPU1RfQUREUkVTU19OT1RfV0VMTEZPUk1FRCwKLSAgICAgICAiSG9zdCBpc3Qga2VpbmUgd29obGdlZm9ybXRlIEFkcmVzc2UifSwKLQotICAgIHsgRVJfUE9SVF9XSEVOX0hPU1RfTlVMTCwKLSAgICAgICAiUG9ydCBrYW5uIG5pY2h0IGZlc3RnZWxlZ3Qgd2VyZGVuLCB3ZW5uIGRlciBIb3N0IG51bGwgaXN0In0sCi0KLSAgICB7IEVSX0lOVkFMSURfUE9SVCwKLSAgICAgICAiVW5nXHUwMEZDbHRpZ2UgUG9ydG51bW1lciJ9LAotCi0gICAgeyBFUl9GUkFHX0ZPUl9HRU5FUklDX1VSSSwKLSAgICAgICAiRnJhZ21lbnQga2FubiBudXIgZlx1MDBGQ3IgZWluZW4gZ2VuZXJpc2NoZW4gVVJJIGZlc3RnZWxlZ3Qgd2VyZGVuIn0sCi0KLSAgICB7IEVSX0ZSQUdfV0hFTl9QQVRIX05VTEwsCi0gICAgICAgIkZyYWdtZW50IGthbm4gbmljaHQgZmVzdGdlbGVndCB3ZXJkZW4sIHdlbm4gZGVyIFBmYWQgbnVsbCBpc3QifSwKLQotICAgIHsgRVJfRlJBR19JTlZBTElEX0NIQVIsCi0gICAgICAgIkZyYWdtZW50IGVudGhcdTAwRTRsdCBlaW4gdW5nXHUwMEZDbHRpZ2VzIFplaWNoZW4ifSwKLQotICAgIHsgRVJfUEFSU0VSX0lOX1VTRSwKLSAgICAgICJQYXJzZXIgd2lyZCBiZXJlaXRzIHZlcndlbmRldCJ9LAotCi0gICAgeyBFUl9DQU5OT1RfQ0hBTkdFX1dISUxFX1BBUlNJTkcsCi0gICAgICAiezB9IHsxfSBrYW5uIHdcdTAwRTRocmVuZCBQYXJzaW5nIG5pY2h0IGdlXHUwMEU0bmRlcnQgd2VyZGVuIn0sCi0KLSAgICB7IEVSX1NFTEZfQ0FVU0FUSU9OX05PVF9QRVJNSVRURUQsCi0gICAgICAiU2VsYnN0a2F1c2FsaXRcdTAwRTR0IG5pY2h0IHp1bFx1MDBFNHNzaWcifSwKLQotICAgIHsgRVJfTk9fVVNFUklORk9fSUZfTk9fSE9TVCwKLSAgICAgICJCZW51dHplcmluZm9ybWF0aW9uZW4ga1x1MDBGNm5uZW4gbmljaHQgYW5nZWdlYmVuIHdlcmRlbiwgd2VubiBkZXIgSG9zdCBuaWNodCBhbmdlZ2ViZW4gd3VyZGUifSwKLQotICAgIHsgRVJfTk9fUE9SVF9JRl9OT19IT1NULAotICAgICAgIlBvcnQga2FubiBuaWNodCBhbmdlZ2ViZW4gd2VyZGVuLCB3ZW5uIGRlciBIb3N0IG5pY2h0IGFuZ2VnZWJlbiB3dXJkZSJ9LAotCi0gICAgeyBFUl9OT19RVUVSWV9TVFJJTkdfSU5fUEFUSCwKLSAgICAgICJBYmZyYWdlemVpY2hlbmZvbGdlIGthbm4gbmljaHQgaW0gUGZhZCB1bmQgaW4gZGVyIEFiZnJhZ2V6ZWljaGVuZm9sZ2UgYW5nZWdlYmVuIHdlcmRlbiJ9LAotCi0gICAgeyBFUl9OT19GUkFHTUVOVF9TVFJJTkdfSU5fUEFUSCwKLSAgICAgICJGcmFnbWVudCBrYW5uIG5pY2h0IGltIFBmYWQgdW5kIGltIEZyYWdtZW50IGFuZ2VnZWJlbiB3ZXJkZW4ifSwKLQotICAgIHsgRVJfQ0FOTk9UX0lOSVRfVVJJX0VNUFRZX1BBUk1TLAotICAgICAgIlVSSSBrYW5uIG5pY2h0IG1pdCBsZWVyZW4gUGFyYW1ldGVybiBpbml0aWFsaXNpZXJ0IHdlcmRlbiJ9LAotCi0gICAgeyBFUl9NRVRIT0RfTk9UX1NVUFBPUlRFRCwKLSAgICAgICJNZXRob2RlIG5vY2ggbmljaHQgdW50ZXJzdFx1MDBGQ3R6dCAifSwKLQotICAgIHsgRVJfSU5DUlNBWFNSQ0ZJTFRFUl9OT1RfUkVTVEFSVEFCTEUsCi0gICAgICAiSW5jcmVtZW50YWxTQVhTb3VyY2VfRmlsdGVyIGthbm4gZGVyemVpdCBuaWNodCBuZXUgZ2VzdGFydGV0IHdlcmRlbiJ9LAotCi0gICAgeyBFUl9YTUxSRFJfTk9UX0JFRk9SRV9TVEFSVFBBUlNFLAotICAgICAgIlhNTFJlYWRlciBuaWNodCB2b3Igc3RhcnRQYXJzZS1BbmZvcmRlcnVuZyJ9LAotCi0gICAgeyBFUl9BWElTX1RSQVZFUlNFUl9OT1RfU1VQUE9SVEVELAotICAgICAgIkFjaHNlbi1UcmF2ZXJzZXIgbmljaHQgdW50ZXJzdFx1MDBGQ3R6dDogezB9In0sCi0KLSAgICB7IEVSX0VSUk9SSEFORExFUl9DUkVBVEVEX1dJVEhfTlVMTF9QUklOVFdSSVRFUiwKLSAgICAgICJMaXN0aW5nRXJyb3JIYW5kbGVyIG1pdCBOdWxsLVByaW50V3JpdGVyIGVyc3RlbGx0LiJ9LAotCi0gICAgeyBFUl9TWVNURU1JRF9VTktOT1dOLAotICAgICAgIlN5c3RlbUlkIHVuYmVrYW5udCJ9LAotCi0gICAgeyBFUl9MT0NBVElPTl9VTktOT1dOLAotICAgICAgIkZlaGxlcnBvc2l0aW9uIHVuYmVrYW5udCJ9LAotCi0gICAgeyBFUl9QUkVGSVhfTVVTVF9SRVNPTFZFLAotICAgICAgIlByXHUwMEU0Zml4IG11c3MgaW4gTmFtZXNwYWNlIGF1ZmdlbFx1MDBGNnN0IHdlcmRlbjogezB9In0sCi0KLSAgICB7IEVSX0NSRUFURURPQ1VNRU5UX05PVF9TVVBQT1JURUQsCi0gICAgICAiY3JlYXRlRG9jdW1lbnQoKSBuaWNodCBpbiBYUGF0aENvbnRleHQgdW50ZXJzdFx1MDBGQ3R6dC4ifSwKLQotICAgIHsgRVJfQ0hJTERfSEFTX05PX09XTkVSX0RPQ1VNRU5ULAotICAgICAgIlVudGVyZ2VvcmRuZXRlcyBBdHRyaWJ1dCBoYXQga2VpbiBFaWdlbnRcdTAwRkNtZXJkb2t1bWVudC4ifSwKLQotICAgIHsgRVJfQ0hJTERfSEFTX05PX09XTkVSX0RPQ1VNRU5UX0VMRU1FTlQsCi0gICAgICAiVW50ZXJnZW9yZG5ldGVzIEF0dHJpYnV0IGhhdCBrZWluIEVpZ2VudFx1MDBGQ21lcmRva3VtZW50ZWxlbWVudC4ifSwKLQotICAgIHsgRVJfQ0FOVF9PVVRQVVRfVEVYVF9CRUZPUkVfRE9DLAotICAgICAgIldhcm51bmc6IFRleHQga2FubiBuaWNodCB2b3IgRG9rdW1lbnRlbGVtZW50IGF1c2dlZ2ViZW4gd2VyZGVuLiBXaXJkIGlnbm9yaWVydC4uLiJ9LAotCi0gICAgeyBFUl9DQU5UX0hBVkVfTU9SRV9USEFOX09ORV9ST09ULAotICAgICAgIk1laHJlcmUgUm9vdHMgZlx1MDBGQ3IgZWluIERPTSBuaWNodCB6dWxcdTAwRTRzc2lnLiJ9LAotCi0gICAgeyBFUl9BUkdfTE9DQUxOQU1FX05VTEwsCi0gICAgICAgIkFyZ3VtZW50IFwibG9jYWxOYW1lXCIgaXN0IG51bGwifSwKLQotICAgIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBIFFOQU1FIGhhcyB0aGUgc3ludGFjdGljIGZvcm0gW05DTmFtZTpdTkNOYW1lCi0gICAgLy8gVGhlIGxvY2FsbmFtZSBpcyB0aGUgcG9ydGlvbiBhZnRlciB0aGUgb3B0aW9uYWwgY29sb247IHRoZSBtZXNzYWdlIGluZGljYXRlcwotICAgIC8vIHRoYXQgdGhlcmUgaXMgYSBwcm9ibGVtIHdpdGggdGhhdCBwYXJ0IG9mIHRoZSBRTkFNRS4KLSAgICB7IEVSX0FSR19MT0NBTE5BTUVfSU5WQUxJRCwKLSAgICAgICAiTG9jYWxuYW1lIGluIFFOQU1FIG11c3MgZWluIGdcdTAwRkNsdGlnZXIgTkNOYW1lIHNlaW4ifSwKLQotICAgIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBIFFOQU1FIGhhcyB0aGUgc3ludGFjdGljIGZvcm0gW05DTmFtZTpdTkNOYW1lCi0gICAgLy8gVGhlIHByZWZpeCBpcyB0aGUgcG9ydGlvbiBiZWZvcmUgdGhlIG9wdGlvbmFsIGNvbG9uOyB0aGUgbWVzc2FnZSBpbmRpY2F0ZXMKLSAgICAvLyB0aGF0IHRoZXJlIGlzIGEgcHJvYmxlbSB3aXRoIHRoYXQgcGFydCBvZiB0aGUgUU5BTUUuCi0gICAgeyBFUl9BUkdfUFJFRklYX0lOVkFMSUQsCi0gICAgICAgIlByXHUwMEU0Zml4IGluIFFOQU1FIG11c3MgZWluIGdcdTAwRkNsdGlnZXIgTkNOYW1lIHNlaW4ifSwKLQotICAgIHsgRVJfTkFNRV9DQU5UX1NUQVJUX1dJVEhfQ09MT04sCi0gICAgICAiTmFtZSBkYXJmIG5pY2h0IG1pdCBlaW5lbSBEb3BwZWxwdW5rdCBiZWdpbm5lbiJ9LAotCi0gICAgeyAiQkFEX0NPREUiLCAiUGFyYW1ldGVyIGZcdTAwRkNyIGNyZWF0ZU1lc3NhZ2Ugd2FyIGF1XHUwMERGZXJoYWxiIGRlcyBnXHUwMEZDbHRpZ2VuIEJlcmVpY2hzIn0sCi0gICAgeyAiRk9STUFUX0ZBSUxFRCIsICJBdXNuYWhtZSBiZWkgbWVzc2FnZUZvcm1hdC1BdWZydWYgYXVzZ2VsXHUwMEY2c3QifSwKLSAgICB7ICJsaW5lIiwgIlplaWxlbm51bW1lciJ9LAotICAgIHsgImNvbHVtbiIsIlNwYWx0ZW5udW1tZXIifSwKLQotICAgIHtFUl9TRVJJQUxJWkVSX05PVF9DT05URU5USEFORExFUiwKLSAgICAgICJTZXJpYWxpemVyLUtsYXNzZSBcInswfVwiIGltcGxlbWVudGllcnQgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIgbmljaHQuIn0sCi0KLSAgICB7RVJfUkVTT1VSQ0VfQ09VTERfTk9UX0ZJTkQsCi0gICAgICAiUmVzc291cmNlIFsgezB9IF0ga29ubnRlIG5pY2h0IGdlZnVuZGVuIHdlcmRlbi5cbiB7MX0iIH0sCi0KLSAgICB7RVJfUkVTT1VSQ0VfQ09VTERfTk9UX0xPQUQsCi0gICAgICAiUmVzc291cmNlIFsgezB9IF0ga29ubnRlIG5pY2h0IGdlbGFkZW4gd2VyZGVuOiB7MX0gXG4gezJ9IFx0IHszfSIgfSwKLQotICAgIHtFUl9CVUZGRVJfU0laRV9MRVNTVEhBTl9aRVJPLAotICAgICAgIlB1ZmZlcmdyXHUwMEY2XHUwMERGZSA8PTAiIH0sCi0KLSAgICB7RVJfSU5WQUxJRF9VVEYxNl9TVVJST0dBVEUsCi0gICAgICAiVW5nXHUwMEZDbHRpZ2UgVVRGLTE2LUVyc2V0enVuZyBmZXN0Z2VzdGVsbHQ6IHswfT8iIH0sCi0KLSAgICB7RVJfT0lFUlJPUiwKLSAgICAgICJJL08tRmVobGVyIiB9LAotCi0gICAge0VSX0lMTEVHQUxfQVRUUklCVVRFX1BPU0lUSU9OLAotICAgICAgIkF0dHJpYnV0IHswfSBrYW5uIG5pY2h0IG5hY2ggdW50ZXJnZW9yZG5ldGVuIEtub3RlbiBvZGVyIHZvciBkZW0gRXJzdGVsbGVuIGVpbmVzIEVsZW1lbnRzIGhpbnp1Z2VmXHUwMEZDZ3Qgd2VyZGVuLiBBdHRyaWJ1dCB3aXJkIGlnbm9yaWVydC4ifSwKLQotICAgICAgLyoKLSAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3R5bGVzaGVldCBjb250YWluZWQgYSByZWZlcmVuY2UgdG8gYQotICAgICAgICogbmFtZXNwYWNlIHByZWZpeCB0aGF0IHdhcyB1bmRlZmluZWQuICBUaGUgdmFsdWUgb2YgdGhlIHN1YnN0aXR1dGlvbgotICAgICAgICogdGV4dCBpcyB0aGUgbmFtZSBvZiB0aGUgcHJlZml4LgotICAgICAgICovCi0gICAge0VSX05BTUVTUEFDRV9QUkVGSVgsCi0gICAgICAiTmFtZXNwYWNlIGZcdTAwRkNyIFByXHUwMEU0Zml4IFwiezB9XCIgd3VyZGUgbmljaHQgZGVrbGFyaWVydC4iIH0sCi0gICAgICAvKgotICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyByZXBvcnRlZCBpZiB0aGUgc3R5bGVzaGVldAotICAgICAgICogYmVpbmcgcHJvY2Vzc2VkIGF0dGVtcHRlZCB0byBjb25zdHJ1Y3QgYW4gWE1MIGRvY3VtZW50IHdpdGggYW4KLSAgICAgICAqIGF0dHJpYnV0ZSBpbiBhIHBsYWNlIG90aGVyIHRoYW4gb24gYW4gZWxlbWVudC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICogc3BlY2lmaWVzIHRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUuCi0gICAgICAgKi8KLSAgICB7RVJfU1RSQVlfQVRUUklCVVRFLAotICAgICAgIkF0dHJpYnV0IFwiezB9XCIgYXVcdTAwREZlcmhhbGIgZGVzIEVsZW1lbnRzLiIgfSwKLQotICAgICAgLyoKLSAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBcyB3aXRoIHRoZSBwcmVjZWRpbmcgbWVzc2FnZSwgYSBuYW1lc3BhY2UKLSAgICAgICAqIGRlY2xhcmF0aW9uIGhhcyB0aGUgZm9ybSBvZiBhbiBhdHRyaWJ1dGUgYW5kIGlzIG9ubHkgcGVybWl0dGVkIHRvCi0gICAgICAgKiBhcHBlYXIgb24gYW4gZWxlbWVudC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCB7MH0gaXMgdGhlIG5hbWVzcGFjZQotICAgICAgICogcHJlZml4IGFuZCB7MX0gaXMgdGhlIFVSSSB0aGF0IHdhcyBiZWluZyB1c2VkIGluIHRoZSBlcnJvbmVvdXMKLSAgICAgICAqIG5hbWVzcGFjZSBkZWNsYXJhdGlvbi4KLSAgICAgICAqLwotICAgIHtFUl9TVFJBWV9OQU1FU1BBQ0UsCi0gICAgICAiTmFtZXNwYWNlLURla2xhcmF0aW9uIHswfT17MX0gYXVcdTAwREZlcmhhbGIgZGVzIEVsZW1lbnRzLiIgfSwKLQotICAgIHtFUl9DT1VMRF9OT1RfTE9BRF9SRVNPVVJDRSwKLSAgICAgICJcInswfVwiIGtvbm50ZSBuaWNodCBnZWxhZGVuIHdlcmRlbiAoQ0xBU1NQQVRIIHByXHUwMEZDZmVuKS4gRGllIFN0YW5kYXJkd2VydGUgd2VyZGVuIHZlcndlbmRldCJ9LAotCi0gICAgeyBFUl9JTExFR0FMX0NIQVJBQ1RFUiwKLSAgICAgICAiVmVyc3VjaCwgWmVpY2hlbiBtaXQgSW50ZWdyYWx3ZXJ0IHswfSBhdXN6dWdlYmVuLCBkYXMgbmljaHQgaW4gZGVyIHNwZXppZWxsZW4gQXVzZ2FiZWNvZGllcnVuZyB2b24gezF9IGRhcmdlc3RlbGx0IHdpcmQuIn0sCi0KLSAgICB7RVJfQ09VTERfTk9UX0xPQURfTUVUSE9EX1BST1BFUlRZLAotICAgICAgIlByb3BlcnR5LURhdGVpIFwiezB9XCIga29ubnRlIGZcdTAwRkNyIEF1c2dhYmVtZXRob2RlIFwiezF9XCIgbmljaHQgZ2VsYWRlbiB3ZXJkZW4gKENMQVNTUEFUSCBwclx1MDBGQ2ZlbikiIH0KLQotCi0gIH07Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgYXNzb2NpYXRpb24gbGlzdC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgYXNzb2NpYXRpb24gbGlzdC4KLSAgICovCi0KLSAgICBwcm90ZWN0ZWQgT2JqZWN0W11bXSBnZXRDb250ZW50cygpIHsKLSAgICAgICAgcmV0dXJuIGNvbnRlbnRzOwotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvcmVzL1hNTEVycm9yUmVzb3VyY2VzX2VuLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9yZXMvWE1MRXJyb3JSZXNvdXJjZXNfZW4uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNzhjOWIxMy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9yZXMvWE1MRXJyb3JSZXNvdXJjZXNfZW4uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDMzICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFhNTEVycm9yUmVzb3VyY2VzX2VuLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTUgMDc6NDU6NDAgc3VyZXNoX2VtYWlsaWQgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnJlczsKLQotCi0vKioKLSAqIERlZmF1bHQgaW1wbGVtZW50YXRpb24gb2YgWFBBVEhFcnJvclJlc291cmNlcy4gIFRoaXMgaXMganVzdAotICogYW4gZW1wdHkgY2xhc3MuCi0gKiBAeHNsLnVzYWdlIGFkdmFuY2VkCi0gKi8KLXB1YmxpYyBjbGFzcyBYTUxFcnJvclJlc291cmNlc19lbiBleHRlbmRzIFhNTEVycm9yUmVzb3VyY2VzCi17Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9yZXMvWE1MRXJyb3JSZXNvdXJjZXNfZXMuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3Jlcy9YTUxFcnJvclJlc291cmNlc19lcy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0NzE0NzMyLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3Jlcy9YTUxFcnJvclJlc291cmNlc19lcy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDUwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXM7Ci0KLQotaW1wb3J0IGphdmEudXRpbC5MaXN0UmVzb3VyY2VCdW5kbGU7Ci0KLS8qKgotICogU2V0IHVwIGVycm9yIG1lc3NhZ2VzLgotICogV2UgYnVpbGQgYSB0d28gZGltZW5zaW9uYWwgYXJyYXkgb2YgbWVzc2FnZSBrZXlzIGFuZAotICogbWVzc2FnZSBzdHJpbmdzLiBJbiBvcmRlciB0byBhZGQgYSBuZXcgbWVzc2FnZSBoZXJlLAotICogeW91IG5lZWQgdG8gZmlyc3QgYWRkIGEgU3RyaW5nIGNvbnN0YW50LiBBbmQgeW91IG5lZWQKLSAqIHRvIGVudGVyIGtleSwgdmFsdWUgcGFpciBhcyBwYXJ0IG9mIHRoZSBjb250ZW50cwotICogYXJyYXkuIFlvdSBhbHNvIG5lZWQgdG8gdXBkYXRlIE1BWF9DT0RFIGZvciBlcnJvciBzdHJpbmdzCi0gKiBhbmQgTUFYX1dBUk5JTkcgZm9yIHdhcm5pbmdzICggTmVlZGVkIGZvciBvbmx5IGluZm9ybWF0aW9uCi0gKiBwdXJwb3NlICkKLSAqLwotcHVibGljIGNsYXNzIFhNTEVycm9yUmVzb3VyY2VzX2VzIGV4dGVuZHMgTGlzdFJlc291cmNlQnVuZGxlCi17Ci0KLS8qCi0gKiBUaGlzIGZpbGUgY29udGFpbnMgZXJyb3IgYW5kIHdhcm5pbmcgbWVzc2FnZXMgcmVsYXRlZCB0byBYYWxhbiBFcnJvcgotICogSGFuZGxpbmcuCi0gKgotICogIEdlbmVyYWwgbm90ZXMgdG8gdHJhbnNsYXRvcnM6Ci0gKgotICogIDEpIFhhbGFuIChvciBtb3JlIHByb3Blcmx5LCBYYWxhbi1pbnRlcnByZXRpdmUpIGFuZCBYU0xUQyBhcmUgbmFtZXMgb2YKLSAqICAgICBjb21wb25lbnRzLgotICogICAgIFhTTFQgaXMgYW4gYWNyb255bSBmb3IgIlhNTCBTdHlsZXNoZWV0IExhbmd1YWdlOiBUcmFuc2Zvcm1hdGlvbnMiLgotICogICAgIFhTTFRDIGlzIGFuIGFjcm9ueW0gZm9yIFhTTFQgQ29tcGlsZXIuCi0gKgotICogIDIpIEEgc3R5bGVzaGVldCBpcyBhIGRlc2NyaXB0aW9uIG9mIGhvdyB0byB0cmFuc2Zvcm0gYW4gaW5wdXQgWE1MIGRvY3VtZW50Ci0gKiAgICAgaW50byBhIHJlc3VsdGFudCBYTUwgZG9jdW1lbnQgKG9yIEhUTUwgZG9jdW1lbnQgb3IgdGV4dCkuICBUaGUKLSAqICAgICBzdHlsZXNoZWV0IGl0c2VsZiBpcyBkZXNjcmliZWQgaW4gdGhlIGZvcm0gb2YgYW4gWE1MIGRvY3VtZW50LgotICoKLSAqICAzKSBBIHRlbXBsYXRlIGlzIGEgY29tcG9uZW50IG9mIGEgc3R5bGVzaGVldCB0aGF0IGlzIHVzZWQgdG8gbWF0Y2ggYQotICogICAgIHBhcnRpY3VsYXIgcG9ydGlvbiBvZiBhbiBpbnB1dCBkb2N1bWVudCBhbmQgc3BlY2lmaWVzIHRoZSBmb3JtIG9mIHRoZQotICogICAgIGNvcnJlc3BvbmRpbmcgcG9ydGlvbiBvZiB0aGUgb3V0cHV0IGRvY3VtZW50LgotICoKLSAqICA0KSBBbiBlbGVtZW50IGlzIGEgbWFyay11cCB0YWcgaW4gYW4gWE1MIGRvY3VtZW50OyBhbiBhdHRyaWJ1dGUgaXMgYQotICogICAgIG1vZGlmaWVyIG9uIHRoZSB0YWcuICBGb3IgZXhhbXBsZSwgaW4gPGVsZW0gYXR0cj0ndmFsJyBhdHRyMj0ndmFsMic+Ci0gKiAgICAgImVsZW0iIGlzIGFuIGVsZW1lbnQgbmFtZSwgImF0dHIiIGFuZCAiYXR0cjIiIGFyZSBhdHRyaWJ1dGUgbmFtZXMgd2l0aAotICogICAgIHRoZSB2YWx1ZXMgInZhbCIgYW5kICJ2YWwyIiwgcmVzcGVjdGl2ZWx5LgotICoKLSAqICA1KSBBIG5hbWVzcGFjZSBkZWNsYXJhdGlvbiBpcyBhIHNwZWNpYWwgYXR0cmlidXRlIHRoYXQgaXMgdXNlZCB0byBhc3NvY2lhdGUKLSAqICAgICBhIHByZWZpeCB3aXRoIGEgVVJJICh0aGUgbmFtZXNwYWNlKS4gIFRoZSBtZWFuaW5ncyBvZiBlbGVtZW50IG5hbWVzIGFuZAotICogICAgIGF0dHJpYnV0ZSBuYW1lcyB0aGF0IHVzZSB0aGF0IHByZWZpeCBhcmUgZGVmaW5lZCB3aXRoIHJlc3BlY3QgdG8gdGhhdAotICogICAgIG5hbWVzcGFjZS4KLSAqCi0gKiAgNikgIlRyYW5zbGV0IiBpcyBhbiBpbnZlbnRlZCB0ZXJtIHRoYXQgZGVzY3JpYmVzIHRoZSBjbGFzcyBmaWxlIHRoYXQKLSAqICAgICByZXN1bHRzIGZyb20gY29tcGlsaW5nIGFuIFhNTCBzdHlsZXNoZWV0IGludG8gYSBKYXZhIGNsYXNzLgotICoKLSAqICA3KSBYUGF0aCBpcyBhIHNwZWNpZmljYXRpb24gdGhhdCBkZXNjcmliZXMgYSBub3RhdGlvbiBmb3IgaWRlbnRpZnlpbmcKLSAqICAgICBub2RlcyBpbiBhIHRyZWUtc3RydWN0dXJlZCByZXByZXNlbnRhdGlvbiBvZiBhbiBYTUwgZG9jdW1lbnQuICBBbgotICogICAgIGluc3RhbmNlIG9mIHRoYXQgbm90YXRpb24gaXMgcmVmZXJyZWQgdG8gYXMgYW4gWFBhdGggZXhwcmVzc2lvbi4KLSAqCi0gKi8KLQotICAvKiogTWF4aW11bSBlcnJvciBtZXNzYWdlcywgdGhpcyBpcyBuZWVkZWQgdG8ga2VlcCB0cmFjayBvZiB0aGUgbnVtYmVyIG9mIG1lc3NhZ2VzLiAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVhfQ09ERSA9IDYxOwotCi0gIC8qKiBNYXhpbXVtIHdhcm5pbmdzLCB0aGlzIGlzIG5lZWRlZCB0byBrZWVwIHRyYWNrIG9mIHRoZSBudW1iZXIgb2Ygd2FybmluZ3MuICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BWF9XQVJOSU5HID0gMDsKLQotICAvKiogTWF4aW11bSBtaXNjIHN0cmluZ3MuICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFYX09USEVSUyA9IDQ7Ci0KLSAgLyoqIE1heGltdW0gdG90YWwgd2FybmluZ3MgYW5kIGVycm9yIG1lc3NhZ2VzLiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVhfTUVTU0FHRVMgPSBNQVhfQ09ERSArIE1BWF9XQVJOSU5HICsgMTsKLQotCi0gIC8qCi0gICAqIE1lc3NhZ2Uga2V5cwotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCA9ICJFUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX09WRVJXUklURV9DQVVTRSA9ICJFUl9DQU5OT1RfT1ZFUldSSVRFX0NBVVNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fREVGQVVMVF9JTVBMID0gIkVSX05PX0RFRkFVTFRfSU1QTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NIVU5LRURJTlRBUlJBWV9OT1RfU1VQUE9SVEVEID0gIkVSX0NIVU5LRURJTlRBUlJBWV9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfT0ZGU0VUX0JJR0dFUl9USEFOX1NMT1QgPSAiRVJfT0ZGU0VUX0JJR0dFUl9USEFOX1NMT1QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1JPVVRJTkVfTk9UX0FWQUlMID0gIkVSX0NPUk9VVElORV9OT1RfQVZBSUwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1JPVVRJTkVfQ09fRVhJVCA9ICJFUl9DT1JPVVRJTkVfQ09fRVhJVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPSk9JTlJPVVRJTkVTRVRfRkFJTEVEID0gIkVSX0NPSk9JTlJPVVRJTkVTRVRfRkFJTEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09ST1VUSU5FX1BBUkFNID0gIkVSX0NPUk9VVElORV9QQVJBTSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BBUlNFUl9ET1RFUk1JTkFURV9BTlNXRVJTID0gIkVSX1BBUlNFUl9ET1RFUk1JTkFURV9BTlNXRVJTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fUEFSU0VfQ0FMTF9XSElMRV9QQVJTSU5HID0gIkVSX05PX1BBUlNFX0NBTExfV0hJTEVfUEFSU0lORyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1RZUEVEX0lURVJBVE9SX0FYSVNfTk9UX0lNUExFTUVOVEVEID0gIkVSX1RZUEVEX0lURVJBVE9SX0FYSVNfTk9UX0lNUExFTUVOVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSVRFUkFUT1JfQVhJU19OT1RfSU1QTEVNRU5URUQgPSAiRVJfSVRFUkFUT1JfQVhJU19OT1RfSU1QTEVNRU5URUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JVEVSQVRPUl9DTE9ORV9OT1RfU1VQUE9SVEVEID0gIkVSX0lURVJBVE9SX0NMT05FX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTktOT1dOX0FYSVNfVFlQRSA9ICJFUl9VTktOT1dOX0FYSVNfVFlQRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FYSVNfTk9UX1NVUFBPUlRFRCA9ICJFUl9BWElTX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19EVE1JRFNfQVZBSUwgPSAiRVJfTk9fRFRNSURTX0FWQUlMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9UX1NVUFBPUlRFRCA9ICJFUl9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9ERV9OT05fTlVMTCA9ICJFUl9OT0RFX05PTl9OVUxMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTERfTk9UX1JFU09MVkVfTk9ERSA9ICJFUl9DT1VMRF9OT1RfUkVTT0xWRV9OT0RFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU1RBUlRQQVJTRV9XSElMRV9QQVJTSU5HID0gIkVSX1NUQVJUUEFSU0VfV0hJTEVfUEFSU0lORyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NUQVJUUEFSU0VfTkVFRFNfU0FYUEFSU0VSID0gIkVSX1NUQVJUUEFSU0VfTkVFRFNfU0FYUEFSU0VSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTERfTk9UX0lOSVRfUEFSU0VSID0gIkVSX0NPVUxEX05PVF9JTklUX1BBUlNFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYQ0VQVElPTl9DUkVBVElOR19QT09MID0gIkVSX0VYQ0VQVElPTl9DUkVBVElOR19QT09MIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUEFUSF9DT05UQUlOU19JTlZBTElEX0VTQ0FQRV9TRVFVRU5DRSA9ICJFUl9QQVRIX0NPTlRBSU5TX0lOVkFMSURfRVNDQVBFX1NFUVVFTkNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU0NIRU1FX1JFUVVJUkVEID0gIkVSX1NDSEVNRV9SRVFVSVJFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1NDSEVNRV9JTl9VUkkgPSAiRVJfTk9fU0NIRU1FX0lOX1VSSSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1NDSEVNRV9JTlVSSSA9ICJFUl9OT19TQ0hFTUVfSU5VUkkiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QQVRIX0lOVkFMSURfQ0hBUiA9ICJFUl9QQVRIX0lOVkFMSURfQ0hBUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NDSEVNRV9GUk9NX05VTExfU1RSSU5HID0gIkVSX1NDSEVNRV9GUk9NX05VTExfU1RSSU5HIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU0NIRU1FX05PVF9DT05GT1JNQU5UID0gIkVSX1NDSEVNRV9OT1RfQ09ORk9STUFOVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0hPU1RfQUREUkVTU19OT1RfV0VMTEZPUk1FRCA9ICJFUl9IT1NUX0FERFJFU1NfTk9UX1dFTExGT1JNRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QT1JUX1dIRU5fSE9TVF9OVUxMID0gIkVSX1BPUlRfV0hFTl9IT1NUX05VTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX1BPUlQgPSAiRVJfSU5WQUxJRF9QT1JUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRlJBR19GT1JfR0VORVJJQ19VUkkgPSJFUl9GUkFHX0ZPUl9HRU5FUklDX1VSSSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZSQUdfV0hFTl9QQVRIX05VTEwgPSAiRVJfRlJBR19XSEVOX1BBVEhfTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZSQUdfSU5WQUxJRF9DSEFSID0gIkVSX0ZSQUdfSU5WQUxJRF9DSEFSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUEFSU0VSX0lOX1VTRSA9ICJFUl9QQVJTRVJfSU5fVVNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX0NIQU5HRV9XSElMRV9QQVJTSU5HID0gIkVSX0NBTk5PVF9DSEFOR0VfV0hJTEVfUEFSU0lORyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NFTEZfQ0FVU0FUSU9OX05PVF9QRVJNSVRURUQgPSAiRVJfU0VMRl9DQVVTQVRJT05fTk9UX1BFUk1JVFRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1VTRVJJTkZPX0lGX05PX0hPU1QgPSAiRVJfTk9fVVNFUklORk9fSUZfTk9fSE9TVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1BPUlRfSUZfTk9fSE9TVCA9ICJFUl9OT19QT1JUX0lGX05PX0hPU1QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19RVUVSWV9TVFJJTkdfSU5fUEFUSCA9ICJFUl9OT19RVUVSWV9TVFJJTkdfSU5fUEFUSCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX0ZSQUdNRU5UX1NUUklOR19JTl9QQVRIID0gIkVSX05PX0ZSQUdNRU5UX1NUUklOR19JTl9QQVRIIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX0lOSVRfVVJJX0VNUFRZX1BBUk1TID0gIkVSX0NBTk5PVF9JTklUX1VSSV9FTVBUWV9QQVJNUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01FVEhPRF9OT1RfU1VQUE9SVEVEID0iRVJfTUVUSE9EX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTkNSU0FYU1JDRklMVEVSX05PVF9SRVNUQVJUQUJMRSA9ICJFUl9JTkNSU0FYU1JDRklMVEVSX05PVF9SRVNUQVJUQUJMRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hNTFJEUl9OT1RfQkVGT1JFX1NUQVJUUEFSU0UgPSAiRVJfWE1MUkRSX05PVF9CRUZPUkVfU1RBUlRQQVJTRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FYSVNfVFJBVkVSU0VSX05PVF9TVVBQT1JURUQgPSAiRVJfQVhJU19UUkFWRVJTRVJfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VSUk9SSEFORExFUl9DUkVBVEVEX1dJVEhfTlVMTF9QUklOVFdSSVRFUiA9ICJFUl9FUlJPUkhBTkRMRVJfQ1JFQVRFRF9XSVRIX05VTExfUFJJTlRXUklURVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TWVNURU1JRF9VTktOT1dOID0gIkVSX1NZU1RFTUlEX1VOS05PV04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9MT0NBVElPTl9VTktOT1dOID0gIkVSX0xPQ0FUSU9OX1VOS05PV04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUkVGSVhfTVVTVF9SRVNPTFZFID0gIkVSX1BSRUZJWF9NVVNUX1JFU09MVkUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DUkVBVEVET0NVTUVOVF9OT1RfU1VQUE9SVEVEID0gIkVSX0NSRUFURURPQ1VNRU5UX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DSElMRF9IQVNfTk9fT1dORVJfRE9DVU1FTlQgPSAiRVJfQ0hJTERfSEFTX05PX09XTkVSX0RPQ1VNRU5UIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0hJTERfSEFTX05PX09XTkVSX0RPQ1VNRU5UX0VMRU1FTlQgPSAiRVJfQ0hJTERfSEFTX05PX09XTkVSX0RPQ1VNRU5UX0VMRU1FTlQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX09VVFBVVF9URVhUX0JFRk9SRV9ET0MgPSAiRVJfQ0FOVF9PVVRQVVRfVEVYVF9CRUZPUkVfRE9DIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9IQVZFX01PUkVfVEhBTl9PTkVfUk9PVCA9ICJFUl9DQU5UX0hBVkVfTU9SRV9USEFOX09ORV9ST09UIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQVJHX0xPQ0FMTkFNRV9OVUxMID0gIkVSX0FSR19MT0NBTE5BTUVfTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FSR19MT0NBTE5BTUVfSU5WQUxJRCA9ICJFUl9BUkdfTE9DQUxOQU1FX0lOVkFMSUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9BUkdfUFJFRklYX0lOVkFMSUQgPSAiRVJfQVJHX1BSRUZJWF9JTlZBTElEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTkFNRV9DQU5UX1NUQVJUX1dJVEhfQ09MT04gPSAiRVJfTkFNRV9DQU5UX1NUQVJUX1dJVEhfQ09MT04iOwotCi0gIC8vIE1lc3NhZ2Uga2V5cyB1c2VkIGJ5IHRoZSBzZXJpYWxpemVyCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1JFU09VUkNFX0NPVUxEX05PVF9GSU5EID0gIkVSX1JFU09VUkNFX0NPVUxEX05PVF9GSU5EIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUkVTT1VSQ0VfQ09VTERfTk9UX0xPQUQgPSAiRVJfUkVTT1VSQ0VfQ09VTERfTk9UX0xPQUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9CVUZGRVJfU0laRV9MRVNTVEhBTl9aRVJPID0gIkVSX0JVRkZFUl9TSVpFX0xFU1NUSEFOX1pFUk8iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX1VURjE2X1NVUlJPR0FURSA9ICJFUl9JTlZBTElEX1VURjE2X1NVUlJPR0FURSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX09JRVJST1IgPSAiRVJfT0lFUlJPUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05BTUVTUEFDRV9QUkVGSVggPSAiRVJfTkFNRVNQQUNFX1BSRUZJWCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NUUkFZX0FUVFJJQlVURSA9ICJFUl9TVFJBWV9BVFRJUkJVVEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TVFJBWV9OQU1FU1BBQ0UgPSAiRVJfU1RSQVlfTkFNRVNQQUNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTERfTk9UX0xPQURfUkVTT1VSQ0UgPSAiRVJfQ09VTERfTk9UX0xPQURfUkVTT1VSQ0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRF9OT1RfTE9BRF9NRVRIT0RfUFJPUEVSVFkgPSAiRVJfQ09VTERfTk9UX0xPQURfTUVUSE9EX1BST1BFUlRZIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU0VSSUFMSVpFUl9OT1RfQ09OVEVOVEhBTkRMRVIgPSAiRVJfU0VSSUFMSVpFUl9OT1RfQ09OVEVOVEhBTkRMRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTExFR0FMX0FUVFJJQlVURV9QT1NJVElPTiA9ICJFUl9JTExFR0FMX0FUVFJJQlVURV9QT1NJVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lMTEVHQUxfQ0hBUkFDVEVSID0gIkVSX0lMTEVHQUxfQ0hBUkFDVEVSIjsKLQotICAvKgotICAgKiBOb3cgZmlsbCBpbiB0aGUgbWVzc2FnZSB0ZXh0LgotICAgKiBUaGVuIGZpbGwgaW4gdGhlIG1lc3NhZ2UgdGV4dCBmb3IgdGhhdCBtZXNzYWdlIGNvZGUgaW4gdGhlCi0gICAqIGFycmF5LiBVc2UgdGhlIG5ldyBlcnJvciBjb2RlIGFzIHRoZSBpbmRleCBpbnRvIHRoZSBhcnJheS4KLSAgICovCi0KLSAgLy8gRXJyb3IgbWVzc2FnZXMuLi4KLQotICAvKiogVGhlIGxvb2t1cCB0YWJsZSBmb3IgZXJyb3IgbWVzc2FnZXMuICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgT2JqZWN0W11bXSBjb250ZW50cyA9IHsKLQotICAvKiogRXJyb3IgbWVzc2FnZSBJRCB0aGF0IGhhcyBhIG51bGwgbWVzc2FnZSwgYnV0IHRha2VzIGluIGEgc2luZ2xlIG9iamVjdC4gICAgKi8KLSAgICB7IkVSMDAwMCIgLCAiezB9IiB9LAotCi0gICAgeyBFUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVELAotICAgICAgIkZ1bmNpXHUwMEYzbiBubyBzb3BvcnRhZGEuIn0sCi0KLSAgICB7IEVSX0NBTk5PVF9PVkVSV1JJVEVfQ0FVU0UsCi0gICAgICAiTm8gc2UgcHVlZGUgc29icmVzY3JpYmlyIGxhIGNhdXNhIn0sCi0KLSAgICB7IEVSX05PX0RFRkFVTFRfSU1QTCwKLSAgICAgICJObyBzZSBoYSBlbmNvbnRyYWRvIGxhIGltcGxhbnRhY2lcdTAwRjNuIHBvciBkZWZlY3RvICJ9LAotCi0gICAgeyBFUl9DSFVOS0VESU5UQVJSQVlfTk9UX1NVUFBPUlRFRCwKLSAgICAgICJDaHVua2VkSW50QXJyYXkoezB9KSBubyBlc3RcdTAwRTEgc29wb3J0YWRvIGFjdHVhbG1lbnRlIn0sCi0KLSAgICB7IEVSX09GRlNFVF9CSUdHRVJfVEhBTl9TTE9ULAotICAgICAgIkVsIGRlc3BsYXphbWllbnRvIGVzIG1heW9yIHF1ZSBsYSByYW51cmEifSwKLQotICAgIHsgRVJfQ09ST1VUSU5FX05PVF9BVkFJTCwKLSAgICAgICJDb3JydXRpbmEgbm8gZGlzcG9uaWJsZSwgaWQ9ezB9In0sCi0KLSAgICB7IEVSX0NPUk9VVElORV9DT19FWElULAotICAgICAgIkNvcm91dGluZU1hbmFnZXIgaGEgcmVjaWJpZG8gbGEgc29saWNpdHVkIGNvX2V4aXQoKSJ9LAotCi0gICAgeyBFUl9DT0pPSU5ST1VUSU5FU0VUX0ZBSUxFRCwKLSAgICAgICJGYWxsbyBkZSBjb19qb2luQ29yb3V0aW5lU2V0KCkifSwKLQotICAgIHsgRVJfQ09ST1VUSU5FX1BBUkFNLAotICAgICAgIkVycm9yIGRlIHBhclx1MDBFMW1ldHJvIGRlIGNvcnJ1dGluYSAoezB9KSJ9LAotCi0gICAgeyBFUl9QQVJTRVJfRE9URVJNSU5BVEVfQU5TV0VSUywKLSAgICAgICJcbklORVNQRVJBRE86IHJlc3B1ZXN0YXMgZG9UZXJtaW5hdGUgZGVsIGFuYWxpemFkb3IgezB9In0sCi0KLSAgICB7IEVSX05PX1BBUlNFX0NBTExfV0hJTEVfUEFSU0lORywKLSAgICAgICJubyBzZSBwdWVkZSByZWFsaXphciB1biBhblx1MDBFMWxpc2lzIG1pZW50cmFzIHNlIGxsZXZhIGEgY2FibyBvdHJvIn0sCi0KLSAgICB7IEVSX1RZUEVEX0lURVJBVE9SX0FYSVNfTk9UX0lNUExFTUVOVEVELAotICAgICAgIkVycm9yOiBlbCBpdGVyYWRvciBpbnRyb2R1Y2lkbyBwYXJhIGVsIGVqZSB7MH0gbm8gc2UgaGEgaW1wbGFudGFkbyJ9LAotCi0gICAgeyBFUl9JVEVSQVRPUl9BWElTX05PVF9JTVBMRU1FTlRFRCwKLSAgICAgICJFcnJvcjogZWwgaXRlcmFkb3IgcGFyYSBlbCBlamUgezB9IG5vIHNlIGhhIGltcGxhbnRhZG8gIn0sCi0KLSAgICB7IEVSX0lURVJBVE9SX0NMT05FX05PVF9TVVBQT1JURUQsCi0gICAgICAiTGEgY2xvbmFjaVx1MDBGM24gZGVsIGl0ZXJhZG9yIG5vIGVzdFx1MDBFMSBzb3BvcnRhZGEifSwKLQotICAgIHsgRVJfVU5LTk9XTl9BWElTX1RZUEUsCi0gICAgICAiVGlwbyB0cmFuc3ZlcnNhbCBkZSBlamUgZGVzY29ub2NpZG86IHswfSJ9LAotCi0gICAgeyBFUl9BWElTX05PVF9TVVBQT1JURUQsCi0gICAgICAiVHJhdmVyc2VyIGRlIGVqZSBubyBzb3BvcnRhZG86IHswfSJ9LAotCi0gICAgeyBFUl9OT19EVE1JRFNfQVZBSUwsCi0gICAgICAiTm8gaGF5IG1cdTAwRTFzIGlkZW50aWZpY2Fkb3JlcyBkZSBEVE0gZGlzcG9uaWJsZXMifSwKLQotICAgIHsgRVJfTk9UX1NVUFBPUlRFRCwKLSAgICAgICJObyBzb3BvcnRhZG86IHswfSJ9LAotCi0gICAgeyBFUl9OT0RFX05PTl9OVUxMLAotICAgICAgIkVsIG5vZG8gZGViZSBzZXIgbm8gbnVsbyBwYXJhIGdldERUTUhhbmRsZUZyb21Ob2RlIn0sCi0KLSAgICB7IEVSX0NPVUxEX05PVF9SRVNPTFZFX05PREUsCi0gICAgICAiTm8gc2UgaGEgcG9kaWRvIHJlc29sdmVyIGVsIG5vZG8gZW4gdW4gaWRlbnRpZmljYWRvciJ9LAotCi0gICAgeyBFUl9TVEFSVFBBUlNFX1dISUxFX1BBUlNJTkcsCi0gICAgICAgInN0YXJ0UGFyc2Ugbm8gcHVlZGUgbGxhbWFyc2UgZHVyYW50ZSBlbCBhblx1MDBFMWxpc2lzIn0sCi0KLSAgICB7IEVSX1NUQVJUUEFSU0VfTkVFRFNfU0FYUEFSU0VSLAotICAgICAgICJzdGFydFBhcnNlIG5lY2VzaXRhIHVuIFNBWFBhcnNlciBubyBudWxvIn0sCi0KLSAgICB7IEVSX0NPVUxEX05PVF9JTklUX1BBUlNFUiwKLSAgICAgICAibm8gc2UgaGEgcG9kaWRvIGluaWNpYWxpemFyIGVsIGFuYWxpemFkb3IgY29uIn0sCi0KLSAgICB7IEVSX0VYQ0VQVElPTl9DUkVBVElOR19QT09MLAotICAgICAgICJleGNlcGNpXHUwMEYzbiBhbCBjcmVhciBsYSBudWV2YSBpbnN0YW5jaWEgcGFyYSBlbCBwb29sIn0sCi0KLSAgICB7IEVSX1BBVEhfQ09OVEFJTlNfSU5WQUxJRF9FU0NBUEVfU0VRVUVOQ0UsCi0gICAgICAgIkxhIHJ1dGEgZGUgYWNjZXNvIGNvbnRpZW5lIHVuYSBzZWN1ZW5jaWEgZGUgZXNjYXBlIG5vIHZcdTAwRTFsaWRhIn0sCi0KLSAgICB7IEVSX1NDSEVNRV9SRVFVSVJFRCwKLSAgICAgICAiU2UgbmVjZXNpdGEgdW4gZXNxdWVtYS4ifSwKLQotICAgIHsgRVJfTk9fU0NIRU1FX0lOX1VSSSwKLSAgICAgICAiTm8gc2UgaGEgZW5jb250cmFkbyB1biBlc3F1ZW1hIGVuIGVsIFVSSTogezB9In0sCi0KLSAgICB7IEVSX05PX1NDSEVNRV9JTlVSSSwKLSAgICAgICAiTm8gc2UgaGEgZW5jb250cmFkbyB1biBlc3F1ZW1hIGVuIGVsIFVSSSJ9LAotCi0gICAgeyBFUl9QQVRIX0lOVkFMSURfQ0hBUiwKLSAgICAgICAiTGEgcnV0YSBkZSBhY2Nlc28gY29udGllbmUgdW4gY2FyXHUwMEUxY3RlciBubyB2XHUwMEUxbGlkbzogezB9In0sCi0KLSAgICB7IEVSX1NDSEVNRV9GUk9NX05VTExfU1RSSU5HLAotICAgICAgICJObyBzZSBwdWVkZSBkZWZpbmlyIHVuIGVzcXVlbWEgYSBwYXJ0aXIgZGUgdW5hIGNhZGVuYSBudWxhIn0sCi0KLSAgICB7IEVSX1NDSEVNRV9OT1RfQ09ORk9STUFOVCwKLSAgICAgICAiRWwgZXNxdWVtYSBubyBlcyB2XHUwMEUxbGlkby4ifSwKLQotICAgIHsgRVJfSE9TVF9BRERSRVNTX05PVF9XRUxMRk9STUVELAotICAgICAgICJFbCBmb3JtYXRvIGRlIGxhIGRpcmVjY2lcdTAwRjNuIGRlIGhvc3Qgbm8gZXMgY29ycmVjdG8ifSwKLQotICAgIHsgRVJfUE9SVF9XSEVOX0hPU1RfTlVMTCwKLSAgICAgICAiTm8gc2UgcHVlZGUgZGVmaW5pciBlbCBwdWVydG8gc2kgZWwgaG9zdCBlcyBudWxvIn0sCi0KLSAgICB7IEVSX0lOVkFMSURfUE9SVCwKLSAgICAgICAiTlx1MDBGQW1lcm8gZGUgcHVlcnRvIG5vIHZcdTAwRTFsaWRvIn0sCi0KLSAgICB7IEVSX0ZSQUdfRk9SX0dFTkVSSUNfVVJJLAotICAgICAgICJTXHUwMEYzbG8gc2UgcHVlZGUgZGVmaW5pciBlbCBmcmFnbWVudG8gcGFyYSB1biBVUkkgZ2VuXHUwMEU5cmljbyJ9LAotCi0gICAgeyBFUl9GUkFHX1dIRU5fUEFUSF9OVUxMLAotICAgICAgICJObyBzZSBwdWVkZSBkZWZpbmlyIGVsIGZyYWdtZW50byBzaSBsYSBydXRhIGRlIGFjY2VzbyBlcyBudWxhIn0sCi0KLSAgICB7IEVSX0ZSQUdfSU5WQUxJRF9DSEFSLAotICAgICAgICJFbCBmcmFnbWVudG8gY29udGllbmUgdW4gY2FyXHUwMEUxY3RlciBubyB2XHUwMEUxbGlkbyJ9LAotCi0gICAgeyBFUl9QQVJTRVJfSU5fVVNFLAotICAgICAgIkVsIGFuYWxpemFkb3IgeWEgc2UgZXN0XHUwMEUxIHV0aWxpemFuZG8ifSwKLQotICAgIHsgRVJfQ0FOTk9UX0NIQU5HRV9XSElMRV9QQVJTSU5HLAotICAgICAgIk5vIHNlIHB1ZWRlIGNhbWJpYXIgezB9IHsxfSBkdXJhbnRlIGVsIGFuXHUwMEUxbGlzaXMifSwKLQotICAgIHsgRVJfU0VMRl9DQVVTQVRJT05fTk9UX1BFUk1JVFRFRCwKLSAgICAgICJMYSBhdXRvY2F1c2FsaWRhZCBubyBlc3RcdTAwRTEgcGVybWl0aWRhIn0sCi0KLSAgICB7IEVSX05PX1VTRVJJTkZPX0lGX05PX0hPU1QsCi0gICAgICAiTm8gc2UgcHVlZGUgZXNwZWNpZmljYXIgbGEgaW5mb3JtYWNpXHUwMEYzbiBkZSB1c3VhcmlvIHNpIG5vIHNlIGhhIGVzcGVjaWZpY2FkbyBlbCBob3N0In0sCi0KLSAgICB7IEVSX05PX1BPUlRfSUZfTk9fSE9TVCwKLSAgICAgICJObyBzZSBwdWVkZSBlc3BlY2lmaWNhciBlbCBwdWVydG8gc2kgbm8gc2UgaGEgZXNwZWNpZmljYWRvIGVsIGhvc3QifSwKLQotICAgIHsgRVJfTk9fUVVFUllfU1RSSU5HX0lOX1BBVEgsCi0gICAgICAiTm8gc2UgcHVlZGUgZXNwZWNpZmljYXIgbGEgY2FkZW5hIGRlIGNvbnN1bHRhIGVuIGxhIHJ1dGEgZGUgYWNjZXNvIHkgZW4gbGEgY2FkZW5hIGRlIGNvbnN1bHRhIn0sCi0KLSAgICB7IEVSX05PX0ZSQUdNRU5UX1NUUklOR19JTl9QQVRILAotICAgICAgIk5vIHNlIHB1ZWRlIGVzcGVjaWZpY2FyIGVsIGZyYWdtZW50byBlbiBsYSBydXRhIGRlIGFjY2VzbyB5IGVuIGVsIGZyYWdtZW50byJ9LAotCi0gICAgeyBFUl9DQU5OT1RfSU5JVF9VUklfRU1QVFlfUEFSTVMsCi0gICAgICAiTm8gc2UgcHVlZGUgaW5pY2lhbGl6YXIgZWwgVVJJIGNvbiBwYXJcdTAwRTFtZXRyb3MgdmFjXHUwMEVEb3MifSwKLQotICAgIHsgRVJfTUVUSE9EX05PVF9TVVBQT1JURUQsCi0gICAgICAiTVx1MDBFOXRvZG8gbm8gc29wb3J0YWRvIGFcdTAwRkFuICJ9LAotCi0gICAgeyBFUl9JTkNSU0FYU1JDRklMVEVSX05PVF9SRVNUQVJUQUJMRSwKLSAgICAgICJJbmNyZW1lbnRhbFNBWFNvdXJjZV9GaWx0ZXIgbm8gc2UgcHVlZGUgcmVpbmljaWFyIGFjdHVhbG1lbnRlIn0sCi0KLSAgICB7IEVSX1hNTFJEUl9OT1RfQkVGT1JFX1NUQVJUUEFSU0UsCi0gICAgICAiWE1MUmVhZGVyIG5vIGFudGVyaW9yIGEgbGEgc29saWNpdHVkIHN0YXJ0UGFyc2UifSwKLQotICAgIHsgRVJfQVhJU19UUkFWRVJTRVJfTk9UX1NVUFBPUlRFRCwKLSAgICAgICJUcmF2ZXJzZXIgZGUgZWplIG5vIHNvcG9ydGFkbzogezB9In0sCi0KLSAgICB7IEVSX0VSUk9SSEFORExFUl9DUkVBVEVEX1dJVEhfTlVMTF9QUklOVFdSSVRFUiwKLSAgICAgICJMaXN0aW5nRXJyb3JIYW5kbGVyIHNlIGhhIGNyZWFkbyBjb24gdW4gdmFsb3IgZGUgUHJpbnRXcml0ZXIgbnVsbyJ9LAotCi0gICAgeyBFUl9TWVNURU1JRF9VTktOT1dOLAotICAgICAgIklkZW50aWZpY2Fkb3IgZGUgU2lzdGVtYSBEZXNjb25vY2lkbyJ9LAotCi0gICAgeyBFUl9MT0NBVElPTl9VTktOT1dOLAotICAgICAgIlViaWNhY2lcdTAwRjNuIGRlbCBlcnJvciBkZXNjb25vY2lkYSJ9LAotCi0gICAgeyBFUl9QUkVGSVhfTVVTVF9SRVNPTFZFLAotICAgICAgIkVsIHByZWZpam8gc2UgZGViZSByZXNvbHZlciBlbiB1biBlc3BhY2lvIGRlIG5vbWJyZXM6IHswfSJ9LAotCi0gICAgeyBFUl9DUkVBVEVET0NVTUVOVF9OT1RfU1VQUE9SVEVELAotICAgICAgImNyZWF0ZURvY3VtZW50KCkgbm8gc29wb3J0YWRvIGVuIFhQYXRoQ29udGV4dCJ9LAotCi0gICAgeyBFUl9DSElMRF9IQVNfTk9fT1dORVJfRE9DVU1FTlQsCi0gICAgICAiRWwgYXRyaWJ1dG8gY2hpbGQgbm8gdGllbmUgdW4gZG9jdW1lbnRvIGRlIHByb3BpZXRhcmlvLiJ9LAotCi0gICAgeyBFUl9DSElMRF9IQVNfTk9fT1dORVJfRE9DVU1FTlRfRUxFTUVOVCwKLSAgICAgICJFbCBhdHJpYnV0byBjaGlsZCBubyB0aWVuZSB1biBlbGVtZW50byBkZSBkb2N1bWVudG8gZGUgcHJvcGlldGFyaW8uIn0sCi0KLSAgICB7IEVSX0NBTlRfT1VUUFVUX1RFWFRfQkVGT1JFX0RPQywKLSAgICAgICJBZHZlcnRlbmNpYTogbm8gc2UgcHVlZGUgcmVhbGl6YXIgbGEgc2FsaWRhIGRlIHRleHRvIGFudGVzIGRlbCBlbGVtZW50byBkZWwgZG9jdW1lbnRvLiBJZ25vcmFuZG8uLi4ifSwKLQotICAgIHsgRVJfQ0FOVF9IQVZFX01PUkVfVEhBTl9PTkVfUk9PVCwKLSAgICAgICJObyBzZSBwdWVkZSB0ZW5lciBtXHUwMEUxcyBkZSB1bmEgcmFcdTAwRUR6IGVuIHVuIERPTS4ifSwKLQotICAgIHsgRVJfQVJHX0xPQ0FMTkFNRV9OVUxMLAotICAgICAgICJFbCBhcmd1bWVudG8gJ2xvY2FsTmFtZScgZXMgbnVsbyJ9LAotCi0gICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIEEgUU5BTUUgaGFzIHRoZSBzeW50YWN0aWMgZm9ybSBbTkNOYW1lOl1OQ05hbWUKLSAgICAvLyBUaGUgbG9jYWxuYW1lIGlzIHRoZSBwb3J0aW9uIGFmdGVyIHRoZSBvcHRpb25hbCBjb2xvbjsgdGhlIG1lc3NhZ2UgaW5kaWNhdGVzCi0gICAgLy8gdGhhdCB0aGVyZSBpcyBhIHByb2JsZW0gd2l0aCB0aGF0IHBhcnQgb2YgdGhlIFFOQU1FLgotICAgIHsgRVJfQVJHX0xPQ0FMTkFNRV9JTlZBTElELAotICAgICAgICJFbCBub21icmUgbG9jYWwgZGUgUU5BTUUgZGViZSBzZXIgdW4gTkNOYW1lIHZcdTAwRTFsaWRvIn0sCi0KLSAgICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQSBRTkFNRSBoYXMgdGhlIHN5bnRhY3RpYyBmb3JtIFtOQ05hbWU6XU5DTmFtZQotICAgIC8vIFRoZSBwcmVmaXggaXMgdGhlIHBvcnRpb24gYmVmb3JlIHRoZSBvcHRpb25hbCBjb2xvbjsgdGhlIG1lc3NhZ2UgaW5kaWNhdGVzCi0gICAgLy8gdGhhdCB0aGVyZSBpcyBhIHByb2JsZW0gd2l0aCB0aGF0IHBhcnQgb2YgdGhlIFFOQU1FLgotICAgIHsgRVJfQVJHX1BSRUZJWF9JTlZBTElELAotICAgICAgICJFbCBwcmVmaWpvIGRlIFFOQU1FIGRlYmUgc2VyIHVuIE5DTmFtZSB2XHUwMEUxbGlkbyJ9LAotCi0gICAgeyBFUl9OQU1FX0NBTlRfU1RBUlRfV0lUSF9DT0xPTiwKLSAgICAgICJFbCBub21icmUgbm8gcHVlZGUgZW1wZXphciBjb24gZG9zIHB1bnRvcyJ9LAotCi0gICAgeyAiQkFEX0NPREUiLCAiRWwgcGFyXHUwMEUxbWV0cm8gcGFyYSBjcmVhciB1biBtZW5zYWplIGVzdFx1MDBFMSBmdWVyYSBkZSBsb3MgbFx1MDBFRG1pdGVzIn0sCi0gICAgeyAiRk9STUFUX0ZBSUxFRCIsICJTZSBoYSBlbWl0aWRvIHVuYSBleGNlcGNpXHUwMEYzbiBkdXJhbnRlIGxhIGxsYW1hZGEgYSBtZXNzYWdlRm9ybWF0In0sCi0gICAgeyAibGluZSIsICJOXHUwMEJBIGRlIExcdTAwRURuZWEifSwKLSAgICB7ICJjb2x1bW4iLCJOXHUwMEJBIGRlIENvbHVtbmEifSwKLQotICAgIHtFUl9TRVJJQUxJWkVSX05PVF9DT05URU5USEFORExFUiwKLSAgICAgICJMYSBjbGFzZSBkZSBzZXJpYWxpemFkb3IgJyd7MH0nJyBubyBpbXBsYW50YSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlci4ifSwKLQotICAgIHtFUl9SRVNPVVJDRV9DT1VMRF9OT1RfRklORCwKLSAgICAgICJObyBzZSBoYSBlbmNvbnRyYWRvIGVsIHJlY3Vyc28gWyB7MH0gXS5cbiB7MX0iIH0sCi0KLSAgICB7RVJfUkVTT1VSQ0VfQ09VTERfTk9UX0xPQUQsCi0gICAgICAiTm8gc2UgaGEgcG9kaWRvIGNhcmdhciBlbCByZWN1cnNvIFsgezB9IF06IHsxfSBcbiB7Mn0gXHQgezN9IiB9LAotCi0gICAge0VSX0JVRkZFUl9TSVpFX0xFU1NUSEFOX1pFUk8sCi0gICAgICAiVGFtYVx1MDBGMW8gZGUgYnVmZmVyIG1lbm9yIG8gaWd1YWwgcXVlIDAiIH0sCi0KLSAgICB7RVJfSU5WQUxJRF9VVEYxNl9TVVJST0dBVEUsCi0gICAgICAiXHUwMEJGU2UgaGEgZGV0ZWN0YWRvIHVuIHN1c3RpdHV0byBVVEYtMTYgbm8gdlx1MDBFMWxpZG86IHswfT8iIH0sCi0KLSAgICB7RVJfT0lFUlJPUiwKLSAgICAgICJFcnJvciBkZSBFUyIgfSwKLQotICAgIHtFUl9JTExFR0FMX0FUVFJJQlVURV9QT1NJVElPTiwKLSAgICAgICJObyBzZSBwdWVkZSBhZ3JlZ2FyIGVsIGF0cmlidXRvIHswfSBkZXNwdVx1MDBFOXMgZGUgbm9kb3Mgc2VjdW5kYXJpb3MgbyBhbnRlcyBkZSBxdWUgc2UgcHJvZHV6Y2EgdW4gZWxlbWVudG8uIFNlIGlnbm9yYXJcdTAwRTEgZWwgYXRyaWJ1dG8uIn0sCi0KLSAgICAgIC8qCi0gICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN0eWxlc2hlZXQgY29udGFpbmVkIGEgcmVmZXJlbmNlIHRvIGEKLSAgICAgICAqIG5hbWVzcGFjZSBwcmVmaXggdGhhdCB3YXMgdW5kZWZpbmVkLiAgVGhlIHZhbHVlIG9mIHRoZSBzdWJzdGl0dXRpb24KLSAgICAgICAqIHRleHQgaXMgdGhlIG5hbWUgb2YgdGhlIHByZWZpeC4KLSAgICAgICAqLwotICAgIHtFUl9OQU1FU1BBQ0VfUFJFRklYLAotICAgICAgIk5vIHNlIGhhIGRlY2xhcmFkbyBlbCBlc3BhY2lvIGRlIG5vbWJyZXMgcGFyYSBlbCBwcmVmaWpvICcnezB9JycuIiB9LAotICAgICAgLyoKLSAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgcmVwb3J0ZWQgaWYgdGhlIHN0eWxlc2hlZXQKLSAgICAgICAqIGJlaW5nIHByb2Nlc3NlZCBhdHRlbXB0ZWQgdG8gY29uc3RydWN0IGFuIFhNTCBkb2N1bWVudCB3aXRoIGFuCi0gICAgICAgKiBhdHRyaWJ1dGUgaW4gYSBwbGFjZSBvdGhlciB0aGFuIG9uIGFuIGVsZW1lbnQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQKLSAgICAgICAqIHNwZWNpZmllcyB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlLgotICAgICAgICovCi0gICAge0VSX1NUUkFZX0FUVFJJQlVURSwKLSAgICAgICJFbCBhdHJpYnV0byAnJ3swfScnIGVzdFx1MDBFMSBmdWVyYSBkZWwgZWxlbWVudG8uIiB9LAotCi0gICAgICAvKgotICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFzIHdpdGggdGhlIHByZWNlZGluZyBtZXNzYWdlLCBhIG5hbWVzcGFjZQotICAgICAgICogZGVjbGFyYXRpb24gaGFzIHRoZSBmb3JtIG9mIGFuIGF0dHJpYnV0ZSBhbmQgaXMgb25seSBwZXJtaXR0ZWQgdG8KLSAgICAgICAqIGFwcGVhciBvbiBhbiBlbGVtZW50LiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHswfSBpcyB0aGUgbmFtZXNwYWNlCi0gICAgICAgKiBwcmVmaXggYW5kIHsxfSBpcyB0aGUgVVJJIHRoYXQgd2FzIGJlaW5nIHVzZWQgaW4gdGhlIGVycm9uZW91cwotICAgICAgICogbmFtZXNwYWNlIGRlY2xhcmF0aW9uLgotICAgICAgICovCi0gICAge0VSX1NUUkFZX05BTUVTUEFDRSwKLSAgICAgICJEZWNsYXJhY2lcdTAwRjNuIGRlbCBlc3BhY2lvIGRlIG5vbWJyZXMgJyd7MH0nJz0nJ3sxfScnIGZ1ZXJhIGRlbCBlbGVtZW50by4iIH0sCi0KLSAgICB7RVJfQ09VTERfTk9UX0xPQURfUkVTT1VSQ0UsCi0gICAgICAiTm8gc2UgaGEgcG9kaWRvIGNhcmdhciAnJ3swfScnIChjb21wcnVlYmUgbGEgQ0xBU1NQQVRIKSwgYWhvcmEgc1x1MDBGM2xvIHNlIGVzdFx1MDBFMW4gdXRpbGl6YW5kbyBsb3MgdmFsb3JlcyBwb3IgZGVmZWN0byJ9LAotCi0gICAgeyBFUl9JTExFR0FMX0NIQVJBQ1RFUiwKLSAgICAgICAiSW50ZW50byBkZSByZWFsaXphciBsYSBzYWxpZGEgZGVsIGNhclx1MDBFMWN0ZXIgZGVsIHZhbG9yIGludGVncmFsIHswfSwgcXVlIG5vIGVzdFx1MDBFMSByZXByZXNlbnRhZG8gZW4gbGEgY29kaWZpY2FjaVx1MDBGM24gZGUgc2FsaWRhIGRlIHsxfS4ifSwKLQotICAgIHtFUl9DT1VMRF9OT1RfTE9BRF9NRVRIT0RfUFJPUEVSVFksCi0gICAgICAiTm8gc2UgaGEgcG9kaWRvIGNhcmdhciBlbCBhcmNoaXZvIGRlIHByb3BpZWRhZGVzICcnezB9JycgcGFyYSBlbCBtXHUwMEU5dG9kbyBkZSBzYWxpZGEgJyd7MX0nJyAoY29tcHJ1ZWJlIGxhIENMQVNTUEFUSCkiIH0KLQotCi0gIH07Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgYXNzb2NpYXRpb24gbGlzdC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgYXNzb2NpYXRpb24gbGlzdC4KLSAgICovCi0KLSAgICBwcm90ZWN0ZWQgT2JqZWN0W11bXSBnZXRDb250ZW50cygpIHsKLSAgICAgICAgcmV0dXJuIGNvbnRlbnRzOwotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvcmVzL1hNTEVycm9yUmVzb3VyY2VzX2ZyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9yZXMvWE1MRXJyb3JSZXNvdXJjZXNfZnIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggODE1NWJmNC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9yZXMvWE1MRXJyb3JSZXNvdXJjZXNfZnIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQ1MCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzOwotCi0KLWltcG9ydCBqYXZhLnV0aWwuTGlzdFJlc291cmNlQnVuZGxlOwotCi0vKioKLSAqIFNldCB1cCBlcnJvciBtZXNzYWdlcy4KLSAqIFdlIGJ1aWxkIGEgdHdvIGRpbWVuc2lvbmFsIGFycmF5IG9mIG1lc3NhZ2Uga2V5cyBhbmQKLSAqIG1lc3NhZ2Ugc3RyaW5ncy4gSW4gb3JkZXIgdG8gYWRkIGEgbmV3IG1lc3NhZ2UgaGVyZSwKLSAqIHlvdSBuZWVkIHRvIGZpcnN0IGFkZCBhIFN0cmluZyBjb25zdGFudC4gQW5kIHlvdSBuZWVkCi0gKiB0byBlbnRlciBrZXksIHZhbHVlIHBhaXIgYXMgcGFydCBvZiB0aGUgY29udGVudHMKLSAqIGFycmF5LiBZb3UgYWxzbyBuZWVkIHRvIHVwZGF0ZSBNQVhfQ09ERSBmb3IgZXJyb3Igc3RyaW5ncwotICogYW5kIE1BWF9XQVJOSU5HIGZvciB3YXJuaW5ncyAoIE5lZWRlZCBmb3Igb25seSBpbmZvcm1hdGlvbgotICogcHVycG9zZSApCi0gKi8KLXB1YmxpYyBjbGFzcyBYTUxFcnJvclJlc291cmNlc19mciBleHRlbmRzIExpc3RSZXNvdXJjZUJ1bmRsZQotewotCi0vKgotICogVGhpcyBmaWxlIGNvbnRhaW5zIGVycm9yIGFuZCB3YXJuaW5nIG1lc3NhZ2VzIHJlbGF0ZWQgdG8gWGFsYW4gRXJyb3IKLSAqIEhhbmRsaW5nLgotICoKLSAqICBHZW5lcmFsIG5vdGVzIHRvIHRyYW5zbGF0b3JzOgotICoKLSAqICAxKSBYYWxhbiAob3IgbW9yZSBwcm9wZXJseSwgWGFsYW4taW50ZXJwcmV0aXZlKSBhbmQgWFNMVEMgYXJlIG5hbWVzIG9mCi0gKiAgICAgY29tcG9uZW50cy4KLSAqICAgICBYU0xUIGlzIGFuIGFjcm9ueW0gZm9yICJYTUwgU3R5bGVzaGVldCBMYW5ndWFnZTogVHJhbnNmb3JtYXRpb25zIi4KLSAqICAgICBYU0xUQyBpcyBhbiBhY3JvbnltIGZvciBYU0xUIENvbXBpbGVyLgotICoKLSAqICAyKSBBIHN0eWxlc2hlZXQgaXMgYSBkZXNjcmlwdGlvbiBvZiBob3cgdG8gdHJhbnNmb3JtIGFuIGlucHV0IFhNTCBkb2N1bWVudAotICogICAgIGludG8gYSByZXN1bHRhbnQgWE1MIGRvY3VtZW50IChvciBIVE1MIGRvY3VtZW50IG9yIHRleHQpLiAgVGhlCi0gKiAgICAgc3R5bGVzaGVldCBpdHNlbGYgaXMgZGVzY3JpYmVkIGluIHRoZSBmb3JtIG9mIGFuIFhNTCBkb2N1bWVudC4KLSAqCi0gKiAgMykgQSB0ZW1wbGF0ZSBpcyBhIGNvbXBvbmVudCBvZiBhIHN0eWxlc2hlZXQgdGhhdCBpcyB1c2VkIHRvIG1hdGNoIGEKLSAqICAgICBwYXJ0aWN1bGFyIHBvcnRpb24gb2YgYW4gaW5wdXQgZG9jdW1lbnQgYW5kIHNwZWNpZmllcyB0aGUgZm9ybSBvZiB0aGUKLSAqICAgICBjb3JyZXNwb25kaW5nIHBvcnRpb24gb2YgdGhlIG91dHB1dCBkb2N1bWVudC4KLSAqCi0gKiAgNCkgQW4gZWxlbWVudCBpcyBhIG1hcmstdXAgdGFnIGluIGFuIFhNTCBkb2N1bWVudDsgYW4gYXR0cmlidXRlIGlzIGEKLSAqICAgICBtb2RpZmllciBvbiB0aGUgdGFnLiAgRm9yIGV4YW1wbGUsIGluIDxlbGVtIGF0dHI9J3ZhbCcgYXR0cjI9J3ZhbDInPgotICogICAgICJlbGVtIiBpcyBhbiBlbGVtZW50IG5hbWUsICJhdHRyIiBhbmQgImF0dHIyIiBhcmUgYXR0cmlidXRlIG5hbWVzIHdpdGgKLSAqICAgICB0aGUgdmFsdWVzICJ2YWwiIGFuZCAidmFsMiIsIHJlc3BlY3RpdmVseS4KLSAqCi0gKiAgNSkgQSBuYW1lc3BhY2UgZGVjbGFyYXRpb24gaXMgYSBzcGVjaWFsIGF0dHJpYnV0ZSB0aGF0IGlzIHVzZWQgdG8gYXNzb2NpYXRlCi0gKiAgICAgYSBwcmVmaXggd2l0aCBhIFVSSSAodGhlIG5hbWVzcGFjZSkuICBUaGUgbWVhbmluZ3Mgb2YgZWxlbWVudCBuYW1lcyBhbmQKLSAqICAgICBhdHRyaWJ1dGUgbmFtZXMgdGhhdCB1c2UgdGhhdCBwcmVmaXggYXJlIGRlZmluZWQgd2l0aCByZXNwZWN0IHRvIHRoYXQKLSAqICAgICBuYW1lc3BhY2UuCi0gKgotICogIDYpICJUcmFuc2xldCIgaXMgYW4gaW52ZW50ZWQgdGVybSB0aGF0IGRlc2NyaWJlcyB0aGUgY2xhc3MgZmlsZSB0aGF0Ci0gKiAgICAgcmVzdWx0cyBmcm9tIGNvbXBpbGluZyBhbiBYTUwgc3R5bGVzaGVldCBpbnRvIGEgSmF2YSBjbGFzcy4KLSAqCi0gKiAgNykgWFBhdGggaXMgYSBzcGVjaWZpY2F0aW9uIHRoYXQgZGVzY3JpYmVzIGEgbm90YXRpb24gZm9yIGlkZW50aWZ5aW5nCi0gKiAgICAgbm9kZXMgaW4gYSB0cmVlLXN0cnVjdHVyZWQgcmVwcmVzZW50YXRpb24gb2YgYW4gWE1MIGRvY3VtZW50LiAgQW4KLSAqICAgICBpbnN0YW5jZSBvZiB0aGF0IG5vdGF0aW9uIGlzIHJlZmVycmVkIHRvIGFzIGFuIFhQYXRoIGV4cHJlc3Npb24uCi0gKgotICovCi0KLSAgLyoqIE1heGltdW0gZXJyb3IgbWVzc2FnZXMsIHRoaXMgaXMgbmVlZGVkIHRvIGtlZXAgdHJhY2sgb2YgdGhlIG51bWJlciBvZiBtZXNzYWdlcy4gICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFYX0NPREUgPSA2MTsKLQotICAvKiogTWF4aW11bSB3YXJuaW5ncywgdGhpcyBpcyBuZWVkZWQgdG8ga2VlcCB0cmFjayBvZiB0aGUgbnVtYmVyIG9mIHdhcm5pbmdzLiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVhfV0FSTklORyA9IDA7Ci0KLSAgLyoqIE1heGltdW0gbWlzYyBzdHJpbmdzLiAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BWF9PVEhFUlMgPSA0OwotCi0gIC8qKiBNYXhpbXVtIHRvdGFsIHdhcm5pbmdzIGFuZCBlcnJvciBtZXNzYWdlcy4gICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFYX01FU1NBR0VTID0gTUFYX0NPREUgKyBNQVhfV0FSTklORyArIDE7Ci0KLQotICAvKgotICAgKiBNZXNzYWdlIGtleXMKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQgPSAiRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9PVkVSV1JJVEVfQ0FVU0UgPSAiRVJfQ0FOTk9UX09WRVJXUklURV9DQVVTRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX0RFRkFVTFRfSU1QTCA9ICJFUl9OT19ERUZBVUxUX0lNUEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DSFVOS0VESU5UQVJSQVlfTk9UX1NVUFBPUlRFRCA9ICJFUl9DSFVOS0VESU5UQVJSQVlfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX09GRlNFVF9CSUdHRVJfVEhBTl9TTE9UID0gIkVSX09GRlNFVF9CSUdHRVJfVEhBTl9TTE9UIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09ST1VUSU5FX05PVF9BVkFJTCA9ICJFUl9DT1JPVVRJTkVfTk9UX0FWQUlMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09ST1VUSU5FX0NPX0VYSVQgPSAiRVJfQ09ST1VUSU5FX0NPX0VYSVQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT0pPSU5ST1VUSU5FU0VUX0ZBSUxFRCA9ICJFUl9DT0pPSU5ST1VUSU5FU0VUX0ZBSUxFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPUk9VVElORV9QQVJBTSA9ICJFUl9DT1JPVVRJTkVfUEFSQU0iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QQVJTRVJfRE9URVJNSU5BVEVfQU5TV0VSUyA9ICJFUl9QQVJTRVJfRE9URVJNSU5BVEVfQU5TV0VSUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1BBUlNFX0NBTExfV0hJTEVfUEFSU0lORyA9ICJFUl9OT19QQVJTRV9DQUxMX1dISUxFX1BBUlNJTkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9UWVBFRF9JVEVSQVRPUl9BWElTX05PVF9JTVBMRU1FTlRFRCA9ICJFUl9UWVBFRF9JVEVSQVRPUl9BWElTX05PVF9JTVBMRU1FTlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lURVJBVE9SX0FYSVNfTk9UX0lNUExFTUVOVEVEID0gIkVSX0lURVJBVE9SX0FYSVNfTk9UX0lNUExFTUVOVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSVRFUkFUT1JfQ0xPTkVfTk9UX1NVUFBPUlRFRCA9ICJFUl9JVEVSQVRPUl9DTE9ORV9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5LTk9XTl9BWElTX1RZUEUgPSAiRVJfVU5LTk9XTl9BWElTX1RZUEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9BWElTX05PVF9TVVBQT1JURUQgPSAiRVJfQVhJU19OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fRFRNSURTX0FWQUlMID0gIkVSX05PX0RUTUlEU19BVkFJTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PVF9TVVBQT1JURUQgPSAiRVJfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PREVfTk9OX05VTEwgPSAiRVJfTk9ERV9OT05fTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxEX05PVF9SRVNPTFZFX05PREUgPSAiRVJfQ09VTERfTk9UX1JFU09MVkVfTk9ERSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NUQVJUUEFSU0VfV0hJTEVfUEFSU0lORyA9ICJFUl9TVEFSVFBBUlNFX1dISUxFX1BBUlNJTkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TVEFSVFBBUlNFX05FRURTX1NBWFBBUlNFUiA9ICJFUl9TVEFSVFBBUlNFX05FRURTX1NBWFBBUlNFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxEX05PVF9JTklUX1BBUlNFUiA9ICJFUl9DT1VMRF9OT1RfSU5JVF9QQVJTRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FWENFUFRJT05fQ1JFQVRJTkdfUE9PTCA9ICJFUl9FWENFUFRJT05fQ1JFQVRJTkdfUE9PTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BBVEhfQ09OVEFJTlNfSU5WQUxJRF9FU0NBUEVfU0VRVUVOQ0UgPSAiRVJfUEFUSF9DT05UQUlOU19JTlZBTElEX0VTQ0FQRV9TRVFVRU5DRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NDSEVNRV9SRVFVSVJFRCA9ICJFUl9TQ0hFTUVfUkVRVUlSRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19TQ0hFTUVfSU5fVVJJID0gIkVSX05PX1NDSEVNRV9JTl9VUkkiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19TQ0hFTUVfSU5VUkkgPSAiRVJfTk9fU0NIRU1FX0lOVVJJIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUEFUSF9JTlZBTElEX0NIQVIgPSAiRVJfUEFUSF9JTlZBTElEX0NIQVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TQ0hFTUVfRlJPTV9OVUxMX1NUUklORyA9ICJFUl9TQ0hFTUVfRlJPTV9OVUxMX1NUUklORyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NDSEVNRV9OT1RfQ09ORk9STUFOVCA9ICJFUl9TQ0hFTUVfTk9UX0NPTkZPUk1BTlQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9IT1NUX0FERFJFU1NfTk9UX1dFTExGT1JNRUQgPSAiRVJfSE9TVF9BRERSRVNTX05PVF9XRUxMRk9STUVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUE9SVF9XSEVOX0hPU1RfTlVMTCA9ICJFUl9QT1JUX1dIRU5fSE9TVF9OVUxMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9QT1JUID0gIkVSX0lOVkFMSURfUE9SVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZSQUdfRk9SX0dFTkVSSUNfVVJJID0iRVJfRlJBR19GT1JfR0VORVJJQ19VUkkiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GUkFHX1dIRU5fUEFUSF9OVUxMID0gIkVSX0ZSQUdfV0hFTl9QQVRIX05VTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GUkFHX0lOVkFMSURfQ0hBUiA9ICJFUl9GUkFHX0lOVkFMSURfQ0hBUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BBUlNFUl9JTl9VU0UgPSAiRVJfUEFSU0VSX0lOX1VTRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9DSEFOR0VfV0hJTEVfUEFSU0lORyA9ICJFUl9DQU5OT1RfQ0hBTkdFX1dISUxFX1BBUlNJTkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TRUxGX0NBVVNBVElPTl9OT1RfUEVSTUlUVEVEID0gIkVSX1NFTEZfQ0FVU0FUSU9OX05PVF9QRVJNSVRURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19VU0VSSU5GT19JRl9OT19IT1NUID0gIkVSX05PX1VTRVJJTkZPX0lGX05PX0hPU1QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19QT1JUX0lGX05PX0hPU1QgPSAiRVJfTk9fUE9SVF9JRl9OT19IT1NUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fUVVFUllfU1RSSU5HX0lOX1BBVEggPSAiRVJfTk9fUVVFUllfU1RSSU5HX0lOX1BBVEgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19GUkFHTUVOVF9TVFJJTkdfSU5fUEFUSCA9ICJFUl9OT19GUkFHTUVOVF9TVFJJTkdfSU5fUEFUSCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9JTklUX1VSSV9FTVBUWV9QQVJNUyA9ICJFUl9DQU5OT1RfSU5JVF9VUklfRU1QVFlfUEFSTVMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9NRVRIT0RfTk9UX1NVUFBPUlRFRCA9IkVSX01FVEhPRF9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5DUlNBWFNSQ0ZJTFRFUl9OT1RfUkVTVEFSVEFCTEUgPSAiRVJfSU5DUlNBWFNSQ0ZJTFRFUl9OT1RfUkVTVEFSVEFCTEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YTUxSRFJfTk9UX0JFRk9SRV9TVEFSVFBBUlNFID0gIkVSX1hNTFJEUl9OT1RfQkVGT1JFX1NUQVJUUEFSU0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9BWElTX1RSQVZFUlNFUl9OT1RfU1VQUE9SVEVEID0gIkVSX0FYSVNfVFJBVkVSU0VSX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FUlJPUkhBTkRMRVJfQ1JFQVRFRF9XSVRIX05VTExfUFJJTlRXUklURVIgPSAiRVJfRVJST1JIQU5ETEVSX0NSRUFURURfV0lUSF9OVUxMX1BSSU5UV1JJVEVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU1lTVEVNSURfVU5LTk9XTiA9ICJFUl9TWVNURU1JRF9VTktOT1dOIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTE9DQVRJT05fVU5LTk9XTiA9ICJFUl9MT0NBVElPTl9VTktOT1dOIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJFRklYX01VU1RfUkVTT0xWRSA9ICJFUl9QUkVGSVhfTVVTVF9SRVNPTFZFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ1JFQVRFRE9DVU1FTlRfTk9UX1NVUFBPUlRFRCA9ICJFUl9DUkVBVEVET0NVTUVOVF9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0hJTERfSEFTX05PX09XTkVSX0RPQ1VNRU5UID0gIkVSX0NISUxEX0hBU19OT19PV05FUl9ET0NVTUVOVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NISUxEX0hBU19OT19PV05FUl9ET0NVTUVOVF9FTEVNRU5UID0gIkVSX0NISUxEX0hBU19OT19PV05FUl9ET0NVTUVOVF9FTEVNRU5UIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9PVVRQVVRfVEVYVF9CRUZPUkVfRE9DID0gIkVSX0NBTlRfT1VUUFVUX1RFWFRfQkVGT1JFX0RPQyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfSEFWRV9NT1JFX1RIQU5fT05FX1JPT1QgPSAiRVJfQ0FOVF9IQVZFX01PUkVfVEhBTl9PTkVfUk9PVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FSR19MT0NBTE5BTUVfTlVMTCA9ICJFUl9BUkdfTE9DQUxOQU1FX05VTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9BUkdfTE9DQUxOQU1FX0lOVkFMSUQgPSAiRVJfQVJHX0xPQ0FMTkFNRV9JTlZBTElEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQVJHX1BSRUZJWF9JTlZBTElEID0gIkVSX0FSR19QUkVGSVhfSU5WQUxJRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05BTUVfQ0FOVF9TVEFSVF9XSVRIX0NPTE9OID0gIkVSX05BTUVfQ0FOVF9TVEFSVF9XSVRIX0NPTE9OIjsKLQotICAvLyBNZXNzYWdlIGtleXMgdXNlZCBieSB0aGUgc2VyaWFsaXplcgotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SRVNPVVJDRV9DT1VMRF9OT1RfRklORCA9ICJFUl9SRVNPVVJDRV9DT1VMRF9OT1RfRklORCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1JFU09VUkNFX0NPVUxEX05PVF9MT0FEID0gIkVSX1JFU09VUkNFX0NPVUxEX05PVF9MT0FEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQlVGRkVSX1NJWkVfTEVTU1RIQU5fWkVSTyA9ICJFUl9CVUZGRVJfU0laRV9MRVNTVEhBTl9aRVJPIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9VVEYxNl9TVVJST0dBVEUgPSAiRVJfSU5WQUxJRF9VVEYxNl9TVVJST0dBVEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9PSUVSUk9SID0gIkVSX09JRVJST1IiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OQU1FU1BBQ0VfUFJFRklYID0gIkVSX05BTUVTUEFDRV9QUkVGSVgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TVFJBWV9BVFRSSUJVVEUgPSAiRVJfU1RSQVlfQVRUSVJCVVRFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU1RSQVlfTkFNRVNQQUNFID0gIkVSX1NUUkFZX05BTUVTUEFDRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxEX05PVF9MT0FEX1JFU09VUkNFID0gIkVSX0NPVUxEX05PVF9MT0FEX1JFU09VUkNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTERfTk9UX0xPQURfTUVUSE9EX1BST1BFUlRZID0gIkVSX0NPVUxEX05PVF9MT0FEX01FVEhPRF9QUk9QRVJUWSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NFUklBTElaRVJfTk9UX0NPTlRFTlRIQU5ETEVSID0gIkVSX1NFUklBTElaRVJfTk9UX0NPTlRFTlRIQU5ETEVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSUxMRUdBTF9BVFRSSUJVVEVfUE9TSVRJT04gPSAiRVJfSUxMRUdBTF9BVFRSSUJVVEVfUE9TSVRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTExFR0FMX0NIQVJBQ1RFUiA9ICJFUl9JTExFR0FMX0NIQVJBQ1RFUiI7Ci0KLSAgLyoKLSAgICogTm93IGZpbGwgaW4gdGhlIG1lc3NhZ2UgdGV4dC4KLSAgICogVGhlbiBmaWxsIGluIHRoZSBtZXNzYWdlIHRleHQgZm9yIHRoYXQgbWVzc2FnZSBjb2RlIGluIHRoZQotICAgKiBhcnJheS4gVXNlIHRoZSBuZXcgZXJyb3IgY29kZSBhcyB0aGUgaW5kZXggaW50byB0aGUgYXJyYXkuCi0gICAqLwotCi0gIC8vIEVycm9yIG1lc3NhZ2VzLi4uCi0KLSAgLyoqIFRoZSBsb29rdXAgdGFibGUgZm9yIGVycm9yIG1lc3NhZ2VzLiAgICovCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIE9iamVjdFtdW10gY29udGVudHMgPSB7Ci0KLSAgLyoqIEVycm9yIG1lc3NhZ2UgSUQgdGhhdCBoYXMgYSBudWxsIG1lc3NhZ2UsIGJ1dCB0YWtlcyBpbiBhIHNpbmdsZSBvYmplY3QuICAgICovCi0gICAgeyJFUjAwMDAiICwgInswfSIgfSwKLQotICAgIHsgRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCwKLSAgICAgICJGb25jdGlvbiBub24gcHJpc2UgZW4gY2hhcmdlLiJ9LAotCi0gICAgeyBFUl9DQU5OT1RfT1ZFUldSSVRFX0NBVVNFLAotICAgICAgIkltcG9zc2libGUgZGUgcmVtcGxhY2VyIGxhIGNhdXNlIn0sCi0KLSAgICB7IEVSX05PX0RFRkFVTFRfSU1QTCwKLSAgICAgICJBdWN1bmUgaW1wbFx1MDBFOW1lbnRhdGlvbiBwYXIgZFx1MDBFOWZhdXQgdHJvdXZcdTAwRTllICJ9LAotCi0gICAgeyBFUl9DSFVOS0VESU5UQVJSQVlfTk9UX1NVUFBPUlRFRCwKLSAgICAgICJDaHVua2VkSW50QXJyYXkoezB9KSBuJydlc3QgYWN0dWVsbGVtZW50IHBhcyBwcmlzIGVuIGNoYXJnZSJ9LAotCi0gICAgeyBFUl9PRkZTRVRfQklHR0VSX1RIQU5fU0xPVCwKLSAgICAgICJEXHUwMEU5Y2FsYWdlIHN1cFx1MDBFOXJpZXVyIFx1MDBFMCBsJ2VtcGxhY2VtZW50In0sCi0KLSAgICB7IEVSX0NPUk9VVElORV9OT1RfQVZBSUwsCi0gICAgICAiQ29yb3V0aW5lIG5vbiBkaXNwb25pYmxlLCBpZD17MH0ifSwKLQotICAgIHsgRVJfQ09ST1VUSU5FX0NPX0VYSVQsCi0gICAgICAiQ29yb3V0aW5lTWFuYWdlciBhIHJlXHUwMEU3dSBsYSBkZW1hbmRlIGNvX2V4aXQoKSJ9LAotCi0gICAgeyBFUl9DT0pPSU5ST1VUSU5FU0VUX0ZBSUxFRCwKLSAgICAgICJFY2hlYyBkZSBjb19qb2luQ29yb3V0aW5lU2V0KCkifSwKLQotICAgIHsgRVJfQ09ST1VUSU5FX1BBUkFNLAotICAgICAgIkVycmV1ciBkZSBwYXJhbVx1MDBFOHRyZSBkZSBjb3JvdXRpbmUgKHswfSkifSwKLQotICAgIHsgRVJfUEFSU0VSX0RPVEVSTUlOQVRFX0FOU1dFUlMsCi0gICAgICAiXG5JTkFUVEVORFUgOiByXHUwMEU5cG9uc2VzIGRvVGVybWluYXRlIGRlIGwnJ2FuYWx5c2V1ciAtIHswfSJ9LAotCi0gICAgeyBFUl9OT19QQVJTRV9DQUxMX1dISUxFX1BBUlNJTkcsCi0gICAgICAiaW1wb3NzaWJsZSBkJ2FwcGVsZXIgbCdhbmFseXNlIGxvcnNxdSdlbGxlIGVzdCBlbiBjb3VycyJ9LAotCi0gICAgeyBFUl9UWVBFRF9JVEVSQVRPUl9BWElTX05PVF9JTVBMRU1FTlRFRCwKLSAgICAgICJFcnJldXIgOiBpdFx1MDBFOXJhdGV1ciBzYWlzaSBwb3VyIGwnJ2F4ZSB7MH0gbm9uIGltcGxcdTAwRTltZW50XHUwMEU5In0sCi0KLSAgICB7IEVSX0lURVJBVE9SX0FYSVNfTk9UX0lNUExFTUVOVEVELAotICAgICAgIkVycmV1ciA6IGl0XHUwMEU5cmF0ZXVyIHBvdXIgbCcnYXhlIHswfSBub24gaW1wbFx1MDBFOW1lbnRcdTAwRTkgIn0sCi0KLSAgICB7IEVSX0lURVJBVE9SX0NMT05FX05PVF9TVVBQT1JURUQsCi0gICAgICAiQ2xvbmUgZCdpdFx1MDBFOXJhdGV1ciBub24gcHJpcyBlbiBjaGFyZ2UifSwKLQotICAgIHsgRVJfVU5LTk9XTl9BWElTX1RZUEUsCi0gICAgICAiVHlwZSBkZSBwYXJjb3VycyBkJydheGUgaW5jb25udSA6IHswfSJ9LAotCi0gICAgeyBFUl9BWElTX05PVF9TVVBQT1JURUQsCi0gICAgICAiUGFyY291cnMgZCcnYXhlIG5vbiBwcmlzIGVuIGNoYXJnZSA6IHswfSJ9LAotCi0gICAgeyBFUl9OT19EVE1JRFNfQVZBSUwsCi0gICAgICAiQXVjdW4gYXV0cmUgSUQgRFRNIG4nZXN0IGRpc3BvbmlibGUifSwKLQotICAgIHsgRVJfTk9UX1NVUFBPUlRFRCwKLSAgICAgICJOb24gcHJpcyBlbiBjaGFyZ2UgOiB7MH0ifSwKLQotICAgIHsgRVJfTk9ERV9OT05fTlVMTCwKLSAgICAgICJMZSBub2V1ZCBkb2l0IFx1MDBFQXRyZSBub24gTlVMTCBwb3VyIGdldERUTUhhbmRsZUZyb21Ob2RlIn0sCi0KLSAgICB7IEVSX0NPVUxEX05PVF9SRVNPTFZFX05PREUsCi0gICAgICAiSW1wb3NzaWJsZSBkZSByXHUwMEU5c291ZHJlIGxlIG5vZXVkIHN1ciB1biBkZXNjcmlwdGV1ciJ9LAotCi0gICAgeyBFUl9TVEFSVFBBUlNFX1dISUxFX1BBUlNJTkcsCi0gICAgICAgImltcG9zc2libGUgZCdhcHBlbGVyIHN0YXJ0UGFyc2UgbG9yc3F1ZSBsJ2FuYWx5c2UgZXN0IGVuIGNvdXJzIn0sCi0KLSAgICB7IEVSX1NUQVJUUEFSU0VfTkVFRFNfU0FYUEFSU0VSLAotICAgICAgICJzdGFydFBhcnNlIG5cdTAwRTljZXNzaXRlIHVuIFNBWFBhcnNlciBub24gTlVMTCJ9LAotCi0gICAgeyBFUl9DT1VMRF9OT1RfSU5JVF9QQVJTRVIsCi0gICAgICAgImltcG9zc2libGUgZCdpbml0aWFsaXNlciBsJ2FuYWx5c2V1ciBhdmVjIn0sCi0KLSAgICB7IEVSX0VYQ0VQVElPTl9DUkVBVElOR19QT09MLAotICAgICAgICJleGNlcHRpb24gbG9ycyBkZSBsYSBjclx1MDBFOWF0aW9uIGRlIGwnaW5zdGFuY2UgZHUgcG9vbCJ9LAotCi0gICAgeyBFUl9QQVRIX0NPTlRBSU5TX0lOVkFMSURfRVNDQVBFX1NFUVVFTkNFLAotICAgICAgICJMZSBjaGVtaW4gZCdhY2NcdTAwRThzIGNvbnRpZW50IHVuZSBzXHUwMEU5cXVlbmNlIGQnXHUwMEU5Y2hhcHBlbWVudCBub24gdmFsaWRlIn0sCi0KLSAgICB7IEVSX1NDSEVNRV9SRVFVSVJFRCwKLSAgICAgICAiTW9kXHUwMEU4bGUgb2JsaWdhdG9pcmUuIn0sCi0KLSAgICB7IEVSX05PX1NDSEVNRV9JTl9VUkksCi0gICAgICAgIk1vZFx1MDBFOGxlIGludHJvdXZhYmxlIGRhbnMgbCcnVVJJOiB7MH0ifSwKLQotICAgIHsgRVJfTk9fU0NIRU1FX0lOVVJJLAotICAgICAgICJNb2RcdTAwRThsZSBpbnRyb3V2YWJsZSBkYW5zIGwnVVJJIn0sCi0KLSAgICB7IEVSX1BBVEhfSU5WQUxJRF9DSEFSLAotICAgICAgICJMZSBjaGVtaW4gY29udGllbnQgdW4gY2FyYWN0XHUwMEU4cmUgbm9uIHZhbGlkZSA6IHswfSJ9LAotCi0gICAgeyBFUl9TQ0hFTUVfRlJPTV9OVUxMX1NUUklORywKLSAgICAgICAiSW1wb3NzaWJsZSBkZSBkXHUwMEU5ZmluaXIgbGUgbW9kXHUwMEU4bGUgXHUwMEUwIHBhcnRpciBkZSBsYSBjaGFcdTAwRUVuZSBOVUxMIn0sCi0KLSAgICB7IEVSX1NDSEVNRV9OT1RfQ09ORk9STUFOVCwKLSAgICAgICAiTGUgbW9kXHUwMEU4bGUgbidlc3QgcGFzIGNvbmZvcm1lLiJ9LAotCi0gICAgeyBFUl9IT1NUX0FERFJFU1NfTk9UX1dFTExGT1JNRUQsCi0gICAgICAgIkxlIGZvcm1hdCBkZSBsJ2FkcmVzc2UgZGUgbCdoXHUwMEY0dGUgbidlc3QgcGFzIGNvcnJlY3QifSwKLQotICAgIHsgRVJfUE9SVF9XSEVOX0hPU1RfTlVMTCwKLSAgICAgICAiSW1wb3NzaWJsZSBkZSBkXHUwMEU5ZmluaXIgbGUgcG9ydCBxdWFuZCBsJ2hcdTAwRjR0ZSBlc3QgTlVMTCJ9LAotCi0gICAgeyBFUl9JTlZBTElEX1BPUlQsCi0gICAgICAgIk51bVx1MDBFOXJvIGRlIHBvcnQgbm9uIHZhbGlkZSJ9LAotCi0gICAgeyBFUl9GUkFHX0ZPUl9HRU5FUklDX1VSSSwKLSAgICAgICAiTGUgZnJhZ21lbnQgbmUgcGV1dCBcdTAwRUF0cmUgZFx1MDBFOWZpbmkgcXVlIHBvdXIgdW4gVVJJIGdcdTAwRTluXHUwMEU5cmlxdWUifSwKLQotICAgIHsgRVJfRlJBR19XSEVOX1BBVEhfTlVMTCwKLSAgICAgICAiSW1wb3NzaWJsZSBkZSBkXHUwMEU5ZmluaXIgbGUgZnJhZ21lbnQgcXVhbmQgbGUgY2hlbWluIGQnYWNjXHUwMEU4cyBlc3QgTlVMTCJ9LAotCi0gICAgeyBFUl9GUkFHX0lOVkFMSURfQ0hBUiwKLSAgICAgICAiTGUgZnJhZ21lbnQgY29udGllbnQgdW4gY2FyYWN0XHUwMEU4cmUgbm9uIHZhbGlkZSJ9LAotCi0gICAgeyBFUl9QQVJTRVJfSU5fVVNFLAotICAgICAgIkwnYW5hbHlzZXVyIGVzdCBkXHUwMEU5alx1MDBFMCB1dGlsaXNcdTAwRTkifSwKLQotICAgIHsgRVJfQ0FOTk9UX0NIQU5HRV9XSElMRV9QQVJTSU5HLAotICAgICAgIkltcG9zc2libGUgZGUgbW9kaWZpZXIgezB9IHsxfSBwZW5kYW50IGwnJ2FuYWx5c2UifSwKLQotICAgIHsgRVJfU0VMRl9DQVVTQVRJT05fTk9UX1BFUk1JVFRFRCwKLSAgICAgICJDYXVzYWxpdFx1MDBFOSBjaXJjdWxhaXJlIG5vbiBhdXRvcmlzXHUwMEU5ZSJ9LAotCi0gICAgeyBFUl9OT19VU0VSSU5GT19JRl9OT19IT1NULAotICAgICAgIlVzZXJpbmZvIHBldXQgbmUgcGFzIFx1MDBFQXRyZSBzcFx1MDBFOWNpZmlcdTAwRTkgc2kgbCdoXHUwMEY0dGUgbmUgbCdlc3QgcGFzIn0sCi0KLSAgICB7IEVSX05PX1BPUlRfSUZfTk9fSE9TVCwKLSAgICAgICJMZSBwb3J0IHBldXQgbmUgcGFzIFx1MDBFQXRyZSBzcFx1MDBFOWNpZmlcdTAwRTkgc2kgbCdoXHUwMEY0dGUgbmUgbCdlc3QgcGFzIn0sCi0KLSAgICB7IEVSX05PX1FVRVJZX1NUUklOR19JTl9QQVRILAotICAgICAgIkxhIGNoYVx1MDBFRW5lIGRlIHJlcXVcdTAwRUF0ZSBuZSBkb2l0IHBhcyBmaWd1cmVyIGRhbnMgdW4gY2hlbWluIGV0IHVuZSBjaGFcdTAwRUVuZSBkZSByZXF1XHUwMEVBdGUifSwKLQotICAgIHsgRVJfTk9fRlJBR01FTlRfU1RSSU5HX0lOX1BBVEgsCi0gICAgICAiTGUgZnJhZ21lbnQgbmUgZG9pdCBwYXMgXHUwMEVBdHJlIGluZGlxdVx1MDBFOSBcdTAwRTAgbGEgZm9pcyBkYW5zIGxlIGNoZW1pbiBldCBkYW5zIGxlIGZyYWdtZW50In0sCi0KLSAgICB7IEVSX0NBTk5PVF9JTklUX1VSSV9FTVBUWV9QQVJNUywKLSAgICAgICJJbXBvc3NpYmxlIGQnaW5pdGlhbGlzZXIgbCdVUkkgYXZlYyBkZXMgcGFyYW1cdTAwRTh0cmVzIHZpZGVzIn0sCi0KLSAgICB7IEVSX01FVEhPRF9OT1RfU1VQUE9SVEVELAotICAgICAgIkxhIG1cdTAwRTl0aG9kZSBuJ2VzdCBwYXMgZW5jb3JlIHByaXNlIGVuIGNoYXJnZSAifSwKLQotICAgIHsgRVJfSU5DUlNBWFNSQ0ZJTFRFUl9OT1RfUkVTVEFSVEFCTEUsCi0gICAgICAiSW5jcmVtZW50YWxTQVhTb3VyY2VfRmlsdGVyIG5lIHBldXQgYWN0dWVsbGVtZW50IHBhcyBcdTAwRUF0cmUgcmVkXHUwMEU5bWFyclx1MDBFOSJ9LAotCi0gICAgeyBFUl9YTUxSRFJfTk9UX0JFRk9SRV9TVEFSVFBBUlNFLAotICAgICAgIlhNTFJlYWRlciBwYXMgYXZhbnQgbGEgZGVtYW5kZSBzdGFydFBhcnNlIn0sCi0KLSAgICB7IEVSX0FYSVNfVFJBVkVSU0VSX05PVF9TVVBQT1JURUQsCi0gICAgICAiUGFyY291cnMgZCcnYXhlIG5vbiBwcmlzIGVuIGNoYXJnZSA6IHswfSJ9LAotCi0gICAgeyBFUl9FUlJPUkhBTkRMRVJfQ1JFQVRFRF9XSVRIX05VTExfUFJJTlRXUklURVIsCi0gICAgICAiTGlzdGluZ0Vycm9ySGFuZGxlciBjclx1MDBFOVx1MDBFOSBhdmVjIFByaW50V3JpdGVyIE5VTEwuIn0sCi0KLSAgICB7IEVSX1NZU1RFTUlEX1VOS05PV04sCi0gICAgICAiSUQgc3lzdFx1MDBFOG1lIGluY29ubnUifSwKLQotICAgIHsgRVJfTE9DQVRJT05fVU5LTk9XTiwKLSAgICAgICJFbXBsYWNlbWVudCBkZSBsJ2VycmV1ciBpbmNvbm51In0sCi0KLSAgICB7IEVSX1BSRUZJWF9NVVNUX1JFU09MVkUsCi0gICAgICAiTGUgcHJcdTAwRTlmaXhlIGRvaXQgXHUwMEVBdHJlIHJcdTAwRTlzb2x1IGVuIGVzcGFjZSBkZSBub21zIDogezB9In0sCi0KLSAgICB7IEVSX0NSRUFURURPQ1VNRU5UX05PVF9TVVBQT1JURUQsCi0gICAgICAiY3JlYXRlRG9jdW1lbnQoKSBub24gcHJpcyBlbiBjaGFyZ2UgZGFucyBYUGF0aENvbnRleHQuIn0sCi0KLSAgICB7IEVSX0NISUxEX0hBU19OT19PV05FUl9ET0NVTUVOVCwKLSAgICAgICJMJ2VuZmFudCBkZSBsJ2F0dHJpYnV0IG5lIHBvc3NcdTAwRThkZSBwYXMgZGUgZG9jdW1lbnQgcHJvcHJpXHUwMEU5dGFpcmUuIn0sCi0KLSAgICB7IEVSX0NISUxEX0hBU19OT19PV05FUl9ET0NVTUVOVF9FTEVNRU5ULAotICAgICAgIkwnZW5mYW50IGRlIGwnYXR0cmlidXQgbmUgcG9zc1x1MDBFOGRlIHBhcyBkJ1x1MDBFOWxcdTAwRTltZW50IGRlIGRvY3VtZW50IHByb3ByaVx1MDBFOXRhaXJlLiJ9LAotCi0gICAgeyBFUl9DQU5UX09VVFBVVF9URVhUX0JFRk9SRV9ET0MsCi0gICAgICAiQXZlcnRpc3NlbWVudCA6IGltcG9zc2libGUgZGUgZ1x1MDBFOW5cdTAwRTlyZXIgdW5lIHNvcnRpZSBkdSB0ZXh0ZSBhdmFudCBsJ1x1MDBFOWxcdTAwRTltZW50IGRlIGRvY3VtZW50LiBOb24gcHJpcyBlbiBjb21wdGUuLi4ifSwKLQotICAgIHsgRVJfQ0FOVF9IQVZFX01PUkVfVEhBTl9PTkVfUk9PVCwKLSAgICAgICJJbXBvc3NpYmxlIGQnYXZvaXIgcGx1cyBkJ3VuZSByYWNpbmUgc3VyIHVuIERPTS4ifSwKLQotICAgIHsgRVJfQVJHX0xPQ0FMTkFNRV9OVUxMLAotICAgICAgICJMJ2FyZ3VtZW50IFwibG9jYWxOYW1lXCIgZXN0IE5VTEwifSwKLQotICAgIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBIFFOQU1FIGhhcyB0aGUgc3ludGFjdGljIGZvcm0gW05DTmFtZTpdTkNOYW1lCi0gICAgLy8gVGhlIGxvY2FsbmFtZSBpcyB0aGUgcG9ydGlvbiBhZnRlciB0aGUgb3B0aW9uYWwgY29sb247IHRoZSBtZXNzYWdlIGluZGljYXRlcwotICAgIC8vIHRoYXQgdGhlcmUgaXMgYSBwcm9ibGVtIHdpdGggdGhhdCBwYXJ0IG9mIHRoZSBRTkFNRS4KLSAgICB7IEVSX0FSR19MT0NBTE5BTUVfSU5WQUxJRCwKLSAgICAgICAiTGUgbm9tIGxvY2FsIGR1IFFOYW1lIGRvaXQgXHUwMEVBdHJlIHVuIE5DTmFtZSB2YWxpZGUifSwKLQotICAgIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBIFFOQU1FIGhhcyB0aGUgc3ludGFjdGljIGZvcm0gW05DTmFtZTpdTkNOYW1lCi0gICAgLy8gVGhlIHByZWZpeCBpcyB0aGUgcG9ydGlvbiBiZWZvcmUgdGhlIG9wdGlvbmFsIGNvbG9uOyB0aGUgbWVzc2FnZSBpbmRpY2F0ZXMKLSAgICAvLyB0aGF0IHRoZXJlIGlzIGEgcHJvYmxlbSB3aXRoIHRoYXQgcGFydCBvZiB0aGUgUU5BTUUuCi0gICAgeyBFUl9BUkdfUFJFRklYX0lOVkFMSUQsCi0gICAgICAgIkxlIHByXHUwMEU5Zml4ZSBkdSBRTmFtZSBkb2l0IFx1MDBFQXRyZSB1biBOQ05hbWUgdmFsaWRlIn0sCi0KLSAgICB7IEVSX05BTUVfQ0FOVF9TVEFSVF9XSVRIX0NPTE9OLAotICAgICAgIkxlIG5vbSBuZSBwZXV0IHBhcyBjb21tZW5jZXIgcGFyIGRldXgtcG9pbnRzIn0sCi0KLSAgICB7ICJCQURfQ09ERSIsICJMZSBwYXJhbVx1MDBFOHRyZSBjcmVhdGVNZXNzYWdlIFx1MDBFOXRhaXQgaG9ycyBsaW1pdGVzIn0sCi0gICAgeyAiRk9STUFUX0ZBSUxFRCIsICJFeGNlcHRpb24gZ1x1MDBFOW5cdTAwRTlyXHUwMEU5ZSBwZW5kYW50IGwnYXBwZWwgbWVzc2FnZUZvcm1hdCJ9LAotICAgIHsgImxpbmUiLCAiTGlnbmUgblx1MDBCMCJ9LAotICAgIHsgImNvbHVtbiIsIkNvbG9ubmUgblx1MDBCMCJ9LAotCi0gICAge0VSX1NFUklBTElaRVJfTk9UX0NPTlRFTlRIQU5ETEVSLAotICAgICAgIkxhIGNsYXNzZSBkZSBzZXJpYWxpemVyICcnezB9JycgbicnaW1wbFx1MDBFOW1lbnRlIHBhcyBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlci4ifSwKLQotICAgIHtFUl9SRVNPVVJDRV9DT1VMRF9OT1RfRklORCwKLSAgICAgICJMYSByZXNzb3VyY2UgWyB7MH0gXSBlc3QgaW50cm91dmFibGUuXG4gezF9IiB9LAotCi0gICAge0VSX1JFU09VUkNFX0NPVUxEX05PVF9MT0FELAotICAgICAgIkxhIHJlc3NvdXJjZSBbIHswfSBdIG4nJ2EgcGFzIHB1IGNoYXJnZXIgOiB7MX0gXG4gezJ9IFx0IHszfSIgfSwKLQotICAgIHtFUl9CVUZGRVJfU0laRV9MRVNTVEhBTl9aRVJPLAotICAgICAgIlRhaWxsZSBkdSB0YW1wb24gPD0wIiB9LAotCi0gICAge0VSX0lOVkFMSURfVVRGMTZfU1VSUk9HQVRFLAotICAgICAgIlN1YnN0aXR1dCBVVEYtMTYgbm9uIHZhbGlkZSBkXHUwMEU5dGVjdFx1MDBFOSA6IHswfSA/IiB9LAotCi0gICAge0VSX09JRVJST1IsCi0gICAgICAiRXJyZXVyIGQnRS1TIiB9LAotCi0gICAge0VSX0lMTEVHQUxfQVRUUklCVVRFX1BPU0lUSU9OLAotICAgICAgIkltcG9zc2libGUgZCcnYWpvdXRlciBsJydhdHRyaWJ1dCB7MH0gYXByXHUwMEU4cyBkZXMgbm9ldWRzIGVuZmFudCBvdSBhdmFudCBsYSBwcm9kdWN0aW9uIGQnJ3VuIFx1MDBFOWxcdTAwRTltZW50LiBMJydhdHRyaWJ1dCBlc3QgaWdub3JcdTAwRTkuIn0sCi0KLSAgICAgIC8qCi0gICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN0eWxlc2hlZXQgY29udGFpbmVkIGEgcmVmZXJlbmNlIHRvIGEKLSAgICAgICAqIG5hbWVzcGFjZSBwcmVmaXggdGhhdCB3YXMgdW5kZWZpbmVkLiAgVGhlIHZhbHVlIG9mIHRoZSBzdWJzdGl0dXRpb24KLSAgICAgICAqIHRleHQgaXMgdGhlIG5hbWUgb2YgdGhlIHByZWZpeC4KLSAgICAgICAqLwotICAgIHtFUl9OQU1FU1BBQ0VfUFJFRklYLAotICAgICAgIkwnJ2VzcGFjZSBkZSBub21zIGR1IHByXHUwMEU5Zml4ZSAnJ3swfScnIG4nJ2EgcGFzIFx1MDBFOXRcdTAwRTkgZFx1MDBFOWNsYXJcdTAwRTkuIiB9LAotICAgICAgLyoKLSAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgcmVwb3J0ZWQgaWYgdGhlIHN0eWxlc2hlZXQKLSAgICAgICAqIGJlaW5nIHByb2Nlc3NlZCBhdHRlbXB0ZWQgdG8gY29uc3RydWN0IGFuIFhNTCBkb2N1bWVudCB3aXRoIGFuCi0gICAgICAgKiBhdHRyaWJ1dGUgaW4gYSBwbGFjZSBvdGhlciB0aGFuIG9uIGFuIGVsZW1lbnQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQKLSAgICAgICAqIHNwZWNpZmllcyB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlLgotICAgICAgICovCi0gICAge0VSX1NUUkFZX0FUVFJJQlVURSwKLSAgICAgICJBdHRyaWJ1dCAnJ3swfScnIFx1MDBFMCBsJydleHRcdTAwRTlyaWV1ciBkZSBsJydcdTAwRTlsXHUwMEU5bWVudC4iIH0sCi0KLSAgICAgIC8qCi0gICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQXMgd2l0aCB0aGUgcHJlY2VkaW5nIG1lc3NhZ2UsIGEgbmFtZXNwYWNlCi0gICAgICAgKiBkZWNsYXJhdGlvbiBoYXMgdGhlIGZvcm0gb2YgYW4gYXR0cmlidXRlIGFuZCBpcyBvbmx5IHBlcm1pdHRlZCB0bwotICAgICAgICogYXBwZWFyIG9uIGFuIGVsZW1lbnQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgezB9IGlzIHRoZSBuYW1lc3BhY2UKLSAgICAgICAqIHByZWZpeCBhbmQgezF9IGlzIHRoZSBVUkkgdGhhdCB3YXMgYmVpbmcgdXNlZCBpbiB0aGUgZXJyb25lb3VzCi0gICAgICAgKiBuYW1lc3BhY2UgZGVjbGFyYXRpb24uCi0gICAgICAgKi8KLSAgICB7RVJfU1RSQVlfTkFNRVNQQUNFLAotICAgICAgIkxhIGRcdTAwRTljbGFyYXRpb24gZCcnZXNwYWNlIGRlIG5vbXMgJyd7MH0nJz0nJ3sxfScnIGVzdCBcdTAwRTAgbCcnZXh0XHUwMEU5cmlldXIgZGUgbCcnXHUwMEU5bFx1MDBFOW1lbnQuIiB9LAotCi0gICAge0VSX0NPVUxEX05PVF9MT0FEX1JFU09VUkNFLAotICAgICAgIkltcG9zc2libGUgZGUgY2hhcmdlciAnJ3swfScnICh2XHUwMEU5cmlmaWVyIENMQVNTUEFUSCksIGxlcyB2YWxldXJzIHBhciBkXHUwMEU5ZmF1dCBzb250IGRvbmMgZW1wbG95XHUwMEU5ZXMifSwKLQotICAgIHsgRVJfSUxMRUdBTF9DSEFSQUNURVIsCi0gICAgICAgIlRlbnRhdGl2ZSBkZSBzb3J0aWUgZCcndW4gY2FyYWN0XHUwMEU4cmUgYXZlYyB1bmUgdmFsZXVyIGVudGlcdTAwRThyZSB7MH0sIG5vbiByZXByXHUwMEU5c2VudFx1MDBFOSBkYW5zIGwnJ2VuY29kYWdlIGRlIHNvcnRpZSBzcFx1MDBFOWNpZmlcdTAwRTkgcG91ciB7MX0uIn0sCi0KLSAgICB7RVJfQ09VTERfTk9UX0xPQURfTUVUSE9EX1BST1BFUlRZLAotICAgICAgIkltcG9zc2libGUgZGUgY2hhcmdlciBsZSBmaWNoaWVyIGRlIHByb3ByaVx1MDBFOXRcdTAwRTlzICcnezB9JycgcG91ciBsYSBtXHUwMEU5dGhvZGUgZGUgc29ydGllICcnezF9JycgKHZcdTAwRTlyaWZpZXIgQ0xBU1NQQVRIKSIgfQotCi0KLSAgfTsKLQotICAvKioKLSAgICogR2V0IHRoZSBhc3NvY2lhdGlvbiBsaXN0LgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBhc3NvY2lhdGlvbiBsaXN0LgotICAgKi8KLQotICAgIHByb3RlY3RlZCBPYmplY3RbXVtdIGdldENvbnRlbnRzKCkgewotICAgICAgICByZXR1cm4gY29udGVudHM7Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9yZXMvWE1MRXJyb3JSZXNvdXJjZXNfaXQuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3Jlcy9YTUxFcnJvclJlc291cmNlc19pdC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhODZiMjA2Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3Jlcy9YTUxFcnJvclJlc291cmNlc19pdC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDUwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXM7Ci0KLQotaW1wb3J0IGphdmEudXRpbC5MaXN0UmVzb3VyY2VCdW5kbGU7Ci0KLS8qKgotICogU2V0IHVwIGVycm9yIG1lc3NhZ2VzLgotICogV2UgYnVpbGQgYSB0d28gZGltZW5zaW9uYWwgYXJyYXkgb2YgbWVzc2FnZSBrZXlzIGFuZAotICogbWVzc2FnZSBzdHJpbmdzLiBJbiBvcmRlciB0byBhZGQgYSBuZXcgbWVzc2FnZSBoZXJlLAotICogeW91IG5lZWQgdG8gZmlyc3QgYWRkIGEgU3RyaW5nIGNvbnN0YW50LiBBbmQgeW91IG5lZWQKLSAqIHRvIGVudGVyIGtleSwgdmFsdWUgcGFpciBhcyBwYXJ0IG9mIHRoZSBjb250ZW50cwotICogYXJyYXkuIFlvdSBhbHNvIG5lZWQgdG8gdXBkYXRlIE1BWF9DT0RFIGZvciBlcnJvciBzdHJpbmdzCi0gKiBhbmQgTUFYX1dBUk5JTkcgZm9yIHdhcm5pbmdzICggTmVlZGVkIGZvciBvbmx5IGluZm9ybWF0aW9uCi0gKiBwdXJwb3NlICkKLSAqLwotcHVibGljIGNsYXNzIFhNTEVycm9yUmVzb3VyY2VzX2l0IGV4dGVuZHMgTGlzdFJlc291cmNlQnVuZGxlCi17Ci0KLS8qCi0gKiBUaGlzIGZpbGUgY29udGFpbnMgZXJyb3IgYW5kIHdhcm5pbmcgbWVzc2FnZXMgcmVsYXRlZCB0byBYYWxhbiBFcnJvcgotICogSGFuZGxpbmcuCi0gKgotICogIEdlbmVyYWwgbm90ZXMgdG8gdHJhbnNsYXRvcnM6Ci0gKgotICogIDEpIFhhbGFuIChvciBtb3JlIHByb3Blcmx5LCBYYWxhbi1pbnRlcnByZXRpdmUpIGFuZCBYU0xUQyBhcmUgbmFtZXMgb2YKLSAqICAgICBjb21wb25lbnRzLgotICogICAgIFhTTFQgaXMgYW4gYWNyb255bSBmb3IgIlhNTCBTdHlsZXNoZWV0IExhbmd1YWdlOiBUcmFuc2Zvcm1hdGlvbnMiLgotICogICAgIFhTTFRDIGlzIGFuIGFjcm9ueW0gZm9yIFhTTFQgQ29tcGlsZXIuCi0gKgotICogIDIpIEEgc3R5bGVzaGVldCBpcyBhIGRlc2NyaXB0aW9uIG9mIGhvdyB0byB0cmFuc2Zvcm0gYW4gaW5wdXQgWE1MIGRvY3VtZW50Ci0gKiAgICAgaW50byBhIHJlc3VsdGFudCBYTUwgZG9jdW1lbnQgKG9yIEhUTUwgZG9jdW1lbnQgb3IgdGV4dCkuICBUaGUKLSAqICAgICBzdHlsZXNoZWV0IGl0c2VsZiBpcyBkZXNjcmliZWQgaW4gdGhlIGZvcm0gb2YgYW4gWE1MIGRvY3VtZW50LgotICoKLSAqICAzKSBBIHRlbXBsYXRlIGlzIGEgY29tcG9uZW50IG9mIGEgc3R5bGVzaGVldCB0aGF0IGlzIHVzZWQgdG8gbWF0Y2ggYQotICogICAgIHBhcnRpY3VsYXIgcG9ydGlvbiBvZiBhbiBpbnB1dCBkb2N1bWVudCBhbmQgc3BlY2lmaWVzIHRoZSBmb3JtIG9mIHRoZQotICogICAgIGNvcnJlc3BvbmRpbmcgcG9ydGlvbiBvZiB0aGUgb3V0cHV0IGRvY3VtZW50LgotICoKLSAqICA0KSBBbiBlbGVtZW50IGlzIGEgbWFyay11cCB0YWcgaW4gYW4gWE1MIGRvY3VtZW50OyBhbiBhdHRyaWJ1dGUgaXMgYQotICogICAgIG1vZGlmaWVyIG9uIHRoZSB0YWcuICBGb3IgZXhhbXBsZSwgaW4gPGVsZW0gYXR0cj0ndmFsJyBhdHRyMj0ndmFsMic+Ci0gKiAgICAgImVsZW0iIGlzIGFuIGVsZW1lbnQgbmFtZSwgImF0dHIiIGFuZCAiYXR0cjIiIGFyZSBhdHRyaWJ1dGUgbmFtZXMgd2l0aAotICogICAgIHRoZSB2YWx1ZXMgInZhbCIgYW5kICJ2YWwyIiwgcmVzcGVjdGl2ZWx5LgotICoKLSAqICA1KSBBIG5hbWVzcGFjZSBkZWNsYXJhdGlvbiBpcyBhIHNwZWNpYWwgYXR0cmlidXRlIHRoYXQgaXMgdXNlZCB0byBhc3NvY2lhdGUKLSAqICAgICBhIHByZWZpeCB3aXRoIGEgVVJJICh0aGUgbmFtZXNwYWNlKS4gIFRoZSBtZWFuaW5ncyBvZiBlbGVtZW50IG5hbWVzIGFuZAotICogICAgIGF0dHJpYnV0ZSBuYW1lcyB0aGF0IHVzZSB0aGF0IHByZWZpeCBhcmUgZGVmaW5lZCB3aXRoIHJlc3BlY3QgdG8gdGhhdAotICogICAgIG5hbWVzcGFjZS4KLSAqCi0gKiAgNikgIlRyYW5zbGV0IiBpcyBhbiBpbnZlbnRlZCB0ZXJtIHRoYXQgZGVzY3JpYmVzIHRoZSBjbGFzcyBmaWxlIHRoYXQKLSAqICAgICByZXN1bHRzIGZyb20gY29tcGlsaW5nIGFuIFhNTCBzdHlsZXNoZWV0IGludG8gYSBKYXZhIGNsYXNzLgotICoKLSAqICA3KSBYUGF0aCBpcyBhIHNwZWNpZmljYXRpb24gdGhhdCBkZXNjcmliZXMgYSBub3RhdGlvbiBmb3IgaWRlbnRpZnlpbmcKLSAqICAgICBub2RlcyBpbiBhIHRyZWUtc3RydWN0dXJlZCByZXByZXNlbnRhdGlvbiBvZiBhbiBYTUwgZG9jdW1lbnQuICBBbgotICogICAgIGluc3RhbmNlIG9mIHRoYXQgbm90YXRpb24gaXMgcmVmZXJyZWQgdG8gYXMgYW4gWFBhdGggZXhwcmVzc2lvbi4KLSAqCi0gKi8KLQotICAvKiogTWF4aW11bSBlcnJvciBtZXNzYWdlcywgdGhpcyBpcyBuZWVkZWQgdG8ga2VlcCB0cmFjayBvZiB0aGUgbnVtYmVyIG9mIG1lc3NhZ2VzLiAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVhfQ09ERSA9IDYxOwotCi0gIC8qKiBNYXhpbXVtIHdhcm5pbmdzLCB0aGlzIGlzIG5lZWRlZCB0byBrZWVwIHRyYWNrIG9mIHRoZSBudW1iZXIgb2Ygd2FybmluZ3MuICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BWF9XQVJOSU5HID0gMDsKLQotICAvKiogTWF4aW11bSBtaXNjIHN0cmluZ3MuICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFYX09USEVSUyA9IDQ7Ci0KLSAgLyoqIE1heGltdW0gdG90YWwgd2FybmluZ3MgYW5kIGVycm9yIG1lc3NhZ2VzLiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVhfTUVTU0FHRVMgPSBNQVhfQ09ERSArIE1BWF9XQVJOSU5HICsgMTsKLQotCi0gIC8qCi0gICAqIE1lc3NhZ2Uga2V5cwotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCA9ICJFUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX09WRVJXUklURV9DQVVTRSA9ICJFUl9DQU5OT1RfT1ZFUldSSVRFX0NBVVNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fREVGQVVMVF9JTVBMID0gIkVSX05PX0RFRkFVTFRfSU1QTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NIVU5LRURJTlRBUlJBWV9OT1RfU1VQUE9SVEVEID0gIkVSX0NIVU5LRURJTlRBUlJBWV9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfT0ZGU0VUX0JJR0dFUl9USEFOX1NMT1QgPSAiRVJfT0ZGU0VUX0JJR0dFUl9USEFOX1NMT1QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1JPVVRJTkVfTk9UX0FWQUlMID0gIkVSX0NPUk9VVElORV9OT1RfQVZBSUwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1JPVVRJTkVfQ09fRVhJVCA9ICJFUl9DT1JPVVRJTkVfQ09fRVhJVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPSk9JTlJPVVRJTkVTRVRfRkFJTEVEID0gIkVSX0NPSk9JTlJPVVRJTkVTRVRfRkFJTEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09ST1VUSU5FX1BBUkFNID0gIkVSX0NPUk9VVElORV9QQVJBTSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BBUlNFUl9ET1RFUk1JTkFURV9BTlNXRVJTID0gIkVSX1BBUlNFUl9ET1RFUk1JTkFURV9BTlNXRVJTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fUEFSU0VfQ0FMTF9XSElMRV9QQVJTSU5HID0gIkVSX05PX1BBUlNFX0NBTExfV0hJTEVfUEFSU0lORyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1RZUEVEX0lURVJBVE9SX0FYSVNfTk9UX0lNUExFTUVOVEVEID0gIkVSX1RZUEVEX0lURVJBVE9SX0FYSVNfTk9UX0lNUExFTUVOVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSVRFUkFUT1JfQVhJU19OT1RfSU1QTEVNRU5URUQgPSAiRVJfSVRFUkFUT1JfQVhJU19OT1RfSU1QTEVNRU5URUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JVEVSQVRPUl9DTE9ORV9OT1RfU1VQUE9SVEVEID0gIkVSX0lURVJBVE9SX0NMT05FX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTktOT1dOX0FYSVNfVFlQRSA9ICJFUl9VTktOT1dOX0FYSVNfVFlQRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FYSVNfTk9UX1NVUFBPUlRFRCA9ICJFUl9BWElTX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19EVE1JRFNfQVZBSUwgPSAiRVJfTk9fRFRNSURTX0FWQUlMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9UX1NVUFBPUlRFRCA9ICJFUl9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9ERV9OT05fTlVMTCA9ICJFUl9OT0RFX05PTl9OVUxMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTERfTk9UX1JFU09MVkVfTk9ERSA9ICJFUl9DT1VMRF9OT1RfUkVTT0xWRV9OT0RFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU1RBUlRQQVJTRV9XSElMRV9QQVJTSU5HID0gIkVSX1NUQVJUUEFSU0VfV0hJTEVfUEFSU0lORyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NUQVJUUEFSU0VfTkVFRFNfU0FYUEFSU0VSID0gIkVSX1NUQVJUUEFSU0VfTkVFRFNfU0FYUEFSU0VSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTERfTk9UX0lOSVRfUEFSU0VSID0gIkVSX0NPVUxEX05PVF9JTklUX1BBUlNFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYQ0VQVElPTl9DUkVBVElOR19QT09MID0gIkVSX0VYQ0VQVElPTl9DUkVBVElOR19QT09MIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUEFUSF9DT05UQUlOU19JTlZBTElEX0VTQ0FQRV9TRVFVRU5DRSA9ICJFUl9QQVRIX0NPTlRBSU5TX0lOVkFMSURfRVNDQVBFX1NFUVVFTkNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU0NIRU1FX1JFUVVJUkVEID0gIkVSX1NDSEVNRV9SRVFVSVJFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1NDSEVNRV9JTl9VUkkgPSAiRVJfTk9fU0NIRU1FX0lOX1VSSSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1NDSEVNRV9JTlVSSSA9ICJFUl9OT19TQ0hFTUVfSU5VUkkiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QQVRIX0lOVkFMSURfQ0hBUiA9ICJFUl9QQVRIX0lOVkFMSURfQ0hBUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NDSEVNRV9GUk9NX05VTExfU1RSSU5HID0gIkVSX1NDSEVNRV9GUk9NX05VTExfU1RSSU5HIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU0NIRU1FX05PVF9DT05GT1JNQU5UID0gIkVSX1NDSEVNRV9OT1RfQ09ORk9STUFOVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0hPU1RfQUREUkVTU19OT1RfV0VMTEZPUk1FRCA9ICJFUl9IT1NUX0FERFJFU1NfTk9UX1dFTExGT1JNRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QT1JUX1dIRU5fSE9TVF9OVUxMID0gIkVSX1BPUlRfV0hFTl9IT1NUX05VTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX1BPUlQgPSAiRVJfSU5WQUxJRF9QT1JUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRlJBR19GT1JfR0VORVJJQ19VUkkgPSJFUl9GUkFHX0ZPUl9HRU5FUklDX1VSSSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZSQUdfV0hFTl9QQVRIX05VTEwgPSAiRVJfRlJBR19XSEVOX1BBVEhfTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZSQUdfSU5WQUxJRF9DSEFSID0gIkVSX0ZSQUdfSU5WQUxJRF9DSEFSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUEFSU0VSX0lOX1VTRSA9ICJFUl9QQVJTRVJfSU5fVVNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX0NIQU5HRV9XSElMRV9QQVJTSU5HID0gIkVSX0NBTk5PVF9DSEFOR0VfV0hJTEVfUEFSU0lORyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NFTEZfQ0FVU0FUSU9OX05PVF9QRVJNSVRURUQgPSAiRVJfU0VMRl9DQVVTQVRJT05fTk9UX1BFUk1JVFRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1VTRVJJTkZPX0lGX05PX0hPU1QgPSAiRVJfTk9fVVNFUklORk9fSUZfTk9fSE9TVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1BPUlRfSUZfTk9fSE9TVCA9ICJFUl9OT19QT1JUX0lGX05PX0hPU1QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19RVUVSWV9TVFJJTkdfSU5fUEFUSCA9ICJFUl9OT19RVUVSWV9TVFJJTkdfSU5fUEFUSCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX0ZSQUdNRU5UX1NUUklOR19JTl9QQVRIID0gIkVSX05PX0ZSQUdNRU5UX1NUUklOR19JTl9QQVRIIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX0lOSVRfVVJJX0VNUFRZX1BBUk1TID0gIkVSX0NBTk5PVF9JTklUX1VSSV9FTVBUWV9QQVJNUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01FVEhPRF9OT1RfU1VQUE9SVEVEID0iRVJfTUVUSE9EX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTkNSU0FYU1JDRklMVEVSX05PVF9SRVNUQVJUQUJMRSA9ICJFUl9JTkNSU0FYU1JDRklMVEVSX05PVF9SRVNUQVJUQUJMRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hNTFJEUl9OT1RfQkVGT1JFX1NUQVJUUEFSU0UgPSAiRVJfWE1MUkRSX05PVF9CRUZPUkVfU1RBUlRQQVJTRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FYSVNfVFJBVkVSU0VSX05PVF9TVVBQT1JURUQgPSAiRVJfQVhJU19UUkFWRVJTRVJfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VSUk9SSEFORExFUl9DUkVBVEVEX1dJVEhfTlVMTF9QUklOVFdSSVRFUiA9ICJFUl9FUlJPUkhBTkRMRVJfQ1JFQVRFRF9XSVRIX05VTExfUFJJTlRXUklURVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TWVNURU1JRF9VTktOT1dOID0gIkVSX1NZU1RFTUlEX1VOS05PV04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9MT0NBVElPTl9VTktOT1dOID0gIkVSX0xPQ0FUSU9OX1VOS05PV04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUkVGSVhfTVVTVF9SRVNPTFZFID0gIkVSX1BSRUZJWF9NVVNUX1JFU09MVkUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DUkVBVEVET0NVTUVOVF9OT1RfU1VQUE9SVEVEID0gIkVSX0NSRUFURURPQ1VNRU5UX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DSElMRF9IQVNfTk9fT1dORVJfRE9DVU1FTlQgPSAiRVJfQ0hJTERfSEFTX05PX09XTkVSX0RPQ1VNRU5UIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0hJTERfSEFTX05PX09XTkVSX0RPQ1VNRU5UX0VMRU1FTlQgPSAiRVJfQ0hJTERfSEFTX05PX09XTkVSX0RPQ1VNRU5UX0VMRU1FTlQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX09VVFBVVF9URVhUX0JFRk9SRV9ET0MgPSAiRVJfQ0FOVF9PVVRQVVRfVEVYVF9CRUZPUkVfRE9DIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9IQVZFX01PUkVfVEhBTl9PTkVfUk9PVCA9ICJFUl9DQU5UX0hBVkVfTU9SRV9USEFOX09ORV9ST09UIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQVJHX0xPQ0FMTkFNRV9OVUxMID0gIkVSX0FSR19MT0NBTE5BTUVfTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FSR19MT0NBTE5BTUVfSU5WQUxJRCA9ICJFUl9BUkdfTE9DQUxOQU1FX0lOVkFMSUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9BUkdfUFJFRklYX0lOVkFMSUQgPSAiRVJfQVJHX1BSRUZJWF9JTlZBTElEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTkFNRV9DQU5UX1NUQVJUX1dJVEhfQ09MT04gPSAiRVJfTkFNRV9DQU5UX1NUQVJUX1dJVEhfQ09MT04iOwotCi0gIC8vIE1lc3NhZ2Uga2V5cyB1c2VkIGJ5IHRoZSBzZXJpYWxpemVyCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1JFU09VUkNFX0NPVUxEX05PVF9GSU5EID0gIkVSX1JFU09VUkNFX0NPVUxEX05PVF9GSU5EIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUkVTT1VSQ0VfQ09VTERfTk9UX0xPQUQgPSAiRVJfUkVTT1VSQ0VfQ09VTERfTk9UX0xPQUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9CVUZGRVJfU0laRV9MRVNTVEhBTl9aRVJPID0gIkVSX0JVRkZFUl9TSVpFX0xFU1NUSEFOX1pFUk8iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX1VURjE2X1NVUlJPR0FURSA9ICJFUl9JTlZBTElEX1VURjE2X1NVUlJPR0FURSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX09JRVJST1IgPSAiRVJfT0lFUlJPUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05BTUVTUEFDRV9QUkVGSVggPSAiRVJfTkFNRVNQQUNFX1BSRUZJWCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NUUkFZX0FUVFJJQlVURSA9ICJFUl9TVFJBWV9BVFRJUkJVVEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TVFJBWV9OQU1FU1BBQ0UgPSAiRVJfU1RSQVlfTkFNRVNQQUNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTERfTk9UX0xPQURfUkVTT1VSQ0UgPSAiRVJfQ09VTERfTk9UX0xPQURfUkVTT1VSQ0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRF9OT1RfTE9BRF9NRVRIT0RfUFJPUEVSVFkgPSAiRVJfQ09VTERfTk9UX0xPQURfTUVUSE9EX1BST1BFUlRZIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU0VSSUFMSVpFUl9OT1RfQ09OVEVOVEhBTkRMRVIgPSAiRVJfU0VSSUFMSVpFUl9OT1RfQ09OVEVOVEhBTkRMRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTExFR0FMX0FUVFJJQlVURV9QT1NJVElPTiA9ICJFUl9JTExFR0FMX0FUVFJJQlVURV9QT1NJVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lMTEVHQUxfQ0hBUkFDVEVSID0gIkVSX0lMTEVHQUxfQ0hBUkFDVEVSIjsKLQotICAvKgotICAgKiBOb3cgZmlsbCBpbiB0aGUgbWVzc2FnZSB0ZXh0LgotICAgKiBUaGVuIGZpbGwgaW4gdGhlIG1lc3NhZ2UgdGV4dCBmb3IgdGhhdCBtZXNzYWdlIGNvZGUgaW4gdGhlCi0gICAqIGFycmF5LiBVc2UgdGhlIG5ldyBlcnJvciBjb2RlIGFzIHRoZSBpbmRleCBpbnRvIHRoZSBhcnJheS4KLSAgICovCi0KLSAgLy8gRXJyb3IgbWVzc2FnZXMuLi4KLQotICAvKiogVGhlIGxvb2t1cCB0YWJsZSBmb3IgZXJyb3IgbWVzc2FnZXMuICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgT2JqZWN0W11bXSBjb250ZW50cyA9IHsKLQotICAvKiogRXJyb3IgbWVzc2FnZSBJRCB0aGF0IGhhcyBhIG51bGwgbWVzc2FnZSwgYnV0IHRha2VzIGluIGEgc2luZ2xlIG9iamVjdC4gICAgKi8KLSAgICB7IkVSMDAwMCIgLCAiezB9IiB9LAotCi0gICAgeyBFUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVELAotICAgICAgIkZ1bnppb25lIG5vbiBzdXBwb3J0YXRhLiJ9LAotCi0gICAgeyBFUl9DQU5OT1RfT1ZFUldSSVRFX0NBVVNFLAotICAgICAgIkltcG9zc2liaWxlIHNvdnJhc2NyaXZlcmUgbGEgY2F1c2EifSwKLQotICAgIHsgRVJfTk9fREVGQVVMVF9JTVBMLAotICAgICAgIk5lc3N1bmEgaW1wbGVtZW50YXppb25lIHByZWRlZmluaXRhIHRyb3ZhdGEgIn0sCi0KLSAgICB7IEVSX0NIVU5LRURJTlRBUlJBWV9OT1RfU1VQUE9SVEVELAotICAgICAgIkNodW5rZWRJbnRBcnJheSh7MH0pIG5vbiBzdXBwb3J0YXRvIGFsIG1vbWVudG8ifSwKLQotICAgIHsgRVJfT0ZGU0VUX0JJR0dFUl9USEFOX1NMT1QsCi0gICAgICAiT2Zmc2V0IHBpXHUwMEY5IGdyYW5kZSBkZWxsbyBzbG90In0sCi0KLSAgICB7IEVSX0NPUk9VVElORV9OT1RfQVZBSUwsCi0gICAgICAiQ28tcm91dGluZSBub24gZGlzcG9uaWJpbGUsIElEPXswfSJ9LAotCi0gICAgeyBFUl9DT1JPVVRJTkVfQ09fRVhJVCwKLSAgICAgICJDb3JvdXRpbmVNYW5hZ2VyIGhhIHJpY2V2dXRvIHVuYSByaWNoaWVzdGEgY29fZXhpdCgpIn0sCi0KLSAgICB7IEVSX0NPSk9JTlJPVVRJTkVTRVRfRkFJTEVELAotICAgICAgImNvX2pvaW5Db3JvdXRpbmVTZXQoKSBub24gcml1c2NpdG8ifSwKLQotICAgIHsgRVJfQ09ST1VUSU5FX1BBUkFNLAotICAgICAgIkVycm9yZSBkZWwgcGFyYW1ldHJvIGRpIGNvLXJvdXRpbmUgKHswfSkifSwKLQotICAgIHsgRVJfUEFSU0VSX0RPVEVSTUlOQVRFX0FOU1dFUlMsCi0gICAgICAiXG5JTVBSRVZJU1RPOiByaXNwb3N0ZSBkb1Rlcm1pbmF0ZSBkZWwgcGFyc2VyIHswfSJ9LAotCi0gICAgeyBFUl9OT19QQVJTRV9DQUxMX1dISUxFX1BBUlNJTkcsCi0gICAgICAiaW1wb3NzaWJpbGUgcmljaGlhbWFyZSBwYXJzZSBtZW50cmUgXHUwMEU4IGluIGNvcnNvIHVuJ2FuYWxpc2kifSwKLQotICAgIHsgRVJfVFlQRURfSVRFUkFUT1JfQVhJU19OT1RfSU1QTEVNRU5URUQsCi0gICAgICAiRXJyb3JlOiBsJydpdGVyYXRvcmUgY29uIHRpcG8gcGVyIGwnJ2Fzc2UgezB9IG5vbiBcdTAwRTggaW1wbGVtZW50YXRvIn0sCi0KLSAgICB7IEVSX0lURVJBVE9SX0FYSVNfTk9UX0lNUExFTUVOVEVELAotICAgICAgIkVycm9yZTogbCcnaXRlcmF0b3JlIHBlciBsJydhc3NlIHswfSBub24gXHUwMEU4IGltcGxlbWVudGF0byAifSwKLQotICAgIHsgRVJfSVRFUkFUT1JfQ0xPTkVfTk9UX1NVUFBPUlRFRCwKLSAgICAgICJEdXBsaWNhemlvbmUgZGVsbCdpdGVyYXRvcmUgbm9uIHN1cHBvcnRhdGEifSwKLQotICAgIHsgRVJfVU5LTk9XTl9BWElTX1RZUEUsCi0gICAgICAiVGlwbyBkaSBhc3NlIHRyYXN2ZXJzYWxlIHNjb25vc2NpdXRvOiB7MH0ifSwKLQotICAgIHsgRVJfQVhJU19OT1RfU1VQUE9SVEVELAotICAgICAgIkFzc2UgdHJhc3ZlcnNhbGUgbm9uIHN1cHBvcnRhdG86IHswfSJ9LAotCi0gICAgeyBFUl9OT19EVE1JRFNfQVZBSUwsCi0gICAgICAiTm9uIHNvbm8gZGlzcG9uaWJpbGkgYWx0cmkgSUQgRFRNIn0sCi0KLSAgICB7IEVSX05PVF9TVVBQT1JURUQsCi0gICAgICAiTm9uIHN1cHBvcnRhdG86IHswfSJ9LAotCi0gICAgeyBFUl9OT0RFX05PTl9OVUxMLAotICAgICAgIklsIG5vZG8gZGV2ZSBlc3NlcmUgbm9uIG51bGxvIHBlciBnZXREVE1IYW5kbGVGcm9tTm9kZSJ9LAotCi0gICAgeyBFUl9DT1VMRF9OT1RfUkVTT0xWRV9OT0RFLAotICAgICAgIkltcG9zc2liaWxlIHJpc29sdmVyZSBpbCBub2RvIGluIHVuIGhhbmRsZSJ9LAotCi0gICAgeyBFUl9TVEFSVFBBUlNFX1dISUxFX1BBUlNJTkcsCi0gICAgICAgImltcG9zc2liaWxlIHJpY2hpYW1hcmUgc3RhcnRQYXJzZSBtZW50cmUgXHUwMEU4IGluIGNvcnNvIHVuJ2FuYWxpc2kifSwKLQotICAgIHsgRVJfU1RBUlRQQVJTRV9ORUVEU19TQVhQQVJTRVIsCi0gICAgICAgInN0YXJ0UGFyc2UgcmljaGllZGUgdW4gdmFsb3JlIG5vbiBudWxsbyBwZXIgU0FYUGFyc2VyIn0sCi0KLSAgICB7IEVSX0NPVUxEX05PVF9JTklUX1BBUlNFUiwKLSAgICAgICAiaW1wb3NzaWJpbGUgaW5pemlhbGl6emFyZSBpbCBwYXJzZXIgY29uIn0sCi0KLSAgICB7IEVSX0VYQ0VQVElPTl9DUkVBVElOR19QT09MLAotICAgICAgICJlY2NlemlvbmUgZHVyYW50ZSBsYSBjcmVhemlvbmUgZGkgdW5hIG51b3ZhIGlzdGFuemEgcGVyIGlsIHBvb2wifSwKLQotICAgIHsgRVJfUEFUSF9DT05UQUlOU19JTlZBTElEX0VTQ0FQRV9TRVFVRU5DRSwKLSAgICAgICAiSWwgcGVyY29yc28gY29udGllbmUgc2VxdWVuemEgZGkgZXNjYXBlIG5vbiB2YWxpZGEifSwKLQotICAgIHsgRVJfU0NIRU1FX1JFUVVJUkVELAotICAgICAgICJMbyBzY2hlbWEgXHUwMEU4IG9iYmxpZ2F0b3Jpby4ifSwKLQotICAgIHsgRVJfTk9fU0NIRU1FX0lOX1VSSSwKLSAgICAgICAiTmVzc3VubyBzY2hlbWEgdHJvdmF0byBuZWxsJydVUkk6IHswfSJ9LAotCi0gICAgeyBFUl9OT19TQ0hFTUVfSU5VUkksCi0gICAgICAgIk5lc3N1bm8gc2NoZW1hIHRyb3ZhdG8gbmVsbCdVUkkifSwKLQotICAgIHsgRVJfUEFUSF9JTlZBTElEX0NIQVIsCi0gICAgICAgIklsIHBlcmNvcnNvIGNvbnRpZW5lIHVuIGNhcmF0dGVyZSBub24gdmFsaWRvOiB7MH0ifSwKLQotICAgIHsgRVJfU0NIRU1FX0ZST01fTlVMTF9TVFJJTkcsCi0gICAgICAgIkltcG9zc2liaWxlIGltcG9zdGFyZSBsbyBzY2hlbWEgZGEgdW5hIHN0cmluZ2EgbnVsbGEifSwKLQotICAgIHsgRVJfU0NIRU1FX05PVF9DT05GT1JNQU5ULAotICAgICAgICJMbyBzY2hlbWEgbm9uIFx1MDBFOCBjb25mb3JtZS4ifSwKLQotICAgIHsgRVJfSE9TVF9BRERSRVNTX05PVF9XRUxMRk9STUVELAotICAgICAgICJIb3N0IG5vbiBcdTAwRTggdW4gaW5kaXJpenpvIGNvcnJldHRvIn0sCi0KLSAgICB7IEVSX1BPUlRfV0hFTl9IT1NUX05VTEwsCi0gICAgICAgIkxhIHBvcnRhIG5vbiBwdVx1MDBGMiBlc3NlcmUgaW1wb3N0YXRhIHNlIGwnaG9zdCBcdTAwRTggbnVsbG8ifSwKLQotICAgIHsgRVJfSU5WQUxJRF9QT1JULAotICAgICAgICJOdW1lcm8gZGkgcG9ydGEgbm9uIHZhbGlkbyJ9LAotCi0gICAgeyBFUl9GUkFHX0ZPUl9HRU5FUklDX1VSSSwKLSAgICAgICAiSWwgZnJhbW1lbnRvIHB1XHUwMEYyIGVzc2VyZSBpbXBvc3RhdG8gc29sbyBwZXIgdW4gVVJJIGdlbmVyaWNvIn0sCi0KLSAgICB7IEVSX0ZSQUdfV0hFTl9QQVRIX05VTEwsCi0gICAgICAgIklsIGZyYW1tZW50byBub24gcHVcdTAwRjIgZXNzZXJlIGltcG9zdGF0byBzZSBpbCBwZXJjb3JzbyBcdTAwRTggbnVsbG8ifSwKLQotICAgIHsgRVJfRlJBR19JTlZBTElEX0NIQVIsCi0gICAgICAgIklsIGZyYW1tZW50byBjb250aWVuZSB1biBjYXJhdHRlcmUgbm9uIHZhbGlkbyJ9LAotCi0gICAgeyBFUl9QQVJTRVJfSU5fVVNFLAotICAgICAgIlBhcnNlciBnaVx1MDBFMCBpbiB1c28ifSwKLQotICAgIHsgRVJfQ0FOTk9UX0NIQU5HRV9XSElMRV9QQVJTSU5HLAotICAgICAgIkltcG9zc2liaWxlIG1vZGlmaWNhcmUgezB9IHsxfSBkdXJhbnRlIGwnJ2FuYWxpc2kifSwKLQotICAgIHsgRVJfU0VMRl9DQVVTQVRJT05fTk9UX1BFUk1JVFRFRCwKLSAgICAgICJDcmVhemlvbmUgYXV0b21hdGljYSBkZWxsYSBjYXVzYSBub24gY29uc2VudGl0YSJ9LAotCi0gICAgeyBFUl9OT19VU0VSSU5GT19JRl9OT19IT1NULAotICAgICAgIlVzZXJpbmZvIG5vbiBwdVx1MDBGMiBlc3NlcmUgc3BlY2lmaWNhdG8gc2UgbCdob3N0IG5vbiBcdTAwRTggc3BlY2lmaWNhdG8ifSwKLQotICAgIHsgRVJfTk9fUE9SVF9JRl9OT19IT1NULAotICAgICAgIkxhIHBvcnRhIG5vbiBwdVx1MDBGMiBlc3NlcmUgc3BlY2lmaWNhdGEgc2UgbCdob3N0IG5vbiBcdTAwRTggc3BlY2lmaWNhdG8ifSwKLQotICAgIHsgRVJfTk9fUVVFUllfU1RSSU5HX0lOX1BBVEgsCi0gICAgICAiTGEgc3RyaW5nYSBkaSBxdWVyeSBub24gcHVcdTAwRjIgZXNzZXJlIHNwZWNpZmljYXRhIG5lbGxhIHN0cmluZ2EgZGkgcGVyY29yc28gZSBxdWVyeS4ifSwKLQotICAgIHsgRVJfTk9fRlJBR01FTlRfU1RSSU5HX0lOX1BBVEgsCi0gICAgICAiSWwgZnJhbW1lbnRvIG5vbiBwdVx1MDBGMiBlc3NlcmUgc3BlY2lmaWNhdG8gc2lhIG5lbCBwZXJjb3JzbyBjaGUgbmVsIGZyYW1tZW50byJ9LAotCi0gICAgeyBFUl9DQU5OT1RfSU5JVF9VUklfRU1QVFlfUEFSTVMsCi0gICAgICAiSW1wb3NzaWJpbGUgaW5pemlhbGl6emFyZSBsJ1VSSSBjb24gaSBwYXJhbWV0cmkgdnVvdGkifSwKLQotICAgIHsgRVJfTUVUSE9EX05PVF9TVVBQT1JURUQsCi0gICAgICAiTWV0b2RvIGF0dHVhbG1lbnRlIG5vbiBzdXBwb3J0YXRvICJ9LAotCi0gICAgeyBFUl9JTkNSU0FYU1JDRklMVEVSX05PVF9SRVNUQVJUQUJMRSwKLSAgICAgICJJbmNyZW1lbnRhbFNBWFNvdXJjZV9GaWx0ZXIgYXR0dWFsbWVudGUgbm9uIHJpYXZ2aWFiaWxlIn0sCi0KLSAgICB7IEVSX1hNTFJEUl9OT1RfQkVGT1JFX1NUQVJUUEFSU0UsCi0gICAgICAiWE1MUmVhZGVyIG5vbiBzaSB0cm92YSBwcmltYSBkZWxsYSByaWNoaWVzdGEgc3RhcnRQYXJzZSJ9LAotCi0gICAgeyBFUl9BWElTX1RSQVZFUlNFUl9OT1RfU1VQUE9SVEVELAotICAgICAgIkFzc2UgdHJhc3ZlcnNhbGUgbm9uIHN1cHBvcnRhdG86IHswfSJ9LAotCi0gICAgeyBFUl9FUlJPUkhBTkRMRVJfQ1JFQVRFRF9XSVRIX05VTExfUFJJTlRXUklURVIsCi0gICAgICAiTGlzdGluZ0Vycm9ySGFuZGxlciBjcmVhdG8gY29uIFByaW50V3JpdGVyIG51bGxvLiJ9LAotCi0gICAgeyBFUl9TWVNURU1JRF9VTktOT1dOLAotICAgICAgIlN5c3RlbUlkIHNjb25vc2NpdXRvIn0sCi0KLSAgICB7IEVSX0xPQ0FUSU9OX1VOS05PV04sCi0gICAgICAiUG9zaXppb25lIHNjb25vc2NpdXRhIGRlbGwnZXJyb3JlIn0sCi0KLSAgICB7IEVSX1BSRUZJWF9NVVNUX1JFU09MVkUsCi0gICAgICAiSWwgcHJlZmlzc28gZGV2ZSBlc3NlcmUgcmlzb2x0byBpbiB1bm8gc3BhemlvIGRpIG5vbWk6IHswfSJ9LAotCi0gICAgeyBFUl9DUkVBVEVET0NVTUVOVF9OT1RfU1VQUE9SVEVELAotICAgICAgImNyZWF0ZURvY3VtZW50KCkgbm9uIHN1cHBvcnRhdG8gaW4gWFBhdGhDb250ZXh0In0sCi0KLSAgICB7IEVSX0NISUxEX0hBU19OT19PV05FUl9ET0NVTUVOVCwKLSAgICAgICJMJ2VsZW1lbnRvIGZpZ2xpbyBkZWxsJ2F0dHJpYnV0byBub24gZGlzcG9uZSBkaSB1biBkb2N1bWVudG8gcHJvcHJpZXRhcmlvLiJ9LAotCi0gICAgeyBFUl9DSElMRF9IQVNfTk9fT1dORVJfRE9DVU1FTlRfRUxFTUVOVCwKLSAgICAgICJMJ2VsZW1lbnRvIGZpZ2xpbyBkZWxsJ2F0dHJpYnV0byBub24gZGlzcG9uZSBkaSB1biBlbGVtZW50byBkaSBkb2N1bWVudG8gcHJvcHJpZXRhcmlvLiJ9LAotCi0gICAgeyBFUl9DQU5UX09VVFBVVF9URVhUX0JFRk9SRV9ET0MsCi0gICAgICAiQXZ2ZXJ0ZW56YTogaW1wb3NzaWJpbGUgY3JlYXJlIGwnb3V0cHV0IGRlbCB0ZXN0byBwcmltYSBkZWxsJ2VsZW1lbnRvIGRlbCBkb2N1bWVudG8uIE9wZXJhemlvbmUgaWdub3JhdGEuLi4ifSwKLQotICAgIHsgRVJfQ0FOVF9IQVZFX01PUkVfVEhBTl9PTkVfUk9PVCwKLSAgICAgICJOb24gcG9zc29ubyBlc2lzdGVyZSBwaVx1MDBGOSByYWRpY2kgaW4gdW4gRE9NLiJ9LAotCi0gICAgeyBFUl9BUkdfTE9DQUxOQU1FX05VTEwsCi0gICAgICAgIkwnYXJnb21lbnRvICdsb2NhbE5hbWUnIFx1MDBFOCBudWxsbyJ9LAotCi0gICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIEEgUU5BTUUgaGFzIHRoZSBzeW50YWN0aWMgZm9ybSBbTkNOYW1lOl1OQ05hbWUKLSAgICAvLyBUaGUgbG9jYWxuYW1lIGlzIHRoZSBwb3J0aW9uIGFmdGVyIHRoZSBvcHRpb25hbCBjb2xvbjsgdGhlIG1lc3NhZ2UgaW5kaWNhdGVzCi0gICAgLy8gdGhhdCB0aGVyZSBpcyBhIHByb2JsZW0gd2l0aCB0aGF0IHBhcnQgb2YgdGhlIFFOQU1FLgotICAgIHsgRVJfQVJHX0xPQ0FMTkFNRV9JTlZBTElELAotICAgICAgICJMb2NhbG5hbWUgaW4gUU5BTUUgZGV2ZSBlc3NlcmUgdW4gTkNOYW1lIHZhbGlkbyJ9LAotCi0gICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIEEgUU5BTUUgaGFzIHRoZSBzeW50YWN0aWMgZm9ybSBbTkNOYW1lOl1OQ05hbWUKLSAgICAvLyBUaGUgcHJlZml4IGlzIHRoZSBwb3J0aW9uIGJlZm9yZSB0aGUgb3B0aW9uYWwgY29sb247IHRoZSBtZXNzYWdlIGluZGljYXRlcwotICAgIC8vIHRoYXQgdGhlcmUgaXMgYSBwcm9ibGVtIHdpdGggdGhhdCBwYXJ0IG9mIHRoZSBRTkFNRS4KLSAgICB7IEVSX0FSR19QUkVGSVhfSU5WQUxJRCwKLSAgICAgICAiSWwgcHJlZmlzc28gaW4gUU5BTUUgZGV2ZSBlc3NlcmUgdW4gTkNOYW1lIHZhbGlkbyJ9LAotCi0gICAgeyBFUl9OQU1FX0NBTlRfU1RBUlRfV0lUSF9DT0xPTiwKLSAgICAgICJJbCBub21lIG5vbiBwdVx1MDBGMiBpbml6aWFyZSBjb24gaSBkdWUgcHVudGkifSwKLQotICAgIHsgIkJBRF9DT0RFIiwgIlBhcmFtZXRybyBwZXIgY3JlYXRlTWVzc2FnZSBmdW9yaSBsaW1pdGUifSwKLSAgICB7ICJGT1JNQVRfRkFJTEVEIiwgIkVjY2V6aW9uZSBkdXJhbnRlIGxhIGNoaWFtYXRhIG1lc3NhZ2VGb3JtYXQifSwKLSAgICB7ICJsaW5lIiwgIk4uIHJpZ2EifSwKLSAgICB7ICJjb2x1bW4iLCJOLiBjb2xvbm5hIn0sCi0KLSAgICB7RVJfU0VSSUFMSVpFUl9OT1RfQ09OVEVOVEhBTkRMRVIsCi0gICAgICAiTGEgY2xhc3NlIHNlcmlhbGl6emF0b3JlICcnezB9Jycgbm9uIGltcGxlbWVudGEgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIuIn0sCi0KLSAgICB7RVJfUkVTT1VSQ0VfQ09VTERfTk9UX0ZJTkQsCi0gICAgICAiUmlzb3JzYSBbIHswfSBdIG5vbiB0cm92YXRhLlxuIHsxfSIgfSwKLQotICAgIHtFUl9SRVNPVVJDRV9DT1VMRF9OT1RfTE9BRCwKLSAgICAgICJJbXBvc3NpYmlsZSBjYXJpY2FyZSBsYSByaXNvcnNhIFsgezB9IF06IHsxfSBcbiB7Mn0gXHQgezN9IiB9LAotCi0gICAge0VSX0JVRkZFUl9TSVpFX0xFU1NUSEFOX1pFUk8sCi0gICAgICAiRGltZW5zaW9uZSBidWZmZXIgPD0wIiB9LAotCi0gICAge0VSX0lOVkFMSURfVVRGMTZfU1VSUk9HQVRFLAotICAgICAgIlJpbGV2YXRvIHN1cnJvZ2F0byBVVEYtMTYgbm9uIHZhbGlkbzogezB9PyIgfSwKLQotICAgIHtFUl9PSUVSUk9SLAotICAgICAgIkVycm9yZSBJTyIgfSwKLQotICAgIHtFUl9JTExFR0FMX0FUVFJJQlVURV9QT1NJVElPTiwKLSAgICAgICJJbXBvc3NpYmlsZSBhZ2dpdW5nZXJlIGwnJ2F0dHJpYnV0byB7MH0gZG9wbyBpIG5vZGkgZmlnbGlvIG8gcHJpbWEgY2hlIHNpYSBwcm9kb3R0byB1biBlbGVtZW50by4gTCcnYXR0cmlidXRvIHZlcnJcdTAwRTAgaWdub3JhdG8uIn0sCi0KLSAgICAgIC8qCi0gICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN0eWxlc2hlZXQgY29udGFpbmVkIGEgcmVmZXJlbmNlIHRvIGEKLSAgICAgICAqIG5hbWVzcGFjZSBwcmVmaXggdGhhdCB3YXMgdW5kZWZpbmVkLiAgVGhlIHZhbHVlIG9mIHRoZSBzdWJzdGl0dXRpb24KLSAgICAgICAqIHRleHQgaXMgdGhlIG5hbWUgb2YgdGhlIHByZWZpeC4KLSAgICAgICAqLwotICAgIHtFUl9OQU1FU1BBQ0VfUFJFRklYLAotICAgICAgIkxvIHNwYXppbyBkaSBub21pIHBlciBpbCBwcmVmaXNzbyAnJ3swfScnIG5vbiBcdTAwRTggc3RhdG8gZGljaGlhcmF0by4iIH0sCi0gICAgICAvKgotICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyByZXBvcnRlZCBpZiB0aGUgc3R5bGVzaGVldAotICAgICAgICogYmVpbmcgcHJvY2Vzc2VkIGF0dGVtcHRlZCB0byBjb25zdHJ1Y3QgYW4gWE1MIGRvY3VtZW50IHdpdGggYW4KLSAgICAgICAqIGF0dHJpYnV0ZSBpbiBhIHBsYWNlIG90aGVyIHRoYW4gb24gYW4gZWxlbWVudC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICogc3BlY2lmaWVzIHRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUuCi0gICAgICAgKi8KLSAgICB7RVJfU1RSQVlfQVRUUklCVVRFLAotICAgICAgIkF0dHJpYnV0byAnJ3swfScnIGFsIGRpIGZ1b3JpIGRlbGwnJ2VsZW1lbnRvLiIgfSwKLQotICAgICAgLyoKLSAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBcyB3aXRoIHRoZSBwcmVjZWRpbmcgbWVzc2FnZSwgYSBuYW1lc3BhY2UKLSAgICAgICAqIGRlY2xhcmF0aW9uIGhhcyB0aGUgZm9ybSBvZiBhbiBhdHRyaWJ1dGUgYW5kIGlzIG9ubHkgcGVybWl0dGVkIHRvCi0gICAgICAgKiBhcHBlYXIgb24gYW4gZWxlbWVudC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCB7MH0gaXMgdGhlIG5hbWVzcGFjZQotICAgICAgICogcHJlZml4IGFuZCB7MX0gaXMgdGhlIFVSSSB0aGF0IHdhcyBiZWluZyB1c2VkIGluIHRoZSBlcnJvbmVvdXMKLSAgICAgICAqIG5hbWVzcGFjZSBkZWNsYXJhdGlvbi4KLSAgICAgICAqLwotICAgIHtFUl9TVFJBWV9OQU1FU1BBQ0UsCi0gICAgICAiRGljaGlhcmF6aW9uZSBkZWxsbyBzcGF6aW8gZGkgbm9taSAnJ3swfScnPScnezF9JycgYWwgZGkgZnVvcmkgZGVsbCcnZWxlbWVudG8uIiB9LAotCi0gICAge0VSX0NPVUxEX05PVF9MT0FEX1JFU09VUkNFLAotICAgICAgIkltcG9zc2liaWxlIGNhcmljYXJlICcnezB9JycgKHZlcmlmaWNhcmUgQ0xBU1NQQVRIKTsgdmVycmFubm8gdXRpbGl6emF0aSBpIHZhbG9yaSBwcmVkZWZpbml0aSJ9LAotCi0gICAgeyBFUl9JTExFR0FMX0NIQVJBQ1RFUiwKLSAgICAgICAiVGVudGF0aXZvIGRpIGVzZWd1aXJlIGwnJ291dHB1dCBkaSB1biBjYXJhdHRlcmUgZGkgdmFsb3JlIGludGVncmFsZSB7MH0gbm9uIHJhcHByZXNlbnRhdG8gbmVsbGEgY29kaWZpY2EgZGkgb3V0cHV0IHsxfSBzcGVjaWZpY2F0YS4ifSwKLQotICAgIHtFUl9DT1VMRF9OT1RfTE9BRF9NRVRIT0RfUFJPUEVSVFksCi0gICAgICAiSW1wb3NzaWJpbGUgY2FyaWNhcmUgaWwgZmlsZSBkZWxsZSBwcm9wcmlldFx1MDBFMCAnJ3swfScnIHBlciBpbCBtZXRvZG8gZGkgZW1pc3Npb25lICcnezF9JycgKHZlcmlmaWNhcmUgQ0xBU1NQQVRIKSIgfQotCi0KLSAgfTsKLQotICAvKioKLSAgICogR2V0IHRoZSBhc3NvY2lhdGlvbiBsaXN0LgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBhc3NvY2lhdGlvbiBsaXN0LgotICAgKi8KLQotICAgIHByb3RlY3RlZCBPYmplY3RbXVtdIGdldENvbnRlbnRzKCkgewotICAgICAgICByZXR1cm4gY29udGVudHM7Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9yZXMvWE1MRXJyb3JSZXNvdXJjZXNfamEuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3Jlcy9YTUxFcnJvclJlc291cmNlc19qYS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkZmEzODdiLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3Jlcy9YTUxFcnJvclJlc291cmNlc19qYS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDUwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXM7Ci0KLQotaW1wb3J0IGphdmEudXRpbC5MaXN0UmVzb3VyY2VCdW5kbGU7Ci0KLS8qKgotICogU2V0IHVwIGVycm9yIG1lc3NhZ2VzLgotICogV2UgYnVpbGQgYSB0d28gZGltZW5zaW9uYWwgYXJyYXkgb2YgbWVzc2FnZSBrZXlzIGFuZAotICogbWVzc2FnZSBzdHJpbmdzLiBJbiBvcmRlciB0byBhZGQgYSBuZXcgbWVzc2FnZSBoZXJlLAotICogeW91IG5lZWQgdG8gZmlyc3QgYWRkIGEgU3RyaW5nIGNvbnN0YW50LiBBbmQgeW91IG5lZWQKLSAqIHRvIGVudGVyIGtleSwgdmFsdWUgcGFpciBhcyBwYXJ0IG9mIHRoZSBjb250ZW50cwotICogYXJyYXkuIFlvdSBhbHNvIG5lZWQgdG8gdXBkYXRlIE1BWF9DT0RFIGZvciBlcnJvciBzdHJpbmdzCi0gKiBhbmQgTUFYX1dBUk5JTkcgZm9yIHdhcm5pbmdzICggTmVlZGVkIGZvciBvbmx5IGluZm9ybWF0aW9uCi0gKiBwdXJwb3NlICkKLSAqLwotcHVibGljIGNsYXNzIFhNTEVycm9yUmVzb3VyY2VzX2phIGV4dGVuZHMgTGlzdFJlc291cmNlQnVuZGxlCi17Ci0KLS8qCi0gKiBUaGlzIGZpbGUgY29udGFpbnMgZXJyb3IgYW5kIHdhcm5pbmcgbWVzc2FnZXMgcmVsYXRlZCB0byBYYWxhbiBFcnJvcgotICogSGFuZGxpbmcuCi0gKgotICogIEdlbmVyYWwgbm90ZXMgdG8gdHJhbnNsYXRvcnM6Ci0gKgotICogIDEpIFhhbGFuIChvciBtb3JlIHByb3Blcmx5LCBYYWxhbi1pbnRlcnByZXRpdmUpIGFuZCBYU0xUQyBhcmUgbmFtZXMgb2YKLSAqICAgICBjb21wb25lbnRzLgotICogICAgIFhTTFQgaXMgYW4gYWNyb255bSBmb3IgIlhNTCBTdHlsZXNoZWV0IExhbmd1YWdlOiBUcmFuc2Zvcm1hdGlvbnMiLgotICogICAgIFhTTFRDIGlzIGFuIGFjcm9ueW0gZm9yIFhTTFQgQ29tcGlsZXIuCi0gKgotICogIDIpIEEgc3R5bGVzaGVldCBpcyBhIGRlc2NyaXB0aW9uIG9mIGhvdyB0byB0cmFuc2Zvcm0gYW4gaW5wdXQgWE1MIGRvY3VtZW50Ci0gKiAgICAgaW50byBhIHJlc3VsdGFudCBYTUwgZG9jdW1lbnQgKG9yIEhUTUwgZG9jdW1lbnQgb3IgdGV4dCkuICBUaGUKLSAqICAgICBzdHlsZXNoZWV0IGl0c2VsZiBpcyBkZXNjcmliZWQgaW4gdGhlIGZvcm0gb2YgYW4gWE1MIGRvY3VtZW50LgotICoKLSAqICAzKSBBIHRlbXBsYXRlIGlzIGEgY29tcG9uZW50IG9mIGEgc3R5bGVzaGVldCB0aGF0IGlzIHVzZWQgdG8gbWF0Y2ggYQotICogICAgIHBhcnRpY3VsYXIgcG9ydGlvbiBvZiBhbiBpbnB1dCBkb2N1bWVudCBhbmQgc3BlY2lmaWVzIHRoZSBmb3JtIG9mIHRoZQotICogICAgIGNvcnJlc3BvbmRpbmcgcG9ydGlvbiBvZiB0aGUgb3V0cHV0IGRvY3VtZW50LgotICoKLSAqICA0KSBBbiBlbGVtZW50IGlzIGEgbWFyay11cCB0YWcgaW4gYW4gWE1MIGRvY3VtZW50OyBhbiBhdHRyaWJ1dGUgaXMgYQotICogICAgIG1vZGlmaWVyIG9uIHRoZSB0YWcuICBGb3IgZXhhbXBsZSwgaW4gPGVsZW0gYXR0cj0ndmFsJyBhdHRyMj0ndmFsMic+Ci0gKiAgICAgImVsZW0iIGlzIGFuIGVsZW1lbnQgbmFtZSwgImF0dHIiIGFuZCAiYXR0cjIiIGFyZSBhdHRyaWJ1dGUgbmFtZXMgd2l0aAotICogICAgIHRoZSB2YWx1ZXMgInZhbCIgYW5kICJ2YWwyIiwgcmVzcGVjdGl2ZWx5LgotICoKLSAqICA1KSBBIG5hbWVzcGFjZSBkZWNsYXJhdGlvbiBpcyBhIHNwZWNpYWwgYXR0cmlidXRlIHRoYXQgaXMgdXNlZCB0byBhc3NvY2lhdGUKLSAqICAgICBhIHByZWZpeCB3aXRoIGEgVVJJICh0aGUgbmFtZXNwYWNlKS4gIFRoZSBtZWFuaW5ncyBvZiBlbGVtZW50IG5hbWVzIGFuZAotICogICAgIGF0dHJpYnV0ZSBuYW1lcyB0aGF0IHVzZSB0aGF0IHByZWZpeCBhcmUgZGVmaW5lZCB3aXRoIHJlc3BlY3QgdG8gdGhhdAotICogICAgIG5hbWVzcGFjZS4KLSAqCi0gKiAgNikgIlRyYW5zbGV0IiBpcyBhbiBpbnZlbnRlZCB0ZXJtIHRoYXQgZGVzY3JpYmVzIHRoZSBjbGFzcyBmaWxlIHRoYXQKLSAqICAgICByZXN1bHRzIGZyb20gY29tcGlsaW5nIGFuIFhNTCBzdHlsZXNoZWV0IGludG8gYSBKYXZhIGNsYXNzLgotICoKLSAqICA3KSBYUGF0aCBpcyBhIHNwZWNpZmljYXRpb24gdGhhdCBkZXNjcmliZXMgYSBub3RhdGlvbiBmb3IgaWRlbnRpZnlpbmcKLSAqICAgICBub2RlcyBpbiBhIHRyZWUtc3RydWN0dXJlZCByZXByZXNlbnRhdGlvbiBvZiBhbiBYTUwgZG9jdW1lbnQuICBBbgotICogICAgIGluc3RhbmNlIG9mIHRoYXQgbm90YXRpb24gaXMgcmVmZXJyZWQgdG8gYXMgYW4gWFBhdGggZXhwcmVzc2lvbi4KLSAqCi0gKi8KLQotICAvKiogTWF4aW11bSBlcnJvciBtZXNzYWdlcywgdGhpcyBpcyBuZWVkZWQgdG8ga2VlcCB0cmFjayBvZiB0aGUgbnVtYmVyIG9mIG1lc3NhZ2VzLiAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVhfQ09ERSA9IDYxOwotCi0gIC8qKiBNYXhpbXVtIHdhcm5pbmdzLCB0aGlzIGlzIG5lZWRlZCB0byBrZWVwIHRyYWNrIG9mIHRoZSBudW1iZXIgb2Ygd2FybmluZ3MuICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BWF9XQVJOSU5HID0gMDsKLQotICAvKiogTWF4aW11bSBtaXNjIHN0cmluZ3MuICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFYX09USEVSUyA9IDQ7Ci0KLSAgLyoqIE1heGltdW0gdG90YWwgd2FybmluZ3MgYW5kIGVycm9yIG1lc3NhZ2VzLiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVhfTUVTU0FHRVMgPSBNQVhfQ09ERSArIE1BWF9XQVJOSU5HICsgMTsKLQotCi0gIC8qCi0gICAqIE1lc3NhZ2Uga2V5cwotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCA9ICJFUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX09WRVJXUklURV9DQVVTRSA9ICJFUl9DQU5OT1RfT1ZFUldSSVRFX0NBVVNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fREVGQVVMVF9JTVBMID0gIkVSX05PX0RFRkFVTFRfSU1QTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NIVU5LRURJTlRBUlJBWV9OT1RfU1VQUE9SVEVEID0gIkVSX0NIVU5LRURJTlRBUlJBWV9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfT0ZGU0VUX0JJR0dFUl9USEFOX1NMT1QgPSAiRVJfT0ZGU0VUX0JJR0dFUl9USEFOX1NMT1QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1JPVVRJTkVfTk9UX0FWQUlMID0gIkVSX0NPUk9VVElORV9OT1RfQVZBSUwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1JPVVRJTkVfQ09fRVhJVCA9ICJFUl9DT1JPVVRJTkVfQ09fRVhJVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPSk9JTlJPVVRJTkVTRVRfRkFJTEVEID0gIkVSX0NPSk9JTlJPVVRJTkVTRVRfRkFJTEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09ST1VUSU5FX1BBUkFNID0gIkVSX0NPUk9VVElORV9QQVJBTSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BBUlNFUl9ET1RFUk1JTkFURV9BTlNXRVJTID0gIkVSX1BBUlNFUl9ET1RFUk1JTkFURV9BTlNXRVJTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fUEFSU0VfQ0FMTF9XSElMRV9QQVJTSU5HID0gIkVSX05PX1BBUlNFX0NBTExfV0hJTEVfUEFSU0lORyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1RZUEVEX0lURVJBVE9SX0FYSVNfTk9UX0lNUExFTUVOVEVEID0gIkVSX1RZUEVEX0lURVJBVE9SX0FYSVNfTk9UX0lNUExFTUVOVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSVRFUkFUT1JfQVhJU19OT1RfSU1QTEVNRU5URUQgPSAiRVJfSVRFUkFUT1JfQVhJU19OT1RfSU1QTEVNRU5URUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JVEVSQVRPUl9DTE9ORV9OT1RfU1VQUE9SVEVEID0gIkVSX0lURVJBVE9SX0NMT05FX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTktOT1dOX0FYSVNfVFlQRSA9ICJFUl9VTktOT1dOX0FYSVNfVFlQRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FYSVNfTk9UX1NVUFBPUlRFRCA9ICJFUl9BWElTX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19EVE1JRFNfQVZBSUwgPSAiRVJfTk9fRFRNSURTX0FWQUlMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9UX1NVUFBPUlRFRCA9ICJFUl9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9ERV9OT05fTlVMTCA9ICJFUl9OT0RFX05PTl9OVUxMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTERfTk9UX1JFU09MVkVfTk9ERSA9ICJFUl9DT1VMRF9OT1RfUkVTT0xWRV9OT0RFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU1RBUlRQQVJTRV9XSElMRV9QQVJTSU5HID0gIkVSX1NUQVJUUEFSU0VfV0hJTEVfUEFSU0lORyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NUQVJUUEFSU0VfTkVFRFNfU0FYUEFSU0VSID0gIkVSX1NUQVJUUEFSU0VfTkVFRFNfU0FYUEFSU0VSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTERfTk9UX0lOSVRfUEFSU0VSID0gIkVSX0NPVUxEX05PVF9JTklUX1BBUlNFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYQ0VQVElPTl9DUkVBVElOR19QT09MID0gIkVSX0VYQ0VQVElPTl9DUkVBVElOR19QT09MIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUEFUSF9DT05UQUlOU19JTlZBTElEX0VTQ0FQRV9TRVFVRU5DRSA9ICJFUl9QQVRIX0NPTlRBSU5TX0lOVkFMSURfRVNDQVBFX1NFUVVFTkNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU0NIRU1FX1JFUVVJUkVEID0gIkVSX1NDSEVNRV9SRVFVSVJFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1NDSEVNRV9JTl9VUkkgPSAiRVJfTk9fU0NIRU1FX0lOX1VSSSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1NDSEVNRV9JTlVSSSA9ICJFUl9OT19TQ0hFTUVfSU5VUkkiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QQVRIX0lOVkFMSURfQ0hBUiA9ICJFUl9QQVRIX0lOVkFMSURfQ0hBUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NDSEVNRV9GUk9NX05VTExfU1RSSU5HID0gIkVSX1NDSEVNRV9GUk9NX05VTExfU1RSSU5HIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU0NIRU1FX05PVF9DT05GT1JNQU5UID0gIkVSX1NDSEVNRV9OT1RfQ09ORk9STUFOVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0hPU1RfQUREUkVTU19OT1RfV0VMTEZPUk1FRCA9ICJFUl9IT1NUX0FERFJFU1NfTk9UX1dFTExGT1JNRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QT1JUX1dIRU5fSE9TVF9OVUxMID0gIkVSX1BPUlRfV0hFTl9IT1NUX05VTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX1BPUlQgPSAiRVJfSU5WQUxJRF9QT1JUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRlJBR19GT1JfR0VORVJJQ19VUkkgPSJFUl9GUkFHX0ZPUl9HRU5FUklDX1VSSSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZSQUdfV0hFTl9QQVRIX05VTEwgPSAiRVJfRlJBR19XSEVOX1BBVEhfTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZSQUdfSU5WQUxJRF9DSEFSID0gIkVSX0ZSQUdfSU5WQUxJRF9DSEFSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUEFSU0VSX0lOX1VTRSA9ICJFUl9QQVJTRVJfSU5fVVNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX0NIQU5HRV9XSElMRV9QQVJTSU5HID0gIkVSX0NBTk5PVF9DSEFOR0VfV0hJTEVfUEFSU0lORyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NFTEZfQ0FVU0FUSU9OX05PVF9QRVJNSVRURUQgPSAiRVJfU0VMRl9DQVVTQVRJT05fTk9UX1BFUk1JVFRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1VTRVJJTkZPX0lGX05PX0hPU1QgPSAiRVJfTk9fVVNFUklORk9fSUZfTk9fSE9TVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1BPUlRfSUZfTk9fSE9TVCA9ICJFUl9OT19QT1JUX0lGX05PX0hPU1QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19RVUVSWV9TVFJJTkdfSU5fUEFUSCA9ICJFUl9OT19RVUVSWV9TVFJJTkdfSU5fUEFUSCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX0ZSQUdNRU5UX1NUUklOR19JTl9QQVRIID0gIkVSX05PX0ZSQUdNRU5UX1NUUklOR19JTl9QQVRIIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX0lOSVRfVVJJX0VNUFRZX1BBUk1TID0gIkVSX0NBTk5PVF9JTklUX1VSSV9FTVBUWV9QQVJNUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01FVEhPRF9OT1RfU1VQUE9SVEVEID0iRVJfTUVUSE9EX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTkNSU0FYU1JDRklMVEVSX05PVF9SRVNUQVJUQUJMRSA9ICJFUl9JTkNSU0FYU1JDRklMVEVSX05PVF9SRVNUQVJUQUJMRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hNTFJEUl9OT1RfQkVGT1JFX1NUQVJUUEFSU0UgPSAiRVJfWE1MUkRSX05PVF9CRUZPUkVfU1RBUlRQQVJTRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FYSVNfVFJBVkVSU0VSX05PVF9TVVBQT1JURUQgPSAiRVJfQVhJU19UUkFWRVJTRVJfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VSUk9SSEFORExFUl9DUkVBVEVEX1dJVEhfTlVMTF9QUklOVFdSSVRFUiA9ICJFUl9FUlJPUkhBTkRMRVJfQ1JFQVRFRF9XSVRIX05VTExfUFJJTlRXUklURVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TWVNURU1JRF9VTktOT1dOID0gIkVSX1NZU1RFTUlEX1VOS05PV04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9MT0NBVElPTl9VTktOT1dOID0gIkVSX0xPQ0FUSU9OX1VOS05PV04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUkVGSVhfTVVTVF9SRVNPTFZFID0gIkVSX1BSRUZJWF9NVVNUX1JFU09MVkUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DUkVBVEVET0NVTUVOVF9OT1RfU1VQUE9SVEVEID0gIkVSX0NSRUFURURPQ1VNRU5UX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DSElMRF9IQVNfTk9fT1dORVJfRE9DVU1FTlQgPSAiRVJfQ0hJTERfSEFTX05PX09XTkVSX0RPQ1VNRU5UIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0hJTERfSEFTX05PX09XTkVSX0RPQ1VNRU5UX0VMRU1FTlQgPSAiRVJfQ0hJTERfSEFTX05PX09XTkVSX0RPQ1VNRU5UX0VMRU1FTlQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX09VVFBVVF9URVhUX0JFRk9SRV9ET0MgPSAiRVJfQ0FOVF9PVVRQVVRfVEVYVF9CRUZPUkVfRE9DIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9IQVZFX01PUkVfVEhBTl9PTkVfUk9PVCA9ICJFUl9DQU5UX0hBVkVfTU9SRV9USEFOX09ORV9ST09UIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQVJHX0xPQ0FMTkFNRV9OVUxMID0gIkVSX0FSR19MT0NBTE5BTUVfTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FSR19MT0NBTE5BTUVfSU5WQUxJRCA9ICJFUl9BUkdfTE9DQUxOQU1FX0lOVkFMSUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9BUkdfUFJFRklYX0lOVkFMSUQgPSAiRVJfQVJHX1BSRUZJWF9JTlZBTElEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTkFNRV9DQU5UX1NUQVJUX1dJVEhfQ09MT04gPSAiRVJfTkFNRV9DQU5UX1NUQVJUX1dJVEhfQ09MT04iOwotCi0gIC8vIE1lc3NhZ2Uga2V5cyB1c2VkIGJ5IHRoZSBzZXJpYWxpemVyCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1JFU09VUkNFX0NPVUxEX05PVF9GSU5EID0gIkVSX1JFU09VUkNFX0NPVUxEX05PVF9GSU5EIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUkVTT1VSQ0VfQ09VTERfTk9UX0xPQUQgPSAiRVJfUkVTT1VSQ0VfQ09VTERfTk9UX0xPQUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9CVUZGRVJfU0laRV9MRVNTVEhBTl9aRVJPID0gIkVSX0JVRkZFUl9TSVpFX0xFU1NUSEFOX1pFUk8iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX1VURjE2X1NVUlJPR0FURSA9ICJFUl9JTlZBTElEX1VURjE2X1NVUlJPR0FURSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX09JRVJST1IgPSAiRVJfT0lFUlJPUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05BTUVTUEFDRV9QUkVGSVggPSAiRVJfTkFNRVNQQUNFX1BSRUZJWCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NUUkFZX0FUVFJJQlVURSA9ICJFUl9TVFJBWV9BVFRJUkJVVEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TVFJBWV9OQU1FU1BBQ0UgPSAiRVJfU1RSQVlfTkFNRVNQQUNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTERfTk9UX0xPQURfUkVTT1VSQ0UgPSAiRVJfQ09VTERfTk9UX0xPQURfUkVTT1VSQ0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRF9OT1RfTE9BRF9NRVRIT0RfUFJPUEVSVFkgPSAiRVJfQ09VTERfTk9UX0xPQURfTUVUSE9EX1BST1BFUlRZIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU0VSSUFMSVpFUl9OT1RfQ09OVEVOVEhBTkRMRVIgPSAiRVJfU0VSSUFMSVpFUl9OT1RfQ09OVEVOVEhBTkRMRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTExFR0FMX0FUVFJJQlVURV9QT1NJVElPTiA9ICJFUl9JTExFR0FMX0FUVFJJQlVURV9QT1NJVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lMTEVHQUxfQ0hBUkFDVEVSID0gIkVSX0lMTEVHQUxfQ0hBUkFDVEVSIjsKLQotICAvKgotICAgKiBOb3cgZmlsbCBpbiB0aGUgbWVzc2FnZSB0ZXh0LgotICAgKiBUaGVuIGZpbGwgaW4gdGhlIG1lc3NhZ2UgdGV4dCBmb3IgdGhhdCBtZXNzYWdlIGNvZGUgaW4gdGhlCi0gICAqIGFycmF5LiBVc2UgdGhlIG5ldyBlcnJvciBjb2RlIGFzIHRoZSBpbmRleCBpbnRvIHRoZSBhcnJheS4KLSAgICovCi0KLSAgLy8gRXJyb3IgbWVzc2FnZXMuLi4KLQotICAvKiogVGhlIGxvb2t1cCB0YWJsZSBmb3IgZXJyb3IgbWVzc2FnZXMuICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgT2JqZWN0W11bXSBjb250ZW50cyA9IHsKLQotICAvKiogRXJyb3IgbWVzc2FnZSBJRCB0aGF0IGhhcyBhIG51bGwgbWVzc2FnZSwgYnV0IHRha2VzIGluIGEgc2luZ2xlIG9iamVjdC4gICAgKi8KLSAgICB7IkVSMDAwMCIgLCAiezB9IiB9LAotCi0gICAgeyBFUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVELAotICAgICAgIlx1OTVBMlx1NjU3MFx1MzA0Q1x1MzBCNVx1MzBERFx1MzBGQ1x1MzBDOFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMiJ9LAotCi0gICAgeyBFUl9DQU5OT1RfT1ZFUldSSVRFX0NBVVNFLAotICAgICAgIlx1NTM5Rlx1NTZFMFx1MzA5Mlx1NEUwQVx1NjZGOFx1MzA0RFx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MyJ9LAotCi0gICAgeyBFUl9OT19ERUZBVUxUX0lNUEwsCi0gICAgICAiXHUzMEM3XHUzMEQ1XHUzMEE5XHUzMEVCXHUzMEM4XHU1QjlGXHU4OEM1XHUzMDRDXHU4OThCXHUzMDY0XHUzMDRCXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzICJ9LAotCi0gICAgeyBFUl9DSFVOS0VESU5UQVJSQVlfTk9UX1NVUFBPUlRFRCwKLSAgICAgICJDaHVua2VkSW50QXJyYXkoezB9KVx1MzA2Rlx1NzNGRVx1NTcyOFx1MzBCNVx1MzBERFx1MzBGQ1x1MzBDOFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5MyJ9LAotCi0gICAgeyBFUl9PRkZTRVRfQklHR0VSX1RIQU5fU0xPVCwKLSAgICAgICJcdTMwQUFcdTMwRDVcdTMwQkJcdTMwQzNcdTMwQzhcdTMwNENcdTMwQjlcdTMwRURcdTMwQzNcdTMwQzhcdTMwODhcdTMwOEFcdTMwODJcdTU5MjdcdTMwNERcdTMwNDRcdTMwNjdcdTMwNTkifSwKLQotICAgIHsgRVJfQ09ST1VUSU5FX05PVF9BVkFJTCwKLSAgICAgICJcdTMwQjNcdTMwRUJcdTMwRkNcdTMwQzFcdTMwRjNcdTMwOTJcdTRGN0ZcdTc1MjhcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDJpZD17MH0ifSwKLQotICAgIHsgRVJfQ09ST1VUSU5FX0NPX0VYSVQsCi0gICAgICAiQ29yb3V0aW5lTWFuYWdlclx1MzA0Q2NvX2V4aXQoKVx1MzBFQVx1MzBBRlx1MzBBOFx1MzBCOVx1MzBDOFx1MzA5Mlx1NTNEN1x1MzA1MVx1NTNENlx1MzA4QVx1MzA3RVx1MzA1N1x1MzA1RiJ9LAotCi0gICAgeyBFUl9DT0pPSU5ST1VUSU5FU0VUX0ZBSUxFRCwKLSAgICAgICJjb19qb2luQ29yb3V0aW5lU2V0KClcdTMwNENcdTU5MzFcdTY1NTdcdTMwNTdcdTMwN0VcdTMwNTdcdTMwNUYifSwKLQotICAgIHsgRVJfQ09ST1VUSU5FX1BBUkFNLAotICAgICAgIlx1MzBCM1x1MzBFQlx1MzBGQ1x1MzBDMVx1MzBGM1x1MzBGQlx1MzBEMVx1MzBFOVx1MzBFMVx1MzBGQ1x1MzBCRlx1MzA2RVx1MzBBOFx1MzBFOVx1MzBGQyh7MH0pIn0sCi0KLSAgICB7IEVSX1BBUlNFUl9ET1RFUk1JTkFURV9BTlNXRVJTLAotICAgICAgIlxuXHU0RTBEXHU2NjBFOiBcdTMwRDFcdTMwRkNcdTMwQjVcdTMwRkNkb1Rlcm1pbmF0ZVx1MzA2RVx1NUZEQ1x1N0I1NFx1MzA2RnswfVx1MzA2N1x1MzA1OSJ9LAotCi0gICAgeyBFUl9OT19QQVJTRV9DQUxMX1dISUxFX1BBUlNJTkcsCi0gICAgICAiXHU4OUUzXHU2NzkwXHUzMDZGXHU2OUNCXHU2NTg3XHU4OUUzXHU2NzkwXHU0RTJEXHUzMDZCXHU1NDdDXHUzMDczXHU1MUZBXHUzMDU5XHUzMDUzXHUzMDY4XHUzMDRDXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzIn0sCi0KLSAgICB7IEVSX1RZUEVEX0lURVJBVE9SX0FYSVNfTk9UX0lNUExFTUVOVEVELAotICAgICAgIlx1MzBBOFx1MzBFOVx1MzBGQzogXHU4RUY4ezB9XHUzMDZFXHU1NzhCXHU2MzA3XHU1QjlBXHUzMDU1XHUzMDhDXHUzMDVGXHUzMEE0XHUzMEM2XHUzMEVDXHUzMEZDXHUzMEJGXHUzMDRDXHU1QjlGXHU4OEM1XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzIn0sCi0KLSAgICB7IEVSX0lURVJBVE9SX0FYSVNfTk9UX0lNUExFTUVOVEVELAotICAgICAgIlx1MzBBOFx1MzBFOVx1MzBGQzogXHU4RUY4ezB9XHUzMDZFXHUzMEE0XHUzMEM2XHUzMEVDXHUzMEZDXHUzMEJGXHUzMDRDXHU1QjlGXHU4OEM1XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzICJ9LAotCi0gICAgeyBFUl9JVEVSQVRPUl9DTE9ORV9OT1RfU1VQUE9SVEVELAotICAgICAgIlx1MzBBNFx1MzBDNlx1MzBFQ1x1MzBGQ1x1MzBCRlx1MzA2RVx1MzBBRlx1MzBFRFx1MzBGQ1x1MzBGM1x1MzA2Rlx1MzBCNVx1MzBERFx1MzBGQ1x1MzBDOFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5MyJ9LAotCi0gICAgeyBFUl9VTktOT1dOX0FYSVNfVFlQRSwKLSAgICAgICJcdTRFMERcdTY2MEVcdTMwNkFcdThFRjhcdTMwQzhcdTMwRTlcdTMwRDBcdTMwRkNcdTMwQjlcdTMwRkJcdTMwQkZcdTMwQTRcdTMwRDdcdTMwNjdcdTMwNTk6IHswfSJ9LAotCi0gICAgeyBFUl9BWElTX05PVF9TVVBQT1JURUQsCi0gICAgICAiXHU4RUY4XHUzMEM4XHUzMEU5XHUzMEQwXHUzMEZDXHUzMEI1XHU2QTVGXHU4MEZEXHUzMDZGXHUzMEI1XHUzMEREXHUzMEZDXHUzMEM4XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzOiB7MH0ifSwKLQotICAgIHsgRVJfTk9fRFRNSURTX0FWQUlMLAotICAgICAgIkRUTSBJRFx1MzA2Rlx1MzA1M1x1MzA4Q1x1NEVFNVx1NEUwQVx1NEY3Rlx1NzUyOFx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MyJ9LAotCi0gICAgeyBFUl9OT1RfU1VQUE9SVEVELAotICAgICAgIlx1MzBCNVx1MzBERFx1MzBGQ1x1MzBDOFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5MzogezB9In0sCi0KLSAgICB7IEVSX05PREVfTk9OX05VTEwsCi0gICAgICAiXHUzMENFXHUzMEZDXHUzMEM5XHUzMDZGZ2V0RFRNSGFuZGxlRnJvbU5vZGVcdTMwNkJcdTMwNjRcdTMwNDRcdTMwNjZcdTk3NUVudWxsXHUzMDY3XHUzMDQyXHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5In0sCi0KLSAgICB7IEVSX0NPVUxEX05PVF9SRVNPTFZFX05PREUsCi0gICAgICAiXHUzMENFXHUzMEZDXHUzMEM5XHUzMDkyXHUzMENGXHUzMEYzXHUzMEM5XHUzMEVCXHUzMDZCXHU4OUUzXHU2QzdBXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDY3XHUzMDU3XHUzMDVGIn0sCi0KLSAgICB7IEVSX1NUQVJUUEFSU0VfV0hJTEVfUEFSU0lORywKLSAgICAgICAic3RhcnRQYXJzZVx1MzA2Rlx1NjlDQlx1NjU4N1x1ODlFM1x1Njc5MFx1NEUyRFx1MzA2Qlx1NTQ3Q1x1MzA3M1x1NTFGQVx1MzA1OVx1MzA1M1x1MzA2OFx1MzA2Rlx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MyJ9LAotCi0gICAgeyBFUl9TVEFSVFBBUlNFX05FRURTX1NBWFBBUlNFUiwKLSAgICAgICAic3RhcnRQYXJzZVx1MzA2Qlx1MzA2Rlx1OTc1RW51bGxcdTMwNkVTQVhQYXJzZXJcdTMwNENcdTVGQzVcdTg5ODFcdTMwNjdcdTMwNTkifSwKLQotICAgIHsgRVJfQ09VTERfTk9UX0lOSVRfUEFSU0VSLAotICAgICAgICJcdTZCMjFcdTMwNkVcdTc0MDZcdTc1MzFcdTMwNjdcdTMwRDFcdTMwRkNcdTMwQjVcdTMwRkNcdTMwOTJcdTUyMURcdTY3MUZcdTUzMTZcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwNjdcdTMwNTdcdTMwNUY6ICJ9LAotCi0gICAgeyBFUl9FWENFUFRJT05fQ1JFQVRJTkdfUE9PTCwKLSAgICAgICAiXHUzMEQ3XHUzMEZDXHUzMEVCXHU3NTI4XHUzMDZFXHU2NUIwXHU4OThGXHUzMEE0XHUzMEYzXHUzMEI5XHUzMEJGXHUzMEYzXHUzMEI5XHUzMDZFXHU0RjVDXHU2MjEwXHU0RTJEXHUzMDZCXHU3NjdBXHU3NTFGXHUzMDU3XHUzMDVGXHU0RjhCXHU1OTE2In0sCi0KLSAgICB7IEVSX1BBVEhfQ09OVEFJTlNfSU5WQUxJRF9FU0NBUEVfU0VRVUVOQ0UsCi0gICAgICAgIlx1MzBEMVx1MzBCOVx1MzA2Qlx1NzEyMVx1NTJCOVx1MzA2QVx1MzBBOFx1MzBCOVx1MzBCMVx1MzBGQ1x1MzBEN1x1MzBGQlx1MzBCN1x1MzBGQ1x1MzBCMVx1MzBGM1x1MzBCOVx1MzA0Q1x1NTQyQlx1MzA3RVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OSJ9LAotCi0gICAgeyBFUl9TQ0hFTUVfUkVRVUlSRUQsCi0gICAgICAgIlx1MzBCOVx1MzBBRFx1MzBGQ1x1MzBFMFx1MzA0Q1x1NUZDNVx1ODk4MVx1MzA2N1x1MzA1OVx1MzAwMiJ9LAotCi0gICAgeyBFUl9OT19TQ0hFTUVfSU5fVVJJLAotICAgICAgICJcdTMwQjlcdTMwQURcdTMwRkNcdTMwRTBcdTMwNENVUklcdTMwNkJcdTg5OEJcdTMwNjRcdTMwNEJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTM6IHswfSJ9LAotCi0gICAgeyBFUl9OT19TQ0hFTUVfSU5VUkksCi0gICAgICAgIlx1MzBCOVx1MzBBRFx1MzBGQ1x1MzBFMFx1MzA0Q1VSSVx1MzA2Qlx1ODk4Qlx1MzA2NFx1MzA0Qlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5MyJ9LAotCi0gICAgeyBFUl9QQVRIX0lOVkFMSURfQ0hBUiwKLSAgICAgICAiXHUzMEQxXHUzMEI5XHUzMDZCXHU3MTIxXHU1MkI5XHUzMDZBXHU2NTg3XHU1QjU3XHUzMDRDXHU1NDJCXHUzMDdFXHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5OiB7MH0ifSwKLQotICAgIHsgRVJfU0NIRU1FX0ZST01fTlVMTF9TVFJJTkcsCi0gICAgICAgIm51bGxcdTY1ODdcdTVCNTdcdTUyMTdcdTMwNEJcdTMwODlcdTMwNkZcdTMwQjlcdTMwQURcdTMwRkNcdTMwRTBcdTMwOTJcdThBMkRcdTVCOUFcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTMifSwKLQotICAgIHsgRVJfU0NIRU1FX05PVF9DT05GT1JNQU5ULAotICAgICAgICJcdTMwQjlcdTMwQURcdTMwRkNcdTMwRTBcdTMwNENcdTY1NzRcdTU0MDhcdTMwNTdcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIifSwKLQotICAgIHsgRVJfSE9TVF9BRERSRVNTX05PVF9XRUxMRk9STUVELAotICAgICAgICJcdTMwREJcdTMwQjlcdTMwQzhcdTMwNkZcdTY1NzRcdTVGNjJcdTVGMEZcdTMwNkVcdTMwQTJcdTMwQzlcdTMwRUNcdTMwQjlcdTMwNjdcdTMwNkZcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTMifSwKLQotICAgIHsgRVJfUE9SVF9XSEVOX0hPU1RfTlVMTCwKLSAgICAgICAiXHUzMERCXHUzMEI5XHUzMEM4XHUzMDRDbnVsbFx1MzA2RVx1NTgzNFx1NTQwOFx1MzA2Rlx1MzBERFx1MzBGQ1x1MzBDOFx1MzA5Mlx1OEEyRFx1NUI5QVx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MyJ9LAotCi0gICAgeyBFUl9JTlZBTElEX1BPUlQsCi0gICAgICAgIlx1NzEyMVx1NTJCOVx1MzA2QVx1MzBERFx1MzBGQ1x1MzBDOFx1NzU2QVx1NTNGNyJ9LAotCi0gICAgeyBFUl9GUkFHX0ZPUl9HRU5FUklDX1VSSSwKLSAgICAgICAiXHU2QzRFXHU3NTI4VVJJXHUzMDZFXHUzMEQ1XHUzMEU5XHUzMEIwXHUzMEUxXHUzMEYzXHUzMEM4XHUzMDZFXHUzMDdGXHU4QTJEXHU1QjlBXHUzMDY3XHUzMDREXHUzMDdFXHUzMDU5In0sCi0KLSAgICB7IEVSX0ZSQUdfV0hFTl9QQVRIX05VTEwsCi0gICAgICAgIlx1MzBEMVx1MzBCOVx1MzA0Q251bGxcdTMwNkVcdTU4MzRcdTU0MDhcdTMwNkZcdTMwRDVcdTMwRTlcdTMwQjBcdTMwRTFcdTMwRjNcdTMwQzhcdTMwOTJcdThBMkRcdTVCOUFcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTMifSwKLQotICAgIHsgRVJfRlJBR19JTlZBTElEX0NIQVIsCi0gICAgICAgIlx1MzBENVx1MzBFOVx1MzBCMFx1MzBFMVx1MzBGM1x1MzBDOFx1MzA2Qlx1NzEyMVx1NTJCOVx1NjU4N1x1NUI1N1x1MzA0Q1x1NTQyQlx1MzA3RVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OSJ9LAotCi0gICAgeyBFUl9QQVJTRVJfSU5fVVNFLAotICAgICAgIlx1MzBEMVx1MzBGQ1x1MzBCNVx1MzBGQ1x1MzA2Rlx1MzA1OVx1MzA2N1x1MzA2Qlx1NEY3Rlx1NzUyOFx1NEUyRFx1MzA2N1x1MzA1OSJ9LAotCi0gICAgeyBFUl9DQU5OT1RfQ0hBTkdFX1dISUxFX1BBUlNJTkcsCi0gICAgICAiXHU4OUUzXHU2NzkwXHU0RTJEXHUzMDZCezB9IHsxfVx1MzA5Mlx1NTkwOVx1NjZGNFx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MyJ9LAotCi0gICAgeyBFUl9TRUxGX0NBVVNBVElPTl9OT1RfUEVSTUlUVEVELAotICAgICAgIlx1ODFFQVx1NURGMVx1NTM5Rlx1NTZFMFx1MzA2Rlx1OEEzMVx1NTNFRlx1MzA1NVx1MzA4Q1x1MzA3RVx1MzA1Qlx1MzA5MyJ9LAotCi0gICAgeyBFUl9OT19VU0VSSU5GT19JRl9OT19IT1NULAotICAgICAgIlx1MzBEQlx1MzBCOVx1MzBDOFx1MzA0Q1x1NjMwN1x1NUI5QVx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA2QVx1MzA0NFx1NTgzNFx1NTQwOFx1MzA2RlVzZXJpbmZvXHUzMDkyXHU2MzA3XHU1QjlBXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzIn0sCi0KLSAgICB7IEVSX05PX1BPUlRfSUZfTk9fSE9TVCwKLSAgICAgICJcdTMwREJcdTMwQjlcdTMwQzhcdTMwNENcdTYzMDdcdTVCOUFcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwNkFcdTMwNDRcdTU4MzRcdTU0MDhcdTMwNkZcdTMwRERcdTMwRkNcdTMwQzhcdTMwOTJcdTYzMDdcdTVCOUFcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTMifSwKLQotICAgIHsgRVJfTk9fUVVFUllfU1RSSU5HX0lOX1BBVEgsCi0gICAgICAiXHU1NTRGXHU1NDA4XHUzMDVCXHU2NTg3XHU1QjU3XHU1MjE3XHUzMDZGXHUzMEQxXHUzMEI5XHUzMDRBXHUzMDg4XHUzMDczXHU1NTRGXHU1NDA4XHUzMDVCXHU2NTg3XHU1QjU3XHU1MjE3XHU1MTg1XHUzMDZCXHU2MzA3XHU1QjlBXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzIn0sCi0KLSAgICB7IEVSX05PX0ZSQUdNRU5UX1NUUklOR19JTl9QQVRILAotICAgICAgIlx1MzBENVx1MzBFOVx1MzBCMFx1MzBFMVx1MzBGM1x1MzBDOFx1MzA2Rlx1MzBEMVx1MzBCOVx1MzA2OFx1MzBENVx1MzBFOVx1MzBCMFx1MzBFMVx1MzBGM1x1MzBDOFx1MzA2RVx1NEUyMVx1NjVCOVx1MzA2Qlx1NjMwN1x1NUI5QVx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MyJ9LAotCi0gICAgeyBFUl9DQU5OT1RfSU5JVF9VUklfRU1QVFlfUEFSTVMsCi0gICAgICAiVVJJXHUzMDZGXHU3QTdBXHUzMDZFXHUzMEQxXHUzMEU5XHUzMEUxXHUzMEZDXHUzMEJGXHUzMDkyXHU0RjdGXHU3NTI4XHUzMDU3XHUzMDY2XHU1MjFEXHU2NzFGXHU1MzE2XHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzIn0sCi0KLSAgICB7IEVSX01FVEhPRF9OT1RfU1VQUE9SVEVELAotICAgICAgIlx1MzBFMVx1MzBCRFx1MzBDM1x1MzBDOVx1MzA2Rlx1MzA3RVx1MzA2MFx1MzBCNVx1MzBERFx1MzBGQ1x1MzBDOFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5MyAifSwKLQotICAgIHsgRVJfSU5DUlNBWFNSQ0ZJTFRFUl9OT1RfUkVTVEFSVEFCTEUsCi0gICAgICAiSW5jcmVtZW50YWxTQVhTb3VyY2VfRmlsdGVyXHUzMDZGXHU3M0ZFXHU1NzI4XHUzMDZGXHU1MThEXHU4RDc3XHU1MkQ1XHU1M0VGXHU4MEZEXHUzMDY3XHUzMDZGXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzIn0sCi0KLSAgICB7IEVSX1hNTFJEUl9OT1RfQkVGT1JFX1NUQVJUUEFSU0UsCi0gICAgICAiWE1MUmVhZGVyXHUzMDZGc3RhcnRQYXJzZVx1MzBFQVx1MzBBRlx1MzBBOFx1MzBCOVx1MzBDOFx1MzA4OFx1MzA4QVx1NTI0RFx1MzA2Qlx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MyJ9LAotCi0gICAgeyBFUl9BWElTX1RSQVZFUlNFUl9OT1RfU1VQUE9SVEVELAotICAgICAgIlx1OEVGOFx1MzBDOFx1MzBFOVx1MzBEMFx1MzBGQ1x1MzBCNVx1NkE1Rlx1ODBGRFx1MzA2Rlx1MzBCNVx1MzBERFx1MzBGQ1x1MzBDOFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5MzogezB9In0sCi0KLSAgICB7IEVSX0VSUk9SSEFORExFUl9DUkVBVEVEX1dJVEhfTlVMTF9QUklOVFdSSVRFUiwKLSAgICAgICJudWxsIFByaW50V3JpdGVyXHUzMDZCXHUzMDg4XHUzMDYzXHUzMDY2TGlzdGluZ0Vycm9ySGFuZGxlclx1MzA0Q1x1NEY1Q1x1NjIxMFx1MzA1NVx1MzA4Q1x1MzA3RVx1MzA1N1x1MzA1Rlx1MzAwMiJ9LAotCi0gICAgeyBFUl9TWVNURU1JRF9VTktOT1dOLAotICAgICAgIlx1NEUwRFx1NjYwRVx1MzA2QVN5c3RlbUlkIn0sCi0KLSAgICB7IEVSX0xPQ0FUSU9OX1VOS05PV04sCi0gICAgICAiXHUzMEE4XHUzMEU5XHUzMEZDXHUzMDZFXHU1ODM0XHU2MjQwXHUzMDRDXHU0RTBEXHU2NjBFXHUzMDY3XHUzMDU5In0sCi0KLSAgICB7IEVSX1BSRUZJWF9NVVNUX1JFU09MVkUsCi0gICAgICAiXHU2M0E1XHU5ODJEXHU4RjlFXHUzMDZGXHUzMENEXHUzMEZDXHUzMEUwXHUzMEI5XHUzMERBXHUzMEZDXHUzMEI5XHUzMDZCXHU4OUUzXHU2QzdBXHUzMDU1XHUzMDhDXHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5OiB7MH0ifSwKLQotICAgIHsgRVJfQ1JFQVRFRE9DVU1FTlRfTk9UX1NVUFBPUlRFRCwKLSAgICAgICJjcmVhdGVEb2N1bWVudCgpXHUzMDZGWFBhdGhDb250ZXh0XHUzMDY3XHUzMEI1XHUzMEREXHUzMEZDXHUzMEM4XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyIn0sCi0KLSAgICB7IEVSX0NISUxEX0hBU19OT19PV05FUl9ET0NVTUVOVCwKLSAgICAgICJcdTVDNUVcdTYwMjdcdTMwNkVcdTVCNTBcdTMwNkJcdTYyNDBcdTY3MDlcdTgwMDVcdTMwQzlcdTMwQURcdTMwRTVcdTMwRTFcdTMwRjNcdTMwQzhcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIifSwKLQotICAgIHsgRVJfQ0hJTERfSEFTX05PX09XTkVSX0RPQ1VNRU5UX0VMRU1FTlQsCi0gICAgICAiXHU1QzVFXHU2MDI3XHUzMDZFXHU1QjUwXHUzMDZCXHU2MjQwXHU2NzA5XHU4MDA1XHUzMEM5XHUzMEFEXHUzMEU1XHUzMEUxXHUzMEYzXHUzMEM4XHU4OTgxXHU3RDIwXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyIn0sCi0KLSAgICB7IEVSX0NBTlRfT1VUUFVUX1RFWFRfQkVGT1JFX0RPQywKLSAgICAgICJcdThCNjZcdTU0NEE6IFx1MzBDOVx1MzBBRFx1MzBFNVx1MzBFMVx1MzBGM1x1MzBDOFx1ODk4MVx1N0QyMFx1MzA2RVx1NTI0RFx1MzA2Qlx1MzBDNlx1MzBBRFx1MzBCOVx1MzBDOFx1MzA5Mlx1NTFGQVx1NTI5Qlx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMiAgXHU3MTIxXHU4OTk2XHUzMDU3XHUzMDdFXHUzMDU5Li4uIn0sCi0KLSAgICB7IEVSX0NBTlRfSEFWRV9NT1JFX1RIQU5fT05FX1JPT1QsCi0gICAgICAiRE9NXHUzMDZCXHU4OTA3XHU2NTcwXHUzMDZFXHUzMEVCXHUzMEZDXHUzMEM4XHUzMDkyXHU2MzAxXHUzMDY0XHUzMDUzXHUzMDY4XHUzMDZGXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyIn0sCi0KLSAgICB7IEVSX0FSR19MT0NBTE5BTUVfTlVMTCwKLSAgICAgICAiXHU1RjE1XHU2NTcwJ2xvY2FsTmFtZSdcdTMwNkZudWxsXHUzMDY3XHUzMDU5In0sCi0KLSAgICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQSBRTkFNRSBoYXMgdGhlIHN5bnRhY3RpYyBmb3JtIFtOQ05hbWU6XU5DTmFtZQotICAgIC8vIFRoZSBsb2NhbG5hbWUgaXMgdGhlIHBvcnRpb24gYWZ0ZXIgdGhlIG9wdGlvbmFsIGNvbG9uOyB0aGUgbWVzc2FnZSBpbmRpY2F0ZXMKLSAgICAvLyB0aGF0IHRoZXJlIGlzIGEgcHJvYmxlbSB3aXRoIHRoYXQgcGFydCBvZiB0aGUgUU5BTUUuCi0gICAgeyBFUl9BUkdfTE9DQUxOQU1FX0lOVkFMSUQsCi0gICAgICAgIlFOQU1FXHUzMDZFTG9jYWxuYW1lXHUzMDZGXHU2NzA5XHU1MkI5XHUzMDZBTkNOYW1lXHUzMDY3XHUzMDQyXHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5In0sCi0KLSAgICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQSBRTkFNRSBoYXMgdGhlIHN5bnRhY3RpYyBmb3JtIFtOQ05hbWU6XU5DTmFtZQotICAgIC8vIFRoZSBwcmVmaXggaXMgdGhlIHBvcnRpb24gYmVmb3JlIHRoZSBvcHRpb25hbCBjb2xvbjsgdGhlIG1lc3NhZ2UgaW5kaWNhdGVzCi0gICAgLy8gdGhhdCB0aGVyZSBpcyBhIHByb2JsZW0gd2l0aCB0aGF0IHBhcnQgb2YgdGhlIFFOQU1FLgotICAgIHsgRVJfQVJHX1BSRUZJWF9JTlZBTElELAotICAgICAgICJRTkFNRVx1MzA2RVx1NjNBNVx1OTgyRFx1OEY5RVx1MzA2Rlx1NjcwOVx1NTJCOVx1MzA2QU5DTmFtZVx1MzA2N1x1MzA0Mlx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OSJ9LAotCi0gICAgeyBFUl9OQU1FX0NBTlRfU1RBUlRfV0lUSF9DT0xPTiwKLSAgICAgICJcdTU0MERcdTUyNERcdTMwNkVcdTUxNDhcdTk4MkRcdTMwOTJcdTMwQjNcdTMwRURcdTMwRjNcdTMwNkJcdTMwNTlcdTMwOEJcdTMwNTNcdTMwNjhcdTMwNkZcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTMifSwKLQotICAgIHsgIkJBRF9DT0RFIiwgImNyZWF0ZU1lc3NhZ2VcdTMwNkVcdTMwRDFcdTMwRTlcdTMwRTFcdTMwRkNcdTMwQkZcdTMwNENcdTdCQzRcdTU2RjJcdTU5MTZcdTMwNjdcdTMwNTkifSwKLSAgICB7ICJGT1JNQVRfRkFJTEVEIiwgIm1lc3NhZ2VGb3JtYXRcdTMwNkVcdTU0N0NcdTUxRkFcdTMwNTdcdTRFMkRcdTMwNkJcdTRGOEJcdTU5MTZcdTMwNENcdTMwQjlcdTMwRURcdTMwRkNcdTMwNTVcdTMwOENcdTMwN0VcdTMwNTdcdTMwNUYifSwKLSAgICB7ICJsaW5lIiwgIlx1ODg0Q1x1NzU2QVx1NTNGNyJ9LAotICAgIHsgImNvbHVtbiIsIlx1NTIxN1x1NzU2QVx1NTNGNyJ9LAotCi0gICAge0VSX1NFUklBTElaRVJfTk9UX0NPTlRFTlRIQU5ETEVSLAotICAgICAgIlx1MzBCN1x1MzBFQVx1MzBBMlx1MzBFOVx1MzBBNFx1MzBCNlx1MzBGQlx1MzBBRlx1MzBFOVx1MzBCOScnezB9JydcdTMwNkZvcmcueG1sLnNheC5Db250ZW50SGFuZGxlclx1MzA5Mlx1NUI5Rlx1ODhDNVx1MzA1N1x1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMiJ9LAotCi0gICAge0VSX1JFU09VUkNFX0NPVUxEX05PVF9GSU5ELAotICAgICAgIlx1MzBFQVx1MzBCRFx1MzBGQ1x1MzBCOVsgezB9IF1cdTMwNkZcdTg5OEJcdTMwNjRcdTMwNEJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwNjdcdTMwNTdcdTMwNUZcdTMwMDJcbiB7MX0iIH0sCi0KLSAgICB7RVJfUkVTT1VSQ0VfQ09VTERfTk9UX0xPQUQsCi0gICAgICAiXHUzMEVBXHUzMEJEXHUzMEZDXHUzMEI5WyB7MH0gXVx1MzA5Mlx1MzBFRFx1MzBGQ1x1MzBDOVx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzA2N1x1MzA1N1x1MzA1RjogezF9IFxuIHsyfSBcdCB7M30iIH0sCi0KLSAgICB7RVJfQlVGRkVSX1NJWkVfTEVTU1RIQU5fWkVSTywKLSAgICAgICJcdTMwRDBcdTMwQzNcdTMwRDVcdTMwQTFcdTMwRkJcdTMwQjVcdTMwQTRcdTMwQkE8PTAiIH0sCi0KLSAgICB7RVJfSU5WQUxJRF9VVEYxNl9TVVJST0dBVEUsCi0gICAgICAiXHU3MTIxXHU1MkI5XHUzMDZBVVRGLTE2XHUzMEI1XHUzMEVEXHUzMEIyXHUzMEZDXHUzMEM4XHUzMDRDXHU2OTFDXHU1MUZBXHUzMDU1XHUzMDhDXHUzMDdFXHUzMDU3XHUzMDVGOiB7MH1cdTMwMDIiIH0sCi0KLSAgICB7RVJfT0lFUlJPUiwKLSAgICAgICJJT1x1MzBBOFx1MzBFOVx1MzBGQyIgfSwKLQotICAgIHtFUl9JTExFR0FMX0FUVFJJQlVURV9QT1NJVElPTiwKLSAgICAgICJcdTVCNTBcdTMwQ0VcdTMwRkNcdTMwQzlcdTMwNkVcdTVGOENcdTMwN0VcdTMwNUZcdTMwNkZcdTg5ODFcdTdEMjBcdTMwNENcdTc1MUZcdTYyMTBcdTMwNTVcdTMwOENcdTMwOEJcdTUyNERcdTMwNkJcdTVDNUVcdTYwMjd7MH1cdTMwOTJcdThGRkRcdTUyQTBcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDJcdTVDNUVcdTYwMjdcdTMwNkZcdTcxMjFcdTg5OTZcdTMwNTVcdTMwOENcdTMwN0VcdTMwNTlcdTMwMDIifSwKLQotICAgICAgLyoKLSAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3R5bGVzaGVldCBjb250YWluZWQgYSByZWZlcmVuY2UgdG8gYQotICAgICAgICogbmFtZXNwYWNlIHByZWZpeCB0aGF0IHdhcyB1bmRlZmluZWQuICBUaGUgdmFsdWUgb2YgdGhlIHN1YnN0aXR1dGlvbgotICAgICAgICogdGV4dCBpcyB0aGUgbmFtZSBvZiB0aGUgcHJlZml4LgotICAgICAgICovCi0gICAge0VSX05BTUVTUEFDRV9QUkVGSVgsCi0gICAgICAiXHU2M0E1XHU5ODJEXHU4RjlFJyd7MH0nJ1x1MzA2RVx1MzBDRFx1MzBGQ1x1MzBFMFx1MzBCOVx1MzBEQVx1MzBGQ1x1MzBCOVx1MzA0Q1x1NUJBM1x1OEEwMFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMiIgfSwKLSAgICAgIC8qCi0gICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIHJlcG9ydGVkIGlmIHRoZSBzdHlsZXNoZWV0Ci0gICAgICAgKiBiZWluZyBwcm9jZXNzZWQgYXR0ZW1wdGVkIHRvIGNvbnN0cnVjdCBhbiBYTUwgZG9jdW1lbnQgd2l0aCBhbgotICAgICAgICogYXR0cmlidXRlIGluIGEgcGxhY2Ugb3RoZXIgdGhhbiBvbiBhbiBlbGVtZW50LiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgKiBzcGVjaWZpZXMgdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgICAqLwotICAgIHtFUl9TVFJBWV9BVFRSSUJVVEUsCi0gICAgICAiXHU1QzVFXHU2MDI3Jyd7MH0nJ1x1MzA0Q1x1ODk4MVx1N0QyMFx1MzA2RVx1NTkxNlx1NTA3NFx1MzA2Qlx1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMiIgfSwKLQotICAgICAgLyoKLSAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBcyB3aXRoIHRoZSBwcmVjZWRpbmcgbWVzc2FnZSwgYSBuYW1lc3BhY2UKLSAgICAgICAqIGRlY2xhcmF0aW9uIGhhcyB0aGUgZm9ybSBvZiBhbiBhdHRyaWJ1dGUgYW5kIGlzIG9ubHkgcGVybWl0dGVkIHRvCi0gICAgICAgKiBhcHBlYXIgb24gYW4gZWxlbWVudC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCB7MH0gaXMgdGhlIG5hbWVzcGFjZQotICAgICAgICogcHJlZml4IGFuZCB7MX0gaXMgdGhlIFVSSSB0aGF0IHdhcyBiZWluZyB1c2VkIGluIHRoZSBlcnJvbmVvdXMKLSAgICAgICAqIG5hbWVzcGFjZSBkZWNsYXJhdGlvbi4KLSAgICAgICAqLwotICAgIHtFUl9TVFJBWV9OQU1FU1BBQ0UsCi0gICAgICAiXHUzMENEXHUzMEZDXHUzMEUwXHUzMEI5XHUzMERBXHUzMEZDXHUzMEI5XHU1QkEzXHU4QTAwJyd7MH0nJz0nJ3sxfScnXHUzMDRDXHU4OTgxXHU3RDIwXHUzMDZFXHU1OTE2XHU1MDc0XHUzMDZCXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyIiB9LAotCi0gICAge0VSX0NPVUxEX05PVF9MT0FEX1JFU09VUkNFLAotICAgICAgIicnezB9JydcdTMwOTJcdTMwRURcdTMwRkNcdTMwQzlcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwNjdcdTMwNTdcdTMwNUYoQ0xBU1NQQVRIXHUzMDkyXHU3OEJBXHU4QThEXHUzMDU3XHUzMDY2XHUzMDRGXHUzMDYwXHUzMDU1XHUzMDQ0KVx1MzAwMlx1NzNGRVx1NTcyOFx1MzA2Rlx1NTM1OFx1MzA2Qlx1MzBDN1x1MzBENVx1MzBBOVx1MzBFQlx1MzBDOFx1MzA5Mlx1NEY3Rlx1NzUyOFx1MzA1N1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OSJ9LAotCi0gICAgeyBFUl9JTExFR0FMX0NIQVJBQ1RFUiwKLSAgICAgICAiezF9XHUzMDZFXHU2MzA3XHU1QjlBXHUzMDU1XHUzMDhDXHUzMDVGXHU1MUZBXHU1MjlCXHUzMEE4XHUzMEYzXHUzMEIzXHUzMEZDXHUzMEM3XHUzMEEzXHUzMEYzXHUzMEIwXHUzMDY3XHU3OTNBXHUzMDU1XHUzMDhDXHUzMDZBXHUzMDQ0XHU2NTc0XHU2NTcwXHU1MDI0ezB9XHUzMDZFXHU2NTg3XHU1QjU3XHUzMDkyXHU1MUZBXHU1MjlCXHUzMDU3XHUzMDg4XHUzMDQ2XHUzMDY4XHUzMDU3XHUzMDdFXHUzMDU3XHUzMDVGXHUzMDAyIn0sCi0KLSAgICB7RVJfQ09VTERfTk9UX0xPQURfTUVUSE9EX1BST1BFUlRZLAotICAgICAgIlx1NTFGQVx1NTI5Qlx1MzBFMVx1MzBCRFx1MzBDM1x1MzBDOScnezF9JydcdTMwNkVcdTMwRDdcdTMwRURcdTMwRDFcdTMwQzZcdTMwQTNcdTMwRkJcdTMwRDVcdTMwQTFcdTMwQTRcdTMwRUInJ3swfScnXHUzMDkyXHUzMEVEXHUzMEZDXHUzMEM5XHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDY3XHUzMDU3XHUzMDVGKENMQVNTUEFUSFx1MzA5Mlx1NzhCQVx1OEE4RFx1MzA1N1x1MzA2Nlx1MzA0Rlx1MzA2MFx1MzA1NVx1MzA0NCkiIH0KLQotCi0gIH07Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgYXNzb2NpYXRpb24gbGlzdC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgYXNzb2NpYXRpb24gbGlzdC4KLSAgICovCi0KLSAgICBwcm90ZWN0ZWQgT2JqZWN0W11bXSBnZXRDb250ZW50cygpIHsKLSAgICAgICAgcmV0dXJuIGNvbnRlbnRzOwotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvcmVzL1hNTEVycm9yUmVzb3VyY2VzX2tvLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9yZXMvWE1MRXJyb3JSZXNvdXJjZXNfa28uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNDkzNjQ4OC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9yZXMvWE1MRXJyb3JSZXNvdXJjZXNfa28uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQ1MCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzOwotCi0KLWltcG9ydCBqYXZhLnV0aWwuTGlzdFJlc291cmNlQnVuZGxlOwotCi0vKioKLSAqIFNldCB1cCBlcnJvciBtZXNzYWdlcy4KLSAqIFdlIGJ1aWxkIGEgdHdvIGRpbWVuc2lvbmFsIGFycmF5IG9mIG1lc3NhZ2Uga2V5cyBhbmQKLSAqIG1lc3NhZ2Ugc3RyaW5ncy4gSW4gb3JkZXIgdG8gYWRkIGEgbmV3IG1lc3NhZ2UgaGVyZSwKLSAqIHlvdSBuZWVkIHRvIGZpcnN0IGFkZCBhIFN0cmluZyBjb25zdGFudC4gQW5kIHlvdSBuZWVkCi0gKiB0byBlbnRlciBrZXksIHZhbHVlIHBhaXIgYXMgcGFydCBvZiB0aGUgY29udGVudHMKLSAqIGFycmF5LiBZb3UgYWxzbyBuZWVkIHRvIHVwZGF0ZSBNQVhfQ09ERSBmb3IgZXJyb3Igc3RyaW5ncwotICogYW5kIE1BWF9XQVJOSU5HIGZvciB3YXJuaW5ncyAoIE5lZWRlZCBmb3Igb25seSBpbmZvcm1hdGlvbgotICogcHVycG9zZSApCi0gKi8KLXB1YmxpYyBjbGFzcyBYTUxFcnJvclJlc291cmNlc19rbyBleHRlbmRzIExpc3RSZXNvdXJjZUJ1bmRsZQotewotCi0vKgotICogVGhpcyBmaWxlIGNvbnRhaW5zIGVycm9yIGFuZCB3YXJuaW5nIG1lc3NhZ2VzIHJlbGF0ZWQgdG8gWGFsYW4gRXJyb3IKLSAqIEhhbmRsaW5nLgotICoKLSAqICBHZW5lcmFsIG5vdGVzIHRvIHRyYW5zbGF0b3JzOgotICoKLSAqICAxKSBYYWxhbiAob3IgbW9yZSBwcm9wZXJseSwgWGFsYW4taW50ZXJwcmV0aXZlKSBhbmQgWFNMVEMgYXJlIG5hbWVzIG9mCi0gKiAgICAgY29tcG9uZW50cy4KLSAqICAgICBYU0xUIGlzIGFuIGFjcm9ueW0gZm9yICJYTUwgU3R5bGVzaGVldCBMYW5ndWFnZTogVHJhbnNmb3JtYXRpb25zIi4KLSAqICAgICBYU0xUQyBpcyBhbiBhY3JvbnltIGZvciBYU0xUIENvbXBpbGVyLgotICoKLSAqICAyKSBBIHN0eWxlc2hlZXQgaXMgYSBkZXNjcmlwdGlvbiBvZiBob3cgdG8gdHJhbnNmb3JtIGFuIGlucHV0IFhNTCBkb2N1bWVudAotICogICAgIGludG8gYSByZXN1bHRhbnQgWE1MIGRvY3VtZW50IChvciBIVE1MIGRvY3VtZW50IG9yIHRleHQpLiAgVGhlCi0gKiAgICAgc3R5bGVzaGVldCBpdHNlbGYgaXMgZGVzY3JpYmVkIGluIHRoZSBmb3JtIG9mIGFuIFhNTCBkb2N1bWVudC4KLSAqCi0gKiAgMykgQSB0ZW1wbGF0ZSBpcyBhIGNvbXBvbmVudCBvZiBhIHN0eWxlc2hlZXQgdGhhdCBpcyB1c2VkIHRvIG1hdGNoIGEKLSAqICAgICBwYXJ0aWN1bGFyIHBvcnRpb24gb2YgYW4gaW5wdXQgZG9jdW1lbnQgYW5kIHNwZWNpZmllcyB0aGUgZm9ybSBvZiB0aGUKLSAqICAgICBjb3JyZXNwb25kaW5nIHBvcnRpb24gb2YgdGhlIG91dHB1dCBkb2N1bWVudC4KLSAqCi0gKiAgNCkgQW4gZWxlbWVudCBpcyBhIG1hcmstdXAgdGFnIGluIGFuIFhNTCBkb2N1bWVudDsgYW4gYXR0cmlidXRlIGlzIGEKLSAqICAgICBtb2RpZmllciBvbiB0aGUgdGFnLiAgRm9yIGV4YW1wbGUsIGluIDxlbGVtIGF0dHI9J3ZhbCcgYXR0cjI9J3ZhbDInPgotICogICAgICJlbGVtIiBpcyBhbiBlbGVtZW50IG5hbWUsICJhdHRyIiBhbmQgImF0dHIyIiBhcmUgYXR0cmlidXRlIG5hbWVzIHdpdGgKLSAqICAgICB0aGUgdmFsdWVzICJ2YWwiIGFuZCAidmFsMiIsIHJlc3BlY3RpdmVseS4KLSAqCi0gKiAgNSkgQSBuYW1lc3BhY2UgZGVjbGFyYXRpb24gaXMgYSBzcGVjaWFsIGF0dHJpYnV0ZSB0aGF0IGlzIHVzZWQgdG8gYXNzb2NpYXRlCi0gKiAgICAgYSBwcmVmaXggd2l0aCBhIFVSSSAodGhlIG5hbWVzcGFjZSkuICBUaGUgbWVhbmluZ3Mgb2YgZWxlbWVudCBuYW1lcyBhbmQKLSAqICAgICBhdHRyaWJ1dGUgbmFtZXMgdGhhdCB1c2UgdGhhdCBwcmVmaXggYXJlIGRlZmluZWQgd2l0aCByZXNwZWN0IHRvIHRoYXQKLSAqICAgICBuYW1lc3BhY2UuCi0gKgotICogIDYpICJUcmFuc2xldCIgaXMgYW4gaW52ZW50ZWQgdGVybSB0aGF0IGRlc2NyaWJlcyB0aGUgY2xhc3MgZmlsZSB0aGF0Ci0gKiAgICAgcmVzdWx0cyBmcm9tIGNvbXBpbGluZyBhbiBYTUwgc3R5bGVzaGVldCBpbnRvIGEgSmF2YSBjbGFzcy4KLSAqCi0gKiAgNykgWFBhdGggaXMgYSBzcGVjaWZpY2F0aW9uIHRoYXQgZGVzY3JpYmVzIGEgbm90YXRpb24gZm9yIGlkZW50aWZ5aW5nCi0gKiAgICAgbm9kZXMgaW4gYSB0cmVlLXN0cnVjdHVyZWQgcmVwcmVzZW50YXRpb24gb2YgYW4gWE1MIGRvY3VtZW50LiAgQW4KLSAqICAgICBpbnN0YW5jZSBvZiB0aGF0IG5vdGF0aW9uIGlzIHJlZmVycmVkIHRvIGFzIGFuIFhQYXRoIGV4cHJlc3Npb24uCi0gKgotICovCi0KLSAgLyoqIE1heGltdW0gZXJyb3IgbWVzc2FnZXMsIHRoaXMgaXMgbmVlZGVkIHRvIGtlZXAgdHJhY2sgb2YgdGhlIG51bWJlciBvZiBtZXNzYWdlcy4gICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFYX0NPREUgPSA2MTsKLQotICAvKiogTWF4aW11bSB3YXJuaW5ncywgdGhpcyBpcyBuZWVkZWQgdG8ga2VlcCB0cmFjayBvZiB0aGUgbnVtYmVyIG9mIHdhcm5pbmdzLiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVhfV0FSTklORyA9IDA7Ci0KLSAgLyoqIE1heGltdW0gbWlzYyBzdHJpbmdzLiAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BWF9PVEhFUlMgPSA0OwotCi0gIC8qKiBNYXhpbXVtIHRvdGFsIHdhcm5pbmdzIGFuZCBlcnJvciBtZXNzYWdlcy4gICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFYX01FU1NBR0VTID0gTUFYX0NPREUgKyBNQVhfV0FSTklORyArIDE7Ci0KLQotICAvKgotICAgKiBNZXNzYWdlIGtleXMKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQgPSAiRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9PVkVSV1JJVEVfQ0FVU0UgPSAiRVJfQ0FOTk9UX09WRVJXUklURV9DQVVTRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX0RFRkFVTFRfSU1QTCA9ICJFUl9OT19ERUZBVUxUX0lNUEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DSFVOS0VESU5UQVJSQVlfTk9UX1NVUFBPUlRFRCA9ICJFUl9DSFVOS0VESU5UQVJSQVlfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX09GRlNFVF9CSUdHRVJfVEhBTl9TTE9UID0gIkVSX09GRlNFVF9CSUdHRVJfVEhBTl9TTE9UIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09ST1VUSU5FX05PVF9BVkFJTCA9ICJFUl9DT1JPVVRJTkVfTk9UX0FWQUlMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09ST1VUSU5FX0NPX0VYSVQgPSAiRVJfQ09ST1VUSU5FX0NPX0VYSVQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT0pPSU5ST1VUSU5FU0VUX0ZBSUxFRCA9ICJFUl9DT0pPSU5ST1VUSU5FU0VUX0ZBSUxFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPUk9VVElORV9QQVJBTSA9ICJFUl9DT1JPVVRJTkVfUEFSQU0iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QQVJTRVJfRE9URVJNSU5BVEVfQU5TV0VSUyA9ICJFUl9QQVJTRVJfRE9URVJNSU5BVEVfQU5TV0VSUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1BBUlNFX0NBTExfV0hJTEVfUEFSU0lORyA9ICJFUl9OT19QQVJTRV9DQUxMX1dISUxFX1BBUlNJTkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9UWVBFRF9JVEVSQVRPUl9BWElTX05PVF9JTVBMRU1FTlRFRCA9ICJFUl9UWVBFRF9JVEVSQVRPUl9BWElTX05PVF9JTVBMRU1FTlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lURVJBVE9SX0FYSVNfTk9UX0lNUExFTUVOVEVEID0gIkVSX0lURVJBVE9SX0FYSVNfTk9UX0lNUExFTUVOVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSVRFUkFUT1JfQ0xPTkVfTk9UX1NVUFBPUlRFRCA9ICJFUl9JVEVSQVRPUl9DTE9ORV9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5LTk9XTl9BWElTX1RZUEUgPSAiRVJfVU5LTk9XTl9BWElTX1RZUEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9BWElTX05PVF9TVVBQT1JURUQgPSAiRVJfQVhJU19OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fRFRNSURTX0FWQUlMID0gIkVSX05PX0RUTUlEU19BVkFJTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PVF9TVVBQT1JURUQgPSAiRVJfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PREVfTk9OX05VTEwgPSAiRVJfTk9ERV9OT05fTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxEX05PVF9SRVNPTFZFX05PREUgPSAiRVJfQ09VTERfTk9UX1JFU09MVkVfTk9ERSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NUQVJUUEFSU0VfV0hJTEVfUEFSU0lORyA9ICJFUl9TVEFSVFBBUlNFX1dISUxFX1BBUlNJTkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TVEFSVFBBUlNFX05FRURTX1NBWFBBUlNFUiA9ICJFUl9TVEFSVFBBUlNFX05FRURTX1NBWFBBUlNFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxEX05PVF9JTklUX1BBUlNFUiA9ICJFUl9DT1VMRF9OT1RfSU5JVF9QQVJTRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FWENFUFRJT05fQ1JFQVRJTkdfUE9PTCA9ICJFUl9FWENFUFRJT05fQ1JFQVRJTkdfUE9PTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BBVEhfQ09OVEFJTlNfSU5WQUxJRF9FU0NBUEVfU0VRVUVOQ0UgPSAiRVJfUEFUSF9DT05UQUlOU19JTlZBTElEX0VTQ0FQRV9TRVFVRU5DRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NDSEVNRV9SRVFVSVJFRCA9ICJFUl9TQ0hFTUVfUkVRVUlSRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19TQ0hFTUVfSU5fVVJJID0gIkVSX05PX1NDSEVNRV9JTl9VUkkiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19TQ0hFTUVfSU5VUkkgPSAiRVJfTk9fU0NIRU1FX0lOVVJJIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUEFUSF9JTlZBTElEX0NIQVIgPSAiRVJfUEFUSF9JTlZBTElEX0NIQVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TQ0hFTUVfRlJPTV9OVUxMX1NUUklORyA9ICJFUl9TQ0hFTUVfRlJPTV9OVUxMX1NUUklORyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NDSEVNRV9OT1RfQ09ORk9STUFOVCA9ICJFUl9TQ0hFTUVfTk9UX0NPTkZPUk1BTlQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9IT1NUX0FERFJFU1NfTk9UX1dFTExGT1JNRUQgPSAiRVJfSE9TVF9BRERSRVNTX05PVF9XRUxMRk9STUVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUE9SVF9XSEVOX0hPU1RfTlVMTCA9ICJFUl9QT1JUX1dIRU5fSE9TVF9OVUxMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9QT1JUID0gIkVSX0lOVkFMSURfUE9SVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZSQUdfRk9SX0dFTkVSSUNfVVJJID0iRVJfRlJBR19GT1JfR0VORVJJQ19VUkkiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GUkFHX1dIRU5fUEFUSF9OVUxMID0gIkVSX0ZSQUdfV0hFTl9QQVRIX05VTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GUkFHX0lOVkFMSURfQ0hBUiA9ICJFUl9GUkFHX0lOVkFMSURfQ0hBUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BBUlNFUl9JTl9VU0UgPSAiRVJfUEFSU0VSX0lOX1VTRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9DSEFOR0VfV0hJTEVfUEFSU0lORyA9ICJFUl9DQU5OT1RfQ0hBTkdFX1dISUxFX1BBUlNJTkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TRUxGX0NBVVNBVElPTl9OT1RfUEVSTUlUVEVEID0gIkVSX1NFTEZfQ0FVU0FUSU9OX05PVF9QRVJNSVRURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19VU0VSSU5GT19JRl9OT19IT1NUID0gIkVSX05PX1VTRVJJTkZPX0lGX05PX0hPU1QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19QT1JUX0lGX05PX0hPU1QgPSAiRVJfTk9fUE9SVF9JRl9OT19IT1NUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fUVVFUllfU1RSSU5HX0lOX1BBVEggPSAiRVJfTk9fUVVFUllfU1RSSU5HX0lOX1BBVEgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19GUkFHTUVOVF9TVFJJTkdfSU5fUEFUSCA9ICJFUl9OT19GUkFHTUVOVF9TVFJJTkdfSU5fUEFUSCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9JTklUX1VSSV9FTVBUWV9QQVJNUyA9ICJFUl9DQU5OT1RfSU5JVF9VUklfRU1QVFlfUEFSTVMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9NRVRIT0RfTk9UX1NVUFBPUlRFRCA9IkVSX01FVEhPRF9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5DUlNBWFNSQ0ZJTFRFUl9OT1RfUkVTVEFSVEFCTEUgPSAiRVJfSU5DUlNBWFNSQ0ZJTFRFUl9OT1RfUkVTVEFSVEFCTEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YTUxSRFJfTk9UX0JFRk9SRV9TVEFSVFBBUlNFID0gIkVSX1hNTFJEUl9OT1RfQkVGT1JFX1NUQVJUUEFSU0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9BWElTX1RSQVZFUlNFUl9OT1RfU1VQUE9SVEVEID0gIkVSX0FYSVNfVFJBVkVSU0VSX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FUlJPUkhBTkRMRVJfQ1JFQVRFRF9XSVRIX05VTExfUFJJTlRXUklURVIgPSAiRVJfRVJST1JIQU5ETEVSX0NSRUFURURfV0lUSF9OVUxMX1BSSU5UV1JJVEVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU1lTVEVNSURfVU5LTk9XTiA9ICJFUl9TWVNURU1JRF9VTktOT1dOIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTE9DQVRJT05fVU5LTk9XTiA9ICJFUl9MT0NBVElPTl9VTktOT1dOIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJFRklYX01VU1RfUkVTT0xWRSA9ICJFUl9QUkVGSVhfTVVTVF9SRVNPTFZFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ1JFQVRFRE9DVU1FTlRfTk9UX1NVUFBPUlRFRCA9ICJFUl9DUkVBVEVET0NVTUVOVF9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0hJTERfSEFTX05PX09XTkVSX0RPQ1VNRU5UID0gIkVSX0NISUxEX0hBU19OT19PV05FUl9ET0NVTUVOVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NISUxEX0hBU19OT19PV05FUl9ET0NVTUVOVF9FTEVNRU5UID0gIkVSX0NISUxEX0hBU19OT19PV05FUl9ET0NVTUVOVF9FTEVNRU5UIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9PVVRQVVRfVEVYVF9CRUZPUkVfRE9DID0gIkVSX0NBTlRfT1VUUFVUX1RFWFRfQkVGT1JFX0RPQyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfSEFWRV9NT1JFX1RIQU5fT05FX1JPT1QgPSAiRVJfQ0FOVF9IQVZFX01PUkVfVEhBTl9PTkVfUk9PVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FSR19MT0NBTE5BTUVfTlVMTCA9ICJFUl9BUkdfTE9DQUxOQU1FX05VTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9BUkdfTE9DQUxOQU1FX0lOVkFMSUQgPSAiRVJfQVJHX0xPQ0FMTkFNRV9JTlZBTElEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQVJHX1BSRUZJWF9JTlZBTElEID0gIkVSX0FSR19QUkVGSVhfSU5WQUxJRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05BTUVfQ0FOVF9TVEFSVF9XSVRIX0NPTE9OID0gIkVSX05BTUVfQ0FOVF9TVEFSVF9XSVRIX0NPTE9OIjsKLQotICAvLyBNZXNzYWdlIGtleXMgdXNlZCBieSB0aGUgc2VyaWFsaXplcgotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SRVNPVVJDRV9DT1VMRF9OT1RfRklORCA9ICJFUl9SRVNPVVJDRV9DT1VMRF9OT1RfRklORCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1JFU09VUkNFX0NPVUxEX05PVF9MT0FEID0gIkVSX1JFU09VUkNFX0NPVUxEX05PVF9MT0FEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQlVGRkVSX1NJWkVfTEVTU1RIQU5fWkVSTyA9ICJFUl9CVUZGRVJfU0laRV9MRVNTVEhBTl9aRVJPIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9VVEYxNl9TVVJST0dBVEUgPSAiRVJfSU5WQUxJRF9VVEYxNl9TVVJST0dBVEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9PSUVSUk9SID0gIkVSX09JRVJST1IiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OQU1FU1BBQ0VfUFJFRklYID0gIkVSX05BTUVTUEFDRV9QUkVGSVgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TVFJBWV9BVFRSSUJVVEUgPSAiRVJfU1RSQVlfQVRUSVJCVVRFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU1RSQVlfTkFNRVNQQUNFID0gIkVSX1NUUkFZX05BTUVTUEFDRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxEX05PVF9MT0FEX1JFU09VUkNFID0gIkVSX0NPVUxEX05PVF9MT0FEX1JFU09VUkNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTERfTk9UX0xPQURfTUVUSE9EX1BST1BFUlRZID0gIkVSX0NPVUxEX05PVF9MT0FEX01FVEhPRF9QUk9QRVJUWSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NFUklBTElaRVJfTk9UX0NPTlRFTlRIQU5ETEVSID0gIkVSX1NFUklBTElaRVJfTk9UX0NPTlRFTlRIQU5ETEVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSUxMRUdBTF9BVFRSSUJVVEVfUE9TSVRJT04gPSAiRVJfSUxMRUdBTF9BVFRSSUJVVEVfUE9TSVRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTExFR0FMX0NIQVJBQ1RFUiA9ICJFUl9JTExFR0FMX0NIQVJBQ1RFUiI7Ci0KLSAgLyoKLSAgICogTm93IGZpbGwgaW4gdGhlIG1lc3NhZ2UgdGV4dC4KLSAgICogVGhlbiBmaWxsIGluIHRoZSBtZXNzYWdlIHRleHQgZm9yIHRoYXQgbWVzc2FnZSBjb2RlIGluIHRoZQotICAgKiBhcnJheS4gVXNlIHRoZSBuZXcgZXJyb3IgY29kZSBhcyB0aGUgaW5kZXggaW50byB0aGUgYXJyYXkuCi0gICAqLwotCi0gIC8vIEVycm9yIG1lc3NhZ2VzLi4uCi0KLSAgLyoqIFRoZSBsb29rdXAgdGFibGUgZm9yIGVycm9yIG1lc3NhZ2VzLiAgICovCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIE9iamVjdFtdW10gY29udGVudHMgPSB7Ci0KLSAgLyoqIEVycm9yIG1lc3NhZ2UgSUQgdGhhdCBoYXMgYSBudWxsIG1lc3NhZ2UsIGJ1dCB0YWtlcyBpbiBhIHNpbmdsZSBvYmplY3QuICAgICovCi0gICAgeyJFUjAwMDAiICwgInswfSIgfSwKLQotICAgIHsgRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCwKLSAgICAgICJcdUQ1NjhcdUMyMThcdUFDMDAgXHVDOUMwXHVDNkQwXHVCNDE4XHVDOUMwIFx1QzU0QVx1QzJCNVx1QjJDOFx1QjJFNCEifSwKLQotICAgIHsgRVJfQ0FOTk9UX09WRVJXUklURV9DQVVTRSwKLSAgICAgICJcdUM2RDBcdUM3NzhcdUM3NDQgXHVBQ0I5XHVDQ0QwIFx1QzRGOCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBFUl9OT19ERUZBVUxUX0lNUEwsCi0gICAgICAiXHVBRTMwXHVCQ0Y4IFx1QUQ2Q1x1RDYwNFx1Qzc0NCBcdUNDM0VcdUM3NDQgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4gIn0sCi0KLSAgICB7IEVSX0NIVU5LRURJTlRBUlJBWV9OT1RfU1VQUE9SVEVELAotICAgICAgIkNodW5rZWRJbnRBcnJheSh7MH0pXHVCMjk0IFx1RDYwNFx1QzdBQyBcdUM5QzBcdUM2RDBcdUI0MThcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBFUl9PRkZTRVRfQklHR0VSX1RIQU5fU0xPVCwKLSAgICAgICJcdUM2MjRcdUQ1MDRcdUMxNEJcdUM3NzQgXHVDMkFDXHVCODZGXHVCQ0Y0XHVCMkU0IFx1RDA3RFx1QjJDOFx1QjJFNC4ifSwKLQotICAgIHsgRVJfQ09ST1VUSU5FX05PVF9BVkFJTCwKLSAgICAgICJDb3JvdXRpbmVcdUM3NDQgXHVDMEFDXHVDNkE5XHVENTYwIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuIElEPXswfSJ9LAotCi0gICAgeyBFUl9DT1JPVVRJTkVfQ09fRVhJVCwKLSAgICAgICJDb3JvdXRpbmVNYW5hZ2VyXHVBQzAwIGNvX2V4aXQoKSBcdUM2OTRcdUNDQURcdUM3NDQgXHVDMjE4XHVDMkUwXHVENTg4XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBFUl9DT0pPSU5ST1VUSU5FU0VUX0ZBSUxFRCwKLSAgICAgICJjb19qb2luQ29yb3V0aW5lU2V0KClcdUI5N0MgXHVDMkU0XHVEMzI4XHVENTg4XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBFUl9DT1JPVVRJTkVfUEFSQU0sCi0gICAgICAiQ29yb3V0aW5lIFx1QjlFNFx1QUMxQ1x1QkNDMFx1QzIxOCBcdUM2MjRcdUI5NTgoezB9KSJ9LAotCi0gICAgeyBFUl9QQVJTRVJfRE9URVJNSU5BVEVfQU5TV0VSUywKLSAgICAgICJcblx1QzYwOFx1QzBDMVx1Q0U1OCBcdUM1NEFcdUM3NDAgXHVDNjI0XHVCOTU4OiBcdUFENkNcdUJCMzggXHVCRDg0XHVDMTFEXHVBRTMwIGRvVGVybWluYXRlXHVBQzAwIHswfVx1QzVEMCBcdUM3NTFcdUIyRjVcdUQ1NjlcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICB7IEVSX05PX1BBUlNFX0NBTExfV0hJTEVfUEFSU0lORywKLSAgICAgICJcdUFENkNcdUJCMzggXHVCRDg0XHVDMTFEIFx1QzkxMSBwYXJzZVx1Qjk3QyBcdUQ2MzhcdUNEOUNcdUQ1NjAgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAgIHsgRVJfVFlQRURfSVRFUkFUT1JfQVhJU19OT1RfSU1QTEVNRU5URUQsCi0gICAgICAiXHVDNjI0XHVCOTU4OiB7MH0gXHVDRDk1XHVDNUQwIFx1QjMwMFx1RDU3NCBcdUM3ODVcdUI4MjVcdUI0MUMgXHVDNzc0XHVEMTMwXHVCODA4XHVDNzc0XHVEMTMwXHVBQzAwIFx1QUQ2Q1x1RDYwNFx1QjQxOFx1QzlDMCBcdUM1NEFcdUM1NThcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICB7IEVSX0lURVJBVE9SX0FYSVNfTk9UX0lNUExFTUVOVEVELAotICAgICAgIlx1QzYyNFx1Qjk1ODogezB9IFx1Q0Q5NVx1QzVEMCBcdUIzMDBcdUQ1NUMgXHVDNzc0XHVEMTMwXHVCODA4XHVDNzc0XHVEMTMwXHVBQzAwIFx1QUQ2Q1x1RDYwNFx1QjQxOFx1QzlDMCBcdUM1NEFcdUM1NThcdUMyQjVcdUIyQzhcdUIyRTQuICJ9LAotCi0gICAgeyBFUl9JVEVSQVRPUl9DTE9ORV9OT1RfU1VQUE9SVEVELAotICAgICAgIlx1Qzc3NFx1RDEzMFx1QjgwOFx1Qzc3NFx1RDEzMCBcdUJDRjVcdUM4MUNcdUIyOTQgXHVDOUMwXHVDNkQwXHVCNDE4XHVDOUMwIFx1QzU0QVx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAgIHsgRVJfVU5LTk9XTl9BWElTX1RZUEUsCi0gICAgICAiXHVDNTRDIFx1QzIxOCBcdUM1QzZcdUIyOTQgXHVDRDk1IFx1QzIxQ1x1RDY4QyBcdUM3MjBcdUQ2MTU6IHswfSJ9LAotCi0gICAgeyBFUl9BWElTX05PVF9TVVBQT1JURUQsCi0gICAgICAiXHVDRDk1IFx1QzIxQ1x1RDY1OFx1QUUzMFx1QUMwMCBcdUM5QzBcdUM2RDBcdUI0MThcdUM5QzAgXHVDNTRBXHVDNzRDOiB7MH0ifSwKLQotICAgIHsgRVJfTk9fRFRNSURTX0FWQUlMLAotICAgICAgIlx1QjM1NCBcdUM3NzRcdUMwQzEgXHVDMEFDXHVDNkE5IFx1QUMwMFx1QjJBNVx1RDU1QyBEVE0gSURcdUFDMDAgXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBFUl9OT1RfU1VQUE9SVEVELAotICAgICAgIlx1QzlDMFx1QzZEMFx1QjQxOFx1QzlDMCBcdUM1NEFcdUM3NEM6IHswfSJ9LAotCi0gICAgeyBFUl9OT0RFX05PTl9OVUxMLAotICAgICAgIlx1QjE3OFx1QjREQ1x1QjI5NCBnZXREVE1IYW5kbGVGcm9tTm9kZVx1QzVEMCBcdUIzMDBcdUQ1NzQgXHVCMTEwXHVDNzc0IFx1QzU0NFx1QjJDOFx1QzVCNFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICB7IEVSX0NPVUxEX05PVF9SRVNPTFZFX05PREUsCi0gICAgICAiXHVCMTc4XHVCNERDXHVCOTdDIFx1RDU3OFx1QjRFNFx1Qjg1QyBcdUJEODRcdUMxMURcdUQ1NjAgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAgIHsgRVJfU1RBUlRQQVJTRV9XSElMRV9QQVJTSU5HLAotICAgICAgICJcdUFENkNcdUJCMzggXHVCRDg0XHVDMTFEIFx1QzkxMSBzdGFydFBhcnNlXHVCOTdDIFx1RDYzOFx1Q0Q5Q1x1RDU2MCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBFUl9TVEFSVFBBUlNFX05FRURTX1NBWFBBUlNFUiwKLSAgICAgICAic3RhcnRQYXJzZVx1QzVEMFx1QjI5NCBcdUIxMTBcdUM3NzQgXHVDNTQ0XHVCMkNDIFNBWFBhcnNlclx1QUMwMCBcdUQ1NDRcdUM2OTRcdUQ1NjlcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICB7IEVSX0NPVUxEX05PVF9JTklUX1BBUlNFUiwKLSAgICAgICAiXHVBRDZDXHVCQjM4IFx1QkQ4NFx1QzExRFx1QUUzMFx1Qjk3QyBcdUNEMDhcdUFFMzBcdUQ2NTRcdUQ1NjAgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAgIHsgRVJfRVhDRVBUSU9OX0NSRUFUSU5HX1BPT0wsCi0gICAgICAgIlx1RDQ4MFx1QzVEMCBcdUIzMDBcdUQ1NUMgXHVDMEM4IFx1Qzc3OFx1QzJBNFx1RDEzNFx1QzJBNFx1Qjk3QyBcdUMwRERcdUMxMzFcdUQ1NThcdUIyOTQgXHVDOTExIFx1QzYwOFx1QzY3OFx1QzBBQ1x1RDU2RFx1Qzc3NCBcdUJDMUNcdUMwRERcdUQ1ODhcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICB7IEVSX1BBVEhfQ09OVEFJTlNfSU5WQUxJRF9FU0NBUEVfU0VRVUVOQ0UsCi0gICAgICAgIlx1QUNCRFx1Qjg1Q1x1QzVEMCBcdUJEODBcdUM4MDFcdUQ1NjlcdUQ1NUMgXHVDNzc0XHVDMkE0XHVDRjAwXHVDNzc0XHVENTA0IFx1QzJEQ1x1RDAwMFx1QzJBNFx1QUMwMCBcdUQzRUNcdUQ1NjhcdUI0MThcdUM1QjQgXHVDNzg4XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBFUl9TQ0hFTUVfUkVRVUlSRUQsCi0gICAgICAgIlx1Q0NCNFx1QUNDNFx1QUMwMCBcdUQ1NDRcdUM2OTRcdUQ1NjlcdUIyQzhcdUIyRTQhIn0sCi0KLSAgICB7IEVSX05PX1NDSEVNRV9JTl9VUkksCi0gICAgICAgIlVSSVx1QzVEMFx1QzExQyBcdUNDQjRcdUFDQzRcdUI5N0MgXHVDQzNFXHVDNzQ0IFx1QzIxOCBcdUM1QzZcdUM3NEM6IHswfSJ9LAotCi0gICAgeyBFUl9OT19TQ0hFTUVfSU5VUkksCi0gICAgICAgIlVSSVx1QzVEMFx1QzExQyBcdUNDQjRcdUFDQzRcdUI5N0MgXHVDQzNFXHVDNzQ0IFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICB7IEVSX1BBVEhfSU5WQUxJRF9DSEFSLAotICAgICAgICJcdUFDQkRcdUI4NUNcdUM1RDAgXHVCRDgwXHVDODAxXHVENTY5XHVENTVDIFx1QkIzOFx1Qzc5MFx1QUMwMCBcdUQzRUNcdUQ1NjhcdUI0Mjg6IHswfSJ9LAotCi0gICAgeyBFUl9TQ0hFTUVfRlJPTV9OVUxMX1NUUklORywKLSAgICAgICAiXHVCMTEwIFx1QkIzOFx1Qzc5MFx1QzVGNFx1QzVEMFx1QzExQyBcdUNDQjRcdUFDQzRcdUI5N0MgXHVDMTI0XHVDODE1XHVENTYwIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICB7IEVSX1NDSEVNRV9OT1RfQ09ORk9STUFOVCwKLSAgICAgICAiXHVDQ0I0XHVBQ0M0XHVBQzAwIFx1Qzc3Q1x1Q0U1OFx1RDU1OFx1QzlDMCBcdUM1NEFcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICB7IEVSX0hPU1RfQUREUkVTU19OT1RfV0VMTEZPUk1FRCwKLSAgICAgICAiXHVENjM4XHVDMkE0XHVEMkI4XHVBQzAwIFx1QzY0NFx1QzgwNFx1RDU1QyBcdUM4RkNcdUMxOENcdUFDMDAgXHVDNTQ0XHVCMkQ5XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBFUl9QT1JUX1dIRU5fSE9TVF9OVUxMLAotICAgICAgICJcdUQ2MzhcdUMyQTRcdUQyQjhcdUFDMDAgXHVCMTEwXHVDNzdDIFx1QUNCRFx1QzZCMCBcdUQzRUNcdUQyQjhcdUI5N0MgXHVDMTI0XHVDODE1XHVENTYwIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICB7IEVSX0lOVkFMSURfUE9SVCwKLSAgICAgICAiXHVEM0VDXHVEMkI4IFx1QkM4OFx1RDYzOFx1QUMwMCBcdUJEODBcdUM4MDFcdUQ1NjlcdUQ1NjlcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICB7IEVSX0ZSQUdfRk9SX0dFTkVSSUNfVVJJLAotICAgICAgICJcdUM3N0NcdUJDMTggVVJJXHVDNUQwIFx1QjMwMFx1RDU3NFx1QzExQ1x1QjlDQyBcdUJEODBcdUJEODRcdUM3NDQgXHVDMTI0XHVDODE1XHVENTYwIFx1QzIxOCBcdUM3ODhcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICB7IEVSX0ZSQUdfV0hFTl9QQVRIX05VTEwsCi0gICAgICAgIlx1QUNCRFx1Qjg1Q1x1QUMwMCBcdUIxMTBcdUM3N0MgXHVBQ0JEXHVDNkIwIFx1QkQ4MFx1QkQ4NFx1Qzc0NCBcdUMxMjRcdUM4MTVcdUQ1NjAgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAgIHsgRVJfRlJBR19JTlZBTElEX0NIQVIsCi0gICAgICAgIlx1QkQ4MFx1QkQ4NFx1QzVEMCBcdUJEODBcdUM4MDFcdUQ1NjlcdUQ1NUMgXHVCQjM4XHVDNzkwXHVBQzAwIFx1RDNFQ1x1RDU2OFx1QjQxOFx1QzVCNCBcdUM3ODhcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICB7IEVSX1BBUlNFUl9JTl9VU0UsCi0gICAgICAiXHVBRDZDXHVCQjM4IFx1QkQ4NFx1QzExRFx1QUUzMFx1QUMwMCBcdUM3NzRcdUJCRjggXHVDMEFDXHVDNkE5XHVCNDE4XHVBQ0UwIFx1Qzc4OFx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAgIHsgRVJfQ0FOTk9UX0NIQU5HRV9XSElMRV9QQVJTSU5HLAotICAgICAgIlx1QUQ2Q1x1QkIzOCBcdUJEODRcdUMxMUQgXHVDOTExIHswfSB7MX1cdUM3NDQoXHVCOTdDKSBcdUJDQzBcdUFDQkRcdUQ1NjAgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAgIHsgRVJfU0VMRl9DQVVTQVRJT05fTk9UX1BFUk1JVFRFRCwKLSAgICAgICJcdUM3OTBcdUNDQjQgXHVDNzc4XHVBQ0ZDIFx1QUQwMFx1QUNDNFx1QjI5NCBcdUQ1QzhcdUM2QTlcdUI0MThcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBFUl9OT19VU0VSSU5GT19JRl9OT19IT1NULAotICAgICAgIlx1RDYzOFx1QzJBNFx1RDJCOFx1Qjk3QyBcdUM5QzBcdUM4MTVcdUQ1NThcdUM5QzAgXHVDNTRBXHVDNzQwIFx1QUNCRFx1QzZCMFx1QzVEMFx1QjI5NCBVc2VyaW5mb1x1Qjk3QyBcdUM5QzBcdUM4MTVcdUQ1NjAgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAgIHsgRVJfTk9fUE9SVF9JRl9OT19IT1NULAotICAgICAgIlx1RDYzOFx1QzJBNFx1RDJCOFx1Qjk3QyBcdUM5QzBcdUM4MTVcdUQ1NThcdUM5QzAgXHVDNTRBXHVDNzQwIFx1QUNCRFx1QzZCMFx1QzVEMFx1QjI5NCBcdUQzRUNcdUQyQjhcdUI5N0MgXHVDOUMwXHVDODE1XHVENTYwIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICB7IEVSX05PX1FVRVJZX1NUUklOR19JTl9QQVRILAotICAgICAgIlx1QUNCRFx1Qjg1QyBcdUJDMEYgXHVDOUM4XHVDNzU4IFx1QkIzOFx1Qzc5MFx1QzVGNFx1QzVEMCBcdUM5QzhcdUM3NTggXHVCQjM4XHVDNzkwXHVDNUY0XHVDNzQ0IFx1QzlDMFx1QzgxNVx1RDU2MCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBFUl9OT19GUkFHTUVOVF9TVFJJTkdfSU5fUEFUSCwKLSAgICAgICJcdUFDQkRcdUI4NUNcdUM2NDAgXHVCRDgwXHVCRDg0XHVDNUQwIFx1QkFBOFx1QjQ1MCBcdUJEODBcdUJEODRcdUM3NDQgXHVDOUMwXHVDODE1XHVENTYwIFx1QzIxOFx1QjI5NCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICB7IEVSX0NBTk5PVF9JTklUX1VSSV9FTVBUWV9QQVJNUywKLSAgICAgICJcdUJFNDggXHVCOUU0XHVBQzFDXHVCQ0MwXHVDMjE4XHVCODVDIFVSSVx1Qjk3QyBcdUNEMDhcdUFFMzBcdUQ2NTRcdUQ1NjAgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAgIHsgRVJfTUVUSE9EX05PVF9TVVBQT1JURUQsCi0gICAgICAiXHVCQTU0XHVDMThDXHVCNERDXHVBQzAwIFx1QzU0NFx1QzlDMSBcdUM5QzBcdUM2RDBcdUI0MThcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0LiAifSwKLQotICAgIHsgRVJfSU5DUlNBWFNSQ0ZJTFRFUl9OT1RfUkVTVEFSVEFCTEUsCi0gICAgICAiXHVENjA0XHVDN0FDIEluY3JlbWVudGFsU0FYU291cmNlX0ZpbHRlclx1Qjk3QyBcdUM3QUNcdUMyRENcdUM3OTFcdUQ1NjAgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAgIHsgRVJfWE1MUkRSX05PVF9CRUZPUkVfU1RBUlRQQVJTRSwKLSAgICAgICJzdGFydFBhcnNlIFx1QzY5NFx1Q0NBRCBcdUM4MDRcdUM1RDAgWE1MUmVhZGVyXHVBQzAwIFx1QzJFNFx1RDU4OVx1QjQxOFx1QzlDMCBcdUM1NEFcdUM1NThcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICB7IEVSX0FYSVNfVFJBVkVSU0VSX05PVF9TVVBQT1JURUQsCi0gICAgICAiXHVDRDk1IFx1QzIxQ1x1RDY1OFx1QUUzMFx1QUMwMCBcdUM5QzBcdUM2RDBcdUI0MThcdUM5QzAgXHVDNTRBXHVDNzRDOiB7MH0ifSwKLQotICAgIHsgRVJfRVJST1JIQU5ETEVSX0NSRUFURURfV0lUSF9OVUxMX1BSSU5UV1JJVEVSLAotICAgICAgIlx1QjExMCBQcmludFdyaXRlclx1Qjg1QyBMaXN0aW5nRXJyb3JIYW5kbGVyXHVBQzAwIFx1QzBERFx1QzEzMVx1QjQxOFx1QzVDOFx1QzJCNVx1QjJDOFx1QjJFNCEifSwKLQotICAgIHsgRVJfU1lTVEVNSURfVU5LTk9XTiwKLSAgICAgICJTeXN0ZW1JZFx1Qjk3QyBcdUM1NEMgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAgIHsgRVJfTE9DQVRJT05fVU5LTk9XTiwKLSAgICAgICJcdUM2MjRcdUI5NTggXHVDNzA0XHVDRTU4XHVCOTdDIFx1QzU0QyBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgeyBFUl9QUkVGSVhfTVVTVF9SRVNPTFZFLAotICAgICAgIlx1QzgxMVx1QjQ1MFx1QzVCNFx1QjI5NCBcdUIxMjRcdUM3ODRcdUMyQTRcdUQzOThcdUM3NzRcdUMyQTRcdUI4NUMgXHVCRDg0XHVDMTFEXHVCNDE4XHVDNUI0XHVDNTdDIFx1RDU2ODogezB9In0sCi0KLSAgICB7IEVSX0NSRUFURURPQ1VNRU5UX05PVF9TVVBQT1JURUQsCi0gICAgICAiWFBhdGhDb250ZXh0XHVDNUQwXHVDMTFDXHVCMjk0IGNyZWF0ZURvY3VtZW50KClcdUFDMDAgXHVDOUMwXHVDNkQwXHVCNDE4XHVDOUMwIFx1QzU0QVx1QzJCNVx1QjJDOFx1QjJFNCEifSwKLQotICAgIHsgRVJfQ0hJTERfSEFTX05PX09XTkVSX0RPQ1VNRU5ULAotICAgICAgIlx1QzE4RFx1QzEzMSBcdUQ1NThcdUM3MDRcdUM1RDAgXHVDMThDXHVDNzIwXHVDNzkwIFx1QkIzOFx1QzExQ1x1QUMwMCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQhIn0sCi0KLSAgICB7IEVSX0NISUxEX0hBU19OT19PV05FUl9ET0NVTUVOVF9FTEVNRU5ULAotICAgICAgIlx1QzE4RFx1QzEzMSBcdUQ1NThcdUM3MDRcdUM1RDAgXHVDMThDXHVDNzIwXHVDNzkwIFx1QkIzOFx1QzExQyBcdUM2OTRcdUMxOENcdUFDMDAgXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0ISJ9LAotCi0gICAgeyBFUl9DQU5UX09VVFBVVF9URVhUX0JFRk9SRV9ET0MsCi0gICAgICAiXHVBQ0JEXHVBQ0UwOiBcdUJCMzhcdUMxMUMgXHVDNjk0XHVDMThDIFx1QzU1RVx1QzVEMCBcdUQxNERcdUMyQTRcdUQyQjhcdUI5N0MgXHVDRDlDXHVCODI1XHVENTYwIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQhIFx1QkIzNFx1QzJEQ1x1RDU1OFx1QjI5NCBcdUM5MTEuLi4ifSwKLQotICAgIHsgRVJfQ0FOVF9IQVZFX01PUkVfVEhBTl9PTkVfUk9PVCwKLSAgICAgICJET01cdUM1RDBcdUMxMUMgXHVCOEU4XHVEMkI4XHVCOTdDIFx1QjQ1MCBcdUFDMUMgXHVDNzc0XHVDMEMxIFx1QzBBQ1x1QzZBOVx1RDU2MCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0ISJ9LAotCi0gICAgeyBFUl9BUkdfTE9DQUxOQU1FX05VTEwsCi0gICAgICAgIidsb2NhbE5hbWUnIFx1Qzc3OFx1QzIxOFx1QUMwMCBcdUIxMTBcdUM3ODVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQSBRTkFNRSBoYXMgdGhlIHN5bnRhY3RpYyBmb3JtIFtOQ05hbWU6XU5DTmFtZQotICAgIC8vIFRoZSBsb2NhbG5hbWUgaXMgdGhlIHBvcnRpb24gYWZ0ZXIgdGhlIG9wdGlvbmFsIGNvbG9uOyB0aGUgbWVzc2FnZSBpbmRpY2F0ZXMKLSAgICAvLyB0aGF0IHRoZXJlIGlzIGEgcHJvYmxlbSB3aXRoIHRoYXQgcGFydCBvZiB0aGUgUU5BTUUuCi0gICAgeyBFUl9BUkdfTE9DQUxOQU1FX0lOVkFMSUQsCi0gICAgICAgIlFOQU1FXHVDNzU4IExvY2FsbmFtZVx1Qzc0MCBcdUM4MDFcdUQ1NjlcdUQ1NUMgTkNOYW1lXHVDNzc0XHVDNUI0XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4ifSwKLQotICAgIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBIFFOQU1FIGhhcyB0aGUgc3ludGFjdGljIGZvcm0gW05DTmFtZTpdTkNOYW1lCi0gICAgLy8gVGhlIHByZWZpeCBpcyB0aGUgcG9ydGlvbiBiZWZvcmUgdGhlIG9wdGlvbmFsIGNvbG9uOyB0aGUgbWVzc2FnZSBpbmRpY2F0ZXMKLSAgICAvLyB0aGF0IHRoZXJlIGlzIGEgcHJvYmxlbSB3aXRoIHRoYXQgcGFydCBvZiB0aGUgUU5BTUUuCi0gICAgeyBFUl9BUkdfUFJFRklYX0lOVkFMSUQsCi0gICAgICAgIlFOQU1FXHVDNzU4IFx1QzgxMVx1QjQ1MFx1QzVCNFx1QjI5NCBcdUM4MDFcdUQ1NjlcdUQ1NUMgTkNOYW1lXHVDNzc0XHVDNUI0XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNC4ifSwKLQotICAgIHsgRVJfTkFNRV9DQU5UX1NUQVJUX1dJVEhfQ09MT04sCi0gICAgICAiXHVDNzc0XHVCOTg0XHVDNzQwIFx1Q0Y1Q1x1Qjg2MFx1QzczQ1x1Qjg1QyBcdUMyRENcdUM3OTFcdUQ1NjAgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAgIHsgIkJBRF9DT0RFIiwgImNyZWF0ZU1lc3NhZ2VcdUM1RDAgXHVCMzAwXHVENTVDIFx1QjlFNFx1QUMxQ1x1QkNDMFx1QzIxOFx1QUMwMCBcdUJDOTRcdUM3MDRcdUI5N0MgXHVCQzk3XHVDNUI0XHVCMEFDXHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotICAgIHsgIkZPUk1BVF9GQUlMRUQiLCAibWVzc2FnZUZvcm1hdCBcdUQ2MzhcdUNEOUMgXHVDOTExIFx1QzYwOFx1QzY3OFx1QzBBQ1x1RDU2RFx1Qzc3NCBcdUJDMUNcdUMwRERcdUQ1ODhcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0gICAgeyAibGluZSIsICJcdUQ1ODkgXHVCQzg4XHVENjM4In0sCi0gICAgeyAiY29sdW1uIiwiXHVDNUY0IFx1QkM4OFx1RDYzOCJ9LAotCi0gICAge0VSX1NFUklBTElaRVJfTk9UX0NPTlRFTlRIQU5ETEVSLAotICAgICAgIlNlcmlhbGl6ZXIgXHVEMDc0XHVCNzk4XHVDMkE0ICcnezB9JydcdUM3NzQoXHVBQzAwKSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlclx1Qjk3QyBcdUFENkNcdUQ2MDRcdUQ1NThcdUM5QzAgXHVDNTRBXHVDNTU4XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAge0VSX1JFU09VUkNFX0NPVUxEX05PVF9GSU5ELAotICAgICAgIlt7MH1dIFx1QjlBQ1x1QzE4Q1x1QzJBNFx1Qjk3QyBcdUNDM0VcdUM3NDQgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC5cbiB7MX0iIH0sCi0KLSAgICB7RVJfUkVTT1VSQ0VfQ09VTERfTk9UX0xPQUQsCi0gICAgICAiW3swfV0gXHVCOUFDXHVDMThDXHVDMkE0XHVBQzAwIFx1QjJFNFx1Qzc0Q1x1Qzc0NCBcdUI4NUNcdUI0RENcdUQ1NjAgXHVDMjE4IFx1QzVDNlx1Qzc0QzogezF9IFxuIHsyfSBcdCB7M30iIH0sCi0KLSAgICB7RVJfQlVGRkVSX1NJWkVfTEVTU1RIQU5fWkVSTywKLSAgICAgICJcdUJDODRcdUQzN0MgXHVEMDZDXHVBRTMwIDw9MCIgfSwKLQotICAgIHtFUl9JTlZBTElEX1VURjE2X1NVUlJPR0FURSwKLSAgICAgICJcdUJEODBcdUM4MDFcdUQ1NjlcdUQ1NUMgVVRGLTE2IFx1QjMwMFx1QjlBQyBcdUM2OTRcdUMxOENcdUFDMDAgXHVBQzEwXHVDOUMwXHVCNDI4OiB7MH0iIH0sCi0KLSAgICB7RVJfT0lFUlJPUiwKLSAgICAgICJJTyBcdUM2MjRcdUI5NTgiIH0sCi0KLSAgICB7RVJfSUxMRUdBTF9BVFRSSUJVVEVfUE9TSVRJT04sCi0gICAgICAiXHVENTU4XHVDNzA0IFx1QjE3OFx1QjREQ1x1QUMwMCBcdUMwRERcdUMxMzFcdUI0MUMgXHVENkM0IFx1QjYxMFx1QjI5NCBcdUM2OTRcdUMxOENcdUFDMDAgXHVDMEREXHVDMTMxXHVCNDE4XHVBRTMwIFx1QzgwNFx1QzVEMCB7MH0gXHVDMThEXHVDMTMxXHVDNzQ0IFx1Q0Q5NFx1QUMwMFx1RDU2MCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiBcdUMxOERcdUMxMzFcdUM3NzQgXHVCQjM0XHVDMkRDXHVCNDI5XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgICAvKgotICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IGNvbnRhaW5lZCBhIHJlZmVyZW5jZSB0byBhCi0gICAgICAgKiBuYW1lc3BhY2UgcHJlZml4IHRoYXQgd2FzIHVuZGVmaW5lZC4gIFRoZSB2YWx1ZSBvZiB0aGUgc3Vic3RpdHV0aW9uCi0gICAgICAgKiB0ZXh0IGlzIHRoZSBuYW1lIG9mIHRoZSBwcmVmaXguCi0gICAgICAgKi8KLSAgICB7RVJfTkFNRVNQQUNFX1BSRUZJWCwKLSAgICAgICInJ3swfScnIFx1QzgxMVx1QjQ1MFx1QzVCNFx1QzVEMCBcdUIzMDBcdUQ1NUMgXHVCMTI0XHVDNzg0XHVDMkE0XHVEMzk4XHVDNzc0XHVDMkE0XHVBQzAwIFx1QzEyMFx1QzVCOFx1QjQxOFx1QzlDMCBcdUM1NEFcdUM1NThcdUMyQjVcdUIyQzhcdUIyRTQuIiB9LAotICAgICAgLyoKLSAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgcmVwb3J0ZWQgaWYgdGhlIHN0eWxlc2hlZXQKLSAgICAgICAqIGJlaW5nIHByb2Nlc3NlZCBhdHRlbXB0ZWQgdG8gY29uc3RydWN0IGFuIFhNTCBkb2N1bWVudCB3aXRoIGFuCi0gICAgICAgKiBhdHRyaWJ1dGUgaW4gYSBwbGFjZSBvdGhlciB0aGFuIG9uIGFuIGVsZW1lbnQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQKLSAgICAgICAqIHNwZWNpZmllcyB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlLgotICAgICAgICovCi0gICAge0VSX1NUUkFZX0FUVFJJQlVURSwKLSAgICAgICInJ3swfScnIFx1QzE4RFx1QzEzMVx1Qzc3NCBcdUM2OTRcdUMxOENcdUM1RDAgXHVEM0VDXHVENTY4XHVCNDE4XHVDNUI0IFx1Qzc4OFx1QzlDMCBcdUM1NEFcdUMyQjVcdUIyQzhcdUIyRTQuIiB9LAotCi0gICAgICAvKgotICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFzIHdpdGggdGhlIHByZWNlZGluZyBtZXNzYWdlLCBhIG5hbWVzcGFjZQotICAgICAgICogZGVjbGFyYXRpb24gaGFzIHRoZSBmb3JtIG9mIGFuIGF0dHJpYnV0ZSBhbmQgaXMgb25seSBwZXJtaXR0ZWQgdG8KLSAgICAgICAqIGFwcGVhciBvbiBhbiBlbGVtZW50LiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHswfSBpcyB0aGUgbmFtZXNwYWNlCi0gICAgICAgKiBwcmVmaXggYW5kIHsxfSBpcyB0aGUgVVJJIHRoYXQgd2FzIGJlaW5nIHVzZWQgaW4gdGhlIGVycm9uZW91cwotICAgICAgICogbmFtZXNwYWNlIGRlY2xhcmF0aW9uLgotICAgICAgICovCi0gICAge0VSX1NUUkFZX05BTUVTUEFDRSwKLSAgICAgICJcdUIxMjRcdUM3ODRcdUMyQTRcdUQzOThcdUM3NzRcdUMyQTQgXHVDMTIwXHVDNUI4ICcnezB9Jyc9Jyd7MX0nJ1x1Qzc3NChcdUFDMDApIFx1QzY5NFx1QzE4Q1x1QzVEMCBcdUQzRUNcdUQ1NjhcdUI0MThcdUM1QjQgXHVDNzg4XHVDOUMwIFx1QzU0QVx1QzJCNVx1QjJDOFx1QjJFNC4iIH0sCi0KLSAgICB7RVJfQ09VTERfTk9UX0xPQURfUkVTT1VSQ0UsCi0gICAgICAiezB9XHVDNzQ0KFx1Qjk3QykgXHVCODVDXHVCNERDXHVENTYwIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuIENMQVNTUEFUSFx1Qjk3QyBcdUQ2NTVcdUM3NzhcdUQ1NThcdUMyRURcdUMyRENcdUM2MjQuIFx1RDYwNFx1QzdBQyBcdUFFMzBcdUJDRjhcdUFDMTJcdUI5Q0MgXHVDMEFDXHVDNkE5XHVENTU4XHVCMjk0IFx1QzkxMVx1Qzc4NVx1QjJDOFx1QjJFNC4ifSwKLQotICAgIHsgRVJfSUxMRUdBTF9DSEFSQUNURVIsCi0gICAgICAgInsxfVx1Qzc1OCBcdUM5QzBcdUM4MTVcdUI0MUMgXHVDRDlDXHVCODI1IFx1Qzc3OFx1Q0Y1NFx1QjUyOVx1QzVEMFx1QzExQyBcdUQ0NUNcdUMyRENcdUI0MThcdUM5QzAgXHVDNTRBXHVCMjk0IFx1QzgxNVx1QzIxOCBcdUFDMTIgezB9XHVDNzU4IFx1QkIzOFx1Qzc5MFx1Qjk3QyBcdUNEOUNcdUI4MjVcdUQ1NThcdUI4MjRcdUFDRTAgXHVDMkRDXHVCM0M0XHVENTg4XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAge0VSX0NPVUxEX05PVF9MT0FEX01FVEhPRF9QUk9QRVJUWSwKLSAgICAgICJcdUNEOUNcdUI4MjUgXHVCQTU0XHVDMThDXHVCNERDICcnezF9JydcdUM1RDAgXHVCMzAwXHVENTVDIFx1QzE4RFx1QzEzMSBcdUQzMENcdUM3N0MgJyd7MH0nJ1x1Qzc0NChcdUI5N0MpIFx1Qjg1Q1x1QjREQ1x1RDU2MCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiBDTEFTU1BBVEhcdUI5N0MgXHVENjU1XHVDNzc4XHVENTU4XHVDMkVEXHVDMkRDXHVDNjI0LiIgfQotCi0KLSAgfTsKLQotICAvKioKLSAgICogR2V0IHRoZSBhc3NvY2lhdGlvbiBsaXN0LgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBhc3NvY2lhdGlvbiBsaXN0LgotICAgKi8KLQotICAgIHByb3RlY3RlZCBPYmplY3RbXVtdIGdldENvbnRlbnRzKCkgewotICAgICAgICByZXR1cm4gY29udGVudHM7Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9yZXMvWE1MRXJyb3JSZXNvdXJjZXNfcHRfQlIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3Jlcy9YTUxFcnJvclJlc291cmNlc19wdF9CUi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4MTRiMTljLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3Jlcy9YTUxFcnJvclJlc291cmNlc19wdF9CUi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDUwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXM7Ci0KLQotaW1wb3J0IGphdmEudXRpbC5MaXN0UmVzb3VyY2VCdW5kbGU7Ci0KLS8qKgotICogU2V0IHVwIGVycm9yIG1lc3NhZ2VzLgotICogV2UgYnVpbGQgYSB0d28gZGltZW5zaW9uYWwgYXJyYXkgb2YgbWVzc2FnZSBrZXlzIGFuZAotICogbWVzc2FnZSBzdHJpbmdzLiBJbiBvcmRlciB0byBhZGQgYSBuZXcgbWVzc2FnZSBoZXJlLAotICogeW91IG5lZWQgdG8gZmlyc3QgYWRkIGEgU3RyaW5nIGNvbnN0YW50LiBBbmQgeW91IG5lZWQKLSAqIHRvIGVudGVyIGtleSwgdmFsdWUgcGFpciBhcyBwYXJ0IG9mIHRoZSBjb250ZW50cwotICogYXJyYXkuIFlvdSBhbHNvIG5lZWQgdG8gdXBkYXRlIE1BWF9DT0RFIGZvciBlcnJvciBzdHJpbmdzCi0gKiBhbmQgTUFYX1dBUk5JTkcgZm9yIHdhcm5pbmdzICggTmVlZGVkIGZvciBvbmx5IGluZm9ybWF0aW9uCi0gKiBwdXJwb3NlICkKLSAqLwotcHVibGljIGNsYXNzIFhNTEVycm9yUmVzb3VyY2VzX3B0X0JSIGV4dGVuZHMgTGlzdFJlc291cmNlQnVuZGxlCi17Ci0KLS8qCi0gKiBUaGlzIGZpbGUgY29udGFpbnMgZXJyb3IgYW5kIHdhcm5pbmcgbWVzc2FnZXMgcmVsYXRlZCB0byBYYWxhbiBFcnJvcgotICogSGFuZGxpbmcuCi0gKgotICogIEdlbmVyYWwgbm90ZXMgdG8gdHJhbnNsYXRvcnM6Ci0gKgotICogIDEpIFhhbGFuIChvciBtb3JlIHByb3Blcmx5LCBYYWxhbi1pbnRlcnByZXRpdmUpIGFuZCBYU0xUQyBhcmUgbmFtZXMgb2YKLSAqICAgICBjb21wb25lbnRzLgotICogICAgIFhTTFQgaXMgYW4gYWNyb255bSBmb3IgIlhNTCBTdHlsZXNoZWV0IExhbmd1YWdlOiBUcmFuc2Zvcm1hdGlvbnMiLgotICogICAgIFhTTFRDIGlzIGFuIGFjcm9ueW0gZm9yIFhTTFQgQ29tcGlsZXIuCi0gKgotICogIDIpIEEgc3R5bGVzaGVldCBpcyBhIGRlc2NyaXB0aW9uIG9mIGhvdyB0byB0cmFuc2Zvcm0gYW4gaW5wdXQgWE1MIGRvY3VtZW50Ci0gKiAgICAgaW50byBhIHJlc3VsdGFudCBYTUwgZG9jdW1lbnQgKG9yIEhUTUwgZG9jdW1lbnQgb3IgdGV4dCkuICBUaGUKLSAqICAgICBzdHlsZXNoZWV0IGl0c2VsZiBpcyBkZXNjcmliZWQgaW4gdGhlIGZvcm0gb2YgYW4gWE1MIGRvY3VtZW50LgotICoKLSAqICAzKSBBIHRlbXBsYXRlIGlzIGEgY29tcG9uZW50IG9mIGEgc3R5bGVzaGVldCB0aGF0IGlzIHVzZWQgdG8gbWF0Y2ggYQotICogICAgIHBhcnRpY3VsYXIgcG9ydGlvbiBvZiBhbiBpbnB1dCBkb2N1bWVudCBhbmQgc3BlY2lmaWVzIHRoZSBmb3JtIG9mIHRoZQotICogICAgIGNvcnJlc3BvbmRpbmcgcG9ydGlvbiBvZiB0aGUgb3V0cHV0IGRvY3VtZW50LgotICoKLSAqICA0KSBBbiBlbGVtZW50IGlzIGEgbWFyay11cCB0YWcgaW4gYW4gWE1MIGRvY3VtZW50OyBhbiBhdHRyaWJ1dGUgaXMgYQotICogICAgIG1vZGlmaWVyIG9uIHRoZSB0YWcuICBGb3IgZXhhbXBsZSwgaW4gPGVsZW0gYXR0cj0ndmFsJyBhdHRyMj0ndmFsMic+Ci0gKiAgICAgImVsZW0iIGlzIGFuIGVsZW1lbnQgbmFtZSwgImF0dHIiIGFuZCAiYXR0cjIiIGFyZSBhdHRyaWJ1dGUgbmFtZXMgd2l0aAotICogICAgIHRoZSB2YWx1ZXMgInZhbCIgYW5kICJ2YWwyIiwgcmVzcGVjdGl2ZWx5LgotICoKLSAqICA1KSBBIG5hbWVzcGFjZSBkZWNsYXJhdGlvbiBpcyBhIHNwZWNpYWwgYXR0cmlidXRlIHRoYXQgaXMgdXNlZCB0byBhc3NvY2lhdGUKLSAqICAgICBhIHByZWZpeCB3aXRoIGEgVVJJICh0aGUgbmFtZXNwYWNlKS4gIFRoZSBtZWFuaW5ncyBvZiBlbGVtZW50IG5hbWVzIGFuZAotICogICAgIGF0dHJpYnV0ZSBuYW1lcyB0aGF0IHVzZSB0aGF0IHByZWZpeCBhcmUgZGVmaW5lZCB3aXRoIHJlc3BlY3QgdG8gdGhhdAotICogICAgIG5hbWVzcGFjZS4KLSAqCi0gKiAgNikgIlRyYW5zbGV0IiBpcyBhbiBpbnZlbnRlZCB0ZXJtIHRoYXQgZGVzY3JpYmVzIHRoZSBjbGFzcyBmaWxlIHRoYXQKLSAqICAgICByZXN1bHRzIGZyb20gY29tcGlsaW5nIGFuIFhNTCBzdHlsZXNoZWV0IGludG8gYSBKYXZhIGNsYXNzLgotICoKLSAqICA3KSBYUGF0aCBpcyBhIHNwZWNpZmljYXRpb24gdGhhdCBkZXNjcmliZXMgYSBub3RhdGlvbiBmb3IgaWRlbnRpZnlpbmcKLSAqICAgICBub2RlcyBpbiBhIHRyZWUtc3RydWN0dXJlZCByZXByZXNlbnRhdGlvbiBvZiBhbiBYTUwgZG9jdW1lbnQuICBBbgotICogICAgIGluc3RhbmNlIG9mIHRoYXQgbm90YXRpb24gaXMgcmVmZXJyZWQgdG8gYXMgYW4gWFBhdGggZXhwcmVzc2lvbi4KLSAqCi0gKi8KLQotICAvKiogTWF4aW11bSBlcnJvciBtZXNzYWdlcywgdGhpcyBpcyBuZWVkZWQgdG8ga2VlcCB0cmFjayBvZiB0aGUgbnVtYmVyIG9mIG1lc3NhZ2VzLiAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVhfQ09ERSA9IDYxOwotCi0gIC8qKiBNYXhpbXVtIHdhcm5pbmdzLCB0aGlzIGlzIG5lZWRlZCB0byBrZWVwIHRyYWNrIG9mIHRoZSBudW1iZXIgb2Ygd2FybmluZ3MuICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BWF9XQVJOSU5HID0gMDsKLQotICAvKiogTWF4aW11bSBtaXNjIHN0cmluZ3MuICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFYX09USEVSUyA9IDQ7Ci0KLSAgLyoqIE1heGltdW0gdG90YWwgd2FybmluZ3MgYW5kIGVycm9yIG1lc3NhZ2VzLiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVhfTUVTU0FHRVMgPSBNQVhfQ09ERSArIE1BWF9XQVJOSU5HICsgMTsKLQotCi0gIC8qCi0gICAqIE1lc3NhZ2Uga2V5cwotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCA9ICJFUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX09WRVJXUklURV9DQVVTRSA9ICJFUl9DQU5OT1RfT1ZFUldSSVRFX0NBVVNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fREVGQVVMVF9JTVBMID0gIkVSX05PX0RFRkFVTFRfSU1QTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NIVU5LRURJTlRBUlJBWV9OT1RfU1VQUE9SVEVEID0gIkVSX0NIVU5LRURJTlRBUlJBWV9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfT0ZGU0VUX0JJR0dFUl9USEFOX1NMT1QgPSAiRVJfT0ZGU0VUX0JJR0dFUl9USEFOX1NMT1QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1JPVVRJTkVfTk9UX0FWQUlMID0gIkVSX0NPUk9VVElORV9OT1RfQVZBSUwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1JPVVRJTkVfQ09fRVhJVCA9ICJFUl9DT1JPVVRJTkVfQ09fRVhJVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPSk9JTlJPVVRJTkVTRVRfRkFJTEVEID0gIkVSX0NPSk9JTlJPVVRJTkVTRVRfRkFJTEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09ST1VUSU5FX1BBUkFNID0gIkVSX0NPUk9VVElORV9QQVJBTSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BBUlNFUl9ET1RFUk1JTkFURV9BTlNXRVJTID0gIkVSX1BBUlNFUl9ET1RFUk1JTkFURV9BTlNXRVJTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fUEFSU0VfQ0FMTF9XSElMRV9QQVJTSU5HID0gIkVSX05PX1BBUlNFX0NBTExfV0hJTEVfUEFSU0lORyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1RZUEVEX0lURVJBVE9SX0FYSVNfTk9UX0lNUExFTUVOVEVEID0gIkVSX1RZUEVEX0lURVJBVE9SX0FYSVNfTk9UX0lNUExFTUVOVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSVRFUkFUT1JfQVhJU19OT1RfSU1QTEVNRU5URUQgPSAiRVJfSVRFUkFUT1JfQVhJU19OT1RfSU1QTEVNRU5URUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JVEVSQVRPUl9DTE9ORV9OT1RfU1VQUE9SVEVEID0gIkVSX0lURVJBVE9SX0NMT05FX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTktOT1dOX0FYSVNfVFlQRSA9ICJFUl9VTktOT1dOX0FYSVNfVFlQRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FYSVNfTk9UX1NVUFBPUlRFRCA9ICJFUl9BWElTX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19EVE1JRFNfQVZBSUwgPSAiRVJfTk9fRFRNSURTX0FWQUlMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9UX1NVUFBPUlRFRCA9ICJFUl9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9ERV9OT05fTlVMTCA9ICJFUl9OT0RFX05PTl9OVUxMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTERfTk9UX1JFU09MVkVfTk9ERSA9ICJFUl9DT1VMRF9OT1RfUkVTT0xWRV9OT0RFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU1RBUlRQQVJTRV9XSElMRV9QQVJTSU5HID0gIkVSX1NUQVJUUEFSU0VfV0hJTEVfUEFSU0lORyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NUQVJUUEFSU0VfTkVFRFNfU0FYUEFSU0VSID0gIkVSX1NUQVJUUEFSU0VfTkVFRFNfU0FYUEFSU0VSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTERfTk9UX0lOSVRfUEFSU0VSID0gIkVSX0NPVUxEX05PVF9JTklUX1BBUlNFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYQ0VQVElPTl9DUkVBVElOR19QT09MID0gIkVSX0VYQ0VQVElPTl9DUkVBVElOR19QT09MIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUEFUSF9DT05UQUlOU19JTlZBTElEX0VTQ0FQRV9TRVFVRU5DRSA9ICJFUl9QQVRIX0NPTlRBSU5TX0lOVkFMSURfRVNDQVBFX1NFUVVFTkNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU0NIRU1FX1JFUVVJUkVEID0gIkVSX1NDSEVNRV9SRVFVSVJFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1NDSEVNRV9JTl9VUkkgPSAiRVJfTk9fU0NIRU1FX0lOX1VSSSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1NDSEVNRV9JTlVSSSA9ICJFUl9OT19TQ0hFTUVfSU5VUkkiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QQVRIX0lOVkFMSURfQ0hBUiA9ICJFUl9QQVRIX0lOVkFMSURfQ0hBUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NDSEVNRV9GUk9NX05VTExfU1RSSU5HID0gIkVSX1NDSEVNRV9GUk9NX05VTExfU1RSSU5HIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU0NIRU1FX05PVF9DT05GT1JNQU5UID0gIkVSX1NDSEVNRV9OT1RfQ09ORk9STUFOVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0hPU1RfQUREUkVTU19OT1RfV0VMTEZPUk1FRCA9ICJFUl9IT1NUX0FERFJFU1NfTk9UX1dFTExGT1JNRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QT1JUX1dIRU5fSE9TVF9OVUxMID0gIkVSX1BPUlRfV0hFTl9IT1NUX05VTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX1BPUlQgPSAiRVJfSU5WQUxJRF9QT1JUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRlJBR19GT1JfR0VORVJJQ19VUkkgPSJFUl9GUkFHX0ZPUl9HRU5FUklDX1VSSSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZSQUdfV0hFTl9QQVRIX05VTEwgPSAiRVJfRlJBR19XSEVOX1BBVEhfTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZSQUdfSU5WQUxJRF9DSEFSID0gIkVSX0ZSQUdfSU5WQUxJRF9DSEFSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUEFSU0VSX0lOX1VTRSA9ICJFUl9QQVJTRVJfSU5fVVNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX0NIQU5HRV9XSElMRV9QQVJTSU5HID0gIkVSX0NBTk5PVF9DSEFOR0VfV0hJTEVfUEFSU0lORyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NFTEZfQ0FVU0FUSU9OX05PVF9QRVJNSVRURUQgPSAiRVJfU0VMRl9DQVVTQVRJT05fTk9UX1BFUk1JVFRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1VTRVJJTkZPX0lGX05PX0hPU1QgPSAiRVJfTk9fVVNFUklORk9fSUZfTk9fSE9TVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1BPUlRfSUZfTk9fSE9TVCA9ICJFUl9OT19QT1JUX0lGX05PX0hPU1QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19RVUVSWV9TVFJJTkdfSU5fUEFUSCA9ICJFUl9OT19RVUVSWV9TVFJJTkdfSU5fUEFUSCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX0ZSQUdNRU5UX1NUUklOR19JTl9QQVRIID0gIkVSX05PX0ZSQUdNRU5UX1NUUklOR19JTl9QQVRIIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX0lOSVRfVVJJX0VNUFRZX1BBUk1TID0gIkVSX0NBTk5PVF9JTklUX1VSSV9FTVBUWV9QQVJNUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01FVEhPRF9OT1RfU1VQUE9SVEVEID0iRVJfTUVUSE9EX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTkNSU0FYU1JDRklMVEVSX05PVF9SRVNUQVJUQUJMRSA9ICJFUl9JTkNSU0FYU1JDRklMVEVSX05PVF9SRVNUQVJUQUJMRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hNTFJEUl9OT1RfQkVGT1JFX1NUQVJUUEFSU0UgPSAiRVJfWE1MUkRSX05PVF9CRUZPUkVfU1RBUlRQQVJTRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FYSVNfVFJBVkVSU0VSX05PVF9TVVBQT1JURUQgPSAiRVJfQVhJU19UUkFWRVJTRVJfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VSUk9SSEFORExFUl9DUkVBVEVEX1dJVEhfTlVMTF9QUklOVFdSSVRFUiA9ICJFUl9FUlJPUkhBTkRMRVJfQ1JFQVRFRF9XSVRIX05VTExfUFJJTlRXUklURVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TWVNURU1JRF9VTktOT1dOID0gIkVSX1NZU1RFTUlEX1VOS05PV04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9MT0NBVElPTl9VTktOT1dOID0gIkVSX0xPQ0FUSU9OX1VOS05PV04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUkVGSVhfTVVTVF9SRVNPTFZFID0gIkVSX1BSRUZJWF9NVVNUX1JFU09MVkUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DUkVBVEVET0NVTUVOVF9OT1RfU1VQUE9SVEVEID0gIkVSX0NSRUFURURPQ1VNRU5UX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DSElMRF9IQVNfTk9fT1dORVJfRE9DVU1FTlQgPSAiRVJfQ0hJTERfSEFTX05PX09XTkVSX0RPQ1VNRU5UIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0hJTERfSEFTX05PX09XTkVSX0RPQ1VNRU5UX0VMRU1FTlQgPSAiRVJfQ0hJTERfSEFTX05PX09XTkVSX0RPQ1VNRU5UX0VMRU1FTlQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX09VVFBVVF9URVhUX0JFRk9SRV9ET0MgPSAiRVJfQ0FOVF9PVVRQVVRfVEVYVF9CRUZPUkVfRE9DIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9IQVZFX01PUkVfVEhBTl9PTkVfUk9PVCA9ICJFUl9DQU5UX0hBVkVfTU9SRV9USEFOX09ORV9ST09UIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQVJHX0xPQ0FMTkFNRV9OVUxMID0gIkVSX0FSR19MT0NBTE5BTUVfTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FSR19MT0NBTE5BTUVfSU5WQUxJRCA9ICJFUl9BUkdfTE9DQUxOQU1FX0lOVkFMSUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9BUkdfUFJFRklYX0lOVkFMSUQgPSAiRVJfQVJHX1BSRUZJWF9JTlZBTElEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTkFNRV9DQU5UX1NUQVJUX1dJVEhfQ09MT04gPSAiRVJfTkFNRV9DQU5UX1NUQVJUX1dJVEhfQ09MT04iOwotCi0gIC8vIE1lc3NhZ2Uga2V5cyB1c2VkIGJ5IHRoZSBzZXJpYWxpemVyCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1JFU09VUkNFX0NPVUxEX05PVF9GSU5EID0gIkVSX1JFU09VUkNFX0NPVUxEX05PVF9GSU5EIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUkVTT1VSQ0VfQ09VTERfTk9UX0xPQUQgPSAiRVJfUkVTT1VSQ0VfQ09VTERfTk9UX0xPQUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9CVUZGRVJfU0laRV9MRVNTVEhBTl9aRVJPID0gIkVSX0JVRkZFUl9TSVpFX0xFU1NUSEFOX1pFUk8iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX1VURjE2X1NVUlJPR0FURSA9ICJFUl9JTlZBTElEX1VURjE2X1NVUlJPR0FURSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX09JRVJST1IgPSAiRVJfT0lFUlJPUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05BTUVTUEFDRV9QUkVGSVggPSAiRVJfTkFNRVNQQUNFX1BSRUZJWCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NUUkFZX0FUVFJJQlVURSA9ICJFUl9TVFJBWV9BVFRJUkJVVEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TVFJBWV9OQU1FU1BBQ0UgPSAiRVJfU1RSQVlfTkFNRVNQQUNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTERfTk9UX0xPQURfUkVTT1VSQ0UgPSAiRVJfQ09VTERfTk9UX0xPQURfUkVTT1VSQ0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRF9OT1RfTE9BRF9NRVRIT0RfUFJPUEVSVFkgPSAiRVJfQ09VTERfTk9UX0xPQURfTUVUSE9EX1BST1BFUlRZIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU0VSSUFMSVpFUl9OT1RfQ09OVEVOVEhBTkRMRVIgPSAiRVJfU0VSSUFMSVpFUl9OT1RfQ09OVEVOVEhBTkRMRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTExFR0FMX0FUVFJJQlVURV9QT1NJVElPTiA9ICJFUl9JTExFR0FMX0FUVFJJQlVURV9QT1NJVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lMTEVHQUxfQ0hBUkFDVEVSID0gIkVSX0lMTEVHQUxfQ0hBUkFDVEVSIjsKLQotICAvKgotICAgKiBOb3cgZmlsbCBpbiB0aGUgbWVzc2FnZSB0ZXh0LgotICAgKiBUaGVuIGZpbGwgaW4gdGhlIG1lc3NhZ2UgdGV4dCBmb3IgdGhhdCBtZXNzYWdlIGNvZGUgaW4gdGhlCi0gICAqIGFycmF5LiBVc2UgdGhlIG5ldyBlcnJvciBjb2RlIGFzIHRoZSBpbmRleCBpbnRvIHRoZSBhcnJheS4KLSAgICovCi0KLSAgLy8gRXJyb3IgbWVzc2FnZXMuLi4KLQotICAvKiogVGhlIGxvb2t1cCB0YWJsZSBmb3IgZXJyb3IgbWVzc2FnZXMuICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgT2JqZWN0W11bXSBjb250ZW50cyA9IHsKLQotICAvKiogRXJyb3IgbWVzc2FnZSBJRCB0aGF0IGhhcyBhIG51bGwgbWVzc2FnZSwgYnV0IHRha2VzIGluIGEgc2luZ2xlIG9iamVjdC4gICAgKi8KLSAgICB7IkVSMDAwMCIgLCAiezB9IiB9LAotCi0gICAgeyBFUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVELAotICAgICAgIkZ1blx1MDBFN1x1MDBFM28gblx1MDBFM28gc3Vwb3J0YWRhISJ9LAotCi0gICAgeyBFUl9DQU5OT1RfT1ZFUldSSVRFX0NBVVNFLAotICAgICAgIk5cdTAwRTNvIFx1MDBFOSBwb3NzXHUwMEVEdmVsIHN1YnN0aXR1aXIgYSBjYXVzYSJ9LAotCi0gICAgeyBFUl9OT19ERUZBVUxUX0lNUEwsCi0gICAgICAiTmVuaHVtYSBpbXBsZW1lbnRhXHUwMEU3XHUwMEUzbyBwYWRyXHUwMEUzbyBlbmNvbnRyYWRhICJ9LAotCi0gICAgeyBFUl9DSFVOS0VESU5UQVJSQVlfTk9UX1NVUFBPUlRFRCwKLSAgICAgICJDaHVua2VkSW50QXJyYXkoezB9KSBuXHUwMEUzbyBzdXBvcnRhZG8gYXR1YWxtZW50ZSJ9LAotCi0gICAgeyBFUl9PRkZTRVRfQklHR0VSX1RIQU5fU0xPVCwKLSAgICAgICJEZXNsb2NhbWVudG8gbWFpb3IgcXVlIG8gc2xvdCJ9LAotCi0gICAgeyBFUl9DT1JPVVRJTkVfTk9UX0FWQUlMLAotICAgICAgIkNvLXJvdGluYSBuXHUwMEUzbyBkaXNwb25cdTAwRUR2ZWwsIGlkPXswfSJ9LAotCi0gICAgeyBFUl9DT1JPVVRJTkVfQ09fRVhJVCwKLSAgICAgICJDb3JvdXRpbmVNYW5hZ2VyIHJlY2ViZXUgYSBzb2xpY2l0YVx1MDBFN1x1MDBFM28gY29fZXhpdCgpIn0sCi0KLSAgICB7IEVSX0NPSk9JTlJPVVRJTkVTRVRfRkFJTEVELAotICAgICAgIkZhbGhhIGVtIGNvX2pvaW5Db3JvdXRpbmVTZXQoKSJ9LAotCi0gICAgeyBFUl9DT1JPVVRJTkVfUEFSQU0sCi0gICAgICAiRXJybyBubyBwYXJcdTAwRTJtZXRybyBkYSBjby1yb3RpbmEgKHswfSkifSwKLQotICAgIHsgRVJfUEFSU0VSX0RPVEVSTUlOQVRFX0FOU1dFUlMsCi0gICAgICAiXG5JTkVTUEVSQURPOiBQYXJzZXIgZG9UZXJtaW5hdGUgcmVzcG9uZGUgezB9In0sCi0KLSAgICB7IEVSX05PX1BBUlNFX0NBTExfV0hJTEVfUEFSU0lORywKLSAgICAgICJvIHBhcnNpbmcgblx1MDBFM28gcG9kZSBzZXIgY2hhbWFkbyBkdXJhbnRlIG8gcGFyc2luZyJ9LAotCi0gICAgeyBFUl9UWVBFRF9JVEVSQVRPUl9BWElTX05PVF9JTVBMRU1FTlRFRCwKLSAgICAgICJFcnJvOiBpdGVyYWRvciBkaWdpdGFkbyBwYXJhIG8gZWl4byB7MH0gblx1MDBFM28gaW1wbGVtZW50YWRvIn0sCi0KLSAgICB7IEVSX0lURVJBVE9SX0FYSVNfTk9UX0lNUExFTUVOVEVELAotICAgICAgIkVycm86IGl0ZXJhZG9yIHBhcmEgbyBlaXhvIHswfSBuXHUwMEUzbyBpbXBsZW1lbnRhZG8gIn0sCi0KLSAgICB7IEVSX0lURVJBVE9SX0NMT05FX05PVF9TVVBQT1JURUQsCi0gICAgICAiY2xvbmFnZW0gZG8gaXRlcmFkb3Igblx1MDBFM28gc3Vwb3J0YWRhIn0sCi0KLSAgICB7IEVSX1VOS05PV05fQVhJU19UWVBFLAotICAgICAgIlRpcG8gdHJhbnN2ZXJzYWwgZGUgZWl4byBkZXNjb25oZWNpZG86IHswfSJ9LAotCi0gICAgeyBFUl9BWElTX05PVF9TVVBQT1JURUQsCi0gICAgICAiVHJhbnN2ZXJzb3IgZGUgZWl4byBuXHUwMEUzbyBzdXBvcnRhZG86IHswfSJ9LAotCi0gICAgeyBFUl9OT19EVE1JRFNfQVZBSUwsCi0gICAgICAiTlx1MDBFM28gaFx1MDBFMSBtYWlzIElEcyBkZSBEVE0gZGlzcG9uXHUwMEVEdmVpcyJ9LAotCi0gICAgeyBFUl9OT1RfU1VQUE9SVEVELAotICAgICAgIk5cdTAwRTNvIHN1cG9ydGFkbzogezB9In0sCi0KLSAgICB7IEVSX05PREVfTk9OX05VTEwsCi0gICAgICAiTyBuXHUwMEYzIGRldmUgc2VyIG5cdTAwRTNvLW51bG8gcGFyYSBnZXREVE1IYW5kbGVGcm9tTm9kZSJ9LAotCi0gICAgeyBFUl9DT1VMRF9OT1RfUkVTT0xWRV9OT0RFLAotICAgICAgIk5cdTAwRTNvIGZvaSBwb3NzXHUwMEVEdmVsIHJlc29sdmVyIG8gblx1MDBGMyBwYXJhIHVtIGhhbmRsZSJ9LAotCi0gICAgeyBFUl9TVEFSVFBBUlNFX1dISUxFX1BBUlNJTkcsCi0gICAgICAgInN0YXJ0UGFyc2Ugblx1MDBFM28gcG9kZSBzZXIgY2hhbWFkbyBkdXJhbnRlIG8gcGFyc2luZyJ9LAotCi0gICAgeyBFUl9TVEFSVFBBUlNFX05FRURTX1NBWFBBUlNFUiwKLSAgICAgICAic3RhcnRQYXJzZSByZXF1ZXIgdW0gU0FYUGFyc2VyIG5cdTAwRTNvIG51bG8ifSwKLQotICAgIHsgRVJfQ09VTERfTk9UX0lOSVRfUEFSU0VSLAotICAgICAgICJuXHUwMEUzbyBmb2kgcG9zc1x1MDBFRHZlbCBpbmljaWFsaXphciBvIHBhcnNlciBjb20ifSwKLQotICAgIHsgRVJfRVhDRVBUSU9OX0NSRUFUSU5HX1BPT0wsCi0gICAgICAgImV4Y2VcdTAwRTdcdTAwRTNvIGFvIGNyaWFyIGEgbm92YSBpbnN0XHUwMEUybmNpYSBkbyBwb29sIn0sCi0KLSAgICB7IEVSX1BBVEhfQ09OVEFJTlNfSU5WQUxJRF9FU0NBUEVfU0VRVUVOQ0UsCi0gICAgICAgIk8gY2FtaW5obyBjb250XHUwMEU5bSB1bWEgc2VxdVx1MDBFQW5jaWEgaW52XHUwMEUxbGlkYSBkZSBjYXJhY3RlcmVzIGRlIGVzY2FwZSJ9LAotCi0gICAgeyBFUl9TQ0hFTUVfUkVRVUlSRUQsCi0gICAgICAgIk8gZXNxdWVtYSBcdTAwRTkgb2JyaWdhdFx1MDBGM3JpbyEifSwKLQotICAgIHsgRVJfTk9fU0NIRU1FX0lOX1VSSSwKLSAgICAgICAiTmVuaHVtIGVzcXVlbWEgZW5jb250cmFkbyBubyBVUkk6IHswfSJ9LAotCi0gICAgeyBFUl9OT19TQ0hFTUVfSU5VUkksCi0gICAgICAgIk5lbmh1bSBlc3F1ZW1hIGVuY29udHJhZG8gbm8gVVJJIn0sCi0KLSAgICB7IEVSX1BBVEhfSU5WQUxJRF9DSEFSLAotICAgICAgICJPIGNhbWluaG8gY29udFx1MDBFOW0gdW0gY2FyYWN0ZXJlIGludlx1MDBFMWxpZG86IHswfSJ9LAotCi0gICAgeyBFUl9TQ0hFTUVfRlJPTV9OVUxMX1NUUklORywKLSAgICAgICAiTlx1MDBFM28gXHUwMEU5IHBvc3NcdTAwRUR2ZWwgZGVmaW5pciBvIGVzcXVlbWEgZGUgdW1hIHN0cmluZyBudWxhIn0sCi0KLSAgICB7IEVSX1NDSEVNRV9OT1RfQ09ORk9STUFOVCwKLSAgICAgICAiTyBlc3F1ZW1hIG5cdTAwRTNvIFx1MDBFOSBjb21wYXRcdTAwRUR2ZWwuIn0sCi0KLSAgICB7IEVSX0hPU1RfQUREUkVTU19OT1RfV0VMTEZPUk1FRCwKLSAgICAgICAiTyBob3N0IG5cdTAwRTNvIFx1MDBFOSB1bSBlbmRlcmVcdTAwRTdvIGNvcnJldG8ifSwKLQotICAgIHsgRVJfUE9SVF9XSEVOX0hPU1RfTlVMTCwKLSAgICAgICAiQSBwb3J0YSBuXHUwMEUzbyBwb2RlIHNlciBkZWZpbmlkYSBxdWFuZG8gbyBob3N0IFx1MDBFOSBudWxvIn0sCi0KLSAgICB7IEVSX0lOVkFMSURfUE9SVCwKLSAgICAgICAiTlx1MDBGQW1lcm8gZGUgcG9ydGEgaW52XHUwMEUxbGlkbyJ9LAotCi0gICAgeyBFUl9GUkFHX0ZPUl9HRU5FUklDX1VSSSwKLSAgICAgICAiTyBmcmFnbWVudG8gc1x1MDBGMyBwb2RlIHNlciBkZWZpbmlkbyBwYXJhIHVtIFVSSSBnZW5cdTAwRTlyaWNvIn0sCi0KLSAgICB7IEVSX0ZSQUdfV0hFTl9QQVRIX05VTEwsCi0gICAgICAgIk8gZnJhZ21lbnRvIG5cdTAwRTNvIHBvZGUgc2VyIGRlZmluaWRvIHF1YW5kbyBvIGNhbWluaG8gXHUwMEU5IG51bG8ifSwKLQotICAgIHsgRVJfRlJBR19JTlZBTElEX0NIQVIsCi0gICAgICAgIk8gZnJhZ21lbnRvIGNvbnRcdTAwRTltIHVtIGNhcmFjdGVyZSBpbnZcdTAwRTFsaWRvIn0sCi0KLSAgICB7IEVSX1BBUlNFUl9JTl9VU0UsCi0gICAgICAiTyBwYXJzZXIgalx1MDBFMSBlc3RcdTAwRTEgc2VuZG8gdXNhZG8ifSwKLQotICAgIHsgRVJfQ0FOTk9UX0NIQU5HRV9XSElMRV9QQVJTSU5HLAotICAgICAgIk5cdTAwRTNvIFx1MDBFOSBwb3NzXHUwMEVEdmVsIGFsdGVyYXIgezB9IHsxfSBkdXJhbnRlIG8gcGFyc2luZyJ9LAotCi0gICAgeyBFUl9TRUxGX0NBVVNBVElPTl9OT1RfUEVSTUlUVEVELAotICAgICAgIkF1dG9hdmVyaWd1YVx1MDBFN1x1MDBFM28gblx1MDBFM28gcGVybWl0aWRhIn0sCi0KLSAgICB7IEVSX05PX1VTRVJJTkZPX0lGX05PX0hPU1QsCi0gICAgICAiQXMgaW5mb3JtYVx1MDBFN1x1MDBGNWVzIGRvIHVzdVx1MDBFMXJpbyBuXHUwMEUzbyBwb2RlbSBzZXIgZXNwZWNpZmljYWRhcyBzZSBvIGhvc3Qgblx1MDBFM28gdGl2ZXIgc2lkbyBlc3BlY2lmaWNhZG8ifSwKLQotICAgIHsgRVJfTk9fUE9SVF9JRl9OT19IT1NULAotICAgICAgIkEgcG9ydGEgblx1MDBFM28gcG9kZSBzZXIgZXNwZWNpZmljYWRhIHNlIG8gaG9zdCBuXHUwMEUzbyB0aXZlciBzaWRvIGVzcGVjaWZpY2FkbyJ9LAotCi0gICAgeyBFUl9OT19RVUVSWV9TVFJJTkdfSU5fUEFUSCwKLSAgICAgICJBIHN0cmluZyBkZSBjb25zdWx0YSBuXHUwMEUzbyBwb2RlIHNlciBlc3BlY2lmaWNhZGEgbm8gY2FtaW5obyBuZW0gbmEgc3RyaW5nIGRlIGNvbnN1bHRhIn0sCi0KLSAgICB7IEVSX05PX0ZSQUdNRU5UX1NUUklOR19JTl9QQVRILAotICAgICAgIk8gZnJhZ21lbnRvIG5cdTAwRTNvIHBvZGUgc2VyIGVzcGVjaWZpY2FkbyBubyBjYW1pbmhvIG5lbSBubyBmcmFnbWVudG8ifSwKLQotICAgIHsgRVJfQ0FOTk9UX0lOSVRfVVJJX0VNUFRZX1BBUk1TLAotICAgICAgIk5cdTAwRTNvIFx1MDBFOSBwb3NzXHUwMEVEdmVsIGluaWNpYWxpemFyIG8gVVJJIGNvbSBwYXJcdTAwRTJtZXRyb3MgdmF6aW9zIn0sCi0KLSAgICB7IEVSX01FVEhPRF9OT1RfU1VQUE9SVEVELAotICAgICAgIk1cdTAwRTl0b2RvIGFpbmRhIG5cdTAwRTNvIHN1cG9ydGFkbyAifSwKLQotICAgIHsgRVJfSU5DUlNBWFNSQ0ZJTFRFUl9OT1RfUkVTVEFSVEFCTEUsCi0gICAgICAiSW5jcmVtZW50YWxTQVhTb3VyY2VfRmlsdGVyIGF0dWFsbWVudGUgblx1MDBFM28gcmVpbmljaWFsaXpcdTAwRTF2ZWwifSwKLQotICAgIHsgRVJfWE1MUkRSX05PVF9CRUZPUkVfU1RBUlRQQVJTRSwKLSAgICAgICJYTUxSZWFkZXIgblx1MDBFM28gYW50ZXJpb3IgXHUwMEUwIHNvbGljaXRhXHUwMEU3XHUwMEUzbyBkZSBzdGFydFBhcnNlIn0sCi0KLSAgICB7IEVSX0FYSVNfVFJBVkVSU0VSX05PVF9TVVBQT1JURUQsCi0gICAgICAiVHJhbnN2ZXJzb3IgZGUgZWl4byBuXHUwMEUzbyBzdXBvcnRhZG86IHswfSJ9LAotCi0gICAgeyBFUl9FUlJPUkhBTkRMRVJfQ1JFQVRFRF9XSVRIX05VTExfUFJJTlRXUklURVIsCi0gICAgICAiTGlzdGluZ0Vycm9ySGFuZGxlciBjcmlhZG8gY29tIFByaW50V3JpdGVyIG51bG8hIn0sCi0KLSAgICB7IEVSX1NZU1RFTUlEX1VOS05PV04sCi0gICAgICAiU3lzdGVtSWQgRGVzY29uaGVjaWRvIn0sCi0KLSAgICB7IEVSX0xPQ0FUSU9OX1VOS05PV04sCi0gICAgICAiTG9jYWxpemFcdTAwRTdcdTAwRTNvIGRlIGVycm8gZGVzY29uaGVjaWRhIn0sCi0KLSAgICB7IEVSX1BSRUZJWF9NVVNUX1JFU09MVkUsCi0gICAgICAiTyBwcmVmaXhvIGRldmUgc2VyIHJlc29sdmlkbyBwYXJhIHVtIG5hbWVzcGFjZTogezB9In0sCi0KLSAgICB7IEVSX0NSRUFURURPQ1VNRU5UX05PVF9TVVBQT1JURUQsCi0gICAgICAiY3JlYXRlRG9jdW1lbnQoKSBuXHUwMEUzbyBzdXBvcnRhZG8gbm8gWFBhdGhDb250ZXh0ISJ9LAotCi0gICAgeyBFUl9DSElMRF9IQVNfTk9fT1dORVJfRE9DVU1FTlQsCi0gICAgICAiTyBmaWxobyBkbyBhdHJpYnV0byBuXHUwMEUzbyB0ZW0gdW0gZG9jdW1lbnRvIGRvIHByb3ByaWV0XHUwMEUxcmlvISJ9LAotCi0gICAgeyBFUl9DSElMRF9IQVNfTk9fT1dORVJfRE9DVU1FTlRfRUxFTUVOVCwKLSAgICAgICJPIGZpbGhvIGRvIGF0cmlidXRvIG5cdTAwRTNvIHRlbSB1bSBlbGVtZW50byBkbyBkb2N1bWVudG8gZG8gcHJvcHJpZXRcdTAwRTFyaW8hIn0sCi0KLSAgICB7IEVSX0NBTlRfT1VUUFVUX1RFWFRfQkVGT1JFX0RPQywKLSAgICAgICJBZHZlcnRcdTAwRUFuY2lhOiBuXHUwMEUzbyBwb2RlIGhhdmVyIHRleHRvIGFudGVzIGRvIGVsZW1lbnRvIGRvIGRvY3VtZW50byEgSWdub3JhbmRvLi4uIn0sCi0KLSAgICB7IEVSX0NBTlRfSEFWRV9NT1JFX1RIQU5fT05FX1JPT1QsCi0gICAgICAiTlx1MDBFM28gcG9kZSB0ZXIgbWFpcyBkZSB1bWEgcmFpeiBlbSB1bSBET00hIn0sCi0KLSAgICB7IEVSX0FSR19MT0NBTE5BTUVfTlVMTCwKLSAgICAgICAiTyBhcmd1bWVudG8gJ2xvY2FsTmFtZScgXHUwMEU5IG51bG8ifSwKLQotICAgIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBIFFOQU1FIGhhcyB0aGUgc3ludGFjdGljIGZvcm0gW05DTmFtZTpdTkNOYW1lCi0gICAgLy8gVGhlIGxvY2FsbmFtZSBpcyB0aGUgcG9ydGlvbiBhZnRlciB0aGUgb3B0aW9uYWwgY29sb247IHRoZSBtZXNzYWdlIGluZGljYXRlcwotICAgIC8vIHRoYXQgdGhlcmUgaXMgYSBwcm9ibGVtIHdpdGggdGhhdCBwYXJ0IG9mIHRoZSBRTkFNRS4KLSAgICB7IEVSX0FSR19MT0NBTE5BTUVfSU5WQUxJRCwKLSAgICAgICAiTG9jYWxuYW1lIGVtIFFOQU1FIGRldmUgc2VyIHVtIE5DTmFtZSB2XHUwMEUxbGlkbyJ9LAotCi0gICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIEEgUU5BTUUgaGFzIHRoZSBzeW50YWN0aWMgZm9ybSBbTkNOYW1lOl1OQ05hbWUKLSAgICAvLyBUaGUgcHJlZml4IGlzIHRoZSBwb3J0aW9uIGJlZm9yZSB0aGUgb3B0aW9uYWwgY29sb247IHRoZSBtZXNzYWdlIGluZGljYXRlcwotICAgIC8vIHRoYXQgdGhlcmUgaXMgYSBwcm9ibGVtIHdpdGggdGhhdCBwYXJ0IG9mIHRoZSBRTkFNRS4KLSAgICB7IEVSX0FSR19QUkVGSVhfSU5WQUxJRCwKLSAgICAgICAiTyBwcmVmaXhvIGVtIFFOQU1FIGRldmUgc2VyIHVtIE5DTmFtZSB2XHUwMEUxbGlkbyJ9LAotCi0gICAgeyBFUl9OQU1FX0NBTlRfU1RBUlRfV0lUSF9DT0xPTiwKLSAgICAgICJPIG5vbWUgblx1MDBFM28gcG9kZSBjb21lXHUwMEU3YXIgY29tIGRvaXMgcG9udG9zIn0sCi0KLSAgICB7ICJCQURfQ09ERSIsICJPIHBhclx1MDBFMm1ldHJvIHBhcmEgY3JlYXRlTWVzc2FnZSBlc3RhdmEgZm9yYSBkb3MgbGltaXRlcyJ9LAotICAgIHsgIkZPUk1BVF9GQUlMRUQiLCAiRXhjZVx1MDBFN1x1MDBFM28gZ2VyYWRhIGR1cmFudGUgYSBjaGFtYWRhIG1lc3NhZ2VGb3JtYXQifSwKLSAgICB7ICJsaW5lIiwgIk5cdTAwQjAgZGEgTGluaGEifSwKLSAgICB7ICJjb2x1bW4iLCJOXHUwMEIwIGRhIENvbHVuYSJ9LAotCi0gICAge0VSX1NFUklBTElaRVJfTk9UX0NPTlRFTlRIQU5ETEVSLAotICAgICAgIkEgY2xhc3NlICcnezB9JycgZG8gc2VyaWFsaXphZG9yIG5cdTAwRTNvIGltcGxlbWVudGEgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIuIn0sCi0KLSAgICB7RVJfUkVTT1VSQ0VfQ09VTERfTk9UX0ZJTkQsCi0gICAgICAiTlx1MDBFM28gZm9pIHBvc3NcdTAwRUR2ZWwgZW5jb250cmFyIG8gcmVjdXJzbyBbIHswfSBdLlxuIHsxfSIgfSwKLQotICAgIHtFUl9SRVNPVVJDRV9DT1VMRF9OT1RfTE9BRCwKLSAgICAgICJPIHJlY3Vyc28gWyB7MH0gXSBuXHUwMEUzbyBmb2kgY2FycmVnYWRvOiB7MX0gXG4gezJ9IFx0IHszfSIgfSwKLQotICAgIHtFUl9CVUZGRVJfU0laRV9MRVNTVEhBTl9aRVJPLAotICAgICAgIlRhbWFuaG8gZG8gYnVmZmVyIDw9MCIgfSwKLQotICAgIHtFUl9JTlZBTElEX1VURjE2X1NVUlJPR0FURSwKLSAgICAgICJGb2kgZGV0ZWN0YWRvIHVtIHN1YnN0aXR1dG8gZGUgVVRGLTE2IGludlx1MDBFMWxpZG86IHswfSA/IiB9LAotCi0gICAge0VSX09JRVJST1IsCi0gICAgICAiRXJybyBkZSBFL1MiIH0sCi0KLSAgICB7RVJfSUxMRUdBTF9BVFRSSUJVVEVfUE9TSVRJT04sCi0gICAgICAiTlx1MDBFM28gXHUwMEU5IHBvc3NcdTAwRUR2ZWwgYWRpY2lvbmFyIG8gYXRyaWJ1dG8gezB9IGRlcG9pcyBkb3Mgblx1MDBGM3MgZmlsaG9zIG91IGFudGVzIHF1ZSB1bSBlbGVtZW50byBzZWphIHByb2R1emlkby4gTyBhdHJpYnV0byBzZXJcdTAwRTEgaWdub3JhZG8uIn0sCi0KLSAgICAgIC8qCi0gICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN0eWxlc2hlZXQgY29udGFpbmVkIGEgcmVmZXJlbmNlIHRvIGEKLSAgICAgICAqIG5hbWVzcGFjZSBwcmVmaXggdGhhdCB3YXMgdW5kZWZpbmVkLiAgVGhlIHZhbHVlIG9mIHRoZSBzdWJzdGl0dXRpb24KLSAgICAgICAqIHRleHQgaXMgdGhlIG5hbWUgb2YgdGhlIHByZWZpeC4KLSAgICAgICAqLwotICAgIHtFUl9OQU1FU1BBQ0VfUFJFRklYLAotICAgICAgIk8gbmFtZXNwYWNlIGRvIHByZWZpeG8gJyd7MH0nJyBuXHUwMEUzbyBmb2kgZGVjbGFyYWRvLiIgfSwKLSAgICAgIC8qCi0gICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIHJlcG9ydGVkIGlmIHRoZSBzdHlsZXNoZWV0Ci0gICAgICAgKiBiZWluZyBwcm9jZXNzZWQgYXR0ZW1wdGVkIHRvIGNvbnN0cnVjdCBhbiBYTUwgZG9jdW1lbnQgd2l0aCBhbgotICAgICAgICogYXR0cmlidXRlIGluIGEgcGxhY2Ugb3RoZXIgdGhhbiBvbiBhbiBlbGVtZW50LiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgKiBzcGVjaWZpZXMgdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgICAqLwotICAgIHtFUl9TVFJBWV9BVFRSSUJVVEUsCi0gICAgICAiQXRyaWJ1dG8gJyd7MH0nJyBmb3JhIGRvIGVsZW1lbnRvLiIgfSwKLQotICAgICAgLyoKLSAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBcyB3aXRoIHRoZSBwcmVjZWRpbmcgbWVzc2FnZSwgYSBuYW1lc3BhY2UKLSAgICAgICAqIGRlY2xhcmF0aW9uIGhhcyB0aGUgZm9ybSBvZiBhbiBhdHRyaWJ1dGUgYW5kIGlzIG9ubHkgcGVybWl0dGVkIHRvCi0gICAgICAgKiBhcHBlYXIgb24gYW4gZWxlbWVudC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCB7MH0gaXMgdGhlIG5hbWVzcGFjZQotICAgICAgICogcHJlZml4IGFuZCB7MX0gaXMgdGhlIFVSSSB0aGF0IHdhcyBiZWluZyB1c2VkIGluIHRoZSBlcnJvbmVvdXMKLSAgICAgICAqIG5hbWVzcGFjZSBkZWNsYXJhdGlvbi4KLSAgICAgICAqLwotICAgIHtFUl9TVFJBWV9OQU1FU1BBQ0UsCi0gICAgICAiRGVjbGFyYVx1MDBFN1x1MDBFM28gZGUgbmFtZXNwYWNlICcnezB9Jyc9Jyd7MX0nJyBmb3JhIGRvIGVsZW1lbnRvLiIgfSwKLQotICAgIHtFUl9DT1VMRF9OT1RfTE9BRF9SRVNPVVJDRSwKLSAgICAgICJOXHUwMEUzbyBmb2kgcG9zc1x1MDBFRHZlbCBjYXJyZWdhciAnJ3swfScnICh2ZXJpZmljYXIgQ0xBU1NQQVRIKTsgdXNhbmRvIGFnb3JhIGFwZW5hcyBvcyBwYWRyXHUwMEY1ZXMifSwKLQotICAgIHsgRVJfSUxMRUdBTF9DSEFSQUNURVIsCi0gICAgICAgIlRlbnRhdGl2YSBkZSBleGliaXIgdW0gY2FyYWN0ZXJlIGRlIHZhbG9yIGludGVncmFsIHswfSBxdWUgblx1MDBFM28gZXN0XHUwMEUxIHJlcHJlc2VudGFkbyBuYSBjb2RpZmljYVx1MDBFN1x1MDBFM28gZGUgc2FcdTAwRURkYSBlc3BlY2lmaWNhZGEgZGUgezF9LiJ9LAotCi0gICAge0VSX0NPVUxEX05PVF9MT0FEX01FVEhPRF9QUk9QRVJUWSwKLSAgICAgICJOXHUwMEUzbyBmb2kgcG9zc1x1MDBFRHZlbCBjYXJyZWdhciBvIGFycXVpdm8gZGUgcHJvcHJpZWRhZGUgJyd7MH0nJyBwYXJhIG8gbVx1MDBFOXRvZG8gZGUgc2FcdTAwRURkYSAnJ3sxfScnICh2ZXJpZmljYXIgQ0xBU1NQQVRIKSIgfQotCi0KLSAgfTsKLQotICAvKioKLSAgICogR2V0IHRoZSBhc3NvY2lhdGlvbiBsaXN0LgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBhc3NvY2lhdGlvbiBsaXN0LgotICAgKi8KLQotICAgIHByb3RlY3RlZCBPYmplY3RbXVtdIGdldENvbnRlbnRzKCkgewotICAgICAgICByZXR1cm4gY29udGVudHM7Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9yZXMvWE1MRXJyb3JSZXNvdXJjZXNfc2suamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3Jlcy9YTUxFcnJvclJlc291cmNlc19zay5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxZTRiMjkzLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3Jlcy9YTUxFcnJvclJlc291cmNlc19zay5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDQzICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFhNTEVycm9yUmVzb3VyY2VzX3NrLmphdmEsdiAxLjEuNi4yIDIwMDUvMDkvMTUgMDc6NDU6NDUgc3VyZXNoX2VtYWlsaWQgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnJlczsKLQotCi1pbXBvcnQgamF2YS51dGlsLkxpc3RSZXNvdXJjZUJ1bmRsZTsKLQotLyoqCi0gKiBTZXQgdXAgZXJyb3IgbWVzc2FnZXMuCi0gKiBXZSBidWlsZCBhIHR3byBkaW1lbnNpb25hbCBhcnJheSBvZiBtZXNzYWdlIGtleXMgYW5kCi0gKiBtZXNzYWdlIHN0cmluZ3MuIEluIG9yZGVyIHRvIGFkZCBhIG5ldyBtZXNzYWdlIGhlcmUsCi0gKiB5b3UgbmVlZCB0byBmaXJzdCBhZGQgYSBTdHJpbmcgY29uc3RhbnQuIEFuZCB5b3UgbmVlZAotICogdG8gZW50ZXIga2V5LCB2YWx1ZSBwYWlyIGFzIHBhcnQgb2YgdGhlIGNvbnRlbnRzCi0gKiBhcnJheS4gWW91IGFsc28gbmVlZCB0byB1cGRhdGUgTUFYX0NPREUgZm9yIGVycm9yIHN0cmluZ3MKLSAqIGFuZCBNQVhfV0FSTklORyBmb3Igd2FybmluZ3MgKCBOZWVkZWQgZm9yIG9ubHkgaW5mb3JtYXRpb24KLSAqIHB1cnBvc2UgKQotICovCi1wdWJsaWMgY2xhc3MgWE1MRXJyb3JSZXNvdXJjZXNfc2sgZXh0ZW5kcyBMaXN0UmVzb3VyY2VCdW5kbGUKLXsKLQotLyoKLSAqIFRoaXMgZmlsZSBjb250YWlucyBlcnJvciBhbmQgd2FybmluZyBtZXNzYWdlcyByZWxhdGVkIHRvIFhhbGFuIEVycm9yCi0gKiBIYW5kbGluZy4KLSAqCi0gKiAgR2VuZXJhbCBub3RlcyB0byB0cmFuc2xhdG9yczoKLSAqCi0gKiAgMSkgWGFsYW4gKG9yIG1vcmUgcHJvcGVybHksIFhhbGFuLWludGVycHJldGl2ZSkgYW5kIFhTTFRDIGFyZSBuYW1lcyBvZgotICogICAgIGNvbXBvbmVudHMuCi0gKiAgICAgWFNMVCBpcyBhbiBhY3JvbnltIGZvciAiWE1MIFN0eWxlc2hlZXQgTGFuZ3VhZ2U6IFRyYW5zZm9ybWF0aW9ucyIuCi0gKiAgICAgWFNMVEMgaXMgYW4gYWNyb255bSBmb3IgWFNMVCBDb21waWxlci4KLSAqCi0gKiAgMikgQSBzdHlsZXNoZWV0IGlzIGEgZGVzY3JpcHRpb24gb2YgaG93IHRvIHRyYW5zZm9ybSBhbiBpbnB1dCBYTUwgZG9jdW1lbnQKLSAqICAgICBpbnRvIGEgcmVzdWx0YW50IFhNTCBkb2N1bWVudCAob3IgSFRNTCBkb2N1bWVudCBvciB0ZXh0KS4gIFRoZQotICogICAgIHN0eWxlc2hlZXQgaXRzZWxmIGlzIGRlc2NyaWJlZCBpbiB0aGUgZm9ybSBvZiBhbiBYTUwgZG9jdW1lbnQuCi0gKgotICogIDMpIEEgdGVtcGxhdGUgaXMgYSBjb21wb25lbnQgb2YgYSBzdHlsZXNoZWV0IHRoYXQgaXMgdXNlZCB0byBtYXRjaCBhCi0gKiAgICAgcGFydGljdWxhciBwb3J0aW9uIG9mIGFuIGlucHV0IGRvY3VtZW50IGFuZCBzcGVjaWZpZXMgdGhlIGZvcm0gb2YgdGhlCi0gKiAgICAgY29ycmVzcG9uZGluZyBwb3J0aW9uIG9mIHRoZSBvdXRwdXQgZG9jdW1lbnQuCi0gKgotICogIDQpIEFuIGVsZW1lbnQgaXMgYSBtYXJrLXVwIHRhZyBpbiBhbiBYTUwgZG9jdW1lbnQ7IGFuIGF0dHJpYnV0ZSBpcyBhCi0gKiAgICAgbW9kaWZpZXIgb24gdGhlIHRhZy4gIEZvciBleGFtcGxlLCBpbiA8ZWxlbSBhdHRyPSd2YWwnIGF0dHIyPSd2YWwyJz4KLSAqICAgICAiZWxlbSIgaXMgYW4gZWxlbWVudCBuYW1lLCAiYXR0ciIgYW5kICJhdHRyMiIgYXJlIGF0dHJpYnV0ZSBuYW1lcyB3aXRoCi0gKiAgICAgdGhlIHZhbHVlcyAidmFsIiBhbmQgInZhbDIiLCByZXNwZWN0aXZlbHkuCi0gKgotICogIDUpIEEgbmFtZXNwYWNlIGRlY2xhcmF0aW9uIGlzIGEgc3BlY2lhbCBhdHRyaWJ1dGUgdGhhdCBpcyB1c2VkIHRvIGFzc29jaWF0ZQotICogICAgIGEgcHJlZml4IHdpdGggYSBVUkkgKHRoZSBuYW1lc3BhY2UpLiAgVGhlIG1lYW5pbmdzIG9mIGVsZW1lbnQgbmFtZXMgYW5kCi0gKiAgICAgYXR0cmlidXRlIG5hbWVzIHRoYXQgdXNlIHRoYXQgcHJlZml4IGFyZSBkZWZpbmVkIHdpdGggcmVzcGVjdCB0byB0aGF0Ci0gKiAgICAgbmFtZXNwYWNlLgotICoKLSAqICA2KSAiVHJhbnNsZXQiIGlzIGFuIGludmVudGVkIHRlcm0gdGhhdCBkZXNjcmliZXMgdGhlIGNsYXNzIGZpbGUgdGhhdAotICogICAgIHJlc3VsdHMgZnJvbSBjb21waWxpbmcgYW4gWE1MIHN0eWxlc2hlZXQgaW50byBhIEphdmEgY2xhc3MuCi0gKgotICogIDcpIFhQYXRoIGlzIGEgc3BlY2lmaWNhdGlvbiB0aGF0IGRlc2NyaWJlcyBhIG5vdGF0aW9uIGZvciBpZGVudGlmeWluZwotICogICAgIG5vZGVzIGluIGEgdHJlZS1zdHJ1Y3R1cmVkIHJlcHJlc2VudGF0aW9uIG9mIGFuIFhNTCBkb2N1bWVudC4gIEFuCi0gKiAgICAgaW5zdGFuY2Ugb2YgdGhhdCBub3RhdGlvbiBpcyByZWZlcnJlZCB0byBhcyBhbiBYUGF0aCBleHByZXNzaW9uLgotICoKLSAqLwotCi0gIC8qKiBNYXhpbXVtIGVycm9yIG1lc3NhZ2VzLCB0aGlzIGlzIG5lZWRlZCB0byBrZWVwIHRyYWNrIG9mIHRoZSBudW1iZXIgb2YgbWVzc2FnZXMuICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BWF9DT0RFID0gNjE7Ci0KLSAgLyoqIE1heGltdW0gd2FybmluZ3MsIHRoaXMgaXMgbmVlZGVkIHRvIGtlZXAgdHJhY2sgb2YgdGhlIG51bWJlciBvZiB3YXJuaW5ncy4gICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFYX1dBUk5JTkcgPSAwOwotCi0gIC8qKiBNYXhpbXVtIG1pc2Mgc3RyaW5ncy4gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVhfT1RIRVJTID0gNDsKLQotICAvKiogTWF4aW11bSB0b3RhbCB3YXJuaW5ncyBhbmQgZXJyb3IgbWVzc2FnZXMuICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BWF9NRVNTQUdFUyA9IE1BWF9DT0RFICsgTUFYX1dBUk5JTkcgKyAxOwotCi0KLSAgLyoKLSAgICogTWVzc2FnZSBrZXlzCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEID0gIkVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfT1ZFUldSSVRFX0NBVVNFID0gIkVSX0NBTk5PVF9PVkVSV1JJVEVfQ0FVU0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19ERUZBVUxUX0lNUEwgPSAiRVJfTk9fREVGQVVMVF9JTVBMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0hVTktFRElOVEFSUkFZX05PVF9TVVBQT1JURUQgPSAiRVJfQ0hVTktFRElOVEFSUkFZX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9PRkZTRVRfQklHR0VSX1RIQU5fU0xPVCA9ICJFUl9PRkZTRVRfQklHR0VSX1RIQU5fU0xPVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPUk9VVElORV9OT1RfQVZBSUwgPSAiRVJfQ09ST1VUSU5FX05PVF9BVkFJTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPUk9VVElORV9DT19FWElUID0gIkVSX0NPUk9VVElORV9DT19FWElUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09KT0lOUk9VVElORVNFVF9GQUlMRUQgPSAiRVJfQ09KT0lOUk9VVElORVNFVF9GQUlMRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1JPVVRJTkVfUEFSQU0gPSAiRVJfQ09ST1VUSU5FX1BBUkFNIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUEFSU0VSX0RPVEVSTUlOQVRFX0FOU1dFUlMgPSAiRVJfUEFSU0VSX0RPVEVSTUlOQVRFX0FOU1dFUlMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19QQVJTRV9DQUxMX1dISUxFX1BBUlNJTkcgPSAiRVJfTk9fUEFSU0VfQ0FMTF9XSElMRV9QQVJTSU5HIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVFlQRURfSVRFUkFUT1JfQVhJU19OT1RfSU1QTEVNRU5URUQgPSAiRVJfVFlQRURfSVRFUkFUT1JfQVhJU19OT1RfSU1QTEVNRU5URUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JVEVSQVRPUl9BWElTX05PVF9JTVBMRU1FTlRFRCA9ICJFUl9JVEVSQVRPUl9BWElTX05PVF9JTVBMRU1FTlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lURVJBVE9SX0NMT05FX05PVF9TVVBQT1JURUQgPSAiRVJfSVRFUkFUT1JfQ0xPTkVfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1VOS05PV05fQVhJU19UWVBFID0gIkVSX1VOS05PV05fQVhJU19UWVBFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQVhJU19OT1RfU1VQUE9SVEVEID0gIkVSX0FYSVNfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX0RUTUlEU19BVkFJTCA9ICJFUl9OT19EVE1JRFNfQVZBSUwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT1RfU1VQUE9SVEVEID0gIkVSX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT0RFX05PTl9OVUxMID0gIkVSX05PREVfTk9OX05VTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRF9OT1RfUkVTT0xWRV9OT0RFID0gIkVSX0NPVUxEX05PVF9SRVNPTFZFX05PREUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TVEFSVFBBUlNFX1dISUxFX1BBUlNJTkcgPSAiRVJfU1RBUlRQQVJTRV9XSElMRV9QQVJTSU5HIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU1RBUlRQQVJTRV9ORUVEU19TQVhQQVJTRVIgPSAiRVJfU1RBUlRQQVJTRV9ORUVEU19TQVhQQVJTRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRF9OT1RfSU5JVF9QQVJTRVIgPSAiRVJfQ09VTERfTk9UX0lOSVRfUEFSU0VSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhDRVBUSU9OX0NSRUFUSU5HX1BPT0wgPSAiRVJfRVhDRVBUSU9OX0NSRUFUSU5HX1BPT0wiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QQVRIX0NPTlRBSU5TX0lOVkFMSURfRVNDQVBFX1NFUVVFTkNFID0gIkVSX1BBVEhfQ09OVEFJTlNfSU5WQUxJRF9FU0NBUEVfU0VRVUVOQ0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TQ0hFTUVfUkVRVUlSRUQgPSAiRVJfU0NIRU1FX1JFUVVJUkVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fU0NIRU1FX0lOX1VSSSA9ICJFUl9OT19TQ0hFTUVfSU5fVVJJIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fU0NIRU1FX0lOVVJJID0gIkVSX05PX1NDSEVNRV9JTlVSSSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BBVEhfSU5WQUxJRF9DSEFSID0gIkVSX1BBVEhfSU5WQUxJRF9DSEFSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU0NIRU1FX0ZST01fTlVMTF9TVFJJTkcgPSAiRVJfU0NIRU1FX0ZST01fTlVMTF9TVFJJTkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TQ0hFTUVfTk9UX0NPTkZPUk1BTlQgPSAiRVJfU0NIRU1FX05PVF9DT05GT1JNQU5UIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSE9TVF9BRERSRVNTX05PVF9XRUxMRk9STUVEID0gIkVSX0hPU1RfQUREUkVTU19OT1RfV0VMTEZPUk1FRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BPUlRfV0hFTl9IT1NUX05VTEwgPSAiRVJfUE9SVF9XSEVOX0hPU1RfTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfUE9SVCA9ICJFUl9JTlZBTElEX1BPUlQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GUkFHX0ZPUl9HRU5FUklDX1VSSSA9IkVSX0ZSQUdfRk9SX0dFTkVSSUNfVVJJIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRlJBR19XSEVOX1BBVEhfTlVMTCA9ICJFUl9GUkFHX1dIRU5fUEFUSF9OVUxMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRlJBR19JTlZBTElEX0NIQVIgPSAiRVJfRlJBR19JTlZBTElEX0NIQVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QQVJTRVJfSU5fVVNFID0gIkVSX1BBUlNFUl9JTl9VU0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfQ0hBTkdFX1dISUxFX1BBUlNJTkcgPSAiRVJfQ0FOTk9UX0NIQU5HRV9XSElMRV9QQVJTSU5HIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU0VMRl9DQVVTQVRJT05fTk9UX1BFUk1JVFRFRCA9ICJFUl9TRUxGX0NBVVNBVElPTl9OT1RfUEVSTUlUVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fVVNFUklORk9fSUZfTk9fSE9TVCA9ICJFUl9OT19VU0VSSU5GT19JRl9OT19IT1NUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fUE9SVF9JRl9OT19IT1NUID0gIkVSX05PX1BPUlRfSUZfTk9fSE9TVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1FVRVJZX1NUUklOR19JTl9QQVRIID0gIkVSX05PX1FVRVJZX1NUUklOR19JTl9QQVRIIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fRlJBR01FTlRfU1RSSU5HX0lOX1BBVEggPSAiRVJfTk9fRlJBR01FTlRfU1RSSU5HX0lOX1BBVEgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfSU5JVF9VUklfRU1QVFlfUEFSTVMgPSAiRVJfQ0FOTk9UX0lOSVRfVVJJX0VNUFRZX1BBUk1TIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTUVUSE9EX05PVF9TVVBQT1JURUQgPSJFUl9NRVRIT0RfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOQ1JTQVhTUkNGSUxURVJfTk9UX1JFU1RBUlRBQkxFID0gIkVSX0lOQ1JTQVhTUkNGSUxURVJfTk9UX1JFU1RBUlRBQkxFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWE1MUkRSX05PVF9CRUZPUkVfU1RBUlRQQVJTRSA9ICJFUl9YTUxSRFJfTk9UX0JFRk9SRV9TVEFSVFBBUlNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQVhJU19UUkFWRVJTRVJfTk9UX1NVUFBPUlRFRCA9ICJFUl9BWElTX1RSQVZFUlNFUl9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVJST1JIQU5ETEVSX0NSRUFURURfV0lUSF9OVUxMX1BSSU5UV1JJVEVSID0gIkVSX0VSUk9SSEFORExFUl9DUkVBVEVEX1dJVEhfTlVMTF9QUklOVFdSSVRFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NZU1RFTUlEX1VOS05PV04gPSAiRVJfU1lTVEVNSURfVU5LTk9XTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0xPQ0FUSU9OX1VOS05PV04gPSAiRVJfTE9DQVRJT05fVU5LTk9XTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BSRUZJWF9NVVNUX1JFU09MVkUgPSAiRVJfUFJFRklYX01VU1RfUkVTT0xWRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NSRUFURURPQ1VNRU5UX05PVF9TVVBQT1JURUQgPSAiRVJfQ1JFQVRFRE9DVU1FTlRfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NISUxEX0hBU19OT19PV05FUl9ET0NVTUVOVCA9ICJFUl9DSElMRF9IQVNfTk9fT1dORVJfRE9DVU1FTlQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DSElMRF9IQVNfTk9fT1dORVJfRE9DVU1FTlRfRUxFTUVOVCA9ICJFUl9DSElMRF9IQVNfTk9fT1dORVJfRE9DVU1FTlRfRUxFTUVOVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfT1VUUFVUX1RFWFRfQkVGT1JFX0RPQyA9ICJFUl9DQU5UX09VVFBVVF9URVhUX0JFRk9SRV9ET0MiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX0hBVkVfTU9SRV9USEFOX09ORV9ST09UID0gIkVSX0NBTlRfSEFWRV9NT1JFX1RIQU5fT05FX1JPT1QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9BUkdfTE9DQUxOQU1FX05VTEwgPSAiRVJfQVJHX0xPQ0FMTkFNRV9OVUxMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQVJHX0xPQ0FMTkFNRV9JTlZBTElEID0gIkVSX0FSR19MT0NBTE5BTUVfSU5WQUxJRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FSR19QUkVGSVhfSU5WQUxJRCA9ICJFUl9BUkdfUFJFRklYX0lOVkFMSUQiOwotCi0gIC8vIE1lc3NhZ2Uga2V5cyB1c2VkIGJ5IHRoZSBzZXJpYWxpemVyCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1JFU09VUkNFX0NPVUxEX05PVF9GSU5EID0gIkVSX1JFU09VUkNFX0NPVUxEX05PVF9GSU5EIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUkVTT1VSQ0VfQ09VTERfTk9UX0xPQUQgPSAiRVJfUkVTT1VSQ0VfQ09VTERfTk9UX0xPQUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9CVUZGRVJfU0laRV9MRVNTVEhBTl9aRVJPID0gIkVSX0JVRkZFUl9TSVpFX0xFU1NUSEFOX1pFUk8iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX1VURjE2X1NVUlJPR0FURSA9ICJFUl9JTlZBTElEX1VURjE2X1NVUlJPR0FURSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX09JRVJST1IgPSAiRVJfT0lFUlJPUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05BTUVTUEFDRV9QUkVGSVggPSAiRVJfTkFNRVNQQUNFX1BSRUZJWCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NUUkFZX0FUVFJJQlVURSA9ICJFUl9TVFJBWV9BVFRJUkJVVEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TVFJBWV9OQU1FU1BBQ0UgPSAiRVJfU1RSQVlfTkFNRVNQQUNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTERfTk9UX0xPQURfUkVTT1VSQ0UgPSAiRVJfQ09VTERfTk9UX0xPQURfUkVTT1VSQ0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRF9OT1RfTE9BRF9NRVRIT0RfUFJPUEVSVFkgPSAiRVJfQ09VTERfTk9UX0xPQURfTUVUSE9EX1BST1BFUlRZIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU0VSSUFMSVpFUl9OT1RfQ09OVEVOVEhBTkRMRVIgPSAiRVJfU0VSSUFMSVpFUl9OT1RfQ09OVEVOVEhBTkRMRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTExFR0FMX0FUVFJJQlVURV9QT1NJVElPTiA9ICJFUl9JTExFR0FMX0FUVFJJQlVURV9QT1NJVElPTiI7Ci0KLSAgLyoKLSAgICogTm93IGZpbGwgaW4gdGhlIG1lc3NhZ2UgdGV4dC4KLSAgICogVGhlbiBmaWxsIGluIHRoZSBtZXNzYWdlIHRleHQgZm9yIHRoYXQgbWVzc2FnZSBjb2RlIGluIHRoZQotICAgKiBhcnJheS4gVXNlIHRoZSBuZXcgZXJyb3IgY29kZSBhcyB0aGUgaW5kZXggaW50byB0aGUgYXJyYXkuCi0gICAqLwotCi0gIC8vIEVycm9yIG1lc3NhZ2VzLi4uCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIE9iamVjdFtdW10gX2NvbnRlbnRzID0gbmV3IE9iamVjdFtdW10gewotCi0gIC8qKiBFcnJvciBtZXNzYWdlIElEIHRoYXQgaGFzIGEgbnVsbCBtZXNzYWdlLCBidXQgdGFrZXMgaW4gYSBzaW5nbGUgb2JqZWN0LiAgICAqLwotICAgIHsiRVIwMDAwIiAsICJ7MH0iIH0sCi0KLSAgICB7IEVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQsCi0gICAgICAiRnVua2NpYSBuaWUgamUgcG9kcG9yb3Zhblx1MDBlMSEifSwKLQotICAgIHsgRVJfQ0FOTk9UX09WRVJXUklURV9DQVVTRSwKLSAgICAgICJOaWUgamUgbW9cdTAxN2VuXHUwMGU5IHByZXBcdTAwZWRzYVx1MDE2NSBwclx1MDBlZFx1MDEwZGludSJ9LAotCi0gICAgeyBFUl9OT19ERUZBVUxUX0lNUEwsCi0gICAgICAiTmVib2xhIG5cdTAwZTFqZGVuXHUwMGUxIFx1MDE3ZWlhZG5hIHByZWR2b2xlblx1MDBlMSBpbXBsZW1lbnRcdTAwZTFjaWEgIn0sCi0KLSAgICB7IEVSX0NIVU5LRURJTlRBUlJBWV9OT1RfU1VQUE9SVEVELAotICAgICAgIkNodW5rZWRJbnRBcnJheSh7MH0pIG5pZSBqZSBtb21lbnRcdTAwZTFsbmUgcG9kcG9yb3Zhblx1MDBmZCJ9LAotCi0gICAgeyBFUl9PRkZTRVRfQklHR0VSX1RIQU5fU0xPVCwKLSAgICAgICJPZmZzZXQgdlx1MDBlNFx1MDEwZFx1MDE2MVx1MDBlZCwgbmVcdTAxN2Ugelx1MDBlMXN1dmthIn0sCi0KLSAgICB7IEVSX0NPUk9VVElORV9OT1RfQVZBSUwsCi0gICAgICAiS29ydXRpbmEgbmllIGplIGRvc3R1cG5cdTAwZTEsIGlkPXswfSJ9LAotCi0gICAgeyBFUl9DT1JPVVRJTkVfQ09fRVhJVCwKLSAgICAgICJDb3JvdXRpbmVNYW5hZ2VyIG9iZHJcdTAxN2VhbCBwb1x1MDE3ZWlhZGF2a3UgY29fZXhpdCgpIn0sCi0KLSAgICB7IEVSX0NPSk9JTlJPVVRJTkVTRVRfRkFJTEVELAotICAgICAgInpseWhhbCBjb19qb2luQ29yb3V0aW5lU2V0KCkifSwKLQotICAgIHsgRVJfQ09ST1VUSU5FX1BBUkFNLAotICAgICAgIkNoeWJhIHBhcmFtZXRyYSBrb3J1dGlueSAoezB9KSJ9LAotCi0gICAgeyBFUl9QQVJTRVJfRE9URVJNSU5BVEVfQU5TV0VSUywKLSAgICAgICJcbk5FT1x1MDEwY0FLXHUwMGMxVkFOXHUwMGM5OiBBbmFseXpcdTAwZTF0b3IgZG9UZXJtaW5hdGUgb2Rwb3ZlZFx1MDBlMSB7MH0ifSwKLQotICAgIHsgRVJfTk9fUEFSU0VfQ0FMTF9XSElMRV9QQVJTSU5HLAotICAgICAgInN5bnRha3RpY2tcdTAwZmQgYW5hbHl6XHUwMGUxdG9yIG5lbVx1MDBmNFx1MDE3ZWUgYnlcdTAxNjUgdm9sYW5cdTAwZmQgcG9cdTAxMGRhcyB2eWtvblx1MDBlMXZhbmlhIGFuYWxcdTAwZmR6eSJ9LAotCi0gICAgeyBFUl9UWVBFRF9JVEVSQVRPUl9BWElTX05PVF9JTVBMRU1FTlRFRCwKLSAgICAgICJDaHliYTogbmFwXHUwMGVkc2FuXHUwMGZkIGl0ZXJcdTAwZTF0b3IgcHJlIG9zIHswfSBuaWUgamUgaW1wbGVtZW50b3Zhblx1MDBmZCJ9LAotCi0gICAgeyBFUl9JVEVSQVRPUl9BWElTX05PVF9JTVBMRU1FTlRFRCwKLSAgICAgICJDaHliYTogaXRlclx1MDBlMXRvciBwcmUgb3MgezB9IG5pZSBqZSBpbXBsZW1lbnRvdmFuXHUwMGZkICJ9LAotCi0gICAgeyBFUl9JVEVSQVRPUl9DTE9ORV9OT1RfU1VQUE9SVEVELAotICAgICAgIktsb24gaXRlclx1MDBlMXRvcmEgbmllIGplIHBvZHBvcm92YW5cdTAwZmQifSwKLQotICAgIHsgRVJfVU5LTk9XTl9BWElTX1RZUEUsCi0gICAgICAiTmV6blx1MDBlMW15IHR5cCBwcmV0XHUwMGVkbmFuaWEgb3NcdTAwZWQ6IHswfSJ9LAotCi0gICAgeyBFUl9BWElTX05PVF9TVVBQT1JURUQsCi0gICAgICAiUHJldFx1MDBlZG5hbmllIG9zXHUwMGVkIG5pZSBqZSBwb2Rwb3JvdmFuXHUwMGU5OiB7MH0ifSwKLQotICAgIHsgRVJfTk9fRFRNSURTX0FWQUlMLAotICAgICAgIlx1MDE3ZGlhZG5lIFx1MDEwZmFsXHUwMTYxaWUgRFRNIElEIG5pZSBzXHUwMGZhIGRvc3R1cG5cdTAwZTkifSwKLQotICAgIHsgRVJfTk9UX1NVUFBPUlRFRCwKLSAgICAgICJOaWUgamUgcG9kcG9yb3Zhblx1MDBlOTogezB9In0sCi0KLSAgICB7IEVSX05PREVfTk9OX05VTEwsCi0gICAgICAiUHJlIGdldERUTUhhbmRsZUZyb21Ob2RlIG11c1x1MDBlZCBieVx1MDE2NSB1em9sIG5lbnVsb3ZcdTAwZmQifSwKLQotICAgIHsgRVJfQ09VTERfTk9UX1JFU09MVkVfTk9ERSwKLSAgICAgICJOZWJvbG8gbW9cdTAxN2VuXHUwMGU5IHVyXHUwMTBkaVx1MDE2NSB1em9sIG5hIHNwcmFjb3ZhbmllIn0sCi0KLSAgICB7IEVSX1NUQVJUUEFSU0VfV0hJTEVfUEFSU0lORywKLSAgICAgICAic3RhcnRQYXJzZSBuZW1cdTAwZjRcdTAxN2VlIGJ5XHUwMTY1IHZvbGFuXHUwMGZkIHBvXHUwMTBkYXMgdnlrb25cdTAwZTF2YW5pYSBhbmFsXHUwMGZkenkifSwKLQotICAgIHsgRVJfU1RBUlRQQVJTRV9ORUVEU19TQVhQQVJTRVIsCi0gICAgICAgInN0YXJ0UGFyc2UgcG90cmVidWplIG5lbnVsb3ZcdTAwZmQgU0FYUGFyc2VyIn0sCi0KLSAgICB7IEVSX0NPVUxEX05PVF9JTklUX1BBUlNFUiwKLSAgICAgICAibmVib2xvIG1vXHUwMTdlblx1MDBlOSBpbmljaWFsaXpvdmFcdTAxNjUgc3ludGFrdGlja1x1MDBmZCBhbmFseXpcdTAwZTF0b3IgcG9tb2NvdSJ9LAotCi0gICAgeyBFUl9FWENFUFRJT05fQ1JFQVRJTkdfUE9PTCwKLSAgICAgICAidlx1MDBmZG5pbWthIHZ5dHZcdTAwZTFyYW5pYSBub3ZlaiBpblx1MDE2MXRhbmNpZSBvYmxhc3RpIn0sCi0KLSAgICB7IEVSX1BBVEhfQ09OVEFJTlNfSU5WQUxJRF9FU0NBUEVfU0VRVUVOQ0UsCi0gICAgICAgIkNlc3RhIG9ic2FodWplIG5lcGxhdG5cdTAwZmEgXHUwMGZhbmlrb3ZcdTAwZmEgc2VrdmVuY2l1In0sCi0KLSAgICB7IEVSX1NDSEVNRV9SRVFVSVJFRCwKLSAgICAgICAiSmUgcG9cdTAxN2VhZG92YW5cdTAwZTEgc2NoXHUwMGU5bWEhIn0sCi0KLSAgICB7IEVSX05PX1NDSEVNRV9JTl9VUkksCi0gICAgICAgIlYgVVJJIHNhIG5lbmFcdTAxNjFsYSBcdTAxN2VpYWRuYSBzY2hcdTAwZTltYTogezB9In0sCi0KLSAgICB7IEVSX05PX1NDSEVNRV9JTlVSSSwKLSAgICAgICAiViBVUkkgbmVib2xhIG5cdTAwZTFqZGVuXHUwMGUxIFx1MDE3ZWlhZG5hIHNjaFx1MDBlOW1hIn0sCi0KLSAgICB7IEVSX1BBVEhfSU5WQUxJRF9DSEFSLAotICAgICAgICJDZXN0YSBvYnNhaHVqZSBuZXBsYXRuXHUwMGZkIHpuYWs6IHswfSJ9LAotCi0gICAgeyBFUl9TQ0hFTUVfRlJPTV9OVUxMX1NUUklORywKLSAgICAgICAiTmllIGplIG1vXHUwMTdlblx1MDBlOSBzdGFub3ZpXHUwMTY1IHNjaFx1MDBlOW11IHogbnVsb3ZcdTAwZTlobyByZVx1MDE2NWF6Y2EifSwKLQotICAgIHsgRVJfU0NIRU1FX05PVF9DT05GT1JNQU5ULAotICAgICAgICJOZXpob2RuXHUwMGUxIHNjaFx1MDBlOW1hLiJ9LAotCi0gICAgeyBFUl9IT1NUX0FERFJFU1NfTk9UX1dFTExGT1JNRUQsCi0gICAgICAgIkhvc3RpdGVcdTAxM2UgbmllIGplIHNwclx1MDBlMXZuZSBmb3JtXHUwMGUxdG92YW5cdTAwZTEgYWRyZXNhIn0sCi0KLSAgICB7IEVSX1BPUlRfV0hFTl9IT1NUX05VTEwsCi0gICAgICAgIk5lbVx1MDBmNFx1MDE3ZWUgYnlcdTAxNjUgc3Rhbm92ZW5cdTAwZmQgcG9ydCwgYWsgamUgaG9zdGl0ZVx1MDEzZSBudWxsIn0sCi0KLSAgICB7IEVSX0lOVkFMSURfUE9SVCwKLSAgICAgICAiTmVwbGF0blx1MDBlOSBcdTAxMGRcdTAwZWRzbG8gcG9ydHUifSwKLQotICAgIHsgRVJfRlJBR19GT1JfR0VORVJJQ19VUkksCi0gICAgICAgIkZyYWdtZW50IG1cdTAwZjRcdTAxN2VlIGJ5XHUwMTY1IHN0YW5vdmVuXHUwMGZkIGxlbiBwcmUgdlx1MDE2MWVvYmVjblx1MDBlOSBVUkkifSwKLQotICAgIHsgRVJfRlJBR19XSEVOX1BBVEhfTlVMTCwKLSAgICAgICAiQWsgamUgY2VzdGEgbnVsb3ZcdTAwZTEsIG5lbVx1MDBmNFx1MDE3ZWUgYnlcdTAxNjUgc3Rhbm92ZW5cdTAwZmQgZnJhZ21lbnQifSwKLQotICAgIHsgRVJfRlJBR19JTlZBTElEX0NIQVIsCi0gICAgICAgIkZyYWdtZW50IG9ic2FodWplIG5lcGxhdG5cdTAwZmQgem5hayJ9LAotCi0gICAgeyBFUl9QQVJTRVJfSU5fVVNFLAotICAgICAgIlN5bnRha3RpY2tcdTAwZmQgYW5hbHl6XHUwMGUxdG9yIGplIHVcdTAxN2UgcG91XHUwMTdlXHUwMGVkdmFuXHUwMGZkIn0sCi0KLSAgICB7IEVSX0NBTk5PVF9DSEFOR0VfV0hJTEVfUEFSU0lORywKLSAgICAgICJOaWUgamUgbW9cdTAxN2VuXHUwMGU5IHptZW5pXHUwMTY1IHswfSB7MX0gcG9cdTAxMGRhcyB2eWtvblx1MDBlMXZhbmlhIGFuYWxcdTAwZmR6eSJ9LAotCi0gICAgeyBFUl9TRUxGX0NBVVNBVElPTl9OT1RfUEVSTUlUVEVELAotICAgICAgIlNhbW96YXByXHUwMGVkXHUwMTBkaW5lbmllIG5pZSBqZSBwb3ZvbGVuXHUwMGU5In0sCi0KLSAgICB7IEVSX05PX1VTRVJJTkZPX0lGX05PX0hPU1QsCi0gICAgICAiQWsgbmVib2wgemFkYW5cdTAwZmQgaG9zdGl0ZVx1MDEzZSwgbW9cdTAxN2VubyBuZWJvbG8gemFkYW5cdTAwZTkgdXNlcmluZm8ifSwKLQotICAgIHsgRVJfTk9fUE9SVF9JRl9OT19IT1NULAotICAgICAgIkFrIG5lYm9sIHphZGFuXHUwMGZkIGhvc3RpdGVcdTAxM2UsIG1vXHUwMTdlbm8gbmVib2wgemFkYW5cdTAwZmQgcG9ydCJ9LAotCi0gICAgeyBFUl9OT19RVUVSWV9TVFJJTkdfSU5fUEFUSCwKLSAgICAgICJSZVx1MDE2NWF6ZWMgZG90YXp1IG5lbVx1MDBmNFx1MDE3ZWUgYnlcdTAxNjUgemFkYW5cdTAwZmQgdiBjZXN0ZSBhIHJlXHUwMTY1YXpjaSBkb3RhenUifSwKLQotICAgIHsgRVJfTk9fRlJBR01FTlRfU1RSSU5HX0lOX1BBVEgsCi0gICAgICAiRnJhZ21lbnQgbmVtXHUwMGY0XHUwMTdlZSBieVx1MDE2NSB6YWRhblx1MDBmZCB2IGNlc3RlLCBhbmkgdm8gZnJhZ21lbnRlIn0sCi0KLSAgICB7IEVSX0NBTk5PVF9JTklUX1VSSV9FTVBUWV9QQVJNUywKLSAgICAgICJOaWUgamUgbW9cdTAxN2VuXHUwMGU5IGluaWNpYWxpem92YVx1MDE2NSBVUkkgcyBwclx1MDBlMXpkbnltaSBwYXJhbWV0cmFtaSJ9LAotCi0gICAgeyBFUl9NRVRIT0RfTk9UX1NVUFBPUlRFRCwKLSAgICAgICJNZXRcdTAwZjNkYSBlXHUwMTYxdGUgbmllIGplIHBvZHBvcm92YW5cdTAwZTEgIn0sCi0KLSAgICB7IEVSX0lOQ1JTQVhTUkNGSUxURVJfTk9UX1JFU1RBUlRBQkxFLAotICAgICAgIkluY3JlbWVudGFsU0FYU291cmNlX0ZpbHRlciBuaWUgamUgbW9tZW50XHUwMGUxbG5lIHJlXHUwMTYxdGFydG92YXRlXHUwMTNlblx1MDBmZCJ9LAotCi0gICAgeyBFUl9YTUxSRFJfTk9UX0JFRk9SRV9TVEFSVFBBUlNFLAotICAgICAgIlhNTFJlYWRlciBuZXByZWRjaFx1MDBlMWR6YSBwb1x1MDE3ZWlhZGF2a2UgbmEgc3RhcnRQYXJzZSJ9LAotCi0gICAgeyBFUl9BWElTX1RSQVZFUlNFUl9OT1RfU1VQUE9SVEVELAotICAgICAgIlByZXRcdTAwZWRuYW5pZSBvc1x1MDBlZCBuaWUgamUgcG9kcG9yb3Zhblx1MDBlOTogezB9In0sCi0KLSAgICB7IEVSX0VSUk9SSEFORExFUl9DUkVBVEVEX1dJVEhfTlVMTF9QUklOVFdSSVRFUiwKLSAgICAgICJMaXN0aW5nRXJyb3JIYW5kbGVyIHZ5dHZvcmVuXHUwMGZkIHMgbnVsb3ZcdTAwZmRtIFByaW50V3JpdGVyISJ9LAotCi0gICAgeyBFUl9TWVNURU1JRF9VTktOT1dOLAotICAgICAgIk5lem5cdTAwZTFtZSBTeXN0ZW1JZCJ9LAotCi0gICAgeyBFUl9MT0NBVElPTl9VTktOT1dOLAotICAgICAgIk5lem5cdTAwZTFtZSBtaWVzdG8gdlx1MDBmZHNreXR1IGNoeWJ5In0sCi0KLSAgICB7IEVSX1BSRUZJWF9NVVNUX1JFU09MVkUsCi0gICAgICAiUHJlZHBvbmEgc2EgbXVzXHUwMGVkIHJvemxcdTAwZWRcdTAxNjFpXHUwMTY1IGRvIG5cdTAwZTF6dm92XHUwMGU5aG8gcHJpZXN0b3J1OiB7MH0ifSwKLQotICAgIHsgRVJfQ1JFQVRFRE9DVU1FTlRfTk9UX1NVUFBPUlRFRCwKLSAgICAgICJjcmVhdGVEb2N1bWVudCgpIG5pZSBqZSBwb2Rwb3JvdmFuXHUwMGU5IFhQYXRoQ29udGV4dCEifSwKLQotICAgIHsgRVJfQ0hJTERfSEFTX05PX09XTkVSX0RPQ1VNRU5ULAotICAgICAgIlBvdG9tb2sgYXRyaWJcdTAwZmF0dSBuZW1cdTAwZTEgZG9rdW1lbnQgdmxhc3RuXHUwMGVka2EhIn0sCi0KLSAgICB7IEVSX0NISUxEX0hBU19OT19PV05FUl9ET0NVTUVOVF9FTEVNRU5ULAotICAgICAgIlBvdG9tb2sgYXRyaWJcdTAwZmF0dSBuZW1cdTAwZTEgc1x1MDBmYVx1MDEwZGFzXHUwMTY1IGRva3VtZW50dSB2bGFzdG5cdTAwZWRrYSEifSwKLQotICAgIHsgRVJfQ0FOVF9PVVRQVVRfVEVYVF9CRUZPUkVfRE9DLAotICAgICAgIlVwb3pvcm5lbmllOiBuZW1vXHUwMTdlbm8gdnlwdXN0aVx1MDE2NSB0ZXh0IHByZWQgZWxlbWVudG9tIGRva3VtZW50dSEgIElnbm9yb3ZhbmllLi4uIn0sCi0KLSAgICB7IEVSX0NBTlRfSEFWRV9NT1JFX1RIQU5fT05FX1JPT1QsCi0gICAgICAiTmllIGplIG1vXHUwMTdlblx1MDBlOSBtYVx1MDE2NSB2aWFjLCBuZVx1MDE3ZSBqZWRlbiBrb3JlXHUwMTQ4IERPTSEifSwKLQotICAgIHsgRVJfQVJHX0xPQ0FMTkFNRV9OVUxMLAotICAgICAgICJBcmd1bWVudCAnbG9jYWxOYW1lJyBqZSBudWxsIn0sCi0KLSAgICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQSBRTkFNRSBoYXMgdGhlIHN5bnRhY3RpYyBmb3JtIFtOQ05hbWU6XU5DTmFtZQotICAgIC8vIFRoZSBsb2NhbG5hbWUgaXMgdGhlIHBvcnRpb24gYWZ0ZXIgdGhlIG9wdGlvbmFsIGNvbG9uOyB0aGUgbWVzc2FnZSBpbmRpY2F0ZXMKLSAgICAvLyB0aGF0IHRoZXJlIGlzIGEgcHJvYmxlbSB3aXRoIHRoYXQgcGFydCBvZiB0aGUgUU5BTUUuCi0gICAgeyBFUl9BUkdfTE9DQUxOQU1FX0lOVkFMSUQsCi0gICAgICAgIkxva1x1MDBlMWxueSBuXHUwMGUxem92IHYgUU5BTUUgYnkgbWFsIGJ5XHUwMTY1IHBsYXRuXHUwMGZkbSBOQ05hbWUifSwKLQotICAgIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBIFFOQU1FIGhhcyB0aGUgc3ludGFjdGljIGZvcm0gW05DTmFtZTpdTkNOYW1lCi0gICAgLy8gVGhlIHByZWZpeCBpcyB0aGUgcG9ydGlvbiBiZWZvcmUgdGhlIG9wdGlvbmFsIGNvbG9uOyB0aGUgbWVzc2FnZSBpbmRpY2F0ZXMKLSAgICAvLyB0aGF0IHRoZXJlIGlzIGEgcHJvYmxlbSB3aXRoIHRoYXQgcGFydCBvZiB0aGUgUU5BTUUuCi0gICAgeyBFUl9BUkdfUFJFRklYX0lOVkFMSUQsCi0gICAgICAgIlByZWRwb25hIHYgUU5BTUUgYnkgbWFsYSBieVx1MDE2NSBwbGF0blx1MDBmZG0gTkNOYW1lIn0sCi0KLSAgICB7ICJCQURfQ09ERSIsICJQYXJhbWV0ZXIgbmEgY3JlYXRlTWVzc2FnZSBib2wgbWltbyBvaHJhbmlcdTAxMGRlbmlhIn0sCi0gICAgeyAiRk9STUFUX0ZBSUxFRCIsICJWXHUwMGZkbmlta2EgcG9cdTAxMGRhcyB2b2xhbmlhIG1lc3NhZ2VGb3JtYXQifSwKLSAgICB7ICJsaW5lIiwgIlJpYWRvayAjIn0sCi0gICAgeyAiY29sdW1uIiwiU3RcdTAxM2FwZWMgIyJ9LAotCi0gICAge0VSX1NFUklBTElaRVJfTk9UX0NPTlRFTlRIQU5ETEVSLAotICAgICAgIlRyaWVkYSBzZXJpYWxpelx1MDBlMXRvcmEgJyd7MH0nJyBuZWltcGxlbWVudHVqZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlci4ifSwKLQotICAgIHtFUl9SRVNPVVJDRV9DT1VMRF9OT1RfRklORCwKLSAgICAgICJQcm9zdHJpZWRvayBbIHswfSBdIG5lbW9ob2wgYnlcdTAxNjUgblx1MDBlMWpkZW5cdTAwZmQuXG4gezF9IiB9LAotCi0gICAge0VSX1JFU09VUkNFX0NPVUxEX05PVF9MT0FELAotICAgICAgIlByb3N0cmllZG9rIFsgezB9IF0gc2EgbmVkYWwgbmFcdTAxMGRcdTAwZWR0YVx1MDE2NTogezF9IFxuIHsyfSBcdCB7M30iIH0sCi0KLSAgICB7RVJfQlVGRkVSX1NJWkVfTEVTU1RIQU5fWkVSTywKLSAgICAgICJWZVx1MDEzZWtvc1x1MDE2NSB2eXJvdm5cdTAwZTF2YWNlaiBwYW1cdTAwZTR0ZSA8PTAiIH0sCi0KLSAgICB7RVJfSU5WQUxJRF9VVEYxNl9TVVJST0dBVEUsCi0gICAgICAiQm9sbyB6aXN0ZW5cdTAwZTkgbmVwbGF0blx1MDBlOSBuYWhyYWRlbmllIFVURi0xNjogezB9ID8iIH0sCi0KLSAgICB7RVJfT0lFUlJPUiwKLSAgICAgICJjaHliYSBJTyIgfSwKLQotICAgIHtFUl9JTExFR0FMX0FUVFJJQlVURV9QT1NJVElPTiwKLSAgICAgICJOaWUgamUgbW9cdTAxN2VuXHUwMGU5IHByaWRhXHUwMTY1IGF0cmliXHUwMGZhdCB7MH0gcG8gdXpsb2NoIHBvdG9ta2EgYWxlYm8gcHJlZCB2eXR2b3Jlblx1MDBlZG0gZWxlbWVudHUuICBBdHJpYlx1MDBmYXQgYnVkZSBpZ25vcm92YW5cdTAwZmQuIn0sCi0KLSAgICAgIC8qCi0gICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN0eWxlc2hlZXQgY29udGFpbmVkIGEgcmVmZXJlbmNlIHRvIGEKLSAgICAgICAqIG5hbWVzcGFjZSBwcmVmaXggdGhhdCB3YXMgdW5kZWZpbmVkLiAgVGhlIHZhbHVlIG9mIHRoZSBzdWJzdGl0dXRpb24KLSAgICAgICAqIHRleHQgaXMgdGhlIG5hbWUgb2YgdGhlIHByZWZpeC4KLSAgICAgICAqLwotICAgIHtFUl9OQU1FU1BBQ0VfUFJFRklYLAotICAgICAgIk5cdTAwZTF6dm92XHUwMGZkIHByaWVzdG9yIHByZSBwcmVkcG9udSAnJ3swfScnIG5lYm9sIGRla2xhcm92YW5cdTAwZmQuIiB9LAotICAgICAgLyoKLSAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgcmVwb3J0ZWQgaWYgdGhlIHN0eWxlc2hlZXQKLSAgICAgICAqIGJlaW5nIHByb2Nlc3NlZCBhdHRlbXB0ZWQgdG8gY29uc3RydWN0IGFuIFhNTCBkb2N1bWVudCB3aXRoIGFuCi0gICAgICAgKiBhdHRyaWJ1dGUgaW4gYSBwbGFjZSBvdGhlciB0aGFuIG9uIGFuIGVsZW1lbnQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQKLSAgICAgICAqIHNwZWNpZmllcyB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlLgotICAgICAgICovCi0gICAge0VSX1NUUkFZX0FUVFJJQlVURSwKLSAgICAgICJBdHJpYlx1MDBmYXQgJyd7MH0nJyBqZSBtaW1vIGVsZW1lbnR1LiIgfSwKLQotICAgICAgLyoKLSAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBcyB3aXRoIHRoZSBwcmVjZWRpbmcgbWVzc2FnZSwgYSBuYW1lc3BhY2UKLSAgICAgICAqIGRlY2xhcmF0aW9uIGhhcyB0aGUgZm9ybSBvZiBhbiBhdHRyaWJ1dGUgYW5kIGlzIG9ubHkgcGVybWl0dGVkIHRvCi0gICAgICAgKiBhcHBlYXIgb24gYW4gZWxlbWVudC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCB7MH0gaXMgdGhlIG5hbWVzcGFjZQotICAgICAgICogcHJlZml4IGFuZCB7MX0gaXMgdGhlIFVSSSB0aGF0IHdhcyBiZWluZyB1c2VkIGluIHRoZSBlcnJvbmVvdXMKLSAgICAgICAqIG5hbWVzcGFjZSBkZWNsYXJhdGlvbi4KLSAgICAgICAqLwotICAgIHtFUl9TVFJBWV9OQU1FU1BBQ0UsCi0gICAgICAiRGVrbGFyXHUwMGUxY2lhIG5cdTAwZTF6dm92XHUwMGU5aG8gcHJpZXN0b3J1ICcnezB9Jyc9Jyd7MX0nJyBqZSBtaW1vIGVsZW1lbnR1LiIgfSwKLQotICAgIHtFUl9DT1VMRF9OT1RfTE9BRF9SRVNPVVJDRSwKLSAgICAgICJOZWRhbG8gc2EgbmFcdTAxMGRcdTAwZWR0YVx1MDE2NSAnJ3swfScnIChza29udHJvbHVqdGUgQ0xBU1NQQVRIKSwgcG91XHUwMTdlXHUwMGVkdmFqXHUwMGZhIHNhIHByZWR2b2xlblx1MDBlOSBob2Rub3R5In0sCi0KLSAgICB7RVJfQ09VTERfTk9UX0xPQURfTUVUSE9EX1BST1BFUlRZLAotICAgICAgIk5lZGFsIHNhIG5hXHUwMTBkXHUwMGVkdGFcdTAxNjUgc1x1MDBmYWJvciB2bGFzdG5vc3RcdTAwZWQgJyd7MH0nJyBwcmUgdlx1MDBmZHN0dXBuXHUwMGZhIG1ldFx1MDBmM2R1ICcnezF9JycgKHNrb250cm9sdWp0ZSBDTEFTU1BBVEgpIiB9Ci0KLQotICB9OwotCi0gIC8qKgotICAgKiBHZXQgdGhlIGxvb2t1cCB0YWJsZSBmb3IgZXJyb3IgbWVzc2FnZXMKLSAgICoKLSAgICogQHJldHVybiBUaGUgYXNzb2NpYXRpb24gbGlzdC4KLSAgICovCi0gIHB1YmxpYyBPYmplY3RbXVtdIGdldENvbnRlbnRzKCkKLSAgewotICAgIHJldHVybiBfY29udGVudHM7Ci0gIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvcmVzL1hNTEVycm9yUmVzb3VyY2VzX3N2LmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9yZXMvWE1MRXJyb3JSZXNvdXJjZXNfc3YuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggN2JlM2M2Yy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9yZXMvWE1MRXJyb3JSZXNvdXJjZXNfc3YuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQ1MCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzOwotCi0KLWltcG9ydCBqYXZhLnV0aWwuTGlzdFJlc291cmNlQnVuZGxlOwotCi0vKioKLSAqIFNldCB1cCBlcnJvciBtZXNzYWdlcy4KLSAqIFdlIGJ1aWxkIGEgdHdvIGRpbWVuc2lvbmFsIGFycmF5IG9mIG1lc3NhZ2Uga2V5cyBhbmQKLSAqIG1lc3NhZ2Ugc3RyaW5ncy4gSW4gb3JkZXIgdG8gYWRkIGEgbmV3IG1lc3NhZ2UgaGVyZSwKLSAqIHlvdSBuZWVkIHRvIGZpcnN0IGFkZCBhIFN0cmluZyBjb25zdGFudC4gQW5kIHlvdSBuZWVkCi0gKiB0byBlbnRlciBrZXksIHZhbHVlIHBhaXIgYXMgcGFydCBvZiB0aGUgY29udGVudHMKLSAqIGFycmF5LiBZb3UgYWxzbyBuZWVkIHRvIHVwZGF0ZSBNQVhfQ09ERSBmb3IgZXJyb3Igc3RyaW5ncwotICogYW5kIE1BWF9XQVJOSU5HIGZvciB3YXJuaW5ncyAoIE5lZWRlZCBmb3Igb25seSBpbmZvcm1hdGlvbgotICogcHVycG9zZSApCi0gKi8KLXB1YmxpYyBjbGFzcyBYTUxFcnJvclJlc291cmNlc19zdiBleHRlbmRzIExpc3RSZXNvdXJjZUJ1bmRsZQotewotCi0vKgotICogVGhpcyBmaWxlIGNvbnRhaW5zIGVycm9yIGFuZCB3YXJuaW5nIG1lc3NhZ2VzIHJlbGF0ZWQgdG8gWGFsYW4gRXJyb3IKLSAqIEhhbmRsaW5nLgotICoKLSAqICBHZW5lcmFsIG5vdGVzIHRvIHRyYW5zbGF0b3JzOgotICoKLSAqICAxKSBYYWxhbiAob3IgbW9yZSBwcm9wZXJseSwgWGFsYW4taW50ZXJwcmV0aXZlKSBhbmQgWFNMVEMgYXJlIG5hbWVzIG9mCi0gKiAgICAgY29tcG9uZW50cy4KLSAqICAgICBYU0xUIGlzIGFuIGFjcm9ueW0gZm9yICJYTUwgU3R5bGVzaGVldCBMYW5ndWFnZTogVHJhbnNmb3JtYXRpb25zIi4KLSAqICAgICBYU0xUQyBpcyBhbiBhY3JvbnltIGZvciBYU0xUIENvbXBpbGVyLgotICoKLSAqICAyKSBBIHN0eWxlc2hlZXQgaXMgYSBkZXNjcmlwdGlvbiBvZiBob3cgdG8gdHJhbnNmb3JtIGFuIGlucHV0IFhNTCBkb2N1bWVudAotICogICAgIGludG8gYSByZXN1bHRhbnQgWE1MIGRvY3VtZW50IChvciBIVE1MIGRvY3VtZW50IG9yIHRleHQpLiAgVGhlCi0gKiAgICAgc3R5bGVzaGVldCBpdHNlbGYgaXMgZGVzY3JpYmVkIGluIHRoZSBmb3JtIG9mIGFuIFhNTCBkb2N1bWVudC4KLSAqCi0gKiAgMykgQSB0ZW1wbGF0ZSBpcyBhIGNvbXBvbmVudCBvZiBhIHN0eWxlc2hlZXQgdGhhdCBpcyB1c2VkIHRvIG1hdGNoIGEKLSAqICAgICBwYXJ0aWN1bGFyIHBvcnRpb24gb2YgYW4gaW5wdXQgZG9jdW1lbnQgYW5kIHNwZWNpZmllcyB0aGUgZm9ybSBvZiB0aGUKLSAqICAgICBjb3JyZXNwb25kaW5nIHBvcnRpb24gb2YgdGhlIG91dHB1dCBkb2N1bWVudC4KLSAqCi0gKiAgNCkgQW4gZWxlbWVudCBpcyBhIG1hcmstdXAgdGFnIGluIGFuIFhNTCBkb2N1bWVudDsgYW4gYXR0cmlidXRlIGlzIGEKLSAqICAgICBtb2RpZmllciBvbiB0aGUgdGFnLiAgRm9yIGV4YW1wbGUsIGluIDxlbGVtIGF0dHI9J3ZhbCcgYXR0cjI9J3ZhbDInPgotICogICAgICJlbGVtIiBpcyBhbiBlbGVtZW50IG5hbWUsICJhdHRyIiBhbmQgImF0dHIyIiBhcmUgYXR0cmlidXRlIG5hbWVzIHdpdGgKLSAqICAgICB0aGUgdmFsdWVzICJ2YWwiIGFuZCAidmFsMiIsIHJlc3BlY3RpdmVseS4KLSAqCi0gKiAgNSkgQSBuYW1lc3BhY2UgZGVjbGFyYXRpb24gaXMgYSBzcGVjaWFsIGF0dHJpYnV0ZSB0aGF0IGlzIHVzZWQgdG8gYXNzb2NpYXRlCi0gKiAgICAgYSBwcmVmaXggd2l0aCBhIFVSSSAodGhlIG5hbWVzcGFjZSkuICBUaGUgbWVhbmluZ3Mgb2YgZWxlbWVudCBuYW1lcyBhbmQKLSAqICAgICBhdHRyaWJ1dGUgbmFtZXMgdGhhdCB1c2UgdGhhdCBwcmVmaXggYXJlIGRlZmluZWQgd2l0aCByZXNwZWN0IHRvIHRoYXQKLSAqICAgICBuYW1lc3BhY2UuCi0gKgotICogIDYpICJUcmFuc2xldCIgaXMgYW4gaW52ZW50ZWQgdGVybSB0aGF0IGRlc2NyaWJlcyB0aGUgY2xhc3MgZmlsZSB0aGF0Ci0gKiAgICAgcmVzdWx0cyBmcm9tIGNvbXBpbGluZyBhbiBYTUwgc3R5bGVzaGVldCBpbnRvIGEgSmF2YSBjbGFzcy4KLSAqCi0gKiAgNykgWFBhdGggaXMgYSBzcGVjaWZpY2F0aW9uIHRoYXQgZGVzY3JpYmVzIGEgbm90YXRpb24gZm9yIGlkZW50aWZ5aW5nCi0gKiAgICAgbm9kZXMgaW4gYSB0cmVlLXN0cnVjdHVyZWQgcmVwcmVzZW50YXRpb24gb2YgYW4gWE1MIGRvY3VtZW50LiAgQW4KLSAqICAgICBpbnN0YW5jZSBvZiB0aGF0IG5vdGF0aW9uIGlzIHJlZmVycmVkIHRvIGFzIGFuIFhQYXRoIGV4cHJlc3Npb24uCi0gKgotICovCi0KLSAgLyoqIE1heGltdW0gZXJyb3IgbWVzc2FnZXMsIHRoaXMgaXMgbmVlZGVkIHRvIGtlZXAgdHJhY2sgb2YgdGhlIG51bWJlciBvZiBtZXNzYWdlcy4gICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFYX0NPREUgPSA2MTsKLQotICAvKiogTWF4aW11bSB3YXJuaW5ncywgdGhpcyBpcyBuZWVkZWQgdG8ga2VlcCB0cmFjayBvZiB0aGUgbnVtYmVyIG9mIHdhcm5pbmdzLiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVhfV0FSTklORyA9IDA7Ci0KLSAgLyoqIE1heGltdW0gbWlzYyBzdHJpbmdzLiAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BWF9PVEhFUlMgPSA0OwotCi0gIC8qKiBNYXhpbXVtIHRvdGFsIHdhcm5pbmdzIGFuZCBlcnJvciBtZXNzYWdlcy4gICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFYX01FU1NBR0VTID0gTUFYX0NPREUgKyBNQVhfV0FSTklORyArIDE7Ci0KLQotICAvKgotICAgKiBNZXNzYWdlIGtleXMKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQgPSAiRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9PVkVSV1JJVEVfQ0FVU0UgPSAiRVJfQ0FOTk9UX09WRVJXUklURV9DQVVTRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX0RFRkFVTFRfSU1QTCA9ICJFUl9OT19ERUZBVUxUX0lNUEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DSFVOS0VESU5UQVJSQVlfTk9UX1NVUFBPUlRFRCA9ICJFUl9DSFVOS0VESU5UQVJSQVlfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX09GRlNFVF9CSUdHRVJfVEhBTl9TTE9UID0gIkVSX09GRlNFVF9CSUdHRVJfVEhBTl9TTE9UIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09ST1VUSU5FX05PVF9BVkFJTCA9ICJFUl9DT1JPVVRJTkVfTk9UX0FWQUlMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09ST1VUSU5FX0NPX0VYSVQgPSAiRVJfQ09ST1VUSU5FX0NPX0VYSVQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT0pPSU5ST1VUSU5FU0VUX0ZBSUxFRCA9ICJFUl9DT0pPSU5ST1VUSU5FU0VUX0ZBSUxFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPUk9VVElORV9QQVJBTSA9ICJFUl9DT1JPVVRJTkVfUEFSQU0iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QQVJTRVJfRE9URVJNSU5BVEVfQU5TV0VSUyA9ICJFUl9QQVJTRVJfRE9URVJNSU5BVEVfQU5TV0VSUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1BBUlNFX0NBTExfV0hJTEVfUEFSU0lORyA9ICJFUl9OT19QQVJTRV9DQUxMX1dISUxFX1BBUlNJTkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9UWVBFRF9JVEVSQVRPUl9BWElTX05PVF9JTVBMRU1FTlRFRCA9ICJFUl9UWVBFRF9JVEVSQVRPUl9BWElTX05PVF9JTVBMRU1FTlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lURVJBVE9SX0FYSVNfTk9UX0lNUExFTUVOVEVEID0gIkVSX0lURVJBVE9SX0FYSVNfTk9UX0lNUExFTUVOVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSVRFUkFUT1JfQ0xPTkVfTk9UX1NVUFBPUlRFRCA9ICJFUl9JVEVSQVRPUl9DTE9ORV9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5LTk9XTl9BWElTX1RZUEUgPSAiRVJfVU5LTk9XTl9BWElTX1RZUEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9BWElTX05PVF9TVVBQT1JURUQgPSAiRVJfQVhJU19OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fRFRNSURTX0FWQUlMID0gIkVSX05PX0RUTUlEU19BVkFJTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PVF9TVVBQT1JURUQgPSAiRVJfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PREVfTk9OX05VTEwgPSAiRVJfTk9ERV9OT05fTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxEX05PVF9SRVNPTFZFX05PREUgPSAiRVJfQ09VTERfTk9UX1JFU09MVkVfTk9ERSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NUQVJUUEFSU0VfV0hJTEVfUEFSU0lORyA9ICJFUl9TVEFSVFBBUlNFX1dISUxFX1BBUlNJTkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TVEFSVFBBUlNFX05FRURTX1NBWFBBUlNFUiA9ICJFUl9TVEFSVFBBUlNFX05FRURTX1NBWFBBUlNFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxEX05PVF9JTklUX1BBUlNFUiA9ICJFUl9DT1VMRF9OT1RfSU5JVF9QQVJTRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FWENFUFRJT05fQ1JFQVRJTkdfUE9PTCA9ICJFUl9FWENFUFRJT05fQ1JFQVRJTkdfUE9PTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BBVEhfQ09OVEFJTlNfSU5WQUxJRF9FU0NBUEVfU0VRVUVOQ0UgPSAiRVJfUEFUSF9DT05UQUlOU19JTlZBTElEX0VTQ0FQRV9TRVFVRU5DRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NDSEVNRV9SRVFVSVJFRCA9ICJFUl9TQ0hFTUVfUkVRVUlSRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19TQ0hFTUVfSU5fVVJJID0gIkVSX05PX1NDSEVNRV9JTl9VUkkiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19TQ0hFTUVfSU5VUkkgPSAiRVJfTk9fU0NIRU1FX0lOVVJJIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUEFUSF9JTlZBTElEX0NIQVIgPSAiRVJfUEFUSF9JTlZBTElEX0NIQVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TQ0hFTUVfRlJPTV9OVUxMX1NUUklORyA9ICJFUl9TQ0hFTUVfRlJPTV9OVUxMX1NUUklORyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NDSEVNRV9OT1RfQ09ORk9STUFOVCA9ICJFUl9TQ0hFTUVfTk9UX0NPTkZPUk1BTlQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9IT1NUX0FERFJFU1NfTk9UX1dFTExGT1JNRUQgPSAiRVJfSE9TVF9BRERSRVNTX05PVF9XRUxMRk9STUVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUE9SVF9XSEVOX0hPU1RfTlVMTCA9ICJFUl9QT1JUX1dIRU5fSE9TVF9OVUxMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9QT1JUID0gIkVSX0lOVkFMSURfUE9SVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZSQUdfRk9SX0dFTkVSSUNfVVJJID0iRVJfRlJBR19GT1JfR0VORVJJQ19VUkkiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GUkFHX1dIRU5fUEFUSF9OVUxMID0gIkVSX0ZSQUdfV0hFTl9QQVRIX05VTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GUkFHX0lOVkFMSURfQ0hBUiA9ICJFUl9GUkFHX0lOVkFMSURfQ0hBUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BBUlNFUl9JTl9VU0UgPSAiRVJfUEFSU0VSX0lOX1VTRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9DSEFOR0VfV0hJTEVfUEFSU0lORyA9ICJFUl9DQU5OT1RfQ0hBTkdFX1dISUxFX1BBUlNJTkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TRUxGX0NBVVNBVElPTl9OT1RfUEVSTUlUVEVEID0gIkVSX1NFTEZfQ0FVU0FUSU9OX05PVF9QRVJNSVRURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19VU0VSSU5GT19JRl9OT19IT1NUID0gIkVSX05PX1VTRVJJTkZPX0lGX05PX0hPU1QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19QT1JUX0lGX05PX0hPU1QgPSAiRVJfTk9fUE9SVF9JRl9OT19IT1NUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fUVVFUllfU1RSSU5HX0lOX1BBVEggPSAiRVJfTk9fUVVFUllfU1RSSU5HX0lOX1BBVEgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19GUkFHTUVOVF9TVFJJTkdfSU5fUEFUSCA9ICJFUl9OT19GUkFHTUVOVF9TVFJJTkdfSU5fUEFUSCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9JTklUX1VSSV9FTVBUWV9QQVJNUyA9ICJFUl9DQU5OT1RfSU5JVF9VUklfRU1QVFlfUEFSTVMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9NRVRIT0RfTk9UX1NVUFBPUlRFRCA9IkVSX01FVEhPRF9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5DUlNBWFNSQ0ZJTFRFUl9OT1RfUkVTVEFSVEFCTEUgPSAiRVJfSU5DUlNBWFNSQ0ZJTFRFUl9OT1RfUkVTVEFSVEFCTEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YTUxSRFJfTk9UX0JFRk9SRV9TVEFSVFBBUlNFID0gIkVSX1hNTFJEUl9OT1RfQkVGT1JFX1NUQVJUUEFSU0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9BWElTX1RSQVZFUlNFUl9OT1RfU1VQUE9SVEVEID0gIkVSX0FYSVNfVFJBVkVSU0VSX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FUlJPUkhBTkRMRVJfQ1JFQVRFRF9XSVRIX05VTExfUFJJTlRXUklURVIgPSAiRVJfRVJST1JIQU5ETEVSX0NSRUFURURfV0lUSF9OVUxMX1BSSU5UV1JJVEVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU1lTVEVNSURfVU5LTk9XTiA9ICJFUl9TWVNURU1JRF9VTktOT1dOIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTE9DQVRJT05fVU5LTk9XTiA9ICJFUl9MT0NBVElPTl9VTktOT1dOIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJFRklYX01VU1RfUkVTT0xWRSA9ICJFUl9QUkVGSVhfTVVTVF9SRVNPTFZFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ1JFQVRFRE9DVU1FTlRfTk9UX1NVUFBPUlRFRCA9ICJFUl9DUkVBVEVET0NVTUVOVF9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0hJTERfSEFTX05PX09XTkVSX0RPQ1VNRU5UID0gIkVSX0NISUxEX0hBU19OT19PV05FUl9ET0NVTUVOVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NISUxEX0hBU19OT19PV05FUl9ET0NVTUVOVF9FTEVNRU5UID0gIkVSX0NISUxEX0hBU19OT19PV05FUl9ET0NVTUVOVF9FTEVNRU5UIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9PVVRQVVRfVEVYVF9CRUZPUkVfRE9DID0gIkVSX0NBTlRfT1VUUFVUX1RFWFRfQkVGT1JFX0RPQyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfSEFWRV9NT1JFX1RIQU5fT05FX1JPT1QgPSAiRVJfQ0FOVF9IQVZFX01PUkVfVEhBTl9PTkVfUk9PVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FSR19MT0NBTE5BTUVfTlVMTCA9ICJFUl9BUkdfTE9DQUxOQU1FX05VTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9BUkdfTE9DQUxOQU1FX0lOVkFMSUQgPSAiRVJfQVJHX0xPQ0FMTkFNRV9JTlZBTElEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQVJHX1BSRUZJWF9JTlZBTElEID0gIkVSX0FSR19QUkVGSVhfSU5WQUxJRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05BTUVfQ0FOVF9TVEFSVF9XSVRIX0NPTE9OID0gIkVSX05BTUVfQ0FOVF9TVEFSVF9XSVRIX0NPTE9OIjsKLQotICAvLyBNZXNzYWdlIGtleXMgdXNlZCBieSB0aGUgc2VyaWFsaXplcgotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SRVNPVVJDRV9DT1VMRF9OT1RfRklORCA9ICJFUl9SRVNPVVJDRV9DT1VMRF9OT1RfRklORCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1JFU09VUkNFX0NPVUxEX05PVF9MT0FEID0gIkVSX1JFU09VUkNFX0NPVUxEX05PVF9MT0FEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQlVGRkVSX1NJWkVfTEVTU1RIQU5fWkVSTyA9ICJFUl9CVUZGRVJfU0laRV9MRVNTVEhBTl9aRVJPIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9VVEYxNl9TVVJST0dBVEUgPSAiRVJfSU5WQUxJRF9VVEYxNl9TVVJST0dBVEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9PSUVSUk9SID0gIkVSX09JRVJST1IiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OQU1FU1BBQ0VfUFJFRklYID0gIkVSX05BTUVTUEFDRV9QUkVGSVgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TVFJBWV9BVFRSSUJVVEUgPSAiRVJfU1RSQVlfQVRUSVJCVVRFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU1RSQVlfTkFNRVNQQUNFID0gIkVSX1NUUkFZX05BTUVTUEFDRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxEX05PVF9MT0FEX1JFU09VUkNFID0gIkVSX0NPVUxEX05PVF9MT0FEX1JFU09VUkNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTERfTk9UX0xPQURfTUVUSE9EX1BST1BFUlRZID0gIkVSX0NPVUxEX05PVF9MT0FEX01FVEhPRF9QUk9QRVJUWSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NFUklBTElaRVJfTk9UX0NPTlRFTlRIQU5ETEVSID0gIkVSX1NFUklBTElaRVJfTk9UX0NPTlRFTlRIQU5ETEVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSUxMRUdBTF9BVFRSSUJVVEVfUE9TSVRJT04gPSAiRVJfSUxMRUdBTF9BVFRSSUJVVEVfUE9TSVRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTExFR0FMX0NIQVJBQ1RFUiA9ICJFUl9JTExFR0FMX0NIQVJBQ1RFUiI7Ci0KLSAgLyoKLSAgICogTm93IGZpbGwgaW4gdGhlIG1lc3NhZ2UgdGV4dC4KLSAgICogVGhlbiBmaWxsIGluIHRoZSBtZXNzYWdlIHRleHQgZm9yIHRoYXQgbWVzc2FnZSBjb2RlIGluIHRoZQotICAgKiBhcnJheS4gVXNlIHRoZSBuZXcgZXJyb3IgY29kZSBhcyB0aGUgaW5kZXggaW50byB0aGUgYXJyYXkuCi0gICAqLwotCi0gIC8vIEVycm9yIG1lc3NhZ2VzLi4uCi0KLSAgLyoqIFRoZSBsb29rdXAgdGFibGUgZm9yIGVycm9yIG1lc3NhZ2VzLiAgICovCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIE9iamVjdFtdW10gY29udGVudHMgPSB7Ci0KLSAgLyoqIEVycm9yIG1lc3NhZ2UgSUQgdGhhdCBoYXMgYSBudWxsIG1lc3NhZ2UsIGJ1dCB0YWtlcyBpbiBhIHNpbmdsZSBvYmplY3QuICAgICovCi0gICAgeyJFUjAwMDAiICwgInswfSIgfSwKLQotICAgIHsgRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCwKLSAgICAgICJGdW5rdGlvbmVuIHN0XHUwMEY2ZHMgaW50ZSEifSwKLQotICAgIHsgRVJfQ0FOTk9UX09WRVJXUklURV9DQVVTRSwKLSAgICAgICJPcnNhayBrYW4gaW50ZSBza3JpdmFzIFx1MDBGNnZlciJ9LAotCi0gICAgeyBFUl9OT19ERUZBVUxUX0lNUEwsCi0gICAgICAiSGl0dGFkZSBpbmdlbiBzdGFuZGFyZGltcGxlbWVudGVyaW5nICJ9LAotCi0gICAgeyBFUl9DSFVOS0VESU5UQVJSQVlfTk9UX1NVUFBPUlRFRCwKLSAgICAgICJDaHVua2VkSW50QXJyYXkoezB9KSB1bmRlcnN0XHUwMEY2ZHMgZlx1MDBGNnIgblx1MDBFNHJ2YXJhbmRlIGludGUifSwKLQotICAgIHsgRVJfT0ZGU0VUX0JJR0dFUl9USEFOX1NMT1QsCi0gICAgICAiT2Zmc2V0IHN0XHUwMEY2cnJlIFx1MDBFNG4gcGxhdHMifSwKLQotICAgIHsgRVJfQ09ST1VUSU5FX05PVF9BVkFJTCwKLSAgICAgICJTaWRvcnV0aW4gXHUwMEU0ciBpbnRlIHRpbGxnXHUwMEU0bmdsaWcsIGlkPXswfSJ9LAotCi0gICAgeyBFUl9DT1JPVVRJTkVfQ09fRVhJVCwKLSAgICAgICJDb3JvdXRpbmVNYW5hZ2VyIGhhciB0YWdpdCBlbW90IGNvX2V4aXQoKS1iZWdcdTAwRTRyYW4ifSwKLQotICAgIHsgRVJfQ09KT0lOUk9VVElORVNFVF9GQUlMRUQsCi0gICAgICAiY29fam9pbkNvcm91dGluZVNldCgpIHV0Zlx1MDBGNnJkZXMgaW50ZSJ9LAotCi0gICAgeyBFUl9DT1JPVVRJTkVfUEFSQU0sCi0gICAgICAiUGFyYW1ldGVyZmVsIGZcdTAwRjZyIHNpZG9ydXRpbiAoezB9KSJ9LAotCi0gICAgeyBFUl9QQVJTRVJfRE9URVJNSU5BVEVfQU5TV0VSUywKLSAgICAgICJcblVORVhQRUNURUQ6IFBhcnNlcnN2YXIgezB9IGZcdTAwRjZyIGRvVGVybWluYXRlIn0sCi0KLSAgICB7IEVSX05PX1BBUlNFX0NBTExfV0hJTEVfUEFSU0lORywKLSAgICAgICJwYXJzZSBmXHUwMEU1ciBpbnRlIGFucm9wYXMgbWVkYW4gdG9sa25pbmcgc2tlciJ9LAotCi0gICAgeyBFUl9UWVBFRF9JVEVSQVRPUl9BWElTX05PVF9JTVBMRU1FTlRFRCwKLSAgICAgICJGZWw6IHR5cGFkIGl0ZXJhdG9yIGZcdTAwRjZyIGF4ZWxuIHswfSBoYXIgaW50ZSBpbXBsZW1lbnRlcmF0cyJ9LAotCi0gICAgeyBFUl9JVEVSQVRPUl9BWElTX05PVF9JTVBMRU1FTlRFRCwKLSAgICAgICJGZWw6IGl0ZXJhdG9yIGZcdTAwRjZyIGF4ZWxuIHswfSBoYXIgaW50ZSBpbXBsZW1lbnRlcmF0cyAifSwKLQotICAgIHsgRVJfSVRFUkFUT1JfQ0xPTkVfTk9UX1NVUFBPUlRFRCwKLSAgICAgICJJdGVyYXRvcmtsb24gdW5kZXJzdFx1MDBGNmRzIGludGUifSwKLQotICAgIHsgRVJfVU5LTk9XTl9BWElTX1RZUEUsCi0gICAgICAiT2tcdTAwRTRuZCBheGVsdHJhdmVyc3R5cDogezB9In0sCi0KLSAgICB7IEVSX0FYSVNfTk9UX1NVUFBPUlRFRCwKLSAgICAgICJBeGVsdHJhdmVycyB1bmRlcnN0XHUwMEY2ZHMgaW50ZTogezB9In0sCi0KLSAgICB7IEVSX05PX0RUTUlEU19BVkFJTCwKLSAgICAgICJJbmdhIGZsZXIgRFRNLUlEOm4gXHUwMEU0ciB0aWxsZ1x1MDBFNG5nbGlnYSJ9LAotCi0gICAgeyBFUl9OT1RfU1VQUE9SVEVELAotICAgICAgIlVuZGVyc3RcdTAwRjZkcyBpbnRlOiB7MH0ifSwKLQotICAgIHsgRVJfTk9ERV9OT05fTlVMTCwKLSAgICAgICJOb2QgbVx1MDBFNXN0ZSB2YXJhIGlja2UtbnVsbCBmXHUwMEY2ciBnZXREVE1IYW5kbGVGcm9tTm9kZSJ9LAotCi0gICAgeyBFUl9DT1VMRF9OT1RfUkVTT0xWRV9OT0RFLAotICAgICAgIkt1bmRlIGludGUgbWF0Y2hhIG5vZGVuIG1lZCBlbiByZWZlcmVucyJ9LAotCi0gICAgeyBFUl9TVEFSVFBBUlNFX1dISUxFX1BBUlNJTkcsCi0gICAgICAgInN0YXJ0UGFyc2UgZlx1MDBFNXIgaW50ZSBhbnJvcGFzIG1lZGFuIHRvbGtuaW5nIHNrZXIifSwKLQotICAgIHsgRVJfU1RBUlRQQVJTRV9ORUVEU19TQVhQQVJTRVIsCi0gICAgICAgInN0YXJ0UGFyc2UgYmVoXHUwMEY2dmVyIGVuIFNBWFBhcnNlciBzb20gXHUwMEU0ciBpY2tlLW51bGwifSwKLQotICAgIHsgRVJfQ09VTERfTk9UX0lOSVRfUEFSU0VSLAotICAgICAgICJrdW5kZSBpbnRlIGluaXRpZXJhIHBhcnNlciBtZWQifSwKLQotICAgIHsgRVJfRVhDRVBUSU9OX0NSRUFUSU5HX1BPT0wsCi0gICAgICAgInVuZGFudGFnIHNrYXBhciBueSBpbnN0YW5zIGZcdTAwRjZyIHBvb2wifSwKLQotICAgIHsgRVJfUEFUSF9DT05UQUlOU19JTlZBTElEX0VTQ0FQRV9TRVFVRU5DRSwKLSAgICAgICAiU1x1MDBGNmt2XHUwMEU0Z2VuIGlubmVoXHUwMEU1bGxlciBlbiBvZ2lsdGlnIGVzY2FwZS1zZWt2ZW5zIn0sCi0KLSAgICB7IEVSX1NDSEVNRV9SRVFVSVJFRCwKLSAgICAgICAiU2NoZW1hIGtyXHUwMEU0dnMhIn0sCi0KLSAgICB7IEVSX05PX1NDSEVNRV9JTl9VUkksCi0gICAgICAgIlNjaGVtYSBzYWtuYXMgaSBVUkk6IHswfSJ9LAotCi0gICAgeyBFUl9OT19TQ0hFTUVfSU5VUkksCi0gICAgICAgIlNjaGVtYSBzYWtuYXMgaSBVUkkifSwKLQotICAgIHsgRVJfUEFUSF9JTlZBTElEX0NIQVIsCi0gICAgICAgIlNcdTAwRjZrdlx1MDBFNGdlbiBpbm5laFx1MDBFNWxsZXIgZXR0IG9naWx0aWd0IHRlY2tlbjogezB9In0sCi0KLSAgICB7IEVSX1NDSEVNRV9GUk9NX05VTExfU1RSSU5HLAotICAgICAgICJLYW4gaW50ZSBzdFx1MDBFNGxsYSBpbiBzY2hlbWEgZnJcdTAwRTVuIG51bGwtc3RyXHUwMEU0bmcifSwKLQotICAgIHsgRVJfU0NIRU1FX05PVF9DT05GT1JNQU5ULAotICAgICAgICJTY2hlbWF0IFx1MDBFNHIgaW50ZSBsaWtmb3JtaWd0LiJ9LAotCi0gICAgeyBFUl9IT1NUX0FERFJFU1NfTk9UX1dFTExGT1JNRUQsCi0gICAgICAgIlZcdTAwRTRyZCBcdTAwRTRyIGludGUgZW4gdlx1MDBFNGxmb3JtdWxlcmFkIGFkcmVzcyJ9LAotCi0gICAgeyBFUl9QT1JUX1dIRU5fSE9TVF9OVUxMLAotICAgICAgICJQb3J0IGthbiBpbnRlIHN0XHUwMEU0bGxhcyBpbiBuXHUwMEU0ciB2XHUwMEU0cmQgXHUwMEU0ciBudWxsIn0sCi0KLSAgICB7IEVSX0lOVkFMSURfUE9SVCwKLSAgICAgICAiT2dpbHRpZ3QgcG9ydG51bW1lciJ9LAotCi0gICAgeyBFUl9GUkFHX0ZPUl9HRU5FUklDX1VSSSwKLSAgICAgICAiRnJhZ21lbnQga2FuIGJhcmEgc3RcdTAwRTRsbGFzIGluIGZcdTAwRjZyIGVuIGFsbG1cdTAwRTRuIFVSSSJ9LAotCi0gICAgeyBFUl9GUkFHX1dIRU5fUEFUSF9OVUxMLAotICAgICAgICJGcmFnbWVudCBrYW4gaW50ZSBzdFx1MDBFNGxsYXMgaW4gblx1MDBFNHIgc1x1MDBGNmt2XHUwMEU0ZyBcdTAwRTRyIG51bGwifSwKLQotICAgIHsgRVJfRlJBR19JTlZBTElEX0NIQVIsCi0gICAgICAgIkZyYWdtZW50IGlubmVoXHUwMEU1bGxlciBldHQgb2dpbHRpZ3QgdGVja2VuIn0sCi0KLSAgICB7IEVSX1BBUlNFUl9JTl9VU0UsCi0gICAgICAiUGFyc2VyIGFudlx1MDBFNG5kcyByZWRhbiJ9LAotCi0gICAgeyBFUl9DQU5OT1RfQ0hBTkdFX1dISUxFX1BBUlNJTkcsCi0gICAgICAiS2FuIGludGUgXHUwMEU0bmRyYSB7MH0gezF9IG1lZGFuIHRvbGtuaW5nIHNrZXIifSwKLQotICAgIHsgRVJfU0VMRl9DQVVTQVRJT05fTk9UX1BFUk1JVFRFRCwKLSAgICAgICJTalx1MDBFNGx2b3JzYWthbmRlIGludGUgdGlsbFx1MDBFNXRlbiJ9LAotCi0gICAgeyBFUl9OT19VU0VSSU5GT19JRl9OT19IT1NULAotICAgICAgIkFudlx1MDBFNG5kYXJpbmZvIGZcdTAwRTVyIGludGUgYW5nZXMgb20gdlx1MDBFNHJkZW4gaW50ZSBcdTAwRTRyIGFuZ2l2ZW4ifSwKLQotICAgIHsgRVJfTk9fUE9SVF9JRl9OT19IT1NULAotICAgICAgIlBvcnQgZlx1MDBFNXIgaW50ZSBhbmdlcyBvbSB2XHUwMEU0cmRlbiBpbnRlIFx1MDBFNHIgYW5naXZlbiJ9LAotCi0gICAgeyBFUl9OT19RVUVSWV9TVFJJTkdfSU5fUEFUSCwKLSAgICAgICJGclx1MDBFNWdlc3RyXHUwMEU0bmcga2FuIGludGUgYW5nZXMgaSBiXHUwMEU1ZGUgc1x1MDBGNmt2XHUwMEU0Z2VuIG9jaCBmclx1MDBFNWdlc3RyXHUwMEU0bmdlbiJ9LAotCi0gICAgeyBFUl9OT19GUkFHTUVOVF9TVFJJTkdfSU5fUEFUSCwKLSAgICAgICJGcmFnbWVudCBrYW4gaW50ZSBhbmdlcyBpIGJcdTAwRTVkZSBzXHUwMEY2a3ZcdTAwRTRnZW4gb2NoIGZyYWdtZW50ZXQifSwKLQotICAgIHsgRVJfQ0FOTk9UX0lOSVRfVVJJX0VNUFRZX1BBUk1TLAotICAgICAgIkthbiBpbnRlIGluaXRpZXJhIFVSSSBtZWQgdG9tbWEgcGFyYW1ldHJhciJ9LAotCi0gICAgeyBFUl9NRVRIT0RfTk9UX1NVUFBPUlRFRCwKLSAgICAgICJNZXRvZGVuIHN0XHUwMEY2ZHMgXHUwMEU0bm51IGludGUgIn0sCi0KLSAgICB7IEVSX0lOQ1JTQVhTUkNGSUxURVJfTk9UX1JFU1RBUlRBQkxFLAotICAgICAgIkluY3JlbWVudGFsU0FYU291cmNlX0ZpbHRlciBrYW4gZlx1MDBGNnIgblx1MDBFNHJ2YXJhbmRlIGludGUgc3RhcnRhcyBvbSJ9LAotCi0gICAgeyBFUl9YTUxSRFJfTk9UX0JFRk9SRV9TVEFSVFBBUlNFLAotICAgICAgIlhNTFJlYWRlciBpbnRlIGZcdTAwRjZyZSBzdGFydFBhcnNlLWJlZ1x1MDBFNHJhbiJ9LAotCi0gICAgeyBFUl9BWElTX1RSQVZFUlNFUl9OT1RfU1VQUE9SVEVELAotICAgICAgIkF4ZWx0cmF2ZXJzIHVuZGVyc3RcdTAwRjZkcyBpbnRlOiB7MH0ifSwKLQotICAgIHsgRVJfRVJST1JIQU5ETEVSX0NSRUFURURfV0lUSF9OVUxMX1BSSU5UV1JJVEVSLAotICAgICAgIkxpc3RpbmdFcnJvckhhbmRsZXIgc2thcGFkIG1lZCBudWxsIFByaW50V3JpdGVyISJ9LAotCi0gICAgeyBFUl9TWVNURU1JRF9VTktOT1dOLAotICAgICAgIlN5c3RlbUlkIG9rXHUwMEU0bnQifSwKLQotICAgIHsgRVJfTE9DQVRJT05fVU5LTk9XTiwKLSAgICAgICJQbGF0c2VuIGZcdTAwRjZyIGZlbGV0IFx1MDBFNHIgb2tcdTAwRTRuZCJ9LAotCi0gICAgeyBFUl9QUkVGSVhfTVVTVF9SRVNPTFZFLAotICAgICAgIlByZWZpeCBtXHUwMEU1c3RlIG1hdGNoYXMgdGlsbCBlbiBuYW1ucnltZDogezB9In0sCi0KLSAgICB7IEVSX0NSRUFURURPQ1VNRU5UX05PVF9TVVBQT1JURUQsCi0gICAgICAiY3JlYXRlRG9jdW1lbnQoKSBzdFx1MDBGNmRzIGludGUgaSBYUGF0aENvbnRleHQhIn0sCi0KLSAgICB7IEVSX0NISUxEX0hBU19OT19PV05FUl9ET0NVTUVOVCwKLSAgICAgICJVbmRlcm9yZG5hdCBhdHRyaWJ1dCBoYXIgaW5nZXQgXHUwMEU0Z2FyZG9rdW1lbnQhIn0sCi0KLSAgICB7IEVSX0NISUxEX0hBU19OT19PV05FUl9ET0NVTUVOVF9FTEVNRU5ULAotICAgICAgIlVuZGVyb3JkbmF0IGF0dHJpYnV0IGhhciBpbmdldCBcdTAwRTRnYXJkb2t1bWVudGVsZW1lbnQhIn0sCi0KLSAgICB7IEVSX0NBTlRfT1VUUFVUX1RFWFRfQkVGT1JFX0RPQywKLSAgICAgICJWYXJuaW5nOiB1dGRhdGF0ZXh0IGthbiBpbnRlIHNrcml2YXMgdXQgZlx1MDBGNnJlIGRva3VtZW50ZWxlbWVudCEgSWdub3JlcmFzLi4uIn0sCi0KLSAgICB7IEVSX0NBTlRfSEFWRV9NT1JFX1RIQU5fT05FX1JPT1QsCi0gICAgICAiRW4gRE9NIGthbiBpbnRlIGhhIGZsZXIgXHUwMEU0biBlbiByb3QhIn0sCi0KLSAgICB7IEVSX0FSR19MT0NBTE5BTUVfTlVMTCwKLSAgICAgICAiQXJndW1lbnRldCAnbG9jYWxOYW1lJyBcdTAwRTRyIG51bGwifSwKLQotICAgIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBIFFOQU1FIGhhcyB0aGUgc3ludGFjdGljIGZvcm0gW05DTmFtZTpdTkNOYW1lCi0gICAgLy8gVGhlIGxvY2FsbmFtZSBpcyB0aGUgcG9ydGlvbiBhZnRlciB0aGUgb3B0aW9uYWwgY29sb247IHRoZSBtZXNzYWdlIGluZGljYXRlcwotICAgIC8vIHRoYXQgdGhlcmUgaXMgYSBwcm9ibGVtIHdpdGggdGhhdCBwYXJ0IG9mIHRoZSBRTkFNRS4KLSAgICB7IEVSX0FSR19MT0NBTE5BTUVfSU5WQUxJRCwKLSAgICAgICAiTG9jYWxuYW1lIGkgUU5BTUUgYlx1MDBGNnIgdmFyYSBnaWx0aWd0IE5DTmFtZSJ9LAotCi0gICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIEEgUU5BTUUgaGFzIHRoZSBzeW50YWN0aWMgZm9ybSBbTkNOYW1lOl1OQ05hbWUKLSAgICAvLyBUaGUgcHJlZml4IGlzIHRoZSBwb3J0aW9uIGJlZm9yZSB0aGUgb3B0aW9uYWwgY29sb247IHRoZSBtZXNzYWdlIGluZGljYXRlcwotICAgIC8vIHRoYXQgdGhlcmUgaXMgYSBwcm9ibGVtIHdpdGggdGhhdCBwYXJ0IG9mIHRoZSBRTkFNRS4KLSAgICB7IEVSX0FSR19QUkVGSVhfSU5WQUxJRCwKLSAgICAgICAiUHJlZml4IGkgUU5BTUUgYlx1MDBGNnIgdmFyYSBnaWx0aWd0IE5DTmFtZSJ9LAotCi0gICAgeyBFUl9OQU1FX0NBTlRfU1RBUlRfV0lUSF9DT0xPTiwKLSAgICAgICJOYW1uZXQga2FuIGludGUgYlx1MDBGNnJqYSBtZWQga29sb24ifSwKLQotICAgIHsgIkJBRF9DT0RFIiwgIlBhcmFtZXRlciBmXHUwMEY2ciBjcmVhdGVNZXNzYWdlIGxpZ2dlciB1dGFuZlx1MDBGNnIgZ3JcdTAwRTRuc3ZcdTAwRTRyZGV0In0sCi0gICAgeyAiRk9STUFUX0ZBSUxFRCIsICJVbmRhbnRhZyB1dGxcdTAwRjZzdCB2aWQgbWVzc2FnZUZvcm1hdC1hbnJvcCJ9LAotICAgIHsgImxpbmUiLCAiUmFkIG5yIn0sCi0gICAgeyAiY29sdW1uIiwiS29sdW1uIG5yIn0sCi0KLSAgICB7RVJfU0VSSUFMSVpFUl9OT1RfQ09OVEVOVEhBTkRMRVIsCi0gICAgICAiU2VyaWFsaXplcmtsYXNzZW4gJyd7MH0nJyBpbXBsZW1lbnRlcmFyIGludGUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIuIn0sCi0KLSAgICB7RVJfUkVTT1VSQ0VfQ09VTERfTk9UX0ZJTkQsCi0gICAgICAiUmVzdXJzZW4gWyB7MH0gXSBrdW5kZSBpbnRlIGhcdTAwRTRtdGFzLlxuIHsxfSIgfSwKLQotICAgIHtFUl9SRVNPVVJDRV9DT1VMRF9OT1RfTE9BRCwKLSAgICAgICJSZXN1cnNlbiBbIHswfSBdIGt1bmRlIGludGUgbGFkZGFzOiB7MX0gXG4gezJ9IFx0IHszfSIgfSwKLQotICAgIHtFUl9CVUZGRVJfU0laRV9MRVNTVEhBTl9aRVJPLAotICAgICAgIkJ1ZmZlcnRzdG9ybGVrIDw9MCIgfSwKLQotICAgIHtFUl9JTlZBTElEX1VURjE2X1NVUlJPR0FURSwKLSAgICAgICJPZ2lsdGlndCBVVEYtMTYtc3Vycm9nYXQgdXBwdFx1MDBFNGNrdDogezB9ID8iIH0sCi0KLSAgICB7RVJfT0lFUlJPUiwKLSAgICAgICJJTy1mZWwiIH0sCi0KLSAgICB7RVJfSUxMRUdBTF9BVFRSSUJVVEVfUE9TSVRJT04sCi0gICAgICAiS2FuIGludGUgbFx1MDBFNGdnYSB0aWxsIGF0dHJpYnV0ZXQgezB9IGVmdGVyIHVuZGVyb3JkbmFkZSBub2RlciBlbGxlciBpbm5hbiBldHQgZWxlbWVudCBoYXIgc2thcGF0cy4gQXR0cmlidXRldCBpZ25vcmVyYXMuIn0sCi0KLSAgICAgIC8qCi0gICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN0eWxlc2hlZXQgY29udGFpbmVkIGEgcmVmZXJlbmNlIHRvIGEKLSAgICAgICAqIG5hbWVzcGFjZSBwcmVmaXggdGhhdCB3YXMgdW5kZWZpbmVkLiAgVGhlIHZhbHVlIG9mIHRoZSBzdWJzdGl0dXRpb24KLSAgICAgICAqIHRleHQgaXMgdGhlIG5hbWUgb2YgdGhlIHByZWZpeC4KLSAgICAgICAqLwotICAgIHtFUl9OQU1FU1BBQ0VfUFJFRklYLAotICAgICAgIk5hbW5yeW1kIGZcdTAwRjZyIHByZWZpeCAnJ3swfScnIGhhciBpbnRlIGRla2xhcmVyYXRzLiIgfSwKLSAgICAgIC8qCi0gICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIHJlcG9ydGVkIGlmIHRoZSBzdHlsZXNoZWV0Ci0gICAgICAgKiBiZWluZyBwcm9jZXNzZWQgYXR0ZW1wdGVkIHRvIGNvbnN0cnVjdCBhbiBYTUwgZG9jdW1lbnQgd2l0aCBhbgotICAgICAgICogYXR0cmlidXRlIGluIGEgcGxhY2Ugb3RoZXIgdGhhbiBvbiBhbiBlbGVtZW50LiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgKiBzcGVjaWZpZXMgdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgICAqLwotICAgIHtFUl9TVFJBWV9BVFRSSUJVVEUsCi0gICAgICAiQXR0cmlidXRldCAnJ3swfScnIGZpbm5zIHV0YW5mXHUwMEY2ciBlbGVtZW50ZXQuIiB9LAotCi0gICAgICAvKgotICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFzIHdpdGggdGhlIHByZWNlZGluZyBtZXNzYWdlLCBhIG5hbWVzcGFjZQotICAgICAgICogZGVjbGFyYXRpb24gaGFzIHRoZSBmb3JtIG9mIGFuIGF0dHJpYnV0ZSBhbmQgaXMgb25seSBwZXJtaXR0ZWQgdG8KLSAgICAgICAqIGFwcGVhciBvbiBhbiBlbGVtZW50LiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHswfSBpcyB0aGUgbmFtZXNwYWNlCi0gICAgICAgKiBwcmVmaXggYW5kIHsxfSBpcyB0aGUgVVJJIHRoYXQgd2FzIGJlaW5nIHVzZWQgaW4gdGhlIGVycm9uZW91cwotICAgICAgICogbmFtZXNwYWNlIGRlY2xhcmF0aW9uLgotICAgICAgICovCi0gICAge0VSX1NUUkFZX05BTUVTUEFDRSwKLSAgICAgICJOYW1ucnltZHNkZWtsYXJhdGlvbmVuICcnezB9Jyc9Jyd7MX0nJyBmaW5ucyB1dGFuZlx1MDBGNnIgZWxlbWVudC4iIH0sCi0KLSAgICB7RVJfQ09VTERfTk9UX0xPQURfUkVTT1VSQ0UsCi0gICAgICAiS3VuZGUgaW50ZSBsYWRkYSAnJ3swfScnIChrb250cm9sbGVyYSBDTEFTU1BBVEgpLCBhbnZcdTAwRTRuZGVyIG51IGVuYmFydCBzdGFuZGFyZHZcdTAwRTRyZGVuIn0sCi0KLSAgICB7IEVSX0lMTEVHQUxfQ0hBUkFDVEVSLAotICAgICAgICJGXHUwMEY2cnNcdTAwRjZrIGF0dCBza3JpdmEgdXRkYXRhdGVja2VuIG1lZCBpbnRlZ3JhbHZcdTAwRTRyZGV0IHswfSBzb20gaW50ZSBcdTAwRTRyIHJlcHJlc2VudGVyYXQgaSBhbmdpdmVuIHV0ZGF0YWtvZG5pbmcgYXYgezF9LiJ9LAotCi0gICAge0VSX0NPVUxEX05PVF9MT0FEX01FVEhPRF9QUk9QRVJUWSwKLSAgICAgICJLdW5kZSBpbnRlIGxhZGRhIGVnZW5za2Fwc2ZpbGVuICcnezB9JycgZlx1MDBGNnIgdXRkYXRhbWV0b2RlbiAnJ3sxfScnIChrb250cm9sbGVyYSBDTEFTU1BBVEgpIiB9Ci0KLQotICB9OwotCi0gIC8qKgotICAgKiBHZXQgdGhlIGFzc29jaWF0aW9uIGxpc3QuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGFzc29jaWF0aW9uIGxpc3QuCi0gICAqLwotCi0gICAgcHJvdGVjdGVkIE9iamVjdFtdW10gZ2V0Q29udGVudHMoKSB7Ci0gICAgICAgIHJldHVybiBjb250ZW50czsKLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3Jlcy9YTUxFcnJvclJlc291cmNlc190ci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvcmVzL1hNTEVycm9yUmVzb3VyY2VzX3RyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDU4OTczYzYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvcmVzL1hNTEVycm9yUmVzb3VyY2VzX3RyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0NDMgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogWE1MRXJyb3JSZXNvdXJjZXNfdHIuamF2YSx2IDEuMS42LjIgMjAwNS8wOS8xNSAwNzo0NTo0NiBzdXJlc2hfZW1haWxpZCBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzOwotCi0KLWltcG9ydCBqYXZhLnV0aWwuTGlzdFJlc291cmNlQnVuZGxlOwotCi0vKioKLSAqIFNldCB1cCBlcnJvciBtZXNzYWdlcy4KLSAqIFdlIGJ1aWxkIGEgdHdvIGRpbWVuc2lvbmFsIGFycmF5IG9mIG1lc3NhZ2Uga2V5cyBhbmQKLSAqIG1lc3NhZ2Ugc3RyaW5ncy4gSW4gb3JkZXIgdG8gYWRkIGEgbmV3IG1lc3NhZ2UgaGVyZSwKLSAqIHlvdSBuZWVkIHRvIGZpcnN0IGFkZCBhIFN0cmluZyBjb25zdGFudC4gQW5kIHlvdSBuZWVkCi0gKiB0byBlbnRlciBrZXksIHZhbHVlIHBhaXIgYXMgcGFydCBvZiB0aGUgY29udGVudHMKLSAqIGFycmF5LiBZb3UgYWxzbyBuZWVkIHRvIHVwZGF0ZSBNQVhfQ09ERSBmb3IgZXJyb3Igc3RyaW5ncwotICogYW5kIE1BWF9XQVJOSU5HIGZvciB3YXJuaW5ncyAoIE5lZWRlZCBmb3Igb25seSBpbmZvcm1hdGlvbgotICogcHVycG9zZSApCi0gKi8KLXB1YmxpYyBjbGFzcyBYTUxFcnJvclJlc291cmNlc190ciBleHRlbmRzIExpc3RSZXNvdXJjZUJ1bmRsZQotewotCi0vKgotICogVGhpcyBmaWxlIGNvbnRhaW5zIGVycm9yIGFuZCB3YXJuaW5nIG1lc3NhZ2VzIHJlbGF0ZWQgdG8gWGFsYW4gRXJyb3IKLSAqIEhhbmRsaW5nLgotICoKLSAqICBHZW5lcmFsIG5vdGVzIHRvIHRyYW5zbGF0b3JzOgotICoKLSAqICAxKSBYYWxhbiAob3IgbW9yZSBwcm9wZXJseSwgWGFsYW4taW50ZXJwcmV0aXZlKSBhbmQgWFNMVEMgYXJlIG5hbWVzIG9mCi0gKiAgICAgY29tcG9uZW50cy4KLSAqICAgICBYU0xUIGlzIGFuIGFjcm9ueW0gZm9yICJYTUwgU3R5bGVzaGVldCBMYW5ndWFnZTogVHJhbnNmb3JtYXRpb25zIi4KLSAqICAgICBYU0xUQyBpcyBhbiBhY3JvbnltIGZvciBYU0xUIENvbXBpbGVyLgotICoKLSAqICAyKSBBIHN0eWxlc2hlZXQgaXMgYSBkZXNjcmlwdGlvbiBvZiBob3cgdG8gdHJhbnNmb3JtIGFuIGlucHV0IFhNTCBkb2N1bWVudAotICogICAgIGludG8gYSByZXN1bHRhbnQgWE1MIGRvY3VtZW50IChvciBIVE1MIGRvY3VtZW50IG9yIHRleHQpLiAgVGhlCi0gKiAgICAgc3R5bGVzaGVldCBpdHNlbGYgaXMgZGVzY3JpYmVkIGluIHRoZSBmb3JtIG9mIGFuIFhNTCBkb2N1bWVudC4KLSAqCi0gKiAgMykgQSB0ZW1wbGF0ZSBpcyBhIGNvbXBvbmVudCBvZiBhIHN0eWxlc2hlZXQgdGhhdCBpcyB1c2VkIHRvIG1hdGNoIGEKLSAqICAgICBwYXJ0aWN1bGFyIHBvcnRpb24gb2YgYW4gaW5wdXQgZG9jdW1lbnQgYW5kIHNwZWNpZmllcyB0aGUgZm9ybSBvZiB0aGUKLSAqICAgICBjb3JyZXNwb25kaW5nIHBvcnRpb24gb2YgdGhlIG91dHB1dCBkb2N1bWVudC4KLSAqCi0gKiAgNCkgQW4gZWxlbWVudCBpcyBhIG1hcmstdXAgdGFnIGluIGFuIFhNTCBkb2N1bWVudDsgYW4gYXR0cmlidXRlIGlzIGEKLSAqICAgICBtb2RpZmllciBvbiB0aGUgdGFnLiAgRm9yIGV4YW1wbGUsIGluIDxlbGVtIGF0dHI9J3ZhbCcgYXR0cjI9J3ZhbDInPgotICogICAgICJlbGVtIiBpcyBhbiBlbGVtZW50IG5hbWUsICJhdHRyIiBhbmQgImF0dHIyIiBhcmUgYXR0cmlidXRlIG5hbWVzIHdpdGgKLSAqICAgICB0aGUgdmFsdWVzICJ2YWwiIGFuZCAidmFsMiIsIHJlc3BlY3RpdmVseS4KLSAqCi0gKiAgNSkgQSBuYW1lc3BhY2UgZGVjbGFyYXRpb24gaXMgYSBzcGVjaWFsIGF0dHJpYnV0ZSB0aGF0IGlzIHVzZWQgdG8gYXNzb2NpYXRlCi0gKiAgICAgYSBwcmVmaXggd2l0aCBhIFVSSSAodGhlIG5hbWVzcGFjZSkuICBUaGUgbWVhbmluZ3Mgb2YgZWxlbWVudCBuYW1lcyBhbmQKLSAqICAgICBhdHRyaWJ1dGUgbmFtZXMgdGhhdCB1c2UgdGhhdCBwcmVmaXggYXJlIGRlZmluZWQgd2l0aCByZXNwZWN0IHRvIHRoYXQKLSAqICAgICBuYW1lc3BhY2UuCi0gKgotICogIDYpICJUcmFuc2xldCIgaXMgYW4gaW52ZW50ZWQgdGVybSB0aGF0IGRlc2NyaWJlcyB0aGUgY2xhc3MgZmlsZSB0aGF0Ci0gKiAgICAgcmVzdWx0cyBmcm9tIGNvbXBpbGluZyBhbiBYTUwgc3R5bGVzaGVldCBpbnRvIGEgSmF2YSBjbGFzcy4KLSAqCi0gKiAgNykgWFBhdGggaXMgYSBzcGVjaWZpY2F0aW9uIHRoYXQgZGVzY3JpYmVzIGEgbm90YXRpb24gZm9yIGlkZW50aWZ5aW5nCi0gKiAgICAgbm9kZXMgaW4gYSB0cmVlLXN0cnVjdHVyZWQgcmVwcmVzZW50YXRpb24gb2YgYW4gWE1MIGRvY3VtZW50LiAgQW4KLSAqICAgICBpbnN0YW5jZSBvZiB0aGF0IG5vdGF0aW9uIGlzIHJlZmVycmVkIHRvIGFzIGFuIFhQYXRoIGV4cHJlc3Npb24uCi0gKgotICovCi0KLSAgLyoqIE1heGltdW0gZXJyb3IgbWVzc2FnZXMsIHRoaXMgaXMgbmVlZGVkIHRvIGtlZXAgdHJhY2sgb2YgdGhlIG51bWJlciBvZiBtZXNzYWdlcy4gICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFYX0NPREUgPSA2MTsKLQotICAvKiogTWF4aW11bSB3YXJuaW5ncywgdGhpcyBpcyBuZWVkZWQgdG8ga2VlcCB0cmFjayBvZiB0aGUgbnVtYmVyIG9mIHdhcm5pbmdzLiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVhfV0FSTklORyA9IDA7Ci0KLSAgLyoqIE1heGltdW0gbWlzYyBzdHJpbmdzLiAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BWF9PVEhFUlMgPSA0OwotCi0gIC8qKiBNYXhpbXVtIHRvdGFsIHdhcm5pbmdzIGFuZCBlcnJvciBtZXNzYWdlcy4gICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFYX01FU1NBR0VTID0gTUFYX0NPREUgKyBNQVhfV0FSTklORyArIDE7Ci0KLQotICAvKgotICAgKiBNZXNzYWdlIGtleXMKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQgPSAiRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9PVkVSV1JJVEVfQ0FVU0UgPSAiRVJfQ0FOTk9UX09WRVJXUklURV9DQVVTRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX0RFRkFVTFRfSU1QTCA9ICJFUl9OT19ERUZBVUxUX0lNUEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DSFVOS0VESU5UQVJSQVlfTk9UX1NVUFBPUlRFRCA9ICJFUl9DSFVOS0VESU5UQVJSQVlfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX09GRlNFVF9CSUdHRVJfVEhBTl9TTE9UID0gIkVSX09GRlNFVF9CSUdHRVJfVEhBTl9TTE9UIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09ST1VUSU5FX05PVF9BVkFJTCA9ICJFUl9DT1JPVVRJTkVfTk9UX0FWQUlMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09ST1VUSU5FX0NPX0VYSVQgPSAiRVJfQ09ST1VUSU5FX0NPX0VYSVQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT0pPSU5ST1VUSU5FU0VUX0ZBSUxFRCA9ICJFUl9DT0pPSU5ST1VUSU5FU0VUX0ZBSUxFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPUk9VVElORV9QQVJBTSA9ICJFUl9DT1JPVVRJTkVfUEFSQU0iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QQVJTRVJfRE9URVJNSU5BVEVfQU5TV0VSUyA9ICJFUl9QQVJTRVJfRE9URVJNSU5BVEVfQU5TV0VSUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1BBUlNFX0NBTExfV0hJTEVfUEFSU0lORyA9ICJFUl9OT19QQVJTRV9DQUxMX1dISUxFX1BBUlNJTkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9UWVBFRF9JVEVSQVRPUl9BWElTX05PVF9JTVBMRU1FTlRFRCA9ICJFUl9UWVBFRF9JVEVSQVRPUl9BWElTX05PVF9JTVBMRU1FTlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lURVJBVE9SX0FYSVNfTk9UX0lNUExFTUVOVEVEID0gIkVSX0lURVJBVE9SX0FYSVNfTk9UX0lNUExFTUVOVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSVRFUkFUT1JfQ0xPTkVfTk9UX1NVUFBPUlRFRCA9ICJFUl9JVEVSQVRPUl9DTE9ORV9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5LTk9XTl9BWElTX1RZUEUgPSAiRVJfVU5LTk9XTl9BWElTX1RZUEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9BWElTX05PVF9TVVBQT1JURUQgPSAiRVJfQVhJU19OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fRFRNSURTX0FWQUlMID0gIkVSX05PX0RUTUlEU19BVkFJTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PVF9TVVBQT1JURUQgPSAiRVJfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PREVfTk9OX05VTEwgPSAiRVJfTk9ERV9OT05fTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxEX05PVF9SRVNPTFZFX05PREUgPSAiRVJfQ09VTERfTk9UX1JFU09MVkVfTk9ERSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NUQVJUUEFSU0VfV0hJTEVfUEFSU0lORyA9ICJFUl9TVEFSVFBBUlNFX1dISUxFX1BBUlNJTkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TVEFSVFBBUlNFX05FRURTX1NBWFBBUlNFUiA9ICJFUl9TVEFSVFBBUlNFX05FRURTX1NBWFBBUlNFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxEX05PVF9JTklUX1BBUlNFUiA9ICJFUl9DT1VMRF9OT1RfSU5JVF9QQVJTRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FWENFUFRJT05fQ1JFQVRJTkdfUE9PTCA9ICJFUl9FWENFUFRJT05fQ1JFQVRJTkdfUE9PTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BBVEhfQ09OVEFJTlNfSU5WQUxJRF9FU0NBUEVfU0VRVUVOQ0UgPSAiRVJfUEFUSF9DT05UQUlOU19JTlZBTElEX0VTQ0FQRV9TRVFVRU5DRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NDSEVNRV9SRVFVSVJFRCA9ICJFUl9TQ0hFTUVfUkVRVUlSRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19TQ0hFTUVfSU5fVVJJID0gIkVSX05PX1NDSEVNRV9JTl9VUkkiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19TQ0hFTUVfSU5VUkkgPSAiRVJfTk9fU0NIRU1FX0lOVVJJIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUEFUSF9JTlZBTElEX0NIQVIgPSAiRVJfUEFUSF9JTlZBTElEX0NIQVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TQ0hFTUVfRlJPTV9OVUxMX1NUUklORyA9ICJFUl9TQ0hFTUVfRlJPTV9OVUxMX1NUUklORyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NDSEVNRV9OT1RfQ09ORk9STUFOVCA9ICJFUl9TQ0hFTUVfTk9UX0NPTkZPUk1BTlQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9IT1NUX0FERFJFU1NfTk9UX1dFTExGT1JNRUQgPSAiRVJfSE9TVF9BRERSRVNTX05PVF9XRUxMRk9STUVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUE9SVF9XSEVOX0hPU1RfTlVMTCA9ICJFUl9QT1JUX1dIRU5fSE9TVF9OVUxMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9QT1JUID0gIkVSX0lOVkFMSURfUE9SVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZSQUdfRk9SX0dFTkVSSUNfVVJJID0iRVJfRlJBR19GT1JfR0VORVJJQ19VUkkiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GUkFHX1dIRU5fUEFUSF9OVUxMID0gIkVSX0ZSQUdfV0hFTl9QQVRIX05VTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GUkFHX0lOVkFMSURfQ0hBUiA9ICJFUl9GUkFHX0lOVkFMSURfQ0hBUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BBUlNFUl9JTl9VU0UgPSAiRVJfUEFSU0VSX0lOX1VTRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9DSEFOR0VfV0hJTEVfUEFSU0lORyA9ICJFUl9DQU5OT1RfQ0hBTkdFX1dISUxFX1BBUlNJTkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TRUxGX0NBVVNBVElPTl9OT1RfUEVSTUlUVEVEID0gIkVSX1NFTEZfQ0FVU0FUSU9OX05PVF9QRVJNSVRURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19VU0VSSU5GT19JRl9OT19IT1NUID0gIkVSX05PX1VTRVJJTkZPX0lGX05PX0hPU1QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19QT1JUX0lGX05PX0hPU1QgPSAiRVJfTk9fUE9SVF9JRl9OT19IT1NUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fUVVFUllfU1RSSU5HX0lOX1BBVEggPSAiRVJfTk9fUVVFUllfU1RSSU5HX0lOX1BBVEgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19GUkFHTUVOVF9TVFJJTkdfSU5fUEFUSCA9ICJFUl9OT19GUkFHTUVOVF9TVFJJTkdfSU5fUEFUSCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9JTklUX1VSSV9FTVBUWV9QQVJNUyA9ICJFUl9DQU5OT1RfSU5JVF9VUklfRU1QVFlfUEFSTVMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9NRVRIT0RfTk9UX1NVUFBPUlRFRCA9IkVSX01FVEhPRF9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5DUlNBWFNSQ0ZJTFRFUl9OT1RfUkVTVEFSVEFCTEUgPSAiRVJfSU5DUlNBWFNSQ0ZJTFRFUl9OT1RfUkVTVEFSVEFCTEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YTUxSRFJfTk9UX0JFRk9SRV9TVEFSVFBBUlNFID0gIkVSX1hNTFJEUl9OT1RfQkVGT1JFX1NUQVJUUEFSU0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9BWElTX1RSQVZFUlNFUl9OT1RfU1VQUE9SVEVEID0gIkVSX0FYSVNfVFJBVkVSU0VSX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FUlJPUkhBTkRMRVJfQ1JFQVRFRF9XSVRIX05VTExfUFJJTlRXUklURVIgPSAiRVJfRVJST1JIQU5ETEVSX0NSRUFURURfV0lUSF9OVUxMX1BSSU5UV1JJVEVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU1lTVEVNSURfVU5LTk9XTiA9ICJFUl9TWVNURU1JRF9VTktOT1dOIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTE9DQVRJT05fVU5LTk9XTiA9ICJFUl9MT0NBVElPTl9VTktOT1dOIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJFRklYX01VU1RfUkVTT0xWRSA9ICJFUl9QUkVGSVhfTVVTVF9SRVNPTFZFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ1JFQVRFRE9DVU1FTlRfTk9UX1NVUFBPUlRFRCA9ICJFUl9DUkVBVEVET0NVTUVOVF9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0hJTERfSEFTX05PX09XTkVSX0RPQ1VNRU5UID0gIkVSX0NISUxEX0hBU19OT19PV05FUl9ET0NVTUVOVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NISUxEX0hBU19OT19PV05FUl9ET0NVTUVOVF9FTEVNRU5UID0gIkVSX0NISUxEX0hBU19OT19PV05FUl9ET0NVTUVOVF9FTEVNRU5UIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9PVVRQVVRfVEVYVF9CRUZPUkVfRE9DID0gIkVSX0NBTlRfT1VUUFVUX1RFWFRfQkVGT1JFX0RPQyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfSEFWRV9NT1JFX1RIQU5fT05FX1JPT1QgPSAiRVJfQ0FOVF9IQVZFX01PUkVfVEhBTl9PTkVfUk9PVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FSR19MT0NBTE5BTUVfTlVMTCA9ICJFUl9BUkdfTE9DQUxOQU1FX05VTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9BUkdfTE9DQUxOQU1FX0lOVkFMSUQgPSAiRVJfQVJHX0xPQ0FMTkFNRV9JTlZBTElEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQVJHX1BSRUZJWF9JTlZBTElEID0gIkVSX0FSR19QUkVGSVhfSU5WQUxJRCI7Ci0KLSAgLy8gTWVzc2FnZSBrZXlzIHVzZWQgYnkgdGhlIHNlcmlhbGl6ZXIKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUkVTT1VSQ0VfQ09VTERfTk9UX0ZJTkQgPSAiRVJfUkVTT1VSQ0VfQ09VTERfTk9UX0ZJTkQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SRVNPVVJDRV9DT1VMRF9OT1RfTE9BRCA9ICJFUl9SRVNPVVJDRV9DT1VMRF9OT1RfTE9BRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0JVRkZFUl9TSVpFX0xFU1NUSEFOX1pFUk8gPSAiRVJfQlVGRkVSX1NJWkVfTEVTU1RIQU5fWkVSTyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfVVRGMTZfU1VSUk9HQVRFID0gIkVSX0lOVkFMSURfVVRGMTZfU1VSUk9HQVRFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfT0lFUlJPUiA9ICJFUl9PSUVSUk9SIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTkFNRVNQQUNFX1BSRUZJWCA9ICJFUl9OQU1FU1BBQ0VfUFJFRklYIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU1RSQVlfQVRUUklCVVRFID0gIkVSX1NUUkFZX0FUVElSQlVURSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NUUkFZX05BTUVTUEFDRSA9ICJFUl9TVFJBWV9OQU1FU1BBQ0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRF9OT1RfTE9BRF9SRVNPVVJDRSA9ICJFUl9DT1VMRF9OT1RfTE9BRF9SRVNPVVJDRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxEX05PVF9MT0FEX01FVEhPRF9QUk9QRVJUWSA9ICJFUl9DT1VMRF9OT1RfTE9BRF9NRVRIT0RfUFJPUEVSVFkiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TRVJJQUxJWkVSX05PVF9DT05URU5USEFORExFUiA9ICJFUl9TRVJJQUxJWkVSX05PVF9DT05URU5USEFORExFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lMTEVHQUxfQVRUUklCVVRFX1BPU0lUSU9OID0gIkVSX0lMTEVHQUxfQVRUUklCVVRFX1BPU0lUSU9OIjsKLQotICAvKgotICAgKiBOb3cgZmlsbCBpbiB0aGUgbWVzc2FnZSB0ZXh0LgotICAgKiBUaGVuIGZpbGwgaW4gdGhlIG1lc3NhZ2UgdGV4dCBmb3IgdGhhdCBtZXNzYWdlIGNvZGUgaW4gdGhlCi0gICAqIGFycmF5LiBVc2UgdGhlIG5ldyBlcnJvciBjb2RlIGFzIHRoZSBpbmRleCBpbnRvIHRoZSBhcnJheS4KLSAgICovCi0KLSAgLy8gRXJyb3IgbWVzc2FnZXMuLi4KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgT2JqZWN0W11bXSBfY29udGVudHMgPSBuZXcgT2JqZWN0W11bXSB7Ci0KLSAgLyoqIEVycm9yIG1lc3NhZ2UgSUQgdGhhdCBoYXMgYSBudWxsIG1lc3NhZ2UsIGJ1dCB0YWtlcyBpbiBhIHNpbmdsZSBvYmplY3QuICAgICovCi0gICAgeyJFUjAwMDAiICwgInswfSIgfSwKLQotICAgIHsgRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCwKLSAgICAgICJcdTAxMzBcdTAxNWZsZXYgZGVzdGVrbGVubWl5b3IhIn0sCi0KLSAgICB7IEVSX0NBTk5PVF9PVkVSV1JJVEVfQ0FVU0UsCi0gICAgICAiTmVkZW5pbiBcdTAwZmN6ZXJpbmUgeWF6XHUwMTMxbGFtYXoifSwKLQotICAgIHsgRVJfTk9fREVGQVVMVF9JTVBMLAotICAgICAgIlZhcnNheVx1MDEzMWxhbiB1eWd1bGFtYSBidWx1bmFtYWRcdTAxMzEifSwKLQotICAgIHsgRVJfQ0hVTktFRElOVEFSUkFZX05PVF9TVVBQT1JURUQsCi0gICAgICAiQ2h1bmtlZEludEFycmF5KHswfSkgXHUwMTVmdSBhbiBkZXN0ZWtsZW5taXlvciJ9LAotCi0gICAgeyBFUl9PRkZTRVRfQklHR0VSX1RIQU5fU0xPVCwKLSAgICAgICJHXHUwMGY2cmVsaSBrb251bSB5dXZhZGFuIGJcdTAwZmN5XHUwMGZjayJ9LAotCi0gICAgeyBFUl9DT1JPVVRJTkVfTk9UX0FWQUlMLAotICAgICAgIkNvcm91dGluZSBrdWxsYW5cdTAxMzFsYW1cdTAxMzF5b3IsIGlkPXswfSJ9LAotCi0gICAgeyBFUl9DT1JPVVRJTkVfQ09fRVhJVCwKLSAgICAgICJDb3JvdXRpbmVNYW5hZ2VyIGNvX2V4aXQoKSBpc3RlXHUwMTFmaSBhbGRcdTAxMzEifSwKLQotICAgIHsgRVJfQ09KT0lOUk9VVElORVNFVF9GQUlMRUQsCi0gICAgICAiY29fam9pbkNvcm91dGluZVNldCgpIGJhXHUwMTVmYXJcdTAxMzFzXHUwMTMxeiBvbGR1In0sCi0KLSAgICB7IEVSX0NPUk9VVElORV9QQVJBTSwKLSAgICAgICJDb3JvdXRpbmUgZGVcdTAxMWZpXHUwMTVmdGlyZ2VzaSBoYXRhc1x1MDEzMSAoezB9KSJ9LAotCi0gICAgeyBFUl9QQVJTRVJfRE9URVJNSU5BVEVfQU5TV0VSUywKLSAgICAgICJcbkJFS0xFTk1FWUVOOiBQYXJzZXIgZG9UZXJtaW5hdGUgeWFuXHUwMTMxdFx1MDEzMSB7MH0ifSwKLQotICAgIHsgRVJfTk9fUEFSU0VfQ0FMTF9XSElMRV9QQVJTSU5HLAotICAgICAgIkF5clx1MDEzMVx1MDE1ZnRcdTAxMzFybWEgc1x1MDEzMXJhc1x1MDEzMW5kYSBwYXJzZSBcdTAwZTdhXHUwMTFmclx1MDEzMWxhbWF6In0sCi0KLSAgICB7IEVSX1RZUEVEX0lURVJBVE9SX0FYSVNfTk9UX0lNUExFTUVOVEVELAotICAgICAgIkhhdGE6IHswfSBla3NlbmkgaVx1MDBlN2luIHRpcCBhdGFubVx1MDEzMVx1MDE1ZiB5aW5lbGV5aWNpIGdlclx1MDBlN2VrbGVcdTAxNWZ0aXJpbG1lZGkifSwKLQotICAgIHsgRVJfSVRFUkFUT1JfQVhJU19OT1RfSU1QTEVNRU5URUQsCi0gICAgICAiSGF0YTogezB9IGVrc2VuaSBpXHUwMGU3aW4geWluZWxleWljaSBnZXJcdTAwZTdla2xlXHUwMTVmdGlyaWxtZWRpIn0sCi0KLSAgICB7IEVSX0lURVJBVE9SX0NMT05FX05PVF9TVVBQT1JURUQsCi0gICAgICAiWWluZWxleWljaSBlXHUwMTVma29weWFzXHUwMTMxIGRlc3Rla2xlbm1peW9yIn0sCi0KLSAgICB7IEVSX1VOS05PV05fQVhJU19UWVBFLAotICAgICAgIkJpbGlubWV5ZW4gZWtzZW4gZG9sYVx1MDE1Zm1hIHRpcGk6IHswfSJ9LAotCi0gICAgeyBFUl9BWElTX05PVF9TVVBQT1JURUQsCi0gICAgICAiRWtzZW4gZG9sYVx1MDE1Zlx1MDEzMWNcdTAxMzEgZGVzdGVrbGVubWl5b3I6IHswfSJ9LAotCi0gICAgeyBFUl9OT19EVE1JRFNfQVZBSUwsCi0gICAgICAiS3VsbGFuXHUwMTMxbGFiaWxlY2VrIGJhXHUwMTVma2EgRFRNIHRhblx1MDEzMXRcdTAxMzFjXHUwMTMxc1x1MDEzMSB5b2sifSwKLQotICAgIHsgRVJfTk9UX1NVUFBPUlRFRCwKLSAgICAgICJEZXN0ZWtsZW5taXlvcjogezB9In0sCi0KLSAgICB7IEVSX05PREVfTk9OX05VTEwsCi0gICAgICAiZ2V0RFRNSGFuZGxlRnJvbU5vZGUgaVx1MDBlN2luIGRcdTAwZmNcdTAxMWZcdTAwZmNtIGJvXHUwMTVmIGRlXHUwMTFmZXJsaSBvbG1hbWFsXHUwMTMxZFx1MDEzMXIifSwKLQotICAgIHsgRVJfQ09VTERfTk9UX1JFU09MVkVfTk9ERSwKLSAgICAgICJEXHUwMGZjXHUwMTFmXHUwMGZjbSB0YW5cdTAxMzF0XHUwMTMxY1x1MDEzMSBkZVx1MDExZmVyZSBcdTAwZTdcdTAwZjZ6XHUwMGZjbGVtZWRpIn0sCi0KLSAgICB7IEVSX1NUQVJUUEFSU0VfV0hJTEVfUEFSU0lORywKLSAgICAgICAiQXlyXHUwMTMxXHUwMTVmdFx1MDEzMXJtYSBzXHUwMTMxcmFzXHUwMTMxbmRhIHN0YXJ0UGFyc2UgXHUwMGU3YVx1MDExZnJcdTAxMzFsYW1heiJ9LAotCi0gICAgeyBFUl9TVEFSVFBBUlNFX05FRURTX1NBWFBBUlNFUiwKLSAgICAgICAic3RhcnRQYXJzZSBpXHUwMGU3aW4gYm9cdTAxNWYgZGVcdTAxMWZlcmxpIG9sbWF5YW4gU0FYUGFyc2VyIGdlcmVraXlvciJ9LAotCi0gICAgeyBFUl9DT1VMRF9OT1RfSU5JVF9QQVJTRVIsCi0gICAgICAgIkF5clx1MDEzMVx1MDE1ZnRcdTAxMzFyXHUwMTMxY1x1MDEzMSBidW51bmxhIGt1bGxhblx1MDEzMW1hIGhhelx1MDEzMXJsYW5hbWFkXHUwMTMxIn0sCi0KLSAgICB7IEVSX0VYQ0VQVElPTl9DUkVBVElOR19QT09MLAotICAgICAgICJIYXZ1eiBpXHUwMGU3aW4geWVuaSBcdTAwZjZybmVrIHlhcmF0XHUwMTMxbFx1MDEzMXJrZW4ga3VyYWwgZFx1MDEzMVx1MDE1Zlx1MDEzMSBkdXJ1bSJ9LAotCi0gICAgeyBFUl9QQVRIX0NPTlRBSU5TX0lOVkFMSURfRVNDQVBFX1NFUVVFTkNFLAotICAgICAgICJZb2wgZ2VcdTAwZTdlcnNpeiBrYVx1MDBlN1x1MDEzMVx1MDE1ZiBkaXppc2kgaVx1MDBlN2VyaXlvciJ9LAotCi0gICAgeyBFUl9TQ0hFTUVfUkVRVUlSRUQsCi0gICAgICAgIlx1MDE1ZWVtYSBnZXJla2xpISJ9LAotCi0gICAgeyBFUl9OT19TQ0hFTUVfSU5fVVJJLAotICAgICAgICJVUkkgaVx1MDBlN2luZGUgXHUwMTVmZW1hIGJ1bHVuYW1hZFx1MDEzMTogezB9In0sCi0KLSAgICB7IEVSX05PX1NDSEVNRV9JTlVSSSwKLSAgICAgICAiVVJJIGlcdTAwZTdpbmRlIFx1MDE1ZmVtYSBidWx1bmFtYWRcdTAxMzEifSwKLQotICAgIHsgRVJfUEFUSF9JTlZBTElEX0NIQVIsCi0gICAgICAgIllvbCBnZVx1MDBlN2Vyc2l6IGthcmFrdGVyIGlcdTAwZTdlcml5b3I6IHswfSJ9LAotCi0gICAgeyBFUl9TQ0hFTUVfRlJPTV9OVUxMX1NUUklORywKLSAgICAgICAiQm9cdTAxNWYgZGVcdTAxMWZlcmxpIGRpemdpZGVuIFx1MDE1ZmVtYSB0YW5cdTAxMzFtbGFuYW1heiJ9LAotCi0gICAgeyBFUl9TQ0hFTUVfTk9UX0NPTkZPUk1BTlQsCi0gICAgICAgIlx1MDE1ZWVtYSB1eXVtbHUgZGVcdTAxMWZpbC4ifSwKLQotICAgIHsgRVJfSE9TVF9BRERSRVNTX05PVF9XRUxMRk9STUVELAotICAgICAgICJBbmFzaXN0ZW0gZG9cdTAxMWZydSBiaVx1MDBlN2ltbGkgYmlyIGFkcmVzIGRlXHUwMTFmaWwifSwKLQotICAgIHsgRVJfUE9SVF9XSEVOX0hPU1RfTlVMTCwKLSAgICAgICAiQW5hc2lzdGVtIGJvXHUwMTVmIGRlXHUwMTFmZXJsaXlrZW4ga2FwXHUwMTMxIHRhblx1MDEzMW1sYW5hbWF6In0sCi0KLSAgICB7IEVSX0lOVkFMSURfUE9SVCwKLSAgICAgICAiS2FwXHUwMTMxIG51bWFyYXNcdTAxMzEgZ2VcdTAwZTdlcnNpeiJ9LAotCi0gICAgeyBFUl9GUkFHX0ZPUl9HRU5FUklDX1VSSSwKLSAgICAgICAiUGFyXHUwMGU3YSB5YWxuXHUwMTMxemNhIHNveXNhbCBVUkkgaVx1MDBlN2luIHRhblx1MDEzMW1sYW5hYmlsaXIifSwKLQotICAgIHsgRVJfRlJBR19XSEVOX1BBVEhfTlVMTCwKLSAgICAgICAiWW9sIGJvXHUwMTVmIGRlXHUwMTFmZXJsaXlrZW4gcGFyXHUwMGU3YSB0YW5cdTAxMzFtbGFuYW1heiJ9LAotCi0gICAgeyBFUl9GUkFHX0lOVkFMSURfQ0hBUiwKLSAgICAgICAiUGFyXHUwMGU3YSBnZVx1MDBlN2Vyc2l6IGthcmFrdGVyIGlcdTAwZTdlcml5b3IifSwKLQotICAgIHsgRVJfUEFSU0VSX0lOX1VTRSwKLSAgICAgICJBeXJcdTAxMzFcdTAxNWZ0XHUwMTMxclx1MDEzMWNcdTAxMzEga3VsbGFuXHUwMTMxbWRhIn0sCi0KLSAgICB7IEVSX0NBTk5PVF9DSEFOR0VfV0hJTEVfUEFSU0lORywKLSAgICAgICJBeXJcdTAxMzFcdTAxNWZ0XHUwMTMxcm1hIHNcdTAxMzFyYXNcdTAxMzFuZGEgezB9IHsxfSBkZVx1MDExZmlcdTAxNWZ0aXJpbGVtZXoifSwKLQotICAgIHsgRVJfU0VMRl9DQVVTQVRJT05fTk9UX1BFUk1JVFRFRCwKLSAgICAgICJcdTAwZDZ6bmVkZW5zZWxsaVx1MDExZmUgaXppbiB2ZXJpbG1leiJ9LAotCi0gICAgeyBFUl9OT19VU0VSSU5GT19JRl9OT19IT1NULAotICAgICAgIkFuYXNpc3RlbSBiZWxpcnRpbG1lZGl5c2Uga3VsbGFuXHUwMTMxY1x1MDEzMSBiaWxnaXNpIGJlbGlydGlsZW1leiJ9LAotCi0gICAgeyBFUl9OT19QT1JUX0lGX05PX0hPU1QsCi0gICAgICAiQW5hc2lzdGVtIGJlbGlydGlsbWVkaXlzZSBrYXBcdTAxMzEgYmVsaXJ0aWxlbWV6In0sCi0KLSAgICB7IEVSX05PX1FVRVJZX1NUUklOR19JTl9QQVRILAotICAgICAgIllvbCB2ZSBzb3JndSBkaXpnaXNpbmRlIHNvcmd1IGRpemdpc2kgYmVsaXJ0aWxlbWV6In0sCi0KLSAgICB7IEVSX05PX0ZSQUdNRU5UX1NUUklOR19JTl9QQVRILAotICAgICAgIlBhclx1MDBlN2EgaGVtIHlvbGRhLCBoZW0gZGUgcGFyXHUwMGU3YWRhIGJlbGlydGlsZW1leiJ9LAotCi0gICAgeyBFUl9DQU5OT1RfSU5JVF9VUklfRU1QVFlfUEFSTVMsCi0gICAgICAiQm9cdTAxNWYgZGVcdTAxMWZpXHUwMTVmdGlyZ2VsZXJsZSBVUkkga3VsbGFuXHUwMTMxbWEgaGF6XHUwMTMxcmxhbmFtYXoifSwKLQotICAgIHsgRVJfTUVUSE9EX05PVF9TVVBQT1JURUQsCi0gICAgICAiWVx1MDBmNm50ZW0gaGVuXHUwMGZjeiBkZXN0ZWtsZW5taXlvciJ9LAotCi0gICAgeyBFUl9JTkNSU0FYU1JDRklMVEVSX05PVF9SRVNUQVJUQUJMRSwKLSAgICAgICJJbmNyZW1lbnRhbFNBWFNvdXJjZV9GaWx0ZXIgXHUwMTVmdSBhbiB5ZW5pZGVuIGJhXHUwMTVmbGF0XHUwMTMxbGFiaWxpciBkdXJ1bWRhIGRlXHUwMTFmaWwifSwKLQotICAgIHsgRVJfWE1MUkRSX05PVF9CRUZPUkVfU1RBUlRQQVJTRSwKLSAgICAgICJYTUxSZWFkZXIsIHN0YXJ0UGFyc2UgaXN0ZVx1MDExZmluZGVuIFx1MDBmNm5jZSBvbG1heiJ9LAotCi0gICAgeyBFUl9BWElTX1RSQVZFUlNFUl9OT1RfU1VQUE9SVEVELAotICAgICAgIkVrc2VuIGRvbGFcdTAxNWZcdTAxMzFjXHUwMTMxIGRlc3Rla2xlbm1peW9yOiB7MH0ifSwKLQotICAgIHsgRVJfRVJST1JIQU5ETEVSX0NSRUFURURfV0lUSF9OVUxMX1BSSU5UV1JJVEVSLAotICAgICAgIkxpc3RpbmdFcnJvckhhbmRsZXIgYm9cdTAxNWYgZGVcdTAxMWZlcmxpIFByaW50V3JpdGVyIGlsZSB5YXJhdFx1MDEzMWxkXHUwMTMxISJ9LAotCi0gICAgeyBFUl9TWVNURU1JRF9VTktOT1dOLAotICAgICAgIlN5c3RlbUlkIGJpbGlubWl5b3IifSwKLQotICAgIHsgRVJfTE9DQVRJT05fVU5LTk9XTiwKLSAgICAgICJIYXRhIHllcmkgYmlsaW5taXlvciJ9LAotCi0gICAgeyBFUl9QUkVGSVhfTVVTVF9SRVNPTFZFLAotICAgICAgIlx1MDBkNm5layBiaXIgYWQgYWxhblx1MDEzMW5hIFx1MDBlN1x1MDBmNnpcdTAwZmNsbWVsaWRpcjogezB9In0sCi0KLSAgICB7IEVSX0NSRUFURURPQ1VNRU5UX05PVF9TVVBQT1JURUQsCi0gICAgICAiWFBhdGhDb250ZXh0IGlcdTAwZTdpbmRlIGNyZWF0ZURvY3VtZW50KCkgZGVzdGVrbGVubWl5b3IhIn0sCi0KLSAgICB7IEVSX0NISUxEX0hBU19OT19PV05FUl9ET0NVTUVOVCwKLSAgICAgICJcdTAwZDZ6bml0ZWxpXHUwMTFmaW4gYWx0IFx1MDBmNlx1MDExZmVzaW5pbiBpeWUgYmVsZ2VzaSB5b2shIn0sCi0KLSAgICB7IEVSX0NISUxEX0hBU19OT19PV05FUl9ET0NVTUVOVF9FTEVNRU5ULAotICAgICAgIlx1MDBkNnpuaXRlbGlcdTAxMWZpbiBhbHQgXHUwMGY2XHUwMTFmZXNpbmluIGl5ZSBiZWxnZSBcdTAwZjZcdTAxMWZlc2kgeW9rISJ9LAotCi0gICAgeyBFUl9DQU5UX09VVFBVVF9URVhUX0JFRk9SRV9ET0MsCi0gICAgICAiVXlhclx1MDEzMTogQmVsZ2UgXHUwMGY2XHUwMTFmZXNpbmRlbiBcdTAwZjZuY2UgbWV0aW4gXHUwMGU3XHUwMTMxa1x1MDEzMVx1MDE1Zlx1MDEzMSBvbGFtYXohICBZb2tzYXlcdTAxMzFsXHUwMTMxeW9yLi4uIn0sCi0KLSAgICB7IEVSX0NBTlRfSEFWRV9NT1JFX1RIQU5fT05FX1JPT1QsCi0gICAgICAiRE9NIFx1MDBmY3plcmluZGUgYmlyZGVuIGZhemxhIGtcdTAwZjZrIG9sYW1heiEifSwKLQotICAgIHsgRVJfQVJHX0xPQ0FMTkFNRV9OVUxMLAotICAgICAgICInbG9jYWxOYW1lJyBiYVx1MDExZlx1MDEzMW1zXHUwMTMxeiBkZVx1MDExZmlcdTAxNWZ0aXJnZXNpIGJvXHUwMTVmIGRlXHUwMTFmZXJsaSJ9LAotCi0gICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIEEgUU5BTUUgaGFzIHRoZSBzeW50YWN0aWMgZm9ybSBbTkNOYW1lOl1OQ05hbWUKLSAgICAvLyBUaGUgbG9jYWxuYW1lIGlzIHRoZSBwb3J0aW9uIGFmdGVyIHRoZSBvcHRpb25hbCBjb2xvbjsgdGhlIG1lc3NhZ2UgaW5kaWNhdGVzCi0gICAgLy8gdGhhdCB0aGVyZSBpcyBhIHByb2JsZW0gd2l0aCB0aGF0IHBhcnQgb2YgdGhlIFFOQU1FLgotICAgIHsgRVJfQVJHX0xPQ0FMTkFNRV9JTlZBTElELAotICAgICAgICJRTkFNRSBpXHUwMGU3aW5kZWtpIHllcmVsIGFkIChsb2NhbG5hbWUpIGdlXHUwMGU3ZXJsaSBiaXIgTkNOYW1lIG9sbWFsXHUwMTMxZFx1MDEzMXIifSwKLQotICAgIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBIFFOQU1FIGhhcyB0aGUgc3ludGFjdGljIGZvcm0gW05DTmFtZTpdTkNOYW1lCi0gICAgLy8gVGhlIHByZWZpeCBpcyB0aGUgcG9ydGlvbiBiZWZvcmUgdGhlIG9wdGlvbmFsIGNvbG9uOyB0aGUgbWVzc2FnZSBpbmRpY2F0ZXMKLSAgICAvLyB0aGF0IHRoZXJlIGlzIGEgcHJvYmxlbSB3aXRoIHRoYXQgcGFydCBvZiB0aGUgUU5BTUUuCi0gICAgeyBFUl9BUkdfUFJFRklYX0lOVkFMSUQsCi0gICAgICAgIlFOQU1FIGlcdTAwZTdpbmRla2kgXHUwMGY2bmVrIGdlXHUwMGU3ZXJsaSBiaXIgTkNOYW1lIG9sbWFsXHUwMTMxZFx1MDEzMXIifSwKLQotICAgIHsgIkJBRF9DT0RFIiwgImNyZWF0ZU1lc3NhZ2UgaVx1MDBlN2luIGt1bGxhblx1MDEzMWxhbiBkZVx1MDExZmlcdTAxNWZ0aXJnZSBzXHUwMTMxblx1MDEzMXJsYXJcdTAxMzFuIGRcdTAxMzFcdTAxNWZcdTAxMzFuZGEifSwKLSAgICB7ICJGT1JNQVRfRkFJTEVEIiwgIm1lc3NhZ2VGb3JtYXQgXHUwMGU3YVx1MDExZnJcdTAxMzFzXHUwMTMxIHNcdTAxMzFyYXNcdTAxMzFuZGEga3VyYWwgZFx1MDEzMVx1MDE1Zlx1MDEzMSBkdXJ1bSB5YXlcdTAxMzFubGFuZFx1MDEzMSJ9LAotICAgIHsgImxpbmUiLCAiU2F0XHUwMTMxciAjIn0sCi0gICAgeyAiY29sdW1uIiwiS29sb24gIyJ9LAotCi0gICAge0VSX1NFUklBTElaRVJfTk9UX0NPTlRFTlRIQU5ETEVSLAotICAgICAgIkRpemlzZWxsZVx1MDE1ZnRpcmljaSBzXHUwMTMxblx1MDEzMWZcdTAxMzEgJyd7MH0nJyBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciBpXHUwMTVmbGV2aW5pIHV5Z3VsYW1cdTAxMzF5b3IuIn0sCi0KLSAgICB7RVJfUkVTT1VSQ0VfQ09VTERfTk9UX0ZJTkQsCi0gICAgICAiS2F5bmFrIFsgezB9IF0gYnVsdW5hbWFkXHUwMTMxLlxuIHsxfSIgfSwKLQotICAgIHtFUl9SRVNPVVJDRV9DT1VMRF9OT1RfTE9BRCwKLSAgICAgICJLYXluYWsgWyB7MH0gXSB5XHUwMGZja2xleWVtZWRpOiB7MX0gXG4gezJ9IFx0IHszfSIgfSwKLQotICAgIHtFUl9CVUZGRVJfU0laRV9MRVNTVEhBTl9aRVJPLAotICAgICAgIkFyYWJlbGxlayBiXHUwMGZjeVx1MDBmY2tsXHUwMGZjXHUwMTFmXHUwMGZjIDw9MCIgfSwKLQotICAgIHtFUl9JTlZBTElEX1VURjE2X1NVUlJPR0FURSwKLSAgICAgICJVVEYtMTYgeWVyaW5lIGt1bGxhblx1MDEzMWxhbiBkZVx1MDExZmVyIGdlXHUwMGU3ZXJzaXo6IHswfSA/IiB9LAotCi0gICAge0VSX09JRVJST1IsCi0gICAgICAiR1x1MDBjNyBoYXRhc1x1MDEzMSIgfSwKLQotICAgIHtFUl9JTExFR0FMX0FUVFJJQlVURV9QT1NJVElPTiwKLSAgICAgICJBbHQgZFx1MDBmY1x1MDExZlx1MDBmY21sZXJkZW4gc29ucmEgeWEgZGEgYmlyIFx1MDBmNlx1MDExZmUgXHUwMGZjcmV0aWxtZWRlbiBcdTAwZjZuY2UgezB9IFx1MDBmNnpuaXRlbGlcdTAxMWZpIGVrbGVuZW1lei4gXHUwMGQ2em5pdGVsaWsgeW9rc2F5XHUwMTMxbGFjYWsuIn0sCi0KLSAgICAgIC8qCi0gICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN0eWxlc2hlZXQgY29udGFpbmVkIGEgcmVmZXJlbmNlIHRvIGEKLSAgICAgICAqIG5hbWVzcGFjZSBwcmVmaXggdGhhdCB3YXMgdW5kZWZpbmVkLiAgVGhlIHZhbHVlIG9mIHRoZSBzdWJzdGl0dXRpb24KLSAgICAgICAqIHRleHQgaXMgdGhlIG5hbWUgb2YgdGhlIHByZWZpeC4KLSAgICAgICAqLwotICAgIHtFUl9OQU1FU1BBQ0VfUFJFRklYLAotICAgICAgIicnezB9JycgXHUwMGY2bmVraW5lIGlsaVx1MDE1ZmtpbiBhZCBhbGFuXHUwMTMxIGJpbGRpcmlsbWVkaS4iIH0sCi0gICAgICAvKgotICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyByZXBvcnRlZCBpZiB0aGUgc3R5bGVzaGVldAotICAgICAgICogYmVpbmcgcHJvY2Vzc2VkIGF0dGVtcHRlZCB0byBjb25zdHJ1Y3QgYW4gWE1MIGRvY3VtZW50IHdpdGggYW4KLSAgICAgICAqIGF0dHJpYnV0ZSBpbiBhIHBsYWNlIG90aGVyIHRoYW4gb24gYW4gZWxlbWVudC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICogc3BlY2lmaWVzIHRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUuCi0gICAgICAgKi8KLSAgICB7RVJfU1RSQVlfQVRUUklCVVRFLAotICAgICAgIicnezB9JycgXHUwMGY2em5pdGVsaVx1MDExZmkgXHUwMGY2XHUwMTFmZW5pbiBkXHUwMTMxXHUwMTVmXHUwMTMxbmRhLiIgfSwKLQotICAgICAgLyoKLSAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBcyB3aXRoIHRoZSBwcmVjZWRpbmcgbWVzc2FnZSwgYSBuYW1lc3BhY2UKLSAgICAgICAqIGRlY2xhcmF0aW9uIGhhcyB0aGUgZm9ybSBvZiBhbiBhdHRyaWJ1dGUgYW5kIGlzIG9ubHkgcGVybWl0dGVkIHRvCi0gICAgICAgKiBhcHBlYXIgb24gYW4gZWxlbWVudC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCB7MH0gaXMgdGhlIG5hbWVzcGFjZQotICAgICAgICogcHJlZml4IGFuZCB7MX0gaXMgdGhlIFVSSSB0aGF0IHdhcyBiZWluZyB1c2VkIGluIHRoZSBlcnJvbmVvdXMKLSAgICAgICAqIG5hbWVzcGFjZSBkZWNsYXJhdGlvbi4KLSAgICAgICAqLwotICAgIHtFUl9TVFJBWV9OQU1FU1BBQ0UsCi0gICAgICAiJyd7MH0nJz0nJ3sxfScnIGFkIGFsYW5cdTAxMzEgYmlsZGlyaW1pIFx1MDBmNlx1MDExZmVuaW4gZFx1MDEzMVx1MDE1Zlx1MDEzMW5kYS4iIH0sCi0KLSAgICB7RVJfQ09VTERfTk9UX0xPQURfUkVTT1VSQ0UsCi0gICAgICAiJyd7MH0nJyB5XHUwMGZja2xlbmVtZWRpIChDTEFTU1BBVEggZGVcdTAxMWZpXHUwMTVma2VuaW5pemkgaW5jZWxleWluKSwgeWFsblx1MDEzMXpjYSB2YXJzYXlcdTAxMzFsYW5sYXIga3VsbGFuXHUwMTMxbFx1MDEzMXlvciJ9LAotCi0gICAge0VSX0NPVUxEX05PVF9MT0FEX01FVEhPRF9QUk9QRVJUWSwKLSAgICAgICInJ3sxfScnIFx1MDBlN1x1MDEzMWtcdTAxMzFcdTAxNWYgeVx1MDBmNm50ZW1pIGlcdTAwZTdpbiAnJ3swfScnIFx1MDBmNnplbGxpayBkb3N5YXNcdTAxMzEgeVx1MDBmY2tsZW5lbWVkaSAoQ0xBU1NQQVRIIGRlXHUwMTFmaVx1MDE1ZmtlbmluaSBpbmNlbGV5aW4pIiB9Ci0KLQotICB9OwotCi0gIC8qKgotICAgKiBHZXQgdGhlIGxvb2t1cCB0YWJsZSBmb3IgZXJyb3IgbWVzc2FnZXMKLSAgICoKLSAgICogQHJldHVybiBUaGUgYXNzb2NpYXRpb24gbGlzdC4KLSAgICovCi0gIHB1YmxpYyBPYmplY3RbXVtdIGdldENvbnRlbnRzKCkKLSAgewotICAgIHJldHVybiBfY29udGVudHM7Ci0gIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvcmVzL1hNTEVycm9yUmVzb3VyY2VzX3poX0NOLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9yZXMvWE1MRXJyb3JSZXNvdXJjZXNfemhfQ04uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYzUwMDEzNS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9yZXMvWE1MRXJyb3JSZXNvdXJjZXNfemhfQ04uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQ1MCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzOwotCi0KLWltcG9ydCBqYXZhLnV0aWwuTGlzdFJlc291cmNlQnVuZGxlOwotCi0vKioKLSAqIFNldCB1cCBlcnJvciBtZXNzYWdlcy4KLSAqIFdlIGJ1aWxkIGEgdHdvIGRpbWVuc2lvbmFsIGFycmF5IG9mIG1lc3NhZ2Uga2V5cyBhbmQKLSAqIG1lc3NhZ2Ugc3RyaW5ncy4gSW4gb3JkZXIgdG8gYWRkIGEgbmV3IG1lc3NhZ2UgaGVyZSwKLSAqIHlvdSBuZWVkIHRvIGZpcnN0IGFkZCBhIFN0cmluZyBjb25zdGFudC4gQW5kIHlvdSBuZWVkCi0gKiB0byBlbnRlciBrZXksIHZhbHVlIHBhaXIgYXMgcGFydCBvZiB0aGUgY29udGVudHMKLSAqIGFycmF5LiBZb3UgYWxzbyBuZWVkIHRvIHVwZGF0ZSBNQVhfQ09ERSBmb3IgZXJyb3Igc3RyaW5ncwotICogYW5kIE1BWF9XQVJOSU5HIGZvciB3YXJuaW5ncyAoIE5lZWRlZCBmb3Igb25seSBpbmZvcm1hdGlvbgotICogcHVycG9zZSApCi0gKi8KLXB1YmxpYyBjbGFzcyBYTUxFcnJvclJlc291cmNlc196aF9DTiBleHRlbmRzIExpc3RSZXNvdXJjZUJ1bmRsZQotewotCi0vKgotICogVGhpcyBmaWxlIGNvbnRhaW5zIGVycm9yIGFuZCB3YXJuaW5nIG1lc3NhZ2VzIHJlbGF0ZWQgdG8gWGFsYW4gRXJyb3IKLSAqIEhhbmRsaW5nLgotICoKLSAqICBHZW5lcmFsIG5vdGVzIHRvIHRyYW5zbGF0b3JzOgotICoKLSAqICAxKSBYYWxhbiAob3IgbW9yZSBwcm9wZXJseSwgWGFsYW4taW50ZXJwcmV0aXZlKSBhbmQgWFNMVEMgYXJlIG5hbWVzIG9mCi0gKiAgICAgY29tcG9uZW50cy4KLSAqICAgICBYU0xUIGlzIGFuIGFjcm9ueW0gZm9yICJYTUwgU3R5bGVzaGVldCBMYW5ndWFnZTogVHJhbnNmb3JtYXRpb25zIi4KLSAqICAgICBYU0xUQyBpcyBhbiBhY3JvbnltIGZvciBYU0xUIENvbXBpbGVyLgotICoKLSAqICAyKSBBIHN0eWxlc2hlZXQgaXMgYSBkZXNjcmlwdGlvbiBvZiBob3cgdG8gdHJhbnNmb3JtIGFuIGlucHV0IFhNTCBkb2N1bWVudAotICogICAgIGludG8gYSByZXN1bHRhbnQgWE1MIGRvY3VtZW50IChvciBIVE1MIGRvY3VtZW50IG9yIHRleHQpLiAgVGhlCi0gKiAgICAgc3R5bGVzaGVldCBpdHNlbGYgaXMgZGVzY3JpYmVkIGluIHRoZSBmb3JtIG9mIGFuIFhNTCBkb2N1bWVudC4KLSAqCi0gKiAgMykgQSB0ZW1wbGF0ZSBpcyBhIGNvbXBvbmVudCBvZiBhIHN0eWxlc2hlZXQgdGhhdCBpcyB1c2VkIHRvIG1hdGNoIGEKLSAqICAgICBwYXJ0aWN1bGFyIHBvcnRpb24gb2YgYW4gaW5wdXQgZG9jdW1lbnQgYW5kIHNwZWNpZmllcyB0aGUgZm9ybSBvZiB0aGUKLSAqICAgICBjb3JyZXNwb25kaW5nIHBvcnRpb24gb2YgdGhlIG91dHB1dCBkb2N1bWVudC4KLSAqCi0gKiAgNCkgQW4gZWxlbWVudCBpcyBhIG1hcmstdXAgdGFnIGluIGFuIFhNTCBkb2N1bWVudDsgYW4gYXR0cmlidXRlIGlzIGEKLSAqICAgICBtb2RpZmllciBvbiB0aGUgdGFnLiAgRm9yIGV4YW1wbGUsIGluIDxlbGVtIGF0dHI9J3ZhbCcgYXR0cjI9J3ZhbDInPgotICogICAgICJlbGVtIiBpcyBhbiBlbGVtZW50IG5hbWUsICJhdHRyIiBhbmQgImF0dHIyIiBhcmUgYXR0cmlidXRlIG5hbWVzIHdpdGgKLSAqICAgICB0aGUgdmFsdWVzICJ2YWwiIGFuZCAidmFsMiIsIHJlc3BlY3RpdmVseS4KLSAqCi0gKiAgNSkgQSBuYW1lc3BhY2UgZGVjbGFyYXRpb24gaXMgYSBzcGVjaWFsIGF0dHJpYnV0ZSB0aGF0IGlzIHVzZWQgdG8gYXNzb2NpYXRlCi0gKiAgICAgYSBwcmVmaXggd2l0aCBhIFVSSSAodGhlIG5hbWVzcGFjZSkuICBUaGUgbWVhbmluZ3Mgb2YgZWxlbWVudCBuYW1lcyBhbmQKLSAqICAgICBhdHRyaWJ1dGUgbmFtZXMgdGhhdCB1c2UgdGhhdCBwcmVmaXggYXJlIGRlZmluZWQgd2l0aCByZXNwZWN0IHRvIHRoYXQKLSAqICAgICBuYW1lc3BhY2UuCi0gKgotICogIDYpICJUcmFuc2xldCIgaXMgYW4gaW52ZW50ZWQgdGVybSB0aGF0IGRlc2NyaWJlcyB0aGUgY2xhc3MgZmlsZSB0aGF0Ci0gKiAgICAgcmVzdWx0cyBmcm9tIGNvbXBpbGluZyBhbiBYTUwgc3R5bGVzaGVldCBpbnRvIGEgSmF2YSBjbGFzcy4KLSAqCi0gKiAgNykgWFBhdGggaXMgYSBzcGVjaWZpY2F0aW9uIHRoYXQgZGVzY3JpYmVzIGEgbm90YXRpb24gZm9yIGlkZW50aWZ5aW5nCi0gKiAgICAgbm9kZXMgaW4gYSB0cmVlLXN0cnVjdHVyZWQgcmVwcmVzZW50YXRpb24gb2YgYW4gWE1MIGRvY3VtZW50LiAgQW4KLSAqICAgICBpbnN0YW5jZSBvZiB0aGF0IG5vdGF0aW9uIGlzIHJlZmVycmVkIHRvIGFzIGFuIFhQYXRoIGV4cHJlc3Npb24uCi0gKgotICovCi0KLSAgLyoqIE1heGltdW0gZXJyb3IgbWVzc2FnZXMsIHRoaXMgaXMgbmVlZGVkIHRvIGtlZXAgdHJhY2sgb2YgdGhlIG51bWJlciBvZiBtZXNzYWdlcy4gICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFYX0NPREUgPSA2MTsKLQotICAvKiogTWF4aW11bSB3YXJuaW5ncywgdGhpcyBpcyBuZWVkZWQgdG8ga2VlcCB0cmFjayBvZiB0aGUgbnVtYmVyIG9mIHdhcm5pbmdzLiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVhfV0FSTklORyA9IDA7Ci0KLSAgLyoqIE1heGltdW0gbWlzYyBzdHJpbmdzLiAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BWF9PVEhFUlMgPSA0OwotCi0gIC8qKiBNYXhpbXVtIHRvdGFsIHdhcm5pbmdzIGFuZCBlcnJvciBtZXNzYWdlcy4gICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFYX01FU1NBR0VTID0gTUFYX0NPREUgKyBNQVhfV0FSTklORyArIDE7Ci0KLQotICAvKgotICAgKiBNZXNzYWdlIGtleXMKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQgPSAiRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9PVkVSV1JJVEVfQ0FVU0UgPSAiRVJfQ0FOTk9UX09WRVJXUklURV9DQVVTRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX0RFRkFVTFRfSU1QTCA9ICJFUl9OT19ERUZBVUxUX0lNUEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DSFVOS0VESU5UQVJSQVlfTk9UX1NVUFBPUlRFRCA9ICJFUl9DSFVOS0VESU5UQVJSQVlfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX09GRlNFVF9CSUdHRVJfVEhBTl9TTE9UID0gIkVSX09GRlNFVF9CSUdHRVJfVEhBTl9TTE9UIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09ST1VUSU5FX05PVF9BVkFJTCA9ICJFUl9DT1JPVVRJTkVfTk9UX0FWQUlMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09ST1VUSU5FX0NPX0VYSVQgPSAiRVJfQ09ST1VUSU5FX0NPX0VYSVQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT0pPSU5ST1VUSU5FU0VUX0ZBSUxFRCA9ICJFUl9DT0pPSU5ST1VUSU5FU0VUX0ZBSUxFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPUk9VVElORV9QQVJBTSA9ICJFUl9DT1JPVVRJTkVfUEFSQU0iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QQVJTRVJfRE9URVJNSU5BVEVfQU5TV0VSUyA9ICJFUl9QQVJTRVJfRE9URVJNSU5BVEVfQU5TV0VSUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1BBUlNFX0NBTExfV0hJTEVfUEFSU0lORyA9ICJFUl9OT19QQVJTRV9DQUxMX1dISUxFX1BBUlNJTkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9UWVBFRF9JVEVSQVRPUl9BWElTX05PVF9JTVBMRU1FTlRFRCA9ICJFUl9UWVBFRF9JVEVSQVRPUl9BWElTX05PVF9JTVBMRU1FTlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lURVJBVE9SX0FYSVNfTk9UX0lNUExFTUVOVEVEID0gIkVSX0lURVJBVE9SX0FYSVNfTk9UX0lNUExFTUVOVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSVRFUkFUT1JfQ0xPTkVfTk9UX1NVUFBPUlRFRCA9ICJFUl9JVEVSQVRPUl9DTE9ORV9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5LTk9XTl9BWElTX1RZUEUgPSAiRVJfVU5LTk9XTl9BWElTX1RZUEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9BWElTX05PVF9TVVBQT1JURUQgPSAiRVJfQVhJU19OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fRFRNSURTX0FWQUlMID0gIkVSX05PX0RUTUlEU19BVkFJTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PVF9TVVBQT1JURUQgPSAiRVJfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PREVfTk9OX05VTEwgPSAiRVJfTk9ERV9OT05fTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxEX05PVF9SRVNPTFZFX05PREUgPSAiRVJfQ09VTERfTk9UX1JFU09MVkVfTk9ERSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NUQVJUUEFSU0VfV0hJTEVfUEFSU0lORyA9ICJFUl9TVEFSVFBBUlNFX1dISUxFX1BBUlNJTkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TVEFSVFBBUlNFX05FRURTX1NBWFBBUlNFUiA9ICJFUl9TVEFSVFBBUlNFX05FRURTX1NBWFBBUlNFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxEX05PVF9JTklUX1BBUlNFUiA9ICJFUl9DT1VMRF9OT1RfSU5JVF9QQVJTRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FWENFUFRJT05fQ1JFQVRJTkdfUE9PTCA9ICJFUl9FWENFUFRJT05fQ1JFQVRJTkdfUE9PTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BBVEhfQ09OVEFJTlNfSU5WQUxJRF9FU0NBUEVfU0VRVUVOQ0UgPSAiRVJfUEFUSF9DT05UQUlOU19JTlZBTElEX0VTQ0FQRV9TRVFVRU5DRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NDSEVNRV9SRVFVSVJFRCA9ICJFUl9TQ0hFTUVfUkVRVUlSRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19TQ0hFTUVfSU5fVVJJID0gIkVSX05PX1NDSEVNRV9JTl9VUkkiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19TQ0hFTUVfSU5VUkkgPSAiRVJfTk9fU0NIRU1FX0lOVVJJIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUEFUSF9JTlZBTElEX0NIQVIgPSAiRVJfUEFUSF9JTlZBTElEX0NIQVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TQ0hFTUVfRlJPTV9OVUxMX1NUUklORyA9ICJFUl9TQ0hFTUVfRlJPTV9OVUxMX1NUUklORyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NDSEVNRV9OT1RfQ09ORk9STUFOVCA9ICJFUl9TQ0hFTUVfTk9UX0NPTkZPUk1BTlQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9IT1NUX0FERFJFU1NfTk9UX1dFTExGT1JNRUQgPSAiRVJfSE9TVF9BRERSRVNTX05PVF9XRUxMRk9STUVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUE9SVF9XSEVOX0hPU1RfTlVMTCA9ICJFUl9QT1JUX1dIRU5fSE9TVF9OVUxMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9QT1JUID0gIkVSX0lOVkFMSURfUE9SVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZSQUdfRk9SX0dFTkVSSUNfVVJJID0iRVJfRlJBR19GT1JfR0VORVJJQ19VUkkiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GUkFHX1dIRU5fUEFUSF9OVUxMID0gIkVSX0ZSQUdfV0hFTl9QQVRIX05VTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GUkFHX0lOVkFMSURfQ0hBUiA9ICJFUl9GUkFHX0lOVkFMSURfQ0hBUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BBUlNFUl9JTl9VU0UgPSAiRVJfUEFSU0VSX0lOX1VTRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9DSEFOR0VfV0hJTEVfUEFSU0lORyA9ICJFUl9DQU5OT1RfQ0hBTkdFX1dISUxFX1BBUlNJTkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TRUxGX0NBVVNBVElPTl9OT1RfUEVSTUlUVEVEID0gIkVSX1NFTEZfQ0FVU0FUSU9OX05PVF9QRVJNSVRURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19VU0VSSU5GT19JRl9OT19IT1NUID0gIkVSX05PX1VTRVJJTkZPX0lGX05PX0hPU1QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19QT1JUX0lGX05PX0hPU1QgPSAiRVJfTk9fUE9SVF9JRl9OT19IT1NUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fUVVFUllfU1RSSU5HX0lOX1BBVEggPSAiRVJfTk9fUVVFUllfU1RSSU5HX0lOX1BBVEgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19GUkFHTUVOVF9TVFJJTkdfSU5fUEFUSCA9ICJFUl9OT19GUkFHTUVOVF9TVFJJTkdfSU5fUEFUSCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9JTklUX1VSSV9FTVBUWV9QQVJNUyA9ICJFUl9DQU5OT1RfSU5JVF9VUklfRU1QVFlfUEFSTVMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9NRVRIT0RfTk9UX1NVUFBPUlRFRCA9IkVSX01FVEhPRF9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5DUlNBWFNSQ0ZJTFRFUl9OT1RfUkVTVEFSVEFCTEUgPSAiRVJfSU5DUlNBWFNSQ0ZJTFRFUl9OT1RfUkVTVEFSVEFCTEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YTUxSRFJfTk9UX0JFRk9SRV9TVEFSVFBBUlNFID0gIkVSX1hNTFJEUl9OT1RfQkVGT1JFX1NUQVJUUEFSU0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9BWElTX1RSQVZFUlNFUl9OT1RfU1VQUE9SVEVEID0gIkVSX0FYSVNfVFJBVkVSU0VSX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FUlJPUkhBTkRMRVJfQ1JFQVRFRF9XSVRIX05VTExfUFJJTlRXUklURVIgPSAiRVJfRVJST1JIQU5ETEVSX0NSRUFURURfV0lUSF9OVUxMX1BSSU5UV1JJVEVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU1lTVEVNSURfVU5LTk9XTiA9ICJFUl9TWVNURU1JRF9VTktOT1dOIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTE9DQVRJT05fVU5LTk9XTiA9ICJFUl9MT0NBVElPTl9VTktOT1dOIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJFRklYX01VU1RfUkVTT0xWRSA9ICJFUl9QUkVGSVhfTVVTVF9SRVNPTFZFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ1JFQVRFRE9DVU1FTlRfTk9UX1NVUFBPUlRFRCA9ICJFUl9DUkVBVEVET0NVTUVOVF9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0hJTERfSEFTX05PX09XTkVSX0RPQ1VNRU5UID0gIkVSX0NISUxEX0hBU19OT19PV05FUl9ET0NVTUVOVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NISUxEX0hBU19OT19PV05FUl9ET0NVTUVOVF9FTEVNRU5UID0gIkVSX0NISUxEX0hBU19OT19PV05FUl9ET0NVTUVOVF9FTEVNRU5UIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9PVVRQVVRfVEVYVF9CRUZPUkVfRE9DID0gIkVSX0NBTlRfT1VUUFVUX1RFWFRfQkVGT1JFX0RPQyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfSEFWRV9NT1JFX1RIQU5fT05FX1JPT1QgPSAiRVJfQ0FOVF9IQVZFX01PUkVfVEhBTl9PTkVfUk9PVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FSR19MT0NBTE5BTUVfTlVMTCA9ICJFUl9BUkdfTE9DQUxOQU1FX05VTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9BUkdfTE9DQUxOQU1FX0lOVkFMSUQgPSAiRVJfQVJHX0xPQ0FMTkFNRV9JTlZBTElEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQVJHX1BSRUZJWF9JTlZBTElEID0gIkVSX0FSR19QUkVGSVhfSU5WQUxJRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05BTUVfQ0FOVF9TVEFSVF9XSVRIX0NPTE9OID0gIkVSX05BTUVfQ0FOVF9TVEFSVF9XSVRIX0NPTE9OIjsKLQotICAvLyBNZXNzYWdlIGtleXMgdXNlZCBieSB0aGUgc2VyaWFsaXplcgotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SRVNPVVJDRV9DT1VMRF9OT1RfRklORCA9ICJFUl9SRVNPVVJDRV9DT1VMRF9OT1RfRklORCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1JFU09VUkNFX0NPVUxEX05PVF9MT0FEID0gIkVSX1JFU09VUkNFX0NPVUxEX05PVF9MT0FEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQlVGRkVSX1NJWkVfTEVTU1RIQU5fWkVSTyA9ICJFUl9CVUZGRVJfU0laRV9MRVNTVEhBTl9aRVJPIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9VVEYxNl9TVVJST0dBVEUgPSAiRVJfSU5WQUxJRF9VVEYxNl9TVVJST0dBVEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9PSUVSUk9SID0gIkVSX09JRVJST1IiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OQU1FU1BBQ0VfUFJFRklYID0gIkVSX05BTUVTUEFDRV9QUkVGSVgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TVFJBWV9BVFRSSUJVVEUgPSAiRVJfU1RSQVlfQVRUSVJCVVRFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU1RSQVlfTkFNRVNQQUNFID0gIkVSX1NUUkFZX05BTUVTUEFDRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxEX05PVF9MT0FEX1JFU09VUkNFID0gIkVSX0NPVUxEX05PVF9MT0FEX1JFU09VUkNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTERfTk9UX0xPQURfTUVUSE9EX1BST1BFUlRZID0gIkVSX0NPVUxEX05PVF9MT0FEX01FVEhPRF9QUk9QRVJUWSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NFUklBTElaRVJfTk9UX0NPTlRFTlRIQU5ETEVSID0gIkVSX1NFUklBTElaRVJfTk9UX0NPTlRFTlRIQU5ETEVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSUxMRUdBTF9BVFRSSUJVVEVfUE9TSVRJT04gPSAiRVJfSUxMRUdBTF9BVFRSSUJVVEVfUE9TSVRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTExFR0FMX0NIQVJBQ1RFUiA9ICJFUl9JTExFR0FMX0NIQVJBQ1RFUiI7Ci0KLSAgLyoKLSAgICogTm93IGZpbGwgaW4gdGhlIG1lc3NhZ2UgdGV4dC4KLSAgICogVGhlbiBmaWxsIGluIHRoZSBtZXNzYWdlIHRleHQgZm9yIHRoYXQgbWVzc2FnZSBjb2RlIGluIHRoZQotICAgKiBhcnJheS4gVXNlIHRoZSBuZXcgZXJyb3IgY29kZSBhcyB0aGUgaW5kZXggaW50byB0aGUgYXJyYXkuCi0gICAqLwotCi0gIC8vIEVycm9yIG1lc3NhZ2VzLi4uCi0KLSAgLyoqIFRoZSBsb29rdXAgdGFibGUgZm9yIGVycm9yIG1lc3NhZ2VzLiAgICovCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIE9iamVjdFtdW10gY29udGVudHMgPSB7Ci0KLSAgLyoqIEVycm9yIG1lc3NhZ2UgSUQgdGhhdCBoYXMgYSBudWxsIG1lc3NhZ2UsIGJ1dCB0YWtlcyBpbiBhIHNpbmdsZSBvYmplY3QuICAgICovCi0gICAgeyJFUjAwMDAiICwgInswfSIgfSwKLQotICAgIHsgRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCwKLSAgICAgICJcdTRFMERcdTY1MkZcdTYzMDFcdThCRTVcdTUxRkRcdTY1NzAhIn0sCi0KLSAgICB7IEVSX0NBTk5PVF9PVkVSV1JJVEVfQ0FVU0UsCi0gICAgICAiXHU2NUUwXHU2Q0Q1XHU4OTg2XHU3NkQ2XHU1MzlGXHU1NkUwIn0sCi0KLSAgICB7IEVSX05PX0RFRkFVTFRfSU1QTCwKLSAgICAgICJcdTYyN0VcdTRFMERcdTUyMzBcdTlFRDhcdThCQTRcdTVCOUVcdTczQjAgIn0sCi0KLSAgICB7IEVSX0NIVU5LRURJTlRBUlJBWV9OT1RfU1VQUE9SVEVELAotICAgICAgIlx1NUY1M1x1NTI0RFx1NEUwRFx1NjUyRlx1NjMwMSBDaHVua2VkSW50QXJyYXkoezB9KSJ9LAotCi0gICAgeyBFUl9PRkZTRVRfQklHR0VSX1RIQU5fU0xPVCwKLSAgICAgICJcdTUwNEZcdTc5RkJcdTkxQ0ZcdTU5MjdcdTRFOEVcdTYzRDJcdTY5RkQifSwKLQotICAgIHsgRVJfQ09ST1VUSU5FX05PVF9BVkFJTCwKLSAgICAgICJDb3JvdXRpbmUgXHU0RTBEXHU1M0VGXHU3NTI4LCBpZD17MH0ifSwKLQotICAgIHsgRVJfQ09ST1VUSU5FX0NPX0VYSVQsCi0gICAgICAiQ29yb3V0aW5lTWFuYWdlciBcdTY1MzZcdTUyMzAgY29fZXhpdCgpIFx1OEJGN1x1NkM0MiJ9LAotCi0gICAgeyBFUl9DT0pPSU5ST1VUSU5FU0VUX0ZBSUxFRCwKLSAgICAgICJjb19qb2luQ29yb3V0aW5lU2V0KCkgXHU1OTMxXHU4RDI1In0sCi0KLSAgICB7IEVSX0NPUk9VVElORV9QQVJBTSwKLSAgICAgICJDb3JvdXRpbmUgXHU1M0MyXHU2NTcwXHU5NTE5XHU4QkVGICh7MH0pIn0sCi0KLSAgICB7IEVSX1BBUlNFUl9ET1RFUk1JTkFURV9BTlNXRVJTLAotICAgICAgIlxuXHU2MTBGXHU1OTE2OiBcdTg5RTNcdTY3OTBcdTU2NjhcdTVCRjlcdTdCNTRcdTU5MER7MH1cdTYyNjdcdTg4NEMgZG9UZXJtaW5hdGUifSwKLQotICAgIHsgRVJfTk9fUEFSU0VfQ0FMTF9XSElMRV9QQVJTSU5HLAotICAgICAgIlx1NjVFMFx1NkNENVx1NTcyOFx1ODlFM1x1Njc5MFx1NjVGNlx1OEMwM1x1NzUyOCBwYXJzZSJ9LAotCi0gICAgeyBFUl9UWVBFRF9JVEVSQVRPUl9BWElTX05PVF9JTVBMRU1FTlRFRCwKLSAgICAgICJcdTk1MTlcdThCRUY6IFx1NjcyQVx1NUI5RVx1NzNCMFx1OEY3NHswfVx1NzY4NFx1N0M3Qlx1NTc4Qlx1NTMxNlx1OEZFRFx1NEVFM1x1NTY2OCJ9LAotCi0gICAgeyBFUl9JVEVSQVRPUl9BWElTX05PVF9JTVBMRU1FTlRFRCwKLSAgICAgICJcdTk1MTlcdThCRUY6IFx1NjcyQVx1NUI5RVx1NzNCMFx1OEY3NHswfVx1NzY4NFx1OEZFRFx1NEVFM1x1NTY2OCAifSwKLQotICAgIHsgRVJfSVRFUkFUT1JfQ0xPTkVfTk9UX1NVUFBPUlRFRCwKLSAgICAgICJcdTRFMERcdTY1MkZcdTYzMDFcdTUxNEJcdTk2ODZcdThGRURcdTRFRTNcdTU2NjgifSwKLQotICAgIHsgRVJfVU5LTk9XTl9BWElTX1RZUEUsCi0gICAgICAiXHU4Rjc0XHU5MDREXHU1Mzg2XHU3QzdCXHU1NzhCXHU2NzJBXHU3N0U1OiB7MH0ifSwKLQotICAgIHsgRVJfQVhJU19OT1RfU1VQUE9SVEVELAotICAgICAgIlx1NEUwRFx1NjUyRlx1NjMwMVx1OEY3NFx1OTA0RFx1NTM4Nlx1N0EwQlx1NUU4RjogezB9In0sCi0KLSAgICB7IEVSX05PX0RUTUlEU19BVkFJTCwKLSAgICAgICJcdTY1RTBcdTZDRDVcdTRGN0ZcdTc1MjhcdTY2RjRcdTU5MUEgRFRNIElEIn0sCi0KLSAgICB7IEVSX05PVF9TVVBQT1JURUQsCi0gICAgICAiXHU0RTBEXHU2NTJGXHU2MzAxOiB7MH0ifSwKLQotICAgIHsgRVJfTk9ERV9OT05fTlVMTCwKLSAgICAgICJnZXREVE1IYW5kbGVGcm9tTm9kZSBcdTc2ODRcdTgyODJcdTcwQjlcdTVGQzVcdTk4N0JcdTRFM0FcdTk3NUVcdTdBN0FcdTUwM0MifSwKLQotICAgIHsgRVJfQ09VTERfTk9UX1JFU09MVkVfTk9ERSwKLSAgICAgICJcdTY1RTBcdTZDRDVcdTVDMDZcdTgyODJcdTcwQjlcdTg5RTNcdTY3OTBcdTRFM0FcdTUzRTVcdTY3QzQifSwKLQotICAgIHsgRVJfU1RBUlRQQVJTRV9XSElMRV9QQVJTSU5HLAotICAgICAgICJcdTY1RTBcdTZDRDVcdTU3MjhcdTg5RTNcdTY3OTBcdTY1RjZcdThDMDNcdTc1Mjggc3RhcnRQYXJzZSJ9LAotCi0gICAgeyBFUl9TVEFSVFBBUlNFX05FRURTX1NBWFBBUlNFUiwKLSAgICAgICAic3RhcnRQYXJzZSBcdTk3MDBcdTg5ODFcdTk3NUVcdTdBN0EgU0FYUGFyc2VyIn0sCi0KLSAgICB7IEVSX0NPVUxEX05PVF9JTklUX1BBUlNFUiwKLSAgICAgICAiXHU2NUUwXHU2Q0Q1XHU0RjdGXHU3NTI4XHU0RUU1XHU0RTBCXHU1QkY5XHU4QzYxXHU1MjFEXHU1OUNCXHU1MzE2XHU4OUUzXHU2NzkwXHU1NjY4In0sCi0KLSAgICB7IEVSX0VYQ0VQVElPTl9DUkVBVElOR19QT09MLAotICAgICAgICJcdTRFM0FcdTZDNjBcdTUyMUJcdTVFRkFcdTY1QjBcdTVCOUVcdTRGOEJcdTY1RjZcdTUxRkFcdTczQjBcdTVGMDJcdTVFMzhcdTk1MTlcdThCRUYifSwKLQotICAgIHsgRVJfUEFUSF9DT05UQUlOU19JTlZBTElEX0VTQ0FQRV9TRVFVRU5DRSwKLSAgICAgICAiXHU4REVGXHU1Rjg0XHU1MzA1XHU1NDJCXHU2NUUwXHU2NTQ4XHU3Njg0XHU4RjZDXHU0RTQ5XHU1RThGXHU1MjE3In0sCi0KLSAgICB7IEVSX1NDSEVNRV9SRVFVSVJFRCwKLSAgICAgICAiXHU2NUI5XHU2ODQ4XHU2NjJGXHU1RkM1XHU5NzAwXHU3Njg0ISJ9LAotCi0gICAgeyBFUl9OT19TQ0hFTUVfSU5fVVJJLAotICAgICAgICJcdTU3MjggVVJJIFx1NEUyRFx1NjI3RVx1NEUwRFx1NTIzMFx1NjVCOVx1Njg0ODogezB9In0sCi0KLSAgICB7IEVSX05PX1NDSEVNRV9JTlVSSSwKLSAgICAgICAiXHU1NzI4IFVSSSBcdTRFMkRcdTYyN0VcdTRFMERcdTUyMzBcdTY1QjlcdTY4NDgifSwKLQotICAgIHsgRVJfUEFUSF9JTlZBTElEX0NIQVIsCi0gICAgICAgIlx1OERFRlx1NUY4NFx1NTMwNVx1NTQyQlx1NjVFMFx1NjU0OFx1NzY4NFx1NUI1N1x1N0IyNjogezB9In0sCi0KLSAgICB7IEVSX1NDSEVNRV9GUk9NX05VTExfU1RSSU5HLAotICAgICAgICJcdTY1RTBcdTZDRDVcdTRFQ0VcdTdBN0FcdTVCNTdcdTdCMjZcdTRFMzJcdThCQkVcdTdGNkVcdTY1QjlcdTY4NDgifSwKLQotICAgIHsgRVJfU0NIRU1FX05PVF9DT05GT1JNQU5ULAotICAgICAgICJcdTY1QjlcdTY4NDhcdTRFMERcdTRFMDBcdTgxRjRcdTMwMDIifSwKLQotICAgIHsgRVJfSE9TVF9BRERSRVNTX05PVF9XRUxMRk9STUVELAotICAgICAgICJcdTRFM0JcdTY3M0FcdTRFMERcdTY2MkZcdTY4M0NcdTVGMEZcdTgyNkZcdTU5N0RcdTc2ODRcdTU3MzBcdTU3NDAifSwKLQotICAgIHsgRVJfUE9SVF9XSEVOX0hPU1RfTlVMTCwKLSAgICAgICAiXHU0RTNCXHU2NzNBXHU0RTNBXHU3QTdBXHU2NUY2LCBcdTY1RTBcdTZDRDVcdThCQkVcdTdGNkVcdTdBRUZcdTUzRTMifSwKLQotICAgIHsgRVJfSU5WQUxJRF9QT1JULAotICAgICAgICJcdTY1RTBcdTY1NDhcdTc2ODRcdTdBRUZcdTUzRTNcdTUzRjcifSwKLQotICAgIHsgRVJfRlJBR19GT1JfR0VORVJJQ19VUkksCi0gICAgICAgIlx1NTNFQVx1ODBGRFx1NEUzQVx1NEUwMFx1ODIyQyBVUkkgXHU4QkJFXHU3RjZFXHU3MjQ3XHU2QkI1In0sCi0KLSAgICB7IEVSX0ZSQUdfV0hFTl9QQVRIX05VTEwsCi0gICAgICAgIlx1OERFRlx1NUY4NFx1NEUzQVx1N0E3QVx1NjVGNiwgXHU2NUUwXHU2Q0Q1XHU4QkJFXHU3RjZFXHU3MjQ3XHU2QkI1In0sCi0KLSAgICB7IEVSX0ZSQUdfSU5WQUxJRF9DSEFSLAotICAgICAgICJcdTcyNDdcdTZCQjVcdTUzMDVcdTU0MkJcdTY1RTBcdTY1NDhcdTc2ODRcdTVCNTdcdTdCMjYifSwKLQotICAgIHsgRVJfUEFSU0VSX0lOX1VTRSwKLSAgICAgICJcdTg5RTNcdTY3OTBcdTU2NjhcdTVERjJcdTU3MjhcdTRGN0ZcdTc1MjgifSwKLQotICAgIHsgRVJfQ0FOTk9UX0NIQU5HRV9XSElMRV9QQVJTSU5HLAotICAgICAgIlx1NjVFMFx1NkNENVx1NTcyOFx1ODlFM1x1Njc5MFx1NjVGNlx1NjZGNFx1NjUzOXswfSB7MX0ifSwKLQotICAgIHsgRVJfU0VMRl9DQVVTQVRJT05fTk9UX1BFUk1JVFRFRCwKLSAgICAgICJcdTRFMERcdTUxNDFcdThCQjhcdTRGN0ZcdTc1MjhcdTgxRUFcdTU2RTAifSwKLQotICAgIHsgRVJfTk9fVVNFUklORk9fSUZfTk9fSE9TVCwKLSAgICAgICJcdTU5ODJcdTY3OUNcdTZDQTFcdTY3MDlcdTYzMDdcdTVCOUFcdTRFM0JcdTY3M0EsIFx1NTIxOVx1NEUwRFx1NTNFRlx1NEVFNVx1NjMwN1x1NUI5QSBVc2VyaW5mbyJ9LAotCi0gICAgeyBFUl9OT19QT1JUX0lGX05PX0hPU1QsCi0gICAgICAiXHU1OTgyXHU2NzlDXHU2Q0ExXHU2NzA5XHU2MzA3XHU1QjlBXHU0RTNCXHU2NzNBLCBcdTUyMTlcdTRFMERcdTUzRUZcdTRFRTVcdTYzMDdcdTVCOUFcdTdBRUZcdTUzRTMifSwKLQotICAgIHsgRVJfTk9fUVVFUllfU1RSSU5HX0lOX1BBVEgsCi0gICAgICAiXHU4REVGXHU1Rjg0XHU1NDhDXHU2N0U1XHU4QkUyXHU1QjU3XHU3QjI2XHU0RTMyXHU0RTJEXHU0RTBEXHU4MEZEXHU2MzA3XHU1QjlBXHU2N0U1XHU4QkUyXHU1QjU3XHU3QjI2XHU0RTMyIn0sCi0KLSAgICB7IEVSX05PX0ZSQUdNRU5UX1NUUklOR19JTl9QQVRILAotICAgICAgIlx1OERFRlx1NUY4NFx1NTQ4Q1x1NzI0N1x1NkJCNVx1NEUyRFx1OTBGRFx1NjVFMFx1NkNENVx1NjMwN1x1NUI5QVx1NzI0N1x1NkJCNSJ9LAotCi0gICAgeyBFUl9DQU5OT1RfSU5JVF9VUklfRU1QVFlfUEFSTVMsCi0gICAgICAiXHU2NUUwXHU2Q0Q1XHU0RUU1XHU3QTdBXHU1M0MyXHU2NTcwXHU1MjFEXHU1OUNCXHU1MzE2IFVSSSJ9LAotCi0gICAgeyBFUl9NRVRIT0RfTk9UX1NVUFBPUlRFRCwKLSAgICAgICJcdTVDMUFcdTRFMERcdTY1MkZcdTYzMDFcdThCRTVcdTY1QjlcdTZDRDUgIn0sCi0KLSAgICB7IEVSX0lOQ1JTQVhTUkNGSUxURVJfTk9UX1JFU1RBUlRBQkxFLAotICAgICAgIlx1NUY1M1x1NTI0RFx1NjVFMFx1NkNENVx1OTFDRFx1NjVCMFx1NTQyRlx1NTJBOCBJbmNyZW1lbnRhbFNBWFNvdXJjZV9GaWx0ZXIifSwKLQotICAgIHsgRVJfWE1MUkRSX05PVF9CRUZPUkVfU1RBUlRQQVJTRSwKLSAgICAgICJYTUxSZWFkZXIgXHU0RTBEXHU1NzI4IHN0YXJ0UGFyc2UgXHU4QkY3XHU2QzQyXHU0RTRCXHU1MjREIn0sCi0KLSAgICB7IEVSX0FYSVNfVFJBVkVSU0VSX05PVF9TVVBQT1JURUQsCi0gICAgICAiXHU0RTBEXHU2NTJGXHU2MzAxXHU4Rjc0XHU5MDREXHU1Mzg2XHU3QTBCXHU1RThGOiB7MH0ifSwKLQotICAgIHsgRVJfRVJST1JIQU5ETEVSX0NSRUFURURfV0lUSF9OVUxMX1BSSU5UV1JJVEVSLAotICAgICAgIlx1NEY3Rlx1NzUyOFx1N0E3QSBQcmludFdyaXRlciBcdTUyMUJcdTVFRkFcdTRFODYgTGlzdGluZ0Vycm9ySGFuZGxlciEifSwKLQotICAgIHsgRVJfU1lTVEVNSURfVU5LTk9XTiwKLSAgICAgICJTeXN0ZW1JZCBcdTY3MkFcdTc3RTUifSwKLQotICAgIHsgRVJfTE9DQVRJT05fVU5LTk9XTiwKLSAgICAgICJcdTk1MTlcdThCRUZcdTYyNDBcdTU3MjhcdTc2ODRcdTRGNERcdTdGNkVcdTY3MkFcdTc3RTUifSwKLQotICAgIHsgRVJfUFJFRklYX01VU1RfUkVTT0xWRSwKLSAgICAgICJcdTUyNERcdTdGMDBcdTVGQzVcdTk4N0JcdTg5RTNcdTY3OTBcdTRFM0FcdTU0MERcdTc5RjBcdTdBN0FcdTk1RjQ6IHswfSJ9LAotCi0gICAgeyBFUl9DUkVBVEVET0NVTUVOVF9OT1RfU1VQUE9SVEVELAotICAgICAgIlhQYXRoQ29udGV4dCBcdTRFMkRcdTRFMERcdTY1MkZcdTYzMDEgY3JlYXRlRG9jdW1lbnQoKSEifSwKLQotICAgIHsgRVJfQ0hJTERfSEFTX05PX09XTkVSX0RPQ1VNRU5ULAotICAgICAgIlx1NUM1RVx1NjAyN1x1NUI1MFx1N0VBN1x1NkNBMVx1NjcwOVx1NjI0MFx1NjcwOVx1ODAwNVx1NjU4N1x1Njg2MyEifSwKLQotICAgIHsgRVJfQ0hJTERfSEFTX05PX09XTkVSX0RPQ1VNRU5UX0VMRU1FTlQsCi0gICAgICAiXHU1QzVFXHU2MDI3XHU1QjUwXHU3RUE3XHU2Q0ExXHU2NzA5XHU2MjQwXHU2NzA5XHU4MDA1XHU2NTg3XHU2ODYzXHU1MTQzXHU3RDIwISJ9LAotCi0gICAgeyBFUl9DQU5UX09VVFBVVF9URVhUX0JFRk9SRV9ET0MsCi0gICAgICAiXHU4QjY2XHU1NDRBOiBcdTY1RTBcdTZDRDVcdThGOTNcdTUxRkFcdTY1ODdcdTY4NjNcdTUxNDNcdTdEMjBcdTRFNEJcdTUyNERcdTc2ODRcdTY1ODdcdTY3MkMhIFx1NUMwNlx1NUZGRFx1NzU2NS4uLiJ9LAotCi0gICAgeyBFUl9DQU5UX0hBVkVfTU9SRV9USEFOX09ORV9ST09ULAotICAgICAgIkRPTSBcdTRFMEFcdTRFMERcdTgwRkRcdTY3MDlcdTU5MUFcdTRFMkFcdTY4MzkhIn0sCi0KLSAgICB7IEVSX0FSR19MT0NBTE5BTUVfTlVMTCwKLSAgICAgICAiXHU1M0MyXHU2NTcwICdsb2NhbE5hbWUnIFx1NEUzQVx1N0E3QVx1NTAzQyJ9LAotCi0gICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIEEgUU5BTUUgaGFzIHRoZSBzeW50YWN0aWMgZm9ybSBbTkNOYW1lOl1OQ05hbWUKLSAgICAvLyBUaGUgbG9jYWxuYW1lIGlzIHRoZSBwb3J0aW9uIGFmdGVyIHRoZSBvcHRpb25hbCBjb2xvbjsgdGhlIG1lc3NhZ2UgaW5kaWNhdGVzCi0gICAgLy8gdGhhdCB0aGVyZSBpcyBhIHByb2JsZW0gd2l0aCB0aGF0IHBhcnQgb2YgdGhlIFFOQU1FLgotICAgIHsgRVJfQVJHX0xPQ0FMTkFNRV9JTlZBTElELAotICAgICAgICJRTkFNRSBcdTRFMkRcdTc2ODRcdTY3MkNcdTU3MzBcdTU0MERcdTc5RjBcdTVFOTRcdTRFM0FcdTY3MDlcdTY1NDggTkNOYW1lIn0sCi0KLSAgICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQSBRTkFNRSBoYXMgdGhlIHN5bnRhY3RpYyBmb3JtIFtOQ05hbWU6XU5DTmFtZQotICAgIC8vIFRoZSBwcmVmaXggaXMgdGhlIHBvcnRpb24gYmVmb3JlIHRoZSBvcHRpb25hbCBjb2xvbjsgdGhlIG1lc3NhZ2UgaW5kaWNhdGVzCi0gICAgLy8gdGhhdCB0aGVyZSBpcyBhIHByb2JsZW0gd2l0aCB0aGF0IHBhcnQgb2YgdGhlIFFOQU1FLgotICAgIHsgRVJfQVJHX1BSRUZJWF9JTlZBTElELAotICAgICAgICJRTkFNRSBcdTRFMkRcdTc2ODRcdTUyNERcdTdGMDBcdTVFOTRcdTRFM0FcdTY3MDlcdTY1NDggTkNOYW1lIn0sCi0KLSAgICB7IEVSX05BTUVfQ0FOVF9TVEFSVF9XSVRIX0NPTE9OLAotICAgICAgIlx1NTQwRFx1NzlGMFx1NEUwRFx1ODBGRFx1NEVFNVx1NTE5Mlx1NTNGN1x1NUYwMFx1NTkzNCJ9LAotCi0gICAgeyAiQkFEX0NPREUiLCAiY3JlYXRlTWVzc2FnZSBcdTc2ODRcdTUzQzJcdTY1NzBcdThEODVcdTUxRkFcdTgzMDNcdTU2RjQifSwKLSAgICB7ICJGT1JNQVRfRkFJTEVEIiwgIlx1OEMwM1x1NzUyOCBtZXNzYWdlRm9ybWF0IFx1NjVGNlx1NjI5Qlx1NTFGQVx1NUYwMlx1NUUzOFx1OTUxOVx1OEJFRiJ9LAotICAgIHsgImxpbmUiLCAiXHU4ODRDXHU1M0Y3In0sCi0gICAgeyAiY29sdW1uIiwiXHU1MjE3XHU1M0Y3In0sCi0KLSAgICB7RVJfU0VSSUFMSVpFUl9OT1RfQ09OVEVOVEhBTkRMRVIsCi0gICAgICAiXHU0RTMyXHU4ODRDXHU1NjY4XHU3QzdCICcnezB9JycgXHU0RTBEXHU1QjlFXHU3M0IwIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyXHUzMDAyIn0sCi0KLSAgICB7RVJfUkVTT1VSQ0VfQ09VTERfTk9UX0ZJTkQsCi0gICAgICAiXHU2MjdFXHU0RTBEXHU1MjMwXHU4RDQ0XHU2RTkwIFsgezB9IF1cdTMwMDJcbiB7MX0iIH0sCi0KLSAgICB7RVJfUkVTT1VSQ0VfQ09VTERfTk9UX0xPQUQsCi0gICAgICAiXHU4RDQ0XHU2RTkwIFsgezB9IF0gXHU2NUUwXHU2Q0Q1XHU1MkEwXHU4RjdEOiB7MX0gXG4gezJ9IFx0IHszfSIgfSwKLQotICAgIHtFUl9CVUZGRVJfU0laRV9MRVNTVEhBTl9aRVJPLAotICAgICAgIlx1N0YxM1x1NTFCMlx1NTMzQVx1NTkyN1x1NUMwRiA8PTAiIH0sCi0KLSAgICB7RVJfSU5WQUxJRF9VVEYxNl9TVVJST0dBVEUsCi0gICAgICAiXHU2OEMwXHU2RDRCXHU1MjMwXHU2NUUwXHU2NTQ4XHU3Njg0IFVURi0xNiBcdTRFRTNcdTc0MDY6IHswfT8iIH0sCi0KLSAgICB7RVJfT0lFUlJPUiwKLSAgICAgICJJTyBcdTk1MTlcdThCRUYiIH0sCi0KLSAgICB7RVJfSUxMRUdBTF9BVFRSSUJVVEVfUE9TSVRJT04sCi0gICAgICAiXHU1NzI4XHU3NTFGXHU2MjEwXHU1QjUwXHU4MjgyXHU3MEI5XHU0RTRCXHU1NDBFXHU2MjE2XHU1NzI4XHU3NTFGXHU2MjEwXHU1MTQzXHU3RDIwXHU0RTRCXHU1MjREXHU2NUUwXHU2Q0Q1XHU2REZCXHU1MkEwXHU1QzVFXHU2MDI3IHswfVx1MzAwMlx1NUMwNlx1NUZGRFx1NzU2NVx1NUM1RVx1NjAyN1x1MzAwMiJ9LAotCi0gICAgICAvKgotICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IGNvbnRhaW5lZCBhIHJlZmVyZW5jZSB0byBhCi0gICAgICAgKiBuYW1lc3BhY2UgcHJlZml4IHRoYXQgd2FzIHVuZGVmaW5lZC4gIFRoZSB2YWx1ZSBvZiB0aGUgc3Vic3RpdHV0aW9uCi0gICAgICAgKiB0ZXh0IGlzIHRoZSBuYW1lIG9mIHRoZSBwcmVmaXguCi0gICAgICAgKi8KLSAgICB7RVJfTkFNRVNQQUNFX1BSRUZJWCwKLSAgICAgICJcdTZDQTFcdTY3MDlcdThCRjRcdTY2MEVcdTU0MERcdTc5RjBcdTdBN0FcdTk1RjRcdTUyNERcdTdGMDAgJyd7MH0nJ1x1MzAwMiIgfSwKLSAgICAgIC8qCi0gICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIHJlcG9ydGVkIGlmIHRoZSBzdHlsZXNoZWV0Ci0gICAgICAgKiBiZWluZyBwcm9jZXNzZWQgYXR0ZW1wdGVkIHRvIGNvbnN0cnVjdCBhbiBYTUwgZG9jdW1lbnQgd2l0aCBhbgotICAgICAgICogYXR0cmlidXRlIGluIGEgcGxhY2Ugb3RoZXIgdGhhbiBvbiBhbiBlbGVtZW50LiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgKiBzcGVjaWZpZXMgdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgICAqLwotICAgIHtFUl9TVFJBWV9BVFRSSUJVVEUsCi0gICAgICAiXHU1QzVFXHU2MDI3ICcnezB9JycgXHU1NzI4XHU1MTQzXHU3RDIwXHU1OTE2XHU5MEU4XHUzMDAyIiB9LAotCi0gICAgICAvKgotICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFzIHdpdGggdGhlIHByZWNlZGluZyBtZXNzYWdlLCBhIG5hbWVzcGFjZQotICAgICAgICogZGVjbGFyYXRpb24gaGFzIHRoZSBmb3JtIG9mIGFuIGF0dHJpYnV0ZSBhbmQgaXMgb25seSBwZXJtaXR0ZWQgdG8KLSAgICAgICAqIGFwcGVhciBvbiBhbiBlbGVtZW50LiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHswfSBpcyB0aGUgbmFtZXNwYWNlCi0gICAgICAgKiBwcmVmaXggYW5kIHsxfSBpcyB0aGUgVVJJIHRoYXQgd2FzIGJlaW5nIHVzZWQgaW4gdGhlIGVycm9uZW91cwotICAgICAgICogbmFtZXNwYWNlIGRlY2xhcmF0aW9uLgotICAgICAgICovCi0gICAge0VSX1NUUkFZX05BTUVTUEFDRSwKLSAgICAgICJcdTU0MERcdTc5RjBcdTdBN0FcdTk1RjRcdTU4RjBcdTY2MEUgJyd7MH0nJz0nJ3sxfScnIFx1NTcyOFx1NTE0M1x1N0QyMFx1NTkxNlx1OTBFOFx1MzAwMiIgfSwKLQotICAgIHtFUl9DT1VMRF9OT1RfTE9BRF9SRVNPVVJDRSwKLSAgICAgICJcdTY1RTBcdTZDRDVcdTUyQTBcdThGN0QgJyd7MH0nJyAoXHU2OEMwXHU2N0U1IENMQVNTUEFUSCksIFx1NzNCMFx1NTcyOFx1NTNFQVx1NEY3Rlx1NzUyOFx1OUVEOFx1OEJBNFx1NTAzQyJ9LAotCi0gICAgeyBFUl9JTExFR0FMX0NIQVJBQ1RFUiwKLSAgICAgICAiXHU1QzFEXHU4QkQ1XHU4RjkzXHU1MUZBXHU2NzJBXHU0RUU1ezF9XHU3Njg0XHU2MzA3XHU1QjlBXHU4RjkzXHU1MUZBXHU3RjE2XHU3ODAxXHU4ODY4XHU3OTNBXHU3Njg0XHU2NTc0XHU2NTcwXHU1MDNDIHswfSBcdTc2ODRcdTVCNTdcdTdCMjZcdTMwMDIifSwKLQotICAgIHtFUl9DT1VMRF9OT1RfTE9BRF9NRVRIT0RfUFJPUEVSVFksCi0gICAgICAiXHU2NUUwXHU2Q0Q1XHU0RTNBXHU4RjkzXHU1MUZBXHU2NUI5XHU2Q0Q1ICcnezF9JycgXHU1MkEwXHU4RjdEXHU1QzVFXHU2MDI3XHU2NTg3XHU0RUY2ICcnezB9JycgKFx1NjhDMFx1NjdFNSBDTEFTU1BBVEgpIiB9Ci0KLQotICB9OwotCi0gIC8qKgotICAgKiBHZXQgdGhlIGFzc29jaWF0aW9uIGxpc3QuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGFzc29jaWF0aW9uIGxpc3QuCi0gICAqLwotCi0gICAgcHJvdGVjdGVkIE9iamVjdFtdW10gZ2V0Q29udGVudHMoKSB7Ci0gICAgICAgIHJldHVybiBjb250ZW50czsKLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3Jlcy9YTUxFcnJvclJlc291cmNlc196aF9ISy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvcmVzL1hNTEVycm9yUmVzb3VyY2VzX3poX0hLLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDFhMGQxNGEuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvcmVzL1hNTEVycm9yUmVzb3VyY2VzX3poX0hLLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3NyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5LTIwMDMgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXM7Ci0KLS8qKgotICogU2V0IHVwIGVycm9yIG1lc3NhZ2VzLgotICogV2UgYnVpbGQgYSB0d28gZGltZW5zaW9uYWwgYXJyYXkgb2YgbWVzc2FnZSBrZXlzIGFuZAotICogbWVzc2FnZSBzdHJpbmdzLiBJbiBvcmRlciB0byBhZGQgYSBuZXcgbWVzc2FnZSBoZXJlLAotICogeW91IG5lZWQgdG8gZmlyc3QgYWRkIGEgU3RyaW5nIGNvbnN0YW50LiBBbmQgeW91IG5lZWQKLSAqIHRvIGVudGVyIGtleSwgdmFsdWUgcGFpciBhcyBwYXJ0IG9mIHRoZSBjb250ZW50cwotICogYXJyYXkuIFlvdSBhbHNvIG5lZWQgdG8gdXBkYXRlIE1BWF9DT0RFIGZvciBlcnJvciBzdHJpbmdzCi0gKiBhbmQgTUFYX1dBUk5JTkcgZm9yIHdhcm5pbmdzICggTmVlZGVkIGZvciBvbmx5IGluZm9ybWF0aW9uCi0gKiBwdXJwb3NlICkKLSAqLwotcHVibGljIGNsYXNzIFhNTEVycm9yUmVzb3VyY2VzX3poX0hLIGV4dGVuZHMgWE1MRXJyb3JSZXNvdXJjZXNfemhfVFcKLXsKLQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9yZXMvWE1MRXJyb3JSZXNvdXJjZXNfemhfVFcuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3Jlcy9YTUxFcnJvclJlc291cmNlc196aF9UVy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlMWQxOTc2Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3Jlcy9YTUxFcnJvclJlc291cmNlc196aF9UVy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDUwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXM7Ci0KLQotaW1wb3J0IGphdmEudXRpbC5MaXN0UmVzb3VyY2VCdW5kbGU7Ci0KLS8qKgotICogU2V0IHVwIGVycm9yIG1lc3NhZ2VzLgotICogV2UgYnVpbGQgYSB0d28gZGltZW5zaW9uYWwgYXJyYXkgb2YgbWVzc2FnZSBrZXlzIGFuZAotICogbWVzc2FnZSBzdHJpbmdzLiBJbiBvcmRlciB0byBhZGQgYSBuZXcgbWVzc2FnZSBoZXJlLAotICogeW91IG5lZWQgdG8gZmlyc3QgYWRkIGEgU3RyaW5nIGNvbnN0YW50LiBBbmQgeW91IG5lZWQKLSAqIHRvIGVudGVyIGtleSwgdmFsdWUgcGFpciBhcyBwYXJ0IG9mIHRoZSBjb250ZW50cwotICogYXJyYXkuIFlvdSBhbHNvIG5lZWQgdG8gdXBkYXRlIE1BWF9DT0RFIGZvciBlcnJvciBzdHJpbmdzCi0gKiBhbmQgTUFYX1dBUk5JTkcgZm9yIHdhcm5pbmdzICggTmVlZGVkIGZvciBvbmx5IGluZm9ybWF0aW9uCi0gKiBwdXJwb3NlICkKLSAqLwotcHVibGljIGNsYXNzIFhNTEVycm9yUmVzb3VyY2VzX3poX1RXIGV4dGVuZHMgTGlzdFJlc291cmNlQnVuZGxlCi17Ci0KLS8qCi0gKiBUaGlzIGZpbGUgY29udGFpbnMgZXJyb3IgYW5kIHdhcm5pbmcgbWVzc2FnZXMgcmVsYXRlZCB0byBYYWxhbiBFcnJvcgotICogSGFuZGxpbmcuCi0gKgotICogIEdlbmVyYWwgbm90ZXMgdG8gdHJhbnNsYXRvcnM6Ci0gKgotICogIDEpIFhhbGFuIChvciBtb3JlIHByb3Blcmx5LCBYYWxhbi1pbnRlcnByZXRpdmUpIGFuZCBYU0xUQyBhcmUgbmFtZXMgb2YKLSAqICAgICBjb21wb25lbnRzLgotICogICAgIFhTTFQgaXMgYW4gYWNyb255bSBmb3IgIlhNTCBTdHlsZXNoZWV0IExhbmd1YWdlOiBUcmFuc2Zvcm1hdGlvbnMiLgotICogICAgIFhTTFRDIGlzIGFuIGFjcm9ueW0gZm9yIFhTTFQgQ29tcGlsZXIuCi0gKgotICogIDIpIEEgc3R5bGVzaGVldCBpcyBhIGRlc2NyaXB0aW9uIG9mIGhvdyB0byB0cmFuc2Zvcm0gYW4gaW5wdXQgWE1MIGRvY3VtZW50Ci0gKiAgICAgaW50byBhIHJlc3VsdGFudCBYTUwgZG9jdW1lbnQgKG9yIEhUTUwgZG9jdW1lbnQgb3IgdGV4dCkuICBUaGUKLSAqICAgICBzdHlsZXNoZWV0IGl0c2VsZiBpcyBkZXNjcmliZWQgaW4gdGhlIGZvcm0gb2YgYW4gWE1MIGRvY3VtZW50LgotICoKLSAqICAzKSBBIHRlbXBsYXRlIGlzIGEgY29tcG9uZW50IG9mIGEgc3R5bGVzaGVldCB0aGF0IGlzIHVzZWQgdG8gbWF0Y2ggYQotICogICAgIHBhcnRpY3VsYXIgcG9ydGlvbiBvZiBhbiBpbnB1dCBkb2N1bWVudCBhbmQgc3BlY2lmaWVzIHRoZSBmb3JtIG9mIHRoZQotICogICAgIGNvcnJlc3BvbmRpbmcgcG9ydGlvbiBvZiB0aGUgb3V0cHV0IGRvY3VtZW50LgotICoKLSAqICA0KSBBbiBlbGVtZW50IGlzIGEgbWFyay11cCB0YWcgaW4gYW4gWE1MIGRvY3VtZW50OyBhbiBhdHRyaWJ1dGUgaXMgYQotICogICAgIG1vZGlmaWVyIG9uIHRoZSB0YWcuICBGb3IgZXhhbXBsZSwgaW4gPGVsZW0gYXR0cj0ndmFsJyBhdHRyMj0ndmFsMic+Ci0gKiAgICAgImVsZW0iIGlzIGFuIGVsZW1lbnQgbmFtZSwgImF0dHIiIGFuZCAiYXR0cjIiIGFyZSBhdHRyaWJ1dGUgbmFtZXMgd2l0aAotICogICAgIHRoZSB2YWx1ZXMgInZhbCIgYW5kICJ2YWwyIiwgcmVzcGVjdGl2ZWx5LgotICoKLSAqICA1KSBBIG5hbWVzcGFjZSBkZWNsYXJhdGlvbiBpcyBhIHNwZWNpYWwgYXR0cmlidXRlIHRoYXQgaXMgdXNlZCB0byBhc3NvY2lhdGUKLSAqICAgICBhIHByZWZpeCB3aXRoIGEgVVJJICh0aGUgbmFtZXNwYWNlKS4gIFRoZSBtZWFuaW5ncyBvZiBlbGVtZW50IG5hbWVzIGFuZAotICogICAgIGF0dHJpYnV0ZSBuYW1lcyB0aGF0IHVzZSB0aGF0IHByZWZpeCBhcmUgZGVmaW5lZCB3aXRoIHJlc3BlY3QgdG8gdGhhdAotICogICAgIG5hbWVzcGFjZS4KLSAqCi0gKiAgNikgIlRyYW5zbGV0IiBpcyBhbiBpbnZlbnRlZCB0ZXJtIHRoYXQgZGVzY3JpYmVzIHRoZSBjbGFzcyBmaWxlIHRoYXQKLSAqICAgICByZXN1bHRzIGZyb20gY29tcGlsaW5nIGFuIFhNTCBzdHlsZXNoZWV0IGludG8gYSBKYXZhIGNsYXNzLgotICoKLSAqICA3KSBYUGF0aCBpcyBhIHNwZWNpZmljYXRpb24gdGhhdCBkZXNjcmliZXMgYSBub3RhdGlvbiBmb3IgaWRlbnRpZnlpbmcKLSAqICAgICBub2RlcyBpbiBhIHRyZWUtc3RydWN0dXJlZCByZXByZXNlbnRhdGlvbiBvZiBhbiBYTUwgZG9jdW1lbnQuICBBbgotICogICAgIGluc3RhbmNlIG9mIHRoYXQgbm90YXRpb24gaXMgcmVmZXJyZWQgdG8gYXMgYW4gWFBhdGggZXhwcmVzc2lvbi4KLSAqCi0gKi8KLQotICAvKiogTWF4aW11bSBlcnJvciBtZXNzYWdlcywgdGhpcyBpcyBuZWVkZWQgdG8ga2VlcCB0cmFjayBvZiB0aGUgbnVtYmVyIG9mIG1lc3NhZ2VzLiAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVhfQ09ERSA9IDYxOwotCi0gIC8qKiBNYXhpbXVtIHdhcm5pbmdzLCB0aGlzIGlzIG5lZWRlZCB0byBrZWVwIHRyYWNrIG9mIHRoZSBudW1iZXIgb2Ygd2FybmluZ3MuICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BWF9XQVJOSU5HID0gMDsKLQotICAvKiogTWF4aW11bSBtaXNjIHN0cmluZ3MuICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFYX09USEVSUyA9IDQ7Ci0KLSAgLyoqIE1heGltdW0gdG90YWwgd2FybmluZ3MgYW5kIGVycm9yIG1lc3NhZ2VzLiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVhfTUVTU0FHRVMgPSBNQVhfQ09ERSArIE1BWF9XQVJOSU5HICsgMTsKLQotCi0gIC8qCi0gICAqIE1lc3NhZ2Uga2V5cwotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCA9ICJFUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX09WRVJXUklURV9DQVVTRSA9ICJFUl9DQU5OT1RfT1ZFUldSSVRFX0NBVVNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fREVGQVVMVF9JTVBMID0gIkVSX05PX0RFRkFVTFRfSU1QTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NIVU5LRURJTlRBUlJBWV9OT1RfU1VQUE9SVEVEID0gIkVSX0NIVU5LRURJTlRBUlJBWV9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfT0ZGU0VUX0JJR0dFUl9USEFOX1NMT1QgPSAiRVJfT0ZGU0VUX0JJR0dFUl9USEFOX1NMT1QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1JPVVRJTkVfTk9UX0FWQUlMID0gIkVSX0NPUk9VVElORV9OT1RfQVZBSUwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1JPVVRJTkVfQ09fRVhJVCA9ICJFUl9DT1JPVVRJTkVfQ09fRVhJVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPSk9JTlJPVVRJTkVTRVRfRkFJTEVEID0gIkVSX0NPSk9JTlJPVVRJTkVTRVRfRkFJTEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09ST1VUSU5FX1BBUkFNID0gIkVSX0NPUk9VVElORV9QQVJBTSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BBUlNFUl9ET1RFUk1JTkFURV9BTlNXRVJTID0gIkVSX1BBUlNFUl9ET1RFUk1JTkFURV9BTlNXRVJTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fUEFSU0VfQ0FMTF9XSElMRV9QQVJTSU5HID0gIkVSX05PX1BBUlNFX0NBTExfV0hJTEVfUEFSU0lORyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1RZUEVEX0lURVJBVE9SX0FYSVNfTk9UX0lNUExFTUVOVEVEID0gIkVSX1RZUEVEX0lURVJBVE9SX0FYSVNfTk9UX0lNUExFTUVOVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSVRFUkFUT1JfQVhJU19OT1RfSU1QTEVNRU5URUQgPSAiRVJfSVRFUkFUT1JfQVhJU19OT1RfSU1QTEVNRU5URUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JVEVSQVRPUl9DTE9ORV9OT1RfU1VQUE9SVEVEID0gIkVSX0lURVJBVE9SX0NMT05FX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTktOT1dOX0FYSVNfVFlQRSA9ICJFUl9VTktOT1dOX0FYSVNfVFlQRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FYSVNfTk9UX1NVUFBPUlRFRCA9ICJFUl9BWElTX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19EVE1JRFNfQVZBSUwgPSAiRVJfTk9fRFRNSURTX0FWQUlMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9UX1NVUFBPUlRFRCA9ICJFUl9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9ERV9OT05fTlVMTCA9ICJFUl9OT0RFX05PTl9OVUxMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTERfTk9UX1JFU09MVkVfTk9ERSA9ICJFUl9DT1VMRF9OT1RfUkVTT0xWRV9OT0RFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU1RBUlRQQVJTRV9XSElMRV9QQVJTSU5HID0gIkVSX1NUQVJUUEFSU0VfV0hJTEVfUEFSU0lORyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NUQVJUUEFSU0VfTkVFRFNfU0FYUEFSU0VSID0gIkVSX1NUQVJUUEFSU0VfTkVFRFNfU0FYUEFSU0VSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTERfTk9UX0lOSVRfUEFSU0VSID0gIkVSX0NPVUxEX05PVF9JTklUX1BBUlNFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYQ0VQVElPTl9DUkVBVElOR19QT09MID0gIkVSX0VYQ0VQVElPTl9DUkVBVElOR19QT09MIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUEFUSF9DT05UQUlOU19JTlZBTElEX0VTQ0FQRV9TRVFVRU5DRSA9ICJFUl9QQVRIX0NPTlRBSU5TX0lOVkFMSURfRVNDQVBFX1NFUVVFTkNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU0NIRU1FX1JFUVVJUkVEID0gIkVSX1NDSEVNRV9SRVFVSVJFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1NDSEVNRV9JTl9VUkkgPSAiRVJfTk9fU0NIRU1FX0lOX1VSSSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1NDSEVNRV9JTlVSSSA9ICJFUl9OT19TQ0hFTUVfSU5VUkkiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QQVRIX0lOVkFMSURfQ0hBUiA9ICJFUl9QQVRIX0lOVkFMSURfQ0hBUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NDSEVNRV9GUk9NX05VTExfU1RSSU5HID0gIkVSX1NDSEVNRV9GUk9NX05VTExfU1RSSU5HIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU0NIRU1FX05PVF9DT05GT1JNQU5UID0gIkVSX1NDSEVNRV9OT1RfQ09ORk9STUFOVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0hPU1RfQUREUkVTU19OT1RfV0VMTEZPUk1FRCA9ICJFUl9IT1NUX0FERFJFU1NfTk9UX1dFTExGT1JNRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QT1JUX1dIRU5fSE9TVF9OVUxMID0gIkVSX1BPUlRfV0hFTl9IT1NUX05VTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX1BPUlQgPSAiRVJfSU5WQUxJRF9QT1JUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRlJBR19GT1JfR0VORVJJQ19VUkkgPSJFUl9GUkFHX0ZPUl9HRU5FUklDX1VSSSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZSQUdfV0hFTl9QQVRIX05VTEwgPSAiRVJfRlJBR19XSEVOX1BBVEhfTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZSQUdfSU5WQUxJRF9DSEFSID0gIkVSX0ZSQUdfSU5WQUxJRF9DSEFSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUEFSU0VSX0lOX1VTRSA9ICJFUl9QQVJTRVJfSU5fVVNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX0NIQU5HRV9XSElMRV9QQVJTSU5HID0gIkVSX0NBTk5PVF9DSEFOR0VfV0hJTEVfUEFSU0lORyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NFTEZfQ0FVU0FUSU9OX05PVF9QRVJNSVRURUQgPSAiRVJfU0VMRl9DQVVTQVRJT05fTk9UX1BFUk1JVFRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1VTRVJJTkZPX0lGX05PX0hPU1QgPSAiRVJfTk9fVVNFUklORk9fSUZfTk9fSE9TVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1BPUlRfSUZfTk9fSE9TVCA9ICJFUl9OT19QT1JUX0lGX05PX0hPU1QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19RVUVSWV9TVFJJTkdfSU5fUEFUSCA9ICJFUl9OT19RVUVSWV9TVFJJTkdfSU5fUEFUSCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX0ZSQUdNRU5UX1NUUklOR19JTl9QQVRIID0gIkVSX05PX0ZSQUdNRU5UX1NUUklOR19JTl9QQVRIIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX0lOSVRfVVJJX0VNUFRZX1BBUk1TID0gIkVSX0NBTk5PVF9JTklUX1VSSV9FTVBUWV9QQVJNUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX01FVEhPRF9OT1RfU1VQUE9SVEVEID0iRVJfTUVUSE9EX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTkNSU0FYU1JDRklMVEVSX05PVF9SRVNUQVJUQUJMRSA9ICJFUl9JTkNSU0FYU1JDRklMVEVSX05PVF9SRVNUQVJUQUJMRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hNTFJEUl9OT1RfQkVGT1JFX1NUQVJUUEFSU0UgPSAiRVJfWE1MUkRSX05PVF9CRUZPUkVfU1RBUlRQQVJTRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FYSVNfVFJBVkVSU0VSX05PVF9TVVBQT1JURUQgPSAiRVJfQVhJU19UUkFWRVJTRVJfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VSUk9SSEFORExFUl9DUkVBVEVEX1dJVEhfTlVMTF9QUklOVFdSSVRFUiA9ICJFUl9FUlJPUkhBTkRMRVJfQ1JFQVRFRF9XSVRIX05VTExfUFJJTlRXUklURVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TWVNURU1JRF9VTktOT1dOID0gIkVSX1NZU1RFTUlEX1VOS05PV04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9MT0NBVElPTl9VTktOT1dOID0gIkVSX0xPQ0FUSU9OX1VOS05PV04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUkVGSVhfTVVTVF9SRVNPTFZFID0gIkVSX1BSRUZJWF9NVVNUX1JFU09MVkUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DUkVBVEVET0NVTUVOVF9OT1RfU1VQUE9SVEVEID0gIkVSX0NSRUFURURPQ1VNRU5UX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DSElMRF9IQVNfTk9fT1dORVJfRE9DVU1FTlQgPSAiRVJfQ0hJTERfSEFTX05PX09XTkVSX0RPQ1VNRU5UIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0hJTERfSEFTX05PX09XTkVSX0RPQ1VNRU5UX0VMRU1FTlQgPSAiRVJfQ0hJTERfSEFTX05PX09XTkVSX0RPQ1VNRU5UX0VMRU1FTlQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX09VVFBVVF9URVhUX0JFRk9SRV9ET0MgPSAiRVJfQ0FOVF9PVVRQVVRfVEVYVF9CRUZPUkVfRE9DIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9IQVZFX01PUkVfVEhBTl9PTkVfUk9PVCA9ICJFUl9DQU5UX0hBVkVfTU9SRV9USEFOX09ORV9ST09UIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQVJHX0xPQ0FMTkFNRV9OVUxMID0gIkVSX0FSR19MT0NBTE5BTUVfTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FSR19MT0NBTE5BTUVfSU5WQUxJRCA9ICJFUl9BUkdfTE9DQUxOQU1FX0lOVkFMSUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9BUkdfUFJFRklYX0lOVkFMSUQgPSAiRVJfQVJHX1BSRUZJWF9JTlZBTElEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTkFNRV9DQU5UX1NUQVJUX1dJVEhfQ09MT04gPSAiRVJfTkFNRV9DQU5UX1NUQVJUX1dJVEhfQ09MT04iOwotCi0gIC8vIE1lc3NhZ2Uga2V5cyB1c2VkIGJ5IHRoZSBzZXJpYWxpemVyCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1JFU09VUkNFX0NPVUxEX05PVF9GSU5EID0gIkVSX1JFU09VUkNFX0NPVUxEX05PVF9GSU5EIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUkVTT1VSQ0VfQ09VTERfTk9UX0xPQUQgPSAiRVJfUkVTT1VSQ0VfQ09VTERfTk9UX0xPQUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9CVUZGRVJfU0laRV9MRVNTVEhBTl9aRVJPID0gIkVSX0JVRkZFUl9TSVpFX0xFU1NUSEFOX1pFUk8iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX1VURjE2X1NVUlJPR0FURSA9ICJFUl9JTlZBTElEX1VURjE2X1NVUlJPR0FURSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX09JRVJST1IgPSAiRVJfT0lFUlJPUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05BTUVTUEFDRV9QUkVGSVggPSAiRVJfTkFNRVNQQUNFX1BSRUZJWCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NUUkFZX0FUVFJJQlVURSA9ICJFUl9TVFJBWV9BVFRJUkJVVEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TVFJBWV9OQU1FU1BBQ0UgPSAiRVJfU1RSQVlfTkFNRVNQQUNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTERfTk9UX0xPQURfUkVTT1VSQ0UgPSAiRVJfQ09VTERfTk9UX0xPQURfUkVTT1VSQ0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRF9OT1RfTE9BRF9NRVRIT0RfUFJPUEVSVFkgPSAiRVJfQ09VTERfTk9UX0xPQURfTUVUSE9EX1BST1BFUlRZIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU0VSSUFMSVpFUl9OT1RfQ09OVEVOVEhBTkRMRVIgPSAiRVJfU0VSSUFMSVpFUl9OT1RfQ09OVEVOVEhBTkRMRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTExFR0FMX0FUVFJJQlVURV9QT1NJVElPTiA9ICJFUl9JTExFR0FMX0FUVFJJQlVURV9QT1NJVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lMTEVHQUxfQ0hBUkFDVEVSID0gIkVSX0lMTEVHQUxfQ0hBUkFDVEVSIjsKLQotICAvKgotICAgKiBOb3cgZmlsbCBpbiB0aGUgbWVzc2FnZSB0ZXh0LgotICAgKiBUaGVuIGZpbGwgaW4gdGhlIG1lc3NhZ2UgdGV4dCBmb3IgdGhhdCBtZXNzYWdlIGNvZGUgaW4gdGhlCi0gICAqIGFycmF5LiBVc2UgdGhlIG5ldyBlcnJvciBjb2RlIGFzIHRoZSBpbmRleCBpbnRvIHRoZSBhcnJheS4KLSAgICovCi0KLSAgLy8gRXJyb3IgbWVzc2FnZXMuLi4KLQotICAvKiogVGhlIGxvb2t1cCB0YWJsZSBmb3IgZXJyb3IgbWVzc2FnZXMuICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgT2JqZWN0W11bXSBjb250ZW50cyA9IHsKLQotICAvKiogRXJyb3IgbWVzc2FnZSBJRCB0aGF0IGhhcyBhIG51bGwgbWVzc2FnZSwgYnV0IHRha2VzIGluIGEgc2luZ2xlIG9iamVjdC4gICAgKi8KLSAgICB7IkVSMDAwMCIgLCAiezB9IiB9LAotCi0gICAgeyBFUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVELAotICAgICAgIlx1NEUwRFx1NjUyRlx1NjNGNFx1NTFGRFx1NjU3OFx1RkYwMSJ9LAotCi0gICAgeyBFUl9DQU5OT1RfT1ZFUldSSVRFX0NBVVNFLAotICAgICAgIlx1NzEyMVx1NkNENVx1ODk4Nlx1NUJFQlx1NTM5Rlx1NTZFMCJ9LAotCi0gICAgeyBFUl9OT19ERUZBVUxUX0lNUEwsCi0gICAgICAiXHU2MjdFXHU0RTBEXHU1MjMwXHU5ODEwXHU4QTJEXHU3Njg0XHU1QkU2XHU4ODRDIn0sCi0KLSAgICB7IEVSX0NIVU5LRURJTlRBUlJBWV9OT1RfU1VQUE9SVEVELAotICAgICAgIlx1NzZFRVx1NTI0RFx1NEUwRFx1NjUyRlx1NjNGNCBDaHVua2VkSW50QXJyYXkoezB9KSJ9LAotCi0gICAgeyBFUl9PRkZTRVRfQklHR0VSX1RIQU5fU0xPVCwKLSAgICAgICJcdTRGNERcdTc5RkJcdTU5MjdcdTY1QkNcdTRGNERcdTdGNkUifSwKLQotICAgIHsgRVJfQ09ST1VUSU5FX05PVF9BVkFJTCwKLSAgICAgICJcdTZDOTJcdTY3MDlcdTUzRUZcdTc1MjhcdTc2ODRcdTUxNzFcdTU0MENcdTVFMzhcdTVGMEZcdUZGMENpZD17MH0ifSwKLQotICAgIHsgRVJfQ09ST1VUSU5FX0NPX0VYSVQsCi0gICAgICAiQ29yb3V0aW5lTWFuYWdlciBcdTY1MzZcdTUyMzAgY29fZXhpdCgpIFx1ODk4MVx1NkM0MiJ9LAotCi0gICAgeyBFUl9DT0pPSU5ST1VUSU5FU0VUX0ZBSUxFRCwKLSAgICAgICJjb19qb2luQ29yb3V0aW5lU2V0KCkgXHU1OTMxXHU2NTU3In0sCi0KLSAgICB7IEVSX0NPUk9VVElORV9QQVJBTSwKLSAgICAgICJcdTUxNzFcdTU0MENcdTVFMzhcdTVGMEZcdTUzQzNcdTY1NzhcdTkzMkZcdThBQTQgKHswfSkifSwKLQotICAgIHsgRVJfUEFSU0VSX0RPVEVSTUlOQVRFX0FOU1dFUlMsCi0gICAgICAiXG5cdTY3MkFcdTk4MTBcdTY3MUY6IFx1NTI1Nlx1Njc5MFx1NTY2OCBkb1Rlcm1pbmF0ZSBcdTdCNTRcdTg5ODYgezB9In0sCi0KLSAgICB7IEVSX05PX1BBUlNFX0NBTExfV0hJTEVfUEFSU0lORywKLSAgICAgICJcdTUyNTZcdTY3OTBcdTY2NDJcdTUzRUZcdTgwRkRcdTY3MkFcdTU0N0NcdTUzRUIgcGFyc2UifSwKLQotICAgIHsgRVJfVFlQRURfSVRFUkFUT1JfQVhJU19OT1RfSU1QTEVNRU5URUQsCi0gICAgICAiXHU5MzJGXHU4QUE0OiBcdTY3MkFcdTVCRTZcdTg4NENcdThFRjggezB9IFx1NzY4NFx1OTg1RVx1NTc4Qlx1OTFDRFx1ODkwN1x1N0EwQlx1NUYwRiJ9LAotCi0gICAgeyBFUl9JVEVSQVRPUl9BWElTX05PVF9JTVBMRU1FTlRFRCwKLSAgICAgICJcdTkzMkZcdThBQTQ6IFx1NjcyQVx1NUJFNlx1ODg0Q1x1OEVGOCB7MH0gXHU3Njg0XHU5MUNEXHU4OTA3XHU3QTBCXHU1RjBGIn0sCi0KLSAgICB7IEVSX0lURVJBVE9SX0NMT05FX05PVF9TVVBQT1JURUQsCi0gICAgICAiXHU0RTBEXHU2NTJGXHU2M0Y0XHU5MUNEXHU4OTA3XHU3QTBCXHU1RjBGXHU4OTA3XHU4OEZEIn0sCi0KLSAgICB7IEVSX1VOS05PV05fQVhJU19UWVBFLAotICAgICAgIlx1NEUwRFx1NjYwRVx1NzY4NFx1OEVGOFx1NTQ2OFx1OTA0QVx1OTg1RVx1NTc4QjogezB9In0sCi0KLSAgICB7IEVSX0FYSVNfTk9UX1NVUFBPUlRFRCwKLSAgICAgICJcdTRFMERcdTY1MkZcdTYzRjRcdThFRjhcdTU0NjhcdTkwNEFcdTdBMEJcdTVGMEY6IHswfSJ9LAotCi0gICAgeyBFUl9OT19EVE1JRFNfQVZBSUwsCi0gICAgICAiXHU0RTBEXHU1MThEXHU2NzA5XHU1M0VGXHU3NTI4XHU3Njg0IERUTSBJRCJ9LAotCi0gICAgeyBFUl9OT1RfU1VQUE9SVEVELAotICAgICAgIlx1NEUwRFx1NjUyRlx1NjNGNDogezB9In0sCi0KLSAgICB7IEVSX05PREVfTk9OX05VTEwsCi0gICAgICAiXHU3QkMwXHU5RURFXHU1RkM1XHU5ODA4XHU2NjJGXHU5NzVFXHU3QTdBXHU1MDNDXHU3Njg0IGdldERUTUhhbmRsZUZyb21Ob2RlIn0sCi0KLSAgICB7IEVSX0NPVUxEX05PVF9SRVNPTFZFX05PREUsCi0gICAgICAiXHU3MTIxXHU2Q0Q1XHU4OUUzXHU2NzkwXHU3QkMwXHU5RURFXHU3MEJBXHU2M0E3XHU1MjM2XHU0RUUzXHU3OEJDIn0sCi0KLSAgICB7IEVSX1NUQVJUUEFSU0VfV0hJTEVfUEFSU0lORywKLSAgICAgICAiXHU1MjU2XHU2NzkwXHU2NjQyXHU1M0VGXHU4MEZEXHU2NzJBXHU1NDdDXHU1M0VCIHN0YXJ0UGFyc2UifSwKLQotICAgIHsgRVJfU1RBUlRQQVJTRV9ORUVEU19TQVhQQVJTRVIsCi0gICAgICAgInN0YXJ0UGFyc2UgXHU5NzAwXHU4OTgxXHU5NzVFXHU3QTdBXHU1MDNDIFNBWFBhcnNlciJ9LAotCi0gICAgeyBFUl9DT1VMRF9OT1RfSU5JVF9QQVJTRVIsCi0gICAgICAgIlx1NzEyMVx1NkNENVx1OEQ3N1x1NTlDQlx1NTI1Nlx1Njc5MFx1NTY2OCJ9LAotCi0gICAgeyBFUl9FWENFUFRJT05fQ1JFQVRJTkdfUE9PTCwKLSAgICAgICAiXHU1RUZBXHU3QUNCXHU5NkM2XHU1MzQwXHU3Njg0XHU2NUIwXHU1N0Y3XHU4ODRDXHU4NjU1XHU3NDA2XHU2NjQyXHU3NjdDXHU3NTFGXHU3NTcwXHU1RTM4XHU3MkMwXHU2Q0MxIn0sCi0KLSAgICB7IEVSX1BBVEhfQ09OVEFJTlNfSU5WQUxJRF9FU0NBUEVfU0VRVUVOQ0UsCi0gICAgICAgIlx1OERFRlx1NUY5MVx1NTMwNVx1NTQyQlx1NzEyMVx1NjU0OFx1NzY4NFx1OTA0MVx1OTZFMlx1NUU4Rlx1NTIxNyJ9LAotCi0gICAgeyBFUl9TQ0hFTUVfUkVRVUlSRUQsCi0gICAgICAgIlx1OTE0RFx1N0Y2RVx1NjYyRlx1NUZDNVx1ODk4MVx1NzY4NFx1RkYwMSJ9LAotCi0gICAgeyBFUl9OT19TQ0hFTUVfSU5fVVJJLAotICAgICAgICJcdTU3MjggVVJJIFx1NEUyRFx1NjI3RVx1NEUwRFx1NTIzMFx1OTE0RFx1N0Y2RTogezB9In0sCi0KLSAgICB7IEVSX05PX1NDSEVNRV9JTlVSSSwKLSAgICAgICAiXHU1NzI4IFVSSSBcdTYyN0VcdTRFMERcdTUyMzBcdTkxNERcdTdGNkUifSwKLQotICAgIHsgRVJfUEFUSF9JTlZBTElEX0NIQVIsCi0gICAgICAgIlx1OERFRlx1NUY5MVx1NTMwNVx1NTQyQlx1NzEyMVx1NjU0OFx1NzY4NFx1NUI1N1x1NTE0MzogezB9In0sCi0KLSAgICB7IEVSX1NDSEVNRV9GUk9NX05VTExfU1RSSU5HLAotICAgICAgICJcdTcxMjFcdTZDRDVcdTVGOUVcdTdBN0FcdTUwM0NcdTVCNTdcdTRFMzJcdThBMkRcdTVCOUFcdTkxNERcdTdGNkUifSwKLQotICAgIHsgRVJfU0NIRU1FX05PVF9DT05GT1JNQU5ULAotICAgICAgICJcdTkxNERcdTdGNkVcdTRFMERcdTRFMDBcdTgxRjRcdTMwMDIifSwKLQotICAgIHsgRVJfSE9TVF9BRERSRVNTX05PVF9XRUxMRk9STUVELAotICAgICAgICJcdTRFM0JcdTZBNUZcdTZDOTJcdTY3MDlcdTVCOENcdTY1NzRcdTc2ODRcdTRGNERcdTU3NDAifSwKLQotICAgIHsgRVJfUE9SVF9XSEVOX0hPU1RfTlVMTCwKLSAgICAgICAiXHU0RTNCXHU2QTVGXHU3MEJBXHU3QTdBXHU1MDNDXHU2NjQyXHVGRjBDXHU3MTIxXHU2Q0Q1XHU4QTJEXHU1QjlBXHU5MDIzXHU2M0E1XHU1N0UwIn0sCi0KLSAgICB7IEVSX0lOVkFMSURfUE9SVCwKLSAgICAgICAiXHU3MTIxXHU2NTQ4XHU3Njg0XHU5MDIzXHU2M0E1XHU1N0UwXHU4NjVGXHU3OEJDIn0sCi0KLSAgICB7IEVSX0ZSQUdfRk9SX0dFTkVSSUNfVVJJLAotICAgICAgICJcdTUzRUFcdTgwRkRcdTVDMERcdTRFMDBcdTgyMkMgVVJJIFx1OEEyRFx1NUI5QVx1NzI0N1x1NkJCNSJ9LAotCi0gICAgeyBFUl9GUkFHX1dIRU5fUEFUSF9OVUxMLAotICAgICAgICJcdThERUZcdTVGOTFcdTcwQkFcdTdBN0FcdTUwM0NcdTY2NDJcdUZGMENcdTcxMjFcdTZDRDVcdThBMkRcdTVCOUFcdTcyNDdcdTZCQjUifSwKLQotICAgIHsgRVJfRlJBR19JTlZBTElEX0NIQVIsCi0gICAgICAgIlx1NzI0N1x1NkJCNVx1NTMwNVx1NTQyQlx1NzEyMVx1NjU0OFx1NzY4NFx1NUI1N1x1NTE0MyJ9LAotCi0gICAgeyBFUl9QQVJTRVJfSU5fVVNFLAotICAgICAgIlx1NTI1Nlx1Njc5MFx1NTY2OFx1NEY3Rlx1NzUyOFx1NEUyRCJ9LAotCi0gICAgeyBFUl9DQU5OT1RfQ0hBTkdFX1dISUxFX1BBUlNJTkcsCi0gICAgICAiXHU1MjU2XHU2NzkwXHU2NjQyXHU3MTIxXHU2Q0Q1XHU4QjhBXHU2NkY0IHswfSB7MX0ifSwKLQotICAgIHsgRVJfU0VMRl9DQVVTQVRJT05fTk9UX1BFUk1JVFRFRCwKLSAgICAgICJcdTRFMERcdTUxNDFcdThBMzFcdTgxRUFcdTg4NENcdTVGMTVcdTc2N0MifSwKLQotICAgIHsgRVJfTk9fVVNFUklORk9fSUZfTk9fSE9TVCwKLSAgICAgICJcdTU5ODJcdTY3OUNcdTZDOTJcdTY3MDlcdTYzMDdcdTVCOUFcdTRFM0JcdTZBNUZcdUZGMENcdTRFMERcdTUzRUZcdTYzMDdcdTVCOUEgVXNlcmluZm8ifSwKLQotICAgIHsgRVJfTk9fUE9SVF9JRl9OT19IT1NULAotICAgICAgIlx1NTk4Mlx1Njc5Q1x1NkM5Mlx1NjcwOVx1NjMwN1x1NUI5QVx1NEUzQlx1NkE1Rlx1RkYwQ1x1NEUwRFx1NTNFRlx1NjMwN1x1NUI5QVx1OTAyM1x1NjNBNVx1NTdFMCJ9LAotCi0gICAgeyBFUl9OT19RVUVSWV9TVFJJTkdfSU5fUEFUSCwKLSAgICAgICJcdTU3MjhcdThERUZcdTVGOTFcdTUzQ0FcdTY3RTVcdThBNjJcdTVCNTdcdTRFMzJcdTRFMkRcdTRFMERcdTUzRUZcdTYzMDdcdTVCOUFcdTY3RTVcdThBNjJcdTVCNTdcdTRFMzIifSwKLQotICAgIHsgRVJfTk9fRlJBR01FTlRfU1RSSU5HX0lOX1BBVEgsCi0gICAgICAiXHU4REVGXHU1RjkxXHU1NDhDXHU3MjQ3XHU2QkI1XHU0RTBEXHU4MEZEXHU1NDBDXHU2NjQyXHU2MzA3XHU1QjlBXHU3MjQ3XHU2QkI1In0sCi0KLSAgICB7IEVSX0NBTk5PVF9JTklUX1VSSV9FTVBUWV9QQVJNUywKLSAgICAgICJcdTcxMjFcdTZDRDVcdTRFRTVcdTdBN0FcdTc2N0RcdTUzQzNcdTY1NzhcdThENzdcdTU5Q0JcdThBMkRcdTVCOUEgVVJJIn0sCi0KLSAgICB7IEVSX01FVEhPRF9OT1RfU1VQUE9SVEVELAotICAgICAgIlx1NUMxQVx1NEUwRFx1NjUyRlx1NjNGNFx1NjVCOVx1NkNENSJ9LAotCi0gICAgeyBFUl9JTkNSU0FYU1JDRklMVEVSX05PVF9SRVNUQVJUQUJMRSwKLSAgICAgICJJbmNyZW1lbnRhbFNBWFNvdXJjZV9GaWx0ZXIgXHU3NkVFXHU1MjREXHU3MTIxXHU2Q0Q1XHU5MUNEXHU2NUIwXHU1NTVGXHU1MkQ1In0sCi0KLSAgICB7IEVSX1hNTFJEUl9OT1RfQkVGT1JFX1NUQVJUUEFSU0UsCi0gICAgICAiWE1MUmVhZGVyIFx1NEUwRFx1ODBGRFx1NTcyOCBzdGFydFBhcnNlIFx1ODk4MVx1NkM0Mlx1NEU0Qlx1NTI0RCJ9LAotCi0gICAgeyBFUl9BWElTX1RSQVZFUlNFUl9OT1RfU1VQUE9SVEVELAotICAgICAgIlx1NEUwRFx1NjUyRlx1NjNGNFx1OEVGOFx1NTQ2OFx1OTA0QVx1N0EwQlx1NUYwRjogezB9In0sCi0KLSAgICB7IEVSX0VSUk9SSEFORExFUl9DUkVBVEVEX1dJVEhfTlVMTF9QUklOVFdSSVRFUiwKLSAgICAgICJcdTRGN0ZcdTc1MjhcdTdBN0FcdTUwM0MgUHJpbnRXcml0ZXIgXHU1RUZBXHU3QUNCIExpc3RpbmdFcnJvckhhbmRsZXJcdUZGMDEifSwKLQotICAgIHsgRVJfU1lTVEVNSURfVU5LTk9XTiwKLSAgICAgICJcdTRFMERcdTY2MEVcdTc2ODQgU3lzdGVtSWQifSwKLQotICAgIHsgRVJfTE9DQVRJT05fVU5LTk9XTiwKLSAgICAgICJcdTRFMERcdTY2MEVcdTc2ODRcdTkzMkZcdThBQTRcdTRGNERcdTdGNkUifSwKLQotICAgIHsgRVJfUFJFRklYX01VU1RfUkVTT0xWRSwKLSAgICAgICJcdTUyNERcdTdGNkVcdTc4QkNcdTVGQzVcdTk4MDhcdTg5RTNcdTY3OTBcdTcwQkFcdTU0N0RcdTU0MERcdTdBN0FcdTk1OTM6IHswfSJ9LAotCi0gICAgeyBFUl9DUkVBVEVET0NVTUVOVF9OT1RfU1VQUE9SVEVELAotICAgICAgIlhQYXRoQ29udGV4dCBcdTRFMkRcdTRFMERcdTY1MkZcdTYzRjQgY3JlYXRlRG9jdW1lbnQoKVx1RkYwMSJ9LAotCi0gICAgeyBFUl9DSElMRF9IQVNfTk9fT1dORVJfRE9DVU1FTlQsCi0gICAgICAiXHU1QzZDXHU2MDI3XHU1QjUwXHU5ODA1XHU0RTBEXHU1MTc3XHU2NzA5XHU2NEMxXHU2NzA5XHU4MDA1XHU2NTg3XHU0RUY2XHVGRjAxIn0sCi0KLSAgICB7IEVSX0NISUxEX0hBU19OT19PV05FUl9ET0NVTUVOVF9FTEVNRU5ULAotICAgICAgIlx1NUM2Q1x1NjAyN1x1NUI1MFx1OTgwNVx1NEUwRFx1NTE3N1x1NjcwOVx1NjRDMVx1NjcwOVx1ODAwNVx1NjU4N1x1NEVGNlx1NTE0M1x1N0QyMFx1RkYwMSJ9LAotCi0gICAgeyBFUl9DQU5UX09VVFBVVF9URVhUX0JFRk9SRV9ET0MsCi0gICAgICAiXHU4QjY2XHU1NDRBOiBcdTcxMjFcdTZDRDVcdTU3MjhcdTY1ODdcdTRFRjZcdTUxNDNcdTdEMjBcdTRFNEJcdTUyNERcdThGMzhcdTUxRkFcdTY1ODdcdTVCNTdcdUZGMDFcdTZCNjNcdTU3MjhcdTVGRkRcdTc1NjUuLi4ifSwKLQotICAgIHsgRVJfQ0FOVF9IQVZFX01PUkVfVEhBTl9PTkVfUk9PVCwKLSAgICAgICJET00gXHU3Njg0XHU2ODM5XHU0RTBEXHU4MEZEXHU4RDg1XHU5MDRFXHU0RTAwXHU1MDBCXHVGRjAxIn0sCi0KLSAgICB7IEVSX0FSR19MT0NBTE5BTUVfTlVMTCwKLSAgICAgICAiXHU1RjE1XHU2NTc4ICdsb2NhbE5hbWUnIFx1NzBCQVx1N0E3QVx1NTAzQyJ9LAotCi0gICAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIEEgUU5BTUUgaGFzIHRoZSBzeW50YWN0aWMgZm9ybSBbTkNOYW1lOl1OQ05hbWUKLSAgICAvLyBUaGUgbG9jYWxuYW1lIGlzIHRoZSBwb3J0aW9uIGFmdGVyIHRoZSBvcHRpb25hbCBjb2xvbjsgdGhlIG1lc3NhZ2UgaW5kaWNhdGVzCi0gICAgLy8gdGhhdCB0aGVyZSBpcyBhIHByb2JsZW0gd2l0aCB0aGF0IHBhcnQgb2YgdGhlIFFOQU1FLgotICAgIHsgRVJfQVJHX0xPQ0FMTkFNRV9JTlZBTElELAotICAgICAgICJRTkFNRSBcdTRFMkRcdTc2ODQgTG9jYWxuYW1lIFx1NjFDOVx1NzBCQVx1NjcwOVx1NjU0OFx1NzY4NCBOQ05hbWUifSwKLQotICAgIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBIFFOQU1FIGhhcyB0aGUgc3ludGFjdGljIGZvcm0gW05DTmFtZTpdTkNOYW1lCi0gICAgLy8gVGhlIHByZWZpeCBpcyB0aGUgcG9ydGlvbiBiZWZvcmUgdGhlIG9wdGlvbmFsIGNvbG9uOyB0aGUgbWVzc2FnZSBpbmRpY2F0ZXMKLSAgICAvLyB0aGF0IHRoZXJlIGlzIGEgcHJvYmxlbSB3aXRoIHRoYXQgcGFydCBvZiB0aGUgUU5BTUUuCi0gICAgeyBFUl9BUkdfUFJFRklYX0lOVkFMSUQsCi0gICAgICAgIlFOQU1FIFx1NEUyRFx1NzY4NFx1NTI0RFx1N0Y2RVx1NzhCQ1x1NjFDOVx1NzBCQVx1NjcwOVx1NjU0OFx1NzY4NCBOQ05hbWUifSwKLQotICAgIHsgRVJfTkFNRV9DQU5UX1NUQVJUX1dJVEhfQ09MT04sCi0gICAgICAiXHU1NDBEXHU3QTMxXHU0RTBEXHU4MEZEXHU0RUU1XHU1MTkyXHU4NjVGXHU3MEJBXHU5NThCXHU5ODJEIn0sCi0KLSAgICB7ICJCQURfQ09ERSIsICJjcmVhdGVNZXNzYWdlIFx1NzY4NFx1NTNDM1x1NjU3OFx1OEQ4NVx1NTFGQVx1N0JDNFx1NTcwRCJ9LAotICAgIHsgIkZPUk1BVF9GQUlMRUQiLCAibWVzc2FnZUZvcm1hdCBcdTU0N0NcdTUzRUJcdTY3MUZcdTk1OTNcdTc2N0NcdTc1MUZcdTc1NzBcdTVFMzhcdTcyQzBcdTZDQzEifSwKLSAgICB7ICJsaW5lIiwgIlx1ODg0Q1x1ODY1RiJ9LAotICAgIHsgImNvbHVtbiIsIlx1OENDN1x1NjU5OVx1NkIwNFx1N0RFOFx1ODY1RiJ9LAotCi0gICAge0VSX1NFUklBTElaRVJfTk9UX0NPTlRFTlRIQU5ETEVSLAotICAgICAgInNlcmlhbGl6ZXIgXHU5ODVFXHU1MjI1ICcnezB9JycgXHU0RTBEXHU1QkU2XHU4ODRDIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyXHUzMDAyIn0sCi0KLSAgICB7RVJfUkVTT1VSQ0VfQ09VTERfTk9UX0ZJTkQsCi0gICAgICAiXHU2MjdFXHU0RTBEXHU1MjMwXHU4Q0M3XHU2RTkwIFsgezB9IF1cdTMwMDJcbnsxfSIgfSwKLQotICAgIHtFUl9SRVNPVVJDRV9DT1VMRF9OT1RfTE9BRCwKLSAgICAgICJcdTcxMjFcdTZDRDVcdThGMDlcdTUxNjVcdThDQzdcdTZFOTAgWyB7MH0gXTogezF9IFxuIHsyfSBcdCB7M30iIH0sCi0KLSAgICB7RVJfQlVGRkVSX1NJWkVfTEVTU1RIQU5fWkVSTywKLSAgICAgICJcdTdERTlcdTg4NURcdTUzNDBcdTU5MjdcdTVDMEYgPD0wIiB9LAotCi0gICAge0VSX0lOVkFMSURfVVRGMTZfU1VSUk9HQVRFLAotICAgICAgIlx1NTA3NVx1NkUyQ1x1NTIzMFx1NzEyMVx1NjU0OFx1NzY4NCBVVEYtMTYgXHU0RUUzXHU3NDA2OiB7MH1cdUZGMUYiIH0sCi0KLSAgICB7RVJfT0lFUlJPUiwKLSAgICAgICJJTyBcdTkzMkZcdThBQTQiIH0sCi0KLSAgICB7RVJfSUxMRUdBTF9BVFRSSUJVVEVfUE9TSVRJT04sCi0gICAgICAiXHU1NzI4XHU3NTIyXHU3NTFGXHU1QjUwXHU5ODA1XHU3QkMwXHU5RURFXHU0RTRCXHU1RjhDXHVGRjBDXHU2MjE2XHU1NzI4XHU3NTIyXHU3NTFGXHU1MTQzXHU3RDIwXHU0RTRCXHU1MjREXHVGRjBDXHU0RTBEXHU1M0VGXHU2NUIwXHU1ODlFXHU1QzZDXHU2MDI3IHswfVx1MzAwMlx1NUM2Q1x1NjAyN1x1NjcwM1x1ODhBQlx1NUZGRFx1NzU2NVx1MzAwMiJ9LAotCi0gICAgICAvKgotICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IGNvbnRhaW5lZCBhIHJlZmVyZW5jZSB0byBhCi0gICAgICAgKiBuYW1lc3BhY2UgcHJlZml4IHRoYXQgd2FzIHVuZGVmaW5lZC4gIFRoZSB2YWx1ZSBvZiB0aGUgc3Vic3RpdHV0aW9uCi0gICAgICAgKiB0ZXh0IGlzIHRoZSBuYW1lIG9mIHRoZSBwcmVmaXguCi0gICAgICAgKi8KLSAgICB7RVJfTkFNRVNQQUNFX1BSRUZJWCwKLSAgICAgICJcdTVCNTdcdTk5OTYgJyd7MH0nJyBcdTc2ODRcdTU0N0RcdTU0MERcdTdBN0FcdTk1OTNcdTVDMUFcdTY3MkFcdTVCQTNcdTU0NEFcdTMwMDIiIH0sCi0gICAgICAvKgotICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyByZXBvcnRlZCBpZiB0aGUgc3R5bGVzaGVldAotICAgICAgICogYmVpbmcgcHJvY2Vzc2VkIGF0dGVtcHRlZCB0byBjb25zdHJ1Y3QgYW4gWE1MIGRvY3VtZW50IHdpdGggYW4KLSAgICAgICAqIGF0dHJpYnV0ZSBpbiBhIHBsYWNlIG90aGVyIHRoYW4gb24gYW4gZWxlbWVudC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICogc3BlY2lmaWVzIHRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUuCi0gICAgICAgKi8KLSAgICB7RVJfU1RSQVlfQVRUUklCVVRFLAotICAgICAgIlx1NUM2Q1x1NjAyNyAnJ3swfScnIFx1NTcyOFx1NTE0M1x1N0QyMFx1NEU0Qlx1NTkxNlx1MzAwMiIgfSwKLQotICAgICAgLyoKLSAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBcyB3aXRoIHRoZSBwcmVjZWRpbmcgbWVzc2FnZSwgYSBuYW1lc3BhY2UKLSAgICAgICAqIGRlY2xhcmF0aW9uIGhhcyB0aGUgZm9ybSBvZiBhbiBhdHRyaWJ1dGUgYW5kIGlzIG9ubHkgcGVybWl0dGVkIHRvCi0gICAgICAgKiBhcHBlYXIgb24gYW4gZWxlbWVudC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCB7MH0gaXMgdGhlIG5hbWVzcGFjZQotICAgICAgICogcHJlZml4IGFuZCB7MX0gaXMgdGhlIFVSSSB0aGF0IHdhcyBiZWluZyB1c2VkIGluIHRoZSBlcnJvbmVvdXMKLSAgICAgICAqIG5hbWVzcGFjZSBkZWNsYXJhdGlvbi4KLSAgICAgICAqLwotICAgIHtFUl9TVFJBWV9OQU1FU1BBQ0UsCi0gICAgICAiXHU1NDdEXHU1NDBEXHU3QTdBXHU5NTkzXHU1QkEzXHU1NDRBICcnezB9Jyc9Jyd7MX0nJyBcdThEODVcdTUxRkFcdTUxNDNcdTdEMjBcdTU5MTZcdTMwMDIiIH0sCi0KLSAgICB7RVJfQ09VTERfTk9UX0xPQURfUkVTT1VSQ0UsCi0gICAgICAiXHU3MTIxXHU2Q0Q1XHU4RjA5XHU1MTY1ICcnezB9JycgKFx1NkFBMlx1NjdFNSBDTEFTU1BBVEgpXHVGRjBDXHU3NkVFXHU1MjREXHU1M0VBXHU0RjdGXHU3NTI4XHU5ODEwXHU4QTJEXHU1MDNDIn0sCi0KLSAgICB7IEVSX0lMTEVHQUxfQ0hBUkFDVEVSLAotICAgICAgICJcdTU2MTdcdThBNjZcdThGMzhcdTUxRkFcdTY1NzRcdTY1NzhcdTUwM0MgezB9IFx1NzY4NFx1NUI1N1x1NTE0M1x1RkYwQ1x1NEY0Nlx1NjYyRlx1NUI4M1x1NEUwRFx1NjYyRlx1NEVFNVx1NjMwN1x1NUI5QVx1NzY4NCB7MX0gXHU4RjM4XHU1MUZBXHU3REU4XHU3OEJDXHU1NDQ4XHU3M0ZFXHUzMDAyIn0sCi0KLSAgICB7RVJfQ09VTERfTk9UX0xPQURfTUVUSE9EX1BST1BFUlRZLAotICAgICAgIlx1NzEyMVx1NkNENVx1OEYwOVx1NTE2NVx1OEYzOFx1NTFGQVx1NjVCOVx1NkNENSAnJ3sxfScnIFx1NzY4NFx1NUM2Q1x1NjAyN1x1NkE5NCAnJ3swfScnIChcdTZBQTJcdTY3RTUgQ0xBU1NQQVRIKSIgfQotCi0KLSAgfTsKLQotICAvKioKLSAgICogR2V0IHRoZSBhc3NvY2lhdGlvbiBsaXN0LgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBhc3NvY2lhdGlvbiBsaXN0LgotICAgKi8KLQotICAgIHByb3RlY3RlZCBPYmplY3RbXVtdIGdldENvbnRlbnRzKCkgewotICAgICAgICByZXR1cm4gY29udGVudHM7Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9yZXMvWE1MTWVzc2FnZXMuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3Jlcy9YTUxNZXNzYWdlcy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiYjJmOWJiLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3Jlcy9YTUxNZXNzYWdlcy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTU5ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFhNTE1lc3NhZ2VzLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTUgMDc6NDU6NDggc3VyZXNoX2VtYWlsaWQgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnJlczsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC51dGlscy5TZWN1cml0eVN1cHBvcnQ7Ci1pbXBvcnQgamF2YS51dGlsLkxpc3RSZXNvdXJjZUJ1bmRsZTsKLWltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwotCi0vKioKLSAqIEEgdXRpbGl0eSBjbGFzcyBmb3IgaXNzdWluZyBYTUwgZXJyb3IgbWVzc2FnZXMuCi0gKiBAeHNsLnVzYWdlIGludGVybmFsCi0gKi8KLXB1YmxpYyBjbGFzcyBYTUxNZXNzYWdlcwotewotCi0gIC8qKiBUaGUgbG9jYWwgb2JqZWN0IHRvIHVzZS4gICovCi0gIHByb3RlY3RlZCBMb2NhbGUgZkxvY2FsZSA9IExvY2FsZS5nZXREZWZhdWx0KCk7Ci0KLSAgLyoqIFRoZSBsYW5ndWFnZSBzcGVjaWZpYyByZXNvdXJjZSBvYmplY3QgZm9yIFhNTCBtZXNzYWdlcy4gICovCi0gIHByaXZhdGUgc3RhdGljIExpc3RSZXNvdXJjZUJ1bmRsZSBYTUxCdW5kbGUgPSBudWxsOwotCi0gIC8qKiBUaGUgY2xhc3MgbmFtZSBvZiB0aGUgWE1MIGVycm9yIG1lc3NhZ2Ugc3RyaW5nIHRhYmxlLiAgICAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MX0VSUk9SX1JFU09VUkNFUyA9Ci0gICAgImNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzLlhNTEVycm9yUmVzb3VyY2VzIjsKLQotICAvKiogU3RyaW5nIHRvIHVzZSBpZiBhIGJhZCBtZXNzYWdlIGNvZGUgaXMgdXNlZC4gKi8KLSAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgQkFEX0NPREUgPSAiQkFEX0NPREUiOwotCi0gIC8qKiBTdHJpbmcgdG8gdXNlIGlmIHRoZSBtZXNzYWdlIGZvcm1hdCBvcGVyYXRpb24gZmFpbGVkLiAgKi8KLSAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgRk9STUFUX0ZBSUxFRCA9ICJGT1JNQVRfRkFJTEVEIjsKLQotICAvKioKLSAgICogU2V0IHRoZSBMb2NhbGUgb2JqZWN0IHRvIHVzZS4KLSAgICoKLSAgICogQHBhcmFtIGxvY2FsZSBub24tbnVsbCByZWZlcmVuY2UgdG8gTG9jYWxlIG9iamVjdC4KLSAgICovCi0gICBwdWJsaWMgdm9pZCBzZXRMb2NhbGUoTG9jYWxlIGxvY2FsZSkKLSAgewotICAgIGZMb2NhbGUgPSBsb2NhbGU7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBMb2NhbGUgb2JqZWN0IHRoYXQgaXMgYmVpbmcgdXNlZC4KLSAgICoKLSAgICogQHJldHVybiBub24tbnVsbCByZWZlcmVuY2UgdG8gTG9jYWxlIG9iamVjdC4KLSAgICovCi0gIHB1YmxpYyBMb2NhbGUgZ2V0TG9jYWxlKCkKLSAgewotICAgIHJldHVybiBmTG9jYWxlOwotICB9Ci0KLSAgLyoqCi0gICAqIENyZWF0ZXMgYSBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCBrZXkgYW5kIHJlcGxhY2VtZW50Ci0gICAqIGFyZ3VtZW50cywgbG9jYWxpemVkIHRvIHRoZSBnaXZlbiBsb2NhbGUuCi0gICAqCi0gICAqIEBwYXJhbSBtc2dLZXkgICAgVGhlIGtleSBmb3IgdGhlIG1lc3NhZ2UgdGV4dC4KLSAgICogQHBhcmFtIGFyZ3MgICAgICBUaGUgYXJndW1lbnRzIHRvIGJlIHVzZWQgYXMgcmVwbGFjZW1lbnQgdGV4dAotICAgKiAgICAgICAgICAgICAgICAgIGluIHRoZSBtZXNzYWdlIGNyZWF0ZWQuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGZvcm1hdHRlZCBtZXNzYWdlIHN0cmluZy4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIGNyZWF0ZVhNTE1lc3NhZ2UoU3RyaW5nIG1zZ0tleSwgT2JqZWN0IGFyZ3NbXSkKLSAgewotICAgIGlmIChYTUxCdW5kbGUgPT0gbnVsbCkgewotICAgICAgICBYTUxCdW5kbGUgPSBTZWN1cml0eVN1cHBvcnQuZ2V0UmVzb3VyY2VCdW5kbGUoWE1MX0VSUk9SX1JFU09VUkNFUyk7Ci0gICAgfQotCi0gICAgaWYgKFhNTEJ1bmRsZSAhPSBudWxsKQotICAgIHsKLSAgICAgIHJldHVybiBjcmVhdGVNc2coWE1MQnVuZGxlLCBtc2dLZXksIGFyZ3MpOwotICAgIH0KLSAgICBlbHNlCi0gICAgICByZXR1cm4gIkNvdWxkIG5vdCBsb2FkIGFueSByZXNvdXJjZSBidW5kbGVzLiI7Ci0gIH0KLQotICAvKioKLSAgICogQ3JlYXRlcyBhIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIGtleSBhbmQgcmVwbGFjZW1lbnQKLSAgICogYXJndW1lbnRzLCBsb2NhbGl6ZWQgdG8gdGhlIGdpdmVuIGxvY2FsZS4KLSAgICoKLSAgICogQHBhcmFtIGZSZXNvdXJjZUJ1bmRsZSBUaGUgcmVzb3VyY2UgYnVuZGxlIHRvIHVzZS4KLSAgICogQHBhcmFtIG1zZ0tleSAgVGhlIG1lc3NhZ2Uga2V5IHRvIHVzZS4KLSAgICogQHBhcmFtIGFyZ3MgICAgICBUaGUgYXJndW1lbnRzIHRvIGJlIHVzZWQgYXMgcmVwbGFjZW1lbnQgdGV4dAotICAgKiAgICAgICAgICAgICAgICAgIGluIHRoZSBtZXNzYWdlIGNyZWF0ZWQuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGZvcm1hdHRlZCBtZXNzYWdlIHN0cmluZy4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIGNyZWF0ZU1zZyhMaXN0UmVzb3VyY2VCdW5kbGUgZlJlc291cmNlQnVuZGxlLAotICAgICAgICBTdHJpbmcgbXNnS2V5LCBPYmplY3QgYXJnc1tdKSAgLy90aHJvd3MgRXhjZXB0aW9uCi0gIHsKLQotICAgIFN0cmluZyBmbXNnID0gbnVsbDsKLSAgICBib29sZWFuIHRocm93ZXggPSBmYWxzZTsKLSAgICBTdHJpbmcgbXNnID0gbnVsbDsKLQotICAgIGlmIChtc2dLZXkgIT0gbnVsbCkKLSAgICAgIG1zZyA9IGZSZXNvdXJjZUJ1bmRsZS5nZXRTdHJpbmcobXNnS2V5KTsKLQotICAgIGlmIChtc2cgPT0gbnVsbCkKLSAgICB7Ci0gICAgICBtc2cgPSBmUmVzb3VyY2VCdW5kbGUuZ2V0U3RyaW5nKEJBRF9DT0RFKTsKLSAgICAgIHRocm93ZXggPSB0cnVlOwotICAgIH0KLQotICAgIGlmIChhcmdzICE9IG51bGwpCi0gICAgewotICAgICAgdHJ5Ci0gICAgICB7Ci0KLSAgICAgICAgLy8gRG8gdGhpcyB0byBrZWVwIGZvcm1hdCBmcm9tIGNyeWluZy4KLSAgICAgICAgLy8gVGhpcyBpcyBiZXR0ZXIgdGhhbiBtYWtpbmcgYSBidW5jaCBvZiBjb25kaXRpb25hbAotICAgICAgICAvLyBjb2RlIGFsbCBvdmVyIHRoZSBwbGFjZS4KLSAgICAgICAgaW50IG4gPSBhcmdzLmxlbmd0aDsKLQotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykKLSAgICAgICAgewotICAgICAgICAgIGlmIChudWxsID09IGFyZ3NbaV0pCi0gICAgICAgICAgICBhcmdzW2ldID0gIiI7Ci0gICAgICAgIH0KLQotICAgICAgICBmbXNnID0gamF2YS50ZXh0Lk1lc3NhZ2VGb3JtYXQuZm9ybWF0KG1zZywgYXJncyk7Ci0gICAgICB9Ci0gICAgICBjYXRjaCAoRXhjZXB0aW9uIGUpCi0gICAgICB7Ci0gICAgICAgIGZtc2cgPSBmUmVzb3VyY2VCdW5kbGUuZ2V0U3RyaW5nKEZPUk1BVF9GQUlMRUQpOwotICAgICAgICBmbXNnICs9ICIgIiArIG1zZzsKLSAgICAgIH0KLSAgICB9Ci0gICAgZWxzZQotICAgICAgZm1zZyA9IG1zZzsKLQotICAgIGlmICh0aHJvd2V4KQotICAgIHsKLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGZtc2cpOwotICAgIH0KLQotICAgIHJldHVybiBmbXNnOwotICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3Jlc29sdmVyL0NhdGFsb2cuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3Jlc29sdmVyL0NhdGFsb2cuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOWFmZjlmMC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9yZXNvbHZlci9DYXRhbG9nLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMjA0ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKi8KLS8qCi0gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKLSAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAotICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgotICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKLSAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCi0gKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLy8gQ2F0YWxvZy5qYXZhIC0gUmVwcmVzZW50cyBPQVNJUyBPcGVuIENhdGFsb2cgZmlsZXMuCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzb2x2ZXI7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmpheHAuU0FYUGFyc2VyRmFjdG9yeUltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlscy5TZWN1cml0eVN1cHBvcnQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXNvbHZlci5oZWxwZXJzLkZpbGVVUkw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXNvbHZlci5oZWxwZXJzLlB1YmxpY0lkOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzb2x2ZXIucmVhZGVycy5DYXRhbG9nUmVhZGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzb2x2ZXIucmVhZGVycy5PQVNJU1hNTENhdGFsb2dSZWFkZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXNvbHZlci5yZWFkZXJzLlNBWENhdGFsb2dSZWFkZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXNvbHZlci5yZWFkZXJzLlRSOTQwMUNhdGFsb2dSZWFkZXI7Ci0KLWltcG9ydCBqYXZhLmlvLkRhdGFJbnB1dFN0cmVhbTsKLWltcG9ydCBqYXZhLmlvLkZpbGVOb3RGb3VuZEV4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5pby5VbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uOwotaW1wb3J0IGphdmEubmV0Lk1hbGZvcm1lZFVSTEV4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLm5ldC5VUkw7Ci1pbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOwotaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwotaW1wb3J0IGphdmEudXRpbC5NYXA7Ci1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXJGYWN0b3J5OwotCi0vKioKLSAqIFJlcHJlc2VudHMgT0FTSVMgT3BlbiBDYXRhbG9nIGZpbGVzLgotICoKLSAqIDxwPlRoaXMgY2xhc3MgaW1wbGVtZW50cyB0aGUgc2VtYW50aWNzIG9mIE9BU0lTIE9wZW4gQ2F0YWxvZyBmaWxlcwotICogKGRlZmluZWQgYnkKLSAqIDxhIGhyZWY9Imh0dHA6Ly93d3cub2FzaXMtb3Blbi5vcmcvaHRtbC9hNDAxLmh0bSI+T0FTSVMgVGVjaG5pY2FsCi0gKiBSZXNvbHV0aW9uIDk0MDE6MTk5NyAoQW1lbmRtZW50IDIgdG8gVFIgOTQwMSk8L2E+KS48L3A+Ci0gKgotICogPHA+VGhlIHByaW1hcnkgcHVycG9zZSBvZiB0aGUgQ2F0YWxvZyBpcyB0byBhc3NvY2lhdGUgcmVzb3VyY2VzIGluIHRoZQotICogZG9jdW1lbnQgd2l0aCBsb2NhbCBzeXN0ZW0gaWRlbnRpZmllcnMuIFNvbWUgZW50aXRpZXMKLSAqIChkb2N1bWVudCB0eXBlcywgWE1MIGVudGl0aWVzLCBhbmQgbm90YXRpb25zKSBoYXZlIG5hbWVzIGFuZCBhbGwgb2YgdGhlbQotICogY2FuIGhhdmUgZWl0aGVyIHB1YmxpYyBvciBzeXN0ZW0gaWRlbnRpZmllcnMgb3IgYm90aC4gKEluIFhNTCwgb25seSBhCi0gKiBub3RhdGlvbiBjYW4gaGF2ZSBhIHB1YmxpYyBpZGVudGlmaWVyIHdpdGhvdXQgYSBzeXN0ZW0gaWRlbnRpZmllciwgYnV0Ci0gKiB0aGUgbWV0aG9kcyBpbXBsZW1lbnRlZCBpbiB0aGlzIGNsYXNzIG9iZXkgdGhlIENhdGFsb2cgc2VtYW50aWNzCi0gKiBmcm9tIHRoZSBTR01MCi0gKiBkYXlzIHdoZW4gc3lzdGVtIGlkZW50aWZpZXJzIHdlcmUgb3B0aW9uYWwuKTwvcD4KLSAqCi0gKiA8cD5UaGUgc3lzdGVtIGlkZW50aWZpZXJzIHJldHVybmVkIGJ5IHRoZSByZXNvbHV0aW9uIG1ldGhvZHMgaW4gdGhpcwotICogY2xhc3MgYXJlIHZhbGlkLCBpLmUuIHVzYWJsZSBieSwgYW5kIGluIGZhY3QgY29uc3RydWN0ZWQgYnksIHRoZQotICogPHR0PmphdmEubmV0LlVSTDwvdHQ+IGNsYXNzLiBVbmZvcnR1bmF0ZWx5LCB0aGlzIGNsYXNzIHNlZW1zIHRvIGJlaGF2ZSBpbgotICogc29tZXdoYXQgbm9uLXN0YW5kYXJkIHdheXMgYW5kIHRoZSBzeXN0ZW0gaWRlbnRpZmllcnMgcmV0dXJuZWQgbWF5Ci0gKiBub3QgYmUgZGlyZWN0bHkgdXNhYmxlIGluIGEgYnJvd3NlciBvciBmaWxlc3lzdGVtIGNvbnRleHQuCi0gKgotICogPHA+VGhpcyBjbGFzcyByZWNvZ25pemVzIGFsbCBvZiB0aGUgQ2F0YWxvZyBlbnRyaWVzIGRlZmluZWQgaW4KLSAqIFRSOTQwMToxOTk3OjwvcD4KLSAqCi0gKiA8dWw+Ci0gKiA8bGk+PGI+QkFTRTwvYj4KLSAqIGNoYW5nZXMgdGhlIGJhc2UgVVJJIGZvciByZXNvbHZpbmcgcmVsYXRpdmUgc3lzdGVtIGlkZW50aWZpZXJzLiBUaGUKLSAqIGluaXRpYWwgYmFzZSBVUkkgaXMgdGhlIFVSSSBvZiB0aGUgbG9jYXRpb24gb2YgdGhlIGNhdGFsb2cgKHdoaWNoIGlzLAotICogaW4gdHVybiwgcmVsYXRpdmUgdG8gdGhlIGxvY2F0aW9uIG9mIHRoZSBjdXJyZW50IHdvcmtpbmcgZGlyZWN0b3J5Ci0gKiBhdCBzdGFydHVwLCBhcyByZXR1cm5lZCBieSB0aGUgPHR0PnVzZXIuZGlyPC90dD4gc3lzdGVtIHByb3BlcnR5KS48L2xpPgotICogPGxpPjxiPkNBVEFMT0c8L2I+Ci0gKiBwcm9jZXNzZXMgb3RoZXIgY2F0YWxvZyBmaWxlcy4gQW4gaW5jbHVkZWQgY2F0YWxvZyBvY2N1cnMgbG9naWNhbGx5Ci0gKiBhdCB0aGUgZW5kIG9mIHRoZSBpbmNsdWRpbmcgY2F0YWxvZy48L2xpPgotICogPGxpPjxiPkRFTEVHQVRFX1BVQkxJQzwvYj4KLSAqIHNwZWNpZmllcyBhbHRlcm5hdGUgY2F0YWxvZ3MgZm9yIHNvbWUgcHVibGljIGlkZW50aWZpZXJzLiBUaGUgZGVsZWdhdGVkCi0gKiBjYXRhbG9ncyBhcmUgbm90IGxvYWRlZCB1bnRpbCB0aGV5IGFyZSBuZWVkZWQsIGJ1dCB0aGV5IGFyZSBjYWNoZWQKLSAqIG9uY2UgbG9hZGVkLjwvbGk+Ci0gKiA8bGk+PGI+REVMRUdBVEVfU1lTVEVNPC9iPgotICogc3BlY2lmaWVzIGFsdGVybmF0ZSBjYXRhbG9ncyBmb3Igc29tZSBzeXN0ZW0gaWRlbnRpZmllcnMuIFRoZSBkZWxlZ2F0ZWQKLSAqIGNhdGFsb2dzIGFyZSBub3QgbG9hZGVkIHVudGlsIHRoZXkgYXJlIG5lZWRlZCwgYnV0IHRoZXkgYXJlIGNhY2hlZAotICogb25jZSBsb2FkZWQuPC9saT4KLSAqIDxsaT48Yj5ERUxFR0FURV9VUkk8L2I+Ci0gKiBzcGVjaWZpZXMgYWx0ZXJuYXRlIGNhdGFsb2dzIGZvciBzb21lIFVSSXMuIFRoZSBkZWxlZ2F0ZWQKLSAqIGNhdGFsb2dzIGFyZSBub3QgbG9hZGVkIHVudGlsIHRoZXkgYXJlIG5lZWRlZCwgYnV0IHRoZXkgYXJlIGNhY2hlZAotICogb25jZSBsb2FkZWQuPC9saT4KLSAqIDxsaT48Yj5SRVdSSVRFX1NZU1RFTTwvYj4KLSAqIHNwZWNpZmllcyBhbHRlcm5hdGUgcHJlZml4IGZvciBhIHN5c3RlbSBpZGVudGlmaWVyLjwvbGk+Ci0gKiA8bGk+PGI+UkVXUklURV9VUkk8L2I+Ci0gKiBzcGVjaWZpZXMgYWx0ZXJuYXRlIHByZWZpeCBmb3IgYSBVUkkuPC9saT4KLSAqIDxsaT48Yj5TWVNURU1fU1VGRklYPC9iPgotICogbWFwcyBhbnkgc3lzdGVtIGlkZW50aWZpZXIgdGhhdCBlbmRzIHdpdGggYSBwYXJ0aWN1bGFyIHN1ZmZpeCB0byBhbm90aGVyCi0gKiBzeXN0ZW0gaWRlbnRpZmllci48L2xpPgotICogPGxpPjxiPlVSSV9TVUZGSVg8L2I+Ci0gKiBtYXBzIGFueSBVUkkgdGhhdCBlbmRzIHdpdGggYSBwYXJ0aWN1bGFyIHN1ZmZpeCB0byBhbm90aGVyIFVSSS48L2xpPgotICogPGxpPjxiPkRPQ1RZUEU8L2I+Ci0gKiBhc3NvY2lhdGVzIHRoZSBuYW1lcyBvZiByb290IGVsZW1lbnRzIHdpdGggVVJJcy4gKEluIG90aGVyIHdvcmRzLCBhbiBYTUwKLSAqIHByb2Nlc3NvciBtaWdodCBpbmZlciB0aGUgZG9jdHlwZSBvZiBhbiBYTUwgZG9jdW1lbnQgdGhhdCBkb2VzIG5vdCBpbmNsdWRlCi0gKiBhIGRvY3R5cGUgZGVjbGFyYXRpb24gYnkgbG9va2luZyBmb3IgdGhlIERPQ1RZUEUgZW50cnkgaW4gdGhlCi0gKiBjYXRhbG9nIHdoaWNoIG1hdGNoZXMgdGhlIG5hbWUgb2YgdGhlIHJvb3QgZWxlbWVudCBvZiB0aGUgZG9jdW1lbnQuKTwvbGk+Ci0gKiA8bGk+PGI+RE9DVU1FTlQ8L2I+Ci0gKiBwcm92aWRlcyBhIGRlZmF1bHQgZG9jdW1lbnQuPC9saT4KLSAqIDxsaT48Yj5EVERERUNMPC9iPgotICogcmVjb2duaXplZCBhbmQgc2lsZW50bHkgaWdub3JlZC4gTm90IHJlbGV2YW50IGZvciBYTUwuPC9saT4KLSAqIDxsaT48Yj5FTlRJVFk8L2I+Ci0gKiBhc3NvY2lhdGVzIGVudGl0eSBuYW1lcyB3aXRoIFVSSXMuPC9saT4KLSAqIDxsaT48Yj5MSU5LVFlQRTwvYj4KLSAqIHJlY29nbml6ZWQgYW5kIHNpbGVudGx5IGlnbm9yZWQuIE5vdCByZWxldmFudCBmb3IgWE1MLjwvbGk+Ci0gKiA8bGk+PGI+Tk9UQVRJT048L2I+Ci0gKiBhc3NvY2lhdGVzIG5vdGF0aW9uIG5hbWVzIHdpdGggVVJJcy48L2xpPgotICogPGxpPjxiPk9WRVJSSURFPC9iPgotICogY2hhbmdlcyB0aGUgb3ZlcnJpZGUgYmVoYXZpb3IuIEluaXRpYWwgYmVoYXZpb3IgaXMgc2V0IGJ5IHRoZQotICogc3lzdGVtIHByb3BlcnR5IDx0dD54bWwuY2F0YWxvZy5vdmVycmlkZTwvdHQ+LiBUaGUgZGVmYXVsdCBpbml0aWFsCi0gKiBiZWhhdmlvciBpcyAnWUVTJywgdGhhdCBpcywgZW50cmllcyBpbiB0aGUgY2F0YWxvZyBvdmVycmlkZQotICogc3lzdGVtIGlkZW50aWZpZXJzIHNwZWNpZmllZCBpbiB0aGUgZG9jdW1lbnQuPC9saT4KLSAqIDxsaT48Yj5QVUJMSUM8L2I+Ci0gKiBtYXBzIGEgcHVibGljIGlkZW50aWZpZXIgdG8gYSBzeXN0ZW0gaWRlbnRpZmllci48L2xpPgotICogPGxpPjxiPlNHTUxERUNMPC9iPgotICogcmVjb2duaXplZCBhbmQgc2lsZW50bHkgaWdub3JlZC4gTm90IHJlbGV2YW50IGZvciBYTUwuPC9saT4KLSAqIDxsaT48Yj5TWVNURU08L2I+Ci0gKiBtYXBzIGEgc3lzdGVtIGlkZW50aWZpZXIgdG8gYW5vdGhlciBzeXN0ZW0gaWRlbnRpZmllci48L2xpPgotICogPGxpPjxiPlVSSTwvYj4KLSAqIG1hcHMgYSBVUkkgdG8gYW5vdGhlciBVUkkuPC9saT4KLSAqIDwvdWw+Ci0gKgotICogPHA+Tm90ZSB0aGF0IEJBU0UgZW50cmllcyBhcmUgdHJlYXRlZCBhcyBkZXNjcmliZWQgYnkgUkZDMjM5Ni4gSW4KLSAqIHBhcnRpY3VsYXIsIHRoaXMgaGFzIHRoZSBjb3VudGVyLWludHVpdGl2ZSBwcm9wZXJ0eSB0aGF0IGFmdGVyIGEgQkFTRQotICogZW50cnkgaWRlbnRpZmluZyAiaHR0cDovL2V4YW1wbGUuY29tL2EvYi9jIiBhcyB0aGUgYmFzZSBVUkksCi0gKiB0aGUgcmVsYXRpdmUgVVJJICJmb28iIGlzIHJlc29sdmVkIHRvIHRoZSBhYnNvbHV0ZSBVUkkKLSAqICJodHRwOi8vZXhhbXBsZS5jb20vYS9iL2ZvbyIuIFlvdSBtdXN0IHByb3ZpZGUgdGhlIHRyYWlsaW5nIHNsYXNoIGlmCi0gKiB5b3UgZG8gbm90IHdhbnQgdGhlIGZpbmFsIGNvbXBvbmVudCBvZiB0aGUgcGF0aCB0byBiZSBkaXNjYXJkZWQgYXMgYQotICogZmlsZW5hbWUgd291bGQgaW4gYSBVUkkgZm9yIGEgcmVzb3VyY2U6ICJodHRwOi8vZXhhbXBsZS5jb20vYS9iL2MvIi4KLSAqIDwvcD4KLSAqCi0gKiA8cD5Ob3RlIHRoYXQgc3Vib3JkaW5hdGUgY2F0YWxvZ3MgKGFsbCBjYXRhbG9ncyBleGNlcHQgdGhlIGZpcnN0LAotICogaW5jbHVkaW5nIENBVEFMT0cgYW5kIERFTEVHQVRFKiBjYXRhbG9ncykgYXJlIG9ubHkgbG9hZGVkIGlmIGFuZCB3aGVuCi0gKiB0aGV5IGFyZSByZXF1aXJlZC48L3A+Ci0gKgotICogPHA+VGhpcyBjbGFzcyByZWxpZXMgb24gY2xhc3NlcyB3aGljaCBpbXBsZW1lbnQgdGhlIENhdGFsb2dSZWFkZXIKLSAqIGludGVyZmFjZSB0byBhY3R1YWxseSBsb2FkIGNhdGFsb2cgZmlsZXMuIFRoaXMgYWxsb3dzIHRoZSBjYXRhbG9nCi0gKiBzZW1hbnRpY3MgdG8gYmUgaW1wbGVtZW50ZWQgZm9yIFRSOTQwMSB0ZXh0LWJhc2VkIGNhdGFsb2dzLCBYTUwKLSAqIGNhdGFsb2dzLCBvciBhbnkgbnVtYmVyIG9mIG90aGVyIHN0b3JhZ2UgZm9ybWF0cy48L3A+Ci0gKgotICogPHA+QWRkaXRpb25hbCBjYXRhbG9ncyBtYXkgYWxzbyBiZSBsb2FkZWQgd2l0aCB0aGUKLSAqIHtAbGluayAjcGFyc2VDYXRhbG9nfSBtZXRob2QuPC9wPgotICogPC9kZD4KLSAqIDwvZGw+Ci0gKgotICogPHA+PGI+Q2hhbmdlIExvZzo8L2I+PC9wPgotICogPGRsPgotICogPGR0PjIuMDwvZHQ+Ci0gKiA8ZGQ+PHA+UmV3cml0ZSB0byB1c2UgQ2F0YWxvZ1JlYWRlcnMuPC9wPjwvZGQ+Ci0gKiA8ZHQ+MS4xPC9kdD4KLSAqIDxkZD48cD5BbGxvdyBxdW90ZWQgY29tcG9uZW50cyBpbiA8dHQ+eG1sLmNhdGFsb2cuZmlsZXM8L3R0PgotICogc28gdGhhdCBVUkxzIGNvbnRhaW5pbmcgY29sb25zIGNhbiBiZSB1c2VkIG9uIFVuaXguCi0gKiBUaGUgc3RyaW5nIHBhc3NlZCB0byA8dHQ+eG1sLmNhdGFsb2cuZmlsZXM8L3R0PiBjYW4gbm93IGhhdmUgdGhlIGZvcm06PC9wPgotICogPHByZT4KLSAqIHVucXVvdGVkLXBhdGgtd2l0aC1uby1zZXAtY2hhcnM6ImRvdWJsZS1xdW90ZWQgcGF0aCB3aXRoIG9yIHdpdGhvdXQgc2VwIGNoYXJzIjonc2luZ2xlLXF1b3RlZCBwYXRoIHdpdGggb3Igd2l0aG91dCBzZXAgY2hhcnMnCi0gKiA8L3ByZT4KLSAqIDxwPihXaGVyZSAiOiIgaXMgdGhlIHNlcGFyYXRlciBjaGFyYWN0ZXIgaW4gdGhpcyBleGFtcGxlLik8L3A+Ci0gKiA8cD5JZiBhbiB1bnF1b3RlZCBwYXRoIGNvbnRhaW5zIGFuIGVtYmVkZGVkIGRvdWJsZSBvciBzaW5nbGUgcXVvdGUKLSAqIGNoYXJhY3Rlciwgbm8gc3BlY2lhbCBwcm9jZXNzaWcgaXMgcGVyZm9ybWVkIG9uIHRoYXQgY2hhcmFjdGVyLiBObwotICogcGF0aCBjYW4gY29udGFpbiBzZXBhcmF0ZXIgY2hhcmFjdGVycywgZG91YmxlLCBhbmQgc2luZ2xlIHF1b3RlcwotICogc2ltdWx0YW5lb3VzbHkuPC9wPgotICogPHA+Rml4IGJ1ZyBpbiBjYWxjdWxhdGlvbiBvZiBCQVNFIGVudHJpZXM6IGlmCi0gKiBhIGNhdGFsb2cgY29udGFpbnMgbXVsdGlwbGUgQkFTRSBlbnRyaWVzLCBlYWNoIGlzIHJlbGF0aXZlIHRvIHRoZSBwcmVjZWRpbmcKLSAqIGJhc2UsIG5vdCB0aGUgZGVmYXVsdCBiYXNlIFVSSSBvZiB0aGUgY2F0YWxvZy48L3A+Ci0gKiA8L2RkPgotICogPGR0PjEuMC4xPC9kdD4KLSAqIDxkZD48cD5GaXhlZCBhIGJ1ZyBpbiB0aGUgY2FsY3VsYXRpb24gb2YgdGhlIGxpc3Qgb2Ygc3Vib3JkaW5hdGUgY2F0YWxvZ3MuCi0gKiBUaGlzIGJ1ZyBjYXVzZWQgYW4gaW5maW5pdGUgbG9vcCB3aGVyZSBwYXJzaW5nIHdvdWxkIGFsdGVybmF0ZWx5IHByb2Nlc3MKLSAqIHR3byBjYXRhbG9ncyBpbmRlZmluaXRlbHkuPC9wPgotICogPC9kZD4KLSAqIDwvZGw+Ci0gKgotICogQHNlZSBDYXRhbG9nUmVhZGVyCi0gKiBAc2VlIENhdGFsb2dFbnRyeQotICoKLSAqIEBhdXRob3IgTm9ybWFuIFdhbHNoCi0gKiA8YSBocmVmPSJtYWlsdG86Tm9ybWFuLldhbHNoQFN1bi5DT00iPk5vcm1hbi5XYWxzaEBTdW4uQ09NPC9hPgotICoKLSAqIEB2ZXJzaW9uIDEuMAotICoKLSAqIDxwPkRlcml2ZWQgZnJvbSBwdWJsaWMgZG9tYWluIGNvZGUgb3JpZ2luYWxseSBwdWJsaXNoZWQgYnkgQXJib3J0ZXh0LAotICogSW5jLjwvcD4KLSAqLwotcHVibGljIGNsYXNzIENhdGFsb2cgewotICAvKiogVGhlIEJBU0UgQ2F0YWxvZyBFbnRyeSB0eXBlLiAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCQVNFICAgICA9IENhdGFsb2dFbnRyeS5hZGRFbnRyeVR5cGUoIkJBU0UiLCAxKTsKLQotICAvKiogVGhlIENBVEFMT0cgQ2F0YWxvZyBFbnRyeSB0eXBlLiAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDQVRBTE9HICA9IENhdGFsb2dFbnRyeS5hZGRFbnRyeVR5cGUoIkNBVEFMT0ciLCAxKTsKLQotICAvKiogVGhlIERPQ1VNRU5UIENhdGFsb2cgRW50cnkgdHlwZS4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRE9DVU1FTlQgPSBDYXRhbG9nRW50cnkuYWRkRW50cnlUeXBlKCJET0NVTUVOVCIsIDEpOwotCi0gIC8qKiBUaGUgT1ZFUlJJREUgQ2F0YWxvZyBFbnRyeSB0eXBlLiAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPVkVSUklERSA9IENhdGFsb2dFbnRyeS5hZGRFbnRyeVR5cGUoIk9WRVJSSURFIiwgMSk7Ci0KLSAgLyoqIFRoZSBTR01MREVDTCBDYXRhbG9nIEVudHJ5IHR5cGUuICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNHTUxERUNMID0gQ2F0YWxvZ0VudHJ5LmFkZEVudHJ5VHlwZSgiU0dNTERFQ0wiLCAxKTsKLQotICAvKiogVGhlIERFTEVHQVRFX1BVQkxJQyBDYXRhbG9nIEVudHJ5IHR5cGUuICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFTEVHQVRFX1BVQkxJQyA9IENhdGFsb2dFbnRyeS5hZGRFbnRyeVR5cGUoIkRFTEVHQVRFX1BVQkxJQyIsIDIpOwotCi0gIC8qKiBUaGUgREVMRUdBVEVfU1lTVEVNIENhdGFsb2cgRW50cnkgdHlwZS4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgREVMRUdBVEVfU1lTVEVNID0gQ2F0YWxvZ0VudHJ5LmFkZEVudHJ5VHlwZSgiREVMRUdBVEVfU1lTVEVNIiwgMik7Ci0KLSAgLyoqIFRoZSBERUxFR0FURV9VUkkgQ2F0YWxvZyBFbnRyeSB0eXBlLiAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBERUxFR0FURV9VUkkgPSBDYXRhbG9nRW50cnkuYWRkRW50cnlUeXBlKCJERUxFR0FURV9VUkkiLCAyKTsKLQotICAvKiogVGhlIERPQ1RZUEUgQ2F0YWxvZyBFbnRyeSB0eXBlLiAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBET0NUWVBFICA9IENhdGFsb2dFbnRyeS5hZGRFbnRyeVR5cGUoIkRPQ1RZUEUiLCAyKTsKLQotICAvKiogVGhlIERURERFQ0wgQ2F0YWxvZyBFbnRyeSB0eXBlLiAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBEVERERUNMICA9IENhdGFsb2dFbnRyeS5hZGRFbnRyeVR5cGUoIkRURERFQ0wiLCAyKTsKLQotICAvKiogVGhlIEVOVElUWSBDYXRhbG9nIEVudHJ5IHR5cGUuICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVOVElUWSAgID0gQ2F0YWxvZ0VudHJ5LmFkZEVudHJ5VHlwZSgiRU5USVRZIiwgMik7Ci0KLSAgLyoqIFRoZSBMSU5LVFlQRSBDYXRhbG9nIEVudHJ5IHR5cGUuICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExJTktUWVBFID0gQ2F0YWxvZ0VudHJ5LmFkZEVudHJ5VHlwZSgiTElOS1RZUEUiLCAyKTsKLQotICAvKiogVGhlIE5PVEFUSU9OIENhdGFsb2cgRW50cnkgdHlwZS4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTk9UQVRJT04gPSBDYXRhbG9nRW50cnkuYWRkRW50cnlUeXBlKCJOT1RBVElPTiIsIDIpOwotCi0gIC8qKiBUaGUgUFVCTElDIENhdGFsb2cgRW50cnkgdHlwZS4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUFVCTElDICAgPSBDYXRhbG9nRW50cnkuYWRkRW50cnlUeXBlKCJQVUJMSUMiLCAyKTsKLQotICAvKiogVGhlIFNZU1RFTSBDYXRhbG9nIEVudHJ5IHR5cGUuICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNZU1RFTSAgID0gQ2F0YWxvZ0VudHJ5LmFkZEVudHJ5VHlwZSgiU1lTVEVNIiwgMik7Ci0KLSAgLyoqIFRoZSBVUkkgQ2F0YWxvZyBFbnRyeSB0eXBlLiAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBVUkkgICAgICA9IENhdGFsb2dFbnRyeS5hZGRFbnRyeVR5cGUoIlVSSSIsIDIpOwotCi0gIC8qKiBUaGUgUkVXUklURV9TWVNURU0gQ2F0YWxvZyBFbnRyeSB0eXBlLiAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVdSSVRFX1NZU1RFTSA9IENhdGFsb2dFbnRyeS5hZGRFbnRyeVR5cGUoIlJFV1JJVEVfU1lTVEVNIiwgMik7Ci0KLSAgLyoqIFRoZSBSRVdSSVRFX1VSSSBDYXRhbG9nIEVudHJ5IHR5cGUuICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFV1JJVEVfVVJJID0gQ2F0YWxvZ0VudHJ5LmFkZEVudHJ5VHlwZSgiUkVXUklURV9VUkkiLCAyKTsKLSAgLyoqIFRoZSBTWVNURU1fU1VGRklYIENhdGFsb2cgRW50cnkgdHlwZS4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1lTVEVNX1NVRkZJWCA9IENhdGFsb2dFbnRyeS5hZGRFbnRyeVR5cGUoIlNZU1RFTV9TVUZGSVgiLCAyKTsKLSAgLyoqIFRoZSBVUklfU1VGRklYIENhdGFsb2cgRW50cnkgdHlwZS4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVVJJX1NVRkZJWCA9IENhdGFsb2dFbnRyeS5hZGRFbnRyeVR5cGUoIlVSSV9TVUZGSVgiLCAyKTsKLQotICAvKioKLSAgICogVGhlIGJhc2UgVVJJIGZvciByZWxhdGl2ZSBzeXN0ZW0gaWRlbnRpZmllcnMgaW4gdGhlIGNhdGFsb2cuCi0gICAqIFRoaXMgbWF5IGJlIGNoYW5nZWQgYnkgQkFTRSBlbnRyaWVzIGluIHRoZSBjYXRhbG9nLgotICAgKi8KLSAgcHJvdGVjdGVkIFVSTCBiYXNlOwotCi0gIC8qKiBUaGUgYmFzZSBVUkkgb2YgdGhlIENhdGFsb2cgZmlsZSBjdXJyZW50bHkgYmVpbmcgcGFyc2VkLiAqLwotICBwcm90ZWN0ZWQgVVJMIGNhdGFsb2dDd2Q7Ci0KLSAgLyoqIFRoZSBjYXRhbG9nIGVudHJpZXMgY3VycmVudGx5IGtub3duIHRvIHRoZSBzeXN0ZW0uICovCi0gIHByb3RlY3RlZCBWZWN0b3IgY2F0YWxvZ0VudHJpZXMgPSBuZXcgVmVjdG9yKCk7Ci0KLSAgLyoqIFRoZSBkZWZhdWx0IGluaXRpYWwgb3ZlcnJpZGUgc2V0dGluZy4gKi8KLSAgcHJvdGVjdGVkIGJvb2xlYW4gZGVmYXVsdF9vdmVycmlkZSA9IHRydWU7Ci0KLSAgLyoqIFRoZSBjYXRhbG9nIG1hbmFnZXIgaW4gdXNlIGZvciB0aGlzIGluc3RhbmNlLiAqLwotICBwcm90ZWN0ZWQgQ2F0YWxvZ01hbmFnZXIgY2F0YWxvZ01hbmFnZXIgPSBDYXRhbG9nTWFuYWdlci5nZXRTdGF0aWNNYW5hZ2VyKCk7Ci0KLSAgLyoqCi0gICAqIEEgdmVjdG9yIG9mIGNhdGFsb2cgZmlsZXMgdG8gYmUgbG9hZGVkLgotICAgKgotICAgKiA8cD5UaGlzIGxpc3QgaXMgaW5pdGlhbGx5IGVzdGFibGlzaGVkIGJ5Ci0gICAqIDxjb2RlPmxvYWRTeXN0ZW1DYXRhbG9nczwvY29kZT4gd2hlbgotICAgKiBpdCBwYXJzZXMgdGhlIHN5c3RlbSBjYXRhbG9nIGxpc3QsIGJ1dCBDQVRBTE9HIGVudHJpZXMgbWF5Ci0gICAqIGNvbnRyaWJ1dGUgdG8gaXQgZHVyaW5nIHRoZSBjb3Vyc2Ugb2YgcGFyc2luZy48L3A+Ci0gICAqCi0gICAqIEBzZWUgI2xvYWRTeXN0ZW1DYXRhbG9ncwotICAgKiBAc2VlICNsb2NhbENhdGFsb2dGaWxlcwotICAgKi8KLSAgcHJvdGVjdGVkIFZlY3RvciBjYXRhbG9nRmlsZXMgPSBuZXcgVmVjdG9yKCk7Ci0KLSAgLyoqCi0gICAqIEEgdmVjdG9yIG9mIGNhdGFsb2cgZmlsZXMgY29uc3RydWN0ZWQgZHVyaW5nIHByb2Nlc3Npbmcgb2YKLSAgICogQ0FUQUxPRyBlbnRyaWVzIGluIHRoZSBjdXJyZW50IGNhdGFsb2cuCi0gICAqCi0gICAqIDxwPlRoaXMgdHdvLWxldmVsIHN5c3RlbSBpcyBhY3R1YWxseSBuZWNlc3NhcnkgdG8gY29ycmVjdGx5IGltcGxlbWVudAotICAgKiB0aGUgc2VtYW50aWNzIG9mIHRoZSBDQVRBTE9HIGVudHJ5LiBJZiBvbmUgY2F0YWxvZyBmaWxlIGluY2x1ZGVzCi0gICAqIGFub3RoZXIgd2l0aCBhIENBVEFMT0cgZW50cnksIHRoZSBpbmNsdWRlZCBjYXRhbG9nIGxvZ2ljYWxseQotICAgKiBvY2N1cnMgPGk+YXQgdGhlIGVuZDwvaT4gb2YgdGhlIGluY2x1ZGluZyBjYXRhbG9nLCBhbmQgYWZ0ZXIgYW55Ci0gICAqIHByZWNlZGluZyBDQVRBTE9HIGVudHJpZXMuIEluIG90aGVyIHdvcmRzLCB0aGUgQ0FUQUxPRyBlbnRyeQotICAgKiBjYW5ub3QgaW5zZXJ0IGFueXRoaW5nIGludG8gdGhlIG1pZGRsZSBvZiBhIGNhdGFsb2cgZmlsZS48L3A+Ci0gICAqCi0gICAqIDxwPldoZW4gcHJvY2Vzc2luZyByZWFjaGVzIHRoZSBlbmQgb2YgZWFjaCBjYXRhbG9nIGZpbGVzLCBhbnkKLSAgICogZWxlbWVudHMgb24gdGhpcyB2ZWN0b3IgYXJlIGFkZGVkIHRvIHRoZSBmcm9udCBvZiB0aGUKLSAgICogPGNvZGU+Y2F0YWxvZ0ZpbGVzPC9jb2RlPiB2ZWN0b3IuPC9wPgotICAgKgotICAgKiBAc2VlICNjYXRhbG9nRmlsZXMKLSAgICovCi0gIHByb3RlY3RlZCBWZWN0b3IgbG9jYWxDYXRhbG9nRmlsZXMgPSBuZXcgVmVjdG9yKCk7Ci0KLSAgLyoqCi0gICAqIEEgdmVjdG9yIG9mIENhdGFsb2dzLgotICAgKgotICAgKiA8cD5UaGUgc2VtYW50aWNzIG9mIENhdGFsb2cgcmVzb2x1dGlvbiBhcmUgc3VjaCB0aGF0IGVhY2gKLSAgICogY2F0YWxvZyBpcyBlZmZlY3RpdmVseSBhIGxpc3Qgb2YgQ2F0YWxvZ3MgKGluIG90aGVyIHdvcmRzLAotICAgKiBhIHJlY3Vyc2l2ZSBsaXN0IG9mIENhdGFsb2cgaW5zdGFuY2VzKS48L3A+Ci0gICAqCi0gICAqIDxwPkNhdGFsb2dzIHRoYXQgYXJlIHByb2Nlc3NlZCBhcyB0aGUgcmVzdWx0IG9mIENBVEFMT0cgb3IKLSAgICogREVMRUdBVEUqIGVudHJpZXMgYXJlIHN1Ym9yZGluYXRlIHRvIHRoZSBjYXRhbG9nIHRoYXQgY29udGFpbmVkCi0gICAqIHRoZW0sIGJ1dCB0aGV5IG1heSBpbiB0dXJuIGhhdmUgc3Vib3JkaW5hdGUgY2F0YWxvZ3MuPC9wPgotICAgKgotICAgKiA8cD5DYXRhbG9ncyBhcmUgb25seSBsb2FkZWQgd2hlbiB0aGV5IGFyZSBuZWVkZWQsIHNvIHRoaXMgdmVjdG9yCi0gICAqIGluaXRpYWxseSBjb250YWlucyBhIGxpc3Qgb2YgQ2F0YWxvZyBmaWxlbmFtZXMgKFVSTHMpLiBJZiwgZHVyaW5nCi0gICAqIHByb2Nlc3NpbmcsIG9uZSBvZiB0aGVzZSBjYXRhbG9ncyBoYXMgdG8gYmUgbG9hZGVkLCB0aGUgcmVzdWx0aW5nCi0gICAqIENhdGFsb2cgb2JqZWN0IGlzIHBsYWNlZCBpbiB0aGUgdmVjdG9yLCBlZmZlY3RpdmVseSBjYWNoaW5nIGl0Ci0gICAqIGZvciB0aGUgbmV4dCBxdWVyeS48L3A+Ci0gICAqLwotICBwcm90ZWN0ZWQgVmVjdG9yIGNhdGFsb2dzID0gbmV3IFZlY3RvcigpOwotCi0gIC8qKgotICAgKiBBIHZlY3RvciBvZiBERUxFR0FURSogQ2F0YWxvZyBlbnRyaWVzIGNvbnN0cnVjdGVkIGR1cmluZwotICAgKiBwcm9jZXNzaW5nIG9mIHRoZSBDYXRhbG9nLgotICAgKgotICAgKiA8cD5UaGlzIHR3by1sZXZlbCBzeXN0ZW0gaGFzIHR3byBwdXJwb3NlczsgZmlyc3QsIGl0IGFsbG93cwotICAgKiB1cyB0byBzb3J0IHRoZSBERUxFR0FURSogZW50cmllcyBieSB0aGUgbGVuZ3RoIG9mIHRoZSBwYXJ0aWFsCi0gICAqIHB1YmxpYyBpZGVudGlmaWVyIHNvIHRoYXQgYSBsaW5lYXIgc2VhcmNoIGVuY291bnRlcnMgdGhlbSBpbgotICAgKiB0aGUgY29ycmVjdCBvcmRlciBhbmQgc2Vjb25kLCBpdCBwdXRzIHRoZW0gYWxsIGF0IHRoZSBlbmQgb2YKLSAgICogdGhlIENhdGFsb2cuPC9wPgotICAgKgotICAgKiA8cD5XaGVuIHByb2Nlc3NpbmcgcmVhY2hlcyB0aGUgZW5kIG9mIGVhY2ggY2F0YWxvZyBmaWxlLCBhbnkKLSAgICogZWxlbWVudHMgb24gdGhpcyB2ZWN0b3IgYXJlIGFkZGVkIHRvIHRoZSBlbmQgb2YgdGhlCi0gICAqIDxjb2RlPmNhdGFsb2dFbnRyaWVzPC9jb2RlPiB2ZWN0b3IuIFRoaXMgYXNzdXJlcyB0aGF0IG1hdGNoaW5nCi0gICAqIFBVQkxJQyBrZXl3b3JkcyBhcmUgZW5jb3VudGVyZWQgYmVmb3JlIERFTEVHQVRFKiBlbnRyaWVzLjwvcD4KLSAgICovCi0gIHByb3RlY3RlZCBWZWN0b3IgbG9jYWxEZWxlZ2F0ZSA9IG5ldyBWZWN0b3IoKTsKLQotICAvKioKLSAgICogQSBoYXNoIG9mIENhdGFsb2dSZWFkZXJzLgotICAgKgotICAgKiA8cD5UaGlzIGhhc2ggbWFwcyBNSU1FIHR5cGVzIHRvIGVsZW1lbnRzIGluIHRoZSByZWFkZXJBcnIKLSAgICogdmVjdG9yLiBUaGlzIGFsbG93cyB0aGUgQ2F0YWxvZyB0byBxdWlja2x5IGxvY2F0ZSB0aGUgcmVhZGVyCi0gICAqIGZvciBhIHBhcnRpY3VsYXIgTUlNRSB0eXBlLjwvcD4KLSAgICovCi0gIHByb3RlY3RlZCBNYXA8U3RyaW5nLCBJbnRlZ2VyPiByZWFkZXJNYXAgPSBuZXcgSGFzaE1hcDw+KCk7Ci0KLSAgLyoqCi0gICAqIEEgdmVjdG9yIG9mIENhdGFsb2dSZWFkZXJzLgotICAgKgotICAgKiA8cD5UaGlzIHZlY3RvciBjb250YWlucyBhbGwgb2YgdGhlIHJlYWRlcnMgaW4gdGhlIG9yZGVyIHRoYXQgdGhleQotICAgKiB3ZXJlIGFkZGVkLiBJbiB0aGUgZXZlbnQgdGhhdCBhIGNhdGFsb2cgaXMgcmVhZCBmcm9tIGEgZmlsZSwgd2hlcmUKLSAgICogdGhlIE1JTUUgdHlwZSBpcyB1bmtub3duLCBlYWNoIHJlYWRlciBpcyBhdHRlbXB0ZWQgaW4gdHVybiB1bnRpbAotICAgKiBvbmUgc3VjY2VlZHMuPC9wPgotICAgKi8KLSAgcHJvdGVjdGVkIFZlY3RvciByZWFkZXJBcnIgPSBuZXcgVmVjdG9yKCk7Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdHMgYW4gZW1wdHkgQ2F0YWxvZy4KLSAgICoKLSAgICogPHA+VGhlIGNvbnN0cnVjdG9yIGludGVycm9nYXRlcyB0aGUgcmVsZXZhbnQgc3lzdGVtIHByb3BlcnRpZXMKLSAgICogdXNpbmcgdGhlIGRlZmF1bHQgKHN0YXRpYykgQ2F0YWxvZ01hbmFnZXIKLSAgICogYW5kIGluaXRpYWxpemVzIHRoZSBjYXRhbG9nIGRhdGEgc3RydWN0dXJlcy48L3A+Ci0gICAqLwotICBwdWJsaWMgQ2F0YWxvZygpIHsKLSAgICAvLyBub3A7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0cyBhbiBlbXB0eSBDYXRhbG9nIHdpdGggYSBzcGVjaWZpYyBDYXRhbG9nTWFuYWdlci4KLSAgICoKLSAgICogPHA+VGhlIGNvbnN0cnVjdG9yIGludGVycm9nYXRlcyB0aGUgcmVsZXZhbnQgc3lzdGVtIHByb3BlcnRpZXMKLSAgICogdXNpbmcgdGhlIHNwZWNpZmllZCBDYXRhbG9nIE1hbmFnZXIKLSAgICogYW5kIGluaXRpYWxpemVzIHRoZSBjYXRhbG9nIGRhdGEgc3RydWN0dXJlcy48L3A+Ci0gICAqLwotICBwdWJsaWMgQ2F0YWxvZyhDYXRhbG9nTWFuYWdlciBtYW5hZ2VyKSB7Ci0gICAgY2F0YWxvZ01hbmFnZXIgPSBtYW5hZ2VyOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgQ2F0YWxvZ01hbmFnZXIgdXNlZCBieSB0aGlzIGNhdGFsb2cuCi0gICAqCi0gICAqLwotICBwdWJsaWMgQ2F0YWxvZ01hbmFnZXIgZ2V0Q2F0YWxvZ01hbmFnZXIoKSB7Ci0gICAgcmV0dXJuIGNhdGFsb2dNYW5hZ2VyOwotICB9Ci0KLSAgLyoqCi0gICAqIEVzdGFibGlzaCB0aGUgQ2F0YWxvZ01hbmFnZXIgdXNlZCBieSB0aGlzIGNhdGFsb2cuCi0gICAqCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRDYXRhbG9nTWFuYWdlcihDYXRhbG9nTWFuYWdlciBtYW5hZ2VyKSB7Ci0gICAgY2F0YWxvZ01hbmFnZXIgPSBtYW5hZ2VyOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldHVwIHJlYWRlcnMuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXR1cFJlYWRlcnMoKSB7Ci0gICAgU0FYUGFyc2VyRmFjdG9yeSBzcGYgPSBjYXRhbG9nTWFuYWdlci51c2VTZXJ2aWNlc01lY2hhbmlzbSgpID8KLSAgICAgICAgICAgICAgICAgICAgU0FYUGFyc2VyRmFjdG9yeS5uZXdJbnN0YW5jZSgpIDogbmV3IFNBWFBhcnNlckZhY3RvcnlJbXBsKCk7Ci0gICAgc3BmLnNldE5hbWVzcGFjZUF3YXJlKHRydWUpOwotICAgIHNwZi5zZXRWYWxpZGF0aW5nKGZhbHNlKTsKLQotICAgIFNBWENhdGFsb2dSZWFkZXIgc2F4UmVhZGVyID0gbmV3IFNBWENhdGFsb2dSZWFkZXIoc3BmKTsKLQotICAgIHNheFJlYWRlci5zZXRDYXRhbG9nUGFyc2VyKG51bGwsICJYTUxDYXRhbG9nIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXNvbHZlci5yZWFkZXJzLlhDYXRhbG9nUmVhZGVyIik7Ci0KLSAgICBzYXhSZWFkZXIuc2V0Q2F0YWxvZ1BhcnNlcihPQVNJU1hNTENhdGFsb2dSZWFkZXIubmFtZXNwYWNlTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiY2F0YWxvZyIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzb2x2ZXIucmVhZGVycy5PQVNJU1hNTENhdGFsb2dSZWFkZXIiKTsKLQotICAgIGFkZFJlYWRlcigiYXBwbGljYXRpb24veG1sIiwgc2F4UmVhZGVyKTsKLQotICAgIFRSOTQwMUNhdGFsb2dSZWFkZXIgdGV4dFJlYWRlciA9IG5ldyBUUjk0MDFDYXRhbG9nUmVhZGVyKCk7Ci0gICAgYWRkUmVhZGVyKCJ0ZXh0L3BsYWluIiwgdGV4dFJlYWRlcik7Ci0gIH0KLQotICAvKioKLSAgICogQWRkIGEgbmV3IENhdGFsb2dSZWFkZXIgdG8gdGhlIENhdGFsb2cuCi0gICAqCi0gICAqIDxwPlRoaXMgbWV0aG9kIGFsbG93cyB5b3UgdG8gYWRkIGEgbmV3IENhdGFsb2dSZWFkZXIgdG8gdGhlCi0gICAqIGNhdGFsb2cuIFRoZSByZWFkZXIgd2lsbCBiZSBhc3NvY2lhdGVkIHdpdGggdGhlIHNwZWNpZmllZCBtaW1lVHlwZS4KLSAgICogWW91IGNhbiBvbmx5IGhhdmUgb25lIHJlYWRlciBwZXIgbWltZVR5cGUuPC9wPgotICAgKgotICAgKiA8cD5JbiB0aGUgYWJzZW5jZSBvZiBhIG1pbWVUeXBlIChlLmcuLCB3aGVuIHJlYWRpbmcgYSBjYXRhbG9nCi0gICAqIGRpcmVjdGx5IGZyb20gYSBmaWxlIG9uIHRoZSBsb2NhbCBzeXN0ZW0pLCB0aGUgcmVhZGVycyBhcmUgYXR0ZW1wdGVkCi0gICAqIGluIHRoZSBvcmRlciB0aGF0IHlvdSBhZGQgdGhlbSB0byB0aGUgQ2F0YWxvZy48L3A+Ci0gICAqCi0gICAqIDxwPk5vdGUgdGhhdCBzdWJvcmRpbmF0ZSBjYXRhbG9ncyAoY3JlYXRlZCBieSBDQVRBTE9HIG9yCi0gICAqIERFTEVHQVRFKiBlbnRyaWVzKSBnZXQgYSBjb3B5IG9mIHRoZSBzZXQgb2YgcmVhZGVycyBwcmVzZW50IGluCi0gICAqIHRoZSBwcmltYXJ5IGNhdGFsb2cgd2hlbiB0aGV5IGFyZSBjcmVhdGVkLiBSZWFkZXJzIGFkZGVkIHN1YnNlcXVlbnRseQotICAgKiB3aWxsIG5vdCBiZSBhdmFpbGFibGUuIEZvciB0aGlzIHJlYXNvbiwgaXQgaXMgYmVzdCB0byBhZGQgYWxsCi0gICAqIG9mIHRoZSByZWFkZXJzIGJlZm9yZSB0aGUgZmlyc3QgY2FsbCB0byBwYXJzZSBhIGNhdGFsb2cuPC9wPgotICAgKgotICAgKiBAcGFyYW0gbWltZVR5cGUgVGhlIE1JTUUgdHlwZSBhc3NvY2lhdGVkIHdpdGggdGhpcyByZWFkZXIuCi0gICAqIEBwYXJhbSByZWFkZXIgVGhlIENhdGFsb2dSZWFkZXIgdG8gdXNlLgotICAgKi8KLSAgcHVibGljIHZvaWQgYWRkUmVhZGVyKFN0cmluZyBtaW1lVHlwZSwgQ2F0YWxvZ1JlYWRlciByZWFkZXIpIHsKLSAgICBpZiAocmVhZGVyTWFwLmNvbnRhaW5zS2V5KG1pbWVUeXBlKSkgewotICAgICAgSW50ZWdlciBwb3MgPSByZWFkZXJNYXAuZ2V0KG1pbWVUeXBlKTsKLSAgICAgIHJlYWRlckFyci5zZXQocG9zLCByZWFkZXIpOwotICAgIH0gZWxzZSB7Ci0gICAgICByZWFkZXJBcnIuYWRkKHJlYWRlcik7Ci0gICAgICBJbnRlZ2VyIHBvcyA9IHJlYWRlckFyci5zaXplKCktMTsKLSAgICAgIHJlYWRlck1hcC5wdXQobWltZVR5cGUsIHBvcyk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIENvcGllcyB0aGUgcmVhZGVyIGxpc3QgZnJvbSB0aGUgY3VycmVudCBDYXRhbG9nIHRvIGEgbmV3IENhdGFsb2cuCi0gICAqCi0gICAqIDxwPlRoaXMgbWV0aG9kIGlzIHVzZWQgaW50ZXJuYWxseSB3aGVuIGNvbnN0cnVjdGluZyBhIG5ldyBjYXRhbG9nLgotICAgKiBJdCBjb3BpZXMgdGhlIGN1cnJlbnQgcmVhZGVyIGFzc29jaWF0aW9ucyBvdmVyIHRvIHRoZSBuZXcgY2F0YWxvZy4KLSAgICogPC9wPgotICAgKgotICAgKiBAcGFyYW0gbmV3Q2F0YWxvZyBUaGUgbmV3IENhdGFsb2cuCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBjb3B5UmVhZGVycyhDYXRhbG9nIG5ld0NhdGFsb2cpIHsKLSAgICAvLyBIYXZlIHRvIGNvcHkgdGhlIHJlYWRlcnMgaW4gdGhlIHJpZ2h0IG9yZGVyLi4uY29udmVydCBoYXNoIHRvIGFycgotICAgIFZlY3RvciBtYXBBcnIgPSBuZXcgVmVjdG9yKHJlYWRlck1hcC5zaXplKCkpOwotCi0gICAgLy8gUGFkIHRoZSBtYXBBcnIgb3V0IHRvIHRoZSByaWdodCBsZW5ndGgKLSAgICBmb3IgKGludCBjb3VudCA9IDA7IGNvdW50IDwgcmVhZGVyTWFwLnNpemUoKTsgY291bnQrKykgewotICAgICAgbWFwQXJyLmFkZChudWxsKTsKLSAgICB9Ci0KLSAgICBmb3IgKE1hcC5FbnRyeTxTdHJpbmcsIEludGVnZXI+IGVudHJ5IDogcmVhZGVyTWFwLmVudHJ5U2V0KCkpIHsKLSAgICAgICAgbWFwQXJyLnNldChlbnRyeS5nZXRWYWx1ZSgpLCBlbnRyeS5nZXRLZXkoKSk7Ci0gICAgfQotCi0gICAgZm9yIChpbnQgY291bnQgPSAwOyBjb3VudCA8IG1hcEFyci5zaXplKCk7IGNvdW50KyspIHsKLSAgICAgIFN0cmluZyBtaW1lVHlwZSA9IChTdHJpbmcpIG1hcEFyci5nZXQoY291bnQpOwotICAgICAgSW50ZWdlciBwb3MgPSByZWFkZXJNYXAuZ2V0KG1pbWVUeXBlKTsKLSAgICAgIG5ld0NhdGFsb2cuYWRkUmVhZGVyKG1pbWVUeXBlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgKENhdGFsb2dSZWFkZXIpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICByZWFkZXJBcnIuZ2V0KHBvcykpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBuZXcgQ2F0YWxvZyBvYmplY3QuCi0gICAqCi0gICAqIDxwPlRoaXMgbWV0aG9kIGNvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhlIHJ1bm5pbmcgQ2F0YWxvZwotICAgKiBjbGFzcyAod2hpY2ggbWlnaHQgYmUgYSBzdWJ0eXBlIG9mIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzb2x2ZXIuQ2F0YWxvZykuCi0gICAqIEFsbCBuZXcgY2F0YWxvZ3MgYXJlIG1hbmFnZWQgYnkgdGhlIHNhbWUgQ2F0YWxvZ01hbmFnZXIuCi0gICAqIDwvcD4KLSAgICoKLSAgICogPHA+Ti5CLiBBbGwgQ2F0YWxvZyBzdWJ0eXBlcyBzaG91bGQgY2FsbCBuZXdDYXRhbG9nKCkgdG8gY29uc3RydWN0Ci0gICAqIGEgbmV3IENhdGFsb2cuIERvIG5vdCBzaW1wbHkgdXNlICJuZXcgU3ViY2xhc3MoKSIgc2luY2UgdGhhdCB3aWxsCi0gICAqIGNvbmZ1c2UgZnV0dXJlIHN1YmNsYXNzZXMuPC9wPgotICAgKi8KLSAgcHJvdGVjdGVkIENhdGFsb2cgbmV3Q2F0YWxvZygpIHsKLSAgICBTdHJpbmcgY2F0YWxvZ0NsYXNzID0gdGhpcy5nZXRDbGFzcygpLmdldE5hbWUoKTsKLQotICAgIHRyeSB7Ci0gICAgICBDYXRhbG9nIGMgPSAoQ2F0YWxvZykgKENsYXNzLmZvck5hbWUoY2F0YWxvZ0NsYXNzKS5uZXdJbnN0YW5jZSgpKTsKLSAgICAgIGMuc2V0Q2F0YWxvZ01hbmFnZXIoY2F0YWxvZ01hbmFnZXIpOwotICAgICAgY29weVJlYWRlcnMoYyk7Ci0gICAgICByZXR1cm4gYzsKLSAgICB9IGNhdGNoIChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGNuZmUpIHsKLSAgICAgIGNhdGFsb2dNYW5hZ2VyLmRlYnVnLm1lc3NhZ2UoMSwgIkNsYXNzIE5vdCBGb3VuZCBFeGNlcHRpb246ICIgKyBjYXRhbG9nQ2xhc3MpOwotICAgIH0gY2F0Y2ggKElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gaWFlKSB7Ci0gICAgICBjYXRhbG9nTWFuYWdlci5kZWJ1Zy5tZXNzYWdlKDEsICJJbGxlZ2FsIEFjY2VzcyBFeGNlcHRpb246ICIgKyBjYXRhbG9nQ2xhc3MpOwotICAgIH0gY2F0Y2ggKEluc3RhbnRpYXRpb25FeGNlcHRpb24gaWUpIHsKLSAgICAgIGNhdGFsb2dNYW5hZ2VyLmRlYnVnLm1lc3NhZ2UoMSwgIkluc3RhbnRpYXRpb24gRXhjZXB0aW9uOiAiICsgY2F0YWxvZ0NsYXNzKTsKLSAgICB9IGNhdGNoIChDbGFzc0Nhc3RFeGNlcHRpb24gY2NlKSB7Ci0gICAgICBjYXRhbG9nTWFuYWdlci5kZWJ1Zy5tZXNzYWdlKDEsICJDbGFzcyBDYXN0IEV4Y2VwdGlvbjogIiArIGNhdGFsb2dDbGFzcyk7Ci0gICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKLSAgICAgIGNhdGFsb2dNYW5hZ2VyLmRlYnVnLm1lc3NhZ2UoMSwgIk90aGVyIEV4Y2VwdGlvbjogIiArIGNhdGFsb2dDbGFzcyk7Ci0gICAgfQotCi0gICAgQ2F0YWxvZyBjID0gbmV3IENhdGFsb2coKTsKLSAgICBjLnNldENhdGFsb2dNYW5hZ2VyKGNhdGFsb2dNYW5hZ2VyKTsKLSAgICBjb3B5UmVhZGVycyhjKTsKLSAgICByZXR1cm4gYzsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IGJhc2UgVVJJLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRDdXJyZW50QmFzZSgpIHsKLSAgICByZXR1cm4gYmFzZS50b1N0cmluZygpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIGRlZmF1bHQgb3ZlcnJpZGUgc2V0dGluZyBhc3NvY2lhdGVkIHdpdGggdGhpcwotICAgKiBjYXRhbG9nLgotICAgKgotICAgKiA8cD5BbGwgY2F0YWxvZyBmaWxlcyBsb2FkZWQgYnkgdGhpcyBjYXRhbG9nIHdpbGwgaGF2ZSB0aGUKLSAgICogaW5pdGlhbCBvdmVycmlkZSBzZXR0aW5nIHNwZWNpZmllZCBieSB0aGlzIGRlZmF1bHQuPC9wPgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXREZWZhdWx0T3ZlcnJpZGUoKSB7Ci0gICAgaWYgKGRlZmF1bHRfb3ZlcnJpZGUpIHsKLSAgICAgIHJldHVybiAieWVzIjsKLSAgICB9IGVsc2UgewotICAgICAgcmV0dXJuICJubyI7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIExvYWQgdGhlIHN5c3RlbSBjYXRhbG9nIGZpbGVzLgotICAgKgotICAgKiA8cD5UaGUgbWV0aG9kIGFkZHMgYWxsIG9mIHRoZQotICAgKiBjYXRhbG9ncyBzcGVjaWZpZWQgaW4gdGhlIDx0dD54bWwuY2F0YWxvZy5maWxlczwvdHQ+IHByb3BlcnR5Ci0gICAqIHRvIHRoZSBDYXRhbG9nIGxpc3QuPC9wPgotICAgKgotICAgKiBAdGhyb3dzIE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiAgT25lIG9mIHRoZSBzeXN0ZW0gY2F0YWxvZ3MgaXMKLSAgICogaWRlbnRpZmllZCB3aXRoIGEgZmlsZW5hbWUgdGhhdCBpcyBub3QgYSB2YWxpZCBVUkwuCi0gICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gT25lIG9mIHRoZSBzeXN0ZW0gY2F0YWxvZ3MgY2Fubm90IGJlIHJlYWQuCi0gICAqLwotICBwdWJsaWMgdm9pZCBsb2FkU3lzdGVtQ2F0YWxvZ3MoKQotICAgIHRocm93cyBNYWxmb3JtZWRVUkxFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKLQotICAgIFZlY3RvciBjYXRhbG9ncyA9IGNhdGFsb2dNYW5hZ2VyLmdldENhdGFsb2dGaWxlcygpOwotICAgIGlmIChjYXRhbG9ncyAhPSBudWxsKSB7Ci0gICAgICBmb3IgKGludCBjb3VudCA9IDA7IGNvdW50IDwgY2F0YWxvZ3Muc2l6ZSgpOyBjb3VudCsrKSB7Ci0gICAgICAgIGNhdGFsb2dGaWxlcy5hZGRFbGVtZW50KGNhdGFsb2dzLmVsZW1lbnRBdChjb3VudCkpOwotICAgICAgfQotICAgIH0KLQotICAgIGlmIChjYXRhbG9nRmlsZXMuc2l6ZSgpID4gMCkgewotICAgICAgLy8gVGhpcyBpcyBhIGxpdHRsZSBvZGQuIFRoZSBwYXJzZUNhdGFsb2coKSBtZXRob2QgZXhwZWN0cwotICAgICAgLy8gYSBmaWxlbmFtZSwgYnV0IGl0IGFkZHMgdGhhdCBuYW1lIHRvIHRoZSBlbmQgb2YgdGhlCi0gICAgICAvLyBjYXRhbG9nRmlsZXMgdmVjdG9yLCBhbmQgdGhlbiBwcm9jZXNzZXMgdGhhdCB2ZWN0b3IuCi0gICAgICAvLyBUaGlzIGFsbG93cyB0aGUgc3lzdGVtIHRvIGhhbmRsZSBDQVRBTE9HIGVudHJpZXMKLSAgICAgIC8vIGNvcnJlY3RseS4KLSAgICAgIC8vCi0gICAgICAvLyBJbiB0aGlzIGluaXQgY2FzZSwgd2UgdGFrZSB0aGUgbGFzdCBlbGVtZW50IG9mZiB0aGUKLSAgICAgIC8vIGNhdGFsb2dGaWxlcyB2ZWN0b3IgYW5kIHBhc3MgaXQgdG8gcGFyc2VDYXRhbG9nLiBUaGlzCi0gICAgICAvLyB3aWxsICJkbyB0aGUgcmlnaHQgdGhpbmciIGluIHRoZSBpbml0IGNhc2UsIGFuZCBhbGxvdwotICAgICAgLy8gcGFyc2VDYXRhbG9nKCkgdG8gZG8gdGhlIHJpZ2h0IHRoaW5nIGluIHRoZSBub24taW5pdAotICAgICAgLy8gY2FzZS4gSG9uZXN0LgotICAgICAgLy8KLSAgICAgIFN0cmluZyBjYXRmaWxlID0gKFN0cmluZykgY2F0YWxvZ0ZpbGVzLmxhc3RFbGVtZW50KCk7Ci0gICAgICBjYXRhbG9nRmlsZXMucmVtb3ZlRWxlbWVudChjYXRmaWxlKTsKLSAgICAgIHBhcnNlQ2F0YWxvZyhjYXRmaWxlKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogUGFyc2UgYSBjYXRhbG9nIGZpbGUsIGF1Z21lbnRpbmcgaW50ZXJuYWwgZGF0YSBzdHJ1Y3R1cmVzLgotICAgKgotICAgKiBAcGFyYW0gZmlsZU5hbWUgVGhlIGZpbGVuYW1lIG9mIHRoZSBjYXRhbG9nIGZpbGUgdG8gcHJvY2VzcwotICAgKgotICAgKiBAdGhyb3dzIE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiBUaGUgZmlsZU5hbWUgY2Fubm90IGJlIHR1cm5lZCBpbnRvCi0gICAqIGEgdmFsaWQgVVJMLgotICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIEVycm9yIHJlYWRpbmcgY2F0YWxvZyBmaWxlLgotICAgKi8KLSAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHBhcnNlQ2F0YWxvZyhTdHJpbmcgZmlsZU5hbWUpCi0gICAgdGhyb3dzIE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewotCi0gICAgZGVmYXVsdF9vdmVycmlkZSA9IGNhdGFsb2dNYW5hZ2VyLmdldFByZWZlclB1YmxpYygpOwotICAgIGNhdGFsb2dNYW5hZ2VyLmRlYnVnLm1lc3NhZ2UoNCwgIlBhcnNlIGNhdGFsb2c6ICIgKyBmaWxlTmFtZSk7Ci0KLSAgICAvLyBQdXQgdGhlIGZpbGUgaW50byB0aGUgbGlzdCBvZiBjYXRhbG9ncyB0byBwcm9jZXNzLi4uCi0gICAgLy8gSW4gYWxsIGNhc2VzIGV4Y2VwdCB0aGUgY2FzZSB3aGVuIGluaXRDYXRhbG9nKCkgaXMgdGhlCi0gICAgLy8gY2FsbGVyLCB0aGlzIHdpbGwgYmUgdGhlIG9ubHkgY2F0YWxvZyBpbml0aWFsbHkgaW4gdGhlIGxpc3QuLi4KLSAgICBjYXRhbG9nRmlsZXMuYWRkRWxlbWVudChmaWxlTmFtZSk7Ci0KLSAgICAvLyBOb3cgcHJvY2VzcyBhbGwgdGhlIHBlbmRpbmcgY2F0YWxvZ3MuLi4KLSAgICBwYXJzZVBlbmRpbmdDYXRhbG9ncygpOwotICB9Ci0KLSAgLyoqCi0gICAqIFBhcnNlIGEgY2F0YWxvZyBmaWxlLCBhdWdtZW50aW5nIGludGVybmFsIGRhdGEgc3RydWN0dXJlcy4KLSAgICoKLSAgICogPHA+Q2F0YWxvZ3MgcmV0cmlldmVkIG92ZXIgdGhlIG5ldCBtYXkgaGF2ZSBhbiBhc3NvY2lhdGVkIE1JTUUgdHlwZS4KLSAgICogVGhlIE1JTUUgdHlwZSBjYW4gYmUgdXNlZCB0byBzZWxlY3QgYW4gYXBwcm9wcmlhdGUgcmVhZGVyLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIG1pbWVUeXBlIFRoZSBNSU1FIHR5cGUgb2YgdGhlIGNhdGFsb2cgZmlsZS4KLSAgICogQHBhcmFtIGlzIFRoZSBJbnB1dFN0cmVhbSBmcm9tIHdoaWNoIHRoZSBjYXRhbG9nIHNob3VsZCBiZSByZWFkCi0gICAqCi0gICAqIEB0aHJvd3MgQ2F0YWxvZ0V4Y2VwdGlvbiBGYWlsZWQgdG8gbG9hZCBjYXRhbG9nCi0gICAqIG1pbWVUeXBlLgotICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIEVycm9yIHJlYWRpbmcgY2F0YWxvZyBmaWxlLgotICAgKi8KLSAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHBhcnNlQ2F0YWxvZyhTdHJpbmcgbWltZVR5cGUsIElucHV0U3RyZWFtIGlzKQotICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgQ2F0YWxvZ0V4Y2VwdGlvbiB7Ci0KLSAgICBkZWZhdWx0X292ZXJyaWRlID0gY2F0YWxvZ01hbmFnZXIuZ2V0UHJlZmVyUHVibGljKCk7Ci0gICAgY2F0YWxvZ01hbmFnZXIuZGVidWcubWVzc2FnZSg0LCAiUGFyc2UgIiArIG1pbWVUeXBlICsgIiBjYXRhbG9nIG9uIGlucHV0IHN0cmVhbSIpOwotCi0gICAgQ2F0YWxvZ1JlYWRlciByZWFkZXIgPSBudWxsOwotCi0gICAgaWYgKHJlYWRlck1hcC5jb250YWluc0tleShtaW1lVHlwZSkpIHsKLSAgICAgIGludCBhcnJheVBvcyA9ICgoSW50ZWdlcikgcmVhZGVyTWFwLmdldChtaW1lVHlwZSkpLmludFZhbHVlKCk7Ci0gICAgICByZWFkZXIgPSAoQ2F0YWxvZ1JlYWRlcikgcmVhZGVyQXJyLmdldChhcnJheVBvcyk7Ci0gICAgfQotCi0gICAgaWYgKHJlYWRlciA9PSBudWxsKSB7Ci0gICAgICBTdHJpbmcgbXNnID0gIk5vIENhdGFsb2dSZWFkZXIgZm9yIE1JTUUgdHlwZTogIiArIG1pbWVUeXBlOwotICAgICAgY2F0YWxvZ01hbmFnZXIuZGVidWcubWVzc2FnZSgyLCBtc2cpOwotICAgICAgdGhyb3cgbmV3IENhdGFsb2dFeGNlcHRpb24oQ2F0YWxvZ0V4Y2VwdGlvbi5VTlBBUlNFQUJMRSwgbXNnKTsKLSAgICB9Ci0KLSAgICByZWFkZXIucmVhZENhdGFsb2codGhpcywgaXMpOwotCi0gICAgLy8gTm93IHByb2Nlc3MgYWxsIHRoZSBwZW5kaW5nIGNhdGFsb2dzLi4uCi0gICAgcGFyc2VQZW5kaW5nQ2F0YWxvZ3MoKTsKLSAgfQotCi0gIC8qKgotICAgKiBQYXJzZSBhIGNhdGFsb2cgZG9jdW1lbnQsIGF1Z21lbnRpbmcgaW50ZXJuYWwgZGF0YSBzdHJ1Y3R1cmVzLgotICAgKgotICAgKiA8cD5UaGlzIG1ldGhvZCBzdXBwb3J0cyBjYXRhbG9nIGZpbGVzIHN0b3JlZCBpbiBqYXIgZmlsZXM6IGUuZy4sCi0gICAqIGphcjpmaWxlOi8vL3BhdGgvdG8vZmlsZW5hbWUuamFyIS9wYXRoL3RvL2NhdGFsb2cueG1sIi4gVGhhdCBVUkkKLSAgICogZG9lc24ndCBzdXJ2aXZlIHRyYW5zbW9ncmlmaWNhdGlvbiB0aHJvdWdoIHRoZSBVUkkgcHJvY2Vzc2luZyB0aGF0Ci0gICAqIHRoZSBwYXJzZUNhdGFsb2coU3RyaW5nKSBwZXJmb3JtcyBhbmQgcGFzc2luZyBpdCBhcyBhbiBpbnB1dCBzdHJlYW0KLSAgICogZG9lc24ndCBzZXQgdGhlIGJhc2UgVVJJIGFwcHJvcHJpYXRlbHkuPC9wPgotICAgKgotICAgKiA8cD5Xcml0dGVuIGJ5IFN0ZWZhbiBXYWNodGVyICgyMDAyLTA5LTI2KTwvcD4KLSAgICoKLSAgICogQHBhcmFtIGFVcmwgVGhlIFVSTCBvZiB0aGUgY2F0YWxvZyBkb2N1bWVudCB0byBwcm9jZXNzCi0gICAqCi0gICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gRXJyb3IgcmVhZGluZyBjYXRhbG9nIGZpbGUuCi0gICAqLwotICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgcGFyc2VDYXRhbG9nKFVSTCBhVXJsKSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgIGNhdGFsb2dDd2QgPSBhVXJsOwotICAgIGJhc2UgPSBhVXJsOwotCi0gICAgZGVmYXVsdF9vdmVycmlkZSA9IGNhdGFsb2dNYW5hZ2VyLmdldFByZWZlclB1YmxpYygpOwotICAgIGNhdGFsb2dNYW5hZ2VyLmRlYnVnLm1lc3NhZ2UoNCwgIlBhcnNlIGNhdGFsb2c6ICIgKyBhVXJsLnRvU3RyaW5nKCkpOwotCi0gICAgRGF0YUlucHV0U3RyZWFtIGluU3RyZWFtID0gbnVsbDsKLSAgICBib29sZWFuIHBhcnNlZCA9IGZhbHNlOwotCi0gICAgZm9yIChpbnQgY291bnQgPSAwOyAhcGFyc2VkICYmIGNvdW50IDwgcmVhZGVyQXJyLnNpemUoKTsgY291bnQrKykgewotICAgICAgQ2F0YWxvZ1JlYWRlciByZWFkZXIgPSAoQ2F0YWxvZ1JlYWRlcikgcmVhZGVyQXJyLmdldChjb3VudCk7Ci0KLSAgICAgIHRyeSB7Ci0gICAgICAgIGluU3RyZWFtID0gbmV3IERhdGFJbnB1dFN0cmVhbShhVXJsLm9wZW5TdHJlYW0oKSk7Ci0gICAgICB9IGNhdGNoIChGaWxlTm90Rm91bmRFeGNlcHRpb24gZm5mZSkgewotICAgICAgICAvLyBObyBjYXRhbG9nOyBnaXZlIHVwIQotICAgICAgICBicmVhazsKLSAgICAgIH0KLQotICAgICAgdHJ5IHsKLSAgICAgICAgcmVhZGVyLnJlYWRDYXRhbG9nKHRoaXMsIGluU3RyZWFtKTsKLSAgICAgICAgcGFyc2VkPXRydWU7Ci0gICAgICB9IGNhdGNoIChDYXRhbG9nRXhjZXB0aW9uIGNlKSB7Ci0gICAgICAgIGlmIChjZS5nZXRFeGNlcHRpb25UeXBlKCkgPT0gQ2F0YWxvZ0V4Y2VwdGlvbi5QQVJTRV9GQUlMRUQpIHsKLSAgICAgICAgICAvLyBnaXZlIHVwIQotICAgICAgICAgIGJyZWFrOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgIC8vIHRyeSBhZ2FpbiEKLSAgICAgICAgfQotICAgICAgfQotCi0gICAgICB0cnkgewotICAgICAgICBpblN0cmVhbS5jbG9zZSgpOwotICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewotICAgICAgICAvL25vcAotICAgICAgfQotICAgIH0KLQotICAgIGlmIChwYXJzZWQpIHBhcnNlUGVuZGluZ0NhdGFsb2dzKCk7Ci0gIH0KLQotICAvKioKLSAgICogUGFyc2UgYWxsIG9mIHRoZSBwZW5kaW5nIGNhdGFsb2dzLgotICAgKgotICAgKiA8cD5DYXRhbG9ncyBtYXkgcmVmZXIgdG8gb3RoZXIgY2F0YWxvZ3MsIHRoaXMgbWV0aG9kIHBhcnNlcwotICAgKiBhbGwgb2YgdGhlIGN1cnJlbnRseSBwZW5kaW5nIGNhdGFsb2cgZmlsZXMuPC9wPgotICAgKi8KLSAgcHJvdGVjdGVkIHN5bmNocm9uaXplZCB2b2lkIHBhcnNlUGVuZGluZ0NhdGFsb2dzKCkKLSAgICB0aHJvd3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7Ci0KLSAgICBpZiAoIWxvY2FsQ2F0YWxvZ0ZpbGVzLmlzRW1wdHkoKSkgewotICAgICAgLy8gTW92ZSBhbGwgdGhlIGxvY2FsQ2F0YWxvZ0ZpbGVzIGludG8gdGhlIGZyb250IG9mCi0gICAgICAvLyB0aGUgY2F0YWxvZ0ZpbGVzIHF1ZXVlCi0gICAgICBWZWN0b3IgbmV3UXVldWUgPSBuZXcgVmVjdG9yKCk7Ci0gICAgICBFbnVtZXJhdGlvbiBxID0gbG9jYWxDYXRhbG9nRmlsZXMuZWxlbWVudHMoKTsKLSAgICAgIHdoaWxlIChxLmhhc01vcmVFbGVtZW50cygpKSB7Ci0gICAgICAgIG5ld1F1ZXVlLmFkZEVsZW1lbnQocS5uZXh0RWxlbWVudCgpKTsKLSAgICAgIH0KLQotICAgICAgLy8gUHV0IHRoZSByZXN0IG9mIHRoZSBjYXRhbG9ncyBvbiB0aGUgZW5kIG9mIHRoZSBuZXcgbGlzdAotICAgICAgZm9yIChpbnQgY3VyQ2F0ID0gMDsgY3VyQ2F0IDwgY2F0YWxvZ0ZpbGVzLnNpemUoKTsgY3VyQ2F0KyspIHsKLSAgICAgICAgU3RyaW5nIGNhdGZpbGUgPSAoU3RyaW5nKSBjYXRhbG9nRmlsZXMuZWxlbWVudEF0KGN1ckNhdCk7Ci0gICAgICAgIG5ld1F1ZXVlLmFkZEVsZW1lbnQoY2F0ZmlsZSk7Ci0gICAgICB9Ci0KLSAgICAgIGNhdGFsb2dGaWxlcyA9IG5ld1F1ZXVlOwotICAgICAgbG9jYWxDYXRhbG9nRmlsZXMuY2xlYXIoKTsKLSAgICB9Ci0KLSAgICAvLyBTdXBwb3NlIHRoZXJlIGFyZSBubyBjYXRhbG9nIGZpbGVzIHRvIHByb2Nlc3MsIGJ1dCB0aGUKLSAgICAvLyBzaW5nbGUgY2F0YWxvZyBhbHJlYWR5IHBhcnNlZCBpbmNsdWRlZCBzb21lIGRlbGVnYXRlCi0gICAgLy8gZW50cmllcz8gTWFrZSBzdXJlIHRoZXkgZG9uJ3QgZ2V0IGxvc3QuCi0gICAgaWYgKGNhdGFsb2dGaWxlcy5pc0VtcHR5KCkgJiYgIWxvY2FsRGVsZWdhdGUuaXNFbXB0eSgpKSB7Ci0gICAgICBFbnVtZXJhdGlvbiBlID0gbG9jYWxEZWxlZ2F0ZS5lbGVtZW50cygpOwotICAgICAgd2hpbGUgKGUuaGFzTW9yZUVsZW1lbnRzKCkpIHsKLSAgICAgICAgY2F0YWxvZ0VudHJpZXMuYWRkRWxlbWVudChlLm5leHRFbGVtZW50KCkpOwotICAgICAgfQotICAgICAgbG9jYWxEZWxlZ2F0ZS5jbGVhcigpOwotICAgIH0KLQotICAgIC8vIE5vdyBwcm9jZXNzIGFsbCB0aGUgZmlsZXMgb24gdGhlIGNhdGFsb2dGaWxlcyB2ZWN0b3IuIFRoaXMKLSAgICAvLyB2ZWN0b3IgY2FuIGdyb3cgZHVyaW5nIHByb2Nlc3NpbmcgaWYgQ0FUQUxPRyBlbnRyaWVzIGFyZQotICAgIC8vIGVuY291bnRlcmVkIGluIHRoZSBjYXRhbG9nCi0gICAgd2hpbGUgKCFjYXRhbG9nRmlsZXMuaXNFbXB0eSgpKSB7Ci0gICAgICBTdHJpbmcgY2F0ZmlsZSA9IChTdHJpbmcpIGNhdGFsb2dGaWxlcy5lbGVtZW50QXQoMCk7Ci0gICAgICB0cnkgewotICAgICAgICBjYXRhbG9nRmlsZXMucmVtb3ZlKDApOwotICAgICAgfSBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgLy8gY2FuJ3QgaGFwcGVuCi0gICAgICB9Ci0KLSAgICAgIGlmIChjYXRhbG9nRW50cmllcy5zaXplKCkgPT0gMCAmJiBjYXRhbG9ncy5zaXplKCkgPT0gMCkgewotICAgICAgICAvLyBXZSBoYXZlbid0IHBhcnNlZCBhbnkgY2F0YWxvZ3MgeWV0LCBsZXQgdGhpcwotICAgICAgICAvLyBjYXRhbG9nIGJlIHRoZSBmaXJzdC4uLgotICAgICAgICB0cnkgewotICAgICAgICAgIHBhcnNlQ2F0YWxvZ0ZpbGUoY2F0ZmlsZSk7Ci0gICAgICAgIH0gY2F0Y2ggKENhdGFsb2dFeGNlcHRpb24gY2UpIHsKLSAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkZJWE1FOiAiICsgY2UudG9TdHJpbmcoKSk7Ci0gICAgICAgIH0KLSAgICAgIH0gZWxzZSB7Ci0gICAgICAgIC8vIFRoaXMgaXMgYSBzdWJvcmRpbmF0ZSBjYXRhbG9nLiBXZSBzYXZlIGl0cyBuYW1lLAotICAgICAgICAvLyBidXQgZG9uJ3QgYm90aGVyIHRvIGxvYWQgaXQgdW5sZXNzIGl0J3MgbmVjZXNzYXJ5LgotICAgICAgICBjYXRhbG9ncy5hZGRFbGVtZW50KGNhdGZpbGUpOwotICAgICAgfQotCi0gICAgICBpZiAoIWxvY2FsQ2F0YWxvZ0ZpbGVzLmlzRW1wdHkoKSkgewotICAgICAgICAvLyBNb3ZlIGFsbCB0aGUgbG9jYWxDYXRhbG9nRmlsZXMgaW50byB0aGUgZnJvbnQgb2YKLSAgICAgICAgLy8gdGhlIGNhdGFsb2dGaWxlcyBxdWV1ZQotICAgICAgICBWZWN0b3IgbmV3UXVldWUgPSBuZXcgVmVjdG9yKCk7Ci0gICAgICAgIEVudW1lcmF0aW9uIHEgPSBsb2NhbENhdGFsb2dGaWxlcy5lbGVtZW50cygpOwotICAgICAgICB3aGlsZSAocS5oYXNNb3JlRWxlbWVudHMoKSkgewotICAgICAgICAgIG5ld1F1ZXVlLmFkZEVsZW1lbnQocS5uZXh0RWxlbWVudCgpKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIFB1dCB0aGUgcmVzdCBvZiB0aGUgY2F0YWxvZ3Mgb24gdGhlIGVuZCBvZiB0aGUgbmV3IGxpc3QKLSAgICAgICAgZm9yIChpbnQgY3VyQ2F0ID0gMDsgY3VyQ2F0IDwgY2F0YWxvZ0ZpbGVzLnNpemUoKTsgY3VyQ2F0KyspIHsKLSAgICAgICAgICBjYXRmaWxlID0gKFN0cmluZykgY2F0YWxvZ0ZpbGVzLmVsZW1lbnRBdChjdXJDYXQpOwotICAgICAgICAgIG5ld1F1ZXVlLmFkZEVsZW1lbnQoY2F0ZmlsZSk7Ci0gICAgICAgIH0KLQotICAgICAgICBjYXRhbG9nRmlsZXMgPSBuZXdRdWV1ZTsKLSAgICAgICAgbG9jYWxDYXRhbG9nRmlsZXMuY2xlYXIoKTsKLSAgICAgIH0KLQotICAgICAgaWYgKCFsb2NhbERlbGVnYXRlLmlzRW1wdHkoKSkgewotICAgICAgICBFbnVtZXJhdGlvbiBlID0gbG9jYWxEZWxlZ2F0ZS5lbGVtZW50cygpOwotICAgICAgICB3aGlsZSAoZS5oYXNNb3JlRWxlbWVudHMoKSkgewotICAgICAgICAgIGNhdGFsb2dFbnRyaWVzLmFkZEVsZW1lbnQoZS5uZXh0RWxlbWVudCgpKTsKLSAgICAgICAgfQotICAgICAgICBsb2NhbERlbGVnYXRlLmNsZWFyKCk7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgLy8gV2UndmUgcGFyc2VkIHRoZW0gYWxsLCByZWluaXQgdGhlIHZlY3Rvci4uLgotICAgIGNhdGFsb2dGaWxlcy5jbGVhcigpOwotICB9Ci0KLSAgLyoqCi0gICAqIFBhcnNlIGEgc2luZ2xlIGNhdGFsb2cgZmlsZSwgYXVnbWVudGluZyBpbnRlcm5hbCBkYXRhIHN0cnVjdHVyZXMuCi0gICAqCi0gICAqIEBwYXJhbSBmaWxlTmFtZSBUaGUgZmlsZW5hbWUgb2YgdGhlIGNhdGFsb2cgZmlsZSB0byBwcm9jZXNzCi0gICAqCi0gICAqIEB0aHJvd3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uIFRoZSBmaWxlTmFtZSBjYW5ub3QgYmUgdHVybmVkIGludG8KLSAgICogYSB2YWxpZCBVUkwuCi0gICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gRXJyb3IgcmVhZGluZyBjYXRhbG9nIGZpbGUuCi0gICAqLwotICBwcm90ZWN0ZWQgc3luY2hyb25pemVkIHZvaWQgcGFyc2VDYXRhbG9nRmlsZShTdHJpbmcgZmlsZU5hbWUpCi0gICAgdGhyb3dzIE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24sIENhdGFsb2dFeGNlcHRpb24gewotCi0gICAgQ2F0YWxvZ0VudHJ5IGVudHJ5OwotCi0gICAgLy8gVGhlIGJhc2UtYmFzZSBpcyB0aGUgY3dkLiBJZiB0aGUgY2F0YWxvZyBmaWxlIGlzIHNwZWNpZmllZAotICAgIC8vIHdpdGggYSByZWxhdGl2ZSBwYXRoLCB0aGlzIGFzc3VyZXMgdGhhdCBpdCBnZXRzIHJlc29sdmVkCi0gICAgLy8gcHJvcGVybHkuLi4KLSAgICB0cnkgewotICAgICAgLy8gdGFjayBvbiBhIGJhc2VuYW1lIGJlY2F1c2UgVVJMcyBwb2ludCB0byBmaWxlcyBub3QgZGlycwotICAgICAgY2F0YWxvZ0N3ZCA9IEZpbGVVUkwubWFrZVVSTCgiYmFzZW5hbWUiKTsKLSAgICB9IGNhdGNoIChNYWxmb3JtZWRVUkxFeGNlcHRpb24gZSkgewotICAgICAgY2F0YWxvZ01hbmFnZXIuZGVidWcubWVzc2FnZSgxLCAiTWFsZm9ybWVkIFVSTCBvbiBjd2QiLCAidXNlci5kaXIiKTsKLSAgICAgIGNhdGFsb2dDd2QgPSBudWxsOwotICAgIH0KLQotICAgIC8vIFRoZSBpbml0aWFsIGJhc2UgVVJJIGlzIHRoZSBsb2NhdGlvbiBvZiB0aGUgY2F0YWxvZyBmaWxlCi0gICAgdHJ5IHsKLSAgICAgIGJhc2UgPSBuZXcgVVJMKGNhdGFsb2dDd2QsIGZpeFNsYXNoZXMoZmlsZU5hbWUpKTsKLSAgICB9IGNhdGNoIChNYWxmb3JtZWRVUkxFeGNlcHRpb24gZSkgewotICAgICAgdHJ5IHsKLSAgICAgICAgYmFzZSA9IG5ldyBVUkwoImZpbGU6IiArIGZpeFNsYXNoZXMoZmlsZU5hbWUpKTsKLSAgICAgIH0gY2F0Y2ggKE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiBlMikgewotICAgICAgICBjYXRhbG9nTWFuYWdlci5kZWJ1Zy5tZXNzYWdlKDEsICJNYWxmb3JtZWQgVVJMIG9uIGNhdGFsb2cgZmlsZW5hbWUiLAotICAgICAgICAgICAgICAgICAgICAgIGZpeFNsYXNoZXMoZmlsZU5hbWUpKTsKLSAgICAgICAgYmFzZSA9IG51bGw7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgY2F0YWxvZ01hbmFnZXIuZGVidWcubWVzc2FnZSgyLCAiTG9hZGluZyBjYXRhbG9nIiwgZmlsZU5hbWUpOwotICAgIGNhdGFsb2dNYW5hZ2VyLmRlYnVnLm1lc3NhZ2UoNCwgIkRlZmF1bHQgQkFTRSIsIGJhc2UudG9TdHJpbmcoKSk7Ci0KLSAgICBmaWxlTmFtZSA9IGJhc2UudG9TdHJpbmcoKTsKLQotICAgIERhdGFJbnB1dFN0cmVhbSBpblN0cmVhbSA9IG51bGw7Ci0gICAgYm9vbGVhbiBwYXJzZWQgPSBmYWxzZTsKLSAgICBib29sZWFuIG5vdEZvdW5kID0gZmFsc2U7Ci0KLSAgICBmb3IgKGludCBjb3VudCA9IDA7ICFwYXJzZWQgJiYgY291bnQgPCByZWFkZXJBcnIuc2l6ZSgpOyBjb3VudCsrKSB7Ci0gICAgICBDYXRhbG9nUmVhZGVyIHJlYWRlciA9IChDYXRhbG9nUmVhZGVyKSByZWFkZXJBcnIuZ2V0KGNvdW50KTsKLQotICAgICAgdHJ5IHsKLSAgICAgICAgbm90Rm91bmQgPSBmYWxzZTsKLSAgICAgICAgaW5TdHJlYW0gPSBuZXcgRGF0YUlucHV0U3RyZWFtKGJhc2Uub3BlblN0cmVhbSgpKTsKLSAgICAgIH0gY2F0Y2ggKEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiBmbmZlKSB7Ci0gICAgICAgIC8vIE5vIGNhdGFsb2c7IGdpdmUgdXAhCi0gICAgICAgIG5vdEZvdW5kID0gdHJ1ZTsKLSAgICAgICAgYnJlYWs7Ci0gICAgICB9Ci0KLSAgICAgIHRyeSB7Ci0gICAgICAgIHJlYWRlci5yZWFkQ2F0YWxvZyh0aGlzLCBpblN0cmVhbSk7Ci0gICAgICAgIHBhcnNlZCA9IHRydWU7Ci0gICAgICB9IGNhdGNoIChDYXRhbG9nRXhjZXB0aW9uIGNlKSB7Ci0gICAgICAgIGlmIChjZS5nZXRFeGNlcHRpb25UeXBlKCkgPT0gQ2F0YWxvZ0V4Y2VwdGlvbi5QQVJTRV9GQUlMRUQpIHsKLSAgICAgICAgICAvLyBnaXZlIHVwIQotICAgICAgICAgIGJyZWFrOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgIC8vIHRyeSBhZ2FpbiEKLSAgICAgICAgfQotICAgICAgfQotCi0gICAgICB0cnkgewotICAgICAgICBpblN0cmVhbS5jbG9zZSgpOwotICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewotICAgICAgICAvL25vcAotICAgICAgfQotICAgIH0KLQotICAgIGlmICghcGFyc2VkKSB7Ci0gICAgICBpZiAobm90Rm91bmQpIHsKLSAgICAgICAgY2F0YWxvZ01hbmFnZXIuZGVidWcubWVzc2FnZSgzLCAiQ2F0YWxvZyBkb2VzIG5vdCBleGlzdCIsIGZpbGVOYW1lKTsKLSAgICAgIH0gZWxzZSB7Ci0gICAgICAgIGNhdGFsb2dNYW5hZ2VyLmRlYnVnLm1lc3NhZ2UoMSwgIkZhaWxlZCB0byBwYXJzZSBjYXRhbG9nIiwgZmlsZU5hbWUpOwotICAgICAgfQotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBDbGVhbnVwIGFuZCBwcm9jZXNzIGEgQ2F0YWxvZyBlbnRyeS4KLSAgICoKLSAgICogPHA+VGhpcyBtZXRob2QgcHJvY2Vzc2VzIGVhY2ggQ2F0YWxvZyBlbnRyeSwgY2hhbmdpbmcgbWFwcGVkCi0gICAqIHJlbGF0aXZlIHN5c3RlbSBpZGVudGlmaWVycyBpbnRvIGFic29sdXRlIG9uZXMgKGJhc2VkIG9uIHRoZSBjdXJyZW50Ci0gICAqIGJhc2UgVVJJKSwgYW5kIG1haW50YWluaW5nIG90aGVyIGluZm9ybWF0aW9uIGFib3V0IHRoZSBjdXJyZW50Ci0gICAqIGNhdGFsb2cuPC9wPgotICAgKgotICAgKiBAcGFyYW0gZW50cnkgVGhlIENhdGFsb2dFbnRyeSB0byBwcm9jZXNzLgotICAgKi8KLSAgcHVibGljIHZvaWQgYWRkRW50cnkoQ2F0YWxvZ0VudHJ5IGVudHJ5KSB7Ci0gICAgaW50IHR5cGUgPSBlbnRyeS5nZXRFbnRyeVR5cGUoKTsKLQotICAgIGlmICh0eXBlID09IEJBU0UpIHsKLSAgICAgIFN0cmluZyB2YWx1ZSA9IGVudHJ5LmdldEVudHJ5QXJnKDApOwotICAgICAgVVJMIG5ld2Jhc2UgPSBudWxsOwotCi0gICAgICBpZiAoYmFzZSA9PSBudWxsKSB7Ci0gICAgICAgIGNhdGFsb2dNYW5hZ2VyLmRlYnVnLm1lc3NhZ2UoNSwgIkJBU0UgQ1VSIiwgIm51bGwiKTsKLSAgICAgIH0gZWxzZSB7Ci0gICAgICAgIGNhdGFsb2dNYW5hZ2VyLmRlYnVnLm1lc3NhZ2UoNSwgIkJBU0UgQ1VSIiwgYmFzZS50b1N0cmluZygpKTsKLSAgICAgIH0KLSAgICAgIGNhdGFsb2dNYW5hZ2VyLmRlYnVnLm1lc3NhZ2UoNCwgIkJBU0UgU1RSIiwgdmFsdWUpOwotCi0gICAgICB0cnkgewotICAgICAgICB2YWx1ZSA9IGZpeFNsYXNoZXModmFsdWUpOwotICAgICAgICBuZXdiYXNlID0gbmV3IFVSTChiYXNlLCB2YWx1ZSk7Ci0gICAgICB9IGNhdGNoIChNYWxmb3JtZWRVUkxFeGNlcHRpb24gZSkgewotICAgICAgICB0cnkgewotICAgICAgICAgIG5ld2Jhc2UgPSBuZXcgVVJMKCJmaWxlOiIgKyB2YWx1ZSk7Ci0gICAgICAgIH0gY2F0Y2ggKE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiBlMikgewotICAgICAgICAgIGNhdGFsb2dNYW5hZ2VyLmRlYnVnLm1lc3NhZ2UoMSwgIk1hbGZvcm1lZCBVUkwgb24gYmFzZSIsIHZhbHVlKTsKLSAgICAgICAgICBuZXdiYXNlID0gbnVsbDsKLSAgICAgICAgfQotICAgICAgfQotCi0gICAgICBpZiAobmV3YmFzZSAhPSBudWxsKSB7Ci0gICAgICAgIGJhc2UgPSBuZXdiYXNlOwotICAgICAgfQotCi0gICAgICBjYXRhbG9nTWFuYWdlci5kZWJ1Zy5tZXNzYWdlKDUsICJCQVNFIE5FVyIsIGJhc2UudG9TdHJpbmcoKSk7Ci0gICAgfSBlbHNlIGlmICh0eXBlID09IENBVEFMT0cpIHsKLSAgICAgIFN0cmluZyBmc2kgPSBtYWtlQWJzb2x1dGUoZW50cnkuZ2V0RW50cnlBcmcoMCkpOwotCi0gICAgICBjYXRhbG9nTWFuYWdlci5kZWJ1Zy5tZXNzYWdlKDQsICJDQVRBTE9HIiwgZnNpKTsKLQotICAgICAgbG9jYWxDYXRhbG9nRmlsZXMuYWRkRWxlbWVudChmc2kpOwotICAgIH0gZWxzZSBpZiAodHlwZSA9PSBQVUJMSUMpIHsKLSAgICAgIFN0cmluZyBwdWJsaWNpZCA9IFB1YmxpY0lkLm5vcm1hbGl6ZShlbnRyeS5nZXRFbnRyeUFyZygwKSk7Ci0gICAgICBTdHJpbmcgc3lzdGVtaWQgPSBtYWtlQWJzb2x1dGUobm9ybWFsaXplVVJJKGVudHJ5LmdldEVudHJ5QXJnKDEpKSk7Ci0KLSAgICAgIGVudHJ5LnNldEVudHJ5QXJnKDAsIHB1YmxpY2lkKTsKLSAgICAgIGVudHJ5LnNldEVudHJ5QXJnKDEsIHN5c3RlbWlkKTsKLQotICAgICAgY2F0YWxvZ01hbmFnZXIuZGVidWcubWVzc2FnZSg0LCAiUFVCTElDIiwgcHVibGljaWQsIHN5c3RlbWlkKTsKLQotICAgICAgY2F0YWxvZ0VudHJpZXMuYWRkRWxlbWVudChlbnRyeSk7Ci0gICAgfSBlbHNlIGlmICh0eXBlID09IFNZU1RFTSkgewotICAgICAgU3RyaW5nIHN5c3RlbWlkID0gbm9ybWFsaXplVVJJKGVudHJ5LmdldEVudHJ5QXJnKDApKTsKLSAgICAgIFN0cmluZyBmc2kgPSBtYWtlQWJzb2x1dGUobm9ybWFsaXplVVJJKGVudHJ5LmdldEVudHJ5QXJnKDEpKSk7Ci0KLSAgICAgIGVudHJ5LnNldEVudHJ5QXJnKDEsIGZzaSk7Ci0KLSAgICAgIGNhdGFsb2dNYW5hZ2VyLmRlYnVnLm1lc3NhZ2UoNCwgIlNZU1RFTSIsIHN5c3RlbWlkLCBmc2kpOwotCi0gICAgICBjYXRhbG9nRW50cmllcy5hZGRFbGVtZW50KGVudHJ5KTsKLSAgICB9IGVsc2UgaWYgKHR5cGUgPT0gVVJJKSB7Ci0gICAgICBTdHJpbmcgdXJpID0gbm9ybWFsaXplVVJJKGVudHJ5LmdldEVudHJ5QXJnKDApKTsKLSAgICAgIFN0cmluZyBhbHRVUkkgPSBtYWtlQWJzb2x1dGUobm9ybWFsaXplVVJJKGVudHJ5LmdldEVudHJ5QXJnKDEpKSk7Ci0KLSAgICAgIGVudHJ5LnNldEVudHJ5QXJnKDEsIGFsdFVSSSk7Ci0KLSAgICAgIGNhdGFsb2dNYW5hZ2VyLmRlYnVnLm1lc3NhZ2UoNCwgIlVSSSIsIHVyaSwgYWx0VVJJKTsKLQotICAgICAgY2F0YWxvZ0VudHJpZXMuYWRkRWxlbWVudChlbnRyeSk7Ci0gICAgfSBlbHNlIGlmICh0eXBlID09IERPQ1VNRU5UKSB7Ci0gICAgICBTdHJpbmcgZnNpID0gbWFrZUFic29sdXRlKG5vcm1hbGl6ZVVSSShlbnRyeS5nZXRFbnRyeUFyZygwKSkpOwotICAgICAgZW50cnkuc2V0RW50cnlBcmcoMCwgZnNpKTsKLQotICAgICAgY2F0YWxvZ01hbmFnZXIuZGVidWcubWVzc2FnZSg0LCAiRE9DVU1FTlQiLCBmc2kpOwotCi0gICAgICBjYXRhbG9nRW50cmllcy5hZGRFbGVtZW50KGVudHJ5KTsKLSAgICB9IGVsc2UgaWYgKHR5cGUgPT0gT1ZFUlJJREUpIHsKLSAgICAgIGNhdGFsb2dNYW5hZ2VyLmRlYnVnLm1lc3NhZ2UoNCwgIk9WRVJSSURFIiwgZW50cnkuZ2V0RW50cnlBcmcoMCkpOwotCi0gICAgICBjYXRhbG9nRW50cmllcy5hZGRFbGVtZW50KGVudHJ5KTsKLSAgICB9IGVsc2UgaWYgKHR5cGUgPT0gU0dNTERFQ0wpIHsKLSAgICAgIC8vIG1lYW5pbmdsZXNzIGluIFhNTAotICAgICAgU3RyaW5nIGZzaSA9IG1ha2VBYnNvbHV0ZShub3JtYWxpemVVUkkoZW50cnkuZ2V0RW50cnlBcmcoMCkpKTsKLSAgICAgIGVudHJ5LnNldEVudHJ5QXJnKDAsIGZzaSk7Ci0KLSAgICAgIGNhdGFsb2dNYW5hZ2VyLmRlYnVnLm1lc3NhZ2UoNCwgIlNHTUxERUNMIiwgZnNpKTsKLQotICAgICAgY2F0YWxvZ0VudHJpZXMuYWRkRWxlbWVudChlbnRyeSk7Ci0gICAgfSBlbHNlIGlmICh0eXBlID09IERFTEVHQVRFX1BVQkxJQykgewotICAgICAgU3RyaW5nIHBwaSA9IFB1YmxpY0lkLm5vcm1hbGl6ZShlbnRyeS5nZXRFbnRyeUFyZygwKSk7Ci0gICAgICBTdHJpbmcgZnNpID0gbWFrZUFic29sdXRlKG5vcm1hbGl6ZVVSSShlbnRyeS5nZXRFbnRyeUFyZygxKSkpOwotCi0gICAgICBlbnRyeS5zZXRFbnRyeUFyZygwLCBwcGkpOwotICAgICAgZW50cnkuc2V0RW50cnlBcmcoMSwgZnNpKTsKLQotICAgICAgY2F0YWxvZ01hbmFnZXIuZGVidWcubWVzc2FnZSg0LCAiREVMRUdBVEVfUFVCTElDIiwgcHBpLCBmc2kpOwotCi0gICAgICBhZGREZWxlZ2F0ZShlbnRyeSk7Ci0gICAgfSBlbHNlIGlmICh0eXBlID09IERFTEVHQVRFX1NZU1RFTSkgewotICAgICAgU3RyaW5nIHBzaSA9IG5vcm1hbGl6ZVVSSShlbnRyeS5nZXRFbnRyeUFyZygwKSk7Ci0gICAgICBTdHJpbmcgZnNpID0gbWFrZUFic29sdXRlKG5vcm1hbGl6ZVVSSShlbnRyeS5nZXRFbnRyeUFyZygxKSkpOwotCi0gICAgICBlbnRyeS5zZXRFbnRyeUFyZygwLCBwc2kpOwotICAgICAgZW50cnkuc2V0RW50cnlBcmcoMSwgZnNpKTsKLQotICAgICAgY2F0YWxvZ01hbmFnZXIuZGVidWcubWVzc2FnZSg0LCAiREVMRUdBVEVfU1lTVEVNIiwgcHNpLCBmc2kpOwotCi0gICAgICBhZGREZWxlZ2F0ZShlbnRyeSk7Ci0gICAgfSBlbHNlIGlmICh0eXBlID09IERFTEVHQVRFX1VSSSkgewotICAgICAgU3RyaW5nIHB1aSA9IG5vcm1hbGl6ZVVSSShlbnRyeS5nZXRFbnRyeUFyZygwKSk7Ci0gICAgICBTdHJpbmcgZnNpID0gbWFrZUFic29sdXRlKG5vcm1hbGl6ZVVSSShlbnRyeS5nZXRFbnRyeUFyZygxKSkpOwotCi0gICAgICBlbnRyeS5zZXRFbnRyeUFyZygwLCBwdWkpOwotICAgICAgZW50cnkuc2V0RW50cnlBcmcoMSwgZnNpKTsKLQotICAgICAgY2F0YWxvZ01hbmFnZXIuZGVidWcubWVzc2FnZSg0LCAiREVMRUdBVEVfVVJJIiwgcHVpLCBmc2kpOwotCi0gICAgICBhZGREZWxlZ2F0ZShlbnRyeSk7Ci0gICAgfSBlbHNlIGlmICh0eXBlID09IFJFV1JJVEVfU1lTVEVNKSB7Ci0gICAgICBTdHJpbmcgcHNpID0gbm9ybWFsaXplVVJJKGVudHJ5LmdldEVudHJ5QXJnKDApKTsKLSAgICAgIFN0cmluZyBycHggPSBtYWtlQWJzb2x1dGUobm9ybWFsaXplVVJJKGVudHJ5LmdldEVudHJ5QXJnKDEpKSk7Ci0KLSAgICAgIGVudHJ5LnNldEVudHJ5QXJnKDAsIHBzaSk7Ci0gICAgICBlbnRyeS5zZXRFbnRyeUFyZygxLCBycHgpOwotCi0gICAgICBjYXRhbG9nTWFuYWdlci5kZWJ1Zy5tZXNzYWdlKDQsICJSRVdSSVRFX1NZU1RFTSIsIHBzaSwgcnB4KTsKLQotICAgICAgY2F0YWxvZ0VudHJpZXMuYWRkRWxlbWVudChlbnRyeSk7Ci0gICAgfSBlbHNlIGlmICh0eXBlID09IFJFV1JJVEVfVVJJKSB7Ci0gICAgICBTdHJpbmcgcHVpID0gbm9ybWFsaXplVVJJKGVudHJ5LmdldEVudHJ5QXJnKDApKTsKLSAgICAgIFN0cmluZyB1cHggPSBtYWtlQWJzb2x1dGUobm9ybWFsaXplVVJJKGVudHJ5LmdldEVudHJ5QXJnKDEpKSk7Ci0KLSAgICAgIGVudHJ5LnNldEVudHJ5QXJnKDAsIHB1aSk7Ci0gICAgICBlbnRyeS5zZXRFbnRyeUFyZygxLCB1cHgpOwotCi0gICAgICBjYXRhbG9nTWFuYWdlci5kZWJ1Zy5tZXNzYWdlKDQsICJSRVdSSVRFX1VSSSIsIHB1aSwgdXB4KTsKLQotICAgICAgY2F0YWxvZ0VudHJpZXMuYWRkRWxlbWVudChlbnRyeSk7Ci0gICAgfSBlbHNlIGlmICh0eXBlID09IFNZU1RFTV9TVUZGSVgpIHsKLSAgICAgIFN0cmluZyBwdWkgPSBub3JtYWxpemVVUkkoZW50cnkuZ2V0RW50cnlBcmcoMCkpOwotICAgICAgU3RyaW5nIHVweCA9IG1ha2VBYnNvbHV0ZShub3JtYWxpemVVUkkoZW50cnkuZ2V0RW50cnlBcmcoMSkpKTsKLQotICAgICAgZW50cnkuc2V0RW50cnlBcmcoMCwgcHVpKTsKLSAgICAgIGVudHJ5LnNldEVudHJ5QXJnKDEsIHVweCk7Ci0KLSAgICAgIGNhdGFsb2dNYW5hZ2VyLmRlYnVnLm1lc3NhZ2UoNCwgIlNZU1RFTV9TVUZGSVgiLCBwdWksIHVweCk7Ci0KLSAgICAgIGNhdGFsb2dFbnRyaWVzLmFkZEVsZW1lbnQoZW50cnkpOwotICAgIH0gZWxzZSBpZiAodHlwZSA9PSBVUklfU1VGRklYKSB7Ci0gICAgICBTdHJpbmcgcHVpID0gbm9ybWFsaXplVVJJKGVudHJ5LmdldEVudHJ5QXJnKDApKTsKLSAgICAgIFN0cmluZyB1cHggPSBtYWtlQWJzb2x1dGUobm9ybWFsaXplVVJJKGVudHJ5LmdldEVudHJ5QXJnKDEpKSk7Ci0KLSAgICAgIGVudHJ5LnNldEVudHJ5QXJnKDAsIHB1aSk7Ci0gICAgICBlbnRyeS5zZXRFbnRyeUFyZygxLCB1cHgpOwotCi0gICAgICBjYXRhbG9nTWFuYWdlci5kZWJ1Zy5tZXNzYWdlKDQsICJVUklfU1VGRklYIiwgcHVpLCB1cHgpOwotCi0gICAgICBjYXRhbG9nRW50cmllcy5hZGRFbGVtZW50KGVudHJ5KTsKLSAgICB9IGVsc2UgaWYgKHR5cGUgPT0gRE9DVFlQRSkgewotICAgICAgU3RyaW5nIGZzaSA9IG1ha2VBYnNvbHV0ZShub3JtYWxpemVVUkkoZW50cnkuZ2V0RW50cnlBcmcoMSkpKTsKLSAgICAgIGVudHJ5LnNldEVudHJ5QXJnKDEsIGZzaSk7Ci0KLSAgICAgIGNhdGFsb2dNYW5hZ2VyLmRlYnVnLm1lc3NhZ2UoNCwgIkRPQ1RZUEUiLCBlbnRyeS5nZXRFbnRyeUFyZygwKSwgZnNpKTsKLQotICAgICAgY2F0YWxvZ0VudHJpZXMuYWRkRWxlbWVudChlbnRyeSk7Ci0gICAgfSBlbHNlIGlmICh0eXBlID09IERURERFQ0wpIHsKLSAgICAgIC8vIG1lYW5pbmdsZXNzIGluIFhNTAotICAgICAgU3RyaW5nIGZwaSA9IFB1YmxpY0lkLm5vcm1hbGl6ZShlbnRyeS5nZXRFbnRyeUFyZygwKSk7Ci0gICAgICBlbnRyeS5zZXRFbnRyeUFyZygwLCBmcGkpOwotICAgICAgU3RyaW5nIGZzaSA9IG1ha2VBYnNvbHV0ZShub3JtYWxpemVVUkkoZW50cnkuZ2V0RW50cnlBcmcoMSkpKTsKLSAgICAgIGVudHJ5LnNldEVudHJ5QXJnKDEsIGZzaSk7Ci0KLSAgICAgIGNhdGFsb2dNYW5hZ2VyLmRlYnVnLm1lc3NhZ2UoNCwgIkRURERFQ0wiLCBmcGksIGZzaSk7Ci0KLSAgICAgIGNhdGFsb2dFbnRyaWVzLmFkZEVsZW1lbnQoZW50cnkpOwotICAgIH0gZWxzZSBpZiAodHlwZSA9PSBFTlRJVFkpIHsKLSAgICAgIFN0cmluZyBmc2kgPSBtYWtlQWJzb2x1dGUobm9ybWFsaXplVVJJKGVudHJ5LmdldEVudHJ5QXJnKDEpKSk7Ci0gICAgICBlbnRyeS5zZXRFbnRyeUFyZygxLCBmc2kpOwotCi0gICAgICBjYXRhbG9nTWFuYWdlci5kZWJ1Zy5tZXNzYWdlKDQsICJFTlRJVFkiLCBlbnRyeS5nZXRFbnRyeUFyZygwKSwgZnNpKTsKLQotICAgICAgY2F0YWxvZ0VudHJpZXMuYWRkRWxlbWVudChlbnRyeSk7Ci0gICAgfSBlbHNlIGlmICh0eXBlID09IExJTktUWVBFKSB7Ci0gICAgICAvLyBtZWFuaW5nbGVzcyBpbiBYTUwKLSAgICAgIFN0cmluZyBmc2kgPSBtYWtlQWJzb2x1dGUobm9ybWFsaXplVVJJKGVudHJ5LmdldEVudHJ5QXJnKDEpKSk7Ci0gICAgICBlbnRyeS5zZXRFbnRyeUFyZygxLCBmc2kpOwotCi0gICAgICBjYXRhbG9nTWFuYWdlci5kZWJ1Zy5tZXNzYWdlKDQsICJMSU5LVFlQRSIsIGVudHJ5LmdldEVudHJ5QXJnKDApLCBmc2kpOwotCi0gICAgICBjYXRhbG9nRW50cmllcy5hZGRFbGVtZW50KGVudHJ5KTsKLSAgICB9IGVsc2UgaWYgKHR5cGUgPT0gTk9UQVRJT04pIHsKLSAgICAgIFN0cmluZyBmc2kgPSBtYWtlQWJzb2x1dGUobm9ybWFsaXplVVJJKGVudHJ5LmdldEVudHJ5QXJnKDEpKSk7Ci0gICAgICBlbnRyeS5zZXRFbnRyeUFyZygxLCBmc2kpOwotCi0gICAgICBjYXRhbG9nTWFuYWdlci5kZWJ1Zy5tZXNzYWdlKDQsICJOT1RBVElPTiIsIGVudHJ5LmdldEVudHJ5QXJnKDApLCBmc2kpOwotCi0gICAgICBjYXRhbG9nRW50cmllcy5hZGRFbGVtZW50KGVudHJ5KTsKLSAgICB9IGVsc2UgewotICAgICAgY2F0YWxvZ0VudHJpZXMuYWRkRWxlbWVudChlbnRyeSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEhhbmRsZSB1bmtub3duIENhdGFsb2dFbnRyeSB0eXBlcy4KLSAgICoKLSAgICogPHA+VGhpcyBtZXRob2QgZXhpc3RzIHRvIGFsbG93IHN1YmNsYXNzZXMgdG8gZGVhbCB3aXRoIHVua25vd24KLSAgICogZW50cnkgdHlwZXMuPC9wPgotICAgKi8KLSAgcHVibGljIHZvaWQgdW5rbm93bkVudHJ5KFZlY3RvciBzdHJpbmdzKSB7Ci0gICAgaWYgKHN0cmluZ3MgIT0gbnVsbCAmJiBzdHJpbmdzLnNpemUoKSA+IDApIHsKLSAgICAgIFN0cmluZyBrZXl3b3JkID0gKFN0cmluZykgc3RyaW5ncy5lbGVtZW50QXQoMCk7Ci0gICAgICBjYXRhbG9nTWFuYWdlci5kZWJ1Zy5tZXNzYWdlKDIsICJVbnJlY29nbml6ZWQgdG9rZW4gcGFyc2luZyBjYXRhbG9nIiwga2V5d29yZCk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFBhcnNlIGFsbCBzdWJvcmRpbmF0ZSBjYXRhbG9ncy4KLSAgICoKLSAgICogPHA+VGhpcyBtZXRob2QgcmVjdXJzaXZlbHkgcGFyc2VzIGFsbCBvZiB0aGUgc3Vib3JkaW5hdGUgY2F0YWxvZ3MuCi0gICAqIElmIHRoaXMgbWV0aG9kIGRvZXMgbm90IHRocm93IGFuIGV4Y2VwdGlvbiwgeW91IGNhbiBiZSBjb25maWRlbnQgdGhhdAotICAgKiBubyBzdWJzZXF1ZW50IGNhbGwgdG8gYW55IHJlc29sdmUqKCkgbWV0aG9kIHdpbGwgZWl0aGVyLCB3aXRoIHR3bwotICAgKiBwb3NzaWJsZSBleGNlcHRpb25zOjwvcD4KLSAgICoKLSAgICogPG9sPgotICAgKiA8bGk+PHA+RGVsZWdhdGVkIGNhdGFsb2dzIGFyZSByZS1wYXJzZWQgZWFjaCB0aW1lIHRoZXkgYXJlIG5lZWRlZAotICAgKiAoYmVjYXVzZSBhIHZhcmlhYmxlIGxpc3Qgb2YgdGhlbSBtYXkgYmUgbmVlZGVkIGluIGVhY2ggY2FzZSwKLSAgICogZGVwZW5kaW5nIG9uIHRoZSBsZW5ndGggb2YgdGhlIG1hdGNoaW5nIHBhcnRpYWwgcHVibGljIGlkZW50aWZpZXIpLjwvcD4KLSAgICogPHA+QnV0IHRoZXkgYXJlIHBhcnNlZCBieSB0aGlzIG1ldGhvZCwgc28gYXMgbG9uZyBhcyB0aGV5IGRvbid0Ci0gICAqIGNoYW5nZSBvciBkaXNhcHBlYXIgd2hpbGUgdGhlIHByb2dyYW0gaXMgcnVubmluZywgdGhleSBzaG91bGRuJ3QKLSAgICogZ2VuZXJhdGUgZXJyb3JzIGxhdGVyIGlmIHRoZXkgZG9uJ3QgZ2VuZXJhdGUgZXJyb3JzIG5vdy48L3A+Ci0gICAqIDxsaT48cD5JZiB5b3UgYWRkIG5ldyBjYXRhbG9ncyB3aXRoIDxjb2RlPnBhcnNlQ2F0YWxvZzwvY29kZT4sIHRoZXkKLSAgICogd29uJ3QgYmUgbG9hZGVkIHVudGlsIHRoZXkgYXJlIG5lZWRlZCBvciB1bnRpbCB5b3UgY2FsbAotICAgKiA8Y29kZT5wYXJzZUFsbENhdGFsb2dzPC9jb2RlPiBhZ2Fpbi48L3A+Ci0gICAqIDwvb2w+Ci0gICAqCi0gICAqIDxwPk9uIHRoZSBvdGhlciBoYW5kLCBpZiB5b3UgZG9uJ3QgY2FsbCB0aGlzIG1ldGhvZCwgeW91IG1heQotICAgKiBzdWNjZXNzZnVsbHkgcGFyc2UgZG9jdW1lbnRzIHdpdGhvdXQgaGF2aW5nIHRvIGxvYWQgYWxsIHBvc3NpYmxlCi0gICAqIGNhdGFsb2dzLjwvcD4KLSAgICoKLSAgICogQHRocm93cyBNYWxmb3JtZWRVUkxFeGNlcHRpb24gVGhlIGZpbGVuYW1lIChVUkwpIGZvciBhCi0gICAqIHN1Ym9yZGluYXRlIG9yIGRlbGVnYXRlZCBjYXRhbG9nIGlzIG5vdCBhIHZhbGlkIFVSTC4KLSAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBFcnJvciByZWFkaW5nIHNvbWUgc3Vib3JkaW5hdGUgb3IgZGVsZWdhdGVkCi0gICAqIGNhdGFsb2cgZmlsZS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHBhcnNlQWxsQ2F0YWxvZ3MoKQotICAgIHRocm93cyBNYWxmb3JtZWRVUkxFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKLQotICAgIC8vIFBhcnNlIGFsbCB0aGUgc3Vib3JkaW5hdGUgY2F0YWxvZ3MKLSAgICBmb3IgKGludCBjYXRQb3MgPSAwOyBjYXRQb3MgPCBjYXRhbG9ncy5zaXplKCk7IGNhdFBvcysrKSB7Ci0gICAgICBDYXRhbG9nIGMgPSBudWxsOwotCi0gICAgICB0cnkgewotICAgICAgICBjID0gKENhdGFsb2cpIGNhdGFsb2dzLmVsZW1lbnRBdChjYXRQb3MpOwotICAgICAgfSBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGUpIHsKLSAgICAgICAgU3RyaW5nIGNhdGZpbGUgPSAoU3RyaW5nKSBjYXRhbG9ncy5lbGVtZW50QXQoY2F0UG9zKTsKLSAgICAgICAgYyA9IG5ld0NhdGFsb2coKTsKLQotICAgICAgICBjLnBhcnNlQ2F0YWxvZyhjYXRmaWxlKTsKLSAgICAgICAgY2F0YWxvZ3Muc2V0RWxlbWVudEF0KGMsIGNhdFBvcyk7Ci0gICAgICAgIGMucGFyc2VBbGxDYXRhbG9ncygpOwotICAgICAgfQotICAgIH0KLQotICAgIC8vIFBhcnNlIGFsbCB0aGUgREVMRUdBVEUgY2F0YWxvZ3MKLSAgICBFbnVtZXJhdGlvbiBlbiA9IGNhdGFsb2dFbnRyaWVzLmVsZW1lbnRzKCk7Ci0gICAgd2hpbGUgKGVuLmhhc01vcmVFbGVtZW50cygpKSB7Ci0gICAgICBDYXRhbG9nRW50cnkgZSA9IChDYXRhbG9nRW50cnkpIGVuLm5leHRFbGVtZW50KCk7Ci0gICAgICBpZiAoZS5nZXRFbnRyeVR5cGUoKSA9PSBERUxFR0FURV9QVUJMSUMKLSAgICAgICAgICB8fCBlLmdldEVudHJ5VHlwZSgpID09IERFTEVHQVRFX1NZU1RFTQotICAgICAgICAgIHx8IGUuZ2V0RW50cnlUeXBlKCkgPT0gREVMRUdBVEVfVVJJKSB7Ci0gICAgICAgIENhdGFsb2cgZGNhdCA9IG5ld0NhdGFsb2coKTsKLSAgICAgICAgZGNhdC5wYXJzZUNhdGFsb2coZS5nZXRFbnRyeUFyZygxKSk7Ci0gICAgICB9Ci0gICAgfQotICB9Ci0KLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBhcHBsaWNhYmxlIERPQ1RZUEUgc3lzdGVtIGlkZW50aWZpZXIuCi0gICAqCi0gICAqIEBwYXJhbSBlbnRpdHlOYW1lIFRoZSBuYW1lIG9mIHRoZSBlbnRpdHkgKGVsZW1lbnQpIGZvciB3aGljaAotICAgKiBhIGRvY3R5cGUgaXMgcmVxdWlyZWQuCi0gICAqIEBwYXJhbSBwdWJsaWNJZCBUaGUgbm9taW5hbCBwdWJsaWMgaWRlbnRpZmllciBmb3IgdGhlIGRvY3R5cGUKLSAgICogKGFzIHByb3ZpZGVkIGluIHRoZSBzb3VyY2UgZG9jdW1lbnQpLgotICAgKiBAcGFyYW0gc3lzdGVtSWQgVGhlIG5vbWluYWwgc3lzdGVtIGlkZW50aWZpZXIgZm9yIHRoZSBkb2N0eXBlCi0gICAqIChhcyBwcm92aWRlZCBpbiB0aGUgc291cmNlIGRvY3VtZW50KS4KLSAgICoKLSAgICogQHJldHVybiBUaGUgc3lzdGVtIGlkZW50aWZpZXIgdG8gdXNlIGZvciB0aGUgZG9jdHlwZS4KLSAgICoKLSAgICogQHRocm93cyBNYWxmb3JtZWRVUkxFeGNlcHRpb24gVGhlIGZvcm1hbCBzeXN0ZW0gaWRlbnRpZmllciBvZiBhCi0gICAqIHN1Ym9yZGluYXRlIGNhdGFsb2cgY2Fubm90IGJlIHR1cm5lZCBpbnRvIGEgdmFsaWQgVVJMLgotICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIEVycm9yIHJlYWRpbmcgc3Vib3JkaW5hdGUgY2F0YWxvZyBmaWxlLgotICAgKi8KLSAgcHVibGljIFN0cmluZyByZXNvbHZlRG9jdHlwZShTdHJpbmcgZW50aXR5TmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcHVibGljSWQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHN5c3RlbUlkKQotICAgIHRocm93cyBNYWxmb3JtZWRVUkxFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKLSAgICBTdHJpbmcgcmVzb2x2ZWQgPSBudWxsOwotCi0gICAgY2F0YWxvZ01hbmFnZXIuZGVidWcubWVzc2FnZSgzLCAicmVzb2x2ZURvY3R5cGUoIgotICAgICAgICAgICAgICAgICAgK2VudGl0eU5hbWUrIiwiK3B1YmxpY0lkKyIsIitzeXN0ZW1JZCsiKSIpOwotCi0gICAgc3lzdGVtSWQgPSBub3JtYWxpemVVUkkoc3lzdGVtSWQpOwotCi0gICAgaWYgKHB1YmxpY0lkICE9IG51bGwgJiYgcHVibGljSWQuc3RhcnRzV2l0aCgidXJuOnB1YmxpY2lkOiIpKSB7Ci0gICAgICBwdWJsaWNJZCA9IFB1YmxpY0lkLmRlY29kZVVSTihwdWJsaWNJZCk7Ci0gICAgfQotCi0gICAgaWYgKHN5c3RlbUlkICE9IG51bGwgJiYgc3lzdGVtSWQuc3RhcnRzV2l0aCgidXJuOnB1YmxpY2lkOiIpKSB7Ci0gICAgICBzeXN0ZW1JZCA9IFB1YmxpY0lkLmRlY29kZVVSTihzeXN0ZW1JZCk7Ci0gICAgICBpZiAocHVibGljSWQgIT0gbnVsbCAmJiAhcHVibGljSWQuZXF1YWxzKHN5c3RlbUlkKSkgewotICAgICAgICBjYXRhbG9nTWFuYWdlci5kZWJ1Zy5tZXNzYWdlKDEsICJ1cm46cHVibGljaWQ6IHN5c3RlbSBpZGVudGlmaWVyIGRpZmZlcnMgZnJvbSBwdWJsaWMgaWRlbnRpZmllcjsgdXNpbmcgcHVibGljIGlkZW50aWZpZXIiKTsKLSAgICAgICAgc3lzdGVtSWQgPSBudWxsOwotICAgICAgfSBlbHNlIHsKLSAgICAgICAgcHVibGljSWQgPSBzeXN0ZW1JZDsKLSAgICAgICAgc3lzdGVtSWQgPSBudWxsOwotICAgICAgfQotICAgIH0KLQotICAgIGlmIChzeXN0ZW1JZCAhPSBudWxsKSB7Ci0gICAgICAvLyBJZiB0aGVyZSdzIGEgU1lTVEVNIGVudHJ5IGluIHRoaXMgY2F0YWxvZywgdXNlIGl0Ci0gICAgICByZXNvbHZlZCA9IHJlc29sdmVMb2NhbFN5c3RlbShzeXN0ZW1JZCk7Ci0gICAgICBpZiAocmVzb2x2ZWQgIT0gbnVsbCkgewotICAgICAgICByZXR1cm4gcmVzb2x2ZWQ7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgaWYgKHB1YmxpY0lkICE9IG51bGwpIHsKLSAgICAgIC8vIElmIHRoZXJlJ3MgYSBQVUJMSUMgZW50cnkgaW4gdGhpcyBjYXRhbG9nLCB1c2UgaXQKLSAgICAgIHJlc29sdmVkID0gcmVzb2x2ZUxvY2FsUHVibGljKERPQ1RZUEUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbnRpdHlOYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVibGljSWQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeXN0ZW1JZCk7Ci0gICAgICBpZiAocmVzb2x2ZWQgIT0gbnVsbCkgewotICAgICAgICByZXR1cm4gcmVzb2x2ZWQ7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgLy8gSWYgdGhlcmUncyBhIERPQ1RZUEUgZW50cnkgaW4gdGhpcyBjYXRhbG9nLCB1c2UgaXQKLSAgICBib29sZWFuIG92ZXIgPSBkZWZhdWx0X292ZXJyaWRlOwotICAgIEVudW1lcmF0aW9uIGVuID0gY2F0YWxvZ0VudHJpZXMuZWxlbWVudHMoKTsKLSAgICB3aGlsZSAoZW4uaGFzTW9yZUVsZW1lbnRzKCkpIHsKLSAgICAgIENhdGFsb2dFbnRyeSBlID0gKENhdGFsb2dFbnRyeSkgZW4ubmV4dEVsZW1lbnQoKTsKLSAgICAgIGlmIChlLmdldEVudHJ5VHlwZSgpID09IE9WRVJSSURFKSB7Ci0gICAgICAgIG92ZXIgPSBlLmdldEVudHJ5QXJnKDApLmVxdWFsc0lnbm9yZUNhc2UoIllFUyIpOwotICAgICAgICBjb250aW51ZTsKLSAgICAgIH0KLQotICAgICAgaWYgKGUuZ2V0RW50cnlUeXBlKCkgPT0gRE9DVFlQRQotICAgICAgICAgICYmIGUuZ2V0RW50cnlBcmcoMCkuZXF1YWxzKGVudGl0eU5hbWUpKSB7Ci0gICAgICAgIGlmIChvdmVyIHx8IHN5c3RlbUlkID09IG51bGwpIHsKLSAgICAgICAgICByZXR1cm4gZS5nZXRFbnRyeUFyZygxKTsKLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLQotICAgIC8vIE90aGVyd2lzZSwgbG9vayBpbiB0aGUgc3Vib3JkaW5hdGUgY2F0YWxvZ3MKLSAgICByZXR1cm4gcmVzb2x2ZVN1Ym9yZGluYXRlQ2F0YWxvZ3MoRE9DVFlQRSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW50aXR5TmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVibGljSWQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5c3RlbUlkKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIGFwcGxpY2FibGUgRE9DVU1FTlQgZW50cnkuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHN5c3RlbSBpZGVudGlmaWVyIHRvIHVzZSBmb3IgdGhlIGRvY3R5cGUuCi0gICAqCi0gICAqIEB0aHJvd3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uIFRoZSBmb3JtYWwgc3lzdGVtIGlkZW50aWZpZXIgb2YgYQotICAgKiBzdWJvcmRpbmF0ZSBjYXRhbG9nIGNhbm5vdCBiZSB0dXJuZWQgaW50byBhIHZhbGlkIFVSTC4KLSAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBFcnJvciByZWFkaW5nIHN1Ym9yZGluYXRlIGNhdGFsb2cgZmlsZS4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgcmVzb2x2ZURvY3VtZW50KCkKLSAgICB0aHJvd3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7Ci0gICAgLy8gSWYgdGhlcmUncyBhIERPQ1VNRU5UIGVudHJ5LCByZXR1cm4gaXQKLQotICAgIGNhdGFsb2dNYW5hZ2VyLmRlYnVnLm1lc3NhZ2UoMywgInJlc29sdmVEb2N1bWVudCIpOwotCi0gICAgRW51bWVyYXRpb24gZW4gPSBjYXRhbG9nRW50cmllcy5lbGVtZW50cygpOwotICAgIHdoaWxlIChlbi5oYXNNb3JlRWxlbWVudHMoKSkgewotICAgICAgQ2F0YWxvZ0VudHJ5IGUgPSAoQ2F0YWxvZ0VudHJ5KSBlbi5uZXh0RWxlbWVudCgpOwotICAgICAgaWYgKGUuZ2V0RW50cnlUeXBlKCkgPT0gRE9DVU1FTlQpIHsKLSAgICAgICAgcmV0dXJuIGUuZ2V0RW50cnlBcmcoMCk7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgcmV0dXJuIHJlc29sdmVTdWJvcmRpbmF0ZUNhdGFsb2dzKERPQ1VNRU5ULAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLCBudWxsLCBudWxsKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIGFwcGxpY2FibGUgRU5USVRZIHN5c3RlbSBpZGVudGlmaWVyLgotICAgKgotICAgKiBAcGFyYW0gZW50aXR5TmFtZSBUaGUgbmFtZSBvZiB0aGUgZW50aXR5IGZvciB3aGljaAotICAgKiBhIHN5c3RlbSBpZGVudGlmaWVyIGlzIHJlcXVpcmVkLgotICAgKiBAcGFyYW0gcHVibGljSWQgVGhlIG5vbWluYWwgcHVibGljIGlkZW50aWZpZXIgZm9yIHRoZSBlbnRpdHkKLSAgICogKGFzIHByb3ZpZGVkIGluIHRoZSBzb3VyY2UgZG9jdW1lbnQpLgotICAgKiBAcGFyYW0gc3lzdGVtSWQgVGhlIG5vbWluYWwgc3lzdGVtIGlkZW50aWZpZXIgZm9yIHRoZSBlbnRpdHkKLSAgICogKGFzIHByb3ZpZGVkIGluIHRoZSBzb3VyY2UgZG9jdW1lbnQpLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBzeXN0ZW0gaWRlbnRpZmllciB0byB1c2UgZm9yIHRoZSBlbnRpdHkuCi0gICAqCi0gICAqIEB0aHJvd3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uIFRoZSBmb3JtYWwgc3lzdGVtIGlkZW50aWZpZXIgb2YgYQotICAgKiBzdWJvcmRpbmF0ZSBjYXRhbG9nIGNhbm5vdCBiZSB0dXJuZWQgaW50byBhIHZhbGlkIFVSTC4KLSAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBFcnJvciByZWFkaW5nIHN1Ym9yZGluYXRlIGNhdGFsb2cgZmlsZS4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgcmVzb2x2ZUVudGl0eShTdHJpbmcgZW50aXR5TmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBwdWJsaWNJZCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBzeXN0ZW1JZCkKLSAgICB0aHJvd3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7Ci0gICAgU3RyaW5nIHJlc29sdmVkID0gbnVsbDsKLQotICAgIGNhdGFsb2dNYW5hZ2VyLmRlYnVnLm1lc3NhZ2UoMywgInJlc29sdmVFbnRpdHkoIgotICAgICAgICAgICAgICAgICAgK2VudGl0eU5hbWUrIiwiK3B1YmxpY0lkKyIsIitzeXN0ZW1JZCsiKSIpOwotCi0gICAgc3lzdGVtSWQgPSBub3JtYWxpemVVUkkoc3lzdGVtSWQpOwotCi0gICAgaWYgKHB1YmxpY0lkICE9IG51bGwgJiYgcHVibGljSWQuc3RhcnRzV2l0aCgidXJuOnB1YmxpY2lkOiIpKSB7Ci0gICAgICBwdWJsaWNJZCA9IFB1YmxpY0lkLmRlY29kZVVSTihwdWJsaWNJZCk7Ci0gICAgfQotCi0gICAgaWYgKHN5c3RlbUlkICE9IG51bGwgJiYgc3lzdGVtSWQuc3RhcnRzV2l0aCgidXJuOnB1YmxpY2lkOiIpKSB7Ci0gICAgICBzeXN0ZW1JZCA9IFB1YmxpY0lkLmRlY29kZVVSTihzeXN0ZW1JZCk7Ci0gICAgICBpZiAocHVibGljSWQgIT0gbnVsbCAmJiAhcHVibGljSWQuZXF1YWxzKHN5c3RlbUlkKSkgewotICAgICAgICBjYXRhbG9nTWFuYWdlci5kZWJ1Zy5tZXNzYWdlKDEsICJ1cm46cHVibGljaWQ6IHN5c3RlbSBpZGVudGlmaWVyIGRpZmZlcnMgZnJvbSBwdWJsaWMgaWRlbnRpZmllcjsgdXNpbmcgcHVibGljIGlkZW50aWZpZXIiKTsKLSAgICAgICAgc3lzdGVtSWQgPSBudWxsOwotICAgICAgfSBlbHNlIHsKLSAgICAgICAgcHVibGljSWQgPSBzeXN0ZW1JZDsKLSAgICAgICAgc3lzdGVtSWQgPSBudWxsOwotICAgICAgfQotICAgIH0KLQotICAgIGlmIChzeXN0ZW1JZCAhPSBudWxsKSB7Ci0gICAgICAvLyBJZiB0aGVyZSdzIGEgU1lTVEVNIGVudHJ5IGluIHRoaXMgY2F0YWxvZywgdXNlIGl0Ci0gICAgICByZXNvbHZlZCA9IHJlc29sdmVMb2NhbFN5c3RlbShzeXN0ZW1JZCk7Ci0gICAgICBpZiAocmVzb2x2ZWQgIT0gbnVsbCkgewotICAgICAgICByZXR1cm4gcmVzb2x2ZWQ7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgaWYgKHB1YmxpY0lkICE9IG51bGwpIHsKLSAgICAgIC8vIElmIHRoZXJlJ3MgYSBQVUJMSUMgZW50cnkgaW4gdGhpcyBjYXRhbG9nLCB1c2UgaXQKLSAgICAgIHJlc29sdmVkID0gcmVzb2x2ZUxvY2FsUHVibGljKEVOVElUWSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVudGl0eU5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwdWJsaWNJZCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5c3RlbUlkKTsKLSAgICAgIGlmIChyZXNvbHZlZCAhPSBudWxsKSB7Ci0gICAgICAgIHJldHVybiByZXNvbHZlZDsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICAvLyBJZiB0aGVyZSdzIGEgRU5USVRZIGVudHJ5IGluIHRoaXMgY2F0YWxvZywgdXNlIGl0Ci0gICAgYm9vbGVhbiBvdmVyID0gZGVmYXVsdF9vdmVycmlkZTsKLSAgICBFbnVtZXJhdGlvbiBlbiA9IGNhdGFsb2dFbnRyaWVzLmVsZW1lbnRzKCk7Ci0gICAgd2hpbGUgKGVuLmhhc01vcmVFbGVtZW50cygpKSB7Ci0gICAgICBDYXRhbG9nRW50cnkgZSA9IChDYXRhbG9nRW50cnkpIGVuLm5leHRFbGVtZW50KCk7Ci0gICAgICBpZiAoZS5nZXRFbnRyeVR5cGUoKSA9PSBPVkVSUklERSkgewotICAgICAgICBvdmVyID0gZS5nZXRFbnRyeUFyZygwKS5lcXVhbHNJZ25vcmVDYXNlKCJZRVMiKTsKLSAgICAgICAgY29udGludWU7Ci0gICAgICB9Ci0KLSAgICAgIGlmIChlLmdldEVudHJ5VHlwZSgpID09IEVOVElUWQotICAgICAgICAgICYmIGUuZ2V0RW50cnlBcmcoMCkuZXF1YWxzKGVudGl0eU5hbWUpKSB7Ci0gICAgICAgIGlmIChvdmVyIHx8IHN5c3RlbUlkID09IG51bGwpIHsKLSAgICAgICAgICByZXR1cm4gZS5nZXRFbnRyeUFyZygxKTsKLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLQotICAgIC8vIE90aGVyd2lzZSwgbG9vayBpbiB0aGUgc3Vib3JkaW5hdGUgY2F0YWxvZ3MKLSAgICByZXR1cm4gcmVzb2x2ZVN1Ym9yZGluYXRlQ2F0YWxvZ3MoRU5USVRZLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbnRpdHlOYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwdWJsaWNJZCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3lzdGVtSWQpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgYXBwbGljYWJsZSBOT1RBVElPTiBzeXN0ZW0gaWRlbnRpZmllci4KLSAgICoKLSAgICogQHBhcmFtIG5vdGF0aW9uTmFtZSBUaGUgbmFtZSBvZiB0aGUgbm90YXRpb24gZm9yIHdoaWNoCi0gICAqIGEgZG9jdHlwZSBpcyByZXF1aXJlZC4KLSAgICogQHBhcmFtIHB1YmxpY0lkIFRoZSBub21pbmFsIHB1YmxpYyBpZGVudGlmaWVyIGZvciB0aGUgbm90YXRpb24KLSAgICogKGFzIHByb3ZpZGVkIGluIHRoZSBzb3VyY2UgZG9jdW1lbnQpLgotICAgKiBAcGFyYW0gc3lzdGVtSWQgVGhlIG5vbWluYWwgc3lzdGVtIGlkZW50aWZpZXIgZm9yIHRoZSBub3RhdGlvbgotICAgKiAoYXMgcHJvdmlkZWQgaW4gdGhlIHNvdXJjZSBkb2N1bWVudCkuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHN5c3RlbSBpZGVudGlmaWVyIHRvIHVzZSBmb3IgdGhlIG5vdGF0aW9uLgotICAgKgotICAgKiBAdGhyb3dzIE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiBUaGUgZm9ybWFsIHN5c3RlbSBpZGVudGlmaWVyIG9mIGEKLSAgICogc3Vib3JkaW5hdGUgY2F0YWxvZyBjYW5ub3QgYmUgdHVybmVkIGludG8gYSB2YWxpZCBVUkwuCi0gICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gRXJyb3IgcmVhZGluZyBzdWJvcmRpbmF0ZSBjYXRhbG9nIGZpbGUuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIHJlc29sdmVOb3RhdGlvbihTdHJpbmcgbm90YXRpb25OYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcHVibGljSWQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBzeXN0ZW1JZCkKLSAgICB0aHJvd3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7Ci0gICAgU3RyaW5nIHJlc29sdmVkID0gbnVsbDsKLQotICAgIGNhdGFsb2dNYW5hZ2VyLmRlYnVnLm1lc3NhZ2UoMywgInJlc29sdmVOb3RhdGlvbigiCi0gICAgICAgICAgICAgICAgICArbm90YXRpb25OYW1lKyIsIitwdWJsaWNJZCsiLCIrc3lzdGVtSWQrIikiKTsKLQotICAgIHN5c3RlbUlkID0gbm9ybWFsaXplVVJJKHN5c3RlbUlkKTsKLQotICAgIGlmIChwdWJsaWNJZCAhPSBudWxsICYmIHB1YmxpY0lkLnN0YXJ0c1dpdGgoInVybjpwdWJsaWNpZDoiKSkgewotICAgICAgcHVibGljSWQgPSBQdWJsaWNJZC5kZWNvZGVVUk4ocHVibGljSWQpOwotICAgIH0KLQotICAgIGlmIChzeXN0ZW1JZCAhPSBudWxsICYmIHN5c3RlbUlkLnN0YXJ0c1dpdGgoInVybjpwdWJsaWNpZDoiKSkgewotICAgICAgc3lzdGVtSWQgPSBQdWJsaWNJZC5kZWNvZGVVUk4oc3lzdGVtSWQpOwotICAgICAgaWYgKHB1YmxpY0lkICE9IG51bGwgJiYgIXB1YmxpY0lkLmVxdWFscyhzeXN0ZW1JZCkpIHsKLSAgICAgICAgY2F0YWxvZ01hbmFnZXIuZGVidWcubWVzc2FnZSgxLCAidXJuOnB1YmxpY2lkOiBzeXN0ZW0gaWRlbnRpZmllciBkaWZmZXJzIGZyb20gcHVibGljIGlkZW50aWZpZXI7IHVzaW5nIHB1YmxpYyBpZGVudGlmaWVyIik7Ci0gICAgICAgIHN5c3RlbUlkID0gbnVsbDsKLSAgICAgIH0gZWxzZSB7Ci0gICAgICAgIHB1YmxpY0lkID0gc3lzdGVtSWQ7Ci0gICAgICAgIHN5c3RlbUlkID0gbnVsbDsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICBpZiAoc3lzdGVtSWQgIT0gbnVsbCkgewotICAgICAgLy8gSWYgdGhlcmUncyBhIFNZU1RFTSBlbnRyeSBpbiB0aGlzIGNhdGFsb2csIHVzZSBpdAotICAgICAgcmVzb2x2ZWQgPSByZXNvbHZlTG9jYWxTeXN0ZW0oc3lzdGVtSWQpOwotICAgICAgaWYgKHJlc29sdmVkICE9IG51bGwpIHsKLSAgICAgICAgcmV0dXJuIHJlc29sdmVkOwotICAgICAgfQotICAgIH0KLQotICAgIGlmIChwdWJsaWNJZCAhPSBudWxsKSB7Ci0gICAgICAvLyBJZiB0aGVyZSdzIGEgUFVCTElDIGVudHJ5IGluIHRoaXMgY2F0YWxvZywgdXNlIGl0Ci0gICAgICByZXNvbHZlZCA9IHJlc29sdmVMb2NhbFB1YmxpYyhOT1RBVElPTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vdGF0aW9uTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHB1YmxpY0lkLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3lzdGVtSWQpOwotICAgICAgaWYgKHJlc29sdmVkICE9IG51bGwpIHsKLSAgICAgICAgcmV0dXJuIHJlc29sdmVkOwotICAgICAgfQotICAgIH0KLQotICAgIC8vIElmIHRoZXJlJ3MgYSBOT1RBVElPTiBlbnRyeSBpbiB0aGlzIGNhdGFsb2csIHVzZSBpdAotICAgIGJvb2xlYW4gb3ZlciA9IGRlZmF1bHRfb3ZlcnJpZGU7Ci0gICAgRW51bWVyYXRpb24gZW4gPSBjYXRhbG9nRW50cmllcy5lbGVtZW50cygpOwotICAgIHdoaWxlIChlbi5oYXNNb3JlRWxlbWVudHMoKSkgewotICAgICAgQ2F0YWxvZ0VudHJ5IGUgPSAoQ2F0YWxvZ0VudHJ5KSBlbi5uZXh0RWxlbWVudCgpOwotICAgICAgaWYgKGUuZ2V0RW50cnlUeXBlKCkgPT0gT1ZFUlJJREUpIHsKLSAgICAgICAgb3ZlciA9IGUuZ2V0RW50cnlBcmcoMCkuZXF1YWxzSWdub3JlQ2FzZSgiWUVTIik7Ci0gICAgICAgIGNvbnRpbnVlOwotICAgICAgfQotCi0gICAgICBpZiAoZS5nZXRFbnRyeVR5cGUoKSA9PSBOT1RBVElPTgotICAgICAgICAgICYmIGUuZ2V0RW50cnlBcmcoMCkuZXF1YWxzKG5vdGF0aW9uTmFtZSkpIHsKLSAgICAgICAgaWYgKG92ZXIgfHwgc3lzdGVtSWQgPT0gbnVsbCkgewotICAgICAgICAgIHJldHVybiBlLmdldEVudHJ5QXJnKDEpOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotCi0gICAgLy8gT3RoZXJ3aXNlLCBsb29rIGluIHRoZSBzdWJvcmRpbmF0ZSBjYXRhbG9ncwotICAgIHJldHVybiByZXNvbHZlU3Vib3JkaW5hdGVDYXRhbG9ncyhOT1RBVElPTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm90YXRpb25OYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwdWJsaWNJZCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3lzdGVtSWQpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgYXBwbGljYWJsZSBQVUJMSUMgb3IgU1lTVEVNIGlkZW50aWZpZXIuCi0gICAqCi0gICAqIDxwPlRoaXMgbWV0aG9kIHNlYXJjaGVzIHRoZSBDYXRhbG9nIGFuZCByZXR1cm5zIHRoZSBzeXN0ZW0KLSAgICogaWRlbnRpZmllciBzcGVjaWZpZWQgZm9yIHRoZSBnaXZlbiBzeXN0ZW0gb3IKLSAgICogcHVibGljIGlkZW50aWZpZXJzLiBJZgotICAgKiBubyBhcHByb3ByaWF0ZSBQVUJMSUMgb3IgU1lTVEVNIGVudHJ5IGlzIGZvdW5kIGluIHRoZSBDYXRhbG9nLAotICAgKiBudWxsIGlzIHJldHVybmVkLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIHB1YmxpY0lkIFRoZSBwdWJsaWMgaWRlbnRpZmllciB0byBsb2NhdGUgaW4gdGhlIGNhdGFsb2cuCi0gICAqIFB1YmxpYyBpZGVudGlmaWVycyBhcmUgbm9ybWFsaXplZCBiZWZvcmUgY29tcGFyaXNvbi4KLSAgICogQHBhcmFtIHN5c3RlbUlkIFRoZSBub21pbmFsIHN5c3RlbSBpZGVudGlmaWVyIGZvciB0aGUgZW50aXR5Ci0gICAqIGluIHF1ZXN0aW9uIChhcyBwcm92aWRlZCBpbiB0aGUgc291cmNlIGRvY3VtZW50KS4KLSAgICoKLSAgICogQHRocm93cyBNYWxmb3JtZWRVUkxFeGNlcHRpb24gVGhlIGZvcm1hbCBzeXN0ZW0gaWRlbnRpZmllciBvZiBhCi0gICAqIHN1Ym9yZGluYXRlIGNhdGFsb2cgY2Fubm90IGJlIHR1cm5lZCBpbnRvIGEgdmFsaWQgVVJMLgotICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIEVycm9yIHJlYWRpbmcgc3Vib3JkaW5hdGUgY2F0YWxvZyBmaWxlLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBzeXN0ZW0gaWRlbnRpZmllciB0byB1c2UuCi0gICAqIE5vdGUgdGhhdCB0aGUgbm9taW5hbCBzeXN0ZW0gaWRlbnRpZmllciBpcyBub3QgcmV0dXJuZWQgaWYgYQotICAgKiBtYXRjaCBpcyBub3QgZm91bmQgaW4gdGhlIGNhdGFsb2csIGluc3RlYWQgbnVsbCBpcyByZXR1cm5lZAotICAgKiB0byBpbmRpY2F0ZSB0aGF0IG5vIG1hdGNoIHdhcyBmb3VuZC4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgcmVzb2x2ZVB1YmxpYyhTdHJpbmcgcHVibGljSWQsIFN0cmluZyBzeXN0ZW1JZCkKLSAgICB0aHJvd3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7Ci0KLSAgICBjYXRhbG9nTWFuYWdlci5kZWJ1Zy5tZXNzYWdlKDMsICJyZXNvbHZlUHVibGljKCIrcHVibGljSWQrIiwiK3N5c3RlbUlkKyIpIik7Ci0KLSAgICBzeXN0ZW1JZCA9IG5vcm1hbGl6ZVVSSShzeXN0ZW1JZCk7Ci0KLSAgICBpZiAocHVibGljSWQgIT0gbnVsbCAmJiBwdWJsaWNJZC5zdGFydHNXaXRoKCJ1cm46cHVibGljaWQ6IikpIHsKLSAgICAgIHB1YmxpY0lkID0gUHVibGljSWQuZGVjb2RlVVJOKHB1YmxpY0lkKTsKLSAgICB9Ci0KLSAgICBpZiAoc3lzdGVtSWQgIT0gbnVsbCAmJiBzeXN0ZW1JZC5zdGFydHNXaXRoKCJ1cm46cHVibGljaWQ6IikpIHsKLSAgICAgIHN5c3RlbUlkID0gUHVibGljSWQuZGVjb2RlVVJOKHN5c3RlbUlkKTsKLSAgICAgIGlmIChwdWJsaWNJZCAhPSBudWxsICYmICFwdWJsaWNJZC5lcXVhbHMoc3lzdGVtSWQpKSB7Ci0gICAgICAgIGNhdGFsb2dNYW5hZ2VyLmRlYnVnLm1lc3NhZ2UoMSwgInVybjpwdWJsaWNpZDogc3lzdGVtIGlkZW50aWZpZXIgZGlmZmVycyBmcm9tIHB1YmxpYyBpZGVudGlmaWVyOyB1c2luZyBwdWJsaWMgaWRlbnRpZmllciIpOwotICAgICAgICBzeXN0ZW1JZCA9IG51bGw7Ci0gICAgICB9IGVsc2UgewotICAgICAgICBwdWJsaWNJZCA9IHN5c3RlbUlkOwotICAgICAgICBzeXN0ZW1JZCA9IG51bGw7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgLy8gSWYgdGhlcmUncyBhIFNZU1RFTSBlbnRyeSBpbiB0aGlzIGNhdGFsb2csIHVzZSBpdAotICAgIGlmIChzeXN0ZW1JZCAhPSBudWxsKSB7Ci0gICAgICBTdHJpbmcgcmVzb2x2ZWQgPSByZXNvbHZlTG9jYWxTeXN0ZW0oc3lzdGVtSWQpOwotICAgICAgaWYgKHJlc29sdmVkICE9IG51bGwpIHsKLSAgICAgICAgcmV0dXJuIHJlc29sdmVkOwotICAgICAgfQotICAgIH0KLQotICAgIC8vIElmIHRoZXJlJ3MgYSBQVUJMSUMgZW50cnkgaW4gdGhpcyBjYXRhbG9nLCB1c2UgaXQKLSAgICBTdHJpbmcgcmVzb2x2ZWQgPSByZXNvbHZlTG9jYWxQdWJsaWMoUFVCTElDLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwdWJsaWNJZCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3lzdGVtSWQpOwotICAgIGlmIChyZXNvbHZlZCAhPSBudWxsKSB7Ci0gICAgICByZXR1cm4gcmVzb2x2ZWQ7Ci0gICAgfQotCi0gICAgLy8gT3RoZXJ3aXNlLCBsb29rIGluIHRoZSBzdWJvcmRpbmF0ZSBjYXRhbG9ncwotICAgIHJldHVybiByZXNvbHZlU3Vib3JkaW5hdGVDYXRhbG9ncyhQVUJMSUMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHB1YmxpY0lkLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeXN0ZW1JZCk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBhcHBsaWNhYmxlIFBVQkxJQyBvciBTWVNURU0gaWRlbnRpZmllci4KLSAgICoKLSAgICogPHA+VGhpcyBtZXRob2Qgc2VhcmNoZXMgdGhlIENhdGFsb2cgYW5kIHJldHVybnMgdGhlIHN5c3RlbQotICAgKiBpZGVudGlmaWVyIHNwZWNpZmllZCBmb3IgdGhlIGdpdmVuIHN5c3RlbSBvciBwdWJsaWMgaWRlbnRpZmllcnMuCi0gICAqIElmIG5vIGFwcHJvcHJpYXRlIFBVQkxJQyBvciBTWVNURU0gZW50cnkgaXMgZm91bmQgaW4gdGhlIENhdGFsb2csCi0gICAqIGRlbGVnYXRlZCBDYXRhbG9ncyBhcmUgaW50ZXJyb2dhdGVkLjwvcD4KLSAgICoKLSAgICogPHA+VGhlcmUgYXJlIGZvdXIgcG9zc2libGUgY2FzZXM6PC9wPgotICAgKgotICAgKiA8dWw+Ci0gICAqIDxsaT5JZiB0aGUgc3lzdGVtIGlkZW50aWZpZXIgcHJvdmlkZWQgbWF0Y2hlcyBhIFNZU1RFTSBlbnRyeQotICAgKiBpbiB0aGUgY3VycmVudCBjYXRhbG9nLCB0aGUgU1lTVEVNIGVudHJ5IGlzIHJldHVybmVkLgotICAgKiA8bGk+SWYgdGhlIHN5c3RlbSBpZGVudGlmaWVyIGlzIG5vdCBudWxsLCB0aGUgUFVCTElDIGVudHJpZXMKLSAgICogdGhhdCB3ZXJlIGVuY291bnRlcmVkIHdoZW4gT1ZFUlJJREUgWUVTIHdhcyBpbiBlZmZlY3QgYXJlCi0gICAqIGludGVycm9nYXRlZCBhbmQgdGhlIGZpcnN0IG1hdGNoaW5nIGVudHJ5IGlzIHJldHVybmVkLjwvbGk+Ci0gICAqIDxsaT5JZiB0aGUgc3lzdGVtIGlkZW50aWZpZXIgaXMgbnVsbCwgdGhlbiBhbGwgb2YgdGhlIFBVQkxJQwotICAgKiBlbnRyaWVzIGFyZSBpbnRlcnJvZ2F0ZWQgYW5kIHRoZSBmaXJzdCBtYXRjaGluZyBlbnRyeQotICAgKiBpcyByZXR1cm5lZC4gVGhpcyBtYXkgbm90IGJlIHRoZSBzYW1lIGFzIHRoZSBwcmVjZWRpbmcgY2FzZSwgaWYKLSAgICogc29tZSBQVUJMSUMgZW50cmllcyBhcmUgZW5jb3VudGVyZWQgd2hlbiBPVkVSUklERSBOTyBpcyBpbiBlZmZlY3QuIEluCi0gICAqIFhNTCwgdGhlIG9ubHkgcGxhY2Ugd2hlcmUgYSBwdWJsaWMgaWRlbnRpZmllciBtYXkgb2NjdXIgd2l0aG91dAotICAgKiBhIHN5c3RlbSBpZGVudGlmaWVyIGlzIGluIGEgbm90YXRpb24gZGVjbGFyYXRpb24uPC9saT4KLSAgICogPGxpPkZpbmFsbHksIGlmIHRoZSBwdWJsaWMgaWRlbnRpZmllciBtYXRjaGVzIG9uZSBvZiB0aGUgcGFydGlhbAotICAgKiBwdWJsaWMgaWRlbnRpZmllcnMgc3BlY2lmaWVkIGluIGEgREVMRUdBVEUqIGVudHJ5IGluCi0gICAqIHRoZSBDYXRhbG9nLCB0aGUgZGVsZWdhdGVkIGNhdGFsb2cgaXMgaW50ZXJyb2dhdGVkLiBUaGUgZmlyc3QKLSAgICogdGltZSB0aGF0IHRoZSBkZWxlZ2F0ZWQgY2F0YWxvZyBpcyByZXF1aXJlZCwgaXQgd2lsbCBiZQotICAgKiByZXRyaWV2ZWQgYW5kIHBhcnNlZC4gSXQgaXMgc3Vic2VxdWVudGx5IGNhY2hlZC4KLSAgICogPC9saT4KLSAgICogPC91bD4KLSAgICoKLSAgICogQHBhcmFtIGVudGl0eVR5cGUgVGhlIENhdGFsb2dFbnRyeSB0eXBlIGZvciB3aGljaCB0aGlzIHF1ZXJ5IGlzCi0gICAqIGJlaW5nIGNvbmR1Y3RlZC4gVGhpcyBpcyBuZWNlc3NhcnkgaW4gb3JkZXIgdG8gZG8gdGhlIGFwcHJvcHJhdGUKLSAgICogcXVlcnkgb24gYSBkZWxlZ2F0ZWQgY2F0YWxvZy4KLSAgICogQHBhcmFtIGVudGl0eU5hbWUgVGhlIG5hbWUgb2YgdGhlIGVudGl0eSBiZWluZyBzZWFyY2hlZCBmb3IsIGlmCi0gICAqIGFwcHJvcHJpYXRlLgotICAgKiBAcGFyYW0gcHVibGljSWQgVGhlIHB1YmxpYyBpZGVudGlmaWVyIG9mIHRoZSBlbnRpdHkgaW4gcXVlc3Rpb24uCi0gICAqIEBwYXJhbSBzeXN0ZW1JZCBUaGUgbm9taW5hbCBzeXN0ZW0gaWRlbnRpZmllciBmb3IgdGhlIGVudGl0eQotICAgKiBpbiBxdWVzdGlvbiAoYXMgcHJvdmlkZWQgaW4gdGhlIHNvdXJjZSBkb2N1bWVudCkuCi0gICAqCi0gICAqIEB0aHJvd3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uIFRoZSBmb3JtYWwgc3lzdGVtIGlkZW50aWZpZXIgb2YgYQotICAgKiBkZWxlZ2F0ZWQgY2F0YWxvZyBjYW5ub3QgYmUgdHVybmVkIGludG8gYSB2YWxpZCBVUkwuCi0gICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gRXJyb3IgcmVhZGluZyBkZWxlZ2F0ZWQgY2F0YWxvZyBmaWxlLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBzeXN0ZW0gaWRlbnRpZmllciB0byB1c2UuCi0gICAqIE5vdGUgdGhhdCB0aGUgbm9taW5hbCBzeXN0ZW0gaWRlbnRpZmllciBpcyBub3QgcmV0dXJuZWQgaWYgYQotICAgKiBtYXRjaCBpcyBub3QgZm91bmQgaW4gdGhlIGNhdGFsb2csIGluc3RlYWQgbnVsbCBpcyByZXR1cm5lZAotICAgKiB0byBpbmRpY2F0ZSB0aGF0IG5vIG1hdGNoIHdhcyBmb3VuZC4KLSAgICovCi0gIHByb3RlY3RlZCBzeW5jaHJvbml6ZWQgU3RyaW5nIHJlc29sdmVMb2NhbFB1YmxpYyhpbnQgZW50aXR5VHlwZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBlbnRpdHlOYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHB1YmxpY0lkLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHN5c3RlbUlkKQotICAgIHRocm93cyBNYWxmb3JtZWRVUkxFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKLQotICAgIC8vIEFsd2F5cyBub3JtYWxpemUgdGhlIHB1YmxpYyBpZGVudGlmaWVyIGJlZm9yZSBhdHRlbXB0aW5nIGEgbWF0Y2gKLSAgICBwdWJsaWNJZCA9IFB1YmxpY0lkLm5vcm1hbGl6ZShwdWJsaWNJZCk7Ci0KLSAgICAvLyBJZiB0aGVyZSdzIGEgU1lTVEVNIGVudHJ5IGluIHRoaXMgY2F0YWxvZywgdXNlIGl0Ci0gICAgaWYgKHN5c3RlbUlkICE9IG51bGwpIHsKLSAgICAgIFN0cmluZyByZXNvbHZlZCA9IHJlc29sdmVMb2NhbFN5c3RlbShzeXN0ZW1JZCk7Ci0gICAgICBpZiAocmVzb2x2ZWQgIT0gbnVsbCkgewotICAgICAgICByZXR1cm4gcmVzb2x2ZWQ7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgLy8gSWYgdGhlcmUncyBhIFBVQkxJQyBlbnRyeSBpbiB0aGlzIGNhdGFsb2csIHVzZSBpdAotICAgIGJvb2xlYW4gb3ZlciA9IGRlZmF1bHRfb3ZlcnJpZGU7Ci0gICAgRW51bWVyYXRpb24gZW4gPSBjYXRhbG9nRW50cmllcy5lbGVtZW50cygpOwotICAgIHdoaWxlIChlbi5oYXNNb3JlRWxlbWVudHMoKSkgewotICAgICAgQ2F0YWxvZ0VudHJ5IGUgPSAoQ2F0YWxvZ0VudHJ5KSBlbi5uZXh0RWxlbWVudCgpOwotICAgICAgaWYgKGUuZ2V0RW50cnlUeXBlKCkgPT0gT1ZFUlJJREUpIHsKLSAgICAgICAgb3ZlciA9IGUuZ2V0RW50cnlBcmcoMCkuZXF1YWxzSWdub3JlQ2FzZSgiWUVTIik7Ci0gICAgICAgIGNvbnRpbnVlOwotICAgICAgfQotCi0gICAgICBpZiAoZS5nZXRFbnRyeVR5cGUoKSA9PSBQVUJMSUMKLSAgICAgICAgICAmJiBlLmdldEVudHJ5QXJnKDApLmVxdWFscyhwdWJsaWNJZCkpIHsKLSAgICAgICAgaWYgKG92ZXIgfHwgc3lzdGVtSWQgPT0gbnVsbCkgewotICAgICAgICAgIHJldHVybiBlLmdldEVudHJ5QXJnKDEpOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotCi0gICAgLy8gSWYgdGhlcmUncyBhIERFTEVHQVRFX1BVQkxJQyBlbnRyeSBpbiB0aGlzIGNhdGFsb2csIHVzZSBpdAotICAgIG92ZXIgPSBkZWZhdWx0X292ZXJyaWRlOwotICAgIGVuID0gY2F0YWxvZ0VudHJpZXMuZWxlbWVudHMoKTsKLSAgICBWZWN0b3IgZGVsQ2F0cyA9IG5ldyBWZWN0b3IoKTsKLSAgICB3aGlsZSAoZW4uaGFzTW9yZUVsZW1lbnRzKCkpIHsKLSAgICAgIENhdGFsb2dFbnRyeSBlID0gKENhdGFsb2dFbnRyeSkgZW4ubmV4dEVsZW1lbnQoKTsKLSAgICAgIGlmIChlLmdldEVudHJ5VHlwZSgpID09IE9WRVJSSURFKSB7Ci0gICAgICAgIG92ZXIgPSBlLmdldEVudHJ5QXJnKDApLmVxdWFsc0lnbm9yZUNhc2UoIllFUyIpOwotICAgICAgICBjb250aW51ZTsKLSAgICAgIH0KLQotICAgICAgaWYgKGUuZ2V0RW50cnlUeXBlKCkgPT0gREVMRUdBVEVfUFVCTElDCi0gICAgICAgICAgJiYgKG92ZXIgfHwgc3lzdGVtSWQgPT0gbnVsbCkpIHsKLSAgICAgICAgU3RyaW5nIHAgPSAoU3RyaW5nKSBlLmdldEVudHJ5QXJnKDApOwotICAgICAgICBpZiAocC5sZW5ndGgoKSA8PSBwdWJsaWNJZC5sZW5ndGgoKQotICAgICAgICAgICAgJiYgcC5lcXVhbHMocHVibGljSWQuc3Vic3RyaW5nKDAsIHAubGVuZ3RoKCkpKSkgewotICAgICAgICAgIC8vIGRlbGVnYXRlIHRoaXMgbWF0Y2ggdG8gdGhlIG90aGVyIGNhdGFsb2cKLQotICAgICAgICAgIGRlbENhdHMuYWRkRWxlbWVudChlLmdldEVudHJ5QXJnKDEpKTsKLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLQotICAgIGlmIChkZWxDYXRzLnNpemUoKSA+IDApIHsKLSAgICAgIEVudW1lcmF0aW9uIGVuQ2F0cyA9IGRlbENhdHMuZWxlbWVudHMoKTsKLQotICAgICAgaWYgKGNhdGFsb2dNYW5hZ2VyLmRlYnVnLmdldERlYnVnKCkgPiAxKSB7Ci0gICAgICAgIGNhdGFsb2dNYW5hZ2VyLmRlYnVnLm1lc3NhZ2UoMiwgIlN3aXRjaGluZyB0byBkZWxlZ2F0ZWQgY2F0YWxvZyhzKToiKTsKLSAgICAgICAgd2hpbGUgKGVuQ2F0cy5oYXNNb3JlRWxlbWVudHMoKSkgewotICAgICAgICAgIFN0cmluZyBkZWxlZ2F0ZWRDYXRhbG9nID0gKFN0cmluZykgZW5DYXRzLm5leHRFbGVtZW50KCk7Ci0gICAgICAgICAgY2F0YWxvZ01hbmFnZXIuZGVidWcubWVzc2FnZSgyLCAiXHQiICsgZGVsZWdhdGVkQ2F0YWxvZyk7Ci0gICAgICAgIH0KLSAgICAgIH0KLQotICAgICAgQ2F0YWxvZyBkY2F0ID0gbmV3Q2F0YWxvZygpOwotCi0gICAgICBlbkNhdHMgPSBkZWxDYXRzLmVsZW1lbnRzKCk7Ci0gICAgICB3aGlsZSAoZW5DYXRzLmhhc01vcmVFbGVtZW50cygpKSB7Ci0gICAgICAgIFN0cmluZyBkZWxlZ2F0ZWRDYXRhbG9nID0gKFN0cmluZykgZW5DYXRzLm5leHRFbGVtZW50KCk7Ci0gICAgICAgIGRjYXQucGFyc2VDYXRhbG9nKGRlbGVnYXRlZENhdGFsb2cpOwotICAgICAgfQotCi0gICAgICByZXR1cm4gZGNhdC5yZXNvbHZlUHVibGljKHB1YmxpY0lkLCBudWxsKTsKLSAgICB9Ci0KLSAgICAvLyBOYWRhIQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgYXBwbGljYWJsZSBTWVNURU0gc3lzdGVtIGlkZW50aWZpZXIuCi0gICAqCi0gICAqIDxwPklmIGEgU1lTVEVNIGVudHJ5IGV4aXN0cyBpbiB0aGUgQ2F0YWxvZwotICAgKiBmb3IgdGhlIHN5c3RlbSBJRCBzcGVjaWZpZWQsIHJldHVybiB0aGUgbWFwcGVkIHZhbHVlLjwvcD4KLSAgICoKLSAgICogPHA+T24gV2luZG93cy1iYXNlZCBvcGVyYXRpbmcgc3lzdGVtcywgdGhlIGNvbXBhcmlzb24gYmV0d2VlbgotICAgKiB0aGUgc3lzdGVtIGlkZW50aWZpZXIgcHJvdmlkZWQgYW5kIHRoZSBTWVNURU0gZW50cmllcyBpbiB0aGUKLSAgICogQ2F0YWxvZyBpcyBjYXNlLWluc2Vuc2l0aXZlLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIHN5c3RlbUlkIFRoZSBzeXN0ZW0gSUQgdG8gbG9jYXRlIGluIHRoZSBjYXRhbG9nLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSByZXNvbHZlZCBzeXN0ZW0gaWRlbnRpZmllci4KLSAgICoKLSAgICogQHRocm93cyBNYWxmb3JtZWRVUkxFeGNlcHRpb24gVGhlIGZvcm1hbCBzeXN0ZW0gaWRlbnRpZmllciBvZiBhCi0gICAqIHN1Ym9yZGluYXRlIGNhdGFsb2cgY2Fubm90IGJlIHR1cm5lZCBpbnRvIGEgdmFsaWQgVVJMLgotICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIEVycm9yIHJlYWRpbmcgc3Vib3JkaW5hdGUgY2F0YWxvZyBmaWxlLgotICAgKi8KLSAgcHVibGljIFN0cmluZyByZXNvbHZlU3lzdGVtKFN0cmluZyBzeXN0ZW1JZCkKLSAgICB0aHJvd3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7Ci0KLSAgICBjYXRhbG9nTWFuYWdlci5kZWJ1Zy5tZXNzYWdlKDMsICJyZXNvbHZlU3lzdGVtKCIrc3lzdGVtSWQrIikiKTsKLQotICAgIHN5c3RlbUlkID0gbm9ybWFsaXplVVJJKHN5c3RlbUlkKTsKLQotICAgIGlmIChzeXN0ZW1JZCAhPSBudWxsICYmIHN5c3RlbUlkLnN0YXJ0c1dpdGgoInVybjpwdWJsaWNpZDoiKSkgewotICAgICAgc3lzdGVtSWQgPSBQdWJsaWNJZC5kZWNvZGVVUk4oc3lzdGVtSWQpOwotICAgICAgcmV0dXJuIHJlc29sdmVQdWJsaWMoc3lzdGVtSWQsIG51bGwpOwotICAgIH0KLQotICAgIC8vIElmIHRoZXJlJ3MgYSBTWVNURU0gZW50cnkgaW4gdGhpcyBjYXRhbG9nLCB1c2UgaXQKLSAgICBpZiAoc3lzdGVtSWQgIT0gbnVsbCkgewotICAgICAgU3RyaW5nIHJlc29sdmVkID0gcmVzb2x2ZUxvY2FsU3lzdGVtKHN5c3RlbUlkKTsKLSAgICAgIGlmIChyZXNvbHZlZCAhPSBudWxsKSB7Ci0gICAgICAgIHJldHVybiByZXNvbHZlZDsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICAvLyBPdGhlcndpc2UsIGxvb2sgaW4gdGhlIHN1Ym9yZGluYXRlIGNhdGFsb2dzCi0gICAgcmV0dXJuIHJlc29sdmVTdWJvcmRpbmF0ZUNhdGFsb2dzKFNZU1RFTSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3lzdGVtSWQpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgYXBwbGljYWJsZSBTWVNURU0gc3lzdGVtIGlkZW50aWZpZXIgaW4gdGhpcwotICAgKiBjYXRhbG9nLgotICAgKgotICAgKiA8cD5JZiBhIFNZU1RFTSBlbnRyeSBleGlzdHMgaW4gdGhlIGNhdGFsb2cgZmlsZQotICAgKiBmb3IgdGhlIHN5c3RlbSBJRCBzcGVjaWZpZWQsIHJldHVybiB0aGUgbWFwcGVkIHZhbHVlLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIHN5c3RlbUlkIFRoZSBzeXN0ZW0gSUQgdG8gbG9jYXRlIGluIHRoZSBjYXRhbG9nCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIG1hcHBlZCBzeXN0ZW0gaWRlbnRpZmllciBvciBudWxsCi0gICAqLwotICBwcm90ZWN0ZWQgU3RyaW5nIHJlc29sdmVMb2NhbFN5c3RlbShTdHJpbmcgc3lzdGVtSWQpCi0gICAgdGhyb3dzIE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewotCi0gICAgU3RyaW5nIG9zbmFtZSA9IFNlY3VyaXR5U3VwcG9ydC5nZXRTeXN0ZW1Qcm9wZXJ0eSgib3MubmFtZSIpOwotICAgIGJvb2xlYW4gd2luZG93cyA9IChvc25hbWUuaW5kZXhPZigiV2luZG93cyIpID49IDApOwotICAgIEVudW1lcmF0aW9uIGVuID0gY2F0YWxvZ0VudHJpZXMuZWxlbWVudHMoKTsKLSAgICB3aGlsZSAoZW4uaGFzTW9yZUVsZW1lbnRzKCkpIHsKLSAgICAgIENhdGFsb2dFbnRyeSBlID0gKENhdGFsb2dFbnRyeSkgZW4ubmV4dEVsZW1lbnQoKTsKLSAgICAgIGlmIChlLmdldEVudHJ5VHlwZSgpID09IFNZU1RFTQotICAgICAgICAgICYmIChlLmdldEVudHJ5QXJnKDApLmVxdWFscyhzeXN0ZW1JZCkKLSAgICAgICAgICAgICAgfHwgKHdpbmRvd3MKLSAgICAgICAgICAgICAgICAgICYmIGUuZ2V0RW50cnlBcmcoMCkuZXF1YWxzSWdub3JlQ2FzZShzeXN0ZW1JZCkpKSkgewotICAgICAgICByZXR1cm4gZS5nZXRFbnRyeUFyZygxKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICAvLyBJZiB0aGVyZSdzIGEgUkVXUklURV9TWVNURU0gZW50cnkgaW4gdGhpcyBjYXRhbG9nLCB1c2UgaXQKLSAgICBlbiA9IGNhdGFsb2dFbnRyaWVzLmVsZW1lbnRzKCk7Ci0gICAgU3RyaW5nIHN0YXJ0U3RyaW5nID0gbnVsbDsKLSAgICBTdHJpbmcgcHJlZml4ID0gbnVsbDsKLSAgICB3aGlsZSAoZW4uaGFzTW9yZUVsZW1lbnRzKCkpIHsKLSAgICAgIENhdGFsb2dFbnRyeSBlID0gKENhdGFsb2dFbnRyeSkgZW4ubmV4dEVsZW1lbnQoKTsKLQotICAgICAgaWYgKGUuZ2V0RW50cnlUeXBlKCkgPT0gUkVXUklURV9TWVNURU0pIHsKLSAgICAgICAgU3RyaW5nIHAgPSAoU3RyaW5nKSBlLmdldEVudHJ5QXJnKDApOwotICAgICAgICBpZiAocC5sZW5ndGgoKSA8PSBzeXN0ZW1JZC5sZW5ndGgoKQotICAgICAgICAgICAgJiYgcC5lcXVhbHMoc3lzdGVtSWQuc3Vic3RyaW5nKDAsIHAubGVuZ3RoKCkpKSkgewotICAgICAgICAgIC8vIElzIHRoaXMgdGhlIGxvbmdlc3QgcHJlZml4PwotICAgICAgICAgIGlmIChzdGFydFN0cmluZyA9PSBudWxsCi0gICAgICAgICAgICAgIHx8IHAubGVuZ3RoKCkgPiBzdGFydFN0cmluZy5sZW5ndGgoKSkgewotICAgICAgICAgICAgc3RhcnRTdHJpbmcgPSBwOwotICAgICAgICAgICAgcHJlZml4ID0gZS5nZXRFbnRyeUFyZygxKTsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICB9Ci0KLSAgICBpZiAocHJlZml4ICE9IG51bGwpIHsKLSAgICAgIC8vIHJldHVybiB0aGUgc3lzdGVtSWQgd2l0aCB0aGUgbmV3IHByZWZpeAotICAgICAgcmV0dXJuIHByZWZpeCArIHN5c3RlbUlkLnN1YnN0cmluZyhzdGFydFN0cmluZy5sZW5ndGgoKSk7Ci0gICAgfQotCi0gICAgLy8gSWYgdGhlcmUncyBhIFNZU1RFTV9TVUZGSVggZW50cnkgaW4gdGhpcyBjYXRhbG9nLCB1c2UgaXQKLSAgICBlbiA9IGNhdGFsb2dFbnRyaWVzLmVsZW1lbnRzKCk7Ci0gICAgU3RyaW5nIHN1ZmZpeFN0cmluZyA9IG51bGw7Ci0gICAgU3RyaW5nIHN1ZmZpeFVSSSA9IG51bGw7Ci0gICAgd2hpbGUgKGVuLmhhc01vcmVFbGVtZW50cygpKSB7Ci0gICAgICBDYXRhbG9nRW50cnkgZSA9IChDYXRhbG9nRW50cnkpIGVuLm5leHRFbGVtZW50KCk7Ci0KLSAgICAgIGlmIChlLmdldEVudHJ5VHlwZSgpID09IFNZU1RFTV9TVUZGSVgpIHsKLSAgICAgICAgU3RyaW5nIHAgPSAoU3RyaW5nKSBlLmdldEVudHJ5QXJnKDApOwotICAgICAgICBpZiAocC5sZW5ndGgoKSA8PSBzeXN0ZW1JZC5sZW5ndGgoKQotICAgICAgICAgICAgJiYgc3lzdGVtSWQuZW5kc1dpdGgocCkpIHsKLSAgICAgICAgICAvLyBJcyB0aGlzIHRoZSBsb25nZXN0IHByZWZpeD8KLSAgICAgICAgICBpZiAoc3VmZml4U3RyaW5nID09IG51bGwKLSAgICAgICAgICAgICAgfHwgcC5sZW5ndGgoKSA+IHN1ZmZpeFN0cmluZy5sZW5ndGgoKSkgewotICAgICAgICAgICAgc3VmZml4U3RyaW5nID0gcDsKLSAgICAgICAgICAgIHN1ZmZpeFVSSSA9IGUuZ2V0RW50cnlBcmcoMSk7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotCi0gICAgaWYgKHN1ZmZpeFVSSSAhPSBudWxsKSB7Ci0gICAgICAvLyByZXR1cm4gdGhlIHN5c3RlbUlkIGZvciB0aGUgc3VmZml4Ci0gICAgICByZXR1cm4gc3VmZml4VVJJOwotICAgIH0KLQotICAgIC8vIElmIHRoZXJlJ3MgYSBERUxFR0FURV9TWVNURU0gZW50cnkgaW4gdGhpcyBjYXRhbG9nLCB1c2UgaXQKLSAgICBlbiA9IGNhdGFsb2dFbnRyaWVzLmVsZW1lbnRzKCk7Ci0gICAgVmVjdG9yIGRlbENhdHMgPSBuZXcgVmVjdG9yKCk7Ci0gICAgd2hpbGUgKGVuLmhhc01vcmVFbGVtZW50cygpKSB7Ci0gICAgICBDYXRhbG9nRW50cnkgZSA9IChDYXRhbG9nRW50cnkpIGVuLm5leHRFbGVtZW50KCk7Ci0KLSAgICAgIGlmIChlLmdldEVudHJ5VHlwZSgpID09IERFTEVHQVRFX1NZU1RFTSkgewotICAgICAgICBTdHJpbmcgcCA9IChTdHJpbmcpIGUuZ2V0RW50cnlBcmcoMCk7Ci0gICAgICAgIGlmIChwLmxlbmd0aCgpIDw9IHN5c3RlbUlkLmxlbmd0aCgpCi0gICAgICAgICAgICAmJiBwLmVxdWFscyhzeXN0ZW1JZC5zdWJzdHJpbmcoMCwgcC5sZW5ndGgoKSkpKSB7Ci0gICAgICAgICAgLy8gZGVsZWdhdGUgdGhpcyBtYXRjaCB0byB0aGUgb3RoZXIgY2F0YWxvZwotCi0gICAgICAgICAgZGVsQ2F0cy5hZGRFbGVtZW50KGUuZ2V0RW50cnlBcmcoMSkpOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotCi0gICAgaWYgKGRlbENhdHMuc2l6ZSgpID4gMCkgewotICAgICAgRW51bWVyYXRpb24gZW5DYXRzID0gZGVsQ2F0cy5lbGVtZW50cygpOwotCi0gICAgICBpZiAoY2F0YWxvZ01hbmFnZXIuZGVidWcuZ2V0RGVidWcoKSA+IDEpIHsKLSAgICAgICAgY2F0YWxvZ01hbmFnZXIuZGVidWcubWVzc2FnZSgyLCAiU3dpdGNoaW5nIHRvIGRlbGVnYXRlZCBjYXRhbG9nKHMpOiIpOwotICAgICAgICB3aGlsZSAoZW5DYXRzLmhhc01vcmVFbGVtZW50cygpKSB7Ci0gICAgICAgICAgU3RyaW5nIGRlbGVnYXRlZENhdGFsb2cgPSAoU3RyaW5nKSBlbkNhdHMubmV4dEVsZW1lbnQoKTsKLSAgICAgICAgICBjYXRhbG9nTWFuYWdlci5kZWJ1Zy5tZXNzYWdlKDIsICJcdCIgKyBkZWxlZ2F0ZWRDYXRhbG9nKTsKLSAgICAgICAgfQotICAgICAgfQotCi0gICAgICBDYXRhbG9nIGRjYXQgPSBuZXdDYXRhbG9nKCk7Ci0KLSAgICAgIGVuQ2F0cyA9IGRlbENhdHMuZWxlbWVudHMoKTsKLSAgICAgIHdoaWxlIChlbkNhdHMuaGFzTW9yZUVsZW1lbnRzKCkpIHsKLSAgICAgICAgU3RyaW5nIGRlbGVnYXRlZENhdGFsb2cgPSAoU3RyaW5nKSBlbkNhdHMubmV4dEVsZW1lbnQoKTsKLSAgICAgICAgZGNhdC5wYXJzZUNhdGFsb2coZGVsZWdhdGVkQ2F0YWxvZyk7Ci0gICAgICB9Ci0KLSAgICAgIHJldHVybiBkY2F0LnJlc29sdmVTeXN0ZW0oc3lzdGVtSWQpOwotICAgIH0KLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgYXBwbGljYWJsZSBVUkkuCi0gICAqCi0gICAqIDxwPklmIGEgVVJJIGVudHJ5IGV4aXN0cyBpbiB0aGUgQ2F0YWxvZwotICAgKiBmb3IgdGhlIFVSSSBzcGVjaWZpZWQsIHJldHVybiB0aGUgbWFwcGVkIHZhbHVlLjwvcD4KLSAgICoKLSAgICogPHA+VVJJIGNvbXBhcmlzb24gaXMgY2FzZSBzZW5zaXRpdmUuPC9wPgotICAgKgotICAgKiBAcGFyYW0gdXJpIFRoZSBVUkkgdG8gbG9jYXRlIGluIHRoZSBjYXRhbG9nLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSByZXNvbHZlZCBVUkkuCi0gICAqCi0gICAqIEB0aHJvd3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uIFRoZSBzeXN0ZW0gaWRlbnRpZmllciBvZiBhCi0gICAqIHN1Ym9yZGluYXRlIGNhdGFsb2cgY2Fubm90IGJlIHR1cm5lZCBpbnRvIGEgdmFsaWQgVVJMLgotICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIEVycm9yIHJlYWRpbmcgc3Vib3JkaW5hdGUgY2F0YWxvZyBmaWxlLgotICAgKi8KLSAgcHVibGljIFN0cmluZyByZXNvbHZlVVJJKFN0cmluZyB1cmkpCi0gICAgdGhyb3dzIE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewotCi0gICAgY2F0YWxvZ01hbmFnZXIuZGVidWcubWVzc2FnZSgzLCAicmVzb2x2ZVVSSSgiK3VyaSsiKSIpOwotCi0gICAgdXJpID0gbm9ybWFsaXplVVJJKHVyaSk7Ci0KLSAgICBpZiAodXJpICE9IG51bGwgJiYgdXJpLnN0YXJ0c1dpdGgoInVybjpwdWJsaWNpZDoiKSkgewotICAgICAgdXJpID0gUHVibGljSWQuZGVjb2RlVVJOKHVyaSk7Ci0gICAgICByZXR1cm4gcmVzb2x2ZVB1YmxpYyh1cmksIG51bGwpOwotICAgIH0KLQotICAgIC8vIElmIHRoZXJlJ3MgYSBVUkkgZW50cnkgaW4gdGhpcyBjYXRhbG9nLCB1c2UgaXQKLSAgICBpZiAodXJpICE9IG51bGwpIHsKLSAgICAgIFN0cmluZyByZXNvbHZlZCA9IHJlc29sdmVMb2NhbFVSSSh1cmkpOwotICAgICAgaWYgKHJlc29sdmVkICE9IG51bGwpIHsKLSAgICAgICAgcmV0dXJuIHJlc29sdmVkOwotICAgICAgfQotICAgIH0KLQotICAgIC8vIE90aGVyd2lzZSwgbG9vayBpbiB0aGUgc3Vib3JkaW5hdGUgY2F0YWxvZ3MKLSAgICByZXR1cm4gcmVzb2x2ZVN1Ym9yZGluYXRlQ2F0YWxvZ3MoVVJJLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cmkpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgYXBwbGljYWJsZSBVUkkgaW4gdGhpcyBjYXRhbG9nLgotICAgKgotICAgKiA8cD5JZiBhIFVSSSBlbnRyeSBleGlzdHMgaW4gdGhlIGNhdGFsb2cgZmlsZQotICAgKiBmb3IgdGhlIFVSSSBzcGVjaWZpZWQsIHJldHVybiB0aGUgbWFwcGVkIHZhbHVlLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIHVyaSBUaGUgVVJJIHRvIGxvY2F0ZSBpbiB0aGUgY2F0YWxvZwotICAgKgotICAgKiBAcmV0dXJuIFRoZSBtYXBwZWQgVVJJIG9yIG51bGwKLSAgICovCi0gIHByb3RlY3RlZCBTdHJpbmcgcmVzb2x2ZUxvY2FsVVJJKFN0cmluZyB1cmkpCi0gICAgdGhyb3dzIE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewotICAgIEVudW1lcmF0aW9uIGVuID0gY2F0YWxvZ0VudHJpZXMuZWxlbWVudHMoKTsKLSAgICB3aGlsZSAoZW4uaGFzTW9yZUVsZW1lbnRzKCkpIHsKLSAgICAgIENhdGFsb2dFbnRyeSBlID0gKENhdGFsb2dFbnRyeSkgZW4ubmV4dEVsZW1lbnQoKTsKLSAgICAgIGlmIChlLmdldEVudHJ5VHlwZSgpID09IFVSSQotICAgICAgICAgICYmIChlLmdldEVudHJ5QXJnKDApLmVxdWFscyh1cmkpKSkgewotICAgICAgICByZXR1cm4gZS5nZXRFbnRyeUFyZygxKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICAvLyBJZiB0aGVyZSdzIGEgUkVXUklURV9VUkkgZW50cnkgaW4gdGhpcyBjYXRhbG9nLCB1c2UgaXQKLSAgICBlbiA9IGNhdGFsb2dFbnRyaWVzLmVsZW1lbnRzKCk7Ci0gICAgU3RyaW5nIHN0YXJ0U3RyaW5nID0gbnVsbDsKLSAgICBTdHJpbmcgcHJlZml4ID0gbnVsbDsKLSAgICB3aGlsZSAoZW4uaGFzTW9yZUVsZW1lbnRzKCkpIHsKLSAgICAgIENhdGFsb2dFbnRyeSBlID0gKENhdGFsb2dFbnRyeSkgZW4ubmV4dEVsZW1lbnQoKTsKLQotICAgICAgaWYgKGUuZ2V0RW50cnlUeXBlKCkgPT0gUkVXUklURV9VUkkpIHsKLSAgICAgICAgU3RyaW5nIHAgPSAoU3RyaW5nKSBlLmdldEVudHJ5QXJnKDApOwotICAgICAgICBpZiAocC5sZW5ndGgoKSA8PSB1cmkubGVuZ3RoKCkKLSAgICAgICAgICAgICYmIHAuZXF1YWxzKHVyaS5zdWJzdHJpbmcoMCwgcC5sZW5ndGgoKSkpKSB7Ci0gICAgICAgICAgLy8gSXMgdGhpcyB0aGUgbG9uZ2VzdCBwcmVmaXg/Ci0gICAgICAgICAgaWYgKHN0YXJ0U3RyaW5nID09IG51bGwKLSAgICAgICAgICAgICAgfHwgcC5sZW5ndGgoKSA+IHN0YXJ0U3RyaW5nLmxlbmd0aCgpKSB7Ci0gICAgICAgICAgICBzdGFydFN0cmluZyA9IHA7Ci0gICAgICAgICAgICBwcmVmaXggPSBlLmdldEVudHJ5QXJnKDEpOwotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLQotICAgIGlmIChwcmVmaXggIT0gbnVsbCkgewotICAgICAgLy8gcmV0dXJuIHRoZSB1cmkgd2l0aCB0aGUgbmV3IHByZWZpeAotICAgICAgcmV0dXJuIHByZWZpeCArIHVyaS5zdWJzdHJpbmcoc3RhcnRTdHJpbmcubGVuZ3RoKCkpOwotICAgIH0KLQotICAgIC8vIElmIHRoZXJlJ3MgYSBVUklfU1VGRklYIGVudHJ5IGluIHRoaXMgY2F0YWxvZywgdXNlIGl0Ci0gICAgZW4gPSBjYXRhbG9nRW50cmllcy5lbGVtZW50cygpOwotICAgIFN0cmluZyBzdWZmaXhTdHJpbmcgPSBudWxsOwotICAgIFN0cmluZyBzdWZmaXhVUkkgPSBudWxsOwotICAgIHdoaWxlIChlbi5oYXNNb3JlRWxlbWVudHMoKSkgewotICAgICAgQ2F0YWxvZ0VudHJ5IGUgPSAoQ2F0YWxvZ0VudHJ5KSBlbi5uZXh0RWxlbWVudCgpOwotCi0gICAgICBpZiAoZS5nZXRFbnRyeVR5cGUoKSA9PSBVUklfU1VGRklYKSB7Ci0gICAgICAgIFN0cmluZyBwID0gKFN0cmluZykgZS5nZXRFbnRyeUFyZygwKTsKLSAgICAgICAgaWYgKHAubGVuZ3RoKCkgPD0gdXJpLmxlbmd0aCgpCi0gICAgICAgICAgICAmJiB1cmkuZW5kc1dpdGgocCkpIHsKLSAgICAgICAgICAvLyBJcyB0aGlzIHRoZSBsb25nZXN0IHByZWZpeD8KLSAgICAgICAgICBpZiAoc3VmZml4U3RyaW5nID09IG51bGwKLSAgICAgICAgICAgICAgfHwgcC5sZW5ndGgoKSA+IHN1ZmZpeFN0cmluZy5sZW5ndGgoKSkgewotICAgICAgICAgICAgc3VmZml4U3RyaW5nID0gcDsKLSAgICAgICAgICAgIHN1ZmZpeFVSSSA9IGUuZ2V0RW50cnlBcmcoMSk7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotCi0gICAgaWYgKHN1ZmZpeFVSSSAhPSBudWxsKSB7Ci0gICAgICAvLyByZXR1cm4gdGhlIHVyaSBmb3IgdGhlIHN1ZmZpeAotICAgICAgcmV0dXJuIHN1ZmZpeFVSSTsKLSAgICB9Ci0KLSAgICAvLyBJZiB0aGVyZSdzIGEgREVMRUdBVEVfVVJJIGVudHJ5IGluIHRoaXMgY2F0YWxvZywgdXNlIGl0Ci0gICAgZW4gPSBjYXRhbG9nRW50cmllcy5lbGVtZW50cygpOwotICAgIFZlY3RvciBkZWxDYXRzID0gbmV3IFZlY3RvcigpOwotICAgIHdoaWxlIChlbi5oYXNNb3JlRWxlbWVudHMoKSkgewotICAgICAgQ2F0YWxvZ0VudHJ5IGUgPSAoQ2F0YWxvZ0VudHJ5KSBlbi5uZXh0RWxlbWVudCgpOwotCi0gICAgICBpZiAoZS5nZXRFbnRyeVR5cGUoKSA9PSBERUxFR0FURV9VUkkpIHsKLSAgICAgICAgU3RyaW5nIHAgPSAoU3RyaW5nKSBlLmdldEVudHJ5QXJnKDApOwotICAgICAgICBpZiAocC5sZW5ndGgoKSA8PSB1cmkubGVuZ3RoKCkKLSAgICAgICAgICAgICYmIHAuZXF1YWxzKHVyaS5zdWJzdHJpbmcoMCwgcC5sZW5ndGgoKSkpKSB7Ci0gICAgICAgICAgLy8gZGVsZWdhdGUgdGhpcyBtYXRjaCB0byB0aGUgb3RoZXIgY2F0YWxvZwotCi0gICAgICAgICAgZGVsQ2F0cy5hZGRFbGVtZW50KGUuZ2V0RW50cnlBcmcoMSkpOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotCi0gICAgaWYgKGRlbENhdHMuc2l6ZSgpID4gMCkgewotICAgICAgRW51bWVyYXRpb24gZW5DYXRzID0gZGVsQ2F0cy5lbGVtZW50cygpOwotCi0gICAgICBpZiAoY2F0YWxvZ01hbmFnZXIuZGVidWcuZ2V0RGVidWcoKSA+IDEpIHsKLSAgICAgICAgY2F0YWxvZ01hbmFnZXIuZGVidWcubWVzc2FnZSgyLCAiU3dpdGNoaW5nIHRvIGRlbGVnYXRlZCBjYXRhbG9nKHMpOiIpOwotICAgICAgICB3aGlsZSAoZW5DYXRzLmhhc01vcmVFbGVtZW50cygpKSB7Ci0gICAgICAgICAgU3RyaW5nIGRlbGVnYXRlZENhdGFsb2cgPSAoU3RyaW5nKSBlbkNhdHMubmV4dEVsZW1lbnQoKTsKLSAgICAgICAgICBjYXRhbG9nTWFuYWdlci5kZWJ1Zy5tZXNzYWdlKDIsICJcdCIgKyBkZWxlZ2F0ZWRDYXRhbG9nKTsKLSAgICAgICAgfQotICAgICAgfQotCi0gICAgICBDYXRhbG9nIGRjYXQgPSBuZXdDYXRhbG9nKCk7Ci0KLSAgICAgIGVuQ2F0cyA9IGRlbENhdHMuZWxlbWVudHMoKTsKLSAgICAgIHdoaWxlIChlbkNhdHMuaGFzTW9yZUVsZW1lbnRzKCkpIHsKLSAgICAgICAgU3RyaW5nIGRlbGVnYXRlZENhdGFsb2cgPSAoU3RyaW5nKSBlbkNhdHMubmV4dEVsZW1lbnQoKTsKLSAgICAgICAgZGNhdC5wYXJzZUNhdGFsb2coZGVsZWdhdGVkQ2F0YWxvZyk7Ci0gICAgICB9Ci0KLSAgICAgIHJldHVybiBkY2F0LnJlc29sdmVVUkkodXJpKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBTZWFyY2ggdGhlIHN1Ym9yZGluYXRlIGNhdGFsb2dzLCBpbiBvcmRlciwgbG9va2luZyBmb3IgYSBtYXRjaC4KLSAgICoKLSAgICogPHA+VGhpcyBtZXRob2Qgc2VhcmNoZXMgdGhlIENhdGFsb2cgYW5kIHJldHVybnMgdGhlIHN5c3RlbQotICAgKiBpZGVudGlmaWVyIHNwZWNpZmllZCBmb3IgdGhlIGdpdmVuIGVudGl0eSB0eXBlIHdpdGggdGhlIGdpdmVuCi0gICAqIG5hbWUsIHB1YmxpYywgYW5kIHN5c3RlbSBpZGVudGlmaWVycy4gSW4gc29tZSBjb250ZXh0cywgdGhlc2UKLSAgICogbWF5IGJlIG51bGwuPC9wPgotICAgKgotICAgKiBAcGFyYW0gZW50aXR5VHlwZSBUaGUgQ2F0YWxvZ0VudHJ5IHR5cGUgZm9yIHdoaWNoIHRoaXMgcXVlcnkgaXMKLSAgICogYmVpbmcgY29uZHVjdGVkLiBUaGlzIGlzIG5lY2Vzc2FyeSBpbiBvcmRlciB0byBkbyB0aGUgYXBwcm9wcmF0ZQotICAgKiBxdWVyeSBvbiBhIHN1Ym9yZGluYXRlIGNhdGFsb2cuCi0gICAqIEBwYXJhbSBlbnRpdHlOYW1lIFRoZSBuYW1lIG9mIHRoZSBlbnRpdHkgYmVpbmcgc2VhcmNoZWQgZm9yLCBpZgotICAgKiBhcHByb3ByaWF0ZS4KLSAgICogQHBhcmFtIHB1YmxpY0lkIFRoZSBwdWJsaWMgaWRlbnRpZmllciBvZiB0aGUgZW50aXR5IGluIHF1ZXN0aW9uCi0gICAqIChhcyBwcm92aWRlZCBpbiB0aGUgc291cmNlIGRvY3VtZW50KS4KLSAgICogQHBhcmFtIHN5c3RlbUlkIFRoZSBub21pbmFsIHN5c3RlbSBpZGVudGlmaWVyIGZvciB0aGUgZW50aXR5Ci0gICAqIGluIHF1ZXN0aW9uIChhcyBwcm92aWRlZCBpbiB0aGUgc291cmNlIGRvY3VtZW50KS4gVGhpcyBwYXJhbWV0ZXIgaXMKLSAgICogb3ZlcmxvYWRlZCBmb3IgdGhlIFVSSSBlbnRyeSB0eXBlLgotICAgKgotICAgKiBAdGhyb3dzIE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiBUaGUgZm9ybWFsIHN5c3RlbSBpZGVudGlmaWVyIG9mIGEKLSAgICogZGVsZWdhdGVkIGNhdGFsb2cgY2Fubm90IGJlIHR1cm5lZCBpbnRvIGEgdmFsaWQgVVJMLgotICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIEVycm9yIHJlYWRpbmcgZGVsZWdhdGVkIGNhdGFsb2cgZmlsZS4KLSAgICoKLSAgICogQHJldHVybiBUaGUgc3lzdGVtIGlkZW50aWZpZXIgdG8gdXNlLgotICAgKiBOb3RlIHRoYXQgdGhlIG5vbWluYWwgc3lzdGVtIGlkZW50aWZpZXIgaXMgbm90IHJldHVybmVkIGlmIGEKLSAgICogbWF0Y2ggaXMgbm90IGZvdW5kIGluIHRoZSBjYXRhbG9nLCBpbnN0ZWFkIG51bGwgaXMgcmV0dXJuZWQKLSAgICogdG8gaW5kaWNhdGUgdGhhdCBubyBtYXRjaCB3YXMgZm91bmQuCi0gICAqLwotICBwcm90ZWN0ZWQgc3luY2hyb25pemVkIFN0cmluZyByZXNvbHZlU3Vib3JkaW5hdGVDYXRhbG9ncyhpbnQgZW50aXR5VHlwZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGVudGl0eU5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBwdWJsaWNJZCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHN5c3RlbUlkKQotICAgIHRocm93cyBNYWxmb3JtZWRVUkxFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKLQotICAgIGZvciAoaW50IGNhdFBvcyA9IDA7IGNhdFBvcyA8IGNhdGFsb2dzLnNpemUoKTsgY2F0UG9zKyspIHsKLSAgICAgIENhdGFsb2cgYyA9IG51bGw7Ci0KLSAgICAgIHRyeSB7Ci0gICAgICAgIGMgPSAoQ2F0YWxvZykgY2F0YWxvZ3MuZWxlbWVudEF0KGNhdFBvcyk7Ci0gICAgICB9IGNhdGNoIChDbGFzc0Nhc3RFeGNlcHRpb24gZSkgewotICAgICAgICBTdHJpbmcgY2F0ZmlsZSA9IChTdHJpbmcpIGNhdGFsb2dzLmVsZW1lbnRBdChjYXRQb3MpOwotICAgICAgICBjID0gbmV3Q2F0YWxvZygpOwotCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgYy5wYXJzZUNhdGFsb2coY2F0ZmlsZSk7Ci0gICAgICAgIH0gY2F0Y2ggKE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiBtdWUpIHsKLSAgICAgICAgICBjYXRhbG9nTWFuYWdlci5kZWJ1Zy5tZXNzYWdlKDEsICJNYWxmb3JtZWQgQ2F0YWxvZyBVUkwiLCBjYXRmaWxlKTsKLSAgICAgICAgfSBjYXRjaCAoRmlsZU5vdEZvdW5kRXhjZXB0aW9uIGZuZmUpIHsKLSAgICAgICAgICBjYXRhbG9nTWFuYWdlci5kZWJ1Zy5tZXNzYWdlKDEsICJGYWlsZWQgdG8gbG9hZCBjYXRhbG9nLCBmaWxlIG5vdCBmb3VuZCIsCi0gICAgICAgICAgICAgICAgICAgICAgICBjYXRmaWxlKTsKLSAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gaW9lKSB7Ci0gICAgICAgICAgY2F0YWxvZ01hbmFnZXIuZGVidWcubWVzc2FnZSgxLCAiRmFpbGVkIHRvIGxvYWQgY2F0YWxvZywgSS9PIGVycm9yIiwgY2F0ZmlsZSk7Ci0gICAgICAgIH0KLQotICAgICAgICBjYXRhbG9ncy5zZXRFbGVtZW50QXQoYywgY2F0UG9zKTsKLSAgICAgIH0KLQotICAgICAgU3RyaW5nIHJlc29sdmVkID0gbnVsbDsKLQotICAgICAgLy8gT2ssIG5vdyB3aGF0IGFyZSB3ZSBzdXBwb3NlZCB0byBjYWxsIGhlcmU/Ci0gICAgICBpZiAoZW50aXR5VHlwZSA9PSBET0NUWVBFKSB7Ci0gICAgICAgIHJlc29sdmVkID0gYy5yZXNvbHZlRG9jdHlwZShlbnRpdHlOYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVibGljSWQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeXN0ZW1JZCk7Ci0gICAgICB9IGVsc2UgaWYgKGVudGl0eVR5cGUgPT0gRE9DVU1FTlQpIHsKLSAgICAgICAgcmVzb2x2ZWQgPSBjLnJlc29sdmVEb2N1bWVudCgpOwotICAgICAgfSBlbHNlIGlmIChlbnRpdHlUeXBlID09IEVOVElUWSkgewotICAgICAgICByZXNvbHZlZCA9IGMucmVzb2x2ZUVudGl0eShlbnRpdHlOYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwdWJsaWNJZCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3lzdGVtSWQpOwotICAgICAgfSBlbHNlIGlmIChlbnRpdHlUeXBlID09IE5PVEFUSU9OKSB7Ci0gICAgICAgIHJlc29sdmVkID0gYy5yZXNvbHZlTm90YXRpb24oZW50aXR5TmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwdWJsaWNJZCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeXN0ZW1JZCk7Ci0gICAgICB9IGVsc2UgaWYgKGVudGl0eVR5cGUgPT0gUFVCTElDKSB7Ci0gICAgICAgIHJlc29sdmVkID0gYy5yZXNvbHZlUHVibGljKHB1YmxpY0lkLCBzeXN0ZW1JZCk7Ci0gICAgICB9IGVsc2UgaWYgKGVudGl0eVR5cGUgPT0gU1lTVEVNKSB7Ci0gICAgICAgIHJlc29sdmVkID0gYy5yZXNvbHZlU3lzdGVtKHN5c3RlbUlkKTsKLSAgICAgIH0gZWxzZSBpZiAoZW50aXR5VHlwZSA9PSBVUkkpIHsKLSAgICAgICAgcmVzb2x2ZWQgPSBjLnJlc29sdmVVUkkoc3lzdGVtSWQpOwotICAgICAgfQotCi0gICAgICBpZiAocmVzb2x2ZWQgIT0gbnVsbCkgewotICAgICAgICByZXR1cm4gcmVzb2x2ZWQ7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotCi0gIC8qKgotICAgKiBSZXBsYWNlIGJhY2tzbGFzaGVzIHdpdGggZm9yd2FyZCBzbGFzaGVzLiAoVVJMcyBhbHdheXMgdXNlCi0gICAqIGZvcndhcmQgc2xhc2hlcy4pCi0gICAqCi0gICAqIEBwYXJhbSBzeXNpZCBUaGUgaW5wdXQgc3lzdGVtIGlkZW50aWZpZXIuCi0gICAqIEByZXR1cm4gVGhlIHNhbWUgc3lzdGVtIGlkZW50aWZpZXIgd2l0aCBiYWNrc2xhc2hlcyB0dXJuZWQgaW50bwotICAgKiBmb3J3YXJkIHNsYXNoZXMuCi0gICAqLwotICBwcm90ZWN0ZWQgU3RyaW5nIGZpeFNsYXNoZXMgKFN0cmluZyBzeXNpZCkgewotICAgIHJldHVybiBzeXNpZC5yZXBsYWNlKCdcXCcsICcvJyk7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IGFuIGFic29sdXRlIFVSSSBmcm9tIGEgcmVsYXRpdmUgb25lLCB1c2luZyB0aGUgY3VycmVudAotICAgKiBiYXNlIFVSSS4KLSAgICoKLSAgICogQHBhcmFtIHN5c2lkIFRoZSAocG9zc2libHkgcmVsYXRpdmUpIHN5c3RlbSBpZGVudGlmaWVyCi0gICAqIEByZXR1cm4gVGhlIHN5c3RlbSBpZGVudGlmaWVyIG1hZGUgYWJzb2x1dGUgd2l0aCByZXNwZWN0IHRvIHRoZQotICAgKiBjdXJyZW50IHtAbGluayAjYmFzZX0uCi0gICAqLwotICBwcm90ZWN0ZWQgU3RyaW5nIG1ha2VBYnNvbHV0ZShTdHJpbmcgc3lzaWQpIHsKLSAgICBVUkwgbG9jYWwgPSBudWxsOwotCi0gICAgc3lzaWQgPSBmaXhTbGFzaGVzKHN5c2lkKTsKLQotICAgIHRyeSB7Ci0gICAgICBsb2NhbCA9IG5ldyBVUkwoYmFzZSwgc3lzaWQpOwotICAgIH0gY2F0Y2ggKE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiBlKSB7Ci0gICAgICBjYXRhbG9nTWFuYWdlci5kZWJ1Zy5tZXNzYWdlKDEsICJNYWxmb3JtZWQgVVJMIG9uIHN5c3RlbSBpZGVudGlmaWVyIiwgc3lzaWQpOwotICAgIH0KLQotICAgIGlmIChsb2NhbCAhPSBudWxsKSB7Ci0gICAgICByZXR1cm4gbG9jYWwudG9TdHJpbmcoKTsKLSAgICB9IGVsc2UgewotICAgICAgcmV0dXJuIHN5c2lkOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBQZXJmb3JtIGNoYXJhY3RlciBub3JtYWxpemF0aW9uIG9uIGEgVVJJIHJlZmVyZW5jZS4KLSAgICoKLSAgICogQHBhcmFtIHVyaXJlZiBUaGUgVVJJIHJlZmVyZW5jZQotICAgKiBAcmV0dXJuIFRoZSBub3JtYWxpemVkIFVSSSByZWZlcmVuY2UuCi0gICAqLwotICBwcm90ZWN0ZWQgU3RyaW5nIG5vcm1hbGl6ZVVSSShTdHJpbmcgdXJpcmVmKSB7Ci0gICAgaWYgKHVyaXJlZiA9PSBudWxsKSB7Ci0gICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICBieXRlW10gYnl0ZXM7Ci0gICAgdHJ5IHsKLSAgICAgIGJ5dGVzID0gdXJpcmVmLmdldEJ5dGVzKCJVVEYtOCIpOwotICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gdWVlKSB7Ci0gICAgICAvLyB0aGlzIGNhbid0IGhhcHBlbgotICAgICAgY2F0YWxvZ01hbmFnZXIuZGVidWcubWVzc2FnZSgxLCAiVVRGLTggaXMgYW4gdW5zdXBwb3J0ZWQgZW5jb2RpbmchPyIpOwotICAgICAgcmV0dXJuIHVyaXJlZjsKLSAgICB9Ci0KLSAgICBTdHJpbmdCdWlsZGVyIG5ld1JlZiA9IG5ldyBTdHJpbmdCdWlsZGVyKGJ5dGVzLmxlbmd0aCk7Ci0gICAgZm9yIChpbnQgY291bnQgPSAwOyBjb3VudCA8IGJ5dGVzLmxlbmd0aDsgY291bnQrKykgewotICAgICAgaW50IGNoID0gYnl0ZXNbY291bnRdICYgMHhGRjsKLQotICAgICAgaWYgKChjaCA8PSAweDIwKSAgICAvLyBjdHJsCi0gICAgICAgICAgfHwgKGNoID4gMHg3RikgIC8vIGhpZ2ggYXNjaWkKLSAgICAgICAgICB8fCAoY2ggPT0gMHgyMikgLy8gIgotICAgICAgICAgIHx8IChjaCA9PSAweDNDKSAvLyA8Ci0gICAgICAgICAgfHwgKGNoID09IDB4M0UpIC8vID4KLSAgICAgICAgICB8fCAoY2ggPT0gMHg1QykgLy8gXAotICAgICAgICAgIHx8IChjaCA9PSAweDVFKSAvLyBeCi0gICAgICAgICAgfHwgKGNoID09IDB4NjApIC8vIGAKLSAgICAgICAgICB8fCAoY2ggPT0gMHg3QikgLy8gewotICAgICAgICAgIHx8IChjaCA9PSAweDdDKSAvLyB8Ci0gICAgICAgICAgfHwgKGNoID09IDB4N0QpIC8vIH0KLSAgICAgICAgICB8fCAoY2ggPT0gMHg3RikpIHsKLSAgICAgICAgbmV3UmVmLmFwcGVuZChlbmNvZGVkQnl0ZShjaCkpOwotICAgICAgfSBlbHNlIHsKLSAgICAgICAgbmV3UmVmLmFwcGVuZCgoY2hhcikgYnl0ZXNbY291bnRdKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gbmV3UmVmLnRvU3RyaW5nKCk7Ci0gIH0KLQotICAvKioKLSAgICogUGVyZm9ybSAlLWVuY29kaW5nIG9uIGEgc2luZ2xlIGJ5dGUuCi0gICAqCi0gICAqIEBwYXJhbSBiIFRoZSA4LWJpdCBpbnRlZ2VyIHRoYXQgcmVwcmVzZW50cyB0aCBieXRlLiAoQnl0ZXMgYXJlIHNpZ25lZAotICAgICAgICAgICAgICBidXQgZW5jb2RpbmcgbmVlZHMgdG8gbG9vayBhdCB0aGUgYnl0ZXMgdW5zaWduZWQuKQotICAgKiBAcmV0dXJuIFRoZSAlLWVuY29kZWQgc3RyaW5nIGZvciB0aGUgYnl0ZSBpbiBxdWVzdGlvbi4KLSAgICovCi0gIHByb3RlY3RlZCBTdHJpbmcgZW5jb2RlZEJ5dGUgKGludCBiKSB7Ci0gICAgU3RyaW5nIGhleCA9IEludGVnZXIudG9IZXhTdHJpbmcoYikudG9VcHBlckNhc2UoKTsKLSAgICBpZiAoaGV4Lmxlbmd0aCgpIDwgMikgewotICAgICAgcmV0dXJuICIlMCIgKyBoZXg7Ci0gICAgfSBlbHNlIHsKLSAgICAgIHJldHVybiAiJSIgKyBoZXg7Ci0gICAgfQotICB9Ci0KLSAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLQotICAvKioKLSAgICogQWRkIHRvIHRoZSBjdXJyZW50IGxpc3Qgb2YgZGVsZWdhdGVkIGNhdGFsb2dzLgotICAgKgotICAgKiA8cD5UaGlzIG1ldGhvZCBhbHdheXMgY29uc3RydWN0cyB0aGUge0BsaW5rICNsb2NhbERlbGVnYXRlfQotICAgKiB2ZWN0b3Igc28gdGhhdCBpdCBpcyBvcmRlcmVkIGJ5IGxlbmd0aCBvZiBwYXJ0aWFsCi0gICAqIHB1YmxpYyBpZGVudGlmaWVyLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIGVudHJ5IFRoZSBERUxFR0FURSBjYXRhbG9nIGVudHJ5Ci0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBhZGREZWxlZ2F0ZShDYXRhbG9nRW50cnkgZW50cnkpIHsKLSAgICBpbnQgcG9zID0gMDsKLSAgICBTdHJpbmcgcGFydGlhbCA9IGVudHJ5LmdldEVudHJ5QXJnKDApOwotCi0gICAgRW51bWVyYXRpb24gbG9jYWwgPSBsb2NhbERlbGVnYXRlLmVsZW1lbnRzKCk7Ci0gICAgd2hpbGUgKGxvY2FsLmhhc01vcmVFbGVtZW50cygpKSB7Ci0gICAgICBDYXRhbG9nRW50cnkgZHBlID0gKENhdGFsb2dFbnRyeSkgbG9jYWwubmV4dEVsZW1lbnQoKTsKLSAgICAgIFN0cmluZyBkcCA9IGRwZS5nZXRFbnRyeUFyZygwKTsKLSAgICAgIGlmIChkcC5lcXVhbHMocGFydGlhbCkpIHsKLSAgICAgICAgLy8gd2UgYWxyZWFkeSBoYXZlIHRoaXMgcHJlZml4Ci0gICAgICAgIHJldHVybjsKLSAgICAgIH0KLSAgICAgIGlmIChkcC5sZW5ndGgoKSA+IHBhcnRpYWwubGVuZ3RoKCkpIHsKLSAgICAgICAgcG9zKys7Ci0gICAgICB9Ci0gICAgICBpZiAoZHAubGVuZ3RoKCkgPCBwYXJ0aWFsLmxlbmd0aCgpKSB7Ci0gICAgICAgIGJyZWFrOwotICAgICAgfQotICAgIH0KLQotICAgIC8vIG5vdyBpbnNlcnQgcGFydGlhbCBpbnRvIHRoZSB2ZWN0b3IgYXQgW3Bvc10KLSAgICBpZiAobG9jYWxEZWxlZ2F0ZS5zaXplKCkgPT0gMCkgewotICAgICAgbG9jYWxEZWxlZ2F0ZS5hZGRFbGVtZW50KGVudHJ5KTsKLSAgICB9IGVsc2UgewotICAgICAgbG9jYWxEZWxlZ2F0ZS5pbnNlcnRFbGVtZW50QXQoZW50cnksIHBvcyk7Ci0gICAgfQotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9yZXNvbHZlci9DYXRhbG9nRW50cnkuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3Jlc29sdmVyL0NhdGFsb2dFbnRyeS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0NGIyYWY5Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3Jlc29sdmVyL0NhdGFsb2dFbnRyeS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjUxICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKi8KLS8qCi0gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKLSAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAotICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgotICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKLSAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCi0gKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLy8gQ2F0YWxvZ0VudHJ5LmphdmEgLSBSZXByZXNlbnRzIENhdGFsb2cgZW50cmllcwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnJlc29sdmVyOwotCi1pbXBvcnQgamF2YS51dGlsLk1hcDsKLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkNvbmN1cnJlbnRIYXNoTWFwOwotaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LmF0b21pYy5BdG9taWNJbnRlZ2VyOwotCi0vKioKLSAqIFJlcHJlc2VudHMgYSBDYXRhbG9nIGVudHJ5LgotICoKLSAqIDxwPkluc3RhbmNlcyBvZiB0aGlzIGNsYXNzIHJlcHJlc2VudCBpbmRpdmlkdWFsIGVudHJpZXMKLSAqIGluIGEgQ2F0YWxvZy48L3A+Ci0gKgotICogPHA+RWFjaCBjYXRhbG9nIGVudHJ5IGhhcyBhIHVuaXF1ZSBuYW1lIGFuZCBpcyBhc3NvY2lhdGVkIHdpdGgKLSAqIGFuIGFyYml0cmFyeSBudW1iZXIgb2YgYXJndW1lbnRzIChhbGwgc3RyaW5ncykuIEZvciBleGFtcGxlLCB0aGUKLSAqIFRSOTQwMSBjYXRhbG9nIGVudHJ5ICJQVUJMSUMiIGhhcyB0d28gYXJndW1lbnRzLCBhIHB1YmxpYyBpZGVudGlmaWVyCi0gKiBhbmQgYSBzeXN0ZW0gaWRlbnRpZmllci4gRWFjaCBlbnRyeSBoYXMgYSB1bmlxdWUgbnVtZXJpYyB0eXBlLAotICogYXNzaWduZWQgYXV0b21hdGljYWxseSB3aGVuIHRoZSBlbnRyeSB0eXBlIGlzIGNyZWF0ZWQuPC9wPgotICoKLSAqIDxwPlRoZSBudW1iZXIgYW5kIHR5cGUgb2YgY2F0YWxvZyBlbnRyaWVzIGlzIG1haW50YWluZWQKLSAqIDxlbT5zdGF0aWNhbGx5PC9lbT4uIENhdGFsb2cgY2xhc3Nlcywgb3IgdGhlaXIgc3ViY2xhc3NlcywgY2FuIGFkZAotICogbmV3IGVudHJ5IHR5cGVzLCBidXQgYWxsIENhdGFsb2cgb2JqZWN0cyBzaGFyZSB0aGUgc2FtZSBnbG9iYWwgcG9vbAotICogb2YgdHlwZXMuPC9wPgotICoKLSAqIDxwPkluaXRpYWxseSB0aGVyZSBhcmUgbm8gdmFsaWQgZW50cmllcy48L3A+Ci0gKgotICogQHNlZSBDYXRhbG9nCi0gKgotICogQGF1dGhvciBOb3JtYW4gV2Fsc2gKLSAqIDxhIGhyZWY9Im1haWx0bzpOb3JtYW4uV2Fsc2hAU3VuLkNPTSI+Tm9ybWFuLldhbHNoQFN1bi5DT008L2E+Ci0gKgotICovCi1wdWJsaWMgY2xhc3MgQ2F0YWxvZ0VudHJ5IHsKLSAgLyoqIFRoZSBuZXh0RW50cnkgaXMgdGhlIG9yZGluYWwgbnVtYmVyIG9mIHRoZSBuZXh0IGVudHJ5IHR5cGUuICovCi0gIHByb3RlY3RlZCBzdGF0aWMgQXRvbWljSW50ZWdlciBuZXh0RW50cnkgPSBuZXcgQXRvbWljSW50ZWdlcigwKTsKLQotICAvKioKLSAgICogVGhlIGVudHJ5VHlwZXMgdmVjdG9yIG1hcHMgY2F0YWxvZyBlbnRyeSBuYW1lcwotICAgKiAoZS5nLiwgJ0JBU0UnIG9yICdTWVNURU0nKSB0byB0aGVpciB0eXBlICgxLCAyLCBldGMuKS4KLSAgICogTmFtZXMgYXJlIGNhc2Ugc2Vuc2l0aXZlLgotICAgKi8KLSAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBNYXA8U3RyaW5nLCBJbnRlZ2VyPiBlbnRyeVR5cGVzID0gbmV3IENvbmN1cnJlbnRIYXNoTWFwPD4oKTsKLQotICAvKiogVGhlIGVudHJ5VHlwZXMgdmVjdG9yIG1hcHMgY2F0YWxvZyBlbnRyeSB0eXBlcyB0byB0aGUKLSAgICAgIG51bWJlciBvZiBhcmd1bWVudHMgdGhleSdyZSByZXF1aXJlZCB0byBoYXZlLiAqLwotICBwcm90ZWN0ZWQgc3RhdGljIFZlY3RvciBlbnRyeUFyZ3MgPSBuZXcgVmVjdG9yKCk7Ci0KLSAgLyoqCi0gICAqIEFkZHMgYSBuZXcgY2F0YWxvZyBlbnRyeSB0eXBlLgotICAgKgotICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgY2F0YWxvZyBlbnRyeSB0eXBlLiBUaGlzIG11c3QgYmUKLSAgICogdW5pcXVlIGFtb25nIGFsbCB0eXBlcyBhbmQgaXMgY2FzZS1zZW5zaXRpdmUuIChBZGRpbmcgYSBkdXBsaWNhdGUKLSAgICogbmFtZSBlZmZlY3RpdmVseSByZXBsYWNlcyB0aGUgb2xkIHR5cGUgd2l0aCB0aGUgbmV3IHR5cGUuKQotICAgKiBAcGFyYW0gbnVtQXJncyBUaGUgbnVtYmVyIG9mIGFyZ3VtZW50cyB0aGF0IHRoaXMgZW50cnkgdHlwZQotICAgKiBpcyByZXF1aXJlZCB0byBoYXZlLiBUaGVyZSBpcyBubyBwcm92aXNpb24gZm9yIHZhcmlhYmxlIG51bWJlcnMKLSAgICogb2YgYXJndW1lbnRzLgotICAgKiBAcmV0dXJuIFRoZSB0eXBlIGZvciB0aGUgbmV3IGVudHJ5LgotICAgKi8KLSAgc3RhdGljIGludCBhZGRFbnRyeVR5cGUoU3RyaW5nIG5hbWUsIGludCBudW1BcmdzKSB7Ci0gICAgZmluYWwgaW50IGluZGV4ID0gbmV4dEVudHJ5LmdldEFuZEluY3JlbWVudCgpOwotICAgIGVudHJ5VHlwZXMucHV0KG5hbWUsIGluZGV4KTsKLSAgICBlbnRyeUFyZ3MuYWRkKGluZGV4LCBudW1BcmdzKTsKLQotICAgIHJldHVybiBpbmRleDsKLSAgfQotCi0gIC8qKgotICAgKiBMb29rdXAgYW4gZW50cnkgdHlwZQotICAgKgotICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgY2F0YWxvZyBlbnRyeSB0eXBlLgotICAgKiBAcmV0dXJuIFRoZSB0eXBlIG9mIHRoZSBjYXRhbG9nIGVudHJ5IHdpdGggdGhlIHNwZWNpZmllZCBuYW1lLgotICAgKiBAdGhyb3dzIEludmFsaWRDYXRhbG9nRW50cnlUeXBlRXhjZXB0aW9uIGlmIG5vIGVudHJ5IGhhcyB0aGUKLSAgICogc3BlY2lmaWVkIG5hbWUuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGludCBnZXRFbnRyeVR5cGUoU3RyaW5nIG5hbWUpCi0gICAgdGhyb3dzIENhdGFsb2dFeGNlcHRpb24gewotICAgIGlmICghZW50cnlUeXBlcy5jb250YWluc0tleShuYW1lKSkgewotICAgICAgdGhyb3cgbmV3IENhdGFsb2dFeGNlcHRpb24oQ2F0YWxvZ0V4Y2VwdGlvbi5JTlZBTElEX0VOVFJZX1RZUEUpOwotICAgIH0KLQotICAgIEludGVnZXIgaVR5cGUgPSBlbnRyeVR5cGVzLmdldChuYW1lKTsKLQotICAgIGlmIChpVHlwZSA9PSBudWxsKSB7Ci0gICAgICB0aHJvdyBuZXcgQ2F0YWxvZ0V4Y2VwdGlvbihDYXRhbG9nRXhjZXB0aW9uLklOVkFMSURfRU5UUllfVFlQRSk7Ci0gICAgfQotCi0gICAgcmV0dXJuIGlUeXBlOwotICB9Ci0KLSAgLyoqCi0gICAqIEZpbmQgb3V0IGhvdyBtYW55IGFyZ3VtZW50cyBhbiBlbnRyeSBpcyByZXF1aXJlZCB0byBoYXZlLgotICAgKgotICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgY2F0YWxvZyBlbnRyeSB0eXBlLgotICAgKiBAcmV0dXJuIFRoZSBudW1iZXIgb2YgYXJndW1lbnRzIHRoYXQgZW50cnkgdHlwZSBpcyByZXF1aXJlZCB0byBoYXZlLgotICAgKiBAdGhyb3dzIEludmFsaWRDYXRhbG9nRW50cnlUeXBlRXhjZXB0aW9uIGlmIG5vIGVudHJ5IGhhcyB0aGUKLSAgICogc3BlY2lmaWVkIG5hbWUuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGludCBnZXRFbnRyeUFyZ0NvdW50KFN0cmluZyBuYW1lKQotICAgIHRocm93cyBDYXRhbG9nRXhjZXB0aW9uIHsKLSAgICByZXR1cm4gZ2V0RW50cnlBcmdDb3VudChnZXRFbnRyeVR5cGUobmFtZSkpOwotICB9Ci0KLSAgLyoqCi0gICAqIEZpbmQgb3V0IGhvdyBtYW55IGFyZ3VtZW50cyBhbiBlbnRyeSBpcyByZXF1aXJlZCB0byBoYXZlLgotICAgKgotICAgKiBAcGFyYW0gdHlwZSBBIHZhbGlkIGNhdGFsb2cgZW50cnkgdHlwZS4KLSAgICogQHJldHVybiBUaGUgbnVtYmVyIG9mIGFyZ3VtZW50cyB0aGF0IGVudHJ5IHR5cGUgaXMgcmVxdWlyZWQgdG8gaGF2ZS4KLSAgICogQHRocm93cyBJbnZhbGlkQ2F0YWxvZ0VudHJ5VHlwZUV4Y2VwdGlvbiBpZiB0aGUgdHlwZSBpcyBpbnZhbGlkLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBpbnQgZ2V0RW50cnlBcmdDb3VudChpbnQgdHlwZSkKLSAgICB0aHJvd3MgQ2F0YWxvZ0V4Y2VwdGlvbiB7Ci0gICAgdHJ5IHsKLSAgICAgIEludGVnZXIgaUFyZ3MgPSAoSW50ZWdlcikgZW50cnlBcmdzLmdldCh0eXBlKTsKLSAgICAgIHJldHVybiBpQXJncy5pbnRWYWx1ZSgpOwotICAgIH0gY2F0Y2ggKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7Ci0gICAgICB0aHJvdyBuZXcgQ2F0YWxvZ0V4Y2VwdGlvbihDYXRhbG9nRXhjZXB0aW9uLklOVkFMSURfRU5UUllfVFlQRSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqIFRoZSBlbnRyeSB0eXBlIG9mIHRoaXMgZW50cnkgKi8KLSAgcHJvdGVjdGVkIGludCBlbnRyeVR5cGUgPSAwOwotCi0gIC8qKiBUaGUgYXJndW1lbnRzIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGVudHJ5ICovCi0gIHByb3RlY3RlZCBWZWN0b3IgYXJncyA9IG51bGw7Ci0KLSAgLyoqCi0gICAqIE51bGwgY29uc3RydWN0b3I7IHNvbWV0aGluZyBmb3Igc3ViY2xhc3NlcyB0byBjYWxsLgotICAgKi8KLSAgcHVibGljIENhdGFsb2dFbnRyeSgpIHt9Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhIGNhdGFsb2cgZW50cnkgb2YgdGhlIHNwZWNpZmllZCB0eXBlLgotICAgKgotICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgZW50cnkgdHlwZQotICAgKiBAcGFyYW0gYXJncyBBIFN0cmluZyBWZWN0b3Igb2YgYXJndW1lbnRzCi0gICAqIEB0aHJvd3MgSW52YWxpZENhdGFsb2dFbnRyeVR5cGVFeGNlcHRpb24gaWYgbm8gc3VjaCBlbnRyeSB0eXBlCi0gICAqIGV4aXN0cy4KLSAgICogQHRocm93cyBJbnZhbGlkQ2F0YWxvZ0VudHJ5RXhjZXB0aW9uIGlmIHRoZSB3cm9uZyBudW1iZXIgb2YgYXJndW1lbnRzCi0gICAqIGlzIHBhc3NlZC4KLSAgICovCi0gIHB1YmxpYyBDYXRhbG9nRW50cnkoU3RyaW5nIG5hbWUsIFZlY3RvciBhcmdzKQotICAgIHRocm93cyBDYXRhbG9nRXhjZXB0aW9uIHsKLSAgICBJbnRlZ2VyIGlUeXBlID0gZW50cnlUeXBlcy5nZXQobmFtZSk7Ci0KLSAgICBpZiAoaVR5cGUgPT0gbnVsbCkgewotICAgICAgdGhyb3cgbmV3IENhdGFsb2dFeGNlcHRpb24oQ2F0YWxvZ0V4Y2VwdGlvbi5JTlZBTElEX0VOVFJZX1RZUEUpOwotICAgIH0KLQotICAgIGludCB0eXBlID0gaVR5cGU7Ci0KLSAgICB0cnkgewotICAgICAgSW50ZWdlciBpQXJncyA9IChJbnRlZ2VyKSBlbnRyeUFyZ3MuZ2V0KHR5cGUpOwotICAgICAgaWYgKGlBcmdzLmludFZhbHVlKCkgIT0gYXJncy5zaXplKCkpIHsKLSAgICAgICAgdGhyb3cgbmV3IENhdGFsb2dFeGNlcHRpb24oQ2F0YWxvZ0V4Y2VwdGlvbi5JTlZBTElEX0VOVFJZKTsKLSAgICAgIH0KLSAgICB9IGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgewotICAgICAgdGhyb3cgbmV3IENhdGFsb2dFeGNlcHRpb24oQ2F0YWxvZ0V4Y2VwdGlvbi5JTlZBTElEX0VOVFJZX1RZUEUpOwotICAgIH0KLQotICAgIGVudHJ5VHlwZSA9IHR5cGU7Ci0gICAgdGhpcy5hcmdzID0gYXJnczsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBjYXRhbG9nIGVudHJ5IG9mIHRoZSBzcGVjaWZpZWQgdHlwZS4KLSAgICoKLSAgICogQHBhcmFtIHR5cGUgVGhlIGVudHJ5IHR5cGUKLSAgICogQHBhcmFtIGFyZ3MgQSBTdHJpbmcgVmVjdG9yIG9mIGFyZ3VtZW50cwotICAgKiBAdGhyb3dzIEludmFsaWRDYXRhbG9nRW50cnlUeXBlRXhjZXB0aW9uIGlmIG5vIHN1Y2ggZW50cnkgdHlwZQotICAgKiBleGlzdHMuCi0gICAqIEB0aHJvd3MgSW52YWxpZENhdGFsb2dFbnRyeUV4Y2VwdGlvbiBpZiB0aGUgd3JvbmcgbnVtYmVyIG9mIGFyZ3VtZW50cwotICAgKiBpcyBwYXNzZWQuCi0gICAqLwotICBwdWJsaWMgQ2F0YWxvZ0VudHJ5KGludCB0eXBlLCBWZWN0b3IgYXJncykKLSAgICB0aHJvd3MgQ2F0YWxvZ0V4Y2VwdGlvbiB7Ci0gICAgdHJ5IHsKLSAgICAgIEludGVnZXIgaUFyZ3MgPSAoSW50ZWdlcikgZW50cnlBcmdzLmdldCh0eXBlKTsKLSAgICAgIGlmIChpQXJncy5pbnRWYWx1ZSgpICE9IGFyZ3Muc2l6ZSgpKSB7Ci0gICAgICAgIHRocm93IG5ldyBDYXRhbG9nRXhjZXB0aW9uKENhdGFsb2dFeGNlcHRpb24uSU5WQUxJRF9FTlRSWSk7Ci0gICAgICB9Ci0gICAgfSBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKLSAgICAgIHRocm93IG5ldyBDYXRhbG9nRXhjZXB0aW9uKENhdGFsb2dFeGNlcHRpb24uSU5WQUxJRF9FTlRSWV9UWVBFKTsKLSAgICB9Ci0KLSAgICBlbnRyeVR5cGUgPSB0eXBlOwotICAgIHRoaXMuYXJncyA9IGFyZ3M7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBlbnRyeSB0eXBlLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBlbnRyeSB0eXBlIG9mIHRoZSBDYXRhbG9nRW50cnkKLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0RW50cnlUeXBlKCkgewotICAgIHJldHVybiBlbnRyeVR5cGU7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IGFuIGVudHJ5IGFyZ3VtZW50LgotICAgKgotICAgKiBAcGFyYW0gYXJnTnVtIFRoZSBhcmd1bWVudCBudW1iZXIgKGFyZ3VtZW50cyBhcmUgbnVtYmVyZWQgZnJvbSAwKS4KLSAgICogQHJldHVybiBUaGUgc3BlY2lmaWVkIGFyZ3VtZW50IG9yIG51bGwgaWYgYW4gaW52YWxpZCBhcmdOdW0gaXMKLSAgICogcHJvdmlkZWQuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldEVudHJ5QXJnKGludCBhcmdOdW0pIHsKLSAgICB0cnkgewotICAgICAgU3RyaW5nIGFyZyA9IChTdHJpbmcpIGFyZ3MuZ2V0KGFyZ051bSk7Ci0gICAgICByZXR1cm4gYXJnOwotICAgIH0gY2F0Y2ggKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7Ci0gICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogU2V0IGFuIGVudHJ5IGFyZ3VtZW50LgotICAgKgotICAgKiA8cD5DYXRhbG9ncyBzb21ldGltZXMgbmVlZCB0byBhZGp1c3QgdGhlIGNhdGxvZyBlbnRyeSBwYXJhbWV0ZXJzLAotICAgKiBmb3IgZXhhbXBsZSB0byBtYWtlIGEgcmVsYXRpdmUgVVJJIGFic29sdXRlIHdpdGggcmVzcGVjdCB0byB0aGUKLSAgICogY3VycmVudCBiYXNlIFVSSS4gQnV0IGluIGdlbmVyYWwsIHRoaXMgZnVuY3Rpb24gc2hvdWxkIG9ubHkgYmUKLSAgICogY2FsbGVkIHNob3J0bHkgYWZ0ZXIgb2JqZWN0IGNyZWF0aW9uIHRvIGRvIHNvbWUgc29ydCBvZiBjbGVhbnVwLgotICAgKiBDYXRhbG9nIGVudHJpZXMgc2hvdWxkIG5vdCBtdXRhdGUgb3ZlciB0aW1lLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIGFyZ051bSBUaGUgYXJndW1lbnQgbnVtYmVyIChhcmd1bWVudHMgYXJlIG51bWJlcmVkIGZyb20gMCkuCi0gICAqIEB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlmIGFuIGludmFsaWQgYXJndW1lbnQKLSAgICogbnVtYmVyIGlzIHByb3ZpZGVkLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0RW50cnlBcmcoaW50IGFyZ051bSwgU3RyaW5nIG5ld3NwZWMpCi0gICAgdGhyb3dzIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiB7Ci0gICAgYXJncy5zZXQoYXJnTnVtLCBuZXdzcGVjKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvcmVzb2x2ZXIvQ2F0YWxvZ0V4Y2VwdGlvbi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvcmVzb2x2ZXIvQ2F0YWxvZ0V4Y2VwdGlvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjMGI1NDA0Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3Jlc29sdmVyL0NhdGFsb2dFeGNlcHRpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE2OCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLy8gQ2F0YWxvZ0V4Y2VwdGlvbi5qYXZhIC0gQ2F0YWxvZyBleGNlcHRpb24KLQotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIG9yIGl0cyBsaWNlbnNvcnMsCi0gKiBhcyBhcHBsaWNhYmxlLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzb2x2ZXI7Ci0KLS8qKgotICogU2lnbmFsIENhdGFsb2cgZXhjZXB0aW9uLgotICoKLSAqIDxwPlRoaXMgZXhjZXB0aW9uIGlzIHRocm93biBpZiBhbiBlcnJvciBvY2N1cnMgbG9hZGluZyBhCi0gKiBjYXRhbG9nIGZpbGUuPC9wPgotICoKLSAqIEBzZWUgQ2F0YWxvZwotICoKLSAqIEBhdXRob3IgTm9ybWFuIFdhbHNoCi0gKiA8YSBocmVmPSJtYWlsdG86Tm9ybWFuLldhbHNoQFN1bi5DT00iPk5vcm1hbi5XYWxzaEBTdW4uQ09NPC9hPgotICoKLSAqLwotcHVibGljIGNsYXNzIENhdGFsb2dFeGNlcHRpb24gZXh0ZW5kcyBFeGNlcHRpb24gewotICAvKiogQSB3cmFwcGVyIGFyb3VuZCBhbm90aGVyIGV4Y2VwdGlvbiAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBXUkFQUEVSID0gMTsKLSAgLyoqIEFuIGludmFsaWQgZW50cnkgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU5WQUxJRF9FTlRSWSA9IDI7Ci0gIC8qKiBBbiBpbnZhbGlkIGVudHJ5IHR5cGUgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU5WQUxJRF9FTlRSWV9UWVBFID0gMzsKLSAgLyoqIENvdWxkIG5vdCBpbnN0YW50aWF0ZSBhbiBYTUwgcGFyc2VyICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE5PX1hNTF9QQVJTRVIgPSA0OwotICAvKiogVW5rbm93biBYTUwgZm9ybWF0ICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFVOS05PV05fRk9STUFUID0gNTsKLSAgLyoqIFVucGFyc2VhYmxlIFhNTCBjYXRhbG9nIChub3QgWE1MKSovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFVOUEFSU0VBQkxFID0gNjsKLSAgLyoqIFhNTCBidXQgcGFyc2UgZmFpbGVkICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBBUlNFX0ZBSUxFRCA9IDc7Ci0gIC8qKiBUZXh0IGNhdGFsb2cgZW5kZWQgaW4gbWlkLWNvbW1lbnQgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVU5FTkRFRF9DT01NRU5UID0gODsKLQotICAvKioKLSAgICogVGhlIGVtYmVkZGVkIGV4Y2VwdGlvbiBpZiB0dW5uZWxsaW5nLCBvciBudWxsLgotICAgKi8KLSAgcHJpdmF0ZSBFeGNlcHRpb24gZXhjZXB0aW9uID0gbnVsbDsKLSAgcHJpdmF0ZSBpbnQgZXhjZXB0aW9uVHlwZSA9IDA7Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIG5ldyBDYXRhbG9nRXhjZXB0aW9uLgotICAgKgotICAgKiBAcGFyYW0gdHlwZSBUaGUgZXhjZXB0aW9uIHR5cGUKLSAgICogQHBhcmFtIG1lc3NhZ2UgVGhlIGVycm9yIG9yIHdhcm5pbmcgbWVzc2FnZS4KLSAgICovCi0gIHB1YmxpYyBDYXRhbG9nRXhjZXB0aW9uIChpbnQgdHlwZSwgU3RyaW5nIG1lc3NhZ2UpIHsKLSAgICBzdXBlcihtZXNzYWdlKTsKLSAgICB0aGlzLmV4Y2VwdGlvblR5cGUgPSB0eXBlOwotICAgIHRoaXMuZXhjZXB0aW9uID0gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBuZXcgQ2F0YWxvZ0V4Y2VwdGlvbi4KLSAgICoKLSAgICogQHBhcmFtIHR5cGUgVGhlIGV4Y2VwdGlvbiB0eXBlCi0gICAqLwotICBwdWJsaWMgQ2F0YWxvZ0V4Y2VwdGlvbiAoaW50IHR5cGUpIHsKLSAgICBzdXBlcigiQ2F0YWxvZyBFeGNlcHRpb24gIiArIHR5cGUpOwotICAgIHRoaXMuZXhjZXB0aW9uVHlwZSA9IHR5cGU7Ci0gICAgdGhpcy5leGNlcHRpb24gPSBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIG5ldyBDYXRhbG9nRXhjZXB0aW9uIHdyYXBwaW5nIGFuIGV4aXN0aW5nIGV4Y2VwdGlvbi4KLSAgICoKLSAgICogPHA+VGhlIGV4aXN0aW5nIGV4Y2VwdGlvbiB3aWxsIGJlIGVtYmVkZGVkIGluIHRoZSBuZXcKLSAgICogb25lLCBhbmQgaXRzIG1lc3NhZ2Ugd2lsbCBiZWNvbWUgdGhlIGRlZmF1bHQgbWVzc2FnZSBmb3IKLSAgICogdGhlIENhdGFsb2dFeGNlcHRpb24uPC9wPgotICAgKgotICAgKiBAcGFyYW0gZSBUaGUgZXhjZXB0aW9uIHRvIGJlIHdyYXBwZWQgaW4gYSBDYXRhbG9nRXhjZXB0aW9uLgotICAgKi8KLSAgcHVibGljIENhdGFsb2dFeGNlcHRpb24gKEV4Y2VwdGlvbiBlKSB7Ci0gICAgc3VwZXIoKTsKLSAgICB0aGlzLmV4Y2VwdGlvblR5cGUgPSBXUkFQUEVSOwotICAgIHRoaXMuZXhjZXB0aW9uID0gZTsKLSAgfQotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBuZXcgQ2F0YWxvZ0V4Y2VwdGlvbiBmcm9tIGFuIGV4aXN0aW5nIGV4Y2VwdGlvbi4KLSAgICoKLSAgICogPHA+VGhlIGV4aXN0aW5nIGV4Y2VwdGlvbiB3aWxsIGJlIGVtYmVkZGVkIGluIHRoZSBuZXcKLSAgICogb25lLCBidXQgdGhlIG5ldyBleGNlcHRpb24gd2lsbCBoYXZlIGl0cyBvd24gbWVzc2FnZS48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBtZXNzYWdlIFRoZSBkZXRhaWwgbWVzc2FnZS4KLSAgICogQHBhcmFtIGUgVGhlIGV4Y2VwdGlvbiB0byBiZSB3cmFwcGVkIGluIGEgQ2F0YWxvZ0V4Y2VwdGlvbi4KLSAgICovCi0gIHB1YmxpYyBDYXRhbG9nRXhjZXB0aW9uIChTdHJpbmcgbWVzc2FnZSwgRXhjZXB0aW9uIGUpIHsKLSAgICBzdXBlcihtZXNzYWdlKTsKLSAgICB0aGlzLmV4Y2VwdGlvblR5cGUgPSBXUkFQUEVSOwotICAgIHRoaXMuZXhjZXB0aW9uID0gZTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gYSBkZXRhaWwgbWVzc2FnZSBmb3IgdGhpcyBleGNlcHRpb24uCi0gICAqCi0gICAqIDxwPklmIHRoZXJlIGlzIGFuIGVtYmVkZGVkIGV4Y2VwdGlvbiwgYW5kIGlmIHRoZSBDYXRhbG9nRXhjZXB0aW9uCi0gICAqIGhhcyBubyBkZXRhaWwgbWVzc2FnZSBvZiBpdHMgb3duLCB0aGlzIG1ldGhvZCB3aWxsIHJldHVybgotICAgKiB0aGUgZGV0YWlsIG1lc3NhZ2UgZnJvbSB0aGUgZW1iZWRkZWQgZXhjZXB0aW9uLjwvcD4KLSAgICoKLSAgICogQHJldHVybiBUaGUgZXJyb3Igb3Igd2FybmluZyBtZXNzYWdlLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRNZXNzYWdlICgpCi0gIHsKLSAgICBTdHJpbmcgbWVzc2FnZSA9IHN1cGVyLmdldE1lc3NhZ2UoKTsKLQotICAgIGlmIChtZXNzYWdlID09IG51bGwgJiYgZXhjZXB0aW9uICE9IG51bGwpIHsKLSAgICAgIHJldHVybiBleGNlcHRpb24uZ2V0TWVzc2FnZSgpOwotICAgIH0gZWxzZSB7Ci0gICAgICByZXR1cm4gbWVzc2FnZTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBlbWJlZGRlZCBleGNlcHRpb24sIGlmIGFueS4KLSAgICoKLSAgICogQHJldHVybiBUaGUgZW1iZWRkZWQgZXhjZXB0aW9uLCBvciBudWxsIGlmIHRoZXJlIGlzIG5vbmUuCi0gICAqLwotICBwdWJsaWMgRXhjZXB0aW9uIGdldEV4Y2VwdGlvbiAoKQotICB7Ci0gICAgcmV0dXJuIGV4Y2VwdGlvbjsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIGV4Y2VwdGlvbiB0eXBlCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGV4Y2VwdGlvbiB0eXBlCi0gICAqLwotICBwdWJsaWMgaW50IGdldEV4Y2VwdGlvblR5cGUgKCkKLSAgewotICAgIHJldHVybiBleGNlcHRpb25UeXBlOwotICB9Ci0KLSAgLyoqCi0gICAqIE92ZXJyaWRlIHRvU3RyaW5nIHRvIHBpY2sgdXAgYW55IGVtYmVkZGVkIGV4Y2VwdGlvbi4KLSAgICoKLSAgICogQHJldHVybiBBIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIGV4Y2VwdGlvbi4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcgKCkKLSAgewotICAgIGlmIChleGNlcHRpb24gIT0gbnVsbCkgewotICAgICAgcmV0dXJuIGV4Y2VwdGlvbi50b1N0cmluZygpOwotICAgIH0gZWxzZSB7Ci0gICAgICByZXR1cm4gc3VwZXIudG9TdHJpbmcoKTsKLSAgICB9Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3Jlc29sdmVyL0NhdGFsb2dNYW5hZ2VyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9yZXNvbHZlci9DYXRhbG9nTWFuYWdlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhYjhjZDI3Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3Jlc29sdmVyL0NhdGFsb2dNYW5hZ2VyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4NDYgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8vIENhdGFsb2dNYW5hZ2VyLmphdmEgLSBBY2Nlc3MgQ2F0YWxvZ01hbmFnZXIucHJvcGVydGllcwotCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gb3IgaXRzIGxpY2Vuc29ycywKLSAqIGFzIGFwcGxpY2FibGUuCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXNvbHZlcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbHMuU2VjdXJpdHlTdXBwb3J0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzb2x2ZXIuaGVscGVycy5Cb290c3RyYXBSZXNvbHZlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnJlc29sdmVyLmhlbHBlcnMuRGVidWc7Ci1pbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKLWltcG9ydCBqYXZhLm5ldC5NYWxmb3JtZWRVUkxFeGNlcHRpb247Ci1pbXBvcnQgamF2YS5uZXQuVVJMOwotaW1wb3J0IGphdmEudXRpbC5NaXNzaW5nUmVzb3VyY2VFeGNlcHRpb247Ci1pbXBvcnQgamF2YS51dGlsLlByb3BlcnR5UmVzb3VyY2VCdW5kbGU7Ci1pbXBvcnQgamF2YS51dGlsLlJlc291cmNlQnVuZGxlOwotaW1wb3J0IGphdmEudXRpbC5TdHJpbmdUb2tlbml6ZXI7Ci1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLWltcG9ydCBzdW4ucmVmbGVjdC5taXNjLlJlZmxlY3RVdGlsOwotCi0vKioKLSAqIENhdGFsb2dNYW5hZ2VyIHByb3ZpZGVzIGFuIGludGVyZmFjZSB0byB0aGUgY2F0YWxvZyBwcm9wZXJ0aWVzLgotICoKLSAqIDxwPlByb3BlcnRpZXMgY2FuIGNvbWUgZnJvbSB0d28gcGxhY2VzOiBmcm9tIHN5c3RlbSBwcm9wZXJ0aWVzIG9yCi0gKiBmcm9tIGEgPGk+Q2F0YWxvZ01hbmFnZXIucHJvcGVydGllczwvaT4gZmlsZS4gVGhpcyBjbGFzcyBwcm92aWRlcyBhIHRyYW5zcGFyZW50Ci0gKiBpbnRlcmZhY2UgdG8gYm90aCwgd2l0aCBzeXN0ZW0gcHJvcGVydGllcyBwcmVmZXJyZWQgb3ZlciBwcm9wZXJ0eSBmaWxlIHZhbHVlcy48L3A+Ci0gKgotICogPHA+VGhlIGZvbGxvd2luZyB0YWJsZSBzdW1tYXJpemVzIHRoZSBwcm9wZXJ0aWVzOjwvcD4KLSAqCi0gKiA8dGFibGUgYm9yZGVyPSIxIj4KLSAqIDx0aGVhZD4KLSAqIDx0cj4KLSAqIDx0ZD5TeXN0ZW0gUHJvcGVydHk8L3RkPgotICogPHRkPkNhdGFsb2dNYW5hZ2VyLnByb3BlcnRpZXM8YnIvPlByb3BlcnR5PC90ZD4KLSAqIDx0ZD5EZXNjcmlwdGlvbjwvdGQ+Ci0gKiA8L3RyPgotICogPC90aGVhZD4KLSAqIDx0Ym9keT4KLSAqIDx0cj4KLSAqIDx0ZD54bWwuY2F0YWxvZy5pZ25vcmVNaXNzaW5nPC90ZD4KLSAqIDx0ZD4mIzE2MDs8L3RkPgotICogPHRkPklmIHRydWUsIGEgbWlzc2luZyA8aT5DYXRhbG9nTWFuYWdlci5wcm9wZXJ0aWVzPC9pPiBmaWxlIG9yIG1pc3NpbmcgcHJvcGVydGllcwotICogd2l0aGluIHRoYXQgZmlsZSB3aWxsIG5vdCBnZW5lcmF0ZSB3YXJuaW5nIG1lc3NhZ2VzLiBTZWUgYWxzbyB0aGUKLSAqIDxpPmlnbm9yZU1pc3NpbmdQcm9wZXJ0aWVzPC9pPiBtZXRob2QuPC90ZD4KLSAqIDwvdHI+Ci0gKgotICogPHRyPgotICogPHRkPnhtbC5jYXRhbG9nLmZpbGVzPC90ZD4KLSAqIDx0ZD5jYXRhbG9nczwvdGQ+Ci0gKiA8dGQ+VGhlIDxlbXBoPnNlbWljb2xvbi1kZWxpbWl0ZWQ8L2VtcGg+IGxpc3Qgb2YgY2F0YWxvZyBmaWxlcy48L3RkPgotICogPC90cj4KLSAqCi0gKiA8dHI+Ci0gKiA8dGQ+JiMxNjA7PC90ZD4KLSAqIDx0ZD5yZWxhdGl2ZS1jYXRhbG9nczwvdGQ+Ci0gKiA8dGQ+SWYgZmFsc2UsIHJlbGF0aXZlIGNhdGFsb2cgVVJJcyBhcmUgbWFkZSBhYnNvbHV0ZSB3aXRoIHJlc3BlY3QgdG8gdGhlIGJhc2UgVVJJIG9mCi0gKiB0aGUgPGk+Q2F0YWxvZ01hbmFnZXIucHJvcGVydGllczwvaT4gZmlsZS4gVGhpcyBzZXR0aW5nIG9ubHkgYXBwbGllcyB0byBjYXRhbG9nCi0gKiBVUklzIG9idGFpbmVkIGZyb20gdGhlIDxpPmNhdGFsb2dzPC9pPiBwcm9wZXJ0eSA8ZW1waD5pbiB0aGU8L2VtcGg+Ci0gKiA8aT5DYXRhbG9nTWFuYWdlci5wcm9wZXJ0aWVzPC9pPiBmaWxlPC90ZD4KLSAqIDwvdHI+Ci0gKgotICogPHRyPgotICogPHRkPnhtbC5jYXRhbG9nLnZlcmJvc2l0eTwvdGQ+Ci0gKiA8dGQ+dmVyYm9zaXR5PC90ZD4KLSAqIDx0ZD5JZiBub24temVybywgdGhlIENhdGFsb2cgY2xhc3NlcyB3aWxsIHByaW50IGluZm9ybWF0aXZlIGFuZCBkZWJ1Z2dpbmcgbWVzc2FnZXMuCi0gKiBUaGUgaGlnaGVyIHRoZSBudW1iZXIsIHRoZSBtb3JlIG1lc3NhZ2VzLjwvdGQ+Ci0gKiA8L3RyPgotICoKLSAqIDx0cj4KLSAqIDx0ZD54bWwuY2F0YWxvZy5wcmVmZXI8L3RkPgotICogPHRkPnByZWZlcjwvdGQ+Ci0gKiA8dGQ+V2hpY2ggaWRlbnRpZmllciBpcyBwcmVmZXJyZWQsICJwdWJsaWMiIG9yICJzeXN0ZW0iPzwvdGQ+Ci0gKiA8L3RyPgotICoKLSAqIDx0cj4KLSAqIDx0ZD54bWwuY2F0YWxvZy5zdGF0aWNDYXRhbG9nPC90ZD4KLSAqIDx0ZD5zdGF0aWMtY2F0YWxvZzwvdGQ+Ci0gKiA8dGQ+U2hvdWxkIGEgc2luZ2xlIGNhdGFsb2cgYmUgY29uc3RydWN0ZWQgZm9yIGFsbCBwYXJzaW5nLCBvciBzaG91bGQgYSBkaWZmZXJlbnQKLSAqIGNhdGFsb2cgYmUgY3JlYXRlZCBmb3IgZWFjaCBwYXJzZXI/PC90ZD4KLSAqIDwvdHI+Ci0gKgotICogPHRyPgotICogPHRkPnhtbC5jYXRhbG9nLmFsbG93UEk8L3RkPgotICogPHRkPmFsbG93LW9hc2lzLXhtbC1jYXRhbG9nLXBpPC90ZD4KLSAqIDx0ZD5JZiB0aGUgc291cmNlIGRvY3VtZW50IGNvbnRhaW5zICJvYXNpcy14bWwtY2F0YWxvZyIgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbnMsCi0gKiBzaG91bGQgdGhleSBiZSB1c2VkPzwvdGQ+Ci0gKiA8L3RyPgotICoKLSAqIDx0cj4KLSAqIDx0ZD54bWwuY2F0YWxvZy5jbGFzc05hbWU8L3RkPgotICogPHRkPmNhdGFsb2ctY2xhc3MtbmFtZTwvdGQ+Ci0gKiA8dGQ+SWYgeW91J3JlIHVzaW5nIHRoZSBjb252ZW5pZW5jZSBjbGFzc2VzCi0gKiA8dHQ+Y29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXNvbHZlci50b29scy4qPC90dD4pLCB0aGlzIHNldHRpbmcKLSAqIGFsbG93cyB5b3UgdG8gc3BlY2lmeSBhbiBhbHRlcm5hdGUgY2xhc3MgbmFtZSB0byB1c2UgZm9yIHRoZSB1bmRlcmx5aW5nCi0gKiBjYXRhbG9nLjwvdGQ+Ci0gKiA8L3RyPgotICogPC90Ym9keT4KLSAqIDwvdGFibGU+Ci0gKgotICogQHNlZSBDYXRhbG9nCi0gKgotICogQGF1dGhvciBOb3JtYW4gV2Fsc2gKLSAqIDxhIGhyZWY9Im1haWx0bzpOb3JtYW4uV2Fsc2hAU3VuLkNPTSI+Tm9ybWFuLldhbHNoQFN1bi5DT008L2E+Ci0gKgotICogQHZlcnNpb24gMS4wCi0gKi8KLQotcHVibGljIGNsYXNzIENhdGFsb2dNYW5hZ2VyIHsKLSAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIHBGaWxlcyAgICAgICAgID0gInhtbC5jYXRhbG9nLmZpbGVzIjsKLSAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIHBWZXJib3NpdHkgICAgID0gInhtbC5jYXRhbG9nLnZlcmJvc2l0eSI7Ci0gIHByaXZhdGUgc3RhdGljIFN0cmluZyBwUHJlZmVyICAgICAgICA9ICJ4bWwuY2F0YWxvZy5wcmVmZXIiOwotICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgcFN0YXRpYyAgICAgICAgPSAieG1sLmNhdGFsb2cuc3RhdGljQ2F0YWxvZyI7Ci0gIHByaXZhdGUgc3RhdGljIFN0cmluZyBwQWxsb3dQSSAgICAgICA9ICJ4bWwuY2F0YWxvZy5hbGxvd1BJIjsKLSAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIHBDbGFzc25hbWUgICAgID0gInhtbC5jYXRhbG9nLmNsYXNzTmFtZSI7Ci0gIHByaXZhdGUgc3RhdGljIFN0cmluZyBwSWdub3JlTWlzc2luZyA9ICJ4bWwuY2F0YWxvZy5pZ25vcmVNaXNzaW5nIjsKLQotICAvKiogQSBzdGF0aWMgQ2F0YWxvZ01hbmFnZXIgaW5zdGFuY2UgZm9yIHNoYXJpbmcgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgQ2F0YWxvZ01hbmFnZXIgc3RhdGljTWFuYWdlciA9IG5ldyBDYXRhbG9nTWFuYWdlcigpOwotCi0gIC8qKiBUaGUgYm9vdHN0cmFwIHJlc29sdmVyIHRvIHVzZSB3aGVuIGxvYWRpbmcgWE1MIENhdGFsb2dzLiAqLwotICBwcml2YXRlIEJvb3RzdHJhcFJlc29sdmVyIGJSZXNvbHZlciA9IG5ldyBCb290c3RyYXBSZXNvbHZlcigpOwotCi0gIC8qKiBGbGFnIHRvIGlnbm9yZSBtaXNzaW5nIHByb3BlcnR5IGZpbGVzIGFuZC9vciBwcm9wZXJ0aWVzICovCi0gIHByaXZhdGUgYm9vbGVhbiBpZ25vcmVNaXNzaW5nUHJvcGVydGllcwotICAgID0gKFNlY3VyaXR5U3VwcG9ydC5nZXRTeXN0ZW1Qcm9wZXJ0eShwSWdub3JlTWlzc2luZykgIT0gbnVsbAotICAgICAgIHx8IFNlY3VyaXR5U3VwcG9ydC5nZXRTeXN0ZW1Qcm9wZXJ0eShwRmlsZXMpICE9IG51bGwpOwotCi0gIC8qKiBIb2xkcyB0aGUgcmVzb3VyY2VzIGFmdGVyIHRoZXkgYXJlIGxvYWRlZCBmcm9tIHRoZSBmaWxlLiAqLwotICBwcml2YXRlIFJlc291cmNlQnVuZGxlIHJlc291cmNlczsKLQotICAvKiogVGhlIG5hbWUgb2YgdGhlIENhdGFsb2dNYW5hZ2VyIHByb3BlcnRpZXMgZmlsZS4gKi8KLSAgcHJpdmF0ZSBTdHJpbmcgcHJvcGVydHlGaWxlID0gIkNhdGFsb2dNYW5hZ2VyLnByb3BlcnRpZXMiOwotCi0gIC8qKiBUaGUgbG9jYXRpb24gb2YgdGhlIHByb3BlcnR5RmlsZSAqLwotICBwcml2YXRlIFVSTCBwcm9wZXJ0eUZpbGVVUkkgPSBudWxsOwotCi0gIC8qKiBEZWZhdWx0IGNhdGFsb2cgZmlsZXMgbGlzdC4gKi8KLSAgcHJpdmF0ZSBTdHJpbmcgZGVmYXVsdENhdGFsb2dGaWxlcyA9ICIuL3hjYXRhbG9nIjsKLQotICAvKiogQ3VycmVudCBjYXRhbG9nIGZpbGVzIGxpc3QuICovCi0gIHByaXZhdGUgU3RyaW5nIGNhdGFsb2dGaWxlcyA9IG51bGw7Ci0KLSAgLyoqIERpZCB0aGUgY2F0YWxvZ0ZpbGVzIGNvbWUgZnJvbSB0aGUgcHJvcGVydGllcyBmaWxlPyAqLwotICBwcml2YXRlIGJvb2xlYW4gZnJvbVByb3BlcnRpZXNGaWxlID0gZmFsc2U7Ci0KLSAgLyoqIERlZmF1bHQgdmVyYm9zaXR5IGxldmVsIGlmIHRoZXJlIGlzIG5vIHByb3BlcnR5IHNldHRpbmcgZm9yIGl0LiAqLwotICBwcml2YXRlIGludCBkZWZhdWx0VmVyYm9zaXR5ID0gMTsKLQotICAvKiogQ3VycmVudCB2ZXJib3NpdHkgbGV2ZWwuICovCi0gIHByaXZhdGUgSW50ZWdlciB2ZXJib3NpdHkgPSBudWxsOwotCi0gIC8qKiBEZWZhdWx0IHByZWZlcmVuY2Ugc2V0dGluZy4gKi8KLSAgcHJpdmF0ZSBib29sZWFuIGRlZmF1bHRQcmVmZXJQdWJsaWMgPSB0cnVlOwotCi0gIC8qKiBDdXJyZW50IHByZWZlcmVuY2Ugc2V0dGluZy4gKi8KLSAgcHJpdmF0ZSBCb29sZWFuIHByZWZlclB1YmxpYyA9IG51bGw7Ci0KLSAgLyoqIERlZmF1bHQgc2V0dGluZyBvZiB0aGUgc3RhdGljIGNhdGFsb2cgZmxhZy4gKi8KLSAgcHJpdmF0ZSBib29sZWFuIGRlZmF1bHRVc2VTdGF0aWNDYXRhbG9nID0gdHJ1ZTsKLQotICAvKiogQ3VycmVudCBzZXR0aW5nIG9mIHRoZSBzdGF0aWMgY2F0YWxvZyBmbGFnLiAqLwotICBwcml2YXRlIEJvb2xlYW4gdXNlU3RhdGljQ2F0YWxvZyA9IG51bGw7Ci0KLSAgLyoqIFRoZSBzdGF0aWMgY2F0YWxvZyB1c2VkIGJ5IHRoaXMgbWFuYWdlci4gKi8KLSAgcHJpdmF0ZSBzdGF0aWMgQ2F0YWxvZyBzdGF0aWNDYXRhbG9nID0gbnVsbDsKLQotICAvKiogRGVmYXVsdCBzZXR0aW5nIG9mIHRoZSBvYXNpc1hNTENhdGFsb2dQSSBmbGFnLiAqLwotICBwcml2YXRlIGJvb2xlYW4gZGVmYXVsdE9hc2lzWE1MQ2F0YWxvZ1BJID0gdHJ1ZTsKLQotICAvKiogQ3VycmVudCBzZXR0aW5nIG9mIHRoZSBvYXNpc1hNTENhdGFsb2dQSSBmbGFnLiAqLwotICBwcml2YXRlIEJvb2xlYW4gb2FzaXNYTUxDYXRhbG9nUEkgPSBudWxsOwotCi0gIC8qKiBEZWZhdWx0IHNldHRpbmcgb2YgdGhlIHJlbGF0aXZlQ2F0YWxvZ3MgZmxhZy4gKi8KLSAgcHJpdmF0ZSBib29sZWFuIGRlZmF1bHRSZWxhdGl2ZUNhdGFsb2dzID0gdHJ1ZTsKLQotICAvKiogQ3VycmVudCBzZXR0aW5nIG9mIHRoZSByZWxhdGl2ZUNhdGFsb2dzIGZsYWcuICovCi0gIHByaXZhdGUgQm9vbGVhbiByZWxhdGl2ZUNhdGFsb2dzID0gbnVsbDsKLQotICAvKiogQ3VycmVudCBjYXRhbG9nIGNsYXNzIG5hbWUuICovCi0gIHByaXZhdGUgU3RyaW5nIGNhdGFsb2dDbGFzc05hbWUgPSBudWxsOwotICAgIC8qKgotICAgICAqIEluZGljYXRlcyB3aGV0aGVyIGltcGxlbWVudGF0aW9uIHBhcnRzIHNob3VsZCB1c2UKLSAgICAgKiAgIHNlcnZpY2UgbG9hZGVyIChvciBzaW1pbGFyKS4KLSAgICAgKiBOb3RlIHRoZSBkZWZhdWx0IHZhbHVlIChmYWxzZSkgaXMgdGhlIHNhZmUgb3B0aW9uLi4KLSAgICAgKi8KLSAgICBwcml2YXRlIGJvb2xlYW4gdXNlU2VydmljZXNNZWNoYW5pc207Ci0KLSAgLyoqIFRoZSBtYW5hZ2VyJ3MgZGVidWcgb2JqZWN0LiBVc2VkIGZvciBwcmludGluZyBkZWJ1Z2dpbmcgbWVzc2FnZXMuCi0gICAqCi0gICAqIDxwPlRoaXMgZmllbGQgaXMgcHVibGljIHNvIHRoYXQgb2JqZWN0cyB0aGF0IGhhdmUgYWNjZXNzIHRvIHRoaXMKLSAgICogQ2F0YWxvZ01hbmFnZXIgY2FuIHVzZSB0aGlzIGRlYnVnIG9iamVjdC48L3A+Ci0gICAqLwotICBwdWJsaWMgRGVidWcgZGVidWcgPSBudWxsOwotCi0gIC8qKiBDb25zdHJ1Y3Rvci4gKi8KLSAgcHVibGljIENhdGFsb2dNYW5hZ2VyKCkgewotICAgIGluaXQoKTsKLSAgfQotCi0gIC8qKiBDb25zdHJ1Y3RvciB0aGF0IHNwZWNpZmllcyBhbiBleHBsaWNpdCBwcm9wZXJ0eSBmaWxlLiAqLwotICBwdWJsaWMgQ2F0YWxvZ01hbmFnZXIoU3RyaW5nIHByb3BlcnR5RmlsZSkgewotICAgIHRoaXMucHJvcGVydHlGaWxlID0gcHJvcGVydHlGaWxlOwotICAgIGluaXQoKTsKLSAgfQotCi0gIHByaXZhdGUgdm9pZCBpbml0KCkgewotICAgIGRlYnVnID0gbmV3IERlYnVnKCk7Ci0gICAgLy8gTm90ZSB0aGF0IHdlIGRvbid0IHNldERlYnVnKCkgaGVyZTsgd2UgZG8gdGhhdCBsYXppbHkuIEVpdGhlciB0aGUKLSAgICAvLyB1c2VyIHdpbGwgc2V0IGl0IGV4cGxpY2l0bHksIG9yIHdlJ2xsIGRvIGl0IGF1dG9tYWdpY2FsbHkgaWYgdGhleQotICAgIC8vIHJlYWQgZnJvbSB0aGUgcHJvcGVydHlGaWxlIGZvciBzb21lIG90aGVyIHJlYXNvbi4gVGhhdCB3YXksIHRoZXJlJ3MKLSAgICAvLyBubyBhdHRlbXB0IHRvIHJlYWQgZnJvbSB0aGUgZmlsZSBiZWZvcmUgdGhlIGNhbGxlciBoYXMgaGFkIGEgY2hhbmNlCi0gICAgLy8gdG8gYXZvaWQgaXQuCi0gICAgaWYgKFN5c3RlbS5nZXRTZWN1cml0eU1hbmFnZXIoKSA9PSBudWxsKSB7Ci0gICAgICAgIHVzZVNlcnZpY2VzTWVjaGFuaXNtID0gdHJ1ZTsKLSAgICB9Ci0gIH0KLSAgLyoqIFNldCB0aGUgYm9vdHN0cmFwIHJlc29sdmVyLiovCi0gIHB1YmxpYyB2b2lkIHNldEJvb3RzdHJhcFJlc29sdmVyKEJvb3RzdHJhcFJlc29sdmVyIHJlc29sdmVyKSB7Ci0gICAgYlJlc29sdmVyID0gcmVzb2x2ZXI7Ci0gIH0KLQotICAvKiogR2V0IHRoZSBib290c3RyYXAgcmVzb2x2ZXIuKi8KLSAgcHVibGljIEJvb3RzdHJhcFJlc29sdmVyIGdldEJvb3RzdHJhcFJlc29sdmVyKCkgewotICAgIHJldHVybiBiUmVzb2x2ZXI7Ci0gIH0KLQotICAvKioKLSAgICogTG9hZCB0aGUgcHJvcGVydGllcyBmcm9tIHRoZSBwcm9wZXJ0eUZpbGUgYW5kIGJ1aWxkIHRoZQotICAgKiByZXNvdXJjZXMgZnJvbSBpdC4KLSAgICovCi0gIHByaXZhdGUgc3luY2hyb25pemVkIHZvaWQgcmVhZFByb3BlcnRpZXMoKSB7Ci0gICAgdHJ5IHsKLSAgICAgIHByb3BlcnR5RmlsZVVSSSA9IENhdGFsb2dNYW5hZ2VyLmNsYXNzLmdldFJlc291cmNlKCIvIitwcm9wZXJ0eUZpbGUpOwotICAgICAgSW5wdXRTdHJlYW0gaW4gPQotICAgICAgICBDYXRhbG9nTWFuYWdlci5jbGFzcy5nZXRSZXNvdXJjZUFzU3RyZWFtKCIvIitwcm9wZXJ0eUZpbGUpOwotICAgICAgaWYgKGluPT1udWxsKSB7Ci0gICAgICAgIGlmICghaWdub3JlTWlzc2luZ1Byb3BlcnRpZXMpIHsKLSAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIkNhbm5vdCBmaW5kICIrcHJvcGVydHlGaWxlKTsKLSAgICAgICAgICAvLyB0aGVyZSdzIG5vIHJlYXNvbiB0byBnaXZlIHRoaXMgd2FybmluZyBtb3JlIHRoYW4gb25jZQotICAgICAgICAgIGlnbm9yZU1pc3NpbmdQcm9wZXJ0aWVzID0gdHJ1ZTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm47Ci0gICAgICB9Ci0gICAgICByZXNvdXJjZXMgPSBuZXcgUHJvcGVydHlSZXNvdXJjZUJ1bmRsZShpbik7Ci0gICAgfSBjYXRjaCAoTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uIG1yZSkgewotICAgICAgaWYgKCFpZ25vcmVNaXNzaW5nUHJvcGVydGllcykgewotICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIkNhbm5vdCByZWFkICIrcHJvcGVydHlGaWxlKTsKLSAgICAgIH0KLSAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKLSAgICAgIGlmICghaWdub3JlTWlzc2luZ1Byb3BlcnRpZXMpIHsKLSAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJGYWlsdXJlIHRyeWluZyB0byByZWFkICIrcHJvcGVydHlGaWxlKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICAvLyBUaGlzIGlzIGEgYml0IG9mIGEgaGFjay4gQWZ0ZXIgd2UndmUgc3VjY2Vzc2Z1bGx5IHJlYWQgdGhlIHByb3BlcnRpZXMsCi0gICAgLy8gdXNlIHRoZW0gdG8gc2V0IHRoZSBkZWZhdWx0IGRlYnVnIGxldmVsLCBpZiB0aGUgdXNlciBoYXNuJ3QgYWxyZWFkeSBzZXQKLSAgICAvLyB0aGUgZGVmYXVsdCBkZWJ1ZyBsZXZlbC4KLSAgICBpZiAodmVyYm9zaXR5ID09IG51bGwpIHsKLSAgICAgIHRyeSB7Ci0gICAgICAgIFN0cmluZyB2ZXJiU3RyID0gcmVzb3VyY2VzLmdldFN0cmluZygidmVyYm9zaXR5Iik7Ci0gICAgICAgIGludCB2ZXJiID0gSW50ZWdlci5wYXJzZUludCh2ZXJiU3RyLnRyaW0oKSk7Ci0gICAgICAgIGRlYnVnLnNldERlYnVnKHZlcmIpOwotICAgICAgICB2ZXJib3NpdHkgPSBuZXcgSW50ZWdlcih2ZXJiKTsKLSAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgIC8vIG5vcAotICAgICAgfQotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBBbGxvdyBhY2Nlc3MgdG8gdGhlIHN0YXRpYyBDYXRhbG9nTWFuYWdlcgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBDYXRhbG9nTWFuYWdlciBnZXRTdGF0aWNNYW5hZ2VyKCkgewotICAgIHJldHVybiBzdGF0aWNNYW5hZ2VyOwotICB9Ci0KLSAgLyoqCi0gICAqIEhvdyBhcmUgbWlzc2luZyBwcm9wZXJ0aWVzIGhhbmRsZWQ/Ci0gICAqCi0gICAqIDxwPklmIHRydWUsIG1pc3Npbmcgb3IgdW5yZWFkYWJsZSBwcm9wZXJ0eSBmaWxlcyB3aWxsCi0gICAqIG5vdCBiZSByZXBvcnRlZC4gT3RoZXJ3aXNlLCBhIG1lc3NhZ2Ugd2lsbCBiZSBzZW50IHRvIFN5c3RlbS5lcnIuCi0gICAqIDwvcD4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGdldElnbm9yZU1pc3NpbmdQcm9wZXJ0aWVzKCkgewotICAgIHJldHVybiBpZ25vcmVNaXNzaW5nUHJvcGVydGllczsKLSAgfQotCi0gIC8qKgotICAgKiBIb3cgc2hvdWxkIG1pc3NpbmcgcHJvcGVydGllcyBiZSBoYW5kbGVkPwotICAgKgotICAgKiA8cD5JZiBpZ25vcmUgaXMgdHJ1ZSwgbWlzc2luZyBvciB1bnJlYWRhYmxlIHByb3BlcnR5IGZpbGVzIHdpbGwKLSAgICogbm90IGJlIHJlcG9ydGVkLiBPdGhlcndpc2UsIGEgbWVzc2FnZSB3aWxsIGJlIHNlbnQgdG8gU3lzdGVtLmVyci4KLSAgICogPC9wPgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0SWdub3JlTWlzc2luZ1Byb3BlcnRpZXMoYm9vbGVhbiBpZ25vcmUpIHsKLSAgICBpZ25vcmVNaXNzaW5nUHJvcGVydGllcyA9IGlnbm9yZTsKLSAgfQotCi0gIC8qKgotICAgKiBIb3cgYXJlIG1pc3NpbmcgcHJvcGVydGllcyBoYW5kbGVkPwotICAgKgotICAgKiA8cD5JZiBpZ25vcmUgaXMgdHJ1ZSwgbWlzc2luZyBvciB1bnJlYWRhYmxlIHByb3BlcnR5IGZpbGVzIHdpbGwKLSAgICogbm90IGJlIHJlcG9ydGVkLiBPdGhlcndpc2UsIGEgbWVzc2FnZSB3aWxsIGJlIHNlbnQgdG8gU3lzdGVtLmVyci4KLSAgICogPC9wPgotICAgKgotICAgKiBAZGVwcmVjYXRlZCBObyBsb25nZXIgc3RhdGljOyB1c2UgZ2V0L3NldCBtZXRob2RzLgotICAgKi8KLSAgcHVibGljIHZvaWQgaWdub3JlTWlzc2luZ1Byb3BlcnRpZXMoYm9vbGVhbiBpZ25vcmUpIHsKLSAgICBzZXRJZ25vcmVNaXNzaW5nUHJvcGVydGllcyhpZ25vcmUpOwotICB9Ci0KLSAgLyoqCi0gICAqIE9idGFpbiB0aGUgdmVyYm9zaXR5IHNldHRpbmcgZnJvbSB0aGUgcHJvcGVydGllcy4KLSAgICoKLSAgICogQHJldHVybiBUaGUgdmVyYm9zaXR5IGxldmVsIGZyb20gdGhlIHByb3BlcnR5RmlsZSBvciB0aGUKLSAgICogZGVmYXVsdFZlcmJvc2l0eS4KLSAgICovCi0gIHByaXZhdGUgaW50IHF1ZXJ5VmVyYm9zaXR5ICgpIHsKLSAgICBTdHJpbmcgZGVmYXVsdFZlcmJTdHIgPSBJbnRlZ2VyLnRvU3RyaW5nKGRlZmF1bHRWZXJib3NpdHkpOwotCi0gICAgU3RyaW5nIHZlcmJTdHIgPSBTZWN1cml0eVN1cHBvcnQuZ2V0U3lzdGVtUHJvcGVydHkocFZlcmJvc2l0eSk7Ci0KLSAgICBpZiAodmVyYlN0ciA9PSBudWxsKSB7Ci0gICAgICBpZiAocmVzb3VyY2VzPT1udWxsKSByZWFkUHJvcGVydGllcygpOwotICAgICAgaWYgKHJlc291cmNlcyAhPSBudWxsKSB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgdmVyYlN0ciA9IHJlc291cmNlcy5nZXRTdHJpbmcoInZlcmJvc2l0eSIpOwotICAgICAgICB9IGNhdGNoIChNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24gZSkgewotICAgICAgICAgIHZlcmJTdHIgPSBkZWZhdWx0VmVyYlN0cjsKLSAgICAgICAgfQotICAgICAgfSBlbHNlIHsKLSAgICAgICAgdmVyYlN0ciA9IGRlZmF1bHRWZXJiU3RyOwotICAgICAgfQotICAgIH0KLQotICAgIGludCB2ZXJiID0gZGVmYXVsdFZlcmJvc2l0eTsKLQotICAgIHRyeSB7Ci0gICAgICB2ZXJiID0gSW50ZWdlci5wYXJzZUludCh2ZXJiU3RyLnRyaW0oKSk7Ci0gICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKLSAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiQ2Fubm90IHBhcnNlIHZlcmJvc2l0eTogXCIiICsgdmVyYlN0ciArICJcIiIpOwotICAgIH0KLQotICAgIC8vIFRoaXMgaXMgYSBiaXQgb2YgYSBoYWNrLiBBZnRlciB3ZSd2ZSBzdWNjZXNzZnVsbHkgZ290IHRoZSB2ZXJib3NpdHksCi0gICAgLy8gd2UgaGF2ZSB0byB1c2UgaXQgdG8gc2V0IHRoZSBkZWZhdWx0IGRlYnVnIGxldmVsLAotICAgIC8vIGlmIHRoZSB1c2VyIGhhc24ndCBhbHJlYWR5IHNldCB0aGUgZGVmYXVsdCBkZWJ1ZyBsZXZlbC4KLSAgICBpZiAodmVyYm9zaXR5ID09IG51bGwpIHsKLSAgICAgIGRlYnVnLnNldERlYnVnKHZlcmIpOwotICAgICAgdmVyYm9zaXR5ID0gbmV3IEludGVnZXIodmVyYik7Ci0gICAgfQotCi0gICAgcmV0dXJuIHZlcmI7Ci0gIH0KLQotICAvKioKLSAgICogV2hhdCBpcyB0aGUgY3VycmVudCB2ZXJib3NpdHk/Ci0gICAqLwotICBwdWJsaWMgaW50IGdldFZlcmJvc2l0eSgpIHsKLSAgICBpZiAodmVyYm9zaXR5ID09IG51bGwpIHsKLSAgICAgIHZlcmJvc2l0eSA9IG5ldyBJbnRlZ2VyKHF1ZXJ5VmVyYm9zaXR5KCkpOwotICAgIH0KLQotICAgIHJldHVybiB2ZXJib3NpdHkuaW50VmFsdWUoKTsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIGN1cnJlbnQgdmVyYm9zaXR5LgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0VmVyYm9zaXR5IChpbnQgdmVyYm9zaXR5KSB7Ci0gICAgdGhpcy52ZXJib3NpdHkgPSBuZXcgSW50ZWdlcih2ZXJib3NpdHkpOwotICAgIGRlYnVnLnNldERlYnVnKHZlcmJvc2l0eSk7Ci0gIH0KLQotICAvKioKLSAgICogV2hhdCBpcyB0aGUgY3VycmVudCB2ZXJib3NpdHk/Ci0gICAqCi0gICAqIEBkZXByZWNhdGVkIE5vIGxvbmdlciBzdGF0aWM7IHVzZSBnZXQvc2V0IG1ldGhvZHMuCi0gICAqLwotICBwdWJsaWMgaW50IHZlcmJvc2l0eSAoKSB7Ci0gICAgcmV0dXJuIGdldFZlcmJvc2l0eSgpOwotICB9Ci0KLSAgLyoqCi0gICAqIE9idGFpbiB0aGUgcmVsYXRpdmVDYXRhbG9ncyBzZXR0aW5nIGZyb20gdGhlIHByb3BlcnRpZXMuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHJlbGF0aXZlQ2F0YWxvZ3Mgc2V0dGluZyBmcm9tIHRoZSBwcm9wZXJ0eUZpbGUgb3IgdGhlCi0gICAqIGRlZmF1bHRSZWxhdGl2ZUNhdGFsb2dzLgotICAgKi8KLSAgcHJpdmF0ZSBib29sZWFuIHF1ZXJ5UmVsYXRpdmVDYXRhbG9ncyAoKSB7Ci0gICAgaWYgKHJlc291cmNlcz09bnVsbCkgcmVhZFByb3BlcnRpZXMoKTsKLQotICAgIGlmIChyZXNvdXJjZXM9PW51bGwpIHJldHVybiBkZWZhdWx0UmVsYXRpdmVDYXRhbG9nczsKLQotICAgIHRyeSB7Ci0gICAgICBTdHJpbmcgYWxsb3cgPSByZXNvdXJjZXMuZ2V0U3RyaW5nKCJyZWxhdGl2ZS1jYXRhbG9ncyIpOwotICAgICAgcmV0dXJuIChhbGxvdy5lcXVhbHNJZ25vcmVDYXNlKCJ0cnVlIikKLSAgICAgICAgICAgICAgfHwgYWxsb3cuZXF1YWxzSWdub3JlQ2FzZSgieWVzIikKLSAgICAgICAgICAgICAgfHwgYWxsb3cuZXF1YWxzSWdub3JlQ2FzZSgiMSIpKTsKLSAgICB9IGNhdGNoIChNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24gZSkgewotICAgICAgcmV0dXJuIGRlZmF1bHRSZWxhdGl2ZUNhdGFsb2dzOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIHJlbGF0aXZlQ2F0YWxvZ3Mgc2V0dGluZy4KLSAgICoKLSAgICogPHA+VGhpcyBwcm9wZXJ0eSBpcyB1c2VkIHdoZW4gdGhlIGNhdGFsb2dGaWxlcyBwcm9wZXJ0eSBpcwotICAgKiBpbnRlcnJvZ2F0ZWQuIElmIHRydWUsIHRoZW4gcmVsYXRpdmUgY2F0YWxvZyBlbnRyeSBmaWxlIG5hbWVzCi0gICAqIGFyZSByZXR1cm5lZC4gSWYgZmFsc2UsIHJlbGF0aXZlIGNhdGFsb2cgZW50cnkgZmlsZSBuYW1lcyBhcmUKLSAgICogbWFkZSBhYnNvbHV0ZSB3aXRoIHJlc3BlY3QgdG8gdGhlIHByb3BlcnRpZXMgZmlsZSBiZWZvcmUgcmV0dXJuaW5nCi0gICAqIHRoZW0uPC9wPgotICAgKgotICAgKiA8cD5UaGlzIHByb3BlcnR5IDxlbXBoPm9ubHkgYXBwbGllczwvZW1waD4gd2hlbiB0aGUgY2F0YWxvZyBmaWxlcwotICAgKiBjb21lIGZyb20gYSBwcm9wZXJ0aWVzIGZpbGUuIElmIHRoZXkgY29tZSBmcm9tIGEgc3lzdGVtIHByb3BlcnR5IG9yCi0gICAqIHRoZSBkZWZhdWx0IGxpc3QsIHRoZXkgYXJlIG5ldmVyIGNvbnNpZGVyZWQgcmVsYXRpdmUuIChXaGF0IHdvdWxkCi0gICAqIHRoZXkgYmUgcmVsYXRpdmUgdG8/KTwvcD4KLSAgICoKLSAgICogPHA+SW4gdGhlIHByb3BlcnRpZXMsIGEgdmFsdWUgb2YgJ3llcycsICd0cnVlJywgb3IgJzEnIGlzIGNvbnNpZGVyZWQKLSAgICogdHJ1ZSwgYW55dGhpbmcgZWxzZSBpcyBmYWxzZS48L3A+Ci0gICAqCi0gICAqIEByZXR1cm4gVGhlIHJlbGF0aXZlQ2F0YWxvZ3Mgc2V0dGluZyBmcm9tIHRoZSBwcm9wZXJ0eUZpbGUgb3IgdGhlCi0gICAqIGRlZmF1bHRSZWxhdGl2ZUNhdGFsb2dzLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZ2V0UmVsYXRpdmVDYXRhbG9ncyAoKSB7Ci0gICAgaWYgKHJlbGF0aXZlQ2F0YWxvZ3MgPT0gbnVsbCkgewotICAgICAgcmVsYXRpdmVDYXRhbG9ncyA9IG5ldyBCb29sZWFuKHF1ZXJ5UmVsYXRpdmVDYXRhbG9ncygpKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gcmVsYXRpdmVDYXRhbG9ncy5ib29sZWFuVmFsdWUoKTsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIHJlbGF0aXZlQ2F0YWxvZ3Mgc2V0dGluZy4KLSAgICoKLSAgICogQHNlZSAjZ2V0UmVsYXRpdmVDYXRhbG9ncygpCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRSZWxhdGl2ZUNhdGFsb2dzIChib29sZWFuIHJlbGF0aXZlKSB7Ci0gICAgcmVsYXRpdmVDYXRhbG9ncyA9IG5ldyBCb29sZWFuKHJlbGF0aXZlKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIHJlbGF0aXZlQ2F0YWxvZ3Mgc2V0dGluZy4KLSAgICoKLSAgICogQGRlcHJlY2F0ZWQgTm8gbG9uZ2VyIHN0YXRpYzsgdXNlIGdldC9zZXQgbWV0aG9kcy4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIHJlbGF0aXZlQ2F0YWxvZ3MgKCkgewotICAgIHJldHVybiBnZXRSZWxhdGl2ZUNhdGFsb2dzKCk7Ci0gIH0KLQotICAvKioKLSAgICogT2J0YWluIHRoZSBsaXN0IG9mIGNhdGFsb2cgZmlsZXMgZnJvbSB0aGUgcHJvcGVydGllcy4KLSAgICoKLSAgICogQHJldHVybiBBIHNlbWljb2xvbiBkZWxpbWl0ZWQgbGlzdCBvZiBjYXRsb2cgZmlsZSBVUklzCi0gICAqLwotICBwcml2YXRlIFN0cmluZyBxdWVyeUNhdGFsb2dGaWxlcyAoKSB7Ci0gICAgU3RyaW5nIGNhdGFsb2dMaXN0ID0gU2VjdXJpdHlTdXBwb3J0LmdldFN5c3RlbVByb3BlcnR5KHBGaWxlcyk7Ci0gICAgZnJvbVByb3BlcnRpZXNGaWxlID0gZmFsc2U7Ci0KLSAgICBpZiAoY2F0YWxvZ0xpc3QgPT0gbnVsbCkgewotICAgICAgaWYgKHJlc291cmNlcyA9PSBudWxsKSByZWFkUHJvcGVydGllcygpOwotICAgICAgaWYgKHJlc291cmNlcyAhPSBudWxsKSB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgY2F0YWxvZ0xpc3QgPSByZXNvdXJjZXMuZ2V0U3RyaW5nKCJjYXRhbG9ncyIpOwotICAgICAgICAgIGZyb21Qcm9wZXJ0aWVzRmlsZSA9IHRydWU7Ci0gICAgICAgIH0gY2F0Y2ggKE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKHByb3BlcnR5RmlsZSArICI6IGNhdGFsb2dzIG5vdCBmb3VuZC4iKTsKLSAgICAgICAgICBjYXRhbG9nTGlzdCA9IG51bGw7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICB9Ci0KLSAgICBpZiAoY2F0YWxvZ0xpc3QgPT0gbnVsbCkgewotICAgICAgY2F0YWxvZ0xpc3QgPSBkZWZhdWx0Q2F0YWxvZ0ZpbGVzOwotICAgIH0KLQotICAgIHJldHVybiBjYXRhbG9nTGlzdDsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIGN1cnJlbnQgbGlzdCBvZiBjYXRhbG9nIGZpbGVzLgotICAgKgotICAgKiBAcmV0dXJuIEEgdmVjdG9yIG9mIHRoZSBjYXRhbG9nIGZpbGUgbmFtZXMgb3IgbnVsbCBpZiBubyBjYXRhbG9ncwotICAgKiBhcmUgYXZhaWxhYmxlIGluIHRoZSBwcm9wZXJ0aWVzLgotICAgKi8KLSAgcHVibGljIFZlY3RvciBnZXRDYXRhbG9nRmlsZXMoKSB7Ci0gICAgaWYgKGNhdGFsb2dGaWxlcyA9PSBudWxsKSB7Ci0gICAgICBjYXRhbG9nRmlsZXMgPSBxdWVyeUNhdGFsb2dGaWxlcygpOwotICAgIH0KLQotICAgIFN0cmluZ1Rva2VuaXplciBmaWxlcyA9IG5ldyBTdHJpbmdUb2tlbml6ZXIoY2F0YWxvZ0ZpbGVzLCAiOyIpOwotICAgIFZlY3RvciBjYXRhbG9ncyA9IG5ldyBWZWN0b3IoKTsKLSAgICB3aGlsZSAoZmlsZXMuaGFzTW9yZVRva2VucygpKSB7Ci0gICAgICBTdHJpbmcgY2F0YWxvZ0ZpbGUgPSBmaWxlcy5uZXh0VG9rZW4oKTsKLSAgICAgIFVSTCBhYnNVUkkgPSBudWxsOwotCi0gICAgICBpZiAoZnJvbVByb3BlcnRpZXNGaWxlICYmICFyZWxhdGl2ZUNhdGFsb2dzKCkpIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICBhYnNVUkkgPSBuZXcgVVJMKHByb3BlcnR5RmlsZVVSSSwgY2F0YWxvZ0ZpbGUpOwotICAgICAgICAgIGNhdGFsb2dGaWxlID0gYWJzVVJJLnRvU3RyaW5nKCk7Ci0gICAgICAgIH0gY2F0Y2ggKE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiBtdWUpIHsKLSAgICAgICAgICBhYnNVUkkgPSBudWxsOwotICAgICAgICB9Ci0gICAgICB9Ci0KLSAgICAgIGNhdGFsb2dzLmFkZChjYXRhbG9nRmlsZSk7Ci0gICAgfQotCi0gICAgcmV0dXJuIGNhdGFsb2dzOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgbGlzdCBvZiBjYXRhbG9nIGZpbGVzLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0Q2F0YWxvZ0ZpbGVzKFN0cmluZyBmaWxlTGlzdCkgewotICAgIGNhdGFsb2dGaWxlcyA9IGZpbGVMaXN0OwotICAgIGZyb21Qcm9wZXJ0aWVzRmlsZSA9IGZhbHNlOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgY3VycmVudCBsaXN0IG9mIGNhdGFsb2cgZmlsZXMuCi0gICAqCi0gICAqIEByZXR1cm4gQSB2ZWN0b3Igb2YgdGhlIGNhdGFsb2cgZmlsZSBuYW1lcyBvciBudWxsIGlmIG5vIGNhdGFsb2dzCi0gICAqIGFyZSBhdmFpbGFibGUgaW4gdGhlIHByb3BlcnRpZXMuCi0gICAqCi0gICAqIEBkZXByZWNhdGVkIE5vIGxvbmdlciBzdGF0aWM7IHVzZSBnZXQvc2V0IG1ldGhvZHMuCi0gICAqLwotICBwdWJsaWMgVmVjdG9yIGNhdGFsb2dGaWxlcygpIHsKLSAgICByZXR1cm4gZ2V0Q2F0YWxvZ0ZpbGVzKCk7Ci0gIH0KLQotICAvKioKLSAgICogT2J0YWluIHRoZSBwcmVmZXJQdWJsaWMgc2V0dGluZyBmcm9tIHRoZSBwcm9wZXJ0aWVzLgotICAgKgotICAgKiA8cD5JbiB0aGUgcHJvcGVydGllcywgYSB2YWx1ZSBvZiAncHVibGljJyBpcyB0cnVlLAotICAgKiBhbnl0aGluZyBlbHNlIGlzIGZhbHNlLjwvcD4KLSAgICoKLSAgICogQHJldHVybiBUcnVlIGlmIHByZWZlciBpcyBwdWJsaWMgb3IgdGhlCi0gICAqIGRlZmF1bHRQcmVmZXJTZXR0aW5nLgotICAgKi8KLSAgcHJpdmF0ZSBib29sZWFuIHF1ZXJ5UHJlZmVyUHVibGljICgpIHsKLSAgICBTdHJpbmcgcHJlZmVyID0gU2VjdXJpdHlTdXBwb3J0LmdldFN5c3RlbVByb3BlcnR5KHBQcmVmZXIpOwotCi0gICAgaWYgKHByZWZlciA9PSBudWxsKSB7Ci0gICAgICBpZiAocmVzb3VyY2VzPT1udWxsKSByZWFkUHJvcGVydGllcygpOwotICAgICAgaWYgKHJlc291cmNlcz09bnVsbCkgcmV0dXJuIGRlZmF1bHRQcmVmZXJQdWJsaWM7Ci0gICAgICB0cnkgewotICAgICAgICBwcmVmZXIgPSByZXNvdXJjZXMuZ2V0U3RyaW5nKCJwcmVmZXIiKTsKLSAgICAgIH0gY2F0Y2ggKE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgIHJldHVybiBkZWZhdWx0UHJlZmVyUHVibGljOwotICAgICAgfQotICAgIH0KLQotICAgIGlmIChwcmVmZXIgPT0gbnVsbCkgewotICAgICAgcmV0dXJuIGRlZmF1bHRQcmVmZXJQdWJsaWM7Ci0gICAgfQotCi0gICAgcmV0dXJuIChwcmVmZXIuZXF1YWxzSWdub3JlQ2FzZSgicHVibGljIikpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgY3VycmVudCBwcmVmZXIgcHVibGljIHNldHRpbmcuCi0gICAqCi0gICAqIEByZXR1cm4gVHJ1ZSBpZiBwdWJsaWMgaWRlbnRpZmllcnMgYXJlIHByZWZlcnJlZC4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGdldFByZWZlclB1YmxpYyAoKSB7Ci0gICAgaWYgKHByZWZlclB1YmxpYyA9PSBudWxsKSB7Ci0gICAgICBwcmVmZXJQdWJsaWMgPSBuZXcgQm9vbGVhbihxdWVyeVByZWZlclB1YmxpYygpKTsKLSAgICB9Ci0gICAgcmV0dXJuIHByZWZlclB1YmxpYy5ib29sZWFuVmFsdWUoKTsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIHByZWZlciBwdWJsaWMgc2V0dGluZy4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFByZWZlclB1YmxpYyAoYm9vbGVhbiBwcmVmZXJQdWJsaWMpIHsKLSAgICB0aGlzLnByZWZlclB1YmxpYyA9IG5ldyBCb29sZWFuKHByZWZlclB1YmxpYyk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBjdXJyZW50IHByZWZlciBwdWJsaWMgc2V0dGluZy4KLSAgICoKLSAgICogQHJldHVybiBUcnVlIGlmIHB1YmxpYyBpZGVudGlmaWVycyBhcmUgcHJlZmVycmVkLgotICAgKgotICAgKiBAZGVwcmVjYXRlZCBObyBsb25nZXIgc3RhdGljOyB1c2UgZ2V0L3NldCBtZXRob2RzLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gcHJlZmVyUHVibGljICgpIHsKLSAgICByZXR1cm4gZ2V0UHJlZmVyUHVibGljKCk7Ci0gIH0KLQotICAvKioKLSAgICogT2J0YWluIHRoZSBzdGF0aWMtY2F0YWxvZyBzZXR0aW5nIGZyb20gdGhlIHByb3BlcnRpZXMuCi0gICAqCi0gICAqIDxwPkluIHRoZSBwcm9wZXJ0aWVzLCBhIHZhbHVlIG9mICd5ZXMnLCAndHJ1ZScsIG9yICcxJyBpcyBjb25zaWRlcmVkCi0gICAqIHRydWUsIGFueXRoaW5nIGVsc2UgaXMgZmFsc2UuPC9wPgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBzdGF0aWMtY2F0YWxvZyBzZXR0aW5nIGZyb20gdGhlIHByb3BlcnR5RmlsZSBvciB0aGUKLSAgICogZGVmYXVsdFVzZVN0YXRpY0NhdGFsb2cuCi0gICAqLwotICBwcml2YXRlIGJvb2xlYW4gcXVlcnlVc2VTdGF0aWNDYXRhbG9nICgpIHsKLSAgICBTdHJpbmcgc3RhdGljQ2F0YWxvZyA9IFNlY3VyaXR5U3VwcG9ydC5nZXRTeXN0ZW1Qcm9wZXJ0eShwU3RhdGljKTsKLQotICAgIGlmIChzdGF0aWNDYXRhbG9nID09IG51bGwpIHsKLSAgICAgIGlmIChyZXNvdXJjZXM9PW51bGwpIHJlYWRQcm9wZXJ0aWVzKCk7Ci0gICAgICBpZiAocmVzb3VyY2VzPT1udWxsKSByZXR1cm4gZGVmYXVsdFVzZVN0YXRpY0NhdGFsb2c7Ci0gICAgICB0cnkgewotICAgICAgICBzdGF0aWNDYXRhbG9nID0gcmVzb3VyY2VzLmdldFN0cmluZygic3RhdGljLWNhdGFsb2ciKTsKLSAgICAgIH0gY2F0Y2ggKE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgIHJldHVybiBkZWZhdWx0VXNlU3RhdGljQ2F0YWxvZzsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICBpZiAoc3RhdGljQ2F0YWxvZyA9PSBudWxsKSB7Ci0gICAgICByZXR1cm4gZGVmYXVsdFVzZVN0YXRpY0NhdGFsb2c7Ci0gICAgfQotCi0gICAgcmV0dXJuIChzdGF0aWNDYXRhbG9nLmVxdWFsc0lnbm9yZUNhc2UoInRydWUiKQotICAgICAgICAgICAgfHwgc3RhdGljQ2F0YWxvZy5lcXVhbHNJZ25vcmVDYXNlKCJ5ZXMiKQotICAgICAgICAgICAgfHwgc3RhdGljQ2F0YWxvZy5lcXVhbHNJZ25vcmVDYXNlKCIxIikpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgY3VycmVudCB1c2Ugc3RhdGljIGNhdGFsb2cgc2V0dGluZy4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGdldFVzZVN0YXRpY0NhdGFsb2coKSB7Ci0gICAgaWYgKHVzZVN0YXRpY0NhdGFsb2cgPT0gbnVsbCkgewotICAgICAgdXNlU3RhdGljQ2F0YWxvZyA9IG5ldyBCb29sZWFuKHF1ZXJ5VXNlU3RhdGljQ2F0YWxvZygpKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gdXNlU3RhdGljQ2F0YWxvZy5ib29sZWFuVmFsdWUoKTsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIHVzZSBzdGF0aWMgY2F0YWxvZyBzZXR0aW5nLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0VXNlU3RhdGljQ2F0YWxvZyhib29sZWFuIHVzZVN0YXRpYykgewotICAgIHVzZVN0YXRpY0NhdGFsb2cgPSBuZXcgQm9vbGVhbih1c2VTdGF0aWMpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgY3VycmVudCB1c2Ugc3RhdGljIGNhdGFsb2cgc2V0dGluZy4KLSAgICoKLSAgICogQGRlcHJlY2F0ZWQgTm8gbG9uZ2VyIHN0YXRpYzsgdXNlIGdldC9zZXQgbWV0aG9kcy4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIHN0YXRpY0NhdGFsb2coKSB7Ci0gICAgcmV0dXJuIGdldFVzZVN0YXRpY0NhdGFsb2coKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgYSBuZXcgY2F0YWxvZyBpbnN0YW5jZS4KLSAgICoKLSAgICogVGhpcyBtZXRob2QgYWx3YXlzIHJldHVybnMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhlIHVuZGVybHlpbmcgY2F0YWxvZyBjbGFzcy4KLSAgICovCi0gIHB1YmxpYyBDYXRhbG9nIGdldFByaXZhdGVDYXRhbG9nKCkgewotICAgIENhdGFsb2cgY2F0YWxvZyA9IHN0YXRpY0NhdGFsb2c7Ci0KLSAgICBpZiAodXNlU3RhdGljQ2F0YWxvZyA9PSBudWxsKSB7Ci0gICAgICB1c2VTdGF0aWNDYXRhbG9nID0gbmV3IEJvb2xlYW4oZ2V0VXNlU3RhdGljQ2F0YWxvZygpKTsKLSAgICB9Ci0KLSAgICBpZiAoY2F0YWxvZyA9PSBudWxsIHx8ICF1c2VTdGF0aWNDYXRhbG9nLmJvb2xlYW5WYWx1ZSgpKSB7Ci0KLSAgICAgIHRyeSB7Ci0gICAgICAgIFN0cmluZyBjYXRhbG9nQ2xhc3NOYW1lID0gZ2V0Q2F0YWxvZ0NsYXNzTmFtZSgpOwotCi0gICAgICAgIGlmIChjYXRhbG9nQ2xhc3NOYW1lID09IG51bGwpIHsKLSAgICAgICAgICBjYXRhbG9nID0gbmV3IENhdGFsb2coKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICB0cnkgewotICAgICAgICAgICAgY2F0YWxvZyA9IChDYXRhbG9nKSBSZWZsZWN0VXRpbC5mb3JOYW1lKGNhdGFsb2dDbGFzc05hbWUpLm5ld0luc3RhbmNlKCk7Ci0gICAgICAgICAgfSBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBjbmZlKSB7Ci0gICAgICAgICAgICBkZWJ1Zy5tZXNzYWdlKDEsIkNhdGFsb2cgY2xhc3MgbmFtZWQgJyIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgKyBjYXRhbG9nQ2xhc3NOYW1lCi0gICAgICAgICAgICAgICAgICAgICAgICAgICsgIicgY291bGQgbm90IGJlIGZvdW5kLiBVc2luZyBkZWZhdWx0LiIpOwotICAgICAgICAgICAgY2F0YWxvZyA9IG5ldyBDYXRhbG9nKCk7Ci0gICAgICAgICAgfSBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGNuZmUpIHsKLSAgICAgICAgICAgIGRlYnVnLm1lc3NhZ2UoMSwiQ2xhc3MgbmFtZWQgJyIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgKyBjYXRhbG9nQ2xhc3NOYW1lCi0gICAgICAgICAgICAgICAgICAgICAgICAgICsgIicgaXMgbm90IGEgQ2F0YWxvZy4gVXNpbmcgZGVmYXVsdC4iKTsKLSAgICAgICAgICAgIGNhdGFsb2cgPSBuZXcgQ2F0YWxvZygpOwotICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGNhdGFsb2cuc2V0Q2F0YWxvZ01hbmFnZXIodGhpcyk7Ci0gICAgICAgIGNhdGFsb2cuc2V0dXBSZWFkZXJzKCk7Ci0gICAgICAgIGNhdGFsb2cubG9hZFN5c3RlbUNhdGFsb2dzKCk7Ci0gICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKLSAgICAgICAgZXgucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICB9Ci0KLSAgICAgIGlmICh1c2VTdGF0aWNDYXRhbG9nLmJvb2xlYW5WYWx1ZSgpKSB7Ci0gICAgICAgIHN0YXRpY0NhdGFsb2cgPSBjYXRhbG9nOwotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiBjYXRhbG9nOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBhIGNhdGFsb2cgaW5zdGFuY2UuCi0gICAqCi0gICAqIElmIHRoaXMgbWFuYWdlciB1c2VzIHN0YXRpYyBjYXRhbG9ncywgdGhlIHNhbWUgc3RhdGljIGNhdGFsb2cgd2lsbAotICAgKiBhbHdheXMgYmUgcmV0dXJuZWQuIE90aGVyd2lzZSBhIG5ldyBjYXRhbG9nIHdpbGwgYmUgcmV0dXJuZWQuCi0gICAqLwotICBwdWJsaWMgQ2F0YWxvZyBnZXRDYXRhbG9nKCkgewotICAgIENhdGFsb2cgY2F0YWxvZyA9IHN0YXRpY0NhdGFsb2c7Ci0KLSAgICBpZiAodXNlU3RhdGljQ2F0YWxvZyA9PSBudWxsKSB7Ci0gICAgICB1c2VTdGF0aWNDYXRhbG9nID0gbmV3IEJvb2xlYW4oZ2V0VXNlU3RhdGljQ2F0YWxvZygpKTsKLSAgICB9Ci0KLSAgICBpZiAoY2F0YWxvZyA9PSBudWxsIHx8ICF1c2VTdGF0aWNDYXRhbG9nLmJvb2xlYW5WYWx1ZSgpKSB7Ci0gICAgICBjYXRhbG9nID0gZ2V0UHJpdmF0ZUNhdGFsb2coKTsKLSAgICAgIGlmICh1c2VTdGF0aWNDYXRhbG9nLmJvb2xlYW5WYWx1ZSgpKSB7Ci0gICAgICAgIHN0YXRpY0NhdGFsb2cgPSBjYXRhbG9nOwotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiBjYXRhbG9nOwotICB9Ci0KLSAgLyoqCi0gICAqIDxwPk9idGFpbiB0aGUgb2FzaXNYTUxDYXRhbG9nUEkgc2V0dGluZyBmcm9tIHRoZSBwcm9wZXJ0aWVzLjwvcD4KLSAgICoKLSAgICogPHA+SW4gdGhlIHByb3BlcnRpZXMsIGEgdmFsdWUgb2YgJ3llcycsICd0cnVlJywgb3IgJzEnIGlzIGNvbnNpZGVyZWQKLSAgICogdHJ1ZSwgYW55dGhpbmcgZWxzZSBpcyBmYWxzZS48L3A+Ci0gICAqCi0gICAqIEByZXR1cm4gVGhlIG9hc2lzWE1MQ2F0YWxvZ1BJIHNldHRpbmcgZnJvbSB0aGUgcHJvcGVydHlGaWxlIG9yIHRoZQotICAgKiBkZWZhdWx0T2FzaXNYTUxDYXRhbG9nUEkuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBxdWVyeUFsbG93T2FzaXNYTUxDYXRhbG9nUEkgKCkgewotICAgIFN0cmluZyBhbGxvdyA9IFNlY3VyaXR5U3VwcG9ydC5nZXRTeXN0ZW1Qcm9wZXJ0eShwQWxsb3dQSSk7Ci0KLSAgICBpZiAoYWxsb3cgPT0gbnVsbCkgewotICAgICAgaWYgKHJlc291cmNlcz09bnVsbCkgcmVhZFByb3BlcnRpZXMoKTsKLSAgICAgIGlmIChyZXNvdXJjZXM9PW51bGwpIHJldHVybiBkZWZhdWx0T2FzaXNYTUxDYXRhbG9nUEk7Ci0gICAgICB0cnkgewotICAgICAgICBhbGxvdyA9IHJlc291cmNlcy5nZXRTdHJpbmcoImFsbG93LW9hc2lzLXhtbC1jYXRhbG9nLXBpIik7Ci0gICAgICB9IGNhdGNoIChNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24gZSkgewotICAgICAgICByZXR1cm4gZGVmYXVsdE9hc2lzWE1MQ2F0YWxvZ1BJOwotICAgICAgfQotICAgIH0KLQotICAgIGlmIChhbGxvdyA9PSBudWxsKSB7Ci0gICAgICByZXR1cm4gZGVmYXVsdE9hc2lzWE1MQ2F0YWxvZ1BJOwotICAgIH0KLQotICAgIHJldHVybiAoYWxsb3cuZXF1YWxzSWdub3JlQ2FzZSgidHJ1ZSIpCi0gICAgICAgICAgICB8fCBhbGxvdy5lcXVhbHNJZ25vcmVDYXNlKCJ5ZXMiKQotICAgICAgICAgICAgfHwgYWxsb3cuZXF1YWxzSWdub3JlQ2FzZSgiMSIpKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGN1cnJlbnQgWE1MIENhdGFsb2cgUEkgc2V0dGluZy4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGdldEFsbG93T2FzaXNYTUxDYXRhbG9nUEkgKCkgewotICAgIGlmIChvYXNpc1hNTENhdGFsb2dQSSA9PSBudWxsKSB7Ci0gICAgICBvYXNpc1hNTENhdGFsb2dQSSA9IG5ldyBCb29sZWFuKHF1ZXJ5QWxsb3dPYXNpc1hNTENhdGFsb2dQSSgpKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gb2FzaXNYTUxDYXRhbG9nUEkuYm9vbGVhblZhbHVlKCk7Ci0gIH0KLQotICBwdWJsaWMgYm9vbGVhbiB1c2VTZXJ2aWNlc01lY2hhbmlzbSgpIHsKLSAgICAgIHJldHVybiB1c2VTZXJ2aWNlc01lY2hhbmlzbTsKLSAgfQotICAvKioKLSAgICogU2V0IHRoZSBYTUwgQ2F0YWxvZyBQSSBzZXR0aW5nCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRBbGxvd09hc2lzWE1MQ2F0YWxvZ1BJKGJvb2xlYW4gYWxsb3dQSSkgewotICAgIG9hc2lzWE1MQ2F0YWxvZ1BJID0gbmV3IEJvb2xlYW4oYWxsb3dQSSk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBjdXJyZW50IFhNTCBDYXRhbG9nIFBJIHNldHRpbmcuCi0gICAqCi0gICAqIEBkZXByZWNhdGVkIE5vIGxvbmdlciBzdGF0aWM7IHVzZSBnZXQvc2V0IG1ldGhvZHMuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBhbGxvd09hc2lzWE1MQ2F0YWxvZ1BJKCkgewotICAgIHJldHVybiBnZXRBbGxvd09hc2lzWE1MQ2F0YWxvZ1BJKCk7Ci0gIH0KLQotICAvKioKLSAgICogT2J0YWluIHRoZSBDYXRhbG9nIGNsYXNzIG5hbWUgc2V0dGluZyBmcm9tIHRoZSBwcm9wZXJ0aWVzLgotICAgKgotICAgKi8KLSAgcHVibGljIFN0cmluZyBxdWVyeUNhdGFsb2dDbGFzc05hbWUgKCkgewotICAgIFN0cmluZyBjbGFzc05hbWUgPSBTZWN1cml0eVN1cHBvcnQuZ2V0U3lzdGVtUHJvcGVydHkocENsYXNzbmFtZSk7Ci0KLSAgICBpZiAoY2xhc3NOYW1lID09IG51bGwpIHsKLSAgICAgIGlmIChyZXNvdXJjZXM9PW51bGwpIHJlYWRQcm9wZXJ0aWVzKCk7Ci0gICAgICBpZiAocmVzb3VyY2VzPT1udWxsKSByZXR1cm4gbnVsbDsKLSAgICAgIHRyeSB7Ci0gICAgICAgIHJldHVybiByZXNvdXJjZXMuZ2V0U3RyaW5nKCJjYXRhbG9nLWNsYXNzLW5hbWUiKTsKLSAgICAgIH0gY2F0Y2ggKE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiBjbGFzc05hbWU7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBjdXJyZW50IENhdGFsb2cgY2xhc3MgbmFtZS4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0Q2F0YWxvZ0NsYXNzTmFtZSgpIHsKLSAgICBpZiAoY2F0YWxvZ0NsYXNzTmFtZSA9PSBudWxsKSB7Ci0gICAgICBjYXRhbG9nQ2xhc3NOYW1lID0gcXVlcnlDYXRhbG9nQ2xhc3NOYW1lKCk7Ci0gICAgfQotCi0gICAgcmV0dXJuIGNhdGFsb2dDbGFzc05hbWU7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBDYXRhbG9nIGNsYXNzIG5hbWUuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRDYXRhbG9nQ2xhc3NOYW1lKFN0cmluZyBjbGFzc05hbWUpIHsKLSAgICBjYXRhbG9nQ2xhc3NOYW1lID0gY2xhc3NOYW1lOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgY3VycmVudCBDYXRhbG9nIGNsYXNzIG5hbWUuCi0gICAqCi0gICAqIEBkZXByZWNhdGVkIE5vIGxvbmdlciBzdGF0aWM7IHVzZSBnZXQvc2V0IG1ldGhvZHMuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGNhdGFsb2dDbGFzc05hbWUoKSB7Ci0gICAgcmV0dXJuIGdldENhdGFsb2dDbGFzc05hbWUoKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvcmVzb2x2ZXIvUmVzb2x2ZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3Jlc29sdmVyL1Jlc29sdmVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDcyMWQ2N2MuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvcmVzb2x2ZXIvUmVzb2x2ZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDY5NCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLy8gUmVzb2x2ZXIuamF2YSAtIFJlcHJlc2VudHMgYW4gZXh0ZW5zaW9uIG9mIE9BU0lTIE9wZW4gQ2F0YWxvZyBmaWxlcy4KLQotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIG9yIGl0cyBsaWNlbnNvcnMsCi0gKiBhcyBhcHBsaWNhYmxlLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzb2x2ZXI7Ci0KLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5pby5GaWxlTm90Rm91bmRFeGNlcHRpb247Ci1pbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOwotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci1pbXBvcnQgamF2YS5uZXQuVVJMOwotaW1wb3J0IGphdmEubmV0LlVSTENvbm5lY3Rpb247Ci1pbXBvcnQgamF2YS5uZXQuTWFsZm9ybWVkVVJMRXhjZXB0aW9uOwotaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLlNBWFBhcnNlckZhY3Rvcnk7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5qYXhwLlNBWFBhcnNlckZhY3RvcnlJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbHMuU2VjdXJpdHlTdXBwb3J0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzb2x2ZXIucmVhZGVycy5TQVhDYXRhbG9nUmVhZGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzb2x2ZXIucmVhZGVycy5PQVNJU1hNTENhdGFsb2dSZWFkZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXNvbHZlci5yZWFkZXJzLlRSOTQwMUNhdGFsb2dSZWFkZXI7Ci0KLS8qKgotICogQW4gZXh0ZW5zaW9uIHRvIE9BU0lTIE9wZW4gQ2F0YWxvZyBmaWxlcywgdGhpcyBjbGFzcyBzdXBwb3J0cwotICogc3VmZml4LWJhc2VkIG1hdGNoaW5nIGFuZCBhbiBleHRlcm5hbCBSRkMyNDgzIHJlc29sdmVyLgotICoKLSAqIEBzZWUgQ2F0YWxvZwotICoKLSAqIEBhdXRob3IgTm9ybWFuIFdhbHNoCi0gKiA8YSBocmVmPSJtYWlsdG86Tm9ybWFuLldhbHNoQFN1bi5DT00iPk5vcm1hbi5XYWxzaEBTdW4uQ09NPC9hPgotICoKLSAqIEB2ZXJzaW9uIDEuMAotICovCi1wdWJsaWMgY2xhc3MgUmVzb2x2ZXIgZXh0ZW5kcyBDYXRhbG9nIHsKLSAgLyoqCi0gICAqIFRoZSBVUklTVUZGSVggQ2F0YWxvZyBFbnRyeSB0eXBlLgotICAgKgotICAgKiA8cD5VUkkgc3VmZml4IGVudHJpZXMgbWF0Y2ggVVJJcyB0aGF0IGVuZCBpbiBhIHNwZWNpZmllZCBzdWZmaXguPC9wPgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVVJJU1VGRklYID0gQ2F0YWxvZ0VudHJ5LmFkZEVudHJ5VHlwZSgiVVJJU1VGRklYIiwgMik7Ci0KLSAgLyoqCi0gICAqIFRoZSBTWVNURU1TVUZGSVggQ2F0YWxvZyBFbnRyeSB0eXBlLgotICAgKgotICAgKiA8cD5TeXN0ZW0gc3VmZml4IGVudHJpZXMgbWF0Y2ggc3lzdGVtIGlkZW50aWZpZXJzIHRoYXQgZW5kIGluIGEKLSAgICogc3BlY2lmaWVkIHN1ZmZpeC48L3A+Ci0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTWVNURU1TVUZGSVggPSBDYXRhbG9nRW50cnkuYWRkRW50cnlUeXBlKCJTWVNURU1TVUZGSVgiLCAyKTsKLQotICAvKioKLSAgICogVGhlIFJFU09MVkVSIENhdGFsb2cgRW50cnkgdHlwZS4KLSAgICoKLSAgICogPHA+QSBob29rIGZvciBwcm92aWRpbmcgc3VwcG9ydCBmb3Igd2ViLWJhc2VkIGJhY2t1cCByZXNvbHZlcnMuPC9wPgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVTT0xWRVIgPSBDYXRhbG9nRW50cnkuYWRkRW50cnlUeXBlKCJSRVNPTFZFUiIsIDEpOwotCi0gIC8qKgotICAgKiBUaGUgU1lTVEVNUkVWRVJTRSBDYXRhbG9nIEVudHJ5IHR5cGUuCi0gICAqCi0gICAqIDxwPlRoaXMgaXMgYSBiaXQgb2YgYSBoYWNrLiBUaGVyZSdzIG5vIGFjdHVhbCBTWVNURU1SRVZFUlNFIGVudHJ5LAotICAgKiBidXQgdGhpcyBlbnRyeSB0eXBlIGlzIHVzZWQgdG8gaW5kaWNhdGUgdGhhdCBhIHJldmVyc2UgbG9va3VwIGlzCi0gICAqIGJlaW5nIHBlcmZvcm1lZC4gKFRoaXMgYWxsb3dzIHRoZSBSZXNvbHZlciB0byBpbXBsZW1lbnQKLSAgICogUkZDMjQ4MyBJMk4gYW5kIEkyTlMuKQotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1lTVEVNUkVWRVJTRQotICAgID0gQ2F0YWxvZ0VudHJ5LmFkZEVudHJ5VHlwZSgiU1lTVEVNUkVWRVJTRSIsIDEpOwotCi0gIC8qKgotICAgKiBTZXR1cCByZWFkZXJzLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0dXBSZWFkZXJzKCkgewotICAgIFNBWFBhcnNlckZhY3Rvcnkgc3BmID0gY2F0YWxvZ01hbmFnZXIudXNlU2VydmljZXNNZWNoYW5pc20oKSA/Ci0gICAgICAgICAgICAgICAgICAgIFNBWFBhcnNlckZhY3RvcnkubmV3SW5zdGFuY2UoKSA6IG5ldyBTQVhQYXJzZXJGYWN0b3J5SW1wbCgpOwotICAgIHNwZi5zZXROYW1lc3BhY2VBd2FyZSh0cnVlKTsKLSAgICBzcGYuc2V0VmFsaWRhdGluZyhmYWxzZSk7Ci0KLSAgICBTQVhDYXRhbG9nUmVhZGVyIHNheFJlYWRlciA9IG5ldyBTQVhDYXRhbG9nUmVhZGVyKHNwZik7Ci0KLSAgICBzYXhSZWFkZXIuc2V0Q2F0YWxvZ1BhcnNlcihudWxsLCAiWE1MQ2F0YWxvZyIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzb2x2ZXIucmVhZGVycy5YQ2F0YWxvZ1JlYWRlciIpOwotCi0gICAgc2F4UmVhZGVyLnNldENhdGFsb2dQYXJzZXIoT0FTSVNYTUxDYXRhbG9nUmVhZGVyLm5hbWVzcGFjZU5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImNhdGFsb2ciLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnJlc29sdmVyLnJlYWRlcnMuRXh0ZW5kZWRYTUxDYXRhbG9nUmVhZGVyIik7Ci0KLSAgICBhZGRSZWFkZXIoImFwcGxpY2F0aW9uL3htbCIsIHNheFJlYWRlcik7Ci0KLSAgICBUUjk0MDFDYXRhbG9nUmVhZGVyIHRleHRSZWFkZXIgPSBuZXcgVFI5NDAxQ2F0YWxvZ1JlYWRlcigpOwotICAgIGFkZFJlYWRlcigidGV4dC9wbGFpbiIsIHRleHRSZWFkZXIpOwotICB9Ci0KLSAgLyoqCi0gICAqIENsZWFudXAgYW5kIHByb2Nlc3MgYSBDYXRhbG9nIGVudHJ5LgotICAgKgotICAgKiA8cD5UaGlzIG1ldGhvZCBwcm9jZXNzZXMgZWFjaCBDYXRhbG9nIGVudHJ5LCBjaGFuZ2luZyBtYXBwZWQKLSAgICogcmVsYXRpdmUgc3lzdGVtIGlkZW50aWZpZXJzIGludG8gYWJzb2x1dGUgb25lcyAoYmFzZWQgb24gdGhlIGN1cnJlbnQKLSAgICogYmFzZSBVUkkpLCBhbmQgbWFpbnRhaW5pbmcgb3RoZXIgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGN1cnJlbnQKLSAgICogY2F0YWxvZy48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBlbnRyeSBUaGUgQ2F0YWxvZ0VudHJ5IHRvIHByb2Nlc3MuCi0gICAqLwotICBwdWJsaWMgdm9pZCBhZGRFbnRyeShDYXRhbG9nRW50cnkgZW50cnkpIHsKLSAgICBpbnQgdHlwZSA9IGVudHJ5LmdldEVudHJ5VHlwZSgpOwotCi0gICAgaWYgKHR5cGUgPT0gVVJJU1VGRklYKSB7Ci0gICAgICBTdHJpbmcgc3VmZml4ID0gbm9ybWFsaXplVVJJKGVudHJ5LmdldEVudHJ5QXJnKDApKTsKLSAgICAgIFN0cmluZyBmc2kgPSBtYWtlQWJzb2x1dGUobm9ybWFsaXplVVJJKGVudHJ5LmdldEVudHJ5QXJnKDEpKSk7Ci0KLSAgICAgIGVudHJ5LnNldEVudHJ5QXJnKDEsIGZzaSk7Ci0KLSAgICAgIGNhdGFsb2dNYW5hZ2VyLmRlYnVnLm1lc3NhZ2UoNCwgIlVSSVNVRkZJWCIsIHN1ZmZpeCwgZnNpKTsKLSAgICB9IGVsc2UgaWYgKHR5cGUgPT0gU1lTVEVNU1VGRklYKSB7Ci0gICAgICBTdHJpbmcgc3VmZml4ID0gbm9ybWFsaXplVVJJKGVudHJ5LmdldEVudHJ5QXJnKDApKTsKLSAgICAgIFN0cmluZyBmc2kgPSBtYWtlQWJzb2x1dGUobm9ybWFsaXplVVJJKGVudHJ5LmdldEVudHJ5QXJnKDEpKSk7Ci0KLSAgICAgIGVudHJ5LnNldEVudHJ5QXJnKDEsIGZzaSk7Ci0KLSAgICAgIGNhdGFsb2dNYW5hZ2VyLmRlYnVnLm1lc3NhZ2UoNCwgIlNZU1RFTVNVRkZJWCIsIHN1ZmZpeCwgZnNpKTsKLSAgICB9Ci0KLSAgICBzdXBlci5hZGRFbnRyeShlbnRyeSk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBhcHBsaWNhYmxlIFVSSS4KLSAgICoKLSAgICogPHA+SWYgYSBVUkkgZW50cnkgZXhpc3RzIGluIHRoZSBDYXRhbG9nCi0gICAqIGZvciB0aGUgVVJJIHNwZWNpZmllZCwgcmV0dXJuIHRoZSBtYXBwZWQgdmFsdWUuPC9wPgotICAgKgotICAgKiA8cD5JbiB0aGUgUmVzb2x2ZXIgKGFzIG9wcG9zZWQgdG8gdGhlIENhdGFsb2cpIGNsYXNzLCBpZiB0aGUKLSAgICogVVJJIGlzbid0IGZvdW5kIGJ5IHRoZSB1c3VhbCBhbGdvcml0aG0sIFVSSVNVRkZJWCBlbnRyaWVzIGFyZQotICAgKiBjb25zaWRlcmVkLjwvcD4KLSAgICoKLSAgICogPHA+VVJJIGNvbXBhcmlzb24gaXMgY2FzZSBzZW5zaXRpdmUuPC9wPgotICAgKgotICAgKiBAcGFyYW0gdXJpIFRoZSBVUkkgdG8gbG9jYXRlIGluIHRoZSBjYXRhbG9nLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSByZXNvbHZlZCBVUkkuCi0gICAqCi0gICAqIEB0aHJvd3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uIFRoZSBzeXN0ZW0gaWRlbnRpZmllciBvZiBhCi0gICAqIHN1Ym9yZGluYXRlIGNhdGFsb2cgY2Fubm90IGJlIHR1cm5lZCBpbnRvIGEgdmFsaWQgVVJMLgotICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIEVycm9yIHJlYWRpbmcgc3Vib3JkaW5hdGUgY2F0YWxvZyBmaWxlLgotICAgKi8KLSAgcHVibGljIFN0cmluZyByZXNvbHZlVVJJKFN0cmluZyB1cmkpCi0gICAgdGhyb3dzIE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewotCi0gICAgU3RyaW5nIHJlc29sdmVkID0gc3VwZXIucmVzb2x2ZVVSSSh1cmkpOwotICAgIGlmIChyZXNvbHZlZCAhPSBudWxsKSB7Ci0gICAgICByZXR1cm4gcmVzb2x2ZWQ7Ci0gICAgfQotCi0gICAgRW51bWVyYXRpb24gZW4gPSBjYXRhbG9nRW50cmllcy5lbGVtZW50cygpOwotICAgIHdoaWxlIChlbi5oYXNNb3JlRWxlbWVudHMoKSkgewotICAgICAgQ2F0YWxvZ0VudHJ5IGUgPSAoQ2F0YWxvZ0VudHJ5KSBlbi5uZXh0RWxlbWVudCgpOwotICAgICAgaWYgKGUuZ2V0RW50cnlUeXBlKCkgPT0gUkVTT0xWRVIpIHsKLSAgICAgICAgcmVzb2x2ZWQgPSByZXNvbHZlRXh0ZXJuYWxTeXN0ZW0odXJpLCBlLmdldEVudHJ5QXJnKDApKTsKLSAgICAgICAgaWYgKHJlc29sdmVkICE9IG51bGwpIHsKLSAgICAgICAgICByZXR1cm4gcmVzb2x2ZWQ7Ci0gICAgICAgIH0KLSAgICAgIH0gZWxzZSBpZiAoZS5nZXRFbnRyeVR5cGUoKSA9PSBVUklTVUZGSVgpIHsKLSAgICAgICAgU3RyaW5nIHN1ZmZpeCA9IGUuZ2V0RW50cnlBcmcoMCk7Ci0gICAgICAgIFN0cmluZyByZXN1bHQgPSBlLmdldEVudHJ5QXJnKDEpOwotCi0gICAgICAgIGlmIChzdWZmaXgubGVuZ3RoKCkgPD0gdXJpLmxlbmd0aCgpCi0gICAgICAgICAgICAmJiB1cmkuc3Vic3RyaW5nKHVyaS5sZW5ndGgoKS1zdWZmaXgubGVuZ3RoKCkpLmVxdWFscyhzdWZmaXgpKSB7Ci0gICAgICAgICAgcmV0dXJuIHJlc3VsdDsKLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLQotICAgIC8vIE90aGVyd2lzZSwgbG9vayBpbiB0aGUgc3Vib3JkaW5hdGUgY2F0YWxvZ3MKLSAgICByZXR1cm4gcmVzb2x2ZVN1Ym9yZGluYXRlQ2F0YWxvZ3MoQ2F0YWxvZy5VUkksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVyaSk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBhcHBsaWNhYmxlIFNZU1RFTSBzeXN0ZW0gaWRlbnRpZmllciwgcmVzb3J0aW5nCi0gICAqIHRvIGV4dGVybmFsIFJFU09MVkVScyBpZiBuZWNlc3NhcnkuCi0gICAqCi0gICAqIDxwPklmIGEgU1lTVEVNIGVudHJ5IGV4aXN0cyBpbiB0aGUgQ2F0YWxvZwotICAgKiBmb3IgdGhlIHN5c3RlbSBJRCBzcGVjaWZpZWQsIHJldHVybiB0aGUgbWFwcGVkIHZhbHVlLjwvcD4KLSAgICoKLSAgICogPHA+SW4gdGhlIFJlc29sdmVyIChhcyBvcHBvc2VkIHRvIHRoZSBDYXRhbG9nKSBjbGFzcywgaWYgdGhlCi0gICAqIFVSSSBpc24ndCBmb3VuZCBieSB0aGUgdXN1YWwgYWxnb3JpdGhtLCBTWVNURU1TVUZGSVggZW50cmllcyBhcmUKLSAgICogY29uc2lkZXJlZC48L3A+Ci0gICAqCi0gICAqIDxwPk9uIFdpbmRvd3MtYmFzZWQgb3BlcmF0aW5nIHN5c3RlbXMsIHRoZSBjb21wYXJpc29uIGJldHdlZW4KLSAgICogdGhlIHN5c3RlbSBpZGVudGlmaWVyIHByb3ZpZGVkIGFuZCB0aGUgU1lTVEVNIGVudHJpZXMgaW4gdGhlCi0gICAqIENhdGFsb2cgaXMgY2FzZS1pbnNlbnNpdGl2ZS48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBzeXN0ZW1JZCBUaGUgc3lzdGVtIElEIHRvIGxvY2F0ZSBpbiB0aGUgY2F0YWxvZy4KLSAgICoKLSAgICogQHJldHVybiBUaGUgc3lzdGVtIGlkZW50aWZpZXIgdG8gdXNlIGZvciBzeXN0ZW1JZC4KLSAgICoKLSAgICogQHRocm93cyBNYWxmb3JtZWRVUkxFeGNlcHRpb24gVGhlIGZvcm1hbCBzeXN0ZW0gaWRlbnRpZmllciBvZiBhCi0gICAqIHN1Ym9yZGluYXRlIGNhdGFsb2cgY2Fubm90IGJlIHR1cm5lZCBpbnRvIGEgdmFsaWQgVVJMLgotICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIEVycm9yIHJlYWRpbmcgc3Vib3JkaW5hdGUgY2F0YWxvZyBmaWxlLgotICAgKi8KLSAgcHVibGljIFN0cmluZyByZXNvbHZlU3lzdGVtKFN0cmluZyBzeXN0ZW1JZCkKLSAgICB0aHJvd3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7Ci0KLSAgICBTdHJpbmcgcmVzb2x2ZWQgPSBzdXBlci5yZXNvbHZlU3lzdGVtKHN5c3RlbUlkKTsKLSAgICBpZiAocmVzb2x2ZWQgIT0gbnVsbCkgewotICAgICAgcmV0dXJuIHJlc29sdmVkOwotICAgIH0KLQotICAgIEVudW1lcmF0aW9uIGVuID0gY2F0YWxvZ0VudHJpZXMuZWxlbWVudHMoKTsKLSAgICB3aGlsZSAoZW4uaGFzTW9yZUVsZW1lbnRzKCkpIHsKLSAgICAgIENhdGFsb2dFbnRyeSBlID0gKENhdGFsb2dFbnRyeSkgZW4ubmV4dEVsZW1lbnQoKTsKLSAgICAgIGlmIChlLmdldEVudHJ5VHlwZSgpID09IFJFU09MVkVSKSB7Ci0gICAgICAgIHJlc29sdmVkID0gcmVzb2x2ZUV4dGVybmFsU3lzdGVtKHN5c3RlbUlkLCBlLmdldEVudHJ5QXJnKDApKTsKLSAgICAgICAgaWYgKHJlc29sdmVkICE9IG51bGwpIHsKLSAgICAgICAgICByZXR1cm4gcmVzb2x2ZWQ7Ci0gICAgICAgIH0KLSAgICAgIH0gZWxzZSBpZiAoZS5nZXRFbnRyeVR5cGUoKSA9PSBTWVNURU1TVUZGSVgpIHsKLSAgICAgICAgU3RyaW5nIHN1ZmZpeCA9IGUuZ2V0RW50cnlBcmcoMCk7Ci0gICAgICAgIFN0cmluZyByZXN1bHQgPSBlLmdldEVudHJ5QXJnKDEpOwotCi0gICAgICAgIGlmIChzdWZmaXgubGVuZ3RoKCkgPD0gc3lzdGVtSWQubGVuZ3RoKCkKLSAgICAgICAgICAgICYmIHN5c3RlbUlkLnN1YnN0cmluZyhzeXN0ZW1JZC5sZW5ndGgoKS1zdWZmaXgubGVuZ3RoKCkpLmVxdWFscyhzdWZmaXgpKSB7Ci0gICAgICAgICAgcmV0dXJuIHJlc3VsdDsKLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiByZXNvbHZlU3Vib3JkaW5hdGVDYXRhbG9ncyhDYXRhbG9nLlNZU1RFTSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3lzdGVtSWQpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgYXBwbGljYWJsZSBQVUJMSUMgb3IgU1lTVEVNIGlkZW50aWZpZXIsIHJlc29ydGluZwotICAgKiB0byBleHRlcm5hbCByZXNvbHZlcnMgaWYgbmVjZXNzYXJ5LgotICAgKgotICAgKiA8cD5UaGlzIG1ldGhvZCBzZWFyY2hlcyB0aGUgQ2F0YWxvZyBhbmQgcmV0dXJucyB0aGUgc3lzdGVtCi0gICAqIGlkZW50aWZpZXIgc3BlY2lmaWVkIGZvciB0aGUgZ2l2ZW4gc3lzdGVtIG9yCi0gICAqIHB1YmxpYyBpZGVudGlmaWVycy4gSWYKLSAgICogbm8gYXBwcm9wcmlhdGUgUFVCTElDIG9yIFNZU1RFTSBlbnRyeSBpcyBmb3VuZCBpbiB0aGUgQ2F0YWxvZywKLSAgICogbnVsbCBpcyByZXR1cm5lZC48L3A+Ci0gICAqCi0gICAqIDxwPk5vdGUgdGhhdCBhIHN5c3RlbSBvciBwdWJsaWMgaWRlbnRpZmllciBpbiB0aGUgY3VycmVudCBjYXRhbG9nCi0gICAqIChvciBzdWJvcmRpbmF0ZSBjYXRhbG9ncykgd2lsbCBiZSB1c2VkIGluIHByZWZlcmVuY2UgdG8gYW4KLSAgICogZXh0ZXJuYWwgcmVzb2x2ZXIuIEZ1cnRoZXIsIGlmIGEgc3lzdGVtSWQgaXMgcHJlc2VudCwgdGhlIGV4dGVybmFsCi0gICAqIHJlc29sdmVyKHMpIHdpbGwgYmUgcXVlcmllZCBmb3IgdGhhdCBiZWZvcmUgdGhlIHB1YmxpY0lkLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIHB1YmxpY0lkIFRoZSBwdWJsaWMgaWRlbnRpZmllciB0byBsb2NhdGUgaW4gdGhlIGNhdGFsb2cuCi0gICAqIFB1YmxpYyBpZGVudGlmaWVycyBhcmUgbm9ybWFsaXplZCBiZWZvcmUgY29tcGFyaXNvbi4KLSAgICogQHBhcmFtIHN5c3RlbUlkIFRoZSBub21pbmFsIHN5c3RlbSBpZGVudGlmaWVyIGZvciB0aGUgZW50aXR5Ci0gICAqIGluIHF1ZXN0aW9uIChhcyBwcm92aWRlZCBpbiB0aGUgc291cmNlIGRvY3VtZW50KS4KLSAgICoKLSAgICogQHRocm93cyBNYWxmb3JtZWRVUkxFeGNlcHRpb24gVGhlIGZvcm1hbCBzeXN0ZW0gaWRlbnRpZmllciBvZiBhCi0gICAqIHN1Ym9yZGluYXRlIGNhdGFsb2cgY2Fubm90IGJlIHR1cm5lZCBpbnRvIGEgdmFsaWQgVVJMLgotICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIEVycm9yIHJlYWRpbmcgc3Vib3JkaW5hdGUgY2F0YWxvZyBmaWxlLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBzeXN0ZW0gaWRlbnRpZmllciB0byB1c2UuCi0gICAqIE5vdGUgdGhhdCB0aGUgbm9taW5hbCBzeXN0ZW0gaWRlbnRpZmllciBpcyBub3QgcmV0dXJuZWQgaWYgYQotICAgKiBtYXRjaCBpcyBub3QgZm91bmQgaW4gdGhlIGNhdGFsb2csIGluc3RlYWQgbnVsbCBpcyByZXR1cm5lZAotICAgKiB0byBpbmRpY2F0ZSB0aGF0IG5vIG1hdGNoIHdhcyBmb3VuZC4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgcmVzb2x2ZVB1YmxpYyhTdHJpbmcgcHVibGljSWQsIFN0cmluZyBzeXN0ZW1JZCkKLSAgICB0aHJvd3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7Ci0KLSAgICBTdHJpbmcgcmVzb2x2ZWQgPSBzdXBlci5yZXNvbHZlUHVibGljKHB1YmxpY0lkLCBzeXN0ZW1JZCk7Ci0gICAgaWYgKHJlc29sdmVkICE9IG51bGwpIHsKLSAgICAgIHJldHVybiByZXNvbHZlZDsKLSAgICB9Ci0KLSAgICBFbnVtZXJhdGlvbiBlbiA9IGNhdGFsb2dFbnRyaWVzLmVsZW1lbnRzKCk7Ci0gICAgd2hpbGUgKGVuLmhhc01vcmVFbGVtZW50cygpKSB7Ci0gICAgICBDYXRhbG9nRW50cnkgZSA9IChDYXRhbG9nRW50cnkpIGVuLm5leHRFbGVtZW50KCk7Ci0gICAgICBpZiAoZS5nZXRFbnRyeVR5cGUoKSA9PSBSRVNPTFZFUikgewotICAgICAgICBpZiAoc3lzdGVtSWQgIT0gbnVsbCkgewotICAgICAgICAgIHJlc29sdmVkID0gcmVzb2x2ZUV4dGVybmFsU3lzdGVtKHN5c3RlbUlkLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGUuZ2V0RW50cnlBcmcoMCkpOwotICAgICAgICAgIGlmIChyZXNvbHZlZCAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gcmVzb2x2ZWQ7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJlc29sdmVkID0gcmVzb2x2ZUV4dGVybmFsUHVibGljKHB1YmxpY0lkLCBlLmdldEVudHJ5QXJnKDApKTsKLSAgICAgICAgaWYgKHJlc29sdmVkICE9IG51bGwpIHsKLSAgICAgICAgICByZXR1cm4gcmVzb2x2ZWQ7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gcmVzb2x2ZVN1Ym9yZGluYXRlQ2F0YWxvZ3MoQ2F0YWxvZy5QVUJMSUMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHB1YmxpY0lkLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeXN0ZW1JZCk7Ci0gIH0KLQotICAgIC8qKgotICAgICAqIFF1ZXJ5IGFuIGV4dGVybmFsIFJGQzI0ODMgcmVzb2x2ZXIgZm9yIGEgc3lzdGVtIGlkZW50aWZpZXIuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc3lzdGVtSWQgVGhlIHN5c3RlbSBJRCB0byBsb2NhdGUuCi0gICAgICogQHBhcmFtIHJlc29sdmVyIFRoZSBuYW1lIG9mIHRoZSByZXNvbHZlciB0byB1c2UuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBzeXN0ZW0gaWRlbnRpZmllciB0byB1c2UgZm9yIHRoZSBzeXN0ZW1JZC4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgU3RyaW5nIHJlc29sdmVFeHRlcm5hbFN5c3RlbShTdHJpbmcgc3lzdGVtSWQsIFN0cmluZyByZXNvbHZlcikKLSAgICAgICAgdGhyb3dzIE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewotICAgICAgICBSZXNvbHZlciByID0gcXVlcnlSZXNvbHZlcihyZXNvbHZlciwgImkybCIsIHN5c3RlbUlkLCBudWxsKTsKLSAgICAgICAgaWYgKHIgIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIHIucmVzb2x2ZVN5c3RlbShzeXN0ZW1JZCk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFF1ZXJ5IGFuIGV4dGVybmFsIFJGQzI0ODMgcmVzb2x2ZXIgZm9yIGEgcHVibGljIGlkZW50aWZpZXIuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcHVibGljSWQgVGhlIHN5c3RlbSBJRCB0byBsb2NhdGUuCi0gICAgICogQHBhcmFtIHJlc29sdmVyIFRoZSBuYW1lIG9mIHRoZSByZXNvbHZlciB0byB1c2UuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBzeXN0ZW0gaWRlbnRpZmllciB0byB1c2UgZm9yIHRoZSBzeXN0ZW1JZC4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgU3RyaW5nIHJlc29sdmVFeHRlcm5hbFB1YmxpYyhTdHJpbmcgcHVibGljSWQsIFN0cmluZyByZXNvbHZlcikKLSAgICAgICAgdGhyb3dzIE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewotICAgICAgICBSZXNvbHZlciByID0gcXVlcnlSZXNvbHZlcihyZXNvbHZlciwgImZwaTJsIiwgcHVibGljSWQsIG51bGwpOwotICAgICAgICBpZiAociAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gci5yZXNvbHZlUHVibGljKHB1YmxpY0lkLCBudWxsKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUXVlcnkgYW4gZXh0ZXJuYWwgUkZDMjQ4MyByZXNvbHZlci4KLSAgICAgKgotICAgICAqIEBwYXJhbSByZXNvbHZlciBUaGUgVVJMIG9mIHRoZSBSRkMyNDgzIHJlc29sdmVyLgotICAgICAqIEBwYXJhbSBjb21tYW5kIFRoZSBjb21tYW5kIHRvIHNlbmQgdGhlIHJlc29sdmVyLgotICAgICAqIEBwYXJhbSBhcmcxIFRoZSBmaXJzdCBhcmd1bWVudCB0byB0aGUgcmVzb2x2ZXIuCi0gICAgICogQHBhcmFtIGFyZzIgVGhlIHNlY29uZCBhcmd1bWVudCB0byB0aGUgcmVzb2x2ZXIsIHVzdWFsbHkgbnVsbC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIFJlc29sdmVyIGNvbnN0cnVjdGVkLgotICAgICAqLwotICAgIHByb3RlY3RlZCBSZXNvbHZlciBxdWVyeVJlc29sdmVyKFN0cmluZyByZXNvbHZlciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgY29tbWFuZCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgYXJnMSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgYXJnMikgewotICAgICAgICBJbnB1dFN0cmVhbSBpU3RyZWFtID0gbnVsbDsKLSAgICAgICAgU3RyaW5nIFJGQzI0ODMgPSByZXNvbHZlciArICI/Y29tbWFuZD0iICsgY29tbWFuZAotICAgICAgICAgICAgKyAiJmZvcm1hdD10cjk0MDEmdXJpPSIgKyBhcmcxCi0gICAgICAgICAgICArICImdXJpMj0iICsgYXJnMjsKLSAgICAgICAgU3RyaW5nIGxpbmUgPSBudWxsOwotCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBVUkwgdXJsID0gbmV3IFVSTChSRkMyNDgzKTsKLQotICAgICAgICAgICAgVVJMQ29ubmVjdGlvbiB1cmxDb24gPSB1cmwub3BlbkNvbm5lY3Rpb24oKTsKLQotICAgICAgICAgICAgdXJsQ29uLnNldFVzZUNhY2hlcyhmYWxzZSk7Ci0KLSAgICAgICAgICAgIFJlc29sdmVyIHIgPSAoUmVzb2x2ZXIpIG5ld0NhdGFsb2coKTsKLQotICAgICAgICAgICAgU3RyaW5nIGNUeXBlID0gdXJsQ29uLmdldENvbnRlbnRUeXBlKCk7Ci0KLSAgICAgICAgICAgIC8vIEkgZG9uJ3QgY2FyZSBhYm91dCB0aGUgY2hhcmFjdGVyIHNldCBvciBzdWJ0eXBlCi0gICAgICAgICAgICBpZiAoY1R5cGUuaW5kZXhPZigiOyIpID4gMCkgewotICAgICAgICAgICAgICAgIGNUeXBlID0gY1R5cGUuc3Vic3RyaW5nKDAsIGNUeXBlLmluZGV4T2YoIjsiKSk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIHIucGFyc2VDYXRhbG9nKGNUeXBlLCB1cmxDb24uZ2V0SW5wdXRTdHJlYW0oKSk7Ci0KLSAgICAgICAgICAgIHJldHVybiByOwotICAgICAgICB9IGNhdGNoIChDYXRhbG9nRXhjZXB0aW9uIGNleCkgewotICAgICAgICAgIGlmIChjZXguZ2V0RXhjZXB0aW9uVHlwZSgpID09IENhdGFsb2dFeGNlcHRpb24uVU5QQVJTRUFCTEUpIHsKLSAgICAgICAgICAgIGNhdGFsb2dNYW5hZ2VyLmRlYnVnLm1lc3NhZ2UoMSwgIlVucGFyc2VhYmxlIGNhdGFsb2c6ICIgKyBSRkMyNDgzKTsKLSAgICAgICAgICB9IGVsc2UgaWYgKGNleC5nZXRFeGNlcHRpb25UeXBlKCkKLSAgICAgICAgICAgICAgICAgICAgID09IENhdGFsb2dFeGNlcHRpb24uVU5LTk9XTl9GT1JNQVQpIHsKLSAgICAgICAgICAgIGNhdGFsb2dNYW5hZ2VyLmRlYnVnLm1lc3NhZ2UoMSwgIlVua25vd24gY2F0YWxvZyBmb3JtYXQ6ICIgKyBSRkMyNDgzKTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0gY2F0Y2ggKE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiBtdWUpIHsKLSAgICAgICAgICAgIGNhdGFsb2dNYW5hZ2VyLmRlYnVnLm1lc3NhZ2UoMSwgIk1hbGZvcm1lZCByZXNvbHZlciBVUkw6ICIgKyBSRkMyNDgzKTsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBpZSkgewotICAgICAgICAgICAgY2F0YWxvZ01hbmFnZXIuZGVidWcubWVzc2FnZSgxLCAiSS9PIEV4Y2VwdGlvbiBvcGVuaW5nIHJlc29sdmVyOiAiICsgUkZDMjQ4Myk7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEFwcGVuZCB0d28gdmVjdG9ycywgcmV0dXJuaW5nIHRoZSByZXN1bHQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdmVjIFRoZSBmaXJzdCB2ZWN0b3IKLSAgICAgKiBAcGFyYW0gYXBwdmVjIFRoZSB2ZWN0b3IgdG8gYmUgYXBwZW5kZWQKLSAgICAgKiBAcmV0dXJuIFRoZSB2ZWN0b3IgdmVjLCB3aXRoIGFwcHZlYydzIGVsZW1lbnRzIGFwcGVuZGVkIHRvIGl0Ci0gICAgICovCi0gICAgcHJpdmF0ZSBWZWN0b3IgYXBwZW5kVmVjdG9yKFZlY3RvciB2ZWMsIFZlY3RvciBhcHB2ZWMpIHsKLSAgICAgICAgaWYgKGFwcHZlYyAhPSBudWxsKSB7Ci0gICAgICAgICAgICBmb3IgKGludCBjb3VudCA9IDA7IGNvdW50IDwgYXBwdmVjLnNpemUoKTsgY291bnQrKykgewotICAgICAgICAgICAgICAgIHZlYy5hZGRFbGVtZW50KGFwcHZlYy5lbGVtZW50QXQoY291bnQpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gdmVjOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEZpbmQgdGhlIFVSTnMgZm9yIGEgZ2l2ZW4gc3lzdGVtIGlkZW50aWZpZXIgaW4gYWxsIGNhdGFsb2dzLgotICAgICAqCi0gICAgICogQHBhcmFtIHN5c3RlbUlkIFRoZSBzeXN0ZW0gSUQgdG8gbG9jYXRlLgotICAgICAqCi0gICAgICogQHJldHVybiBBIHZlY3RvciBvZiBVUk5zIHRoYXQgbWFwIHRvIHRoZSBzeXN0ZW1JZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgVmVjdG9yIHJlc29sdmVBbGxTeXN0ZW1SZXZlcnNlKFN0cmluZyBzeXN0ZW1JZCkKLSAgICAgICAgdGhyb3dzIE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewotICAgICAgICBWZWN0b3IgcmVzb2x2ZWQgPSBuZXcgVmVjdG9yKCk7Ci0KLSAgICAgICAgLy8gSWYgdGhlcmUncyBhIFNZU1RFTSBlbnRyeSBpbiB0aGlzIGNhdGFsb2csIHVzZSBpdAotICAgICAgICBpZiAoc3lzdGVtSWQgIT0gbnVsbCkgewotICAgICAgICAgICAgVmVjdG9yIGxvY2FsUmVzb2x2ZWQgPSByZXNvbHZlTG9jYWxTeXN0ZW1SZXZlcnNlKHN5c3RlbUlkKTsKLSAgICAgICAgICAgIHJlc29sdmVkID0gYXBwZW5kVmVjdG9yKHJlc29sdmVkLCBsb2NhbFJlc29sdmVkKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIE90aGVyd2lzZSwgbG9vayBpbiB0aGUgc3Vib3JkaW5hdGUgY2F0YWxvZ3MKLSAgICAgICAgVmVjdG9yIHN1YlJlc29sdmVkID0gcmVzb2x2ZUFsbFN1Ym9yZGluYXRlQ2F0YWxvZ3MoU1lTVEVNUkVWRVJTRSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3lzdGVtSWQpOwotCi0gICAgICAgIHJldHVybiBhcHBlbmRWZWN0b3IocmVzb2x2ZWQsIHN1YlJlc29sdmVkKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBGaW5kIHRoZSBVUk4gZm9yIGEgZ2l2ZW4gc3lzdGVtIGlkZW50aWZpZXIuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc3lzdGVtSWQgVGhlIHN5c3RlbSBJRCB0byBsb2NhdGUuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIEEgKHNpbmdsZSkgVVJOIHRoYXQgbWFwcyB0byB0aGUgc3lzdGVtSWQuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyByZXNvbHZlU3lzdGVtUmV2ZXJzZShTdHJpbmcgc3lzdGVtSWQpCi0gICAgICAgIHRocm93cyBNYWxmb3JtZWRVUkxFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKLSAgICAgICAgVmVjdG9yIHJlc29sdmVkID0gcmVzb2x2ZUFsbFN5c3RlbVJldmVyc2Uoc3lzdGVtSWQpOwotICAgICAgICBpZiAocmVzb2x2ZWQgIT0gbnVsbCAmJiByZXNvbHZlZC5zaXplKCkgPiAwKSB7Ci0gICAgICAgICAgICByZXR1cm4gKFN0cmluZykgcmVzb2x2ZWQuZWxlbWVudEF0KDApOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIGFwcGxpY2FibGUgU1lTVEVNIHN5c3RlbSBpZGVudGlmaWVycy4KLSAgICAgKgotICAgICAqIDxwPklmIG9uZSBvciBtb3JlIFNZU1RFTSBlbnRyaWVzIGV4aXN0cyBpbiB0aGUgQ2F0YWxvZwotICAgICAqIGZvciB0aGUgc3lzdGVtIElEIHNwZWNpZmllZCwgcmV0dXJuIHRoZSBtYXBwZWQgdmFsdWVzLjwvcD4KLSAgICAgKgotICAgICAqIDxwPlRoZSBjYWxsZXIgaXMgcmVzcG9uc2libGUgZm9yIGRvaW5nIGFueSBuZWNlc3NhcnkKLSAgICAgKiBub3JtYWxpemF0aW9uIG9mIHRoZSBzeXN0ZW0gaWRlbnRpZmllciBiZWZvcmUgY2FsbGluZwotICAgICAqIHRoaXMgbWV0aG9kLiBGb3IgZXhhbXBsZSwgYSByZWxhdGl2ZSBzeXN0ZW0gaWRlbnRpZmllciBpbgotICAgICAqIGEgZG9jdW1lbnQgbWlnaHQgYmUgY29udmVydGVkIHRvIGFuIGFic29sdXRlIHN5c3RlbSBpZGVudGlmaWVyCi0gICAgICogYmVmb3JlIGF0dGVtcHRpbmcgdG8gcmVzb2x2ZSBpdC48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5Ob3RlIHRoYXQgdGhpcyBmdW5jdGlvbiB3aWxsIGZvcmNlIGFsbCBzdWJvcmRpbmF0ZSBjYXRhbG9ncwotICAgICAqIHRvIGJlIGxvYWRlZC48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5PbiBXaW5kb3dzLWJhc2VkIG9wZXJhdGluZyBzeXN0ZW1zLCB0aGUgY29tcGFyaXNvbiBiZXR3ZWVuCi0gICAgICogdGhlIHN5c3RlbSBpZGVudGlmaWVyIHByb3ZpZGVkIGFuZCB0aGUgU1lTVEVNIGVudHJpZXMgaW4gdGhlCi0gICAgICogQ2F0YWxvZyBpcyBjYXNlLWluc2Vuc2l0aXZlLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzeXN0ZW1JZCBUaGUgc3lzdGVtIElEIHRvIGxvY2F0ZSBpbiB0aGUgY2F0YWxvZy4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIHN5c3RlbSBpZGVudGlmaWVyIHRvIHVzZSBmb3IgdGhlIG5vdGF0aW9uLgotICAgICAqCi0gICAgICogQHRocm93cyBNYWxmb3JtZWRVUkxFeGNlcHRpb24gVGhlIGZvcm1hbCBzeXN0ZW0gaWRlbnRpZmllciBvZiBhCi0gICAgICogc3Vib3JkaW5hdGUgY2F0YWxvZyBjYW5ub3QgYmUgdHVybmVkIGludG8gYSB2YWxpZCBVUkwuCi0gICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBFcnJvciByZWFkaW5nIHN1Ym9yZGluYXRlIGNhdGFsb2cgZmlsZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgVmVjdG9yIHJlc29sdmVBbGxTeXN0ZW0oU3RyaW5nIHN5c3RlbUlkKQotICAgICAgICB0aHJvd3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgIFZlY3RvciByZXNvbHV0aW9ucyA9IG5ldyBWZWN0b3IoKTsKLQotICAgICAgICAvLyBJZiB0aGVyZSBhcmUgU1lTVEVNIGVudHJpZXMgaW4gdGhpcyBjYXRhbG9nLCBzdGFydCB3aXRoIHRoZW0KLSAgICAgICAgaWYgKHN5c3RlbUlkICE9IG51bGwpIHsKLSAgICAgICAgICAgIFZlY3RvciBsb2NhbFJlc29sdXRpb25zID0gcmVzb2x2ZUFsbExvY2FsU3lzdGVtKHN5c3RlbUlkKTsKLSAgICAgICAgICAgIHJlc29sdXRpb25zID0gYXBwZW5kVmVjdG9yKHJlc29sdXRpb25zLCBsb2NhbFJlc29sdXRpb25zKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIFRoZW4gbG9vayBpbiB0aGUgc3Vib3JkaW5hdGUgY2F0YWxvZ3MKLSAgICAgICAgVmVjdG9yIHN1YlJlc29sdXRpb25zID0gcmVzb2x2ZUFsbFN1Ym9yZGluYXRlQ2F0YWxvZ3MoU1lTVEVNLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeXN0ZW1JZCk7Ci0gICAgICAgIHJlc29sdXRpb25zID0gYXBwZW5kVmVjdG9yKHJlc29sdXRpb25zLCBzdWJSZXNvbHV0aW9ucyk7Ci0KLSAgICAgICAgaWYgKHJlc29sdXRpb25zLnNpemUoKSA+IDApIHsKLSAgICAgICAgICAgIHJldHVybiByZXNvbHV0aW9uczsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIGFsbCBhcHBsaWNhYmxlIFNZU1RFTSBzeXN0ZW0gaWRlbnRpZmllcnMgaW4gdGhpcwotICAgICAqIGNhdGFsb2cuCi0gICAgICoKLSAgICAgKiA8cD5JZiBvbmUgb3IgbW9yZSBTWVNURU0gZW50cmllcyBleGlzdHMgaW4gdGhlIGNhdGFsb2cgZmlsZQotICAgICAqIGZvciB0aGUgc3lzdGVtIElEIHNwZWNpZmllZCwgcmV0dXJuIHRoZSBtYXBwZWQgdmFsdWVzLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzeXN0ZW1JZCBUaGUgc3lzdGVtIElEIHRvIGxvY2F0ZSBpbiB0aGUgY2F0YWxvZwotICAgICAqCi0gICAgICogQHJldHVybiBBIHZlY3RvciBvZiB0aGUgbWFwcGVkIHN5c3RlbSBpZGVudGlmaWVycyBvciBudWxsCi0gICAgICovCi0gICAgcHJpdmF0ZSBWZWN0b3IgcmVzb2x2ZUFsbExvY2FsU3lzdGVtKFN0cmluZyBzeXN0ZW1JZCkgewotICAgICAgICBWZWN0b3IgbWFwID0gbmV3IFZlY3RvcigpOwotICAgICAgICBTdHJpbmcgb3NuYW1lID0gU2VjdXJpdHlTdXBwb3J0LmdldFN5c3RlbVByb3BlcnR5KCJvcy5uYW1lIik7Ci0gICAgICAgIGJvb2xlYW4gd2luZG93cyA9IChvc25hbWUuaW5kZXhPZigiV2luZG93cyIpID49IDApOwotICAgICAgICBFbnVtZXJhdGlvbiBlbiA9IGNhdGFsb2dFbnRyaWVzLmVsZW1lbnRzKCk7Ci0gICAgICAgIHdoaWxlIChlbi5oYXNNb3JlRWxlbWVudHMoKSkgewotICAgICAgICAgICAgQ2F0YWxvZ0VudHJ5IGUgPSAoQ2F0YWxvZ0VudHJ5KSBlbi5uZXh0RWxlbWVudCgpOwotICAgICAgICAgICAgaWYgKGUuZ2V0RW50cnlUeXBlKCkgPT0gU1lTVEVNCi0gICAgICAgICAgICAgICAgJiYgKGUuZ2V0RW50cnlBcmcoMCkuZXF1YWxzKHN5c3RlbUlkKQotICAgICAgICAgICAgICAgICAgICB8fCAod2luZG93cwotICAgICAgICAgICAgICAgICAgICAgICAgJiYgZS5nZXRFbnRyeUFyZygwKS5lcXVhbHNJZ25vcmVDYXNlKHN5c3RlbUlkKSkpKSB7Ci0gICAgICAgICAgICAgICAgbWFwLmFkZEVsZW1lbnQoZS5nZXRFbnRyeUFyZygxKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKG1hcC5zaXplKCkgPT0gMCkgewotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gbWFwOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRmluZCB0aGUgVVJOcyBmb3IgYSBnaXZlbiBzeXN0ZW0gaWRlbnRpZmllciBpbiB0aGUgY3VycmVudCBjYXRhbG9nLgotICAgICAqCi0gICAgICogQHBhcmFtIHN5c3RlbUlkIFRoZSBzeXN0ZW0gSUQgdG8gbG9jYXRlLgotICAgICAqCi0gICAgICogQHJldHVybiBBIHZlY3RvciBvZiBVUk5zIHRoYXQgbWFwIHRvIHRoZSBzeXN0ZW1JZC4KLSAgICAgKi8KLSAgICBwcml2YXRlIFZlY3RvciByZXNvbHZlTG9jYWxTeXN0ZW1SZXZlcnNlKFN0cmluZyBzeXN0ZW1JZCkgewotICAgICAgICBWZWN0b3IgbWFwID0gbmV3IFZlY3RvcigpOwotICAgICAgICBTdHJpbmcgb3NuYW1lID0gU2VjdXJpdHlTdXBwb3J0LmdldFN5c3RlbVByb3BlcnR5KCJvcy5uYW1lIik7Ci0gICAgICAgIGJvb2xlYW4gd2luZG93cyA9IChvc25hbWUuaW5kZXhPZigiV2luZG93cyIpID49IDApOwotICAgICAgICBFbnVtZXJhdGlvbiBlbiA9IGNhdGFsb2dFbnRyaWVzLmVsZW1lbnRzKCk7Ci0gICAgICAgIHdoaWxlIChlbi5oYXNNb3JlRWxlbWVudHMoKSkgewotICAgICAgICAgICAgQ2F0YWxvZ0VudHJ5IGUgPSAoQ2F0YWxvZ0VudHJ5KSBlbi5uZXh0RWxlbWVudCgpOwotICAgICAgICAgICAgaWYgKGUuZ2V0RW50cnlUeXBlKCkgPT0gU1lTVEVNCi0gICAgICAgICAgICAgICAgJiYgKGUuZ2V0RW50cnlBcmcoMSkuZXF1YWxzKHN5c3RlbUlkKQotICAgICAgICAgICAgICAgICAgICB8fCAod2luZG93cwotICAgICAgICAgICAgICAgICAgICAgICAgJiYgZS5nZXRFbnRyeUFyZygxKS5lcXVhbHNJZ25vcmVDYXNlKHN5c3RlbUlkKSkpKSB7Ci0gICAgICAgICAgICAgICAgbWFwLmFkZEVsZW1lbnQoZS5nZXRFbnRyeUFyZygwKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKG1hcC5zaXplKCkgPT0gMCkgewotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gbWFwOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2VhcmNoIHRoZSBzdWJvcmRpbmF0ZSBjYXRhbG9ncywgaW4gb3JkZXIsIGxvb2tpbmcgZm9yIGFsbAotICAgICAqIG1hdGNoLgotICAgICAqCi0gICAgICogPHA+VGhpcyBtZXRob2Qgc2VhcmNoZXMgdGhlIENhdGFsb2cgYW5kIHJldHVybnMgYWxsIG9mIHRoZSBzeXN0ZW0KLSAgICAgKiBpZGVudGlmaWVycyBzcGVjaWZpZWQgZm9yIHRoZSBnaXZlbiBlbnRpdHkgdHlwZSB3aXRoIHRoZSBnaXZlbgotICAgICAqIG5hbWUsIHB1YmxpYywgYW5kIHN5c3RlbSBpZGVudGlmaWVycy4gSW4gc29tZSBjb250ZXh0cywgdGhlc2UKLSAgICAgKiBtYXkgYmUgbnVsbC48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gZW50aXR5VHlwZSBUaGUgQ2F0YWxvZ0VudHJ5IHR5cGUgZm9yIHdoaWNoIHRoaXMgcXVlcnkgaXMKLSAgICAgKiBiZWluZyBjb25kdWN0ZWQuIFRoaXMgaXMgbmVjZXNzYXJ5IGluIG9yZGVyIHRvIGRvIHRoZSBhcHByb3ByYXRlCi0gICAgICogcXVlcnkgb24gYSBzdWJvcmRpbmF0ZSBjYXRhbG9nLgotICAgICAqIEBwYXJhbSBlbnRpdHlOYW1lIFRoZSBuYW1lIG9mIHRoZSBlbnRpdHkgYmVpbmcgc2VhcmNoZWQgZm9yLCBpZgotICAgICAqIGFwcHJvcHJpYXRlLgotICAgICAqIEBwYXJhbSBwdWJsaWNJZCBUaGUgcHVibGljIGlkZW50aWZpZXIgb2YgdGhlIGVudGl0eSBpbiBxdWVzdGlvbgotICAgICAqIChhcyBwcm92aWRlZCBpbiB0aGUgc291cmNlIGRvY3VtZW50KS4KLSAgICAgKiBAcGFyYW0gc3lzdGVtSWQgVGhlIG5vbWluYWwgc3lzdGVtIGlkZW50aWZpZXIgZm9yIHRoZSBlbnRpdHkKLSAgICAgKiBpbiBxdWVzdGlvbiAoYXMgcHJvdmlkZWQgaW4gdGhlIHNvdXJjZSBkb2N1bWVudCkuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiBUaGUgZm9ybWFsIHN5c3RlbSBpZGVudGlmaWVyIG9mIGEKLSAgICAgKiBkZWxlZ2F0ZWQgY2F0YWxvZyBjYW5ub3QgYmUgdHVybmVkIGludG8gYSB2YWxpZCBVUkwuCi0gICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBFcnJvciByZWFkaW5nIGRlbGVnYXRlZCBjYXRhbG9nIGZpbGUuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBzeXN0ZW0gaWRlbnRpZmllciB0byB1c2UuCi0gICAgICogTm90ZSB0aGF0IHRoZSBub21pbmFsIHN5c3RlbSBpZGVudGlmaWVyIGlzIG5vdCByZXR1cm5lZCBpZiBhCi0gICAgICogbWF0Y2ggaXMgbm90IGZvdW5kIGluIHRoZSBjYXRhbG9nLCBpbnN0ZWFkIG51bGwgaXMgcmV0dXJuZWQKLSAgICAgKiB0byBpbmRpY2F0ZSB0aGF0IG5vIG1hdGNoIHdhcyBmb3VuZC4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN5bmNocm9uaXplZCBWZWN0b3IgcmVzb2x2ZUFsbFN1Ym9yZGluYXRlQ2F0YWxvZ3MoaW50IGVudGl0eVR5cGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGVudGl0eU5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHB1YmxpY0lkLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBzeXN0ZW1JZCkKLSAgICAgICAgdGhyb3dzIE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewotCi0gICAgICAgIFZlY3RvciByZXNvbHV0aW9ucyA9IG5ldyBWZWN0b3IoKTsKLQotICAgICAgICBmb3IgKGludCBjYXRQb3MgPSAwOyBjYXRQb3MgPCBjYXRhbG9ncy5zaXplKCk7IGNhdFBvcysrKSB7Ci0gICAgICAgICAgICBSZXNvbHZlciBjID0gbnVsbDsKLQotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICBjID0gKFJlc29sdmVyKSBjYXRhbG9ncy5lbGVtZW50QXQoY2F0UG9zKTsKLSAgICAgICAgICAgIH0gY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIGNhdGZpbGUgPSAoU3RyaW5nKSBjYXRhbG9ncy5lbGVtZW50QXQoY2F0UG9zKTsKLSAgICAgICAgICAgICAgICBjID0gKFJlc29sdmVyKSBuZXdDYXRhbG9nKCk7Ci0KLSAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICBjLnBhcnNlQ2F0YWxvZyhjYXRmaWxlKTsKLSAgICAgICAgICAgICAgICB9IGNhdGNoIChNYWxmb3JtZWRVUkxFeGNlcHRpb24gbXVlKSB7Ci0gICAgICAgICAgICAgICAgICAgIGNhdGFsb2dNYW5hZ2VyLmRlYnVnLm1lc3NhZ2UoMSwgIk1hbGZvcm1lZCBDYXRhbG9nIFVSTCIsIGNhdGZpbGUpOwotICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiBmbmZlKSB7Ci0gICAgICAgICAgICAgICAgICAgIGNhdGFsb2dNYW5hZ2VyLmRlYnVnLm1lc3NhZ2UoMSwgIkZhaWxlZCB0byBsb2FkIGNhdGFsb2csIGZpbGUgbm90IGZvdW5kIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgY2F0ZmlsZSk7Ci0gICAgICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gaW9lKSB7Ci0gICAgICAgICAgICAgICAgICAgIGNhdGFsb2dNYW5hZ2VyLmRlYnVnLm1lc3NhZ2UoMSwgIkZhaWxlZCB0byBsb2FkIGNhdGFsb2csIEkvTyBlcnJvciIsIGNhdGZpbGUpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIGNhdGFsb2dzLnNldEVsZW1lbnRBdChjLCBjYXRQb3MpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBTdHJpbmcgcmVzb2x2ZWQgPSBudWxsOwotCi0gICAgICAgICAgICAvLyBPaywgbm93IHdoYXQgYXJlIHdlIHN1cHBvc2VkIHRvIGNhbGwgaGVyZT8KLSAgICAgICAgICAgIGlmIChlbnRpdHlUeXBlID09IERPQ1RZUEUpIHsKLSAgICAgICAgICAgICAgICByZXNvbHZlZCA9IGMucmVzb2x2ZURvY3R5cGUoZW50aXR5TmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVibGljSWQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5c3RlbUlkKTsKLSAgICAgICAgICAgICAgICBpZiAocmVzb2x2ZWQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAvLyBPbmx5IGZpbmQgb25lIERPQ1RZUEUgcmVzb2x1dGlvbgotICAgICAgICAgICAgICAgICAgICByZXNvbHV0aW9ucy5hZGRFbGVtZW50KHJlc29sdmVkKTsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdXRpb25zOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0gZWxzZSBpZiAoZW50aXR5VHlwZSA9PSBET0NVTUVOVCkgewotICAgICAgICAgICAgICAgIHJlc29sdmVkID0gYy5yZXNvbHZlRG9jdW1lbnQoKTsKLSAgICAgICAgICAgICAgICBpZiAocmVzb2x2ZWQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAvLyBPbmx5IGZpbmQgb25lIERPQ1VNRU5UIHJlc29sdXRpb24KLSAgICAgICAgICAgICAgICAgICAgcmVzb2x1dGlvbnMuYWRkRWxlbWVudChyZXNvbHZlZCk7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHV0aW9uczsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9IGVsc2UgaWYgKGVudGl0eVR5cGUgPT0gRU5USVRZKSB7Ci0gICAgICAgICAgICAgICAgcmVzb2x2ZWQgPSBjLnJlc29sdmVFbnRpdHkoZW50aXR5TmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwdWJsaWNJZCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeXN0ZW1JZCk7Ci0gICAgICAgICAgICAgICAgaWYgKHJlc29sdmVkICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gT25seSBmaW5kIG9uZSBFTlRJVFkgcmVzb2x1dGlvbgotICAgICAgICAgICAgICAgICAgICByZXNvbHV0aW9ucy5hZGRFbGVtZW50KHJlc29sdmVkKTsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdXRpb25zOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0gZWxzZSBpZiAoZW50aXR5VHlwZSA9PSBOT1RBVElPTikgewotICAgICAgICAgICAgICAgIHJlc29sdmVkID0gYy5yZXNvbHZlTm90YXRpb24oZW50aXR5TmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHB1YmxpY0lkLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3lzdGVtSWQpOwotICAgICAgICAgICAgICAgIGlmIChyZXNvbHZlZCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIE9ubHkgZmluZCBvbmUgTk9UQVRJT04gcmVzb2x1dGlvbgotICAgICAgICAgICAgICAgICAgICByZXNvbHV0aW9ucy5hZGRFbGVtZW50KHJlc29sdmVkKTsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdXRpb25zOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0gZWxzZSBpZiAoZW50aXR5VHlwZSA9PSBQVUJMSUMpIHsKLSAgICAgICAgICAgICAgICByZXNvbHZlZCA9IGMucmVzb2x2ZVB1YmxpYyhwdWJsaWNJZCwgc3lzdGVtSWQpOwotICAgICAgICAgICAgICAgIGlmIChyZXNvbHZlZCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIE9ubHkgZmluZCBvbmUgUFVCTElDIHJlc29sdXRpb24KLSAgICAgICAgICAgICAgICAgICAgcmVzb2x1dGlvbnMuYWRkRWxlbWVudChyZXNvbHZlZCk7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHV0aW9uczsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9IGVsc2UgaWYgKGVudGl0eVR5cGUgPT0gU1lTVEVNKSB7Ci0gICAgICAgICAgICAgICAgVmVjdG9yIGxvY2FsUmVzb2x1dGlvbnMgPSBjLnJlc29sdmVBbGxTeXN0ZW0oc3lzdGVtSWQpOwotICAgICAgICAgICAgICAgIHJlc29sdXRpb25zID0gYXBwZW5kVmVjdG9yKHJlc29sdXRpb25zLCBsb2NhbFJlc29sdXRpb25zKTsKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0gZWxzZSBpZiAoZW50aXR5VHlwZSA9PSBTWVNURU1SRVZFUlNFKSB7Ci0gICAgICAgICAgICAgICAgVmVjdG9yIGxvY2FsUmVzb2x1dGlvbnMgPSBjLnJlc29sdmVBbGxTeXN0ZW1SZXZlcnNlKHN5c3RlbUlkKTsKLSAgICAgICAgICAgICAgICByZXNvbHV0aW9ucyA9IGFwcGVuZFZlY3RvcihyZXNvbHV0aW9ucywgbG9jYWxSZXNvbHV0aW9ucyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAocmVzb2x1dGlvbnMgIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIHJlc29sdXRpb25zOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9yZXNvbHZlci9oZWxwZXJzL0Jvb3RzdHJhcFJlc29sdmVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9yZXNvbHZlci9oZWxwZXJzL0Jvb3RzdHJhcFJlc29sdmVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGU0NGY1MGQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvcmVzb2x2ZXIvaGVscGVycy9Cb290c3RyYXBSZXNvbHZlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjAwICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKi8KLS8qCi0gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKLSAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAotICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgotICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKLSAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCi0gKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLy8gQm9vdHN0cmFwUmVzb2x2ZXIuamF2YSAtIFJlc29sdmUgZW50aXRpZXMgYW5kIFVSSXMgaW50ZXJuYWxseQotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzb2x2ZXIuaGVscGVyczsKLQotaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5uZXQuTWFsZm9ybWVkVVJMRXhjZXB0aW9uOwotaW1wb3J0IGphdmEubmV0LlVSTDsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKLWltcG9ydCBqYXZhLnV0aWwuTWFwOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uU291cmNlOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5VUklSZXNvbHZlcjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnNheC5TQVhTb3VyY2U7Ci1pbXBvcnQgb3JnLnhtbC5zYXguRW50aXR5UmVzb2x2ZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguSW5wdXRTb3VyY2U7Ci0KLS8qKgotICogQSBzaW1wbGUgYm9vdHN0cmFwcGluZyByZXNvbHZlci4KLSAqCi0gKiA8cD5UaGlzIGNsYXNzIGlzIHVzZWQgYXMgdGhlIGVudGl0eSByZXNvbHZlciB3aGVuIHJlYWRpbmcgWE1MIENhdGFsb2dzLgotICogSXQgc2VhcmNoZXMgZm9yIHRoZSBPQVNJUyBYTUwgQ2F0YWxvZyBEVEQsIFJlbGF4IE5HIEdyYW1tYXIgYW5kIFczQyBYTUwgU2NoZW1hCi0gKiBhcyByZXNvdXJjZXMgKGUuZy4sIGluIHRoZSByZXNvbHZlciBqYXIgZmlsZSkuPC9wPgotICoKLSAqIDxwPklmIHlvdSBoYXZlIHlvdXIgb3duIERURHMgb3Igc2NoZW1hcywgeW91IGNhbiBleHRlbmQgdGhpcyBjbGFzcyBhbmQKLSAqIHNldCB0aGUgQm9vdHN0cmFwUmVzb2x2ZXIgaW4geW91ciBDYXRhbG9nTWFuYWdlci48L3A+Ci0gKgotICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnJlc29sdmVyLkNhdGFsb2dNYW5hZ2VyCi0gKgotICogQGF1dGhvciBOb3JtYW4gV2Fsc2gKLSAqIDxhIGhyZWY9Im1haWx0bzpOb3JtYW4uV2Fsc2hAU3VuLkNPTSI+Tm9ybWFuLldhbHNoQFN1bi5DT008L2E+Ci0gKgotICovCi1wdWJsaWMgY2xhc3MgQm9vdHN0cmFwUmVzb2x2ZXIgaW1wbGVtZW50cyBFbnRpdHlSZXNvbHZlciwgVVJJUmVzb2x2ZXIgewotICAvKiogVVJJIG9mIHRoZSBXM0MgWE1MIFNjaGVtYSBmb3IgT0FTSVMgWE1MIENhdGFsb2cgZmlsZXMuICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIHhtbENhdGFsb2dYU0QgPSAiaHR0cDovL3d3dy5vYXNpcy1vcGVuLm9yZy9jb21taXR0ZWVzL2VudGl0eS9yZWxlYXNlLzEuMC9jYXRhbG9nLnhzZCI7Ci0KLSAgLyoqIFVSSSBvZiB0aGUgUkVMQVggTkcgR3JhbW1hciBmb3IgT0FTSVMgWE1MIENhdGFsb2cgZmlsZXMuICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIHhtbENhdGFsb2dSTkcgPSAiaHR0cDovL3d3dy5vYXNpcy1vcGVuLm9yZy9jb21taXR0ZWVzL2VudGl0eS9yZWxlYXNlLzEuMC9jYXRhbG9nLnJuZyI7Ci0KLSAgLyoqIFB1YmxpYyBpZGVudGlmaWVyIGZvciBPQVNJUyBYTUwgQ2F0YWxvZyBmaWxlcy4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgeG1sQ2F0YWxvZ1B1YklkID0gIi0vL09BU0lTLy9EVEQgWE1MIENhdGFsb2dzIFYxLjAvL0VOIjsKLQotICAvKiogU3lzdGVtIGlkZW50aWZpZXIgZm9yIE9BU0lTIFhNTCBDYXRhbG9nIGZpbGVzLiAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyB4bWxDYXRhbG9nU3lzSWQgPSAiaHR0cDovL3d3dy5vYXNpcy1vcGVuLm9yZy9jb21taXR0ZWVzL2VudGl0eS9yZWxlYXNlLzEuMC9jYXRhbG9nLmR0ZCI7Ci0KLSAgLyoqIFByaXZhdGUgaGFzaCB1c2VkIGZvciBwdWJsaWMgaWRlbnRpZmllcnMuICovCi0gIHByaXZhdGUgZmluYWwgTWFwPFN0cmluZywgU3RyaW5nPiBwdWJsaWNNYXAgPSBuZXcgSGFzaE1hcDw+KCk7Ci0KLSAgLyoqIFByaXZhdGUgaGFzaCB1c2VkIGZvciBzeXN0ZW0gaWRlbnRpZmllcnMuICovCi0gIHByaXZhdGUgZmluYWwgTWFwPFN0cmluZywgU3RyaW5nPiBzeXN0ZW1NYXAgPSBuZXcgSGFzaE1hcDw+KCk7Ci0KLSAgLyoqIFByaXZhdGUgaGFzaCB1c2VkIGZvciBVUklzLiAqLwotICBwcml2YXRlIGZpbmFsIE1hcDxTdHJpbmcsIFN0cmluZz4gdXJpTWFwID0gbmV3IEhhc2hNYXA8PigpOwotCi0gIC8qKiBDb25zdHJ1Y3Rvci4gKi8KLSAgcHVibGljIEJvb3RzdHJhcFJlc29sdmVyKCkgewotICAgIFVSTCB1cmwgPSB0aGlzLmdldENsYXNzKCkuZ2V0UmVzb3VyY2UoIi9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3Jlc29sdmVyL2V0Yy9jYXRhbG9nLmR0ZCIpOwotICAgIGlmICh1cmwgIT0gbnVsbCkgewotICAgICAgcHVibGljTWFwLnB1dCh4bWxDYXRhbG9nUHViSWQsIHVybC50b1N0cmluZygpKTsKLSAgICAgIHN5c3RlbU1hcC5wdXQoeG1sQ2F0YWxvZ1N5c0lkLCB1cmwudG9TdHJpbmcoKSk7Ci0gICAgfQotCi0gICAgdXJsID0gdGhpcy5nZXRDbGFzcygpLmdldFJlc291cmNlKCIvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9yZXNvbHZlci9ldGMvY2F0YWxvZy5ybmciKTsKLSAgICBpZiAodXJsICE9IG51bGwpIHsKLSAgICAgIHVyaU1hcC5wdXQoeG1sQ2F0YWxvZ1JORywgdXJsLnRvU3RyaW5nKCkpOwotICAgIH0KLQotICAgIHVybCA9IHRoaXMuZ2V0Q2xhc3MoKS5nZXRSZXNvdXJjZSgiL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvcmVzb2x2ZXIvZXRjL2NhdGFsb2cueHNkIik7Ci0gICAgaWYgKHVybCAhPSBudWxsKSB7Ci0gICAgICB1cmlNYXAucHV0KHhtbENhdGFsb2dYU0QsIHVybC50b1N0cmluZygpKTsKLSAgICB9Ci0gIH0KLQotICAvKiogU0FYIHJlc29sdmVFbnRpdHkgQVBJLiAqLwotICBwdWJsaWMgSW5wdXRTb3VyY2UgcmVzb2x2ZUVudGl0eSAoU3RyaW5nIHB1YmxpY0lkLCBTdHJpbmcgc3lzdGVtSWQpIHsKLSAgICBTdHJpbmcgcmVzb2x2ZWQgPSBudWxsOwotCi0gICAgaWYgKHN5c3RlbUlkICE9IG51bGwgJiYgc3lzdGVtTWFwLmNvbnRhaW5zS2V5KHN5c3RlbUlkKSkgewotICAgICAgcmVzb2x2ZWQgPSBzeXN0ZW1NYXAuZ2V0KHN5c3RlbUlkKTsKLSAgICB9IGVsc2UgaWYgKHB1YmxpY0lkICE9IG51bGwgJiYgcHVibGljTWFwLmNvbnRhaW5zS2V5KHB1YmxpY0lkKSkgewotICAgICAgcmVzb2x2ZWQgPSBwdWJsaWNNYXAuZ2V0KHB1YmxpY0lkKTsKLSAgICB9Ci0KLSAgICBpZiAocmVzb2x2ZWQgIT0gbnVsbCkgewotICAgICAgdHJ5IHsKLSAgICAgICAgSW5wdXRTb3VyY2UgaVNvdXJjZSA9IG5ldyBJbnB1dFNvdXJjZShyZXNvbHZlZCk7Ci0gICAgICAgIGlTb3VyY2Uuc2V0UHVibGljSWQocHVibGljSWQpOwotCi0gICAgICAgIC8vIElkZWFsbHkgdGhpcyBtZXRob2Qgd291bGQgbm90IGF0dGVtcHQgdG8gb3BlbiB0aGUKLSAgICAgICAgLy8gSW5wdXRTdHJlYW0sIGJ1dCB0aGVyZSBpcyBhIGJ1ZyAoaW4gWGVyY2VzLCBhdCBsZWFzdCkKLSAgICAgICAgLy8gdGhhdCBjYXVzZXMgdGhlIHBhcnNlciB0byBtaXN0YWtlbmx5IG9wZW4gdGhlIHdyb25nCi0gICAgICAgIC8vIHN5c3RlbSBpZGVudGlmaWVyIGlmIHRoZSByZXR1cm5lZCBJbnB1dFNvdXJjZSBkb2VzCi0gICAgICAgIC8vIG5vdCBoYXZlIGEgYnl0ZVN0cmVhbS4KLSAgICAgICAgLy8KLSAgICAgICAgLy8gSXQgY291bGQgYmUgYXJndWVkIHRoYXQgd2Ugc3RpbGwgc2hvdWxkbid0IGRvIHRoaXMgaGVyZSwKLSAgICAgICAgLy8gYnV0IHNpbmNlIHRoZSBwdXJwb3NlIG9mIGNhbGxpbmcgdGhlIGVudGl0eVJlc29sdmVyIGlzCi0gICAgICAgIC8vIGFsbW9zdCBjZXJ0YWlubHkgdG8gb3BlbiB0aGUgaW5wdXQgc3RyZWFtLCBpdCBzZWVtcyB0bwotICAgICAgICAvLyBkbyBsaXR0bGUgaGFybS4KLSAgICAgICAgLy8KLSAgICAgICAgVVJMIHVybCA9IG5ldyBVUkwocmVzb2x2ZWQpOwotICAgICAgICBJbnB1dFN0cmVhbSBpU3RyZWFtID0gdXJsLm9wZW5TdHJlYW0oKTsKLSAgICAgICAgaVNvdXJjZS5zZXRCeXRlU3RyZWFtKGlTdHJlYW0pOwotCi0gICAgICAgIHJldHVybiBpU291cmNlOwotICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgLy8gRklYTUU6IHNpbGVudGx5IGZhaWw/Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqIFRyYW5zZm9ybWVyIHJlc29sdmUgQVBJLiAqLwotICBwdWJsaWMgU291cmNlIHJlc29sdmUoU3RyaW5nIGhyZWYsIFN0cmluZyBiYXNlKQotICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiB7Ci0KLSAgICBTdHJpbmcgdXJpID0gaHJlZjsKLSAgICBTdHJpbmcgZnJhZ21lbnQgPSBudWxsOwotICAgIGludCBoYXNoUG9zID0gaHJlZi5pbmRleE9mKCIjIik7Ci0gICAgaWYgKGhhc2hQb3MgPj0gMCkgewotICAgICAgdXJpID0gaHJlZi5zdWJzdHJpbmcoMCwgaGFzaFBvcyk7Ci0gICAgICBmcmFnbWVudCA9IGhyZWYuc3Vic3RyaW5nKGhhc2hQb3MrMSk7Ci0gICAgfQotCi0gICAgU3RyaW5nIHJlc3VsdCA9IG51bGw7Ci0gICAgaWYgKGhyZWYgIT0gbnVsbCAmJiB1cmlNYXAuY29udGFpbnNLZXkoaHJlZikpIHsKLSAgICAgIHJlc3VsdCA9IHVyaU1hcC5nZXQoaHJlZik7Ci0gICAgfQotCi0gICAgaWYgKHJlc3VsdCA9PSBudWxsKSB7Ci0gICAgICB0cnkgewotICAgICAgICBVUkwgdXJsID0gbnVsbDsKLQotICAgICAgICBpZiAoYmFzZT09bnVsbCkgewotICAgICAgICAgIHVybCA9IG5ldyBVUkwodXJpKTsKLSAgICAgICAgICByZXN1bHQgPSB1cmwudG9TdHJpbmcoKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICBVUkwgYmFzZVVSTCA9IG5ldyBVUkwoYmFzZSk7Ci0gICAgICAgICAgdXJsID0gKGhyZWYubGVuZ3RoKCk9PTAgPyBiYXNlVVJMIDogbmV3IFVSTChiYXNlVVJMLCB1cmkpKTsKLSAgICAgICAgICByZXN1bHQgPSB1cmwudG9TdHJpbmcoKTsKLSAgICAgICAgfQotICAgICAgfSBjYXRjaCAoamF2YS5uZXQuTWFsZm9ybWVkVVJMRXhjZXB0aW9uIG11ZSkgewotICAgICAgICAvLyB0cnkgdG8gbWFrZSBhbiBhYnNvbHV0ZSBVUkkgZnJvbSB0aGUgY3VycmVudCBiYXNlCi0gICAgICAgIFN0cmluZyBhYnNCYXNlID0gbWFrZUFic29sdXRlKGJhc2UpOwotICAgICAgICBpZiAoIWFic0Jhc2UuZXF1YWxzKGJhc2UpKSB7Ci0gICAgICAgICAgLy8gZG9uJ3QgYm90aGVyIGlmIHRoZSBhYnNCYXNlIGlzbid0IGRpZmZlcmVudCEKLSAgICAgICAgICByZXR1cm4gcmVzb2x2ZShocmVmLCBhYnNCYXNlKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oIk1hbGZvcm1lZCBVUkwgIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGhyZWYgKyAiKGJhc2UgIiArIGJhc2UgKyAiKSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG11ZSk7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICB9Ci0KLSAgICBTQVhTb3VyY2Ugc291cmNlID0gbmV3IFNBWFNvdXJjZSgpOwotICAgIHNvdXJjZS5zZXRJbnB1dFNvdXJjZShuZXcgSW5wdXRTb3VyY2UocmVzdWx0KSk7Ci0gICAgcmV0dXJuIHNvdXJjZTsKLSAgfQotCi0gIC8qKiBBdHRlbXB0IHRvIGNvbnN0cnVjdCBhbiBhYnNvbHV0ZSBVUkkgKi8KLSAgcHJpdmF0ZSBTdHJpbmcgbWFrZUFic29sdXRlKFN0cmluZyB1cmkpIHsKLSAgICBpZiAodXJpID09IG51bGwpIHsKLSAgICAgIHVyaSA9ICIiOwotICAgIH0KLQotICAgIHRyeSB7Ci0gICAgICBVUkwgdXJsID0gbmV3IFVSTCh1cmkpOwotICAgICAgcmV0dXJuIHVybC50b1N0cmluZygpOwotICAgIH0gY2F0Y2ggKE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiBtdWUpIHsKLSAgICAgIHRyeSB7Ci0gICAgICAgIFVSTCBmaWxlVVJMID0gRmlsZVVSTC5tYWtlVVJMKHVyaSk7Ci0gICAgICAgIHJldHVybiBmaWxlVVJMLnRvU3RyaW5nKCk7Ci0gICAgICB9IGNhdGNoIChNYWxmb3JtZWRVUkxFeGNlcHRpb24gbXVlMikgewotICAgICAgICAvLyBiYWlsCi0gICAgICAgIHJldHVybiB1cmk7Ci0gICAgICB9Ci0gICAgfQotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9yZXNvbHZlci9oZWxwZXJzL0RlYnVnLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9yZXNvbHZlci9oZWxwZXJzL0RlYnVnLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGZiZjJiOGYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvcmVzb2x2ZXIvaGVscGVycy9EZWJ1Zy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTExICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vLyBEZWJ1Zy5qYXZhIC0gUHJpbnQgZGVidWcgbWVzc2FnZXMKLQotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIG9yIGl0cyBsaWNlbnNvcnMsCi0gKiBhcyBhcHBsaWNhYmxlLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzb2x2ZXIuaGVscGVyczsKLQotLyoqCi0gKiBTdGF0aWMgZGVidWdnaW5nL21lc3NhZ2luZyBjbGFzcyBmb3IgQ2F0YWxvZ3MuCi0gKgotICogPHA+VGhpcyBjbGFzcyBkZWZpbmVzIGEgc2V0IG9mIHN0YXRpYyBtZXRob2RzIHRoYXQgY2FuIGJlIGNhbGxlZAotICogdG8gcHJvZHVjZSBkZWJ1Z2dpbmcgbWVzc2FnZXMuIE1lc3NhZ2VzIGhhdmUgYW4gYXNzb2NpYXRlZCAiZGVidWcKLSAqIGxldmVsIiBhbmQgbWVzc2FnZXMgYmVsb3cgdGhlIGN1cnJlbnQgc2V0dGluZyBhcmUgbm90IGRpc3BsYXllZC48L3A+Ci0gKgotICogQGF1dGhvciBOb3JtYW4gV2Fsc2gKLSAqIDxhIGhyZWY9Im1haWx0bzpOb3JtYW4uV2Fsc2hAU3VuLkNPTSI+Tm9ybWFuLldhbHNoQFN1bi5DT008L2E+Ci0gKgotICovCi1wdWJsaWMgY2xhc3MgRGVidWcgewotICAvKiogVGhlIGludGVybmFsIGRlYnVnIGxldmVsLiAqLwotICBwcm90ZWN0ZWQgaW50IGRlYnVnID0gMDsKLQotICAvKiogQ29uc3RydWN0b3IgKi8KLSAgcHVibGljIERlYnVnKCkgewotICAgIC8vIG5vcAotICB9Ci0KLSAgLyoqIFNldCB0aGUgZGVidWcgbGV2ZWwgZm9yIGZ1dHVyZSBtZXNzYWdlcy4gKi8KLSAgcHVibGljIHZvaWQgc2V0RGVidWcoaW50IG5ld0RlYnVnKSB7Ci0gICAgZGVidWcgPSBuZXdEZWJ1ZzsKLSAgfQotCi0gIC8qKiBHZXQgdGhlIGN1cnJlbnQgZGVidWcgbGV2ZWwuICovCi0gIHB1YmxpYyBpbnQgZ2V0RGVidWcoKSB7Ci0gICAgcmV0dXJuIGRlYnVnOwotICB9Ci0KLSAgLyoqCi0gICAqIFByaW50IGRlYnVnIG1lc3NhZ2UgKGlmIHRoZSBkZWJ1ZyBsZXZlbCBpcyBoaWdoIGVub3VnaCkuCi0gICAqCi0gICAqIDxwPlByaW50cyAidGhlIG1lc3NhZ2UiPC9wPgotICAgKgotICAgKiBAcGFyYW0gbGV2ZWwgVGhlIGRlYnVnIGxldmVsIG9mIHRoaXMgbWVzc2FnZS4gVGhpcyBtZXNzYWdlCi0gICAqIHdpbGwgb25seSBiZQotICAgKiBkaXNwbGF5ZWQgaWYgdGhlIGN1cnJlbnQgZGVidWcgbGV2ZWwgaXMgYXQgbGVhc3QgZXF1YWwgdG8gdGhpcwotICAgKiB2YWx1ZS4KLSAgICogQHBhcmFtIG1lc3NhZ2UgVGhlIHRleHQgb2YgdGhlIG1lc3NhZ2UuCi0gICAqLwotICBwdWJsaWMgdm9pZCBtZXNzYWdlKGludCBsZXZlbCwgU3RyaW5nIG1lc3NhZ2UpIHsKLSAgICBpZiAoZGVidWcgPj0gbGV2ZWwpIHsKLSAgICAgIFN5c3RlbS5vdXQucHJpbnRsbihtZXNzYWdlKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogUHJpbnQgZGVidWcgbWVzc2FnZSAoaWYgdGhlIGRlYnVnIGxldmVsIGlzIGhpZ2ggZW5vdWdoKS4KLSAgICoKLSAgICogPHA+UHJpbnRzICJ0aGUgbWVzc2FnZTogc3BlYyI8L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBsZXZlbCBUaGUgZGVidWcgbGV2ZWwgb2YgdGhpcyBtZXNzYWdlLiBUaGlzIG1lc3NhZ2UKLSAgICogd2lsbCBvbmx5IGJlCi0gICAqIGRpc3BsYXllZCBpZiB0aGUgY3VycmVudCBkZWJ1ZyBsZXZlbCBpcyBhdCBsZWFzdCBlcXVhbCB0byB0aGlzCi0gICAqIHZhbHVlLgotICAgKiBAcGFyYW0gbWVzc2FnZSBUaGUgdGV4dCBvZiB0aGUgbWVzc2FnZS4KLSAgICogQHBhcmFtIHNwZWMgQW4gYXJndW1lbnQgdG8gdGhlIG1lc3NhZ2UuCi0gICAqLwotICBwdWJsaWMgdm9pZCBtZXNzYWdlKGludCBsZXZlbCwgU3RyaW5nIG1lc3NhZ2UsIFN0cmluZyBzcGVjKSB7Ci0gICAgaWYgKGRlYnVnID49IGxldmVsKSB7Ci0gICAgICBTeXN0ZW0ub3V0LnByaW50bG4obWVzc2FnZSArICI6ICIgKyBzcGVjKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogUHJpbnQgZGVidWcgbWVzc2FnZSAoaWYgdGhlIGRlYnVnIGxldmVsIGlzIGhpZ2ggZW5vdWdoKS4KLSAgICoKLSAgICogPHA+UHJpbnRzICJ0aGUgbWVzc2FnZTogc3BlYzEiIGFuZCAic3BlYzIiIGluZGVudGVkIG9uIHRoZSBuZXh0IGxpbmUuPC9wPgotICAgKgotICAgKiBAcGFyYW0gbGV2ZWwgVGhlIGRlYnVnIGxldmVsIG9mIHRoaXMgbWVzc2FnZS4gVGhpcyBtZXNzYWdlCi0gICAqIHdpbGwgb25seSBiZQotICAgKiBkaXNwbGF5ZWQgaWYgdGhlIGN1cnJlbnQgZGVidWcgbGV2ZWwgaXMgYXQgbGVhc3QgZXF1YWwgdG8gdGhpcwotICAgKiB2YWx1ZS4KLSAgICogQHBhcmFtIG1lc3NhZ2UgVGhlIHRleHQgb2YgdGhlIG1lc3NhZ2UuCi0gICAqIEBwYXJhbSBzcGVjMSBBbiBhcmd1bWVudCB0byB0aGUgbWVzc2FnZS4KLSAgICogQHBhcmFtIHNwZWMyIEFub3RoZXIgYXJndW1lbnQgdG8gdGhlIG1lc3NhZ2UuCi0gICAqLwotICBwdWJsaWMgdm9pZCBtZXNzYWdlKGludCBsZXZlbCwgU3RyaW5nIG1lc3NhZ2UsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBzcGVjMSwgU3RyaW5nIHNwZWMyKSB7Ci0gICAgaWYgKGRlYnVnID49IGxldmVsKSB7Ci0gICAgICBTeXN0ZW0ub3V0LnByaW50bG4obWVzc2FnZSArICI6ICIgKyBzcGVjMSk7Ci0gICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlx0IiArIHNwZWMyKTsKLSAgICB9Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3Jlc29sdmVyL2hlbHBlcnMvRmlsZVVSTC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvcmVzb2x2ZXIvaGVscGVycy9GaWxlVVJMLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGU1YTU2MDUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvcmVzb2x2ZXIvaGVscGVycy9GaWxlVVJMLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5MyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLy8gRmlsZVVSTC5qYXZhIC0gQ29uc3RydWN0IGEgZmlsZTogc2NoZW1lIFVSTAotCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gb3IgaXRzIGxpY2Vuc29ycywKLSAqIGFzIGFwcGxpY2FibGUuCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXNvbHZlci5oZWxwZXJzOwotCi1pbXBvcnQgamF2YS5uZXQuVVJMOwotaW1wb3J0IGphdmEubmV0Lk1hbGZvcm1lZFVSTEV4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLkZpbGU7Ci0KLS8qKgotICogU3RhdGljIG1ldGhvZCBmb3IgZGVhbGluZyB3aXRoIGZpbGU6IFVSTHMuCi0gKgotICogPHA+VGhpcyBjbGFzcyBkZWZpbmVzIGEgc3RhdGljIG1ldGhvZCB0aGF0IGNhbiBiZSB1c2VkIHRvIGNvbnN0cnVjdAotICogYW4gYXBwcm9wcmlhdGUgZmlsZTogVVJMIGZyb20gcGFydHMuIEl0J3MgZGVmaW5lZCBoZXJlIHNvIHRoYXQgaXQKLSAqIGNhbiBiZSByZXVzZWQgdGhyb3VnaHQgdGhlIHJlc29sdmVyLjwvcD4KLSAqCi0gKiA8cD4oWWVzLCBJJ2QgcmF0aGVyIGhhdmUgY2FsbGVkIHRoaXMgY2xhc3MgRmlsZVVSPGI+STwvYj4sIGJ1dAotICogZ2l2ZW4gdGhhdCBhIGphdmUubmV0LlVSTCBpcyByZXR1cm5lZCwgaXQgc2VlbWVkLi4uZXZlbiBtb3JlCi0gKiBjb25mdXNpbmcuKTwvcD4KLSAqCi0gKiBAYXV0aG9yIE5vcm1hbiBXYWxzaAotICogPGEgaHJlZj0ibWFpbHRvOk5vcm1hbi5XYWxzaEBTdW4uQ09NIj5Ob3JtYW4uV2Fsc2hAU3VuLkNPTTwvYT4KLSAqCi0gKiBAdmVyc2lvbiAxLjAKLSAqLwotcHVibGljIGFic3RyYWN0IGNsYXNzIEZpbGVVUkwgewotICBwcm90ZWN0ZWQgRmlsZVVSTCgpIHsgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBmaWxlOiBVUkwgZm9yIGEgcGF0aCBuYW1lLgotICAgKgotICAgKiA8cD5VUkxzIGluIHRoZSBmaWxlOiBzY2hlbWUgY2FuIGJlIGNvbnN0cnVjdGVkIGZvciBwYXRocyBvbgotICAgKiB0aGUgbG9jYWwgZmlsZSBzeXN0ZW0uIFNldmVyYWwgcG9zc2liaWxpdGllcyBuZWVkIHRvIGJlIGNvbnNpZGVyZWQ6Ci0gICAqIDwvcD4KLSAgICoKLSAgICogPHVsPgotICAgKiA8bGk+SWYgdGhlIHBhdGggZG9lcyBub3QgYmVnaW4gd2l0aCBhIHNsYXNoLCB0aGVuIGl0IGlzIGFzc3VtZWQKLSAgICogdG8gcmVzaWRlIGluIHRoZSB1c2VycyBjdXJyZW50IHdvcmtpbmcgZGlyZWN0b3J5Ci0gICAqIChTeXN0ZW0uZ2V0UHJvcGVydHkoInVzZXIuZGlyIikpLjwvbGk+Ci0gICAqIDxsaT5PbiBXaW5kb3dzIG1hY2hpbmVzLCB0aGUgY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeSB1c2VzCi0gICAqIGJhY2tzbGFzaGVzIChcXCwgaW5zdGVhZCBvZiAvKS48L2xpPgotICAgKiA8bGk+SWYgdGhlIGN1cnJlbnQgd29ya2luZyBkaXJlY3RvcnkgaXMgIi8iLCBkb24ndCBhZGQgYW4gZXh0cmEKLSAgICogc2xhc2ggYmVmb3JlIHRoZSBiYXNlIG5hbWUuPC9saT4KLSAgICogPC91bD4KLSAgICoKLSAgICogPHA+VGhpcyBtZXRob2QgaXMgZGVjbGFyZWQgc3RhdGljIHNvIHRoYXQgb3RoZXIgY2xhc3NlcwotICAgKiBjYW4gdXNlIGl0IGRpcmVjdGx5LjwvcD4KLSAgICoKLSAgICogQHBhcmFtIHBhdGhuYW1lIFRoZSBwYXRoIG5hbWUgY29tcG9uZW50IGZvciB3aGljaCB0byBjb25zdHJ1Y3QgYSBVUkwuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGFwcHJvcHJpYXRlIGZpbGU6IFVSTC4KLSAgICoKLSAgICogQHRocm93cyBNYWxmb3JtZWRVUkxFeGNlcHRpb24gaWYgdGhlIHBhdGhuYW1lIGNhbid0IGJlIHR1cm5lZCBpbnRvCi0gICAqICAgICAgICAgYSBwcm9wZXIgVVJMLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBVUkwgbWFrZVVSTChTdHJpbmcgcGF0aG5hbWUpIHRocm93cyBNYWxmb3JtZWRVUkxFeGNlcHRpb24gewotICAgIC8qaWYgKHBhdGhuYW1lLnN0YXJ0c1dpdGgoIi8iKSkgewotICAgICAgcmV0dXJuIG5ldyBVUkwoImZpbGU6Ly8iICsgcGF0aG5hbWUpOwotICAgIH0KLQotICAgIFN0cmluZyB1c2VyZGlyID0gU3lzdGVtLmdldFByb3BlcnR5KCJ1c2VyLmRpciIpOwotICAgIHVzZXJkaXIucmVwbGFjZSgnXFwnLCAnLycpOwotCi0gICAgaWYgKHVzZXJkaXIuZW5kc1dpdGgoIi8iKSkgewotICAgICAgcmV0dXJuIG5ldyBVUkwoImZpbGU6Ly8vIiArIHVzZXJkaXIgKyBwYXRobmFtZSk7Ci0gICAgfSBlbHNlIHsKLSAgICAgIHJldHVybiBuZXcgVVJMKCJmaWxlOi8vLyIgKyB1c2VyZGlyICsgIi8iICsgcGF0aG5hbWUpOwotICAgIH0KLSAgICAgKi8KLSAgICAgIEZpbGUgZmlsZSA9IG5ldyBGaWxlKHBhdGhuYW1lKTsKLSAgICAgIHJldHVybiBmaWxlLnRvVVJJKCkudG9VUkwoKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvcmVzb2x2ZXIvaGVscGVycy9OYW1lc3BhY2VzLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9yZXNvbHZlci9oZWxwZXJzL05hbWVzcGFjZXMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDI2MjRhNi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9yZXNvbHZlci9oZWxwZXJzL05hbWVzcGFjZXMuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExNCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLy8gTmFtZXNwYWNlcy5qYXZhIC0gQW5hbHl6ZSBuYW1lc3BhY2Ugbm9kZXMgaW4gYSBET00gdHJlZQotCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gb3IgaXRzIGxpY2Vuc29ycywKLSAqIGFzIGFwcGxpY2FibGUuCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXNvbHZlci5oZWxwZXJzOwotCi1pbXBvcnQgb3JnLnczYy5kb20uKjsKLQotLyoqCi0gKiBTdGF0aWMgTmFtZXNwYWNlIHF1ZXJ5IG1ldGhvZHMuCi0gKgotICogPHA+VGhpcyBjbGFzcyBkZWZpbmVzIGEgc2V0IG9mIHN0YXRpYyBtZXRob2RzIHRoYXQgY2FuIGJlIGNhbGxlZAotICogdG8gYW5hbHl6ZSB0aGUgbmFtZXNwYWNlIHByb3BlcnRpZXMgb2YgRE9NIG5vZGVzLjwvcD4KLSAqCi0gKiBAYXV0aG9yIE5vcm1hbiBXYWxzaAotICogPGEgaHJlZj0ibWFpbHRvOk5vcm1hbi5XYWxzaEBTdW4uQ09NIj5Ob3JtYW4uV2Fsc2hAU3VuLkNPTTwvYT4KLSAqCi0gKi8KLXB1YmxpYyBjbGFzcyBOYW1lc3BhY2VzIHsKLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSAicHJlZml4IiBwYXJ0IG9mIGEgUU5hbWUgb3IgdGhlIGVtcHR5IHN0cmluZyAobm90Ci0gICAgICogbnVsbCkgaWYgdGhlIG5hbWUgaGFzIG5vIHByZWZpeC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlbGVtZW50IFRoZSBRTmFtZSBvZiBhbiBlbGVtZW50LgotICAgICAqIEByZXR1cm4gVGhlIHByZWZpeCBwYXJ0IG9mIHRoZSBlbGVtZW50IG5hbWUuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0UHJlZml4KEVsZW1lbnQgZWxlbWVudCkgewotICAgICAgICBTdHJpbmcgbmFtZSA9IGVsZW1lbnQuZ2V0VGFnTmFtZSgpOwotICAgICAgICBTdHJpbmcgcHJlZml4ID0gIiI7Ci0KLSAgICAgICAgaWYgKG5hbWUuaW5kZXhPZignOicpID4gMCkgewotICAgICAgICAgICAgcHJlZml4ID0gbmFtZS5zdWJzdHJpbmcoMCwgbmFtZS5pbmRleE9mKCc6JykpOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIHByZWZpeDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSAibG9jYWxuYW1lIiBwYXJ0IG9mIGEgUU5hbWUsIHdoaWNoIGlzIHRoZSB3aG9sZQotICAgICAqIG5hbWUgaWYgaXQgaGFzIG5vIHByZWZpeC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlbGVtZW50IFRoZSBRTmFtZSBvZiBhbiBlbGVtZW50LgotICAgICAqIEByZXR1cm4gVGhlIGxvY2FsIHBhcnQgb2YgYSBRTmFtZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBnZXRMb2NhbE5hbWUoRWxlbWVudCBlbGVtZW50KSB7Ci0gICAgICAgIFN0cmluZyBuYW1lID0gZWxlbWVudC5nZXRUYWdOYW1lKCk7Ci0KLSAgICAgICAgaWYgKG5hbWUuaW5kZXhPZignOicpID4gMCkgewotICAgICAgICAgICAgbmFtZSA9IG5hbWUuc3Vic3RyaW5nKG5hbWUuaW5kZXhPZignOicpKzEpOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIG5hbWU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgbmFtZXNwYWNlIFVSSSBmb3IgdGhlIHNwZWNpZmllZCBwcmVmaXggYXQgdGhlCi0gICAgICogc3BlY2lmaWVkIGNvbnRleHQgbm9kZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBub2RlIFRoZSBjb250ZXh0IG5vZGUuCi0gICAgICogQHBhcmFtIHByZWZpeCBUaGUgcHJlZml4LgotICAgICAqIEByZXR1cm4gVGhlIG5hbWVzcGFjZSBVUkkgYXNzb2NpYXRlZCB3aXRoIHRoZSBwcmVmaXgsIG9yCi0gICAgICogbnVsbCBpZiBubyBuYW1lc3BhY2UgZGVjbGFyYXRpb24gZXhpc3RzIGZvciB0aGUgcHJlZml4LgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldE5hbWVzcGFjZVVSSShOb2RlIG5vZGUsIFN0cmluZyBwcmVmaXgpIHsKLSAgICAgICAgaWYgKG5vZGUgPT0gbnVsbCB8fCBub2RlLmdldE5vZGVUeXBlKCkgIT0gTm9kZS5FTEVNRU5UX05PREUpIHsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKHByZWZpeC5lcXVhbHMoIiIpKSB7Ci0gICAgICAgICAgICBpZiAoKChFbGVtZW50KSBub2RlKS5oYXNBdHRyaWJ1dGUoInhtbG5zIikpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gKChFbGVtZW50KSBub2RlKS5nZXRBdHRyaWJ1dGUoInhtbG5zIik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBTdHJpbmcgbnNhdHRyID0gInhtbG5zOiIgKyBwcmVmaXg7Ci0gICAgICAgICAgICBpZiAoKChFbGVtZW50KSBub2RlKS5oYXNBdHRyaWJ1dGUobnNhdHRyKSkgewotICAgICAgICAgICAgICAgIHJldHVybiAoKEVsZW1lbnQpIG5vZGUpLmdldEF0dHJpYnV0ZShuc2F0dHIpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIGdldE5hbWVzcGFjZVVSSShub2RlLmdldFBhcmVudE5vZGUoKSwgcHJlZml4KTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBuYW1lc3BhY2UgVVJJIGZvciB0aGUgbmFtZXNwYWNlIHRvIHdoaWNoIHRoZQotICAgICAqIGVsZW1lbnQgYmVsb25ncy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlbGVtZW50IFRoZSBlbGVtZW50LgotICAgICAqIEByZXR1cm4gVGhlIG5hbWVzcGFjZSBVUkkgYXNzb2NpYXRlZCB3aXRoIHRoZSBuYW1lc3BhY2Ugb2YgdGhlCi0gICAgICogZWxlbWVudCwgb3IgbnVsbCBpZiBubyBuYW1lc3BhY2UgZGVjbGFyYXRpb24gZXhpc3RzIGZvciBpdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBnZXROYW1lc3BhY2VVUkkoRWxlbWVudCBlbGVtZW50KSB7Ci0gICAgICAgIFN0cmluZyBwcmVmaXggPSBnZXRQcmVmaXgoZWxlbWVudCk7Ci0gICAgICAgIHJldHVybiBnZXROYW1lc3BhY2VVUkkoZWxlbWVudCwgcHJlZml4KTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9yZXNvbHZlci9oZWxwZXJzL1B1YmxpY0lkLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9yZXNvbHZlci9oZWxwZXJzL1B1YmxpY0lkLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDgyMTFhNzcuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvcmVzb2x2ZXIvaGVscGVycy9QdWJsaWNJZC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTYxICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vLyBQdWJsaWNJZC5qYXZhIC0gSW5mb3JtYXRpb24gYWJvdXQgcHVibGljIGlkZW50aWZpZXJzCi0KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBvciBpdHMgbGljZW5zb3JzLAotICogYXMgYXBwbGljYWJsZS4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnJlc29sdmVyLmhlbHBlcnM7Ci0KLS8qKgotICogU3RhdGljIG1ldGhvZHMgZm9yIGRlYWxpbmcgd2l0aCBwdWJsaWMgaWRlbnRpZmllcnMuCi0gKgotICogPHA+VGhpcyBjbGFzcyBkZWZpbmVzIGEgc2V0IG9mIHN0YXRpYyBtZXRob2RzIHRoYXQgY2FuIGJlIGNhbGxlZAotICogdG8gaGFuZGxlIHB1YmxpYyBpZGVudGlmaWVycy48L3A+Ci0gKgotICogQGF1dGhvciBOb3JtYW4gV2Fsc2gKLSAqIDxhIGhyZWY9Im1haWx0bzpOb3JtYW4uV2Fsc2hAU3VuLkNPTSI+Tm9ybWFuLldhbHNoQFN1bi5DT008L2E+Ci0gKgotICovCi1wdWJsaWMgYWJzdHJhY3QgY2xhc3MgUHVibGljSWQgewotICBwcm90ZWN0ZWQgUHVibGljSWQoKSB7IH0KLQotICAvKioKLSAgICogTm9ybWFsaXplIGEgcHVibGljIGlkZW50aWZpZXIuCi0gICAqCi0gICAqIDxwPlB1YmxpYyBpZGVudGlmaWVycyBtdXN0IGJlIG5vcm1hbGl6ZWQgYWNjb3JkaW5nIHRvIHRoZSBmb2xsb3dpbmcKLSAgICogcnVsZXMgYmVmb3JlIGNvbXBhcmlzb25zIGJldHdlZW4gdGhlbSBjYW4gYmUgbWFkZTo8L3A+Ci0gICAqCi0gICAqIDx1bD4KLSAgICogPGxpPldoaXRlc3BhY2UgY2hhcmFjdGVycyBhcmUgbm9ybWFsaXplZCB0byBzcGFjZXMgKGUuZy4sIGxpbmUgZmVlZHMsCi0gICAqIHRhYnMsIGV0Yy4gYmVjb21lIHNwYWNlcykuPC9saT4KLSAgICogPGxpPkxlYWRpbmcgYW5kIHRyYWlsaW5nIHdoaXRlc3BhY2UgaXMgcmVtb3ZlZC48L2xpPgotICAgKiA8bGk+TXVsdGlwbGUgaW50ZXJuYWwgd2hpdGVzcGFjZXMgYXJlIG5vcm1hbGl6ZWQgdG8gYSBzaW5nbGUKLSAgICogc3BhY2UuPC9saT4KLSAgICogPC91bD4KLSAgICoKLSAgICogPHA+VGhpcyBtZXRob2QgaXMgZGVjbGFyZWQgc3RhdGljIHNvIHRoYXQgb3RoZXIgY2xhc3NlcwotICAgKiBjYW4gdXNlIGl0IGRpcmVjdGx5LjwvcD4KLSAgICoKLSAgICogQHBhcmFtIHB1YmxpY0lkIFRoZSB1bm5vcm1hbGl6ZWQgcHVibGljIGlkZW50aWZpZXIuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIG5vcm1hbGl6ZWQgaWRlbnRpZmllci4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgU3RyaW5nIG5vcm1hbGl6ZShTdHJpbmcgcHVibGljSWQpIHsKLSAgICBTdHJpbmcgbm9ybWFsID0gcHVibGljSWQucmVwbGFjZSgnXHQnLCAnICcpOwotICAgIG5vcm1hbCA9IG5vcm1hbC5yZXBsYWNlKCdccicsICcgJyk7Ci0gICAgbm9ybWFsID0gbm9ybWFsLnJlcGxhY2UoJ1xuJywgJyAnKTsKLSAgICBub3JtYWwgPSBub3JtYWwudHJpbSgpOwotCi0gICAgaW50IHBvczsKLQotICAgIHdoaWxlICgocG9zID0gbm9ybWFsLmluZGV4T2YoIiAgIikpID49IDApIHsKLSAgICAgIG5vcm1hbCA9IG5vcm1hbC5zdWJzdHJpbmcoMCwgcG9zKSArIG5vcm1hbC5zdWJzdHJpbmcocG9zKzEpOwotICAgIH0KLQotICAgIHJldHVybiBub3JtYWw7Ci0gIH0KLQotICAvKioKLSAgICogRW5jb2RlIGEgcHVibGljIGlkZW50aWZpZXIgYXMgYSAicHVibGljaWQiIFVSTi4KLSAgICoKLSAgICogPHA+VGhpcyBtZXRob2QgaXMgZGVjbGFyZWQgc3RhdGljIHNvIHRoYXQgb3RoZXIgY2xhc3NlcwotICAgKiBjYW4gdXNlIGl0IGRpcmVjdGx5LjwvcD4KLSAgICoKLSAgICogQHBhcmFtIHB1YmxpY0lkIFRoZSB1bm5vcm1hbGl6ZWQgcHVibGljIGlkZW50aWZpZXIuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIG5vcm1hbGl6ZWQgaWRlbnRpZmllci4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGVuY29kZVVSTihTdHJpbmcgcHVibGljSWQpIHsKLSAgICBTdHJpbmcgdXJuID0gUHVibGljSWQubm9ybWFsaXplKHB1YmxpY0lkKTsKLQotICAgIHVybiA9IFB1YmxpY0lkLnN0cmluZ1JlcGxhY2UodXJuLCAiJSIsICIlMjUiKTsKLSAgICB1cm4gPSBQdWJsaWNJZC5zdHJpbmdSZXBsYWNlKHVybiwgIjsiLCAiJTNCIik7Ci0gICAgdXJuID0gUHVibGljSWQuc3RyaW5nUmVwbGFjZSh1cm4sICInIiwgIiUyNyIpOwotICAgIHVybiA9IFB1YmxpY0lkLnN0cmluZ1JlcGxhY2UodXJuLCAiPyIsICIlM0YiKTsKLSAgICB1cm4gPSBQdWJsaWNJZC5zdHJpbmdSZXBsYWNlKHVybiwgIiMiLCAiJTIzIik7Ci0gICAgdXJuID0gUHVibGljSWQuc3RyaW5nUmVwbGFjZSh1cm4sICIrIiwgIiUyQiIpOwotICAgIHVybiA9IFB1YmxpY0lkLnN0cmluZ1JlcGxhY2UodXJuLCAiICIsICIrIik7Ci0gICAgdXJuID0gUHVibGljSWQuc3RyaW5nUmVwbGFjZSh1cm4sICI6OiIsICI7Iik7Ci0gICAgdXJuID0gUHVibGljSWQuc3RyaW5nUmVwbGFjZSh1cm4sICI6IiwgIiUzQSIpOwotICAgIHVybiA9IFB1YmxpY0lkLnN0cmluZ1JlcGxhY2UodXJuLCAiLy8iLCAiOiIpOwotICAgIHVybiA9IFB1YmxpY0lkLnN0cmluZ1JlcGxhY2UodXJuLCAiLyIsICIlMkYiKTsKLQotICAgIHJldHVybiAidXJuOnB1YmxpY2lkOiIgKyB1cm47Ci0gIH0KLQotICAvKioKLSAgICogRGVjb2RlIGEgInB1YmxpY2lkIiBVUk4gaW50byBhIHB1YmxpYyBpZGVudGlmaWVyLgotICAgKgotICAgKiA8cD5UaGlzIG1ldGhvZCBpcyBkZWNsYXJlZCBzdGF0aWMgc28gdGhhdCBvdGhlciBjbGFzc2VzCi0gICAqIGNhbiB1c2UgaXQgZGlyZWN0bHkuPC9wPgotICAgKgotICAgKiBAcGFyYW0gdXJuIFRoZSB1cm46cHVibGljaWQ6IFVSTgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBub3JtYWxpemVkIGlkZW50aWZpZXIuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIFN0cmluZyBkZWNvZGVVUk4oU3RyaW5nIHVybikgewotICAgIFN0cmluZyBwdWJsaWNJZCA9ICIiOwotCi0gICAgaWYgKHVybi5zdGFydHNXaXRoKCJ1cm46cHVibGljaWQ6IikpIHsKLSAgICAgIHB1YmxpY0lkID0gdXJuLnN1YnN0cmluZygxMyk7Ci0gICAgfSBlbHNlIHsKLSAgICAgIHJldHVybiB1cm47Ci0gICAgfQotCi0gICAgcHVibGljSWQgPSBQdWJsaWNJZC5zdHJpbmdSZXBsYWNlKHB1YmxpY0lkLCAiJTJGIiwgIi8iKTsKLSAgICBwdWJsaWNJZCA9IFB1YmxpY0lkLnN0cmluZ1JlcGxhY2UocHVibGljSWQsICI6IiwgIi8vIik7Ci0gICAgcHVibGljSWQgPSBQdWJsaWNJZC5zdHJpbmdSZXBsYWNlKHB1YmxpY0lkLCAiJTNBIiwgIjoiKTsKLSAgICBwdWJsaWNJZCA9IFB1YmxpY0lkLnN0cmluZ1JlcGxhY2UocHVibGljSWQsICI7IiwgIjo6Iik7Ci0gICAgcHVibGljSWQgPSBQdWJsaWNJZC5zdHJpbmdSZXBsYWNlKHB1YmxpY0lkLCAiKyIsICIgIik7Ci0gICAgcHVibGljSWQgPSBQdWJsaWNJZC5zdHJpbmdSZXBsYWNlKHB1YmxpY0lkLCAiJTJCIiwgIisiKTsKLSAgICBwdWJsaWNJZCA9IFB1YmxpY0lkLnN0cmluZ1JlcGxhY2UocHVibGljSWQsICIlMjMiLCAiIyIpOwotICAgIHB1YmxpY0lkID0gUHVibGljSWQuc3RyaW5nUmVwbGFjZShwdWJsaWNJZCwgIiUzRiIsICI/Iik7Ci0gICAgcHVibGljSWQgPSBQdWJsaWNJZC5zdHJpbmdSZXBsYWNlKHB1YmxpY0lkLCAiJTI3IiwgIiciKTsKLSAgICBwdWJsaWNJZCA9IFB1YmxpY0lkLnN0cmluZ1JlcGxhY2UocHVibGljSWQsICIlM0IiLCAiOyIpOwotICAgIHB1YmxpY0lkID0gUHVibGljSWQuc3RyaW5nUmVwbGFjZShwdWJsaWNJZCwgIiUyNSIsICIlIik7Ci0KLSAgICByZXR1cm4gcHVibGljSWQ7Ci0gICAgfQotCi0gIC8qKgotICAgKiBSZXBsYWNlIG9uZSBzdHJpbmcgd2l0aCBhbm90aGVyLgotICAgKgotICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIHN0cmluZ1JlcGxhY2UoU3RyaW5nIHN0ciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG9sZFN0ciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG5ld1N0cikgewotCi0gICAgU3RyaW5nIHJlc3VsdCA9ICIiOwotICAgIGludCBwb3MgPSBzdHIuaW5kZXhPZihvbGRTdHIpOwotCi0gICAgLy8gICAgU3lzdGVtLm91dC5wcmludGxuKHN0ciArICI6ICIgKyBvbGRTdHIgKyAiID0+ICIgKyBuZXdTdHIpOwotCi0gICAgd2hpbGUgKHBvcyA+PSAwKSB7Ci0gICAgICAvLyAgICAgIFN5c3RlbS5vdXQucHJpbnRsbihzdHIgKyAiICgiICsgcG9zICsgIikiKTsKLSAgICAgIHJlc3VsdCArPSBzdHIuc3Vic3RyaW5nKDAsIHBvcyk7Ci0gICAgICByZXN1bHQgKz0gbmV3U3RyOwotICAgICAgc3RyID0gc3RyLnN1YnN0cmluZyhwb3MrMSk7Ci0KLSAgICAgIHBvcyA9IHN0ci5pbmRleE9mKG9sZFN0cik7Ci0gICAgfQotCi0gICAgcmV0dXJuIHJlc3VsdCArIHN0cjsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvcmVzb2x2ZXIvcmVhZGVycy9DYXRhbG9nUmVhZGVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9yZXNvbHZlci9yZWFkZXJzL0NhdGFsb2dSZWFkZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggY2M4YmQwOS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9yZXNvbHZlci9yZWFkZXJzL0NhdGFsb2dSZWFkZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDgxICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vLyBDYXRhbG9nUmVhZGVyLmphdmEgLSBBbiBpbnRlcmZhY2UgZm9yIHJlYWRpbmcgY2F0YWxvZyBmaWxlcwotCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gb3IgaXRzIGxpY2Vuc29ycywKLSAqIGFzIGFwcGxpY2FibGUuCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXNvbHZlci5yZWFkZXJzOwotCi1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLm5ldC5NYWxmb3JtZWRVUkxFeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXNvbHZlci5DYXRhbG9nRXhjZXB0aW9uOwotCi1pbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnJlc29sdmVyLkNhdGFsb2c7Ci0KLS8qKgotICogVGhlIENhdGFsb2dSZWFkZXIgaW50ZXJmYWNlLgotICoKLSAqIDxwPlRoZSBDYXRhbG9nIGNsYXNzIHJlcXVpcmVzIHRoYXQgY2xhc3NlcyBpbXBsZW1lbnQgdGhpcyBpbnRlcmZhY2UKLSAqIGluIG9yZGVyIHRvIGJlIHVzZWQgdG8gcmVhZCBjYXRhbG9ncy4gRXhhbXBsZXMgb2YgQ2F0YWxvZ1JlYWRlcnMKLSAqIGluY2x1ZGUgdGhlIFRleHRDYXRhbG9nUmVhZGVyLCB0aGUgU0FYQ2F0YWxvZ1JlYWRlciwgYW5kIHRoZQotICogRE9NQ2F0YWxvZ1JlYWRlci48L3A+Ci0gKgotICogQHNlZSBDYXRhbG9nCi0gKgotICogQGF1dGhvciBOb3JtYW4gV2Fsc2gKLSAqIDxhIGhyZWY9Im1haWx0bzpOb3JtYW4uV2Fsc2hAU3VuLkNPTSI+Tm9ybWFuLldhbHNoQFN1bi5DT008L2E+Ci0gKgotICovCi1wdWJsaWMgaW50ZXJmYWNlIENhdGFsb2dSZWFkZXIgewotICAgIC8qKgotICAgICAqIFJlYWQgYSBjYXRhbG9nIGZyb20gYSBmaWxlLgotICAgICAqCi0gICAgICogPHA+VGhpcyBjbGFzcyByZWFkcyBhIGNhdGFsb2cgZnJvbSBhIFVSTC48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gY2F0YWxvZyBUaGUgY2F0YWxvZyBmb3Igd2hpY2ggdGhpcyByZWFkZXIgaXMgY2FsbGVkLgotICAgICAqIEBwYXJhbSBmaWxlVXJsIFRoZSBVUkwgb2YgYSBkb2N1bWVudCB0byBiZSByZWFkLgotICAgICAqIEB0aHJvd3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgVVJMIGNhbm5vdCBiZQotICAgICAqIHR1cm5lZCBpbnRvIGEgVVJMIG9iamVjdC4KLSAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHRoZSBVUkwgY2Fubm90IGJlIHJlYWQuCi0gICAgICogQHRocm93cyBVbmtub3duQ2F0YWxvZ0Zvcm1hdEV4Y2VwdGlvbiBpZiB0aGUgY2F0YWxvZyBmb3JtYXQgaXMKLSAgICAgKiBub3QgcmVjb2duaXplZC4KLSAgICAgKiBAdGhyb3dzIFVucGFyc2VhYmxlQ2F0YWxvZ0V4Y2VwdGlvbiBpZiB0aGUgY2F0YWxvZyBjYW5ub3QgYmUgcGFyc2VkLgotICAgICAqIChGb3IgZXhhbXBsZSwgaWYgaXQgaXMgc3VwcG9zZWQgdG8gYmUgWE1MIGFuZCBpc24ndCB3ZWxsLWZvcm1lZC4pCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcmVhZENhdGFsb2coQ2F0YWxvZyBjYXRhbG9nLCBTdHJpbmcgZmlsZVVybCkKLSAgICAgIHRocm93cyBNYWxmb3JtZWRVUkxFeGNlcHRpb24sIElPRXhjZXB0aW9uLCBDYXRhbG9nRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogUmVhZCBhIGNhdGFsb2cgZnJvbSBhbiBpbnB1dCBzdHJlYW0uCi0gICAgICoKLSAgICAgKiA8cD5UaGlzIGNsYXNzIHJlYWRzIGEgY2F0YWxvZyBmcm9tIGFuIGlucHV0IHN0cmVhbS48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gY2F0YWxvZyBUaGUgY2F0YWxvZyBmb3Igd2hpY2ggdGhpcyByZWFkZXIgaXMgY2FsbGVkLgotICAgICAqIEBwYXJhbSBpcyBUaGUgaW5wdXQgc3RyZWFtIHRoYXQgaXMgdG8gYmUgcmVhZC4KLSAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHRoZSBVUkwgY2Fubm90IGJlIHJlYWQuCi0gICAgICogQHRocm93cyBVbmtub3duQ2F0YWxvZ0Zvcm1hdEV4Y2VwdGlvbiBpZiB0aGUgY2F0YWxvZyBmb3JtYXQgaXMKLSAgICAgKiBub3QgcmVjb2duaXplZC4KLSAgICAgKiBAdGhyb3dzIFVucGFyc2VhYmxlQ2F0YWxvZ0V4Y2VwdGlvbiBpZiB0aGUgY2F0YWxvZyBjYW5ub3QgYmUgcGFyc2VkLgotICAgICAqIChGb3IgZXhhbXBsZSwgaWYgaXQgaXMgc3VwcG9zZWQgdG8gYmUgWE1MIGFuZCBpc24ndCB3ZWxsLWZvcm1lZC4pCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcmVhZENhdGFsb2coQ2F0YWxvZyBjYXRhbG9nLCBJbnB1dFN0cmVhbSBpcykKLSAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBDYXRhbG9nRXhjZXB0aW9uOwotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvcmVzb2x2ZXIvcmVhZGVycy9ET01DYXRhbG9nUGFyc2VyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9yZXNvbHZlci9yZWFkZXJzL0RPTUNhdGFsb2dQYXJzZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZmY0YWY5NS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9yZXNvbHZlci9yZWFkZXJzL0RPTUNhdGFsb2dQYXJzZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDUzICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vLyBET01DYXRhbG9nUGFyc2VyLmphdmEgLSBBbiBpbnRlcmZhY2UgZm9yIHJlYWRpbmcgY2F0YWxvZyBmaWxlcwotCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gb3IgaXRzIGxpY2Vuc29ycywKLSAqIGFzIGFwcGxpY2FibGUuCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXNvbHZlci5yZWFkZXJzOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXNvbHZlci5DYXRhbG9nOwotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci0KLS8qKgotICogVGhlIERPTUNhdGFsb2dQYXJzZXIgaW50ZXJmYWNlLgotICoKLSAqIDxwPlRoaXMgaW50ZXJmYWNlIG11c3QgYmUgaW1wbGVtZW50ZWQgaW4gb3JkZXIgZm9yIGEgY2xhc3MgdG8KLSAqIHBhcnRpY2lwYXRlIGFzIGEgcGFyc2VyIGZvciB0aGUgRE9NQ2F0YWxvZ1JlYWRlci4KLSAqCi0gKiBAc2VlIENhdGFsb2cKLSAqIEBzZWUgRE9NQ2F0YWxvZ1JlYWRlcgotICoKLSAqIEBhdXRob3IgTm9ybWFuIFdhbHNoCi0gKiA8YSBocmVmPSJtYWlsdG86Tm9ybWFuLldhbHNoQFN1bi5DT00iPk5vcm1hbi5XYWxzaEBTdW4uQ09NPC9hPgotICoKLSAqLwotcHVibGljIGludGVyZmFjZSBET01DYXRhbG9nUGFyc2VyIHsKLSAgICAvKioKLSAgICAgKiBQYXJzZSBhIERPTSBub2RlIGFzIGEgY2F0YWxvZyBlbnRyeS4KLSAgICAgKgotICAgICAqIDxwPlRoaXMgbWV0aG9kIGlzIGV4cGVjdGVkIHRvIGFuYWx5emUgdGhlIHNwZWNpZmllZCBub2RlIGFuZAotICAgICAqIGNvbnN0cnVjdCBhcHByb3ByaWF0ZSBjYXRhbG9nIGVudHJ5KGllcykgZnJvbSBpdC48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gY2F0YWxvZyBUaGUgY2F0YWxvZyBmb3Igd2hpY2ggdGhpcyBub2RlIGlzIGJlaW5nIGNvbnNpZGVyZWQuCi0gICAgICogQHBhcmFtIG5vZGUgVGhlIERPTSBOb2RlIGZyb20gdGhlIGNhdGFsb2cuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcGFyc2VDYXRhbG9nRW50cnkoQ2F0YWxvZyBjYXRhbG9nLCBOb2RlIG5vZGUpOwotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvcmVzb2x2ZXIvcmVhZGVycy9ET01DYXRhbG9nUmVhZGVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9yZXNvbHZlci9yZWFkZXJzL0RPTUNhdGFsb2dSZWFkZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNmY0NDk1My4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9yZXNvbHZlci9yZWFkZXJzL0RPTUNhdGFsb2dSZWFkZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI0MyArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDE1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICovCi0vKgotICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCi0gKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKLSAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KLSAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCi0gKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAotICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8vIERPTUNhdGFsb2dSZWFkZXIuamF2YSAtIFJlYWQgWE1MIENhdGFsb2cgZmlsZXMKLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnJlc29sdmVyLnJlYWRlcnM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnJlc29sdmVyLkNhdGFsb2c7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXNvbHZlci5DYXRhbG9nRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzb2x2ZXIuaGVscGVycy5OYW1lc3BhY2VzOwotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci1pbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKLWltcG9ydCBqYXZhLm5ldC5NYWxmb3JtZWRVUkxFeGNlcHRpb247Ci1pbXBvcnQgamF2YS5uZXQuVVJMOwotaW1wb3J0IGphdmEubmV0LlVSTENvbm5lY3Rpb247Ci1pbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7Ci1pbXBvcnQgamF2YS51dGlsLk1hcDsKLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXI7Ci1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy5QYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uOwotaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLkVsZW1lbnQ7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci1pbXBvcnQgc3VuLnJlZmxlY3QubWlzYy5SZWZsZWN0VXRpbDsKLQotLyoqCi0gKiBBIERPTS1iYXNlZCBDYXRhbG9nUmVhZGVyLgotICoKLSAqIDxwPlRoaXMgY2xhc3MgaXMgdXNlZCB0byByZWFkIFhNTCBDYXRhbG9ncyB1c2luZyB0aGUgRE9NLiBUaGlzIHJlYWRlcgotICogaGFzIGFuIGFkdmFudGFnZSBvdmVyIHRoZSBTQVgtYmFzZWQgcmVhZGVyIHRoYXQgaXQgY2FuIGFuYWx5emUgdGhlCi0gKiBET00gdHJlZSByYXRoZXIgdGhhbiBzaW1wbHkgYSBzZXJpZXMgb2YgU0FYIGV2ZW50cy4gSXQgaGFzIHRoZSBkaXNhZHZhbnRhZ2UKLSAqIHRoYXQgaXQgcmVxdWlyZXMgYWxsIG9mIHRoZSBjb2RlIG5lY2Vzc2FyeSB0byBidWlsZCBhbmQgd2FsayBhIERPTQotICogdHJlZS48L3A+Ci0gKgotICogPHA+U2luY2UgdGhlIGNob2ljZSBvZiBDYXRhbG9nUmVhZGVycyAoaW4gdGhlIElucHV0U3RyZWFtIGNhc2UpIGNhbiBvbmx5Ci0gKiBiZSBtYWRlIG9uIHRoZSBiYXNpcyBvZiBNSU1FIHR5cGUsIHRoZSBmb2xsb3dpbmcgcHJvYmxlbSBvY2N1cnM6IG9ubHkKLSAqIG9uZSBDYXRhbG9nUmVhZGVyIGNhbiBleGlzdCBmb3IgYWxsIFhNTCBtaW1lIHR5cGVzLiBJbiBvcmRlciB0byBnZXQKLSAqIGFyb3VuZCB0aGlzIHByb2JsZW0sIHRoZSBET01DYXRhbG9nUmVhZGVyIHJlbGllcyBvbiBhIHNldCBvZiBleHRlcm5hbAotICogQ2F0YWxvZ1BhcnNlcnMgdG8gYWN0dWFsbHkgYnVpbGQgdGhlIGNhdGFsb2cuPC9wPgotICoKLSAqIDxwPlRoZSBzZWxlY3Rpb24gb2YgQ2F0YWxvZ1BhcnNlcnMgaXMgbWFkZSBvbiB0aGUgYmFzaXMgb2YgdGhlIFFOYW1lCi0gKiBvZiB0aGUgcm9vdCBlbGVtZW50IG9mIHRoZSBkb2N1bWVudC48L3A+Ci0gKgotICoKLSAqIEBzZWUgQ2F0YWxvZwotICogQHNlZSBDYXRhbG9nUmVhZGVyCi0gKiBAc2VlIFNBWENhdGFsb2dSZWFkZXIKLSAqIEBzZWUgVGV4dENhdGFsb2dSZWFkZXIKLSAqIEBzZWUgRE9NQ2F0YWxvZ1BhcnNlcgotICoKLSAqIEBhdXRob3IgTm9ybWFuIFdhbHNoCi0gKiA8YSBocmVmPSJtYWlsdG86Tm9ybWFuLldhbHNoQFN1bi5DT00iPk5vcm1hbi5XYWxzaEBTdW4uQ09NPC9hPgotICoKLSAqLwotcHVibGljIGNsYXNzIERPTUNhdGFsb2dSZWFkZXIgaW1wbGVtZW50cyBDYXRhbG9nUmVhZGVyIHsKLSAgLyoqCi0gICAqIE1hcHBpbmcgdGFibGUgZnJvbSBRTmFtZXMgdG8gQ2F0YWxvZ1BhcnNlciBjbGFzc2VzLgotICAgKgotICAgKiA8cD5FYWNoIGtleSBpbiB0aGlzIGhhc2ggdGFibGUgaGFzIHRoZSBmb3JtICJlbGVtZW50bmFtZSIKLSAgICogb3IgIntuYW1lc3BhY2V1cml9ZWxlbWVudG5hbWUiLiBUaGUgZm9ybWVyIGlzIHVzZWQgaWYgdGhlCi0gICAqIG5hbWVzcGFjZSBVUkkgaXMgbnVsbC48L3A+Ci0gICAqLwotICBwcm90ZWN0ZWQgTWFwPFN0cmluZywgU3RyaW5nPiBuYW1lc3BhY2VNYXAgPSBuZXcgSGFzaE1hcDw+KCk7Ci0KLSAgLyoqCi0gICAqIEFkZCBhIG5ldyBwYXJzZXIgdG8gdGhlIHJlYWRlci4KLSAgICoKLSAgICogPHA+VGhpcyBtZXRob2QgYXNzb2NpYXRlcyB0aGUgc3BlY2lmaWVkIHBhcnNlckNsYXNzIHdpdGggdGhlCi0gICAqIG5hbWVzcGFjZVVSSS9yb290RWxlbWVudCBuYW1lcyBzcGVjaWZpZWQuPC9wPgotICAgKgotICAgKiBAcGFyYW0gbmFtZXNwYWNlVVJJIFRoZSBuYW1lc3BhY2UgVVJJLiA8ZW0+Tm90PC9lbT4gdGhlIHByZWZpeC4KLSAgICogQHBhcmFtIHJvb3RFbGVtZW50IFRoZSBuYW1lIG9mIHRoZSByb290IGVsZW1lbnQuCi0gICAqIEBwYXJhbSBwYXJzZXJDbGFzcyBUaGUgbmFtZSBvZiB0aGUgcGFyc2VyQ2xhc3MgdG8gaW5zdGFudGlhdGUKLSAgICogZm9yIHRoaXMga2luZCBvZiBjYXRhbG9nLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0Q2F0YWxvZ1BhcnNlcihTdHJpbmcgbmFtZXNwYWNlVVJJLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyByb290RWxlbWVudCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcGFyc2VyQ2xhc3MpIHsKLSAgICBpZiAobmFtZXNwYWNlVVJJID09IG51bGwpIHsKLSAgICAgIG5hbWVzcGFjZU1hcC5wdXQocm9vdEVsZW1lbnQsIHBhcnNlckNsYXNzKTsKLSAgICB9IGVsc2UgewotICAgICAgbmFtZXNwYWNlTWFwLnB1dCgieyIrbmFtZXNwYWNlVVJJKyJ9Iityb290RWxlbWVudCwgcGFyc2VyQ2xhc3MpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIG5hbWUgb2YgdGhlIHBhcnNlciBjbGFzcyBmb3IgYSBnaXZlbiBjYXRhbG9nIHR5cGUuCi0gICAqCi0gICAqIDxwPlRoaXMgbWV0aG9kIHJldHVybnMgdGhlIHBhcnNlckNsYXNzIGFzc29jaWF0ZWQgd2l0aCB0aGUKLSAgICogbmFtZXNwYWNlVVJJL3Jvb3RFbGVtZW50IG5hbWVzIHNwZWNpZmllZC48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkgVGhlIG5hbWVzcGFjZSBVUkkuIDxlbT5Ob3Q8L2VtPiB0aGUgcHJlZml4LgotICAgKiBAcGFyYW0gcm9vdEVsZW1lbnQgVGhlIG5hbWUgb2YgdGhlIHJvb3QgZWxlbWVudC4KLSAgICogQHJldHVybiBUaGUgcGFyc2VyIGNsYXNzLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRDYXRhbG9nUGFyc2VyKFN0cmluZyBuYW1lc3BhY2VVUkksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcm9vdEVsZW1lbnQpIHsKLSAgICBpZiAobmFtZXNwYWNlVVJJID09IG51bGwpIHsKLSAgICAgIHJldHVybiBuYW1lc3BhY2VNYXAuZ2V0KHJvb3RFbGVtZW50KTsKLSAgICB9IGVsc2UgewotICAgICAgcmV0dXJuIG5hbWVzcGFjZU1hcC5nZXQoInsiK25hbWVzcGFjZVVSSSsifSIrcm9vdEVsZW1lbnQpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBOdWxsIGNvbnN0cnVjdG9yOyBzb21ldGhpbmcgZm9yIHN1YmNsYXNzZXMgdG8gY2FsbC4KLSAgICovCi0gIHB1YmxpYyBET01DYXRhbG9nUmVhZGVyKCkgeyB9Ci0KLSAgLyoqCi0gICAqIFJlYWQgYSBjYXRhbG9nIGZyb20gYW4gaW5wdXQgc3RyZWFtLgotICAgKgotICAgKiA8cD5UaGlzIGNsYXNzIHJlYWRzIGEgY2F0YWxvZyBmcm9tIGFuIGlucHV0IHN0cmVhbTo8L3A+Ci0gICAqCi0gICAqIDx1bD4KLSAgICogPGxpPkJhc2VkIG9uIHRoZSBRTmFtZSBvZiB0aGUgcm9vdCBlbGVtZW50LCBpdCBkZXRlcm1pbmVzIHdoaWNoCi0gICAqIHBhcnNlciB0byBpbnN0YW50aWF0ZSBmb3IgdGhpcyBjYXRhbG9nLjwvbGk+Ci0gICAqIDxsaT5JdCBjb25zdHJ1Y3RzIGEgRE9NIERvY3VtZW50IGZyb20gdGhlIGNhdGFsb2cgYW5kPC9saT4KLSAgICogPGxpPkZvciBlYWNoIGNoaWxkIG9mIHRoZSByb290IG5vZGUsIGl0IGNhbGxzIHRoZSBwYXJzZXIncwotICAgKiBwYXJzZUNhdGFsb2dFbnRyeSBtZXRob2QuIFRoaXMgbWV0aG9kIGlzIGV4cGVjdGVkIHRvIG1ha2UKLSAgICogYXBwcm9wcmlhdGUgY2FsbHMgYmFjayBpbnRvIHRoZSBjYXRhbG9nIHRvIGFkZCBlbnRyaWVzIGZvciB0aGUKLSAgICogZW50cmllcyBpbiB0aGUgY2F0YWxvZy4gSXQgaXMgZnJlZSB0byBkbyB0aGlzIGluIHdoYXRldmVyIG1hbm5lcgotICAgKiBpcyBhcHByb3ByaWF0ZSAocGVyaGFwcyB1c2luZyBqdXN0IHRoZSBub2RlIHBhc3NlZCBpbiwgcGVyaGFwcwotICAgKiB3YW5kZXJpbmcgYXJiaXRyYXJpbHkgdGhyb3VnaG91dCB0aGUgdHJlZSkuPC9saT4KLSAgICogPC91bD4KLSAgICoKLSAgICogQHBhcmFtIGNhdGFsb2cgVGhlIGNhdGFsb2cgZm9yIHdoaWNoIHRoaXMgcmVhZGVyIGlzIGNhbGxlZC4KLSAgICogQHBhcmFtIGlzIFRoZSBpbnB1dCBzdHJlYW0gdGhhdCBpcyB0byBiZSByZWFkLgotICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHRoZSBVUkwgY2Fubm90IGJlIHJlYWQuCi0gICAqIEB0aHJvd3MgVW5rbm93bkNhdGFsb2dGb3JtYXRFeGNlcHRpb24gaWYgdGhlIGNhdGFsb2cgZm9ybWF0IGlzCi0gICAqIG5vdCByZWNvZ25pemVkLgotICAgKiBAdGhyb3dzIFVucGFyc2VhYmxlQ2F0YWxvZ0V4Y2VwdGlvbiBpZiB0aGUgY2F0YWxvZyBjYW5ub3QgYmUgcGFyc2VkLgotICAgKiAoRm9yIGV4YW1wbGUsIGlmIGl0IGlzIHN1cHBvc2VkIHRvIGJlIFhNTCBhbmQgaXNuJ3Qgd2VsbC1mb3JtZWQgb3IKLSAgICogaWYgdGhlIHBhcnNlciBjbGFzcyBjYW5ub3QgYmUgaW5zdGFudGlhdGVkLikKLSAgICovCi0gIHB1YmxpYyB2b2lkIHJlYWRDYXRhbG9nKENhdGFsb2cgY2F0YWxvZywgSW5wdXRTdHJlYW0gaXMpCi0gICAgdGhyb3dzIElPRXhjZXB0aW9uLCBDYXRhbG9nRXhjZXB0aW9uIHsKLQotICAgIERvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSA9IG51bGw7Ci0gICAgRG9jdW1lbnRCdWlsZGVyIGJ1aWxkZXIgPSBudWxsOwotCi0gICAgZmFjdG9yeSA9IERvY3VtZW50QnVpbGRlckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKLSAgICBmYWN0b3J5LnNldE5hbWVzcGFjZUF3YXJlKGZhbHNlKTsKLSAgICBmYWN0b3J5LnNldFZhbGlkYXRpbmcoZmFsc2UpOwotICAgIHRyeSB7Ci0gICAgICBidWlsZGVyID0gZmFjdG9yeS5uZXdEb2N1bWVudEJ1aWxkZXIoKTsKLSAgICB9IGNhdGNoIChQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIHBjZSkgewotICAgICAgdGhyb3cgbmV3IENhdGFsb2dFeGNlcHRpb24oQ2F0YWxvZ0V4Y2VwdGlvbi5VTlBBUlNFQUJMRSk7Ci0gICAgfQotCi0gICAgRG9jdW1lbnQgZG9jID0gbnVsbDsKLQotICAgIHRyeSB7Ci0gICAgICBkb2MgPSBidWlsZGVyLnBhcnNlKGlzKTsKLSAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gc2UpIHsKLSAgICAgIHRocm93IG5ldyBDYXRhbG9nRXhjZXB0aW9uKENhdGFsb2dFeGNlcHRpb24uVU5LTk9XTl9GT1JNQVQpOwotICAgIH0KLQotICAgIEVsZW1lbnQgcm9vdCA9IGRvYy5nZXREb2N1bWVudEVsZW1lbnQoKTsKLQotICAgIFN0cmluZyBuYW1lc3BhY2VVUkkgPSBOYW1lc3BhY2VzLmdldE5hbWVzcGFjZVVSSShyb290KTsKLSAgICBTdHJpbmcgbG9jYWxOYW1lICAgID0gTmFtZXNwYWNlcy5nZXRMb2NhbE5hbWUocm9vdCk7Ci0KLSAgICBTdHJpbmcgZG9tUGFyc2VyQ2xhc3MgPSBnZXRDYXRhbG9nUGFyc2VyKG5hbWVzcGFjZVVSSSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2FsTmFtZSk7Ci0KLSAgICBpZiAoZG9tUGFyc2VyQ2xhc3MgPT0gbnVsbCkgewotICAgICAgaWYgKG5hbWVzcGFjZVVSSSA9PSBudWxsKSB7Ci0gICAgICAgIGNhdGFsb2cuZ2V0Q2F0YWxvZ01hbmFnZXIoKS5kZWJ1Zy5tZXNzYWdlKDEsICJObyBDYXRhbG9nIHBhcnNlciBmb3IgIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGxvY2FsTmFtZSk7Ci0gICAgICB9IGVsc2UgewotICAgICAgICBjYXRhbG9nLmdldENhdGFsb2dNYW5hZ2VyKCkuZGVidWcubWVzc2FnZSgxLCAiTm8gQ2F0YWxvZyBwYXJzZXIgZm9yICIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAieyIgKyBuYW1lc3BhY2VVUkkgKyAifSIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBsb2NhbE5hbWUpOwotICAgICAgfQotICAgICAgcmV0dXJuOwotICAgIH0KLQotICAgIERPTUNhdGFsb2dQYXJzZXIgZG9tUGFyc2VyID0gbnVsbDsKLQotICAgIHRyeSB7Ci0gICAgICBkb21QYXJzZXIgPSAoRE9NQ2F0YWxvZ1BhcnNlcikgUmVmbGVjdFV0aWwuZm9yTmFtZShkb21QYXJzZXJDbGFzcykubmV3SW5zdGFuY2UoKTsKLSAgICB9IGNhdGNoIChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGNuZmUpIHsKLSAgICAgIGNhdGFsb2cuZ2V0Q2F0YWxvZ01hbmFnZXIoKS5kZWJ1Zy5tZXNzYWdlKDEsICJDYW5ub3QgbG9hZCBYTUwgQ2F0YWxvZyBQYXJzZXIgY2xhc3MiLCBkb21QYXJzZXJDbGFzcyk7Ci0gICAgICB0aHJvdyBuZXcgQ2F0YWxvZ0V4Y2VwdGlvbihDYXRhbG9nRXhjZXB0aW9uLlVOUEFSU0VBQkxFKTsKLSAgICB9IGNhdGNoIChJbnN0YW50aWF0aW9uRXhjZXB0aW9uIGllKSB7Ci0gICAgICBjYXRhbG9nLmdldENhdGFsb2dNYW5hZ2VyKCkuZGVidWcubWVzc2FnZSgxLCAiQ2Fubm90IGluc3RhbnRpYXRlIFhNTCBDYXRhbG9nIFBhcnNlciBjbGFzcyIsIGRvbVBhcnNlckNsYXNzKTsKLSAgICAgIHRocm93IG5ldyBDYXRhbG9nRXhjZXB0aW9uKENhdGFsb2dFeGNlcHRpb24uVU5QQVJTRUFCTEUpOwotICAgIH0gY2F0Y2ggKElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gaWFlKSB7Ci0gICAgICBjYXRhbG9nLmdldENhdGFsb2dNYW5hZ2VyKCkuZGVidWcubWVzc2FnZSgxLCAiQ2Fubm90IGFjY2VzcyBYTUwgQ2F0YWxvZyBQYXJzZXIgY2xhc3MiLCBkb21QYXJzZXJDbGFzcyk7Ci0gICAgICB0aHJvdyBuZXcgQ2F0YWxvZ0V4Y2VwdGlvbihDYXRhbG9nRXhjZXB0aW9uLlVOUEFSU0VBQkxFKTsKLSAgICB9IGNhdGNoIChDbGFzc0Nhc3RFeGNlcHRpb24gY2NlICkgewotICAgICAgY2F0YWxvZy5nZXRDYXRhbG9nTWFuYWdlcigpLmRlYnVnLm1lc3NhZ2UoMSwgIkNhbm5vdCBjYXN0IFhNTCBDYXRhbG9nIFBhcnNlciBjbGFzcyIsIGRvbVBhcnNlckNsYXNzKTsKLSAgICAgIHRocm93IG5ldyBDYXRhbG9nRXhjZXB0aW9uKENhdGFsb2dFeGNlcHRpb24uVU5QQVJTRUFCTEUpOwotICAgIH0KLQotICAgIE5vZGUgbm9kZSA9IHJvb3QuZ2V0Rmlyc3RDaGlsZCgpOwotICAgIHdoaWxlIChub2RlICE9IG51bGwpIHsKLSAgICAgIGRvbVBhcnNlci5wYXJzZUNhdGFsb2dFbnRyeShjYXRhbG9nLCBub2RlKTsKLSAgICAgIG5vZGUgPSBub2RlLmdldE5leHRTaWJsaW5nKCk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFJlYWQgdGhlIGNhdGFsb2cgYmVoaW5kIHRoZSBzcGVjaWZpZWQgVVJMLgotICAgKgotICAgKiBAc2VlICNyZWFkQ2F0YWxvZyhDYXRhbG9nLCBJbnB1dFN0cmVhbSkKLSAgICoKLSAgICogQHBhcmFtIGNhdGFsb2cgVGhlIGNhdGFsb2cgZm9yIHdoaWNoIHdlIGFyZSByZWFkaW5nLgotICAgKiBAcGFyYW0gZmlsZVVybCBUaGUgVVJMIG9mIHRoZSBkb2N1bWVudCB0aGF0IHNob3VsZCBiZSByZWFkLgotICAgKgotICAgKiBAdGhyb3dzIE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIFVSTCBjYW5ub3QgYmUKLSAgICogdHVybmVkIGludG8gYSBVUkwgb2JqZWN0LgotICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHRoZSBVUkwgY2Fubm90IGJlIHJlYWQuCi0gICAqIEB0aHJvd3MgVW5rbm93bkNhdGFsb2dGb3JtYXRFeGNlcHRpb24gaWYgdGhlIGNhdGFsb2cgZm9ybWF0IGlzCi0gICAqIG5vdCByZWNvZ25pemVkLgotICAgKiBAdGhyb3dzIFVucGFyc2VhYmxlQ2F0YWxvZ0V4Y2VwdGlvbiBpZiB0aGUgY2F0YWxvZyBjYW5ub3QgYmUgcGFyc2VkLgotICAgKiAoRm9yIGV4YW1wbGUsIGlmIGl0IGlzIHN1cHBvc2VkIHRvIGJlIFhNTCBhbmQgaXNuJ3Qgd2VsbC1mb3JtZWQuKQotICAgKi8KLSAgcHVibGljIHZvaWQgcmVhZENhdGFsb2coQ2F0YWxvZyBjYXRhbG9nLCBTdHJpbmcgZmlsZVVybCkKLSAgICB0aHJvd3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiwgQ2F0YWxvZ0V4Y2VwdGlvbiB7Ci0gICAgVVJMIHVybCA9IG5ldyBVUkwoZmlsZVVybCk7Ci0gICAgVVJMQ29ubmVjdGlvbiB1cmxDb24gPSB1cmwub3BlbkNvbm5lY3Rpb24oKTsKLSAgICByZWFkQ2F0YWxvZyhjYXRhbG9nLCB1cmxDb24uZ2V0SW5wdXRTdHJlYW0oKSk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3Jlc29sdmVyL3JlYWRlcnMvRXh0ZW5kZWRYTUxDYXRhbG9nUmVhZGVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9yZXNvbHZlci9yZWFkZXJzL0V4dGVuZGVkWE1MQ2F0YWxvZ1JlYWRlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhNjM4YTQ3Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3Jlc29sdmVyL3JlYWRlcnMvRXh0ZW5kZWRYTUxDYXRhbG9nUmVhZGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxODcgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8vIEV4dGVuZGVkWE1MQ2F0YWxvZ1JlYWRlci5qYXZhIC0gUmVhZCBYTUwgQ2F0YWxvZyBmaWxlcwotCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gb3IgaXRzIGxpY2Vuc29ycywKLSAqIGFzIGFwcGxpY2FibGUuCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXNvbHZlci5yZWFkZXJzOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnJlc29sdmVyLkNhdGFsb2c7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXNvbHZlci5SZXNvbHZlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnJlc29sdmVyLkNhdGFsb2dFbnRyeTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnJlc29sdmVyLkNhdGFsb2dFeGNlcHRpb247Ci0KLWltcG9ydCBvcmcueG1sLnNheC4qOwotaW1wb3J0IG9yZy53M2MuZG9tLio7Ci0KLS8qKgotICogUGFyc2UgRXh0ZW5kZWQgT0FTSVMgRW50aXR5IFJlc29sdXRpb24gVGVjaG5pY2FsIENvbW1pdHRlZQotICogWE1MIENhdGFsb2cgZmlsZXMuCi0gKgotICogQHNlZSBDYXRhbG9nCi0gKgotICogQGF1dGhvciBOb3JtYW4gV2Fsc2gKLSAqIDxhIGhyZWY9Im1haWx0bzpOb3JtYW4uV2Fsc2hAU3VuLkNPTSI+Tm9ybWFuLldhbHNoQFN1bi5DT008L2E+Ci0gKgotICovCi1wdWJsaWMgY2xhc3MgRXh0ZW5kZWRYTUxDYXRhbG9nUmVhZGVyIGV4dGVuZHMgT0FTSVNYTUxDYXRhbG9nUmVhZGVyIHsKLSAgLyoqIFRoZSBuYW1lc3BhY2UgbmFtZSBvZiBleHRlbmRlZCBjYXRhbG9nIGVsZW1lbnRzICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIGV4dGVuZGVkTmFtZXNwYWNlTmFtZSA9ICJodHRwOi8vbndhbHNoLmNvbS94Y2F0YWxvZy8xLjAiOwotCi0gIC8qKgotICAgKiBUaGUgU0FYIDxjb2RlPnN0YXJ0RWxlbWVudDwvY29kZT4gbWV0aG9kIHJlY29nbml6ZXMgZWxlbWVudHMKLSAgICogZnJvbSB0aGUgcGxhaW4gY2F0YWxvZyBmb3JtYXQgYW5kIGluc3RhbnRpYXRlcyBDYXRhbG9nRW50cnkKLSAgICogb2JqZWN0cyBmb3IgdGhlbS4KLSAgICoKLSAgICogQHBhcmFtIG5hbWVzcGFjZVVSSSBUaGUgbmFtZXNwYWNlIG5hbWUgb2YgdGhlIGVsZW1lbnQuCi0gICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGxvY2FsIG5hbWUgb2YgdGhlIGVsZW1lbnQuCi0gICAqIEBwYXJhbSBxTmFtZSBUaGUgUU5hbWUgb2YgdGhlIGVsZW1lbnQuCi0gICAqIEBwYXJhbSBhdHRzIFRoZSBsaXN0IG9mIGF0dHJpYnV0ZXMgb24gdGhlIGVsZW1lbnQuCi0gICAqCi0gICAqIEBzZWUgQ2F0YWxvZ0VudHJ5Ci0gICAqLwotICBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQgKFN0cmluZyBuYW1lc3BhY2VVUkksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGxvY2FsTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcU5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgQXR0cmlidXRlcyBhdHRzKQotICAgIHRocm93cyBTQVhFeGNlcHRpb24gewotCi0gICAgLy8gQ2hlY2sgYmVmb3JlIGNhbGxpbmcgdGhlIHN1cGVyIGJlY2F1c2Ugc3VwZXIgd2lsbCByZXBvcnQgb3VyCi0gICAgLy8gbmFtZXNwYWNlIGFzIGFuIGV4dGVuc2lvbiBuYW1lc3BhY2UsIGJ1dCB0aGF0IGRvZXNuJ3QgY291bnQKLSAgICAvLyBmb3IgdGhpcyBlbGVtZW50LgotICAgIGJvb2xlYW4gaW5FeHRlbnNpb24gPSBpbkV4dGVuc2lvbk5hbWVzcGFjZSgpOwotCi0gICAgc3VwZXIuc3RhcnRFbGVtZW50KG5hbWVzcGFjZVVSSSwgbG9jYWxOYW1lLCBxTmFtZSwgYXR0cyk7Ci0KLSAgICBpbnQgZW50cnlUeXBlID0gLTE7Ci0gICAgVmVjdG9yIGVudHJ5QXJncyA9IG5ldyBWZWN0b3IoKTsKLQotICAgIGlmIChuYW1lc3BhY2VVUkkgIT0gbnVsbCAmJiBleHRlbmRlZE5hbWVzcGFjZU5hbWUuZXF1YWxzKG5hbWVzcGFjZVVSSSkKLSAgICAgICAgJiYgIWluRXh0ZW5zaW9uKSB7Ci0gICAgICAvLyBUaGlzIGlzIGFuIEV4dGVuZGVkIFhNTCBDYXRhbG9nIGVudHJ5Ci0KLSAgICAgIGlmIChhdHRzLmdldFZhbHVlKCJ4bWw6YmFzZSIpICE9IG51bGwpIHsKLSAgICAgICAgU3RyaW5nIGJhc2VVUkkgPSBhdHRzLmdldFZhbHVlKCJ4bWw6YmFzZSIpOwotICAgICAgICBlbnRyeVR5cGUgPSBDYXRhbG9nLkJBU0U7Ci0gICAgICAgIGVudHJ5QXJncy5hZGQoYmFzZVVSSSk7Ci0gICAgICAgIGJhc2VVUklTdGFjay5wdXNoKGJhc2VVUkkpOwotCi0gICAgICAgIGRlYnVnLm1lc3NhZ2UoNCwgInhtbDpiYXNlIiwgYmFzZVVSSSk7Ci0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICBDYXRhbG9nRW50cnkgY2UgPSBuZXcgQ2F0YWxvZ0VudHJ5KGVudHJ5VHlwZSwgZW50cnlBcmdzKTsKLSAgICAgICAgICBjYXRhbG9nLmFkZEVudHJ5KGNlKTsKLSAgICAgICAgfSBjYXRjaCAoQ2F0YWxvZ0V4Y2VwdGlvbiBjZXgpIHsKLSAgICAgICAgICBpZiAoY2V4LmdldEV4Y2VwdGlvblR5cGUoKSA9PSBDYXRhbG9nRXhjZXB0aW9uLklOVkFMSURfRU5UUllfVFlQRSkgewotICAgICAgICAgICAgZGVidWcubWVzc2FnZSgxLCAiSW52YWxpZCBjYXRhbG9nIGVudHJ5IHR5cGUiLCBsb2NhbE5hbWUpOwotICAgICAgICAgIH0gZWxzZSBpZiAoY2V4LmdldEV4Y2VwdGlvblR5cGUoKSA9PSBDYXRhbG9nRXhjZXB0aW9uLklOVkFMSURfRU5UUlkpIHsKLSAgICAgICAgICAgIGRlYnVnLm1lc3NhZ2UoMSwgIkludmFsaWQgY2F0YWxvZyBlbnRyeSAoYmFzZSkiLCBsb2NhbE5hbWUpOwotICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGVudHJ5VHlwZSA9IC0xOwotICAgICAgICBlbnRyeUFyZ3MgPSBuZXcgVmVjdG9yKCk7Ci0gICAgICB9IGVsc2UgewotICAgICAgICBiYXNlVVJJU3RhY2sucHVzaChiYXNlVVJJU3RhY2sucGVlaygpKTsKLSAgICAgIH0KLQotICAgICAgaWYgKGxvY2FsTmFtZS5lcXVhbHMoInVyaVN1ZmZpeCIpKSB7Ci0gICAgICAgIGlmIChjaGVja0F0dHJpYnV0ZXMoYXR0cywgInN1ZmZpeCIsICJ1cmkiKSkgewotICAgICAgICAgIGVudHJ5VHlwZSA9IFJlc29sdmVyLlVSSVNVRkZJWDsKLSAgICAgICAgICBlbnRyeUFyZ3MuYWRkKGF0dHMuZ2V0VmFsdWUoInN1ZmZpeCIpKTsKLSAgICAgICAgICBlbnRyeUFyZ3MuYWRkKGF0dHMuZ2V0VmFsdWUoInVyaSIpKTsKLQotICAgICAgICAgIGRlYnVnLm1lc3NhZ2UoNCwgInVyaVN1ZmZpeCIsCi0gICAgICAgICAgICAgICAgICAgICAgICBhdHRzLmdldFZhbHVlKCJzdWZmaXgiKSwKLSAgICAgICAgICAgICAgICAgICAgICAgIGF0dHMuZ2V0VmFsdWUoInVyaSIpKTsKLSAgICAgICAgfQotICAgICAgfSBlbHNlIGlmIChsb2NhbE5hbWUuZXF1YWxzKCJzeXN0ZW1TdWZmaXgiKSkgewotICAgICAgICBpZiAoY2hlY2tBdHRyaWJ1dGVzKGF0dHMsICJzdWZmaXgiLCAidXJpIikpIHsKLSAgICAgICAgICBlbnRyeVR5cGUgPSBSZXNvbHZlci5TWVNURU1TVUZGSVg7Ci0gICAgICAgICAgZW50cnlBcmdzLmFkZChhdHRzLmdldFZhbHVlKCJzdWZmaXgiKSk7Ci0gICAgICAgICAgZW50cnlBcmdzLmFkZChhdHRzLmdldFZhbHVlKCJ1cmkiKSk7Ci0KLSAgICAgICAgICBkZWJ1Zy5tZXNzYWdlKDQsICJzeXN0ZW1TdWZmaXgiLAotICAgICAgICAgICAgICAgICAgICAgICAgYXR0cy5nZXRWYWx1ZSgic3VmZml4IiksCi0gICAgICAgICAgICAgICAgICAgICAgICBhdHRzLmdldFZhbHVlKCJ1cmkiKSk7Ci0gICAgICAgIH0KLSAgICAgIH0gZWxzZSB7Ci0gICAgICAgIC8vIFRoaXMgaXMgZXF1aXZhbGVudCB0byBhbiBpbnZhbGlkIGNhdGFsb2cgZW50cnkgdHlwZQotICAgICAgICBkZWJ1Zy5tZXNzYWdlKDEsICJJbnZhbGlkIGNhdGFsb2cgZW50cnkgdHlwZSIsIGxvY2FsTmFtZSk7Ci0gICAgICB9Ci0KLSAgICAgIGlmIChlbnRyeVR5cGUgPj0gMCkgewotICAgICAgICB0cnkgewotICAgICAgICAgIENhdGFsb2dFbnRyeSBjZSA9IG5ldyBDYXRhbG9nRW50cnkoZW50cnlUeXBlLCBlbnRyeUFyZ3MpOwotICAgICAgICAgIGNhdGFsb2cuYWRkRW50cnkoY2UpOwotICAgICAgICB9IGNhdGNoIChDYXRhbG9nRXhjZXB0aW9uIGNleCkgewotICAgICAgICAgIGlmIChjZXguZ2V0RXhjZXB0aW9uVHlwZSgpID09IENhdGFsb2dFeGNlcHRpb24uSU5WQUxJRF9FTlRSWV9UWVBFKSB7Ci0gICAgICAgICAgICBkZWJ1Zy5tZXNzYWdlKDEsICJJbnZhbGlkIGNhdGFsb2cgZW50cnkgdHlwZSIsIGxvY2FsTmFtZSk7Ci0gICAgICAgICAgfSBlbHNlIGlmIChjZXguZ2V0RXhjZXB0aW9uVHlwZSgpID09IENhdGFsb2dFeGNlcHRpb24uSU5WQUxJRF9FTlRSWSkgewotICAgICAgICAgICAgZGVidWcubWVzc2FnZSgxLCAiSW52YWxpZCBjYXRhbG9nIGVudHJ5IiwgbG9jYWxOYW1lKTsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICB9Ci0gIH0KLQotICAvKiogVGhlIFNBWCA8Y29kZT5lbmRFbGVtZW50PC9jb2RlPiBtZXRob2QgZG9lcyBub3RoaW5nLiAqLwotICBwdWJsaWMgdm9pZCBlbmRFbGVtZW50IChTdHJpbmcgbmFtZXNwYWNlVVJJLAotICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbG9jYWxOYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcU5hbWUpCi0gICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0KLSAgICBzdXBlci5lbmRFbGVtZW50KG5hbWVzcGFjZVVSSSwgbG9jYWxOYW1lLCBxTmFtZSk7Ci0KLSAgICAvLyBDaGVjayBhZnRlciBwb3BwaW5nIHRoZSBzdGFjayBzbyB3ZSBkb24ndCBlcnJvbmVvdXNseSB0aGluayB3ZQotICAgIC8vIGFyZSBvdXIgb3duIGV4dGVuc2lvbiBuYW1lc3BhY2UuLi4KLSAgICBib29sZWFuIGluRXh0ZW5zaW9uID0gaW5FeHRlbnNpb25OYW1lc3BhY2UoKTsKLQotICAgIGludCBlbnRyeVR5cGUgPSAtMTsKLSAgICBWZWN0b3IgZW50cnlBcmdzID0gbmV3IFZlY3RvcigpOwotCi0gICAgaWYgKG5hbWVzcGFjZVVSSSAhPSBudWxsCi0gICAgICAgICYmIChleHRlbmRlZE5hbWVzcGFjZU5hbWUuZXF1YWxzKG5hbWVzcGFjZVVSSSkpCi0gICAgICAgICYmICFpbkV4dGVuc2lvbikgewotCi0gICAgICBTdHJpbmcgcG9wVVJJID0gKFN0cmluZykgYmFzZVVSSVN0YWNrLnBvcCgpOwotICAgICAgU3RyaW5nIGJhc2VVUkkgPSAoU3RyaW5nKSBiYXNlVVJJU3RhY2sucGVlaygpOwotCi0gICAgICBpZiAoIWJhc2VVUkkuZXF1YWxzKHBvcFVSSSkpIHsKLSAgICAgICAgZW50cnlUeXBlID0gY2F0YWxvZy5CQVNFOwotICAgICAgICBlbnRyeUFyZ3MuYWRkKGJhc2VVUkkpOwotCi0gICAgICAgIGRlYnVnLm1lc3NhZ2UoNCwgIihyZXNldCkgeG1sOmJhc2UiLCBiYXNlVVJJKTsKLQotICAgICAgICB0cnkgewotICAgICAgICAgIENhdGFsb2dFbnRyeSBjZSA9IG5ldyBDYXRhbG9nRW50cnkoZW50cnlUeXBlLCBlbnRyeUFyZ3MpOwotICAgICAgICAgIGNhdGFsb2cuYWRkRW50cnkoY2UpOwotICAgICAgICB9IGNhdGNoIChDYXRhbG9nRXhjZXB0aW9uIGNleCkgewotICAgICAgICAgIGlmIChjZXguZ2V0RXhjZXB0aW9uVHlwZSgpID09IENhdGFsb2dFeGNlcHRpb24uSU5WQUxJRF9FTlRSWV9UWVBFKSB7Ci0gICAgICAgICAgICBkZWJ1Zy5tZXNzYWdlKDEsICJJbnZhbGlkIGNhdGFsb2cgZW50cnkgdHlwZSIsIGxvY2FsTmFtZSk7Ci0gICAgICAgICAgfSBlbHNlIGlmIChjZXguZ2V0RXhjZXB0aW9uVHlwZSgpID09IENhdGFsb2dFeGNlcHRpb24uSU5WQUxJRF9FTlRSWSkgewotICAgICAgICAgICAgZGVidWcubWVzc2FnZSgxLCAiSW52YWxpZCBjYXRhbG9nIGVudHJ5IChyYmFzZSkiLCBsb2NhbE5hbWUpOwotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvcmVzb2x2ZXIvcmVhZGVycy9PQVNJU1hNTENhdGFsb2dSZWFkZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3Jlc29sdmVyL3JlYWRlcnMvT0FTSVNYTUxDYXRhbG9nUmVhZGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGYxZDZiODkuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvcmVzb2x2ZXIvcmVhZGVycy9PQVNJU1hNTENhdGFsb2dSZWFkZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDU0MSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLy8gT0FTSVNYTUxDYXRhbG9nUmVhZGVyLmphdmEgLSBSZWFkIFhNTCBDYXRhbG9nIGZpbGVzCi0KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBvciBpdHMgbGljZW5zb3JzLAotICogYXMgYXBwbGljYWJsZS4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnJlc29sdmVyLnJlYWRlcnM7Ci0KLWltcG9ydCBqYXZhLnV0aWwuU3RhY2s7Ci1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLWltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXNvbHZlci5DYXRhbG9nOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzb2x2ZXIuQ2F0YWxvZ0VudHJ5OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzb2x2ZXIuQ2F0YWxvZ0V4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnJlc29sdmVyLmhlbHBlcnMuUHVibGljSWQ7Ci0KLWltcG9ydCBvcmcueG1sLnNheC4qOwotaW1wb3J0IG9yZy53M2MuZG9tLio7Ci0KLS8qKgotICogUGFyc2UgT0FTSVMgRW50aXR5IFJlc29sdXRpb24gVGVjaG5pY2FsIENvbW1pdHRlZQotICogWE1MIENhdGFsb2cgZmlsZXMuCi0gKgotICogQHNlZSBDYXRhbG9nCi0gKgotICogQGF1dGhvciBOb3JtYW4gV2Fsc2gKLSAqIDxhIGhyZWY9Im1haWx0bzpOb3JtYW4uV2Fsc2hAU3VuLkNPTSI+Tm9ybWFuLldhbHNoQFN1bi5DT008L2E+Ci0gKgotICovCi1wdWJsaWMgY2xhc3MgT0FTSVNYTUxDYXRhbG9nUmVhZGVyIGV4dGVuZHMgU0FYQ2F0YWxvZ1JlYWRlciBpbXBsZW1lbnRzIFNBWENhdGFsb2dQYXJzZXIgewotICAvKiogVGhlIGNhdGFsb2cgb2JqZWN0IG5lZWRzIHRvIGJlIHN0b3JlZCBieSB0aGUgb2JqZWN0IHNvIHRoYXQKLSAgICogU0FYIGNhbGxiYWNrcyBjYW4gdXNlIGl0LgotICAgKi8KLSAgcHJvdGVjdGVkIENhdGFsb2cgY2F0YWxvZyA9IG51bGw7Ci0KLSAgLyoqIFRoZSBuYW1lc3BhY2UgbmFtZSBvZiBPQVNJUyBFUlRDIGNhdGFsb2dzICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIG5hbWVzcGFjZU5hbWUgPSAidXJuOm9hc2lzOm5hbWVzOnRjOmVudGl0eTp4bWxuczp4bWw6Y2F0YWxvZyI7Ci0KLSAgLyoqIFRoZSBuYW1lc3BhY2UgbmFtZSBvZiBPQVNJUyBFUlRDIFRSOTQwMSBjYXRhbG9nIGV4dGVuc2lvbiAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyB0cjk0MDFOYW1lc3BhY2VOYW1lID0gInVybjpvYXNpczpuYW1lczp0YzplbnRpdHk6eG1sbnM6dHI5NDAxOmNhdGFsb2ciOwotCi0gIHByb3RlY3RlZCBTdGFjayBiYXNlVVJJU3RhY2sgPSBuZXcgU3RhY2soKTsKLSAgcHJvdGVjdGVkIFN0YWNrIG92ZXJyaWRlU3RhY2sgPSBuZXcgU3RhY2soKTsKLSAgcHJvdGVjdGVkIFN0YWNrIG5hbWVzcGFjZVN0YWNrID0gbmV3IFN0YWNrKCk7Ci0KLSAgLyoqIFNldCB0aGUgY3VycmVudCBjYXRhbG9nLiAqLwotICBwdWJsaWMgdm9pZCBzZXRDYXRhbG9nIChDYXRhbG9nIGNhdGFsb2cpIHsKLSAgICB0aGlzLmNhdGFsb2cgPSBjYXRhbG9nOwotICAgIGRlYnVnID0gY2F0YWxvZy5nZXRDYXRhbG9nTWFuYWdlcigpLmRlYnVnOwotICB9Ci0KLSAgLyoqIEdldCB0aGUgY3VycmVudCBjYXRhbG9nLiAqLwotICBwdWJsaWMgQ2F0YWxvZyBnZXRDYXRhbG9nICgpIHsKLSAgICByZXR1cm4gY2F0YWxvZzsKLSAgfQotCi0gIC8qKgotICAgKiBBcmUgd2UgaW4gYW4gZXh0ZW5zaW9uIG5hbWVzcGFjZT8KLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHRoZSBjdXJyZW50IHN0YWNrIG9mIG9wZW4gbmFtZXNwYWNlcyBpbmNsdWRlcwotICAgKiAgICAgICAgICAgICAgIGFuIGV4dGVuc2lvbiBuYW1lc3BhY2UuCi0gICAqLwotICBwcm90ZWN0ZWQgYm9vbGVhbiBpbkV4dGVuc2lvbk5hbWVzcGFjZSgpIHsKLSAgICBib29sZWFuIGluRXh0ZW5zaW9uID0gZmFsc2U7Ci0KLSAgICBFbnVtZXJhdGlvbiBlbGVtZW50cyA9IG5hbWVzcGFjZVN0YWNrLmVsZW1lbnRzKCk7Ci0gICAgd2hpbGUgKCFpbkV4dGVuc2lvbiAmJiBlbGVtZW50cy5oYXNNb3JlRWxlbWVudHMoKSkgewotICAgICAgU3RyaW5nIG5zID0gKFN0cmluZykgZWxlbWVudHMubmV4dEVsZW1lbnQoKTsKLSAgICAgIGlmIChucyA9PSBudWxsKSB7Ci0gICAgICAgIGluRXh0ZW5zaW9uID0gdHJ1ZTsKLSAgICAgIH0gZWxzZSB7Ci0gICAgICAgIGluRXh0ZW5zaW9uID0gKCFucy5lcXVhbHModHI5NDAxTmFtZXNwYWNlTmFtZSkKLSAgICAgICAgICAgICAgICAgICAgICAgJiYgIW5zLmVxdWFscyhuYW1lc3BhY2VOYW1lKSk7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgcmV0dXJuIGluRXh0ZW5zaW9uOwotICB9Ci0KLSAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAvLyBJbXBsZW1lbnQgdGhlIFNBWCBDb250ZW50SGFuZGxlciBpbnRlcmZhY2UKLQotICAvKiogVGhlIFNBWCA8Y29kZT5zZXREb2N1bWVudExvY2F0b3I8L2NvZGU+IG1ldGhvZCBkb2VzIG5vdGhpbmcuICovCi0gIHB1YmxpYyB2b2lkIHNldERvY3VtZW50TG9jYXRvciAoTG9jYXRvciBsb2NhdG9yKSB7Ci0gICAgcmV0dXJuOwotICB9Ci0KLSAgLyoqIFRoZSBTQVggPGNvZGU+c3RhcnREb2N1bWVudDwvY29kZT4gbWV0aG9kIGRvZXMgbm90aGluZy4gKi8KLSAgcHVibGljIHZvaWQgc3RhcnREb2N1bWVudCAoKQotICAgIHRocm93cyBTQVhFeGNlcHRpb24gewotICAgIGJhc2VVUklTdGFjay5wdXNoKGNhdGFsb2cuZ2V0Q3VycmVudEJhc2UoKSk7Ci0gICAgb3ZlcnJpZGVTdGFjay5wdXNoKGNhdGFsb2cuZ2V0RGVmYXVsdE92ZXJyaWRlKCkpOwotICAgIHJldHVybjsKLSAgfQotCi0gIC8qKiBUaGUgU0FYIDxjb2RlPmVuZERvY3VtZW50PC9jb2RlPiBtZXRob2QgZG9lcyBub3RoaW5nLiAqLwotICBwdWJsaWMgdm9pZCBlbmREb2N1bWVudCAoKQotICAgIHRocm93cyBTQVhFeGNlcHRpb24gewotICAgIHJldHVybjsKLSAgfQotCi0gIC8qKgotICAgKiBUaGUgU0FYIDxjb2RlPnN0YXJ0RWxlbWVudDwvY29kZT4gbWV0aG9kIHJlY29nbml6ZXMgZWxlbWVudHMKLSAgICogZnJvbSB0aGUgcGxhaW4gY2F0YWxvZyBmb3JtYXQgYW5kIGluc3RhbnRpYXRlcyBDYXRhbG9nRW50cnkKLSAgICogb2JqZWN0cyBmb3IgdGhlbS4KLSAgICoKLSAgICogQHBhcmFtIG5hbWVzcGFjZVVSSSBUaGUgbmFtZXNwYWNlIG5hbWUgb2YgdGhlIGVsZW1lbnQuCi0gICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGxvY2FsIG5hbWUgb2YgdGhlIGVsZW1lbnQuCi0gICAqIEBwYXJhbSBxTmFtZSBUaGUgUU5hbWUgb2YgdGhlIGVsZW1lbnQuCi0gICAqIEBwYXJhbSBhdHRzIFRoZSBsaXN0IG9mIGF0dHJpYnV0ZXMgb24gdGhlIGVsZW1lbnQuCi0gICAqCi0gICAqIEBzZWUgQ2F0YWxvZ0VudHJ5Ci0gICAqLwotICBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQgKFN0cmluZyBuYW1lc3BhY2VVUkksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGxvY2FsTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcU5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgQXR0cmlidXRlcyBhdHRzKQotICAgIHRocm93cyBTQVhFeGNlcHRpb24gewotCi0gICAgaW50IGVudHJ5VHlwZSA9IC0xOwotICAgIFZlY3RvciBlbnRyeUFyZ3MgPSBuZXcgVmVjdG9yKCk7Ci0KLSAgICBuYW1lc3BhY2VTdGFjay5wdXNoKG5hbWVzcGFjZVVSSSk7Ci0KLSAgICBib29sZWFuIGluRXh0ZW5zaW9uID0gaW5FeHRlbnNpb25OYW1lc3BhY2UoKTsKLQotICAgIGlmIChuYW1lc3BhY2VVUkkgIT0gbnVsbCAmJiBuYW1lc3BhY2VOYW1lLmVxdWFscyhuYW1lc3BhY2VVUkkpCi0gICAgICAgICYmICFpbkV4dGVuc2lvbikgewotICAgICAgLy8gVGhpcyBpcyBhbiBYTUwgQ2F0YWxvZyBlbnRyeQotCi0gICAgICBpZiAoYXR0cy5nZXRWYWx1ZSgieG1sOmJhc2UiKSAhPSBudWxsKSB7Ci0gICAgICAgIFN0cmluZyBiYXNlVVJJID0gYXR0cy5nZXRWYWx1ZSgieG1sOmJhc2UiKTsKLSAgICAgICAgZW50cnlUeXBlID0gQ2F0YWxvZy5CQVNFOwotICAgICAgICBlbnRyeUFyZ3MuYWRkKGJhc2VVUkkpOwotICAgICAgICBiYXNlVVJJU3RhY2sucHVzaChiYXNlVVJJKTsKLQotICAgICAgICBkZWJ1Zy5tZXNzYWdlKDQsICJ4bWw6YmFzZSIsIGJhc2VVUkkpOwotCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgQ2F0YWxvZ0VudHJ5IGNlID0gbmV3IENhdGFsb2dFbnRyeShlbnRyeVR5cGUsIGVudHJ5QXJncyk7Ci0gICAgICAgICAgY2F0YWxvZy5hZGRFbnRyeShjZSk7Ci0gICAgICAgIH0gY2F0Y2ggKENhdGFsb2dFeGNlcHRpb24gY2V4KSB7Ci0gICAgICAgICAgaWYgKGNleC5nZXRFeGNlcHRpb25UeXBlKCkgPT0gQ2F0YWxvZ0V4Y2VwdGlvbi5JTlZBTElEX0VOVFJZX1RZUEUpIHsKLSAgICAgICAgICAgIGRlYnVnLm1lc3NhZ2UoMSwgIkludmFsaWQgY2F0YWxvZyBlbnRyeSB0eXBlIiwgbG9jYWxOYW1lKTsKLSAgICAgICAgICB9IGVsc2UgaWYgKGNleC5nZXRFeGNlcHRpb25UeXBlKCkgPT0gQ2F0YWxvZ0V4Y2VwdGlvbi5JTlZBTElEX0VOVFJZKSB7Ci0gICAgICAgICAgICBkZWJ1Zy5tZXNzYWdlKDEsICJJbnZhbGlkIGNhdGFsb2cgZW50cnkgKGJhc2UpIiwgbG9jYWxOYW1lKTsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBlbnRyeVR5cGUgPSAtMTsKLSAgICAgICAgZW50cnlBcmdzID0gbmV3IFZlY3RvcigpOwotCi0gICAgICB9IGVsc2UgewotICAgICAgICBiYXNlVVJJU3RhY2sucHVzaChiYXNlVVJJU3RhY2sucGVlaygpKTsKLSAgICAgIH0KLQotICAgICAgaWYgKChsb2NhbE5hbWUuZXF1YWxzKCJjYXRhbG9nIikgfHwgbG9jYWxOYW1lLmVxdWFscygiZ3JvdXAiKSkKLSAgICAgICAgICAmJiBhdHRzLmdldFZhbHVlKCJwcmVmZXIiKSAhPSBudWxsKSB7Ci0gICAgICAgIFN0cmluZyBvdmVycmlkZSA9IGF0dHMuZ2V0VmFsdWUoInByZWZlciIpOwotCi0gICAgICAgIGlmIChvdmVycmlkZS5lcXVhbHMoInB1YmxpYyIpKSB7Ci0gICAgICAgICAgb3ZlcnJpZGUgPSAieWVzIjsKLSAgICAgICAgfSBlbHNlIGlmIChvdmVycmlkZS5lcXVhbHMoInN5c3RlbSIpKSB7Ci0gICAgICAgICAgb3ZlcnJpZGUgPSAibm8iOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgIGRlYnVnLm1lc3NhZ2UoMSwKLSAgICAgICAgICAgICAgICAgICAgICAgICJJbnZhbGlkIHByZWZlcjogbXVzdCBiZSAnc3lzdGVtJyBvciAncHVibGljJyIsCi0gICAgICAgICAgICAgICAgICAgICAgICBsb2NhbE5hbWUpOwotICAgICAgICAgIG92ZXJyaWRlID0gY2F0YWxvZy5nZXREZWZhdWx0T3ZlcnJpZGUoKTsKLSAgICAgICAgfQotCi0gICAgICAgIGVudHJ5VHlwZSA9IENhdGFsb2cuT1ZFUlJJREU7Ci0gICAgICAgIGVudHJ5QXJncy5hZGQob3ZlcnJpZGUpOwotICAgICAgICBvdmVycmlkZVN0YWNrLnB1c2gob3ZlcnJpZGUpOwotCi0gICAgICAgIGRlYnVnLm1lc3NhZ2UoNCwgIm92ZXJyaWRlIiwgb3ZlcnJpZGUpOwotCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgQ2F0YWxvZ0VudHJ5IGNlID0gbmV3IENhdGFsb2dFbnRyeShlbnRyeVR5cGUsIGVudHJ5QXJncyk7Ci0gICAgICAgICAgY2F0YWxvZy5hZGRFbnRyeShjZSk7Ci0gICAgICAgIH0gY2F0Y2ggKENhdGFsb2dFeGNlcHRpb24gY2V4KSB7Ci0gICAgICAgICAgaWYgKGNleC5nZXRFeGNlcHRpb25UeXBlKCkgPT0gQ2F0YWxvZ0V4Y2VwdGlvbi5JTlZBTElEX0VOVFJZX1RZUEUpIHsKLSAgICAgICAgICAgIGRlYnVnLm1lc3NhZ2UoMSwgIkludmFsaWQgY2F0YWxvZyBlbnRyeSB0eXBlIiwgbG9jYWxOYW1lKTsKLSAgICAgICAgICB9IGVsc2UgaWYgKGNleC5nZXRFeGNlcHRpb25UeXBlKCkgPT0gQ2F0YWxvZ0V4Y2VwdGlvbi5JTlZBTElEX0VOVFJZKSB7Ci0gICAgICAgICAgICBkZWJ1Zy5tZXNzYWdlKDEsICJJbnZhbGlkIGNhdGFsb2cgZW50cnkgKG92ZXJyaWRlKSIsIGxvY2FsTmFtZSk7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgZW50cnlUeXBlID0gLTE7Ci0gICAgICAgIGVudHJ5QXJncyA9IG5ldyBWZWN0b3IoKTsKLQotICAgICAgfSBlbHNlIHsKLSAgICAgICAgb3ZlcnJpZGVTdGFjay5wdXNoKG92ZXJyaWRlU3RhY2sucGVlaygpKTsKLSAgICAgIH0KLQotICAgICAgaWYgKGxvY2FsTmFtZS5lcXVhbHMoImRlbGVnYXRlUHVibGljIikpIHsKLSAgICAgICAgaWYgKGNoZWNrQXR0cmlidXRlcyhhdHRzLCAicHVibGljSWRTdGFydFN0cmluZyIsICJjYXRhbG9nIikpIHsKLSAgICAgICAgICBlbnRyeVR5cGUgPSBDYXRhbG9nLkRFTEVHQVRFX1BVQkxJQzsKLSAgICAgICAgICBlbnRyeUFyZ3MuYWRkKGF0dHMuZ2V0VmFsdWUoInB1YmxpY0lkU3RhcnRTdHJpbmciKSk7Ci0gICAgICAgICAgZW50cnlBcmdzLmFkZChhdHRzLmdldFZhbHVlKCJjYXRhbG9nIikpOwotCi0gICAgICAgICAgZGVidWcubWVzc2FnZSg0LCAiZGVsZWdhdGVQdWJsaWMiLAotICAgICAgICAgICAgICAgICAgICAgICAgUHVibGljSWQubm9ybWFsaXplKGF0dHMuZ2V0VmFsdWUoInB1YmxpY0lkU3RhcnRTdHJpbmciKSksCi0gICAgICAgICAgICAgICAgICAgICAgICBhdHRzLmdldFZhbHVlKCJjYXRhbG9nIikpOwotICAgICAgICB9Ci0gICAgICB9IGVsc2UgaWYgKGxvY2FsTmFtZS5lcXVhbHMoImRlbGVnYXRlU3lzdGVtIikpIHsKLSAgICAgICAgaWYgKGNoZWNrQXR0cmlidXRlcyhhdHRzLCAic3lzdGVtSWRTdGFydFN0cmluZyIsICJjYXRhbG9nIikpIHsKLSAgICAgICAgICBlbnRyeVR5cGUgPSBDYXRhbG9nLkRFTEVHQVRFX1NZU1RFTTsKLSAgICAgICAgICBlbnRyeUFyZ3MuYWRkKGF0dHMuZ2V0VmFsdWUoInN5c3RlbUlkU3RhcnRTdHJpbmciKSk7Ci0gICAgICAgICAgZW50cnlBcmdzLmFkZChhdHRzLmdldFZhbHVlKCJjYXRhbG9nIikpOwotCi0gICAgICAgICAgZGVidWcubWVzc2FnZSg0LCAiZGVsZWdhdGVTeXN0ZW0iLAotICAgICAgICAgICAgICAgICAgICAgICAgYXR0cy5nZXRWYWx1ZSgic3lzdGVtSWRTdGFydFN0cmluZyIpLAotICAgICAgICAgICAgICAgICAgICAgICAgYXR0cy5nZXRWYWx1ZSgiY2F0YWxvZyIpKTsKLSAgICAgICAgfQotICAgICAgfSBlbHNlIGlmIChsb2NhbE5hbWUuZXF1YWxzKCJkZWxlZ2F0ZVVSSSIpKSB7Ci0gICAgICAgIGlmIChjaGVja0F0dHJpYnV0ZXMoYXR0cywgInVyaVN0YXJ0U3RyaW5nIiwgImNhdGFsb2ciKSkgewotICAgICAgICAgIGVudHJ5VHlwZSA9IENhdGFsb2cuREVMRUdBVEVfVVJJOwotICAgICAgICAgIGVudHJ5QXJncy5hZGQoYXR0cy5nZXRWYWx1ZSgidXJpU3RhcnRTdHJpbmciKSk7Ci0gICAgICAgICAgZW50cnlBcmdzLmFkZChhdHRzLmdldFZhbHVlKCJjYXRhbG9nIikpOwotCi0gICAgICAgICAgZGVidWcubWVzc2FnZSg0LCAiZGVsZWdhdGVVUkkiLAotICAgICAgICAgICAgICAgICAgICAgICAgYXR0cy5nZXRWYWx1ZSgidXJpU3RhcnRTdHJpbmciKSwKLSAgICAgICAgICAgICAgICAgICAgICAgIGF0dHMuZ2V0VmFsdWUoImNhdGFsb2ciKSk7Ci0gICAgICAgIH0KLSAgICAgIH0gZWxzZSBpZiAobG9jYWxOYW1lLmVxdWFscygicmV3cml0ZVN5c3RlbSIpKSB7Ci0gICAgICAgIGlmIChjaGVja0F0dHJpYnV0ZXMoYXR0cywgInN5c3RlbUlkU3RhcnRTdHJpbmciLCAicmV3cml0ZVByZWZpeCIpKSB7Ci0gICAgICAgICAgZW50cnlUeXBlID0gQ2F0YWxvZy5SRVdSSVRFX1NZU1RFTTsKLSAgICAgICAgICBlbnRyeUFyZ3MuYWRkKGF0dHMuZ2V0VmFsdWUoInN5c3RlbUlkU3RhcnRTdHJpbmciKSk7Ci0gICAgICAgICAgZW50cnlBcmdzLmFkZChhdHRzLmdldFZhbHVlKCJyZXdyaXRlUHJlZml4IikpOwotCi0gICAgICAgICAgZGVidWcubWVzc2FnZSg0LCAicmV3cml0ZVN5c3RlbSIsCi0gICAgICAgICAgICAgICAgICAgICAgICBhdHRzLmdldFZhbHVlKCJzeXN0ZW1JZFN0YXJ0U3RyaW5nIiksCi0gICAgICAgICAgICAgICAgICAgICAgICBhdHRzLmdldFZhbHVlKCJyZXdyaXRlUHJlZml4IikpOwotICAgICAgICB9Ci0gICAgICB9IGVsc2UgaWYgKGxvY2FsTmFtZS5lcXVhbHMoInN5c3RlbVN1ZmZpeCIpKSB7Ci0gICAgICAgIGlmIChjaGVja0F0dHJpYnV0ZXMoYXR0cywgInN5c3RlbUlkU3VmZml4IiwgInVyaSIpKSB7Ci0gICAgICAgICAgZW50cnlUeXBlID0gQ2F0YWxvZy5TWVNURU1fU1VGRklYOwotICAgICAgICAgIGVudHJ5QXJncy5hZGQoYXR0cy5nZXRWYWx1ZSgic3lzdGVtSWRTdWZmaXgiKSk7Ci0gICAgICAgICAgZW50cnlBcmdzLmFkZChhdHRzLmdldFZhbHVlKCJ1cmkiKSk7Ci0KLSAgICAgICAgICBkZWJ1Zy5tZXNzYWdlKDQsICJzeXN0ZW1TdWZmaXgiLAotICAgICAgICAgICAgICAgICAgICAgICAgYXR0cy5nZXRWYWx1ZSgic3lzdGVtSWRTdWZmaXgiKSwKLSAgICAgICAgICAgICAgICAgICAgICAgIGF0dHMuZ2V0VmFsdWUoInVyaSIpKTsKLSAgICAgICAgfQotICAgICAgfSBlbHNlIGlmIChsb2NhbE5hbWUuZXF1YWxzKCJyZXdyaXRlVVJJIikpIHsKLSAgICAgICAgaWYgKGNoZWNrQXR0cmlidXRlcyhhdHRzLCAidXJpU3RhcnRTdHJpbmciLCAicmV3cml0ZVByZWZpeCIpKSB7Ci0gICAgICAgICAgZW50cnlUeXBlID0gQ2F0YWxvZy5SRVdSSVRFX1VSSTsKLSAgICAgICAgICBlbnRyeUFyZ3MuYWRkKGF0dHMuZ2V0VmFsdWUoInVyaVN0YXJ0U3RyaW5nIikpOwotICAgICAgICAgIGVudHJ5QXJncy5hZGQoYXR0cy5nZXRWYWx1ZSgicmV3cml0ZVByZWZpeCIpKTsKLQotICAgICAgICAgIGRlYnVnLm1lc3NhZ2UoNCwgInJld3JpdGVVUkkiLAotICAgICAgICAgICAgICAgICAgICAgICAgYXR0cy5nZXRWYWx1ZSgidXJpU3RhcnRTdHJpbmciKSwKLSAgICAgICAgICAgICAgICAgICAgICAgIGF0dHMuZ2V0VmFsdWUoInJld3JpdGVQcmVmaXgiKSk7Ci0gICAgICAgIH0KLSAgICAgIH0gZWxzZSBpZiAobG9jYWxOYW1lLmVxdWFscygidXJpU3VmZml4IikpIHsKLSAgICAgICAgaWYgKGNoZWNrQXR0cmlidXRlcyhhdHRzLCAidXJpU3VmZml4IiwgInVyaSIpKSB7Ci0gICAgICAgICAgZW50cnlUeXBlID0gQ2F0YWxvZy5VUklfU1VGRklYOwotICAgICAgICAgIGVudHJ5QXJncy5hZGQoYXR0cy5nZXRWYWx1ZSgidXJpU3VmZml4IikpOwotICAgICAgICAgIGVudHJ5QXJncy5hZGQoYXR0cy5nZXRWYWx1ZSgidXJpIikpOwotCi0gICAgICAgICAgZGVidWcubWVzc2FnZSg0LCAidXJpU3VmZml4IiwKLSAgICAgICAgICAgICAgICAgICAgICAgIGF0dHMuZ2V0VmFsdWUoInVyaVN1ZmZpeCIpLAotICAgICAgICAgICAgICAgICAgICAgICAgYXR0cy5nZXRWYWx1ZSgidXJpIikpOwotICAgICAgICB9Ci0gICAgICB9IGVsc2UgaWYgKGxvY2FsTmFtZS5lcXVhbHMoIm5leHRDYXRhbG9nIikpIHsKLSAgICAgICAgaWYgKGNoZWNrQXR0cmlidXRlcyhhdHRzLCAiY2F0YWxvZyIpKSB7Ci0gICAgICAgICAgZW50cnlUeXBlID0gQ2F0YWxvZy5DQVRBTE9HOwotICAgICAgICAgIGVudHJ5QXJncy5hZGQoYXR0cy5nZXRWYWx1ZSgiY2F0YWxvZyIpKTsKLQotICAgICAgICAgIGRlYnVnLm1lc3NhZ2UoNCwgIm5leHRDYXRhbG9nIiwgYXR0cy5nZXRWYWx1ZSgiY2F0YWxvZyIpKTsKLSAgICAgICAgfQotICAgICAgfSBlbHNlIGlmIChsb2NhbE5hbWUuZXF1YWxzKCJwdWJsaWMiKSkgewotICAgICAgICBpZiAoY2hlY2tBdHRyaWJ1dGVzKGF0dHMsICJwdWJsaWNJZCIsICJ1cmkiKSkgewotICAgICAgICAgIGVudHJ5VHlwZSA9IENhdGFsb2cuUFVCTElDOwotICAgICAgICAgIGVudHJ5QXJncy5hZGQoYXR0cy5nZXRWYWx1ZSgicHVibGljSWQiKSk7Ci0gICAgICAgICAgZW50cnlBcmdzLmFkZChhdHRzLmdldFZhbHVlKCJ1cmkiKSk7Ci0KLSAgICAgICAgICBkZWJ1Zy5tZXNzYWdlKDQsICJwdWJsaWMiLAotICAgICAgICAgICAgICAgICAgICAgICAgUHVibGljSWQubm9ybWFsaXplKGF0dHMuZ2V0VmFsdWUoInB1YmxpY0lkIikpLAotICAgICAgICAgICAgICAgICAgICAgICAgYXR0cy5nZXRWYWx1ZSgidXJpIikpOwotICAgICAgICB9Ci0gICAgICB9IGVsc2UgaWYgKGxvY2FsTmFtZS5lcXVhbHMoInN5c3RlbSIpKSB7Ci0gICAgICAgIGlmIChjaGVja0F0dHJpYnV0ZXMoYXR0cywgInN5c3RlbUlkIiwgInVyaSIpKSB7Ci0gICAgICAgICAgZW50cnlUeXBlID0gQ2F0YWxvZy5TWVNURU07Ci0gICAgICAgICAgZW50cnlBcmdzLmFkZChhdHRzLmdldFZhbHVlKCJzeXN0ZW1JZCIpKTsKLSAgICAgICAgICBlbnRyeUFyZ3MuYWRkKGF0dHMuZ2V0VmFsdWUoInVyaSIpKTsKLQotICAgICAgICAgIGRlYnVnLm1lc3NhZ2UoNCwgInN5c3RlbSIsCi0gICAgICAgICAgICAgICAgICAgICAgICBhdHRzLmdldFZhbHVlKCJzeXN0ZW1JZCIpLAotICAgICAgICAgICAgICAgICAgICAgICAgYXR0cy5nZXRWYWx1ZSgidXJpIikpOwotICAgICAgICB9Ci0gICAgICB9IGVsc2UgaWYgKGxvY2FsTmFtZS5lcXVhbHMoInVyaSIpKSB7Ci0gICAgICAgIGlmIChjaGVja0F0dHJpYnV0ZXMoYXR0cywgIm5hbWUiLCAidXJpIikpIHsKLSAgICAgICAgICBlbnRyeVR5cGUgPSBDYXRhbG9nLlVSSTsKLSAgICAgICAgICBlbnRyeUFyZ3MuYWRkKGF0dHMuZ2V0VmFsdWUoIm5hbWUiKSk7Ci0gICAgICAgICAgZW50cnlBcmdzLmFkZChhdHRzLmdldFZhbHVlKCJ1cmkiKSk7Ci0KLSAgICAgICAgICBkZWJ1Zy5tZXNzYWdlKDQsICJ1cmkiLAotICAgICAgICAgICAgICAgICAgICAgICAgYXR0cy5nZXRWYWx1ZSgibmFtZSIpLAotICAgICAgICAgICAgICAgICAgICAgICAgYXR0cy5nZXRWYWx1ZSgidXJpIikpOwotICAgICAgICB9Ci0gICAgICB9IGVsc2UgaWYgKGxvY2FsTmFtZS5lcXVhbHMoImNhdGFsb2ciKSkgewotICAgICAgICAvLyBub3AsIHN0YXJ0IG9mIGNhdGFsb2cKLSAgICAgIH0gZWxzZSBpZiAobG9jYWxOYW1lLmVxdWFscygiZ3JvdXAiKSkgewotICAgICAgICAvLyBub3AsIGEgZ3JvdXAKLSAgICAgIH0gZWxzZSB7Ci0gICAgICAgIC8vIFRoaXMgaXMgZXF1aXZhbGVudCB0byBhbiBpbnZhbGlkIGNhdGFsb2cgZW50cnkgdHlwZQotICAgICAgICBkZWJ1Zy5tZXNzYWdlKDEsICJJbnZhbGlkIGNhdGFsb2cgZW50cnkgdHlwZSIsIGxvY2FsTmFtZSk7Ci0gICAgICB9Ci0KLSAgICAgIGlmIChlbnRyeVR5cGUgPj0gMCkgewotICAgICAgICB0cnkgewotICAgICAgICAgIENhdGFsb2dFbnRyeSBjZSA9IG5ldyBDYXRhbG9nRW50cnkoZW50cnlUeXBlLCBlbnRyeUFyZ3MpOwotICAgICAgICAgIGNhdGFsb2cuYWRkRW50cnkoY2UpOwotICAgICAgICB9IGNhdGNoIChDYXRhbG9nRXhjZXB0aW9uIGNleCkgewotICAgICAgICAgIGlmIChjZXguZ2V0RXhjZXB0aW9uVHlwZSgpID09IENhdGFsb2dFeGNlcHRpb24uSU5WQUxJRF9FTlRSWV9UWVBFKSB7Ci0gICAgICAgICAgICBkZWJ1Zy5tZXNzYWdlKDEsICJJbnZhbGlkIGNhdGFsb2cgZW50cnkgdHlwZSIsIGxvY2FsTmFtZSk7Ci0gICAgICAgICAgfSBlbHNlIGlmIChjZXguZ2V0RXhjZXB0aW9uVHlwZSgpID09IENhdGFsb2dFeGNlcHRpb24uSU5WQUxJRF9FTlRSWSkgewotICAgICAgICAgICAgZGVidWcubWVzc2FnZSgxLCAiSW52YWxpZCBjYXRhbG9nIGVudHJ5IiwgbG9jYWxOYW1lKTsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICB9Ci0KLSAgICBpZiAobmFtZXNwYWNlVVJJICE9IG51bGwgJiYgdHI5NDAxTmFtZXNwYWNlTmFtZS5lcXVhbHMobmFtZXNwYWNlVVJJKQotICAgICAgICAmJiAhaW5FeHRlbnNpb24pIHsKLSAgICAgIC8vIFRoaXMgaXMgYSBUUjk0MDEgQ2F0YWxvZyBlbnRyeQotCi0gICAgICBpZiAoYXR0cy5nZXRWYWx1ZSgieG1sOmJhc2UiKSAhPSBudWxsKSB7Ci0gICAgICAgIFN0cmluZyBiYXNlVVJJID0gYXR0cy5nZXRWYWx1ZSgieG1sOmJhc2UiKTsKLSAgICAgICAgZW50cnlUeXBlID0gQ2F0YWxvZy5CQVNFOwotICAgICAgICBlbnRyeUFyZ3MuYWRkKGJhc2VVUkkpOwotICAgICAgICBiYXNlVVJJU3RhY2sucHVzaChiYXNlVVJJKTsKLQotICAgICAgICBkZWJ1Zy5tZXNzYWdlKDQsICJ4bWw6YmFzZSIsIGJhc2VVUkkpOwotCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgQ2F0YWxvZ0VudHJ5IGNlID0gbmV3IENhdGFsb2dFbnRyeShlbnRyeVR5cGUsIGVudHJ5QXJncyk7Ci0gICAgICAgICAgY2F0YWxvZy5hZGRFbnRyeShjZSk7Ci0gICAgICAgIH0gY2F0Y2ggKENhdGFsb2dFeGNlcHRpb24gY2V4KSB7Ci0gICAgICAgICAgaWYgKGNleC5nZXRFeGNlcHRpb25UeXBlKCkgPT0gQ2F0YWxvZ0V4Y2VwdGlvbi5JTlZBTElEX0VOVFJZX1RZUEUpIHsKLSAgICAgICAgICAgIGRlYnVnLm1lc3NhZ2UoMSwgIkludmFsaWQgY2F0YWxvZyBlbnRyeSB0eXBlIiwgbG9jYWxOYW1lKTsKLSAgICAgICAgICB9IGVsc2UgaWYgKGNleC5nZXRFeGNlcHRpb25UeXBlKCkgPT0gQ2F0YWxvZ0V4Y2VwdGlvbi5JTlZBTElEX0VOVFJZKSB7Ci0gICAgICAgICAgICBkZWJ1Zy5tZXNzYWdlKDEsICJJbnZhbGlkIGNhdGFsb2cgZW50cnkgKGJhc2UpIiwgbG9jYWxOYW1lKTsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBlbnRyeVR5cGUgPSAtMTsKLSAgICAgICAgZW50cnlBcmdzID0gbmV3IFZlY3RvcigpOwotCi0gICAgICB9IGVsc2UgewotICAgICAgICBiYXNlVVJJU3RhY2sucHVzaChiYXNlVVJJU3RhY2sucGVlaygpKTsKLSAgICAgIH0KLQotICAgICAgaWYgKGxvY2FsTmFtZS5lcXVhbHMoImRvY3R5cGUiKSkgewotICAgICAgICBlbnRyeVR5cGUgPSBjYXRhbG9nLkRPQ1RZUEU7Ci0gICAgICAgIGVudHJ5QXJncy5hZGQoYXR0cy5nZXRWYWx1ZSgibmFtZSIpKTsKLSAgICAgICAgZW50cnlBcmdzLmFkZChhdHRzLmdldFZhbHVlKCJ1cmkiKSk7Ci0gICAgICB9IGVsc2UgaWYgKGxvY2FsTmFtZS5lcXVhbHMoImRvY3VtZW50IikpIHsKLSAgICAgICAgZW50cnlUeXBlID0gY2F0YWxvZy5ET0NVTUVOVDsKLSAgICAgICAgZW50cnlBcmdzLmFkZChhdHRzLmdldFZhbHVlKCJ1cmkiKSk7Ci0gICAgICB9IGVsc2UgaWYgKGxvY2FsTmFtZS5lcXVhbHMoImR0ZGRlY2wiKSkgewotICAgICAgICBlbnRyeVR5cGUgPSBjYXRhbG9nLkRURERFQ0w7Ci0gICAgICAgIGVudHJ5QXJncy5hZGQoYXR0cy5nZXRWYWx1ZSgicHVibGljSWQiKSk7Ci0gICAgICAgIGVudHJ5QXJncy5hZGQoYXR0cy5nZXRWYWx1ZSgidXJpIikpOwotICAgICAgfSBlbHNlIGlmIChsb2NhbE5hbWUuZXF1YWxzKCJlbnRpdHkiKSkgewotICAgICAgICBlbnRyeVR5cGUgPSBDYXRhbG9nLkVOVElUWTsKLSAgICAgICAgZW50cnlBcmdzLmFkZChhdHRzLmdldFZhbHVlKCJuYW1lIikpOwotICAgICAgICBlbnRyeUFyZ3MuYWRkKGF0dHMuZ2V0VmFsdWUoInVyaSIpKTsKLSAgICAgIH0gZWxzZSBpZiAobG9jYWxOYW1lLmVxdWFscygibGlua3R5cGUiKSkgewotICAgICAgICBlbnRyeVR5cGUgPSBDYXRhbG9nLkxJTktUWVBFOwotICAgICAgICBlbnRyeUFyZ3MuYWRkKGF0dHMuZ2V0VmFsdWUoIm5hbWUiKSk7Ci0gICAgICAgIGVudHJ5QXJncy5hZGQoYXR0cy5nZXRWYWx1ZSgidXJpIikpOwotICAgICAgfSBlbHNlIGlmIChsb2NhbE5hbWUuZXF1YWxzKCJub3RhdGlvbiIpKSB7Ci0gICAgICAgIGVudHJ5VHlwZSA9IENhdGFsb2cuTk9UQVRJT047Ci0gICAgICAgIGVudHJ5QXJncy5hZGQoYXR0cy5nZXRWYWx1ZSgibmFtZSIpKTsKLSAgICAgICAgZW50cnlBcmdzLmFkZChhdHRzLmdldFZhbHVlKCJ1cmkiKSk7Ci0gICAgICB9IGVsc2UgaWYgKGxvY2FsTmFtZS5lcXVhbHMoInNnbWxkZWNsIikpIHsKLSAgICAgICAgZW50cnlUeXBlID0gQ2F0YWxvZy5TR01MREVDTDsKLSAgICAgICAgZW50cnlBcmdzLmFkZChhdHRzLmdldFZhbHVlKCJ1cmkiKSk7Ci0gICAgICB9IGVsc2UgewotICAgICAgICAvLyBUaGlzIGlzIGVxdWl2YWxlbnQgdG8gYW4gaW52YWxpZCBjYXRhbG9nIGVudHJ5IHR5cGUKLSAgICAgICAgZGVidWcubWVzc2FnZSgxLCAiSW52YWxpZCBjYXRhbG9nIGVudHJ5IHR5cGUiLCBsb2NhbE5hbWUpOwotICAgICAgfQotCi0gICAgICBpZiAoZW50cnlUeXBlID49IDApIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICBDYXRhbG9nRW50cnkgY2UgPSBuZXcgQ2F0YWxvZ0VudHJ5KGVudHJ5VHlwZSwgZW50cnlBcmdzKTsKLSAgICAgICAgICBjYXRhbG9nLmFkZEVudHJ5KGNlKTsKLSAgICAgICAgfSBjYXRjaCAoQ2F0YWxvZ0V4Y2VwdGlvbiBjZXgpIHsKLSAgICAgICAgICBpZiAoY2V4LmdldEV4Y2VwdGlvblR5cGUoKSA9PSBDYXRhbG9nRXhjZXB0aW9uLklOVkFMSURfRU5UUllfVFlQRSkgewotICAgICAgICAgICAgZGVidWcubWVzc2FnZSgxLCAiSW52YWxpZCBjYXRhbG9nIGVudHJ5IHR5cGUiLCBsb2NhbE5hbWUpOwotICAgICAgICAgIH0gZWxzZSBpZiAoY2V4LmdldEV4Y2VwdGlvblR5cGUoKSA9PSBDYXRhbG9nRXhjZXB0aW9uLklOVkFMSURfRU5UUlkpIHsKLSAgICAgICAgICAgIGRlYnVnLm1lc3NhZ2UoMSwgIkludmFsaWQgY2F0YWxvZyBlbnRyeSIsIGxvY2FsTmFtZSk7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotICB9Ci0KLSAgcHVibGljIGJvb2xlYW4gY2hlY2tBdHRyaWJ1dGVzIChBdHRyaWJ1dGVzIGF0dHMsIFN0cmluZyBhdHROYW1lKSB7Ci0gICAgaWYgKGF0dHMuZ2V0VmFsdWUoYXR0TmFtZSkgPT0gbnVsbCkgewotICAgICAgZGVidWcubWVzc2FnZSgxLCAiRXJyb3I6IHJlcXVpcmVkIGF0dHJpYnV0ZSAiICsgYXR0TmFtZSArICIgbWlzc2luZy4iKTsKLSAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9IGVsc2UgewotICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotICB9Ci0KLSAgcHVibGljIGJvb2xlYW4gY2hlY2tBdHRyaWJ1dGVzIChBdHRyaWJ1dGVzIGF0dHMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGF0dE5hbWUxLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBhdHROYW1lMikgewotICAgIHJldHVybiBjaGVja0F0dHJpYnV0ZXMoYXR0cywgYXR0TmFtZTEpCi0gICAgICAmJiBjaGVja0F0dHJpYnV0ZXMoYXR0cywgYXR0TmFtZTIpOwotICB9Ci0KLSAgLyoqIFRoZSBTQVggPGNvZGU+ZW5kRWxlbWVudDwvY29kZT4gbWV0aG9kIGRvZXMgbm90aGluZy4gKi8KLSAgcHVibGljIHZvaWQgZW5kRWxlbWVudCAoU3RyaW5nIG5hbWVzcGFjZVVSSSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGxvY2FsTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHFOYW1lKQotICAgIHRocm93cyBTQVhFeGNlcHRpb24gewotCi0gICAgaW50IGVudHJ5VHlwZSA9IC0xOwotICAgIFZlY3RvciBlbnRyeUFyZ3MgPSBuZXcgVmVjdG9yKCk7Ci0KLSAgICBib29sZWFuIGluRXh0ZW5zaW9uID0gaW5FeHRlbnNpb25OYW1lc3BhY2UoKTsKLQotICAgIGlmIChuYW1lc3BhY2VVUkkgIT0gbnVsbAotICAgICAgICAmJiAhaW5FeHRlbnNpb24KLSAgICAgICAgJiYgKG5hbWVzcGFjZU5hbWUuZXF1YWxzKG5hbWVzcGFjZVVSSSkKLSAgICAgICAgICAgIHx8IHRyOTQwMU5hbWVzcGFjZU5hbWUuZXF1YWxzKG5hbWVzcGFjZVVSSSkpKSB7Ci0KLSAgICAgIFN0cmluZyBwb3BVUkkgPSAoU3RyaW5nKSBiYXNlVVJJU3RhY2sucG9wKCk7Ci0gICAgICBTdHJpbmcgYmFzZVVSSSA9IChTdHJpbmcpIGJhc2VVUklTdGFjay5wZWVrKCk7Ci0KLSAgICAgIGlmICghYmFzZVVSSS5lcXVhbHMocG9wVVJJKSkgewotICAgICAgICBlbnRyeVR5cGUgPSBjYXRhbG9nLkJBU0U7Ci0gICAgICAgIGVudHJ5QXJncy5hZGQoYmFzZVVSSSk7Ci0KLSAgICAgICAgZGVidWcubWVzc2FnZSg0LCAiKHJlc2V0KSB4bWw6YmFzZSIsIGJhc2VVUkkpOwotCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgQ2F0YWxvZ0VudHJ5IGNlID0gbmV3IENhdGFsb2dFbnRyeShlbnRyeVR5cGUsIGVudHJ5QXJncyk7Ci0gICAgICAgICAgY2F0YWxvZy5hZGRFbnRyeShjZSk7Ci0gICAgICAgIH0gY2F0Y2ggKENhdGFsb2dFeGNlcHRpb24gY2V4KSB7Ci0gICAgICAgICAgaWYgKGNleC5nZXRFeGNlcHRpb25UeXBlKCkgPT0gQ2F0YWxvZ0V4Y2VwdGlvbi5JTlZBTElEX0VOVFJZX1RZUEUpIHsKLSAgICAgICAgICAgIGRlYnVnLm1lc3NhZ2UoMSwgIkludmFsaWQgY2F0YWxvZyBlbnRyeSB0eXBlIiwgbG9jYWxOYW1lKTsKLSAgICAgICAgICB9IGVsc2UgaWYgKGNleC5nZXRFeGNlcHRpb25UeXBlKCkgPT0gQ2F0YWxvZ0V4Y2VwdGlvbi5JTlZBTElEX0VOVFJZKSB7Ci0gICAgICAgICAgICBkZWJ1Zy5tZXNzYWdlKDEsICJJbnZhbGlkIGNhdGFsb2cgZW50cnkgKHJiYXNlKSIsIGxvY2FsTmFtZSk7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotCi0gICAgaWYgKG5hbWVzcGFjZVVSSSAhPSBudWxsICYmIG5hbWVzcGFjZU5hbWUuZXF1YWxzKG5hbWVzcGFjZVVSSSkKLSAgICAgICAgJiYgIWluRXh0ZW5zaW9uKSB7Ci0gICAgICBpZiAobG9jYWxOYW1lLmVxdWFscygiY2F0YWxvZyIpIHx8IGxvY2FsTmFtZS5lcXVhbHMoImdyb3VwIikpIHsKLSAgICAgICAgU3RyaW5nIHBvcE92ZXJyaWRlID0gKFN0cmluZykgb3ZlcnJpZGVTdGFjay5wb3AoKTsKLSAgICAgICAgU3RyaW5nIG92ZXJyaWRlID0gKFN0cmluZykgb3ZlcnJpZGVTdGFjay5wZWVrKCk7Ci0KLSAgICAgICAgaWYgKCFvdmVycmlkZS5lcXVhbHMocG9wT3ZlcnJpZGUpKSB7Ci0gICAgICAgICAgZW50cnlUeXBlID0gY2F0YWxvZy5PVkVSUklERTsKLSAgICAgICAgICBlbnRyeUFyZ3MuYWRkKG92ZXJyaWRlKTsKLSAgICAgICAgICBvdmVycmlkZVN0YWNrLnB1c2gob3ZlcnJpZGUpOwotCi0gICAgICAgICAgZGVidWcubWVzc2FnZSg0LCAiKHJlc2V0KSBvdmVycmlkZSIsIG92ZXJyaWRlKTsKLQotICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBDYXRhbG9nRW50cnkgY2UgPSBuZXcgQ2F0YWxvZ0VudHJ5KGVudHJ5VHlwZSwgZW50cnlBcmdzKTsKLSAgICAgICAgICAgIGNhdGFsb2cuYWRkRW50cnkoY2UpOwotICAgICAgICAgIH0gY2F0Y2ggKENhdGFsb2dFeGNlcHRpb24gY2V4KSB7Ci0gICAgICAgICAgICBpZiAoY2V4LmdldEV4Y2VwdGlvblR5cGUoKSA9PSBDYXRhbG9nRXhjZXB0aW9uLklOVkFMSURfRU5UUllfVFlQRSkgewotICAgICAgICAgICAgICBkZWJ1Zy5tZXNzYWdlKDEsICJJbnZhbGlkIGNhdGFsb2cgZW50cnkgdHlwZSIsIGxvY2FsTmFtZSk7Ci0gICAgICAgICAgICB9IGVsc2UgaWYgKGNleC5nZXRFeGNlcHRpb25UeXBlKCkgPT0gQ2F0YWxvZ0V4Y2VwdGlvbi5JTlZBTElEX0VOVFJZKSB7Ci0gICAgICAgICAgICAgIGRlYnVnLm1lc3NhZ2UoMSwgIkludmFsaWQgY2F0YWxvZyBlbnRyeSAocm92ZXJyaWRlKSIsIGxvY2FsTmFtZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotCi0gICAgbmFtZXNwYWNlU3RhY2sucG9wKCk7Ci0KLSAgICByZXR1cm47Ci0gIH0KLQotICAvKiogVGhlIFNBWCA8Y29kZT5jaGFyYWN0ZXJzPC9jb2RlPiBtZXRob2QgZG9lcyBub3RoaW5nLiAqLwotICBwdWJsaWMgdm9pZCBjaGFyYWN0ZXJzIChjaGFyIGNoW10sIGludCBzdGFydCwgaW50IGxlbmd0aCkKLSAgICB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICByZXR1cm47Ci0gIH0KLQotICAvKiogVGhlIFNBWCA8Y29kZT5pZ25vcmFibGVXaGl0ZXNwYWNlPC9jb2RlPiBtZXRob2QgZG9lcyBub3RoaW5nLiAqLwotICBwdWJsaWMgdm9pZCBpZ25vcmFibGVXaGl0ZXNwYWNlIChjaGFyIGNoW10sIGludCBzdGFydCwgaW50IGxlbmd0aCkKLSAgICB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICByZXR1cm47Ci0gIH0KLQotICAvKiogVGhlIFNBWCA8Y29kZT5wcm9jZXNzaW5nSW5zdHJ1Y3Rpb248L2NvZGU+IG1ldGhvZCBkb2VzIG5vdGhpbmcuICovCi0gIHB1YmxpYyB2b2lkIHByb2Nlc3NpbmdJbnN0cnVjdGlvbiAoU3RyaW5nIHRhcmdldCwgU3RyaW5nIGRhdGEpCi0gICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0gICAgcmV0dXJuOwotICB9Ci0KLSAgLyoqIFRoZSBTQVggPGNvZGU+c2tpcHBlZEVudGl0eTwvY29kZT4gbWV0aG9kIGRvZXMgbm90aGluZy4gKi8KLSAgcHVibGljIHZvaWQgc2tpcHBlZEVudGl0eSAoU3RyaW5nIG5hbWUpCi0gICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0gICAgcmV0dXJuOwotICB9Ci0KLSAgLyoqIFRoZSBTQVggPGNvZGU+c3RhcnRQcmVmaXhNYXBwaW5nPC9jb2RlPiBtZXRob2QgZG9lcyBub3RoaW5nLiAqLwotICBwdWJsaWMgdm9pZCBzdGFydFByZWZpeE1hcHBpbmcoU3RyaW5nIHByZWZpeCwgU3RyaW5nIHVyaSkKLSAgICB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICByZXR1cm47Ci0gIH0KLQotICAvKiogVGhlIFNBWCA8Y29kZT5lbmRQcmVmaXhNYXBwaW5nPC9jb2RlPiBtZXRob2QgZG9lcyBub3RoaW5nLiAqLwotICBwdWJsaWMgdm9pZCBlbmRQcmVmaXhNYXBwaW5nKFN0cmluZyBwcmVmaXgpCi0gICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0gICAgcmV0dXJuOwotICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3Jlc29sdmVyL3JlYWRlcnMvU0FYQ2F0YWxvZ1BhcnNlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvcmVzb2x2ZXIvcmVhZGVycy9TQVhDYXRhbG9nUGFyc2VyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDc4Mjc0NGIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvcmVzb2x2ZXIvcmVhZGVycy9TQVhDYXRhbG9nUGFyc2VyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0NSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLy8gU0FYQ2F0YWxvZ1BhcnNlci5qYXZhIC0gQW4gaW50ZXJmYWNlIGZvciByZWFkaW5nIGNhdGFsb2cgZmlsZXMKLQotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIG9yIGl0cyBsaWNlbnNvcnMsCi0gKiBhcyBhcHBsaWNhYmxlLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzb2x2ZXIucmVhZGVyczsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzb2x2ZXIuQ2F0YWxvZzsKLWltcG9ydCBvcmcueG1sLnNheC4qOwotCi0vKioKLSAqIFRoZSBTQVhDYXRhbG9nUGFyc2VyIGludGVyZmFjZS4KLSAqCi0gKiA8cD5UaGlzIGludGVyZmFjZSBtdXN0IGJlIGltcGxlbWVudGVkIGluIG9yZGVyIGZvciBhIGNsYXNzIHRvCi0gKiBwYXJ0aWNpcGF0ZSBhcyBhIHBhcnNlciBmb3IgdGhlIFNBWENhdGFsb2dSZWFkZXIuCi0gKgotICogQHNlZSBDYXRhbG9nCi0gKiBAc2VlIFNBWENhdGFsb2dSZWFkZXIKLSAqCi0gKiBAYXV0aG9yIE5vcm1hbiBXYWxzaAotICogPGEgaHJlZj0ibWFpbHRvOk5vcm1hbi5XYWxzaEBTdW4uQ09NIj5Ob3JtYW4uV2Fsc2hAU3VuLkNPTTwvYT4KLSAqCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgU0FYQ2F0YWxvZ1BhcnNlciBleHRlbmRzIENvbnRlbnRIYW5kbGVyLCBEb2N1bWVudEhhbmRsZXIgewotICAgIC8qKiBTZXQgdGhlIENhdGFsb2cgZm9yIHdoaWNoIHBhcnNpbmcgaXMgYmVpbmcgcGVyZm9ybWVkLiAqLwotICAgIHB1YmxpYyB2b2lkIHNldENhdGFsb2coQ2F0YWxvZyBjYXRhbG9nKTsKLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3Jlc29sdmVyL3JlYWRlcnMvU0FYQ2F0YWxvZ1JlYWRlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvcmVzb2x2ZXIvcmVhZGVycy9TQVhDYXRhbG9nUmVhZGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDNlNzVhYjMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvcmVzb2x2ZXIvcmVhZGVycy9TQVhDYXRhbG9nUmVhZGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw1MDIgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqLwotLyoKLSAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQotICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCi0gKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCi0gKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAotICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKLSAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vLyBTQVhDYXRhbG9nUmVhZGVyLmphdmEgLSBSZWFkIFhNTCBDYXRhbG9nIGZpbGVzCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXNvbHZlci5yZWFkZXJzOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXNvbHZlci5DYXRhbG9nOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzb2x2ZXIuQ2F0YWxvZ0V4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnJlc29sdmVyLkNhdGFsb2dNYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzb2x2ZXIuaGVscGVycy5EZWJ1ZzsKLWltcG9ydCBqYXZhLmlvLkZpbGVOb3RGb3VuZEV4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5uZXQuTWFsZm9ybWVkVVJMRXhjZXB0aW9uOwotaW1wb3J0IGphdmEubmV0LlVSTDsKLWltcG9ydCBqYXZhLm5ldC5VUkxDb25uZWN0aW9uOwotaW1wb3J0IGphdmEubmV0LlVua25vd25Ib3N0RXhjZXB0aW9uOwotaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwotaW1wb3J0IGphdmEudXRpbC5NYXA7Ci1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXI7Ci1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyRmFjdG9yeTsKLWltcG9ydCBvcmcueG1sLnNheC5BdHRyaWJ1dGVMaXN0OwotaW1wb3J0IG9yZy54bWwuc2F4LkF0dHJpYnV0ZXM7Ci1pbXBvcnQgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguRG9jdW1lbnRIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LkVudGl0eVJlc29sdmVyOwotaW1wb3J0IG9yZy54bWwuc2F4LklucHV0U291cmNlOwotaW1wb3J0IG9yZy54bWwuc2F4LkxvY2F0b3I7Ci1pbXBvcnQgb3JnLnhtbC5zYXguUGFyc2VyOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKLWltcG9ydCBzdW4ucmVmbGVjdC5taXNjLlJlZmxlY3RVdGlsOwotCi0vKioKLSAqIEEgU0FYLWJhc2VkIENhdGFsb2dSZWFkZXIuCi0gKgotICogPHA+VGhpcyBjbGFzcyBpcyB1c2VkIHRvIHJlYWQgWE1MIENhdGFsb2dzIHVzaW5nIHRoZSBTQVguIFRoaXMgcmVhZGVyCi0gKiBoYXMgYW4gYWR2YW50YWdlIG92ZXIgdGhlIERPTS1iYXNlZCByZWFkZXIgaW4gdGhhdCBpdCBmdW5jdGlvbnMgb24KLSAqIHRoZSBzdHJlYW0gb2YgU0FYIGV2ZW50cy4gSXQgaGFzIHRoZSBkaXNhZHZhbnRhZ2UKLSAqIHRoYXQgaXQgY2Fubm90IGxvb2sgYXJvdW5kIGluIHRoZSB0cmVlLjwvcD4KLSAqCi0gKiA8cD5TaW5jZSB0aGUgY2hvaWNlIG9mIENhdGFsb2dSZWFkZXJzIChpbiB0aGUgSW5wdXRTdHJlYW0gY2FzZSkgY2FuIG9ubHkKLSAqIGJlIG1hZGUgb24gdGhlIGJhc2lzIG9mIE1JTUUgdHlwZSwgdGhlIGZvbGxvd2luZyBwcm9ibGVtIG9jY3Vyczogb25seQotICogb25lIENhdGFsb2dSZWFkZXIgY2FuIGV4aXN0IGZvciBhbGwgWE1MIG1pbWUgdHlwZXMuIEluIG9yZGVyIHRvIGdldAotICogYXJvdW5kIHRoaXMgcHJvYmxlbSwgdGhlIFNBWENhdGFsb2dSZWFkZXIgcmVsaWVzIG9uIGEgc2V0IG9mIGV4dGVybmFsCi0gKiBDYXRhbG9nUGFyc2VycyB0byBhY3R1YWxseSBidWlsZCB0aGUgY2F0YWxvZy48L3A+Ci0gKgotICogPHA+VGhlIHNlbGVjdGlvbiBvZiBDYXRhbG9nUGFyc2VycyBpcyBtYWRlIG9uIHRoZSBiYXNpcyBvZiB0aGUgUU5hbWUKLSAqIG9mIHRoZSByb290IGVsZW1lbnQgb2YgdGhlIGRvY3VtZW50LjwvcD4KLSAqCi0gKiBAc2VlIENhdGFsb2cKLSAqIEBzZWUgQ2F0YWxvZ1JlYWRlcgotICogQHNlZSBTQVhDYXRhbG9nUmVhZGVyCi0gKiBAc2VlIFRleHRDYXRhbG9nUmVhZGVyCi0gKiBAc2VlIERPTUNhdGFsb2dQYXJzZXIKLSAqCi0gKiBAYXV0aG9yIE5vcm1hbiBXYWxzaAotICogPGEgaHJlZj0ibWFpbHRvOk5vcm1hbi5XYWxzaEBTdW4uQ09NIj5Ob3JtYW4uV2Fsc2hAU3VuLkNPTTwvYT4KLSAqCi0gKi8KLXB1YmxpYyBjbGFzcyBTQVhDYXRhbG9nUmVhZGVyIGltcGxlbWVudHMgQ2F0YWxvZ1JlYWRlciwgQ29udGVudEhhbmRsZXIsIERvY3VtZW50SGFuZGxlciB7Ci0gIC8qKiBUaGUgU0FYIFBhcnNlciBGYWN0b3J5ICovCi0gIHByb3RlY3RlZCBTQVhQYXJzZXJGYWN0b3J5IHBhcnNlckZhY3RvcnkgPSBudWxsOwotCi0gIC8qKiBUaGUgU0FYIFBhcnNlciBDbGFzcyAqLwotICBwcm90ZWN0ZWQgU3RyaW5nIHBhcnNlckNsYXNzID0gbnVsbDsKLQotICAvKioKLSAgICAgKiBNYXBwaW5nIHRhYmxlIGZyb20gUU5hbWVzIHRvIENhdGFsb2dQYXJzZXIgY2xhc3Nlcy4KLSAgICAgKgotICAgICAqIDxwPkVhY2gga2V5IGluIHRoaXMgaGFzaCB0YWJsZSBoYXMgdGhlIGZvcm0gImVsZW1lbnRuYW1lIgotICAgICAqIG9yICJ7bmFtZXNwYWNldXJpfWVsZW1lbnRuYW1lIi4gVGhlIGZvcm1lciBpcyB1c2VkIGlmIHRoZQotICAgICAqIG5hbWVzcGFjZSBVUkkgaXMgbnVsbC48L3A+Ci0gICAgICovCi0gIHByb3RlY3RlZCBNYXA8U3RyaW5nLCBTdHJpbmc+IG5hbWVzcGFjZU1hcCA9IG5ldyBIYXNoTWFwPD4oKTsKLQotICAvKiogVGhlIHBhcnNlciBpbiB1c2UgZm9yIHRoZSBjdXJyZW50IGNhdGFsb2cuICovCi0gIHByaXZhdGUgU0FYQ2F0YWxvZ1BhcnNlciBzYXhQYXJzZXIgPSBudWxsOwotCi0gIC8qKiBTZXQgaWYgc29tZXRoaW5nIGdvZXMgaG9ycmlibHkgd3JvbmcuIEl0IGFsbG93cyB0aGUgY2xhc3MgdG8KLSAgICAgKiBpZ25vcmUgdGhlIHJlc3Qgb2YgdGhlIGV2ZW50cyB0aGF0IGFyZSByZWNlaXZlZC4KLSAgICAgKi8KLSAgcHJpdmF0ZSBib29sZWFuIGFiYW5kb25Ib3BlID0gZmFsc2U7Ci0KLSAgLyoqIFRoZSBDYXRhbG9nIHRoYXQgd2UncmUgd29ya2luZyBmb3IuICovCi0gIHByaXZhdGUgQ2F0YWxvZyBjYXRhbG9nOwotCi0gIC8qKiBTZXQgdGhlIFhNTCBTQVggUGFyc2VyIEZhY3RvcnkuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRQYXJzZXJGYWN0b3J5KFNBWFBhcnNlckZhY3RvcnkgcGFyc2VyRmFjdG9yeSkgewotICAgIHRoaXMucGFyc2VyRmFjdG9yeSA9IHBhcnNlckZhY3Rvcnk7Ci0gIH0KLQotICAvKiogU2V0IHRoZSBYTUwgU0FYIFBhcnNlciBDbGFzcwotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0UGFyc2VyQ2xhc3MoU3RyaW5nIHBhcnNlckNsYXNzKSB7Ci0gICAgdGhpcy5wYXJzZXJDbGFzcyA9IHBhcnNlckNsYXNzOwotICB9Ci0KLSAgLyoqIEdldCB0aGUgcGFyc2VyIGZhY3RvcnkgY3VycmVudGx5IGluIHVzZS4gKi8KLSAgcHVibGljIFNBWFBhcnNlckZhY3RvcnkgZ2V0UGFyc2VyRmFjdG9yeSgpIHsKLSAgICByZXR1cm4gcGFyc2VyRmFjdG9yeTsKLSAgfQotCi0gIC8qKiBHZXQgdGhlIHBhcnNlciBjbGFzcyBjdXJyZW50bHkgaW4gdXNlLiAqLwotICBwdWJsaWMgU3RyaW5nIGdldFBhcnNlckNsYXNzKCkgewotICAgIHJldHVybiBwYXJzZXJDbGFzczsKLSAgfQotCi0gIC8qKiBUaGUgZGVidWcgY2xhc3MgdG8gdXNlIGZvciB0aGlzIHJlYWRlci4KLSAgICoKLSAgICogVGhpcyBpcyBhIGJpdCBvZiBhIGhhY2suIEFueXdheSwgd2hlbmV2ZXIgd2UgcmVhZCBmb3IgYSBjYXRhbG9nLAotICAgKiB3ZSBleHRyYWN0IHRoZSBkZWJ1ZyBvYmplY3QKLSAgICogZnJvbSB0aGUgY2F0YWxvZydzIG1hbmFnZXIgc28gdGhhdCB3ZSBjYW4gdXNlIGl0IHRvIHByaW50IG1lc3NhZ2VzLgotICAgKgotICAgKiBJbiBwcm9kdWN0aW9uLCB3ZSBkb24ndCByZWFsbHkgZXhwZWN0IGFueSBtZXNzYWdlcyBzbyBpdCBkb2Vzbid0Ci0gICAqIHJlYWxseSBtYXR0ZXIuIEJ1dCBpdCdzIHN0aWxsIGEgYml0IG9mIGEgaGFjay4KLSAgICovCi0gIHByb3RlY3RlZCBEZWJ1ZyBkZWJ1ZyA9IENhdGFsb2dNYW5hZ2VyLmdldFN0YXRpY01hbmFnZXIoKS5kZWJ1ZzsKLQotICAvKiogVGhlIGNvbnN0cnVjdG9yICovCi0gIHB1YmxpYyBTQVhDYXRhbG9nUmVhZGVyKCkgewotICAgIHBhcnNlckZhY3RvcnkgPSBudWxsOwotICAgIHBhcnNlckNsYXNzID0gbnVsbDsKLSAgfQotCi0gIC8qKiBUaGUgY29uc3RydWN0b3IgKi8KLSAgcHVibGljIFNBWENhdGFsb2dSZWFkZXIoU0FYUGFyc2VyRmFjdG9yeSBwYXJzZXJGYWN0b3J5KSB7Ci0gICAgdGhpcy5wYXJzZXJGYWN0b3J5ID0gcGFyc2VyRmFjdG9yeTsKLSAgfQotCi0gIC8qKiBUaGUgY29uc3RydWN0b3IgKi8KLSAgcHVibGljIFNBWENhdGFsb2dSZWFkZXIoU3RyaW5nIHBhcnNlckNsYXNzKSB7Ci0gICAgdGhpcy5wYXJzZXJDbGFzcyA9IHBhcnNlckNsYXNzOwotICB9Ci0KLSAgLyoqIFNldCB0aGUgU0FYQ2F0YWxvZ1BhcnNlciBjbGFzcyBmb3IgdGhlIGdpdmVuIG5hbWVzcGFjZS9yb290Ci0gICAgICogZWxlbWVudCB0eXBlLgotICAgICAqLwotICBwdWJsaWMgdm9pZCBzZXRDYXRhbG9nUGFyc2VyKFN0cmluZyBuYW1lc3BhY2VVUkksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHJvb3RFbGVtZW50LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBwYXJzZXJDbGFzcykgewotICAgIGlmIChuYW1lc3BhY2VVUkkgPT0gbnVsbCkgewotICAgICAgbmFtZXNwYWNlTWFwLnB1dChyb290RWxlbWVudCwgcGFyc2VyQ2xhc3MpOwotICAgIH0gZWxzZSB7Ci0gICAgICBuYW1lc3BhY2VNYXAucHV0KCJ7IituYW1lc3BhY2VVUkkrIn0iK3Jvb3RFbGVtZW50LCBwYXJzZXJDbGFzcyk7Ci0gICAgfQotICB9Ci0KLSAgLyoqIEdldCB0aGUgU0FYQ2F0YWxvZ1BhcnNlciBjbGFzcyBmb3IgdGhlIGdpdmVuIG5hbWVzcGFjZS9yb290Ci0gICAgICogZWxlbWVudCB0eXBlLgotICAgICAqLwotICBwdWJsaWMgU3RyaW5nIGdldENhdGFsb2dQYXJzZXIoU3RyaW5nIG5hbWVzcGFjZVVSSSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyByb290RWxlbWVudCkgewotICAgIGlmIChuYW1lc3BhY2VVUkkgPT0gbnVsbCkgewotICAgICAgcmV0dXJuIG5hbWVzcGFjZU1hcC5nZXQocm9vdEVsZW1lbnQpOwotICAgIH0gZWxzZSB7Ci0gICAgICByZXR1cm4gbmFtZXNwYWNlTWFwLmdldCgieyIrbmFtZXNwYWNlVVJJKyJ9Iityb290RWxlbWVudCk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFBhcnNlIGFuIFhNTCBDYXRhbG9nIGZpbGUuCi0gICAqCi0gICAqIEBwYXJhbSBjYXRhbG9nIFRoZSBjYXRhbG9nIHRvIHdoaWNoIHRoaXMgY2F0YWxvZyBmaWxlIGJlbG9uZ3MKLSAgICogQHBhcmFtIGZpbGVVcmwgVGhlIFVSTCBvciBmaWxlbmFtZSBvZiB0aGUgY2F0YWxvZyBmaWxlIHRvIHByb2Nlc3MKLSAgICoKLSAgICogQHRocm93cyBNYWxmb3JtZWRVUkxFeGNlcHRpb24gSW1wcm9wZXIgZmlsZVVybAotICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIEVycm9yIHJlYWRpbmcgY2F0YWxvZyBmaWxlCi0gICAqLwotICBwdWJsaWMgdm9pZCByZWFkQ2F0YWxvZyhDYXRhbG9nIGNhdGFsb2csIFN0cmluZyBmaWxlVXJsKQotICAgIHRocm93cyBNYWxmb3JtZWRVUkxFeGNlcHRpb24sIElPRXhjZXB0aW9uLAotICAgICAgICAgICBDYXRhbG9nRXhjZXB0aW9uIHsKLQotICAgIFVSTCB1cmwgPSBudWxsOwotCi0gICAgdHJ5IHsKLSAgICAgIHVybCA9IG5ldyBVUkwoZmlsZVVybCk7Ci0gICAgfSBjYXRjaCAoTWFsZm9ybWVkVVJMRXhjZXB0aW9uIGUpIHsKLSAgICAgIHVybCA9IG5ldyBVUkwoImZpbGU6Ly8vIiArIGZpbGVVcmwpOwotICAgIH0KLQotICAgIGRlYnVnID0gY2F0YWxvZy5nZXRDYXRhbG9nTWFuYWdlcigpLmRlYnVnOwotCi0gICAgdHJ5IHsKLSAgICAgIFVSTENvbm5lY3Rpb24gdXJsQ29uID0gdXJsLm9wZW5Db25uZWN0aW9uKCk7Ci0gICAgICByZWFkQ2F0YWxvZyhjYXRhbG9nLCB1cmxDb24uZ2V0SW5wdXRTdHJlYW0oKSk7Ci0gICAgfSBjYXRjaCAoRmlsZU5vdEZvdW5kRXhjZXB0aW9uIGUpIHsKLSAgICAgIGNhdGFsb2cuZ2V0Q2F0YWxvZ01hbmFnZXIoKS5kZWJ1Zy5tZXNzYWdlKDEsICJGYWlsZWQgdG8gbG9hZCBjYXRhbG9nLCBmaWxlIG5vdCBmb3VuZCIsCi0gICAgICAgICAgICAgICAgICAgIHVybC50b1N0cmluZygpKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogUGFyc2UgYW4gWE1MIENhdGFsb2cgc3RyZWFtLgotICAgKgotICAgKiBAcGFyYW0gY2F0YWxvZyBUaGUgY2F0YWxvZyB0byB3aGljaCB0aGlzIGNhdGFsb2cgZmlsZSBiZWxvbmdzCi0gICAqIEBwYXJhbSBpcyBUaGUgaW5wdXQgc3RyZWFtIGZyb20gd2hpY2ggdGhlIGNhdGFsb2cgd2lsbCBiZSByZWFkCi0gICAqCi0gICAqIEB0aHJvd3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uIEltcHJvcGVyIGZpbGVVcmwKLSAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBFcnJvciByZWFkaW5nIGNhdGFsb2cgZmlsZQotICAgKiBAdGhyb3dzIENhdGFsb2dFeGNlcHRpb24gQSBDYXRhbG9nIGV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgcmVhZENhdGFsb2coQ2F0YWxvZyBjYXRhbG9nLCBJbnB1dFN0cmVhbSBpcykKLSAgICB0aHJvd3MgSU9FeGNlcHRpb24sIENhdGFsb2dFeGNlcHRpb24gewotCi0gICAgLy8gQ3JlYXRlIGFuIGluc3RhbmNlIG9mIHRoZSBwYXJzZXIKLSAgICBpZiAocGFyc2VyRmFjdG9yeSA9PSBudWxsICYmIHBhcnNlckNsYXNzID09IG51bGwpIHsKLSAgICAgIGRlYnVnLm1lc3NhZ2UoMSwgIkNhbm5vdCByZWFkIFNBWCBjYXRhbG9nIHdpdGhvdXQgYSBwYXJzZXIiKTsKLSAgICAgIHRocm93IG5ldyBDYXRhbG9nRXhjZXB0aW9uKENhdGFsb2dFeGNlcHRpb24uVU5QQVJTRUFCTEUpOwotICAgIH0KLQotICAgIGRlYnVnID0gY2F0YWxvZy5nZXRDYXRhbG9nTWFuYWdlcigpLmRlYnVnOwotICAgIEVudGl0eVJlc29sdmVyIGJSZXNvbHZlciA9IGNhdGFsb2cuZ2V0Q2F0YWxvZ01hbmFnZXIoKS5nZXRCb290c3RyYXBSZXNvbHZlcigpOwotCi0gICAgdGhpcy5jYXRhbG9nID0gY2F0YWxvZzsKLQotICAgIHRyeSB7Ci0gICAgICBpZiAocGFyc2VyRmFjdG9yeSAhPSBudWxsKSB7Ci0gICAgICAgIFNBWFBhcnNlciBwYXJzZXIgPSBwYXJzZXJGYWN0b3J5Lm5ld1NBWFBhcnNlcigpOwotICAgICAgICBTQVhQYXJzZXJIYW5kbGVyIHNwSGFuZGxlciA9IG5ldyBTQVhQYXJzZXJIYW5kbGVyKCk7Ci0gICAgICAgIHNwSGFuZGxlci5zZXRDb250ZW50SGFuZGxlcih0aGlzKTsKLSAgICAgICAgaWYgKGJSZXNvbHZlciAhPSBudWxsKSB7Ci0gICAgICAgICAgc3BIYW5kbGVyLnNldEVudGl0eVJlc29sdmVyKGJSZXNvbHZlcik7Ci0gICAgICAgIH0KLSAgICAgICAgcGFyc2VyLnBhcnNlKG5ldyBJbnB1dFNvdXJjZShpcyksIHNwSGFuZGxlcik7Ci0gICAgICB9IGVsc2UgewotICAgICAgICBQYXJzZXIgcGFyc2VyID0gKFBhcnNlcikgUmVmbGVjdFV0aWwuZm9yTmFtZShwYXJzZXJDbGFzcykubmV3SW5zdGFuY2UoKTsKLSAgICAgICAgcGFyc2VyLnNldERvY3VtZW50SGFuZGxlcih0aGlzKTsKLSAgICAgICAgaWYgKGJSZXNvbHZlciAhPSBudWxsKSB7Ci0gICAgICAgICAgcGFyc2VyLnNldEVudGl0eVJlc29sdmVyKGJSZXNvbHZlcik7Ci0gICAgICAgIH0KLSAgICAgICAgcGFyc2VyLnBhcnNlKG5ldyBJbnB1dFNvdXJjZShpcykpOwotICAgICAgfQotICAgIH0gY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gY25mZSkgewotICAgICAgdGhyb3cgbmV3IENhdGFsb2dFeGNlcHRpb24oQ2F0YWxvZ0V4Y2VwdGlvbi5VTlBBUlNFQUJMRSk7Ci0gICAgfSBjYXRjaCAoSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBpYWUpIHsKLSAgICAgIHRocm93IG5ldyBDYXRhbG9nRXhjZXB0aW9uKENhdGFsb2dFeGNlcHRpb24uVU5QQVJTRUFCTEUpOwotICAgIH0gY2F0Y2ggKEluc3RhbnRpYXRpb25FeGNlcHRpb24gaWUpIHsKLSAgICAgIHRocm93IG5ldyBDYXRhbG9nRXhjZXB0aW9uKENhdGFsb2dFeGNlcHRpb24uVU5QQVJTRUFCTEUpOwotICAgIH0gY2F0Y2ggKFBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gcGNlKSB7Ci0gICAgICB0aHJvdyBuZXcgQ2F0YWxvZ0V4Y2VwdGlvbihDYXRhbG9nRXhjZXB0aW9uLlVOS05PV05fRk9STUFUKTsKLSAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gc2UpIHsKLSAgICAgIEV4Y2VwdGlvbiBlID0gc2UuZ2V0RXhjZXB0aW9uKCk7Ci0gICAgICAvLyBGSVhNRTogdGhlcmUgbXVzdCBiZSBhIGJldHRlciB3YXkKLSAgICAgIFVua25vd25Ib3N0RXhjZXB0aW9uIHVoZSA9IG5ldyBVbmtub3duSG9zdEV4Y2VwdGlvbigpOwotICAgICAgRmlsZU5vdEZvdW5kRXhjZXB0aW9uIGZuZmUgPSBuZXcgRmlsZU5vdEZvdW5kRXhjZXB0aW9uKCk7Ci0gICAgICBpZiAoZSAhPSBudWxsKSB7Ci0gICAgICAgIGlmIChlLmdldENsYXNzKCkgPT0gdWhlLmdldENsYXNzKCkpIHsKLSAgICAgICAgICB0aHJvdyBuZXcgQ2F0YWxvZ0V4Y2VwdGlvbihDYXRhbG9nRXhjZXB0aW9uLlBBUlNFX0ZBSUxFRCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlLnRvU3RyaW5nKCkpOwotICAgICAgICB9IGVsc2UgaWYgKGUuZ2V0Q2xhc3MoKSA9PSBmbmZlLmdldENsYXNzKCkpIHsKLSAgICAgICAgICB0aHJvdyBuZXcgQ2F0YWxvZ0V4Y2VwdGlvbihDYXRhbG9nRXhjZXB0aW9uLlBBUlNFX0ZBSUxFRCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlLnRvU3RyaW5nKCkpOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgICB0aHJvdyBuZXcgQ2F0YWxvZ0V4Y2VwdGlvbihzZSk7Ci0gICAgfQotICB9Ci0KLSAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAvLyBJbXBsZW1lbnQgdGhlIFNBWCBDb250ZW50SGFuZGxlciBpbnRlcmZhY2UKLQotICAvKiogVGhlIFNBWCA8Y29kZT5zZXREb2N1bWVudExvY2F0b3I8L2NvZGU+IG1ldGhvZC4gRG9lcyBub3RoaW5nLiAqLwotICBwdWJsaWMgdm9pZCBzZXREb2N1bWVudExvY2F0b3IgKExvY2F0b3IgbG9jYXRvcikgewotICAgIGlmIChzYXhQYXJzZXIgIT0gbnVsbCkgewotICAgICAgc2F4UGFyc2VyLnNldERvY3VtZW50TG9jYXRvcihsb2NhdG9yKTsKLSAgICB9Ci0gIH0KLQotICAvKiogVGhlIFNBWCA8Y29kZT5zdGFydERvY3VtZW50PC9jb2RlPiBtZXRob2QuIERvZXMgbm90aGluZy4gKi8KLSAgcHVibGljIHZvaWQgc3RhcnREb2N1bWVudCAoKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICBzYXhQYXJzZXIgPSBudWxsOwotICAgIGFiYW5kb25Ib3BlID0gZmFsc2U7Ci0gICAgcmV0dXJuOwotICB9Ci0KLSAgLyoqIFRoZSBTQVggPGNvZGU+ZW5kRG9jdW1lbnQ8L2NvZGU+IG1ldGhvZC4gRG9lcyBub3RoaW5nLiAqLwotICBwdWJsaWMgdm9pZCBlbmREb2N1bWVudCAoKXRocm93cyBTQVhFeGNlcHRpb24gewotICAgIGlmIChzYXhQYXJzZXIgIT0gbnVsbCkgewotICAgICAgc2F4UGFyc2VyLmVuZERvY3VtZW50KCk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFRoZSBTQVggPGNvZGU+c3RhcnRFbGVtZW50PC9jb2RlPiBtZXRob2QuCi0gICAqCi0gICAqIDxwPlRoZSBjYXRhbG9nIHBhcnNlciBpcyBzZWxlY3RlZCBiYXNlZCBvbiB0aGUgbmFtZXNwYWNlIG9mIHRoZQotICAgKiBmaXJzdCBlbGVtZW50IGVuY291bnRlcmVkIGluIHRoZSBjYXRhbG9nLjwvcD4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudCAoU3RyaW5nIG5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgQXR0cmlidXRlTGlzdCBhdHRzKQotICAgIHRocm93cyBTQVhFeGNlcHRpb24gewotCi0gICAgaWYgKGFiYW5kb25Ib3BlKSB7Ci0gICAgICByZXR1cm47Ci0gICAgfQotCi0gICAgaWYgKHNheFBhcnNlciA9PSBudWxsKSB7Ci0gICAgICBTdHJpbmcgcHJlZml4ID0gIiI7Ci0gICAgICBpZiAobmFtZS5pbmRleE9mKCc6JykgPiAwKSB7Ci0gICAgICAgIHByZWZpeCA9IG5hbWUuc3Vic3RyaW5nKDAsIG5hbWUuaW5kZXhPZignOicpKTsKLSAgICAgIH0KLQotICAgICAgU3RyaW5nIGxvY2FsTmFtZSA9IG5hbWU7Ci0gICAgICBpZiAobG9jYWxOYW1lLmluZGV4T2YoJzonKSA+IDApIHsKLSAgICAgICAgbG9jYWxOYW1lID0gbG9jYWxOYW1lLnN1YnN0cmluZyhsb2NhbE5hbWUuaW5kZXhPZignOicpKzEpOwotICAgICAgfQotCi0gICAgICBTdHJpbmcgbmFtZXNwYWNlVVJJID0gbnVsbDsKLSAgICAgIGlmIChwcmVmaXguZXF1YWxzKCIiKSkgewotICAgICAgICBuYW1lc3BhY2VVUkkgPSBhdHRzLmdldFZhbHVlKCJ4bWxucyIpOwotICAgICAgfSBlbHNlIHsKLSAgICAgICAgbmFtZXNwYWNlVVJJID0gYXR0cy5nZXRWYWx1ZSgieG1sbnM6IiArIHByZWZpeCk7Ci0gICAgICB9Ci0KLSAgICAgIFN0cmluZyBzYXhQYXJzZXJDbGFzcyA9IGdldENhdGFsb2dQYXJzZXIobmFtZXNwYWNlVVJJLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhbE5hbWUpOwotCi0gICAgICBpZiAoc2F4UGFyc2VyQ2xhc3MgPT0gbnVsbCkgewotICAgICAgICBhYmFuZG9uSG9wZSA9IHRydWU7Ci0gICAgICAgIGlmIChuYW1lc3BhY2VVUkkgPT0gbnVsbCkgewotICAgICAgICAgIGRlYnVnLm1lc3NhZ2UoMiwgIk5vIENhdGFsb2cgcGFyc2VyIGZvciAiICsgbmFtZSk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgZGVidWcubWVzc2FnZSgyLCAiTm8gQ2F0YWxvZyBwYXJzZXIgZm9yICIKLSAgICAgICAgICAgICAgICAgICAgICAgICsgInsiICsgbmFtZXNwYWNlVVJJICsgIn0iCi0gICAgICAgICAgICAgICAgICAgICAgICArIG5hbWUpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybjsKLSAgICAgIH0KLQotICAgICAgdHJ5IHsKLSAgICAgICAgc2F4UGFyc2VyID0gKFNBWENhdGFsb2dQYXJzZXIpCi0gICAgICAgICAgUmVmbGVjdFV0aWwuZm9yTmFtZShzYXhQYXJzZXJDbGFzcykubmV3SW5zdGFuY2UoKTsKLQotICAgICAgICBzYXhQYXJzZXIuc2V0Q2F0YWxvZyhjYXRhbG9nKTsKLSAgICAgICAgc2F4UGFyc2VyLnN0YXJ0RG9jdW1lbnQoKTsKLSAgICAgICAgc2F4UGFyc2VyLnN0YXJ0RWxlbWVudChuYW1lLCBhdHRzKTsKLSAgICAgIH0gY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gY25mZSkgewotICAgICAgICBzYXhQYXJzZXIgPSBudWxsOwotICAgICAgICBhYmFuZG9uSG9wZSA9IHRydWU7Ci0gICAgICAgIGRlYnVnLm1lc3NhZ2UoMiwgY25mZS50b1N0cmluZygpKTsKLSAgICAgIH0gY2F0Y2ggKEluc3RhbnRpYXRpb25FeGNlcHRpb24gaWUpIHsKLSAgICAgICAgc2F4UGFyc2VyID0gbnVsbDsKLSAgICAgICAgYWJhbmRvbkhvcGUgPSB0cnVlOwotICAgICAgICBkZWJ1Zy5tZXNzYWdlKDIsIGllLnRvU3RyaW5nKCkpOwotICAgICAgfSBjYXRjaCAoSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBpYWUpIHsKLSAgICAgICAgc2F4UGFyc2VyID0gbnVsbDsKLSAgICAgICAgYWJhbmRvbkhvcGUgPSB0cnVlOwotICAgICAgICBkZWJ1Zy5tZXNzYWdlKDIsIGlhZS50b1N0cmluZygpKTsKLSAgICAgIH0gY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBjY2UgKSB7Ci0gICAgICAgIHNheFBhcnNlciA9IG51bGw7Ci0gICAgICAgIGFiYW5kb25Ib3BlID0gdHJ1ZTsKLSAgICAgICAgZGVidWcubWVzc2FnZSgyLCBjY2UudG9TdHJpbmcoKSk7Ci0gICAgICB9Ci0gICAgfSBlbHNlIHsKLSAgICAgIHNheFBhcnNlci5zdGFydEVsZW1lbnQobmFtZSwgYXR0cyk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFRoZSBTQVgyIDxjb2RlPnN0YXJ0RWxlbWVudDwvY29kZT4gbWV0aG9kLgotICAgKgotICAgKiA8cD5UaGUgY2F0YWxvZyBwYXJzZXIgaXMgc2VsZWN0ZWQgYmFzZWQgb24gdGhlIG5hbWVzcGFjZSBvZiB0aGUKLSAgICogZmlyc3QgZWxlbWVudCBlbmNvdW50ZXJlZCBpbiB0aGUgY2F0YWxvZy48L3A+Ci0gICAqLwotICBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQgKFN0cmluZyBuYW1lc3BhY2VVUkksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGxvY2FsTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcU5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgQXR0cmlidXRlcyBhdHRzKQotICAgIHRocm93cyBTQVhFeGNlcHRpb24gewotCi0gICAgaWYgKGFiYW5kb25Ib3BlKSB7Ci0gICAgICByZXR1cm47Ci0gICAgfQotCi0gICAgaWYgKHNheFBhcnNlciA9PSBudWxsKSB7Ci0gICAgICBTdHJpbmcgc2F4UGFyc2VyQ2xhc3MgPSBnZXRDYXRhbG9nUGFyc2VyKG5hbWVzcGFjZVVSSSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWxOYW1lKTsKLQotICAgICAgaWYgKHNheFBhcnNlckNsYXNzID09IG51bGwpIHsKLSAgICAgICAgYWJhbmRvbkhvcGUgPSB0cnVlOwotICAgICAgICBpZiAobmFtZXNwYWNlVVJJID09IG51bGwpIHsKLSAgICAgICAgICBkZWJ1Zy5tZXNzYWdlKDIsICJObyBDYXRhbG9nIHBhcnNlciBmb3IgIiArIGxvY2FsTmFtZSk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgZGVidWcubWVzc2FnZSgyLCAiTm8gQ2F0YWxvZyBwYXJzZXIgZm9yICIKLSAgICAgICAgICAgICAgICAgICAgICAgICsgInsiICsgbmFtZXNwYWNlVVJJICsgIn0iCi0gICAgICAgICAgICAgICAgICAgICAgICArIGxvY2FsTmFtZSk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuOwotICAgICAgfQotCi0gICAgICB0cnkgewotICAgICAgICBzYXhQYXJzZXIgPSAoU0FYQ2F0YWxvZ1BhcnNlcikKLSAgICAgICAgICBSZWZsZWN0VXRpbC5mb3JOYW1lKHNheFBhcnNlckNsYXNzKS5uZXdJbnN0YW5jZSgpOwotCi0gICAgICAgIHNheFBhcnNlci5zZXRDYXRhbG9nKGNhdGFsb2cpOwotICAgICAgICBzYXhQYXJzZXIuc3RhcnREb2N1bWVudCgpOwotICAgICAgICBzYXhQYXJzZXIuc3RhcnRFbGVtZW50KG5hbWVzcGFjZVVSSSwgbG9jYWxOYW1lLCBxTmFtZSwgYXR0cyk7Ci0gICAgICB9IGNhdGNoIChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGNuZmUpIHsKLSAgICAgICAgc2F4UGFyc2VyID0gbnVsbDsKLSAgICAgICAgYWJhbmRvbkhvcGUgPSB0cnVlOwotICAgICAgICBkZWJ1Zy5tZXNzYWdlKDIsIGNuZmUudG9TdHJpbmcoKSk7Ci0gICAgICB9IGNhdGNoIChJbnN0YW50aWF0aW9uRXhjZXB0aW9uIGllKSB7Ci0gICAgICAgIHNheFBhcnNlciA9IG51bGw7Ci0gICAgICAgIGFiYW5kb25Ib3BlID0gdHJ1ZTsKLSAgICAgICAgZGVidWcubWVzc2FnZSgyLCBpZS50b1N0cmluZygpKTsKLSAgICAgIH0gY2F0Y2ggKElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gaWFlKSB7Ci0gICAgICAgIHNheFBhcnNlciA9IG51bGw7Ci0gICAgICAgIGFiYW5kb25Ib3BlID0gdHJ1ZTsKLSAgICAgICAgZGVidWcubWVzc2FnZSgyLCBpYWUudG9TdHJpbmcoKSk7Ci0gICAgICB9IGNhdGNoIChDbGFzc0Nhc3RFeGNlcHRpb24gY2NlICkgewotICAgICAgICBzYXhQYXJzZXIgPSBudWxsOwotICAgICAgICBhYmFuZG9uSG9wZSA9IHRydWU7Ci0gICAgICAgIGRlYnVnLm1lc3NhZ2UoMiwgY2NlLnRvU3RyaW5nKCkpOwotICAgICAgfQotICAgIH0gZWxzZSB7Ci0gICAgICBzYXhQYXJzZXIuc3RhcnRFbGVtZW50KG5hbWVzcGFjZVVSSSwgbG9jYWxOYW1lLCBxTmFtZSwgYXR0cyk7Ci0gICAgfQotICB9Ci0KLSAgLyoqIFRoZSBTQVggPGNvZGU+ZW5kRWxlbWVudDwvY29kZT4gbWV0aG9kLiBEb2VzIG5vdGhpbmcuICovCi0gIHB1YmxpYyB2b2lkIGVuZEVsZW1lbnQgKFN0cmluZyBuYW1lKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICBpZiAoc2F4UGFyc2VyICE9IG51bGwpIHsKLSAgICAgIHNheFBhcnNlci5lbmRFbGVtZW50KG5hbWUpOwotICAgIH0KLSAgfQotCi0gIC8qKiBUaGUgU0FYMiA8Y29kZT5lbmRFbGVtZW50PC9jb2RlPiBtZXRob2QuIERvZXMgbm90aGluZy4gKi8KLSAgcHVibGljIHZvaWQgZW5kRWxlbWVudCAoU3RyaW5nIG5hbWVzcGFjZVVSSSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGxvY2FsTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHFOYW1lKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICBpZiAoc2F4UGFyc2VyICE9IG51bGwpIHsKLSAgICAgIHNheFBhcnNlci5lbmRFbGVtZW50KG5hbWVzcGFjZVVSSSwgbG9jYWxOYW1lLCBxTmFtZSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqIFRoZSBTQVggPGNvZGU+Y2hhcmFjdGVyczwvY29kZT4gbWV0aG9kLiBEb2VzIG5vdGhpbmcuICovCi0gIHB1YmxpYyB2b2lkIGNoYXJhY3RlcnMgKGNoYXIgY2hbXSwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKQotICAgIHRocm93cyBTQVhFeGNlcHRpb24gewotICAgIGlmIChzYXhQYXJzZXIgIT0gbnVsbCkgewotICAgICAgc2F4UGFyc2VyLmNoYXJhY3RlcnMoY2gsIHN0YXJ0LCBsZW5ndGgpOwotICAgIH0KLSAgfQotCi0gIC8qKiBUaGUgU0FYIDxjb2RlPmlnbm9yYWJsZVdoaXRlc3BhY2U8L2NvZGU+IG1ldGhvZC4gRG9lcyBub3RoaW5nLiAqLwotICBwdWJsaWMgdm9pZCBpZ25vcmFibGVXaGl0ZXNwYWNlIChjaGFyIGNoW10sIGludCBzdGFydCwgaW50IGxlbmd0aCkKLSAgICB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICBpZiAoc2F4UGFyc2VyICE9IG51bGwpIHsKLSAgICAgIHNheFBhcnNlci5pZ25vcmFibGVXaGl0ZXNwYWNlKGNoLCBzdGFydCwgbGVuZ3RoKTsKLSAgICB9Ci0gIH0KLQotICAvKiogVGhlIFNBWCA8Y29kZT5wcm9jZXNzaW5nSW5zdHJ1Y3Rpb248L2NvZGU+IG1ldGhvZC4gRG9lcyBub3RoaW5nLiAqLwotICBwdWJsaWMgdm9pZCBwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24gKFN0cmluZyB0YXJnZXQsIFN0cmluZyBkYXRhKQotICAgIHRocm93cyBTQVhFeGNlcHRpb24gewotICAgIGlmIChzYXhQYXJzZXIgIT0gbnVsbCkgewotICAgICAgc2F4UGFyc2VyLnByb2Nlc3NpbmdJbnN0cnVjdGlvbih0YXJnZXQsIGRhdGEpOwotICAgIH0KLSAgfQotCi0gIC8qKiBUaGUgU0FYIDxjb2RlPnN0YXJ0UHJlZml4TWFwcGluZzwvY29kZT4gbWV0aG9kLiBEb2VzIG5vdGhpbmcuICovCi0gIHB1YmxpYyB2b2lkIHN0YXJ0UHJlZml4TWFwcGluZyAoU3RyaW5nIHByZWZpeCwgU3RyaW5nIHVyaSkKLSAgICB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICBpZiAoc2F4UGFyc2VyICE9IG51bGwpIHsKLSAgICAgIHNheFBhcnNlci5zdGFydFByZWZpeE1hcHBpbmcgKHByZWZpeCwgdXJpKTsKLSAgICB9Ci0gIH0KLQotICAvKiogVGhlIFNBWCA8Y29kZT5lbmRQcmVmaXhNYXBwaW5nPC9jb2RlPiBtZXRob2QuIERvZXMgbm90aGluZy4gKi8KLSAgcHVibGljIHZvaWQgZW5kUHJlZml4TWFwcGluZyAoU3RyaW5nIHByZWZpeCkKLSAgICB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICBpZiAoc2F4UGFyc2VyICE9IG51bGwpIHsKLSAgICAgIHNheFBhcnNlci5lbmRQcmVmaXhNYXBwaW5nIChwcmVmaXgpOwotICAgIH0KLSAgfQotCi0gIC8qKiBUaGUgU0FYIDxjb2RlPnNraXBwZWRlbnRpdHk8L2NvZGU+IG1ldGhvZC4gRG9lcyBub3RoaW5nLiAqLwotICBwdWJsaWMgdm9pZCBza2lwcGVkRW50aXR5IChTdHJpbmcgbmFtZSkKLSAgICB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICBpZiAoc2F4UGFyc2VyICE9IG51bGwpIHsKLSAgICAgIHNheFBhcnNlci5za2lwcGVkRW50aXR5KG5hbWUpOwotICAgIH0KLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvcmVzb2x2ZXIvcmVhZGVycy9TQVhQYXJzZXJIYW5kbGVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9yZXNvbHZlci9yZWFkZXJzL1NBWFBhcnNlckhhbmRsZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMGQwNzUxMC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9yZXNvbHZlci9yZWFkZXJzL1NBWFBhcnNlckhhbmRsZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE1MCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLy8gU0FYUGFyc2VySGFuZGxlci5qYXZhIC0gQW4gZW50aXR5LXJlc29sdmluZyBEZWZhdWx0SGFuZGxlcgotCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gb3IgaXRzIGxpY2Vuc29ycywKLSAqIGFzIGFwcGxpY2FibGUuCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXNvbHZlci5yZWFkZXJzOwotCi1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLQotaW1wb3J0IG9yZy54bWwuc2F4Lio7Ci1pbXBvcnQgb3JnLnhtbC5zYXguaGVscGVycy4qOwotCi0vKioKLSAqIEFuIGVudGl0eS1yZXNvbHZpbmcgRGVmYXVsdEhhbmRsZXIuCi0gKgotICogPHA+VGhpcyBjbGFzcyBwcm92aWRlcyBhIFNBWFBhcnNlciBEZWZhdWx0SGFuZGxlciB0aGF0IHBlcmZvcm1zCi0gKiBlbnRpdHkgcmVzb2x1dGlvbi4KLSAqIDwvcD4KLSAqCi0gKiBAYXV0aG9yIE5vcm1hbiBXYWxzaAotICogPGEgaHJlZj0ibWFpbHRvOk5vcm1hbi5XYWxzaEBTdW4uQ09NIj5Ob3JtYW4uV2Fsc2hAU3VuLkNPTTwvYT4KLSAqLwotcHVibGljIGNsYXNzIFNBWFBhcnNlckhhbmRsZXIgZXh0ZW5kcyBEZWZhdWx0SGFuZGxlciB7Ci0gIHByaXZhdGUgRW50aXR5UmVzb2x2ZXIgZXIgPSBudWxsOwotICBwcml2YXRlIENvbnRlbnRIYW5kbGVyIGNoID0gbnVsbDsKLQotICBwdWJsaWMgU0FYUGFyc2VySGFuZGxlcigpIHsKLSAgICBzdXBlcigpOwotICB9Ci0KLSAgcHVibGljIHZvaWQgc2V0RW50aXR5UmVzb2x2ZXIoRW50aXR5UmVzb2x2ZXIgZXIpIHsKLSAgICB0aGlzLmVyID0gZXI7Ci0gIH0KLQotICBwdWJsaWMgdm9pZCBzZXRDb250ZW50SGFuZGxlcihDb250ZW50SGFuZGxlciBjaCkgewotICAgIHRoaXMuY2ggPSBjaDsKLSAgfQotCi0gIC8vIEVudGl0eSBSZXNvbHZlcgotICBwdWJsaWMgSW5wdXRTb3VyY2UgcmVzb2x2ZUVudGl0eShTdHJpbmcgcHVibGljSWQsIFN0cmluZyBzeXN0ZW1JZCkKLSAgICB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLQotICAgIGlmIChlciAhPSBudWxsKSB7Ci0gICAgICB0cnkgewotICAgICAgICByZXR1cm4gZXIucmVzb2x2ZUVudGl0eShwdWJsaWNJZCwgc3lzdGVtSWQpOwotICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewotICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigicmVzb2x2ZUVudGl0eSB0aHJldyBJT0V4Y2VwdGlvbiEiKTsKLSAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgIH0KLSAgICB9IGVsc2UgewotICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotICB9Ci0KLSAgLy8gQ29udGVudCBIYW5kbGVyCi0gIHB1YmxpYyB2b2lkIGNoYXJhY3RlcnMoY2hhcltdIGNoLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpCi0gICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0gICAgaWYgKHRoaXMuY2ggIT0gbnVsbCkgewotICAgICAgdGhpcy5jaC5jaGFyYWN0ZXJzKGNoLCBzdGFydCwgbGVuZ3RoKTsKLSAgICB9Ci0gIH0KLQotICBwdWJsaWMgdm9pZCBlbmREb2N1bWVudCgpCi0gICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0gICAgaWYgKGNoICE9IG51bGwpIHsKLSAgICAgIGNoLmVuZERvY3VtZW50KCk7Ci0gICAgfQotICB9Ci0KLSAgcHVibGljIHZvaWQgZW5kRWxlbWVudChTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgbG9jYWxOYW1lLCBTdHJpbmcgcU5hbWUpCi0gICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0gICAgaWYgKGNoICE9IG51bGwpIHsKLSAgICAgIGNoLmVuZEVsZW1lbnQobmFtZXNwYWNlVVJJLCBsb2NhbE5hbWUsIHFOYW1lKTsKLSAgICB9Ci0gIH0KLQotICBwdWJsaWMgdm9pZCBlbmRQcmVmaXhNYXBwaW5nKFN0cmluZyBwcmVmaXgpCi0gICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0gICAgaWYgKGNoICE9IG51bGwpIHsKLSAgICAgIGNoLmVuZFByZWZpeE1hcHBpbmcocHJlZml4KTsKLSAgICB9Ci0gIH0KLQotICBwdWJsaWMgdm9pZCBpZ25vcmFibGVXaGl0ZXNwYWNlKGNoYXJbXSBjaCwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKQotICAgIHRocm93cyBTQVhFeGNlcHRpb24gewotICAgIGlmICh0aGlzLmNoICE9IG51bGwpIHsKLSAgICAgIHRoaXMuY2guaWdub3JhYmxlV2hpdGVzcGFjZShjaCwgc3RhcnQsIGxlbmd0aCk7Ci0gICAgfQotICB9Ci0KLSAgcHVibGljIHZvaWQgcHJvY2Vzc2luZ0luc3RydWN0aW9uKFN0cmluZyB0YXJnZXQsIFN0cmluZyBkYXRhKQotICAgIHRocm93cyBTQVhFeGNlcHRpb24gewotICAgIGlmIChjaCAhPSBudWxsKSB7Ci0gICAgICBjaC5wcm9jZXNzaW5nSW5zdHJ1Y3Rpb24odGFyZ2V0LCBkYXRhKTsKLSAgICB9Ci0gIH0KLQotICBwdWJsaWMgdm9pZCBzZXREb2N1bWVudExvY2F0b3IoTG9jYXRvciBsb2NhdG9yKSB7Ci0gICAgaWYgKGNoICE9IG51bGwpIHsKLSAgICAgIGNoLnNldERvY3VtZW50TG9jYXRvcihsb2NhdG9yKTsKLSAgICB9Ci0gIH0KLQotICBwdWJsaWMgdm9pZCBza2lwcGVkRW50aXR5KFN0cmluZyBuYW1lKQotICAgIHRocm93cyBTQVhFeGNlcHRpb24gewotICAgIGlmIChjaCAhPSBudWxsKSB7Ci0gICAgICBjaC5za2lwcGVkRW50aXR5KG5hbWUpOwotICAgIH0KLSAgfQotCi0gIHB1YmxpYyB2b2lkIHN0YXJ0RG9jdW1lbnQoKQotICAgIHRocm93cyBTQVhFeGNlcHRpb24gewotICAgIGlmIChjaCAhPSBudWxsKSB7Ci0gICAgICBjaC5zdGFydERvY3VtZW50KCk7Ci0gICAgfQotICB9Ci0KLSAgcHVibGljIHZvaWQgc3RhcnRFbGVtZW50KFN0cmluZyBuYW1lc3BhY2VVUkksIFN0cmluZyBsb2NhbE5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcU5hbWUsIEF0dHJpYnV0ZXMgYXR0cykKLSAgICB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICBpZiAoY2ggIT0gbnVsbCkgewotICAgICAgY2guc3RhcnRFbGVtZW50KG5hbWVzcGFjZVVSSSwgbG9jYWxOYW1lLCBxTmFtZSwgYXR0cyk7Ci0gICAgfQotICB9Ci0KLSAgcHVibGljIHZvaWQgc3RhcnRQcmVmaXhNYXBwaW5nKFN0cmluZyBwcmVmaXgsIFN0cmluZyB1cmkpCi0gICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0gICAgaWYgKGNoICE9IG51bGwpIHsKLSAgICAgIGNoLnN0YXJ0UHJlZml4TWFwcGluZyhwcmVmaXgsIHVyaSk7Ci0gICAgfQotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9yZXNvbHZlci9yZWFkZXJzL1RSOTQwMUNhdGFsb2dSZWFkZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3Jlc29sdmVyL3JlYWRlcnMvVFI5NDAxQ2F0YWxvZ1JlYWRlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiMjc0ODEwLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3Jlc29sdmVyL3JlYWRlcnMvVFI5NDAxQ2F0YWxvZ1JlYWRlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTQzICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vLyBUUjk0MDFDYXRhbG9nUmVhZGVyLmphdmEgLSBSZWFkIE9BU0lTIENhdGFsb2cgZmlsZXMKLQotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIG9yIGl0cyBsaWNlbnNvcnMsCi0gKiBhcyBhcHBsaWNhYmxlLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzb2x2ZXIucmVhZGVyczsKLQotaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLm5ldC5NYWxmb3JtZWRVUkxFeGNlcHRpb247Ci1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnJlc29sdmVyLkNhdGFsb2c7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXNvbHZlci5DYXRhbG9nRW50cnk7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXNvbHZlci5DYXRhbG9nRXhjZXB0aW9uOwotCi0vKioKLSAqIFBhcnNlcyBPQVNJUyBPcGVuIENhdGFsb2cgZmlsZXMuCi0gKgotICogPHA+VGhpcyBjbGFzcyByZWFkcyBPQVNJUyBPcGVuIENhdGFsb2cgZmlsZXMsIHJldHVybmluZyBhIHN0cmVhbQotICogb2YgdG9rZW5zLjwvcD4KLSAqCi0gKiA8cD5UaGlzIGNvZGUgaW50ZXJyb2dhdGVzIHRoZSBmb2xsb3dpbmcgbm9uLXN0YW5kYXJkIHN5c3RlbSBwcm9wZXJ0aWVzOjwvcD4KLSAqCi0gKiA8ZGw+Ci0gKiA8ZHQ+PGI+eG1sLmNhdGFsb2cuZGVidWc8L2I+PC9kdD4KLSAqIDxkZD48cD5TZXRzIHRoZSBkZWJ1ZyBsZXZlbC4gQSB2YWx1ZSBvZiAwIGlzIGFzc3VtZWQgaWYgdGhlCi0gKiBwcm9wZXJ0eSBpcyBub3Qgc2V0IG9yIGlzIG5vdCBhIG51bWJlci48L3A+PC9kZD4KLSAqIDwvZGw+Ci0gKgotICogQHNlZSBDYXRhbG9nCi0gKgotICogQGF1dGhvciBOb3JtYW4gV2Fsc2gKLSAqIDxhIGhyZWY9Im1haWx0bzpOb3JtYW4uV2Fsc2hAU3VuLkNPTSI+Tm9ybWFuLldhbHNoQFN1bi5DT008L2E+Ci0gKgotICovCi1wdWJsaWMgY2xhc3MgVFI5NDAxQ2F0YWxvZ1JlYWRlciBleHRlbmRzIFRleHRDYXRhbG9nUmVhZGVyIHsKLQotICAvKioKLSAgICogU3RhcnQgcGFyc2luZyBhbiBPQVNJUyBUUjk0MDEgT3BlbiBDYXRhbG9nIGZpbGUuIFRoZSBmaWxlIGlzCi0gICAqIGFjdHVhbGx5IHJlYWQgYW5kIHBhcnNlZAotICAgKiBhcyBuZWVkZWQgYnkgPGNvZGU+bmV4dEVudHJ5PC9jb2RlPi4KLSAgICoKLSAgICogPHA+SW4gYSBUUjk0MDEgQ2F0YWxvZyB0aGUgJ0RFTEVHQVRFJyBlbnRyeSBkZWxlZ2F0ZXMgcHVibGljCi0gICAqIGlkZW50aWZpZXJzLiBUaGVyZSBpcyBubyBkZWxlZ2F0ZSBlbnRyeSBmb3Igc3lzdGVtIGlkZW50aWZpZXJzCi0gICAqIG9yIFVSSXMuPC9wPgotICAgKgotICAgKiBAcGFyYW0gY2F0YWxvZyBUaGUgQ2F0YWxvZyB0byBwb3B1bGF0ZQotICAgKiBAcGFyYW0gaXMgVGhlIGlucHV0IHN0cmVhbSBmcm9tIHdoaWNoIHRvIHJlYWQgdGhlIFRSOTQwMSBDYXRhbG9nCi0gICAqCi0gICAqIEB0aHJvd3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uIEltcHJvcGVyIGZpbGVVcmwKLSAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBFcnJvciByZWFkaW5nIGNhdGFsb2cgZmlsZQotICAgKi8KLSAgcHVibGljIHZvaWQgcmVhZENhdGFsb2coQ2F0YWxvZyBjYXRhbG9nLCBJbnB1dFN0cmVhbSBpcykKLSAgICB0aHJvd3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7Ci0KLSAgICBjYXRmaWxlID0gaXM7Ci0KLSAgICBpZiAoY2F0ZmlsZSA9PSBudWxsKSB7Ci0gICAgICByZXR1cm47Ci0gICAgfQotCi0gICAgVmVjdG9yIHVua25vd25FbnRyeSA9IG51bGw7Ci0KLSAgICB0cnkgewotICAgICAgd2hpbGUgKHRydWUpIHsKLSAgICAgICAgU3RyaW5nIHRva2VuID0gbmV4dFRva2VuKCk7Ci0KLSAgICAgICAgaWYgKHRva2VuID09IG51bGwpIHsKLSAgICAgICAgICBpZiAodW5rbm93bkVudHJ5ICE9IG51bGwpIHsKLSAgICAgICAgICAgIGNhdGFsb2cudW5rbm93bkVudHJ5KHVua25vd25FbnRyeSk7Ci0gICAgICAgICAgICB1bmtub3duRW50cnkgPSBudWxsOwotICAgICAgICAgIH0KLSAgICAgICAgICBjYXRmaWxlLmNsb3NlKCk7Ci0gICAgICAgICAgY2F0ZmlsZSA9IG51bGw7Ci0gICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0KLSAgICAgICAgU3RyaW5nIGVudHJ5VG9rZW4gPSBudWxsOwotICAgICAgICBpZiAoY2FzZVNlbnNpdGl2ZSkgewotICAgICAgICAgIGVudHJ5VG9rZW4gPSB0b2tlbjsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICBlbnRyeVRva2VuID0gdG9rZW4udG9VcHBlckNhc2UoKTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChlbnRyeVRva2VuLmVxdWFscygiREVMRUdBVEUiKSkgewotICAgICAgICAgIGVudHJ5VG9rZW4gPSAiREVMRUdBVEVfUFVCTElDIjsKLSAgICAgICAgfQotCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgaW50IHR5cGUgPSBDYXRhbG9nRW50cnkuZ2V0RW50cnlUeXBlKGVudHJ5VG9rZW4pOwotICAgICAgICAgIGludCBudW1BcmdzID0gQ2F0YWxvZ0VudHJ5LmdldEVudHJ5QXJnQ291bnQodHlwZSk7Ci0gICAgICAgICAgVmVjdG9yIGFyZ3MgPSBuZXcgVmVjdG9yKCk7Ci0KLSAgICAgICAgICBpZiAodW5rbm93bkVudHJ5ICE9IG51bGwpIHsKLSAgICAgICAgICAgIGNhdGFsb2cudW5rbm93bkVudHJ5KHVua25vd25FbnRyeSk7Ci0gICAgICAgICAgICB1bmtub3duRW50cnkgPSBudWxsOwotICAgICAgICAgIH0KLQotICAgICAgICAgIGZvciAoaW50IGNvdW50ID0gMDsgY291bnQgPCBudW1BcmdzOyBjb3VudCsrKSB7Ci0gICAgICAgICAgICBhcmdzLmFkZEVsZW1lbnQobmV4dFRva2VuKCkpOwotICAgICAgICAgIH0KLQotICAgICAgICAgIGNhdGFsb2cuYWRkRW50cnkobmV3IENhdGFsb2dFbnRyeShlbnRyeVRva2VuLCBhcmdzKSk7Ci0gICAgICAgIH0gY2F0Y2ggKENhdGFsb2dFeGNlcHRpb24gY2V4KSB7Ci0gICAgICAgICAgaWYgKGNleC5nZXRFeGNlcHRpb25UeXBlKCkgPT0gQ2F0YWxvZ0V4Y2VwdGlvbi5JTlZBTElEX0VOVFJZX1RZUEUpIHsKLSAgICAgICAgICAgIGlmICh1bmtub3duRW50cnkgPT0gbnVsbCkgewotICAgICAgICAgICAgICB1bmtub3duRW50cnkgPSBuZXcgVmVjdG9yKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICB1bmtub3duRW50cnkuYWRkRWxlbWVudCh0b2tlbik7Ci0gICAgICAgICAgfSBlbHNlIGlmIChjZXguZ2V0RXhjZXB0aW9uVHlwZSgpID09IENhdGFsb2dFeGNlcHRpb24uSU5WQUxJRF9FTlRSWSkgewotICAgICAgICAgICAgY2F0YWxvZy5nZXRDYXRhbG9nTWFuYWdlcigpLmRlYnVnLm1lc3NhZ2UoMSwgIkludmFsaWQgY2F0YWxvZyBlbnRyeSIsIHRva2VuKTsKLSAgICAgICAgICAgIHVua25vd25FbnRyeSA9IG51bGw7Ci0gICAgICAgICAgfSBlbHNlIGlmIChjZXguZ2V0RXhjZXB0aW9uVHlwZSgpID09IENhdGFsb2dFeGNlcHRpb24uVU5FTkRFRF9DT01NRU5UKSB7Ci0gICAgICAgICAgICBjYXRhbG9nLmdldENhdGFsb2dNYW5hZ2VyKCkuZGVidWcubWVzc2FnZSgxLCBjZXguZ2V0TWVzc2FnZSgpKTsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICB9IGNhdGNoIChDYXRhbG9nRXhjZXB0aW9uIGNleDIpIHsKLSAgICAgIGlmIChjZXgyLmdldEV4Y2VwdGlvblR5cGUoKSA9PSBDYXRhbG9nRXhjZXB0aW9uLlVORU5ERURfQ09NTUVOVCkgewotICAgICAgICBjYXRhbG9nLmdldENhdGFsb2dNYW5hZ2VyKCkuZGVidWcubWVzc2FnZSgxLCBjZXgyLmdldE1lc3NhZ2UoKSk7Ci0gICAgICB9Ci0gICAgfQotCi0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3Jlc29sdmVyL3JlYWRlcnMvVGV4dENhdGFsb2dSZWFkZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3Jlc29sdmVyL3JlYWRlcnMvVGV4dENhdGFsb2dSZWFkZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMzQ5M2U0OC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9yZXNvbHZlci9yZWFkZXJzL1RleHRDYXRhbG9nUmVhZGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzMDMgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8vIFRleHRDYXRhbG9nUmVhZGVyLmphdmEgLSBSZWFkIHRleHQvcGxhaW4gQ2F0YWxvZyBmaWxlcwotCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gb3IgaXRzIGxpY2Vuc29ycywKLSAqIGFzIGFwcGxpY2FibGUuCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXNvbHZlci5yZWFkZXJzOwotCi1pbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotaW1wb3J0IGphdmEuaW8uRmlsZU5vdEZvdW5kRXhjZXB0aW9uOwotaW1wb3J0IGphdmEubmV0LlVSTDsKLWltcG9ydCBqYXZhLm5ldC5VUkxDb25uZWN0aW9uOwotaW1wb3J0IGphdmEubmV0Lk1hbGZvcm1lZFVSTEV4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotaW1wb3J0IGphdmEudXRpbC5TdGFjazsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnJlc29sdmVyLkNhdGFsb2c7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXNvbHZlci5DYXRhbG9nRW50cnk7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXNvbHZlci5DYXRhbG9nRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzb2x2ZXIucmVhZGVycy5DYXRhbG9nUmVhZGVyOwotCi0vKioKLSAqIFBhcnNlcyBwbGFpbiB0ZXh0IENhdGFsb2cgZmlsZXMuCi0gKgotICogPHA+VGhpcyBjbGFzcyByZWFkcyBwbGFpbiB0ZXh0IE9wZW4gQ2F0YWxvZyBmaWxlcy48L3A+Ci0gKgotICogQHNlZSBDYXRhbG9nCi0gKgotICogQGF1dGhvciBOb3JtYW4gV2Fsc2gKLSAqIDxhIGhyZWY9Im1haWx0bzpOb3JtYW4uV2Fsc2hAU3VuLkNPTSI+Tm9ybWFuLldhbHNoQFN1bi5DT008L2E+Ci0gKgotICovCi1wdWJsaWMgY2xhc3MgVGV4dENhdGFsb2dSZWFkZXIgaW1wbGVtZW50cyBDYXRhbG9nUmVhZGVyIHsKLSAgLyoqIFRoZSBpbnB1dCBzdHJlYW0gdXNlZCB0byByZWFkIHRoZSBjYXRhbG9nICovCi0gIHByb3RlY3RlZCBJbnB1dFN0cmVhbSBjYXRmaWxlID0gbnVsbDsKLQotICAvKioKLSAgICogQ2hhcmFjdGVyIGxvb2thaGVhZCBzdGFjay4gUmVhZGluZyBhIGNhdGFsb2cgc29tZXRpbWVzIHJlcXVpcmVzCi0gICAqIHVwIHRvIHR3byBjaGFyYWN0ZXJzIG9mIGxvb2thaGVhZC4KLSAgICovCi0gIHByb3RlY3RlZCBpbnRbXSBzdGFjayA9IG5ldyBpbnRbM107Ci0KLSAgLyoqCi0gICAqIFRva2VuIHN0YWNrLiBSZWNvZ25pemluZyBhbiB1bmV4cGVjdGVkIGNhdGFsb2cgZW50cnkgcmVxdWlyZXMKLSAgICogdGhlIGFiaWxpdHkgdG8gInB1c2ggYmFjayIgYSB0b2tlbi4KLSAgICovCi0gIHByb3RlY3RlZCBTdGFjayB0b2tlblN0YWNrID0gbmV3IFN0YWNrKCk7Ci0KLSAgLyoqIFRoZSBjdXJyZW50IHBvc2l0aW9uIG9uIHRoZSBsb29rYWhlYWQgc3RhY2sgKi8KLSAgcHJvdGVjdGVkIGludCB0b3AgPSAtMTsKLQotICAvKiogQXJlIGtleXdvcmRzIGluIHRoZSBjYXRhbG9nIGNhc2Ugc2Vuc2l0aXZlPyAqLwotICBwcm90ZWN0ZWQgYm9vbGVhbiBjYXNlU2Vuc2l0aXZlID0gZmFsc2U7Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhIENhdGFsb2dSZWFkZXIgb2JqZWN0LgotICAgKi8KLSAgcHVibGljIFRleHRDYXRhbG9nUmVhZGVyKCkgeyB9Ci0KLSAgcHVibGljIHZvaWQgc2V0Q2FzZVNlbnNpdGl2ZShib29sZWFuIGlzQ2FzZVNlbnNpdGl2ZSkgewotICAgIGNhc2VTZW5zaXRpdmUgPSBpc0Nhc2VTZW5zaXRpdmU7Ci0gIH0KLQotICBwdWJsaWMgYm9vbGVhbiBnZXRDYXNlU2Vuc2l0aXZlKCkgewotICAgIHJldHVybiBjYXNlU2Vuc2l0aXZlOwotICB9Ci0KLSAgLyoqCi0gICAqIFN0YXJ0IHBhcnNpbmcgYSB0ZXh0IGNhdGFsb2cgZmlsZS4gVGhlIGZpbGUgaXMKLSAgICogYWN0dWFsbHkgcmVhZCBhbmQgcGFyc2VkCi0gICAqIGFzIG5lZWRlZCBieSA8Y29kZT5uZXh0RW50cnk8L2NvZGU+LjwvcD4KLSAgICoKLSAgICogQHBhcmFtIGZpbGVVcmwgIFRoZSBVUkwgb3IgZmlsZW5hbWUgb2YgdGhlIGNhdGFsb2cgZmlsZSB0byBwcm9jZXNzCi0gICAqCi0gICAqIEB0aHJvd3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uIEltcHJvcGVyIGZpbGVVcmwKLSAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBFcnJvciByZWFkaW5nIGNhdGFsb2cgZmlsZQotICAgKi8KLSAgcHVibGljIHZvaWQgcmVhZENhdGFsb2coQ2F0YWxvZyBjYXRhbG9nLCBTdHJpbmcgZmlsZVVybCkKLSAgICB0aHJvd3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7Ci0gICAgVVJMIGNhdFVSTCA9IG51bGw7Ci0KLSAgICB0cnkgewotICAgICAgY2F0VVJMID0gbmV3IFVSTChmaWxlVXJsKTsKLSAgICB9IGNhdGNoIChNYWxmb3JtZWRVUkxFeGNlcHRpb24gZSkgewotICAgICAgY2F0VVJMID0gbmV3IFVSTCgiZmlsZTovLy8iICsgZmlsZVVybCk7Ci0gICAgfQotCi0gICAgVVJMQ29ubmVjdGlvbiB1cmxDb24gPSBjYXRVUkwub3BlbkNvbm5lY3Rpb24oKTsKLSAgICB0cnkgewotICAgICAgcmVhZENhdGFsb2coY2F0YWxvZywgdXJsQ29uLmdldElucHV0U3RyZWFtKCkpOwotICAgIH0gY2F0Y2ggKEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiBlKSB7Ci0gICAgICBjYXRhbG9nLmdldENhdGFsb2dNYW5hZ2VyKCkuZGVidWcubWVzc2FnZSgxLCAiRmFpbGVkIHRvIGxvYWQgY2F0YWxvZywgZmlsZSBub3QgZm91bmQiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2F0VVJMLnRvU3RyaW5nKCkpOwotICAgIH0KLSAgfQotCi0gIHB1YmxpYyB2b2lkIHJlYWRDYXRhbG9nKENhdGFsb2cgY2F0YWxvZywgSW5wdXRTdHJlYW0gaXMpCi0gICAgdGhyb3dzIE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewotCi0gICAgY2F0ZmlsZSA9IGlzOwotCi0gICAgaWYgKGNhdGZpbGUgPT0gbnVsbCkgewotICAgICAgcmV0dXJuOwotICAgIH0KLQotICAgIFZlY3RvciB1bmtub3duRW50cnkgPSBudWxsOwotCi0gICAgdHJ5IHsKLSAgICAgIHdoaWxlICh0cnVlKSB7Ci0gICAgICAgIFN0cmluZyB0b2tlbiA9IG5leHRUb2tlbigpOwotCi0gICAgICAgIGlmICh0b2tlbiA9PSBudWxsKSB7Ci0gICAgICAgICAgaWYgKHVua25vd25FbnRyeSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBjYXRhbG9nLnVua25vd25FbnRyeSh1bmtub3duRW50cnkpOwotICAgICAgICAgICAgdW5rbm93bkVudHJ5ID0gbnVsbDsKLSAgICAgICAgICB9Ci0gICAgICAgICAgY2F0ZmlsZS5jbG9zZSgpOwotICAgICAgICAgIGNhdGZpbGUgPSBudWxsOwotICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotCi0gICAgICAgIFN0cmluZyBlbnRyeVRva2VuID0gbnVsbDsKLSAgICAgICAgaWYgKGNhc2VTZW5zaXRpdmUpIHsKLSAgICAgICAgICBlbnRyeVRva2VuID0gdG9rZW47Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgZW50cnlUb2tlbiA9IHRva2VuLnRvVXBwZXJDYXNlKCk7Ci0gICAgICAgIH0KLQotICAgICAgICB0cnkgewotICAgICAgICAgIGludCB0eXBlID0gQ2F0YWxvZ0VudHJ5LmdldEVudHJ5VHlwZShlbnRyeVRva2VuKTsKLSAgICAgICAgICBpbnQgbnVtQXJncyA9IENhdGFsb2dFbnRyeS5nZXRFbnRyeUFyZ0NvdW50KHR5cGUpOwotICAgICAgICAgIFZlY3RvciBhcmdzID0gbmV3IFZlY3RvcigpOwotCi0gICAgICAgICAgaWYgKHVua25vd25FbnRyeSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBjYXRhbG9nLnVua25vd25FbnRyeSh1bmtub3duRW50cnkpOwotICAgICAgICAgICAgdW5rbm93bkVudHJ5ID0gbnVsbDsKLSAgICAgICAgICB9Ci0KLSAgICAgICAgICBmb3IgKGludCBjb3VudCA9IDA7IGNvdW50IDwgbnVtQXJnczsgY291bnQrKykgewotICAgICAgICAgICAgYXJncy5hZGRFbGVtZW50KG5leHRUb2tlbigpKTsKLSAgICAgICAgICB9Ci0KLSAgICAgICAgICBjYXRhbG9nLmFkZEVudHJ5KG5ldyBDYXRhbG9nRW50cnkoZW50cnlUb2tlbiwgYXJncykpOwotICAgICAgICB9IGNhdGNoIChDYXRhbG9nRXhjZXB0aW9uIGNleCkgewotICAgICAgICAgIGlmIChjZXguZ2V0RXhjZXB0aW9uVHlwZSgpID09IENhdGFsb2dFeGNlcHRpb24uSU5WQUxJRF9FTlRSWV9UWVBFKSB7Ci0gICAgICAgICAgICBpZiAodW5rbm93bkVudHJ5ID09IG51bGwpIHsKLSAgICAgICAgICAgICAgdW5rbm93bkVudHJ5ID0gbmV3IFZlY3RvcigpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgdW5rbm93bkVudHJ5LmFkZEVsZW1lbnQodG9rZW4pOwotICAgICAgICAgIH0gZWxzZSBpZiAoY2V4LmdldEV4Y2VwdGlvblR5cGUoKSA9PSBDYXRhbG9nRXhjZXB0aW9uLklOVkFMSURfRU5UUlkpIHsKLSAgICAgICAgICAgIGNhdGFsb2cuZ2V0Q2F0YWxvZ01hbmFnZXIoKS5kZWJ1Zy5tZXNzYWdlKDEsICJJbnZhbGlkIGNhdGFsb2cgZW50cnkiLCB0b2tlbik7Ci0gICAgICAgICAgICB1bmtub3duRW50cnkgPSBudWxsOwotICAgICAgICAgIH0gZWxzZSBpZiAoY2V4LmdldEV4Y2VwdGlvblR5cGUoKSA9PSBDYXRhbG9nRXhjZXB0aW9uLlVORU5ERURfQ09NTUVOVCkgewotICAgICAgICAgICAgY2F0YWxvZy5nZXRDYXRhbG9nTWFuYWdlcigpLmRlYnVnLm1lc3NhZ2UoMSwgY2V4LmdldE1lc3NhZ2UoKSk7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfSBjYXRjaCAoQ2F0YWxvZ0V4Y2VwdGlvbiBjZXgyKSB7Ci0gICAgICBpZiAoY2V4Mi5nZXRFeGNlcHRpb25UeXBlKCkgPT0gQ2F0YWxvZ0V4Y2VwdGlvbi5VTkVOREVEX0NPTU1FTlQpIHsKLSAgICAgICAgY2F0YWxvZy5nZXRDYXRhbG9nTWFuYWdlcigpLmRlYnVnLm1lc3NhZ2UoMSwgY2V4Mi5nZXRNZXNzYWdlKCkpOwotICAgICAgfQotICAgIH0KLSAgfQotCi0gIC8qKgotICAgICAqIFRoZSBkZXN0cnVjdG9yLgotICAgICAqCi0gICAgICogPHA+TWFrZXMgc3VyZSB0aGUgY2F0YWxvZyBmaWxlIGlzIGNsb3NlZC48L3A+Ci0gICAgICovCi0gIHByb3RlY3RlZCB2b2lkIGZpbmFsaXplKCkgewotICAgIGlmIChjYXRmaWxlICE9IG51bGwpIHsKLSAgICAgIHRyeSB7Ci0gICAgICAgIGNhdGZpbGUuY2xvc2UoKTsKLSAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgLy8gd2hhdGV2ZXIuLi4KLSAgICAgIH0KLSAgICB9Ci0gICAgY2F0ZmlsZSA9IG51bGw7Ci0gIH0KLQotICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSBuZXh0IHRva2VuIGluIHRoZSBjYXRhbG9nIGZpbGUuCi0gICAgICoKLSAgICAgKiA8cD5GWUk6IFRoaXMgY29kZSBkb2VzIG5vdCB0aHJvdyBhbnkgc29ydCBvZiBleGNlcHRpb24gZm9yCi0gICAgICogYSBmaWxlIHRoYXQgY29udGFpbnMgYW4gbgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgQ2F0YWxvZyBmaWxlIHRva2VuIGZyb20gdGhlIGlucHV0IHN0cmVhbS4KLSAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIElmIGFuIGVycm9yIG9jY3VycyByZWFkaW5nIGZyb20gdGhlIHN0cmVhbS4KLSAgICAgKi8KLSAgcHJvdGVjdGVkIFN0cmluZyBuZXh0VG9rZW4oKSB0aHJvd3MgSU9FeGNlcHRpb24sIENhdGFsb2dFeGNlcHRpb24gewotICAgIFN0cmluZyB0b2tlbiA9ICIiOwotICAgIGludCBjaCwgbmV4dGNoOwotCi0gICAgaWYgKCF0b2tlblN0YWNrLmVtcHR5KCkpIHsKLSAgICAgIHJldHVybiAoU3RyaW5nKSB0b2tlblN0YWNrLnBvcCgpOwotICAgIH0KLQotICAgIC8vIFNraXAgb3ZlciBsZWFkaW5nIHdoaXRlc3BhY2UgYW5kIGNvbW1lbnRzCi0gICAgd2hpbGUgKHRydWUpIHsKLSAgICAgIC8vIHNraXAgbGVhZGluZyB3aGl0ZXNwYWNlCi0gICAgICBjaCA9IGNhdGZpbGUucmVhZCgpOwotICAgICAgd2hpbGUgKGNoIDw9ICcgJykgeyAgICAgIC8vIGFsbCBjdHJscyBhcmUgd2hpdGVzcGFjZQotICAgICAgICBjaCA9IGNhdGZpbGUucmVhZCgpOwotICAgICAgICBpZiAoY2ggPCAwKSB7Ci0gICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLSAgICAgIH0KLQotICAgICAgLy8gbm93ICdjaCcgaXMgdGhlIGN1cnJlbnQgY2hhciBmcm9tIHRoZSBmaWxlCi0gICAgICBuZXh0Y2ggPSBjYXRmaWxlLnJlYWQoKTsKLSAgICAgIGlmIChuZXh0Y2ggPCAwKSB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgICAgfQotCi0gICAgICBpZiAoY2ggPT0gJy0nICYmIG5leHRjaCA9PSAnLScpIHsKLSAgICAgICAgLy8gd2UndmUgZm91bmQgYSBjb21tZW50LCBza2lwIGl0Li4uCi0gICAgICAgIGNoID0gJyAnOwotICAgICAgICBuZXh0Y2ggPSBuZXh0Q2hhcigpOwotICAgICAgICB3aGlsZSAoKGNoICE9ICctJyB8fCBuZXh0Y2ggIT0gJy0nKSAmJiBuZXh0Y2ggPiAwKSB7Ci0gICAgICAgICAgY2ggPSBuZXh0Y2g7Ci0gICAgICAgICAgbmV4dGNoID0gbmV4dENoYXIoKTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChuZXh0Y2ggPCAwKSB7Ci0gICAgICAgICAgdGhyb3cgbmV3IENhdGFsb2dFeGNlcHRpb24oQ2F0YWxvZ0V4Y2VwdGlvbi5VTkVOREVEX0NPTU1FTlQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlVudGVybWluYXRlZCBjb21tZW50IGluIGNhdGFsb2cgZmlsZTsgRU9GIHRyZWF0ZWQgYXMgZW5kLW9mLWNvbW1lbnQuIik7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBPaywgd2UndmUgZm91bmQgdGhlIGVuZCBvZiB0aGUgY29tbWVudCwKLSAgICAgICAgLy8gbG9vcCBiYWNrIHRvIHRoZSB0b3AgYW5kIHN0YXJ0IGFnYWluLi4uCi0gICAgICB9IGVsc2UgewotICAgICAgICBzdGFja1srK3RvcF0gPSBuZXh0Y2g7Ci0gICAgICAgIHN0YWNrWysrdG9wXSA9IGNoOwotICAgICAgICBicmVhazsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICBjaCA9IG5leHRDaGFyKCk7Ci0gICAgaWYgKGNoID09ICciJyB8fCBjaCA9PSAnXCcnKSB7Ci0gICAgICBpbnQgcXVvdGUgPSBjaDsKLSAgICAgIHdoaWxlICgoY2ggPSBuZXh0Q2hhcigpKSAhPSBxdW90ZSkgewotICAgICAgICBjaGFyW10gY2hhcmFyciA9IG5ldyBjaGFyWzFdOwotICAgICAgICBjaGFyYXJyWzBdID0gKGNoYXIpIGNoOwotICAgICAgICBTdHJpbmcgcyA9IG5ldyBTdHJpbmcoY2hhcmFycik7Ci0gICAgICAgIHRva2VuID0gdG9rZW4uY29uY2F0KHMpOwotICAgICAgfQotICAgICAgcmV0dXJuIHRva2VuOwotICAgIH0gZWxzZSB7Ci0gICAgICAvLyByZXR1cm4gdGhlIG5leHQgd2hpdGVzcGFjZSBvciBjb21tZW50IGRlbGltaXRlZAotICAgICAgLy8gc3RyaW5nCi0gICAgICB3aGlsZSAoY2ggPiAnICcpIHsKLSAgICAgICAgbmV4dGNoID0gbmV4dENoYXIoKTsKLSAgICAgICAgaWYgKGNoID09ICctJyAmJiBuZXh0Y2ggPT0gJy0nKSB7Ci0gICAgICAgICAgc3RhY2tbKyt0b3BdID0gY2g7Ci0gICAgICAgICAgc3RhY2tbKyt0b3BdID0gbmV4dGNoOwotICAgICAgICAgIHJldHVybiB0b2tlbjsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICBjaGFyW10gY2hhcmFyciA9IG5ldyBjaGFyWzFdOwotICAgICAgICAgIGNoYXJhcnJbMF0gPSAoY2hhcikgY2g7Ci0gICAgICAgICAgU3RyaW5nIHMgPSBuZXcgU3RyaW5nKGNoYXJhcnIpOwotICAgICAgICAgIHRva2VuID0gdG9rZW4uY29uY2F0KHMpOwotICAgICAgICAgIGNoID0gbmV4dGNoOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgICByZXR1cm4gdG9rZW47Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAgICogUmV0dXJuIHRoZSBuZXh0IGxvZ2ljYWwgY2hhcmFjdGVyIGZyb20gdGhlIGlucHV0IHN0cmVhbS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIG5leHQgKGxvZ2ljYWwpIGNoYXJhY3RlciBmcm9tIHRoZSBpbnB1dCBzdHJlYW0uIFRoZQotICAgICAqIGNoYXJhY3RlciBtYXkgYmUgYnVmZmVyZWQgZnJvbSBhIHByZXZpb3VzIGxvb2thaGVhZC4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gSWYgYW4gZXJyb3Igb2NjdXJzIHJlYWRpbmcgZnJvbSB0aGUgc3RyZWFtLgotICAgICAqLwotICBwcm90ZWN0ZWQgaW50IG5leHRDaGFyKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLSAgICBpZiAodG9wIDwgMCkgewotICAgICAgcmV0dXJuIGNhdGZpbGUucmVhZCgpOwotICAgIH0gZWxzZSB7Ci0gICAgICByZXR1cm4gc3RhY2tbdG9wLS1dOwotICAgIH0KLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvcmVzb2x2ZXIvcmVhZGVycy9YQ2F0YWxvZ1JlYWRlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvcmVzb2x2ZXIvcmVhZGVycy9YQ2F0YWxvZ1JlYWRlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzZDk0NTQ1Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3Jlc29sdmVyL3JlYWRlcnMvWENhdGFsb2dSZWFkZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE4OCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLy8gWENhdGFsb2dSZWFkZXIuamF2YSAtIFJlYWQgWE1MIENhdGFsb2cgZmlsZXMKLQotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIG9yIGl0cyBsaWNlbnNvcnMsCi0gKiBhcyBhcHBsaWNhYmxlLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzb2x2ZXIucmVhZGVyczsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXNvbHZlci5DYXRhbG9nOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzb2x2ZXIuQ2F0YWxvZ0VudHJ5OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzb2x2ZXIuQ2F0YWxvZ0V4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnJlc29sdmVyLmhlbHBlcnMuUHVibGljSWQ7Ci0KLWltcG9ydCBvcmcueG1sLnNheC4qOwotCi1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuKjsKLQotLyoqCi0gKiBQYXJzZSAieGNhdGFsb2ciIFhNTCBDYXRhbG9nIGZpbGVzLCB0aGlzIGlzIHRoZSBYTUwgQ2F0YWxvZyBmb3JtYXQKLSAqIGRldmVsb3BlZCBieSBKb2huIENvd2FuIGFuZCBzdXBwb3J0ZWQgYnkgQXBhY2hlLgotICoKLSAqIEBzZWUgQ2F0YWxvZwotICoKLSAqIEBhdXRob3IgTm9ybWFuIFdhbHNoCi0gKiA8YSBocmVmPSJtYWlsdG86Tm9ybWFuLldhbHNoQFN1bi5DT00iPk5vcm1hbi5XYWxzaEBTdW4uQ09NPC9hPgotICoKLSAqLwotcHVibGljIGNsYXNzIFhDYXRhbG9nUmVhZGVyIGV4dGVuZHMgU0FYQ2F0YWxvZ1JlYWRlciBpbXBsZW1lbnRzIFNBWENhdGFsb2dQYXJzZXIgewotICAvKiogVGhlIGNhdGFsb2cgb2JqZWN0IG5lZWRzIHRvIGJlIHN0b3JlZCBieSB0aGUgb2JqZWN0IHNvIHRoYXQKLSAgICogU0FYIGNhbGxiYWNrcyBjYW4gdXNlIGl0LgotICAgKi8KLSAgcHJvdGVjdGVkIENhdGFsb2cgY2F0YWxvZyA9IG51bGw7Ci0KLSAgLyoqIFNldCB0aGUgY3VycmVudCBjYXRhbG9nLiAqLwotICBwdWJsaWMgdm9pZCBzZXRDYXRhbG9nIChDYXRhbG9nIGNhdGFsb2cpIHsKLSAgICB0aGlzLmNhdGFsb2cgPSBjYXRhbG9nOwotICB9Ci0KLSAgLyoqIEdldCB0aGUgY3VycmVudCBjYXRhbG9nLiAqLwotICBwdWJsaWMgQ2F0YWxvZyBnZXRDYXRhbG9nICgpIHsKLSAgICByZXR1cm4gY2F0YWxvZzsKLSAgfQotCi0gIC8qKiBUaGUgY29uc3RydWN0b3IgKi8KLSAgcHVibGljIFhDYXRhbG9nUmVhZGVyKFNBWFBhcnNlckZhY3RvcnkgcGFyc2VyRmFjdG9yeSkgewotICAgIHN1cGVyKHBhcnNlckZhY3RvcnkpOwotICB9Ci0KLSAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAvLyBJbXBsZW1lbnQgdGhlIFNBWCBEb2N1bWVudEhhbmRsZXIgaW50ZXJmYWNlCi0KLSAgLyoqIFRoZSBTQVggPGNvZGU+c2V0RG9jdW1lbnRMb2NhdG9yPC9jb2RlPiBtZXRob2QgZG9lcyBub3RoaW5nLiAqLwotICBwdWJsaWMgdm9pZCBzZXREb2N1bWVudExvY2F0b3IgKExvY2F0b3IgbG9jYXRvcikgewotICAgIHJldHVybjsKLSAgfQotCi0gIC8qKiBUaGUgU0FYIDxjb2RlPnN0YXJ0RG9jdW1lbnQ8L2NvZGU+IG1ldGhvZCBkb2VzIG5vdGhpbmcuICovCi0gIHB1YmxpYyB2b2lkIHN0YXJ0RG9jdW1lbnQgKCkKLSAgICB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICByZXR1cm47Ci0gIH0KLQotICAvKiogVGhlIFNBWCA8Y29kZT5lbmREb2N1bWVudDwvY29kZT4gbWV0aG9kIGRvZXMgbm90aGluZy4gKi8KLSAgcHVibGljIHZvaWQgZW5kRG9jdW1lbnQgKCkKLSAgICB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICByZXR1cm47Ci0gIH0KLQotICAvKioKLSAgICogVGhlIFNBWCA8Y29kZT5zdGFydEVsZW1lbnQ8L2NvZGU+IG1ldGhvZCByZWNvZ25pemVzIGVsZW1lbnRzCi0gICAqIGZyb20gdGhlIHBsYWluIGNhdGFsb2cgZm9ybWF0IGFuZCBpbnN0YW50aWF0ZXMgQ2F0YWxvZ0VudHJ5Ci0gICAqIG9iamVjdHMgZm9yIHRoZW0uCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkgVGhlIG5hbWVzcGFjZSBuYW1lIG9mIHRoZSBlbGVtZW50LgotICAgKiBAcGFyYW0gbG9jYWxOYW1lIFRoZSBsb2NhbCBuYW1lIG9mIHRoZSBlbGVtZW50LgotICAgKiBAcGFyYW0gcU5hbWUgVGhlIFFOYW1lIG9mIHRoZSBlbGVtZW50LgotICAgKiBAcGFyYW0gYXR0cyBUaGUgbGlzdCBvZiBhdHRyaWJ1dGVzIG9uIHRoZSBlbGVtZW50LgotICAgKgotICAgKiBAc2VlIENhdGFsb2dFbnRyeQotICAgKi8KLSAgcHVibGljIHZvaWQgc3RhcnRFbGVtZW50IChTdHJpbmcgbmFtZXNwYWNlVVJJLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBsb2NhbE5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHFOYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0dHJpYnV0ZXMgYXR0cykKLSAgICB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLQotICAgIGludCBlbnRyeVR5cGUgPSAtMTsKLSAgICBWZWN0b3IgZW50cnlBcmdzID0gbmV3IFZlY3RvcigpOwotCi0gICAgaWYgKGxvY2FsTmFtZS5lcXVhbHMoIkJhc2UiKSkgewotICAgICAgZW50cnlUeXBlID0gY2F0YWxvZy5CQVNFOwotICAgICAgZW50cnlBcmdzLmFkZChhdHRzLmdldFZhbHVlKCJIUmVmIikpOwotCi0gICAgICBjYXRhbG9nLmdldENhdGFsb2dNYW5hZ2VyKCkuZGVidWcubWVzc2FnZSg0LCAiQmFzZSIsIGF0dHMuZ2V0VmFsdWUoIkhSZWYiKSk7Ci0gICAgfSBlbHNlIGlmIChsb2NhbE5hbWUuZXF1YWxzKCJEZWxlZ2F0ZSIpKSB7Ci0gICAgICBlbnRyeVR5cGUgPSBjYXRhbG9nLkRFTEVHQVRFX1BVQkxJQzsKLSAgICAgIGVudHJ5QXJncy5hZGQoYXR0cy5nZXRWYWx1ZSgiUHVibGljSWQiKSk7Ci0gICAgICBlbnRyeUFyZ3MuYWRkKGF0dHMuZ2V0VmFsdWUoIkhSZWYiKSk7Ci0KLSAgICAgIGNhdGFsb2cuZ2V0Q2F0YWxvZ01hbmFnZXIoKS5kZWJ1Zy5tZXNzYWdlKDQsICJEZWxlZ2F0ZSIsCi0gICAgICAgICAgICAgICAgICAgIFB1YmxpY0lkLm5vcm1hbGl6ZShhdHRzLmdldFZhbHVlKCJQdWJsaWNJZCIpKSwKLSAgICAgICAgICAgICAgICAgICAgYXR0cy5nZXRWYWx1ZSgiSFJlZiIpKTsKLSAgICB9IGVsc2UgaWYgKGxvY2FsTmFtZS5lcXVhbHMoIkV4dGVuZCIpKSB7Ci0gICAgICBlbnRyeVR5cGUgPSBjYXRhbG9nLkNBVEFMT0c7Ci0gICAgICBlbnRyeUFyZ3MuYWRkKGF0dHMuZ2V0VmFsdWUoIkhSZWYiKSk7Ci0KLSAgICAgIGNhdGFsb2cuZ2V0Q2F0YWxvZ01hbmFnZXIoKS5kZWJ1Zy5tZXNzYWdlKDQsICJFeHRlbmQiLCBhdHRzLmdldFZhbHVlKCJIUmVmIikpOwotICAgIH0gZWxzZSBpZiAobG9jYWxOYW1lLmVxdWFscygiTWFwIikpIHsKLSAgICAgIGVudHJ5VHlwZSA9IGNhdGFsb2cuUFVCTElDOwotICAgICAgZW50cnlBcmdzLmFkZChhdHRzLmdldFZhbHVlKCJQdWJsaWNJZCIpKTsKLSAgICAgIGVudHJ5QXJncy5hZGQoYXR0cy5nZXRWYWx1ZSgiSFJlZiIpKTsKLQotICAgICAgY2F0YWxvZy5nZXRDYXRhbG9nTWFuYWdlcigpLmRlYnVnLm1lc3NhZ2UoNCwgIk1hcCIsCi0gICAgICAgICAgICAgICAgICAgIFB1YmxpY0lkLm5vcm1hbGl6ZShhdHRzLmdldFZhbHVlKCJQdWJsaWNJZCIpKSwKLSAgICAgICAgICAgICAgICAgICAgYXR0cy5nZXRWYWx1ZSgiSFJlZiIpKTsKLSAgICB9IGVsc2UgaWYgKGxvY2FsTmFtZS5lcXVhbHMoIlJlbWFwIikpIHsKLSAgICAgIGVudHJ5VHlwZSA9IGNhdGFsb2cuU1lTVEVNOwotICAgICAgZW50cnlBcmdzLmFkZChhdHRzLmdldFZhbHVlKCJTeXN0ZW1JZCIpKTsKLSAgICAgIGVudHJ5QXJncy5hZGQoYXR0cy5nZXRWYWx1ZSgiSFJlZiIpKTsKLQotICAgICAgY2F0YWxvZy5nZXRDYXRhbG9nTWFuYWdlcigpLmRlYnVnLm1lc3NhZ2UoNCwgIlJlbWFwIiwKLSAgICAgICAgICAgICAgICAgICAgYXR0cy5nZXRWYWx1ZSgiU3lzdGVtSWQiKSwKLSAgICAgICAgICAgICAgICAgICAgYXR0cy5nZXRWYWx1ZSgiSFJlZiIpKTsKLSAgICB9IGVsc2UgaWYgKGxvY2FsTmFtZS5lcXVhbHMoIlhNTENhdGFsb2ciKSkgewotICAgICAgLy8gbm9wLCBzdGFydCBvZiBjYXRhbG9nCi0gICAgfSBlbHNlIHsKLSAgICAgIC8vIFRoaXMgaXMgZXF1aXZhbGVudCB0byBhbiBpbnZhbGlkIGNhdGFsb2cgZW50cnkgdHlwZQotICAgICAgY2F0YWxvZy5nZXRDYXRhbG9nTWFuYWdlcigpLmRlYnVnLm1lc3NhZ2UoMSwgIkludmFsaWQgY2F0YWxvZyBlbnRyeSB0eXBlIiwgbG9jYWxOYW1lKTsKLSAgICB9Ci0KLSAgICBpZiAoZW50cnlUeXBlID49IDApIHsKLSAgICAgIHRyeSB7Ci0gICAgICAgIENhdGFsb2dFbnRyeSBjZSA9IG5ldyBDYXRhbG9nRW50cnkoZW50cnlUeXBlLCBlbnRyeUFyZ3MpOwotICAgICAgICBjYXRhbG9nLmFkZEVudHJ5KGNlKTsKLSAgICAgIH0gY2F0Y2ggKENhdGFsb2dFeGNlcHRpb24gY2V4KSB7Ci0gICAgICAgIGlmIChjZXguZ2V0RXhjZXB0aW9uVHlwZSgpID09IENhdGFsb2dFeGNlcHRpb24uSU5WQUxJRF9FTlRSWV9UWVBFKSB7Ci0gICAgICAgICAgY2F0YWxvZy5nZXRDYXRhbG9nTWFuYWdlcigpLmRlYnVnLm1lc3NhZ2UoMSwgIkludmFsaWQgY2F0YWxvZyBlbnRyeSB0eXBlIiwgbG9jYWxOYW1lKTsKLSAgICAgICAgfSBlbHNlIGlmIChjZXguZ2V0RXhjZXB0aW9uVHlwZSgpID09IENhdGFsb2dFeGNlcHRpb24uSU5WQUxJRF9FTlRSWSkgewotICAgICAgICAgIGNhdGFsb2cuZ2V0Q2F0YWxvZ01hbmFnZXIoKS5kZWJ1Zy5tZXNzYWdlKDEsICJJbnZhbGlkIGNhdGFsb2cgZW50cnkiLCBsb2NhbE5hbWUpOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotICAgIH0KLQotICAgIC8qKiBUaGUgU0FYIDxjb2RlPmVuZEVsZW1lbnQ8L2NvZGU+IG1ldGhvZCBkb2VzIG5vdGhpbmcuICovCi0gICAgcHVibGljIHZvaWQgZW5kRWxlbWVudCAoU3RyaW5nIG5hbWVzcGFjZVVSSSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbG9jYWxOYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBxTmFtZSkKLSAgICAgIHRocm93cyBTQVhFeGNlcHRpb24gewotICAgICAgcmV0dXJuOwotICAgIH0KLQotICAvKiogVGhlIFNBWCA8Y29kZT5jaGFyYWN0ZXJzPC9jb2RlPiBtZXRob2QgZG9lcyBub3RoaW5nLiAqLwotICBwdWJsaWMgdm9pZCBjaGFyYWN0ZXJzIChjaGFyIGNoW10sIGludCBzdGFydCwgaW50IGxlbmd0aCkKLSAgICB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICByZXR1cm47Ci0gIH0KLQotICAvKiogVGhlIFNBWCA8Y29kZT5pZ25vcmFibGVXaGl0ZXNwYWNlPC9jb2RlPiBtZXRob2QgZG9lcyBub3RoaW5nLiAqLwotICBwdWJsaWMgdm9pZCBpZ25vcmFibGVXaGl0ZXNwYWNlIChjaGFyIGNoW10sIGludCBzdGFydCwgaW50IGxlbmd0aCkKLSAgICB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICByZXR1cm47Ci0gIH0KLQotICAvKiogVGhlIFNBWCA8Y29kZT5wcm9jZXNzaW5nSW5zdHJ1Y3Rpb248L2NvZGU+IG1ldGhvZCBkb2VzIG5vdGhpbmcuICovCi0gIHB1YmxpYyB2b2lkIHByb2Nlc3NpbmdJbnN0cnVjdGlvbiAoU3RyaW5nIHRhcmdldCwgU3RyaW5nIGRhdGEpCi0gICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0gICAgcmV0dXJuOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9yZXNvbHZlci90b29scy9DYXRhbG9nUmVzb2x2ZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3Jlc29sdmVyL3Rvb2xzL0NhdGFsb2dSZXNvbHZlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyNTk1MWFhLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3Jlc29sdmVyL3Rvb2xzL0NhdGFsb2dSZXNvbHZlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzQzICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vLyBDYXRhbG9nUmVzb2x2ZXIuamF2YSAtIEEgU0FYIEVudGl0eVJlc29sdmVyL0pBWFAgVVJJIFJlc29sdmVyCi0KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBvciBpdHMgbGljZW5zb3JzLAotICogYXMgYXBwbGljYWJsZS4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnJlc29sdmVyLnRvb2xzOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5qYXhwLlNBWFBhcnNlckZhY3RvcnlJbXBsOwotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci1pbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKLWltcG9ydCBqYXZhLm5ldC5VUkw7Ci1pbXBvcnQgamF2YS5uZXQuTWFsZm9ybWVkVVJMRXhjZXB0aW9uOwotCi1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LlhNTFJlYWRlcjsKLWltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKLWltcG9ydCBvcmcueG1sLnNheC5FbnRpdHlSZXNvbHZlcjsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlNBWFNvdXJjZTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlNvdXJjZTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlVSSVJlc29sdmVyOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXJGYWN0b3J5OwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXNvbHZlci5DYXRhbG9nOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzb2x2ZXIuQ2F0YWxvZ01hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXNvbHZlci5oZWxwZXJzLkZpbGVVUkw7Ci0KLS8qKgotICogQSBTQVggRW50aXR5UmVzb2x2ZXIvSkFYUCBVUklSZXNvbHZlciB0aGF0IHVzZXMgY2F0YWxvZ3MuCi0gKgotICogPHA+VGhpcyBjbGFzcyBpbXBsZW1lbnRzIGJvdGggYSBTQVggRW50aXR5UmVzb2x2ZXIgYW5kIGEgSkFYUCBVUklSZXNvbHZlci4KLSAqIDwvcD4KLSAqCi0gKiA8cD5UaGlzIHJlc29sdmVyIHVuZGVyc3RhbmRzIE9BU0lTIFRSOTQwMSBjYXRhbG9ncywgWENhdGFsb2dzLCBhbmQgdGhlCi0gKiBjdXJyZW50IHdvcmtpbmcgZHJhZnQgb2YgdGhlIE9BU0lTIEVudGl0eSBSZXNvbHV0aW9uIFRlY2huaWNhbAotICogQ29tbWl0dGVlIHNwZWNpZmljYXRpb24uPC9wPgotICoKLSAqIEBzZWUgQ2F0YWxvZwotICogQHNlZSBvcmcueG1sLnNheC5FbnRpdHlSZXNvbHZlcgotICogQHNlZSBqYXZheC54bWwudHJhbnNmb3JtLlVSSVJlc29sdmVyCi0gKgotICogQGF1dGhvciBOb3JtYW4gV2Fsc2gKLSAqIDxhIGhyZWY9Im1haWx0bzpOb3JtYW4uV2Fsc2hAU3VuLkNPTSI+Tm9ybWFuLldhbHNoQFN1bi5DT008L2E+Ci0gKgotICogQHZlcnNpb24gMS4wCi0gKi8KLXB1YmxpYyBjbGFzcyBDYXRhbG9nUmVzb2x2ZXIgaW1wbGVtZW50cyBFbnRpdHlSZXNvbHZlciwgVVJJUmVzb2x2ZXIgewotICAvKiogTWFrZSB0aGUgcGFyc2VyIE5hbWVzcGFjZSBhd2FyZT8gKi8KLSAgcHVibGljIGJvb2xlYW4gbmFtZXNwYWNlQXdhcmUgPSB0cnVlOwotCi0gIC8qKiBNYWtlIHRoZSBwYXJzZXIgdmFsaWRhdGluZz8gKi8KLSAgcHVibGljIGJvb2xlYW4gdmFsaWRhdGluZyA9IGZhbHNlOwotCi0gIC8qKiBUaGUgdW5kZXJseWluZyBjYXRhbG9nICovCi0gIHByaXZhdGUgQ2F0YWxvZyBjYXRhbG9nID0gbnVsbDsKLQotICAvKiogVGhlIGNhdGFsb2cgbWFuYWdlciAqLwotICBwcml2YXRlIENhdGFsb2dNYW5hZ2VyIGNhdGFsb2dNYW5hZ2VyID0gQ2F0YWxvZ01hbmFnZXIuZ2V0U3RhdGljTWFuYWdlcigpOwotCi0gIC8qKiBDb25zdHJ1Y3RvciAqLwotICBwdWJsaWMgQ2F0YWxvZ1Jlc29sdmVyKCkgewotICAgIGluaXRpYWxpemVDYXRhbG9ncyhmYWxzZSk7Ci0gIH0KLQotICAvKiogQ29uc3RydWN0b3IgKi8KLSAgcHVibGljIENhdGFsb2dSZXNvbHZlcihib29sZWFuIHByaXZhdGVDYXRhbG9nKSB7Ci0gICAgaW5pdGlhbGl6ZUNhdGFsb2dzKHByaXZhdGVDYXRhbG9nKTsKLSAgfQotCi0gIC8qKiBDb25zdHJ1Y3RvciAqLwotICBwdWJsaWMgQ2F0YWxvZ1Jlc29sdmVyKENhdGFsb2dNYW5hZ2VyIG1hbmFnZXIpIHsKLSAgICBjYXRhbG9nTWFuYWdlciA9IG1hbmFnZXI7Ci0gICAgaW5pdGlhbGl6ZUNhdGFsb2dzKCFjYXRhbG9nTWFuYWdlci5nZXRVc2VTdGF0aWNDYXRhbG9nKCkpOwotICB9Ci0KLSAgLyoqIEluaXRpYWxpemUgY2F0YWxvZyAqLwotICBwcml2YXRlIHZvaWQgaW5pdGlhbGl6ZUNhdGFsb2dzKGJvb2xlYW4gcHJpdmF0ZUNhdGFsb2cpIHsKLSAgICBjYXRhbG9nID0gY2F0YWxvZ01hbmFnZXIuZ2V0Q2F0YWxvZygpOwotICB9Ci0KLSAgLyoqIFJldHVybiB0aGUgdW5kZXJseWluZyBjYXRhbG9nICovCi0gIHB1YmxpYyBDYXRhbG9nIGdldENhdGFsb2coKSB7Ci0gICAgcmV0dXJuIGNhdGFsb2c7Ci0gIH0KLQotICAvKioKLSAgICogSW1wbGVtZW50cyB0aGUgZ3V0cyBvZiB0aGUgPGNvZGU+cmVzb2x2ZUVudGl0eTwvY29kZT4gbWV0aG9kCi0gICAqIGZvciB0aGUgU0FYIGludGVyZmFjZS4KLSAgICoKLSAgICogPHA+UHJlc2VudGVkIHdpdGggYW4gb3B0aW9uYWwgcHVibGljIGlkZW50aWZpZXIgYW5kIGEgc3lzdGVtCi0gICAqIGlkZW50aWZpZXIsIHRoaXMgZnVuY3Rpb24gYXR0ZW1wdHMgdG8gbG9jYXRlIGEgbWFwcGluZyBpbiB0aGUKLSAgICogY2F0YWxvZ3MuPC9wPgotICAgKgotICAgKiA8cD5JZiBzdWNoIGEgbWFwcGluZyBpcyBmb3VuZCwgaXQgaXMgcmV0dXJuZWQuICBJZiBubyBtYXBwaW5nIGlzCi0gICAqIGZvdW5kLCBudWxsIGlzIHJldHVybmVkLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIHB1YmxpY0lkICBUaGUgcHVibGljIGlkZW50aWZpZXIgZm9yIHRoZSBlbnRpdHkgaW4gcXVlc3Rpb24uCi0gICAqIFRoaXMgbWF5IGJlIG51bGwuCi0gICAqCi0gICAqIEBwYXJhbSBzeXN0ZW1JZCAgVGhlIHN5c3RlbSBpZGVudGlmaWVyIGZvciB0aGUgZW50aXR5IGluIHF1ZXN0aW9uLgotICAgKiBYTUwgcmVxdWlyZXMgYSBzeXN0ZW0gaWRlbnRpZmllciBvbiBhbGwgZXh0ZXJuYWwgZW50aXRpZXMsIHNvIHRoaXMKLSAgICogdmFsdWUgaXMgYWx3YXlzIHNwZWNpZmllZC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgcmVzb2x2ZWQgaWRlbnRpZmllciAoYSBVUkkgcmVmZXJlbmNlKS4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0UmVzb2x2ZWRFbnRpdHkgKFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkKSB7Ci0gICAgU3RyaW5nIHJlc29sdmVkID0gbnVsbDsKLQotICAgIGlmIChjYXRhbG9nID09IG51bGwpIHsKLSAgICAgIGNhdGFsb2dNYW5hZ2VyLmRlYnVnLm1lc3NhZ2UoMSwgIkNhdGFsb2cgcmVzb2x1dGlvbiBhdHRlbXB0ZWQgd2l0aCBudWxsIGNhdGFsb2c7IGlnbm9yZWQiKTsKLSAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIGlmIChzeXN0ZW1JZCAhPSBudWxsKSB7Ci0gICAgICB0cnkgewotICAgICAgICByZXNvbHZlZCA9IGNhdGFsb2cucmVzb2x2ZVN5c3RlbShzeXN0ZW1JZCk7Ci0gICAgICB9IGNhdGNoIChNYWxmb3JtZWRVUkxFeGNlcHRpb24gbWUpIHsKLSAgICAgICAgY2F0YWxvZ01hbmFnZXIuZGVidWcubWVzc2FnZSgxLCAiTWFsZm9ybWVkIFVSTCBleGNlcHRpb24gdHJ5aW5nIHRvIHJlc29sdmUiLAotICAgICAgICAgICAgICAgICAgICAgIHB1YmxpY0lkKTsKLSAgICAgICAgcmVzb2x2ZWQgPSBudWxsOwotICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gaWUpIHsKLSAgICAgICAgY2F0YWxvZ01hbmFnZXIuZGVidWcubWVzc2FnZSgxLCAiSS9PIGV4Y2VwdGlvbiB0cnlpbmcgdG8gcmVzb2x2ZSIsIHB1YmxpY0lkKTsKLSAgICAgICAgcmVzb2x2ZWQgPSBudWxsOwotICAgICAgfQotICAgIH0KLQotICAgIGlmIChyZXNvbHZlZCA9PSBudWxsKSB7Ci0gICAgICBpZiAocHVibGljSWQgIT0gbnVsbCkgewotICAgICAgICB0cnkgewotICAgICAgICAgIHJlc29sdmVkID0gY2F0YWxvZy5yZXNvbHZlUHVibGljKHB1YmxpY0lkLCBzeXN0ZW1JZCk7Ci0gICAgICAgIH0gY2F0Y2ggKE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiBtZSkgewotICAgICAgICAgIGNhdGFsb2dNYW5hZ2VyLmRlYnVnLm1lc3NhZ2UoMSwgIk1hbGZvcm1lZCBVUkwgZXhjZXB0aW9uIHRyeWluZyB0byByZXNvbHZlIiwKLSAgICAgICAgICAgICAgICAgICAgICAgIHB1YmxpY0lkKTsKLSAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gaWUpIHsKLSAgICAgICAgICBjYXRhbG9nTWFuYWdlci5kZWJ1Zy5tZXNzYWdlKDEsICJJL08gZXhjZXB0aW9uIHRyeWluZyB0byByZXNvbHZlIiwgcHVibGljSWQpOwotICAgICAgICB9Ci0gICAgICB9Ci0KLSAgICAgIGlmIChyZXNvbHZlZCAhPSBudWxsKSB7Ci0gICAgICAgIGNhdGFsb2dNYW5hZ2VyLmRlYnVnLm1lc3NhZ2UoMiwgIlJlc29sdmVkIHB1YmxpYyIsIHB1YmxpY0lkLCByZXNvbHZlZCk7Ci0gICAgICB9Ci0gICAgfSBlbHNlIHsKLSAgICAgIGNhdGFsb2dNYW5hZ2VyLmRlYnVnLm1lc3NhZ2UoMiwgIlJlc29sdmVkIHN5c3RlbSIsIHN5c3RlbUlkLCByZXNvbHZlZCk7Ci0gICAgfQotCi0gICAgcmV0dXJuIHJlc29sdmVkOwotICB9Ci0KLSAgLyoqCi0gICAqIEltcGxlbWVudHMgdGhlIDxjb2RlPnJlc29sdmVFbnRpdHk8L2NvZGU+IG1ldGhvZAotICAgKiBmb3IgdGhlIFNBWCBpbnRlcmZhY2UuCi0gICAqCi0gICAqIDxwPlByZXNlbnRlZCB3aXRoIGFuIG9wdGlvbmFsIHB1YmxpYyBpZGVudGlmaWVyIGFuZCBhIHN5c3RlbQotICAgKiBpZGVudGlmaWVyLCB0aGlzIGZ1bmN0aW9uIGF0dGVtcHRzIHRvIGxvY2F0ZSBhIG1hcHBpbmcgaW4gdGhlCi0gICAqIGNhdGFsb2dzLjwvcD4KLSAgICoKLSAgICogPHA+SWYgc3VjaCBhIG1hcHBpbmcgaXMgZm91bmQsIHRoZSByZXNvbHZlciBhdHRlbXB0cyB0byBvcGVuCi0gICAqIHRoZSBtYXBwZWQgdmFsdWUgYXMgYW4gSW5wdXRTb3VyY2UgYW5kIHJldHVybiBpdC4gRXhjZXB0aW9ucyBhcmUKLSAgICogaWdub3JlZCBhbmQgbnVsbCBpcyByZXR1cm5lZCBpZiB0aGUgbWFwcGVkIHZhbHVlIGNhbm5vdCBiZSBvcGVuZWQKLSAgICogYXMgYW4gaW5wdXQgc291cmNlLjwvcD4KLSAgICoKLSAgICogPHA+SWYgbm8gbWFwcGluZyBpcyBmb3VuZCAob3IgYW4gZXJyb3Igb2NjdXJzIGF0dGVtcHRpbmcgdG8gb3BlbgotICAgKiB0aGUgbWFwcGVkIHZhbHVlIGFzIGFuIGlucHV0IHNvdXJjZSksIG51bGwgaXMgcmV0dXJuZWQgYW5kIHRoZSBzeXN0ZW0KLSAgICogd2lsbCB1c2UgdGhlIHNwZWNpZmllZCBzeXN0ZW0gaWRlbnRpZmllciBhcyBpZiBubyBlbnRpdHlSZXNvbHZlcgotICAgKiB3YXMgc3BlY2lmaWVkLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIHB1YmxpY0lkICBUaGUgcHVibGljIGlkZW50aWZpZXIgZm9yIHRoZSBlbnRpdHkgaW4gcXVlc3Rpb24uCi0gICAqIFRoaXMgbWF5IGJlIG51bGwuCi0gICAqCi0gICAqIEBwYXJhbSBzeXN0ZW1JZCAgVGhlIHN5c3RlbSBpZGVudGlmaWVyIGZvciB0aGUgZW50aXR5IGluIHF1ZXN0aW9uLgotICAgKiBYTUwgcmVxdWlyZXMgYSBzeXN0ZW0gaWRlbnRpZmllciBvbiBhbGwgZXh0ZXJuYWwgZW50aXRpZXMsIHNvIHRoaXMKLSAgICogdmFsdWUgaXMgYWx3YXlzIHNwZWNpZmllZC4KLSAgICoKLSAgICogQHJldHVybiBBbiBJbnB1dFNvdXJjZSBmb3IgdGhlIG1hcHBlZCBpZGVudGlmaWVyLCBvciBudWxsLgotICAgKi8KLSAgcHVibGljIElucHV0U291cmNlIHJlc29sdmVFbnRpdHkgKFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkKSB7Ci0gICAgU3RyaW5nIHJlc29sdmVkID0gZ2V0UmVzb2x2ZWRFbnRpdHkocHVibGljSWQsIHN5c3RlbUlkKTsKLQotICAgIGlmIChyZXNvbHZlZCAhPSBudWxsKSB7Ci0gICAgICB0cnkgewotICAgICAgICBJbnB1dFNvdXJjZSBpU291cmNlID0gbmV3IElucHV0U291cmNlKHJlc29sdmVkKTsKLSAgICAgICAgaVNvdXJjZS5zZXRQdWJsaWNJZChwdWJsaWNJZCk7Ci0KLSAgICAgICAgLy8gSWRlYWxseSB0aGlzIG1ldGhvZCB3b3VsZCBub3QgYXR0ZW1wdCB0byBvcGVuIHRoZQotICAgICAgICAvLyBJbnB1dFN0cmVhbSwgYnV0IHRoZXJlIGlzIGEgYnVnIChpbiBYZXJjZXMsIGF0IGxlYXN0KQotICAgICAgICAvLyB0aGF0IGNhdXNlcyB0aGUgcGFyc2VyIHRvIG1pc3Rha2VubHkgb3BlbiB0aGUgd3JvbmcKLSAgICAgICAgLy8gc3lzdGVtIGlkZW50aWZpZXIgaWYgdGhlIHJldHVybmVkIElucHV0U291cmNlIGRvZXMKLSAgICAgICAgLy8gbm90IGhhdmUgYSBieXRlU3RyZWFtLgotICAgICAgICAvLwotICAgICAgICAvLyBJdCBjb3VsZCBiZSBhcmd1ZWQgdGhhdCB3ZSBzdGlsbCBzaG91bGRuJ3QgZG8gdGhpcyBoZXJlLAotICAgICAgICAvLyBidXQgc2luY2UgdGhlIHB1cnBvc2Ugb2YgY2FsbGluZyB0aGUgZW50aXR5UmVzb2x2ZXIgaXMKLSAgICAgICAgLy8gYWxtb3N0IGNlcnRhaW5seSB0byBvcGVuIHRoZSBpbnB1dCBzdHJlYW0sIGl0IHNlZW1zIHRvCi0gICAgICAgIC8vIGRvIGxpdHRsZSBoYXJtLgotICAgICAgICAvLwotICAgICAgICBVUkwgdXJsID0gbmV3IFVSTChyZXNvbHZlZCk7Ci0gICAgICAgIElucHV0U3RyZWFtIGlTdHJlYW0gPSB1cmwub3BlblN0cmVhbSgpOwotICAgICAgICBpU291cmNlLnNldEJ5dGVTdHJlYW0oaVN0cmVhbSk7Ci0KLSAgICAgICAgcmV0dXJuIGlTb3VyY2U7Ci0gICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgICBjYXRhbG9nTWFuYWdlci5kZWJ1Zy5tZXNzYWdlKDEsICJGYWlsZWQgdG8gY3JlYXRlIElucHV0U291cmNlIiwgcmVzb2x2ZWQpOwotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKiBKQVhQIFVSSVJlc29sdmVyIEFQSSAqLwotICBwdWJsaWMgU291cmNlIHJlc29sdmUoU3RyaW5nIGhyZWYsIFN0cmluZyBiYXNlKQotICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiB7Ci0KLSAgICBTdHJpbmcgdXJpID0gaHJlZjsKLSAgICBTdHJpbmcgZnJhZ21lbnQgPSBudWxsOwotICAgIGludCBoYXNoUG9zID0gaHJlZi5pbmRleE9mKCIjIik7Ci0gICAgaWYgKGhhc2hQb3MgPj0gMCkgewotICAgICAgdXJpID0gaHJlZi5zdWJzdHJpbmcoMCwgaGFzaFBvcyk7Ci0gICAgICBmcmFnbWVudCA9IGhyZWYuc3Vic3RyaW5nKGhhc2hQb3MrMSk7Ci0gICAgfQotCi0gICAgU3RyaW5nIHJlc3VsdCA9IG51bGw7Ci0KLSAgICB0cnkgewotICAgICAgcmVzdWx0ID0gY2F0YWxvZy5yZXNvbHZlVVJJKGhyZWYpOwotICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAvLyBub3A7Ci0gICAgfQotCi0gICAgaWYgKHJlc3VsdCA9PSBudWxsKSB7Ci0gICAgICB0cnkgewotICAgICAgICBVUkwgdXJsID0gbnVsbDsKLQotICAgICAgICBpZiAoYmFzZT09bnVsbCkgewotICAgICAgICAgIHVybCA9IG5ldyBVUkwodXJpKTsKLSAgICAgICAgICByZXN1bHQgPSB1cmwudG9TdHJpbmcoKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICBVUkwgYmFzZVVSTCA9IG5ldyBVUkwoYmFzZSk7Ci0gICAgICAgICAgdXJsID0gKGhyZWYubGVuZ3RoKCk9PTAgPyBiYXNlVVJMIDogbmV3IFVSTChiYXNlVVJMLCB1cmkpKTsKLSAgICAgICAgICByZXN1bHQgPSB1cmwudG9TdHJpbmcoKTsKLSAgICAgICAgfQotICAgICAgfSBjYXRjaCAoamF2YS5uZXQuTWFsZm9ybWVkVVJMRXhjZXB0aW9uIG11ZSkgewotICAgICAgICAvLyB0cnkgdG8gbWFrZSBhbiBhYnNvbHV0ZSBVUkkgZnJvbSB0aGUgY3VycmVudCBiYXNlCi0gICAgICAgIFN0cmluZyBhYnNCYXNlID0gbWFrZUFic29sdXRlKGJhc2UpOwotICAgICAgICBpZiAoIWFic0Jhc2UuZXF1YWxzKGJhc2UpKSB7Ci0gICAgICAgICAgLy8gZG9uJ3QgYm90aGVyIGlmIHRoZSBhYnNCYXNlIGlzbid0IGRpZmZlcmVudCEKLSAgICAgICAgICByZXR1cm4gcmVzb2x2ZShocmVmLCBhYnNCYXNlKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oIk1hbGZvcm1lZCBVUkwgIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGhyZWYgKyAiKGJhc2UgIiArIGJhc2UgKyAiKSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG11ZSk7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICB9Ci0KLSAgICBjYXRhbG9nTWFuYWdlci5kZWJ1Zy5tZXNzYWdlKDIsICJSZXNvbHZlZCBVUkkiLCBocmVmLCByZXN1bHQpOwotCi0gICAgU0FYU291cmNlIHNvdXJjZSA9IG5ldyBTQVhTb3VyY2UoKTsKLSAgICBzb3VyY2Uuc2V0SW5wdXRTb3VyY2UobmV3IElucHV0U291cmNlKHJlc3VsdCkpOwotICAgIHNldEVudGl0eVJlc29sdmVyKHNvdXJjZSk7Ci0gICAgcmV0dXJuIHNvdXJjZTsKLSAgfQotCi0gIC8qKgotICAgKiA8cD5Fc3RhYmxpc2ggYW4gZW50aXR5UmVzb2x2ZXIgZm9yIG5ld2x5IHJlc29sdmVkIFVSSXMuPC9wPgotICAgKgotICAgKiA8cD5UaGlzIGlzIGNhbGxlZCBmcm9tIHRoZSBVUklSZXNvbHZlciB0byBzZXQgYW4gRW50aXR5UmVzb2x2ZXIKLSAgICogb24gdGhlIFNBWCBwYXJzZXIgdG8gYmUgdXNlZCBmb3IgbmV3IFhNTCBkb2N1bWVudHMgdGhhdCBhcmUKLSAgICogZW5jb3VudGVyZWQgYXMgYSByZXN1bHQgb2YgdGhlIGRvY3VtZW50KCkgZnVuY3Rpb24sIHhzbDppbXBvcnQsCi0gICAqIG9yIHhzbDppbmNsdWRlLiAgVGhpcyBpcyBkb25lIGJlY2F1c2UgdGhlIFhTTFQgcHJvY2Vzc29yIGNhbGxzCi0gICAqIG91dCB0byB0aGUgU0FYUGFyc2VyRmFjdG9yeSBpdHNlbGYgdG8gY3JlYXRlIGEgbmV3IFNBWFBhcnNlciB0bwotICAgKiBwYXJzZSB0aGUgbmV3IGRvY3VtZW50LiAgVGhlIG5ldyBwYXJzZXIgZG9lcyBub3QgYXV0b21hdGljYWxseQotICAgKiBpbmhlcml0IHRoZSBFbnRpdHlSZXNvbHZlciBvZiB0aGUgb3JpZ2luYWwgKGFsdGhvdWdoIGFyZ3VhYmx5Ci0gICAqIGl0IHNob3VsZCkuICBTZWUgYmVsb3c6PC9wPgotICAgKgotICAgKiA8dHQ+IklmIGFuIGFwcGxpY2F0aW9uIHdhbnRzIHRvIHNldCB0aGUgRXJyb3JIYW5kbGVyIG9yCi0gICAqIEVudGl0eVJlc29sdmVyIGZvciBhbiBYTUxSZWFkZXIgdXNlZCBkdXJpbmcgYSB0cmFuc2Zvcm1hdGlvbiwKLSAgICogaXQgc2hvdWxkIHVzZSBhIFVSSVJlc29sdmVyIHRvIHJldHVybiB0aGUgU0FYU291cmNlIHdoaWNoCi0gICAqIHByb3ZpZGVzICh3aXRoIGdldFhNTFJlYWRlcikgYSByZWZlcmVuY2UgdG8gdGhlIFhNTFJlYWRlciI8L3R0PgotICAgKgotICAgKiA8cD4uLi5xdW90ZWQgZnJvbSBwYWdlIDExOCBvZiB0aGUgSmF2YSBBUEkgZm9yIFhNTAotICAgKiBQcm9jZXNzaW5nIDEuMSBzcGVjaWZpY2F0aW9uPC9wPgotICAgKgotICAgKi8KLSAgcHJpdmF0ZSB2b2lkIHNldEVudGl0eVJlc29sdmVyKFNBWFNvdXJjZSBzb3VyY2UpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiB7Ci0gICAgWE1MUmVhZGVyIHJlYWRlciA9IHNvdXJjZS5nZXRYTUxSZWFkZXIoKTsKLSAgICBpZiAocmVhZGVyID09IG51bGwpIHsKLSAgICAgIFNBWFBhcnNlckZhY3Rvcnkgc3BGYWN0b3J5ID0gY2F0YWxvZ01hbmFnZXIudXNlU2VydmljZXNNZWNoYW5pc20oKSA/Ci0gICAgICAgICAgICAgICAgICAgIFNBWFBhcnNlckZhY3RvcnkubmV3SW5zdGFuY2UoKSA6IG5ldyBTQVhQYXJzZXJGYWN0b3J5SW1wbCgpOwotICAgICAgc3BGYWN0b3J5LnNldE5hbWVzcGFjZUF3YXJlKHRydWUpOwotICAgICAgdHJ5IHsKLSAgICAgICAgcmVhZGVyID0gc3BGYWN0b3J5Lm5ld1NBWFBhcnNlcigpLmdldFhNTFJlYWRlcigpOwotICAgICAgfQotICAgICAgY2F0Y2ggKFBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gZXgpIHsKLSAgICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKGV4KTsKLSAgICAgIH0KLSAgICAgIGNhdGNoIChTQVhFeGNlcHRpb24gZXgpIHsKLSAgICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKGV4KTsKLSAgICAgIH0KLSAgICB9Ci0gICAgcmVhZGVyLnNldEVudGl0eVJlc29sdmVyKHRoaXMpOwotICAgIHNvdXJjZS5zZXRYTUxSZWFkZXIocmVhZGVyKTsKLSAgfQotCi0gIC8qKiBBdHRlbXB0IHRvIGNvbnN0cnVjdCBhbiBhYnNvbHV0ZSBVUkkgKi8KLSAgcHJpdmF0ZSBTdHJpbmcgbWFrZUFic29sdXRlKFN0cmluZyB1cmkpIHsKLSAgICBpZiAodXJpID09IG51bGwpIHsKLSAgICAgIHVyaSA9ICIiOwotICAgIH0KLQotICAgIHRyeSB7Ci0gICAgICBVUkwgdXJsID0gbmV3IFVSTCh1cmkpOwotICAgICAgcmV0dXJuIHVybC50b1N0cmluZygpOwotICAgIH0gY2F0Y2ggKE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiBtdWUpIHsKLSAgICAgIHRyeSB7Ci0gICAgICAgIFVSTCBmaWxlVVJMID0gRmlsZVVSTC5tYWtlVVJMKHVyaSk7Ci0gICAgICAgIHJldHVybiBmaWxlVVJMLnRvU3RyaW5nKCk7Ci0gICAgICB9IGNhdGNoIChNYWxmb3JtZWRVUkxFeGNlcHRpb24gbXVlMikgewotICAgICAgICAvLyBiYWlsCi0gICAgICAgIHJldHVybiB1cmk7Ci0gICAgICB9Ci0gICAgfQotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9yZXNvbHZlci90b29scy9SZXNvbHZpbmdQYXJzZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3Jlc29sdmVyL3Rvb2xzL1Jlc29sdmluZ1BhcnNlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwZDkwZDU3Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3Jlc29sdmVyL3Rvb2xzL1Jlc29sdmluZ1BhcnNlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDQ2ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vLyBSZXNvbHZpbmdQYXJzZXIuamF2YSAtIEFuIGludGVyZmFjZSBmb3IgcmVhZGluZyBjYXRhbG9nIGZpbGVzCi0KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBvciBpdHMgbGljZW5zb3JzLAotICogYXMgYXBwbGljYWJsZS4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnJlc29sdmVyLnRvb2xzOwotCi1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOwotaW1wb3J0IGphdmEubmV0LlVSTDsKLWltcG9ydCBqYXZhLm5ldC5NYWxmb3JtZWRVUkxFeGNlcHRpb247Ci1pbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKLQotaW1wb3J0IG9yZy54bWwuc2F4LlBhcnNlcjsKLWltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKLWltcG9ydCBvcmcueG1sLnNheC5Mb2NhdG9yOwotaW1wb3J0IG9yZy54bWwuc2F4LkVycm9ySGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5EVERIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LkRvY3VtZW50SGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5BdHRyaWJ1dGVMaXN0OwotaW1wb3J0IG9yZy54bWwuc2F4LkVudGl0eVJlc29sdmVyOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKLQotaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLlNBWFBhcnNlckZhY3Rvcnk7Ci1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5qYXhwLlNBWFBhcnNlckZhY3RvcnlJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzb2x2ZXIuQ2F0YWxvZzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnJlc29sdmVyLkNhdGFsb2dNYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzb2x2ZXIuaGVscGVycy5GaWxlVVJMOwotCi0vKioKLSAqIEEgU0FYIFBhcnNlciB0aGF0IHBlcmZvcm1zIGNhdGFsb2ctYmFzZWQgZW50aXR5IHJlc29sdXRpb24uCi0gKgotICogPHA+VGhpcyBjbGFzcyBpbXBsZW1lbnRzIGEgU0FYIFBhcnNlciB0aGF0IHBlcmZvcm1zIGVudGl0eSByZXNvbHV0aW9uCi0gKiB1c2luZyB0aGUgQ2F0YWxvZ1Jlc29sdmVyLiBUaGUgYWN0dWFsLCB1bmRlcmx5aW5nIHBhcnNlciBpcyBvYnRhaW5lZAotICogZnJvbSBhIFNBWFBhcnNlckZhY3RvcnkuPC9wPgotICogPC9wPgotICoKLSAqIEBkZXByZWNhdGVkIFRoaXMgaW50ZXJmYWNlIGhhcyBiZWVuIHJlcGxhY2VkIGJ5IHRoZQotICogICAgICAgICAgICAge0BsaW5rIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzb2x2ZXIudG9vbHMuUmVzb2x2aW5nWE1MUmVhZGVyfSBmb3IgU0FYMi4KLSAqIEBzZWUgQ2F0YWxvZ1Jlc29sdmVyCi0gKiBAc2VlIG9yZy54bWwuc2F4LlBhcnNlcgotICoKLSAqIEBhdXRob3IgTm9ybWFuIFdhbHNoCi0gKiA8YSBocmVmPSJtYWlsdG86Tm9ybWFuLldhbHNoQFN1bi5DT00iPk5vcm1hbi5XYWxzaEBTdW4uQ09NPC9hPgotICoKLSAqIEB2ZXJzaW9uIDEuMAotICovCi1wdWJsaWMgY2xhc3MgUmVzb2x2aW5nUGFyc2VyCi0gIGltcGxlbWVudHMgUGFyc2VyLCBEVERIYW5kbGVyLCBEb2N1bWVudEhhbmRsZXIsIEVudGl0eVJlc29sdmVyIHsKLSAgLyoqIE1ha2UgdGhlIHBhcnNlciBOYW1lc3BhY2UgYXdhcmU/ICovCi0gIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBuYW1lc3BhY2VBd2FyZSA9IHRydWU7Ci0KLSAgLyoqIE1ha2UgdGhlIHBhcnNlciB2YWxpZGF0aW5nPyAqLwotICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gdmFsaWRhdGluZyA9IGZhbHNlOwotCi0gIC8qKiBTdXBwcmVzcyBleHBsYW5hdG9yeSBtZXNzYWdlPwotICAgKgotICAgKiBAc2VlICNwYXJzZShJbnB1dFNvdXJjZSkKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBzdXBwcmVzc0V4cGxhbmF0aW9uID0gZmFsc2U7Ci0KLSAgLyoqIFRoZSB1bmRlcmx5aW5nIHBhcnNlci4gKi8KLSAgcHJpdmF0ZSBTQVhQYXJzZXIgc2F4UGFyc2VyID0gbnVsbDsKLQotICAvKiogVGhlIHVuZGVybHlpbmcgcmVhZGVyLiAqLwotICBwcml2YXRlIFBhcnNlciBwYXJzZXIgPSBudWxsOwotCi0gIC8qKiBUaGUgdW5kZXJseWluZyBEb2N1bWVudEhhbmRsZXIuICovCi0gIHByaXZhdGUgRG9jdW1lbnRIYW5kbGVyIGRvY3VtZW50SGFuZGxlciA9IG51bGw7Ci0KLSAgLyoqIFRoZSB1bmRlcmx5aW5nIERUREhhbmRsZXIuICovCi0gIHByaXZhdGUgRFRESGFuZGxlciBkdGRIYW5kbGVyID0gbnVsbDsKLQotICAvKiogVGhlIG1hbmFnZXIgZm9yIHRoZSB1bmRlcmx5aW5nIHJlc29sdmVyLiAqLwotICBwcml2YXRlIENhdGFsb2dNYW5hZ2VyIGNhdGFsb2dNYW5hZ2VyID0gQ2F0YWxvZ01hbmFnZXIuZ2V0U3RhdGljTWFuYWdlcigpOwotCi0gIC8qKiBUaGUgdW5kZXJseWluZyBjYXRhbG9nIHJlc29sdmVyLiAqLwotICBwcml2YXRlIENhdGFsb2dSZXNvbHZlciBjYXRhbG9nUmVzb2x2ZXIgPSBudWxsOwotCi0gIC8qKiBBIHNlcGFyYXRlIHJlc29sdmVyIGZvciBvYXNpcy14bWwtcGkgY2F0YWxvZ3MuICovCi0gIHByaXZhdGUgQ2F0YWxvZ1Jlc29sdmVyIHBpQ2F0YWxvZ1Jlc29sdmVyID0gbnVsbDsKLQotICAvKiogQXJlIHdlIGluIHRoZSBwcm9sb2c/IElzIGFuIG9hc2lzLXhtbC1jYXRhbG9nIFBJIHZhbGlkIG5vdz8gKi8KLSAgcHJpdmF0ZSBib29sZWFuIGFsbG93WE1MQ2F0YWxvZ1BJID0gZmFsc2U7Ci0KLSAgLyoqIEhhcyBhbiBvYXNpcy14bWwtY2F0YWxvZyBQSSBiZWVuIHNlZW4/ICovCi0gIHByaXZhdGUgYm9vbGVhbiBvYXNpc1hNTENhdGFsb2dQSSA9IGZhbHNlOwotCi0gIC8qKiBUaGUgYmFzZSBVUkkgb2YgdGhlIGlucHV0IGRvY3VtZW50LCBpZiBrbm93bi4gKi8KLSAgcHJpdmF0ZSBVUkwgYmFzZVVSTCA9IG51bGw7Ci0KLSAgLyoqIENvbnN0cnVjdG9yLiAqLwotICBwdWJsaWMgUmVzb2x2aW5nUGFyc2VyKCkgewotICAgIGluaXRQYXJzZXIoKTsKLSAgfQotCi0gIC8qKiBDb25zdHJ1Y3Rvci4gKi8KLSAgcHVibGljIFJlc29sdmluZ1BhcnNlcihDYXRhbG9nTWFuYWdlciBtYW5hZ2VyKSB7Ci0gICAgY2F0YWxvZ01hbmFnZXIgPSBtYW5hZ2VyOwotICAgIGluaXRQYXJzZXIoKTsKLSAgfQotCi0gIC8qKiBJbml0aWFsaXplIHRoZSBwYXJzZXIuICovCi0gIHByaXZhdGUgdm9pZCBpbml0UGFyc2VyKCkgewotICAgIGNhdGFsb2dSZXNvbHZlciA9IG5ldyBDYXRhbG9nUmVzb2x2ZXIoY2F0YWxvZ01hbmFnZXIpOwotICAgIFNBWFBhcnNlckZhY3Rvcnkgc3BmID0gY2F0YWxvZ01hbmFnZXIudXNlU2VydmljZXNNZWNoYW5pc20oKSA/Ci0gICAgICAgICAgICAgICAgICAgIFNBWFBhcnNlckZhY3RvcnkubmV3SW5zdGFuY2UoKSA6IG5ldyBTQVhQYXJzZXJGYWN0b3J5SW1wbCgpOwotICAgIHNwZi5zZXROYW1lc3BhY2VBd2FyZShuYW1lc3BhY2VBd2FyZSk7Ci0gICAgc3BmLnNldFZhbGlkYXRpbmcodmFsaWRhdGluZyk7Ci0KLSAgICB0cnkgewotICAgICAgc2F4UGFyc2VyID0gc3BmLm5ld1NBWFBhcnNlcigpOwotICAgICAgcGFyc2VyID0gc2F4UGFyc2VyLmdldFBhcnNlcigpOwotICAgICAgZG9jdW1lbnRIYW5kbGVyID0gbnVsbDsKLSAgICAgIGR0ZEhhbmRsZXIgPSBudWxsOwotICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgewotICAgICAgZXgucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgfQotICB9Ci0KLSAgLyoqIFJldHVybiB0aGUgQ2F0YWxvZyBiZWluZyB1c2VkLiAqLwotICBwdWJsaWMgQ2F0YWxvZyBnZXRDYXRhbG9nKCkgewotICAgIHJldHVybiBjYXRhbG9nUmVzb2x2ZXIuZ2V0Q2F0YWxvZygpOwotICB9Ci0KLSAgLyoqCi0gICAqIFNBWCBQYXJzZXIgQVBJLgotICAgKgotICAgKiA8cD5Ob3RlIHRoYXQgdGhlIEpBWFAgMS4xZWEyIHBhcnNlciBjcmFzaGVzIHdpdGggYW4gSW50ZXJuYWxFcnJvciBpZgotICAgKiBpdCBlbmNvdW50ZXJzIGEgc3lzdGVtIGlkZW50aWZpZXIgdGhhdCBhcHBlYXJzIHRvIGJlIGEgcmVsYXRpdmUgVVJJCi0gICAqIHRoYXQgYmVnaW5zIHdpdGggYSBzbGFzaC4gRm9yIGV4YW1wbGUsIHRoZSBkZWNsYXJhdGlvbjo8L3A+Ci0gICAqCi0gICAqIDxwcmU+Ci0gICAqICZsdDshRE9DVFlQRSBib29rIFNZU1RFTSAiL3BhdGgvdG8vZHRkL29uL215L3N5c3RlbS9kb2Nib29reC5kdGQiPgotICAgKiA8L3ByZT4KLSAgICoKLSAgICogPHA+d291bGQgY2F1c2Ugc3VjaCBhbiBlcnJvci4gQXMgYSBjb252ZW5pZW5jZSwgdGhpcyBtZXRob2QgY2F0Y2hlcwotICAgKiB0aGF0IGVycm9yIGFuZCBwcmludHMgYW4gZXhwbGFuYXRpb24uIChVbmZvcnR1bmF0ZWx5LCBpdCdzIG5vdCBwb3NzaWJsZQotICAgKiB0byBpZGVudGlmeSB0aGUgcGFydGljdWxhciBzeXN0ZW0gaWRlbnRpZmllciB0aGF0IGNhdXNlcyB0aGUgcHJvYmxlbS4pCi0gICAqIDwvcD4KLSAgICoKLSAgICogPHA+VGhlIHVuZGVybHlpbmcgZXJyb3IgaXMgZm9yd2FyZGVkIGFmdGVyIHByaW50aW5nIHRoZSBleHBsYW5hdG9yeQotICAgKiBtZXNzYWdlLiBUaGUgbWVzc2FnZSBpcyBvbmx5IGV2ZXJ5IHByaW50ZWQgb25jZSBhbmQgaWYKLSAgICogPGNvZGU+c3VwcHJlc3NFeHBsYW5hdGlvbjwvY29kZT4gaXMgc2V0IHRvIDxjb2RlPmZhbHNlPC9jb2RlPiBiZWZvcmUKLSAgICogcGFyc2luZywgaXQgd2lsbCBuZXZlciBiZSBwcmludGVkLjwvcD4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHBhcnNlKElucHV0U291cmNlIGlucHV0KQotICAgIHRocm93cyBJT0V4Y2VwdGlvbiwKLSAgICAgICAgICAgU0FYRXhjZXB0aW9uIHsKLSAgICBzZXR1cFBhcnNlKGlucHV0LmdldFN5c3RlbUlkKCkpOwotICAgIHRyeSB7Ci0gICAgICBwYXJzZXIucGFyc2UoaW5wdXQpOwotICAgIH0gY2F0Y2ggKEludGVybmFsRXJyb3IgaWUpIHsKLSAgICAgIGV4cGxhaW4oaW5wdXQuZ2V0U3lzdGVtSWQoKSk7Ci0gICAgICB0aHJvdyBpZTsKLSAgICB9Ci0gIH0KLQotICAvKiogU0FYIFBhcnNlciBBUEkuCi0gICAqCi0gICAqIEBzZWUgI3BhcnNlKElucHV0U291cmNlKQotICAgKi8KLSAgcHVibGljIHZvaWQgcGFyc2UoU3RyaW5nIHN5c3RlbUlkKQotICAgIHRocm93cyBJT0V4Y2VwdGlvbiwKLSAgICAgICAgICAgU0FYRXhjZXB0aW9uIHsKLSAgICBzZXR1cFBhcnNlKHN5c3RlbUlkKTsKLSAgICB0cnkgewotICAgICAgcGFyc2VyLnBhcnNlKHN5c3RlbUlkKTsKLSAgICB9IGNhdGNoIChJbnRlcm5hbEVycm9yIGllKSB7Ci0gICAgICBleHBsYWluKHN5c3RlbUlkKTsKLSAgICAgIHRocm93IGllOwotICAgIH0KLSAgfQotCi0gIC8qKiBTQVggUGFyc2VyIEFQSS4gKi8KLSAgcHVibGljIHZvaWQgc2V0RG9jdW1lbnRIYW5kbGVyKERvY3VtZW50SGFuZGxlciBoYW5kbGVyKSB7Ci0gICAgZG9jdW1lbnRIYW5kbGVyID0gaGFuZGxlcjsKLSAgfQotCi0gIC8qKiBTQVggUGFyc2VyIEFQSS4gKi8KLSAgcHVibGljIHZvaWQgc2V0RFRESGFuZGxlcihEVERIYW5kbGVyIGhhbmRsZXIpIHsKLSAgICBkdGRIYW5kbGVyID0gaGFuZGxlcjsKLSAgfQotCi0gIC8qKgotICAgKiBTQVggUGFyc2VyIEFQSS4KLSAgICoKLSAgICogPHA+VGhlIHB1cnBvc2Ugb2YgdGhpcyBjbGFzcyBpcyB0byBpbXBsZW1lbnQgYW4gZW50aXR5IHJlc29sdmVyLgotICAgKiBBdHRlbXB0aW5nIHRvIHNldCBhIGRpZmZlcmVudCBvbmUgaXMgcG9pbnRsZXNzIChhbmQgaWdub3JlZCkuPC9wPgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0RW50aXR5UmVzb2x2ZXIoRW50aXR5UmVzb2x2ZXIgcmVzb2x2ZXIpIHsKLSAgICAvLyBub3AKLSAgfQotCi0gIC8qKiBTQVggUGFyc2VyIEFQSS4gKi8KLSAgcHVibGljIHZvaWQgc2V0RXJyb3JIYW5kbGVyKEVycm9ySGFuZGxlciBoYW5kbGVyKSB7Ci0gICAgcGFyc2VyLnNldEVycm9ySGFuZGxlcihoYW5kbGVyKTsKLSAgfQotCi0gIC8qKiBTQVggUGFyc2VyIEFQSS4gKi8KLSAgcHVibGljIHZvaWQgc2V0TG9jYWxlKExvY2FsZSBsb2NhbGUpIHRocm93cyBTQVhFeGNlcHRpb24gewotICAgIHBhcnNlci5zZXRMb2NhbGUobG9jYWxlKTsKLSAgfQotCi0gIC8qKiBTQVggRG9jdW1lbnRIYW5kbGVyIEFQSS4gKi8KLSAgcHVibGljIHZvaWQgY2hhcmFjdGVycyhjaGFyW10gY2gsIGludCBzdGFydCwgaW50IGxlbmd0aCkKLSAgICB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICBpZiAoZG9jdW1lbnRIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgIGRvY3VtZW50SGFuZGxlci5jaGFyYWN0ZXJzKGNoLHN0YXJ0LGxlbmd0aCk7Ci0gICAgfQotICB9Ci0KLSAgLyoqIFNBWCBEb2N1bWVudEhhbmRsZXIgQVBJLiAqLwotICBwdWJsaWMgdm9pZCBlbmREb2N1bWVudCgpIHRocm93cyBTQVhFeGNlcHRpb24gewotICAgIGlmIChkb2N1bWVudEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgZG9jdW1lbnRIYW5kbGVyLmVuZERvY3VtZW50KCk7Ci0gICAgfQotICB9Ci0KLSAgLyoqIFNBWCBEb2N1bWVudEhhbmRsZXIgQVBJLiAqLwotICBwdWJsaWMgdm9pZCBlbmRFbGVtZW50KFN0cmluZyBuYW1lKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICBpZiAoZG9jdW1lbnRIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgIGRvY3VtZW50SGFuZGxlci5lbmRFbGVtZW50KG5hbWUpOwotICAgIH0KLSAgfQotCi0gIC8qKiBTQVggRG9jdW1lbnRIYW5kbGVyIEFQSS4gKi8KLSAgcHVibGljIHZvaWQgaWdub3JhYmxlV2hpdGVzcGFjZShjaGFyW10gY2gsIGludCBzdGFydCwgaW50IGxlbmd0aCkKLSAgICB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICBpZiAoZG9jdW1lbnRIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgIGRvY3VtZW50SGFuZGxlci5pZ25vcmFibGVXaGl0ZXNwYWNlKGNoLHN0YXJ0LGxlbmd0aCk7Ci0gICAgfQotICB9Ci0KLSAgLyoqIFNBWCBEb2N1bWVudEhhbmRsZXIgQVBJLiAqLwotICBwdWJsaWMgdm9pZCBwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oU3RyaW5nIHRhcmdldCwgU3RyaW5nIHBpZGF0YSkKLSAgICB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLQotICAgIGlmICh0YXJnZXQuZXF1YWxzKCJvYXNpcy14bWwtY2F0YWxvZyIpKSB7Ci0gICAgICBVUkwgY2F0YWxvZyA9IG51bGw7Ci0gICAgICBTdHJpbmcgZGF0YSA9IHBpZGF0YTsKLQotICAgICAgaW50IHBvcyA9IGRhdGEuaW5kZXhPZigiY2F0YWxvZz0iKTsKLSAgICAgIGlmIChwb3MgPj0gMCkgewotICAgICAgICBkYXRhID0gZGF0YS5zdWJzdHJpbmcocG9zKzgpOwotICAgICAgICBpZiAoZGF0YS5sZW5ndGgoKSA+IDEpIHsKLSAgICAgICAgICBTdHJpbmcgcXVvdGUgPSBkYXRhLnN1YnN0cmluZygwLDEpOwotICAgICAgICAgIGRhdGEgPSBkYXRhLnN1YnN0cmluZygxKTsKLSAgICAgICAgICBwb3MgPSBkYXRhLmluZGV4T2YocXVvdGUpOwotICAgICAgICAgIGlmIChwb3MgPj0gMCkgewotICAgICAgICAgICAgZGF0YSA9IGRhdGEuc3Vic3RyaW5nKDAsIHBvcyk7Ci0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICBpZiAoYmFzZVVSTCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgY2F0YWxvZyA9IG5ldyBVUkwoYmFzZVVSTCwgZGF0YSk7Ci0gICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgY2F0YWxvZyA9IG5ldyBVUkwoZGF0YSk7Ci0gICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0gY2F0Y2ggKE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiBtdWUpIHsKLSAgICAgICAgICAgICAgLy8gbmV2ZXJtaW5kCi0gICAgICAgICAgICB9Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICB9Ci0KLSAgICAgIGlmIChhbGxvd1hNTENhdGFsb2dQSSkgewotICAgICAgICBpZiAoY2F0YWxvZ01hbmFnZXIuZ2V0QWxsb3dPYXNpc1hNTENhdGFsb2dQSSgpKSB7Ci0gICAgICAgICAgY2F0YWxvZ01hbmFnZXIuZGVidWcubWVzc2FnZSg0LCJvYXNpcy14bWwtY2F0YWxvZyBQSSIsIHBpZGF0YSk7Ci0KLSAgICAgICAgICBpZiAoY2F0YWxvZyAhPSBudWxsKSB7Ci0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICBjYXRhbG9nTWFuYWdlci5kZWJ1Zy5tZXNzYWdlKDQsIm9hc2lzLXhtbC1jYXRhbG9nIiwgY2F0YWxvZy50b1N0cmluZygpKTsKLSAgICAgICAgICAgICAgb2FzaXNYTUxDYXRhbG9nUEkgPSB0cnVlOwotCi0gICAgICAgICAgICAgIGlmIChwaUNhdGFsb2dSZXNvbHZlciA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgcGlDYXRhbG9nUmVzb2x2ZXIgPSBuZXcgQ2F0YWxvZ1Jlc29sdmVyKHRydWUpOwotICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgcGlDYXRhbG9nUmVzb2x2ZXIuZ2V0Q2F0YWxvZygpLnBhcnNlQ2F0YWxvZyhjYXRhbG9nLnRvU3RyaW5nKCkpOwotICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgY2F0YWxvZ01hbmFnZXIuZGVidWcubWVzc2FnZSgzLCAiRXhjZXB0aW9uIHBhcnNpbmcgb2FzaXMteG1sLWNhdGFsb2c6ICIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGNhdGFsb2cudG9TdHJpbmcoKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIGNhdGFsb2dNYW5hZ2VyLmRlYnVnLm1lc3NhZ2UoMywgIlBJIG9hc2lzLXhtbC1jYXRhbG9nIHVucGFyc2VhYmxlOiAiICsgcGlkYXRhKTsKLSAgICAgICAgICB9Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgY2F0YWxvZ01hbmFnZXIuZGVidWcubWVzc2FnZSg0LCJQSSBvYXNpcy14bWwtY2F0YWxvZyBpZ25vcmVkOiAiICsgcGlkYXRhKTsKLSAgICAgICAgfQotICAgICAgfSBlbHNlIHsKLSAgICAgICAgY2F0YWxvZ01hbmFnZXIuZGVidWcubWVzc2FnZSgzLCAiUEkgb2FzaXMteG1sLWNhdGFsb2cgb2NjdXJyZWQgaW4gYW4gaW52YWxpZCBwbGFjZTogIgotICAgICAgICAgICAgICAgICAgICAgICsgcGlkYXRhKTsKLSAgICAgIH0KLSAgICB9IGVsc2UgewotICAgICAgaWYgKGRvY3VtZW50SGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgIGRvY3VtZW50SGFuZGxlci5wcm9jZXNzaW5nSW5zdHJ1Y3Rpb24odGFyZ2V0LCBwaWRhdGEpOwotICAgICAgfQotICAgIH0KLSAgfQotCi0gIC8qKiBTQVggRG9jdW1lbnRIYW5kbGVyIEFQSS4gKi8KLSAgcHVibGljIHZvaWQgc2V0RG9jdW1lbnRMb2NhdG9yKExvY2F0b3IgbG9jYXRvcikgewotICAgIGlmIChkb2N1bWVudEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgZG9jdW1lbnRIYW5kbGVyLnNldERvY3VtZW50TG9jYXRvcihsb2NhdG9yKTsKLSAgICB9Ci0gIH0KLQotICAvKiogU0FYIERvY3VtZW50SGFuZGxlciBBUEkuICovCi0gIHB1YmxpYyB2b2lkIHN0YXJ0RG9jdW1lbnQoKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICBpZiAoZG9jdW1lbnRIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgIGRvY3VtZW50SGFuZGxlci5zdGFydERvY3VtZW50KCk7Ci0gICAgfQotICB9Ci0KLSAgLyoqIFNBWCBEb2N1bWVudEhhbmRsZXIgQVBJLiAqLwotICBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQoU3RyaW5nIG5hbWUsIEF0dHJpYnV0ZUxpc3QgYXR0cykKLSAgICB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICBhbGxvd1hNTENhdGFsb2dQSSA9IGZhbHNlOwotICAgIGlmIChkb2N1bWVudEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgZG9jdW1lbnRIYW5kbGVyLnN0YXJ0RWxlbWVudChuYW1lLGF0dHMpOwotICAgIH0KLSAgfQotCi0gIC8qKiBTQVggRFRESGFuZGxlciBBUEkuICovCi0gIHB1YmxpYyB2b2lkIG5vdGF0aW9uRGVjbCAoU3RyaW5nIG5hbWUsIFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkKQotICAgIHRocm93cyBTQVhFeGNlcHRpb24gewotICAgIGFsbG93WE1MQ2F0YWxvZ1BJID0gZmFsc2U7Ci0gICAgaWYgKGR0ZEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgZHRkSGFuZGxlci5ub3RhdGlvbkRlY2wobmFtZSxwdWJsaWNJZCxzeXN0ZW1JZCk7Ci0gICAgfQotICB9Ci0KLSAgLyoqIFNBWCBEVERIYW5kbGVyIEFQSS4gKi8KLSAgcHVibGljIHZvaWQgdW5wYXJzZWRFbnRpdHlEZWNsIChTdHJpbmcgbmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcHVibGljSWQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHN5c3RlbUlkLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBub3RhdGlvbk5hbWUpCi0gICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0gICAgYWxsb3dYTUxDYXRhbG9nUEkgPSBmYWxzZTsKLSAgICBpZiAoZHRkSGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICBkdGRIYW5kbGVyLnVucGFyc2VkRW50aXR5RGVjbCAobmFtZSwgcHVibGljSWQsIHN5c3RlbUlkLCBub3RhdGlvbk5hbWUpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBJbXBsZW1lbnRzIHRoZSA8Y29kZT5yZXNvbHZlRW50aXR5PC9jb2RlPiBtZXRob2QKLSAgICogZm9yIHRoZSBTQVggaW50ZXJmYWNlLCB1c2luZyBhbiB1bmRlcmx5aW5nIENhdGFsb2dSZXNvbHZlcgotICAgKiB0byBkbyB0aGUgcmVhbCB3b3JrLgotICAgKi8KLSAgcHVibGljIElucHV0U291cmNlIHJlc29sdmVFbnRpdHkgKFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkKSB7Ci0gICAgYWxsb3dYTUxDYXRhbG9nUEkgPSBmYWxzZTsKLSAgICBTdHJpbmcgcmVzb2x2ZWQgPSBjYXRhbG9nUmVzb2x2ZXIuZ2V0UmVzb2x2ZWRFbnRpdHkocHVibGljSWQsIHN5c3RlbUlkKTsKLQotICAgIGlmIChyZXNvbHZlZCA9PSBudWxsICYmIHBpQ2F0YWxvZ1Jlc29sdmVyICE9IG51bGwpIHsKLSAgICAgIHJlc29sdmVkID0gcGlDYXRhbG9nUmVzb2x2ZXIuZ2V0UmVzb2x2ZWRFbnRpdHkocHVibGljSWQsIHN5c3RlbUlkKTsKLSAgICB9Ci0KLSAgICBpZiAocmVzb2x2ZWQgIT0gbnVsbCkgewotICAgICAgdHJ5IHsKLSAgICAgICAgSW5wdXRTb3VyY2UgaVNvdXJjZSA9IG5ldyBJbnB1dFNvdXJjZShyZXNvbHZlZCk7Ci0gICAgICAgIGlTb3VyY2Uuc2V0UHVibGljSWQocHVibGljSWQpOwotCi0gICAgICAgIC8vIElkZWFsbHkgdGhpcyBtZXRob2Qgd291bGQgbm90IGF0dGVtcHQgdG8gb3BlbiB0aGUKLSAgICAgICAgLy8gSW5wdXRTdHJlYW0sIGJ1dCB0aGVyZSBpcyBhIGJ1ZyAoaW4gWGVyY2VzLCBhdCBsZWFzdCkKLSAgICAgICAgLy8gdGhhdCBjYXVzZXMgdGhlIHBhcnNlciB0byBtaXN0YWtlbmx5IG9wZW4gdGhlIHdyb25nCi0gICAgICAgIC8vIHN5c3RlbSBpZGVudGlmaWVyIGlmIHRoZSByZXR1cm5lZCBJbnB1dFNvdXJjZSBkb2VzCi0gICAgICAgIC8vIG5vdCBoYXZlIGEgYnl0ZVN0cmVhbS4KLSAgICAgICAgLy8KLSAgICAgICAgLy8gSXQgY291bGQgYmUgYXJndWVkIHRoYXQgd2Ugc3RpbGwgc2hvdWxkbid0IGRvIHRoaXMgaGVyZSwKLSAgICAgICAgLy8gYnV0IHNpbmNlIHRoZSBwdXJwb3NlIG9mIGNhbGxpbmcgdGhlIGVudGl0eVJlc29sdmVyIGlzCi0gICAgICAgIC8vIGFsbW9zdCBjZXJ0YWlubHkgdG8gb3BlbiB0aGUgaW5wdXQgc3RyZWFtLCBpdCBzZWVtcyB0bwotICAgICAgICAvLyBkbyBsaXR0bGUgaGFybS4KLSAgICAgICAgLy8KLSAgICAgICAgVVJMIHVybCA9IG5ldyBVUkwocmVzb2x2ZWQpOwotICAgICAgICBJbnB1dFN0cmVhbSBpU3RyZWFtID0gdXJsLm9wZW5TdHJlYW0oKTsKLSAgICAgICAgaVNvdXJjZS5zZXRCeXRlU3RyZWFtKGlTdHJlYW0pOwotCi0gICAgICAgIHJldHVybiBpU291cmNlOwotICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgY2F0YWxvZ01hbmFnZXIuZGVidWcubWVzc2FnZSgxLCAiRmFpbGVkIHRvIGNyZWF0ZSBJbnB1dFNvdXJjZSIsIHJlc29sdmVkKTsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICB9Ci0gICAgfSBlbHNlIHsKLSAgICAgIHJldHVybiBudWxsOwotICAgIH0KLSAgfQotCi0gIC8qKiBTZXR1cCBmb3IgcGFyc2luZy4gKi8KLSAgcHJpdmF0ZSB2b2lkIHNldHVwUGFyc2UoU3RyaW5nIHN5c3RlbUlkKSB7Ci0gICAgYWxsb3dYTUxDYXRhbG9nUEkgPSB0cnVlOwotICAgIHBhcnNlci5zZXRFbnRpdHlSZXNvbHZlcih0aGlzKTsKLSAgICBwYXJzZXIuc2V0RG9jdW1lbnRIYW5kbGVyKHRoaXMpOwotICAgIHBhcnNlci5zZXREVERIYW5kbGVyKHRoaXMpOwotCi0gICAgVVJMIGN3ZCA9IG51bGw7Ci0KLSAgICB0cnkgewotICAgICAgY3dkID0gRmlsZVVSTC5tYWtlVVJMKCJiYXNlbmFtZSIpOwotICAgIH0gY2F0Y2ggKE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiBtdWUpIHsKLSAgICAgIGN3ZCA9IG51bGw7Ci0gICAgfQotCi0gICAgdHJ5IHsKLSAgICAgIGJhc2VVUkwgPSBuZXcgVVJMKHN5c3RlbUlkKTsKLSAgICB9IGNhdGNoIChNYWxmb3JtZWRVUkxFeGNlcHRpb24gbXVlKSB7Ci0gICAgICBpZiAoY3dkICE9IG51bGwpIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICBiYXNlVVJMID0gbmV3IFVSTChjd2QsIHN5c3RlbUlkKTsKLSAgICAgICAgfSBjYXRjaCAoTWFsZm9ybWVkVVJMRXhjZXB0aW9uIG11ZTIpIHsKLSAgICAgICAgICAvLyBnaXZlIHVwCi0gICAgICAgICAgYmFzZVVSTCA9IG51bGw7Ci0gICAgICAgIH0KLSAgICAgIH0gZWxzZSB7Ci0gICAgICAgIC8vIGdpdmUgdXAKLSAgICAgICAgYmFzZVVSTCA9IG51bGw7Ci0gICAgICB9Ci0gICAgfQotICB9Ci0KLSAgLyoqIFByb3ZpZGUgb25lIHBvc3NpYmxlIGV4cGxhbmF0aW9uIGZvciBhbiBJbnRlcm5hbEVycm9yLiAqLwotICBwcml2YXRlIHZvaWQgZXhwbGFpbihTdHJpbmcgc3lzdGVtSWQpIHsKLSAgICBpZiAoIXN1cHByZXNzRXhwbGFuYXRpb24pIHsKLSAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiUGFyc2VyIHByb2JhYmx5IGVuY291bnRlcmVkIGJhZCBVUkkgaW4gIiArIHN5c3RlbUlkKTsKLSAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiRm9yIGV4YW1wbGUsIHJlcGxhY2UgJy9zb21lL3VyaScgd2l0aCAnZmlsZTovc29tZS91cmknLiIpOwotICAgIH0KLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvcmVzb2x2ZXIvdG9vbHMvUmVzb2x2aW5nWE1MRmlsdGVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9yZXNvbHZlci90b29scy9SZXNvbHZpbmdYTUxGaWx0ZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNjYwZTRhZi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9yZXNvbHZlci90b29scy9SZXNvbHZpbmdYTUxGaWx0ZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDM1MyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLy8gUmVzb2x2aW5nWE1MRmlsdGVyLmphdmEgLSBBbiBYTUxGaWx0ZXIgdGhhdCBwZXJmb3JtcyBjYXRhbG9nIHJlc29sdXRpb24KLQotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIG9yIGl0cyBsaWNlbnNvcnMsCi0gKiBhcyBhcHBsaWNhYmxlLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzb2x2ZXIudG9vbHM7Ci0KLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5uZXQuTWFsZm9ybWVkVVJMRXhjZXB0aW9uOwotaW1wb3J0IGphdmEubmV0LlVSTDsKLQotaW1wb3J0IG9yZy54bWwuc2F4LklucHV0U291cmNlOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5YTUxSZWFkZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguQXR0cmlidXRlczsKLWltcG9ydCBvcmcueG1sLnNheC5oZWxwZXJzLlhNTEZpbHRlckltcGw7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnJlc29sdmVyLkNhdGFsb2c7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXNvbHZlci5DYXRhbG9nTWFuYWdlcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzb2x2ZXIuaGVscGVycy5GaWxlVVJMOwotCi0vKioKLSAqIEEgU0FYIFhNTEZpbHRlciB0aGF0IHBlcmZvcm1zIGNhdGFsb2ctYmFzZWQgZW50aXR5IHJlc29sdXRpb24uCi0gKgotICogPHA+VGhpcyBjbGFzcyBpbXBsZW1lbnRzIGEgU0FYIFhNTEZpbHRlciB0aGF0IHBlcmZvcm1zIGVudGl0eSByZXNvbHV0aW9uCi0gKiB1c2luZyB0aGUgQ2F0YWxvZ1Jlc29sdmVyLiBUaGUgYWN0dWFsLCB1bmRlcmx5aW5nIHBhcnNlciBpcyBvYnRhaW5lZAotICogZnJvbSBhIFNBWFBhcnNlckZhY3RvcnkuPC9wPgotICogPC9wPgotICoKLSAqIEBzZWUgQ2F0YWxvZ1Jlc29sdmVyCi0gKiBAc2VlIG9yZy54bWwuc2F4LlhNTEZpbHRlcgotICoKLSAqIEBhdXRob3IgTm9ybWFuIFdhbHNoCi0gKiA8YSBocmVmPSJtYWlsdG86Tm9ybWFuLldhbHNoQFN1bi5DT00iPk5vcm1hbi5XYWxzaEBTdW4uQ09NPC9hPgotICoKLSAqIEB2ZXJzaW9uIDEuMAotICovCi1wdWJsaWMgY2xhc3MgUmVzb2x2aW5nWE1MRmlsdGVyIGV4dGVuZHMgWE1MRmlsdGVySW1wbCB7Ci0gIC8qKgotICAgKiBTdXBwcmVzcyBleHBsYW5hdG9yeSBtZXNzYWdlPwotICAgKgotICAgKiBAc2VlICNwYXJzZShJbnB1dFNvdXJjZSkKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBzdXBwcmVzc0V4cGxhbmF0aW9uID0gZmFsc2U7Ci0KLSAgLyoqIFRoZSBtYW5hZ2VyIGZvciB0aGUgdW5kZXJseWluZyByZXNvbHZlci4gKi8KLSAgQ2F0YWxvZ01hbmFnZXIgY2F0YWxvZ01hbmFnZXIgPSBDYXRhbG9nTWFuYWdlci5nZXRTdGF0aWNNYW5hZ2VyKCk7Ci0KLSAgLyoqIFRoZSB1bmRlcmx5aW5nIGNhdGFsb2cgcmVzb2x2ZXIuICovCi0gIHByaXZhdGUgQ2F0YWxvZ1Jlc29sdmVyIGNhdGFsb2dSZXNvbHZlciA9IG51bGw7Ci0KLSAgLyoqIEEgc2VwYXJhdGUgcmVzb2x2ZXIgZm9yIG9hc2lzLXhtbC1waSBjYXRhbG9ncy4gKi8KLSAgcHJpdmF0ZSBDYXRhbG9nUmVzb2x2ZXIgcGlDYXRhbG9nUmVzb2x2ZXIgPSBudWxsOwotCi0gIC8qKiBBcmUgd2UgaW4gdGhlIHByb2xvZz8gSXMgYW4gb2FzaXMteG1sLWNhdGFsb2cgUEkgdmFsaWQgbm93PyAqLwotICBwcml2YXRlIGJvb2xlYW4gYWxsb3dYTUxDYXRhbG9nUEkgPSBmYWxzZTsKLQotICAvKiogSGFzIGFuIG9hc2lzLXhtbC1jYXRhbG9nIFBJIGJlZW4gc2Vlbj8gKi8KLSAgcHJpdmF0ZSBib29sZWFuIG9hc2lzWE1MQ2F0YWxvZ1BJID0gZmFsc2U7Ci0KLSAgLyoqIFRoZSBiYXNlIFVSSSBvZiB0aGUgaW5wdXQgZG9jdW1lbnQsIGlmIGtub3duLiAqLwotICBwcml2YXRlIFVSTCBiYXNlVVJMID0gbnVsbDsKLQotICAvKiogQ29uc3RydWN0IGFuIGVtcHR5IFhNTCBGaWx0ZXIgd2l0aCBubyBwYXJlbnQuICovCi0gIHB1YmxpYyBSZXNvbHZpbmdYTUxGaWx0ZXIoKSB7Ci0gICAgc3VwZXIoKTsKLSAgICBjYXRhbG9nUmVzb2x2ZXIgPSBuZXcgQ2F0YWxvZ1Jlc29sdmVyKGNhdGFsb2dNYW5hZ2VyKTsKLSAgfQotCi0gIC8qKiBDb25zdHJ1Y3QgYW4gWE1MIGZpbHRlciB3aXRoIHRoZSBzcGVjaWZpZWQgcGFyZW50LiAqLwotICBwdWJsaWMgUmVzb2x2aW5nWE1MRmlsdGVyKFhNTFJlYWRlciBwYXJlbnQpIHsKLSAgICBzdXBlcihwYXJlbnQpOwotICAgIGNhdGFsb2dSZXNvbHZlciA9IG5ldyBDYXRhbG9nUmVzb2x2ZXIoY2F0YWxvZ01hbmFnZXIpOwotICB9Ci0KLSAgLyoqIENvbnN0cnVjdCBhbiBYTUwgZmlsdGVyIHdpdGggdGhlIHNwZWNpZmllZCBwYXJlbnQuICovCi0gIHB1YmxpYyBSZXNvbHZpbmdYTUxGaWx0ZXIoQ2F0YWxvZ01hbmFnZXIgbWFuYWdlcikgewotICAgIHN1cGVyKCk7Ci0gICAgY2F0YWxvZ01hbmFnZXIgPSBtYW5hZ2VyOwotICAgIGNhdGFsb2dSZXNvbHZlciA9IG5ldyBDYXRhbG9nUmVzb2x2ZXIoY2F0YWxvZ01hbmFnZXIpOwotICB9Ci0KLSAgLyoqIENvbnN0cnVjdCBhbiBYTUwgZmlsdGVyIHdpdGggdGhlIHNwZWNpZmllZCBwYXJlbnQuICovCi0gIHB1YmxpYyBSZXNvbHZpbmdYTUxGaWx0ZXIoWE1MUmVhZGVyIHBhcmVudCwgQ2F0YWxvZ01hbmFnZXIgbWFuYWdlcikgewotICAgIHN1cGVyKHBhcmVudCk7Ci0gICAgY2F0YWxvZ01hbmFnZXIgPSBtYW5hZ2VyOwotICAgIGNhdGFsb2dSZXNvbHZlciA9IG5ldyBDYXRhbG9nUmVzb2x2ZXIoY2F0YWxvZ01hbmFnZXIpOwotICB9Ci0KLSAgLyoqCi0gICAqIFByb3ZpZGUgYWNjZXNzdG8gdGhlIHVuZGVybHlpbmcgQ2F0YWxvZy4KLSAgICovCi0gIHB1YmxpYyBDYXRhbG9nIGdldENhdGFsb2coKSB7Ci0gICAgcmV0dXJuIGNhdGFsb2dSZXNvbHZlci5nZXRDYXRhbG9nKCk7Ci0gIH0KLQotICAvKioKLSAgICogU0FYIFhNTFJlYWRlciBBUEkuCi0gICAqCi0gICAqIDxwPk5vdGUgdGhhdCB0aGUgSkFYUCAxLjFlYTIgcGFyc2VyIGNyYXNoZXMgd2l0aCBhbiBJbnRlcm5hbEVycm9yIGlmCi0gICAqIGl0IGVuY291bnRlcnMgYSBzeXN0ZW0gaWRlbnRpZmllciB0aGF0IGFwcGVhcnMgdG8gYmUgYSByZWxhdGl2ZSBVUkkKLSAgICogdGhhdCBiZWdpbnMgd2l0aCBhIHNsYXNoLiBGb3IgZXhhbXBsZSwgdGhlIGRlY2xhcmF0aW9uOjwvcD4KLSAgICoKLSAgICogPHByZT4KLSAgICogJmx0OyFET0NUWVBFIGJvb2sgU1lTVEVNICIvcGF0aC90by9kdGQvb24vbXkvc3lzdGVtL2RvY2Jvb2t4LmR0ZCI+Ci0gICAqIDwvcHJlPgotICAgKgotICAgKiA8cD53b3VsZCBjYXVzZSBzdWNoIGFuIGVycm9yLiBBcyBhIGNvbnZlbmllbmNlLCB0aGlzIG1ldGhvZCBjYXRjaGVzCi0gICAqIHRoYXQgZXJyb3IgYW5kIHByaW50cyBhbiBleHBsYW5hdGlvbi4gKFVuZm9ydHVuYXRlbHksIGl0J3Mgbm90IHBvc3NpYmxlCi0gICAqIHRvIGlkZW50aWZ5IHRoZSBwYXJ0aWN1bGFyIHN5c3RlbSBpZGVudGlmaWVyIHRoYXQgY2F1c2VzIHRoZSBwcm9ibGVtLikKLSAgICogPC9wPgotICAgKgotICAgKiA8cD5UaGUgdW5kZXJseWluZyBlcnJvciBpcyBmb3J3YXJkZWQgYWZ0ZXIgcHJpbnRpbmcgdGhlIGV4cGxhbmF0b3J5Ci0gICAqIG1lc3NhZ2UuIFRoZSBtZXNzYWdlIGlzIG9ubHkgZXZlcnkgcHJpbnRlZCBvbmNlIGFuZCBpZgotICAgKiA8Y29kZT5zdXBwcmVzc0V4cGxhbmF0aW9uPC9jb2RlPiBpcyBzZXQgdG8gPGNvZGU+ZmFsc2U8L2NvZGU+IGJlZm9yZQotICAgKiBwYXJzaW5nLCBpdCB3aWxsIG5ldmVyIGJlIHByaW50ZWQuPC9wPgotICAgKi8KLSAgcHVibGljIHZvaWQgcGFyc2UoSW5wdXRTb3VyY2UgaW5wdXQpCi0gICAgdGhyb3dzIElPRXhjZXB0aW9uLCBTQVhFeGNlcHRpb24gewotICAgIGFsbG93WE1MQ2F0YWxvZ1BJID0gdHJ1ZTsKLQotICAgIHNldHVwQmFzZVVSSShpbnB1dC5nZXRTeXN0ZW1JZCgpKTsKLQotICAgIHRyeSB7Ci0gICAgICBzdXBlci5wYXJzZShpbnB1dCk7Ci0gICAgfSBjYXRjaCAoSW50ZXJuYWxFcnJvciBpZSkgewotICAgICAgZXhwbGFpbihpbnB1dC5nZXRTeXN0ZW1JZCgpKTsKLSAgICAgIHRocm93IGllOwotICAgIH0KLSAgfQotCi0gIC8qKiBTQVggWE1MUmVhZGVyIEFQSS4KLSAgICoKLSAgICogQHNlZSAjcGFyc2UoSW5wdXRTb3VyY2UpCi0gICAqLwotICBwdWJsaWMgdm9pZCBwYXJzZShTdHJpbmcgc3lzdGVtSWQpCi0gICAgdGhyb3dzIElPRXhjZXB0aW9uLCBTQVhFeGNlcHRpb24gewotICAgIGFsbG93WE1MQ2F0YWxvZ1BJID0gdHJ1ZTsKLQotICAgIHNldHVwQmFzZVVSSShzeXN0ZW1JZCk7Ci0KLSAgICB0cnkgewotICAgICAgc3VwZXIucGFyc2Uoc3lzdGVtSWQpOwotICAgIH0gY2F0Y2ggKEludGVybmFsRXJyb3IgaWUpIHsKLSAgICAgIGV4cGxhaW4oc3lzdGVtSWQpOwotICAgICAgdGhyb3cgaWU7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEltcGxlbWVudHMgdGhlIDxjb2RlPnJlc29sdmVFbnRpdHk8L2NvZGU+IG1ldGhvZAotICAgKiBmb3IgdGhlIFNBWCBpbnRlcmZhY2UsIHVzaW5nIGFuIHVuZGVybHlpbmcgQ2F0YWxvZ1Jlc29sdmVyCi0gICAqIHRvIGRvIHRoZSByZWFsIHdvcmsuCi0gICAqLwotICBwdWJsaWMgSW5wdXRTb3VyY2UgcmVzb2x2ZUVudGl0eSAoU3RyaW5nIHB1YmxpY0lkLCBTdHJpbmcgc3lzdGVtSWQpIHsKLSAgICBhbGxvd1hNTENhdGFsb2dQSSA9IGZhbHNlOwotICAgIFN0cmluZyByZXNvbHZlZCA9IGNhdGFsb2dSZXNvbHZlci5nZXRSZXNvbHZlZEVudGl0eShwdWJsaWNJZCwgc3lzdGVtSWQpOwotCi0gICAgaWYgKHJlc29sdmVkID09IG51bGwgJiYgcGlDYXRhbG9nUmVzb2x2ZXIgIT0gbnVsbCkgewotICAgICAgcmVzb2x2ZWQgPSBwaUNhdGFsb2dSZXNvbHZlci5nZXRSZXNvbHZlZEVudGl0eShwdWJsaWNJZCwgc3lzdGVtSWQpOwotICAgIH0KLQotICAgIGlmIChyZXNvbHZlZCAhPSBudWxsKSB7Ci0gICAgICB0cnkgewotICAgICAgICBJbnB1dFNvdXJjZSBpU291cmNlID0gbmV3IElucHV0U291cmNlKHJlc29sdmVkKTsKLSAgICAgICAgaVNvdXJjZS5zZXRQdWJsaWNJZChwdWJsaWNJZCk7Ci0KLSAgICAgICAgLy8gSWRlYWxseSB0aGlzIG1ldGhvZCB3b3VsZCBub3QgYXR0ZW1wdCB0byBvcGVuIHRoZQotICAgICAgICAvLyBJbnB1dFN0cmVhbSwgYnV0IHRoZXJlIGlzIGEgYnVnIChpbiBYZXJjZXMsIGF0IGxlYXN0KQotICAgICAgICAvLyB0aGF0IGNhdXNlcyB0aGUgcGFyc2VyIHRvIG1pc3Rha2VubHkgb3BlbiB0aGUgd3JvbmcKLSAgICAgICAgLy8gc3lzdGVtIGlkZW50aWZpZXIgaWYgdGhlIHJldHVybmVkIElucHV0U291cmNlIGRvZXMKLSAgICAgICAgLy8gbm90IGhhdmUgYSBieXRlU3RyZWFtLgotICAgICAgICAvLwotICAgICAgICAvLyBJdCBjb3VsZCBiZSBhcmd1ZWQgdGhhdCB3ZSBzdGlsbCBzaG91bGRuJ3QgZG8gdGhpcyBoZXJlLAotICAgICAgICAvLyBidXQgc2luY2UgdGhlIHB1cnBvc2Ugb2YgY2FsbGluZyB0aGUgZW50aXR5UmVzb2x2ZXIgaXMKLSAgICAgICAgLy8gYWxtb3N0IGNlcnRhaW5seSB0byBvcGVuIHRoZSBpbnB1dCBzdHJlYW0sIGl0IHNlZW1zIHRvCi0gICAgICAgIC8vIGRvIGxpdHRsZSBoYXJtLgotICAgICAgICAvLwotICAgICAgICBVUkwgdXJsID0gbmV3IFVSTChyZXNvbHZlZCk7Ci0gICAgICAgIElucHV0U3RyZWFtIGlTdHJlYW0gPSB1cmwub3BlblN0cmVhbSgpOwotICAgICAgICBpU291cmNlLnNldEJ5dGVTdHJlYW0oaVN0cmVhbSk7Ci0KLSAgICAgICAgcmV0dXJuIGlTb3VyY2U7Ci0gICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgICBjYXRhbG9nTWFuYWdlci5kZWJ1Zy5tZXNzYWdlKDEsICJGYWlsZWQgdG8gY3JlYXRlIElucHV0U291cmNlIiwgcmVzb2x2ZWQpOwotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgIH0KLSAgICB9IGVsc2UgewotICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotICB9Ci0KLSAgLyoqIFNBWCBEVERIYW5kbGVyIEFQSS4KLSAgICoKLSAgICogPHA+Q2FwdHVyZWQgaGVyZSBvbmx5IHRvIGRldGVjdCB0aGUgZW5kIG9mIHRoZSBwcm9sb2cgc28gdGhhdAotICAgKiB3ZSBjYW4gaWdub3JlIHN1YnNlcXVlbnQgb2FzaXMteG1sLWNhdGFsb2cgUElzLiBPdGhlcndpc2UKLSAgICogdGhlIGV2ZW50cyBhcmUganVzdCBwYXNzZWQgdGhyb3VnaC48L3A+Ci0gICAqLwotICBwdWJsaWMgdm9pZCBub3RhdGlvbkRlY2wgKFN0cmluZyBuYW1lLCBTdHJpbmcgcHVibGljSWQsIFN0cmluZyBzeXN0ZW1JZCkKLSAgICB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICBhbGxvd1hNTENhdGFsb2dQSSA9IGZhbHNlOwotICAgIHN1cGVyLm5vdGF0aW9uRGVjbChuYW1lLHB1YmxpY0lkLHN5c3RlbUlkKTsKLSAgfQotCi0gIC8qKiBTQVggRFRESGFuZGxlciBBUEkuCi0gICAqCi0gICAqIDxwPkNhcHR1cmVkIGhlcmUgb25seSB0byBkZXRlY3QgdGhlIGVuZCBvZiB0aGUgcHJvbG9nIHNvIHRoYXQKLSAgICogd2UgY2FuIGlnbm9yZSBzdWJzZXF1ZW50IG9hc2lzLXhtbC1jYXRhbG9nIFBJcy4gT3RoZXJ3aXNlCi0gICAqIHRoZSBldmVudHMgYXJlIGp1c3QgcGFzc2VkIHRocm91Z2guPC9wPgotICAgKi8KLSAgcHVibGljIHZvaWQgdW5wYXJzZWRFbnRpdHlEZWNsIChTdHJpbmcgbmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcHVibGljSWQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHN5c3RlbUlkLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBub3RhdGlvbk5hbWUpCi0gICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0gICAgYWxsb3dYTUxDYXRhbG9nUEkgPSBmYWxzZTsKLSAgICBzdXBlci51bnBhcnNlZEVudGl0eURlY2wgKG5hbWUsIHB1YmxpY0lkLCBzeXN0ZW1JZCwgbm90YXRpb25OYW1lKTsKLSAgfQotCi0gIC8qKiBTQVggQ29udGVudEhhbmRsZXIgQVBJLgotICAgKgotICAgKiA8cD5DYXB0dXJlZCBoZXJlIG9ubHkgdG8gZGV0ZWN0IHRoZSBlbmQgb2YgdGhlIHByb2xvZyBzbyB0aGF0Ci0gICAqIHdlIGNhbiBpZ25vcmUgc3Vic2VxdWVudCBvYXNpcy14bWwtY2F0YWxvZyBQSXMuIE90aGVyd2lzZQotICAgKiB0aGUgZXZlbnRzIGFyZSBqdXN0IHBhc3NlZCB0aHJvdWdoLjwvcD4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudCAoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSwgU3RyaW5nIHFOYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0dHJpYnV0ZXMgYXR0cykKLSAgICB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICBhbGxvd1hNTENhdGFsb2dQSSA9IGZhbHNlOwotICAgIHN1cGVyLnN0YXJ0RWxlbWVudCh1cmksbG9jYWxOYW1lLHFOYW1lLGF0dHMpOwotICB9Ci0KLSAgLyoqIFNBWCBDb250ZW50SGFuZGxlciBBUEkuCi0gICAqCi0gICAqIDxwPkRldGVjdCBhbmQgdXNlIHRoZSBvYXNpcy14bWwtY2F0YWxvZyBQSSBpZiBpdCBvY2N1cnMuPC9wPgotICAgKi8KLSAgcHVibGljIHZvaWQgcHJvY2Vzc2luZ0luc3RydWN0aW9uKFN0cmluZyB0YXJnZXQsIFN0cmluZyBwaWRhdGEpCi0gICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0gICAgaWYgKHRhcmdldC5lcXVhbHMoIm9hc2lzLXhtbC1jYXRhbG9nIikpIHsKLSAgICAgIFVSTCBjYXRhbG9nID0gbnVsbDsKLSAgICAgIFN0cmluZyBkYXRhID0gcGlkYXRhOwotCi0gICAgICBpbnQgcG9zID0gZGF0YS5pbmRleE9mKCJjYXRhbG9nPSIpOwotICAgICAgaWYgKHBvcyA+PSAwKSB7Ci0gICAgICAgIGRhdGEgPSBkYXRhLnN1YnN0cmluZyhwb3MrOCk7Ci0gICAgICAgIGlmIChkYXRhLmxlbmd0aCgpID4gMSkgewotICAgICAgICAgIFN0cmluZyBxdW90ZSA9IGRhdGEuc3Vic3RyaW5nKDAsMSk7Ci0gICAgICAgICAgZGF0YSA9IGRhdGEuc3Vic3RyaW5nKDEpOwotICAgICAgICAgIHBvcyA9IGRhdGEuaW5kZXhPZihxdW90ZSk7Ci0gICAgICAgICAgaWYgKHBvcyA+PSAwKSB7Ci0gICAgICAgICAgICBkYXRhID0gZGF0YS5zdWJzdHJpbmcoMCwgcG9zKTsKLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgIGlmIChiYXNlVVJMICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBjYXRhbG9nID0gbmV3IFVSTChiYXNlVVJMLCBkYXRhKTsKLSAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBjYXRhbG9nID0gbmV3IFVSTChkYXRhKTsKLSAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfSBjYXRjaCAoTWFsZm9ybWVkVVJMRXhjZXB0aW9uIG11ZSkgewotICAgICAgICAgICAgICAvLyBuZXZlcm1pbmQKLSAgICAgICAgICAgIH0KLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgIH0KLQotICAgICAgaWYgKGFsbG93WE1MQ2F0YWxvZ1BJKSB7Ci0gICAgICAgIGlmIChjYXRhbG9nTWFuYWdlci5nZXRBbGxvd09hc2lzWE1MQ2F0YWxvZ1BJKCkpIHsKLSAgICAgICAgICBjYXRhbG9nTWFuYWdlci5kZWJ1Zy5tZXNzYWdlKDQsIm9hc2lzLXhtbC1jYXRhbG9nIFBJIiwgcGlkYXRhKTsKLQotICAgICAgICAgIGlmIChjYXRhbG9nICE9IG51bGwpIHsKLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgIGNhdGFsb2dNYW5hZ2VyLmRlYnVnLm1lc3NhZ2UoNCwib2FzaXMteG1sLWNhdGFsb2ciLCBjYXRhbG9nLnRvU3RyaW5nKCkpOwotICAgICAgICAgICAgICBvYXNpc1hNTENhdGFsb2dQSSA9IHRydWU7Ci0KLSAgICAgICAgICAgICAgaWYgKHBpQ2F0YWxvZ1Jlc29sdmVyID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBwaUNhdGFsb2dSZXNvbHZlciA9IG5ldyBDYXRhbG9nUmVzb2x2ZXIodHJ1ZSk7Ci0gICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICBwaUNhdGFsb2dSZXNvbHZlci5nZXRDYXRhbG9nKCkucGFyc2VDYXRhbG9nKGNhdGFsb2cudG9TdHJpbmcoKSk7Ci0gICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICBjYXRhbG9nTWFuYWdlci5kZWJ1Zy5tZXNzYWdlKDMsICJFeGNlcHRpb24gcGFyc2luZyBvYXNpcy14bWwtY2F0YWxvZzogIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgY2F0YWxvZy50b1N0cmluZygpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgY2F0YWxvZ01hbmFnZXIuZGVidWcubWVzc2FnZSgzLCAiUEkgb2FzaXMteG1sLWNhdGFsb2cgdW5wYXJzZWFibGU6ICIgKyBwaWRhdGEpOwotICAgICAgICAgIH0KLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICBjYXRhbG9nTWFuYWdlci5kZWJ1Zy5tZXNzYWdlKDQsIlBJIG9hc2lzLXhtbC1jYXRhbG9nIGlnbm9yZWQ6ICIgKyBwaWRhdGEpOwotICAgICAgICB9Ci0gICAgICB9IGVsc2UgewotICAgICAgICBjYXRhbG9nTWFuYWdlci5kZWJ1Zy5tZXNzYWdlKDMsICJQSSBvYXNpcy14bWwtY2F0YWxvZyBvY2N1cnJlZCBpbiBhbiBpbnZhbGlkIHBsYWNlOiAiCi0gICAgICAgICAgICAgICAgICAgICAgKyBwaWRhdGEpOwotICAgICAgfQotICAgIH0gZWxzZSB7Ci0gICAgICBzdXBlci5wcm9jZXNzaW5nSW5zdHJ1Y3Rpb24odGFyZ2V0LCBwaWRhdGEpOwotICAgIH0KLSAgfQotCi0gIC8qKiBTYXZlIHRoZSBiYXNlIFVSSSBvZiB0aGUgZG9jdW1lbnQgYmVpbmcgcGFyc2VkLiAqLwotICBwcml2YXRlIHZvaWQgc2V0dXBCYXNlVVJJKFN0cmluZyBzeXN0ZW1JZCkgewotICAgIFVSTCBjd2QgPSBudWxsOwotCi0gICAgdHJ5IHsKLSAgICAgIGN3ZCA9IEZpbGVVUkwubWFrZVVSTCgiYmFzZW5hbWUiKTsKLSAgICB9IGNhdGNoIChNYWxmb3JtZWRVUkxFeGNlcHRpb24gbXVlKSB7Ci0gICAgICBjd2QgPSBudWxsOwotICAgIH0KLQotICAgIHRyeSB7Ci0gICAgICBiYXNlVVJMID0gbmV3IFVSTChzeXN0ZW1JZCk7Ci0gICAgfSBjYXRjaCAoTWFsZm9ybWVkVVJMRXhjZXB0aW9uIG11ZSkgewotICAgICAgaWYgKGN3ZCAhPSBudWxsKSB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgYmFzZVVSTCA9IG5ldyBVUkwoY3dkLCBzeXN0ZW1JZCk7Ci0gICAgICAgIH0gY2F0Y2ggKE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiBtdWUyKSB7Ci0gICAgICAgICAgLy8gZ2l2ZSB1cAotICAgICAgICAgIGJhc2VVUkwgPSBudWxsOwotICAgICAgICB9Ci0gICAgICB9IGVsc2UgewotICAgICAgICAvLyBnaXZlIHVwCi0gICAgICAgIGJhc2VVUkwgPSBudWxsOwotICAgICAgfQotICAgIH0KLSAgfQotCi0gIC8qKiBQcm92aWRlIG9uZSBwb3NzaWJsZSBleHBsYW5hdGlvbiBmb3IgYW4gSW50ZXJuYWxFcnJvci4gKi8KLSAgcHJpdmF0ZSB2b2lkIGV4cGxhaW4oU3RyaW5nIHN5c3RlbUlkKSB7Ci0gICAgaWYgKCFzdXBwcmVzc0V4cGxhbmF0aW9uKSB7Ci0gICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlhNTFJlYWRlciBwcm9iYWJseSBlbmNvdW50ZXJlZCBiYWQgVVJJIGluICIgKyBzeXN0ZW1JZCk7Ci0gICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkZvciBleGFtcGxlLCByZXBsYWNlICcvc29tZS91cmknIHdpdGggJ2ZpbGU6L3NvbWUvdXJpJy4iKTsKLSAgICB9Ci0gICAgc3VwcHJlc3NFeHBsYW5hdGlvbiA9IHRydWU7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3Jlc29sdmVyL3Rvb2xzL1Jlc29sdmluZ1hNTFJlYWRlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvcmVzb2x2ZXIvdG9vbHMvUmVzb2x2aW5nWE1MUmVhZGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDBhOThjZDguLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvcmVzb2x2ZXIvdG9vbHMvUmVzb2x2aW5nWE1MUmVhZGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5NyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLy8gUmVzb2x2aW5nWE1MUmVhZGVyLmphdmEgLSBBbiBYTUxSZWFkZXIgdGhhdCBwZXJmb3JtcyBjYXRhbG9nIHJlc29sdXRpb24KLQotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIG9yIGl0cyBsaWNlbnNvcnMsCi0gKiBhcyBhcHBsaWNhYmxlLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzb2x2ZXIudG9vbHM7Ci0KLWltcG9ydCBvcmcueG1sLnNheC4qOwotCi1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuKjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuamF4cC5TQVhQYXJzZXJGYWN0b3J5SW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnJlc29sdmVyLio7Ci0KLS8qKgotICogQSBTQVggWE1MUmVhZGVyIHRoYXQgcGVyZm9ybXMgY2F0YWxvZy1iYXNlZCBlbnRpdHkgcmVzb2x1dGlvbi4KLSAqCi0gKiA8cD5UaGlzIGNsYXNzIGltcGxlbWVudHMgYSBTQVggWE1MUmVhZGVyIHRoYXQgcGVyZm9ybXMgZW50aXR5IHJlc29sdXRpb24KLSAqIHVzaW5nIHRoZSBDYXRhbG9nUmVzb2x2ZXIuIFRoZSBhY3R1YWwsIHVuZGVybHlpbmcgcGFyc2VyIGlzIG9idGFpbmVkCi0gKiBmcm9tIGEgU0FYUGFyc2VyRmFjdG9yeS48L3A+Ci0gKiA8L3A+Ci0gKgotICogQHNlZSBDYXRhbG9nUmVzb2x2ZXIKLSAqIEBzZWUgb3JnLnhtbC5zYXguWE1MUmVhZGVyCi0gKgotICogQGF1dGhvciBOb3JtYW4gV2Fsc2gKLSAqIDxhIGhyZWY9Im1haWx0bzpOb3JtYW4uV2Fsc2hAU3VuLkNPTSI+Tm9ybWFuLldhbHNoQFN1bi5DT008L2E+Ci0gKgotICogQHZlcnNpb24gMS4wCi0gKi8KLXB1YmxpYyBjbGFzcyBSZXNvbHZpbmdYTUxSZWFkZXIgZXh0ZW5kcyBSZXNvbHZpbmdYTUxGaWx0ZXIgewotICAvKiogTWFrZSB0aGUgcGFyc2VyIE5hbWVzcGFjZSBhd2FyZT8gKi8KLSAgcHVibGljIHN0YXRpYyBib29sZWFuIG5hbWVzcGFjZUF3YXJlID0gdHJ1ZTsKLQotICAvKiogTWFrZSB0aGUgcGFyc2VyIHZhbGlkYXRpbmc/ICovCi0gIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiB2YWxpZGF0aW5nID0gZmFsc2U7Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhIG5ldyByZWFkZXIgZnJvbSB0aGUgSkFYUCBmYWN0b3J5LgotICAgKgotICAgKiA8cD5JbiBvcmRlciB0byBkbyBpdHMgam9iLCBhIFJlc29sdmluZ1hNTFJlYWRlciBtdXN0IGluIGZhY3QgYmUKLSAgICogYSBmaWx0ZXIuIFNvIHRoZSBvbmx5IGRpZmZlcmVuY2UgYmV0d2VlbiB0aGlzIGNvZGUgYW5kIHRoZSBmaWx0ZXIKLSAgICogY29kZSBpcyB0aGF0IHRoZSBjb25zdHJ1Y3RvciBidWlsZHMgYSBuZXcgcmVhZGVyLjwvcD4KLSAgICovCi0gIHB1YmxpYyBSZXNvbHZpbmdYTUxSZWFkZXIoKSB7Ci0gICAgc3VwZXIoKTsKLSAgICBTQVhQYXJzZXJGYWN0b3J5IHNwZiA9IGNhdGFsb2dNYW5hZ2VyLnVzZVNlcnZpY2VzTWVjaGFuaXNtKCkgPwotICAgICAgICAgICAgICAgICAgICBTQVhQYXJzZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCkgOiBuZXcgU0FYUGFyc2VyRmFjdG9yeUltcGwoKTsKLSAgICBzcGYuc2V0TmFtZXNwYWNlQXdhcmUobmFtZXNwYWNlQXdhcmUpOwotICAgIHNwZi5zZXRWYWxpZGF0aW5nKHZhbGlkYXRpbmcpOwotICAgIHRyeSB7Ci0gICAgICBTQVhQYXJzZXIgcGFyc2VyID0gc3BmLm5ld1NBWFBhcnNlcigpOwotICAgICAgc2V0UGFyZW50KHBhcnNlci5nZXRYTUxSZWFkZXIoKSk7Ci0gICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7Ci0gICAgICBleC5wcmludFN0YWNrVHJhY2UoKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgbmV3IHJlYWRlciBmcm9tIHRoZSBKQVhQIGZhY3RvcnkuCi0gICAqCi0gICAqIDxwPkluIG9yZGVyIHRvIGRvIGl0cyBqb2IsIGEgUmVzb2x2aW5nWE1MUmVhZGVyIG11c3QgaW4gZmFjdCBiZQotICAgKiBhIGZpbHRlci4gU28gdGhlIG9ubHkgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoaXMgY29kZSBhbmQgdGhlIGZpbHRlcgotICAgKiBjb2RlIGlzIHRoYXQgdGhlIGNvbnN0cnVjdG9yIGJ1aWxkcyBhIG5ldyByZWFkZXIuPC9wPgotICAgKi8KLSAgcHVibGljIFJlc29sdmluZ1hNTFJlYWRlcihDYXRhbG9nTWFuYWdlciBtYW5hZ2VyKSB7Ci0gICAgc3VwZXIobWFuYWdlcik7Ci0gICAgU0FYUGFyc2VyRmFjdG9yeSBzcGYgPSBjYXRhbG9nTWFuYWdlci51c2VTZXJ2aWNlc01lY2hhbmlzbSgpID8KLSAgICAgICAgICAgICAgICAgICAgU0FYUGFyc2VyRmFjdG9yeS5uZXdJbnN0YW5jZSgpIDogbmV3IFNBWFBhcnNlckZhY3RvcnlJbXBsKCk7Ci0gICAgc3BmLnNldE5hbWVzcGFjZUF3YXJlKG5hbWVzcGFjZUF3YXJlKTsKLSAgICBzcGYuc2V0VmFsaWRhdGluZyh2YWxpZGF0aW5nKTsKLSAgICB0cnkgewotICAgICAgU0FYUGFyc2VyIHBhcnNlciA9IHNwZi5uZXdTQVhQYXJzZXIoKTsKLSAgICAgIHNldFBhcmVudChwYXJzZXIuZ2V0WE1MUmVhZGVyKCkpOwotICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgewotICAgICAgZXgucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgfQotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemUvQmFzZU1hcmt1cFNlcmlhbGl6ZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZS9CYXNlTWFya3VwU2VyaWFsaXplci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmNGQ1YTFjLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZS9CYXNlTWFya3VwU2VyaWFsaXplci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTk2NyArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDE1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICovCi0vKgotICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCi0gKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKLSAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KLSAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCi0gKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAotICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotLy8gU2VwIDE0LCAyMDAwOgotLy8gIEZpeGVkIGNvbW1lbnRzIHRvIHByZXNlcnZlIHdoaXRlc3BhY2VzIGFuZCBhZGQgYSBsaW5lIGJyZWFrCi0vLyAgd2hlbiBpbmRlbnRpbmcuIFJlcG9ydGVkIGJ5IEdlcnZhc2UgTWFya2hhbSA8Z2VydkBnZXJ2Lm5ldD4KLS8vIFNlcCAxNCwgMjAwMDoKLS8vICBGaXhlZCBzZXJpYWxpemVyIHRvIHJlcG9ydCBJTyBleGNlcHRpb24gZGlyZWN0bHksIGluc3RlYWQgYXQKLS8vICB0aGUgZW5kIG9mIGRvY3VtZW50IHByb2Nlc3NpbmcuCi0vLyAgUmVwb3J0ZWQgYnkgUGF0cmljayBIaWdnaW5zIDxwaGlnZ2luc0B0cmFuc3phcC5jb20+Ci0vLyBTZXAgMTMsIDIwMDA6Ci0vLyAgIENSIGluIGNoYXJhY3RlciBkYXRhIHdpbGwgcHJpbnQgYXMgJiMwRDsKLS8vIEF1ZyAyNSwgMjAwMDoKLS8vICAgRml4ZWQgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiBwcmludGluZyBpbnNpZGUgZWxlbWVudCBjb250ZW50Ci0vLyAgIHRvIG5vdCBlc2NhcGUgY29udGVudC4gUmVwb3J0ZWQgYnkgTWlrYWVsIFN0YWxkYWwKLS8vICAgPGQ5Ni1tc3RAZC5rdGguc2U+Ci0vLyBBdWcgMjUsIDIwMDA6Ci0vLyAgIEFkZGVkIGFiaWxpdHkgdG8gb21pdCBjb21tZW50cy4KLS8vICAgQ29udHJpYnV0ZWQgYnkgQW51cGFtIEJhZ2NoaSA8YWJhZ2NoaUBqdGNzdi5jb20+Ci0vLyBBdWcgMjYsIDIwMDA6Ci0vLyAgIEZpeGVkIGJ1ZyBpbiBuZXdsaW5lIGhhbmRsaW5nIHdoZW4gcHJlc2VydmluZyBzcGFjZXMuCi0vLyAgIENvbnRyaWJ1dGVkIGJ5IE1pa2UgRHVzc2VhdWx0IDxtZHVzc2VhdWx0QGhvbWUuY29tPgotLy8gQXVnIDI5LCAyMDAwOgotLy8gICBGaXhlZCBzdGF0ZS51bmVzY2FwZWQgbm90IGJlaW5nIHNldCB0byBmYWxzZSB3aGVuCi0vLyAgIGVudGVyaW5nIGVsZW1lbnQgc3RhdGUuCi0vLyAgIFJlcG9ydGVkIGJ5IExvd2VsbCBWYXVnaG4gPGx2YXVnaG5AYWdpbGxpb24uY29tPgotCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemU7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbS5ET01FcnJvckltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5kb20uRE9NTG9jYXRvckltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5kb20uRE9NTWVzc2FnZUZvcm1hdHRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuWE1MQ2hhcjsKLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uV3JpdGVyOwotaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwotaW1wb3J0IGphdmEudXRpbC5NYXA7Ci1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotaW1wb3J0IG9yZy53M2MuZG9tLkRPTUVycm9yOwotaW1wb3J0IG9yZy53M2MuZG9tLkRPTUVycm9ySGFuZGxlcjsKLWltcG9ydCBvcmcudzNjLmRvbS5ET01JbXBsZW1lbnRhdGlvbjsKLWltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKLWltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudEZyYWdtZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50VHlwZTsKLWltcG9ydCBvcmcudzNjLmRvbS5FbGVtZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLkVudGl0eTsKLWltcG9ydCBvcmcudzNjLmRvbS5OYW1lZE5vZGVNYXA7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob3RhdGlvbjsKLWltcG9ydCBvcmcudzNjLmRvbS5scy5MU0V4Y2VwdGlvbjsKLWltcG9ydCBvcmcudzNjLmRvbS5scy5MU1NlcmlhbGl6ZXJGaWx0ZXI7Ci1pbXBvcnQgb3JnLnczYy5kb20udHJhdmVyc2FsLk5vZGVGaWx0ZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguRFRESGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5Eb2N1bWVudEhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguTG9jYXRvcjsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguZXh0LkRlY2xIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LmV4dC5MZXhpY2FsSGFuZGxlcjsKLQotLyoqCi0gKiBCYXNlIGNsYXNzIGZvciBhIHNlcmlhbGl6ZXIgc3VwcG9ydGluZyBib3RoIERPTSBhbmQgU0FYIHByZXR0eQotICogc2VyaWFsaXppbmcgb2YgWE1ML0hUTUwvWEhUTUwgZG9jdW1lbnRzLiBEZXJpdmVzIGNsYXNzZXMgcGVyZm9ybQotICogdGhlIG1ldGhvZC1zcGVjaWZpYyBzZXJpYWxpemluZywgdGhpcyBjbGFzcyBwcm92aWRlcyB0aGUgY29tbW9uCi0gKiBzZXJpYWxpemluZyBtZWNoYW5pc21zLgotICogPHA+Ci0gKiBUaGUgc2VyaWFsaXplciBtdXN0IGJlIGluaXRpYWxpemVkIHdpdGggdGhlIHByb3BlciB3cml0ZXIgYW5kCi0gKiBvdXRwdXQgZm9ybWF0IGJlZm9yZSBpdCBjYW4gYmUgdXNlZCBieSBjYWxsaW5nIHtAbGluayAjc2V0T3V0cHV0Q2hhclN0cmVhbX0KLSAqIG9yIHtAbGluayAjc2V0T3V0cHV0Qnl0ZVN0cmVhbX0gZm9yIHRoZSB3cml0ZXIgYW5kIHtAbGluayAjc2V0T3V0cHV0Rm9ybWF0fQotICogZm9yIHRoZSBvdXRwdXQgZm9ybWF0LgotICogPHA+Ci0gKiBUaGUgc2VyaWFsaXplciBjYW4gYmUgcmV1c2VkIGFueSBudW1iZXIgb2YgdGltZXMsIGJ1dCBjYW5ub3QKLSAqIGJlIHVzZWQgY29uY3VycmVudGx5IGJ5IHR3byB0aHJlYWRzLgotICogPHA+Ci0gKiBJZiBhbiBvdXRwdXQgc3RyZWFtIGlzIHVzZWQsIHRoZSBlbmNvZGluZyBpcyB0YWtlbiBmcm9tIHRoZQotICogb3V0cHV0IGZvcm1hdCAoZGVmYXVsdHMgdG8gPHR0PlVURi04PC90dD4pLiBJZiBhIHdyaXRlciBpcwotICogdXNlZCwgbWFrZSBzdXJlIHRoZSB3cml0ZXIgdXNlcyB0aGUgc2FtZSBlbmNvZGluZyAoaWYgYXBwbGllcykKLSAqIGFzIHNwZWNpZmllZCBpbiB0aGUgb3V0cHV0IGZvcm1hdC4KLSAqIDxwPgotICogVGhlIHNlcmlhbGl6ZXIgc3VwcG9ydHMgYm90aCBET00gYW5kIFNBWC4gRE9NIHNlcmlhbGl6aW5nIGlzIGRvbmUKLSAqIGJ5IGNhbGxpbmcge0BsaW5rICNzZXJpYWxpemUoRG9jdW1lbnQpfSBhbmQgU0FYIHNlcmlhbGl6aW5nIGlzIGRvbmUgYnkgZmlyaW5nCi0gKiBTQVggZXZlbnRzIGFuZCB1c2luZyB0aGUgc2VyaWFsaXplciBhcyBhIGRvY3VtZW50IGhhbmRsZXIuCi0gKiBUaGlzIGFsc28gYXBwbGllcyB0byBkZXJpdmVkIGNsYXNzLgotICogPHA+Ci0gKiBJZiBhbiBJL08gZXhjZXB0aW9uIG9jY3VycyB3aGlsZSBzZXJpYWxpemluZywgdGhlIHNlcmlhbGl6ZXIKLSAqIHdpbGwgbm90IHRocm93IGFuIGV4Y2VwdGlvbiBkaXJlY3RseSwgYnV0IG9ubHkgdGhyb3cgaXQKLSAqIGF0IHRoZSBlbmQgb2Ygc2VyaWFsaXppbmcgKGVpdGhlciBET00gb3IgU0FYJ3Mge0BsaW5rCi0gKiBvcmcueG1sLnNheC5Eb2N1bWVudEhhbmRsZXIjZW5kRG9jdW1lbnR9LgotICogPHA+Ci0gKiBGb3IgZWxlbWVudHMgdGhhdCBhcmUgbm90IHNwZWNpZmllZCBhcyB3aGl0ZXNwYWNlIHByZXNlcnZpbmcsCi0gKiB0aGUgc2VyaWFsaXplciB3aWxsIHBvdGVudGlhbGx5IGJyZWFrIGxvbmcgdGV4dCBsaW5lcyBhdCBzcGFjZQotICogYm91bmRhcmllcywgaW5kZW50IGxpbmVzLCBhbmQgc2VyaWFsaXplIGVsZW1lbnRzIG9uIHNlcGFyYXRlCi0gKiBsaW5lcy4gTGluZSB0ZXJtaW5hdG9ycyB3aWxsIGJlIHJlZ2FyZGVkIGFzIHNwYWNlcywgYW5kCi0gKiBzcGFjZXMgYXQgYmVnaW5uaW5nIG9mIGxpbmUgd2lsbCBiZSBzdHJpcHBlZC4KLSAqIDxwPgotICogV2hlbiBpbmRlbnRpbmcsIHRoZSBzZXJpYWxpemVyIGlzIGNhcGFibGUgb2YgZGV0ZWN0aW5nIHNlZW1pbmdseQotICogZWxlbWVudCBjb250ZW50LCBhbmQgc2VyaWFsaXppbmcgdGhlc2UgZWxlbWVudHMgaW5kZW50ZWQgb24gc2VwYXJhdGUKLSAqIGxpbmVzLiBBbiBlbGVtZW50IGlzIHNlcmlhbGl6ZWQgaW5kZW50ZWQgd2hlbiBpdCBpcyB0aGUgZmlyc3Qgb3IKLSAqIGxhc3QgY2hpbGQgb2YgYW4gZWxlbWVudCwgb3IgaW1tZWRpYXRlIGZvbGxvd2luZyBvciBwcmVjZWRpbmcKLSAqIGFub3RoZXIgZWxlbWVudC4KLSAqCi0gKgotICogQGF1dGhvciA8YSBocmVmPSJtYWlsdG86YXJraW5AaW50YWxpby5jb20iPkFzc2FmIEFya2luPC9hPgotICogQGF1dGhvciA8YSBocmVmPSJtYWlsdG86cmFodWwuc3JpdmFzdGF2YUBzdW4uY29tIj5SYWh1bCBTcml2YXN0YXZhPC9hPgotICogQGF1dGhvciBFbGVuYSBMaXRhbmksIElCTQotICogQGF1dGhvciBTdW5pdGhhIFJlZGR5LCBTdW4gTWljcm9zeXN0ZW1zCi0gKiBAc2VlIFNlcmlhbGl6ZXIKLSAqIEBzZWUgTFNTZXJpYWxpemVyCi0gKi8KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBCYXNlTWFya3VwU2VyaWFsaXplcgotICAgIGltcGxlbWVudHMgQ29udGVudEhhbmRsZXIsIERvY3VtZW50SGFuZGxlciwgTGV4aWNhbEhhbmRsZXIsCi0gICAgICAgICAgICAgICBEVERIYW5kbGVyLCBEZWNsSGFuZGxlciwgRE9NU2VyaWFsaXplciwgU2VyaWFsaXplcgotewotCi0gICAgLy8gRE9NIEwzIGltcGxlbWVudGF0aW9uCi0gICAgcHJvdGVjdGVkIHNob3J0IGZlYXR1cmVzID0gMHhGRkZGRkZGRjsKLSAgICBwcm90ZWN0ZWQgRE9NRXJyb3JIYW5kbGVyIGZET01FcnJvckhhbmRsZXI7Ci0gICAgcHJvdGVjdGVkIGZpbmFsIERPTUVycm9ySW1wbCBmRE9NRXJyb3IgPSBuZXcgRE9NRXJyb3JJbXBsKCk7Ci0gICAgcHJvdGVjdGVkIExTU2VyaWFsaXplckZpbHRlciBmRE9NRmlsdGVyOwotCi0gICAgcHJvdGVjdGVkIEVuY29kaW5nSW5mbyBfZW5jb2RpbmdJbmZvOwotCi0KLSAgICAvKioKLSAgICAgKiBIb2xkcyBhcnJheSBvZiBhbGwgZWxlbWVudCBzdGF0ZXMgdGhhdCBoYXZlIGJlZW4gZW50ZXJlZC4KLSAgICAgKiBUaGUgYXJyYXkgaXMgYXV0b21hdGljYWxseSByZXNpemVkLiBXaGVuIGxlYXZpbmcgYW4gZWxlbWVudCwKLSAgICAgKiBpdCdzIHN0YXRlIGlzIG5vdCByZW1vdmVkIGJ1dCByZXVzZWQgd2hlbiBsYXRlciByZXR1cm5pbmcKLSAgICAgKiB0byB0aGUgc2FtZSBuZXN0aW5nIGxldmVsLgotICAgICAqLwotICAgIHByaXZhdGUgRWxlbWVudFN0YXRlW10gIF9lbGVtZW50U3RhdGVzOwotCi0KLSAgICAvKioKLSAgICAgKiBUaGUgaW5kZXggb2YgdGhlIG5leHQgc3RhdGUgdG8gcGxhY2UgaW4gdGhlIGFycmF5LAotICAgICAqIG9yIG9uZSBwbHVzIHRoZSBpbmRleCBvZiB0aGUgY3VycmVudCBzdGF0ZS4gV2hlbiB6ZXJvLAotICAgICAqIHdlIGFyZSBpbiBubyBzdGF0ZS4KLSAgICAgKi8KLSAgICBwcml2YXRlIGludCAgICAgICAgICAgICBfZWxlbWVudFN0YXRlQ291bnQ7Ci0KLQotICAgIC8qKgotICAgICAqIFZlY3RvciBob2xkaW5nIGNvbW1lbnRzIGFuZCBQSXMgdGhhdCBjb21lIGJlZm9yZSB0aGUgcm9vdAotICAgICAqIGVsZW1lbnQgKGV2ZW4gYWZ0ZXIgaXQpLCBzZWUge0BsaW5rICNzZXJpYWxpemVQcmVSb290fS4KLSAgICAgKi8KLSAgICBwcml2YXRlIFZlY3RvciAgICAgICAgICBfcHJlUm9vdDsKLQotCi0gICAgLyoqCi0gICAgICogSWYgdGhlIGRvY3VtZW50IGhhcyBiZWVuIHN0YXJ0ZWQgKGhlYWRlciBzZXJpYWxpemVkKSwgdGhpcwotICAgICAqIGZsYWcgaXMgc2V0IHRvIHRydWUgc28gaXQncyBub3Qgc3RhcnRlZCB0d2ljZS4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiAgICAgICBfc3RhcnRlZDsKLQotCi0gICAgLyoqCi0gICAgICogVHJ1ZSBpZiB0aGUgc2VyaWFsaXplciBoYXMgYmVlbiBwcmVwYXJlZC4gVGhpcyBmbGFnIGlzIHNldAotICAgICAqIHRvIGZhbHNlIHdoZW4gdGhlIHNlcmlhbGl6ZXIgaXMgcmVzZXQgcHJpb3IgdG8gdXNpbmcgaXQsCi0gICAgICogYW5kIHRvIHRydWUgYWZ0ZXIgaXQgaGFzIGJlZW4gcHJlcGFyZWQgZm9yIHVzYWdlLgotICAgICAqLwotICAgIHByaXZhdGUgYm9vbGVhbiAgICAgICAgIF9wcmVwYXJlZDsKLQotCi0gICAgLyoqCi0gICAgICogQXNzb2NpYXRpb24gYmV0d2VlbiBuYW1lc3BhY2UgVVJJcyAoa2V5cykgYW5kIHByZWZpeGVzICh2YWx1ZXMpLgotICAgICAqIEFjY3VtdWxhdGVkIGhlcmUgcHJpb3IgdG8gc3RhcnRpbmcgYW4gZWxlbWVudCBhbmQgcGxhY2luZyB0aGlzCi0gICAgICogbGlzdCBpbiB0aGUgZWxlbWVudCBzdGF0ZS4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgTWFwPFN0cmluZywgU3RyaW5nPiAgX3ByZWZpeGVzOwotCi0KLSAgICAvKioKLSAgICAgKiBUaGUgc3lzdGVtIGlkZW50aWZpZXIgb2YgdGhlIGRvY3VtZW50IHR5cGUsIGlmIGtub3duLgotICAgICAqLwotICAgIHByb3RlY3RlZCBTdHJpbmcgICAgICAgIF9kb2NUeXBlUHVibGljSWQ7Ci0KLQotICAgIC8qKgotICAgICAqIFRoZSBzeXN0ZW0gaWRlbnRpZmllciBvZiB0aGUgZG9jdW1lbnQgdHlwZSwgaWYga25vd24uCi0gICAgICovCi0gICAgcHJvdGVjdGVkIFN0cmluZyAgICAgICAgX2RvY1R5cGVTeXN0ZW1JZDsKLQotCi0gICAgLyoqCi0gICAgICogVGhlIG91dHB1dCBmb3JtYXQgYXNzb2NpYXRlZCB3aXRoIHRoaXMgc2VyaWFsaXplci4gVGhpcyB3aWxsIG5ldmVyCi0gICAgICogYmUgYSBudWxsIHJlZmVyZW5jZS4gSWYgbm8gZm9ybWF0IHdhcyBwYXNzZWQgdG8gdGhlIGNvbnN0cnVjdG9yLAotICAgICAqIHRoZSBkZWZhdWx0IG9uZSBmb3IgdGhpcyBkb2N1bWVudCB0eXBlIHdpbGwgYmUgdXNlZC4gVGhlIGZvcm1hdAotICAgICAqIG9iamVjdCBpcyBuZXZlciBjaGFuZ2VkIGJ5IHRoZSBzZXJpYWxpemVyLgotICAgICAqLwotICAgIHByb3RlY3RlZCBPdXRwdXRGb3JtYXQgICBfZm9ybWF0OwotCi0KLSAgICAvKioKLSAgICAgKiBUaGUgcHJpbnRlciB1c2VkIGZvciBwcmludGluZyB0ZXh0IHBhcnRzLgotICAgICAqLwotICAgIHByb3RlY3RlZCBQcmludGVyICAgICAgIF9wcmludGVyOwotCi0KLSAgICAvKioKLSAgICAgKiBUcnVlIGlmIGluZGVudGluZyBwcmludGVyLgotICAgICAqLwotICAgIHByb3RlY3RlZCBib29sZWFuICAgICAgIF9pbmRlbnRpbmc7Ci0KLSAgICAvKiogVGVtcG9yYXJ5IGJ1ZmZlciB0byBzdG9yZSBjaGFyYWN0ZXIgZGF0YSAqLwotICAgIHByb3RlY3RlZCBmaW5hbCBTdHJpbmdCdWZmZXIgZlN0ckJ1ZmZlciA9IG5ldyBTdHJpbmdCdWZmZXIoNDApOwotCi0gICAgLyoqCi0gICAgICogVGhlIHVuZGVybHlpbmcgd3JpdGVyLgotICAgICAqLwotICAgIHByaXZhdGUgV3JpdGVyICAgICAgICAgIF93cml0ZXI7Ci0KLQotICAgIC8qKgotICAgICAqIFRoZSBvdXRwdXQgc3RyZWFtLgotICAgICAqLwotICAgIHByaXZhdGUgT3V0cHV0U3RyZWFtICAgIF9vdXRwdXQ7Ci0KLSAgICAvKiogQ3VycmVudCBub2RlIHRoYXQgaXMgYmVpbmcgcHJvY2Vzc2VkICAqLwotICAgIHByb3RlY3RlZCBOb2RlIGZDdXJyZW50Tm9kZSA9IG51bGw7Ci0KLQotCi0gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS8vCi0gICAgLy8gQ29uc3RydWN0b3IgYW5kIGluaXRpYWxpemF0aW9uIC8vCi0gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS8vCi0KLQotICAgIC8qKgotICAgICAqIFByb3RlY3RlZCBjb25zdHJ1Y3RvciBjYW4gb25seSBiZSB1c2VkIGJ5IGRlcml2ZWQgY2xhc3MuCi0gICAgICogTXVzdCBpbml0aWFsaXplIHRoZSBzZXJpYWxpemVyIGJlZm9yZSBzZXJpYWxpemluZyBhbnkgZG9jdW1lbnQsCi0gICAgICogYnkgY2FsbGluZyB7QGxpbmsgI3NldE91dHB1dENoYXJTdHJlYW19IG9yIHtAbGluayAjc2V0T3V0cHV0Qnl0ZVN0cmVhbX0KLSAgICAgICAgICAgICAgICAgKiBmaXJzdAotICAgICAqLwotICAgIHByb3RlY3RlZCBCYXNlTWFya3VwU2VyaWFsaXplciggT3V0cHV0Rm9ybWF0IGZvcm1hdCApCi0gICAgewotICAgICAgICBpbnQgaTsKLQotICAgICAgICBfZWxlbWVudFN0YXRlcyA9IG5ldyBFbGVtZW50U3RhdGVbIDEwIF07Ci0gICAgICAgIGZvciAoIGkgPSAwIDsgaSA8IF9lbGVtZW50U3RhdGVzLmxlbmd0aCA7ICsraSApCi0gICAgICAgICAgICBfZWxlbWVudFN0YXRlc1sgaSBdID0gbmV3IEVsZW1lbnRTdGF0ZSgpOwotICAgICAgICBfZm9ybWF0ID0gZm9ybWF0OwotICAgIH0KLQotCi0gICAgcHVibGljIERvY3VtZW50SGFuZGxlciBhc0RvY3VtZW50SGFuZGxlcigpCi0gICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgcHJlcGFyZSgpOwotICAgICAgICByZXR1cm4gdGhpczsKLSAgICB9Ci0KLQotICAgIHB1YmxpYyBDb250ZW50SGFuZGxlciBhc0NvbnRlbnRIYW5kbGVyKCkKLSAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uCi0gICAgewotICAgICAgICBwcmVwYXJlKCk7Ci0gICAgICAgIHJldHVybiB0aGlzOwotICAgIH0KLQotCi0gICAgcHVibGljIERPTVNlcmlhbGl6ZXIgYXNET01TZXJpYWxpemVyKCkKLSAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uCi0gICAgewotICAgICAgICBwcmVwYXJlKCk7Ci0gICAgICAgIHJldHVybiB0aGlzOwotICAgIH0KLQotCi0gICAgcHVibGljIHZvaWQgc2V0T3V0cHV0Qnl0ZVN0cmVhbSggT3V0cHV0U3RyZWFtIG91dHB1dCApCi0gICAgewotICAgICAgICBpZiAoIG91dHB1dCA9PSBudWxsICkgewotICAgICAgICAgICAgU3RyaW5nIG1zZyA9IERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShET01NZXNzYWdlRm9ybWF0dGVyLlNFUklBTElaRVJfRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQXJndW1lbnRJc051bGwiLCBuZXcgT2JqZWN0W117Im91dHB1dCJ9KTsKLSAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbihtc2cpOwotICAgICAgICB9Ci0gICAgICAgIF9vdXRwdXQgPSBvdXRwdXQ7Ci0gICAgICAgIF93cml0ZXIgPSBudWxsOwotICAgICAgICByZXNldCgpOwotICAgIH0KLQotCi0gICAgcHVibGljIHZvaWQgc2V0T3V0cHV0Q2hhclN0cmVhbSggV3JpdGVyIHdyaXRlciApCi0gICAgewotICAgICAgICBpZiAoIHdyaXRlciA9PSBudWxsICkgewotICAgICAgICAgICAgU3RyaW5nIG1zZyA9IERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShET01NZXNzYWdlRm9ybWF0dGVyLlNFUklBTElaRVJfRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQXJndW1lbnRJc051bGwiLCBuZXcgT2JqZWN0W117IndyaXRlciJ9KTsKLSAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbihtc2cpOwotICAgICAgICB9Ci0gICAgICAgIF93cml0ZXIgPSB3cml0ZXI7Ci0gICAgICAgIF9vdXRwdXQgPSBudWxsOwotICAgICAgICByZXNldCgpOwotICAgIH0KLQotCi0gICAgcHVibGljIHZvaWQgc2V0T3V0cHV0Rm9ybWF0KCBPdXRwdXRGb3JtYXQgZm9ybWF0ICkKLSAgICB7Ci0gICAgICAgIGlmICggZm9ybWF0ID09IG51bGwgKSB7Ci0gICAgICAgICAgICBTdHJpbmcgbXNnID0gRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuU0VSSUFMSVpFUl9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBcmd1bWVudElzTnVsbCIsIG5ldyBPYmplY3RbXXsiZm9ybWF0In0pOwotICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKG1zZyk7Ci0gICAgICAgIH0KLSAgICAgICAgX2Zvcm1hdCA9IGZvcm1hdDsKLSAgICAgICAgcmVzZXQoKTsKLSAgICB9Ci0KLQotICAgIHB1YmxpYyBib29sZWFuIHJlc2V0KCkKLSAgICB7Ci0gICAgICAgIGlmICggX2VsZW1lbnRTdGF0ZUNvdW50ID4gMSApIHsKLSAgICAgICAgICAgIFN0cmluZyBtc2cgPSBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5TRVJJQUxJWkVSX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlJlc2V0SW5NaWRkbGUiLCBudWxsKTsKLSAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24obXNnKTsKLSAgICAgICAgfQotICAgICAgICBfcHJlcGFyZWQgPSBmYWxzZTsKLSAgICAgICAgZkN1cnJlbnROb2RlID0gbnVsbDsKLSAgICAgICAgZlN0ckJ1ZmZlci5zZXRMZW5ndGgoMCk7Ci0gICAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotCi0gICAgcHJvdGVjdGVkIHZvaWQgcHJlcGFyZSgpCi0gICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaWYgKCBfcHJlcGFyZWQgKQotICAgICAgICAgICAgcmV0dXJuOwotCi0gICAgICAgIGlmICggX3dyaXRlciA9PSBudWxsICYmIF9vdXRwdXQgPT0gbnVsbCApIHsKLSAgICAgICAgICAgIFN0cmluZyBtc2cgPSBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5TRVJJQUxJWkVSX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5vV3JpdGVyU3VwcGxpZWQiLCBudWxsKTsKLSAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbihtc2cpOwotICAgICAgICB9Ci0gICAgICAgIC8vIElmIHRoZSBvdXRwdXQgc3RyZWFtIGhhcyBiZWVuIHNldCwgdXNlIGl0IHRvIGNvbnN0cnVjdAotICAgICAgICAvLyB0aGUgd3JpdGVyLiBJdCBpcyBwb3NzaWJsZSB0aGF0IHRoZSBzZXJpYWxpemVyIGhhcyBiZWVuCi0gICAgICAgIC8vIHJldXNlZCB3aXRoIHRoZSBzYW1lIG91dHB1dCBzdHJlYW0gYW5kIGRpZmZlcmVudCBlbmNvZGluZy4KLQotICAgICAgICBfZW5jb2RpbmdJbmZvID0gX2Zvcm1hdC5nZXRFbmNvZGluZ0luZm8oKTsKLQotICAgICAgICBpZiAoIF9vdXRwdXQgIT0gbnVsbCApIHsKLSAgICAgICAgICAgIF93cml0ZXIgPSBfZW5jb2RpbmdJbmZvLmdldFdyaXRlcihfb3V0cHV0KTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmICggX2Zvcm1hdC5nZXRJbmRlbnRpbmcoKSApIHsKLSAgICAgICAgICAgIF9pbmRlbnRpbmcgPSB0cnVlOwotICAgICAgICAgICAgX3ByaW50ZXIgPSBuZXcgSW5kZW50UHJpbnRlciggX3dyaXRlciwgX2Zvcm1hdCApOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgX2luZGVudGluZyA9IGZhbHNlOwotICAgICAgICAgICAgX3ByaW50ZXIgPSBuZXcgUHJpbnRlciggX3dyaXRlciwgX2Zvcm1hdCApOwotICAgICAgICB9Ci0KLSAgICAgICAgRWxlbWVudFN0YXRlIHN0YXRlOwotCi0gICAgICAgIF9lbGVtZW50U3RhdGVDb3VudCA9IDA7Ci0gICAgICAgIHN0YXRlID0gX2VsZW1lbnRTdGF0ZXNbIDAgXTsKLSAgICAgICAgc3RhdGUubmFtZXNwYWNlVVJJID0gbnVsbDsKLSAgICAgICAgc3RhdGUubG9jYWxOYW1lID0gbnVsbDsKLSAgICAgICAgc3RhdGUucmF3TmFtZSA9IG51bGw7Ci0gICAgICAgIHN0YXRlLnByZXNlcnZlU3BhY2UgPSBfZm9ybWF0LmdldFByZXNlcnZlU3BhY2UoKTsKLSAgICAgICAgc3RhdGUuZW1wdHkgPSB0cnVlOwotICAgICAgICBzdGF0ZS5hZnRlckVsZW1lbnQgPSBmYWxzZTsKLSAgICAgICAgc3RhdGUuYWZ0ZXJDb21tZW50ID0gZmFsc2U7Ci0gICAgICAgIHN0YXRlLmRvQ0RhdGEgPSBzdGF0ZS5pbkNEYXRhID0gZmFsc2U7Ci0gICAgICAgIHN0YXRlLnByZWZpeGVzID0gbnVsbDsKLQotICAgICAgICBfZG9jVHlwZVB1YmxpY0lkID0gX2Zvcm1hdC5nZXREb2N0eXBlUHVibGljKCk7Ci0gICAgICAgIF9kb2NUeXBlU3lzdGVtSWQgPSBfZm9ybWF0LmdldERvY3R5cGVTeXN0ZW0oKTsKLSAgICAgICAgX3N0YXJ0ZWQgPSBmYWxzZTsKLSAgICAgICAgX3ByZXBhcmVkID0gdHJ1ZTsKLSAgICB9Ci0KLQotCi0gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLy8KLSAgICAvLyBET00gZG9jdW1lbnQgc2VyaWFsaXppbmcgbWV0aG9kcyAvLwotICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS8vCi0KLQotICAgIC8qKgotICAgICAqIFNlcmlhbGl6ZXMgdGhlIERPTSBlbGVtZW50IHVzaW5nIHRoZSBwcmV2aW91c2x5IHNwZWNpZmllZAotICAgICAqIHdyaXRlciBhbmQgb3V0cHV0IGZvcm1hdC4gVGhyb3dzIGFuIGV4Y2VwdGlvbiBvbmx5IGlmCi0gICAgICogYW4gSS9PIGV4Y2VwdGlvbiBvY2N1cmVkIHdoaWxlIHNlcmlhbGl6aW5nLgotICAgICAqCi0gICAgICogQHBhcmFtIGVsZW0gVGhlIGVsZW1lbnQgdG8gc2VyaWFsaXplCi0gICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBBbiBJL08gZXhjZXB0aW9uIG9jY3VyZWQgd2hpbGUKLSAgICAgKiAgIHNlcmlhbGl6aW5nCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2VyaWFsaXplKCBFbGVtZW50IGVsZW0gKQotICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIHJlc2V0KCk7Ci0gICAgICAgIHByZXBhcmUoKTsKLSAgICAgICAgc2VyaWFsaXplTm9kZSggZWxlbSApOwotICAgICAgICBfcHJpbnRlci5mbHVzaCgpOwotICAgICAgICBpZiAoIF9wcmludGVyLmdldEV4Y2VwdGlvbigpICE9IG51bGwgKQotICAgICAgICAgICAgdGhyb3cgX3ByaW50ZXIuZ2V0RXhjZXB0aW9uKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2VyaWFsaXplcyBhIG5vZGUgdXNpbmcgdGhlIHByZXZpb3VzbHkgc3BlY2lmaWVkCi0gICAgICogd3JpdGVyIGFuZCBvdXRwdXQgZm9ybWF0LiBUaHJvd3MgYW4gZXhjZXB0aW9uIG9ubHkgaWYKLSAgICAgKiBhbiBJL08gZXhjZXB0aW9uIG9jY3VyZWQgd2hpbGUgc2VyaWFsaXppbmcuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbm9kZSBOb2RlIHRvIHNlcmlhbGl6ZQotICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gQW4gSS9PIGV4Y2VwdGlvbiBvY2N1cmVkIHdoaWxlIHNlcmlhbGl6aW5nCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2VyaWFsaXplKCBOb2RlIG5vZGUgKSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgICAgICByZXNldCgpOwotICAgICAgICBwcmVwYXJlKCk7Ci0gICAgICAgIHNlcmlhbGl6ZU5vZGUoIG5vZGUgKTsKLSAgICAgICAgLy9QcmludCBhbnkgUElzIGFuZCBDb21tZW50cyB3aGljaCBhcHBlYXJlZCBpbiAnbm9kZScKLSAgICAgICAgc2VyaWFsaXplUHJlUm9vdCgpOwotICAgICAgICBfcHJpbnRlci5mbHVzaCgpOwotICAgICAgICBpZiAoIF9wcmludGVyLmdldEV4Y2VwdGlvbigpICE9IG51bGwgKQotICAgICAgICAgICAgdGhyb3cgX3ByaW50ZXIuZ2V0RXhjZXB0aW9uKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2VyaWFsaXplcyB0aGUgRE9NIGRvY3VtZW50IGZyYWdtbnQgdXNpbmcgdGhlIHByZXZpb3VzbHkgc3BlY2lmaWVkCi0gICAgICogd3JpdGVyIGFuZCBvdXRwdXQgZm9ybWF0LiBUaHJvd3MgYW4gZXhjZXB0aW9uIG9ubHkgaWYKLSAgICAgKiBhbiBJL08gZXhjZXB0aW9uIG9jY3VyZWQgd2hpbGUgc2VyaWFsaXppbmcuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZWxlbSBUaGUgZWxlbWVudCB0byBzZXJpYWxpemUKLSAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIEFuIEkvTyBleGNlcHRpb24gb2NjdXJlZCB3aGlsZQotICAgICAqICAgc2VyaWFsaXppbmcKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXJpYWxpemUoIERvY3VtZW50RnJhZ21lbnQgZnJhZyApCi0gICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgcmVzZXQoKTsKLSAgICAgICAgcHJlcGFyZSgpOwotICAgICAgICBzZXJpYWxpemVOb2RlKCBmcmFnICk7Ci0gICAgICAgIF9wcmludGVyLmZsdXNoKCk7Ci0gICAgICAgIGlmICggX3ByaW50ZXIuZ2V0RXhjZXB0aW9uKCkgIT0gbnVsbCApCi0gICAgICAgICAgICB0aHJvdyBfcHJpbnRlci5nZXRFeGNlcHRpb24oKTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFNlcmlhbGl6ZXMgdGhlIERPTSBkb2N1bWVudCB1c2luZyB0aGUgcHJldmlvdXNseSBzcGVjaWZpZWQKLSAgICAgKiB3cml0ZXIgYW5kIG91dHB1dCBmb3JtYXQuIFRocm93cyBhbiBleGNlcHRpb24gb25seSBpZgotICAgICAqIGFuIEkvTyBleGNlcHRpb24gb2NjdXJlZCB3aGlsZSBzZXJpYWxpemluZy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBkb2MgVGhlIGRvY3VtZW50IHRvIHNlcmlhbGl6ZQotICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gQW4gSS9PIGV4Y2VwdGlvbiBvY2N1cmVkIHdoaWxlCi0gICAgICogICBzZXJpYWxpemluZwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNlcmlhbGl6ZSggRG9jdW1lbnQgZG9jICkKLSAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uCi0gICAgewotICAgICAgICByZXNldCgpOwotICAgICAgICBwcmVwYXJlKCk7Ci0gICAgICAgIHNlcmlhbGl6ZU5vZGUoIGRvYyApOwotICAgICAgICBzZXJpYWxpemVQcmVSb290KCk7Ci0gICAgICAgIF9wcmludGVyLmZsdXNoKCk7Ci0gICAgICAgIGlmICggX3ByaW50ZXIuZ2V0RXhjZXB0aW9uKCkgIT0gbnVsbCApCi0gICAgICAgICAgICB0aHJvdyBfcHJpbnRlci5nZXRFeGNlcHRpb24oKTsKLSAgICB9Ci0KLQotICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLy8KLSAgICAvLyBTQVggZG9jdW1lbnQgaGFuZGxlciBzZXJpYWxpemluZyBtZXRob2RzIC8vCi0gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0vLwotCi0KLSAgICBwdWJsaWMgdm9pZCBzdGFydERvY3VtZW50KCkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIHByZXBhcmUoKTsKLSAgICAgICAgfSBjYXRjaCAoIElPRXhjZXB0aW9uIGV4Y2VwdCApIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oIGV4Y2VwdC50b1N0cmluZygpICk7Ci0gICAgICAgIH0KLSAgICAgICAgLy8gTm90aGluZyB0byBkbyBoZXJlLiBBbGwgdGhlIG1hZ2ljIGhhcHBlbnMgaW4gc3RhcnREb2N1bWVudChTdHJpbmcpCi0gICAgfQotCi0KLSAgICBwdWJsaWMgdm9pZCBjaGFyYWN0ZXJzKCBjaGFyW10gY2hhcnMsIGludCBzdGFydCwgaW50IGxlbmd0aCApCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIEVsZW1lbnRTdGF0ZSBzdGF0ZTsKLQotICAgICAgICB0cnkgewotICAgICAgICBzdGF0ZSA9IGNvbnRlbnQoKTsKLQotICAgICAgICAvLyBDaGVjayBpZiB0ZXh0IHNob3VsZCBiZSBwcmludCBhcyBDREFUQSBzZWN0aW9uIG9yIHVuZXNjYXBlZAotICAgICAgICAvLyBiYXNlZCBvbiBlbGVtZW50cyBsaXN0ZWQgaW4gdGhlIG91dHB1dCBmb3JtYXQgKHRoZSBlbGVtZW50Ci0gICAgICAgIC8vIHN0YXRlKSBvciB3aGV0aGVyIHdlIGFyZSBpbnNpZGUgYSBDREFUQSBzZWN0aW9uIG9yIGVudGl0eS4KLQotICAgICAgICBpZiAoIHN0YXRlLmluQ0RhdGEgfHwgc3RhdGUuZG9DRGF0YSApIHsKLSAgICAgICAgICAgIGludCAgICAgICAgICBzYXZlSW5kZW50OwotCi0gICAgICAgICAgICAvLyBQcmludCBhIENEQVRBIHNlY3Rpb24uIFRoZSB0ZXh0IGlzIG5vdCBlc2NhcGVkLCBidXQgJ11dPicKLSAgICAgICAgICAgIC8vIGFwcGVhcmluZyBpbiB0aGUgY29kZSBtdXN0IGJlIGlkZW50aWZpZWQgYW5kIGRlYWx0IHdpdGguCi0gICAgICAgICAgICAvLyBUaGUgY29udGVudHMgb2YgYSB0ZXh0IG5vZGUgaXMgY29uc2lkZXJlZCBzcGFjZSBwcmVzZXJ2aW5nLgotICAgICAgICAgICAgaWYgKCAhIHN0YXRlLmluQ0RhdGEgKSB7Ci0gICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAiPCFbQ0RBVEFbIiApOwotICAgICAgICAgICAgICAgIHN0YXRlLmluQ0RhdGEgPSB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgc2F2ZUluZGVudCA9IF9wcmludGVyLmdldE5leHRJbmRlbnQoKTsKLSAgICAgICAgICAgIF9wcmludGVyLnNldE5leHRJbmRlbnQoIDAgKTsKLSAgICAgICAgICAgIGNoYXIgY2g7Ci0gICAgICAgICAgICBmaW5hbCBpbnQgZW5kID0gc3RhcnQgKyBsZW5ndGg7Ci0gICAgICAgICAgICBmb3IgKCBpbnQgaW5kZXggPSBzdGFydCA7IGluZGV4IDwgZW5kOyArK2luZGV4ICkgewotICAgICAgICAgICAgICAgIGNoID0gY2hhcnNbaW5kZXhdOwotICAgICAgICAgICAgICAgIGlmICggY2ggPT0gJ10nICYmIGluZGV4ICsgMiA8IGVuZCAmJgotICAgICAgICAgICAgICAgICAgICAgY2hhcnNbIGluZGV4ICsgMSBdID09ICddJyAmJiBjaGFyc1sgaW5kZXggKyAyIF0gPT0gJz4nICkgewotICAgICAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoIl1dXV0+PCFbQ0RBVEFbPiIpOwotICAgICAgICAgICAgICAgICAgICBpbmRleCArPTI7Ci0gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpZiAoIVhNTENoYXIuaXNWYWxpZChjaCkpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gY2hlY2sgaWYgaXQgaXMgc3Vycm9nYXRlCi0gICAgICAgICAgICAgICAgICAgIGlmICgrK2luZGV4IDwgZW5kKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzdXJyb2dhdGVzKGNoLCBjaGFyc1tpbmRleF0pOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgZmF0YWxFcnJvcigiVGhlIGNoYXJhY3RlciAnIisoY2hhciljaCsiJyBpcyBhbiBpbnZhbGlkIFhNTCBjaGFyYWN0ZXIiKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICBpZiAoICggY2ggPj0gJyAnICYmIF9lbmNvZGluZ0luZm8uaXNQcmludGFibGUoKGNoYXIpY2gpICYmIGNoICE9IDB4RjcgKSB8fAotICAgICAgICAgICAgICAgICAgICAgICAgY2ggPT0gJ1xuJyB8fCBjaCA9PSAnXHInIHx8IGNoID09ICdcdCcgKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoKGNoYXIpY2gpOwotICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhlIGNoYXJhY3RlciBpcyBub3QgcHJpbnRhYmxlIC0tIHNwbGl0IENEQVRBIHNlY3Rpb24KLSAgICAgICAgICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCgiXV0+JiN4Iik7Ci0gICAgICAgICAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoSW50ZWdlci50b0hleFN0cmluZyhjaCkpOwotICAgICAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCI7PCFbQ0RBVEFbIik7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBfcHJpbnRlci5zZXROZXh0SW5kZW50KCBzYXZlSW5kZW50ICk7Ci0KLSAgICAgICAgfSBlbHNlIHsKLQotICAgICAgICAgICAgaW50IHNhdmVJbmRlbnQ7Ci0KLSAgICAgICAgICAgIGlmICggc3RhdGUucHJlc2VydmVTcGFjZSApIHsKLSAgICAgICAgICAgICAgICAvLyBJZiBwcmVzZXJ2aW5nIHNwYWNlIHRoZW4gaG9sZCBvZiBpbmRlbnRhdGlvbiBzbyBubwotICAgICAgICAgICAgICAgIC8vIGV4Y2Vzc2l2ZSBzcGFjZXMgYXJlIHByaW50ZWQgYXQgbGluZSBicmVha3MsIGVzY2FwZQotICAgICAgICAgICAgICAgIC8vIHRoZSB0ZXh0IGNvbnRlbnQgd2l0aG91dCByZXBsYWNpbmcgc3BhY2VzIGFuZCBwcmludAotICAgICAgICAgICAgICAgIC8vIHRoZSB0ZXh0IGJyZWFraW5nIG9ubHkgYXQgbGluZSBicmVha3MuCi0gICAgICAgICAgICAgICAgc2F2ZUluZGVudCA9IF9wcmludGVyLmdldE5leHRJbmRlbnQoKTsKLSAgICAgICAgICAgICAgICBfcHJpbnRlci5zZXROZXh0SW5kZW50KCAwICk7Ci0gICAgICAgICAgICAgICAgcHJpbnRUZXh0KCBjaGFycywgc3RhcnQsIGxlbmd0aCwgdHJ1ZSwgc3RhdGUudW5lc2NhcGVkICk7Ci0gICAgICAgICAgICAgICAgX3ByaW50ZXIuc2V0TmV4dEluZGVudCggc2F2ZUluZGVudCApOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBwcmludFRleHQoIGNoYXJzLCBzdGFydCwgbGVuZ3RoLCBmYWxzZSwgc3RhdGUudW5lc2NhcGVkICk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgfSBjYXRjaCAoIElPRXhjZXB0aW9uIGV4Y2VwdCApIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oIGV4Y2VwdCApOwotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgdm9pZCBpZ25vcmFibGVXaGl0ZXNwYWNlKCBjaGFyW10gY2hhcnMsIGludCBzdGFydCwgaW50IGxlbmd0aCApCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGludCBpOwotCi0gICAgICAgIHRyeSB7Ci0gICAgICAgIGNvbnRlbnQoKTsKLQotICAgICAgICAvLyBQcmludCBpZ25vcmFibGUgd2hpdGVzcGFjZXMgb25seSB3aGVuIGluZGVudGluZywgYWZ0ZXIKLSAgICAgICAgLy8gYWxsIHRoZXkgYXJlIGluZGVudGF0aW9uLiBDYW5jZWwgdGhlIGluZGVudGF0aW9uIHRvCi0gICAgICAgIC8vIG5vdCBpbmRlbnQgdHdpY2UuCi0gICAgICAgIGlmICggX2luZGVudGluZyApIHsKLSAgICAgICAgICAgIF9wcmludGVyLnNldFRoaXNJbmRlbnQoIDAgKTsKLSAgICAgICAgICAgIGZvciAoIGkgPSBzdGFydCA7IGxlbmd0aC0tID4gMCA7ICsraSApCi0gICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCBjaGFyc1sgaSBdICk7Ci0gICAgICAgIH0KLSAgICAgICAgfSBjYXRjaCAoIElPRXhjZXB0aW9uIGV4Y2VwdCApIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oIGV4Y2VwdCApOwotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgZmluYWwgdm9pZCBwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oIFN0cmluZyB0YXJnZXQsIFN0cmluZyBjb2RlICkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIHByb2Nlc3NpbmdJbnN0cnVjdGlvbklPKCB0YXJnZXQsIGNvZGUgKTsKLSAgICAgICAgfSBjYXRjaCAoIElPRXhjZXB0aW9uIGV4Y2VwdCApIHsKLSAgICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbiggZXhjZXB0ICk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBwcm9jZXNzaW5nSW5zdHJ1Y3Rpb25JTyggU3RyaW5nIHRhcmdldCwgU3RyaW5nIGNvZGUgKQotICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGludCAgICAgICAgICBpbmRleDsKLSAgICAgICAgRWxlbWVudFN0YXRlIHN0YXRlOwotCi0gICAgICAgIHN0YXRlID0gY29udGVudCgpOwotCi0gICAgICAgIC8vIENyZWF0ZSB0aGUgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiB0ZXh0dWFsIHJlcHJlc2VudGF0aW9uLgotICAgICAgICAvLyBNYWtlIHN1cmUgd2UgZG9uJ3QgaGF2ZSAnPz4nIGluc2lkZSBlaXRoZXIgdGFyZ2V0IG9yIGNvZGUuCi0gICAgICAgIGluZGV4ID0gdGFyZ2V0LmluZGV4T2YoICI/PiIgKTsKLSAgICAgICAgaWYgKCBpbmRleCA+PSAwICkKLSAgICAgICAgICAgIGZTdHJCdWZmZXIuYXBwZW5kKCAiPD8iICkuYXBwZW5kKCB0YXJnZXQuc3Vic3RyaW5nKCAwLCBpbmRleCApICk7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICAgIGZTdHJCdWZmZXIuYXBwZW5kKCAiPD8iICkuYXBwZW5kKCB0YXJnZXQgKTsKLSAgICAgICAgaWYgKCBjb2RlICE9IG51bGwgKSB7Ci0gICAgICAgICAgICBmU3RyQnVmZmVyLmFwcGVuZCggJyAnICk7Ci0gICAgICAgICAgICBpbmRleCA9IGNvZGUuaW5kZXhPZiggIj8+IiApOwotICAgICAgICAgICAgaWYgKCBpbmRleCA+PSAwICkKLSAgICAgICAgICAgICAgICBmU3RyQnVmZmVyLmFwcGVuZCggY29kZS5zdWJzdHJpbmcoIDAsIGluZGV4ICkgKTsKLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICBmU3RyQnVmZmVyLmFwcGVuZCggY29kZSApOwotICAgICAgICB9Ci0gICAgICAgIGZTdHJCdWZmZXIuYXBwZW5kKCAiPz4iICk7Ci0KLSAgICAgICAgLy8gSWYgYmVmb3JlIHRoZSByb290IGVsZW1lbnQgKG9yIGFmdGVyIGl0KSwgZG8gbm90IHByaW50Ci0gICAgICAgIC8vIHRoZSBQSSBkaXJlY3RseSBidXQgcGxhY2UgaXQgaW4gdGhlIHByZS1yb290IHZlY3Rvci4KLSAgICAgICAgaWYgKCBpc0RvY3VtZW50U3RhdGUoKSApIHsKLSAgICAgICAgICAgIGlmICggX3ByZVJvb3QgPT0gbnVsbCApCi0gICAgICAgICAgICAgICAgX3ByZVJvb3QgPSBuZXcgVmVjdG9yKCk7Ci0gICAgICAgICAgICBfcHJlUm9vdC5hZGRFbGVtZW50KCBmU3RyQnVmZmVyLnRvU3RyaW5nKCkgKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIF9wcmludGVyLmluZGVudCgpOwotICAgICAgICAgICAgcHJpbnRUZXh0KCBmU3RyQnVmZmVyLnRvU3RyaW5nKCksIHRydWUsIHRydWUgKTsKLSAgICAgICAgICAgIF9wcmludGVyLnVuaW5kZW50KCk7Ci0gICAgICAgICAgICBpZiAoIF9pbmRlbnRpbmcgKQotICAgICAgICAgICAgc3RhdGUuYWZ0ZXJFbGVtZW50ID0gdHJ1ZTsKLSAgICAgICAgfQotCi0gICAgICAgIGZTdHJCdWZmZXIuc2V0TGVuZ3RoKDApOwotICAgIH0KLQotCi0gICAgcHVibGljIHZvaWQgY29tbWVudCggY2hhcltdIGNoYXJzLCBpbnQgc3RhcnQsIGludCBsZW5ndGggKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICB0cnkgewotICAgICAgICBjb21tZW50KCBuZXcgU3RyaW5nKCBjaGFycywgc3RhcnQsIGxlbmd0aCApICk7Ci0gICAgICAgIH0gY2F0Y2ggKCBJT0V4Y2VwdGlvbiBleGNlcHQgKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKCBleGNlcHQgKTsKLSAgICB9Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgdm9pZCBjb21tZW50KCBTdHJpbmcgdGV4dCApCi0gICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaW50ICAgICAgICAgIGluZGV4OwotICAgICAgICBFbGVtZW50U3RhdGUgc3RhdGU7Ci0KLSAgICAgICAgaWYgKCBfZm9ybWF0LmdldE9taXRDb21tZW50cygpICkKLSAgICAgICAgICAgIHJldHVybjsKLQotICAgICAgICBzdGF0ZSAgPSBjb250ZW50KCk7Ci0gICAgICAgIC8vIENyZWF0ZSB0aGUgcHJvY2Vzc2luZyBjb21tZW50IHRleHR1YWwgcmVwcmVzZW50YXRpb24uCi0gICAgICAgIC8vIE1ha2Ugc3VyZSB3ZSBkb24ndCBoYXZlICctLT4nIGluc2lkZSB0aGUgY29tbWVudC4KLSAgICAgICAgaW5kZXggPSB0ZXh0LmluZGV4T2YoICItLT4iICk7Ci0gICAgICAgIGlmICggaW5kZXggPj0gMCApCi0gICAgICAgICAgICBmU3RyQnVmZmVyLmFwcGVuZCggIjwhLS0iICkuYXBwZW5kKCB0ZXh0LnN1YnN0cmluZyggMCwgaW5kZXggKSApLmFwcGVuZCggIi0tPiIgKTsKLSAgICAgICAgZWxzZQotICAgICAgICAgICAgZlN0ckJ1ZmZlci5hcHBlbmQoICI8IS0tIiApLmFwcGVuZCggdGV4dCApLmFwcGVuZCggIi0tPiIgKTsKLQotICAgICAgICAvLyBJZiBiZWZvcmUgdGhlIHJvb3QgZWxlbWVudCAob3IgYWZ0ZXIgaXQpLCBkbyBub3QgcHJpbnQKLSAgICAgICAgLy8gdGhlIGNvbW1lbnQgZGlyZWN0bHkgYnV0IHBsYWNlIGl0IGluIHRoZSBwcmUtcm9vdCB2ZWN0b3IuCi0gICAgICAgIGlmICggaXNEb2N1bWVudFN0YXRlKCkgKSB7Ci0gICAgICAgICAgICBpZiAoIF9wcmVSb290ID09IG51bGwgKQotICAgICAgICAgICAgICAgIF9wcmVSb290ID0gbmV3IFZlY3RvcigpOwotICAgICAgICAgICAgX3ByZVJvb3QuYWRkRWxlbWVudCggZlN0ckJ1ZmZlci50b1N0cmluZygpICk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAvLyBJbmRlbnQgdGhpcyBlbGVtZW50IG9uIGEgbmV3IGxpbmUgaWYgdGhlIGZpcnN0Ci0gICAgICAgICAgICAvLyBjb250ZW50IG9mIHRoZSBwYXJlbnQgZWxlbWVudCBvciBpbW1lZGlhdGVseQotICAgICAgICAgICAgLy8gZm9sbG93aW5nIGFuIGVsZW1lbnQuCi0gICAgICAgICAgICBpZiAoIF9pbmRlbnRpbmcgJiYgISBzdGF0ZS5wcmVzZXJ2ZVNwYWNlKQotICAgICAgICAgICAgICAgIF9wcmludGVyLmJyZWFrTGluZSgpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIuaW5kZW50KCk7Ci0gICAgICAgICAgICBwcmludFRleHQoIGZTdHJCdWZmZXIudG9TdHJpbmcoKSwgdHJ1ZSwgdHJ1ZSApOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIudW5pbmRlbnQoKTsKLSAgICAgICAgICAgIGlmICggX2luZGVudGluZyApCi0gICAgICAgICAgICAgICAgc3RhdGUuYWZ0ZXJFbGVtZW50ID0gdHJ1ZTsKLSAgICAgICAgfQotCi0gICAgICAgIGZTdHJCdWZmZXIuc2V0TGVuZ3RoKDApOwotICAgICAgICBzdGF0ZS5hZnRlckNvbW1lbnQgPSB0cnVlOwotICAgICAgICBzdGF0ZS5hZnRlckVsZW1lbnQgPSBmYWxzZTsKLSAgICB9Ci0KLQotICAgIHB1YmxpYyB2b2lkIHN0YXJ0Q0RBVEEoKQotICAgIHsKLSAgICAgICAgRWxlbWVudFN0YXRlIHN0YXRlOwotCi0gICAgICAgIHN0YXRlID0gZ2V0RWxlbWVudFN0YXRlKCk7Ci0gICAgICAgIHN0YXRlLmRvQ0RhdGEgPSB0cnVlOwotICAgIH0KLQotCi0gICAgcHVibGljIHZvaWQgZW5kQ0RBVEEoKQotICAgIHsKLSAgICAgICAgRWxlbWVudFN0YXRlIHN0YXRlOwotCi0gICAgICAgIHN0YXRlID0gZ2V0RWxlbWVudFN0YXRlKCk7Ci0gICAgICAgIHN0YXRlLmRvQ0RhdGEgPSBmYWxzZTsKLSAgICB9Ci0KLQotICAgIHB1YmxpYyB2b2lkIHN0YXJ0Tm9uRXNjYXBpbmcoKQotICAgIHsKLSAgICAgICAgRWxlbWVudFN0YXRlIHN0YXRlOwotCi0gICAgICAgIHN0YXRlID0gZ2V0RWxlbWVudFN0YXRlKCk7Ci0gICAgICAgIHN0YXRlLnVuZXNjYXBlZCA9IHRydWU7Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgdm9pZCBlbmROb25Fc2NhcGluZygpCi0gICAgewotICAgICAgICBFbGVtZW50U3RhdGUgc3RhdGU7Ci0KLSAgICAgICAgc3RhdGUgPSBnZXRFbGVtZW50U3RhdGUoKTsKLSAgICAgICAgc3RhdGUudW5lc2NhcGVkID0gZmFsc2U7Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgdm9pZCBzdGFydFByZXNlcnZpbmcoKQotICAgIHsKLSAgICAgICAgRWxlbWVudFN0YXRlIHN0YXRlOwotCi0gICAgICAgIHN0YXRlID0gZ2V0RWxlbWVudFN0YXRlKCk7Ci0gICAgICAgIHN0YXRlLnByZXNlcnZlU3BhY2UgPSB0cnVlOwotICAgIH0KLQotCi0gICAgcHVibGljIHZvaWQgZW5kUHJlc2VydmluZygpCi0gICAgewotICAgICAgICBFbGVtZW50U3RhdGUgc3RhdGU7Ci0KLSAgICAgICAgc3RhdGUgPSBnZXRFbGVtZW50U3RhdGUoKTsKLSAgICAgICAgc3RhdGUucHJlc2VydmVTcGFjZSA9IGZhbHNlOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogQ2FsbGVkIGF0IHRoZSBlbmQgb2YgdGhlIGRvY3VtZW50IHRvIHdyYXAgaXQgdXAuCi0gICAgICogV2lsbCBmbHVzaCB0aGUgb3V0cHV0IHN0cmVhbSBhbmQgdGhyb3cgYW4gZXhjZXB0aW9uCi0gICAgICogaWYgYW55IEkvTyBlcnJvciBvY2N1cmVkIHdoaWxlIHNlcmlhbGl6aW5nLgotICAgICAqCi0gICAgICogQHRocm93cyBTQVhFeGNlcHRpb24gQW4gSS9PIGV4Y2VwdGlvbiBvY2N1cmVkIGR1cmluZwotICAgICAqICBzZXJpYWxpemluZwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZERvY3VtZW50KCkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgLy8gUHJpbnQgYWxsIHRoZSBlbGVtZW50cyBhY2N1bXVsYXRlZCBvdXRzaWRlIG9mCi0gICAgICAgIC8vIHRoZSByb290IGVsZW1lbnQuCi0gICAgICAgIHNlcmlhbGl6ZVByZVJvb3QoKTsKLSAgICAgICAgLy8gRmx1c2ggdGhlIG91dHB1dCwgdGhpcyBpcyBuZWNlc3NhcnkgZm9yIGZTdHJCdWZmZXJlZCBvdXRwdXQuCi0gICAgICAgIF9wcmludGVyLmZsdXNoKCk7Ci0gICAgICAgIH0gY2F0Y2ggKCBJT0V4Y2VwdGlvbiBleGNlcHQgKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKCBleGNlcHQgKTsKLSAgICB9Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgdm9pZCBzdGFydEVudGl0eSggU3RyaW5nIG5hbWUgKQotICAgIHsKLSAgICAgICAgLy8gPz8/Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgdm9pZCBlbmRFbnRpdHkoIFN0cmluZyBuYW1lICkKLSAgICB7Ci0gICAgICAgIC8vID8/PwotICAgIH0KLQotCi0gICAgcHVibGljIHZvaWQgc2V0RG9jdW1lbnRMb2NhdG9yKCBMb2NhdG9yIGxvY2F0b3IgKQotICAgIHsKLSAgICAgICAgLy8gTm90aGluZyB0byBkbwotICAgIH0KLQotCi0gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS8vCi0gICAgLy8gU0FYIGNvbnRlbnQgaGFuZGxlciBzZXJpYWxpemluZyBtZXRob2RzIC8vCi0gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS8vCi0KLQotICAgIHB1YmxpYyB2b2lkIHNraXBwZWRFbnRpdHkgKCBTdHJpbmcgbmFtZSApCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgIGVuZENEQVRBKCk7Ci0gICAgICAgIGNvbnRlbnQoKTsKLSAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAnJicgKTsKLSAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCBuYW1lICk7Ci0gICAgICAgIF9wcmludGVyLnByaW50VGV4dCggJzsnICk7Ci0gICAgICAgIH0gY2F0Y2ggKCBJT0V4Y2VwdGlvbiBleGNlcHQgKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKCBleGNlcHQgKTsKLSAgICB9Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgdm9pZCBzdGFydFByZWZpeE1hcHBpbmcoIFN0cmluZyBwcmVmaXgsIFN0cmluZyB1cmkgKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAoIF9wcmVmaXhlcyA9PSBudWxsICkKLSAgICAgICAgICAgIF9wcmVmaXhlcyA9IG5ldyBIYXNoTWFwPD4oKTsKLSAgICAgICAgX3ByZWZpeGVzLnB1dCggdXJpLCBwcmVmaXggPT0gbnVsbCA/ICIiIDogcHJlZml4ICk7Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgdm9pZCBlbmRQcmVmaXhNYXBwaW5nKCBTdHJpbmcgcHJlZml4ICkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICB9Ci0KLQotICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLy8KLSAgICAvLyBTQVggRFREL0RlY2wgaGFuZGxlciBzZXJpYWxpemluZyBtZXRob2RzIC8vCi0gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0vLwotCi0KLSAgICBwdWJsaWMgZmluYWwgdm9pZCBzdGFydERURCggU3RyaW5nIG5hbWUsIFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkICkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgX3ByaW50ZXIuZW50ZXJEVEQoKTsKLSAgICAgICAgX2RvY1R5cGVQdWJsaWNJZCA9IHB1YmxpY0lkOwotICAgICAgICBfZG9jVHlwZVN5c3RlbUlkID0gc3lzdGVtSWQ7Ci0KLSAgICAgICAgfSBjYXRjaCAoIElPRXhjZXB0aW9uIGV4Y2VwdCApIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oIGV4Y2VwdCApOwotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgdm9pZCBlbmREVEQoKQotICAgIHsKLSAgICAgICAgLy8gTm90aGluZyB0byBkbyBoZXJlLCBhbGwgdGhlIG1hZ2ljIG9jY3VycyBpbiBzdGFydERvY3VtZW50KFN0cmluZykuCi0gICAgfQotCi0KLSAgICBwdWJsaWMgdm9pZCBlbGVtZW50RGVjbCggU3RyaW5nIG5hbWUsIFN0cmluZyBtb2RlbCApCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgIF9wcmludGVyLmVudGVyRFREKCk7Ci0gICAgICAgIF9wcmludGVyLnByaW50VGV4dCggIjwhRUxFTUVOVCAiICk7Ci0gICAgICAgIF9wcmludGVyLnByaW50VGV4dCggbmFtZSApOwotICAgICAgICBfcHJpbnRlci5wcmludFRleHQoICcgJyApOwotICAgICAgICBfcHJpbnRlci5wcmludFRleHQoIG1vZGVsICk7Ci0gICAgICAgIF9wcmludGVyLnByaW50VGV4dCggJz4nICk7Ci0gICAgICAgIGlmICggX2luZGVudGluZyApCi0gICAgICAgICAgICBfcHJpbnRlci5icmVha0xpbmUoKTsKLSAgICAgICAgfSBjYXRjaCAoIElPRXhjZXB0aW9uIGV4Y2VwdCApIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oIGV4Y2VwdCApOwotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgdm9pZCBhdHRyaWJ1dGVEZWNsKCBTdHJpbmcgZU5hbWUsIFN0cmluZyBhTmFtZSwgU3RyaW5nIHR5cGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHZhbHVlRGVmYXVsdCwgU3RyaW5nIHZhbHVlICkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgX3ByaW50ZXIuZW50ZXJEVEQoKTsKLSAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAiPCFBVFRMSVNUICIgKTsKLSAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCBlTmFtZSApOwotICAgICAgICBfcHJpbnRlci5wcmludFRleHQoICcgJyApOwotICAgICAgICBfcHJpbnRlci5wcmludFRleHQoIGFOYW1lICk7Ci0gICAgICAgIF9wcmludGVyLnByaW50VGV4dCggJyAnICk7Ci0gICAgICAgIF9wcmludGVyLnByaW50VGV4dCggdHlwZSApOwotICAgICAgICBpZiAoIHZhbHVlRGVmYXVsdCAhPSBudWxsICkgewotICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAnICcgKTsKLSAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggdmFsdWVEZWZhdWx0ICk7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKCB2YWx1ZSAhPSBudWxsICkgewotICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAiIFwiIiApOwotICAgICAgICAgICAgcHJpbnRFc2NhcGVkKCB2YWx1ZSApOwotICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAnIicgKTsKLSAgICAgICAgfQotICAgICAgICBfcHJpbnRlci5wcmludFRleHQoICc+JyApOwotICAgICAgICBpZiAoIF9pbmRlbnRpbmcgKQotICAgICAgICAgICAgX3ByaW50ZXIuYnJlYWtMaW5lKCk7Ci0gICAgICAgIH0gY2F0Y2ggKCBJT0V4Y2VwdGlvbiBleGNlcHQgKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKCBleGNlcHQgKTsKLSAgICB9Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgdm9pZCBpbnRlcm5hbEVudGl0eURlY2woIFN0cmluZyBuYW1lLCBTdHJpbmcgdmFsdWUgKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICB0cnkgewotICAgICAgICBfcHJpbnRlci5lbnRlckRURCgpOwotICAgICAgICBfcHJpbnRlci5wcmludFRleHQoICI8IUVOVElUWSAiICk7Ci0gICAgICAgIF9wcmludGVyLnByaW50VGV4dCggbmFtZSApOwotICAgICAgICBfcHJpbnRlci5wcmludFRleHQoICIgXCIiICk7Ci0gICAgICAgIHByaW50RXNjYXBlZCggdmFsdWUgKTsKLSAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAiXCI+IiApOwotICAgICAgICBpZiAoIF9pbmRlbnRpbmcgKQotICAgICAgICAgICAgX3ByaW50ZXIuYnJlYWtMaW5lKCk7Ci0gICAgICAgIH0gY2F0Y2ggKCBJT0V4Y2VwdGlvbiBleGNlcHQgKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKCBleGNlcHQgKTsKLSAgICAgICAgfQotICAgIH0KLQotCi0gICAgcHVibGljIHZvaWQgZXh0ZXJuYWxFbnRpdHlEZWNsKCBTdHJpbmcgbmFtZSwgU3RyaW5nIHB1YmxpY0lkLCBTdHJpbmcgc3lzdGVtSWQgKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICB0cnkgewotICAgICAgICBfcHJpbnRlci5lbnRlckRURCgpOwotICAgICAgICB1bnBhcnNlZEVudGl0eURlY2woIG5hbWUsIHB1YmxpY0lkLCBzeXN0ZW1JZCwgbnVsbCApOwotICAgICAgICB9IGNhdGNoICggSU9FeGNlcHRpb24gZXhjZXB0ICkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbiggZXhjZXB0ICk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIHB1YmxpYyB2b2lkIHVucGFyc2VkRW50aXR5RGVjbCggU3RyaW5nIG5hbWUsIFN0cmluZyBwdWJsaWNJZCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBzeXN0ZW1JZCwgU3RyaW5nIG5vdGF0aW9uTmFtZSApCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgIF9wcmludGVyLmVudGVyRFREKCk7Ci0gICAgICAgIGlmICggcHVibGljSWQgPT0gbnVsbCApIHsKLSAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggIjwhRU5USVRZICIgKTsKLSAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggbmFtZSApOwotICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAiIFNZU1RFTSAiICk7Ci0gICAgICAgICAgICBwcmludERvY3R5cGVVUkwoIHN5c3RlbUlkICk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoICI8IUVOVElUWSAiICk7Ci0gICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoIG5hbWUgKTsKLSAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggIiBQVUJMSUMgIiApOwotICAgICAgICAgICAgcHJpbnREb2N0eXBlVVJMKCBwdWJsaWNJZCApOwotICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAnICcgKTsKLSAgICAgICAgICAgIHByaW50RG9jdHlwZVVSTCggc3lzdGVtSWQgKTsKLSAgICAgICAgfQotICAgICAgICBpZiAoIG5vdGF0aW9uTmFtZSAhPSBudWxsICkgewotICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAiIE5EQVRBICIgKTsKLSAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggbm90YXRpb25OYW1lICk7Ci0gICAgICAgIH0KLSAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAnPicgKTsKLSAgICAgICAgaWYgKCBfaW5kZW50aW5nICkKLSAgICAgICAgICAgIF9wcmludGVyLmJyZWFrTGluZSgpOwotICAgICAgICB9IGNhdGNoICggSU9FeGNlcHRpb24gZXhjZXB0ICkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbiggZXhjZXB0ICk7Ci0gICAgfQotICAgIH0KLQotCi0gICAgcHVibGljIHZvaWQgbm90YXRpb25EZWNsKCBTdHJpbmcgbmFtZSwgU3RyaW5nIHB1YmxpY0lkLCBTdHJpbmcgc3lzdGVtSWQgKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICB0cnkgewotICAgICAgICBfcHJpbnRlci5lbnRlckRURCgpOwotICAgICAgICBpZiAoIHB1YmxpY0lkICE9IG51bGwgKSB7Ci0gICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoICI8IU5PVEFUSU9OICIgKTsKLSAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggbmFtZSApOwotICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAiIFBVQkxJQyAiICk7Ci0gICAgICAgICAgICBwcmludERvY3R5cGVVUkwoIHB1YmxpY0lkICk7Ci0gICAgICAgICAgICBpZiAoIHN5c3RlbUlkICE9IG51bGwgKSB7Ci0gICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAnICcgKTsKLSAgICAgICAgICAgICAgICBwcmludERvY3R5cGVVUkwoIHN5c3RlbUlkICk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoICI8IU5PVEFUSU9OICIgKTsKLSAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggbmFtZSApOwotICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAiIFNZU1RFTSAiICk7Ci0gICAgICAgICAgICBwcmludERvY3R5cGVVUkwoIHN5c3RlbUlkICk7Ci0gICAgICAgIH0KLSAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAnPicgKTsKLSAgICAgICAgaWYgKCBfaW5kZW50aW5nICkKLSAgICAgICAgICAgIF9wcmludGVyLmJyZWFrTGluZSgpOwotICAgICAgICB9IGNhdGNoICggSU9FeGNlcHRpb24gZXhjZXB0ICkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbiggZXhjZXB0ICk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLy8KLSAgICAvLyBHZW5lcmljIG5vZGUgc2VyaWFsaXppbmcgbWV0aG9kcyBtZXRob2RzIC8vCi0gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0vLwotCi0KLSAgICAvKioKLSAgICAgKiBTZXJpYWxpemUgdGhlIERPTSBub2RlLiBUaGlzIG1ldGhvZCBpcyBzaGFyZWQgYWNyb3NzIFhNTCwgSFRNTCBhbmQgWEhUTUwKLSAgICAgKiBzZXJpYWxpemVycyBhbmQgdGhlIGRpZmZlcmVuY2VzIGFyZSBtYXNrZWQgb3V0IGluIGEgc2VwYXJhdGUge0BsaW5rCi0gICAgICogI3NlcmlhbGl6ZUVsZW1lbnR9LgotICAgICAqCi0gICAgICogQHBhcmFtIG5vZGUgVGhlIG5vZGUgdG8gc2VyaWFsaXplCi0gICAgICogQHNlZSAjc2VyaWFsaXplRWxlbWVudAotICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gQW4gSS9PIGV4Y2VwdGlvbiBvY2N1cmVkIHdoaWxlCi0gICAgICogICBzZXJpYWxpemluZwotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIHNlcmlhbGl6ZU5vZGUoIE5vZGUgbm9kZSApCi0gICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgZkN1cnJlbnROb2RlID0gbm9kZTsKLQotICAgICAgICAvLyBCYXNlZCBvbiB0aGUgbm9kZSB0eXBlIGNhbGwgdGhlIHN1aXRhYmxlIFNBWCBoYW5kbGVyLgotICAgICAgICAvLyBPbmx5IGNvbW1lbnRzIGVudGl0aWVzIGFuZCBkb2N1bWVudHMgd2hpY2ggYXJlIG5vdAotICAgICAgICAvLyBoYW5kbGVkIGJ5IFNBWCBhcmUgc2VyaWFsaXplZCBkaXJlY3RseS4KLSAgICAgICAgc3dpdGNoICggbm9kZS5nZXROb2RlVHlwZSgpICkgewotICAgICAgICBjYXNlIE5vZGUuVEVYVF9OT0RFIDogewotICAgICAgICAgICAgU3RyaW5nIHRleHQ7Ci0KLSAgICAgICAgICAgIHRleHQgPSBub2RlLmdldE5vZGVWYWx1ZSgpOwotICAgICAgICAgICAgaWYgKCB0ZXh0ICE9IG51bGwgKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGZET01GaWx0ZXIgIT1udWxsICYmCi0gICAgICAgICAgICAgICAgICAgIChmRE9NRmlsdGVyLmdldFdoYXRUb1Nob3coKSAmIE5vZGVGaWx0ZXIuU0hPV19URVhUKSE9IDApIHsKLSAgICAgICAgICAgICAgICAgICAgc2hvcnQgY29kZSA9IGZET01GaWx0ZXIuYWNjZXB0Tm9kZShub2RlKTsKLSAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChjb2RlKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIE5vZGVGaWx0ZXIuRklMVEVSX1JFSkVDVDoKLSAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgTm9kZUZpbHRlci5GSUxURVJfU0tJUDogewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDogewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYXJhY3RlcnModGV4dCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSBpZiAoICFfaW5kZW50aW5nIHx8IGdldEVsZW1lbnRTdGF0ZSgpLnByZXNlcnZlU3BhY2UKLSAgICAgICAgICAgICAgICAgICAgIHx8ICh0ZXh0LnJlcGxhY2UoJ1xuJywnICcpLnRyaW0oKS5sZW5ndGgoKSAhPSAwKSkKLSAgICAgICAgICAgICAgICAgICAgY2hhcmFjdGVycyggdGV4dCApOwotCi0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgfQotCi0gICAgICAgIGNhc2UgTm9kZS5DREFUQV9TRUNUSU9OX05PREUgOiB7Ci0gICAgICAgICAgICBTdHJpbmcgdGV4dCA9IG5vZGUuZ2V0Tm9kZVZhbHVlKCk7Ci0gICAgICAgICAgICBpZiAoKGZlYXR1cmVzICYgRE9NU2VyaWFsaXplckltcGwuQ0RBVEEpICE9IDApIHsKLSAgICAgICAgICAgICAgICBpZiAodGV4dCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChmRE9NRmlsdGVyICE9IG51bGwKLSAgICAgICAgICAgICAgICAgICAgICAgICYmIChmRE9NRmlsdGVyLmdldFdoYXRUb1Nob3coKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICYgTm9kZUZpbHRlci5TSE9XX0NEQVRBX1NFQ1RJT04pCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIT0gMCkgewotICAgICAgICAgICAgICAgICAgICAgICAgc2hvcnQgY29kZSA9IGZET01GaWx0ZXIuYWNjZXB0Tm9kZShub2RlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHN3aXRjaCAoY29kZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgTm9kZUZpbHRlci5GSUxURVJfUkVKRUNUIDoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIE5vZGVGaWx0ZXIuRklMVEVSX1NLSVAgOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBza2lwIHRoZSBDREFUQSBub2RlCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0IDoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9mYWxsIHRocm91Z2guLgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgc3RhcnRDREFUQSgpOwotICAgICAgICAgICAgICAgICAgICBjaGFyYWN0ZXJzKHRleHQpOwotICAgICAgICAgICAgICAgICAgICBlbmRDREFUQSgpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgLy8gdHJhbnNmb3JtIGludG8gYSB0ZXh0IG5vZGUKLSAgICAgICAgICAgICAgICBjaGFyYWN0ZXJzKHRleHQpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIH0KLSAgICAgICAgY2FzZSBOb2RlLkNPTU1FTlRfTk9ERSA6IHsKLSAgICAgICAgICAgIFN0cmluZyB0ZXh0OwotCi0gICAgICAgICAgICBpZiAoICEgX2Zvcm1hdC5nZXRPbWl0Q29tbWVudHMoKSApIHsKLSAgICAgICAgICAgICAgICB0ZXh0ID0gbm9kZS5nZXROb2RlVmFsdWUoKTsKLSAgICAgICAgICAgICAgICBpZiAoIHRleHQgIT0gbnVsbCApIHsKLQotICAgICAgICAgICAgICAgICAgICBpZiAoZkRPTUZpbHRlciAhPW51bGwgJiYKLSAgICAgICAgICAgICAgICAgICAgICAgICAgKGZET01GaWx0ZXIuZ2V0V2hhdFRvU2hvdygpICYgTm9kZUZpbHRlci5TSE9XX0NPTU1FTlQpIT0gMCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICBzaG9ydCBjb2RlID0gZkRPTUZpbHRlci5hY2NlcHROb2RlKG5vZGUpOwotICAgICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGNvZGUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgTm9kZUZpbHRlci5GSUxURVJfUkVKRUNUOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBOb2RlRmlsdGVyLkZJTFRFUl9TS0lQOiB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2tpcCB0aGUgY29tbWVudCBub2RlCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDogewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBmYWxsIHRocm91Z2gKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGNvbW1lbnQoIHRleHQgKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgfQotCi0gICAgICAgIGNhc2UgTm9kZS5FTlRJVFlfUkVGRVJFTkNFX05PREUgOiB7Ci0gICAgICAgICAgICBOb2RlICAgICAgICAgY2hpbGQ7Ci0KLSAgICAgICAgICAgIGVuZENEQVRBKCk7Ci0gICAgICAgICAgICBjb250ZW50KCk7Ci0KLSAgICAgICAgICAgIGlmICgoKGZlYXR1cmVzICYgRE9NU2VyaWFsaXplckltcGwuRU5USVRJRVMpICE9IDApCi0gICAgICAgICAgICAgICAgfHwgKG5vZGUuZ2V0Rmlyc3RDaGlsZCgpID09IG51bGwpKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGZET01GaWx0ZXIgIT1udWxsICYmCi0gICAgICAgICAgICAgICAgICAgICAgKGZET01GaWx0ZXIuZ2V0V2hhdFRvU2hvdygpICYgTm9kZUZpbHRlci5TSE9XX0VOVElUWV9SRUZFUkVOQ0UpIT0gMCkgewotICAgICAgICAgICAgICAgICAgICAgIHNob3J0IGNvZGUgPSBmRE9NRmlsdGVyLmFjY2VwdE5vZGUobm9kZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChjb2RlKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIE5vZGVGaWx0ZXIuRklMVEVSX1JFSkVDVDp7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOyAvLyByZW1vdmUgdGhlIG5vZGUKLSAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIE5vZGVGaWx0ZXIuRklMVEVSX1NLSVA6IHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkID0gbm9kZS5nZXRGaXJzdENoaWxkKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoIGNoaWxkICE9IG51bGwgKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VyaWFsaXplTm9kZSggY2hpbGQgKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZCA9IGNoaWxkLmdldE5leHRTaWJsaW5nKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OiB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZmFsbCB0aHJvdWdoCi0gICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgY2hlY2tVbmJvdW5kTmFtZXNwYWNlUHJlZml4ZWROb2RlKG5vZGUpOwotCi0gICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCImIik7Ci0gICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KG5vZGUuZ2V0Tm9kZU5hbWUoKSk7Ci0gICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCI7Iik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBjaGlsZCA9IG5vZGUuZ2V0Rmlyc3RDaGlsZCgpOwotICAgICAgICAgICAgICAgIHdoaWxlICggY2hpbGQgIT0gbnVsbCApIHsKLSAgICAgICAgICAgICAgICAgICAgc2VyaWFsaXplTm9kZSggY2hpbGQgKTsKLSAgICAgICAgICAgICAgICAgICAgY2hpbGQgPSBjaGlsZC5nZXROZXh0U2libGluZygpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIH0KLQotICAgICAgICBjYXNlIE5vZGUuUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFIDogewotCi0gICAgICAgICAgICBpZiAoZkRPTUZpbHRlciAhPW51bGwgJiYKLSAgICAgICAgICAgICAgICAgIChmRE9NRmlsdGVyLmdldFdoYXRUb1Nob3coKSAmIE5vZGVGaWx0ZXIuU0hPV19QUk9DRVNTSU5HX0lOU1RSVUNUSU9OKSE9IDApIHsKLSAgICAgICAgICAgICAgICAgIHNob3J0IGNvZGUgPSBmRE9NRmlsdGVyLmFjY2VwdE5vZGUobm9kZSk7Ci0gICAgICAgICAgICAgICAgICBzd2l0Y2ggKGNvZGUpIHsKLSAgICAgICAgICAgICAgICAgICAgY2FzZSBOb2RlRmlsdGVyLkZJTFRFUl9SRUpFQ1Q6Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgTm9kZUZpbHRlci5GSUxURVJfU0tJUDogewotICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47ICAvLyBza2lwIHRoaXMgbm9kZQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHsgLy8gZmFsbCB0aHJvdWdoCi0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHByb2Nlc3NpbmdJbnN0cnVjdGlvbklPKCBub2RlLmdldE5vZGVOYW1lKCksIG5vZGUuZ2V0Tm9kZVZhbHVlKCkgKTsKLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICB9Ci0gICAgICAgIGNhc2UgTm9kZS5FTEVNRU5UX05PREUgOiAgewotCi0gICAgICAgICAgICBpZiAoZkRPTUZpbHRlciAhPW51bGwgJiYKLSAgICAgICAgICAgICAgICAgIChmRE9NRmlsdGVyLmdldFdoYXRUb1Nob3coKSAmIE5vZGVGaWx0ZXIuU0hPV19FTEVNRU5UKSE9IDApIHsKLSAgICAgICAgICAgICAgICAgIHNob3J0IGNvZGUgPSBmRE9NRmlsdGVyLmFjY2VwdE5vZGUobm9kZSk7Ci0gICAgICAgICAgICAgICAgICBzd2l0Y2ggKGNvZGUpIHsKLSAgICAgICAgICAgICAgICAgICAgY2FzZSBOb2RlRmlsdGVyLkZJTFRFUl9SRUpFQ1Q6IHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBjYXNlIE5vZGVGaWx0ZXIuRklMVEVSX1NLSVA6IHsKLSAgICAgICAgICAgICAgICAgICAgICAgIE5vZGUgY2hpbGQgPSBub2RlLmdldEZpcnN0Q2hpbGQoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlICggY2hpbGQgIT0gbnVsbCApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXJpYWxpemVOb2RlKCBjaGlsZCApOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkID0gY2hpbGQuZ2V0TmV4dFNpYmxpbmcoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsgIC8vIHNraXAgdGhpcyBub2RlCi0gICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OiB7IC8vIGZhbGwgdGhyb3VnaAotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBzZXJpYWxpemVFbGVtZW50KCAoRWxlbWVudCkgbm9kZSApOwotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIH0KLSAgICAgICAgY2FzZSBOb2RlLkRPQ1VNRU5UX05PREUgOiB7Ci0gICAgICAgICAgICBEb2N1bWVudFR5cGUgICAgICBkb2NUeXBlOwotICAgICAgICAgICAgRE9NSW1wbGVtZW50YXRpb24gZG9tSW1wbDsKLSAgICAgICAgICAgIE5hbWVkTm9kZU1hcCAgICAgIG1hcDsKLSAgICAgICAgICAgIEVudGl0eSAgICAgICAgICAgIGVudGl0eTsKLSAgICAgICAgICAgIE5vdGF0aW9uICAgICAgICAgIG5vdGF0aW9uOwotICAgICAgICAgICAgaW50ICAgICAgICAgICAgICAgaTsKLQotICAgICAgICAgICAgc2VyaWFsaXplRG9jdW1lbnQoKTsKLQotICAgICAgICAgICAgLy8gSWYgdGhlcmUgaXMgYSBkb2N1bWVudCB0eXBlLCB1c2UgdGhlIFNBWCBldmVudHMgdG8KLSAgICAgICAgICAgIC8vIHNlcmlhbGl6ZSBpdC4KLSAgICAgICAgICAgIGRvY1R5cGUgPSAoIChEb2N1bWVudCkgbm9kZSApLmdldERvY3R5cGUoKTsKLSAgICAgICAgICAgIGlmIChkb2NUeXBlICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAvLyBET00gTGV2ZWwgMiAob3IgaGlnaGVyKQotICAgICAgICAgICAgICAgIGRvbUltcGwgPSAoIChEb2N1bWVudCkgbm9kZSApLmdldEltcGxlbWVudGF0aW9uKCk7Ci0gICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGludGVybmFsOwotCi0gICAgICAgICAgICAgICAgICAgIF9wcmludGVyLmVudGVyRFREKCk7Ci0gICAgICAgICAgICAgICAgICAgIF9kb2NUeXBlUHVibGljSWQgPSBkb2NUeXBlLmdldFB1YmxpY0lkKCk7Ci0gICAgICAgICAgICAgICAgICAgIF9kb2NUeXBlU3lzdGVtSWQgPSBkb2NUeXBlLmdldFN5c3RlbUlkKCk7Ci0gICAgICAgICAgICAgICAgICAgIGludGVybmFsID0gZG9jVHlwZS5nZXRJbnRlcm5hbFN1YnNldCgpOwotICAgICAgICAgICAgICAgICAgICBpZiAoIGludGVybmFsICE9IG51bGwgJiYgaW50ZXJuYWwubGVuZ3RoKCkgPiAwICkKLSAgICAgICAgICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggaW50ZXJuYWwgKTsKLSAgICAgICAgICAgICAgICAgICAgZW5kRFREKCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIC8vIERPTSBMZXZlbCAxIC0tIGRvZXMgaW1wbGVtZW50YXRpb24gaGF2ZSBtZXRob2RzPwotICAgICAgICAgICAgICAgIGNhdGNoIChOb1N1Y2hNZXRob2RFcnJvciBuc21lKSB7Ci0gICAgICAgICAgICAgICAgICAgIENsYXNzIGRvY1R5cGVDbGFzcyA9IGRvY1R5cGUuZ2V0Q2xhc3MoKTsKLQotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgZG9jVHlwZVB1YmxpY0lkID0gbnVsbDsKLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGRvY1R5cGVTeXN0ZW1JZCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2QgZ2V0UHVibGljSWQgPSBkb2NUeXBlQ2xhc3MuZ2V0TWV0aG9kKCJnZXRQdWJsaWNJZCIsIChDbGFzc1tdKSBudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChnZXRQdWJsaWNJZC5nZXRSZXR1cm5UeXBlKCkuZXF1YWxzKFN0cmluZy5jbGFzcykpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2NUeXBlUHVibGljSWQgPSAoU3RyaW5nKWdldFB1YmxpY0lkLmludm9rZShkb2NUeXBlLCAoT2JqZWN0W10pIG51bGwpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWdub3JlCi0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGphdmEubGFuZy5yZWZsZWN0Lk1ldGhvZCBnZXRTeXN0ZW1JZCA9IGRvY1R5cGVDbGFzcy5nZXRNZXRob2QoImdldFN5c3RlbUlkIiwgKENsYXNzW10pIG51bGwpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGdldFN5c3RlbUlkLmdldFJldHVyblR5cGUoKS5lcXVhbHMoU3RyaW5nLmNsYXNzKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvY1R5cGVTeXN0ZW1JZCA9IChTdHJpbmcpZ2V0U3lzdGVtSWQuaW52b2tlKGRvY1R5cGUsIChPYmplY3RbXSkgbnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBpZ25vcmUKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBfcHJpbnRlci5lbnRlckRURCgpOwotICAgICAgICAgICAgICAgICAgICBfZG9jVHlwZVB1YmxpY0lkID0gZG9jVHlwZVB1YmxpY0lkOwotICAgICAgICAgICAgICAgICAgICBfZG9jVHlwZVN5c3RlbUlkID0gZG9jVHlwZVN5c3RlbUlkOwotICAgICAgICAgICAgICAgICAgICBlbmREVEQoKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBzZXJpYWxpemVEVEQoZG9jVHlwZS5nZXROYW1lKCkpOwotCi0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBfc3RhcnRlZCA9IHRydWU7Ci0KLSAgICAgICAgICAgIC8vICEhIEZhbGwgdGhyb3VnaAotICAgICAgICB9Ci0gICAgICAgIGNhc2UgTm9kZS5ET0NVTUVOVF9GUkFHTUVOVF9OT0RFIDogewotICAgICAgICAgICAgTm9kZSAgICAgICAgIGNoaWxkOwotCi0gICAgICAgICAgICAvLyBCeSBkZWZpbml0aW9uIHRoaXMgd2lsbCBoYXBwZW4gaWYgdGhlIG5vZGUgaXMgYSBkb2N1bWVudCwKLSAgICAgICAgICAgIC8vIGRvY3VtZW50IGZyYWdtZW50LCBldGMuIEp1c3Qgc2VyaWFsaXplIGl0cyBjb250ZW50cy4gSXQgd2lsbAotICAgICAgICAgICAgLy8gd29yayB3ZWxsIGZvciBvdGhlciBub2RlcyB0aGF0IHdlIGRvIG5vdCBrbm93IGhvdyB0byBzZXJpYWxpemUuCi0gICAgICAgICAgICBjaGlsZCA9IG5vZGUuZ2V0Rmlyc3RDaGlsZCgpOwotICAgICAgICAgICAgd2hpbGUgKCBjaGlsZCAhPSBudWxsICkgewotICAgICAgICAgICAgICAgIHNlcmlhbGl6ZU5vZGUoIGNoaWxkICk7Ci0gICAgICAgICAgICAgICAgY2hpbGQgPSBjaGlsZC5nZXROZXh0U2libGluZygpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIH0KLQotICAgICAgICBkZWZhdWx0OgotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIC8qIFNlcmlhbGl6ZXMgWE1MIERlY2xhcmF0aW9uLCBhY2NvcmRpbmcgdG8gJ3htbC1kZWNsYXJhdGlvbicgcHJvcGVydHkuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgc2VyaWFsaXplRG9jdW1lbnQoKXRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgIGludCAgICBpOwotCi0gICAgICAgIFN0cmluZyBkdGQgPSBfcHJpbnRlci5sZWF2ZURURCgpOwotICAgICAgICBpZiAoISBfc3RhcnRlZCkgewotCi0gICAgICAgICAgICBpZiAoISBfZm9ybWF0LmdldE9taXRYTUxEZWNsYXJhdGlvbigpKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nQnVmZmVyICAgIGJ1ZmZlcjsKLQotICAgICAgICAgICAgICAgIC8vIFNlcmlhbGl6ZSB0aGUgZG9jdW1lbnQgZGVjbGFyYXRpb24gYXBwcmVhaW5nIGF0IHRoZSBoZWFkCi0gICAgICAgICAgICAgICAgLy8gb2YgdmVyeSBYTUwgZG9jdW1lbnQgKHVubGVzcyBhc2tlZCBub3QgdG8pLgotICAgICAgICAgICAgICAgIGJ1ZmZlciA9IG5ldyBTdHJpbmdCdWZmZXIoICI8P3htbCB2ZXJzaW9uPVwiIiApOwotICAgICAgICAgICAgICAgIGlmIChfZm9ybWF0LmdldFZlcnNpb24oKSAhPSBudWxsKQotICAgICAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCBfZm9ybWF0LmdldFZlcnNpb24oKSApOwotICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCggIjEuMCIgKTsKLSAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCAnIicgKTsKLSAgICAgICAgICAgICAgICBTdHJpbmcgZm9ybWF0X2VuY29kaW5nID0gIF9mb3JtYXQuZ2V0RW5jb2RpbmcoKTsKLSAgICAgICAgICAgICAgICBpZiAoZm9ybWF0X2VuY29kaW5nICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCggIiBlbmNvZGluZz1cIiIgKTsKLSAgICAgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCggZm9ybWF0X2VuY29kaW5nICk7Ci0gICAgICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoICciJyApOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpZiAoX2Zvcm1hdC5nZXRTdGFuZGFsb25lKCkgJiYgX2RvY1R5cGVTeXN0ZW1JZCA9PSBudWxsICYmCi0gICAgICAgICAgICAgICAgICAgIF9kb2NUeXBlUHVibGljSWQgPT0gbnVsbCkKLSAgICAgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCggIiBzdGFuZGFsb25lPVwieWVzXCIiICk7Ci0gICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCggIj8+IiApOwotICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggYnVmZmVyICk7Ci0gICAgICAgICAgICAgICAgX3ByaW50ZXIuYnJlYWtMaW5lKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBBbHdheXMgc2VyaWFsaXplIHRoZXNlLCBldmVuIGlmIG5vdCB0ZSBmaXJzdCByb290IGVsZW1lbnQuCi0gICAgICAgIHNlcmlhbGl6ZVByZVJvb3QoKTsKLQotICAgIH0KLQotICAgIC8qIFNlcmlhbGl6ZXMgRFRELCBpZiBwcmVzZW50LgotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIHNlcmlhbGl6ZURURChTdHJpbmcgbmFtZSkgdGhyb3dzIElPRXhjZXB0aW9uewotCi0gICAgICAgIFN0cmluZyBkdGQgPSBfcHJpbnRlci5sZWF2ZURURCgpOwotICAgICAgICBpZiAoISBfZm9ybWF0LmdldE9taXREb2N1bWVudFR5cGUoKSkgewotICAgICAgICAgICAgaWYgKF9kb2NUeXBlU3lzdGVtSWQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIC8vIFN5c3RlbSBpZGVudGlmaWVyIG11c3QgYmUgc3BlY2lmaWVkIHRvIHByaW50IERPQ1RZUEUuCi0gICAgICAgICAgICAgICAgLy8gSWYgcHVibGljIGlkZW50aWZpZXIgaXMgc3BlY2lmaWVkIHByaW50ICdQVUJMSUMKLSAgICAgICAgICAgICAgICAvLyA8cHVibGljPiA8c3lzdGVtPicsIGlmIG5vdCwgcHJpbnQgJ1NZU1RFTSA8c3lzdGVtPicuCi0gICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAiPCFET0NUWVBFICIgKTsKLSAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoIG5hbWUgKTsKLSAgICAgICAgICAgICAgICBpZiAoX2RvY1R5cGVQdWJsaWNJZCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggIiBQVUJMSUMgIiApOwotICAgICAgICAgICAgICAgICAgICBwcmludERvY3R5cGVVUkwoIF9kb2NUeXBlUHVibGljSWQgKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKF9pbmRlbnRpbmcpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIF9wcmludGVyLmJyZWFrTGluZSgpOwotICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDAgOyBpIDwgMTggKyBuYW1lLmxlbmd0aCgpIDsgKytpKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggIiAiICk7Ci0gICAgICAgICAgICAgICAgICAgIH0gZWxzZQotICAgICAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAiICIgKTsKLSAgICAgICAgICAgICAgICAgICAgcHJpbnREb2N0eXBlVVJMKCBfZG9jVHlwZVN5c3RlbUlkICk7Ci0gICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAiIFNZU1RFTSAiICk7Ci0gICAgICAgICAgICAgICAgICAgIHByaW50RG9jdHlwZVVSTCggX2RvY1R5cGVTeXN0ZW1JZCApOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8vIElmIHdlIGFjY3VtdWxhdGVkIGFueSBEVEQgY29udGVudHMgd2hpbGUgcHJpbnRpbmcuCi0gICAgICAgICAgICAgICAgLy8gdGhpcyB3b3VsZCBiZSB0aGUgcGxhY2UgdG8gcHJpbnQgaXQuCi0gICAgICAgICAgICAgICAgaWYgKGR0ZCAhPSBudWxsICYmIGR0ZC5sZW5ndGgoKSA+IDApIHsKLSAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAiIFsiICk7Ci0gICAgICAgICAgICAgICAgICAgIHByaW50VGV4dCggZHRkLCB0cnVlLCB0cnVlICk7Ci0gICAgICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggJ10nICk7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAiPiIgKTsKLSAgICAgICAgICAgICAgICBfcHJpbnRlci5icmVha0xpbmUoKTsKLSAgICAgICAgICAgIH0gZWxzZSBpZiAoZHRkICE9IG51bGwgJiYgZHRkLmxlbmd0aCgpID4gMCkgewotICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggIjwhRE9DVFlQRSAiICk7Ci0gICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCBuYW1lICk7Ci0gICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAiIFsiICk7Ci0gICAgICAgICAgICAgICAgcHJpbnRUZXh0KCBkdGQsIHRydWUsIHRydWUgKTsKLSAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoICJdPiIgKTsKLSAgICAgICAgICAgICAgICBfcHJpbnRlci5icmVha0xpbmUoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogTXVzdCBiZSBjYWxsZWQgYnkgYSBtZXRob2QgYWJvdXQgdG8gcHJpbnQgYW55IHR5cGUgb2YgY29udGVudC4KLSAgICAgKiBJZiB0aGUgZWxlbWVudCB3YXMganVzdCBvcGVuZWQsIHRoZSBvcGVuaW5nIHRhZyBpcyBjbG9zZWQgYW5kCi0gICAgICogd2lsbCBiZSBtYXRjaGVkIHRvIGEgY2xvc2luZyB0YWcuIFJldHVybnMgdGhlIGN1cnJlbnQgZWxlbWVudAotICAgICAqIHN0YXRlIHdpdGggPHR0PmVtcHR5PC90dD4gYW5kIDx0dD5hZnRlckVsZW1lbnQ8L3R0PiBzZXQgdG8gZmFsc2UuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBjdXJyZW50IGVsZW1lbnQgc3RhdGUKLSAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIEFuIEkvTyBleGNlcHRpb24gb2NjdXJlZCB3aGlsZQotICAgICAqICAgc2VyaWFsaXppbmcKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgRWxlbWVudFN0YXRlIGNvbnRlbnQoKQotICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIEVsZW1lbnRTdGF0ZSBzdGF0ZTsKLQotICAgICAgICBzdGF0ZSA9IGdldEVsZW1lbnRTdGF0ZSgpOwotICAgICAgICBpZiAoICEgaXNEb2N1bWVudFN0YXRlKCkgKSB7Ci0gICAgICAgICAgICAvLyBOZWVkIHRvIGNsb3NlIENEYXRhIHNlY3Rpb24gZmlyc3QKLSAgICAgICAgICAgIGlmICggc3RhdGUuaW5DRGF0YSAmJiAhIHN0YXRlLmRvQ0RhdGEgKSB7Ci0gICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAiXV0+IiApOwotICAgICAgICAgICAgICAgIHN0YXRlLmluQ0RhdGEgPSBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIElmIHRoaXMgaXMgdGhlIGZpcnN0IGNvbnRlbnQgaW4gdGhlIGVsZW1lbnQsCi0gICAgICAgICAgICAvLyBjaGFuZ2UgdGhlIHN0YXRlIHRvIG5vdC1lbXB0eSBhbmQgY2xvc2UgdGhlCi0gICAgICAgICAgICAvLyBvcGVuaW5nIGVsZW1lbnQgdGFnLgotICAgICAgICAgICAgaWYgKCBzdGF0ZS5lbXB0eSApIHsKLSAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoICc+JyApOwotICAgICAgICAgICAgICAgIHN0YXRlLmVtcHR5ID0gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyBFeGNlcHQgZm9yIG9uZSBjb250ZW50IHR5cGUsIGFsbCBvZiB0aGVtCi0gICAgICAgICAgICAvLyBhcmUgbm90IGxhc3QgZWxlbWVudC4gVGhhdCBvbmUgY29udGVudAotICAgICAgICAgICAgLy8gdHlwZSB3aWxsIHRha2UgY2FyZSBvZiBpdHNlbGYuCi0gICAgICAgICAgICBzdGF0ZS5hZnRlckVsZW1lbnQgPSBmYWxzZTsKLSAgICAgICAgICAgIC8vIEV4Y2VwdCBmb3Igb25lIGNvbnRlbnQgdHlwZSwgYWxsIG9mIHRoZW0KLSAgICAgICAgICAgIC8vIGFyZSBub3QgbGFzdCBjb21tZW50LiBUaGF0IG9uZSBjb250ZW50Ci0gICAgICAgICAgICAvLyB0eXBlIHdpbGwgdGFrZSBjYXJlIG9mIGl0c2VsZi4KLSAgICAgICAgICAgIHN0YXRlLmFmdGVyQ29tbWVudCA9IGZhbHNlOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBzdGF0ZTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIENhbGxlZCB0byBwcmludCB0aGUgdGV4dCBjb250ZW50cyBpbiB0aGUgcHJldmFpbGluZyBlbGVtZW50IGZvcm1hdC4KLSAgICAgKiBTaW5jZSB0aGlzIG1ldGhvZCBpcyBjYXBhYmxlIG9mIHByaW50aW5nIHRleHQgYXMgQ0RBVEEsIGl0IGlzIHVzZWQKLSAgICAgKiBmb3IgdGhhdCBwdXJwb3NlIGFzIHdlbGwuIFdoaXRlIHNwYWNlIGhhbmRsaW5nIGlzIGRldGVybWluZWQgYnkgdGhlCi0gICAgICogY3VycmVudCBlbGVtZW50IHN0YXRlLiBJbiBhZGRpdGlvbiwgdGhlIG91dHB1dCBmb3JtYXQgY2FuIGRpY3RhdGUKLSAgICAgKiB3aGV0aGVyIHRoZSB0ZXh0IGlzIHByaW50ZWQgYXMgQ0RBVEEgb3IgdW5lc2NhcGVkLgotICAgICAqCi0gICAgICogQHBhcmFtIHRleHQgVGhlIHRleHQgdG8gcHJpbnQKLSAgICAgKiBAcGFyYW0gdW5lc2NhcGVkIFRydWUgaXMgc2hvdWxkIHByaW50IHVuZXNjYXBlZAotICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gQW4gSS9PIGV4Y2VwdGlvbiBvY2N1cmVkIHdoaWxlCi0gICAgICogICBzZXJpYWxpemluZwotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIGNoYXJhY3RlcnMoIFN0cmluZyB0ZXh0ICkKLSAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uCi0gICAgewotICAgICAgICBFbGVtZW50U3RhdGUgc3RhdGU7Ci0KLSAgICAgICAgc3RhdGUgPSBjb250ZW50KCk7Ci0gICAgICAgIC8vIENoZWNrIGlmIHRleHQgc2hvdWxkIGJlIHByaW50IGFzIENEQVRBIHNlY3Rpb24gb3IgdW5lc2NhcGVkCi0gICAgICAgIC8vIGJhc2VkIG9uIGVsZW1lbnRzIGxpc3RlZCBpbiB0aGUgb3V0cHV0IGZvcm1hdCAodGhlIGVsZW1lbnQKLSAgICAgICAgLy8gc3RhdGUpIG9yIHdoZXRoZXIgd2UgYXJlIGluc2lkZSBhIENEQVRBIHNlY3Rpb24gb3IgZW50aXR5LgotCi0gICAgICAgIGlmICggc3RhdGUuaW5DRGF0YSB8fCBzdGF0ZS5kb0NEYXRhICkgewotICAgICAgICAgICAgaW50ICAgICAgICAgIGluZGV4OwotICAgICAgICAgICAgaW50ICAgICAgICAgIHNhdmVJbmRlbnQ7Ci0KLSAgICAgICAgICAgIC8vIFByaW50IGEgQ0RBVEEgc2VjdGlvbi4gVGhlIHRleHQgaXMgbm90IGVzY2FwZWQsIGJ1dCAnXV0+JwotICAgICAgICAgICAgLy8gYXBwZWFyaW5nIGluIHRoZSBjb2RlIG11c3QgYmUgaWRlbnRpZmllZCBhbmQgZGVhbHQgd2l0aC4KLSAgICAgICAgICAgIC8vIFRoZSBjb250ZW50cyBvZiBhIHRleHQgbm9kZSBpcyBjb25zaWRlcmVkIHNwYWNlIHByZXNlcnZpbmcuCi0gICAgICAgICAgICBpZiAoICEgc3RhdGUuaW5DRGF0YSApIHsKLSAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoIjwhW0NEQVRBWyIpOwotICAgICAgICAgICAgICAgIHN0YXRlLmluQ0RhdGEgPSB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgc2F2ZUluZGVudCA9IF9wcmludGVyLmdldE5leHRJbmRlbnQoKTsKLSAgICAgICAgICAgIF9wcmludGVyLnNldE5leHRJbmRlbnQoIDAgKTsKLSAgICAgICAgICAgIHByaW50Q0RBVEFUZXh0KCB0ZXh0KTsKLSAgICAgICAgICAgIF9wcmludGVyLnNldE5leHRJbmRlbnQoIHNhdmVJbmRlbnQgKTsKLQotICAgICAgICB9IGVsc2UgewotCi0gICAgICAgICAgICBpbnQgc2F2ZUluZGVudDsKLQotICAgICAgICAgICAgaWYgKCBzdGF0ZS5wcmVzZXJ2ZVNwYWNlICkgewotICAgICAgICAgICAgICAgIC8vIElmIHByZXNlcnZpbmcgc3BhY2UgdGhlbiBob2xkIG9mIGluZGVudGF0aW9uIHNvIG5vCi0gICAgICAgICAgICAgICAgLy8gZXhjZXNzaXZlIHNwYWNlcyBhcmUgcHJpbnRlZCBhdCBsaW5lIGJyZWFrcywgZXNjYXBlCi0gICAgICAgICAgICAgICAgLy8gdGhlIHRleHQgY29udGVudCB3aXRob3V0IHJlcGxhY2luZyBzcGFjZXMgYW5kIHByaW50Ci0gICAgICAgICAgICAgICAgLy8gdGhlIHRleHQgYnJlYWtpbmcgb25seSBhdCBsaW5lIGJyZWFrcy4KLSAgICAgICAgICAgICAgICBzYXZlSW5kZW50ID0gX3ByaW50ZXIuZ2V0TmV4dEluZGVudCgpOwotICAgICAgICAgICAgICAgIF9wcmludGVyLnNldE5leHRJbmRlbnQoIDAgKTsKLSAgICAgICAgICAgICAgICBwcmludFRleHQoIHRleHQsIHRydWUsIHN0YXRlLnVuZXNjYXBlZCApOwotICAgICAgICAgICAgICAgIF9wcmludGVyLnNldE5leHRJbmRlbnQoIHNhdmVJbmRlbnQgKTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgcHJpbnRUZXh0KCB0ZXh0LCBmYWxzZSwgc3RhdGUudW5lc2NhcGVkICk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIHN1aXRhYmxlIGVudGl0eSByZWZlcmVuY2UgZm9yIHRoaXMgY2hhcmFjdGVyIHZhbHVlLAotICAgICAqIG9yIG51bGwgaWYgbm8gc3VjaCBlbnRpdHkgZXhpc3RzLiBDYWxsaW5nIHRoaXMgbWV0aG9kIHdpdGggPHR0PicmYW1wOyc8L3R0PgotICAgICAqIHdpbGwgcmV0dXJuIDx0dD4iJmFtcDthbXA7IjwvdHQ+LgotICAgICAqCi0gICAgICogQHBhcmFtIGNoIENoYXJhY3RlciB2YWx1ZQotICAgICAqIEByZXR1cm4gQ2hhcmFjdGVyIGVudGl0eSBuYW1lLCBvciBudWxsCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGFic3RyYWN0IFN0cmluZyBnZXRFbnRpdHlSZWYoIGludCBjaCApOwotCi0KLSAgICAvKioKLSAgICAgKiBDYWxsZWQgdG8gc2VyaWFsaXplZSB0aGUgRE9NIGVsZW1lbnQuIFRoZSBlbGVtZW50IGlzIHNlcmlhbGl6ZWQgYmFzZWQgb24KLSAgICAgKiB0aGUgc2VyaWFsaXplcidzIG1ldGhvZCAoWE1MLCBIVE1MLCBYSFRNTCkuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZWxlbSBUaGUgZWxlbWVudCB0byBzZXJpYWxpemUKLSAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIEFuIEkvTyBleGNlcHRpb24gb2NjdXJlZCB3aGlsZQotICAgICAqICAgc2VyaWFsaXppbmcKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgYWJzdHJhY3Qgdm9pZCBzZXJpYWxpemVFbGVtZW50KCBFbGVtZW50IGVsZW0gKQotICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb247Ci0KLQotICAgIC8qKgotICAgICAqIENvbW1lbnRzIGFuZCBQSXMgY2Fubm90IGJlIHNlcmlhbGl6ZWQgYmVmb3JlIHRoZSByb290IGVsZW1lbnQsCi0gICAgICogYmVjYXVzZSB0aGUgcm9vdCBlbGVtZW50IHNlcmlhbGl6ZXMgdGhlIGRvY3VtZW50IHR5cGUsIHdoaWNoCi0gICAgICogZ2VuZXJhbGx5IGNvbWVzIGZpcnN0LiBJbnN0ZWFkIHN1Y2ggUElzIGFuZCBjb21tZW50cyBhcmUKLSAgICAgKiBhY2N1bXVsYXRlZCBpbnNpZGUgYSB2ZWN0b3IgYW5kIHNlcmlhbGl6ZWQgYnkgY2FsbGluZyB0aGlzCi0gICAgICogbWV0aG9kLiBXaWxsIGJlIGNhbGxlZCB3aGVuIHRoZSByb290IGVsZW1lbnQgaXMgc2VyaWFsaXplZAotICAgICAqIGFuZCB3aGVuIHRoZSBkb2N1bWVudCBmaW5pc2hlZCBzZXJpYWxpemluZy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gQW4gSS9PIGV4Y2VwdGlvbiBvY2N1cmVkIHdoaWxlCi0gICAgICogICBzZXJpYWxpemluZwotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIHNlcmlhbGl6ZVByZVJvb3QoKQotICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGludCBpOwotCi0gICAgICAgIGlmICggX3ByZVJvb3QgIT0gbnVsbCApIHsKLSAgICAgICAgICAgIGZvciAoIGkgPSAwIDsgaSA8IF9wcmVSb290LnNpemUoKSA7ICsraSApIHsKLSAgICAgICAgICAgICAgICBwcmludFRleHQoIChTdHJpbmcpIF9wcmVSb290LmVsZW1lbnRBdCggaSApLCB0cnVlLCB0cnVlICk7Ci0gICAgICAgICAgICAgICAgaWYgKCBfaW5kZW50aW5nICkKLSAgICAgICAgICAgICAgICBfcHJpbnRlci5icmVha0xpbmUoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIF9wcmVSb290LnJlbW92ZUFsbEVsZW1lbnRzKCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLy8KLSAgICAvLyBUZXh0IHByZXR0eSBwcmludGluZyBhbmQgZm9ybWF0dGluZyBtZXRob2RzIC8vCi0gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0vLwotCi0gICAgcHJvdGVjdGVkIHZvaWQgcHJpbnRDREFUQVRleHQoIFN0cmluZyB0ZXh0ICkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLSAgICAgICAgaW50IGxlbmd0aCA9IHRleHQubGVuZ3RoKCk7Ci0gICAgICAgIGNoYXIgY2g7Ci0KLSAgICAgICAgZm9yICggaW50IGluZGV4ID0gMCA7IGluZGV4IDwgIGxlbmd0aDsgKytpbmRleCApIHsKLSAgICAgICAgICAgIGNoID0gdGV4dC5jaGFyQXQoIGluZGV4ICk7Ci0gICAgICAgICAgICBpZiAoY2ggPT0gJ10nCi0gICAgICAgICAgICAgICAgJiYgaW5kZXggKyAyIDwgbGVuZ3RoCi0gICAgICAgICAgICAgICAgJiYgdGV4dC5jaGFyQXQoaW5kZXggKyAxKSA9PSAnXScKLSAgICAgICAgICAgICAgICAmJiB0ZXh0LmNoYXJBdChpbmRleCArIDIpID09ICc+JykgeyAvLyBjaGVjayBmb3IgJ11dPicKLSAgICAgICAgICAgICAgICBpZiAoZkRPTUVycm9ySGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIFJFVklTSVQ6IHRoaXMgbWVhbnMgdGhhdCBpZiBET00gRXJyb3IgaGFuZGxlciBpcyBub3QgcmVnaXN0ZXJlZCB3ZSBkb24ndCByZXBvcnQgYW55Ci0gICAgICAgICAgICAgICAgICAgIC8vIGZhdGFsIGVycm9ycyBhbmQgbWlnaHQgc2VyaWFsaXplIG5vdCB3ZWxsZm9ybWVkIGRvY3VtZW50Ci0gICAgICAgICAgICAgICAgICAgIGlmICgoZmVhdHVyZXMgJiBET01TZXJpYWxpemVySW1wbC5TUExJVENEQVRBKSA9PSAwKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbXNnID0gRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuU0VSSUFMSVpFUl9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIkVuZGluZ0NEQVRBIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoZmVhdHVyZXMgJiBET01TZXJpYWxpemVySW1wbC5XRUxMRk9STUVEKSAhPSAwKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaXNzdWUgZmF0YWwgZXJyb3IKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2RpZnlET01FcnJvcihtc2csIERPTUVycm9yLlNFVkVSSVRZX0ZBVEFMX0VSUk9SLCAid2YtaW52YWxpZC1jaGFyYWN0ZXIiLCBmQ3VycmVudE5vZGUpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZET01FcnJvckhhbmRsZXIuaGFuZGxlRXJyb3IoZkRPTUVycm9yKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTFNFeGNlcHRpb24oTFNFeGNlcHRpb24uU0VSSUFMSVpFX0VSUiwgbXNnKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlzc3VlIGVycm9yCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kaWZ5RE9NRXJyb3IobXNnLCBET01FcnJvci5TRVZFUklUWV9FUlJPUiwgImNkYXRhLXNlY3Rpb24tbm90LXNwbGl0dGVkIiwgZkN1cnJlbnROb2RlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWZET01FcnJvckhhbmRsZXIuaGFuZGxlRXJyb3IoZkRPTUVycm9yKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTFNFeGNlcHRpb24oTFNFeGNlcHRpb24uU0VSSUFMSVpFX0VSUiwgbXNnKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBpc3N1ZSB3YXJuaW5nCi0gICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbXNnID0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuU0VSSUFMSVpFUl9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTcGxpdHRpbmdDREFUQSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwpOwotICAgICAgICAgICAgICAgICAgICAgICAgbW9kaWZ5RE9NRXJyb3IoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbXNnLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIERPTUVycm9yLlNFVkVSSVRZX1dBUk5JTkcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwgZkN1cnJlbnROb2RlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZET01FcnJvckhhbmRsZXIuaGFuZGxlRXJyb3IoZkRPTUVycm9yKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvLyBzcGxpdCBDREFUQSBzZWN0aW9uCi0gICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCJdXV1dPjwhW0NEQVRBWz4iKTsKLSAgICAgICAgICAgICAgICBpbmRleCArPSAyOwotICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAoIVhNTENoYXIuaXNWYWxpZChjaCkpIHsKLSAgICAgICAgICAgICAgICAvLyBjaGVjayBpZiBpdCBpcyBzdXJyb2dhdGUKLSAgICAgICAgICAgICAgICBpZiAoKytpbmRleCA8bGVuZ3RoKSB7Ci0gICAgICAgICAgICAgICAgICAgIHN1cnJvZ2F0ZXMoY2gsIHRleHQuY2hhckF0KGluZGV4KSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICBmYXRhbEVycm9yKCJUaGUgY2hhcmFjdGVyICciKyhjaGFyKWNoKyInIGlzIGFuIGludmFsaWQgWE1MIGNoYXJhY3RlciIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgaWYgKCAoIGNoID49ICcgJyAmJiBfZW5jb2RpbmdJbmZvLmlzUHJpbnRhYmxlKChjaGFyKWNoKSAmJiBjaCAhPSAweEY3ICkgfHwKLSAgICAgICAgICAgICAgICAgICAgIGNoID09ICdcbicgfHwgY2ggPT0gJ1xyJyB8fCBjaCA9PSAnXHQnICkgewotICAgICAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoKGNoYXIpY2gpOwotICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0KLSAgICAgICAgICAgICAgICAgICAgLy8gVGhlIGNoYXJhY3RlciBpcyBub3QgcHJpbnRhYmxlIC0tIHNwbGl0IENEQVRBIHNlY3Rpb24KLSAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCJdXT4mI3giKTsKLSAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KEludGVnZXIudG9IZXhTdHJpbmcoY2gpKTsKLSAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCI7PCFbQ0RBVEFbIik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICBwcm90ZWN0ZWQgdm9pZCBzdXJyb2dhdGVzKGludCBoaWdoLCBpbnQgbG93KSB0aHJvd3MgSU9FeGNlcHRpb257Ci0gICAgICAgIGlmIChYTUxDaGFyLmlzSGlnaFN1cnJvZ2F0ZShoaWdoKSkgewotICAgICAgICAgICAgaWYgKCFYTUxDaGFyLmlzTG93U3Vycm9nYXRlKGxvdykpIHsKLSAgICAgICAgICAgICAgICAvL0ludmFsaWQgWE1MCi0gICAgICAgICAgICAgICAgZmF0YWxFcnJvcigiVGhlIGNoYXJhY3RlciAnIisoY2hhcilsb3crIicgaXMgYW4gaW52YWxpZCBYTUwgY2hhcmFjdGVyIik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBpbnQgc3VwcGxlbWVudGFsID0gWE1MQ2hhci5zdXBwbGVtZW50YWwoKGNoYXIpaGlnaCwgKGNoYXIpbG93KTsKLSAgICAgICAgICAgICAgICBpZiAoIVhNTENoYXIuaXNWYWxpZChzdXBwbGVtZW50YWwpKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vSW52YWxpZCBYTUwKLSAgICAgICAgICAgICAgICAgICAgZmF0YWxFcnJvcigiVGhlIGNoYXJhY3RlciAnIisoY2hhcilzdXBwbGVtZW50YWwrIicgaXMgYW4gaW52YWxpZCBYTUwgY2hhcmFjdGVyIik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICBpZiAoY29udGVudCgpLmluQ0RhdGEgKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoIl1dPiYjeCIpOwotICAgICAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KEludGVnZXIudG9IZXhTdHJpbmcoc3VwcGxlbWVudGFsKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoIjs8IVtDREFUQVsiKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHByaW50SGV4KHN1cHBsZW1lbnRhbCk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBmYXRhbEVycm9yKCJUaGUgY2hhcmFjdGVyICciKyhjaGFyKWhpZ2grIicgaXMgYW4gaW52YWxpZCBYTUwgY2hhcmFjdGVyIik7Ci0gICAgICAgIH0KLQotICAgIH0KLQotICAgIC8qKgotICAgICAqIENhbGxlZCB0byBwcmludCBhZGRpdGlvbmFsIHRleHQgd2l0aCB3aGl0ZXNwYWNlIGhhbmRsaW5nLgotICAgICAqIElmIHNwYWNlcyBhcmUgcHJlc2VydmVkLCB0aGUgdGV4dCBpcyBwcmludGVkIGFzIGlmIGJ5IGNhbGxpbmcKLSAgICAgKiB7QGxpbmsgI3ByaW50VGV4dChTdHJpbmcsYm9vbGVhbixib29sZWFuKX0gd2l0aCBhIGNhbGwgdG8ge0BsaW5rIFByaW50ZXIjYnJlYWtMaW5lfQotICAgICAqIGZvciBlYWNoIG5ldyBsaW5lLiBJZiBzcGFjZXMgYXJlIG5vdCBwcmVzZXJ2ZWQsIHRoZSB0ZXh0IGlzCi0gICAgICogYnJva2VuIGF0IHNwYWNlIGJvdW5kYXJpZXMgaWYgbG9uZ2VyIHRoYW4gdGhlIGxpbmUgd2lkdGg7Ci0gICAgICogTXVsdGlwbGUgc3BhY2VzIGFyZSBwcmludGVkIGFzIHN1Y2gsIGJ1dCBzcGFjZXMgYXQgYmVnaW5uaW5nCi0gICAgICogb2YgbGluZSBhcmUgcmVtb3ZlZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSB0ZXh0IFRoZSB0ZXh0IHRvIHByaW50Ci0gICAgICogQHBhcmFtIHByZXNlcnZlU3BhY2UgU3BhY2UgcHJlc2VydmluZyBmbGFnCi0gICAgICogQHBhcmFtIHVuZXNjYXBlZCBQcmludCB1bmVzY2FwZWQKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCBwcmludFRleHQoIGNoYXJbXSBjaGFycywgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBwcmVzZXJ2ZVNwYWNlLCBib29sZWFuIHVuZXNjYXBlZCApCi0gICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaW50IGluZGV4OwotICAgICAgICBjaGFyIGNoOwotCi0gICAgICAgIGlmICggcHJlc2VydmVTcGFjZSApIHsKLSAgICAgICAgICAgIC8vIFByZXNlcnZpbmcgc3BhY2VzOiB0aGUgdGV4dCBtdXN0IHByaW50IGV4YWN0bHkgYXMgaXQgaXMsCi0gICAgICAgICAgICAvLyB3aXRob3V0IGJyZWFraW5nIHdoZW4gc3BhY2VzIGFwcGVhciBpbiB0aGUgdGV4dCBhbmQgd2l0aG91dAotICAgICAgICAgICAgLy8gY29uc29saWRhdGluZyBzcGFjZXMuIElmIGEgbGluZSB0ZXJtaW5hdG9yIGlzIHVzZWQsIGEgbGluZQotICAgICAgICAgICAgLy8gYnJlYWsgd2lsbCBvY2N1ci4KLSAgICAgICAgICAgIHdoaWxlICggbGVuZ3RoLS0gPiAwICkgewotICAgICAgICAgICAgICAgIGNoID0gY2hhcnNbIHN0YXJ0IF07Ci0gICAgICAgICAgICAgICAgKytzdGFydDsKLSAgICAgICAgICAgICAgICBpZiAoIGNoID09ICdcbicgfHwgY2ggPT0gJ1xyJyB8fCB1bmVzY2FwZWQgKQotICAgICAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoIGNoICk7Ci0gICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICBwcmludEVzY2FwZWQoIGNoICk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAvLyBOb3QgcHJlc2VydmluZyBzcGFjZXM6IHByaW50IG9uZSBwYXJ0IGF0IGEgdGltZSwgYW5kCi0gICAgICAgICAgICAvLyB1c2Ugc3BhY2VzIGJldHdlZW4gcGFydHMgdG8gYnJlYWsgdGhlbSBpbnRvIGRpZmZlcmVudAotICAgICAgICAgICAgLy8gbGluZXMuIFNwYWNlcyBhdCBiZWdpbm5pbmcgb2YgbGluZSB3aWxsIGJlIHN0cmlwcGVkCi0gICAgICAgICAgICAvLyBieSBwcmludGluZyBtZWNoYW5pc20uIExpbmUgdGVybWluYXRvciBpcyB0cmVhdGVkCi0gICAgICAgICAgICAvLyBubyBkaWZmZXJlbnQgdGhhbiBvdGhlciB0ZXh0IHBhcnQuCi0gICAgICAgICAgICB3aGlsZSAoIGxlbmd0aC0tID4gMCApIHsKLSAgICAgICAgICAgICAgICBjaCA9IGNoYXJzWyBzdGFydCBdOwotICAgICAgICAgICAgICAgICsrc3RhcnQ7Ci0gICAgICAgICAgICAgICAgaWYgKCBjaCA9PSAnICcgfHwgY2ggPT0gJ1xmJyB8fCBjaCA9PSAnXHQnIHx8IGNoID09ICdcbicgfHwgY2ggPT0gJ1xyJyApCi0gICAgICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50U3BhY2UoKTsKLSAgICAgICAgICAgICAgICBlbHNlIGlmICggdW5lc2NhcGVkICkKLSAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCBjaCApOwotICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgICAgcHJpbnRFc2NhcGVkKCBjaCApOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICBwcm90ZWN0ZWQgdm9pZCBwcmludFRleHQoIFN0cmluZyB0ZXh0LCBib29sZWFuIHByZXNlcnZlU3BhY2UsIGJvb2xlYW4gdW5lc2NhcGVkICkKLSAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uCi0gICAgewotICAgICAgICBpbnQgaW5kZXg7Ci0gICAgICAgIGNoYXIgY2g7Ci0KLSAgICAgICAgaWYgKCBwcmVzZXJ2ZVNwYWNlICkgewotICAgICAgICAgICAgLy8gUHJlc2VydmluZyBzcGFjZXM6IHRoZSB0ZXh0IG11c3QgcHJpbnQgZXhhY3RseSBhcyBpdCBpcywKLSAgICAgICAgICAgIC8vIHdpdGhvdXQgYnJlYWtpbmcgd2hlbiBzcGFjZXMgYXBwZWFyIGluIHRoZSB0ZXh0IGFuZCB3aXRob3V0Ci0gICAgICAgICAgICAvLyBjb25zb2xpZGF0aW5nIHNwYWNlcy4gSWYgYSBsaW5lIHRlcm1pbmF0b3IgaXMgdXNlZCwgYSBsaW5lCi0gICAgICAgICAgICAvLyBicmVhayB3aWxsIG9jY3VyLgotICAgICAgICAgICAgZm9yICggaW5kZXggPSAwIDsgaW5kZXggPCB0ZXh0Lmxlbmd0aCgpIDsgKytpbmRleCApIHsKLSAgICAgICAgICAgICAgICBjaCA9IHRleHQuY2hhckF0KCBpbmRleCApOwotICAgICAgICAgICAgICAgIGlmICggY2ggPT0gJ1xuJyB8fCBjaCA9PSAnXHInIHx8IHVuZXNjYXBlZCApCi0gICAgICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggY2ggKTsKLSAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgIHByaW50RXNjYXBlZCggY2ggKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIC8vIE5vdCBwcmVzZXJ2aW5nIHNwYWNlczogcHJpbnQgb25lIHBhcnQgYXQgYSB0aW1lLCBhbmQKLSAgICAgICAgICAgIC8vIHVzZSBzcGFjZXMgYmV0d2VlbiBwYXJ0cyB0byBicmVhayB0aGVtIGludG8gZGlmZmVyZW50Ci0gICAgICAgICAgICAvLyBsaW5lcy4gU3BhY2VzIGF0IGJlZ2lubmluZyBvZiBsaW5lIHdpbGwgYmUgc3RyaXBwZWQKLSAgICAgICAgICAgIC8vIGJ5IHByaW50aW5nIG1lY2hhbmlzbS4gTGluZSB0ZXJtaW5hdG9yIGlzIHRyZWF0ZWQKLSAgICAgICAgICAgIC8vIG5vIGRpZmZlcmVudCB0aGFuIG90aGVyIHRleHQgcGFydC4KLSAgICAgICAgICAgIGZvciAoIGluZGV4ID0gMCA7IGluZGV4IDwgdGV4dC5sZW5ndGgoKSA7ICsraW5kZXggKSB7Ci0gICAgICAgICAgICAgICAgY2ggPSB0ZXh0LmNoYXJBdCggaW5kZXggKTsKLSAgICAgICAgICAgICAgICBpZiAoIGNoID09ICcgJyB8fCBjaCA9PSAnXGYnIHx8IGNoID09ICdcdCcgfHwgY2ggPT0gJ1xuJyB8fCBjaCA9PSAnXHInICkKLSAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRTcGFjZSgpOwotICAgICAgICAgICAgICAgIGVsc2UgaWYgKCB1bmVzY2FwZWQgKQotICAgICAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoIGNoICk7Ci0gICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICBwcmludEVzY2FwZWQoIGNoICk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFByaW50IGEgZG9jdW1lbnQgdHlwZSBwdWJsaWMgb3Igc3lzdGVtIGlkZW50aWZpZXIgVVJMLgotICAgICAqIEVuY2Fwc3VsYXRlcyB0aGUgVVJMIGluIGRvdWJsZSBxdW90ZXMsIGVzY2FwZXMgbm9uLXByaW50aW5nCi0gICAgICogY2hhcmFjdGVycyBhbmQgcHJpbnQgaXQgZXF1aXZhbGVudCB0byB7QGxpbmsgI3ByaW50VGV4dH0uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdXJsIFRoZSBkb2N1bWVudCB0eXBlIHVybCB0byBwcmludAotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIHByaW50RG9jdHlwZVVSTCggU3RyaW5nIHVybCApCi0gICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaW50ICAgICAgICAgICAgICAgIGk7Ci0KLSAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAnIicgKTsKLSAgICAgICAgZm9yKCBpID0gMCA7IGkgPCB1cmwubGVuZ3RoKCkgOyArK2kgKSB7Ci0gICAgICAgICAgICBpZiAoIHVybC5jaGFyQXQoIGkgKSA9PSAnIicgfHwgIHVybC5jaGFyQXQoIGkgKSA8IDB4MjAgfHwgdXJsLmNoYXJBdCggaSApID4gMHg3RiApIHsKLSAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoICclJyApOwotICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggSW50ZWdlci50b0hleFN0cmluZyggdXJsLmNoYXJBdCggaSApICkgKTsKLSAgICAgICAgICAgIH0gZWxzZQotICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggdXJsLmNoYXJBdCggaSApICk7Ci0gICAgICAgIH0KLSAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAnIicgKTsKLSAgICB9Ci0KLQotICAgIHByb3RlY3RlZCB2b2lkIHByaW50RXNjYXBlZCggaW50IGNoICkKLSAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uCi0gICAgewotICAgICAgICBTdHJpbmcgY2hhclJlZjsKLSAgICAgICAgLy8gSWYgdGhlcmUgaXMgYSBzdWl0YWJsZSBlbnRpdHkgcmVmZXJlbmNlIGZvciB0aGlzCi0gICAgICAgIC8vIGNoYXJhY3RlciwgcHJpbnQgaXQuIFRoZSBsaXN0IG9mIGF2YWlsYWJsZSBlbnRpdHkKLSAgICAgICAgLy8gcmVmZXJlbmNlcyBpcyBhbG1vc3QgYnV0IG5vdCBpZGVudGljYWwgYmV0d2VlbgotICAgICAgICAvLyBYTUwgYW5kIEhUTUwuCi0gICAgICAgIGNoYXJSZWYgPSBnZXRFbnRpdHlSZWYoIGNoICk7Ci0gICAgICAgIGlmICggY2hhclJlZiAhPSBudWxsICkgewotICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAnJicgKTsKLSAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggY2hhclJlZiApOwotICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAnOycgKTsKLSAgICAgICAgfSBlbHNlIGlmICggKCBjaCA+PSAnICcgJiYgX2VuY29kaW5nSW5mby5pc1ByaW50YWJsZSgoY2hhciljaCkgJiYgY2ggIT0gMHhGNyApIHx8Ci0gICAgICAgICAgICAgICAgICAgIGNoID09ICdcbicgfHwgY2ggPT0gJ1xyJyB8fCBjaCA9PSAnXHQnICkgewotICAgICAgICAgICAgLy8gTm9uIHByaW50YWJsZXMgYXJlIGJlbG93IEFTQ0lJIHNwYWNlIGJ1dCBub3QgdGFiIG9yIGxpbmUKLSAgICAgICAgICAgIC8vIHRlcm1pbmF0b3IsIEFTQ0lJIGRlbGV0ZSwgb3IgYWJvdmUgYSBjZXJ0YWluIFVuaWNvZGUgdGhyZXNob2xkLgotICAgICAgICAgICAgaWYgKGNoIDwgMHgxMDAwMCkgewotICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCgoY2hhciljaCApOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoKGNoYXIpKCgoY2gtMHgxMDAwMCk+PjEwKSsweGQ4MDApKTsKLSAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoKGNoYXIpKCgoY2gtMHgxMDAwMCkmMHgzZmYpKzB4ZGMwMCkpOwotICAgICAgICAgICAgfQotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnRIZXgoY2gpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBFc2NhcGVzIGNoYXJzCi0gICAgICAgICAqLwotICAgICAgICAgZmluYWwgdm9pZCBwcmludEhleCggaW50IGNoKSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoICImI3giICk7Ci0gICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dChJbnRlZ2VyLnRvSGV4U3RyaW5nKGNoKSk7Ci0gICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggJzsnICk7Ci0KLSAgICAgICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogRXNjYXBlcyBhIHN0cmluZyBzbyBpdCBtYXkgYmUgcHJpbnRlZCBhcyB0ZXh0IGNvbnRlbnQgb3IgYXR0cmlidXRlCi0gICAgICogdmFsdWUuIE5vbiBwcmludGFibGUgY2hhcmFjdGVycyBhcmUgZXNjYXBlZCB1c2luZyBjaGFyYWN0ZXIgcmVmZXJlbmNlcy4KLSAgICAgKiBXaGVyZSB0aGUgZm9ybWF0IHNwZWNpZmllcyBhIGRlYXVsdCBlbnRpdHkgcmVmZXJlbmNlLCB0aGF0IHJlZmVyZW5jZQotICAgICAqIGlzIHVzZWQgKGUuZy4gPHR0PiZhbXA7bHQ7PC90dD4pLgotICAgICAqCi0gICAgICogQHBhcmFtIHNvdXJjZSBUaGUgc3RyaW5nIHRvIGVzY2FwZQotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIHByaW50RXNjYXBlZCggU3RyaW5nIHNvdXJjZSApCi0gICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgZm9yICggaW50IGkgPSAwIDsgaSA8IHNvdXJjZS5sZW5ndGgoKSA7ICsraSApIHsKLSAgICAgICAgICAgIGludCBjaCA9IHNvdXJjZS5jaGFyQXQoaSk7Ci0gICAgICAgICAgICBpZiAoKGNoICYgMHhmYzAwKSA9PSAweGQ4MDAgJiYgaSsxIDwgc291cmNlLmxlbmd0aCgpKSB7Ci0gICAgICAgICAgICAgICAgaW50IGxvd2NoID0gc291cmNlLmNoYXJBdChpKzEpOwotICAgICAgICAgICAgICAgIGlmICgobG93Y2ggJiAweGZjMDApID09IDB4ZGMwMCkgewotICAgICAgICAgICAgICAgICAgICBjaCA9IDB4MTAwMDAgKyAoKGNoLTB4ZDgwMCk8PDEwKSArIGxvd2NoLTB4ZGMwMDsKLSAgICAgICAgICAgICAgICAgICAgaSsrOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHByaW50RXNjYXBlZChjaCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0vLwotICAgIC8vIEVsZW1lbnQgc3RhdGUgaGFuZGxpbmcgbWV0aG9kcyAvLwotICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0vLwotCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIHN0YXRlIG9mIHRoZSBjdXJyZW50IGVsZW1lbnQuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIEN1cnJlbnQgZWxlbWVudCBzdGF0ZQotICAgICAqLwotICAgIHByb3RlY3RlZCBFbGVtZW50U3RhdGUgZ2V0RWxlbWVudFN0YXRlKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBfZWxlbWVudFN0YXRlc1sgX2VsZW1lbnRTdGF0ZUNvdW50IF07Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBFbnRlciBhIG5ldyBlbGVtZW50IHN0YXRlIGZvciB0aGUgc3BlY2lmaWVkIGVsZW1lbnQuCi0gICAgICogVGFnIG5hbWUgYW5kIHNwYWNlIHByZXNlcnZpbmcgaXMgc3BlY2lmaWVkLCBlbGVtZW50Ci0gICAgICogc3RhdGUgaXMgaW5pdGlhbGx5IGVtcHR5LgotICAgICAqCi0gICAgICogQHJldHVybiBDdXJyZW50IGVsZW1lbnQgc3RhdGUsIG9yIG51bGwKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgRWxlbWVudFN0YXRlIGVudGVyRWxlbWVudFN0YXRlKCBTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgbG9jYWxOYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyByYXdOYW1lLCBib29sZWFuIHByZXNlcnZlU3BhY2UgKQotICAgIHsKLSAgICAgICAgRWxlbWVudFN0YXRlIHN0YXRlOwotCi0gICAgICAgIGlmICggX2VsZW1lbnRTdGF0ZUNvdW50ICsgMSA9PSBfZWxlbWVudFN0YXRlcy5sZW5ndGggKSB7Ci0gICAgICAgICAgICBFbGVtZW50U3RhdGVbXSBuZXdTdGF0ZXM7Ci0KLSAgICAgICAgICAgIC8vIE5lZWQgdG8gY3JlYXRlIGEgbGFyZ2VyIGFycmF5IG9mIHN0YXRlcy4gVGhpcyBkb2VzIG5vdCBoYXBwZW4KLSAgICAgICAgICAgIC8vIG9mdGVuLCB1bmxlc3MgdGhlIGRvY3VtZW50IGlzIHJlYWxseSBkZWVwLgotICAgICAgICAgICAgbmV3U3RhdGVzID0gbmV3IEVsZW1lbnRTdGF0ZVsgX2VsZW1lbnRTdGF0ZXMubGVuZ3RoICsgMTAgXTsKLSAgICAgICAgICAgIGZvciAoIGludCBpID0gMCA7IGkgPCBfZWxlbWVudFN0YXRlcy5sZW5ndGggOyArK2kgKQotICAgICAgICAgICAgICAgIG5ld1N0YXRlc1sgaSBdID0gX2VsZW1lbnRTdGF0ZXNbIGkgXTsKLSAgICAgICAgICAgIGZvciAoIGludCBpID0gX2VsZW1lbnRTdGF0ZXMubGVuZ3RoIDsgaSA8IG5ld1N0YXRlcy5sZW5ndGggOyArK2kgKQotICAgICAgICAgICAgICAgIG5ld1N0YXRlc1sgaSBdID0gbmV3IEVsZW1lbnRTdGF0ZSgpOwotICAgICAgICAgICAgX2VsZW1lbnRTdGF0ZXMgPSBuZXdTdGF0ZXM7Ci0gICAgICAgIH0KLQotICAgICAgICArK19lbGVtZW50U3RhdGVDb3VudDsKLSAgICAgICAgc3RhdGUgPSBfZWxlbWVudFN0YXRlc1sgX2VsZW1lbnRTdGF0ZUNvdW50IF07Ci0gICAgICAgIHN0YXRlLm5hbWVzcGFjZVVSSSA9IG5hbWVzcGFjZVVSSTsKLSAgICAgICAgc3RhdGUubG9jYWxOYW1lID0gbG9jYWxOYW1lOwotICAgICAgICBzdGF0ZS5yYXdOYW1lID0gcmF3TmFtZTsKLSAgICAgICAgc3RhdGUucHJlc2VydmVTcGFjZSA9IHByZXNlcnZlU3BhY2U7Ci0gICAgICAgIHN0YXRlLmVtcHR5ID0gdHJ1ZTsKLSAgICAgICAgc3RhdGUuYWZ0ZXJFbGVtZW50ID0gZmFsc2U7Ci0gICAgICAgIHN0YXRlLmFmdGVyQ29tbWVudCA9IGZhbHNlOwotICAgICAgICBzdGF0ZS5kb0NEYXRhID0gc3RhdGUuaW5DRGF0YSA9IGZhbHNlOwotICAgICAgICBzdGF0ZS51bmVzY2FwZWQgPSBmYWxzZTsKLSAgICAgICAgc3RhdGUucHJlZml4ZXMgPSBfcHJlZml4ZXM7Ci0KLSAgICAgICAgX3ByZWZpeGVzID0gbnVsbDsKLSAgICAgICAgcmV0dXJuIHN0YXRlOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogTGVhdmUgdGhlIGN1cnJlbnQgZWxlbWVudCBzdGF0ZSBhbmQgcmV0dXJuIHRvIHRoZQotICAgICAqIHN0YXRlIG9mIHRoZSBwYXJlbnQgZWxlbWVudC4gSWYgdGhpcyB3YXMgdGhlIHJvb3QKLSAgICAgKiBlbGVtZW50LCByZXR1cm4gdG8gdGhlIHN0YXRlIG9mIHRoZSBkb2N1bWVudC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gUHJldmlvdXMgZWxlbWVudCBzdGF0ZQotICAgICAqLwotICAgIHByb3RlY3RlZCBFbGVtZW50U3RhdGUgbGVhdmVFbGVtZW50U3RhdGUoKQotICAgIHsKLSAgICAgICAgaWYgKCBfZWxlbWVudFN0YXRlQ291bnQgPiAwICkgewotICAgICAgICAgICAgLypDb3JyZWN0ZWQgYnkgRGF2aWQgQmxvbmRlYXUgKGJsb25kZWF1QGludGFsaW8uY29tKSovCi0gICAgICAgICAgICAgICAgX3ByZWZpeGVzID0gbnVsbDsKLSAgICAgICAgICAgICAgICAvL19wcmVmaXhlcyA9IF9lbGVtZW50U3RhdGVzWyBfZWxlbWVudFN0YXRlQ291bnQgXS5wcmVmaXhlczsKLSAgICAgICAgICAgIC0tIF9lbGVtZW50U3RhdGVDb3VudDsKLSAgICAgICAgICAgIHJldHVybiBfZWxlbWVudFN0YXRlc1sgX2VsZW1lbnRTdGF0ZUNvdW50IF07Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBTdHJpbmcgbXNnID0gRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuU0VSSUFMSVpFUl9ET01BSU4sICJJbnRlcm5hbCIsIG51bGwpOwotICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbihtc2cpOwotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRydWUgaWYgaW4gdGhlIHN0YXRlIG9mIHRoZSBkb2N1bWVudC4KLSAgICAgKiBSZXR1cm5zIHRydWUgYmVmb3JlIGVudGVyaW5nIGFueSBlbGVtZW50IGFuZCBhZnRlcgotICAgICAqIGxlYXZpbmcgdGhlIHJvb3QgZWxlbWVudC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVHJ1ZSBpZiBpbiB0aGUgc3RhdGUgb2YgdGhlIGRvY3VtZW50Ci0gICAgICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gaXNEb2N1bWVudFN0YXRlKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBfZWxlbWVudFN0YXRlQ291bnQgPT0gMDsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIG5hbWVzcGFjZSBwcmVmaXggZm9yIHRoZSBzcGVjaWZpZWQgVVJJLgotICAgICAqIElmIHRoZSBVUkkgaGFzIGJlZW4gbWFwcGVkIHRvIGEgcHJlZml4LCByZXR1cm5zIHRoZQotICAgICAqIHByZWZpeCwgb3RoZXJ3aXNlIHJldHVybnMgbnVsbC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkgVGhlIG5hbWVzcGFjZSBVUkkKLSAgICAgKiBAcmV0dXJuIFRoZSBuYW1lc3BhY2UgcHJlZml4IGlmIGtub3duLCBvciBudWxsCi0gICAgICovCi0gICAgcHJvdGVjdGVkIFN0cmluZyBnZXRQcmVmaXgoIFN0cmluZyBuYW1lc3BhY2VVUkkgKQotICAgIHsKLSAgICAgICAgU3RyaW5nICAgIHByZWZpeDsKLQotICAgICAgICBpZiAoIF9wcmVmaXhlcyAhPSBudWxsICkgewotICAgICAgICAgICAgcHJlZml4ID0gX3ByZWZpeGVzLmdldCggbmFtZXNwYWNlVVJJICk7Ci0gICAgICAgICAgICBpZiAoIHByZWZpeCAhPSBudWxsICkKLSAgICAgICAgICAgICAgICByZXR1cm4gcHJlZml4OwotICAgICAgICB9Ci0gICAgICAgIGlmICggX2VsZW1lbnRTdGF0ZUNvdW50ID09IDAgKQotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgZm9yICggaW50IGkgPSBfZWxlbWVudFN0YXRlQ291bnQgOyBpID4gMCA7IC0taSApIHsKLSAgICAgICAgICAgICAgICBpZiAoIF9lbGVtZW50U3RhdGVzWyBpIF0ucHJlZml4ZXMgIT0gbnVsbCApIHsKLSAgICAgICAgICAgICAgICAgICAgcHJlZml4ID0gKFN0cmluZykgX2VsZW1lbnRTdGF0ZXNbIGkgXS5wcmVmaXhlcy5nZXQoIG5hbWVzcGFjZVVSSSApOwotICAgICAgICAgICAgICAgICAgICBpZiAoIHByZWZpeCAhPSBudWxsICkKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBwcmVmaXg7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoZSBtZXRob2QgbW9kaWZpZXMgZ2xvYmFsIERPTSBlcnJvciBvYmplY3QKLSAgICAgKgotICAgICAqIEBwYXJhbSBtZXNzYWdlCi0gICAgICogQHBhcmFtIHNldmVyaXR5Ci0gICAgICogQHBhcmFtIHR5cGUKLSAgICAgKiBAcmV0dXJuIGEgRE9NRXJyb3IKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgRE9NRXJyb3IgbW9kaWZ5RE9NRXJyb3IoU3RyaW5nIG1lc3NhZ2UsIHNob3J0IHNldmVyaXR5LCBTdHJpbmcgdHlwZSwgTm9kZSBub2RlKXsKLSAgICAgICAgICAgIGZET01FcnJvci5yZXNldCgpOwotICAgICAgICAgICAgZkRPTUVycm9yLmZNZXNzYWdlID0gbWVzc2FnZTsKLSAgICAgICAgICAgIGZET01FcnJvci5mVHlwZSA9IHR5cGU7Ci0gICAgICAgICAgICBmRE9NRXJyb3IuZlNldmVyaXR5ID0gc2V2ZXJpdHk7Ci0gICAgICAgICAgICBmRE9NRXJyb3IuZkxvY2F0b3IgPSBuZXcgRE9NTG9jYXRvckltcGwoLTEsIC0xLCAtMSwgbm9kZSwgbnVsbCk7Ci0gICAgICAgICAgICByZXR1cm4gZkRPTUVycm9yOwotCi0gICAgfQotCi0KLSAgICBwcm90ZWN0ZWQgdm9pZCBmYXRhbEVycm9yKFN0cmluZyBtZXNzYWdlKSB0aHJvd3MgSU9FeGNlcHRpb257Ci0gICAgICAgIGlmIChmRE9NRXJyb3JIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIG1vZGlmeURPTUVycm9yKG1lc3NhZ2UsIERPTUVycm9yLlNFVkVSSVRZX0ZBVEFMX0VSUk9SLCBudWxsLCBmQ3VycmVudE5vZGUpOwotICAgICAgICAgICAgZkRPTUVycm9ySGFuZGxlci5oYW5kbGVFcnJvcihmRE9NRXJyb3IpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKG1lc3NhZ2UpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBET00gbGV2ZWwgMzoKLSAgICAgICAgICogQ2hlY2sgYSBub2RlIHRvIGRldGVybWluZSBpZiBpdCBjb250YWlucyB1bmJvdW5kIG5hbWVzcGFjZSBwcmVmaXhlcy4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIG5vZGUgVGhlIG5vZGUgdG8gY2hlY2sgZm9yIHVuYm91bmQgbmFtZXNwYWNlIHByZWZpY2VzCi0gICAgICAgICAqLwotICAgICAgICAgcHJvdGVjdGVkIHZvaWQgY2hlY2tVbmJvdW5kTmFtZXNwYWNlUHJlZml4ZWROb2RlIChOb2RlIG5vZGUpIHRocm93cyBJT0V4Y2VwdGlvbnsKLQotICAgICAgICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplL0RPTVNlcmlhbGl6ZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZS9ET01TZXJpYWxpemVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDQwNTY2NjEuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplL0RPTVNlcmlhbGl6ZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDc5ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwMiwyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplOwotCi0KLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotaW1wb3J0IG9yZy53M2MuZG9tLkVsZW1lbnQ7Ci1pbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7Ci1pbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnRGcmFnbWVudDsKLQotCi0KLS8qKgotICogSW50ZXJmYWNlIGZvciBhIERPTSBzZXJpYWxpemVyIGltcGxlbWVudGF0aW9uLgotICoKLSAqCi0gKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzpTY290dF9Cb2FnL0NBTS9Mb3R1c0Bsb3R1cy5jb20iPlNjb3R0IEJvYWc8L2E+Ci0gKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzphcmtpbkBpbnRhbGlvLmNvbSI+QXNzYWYgQXJraW48L2E+Ci0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgRE9NU2VyaWFsaXplcgotewotCi0KLSAgICAvKioKLSAgICAgKiBTZXJpYWxpemVkIHRoZSBET00gZWxlbWVudC4gVGhyb3dzIGFuIGV4Y2VwdGlvbiBvbmx5IGlmCi0gICAgICogYW4gSS9PIGV4Y2VwdGlvbiBvY2N1cmVkIHdoaWxlIHNlcmlhbGl6aW5nLgotICAgICAqCi0gICAgICogQHBhcmFtIGVsZW0gVGhlIGVsZW1lbnQgdG8gc2VyaWFsaXplCi0gICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBBbiBJL08gZXhjZXB0aW9uIG9jY3VyZWQgd2hpbGUKLSAgICAgKiAgIHNlcmlhbGl6aW5nCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2VyaWFsaXplKCBFbGVtZW50IGVsZW0gKQotICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb247Ci0KLQotICAgIC8qKgotICAgICAqIFNlcmlhbGl6ZXMgdGhlIERPTSBkb2N1bWVudC4gVGhyb3dzIGFuIGV4Y2VwdGlvbiBvbmx5IGlmCi0gICAgICogYW4gSS9PIGV4Y2VwdGlvbiBvY2N1cmVkIHdoaWxlIHNlcmlhbGl6aW5nLgotICAgICAqCi0gICAgICogQHBhcmFtIGRvYyBUaGUgZG9jdW1lbnQgdG8gc2VyaWFsaXplCi0gICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBBbiBJL08gZXhjZXB0aW9uIG9jY3VyZWQgd2hpbGUKLSAgICAgKiAgIHNlcmlhbGl6aW5nCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2VyaWFsaXplKCBEb2N1bWVudCBkb2MgKQotICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb247Ci0KLQotICAgIC8qKgotICAgICAqIFNlcmlhbGl6ZXMgdGhlIERPTSBkb2N1bWVudCBmcmFnbWVudC4gVGhyb3dzIGFuIGV4Y2VwdGlvbgotICAgICAqIG9ubHkgaWYgYW4gSS9PIGV4Y2VwdGlvbiBvY2N1cmVkIHdoaWxlIHNlcmlhbGl6aW5nLgotICAgICAqCi0gICAgICogQHBhcmFtIGZyYWcgVGhlIGRvY3VtZW50IGZyYWdtZW50IHRvIHNlcmlhbGl6ZQotICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gQW4gSS9PIGV4Y2VwdGlvbiBvY2N1cmVkIHdoaWxlCi0gICAgICogICBzZXJpYWxpemluZwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNlcmlhbGl6ZSggRG9jdW1lbnRGcmFnbWVudCBmcmFnICkKLSAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uOwotCi0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZS9ET01TZXJpYWxpemVySW1wbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplL0RPTVNlcmlhbGl6ZXJJbXBsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDhmMTRkNzQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplL0RPTVNlcmlhbGl6ZXJJbXBsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMjA1ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemU7Ci0KLWltcG9ydCBqYXZhLmlvLkZpbGVPdXRwdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKLWltcG9ydCBqYXZhLmlvLlN0cmluZ1dyaXRlcjsKLWltcG9ydCBqYXZhLmlvLlVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb247Ci1pbXBvcnQgamF2YS5pby5Xcml0ZXI7Ci1pbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kOwotaW1wb3J0IGphdmEubmV0Lkh0dHBVUkxDb25uZWN0aW9uOwotaW1wb3J0IGphdmEubmV0LlVSTDsKLWltcG9ydCBqYXZhLm5ldC5VUkxDb25uZWN0aW9uOwotaW1wb3J0IGphdmEudXRpbC5TdHJpbmdUb2tlbml6ZXI7Ci1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tLkFib3J0RXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tLkNvcmVEb2N1bWVudEltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5kb20uRE9NRXJyb3JJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tLkRPTUxvY2F0b3JJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tLkRPTU1lc3NhZ2VGb3JtYXR0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5kb20uRE9NTm9ybWFsaXplcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbS5ET01TdHJpbmdMaXN0SW1wbDsKLWltcG9ydCBvcmcudzNjLmRvbS5ET01Db25maWd1cmF0aW9uOwotaW1wb3J0IG9yZy53M2MuZG9tLkRPTUVycm9yOwotaW1wb3J0IG9yZy53M2MuZG9tLkRPTUVycm9ySGFuZGxlcjsKLWltcG9ydCBvcmcudzNjLmRvbS5ET01TdHJpbmdMaXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5Db25zdGFudHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLlhNTEVudGl0eU1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLkRPTVV0aWw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLk5hbWVzcGFjZVN1cHBvcnQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlN5bWJvbFRhYmxlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5YTUwxMUNoYXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlhNTENoYXI7Ci1pbXBvcnQgb3JnLnczYy5kb20uQXR0cjsKLWltcG9ydCBvcmcudzNjLmRvbS5Db21tZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLkRPTUV4Y2VwdGlvbjsKLWltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKLWltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudEZyYWdtZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLkVsZW1lbnQ7Ci1pbXBvcnQgb3JnLnczYy5kb20uTmFtZWROb2RlTWFwOwotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci1pbXBvcnQgb3JnLnczYy5kb20uUHJvY2Vzc2luZ0luc3RydWN0aW9uOwotaW1wb3J0IG9yZy53M2MuZG9tLmxzLkxTRXhjZXB0aW9uOwotaW1wb3J0IG9yZy53M2MuZG9tLmxzLkxTT3V0cHV0OwotaW1wb3J0IG9yZy53M2MuZG9tLmxzLkxTU2VyaWFsaXplcjsKLWltcG9ydCBvcmcudzNjLmRvbS5scy5MU1NlcmlhbGl6ZXJGaWx0ZXI7Ci0KLQotLyoqCi0gKiBFWFBFUklNRU5UQUw6IEltcGxlbWVuYXRhdGlvbiBvZiBET00gTGV2ZWwgMyBvcmcudzNjLmxzLkxTU2VyaWFsaXplciAgYnkgZGVsZWdhdGluZyBzZXJpYWxpemF0aW9uCi0gKiBjYWxscyB0byA8Q09ERT5YTUxTZXJpYWxpemVyPC9DT0RFPi4KLSAqIExTU2VyaWFsaXplciBwcm92aWRlcyBhbiBBUEkgZm9yIHNlcmlhbGl6aW5nICh3cml0aW5nKSBhIERPTSBkb2N1bWVudCBvdXQgaW4gYW4KLSAqIFhNTCBkb2N1bWVudC4gVGhlIFhNTCBkYXRhIGlzIHdyaXR0ZW4gdG8gYW4gb3V0cHV0IHN0cmVhbS4KLSAqIER1cmluZyBzZXJpYWxpemF0aW9uIG9mIFhNTCBkYXRhLCBuYW1lc3BhY2UgZml4dXAgaXMgZG9uZSB3aGVuIHBvc3NpYmxlIGFzCi0gKiBkZWZpbmVkIGluIERPTSBMZXZlbCAzIENvcmUsIEFwcGVuZGl4IEIuCi0gKgotICogQGF1dGhvciBFbGVuYSBMaXRhbmksIElCTQotICogQGF1dGhvciBHb3BhbCBTaGFybWEsIFN1biBNaWNyb3N5c3RlbXMKLSAqIEBhdXRob3IgQXJ1biBZYWRhdiwgU3VuIE1pY3Jvc3lzdGVtcwotICogQGF1dGhvciBTdW5pdGhhIFJlZGR5LCBTdW4gTWljcm9zeXN0ZW1zCi0gKiBAdmVyc2lvbiAkSWQ6IERPTVNlcmlhbGl6ZXJJbXBsLmphdmEsdiAxLjExIDIwMTAtMTEtMDEgMDQ6NDA6MzYgam9laHcgRXhwICQKLSAqLwotcHVibGljIGNsYXNzIERPTVNlcmlhbGl6ZXJJbXBsIGltcGxlbWVudHMgTFNTZXJpYWxpemVyLCBET01Db25maWd1cmF0aW9uIHsKLQotICAgIC8vIFRPRE86IFdoZW4gRE9NIExldmVsIDMgZ29lcyB0byBSRUMgcmVwbGFjZSBtZXRob2QgY2FsbHMgdXNpbmcKLSAgICAvLyByZWZsZWN0aW9uIGZvcjogZ2V0WG1sRW5jb2RpbmcsIGdldElucHV0RW5jb2RpbmcgYW5kIGdldFhtbEVuY29kaW5nCi0gICAgLy8gd2l0aCByZWd1bGFyIHN0YXRpYyBjYWxscyBvbiB0aGUgRG9jdW1lbnQgb2JqZWN0LgotCi0gICAgLy8gZGF0YQotICAgIC8vIHNlcmlhbGl6ZXIKLSAgICBwcml2YXRlIFhNTFNlcmlhbGl6ZXIgc2VyaWFsaXplcjsKLQotICAgIC8vIFhNTCAxLjEgc2VyaWFsaXplcgotICAgIHByaXZhdGUgWE1MMTFTZXJpYWxpemVyIHhtbDExU2VyaWFsaXplcjsKLQotICAgIC8vUmVjb2duaXplZCBwYXJhbWV0ZXJzCi0gICAgcHJpdmF0ZSBET01TdHJpbmdMaXN0IGZSZWNvZ25pemVkUGFyYW1ldGVyczsKLQotICAgIC8qKiBSRVZJU0lUOiBDdXJyZW50bHkgd2UgaGFuZGxlIDMgZGlmZmVyZW50IGNvbmZpZ3VyYXRpb25zLCB3b3VsZCBiZSBuaWNlIGp1c3QgaGF2ZSBvbmUgY29uZmlndXJhdGlvbgotICAgICAqIHRoYXQgaGFzIGRpZmZlcmVudCByZWNvZ25pemVkIHBhcmFtZXRlcnMgZGVwZW5kaW5nIGlmIGl0IGlzIHVzZWQgaW4gQ29yZS9MUy4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgc2hvcnQgZmVhdHVyZXMgPSAwOwotCi0gICAgcHJvdGVjdGVkIGZpbmFsIHN0YXRpYyBzaG9ydCBOQU1FU1BBQ0VTICAgICAgICAgID0gMHgxPDwwOwotICAgIHByb3RlY3RlZCBmaW5hbCBzdGF0aWMgc2hvcnQgV0VMTEZPUk1FRCAgICAgICAgICA9IDB4MTw8MTsKLSAgICBwcm90ZWN0ZWQgZmluYWwgc3RhdGljIHNob3J0IEVOVElUSUVTICAgICAgICAgICAgPSAweDE8PDI7Ci0gICAgcHJvdGVjdGVkIGZpbmFsIHN0YXRpYyBzaG9ydCBDREFUQSAgICAgICAgICAgICAgID0gMHgxPDwzOwotICAgIHByb3RlY3RlZCBmaW5hbCBzdGF0aWMgc2hvcnQgU1BMSVRDREFUQSAgICAgICAgICA9IDB4MTw8NDsKLSAgICBwcm90ZWN0ZWQgZmluYWwgc3RhdGljIHNob3J0IENPTU1FTlRTICAgICAgICAgICAgPSAweDE8PDU7Ci0gICAgcHJvdGVjdGVkIGZpbmFsIHN0YXRpYyBzaG9ydCBESVNDQVJEREVGQVVMVCAgICAgID0gMHgxPDw2OwotICAgIHByb3RlY3RlZCBmaW5hbCBzdGF0aWMgc2hvcnQgSU5GT1NFVCAgICAgICAgICAgICA9IDB4MTw8NzsKLSAgICBwcm90ZWN0ZWQgZmluYWwgc3RhdGljIHNob3J0IFhNTERFQ0wgICAgICAgICAgICAgPSAweDE8PDg7Ci0gICAgcHJvdGVjdGVkIGZpbmFsIHN0YXRpYyBzaG9ydCBOU0RFQ0wgICAgICAgICAgICAgID0gMHgxPDw5OwotICAgIHByb3RlY3RlZCBmaW5hbCBzdGF0aWMgc2hvcnQgRE9NX0VMRU1FTlRfQ09OVEVOVF9XSElURVNQQUNFID0gMHgxPDwxMDsKLSAgICBwcm90ZWN0ZWQgZmluYWwgc3RhdGljIHNob3J0IEZPUk1BVF9QUkVUVFlfUFJJTlQgPSAweDE8PDExOwotCi0gICAgLy8gd2VsbC1mb3JtbmVzcyBjaGVja2luZwotICAgIHByaXZhdGUgRE9NRXJyb3JIYW5kbGVyIGZFcnJvckhhbmRsZXIgPSBudWxsOwotICAgIHByaXZhdGUgZmluYWwgRE9NRXJyb3JJbXBsIGZFcnJvciA9IG5ldyBET01FcnJvckltcGwoKTsKLSAgICBwcml2YXRlIGZpbmFsIERPTUxvY2F0b3JJbXBsIGZMb2NhdG9yID0gbmV3IERPTUxvY2F0b3JJbXBsKCk7Ci0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IExTU2VyaWFsaXplci4KLSAgICAgKiBUaGUgY29uc3RydWN0b3IgdHVybnMgb24gdGhlIG5hbWVzcGFjZSBzdXBwb3J0IGluIDxjb2RlPlhNTFNlcmlhbGl6ZXI8L2NvZGU+IGFuZAotICAgICAqIGluaXRpYWxpemVzIHRoZSBmb2xsb3dpbmcgZmllbGRzOiBmTlNCaW5kZXIsIGZMb2NhbE5TQmluZGVyLCBmU3ltYm9sVGFibGUsCi0gICAgICogZkVtcHR5U3ltYm9sLCBmWG1sU3ltYm9sLCBmWG1sbnNTeW1ib2wsIGZOYW1lc3BhY2VDb3VudGVyLCBmRmVhdHVyZXMuCi0gICAgICovCi0gICAgcHVibGljIERPTVNlcmlhbGl6ZXJJbXBsKCkgewotICAgICAgICAvLyBzZXQgZGVmYXVsdCBmZWF0dXJlcwotICAgICAgICBmZWF0dXJlcyB8PSBOQU1FU1BBQ0VTOwotICAgICAgICBmZWF0dXJlcyB8PSBFTlRJVElFUzsKLSAgICAgICAgZmVhdHVyZXMgfD0gQ09NTUVOVFM7Ci0gICAgICAgIGZlYXR1cmVzIHw9IENEQVRBOwotICAgICAgICBmZWF0dXJlcyB8PSBTUExJVENEQVRBOwotICAgICAgICBmZWF0dXJlcyB8PSBXRUxMRk9STUVEOwotICAgICAgICBmZWF0dXJlcyB8PSBOU0RFQ0w7Ci0gICAgICAgIGZlYXR1cmVzIHw9IERPTV9FTEVNRU5UX0NPTlRFTlRfV0hJVEVTUEFDRTsKLSAgICAgICAgZmVhdHVyZXMgfD0gRElTQ0FSRERFRkFVTFQ7Ci0gICAgICAgIGZlYXR1cmVzIHw9IFhNTERFQ0w7Ci0KLSAgICAgICAgc2VyaWFsaXplciA9IG5ldyBYTUxTZXJpYWxpemVyKCk7Ci0gICAgICAgIGluaXRTZXJpYWxpemVyKHNlcmlhbGl6ZXIpOwotICAgIH0KLQotCi0KLSAgICAvLwotICAgIC8vIExTU2VyaWFsaXplciBtZXRob2RzCi0gICAgLy8KLQotICAgIHB1YmxpYyBET01Db25maWd1cmF0aW9uIGdldERvbUNvbmZpZygpewotICAgICAgICByZXR1cm4gdGhpczsKLSAgICB9Ci0KLSAgICAvKiogRE9NIEwzLUVYUEVSSU1FTlRBTDoKLSAgICAgKiBTZXR0ZXIgZm9yIGJvb2xlYW4gYW5kIG9iamVjdCBwYXJhbWV0ZXJzCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0UGFyYW1ldGVyKFN0cmluZyBuYW1lLCBPYmplY3QgdmFsdWUpIHRocm93cyBET01FeGNlcHRpb24gewotICAgICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBCb29sZWFuKSB7Ci0gICAgICAgICAgICBib29sZWFuIHN0YXRlID0gKChCb29sZWFuKSB2YWx1ZSkuYm9vbGVhblZhbHVlKCk7Ci0gICAgICAgICAgICBpZiAobmFtZS5lcXVhbHNJZ25vcmVDYXNlKENvbnN0YW50cy5ET01fSU5GT1NFVCkpewotICAgICAgICAgICAgICAgIGlmIChzdGF0ZSl7Ci0gICAgICAgICAgICAgICAgICAgIGZlYXR1cmVzICY9IH5FTlRJVElFUzsKLSAgICAgICAgICAgICAgICAgICAgZmVhdHVyZXMgJj0gfkNEQVRBOwotICAgICAgICAgICAgICAgICAgICBmZWF0dXJlcyB8PSBOQU1FU1BBQ0VTOwotICAgICAgICAgICAgICAgICAgICBmZWF0dXJlcyB8PSBOU0RFQ0w7Ci0gICAgICAgICAgICAgICAgICAgIGZlYXR1cmVzIHw9IFdFTExGT1JNRUQ7Ci0gICAgICAgICAgICAgICAgICAgIGZlYXR1cmVzIHw9IENPTU1FTlRTOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvLyBmYWxzZSBkb2VzIG5vdCBoYXZlIGFueSBlZmZlY3QKLSAgICAgICAgICAgIH0gZWxzZSBpZiAobmFtZS5lcXVhbHNJZ25vcmVDYXNlKENvbnN0YW50cy5ET01fWE1MREVDTCkpIHsKLSAgICAgICAgICAgICAgICBmZWF0dXJlcyA9Ci0gICAgICAgICAgICAgICAgICAgIChzaG9ydCkgKHN0YXRlID8gZmVhdHVyZXMgfCBYTUxERUNMIDogZmVhdHVyZXMgJiB+WE1MREVDTCk7Ci0gICAgICAgICAgICB9IGVsc2UgaWYgKG5hbWUuZXF1YWxzSWdub3JlQ2FzZShDb25zdGFudHMuRE9NX05BTUVTUEFDRVMpKSB7Ci0gICAgICAgICAgICAgICAgZmVhdHVyZXMgPQotICAgICAgICAgICAgICAgICAgICAoc2hvcnQpIChzdGF0ZQotICAgICAgICAgICAgICAgICAgICAgICAgPyBmZWF0dXJlcyB8IE5BTUVTUEFDRVMKLSAgICAgICAgICAgICAgICAgICAgICAgIDogZmVhdHVyZXMgJiB+TkFNRVNQQUNFUyk7Ci0gICAgICAgICAgICAgICAgc2VyaWFsaXplci5mTmFtZXNwYWNlcyA9IHN0YXRlOwotICAgICAgICAgICAgfSBlbHNlIGlmIChuYW1lLmVxdWFsc0lnbm9yZUNhc2UoQ29uc3RhbnRzLkRPTV9TUExJVF9DREFUQSkpIHsKLSAgICAgICAgICAgICAgICBmZWF0dXJlcyA9Ci0gICAgICAgICAgICAgICAgICAgIChzaG9ydCkgKHN0YXRlCi0gICAgICAgICAgICAgICAgICAgICAgICA/IGZlYXR1cmVzIHwgU1BMSVRDREFUQQotICAgICAgICAgICAgICAgICAgICAgICAgOiBmZWF0dXJlcyAmIH5TUExJVENEQVRBKTsKLSAgICAgICAgICAgIH0gZWxzZSBpZiAobmFtZS5lcXVhbHNJZ25vcmVDYXNlKENvbnN0YW50cy5ET01fRElTQ0FSRF9ERUZBVUxUX0NPTlRFTlQpKSB7Ci0gICAgICAgICAgICAgICAgZmVhdHVyZXMgPQotICAgICAgICAgICAgICAgICAgICAoc2hvcnQpIChzdGF0ZQotICAgICAgICAgICAgICAgICAgICAgICAgPyBmZWF0dXJlcyB8IERJU0NBUkRERUZBVUxUCi0gICAgICAgICAgICAgICAgICAgICAgICA6IGZlYXR1cmVzICYgfkRJU0NBUkRERUZBVUxUKTsKLSAgICAgICAgICAgIH0gZWxzZSBpZiAobmFtZS5lcXVhbHNJZ25vcmVDYXNlKENvbnN0YW50cy5ET01fV0VMTEZPUk1FRCkpIHsKLSAgICAgICAgICAgICAgICBmZWF0dXJlcyA9Ci0gICAgICAgICAgICAgICAgICAgIChzaG9ydCkgKHN0YXRlCi0gICAgICAgICAgICAgICAgICAgICAgICA/IGZlYXR1cmVzIHwgV0VMTEZPUk1FRAotICAgICAgICAgICAgICAgICAgICAgICAgOiBmZWF0dXJlcyAmIH5XRUxMRk9STUVEKTsKLSAgICAgICAgICAgIH0gZWxzZSBpZiAobmFtZS5lcXVhbHNJZ25vcmVDYXNlKENvbnN0YW50cy5ET01fRU5USVRJRVMpKXsKLSAgICAgICAgICAgICAgICBmZWF0dXJlcyA9Ci0gICAgICAgICAgICAgICAgICAgIChzaG9ydCkgKHN0YXRlCi0gICAgICAgICAgICAgICAgICAgICAgICA/IGZlYXR1cmVzIHwgRU5USVRJRVMKLSAgICAgICAgICAgICAgICAgICAgICAgIDogZmVhdHVyZXMgJiB+RU5USVRJRVMpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAobmFtZS5lcXVhbHNJZ25vcmVDYXNlKENvbnN0YW50cy5ET01fQ0RBVEFfU0VDVElPTlMpKXsKLSAgICAgICAgICAgICAgICBmZWF0dXJlcyA9Ci0gICAgICAgICAgICAgICAgICAgIChzaG9ydCkgKHN0YXRlCi0gICAgICAgICAgICAgICAgICAgICAgICA/IGZlYXR1cmVzIHwgQ0RBVEEKLSAgICAgICAgICAgICAgICAgICAgICAgIDogZmVhdHVyZXMgJiB+Q0RBVEEpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAobmFtZS5lcXVhbHNJZ25vcmVDYXNlKENvbnN0YW50cy5ET01fQ09NTUVOVFMpKXsKLSAgICAgICAgICAgICAgICBmZWF0dXJlcyA9Ci0gICAgICAgICAgICAgICAgICAgICAoc2hvcnQpIChzdGF0ZQotICAgICAgICAgICAgICAgICAgICAgICAgID8gZmVhdHVyZXMgfCBDT01NRU5UUwotICAgICAgICAgICAgICAgICAgICAgICAgIDogZmVhdHVyZXMgJiB+Q09NTUVOVFMpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAobmFtZS5lcXVhbHNJZ25vcmVDYXNlKENvbnN0YW50cy5ET01fRk9STUFUX1BSRVRUWV9QUklOVCkpewotICAgICAgICAgICAgICAgIGZlYXR1cmVzID0KLSAgICAgICAgICAgICAgICAgICAgIChzaG9ydCkgKHN0YXRlCi0gICAgICAgICAgICAgICAgICAgICAgICAgPyBmZWF0dXJlcyB8IEZPUk1BVF9QUkVUVFlfUFJJTlQKLSAgICAgICAgICAgICAgICAgICAgICAgICA6IGZlYXR1cmVzICYgfkZPUk1BVF9QUkVUVFlfUFJJTlQpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzSWdub3JlQ2FzZShDb25zdGFudHMuRE9NX0NBTk9OSUNBTF9GT1JNKQotICAgICAgICAgICAgICAgICAgICB8fCBuYW1lLmVxdWFsc0lnbm9yZUNhc2UoQ29uc3RhbnRzLkRPTV9WQUxJREFURV9JRl9TQ0hFTUEpCi0gICAgICAgICAgICAgICAgICAgIHx8IG5hbWUuZXF1YWxzSWdub3JlQ2FzZShDb25zdGFudHMuRE9NX1ZBTElEQVRFKQotICAgICAgICAgICAgICAgICAgICB8fCBuYW1lLmVxdWFsc0lnbm9yZUNhc2UoQ29uc3RhbnRzLkRPTV9DSEVDS19DSEFSX05PUk1BTElaQVRJT04pCi0gICAgICAgICAgICAgICAgICAgIHx8IG5hbWUuZXF1YWxzSWdub3JlQ2FzZShDb25zdGFudHMuRE9NX0RBVEFUWVBFX05PUk1BTElaQVRJT04pKSB7Ci0gICAgICAgICAgICAgICAgLy8gIHx8IG5hbWUuZXF1YWxzSWdub3JlQ2FzZShDb25zdGFudHMuRE9NX05PUk1BTElaRV9DSEFSQUNURVJTKSkgewotICAgICAgICAgICAgICAgIC8vIHRydWUgaXMgbm90IHN1cHBvcnRlZAotICAgICAgICAgICAgICAgIGlmIChzdGF0ZSkgewotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbXNnID0KLSAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZSgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIkZFQVRVUkVfTk9UX1NVUFBPUlRFRCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgbmFtZSB9KTsKLSAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIsIG1zZyk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfWVsc2UgaWYgKAotICAgICAgICAgICAgICAgICAgICAgICAgbmFtZS5lcXVhbHNJZ25vcmVDYXNlKENvbnN0YW50cy5ET01fTkFNRVNQQUNFX0RFQ0xBUkFUSU9OUykpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9uYW1lc3BhY2UtZGVjbGFyYXRpb24gaGFzIGVmZmVjdCBvbmx5IGlmIG5hbWVzcGFjZXMgaXMgdHJ1ZQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmZWF0dXJlcyA9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHNob3J0KSAoc3RhdGUKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gZmVhdHVyZXMgfCBOU0RFQ0wKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogZmVhdHVyZXMgJiB+TlNERUNMKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VyaWFsaXplci5mTmFtZXNwYWNlUHJlZml4ZXMgPSBzdGF0ZTsKLSAgICAgICAgICAgIH0gZWxzZSBpZiAobmFtZS5lcXVhbHNJZ25vcmVDYXNlKENvbnN0YW50cy5ET01fRUxFTUVOVF9DT05URU5UX1dISVRFU1BBQ0UpCi0gICAgICAgICAgICAgICAgICAgIHx8IG5hbWUuZXF1YWxzSWdub3JlQ2FzZShDb25zdGFudHMuRE9NX0lHTk9SRV9VTktOT1dOX0NIQVJBQ1RFUl9ERU5PUk1BTElaQVRJT05TKSkgewotICAgICAgICAgICAgICAgIC8vIGZhbHNlIGlzIG5vdCBzdXBwb3J0ZWQKLSAgICAgICAgICAgICAgICBpZiAoIXN0YXRlKSB7Ci0gICAgICAgICAgICAgICAgICAgIFN0cmluZyBtc2cgPQotICAgICAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRkVBVFVSRV9OT1RfU1VQUE9SVEVEIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBuYW1lIH0pOwotICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUiwgbXNnKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIFN0cmluZyBtc2cgPQotICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoCi0gICAgICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAiRkVBVFVSRV9OT1RfRk9VTkQiLAotICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgbmFtZSB9KTsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUiwgbXNnKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSBlbHNlIGlmIChuYW1lLmVxdWFsc0lnbm9yZUNhc2UoQ29uc3RhbnRzLkRPTV9FUlJPUl9IQU5ETEVSKSkgewotICAgICAgICAgICAgaWYgKHZhbHVlID09IG51bGwgfHwgdmFsdWUgaW5zdGFuY2VvZiBET01FcnJvckhhbmRsZXIpIHsKLSAgICAgICAgICAgICAgICBmRXJyb3JIYW5kbGVyID0gKERPTUVycm9ySGFuZGxlcil2YWx1ZTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIG1zZyA9Ci0gICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZSgKLSAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICJUWVBFX01JU01BVENIX0VSUiIsCi0gICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBuYW1lIH0pOwotICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLlRZUEVfTUlTTUFUQ0hfRVJSLCBtc2cpOwotICAgICAgICAgICAgfQotICAgICAgICB9IGVsc2UgaWYgKAotICAgICAgICAgICAgbmFtZS5lcXVhbHNJZ25vcmVDYXNlKENvbnN0YW50cy5ET01fUkVTT1VSQ0VfUkVTT0xWRVIpCi0gICAgICAgICAgICAgICAgfHwgbmFtZS5lcXVhbHNJZ25vcmVDYXNlKENvbnN0YW50cy5ET01fU0NIRU1BX0xPQ0FUSU9OKQotICAgICAgICAgICAgICAgIHx8IG5hbWUuZXF1YWxzSWdub3JlQ2FzZShDb25zdGFudHMuRE9NX1NDSEVNQV9UWVBFKQotICAgICAgICAgICAgICAgIHx8IG5hbWUuZXF1YWxzSWdub3JlQ2FzZShDb25zdGFudHMuRE9NX05PUk1BTElaRV9DSEFSQUNURVJTKQotICAgICAgICAgICAgICAgICYmIHZhbHVlICE9IG51bGwpIHsKLSAgICAgICAgICAgIFN0cmluZyBtc2cgPQotICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZSgKLSAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAiRkVBVFVSRV9OT1RfU1VQUE9SVEVEIiwKLSAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgbmFtZSB9KTsKLSAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSLCBtc2cpOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgU3RyaW5nIG1zZyA9Ci0gICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKAotICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICJGRUFUVVJFX05PVF9GT1VORCIsCi0gICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7IG5hbWUgfSk7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfRk9VTkRfRVJSLCBtc2cpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqIERPTSBMMy1FWFBFUklNRU5UQUw6Ci0gICAgICogQ2hlY2sgaWYgcGFyYW1ldGVyIGNhbiBiZSBzZXQKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBjYW5TZXRQYXJhbWV0ZXIoU3RyaW5nIG5hbWUsIE9iamVjdCBzdGF0ZSkgewotCi0gICAgICAgIGlmIChzdGF0ZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChzdGF0ZSBpbnN0YW5jZW9mIEJvb2xlYW4pIHsKLSAgICAgICAgICAgIGJvb2xlYW4gdmFsdWUgPSAoKEJvb2xlYW4pIHN0YXRlKS5ib29sZWFuVmFsdWUoKTsKLQotICAgICAgICAgICAgaWYgKG5hbWUuZXF1YWxzSWdub3JlQ2FzZShDb25zdGFudHMuRE9NX05BTUVTUEFDRVMpCi0gICAgICAgICAgICAgICAgfHwgbmFtZS5lcXVhbHNJZ25vcmVDYXNlKENvbnN0YW50cy5ET01fU1BMSVRfQ0RBVEEpCi0gICAgICAgICAgICAgICAgfHwgbmFtZS5lcXVhbHNJZ25vcmVDYXNlKENvbnN0YW50cy5ET01fRElTQ0FSRF9ERUZBVUxUX0NPTlRFTlQpCi0gICAgICAgICAgICAgICAgfHwgbmFtZS5lcXVhbHNJZ25vcmVDYXNlKENvbnN0YW50cy5ET01fWE1MREVDTCkKLSAgICAgICAgICAgICAgICB8fCBuYW1lLmVxdWFsc0lnbm9yZUNhc2UoQ29uc3RhbnRzLkRPTV9XRUxMRk9STUVEKQotICAgICAgICAgICAgICAgIHx8IG5hbWUuZXF1YWxzSWdub3JlQ2FzZShDb25zdGFudHMuRE9NX0lORk9TRVQpCi0gICAgICAgICAgICAgICAgfHwgbmFtZS5lcXVhbHNJZ25vcmVDYXNlKENvbnN0YW50cy5ET01fRU5USVRJRVMpCi0gICAgICAgICAgICAgICAgfHwgbmFtZS5lcXVhbHNJZ25vcmVDYXNlKENvbnN0YW50cy5ET01fQ0RBVEFfU0VDVElPTlMpCi0gICAgICAgICAgICAgICAgfHwgbmFtZS5lcXVhbHNJZ25vcmVDYXNlKENvbnN0YW50cy5ET01fQ09NTUVOVFMpCi0gICAgICAgICAgICAgICAgfHwgbmFtZS5lcXVhbHNJZ25vcmVDYXNlKENvbnN0YW50cy5ET01fTkFNRVNQQUNFX0RFQ0xBUkFUSU9OUykKLSAgICAgICAgICAgICAgICB8fCBuYW1lLmVxdWFsc0lnbm9yZUNhc2UoQ29uc3RhbnRzLkRPTV9GT1JNQVRfUFJFVFRZX1BSSU5UKSkgewotICAgICAgICAgICAgICAgIC8vIGJvdGggdmFsdWVzIHN1cHBvcnRlZAotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgfSBlbHNlIGlmIChuYW1lLmVxdWFsc0lnbm9yZUNhc2UoQ29uc3RhbnRzLkRPTV9DQU5PTklDQUxfRk9STSkKLSAgICAgICAgICAgICAgICB8fCBuYW1lLmVxdWFsc0lnbm9yZUNhc2UoQ29uc3RhbnRzLkRPTV9WQUxJREFURV9JRl9TQ0hFTUEpCi0gICAgICAgICAgICAgICAgfHwgbmFtZS5lcXVhbHNJZ25vcmVDYXNlKENvbnN0YW50cy5ET01fVkFMSURBVEUpCi0gICAgICAgICAgICAgICAgfHwgbmFtZS5lcXVhbHNJZ25vcmVDYXNlKENvbnN0YW50cy5ET01fQ0hFQ0tfQ0hBUl9OT1JNQUxJWkFUSU9OKQotICAgICAgICAgICAgICAgIHx8IG5hbWUuZXF1YWxzSWdub3JlQ2FzZShDb25zdGFudHMuRE9NX0RBVEFUWVBFX05PUk1BTElaQVRJT04pKSB7Ci0gICAgICAgICAgICAgICAgLy8gfHwgbmFtZS5lcXVhbHNJZ25vcmVDYXNlKENvbnN0YW50cy5ET01fTk9STUFMSVpFX0NIQVJBQ1RFUlMpKSB7Ci0gICAgICAgICAgICAgICAgLy8gdHJ1ZSBpcyBub3Qgc3VwcG9ydGVkCi0gICAgICAgICAgICAgICAgcmV0dXJuICF2YWx1ZTsKLSAgICAgICAgICAgIH0gZWxzZSBpZiAobmFtZS5lcXVhbHNJZ25vcmVDYXNlKENvbnN0YW50cy5ET01fRUxFTUVOVF9DT05URU5UX1dISVRFU1BBQ0UpCi0gICAgICAgICAgICAgICAgfHwgbmFtZS5lcXVhbHNJZ25vcmVDYXNlKENvbnN0YW50cy5ET01fSUdOT1JFX1VOS05PV05fQ0hBUkFDVEVSX0RFTk9STUFMSVpBVElPTlMpKSB7Ci0gICAgICAgICAgICAgICAgLy8gZmFsc2UgaXMgbm90IHN1cHBvcnRlZAotICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSBlbHNlIGlmIChuYW1lLmVxdWFsc0lnbm9yZUNhc2UoQ29uc3RhbnRzLkRPTV9FUlJPUl9IQU5ETEVSKSAmJgotICAgICAgICAgICAgc3RhdGUgPT0gbnVsbCB8fCBzdGF0ZSBpbnN0YW5jZW9mIERPTUVycm9ySGFuZGxlcikgewotICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogIERPTSBMZXZlbCAzIENvcmUgQ1IgLSBFeHBlcmltZW50YWwuCi0gICAgICoKLSAgICAgKiAgVGhlIGxpc3Qgb2YgdGhlIHBhcmFtZXRlcnMgc3VwcG9ydGVkIGJ5IHRoaXMKLSAgICAgKiA8Y29kZT5ET01Db25maWd1cmF0aW9uPC9jb2RlPiBvYmplY3QgYW5kIGZvciB3aGljaCBhdCBsZWFzdCBvbmUgdmFsdWUKLSAgICAgKiBjYW4gYmUgc2V0IGJ5IHRoZSBhcHBsaWNhdGlvbi4gTm90ZSB0aGF0IHRoaXMgbGlzdCBjYW4gYWxzbyBjb250YWluCi0gICAgICogcGFyYW1ldGVyIG5hbWVzIGRlZmluZWQgb3V0c2lkZSB0aGlzIHNwZWNpZmljYXRpb24uCi0gICAgICovCi0gICAgcHVibGljIERPTVN0cmluZ0xpc3QgZ2V0UGFyYW1ldGVyTmFtZXMoKSB7Ci0KLSAgICAgICAgaWYgKGZSZWNvZ25pemVkUGFyYW1ldGVycyA9PSBudWxsKXsKLSAgICAgICAgICAgICAgICAgICAgICAgIFZlY3RvciBwYXJhbWV0ZXJzID0gbmV3IFZlY3RvcigpOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAvL0FkZCBET00gcmVjb2duaXplZCBwYXJhbWV0ZXJzCi0gICAgICAgICAgICAgICAgICAgICAgICAvL1JFVklTSVQ6IFdvdWxkIGhhdmUgYmVlbiBuaWNlIHRvIGhhdmUgYSBsaXN0IG9mCi0gICAgICAgICAgICAgICAgICAgICAgICAvL3JlY29nbml6ZWQgcGFyYW1ldGVycy4KLSAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtZXRlcnMuYWRkKENvbnN0YW50cy5ET01fTkFNRVNQQUNFUyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBwYXJhbWV0ZXJzLmFkZChDb25zdGFudHMuRE9NX1NQTElUX0NEQVRBKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtZXRlcnMuYWRkKENvbnN0YW50cy5ET01fRElTQ0FSRF9ERUZBVUxUX0NPTlRFTlQpOwotICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1ldGVycy5hZGQoQ29uc3RhbnRzLkRPTV9YTUxERUNMKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtZXRlcnMuYWRkKENvbnN0YW50cy5ET01fQ0FOT05JQ0FMX0ZPUk0pOwotICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1ldGVycy5hZGQoQ29uc3RhbnRzLkRPTV9WQUxJREFURV9JRl9TQ0hFTUEpOwotICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1ldGVycy5hZGQoQ29uc3RhbnRzLkRPTV9WQUxJREFURSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBwYXJhbWV0ZXJzLmFkZChDb25zdGFudHMuRE9NX0NIRUNLX0NIQVJfTk9STUFMSVpBVElPTik7Ci0gICAgICAgICAgICAgICAgICAgICAgICBwYXJhbWV0ZXJzLmFkZChDb25zdGFudHMuRE9NX0RBVEFUWVBFX05PUk1BTElaQVRJT04pOwotICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1ldGVycy5hZGQoQ29uc3RhbnRzLkRPTV9GT1JNQVRfUFJFVFRZX1BSSU5UKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vcGFyYW1ldGVycy5hZGQoQ29uc3RhbnRzLkRPTV9OT1JNQUxJWkVfQ0hBUkFDVEVSUyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBwYXJhbWV0ZXJzLmFkZChDb25zdGFudHMuRE9NX1dFTExGT1JNRUQpOwotICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1ldGVycy5hZGQoQ29uc3RhbnRzLkRPTV9JTkZPU0VUKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtZXRlcnMuYWRkKENvbnN0YW50cy5ET01fTkFNRVNQQUNFX0RFQ0xBUkFUSU9OUyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBwYXJhbWV0ZXJzLmFkZChDb25zdGFudHMuRE9NX0VMRU1FTlRfQ09OVEVOVF9XSElURVNQQUNFKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtZXRlcnMuYWRkKENvbnN0YW50cy5ET01fRU5USVRJRVMpOwotICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1ldGVycy5hZGQoQ29uc3RhbnRzLkRPTV9DREFUQV9TRUNUSU9OUyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBwYXJhbWV0ZXJzLmFkZChDb25zdGFudHMuRE9NX0NPTU1FTlRTKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtZXRlcnMuYWRkKENvbnN0YW50cy5ET01fSUdOT1JFX1VOS05PV05fQ0hBUkFDVEVSX0RFTk9STUFMSVpBVElPTlMpOwotICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1ldGVycy5hZGQoQ29uc3RhbnRzLkRPTV9FUlJPUl9IQU5ETEVSKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vcGFyYW1ldGVycy5hZGQoQ29uc3RhbnRzLkRPTV9TQ0hFTUFfTE9DQVRJT04pOwotICAgICAgICAgICAgICAgICAgICAgICAgLy9wYXJhbWV0ZXJzLmFkZChDb25zdGFudHMuRE9NX1NDSEVNQV9UWVBFKTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgLy9BZGQgcmVjb2duaXplZCB4ZXJjZXMgZmVhdHVyZXMgYW5kIHByb3BlcnRpZXMKLQotICAgICAgICAgICAgICAgICAgICAgICAgZlJlY29nbml6ZWRQYXJhbWV0ZXJzID0gbmV3IERPTVN0cmluZ0xpc3RJbXBsKHBhcmFtZXRlcnMpOwotCi0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gZlJlY29nbml6ZWRQYXJhbWV0ZXJzOwotICAgIH0KLQotICAgIC8qKiBET00gTDMtRVhQRVJJTUVOVEFMOgotICAgICAqIEdldHRlciBmb3IgYm9vbGVhbiBhbmQgb2JqZWN0IHBhcmFtZXRlcnMKLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0IGdldFBhcmFtZXRlcihTdHJpbmcgbmFtZSkgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgaWYobmFtZS5lcXVhbHNJZ25vcmVDYXNlKENvbnN0YW50cy5ET01fTk9STUFMSVpFX0NIQVJBQ1RFUlMpKXsKLSAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfSBlbHNlIGlmIChuYW1lLmVxdWFsc0lnbm9yZUNhc2UoQ29uc3RhbnRzLkRPTV9DT01NRU5UUykpIHsKLSAgICAgICAgICAgIHJldHVybiAoKGZlYXR1cmVzICYgQ09NTUVOVFMpICE9IDApID8gQm9vbGVhbi5UUlVFIDogQm9vbGVhbi5GQUxTRTsKLSAgICAgICAgfSBlbHNlIGlmIChuYW1lLmVxdWFsc0lnbm9yZUNhc2UoQ29uc3RhbnRzLkRPTV9OQU1FU1BBQ0VTKSkgewotICAgICAgICAgICAgcmV0dXJuIChmZWF0dXJlcyAmIE5BTUVTUEFDRVMpICE9IDAgPyBCb29sZWFuLlRSVUUgOiBCb29sZWFuLkZBTFNFOwotICAgICAgICB9IGVsc2UgaWYgKG5hbWUuZXF1YWxzSWdub3JlQ2FzZShDb25zdGFudHMuRE9NX1hNTERFQ0wpKSB7Ci0gICAgICAgICAgICByZXR1cm4gKGZlYXR1cmVzICYgWE1MREVDTCkgIT0gMCA/IEJvb2xlYW4uVFJVRSA6IEJvb2xlYW4uRkFMU0U7Ci0gICAgICAgIH0gZWxzZSBpZiAobmFtZS5lcXVhbHNJZ25vcmVDYXNlKENvbnN0YW50cy5ET01fQ0RBVEFfU0VDVElPTlMpKSB7Ci0gICAgICAgICAgICByZXR1cm4gKGZlYXR1cmVzICYgQ0RBVEEpICE9IDAgPyBCb29sZWFuLlRSVUUgOiBCb29sZWFuLkZBTFNFOwotICAgICAgICB9IGVsc2UgaWYgKG5hbWUuZXF1YWxzSWdub3JlQ2FzZShDb25zdGFudHMuRE9NX0VOVElUSUVTKSkgewotICAgICAgICAgICAgcmV0dXJuIChmZWF0dXJlcyAmIEVOVElUSUVTKSAhPSAwID8gQm9vbGVhbi5UUlVFIDogQm9vbGVhbi5GQUxTRTsKLSAgICAgICAgfSBlbHNlIGlmIChuYW1lLmVxdWFsc0lnbm9yZUNhc2UoQ29uc3RhbnRzLkRPTV9TUExJVF9DREFUQSkpIHsKLSAgICAgICAgICAgIHJldHVybiAoZmVhdHVyZXMgJiBTUExJVENEQVRBKSAhPSAwID8gQm9vbGVhbi5UUlVFIDogQm9vbGVhbi5GQUxTRTsKLSAgICAgICAgfSBlbHNlIGlmIChuYW1lLmVxdWFsc0lnbm9yZUNhc2UoQ29uc3RhbnRzLkRPTV9XRUxMRk9STUVEKSkgewotICAgICAgICAgICAgcmV0dXJuIChmZWF0dXJlcyAmIFdFTExGT1JNRUQpICE9IDAgPyBCb29sZWFuLlRSVUUgOiBCb29sZWFuLkZBTFNFOwotICAgICAgICB9IGVsc2UgaWYgKG5hbWUuZXF1YWxzSWdub3JlQ2FzZShDb25zdGFudHMuRE9NX05BTUVTUEFDRV9ERUNMQVJBVElPTlMpKSB7Ci0gICAgICAgICAgICByZXR1cm4gKGZlYXR1cmVzICYgTlNERUNMKSAhPSAwID8gQm9vbGVhbi5UUlVFIDogQm9vbGVhbi5GQUxTRTsKLSAgICAgICAgfSBlbHNlIGlmIChuYW1lLmVxdWFsc0lnbm9yZUNhc2UoQ29uc3RhbnRzLkRPTV9GT1JNQVRfUFJFVFRZX1BSSU5UKSkgewotICAgICAgICAgICAgcmV0dXJuIChmZWF0dXJlcyAmIEZPUk1BVF9QUkVUVFlfUFJJTlQpICE9IDAgPyBCb29sZWFuLlRSVUUgOiBCb29sZWFuLkZBTFNFOwotICAgICAgICB9IGVsc2UgaWYgKG5hbWUuZXF1YWxzSWdub3JlQ2FzZShDb25zdGFudHMuRE9NX0VMRU1FTlRfQ09OVEVOVF9XSElURVNQQUNFKSB8fAotICAgICAgICAgICAgICAgICAgIG5hbWUuZXF1YWxzSWdub3JlQ2FzZShDb25zdGFudHMuRE9NX0lHTk9SRV9VTktOT1dOX0NIQVJBQ1RFUl9ERU5PUk1BTElaQVRJT05TKSkgewotICAgICAgICAgICAgcmV0dXJuIEJvb2xlYW4uVFJVRTsKLSAgICAgICAgfWVsc2UgaWYgKG5hbWUuZXF1YWxzSWdub3JlQ2FzZShDb25zdGFudHMuRE9NX0RJU0NBUkRfREVGQVVMVF9DT05URU5UKSl7Ci0gICAgICAgICAgICByZXR1cm4gKChmZWF0dXJlcyAmIERJU0NBUkRERUZBVUxUKSE9MCk/Qm9vbGVhbi5UUlVFOkJvb2xlYW4uRkFMU0U7Ci0gICAgICAgIH1lbHNlIGlmIChuYW1lLmVxdWFsc0lnbm9yZUNhc2UoQ29uc3RhbnRzLkRPTV9JTkZPU0VUKSl7Ci0gICAgICAgICAgICBpZiAoKGZlYXR1cmVzICYgRU5USVRJRVMpID09IDAgJiYKLSAgICAgICAgICAgICAgICAgKGZlYXR1cmVzICYgQ0RBVEEpID09IDAgJiYKLSAgICAgICAgICAgICAgICAgKGZlYXR1cmVzICYgTkFNRVNQQUNFUykgIT0gMCAmJgotICAgICAgICAgICAgICAgICAoZmVhdHVyZXMgJiBOU0RFQ0wpICE9IDAgJiYKLSAgICAgICAgICAgICAgICAgKGZlYXR1cmVzICYgV0VMTEZPUk1FRCkgIT0gMCAmJgotICAgICAgICAgICAgICAgICAoZmVhdHVyZXMgJiBDT01NRU5UUykgIT0gMCkgewotICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEJvb2xlYW4uVFJVRTsKLSAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICByZXR1cm4gQm9vbGVhbi5GQUxTRTsKLSAgICAgICAgfSBlbHNlIGlmIChuYW1lLmVxdWFsc0lnbm9yZUNhc2UoQ29uc3RhbnRzLkRPTV9DQU5PTklDQUxfRk9STSkKLSAgICAgICAgICAgICAgICB8fCBuYW1lLmVxdWFsc0lnbm9yZUNhc2UoQ29uc3RhbnRzLkRPTV9WQUxJREFURV9JRl9TQ0hFTUEpCi0gICAgICAgICAgICAgICAgfHwgbmFtZS5lcXVhbHNJZ25vcmVDYXNlKENvbnN0YW50cy5ET01fQ0hFQ0tfQ0hBUl9OT1JNQUxJWkFUSU9OKQotICAgICAgICAgICAgICAgIHx8IG5hbWUuZXF1YWxzSWdub3JlQ2FzZShDb25zdGFudHMuRE9NX1ZBTElEQVRFKQotICAgICAgICAgICAgICAgIHx8IG5hbWUuZXF1YWxzSWdub3JlQ2FzZShDb25zdGFudHMuRE9NX1ZBTElEQVRFX0lGX1NDSEVNQSkKLSAgICAgICAgICAgICAgICB8fCBuYW1lLmVxdWFsc0lnbm9yZUNhc2UoQ29uc3RhbnRzLkRPTV9EQVRBVFlQRV9OT1JNQUxJWkFUSU9OKSkgewotICAgICAgICAgICAgcmV0dXJuIEJvb2xlYW4uRkFMU0U7Ci0gICAgICAgIH0gZWxzZSBpZiAobmFtZS5lcXVhbHNJZ25vcmVDYXNlKENvbnN0YW50cy5ET01fRVJST1JfSEFORExFUikpIHsKLSAgICAgICAgICAgIHJldHVybiBmRXJyb3JIYW5kbGVyOwotICAgICAgICB9IGVsc2UgaWYgKAotICAgICAgICAgICAgbmFtZS5lcXVhbHNJZ25vcmVDYXNlKENvbnN0YW50cy5ET01fUkVTT1VSQ0VfUkVTT0xWRVIpCi0gICAgICAgICAgICAgICAgfHwgbmFtZS5lcXVhbHNJZ25vcmVDYXNlKENvbnN0YW50cy5ET01fU0NIRU1BX0xPQ0FUSU9OKQotICAgICAgICAgICAgICAgIHx8IG5hbWUuZXF1YWxzSWdub3JlQ2FzZShDb25zdGFudHMuRE9NX1NDSEVNQV9UWVBFKSkgewotICAgICAgICAgICAgU3RyaW5nIG1zZyA9Ci0gICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKAotICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICJGRUFUVVJFX05PVF9TVVBQT1JURUQiLAotICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBuYW1lIH0pOwotICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIsIG1zZyk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBTdHJpbmcgbXNnID0KLSAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoCi0gICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuRE9NX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgIkZFQVRVUkVfTk9UX0ZPVU5EIiwKLSAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgbmFtZSB9KTsKLSAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9GT1VORF9FUlIsIG1zZyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIERPTSBMMyBFWFBFUklNRU5UQUw6Ci0gICAgICogIFNlcmlhbGl6ZSB0aGUgc3BlY2lmaWVkIG5vZGUgYXMgZGVzY3JpYmVkIGFib3ZlIGluIHRoZSBkZXNjcmlwdGlvbiBvZgotICAgICAqIDxjb2RlPkxTU2VyaWFsaXplcjwvY29kZT4uIFRoZSByZXN1bHQgb2Ygc2VyaWFsaXppbmcgdGhlIG5vZGUgaXMKLSAgICAgKiByZXR1cm5lZCBhcyBhIHN0cmluZy4gV3JpdGluZyBhIERvY3VtZW50IG9yIEVudGl0eSBub2RlIHByb2R1Y2VzIGEKLSAgICAgKiBzZXJpYWxpemVkIGZvcm0gdGhhdCBpcyB3ZWxsIGZvcm1lZCBYTUwuIFdyaXRpbmcgb3RoZXIgbm9kZSB0eXBlcwotICAgICAqIHByb2R1Y2VzIGEgZnJhZ21lbnQgb2YgdGV4dCBpbiBhIGZvcm0gdGhhdCBpcyBub3QgZnVsbHkgZGVmaW5lZCBieQotICAgICAqIHRoaXMgZG9jdW1lbnQsIGJ1dCB0aGF0IHNob3VsZCBiZSB1c2VmdWwgdG8gYSBodW1hbiBmb3IgZGVidWdnaW5nIG9yCi0gICAgICogZGlhZ25vc3RpYyBwdXJwb3Nlcy4KLSAgICAgKiBAcGFyYW0gd25vZGUgIFRoZSBub2RlIHRvIGJlIHdyaXR0ZW4uCi0gICAgICogQHJldHVybiAgUmV0dXJucyB0aGUgc2VyaWFsaXplZCBkYXRhCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgICBET01TVFJJTkdfU0laRV9FUlI6IFRoZSByZXN1bHRpbmcgc3RyaW5nIGlzIHRvbyBsb25nIHRvIGZpdCBpbiBhCi0gICAgICogICA8Y29kZT5ET01TdHJpbmc8L2NvZGU+LgotICAgICAqIEBleGNlcHRpb24gTFNFeGNlcHRpb24KLSAgICAgKiAgICBTRVJJQUxJWkVfRVJSOiBVbmFibGUgdG8gc2VyaWFsaXplIHRoZSBub2RlLiAgRE9NIGFwcGxpY2F0aW9ucyBzaG91bGQKLSAgICAgKiAgICBhdHRhY2ggYSA8Y29kZT5ET01FcnJvckhhbmRsZXI8L2NvZGU+IHVzaW5nIHRoZSBwYXJhbWV0ZXIKLSAgICAgKiAgICAmcXVvdDs8aT5lcnJvci1oYW5kbGVyPC9pPiZxdW90OyB0byBnZXQgZGV0YWlscyBvbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIHdyaXRlVG9TdHJpbmcoTm9kZSB3bm9kZSkgdGhyb3dzIERPTUV4Y2VwdGlvbiwgTFNFeGNlcHRpb24gewotICAgICAgICAvLyBkZXRlcm1pbmUgd2hpY2ggc2VyaWFsaXplciB0byB1c2U6Ci0gICAgICAgIERvY3VtZW50IGRvYyA9ICh3bm9kZS5nZXROb2RlVHlwZSgpID09IE5vZGUuRE9DVU1FTlRfTk9ERSk/KERvY3VtZW50KXdub2RlOndub2RlLmdldE93bmVyRG9jdW1lbnQoKTsKLSAgICAgICAgTWV0aG9kIGdldFZlcnNpb24gPSBudWxsOwotICAgICAgICBYTUxTZXJpYWxpemVyIHNlciA9IG51bGw7Ci0gICAgICAgIFN0cmluZyB2ZXIgPSBudWxsOwotICAgICAgICAvLyB0aGlzIHNob3VsZCBydW4gdW5kZXIgSkRLIDEuMS44Li4uCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBnZXRWZXJzaW9uID0gZG9jLmdldENsYXNzKCkuZ2V0TWV0aG9kKCJnZXRYbWxWZXJzaW9uIiwgbmV3IENsYXNzW117fSk7Ci0gICAgICAgICAgICBpZihnZXRWZXJzaW9uICE9IG51bGwgKSB7Ci0gICAgICAgICAgICAgICAgdmVyID0gKFN0cmluZylnZXRWZXJzaW9uLmludm9rZShkb2MsIChPYmplY3RbXSkgbnVsbCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAvLyBubyB3YXkgdG8gdGVzdCB0aGUgdmVyc2lvbi4uLgotICAgICAgICAgICAgLy8gaWdub3JlIHRoZSBleGNlcHRpb24KLSAgICAgICAgfQotICAgICAgICBpZih2ZXIgIT0gbnVsbCAmJiB2ZXIuZXF1YWxzKCIxLjEiKSkgewotICAgICAgICAgICAgaWYoeG1sMTFTZXJpYWxpemVyID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICB4bWwxMVNlcmlhbGl6ZXIgPSBuZXcgWE1MMTFTZXJpYWxpemVyKCk7Ci0gICAgICAgICAgICAgICAgaW5pdFNlcmlhbGl6ZXIoeG1sMTFTZXJpYWxpemVyKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIGNvcHkgc2V0dGluZyBmcm9tICJtYWluIiBzZXJpYWxpemVyIHRvIFhNTCAxLjEgc2VyaWFsaXplcgotICAgICAgICAgICAgY29weVNldHRpbmdzKHNlcmlhbGl6ZXIsIHhtbDExU2VyaWFsaXplcik7Ci0gICAgICAgICAgICBzZXIgPSB4bWwxMVNlcmlhbGl6ZXI7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBzZXIgPSBzZXJpYWxpemVyOwotICAgICAgICB9Ci0KLSAgICAgICAgU3RyaW5nV3JpdGVyIGRlc3RpbmF0aW9uID0gbmV3IFN0cmluZ1dyaXRlcigpOwotICAgICAgICB0cnkgewotICAgICAgICAgICAgcHJlcGFyZUZvclNlcmlhbGl6YXRpb24oc2VyLCB3bm9kZSk7Ci0gICAgICAgICAgICBzZXIuX2Zvcm1hdC5zZXRFbmNvZGluZygiVVRGLTE2Iik7Ci0gICAgICAgICAgICBzZXIuc2V0T3V0cHV0Q2hhclN0cmVhbShkZXN0aW5hdGlvbik7Ci0gICAgICAgICAgICBpZiAod25vZGUuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLkRPQ1VNRU5UX05PREUpIHsKLSAgICAgICAgICAgICAgICBzZXIuc2VyaWFsaXplKChEb2N1bWVudCl3bm9kZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmICh3bm9kZS5nZXROb2RlVHlwZSgpID09IE5vZGUuRE9DVU1FTlRfRlJBR01FTlRfTk9ERSkgewotICAgICAgICAgICAgICAgIHNlci5zZXJpYWxpemUoKERvY3VtZW50RnJhZ21lbnQpd25vZGUpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAod25vZGUuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLkVMRU1FTlRfTk9ERSkgewotICAgICAgICAgICAgICAgIHNlci5zZXJpYWxpemUoKEVsZW1lbnQpd25vZGUpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAod25vZGUuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLlRFWFRfTk9ERSB8fAotICAgICAgICAgICAgICAgICAgICB3bm9kZS5nZXROb2RlVHlwZSgpID09IE5vZGUuQ09NTUVOVF9OT0RFIHx8Ci0gICAgICAgICAgICAgICAgICAgIHdub2RlLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5FTlRJVFlfUkVGRVJFTkNFX05PREUgfHwKLSAgICAgICAgICAgICAgICAgICAgd25vZGUuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLkNEQVRBX1NFQ1RJT05fTk9ERSB8fAotICAgICAgICAgICAgICAgICAgICB3bm9kZS5nZXROb2RlVHlwZSgpID09IE5vZGUuUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFICkgewotICAgICAgICAgICAgICAgIHNlci5zZXJpYWxpemUod25vZGUpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIG1zZyA9IERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZSgKLSAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5TRVJJQUxJWkVSX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgInVuYWJsZS10by1zZXJpYWxpemUtbm9kZSIsIG51bGwpOwotICAgICAgICAgICAgICAgIGlmIChzZXIuZkRPTUVycm9ySGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIERPTUVycm9ySW1wbCBlcnJvciA9IG5ldyBET01FcnJvckltcGwoKTsKLSAgICAgICAgICAgICAgICAgICAgZXJyb3IuZlR5cGUgPSAidW5hYmxlLXRvLXNlcmlhbGl6ZS1ub2RlIjsKLSAgICAgICAgICAgICAgICAgICAgZXJyb3IuZk1lc3NhZ2UgPSBtc2c7Ci0gICAgICAgICAgICAgICAgICAgIGVycm9yLmZTZXZlcml0eSA9IERPTUVycm9yLlNFVkVSSVRZX0ZBVEFMX0VSUk9SOwotICAgICAgICAgICAgICAgICAgICBzZXIuZkRPTUVycm9ySGFuZGxlci5oYW5kbGVFcnJvcihlcnJvcik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHRocm93IG5ldyBMU0V4Y2VwdGlvbihMU0V4Y2VwdGlvbi5TRVJJQUxJWkVfRVJSLCBtc2cpOwotICAgICAgICAgICAgfQotICAgICAgICB9IGNhdGNoIChMU0V4Y2VwdGlvbiBsc2UpIHsKLSAgICAgICAgICAgIC8vIFJldGhyb3cgTFNFeGNlcHRpb24uCi0gICAgICAgICAgICB0aHJvdyBsc2U7Ci0gICAgICAgIH0gY2F0Y2ggKEFib3J0RXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIHRocm93IChMU0V4Y2VwdGlvbikgbmV3IExTRXhjZXB0aW9uKExTRXhjZXB0aW9uLlNFUklBTElaRV9FUlIsIGUudG9TdHJpbmcoKSkuaW5pdENhdXNlKGUpOwotICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBpb2UpIHsKLSAgICAgICAgICAgIC8vIFJFVklTSVQ6IEEgZ2VuZXJpYyBJT0V4Y2VwdGlvbiBkb2Vzbid0IHByb3ZpZGUgZW5vdWdoIGluZm9ybWF0aW9uCi0gICAgICAgICAgICAvLyB0byBkZXRlcm1pbmUgdGhhdCB0aGUgc2VyaWFsaXplZCBkb2N1bWVudCBpcyB0b28gbGFyZ2UgdG8gZml0Ci0gICAgICAgICAgICAvLyBpbnRvIGEgc3RyaW5nLiBUaGlzIGNvdWxkIGhhdmUgdGhyb3duIGZvciBzb21lIG90aGVyIHJlYXNvbi4gLS0gbXJnbGF2YXMKLSAgICAgICAgICAgIFN0cmluZyBtc2cgPSBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoCi0gICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLAotICAgICAgICAgICAgICAgICJTVFJJTkdfVE9PX0xPTkciLAotICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7IGlvZS5nZXRNZXNzYWdlKCl9KTsKLSAgICAgICAgICAgIHRocm93IChET01FeGNlcHRpb24pIG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLkRPTVNUUklOR19TSVpFX0VSUiwgbXNnKS5pbml0Q2F1c2UoaW9lKTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBkZXN0aW5hdGlvbi50b1N0cmluZygpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIERPTSBMMyBFWFBFUklNRU5UQUw6Ci0gICAgICogVGhlIGVuZC1vZi1saW5lIHNlcXVlbmNlIG9mIGNoYXJhY3RlcnMgdG8gYmUgdXNlZCBpbiB0aGUgWE1MIGJlaW5nCi0gICAgICogd3JpdHRlbiBvdXQuIFRoZSBvbmx5IHBlcm1pdHRlZCB2YWx1ZXMgYXJlIHRoZXNlOgotICAgICAqIDxkbD4KLSAgICAgKiA8ZHQ+PGNvZGU+bnVsbDwvY29kZT48L2R0PgotICAgICAqIDxkZD4KLSAgICAgKiBVc2UgYSBkZWZhdWx0IGVuZC1vZi1saW5lIHNlcXVlbmNlLiBET00gaW1wbGVtZW50YXRpb25zIHNob3VsZCBjaG9vc2UKLSAgICAgKiB0aGUgZGVmYXVsdCB0byBtYXRjaCB0aGUgdXN1YWwgY29udmVudGlvbiBmb3IgdGV4dCBmaWxlcyBpbiB0aGUKLSAgICAgKiBlbnZpcm9ubWVudCBiZWluZyB1c2VkLiBJbXBsZW1lbnRhdGlvbnMgbXVzdCBjaG9vc2UgYSBkZWZhdWx0Ci0gICAgICogc2VxdWVuY2UgdGhhdCBtYXRjaGVzIG9uZSBvZiB0aG9zZSBhbGxvd2VkIGJ5ICAyLjExICJFbmQtb2YtTGluZQotICAgICAqIEhhbmRsaW5nIi4gPC9kZD4KLSAgICAgKiA8ZHQ+Q1I8L2R0PgotICAgICAqIDxkZD5UaGUgY2FycmlhZ2UtcmV0dXJuIGNoYXJhY3RlciAoI3hEKS48L2RkPgotICAgICAqIDxkdD5DUi1MRjwvZHQ+Ci0gICAgICogPGRkPiBUaGUKLSAgICAgKiBjYXJyaWFnZS1yZXR1cm4gYW5kIGxpbmUtZmVlZCBjaGFyYWN0ZXJzICgjeEQgI3hBKS4gPC9kZD4KLSAgICAgKiA8ZHQ+TEY8L2R0PgotICAgICAqIDxkZD4gVGhlIGxpbmUtZmVlZAotICAgICAqIGNoYXJhY3RlciAoI3hBKS4gPC9kZD4KLSAgICAgKiA8L2RsPgotICAgICAqIDxicj5UaGUgZGVmYXVsdCB2YWx1ZSBmb3IgdGhpcyBhdHRyaWJ1dGUgaXMgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0TmV3TGluZShTdHJpbmcgbmV3TGluZSkgewotICAgICAgICBzZXJpYWxpemVyLl9mb3JtYXQuc2V0TGluZVNlcGFyYXRvcihuZXdMaW5lKTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIERPTSBMMyBFWFBFUklNRU5UQUw6Ci0gICAgICogVGhlIGVuZC1vZi1saW5lIHNlcXVlbmNlIG9mIGNoYXJhY3RlcnMgdG8gYmUgdXNlZCBpbiB0aGUgWE1MIGJlaW5nCi0gICAgICogd3JpdHRlbiBvdXQuIFRoZSBvbmx5IHBlcm1pdHRlZCB2YWx1ZXMgYXJlIHRoZXNlOgotICAgICAqIDxkbD4KLSAgICAgKiA8ZHQ+PGNvZGU+bnVsbDwvY29kZT48L2R0PgotICAgICAqIDxkZD4KLSAgICAgKiBVc2UgYSBkZWZhdWx0IGVuZC1vZi1saW5lIHNlcXVlbmNlLiBET00gaW1wbGVtZW50YXRpb25zIHNob3VsZCBjaG9vc2UKLSAgICAgKiB0aGUgZGVmYXVsdCB0byBtYXRjaCB0aGUgdXN1YWwgY29udmVudGlvbiBmb3IgdGV4dCBmaWxlcyBpbiB0aGUKLSAgICAgKiBlbnZpcm9ubWVudCBiZWluZyB1c2VkLiBJbXBsZW1lbnRhdGlvbnMgbXVzdCBjaG9vc2UgYSBkZWZhdWx0Ci0gICAgICogc2VxdWVuY2UgdGhhdCBtYXRjaGVzIG9uZSBvZiB0aG9zZSBhbGxvd2VkIGJ5ICAyLjExICJFbmQtb2YtTGluZQotICAgICAqIEhhbmRsaW5nIi4gPC9kZD4KLSAgICAgKiA8ZHQ+Q1I8L2R0PgotICAgICAqIDxkZD5UaGUgY2FycmlhZ2UtcmV0dXJuIGNoYXJhY3RlciAoI3hEKS48L2RkPgotICAgICAqIDxkdD5DUi1MRjwvZHQ+Ci0gICAgICogPGRkPiBUaGUKLSAgICAgKiBjYXJyaWFnZS1yZXR1cm4gYW5kIGxpbmUtZmVlZCBjaGFyYWN0ZXJzICgjeEQgI3hBKS4gPC9kZD4KLSAgICAgKiA8ZHQ+TEY8L2R0PgotICAgICAqIDxkZD4gVGhlIGxpbmUtZmVlZAotICAgICAqIGNoYXJhY3RlciAoI3hBKS4gPC9kZD4KLSAgICAgKiA8L2RsPgotICAgICAqIDxicj5UaGUgZGVmYXVsdCB2YWx1ZSBmb3IgdGhpcyBhdHRyaWJ1dGUgaXMgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXROZXdMaW5lKCkgewotICAgICAgICByZXR1cm4gc2VyaWFsaXplci5fZm9ybWF0LmdldExpbmVTZXBhcmF0b3IoKTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqICBXaGVuIHRoZSBhcHBsaWNhdGlvbiBwcm92aWRlcyBhIGZpbHRlciwgdGhlIHNlcmlhbGl6ZXIgd2lsbCBjYWxsIG91dAotICAgICAqIHRvIHRoZSBmaWx0ZXIgYmVmb3JlIHNlcmlhbGl6aW5nIGVhY2ggTm9kZS4gQXR0cmlidXRlIG5vZGVzIGFyZSBuZXZlcgotICAgICAqIHBhc3NlZCB0byB0aGUgZmlsdGVyLiBUaGUgZmlsdGVyIGltcGxlbWVudGF0aW9uIGNhbiBjaG9vc2UgdG8gcmVtb3ZlCi0gICAgICogdGhlIG5vZGUgZnJvbSB0aGUgc3RyZWFtIG9yIHRvIHRlcm1pbmF0ZSB0aGUgc2VyaWFsaXphdGlvbiBlYXJseS4KLSAgICAgKi8KLSAgICBwdWJsaWMgTFNTZXJpYWxpemVyRmlsdGVyIGdldEZpbHRlcigpewotICAgICAgICByZXR1cm4gc2VyaWFsaXplci5mRE9NRmlsdGVyOwotICAgIH0KLSAgICAvKioKLSAgICAgKiAgV2hlbiB0aGUgYXBwbGljYXRpb24gcHJvdmlkZXMgYSBmaWx0ZXIsIHRoZSBzZXJpYWxpemVyIHdpbGwgY2FsbCBvdXQKLSAgICAgKiB0byB0aGUgZmlsdGVyIGJlZm9yZSBzZXJpYWxpemluZyBlYWNoIE5vZGUuIEF0dHJpYnV0ZSBub2RlcyBhcmUgbmV2ZXIKLSAgICAgKiBwYXNzZWQgdG8gdGhlIGZpbHRlci4gVGhlIGZpbHRlciBpbXBsZW1lbnRhdGlvbiBjYW4gY2hvb3NlIHRvIHJlbW92ZQotICAgICAqIHRoZSBub2RlIGZyb20gdGhlIHN0cmVhbSBvciB0byB0ZXJtaW5hdGUgdGhlIHNlcmlhbGl6YXRpb24gZWFybHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RmlsdGVyKExTU2VyaWFsaXplckZpbHRlciBmaWx0ZXIpewotICAgICAgICBzZXJpYWxpemVyLmZET01GaWx0ZXIgPSBmaWx0ZXI7Ci0gICAgfQotCi0gICAgLy8gdGhpcyBpbml0aWFsaXplcyBhIG5ld2x5LWNyZWF0ZWQgc2VyaWFsaXplcgotICAgIHByaXZhdGUgdm9pZCBpbml0U2VyaWFsaXplcihYTUxTZXJpYWxpemVyIHNlcikgewotICAgICAgICBzZXIuZk5TQmluZGVyID0gbmV3IE5hbWVzcGFjZVN1cHBvcnQoKTsKLSAgICAgICAgc2VyLmZMb2NhbE5TQmluZGVyID0gbmV3IE5hbWVzcGFjZVN1cHBvcnQoKTsKLSAgICAgICAgc2VyLmZTeW1ib2xUYWJsZSA9IG5ldyBTeW1ib2xUYWJsZSgpOwotICAgIH0KLQotICAgIC8vIGNvcGllcyBhbGwgc2V0dGluZ3MgdGhhdCBjb3VsZCBoYXZlIGJlZW4gbW9kaWZpZWQKLSAgICAvLyBieSBjYWxscyB0byBMU1NlcmlhbGl6ZXIgbWV0aG9kcyBmcm9tIG9uZSBzZXJpYWxpemVyIHRvIGFub3RoZXIuCi0gICAgLy8gSU1QT1JUQU5UOiAgaWYgbmV3IG1ldGhvZHMgYXJlIGltcGxlbWVudGVkIG9yIG1vcmUgc2V0dGluZ3Mgb2YKLSAgICAvLyB0aGUgc2VyaWFsaXplciBhcmUgbWFkZSBhbHRlcmFibGUsIHRoaXMgbXVzdCBiZQotICAgIC8vIHJlZmxlY3RlZCBpbiB0aGlzIG1ldGhvZCEKLSAgICBwcml2YXRlIHZvaWQgY29weVNldHRpbmdzKFhNTFNlcmlhbGl6ZXIgc3JjLCBYTUxTZXJpYWxpemVyIGRlc3QpIHsKLSAgICAgICAgZGVzdC5mRE9NRXJyb3JIYW5kbGVyID0gZkVycm9ySGFuZGxlcjsKLSAgICAgICAgZGVzdC5fZm9ybWF0LnNldEVuY29kaW5nKHNyYy5fZm9ybWF0LmdldEVuY29kaW5nKCkpOwotICAgICAgICBkZXN0Ll9mb3JtYXQuc2V0TGluZVNlcGFyYXRvcihzcmMuX2Zvcm1hdC5nZXRMaW5lU2VwYXJhdG9yKCkpOwotICAgICAgICBkZXN0LmZET01GaWx0ZXIgPSBzcmMuZkRPTUZpbHRlcjsKLSAgICB9Ly9jb3B5c2V0dGluZ3MKLQotICAgIC8qKgotICAgICAgKiAgU2VyaWFsaXplIHRoZSBzcGVjaWZpZWQgbm9kZSBhcyBkZXNjcmliZWQgYWJvdmUgaW4gdGhlIGdlbmVyYWwKLSAgICAgICogZGVzY3JpcHRpb24gb2YgdGhlIDxjb2RlPkxTU2VyaWFsaXplcjwvY29kZT4gaW50ZXJmYWNlLiBUaGUgb3V0cHV0Ci0gICAgICAqIGlzIHdyaXR0ZW4gdG8gdGhlIHN1cHBsaWVkIDxjb2RlPkxTT3V0cHV0PC9jb2RlPi4KLSAgICAgICogPGJyPiBXaGVuIHdyaXRpbmcgdG8gYSA8Y29kZT5MU091dHB1dDwvY29kZT4sIHRoZSBlbmNvZGluZyBpcyBmb3VuZCBieQotICAgICAgKiBsb29raW5nIGF0IHRoZSBlbmNvZGluZyBpbmZvcm1hdGlvbiB0aGF0IGlzIHJlYWNoYWJsZSB0aHJvdWdoIHRoZQotICAgICAgKiA8Y29kZT5MU091dHB1dDwvY29kZT4gYW5kIHRoZSBpdGVtIHRvIGJlIHdyaXR0ZW4gKG9yIGl0cyBvd25lcgotICAgICAgKiBkb2N1bWVudCkgaW4gdGhpcyBvcmRlcjoKLSAgICAgICogPG9sPgotICAgICAgKiA8bGk+IDxjb2RlPkxTT3V0cHV0LmVuY29kaW5nPC9jb2RlPiwKLSAgICAgICogPC9saT4KLSAgICAgICogPGxpPgotICAgICAgKiA8Y29kZT5Eb2N1bWVudC5hY3R1YWxFbmNvZGluZzwvY29kZT4sCi0gICAgICAqIDwvbGk+Ci0gICAgICAqIDxsaT4KLSAgICAgICogPGNvZGU+RG9jdW1lbnQueG1sRW5jb2Rpbmc8L2NvZGU+LgotICAgICAgKiA8L2xpPgotICAgICAgKiA8L29sPgotICAgICAgKiA8YnI+IElmIG5vIGVuY29kaW5nIGlzIHJlYWNoYWJsZSB0aHJvdWdoIHRoZSBhYm92ZSBwcm9wZXJ0aWVzLCBhCi0gICAgICAqIGRlZmF1bHQgZW5jb2Rpbmcgb2YgIlVURi04IiB3aWxsIGJlIHVzZWQuCi0gICAgICAqIDxicj4gSWYgdGhlIHNwZWNpZmllZCBlbmNvZGluZyBpcyBub3Qgc3VwcG9ydGVkIGFuCi0gICAgICAqICJ1bnN1cHBvcnRlZC1lbmNvZGluZyIgZXJyb3IgaXMgcmFpc2VkLgotICAgICAgKiA8YnI+IElmIG5vIG91dHB1dCBpcyBzcGVjaWZpZWQgaW4gdGhlIDxjb2RlPkxTT3V0cHV0PC9jb2RlPiwgYQotICAgICAgKiAibm8tb3V0cHV0LXNwZWNpZmllZCIgZXJyb3IgaXMgcmFpc2VkLgotICAgICAgKiBAcGFyYW0gbm9kZSAgVGhlIG5vZGUgdG8gc2VyaWFsaXplLgotICAgICAgKiBAcGFyYW0gZGVzdGluYXRpb24gVGhlIGRlc3RpbmF0aW9uIGZvciB0aGUgc2VyaWFsaXplZCBET00uCi0gICAgICAqIEByZXR1cm4gIFJldHVybnMgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgPGNvZGU+bm9kZTwvY29kZT4gd2FzCi0gICAgICAqICAgc3VjY2Vzc2Z1bGx5IHNlcmlhbGl6ZWQgYW5kIDxjb2RlPmZhbHNlPC9jb2RlPiBpbiBjYXNlIHRoZSBub2RlCi0gICAgICAqICAgY291bGRuJ3QgYmUgc2VyaWFsaXplZC4KLSAgICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gd3JpdGUoTm9kZSBub2RlLCBMU091dHB1dCBkZXN0aW5hdGlvbikgdGhyb3dzIExTRXhjZXB0aW9uewotCi0gICAgICAgIGlmIChub2RlID09IG51bGwpCi0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0KLSAgICAgICAgTWV0aG9kIGdldFZlcnNpb24gPSBudWxsOwotICAgICAgICBYTUxTZXJpYWxpemVyIHNlciA9IG51bGw7Ci0gICAgICAgIFN0cmluZyB2ZXIgPSBudWxsOwotICAgICAgICBEb2N1bWVudCBmRG9jdW1lbnQgPShub2RlLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5ET0NVTUVOVF9OT0RFKQotICAgICAgICAgICAgICAgID8gKERvY3VtZW50KSBub2RlCi0gICAgICAgICAgICAgICAgOiBub2RlLmdldE93bmVyRG9jdW1lbnQoKTsKLSAgICAgICAgLy8gdGhpcyBzaG91bGQgcnVuIHVuZGVyIEpESyAxLjEuOC4uLgotICAgICAgICB0cnkgewotICAgICAgICAgICAgZ2V0VmVyc2lvbiA9IGZEb2N1bWVudC5nZXRDbGFzcygpLmdldE1ldGhvZCgiZ2V0WG1sVmVyc2lvbiIsIG5ldyBDbGFzc1tdIHt9KTsKLSAgICAgICAgICAgIGlmIChnZXRWZXJzaW9uICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICB2ZXIgPSAoU3RyaW5nKSBnZXRWZXJzaW9uLmludm9rZShmRG9jdW1lbnQsIChPYmplY3RbXSkgbnVsbCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAvL25vIHdheSB0byB0ZXN0IHRoZSB2ZXJzaW9uLi4uCi0gICAgICAgICAgICAvL2lnbm9yZSB0aGUgZXhjZXB0aW9uCi0gICAgICAgIH0KLSAgICAgICAgLy9kZXRlcm1pbmUgd2hpY2ggc2VyaWFsaXplciB0byB1c2U6Ci0gICAgICAgIGlmICh2ZXIgIT0gbnVsbCAmJiB2ZXIuZXF1YWxzKCIxLjEiKSkgewotICAgICAgICAgICAgaWYgKHhtbDExU2VyaWFsaXplciA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgeG1sMTFTZXJpYWxpemVyID0gbmV3IFhNTDExU2VyaWFsaXplcigpOwotICAgICAgICAgICAgICAgIGluaXRTZXJpYWxpemVyKHhtbDExU2VyaWFsaXplcik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvL2NvcHkgc2V0dGluZyBmcm9tICJtYWluIiBzZXJpYWxpemVyIHRvIFhNTCAxLjEgc2VyaWFsaXplcgotICAgICAgICAgICAgY29weVNldHRpbmdzKHNlcmlhbGl6ZXIsIHhtbDExU2VyaWFsaXplcik7Ci0gICAgICAgICAgICBzZXIgPSB4bWwxMVNlcmlhbGl6ZXI7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBzZXIgPSBzZXJpYWxpemVyOwotICAgICAgICB9Ci0KLSAgICAgICAgU3RyaW5nIGVuY29kaW5nID0gbnVsbDsKLSAgICAgICAgaWYgKChlbmNvZGluZyA9IGRlc3RpbmF0aW9uLmdldEVuY29kaW5nKCkpID09IG51bGwpIHsKLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgTWV0aG9kIGdldEVuY29kaW5nID0KLSAgICAgICAgICAgICAgICAgICAgZkRvY3VtZW50LmdldENsYXNzKCkuZ2V0TWV0aG9kKCJnZXRJbnB1dEVuY29kaW5nIiwgbmV3IENsYXNzW10ge30pOwotICAgICAgICAgICAgICAgIGlmIChnZXRFbmNvZGluZyAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGVuY29kaW5nID0gKFN0cmluZykgZ2V0RW5jb2RpbmcuaW52b2tlKGZEb2N1bWVudCwgKE9iamVjdFtdKSBudWxsKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgIC8vIGlnbm9yZSB0aGUgZXhjZXB0aW9uCi0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoZW5jb2RpbmcgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgIE1ldGhvZCBnZXRFbmNvZGluZyA9Ci0gICAgICAgICAgICAgICAgICAgICAgICBmRG9jdW1lbnQuZ2V0Q2xhc3MoKS5nZXRNZXRob2QoImdldFhtbEVuY29kaW5nIiwgbmV3IENsYXNzW10ge30pOwotICAgICAgICAgICAgICAgICAgICBpZiAoZ2V0RW5jb2RpbmcgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgZW5jb2RpbmcgPSAoU3RyaW5nKSBnZXRFbmNvZGluZy5pbnZva2UoZkRvY3VtZW50LCAoT2JqZWN0W10pIG51bGwpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gaWdub3JlIHRoZSBleGNlcHRpb24KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaWYgKGVuY29kaW5nID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgZW5jb2RpbmcgPSAiVVRGLTgiOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICB0cnkgewotICAgICAgICAgICAgcHJlcGFyZUZvclNlcmlhbGl6YXRpb24oc2VyLCBub2RlKTsKLSAgICAgICAgICAgIHNlci5fZm9ybWF0LnNldEVuY29kaW5nKGVuY29kaW5nKTsKLSAgICAgICAgICAgIE91dHB1dFN0cmVhbSBvdXRwdXRTdHJlYW0gPSBkZXN0aW5hdGlvbi5nZXRCeXRlU3RyZWFtKCk7Ci0gICAgICAgICAgICBXcml0ZXIgd3JpdGVyID0gZGVzdGluYXRpb24uZ2V0Q2hhcmFjdGVyU3RyZWFtKCk7Ci0gICAgICAgICAgICBTdHJpbmcgdXJpID0gIGRlc3RpbmF0aW9uLmdldFN5c3RlbUlkKCk7Ci0gICAgICAgICAgICBpZiAod3JpdGVyID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBpZiAob3V0cHV0U3RyZWFtID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKHVyaSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbXNnID0gRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuU0VSSUFMSVpFUl9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIm5vLW91dHB1dC1zcGVjaWZpZWQiLCBudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZXIuZkRPTUVycm9ySGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgRE9NRXJyb3JJbXBsIGVycm9yID0gbmV3IERPTUVycm9ySW1wbCgpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yLmZUeXBlID0gIm5vLW91dHB1dC1zcGVjaWZpZWQiOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yLmZNZXNzYWdlID0gbXNnOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yLmZTZXZlcml0eSA9IERPTUVycm9yLlNFVkVSSVRZX0ZBVEFMX0VSUk9SOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlci5mRE9NRXJyb3JIYW5kbGVyLmhhbmRsZUVycm9yKGVycm9yKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBMU0V4Y2VwdGlvbihMU0V4Y2VwdGlvbi5TRVJJQUxJWkVfRVJSLCBtc2cpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gVVJJIHdhcyBzcGVjaWZpZWQuIEhhbmRsZSByZWxhdGl2ZSBVUklzLgotICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGV4cGFuZGVkID0gWE1MRW50aXR5TWFuYWdlci5leHBhbmRTeXN0ZW1JZCh1cmksIG51bGwsIHRydWUpOwotICAgICAgICAgICAgICAgICAgICAgICAgVVJMIHVybCA9IG5ldyBVUkwoZXhwYW5kZWQgIT0gbnVsbCA/IGV4cGFuZGVkIDogdXJpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIE91dHB1dFN0cmVhbSBvdXQgPSBudWxsOwotICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHByb3RvY29sID0gdXJsLmdldFByb3RvY29sKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgaG9zdCA9IHVybC5nZXRIb3N0KCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBVc2UgRmlsZU91dHB1dFN0cmVhbSBpZiB0aGlzIFVSSSBpcyBmb3IgYSBsb2NhbCBmaWxlLgotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHByb3RvY29sLmVxdWFscygiZmlsZSIpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgKGhvc3QgPT0gbnVsbCB8fCBob3N0Lmxlbmd0aCgpID09IDAgfHwgaG9zdC5lcXVhbHMoImxvY2FsaG9zdCIpKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dCA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKGdldFBhdGhXaXRob3V0RXNjYXBlcyh1cmwuZ2V0RmlsZSgpKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBUcnkgdG8gd3JpdGUgdG8gc29tZSBvdGhlciBraW5kIG9mIFVSSS4gU29tZSBwcm90b2NvbHMKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIHdvbid0IHN1cHBvcnQgdGhpcywgdGhvdWdoIEhUVFAgc2hvdWxkIHdvcmsuCi0gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBVUkxDb25uZWN0aW9uIHVybENvbiA9IHVybC5vcGVuQ29ubmVjdGlvbigpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVybENvbi5zZXREb0lucHV0KGZhbHNlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cmxDb24uc2V0RG9PdXRwdXQodHJ1ZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgdXJsQ29uLnNldFVzZUNhY2hlcyhmYWxzZSk7IC8vIEVuYWJsZSB0dW5uZWxpbmcuCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHVybENvbiBpbnN0YW5jZW9mIEh0dHBVUkxDb25uZWN0aW9uKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoZSBET00gTDMgTFMgQ1Igc2F5cyBpZiB3ZSBhcmUgd3JpdGluZyB0byBhbiBIVFRQIFVSSQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpdCBpcyB0byBiZSBkb25lIHdpdGggYW4gSFRUUCBQVVQuCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEh0dHBVUkxDb25uZWN0aW9uIGh0dHBDb24gPSAoSHR0cFVSTENvbm5lY3Rpb24pIHVybENvbjsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaHR0cENvbi5zZXRSZXF1ZXN0TWV0aG9kKCJQVVQiKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgb3V0ID0gdXJsQ29uLmdldE91dHB1dFN0cmVhbSgpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgc2VyLnNldE91dHB1dEJ5dGVTdHJlYW0ob3V0KTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gYnl0ZSBzdHJlYW0gd2FzIHNwZWNpZmllZAotICAgICAgICAgICAgICAgICAgICBzZXIuc2V0T3V0cHV0Qnl0ZVN0cmVhbShvdXRwdXRTdHJlYW0pOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIC8vIGNoYXJhY3RlciBzdHJlYW0gaXMgc3BlY2lmaWVkCi0gICAgICAgICAgICAgICAgc2VyLnNldE91dHB1dENoYXJTdHJlYW0od3JpdGVyKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKG5vZGUuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLkRPQ1VNRU5UX05PREUpCi0gICAgICAgICAgICAgICAgc2VyLnNlcmlhbGl6ZSgoRG9jdW1lbnQpIG5vZGUpOwotICAgICAgICAgICAgZWxzZSBpZiAobm9kZS5nZXROb2RlVHlwZSgpID09IE5vZGUuRE9DVU1FTlRfRlJBR01FTlRfTk9ERSkKLSAgICAgICAgICAgICAgICBzZXIuc2VyaWFsaXplKChEb2N1bWVudEZyYWdtZW50KSBub2RlKTsKLSAgICAgICAgICAgIGVsc2UgaWYgKG5vZGUuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLkVMRU1FTlRfTk9ERSkKLSAgICAgICAgICAgICAgICBzZXIuc2VyaWFsaXplKChFbGVtZW50KSBub2RlKTsKLSAgICAgICAgICAgIGVsc2UgaWYgKG5vZGUuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLlRFWFRfTk9ERSB8fAotICAgICAgICAgICAgICAgICAgICBub2RlLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5DT01NRU5UX05PREUgfHwKLSAgICAgICAgICAgICAgICAgICAgbm9kZS5nZXROb2RlVHlwZSgpID09IE5vZGUuRU5USVRZX1JFRkVSRU5DRV9OT0RFIHx8Ci0gICAgICAgICAgICAgICAgICAgIG5vZGUuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLkNEQVRBX1NFQ1RJT05fTk9ERSB8fAotICAgICAgICAgICAgICAgICAgICBub2RlLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5QUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREUgKSB7Ci0gICAgICAgICAgICAgICAgc2VyLnNlcmlhbGl6ZShub2RlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0gY2F0Y2goIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gdWUpIHsKLSAgICAgICAgICAgIGlmIChzZXIuZkRPTUVycm9ySGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgRE9NRXJyb3JJbXBsIGVycm9yID0gbmV3IERPTUVycm9ySW1wbCgpOwotICAgICAgICAgICAgICAgIGVycm9yLmZFeGNlcHRpb24gPSB1ZTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IuZlR5cGUgPSAidW5zdXBwb3J0ZWQtZW5jb2RpbmciOwotICAgICAgICAgICAgICAgIGVycm9yLmZNZXNzYWdlID0gdWUuZ2V0TWVzc2FnZSgpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvci5mU2V2ZXJpdHkgPSBET01FcnJvci5TRVZFUklUWV9GQVRBTF9FUlJPUjsKLSAgICAgICAgICAgICAgICBzZXIuZkRPTUVycm9ySGFuZGxlci5oYW5kbGVFcnJvcihlcnJvcik7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB0aHJvdyBuZXcgTFNFeGNlcHRpb24oTFNFeGNlcHRpb24uU0VSSUFMSVpFX0VSUiwKLSAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoCi0gICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuU0VSSUFMSVpFUl9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICJ1bnN1cHBvcnRlZC1lbmNvZGluZyIsIG51bGwpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vcmV0dXJuIGZhbHNlOwotICAgICAgICB9IGNhdGNoIChMU0V4Y2VwdGlvbiBsc2UpIHsKLSAgICAgICAgICAgIC8vIFJldGhyb3cgTFNFeGNlcHRpb24uCi0gICAgICAgICAgICB0aHJvdyBsc2U7Ci0gICAgICAgIH0gY2F0Y2ggKEFib3J0RXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICB0aHJvdyAoTFNFeGNlcHRpb24pIERPTVV0aWwuY3JlYXRlTFNFeGNlcHRpb24oTFNFeGNlcHRpb24uU0VSSUFMSVpFX0VSUiwgZSkuZmlsbEluU3RhY2tUcmFjZSgpOwotICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgaWYgKHNlci5mRE9NRXJyb3JIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBET01FcnJvckltcGwgZXJyb3IgPSBuZXcgRE9NRXJyb3JJbXBsKCk7Ci0gICAgICAgICAgICAgICAgZXJyb3IuZkV4Y2VwdGlvbiA9IGU7Ci0gICAgICAgICAgICAgICAgZXJyb3IuZk1lc3NhZ2UgPSBlLmdldE1lc3NhZ2UoKTsKLSAgICAgICAgICAgICAgICBlcnJvci5mU2V2ZXJpdHkgPSBET01FcnJvci5TRVZFUklUWV9FUlJPUjsKLSAgICAgICAgICAgICAgICBzZXIuZkRPTUVycm9ySGFuZGxlci5oYW5kbGVFcnJvcihlcnJvcik7Ci0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHRocm93IChMU0V4Y2VwdGlvbikgRE9NVXRpbC5jcmVhdGVMU0V4Y2VwdGlvbihMU0V4Y2VwdGlvbi5TRVJJQUxJWkVfRVJSLCBlKS5maWxsSW5TdGFja1RyYWNlKCk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHRydWU7Ci0KLSAgICB9IC8vd3JpdGUKLQotICAgIC8qKgotICAgICAgKiAgU2VyaWFsaXplIHRoZSBzcGVjaWZpZWQgbm9kZSBhcyBkZXNjcmliZWQgYWJvdmUgaW4gdGhlIGdlbmVyYWwKLSAgICAgICogZGVzY3JpcHRpb24gb2YgdGhlIDxjb2RlPkxTU2VyaWFsaXplcjwvY29kZT4gaW50ZXJmYWNlLiBUaGUgb3V0cHV0Ci0gICAgICAqIGlzIHdyaXR0ZW4gdG8gdGhlIHN1cHBsaWVkIFVSSS4KLSAgICAgICogPGJyPiBXaGVuIHdyaXRpbmcgdG8gYSBVUkksIHRoZSBlbmNvZGluZyBpcyBmb3VuZCBieSBsb29raW5nIGF0IHRoZQotICAgICAgKiBlbmNvZGluZyBpbmZvcm1hdGlvbiB0aGF0IGlzIHJlYWNoYWJsZSB0aHJvdWdoIHRoZSBpdGVtIHRvIGJlIHdyaXR0ZW4KLSAgICAgICogKG9yIGl0cyBvd25lciBkb2N1bWVudCkgaW4gdGhpcyBvcmRlcjoKLSAgICAgICogPG9sPgotICAgICAgKiA8bGk+Ci0gICAgICAqIDxjb2RlPkRvY3VtZW50LmlucHV0RW5jb2Rpbmc8L2NvZGU+LAotICAgICAgKiA8L2xpPgotICAgICAgKiA8bGk+Ci0gICAgICAqIDxjb2RlPkRvY3VtZW50LnhtbEVuY29kaW5nPC9jb2RlPi4KLSAgICAgICogPC9saT4KLSAgICAgICogPC9vbD4KLSAgICAgICogPGJyPiBJZiBubyBlbmNvZGluZyBpcyByZWFjaGFibGUgdGhyb3VnaCB0aGUgYWJvdmUgcHJvcGVydGllcywgYQotICAgICAgKiBkZWZhdWx0IGVuY29kaW5nIG9mICJVVEYtOCIgd2lsbCBiZSB1c2VkLgotICAgICAgKiA8YnI+IElmIHRoZSBzcGVjaWZpZWQgZW5jb2RpbmcgaXMgbm90IHN1cHBvcnRlZCBhbgotICAgICAgKiAidW5zdXBwb3J0ZWQtZW5jb2RpbmciIGVycm9yIGlzIHJhaXNlZC4KLSAgICAgICogQHBhcmFtIG5vZGUgIFRoZSBub2RlIHRvIHNlcmlhbGl6ZS4KLSAgICAgICogQHBhcmFtIFVSSSBUaGUgVVJJIHRvIHdyaXRlIHRvLgotICAgICAgKiBAcmV0dXJuICBSZXR1cm5zIDxjb2RlPnRydWU8L2NvZGU+IGlmIDxjb2RlPm5vZGU8L2NvZGU+IHdhcwotICAgICAgKiAgIHN1Y2Nlc3NmdWxseSBzZXJpYWxpemVkIGFuZCA8Y29kZT5mYWxzZTwvY29kZT4gaW4gY2FzZSB0aGUgbm9kZQotICAgICAgKiAgIGNvdWxkbid0IGJlIHNlcmlhbGl6ZWQuCi0gICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIHdyaXRlVG9VUkkoTm9kZSBub2RlLCBTdHJpbmcgVVJJKSB0aHJvd3MgTFNFeGNlcHRpb257Ci0gICAgICAgIGlmIChub2RlID09IG51bGwpewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0KLSAgICAgICAgTWV0aG9kIGdldFhtbFZlcnNpb24gPSBudWxsOwotICAgICAgICBYTUxTZXJpYWxpemVyIHNlciA9IG51bGw7Ci0gICAgICAgIFN0cmluZyB2ZXIgPSBudWxsOwotICAgICAgICBTdHJpbmcgZW5jb2RpbmcgPSBudWxsOwotCi0gICAgICAgIERvY3VtZW50IGZEb2N1bWVudCA9KG5vZGUuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLkRPQ1VNRU5UX05PREUpCi0gICAgICAgICAgICAgICAgPyAoRG9jdW1lbnQpIG5vZGUKLSAgICAgICAgICAgICAgICA6IG5vZGUuZ2V0T3duZXJEb2N1bWVudCgpOwotICAgICAgICAvLyB0aGlzIHNob3VsZCBydW4gdW5kZXIgSkRLIDEuMS44Li4uCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBnZXRYbWxWZXJzaW9uID0KLSAgICAgICAgICAgICAgICBmRG9jdW1lbnQuZ2V0Q2xhc3MoKS5nZXRNZXRob2QoImdldFhtbFZlcnNpb24iLCBuZXcgQ2xhc3NbXSB7fSk7Ci0gICAgICAgICAgICBpZiAoZ2V0WG1sVmVyc2lvbiAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgdmVyID0gKFN0cmluZykgZ2V0WG1sVmVyc2lvbi5pbnZva2UoZkRvY3VtZW50LCAoT2JqZWN0W10pIG51bGwpOwotICAgICAgICAgICAgfQotICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgLy8gbm8gd2F5IHRvIHRlc3QgdGhlIHZlcnNpb24uLi4KLSAgICAgICAgICAgIC8vIGlnbm9yZSB0aGUgZXhjZXB0aW9uCi0gICAgICAgIH0KLSAgICAgICAgaWYgKHZlciAhPSBudWxsICYmIHZlci5lcXVhbHMoIjEuMSIpKSB7Ci0gICAgICAgICAgICBpZiAoeG1sMTFTZXJpYWxpemVyID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICB4bWwxMVNlcmlhbGl6ZXIgPSBuZXcgWE1MMTFTZXJpYWxpemVyKCk7Ci0gICAgICAgICAgICAgICAgaW5pdFNlcmlhbGl6ZXIoeG1sMTFTZXJpYWxpemVyKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIGNvcHkgc2V0dGluZyBmcm9tICJtYWluIiBzZXJpYWxpemVyIHRvIFhNTCAxLjEgc2VyaWFsaXplcgotICAgICAgICAgICAgY29weVNldHRpbmdzKHNlcmlhbGl6ZXIsIHhtbDExU2VyaWFsaXplcik7Ci0gICAgICAgICAgICBzZXIgPSB4bWwxMVNlcmlhbGl6ZXI7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBzZXIgPSBzZXJpYWxpemVyOwotICAgICAgICB9Ci0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIE1ldGhvZCBnZXRFbmNvZGluZyA9Ci0gICAgICAgICAgICAgICAgZkRvY3VtZW50LmdldENsYXNzKCkuZ2V0TWV0aG9kKCJnZXRJbnB1dEVuY29kaW5nIiwgbmV3IENsYXNzW10ge30pOwotICAgICAgICAgICAgaWYgKGdldEVuY29kaW5nICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBlbmNvZGluZyA9IChTdHJpbmcpIGdldEVuY29kaW5nLmludm9rZShmRG9jdW1lbnQsIChPYmplY3RbXSkgbnVsbCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAvLyBpZ25vcmUgdGhlIGV4Y2VwdGlvbgotICAgICAgICB9Ci0gICAgICAgIGlmIChlbmNvZGluZyA9PSBudWxsKSB7Ci0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIE1ldGhvZCBnZXRFbmNvZGluZyA9Ci0gICAgICAgICAgICAgICAgICAgIGZEb2N1bWVudC5nZXRDbGFzcygpLmdldE1ldGhvZCgiZ2V0WG1sRW5jb2RpbmciLCBuZXcgQ2xhc3NbXSB7fSk7Ci0gICAgICAgICAgICAgICAgaWYgKGdldEVuY29kaW5nICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgZW5jb2RpbmcgPSAoU3RyaW5nKSBnZXRFbmNvZGluZy5pbnZva2UoZkRvY3VtZW50LCAoT2JqZWN0W10pIG51bGwpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgLy8gaWdub3JlIHRoZSBleGNlcHRpb24KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChlbmNvZGluZyA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZW5jb2RpbmcgPSAiVVRGLTgiOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIHByZXBhcmVGb3JTZXJpYWxpemF0aW9uKHNlciwgbm9kZSk7Ci0gICAgICAgICAgICBzZXIuX2Zvcm1hdC5zZXRFbmNvZGluZyhlbmNvZGluZyk7Ci0KLSAgICAgICAgICAgIC8vIFVSSSB3YXMgc3BlY2lmaWVkLiBIYW5kbGUgcmVsYXRpdmUgVVJJcy4KLSAgICAgICAgICAgIFN0cmluZyBleHBhbmRlZCA9IFhNTEVudGl0eU1hbmFnZXIuZXhwYW5kU3lzdGVtSWQoVVJJLCBudWxsLCB0cnVlKTsKLSAgICAgICAgICAgIFVSTCB1cmwgPSBuZXcgVVJMKGV4cGFuZGVkICE9IG51bGwgPyBleHBhbmRlZCA6IFVSSSk7Ci0gICAgICAgICAgICBPdXRwdXRTdHJlYW0gb3V0ID0gbnVsbDsKLSAgICAgICAgICAgIFN0cmluZyBwcm90b2NvbCA9IHVybC5nZXRQcm90b2NvbCgpOwotICAgICAgICAgICAgU3RyaW5nIGhvc3QgPSB1cmwuZ2V0SG9zdCgpOwotICAgICAgICAgICAgLy8gVXNlIEZpbGVPdXRwdXRTdHJlYW0gaWYgdGhpcyBVUkkgaXMgZm9yIGEgbG9jYWwgZmlsZS4KLSAgICAgICAgICAgIGlmIChwcm90b2NvbC5lcXVhbHMoImZpbGUiKQotICAgICAgICAgICAgICAgICYmIChob3N0ID09IG51bGwgfHwgaG9zdC5sZW5ndGgoKSA9PSAwIHx8IGhvc3QuZXF1YWxzKCJsb2NhbGhvc3QiKSkpIHsKLSAgICAgICAgICAgICAgICBvdXQgPSBuZXcgRmlsZU91dHB1dFN0cmVhbShnZXRQYXRoV2l0aG91dEVzY2FwZXModXJsLmdldEZpbGUoKSkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gVHJ5IHRvIHdyaXRlIHRvIHNvbWUgb3RoZXIga2luZCBvZiBVUkkuIFNvbWUgcHJvdG9jb2xzCi0gICAgICAgICAgICAvLyB3b24ndCBzdXBwb3J0IHRoaXMsIHRob3VnaCBIVFRQIHNob3VsZCB3b3JrLgotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgVVJMQ29ubmVjdGlvbiB1cmxDb24gPSB1cmwub3BlbkNvbm5lY3Rpb24oKTsKLSAgICAgICAgICAgICAgICB1cmxDb24uc2V0RG9JbnB1dChmYWxzZSk7Ci0gICAgICAgICAgICAgICAgdXJsQ29uLnNldERvT3V0cHV0KHRydWUpOwotICAgICAgICAgICAgICAgIHVybENvbi5zZXRVc2VDYWNoZXMoZmFsc2UpOyAvLyBFbmFibGUgdHVubmVsaW5nLgotICAgICAgICAgICAgICAgIGlmICh1cmxDb24gaW5zdGFuY2VvZiBIdHRwVVJMQ29ubmVjdGlvbikgewotICAgICAgICAgICAgICAgICAgICAvLyBUaGUgRE9NIEwzIExTIENSIHNheXMgaWYgd2UgYXJlIHdyaXRpbmcgdG8gYW4gSFRUUCBVUkkKLSAgICAgICAgICAgICAgICAgICAgLy8gaXQgaXMgdG8gYmUgZG9uZSB3aXRoIGFuIEhUVFAgUFVULgotICAgICAgICAgICAgICAgICAgICBIdHRwVVJMQ29ubmVjdGlvbiBodHRwQ29uID0gKEh0dHBVUkxDb25uZWN0aW9uKSB1cmxDb247Ci0gICAgICAgICAgICAgICAgICAgIGh0dHBDb24uc2V0UmVxdWVzdE1ldGhvZCgiUFVUIik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIG91dCA9IHVybENvbi5nZXRPdXRwdXRTdHJlYW0oKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHNlci5zZXRPdXRwdXRCeXRlU3RyZWFtKG91dCk7Ci0KLSAgICAgICAgICAgIGlmIChub2RlLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5ET0NVTUVOVF9OT0RFKQotICAgICAgICAgICAgICAgIHNlci5zZXJpYWxpemUoKERvY3VtZW50KSBub2RlKTsKLSAgICAgICAgICAgIGVsc2UgaWYgKG5vZGUuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLkRPQ1VNRU5UX0ZSQUdNRU5UX05PREUpCi0gICAgICAgICAgICAgICAgc2VyLnNlcmlhbGl6ZSgoRG9jdW1lbnRGcmFnbWVudCkgbm9kZSk7Ci0gICAgICAgICAgICBlbHNlIGlmIChub2RlLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5FTEVNRU5UX05PREUpCi0gICAgICAgICAgICAgICAgc2VyLnNlcmlhbGl6ZSgoRWxlbWVudCkgbm9kZSk7Ci0gICAgICAgICAgICBlbHNlIGlmIChub2RlLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5URVhUX05PREUgfHwKLSAgICAgICAgICAgICAgICAgICAgbm9kZS5nZXROb2RlVHlwZSgpID09IE5vZGUuQ09NTUVOVF9OT0RFIHx8Ci0gICAgICAgICAgICAgICAgICAgIG5vZGUuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLkVOVElUWV9SRUZFUkVOQ0VfTk9ERSB8fAotICAgICAgICAgICAgICAgICAgICBub2RlLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5DREFUQV9TRUNUSU9OX05PREUgfHwKLSAgICAgICAgICAgICAgICAgICAgbm9kZS5nZXROb2RlVHlwZSgpID09IE5vZGUuUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFICkgewotICAgICAgICAgICAgICAgIHNlci5zZXJpYWxpemUobm9kZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9IGNhdGNoIChMU0V4Y2VwdGlvbiBsc2UpIHsKLSAgICAgICAgICAgIC8vIFJldGhyb3cgTFNFeGNlcHRpb24uCi0gICAgICAgICAgICB0aHJvdyBsc2U7Ci0gICAgICAgIH0gY2F0Y2ggKEFib3J0RXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICB0aHJvdyAoTFNFeGNlcHRpb24pIERPTVV0aWwuY3JlYXRlTFNFeGNlcHRpb24oTFNFeGNlcHRpb24uU0VSSUFMSVpFX0VSUiwgZSkuZmlsbEluU3RhY2tUcmFjZSgpOwotICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgaWYgKHNlci5mRE9NRXJyb3JIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBET01FcnJvckltcGwgZXJyb3IgPSBuZXcgRE9NRXJyb3JJbXBsKCk7Ci0gICAgICAgICAgICAgICAgZXJyb3IuZkV4Y2VwdGlvbiA9IGU7Ci0gICAgICAgICAgICAgICAgZXJyb3IuZk1lc3NhZ2UgPSBlLmdldE1lc3NhZ2UoKTsKLSAgICAgICAgICAgICAgICBlcnJvci5mU2V2ZXJpdHkgPSBET01FcnJvci5TRVZFUklUWV9FUlJPUjsKLSAgICAgICAgICAgICAgICBzZXIuZkRPTUVycm9ySGFuZGxlci5oYW5kbGVFcnJvcihlcnJvcik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICB0aHJvdyAoTFNFeGNlcHRpb24pIERPTVV0aWwuY3JlYXRlTFNFeGNlcHRpb24oTFNFeGNlcHRpb24uU0VSSUFMSVpFX0VSUiwgZSkuZmlsbEluU3RhY2tUcmFjZSgpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiB0cnVlOwotICAgIH0gLy93cml0ZVVSSQotCi0KLSAgICAvLwotICAgIC8vICBQcml2YXRlIG1ldGhvZHMKLSAgICAvLwotCi0gICAgcHJpdmF0ZSB2b2lkIHByZXBhcmVGb3JTZXJpYWxpemF0aW9uKFhNTFNlcmlhbGl6ZXIgc2VyLCBOb2RlIG5vZGUpIHsKLSAgICAgICAgc2VyLnJlc2V0KCk7Ci0gICAgICAgIHNlci5mZWF0dXJlcyA9IGZlYXR1cmVzOwotICAgICAgICBzZXIuZkRPTUVycm9ySGFuZGxlciA9IGZFcnJvckhhbmRsZXI7Ci0gICAgICAgIHNlci5mTmFtZXNwYWNlcyA9IChmZWF0dXJlcyAmIE5BTUVTUEFDRVMpICE9IDA7Ci0gICAgICAgIHNlci5mTmFtZXNwYWNlUHJlZml4ZXMgPSAoZmVhdHVyZXMgJiBOU0RFQ0wpICE9IDA7Ci0gICAgICAgIHNlci5fZm9ybWF0LnNldE9taXRDb21tZW50cygoZmVhdHVyZXMgJiBDT01NRU5UUyk9PTApOwotICAgICAgICBzZXIuX2Zvcm1hdC5zZXRPbWl0WE1MRGVjbGFyYXRpb24oKGZlYXR1cmVzICYgWE1MREVDTCkgPT0gMCk7Ci0gICAgICAgIHNlci5fZm9ybWF0LnNldEluZGVudGluZygoZmVhdHVyZXMgJiBGT1JNQVRfUFJFVFRZX1BSSU5UKSAhPSAwKTsKLQotICAgICAgICBpZiAoKGZlYXR1cmVzICYgV0VMTEZPUk1FRCkgIT0gMCkgewotICAgICAgICAgICAgLy8gUkVWSVNJVDogdGhpcyBpcyBpbmVmZmljaWVudCBpbXBsZW1lbnRhdGlvbiBvZiB3ZWxsLWZvcm1uZXNzLiBJbnN0ZWFkLCB3ZSBzaG91bGQgY2hlY2sKLSAgICAgICAgICAgIC8vIHdlbGwtZm9ybW5lc3MgYXMgd2Ugc2VyaWFsaXplIHRoZSB0cmVlCi0gICAgICAgICAgICBOb2RlIG5leHQsIHJvb3Q7Ci0gICAgICAgICAgICByb290ID0gbm9kZTsKLSAgICAgICAgICAgIE1ldGhvZCB2ZXJzaW9uQ2hhbmdlZDsKLSAgICAgICAgICAgIGJvb2xlYW4gdmVyaWZ5TmFtZXMgPSB0cnVlOwotICAgICAgICAgICAgRG9jdW1lbnQgZG9jdW1lbnQgPShub2RlLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5ET0NVTUVOVF9OT0RFKQotICAgICAgICAgICAgICAgICAgICA/IChEb2N1bWVudCkgbm9kZQotICAgICAgICAgICAgICAgICAgICA6IG5vZGUuZ2V0T3duZXJEb2N1bWVudCgpOwotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICB2ZXJzaW9uQ2hhbmdlZCA9IGRvY3VtZW50LmdldENsYXNzKCkuZ2V0TWV0aG9kKCJpc1hNTFZlcnNpb25DaGFuZ2VkKCkiLCBuZXcgQ2xhc3NbXSB7fSk7Ci0gICAgICAgICAgICAgICAgaWYgKHZlcnNpb25DaGFuZ2VkICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgdmVyaWZ5TmFtZXMgPSAoKEJvb2xlYW4pdmVyc2lvbkNoYW5nZWQuaW52b2tlKGRvY3VtZW50LCAoT2JqZWN0W10pIG51bGwpKS5ib29sZWFuVmFsdWUoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgIC8vbm8gd2F5IHRvIHRlc3QgdGhlIHZlcnNpb24uLi4KLSAgICAgICAgICAgICAgICAvL2lnbm9yZSB0aGUgZXhjZXB0aW9uCi0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAobm9kZS5nZXRGaXJzdENoaWxkKCkgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHdoaWxlIChub2RlICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgdmVyaWZ5KG5vZGUsIHZlcmlmeU5hbWVzLCBmYWxzZSk7Ci0gICAgICAgICAgICAgICAgICAgIC8vIE1vdmUgZG93biB0byBmaXJzdCBjaGlsZAotICAgICAgICAgICAgICAgICAgICBuZXh0ID0gbm9kZS5nZXRGaXJzdENoaWxkKCk7Ci0gICAgICAgICAgICAgICAgICAgIC8vIE5vIGNoaWxkIG5vZGVzLCBzbyB3YWxrIHRyZWUKLSAgICAgICAgICAgICAgICAgICAgd2hpbGUgKG5leHQgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgIC8vIE1vdmUgdG8gc2libGluZyBpZiBwb3NzaWJsZS4KLSAgICAgICAgICAgICAgICAgICAgICBuZXh0ID0gbm9kZS5nZXROZXh0U2libGluZygpOwotICAgICAgICAgICAgICAgICAgICAgIGlmIChuZXh0ID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZSA9IG5vZGUuZ2V0UGFyZW50Tm9kZSgpOwotICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocm9vdCA9PSBub2RlKXsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5leHQgPSBudWxsOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgbmV4dCA9IG5vZGUuZ2V0TmV4dFNpYmxpbmcoKTsKLSAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgbm9kZSA9IG5leHQ7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgdmVyaWZ5KG5vZGUsIHZlcmlmeU5hbWVzLCBmYWxzZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIHByaXZhdGUgdm9pZCB2ZXJpZnkgKE5vZGUgbm9kZSwgYm9vbGVhbiB2ZXJpZnlOYW1lcywgYm9vbGVhbiB4bWwxMVZlcnNpb24pewotCi0gICAgICAgIGludCB0eXBlID0gbm9kZS5nZXROb2RlVHlwZSgpOwotICAgICAgICBmTG9jYXRvci5mUmVsYXRlZE5vZGUgPSBub2RlOwotICAgICAgICBib29sZWFuIHdlbGxmb3JtZWQ7Ci0gICAgICAgIHN3aXRjaCAodHlwZSkgewotICAgICAgICAgICAgY2FzZSBOb2RlLkRPQ1VNRU5UX05PREU6ewotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2FzZSBOb2RlLkRPQ1VNRU5UX1RZUEVfTk9ERTp7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXNlIE5vZGUuRUxFTUVOVF9OT0RFOnsKLSAgICAgICAgICAgICAgICBpZiAodmVyaWZ5TmFtZXMpewotICAgICAgICAgICAgICAgICAgICBpZigoZmVhdHVyZXMgJiBOQU1FU1BBQ0VTKSAhPSAwKXsKLSAgICAgICAgICAgICAgICAgICAgICAgIHdlbGxmb3JtZWQgPSBDb3JlRG9jdW1lbnRJbXBsLmlzVmFsaWRRTmFtZShub2RlLmdldFByZWZpeCgpICwgbm9kZS5nZXRMb2NhbE5hbWUoKSwgeG1sMTFWZXJzaW9uKSA7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZXsKLSAgICAgICAgICAgICAgICAgICAgICAgIHdlbGxmb3JtZWQgPSBDb3JlRG9jdW1lbnRJbXBsLmlzWE1MTmFtZShub2RlLmdldE5vZGVOYW1lKCkgLCB4bWwxMVZlcnNpb24pOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGlmICghd2VsbGZvcm1lZCl7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF3ZWxsZm9ybWVkKXsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZFcnJvckhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG1zZyA9IERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZSgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIndmLWludmFsaWQtY2hhcmFjdGVyLWluLW5vZGUtbmFtZSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdeyJFbGVtZW50Iiwgbm9kZS5nZXROb2RlTmFtZSgpfSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRE9NTm9ybWFsaXplci5yZXBvcnRET01FcnJvcihmRXJyb3JIYW5kbGVyLCBmRXJyb3IsIGZMb2NhdG9yLCBtc2csIERPTUVycm9yLlNFVkVSSVRZX0ZBVEFMX0VSUk9SLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ3Zi1pbnZhbGlkLWNoYXJhY3Rlci1pbi1ub2RlLW5hbWUiKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgTmFtZWROb2RlTWFwIGF0dHJpYnV0ZXMgPSAobm9kZS5oYXNBdHRyaWJ1dGVzKCkpID8gbm9kZS5nZXRBdHRyaWJ1dGVzKCkgOiBudWxsOwotICAgICAgICAgICAgICAgIGlmIChhdHRyaWJ1dGVzICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhdHRyaWJ1dGVzLmdldExlbmd0aCgpOyArK2kpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIEF0dHIgYXR0ciA9IChBdHRyKSBhdHRyaWJ1dGVzLml0ZW0oaSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmTG9jYXRvci5mUmVsYXRlZE5vZGUgPSBhdHRyOwotICAgICAgICAgICAgICAgICAgICAgICAgRE9NTm9ybWFsaXplci5pc0F0dHJWYWx1ZVdGKCBmRXJyb3JIYW5kbGVyLCBmRXJyb3IsIGZMb2NhdG9yLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzLCBhdHRyLCBhdHRyLmdldFZhbHVlKCksIHhtbDExVmVyc2lvbik7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAodmVyaWZ5TmFtZXMpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB3ZWxsZm9ybWVkID0gQ29yZURvY3VtZW50SW1wbC5pc1hNTE5hbWUoIGF0dHIuZ2V0Tm9kZU5hbWUoKSwgeG1sMTFWZXJzaW9uKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXdlbGxmb3JtZWQpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBtc2cgPQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZSgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAid2YtaW52YWxpZC1jaGFyYWN0ZXItaW4tbm9kZS1uYW1lIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgIkF0dHIiLCBub2RlLmdldE5vZGVOYW1lKCl9KTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERPTU5vcm1hbGl6ZXIucmVwb3J0RE9NRXJyb3IoIGZFcnJvckhhbmRsZXIsIGZFcnJvciwgZkxvY2F0b3IsIG1zZywgRE9NRXJyb3IuU0VWRVJJVFlfRkFUQUxfRVJST1IsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIndmLWludmFsaWQtY2hhcmFjdGVyLWluLW5vZGUtbmFtZSIpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgY2FzZSBOb2RlLkNPTU1FTlRfTk9ERTogewotICAgICAgICAgICAgLy8gb25seSB2ZXJpZnkgd2VsbC1mb3JtbmVzcyBpZiBjb21tZW50cyBpbmNsdWRlZCBpbiB0aGUgdHJlZQotICAgICAgICAgICAgaWYgKChmZWF0dXJlcyAmIENPTU1FTlRTKSAhPSAwKQotICAgICAgICAgICAgICAgIERPTU5vcm1hbGl6ZXIuaXNDb21tZW50V0YoZkVycm9ySGFuZGxlciwgZkVycm9yLCBmTG9jYXRvciwgKChDb21tZW50KW5vZGUpLmdldERhdGEoKSwgeG1sMTFWZXJzaW9uKTsKLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICB9Ci0gICAgICAgIGNhc2UgTm9kZS5FTlRJVFlfUkVGRVJFTkNFX05PREU6IHsKLSAgICAgICAgICAgIC8vIG9ubHkgaWYgZW50aXR5IGlzIHByZXNlcnZlZCBpbiB0aGUgdHJlZQotICAgICAgICAgICAgaWYgKHZlcmlmeU5hbWVzICYmIChmZWF0dXJlcyAmIEVOVElUSUVTKSAhPSAwKXsKLSAgICAgICAgICAgICAgICBDb3JlRG9jdW1lbnRJbXBsLmlzWE1MTmFtZShub2RlLmdldE5vZGVOYW1lKCkgLCB4bWwxMVZlcnNpb24pOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgfQotICAgICAgICBjYXNlIE5vZGUuQ0RBVEFfU0VDVElPTl9OT0RFOiB7Ci0gICAgICAgICAgICAvLyB2ZXJpZnkgY29udGVudAotICAgICAgICAgICAgRE9NTm9ybWFsaXplci5pc1hNTENoYXJXRihmRXJyb3JIYW5kbGVyLCBmRXJyb3IsIGZMb2NhdG9yLCBub2RlLmdldE5vZGVWYWx1ZSgpLCB4bWwxMVZlcnNpb24pOwotICAgICAgICAgICAgLy8gdGhlIF1dPiBzdHJpbmcgd2lsbCBiZSBjaGVja2VkIGR1cmluZyBzZXJpYWxpemF0aW9uCi0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgfQotICAgICAgICBjYXNlIE5vZGUuVEVYVF9OT0RFOnsKLSAgICAgICAgICAgIERPTU5vcm1hbGl6ZXIuaXNYTUxDaGFyV0YoZkVycm9ySGFuZGxlciwgZkVycm9yLCBmTG9jYXRvciwgbm9kZS5nZXROb2RlVmFsdWUoKSwgeG1sMTFWZXJzaW9uKTsKLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICB9Ci0gICAgICAgIGNhc2UgTm9kZS5QUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREU6ewotICAgICAgICAgICAgUHJvY2Vzc2luZ0luc3RydWN0aW9uIHBpbm9kZSA9IChQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24pbm9kZSA7Ci0gICAgICAgICAgICBTdHJpbmcgdGFyZ2V0ID0gcGlub2RlLmdldFRhcmdldCgpOwotICAgICAgICAgICAgaWYgKHZlcmlmeU5hbWVzKSB7Ci0gICAgICAgICAgICAgICAgaWYgKHhtbDExVmVyc2lvbikgewotICAgICAgICAgICAgICAgICAgICB3ZWxsZm9ybWVkID0gWE1MMTFDaGFyLmlzWE1MMTFWYWxpZE5hbWUodGFyZ2V0KTsKLSAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICB3ZWxsZm9ybWVkID0gWE1MQ2hhci5pc1ZhbGlkTmFtZSh0YXJnZXQpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIGlmICghd2VsbGZvcm1lZCkgewotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbXNnID0KLSAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZSgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIndmLWludmFsaWQtY2hhcmFjdGVyLWluLW5vZGUtbmFtZSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgIkVsZW1lbnQiLCBub2RlLmdldE5vZGVOYW1lKCl9KTsKLSAgICAgICAgICAgICAgICAgICAgRE9NTm9ybWFsaXplci5yZXBvcnRET01FcnJvcigKLSAgICAgICAgICAgICAgICAgICAgICAgIGZFcnJvckhhbmRsZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICBmRXJyb3IsCi0gICAgICAgICAgICAgICAgICAgICAgICBmTG9jYXRvciwKLSAgICAgICAgICAgICAgICAgICAgICAgIG1zZywKLSAgICAgICAgICAgICAgICAgICAgICAgIERPTUVycm9yLlNFVkVSSVRZX0ZBVEFMX0VSUk9SLAotICAgICAgICAgICAgICAgICAgICAgICAgIndmLWludmFsaWQtY2hhcmFjdGVyLWluLW5vZGUtbmFtZSIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIERPTU5vcm1hbGl6ZXIuaXNYTUxDaGFyV0YoZkVycm9ySGFuZGxlciwgZkVycm9yLCBmTG9jYXRvciwgcGlub2RlLmdldERhdGEoKSwgeG1sMTFWZXJzaW9uKTsKLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgIH0KLQotICAgIHByaXZhdGUgU3RyaW5nIGdldFBhdGhXaXRob3V0RXNjYXBlcyhTdHJpbmcgb3JpZ1BhdGgpIHsKLSAgICAgICAgaWYgKG9yaWdQYXRoICE9IG51bGwgJiYgb3JpZ1BhdGgubGVuZ3RoKCkgIT0gMCAmJiBvcmlnUGF0aC5pbmRleE9mKCclJykgIT0gLTEpIHsKLSAgICAgICAgICAgIC8vIExvY2F0ZSB0aGUgZXNjYXBlIGNoYXJhY3RlcnMKLSAgICAgICAgICAgIFN0cmluZ1Rva2VuaXplciB0b2tlbml6ZXIgPSBuZXcgU3RyaW5nVG9rZW5pemVyKG9yaWdQYXRoLCAiJSIpOwotICAgICAgICAgICAgU3RyaW5nQnVmZmVyIHJlc3VsdCA9IG5ldyBTdHJpbmdCdWZmZXIob3JpZ1BhdGgubGVuZ3RoKCkpOwotICAgICAgICAgICAgaW50IHNpemUgPSB0b2tlbml6ZXIuY291bnRUb2tlbnMoKTsKLSAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQodG9rZW5pemVyLm5leHRUb2tlbigpKTsKLSAgICAgICAgICAgIGZvcihpbnQgaSA9IDE7IGkgPCBzaXplOyArK2kpIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgdG9rZW4gPSB0b2tlbml6ZXIubmV4dFRva2VuKCk7Ci0gICAgICAgICAgICAgICAgLy8gRGVjb2RlIHRoZSAyIGRpZ2l0IGhleGFkZWNpbWFsIG51bWJlciBmb2xsb3dpbmcgJSBpbiAnJW5uJwotICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoKGNoYXIpSW50ZWdlci52YWx1ZU9mKHRva2VuLnN1YnN0cmluZygwLCAyKSwgMTYpLmludFZhbHVlKCkpOwotICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQodG9rZW4uc3Vic3RyaW5nKDIpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiByZXN1bHQudG9TdHJpbmcoKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gb3JpZ1BhdGg7Ci0gICAgfQotCi19Ly9ET01TZXJpYWxpemVySW1wbApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplL0VsZW1lbnRTdGF0ZS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplL0VsZW1lbnRTdGF0ZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3NjUzYTJmLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZS9FbGVtZW50U3RhdGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEwOCArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDE1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICovCi0vKgotICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCi0gKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKLSAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KLSAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCi0gKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAotICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplOwotCi0KLWltcG9ydCBqYXZhLnV0aWwuTWFwOwotCi0KLS8qKgotICogSG9sZHMgdGhlIHN0YXRlIG9mIHRoZSBjdXJyZW50bHkgc2VyaWFsaXplZCBlbGVtZW50LgotICoKLSAqCi0gKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzphcmtpbkBpbnRhbGlvLmNvbSI+QXNzYWYgQXJraW48L2E+Ci0gKiBAc2VlIEJhc2VNYXJrdXBTZXJpYWxpemVyCi0gKi8KLXB1YmxpYyBjbGFzcyBFbGVtZW50U3RhdGUKLXsKLQotCi0gICAgLyoqCi0gICAgICogVGhlIGVsZW1lbnQncyByYXcgdGFnIG5hbWUgKGxvY2FsIG9yIHByZWZpeDpsb2NhbCkuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyByYXdOYW1lOwotCi0KLSAgICAvKioKLSAgICAgKiBUaGUgZWxlbWVudCdzIGxvY2FsIHRhZyBuYW1lLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgbG9jYWxOYW1lOwotCi0KLSAgICAvKioKLSAgICAgKiBUaGUgZWxlbWVudCdzIG5hbWVzcGFjZSBVUkkuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBuYW1lc3BhY2VVUkk7Ci0KLQotICAgIC8qKgotICAgICAqIFRydWUgaWYgZWxlbWVudCBpcyBzcGFjZSBwcmVzZXJ2aW5nLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIHByZXNlcnZlU3BhY2U7Ci0KLQotICAgIC8qKgotICAgICAqIFRydWUgaWYgZWxlbWVudCBpcyBlbXB0eS4gVHVybnMgZmFsc2UgaW1tZWRpYXRlbHkKLSAgICAgKiBhZnRlciBzZXJpYWxpemluZyB0aGUgZmlyc3QgY29udGVudHMgb2YgdGhlIGVsZW1lbnQuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZW1wdHk7Ci0KLQotICAgIC8qKgotICAgICAqIFRydWUgaWYgdGhlIGxhc3Qgc2VyaWFsaXplZCBub2RlIHdhcyBhbiBlbGVtZW50IG5vZGUuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gYWZ0ZXJFbGVtZW50OwotCi0KLSAgICAvKioKLSAgICAgKiBUcnVlIGlmIHRoZSBsYXN0IHNlcmlhbGl6ZWQgbm9kZSB3YXMgYSBjb21tZW50IG5vZGUuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gYWZ0ZXJDb21tZW50OwotCi0KLSAgICAvKioKLSAgICAgKiBUcnVlIGlmIHRleHR1YWwgY29udGVudCBvZiBjdXJyZW50IGVsZW1lbnQgc2hvdWxkIGJlCi0gICAgICogc2VyaWFsaXplZCBhcyBDREFUQSBzZWN0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGRvQ0RhdGE7Ci0KLQotICAgIC8qKgotICAgICAqIFRydWUgaWYgdGV4dHVhbCBjb250ZW50IG9mIGN1cnJlbnQgZWxlbWVudCBzaG91bGQgYmUKLSAgICAgKiBzZXJpYWxpemVkIGFzIHJhdyBjaGFyYWN0ZXJzICh1bmVzY2FwZWQpLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIHVuZXNjYXBlZDsKLQotCi0gICAgLyoqCi0gICAgICogVHJ1ZSB3aGlsZSBpbnNpZGUgQ0RhdGEgYW5kIHByaW50aW5nIHRleHQgYXMgQ0RhdGEuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaW5DRGF0YTsKLQotCi0gICAgLyoqCi0gICAgICogQXNzb2NpYXRpb24gYmV0d2VlbiBuYW1lc3BhY2UgVVJJcyAoa2V5cykgYW5kIHByZWZpeGVzICh2YWx1ZXMpLgotICAgICAqLwotICAgIHB1YmxpYyBNYXA8U3RyaW5nLCBTdHJpbmc+IHByZWZpeGVzOwotCi0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZS9FbmNvZGluZ0luZm8uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZS9FbmNvZGluZ0luZm8uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOWMyMTc1Ni4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemUvRW5jb2RpbmdJbmZvLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyNzEgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMC0yMDAyLDIwMDQsMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemU7Ci0KLWltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKLWltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbVdyaXRlcjsKLWltcG9ydCBqYXZhLmlvLlVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb247Ci1pbXBvcnQgamF2YS5pby5Xcml0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLkVuY29kaW5nTWFwOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgcmVwcmVzZW50cyBhbiBlbmNvZGluZy4KLSAqCi0gKiBAdmVyc2lvbiAkSWQ6IEVuY29kaW5nSW5mby5qYXZhLHYgMS42IDIwMDcvMTAvMTggMDM6Mzk6MDggam9laHcgRXhwICQKLSAqLwotcHVibGljIGNsYXNzIEVuY29kaW5nSW5mbyB7Ci0KLSAgICAvLyBBbiBhcnJheSB0byBob2xkIHRoZSBhcmd1bWVudCBmb3IgYSBtZXRob2Qgb2YgQ2hhcnNldCwgQ2hhcnNldEVuY29kZXIgb3IgQ2hhclRvQnl0ZUNvbnZlcnRlci4KLSAgICBwcml2YXRlIE9iamVjdCBbXSBmQXJnc0Zvck1ldGhvZCA9IG51bGw7Ci0KLSAgICAvLyBuYW1lIG9mIGVuY29kaW5nIGFzIHJlZ2lzdGVyZWQgd2l0aCBJQU5BOwotICAgIC8vIHByZWZlcmFibHkgYSBNSU1FIG5hbWUsIGJ1dCBhbGlhc2VzIGFyZSBmaW5lIHRvby4KLSAgICBTdHJpbmcgaWFuYU5hbWU7Ci0gICAgU3RyaW5nIGphdmFOYW1lOwotICAgIGludCBsYXN0UHJpbnRhYmxlOwotCi0gICAgLy8gVGhlIENoYXJzZXRFbmNvZGVyIHdpdGggd2hpY2ggd2UgdGVzdCB1bnVzdWFsIGNoYXJhY3RlcnMuCi0gICAgT2JqZWN0IGZDaGFyc2V0RW5jb2RlciA9IG51bGw7Ci0KLSAgICAvLyBUaGUgQ2hhclRvQnl0ZUNvbnZlcnRlciB3aXRoIHdoaWNoIHdlIHRlc3QgdW51c3VhbCBjaGFyYWN0ZXJzLgotICAgIE9iamVjdCBmQ2hhclRvQnl0ZUNvbnZlcnRlciA9IG51bGw7Ci0KLSAgICAvLyBJcyB0aGUgY29udmVydGVyIG51bGwgYmVjYXVzZSBpdCBjYW4ndCBiZSBpbnN0YW50aWF0ZWQKLSAgICAvLyBmb3Igc29tZSByZWFzb24gKHBlcmhhcHMgd2UncmUgcnVubmluZyB3aXRoIGluc3VmZmljaWVudCBhdXRob3JpdHkgYXMKLSAgICAvLyBhbiBhcHBsZXQ/Ci0gICAgYm9vbGVhbiBmSGF2ZVRyaWVkQ1RvQiA9IGZhbHNlOwotCi0gICAgLy8gSXMgdGhlIGNoYXJzZXQgZW5jb2RlciB1c2FibGUgb3IgYXZhaWxhYmxlLgotICAgIGJvb2xlYW4gZkhhdmVUcmllZENoYXJzZXRFbmNvZGVyID0gZmFsc2U7Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGVzIG5ldyA8Y29kZT5FbmNvZGluZ0luZm88L2NvZGU+IGluc3RhbmNlLgotICAgICAqLwotICAgIHB1YmxpYyBFbmNvZGluZ0luZm8oU3RyaW5nIGlhbmFOYW1lLCBTdHJpbmcgamF2YU5hbWUsIGludCBsYXN0UHJpbnRhYmxlKSB7Ci0gICAgICAgIHRoaXMuaWFuYU5hbWUgPSBpYW5hTmFtZTsKLSAgICAgICAgdGhpcy5qYXZhTmFtZSA9IEVuY29kaW5nTWFwLmdldElBTkEySmF2YU1hcHBpbmcoaWFuYU5hbWUpOwotICAgICAgICB0aGlzLmxhc3RQcmludGFibGUgPSBsYXN0UHJpbnRhYmxlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYSBNSU1FIGNoYXJzZXQgbmFtZSBvZiB0aGlzIGVuY29kaW5nLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0SUFOQU5hbWUoKSB7Ci0gICAgICAgIHJldHVybiB0aGlzLmlhbmFOYW1lOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYSB3cml0ZXIgZm9yIHRoaXMgZW5jb2RpbmcgYmFzZWQgb24KLSAgICAgKiBhbiBvdXRwdXQgc3RyZWFtLgotICAgICAqCi0gICAgICogQHJldHVybiBBIHN1aXRhYmxlIHdyaXRlcgotICAgICAqIEBleGNlcHRpb24gVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBUaGVyZSBpcyBubyBjb252ZXJ0b3IKLSAgICAgKiAgdG8gc3VwcG9ydCB0aGlzIGVuY29kaW5nCi0gICAgICovCi0gICAgcHVibGljIFdyaXRlciBnZXRXcml0ZXIoT3V0cHV0U3RyZWFtIG91dHB1dCkKLSAgICAgICAgdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gewotICAgICAgICAvLyB0aGlzIHNob3VsZCBhbHdheXMgYmUgdHJ1ZSEKLSAgICAgICAgaWYgKGphdmFOYW1lICE9IG51bGwpCi0gICAgICAgICAgICByZXR1cm4gbmV3IE91dHB1dFN0cmVhbVdyaXRlcihvdXRwdXQsIGphdmFOYW1lKTsKLSAgICAgICAgamF2YU5hbWUgPSBFbmNvZGluZ01hcC5nZXRJQU5BMkphdmFNYXBwaW5nKGlhbmFOYW1lKTsKLSAgICAgICAgaWYoamF2YU5hbWUgPT0gbnVsbCkKLSAgICAgICAgICAgIC8vIHVzZSBVVEYtOCBhcyBwcmVmZXJyZWQgZW5jb2RpbmcKLSAgICAgICAgICAgIHJldHVybiBuZXcgT3V0cHV0U3RyZWFtV3JpdGVyKG91dHB1dCwgIlVURjgiKTsKLSAgICAgICAgcmV0dXJuIG5ldyBPdXRwdXRTdHJlYW1Xcml0ZXIob3V0cHV0LCBqYXZhTmFtZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ2hlY2tzIHdoZXRoZXIgdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXIgaXMgcHJpbnRhYmxlIG9yIG5vdCBpbiB0aGlzIGVuY29kaW5nLgotICAgICAqCi0gICAgICogQHBhcmFtIGNoIGEgY29kZSBwb2ludCAoMC0weDEwZmZmZikKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc1ByaW50YWJsZShjaGFyIGNoKSB7Ci0gICAgICAgIGlmIChjaCA8PSB0aGlzLmxhc3RQcmludGFibGUpIHsKLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBpc1ByaW50YWJsZTAoY2gpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENoZWNrcyB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyIGlzIHByaW50YWJsZSBvciBub3QgaW4gdGhpcyBlbmNvZGluZy4KLSAgICAgKiBUaGlzIG1ldGhvZCBhY2NvbXBsaXNoZXMgdGhpcyB1c2luZyBhIGphdmEubmlvLkNoYXJzZXRFbmNvZGVyLiBJZiBOSU8gaXNuJ3QKLSAgICAgKiBhdmFpbGFibGUgaXQgd2lsbCBhdHRlbXB0IHVzZSBhIHN1bi5pby5DaGFyVG9CeXRlQ29udmVydGVyLgotICAgICAqCi0gICAgICogQHBhcmFtIGNoIGEgY29kZSBwb2ludCAoMC0weDEwZmZmZikKLSAgICAgKi8KLSAgICBwcml2YXRlIGJvb2xlYW4gaXNQcmludGFibGUwKGNoYXIgY2gpIHsKLQotICAgICAgICAvLyBBdHRlbXB0IHRvIGdldCBhIENoYXJzZXRFbmNvZGVyIGZvciB0aGlzIGVuY29kaW5nLgotICAgICAgICBpZiAoZkNoYXJzZXRFbmNvZGVyID09IG51bGwgJiYgQ2hhcnNldE1ldGhvZHMuZmdOSU9DaGFyc2V0QXZhaWxhYmxlICYmICFmSGF2ZVRyaWVkQ2hhcnNldEVuY29kZXIpIHsKLSAgICAgICAgICAgIGlmIChmQXJnc0Zvck1ldGhvZCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZkFyZ3NGb3JNZXRob2QgPSBuZXcgT2JqZWN0IFsxXTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIHRyeSBhbmQgY3JlYXRlIHRoZSBDaGFyc2V0RW5jb2RlcgotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICBmQXJnc0Zvck1ldGhvZFswXSA9IGphdmFOYW1lOwotICAgICAgICAgICAgICAgIE9iamVjdCBjaGFyc2V0ID0gQ2hhcnNldE1ldGhvZHMuZmdDaGFyc2V0Rm9yTmFtZU1ldGhvZC5pbnZva2UobnVsbCwgZkFyZ3NGb3JNZXRob2QpOwotICAgICAgICAgICAgICAgIGlmICgoKEJvb2xlYW4pIENoYXJzZXRNZXRob2RzLmZnQ2hhcnNldENhbkVuY29kZU1ldGhvZC5pbnZva2UoY2hhcnNldCwgKE9iamVjdFtdKSBudWxsKSkuYm9vbGVhblZhbHVlKCkpIHsKLSAgICAgICAgICAgICAgICAgICAgZkNoYXJzZXRFbmNvZGVyID0gQ2hhcnNldE1ldGhvZHMuZmdDaGFyc2V0TmV3RW5jb2Rlck1ldGhvZC5pbnZva2UoY2hhcnNldCwgKE9iamVjdFtdKSBudWxsKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLy8gVGhpcyBjaGFyc2V0IGNhbm5vdCBiZSB1c2VkIGZvciBlbmNvZGluZywgZG9uJ3QgdHJ5IGl0IGFnYWluLi4uCi0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIGZIYXZlVHJpZWRDaGFyc2V0RW5jb2RlciA9IHRydWU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgLy8gZG9uJ3QgdHJ5IGl0IGFnYWluLi4uCi0gICAgICAgICAgICAgICAgZkhhdmVUcmllZENoYXJzZXRFbmNvZGVyID0gdHJ1ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICAvLyBBdHRlbXB0IHRvIHVzZSB0aGUgQ2hhcnNldEVuY29kZXIgdG8gZGV0ZXJtaW5lIHdoZXRoZXIgdGhlIGNoYXJhY3RlciBpcyBwcmludGFibGUuCi0gICAgICAgIGlmIChmQ2hhcnNldEVuY29kZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICBmQXJnc0Zvck1ldGhvZFswXSA9IG5ldyBDaGFyYWN0ZXIoY2gpOwotICAgICAgICAgICAgICAgIHJldHVybiAoKEJvb2xlYW4pIENoYXJzZXRNZXRob2RzLmZnQ2hhcnNldEVuY29kZXJDYW5FbmNvZGVNZXRob2QuaW52b2tlKGZDaGFyc2V0RW5jb2RlciwgZkFyZ3NGb3JNZXRob2QpKS5ib29sZWFuVmFsdWUoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgIC8vIG9idmlvdXNseSBjYW4ndCB1c2UgdGhpcyBjaGFyc2V0IGVuY29kZXI7IHBvc3NpYmx5IGEgSkRLIGJ1ZwotICAgICAgICAgICAgICAgIGZDaGFyc2V0RW5jb2RlciA9IG51bGw7Ci0gICAgICAgICAgICAgICAgZkhhdmVUcmllZENoYXJzZXRFbmNvZGVyID0gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBBcyBhIGxhc3QgcmVzb3J0IHRyeSB0byB1c2UgYSBzdW4uaW8uQ2hhclRvQnl0ZUNvbnZlcnRlciB0bwotICAgICAgICAvLyBkZXRlcm1pbmUgd2hldGhlciB0aGlzIGNoYXJhY3RlciBpcyBwcmludGFibGUuIFdlIHdpbGwgYWx3YXlzCi0gICAgICAgIC8vIHJlYWNoIGhlcmUgb24gSkRLIDEuMyBvciBiZWxvdy4KLSAgICAgICAgaWYgKGZDaGFyVG9CeXRlQ29udmVydGVyID09IG51bGwpIHsKLSAgICAgICAgICAgIGlmIChmSGF2ZVRyaWVkQ1RvQiB8fCAhQ2hhclRvQnl0ZUNvbnZlcnRlck1ldGhvZHMuZmdDb252ZXJ0ZXJzQXZhaWxhYmxlKSB7Ci0gICAgICAgICAgICAgICAgLy8gZm9yZ2V0IGl0OyBub3RoaW5nIHdlIGNhbiBkby4uLgotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChmQXJnc0Zvck1ldGhvZCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZkFyZ3NGb3JNZXRob2QgPSBuZXcgT2JqZWN0IFsxXTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIHRyeSBhbmQgY3JlYXRlIHRoZSBDaGFyVG9CeXRlQ29udmVydGVyCi0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIGZBcmdzRm9yTWV0aG9kWzBdID0gamF2YU5hbWU7Ci0gICAgICAgICAgICAgICAgZkNoYXJUb0J5dGVDb252ZXJ0ZXIgPSBDaGFyVG9CeXRlQ29udmVydGVyTWV0aG9kcy5mZ0dldENvbnZlcnRlck1ldGhvZC5pbnZva2UobnVsbCwgZkFyZ3NGb3JNZXRob2QpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgLy8gZG9uJ3QgdHJ5IGl0IGFnYWluLi4uCi0gICAgICAgICAgICAgICAgZkhhdmVUcmllZENUb0IgPSB0cnVlOwotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICB0cnkgewotICAgICAgICAgICAgZkFyZ3NGb3JNZXRob2RbMF0gPSBuZXcgQ2hhcmFjdGVyKGNoKTsKLSAgICAgICAgICAgIHJldHVybiAoKEJvb2xlYW4pIENoYXJUb0J5dGVDb252ZXJ0ZXJNZXRob2RzLmZnQ2FuQ29udmVydE1ldGhvZC5pbnZva2UoZkNoYXJUb0J5dGVDb252ZXJ0ZXIsIGZBcmdzRm9yTWV0aG9kKSkuYm9vbGVhblZhbHVlKCk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAvLyBvYnZpb3VzbHkgY2FuJ3QgdXNlIHRoaXMgY29udmVydGVyOyBwcm9iYWJseSBzb21lIGtpbmQgb2YKLSAgICAgICAgICAgIC8vIHNlY3VyaXR5IHJlc3RyaWN0aW9uCi0gICAgICAgICAgICBmQ2hhclRvQnl0ZUNvbnZlcnRlciA9IG51bGw7Ci0gICAgICAgICAgICBmSGF2ZVRyaWVkQ1RvQiA9IGZhbHNlOwotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLy8gaXMgdGhpcyBhbiBlbmNvZGluZyBuYW1lIHJlY29nbml6ZWQgYnkgdGhpcyBKREs/Ci0gICAgLy8gaWYgbm90LCB3aWxsIHRocm93IFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24KLSAgICBwdWJsaWMgc3RhdGljIHZvaWQgdGVzdEphdmFFbmNvZGluZ05hbWUoU3RyaW5nIG5hbWUpICB0aHJvd3MgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiB7Ci0gICAgICAgIGZpbmFsIGJ5dGUgW10gYlRlc3QgPSB7KGJ5dGUpJ3YnLCAoYnl0ZSknYScsIChieXRlKSdsJywgKGJ5dGUpJ2knLCAoYnl0ZSknZCd9OwotICAgICAgICBTdHJpbmcgcyA9IG5ldyBTdHJpbmcoYlRlc3QsIG5hbWUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEhvbGRlciBvZiBtZXRob2RzIGZyb20gamF2YS5uaW8uY2hhcnNldC5DaGFyc2V0IGFuZCBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXRFbmNvZGVyLgotICAgICAqLwotICAgIHN0YXRpYyBjbGFzcyBDaGFyc2V0TWV0aG9kcyB7Ci0KLSAgICAgICAgLy8gTWV0aG9kOiBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXQuZm9yTmFtZShqYXZhLmxhbmcuU3RyaW5nKQotICAgICAgICBwcml2YXRlIHN0YXRpYyBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2QgZmdDaGFyc2V0Rm9yTmFtZU1ldGhvZCA9IG51bGw7Ci0KLSAgICAgICAgLy8gTWV0aG9kOiBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXQuY2FuRW5jb2RlKCkKLSAgICAgICAgcHJpdmF0ZSBzdGF0aWMgamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kIGZnQ2hhcnNldENhbkVuY29kZU1ldGhvZCA9IG51bGw7Ci0KLSAgICAgICAgLy8gTWV0aG9kOiBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXQubmV3RW5jb2RlcigpCi0gICAgICAgIHByaXZhdGUgc3RhdGljIGphdmEubGFuZy5yZWZsZWN0Lk1ldGhvZCBmZ0NoYXJzZXROZXdFbmNvZGVyTWV0aG9kID0gbnVsbDsKLQotICAgICAgICAvLyBNZXRob2Q6IGphdmEubmlvLmNoYXJzZXQuQ2hhcnNldEVuY29kZXIuY2FuRW5jb2RlKGNoYXIpCi0gICAgICAgIHByaXZhdGUgc3RhdGljIGphdmEubGFuZy5yZWZsZWN0Lk1ldGhvZCBmZ0NoYXJzZXRFbmNvZGVyQ2FuRW5jb2RlTWV0aG9kID0gbnVsbDsKLQotICAgICAgICAvLyBGbGFnIGluZGljYXRpbmcgd2hldGhlciBvciBub3QgamF2YS5uaW8uY2hhcnNldC4qIGlzIGF2YWlsYWJsZS4KLSAgICAgICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBmZ05JT0NoYXJzZXRBdmFpbGFibGUgPSBmYWxzZTsKLQotICAgICAgICBwcml2YXRlIENoYXJzZXRNZXRob2RzKCkge30KLQotICAgICAgICAvLyBBdHRlbXB0IHRvIGdldCBtZXRob2RzIGZvciBDaGFyc2V0IGFuZCBDaGFyc2V0RW5jb2RlciBvbiBjbGFzcyBpbml0aWFsaXphdGlvbi4KLSAgICAgICAgc3RhdGljIHsKLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgQ2xhc3MgY2hhcnNldENsYXNzID0gQ2xhc3MuZm9yTmFtZSgiamF2YS5uaW8uY2hhcnNldC5DaGFyc2V0Iik7Ci0gICAgICAgICAgICAgICAgQ2xhc3MgY2hhcnNldEVuY29kZXJDbGFzcyA9IENsYXNzLmZvck5hbWUoImphdmEubmlvLmNoYXJzZXQuQ2hhcnNldEVuY29kZXIiKTsKLSAgICAgICAgICAgICAgICBmZ0NoYXJzZXRGb3JOYW1lTWV0aG9kID0gY2hhcnNldENsYXNzLmdldE1ldGhvZCgiZm9yTmFtZSIsIG5ldyBDbGFzcyBbXSB7U3RyaW5nLmNsYXNzfSk7Ci0gICAgICAgICAgICAgICAgZmdDaGFyc2V0Q2FuRW5jb2RlTWV0aG9kID0gY2hhcnNldENsYXNzLmdldE1ldGhvZCgiY2FuRW5jb2RlIiwgbmV3IENsYXNzIFtdIHt9KTsKLSAgICAgICAgICAgICAgICBmZ0NoYXJzZXROZXdFbmNvZGVyTWV0aG9kID0gY2hhcnNldENsYXNzLmdldE1ldGhvZCgibmV3RW5jb2RlciIsIG5ldyBDbGFzcyBbXSB7fSk7Ci0gICAgICAgICAgICAgICAgZmdDaGFyc2V0RW5jb2RlckNhbkVuY29kZU1ldGhvZCA9IGNoYXJzZXRFbmNvZGVyQ2xhc3MuZ2V0TWV0aG9kKCJjYW5FbmNvZGUiLCBuZXcgQ2xhc3MgW10ge0NoYXJhY3Rlci5UWVBFfSk7Ci0gICAgICAgICAgICAgICAgZmdOSU9DaGFyc2V0QXZhaWxhYmxlID0gdHJ1ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIENsYXNzTm90Rm91bmRFeGNlcHRpb24sIE5vU3VjaE1ldGhvZEV4Y2VwdGlvbiBvciBTZWN1cml0eUV4Y2VwdGlvbgotICAgICAgICAgICAgLy8gV2hhdGV2ZXIgdGhlIGNhc2UsIHdlIGNhbm5vdCB1c2UgamF2YS5uaW8uY2hhcnNldC4qLgotICAgICAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleGMpIHsKLSAgICAgICAgICAgICAgICBmZ0NoYXJzZXRGb3JOYW1lTWV0aG9kID0gbnVsbDsKLSAgICAgICAgICAgICAgICBmZ0NoYXJzZXRDYW5FbmNvZGVNZXRob2QgPSBudWxsOwotICAgICAgICAgICAgICAgIGZnQ2hhcnNldEVuY29kZXJDYW5FbmNvZGVNZXRob2QgPSBudWxsOwotICAgICAgICAgICAgICAgIGZnQ2hhcnNldE5ld0VuY29kZXJNZXRob2QgPSBudWxsOwotICAgICAgICAgICAgICAgIGZnTklPQ2hhcnNldEF2YWlsYWJsZSA9IGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSG9sZGVyIG9mIG1ldGhvZHMgZnJvbSBzdW4uaW8uQ2hhclRvQnl0ZUNvbnZlcnRlci4KLSAgICAgKi8KLSAgICBzdGF0aWMgY2xhc3MgQ2hhclRvQnl0ZUNvbnZlcnRlck1ldGhvZHMgewotCi0gICAgICAgIC8vIE1ldGhvZDogc3VuLmlvLkNoYXJUb0J5dGVDb252ZXJ0ZXIuZ2V0Q29udmVydGVyKGphdmEubGFuZy5TdHJpbmcpCi0gICAgICAgIHByaXZhdGUgc3RhdGljIGphdmEubGFuZy5yZWZsZWN0Lk1ldGhvZCBmZ0dldENvbnZlcnRlck1ldGhvZCA9IG51bGw7Ci0KLSAgICAgICAgLy8gTWV0aG9kOiBzdW4uaW8uQ2hhclRvQnl0ZUNvbnZlcnRlci5jYW5Db252ZXJ0KGNoYXIpCi0gICAgICAgIHByaXZhdGUgc3RhdGljIGphdmEubGFuZy5yZWZsZWN0Lk1ldGhvZCBmZ0NhbkNvbnZlcnRNZXRob2QgPSBudWxsOwotCi0gICAgICAgIC8vIEZsYWcgaW5kaWNhdGluZyB3aGV0aGVyIG9yIG5vdCBzdW4uaW8uQ2hhclRvQnl0ZUNvbnZlcnRlciBpcyBhdmFpbGFibGUuCi0gICAgICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gZmdDb252ZXJ0ZXJzQXZhaWxhYmxlID0gZmFsc2U7Ci0KLSAgICAgICAgcHJpdmF0ZSBDaGFyVG9CeXRlQ29udmVydGVyTWV0aG9kcygpIHt9Ci0KLSAgICAgICAgLy8gQXR0ZW1wdCB0byBnZXQgbWV0aG9kcyBmb3IgY2hhciB0byBieXRlIGNvbnZlcnRlciBvbiBjbGFzcyBpbml0aWFsaXphdGlvbi4KLSAgICAgICAgc3RhdGljIHsKLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgQ2xhc3MgY2xhenogPSBDbGFzcy5mb3JOYW1lKCJzdW4uaW8uQ2hhclRvQnl0ZUNvbnZlcnRlciIpOwotICAgICAgICAgICAgICAgIGZnR2V0Q29udmVydGVyTWV0aG9kID0gY2xhenouZ2V0TWV0aG9kKCJnZXRDb252ZXJ0ZXIiLCBuZXcgQ2xhc3MgW10ge1N0cmluZy5jbGFzc30pOwotICAgICAgICAgICAgICAgIGZnQ2FuQ29udmVydE1ldGhvZCA9IGNsYXp6LmdldE1ldGhvZCgiY2FuQ29udmVydCIsIG5ldyBDbGFzcyBbXSB7Q2hhcmFjdGVyLlRZUEV9KTsKLSAgICAgICAgICAgICAgICBmZ0NvbnZlcnRlcnNBdmFpbGFibGUgPSB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiwgTm9TdWNoTWV0aG9kRXhjZXB0aW9uIG9yIFNlY3VyaXR5RXhjZXB0aW9uCi0gICAgICAgICAgICAvLyBXaGF0ZXZlciB0aGUgY2FzZSwgd2UgY2Fubm90IHVzZSBzdW4uaW8uQ2hhclRvQnl0ZUNvbnZlcnRlci4KLSAgICAgICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXhjKSB7Ci0gICAgICAgICAgICAgICAgZmdHZXRDb252ZXJ0ZXJNZXRob2QgPSBudWxsOwotICAgICAgICAgICAgICAgIGZnQ2FuQ29udmVydE1ldGhvZCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgZmdDb252ZXJ0ZXJzQXZhaWxhYmxlID0gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemUvRW5jb2RpbmdzLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemUvRW5jb2RpbmdzLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDQxZmViOWQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplL0VuY29kaW5ncy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTI0ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKi8KLS8qCi0gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKLSAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAotICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgotICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKLSAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCi0gKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemU7Ci0KLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5FbmNvZGluZ01hcDsKLWltcG9ydCBqYXZhLmlvLlVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb247Ci1pbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKLWltcG9ydCBqYXZhLnV0aWwuTWFwOwotaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkNvbmN1cnJlbnRIYXNoTWFwOwotCi0KLS8qKgotICogUHJvdmlkZXMgaW5mb3JtYXRpb24gYWJvdXQgZW5jb2RpbmdzLiBEZXBlbmRzIG9uIHRoZSBKYXZhIHJ1bnRpbWUKLSAqIHRvIHByb3ZpZGVzIHdyaXRlcnMgZm9yIHRoZSBkaWZmZXJlbnQgZW5jb2RpbmdzLCBidXQgY2FuIGJlIHVzZWQKLSAqIHRvIG92ZXJyaWRlIGVuY29kaW5nIG5hbWVzIGFuZCBwcm92aWRlIHRoZSBsYXN0IHByaW50YWJsZSBjaGFyYWN0ZXIKLSAqIGZvciBlYWNoIGVuY29kaW5nLgotICoKLSAqIEBhdXRob3IgPGEgaHJlZj0ibWFpbHRvOmFya2luQGludGFsaW8uY29tIj5Bc3NhZiBBcmtpbjwvYT4KLSAqLwotY2xhc3MgRW5jb2RpbmdzCi17Ci0KLQotICAgIC8qKgotICAgICAqIFRoZSBsYXN0IHByaW50YWJsZSBjaGFyYWN0ZXIgZm9yIHVua25vd24gZW5jb2RpbmdzLgotICAgICAqLwotICAgIHN0YXRpYyBmaW5hbCBpbnQgREVGQVVMVF9MQVNUX1BSSU5UQUJMRSA9IDB4N0Y7Ci0KLSAgICAvLyBsYXN0IHByaW50YWJsZSBjaGFyYWN0ZXIgZm9yIFVuaWNvZGUtY29tcGF0aWJsZSBlbmNvZGluZ3MKLSAgICBzdGF0aWMgZmluYWwgaW50IExBU1RfUFJJTlRBQkxFX1VOSUNPREUgPSAweGZmZmY7Ci0gICAgLy8gdW5pY29kZS1jb21wbGlhbnQgZW5jb2RpbmdzOyBjYW4gZXhwcmVzcyBwbGFuZSAwCi0gICAgc3RhdGljIGZpbmFsIFN0cmluZ1tdIFVOSUNPREVfRU5DT0RJTkdTID0gewotICAgICAgICAiVW5pY29kZSIsICJVbmljb2RlQmlnIiwgIlVuaWNvZGVMaXR0bGUiLCAiR0IyMzEyIiwgIlVURjgiLCAiVVRGLTE2IiwKLSAgICB9OwotICAgIC8vIGRlZmF1bHQgKEphdmEpIGVuY29kaW5nIGlmIG5vbmUgc3VwcGxpZWQ6Ci0gICAgc3RhdGljIGZpbmFsIFN0cmluZyBERUZBVUxUX0VOQ09ESU5HID0gIlVURjgiOwotCi0gICAgLy8gbm90ZSB0aGF0IHRoZSBzaXplIG9mIHRoaXMgTWFwCi0gICAgLy8gaXMgYm91bmRlZCBieSB0aGUgbnVtYmVyIG9mIGVuY29kaW5ncyByZWNvZ25pemVkIGJ5IEVuY29kaW5nTWFwOwotICAgIC8vIHRoZXJlZm9yZSBpdCBwb3NlcyBubyBzdGF0aWMgbXV0YWJpbGl0eSByaXNrLgotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIE1hcDxTdHJpbmcsIEVuY29kaW5nSW5mbz4gX2VuY29kaW5ncyA9IG5ldyBDb25jdXJyZW50SGFzaE1hcCgpOwotCi0gICAgLyoqCi0gICAgICogQHBhcmFtIGVuY29kaW5nIGEgTUlNRSBjaGFyc2V0IG5hbWUsIG9yIG51bGwuCi0gICAgICovCi0gICAgc3RhdGljIEVuY29kaW5nSW5mbyBnZXRFbmNvZGluZ0luZm8oU3RyaW5nIGVuY29kaW5nLCBib29sZWFuIGFsbG93SmF2YU5hbWVzKSB0aHJvd3MgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiB7Ci0gICAgICAgIEVuY29kaW5nSW5mbyBlSW5mbyA9IG51bGw7Ci0gICAgICAgIGlmIChlbmNvZGluZyA9PSBudWxsKSB7Ci0gICAgICAgICAgICBpZigoZUluZm8gPSBfZW5jb2RpbmdzLmdldChERUZBVUxUX0VOQ09ESU5HKSkgIT0gbnVsbCkKLSAgICAgICAgICAgICAgICByZXR1cm4gZUluZm87Ci0gICAgICAgICAgICBlSW5mbyA9IG5ldyBFbmNvZGluZ0luZm8oRW5jb2RpbmdNYXAuZ2V0SmF2YTJJQU5BTWFwcGluZyhERUZBVUxUX0VOQ09ESU5HKSwgREVGQVVMVF9FTkNPRElORywgTEFTVF9QUklOVEFCTEVfVU5JQ09ERSk7Ci0gICAgICAgICAgICBfZW5jb2RpbmdzLnB1dChERUZBVUxUX0VOQ09ESU5HLCBlSW5mbyk7Ci0gICAgICAgICAgICByZXR1cm4gZUluZm87Ci0gICAgICAgIH0KLSAgICAgICAgLy8gbmVlZCB0byBjb252ZXJ0IGl0IHRvIHVwcGVyIGNhc2U6Ci0gICAgICAgIGVuY29kaW5nID0gZW5jb2RpbmcudG9VcHBlckNhc2UoTG9jYWxlLkVOR0xJU0gpOwotICAgICAgICBTdHJpbmcgak5hbWUgPSBFbmNvZGluZ01hcC5nZXRJQU5BMkphdmFNYXBwaW5nKGVuY29kaW5nKTsKLSAgICAgICAgaWYoak5hbWUgPT0gbnVsbCkgewotICAgICAgICAgICAgLy8gc2VlIGlmIHRoZSBlbmNvZGluZyBwYXNzZWQgaW4gaXMgYSBKYXZhIGVuY29kaW5nIG5hbWUuCi0gICAgICAgICAgICBpZihhbGxvd0phdmFOYW1lcyApIHsKLSAgICAgICAgICAgICAgICBFbmNvZGluZ0luZm8udGVzdEphdmFFbmNvZGluZ05hbWUoZW5jb2RpbmcpOwotICAgICAgICAgICAgICAgIGlmKChlSW5mbyA9IF9lbmNvZGluZ3MuZ2V0KGVuY29kaW5nKSkgIT0gbnVsbCkKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVJbmZvOwotICAgICAgICAgICAgICAgIC8vIGlzIGl0IGtub3duIHRvIGJlIHVuaWNvZGUtY29tcGxpYW50PwotICAgICAgICAgICAgICAgIGludCBpPTA7Ci0gICAgICAgICAgICAgICAgZm9yKDsgaTxVTklDT0RFX0VOQ09ESU5HUy5sZW5ndGg7IGkrKykgewotICAgICAgICAgICAgICAgICAgICBpZihVTklDT0RFX0VOQ09ESU5HU1tpXS5lcXVhbHNJZ25vcmVDYXNlKGVuY29kaW5nKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgZUluZm8gPSBuZXcgRW5jb2RpbmdJbmZvKEVuY29kaW5nTWFwLmdldEphdmEySUFOQU1hcHBpbmcoZW5jb2RpbmcpLCBlbmNvZGluZywgTEFTVF9QUklOVEFCTEVfVU5JQ09ERSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpZihpID09IFVOSUNPREVfRU5DT0RJTkdTLmxlbmd0aCkgewotICAgICAgICAgICAgICAgICAgICBlSW5mbyA9IG5ldyBFbmNvZGluZ0luZm8oRW5jb2RpbmdNYXAuZ2V0SmF2YTJJQU5BTWFwcGluZyhlbmNvZGluZyksIGVuY29kaW5nLCBERUZBVUxUX0xBU1RfUFJJTlRBQkxFKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgX2VuY29kaW5ncy5wdXQoZW5jb2RpbmcsIGVJbmZvKTsKLSAgICAgICAgICAgICAgICByZXR1cm4gZUluZm87Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uKGVuY29kaW5nKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBpZiAoKGVJbmZvID0gX2VuY29kaW5ncy5nZXQoak5hbWUpKSAhPSBudWxsKQotICAgICAgICAgICAgcmV0dXJuIGVJbmZvOwotICAgICAgICAvLyBoYXZlIHRvIGNyZWF0ZSBvbmUuLi4KLSAgICAgICAgLy8gaXMgaXQga25vd24gdG8gYmUgdW5pY29kZS1jb21wbGlhbnQ/Ci0gICAgICAgIGludCBpPTA7Ci0gICAgICAgIGZvcig7IGk8VU5JQ09ERV9FTkNPRElOR1MubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgIGlmKFVOSUNPREVfRU5DT0RJTkdTW2ldLmVxdWFsc0lnbm9yZUNhc2Uoak5hbWUpKSB7Ci0gICAgICAgICAgICAgICAgZUluZm8gPSBuZXcgRW5jb2RpbmdJbmZvKGVuY29kaW5nLCBqTmFtZSwgTEFTVF9QUklOVEFCTEVfVU5JQ09ERSk7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgaWYoaSA9PSBVTklDT0RFX0VOQ09ESU5HUy5sZW5ndGgpIHsKLSAgICAgICAgICAgIGVJbmZvID0gbmV3IEVuY29kaW5nSW5mbyhlbmNvZGluZywgak5hbWUsIERFRkFVTFRfTEFTVF9QUklOVEFCTEUpOwotICAgICAgICB9Ci0gICAgICAgIF9lbmNvZGluZ3MucHV0KGpOYW1lLCBlSW5mbyk7Ci0gICAgICAgIHJldHVybiBlSW5mbzsKLSAgICB9Ci0KLSAgICBzdGF0aWMgZmluYWwgU3RyaW5nIEpJU19EQU5HRVJfQ0hBUlMKLSAgICA9ICJcXFx1MDA3ZVx1MDA3Zlx1MDBhMlx1MDBhM1x1MDBhNVx1MDBhYyIKLSAgICArIlx1MjAxNFx1MjAxNVx1MjAxNlx1MjAyNlx1MjAzZVx1MjAzZVx1MjIyNVx1MjIyZlx1MzAxYyIKLSAgICArIlx1ZmYzY1x1ZmY1ZVx1ZmZlMFx1ZmZlMVx1ZmZlMlx1ZmZlMyI7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZS9IVE1MRW50aXRpZXMucmVzIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplL0hUTUxFbnRpdGllcy5yZXMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDA0MjM2MzAuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplL0hUTUxFbnRpdGllcy5yZXMKKysrIC9kZXYvbnVsbApAQCAtMSwyOTAgKzAsMCBAQAotIyAkSWQ6IEhUTUxFbnRpdGllcy5yZXMsdiAxLjMgMjAwMC8wOC8zMCAxODo1OToyMCBhcmtpbiBFeHAgJAotIwotIyBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzphcmtpbkBpbnRhbGlvLmNvbSI+QXNzYWYgQXJraW48L2E+Ci0jCi0jIENoYXJhY3RlciBlbnRpdHkgcmVmZXJlbmNlcyBmb3IgbWFya3VwLXNpZ25pZmljYW50Ci0jCi1xdW90IDM0Ci1hbXAgMzgKLWx0IDYwCi1ndCA2MgotbmJzcCAxNjAKLSMKLSMgQ2hhcmFjdGVyIGVudGl0eSByZWZlcmVuY2VzIGZvciBJU08gODg1OS0xIGNoYXJhY3RlcnMKLSMKLWlleGNsIDE2MQotY2VudCAxNjIKLXBvdW5kIDE2MwotY3VycmVuIDE2NAoteWVuIDE2NQotYnJ2YmFyIDE2Ngotc2VjdCAxNjcKLXVtbCAxNjgKLWNvcHkgMTY5Ci1vcmRmIDE3MAotbGFxdW8gMTcxCi1ub3QgMTcyCi1zaHkgMTczCi1yZWcgMTc0Ci1tYWNyIDE3NQotZGVnIDE3NgotcGx1c21uIDE3Nwotc3VwMiAxNzgKLXN1cDMgMTc5Ci1hY3V0ZSAxODAKLW1pY3JvIDE4MQotcGFyYSAxODIKLW1pZGRvdCAxODMKLWNlZGlsIDE4NAotc3VwMSAxODUKLW9yZG0gMTg2Ci1yYXF1byAxODcKLWZyYWMxNCAxODgKLWZyYWMxMiAxODkKLWZyYWMzNCAxOTAKLWlxdWVzdCAxOTEKLUFncmF2ZSAxOTIKLUFhY3V0ZSAxOTMKLUFjaXJjIDE5NAotQXRpbGRlIDE5NQotQXVtbCAxOTYKLUFyaW5nIDE5NwotQUVsaWcgMTk4Ci1DY2VkaWwgMTk5Ci1FZ3JhdmUgMjAwCi1FYWN1dGUgMjAxCi1FY2lyYyAyMDIKLUV1bWwgMjAzCi1JZ3JhdmUgMjA0Ci1JYWN1dGUgMjA1Ci1JY2lyYyAyMDYKLUl1bWwgMjA3Ci1FVEggMjA4Ci1OdGlsZGUgMjA5Ci1PZ3JhdmUgMjEwCi1PYWN1dGUgMjExCi1PY2lyYyAyMTIKLU90aWxkZSAyMTMKLU91bWwgMjE0Ci10aW1lcyAyMTUKLU9zbGFzaCAyMTYKLVVncmF2ZSAyMTcKLVVhY3V0ZSAyMTgKLVVjaXJjIDIxOQotVXVtbCAyMjAKLVlhY3V0ZSAyMjEKLVRIT1JOIDIyMgotc3psaWcgMjIzCi1hZ3JhdmUgMjI0Ci1hYWN1dGUgMjI1Ci1hY2lyYyAyMjYKLWF0aWxkZSAyMjcKLWF1bWwgMjI4Ci1hcmluZyAyMjkKLWFlbGlnIDIzMAotY2NlZGlsIDIzMQotZWdyYXZlIDIzMgotZWFjdXRlIDIzMwotZWNpcmMgMjM0Ci1ldW1sIDIzNQotaWdyYXZlIDIzNgotaWFjdXRlIDIzNwotaWNpcmMgMjM4Ci1pdW1sIDIzOQotZXRoIDI0MAotbnRpbGRlIDI0MQotb2dyYXZlIDI0Mgotb2FjdXRlIDI0Mwotb2NpcmMgMjQ0Ci1vdGlsZGUgMjQ1Ci1vdW1sIDI0NgotZGl2aWRlIDI0Nwotb3NsYXNoIDI0OAotdWdyYXZlIDI0OQotdWFjdXRlIDI1MAotdWNpcmMgMjUxCi11dW1sIDI1MgoteWFjdXRlIDI1MwotdGhvcm4gMjU0Ci15dW1sIDI1NQotIwotIyBDaGFyYWN0ZXIgZW50aXR5IHJlZmVyZW5jZXMgZm9yIHN5bWJvbHMsIG1hdGhlbWF0aWNhbCBzeW1ib2xzLCBhbmQgR3JlZWsgbGV0dGVycwotIwotIyBMYXRpbiBFeHRlbmRlZAotZm5vZiA0MDIKLSMKLSMgR3JlZWsKLUFscGhhIDkxMwotQmV0YSA5MTQKLUdhbW1hIDkxNQotRGVsdGEgOTE2Ci1FcHNpbG9uIDkxNwotWmV0YSA5MTgKLUV0YSA5MTkKLVRoZXRhIDkyMAotSW90YSA5MjEKLUthcHBhIDkyMgotTGFtYmRhIDkyMwotTXUgOTI0Ci1OdSA5MjUKLVhpIDkyNgotT21pY3JvbiA5MjcKLVBpIDkyOAotUmhvIDkyOQotU2lnbWEgOTMxCi1UYXUgOTMyCi1VcHNpbG9uIDkzMwotUGhpIDkzNAotQ2hpIDkzNQotUHNpIDkzNgotT21lZ2EgOTM3Ci1hbHBoYSA5NDUKLWJldGEgOTQ2Ci1nYW1tYSA5NDcKLWRlbHRhIDk0OAotZXBzaWxvbiA5NDkKLXpldGEgOTUwCi1ldGEgOTUxCi10aGV0YSA5NTIKLWlvdGEgOTUzCi1rYXBwYSA5NTQKLWxhbWJkYSA5NTUKLW11IDk1NgotbnUgOTU3Ci14aSA5NTgKLW9taWNyb24gOTU5Ci1waSA5NjAKLXJobyA5NjEKLXNpZ21hZiA5NjIKLXNpZ21hIDk2MwotdGF1IDk2NAotdXBzaWxvbiA5NjUKLXBoaSA5NjYKLWNoaSA5NjcKLXBzaSA5NjgKLW9tZWdhIDk2OQotdGhldGFzeW0gOTc3Ci11cHNpaCA5NzgKLXBpdiA5ODIKLSMKLSMgR2VuZXJhbCBQdW5jdHVhdGlvbgotYnVsbCA4MjI2Ci1oZWxsaXAgODIzMAotcHJpbWUgODI0MgotUHJpbWUgODI0Mwotb2xpbmUgODI1NAotZnJhc2wgODI2MAotIwotIyBMZXR0ZXJsaWtlIFN5bWJvbHMKLXdlaWVycCA4NDcyCi1pbWFnZSA4NDY1Ci1yZWFsIDg0NzYKLXRyYWRlIDg0ODIKLWFsZWZzeW0gODUwMQotIwotIyBBcnJvd3MKLWxhcnIgODU5MgotdWFyciA4NTkzCi1yYXJyIDg1OTQKLWRhcnIgODU5NQotaGFyciA4NTk2Ci1jcmFyciA4NjI5Ci1sQXJyIDg2NTYKLXVBcnIgODY1NwotckFyciA4NjU4Ci1kQXJyIDg2NTkKLWhBcnIgODY2MAotIwotIyBNYXRoZW1hdGljYWwgT3BlcmF0b3JzCi1mb3JhbGwgODcwNAotcGFydCA4NzA2Ci1leGlzdCA4NzA3Ci1lbXB0eSA4NzA5Ci1uYWJsYSA4NzExCi1pc2luIDg3MTIKLW5vdGluIDg3MTMKLW5pIDg3MTUKLXByb2QgODcxOQotc3VtIDg3MjEKLW1pbnVzIDg3MjIKLWxvd2FzdCA4NzI3Ci1yYWRpYyA4NzMwCi1wcm9wIDg3MzMKLWluZmluIDg3MzQKLWFuZyA4NzM2Ci1hbmQgODc0Mwotb3IgODc0NAotY2FwIDg3NDUKLWN1cCA4NzQ2Ci1pbnQgODc0NwotdGhlcmU0IDg3NTYKLXNpbSA4NzY0Ci1jb25nIDg3NzMKLWFzeW1wIDg3NzYKLW5lIDg4MDAKLWVxdWl2IDg4MDEKLWxlIDg4MDQKLWdlIDg4MDUKLXN1YiA4ODM0Ci1zdXAgODgzNQotbnN1YiA4ODM2Ci1zdWJlIDg4MzgKLXN1cGUgODgzOQotb3BsdXMgODg1Mwotb3RpbWVzIDg4NTUKLXBlcnAgODg2OQotc2RvdCA4OTAxCi0jCi0jIE1pc2NlbGxhbmVvdXMgVGVjaG5pY2FsCi1sY2VpbCA4OTY4Ci1yY2VpbCA4OTY5Ci1sZmxvb3IgODk3MAotcmZsb29yIDg5NzEKLWxhbmcgOTAwMQotcmFuZyA5MDAyCi0jCi0jIEdlb21ldHJpYyBTaGFwZXMKLWxveiA5Njc0Ci0jCi0jIE1pc2NlbGxhbmVvdXMgU3ltYm9scwotc3BhZGVzIDk4MjQKLWNsdWJzIDk4MjcKLWhlYXJ0cyA5ODI5Ci1kaWFtcyA5ODMwCi0jCi0jIENoYXJhY3RlciBlbnRpdHkgcmVmZXJlbmNlcyBmb3IgaW50ZXJuYXRpb25hbGl6YXRpb24gY2hhcmFjdGVycwotIwotIyBMYXRpbiBFeHRlbmRlZC1BCi1PRWxpZyAzMzgKLW9lbGlnIDMzOQotIy0tIENvbW1lbnRlZCBvdXQuIE5OIDQuNyBkb2VzIG5vdCBzZWVtIHRvIHN1cHBvcnQgdGhlc2UgLS0KLSNTY2Fyb24gMzUyCi0jc2Nhcm9uIDM1MwotWXVtbCAzNzYKLSMKLSMgU3BhY2luZyBNb2RpZmllciBMZXR0ZXJzCi1jaXJjIDcxMAotdGlsZGUgNzMyCi0jCi0jIEdlbmVyYWwgUHVuY3R1YXRpb24KLWVuc3AgODE5NAotZW1zcCA4MTk1Ci10aGluc3AgODIwMQotenduaiA4MjA0Ci16d2ogODIwNQotbHJtIDgyMDYKLXJsbSA4MjA3Ci1uZGFzaCA4MjExCi1tZGFzaCA4MjEyCi1sc3F1byA4MjE2Ci1yc3F1byA4MjE3Ci1zYnF1byA4MjE4Ci1sZHF1byA4MjIwCi1yZHF1byA4MjIxCi1iZHF1byA4MjIyCi1kYWdnZXIgODIyNAotRGFnZ2VyIDgyMjUKLXBlcm1pbCA4MjQwCi1sc2FxdW8gODI0OQotcnNhcXVvIDgyNTAKLWV1cm8gODM2NApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplL0hUTUxTZXJpYWxpemVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemUvSFRNTFNlcmlhbGl6ZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNDliYmUxOC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemUvSFRNTFNlcmlhbGl6ZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDg3NiArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDE1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICovCi0vKgotICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCi0gKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKLSAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KLSAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCi0gKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAotICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotCi0vLyBTZXAgMTQsIDIwMDA6Ci0vLyAgRml4ZWQgc2VyaWFsaXplciB0byByZXBvcnQgSU8gZXhjZXB0aW9uIGRpcmVjdGx5LCBpbnN0ZWFkIGF0Ci0vLyAgdGhlIGVuZCBvZiBkb2N1bWVudCBwcm9jZXNzaW5nLgotLy8gIFJlcG9ydGVkIGJ5IFBhdHJpY2sgSGlnZ2lucyA8cGhpZ2dpbnNAdHJhbnN6YXAuY29tPgotLy8gQXVnIDIxLCAyMDAwOgotLy8gIEZpeGVkIGJ1ZyBpbiBzdGFydERvY3VtZW50IG5vdCBjYWxsaW5nIHByZXBhcmUuCi0vLyAgUmVwb3J0ZWQgYnkgTWlrYWVsIFN0YWxkYWwgPGQ5Ni1tc3QtaW5nZW4tcmVrbGFtQGQua3RoLnNlPgotLy8gQXVnIDIxLCAyMDAwOgotLy8gIEFkZGVkIGFiaWxpdHkgdG8gb21pdCBET0NUWVBFIGRlY2xhcmF0aW9uLgotLy8gU2VwIDEsIDIwMDA6Ci0vLyAgIElmIG5vIG91dHB1dCBmb3JtYXQgaXMgcHJvdmlkZWQgdGhlIHNlcmlhbGl6ZXIgbm93IGRlZmF1bHRzCi0vLyAgIHRvIElTTy04ODU5LTEgZW5jb2RpbmcuIFJlcG9ydGVkIGJ5IE1pa2FlbCBTdGFsZGFsCi0vLyAgIDxkOTYtbXN0QGQua3RoLnNlPgotCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemU7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbS5ET01NZXNzYWdlRm9ybWF0dGVyOwotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci1pbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5pby5Xcml0ZXI7Ci1pbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKLWltcG9ydCBqYXZhLnV0aWwuTWFwOwotaW1wb3J0IG9yZy53M2MuZG9tLkF0dHI7Ci1pbXBvcnQgb3JnLnczYy5kb20uRWxlbWVudDsKLWltcG9ydCBvcmcudzNjLmRvbS5OYW1lZE5vZGVNYXA7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcueG1sLnNheC5BdHRyaWJ1dGVMaXN0OwotaW1wb3J0IG9yZy54bWwuc2F4LkF0dHJpYnV0ZXM7Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotCi0KLS8qKgotICogSW1wbGVtZW50cyBhbiBIVE1ML1hIVE1MIHNlcmlhbGl6ZXIgc3VwcG9ydGluZyBib3RoIERPTSBhbmQgU0FYCi0gKiBwcmV0dHkgc2VyaWFsaXppbmcuIEhUTUwvWEhUTUwgbW9kZSBpcyBkZXRlcm1pbmVkIGluIHRoZQotICogY29uc3RydWN0b3IuICBGb3IgdXNhZ2UgaW5zdHJ1Y3Rpb25zIHNlZSB7QGxpbmsgU2VyaWFsaXplcn0uCi0gKiA8cD4KLSAqIElmIGFuIG91dHB1dCBzdHJlYW0gaXMgdXNlZCwgdGhlIGVuY29kaW5nIGlzIHRha2VuIGZyb20gdGhlCi0gKiBvdXRwdXQgZm9ybWF0IChkZWZhdWx0cyB0byA8dHQ+VVRGLTg8L3R0PikuIElmIGEgd3JpdGVyIGlzCi0gKiB1c2VkLCBtYWtlIHN1cmUgdGhlIHdyaXRlciB1c2VzIHRoZSBzYW1lIGVuY29kaW5nIChpZiBhcHBsaWVzKQotICogYXMgc3BlY2lmaWVkIGluIHRoZSBvdXRwdXQgZm9ybWF0LgotICogPHA+Ci0gKiBUaGUgc2VyaWFsaXplciBzdXBwb3J0cyBib3RoIERPTSBhbmQgU0FYLiBET00gc2VyaWFsaXppbmcgaXMgZG9uZQotICogYnkgY2FsbGluZyB7QGxpbmsgI3NlcmlhbGl6ZX0gYW5kIFNBWCBzZXJpYWxpemluZyBpcyBkb25lIGJ5IGZpcmluZwotICogU0FYIGV2ZW50cyBhbmQgdXNpbmcgdGhlIHNlcmlhbGl6ZXIgYXMgYSBkb2N1bWVudCBoYW5kbGVyLgotICogPHA+Ci0gKiBJZiBhbiBJL08gZXhjZXB0aW9uIG9jY3VycyB3aGlsZSBzZXJpYWxpemluZywgdGhlIHNlcmlhbGl6ZXIKLSAqIHdpbGwgbm90IHRocm93IGFuIGV4Y2VwdGlvbiBkaXJlY3RseSwgYnV0IG9ubHkgdGhyb3cgaXQKLSAqIGF0IHRoZSBlbmQgb2Ygc2VyaWFsaXppbmcgKGVpdGhlciBET00gb3IgU0FYJ3Mge0BsaW5rCi0gKiBvcmcueG1sLnNheC5Eb2N1bWVudEhhbmRsZXIjZW5kRG9jdW1lbnR9LgotICogPHA+Ci0gKiBGb3IgZWxlbWVudHMgdGhhdCBhcmUgbm90IHNwZWNpZmllZCBhcyB3aGl0ZXNwYWNlIHByZXNlcnZpbmcsCi0gKiB0aGUgc2VyaWFsaXplciB3aWxsIHBvdGVudGlhbGx5IGJyZWFrIGxvbmcgdGV4dCBsaW5lcyBhdCBzcGFjZQotICogYm91bmRhcmllcywgaW5kZW50IGxpbmVzLCBhbmQgc2VyaWFsaXplIGVsZW1lbnRzIG9uIHNlcGFyYXRlCi0gKiBsaW5lcy4gTGluZSB0ZXJtaW5hdG9ycyB3aWxsIGJlIHJlZ2FyZGVkIGFzIHNwYWNlcywgYW5kCi0gKiBzcGFjZXMgYXQgYmVnaW5uaW5nIG9mIGxpbmUgd2lsbCBiZSBzdHJpcHBlZC4KLSAqIDxwPgotICogWEhUTUwgaXMgc2xpZ2h0bHkgZGlmZmVyZW50IHRoYW4gSFRNTDoKLSAqIDx1bD4KLSAqIDxsaT5FbGVtZW50L2F0dHJpYnV0ZSBuYW1lcyBhcmUgbG93ZXIgY2FzZSBhbmQgY2FzZSBtYXR0ZXJzCi0gKiA8bGk+QXR0cmlidXRlcyBtdXN0IHNwZWNpZnkgdmFsdWUsIGV2ZW4gaWYgZW1wdHkgc3RyaW5nCi0gKiA8bGk+RW1wdHkgZWxlbWVudHMgbXVzdCBoYXZlICcvJyBpbiBlbXB0eSB0YWcKLSAqIDxsaT5Db250ZW50cyBvZiBTQ1JJUFQgYW5kIFNUWUxFIGVsZW1lbnRzIHNlcmlhbGl6ZWQgYXMgQ0RBVEEKLSAqIDwvdWw+Ci0gKgotICogQGRlcHJlY2F0ZWQgVGhpcyBjbGFzcyB3YXMgZGVwcmVjYXRlZCBpbiBYZXJjZXMgMi42LjIuIEl0IGlzCi0gKiByZWNvbW1lbmRlZCB0aGF0IG5ldyBhcHBsaWNhdGlvbnMgdXNlIEpBWFAncyBUcmFuc2Zvcm1hdGlvbiBBUEkKLSAqIGZvciBYTUwgKFRyQVgpIGZvciBzZXJpYWxpemluZyBIVE1MLiBTZWUgdGhlIFhlcmNlcyBkb2N1bWVudGF0aW9uCi0gKiBmb3IgbW9yZSBpbmZvcm1hdGlvbi4KLSAqIEBhdXRob3IgPGEgaHJlZj0ibWFpbHRvOmFya2luQGludGFsaW8uY29tIj5Bc3NhZiBBcmtpbjwvYT4KLSAqIEBzZWUgU2VyaWFsaXplcgotICovCi1wdWJsaWMgY2xhc3MgSFRNTFNlcmlhbGl6ZXIKLSAgICBleHRlbmRzIEJhc2VNYXJrdXBTZXJpYWxpemVyCi17Ci0KLQotICAgIC8qKgotICAgICAqIFRydWUgaWYgc2VyaWFsaXppbmcgaW4gWEhUTUwgZm9ybWF0LgotICAgICAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBfeGh0bWw7Ci0KLQotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFhIVE1MTmFtZXNwYWNlID0gImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwiOwotCi0gICAgLy8gZm9yIHVzZXJzIHRvIG92ZXJyaWRlIFhIVE1MTmFtZXNwYWNlIGlmIG5lZWQgYmUuCi0gICAgcHJpdmF0ZSBTdHJpbmcgZlVzZXJYSFRNTE5hbWVzcGFjZSA9IG51bGw7Ci0KLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHMgYSBuZXcgSFRNTC9YSFRNTCBzZXJpYWxpemVyIGRlcGVuZGluZyBvbiB0aGUgdmFsdWUgb2YKLSAgICAgKiA8dHQ+eGh0bWw8L3R0Pi4gVGhlIHNlcmlhbGl6ZXIgY2Fubm90IGJlIHVzZWQgd2l0aG91dCBjYWxsaW5nCi0gICAgICoge0BsaW5rICNzZXRPdXRwdXRDaGFyU3RyZWFtfSBvciB7QGxpbmsgI3NldE91dHB1dEJ5dGVTdHJlYW19IGZpcnN0LgotICAgICAqCi0gICAgICogQHBhcmFtIHhodG1sIFRydWUgaWYgWEhUTUwgc2VyaWFsaXppbmcKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgSFRNTFNlcmlhbGl6ZXIoIGJvb2xlYW4geGh0bWwsIE91dHB1dEZvcm1hdCBmb3JtYXQgKQotICAgIHsKLSAgICAgICAgc3VwZXIoIGZvcm1hdCApOwotICAgICAgICBfeGh0bWwgPSB4aHRtbDsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHMgYSBuZXcgc2VyaWFsaXplci4gVGhlIHNlcmlhbGl6ZXIgY2Fubm90IGJlIHVzZWQgd2l0aG91dAotICAgICAqIGNhbGxpbmcge0BsaW5rICNzZXRPdXRwdXRDaGFyU3RyZWFtfSBvciB7QGxpbmsgI3NldE91dHB1dEJ5dGVTdHJlYW19Ci0gICAgICogZmlyc3QuCi0gICAgICovCi0gICAgcHVibGljIEhUTUxTZXJpYWxpemVyKCkKLSAgICB7Ci0gICAgICAgIHRoaXMoIGZhbHNlLCBuZXcgT3V0cHV0Rm9ybWF0KCBNZXRob2QuSFRNTCwgIklTTy04ODU5LTEiLCBmYWxzZSApICk7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHNlcmlhbGl6ZXIuIFRoZSBzZXJpYWxpemVyIGNhbm5vdCBiZSB1c2VkIHdpdGhvdXQKLSAgICAgKiBjYWxsaW5nIHtAbGluayAjc2V0T3V0cHV0Q2hhclN0cmVhbX0gb3Ige0BsaW5rICNzZXRPdXRwdXRCeXRlU3RyZWFtfQotICAgICAqIGZpcnN0LgotICAgICAqLwotICAgIHB1YmxpYyBIVE1MU2VyaWFsaXplciggT3V0cHV0Rm9ybWF0IGZvcm1hdCApCi0gICAgewotICAgICAgICB0aGlzKCBmYWxzZSwgZm9ybWF0ICE9IG51bGwgPyBmb3JtYXQgOiBuZXcgT3V0cHV0Rm9ybWF0KCBNZXRob2QuSFRNTCwgIklTTy04ODU5LTEiLCBmYWxzZSApICk7Ci0gICAgfQotCi0KLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHMgYSBuZXcgc2VyaWFsaXplciB0aGF0IHdyaXRlcyB0byB0aGUgc3BlY2lmaWVkIHdyaXRlcgotICAgICAqIHVzaW5nIHRoZSBzcGVjaWZpZWQgb3V0cHV0IGZvcm1hdC4gSWYgPHR0PmZvcm1hdDwvdHQ+IGlzIG51bGwsCi0gICAgICogd2lsbCB1c2UgYSBkZWZhdWx0IG91dHB1dCBmb3JtYXQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gd3JpdGVyIFRoZSB3cml0ZXIgdG8gdXNlCi0gICAgICogQHBhcmFtIGZvcm1hdCBUaGUgb3V0cHV0IGZvcm1hdCB0byB1c2UsIG51bGwgZm9yIHRoZSBkZWZhdWx0Ci0gICAgICovCi0gICAgcHVibGljIEhUTUxTZXJpYWxpemVyKCBXcml0ZXIgd3JpdGVyLCBPdXRwdXRGb3JtYXQgZm9ybWF0ICkKLSAgICB7Ci0gICAgICAgIHRoaXMoIGZhbHNlLCBmb3JtYXQgIT0gbnVsbCA/IGZvcm1hdCA6IG5ldyBPdXRwdXRGb3JtYXQoIE1ldGhvZC5IVE1MLCAiSVNPLTg4NTktMSIsIGZhbHNlICkgKTsKLSAgICAgICAgc2V0T3V0cHV0Q2hhclN0cmVhbSggd3JpdGVyICk7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHNlcmlhbGl6ZXIgdGhhdCB3cml0ZXMgdG8gdGhlIHNwZWNpZmllZCBvdXRwdXQKLSAgICAgKiBzdHJlYW0gdXNpbmcgdGhlIHNwZWNpZmllZCBvdXRwdXQgZm9ybWF0LiBJZiA8dHQ+Zm9ybWF0PC90dD4KLSAgICAgKiBpcyBudWxsLCB3aWxsIHVzZSBhIGRlZmF1bHQgb3V0cHV0IGZvcm1hdC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBvdXRwdXQgVGhlIG91dHB1dCBzdHJlYW0gdG8gdXNlCi0gICAgICogQHBhcmFtIGZvcm1hdCBUaGUgb3V0cHV0IGZvcm1hdCB0byB1c2UsIG51bGwgZm9yIHRoZSBkZWZhdWx0Ci0gICAgICovCi0gICAgcHVibGljIEhUTUxTZXJpYWxpemVyKCBPdXRwdXRTdHJlYW0gb3V0cHV0LCBPdXRwdXRGb3JtYXQgZm9ybWF0ICkKLSAgICB7Ci0gICAgICAgIHRoaXMoIGZhbHNlLCBmb3JtYXQgIT0gbnVsbCA/IGZvcm1hdCA6IG5ldyBPdXRwdXRGb3JtYXQoIE1ldGhvZC5IVE1MLCAiSVNPLTg4NTktMSIsIGZhbHNlICkgKTsKLSAgICAgICAgc2V0T3V0cHV0Qnl0ZVN0cmVhbSggb3V0cHV0ICk7Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgdm9pZCBzZXRPdXRwdXRGb3JtYXQoIE91dHB1dEZvcm1hdCBmb3JtYXQgKQotICAgIHsKLSAgICAgICAgc3VwZXIuc2V0T3V0cHV0Rm9ybWF0KCBmb3JtYXQgIT0gbnVsbCA/IGZvcm1hdCA6IG5ldyBPdXRwdXRGb3JtYXQoIE1ldGhvZC5IVE1MLCAiSVNPLTg4NTktMSIsIGZhbHNlICkgKTsKLSAgICB9Ci0KLSAgICAvLyBTZXQgIHZhbHVlIGZvciBhbHRlcm5hdGUgWEhUTUwgbmFtZXNwYWNlLgotICAgIHB1YmxpYyB2b2lkIHNldFhIVE1MTmFtZXNwYWNlKFN0cmluZyBuZXdOYW1lc3BhY2UpIHsKLSAgICAgICAgZlVzZXJYSFRNTE5hbWVzcGFjZSA9IG5ld05hbWVzcGFjZTsKLSAgICB9IC8vIHNldFhIVE1MTmFtZXNwYWNlKFN0cmluZykKLQotICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0vLwotICAgIC8vIFNBWCBjb250ZW50IGhhbmRsZXIgc2VyaWFsaXppbmcgbWV0aG9kcyAvLwotICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0vLwotCi0KLSAgICBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQoIFN0cmluZyBuYW1lc3BhY2VVUkksIFN0cmluZyBsb2NhbE5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcmF3TmFtZSwgQXR0cmlidXRlcyBhdHRycyApCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGludCAgICAgICAgICBpOwotICAgICAgICBib29sZWFuICAgICAgcHJlc2VydmVTcGFjZTsKLSAgICAgICAgRWxlbWVudFN0YXRlIHN0YXRlOwotICAgICAgICBTdHJpbmcgICAgICAgbmFtZTsKLSAgICAgICAgU3RyaW5nICAgICAgIHZhbHVlOwotICAgICAgICBTdHJpbmcgICAgICAgaHRtbE5hbWU7Ci0gICAgICAgIGJvb2xlYW4gICAgICBhZGROU0F0dHIgPSBmYWxzZTsKLQotICAgICAgICB0cnkgewotICAgICAgICAgICAgaWYgKCBfcHJpbnRlciA9PSBudWxsICkKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5TRVJJQUxJWkVSX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAgICAgIk5vV3JpdGVyU3VwcGxpZWQiLCBudWxsKSk7Ci0KLSAgICAgICAgICAgIHN0YXRlID0gZ2V0RWxlbWVudFN0YXRlKCk7Ci0gICAgICAgICAgICBpZiAoIGlzRG9jdW1lbnRTdGF0ZSgpICkgewotICAgICAgICAgICAgICAgIC8vIElmIHRoaXMgaXMgdGhlIHJvb3QgZWxlbWVudCBoYW5kbGUgaXQgZGlmZmVyZW50bHkuCi0gICAgICAgICAgICAgICAgLy8gSWYgdGhlIGZpcnN0IHJvb3QgZWxlbWVudCBpbiB0aGUgZG9jdW1lbnQsIHNlcmlhbGl6ZQotICAgICAgICAgICAgICAgIC8vIHRoZSBkb2N1bWVudCdzIERPQ1RZUEUuIFNwYWNlIHByZXNlcnZpbmcgZGVmYXVsdHMKLSAgICAgICAgICAgICAgICAvLyB0byB0aGF0IG9mIHRoZSBvdXRwdXQgZm9ybWF0LgotICAgICAgICAgICAgICAgIGlmICggISBfc3RhcnRlZCApCi0gICAgICAgICAgICAgICAgICAgIHN0YXJ0RG9jdW1lbnQoIChsb2NhbE5hbWUgPT0gbnVsbCB8fCBsb2NhbE5hbWUubGVuZ3RoKCkgPT0gMCkKLSAgICAgICAgICAgICAgICAgICAgICAgID8gcmF3TmFtZSA6IGxvY2FsTmFtZSApOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAvLyBGb3IgYW55IG90aGVyIGVsZW1lbnQsIGlmIGZpcnN0IGluIHBhcmVudCwgdGhlbgotICAgICAgICAgICAgICAgIC8vIGNsb3NlIHBhcmVudCdzIG9wZW5pbmcgdGFnIGFuZCB1c2UgdGhlIHBhcm5ldCdzCi0gICAgICAgICAgICAgICAgLy8gc3BhY2UgcHJlc2VydmluZy4KLSAgICAgICAgICAgICAgICBpZiAoIHN0YXRlLmVtcHR5ICkKLSAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAnPicgKTsKLSAgICAgICAgICAgICAgICAvLyBJbmRlbnQgdGhpcyBlbGVtZW50IG9uIGEgbmV3IGxpbmUgaWYgdGhlIGZpcnN0Ci0gICAgICAgICAgICAgICAgLy8gY29udGVudCBvZiB0aGUgcGFyZW50IGVsZW1lbnQgb3IgaW1tZWRpYXRlbHkKLSAgICAgICAgICAgICAgICAvLyBmb2xsb3dpbmcgYW4gZWxlbWVudC4KLSAgICAgICAgICAgICAgICBpZiAoIF9pbmRlbnRpbmcgJiYgISBzdGF0ZS5wcmVzZXJ2ZVNwYWNlICYmCi0gICAgICAgICAgICAgICAgICAgICAoIHN0YXRlLmVtcHR5IHx8IHN0YXRlLmFmdGVyRWxlbWVudCApICkKLSAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIuYnJlYWtMaW5lKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBwcmVzZXJ2ZVNwYWNlID0gc3RhdGUucHJlc2VydmVTcGFjZTsKLQotICAgICAgICAgICAgLy8gRG8gbm90IGNoYW5nZSB0aGUgY3VycmVudCBlbGVtZW50IHN0YXRlIHlldC4KLSAgICAgICAgICAgIC8vIFRoaXMgb25seSBoYXBwZW5zIGluIGVuZEVsZW1lbnQoKS4KLQotICAgICAgICAgICAgLy8gQXMgcGVyIFNBWDIsIHRoZSBuYW1lc3BhY2UgVVJJIGlzIGFuIGVtcHR5IHN0cmluZyBpZiB0aGUgZWxlbWVudCBoYXMgbm8KLSAgICAgICAgICAgIC8vIG5hbWVzcGFjZSBVUkksIG9yIG5hbWVzcGFjZXMgaXMgdHVybmVkIG9mZi4gVGhlIGNoZWNrIGFnYWluc3QgbnVsbCBwcm90ZWN0cwotICAgICAgICAgICAgLy8gYWdhaW5zdCBicm9rZW4gU0FYIGltcGxlbWVudGF0aW9ucywgc28gSSd2ZSBsZWZ0IGl0IHRoZXJlLiAtIG1yZ2xhdmFzCi0gICAgICAgICAgICBib29sZWFuIGhhc05hbWVzcGFjZVVSSSA9IChuYW1lc3BhY2VVUkkgIT0gbnVsbCAmJiBuYW1lc3BhY2VVUkkubGVuZ3RoKCkgIT0gMCk7Ci0KLSAgICAgICAgICAgIC8vIFNBWDI6IHJhd05hbWUgKFFOYW1lKSBjb3VsZCBiZSBlbXB0eSBzdHJpbmcgaWYKLSAgICAgICAgICAgIC8vIG5hbWVzcGFjZS1wcmVmaXhlcyBwcm9wZXJ0eSBpcyBmYWxzZS4KLSAgICAgICAgICAgIGlmICggcmF3TmFtZSA9PSBudWxsIHx8IHJhd05hbWUubGVuZ3RoKCkgPT0gMCkgewotICAgICAgICAgICAgICAgIHJhd05hbWUgPSBsb2NhbE5hbWU7Ci0gICAgICAgICAgICAgICAgaWYgKCBoYXNOYW1lc3BhY2VVUkkgKSB7Ci0gICAgICAgICAgICAgICAgICAgIFN0cmluZyBwcmVmaXg7Ci0gICAgICAgICAgICAgICAgICAgIHByZWZpeCA9IGdldFByZWZpeCggbmFtZXNwYWNlVVJJICk7Ci0gICAgICAgICAgICAgICAgICAgIGlmICggcHJlZml4ICE9IG51bGwgJiYgcHJlZml4Lmxlbmd0aCgpICE9IDAgKQotICAgICAgICAgICAgICAgICAgICAgICAgcmF3TmFtZSA9IHByZWZpeCArICI6IiArIGxvY2FsTmFtZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgYWRkTlNBdHRyID0gdHJ1ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmICggIWhhc05hbWVzcGFjZVVSSSApCi0gICAgICAgICAgICAgICAgaHRtbE5hbWUgPSByYXdOYW1lOwotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgaWYgKCBuYW1lc3BhY2VVUkkuZXF1YWxzKCBYSFRNTE5hbWVzcGFjZSApIHx8Ci0gICAgICAgICAgICAgICAgICAgICAgICAoZlVzZXJYSFRNTE5hbWVzcGFjZSAhPSBudWxsICYmIGZVc2VyWEhUTUxOYW1lc3BhY2UuZXF1YWxzKG5hbWVzcGFjZVVSSSkpICkKLSAgICAgICAgICAgICAgICAgICAgaHRtbE5hbWUgPSBsb2NhbE5hbWU7Ci0gICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICBodG1sTmFtZSA9IG51bGw7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIFhIVE1MOiBlbGVtZW50IG5hbWVzIGFyZSBsb3dlciBjYXNlLCBET00gd2lsbCBiZSBkaWZmZXJlbnQKLSAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggJzwnICk7Ci0gICAgICAgICAgICBpZiAoIF94aHRtbCApCi0gICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCByYXdOYW1lLnRvTG93ZXJDYXNlKExvY2FsZS5FTkdMSVNIKSApOwotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggcmF3TmFtZSApOwotICAgICAgICAgICAgX3ByaW50ZXIuaW5kZW50KCk7Ci0KLSAgICAgICAgICAgIC8vIEZvciBlYWNoIGF0dHJpYnV0ZSBzZXJpYWxpemUgaXQncyBuYW1lIGFuZCB2YWx1ZSBhcyBvbmUgcGFydCwKLSAgICAgICAgICAgIC8vIHNlcGFyYXRlZCB3aXRoIGEgc3BhY2Ugc28gdGhlIGVsZW1lbnQgY2FuIGJlIGJyb2tlbiBvbgotICAgICAgICAgICAgLy8gbXVsdGlwbGUgbGluZXMuCi0gICAgICAgICAgICBpZiAoIGF0dHJzICE9IG51bGwgKSB7Ci0gICAgICAgICAgICAgICAgZm9yICggaSA9IDAgOyBpIDwgYXR0cnMuZ2V0TGVuZ3RoKCkgOyArK2kgKSB7Ci0gICAgICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50U3BhY2UoKTsKLSAgICAgICAgICAgICAgICAgICAgbmFtZSA9IGF0dHJzLmdldFFOYW1lKCBpICkudG9Mb3dlckNhc2UoTG9jYWxlLkVOR0xJU0gpOwotICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IGF0dHJzLmdldFZhbHVlKCBpICk7Ci0gICAgICAgICAgICAgICAgICAgIGlmICggX3hodG1sIHx8IGhhc05hbWVzcGFjZVVSSSApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIFhIVE1MOiBwcmludCBlbXB0eSBzdHJpbmcgZm9yIG51bGwgdmFsdWVzLgotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCB2YWx1ZSA9PSBudWxsICkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggbmFtZSApOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggIj1cIlwiIiApOwotICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoIG5hbWUgKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoICI9XCIiICk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnRFc2NhcGVkKCB2YWx1ZSApOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggJyInICk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBIVE1MOiBFbXB0eSB2YWx1ZXMgcHJpbnQgYXMgYXR0cmlidXRlIG5hbWUsIG5vIHZhbHVlLgotICAgICAgICAgICAgICAgICAgICAgICAgLy8gSFRNTDogVVJJIGF0dHJpYnV0ZXMgd2lsbCBwcmludCB1bmVzY2FwZWQKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmICggdmFsdWUgPT0gbnVsbCApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9ICIiOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCAhX2Zvcm1hdC5nZXRQcmVzZXJ2ZUVtcHR5QXR0cmlidXRlcygpICYmIHZhbHVlLmxlbmd0aCgpID09IDAgKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggbmFtZSApOwotICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoIEhUTUxkdGQuaXNVUkkoIHJhd05hbWUsIG5hbWUgKSApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoIG5hbWUgKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoICI9XCIiICk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCBlc2NhcGVVUkkoIHZhbHVlICkgKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoICciJyApOwotICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICggSFRNTGR0ZC5pc0Jvb2xlYW4oIHJhd05hbWUsIG5hbWUgKSApCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCBuYW1lICk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoIG5hbWUgKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoICI9XCIiICk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnRFc2NhcGVkKCB2YWx1ZSApOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggJyInICk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoIGh0bWxOYW1lICE9IG51bGwgJiYgSFRNTGR0ZC5pc1ByZXNlcnZlU3BhY2UoIGh0bWxOYW1lICkgKQotICAgICAgICAgICAgICAgIHByZXNlcnZlU3BhY2UgPSB0cnVlOwotCi0gICAgICAgICAgICBpZiAoIGFkZE5TQXR0ciApIHsKLSAgICAgICAgICAgICAgICBmb3IgKE1hcC5FbnRyeTxTdHJpbmcsIFN0cmluZz4gZW50cnkgOiBfcHJlZml4ZXMuZW50cnlTZXQoKSkgewotICAgICAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFNwYWNlKCk7Ci0gICAgICAgICAgICAgICAgICAgIHZhbHVlID0gZW50cnkuZ2V0S2V5KCk7IC8vVGhlIHByZWZpeGVzIG1hcCB1c2VzIHRoZSBVUkkgdmFsdWUgYXMga2V5LgotICAgICAgICAgICAgICAgICAgICBuYW1lID0gZW50cnkuZ2V0VmFsdWUoKTsgLy9hbmQgcHJlZml4IG5hbWUgYXMgdmFsdWUKLSAgICAgICAgICAgICAgICAgICAgaWYgKCBuYW1lLmxlbmd0aCgpID09IDAgKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoICJ4bWxucz1cIiIgKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHByaW50RXNjYXBlZCggdmFsdWUgKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggJyInICk7Ci0gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoICJ4bWxuczoiICk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoIG5hbWUgKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggIj1cIiIgKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHByaW50RXNjYXBlZCggdmFsdWUgKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggJyInICk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIE5vdyBpdCdzIHRpbWUgdG8gZW50ZXIgYSBuZXcgZWxlbWVudCBzdGF0ZQotICAgICAgICAgICAgLy8gd2l0aCB0aGUgdGFnIG5hbWUgYW5kIHNwYWNlIHByZXNlcnZpbmcuCi0gICAgICAgICAgICAvLyBXZSBzdGlsbCBkbyBub3QgY2hhbmdlIHRoZSBjdXJlbnQgZWxlbWVudCBzdGF0ZS4KLSAgICAgICAgICAgIHN0YXRlID0gZW50ZXJFbGVtZW50U3RhdGUoIG5hbWVzcGFjZVVSSSwgbG9jYWxOYW1lLCByYXdOYW1lLCBwcmVzZXJ2ZVNwYWNlICk7Ci0KLSAgICAgICAgICAgIC8vIFByZXZlbnRzIGxpbmUgYnJlYWtzIGluc2lkZSBBL1RECi0KLSAgICAgICAgICAgIGlmICggaHRtbE5hbWUgIT0gbnVsbCAmJiAoIGh0bWxOYW1lLmVxdWFsc0lnbm9yZUNhc2UoICJBIiApIHx8Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBodG1sTmFtZS5lcXVhbHNJZ25vcmVDYXNlKCAiVEQiICkgKSApIHsKLSAgICAgICAgICAgICAgICBzdGF0ZS5lbXB0eSA9IGZhbHNlOwotICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggJz4nICk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIEhhbmRsZSBTQ1JJUFQgYW5kIFNUWUxFIHNwZWNpZmljYWxseSBieSBjaGFuZ2luZyB0aGUKLSAgICAgICAgICAgIC8vIHN0YXRlIG9mIHRoZSBjdXJyZW50IGVsZW1lbnQgdG8gQ0RBVEEgKFhIVE1MKSBvcgotICAgICAgICAgICAgLy8gdW5lc2NhcGVkIChIVE1MKS4KLSAgICAgICAgICAgIGlmICggaHRtbE5hbWUgIT0gbnVsbCAmJiAoIHJhd05hbWUuZXF1YWxzSWdub3JlQ2FzZSggIlNDUklQVCIgKSB8fAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmF3TmFtZS5lcXVhbHNJZ25vcmVDYXNlKCAiU1RZTEUiICkgKSApIHsKLSAgICAgICAgICAgICAgICBpZiAoIF94aHRtbCApIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gWEhUTUw6IFByaW50IGNvbnRlbnRzIGFzIENEQVRBIHNlY3Rpb24KLSAgICAgICAgICAgICAgICAgICAgc3RhdGUuZG9DRGF0YSA9IHRydWU7Ci0gICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gSFRNTDogUHJpbnQgY29udGVudHMgdW5lc2NhcGVkCi0gICAgICAgICAgICAgICAgICAgIHN0YXRlLnVuZXNjYXBlZCA9IHRydWU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9IGNhdGNoICggSU9FeGNlcHRpb24gZXhjZXB0ICkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbiggZXhjZXB0ICk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIHB1YmxpYyB2b2lkIGVuZEVsZW1lbnQoIFN0cmluZyBuYW1lc3BhY2VVUkksIFN0cmluZyBsb2NhbE5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHJhd05hbWUgKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICB0cnkgewotICAgICAgICAgICAgZW5kRWxlbWVudElPKCBuYW1lc3BhY2VVUkksIGxvY2FsTmFtZSwgcmF3TmFtZSApOwotICAgICAgICB9IGNhdGNoICggSU9FeGNlcHRpb24gZXhjZXB0ICkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbiggZXhjZXB0ICk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIHB1YmxpYyB2b2lkIGVuZEVsZW1lbnRJTyggU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIGxvY2FsTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyByYXdOYW1lICkKLSAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uCi0gICAgewotICAgICAgICBFbGVtZW50U3RhdGUgc3RhdGU7Ci0gICAgICAgIFN0cmluZyAgICAgICBodG1sTmFtZTsKLQotICAgICAgICAvLyBXb3JrcyBtdWNoIGxpa2UgY29udGVudCgpIHdpdGggYWRkaXRpb25zIGZvciBjbG9zaW5nCi0gICAgICAgIC8vIGFuIGVsZW1lbnQuIE5vdGUgdGhlIGRpZmZlcmVudCBjaGVja3MgZm9yIHRoZSBjbG9zZWQKLSAgICAgICAgLy8gZWxlbWVudCdzIHN0YXRlIGFuZCB0aGUgcGFyZW50IGVsZW1lbnQncyBzdGF0ZS4KLSAgICAgICAgX3ByaW50ZXIudW5pbmRlbnQoKTsKLSAgICAgICAgc3RhdGUgPSBnZXRFbGVtZW50U3RhdGUoKTsKLQotICAgICAgICBpZiAoIHN0YXRlLm5hbWVzcGFjZVVSSSA9PSBudWxsIHx8IHN0YXRlLm5hbWVzcGFjZVVSSS5sZW5ndGgoKSA9PSAwICkKLSAgICAgICAgICAgIGh0bWxOYW1lID0gc3RhdGUucmF3TmFtZTsKLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBpZiAoIHN0YXRlLm5hbWVzcGFjZVVSSS5lcXVhbHMoIFhIVE1MTmFtZXNwYWNlICkgfHwKLSAgICAgICAgICAgICAgICAgICAgICAgIChmVXNlclhIVE1MTmFtZXNwYWNlICE9IG51bGwgJiYgZlVzZXJYSFRNTE5hbWVzcGFjZS5lcXVhbHMoc3RhdGUubmFtZXNwYWNlVVJJKSkgKQotICAgICAgICAgICAgICAgIGh0bWxOYW1lID0gc3RhdGUubG9jYWxOYW1lOwotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIGh0bWxOYW1lID0gbnVsbDsKLSAgICAgICAgfQotCi0gICAgICAgIGlmICggX3hodG1sKSB7Ci0gICAgICAgICAgICBpZiAoIHN0YXRlLmVtcHR5ICkgewotICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggIiAvPiIgKTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgLy8gTXVzdCBsZWF2ZSBDRGF0YSBzZWN0aW9uIGZpcnN0Ci0gICAgICAgICAgICAgICAgaWYgKCBzdGF0ZS5pbkNEYXRhICkKLSAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAiXV0+IiApOwotICAgICAgICAgICAgICAgIC8vIFhIVE1MOiBlbGVtZW50IG5hbWVzIGFyZSBsb3dlciBjYXNlLCBET00gd2lsbCBiZSBkaWZmZXJlbnQKLSAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoICI8LyIgKTsKLSAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoIHN0YXRlLnJhd05hbWUudG9Mb3dlckNhc2UoTG9jYWxlLkVOR0xJU0gpICk7Ci0gICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAnPicgKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIGlmICggc3RhdGUuZW1wdHkgKQotICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggJz4nICk7Ci0gICAgICAgICAgICAvLyBUaGlzIGVsZW1lbnQgaXMgbm90IGVtcHR5IGFuZCB0aGF0IGxhc3QgY29udGVudCB3YXMKLSAgICAgICAgICAgIC8vIGFub3RoZXIgZWxlbWVudCwgc28gcHJpbnQgYSBsaW5lIGJyZWFrIGJlZm9yZSB0aGF0Ci0gICAgICAgICAgICAvLyBsYXN0IGVsZW1lbnQgYW5kIHRoaXMgZWxlbWVudCdzIGNsb3NpbmcgdGFnLgotICAgICAgICAgICAgLy8gW2tlaXRoXSBQcm92aWRlZCB0aGlzIGlzIG5vdCBhbiBhbmNob3IuCi0gICAgICAgICAgICAvLyBIVE1MOiBzb21lIGVsZW1lbnRzIGRvIG5vdCBwcmludCBjbG9zaW5nIHRhZyAoZS5nLiBMSSkKLSAgICAgICAgICAgIGlmICggaHRtbE5hbWUgPT0gbnVsbCB8fCAhIEhUTUxkdGQuaXNPbmx5T3BlbmluZyggaHRtbE5hbWUgKSApIHsKLSAgICAgICAgICAgICAgICBpZiAoIF9pbmRlbnRpbmcgJiYgISBzdGF0ZS5wcmVzZXJ2ZVNwYWNlICYmIHN0YXRlLmFmdGVyRWxlbWVudCApCi0gICAgICAgICAgICAgICAgICAgIF9wcmludGVyLmJyZWFrTGluZSgpOwotICAgICAgICAgICAgICAgIC8vIE11c3QgbGVhdmUgQ0RhdGEgc2VjdGlvbiBmaXJzdCAoSWxsZWdhbCBpbiBIVE1MLCBidXQgc3RpbGwpCi0gICAgICAgICAgICAgICAgaWYgKCBzdGF0ZS5pbkNEYXRhICkKLSAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAiXV0+IiApOwotICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggIjwvIiApOwotICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggc3RhdGUucmF3TmFtZSApOwotICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggJz4nICk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgLy8gTGVhdmUgdGhlIGVsZW1lbnQgc3RhdGUgYW5kIHVwZGF0ZSB0aGF0IG9mIHRoZSBwYXJlbnQKLSAgICAgICAgLy8gKGlmIHdlJ3JlIG5vdCByb290KSB0byBub3QgZW1wdHkgYW5kIGFmdGVyIGVsZW1lbnQuCi0gICAgICAgIHN0YXRlID0gbGVhdmVFbGVtZW50U3RhdGUoKTsKLSAgICAgICAgLy8gVGVtcG9yYXJ5IGhhY2sgdG8gcHJldmVudCBsaW5lIGJyZWFrcyBpbnNpZGUgQS9URAotICAgICAgICBpZiAoIGh0bWxOYW1lID09IG51bGwgfHwgKCAhIGh0bWxOYW1lLmVxdWFsc0lnbm9yZUNhc2UoICJBIiApICYmCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICEgaHRtbE5hbWUuZXF1YWxzSWdub3JlQ2FzZSggIlREIiApICkgKQotCi0gICAgICAgICAgICBzdGF0ZS5hZnRlckVsZW1lbnQgPSB0cnVlOwotICAgICAgICBzdGF0ZS5lbXB0eSA9IGZhbHNlOwotICAgICAgICBpZiAoIGlzRG9jdW1lbnRTdGF0ZSgpICkKLSAgICAgICAgICAgIF9wcmludGVyLmZsdXNoKCk7Ci0gICAgfQotCi0KLSAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS8vCi0gICAgLy8gU0FYIGRvY3VtZW50IGhhbmRsZXIgc2VyaWFsaXppbmcgbWV0aG9kcyAvLwotICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLy8KLQotCi0gICAgcHVibGljIHZvaWQgY2hhcmFjdGVycyggY2hhcltdIGNoYXJzLCBpbnQgc3RhcnQsIGludCBsZW5ndGggKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBFbGVtZW50U3RhdGUgc3RhdGU7Ci0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIC8vIEhUTUw6IG5vIENEQVRBIHNlY3Rpb24KLSAgICAgICAgICAgIHN0YXRlID0gY29udGVudCgpOwotICAgICAgICAgICAgc3RhdGUuZG9DRGF0YSA9IGZhbHNlOwotICAgICAgICAgICAgc3VwZXIuY2hhcmFjdGVycyggY2hhcnMsIHN0YXJ0LCBsZW5ndGggKTsKLSAgICAgICAgfSBjYXRjaCAoIElPRXhjZXB0aW9uIGV4Y2VwdCApIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oIGV4Y2VwdCApOwotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQoIFN0cmluZyB0YWdOYW1lLCBBdHRyaWJ1dGVMaXN0IGF0dHJzICkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaW50ICAgICAgICAgIGk7Ci0gICAgICAgIGJvb2xlYW4gICAgICBwcmVzZXJ2ZVNwYWNlOwotICAgICAgICBFbGVtZW50U3RhdGUgc3RhdGU7Ci0gICAgICAgIFN0cmluZyAgICAgICBuYW1lOwotICAgICAgICBTdHJpbmcgICAgICAgdmFsdWU7Ci0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGlmICggX3ByaW50ZXIgPT0gbnVsbCApCi0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZSgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuU0VSSUFMSVpFUl9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICJOb1dyaXRlclN1cHBsaWVkIiwgbnVsbCkpOwotCi0KLSAgICAgICAgICAgIHN0YXRlID0gZ2V0RWxlbWVudFN0YXRlKCk7Ci0gICAgICAgICAgICBpZiAoIGlzRG9jdW1lbnRTdGF0ZSgpICkgewotICAgICAgICAgICAgICAgIC8vIElmIHRoaXMgaXMgdGhlIHJvb3QgZWxlbWVudCBoYW5kbGUgaXQgZGlmZmVyZW50bHkuCi0gICAgICAgICAgICAgICAgLy8gSWYgdGhlIGZpcnN0IHJvb3QgZWxlbWVudCBpbiB0aGUgZG9jdW1lbnQsIHNlcmlhbGl6ZQotICAgICAgICAgICAgICAgIC8vIHRoZSBkb2N1bWVudCdzIERPQ1RZUEUuIFNwYWNlIHByZXNlcnZpbmcgZGVmYXVsdHMKLSAgICAgICAgICAgICAgICAvLyB0byB0aGF0IG9mIHRoZSBvdXRwdXQgZm9ybWF0LgotICAgICAgICAgICAgICAgIGlmICggISBfc3RhcnRlZCApCi0gICAgICAgICAgICAgICAgICAgIHN0YXJ0RG9jdW1lbnQoIHRhZ05hbWUgKTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgLy8gRm9yIGFueSBvdGhlciBlbGVtZW50LCBpZiBmaXJzdCBpbiBwYXJlbnQsIHRoZW4KLSAgICAgICAgICAgICAgICAvLyBjbG9zZSBwYXJlbnQncyBvcGVuaW5nIHRhZyBhbmQgdXNlIHRoZSBwYXJuZXQncwotICAgICAgICAgICAgICAgIC8vIHNwYWNlIHByZXNlcnZpbmcuCi0gICAgICAgICAgICAgICAgaWYgKCBzdGF0ZS5lbXB0eSApCi0gICAgICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggJz4nICk7Ci0gICAgICAgICAgICAgICAgLy8gSW5kZW50IHRoaXMgZWxlbWVudCBvbiBhIG5ldyBsaW5lIGlmIHRoZSBmaXJzdAotICAgICAgICAgICAgICAgIC8vIGNvbnRlbnQgb2YgdGhlIHBhcmVudCBlbGVtZW50IG9yIGltbWVkaWF0ZWx5Ci0gICAgICAgICAgICAgICAgLy8gZm9sbG93aW5nIGFuIGVsZW1lbnQuCi0gICAgICAgICAgICAgICAgaWYgKCBfaW5kZW50aW5nICYmICEgc3RhdGUucHJlc2VydmVTcGFjZSAmJgotICAgICAgICAgICAgICAgICAgICAgKCBzdGF0ZS5lbXB0eSB8fCBzdGF0ZS5hZnRlckVsZW1lbnQgKSApCi0gICAgICAgICAgICAgICAgICAgIF9wcmludGVyLmJyZWFrTGluZSgpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcHJlc2VydmVTcGFjZSA9IHN0YXRlLnByZXNlcnZlU3BhY2U7Ci0KLSAgICAgICAgICAgIC8vIERvIG5vdCBjaGFuZ2UgdGhlIGN1cnJlbnQgZWxlbWVudCBzdGF0ZSB5ZXQuCi0gICAgICAgICAgICAvLyBUaGlzIG9ubHkgaGFwcGVucyBpbiBlbmRFbGVtZW50KCkuCi0KLSAgICAgICAgICAgIC8vIFhIVE1MOiBlbGVtZW50IG5hbWVzIGFyZSBsb3dlciBjYXNlLCBET00gd2lsbCBiZSBkaWZmZXJlbnQKLSAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggJzwnICk7Ci0gICAgICAgICAgICBpZiAoIF94aHRtbCApCi0gICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCB0YWdOYW1lLnRvTG93ZXJDYXNlKExvY2FsZS5FTkdMSVNIKSApOwotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggdGFnTmFtZSApOwotICAgICAgICAgICAgX3ByaW50ZXIuaW5kZW50KCk7Ci0KLSAgICAgICAgICAgIC8vIEZvciBlYWNoIGF0dHJpYnV0ZSBzZXJpYWxpemUgaXQncyBuYW1lIGFuZCB2YWx1ZSBhcyBvbmUgcGFydCwKLSAgICAgICAgICAgIC8vIHNlcGFyYXRlZCB3aXRoIGEgc3BhY2Ugc28gdGhlIGVsZW1lbnQgY2FuIGJlIGJyb2tlbiBvbgotICAgICAgICAgICAgLy8gbXVsdGlwbGUgbGluZXMuCi0gICAgICAgICAgICBpZiAoIGF0dHJzICE9IG51bGwgKSB7Ci0gICAgICAgICAgICAgICAgZm9yICggaSA9IDAgOyBpIDwgYXR0cnMuZ2V0TGVuZ3RoKCkgOyArK2kgKSB7Ci0gICAgICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50U3BhY2UoKTsKLSAgICAgICAgICAgICAgICAgICAgbmFtZSA9IGF0dHJzLmdldE5hbWUoIGkgKS50b0xvd2VyQ2FzZShMb2NhbGUuRU5HTElTSCk7Ci0gICAgICAgICAgICAgICAgICAgIHZhbHVlID0gYXR0cnMuZ2V0VmFsdWUoIGkgKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKCBfeGh0bWwgKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBYSFRNTDogcHJpbnQgZW1wdHkgc3RyaW5nIGZvciBudWxsIHZhbHVlcy4KLSAgICAgICAgICAgICAgICAgICAgICAgIGlmICggdmFsdWUgPT0gbnVsbCApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoIG5hbWUgKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoICI9XCJcIiIgKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCBuYW1lICk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAiPVwiIiApOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaW50RXNjYXBlZCggdmFsdWUgKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoICciJyApOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gSFRNTDogRW1wdHkgdmFsdWVzIHByaW50IGFzIGF0dHJpYnV0ZSBuYW1lLCBubyB2YWx1ZS4KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIEhUTUw6IFVSSSBhdHRyaWJ1dGVzIHdpbGwgcHJpbnQgdW5lc2NhcGVkCi0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIHZhbHVlID09IG51bGwgKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSAiIjsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGlmICggIV9mb3JtYXQuZ2V0UHJlc2VydmVFbXB0eUF0dHJpYnV0ZXMoKSAmJiB2YWx1ZS5sZW5ndGgoKSA9PSAwICkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoIG5hbWUgKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKCBIVE1MZHRkLmlzVVJJKCB0YWdOYW1lLCBuYW1lICkgKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCBuYW1lICk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAiPVwiIiApOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggZXNjYXBlVVJJKCB2YWx1ZSApICk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAnIicgKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIEhUTUxkdGQuaXNCb29sZWFuKCB0YWdOYW1lLCBuYW1lICkgKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggbmFtZSApOwotICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCBuYW1lICk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAiPVwiIiApOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaW50RXNjYXBlZCggdmFsdWUgKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoICciJyApOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKCBIVE1MZHRkLmlzUHJlc2VydmVTcGFjZSggdGFnTmFtZSApICkKLSAgICAgICAgICAgICAgICBwcmVzZXJ2ZVNwYWNlID0gdHJ1ZTsKLQotICAgICAgICAgICAgLy8gTm93IGl0J3MgdGltZSB0byBlbnRlciBhIG5ldyBlbGVtZW50IHN0YXRlCi0gICAgICAgICAgICAvLyB3aXRoIHRoZSB0YWcgbmFtZSBhbmQgc3BhY2UgcHJlc2VydmluZy4KLSAgICAgICAgICAgIC8vIFdlIHN0aWxsIGRvIG5vdCBjaGFuZ2UgdGhlIGN1cmVudCBlbGVtZW50IHN0YXRlLgotICAgICAgICAgICAgc3RhdGUgPSBlbnRlckVsZW1lbnRTdGF0ZSggbnVsbCwgbnVsbCwgdGFnTmFtZSwgcHJlc2VydmVTcGFjZSApOwotCi0gICAgICAgICAgICAvLyBQcmV2ZW50cyBsaW5lIGJyZWFrcyBpbnNpZGUgQS9URAotICAgICAgICAgICAgaWYgKCB0YWdOYW1lLmVxdWFsc0lnbm9yZUNhc2UoICJBIiApIHx8IHRhZ05hbWUuZXF1YWxzSWdub3JlQ2FzZSggIlREIiApICkgewotICAgICAgICAgICAgICAgIHN0YXRlLmVtcHR5ID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAnPicgKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gSGFuZGxlIFNDUklQVCBhbmQgU1RZTEUgc3BlY2lmaWNhbGx5IGJ5IGNoYW5naW5nIHRoZQotICAgICAgICAgICAgLy8gc3RhdGUgb2YgdGhlIGN1cnJlbnQgZWxlbWVudCB0byBDREFUQSAoWEhUTUwpIG9yCi0gICAgICAgICAgICAvLyB1bmVzY2FwZWQgKEhUTUwpLgotICAgICAgICAgICAgaWYgKCB0YWdOYW1lLmVxdWFsc0lnbm9yZUNhc2UoICJTQ1JJUFQiICkgfHwKLSAgICAgICAgICAgICAgICAgdGFnTmFtZS5lcXVhbHNJZ25vcmVDYXNlKCAiU1RZTEUiICkgKSB7Ci0gICAgICAgICAgICAgICAgaWYgKCBfeGh0bWwgKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIFhIVE1MOiBQcmludCBjb250ZW50cyBhcyBDREFUQSBzZWN0aW9uCi0gICAgICAgICAgICAgICAgICAgIHN0YXRlLmRvQ0RhdGEgPSB0cnVlOwotICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIEhUTUw6IFByaW50IGNvbnRlbnRzIHVuZXNjYXBlZAotICAgICAgICAgICAgICAgICAgICBzdGF0ZS51bmVzY2FwZWQgPSB0cnVlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfSBjYXRjaCAoIElPRXhjZXB0aW9uIGV4Y2VwdCApIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oIGV4Y2VwdCApOwotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgdm9pZCBlbmRFbGVtZW50KCBTdHJpbmcgdGFnTmFtZSApCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGVuZEVsZW1lbnQoIG51bGwsIG51bGwsIHRhZ05hbWUgKTsKLSAgICB9Ci0KLQotICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLy8KLSAgICAvLyBHZW5lcmljIG5vZGUgc2VyaWFsaXppbmcgbWV0aG9kcyBtZXRob2RzIC8vCi0gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0vLwotCi0KLSAgICAvKioKLSAgICAgKiBDYWxsZWQgdG8gc2VyaWFsaXplIHRoZSBkb2N1bWVudCdzIERPQ1RZUEUgYnkgdGhlIHJvb3QgZWxlbWVudC4KLSAgICAgKiBUaGUgZG9jdW1lbnQgdHlwZSBkZWNsYXJhdGlvbiBtdXN0IG5hbWUgdGhlIHJvb3QgZWxlbWVudCwKLSAgICAgKiBidXQgdGhlIHJvb3QgZWxlbWVudCBpcyBvbmx5IGtub3duIHdoZW4gdGhhdCBlbGVtZW50IGlzIHNlcmlhbGl6ZWQsCi0gICAgICogYW5kIG5vdCBhdCB0aGUgc3RhcnQgb2YgdGhlIGRvY3VtZW50LgotICAgICAqIDxwPgotICAgICAqIFRoaXMgbWV0aG9kIHdpbGwgY2hlY2sgaWYgaXQgaGFzIG5vdCBiZWVuIGNhbGxlZCBiZWZvcmUgKHtAbGluayAjX3N0YXJ0ZWR9KSwKLSAgICAgKiB3aWxsIHNlcmlhbGl6ZSB0aGUgZG9jdW1lbnQgdHlwZSBkZWNsYXJhdGlvbiwgYW5kIHdpbGwgc2VyaWFsaXplIGFsbAotICAgICAqIHByZS1yb290IGNvbW1lbnRzIGFuZCBQSXMgdGhhdCB3ZXJlIGFjY3VtdWxhdGVkIGluIHRoZSBkb2N1bWVudAotICAgICAqIChzZWUge0BsaW5rICNzZXJpYWxpemVQcmVSb290fSkuIFByZS1yb290IHdpbGwgYmUgc2VyaWFsaXplZCBldmVuIGlmCi0gICAgICogdGhpcyBpcyBub3QgdGhlIGZpcnN0IHJvb3QgZWxlbWVudCBvZiB0aGUgZG9jdW1lbnQuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgc3RhcnREb2N1bWVudCggU3RyaW5nIHJvb3RUYWdOYW1lICkKLSAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uCi0gICAgewotICAgICAgICBTdHJpbmdCdWZmZXIgYnVmZmVyOwotCi0gICAgICAgIC8vIE5vdCBzdXBwb3J0ZWQgaW4gSFRNTC9YSFRNTCwgYnV0IHdlIHN0aWxsIGhhdmUgdG8gc3dpdGNoCi0gICAgICAgIC8vIG91dCBvZiBEVEQgbW9kZS4KLSAgICAgICAgX3ByaW50ZXIubGVhdmVEVEQoKTsKLSAgICAgICAgaWYgKCAhIF9zdGFydGVkICkgewotICAgICAgICAgICAgLy8gSWYgdGhlIHB1YmxpYyBhbmQgc3lzdGVtIGlkZW50aWZpZXJzIHdlcmUgbm90IHNwZWNpZmllZAotICAgICAgICAgICAgLy8gaW4gdGhlIG91dHB1dCBmb3JtYXQsIHVzZSB0aGUgYXBwcm9wcmlhdGUgb25lcyBmb3IgSFRNTAotICAgICAgICAgICAgLy8gb3IgWEhUTUwuCi0gICAgICAgICAgICBpZiAoIF9kb2NUeXBlUHVibGljSWQgPT0gbnVsbCAmJiBfZG9jVHlwZVN5c3RlbUlkID09IG51bGwgKSB7Ci0gICAgICAgICAgICAgICAgaWYgKCBfeGh0bWwgKSB7Ci0gICAgICAgICAgICAgICAgICAgIF9kb2NUeXBlUHVibGljSWQgPSBIVE1MZHRkLlhIVE1MUHVibGljSWQ7Ci0gICAgICAgICAgICAgICAgICAgIF9kb2NUeXBlU3lzdGVtSWQgPSBIVE1MZHRkLlhIVE1MU3lzdGVtSWQ7Ci0gICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgX2RvY1R5cGVQdWJsaWNJZCA9IEhUTUxkdGQuSFRNTFB1YmxpY0lkOwotICAgICAgICAgICAgICAgICAgICBfZG9jVHlwZVN5c3RlbUlkID0gSFRNTGR0ZC5IVE1MU3lzdGVtSWQ7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAoICEgX2Zvcm1hdC5nZXRPbWl0RG9jdW1lbnRUeXBlKCkgKSB7Ci0gICAgICAgICAgICAgICAgLy8gWEhUTUw6IElmIHB1YmxpYyBpZGVudGlmaWVyIGFuZCBzeXN0ZW0gaWRlbnRpZmllcgotICAgICAgICAgICAgICAgIC8vICBzcGVjaWZpZWQsIHByaW50IHRoZW0sIGVsc2UgcHJpbnQganVzdCBzeXN0ZW0gaWRlbnRpZmllcgotICAgICAgICAgICAgICAgIC8vIEhUTUw6IElmIHB1YmxpYyBpZGVudGlmaWVyIHNwZWNpZmllZCwgcHJpbnQgaXQgd2l0aAotICAgICAgICAgICAgICAgIC8vICBzeXN0ZW0gaWRlbnRpZmllciwgaWYgc3BlY2lmaWVkLgotICAgICAgICAgICAgICAgIC8vIFhIVE1MIHJlcXVpcmVzIHRoYXQgYWxsIGVsZW1lbnQgbmFtZXMgYXJlIGxvd2VyIGNhc2UsIHNvIHRoZQotICAgICAgICAgICAgICAgIC8vIHJvb3Qgb24gdGhlIERPQ1RZUEUgbXVzdCBiZSAnaHRtbCcuIC0gbXJnbGF2YXMKLSAgICAgICAgICAgICAgICBpZiAoIF9kb2NUeXBlUHVibGljSWQgIT0gbnVsbCAmJiAoICEgX3hodG1sIHx8IF9kb2NUeXBlU3lzdGVtSWQgIT0gbnVsbCApICApIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKF94aHRtbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAiPCFET0NUWVBFIGh0bWwgUFVCTElDICIgKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggIjwhRE9DVFlQRSBIVE1MIFBVQkxJQyAiICk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgcHJpbnREb2N0eXBlVVJMKCBfZG9jVHlwZVB1YmxpY0lkICk7Ci0gICAgICAgICAgICAgICAgICAgIGlmICggX2RvY1R5cGVTeXN0ZW1JZCAhPSBudWxsICkgewotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCBfaW5kZW50aW5nICkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9wcmludGVyLmJyZWFrTGluZSgpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggIiAgICAgICAgICAgICAgICAgICAgICAiICk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UKLSAgICAgICAgICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggJyAnICk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBwcmludERvY3R5cGVVUkwoIF9kb2NUeXBlU3lzdGVtSWQgKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoICc+JyApOwotICAgICAgICAgICAgICAgICAgICBfcHJpbnRlci5icmVha0xpbmUoKTsKLSAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCBfZG9jVHlwZVN5c3RlbUlkICE9IG51bGwgKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChfeGh0bWwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggIjwhRE9DVFlQRSBodG1sIFNZU1RFTSAiICk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoICI8IURPQ1RZUEUgSFRNTCBTWVNURU0gIiApOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIHByaW50RG9jdHlwZVVSTCggX2RvY1R5cGVTeXN0ZW1JZCApOwotICAgICAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoICc+JyApOwotICAgICAgICAgICAgICAgICAgICBfcHJpbnRlci5icmVha0xpbmUoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBfc3RhcnRlZCA9IHRydWU7Ci0gICAgICAgIC8vIEFsd2F5cyBzZXJpYWxpemUgdGhlc2UsIGV2ZW4gaWYgbm90IHRlIGZpcnN0IHJvb3QgZWxlbWVudC4KLSAgICAgICAgc2VyaWFsaXplUHJlUm9vdCgpOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogQ2FsbGVkIHRvIHNlcmlhbGl6ZSBhIERPTSBlbGVtZW50LiBFcXVpdmFsZW50IHRvIGNhbGxpbmcge0BsaW5rCi0gICAgICogI3N0YXJ0RWxlbWVudH0sIHtAbGluayAjZW5kRWxlbWVudH0gYW5kIHNlcmlhbGl6aW5nIGV2ZXJ5dGhpbmcKLSAgICAgKiBpbmJldHdlZW4sIGJ1dCBiZXR0ZXIgb3B0aW1pemVkLgotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIHNlcmlhbGl6ZUVsZW1lbnQoIEVsZW1lbnQgZWxlbSApCi0gICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgQXR0ciAgICAgICAgIGF0dHI7Ci0gICAgICAgIE5hbWVkTm9kZU1hcCBhdHRyTWFwOwotICAgICAgICBpbnQgICAgICAgICAgaTsKLSAgICAgICAgTm9kZSAgICAgICAgIGNoaWxkOwotICAgICAgICBFbGVtZW50U3RhdGUgc3RhdGU7Ci0gICAgICAgIGJvb2xlYW4gICAgICBwcmVzZXJ2ZVNwYWNlOwotICAgICAgICBTdHJpbmcgICAgICAgbmFtZTsKLSAgICAgICAgU3RyaW5nICAgICAgIHZhbHVlOwotICAgICAgICBTdHJpbmcgICAgICAgdGFnTmFtZTsKLQotICAgICAgICB0YWdOYW1lID0gZWxlbS5nZXRUYWdOYW1lKCk7Ci0gICAgICAgIHN0YXRlID0gZ2V0RWxlbWVudFN0YXRlKCk7Ci0gICAgICAgIGlmICggaXNEb2N1bWVudFN0YXRlKCkgKSB7Ci0gICAgICAgICAgICAvLyBJZiB0aGlzIGlzIHRoZSByb290IGVsZW1lbnQgaGFuZGxlIGl0IGRpZmZlcmVudGx5LgotICAgICAgICAgICAgLy8gSWYgdGhlIGZpcnN0IHJvb3QgZWxlbWVudCBpbiB0aGUgZG9jdW1lbnQsIHNlcmlhbGl6ZQotICAgICAgICAgICAgLy8gdGhlIGRvY3VtZW50J3MgRE9DVFlQRS4gU3BhY2UgcHJlc2VydmluZyBkZWZhdWx0cwotICAgICAgICAgICAgLy8gdG8gdGhhdCBvZiB0aGUgb3V0cHV0IGZvcm1hdC4KLSAgICAgICAgICAgIGlmICggISBfc3RhcnRlZCApCi0gICAgICAgICAgICAgICAgc3RhcnREb2N1bWVudCggdGFnTmFtZSApOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgLy8gRm9yIGFueSBvdGhlciBlbGVtZW50LCBpZiBmaXJzdCBpbiBwYXJlbnQsIHRoZW4KLSAgICAgICAgICAgIC8vIGNsb3NlIHBhcmVudCdzIG9wZW5pbmcgdGFnIGFuZCB1c2UgdGhlIHBhcm5ldCdzCi0gICAgICAgICAgICAvLyBzcGFjZSBwcmVzZXJ2aW5nLgotICAgICAgICAgICAgaWYgKCBzdGF0ZS5lbXB0eSApCi0gICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAnPicgKTsKLSAgICAgICAgICAgIC8vIEluZGVudCB0aGlzIGVsZW1lbnQgb24gYSBuZXcgbGluZSBpZiB0aGUgZmlyc3QKLSAgICAgICAgICAgIC8vIGNvbnRlbnQgb2YgdGhlIHBhcmVudCBlbGVtZW50IG9yIGltbWVkaWF0ZWx5Ci0gICAgICAgICAgICAvLyBmb2xsb3dpbmcgYW4gZWxlbWVudC4KLSAgICAgICAgICAgIGlmICggX2luZGVudGluZyAmJiAhIHN0YXRlLnByZXNlcnZlU3BhY2UgJiYKLSAgICAgICAgICAgICAgICAgKCBzdGF0ZS5lbXB0eSB8fCBzdGF0ZS5hZnRlckVsZW1lbnQgKSApCi0gICAgICAgICAgICAgICAgX3ByaW50ZXIuYnJlYWtMaW5lKCk7Ci0gICAgICAgIH0KLSAgICAgICAgcHJlc2VydmVTcGFjZSA9IHN0YXRlLnByZXNlcnZlU3BhY2U7Ci0KLSAgICAgICAgLy8gRG8gbm90IGNoYW5nZSB0aGUgY3VycmVudCBlbGVtZW50IHN0YXRlIHlldC4KLSAgICAgICAgLy8gVGhpcyBvbmx5IGhhcHBlbnMgaW4gZW5kRWxlbWVudCgpLgotCi0gICAgICAgIC8vIFhIVE1MOiBlbGVtZW50IG5hbWVzIGFyZSBsb3dlciBjYXNlLCBET00gd2lsbCBiZSBkaWZmZXJlbnQKLSAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAnPCcgKTsKLSAgICAgICAgaWYgKCBfeGh0bWwgKQotICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCB0YWdOYW1lLnRvTG93ZXJDYXNlKExvY2FsZS5FTkdMSVNIKSApOwotICAgICAgICBlbHNlCi0gICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoIHRhZ05hbWUgKTsKLSAgICAgICAgX3ByaW50ZXIuaW5kZW50KCk7Ci0KLSAgICAgICAgLy8gTG9va3VwIHRoZSBlbGVtZW50J3MgYXR0cmlidXRlLCBidXQgb25seSBwcmludCBzcGVjaWZpZWQKLSAgICAgICAgLy8gYXR0cmlidXRlcy4gKFVuc3BlY2lmaWVkIGF0dHJpYnV0ZXMgYXJlIGRlcml2ZWQgZnJvbSB0aGUgRFRELgotICAgICAgICAvLyBGb3IgZWFjaCBhdHRyaWJ1dGUgcHJpbnQgaXQncyBuYW1lIGFuZCB2YWx1ZSBhcyBvbmUgcGFydCwKLSAgICAgICAgLy8gc2VwYXJhdGVkIHdpdGggYSBzcGFjZSBzbyB0aGUgZWxlbWVudCBjYW4gYmUgYnJva2VuIG9uCi0gICAgICAgIC8vIG11bHRpcGxlIGxpbmVzLgotICAgICAgICBhdHRyTWFwID0gZWxlbS5nZXRBdHRyaWJ1dGVzKCk7Ci0gICAgICAgIGlmICggYXR0ck1hcCAhPSBudWxsICkgewotICAgICAgICAgICAgZm9yICggaSA9IDAgOyBpIDwgYXR0ck1hcC5nZXRMZW5ndGgoKSA7ICsraSApIHsKLSAgICAgICAgICAgICAgICBhdHRyID0gKEF0dHIpIGF0dHJNYXAuaXRlbSggaSApOwotICAgICAgICAgICAgICAgIG5hbWUgPSBhdHRyLmdldE5hbWUoKS50b0xvd2VyQ2FzZShMb2NhbGUuRU5HTElTSCk7Ci0gICAgICAgICAgICAgICAgdmFsdWUgPSBhdHRyLmdldFZhbHVlKCk7Ci0gICAgICAgICAgICAgICAgaWYgKCBhdHRyLmdldFNwZWNpZmllZCgpICkgewotICAgICAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFNwYWNlKCk7Ci0gICAgICAgICAgICAgICAgICAgIGlmICggX3hodG1sICkgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gWEhUTUw6IHByaW50IGVtcHR5IHN0cmluZyBmb3IgbnVsbCB2YWx1ZXMuCi0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIHZhbHVlID09IG51bGwgKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCBuYW1lICk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAiPVwiXCIiICk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggbmFtZSApOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggIj1cIiIgKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmludEVzY2FwZWQoIHZhbHVlICk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAnIicgKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIEhUTUw6IEVtcHR5IHZhbHVlcyBwcmludCBhcyBhdHRyaWJ1dGUgbmFtZSwgbm8gdmFsdWUuCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBIVE1MOiBVUkkgYXR0cmlidXRlcyB3aWxsIHByaW50IHVuZXNjYXBlZAotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCB2YWx1ZSA9PSBudWxsICkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlID0gIiI7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoICFfZm9ybWF0LmdldFByZXNlcnZlRW1wdHlBdHRyaWJ1dGVzKCkgJiYgdmFsdWUubGVuZ3RoKCkgPT0gMCApCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCBuYW1lICk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICggSFRNTGR0ZC5pc1VSSSggdGFnTmFtZSwgbmFtZSApICkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggbmFtZSApOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggIj1cIiIgKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoIGVzY2FwZVVSSSggdmFsdWUgKSApOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggJyInICk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCBIVE1MZHRkLmlzQm9vbGVhbiggdGFnTmFtZSwgbmFtZSApICkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoIG5hbWUgKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggbmFtZSApOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggIj1cIiIgKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmludEVzY2FwZWQoIHZhbHVlICk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAnIicgKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBpZiAoIEhUTUxkdGQuaXNQcmVzZXJ2ZVNwYWNlKCB0YWdOYW1lICkgKQotICAgICAgICAgICAgcHJlc2VydmVTcGFjZSA9IHRydWU7Ci0KLSAgICAgICAgLy8gSWYgZWxlbWVudCBoYXMgY2hpbGRyZW4sIG9yIGlmIGVsZW1lbnQgaXMgbm90IGFuIGVtcHR5IHRhZywKLSAgICAgICAgLy8gc2VyaWFsaXplIGFuIG9wZW5pbmcgdGFnLgotICAgICAgICBpZiAoIGVsZW0uaGFzQ2hpbGROb2RlcygpIHx8ICEgSFRNTGR0ZC5pc0VtcHR5VGFnKCB0YWdOYW1lICkgKSB7Ci0gICAgICAgICAgICAvLyBFbnRlciBhbiBlbGVtZW50IHN0YXRlLCBhbmQgc2VyaWFsaXplIHRoZSBjaGlsZHJlbgotICAgICAgICAgICAgLy8gb25lIGJ5IG9uZS4gRmluYWxseSwgZW5kIHRoZSBlbGVtZW50LgotICAgICAgICAgICAgc3RhdGUgPSBlbnRlckVsZW1lbnRTdGF0ZSggbnVsbCwgbnVsbCwgdGFnTmFtZSwgcHJlc2VydmVTcGFjZSApOwotCi0gICAgICAgICAgICAvLyBQcmV2ZW50cyBsaW5lIGJyZWFrcyBpbnNpZGUgQS9URAotICAgICAgICAgICAgaWYgKCB0YWdOYW1lLmVxdWFsc0lnbm9yZUNhc2UoICJBIiApIHx8IHRhZ05hbWUuZXF1YWxzSWdub3JlQ2FzZSggIlREIiApICkgewotICAgICAgICAgICAgICAgIHN0YXRlLmVtcHR5ID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAnPicgKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gSGFuZGxlIFNDUklQVCBhbmQgU1RZTEUgc3BlY2lmaWNhbGx5IGJ5IGNoYW5naW5nIHRoZQotICAgICAgICAgICAgLy8gc3RhdGUgb2YgdGhlIGN1cnJlbnQgZWxlbWVudCB0byBDREFUQSAoWEhUTUwpIG9yCi0gICAgICAgICAgICAvLyB1bmVzY2FwZWQgKEhUTUwpLgotICAgICAgICAgICAgaWYgKCB0YWdOYW1lLmVxdWFsc0lnbm9yZUNhc2UoICJTQ1JJUFQiICkgfHwKLSAgICAgICAgICAgICAgICAgdGFnTmFtZS5lcXVhbHNJZ25vcmVDYXNlKCAiU1RZTEUiICkgKSB7Ci0gICAgICAgICAgICAgICAgaWYgKCBfeGh0bWwgKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIFhIVE1MOiBQcmludCBjb250ZW50cyBhcyBDREFUQSBzZWN0aW9uCi0gICAgICAgICAgICAgICAgICAgIHN0YXRlLmRvQ0RhdGEgPSB0cnVlOwotICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIEhUTUw6IFByaW50IGNvbnRlbnRzIHVuZXNjYXBlZAotICAgICAgICAgICAgICAgICAgICBzdGF0ZS51bmVzY2FwZWQgPSB0cnVlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNoaWxkID0gZWxlbS5nZXRGaXJzdENoaWxkKCk7Ci0gICAgICAgICAgICB3aGlsZSAoIGNoaWxkICE9IG51bGwgKSB7Ci0gICAgICAgICAgICAgICAgc2VyaWFsaXplTm9kZSggY2hpbGQgKTsKLSAgICAgICAgICAgICAgICBjaGlsZCA9IGNoaWxkLmdldE5leHRTaWJsaW5nKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbmRFbGVtZW50SU8oIG51bGwsIG51bGwsIHRhZ05hbWUgKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIF9wcmludGVyLnVuaW5kZW50KCk7Ci0gICAgICAgICAgICAvLyBYSFRNTDogQ2xvc2UgZW1wdHkgdGFnIHdpdGggJyAvPicgc28gaXQncyBYTUwgYW5kIEhUTUwgY29tcGF0aWJsZS4KLSAgICAgICAgICAgIC8vIEhUTUw6IEVtcHR5IHRhZ3MgYXJlIGRlZmluZWQgYXMgc3VjaCBpbiBEVEQgbm8gaW4gZG9jdW1lbnQuCi0gICAgICAgICAgICBpZiAoIF94aHRtbCApCi0gICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAiIC8+IiApOwotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggJz4nICk7Ci0gICAgICAgICAgICAvLyBBZnRlciBlbGVtZW50IGJ1dCBwYXJlbnQgZWxlbWVudCBpcyBubyBsb25nZXIgZW1wdHkuCi0gICAgICAgICAgICBzdGF0ZS5hZnRlckVsZW1lbnQgPSB0cnVlOwotICAgICAgICAgICAgc3RhdGUuZW1wdHkgPSBmYWxzZTsKLSAgICAgICAgICAgIGlmICggaXNEb2N1bWVudFN0YXRlKCkgKQotICAgICAgICAgICAgICAgIF9wcmludGVyLmZsdXNoKCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotCi0gICAgcHJvdGVjdGVkIHZvaWQgY2hhcmFjdGVycyggU3RyaW5nIHRleHQgKQotICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIEVsZW1lbnRTdGF0ZSBzdGF0ZTsKLQotICAgICAgICAvLyBIVE1MOiBubyBDREFUQSBzZWN0aW9uCi0gICAgICAgIHN0YXRlID0gY29udGVudCgpOwotICAgICAgICBzdXBlci5jaGFyYWN0ZXJzKCB0ZXh0ICk7Ci0gICAgfQotCi0KLSAgICBwcm90ZWN0ZWQgU3RyaW5nIGdldEVudGl0eVJlZiggaW50IGNoICkKLSAgICB7Ci0gICAgICAgIHJldHVybiBIVE1MZHRkLmZyb21DaGFyKCBjaCApOwotICAgIH0KLQotCi0gICAgcHJvdGVjdGVkIFN0cmluZyBlc2NhcGVVUkkoIFN0cmluZyB1cmkgKQotICAgIHsKLSAgICAgICAgaW50IGluZGV4OwotCi0gICAgICAgIC8vIFhYWCAgQXBwYXJlbnRseSBOZXRzY2FwZSBkb2Vzbid0IGxpa2UgaWYgd2UgZXNjYXBlIHRoZSBVUkkKLSAgICAgICAgLy8gICAgICB1c2luZyAlbm4sIHNvIHdlIGxlYXZlIGl0IGFzIGlzLCBqdXN0IHJlbW92ZSBhbnkgcXVvdGVzLgotICAgICAgICBpbmRleCA9IHVyaS5pbmRleE9mKCAiXCIiICk7Ci0gICAgICAgIGlmICggaW5kZXggPj0gMCApCi0gICAgICAgICAgICByZXR1cm4gdXJpLnN1YnN0cmluZyggMCwgaW5kZXggKTsKLSAgICAgICAgZWxzZQotICAgICAgICAgICAgcmV0dXJuIHVyaTsKLSAgICB9Ci0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplL0hUTUxkdGQuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZS9IVE1MZHRkLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDZhMDA4MTguLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplL0hUTUxkdGQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDU1NiArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDE1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICovCi0vKgotICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCi0gKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKLSAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KLSAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCi0gKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAotICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotLy8gQXVnIDIxLCAyMDAwOgotLy8gICBGaXhlZCBidWcgaW4gaXNFbGVtZW50IGFuZCBtYWRlIEhUTUxkdGQgcHVibGljLgotLy8gICBDb250cmlidXRlZCBieSBFcmljIFNDSEFFRkZFUiIgPGVzY2hhZWZmZXJAcG9zdGVyY29uc2VpbC5jb20+Ci0KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZTsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tLkRPTU1lc3NhZ2VGb3JtYXR0ZXI7Ci1pbXBvcnQgamF2YS5pby5CdWZmZXJlZFJlYWRlcjsKLWltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW1SZWFkZXI7Ci1pbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7Ci1pbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKLWltcG9ydCBqYXZhLnV0aWwuTWFwOwotCi0KLS8qKgotICogVXRpbGl0eSBjbGFzcyBmb3IgYWNjZXNzaW5nIGluZm9ybWF0aW9uIHNwZWNpZmljIHRvIEhUTUwgZG9jdW1lbnRzLgotICogVGhlIEhUTUwgRFREIGlzIGV4cHJlc3NlZCBhcyB0aHJlZSB1dGlsaXR5IGZ1bmN0aW9uIGdyb3Vwcy4gVHdvIG1ldGhvZHMKLSAqIGFsbG93IGZvciBjaGVja2luZyB3aGV0aGVyIGFuIGVsZW1lbnQgcmVxdWlyZXMgYW4gb3BlbiB0YWcgb24gcHJpbnRpbmcKLSAqICh7QGxpbmsgI2lzRW1wdHlUYWd9KSBvciBvbiBwYXJzaW5nICh7QGxpbmsgI2lzT3B0aW9uYWxDbG9zaW5nfSkuCi0gKiA8UD4KLSAqIFR3byBvdGhlciBtZXRob2RzIHRyYW5zbGF0ZSBjaGFyYWN0ZXIgcmVmZXJlbmNlcyBmcm9tIG5hbWUgdG8gdmFsdWUgYW5kCi0gKiBmcm9tIHZhbHVlIHRvIG5hbWUuIEEgc21hbGwgZW50aXRpZXMgcmVzb3VyY2UgaXMgbG9hZGVkIGludG8gbWVtb3J5IHRoZQotICogZmlyc3QgdGltZSBhbnkgb2YgdGhlc2UgbWV0aG9kcyBpcyBjYWxsZWQgZm9yIGZhc3QgYW5kIGVmZmljaWVudCBhY2Nlc3MuCi0gKgotICoKLSAqIEBhdXRob3IgPGEgaHJlZj0ibWFpbHRvOmFya2luQGludGFsaW8uY29tIj5Bc3NhZiBBcmtpbjwvYT4KLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIEhUTUxkdGQKLXsKLQotICAgIC8qKgotICAgICAqIFB1YmxpYyBpZGVudGlmaWVyIGZvciBIVE1MIDQuMDEgKFN0cmljdCkgZG9jdW1lbnQgdHlwZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBIVE1MUHVibGljSWQgPSAiLS8vVzNDLy9EVEQgSFRNTCA0LjAxLy9FTiI7Ci0KLSAgICAvKioKLSAgICAgKiBTeXN0ZW0gaWRlbnRpZmllciBmb3IgSFRNTCA0LjAxIChTdHJpY3QpIGRvY3VtZW50IHR5cGUuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSFRNTFN5c3RlbUlkID0KLSAgICAgICAgImh0dHA6Ly93d3cudzMub3JnL1RSL2h0bWw0L3N0cmljdC5kdGQiOwotCi0gICAgLyoqCi0gICAgICogUHVibGljIGlkZW50aWZpZXIgZm9yIFhIVE1MIDEuMCAoU3RyaWN0KSBkb2N1bWVudCB0eXBlLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFhIVE1MUHVibGljSWQgPQotICAgICAgICAiLS8vVzNDLy9EVEQgWEhUTUwgMS4wIFN0cmljdC8vRU4iOwotCi0gICAgLyoqCi0gICAgICogU3lzdGVtIGlkZW50aWZpZXIgZm9yIFhIVE1MIDEuMCAoU3RyaWN0KSBkb2N1bWVudCB0eXBlLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFhIVE1MU3lzdGVtSWQgPQotICAgICAgICAiaHR0cDovL3d3dy53My5vcmcvVFIveGh0bWwxL0RURC94aHRtbDEtc3RyaWN0LmR0ZCI7Ci0KLSAgICAvKioKLSAgICAgKiBUYWJsZSBvZiByZXZlcnNlIGNoYXJhY3RlciByZWZlcmVuY2UgbWFwcGluZy4gQ2hhcmFjdGVyIGNvZGVzIGFyZSBoZWxkCi0gICAgICogYXMgc2luZ2xlLWNoYXJhY3RlciBzdHJpbmdzLCBtYXBwZWQgdG8gdGhlaXIgcmVmZXJlbmNlIG5hbWUuCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgTWFwPEludGVnZXIsIFN0cmluZz4gX2J5Q2hhcjsKLQotCi0gICAgLyoqCi0gICAgICogVGFibGUgb2YgZW50aXR5IG5hbWUgdG8gdmFsdWUgbWFwcGluZy4gRW50aXRpZXMgYXJlIGhlbGQgYXMgc3RyaW5ncywKLSAgICAgKiBjaGFyYWN0ZXIgcmVmZXJlbmNlcyBhcyA8VFQ+Q2hhcmFjdGVyPC9UVD4gb2JqZWN0cy4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBNYXA8U3RyaW5nLCBJbnRlZ2VyPiBfYnlOYW1lOwotCi0KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBNYXA8U3RyaW5nLCBTdHJpbmdbXT4gX2Jvb2xBdHRyczsKLQotCi0gICAgLyoqCi0gICAgICogSG9sZHMgZWxlbWVudCBkZWZpbml0aW9ucy4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBNYXA8U3RyaW5nLCBJbnRlZ2VyPiBfZWxlbURlZnM7Ci0KLQotICAgIC8qKgotICAgICAqIExvY2F0ZXMgdGhlIEhUTUwgZW50aXRpZXMgZmlsZSB0aGF0IGlzIGxvYWRlZCB1cG9uIGluaXRpYWxpemF0aW9uLgotICAgICAqIFRoaXMgZmlsZSBpcyBhIHJlc291cmNlIGxvYWRlZCB3aXRoIHRoZSBkZWZhdWx0IGNsYXNzIGxvYWRlci4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgICAgIEVOVElUSUVTX1JFU09VUkNFID0gIkhUTUxFbnRpdGllcy5yZXMiOwotCi0KLSAgICAvKioKLSAgICAgKiBPbmx5IG9wZW5pbmcgdGFnIHNob3VsZCBiZSBwcmludGVkLgotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBPTkxZX09QRU5JTkcgPSAweDAwMDE7Ci0KLSAgICAvKioKLSAgICAgKiBFbGVtZW50IGNvbnRhaW5zIGVsZW1lbnQgY29udGVudCBvbmx5LgotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBFTEVNX0NPTlRFTlQgPSAweDAwMDI7Ci0KLQotICAgIC8qKgotICAgICAqIEVsZW1lbnQgcHJlc2VydmUgc3BhY2VzLgotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBQUkVTRVJWRSAgICAgPSAweDAwMDQ7Ci0KLQotICAgIC8qKgotICAgICAqIE9wdGlvbmFsIGNsb3NpbmcgdGFnLgotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBPUFRfQ0xPU0lORyAgPSAweDAwMDg7Ci0KLQotICAgIC8qKgotICAgICAqIEVsZW1lbnQgaXMgZW1wdHkgKGFsc28gbWVhbnMgb25seSBvcGVuaW5nIHRhZykKLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgRU1QVFkgICAgICAgID0gMHgwMDEwIHwgT05MWV9PUEVOSU5HOwotCi0KLSAgICAvKioKLSAgICAgKiBBbGxvd2VkIHRvIGFwcGVhciBpbiBoZWFkLgotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBBTExPV0VEX0hFQUQgPSAweDAwMjA7Ci0KLQotICAgIC8qKgotICAgICAqIFdoZW4gb3BlbmVkLCBjbG9zZXMgUC4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQ0xPU0VfUCAgICAgID0gMHgwMDQwOwotCi0KLSAgICAvKioKLSAgICAgKiBXaGVuIG9wZW5lZCwgY2xvc2VzIEREIG9yIERULgotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBDTE9TRV9ERF9EVCAgPSAweDAwODA7Ci0KLQotICAgIC8qKgotICAgICAqIFdoZW4gb3BlbmVkLCBjbG9zZXMgaXRzZWxmLgotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBDTE9TRV9TRUxGICAgPSAweDAxMDA7Ci0KLQotICAgIC8qKgotICAgICAqIFdoZW4gb3BlbmVkLCBjbG9zZXMgYW5vdGhlciB0YWJsZSBzZWN0aW9uLgotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBDTE9TRV9UQUJMRSAgPSAweDAyMDA7Ci0KLQotICAgIC8qKgotICAgICAqIFdoZW4gb3BlbmVkLCBjbG9zZXMgVEggb3IgVEQuCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IENMT1NFX1RIX1REICA9IDB4MDQwMDA7Ci0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdHJ1ZSBpZiBlbGVtZW50IGlzIGRlY2xhcmVkIHRvIGJlIGVtcHR5LiBIVE1MIGVsZW1lbnRzIGFyZQotICAgICAqIGRlZmluZXMgYXMgZW1wdHkgaW4gdGhlIERURCwgbm90IGJ5IHRoZSBkb2N1bWVudCBzeW50YXguCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdGFnTmFtZSBUaGUgZWxlbWVudCB0YWcgbmFtZSAodXBwZXIgY2FzZSkKLSAgICAgKiBAcmV0dXJuIFRydWUgaWYgZWxlbWVudCBpcyBlbXB0eQotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0VtcHR5VGFnKCBTdHJpbmcgdGFnTmFtZSApCi0gICAgewotICAgICAgICByZXR1cm4gaXNFbGVtZW50KCB0YWdOYW1lLCBFTVBUWSApOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIGlmIGVsZW1lbnQgaXMgZGVjbGFyZWQgdG8gaGF2ZSBlbGVtZW50IGNvbnRlbnQuCi0gICAgICogV2hpdGVzcGFjZXMgYXBwZWFyaW5nIGluc2lkZSBlbGVtZW50IGNvbnRlbnQgd2lsbCBiZSBpZ25vcmVkLAotICAgICAqIG90aGVyIHRleHQgd2lsbCBzaW1wbHkgcmVwb3J0IGFuIGVycm9yLgotICAgICAqCi0gICAgICogQHBhcmFtIHRhZ05hbWUgVGhlIGVsZW1lbnQgdGFnIG5hbWUgKHVwcGVyIGNhc2UpCi0gICAgICogQHJldHVybiBUcnVlIGlmIGVsZW1lbnQgY29udGVudAotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0VsZW1lbnRDb250ZW50KCBTdHJpbmcgdGFnTmFtZSApCi0gICAgewotICAgICAgICByZXR1cm4gaXNFbGVtZW50KCB0YWdOYW1lLCBFTEVNX0NPTlRFTlQgKTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdHJ1ZSBpZiBlbGVtZW50J3MgdGV4dHVhbCBjb250ZW50cyBwcmVzZXJ2ZXMgc3BhY2VzLgotICAgICAqIFRoaXMgb25seSBhcHBsaWVzIHRvIFBSRSBhbmQgVEVYVEFSRUEsIGFsbCBvdGhlciBIVE1MIGVsZW1lbnRzCi0gICAgICogZG8gbm90IHByZXNlcnZlIHNwYWNlLgotICAgICAqCi0gICAgICogQHBhcmFtIHRhZ05hbWUgVGhlIGVsZW1lbnQgdGFnIG5hbWUgKHVwcGVyIGNhc2UpCi0gICAgICogQHJldHVybiBUcnVlIGlmIGVsZW1lbnQncyB0ZXh0IGNvbnRlbnQgcHJlc2VydmVzIHNwYWNlcwotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc1ByZXNlcnZlU3BhY2UoIFN0cmluZyB0YWdOYW1lICkKLSAgICB7Ci0gICAgICAgIHJldHVybiBpc0VsZW1lbnQoIHRhZ05hbWUsIFBSRVNFUlZFICk7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRydWUgaWYgZWxlbWVudCdzIGNsb3NpbmcgdGFnIGlzIG9wdGlvbmFsIGFuZCBuZWVkIG5vdAotICAgICAqIGV4aXN0LiBBbiBlcnJvciB3aWxsIG5vdCBiZSByZXBvcnRlZCBmb3Igc3VjaCBlbGVtZW50cyBpZiB0aGV5Ci0gICAgICogYXJlIG5vdCBjbG9zZWQuIEZvciBleGFtcGxlLCA8dHQ+TEk8L3R0PiBpcyBtb3N0IG9mdGVuIG5vdCBjbG9zZWQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdGFnTmFtZSBUaGUgZWxlbWVudCB0YWcgbmFtZSAodXBwZXIgY2FzZSkKLSAgICAgKiBAcmV0dXJuIFRydWUgaWYgY2xvc2luZyB0YWcgaW1wbGllZAotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc09wdGlvbmFsQ2xvc2luZyggU3RyaW5nIHRhZ05hbWUgKQotICAgIHsKLSAgICAgICAgcmV0dXJuIGlzRWxlbWVudCggdGFnTmFtZSwgT1BUX0NMT1NJTkcgKTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdHJ1ZSBpZiBlbGVtZW50J3MgY2xvc2luZyB0YWcgaXMgZ2VuZXJhbGx5IG5vdCBwcmludGVkLgotICAgICAqIEZvciBleGFtcGxlLCA8dHQ+TEk8L3R0PiBzaG91bGQgbm90IHByaW50IHRoZSBjbG9zaW5nIHRhZy4KLSAgICAgKgotICAgICAqIEBwYXJhbSB0YWdOYW1lIFRoZSBlbGVtZW50IHRhZyBuYW1lICh1cHBlciBjYXNlKQotICAgICAqIEByZXR1cm4gVHJ1ZSBpZiBvbmx5IG9wZW5pbmcgdGFnIHNob3VsZCBiZSBwcmludGVkCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzT25seU9wZW5pbmcoIFN0cmluZyB0YWdOYW1lICkKLSAgICB7Ci0gICAgICAgIHJldHVybiBpc0VsZW1lbnQoIHRhZ05hbWUsIE9OTFlfT1BFTklORyApOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBvcGVuaW5nIG9mIG9uZSBlbGVtZW50ICg8dHQ+dGFnTmFtZTwvdHQ+KSBpbXBsaWVzCi0gICAgICogdGhlIGNsb3Npbmcgb2YgYW5vdGhlciBvcGVuIGVsZW1lbnQgKDx0dD5vcGVuVGFnPC90dD4pLiBGb3IgZXhhbXBsZSwKLSAgICAgKiBldmVyeSBvcGVuaW5nIDx0dD5MSTwvdHQ+IHdpbGwgY2xvc2UgdGhlIHByZXZpb3VzbHkgb3BlbiA8dHQ+TEk8L3R0PiwKLSAgICAgKiBhbmQgZXZlcnkgb3BlbmluZyA8dHQ+Qk9EWTwvdHQ+IHdpbGwgY2xvc2UgdGhlIHByZXZpb3VzbHkgb3BlbiA8dHQ+SEVBRDwvdHQ+LgotICAgICAqCi0gICAgICogQHBhcmFtIHRhZ05hbWUgVGhlIG5ld2x5IG9wZW5lZCBlbGVtZW50Ci0gICAgICogQHBhcmFtIG9wZW5UYWcgVGhlIGFscmVhZHkgb3BlbmVkIGVsZW1lbnQKLSAgICAgKiBAcmV0dXJuIFRydWUgaWYgY2xvc2luZyB0YWcgY2xvc2VzIG9wZW5pbmcgdGFnCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzQ2xvc2luZyggU3RyaW5nIHRhZ05hbWUsIFN0cmluZyBvcGVuVGFnICkKLSAgICB7Ci0gICAgICAgIC8vIFNldmVyYWwgZWxlbWVudHMgYXJlIGRlZmluZWQgYXMgY2xvc2luZyB0aGUgSEVBRAotICAgICAgICBpZiAoIG9wZW5UYWcuZXF1YWxzSWdub3JlQ2FzZSggIkhFQUQiICkgKQotICAgICAgICAgICAgcmV0dXJuICEgaXNFbGVtZW50KCB0YWdOYW1lLCBBTExPV0VEX0hFQUQgKTsKLSAgICAgICAgLy8gUCBjbG9zZXMgaXRlc2VsZgotICAgICAgICBpZiAoIG9wZW5UYWcuZXF1YWxzSWdub3JlQ2FzZSggIlAiICkgKQotICAgICAgICAgICAgcmV0dXJuIGlzRWxlbWVudCggdGFnTmFtZSwgQ0xPU0VfUCApOwotICAgICAgICAvLyBEVCBjbG9zZXMgREQsIEREIGNsb3NlcyBEVAotICAgICAgICBpZiAoIG9wZW5UYWcuZXF1YWxzSWdub3JlQ2FzZSggIkRUIiApIHx8IG9wZW5UYWcuZXF1YWxzSWdub3JlQ2FzZSggIkREIiApICkKLSAgICAgICAgICAgIHJldHVybiBpc0VsZW1lbnQoIHRhZ05hbWUsIENMT1NFX0REX0RUICk7Ci0gICAgICAgIC8vIExJIGFuZCBPUFRJT04gY2xvc2UgdGhlbXNlbHZlcwotICAgICAgICBpZiAoIG9wZW5UYWcuZXF1YWxzSWdub3JlQ2FzZSggIkxJIiApIHx8IG9wZW5UYWcuZXF1YWxzSWdub3JlQ2FzZSggIk9QVElPTiIgKSApCi0gICAgICAgICAgICByZXR1cm4gaXNFbGVtZW50KCB0YWdOYW1lLCBDTE9TRV9TRUxGICk7Ci0gICAgICAgIC8vIEVhY2ggb2YgdGhlc2UgdGFibGUgc2VjdGlvbnMgY2xvc2VzIGFsbCB0aGUgb3RoZXJzCi0gICAgICAgIGlmICggb3BlblRhZy5lcXVhbHNJZ25vcmVDYXNlKCAiVEhFQUQiICkgfHwgb3BlblRhZy5lcXVhbHNJZ25vcmVDYXNlKCAiVEZPT1QiICkgfHwKLSAgICAgICAgICAgICBvcGVuVGFnLmVxdWFsc0lnbm9yZUNhc2UoICJUQk9EWSIgKSB8fCBvcGVuVGFnLmVxdWFsc0lnbm9yZUNhc2UoICJUUiIgKSB8fAotICAgICAgICAgICAgIG9wZW5UYWcuZXF1YWxzSWdub3JlQ2FzZSggIkNPTEdST1VQIiApICkKLSAgICAgICAgICAgIHJldHVybiBpc0VsZW1lbnQoIHRhZ05hbWUsIENMT1NFX1RBQkxFICk7Ci0gICAgICAgIC8vIFREIGNsb3NlcyBUSCBhbmQgVEggY2xvc2VzIFRECi0gICAgICAgIGlmICggb3BlblRhZy5lcXVhbHNJZ25vcmVDYXNlKCAiVEgiICkgfHwgb3BlblRhZy5lcXVhbHNJZ25vcmVDYXNlKCAiVEQiICkgKQotICAgICAgICAgICAgcmV0dXJuIGlzRWxlbWVudCggdGFnTmFtZSwgQ0xPU0VfVEhfVEQgKTsKLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgYXR0cmlidXRlIGl0IGEgVVJJIGFuZCBzaG91bGQgYmUKLSAgICAgKiBlc2NhcGVkIGFwcHJvcHJpYXRlbHkuIEluIEhUTUwgVVJJcyBhcmUgZXNjYXBlZCBkaWZmZXJlbnRseQotICAgICAqIHRoYW4gbm9ybWFsIGF0dHJpYnV0ZXMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdGFnTmFtZSBUaGUgZWxlbWVudCdzIHRhZyBuYW1lCi0gICAgICogQHBhcmFtIGF0dHJOYW1lIFRoZSBhdHRyaWJ1dGUncyBuYW1lCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzVVJJKCBTdHJpbmcgdGFnTmFtZSwgU3RyaW5nIGF0dHJOYW1lICkKLSAgICB7Ci0gICAgICAgIC8vIFN0dXBpZCBjaGVja3MuCi0gICAgICAgIHJldHVybiAoIGF0dHJOYW1lLmVxdWFsc0lnbm9yZUNhc2UoICJocmVmIiApIHx8IGF0dHJOYW1lLmVxdWFsc0lnbm9yZUNhc2UoICJzcmMiICkgKTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgc3BlY2lmaWVkIGF0dHJpYnV0ZSBpcyBhIGJvb2xlYW4gYW5kIHNob3VsZCBiZQotICAgICAqIHByaW50ZWQgd2l0aG91dCB0aGUgdmFsdWUuIFRoaXMgYXBwbGllcyB0byBhdHRyaWJ1dGVzIHRoYXQgYXJlIHRydWUKLSAgICAgKiBpZiB0aGV5IGV4aXN0LCBzdWNoIGFzIHNlbGVjdGVkIChPUFRJT04vSU5QVVQpLgotICAgICAqCi0gICAgICogQHBhcmFtIHRhZ05hbWUgVGhlIGVsZW1lbnQncyB0YWcgbmFtZQotICAgICAqIEBwYXJhbSBhdHRyTmFtZSBUaGUgYXR0cmlidXRlJ3MgbmFtZQotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0Jvb2xlYW4oIFN0cmluZyB0YWdOYW1lLCBTdHJpbmcgYXR0ck5hbWUgKQotICAgIHsKLSAgICAgICAgU3RyaW5nW10gYXR0ck5hbWVzOwotCi0gICAgICAgIGF0dHJOYW1lcyA9IF9ib29sQXR0cnMuZ2V0KCB0YWdOYW1lLnRvVXBwZXJDYXNlKExvY2FsZS5FTkdMSVNIKSApOwotICAgICAgICBpZiAoIGF0dHJOYW1lcyA9PSBudWxsICkKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgZm9yICggaW50IGkgPSAwIDsgaSA8IGF0dHJOYW1lcy5sZW5ndGggOyArK2kgKQotICAgICAgICAgICAgaWYgKCBhdHRyTmFtZXNbIGkgXS5lcXVhbHNJZ25vcmVDYXNlKCBhdHRyTmFtZSApICkKLSAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgYW4gSFRNTCBjaGFyYWN0ZXIgcmVmZXJlbmNlIGJ5IGl0cyBuYW1lLiBJZiB0aGUKLSAgICAgKiByZWZlcmVuY2UgaXMgbm90IGZvdW5kIG9yIHdhcyBub3QgZGVmaW5lZCBhcyBhIGNoYXJhY3RlciByZWZlcmVuY2UsCi0gICAgICogcmV0dXJucyBFT0YgKC0xKS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lIE5hbWUgb2YgY2hhcmFjdGVyIHJlZmVyZW5jZQotICAgICAqIEByZXR1cm4gQ2hhcmFjdGVyIGNvZGUgb3IgRU9GICgtMSkKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGludCBjaGFyRnJvbU5hbWUoIFN0cmluZyBuYW1lICkKLSAgICB7Ci0gICAgICAgIE9iamVjdCAgICB2YWx1ZTsKLQotICAgICAgICBpbml0aWFsaXplKCk7Ci0gICAgICAgIHZhbHVlID0gX2J5TmFtZS5nZXQoIG5hbWUgKTsKLSAgICAgICAgaWYgKCB2YWx1ZSAhPSBudWxsICYmIHZhbHVlIGluc3RhbmNlb2YgSW50ZWdlciApCi0gICAgICAgICAgICByZXR1cm4gKCAoSW50ZWdlcikgdmFsdWUgKS5pbnRWYWx1ZSgpOwotICAgICAgICBlbHNlCi0gICAgICAgICAgICByZXR1cm4gLTE7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIGFuIEhUTUwgY2hhcmFjdGVyIHJlZmVyZW5jZSBiYXNlZCBvbiBpdHMgY2hhcmFjdGVyCi0gICAgICogdmFsdWUuIE9ubHkgdmFsaWQgZm9yIGVudGl0aWVzIGRlZmluZWQgZnJvbSBjaGFyYWN0ZXIgcmVmZXJlbmNlcy4gSWYgbm8KLSAgICAgKiBzdWNoIGNoYXJhY3RlciB2YWx1ZSB3YXMgZGVmaW5lZCwgcmV0dXJuIG51bGwuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdmFsdWUgQ2hhcmFjdGVyIHZhbHVlIG9mIGVudGl0eQotICAgICAqIEByZXR1cm4gRW50aXR5J3MgbmFtZSBvciBudWxsCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZnJvbUNoYXIoaW50IHZhbHVlICkKLSAgICB7Ci0gICAgICAgaWYgKHZhbHVlID4gMHhmZmZmKQotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0KLSAgICAgICAgU3RyaW5nIG5hbWU7Ci0KLSAgICAgICAgaW5pdGlhbGl6ZSgpOwotICAgICAgICBuYW1lID0gX2J5Q2hhci5nZXQodmFsdWUpOwotICAgICAgICByZXR1cm4gbmFtZTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIEluaXRpYWxpemUgdXBvbiBmaXJzdCBhY2Nlc3MuIFdpbGwgbG9hZCBhbGwgdGhlIEhUTUwgY2hhcmFjdGVyIHJlZmVyZW5jZXMKLSAgICAgKiBpbnRvIGEgbGlzdCB0aGF0IGlzIGFjY2Vzc2libGUgYnkgbmFtZSBvciBjaGFyYWN0ZXIgdmFsdWUgYW5kIGlzIG9wdGltaXplZAotICAgICAqIGZvciBjaGFyYWN0ZXIgc3Vic3RpdHV0aW9uLiBUaGlzIG1ldGhvZCBtYXkgYmUgY2FsbGVkIGFueSBudW1iZXIgb2YgdGltZXMKLSAgICAgKiBidXQgd2lsbCBleGVjdXRlIG9ubHkgb25jZS4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGluaXRpYWxpemUoKQotICAgIHsKLSAgICAgICAgSW5wdXRTdHJlYW0gICAgIGlzID0gbnVsbDsKLSAgICAgICAgQnVmZmVyZWRSZWFkZXIgIHJlYWRlciA9IG51bGw7Ci0gICAgICAgIGludCAgICAgICAgICAgICBpbmRleDsKLSAgICAgICAgU3RyaW5nICAgICAgICAgIG5hbWU7Ci0gICAgICAgIFN0cmluZyAgICAgICAgICB2YWx1ZTsKLSAgICAgICAgaW50ICAgICAgICAgICAgIGNvZGU7Ci0gICAgICAgIFN0cmluZyAgICAgICAgICBsaW5lOwotCi0gICAgICAgIC8vIE1ha2Ugc3VyZSBub3QgdG8gaW5pdGlhbGl6ZSB0d2ljZS4KLSAgICAgICAgaWYgKCBfYnlOYW1lICE9IG51bGwgKQotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB0cnkgewotICAgICAgICAgICAgX2J5TmFtZSA9IG5ldyBIYXNoTWFwPD4oKTsKLSAgICAgICAgICAgIF9ieUNoYXIgPSBuZXcgSGFzaE1hcDw+KCk7Ci0gICAgICAgICAgICBpcyA9IEhUTUxkdGQuY2xhc3MuZ2V0UmVzb3VyY2VBc1N0cmVhbSggRU5USVRJRVNfUkVTT1VSQ0UgKTsKLSAgICAgICAgICAgIGlmICggaXMgPT0gbnVsbCApIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZSgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuU0VSSUFMSVpFUl9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICJSZXNvdXJjZU5vdEZvdW5kIiwgbmV3IE9iamVjdFtdIHtFTlRJVElFU19SRVNPVVJDRX0pKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJlYWRlciA9IG5ldyBCdWZmZXJlZFJlYWRlciggbmV3IElucHV0U3RyZWFtUmVhZGVyKCBpcywgIkFTQ0lJIiApICk7Ci0gICAgICAgICAgICBsaW5lID0gcmVhZGVyLnJlYWRMaW5lKCk7Ci0gICAgICAgICAgICB3aGlsZSAoIGxpbmUgIT0gbnVsbCApIHsKLSAgICAgICAgICAgICAgICBpZiAoIGxpbmUubGVuZ3RoKCkgPT0gMCB8fCBsaW5lLmNoYXJBdCggMCApID09ICcjJyApIHsKLSAgICAgICAgICAgICAgICAgICAgbGluZSA9IHJlYWRlci5yZWFkTGluZSgpOwotICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaW5kZXggPSBsaW5lLmluZGV4T2YoICcgJyApOwotICAgICAgICAgICAgICAgIGlmICggaW5kZXggPiAxICkgewotICAgICAgICAgICAgICAgICAgICBuYW1lID0gbGluZS5zdWJzdHJpbmcoIDAsIGluZGV4ICk7Ci0gICAgICAgICAgICAgICAgICAgICsraW5kZXg7Ci0gICAgICAgICAgICAgICAgICAgIGlmICggaW5kZXggPCBsaW5lLmxlbmd0aCgpICkgewotICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBsaW5lLnN1YnN0cmluZyggaW5kZXggKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4ID0gdmFsdWUuaW5kZXhPZiggJyAnICk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIGluZGV4ID4gMCApCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZS5zdWJzdHJpbmcoIDAsIGluZGV4ICk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBjb2RlID0gSW50ZWdlci5wYXJzZUludCggdmFsdWUgKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWZpbmVFbnRpdHkoIG5hbWUsIChjaGFyKSBjb2RlICk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgbGluZSA9IHJlYWRlci5yZWFkTGluZSgpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaXMuY2xvc2UoKTsKLSAgICAgICAgfSAgY2F0Y2ggKCBFeGNlcHRpb24gZXhjZXB0ICkgewotICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZSgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5TRVJJQUxJWkVSX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAiUmVzb3VyY2VOb3RMb2FkZWQiLCBuZXcgT2JqZWN0W10ge0VOVElUSUVTX1JFU09VUkNFLCBleGNlcHQudG9TdHJpbmcoKX0pKTsKLSAgICAgICAgfSBmaW5hbGx5IHsKLSAgICAgICAgICAgIGlmICggaXMgIT0gbnVsbCApIHsKLSAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICBpcy5jbG9zZSgpOwotICAgICAgICAgICAgICAgIH0gY2F0Y2ggKCBFeGNlcHRpb24gZXhjZXB0ICkgeyB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIERlZmluZXMgYSBuZXcgY2hhcmFjdGVyIHJlZmVyZW5jZS4gVGhlIHJlZmVyZW5jZSdzIG5hbWUgYW5kIHZhbHVlIGFyZQotICAgICAqIHN1cHBsaWVkLiBOb3RoaW5nIGhhcHBlbnMgaWYgdGhlIGNoYXJhY3RlciByZWZlcmVuY2UgaXMgYWxyZWFkeSBkZWZpbmVkLgotICAgICAqIDxQPgotICAgICAqIFVubGlrZSBpbnRlcm5hbCBlbnRpdGllcywgY2hhcmFjdGVyIHJlZmVyZW5jZXMgYXJlIGEgc3RyaW5nIHRvIHNpbmdsZQotICAgICAqIGNoYXJhY3RlciBtYXBwaW5nLiBUaGV5IGFyZSB1c2VkIHRvIG1hcCBub24tQVNDSUkgY2hhcmFjdGVycyBib3RoIG9uCi0gICAgICogcGFyc2luZyBhbmQgcHJpbnRpbmcsIHByaW1hcmlseSBmb3IgSFRNTCBkb2N1bWVudHMuICcmbHQ7YW1wOycgaXMgYW4KLSAgICAgKiBleGFtcGxlIG9mIGEgY2hhcmFjdGVyIHJlZmVyZW5jZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBlbnRpdHkncyBuYW1lCi0gICAgICogQHBhcmFtIHZhbHVlIFRoZSBlbnRpdHkncyB2YWx1ZQotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIHZvaWQgZGVmaW5lRW50aXR5KCBTdHJpbmcgbmFtZSwgY2hhciB2YWx1ZSApCi0gICAgewotICAgICAgICBpZiAoIF9ieU5hbWUuZ2V0KCBuYW1lICkgPT0gbnVsbCApIHsKLSAgICAgICAgICAgIF9ieU5hbWUucHV0KCBuYW1lLCBuZXcgSW50ZWdlciggdmFsdWUgKSApOwotICAgICAgICAgICAgX2J5Q2hhci5wdXQoIG5ldyBJbnRlZ2VyKCB2YWx1ZSApLCBuYW1lICk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIHByaXZhdGUgc3RhdGljIHZvaWQgZGVmaW5lRWxlbWVudCggU3RyaW5nIG5hbWUsIGludCBmbGFncyApCi0gICAgewotICAgICAgICBfZWxlbURlZnMucHV0KG5hbWUsIGZsYWdzKTsKLSAgICB9Ci0KLQotICAgIHByaXZhdGUgc3RhdGljIHZvaWQgZGVmaW5lQm9vbGVhbiggU3RyaW5nIHRhZ05hbWUsIFN0cmluZyBhdHRyTmFtZSApCi0gICAgewotICAgICAgICBkZWZpbmVCb29sZWFuKCB0YWdOYW1lLCBuZXcgU3RyaW5nW10geyBhdHRyTmFtZSB9ICk7Ci0gICAgfQotCi0KLSAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGRlZmluZUJvb2xlYW4oIFN0cmluZyB0YWdOYW1lLCBTdHJpbmdbXSBhdHRyTmFtZXMgKQotICAgIHsKLSAgICAgICAgX2Jvb2xBdHRycy5wdXQoIHRhZ05hbWUsIGF0dHJOYW1lcyApOwotICAgIH0KLQotCi0gICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBpc0VsZW1lbnQoIFN0cmluZyBuYW1lLCBpbnQgZmxhZyApCi0gICAgewotICAgICAgICBJbnRlZ2VyIGZsYWdzOwotCi0gICAgICAgIGZsYWdzID0gX2VsZW1EZWZzLmdldCggbmFtZS50b1VwcGVyQ2FzZShMb2NhbGUuRU5HTElTSCkgKTsKLSAgICAgICAgaWYgKCBmbGFncyA9PSBudWxsICkKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgZWxzZQotICAgICAgICAgICAgcmV0dXJuICggKCBmbGFncy5pbnRWYWx1ZSgpICYgZmxhZyApID09IGZsYWcgKTsKLSAgICB9Ci0KLQotICAgIHN0YXRpYwotICAgIHsKLSAgICAgICAgX2VsZW1EZWZzID0gbmV3IEhhc2hNYXA8PigpOwotICAgICAgICBkZWZpbmVFbGVtZW50KCAiQUREUkVTUyIsIENMT1NFX1AgKTsKLSAgICAgICAgZGVmaW5lRWxlbWVudCggIkFSRUEiLCBFTVBUWSApOwotICAgICAgICBkZWZpbmVFbGVtZW50KCAiQkFTRSIsICBFTVBUWSB8IEFMTE9XRURfSEVBRCApOwotICAgICAgICBkZWZpbmVFbGVtZW50KCAiQkFTRUZPTlQiLCBFTVBUWSApOwotICAgICAgICBkZWZpbmVFbGVtZW50KCAiQkxPQ0tRVU9URSIsIENMT1NFX1AgKTsKLSAgICAgICAgZGVmaW5lRWxlbWVudCggIkJPRFkiLCBPUFRfQ0xPU0lORyApOwotICAgICAgICBkZWZpbmVFbGVtZW50KCAiQlIiLCBFTVBUWSApOwotICAgICAgICBkZWZpbmVFbGVtZW50KCAiQ09MIiwgRU1QVFkgKTsKLSAgICAgICAgZGVmaW5lRWxlbWVudCggIkNPTEdST1VQIiwgRUxFTV9DT05URU5UIHwgT1BUX0NMT1NJTkcgfCBDTE9TRV9UQUJMRSApOwotICAgICAgICBkZWZpbmVFbGVtZW50KCAiREQiLCBPUFRfQ0xPU0lORyB8IE9OTFlfT1BFTklORyB8IENMT1NFX0REX0RUICk7Ci0gICAgICAgIGRlZmluZUVsZW1lbnQoICJESVYiLCBDTE9TRV9QICk7Ci0gICAgICAgIGRlZmluZUVsZW1lbnQoICJETCIsIEVMRU1fQ09OVEVOVCB8IENMT1NFX1AgKTsKLSAgICAgICAgZGVmaW5lRWxlbWVudCggIkRUIiwgT1BUX0NMT1NJTkcgfCBPTkxZX09QRU5JTkcgfCBDTE9TRV9ERF9EVCApOwotICAgICAgICBkZWZpbmVFbGVtZW50KCAiRklFTERTRVQiLCBDTE9TRV9QICk7Ci0gICAgICAgIGRlZmluZUVsZW1lbnQoICJGT1JNIiwgQ0xPU0VfUCApOwotICAgICAgICBkZWZpbmVFbGVtZW50KCAiRlJBTUUiLCBFTVBUWSB8IE9QVF9DTE9TSU5HICk7Ci0gICAgICAgIGRlZmluZUVsZW1lbnQoICJIMSIsIENMT1NFX1AgKTsKLSAgICAgICAgZGVmaW5lRWxlbWVudCggIkgyIiwgQ0xPU0VfUCApOwotICAgICAgICBkZWZpbmVFbGVtZW50KCAiSDMiLCBDTE9TRV9QICk7Ci0gICAgICAgIGRlZmluZUVsZW1lbnQoICJINCIsIENMT1NFX1AgKTsKLSAgICAgICAgZGVmaW5lRWxlbWVudCggIkg1IiwgQ0xPU0VfUCApOwotICAgICAgICBkZWZpbmVFbGVtZW50KCAiSDYiLCBDTE9TRV9QICk7Ci0gICAgICAgIGRlZmluZUVsZW1lbnQoICJIRUFEIiwgRUxFTV9DT05URU5UIHwgT1BUX0NMT1NJTkcgKTsKLSAgICAgICAgZGVmaW5lRWxlbWVudCggIkhSIiwgRU1QVFkgfCBDTE9TRV9QICk7Ci0gICAgICAgIGRlZmluZUVsZW1lbnQoICJIVE1MIiwgRUxFTV9DT05URU5UIHwgT1BUX0NMT1NJTkcgKTsKLSAgICAgICAgZGVmaW5lRWxlbWVudCggIklNRyIsIEVNUFRZICk7Ci0gICAgICAgIGRlZmluZUVsZW1lbnQoICJJTlBVVCIsIEVNUFRZICk7Ci0gICAgICAgIGRlZmluZUVsZW1lbnQoICJJU0lOREVYIiwgRU1QVFkgfCBBTExPV0VEX0hFQUQgKTsKLSAgICAgICAgZGVmaW5lRWxlbWVudCggIkxJIiwgT1BUX0NMT1NJTkcgfCBPTkxZX09QRU5JTkcgfCBDTE9TRV9TRUxGICk7Ci0gICAgICAgIGRlZmluZUVsZW1lbnQoICJMSU5LIiwgRU1QVFkgfCBBTExPV0VEX0hFQUQgKTsKLSAgICAgICAgZGVmaW5lRWxlbWVudCggIk1BUCIsIEFMTE9XRURfSEVBRCApOwotICAgICAgICBkZWZpbmVFbGVtZW50KCAiTUVUQSIsIEVNUFRZIHwgQUxMT1dFRF9IRUFEICk7Ci0gICAgICAgIGRlZmluZUVsZW1lbnQoICJPTCIsIEVMRU1fQ09OVEVOVCB8IENMT1NFX1AgKTsKLSAgICAgICAgZGVmaW5lRWxlbWVudCggIk9QVEdST1VQIiwgRUxFTV9DT05URU5UICk7Ci0gICAgICAgIGRlZmluZUVsZW1lbnQoICJPUFRJT04iLCBPUFRfQ0xPU0lORyB8IE9OTFlfT1BFTklORyB8IENMT1NFX1NFTEYgKTsKLSAgICAgICAgZGVmaW5lRWxlbWVudCggIlAiLCBPUFRfQ0xPU0lORyB8IENMT1NFX1AgfCBDTE9TRV9TRUxGICk7Ci0gICAgICAgIGRlZmluZUVsZW1lbnQoICJQQVJBTSIsIEVNUFRZICk7Ci0gICAgICAgIGRlZmluZUVsZW1lbnQoICJQUkUiLCBQUkVTRVJWRSB8IENMT1NFX1AgKTsKLSAgICAgICAgZGVmaW5lRWxlbWVudCggIlNDUklQVCIsIEFMTE9XRURfSEVBRCB8IFBSRVNFUlZFICk7Ci0gICAgICAgIGRlZmluZUVsZW1lbnQoICJOT1NDUklQVCIsIEFMTE9XRURfSEVBRCB8IFBSRVNFUlZFICk7Ci0gICAgICAgIGRlZmluZUVsZW1lbnQoICJTRUxFQ1QiLCBFTEVNX0NPTlRFTlQgKTsKLSAgICAgICAgZGVmaW5lRWxlbWVudCggIlNUWUxFIiwgQUxMT1dFRF9IRUFEIHwgUFJFU0VSVkUgKTsKLSAgICAgICAgZGVmaW5lRWxlbWVudCggIlRBQkxFIiwgRUxFTV9DT05URU5UIHwgQ0xPU0VfUCApOwotICAgICAgICBkZWZpbmVFbGVtZW50KCAiVEJPRFkiLCBFTEVNX0NPTlRFTlQgfCBPUFRfQ0xPU0lORyB8IENMT1NFX1RBQkxFICk7Ci0gICAgICAgIGRlZmluZUVsZW1lbnQoICJURCIsIE9QVF9DTE9TSU5HIHwgQ0xPU0VfVEhfVEQgKTsKLSAgICAgICAgZGVmaW5lRWxlbWVudCggIlRFWFRBUkVBIiwgUFJFU0VSVkUgKTsKLSAgICAgICAgZGVmaW5lRWxlbWVudCggIlRGT09UIiwgRUxFTV9DT05URU5UIHwgT1BUX0NMT1NJTkcgfCBDTE9TRV9UQUJMRSApOwotICAgICAgICBkZWZpbmVFbGVtZW50KCAiVEgiLCBPUFRfQ0xPU0lORyB8IENMT1NFX1RIX1REICk7Ci0gICAgICAgIGRlZmluZUVsZW1lbnQoICJUSEVBRCIsIEVMRU1fQ09OVEVOVCB8IE9QVF9DTE9TSU5HIHwgQ0xPU0VfVEFCTEUgKTsKLSAgICAgICAgZGVmaW5lRWxlbWVudCggIlRJVExFIiwgQUxMT1dFRF9IRUFEICk7Ci0gICAgICAgIGRlZmluZUVsZW1lbnQoICJUUiIsIEVMRU1fQ09OVEVOVCB8IE9QVF9DTE9TSU5HIHwgQ0xPU0VfVEFCTEUgKTsKLSAgICAgICAgZGVmaW5lRWxlbWVudCggIlVMIiwgRUxFTV9DT05URU5UIHwgQ0xPU0VfUCApOwotCi0gICAgICAgIF9ib29sQXR0cnMgPSBuZXcgSGFzaE1hcDw+KCk7Ci0gICAgICAgIGRlZmluZUJvb2xlYW4oICJBUkVBIiwgImhyZWYiICk7Ci0gICAgICAgIGRlZmluZUJvb2xlYW4oICJCVVRUT04iLCAiZGlzYWJsZWQiICk7Ci0gICAgICAgIGRlZmluZUJvb2xlYW4oICJESVIiLCAiY29tcGFjdCIgKTsKLSAgICAgICAgZGVmaW5lQm9vbGVhbiggIkRMIiwgImNvbXBhY3QiICk7Ci0gICAgICAgIGRlZmluZUJvb2xlYW4oICJGUkFNRSIsICJub3Jlc2l6ZSIgKTsKLSAgICAgICAgZGVmaW5lQm9vbGVhbiggIkhSIiwgIm5vc2hhZGUiICk7Ci0gICAgICAgIGRlZmluZUJvb2xlYW4oICJJTUFHRSIsICJpc21hcCIgKTsKLSAgICAgICAgZGVmaW5lQm9vbGVhbiggIklOUFVUIiwgbmV3IFN0cmluZ1tdIHsgImRlZmF1bHRjaGVja2VkIiwgImNoZWNrZWQiLCAicmVhZG9ubHkiLCAiZGlzYWJsZWQiIH0gKTsKLSAgICAgICAgZGVmaW5lQm9vbGVhbiggIkxJTksiLCAibGluayIgKTsKLSAgICAgICAgZGVmaW5lQm9vbGVhbiggIk1FTlUiLCAiY29tcGFjdCIgKTsKLSAgICAgICAgZGVmaW5lQm9vbGVhbiggIk9CSkVDVCIsICJkZWNsYXJlIiApOwotICAgICAgICBkZWZpbmVCb29sZWFuKCAiT0wiLCAiY29tcGFjdCIgKTsKLSAgICAgICAgZGVmaW5lQm9vbGVhbiggIk9QVEdST1VQIiwgImRpc2FibGVkIiApOwotICAgICAgICBkZWZpbmVCb29sZWFuKCAiT1BUSU9OIiwgbmV3IFN0cmluZ1tdIHsgImRlZmF1bHQtc2VsZWN0ZWQiLCAic2VsZWN0ZWQiLCAiZGlzYWJsZWQiIH0gKTsKLSAgICAgICAgZGVmaW5lQm9vbGVhbiggIlNDUklQVCIsICJkZWZlciIgKTsKLSAgICAgICAgZGVmaW5lQm9vbGVhbiggIlNFTEVDVCIsIG5ldyBTdHJpbmdbXSB7ICJtdWx0aXBsZSIsICJkaXNhYmxlZCIgfSApOwotICAgICAgICBkZWZpbmVCb29sZWFuKCAiU1RZTEUiLCAiZGlzYWJsZWQiICk7Ci0gICAgICAgIGRlZmluZUJvb2xlYW4oICJURCIsICJub3dyYXAiICk7Ci0gICAgICAgIGRlZmluZUJvb2xlYW4oICJUSCIsICJub3dyYXAiICk7Ci0gICAgICAgIGRlZmluZUJvb2xlYW4oICJURVhUQVJFQSIsIG5ldyBTdHJpbmdbXSB7ICJkaXNhYmxlZCIsICJyZWFkb25seSIgfSApOwotICAgICAgICBkZWZpbmVCb29sZWFuKCAiVUwiLCAiY29tcGFjdCIgKTsKLQotICAgICAgICBpbml0aWFsaXplKCk7Ci0gICAgfQotCi0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplL0luZGVudFByaW50ZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZS9JbmRlbnRQcmludGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGVmYzdhZjEuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplL0luZGVudFByaW50ZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDM2NSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZTsKLQotCi1pbXBvcnQgamF2YS5pby5Xcml0ZXI7Ci1pbXBvcnQgamF2YS5pby5TdHJpbmdXcml0ZXI7Ci1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLQotCi0vKioKLSAqIEV4dGVuZHMge0BsaW5rIFByaW50ZXJ9IGFuZCBhZGRzIHN1cHBvcnQgZm9yIGluZGVudGF0aW9uIGFuZCBsaW5lCi0gKiB3cmFwcGluZy4KLSAqCi0gKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzphcmtpbkBpbnRhbGlvLmNvbSI+QXNzYWYgQXJraW48L2E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBJbmRlbnRQcmludGVyCi0gICAgZXh0ZW5kcyBQcmludGVyCi17Ci0KLQotICAgIC8qKgotICAgICAqIEhvbGRzIHRoZSBjdXJyZW50bHkgYWNjdW11bGF0aW5nIHRleHQgbGluZS4gVGhpcyBidWZmZXIgd2lsbCBjb25zdGFudGx5Ci0gICAgICogYmUgcmV1c2VkIGJ5IGRlbGV0aW5nIGl0cyBjb250ZW50cyBpbnN0ZWFkIG9mIHJlYWxsb2NhdGluZyBpdC4KLSAgICAgKi8KLSAgICBwcml2YXRlIFN0cmluZ0J1ZmZlciAgICBfbGluZTsKLQotCi0gICAgLyoqCi0gICAgICogSG9sZHMgdGhlIGN1cnJlbnRseSBhY2N1bXVsYXRpbmcgdGV4dCB0aGF0IGZvbGxvd3Mge0BsaW5rICNfbGluZX0uCi0gICAgICogV2hlbiB0aGUgZW5kIG9mIHRoZSBwYXJ0IGlzIGlkZW50aWZpZWQgYnkgYSBjYWxsIHRvIHtAbGluayAjcHJpbnRTcGFjZX0KLSAgICAgKiBvciB7QGxpbmsgI2JyZWFrTGluZX0sIHRoaXMgcGFydCBpcyBhZGRlZCB0byB0aGUgYWNjdW11bGF0ZWQgbGluZS4KLSAgICAgKi8KLSAgICBwcml2YXRlIFN0cmluZ0J1ZmZlciAgICBfdGV4dDsKLQotCi0gICAgLyoqCi0gICAgICogQ291bnRzIGhvdyBtYW55IHdoaXRlIHNwYWNlcyBjb21lIGJldHdlZW4gdGhlIGFjY3VtdWxhdGVkIGxpbmUgYW5kIHRoZQotICAgICAqIGN1cnJlbnQgYWNjdW11bGF0ZWQgdGV4dC4gTXVsdGlwbGUgc3BhY2VzIGF0IHRoZSBlbmQgb2YgdGhlIGEgbGluZQotICAgICAqIHdpbGwgbm90IGJlIHByaW50ZWQuCi0gICAgICovCi0gICAgcHJpdmF0ZSBpbnQgICAgICAgICAgICAgX3NwYWNlczsKLQotCi0gICAgLyoqCi0gICAgICogSG9sZHMgdGhlIGluZGVudGF0aW9uIGZvciB0aGUgY3VycmVudCBsaW5lIHRoYXQgaXMgbm93IGFjY3VtdWxhdGluZyBpbgotICAgICAqIG1lbW9yeSBhbmQgd2lsbCBiZSBzZW50IGZvciBwcmludGluZyBzaG9ydGx5LgotICAgICAqLwotICAgIHByaXZhdGUgaW50ICAgICAgICAgICAgIF90aGlzSW5kZW50OwotCi0KLSAgICAvKioKLSAgICAgKiBIb2xkcyB0aGUgaW5kZW50YXRpb24gZm9yIHRoZSBuZXh0IGxpbmUgdG8gYmUgcHJpbnRlZC4gQWZ0ZXIgdGhpcyBsaW5lIGlzCi0gICAgICogcHJpbnRlZCwge0BsaW5rICNfbmV4dEluZGVudH0gaXMgYXNzaWduZWQgdG8ge0BsaW5rICNfdGhpc0luZGVudH0uCi0gICAgICovCi0gICAgcHJpdmF0ZSBpbnQgICAgICAgICAgICAgX25leHRJbmRlbnQ7Ci0KLQotICAgIHB1YmxpYyBJbmRlbnRQcmludGVyKCBXcml0ZXIgd3JpdGVyLCBPdXRwdXRGb3JtYXQgZm9ybWF0KQotICAgIHsKLSAgICAgICAgc3VwZXIoIHdyaXRlciwgZm9ybWF0ICk7Ci0gICAgICAgIC8vIEluaXRpYWxpemUgZXZlcnl0aGluZyBmb3IgYSBmaXJzdC9zZWNvbmQgcnVuLgotICAgICAgICBfbGluZSA9IG5ldyBTdHJpbmdCdWZmZXIoIDgwICk7Ci0gICAgICAgIF90ZXh0ID0gbmV3IFN0cmluZ0J1ZmZlciggMjAgKTsKLSAgICAgICAgX3NwYWNlcyA9IDA7Ci0gICAgICAgIF90aGlzSW5kZW50ID0gX25leHRJbmRlbnQgPSAwOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogQ2FsbGVkIGJ5IGFueSBvZiB0aGUgRFREIGhhbmRsZXJzIHRvIGVudGVyIERURCBtb2RlLgotICAgICAqIE9uY2UgZW50ZXJlZCwgYWxsIG91dHB1dCB3aWxsIGJlIGFjY3VtdWxhdGVkIGluIGEgc3RyaW5nCi0gICAgICogdGhhdCBjYW4gYmUgcHJpbnRlZCBhcyBwYXJ0IG9mIHRoZSBkb2N1bWVudCdzIERURC4KLSAgICAgKiBUaGlzIG1ldGhvZCBtYXkgYmUgY2FsbGVkIGFueSBudW1iZXIgb2YgdGltZSBidXQgd2lsbCBvbmx5Ci0gICAgICogaGF2ZSBhZmZlY3QgdGhlIGZpcnN0IHRpbWUgaXQncyBjYWxsZWQuIFRvIGV4aXN0IERURCBzdGF0ZQotICAgICAqIGFuZCBnZXQgdGhlIGFjY3VtdWxhdGVkIERURCwgY2FsbCB7QGxpbmsgI2xlYXZlRFREfS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbnRlckRURCgpCi0gICAgewotICAgICAgICAvLyBDYW4gb25seSBlbnRlciBEVEQgc3RhdGUgb25jZS4gT25jZSB3ZSdyZSBvdXQgb2YgRFRECi0gICAgICAgIC8vIHN0YXRlLCBjYW4gbm8gbG9uZ2VyIHJlLWVudGVyIGl0LgotICAgICAgICBpZiAoIF9kdGRXcml0ZXIgPT0gbnVsbCApIHsKLSAgICAgICAgICAgIF9saW5lLmFwcGVuZCggX3RleHQgKTsKLSAgICAgICAgICAgIF90ZXh0ID0gbmV3IFN0cmluZ0J1ZmZlciggMjAgKTsKLSAgICAgICAgICAgIGZsdXNoTGluZSggZmFsc2UgKTsKLSAgICAgICAgICAgIF9kdGRXcml0ZXIgPSBuZXcgU3RyaW5nV3JpdGVyKCk7Ci0gICAgICAgICAgICBfZG9jV3JpdGVyID0gX3dyaXRlcjsKLSAgICAgICAgICAgIF93cml0ZXIgPSBfZHRkV3JpdGVyOwotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBDYWxsZWQgYnkgdGhlIHJvb3QgZWxlbWVudCB0byBsZWF2ZSBEVEQgbW9kZSBhbmQgaWYgYW55Ci0gICAgICogRFREIHBhcnRzIHdlcmUgcHJpbnRlciwgd2lsbCByZXR1cm4gYSBzdHJpbmcgd2l0aCB0aGVpcgotICAgICAqIHRleHR1YWwgY29udGVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGxlYXZlRFREKCkKLSAgICB7Ci0gICAgICAgIC8vIE9ubHkgd29ya3MgaWYgd2UncmUgZ29pbmcgb3V0IG9mIERURCBtb2RlLgotICAgICAgICBpZiAoIF93cml0ZXIgPT0gX2R0ZFdyaXRlciApIHsKLSAgICAgICAgICAgIF9saW5lLmFwcGVuZCggX3RleHQgKTsKLSAgICAgICAgICAgIF90ZXh0ID0gbmV3IFN0cmluZ0J1ZmZlciggMjAgKTsKLSAgICAgICAgICAgIGZsdXNoTGluZSggZmFsc2UgKTsKLSAgICAgICAgICAgIF93cml0ZXIgPSBfZG9jV3JpdGVyOwotICAgICAgICAgICAgcmV0dXJuIF9kdGRXcml0ZXIudG9TdHJpbmcoKTsKLSAgICAgICAgfSBlbHNlCi0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIENhbGxlZCB0byBwcmludCBhZGRpdGlvbmFsIHRleHQuIEVhY2ggdGltZSB0aGlzIG1ldGhvZCBpcyBjYWxsZWQKLSAgICAgKiBpdCBhY2N1bXVsYXRlcyBtb3JlIHRleHQuIFdoZW4gYSBzcGFjZSBpcyBwcmludGVkICh7QGxpbmsKLSAgICAgKiAjcHJpbnRTcGFjZX0pIGFsbCB0aGUgYWNjdW11bGF0ZWQgdGV4dCBiZWNvbWVzIG9uZSBwYXJ0IGFuZCBpcwotICAgICAqIGFkZGVkIHRvIHRoZSBhY2N1bXVsYXRlIGxpbmUuIFdoZW4gYSBsaW5lIGlzIGxvbmcgZW5vdWdoLCBpdCBjYW4KLSAgICAgKiBiZSBicm9rZW4gYXQgaXRzIHRleHQgYm91bmRhcnkuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdGV4dCBUaGUgdGV4dCB0byBwcmludAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHByaW50VGV4dCggU3RyaW5nIHRleHQgKQotICAgIHsKLSAgICAgICAgX3RleHQuYXBwZW5kKCB0ZXh0ICk7Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgdm9pZCBwcmludFRleHQoIFN0cmluZ0J1ZmZlciB0ZXh0ICkKLSAgICB7Ci0gICAgICAgIF90ZXh0LmFwcGVuZCggdGV4dC50b1N0cmluZygpICk7Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgdm9pZCBwcmludFRleHQoIGNoYXIgY2ggKQotICAgIHsKLSAgICAgICAgX3RleHQuYXBwZW5kKCBjaCApOwotICAgIH0KLQotCi0gICAgcHVibGljIHZvaWQgcHJpbnRUZXh0KCBjaGFyW10gY2hhcnMsIGludCBzdGFydCwgaW50IGxlbmd0aCApCi0gICAgewotICAgICAgICBfdGV4dC5hcHBlbmQoIGNoYXJzLCBzdGFydCwgbGVuZ3RoICk7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBDYWxsZWQgdG8gcHJpbnQgYSBzaW5nbGUgc3BhY2UgYmV0d2VlbiB0ZXh0IHBhcnRzIHRoYXQgbWF5IGJlCi0gICAgICogYnJva2VuIGludG8gc2VwYXJhdGUgbGluZXMuIE11c3Qgbm90IGJlIGNhbGxlZCB0byBwcmludCBhIHNwYWNlCi0gICAgICogd2hlbiBwcmVzZXJ2aW5nIHNwYWNlcy4gVGhlIHRleHQgYWNjdW11bGF0ZWQgc28gZmFyIHdpdGgge0BsaW5rCi0gICAgICogI3ByaW50VGV4dH0gd2lsbCBiZSBhZGRlZCB0byB0aGUgYWNjdW11bGF0ZWQgbGluZSwgYW5kIGEgc3BhY2UKLSAgICAgKiBzZXBhcmF0b3Igd2lsbCBiZSBjb3VudGVkLiBJZiB0aGUgbGluZSBhY2N1bXVsYXRlZCBzbyBmYXIgaXMKLSAgICAgKiBsb25nIGVub3VnaCwgaXQgd2lsbCBiZSBwcmludGVkLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHByaW50U3BhY2UoKQotICAgIHsKLSAgICAgICAgLy8gVGhlIGxpbmUgY29uc2lzdHMgb2YgdGhlIHRleHQgYWNjdW11bGF0ZWQgaW4gX2xpbmUsCi0gICAgICAgIC8vIGZvbGxvd2VkIGJ5IG9uZSBvciBtb3JlIHNwYWNlcyBhcyBjb3VudGVkIGJ5IF9zcGFjZXMsCi0gICAgICAgIC8vIGZvbGxvd2VkIGJ5IG1vcmUgc3BhY2UgYWNjdW11bGF0ZWQgaW4gX3RleHQ6Ci0gICAgICAgIC8vIC0gIFRleHQgaXMgcHJpbnRlZCBhbmQgYWNjdW11bGF0ZWQgaW50byBfdGV4dC4KLSAgICAgICAgLy8gLSAgQSBzcGFjZSBpcyBwcmludGVkLCBzbyBfdGV4dCBpcyBhZGRlZCB0byBfbGluZSBhbmQKLSAgICAgICAgLy8gICAgYSBzcGFjZSBpcyBjb3VudGVkLgotICAgICAgICAvLyAtICBNb3JlIHRleHQgaXMgcHJpbnRlZCBhbmQgYWNjdW11bGF0ZWQgaW50byBfdGV4dC4KLSAgICAgICAgLy8gLSAgQSBzcGFjZSBpcyBwcmludGVkLCB0aGUgcHJldmlvdXMgc3BhY2VzIGFyZSBhZGRlZAotICAgICAgICAvLyAgICB0byBfbGluZSwgdGhlIF90ZXh0IGlzIGFkZGVkIHRvIF9saW5lLCBhbmQgYSBuZXcKLSAgICAgICAgLy8gICAgc3BhY2UgaXMgY291bnRlZC4KLQotICAgICAgICAvLyBJZiB0ZXh0IHdhcyBhY2N1bXVsYXRlZCB3aXRoIHByaW50VGV4dCgpLCB0aGVuIHRoZSBzcGFjZQotICAgICAgICAvLyBtZWFucyB3ZSBoYXZlIHRvIG1vdmUgdGhhdCB0ZXh0IGludG8gdGhlIGxpbmUgYW5kCi0gICAgICAgIC8vIHN0YXJ0IGFjY3VtdWxhdGluZyBuZXcgdGV4dCB3aXRoIHByaW50VGV4dCgpLgotICAgICAgICBpZiAoIF90ZXh0Lmxlbmd0aCgpID4gMCApIHsKLSAgICAgICAgICAgIC8vIElmIHRoZSB0ZXh0IGJyZWFrcyBhIGxpbmUgYm91bmFyeSwgd3JhcCB0byB0aGUgbmV4dCBsaW5lLgotICAgICAgICAgICAgLy8gVGhlIHByaW50ZWQgbGluZSBzaXplIGNvbnNpc3RzIG9mIHRoZSBpbmRlbnRhdGlvbiB3ZSdyZSBnb2luZwotICAgICAgICAgICAgLy8gdG8gdXNlIG5leHQsIHRoZSBhY2N1bXVsYXRlZCBsaW5lIHNvIGZhciwgc29tZSBzcGFjZXMgYW5kIHRoZQotICAgICAgICAgICAgLy8gYWNjdW11bGF0ZWQgdGV4dCBzbyBmYXIuCi0gICAgICAgICAgICBpZiAoIF9mb3JtYXQuZ2V0TGluZVdpZHRoKCkgPiAwICYmCi0gICAgICAgICAgICAgICAgIF90aGlzSW5kZW50ICsgX2xpbmUubGVuZ3RoKCkgKyBfc3BhY2VzICsgX3RleHQubGVuZ3RoKCkgPiBfZm9ybWF0LmdldExpbmVXaWR0aCgpICkgewotICAgICAgICAgICAgICAgIGZsdXNoTGluZSggZmFsc2UgKTsKLSAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICAvLyBQcmludCBsaW5lIGFuZCBuZXcgbGluZSwgdGhlbiB6ZXJvIHRoZSBsaW5lIGNvbnRlbnRzLgotICAgICAgICAgICAgICAgICAgICBfd3JpdGVyLndyaXRlKCBfZm9ybWF0LmdldExpbmVTZXBhcmF0b3IoKSApOwotICAgICAgICAgICAgICAgIH0gY2F0Y2ggKCBJT0V4Y2VwdGlvbiBleGNlcHQgKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIFdlIGRvbid0IHRocm93IGFuIGV4Y2VwdGlvbiwgYnV0IGhvbGQgaXQKLSAgICAgICAgICAgICAgICAgICAgLy8gdW50aWwgdGhlIGVuZCBvZiB0aGUgZG9jdW1lbnQuCi0gICAgICAgICAgICAgICAgICAgIGlmICggX2V4Y2VwdGlvbiA9PSBudWxsICkKLSAgICAgICAgICAgICAgICAgICAgICAgIF9leGNlcHRpb24gPSBleGNlcHQ7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBBZGQgYXMgbWFueSBzcGFjZXMgYXMgd2UgYWNjdW11bGFlZCBiZWZvcmUuCi0gICAgICAgICAgICAvLyBBdCB0aGUgZW5kIG9mIHRoaXMgbG9vcCwgX3NwYWNlcyBpcyB6ZXJvLgotICAgICAgICAgICAgd2hpbGUgKCBfc3BhY2VzID4gMCApIHsKLSAgICAgICAgICAgICAgICBfbGluZS5hcHBlbmQoICcgJyApOwotICAgICAgICAgICAgICAgIC0tX3NwYWNlczsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIF9saW5lLmFwcGVuZCggX3RleHQgKTsKLSAgICAgICAgICAgIF90ZXh0ID0gbmV3IFN0cmluZ0J1ZmZlciggMjAgKTsKLSAgICAgICAgfQotICAgICAgICAvLyBTdGFydGluZyBhIG5ldyB3b3JkOiBhY2N1bXVsYXRlIHRoZSB0ZXh0IGJldHdlZW4gdGhlIGxpbmUKLSAgICAgICAgLy8gYW5kIHRoaXMgbmV3IHdvcmQ7IG5vdCBhIG5ldyB3b3JkOiBqdXN0IGFkZCBhbm90aGVyIHNwYWNlLgotICAgICAgICArK19zcGFjZXM7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBDYWxsZWQgdG8gcHJpbnQgYSBsaW5lIGNvbnNpc3Rpbmcgb2YgdGhlIHRleHQgYWNjdW11bGF0ZWQgc28KLSAgICAgKiBmYXIuIFRoaXMgaXMgZXF1aXZhbGVudCB0byBjYWxsaW5nIHtAbGluayAjcHJpbnRTcGFjZX0gYnV0Ci0gICAgICogZm9yY2luZyB0aGUgbGluZSB0byBwcmludCBhbmQgc3RhcnRpbmcgYSBuZXcgbGluZSAoe0BsaW5rCi0gICAgICogI3ByaW50U3BhY2V9IHdpbGwgb25seSBzdGFydCBhIG5ldyBsaW5lIGlmIHRoZSBjdXJyZW50IGxpbmUKLSAgICAgKiBpcyBsb25nIGVub3VnaCkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgYnJlYWtMaW5lKCkKLSAgICB7Ci0gICAgICAgIGJyZWFrTGluZSggZmFsc2UgKTsKLSAgICB9Ci0KLQotICAgIHB1YmxpYyB2b2lkIGJyZWFrTGluZSggYm9vbGVhbiBwcmVzZXJ2ZVNwYWNlICkKLSAgICB7Ci0gICAgICAgIC8vIEVxdWl2YWxlbnQgdG8gY2FsbGluZyBwcmludFNwYWNlIGFuZCBmb3JjaW5nIGEgZmx1c2hMaW5lLgotICAgICAgICBpZiAoIF90ZXh0Lmxlbmd0aCgpID4gMCApIHsKLSAgICAgICAgICAgIHdoaWxlICggX3NwYWNlcyA+IDAgKSB7Ci0gICAgICAgICAgICAgICAgX2xpbmUuYXBwZW5kKCAnICcgKTsKLSAgICAgICAgICAgICAgICAtLV9zcGFjZXM7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBfbGluZS5hcHBlbmQoIF90ZXh0ICk7Ci0gICAgICAgICAgICBfdGV4dCA9IG5ldyBTdHJpbmdCdWZmZXIoIDIwICk7Ci0gICAgICAgIH0KLSAgICAgICAgZmx1c2hMaW5lKCBwcmVzZXJ2ZVNwYWNlICk7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAvLyBQcmludCBsaW5lIGFuZCBuZXcgbGluZSwgdGhlbiB6ZXJvIHRoZSBsaW5lIGNvbnRlbnRzLgotICAgICAgICAgICAgX3dyaXRlci53cml0ZSggX2Zvcm1hdC5nZXRMaW5lU2VwYXJhdG9yKCkgKTsKLSAgICAgICAgfSBjYXRjaCAoIElPRXhjZXB0aW9uIGV4Y2VwdCApIHsKLSAgICAgICAgICAgIC8vIFdlIGRvbid0IHRocm93IGFuIGV4Y2VwdGlvbiwgYnV0IGhvbGQgaXQKLSAgICAgICAgICAgIC8vIHVudGlsIHRoZSBlbmQgb2YgdGhlIGRvY3VtZW50LgotICAgICAgICAgICAgaWYgKCBfZXhjZXB0aW9uID09IG51bGwgKQotICAgICAgICAgICAgICAgIF9leGNlcHRpb24gPSBleGNlcHQ7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIEZsdXNoZXMgdGhlIGxpbmUgYWNjdW11bGF0ZWQgc28gZmFyIHRvIHRoZSB3cml0ZXIgYW5kIGdldCByZWFkeQotICAgICAqIHRvIGFjY3VtdWxhdGUgdGhlIG5leHQgbGluZS4gVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHtAbGluawotICAgICAqICNwcmludFRleHR9IGFuZCB7QGxpbmsgI3ByaW50U3BhY2V9IHdoZW4gdGhlIGFjY3VtdWxhdGVkIGxpbmUgcGx1cwotICAgICAqIGFjY3VtdWxhdGVkIHRleHQgYXJlIHR3byBsb25nIHRvIGZpdCBvbiBhIGdpdmVuIGxpbmUuIEF0IHRoZSBlbmQgb2YKLSAgICAgKiB0aGlzIG1ldGhvZCBfbGluZSBpcyBlbXB0eSBhbmQgX3NwYWNlcyBpcyB6ZXJvLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGZsdXNoTGluZSggYm9vbGVhbiBwcmVzZXJ2ZVNwYWNlICkKLSAgICB7Ci0gICAgICAgIGludCAgICAgaW5kZW50OwotCi0gICAgICAgIGlmICggX2xpbmUubGVuZ3RoKCkgPiAwICkgewotICAgICAgICAgICAgdHJ5IHsKLQotICAgICAgICAgICAgICAgIGlmICggX2Zvcm1hdC5nZXRJbmRlbnRpbmcoKSAmJiAhIHByZXNlcnZlU3BhY2UgKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIE1ha2Ugc3VyZSB0aGUgaW5kZW50YXRpb24gZG9lcyBub3QgYmxvdyB1cyBhd2F5LgotICAgICAgICAgICAgICAgICAgICBpbmRlbnQgPSBfdGhpc0luZGVudDsKLSAgICAgICAgICAgICAgICAgICAgaWYgKCAoIDIgKiBpbmRlbnQgKSA+IF9mb3JtYXQuZ2V0TGluZVdpZHRoKCkgJiYgX2Zvcm1hdC5nZXRMaW5lV2lkdGgoKSA+IDAgKQotICAgICAgICAgICAgICAgICAgICAgICAgaW5kZW50ID0gX2Zvcm1hdC5nZXRMaW5lV2lkdGgoKSAvIDI7Ci0gICAgICAgICAgICAgICAgICAgIC8vIFByaW50IHRoZSBpbmRlbnRhdGlvbiBhcyBzcGFjZXMgYW5kIHNldCB0aGUgY3VycmVudAotICAgICAgICAgICAgICAgICAgICAvLyBpbmRlbnRhdGlvbiB0byB0aGUgbmV4dCBleHBlY3RlZCBpbmRlbnRhdGlvbi4KLSAgICAgICAgICAgICAgICAgICAgd2hpbGUgKCBpbmRlbnQgPiAwICkgewotICAgICAgICAgICAgICAgICAgICAgICAgX3dyaXRlci53cml0ZSggJyAnICk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAtLWluZGVudDsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBfdGhpc0luZGVudCA9IF9uZXh0SW5kZW50OwotCi0gICAgICAgICAgICAgICAgLy8gVGhlcmUgaXMgbm8gbmVlZCB0byBwcmludCB0aGUgc3BhY2VzIGF0IHRoZSBlbmQgb2YgdGhlIGxpbmUsCi0gICAgICAgICAgICAgICAgLy8gdGhleSBhcmUgc2ltcGx5IHN0cmlwcGVkIGFuZCByZXBsYWNlZCB3aXRoIGEgc2luZ2xlIGxpbmUKLSAgICAgICAgICAgICAgICAvLyBzZXBhcmF0b3IuCi0gICAgICAgICAgICAgICAgX3NwYWNlcyA9IDA7Ci0gICAgICAgICAgICAgICAgX3dyaXRlci53cml0ZSggX2xpbmUudG9TdHJpbmcoKSApOwotCi0gICAgICAgICAgICAgICAgX2xpbmUgPSBuZXcgU3RyaW5nQnVmZmVyKCA0MCApOwotICAgICAgICAgICAgfSBjYXRjaCAoIElPRXhjZXB0aW9uIGV4Y2VwdCApIHsKLSAgICAgICAgICAgICAgICAvLyBXZSBkb24ndCB0aHJvdyBhbiBleGNlcHRpb24sIGJ1dCBob2xkIGl0Ci0gICAgICAgICAgICAgICAgLy8gdW50aWwgdGhlIGVuZCBvZiB0aGUgZG9jdW1lbnQuCi0gICAgICAgICAgICAgICAgaWYgKCBfZXhjZXB0aW9uID09IG51bGwgKQotICAgICAgICAgICAgICAgICAgICBfZXhjZXB0aW9uID0gZXhjZXB0OwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBGbHVzaCB0aGUgb3V0cHV0IHN0cmVhbS4gTXVzdCBiZSBjYWxsZWQgd2hlbiBkb25lIHByaW50aW5nCi0gICAgICogdGhlIGRvY3VtZW50LCBvdGhlcndpc2Ugc29tZSB0ZXh0IG1pZ2h0IGJlIGJ1ZmZlcmVkLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGZsdXNoKCkKLSAgICB7Ci0gICAgICAgIGlmICggX2xpbmUubGVuZ3RoKCkgPiAwIHx8IF90ZXh0Lmxlbmd0aCgpID4gMCApCi0gICAgICAgICAgICBicmVha0xpbmUoKTsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIF93cml0ZXIuZmx1c2goKTsKLSAgICAgICAgfSBjYXRjaCAoIElPRXhjZXB0aW9uIGV4Y2VwdCApIHsKLSAgICAgICAgICAgIC8vIFdlIGRvbid0IHRocm93IGFuIGV4Y2VwdGlvbiwgYnV0IGhvbGQgaXQKLSAgICAgICAgICAgIC8vIHVudGlsIHRoZSBlbmQgb2YgdGhlIGRvY3VtZW50LgotICAgICAgICAgICAgaWYgKCBfZXhjZXB0aW9uID09IG51bGwgKQotICAgICAgICAgICAgICAgIF9leGNlcHRpb24gPSBleGNlcHQ7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIEluY3JlbWVudCB0aGUgaW5kZW50YXRpb24gZm9yIHRoZSBuZXh0IGxpbmUuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgaW5kZW50KCkKLSAgICB7Ci0gICAgICAgIF9uZXh0SW5kZW50ICs9IF9mb3JtYXQuZ2V0SW5kZW50KCk7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBEZWNyZW1lbnQgdGhlIGluZGVudGF0aW9uIGZvciB0aGUgbmV4dCBsaW5lLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHVuaW5kZW50KCkKLSAgICB7Ci0gICAgICAgIF9uZXh0SW5kZW50IC09IF9mb3JtYXQuZ2V0SW5kZW50KCk7Ci0gICAgICAgIGlmICggX25leHRJbmRlbnQgPCAwICkKLSAgICAgICAgICAgIF9uZXh0SW5kZW50ID0gMDsKLSAgICAgICAgLy8gSWYgdGhlcmUgaXMgbm8gY3VycmVudCBsaW5lIGFuZCB3ZSdyZSBkZS1pZGVudGluZyB0aGVuCi0gICAgICAgIC8vIHRoaXMgaW5kZW50YXRpb24gbGV2ZWwgaXMgYWN0dWFsbHkgdGhlIG5leHQgbGV2ZWwuCi0gICAgICAgIGlmICggKCBfbGluZS5sZW5ndGgoKSArIF9zcGFjZXMgKyBfdGV4dC5sZW5ndGgoKSApID09IDAgKQotICAgICAgICAgICAgX3RoaXNJbmRlbnQgPSBfbmV4dEluZGVudDsKLSAgICB9Ci0KLQotICAgIHB1YmxpYyBpbnQgZ2V0TmV4dEluZGVudCgpCi0gICAgewotICAgICAgICByZXR1cm4gX25leHRJbmRlbnQ7Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgdm9pZCBzZXROZXh0SW5kZW50KCBpbnQgaW5kZW50ICkKLSAgICB7Ci0gICAgICAgIF9uZXh0SW5kZW50ID0gaW5kZW50OwotICAgIH0KLQotCi0gICAgcHVibGljIHZvaWQgc2V0VGhpc0luZGVudCggaW50IGluZGVudCApCi0gICAgewotICAgICAgICBfdGhpc0luZGVudCA9IGluZGVudDsKLSAgICB9Ci0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplL0xpbmVTZXBhcmF0b3IuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZS9MaW5lU2VwYXJhdG9yLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGJiNGIxYjkuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplL0xpbmVTZXBhcmF0b3IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDU3ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwMiwyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplOwotCi0KLS8qKgotICogQGF1dGhvciA8YSBocmVmPSJtYWlsdG86YXJraW5AaW50YWxpby4uY29tIj5Bc3NhZiBBcmtpbjwvYT4KLSAqIEBzZWUgT3V0cHV0Rm9ybWF0Ci0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBMaW5lU2VwYXJhdG9yCi17Ci0KLQotICAgIC8qKgotICAgICAqIExpbmUgc2VwYXJhdG9yIGZvciBVbml4IHN5c3RlbXMgKDx0dD5cbjwvdHQ+KS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBVbml4ID0gIlxuIjsKLQotCi0gICAgLyoqCi0gICAgICogTGluZSBzZXBhcmF0b3IgZm9yIFdpbmRvd3Mgc3lzdGVtcyAoPHR0PlxyXG48L3R0PikuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV2luZG93cyA9ICJcclxuIjsKLQotCi0gICAgLyoqCi0gICAgICogTGluZSBzZXBhcmF0b3IgZm9yIE1hY2ludG9zaCBzeXN0ZW1zICg8dHQ+XHI8L3R0PikuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTWFjaW50b3NoID0gIlxyIjsKLQotCi0gICAgLyoqCi0gICAgICogTGluZSBzZXBhcmF0b3IgZm9yIHRoZSBXZWIgKDx0dD5cbjwvdHQ+KS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXZWIgPSAiXG4iOwotCi0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZS9NZXRob2QuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZS9NZXRob2QuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYzZjZmZmMC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemUvTWV0aG9kLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw2MyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZTsKLQotCi0vKioKLSAqIEBhdXRob3IgPGEgaHJlZj0ibWFpbHRvOmFya2luQGludGFsaW8uY29tIj5Bc3NhZiBBcmtpbjwvYT4KLSAqIEBzZWUgT3V0cHV0Rm9ybWF0Ci0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBNZXRob2QKLXsKLQotCi0gICAgLyoqCi0gICAgICogVGhlIG91dHB1dCBtZXRob2QgZm9yIFhNTCBkb2N1bWVudHMuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MID0gInhtbCI7Ci0KLQotICAgIC8qKgotICAgICAqIFRoZSBvdXRwdXQgbWV0aG9kIGZvciBIVE1MIGRvY3VtZW50cy4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBIVE1MID0gImh0bWwiOwotCi0KLSAgICAvKioKLSAgICAgKiBUaGUgb3V0cHV0IG1ldGhvZCBmb3IgSFRNTCBkb2N1bWVudHMgYXMgWEhUTUwuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgWEhUTUwgPSAieGh0bWwiOwotCi0KLSAgICAvKioKLSAgICAgKiBUaGUgb3V0cHV0IG1ldGhvZCBmb3IgdGV4dCBkb2N1bWVudHMuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgVEVYVCA9ICJ0ZXh0IjsKLQotCi0gICAgLyoqCi0gICAgICogVGhlIG91dHB1dCBtZXRob2QgZm9yIEZPIGRvY3VtZW50cyBhcyBQREYuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRk9QID0gImZvcCI7Ci0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplL091dHB1dEZvcm1hdC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplL091dHB1dEZvcm1hdC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1MDVhODk5Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZS9PdXRwdXRGb3JtYXQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDk2MSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLQotLy8gQXVnIDIxLCAyMDAwOgotLy8gIEFkZGVkIGFiaWxpdHkgdG8gb21pdCBET0NUWVBFIGRlY2xhcmF0aW9uLgotLy8gIFJlcG9ydGVkIGJ5IExhcnMgTWFydGluIDxsYXJzQHNtYi10ZWMuY29tPgotLy8gQXVnIDI1LCAyMDAwOgotLy8gIEFkZGVkIGFiaWxpdHkgdG8gb21pdCBjb21tZW50cy4KLS8vICBDb250cmlidXRlZCBieSBBbnVwYW0gQmFnY2hpIDxhYmFnY2hpQGp0Y3N2LmNvbT4KLQotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplOwotCi0KLWltcG9ydCBqYXZhLmlvLlVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb247Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKLWltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudFR5cGU7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcudzNjLmRvbS5odG1sLkhUTUxEb2N1bWVudDsKLQotCi0vKioKLSAqIFNwZWNpZmllcyBhbiBvdXRwdXQgZm9ybWF0IHRvIGNvbnRyb2wgdGhlIHNlcmlhbGl6ZXIuIEJhc2VkIG9uIHRoZQotICogWFNMVCBzcGVjaWZpY2F0aW9uIGZvciBvdXRwdXQgZm9ybWF0LCBwbHVzIGFkZGl0aW9uYWwgcGFyYW1ldGVycy4KLSAqIFVzZWQgdG8gc2VsZWN0IHRoZSBzdWl0YWJsZSBzZXJpYWxpemVyIGFuZCBkZXRlcm1pbmUgaG93IHRoZQotICogZG9jdW1lbnQgc2hvdWxkIGJlIGZvcm1hdHRlZCBvbiBvdXRwdXQuCi0gKiA8cD4KLSAqIFRoZSB0d28gaW50ZXJlc3RpbmcgY29uc3RydWN0b3JzIGFyZToKLSAqIDx1bD4KLSAqIDxsaT57QGxpbmsgI091dHB1dEZvcm1hdChTdHJpbmcsU3RyaW5nLGJvb2xlYW4pfSBjcmVhdGVzIGEgZm9ybWF0Ci0gKiAgZm9yIHRoZSBzcGVjaWZpZWQgbWV0aG9kIChYTUwsIEhUTUwsIFRleHQsIGV0YyksIGVuY29kaW5nIGFuZCBpbmRlbnRhdGlvbgotICogPGxpPntAbGluayAjT3V0cHV0Rm9ybWF0KERvY3VtZW50LFN0cmluZyxib29sZWFuKX0gY3JlYXRlcyBhIGZvcm1hdAotICogIGNvbXBhdGlibGUgd2l0aCB0aGUgZG9jdW1lbnQgdHlwZSAoWE1MLCBIVE1MLCBUZXh0LCBldGMpLCBlbmNvZGluZyBhbmQKLSAqICBpbmRlbnRhdGlvbgotICogPC91bD4KLSAqCi0gKgotICogQGF1dGhvciA8YSBocmVmPSJtYWlsdG86YXJraW5AaW50YWxpby5jb20iPkFzc2FmIEFya2luPC9hPgotICogICAgICAgICA8YSBocmVmPSJtYWlsdG86dmlzY29AaW50YWxpby5jb20iPktlaXRoIFZpc2NvPC9hPgotICogQHNlZSBTZXJpYWxpemVyCi0gKiBAc2VlIE1ldGhvZAotICogQHNlZSBMaW5lU2VwYXJhdG9yCi0gKi8KLXB1YmxpYyBjbGFzcyBPdXRwdXRGb3JtYXQKLXsKLQotCi0gICAgcHVibGljIHN0YXRpYyBjbGFzcyBEVEQKLSAgICB7Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFB1YmxpYyBpZGVudGlmaWVyIGZvciBIVE1MIDQuMDEgKFN0cmljdCkgZG9jdW1lbnQgdHlwZS4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEhUTUxQdWJsaWNJZCA9ICItLy9XM0MvL0RURCBIVE1MIDQuMDEvL0VOIjsKLQotICAgICAgICAvKioKLSAgICAgICAgICogU3lzdGVtIGlkZW50aWZpZXIgZm9yIEhUTUwgNC4wMSAoU3RyaWN0KSBkb2N1bWVudCB0eXBlLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSFRNTFN5c3RlbUlkID0KLSAgICAgICAgICAgICJodHRwOi8vd3d3LnczLm9yZy9UUi9odG1sNC9zdHJpY3QuZHRkIjsKLQotICAgICAgICAvKioKLSAgICAgICAgICogUHVibGljIGlkZW50aWZpZXIgZm9yIFhIVE1MIDEuMCAoU3RyaWN0KSBkb2N1bWVudCB0eXBlLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgWEhUTUxQdWJsaWNJZCA9Ci0gICAgICAgICAgICAiLS8vVzNDLy9EVEQgWEhUTUwgMS4wIFN0cmljdC8vRU4iOwotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBTeXN0ZW0gaWRlbnRpZmllciBmb3IgWEhUTUwgMS4wIChTdHJpY3QpIGRvY3VtZW50IHR5cGUuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBYSFRNTFN5c3RlbUlkID0KLSAgICAgICAgICAgICJodHRwOi8vd3d3LnczLm9yZy9UUi94aHRtbDEvRFREL3hodG1sMS1zdHJpY3QuZHRkIjsKLQotICAgIH0KLQotCi0gICAgcHVibGljIHN0YXRpYyBjbGFzcyBEZWZhdWx0cwotICAgIHsKLQotICAgICAgICAvKioKLSAgICAgICAgICogSWYgaW5kZW50YXRpb24gaXMgdHVybmVkIG9uLCB0aGUgZGVmYXVsdCBpZGVudGF0aW9uCi0gICAgICAgICAqIGxldmVsIGlzIDQuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBzZWUgI3NldEluZGVudGluZyhib29sZWFuKQotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSW5kZW50ID0gNDsKLQotICAgICAgICAvKioKLSAgICAgICAgICogVGhlIGRlZmF1bHQgZW5jb2RpbmcgZm9yIFdlYiBkb2N1bWVudHMgaXQgVVRGLTguCi0gICAgICAgICAqCi0gICAgICAgICAqIEBzZWUgI2dldEVuY29kaW5nKCkKLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVuY29kaW5nID0gIlVURi04IjsKLQotICAgICAgICAvKioKLSAgICAgICAgICogVGhlIGRlZmF1bHQgbGluZSB3aWR0aCBhdCB3aGljaCB0byBicmVhayBsb25nIGxpbmVzCi0gICAgICAgICAqIHdoZW4gaWRlbnRpbmcuIFRoaXMgaXMgc2V0IHRvIDcyLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTGluZVdpZHRoID0gNzI7Ci0KLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIEhvbGRzIHRoZSBvdXRwdXQgbWV0aG9kIHNwZWNpZmllZCBmb3IgdGhpcyBkb2N1bWVudCwKLSAgICAgKiBvciBudWxsIGlmIG5vIG1ldGhvZCB3YXMgc3BlY2lmaWVkLgotICAgICAqLwotICAgIHByaXZhdGUgU3RyaW5nIF9tZXRob2Q7Ci0KLQotICAgIC8qKgotICAgICAqIFNwZWNpZmllcyB0aGUgdmVyc2lvbiBvZiB0aGUgb3V0cHV0IG1ldGhvZC4KLSAgICAgKi8KLSAgICBwcml2YXRlIFN0cmluZyBfdmVyc2lvbjsKLQotCi0gICAgLyoqCi0gICAgICogVGhlIGluZGVudGF0aW9uIGxldmVsLCBvciB6ZXJvIGlmIG5vIGluZGVudGF0aW9uCi0gICAgICogd2FzIHJlcXVlc3RlZC4KLSAgICAgKi8KLSAgICBwcml2YXRlIGludCBfaW5kZW50ID0gMDsKLQotCi0gICAgLyoqCi0gICAgICogVGhlIGVuY29kaW5nIHRvIHVzZSwgaWYgYW4gaW5wdXQgc3RyZWFtIGlzIHVzZWQuCi0gICAgICogVGhlIGRlZmF1bHQgaXMgYWx3YXlzIFVURi04LgotICAgICAqLwotICAgIHByaXZhdGUgU3RyaW5nIF9lbmNvZGluZyA9IERlZmF1bHRzLkVuY29kaW5nOwotCi0gICAgLyoqCi0gICAgICogVGhlIEVuY29kaW5nSW5mbyBpbnN0YW5jZSBmb3IgX2VuY29kaW5nLgotICAgICAqLwotICAgIHByaXZhdGUgRW5jb2RpbmdJbmZvIF9lbmNvZGluZ0luZm8gPSBudWxsOwotCi0gICAgLy8gd2hldGhlciBqYXZhIG5hbWVzIGZvciBlbmNvZGluZ3MgYXJlIHBlcm1pdHRlZAotICAgIHByaXZhdGUgYm9vbGVhbiBfYWxsb3dKYXZhTmFtZXMgPSBmYWxzZTsKLQotICAgIC8qKgotICAgICAqIFRoZSBzcGVjaWZpZWQgbWVkaWEgdHlwZSBvciBudWxsLgotICAgICAqLwotICAgIHByaXZhdGUgU3RyaW5nIF9tZWRpYVR5cGU7Ci0KLQotICAgIC8qKgotICAgICAqIFRoZSBzcGVjaWZpZWQgZG9jdW1lbnQgdHlwZSBzeXN0ZW0gaWRlbnRpZmllciwgb3IgbnVsbC4KLSAgICAgKi8KLSAgICBwcml2YXRlIFN0cmluZyBfZG9jdHlwZVN5c3RlbTsKLQotCi0gICAgLyoqCi0gICAgICogVGhlIHNwZWNpZmllZCBkb2N1bWVudCB0eXBlIHB1YmxpYyBpZGVudGlmaWVyLCBvciBudWxsLgotICAgICAqLwotICAgIHByaXZhdGUgU3RyaW5nIF9kb2N0eXBlUHVibGljOwotCi0KLSAgICAvKioKLSAgICAgKiBUdXJlIGlmIHRoZSBYTUwgZGVjbGFyYXRpb24gc2hvdWxkIGJlIG9tbWl0ZWQ7Ci0gICAgICovCi0gICAgcHJpdmF0ZSBib29sZWFuIF9vbWl0WG1sRGVjbGFyYXRpb24gPSBmYWxzZTsKLQotCi0gICAgLyoqCi0gICAgICogVHVyZSBpZiB0aGUgRE9DVFlQRSBkZWNsYXJhdGlvbiBzaG91bGQgYmUgb21taXRlZDsKLSAgICAgKi8KLSAgICBwcml2YXRlIGJvb2xlYW4gX29taXREb2N0eXBlID0gZmFsc2U7Ci0KLQotICAgIC8qKgotICAgICAqIFR1cmUgaWYgY29tbWVudHMgc2hvdWxkIGJlIG9tbWl0ZWQ7Ci0gICAgICovCi0gICAgcHJpdmF0ZSBib29sZWFuIF9vbWl0Q29tbWVudHMgPSBmYWxzZTsKLQotCi0gICAgLyoqCi0gICAgICogVHVyZSBpZiB0aGUgY29tbWVudHMgc2hvdWxkIGJlIG9tbWl0ZWQ7Ci0gICAgICovCi0gICAgcHJpdmF0ZSBib29sZWFuIF9zdHJpcENvbW1lbnRzID0gZmFsc2U7Ci0KLQotICAgIC8qKgotICAgICAqIFRydWUgaWYgdGhlIGRvY3VtZW50IHR5cGUgc2hvdWxkIGJlIG1hcmtlZCBhcyBzdGFuZGFsb25lLgotICAgICAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBfc3RhbmRhbG9uZSA9IGZhbHNlOwotCi0KLSAgICAvKioKLSAgICAgKiBMaXN0IG9mIGVsZW1lbnQgdGFnIG5hbWVzIHdob3NlIHRleHQgbm9kZSBjaGlsZHJlbiBtdXN0Ci0gICAgICogYmUgb3V0cHV0IGFzIENEQVRBLgotICAgICAqLwotICAgIHByaXZhdGUgU3RyaW5nW10gX2NkYXRhRWxlbWVudHM7Ci0KLQotICAgIC8qKgotICAgICAqIExpc3Qgb2YgZWxlbWVudCB0YWcgbmFtZXMgd2hvc2UgdGV4dCBub2RlIGNoaWxkcmVuIG11c3QKLSAgICAgKiBiZSBvdXRwdXQgdW5lc2NhcGVkLgotICAgICAqLwotICAgIHByaXZhdGUgU3RyaW5nW10gX25vbkVzY2FwaW5nRWxlbWVudHM7Ci0KLQotICAgIC8qKgotICAgICAqIFRoZSBzZWxlY3RlZCBsaW5lIHNlcGFyYXRvci4KLSAgICAgKi8KLSAgICBwcml2YXRlIFN0cmluZyBfbGluZVNlcGFyYXRvciA9IExpbmVTZXBhcmF0b3IuV2ViOwotCi0KLSAgICAvKioKLSAgICAgKiBUaGUgbGluZSB3aWR0aCBhdCB3aGljaCB0byB3cmFwIGxvbmcgbGluZXMgd2hlbiBpbmRlbnRpbmcuCi0gICAgICovCi0gICAgcHJpdmF0ZSBpbnQgX2xpbmVXaWR0aCA9IERlZmF1bHRzLkxpbmVXaWR0aDsKLQotCi0gICAgLyoqCi0gICAgICogVHJ1ZSBpZiBzcGFjZXMgc2hvdWxkIGJlIHByZXNlcnZlZCBpbiBlbGVtZW50cyB0aGF0IGRvIG5vdAotICAgICAqIHNwZWNpZnkgb3RoZXJ3aXNlLCBvciBzcGVjaWZ5IHRoZSBkZWZhdWx0IGJlaGF2aW9yLgotICAgICAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBfcHJlc2VydmUgPSBmYWxzZTsKLSAgICAgICAgLyoqIElmIHRydWUsIGFuIGVtcHR5IHN0cmluZyB2YWx1ZWQgYXR0cmlidXRlIGlzIG91dHB1dCBhcyAiIi4gSWYgZmFsc2UgYW5kCi0gICAgICAgICAqIGFuZCB3ZSBhcmUgdXNpbmcgdGhlIEhUTUxTZXJpYWxpemVyLCB0aGVuIG9ubHkgdGhlIGF0dHJpYnV0ZSBuYW1lIGlzCi0gICAgICAgICAqIHNlcmlhbGl6ZWQuIERlZmF1bHRzIHRvIGZhbHNlIGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eS4KLSAgICAgICAgICovCi0gICAgICAgIHByaXZhdGUgYm9vbGVhbiBfcHJlc2VydmVFbXB0eUF0dHJpYnV0ZXMgPSBmYWxzZTsKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHMgYSBuZXcgb3V0cHV0IGZvcm1hdCB3aXRoIHRoZSBkZWZhdWx0IHZhbHVlcy4KLSAgICAgKi8KLSAgICBwdWJsaWMgT3V0cHV0Rm9ybWF0KCkKLSAgICB7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IG91dHB1dCBmb3JtYXQgd2l0aCB0aGUgZGVmYXVsdCB2YWx1ZXMgZm9yCi0gICAgICogdGhlIHNwZWNpZmllZCBtZXRob2QgYW5kIGVuY29kaW5nLiBJZiA8dHQ+aW5kZW50PC90dD4KLSAgICAgKiBpcyB0cnVlLCB0aGUgZG9jdW1lbnQgd2lsbCBiZSBwcmV0dHkgcHJpbnRlZCB3aXRoIHRoZSBkZWZhdWx0Ci0gICAgICogaW5kZW50YXRpb24gbGV2ZWwgYW5kIGRlZmF1bHQgbGluZSB3cmFwcGluZy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBtZXRob2QgVGhlIHNwZWNpZmllZCBvdXRwdXQgbWV0aG9kCi0gICAgICogQHBhcmFtIGVuY29kaW5nIFRoZSBzcGVjaWZpZWQgZW5jb2RpbmcKLSAgICAgKiBAcGFyYW0gaW5kZW50aW5nIFRydWUgZm9yIHByZXR0eSBwcmludGluZwotICAgICAqIEBzZWUgI3NldEVuY29kaW5nCi0gICAgICogQHNlZSAjc2V0SW5kZW50aW5nCi0gICAgICogQHNlZSAjc2V0TWV0aG9kCi0gICAgICovCi0gICAgcHVibGljIE91dHB1dEZvcm1hdCggU3RyaW5nIG1ldGhvZCwgU3RyaW5nIGVuY29kaW5nLCBib29sZWFuIGluZGVudGluZyApCi0gICAgewotICAgICAgICBzZXRNZXRob2QoIG1ldGhvZCApOwotICAgICAgICBzZXRFbmNvZGluZyggZW5jb2RpbmcgKTsKLSAgICAgICAgc2V0SW5kZW50aW5nKCBpbmRlbnRpbmcgKTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHMgYSBuZXcgb3V0cHV0IGZvcm1hdCB3aXRoIHRoZSBwcm9wZXIgbWV0aG9kLAotICAgICAqIGRvY3VtZW50IHR5cGUgaWRlbnRpZmllcnMgYW5kIG1lZGlhIHR5cGUgZm9yIHRoZSBzcGVjaWZpZWQKLSAgICAgKiBkb2N1bWVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBkb2MgVGhlIGRvY3VtZW50IHRvIG91dHB1dAotICAgICAqIEBzZWUgI3doaWNoTWV0aG9kCi0gICAgICovCi0gICAgcHVibGljIE91dHB1dEZvcm1hdCggRG9jdW1lbnQgZG9jICkKLSAgICB7Ci0gICAgICAgIHNldE1ldGhvZCggd2hpY2hNZXRob2QoIGRvYyApICk7Ci0gICAgICAgIHNldERvY3R5cGUoIHdoaWNoRG9jdHlwZVB1YmxpYyggZG9jICksIHdoaWNoRG9jdHlwZVN5c3RlbSggZG9jICkgKTsKLSAgICAgICAgc2V0TWVkaWFUeXBlKCB3aGljaE1lZGlhVHlwZSggZ2V0TWV0aG9kKCkgKSApOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0cyBhIG5ldyBvdXRwdXQgZm9ybWF0IHdpdGggdGhlIHByb3BlciBtZXRob2QsCi0gICAgICogZG9jdW1lbnQgdHlwZSBpZGVudGlmaWVycyBhbmQgbWVkaWEgdHlwZSBmb3IgdGhlIHNwZWNpZmllZAotICAgICAqIGRvY3VtZW50LCBhbmQgd2l0aCB0aGUgc3BlY2lmaWVkIGVuY29kaW5nLiBJZiA8dHQ+aW5kZW50PC90dD4KLSAgICAgKiBpcyB0cnVlLCB0aGUgZG9jdW1lbnQgd2lsbCBiZSBwcmV0dHkgcHJpbnRlZCB3aXRoIHRoZSBkZWZhdWx0Ci0gICAgICogaW5kZW50YXRpb24gbGV2ZWwgYW5kIGRlZmF1bHQgbGluZSB3cmFwcGluZy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBkb2MgVGhlIGRvY3VtZW50IHRvIG91dHB1dAotICAgICAqIEBwYXJhbSBlbmNvZGluZyBUaGUgc3BlY2lmaWVkIGVuY29kaW5nCi0gICAgICogQHBhcmFtIGluZGVudGluZyBUcnVlIGZvciBwcmV0dHkgcHJpbnRpbmcKLSAgICAgKiBAc2VlICNzZXRFbmNvZGluZwotICAgICAqIEBzZWUgI3NldEluZGVudGluZwotICAgICAqIEBzZWUgI3doaWNoTWV0aG9kCi0gICAgICovCi0gICAgcHVibGljIE91dHB1dEZvcm1hdCggRG9jdW1lbnQgZG9jLCBTdHJpbmcgZW5jb2RpbmcsIGJvb2xlYW4gaW5kZW50aW5nICkKLSAgICB7Ci0gICAgICAgIHRoaXMoIGRvYyApOwotICAgICAgICBzZXRFbmNvZGluZyggZW5jb2RpbmcgKTsKLSAgICAgICAgc2V0SW5kZW50aW5nKCBpbmRlbnRpbmcgKTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIG1ldGhvZCBzcGVjaWZpZWQgZm9yIHRoaXMgb3V0cHV0IGZvcm1hdC4KLSAgICAgKiBUeXBpY2FsbHkgdGhlIG1ldGhvZCB3aWxsIGJlIDx0dD54bWw8L3R0PiwgPHR0Pmh0bWw8L3R0PgotICAgICAqIG9yIDx0dD50ZXh0PC90dD4sIGJ1dCBpdCBtaWdodCBiZSBvdGhlciB2YWx1ZXMuCi0gICAgICogSWYgbm8gbWV0aG9kIHdhcyBzcGVjaWZpZWQsIG51bGwgd2lsbCBiZSByZXR1cm5lZAotICAgICAqIGFuZCB0aGUgbW9zdCBzdWl0YWJsZSBtZXRob2Qgd2lsbCBiZSBkZXRlcm1pbmVkIGZvcgotICAgICAqIHRoZSBkb2N1bWVudCBieSBjYWxsaW5nIHtAbGluayAjd2hpY2hNZXRob2R9LgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgc3BlY2lmaWVkIG91dHB1dCBtZXRob2QsIG9yIG51bGwKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE1ldGhvZCgpCi0gICAgewotICAgICAgICByZXR1cm4gX21ldGhvZDsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIG1ldGhvZCBmb3IgdGhpcyBvdXRwdXQgZm9ybWF0LgotICAgICAqCi0gICAgICogQHNlZSAjZ2V0TWV0aG9kCi0gICAgICogQHBhcmFtIG1ldGhvZCBUaGUgb3V0cHV0IG1ldGhvZCwgb3IgbnVsbAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldE1ldGhvZCggU3RyaW5nIG1ldGhvZCApCi0gICAgewotICAgICAgICBfbWV0aG9kID0gbWV0aG9kOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgdmVyc2lvbiBmb3IgdGhpcyBvdXRwdXQgbWV0aG9kLgotICAgICAqIElmIG5vIHZlcnNpb24gd2FzIHNwZWNpZmllZCwgd2lsbCByZXR1cm4gbnVsbAotICAgICAqIGFuZCB0aGUgZGVmYXVsdCB2ZXJzaW9uIG51bWJlciB3aWxsIGJlIHVzZWQuCi0gICAgICogSWYgdGhlIHNlcmlhbGl6ZXJyIGRvZXMgbm90IHN1cHBvcnQgdGhhdCBwYXJ0aWN1bGFyCi0gICAgICogdmVyc2lvbiwgaXQgc2hvdWxkIGRlZmF1bHQgdG8gYSBzdXBwb3J0ZWQgdmVyc2lvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIHNwZWNpZmllZCBtZXRob2QgdmVyc2lvbiwgb3IgbnVsbAotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VmVyc2lvbigpCi0gICAgewotICAgICAgICByZXR1cm4gX3ZlcnNpb247Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSB2ZXJzaW9uIGZvciB0aGlzIG91dHB1dCBtZXRob2QuCi0gICAgICogRm9yIFhNTCB0aGUgdmFsdWUgd291bGQgYmUgIjEuMCIsIGZvciBIVE1MCi0gICAgICogaXQgd291bGQgYmUgIjQuMCIuCi0gICAgICoKLSAgICAgKiBAc2VlICNnZXRWZXJzaW9uCi0gICAgICogQHBhcmFtIHZlcnNpb24gVGhlIG91dHB1dCBtZXRob2QgdmVyc2lvbiwgb3IgbnVsbAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFZlcnNpb24oIFN0cmluZyB2ZXJzaW9uICkKLSAgICB7Ci0gICAgICAgIF92ZXJzaW9uID0gdmVyc2lvbjsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIGluZGVudGF0aW9uIHNwZWNpZmllZC4gSWYgbm8gaW5kZW50YXRpb24KLSAgICAgKiB3YXMgc3BlY2lmaWVkLCB6ZXJvIGlzIHJldHVybmVkIGFuZCB0aGUgZG9jdW1lbnQKLSAgICAgKiBzaG91bGQgbm90IGJlIGluZGVudGVkLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgaW5kZW50YXRpb24gb3IgemVybwotICAgICAqIEBzZWUgI3NldEluZGVudGluZwotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0SW5kZW50KCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBfaW5kZW50OwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIGlmIGluZGVudGF0aW9uIHdhcyBzcGVjaWZpZWQuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0SW5kZW50aW5nKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiAoIF9pbmRlbnQgPiAwICk7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSBpbmRlbnRhdGlvbi4gVGhlIGRvY3VtZW50IHdpbGwgbm90IGJlCi0gICAgICogaW5kZW50ZWQgaWYgdGhlIGluZGVudGF0aW9uIGlzIHNldCB0byB6ZXJvLgotICAgICAqIENhbGxpbmcge0BsaW5rICNzZXRJbmRlbnRpbmd9IHdpbGwgcmVzZXQgdGhpcwotICAgICAqIHZhbHVlIHRvIHplcm8gKG9mZikgb3IgdGhlIGRlZmF1bHQgKG9uKS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBpbmRlbnQgVGhlIGluZGVudGF0aW9uLCBvciB6ZXJvCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0SW5kZW50KCBpbnQgaW5kZW50ICkKLSAgICB7Ci0gICAgICAgIGlmICggaW5kZW50IDwgMCApCi0gICAgICAgICAgICBfaW5kZW50ID0gMDsKLSAgICAgICAgZWxzZQotICAgICAgICAgICAgX2luZGVudCA9IGluZGVudDsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIGluZGVudGF0aW9uIG9uIGFuZCBvZmYuIFdoZW4gc2V0IG9uLCB0aGUgZGVmYXVsdAotICAgICAqIGluZGVudGF0aW9uIGxldmVsIGFuZCBkZWZhdWx0IGxpbmUgd3JhcHBpbmcgaXMgdXNlZAotICAgICAqIChzZWUge0BsaW5rIERlZmF1bHRzI0luZGVudH0gYW5kIHtAbGluayBEZWZhdWx0cyNMaW5lV2lkdGh9KS4KLSAgICAgKiBUbyBzcGVjaWZ5IGEgZGlmZmVyZW50IGluZGVudGF0aW9uIGxldmVsIG9yIGxpbmUgd3JhcHBpbmcsCi0gICAgICogdXNlIHtAbGluayAjc2V0SW5kZW50fSBhbmQge0BsaW5rICNzZXRMaW5lV2lkdGh9LgotICAgICAqCi0gICAgICogQHBhcmFtIG9uIFRydWUgaWYgaW5kZW50YXRpb24gc2hvdWxkIGJlIG9uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0SW5kZW50aW5nKCBib29sZWFuIG9uICkKLSAgICB7Ci0gICAgICAgIGlmICggb24gKSB7Ci0gICAgICAgICAgICBfaW5kZW50ID0gRGVmYXVsdHMuSW5kZW50OwotICAgICAgICAgICAgX2xpbmVXaWR0aCA9IERlZmF1bHRzLkxpbmVXaWR0aDsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIF9pbmRlbnQgPSAwOwotICAgICAgICAgICAgX2xpbmVXaWR0aCA9IDA7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIHNwZWNpZmllZCBlbmNvZGluZy4gSWYgbm8gZW5jb2Rpbmcgd2FzCi0gICAgICogc3BlY2lmaWVkLCB0aGUgZGVmYXVsdCBpcyBhbHdheXMgIlVURi04Ii4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIGVuY29kaW5nCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRFbmNvZGluZygpCi0gICAgewotICAgICAgICByZXR1cm4gX2VuY29kaW5nOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogU2V0cyB0aGUgZW5jb2RpbmcgZm9yIHRoaXMgb3V0cHV0IG1ldGhvZC4gSWYgbm8KLSAgICAgKiBlbmNvZGluZyB3YXMgc3BlY2lmaWVkLCB0aGUgZGVmYXVsdCBpcyBhbHdheXMgIlVURi04Ii4KLSAgICAgKiBNYWtlIHN1cmUgdGhlIGVuY29kaW5nIGlzIGNvbXBhdGlibGUgd2l0aCB0aGUgb25lCi0gICAgICogdXNlZCBieSB0aGUge0BsaW5rIGphdmEuaW8uV3JpdGVyfS4KLSAgICAgKgotICAgICAqIEBzZWUgI2dldEVuY29kaW5nCi0gICAgICogQHBhcmFtIGVuY29kaW5nIFRoZSBlbmNvZGluZywgb3IgbnVsbAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEVuY29kaW5nKCBTdHJpbmcgZW5jb2RpbmcgKQotICAgIHsKLSAgICAgICAgX2VuY29kaW5nID0gZW5jb2Rpbmc7Ci0gICAgICAgIF9lbmNvZGluZ0luZm8gPSBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIGVuY29kaW5nIGZvciB0aGlzIG91dHB1dCBtZXRob2Qgd2l0aCBhbiA8Y29kZT5FbmNvZGluZ0luZm88L2NvZGU+Ci0gICAgICogaW5zdGFuY2UuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RW5jb2RpbmcoRW5jb2RpbmdJbmZvIGVuY0luZm8pIHsKLSAgICAgICAgX2VuY29kaW5nID0gZW5jSW5mby5nZXRJQU5BTmFtZSgpOwotICAgICAgICBfZW5jb2RpbmdJbmZvID0gZW5jSW5mbzsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGFuIDxjb2RlPkVuY29kaW5nSW5mbzxjb2RlPiBpbnN0YW5jZSBmb3IgdGhlIGVuY29kaW5nLgotICAgICAqCi0gICAgICogQHNlZSAjc2V0RW5jb2RpbmcKLSAgICAgKi8KLSAgICBwdWJsaWMgRW5jb2RpbmdJbmZvIGdldEVuY29kaW5nSW5mbygpIHRocm93cyBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKF9lbmNvZGluZ0luZm8gPT0gbnVsbCkKLSAgICAgICAgICAgIF9lbmNvZGluZ0luZm8gPSBFbmNvZGluZ3MuZ2V0RW5jb2RpbmdJbmZvKF9lbmNvZGluZywgX2FsbG93SmF2YU5hbWVzKTsKLSAgICAgICAgcmV0dXJuIF9lbmNvZGluZ0luZm87Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0cyB3aGV0aGVyIGphdmEgZW5jb2RpbmcgbmFtZXMgYXJlIHBlcm1pdHRlZAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEFsbG93SmF2YU5hbWVzIChib29sZWFuIGFsbG93KSB7Ci0gICAgICAgIF9hbGxvd0phdmFOYW1lcyA9IGFsbG93OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgd2hldGhlciBqYXZhIGVuY29kaW5nIG5hbWVzIGFyZSBwZXJtaXR0ZWQKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBzZXRBbGxvd0phdmFOYW1lcyAoKSB7Ci0gICAgICAgIHJldHVybiBfYWxsb3dKYXZhTmFtZXM7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgc3BlY2lmaWVkIG1lZGlhIHR5cGUsIG9yIG51bGwuCi0gICAgICogVG8gZGV0ZXJtaW5lIHRoZSBtZWRpYSB0eXBlIGJhc2VkIG9uIHRoZQotICAgICAqIGRvY3VtZW50IHR5cGUsIHVzZSB7QGxpbmsgI3doaWNoTWVkaWFUeXBlfS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIHNwZWNpZmllZCBtZWRpYSB0eXBlLCBvciBudWxsCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRNZWRpYVR5cGUoKQotICAgIHsKLSAgICAgICAgcmV0dXJuIF9tZWRpYVR5cGU7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSBtZWRpYSB0eXBlLgotICAgICAqCi0gICAgICogQHNlZSAjZ2V0TWVkaWFUeXBlCi0gICAgICogQHBhcmFtIG1lZGlhVHlwZSBUaGUgc3BlY2lmaWVkIG1lZGlhIHR5cGUKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRNZWRpYVR5cGUoIFN0cmluZyBtZWRpYVR5cGUgKQotICAgIHsKLSAgICAgICAgX21lZGlhVHlwZSA9IG1lZGlhVHlwZTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIGRvY3VtZW50IHR5cGUgcHVibGljIGFuZCBzeXN0ZW0gaWRlbnRpZmllcnMuCi0gICAgICogUmVxdWlyZWQgb25seSBpZiB0aGUgRE9NIERvY3VtZW50IG9yIFNBWCBldmVudHMgZG8gbm90Ci0gICAgICogc3BlY2lmeSB0aGUgZG9jdW1lbnQgdHlwZSwgYW5kIG9uZSBtdXN0IGJlIHByZXNlbnQgaW4KLSAgICAgKiB0aGUgc2VyaWFsaXplZCBkb2N1bWVudC4gQW55IGRvY3VtZW50IHR5cGUgc3BlY2lmaWVkCi0gICAgICogYnkgdGhlIERPTSBEb2N1bWVudCBvciBTQVggZXZlbnRzIHdpbGwgb3ZlcnJpZGUgdGhlc2UKLSAgICAgKiB2YWx1ZXMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcHVibGljSWQgVGhlIHB1YmxpYyBpZGVudGlmaWVyLCBvciBudWxsCi0gICAgICogQHBhcmFtIHN5c3RlbUlkIFRoZSBzeXN0ZW0gaWRlbnRpZmllciwgb3IgbnVsbAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldERvY3R5cGUoIFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkICkKLSAgICB7Ci0gICAgICAgIF9kb2N0eXBlUHVibGljID0gcHVibGljSWQ7Ci0gICAgICAgIF9kb2N0eXBlU3lzdGVtID0gc3lzdGVtSWQ7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBzcGVjaWZpZWQgZG9jdW1lbnQgdHlwZSBwdWJsaWMgaWRlbnRpZmllciwKLSAgICAgKiBvciBudWxsLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0RG9jdHlwZVB1YmxpYygpCi0gICAgewotICAgICAgICByZXR1cm4gX2RvY3R5cGVQdWJsaWM7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBzcGVjaWZpZWQgZG9jdW1lbnQgdHlwZSBzeXN0ZW0gaWRlbnRpZmllciwKLSAgICAgKiBvciBudWxsLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0RG9jdHlwZVN5c3RlbSgpCi0gICAgewotICAgICAgICByZXR1cm4gX2RvY3R5cGVTeXN0ZW07Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRydWUgaWYgY29tbWVudHMgc2hvdWxkIGJlIG9tbWl0ZWQuCi0gICAgICogVGhlIGRlZmF1bHQgaXMgZmFsc2UuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0T21pdENvbW1lbnRzKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBfb21pdENvbW1lbnRzOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogU2V0cyBjb21tZW50IG9taXR0aW5nIG9uIGFuZCBvZmYuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gb21pdCBUcnVlIGlmIGNvbW1lbnRzIHNob3VsZCBiZSBvbW1pdGVkCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0T21pdENvbW1lbnRzKCBib29sZWFuIG9taXQgKQotICAgIHsKLSAgICAgICAgX29taXRDb21tZW50cyA9IG9taXQ7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIERPQ1RZUEUgZGVjbGFyYXRpb24gc2hvdWxkCi0gICAgICogYmUgb21taXRlZC4gVGhlIGRlZmF1bHQgaXMgZmFsc2UuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0T21pdERvY3VtZW50VHlwZSgpCi0gICAgewotICAgICAgICByZXR1cm4gX29taXREb2N0eXBlOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogU2V0cyBET0NUWVBFIGRlY2xhcmF0aW9uIG9taXR0aW5nIG9uIGFuZCBvZmYuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gb21pdCBUcnVlIGlmIERPQ1RZUEUgZGVjbGFyYXRpb24gc2hvdWxkIGJlIG9tbWl0ZWQKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRPbWl0RG9jdW1lbnRUeXBlKCBib29sZWFuIG9taXQgKQotICAgIHsKLSAgICAgICAgX29taXREb2N0eXBlID0gb21pdDsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgWE1MIGRvY3VtZW50IGRlY2xhcmF0aW9uIHNob3VsZAotICAgICAqIGJlIG9tbWl0ZWQuIFRoZSBkZWZhdWx0IGlzIGZhbHNlLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGdldE9taXRYTUxEZWNsYXJhdGlvbigpCi0gICAgewotICAgICAgICByZXR1cm4gX29taXRYbWxEZWNsYXJhdGlvbjsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFNldHMgWE1MIGRlY2xhcmF0aW9uIG9taXR0aW5nIG9uIGFuZCBvZmYuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gb21pdCBUcnVlIGlmIFhNTCBkZWNsYXJhdGlvbiBzaG91bGQgYmUgb21taXRlZAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldE9taXRYTUxEZWNsYXJhdGlvbiggYm9vbGVhbiBvbWl0ICkKLSAgICB7Ci0gICAgICAgIF9vbWl0WG1sRGVjbGFyYXRpb24gPSBvbWl0OwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBkb2N1bWVudCB0eXBlIGlzIHN0YW5kYWxvbmUuCi0gICAgICogVGhlIGRlZmF1bHQgaXMgZmFsc2UuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0U3RhbmRhbG9uZSgpCi0gICAgewotICAgICAgICByZXR1cm4gX3N0YW5kYWxvbmU7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBTZXRzIGRvY3VtZW50IERURCBzdGFuZGFsb25lLiBUaGUgcHVibGljIGFuZCBzeXN0ZW0KLSAgICAgKiBpZGVudGlmaWVycyBtdXN0IGJlIG51bGwgZm9yIHRoZSBkb2N1bWVudCB0byBiZQotICAgICAqIHNlcmlhbGl6ZWQgYXMgc3RhbmRhbG9uZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzdGFuZGFsb25lIFRydWUgaWYgZG9jdW1lbnQgRFREIGlzIHN0YW5kYWxvbmUKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRTdGFuZGFsb25lKCBib29sZWFuIHN0YW5kYWxvbmUgKQotICAgIHsKLSAgICAgICAgX3N0YW5kYWxvbmUgPSBzdGFuZGFsb25lOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhIGxpc3Qgb2YgYWxsIHRoZSBlbGVtZW50cyB3aG9zZSB0ZXh0IG5vZGUgY2hpbGRyZW4KLSAgICAgKiBzaG91bGQgYmUgb3V0cHV0IGFzIENEQVRBLCBvciBudWxsIGlmIG5vIHN1Y2ggZWxlbWVudHMgd2VyZQotICAgICAqIHNwZWNpZmllZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nW10gZ2V0Q0RhdGFFbGVtZW50cygpCi0gICAgewotICAgICAgICByZXR1cm4gX2NkYXRhRWxlbWVudHM7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIHRleHQgbm9kZSBjaGlsZHJlbiBvZiB0aGUgZ2l2ZW4gZWxlbWVudHMKLSAgICAgKiBzaG91bGQgYmUgb3V0cHV0IGFzIENEQVRBLgotICAgICAqCi0gICAgICogQHBhcmFtIHRhZ05hbWUgVGhlIGVsZW1lbnQncyB0YWcgbmFtZQotICAgICAqIEByZXR1cm4gVHJ1ZSBpZiBzaG91bGQgc2VyaWFsaXplIGFzIENEQVRBCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNDRGF0YUVsZW1lbnQoIFN0cmluZyB0YWdOYW1lICkKLSAgICB7Ci0gICAgICAgIGludCBpOwotCi0gICAgICAgIGlmICggX2NkYXRhRWxlbWVudHMgPT0gbnVsbCApCi0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIGZvciAoIGkgPSAwIDsgaSA8IF9jZGF0YUVsZW1lbnRzLmxlbmd0aCA7ICsraSApCi0gICAgICAgICAgICBpZiAoIF9jZGF0YUVsZW1lbnRzWyBpIF0uZXF1YWxzKCB0YWdOYW1lICkgKQotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSBsaXN0IG9mIGVsZW1lbnRzIGZvciB3aGljaCB0ZXh0IG5vZGUgY2hpbGRyZW4KLSAgICAgKiBzaG91bGQgYmUgb3V0cHV0IGFzIENEQVRBLgotICAgICAqCi0gICAgICogQHBhcmFtIGNkYXRhRWxlbWVudHMgTGlzdCBvZiBDREFUQSBlbGVtZW50IHRhZyBuYW1lcwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldENEYXRhRWxlbWVudHMoIFN0cmluZ1tdIGNkYXRhRWxlbWVudHMgKQotICAgIHsKLSAgICAgICAgX2NkYXRhRWxlbWVudHMgPSBjZGF0YUVsZW1lbnRzOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhIGxpc3Qgb2YgYWxsIHRoZSBlbGVtZW50cyB3aG9zZSB0ZXh0IG5vZGUgY2hpbGRyZW4KLSAgICAgKiBzaG91bGQgYmUgb3V0cHV0IHVuZXNjYXBlZCAobm8gY2hhcmFjdGVyIHJlZmVyZW5jZXMpLCBvciBudWxsCi0gICAgICogaWYgbm8gc3VjaCBlbGVtZW50cyB3ZXJlIHNwZWNpZmllZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nW10gZ2V0Tm9uRXNjYXBpbmdFbGVtZW50cygpCi0gICAgewotICAgICAgICByZXR1cm4gX25vbkVzY2FwaW5nRWxlbWVudHM7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIHRleHQgbm9kZSBjaGlsZHJlbiBvZiB0aGUgZ2l2ZW4gZWxlbWVudHMKLSAgICAgKiBzaG91bGQgYmUgb3V0cHV0IHVuZXNjYXBlZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSB0YWdOYW1lIFRoZSBlbGVtZW50J3MgdGFnIG5hbWUKLSAgICAgKiBAcmV0dXJuIFRydWUgaWYgc2hvdWxkIHNlcmlhbGl6ZSB1bmVzY2FwZWQKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc05vbkVzY2FwaW5nRWxlbWVudCggU3RyaW5nIHRhZ05hbWUgKQotICAgIHsKLSAgICAgICAgaW50IGk7Ci0KLSAgICAgICAgaWYgKCBfbm9uRXNjYXBpbmdFbGVtZW50cyA9PSBudWxsICkgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0gICAgICAgIGZvciAoIGkgPSAwIDsgaSA8IF9ub25Fc2NhcGluZ0VsZW1lbnRzLmxlbmd0aCA7ICsraSApCi0gICAgICAgICAgICBpZiAoIF9ub25Fc2NhcGluZ0VsZW1lbnRzWyBpIF0uZXF1YWxzKCB0YWdOYW1lICkgKQotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSBsaXN0IG9mIGVsZW1lbnRzIGZvciB3aGljaCB0ZXh0IG5vZGUgY2hpbGRyZW4KLSAgICAgKiBzaG91bGQgYmUgb3V0cHV0IHVuZXNjYXBlZCAobm8gY2hhcmFjdGVyIHJlZmVyZW5jZXMpLgotICAgICAqCi0gICAgICogQHBhcmFtIG5vbkVzY2FwaW5nRWxlbWVudHMgTGlzdCBvZiB1bmVzY2FwZWQgZWxlbWVudCB0YWcgbmFtZXMKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXROb25Fc2NhcGluZ0VsZW1lbnRzKCBTdHJpbmdbXSBub25Fc2NhcGluZ0VsZW1lbnRzICkKLSAgICB7Ci0gICAgICAgIF9ub25Fc2NhcGluZ0VsZW1lbnRzID0gbm9uRXNjYXBpbmdFbGVtZW50czsKLSAgICB9Ci0KLQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhIHNwZWNpZmljIGxpbmUgc2VwYXJhdG9yIHRvIHVzZS4gVGhlIGRlZmF1bHQgaXMgdGhlCi0gICAgICogV2ViIGxpbmUgc2VwYXJhdG9yICg8dHQ+XG48L3R0PikuIEEgc3RyaW5nIGlzIHJldHVybmVkIHRvCi0gICAgICogc3VwcG9ydCBkb3VibGUgY29kZXMgKENSICsgTEYpLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgc3BlY2lmaWVkIGxpbmUgc2VwYXJhdG9yCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRMaW5lU2VwYXJhdG9yKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBfbGluZVNlcGFyYXRvcjsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIGxpbmUgc2VwYXJhdG9yLiBUaGUgZGVmYXVsdCBpcyB0aGUgV2ViIGxpbmUgc2VwYXJhdG9yCi0gICAgICogKDx0dD5cbjwvdHQ+KS4gVGhlIG1hY2hpbmUncyBsaW5lIHNlcGFyYXRvciBjYW4gYmUgb2J0YWluZWQKLSAgICAgKiBmcm9tIHRoZSBzeXN0ZW0gcHJvcGVydHkgPHR0PmxpbmUuc2VwYXJhdG9yPC90dD4sIGJ1dCBpcyBvbmx5Ci0gICAgICogdXNlZnVsIGlmIHRoZSBkb2N1bWVudCBpcyBlZGl0ZWQgb24gbWFjaGluZXMgb2YgdGhlIHNhbWUgdHlwZS4KLSAgICAgKiBGb3IgZ2VuZXJhbCBkb2N1bWVudHMsIHVzZSB0aGUgV2ViIGxpbmUgc2VwYXJhdG9yLgotICAgICAqCi0gICAgICogQHBhcmFtIGxpbmVTZXBhcmF0b3IgVGhlIHNwZWNpZmllZCBsaW5lIHNlcGFyYXRvcgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldExpbmVTZXBhcmF0b3IoIFN0cmluZyBsaW5lU2VwYXJhdG9yICkKLSAgICB7Ci0gICAgICAgIGlmICggbGluZVNlcGFyYXRvciA9PSBudWxsICkKLSAgICAgICAgICAgIF9saW5lU2VwYXJhdG9yID0gIExpbmVTZXBhcmF0b3IuV2ViOwotICAgICAgICBlbHNlCi0gICAgICAgICAgICBfbGluZVNlcGFyYXRvciA9IGxpbmVTZXBhcmF0b3I7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIGRlZmF1bHQgYmVoYXZpb3IgZm9yIHRoaXMgZm9ybWF0IGlzIHRvCi0gICAgICogcHJlc2VydmUgc3BhY2VzLiBBbGwgZWxlbWVudHMgdGhhdCBkbyBub3Qgc3BlY2lmeSBvdGhlcndpc2UKLSAgICAgKiBvciBzcGVjaWZ5IHRoZSBkZWZhdWx0IGJlaGF2aW9yIHdpbGwgYmUgZm9ybWF0dGVkIGJhc2VkIG9uCi0gICAgICogdGhpcyBydWxlLiBBbGwgZWxlbWVudHMgdGhhdCBzcGVjaWZ5IHNwYWNlIHByZXNlcnZpbmcgd2lsbAotICAgICAqIGFsd2F5cyBwcmVzZXJ2ZSBzcGFjZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXRQcmVzZXJ2ZVNwYWNlKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBfcHJlc2VydmU7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBTZXRzIHNwYWNlIHByZXNlcnZpbmcgYXMgdGhlIGRlZmF1bHQgYmVoYXZpb3IuIFRoZSBkZWZhdWx0IGlzCi0gICAgICogc3BhY2Ugc3RyaXBwaW5nIGFuZCBhbGwgZWxlbWVudHMgdGhhdCBkbyBub3Qgc3BlY2lmeSBvdGhlcndpc2UKLSAgICAgKiBvciB1c2UgdGhlIGRlZmF1bHQgdmFsdWUgd2lsbCBub3QgcHJlc2VydmUgc3BhY2VzLgotICAgICAqCi0gICAgICogQHBhcmFtIHByZXNlcnZlIFRydWUgaWYgc3BhY2VzIHNob3VsZCBiZSBwcmVzZXJ2ZWQKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRQcmVzZXJ2ZVNwYWNlKCBib29sZWFuIHByZXNlcnZlICkKLSAgICB7Ci0gICAgICAgIF9wcmVzZXJ2ZSA9IHByZXNlcnZlOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSBzZWxlY3RlZCBsaW5lIHdpZHRoIGZvciBicmVha2luZyB1cCBsb25nIGxpbmVzLgotICAgICAqIFdoZW4gaW5kZW50aW5nLCBhbmQgb25seSB3aGVuIGluZGVudGluZywgbG9uZyBsaW5lcyB3aWxsIGJlCi0gICAgICogYnJva2VuIGF0IHNwYWNlIGJvdW5kYXJpZXMgYmFzZWQgb24gdGhpcyBsaW5lIHdpZHRoLgotICAgICAqIE5vIGxpbmUgd3JhcHBpbmcgb2NjdXJzIGlmIHRoaXMgdmFsdWUgaXMgemVyby4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldExpbmVXaWR0aCgpCi0gICAgewotICAgICAgICByZXR1cm4gX2xpbmVXaWR0aDsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIGxpbmUgd2lkdGguIElmIHplcm8gdGhlbiBubyBsaW5lIHdyYXBwaW5nIHdpbGwKLSAgICAgKiBvY2N1ci4gQ2FsbGluZyB7QGxpbmsgI3NldEluZGVudGluZ30gd2lsbCByZXNldCB0aGlzCi0gICAgICogdmFsdWUgdG8gemVybyAob2ZmKSBvciB0aGUgZGVmYXVsdCAob24pLgotICAgICAqCi0gICAgICogQHBhcmFtIGxpbmVXaWR0aCBUaGUgbGluZSB3aWR0aCB0byB1c2UsIHplcm8gZm9yIGRlZmF1bHQKLSAgICAgKiBAc2VlICNnZXRMaW5lV2lkdGgKLSAgICAgKiBAc2VlICNzZXRJbmRlbnRpbmcKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRMaW5lV2lkdGgoIGludCBsaW5lV2lkdGggKQotICAgIHsKLSAgICAgICAgaWYgKCBsaW5lV2lkdGggPD0gMCApCi0gICAgICAgICAgICBfbGluZVdpZHRoID0gMDsKLSAgICAgICAgZWxzZQotICAgICAgICAgICAgX2xpbmVXaWR0aCA9IGxpbmVXaWR0aDsKLSAgICB9Ci0gICAgICAgIC8qKgotICAgICAgICAgKiBSZXR1cm5zIHRoZSBwcmVzZXJ2ZUVtcHR5QXR0cmlidXRlIGZsYWcuIElmIGZsYWcgaXMgZmFsc2UsIHRoZW4nCi0gICAgICAgICAqIGF0dHJpYnV0ZXMgd2l0aCBlbXB0eSBzdHJpbmcgdmFsdWVzIGFyZSBvdXRwdXQgYXMgdGhlIGF0dHJpYnV0ZQotICAgICAgICAgKiBuYW1lIG9ubHkgKGluIEhUTUwgbW9kZSkuCi0gICAgICAgICAqIEByZXR1cm4gcHJlc2VydmUgdGhlIHByZXNlcnZlIGZsYWcKLSAgICAgICAgICovICAgICBwdWJsaWMgYm9vbGVhbiBnZXRQcmVzZXJ2ZUVtcHR5QXR0cmlidXRlcyAoKSB7ICAgICAgICAgIHJldHVybiBfcHJlc2VydmVFbXB0eUF0dHJpYnV0ZXM7ICAgICAgICB9ICAgICAgIC8qKgotICAgICAgICAgKiBTZXRzIHRoZSBwcmVzZXJ2ZUVtcHR5QXR0cmlidXRlIGZsYWcuIElmIGZsYWcgaXMgZmFsc2UsIHRoZW4nCi0gICAgICAgICAqIGF0dHJpYnV0ZXMgd2l0aCBlbXB0eSBzdHJpbmcgdmFsdWVzIGFyZSBvdXRwdXQgYXMgdGhlIGF0dHJpYnV0ZQotICAgICAgICAgKiBuYW1lIG9ubHkgKGluIEhUTUwgbW9kZSkuCi0gICAgICAgICAqIEBwYXJhbSBwcmVzZXJ2ZSB0aGUgcHJlc2VydmUgZmxhZwotICAgICAgICAgKi8gICAgIHB1YmxpYyB2b2lkIHNldFByZXNlcnZlRW1wdHlBdHRyaWJ1dGVzIChib29sZWFuIHByZXNlcnZlKSB7ICAgICAgICAgICAgIF9wcmVzZXJ2ZUVtcHR5QXR0cmlidXRlcyA9IHByZXNlcnZlOyAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBsYXN0IHByaW50YWJsZSBjaGFyYWN0ZXIgYmFzZWQgb24gdGhlIHNlbGVjdGVkCi0gICAgICogZW5jb2RpbmcuIENvbnRyb2wgY2hhcmFjdGVycyBhbmQgbm9uLXByaW50YWJsZSBjaGFyYWN0ZXJzCi0gICAgICogYXJlIGFsd2F5cyBwcmludGVkIGFzIGNoYXJhY3RlciByZWZlcmVuY2VzLgotICAgICAqLwotICAgIHB1YmxpYyBjaGFyIGdldExhc3RQcmludGFibGUoKQotICAgIHsKLSAgICAgICAgaWYgKCBnZXRFbmNvZGluZygpICE9IG51bGwgJiYKLSAgICAgICAgICAgICAoIGdldEVuY29kaW5nKCkuZXF1YWxzSWdub3JlQ2FzZSggIkFTQ0lJIiApICkgKQotICAgICAgICAgICAgcmV0dXJuIDB4RkY7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICAgIHJldHVybiAweEZGRkY7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBEZXRlcm1pbmUgdGhlIG91dHB1dCBtZXRob2QgZm9yIHRoZSBzcGVjaWZpZWQgZG9jdW1lbnQuCi0gICAgICogSWYgdGhlIGRvY3VtZW50IGlzIGFuIGluc3RhbmNlIG9mIHtAbGluayBvcmcudzNjLmRvbS5odG1sLkhUTUxEb2N1bWVudH0KLSAgICAgKiB0aGVuIHRoZSBtZXRob2QgaXMgc2FpZCB0byBiZSA8dHQ+aHRtbDwvdHQ+LiBJZiB0aGUgcm9vdAotICAgICAqIGVsZW1lbnQgaXMgJ2h0bWwnIGFuZCBhbGwgdGV4dCBub2RlcyBwcmVjZWRpbmcgdGhlIHJvb3QKLSAgICAgKiBlbGVtZW50IGFyZSBhbGwgd2hpdGVzcGFjZSwgdGhlbiB0aGUgbWV0aG9kIGlzIHNhaWQgdG8gYmUKLSAgICAgKiA8dHQ+aHRtbDwvdHQ+LiBPdGhlcndpc2UgdGhlIG1ldGhvZCBpcyA8dHQ+eG1sPC90dD4uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZG9jIFRoZSBkb2N1bWVudCB0byBjaGVjawotICAgICAqIEByZXR1cm4gVGhlIHN1aXRhYmxlIG1ldGhvZAotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHdoaWNoTWV0aG9kKCBEb2N1bWVudCBkb2MgKQotICAgIHsKLSAgICAgICAgTm9kZSAgICBub2RlOwotICAgICAgICBTdHJpbmcgIHZhbHVlOwotICAgICAgICBpbnQgICAgIGk7Ci0KLSAgICAgICAgLy8gSWYgZG9jdW1lbnQgaXMgZGVyaXZlZCBmcm9tIEhUTUxEb2N1bWVudCB0aGVuIHRoZSBkZWZhdWx0Ci0gICAgICAgIC8vIG1ldGhvZCBpcyBodG1sLgotICAgICAgICBpZiAoIGRvYyBpbnN0YW5jZW9mIEhUTUxEb2N1bWVudCApCi0gICAgICAgICAgICByZXR1cm4gTWV0aG9kLkhUTUw7Ci0KLSAgICAgICAgLy8gTG9va3VwIHRoZSByb290IGVsZW1lbnQgYW5kIHRoZSB0ZXh0IG5vZGVzIHByZWNlZGluZyBpdC4KLSAgICAgICAgLy8gSWYgcm9vdCBlbGVtZW50IGlzIGh0bWwgYW5kIGFsbCB0ZXh0IG5vZGVzIGNvbnRhaW4gd2hpdGVzcGFjZQotICAgICAgICAvLyBvbmx5LCB0aGUgbWV0aG9kIGlzIGh0bWwuCi0KLSAgICAgICAgLy8gRklYTUUgKFNNKSBzaG91bGQgd2UgY2FyZSBhYm91dCBuYW1lc3BhY2VzIGhlcmU/Ci0KLSAgICAgICAgbm9kZSA9IGRvYy5nZXRGaXJzdENoaWxkKCk7Ci0gICAgICAgIHdoaWxlIChub2RlICE9IG51bGwpIHsKLSAgICAgICAgICAgIC8vIElmIHRoZSByb290IGVsZW1lbnQgaXMgaHRtbCwgdGhlIG1ldGhvZCBpcyBodG1sLgotICAgICAgICAgICAgaWYgKCBub2RlLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5FTEVNRU5UX05PREUgKSB7Ci0gICAgICAgICAgICAgICAgaWYgKCBub2RlLmdldE5vZGVOYW1lKCkuZXF1YWxzSWdub3JlQ2FzZSggImh0bWwiICkgKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBNZXRob2QuSFRNTDsKLSAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCBub2RlLmdldE5vZGVOYW1lKCkuZXF1YWxzSWdub3JlQ2FzZSggInJvb3QiICkgKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBNZXRob2QuRk9QOwotICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBNZXRob2QuWE1MOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0gZWxzZSBpZiAoIG5vZGUuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLlRFWFRfTk9ERSApIHsKLSAgICAgICAgICAgICAgICAvLyBJZiBhIHRleHQgbm9kZSBwcmVjZWRpbmcgdGhlIHJvb3QgZWxlbWVudCBjb250YWlucwotICAgICAgICAgICAgICAgIC8vIG9ubHkgd2hpdGVzcGFjZSwgdGhpcyBtaWdodCBiZSBodG1sLCBvdGhlcndpc2UgaXQncwotICAgICAgICAgICAgICAgIC8vIGRlZmluaXRlbHkgeG1sLgotICAgICAgICAgICAgICAgIHZhbHVlID0gbm9kZS5nZXROb2RlVmFsdWUoKTsKLSAgICAgICAgICAgICAgICBmb3IgKCBpID0gMCA7IGkgPCB2YWx1ZS5sZW5ndGgoKSA7ICsraSApCi0gICAgICAgICAgICAgICAgICAgIGlmICggdmFsdWUuY2hhckF0KCBpICkgIT0gMHgyMCAmJiB2YWx1ZS5jaGFyQXQoIGkgKSAhPSAweDBBICYmCi0gICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUuY2hhckF0KCBpICkgIT0gMHgwOSAmJiB2YWx1ZS5jaGFyQXQoIGkgKSAhPSAweDBEICkKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBNZXRob2QuWE1MOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgbm9kZSA9IG5vZGUuZ2V0TmV4dFNpYmxpbmcoKTsKLSAgICAgICAgfQotICAgICAgICAvLyBBbnl0aGluZyBlbHNlLCB0aGUgbWV0aG9kIGlzIHhtbC4KLSAgICAgICAgcmV0dXJuIE1ldGhvZC5YTUw7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBkb2N1bWVudCB0eXBlIHB1YmxpYyBpZGVudGlmaWVyCi0gICAgICogc3BlY2lmaWVkIGZvciB0aGlzIGRvY3VtZW50LCBvciBudWxsLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHdoaWNoRG9jdHlwZVB1YmxpYyggRG9jdW1lbnQgZG9jICkKLSAgICB7Ci0gICAgICAgIERvY3VtZW50VHlwZSBkb2N0eXBlOwotCi0gICAgICAgICAgIC8qICBET00gTGV2ZWwgMiB3YXMgaW50cm9kdWNlZCBpbnRvIHRoZSBjb2RlIGJhc2UqLwotICAgICAgICAgICBkb2N0eXBlID0gZG9jLmdldERvY3R5cGUoKTsKLSAgICAgICAgICAgaWYgKCBkb2N0eXBlICE9IG51bGwgKSB7Ci0gICAgICAgICAgIC8vIE5vdGUgb24gY2F0Y2g6IERPTSBMZXZlbCAxIGRvZXMgbm90IHNwZWNpZnkgdGhpcyBtZXRob2QKLSAgICAgICAgICAgLy8gYW5kIHRoZSBjb2RlIHdpbGwgdGhyb3cgYSBOb1N1Y2hNZXRob2RFcnJvcgotICAgICAgICAgICB0cnkgewotICAgICAgICAgICByZXR1cm4gZG9jdHlwZS5nZXRQdWJsaWNJZCgpOwotICAgICAgICAgICB9IGNhdGNoICggRXJyb3IgZXhjZXB0ICkgeyAgfQotICAgICAgICAgICB9Ci0KLSAgICAgICAgaWYgKCBkb2MgaW5zdGFuY2VvZiBIVE1MRG9jdW1lbnQgKQotICAgICAgICAgICAgcmV0dXJuIERURC5YSFRNTFB1YmxpY0lkOwotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIGRvY3VtZW50IHR5cGUgc3lzdGVtIGlkZW50aWZpZXIKLSAgICAgKiBzcGVjaWZpZWQgZm9yIHRoaXMgZG9jdW1lbnQsIG9yIG51bGwuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBTdHJpbmcgd2hpY2hEb2N0eXBlU3lzdGVtKCBEb2N1bWVudCBkb2MgKQotICAgIHsKLSAgICAgICAgRG9jdW1lbnRUeXBlIGRvY3R5cGU7Ci0KLSAgICAgICAgLyogRE9NIExldmVsIDIgd2FzIGludHJvZHVjZWQgaW50byB0aGUgY29kZSBiYXNlKi8KLSAgICAgICAgICAgZG9jdHlwZSA9IGRvYy5nZXREb2N0eXBlKCk7Ci0gICAgICAgICAgIGlmICggZG9jdHlwZSAhPSBudWxsICkgewotICAgICAgICAgICAvLyBOb3RlIG9uIGNhdGNoOiBET00gTGV2ZWwgMSBkb2VzIG5vdCBzcGVjaWZ5IHRoaXMgbWV0aG9kCi0gICAgICAgICAgIC8vIGFuZCB0aGUgY29kZSB3aWxsIHRocm93IGEgTm9TdWNoTWV0aG9kRXJyb3IKLSAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgcmV0dXJuIGRvY3R5cGUuZ2V0U3lzdGVtSWQoKTsKLSAgICAgICAgICAgfSBjYXRjaCAoIEVycm9yIGV4Y2VwdCApIHsgfQotICAgICAgICAgICB9Ci0KLSAgICAgICAgaWYgKCBkb2MgaW5zdGFuY2VvZiBIVE1MRG9jdW1lbnQgKQotICAgICAgICAgICAgcmV0dXJuIERURC5YSFRNTFN5c3RlbUlkOwotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIHN1aXRhYmxlIG1lZGlhIGZvcm1hdCBmb3IgYSBkb2N1bWVudAotICAgICAqIG91dHB1dCB3aXRoIHRoZSBzcGVjaWZpZWQgbWV0aG9kLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHdoaWNoTWVkaWFUeXBlKCBTdHJpbmcgbWV0aG9kICkKLSAgICB7Ci0gICAgICAgIGlmICggbWV0aG9kLmVxdWFsc0lnbm9yZUNhc2UoIE1ldGhvZC5YTUwgKSApCi0gICAgICAgICAgICByZXR1cm4gInRleHQveG1sIjsKLSAgICAgICAgaWYgKCBtZXRob2QuZXF1YWxzSWdub3JlQ2FzZSggTWV0aG9kLkhUTUwgKSApCi0gICAgICAgICAgICByZXR1cm4gInRleHQvaHRtbCI7Ci0gICAgICAgIGlmICggbWV0aG9kLmVxdWFsc0lnbm9yZUNhc2UoIE1ldGhvZC5YSFRNTCApICkKLSAgICAgICAgICAgIHJldHVybiAidGV4dC9odG1sIjsKLSAgICAgICAgaWYgKCBtZXRob2QuZXF1YWxzSWdub3JlQ2FzZSggTWV0aG9kLlRFWFQgKSApCi0gICAgICAgICAgICByZXR1cm4gInRleHQvcGxhaW4iOwotICAgICAgICBpZiAoIG1ldGhvZC5lcXVhbHNJZ25vcmVDYXNlKCBNZXRob2QuRk9QICkgKQotICAgICAgICAgICAgcmV0dXJuICJhcHBsaWNhdGlvbi9wZGYiOwotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplL1ByaW50ZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZS9QcmludGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGFiOWQ4ZTQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplL1ByaW50ZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDM2NCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLQotLy8gU2VwIDE0LCAyMDAwOgotLy8gIEZpeGVkIHNlcmlhbGl6ZXIgdG8gcmVwb3J0IElPIGV4Y2VwdGlvbiBkaXJlY3RseSwgaW5zdGVhZCBhdAotLy8gIHRoZSBlbmQgb2YgZG9jdW1lbnQgcHJvY2Vzc2luZy4KLS8vICBSZXBvcnRlZCBieSBQYXRyaWNrIEhpZ2dpbnMgPHBoaWdnaW5zQHRyYW5zemFwLmNvbT4KLQotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplOwotCi0KLWltcG9ydCBqYXZhLmlvLldyaXRlcjsKLWltcG9ydCBqYXZhLmlvLlN0cmluZ1dyaXRlcjsKLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotCi0KLS8qKgotICogVGhlIHByaW50ZXIgaXMgcmVzcG9uc2libGUgZm9yIHNlbmRpbmcgdGV4dCB0byB0aGUgb3V0cHV0IHN0cmVhbQotICogb3Igd3JpdGVyLiBUaGlzIGNsYXNzIHBlcmZvcm1zIGRpcmVjdCB3cml0aW5nIGZvciBlZmZpY2llbmN5LgotICoge0BsaW5rIEluZGVudFByaW50ZXJ9IHN1cHBvcnRzIGluZGVudGF0aW9uIGFuZCBsaW5lIHdyYXBwaW5nIGJ5Ci0gKiBleHRlbmRpbmcgdGhpcyBjbGFzcy4KLSAqCi0gKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzphcmtpbkBpbnRhbGlvLmNvbSI+QXNzYWYgQXJraW48L2E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBQcmludGVyCi17Ci0KLQotICAgIC8qKgotICAgICAqIFRoZSBvdXRwdXQgZm9ybWF0IGFzc29jaWF0ZWQgd2l0aCB0aGlzIHNlcmlhbGl6ZXIuIFRoaXMgd2lsbCBuZXZlcgotICAgICAqIGJlIGEgbnVsbCByZWZlcmVuY2UuIElmIG5vIGZvcm1hdCB3YXMgcGFzc2VkIHRvIHRoZSBjb25zdHJ1Y3RvciwKLSAgICAgKiB0aGUgZGVmYXVsdCBvbmUgZm9yIHRoaXMgZG9jdW1lbnQgdHlwZSB3aWxsIGJlIHVzZWQuIFRoZSBmb3JtYXQKLSAgICAgKiBvYmplY3QgaXMgbmV2ZXIgY2hhbmdlZCBieSB0aGUgc2VyaWFsaXplci4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgZmluYWwgT3V0cHV0Rm9ybWF0IF9mb3JtYXQ7Ci0KLQotICAgIC8qKgotICAgICAqIFRoZSB3cml0ZXIgdG8gd2hpY2ggdGhlIGRvY3VtZW50IGlzIHdyaXR0ZW4uCi0gICAgICovCi0gICAgcHJvdGVjdGVkIFdyaXRlciAgICAgICAgICAgICBfd3JpdGVyOwotCi0KLSAgICAvKioKLSAgICAgKiBUaGUgRFREIHdyaXRlci4gV2hlbiB3ZSBzd2l0Y2ggdG8gRFREIG1vZGUsIGFsbCBvdXRwdXQgaXMKLSAgICAgKiBhY2N1bXVsYXRlZCBpbiB0aGlzIERURCB3cml0ZXIuIFdoZW4gd2Ugc3dpdGNoIG91dCBvZiBpdCwKLSAgICAgKiB0aGUgb3V0cHV0IGlzIG9idGFpbmVkIGFzIGEgc3RyaW5nLiBNdXN0IG5vdCBiZSByZXNldCB0bwotICAgICAqIG51bGwgdW50aWwgd2UncmUgZG9uZSB3aXRoIHRoZSBkb2N1bWVudC4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgU3RyaW5nV3JpdGVyICAgICAgIF9kdGRXcml0ZXI7Ci0KLQotICAgIC8qKgotICAgICAqIEhvbGRzIGEgcmVmZXJlbmNlIHRvIHRoZSBkb2N1bWVudCB3cml0ZXIgd2hpbGUgd2UgYXJlCi0gICAgICogaW4gRFREIG1vZGUuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIFdyaXRlciAgICAgICAgICBfZG9jV3JpdGVyOwotCi0KLSAgICAvKioKLSAgICAgKiBIb2xkcyB0aGUgZXhjZXB0aW9uIHRocm93biBieSB0aGUgc2VyaWFsaXplci4gIEV4Y2VwdGlvbnMgZG8gbm90IGNhdXNlCi0gICAgICogdGhlIHNlcmlhbGl6ZXIgdG8gcXVpdCwgYnV0IGFyZSBoZWxkIGFuZCBvbmUgaXMgdGhyb3duIGF0IHRoZSBlbmQuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIElPRXhjZXB0aW9uICAgICBfZXhjZXB0aW9uOwotCi0KLSAgICAvKioKLSAgICAgKiBUaGUgc2l6ZSBvZiB0aGUgb3V0cHV0IGJ1ZmZlci4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQnVmZmVyU2l6ZSA9IDQwOTY7Ci0KLQotICAgIC8qKgotICAgICAqIE91dHB1dCBidWZmZXIuCi0gICAgICovCi0gICAgcHJpdmF0ZSBmaW5hbCBjaGFyW10gIF9idWZmZXIgPSBuZXcgY2hhclsgQnVmZmVyU2l6ZSBdOwotCi0KLSAgICAvKioKLSAgICAgKiBQb3NpdGlvbiB3aXRoaW4gdGhlIG91dHB1dCBidWZmZXIuCi0gICAgICovCi0gICAgcHJpdmF0ZSBpbnQgICAgICAgICAgIF9wb3MgPSAwOwotCi0KLSAgICBwdWJsaWMgUHJpbnRlciggV3JpdGVyIHdyaXRlciwgT3V0cHV0Rm9ybWF0IGZvcm1hdCkKLSAgICB7Ci0gICAgICAgIF93cml0ZXIgPSB3cml0ZXI7Ci0gICAgICAgIF9mb3JtYXQgPSBmb3JtYXQ7Ci0gICAgICAgIF9leGNlcHRpb24gPSBudWxsOwotICAgICAgICBfZHRkV3JpdGVyID0gbnVsbDsKLSAgICAgICAgX2RvY1dyaXRlciA9IG51bGw7Ci0gICAgICAgIF9wb3MgPSAwOwotICAgIH0KLQotCi0gICAgcHVibGljIElPRXhjZXB0aW9uIGdldEV4Y2VwdGlvbigpCi0gICAgewotICAgICAgICByZXR1cm4gX2V4Y2VwdGlvbjsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIENhbGxlZCBieSBhbnkgb2YgdGhlIERURCBoYW5kbGVycyB0byBlbnRlciBEVEQgbW9kZS4KLSAgICAgKiBPbmNlIGVudGVyZWQsIGFsbCBvdXRwdXQgd2lsbCBiZSBhY2N1bXVsYXRlZCBpbiBhIHN0cmluZwotICAgICAqIHRoYXQgY2FuIGJlIHByaW50ZWQgYXMgcGFydCBvZiB0aGUgZG9jdW1lbnQncyBEVEQuCi0gICAgICogVGhpcyBtZXRob2QgbWF5IGJlIGNhbGxlZCBhbnkgbnVtYmVyIG9mIHRpbWUgYnV0IHdpbGwgb25seQotICAgICAqIGhhdmUgYWZmZWN0IHRoZSBmaXJzdCB0aW1lIGl0J3MgY2FsbGVkLiBUbyBleGlzdCBEVEQgc3RhdGUKLSAgICAgKiBhbmQgZ2V0IHRoZSBhY2N1bXVsYXRlZCBEVEQsIGNhbGwge0BsaW5rICNsZWF2ZURURH0uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW50ZXJEVEQoKQotICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIC8vIENhbiBvbmx5IGVudGVyIERURCBzdGF0ZSBvbmNlLiBPbmNlIHdlJ3JlIG91dCBvZiBEVEQKLSAgICAgICAgLy8gc3RhdGUsIGNhbiBubyBsb25nZXIgcmUtZW50ZXIgaXQuCi0gICAgICAgIGlmICggX2R0ZFdyaXRlciA9PSBudWxsICkgewotICAgICAgICAgICAgZmx1c2hMaW5lKCBmYWxzZSApOwotCi0gICAgICAgICAgICAgICAgICAgICAgICBfZHRkV3JpdGVyID0gbmV3IFN0cmluZ1dyaXRlcigpOwotICAgICAgICAgICAgX2RvY1dyaXRlciA9IF93cml0ZXI7Ci0gICAgICAgICAgICBfd3JpdGVyID0gX2R0ZFdyaXRlcjsKLSAgICAgICAgfQotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogQ2FsbGVkIGJ5IHRoZSByb290IGVsZW1lbnQgdG8gbGVhdmUgRFREIG1vZGUgYW5kIGlmIGFueQotICAgICAqIERURCBwYXJ0cyB3ZXJlIHByaW50ZXIsIHdpbGwgcmV0dXJuIGEgc3RyaW5nIHdpdGggdGhlaXIKLSAgICAgKiB0ZXh0dWFsIGNvbnRlbnQuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBsZWF2ZURURCgpCi0gICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgLy8gT25seSB3b3JrcyBpZiB3ZSdyZSBnb2luZyBvdXQgb2YgRFREIG1vZGUuCi0gICAgICAgIGlmICggX3dyaXRlciA9PSBfZHRkV3JpdGVyICkgewotICAgICAgICAgICAgZmx1c2hMaW5lKCBmYWxzZSApOwotCi0gICAgICAgICAgICAgICAgICAgICAgICBfd3JpdGVyID0gX2RvY1dyaXRlcjsKLSAgICAgICAgICAgIHJldHVybiBfZHRkV3JpdGVyLnRvU3RyaW5nKCk7Ci0gICAgICAgIH0gZWxzZQotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgdm9pZCBwcmludFRleHQoIFN0cmluZyB0ZXh0ICkKLSAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uCi0gICAgewotICAgICAgICB0cnkgewotICAgICAgICAgICAgaW50IGxlbmd0aCA9IHRleHQubGVuZ3RoKCk7Ci0gICAgICAgICAgICBmb3IgKCBpbnQgaSA9IDAgOyBpIDwgbGVuZ3RoIDsgKytpICkgewotICAgICAgICAgICAgICAgIGlmICggX3BvcyA9PSBCdWZmZXJTaXplICkgewotICAgICAgICAgICAgICAgICAgICBfd3JpdGVyLndyaXRlKCBfYnVmZmVyICk7Ci0gICAgICAgICAgICAgICAgICAgIF9wb3MgPSAwOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBfYnVmZmVyWyBfcG9zIF0gPSB0ZXh0LmNoYXJBdCggaSApOwotICAgICAgICAgICAgICAgICsrX3BvczsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSBjYXRjaCAoIElPRXhjZXB0aW9uIGV4Y2VwdCApIHsKLSAgICAgICAgICAgIC8vIFdlIGRvbid0IHRocm93IGFuIGV4Y2VwdGlvbiwgYnV0IGhvbGQgaXQKLSAgICAgICAgICAgIC8vIHVudGlsIHRoZSBlbmQgb2YgdGhlIGRvY3VtZW50LgotICAgICAgICAgICAgaWYgKCBfZXhjZXB0aW9uID09IG51bGwgKQotICAgICAgICAgICAgICAgIF9leGNlcHRpb24gPSBleGNlcHQ7Ci0gICAgICAgICAgICB0aHJvdyBleGNlcHQ7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIHB1YmxpYyB2b2lkIHByaW50VGV4dCggU3RyaW5nQnVmZmVyIHRleHQgKQotICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBpbnQgbGVuZ3RoID0gdGV4dC5sZW5ndGgoKTsKLSAgICAgICAgICAgIGZvciAoIGludCBpID0gMCA7IGkgPCBsZW5ndGggOyArK2kgKSB7Ci0gICAgICAgICAgICAgICAgaWYgKCBfcG9zID09IEJ1ZmZlclNpemUgKSB7Ci0gICAgICAgICAgICAgICAgICAgIF93cml0ZXIud3JpdGUoIF9idWZmZXIgKTsKLSAgICAgICAgICAgICAgICAgICAgX3BvcyA9IDA7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIF9idWZmZXJbIF9wb3MgXSA9IHRleHQuY2hhckF0KCBpICk7Ci0gICAgICAgICAgICAgICAgKytfcG9zOwotICAgICAgICAgICAgfQotICAgICAgICB9IGNhdGNoICggSU9FeGNlcHRpb24gZXhjZXB0ICkgewotICAgICAgICAgICAgLy8gV2UgZG9uJ3QgdGhyb3cgYW4gZXhjZXB0aW9uLCBidXQgaG9sZCBpdAotICAgICAgICAgICAgLy8gdW50aWwgdGhlIGVuZCBvZiB0aGUgZG9jdW1lbnQuCi0gICAgICAgICAgICBpZiAoIF9leGNlcHRpb24gPT0gbnVsbCApCi0gICAgICAgICAgICAgICAgX2V4Y2VwdGlvbiA9IGV4Y2VwdDsKLSAgICAgICAgICAgIHRocm93IGV4Y2VwdDsKLSAgICAgICAgfQotICAgIH0KLQotCi0gICAgcHVibGljIHZvaWQgcHJpbnRUZXh0KCBjaGFyW10gY2hhcnMsIGludCBzdGFydCwgaW50IGxlbmd0aCApCi0gICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIHdoaWxlICggbGVuZ3RoLS0gPiAwICkgewotICAgICAgICAgICAgICAgIGlmICggX3BvcyA9PSBCdWZmZXJTaXplICkgewotICAgICAgICAgICAgICAgICAgICBfd3JpdGVyLndyaXRlKCBfYnVmZmVyICk7Ci0gICAgICAgICAgICAgICAgICAgIF9wb3MgPSAwOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBfYnVmZmVyWyBfcG9zIF0gPSBjaGFyc1sgc3RhcnQgXTsKLSAgICAgICAgICAgICAgICArK3N0YXJ0OwotICAgICAgICAgICAgICAgICsrX3BvczsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSBjYXRjaCAoIElPRXhjZXB0aW9uIGV4Y2VwdCApIHsKLSAgICAgICAgICAgIC8vIFdlIGRvbid0IHRocm93IGFuIGV4Y2VwdGlvbiwgYnV0IGhvbGQgaXQKLSAgICAgICAgICAgIC8vIHVudGlsIHRoZSBlbmQgb2YgdGhlIGRvY3VtZW50LgotICAgICAgICAgICAgaWYgKCBfZXhjZXB0aW9uID09IG51bGwgKQotICAgICAgICAgICAgICAgIF9leGNlcHRpb24gPSBleGNlcHQ7Ci0gICAgICAgICAgICB0aHJvdyBleGNlcHQ7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIHB1YmxpYyB2b2lkIHByaW50VGV4dCggY2hhciBjaCApCi0gICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGlmICggX3BvcyA9PSBCdWZmZXJTaXplICkgewotICAgICAgICAgICAgICAgIF93cml0ZXIud3JpdGUoIF9idWZmZXIgKTsKLSAgICAgICAgICAgICAgICBfcG9zID0gMDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIF9idWZmZXJbIF9wb3MgXSA9IGNoOwotICAgICAgICAgICAgKytfcG9zOwotICAgICAgICB9IGNhdGNoICggSU9FeGNlcHRpb24gZXhjZXB0ICkgewotICAgICAgICAgICAgLy8gV2UgZG9uJ3QgdGhyb3cgYW4gZXhjZXB0aW9uLCBidXQgaG9sZCBpdAotICAgICAgICAgICAgLy8gdW50aWwgdGhlIGVuZCBvZiB0aGUgZG9jdW1lbnQuCi0gICAgICAgICAgICBpZiAoIF9leGNlcHRpb24gPT0gbnVsbCApCi0gICAgICAgICAgICAgICAgX2V4Y2VwdGlvbiA9IGV4Y2VwdDsKLSAgICAgICAgICAgIHRocm93IGV4Y2VwdDsKLSAgICAgICAgfQotICAgIH0KLQotCi0gICAgcHVibGljIHZvaWQgcHJpbnRTcGFjZSgpCi0gICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGlmICggX3BvcyA9PSBCdWZmZXJTaXplICkgewotICAgICAgICAgICAgICAgIF93cml0ZXIud3JpdGUoIF9idWZmZXIgKTsKLSAgICAgICAgICAgICAgICBfcG9zID0gMDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIF9idWZmZXJbIF9wb3MgXSA9ICcgJzsKLSAgICAgICAgICAgICsrX3BvczsKLSAgICAgICAgfSBjYXRjaCAoIElPRXhjZXB0aW9uIGV4Y2VwdCApIHsKLSAgICAgICAgICAgIC8vIFdlIGRvbid0IHRocm93IGFuIGV4Y2VwdGlvbiwgYnV0IGhvbGQgaXQKLSAgICAgICAgICAgIC8vIHVudGlsIHRoZSBlbmQgb2YgdGhlIGRvY3VtZW50LgotICAgICAgICAgICAgaWYgKCBfZXhjZXB0aW9uID09IG51bGwgKQotICAgICAgICAgICAgICAgIF9leGNlcHRpb24gPSBleGNlcHQ7Ci0gICAgICAgICAgICB0aHJvdyBleGNlcHQ7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIHB1YmxpYyB2b2lkIGJyZWFrTGluZSgpCi0gICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGlmICggX3BvcyA9PSBCdWZmZXJTaXplICkgewotICAgICAgICAgICAgICAgIF93cml0ZXIud3JpdGUoIF9idWZmZXIgKTsKLSAgICAgICAgICAgICAgICBfcG9zID0gMDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIF9idWZmZXJbIF9wb3MgXSA9ICdcbic7Ci0gICAgICAgICAgICArK19wb3M7Ci0gICAgICAgIH0gY2F0Y2ggKCBJT0V4Y2VwdGlvbiBleGNlcHQgKSB7Ci0gICAgICAgICAgICAvLyBXZSBkb24ndCB0aHJvdyBhbiBleGNlcHRpb24sIGJ1dCBob2xkIGl0Ci0gICAgICAgICAgICAvLyB1bnRpbCB0aGUgZW5kIG9mIHRoZSBkb2N1bWVudC4KLSAgICAgICAgICAgIGlmICggX2V4Y2VwdGlvbiA9PSBudWxsICkKLSAgICAgICAgICAgICAgICBfZXhjZXB0aW9uID0gZXhjZXB0OwotICAgICAgICAgICAgdGhyb3cgZXhjZXB0OwotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgdm9pZCBicmVha0xpbmUoIGJvb2xlYW4gcHJlc2VydmVTcGFjZSApCi0gICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgYnJlYWtMaW5lKCk7Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgdm9pZCBmbHVzaExpbmUoIGJvb2xlYW4gcHJlc2VydmVTcGFjZSApCi0gICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgLy8gV3JpdGUgYW55dGhpbmcgbGVmdCBpbiB0aGUgYnVmZmVyIGludG8gdGhlIHdyaXRlci4KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIF93cml0ZXIud3JpdGUoIF9idWZmZXIsIDAsIF9wb3MgKTsKLSAgICAgICAgfSBjYXRjaCAoIElPRXhjZXB0aW9uIGV4Y2VwdCApIHsKLSAgICAgICAgICAgIC8vIFdlIGRvbid0IHRocm93IGFuIGV4Y2VwdGlvbiwgYnV0IGhvbGQgaXQKLSAgICAgICAgICAgIC8vIHVudGlsIHRoZSBlbmQgb2YgdGhlIGRvY3VtZW50LgotICAgICAgICAgICAgaWYgKCBfZXhjZXB0aW9uID09IG51bGwgKQotICAgICAgICAgICAgICAgIF9leGNlcHRpb24gPSBleGNlcHQ7Ci0gICAgICAgIH0KLSAgICAgICAgX3BvcyA9IDA7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBGbHVzaCB0aGUgb3V0cHV0IHN0cmVhbS4gTXVzdCBiZSBjYWxsZWQgd2hlbiBkb25lIHByaW50aW5nCi0gICAgICogdGhlIGRvY3VtZW50LCBvdGhlcndpc2Ugc29tZSB0ZXh0IG1pZ2h0IGJlIGJ1ZmZlcmVkLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGZsdXNoKCkKLSAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uCi0gICAgewotICAgICAgICB0cnkgewotICAgICAgICAgICAgX3dyaXRlci53cml0ZSggX2J1ZmZlciwgMCwgX3BvcyApOwotICAgICAgICAgICAgX3dyaXRlci5mbHVzaCgpOwotICAgICAgICB9IGNhdGNoICggSU9FeGNlcHRpb24gZXhjZXB0ICkgewotICAgICAgICAgICAgLy8gV2UgZG9uJ3QgdGhyb3cgYW4gZXhjZXB0aW9uLCBidXQgaG9sZCBpdAotICAgICAgICAgICAgLy8gdW50aWwgdGhlIGVuZCBvZiB0aGUgZG9jdW1lbnQuCi0gICAgICAgICAgICBpZiAoIF9leGNlcHRpb24gPT0gbnVsbCApCi0gICAgICAgICAgICAgICAgX2V4Y2VwdGlvbiA9IGV4Y2VwdDsKLSAgICAgICAgICAgIHRocm93IGV4Y2VwdDsKLSAgICAgICAgfQotICAgICAgICBfcG9zID0gMDsKLSAgICB9Ci0KLQotICAgIHB1YmxpYyB2b2lkIGluZGVudCgpCi0gICAgewotICAgICAgICAvLyBOT09QCi0gICAgfQotCi0KLSAgICBwdWJsaWMgdm9pZCB1bmluZGVudCgpCi0gICAgewotICAgICAgICAvLyBOT09QCi0gICAgfQotCi0KLSAgICBwdWJsaWMgaW50IGdldE5leHRJbmRlbnQoKQotICAgIHsKLSAgICAgICAgcmV0dXJuIDA7Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgdm9pZCBzZXROZXh0SW5kZW50KCBpbnQgaW5kZW50ICkKLSAgICB7Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgdm9pZCBzZXRUaGlzSW5kZW50KCBpbnQgaW5kZW50ICkKLSAgICB7Ci0gICAgfQotCi0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZS9TZWN1cml0eVN1cHBvcnQuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZS9TZWN1cml0eVN1cHBvcnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYjhhZDhmOC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemUvU2VjdXJpdHlTdXBwb3J0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNTIgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMiwyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZTsKLQotaW1wb3J0IGphdmEuaW8uRmlsZTsKLWltcG9ydCBqYXZhLmlvLkZpbGVJbnB1dFN0cmVhbTsKLWltcG9ydCBqYXZhLmlvLkZpbGVOb3RGb3VuZEV4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOwotCi1pbXBvcnQgamF2YS5zZWN1cml0eS5BY2Nlc3NDb250cm9sbGVyOwotaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpdmlsZWdlZEFjdGlvbjsKLWltcG9ydCBqYXZhLnNlY3VyaXR5LlByaXZpbGVnZWRBY3Rpb25FeGNlcHRpb247Ci1pbXBvcnQgamF2YS5zZWN1cml0eS5Qcml2aWxlZ2VkRXhjZXB0aW9uQWN0aW9uOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgaXMgZHVwbGljYXRlZCBmb3IgZWFjaCBzdWJwYWNrYWdlIHNvIGtlZXAgaXQgaW4gc3luYy4KLSAqIEl0IGlzIHBhY2thZ2UgcHJpdmF0ZSBhbmQgdGhlcmVmb3JlIGlzIG5vdCBleHBvc2VkIGFzIHBhcnQgb2YgYW55IEFQSS4KLSAqCi0gKiBAeGVyY2VzLmludGVybmFsCi0gKi8KLWZpbmFsIGNsYXNzIFNlY3VyaXR5U3VwcG9ydCB7Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTZWN1cml0eVN1cHBvcnQgc2VjdXJpdHlTdXBwb3J0ID0gbmV3IFNlY3VyaXR5U3VwcG9ydCgpOwotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIGFuIGluc3RhbmNlIG9mIHRoaXMgY2xhc3MuCi0gICAgICovCi0gICAgc3RhdGljIFNlY3VyaXR5U3VwcG9ydCBnZXRJbnN0YW5jZSgpIHsKLSAgICAgICAgcmV0dXJuIHNlY3VyaXR5U3VwcG9ydDsKLSAgICB9Ci0KLSAgICBDbGFzc0xvYWRlciBnZXRDb250ZXh0Q2xhc3NMb2FkZXIoKSB7Ci0gICAgICAgIHJldHVybiAoQ2xhc3NMb2FkZXIpCi0gICAgICAgIEFjY2Vzc0NvbnRyb2xsZXIuZG9Qcml2aWxlZ2VkKG5ldyBQcml2aWxlZ2VkQWN0aW9uKCkgewotICAgICAgICAgICAgcHVibGljIE9iamVjdCBydW4oKSB7Ci0gICAgICAgICAgICAgICAgQ2xhc3NMb2FkZXIgY2wgPSBudWxsOwotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgIGNsID0gVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5nZXRDb250ZXh0Q2xhc3NMb2FkZXIoKTsKLSAgICAgICAgICAgICAgICB9IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBleCkgeyB9Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGNsOwotICAgICAgICAgICAgfQotICAgICAgICB9KTsKLSAgICB9Ci0KLSAgICBDbGFzc0xvYWRlciBnZXRTeXN0ZW1DbGFzc0xvYWRlcigpIHsKLSAgICAgICAgcmV0dXJuIChDbGFzc0xvYWRlcikKLSAgICAgICAgQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQobmV3IFByaXZpbGVnZWRBY3Rpb24oKSB7Ci0gICAgICAgICAgICBwdWJsaWMgT2JqZWN0IHJ1bigpIHsKLSAgICAgICAgICAgICAgICBDbGFzc0xvYWRlciBjbCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgY2wgPSBDbGFzc0xvYWRlci5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpOwotICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIGV4KSB7fQotICAgICAgICAgICAgICAgIHJldHVybiBjbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSk7Ci0gICAgfQotCi0gICAgQ2xhc3NMb2FkZXIgZ2V0UGFyZW50Q2xhc3NMb2FkZXIoZmluYWwgQ2xhc3NMb2FkZXIgY2wpIHsKLSAgICAgICAgcmV0dXJuIChDbGFzc0xvYWRlcikKLSAgICAgICAgQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQobmV3IFByaXZpbGVnZWRBY3Rpb24oKSB7Ci0gICAgICAgICAgICBwdWJsaWMgT2JqZWN0IHJ1bigpIHsKLSAgICAgICAgICAgICAgICBDbGFzc0xvYWRlciBwYXJlbnQgPSBudWxsOwotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgIHBhcmVudCA9IGNsLmdldFBhcmVudCgpOwotICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIGV4KSB7fQotCi0gICAgICAgICAgICAgICAgLy8gZWxpbWluYXRlIGxvb3BzIGluIGNhc2Ugb2YgdGhlIGJvb3QKLSAgICAgICAgICAgICAgICAvLyBDbGFzc0xvYWRlciByZXR1cm5pbmcgaXRzZWxmIGFzIGEgcGFyZW50Ci0gICAgICAgICAgICAgICAgcmV0dXJuIChwYXJlbnQgPT0gY2wpID8gbnVsbCA6IHBhcmVudDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSk7Ci0gICAgfQotCi0gICAgU3RyaW5nIGdldFN5c3RlbVByb3BlcnR5KGZpbmFsIFN0cmluZyBwcm9wTmFtZSkgewotICAgICAgICByZXR1cm4gKFN0cmluZykKLSAgICAgICAgQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQobmV3IFByaXZpbGVnZWRBY3Rpb24oKSB7Ci0gICAgICAgICAgICBwdWJsaWMgT2JqZWN0IHJ1bigpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gU3lzdGVtLmdldFByb3BlcnR5KHByb3BOYW1lKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSk7Ci0gICAgfQotCi0gICAgRmlsZUlucHV0U3RyZWFtIGdldEZpbGVJbnB1dFN0cmVhbShmaW5hbCBGaWxlIGZpbGUpCi0gICAgdGhyb3dzIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIHJldHVybiAoRmlsZUlucHV0U3RyZWFtKQotICAgICAgICAgICAgQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQobmV3IFByaXZpbGVnZWRFeGNlcHRpb25BY3Rpb24oKSB7Ci0gICAgICAgICAgICAgICAgcHVibGljIE9iamVjdCBydW4oKSB0aHJvd3MgRmlsZU5vdEZvdW5kRXhjZXB0aW9uIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBGaWxlSW5wdXRTdHJlYW0oZmlsZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfSk7Ci0gICAgICAgIH0gY2F0Y2ggKFByaXZpbGVnZWRBY3Rpb25FeGNlcHRpb24gZSkgewotICAgICAgICAgICAgdGhyb3cgKEZpbGVOb3RGb3VuZEV4Y2VwdGlvbillLmdldEV4Y2VwdGlvbigpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgSW5wdXRTdHJlYW0gZ2V0UmVzb3VyY2VBc1N0cmVhbShmaW5hbCBDbGFzc0xvYWRlciBjbCwKLSAgICAgICAgICAgIGZpbmFsIFN0cmluZyBuYW1lKQotICAgIHsKLSAgICAgICAgcmV0dXJuIChJbnB1dFN0cmVhbSkKLSAgICAgICAgQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQobmV3IFByaXZpbGVnZWRBY3Rpb24oKSB7Ci0gICAgICAgICAgICBwdWJsaWMgT2JqZWN0IHJ1bigpIHsKLSAgICAgICAgICAgICAgICBJbnB1dFN0cmVhbSByaXM7Ci0gICAgICAgICAgICAgICAgaWYgKGNsID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgcmlzID0gQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtUmVzb3VyY2VBc1N0cmVhbShuYW1lKTsKLSAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICByaXMgPSBjbC5nZXRSZXNvdXJjZUFzU3RyZWFtKG5hbWUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICByZXR1cm4gcmlzOwotICAgICAgICAgICAgfQotICAgICAgICB9KTsKLSAgICB9Ci0KLSAgICBib29sZWFuIGdldEZpbGVFeGlzdHMoZmluYWwgRmlsZSBmKSB7Ci0gICAgICAgIHJldHVybiAoKEJvb2xlYW4pCi0gICAgICAgICAgICAgICAgQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQobmV3IFByaXZpbGVnZWRBY3Rpb24oKSB7Ci0gICAgICAgICAgICAgICAgICAgIHB1YmxpYyBPYmplY3QgcnVuKCkgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBCb29sZWFuKGYuZXhpc3RzKCkpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfSkpLmJvb2xlYW5WYWx1ZSgpOwotICAgIH0KLQotICAgIGxvbmcgZ2V0TGFzdE1vZGlmaWVkKGZpbmFsIEZpbGUgZikgewotICAgICAgICByZXR1cm4gKChMb25nKQotICAgICAgICAgICAgICAgIEFjY2Vzc0NvbnRyb2xsZXIuZG9Qcml2aWxlZ2VkKG5ldyBQcml2aWxlZ2VkQWN0aW9uKCkgewotICAgICAgICAgICAgICAgICAgICBwdWJsaWMgT2JqZWN0IHJ1bigpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgTG9uZyhmLmxhc3RNb2RpZmllZCgpKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0pKS5sb25nVmFsdWUoKTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIFNlY3VyaXR5U3VwcG9ydCAoKSB7fQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplL1NlcmlhbGl6ZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZS9TZXJpYWxpemVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDVhZWNiNGYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplL1NlcmlhbGl6ZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEyMyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZTsKLQotCi1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKLWltcG9ydCBqYXZhLmlvLldyaXRlcjsKLQotaW1wb3J0IG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LkRvY3VtZW50SGFuZGxlcjsKLQotCi0vKioKLSAqIEludGVyZmFjZSBmb3IgYSBET00gc2VyaWFsaXplciBpbXBsZW1lbnRhdGlvbiwgZmFjdG9yeSBmb3IgRE9NIGFuZCBTQVgKLSAqIHNlcmlhbGl6ZXJzLCBhbmQgc3RhdGljIG1ldGhvZHMgZm9yIHNlcmlhbGl6aW5nIERPTSBkb2N1bWVudHMuCi0gKiA8cD4KLSAqIFRvIHNlcmlhbGl6ZSBhIGRvY3VtZW50IHVzaW5nIFNBWCBldmVudHMsIGNyZWF0ZSBhIGNvbXBhdGlibGUgc2VyaWFsaXplcgotICogYW5kIHBhc3MgaXQgYXJvdW5kIGFzIGEge0BsaW5rCi0gKiBvcmcueG1sLnNheC5Eb2N1bWVudEhhbmRsZXJ9LiBJZiBhbiBJL08gZXJyb3Igb2NjdXJzIHdoaWxlIHNlcmlhbGl6aW5nLCBpdCB3aWxsCi0gKiBiZSB0aHJvd24gYnkge0BsaW5rIERvY3VtZW50SGFuZGxlciNlbmREb2N1bWVudH0uIFRoZSBTQVggc2VyaWFsaXplcgotICogbWF5IGFsc28gYmUgdXNlZCBhcyB7QGxpbmsgb3JnLnhtbC5zYXguRFRESGFuZGxlcn0sIHtAbGluayBvcmcueG1sLnNheC5leHQuRGVjbEhhbmRsZXJ9IGFuZAotICoge0BsaW5rIG9yZy54bWwuc2F4LmV4dC5MZXhpY2FsSGFuZGxlcn0uCi0gKiA8cD4KLSAqIFRvIHNlcmlhbGl6ZSBhIERPTSBkb2N1bWVudCBvciBET00gZWxlbWVudCwgY3JlYXRlIGEgY29tcGF0aWJsZQotICogc2VyaWFsaXplciBhbmQgY2FsbCBpdCdzIHtAbGluawotICogRE9NU2VyaWFsaXplciNzZXJpYWxpemUoRG9jdW1lbnQpfSBvciB7QGxpbmsgRE9NU2VyaWFsaXplciNzZXJpYWxpemUoRWxlbWVudCl9IG1ldGhvZHMuCi0gKiBCb3RoIG1ldGhvZHMgd291bGQgcHJvZHVjZSBhIGZ1bGwgWE1MIGRvY3VtZW50LCB0byBzZXJpemxpZSBvbmx5Ci0gKiB0aGUgcG9ydGlvbiBvZiB0aGUgZG9jdW1lbnQgdXNlIHtAbGluayBPdXRwdXRGb3JtYXQjc2V0T21pdFhNTERlY2xhcmF0aW9ufQotICogYW5kIHNwZWNpZnkgbm8gZG9jdW1lbnQgdHlwZS4KLSAqIDxwPgotICogVGhlIHtAbGluayBPdXRwdXRGb3JtYXR9IGRpY3RhdGVzIHdoYXQgdW5kZXJseWluZyBzZXJpYWxpemVkIGlzIHVzZWQKLSAqIHRvIHNlcmlhbGl6ZSB0aGUgZG9jdW1lbnQgYmFzZWQgb24gdGhlIHNwZWNpZmllZCBtZXRob2QuIElmIHRoZSBvdXRwdXQKLSAqIGZvcm1hdCBvciBtZXRob2QgYXJlIG1pc3NpbmcsIHRoZSBkZWZhdWx0IGlzIGFuIFhNTCBzZXJpYWxpemVyIHdpdGgKLSAqIFVURi04IGVuY29kaW5nIGFuZCBub3cgaW5kZW50YXRpb24uCi0gKgotICoKLSAqIEBhdXRob3IgPGEgaHJlZj0ibWFpbHRvOmFya2luQGludGFsaW8uY29tIj5Bc3NhZiBBcmtpbjwvYT4KLSAqIEBhdXRob3IgPGEgaHJlZj0ibWFpbHRvOlNjb3R0X0JvYWcvQ0FNL0xvdHVzQGxvdHVzLmNvbSI+U2NvdHQgQm9hZzwvYT4KLSAqIEBzZWUgRG9jdW1lbnRIYW5kbGVyCi0gKiBAc2VlIENvbnRlbnRIYW5kbGVyCi0gKiBAc2VlIE91dHB1dEZvcm1hdAotICogQHNlZSBET01TZXJpYWxpemVyCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgU2VyaWFsaXplcgotewotCi0KLSAgICAvKioKLSAgICAgKiBTcGVjaWZpZXMgYW4gb3V0cHV0IHN0cmVhbSB0byB3aGljaCB0aGUgZG9jdW1lbnQgc2hvdWxkIGJlCi0gICAgICogc2VyaWFsaXplZC4gVGhpcyBtZXRob2Qgc2hvdWxkIG5vdCBiZSBjYWxsZWQgd2hpbGUgdGhlCi0gICAgICogc2VyaWFsaXplciBpcyBpbiB0aGUgcHJvY2VzcyBvZiBzZXJpYWxpemluZyBhIGRvY3VtZW50LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldE91dHB1dEJ5dGVTdHJlYW0oT3V0cHV0U3RyZWFtIG91dHB1dCk7Ci0KLQotICAgIC8qKgotICAgICAqIFNwZWNpZmllcyBhIHdyaXRlciB0byB3aGljaCB0aGUgZG9jdW1lbnQgc2hvdWxkIGJlIHNlcmlhbGl6ZWQuCi0gICAgICogVGhpcyBtZXRob2Qgc2hvdWxkIG5vdCBiZSBjYWxsZWQgd2hpbGUgdGhlIHNlcmlhbGl6ZXIgaXMgaW4KLSAgICAgKiB0aGUgcHJvY2VzcyBvZiBzZXJpYWxpemluZyBhIGRvY3VtZW50LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldE91dHB1dENoYXJTdHJlYW0oIFdyaXRlciBvdXRwdXQgKTsKLQotCi0gICAgLyoqCi0gICAgICogU3BlY2lmaWVzIGFuIG91dHB1dCBmb3JtYXQgZm9yIHRoaXMgc2VyaWFsaXplci4gSXQgdGhlCi0gICAgICogc2VyaWFsaXplciBoYXMgYWxyZWFkeSBiZWVuIGFzc29jaWF0ZWQgd2l0aCBhbiBvdXRwdXQgZm9ybWF0LAotICAgICAqIGl0IHdpbGwgc3dpdGNoIHRvIHRoZSBuZXcgZm9ybWF0LiBUaGlzIG1ldGhvZCBzaG91bGQgbm90IGJlCi0gICAgICogY2FsbGVkIHdoaWxlIHRoZSBzZXJpYWxpemVyIGlzIGluIHRoZSBwcm9jZXNzIG9mIHNlcmlhbGl6aW5nCi0gICAgICogYSBkb2N1bWVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBmb3JtYXQgVGhlIG91dHB1dCBmb3JtYXQgdG8gdXNlCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0T3V0cHV0Rm9ybWF0KCBPdXRwdXRGb3JtYXQgZm9ybWF0ICk7Ci0KLQotICAgIC8qKgotICAgICAqIFJldHVybiBhIHtAbGluayBEb2N1bWVudEhhbmRsZXJ9IGludGVyZmFjZSBpbnRvIHRoaXMgc2VyaWFsaXplci4KLSAgICAgKiBJZiB0aGUgc2VyaWFsaXplciBkb2VzIG5vdCBzdXBwb3J0IHRoZSB7QGxpbmsgRG9jdW1lbnRIYW5kbGVyfQotICAgICAqIGludGVyZmFjZSwgaXQgc2hvdWxkIHJldHVybiBudWxsLgotICAgICAqLwotICAgIHB1YmxpYyBEb2N1bWVudEhhbmRsZXIgYXNEb2N1bWVudEhhbmRsZXIoKQotICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb247Ci0KLQotICAgIC8qKgotICAgICAqIFJldHVybiBhIHtAbGluayBDb250ZW50SGFuZGxlcn0gaW50ZXJmYWNlIGludG8gdGhpcyBzZXJpYWxpemVyLgotICAgICAqIElmIHRoZSBzZXJpYWxpemVyIGRvZXMgbm90IHN1cHBvcnQgdGhlIHtAbGluayBDb250ZW50SGFuZGxlcn0KLSAgICAgKiBpbnRlcmZhY2UsIGl0IHNob3VsZCByZXR1cm4gbnVsbC4KLSAgICAgKi8KLSAgICBwdWJsaWMgQ29udGVudEhhbmRsZXIgYXNDb250ZW50SGFuZGxlcigpCi0gICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbjsKLQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIGEge0BsaW5rIERPTVNlcmlhbGl6ZXJ9IGludGVyZmFjZSBpbnRvIHRoaXMgc2VyaWFsaXplci4KLSAgICAgKiBJZiB0aGUgc2VyaWFsaXplciBkb2VzIG5vdCBzdXBwb3J0IHRoZSB7QGxpbmsgRE9NU2VyaWFsaXplcn0KLSAgICAgKiBpbnRlcmZhY2UsIGl0IHNob3VsZCByZXR1cm4gbnVsbC4KLSAgICAgKi8KLSAgICBwdWJsaWMgRE9NU2VyaWFsaXplciBhc0RPTVNlcmlhbGl6ZXIoKQotICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb247Ci0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplL1NlcmlhbGl6ZXJGYWN0b3J5LmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemUvU2VyaWFsaXplckZhY3RvcnkuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMjdiMWU1Yy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemUvU2VyaWFsaXplckZhY3RvcnkuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE1MSArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDE1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICovCi0vKgotICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCi0gKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKLSAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KLSAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCi0gKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAotICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlscy5PYmplY3RGYWN0b3J5OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbHMuU2VjdXJpdHlTdXBwb3J0OwotaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLldyaXRlcjsKLWltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7Ci1pbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7Ci1pbXBvcnQgamF2YS51dGlsLk1hcDsKLWltcG9ydCBqYXZhLnV0aWwuU3RyaW5nVG9rZW5pemVyOwotCi0vKioKLSAqCi0gKgotICogQHZlcnNpb24gJFJldmlzaW9uOiAxLjYgJCAkRGF0ZTogMjAxMC0xMS0wMSAwNDo0MDozNiAkCi0gKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzpTY290dF9Cb2FnL0NBTS9Mb3R1c0Bsb3R1cy5jb20iPlNjb3R0IEJvYWc8L2E+Ci0gKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzphcmtpbkBpbnRhbGlvLmNvbSI+QXNzYWYgQXJraW48L2E+Ci0gKi8KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBTZXJpYWxpemVyRmFjdG9yeQotewotCi0KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBGYWN0b3JpZXNQcm9wZXJ0eSA9ICJjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZS5mYWN0b3JpZXMiOwotCi0KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBNYXA8U3RyaW5nLCBTZXJpYWxpemVyRmFjdG9yeT4gIF9mYWN0b3JpZXMgPSBDb2xsZWN0aW9ucy5zeW5jaHJvbml6ZWRNYXAobmV3IEhhc2hNYXAoKSk7Ci0KLQotICAgIHN0YXRpYwotICAgIHsKLSAgICAgICAgU2VyaWFsaXplckZhY3RvcnkgZmFjdG9yeTsKLSAgICAgICAgU3RyaW5nICAgICAgICAgICAgbGlzdDsKLSAgICAgICAgU3RyaW5nVG9rZW5pemVyICAgdG9rZW47Ci0gICAgICAgIFN0cmluZyAgICAgICAgICAgIGNsYXNzTmFtZTsKLQotICAgICAgICAvLyBUaGUgZGVmYXVsdCBmYWN0b3JpZXMgYXJlIGFsd2F5cyByZWdpc3RlcmVkIGZpcnN0LAotICAgICAgICAvLyBhbnkgZmFjdG9yeSBzcGVjaWZpZWQgaW4gdGhlIHByb3BlcnRpZXMgZmlsZSBhbmQgc3VwcG9ydGluZwotICAgICAgICAvLyB0aGUgc2FtZSBtZXRob2Qgd2lsbCBvdmVycmlkZSB0aGUgZGVmYXVsdCBmYWN0b3J5LgotICAgICAgICBmYWN0b3J5ID0gIG5ldyBTZXJpYWxpemVyRmFjdG9yeUltcGwoIE1ldGhvZC5YTUwgKTsKLSAgICAgICAgcmVnaXN0ZXJTZXJpYWxpemVyRmFjdG9yeSggZmFjdG9yeSApOwotICAgICAgICBmYWN0b3J5ID0gIG5ldyBTZXJpYWxpemVyRmFjdG9yeUltcGwoIE1ldGhvZC5IVE1MICk7Ci0gICAgICAgIHJlZ2lzdGVyU2VyaWFsaXplckZhY3RvcnkoIGZhY3RvcnkgKTsKLSAgICAgICAgZmFjdG9yeSA9ICBuZXcgU2VyaWFsaXplckZhY3RvcnlJbXBsKCBNZXRob2QuWEhUTUwgKTsKLSAgICAgICAgcmVnaXN0ZXJTZXJpYWxpemVyRmFjdG9yeSggZmFjdG9yeSApOwotICAgICAgICBmYWN0b3J5ID0gIG5ldyBTZXJpYWxpemVyRmFjdG9yeUltcGwoIE1ldGhvZC5URVhUICk7Ci0gICAgICAgIHJlZ2lzdGVyU2VyaWFsaXplckZhY3RvcnkoIGZhY3RvcnkgKTsKLQotICAgICAgICBsaXN0ID0gU2VjdXJpdHlTdXBwb3J0LmdldFN5c3RlbVByb3BlcnR5KCBGYWN0b3JpZXNQcm9wZXJ0eSApOwotICAgICAgICBpZiAoIGxpc3QgIT0gbnVsbCApIHsKLSAgICAgICAgICAgIHRva2VuID0gbmV3IFN0cmluZ1Rva2VuaXplciggbGlzdCwgIiA7LDoiICk7Ci0gICAgICAgICAgICB3aGlsZSAoIHRva2VuLmhhc01vcmVUb2tlbnMoKSApIHsKLSAgICAgICAgICAgICAgICBjbGFzc05hbWUgPSB0b2tlbi5uZXh0VG9rZW4oKTsKLSAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICBmYWN0b3J5ID0gKFNlcmlhbGl6ZXJGYWN0b3J5KSBPYmplY3RGYWN0b3J5Lm5ld0luc3RhbmNlKCBjbGFzc05hbWUsIHRydWUpOwotICAgICAgICAgICAgICAgICAgICBpZiAoIF9mYWN0b3JpZXMuY29udGFpbnNLZXkoIGZhY3RvcnkuZ2V0U3VwcG9ydGVkTWV0aG9kKCkgKSApCi0gICAgICAgICAgICAgICAgICAgICAgICBfZmFjdG9yaWVzLnB1dCggZmFjdG9yeS5nZXRTdXBwb3J0ZWRNZXRob2QoKSwgZmFjdG9yeSApOwotICAgICAgICAgICAgICAgIH0gY2F0Y2ggKCBFeGNlcHRpb24gZXhjZXB0ICkgeyB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFJlZ2lzdGVyIGEgc2VyaWFsaXplciBmYWN0b3J5LCBrZXllZCBieSB0aGUgZ2l2ZW4KLSAgICAgKiBtZXRob2Qgc3RyaW5nLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgdm9pZCByZWdpc3RlclNlcmlhbGl6ZXJGYWN0b3J5KCBTZXJpYWxpemVyRmFjdG9yeSBmYWN0b3J5ICkKLSAgICB7Ci0gICAgICAgIFN0cmluZyBtZXRob2Q7Ci0KLSAgICAgICAgc3luY2hyb25pemVkICggX2ZhY3RvcmllcyApIHsKLSAgICAgICAgbWV0aG9kID0gZmFjdG9yeS5nZXRTdXBwb3J0ZWRNZXRob2QoKTsKLSAgICAgICAgX2ZhY3Rvcmllcy5wdXQoIG1ldGhvZCwgZmFjdG9yeSApOwotICAgIH0KLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFJlZ2lzdGVyIGEgc2VyaWFsaXplciBmYWN0b3J5LCBrZXllZCBieSB0aGUgZ2l2ZW4KLSAgICAgKiBtZXRob2Qgc3RyaW5nLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgU2VyaWFsaXplckZhY3RvcnkgZ2V0U2VyaWFsaXplckZhY3RvcnkoIFN0cmluZyBtZXRob2QgKQotICAgIHsKLSAgICAgICAgcmV0dXJuIF9mYWN0b3JpZXMuZ2V0KCBtZXRob2QgKTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIG1ldGhvZCBzdXBwb3J0ZWQgYnkgdGhpcyBmYWN0b3J5IGFuZCB1c2VkIHRvIHJlZ2lzdGVyCi0gICAgICogdGhlIGZhY3RvcnkuIFRoaXMgY2FsbCBpcyByZXF1aXJlZCBzbyBmYWN0b3JpZXMgY2FuIGJlIGFkZGVkIGZyb20KLSAgICAgKiBhIHByb3BlcnRpZXMgZmlsZSBieSBrbm93aW5nIG9ubHkgdGhlIGNsYXNzIG5hbWUuIFRoaXMgbWV0aG9kIGlzCi0gICAgICogcHJvdGVjdGVkLCBpdCBpcyBvbmx5IHJlcXVpcmVkIGJ5IHRoaXMgY2xhc3MgYnV0IG11c3QgYmUgaW1wbGVtZW50ZWQKLSAgICAgKiBpbiBkZXJpdmVkIGNsYXNzZXMuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGFic3RyYWN0IFN0cmluZyBnZXRTdXBwb3J0ZWRNZXRob2QoKTsKLQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlIGEgbmV3IHNlcmlhbGl6ZXIgYmFzZWQgb24gdGhlIHtAbGluayBPdXRwdXRGb3JtYXR9LgotICAgICAqIElmIHRoaXMgbWV0aG9kIGlzIHVzZWQgdG8gY3JlYXRlIHRoZSBzZXJpYWxpemVyLCB0aGUge0BsaW5rCi0gICAgICogU2VyaWFsaXplciNzZXRPdXRwdXRCeXRlU3RyZWFtfSBvciB7QGxpbmsgU2VyaWFsaXplciNzZXRPdXRwdXRDaGFyU3RyZWFtfQotICAgICAqIG1ldGhvZHMgbXVzdCBiZSBjYWxsZWQgYmVmb3JlIHNlcmlhbGl6aW5nIGEgZG9jdW1lbnQuCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IFNlcmlhbGl6ZXIgbWFrZVNlcmlhbGl6ZXIoT3V0cHV0Rm9ybWF0IGZvcm1hdCk7Ci0KLQotICAgIC8qKgotICAgICAqIENyZWF0ZSBhIG5ldyBzZXJpYWxpemVyLCBiYXNlZCBvbiB0aGUge0BsaW5rIE91dHB1dEZvcm1hdH0gYW5kCi0gICAgICogdXNpbmcgdGhlIHdyaXRlciBhcyB0aGUgb3V0cHV0IGNoYXJhY3RlciBzdHJlYW0uICBJZiB0aGlzCi0gICAgICogbWV0aG9kIGlzIHVzZWQsIHRoZSBlbmNvZGluZyBwcm9wZXJ0eSB3aWxsIGJlIGlnbm9yZWQuCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IFNlcmlhbGl6ZXIgbWFrZVNlcmlhbGl6ZXIoIFdyaXRlciB3cml0ZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE91dHB1dEZvcm1hdCBmb3JtYXQgKTsKLQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlIGEgbmV3IHNlcmlhbGl6ZXIsIGJhc2VkIG9uIHRoZSB7QGxpbmsgT3V0cHV0Rm9ybWF0fSBhbmQKLSAgICAgKiB1c2luZyB0aGUgb3V0cHV0IGJ5dGUgc3RyZWFtIGFuZCB0aGUgZW5jb2Rpbmcgc3BlY2lmaWVkIGluIHRoZQotICAgICAqIG91dHB1dCBmb3JtYXQuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gVGhlIHNwZWNpZmllZCBlbmNvZGluZyBpcwotICAgICAqICAgbm90IHN1cHBvcnRlZAotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCBTZXJpYWxpemVyIG1ha2VTZXJpYWxpemVyKCBPdXRwdXRTdHJlYW0gb3V0cHV0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPdXRwdXRGb3JtYXQgZm9ybWF0ICkKLSAgICAgICAgdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb247Ci0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplL1NlcmlhbGl6ZXJGYWN0b3J5SW1wbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplL1NlcmlhbGl6ZXJGYWN0b3J5SW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkZDI3ZTU3Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZS9TZXJpYWxpemVyRmFjdG9yeUltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExNiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZTsKLQotCi1pbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5pby5Xcml0ZXI7Ci1pbXBvcnQgamF2YS5pby5VbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tLkRPTU1lc3NhZ2VGb3JtYXR0ZXI7Ci0KLS8qKgotICogRGVmYXVsdCBzZXJpYWxpemVyIGZhY3RvcnkgY2FuIGNvbnN0cnVjdCBzZXJpYWxpemVycyBmb3IgdGhlIHRocmVlCi0gKiBtYXJrdXAgc2VyaWFsaXplcnMgKFhNTCwgSFRNTCwgWEhUTUwgKS4KLSAqCi0gKgotICogQGF1dGhvciA8YSBocmVmPSJtYWlsdG86U2NvdHRfQm9hZy9DQU0vTG90dXNAbG90dXMuY29tIj5TY290dCBCb2FnPC9hPgotICogQGF1dGhvciA8YSBocmVmPSJtYWlsdG86YXJraW5AaW50YWxpby5jb20iPkFzc2FmIEFya2luPC9hPgotICovCi1maW5hbCBjbGFzcyBTZXJpYWxpemVyRmFjdG9yeUltcGwKLSAgICBleHRlbmRzIFNlcmlhbGl6ZXJGYWN0b3J5Ci17Ci0KLQotICAgIHByaXZhdGUgU3RyaW5nIF9tZXRob2Q7Ci0KLQotICAgIFNlcmlhbGl6ZXJGYWN0b3J5SW1wbCggU3RyaW5nIG1ldGhvZCApCi0gICAgewotICAgICAgICBfbWV0aG9kID0gbWV0aG9kOwotICAgICAgICBpZiAoICEgX21ldGhvZC5lcXVhbHMoIE1ldGhvZC5YTUwgKSAmJgotICAgICAgICAgICAgICEgX21ldGhvZC5lcXVhbHMoIE1ldGhvZC5IVE1MICkgJiYKLSAgICAgICAgICAgICAhIF9tZXRob2QuZXF1YWxzKCBNZXRob2QuWEhUTUwgKSAmJgotICAgICAgICAgICAgICEgX21ldGhvZC5lcXVhbHMoIE1ldGhvZC5URVhUICkgKSB7Ci0gICAgICAgICAgICBTdHJpbmcgbXNnID0gRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuU0VSSUFMSVpFUl9ET01BSU4sICJNZXRob2ROb3RTdXBwb3J0ZWQiLCBuZXcgT2JqZWN0W117bWV0aG9kfSk7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKG1zZyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIHB1YmxpYyBTZXJpYWxpemVyIG1ha2VTZXJpYWxpemVyKCBPdXRwdXRGb3JtYXQgZm9ybWF0ICkKLSAgICB7Ci0gICAgICAgIFNlcmlhbGl6ZXIgc2VyaWFsaXplcjsKLQotICAgICAgICBzZXJpYWxpemVyID0gZ2V0U2VyaWFsaXplciggZm9ybWF0ICk7Ci0gICAgICAgIHNlcmlhbGl6ZXIuc2V0T3V0cHV0Rm9ybWF0KCBmb3JtYXQgKTsKLSAgICAgICAgcmV0dXJuIHNlcmlhbGl6ZXI7Ci0gICAgfQotCi0KLQotICAgIHB1YmxpYyBTZXJpYWxpemVyIG1ha2VTZXJpYWxpemVyKCBXcml0ZXIgd3JpdGVyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPdXRwdXRGb3JtYXQgZm9ybWF0ICkKLSAgICB7Ci0gICAgICAgIFNlcmlhbGl6ZXIgc2VyaWFsaXplcjsKLQotICAgICAgICBzZXJpYWxpemVyID0gZ2V0U2VyaWFsaXplciggZm9ybWF0ICk7Ci0gICAgICAgIHNlcmlhbGl6ZXIuc2V0T3V0cHV0Q2hhclN0cmVhbSggd3JpdGVyICk7Ci0gICAgICAgIHJldHVybiBzZXJpYWxpemVyOwotICAgIH0KLQotCi0gICAgcHVibGljIFNlcmlhbGl6ZXIgbWFrZVNlcmlhbGl6ZXIoIE91dHB1dFN0cmVhbSBvdXRwdXQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE91dHB1dEZvcm1hdCBmb3JtYXQgKQotICAgICAgICB0aHJvd3MgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgU2VyaWFsaXplciBzZXJpYWxpemVyOwotCi0gICAgICAgIHNlcmlhbGl6ZXIgPSBnZXRTZXJpYWxpemVyKCBmb3JtYXQgKTsKLSAgICAgICAgc2VyaWFsaXplci5zZXRPdXRwdXRCeXRlU3RyZWFtKCBvdXRwdXQgKTsKLSAgICAgICAgcmV0dXJuIHNlcmlhbGl6ZXI7Ci0gICAgfQotCi0KLSAgICBwcml2YXRlIFNlcmlhbGl6ZXIgZ2V0U2VyaWFsaXplciggT3V0cHV0Rm9ybWF0IGZvcm1hdCApCi0gICAgewotICAgICAgICBpZiAoIF9tZXRob2QuZXF1YWxzKCBNZXRob2QuWE1MICkgKSB7Ci0gICAgICAgICAgICByZXR1cm4gbmV3IFhNTFNlcmlhbGl6ZXIoIGZvcm1hdCApOwotICAgICAgICB9IGVsc2UgaWYgKCBfbWV0aG9kLmVxdWFscyggTWV0aG9kLkhUTUwgKSApIHsKLSAgICAgICAgICAgIHJldHVybiBuZXcgSFRNTFNlcmlhbGl6ZXIoIGZvcm1hdCApOwotICAgICAgICB9ICBlbHNlIGlmICggX21ldGhvZC5lcXVhbHMoIE1ldGhvZC5YSFRNTCApICkgewotICAgICAgICAgICAgcmV0dXJuIG5ldyBYSFRNTFNlcmlhbGl6ZXIoIGZvcm1hdCApOwotICAgICAgICB9ICBlbHNlIGlmICggX21ldGhvZC5lcXVhbHMoIE1ldGhvZC5URVhUICkgKSB7Ci0gICAgICAgICAgICByZXR1cm4gbmV3IFRleHRTZXJpYWxpemVyKCk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBTdHJpbmcgbXNnID0gRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKERPTU1lc3NhZ2VGb3JtYXR0ZXIuU0VSSUFMSVpFUl9ET01BSU4sICJNZXRob2ROb3RTdXBwb3J0ZWQiLCBuZXcgT2JqZWN0W117X21ldGhvZH0pOwotICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbihtc2cpOwotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICBwcm90ZWN0ZWQgU3RyaW5nIGdldFN1cHBvcnRlZE1ldGhvZCgpCi0gICAgewotICAgICAgICByZXR1cm4gX21ldGhvZDsKLSAgICB9Ci0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplL1RleHRTZXJpYWxpemVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemUvVGV4dFNlcmlhbGl6ZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNzg5ZjYzNi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemUvVGV4dFNlcmlhbGl6ZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDM5MCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDIsMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLQotLy8gU2VwIDE0LCAyMDAwOgotLy8gIEZpeGVkIHNlcmlhbGl6ZXIgdG8gcmVwb3J0IElPIGV4Y2VwdGlvbiBkaXJlY3RseSwgaW5zdGVhZCBhdAotLy8gIHRoZSBlbmQgb2YgZG9jdW1lbnQgcHJvY2Vzc2luZy4KLS8vICBSZXBvcnRlZCBieSBQYXRyaWNrIEhpZ2dpbnMgPHBoaWdnaW5zQHRyYW5zemFwLmNvbT4KLQotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplOwotCi0KLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotCi1pbXBvcnQgb3JnLnczYy5kb20uRWxlbWVudDsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotaW1wb3J0IG9yZy54bWwuc2F4LkF0dHJpYnV0ZUxpc3Q7Ci1pbXBvcnQgb3JnLnhtbC5zYXguQXR0cmlidXRlczsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci0KLQotLyoqCi0gKiBJbXBsZW1lbnRzIGEgdGV4dCBzZXJpYWxpemVyIHN1cHBvcnRpbmcgYm90aCBET00gYW5kIFNBWAotICogc2VyaWFsaXppbmcuIEZvciB1c2FnZSBpbnN0cnVjdGlvbnMgc2VlIHtAbGluayBTZXJpYWxpemVyfS4KLSAqIDxwPgotICogSWYgYW4gb3V0cHV0IHN0cmVhbSBpcyB1c2VkLCB0aGUgZW5jb2RpbmcgaXMgdGFrZW4gZnJvbSB0aGUKLSAqIG91dHB1dCBmb3JtYXQgKGRlZmF1bHRzIHRvIDx0dD5VVEYtODwvdHQ+KS4gSWYgYSB3cml0ZXIgaXMKLSAqIHVzZWQsIG1ha2Ugc3VyZSB0aGUgd3JpdGVyIHVzZXMgdGhlIHNhbWUgZW5jb2RpbmcgKGlmIGFwcGxpZXMpCi0gKiBhcyBzcGVjaWZpZWQgaW4gdGhlIG91dHB1dCBmb3JtYXQuCi0gKiA8cD4KLSAqIFRoZSBzZXJpYWxpemVyIHN1cHBvcnRzIGJvdGggRE9NIGFuZCBTQVguIERPTSBzZXJpYWxpemluZyBpcyBkb25lCi0gKiBieSBjYWxsaW5nIHtAbGluayAjc2VyaWFsaXplfSBhbmQgU0FYIHNlcmlhbGl6aW5nIGlzIGRvbmUgYnkgZmlyaW5nCi0gKiBTQVggZXZlbnRzIGFuZCB1c2luZyB0aGUgc2VyaWFsaXplciBhcyBhIGRvY3VtZW50IGhhbmRsZXIuCi0gKiA8cD4KLSAqIElmIGFuIEkvTyBleGNlcHRpb24gb2NjdXJzIHdoaWxlIHNlcmlhbGl6aW5nLCB0aGUgc2VyaWFsaXplcgotICogd2lsbCBub3QgdGhyb3cgYW4gZXhjZXB0aW9uIGRpcmVjdGx5LCBidXQgb25seSB0aHJvdyBpdAotICogYXQgdGhlIGVuZCBvZiBzZXJpYWxpemluZyAoZWl0aGVyIERPTSBvciBTQVgncyB7QGxpbmsKLSAqIG9yZy54bWwuc2F4LkRvY3VtZW50SGFuZGxlciNlbmREb2N1bWVudH0uCi0gKgotICoKLSAqIEBhdXRob3IgPGEgaHJlZj0ibWFpbHRvOmFya2luQGludGFsaW8uY29tIj5Bc3NhZiBBcmtpbjwvYT4KLSAqIEBzZWUgU2VyaWFsaXplcgotICovCi1wdWJsaWMgY2xhc3MgVGV4dFNlcmlhbGl6ZXIKLSAgICBleHRlbmRzIEJhc2VNYXJrdXBTZXJpYWxpemVyCi17Ci0KLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHMgYSBuZXcgc2VyaWFsaXplci4gVGhlIHNlcmlhbGl6ZXIgY2Fubm90IGJlIHVzZWQgd2l0aG91dAotICAgICAqIGNhbGxpbmcge0BsaW5rICNzZXRPdXRwdXRDaGFyU3RyZWFtfSBvciB7QGxpbmsgI3NldE91dHB1dEJ5dGVTdHJlYW19Ci0gICAgICogZmlyc3QuCi0gICAgICovCi0gICAgcHVibGljIFRleHRTZXJpYWxpemVyKCkKLSAgICB7Ci0gICAgICAgIHN1cGVyKCBuZXcgT3V0cHV0Rm9ybWF0KCBNZXRob2QuVEVYVCwgbnVsbCwgZmFsc2UgKSApOwotICAgIH0KLQotCi0gICAgcHVibGljIHZvaWQgc2V0T3V0cHV0Rm9ybWF0KCBPdXRwdXRGb3JtYXQgZm9ybWF0ICkKLSAgICB7Ci0gICAgICAgIHN1cGVyLnNldE91dHB1dEZvcm1hdCggZm9ybWF0ICE9IG51bGwgPyBmb3JtYXQgOiBuZXcgT3V0cHV0Rm9ybWF0KCBNZXRob2QuVEVYVCwgbnVsbCwgZmFsc2UgKSApOwotICAgIH0KLQotCi0gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS8vCi0gICAgLy8gU0FYIGNvbnRlbnQgaGFuZGxlciBzZXJpYWxpemluZyBtZXRob2RzIC8vCi0gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS8vCi0KLQotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudCggU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIGxvY2FsTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyByYXdOYW1lLCBBdHRyaWJ1dGVzIGF0dHJzICkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgc3RhcnRFbGVtZW50KCByYXdOYW1lID09IG51bGwgPyBsb2NhbE5hbWUgOiByYXdOYW1lLCBudWxsICk7Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgdm9pZCBlbmRFbGVtZW50KCBTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgbG9jYWxOYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyByYXdOYW1lICkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgZW5kRWxlbWVudCggcmF3TmFtZSA9PSBudWxsID8gbG9jYWxOYW1lIDogcmF3TmFtZSApOwotICAgIH0KLQotCi0gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0vLwotICAgIC8vIFNBWCBkb2N1bWVudCBoYW5kbGVyIHNlcmlhbGl6aW5nIG1ldGhvZHMgLy8KLSAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLTAwMC0tLS0tLS0tLS8vCi0KLQotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudCggU3RyaW5nIHRhZ05hbWUsIEF0dHJpYnV0ZUxpc3QgYXR0cnMgKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBib29sZWFuICAgICAgcHJlc2VydmVTcGFjZTsKLSAgICAgICAgRWxlbWVudFN0YXRlIHN0YXRlOwotCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBzdGF0ZSA9IGdldEVsZW1lbnRTdGF0ZSgpOwotICAgICAgICAgICAgaWYgKCBpc0RvY3VtZW50U3RhdGUoKSApIHsKLSAgICAgICAgICAgICAgICAvLyBJZiB0aGlzIGlzIHRoZSByb290IGVsZW1lbnQgaGFuZGxlIGl0IGRpZmZlcmVudGx5LgotICAgICAgICAgICAgICAgIC8vIElmIHRoZSBmaXJzdCByb290IGVsZW1lbnQgaW4gdGhlIGRvY3VtZW50LCBzZXJpYWxpemUKLSAgICAgICAgICAgICAgICAvLyB0aGUgZG9jdW1lbnQncyBET0NUWVBFLiBTcGFjZSBwcmVzZXJ2aW5nIGRlZmF1bHRzCi0gICAgICAgICAgICAgICAgLy8gdG8gdGhhdCBvZiB0aGUgb3V0cHV0IGZvcm1hdC4KLSAgICAgICAgICAgICAgICBpZiAoICEgX3N0YXJ0ZWQgKQotICAgICAgICAgICAgICAgICAgICBzdGFydERvY3VtZW50KCB0YWdOYW1lICk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyBGb3IgYW55IG90aGVyIGVsZW1lbnQsIGlmIGZpcnN0IGluIHBhcmVudCwgdGhlbgotICAgICAgICAgICAgLy8gdXNlIHRoZSBwYXJuZXQncyBzcGFjZSBwcmVzZXJ2aW5nLgotICAgICAgICAgICAgcHJlc2VydmVTcGFjZSA9IHN0YXRlLnByZXNlcnZlU3BhY2U7Ci0KLSAgICAgICAgICAgIC8vIERvIG5vdCBjaGFuZ2UgdGhlIGN1cnJlbnQgZWxlbWVudCBzdGF0ZSB5ZXQuCi0gICAgICAgICAgICAvLyBUaGlzIG9ubHkgaGFwcGVucyBpbiBlbmRFbGVtZW50KCkuCi0KLSAgICAgICAgICAgIC8vIElnbm9yZSBhbGwgb3RoZXIgYXR0cmlidXRlcyBvZiB0aGUgZWxlbWVudCwgb25seSBwcmludGluZwotICAgICAgICAgICAgLy8gaXRzIGNvbnRlbnRzLgotCi0gICAgICAgICAgICAvLyBOb3cgaXQncyB0aW1lIHRvIGVudGVyIGEgbmV3IGVsZW1lbnQgc3RhdGUKLSAgICAgICAgICAgIC8vIHdpdGggdGhlIHRhZyBuYW1lIGFuZCBzcGFjZSBwcmVzZXJ2aW5nLgotICAgICAgICAgICAgLy8gV2Ugc3RpbGwgZG8gbm90IGNoYW5nZSB0aGUgY3VyZW50IGVsZW1lbnQgc3RhdGUuCi0gICAgICAgICAgICBzdGF0ZSA9IGVudGVyRWxlbWVudFN0YXRlKCBudWxsLCBudWxsLCB0YWdOYW1lLCBwcmVzZXJ2ZVNwYWNlICk7Ci0gICAgICAgIH0gY2F0Y2ggKCBJT0V4Y2VwdGlvbiBleGNlcHQgKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKCBleGNlcHQgKTsKLSAgICAgICAgfQotICAgIH0KLQotCi0gICAgcHVibGljIHZvaWQgZW5kRWxlbWVudCggU3RyaW5nIHRhZ05hbWUgKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICB0cnkgewotICAgICAgICAgICAgZW5kRWxlbWVudElPKCB0YWdOYW1lICk7Ci0gICAgICAgIH0gY2F0Y2ggKCBJT0V4Y2VwdGlvbiBleGNlcHQgKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKCBleGNlcHQgKTsKLSAgICAgICAgfQotICAgIH0KLQotCi0gICAgcHVibGljIHZvaWQgZW5kRWxlbWVudElPKCBTdHJpbmcgdGFnTmFtZSApCi0gICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgRWxlbWVudFN0YXRlIHN0YXRlOwotCi0gICAgICAgIC8vIFdvcmtzIG11Y2ggbGlrZSBjb250ZW50KCkgd2l0aCBhZGRpdGlvbnMgZm9yIGNsb3NpbmcKLSAgICAgICAgLy8gYW4gZWxlbWVudC4gTm90ZSB0aGUgZGlmZmVyZW50IGNoZWNrcyBmb3IgdGhlIGNsb3NlZAotICAgICAgICAvLyBlbGVtZW50J3Mgc3RhdGUgYW5kIHRoZSBwYXJlbnQgZWxlbWVudCdzIHN0YXRlLgotICAgICAgICBzdGF0ZSA9IGdldEVsZW1lbnRTdGF0ZSgpOwotICAgICAgICAvLyBMZWF2ZSB0aGUgZWxlbWVudCBzdGF0ZSBhbmQgdXBkYXRlIHRoYXQgb2YgdGhlIHBhcmVudAotICAgICAgICAvLyAoaWYgd2UncmUgbm90IHJvb3QpIHRvIG5vdCBlbXB0eSBhbmQgYWZ0ZXIgZWxlbWVudC4KLSAgICAgICAgc3RhdGUgPSBsZWF2ZUVsZW1lbnRTdGF0ZSgpOwotICAgICAgICBzdGF0ZS5hZnRlckVsZW1lbnQgPSB0cnVlOwotICAgICAgICBzdGF0ZS5lbXB0eSA9IGZhbHNlOwotICAgICAgICBpZiAoIGlzRG9jdW1lbnRTdGF0ZSgpICkKLSAgICAgICAgICAgIF9wcmludGVyLmZsdXNoKCk7Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgdm9pZCBwcm9jZXNzaW5nSW5zdHJ1Y3Rpb25JTyggU3RyaW5nIHRhcmdldCwgU3RyaW5nIGNvZGUgKSB0aHJvd3MgSU9FeGNlcHRpb24KLSAgICB7Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgdm9pZCBjb21tZW50KCBTdHJpbmcgdGV4dCApCi0gICAgewotICAgIH0KLQotCi0gICAgcHVibGljIHZvaWQgY29tbWVudCggY2hhcltdIGNoYXJzLCBpbnQgc3RhcnQsIGludCBsZW5ndGggKQotICAgIHsKLSAgICB9Ci0KLQotICAgIHB1YmxpYyB2b2lkIGNoYXJhY3RlcnMoIGNoYXJbXSBjaGFycywgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoICkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgRWxlbWVudFN0YXRlIHN0YXRlOwotCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBzdGF0ZSA9IGNvbnRlbnQoKTsKLSAgICAgICAgICAgIHN0YXRlLmRvQ0RhdGEgPSBzdGF0ZS5pbkNEYXRhID0gZmFsc2U7Ci0gICAgICAgICAgICBwcmludFRleHQoIGNoYXJzLCBzdGFydCwgbGVuZ3RoLCB0cnVlLCB0cnVlICk7Ci0gICAgICAgIH0gY2F0Y2ggKCBJT0V4Y2VwdGlvbiBleGNlcHQgKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKCBleGNlcHQgKTsKLSAgICAgICAgfQotICAgIH0KLQotCi0gICAgcHJvdGVjdGVkIHZvaWQgY2hhcmFjdGVycyggU3RyaW5nIHRleHQsIGJvb2xlYW4gdW5lc2NhcGVkICkKLSAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uCi0gICAgewotICAgICAgICBFbGVtZW50U3RhdGUgc3RhdGU7Ci0KLSAgICAgICAgc3RhdGUgPSBjb250ZW50KCk7Ci0gICAgICAgIHN0YXRlLmRvQ0RhdGEgPSBzdGF0ZS5pbkNEYXRhID0gZmFsc2U7Ci0gICAgICAgIHByaW50VGV4dCggdGV4dCwgdHJ1ZSwgdHJ1ZSApOwotICAgIH0KLQotCi0gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0vLwotICAgIC8vIEdlbmVyaWMgbm9kZSBzZXJpYWxpemluZyBtZXRob2RzIG1ldGhvZHMgLy8KLSAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS8vCi0KLQotICAgIC8qKgotICAgICAqIENhbGxlZCB0byBzZXJpYWxpemUgdGhlIGRvY3VtZW50J3MgRE9DVFlQRSBieSB0aGUgcm9vdCBlbGVtZW50LgotICAgICAqIDxwPgotICAgICAqIFRoaXMgbWV0aG9kIHdpbGwgY2hlY2sgaWYgaXQgaGFzIG5vdCBiZWVuIGNhbGxlZCBiZWZvcmUgKHtAbGluayAjX3N0YXJ0ZWR9KSwKLSAgICAgKiB3aWxsIHNlcmlhbGl6ZSB0aGUgZG9jdW1lbnQgdHlwZSBkZWNsYXJhdGlvbiwgYW5kIHdpbGwgc2VyaWFsaXplIGFsbAotICAgICAqIHByZS1yb290IGNvbW1lbnRzIGFuZCBQSXMgdGhhdCB3ZXJlIGFjY3VtdWxhdGVkIGluIHRoZSBkb2N1bWVudAotICAgICAqIChzZWUge0BsaW5rICNzZXJpYWxpemVQcmVSb290fSkuIFByZS1yb290IHdpbGwgYmUgc2VyaWFsaXplZCBldmVuIGlmCi0gICAgICogdGhpcyBpcyBub3QgdGhlIGZpcnN0IHJvb3QgZWxlbWVudCBvZiB0aGUgZG9jdW1lbnQuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgc3RhcnREb2N1bWVudCggU3RyaW5nIHJvb3RUYWdOYW1lICkKLSAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uCi0gICAgewotICAgICAgICAvLyBSZXF1aXJlZCB0byBzdG9wIHByb2Nlc3NpbmcgdGhlIERURCwgZXZlbiB0aG91Z2ggdGhlIERURAotICAgICAgICAvLyBpcyBub3QgcHJpbnRlZC4KLSAgICAgICAgX3ByaW50ZXIubGVhdmVEVEQoKTsKLQotICAgICAgICBfc3RhcnRlZCA9IHRydWU7Ci0gICAgICAgIC8vIEFsd2F5cyBzZXJpYWxpemUgdGhlc2UsIGV2ZW4gaWYgbm90IHRlIGZpcnN0IHJvb3QgZWxlbWVudC4KLSAgICAgICAgc2VyaWFsaXplUHJlUm9vdCgpOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogQ2FsbGVkIHRvIHNlcmlhbGl6ZSBhIERPTSBlbGVtZW50LiBFcXVpdmFsZW50IHRvIGNhbGxpbmcge0BsaW5rCi0gICAgICogI3N0YXJ0RWxlbWVudH0sIHtAbGluayAjZW5kRWxlbWVudH0gYW5kIHNlcmlhbGl6aW5nIGV2ZXJ5dGhpbmcKLSAgICAgKiBpbmJldHdlZW4sIGJ1dCBiZXR0ZXIgb3B0aW1pemVkLgotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIHNlcmlhbGl6ZUVsZW1lbnQoIEVsZW1lbnQgZWxlbSApCi0gICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgTm9kZSAgICAgICAgIGNoaWxkOwotICAgICAgICBFbGVtZW50U3RhdGUgc3RhdGU7Ci0gICAgICAgIGJvb2xlYW4gICAgICBwcmVzZXJ2ZVNwYWNlOwotICAgICAgICBTdHJpbmcgICAgICAgdGFnTmFtZTsKLQotICAgICAgICB0YWdOYW1lID0gZWxlbS5nZXRUYWdOYW1lKCk7Ci0gICAgICAgIHN0YXRlID0gZ2V0RWxlbWVudFN0YXRlKCk7Ci0gICAgICAgIGlmICggaXNEb2N1bWVudFN0YXRlKCkgKSB7Ci0gICAgICAgICAgICAvLyBJZiB0aGlzIGlzIHRoZSByb290IGVsZW1lbnQgaGFuZGxlIGl0IGRpZmZlcmVudGx5LgotICAgICAgICAgICAgLy8gSWYgdGhlIGZpcnN0IHJvb3QgZWxlbWVudCBpbiB0aGUgZG9jdW1lbnQsIHNlcmlhbGl6ZQotICAgICAgICAgICAgLy8gdGhlIGRvY3VtZW50J3MgRE9DVFlQRS4gU3BhY2UgcHJlc2VydmluZyBkZWZhdWx0cwotICAgICAgICAgICAgLy8gdG8gdGhhdCBvZiB0aGUgb3V0cHV0IGZvcm1hdC4KLSAgICAgICAgICAgIGlmICggISBfc3RhcnRlZCApCi0gICAgICAgICAgICAgICAgc3RhcnREb2N1bWVudCggdGFnTmFtZSApOwotICAgICAgICB9Ci0gICAgICAgIC8vIEZvciBhbnkgb3RoZXIgZWxlbWVudCwgaWYgZmlyc3QgaW4gcGFyZW50LCB0aGVuCi0gICAgICAgIC8vIHVzZSB0aGUgcGFybmV0J3Mgc3BhY2UgcHJlc2VydmluZy4KLSAgICAgICAgcHJlc2VydmVTcGFjZSA9IHN0YXRlLnByZXNlcnZlU3BhY2U7Ci0KLSAgICAgICAgLy8gRG8gbm90IGNoYW5nZSB0aGUgY3VycmVudCBlbGVtZW50IHN0YXRlIHlldC4KLSAgICAgICAgLy8gVGhpcyBvbmx5IGhhcHBlbnMgaW4gZW5kRWxlbWVudCgpLgotCi0gICAgICAgIC8vIElnbm9yZSBhbGwgb3RoZXIgYXR0cmlidXRlcyBvZiB0aGUgZWxlbWVudCwgb25seSBwcmludGluZwotICAgICAgICAvLyBpdHMgY29udGVudHMuCi0KLSAgICAgICAgLy8gSWYgZWxlbWVudCBoYXMgY2hpbGRyZW4sIHRoZW4gc2VyaWFsaXplIHRoZW0sIG90aGVyd2lzZQotICAgICAgICAvLyBzZXJpYWxpemUgZW4gZW1wdHkgdGFnLgotICAgICAgICBpZiAoIGVsZW0uaGFzQ2hpbGROb2RlcygpICkgewotICAgICAgICAgICAgLy8gRW50ZXIgYW4gZWxlbWVudCBzdGF0ZSwgYW5kIHNlcmlhbGl6ZSB0aGUgY2hpbGRyZW4KLSAgICAgICAgICAgIC8vIG9uZSBieSBvbmUuIEZpbmFsbHksIGVuZCB0aGUgZWxlbWVudC4KLSAgICAgICAgICAgIHN0YXRlID0gZW50ZXJFbGVtZW50U3RhdGUoIG51bGwsIG51bGwsIHRhZ05hbWUsIHByZXNlcnZlU3BhY2UgKTsKLSAgICAgICAgICAgIGNoaWxkID0gZWxlbS5nZXRGaXJzdENoaWxkKCk7Ci0gICAgICAgICAgICB3aGlsZSAoIGNoaWxkICE9IG51bGwgKSB7Ci0gICAgICAgICAgICAgICAgc2VyaWFsaXplTm9kZSggY2hpbGQgKTsKLSAgICAgICAgICAgICAgICBjaGlsZCA9IGNoaWxkLmdldE5leHRTaWJsaW5nKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbmRFbGVtZW50SU8oIHRhZ05hbWUgKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIGlmICggISBpc0RvY3VtZW50U3RhdGUoKSApIHsKLSAgICAgICAgICAgICAgICAvLyBBZnRlciBlbGVtZW50IGJ1dCBwYXJlbnQgZWxlbWVudCBpcyBubyBsb25nZXIgZW1wdHkuCi0gICAgICAgICAgICAgICAgc3RhdGUuYWZ0ZXJFbGVtZW50ID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICBzdGF0ZS5lbXB0eSA9IGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBTZXJpYWxpemUgdGhlIERPTSBub2RlLiBUaGlzIG1ldGhvZCBpcyB1bmlxdWUgdG8gdGhlIFRleHQgc2VyaWFsaXplci4KLSAgICAgKgotICAgICAqIEBwYXJhbSBub2RlIFRoZSBub2RlIHRvIHNlcmlhbGl6ZQotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIHNlcmlhbGl6ZU5vZGUoIE5vZGUgbm9kZSApCi0gICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgLy8gQmFzZWQgb24gdGhlIG5vZGUgdHlwZSBjYWxsIHRoZSBzdWl0YWJsZSBTQVggaGFuZGxlci4KLSAgICAgICAgLy8gT25seSBjb21tZW50cyBlbnRpdGllcyBhbmQgZG9jdW1lbnRzIHdoaWNoIGFyZSBub3QKLSAgICAgICAgLy8gaGFuZGxlZCBieSBTQVggYXJlIHNlcmlhbGl6ZWQgZGlyZWN0bHkuCi0gICAgICAgIHN3aXRjaCAoIG5vZGUuZ2V0Tm9kZVR5cGUoKSApIHsKLSAgICAgICAgY2FzZSBOb2RlLlRFWFRfTk9ERSA6IHsKLSAgICAgICAgICAgIFN0cmluZyB0ZXh0OwotCi0gICAgICAgICAgICB0ZXh0ID0gbm9kZS5nZXROb2RlVmFsdWUoKTsKLSAgICAgICAgICAgIGlmICggdGV4dCAhPSBudWxsICkKLSAgICAgICAgICAgICAgICBjaGFyYWN0ZXJzKCBub2RlLmdldE5vZGVWYWx1ZSgpLCB0cnVlICk7Ci0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgfQotCi0gICAgICAgIGNhc2UgTm9kZS5DREFUQV9TRUNUSU9OX05PREUgOiB7Ci0gICAgICAgICAgICBTdHJpbmcgdGV4dDsKLQotICAgICAgICAgICAgdGV4dCA9IG5vZGUuZ2V0Tm9kZVZhbHVlKCk7Ci0gICAgICAgICAgICBpZiAoIHRleHQgIT0gbnVsbCApCi0gICAgICAgICAgICAgICAgY2hhcmFjdGVycyggbm9kZS5nZXROb2RlVmFsdWUoKSwgdHJ1ZSApOwotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIH0KLQotICAgICAgICBjYXNlIE5vZGUuQ09NTUVOVF9OT0RFIDoKLSAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgIGNhc2UgTm9kZS5FTlRJVFlfUkVGRVJFTkNFX05PREUgOgotICAgICAgICAgICAgLy8gSWdub3JlLgotICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgY2FzZSBOb2RlLlBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERSA6Ci0gICAgICAgICAgICBicmVhazsKLQotICAgICAgICBjYXNlIE5vZGUuRUxFTUVOVF9OT0RFIDoKLSAgICAgICAgICAgIHNlcmlhbGl6ZUVsZW1lbnQoIChFbGVtZW50KSBub2RlICk7Ci0gICAgICAgICAgICBicmVhazsKLQotICAgICAgICBjYXNlIE5vZGUuRE9DVU1FTlRfTk9ERSA6Ci0gICAgICAgICAgICAvLyAhISEgRmFsbCB0aHJvdWdoCi0gICAgICAgIGNhc2UgTm9kZS5ET0NVTUVOVF9GUkFHTUVOVF9OT0RFIDogewotICAgICAgICAgICAgTm9kZSAgICAgICAgIGNoaWxkOwotCi0gICAgICAgICAgICAvLyBCeSBkZWZpbml0aW9uIHRoaXMgd2lsbCBoYXBwZW4gaWYgdGhlIG5vZGUgaXMgYSBkb2N1bWVudCwKLSAgICAgICAgICAgIC8vIGRvY3VtZW50IGZyYWdtZW50LCBldGMuIEp1c3Qgc2VyaWFsaXplIGl0cyBjb250ZW50cy4gSXQgd2lsbAotICAgICAgICAgICAgLy8gd29yayB3ZWxsIGZvciBvdGhlciBub2RlcyB0aGF0IHdlIGRvIG5vdCBrbm93IGhvdyB0byBzZXJpYWxpemUuCi0gICAgICAgICAgICBjaGlsZCA9IG5vZGUuZ2V0Rmlyc3RDaGlsZCgpOwotICAgICAgICAgICAgd2hpbGUgKCBjaGlsZCAhPSBudWxsICkgewotICAgICAgICAgICAgICAgIHNlcmlhbGl6ZU5vZGUoIGNoaWxkICk7Ci0gICAgICAgICAgICAgICAgY2hpbGQgPSBjaGlsZC5nZXROZXh0U2libGluZygpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIH0KLQotICAgICAgICBkZWZhdWx0OgotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIHByb3RlY3RlZCBFbGVtZW50U3RhdGUgY29udGVudCgpCi0gICAgewotICAgICAgICBFbGVtZW50U3RhdGUgc3RhdGU7Ci0KLSAgICAgICAgc3RhdGUgPSBnZXRFbGVtZW50U3RhdGUoKTsKLSAgICAgICAgaWYgKCAhIGlzRG9jdW1lbnRTdGF0ZSgpICkgewotICAgICAgICAgICAgLy8gSWYgdGhpcyBpcyB0aGUgZmlyc3QgY29udGVudCBpbiB0aGUgZWxlbWVudCwKLSAgICAgICAgICAgIC8vIGNoYW5nZSB0aGUgc3RhdGUgdG8gbm90LWVtcHR5LgotICAgICAgICAgICAgaWYgKCBzdGF0ZS5lbXB0eSApCi0gICAgICAgICAgICAgICAgc3RhdGUuZW1wdHkgPSBmYWxzZTsKLSAgICAgICAgICAgIC8vIEV4Y2VwdCBmb3Igb25lIGNvbnRlbnQgdHlwZSwgYWxsIG9mIHRoZW0KLSAgICAgICAgICAgIC8vIGFyZSBub3QgbGFzdCBlbGVtZW50LiBUaGF0IG9uZSBjb250ZW50Ci0gICAgICAgICAgICAvLyB0eXBlIHdpbGwgdGFrZSBjYXJlIG9mIGl0c2VsZi4KLSAgICAgICAgICAgIHN0YXRlLmFmdGVyRWxlbWVudCA9IGZhbHNlOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBzdGF0ZTsKLSAgICB9Ci0KLQotICAgIHByb3RlY3RlZCBTdHJpbmcgZ2V0RW50aXR5UmVmKCBpbnQgY2ggKQotICAgIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZS9YSFRNTFNlcmlhbGl6ZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZS9YSFRNTFNlcmlhbGl6ZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNTkyNWEyNS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemUvWEhUTUxTZXJpYWxpemVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMDQgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplOwotCi0KLWltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKLWltcG9ydCBqYXZhLmlvLldyaXRlcjsKLQotCi0vKioKLSAqIEltcGxlbWVudHMgYW4gWEhUTUwgc2VyaWFsaXplciBzdXBwb3J0aW5nIGJvdGggRE9NIGFuZCBTQVgKLSAqIHByZXR0eSBzZXJpYWxpemluZy4gRm9yIHVzYWdlIGluc3RydWN0aW9ucyBzZWUgZWl0aGVyIHtAbGluawotICogU2VyaWFsaXplcn0gb3Ige0BsaW5rIEJhc2VNYXJrdXBTZXJpYWxpemVyfS4KLSAqCi0gKiBAZGVwcmVjYXRlZCBUaGlzIGNsYXNzIHdhcyBkZXByZWNhdGVkIGluIFhlcmNlcyAyLjYuMi4gSXQgaXMKLSAqIHJlY29tbWVuZGVkIHRoYXQgbmV3IGFwcGxpY2F0aW9ucyB1c2UgSkFYUCdzIFRyYW5zZm9ybWF0aW9uIEFQSQotICogZm9yIFhNTCAoVHJBWCkgZm9yIHNlcmlhbGl6aW5nIFhIVE1MLiBTZWUgdGhlIFhlcmNlcyBkb2N1bWVudGF0aW9uCi0gKiBmb3IgbW9yZSBpbmZvcm1hdGlvbi4KLSAqIEBhdXRob3IgPGEgaHJlZj0ibWFpbHRvOmFya2luQGludGFsaW8uY29tIj5Bc3NhZiBBcmtpbjwvYT4KLSAqIEBzZWUgU2VyaWFsaXplcgotICovCi1wdWJsaWMgY2xhc3MgWEhUTUxTZXJpYWxpemVyCi0gICAgZXh0ZW5kcyBIVE1MU2VyaWFsaXplcgotewotCi0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHNlcmlhbGl6ZXIuIFRoZSBzZXJpYWxpemVyIGNhbm5vdCBiZSB1c2VkIHdpdGhvdXQKLSAgICAgKiBjYWxsaW5nIHtAbGluayAjc2V0T3V0cHV0Q2hhclN0cmVhbX0gb3Ige0BsaW5rICNzZXRPdXRwdXRCeXRlU3RyZWFtfQotICAgICAqIGZpcnN0LgotICAgICAqLwotICAgIHB1YmxpYyBYSFRNTFNlcmlhbGl6ZXIoKQotICAgIHsKLSAgICAgICAgc3VwZXIoIHRydWUsIG5ldyBPdXRwdXRGb3JtYXQoIE1ldGhvZC5YSFRNTCwgbnVsbCwgZmFsc2UgKSApOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0cyBhIG5ldyBzZXJpYWxpemVyLiBUaGUgc2VyaWFsaXplciBjYW5ub3QgYmUgdXNlZCB3aXRob3V0Ci0gICAgICogY2FsbGluZyB7QGxpbmsgI3NldE91dHB1dENoYXJTdHJlYW19IG9yIHtAbGluayAjc2V0T3V0cHV0Qnl0ZVN0cmVhbX0KLSAgICAgKiBmaXJzdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgWEhUTUxTZXJpYWxpemVyKCBPdXRwdXRGb3JtYXQgZm9ybWF0ICkKLSAgICB7Ci0gICAgICAgIHN1cGVyKCB0cnVlLCBmb3JtYXQgIT0gbnVsbCA/IGZvcm1hdCA6IG5ldyBPdXRwdXRGb3JtYXQoIE1ldGhvZC5YSFRNTCwgbnVsbCwgZmFsc2UgKSApOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0cyBhIG5ldyBzZXJpYWxpemVyIHRoYXQgd3JpdGVzIHRvIHRoZSBzcGVjaWZpZWQgd3JpdGVyCi0gICAgICogdXNpbmcgdGhlIHNwZWNpZmllZCBvdXRwdXQgZm9ybWF0LiBJZiA8dHQ+Zm9ybWF0PC90dD4gaXMgbnVsbCwKLSAgICAgKiB3aWxsIHVzZSBhIGRlZmF1bHQgb3V0cHV0IGZvcm1hdC4KLSAgICAgKgotICAgICAqIEBwYXJhbSB3cml0ZXIgVGhlIHdyaXRlciB0byB1c2UKLSAgICAgKiBAcGFyYW0gZm9ybWF0IFRoZSBvdXRwdXQgZm9ybWF0IHRvIHVzZSwgbnVsbCBmb3IgdGhlIGRlZmF1bHQKLSAgICAgKi8KLSAgICBwdWJsaWMgWEhUTUxTZXJpYWxpemVyKCBXcml0ZXIgd3JpdGVyLCBPdXRwdXRGb3JtYXQgZm9ybWF0ICkKLSAgICB7Ci0gICAgICAgIHN1cGVyKCB0cnVlLCBmb3JtYXQgIT0gbnVsbCA/IGZvcm1hdCA6IG5ldyBPdXRwdXRGb3JtYXQoIE1ldGhvZC5YSFRNTCwgbnVsbCwgZmFsc2UgKSApOwotICAgICAgICBzZXRPdXRwdXRDaGFyU3RyZWFtKCB3cml0ZXIgKTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHMgYSBuZXcgc2VyaWFsaXplciB0aGF0IHdyaXRlcyB0byB0aGUgc3BlY2lmaWVkIG91dHB1dAotICAgICAqIHN0cmVhbSB1c2luZyB0aGUgc3BlY2lmaWVkIG91dHB1dCBmb3JtYXQuIElmIDx0dD5mb3JtYXQ8L3R0PgotICAgICAqIGlzIG51bGwsIHdpbGwgdXNlIGEgZGVmYXVsdCBvdXRwdXQgZm9ybWF0LgotICAgICAqCi0gICAgICogQHBhcmFtIG91dHB1dCBUaGUgb3V0cHV0IHN0cmVhbSB0byB1c2UKLSAgICAgKiBAcGFyYW0gZm9ybWF0IFRoZSBvdXRwdXQgZm9ybWF0IHRvIHVzZSwgbnVsbCBmb3IgdGhlIGRlZmF1bHQKLSAgICAgKi8KLSAgICBwdWJsaWMgWEhUTUxTZXJpYWxpemVyKCBPdXRwdXRTdHJlYW0gb3V0cHV0LCBPdXRwdXRGb3JtYXQgZm9ybWF0ICkKLSAgICB7Ci0gICAgICAgIHN1cGVyKCB0cnVlLCBmb3JtYXQgIT0gbnVsbCA/IGZvcm1hdCA6IG5ldyBPdXRwdXRGb3JtYXQoIE1ldGhvZC5YSFRNTCwgbnVsbCwgZmFsc2UgKSApOwotICAgICAgICBzZXRPdXRwdXRCeXRlU3RyZWFtKCBvdXRwdXQgKTsKLSAgICB9Ci0KLQotICAgIHB1YmxpYyB2b2lkIHNldE91dHB1dEZvcm1hdCggT3V0cHV0Rm9ybWF0IGZvcm1hdCApCi0gICAgewotICAgICAgICBzdXBlci5zZXRPdXRwdXRGb3JtYXQoIGZvcm1hdCAhPSBudWxsID8gZm9ybWF0IDogbmV3IE91dHB1dEZvcm1hdCggTWV0aG9kLlhIVE1MLCBudWxsLCBmYWxzZSApICk7Ci0gICAgfQotCi0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZS9YTUwxMVNlcmlhbGl6ZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZS9YTUwxMVNlcmlhbGl6ZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZTE3MjhjZC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemUvWE1MMTFTZXJpYWxpemVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw1MzcgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDAyLDIwMDQsMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLQotCi0vLyBTZXAgMTQsIDIwMDA6Ci0vLyAgRml4ZWQgcHJvYmxlbSB3aXRoIG5hbWVzcGFjZSBoYW5kbGluZy4gQ29udHJpYnV0ZWQgYnkKLS8vICBEYXZpZCBCbG9uZGVhdSA8YmxvbmRlYXVAaW50YWxpby5jb20+Ci0vLyBTZXAgMTQsIDIwMDA6Ci0vLyAgRml4ZWQgc2VyaWFsaXplciB0byByZXBvcnQgSU8gZXhjZXB0aW9uIGRpcmVjdGx5LCBpbnN0ZWFkIGF0Ci0vLyAgdGhlIGVuZCBvZiBkb2N1bWVudCBwcm9jZXNzaW5nLgotLy8gIFJlcG9ydGVkIGJ5IFBhdHJpY2sgSGlnZ2lucyA8cGhpZ2dpbnNAdHJhbnN6YXAuY29tPgotLy8gQXVnIDIxLCAyMDAwOgotLy8gIEZpeGVkIGJ1ZyBpbiBzdGFydERvY3VtZW50IG5vdCBjYWxsaW5nIHByZXBhcmUuCi0vLyAgUmVwb3J0ZWQgYnkgTWlrYWVsIFN0YWxkYWwgPGQ5Ni1tc3QtaW5nZW4tcmVrbGFtQGQua3RoLnNlPgotLy8gQXVnIDIxLCAyMDAwOgotLy8gIEFkZGVkIGFiaWxpdHkgdG8gb21pdCBET0NUWVBFIGRlY2xhcmF0aW9uLgotCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemU7Ci0KLQotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci1pbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5pby5Xcml0ZXI7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbS5ET01NZXNzYWdlRm9ybWF0dGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5Db25zdGFudHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLk5hbWVzcGFjZVN1cHBvcnQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlN5bWJvbFRhYmxlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5YTUwxMUNoYXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlhNTENoYXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotaW1wb3J0IG9yZy53M2MuZG9tLkRPTUVycm9yOwotCi0vKioKLSAqIEltcGxlbWVudHMgYW4gWE1MIHNlcmlhbGl6ZXIgc3VwcG9ydGluZyBib3RoIERPTSBhbmQgU0FYIHByZXR0eQotICogc2VyaWFsaXppbmcuIEZvciB1c2FnZSBpbnN0cnVjdGlvbnMgc2VlIHtAbGluayBTZXJpYWxpemVyfS4KLSAqIDxwPgotICogSWYgYW4gb3V0cHV0IHN0cmVhbSBpcyB1c2VkLCB0aGUgZW5jb2RpbmcgaXMgdGFrZW4gZnJvbSB0aGUKLSAqIG91dHB1dCBmb3JtYXQgKGRlZmF1bHRzIHRvIDx0dD5VVEYtODwvdHQ+KS4gSWYgYSB3cml0ZXIgaXMKLSAqIHVzZWQsIG1ha2Ugc3VyZSB0aGUgd3JpdGVyIHVzZXMgdGhlIHNhbWUgZW5jb2RpbmcgKGlmIGFwcGxpZXMpCi0gKiBhcyBzcGVjaWZpZWQgaW4gdGhlIG91dHB1dCBmb3JtYXQuCi0gKiA8cD4KLSAqIFRoZSBzZXJpYWxpemVyIHN1cHBvcnRzIGJvdGggRE9NIGFuZCBTQVguIFNBWCBzZXJpYWxpemluZyBpcyBkb25lIGJ5IGZpcmluZwotICogU0FYIGV2ZW50cyBhbmQgdXNpbmcgdGhlIHNlcmlhbGl6ZXIgYXMgYSBkb2N1bWVudCBoYW5kbGVyLiBET00gc2VyaWFsaXppbmcgaXMgZG9uZQotICogYnkgY2FsbGluZyB7QGxpbmsgI3NlcmlhbGl6ZShEb2N1bWVudCl9IG9yIGJ5IHVzaW5nIERPTSBMZXZlbCAzCi0gKiB7QGxpbmsgb3JnLnczYy5kb20ubHMuRE9NU2VyaWFsaXplcn0gYW5kCi0gKiBzZXJpYWxpemluZyB3aXRoIHtAbGluayBvcmcudzNjLmRvbS5scy5ET01TZXJpYWxpemVyI3dyaXRlfSwKLSAqIHtAbGluayBvcmcudzNjLmRvbS5scy5ET01TZXJpYWxpemVyI3dyaXRlVG9TdHJpbmd9LgotICogPHA+Ci0gKiBJZiBhbiBJL08gZXhjZXB0aW9uIG9jY3VycyB3aGlsZSBzZXJpYWxpemluZywgdGhlIHNlcmlhbGl6ZXIKLSAqIHdpbGwgbm90IHRocm93IGFuIGV4Y2VwdGlvbiBkaXJlY3RseSwgYnV0IG9ubHkgdGhyb3cgaXQKLSAqIGF0IHRoZSBlbmQgb2Ygc2VyaWFsaXppbmcgKGVpdGhlciBET00gb3IgU0FYJ3Mge0BsaW5rCi0gKiBvcmcueG1sLnNheC5Eb2N1bWVudEhhbmRsZXIjZW5kRG9jdW1lbnR9LgotICogPHA+Ci0gKiBGb3IgZWxlbWVudHMgdGhhdCBhcmUgbm90IHNwZWNpZmllZCBhcyB3aGl0ZXNwYWNlIHByZXNlcnZpbmcsCi0gKiB0aGUgc2VyaWFsaXplciB3aWxsIHBvdGVudGlhbGx5IGJyZWFrIGxvbmcgdGV4dCBsaW5lcyBhdCBzcGFjZQotICogYm91bmRhcmllcywgaW5kZW50IGxpbmVzLCBhbmQgc2VyaWFsaXplIGVsZW1lbnRzIG9uIHNlcGFyYXRlCi0gKiBsaW5lcy4gTGluZSB0ZXJtaW5hdG9ycyB3aWxsIGJlIHJlZ2FyZGVkIGFzIHNwYWNlcywgYW5kCi0gKiBzcGFjZXMgYXQgYmVnaW5uaW5nIG9mIGxpbmUgd2lsbCBiZSBzdHJpcHBlZC4KLSAqIEBhdXRob3IgPGEgaHJlZj0ibWFpbHRvOmFya2luQGludGFsaW8uY29tIj5Bc3NhZiBBcmtpbjwvYT4KLSAqIEBhdXRob3IgPGEgaHJlZj0ibWFpbHRvOnJhaHVsLnNyaXZhc3RhdmFAc3VuLmNvbSI+UmFodWwgU3JpdmFzdGF2YTwvYT4KLSAqIEBhdXRob3IgRWxlbmEgTGl0YW5pIElCTQotICogQHNlZSBTZXJpYWxpemVyCi0gKi8KLXB1YmxpYyBjbGFzcyBYTUwxMVNlcmlhbGl6ZXIKLWV4dGVuZHMgWE1MU2VyaWFsaXplciB7Ci0KLSAgICAvLwotICAgIC8vIGNvbnN0YW50cwotICAgIC8vCi0KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGJvb2xlYW4gREVCVUcgPSBmYWxzZTsKLQotICAgIC8vCi0gICAgLy8gZGF0YQotICAgIC8vCi0KLSAgICAvLwotICAgIC8vIERPTSBMZXZlbCAzIGltcGxlbWVudGF0aW9uOiB2YXJpYWJsZXMgaW50aWFsaXplZCBpbiBET01TZXJpYWxpemVySW1wbAotICAgIC8vCi0KLSAgICAvKiogc3RvcmVzIG5hbWVzcGFjZXMgaW4gc2NvcGUgKi8KLSAgICBwcm90ZWN0ZWQgTmFtZXNwYWNlU3VwcG9ydCBmTlNCaW5kZXI7Ci0KLSAgICAvKiogc3RvcmVzIGFsbCBuYW1lc3BhY2UgYmluZGluZ3Mgb24gdGhlIGN1cnJlbnQgZWxlbWVudCAqLwotICAgIHByb3RlY3RlZCBOYW1lc3BhY2VTdXBwb3J0IGZMb2NhbE5TQmluZGVyOwotCi0gICAgLyoqIHN5bWJvbCB0YWJsZSBmb3Igc2VyaWFsaXphdGlvbiAqLwotICAgIHByb3RlY3RlZCBTeW1ib2xUYWJsZSBmU3ltYm9sVGFibGU7Ci0KLSAgICAvLyBpcyBub2RlIGRvbSBsZXZlbCAxIG5vZGU/Ci0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZkRPTUwxID0gZmFsc2U7Ci0gICAgLy8gY291bnRlciBmb3IgbmV3IHByZWZpeCBuYW1lcwotICAgIHByb3RlY3RlZCBpbnQgZk5hbWVzcGFjZUNvdW50ZXIgPSAxOwotICAgIHByb3RlY3RlZCBmaW5hbCBzdGF0aWMgU3RyaW5nIFBSRUZJWCA9ICJOUyI7Ci0KLSAgICAvKioKLSAgICAgKiBDb250cm9scyB3aGV0aGVyIG5hbWVzcGFjZSBmaXh1cCBzaG91bGQgYmUgcGVyZm9ybWVkIGR1cmluZwotICAgICAqIHRoZSBzZXJpYWxpemF0aW9uLgotICAgICAqIE5PVEU6IGlmIHRoaXMgZmllbGQgaXMgc2V0IHRvIHRydWUgdGhlIGZvbGxvd2luZwotICAgICAqIGZpZWxkcyBuZWVkIHRvIGJlIGluaXRpYWxpemVkOiBmTlNCaW5kZXIsIGZMb2NhbE5TQmluZGVyLCBmU3ltYm9sVGFibGUsCi0gICAgICogWE1MU3ltYm9scy5FTVBUWV9TVFJJTkcsIGZYbWxTeW1ib2wsIGZYbWxuc1N5bWJvbCwgZk5hbWVzcGFjZUNvdW50ZXIuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZk5hbWVzcGFjZXMgPSBmYWxzZTsKLQotCi0gICAgcHJpdmF0ZSBib29sZWFuIGZQcmVzZXJ2ZVNwYWNlOwotCi0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHNlcmlhbGl6ZXIuIFRoZSBzZXJpYWxpemVyIGNhbm5vdCBiZSB1c2VkIHdpdGhvdXQKLSAgICAgKiBjYWxsaW5nIHtAbGluayAjc2V0T3V0cHV0Q2hhclN0cmVhbX0gb3Ige0BsaW5rICNzZXRPdXRwdXRCeXRlU3RyZWFtfQotICAgICAqIGZpcnN0LgotICAgICAqLwotICAgIHB1YmxpYyBYTUwxMVNlcmlhbGl6ZXIoKSB7Ci0gICAgICAgIHN1cGVyKCApOwotICAgICAgICBfZm9ybWF0LnNldFZlcnNpb24oIjEuMSIpOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0cyBhIG5ldyBzZXJpYWxpemVyLiBUaGUgc2VyaWFsaXplciBjYW5ub3QgYmUgdXNlZCB3aXRob3V0Ci0gICAgICogY2FsbGluZyB7QGxpbmsgI3NldE91dHB1dENoYXJTdHJlYW19IG9yIHtAbGluayAjc2V0T3V0cHV0Qnl0ZVN0cmVhbX0KLSAgICAgKiBmaXJzdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgWE1MMTFTZXJpYWxpemVyKCBPdXRwdXRGb3JtYXQgZm9ybWF0ICkgewotICAgICAgICBzdXBlciggZm9ybWF0ICk7Ci0gICAgICAgIF9mb3JtYXQuc2V0VmVyc2lvbigiMS4xIik7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHNlcmlhbGl6ZXIgdGhhdCB3cml0ZXMgdG8gdGhlIHNwZWNpZmllZCB3cml0ZXIKLSAgICAgKiB1c2luZyB0aGUgc3BlY2lmaWVkIG91dHB1dCBmb3JtYXQuIElmIDx0dD5mb3JtYXQ8L3R0PiBpcyBudWxsLAotICAgICAqIHdpbGwgdXNlIGEgZGVmYXVsdCBvdXRwdXQgZm9ybWF0LgotICAgICAqCi0gICAgICogQHBhcmFtIHdyaXRlciBUaGUgd3JpdGVyIHRvIHVzZQotICAgICAqIEBwYXJhbSBmb3JtYXQgVGhlIG91dHB1dCBmb3JtYXQgdG8gdXNlLCBudWxsIGZvciB0aGUgZGVmYXVsdAotICAgICAqLwotICAgIHB1YmxpYyBYTUwxMVNlcmlhbGl6ZXIoIFdyaXRlciB3cml0ZXIsIE91dHB1dEZvcm1hdCBmb3JtYXQgKSB7Ci0gICAgICAgIHN1cGVyKCB3cml0ZXIsIGZvcm1hdCApOwotICAgICAgICBfZm9ybWF0LnNldFZlcnNpb24oIjEuMSIpOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0cyBhIG5ldyBzZXJpYWxpemVyIHRoYXQgd3JpdGVzIHRvIHRoZSBzcGVjaWZpZWQgb3V0cHV0Ci0gICAgICogc3RyZWFtIHVzaW5nIHRoZSBzcGVjaWZpZWQgb3V0cHV0IGZvcm1hdC4gSWYgPHR0PmZvcm1hdDwvdHQ+Ci0gICAgICogaXMgbnVsbCwgd2lsbCB1c2UgYSBkZWZhdWx0IG91dHB1dCBmb3JtYXQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gb3V0cHV0IFRoZSBvdXRwdXQgc3RyZWFtIHRvIHVzZQotICAgICAqIEBwYXJhbSBmb3JtYXQgVGhlIG91dHB1dCBmb3JtYXQgdG8gdXNlLCBudWxsIGZvciB0aGUgZGVmYXVsdAotICAgICAqLwotICAgIHB1YmxpYyBYTUwxMVNlcmlhbGl6ZXIoIE91dHB1dFN0cmVhbSBvdXRwdXQsIE91dHB1dEZvcm1hdCBmb3JtYXQgKSB7Ci0gICAgICAgIHN1cGVyKCBvdXRwdXQsIGZvcm1hdCAhPSBudWxsID8gZm9ybWF0IDogbmV3IE91dHB1dEZvcm1hdCggTWV0aG9kLlhNTCwgbnVsbCwgZmFsc2UgKSApOwotICAgICAgICBfZm9ybWF0LnNldFZlcnNpb24oIjEuMSIpOwotICAgIH0KLQotICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0vLwotICAgIC8vIFNBWCBjb250ZW50IGhhbmRsZXIgc2VyaWFsaXppbmcgbWV0aG9kcyAvLwotICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0vLwotCi0KLSAgICBwdWJsaWMgdm9pZCBjaGFyYWN0ZXJzKCBjaGFyW10gY2hhcnMsIGludCBzdGFydCwgaW50IGxlbmd0aCApCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIEVsZW1lbnRTdGF0ZSBzdGF0ZTsKLQotICAgICAgICB0cnkgewotICAgICAgICAgICAgc3RhdGUgPSBjb250ZW50KCk7Ci0KLSAgICAgICAgICAgIC8vIENoZWNrIGlmIHRleHQgc2hvdWxkIGJlIHByaW50IGFzIENEQVRBIHNlY3Rpb24gb3IgdW5lc2NhcGVkCi0gICAgICAgICAgICAvLyBiYXNlZCBvbiBlbGVtZW50cyBsaXN0ZWQgaW4gdGhlIG91dHB1dCBmb3JtYXQgKHRoZSBlbGVtZW50Ci0gICAgICAgICAgICAvLyBzdGF0ZSkgb3Igd2hldGhlciB3ZSBhcmUgaW5zaWRlIGEgQ0RBVEEgc2VjdGlvbiBvciBlbnRpdHkuCi0KLSAgICAgICAgICAgIGlmICggc3RhdGUuaW5DRGF0YSB8fCBzdGF0ZS5kb0NEYXRhICkgewotICAgICAgICAgICAgICAgIGludCAgICAgICAgICBzYXZlSW5kZW50OwotCi0gICAgICAgICAgICAgICAgLy8gUHJpbnQgYSBDREFUQSBzZWN0aW9uLiBUaGUgdGV4dCBpcyBub3QgZXNjYXBlZCwgYnV0ICddXT4nCi0gICAgICAgICAgICAgICAgLy8gYXBwZWFyaW5nIGluIHRoZSBjb2RlIG11c3QgYmUgaWRlbnRpZmllZCBhbmQgZGVhbHQgd2l0aC4KLSAgICAgICAgICAgICAgICAvLyBUaGUgY29udGVudHMgb2YgYSB0ZXh0IG5vZGUgaXMgY29uc2lkZXJlZCBzcGFjZSBwcmVzZXJ2aW5nLgotICAgICAgICAgICAgICAgIGlmICggISBzdGF0ZS5pbkNEYXRhICkgewotICAgICAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoICI8IVtDREFUQVsiICk7Ci0gICAgICAgICAgICAgICAgICAgIHN0YXRlLmluQ0RhdGEgPSB0cnVlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBzYXZlSW5kZW50ID0gX3ByaW50ZXIuZ2V0TmV4dEluZGVudCgpOwotICAgICAgICAgICAgICAgIF9wcmludGVyLnNldE5leHRJbmRlbnQoIDAgKTsKLSAgICAgICAgICAgICAgICBjaGFyIGNoOwotICAgICAgICAgICAgICAgIGZpbmFsIGludCBlbmQgPSBzdGFydCArIGxlbmd0aDsKLSAgICAgICAgICAgICAgICBmb3IgKCBpbnQgaW5kZXggPSBzdGFydDsgaW5kZXggPCBlbmQ7ICsraW5kZXggKSB7Ci0gICAgICAgICAgICAgICAgICAgIGNoID0gY2hhcnNbaW5kZXhdOwotICAgICAgICAgICAgICAgICAgICBpZiAoIGNoID09ICddJyAmJiBpbmRleCArIDIgPCBlbmQgJiYKLSAgICAgICAgICAgICAgICAgICAgICAgIGNoYXJzWyBpbmRleCArIDEgXSA9PSAnXScgJiYgY2hhcnNbIGluZGV4ICsgMiBdID09ICc+JyApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCgiXV1dXT48IVtDREFUQVs+Iik7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpbmRleCArPTI7Ci0gICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBpZiAoIVhNTDExQ2hhci5pc1hNTDExVmFsaWQoY2gpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBjaGVjayBpZiBpdCBpcyBzdXJyb2dhdGUKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmICgrK2luZGV4IDwgZW5kKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Vycm9nYXRlcyhjaCwgY2hhcnNbaW5kZXhdKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhdGFsRXJyb3IoIlRoZSBjaGFyYWN0ZXIgJyIrKGNoYXIpY2grIicgaXMgYW4gaW52YWxpZCBYTUwgY2hhcmFjdGVyIik7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmICggX2VuY29kaW5nSW5mby5pc1ByaW50YWJsZSgoY2hhciljaCkgJiYgWE1MMTFDaGFyLmlzWE1MMTFWYWxpZExpdGVyYWwoY2gpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KChjaGFyKWNoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhlIGNoYXJhY3RlciBpcyBub3QgcHJpbnRhYmxlIC0tIHNwbGl0IENEQVRBIHNlY3Rpb24KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoIl1dPiYjeCIpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dChJbnRlZ2VyLnRvSGV4U3RyaW5nKGNoKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCI7PCFbQ0RBVEFbIik7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgX3ByaW50ZXIuc2V0TmV4dEluZGVudCggc2F2ZUluZGVudCApOwotCi0gICAgICAgICAgICB9IGVsc2UgewotCi0gICAgICAgICAgICAgICAgaW50IHNhdmVJbmRlbnQ7Ci0KLSAgICAgICAgICAgICAgICBpZiAoIHN0YXRlLnByZXNlcnZlU3BhY2UgKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIElmIHByZXNlcnZpbmcgc3BhY2UgdGhlbiBob2xkIG9mIGluZGVudGF0aW9uIHNvIG5vCi0gICAgICAgICAgICAgICAgICAgIC8vIGV4Y2Vzc2l2ZSBzcGFjZXMgYXJlIHByaW50ZWQgYXQgbGluZSBicmVha3MsIGVzY2FwZQotICAgICAgICAgICAgICAgICAgICAvLyB0aGUgdGV4dCBjb250ZW50IHdpdGhvdXQgcmVwbGFjaW5nIHNwYWNlcyBhbmQgcHJpbnQKLSAgICAgICAgICAgICAgICAgICAgLy8gdGhlIHRleHQgYnJlYWtpbmcgb25seSBhdCBsaW5lIGJyZWFrcy4KLSAgICAgICAgICAgICAgICAgICAgc2F2ZUluZGVudCA9IF9wcmludGVyLmdldE5leHRJbmRlbnQoKTsKLSAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIuc2V0TmV4dEluZGVudCggMCApOwotICAgICAgICAgICAgICAgICAgICBwcmludFRleHQoIGNoYXJzLCBzdGFydCwgbGVuZ3RoLCB0cnVlLCBzdGF0ZS51bmVzY2FwZWQgKTsKLSAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIuc2V0TmV4dEluZGVudCggc2F2ZUluZGVudCApOwotICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIHByaW50VGV4dCggY2hhcnMsIHN0YXJ0LCBsZW5ndGgsIGZhbHNlLCBzdGF0ZS51bmVzY2FwZWQgKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gY2F0Y2ggKCBJT0V4Y2VwdGlvbiBleGNlcHQgKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKCBleGNlcHQgKTsKLSAgICAgICAgfQotICAgIH0KLQotCi0gICAgLy8KLSAgICAvLyBvdmVyd3JpdGUgcHJpbnRpbmcgZnVuY3Rpb25zIHRvIG1ha2Ugc3VyZSBzZXJpYWxpemVyIHByaW50cyBvdXQgdmFsaWQgWE1MCi0gICAgLy8KLSAgICBwcm90ZWN0ZWQgdm9pZCBwcmludEVzY2FwZWQoIFN0cmluZyBzb3VyY2UgKSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgICAgICBpbnQgbGVuZ3RoID0gc291cmNlLmxlbmd0aCgpOwotICAgICAgICBmb3IgKCBpbnQgaSA9IDAgOyBpIDwgbGVuZ3RoIDsgKytpICkgewotICAgICAgICAgICAgaW50IGNoID0gc291cmNlLmNoYXJBdChpKTsKLSAgICAgICAgICAgIGlmICghWE1MMTFDaGFyLmlzWE1MMTFWYWxpZChjaCkpIHsKLSAgICAgICAgICAgICAgICBpZiAoKytpIDxsZW5ndGgpIHsKLSAgICAgICAgICAgICAgICAgICAgc3Vycm9nYXRlcyhjaCwgc291cmNlLmNoYXJBdChpKSk7Ci0gICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgZmF0YWxFcnJvcigiVGhlIGNoYXJhY3RlciAnIisoY2hhciljaCsiJyBpcyBhbiBpbnZhbGlkIFhNTCBjaGFyYWN0ZXIiKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoY2ggPT0gJ1xuJyB8fCBjaCA9PSAnXHInIHx8IGNoID09ICdcdCcgfHwgY2ggPT0gMHgwMDg1IHx8IGNoID09IDB4MjAyOCl7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaW50SGV4KGNoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoY2ggPT0gJzwnKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCgiJmx0OyIpOwotICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjaCA9PSAnJicpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCImYW1wOyIpOwotICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjaCA9PSAnIicpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCImcXVvdDsiKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoKGNoID49ICcgJyAmJiBfZW5jb2RpbmdJbmZvLmlzUHJpbnRhYmxlKChjaGFyKSBjaCkpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCgoY2hhcikgY2gpOwotICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnRIZXgoY2gpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHJvdGVjdGVkIGZpbmFsIHZvaWQgcHJpbnRDREFUQVRleHQoU3RyaW5nIHRleHQpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgIGludCBsZW5ndGggPSB0ZXh0Lmxlbmd0aCgpOwotICAgICAgICBjaGFyIGNoOwotCi0gICAgICAgIGZvciAoaW50IGluZGV4ID0gMDsgaW5kZXggPCBsZW5ndGg7ICsraW5kZXgpIHsKLSAgICAgICAgICAgIGNoID0gdGV4dC5jaGFyQXQoaW5kZXgpOwotCi0gICAgICAgICAgICBpZiAoY2ggPT0gJ10nCi0gICAgICAgICAgICAgICAgJiYgaW5kZXggKyAyIDwgbGVuZ3RoCi0gICAgICAgICAgICAgICAgJiYgdGV4dC5jaGFyQXQoaW5kZXggKyAxKSA9PSAnXScKLSAgICAgICAgICAgICAgICAmJiB0ZXh0LmNoYXJBdChpbmRleCArIDIpID09ICc+JykgeyAvLyBjaGVjayBmb3IgJ11dPicKLSAgICAgICAgICAgICAgICBpZiAoZkRPTUVycm9ySGFuZGxlciAhPSBudWxsKXsKLSAgICAgICAgICAgICAgICAgICAgLy8gUkVWSVNJVDogdGhpcyBtZWFucyB0aGF0IGlmIERPTSBFcnJvciBoYW5kbGVyIGlzIG5vdCByZWdpc3RlcmVkIHdlIGRvbid0IHJlcG9ydCBhbnkKLSAgICAgICAgICAgICAgICAgICAgLy8gZmF0YWwgZXJyb3JzIGFuZCBtaWdodCBzZXJpYWxpemUgbm90IHdlbGxmb3JtZWQgZG9jdW1lbnQKLSAgICAgICAgICAgICAgICBpZiAoKGZlYXR1cmVzICYgRE9NU2VyaWFsaXplckltcGwuU1BMSVRDREFUQSkgPT0gMAotICAgICAgICAgICAgICAgICAgICAmJiAoZmVhdHVyZXMgJiBET01TZXJpYWxpemVySW1wbC5XRUxMRk9STUVEKSA9PSAwKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIGlzc3VlIGZhdGFsIGVycm9yCi0gICAgICAgICAgICAgICAgICAgIFN0cmluZyBtc2cgPQotICAgICAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuU0VSSUFMSVpFUl9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIkVuZGluZ0NEQVRBIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsKTsKLSAgICAgICAgICAgICAgICAgICAgbW9kaWZ5RE9NRXJyb3IoCi0gICAgICAgICAgICAgICAgICAgICAgICBtc2csCi0gICAgICAgICAgICAgICAgICAgICAgICBET01FcnJvci5TRVZFUklUWV9GQVRBTF9FUlJPUiwKLSAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsIGZDdXJyZW50Tm9kZSk7Ci0gICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gY29udGludWVQcm9jZXNzID0KLSAgICAgICAgICAgICAgICAgICAgICAgIGZET01FcnJvckhhbmRsZXIuaGFuZGxlRXJyb3IoZkRPTUVycm9yKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKCFjb250aW51ZVByb2Nlc3MpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gaXNzdWUgd2FybmluZwotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbXNnID0KLSAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZSgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLlNFUklBTElaRVJfRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTcGxpdHRpbmdDREFUQSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgIG1vZGlmeURPTUVycm9yKAotICAgICAgICAgICAgICAgICAgICAgICAgbXNnLAotICAgICAgICAgICAgICAgICAgICAgICAgRE9NRXJyb3IuU0VWRVJJVFlfV0FSTklORywKLSAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsIGZDdXJyZW50Tm9kZSk7Ci0gICAgICAgICAgICAgICAgICAgIGZET01FcnJvckhhbmRsZXIuaGFuZGxlRXJyb3IoZkRPTUVycm9yKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIC8vIHNwbGl0IENEQVRBIHNlY3Rpb24KLSAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoIl1dXV0+PCFbQ0RBVEFbPiIpOwotICAgICAgICAgICAgICAgIGluZGV4ICs9IDI7Ci0gICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmICghWE1MMTFDaGFyLmlzWE1MMTFWYWxpZChjaCkpIHsKLSAgICAgICAgICAgICAgICAvLyBjaGVjayBpZiBpdCBpcyBzdXJyb2dhdGUKLSAgICAgICAgICAgICAgICBpZiAoKytpbmRleCA8IGxlbmd0aCkgewotICAgICAgICAgICAgICAgICAgICBzdXJyb2dhdGVzKGNoLCB0ZXh0LmNoYXJBdChpbmRleCkpOwotICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIGZhdGFsRXJyb3IoCi0gICAgICAgICAgICAgICAgICAgICAgICAiVGhlIGNoYXJhY3RlciAnIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgKGNoYXIpIGNoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiJyBpcyBhbiBpbnZhbGlkIFhNTCBjaGFyYWN0ZXIiKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIGlmIChfZW5jb2RpbmdJbmZvLmlzUHJpbnRhYmxlKChjaGFyKSBjaCkKLSAgICAgICAgICAgICAgICAgICAgJiYgWE1MMTFDaGFyLmlzWE1MMTFWYWxpZExpdGVyYWwoY2gpKSB7Ci0gICAgICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCgoY2hhcikgY2gpOwotICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0KLSAgICAgICAgICAgICAgICAgICAgLy8gVGhlIGNoYXJhY3RlciBpcyBub3QgcHJpbnRhYmxlIC0tIHNwbGl0IENEQVRBIHNlY3Rpb24KLSAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCJdXT4mI3giKTsKLSAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KEludGVnZXIudG9IZXhTdHJpbmcoY2gpKTsKLSAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCI7PCFbQ0RBVEFbIik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICAvLyBub3RlIHRoYXQgdGhpcyAiaW50IiBzaG91bGQsIGluIGFsbCBjYXNlcywgYmUgYSBjaGFyLgotICAgIC8vIFJFVklTSVQ6ICBtYWtlIGl0IGEgY2hhci4uLgotICAgIHByb3RlY3RlZCBmaW5hbCB2b2lkIHByaW50WE1MQ2hhciggaW50IGNoICkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLQotICAgICAgICBpZiAoY2ggPT0gJ1xyJyB8fCBjaCA9PSAweDAwODUgfHwgY2ggPT0gMHgyMDI4KSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBwcmludEhleChjaCk7Ci0gICAgICAgIH0gZWxzZSBpZiAoIGNoID09ICc8JykgewotICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCImbHQ7Iik7Ci0gICAgICAgIH0gZWxzZSBpZiAoY2ggPT0gJyYnKSB7Ci0gICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoIiZhbXA7Iik7Ci0gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjaCA9PSAnPicpewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2hhcmFjdGVyIHNlcXVlbmNlICJdXT4iIGNhbid0IGFwcGVhciBpbiBjb250ZW50LCB0aGVyZWZvcmUKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIHdlIHNob3VsZCBlc2NhcGUgJz4nCi0gICAgICAgICAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoIiZndDsiKTsKLSAgICAgICAgfSBlbHNlIGlmICggX2VuY29kaW5nSW5mby5pc1ByaW50YWJsZSgoY2hhciljaCkgJiYgWE1MMTFDaGFyLmlzWE1MMTFWYWxpZExpdGVyYWwoY2gpKSB7Ci0gICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoKGNoYXIpY2gpOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgIHByaW50SGV4KGNoKTsKLSAgICAgICAgfQotICAgIH0KLQotCi0KLSAgICBwcm90ZWN0ZWQgZmluYWwgdm9pZCBzdXJyb2dhdGVzKGludCBoaWdoLCBpbnQgbG93KSB0aHJvd3MgSU9FeGNlcHRpb257Ci0gICAgICAgIGlmIChYTUxDaGFyLmlzSGlnaFN1cnJvZ2F0ZShoaWdoKSkgewotICAgICAgICAgICAgaWYgKCFYTUxDaGFyLmlzTG93U3Vycm9nYXRlKGxvdykpIHsKLSAgICAgICAgICAgICAgICAvL0ludmFsaWQgWE1MCi0gICAgICAgICAgICAgICAgZmF0YWxFcnJvcigiVGhlIGNoYXJhY3RlciAnIisoY2hhcilsb3crIicgaXMgYW4gaW52YWxpZCBYTUwgY2hhcmFjdGVyIik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBpbnQgc3VwcGxlbWVudGFsID0gWE1MQ2hhci5zdXBwbGVtZW50YWwoKGNoYXIpaGlnaCwgKGNoYXIpbG93KTsKLSAgICAgICAgICAgICAgICBpZiAoIVhNTDExQ2hhci5pc1hNTDExVmFsaWQoc3VwcGxlbWVudGFsKSkgewotICAgICAgICAgICAgICAgICAgICAvL0ludmFsaWQgWE1MCi0gICAgICAgICAgICAgICAgICAgIGZhdGFsRXJyb3IoIlRoZSBjaGFyYWN0ZXIgJyIrKGNoYXIpc3VwcGxlbWVudGFsKyInIGlzIGFuIGludmFsaWQgWE1MIGNoYXJhY3RlciIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGNvbnRlbnQoKS5pbkNEYXRhICkgewotICAgICAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCJdXT4mI3giKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dChJbnRlZ2VyLnRvSGV4U3RyaW5nKHN1cHBsZW1lbnRhbCkpOwotICAgICAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCI7PCFbQ0RBVEFbIik7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmludEhleChzdXBwbGVtZW50YWwpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgZmF0YWxFcnJvcigiVGhlIGNoYXJhY3RlciAnIisoY2hhciloaWdoKyInIGlzIGFuIGludmFsaWQgWE1MIGNoYXJhY3RlciIpOwotICAgICAgICB9Ci0KLSAgICB9Ci0KLQotICAgIHByb3RlY3RlZCB2b2lkIHByaW50VGV4dCggU3RyaW5nIHRleHQsIGJvb2xlYW4gcHJlc2VydmVTcGFjZSwgYm9vbGVhbiB1bmVzY2FwZWQgKQotICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgIGludCBpbmRleDsKLSAgICAgICAgY2hhciBjaDsKLSAgICAgICAgaW50IGxlbmd0aCA9IHRleHQubGVuZ3RoKCk7Ci0gICAgICAgIGlmICggcHJlc2VydmVTcGFjZSApIHsKLSAgICAgICAgICAgIC8vIFByZXNlcnZpbmcgc3BhY2VzOiB0aGUgdGV4dCBtdXN0IHByaW50IGV4YWN0bHkgYXMgaXQgaXMsCi0gICAgICAgICAgICAvLyB3aXRob3V0IGJyZWFraW5nIHdoZW4gc3BhY2VzIGFwcGVhciBpbiB0aGUgdGV4dCBhbmQgd2l0aG91dAotICAgICAgICAgICAgLy8gY29uc29saWRhdGluZyBzcGFjZXMuIElmIGEgbGluZSB0ZXJtaW5hdG9yIGlzIHVzZWQsIGEgbGluZQotICAgICAgICAgICAgLy8gYnJlYWsgd2lsbCBvY2N1ci4KLSAgICAgICAgICAgIGZvciAoIGluZGV4ID0gMCA7IGluZGV4IDwgbGVuZ3RoIDsgKytpbmRleCApIHsKLSAgICAgICAgICAgICAgICBjaCA9IHRleHQuY2hhckF0KCBpbmRleCApOwotICAgICAgICAgICAgICAgIGlmICghWE1MMTFDaGFyLmlzWE1MMTFWYWxpZChjaCkpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gY2hlY2sgaWYgaXQgaXMgc3Vycm9nYXRlCi0gICAgICAgICAgICAgICAgICAgIGlmICgrK2luZGV4IDxsZW5ndGgpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHN1cnJvZ2F0ZXMoY2gsIHRleHQuY2hhckF0KGluZGV4KSk7Ci0gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmYXRhbEVycm9yKCJUaGUgY2hhcmFjdGVyICciKyhjaGFyKWNoKyInIGlzIGFuIGludmFsaWQgWE1MIGNoYXJhY3RlciIpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpZiAoIHVuZXNjYXBlZCAgJiYgWE1MMTFDaGFyLmlzWE1MMTFWYWxpZExpdGVyYWwoY2gpKSB7Ci0gICAgICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggY2ggKTsKLSAgICAgICAgICAgICAgICB9IGVsc2UKLSAgICAgICAgICAgICAgICAgICAgcHJpbnRYTUxDaGFyKCBjaCApOwotICAgICAgICAgICAgfQotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgLy8gTm90IHByZXNlcnZpbmcgc3BhY2VzOiBwcmludCBvbmUgcGFydCBhdCBhIHRpbWUsIGFuZAotICAgICAgICAgICAgLy8gdXNlIHNwYWNlcyBiZXR3ZWVuIHBhcnRzIHRvIGJyZWFrIHRoZW0gaW50byBkaWZmZXJlbnQKLSAgICAgICAgICAgIC8vIGxpbmVzLiBTcGFjZXMgYXQgYmVnaW5uaW5nIG9mIGxpbmUgd2lsbCBiZSBzdHJpcHBlZAotICAgICAgICAgICAgLy8gYnkgcHJpbnRpbmcgbWVjaGFuaXNtLiBMaW5lIHRlcm1pbmF0b3IgaXMgdHJlYXRlZAotICAgICAgICAgICAgLy8gbm8gZGlmZmVyZW50IHRoYW4gb3RoZXIgdGV4dCBwYXJ0LgotICAgICAgICAgICAgZm9yICggaW5kZXggPSAwIDsgaW5kZXggPCBsZW5ndGggOyArK2luZGV4ICkgewotICAgICAgICAgICAgICAgIGNoID0gdGV4dC5jaGFyQXQoIGluZGV4ICk7Ci0gICAgICAgICAgICAgICAgaWYgKCFYTUwxMUNoYXIuaXNYTUwxMVZhbGlkKGNoKSkgewotICAgICAgICAgICAgICAgICAgICAvLyBjaGVjayBpZiBpdCBpcyBzdXJyb2dhdGUKLSAgICAgICAgICAgICAgICAgICAgaWYgKCsraW5kZXggPGxlbmd0aCkgewotICAgICAgICAgICAgICAgICAgICAgICAgc3Vycm9nYXRlcyhjaCwgdGV4dC5jaGFyQXQoaW5kZXgpKTsKLSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZhdGFsRXJyb3IoIlRoZSBjaGFyYWN0ZXIgJyIrKGNoYXIpY2grIicgaXMgYW4gaW52YWxpZCBYTUwgY2hhcmFjdGVyIik7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgaWYgKCB1bmVzY2FwZWQgJiYgWE1MMTFDaGFyLmlzWE1MMTFWYWxpZExpdGVyYWwoY2gpICkKLSAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCBjaCApOwotICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgICAgcHJpbnRYTUxDaGFyKCBjaCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotCi0gICAgcHJvdGVjdGVkIHZvaWQgcHJpbnRUZXh0KCBjaGFyW10gY2hhcnMsIGludCBzdGFydCwgaW50IGxlbmd0aCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gcHJlc2VydmVTcGFjZSwgYm9vbGVhbiB1bmVzY2FwZWQgKSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgICAgICBpbnQgaW5kZXg7Ci0gICAgICAgIGNoYXIgY2g7Ci0KLSAgICAgICAgaWYgKCBwcmVzZXJ2ZVNwYWNlICkgewotICAgICAgICAgICAgLy8gUHJlc2VydmluZyBzcGFjZXM6IHRoZSB0ZXh0IG11c3QgcHJpbnQgZXhhY3RseSBhcyBpdCBpcywKLSAgICAgICAgICAgIC8vIHdpdGhvdXQgYnJlYWtpbmcgd2hlbiBzcGFjZXMgYXBwZWFyIGluIHRoZSB0ZXh0IGFuZCB3aXRob3V0Ci0gICAgICAgICAgICAvLyBjb25zb2xpZGF0aW5nIHNwYWNlcy4gSWYgYSBsaW5lIHRlcm1pbmF0b3IgaXMgdXNlZCwgYSBsaW5lCi0gICAgICAgICAgICAvLyBicmVhayB3aWxsIG9jY3VyLgotICAgICAgICAgICAgd2hpbGUgKCBsZW5ndGgtLSA+IDAgKSB7Ci0gICAgICAgICAgICAgICAgY2ggPSBjaGFyc1tzdGFydCsrXTsKLSAgICAgICAgICAgICAgICBpZiAoIVhNTDExQ2hhci5pc1hNTDExVmFsaWQoY2gpKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIGNoZWNrIGlmIGl0IGlzIHN1cnJvZ2F0ZQotICAgICAgICAgICAgICAgICAgICBpZiAoIGxlbmd0aC0tID4gMCkgewotICAgICAgICAgICAgICAgICAgICAgICAgc3Vycm9nYXRlcyhjaCwgY2hhcnNbc3RhcnQrK10pOwotICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgZmF0YWxFcnJvcigiVGhlIGNoYXJhY3RlciAnIisoY2hhciljaCsiJyBpcyBhbiBpbnZhbGlkIFhNTCBjaGFyYWN0ZXIiKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaWYgKCB1bmVzY2FwZWQgJiYgWE1MMTFDaGFyLmlzWE1MMTFWYWxpZExpdGVyYWwoY2gpKQotICAgICAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoIGNoICk7Ci0gICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICBwcmludFhNTENoYXIoIGNoICk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAvLyBOb3QgcHJlc2VydmluZyBzcGFjZXM6IHByaW50IG9uZSBwYXJ0IGF0IGEgdGltZSwgYW5kCi0gICAgICAgICAgICAvLyB1c2Ugc3BhY2VzIGJldHdlZW4gcGFydHMgdG8gYnJlYWsgdGhlbSBpbnRvIGRpZmZlcmVudAotICAgICAgICAgICAgLy8gbGluZXMuIFNwYWNlcyBhdCBiZWdpbm5pbmcgb2YgbGluZSB3aWxsIGJlIHN0cmlwcGVkCi0gICAgICAgICAgICAvLyBieSBwcmludGluZyBtZWNoYW5pc20uIExpbmUgdGVybWluYXRvciBpcyB0cmVhdGVkCi0gICAgICAgICAgICAvLyBubyBkaWZmZXJlbnQgdGhhbiBvdGhlciB0ZXh0IHBhcnQuCi0gICAgICAgICAgICB3aGlsZSAoIGxlbmd0aC0tID4gMCApIHsKLSAgICAgICAgICAgICAgICBjaCA9IGNoYXJzW3N0YXJ0KytdOwotICAgICAgICAgICAgICAgIGlmICghWE1MMTFDaGFyLmlzWE1MMTFWYWxpZChjaCkpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gY2hlY2sgaWYgaXQgaXMgc3Vycm9nYXRlCi0gICAgICAgICAgICAgICAgICAgIGlmICggbGVuZ3RoLS0gPiAwKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzdXJyb2dhdGVzKGNoLCBjaGFyc1tzdGFydCsrXSk7Ci0gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmYXRhbEVycm9yKCJUaGUgY2hhcmFjdGVyICciKyhjaGFyKWNoKyInIGlzIGFuIGludmFsaWQgWE1MIGNoYXJhY3RlciIpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIGlmICggdW5lc2NhcGVkICYmIFhNTDExQ2hhci5pc1hNTDExVmFsaWRMaXRlcmFsKGNoKSkKLSAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCBjaCApOwotICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgICAgcHJpbnRYTUxDaGFyKCBjaCApOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgYm9vbGVhbiByZXNldCgpIHsKLSAgICAgICAgc3VwZXIucmVzZXQoKTsKLSAgICAgICAgcmV0dXJuIHRydWU7Ci0KLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZS9YTUxTZXJpYWxpemVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemUvWE1MU2VyaWFsaXplci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhOTI2ZDEyLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZS9YTUxTZXJpYWxpemVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNDY0ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKi8KLS8qCi0gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKLSAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAotICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgotICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKLSAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCi0gKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi0KLQotLy8gU2VwIDE0LCAyMDAwOgotLy8gIEZpeGVkIHByb2JsZW0gd2l0aCBuYW1lc3BhY2UgaGFuZGxpbmcuIENvbnRyaWJ1dGVkIGJ5Ci0vLyAgRGF2aWQgQmxvbmRlYXUgPGJsb25kZWF1QGludGFsaW8uY29tPgotLy8gU2VwIDE0LCAyMDAwOgotLy8gIEZpeGVkIHNlcmlhbGl6ZXIgdG8gcmVwb3J0IElPIGV4Y2VwdGlvbiBkaXJlY3RseSwgaW5zdGVhZCBhdAotLy8gIHRoZSBlbmQgb2YgZG9jdW1lbnQgcHJvY2Vzc2luZy4KLS8vICBSZXBvcnRlZCBieSBQYXRyaWNrIEhpZ2dpbnMgPHBoaWdnaW5zQHRyYW5zemFwLmNvbT4KLS8vIEF1ZyAyMSwgMjAwMDoKLS8vICBGaXhlZCBidWcgaW4gc3RhcnREb2N1bWVudCBub3QgY2FsbGluZyBwcmVwYXJlLgotLy8gIFJlcG9ydGVkIGJ5IE1pa2FlbCBTdGFsZGFsIDxkOTYtbXN0LWluZ2VuLXJla2xhbUBkLmt0aC5zZT4KLS8vIEF1ZyAyMSwgMjAwMDoKLS8vICBBZGRlZCBhYmlsaXR5IHRvIG9taXQgRE9DVFlQRSBkZWNsYXJhdGlvbi4KLQotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5kb20uRE9NTWVzc2FnZUZvcm1hdHRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuTmFtZXNwYWNlU3VwcG9ydDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuU3ltYm9sVGFibGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlhNTENoYXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlhNTFN5bWJvbHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuTmFtZXNwYWNlQ29udGV4dDsKLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uV3JpdGVyOwotaW1wb3J0IGphdmEudXRpbC5NYXA7Ci1pbXBvcnQgb3JnLnczYy5kb20uQXR0cjsKLWltcG9ydCBvcmcudzNjLmRvbS5ET01FcnJvcjsKLWltcG9ydCBvcmcudzNjLmRvbS5FbGVtZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLk5hbWVkTm9kZU1hcDsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotaW1wb3J0IG9yZy53M2MuZG9tLnRyYXZlcnNhbC5Ob2RlRmlsdGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LkF0dHJpYnV0ZUxpc3Q7Ci1pbXBvcnQgb3JnLnhtbC5zYXguQXR0cmlidXRlczsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguaGVscGVycy5BdHRyaWJ1dGVzSW1wbDsKLQotLyoqCi0gKiBJbXBsZW1lbnRzIGFuIFhNTCBzZXJpYWxpemVyIHN1cHBvcnRpbmcgYm90aCBET00gYW5kIFNBWCBwcmV0dHkKLSAqIHNlcmlhbGl6aW5nLiBGb3IgdXNhZ2UgaW5zdHJ1Y3Rpb25zIHNlZSB7QGxpbmsgU2VyaWFsaXplcn0uCi0gKiA8cD4KLSAqIElmIGFuIG91dHB1dCBzdHJlYW0gaXMgdXNlZCwgdGhlIGVuY29kaW5nIGlzIHRha2VuIGZyb20gdGhlCi0gKiBvdXRwdXQgZm9ybWF0IChkZWZhdWx0cyB0byA8dHQ+VVRGLTg8L3R0PikuIElmIGEgd3JpdGVyIGlzCi0gKiB1c2VkLCBtYWtlIHN1cmUgdGhlIHdyaXRlciB1c2VzIHRoZSBzYW1lIGVuY29kaW5nIChpZiBhcHBsaWVzKQotICogYXMgc3BlY2lmaWVkIGluIHRoZSBvdXRwdXQgZm9ybWF0LgotICogPHA+Ci0gKiBUaGUgc2VyaWFsaXplciBzdXBwb3J0cyBib3RoIERPTSBhbmQgU0FYLiBTQVggc2VyaWFsaXppbmcgaXMgZG9uZSBieSBmaXJpbmcKLSAqIFNBWCBldmVudHMgYW5kIHVzaW5nIHRoZSBzZXJpYWxpemVyIGFzIGEgZG9jdW1lbnQgaGFuZGxlci4gRE9NIHNlcmlhbGl6aW5nIGlzIGRvbmUKLSAqIGJ5IGNhbGxpbmcge0BsaW5rICNzZXJpYWxpemUoRG9jdW1lbnQpfSBvciBieSB1c2luZyBET00gTGV2ZWwgMwotICoge0BsaW5rIG9yZy53M2MuZG9tLmxzLkRPTVNlcmlhbGl6ZXJ9IGFuZAotICogc2VyaWFsaXppbmcgd2l0aCB7QGxpbmsgb3JnLnczYy5kb20ubHMuRE9NU2VyaWFsaXplciN3cml0ZX0sCi0gKiB7QGxpbmsgb3JnLnczYy5kb20ubHMuRE9NU2VyaWFsaXplciN3cml0ZVRvU3RyaW5nfS4KLSAqIDxwPgotICogSWYgYW4gSS9PIGV4Y2VwdGlvbiBvY2N1cnMgd2hpbGUgc2VyaWFsaXppbmcsIHRoZSBzZXJpYWxpemVyCi0gKiB3aWxsIG5vdCB0aHJvdyBhbiBleGNlcHRpb24gZGlyZWN0bHksIGJ1dCBvbmx5IHRocm93IGl0Ci0gKiBhdCB0aGUgZW5kIG9mIHNlcmlhbGl6aW5nIChlaXRoZXIgRE9NIG9yIFNBWCdzIHtAbGluawotICogb3JnLnhtbC5zYXguRG9jdW1lbnRIYW5kbGVyI2VuZERvY3VtZW50fS4KLSAqIDxwPgotICogRm9yIGVsZW1lbnRzIHRoYXQgYXJlIG5vdCBzcGVjaWZpZWQgYXMgd2hpdGVzcGFjZSBwcmVzZXJ2aW5nLAotICogdGhlIHNlcmlhbGl6ZXIgd2lsbCBwb3RlbnRpYWxseSBicmVhayBsb25nIHRleHQgbGluZXMgYXQgc3BhY2UKLSAqIGJvdW5kYXJpZXMsIGluZGVudCBsaW5lcywgYW5kIHNlcmlhbGl6ZSBlbGVtZW50cyBvbiBzZXBhcmF0ZQotICogbGluZXMuIExpbmUgdGVybWluYXRvcnMgd2lsbCBiZSByZWdhcmRlZCBhcyBzcGFjZXMsIGFuZAotICogc3BhY2VzIGF0IGJlZ2lubmluZyBvZiBsaW5lIHdpbGwgYmUgc3RyaXBwZWQuCi0gKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzphcmtpbkBpbnRhbGlvLmNvbSI+QXNzYWYgQXJraW48L2E+Ci0gKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzpyYWh1bC5zcml2YXN0YXZhQHN1bi5jb20iPlJhaHVsIFNyaXZhc3RhdmE8L2E+Ci0gKiBAYXV0aG9yIEVsZW5hIExpdGFuaSBJQk0KLSAqIEBzZWUgU2VyaWFsaXplcgotICovCi1wdWJsaWMgY2xhc3MgWE1MU2VyaWFsaXplcgotZXh0ZW5kcyBCYXNlTWFya3VwU2VyaWFsaXplciB7Ci0KLSAgICAvLwotICAgIC8vIGNvbnN0YW50cwotICAgIC8vCi0KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGJvb2xlYW4gREVCVUcgPSBmYWxzZTsKLQotICAgIC8vCi0gICAgLy8gZGF0YQotICAgIC8vCi0KLSAgICAvLwotICAgIC8vIERPTSBMZXZlbCAzIGltcGxlbWVudGF0aW9uOiB2YXJpYWJsZXMgaW50aWFsaXplZCBpbiBET01TZXJpYWxpemVySW1wbAotICAgIC8vCi0KLSAgICAvKiogc3RvcmVzIG5hbWVzcGFjZXMgaW4gc2NvcGUgKi8KLSAgICBwcm90ZWN0ZWQgTmFtZXNwYWNlU3VwcG9ydCBmTlNCaW5kZXI7Ci0KLSAgICAvKiogc3RvcmVzIGFsbCBuYW1lc3BhY2UgYmluZGluZ3Mgb24gdGhlIGN1cnJlbnQgZWxlbWVudCAqLwotICAgIHByb3RlY3RlZCBOYW1lc3BhY2VTdXBwb3J0IGZMb2NhbE5TQmluZGVyOwotCi0gICAgLyoqIHN5bWJvbCB0YWJsZSBmb3Igc2VyaWFsaXphdGlvbiAqLwotICAgIHByb3RlY3RlZCBTeW1ib2xUYWJsZSBmU3ltYm9sVGFibGU7Ci0KLSAgICBwcm90ZWN0ZWQgZmluYWwgc3RhdGljIFN0cmluZyBQUkVGSVggPSAiTlMiOwotCi0gICAgLyoqCi0gICAgICogQ29udHJvbHMgd2hldGhlciBuYW1lc3BhY2UgZml4dXAgc2hvdWxkIGJlIHBlcmZvcm1lZCBkdXJpbmcKLSAgICAgKiB0aGUgc2VyaWFsaXphdGlvbi4KLSAgICAgKiBOT1RFOiBpZiB0aGlzIGZpZWxkIGlzIHNldCB0byB0cnVlIHRoZSBmb2xsb3dpbmcKLSAgICAgKiBmaWVsZHMgbmVlZCB0byBiZSBpbml0aWFsaXplZDogZk5TQmluZGVyLCBmTG9jYWxOU0JpbmRlciwgZlN5bWJvbFRhYmxlLAotICAgICAqIFhNTFN5bWJvbHMuRU1QVFlfU1RSSU5HLCBmWG1sU3ltYm9sLCBmWG1sbnNTeW1ib2wKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBmTmFtZXNwYWNlcyA9IGZhbHNlOwotCi0gICAgLyoqCi0gICAgICogQ29udHJvbHMgd2hldGhlciBuYW1lc3BhY2UgcHJlZml4ZXMgd2lsbCBiZSBwcmludGVkIG91dCBkdXJpbmcgc2VyaWFsaXphdGlvbgotICAgICAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIGZOYW1lc3BhY2VQcmVmaXhlcyA9IHRydWU7Ci0KLQotICAgIHByaXZhdGUgYm9vbGVhbiBmUHJlc2VydmVTcGFjZTsKLQotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0cyBhIG5ldyBzZXJpYWxpemVyLiBUaGUgc2VyaWFsaXplciBjYW5ub3QgYmUgdXNlZCB3aXRob3V0Ci0gICAgICogY2FsbGluZyB7QGxpbmsgI3NldE91dHB1dENoYXJTdHJlYW19IG9yIHtAbGluayAjc2V0T3V0cHV0Qnl0ZVN0cmVhbX0KLSAgICAgKiBmaXJzdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgWE1MU2VyaWFsaXplcigpIHsKLSAgICAgICAgc3VwZXIoIG5ldyBPdXRwdXRGb3JtYXQoIE1ldGhvZC5YTUwsIG51bGwsIGZhbHNlICkgKTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHMgYSBuZXcgc2VyaWFsaXplci4gVGhlIHNlcmlhbGl6ZXIgY2Fubm90IGJlIHVzZWQgd2l0aG91dAotICAgICAqIGNhbGxpbmcge0BsaW5rICNzZXRPdXRwdXRDaGFyU3RyZWFtfSBvciB7QGxpbmsgI3NldE91dHB1dEJ5dGVTdHJlYW19Ci0gICAgICogZmlyc3QuCi0gICAgICovCi0gICAgcHVibGljIFhNTFNlcmlhbGl6ZXIoIE91dHB1dEZvcm1hdCBmb3JtYXQgKSB7Ci0gICAgICAgIHN1cGVyKCBmb3JtYXQgIT0gbnVsbCA/IGZvcm1hdCA6IG5ldyBPdXRwdXRGb3JtYXQoIE1ldGhvZC5YTUwsIG51bGwsIGZhbHNlICkgKTsKLSAgICAgICAgX2Zvcm1hdC5zZXRNZXRob2QoIE1ldGhvZC5YTUwgKTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHMgYSBuZXcgc2VyaWFsaXplciB0aGF0IHdyaXRlcyB0byB0aGUgc3BlY2lmaWVkIHdyaXRlcgotICAgICAqIHVzaW5nIHRoZSBzcGVjaWZpZWQgb3V0cHV0IGZvcm1hdC4gSWYgPHR0PmZvcm1hdDwvdHQ+IGlzIG51bGwsCi0gICAgICogd2lsbCB1c2UgYSBkZWZhdWx0IG91dHB1dCBmb3JtYXQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gd3JpdGVyIFRoZSB3cml0ZXIgdG8gdXNlCi0gICAgICogQHBhcmFtIGZvcm1hdCBUaGUgb3V0cHV0IGZvcm1hdCB0byB1c2UsIG51bGwgZm9yIHRoZSBkZWZhdWx0Ci0gICAgICovCi0gICAgcHVibGljIFhNTFNlcmlhbGl6ZXIoIFdyaXRlciB3cml0ZXIsIE91dHB1dEZvcm1hdCBmb3JtYXQgKSB7Ci0gICAgICAgIHN1cGVyKCBmb3JtYXQgIT0gbnVsbCA/IGZvcm1hdCA6IG5ldyBPdXRwdXRGb3JtYXQoIE1ldGhvZC5YTUwsIG51bGwsIGZhbHNlICkgKTsKLSAgICAgICAgX2Zvcm1hdC5zZXRNZXRob2QoIE1ldGhvZC5YTUwgKTsKLSAgICAgICAgc2V0T3V0cHV0Q2hhclN0cmVhbSggd3JpdGVyICk7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHNlcmlhbGl6ZXIgdGhhdCB3cml0ZXMgdG8gdGhlIHNwZWNpZmllZCBvdXRwdXQKLSAgICAgKiBzdHJlYW0gdXNpbmcgdGhlIHNwZWNpZmllZCBvdXRwdXQgZm9ybWF0LiBJZiA8dHQ+Zm9ybWF0PC90dD4KLSAgICAgKiBpcyBudWxsLCB3aWxsIHVzZSBhIGRlZmF1bHQgb3V0cHV0IGZvcm1hdC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBvdXRwdXQgVGhlIG91dHB1dCBzdHJlYW0gdG8gdXNlCi0gICAgICogQHBhcmFtIGZvcm1hdCBUaGUgb3V0cHV0IGZvcm1hdCB0byB1c2UsIG51bGwgZm9yIHRoZSBkZWZhdWx0Ci0gICAgICovCi0gICAgcHVibGljIFhNTFNlcmlhbGl6ZXIoIE91dHB1dFN0cmVhbSBvdXRwdXQsIE91dHB1dEZvcm1hdCBmb3JtYXQgKSB7Ci0gICAgICAgIHN1cGVyKCBmb3JtYXQgIT0gbnVsbCA/IGZvcm1hdCA6IG5ldyBPdXRwdXRGb3JtYXQoIE1ldGhvZC5YTUwsIG51bGwsIGZhbHNlICkgKTsKLSAgICAgICAgX2Zvcm1hdC5zZXRNZXRob2QoIE1ldGhvZC5YTUwgKTsKLSAgICAgICAgc2V0T3V0cHV0Qnl0ZVN0cmVhbSggb3V0cHV0ICk7Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgdm9pZCBzZXRPdXRwdXRGb3JtYXQoIE91dHB1dEZvcm1hdCBmb3JtYXQgKSB7Ci0gICAgICAgIHN1cGVyLnNldE91dHB1dEZvcm1hdCggZm9ybWF0ICE9IG51bGwgPyBmb3JtYXQgOiBuZXcgT3V0cHV0Rm9ybWF0KCBNZXRob2QuWE1MLCBudWxsLCBmYWxzZSApICk7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZHMgdHVybnMgb24gbmFtZXNwYWNlIGZpeHVwIGFsZ29yaXRobSBkdXJpbmcKLSAgICAgKiBET00gc2VyaWFsaXphdGlvbi4KLSAgICAgKiBAc2VlIG9yZy53M2MuZG9tLmxzLkRPTVNlcmlhbGl6ZXIKLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lc3BhY2VzCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0TmFtZXNwYWNlcyAoYm9vbGVhbiBuYW1lc3BhY2VzKXsKLSAgICAgICAgZk5hbWVzcGFjZXMgPSBuYW1lc3BhY2VzOwotICAgICAgICBpZiAoZk5TQmluZGVyID09IG51bGwpIHsKLSAgICAgICAgICAgIGZOU0JpbmRlciA9IG5ldyBOYW1lc3BhY2VTdXBwb3J0KCk7Ci0gICAgICAgICAgICBmTG9jYWxOU0JpbmRlciA9IG5ldyBOYW1lc3BhY2VTdXBwb3J0KCk7Ci0gICAgICAgICAgICBmU3ltYm9sVGFibGUgPSBuZXcgU3ltYm9sVGFibGUoKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0vLwotICAgIC8vIFNBWCBjb250ZW50IGhhbmRsZXIgc2VyaWFsaXppbmcgbWV0aG9kcyAvLwotICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0vLwotCi0KLSAgICBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQoIFN0cmluZyBuYW1lc3BhY2VVUkksIFN0cmluZyBsb2NhbE5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcmF3TmFtZSwgQXR0cmlidXRlcyBhdHRycyApCi0gICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaW50ICAgICAgICAgIGk7Ci0gICAgICAgIGJvb2xlYW4gICAgICBwcmVzZXJ2ZVNwYWNlOwotICAgICAgICBFbGVtZW50U3RhdGUgc3RhdGU7Ci0gICAgICAgIFN0cmluZyAgICAgICBuYW1lOwotICAgICAgICBTdHJpbmcgICAgICAgdmFsdWU7Ci0gICAgICAgIGJvb2xlYW4gICAgICBhZGROU0F0dHIgPSBmYWxzZTsKLQotICAgICAgICBpZiAoREVCVUcpIHsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiPT0+c3RhcnRFbGVtZW50KCIrbmFtZXNwYWNlVVJJKyIsIitsb2NhbE5hbWUrCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiwiK3Jhd05hbWUrIikiKTsKLSAgICAgICAgfQotCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBpZiAoX3ByaW50ZXIgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIFN0cmluZyBtc2cgPSBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5TRVJJQUxJWkVSX0RPTUFJTiwgIk5vV3JpdGVyU3VwcGxpZWQiLCBudWxsKTsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKG1zZyk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIHN0YXRlID0gZ2V0RWxlbWVudFN0YXRlKCk7Ci0gICAgICAgICAgICBpZiAoaXNEb2N1bWVudFN0YXRlKCkpIHsKLSAgICAgICAgICAgICAgICAvLyBJZiB0aGlzIGlzIHRoZSByb290IGVsZW1lbnQgaGFuZGxlIGl0IGRpZmZlcmVudGx5LgotICAgICAgICAgICAgICAgIC8vIElmIHRoZSBmaXJzdCByb290IGVsZW1lbnQgaW4gdGhlIGRvY3VtZW50LCBzZXJpYWxpemUKLSAgICAgICAgICAgICAgICAvLyB0aGUgZG9jdW1lbnQncyBET0NUWVBFLiBTcGFjZSBwcmVzZXJ2aW5nIGRlZmF1bHRzCi0gICAgICAgICAgICAgICAgLy8gdG8gdGhhdCBvZiB0aGUgb3V0cHV0IGZvcm1hdC4KLSAgICAgICAgICAgICAgICBpZiAoISBfc3RhcnRlZCkKLSAgICAgICAgICAgICAgICAgICAgc3RhcnREb2N1bWVudCggKCBsb2NhbE5hbWUgPT0gbnVsbCB8fCBsb2NhbE5hbWUubGVuZ3RoKCkgPT0gMCApID8gcmF3TmFtZSA6IGxvY2FsTmFtZSApOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAvLyBGb3IgYW55IG90aGVyIGVsZW1lbnQsIGlmIGZpcnN0IGluIHBhcmVudCwgdGhlbgotICAgICAgICAgICAgICAgIC8vIGNsb3NlIHBhcmVudCdzIG9wZW5pbmcgdGFnIGFuZCB1c2UgdGhlIHBhcm5ldCdzCi0gICAgICAgICAgICAgICAgLy8gc3BhY2UgcHJlc2VydmluZy4KLSAgICAgICAgICAgICAgICBpZiAoc3RhdGUuZW1wdHkpCi0gICAgICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggJz4nICk7Ci0gICAgICAgICAgICAgICAgLy8gTXVzdCBsZWF2ZSBDRGF0YSBzZWN0aW9uIGZpcnN0Ci0gICAgICAgICAgICAgICAgaWYgKHN0YXRlLmluQ0RhdGEpIHsKLSAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAiXV0+IiApOwotICAgICAgICAgICAgICAgICAgICBzdGF0ZS5pbkNEYXRhID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIC8vIEluZGVudCB0aGlzIGVsZW1lbnQgb24gYSBuZXcgbGluZSBpZiB0aGUgZmlyc3QKLSAgICAgICAgICAgICAgICAvLyBjb250ZW50IG9mIHRoZSBwYXJlbnQgZWxlbWVudCBvciBpbW1lZGlhdGVseQotICAgICAgICAgICAgICAgIC8vIGZvbGxvd2luZyBhbiBlbGVtZW50IG9yIGEgY29tbWVudAotICAgICAgICAgICAgICAgIGlmIChfaW5kZW50aW5nICYmICEgc3RhdGUucHJlc2VydmVTcGFjZSAmJgotICAgICAgICAgICAgICAgICAgICAoIHN0YXRlLmVtcHR5IHx8IHN0YXRlLmFmdGVyRWxlbWVudCB8fCBzdGF0ZS5hZnRlckNvbW1lbnQpKQotICAgICAgICAgICAgICAgICAgICBfcHJpbnRlci5icmVha0xpbmUoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHByZXNlcnZlU3BhY2UgPSBzdGF0ZS5wcmVzZXJ2ZVNwYWNlOwotCi0gICAgICAgICAgICAvL1dlIHJlbW92ZSB0aGUgbmFtZXNwYWNlcyBmcm9tIHRoZSBhdHRyaWJ1dGVzIGxpc3Qgc28gdGhhdCB0aGV5IHdpbGwKLSAgICAgICAgICAgIC8vYmUgaW4gX3ByZWZpeGVzCi0gICAgICAgICAgICBhdHRycyA9IGV4dHJhY3ROYW1lc3BhY2VzKGF0dHJzKTsKLQotICAgICAgICAgICAgLy8gRG8gbm90IGNoYW5nZSB0aGUgY3VycmVudCBlbGVtZW50IHN0YXRlIHlldC4KLSAgICAgICAgICAgIC8vIFRoaXMgb25seSBoYXBwZW5zIGluIGVuZEVsZW1lbnQoKS4KLSAgICAgICAgICAgIGlmIChyYXdOYW1lID09IG51bGwgfHwgcmF3TmFtZS5sZW5ndGgoKSA9PSAwKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGxvY2FsTmFtZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIFN0cmluZyBtc2cgPSBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoRE9NTWVzc2FnZUZvcm1hdHRlci5TRVJJQUxJWkVSX0RPTUFJTiwgIk5vTmFtZSIsIG51bGwpOwotICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKG1zZyk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGlmIChuYW1lc3BhY2VVUkkgIT0gbnVsbCAmJiAhIG5hbWVzcGFjZVVSSS5lcXVhbHMoICIiICkpIHsKLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHByZWZpeDsKLSAgICAgICAgICAgICAgICAgICAgcHJlZml4ID0gZ2V0UHJlZml4KCBuYW1lc3BhY2VVUkkgKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKHByZWZpeCAhPSBudWxsICYmIHByZWZpeC5sZW5ndGgoKSA+IDApCi0gICAgICAgICAgICAgICAgICAgICAgICByYXdOYW1lID0gcHJlZml4ICsgIjoiICsgbG9jYWxOYW1lOwotICAgICAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgICAgICByYXdOYW1lID0gbG9jYWxOYW1lOwotICAgICAgICAgICAgICAgIH0gZWxzZQotICAgICAgICAgICAgICAgICAgICByYXdOYW1lID0gbG9jYWxOYW1lOwotICAgICAgICAgICAgICAgIGFkZE5TQXR0ciA9IHRydWU7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggJzwnICk7Ci0gICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoIHJhd05hbWUgKTsKLSAgICAgICAgICAgIF9wcmludGVyLmluZGVudCgpOwotCi0gICAgICAgICAgICAvLyBGb3IgZWFjaCBhdHRyaWJ1dGUgcHJpbnQgaXQncyBuYW1lIGFuZCB2YWx1ZSBhcyBvbmUgcGFydCwKLSAgICAgICAgICAgIC8vIHNlcGFyYXRlZCB3aXRoIGEgc3BhY2Ugc28gdGhlIGVsZW1lbnQgY2FuIGJlIGJyb2tlbiBvbgotICAgICAgICAgICAgLy8gbXVsdGlwbGUgbGluZXMuCi0gICAgICAgICAgICBpZiAoYXR0cnMgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZvciAoaSA9IDAgOyBpIDwgYXR0cnMuZ2V0TGVuZ3RoKCkgOyArK2kpIHsKLSAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRTcGFjZSgpOwotCi0gICAgICAgICAgICAgICAgICAgIG5hbWUgPSBhdHRycy5nZXRRTmFtZSggaSApOwotICAgICAgICAgICAgICAgICAgICBpZiAobmFtZSAhPSBudWxsICYmIG5hbWUubGVuZ3RoKCkgPT0gMCkgewotICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHByZWZpeDsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBhdHRyVVJJOwotCi0gICAgICAgICAgICAgICAgICAgICAgICBuYW1lID0gYXR0cnMuZ2V0TG9jYWxOYW1lKCBpICk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBhdHRyVVJJID0gYXR0cnMuZ2V0VVJJKCBpICk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoKCBhdHRyVVJJICE9IG51bGwgJiYgYXR0clVSSS5sZW5ndGgoKSAhPSAwICkgJiYKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAoIG5hbWVzcGFjZVVSSSA9PSBudWxsIHx8IG5hbWVzcGFjZVVSSS5sZW5ndGgoKSA9PSAwIHx8Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAhIGF0dHJVUkkuZXF1YWxzKCBuYW1lc3BhY2VVUkkgKSApKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJlZml4ID0gZ2V0UHJlZml4KCBhdHRyVVJJICk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHByZWZpeCAhPSBudWxsICYmIHByZWZpeC5sZW5ndGgoKSA+IDApCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUgPSBwcmVmaXggKyAiOiIgKyBuYW1lOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBhdHRycy5nZXRWYWx1ZSggaSApOwotICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkKLSAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlID0gIiI7Ci0gICAgICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggbmFtZSApOwotICAgICAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoICI9XCIiICk7Ci0gICAgICAgICAgICAgICAgICAgIHByaW50RXNjYXBlZCggdmFsdWUgKTsKLSAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAnIicgKTsKLQotICAgICAgICAgICAgICAgICAgICAvLyBJZiB0aGUgYXR0cmlidXRlIHhtbDpzcGFjZSBleGlzdHMsIGRldGVybWluZSB3aGV0aGVyCi0gICAgICAgICAgICAgICAgICAgIC8vIHRvIHByZXNlcnZlIHNwYWNlcyBpbiB0aGlzIGFuZCBjaGlsZCBub2RlcyBiYXNlZCBvbgotICAgICAgICAgICAgICAgICAgICAvLyBpdHMgdmFsdWUuCi0gICAgICAgICAgICAgICAgICAgIGlmIChuYW1lLmVxdWFscyggInhtbDpzcGFjZSIgKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlLmVxdWFscyggInByZXNlcnZlIiApKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZXNlcnZlU3BhY2UgPSB0cnVlOwotICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZXNlcnZlU3BhY2UgPSBfZm9ybWF0LmdldFByZXNlcnZlU3BhY2UoKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKF9wcmVmaXhlcyAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZm9yIChNYXAuRW50cnk8U3RyaW5nLCBTdHJpbmc+IGVudHJ5IDogX3ByZWZpeGVzLmVudHJ5U2V0KCkpIHsKLSAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRTcGFjZSgpOwotICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IGVudHJ5LmdldEtleSgpOyAvL1RoZSBwcmVmaXhlcyBtYXAgdXNlcyB0aGUgVVJJIHZhbHVlIGFzIGtleS4KLSAgICAgICAgICAgICAgICAgICAgbmFtZSA9IGVudHJ5LmdldFZhbHVlKCk7IC8vYW5kIHByZWZpeCBuYW1lIGFzIHZhbHVlCi0gICAgICAgICAgICAgICAgICAgIGlmIChuYW1lLmxlbmd0aCgpID09IDApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggInhtbG5zPVwiIiApOwotICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnRFc2NhcGVkKCB2YWx1ZSApOwotICAgICAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAnIicgKTsKLSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggInhtbG5zOiIgKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggbmFtZSApOwotICAgICAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAiPVwiIiApOwotICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnRFc2NhcGVkKCB2YWx1ZSApOwotICAgICAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAnIicgKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gTm93IGl0J3MgdGltZSB0byBlbnRlciBhIG5ldyBlbGVtZW50IHN0YXRlCi0gICAgICAgICAgICAvLyB3aXRoIHRoZSB0YWcgbmFtZSBhbmQgc3BhY2UgcHJlc2VydmluZy4KLSAgICAgICAgICAgIC8vIFdlIHN0aWxsIGRvIG5vdCBjaGFuZ2UgdGhlIGN1cmVudCBlbGVtZW50IHN0YXRlLgotICAgICAgICAgICAgc3RhdGUgPSBlbnRlckVsZW1lbnRTdGF0ZSggbmFtZXNwYWNlVVJJLCBsb2NhbE5hbWUsIHJhd05hbWUsIHByZXNlcnZlU3BhY2UgKTsKLSAgICAgICAgICAgIG5hbWUgPSAoIGxvY2FsTmFtZSA9PSBudWxsIHx8IGxvY2FsTmFtZS5sZW5ndGgoKSA9PSAwICkgPyByYXdOYW1lIDogbmFtZXNwYWNlVVJJICsgIl4iICsgbG9jYWxOYW1lOwotICAgICAgICAgICAgc3RhdGUuZG9DRGF0YSA9IF9mb3JtYXQuaXNDRGF0YUVsZW1lbnQoIG5hbWUgKTsKLSAgICAgICAgICAgIHN0YXRlLnVuZXNjYXBlZCA9IF9mb3JtYXQuaXNOb25Fc2NhcGluZ0VsZW1lbnQoIG5hbWUgKTsKLSAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXhjZXB0KSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKCBleGNlcHQgKTsKLSAgICAgICAgfQotICAgIH0KLQotCi0gICAgcHVibGljIHZvaWQgZW5kRWxlbWVudCggU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIGxvY2FsTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcmF3TmFtZSApCi0gICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGVuZEVsZW1lbnRJTyggbmFtZXNwYWNlVVJJLCBsb2NhbE5hbWUsIHJhd05hbWUgKTsKLSAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXhjZXB0KSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKCBleGNlcHQgKTsKLSAgICAgICAgfQotICAgIH0KLQotCi0gICAgcHVibGljIHZvaWQgZW5kRWxlbWVudElPKCBTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgbG9jYWxOYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHJhd05hbWUgKQotICAgIHRocm93cyBJT0V4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgRWxlbWVudFN0YXRlIHN0YXRlOwotICAgICAgICBpZiAoREVCVUcpIHsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiPT0+ZW5kRWxlbWVudDogIiArcmF3TmFtZSk7Ci0gICAgICAgIH0KLSAgICAgICAgLy8gV29ya3MgbXVjaCBsaWtlIGNvbnRlbnQoKSB3aXRoIGFkZGl0aW9ucyBmb3IgY2xvc2luZwotICAgICAgICAvLyBhbiBlbGVtZW50LiBOb3RlIHRoZSBkaWZmZXJlbnQgY2hlY2tzIGZvciB0aGUgY2xvc2VkCi0gICAgICAgIC8vIGVsZW1lbnQncyBzdGF0ZSBhbmQgdGhlIHBhcmVudCBlbGVtZW50J3Mgc3RhdGUuCi0gICAgICAgIF9wcmludGVyLnVuaW5kZW50KCk7Ci0gICAgICAgIHN0YXRlID0gZ2V0RWxlbWVudFN0YXRlKCk7Ci0gICAgICAgIGlmIChzdGF0ZS5lbXB0eSkgewotICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAiLz4iICk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAvLyBNdXN0IGxlYXZlIENEYXRhIHNlY3Rpb24gZmlyc3QKLSAgICAgICAgICAgIGlmIChzdGF0ZS5pbkNEYXRhKQotICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggIl1dPiIgKTsKLSAgICAgICAgICAgIC8vIFRoaXMgZWxlbWVudCBpcyBub3QgZW1wdHkgYW5kIHRoYXQgbGFzdCBjb250ZW50IHdhcwotICAgICAgICAgICAgLy8gYW5vdGhlciBlbGVtZW50LCBzbyBwcmludCBhIGxpbmUgYnJlYWsgYmVmb3JlIHRoYXQKLSAgICAgICAgICAgIC8vIGxhc3QgZWxlbWVudCBhbmQgdGhpcyBlbGVtZW50J3MgY2xvc2luZyB0YWcuCi0gICAgICAgICAgICBpZiAoX2luZGVudGluZyAmJiAhIHN0YXRlLnByZXNlcnZlU3BhY2UgJiYgKHN0YXRlLmFmdGVyRWxlbWVudCB8fCBzdGF0ZS5hZnRlckNvbW1lbnQpKQotICAgICAgICAgICAgICAgIF9wcmludGVyLmJyZWFrTGluZSgpOwotICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAiPC8iICk7Ci0gICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoIHN0YXRlLnJhd05hbWUgKTsKLSAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggJz4nICk7Ci0gICAgICAgIH0KLSAgICAgICAgLy8gTGVhdmUgdGhlIGVsZW1lbnQgc3RhdGUgYW5kIHVwZGF0ZSB0aGF0IG9mIHRoZSBwYXJlbnQKLSAgICAgICAgLy8gKGlmIHdlJ3JlIG5vdCByb290KSB0byBub3QgZW1wdHkgYW5kIGFmdGVyIGVsZW1lbnQuCi0gICAgICAgIHN0YXRlID0gbGVhdmVFbGVtZW50U3RhdGUoKTsKLSAgICAgICAgc3RhdGUuYWZ0ZXJFbGVtZW50ID0gdHJ1ZTsKLSAgICAgICAgc3RhdGUuYWZ0ZXJDb21tZW50ID0gZmFsc2U7Ci0gICAgICAgIHN0YXRlLmVtcHR5ID0gZmFsc2U7Ci0gICAgICAgIGlmIChpc0RvY3VtZW50U3RhdGUoKSkKLSAgICAgICAgICAgIF9wcmludGVyLmZsdXNoKCk7Ci0gICAgfQotCi0KLSAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS8vCi0gICAgLy8gU0FYIGRvY3VtZW50IGhhbmRsZXIgc2VyaWFsaXppbmcgbWV0aG9kcyAvLwotICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLy8KLQotCi0gICAgcHVibGljIHZvaWQgc3RhcnRFbGVtZW50KCBTdHJpbmcgdGFnTmFtZSwgQXR0cmlidXRlTGlzdCBhdHRycyApCi0gICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaW50ICAgICAgICAgIGk7Ci0gICAgICAgIGJvb2xlYW4gICAgICBwcmVzZXJ2ZVNwYWNlOwotICAgICAgICBFbGVtZW50U3RhdGUgc3RhdGU7Ci0gICAgICAgIFN0cmluZyAgICAgICBuYW1lOwotICAgICAgICBTdHJpbmcgICAgICAgdmFsdWU7Ci0KLQotICAgICAgICBpZiAoREVCVUcpIHsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiPT0+c3RhcnRFbGVtZW50KCIrdGFnTmFtZSsiKSIpOwotICAgICAgICB9Ci0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGlmIChfcHJpbnRlciA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIG1zZyA9IERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShET01NZXNzYWdlRm9ybWF0dGVyLlNFUklBTElaRVJfRE9NQUlOLCAiTm9Xcml0ZXJTdXBwbGllZCIsIG51bGwpOwotICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24obXNnKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgc3RhdGUgPSBnZXRFbGVtZW50U3RhdGUoKTsKLSAgICAgICAgICAgIGlmIChpc0RvY3VtZW50U3RhdGUoKSkgewotICAgICAgICAgICAgICAgIC8vIElmIHRoaXMgaXMgdGhlIHJvb3QgZWxlbWVudCBoYW5kbGUgaXQgZGlmZmVyZW50bHkuCi0gICAgICAgICAgICAgICAgLy8gSWYgdGhlIGZpcnN0IHJvb3QgZWxlbWVudCBpbiB0aGUgZG9jdW1lbnQsIHNlcmlhbGl6ZQotICAgICAgICAgICAgICAgIC8vIHRoZSBkb2N1bWVudCdzIERPQ1RZUEUuIFNwYWNlIHByZXNlcnZpbmcgZGVmYXVsdHMKLSAgICAgICAgICAgICAgICAvLyB0byB0aGF0IG9mIHRoZSBvdXRwdXQgZm9ybWF0LgotICAgICAgICAgICAgICAgIGlmICghIF9zdGFydGVkKQotICAgICAgICAgICAgICAgICAgICBzdGFydERvY3VtZW50KCB0YWdOYW1lICk7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIC8vIEZvciBhbnkgb3RoZXIgZWxlbWVudCwgaWYgZmlyc3QgaW4gcGFyZW50LCB0aGVuCi0gICAgICAgICAgICAgICAgLy8gY2xvc2UgcGFyZW50J3Mgb3BlbmluZyB0YWcgYW5kIHVzZSB0aGUgcGFybmV0J3MKLSAgICAgICAgICAgICAgICAvLyBzcGFjZSBwcmVzZXJ2aW5nLgotICAgICAgICAgICAgICAgIGlmIChzdGF0ZS5lbXB0eSkKLSAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAnPicgKTsKLSAgICAgICAgICAgICAgICAvLyBNdXN0IGxlYXZlIENEYXRhIHNlY3Rpb24gZmlyc3QKLSAgICAgICAgICAgICAgICBpZiAoc3RhdGUuaW5DRGF0YSkgewotICAgICAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoICJdXT4iICk7Ci0gICAgICAgICAgICAgICAgICAgIHN0YXRlLmluQ0RhdGEgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLy8gSW5kZW50IHRoaXMgZWxlbWVudCBvbiBhIG5ldyBsaW5lIGlmIHRoZSBmaXJzdAotICAgICAgICAgICAgICAgIC8vIGNvbnRlbnQgb2YgdGhlIHBhcmVudCBlbGVtZW50IG9yIGltbWVkaWF0ZWx5Ci0gICAgICAgICAgICAgICAgLy8gZm9sbG93aW5nIGFuIGVsZW1lbnQuCi0gICAgICAgICAgICAgICAgaWYgKF9pbmRlbnRpbmcgJiYgISBzdGF0ZS5wcmVzZXJ2ZVNwYWNlICYmCi0gICAgICAgICAgICAgICAgICAgICggc3RhdGUuZW1wdHkgfHwgc3RhdGUuYWZ0ZXJFbGVtZW50IHx8IHN0YXRlLmFmdGVyQ29tbWVudCkpCi0gICAgICAgICAgICAgICAgICAgIF9wcmludGVyLmJyZWFrTGluZSgpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcHJlc2VydmVTcGFjZSA9IHN0YXRlLnByZXNlcnZlU3BhY2U7Ci0KLSAgICAgICAgICAgIC8vIERvIG5vdCBjaGFuZ2UgdGhlIGN1cnJlbnQgZWxlbWVudCBzdGF0ZSB5ZXQuCi0gICAgICAgICAgICAvLyBUaGlzIG9ubHkgaGFwcGVucyBpbiBlbmRFbGVtZW50KCkuCi0KLSAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggJzwnICk7Ci0gICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoIHRhZ05hbWUgKTsKLSAgICAgICAgICAgIF9wcmludGVyLmluZGVudCgpOwotCi0gICAgICAgICAgICAvLyBGb3IgZWFjaCBhdHRyaWJ1dGUgcHJpbnQgaXQncyBuYW1lIGFuZCB2YWx1ZSBhcyBvbmUgcGFydCwKLSAgICAgICAgICAgIC8vIHNlcGFyYXRlZCB3aXRoIGEgc3BhY2Ugc28gdGhlIGVsZW1lbnQgY2FuIGJlIGJyb2tlbiBvbgotICAgICAgICAgICAgLy8gbXVsdGlwbGUgbGluZXMuCi0gICAgICAgICAgICBpZiAoYXR0cnMgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGZvciAoaSA9IDAgOyBpIDwgYXR0cnMuZ2V0TGVuZ3RoKCkgOyArK2kpIHsKLSAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRTcGFjZSgpOwotICAgICAgICAgICAgICAgICAgICBuYW1lID0gYXR0cnMuZ2V0TmFtZSggaSApOwotICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IGF0dHJzLmdldFZhbHVlKCBpICk7Ci0gICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoIG5hbWUgKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggIj1cIiIgKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHByaW50RXNjYXBlZCggdmFsdWUgKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggJyInICk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAvLyBJZiB0aGUgYXR0cmlidXRlIHhtbDpzcGFjZSBleGlzdHMsIGRldGVybWluZSB3aGV0aGVyCi0gICAgICAgICAgICAgICAgICAgIC8vIHRvIHByZXNlcnZlIHNwYWNlcyBpbiB0aGlzIGFuZCBjaGlsZCBub2RlcyBiYXNlZCBvbgotICAgICAgICAgICAgICAgICAgICAvLyBpdHMgdmFsdWUuCi0gICAgICAgICAgICAgICAgICAgIGlmIChuYW1lLmVxdWFscyggInhtbDpzcGFjZSIgKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlLmVxdWFscyggInByZXNlcnZlIiApKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZXNlcnZlU3BhY2UgPSB0cnVlOwotICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZXNlcnZlU3BhY2UgPSBfZm9ybWF0LmdldFByZXNlcnZlU3BhY2UoKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIE5vdyBpdCdzIHRpbWUgdG8gZW50ZXIgYSBuZXcgZWxlbWVudCBzdGF0ZQotICAgICAgICAgICAgLy8gd2l0aCB0aGUgdGFnIG5hbWUgYW5kIHNwYWNlIHByZXNlcnZpbmcuCi0gICAgICAgICAgICAvLyBXZSBzdGlsbCBkbyBub3QgY2hhbmdlIHRoZSBjdXJlbnQgZWxlbWVudCBzdGF0ZS4KLSAgICAgICAgICAgIHN0YXRlID0gZW50ZXJFbGVtZW50U3RhdGUoIG51bGwsIG51bGwsIHRhZ05hbWUsIHByZXNlcnZlU3BhY2UgKTsKLSAgICAgICAgICAgIHN0YXRlLmRvQ0RhdGEgPSBfZm9ybWF0LmlzQ0RhdGFFbGVtZW50KCB0YWdOYW1lICk7Ci0gICAgICAgICAgICBzdGF0ZS51bmVzY2FwZWQgPSBfZm9ybWF0LmlzTm9uRXNjYXBpbmdFbGVtZW50KCB0YWdOYW1lICk7Ci0gICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4Y2VwdCkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbiggZXhjZXB0ICk7Ci0gICAgICAgIH0KLQotICAgIH0KLQotCi0gICAgcHVibGljIHZvaWQgZW5kRWxlbWVudCggU3RyaW5nIHRhZ05hbWUgKQotICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGVuZEVsZW1lbnQoIG51bGwsIG51bGwsIHRhZ05hbWUgKTsKLSAgICB9Ci0KLQotCi0gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0vLwotICAgIC8vIEdlbmVyaWMgbm9kZSBzZXJpYWxpemluZyBtZXRob2RzIG1ldGhvZHMgLy8KLSAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS8vCi0KLQotICAgIC8qKgotICAgICAqIENhbGxlZCB0byBzZXJpYWxpemUgdGhlIGRvY3VtZW50J3MgRE9DVFlQRSBieSB0aGUgcm9vdCBlbGVtZW50LgotICAgICAqIFRoZSBkb2N1bWVudCB0eXBlIGRlY2xhcmF0aW9uIG11c3QgbmFtZSB0aGUgcm9vdCBlbGVtZW50LAotICAgICAqIGJ1dCB0aGUgcm9vdCBlbGVtZW50IGlzIG9ubHkga25vd24gd2hlbiB0aGF0IGVsZW1lbnQgaXMgc2VyaWFsaXplZCwKLSAgICAgKiBhbmQgbm90IGF0IHRoZSBzdGFydCBvZiB0aGUgZG9jdW1lbnQuCi0gICAgICogPHA+Ci0gICAgICogVGhpcyBtZXRob2Qgd2lsbCBjaGVjayBpZiBpdCBoYXMgbm90IGJlZW4gY2FsbGVkIGJlZm9yZSAoe0BsaW5rICNfc3RhcnRlZH0pLAotICAgICAqIHdpbGwgc2VyaWFsaXplIHRoZSBkb2N1bWVudCB0eXBlIGRlY2xhcmF0aW9uLCBhbmQgd2lsbCBzZXJpYWxpemUgYWxsCi0gICAgICogcHJlLXJvb3QgY29tbWVudHMgYW5kIFBJcyB0aGF0IHdlcmUgYWNjdW11bGF0ZWQgaW4gdGhlIGRvY3VtZW50Ci0gICAgICogKHNlZSB7QGxpbmsgI3NlcmlhbGl6ZVByZVJvb3R9KS4gUHJlLXJvb3Qgd2lsbCBiZSBzZXJpYWxpemVkIGV2ZW4gaWYKLSAgICAgKiB0aGlzIGlzIG5vdCB0aGUgZmlyc3Qgcm9vdCBlbGVtZW50IG9mIHRoZSBkb2N1bWVudC4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCBzdGFydERvY3VtZW50KCBTdHJpbmcgcm9vdFRhZ05hbWUgKQotICAgIHRocm93cyBJT0V4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaW50ICAgIGk7Ci0gICAgICAgIFN0cmluZyBkdGQ7Ci0KLSAgICAgICAgZHRkID0gX3ByaW50ZXIubGVhdmVEVEQoKTsKLSAgICAgICAgaWYgKCEgX3N0YXJ0ZWQpIHsKLQotICAgICAgICAgICAgaWYgKCEgX2Zvcm1hdC5nZXRPbWl0WE1MRGVjbGFyYXRpb24oKSkgewotICAgICAgICAgICAgICAgIFN0cmluZ0J1ZmZlciAgICBidWZmZXI7Ci0KLSAgICAgICAgICAgICAgICAvLyBTZXJpYWxpemUgdGhlIGRvY3VtZW50IGRlY2xhcmF0aW9uIGFwcHJlYWluZyBhdCB0aGUgaGVhZAotICAgICAgICAgICAgICAgIC8vIG9mIHZlcnkgWE1MIGRvY3VtZW50ICh1bmxlc3MgYXNrZWQgbm90IHRvKS4KLSAgICAgICAgICAgICAgICBidWZmZXIgPSBuZXcgU3RyaW5nQnVmZmVyKCAiPD94bWwgdmVyc2lvbj1cIiIgKTsKLSAgICAgICAgICAgICAgICBpZiAoX2Zvcm1hdC5nZXRWZXJzaW9uKCkgIT0gbnVsbCkKLSAgICAgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCggX2Zvcm1hdC5nZXRWZXJzaW9uKCkgKTsKLSAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoICIxLjAiICk7Ci0gICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCggJyInICk7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIGZvcm1hdF9lbmNvZGluZyA9ICBfZm9ybWF0LmdldEVuY29kaW5nKCk7Ci0gICAgICAgICAgICAgICAgaWYgKGZvcm1hdF9lbmNvZGluZyAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoICIgZW5jb2Rpbmc9XCIiICk7Ci0gICAgICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoIGZvcm1hdF9lbmNvZGluZyApOwotICAgICAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCAnIicgKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaWYgKF9mb3JtYXQuZ2V0U3RhbmRhbG9uZSgpICYmIF9kb2NUeXBlU3lzdGVtSWQgPT0gbnVsbCAmJgotICAgICAgICAgICAgICAgICAgICBfZG9jVHlwZVB1YmxpY0lkID09IG51bGwpCi0gICAgICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoICIgc3RhbmRhbG9uZT1cInllc1wiIiApOwotICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoICI/PiIgKTsKLSAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoIGJ1ZmZlciApOwotICAgICAgICAgICAgICAgIF9wcmludGVyLmJyZWFrTGluZSgpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAoISBfZm9ybWF0LmdldE9taXREb2N1bWVudFR5cGUoKSkgewotICAgICAgICAgICAgICAgIGlmIChfZG9jVHlwZVN5c3RlbUlkICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gU3lzdGVtIGlkZW50aWZpZXIgbXVzdCBiZSBzcGVjaWZpZWQgdG8gcHJpbnQgRE9DVFlQRS4KLSAgICAgICAgICAgICAgICAgICAgLy8gSWYgcHVibGljIGlkZW50aWZpZXIgaXMgc3BlY2lmaWVkIHByaW50ICdQVUJMSUMKLSAgICAgICAgICAgICAgICAgICAgLy8gPHB1YmxpYz4gPHN5c3RlbT4nLCBpZiBub3QsIHByaW50ICdTWVNURU0gPHN5c3RlbT4nLgotICAgICAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoICI8IURPQ1RZUEUgIiApOwotICAgICAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoIHJvb3RUYWdOYW1lICk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChfZG9jVHlwZVB1YmxpY0lkICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggIiBQVUJMSUMgIiApOwotICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnREb2N0eXBlVVJMKCBfZG9jVHlwZVB1YmxpY0lkICk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoX2luZGVudGluZykgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9wcmludGVyLmJyZWFrTGluZSgpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaSA9IDAgOyBpIDwgMTggKyByb290VGFnTmFtZS5sZW5ndGgoKSA7ICsraSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAiICIgKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggIiAiICk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBwcmludERvY3R5cGVVUkwoIF9kb2NUeXBlU3lzdGVtSWQgKTsKLSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggIiBTWVNURU0gIiApOwotICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnREb2N0eXBlVVJMKCBfZG9jVHlwZVN5c3RlbUlkICk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAvLyBJZiB3ZSBhY2N1bXVsYXRlZCBhbnkgRFREIGNvbnRlbnRzIHdoaWxlIHByaW50aW5nLgotICAgICAgICAgICAgICAgICAgICAvLyB0aGlzIHdvdWxkIGJlIHRoZSBwbGFjZSB0byBwcmludCBpdC4KLSAgICAgICAgICAgICAgICAgICAgaWYgKGR0ZCAhPSBudWxsICYmIGR0ZC5sZW5ndGgoKSA+IDApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggIiBbIiApOwotICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnRUZXh0KCBkdGQsIHRydWUsIHRydWUgKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggJ10nICk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoICI+IiApOwotICAgICAgICAgICAgICAgICAgICBfcHJpbnRlci5icmVha0xpbmUoKTsKLSAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGR0ZCAhPSBudWxsICYmIGR0ZC5sZW5ndGgoKSA+IDApIHsKLSAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAiPCFET0NUWVBFICIgKTsKLSAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCByb290VGFnTmFtZSApOwotICAgICAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoICIgWyIgKTsKLSAgICAgICAgICAgICAgICAgICAgcHJpbnRUZXh0KCBkdGQsIHRydWUsIHRydWUgKTsKLSAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAiXT4iICk7Ci0gICAgICAgICAgICAgICAgICAgIF9wcmludGVyLmJyZWFrTGluZSgpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBfc3RhcnRlZCA9IHRydWU7Ci0gICAgICAgIC8vIEFsd2F5cyBzZXJpYWxpemUgdGhlc2UsIGV2ZW4gaWYgbm90IHRlIGZpcnN0IHJvb3QgZWxlbWVudC4KLSAgICAgICAgc2VyaWFsaXplUHJlUm9vdCgpOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogQ2FsbGVkIHRvIHNlcmlhbGl6ZSBhIERPTSBlbGVtZW50LiBFcXVpdmFsZW50IHRvIGNhbGxpbmcge0BsaW5rCi0gICAgICogI3N0YXJ0RWxlbWVudH0sIHtAbGluayAjZW5kRWxlbWVudH0gYW5kIHNlcmlhbGl6aW5nIGV2ZXJ5dGhpbmcKLSAgICAgKiBpbmJldHdlZW4sIGJ1dCBiZXR0ZXIgb3B0aW1pemVkLgotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIHNlcmlhbGl6ZUVsZW1lbnQoIEVsZW1lbnQgZWxlbSApCi0gICAgdGhyb3dzIElPRXhjZXB0aW9uCi0gICAgewotICAgICAgICBBdHRyICAgICAgICAgYXR0cjsKLSAgICAgICAgTmFtZWROb2RlTWFwIGF0dHJNYXA7Ci0gICAgICAgIGludCAgICAgICAgICBpOwotICAgICAgICBOb2RlICAgICAgICAgY2hpbGQ7Ci0gICAgICAgIEVsZW1lbnRTdGF0ZSBzdGF0ZTsKLSAgICAgICAgU3RyaW5nICAgICAgIG5hbWU7Ci0gICAgICAgIFN0cmluZyAgICAgICB2YWx1ZTsKLSAgICAgICAgU3RyaW5nICAgICAgIHRhZ05hbWU7Ci0KLSAgICAgICAgU3RyaW5nIHByZWZpeCwgbG9jYWxVcmk7Ci0gICAgICAgIFN0cmluZyB1cmk7Ci0gICAgICAgIGlmIChmTmFtZXNwYWNlcykgewotICAgICAgICAgICAgLy8gbG9jYWwgYmluZGVyIHN0b3JlcyBuYW1lc3BhY2UgZGVjbGFyYXRpb24KLSAgICAgICAgICAgIC8vIHRoYXQgaGFzIGJlZW4gcHJpbnRlZCBvdXQgZHVyaW5nIG5hbWVzcGFjZSBmaXh1cCBvZgotICAgICAgICAgICAgLy8gdGhlIGN1cnJlbnQgZWxlbWVudAotICAgICAgICAgICAgZkxvY2FsTlNCaW5kZXIucmVzZXQoKTsKLQotICAgICAgICAgICAgLy8gYWRkIG5ldyBuYW1lc3BhY2UgY29udGV4dAotICAgICAgICAgICAgZk5TQmluZGVyLnB1c2hDb250ZXh0KCk7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoREVCVUcpIHsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiPT0+c3RhcnRFbGVtZW50OiAiICtlbGVtLmdldE5vZGVOYW1lKCkgKyIgbnM9IitlbGVtLmdldE5hbWVzcGFjZVVSSSgpKTsKLSAgICAgICAgfQotICAgICAgICB0YWdOYW1lID0gZWxlbS5nZXRUYWdOYW1lKCk7Ci0gICAgICAgIHN0YXRlID0gZ2V0RWxlbWVudFN0YXRlKCk7Ci0gICAgICAgIGlmIChpc0RvY3VtZW50U3RhdGUoKSkgewotICAgICAgICAgICAgLy8gSWYgdGhpcyBpcyB0aGUgcm9vdCBlbGVtZW50IGhhbmRsZSBpdCBkaWZmZXJlbnRseS4KLSAgICAgICAgICAgIC8vIElmIHRoZSBmaXJzdCByb290IGVsZW1lbnQgaW4gdGhlIGRvY3VtZW50LCBzZXJpYWxpemUKLSAgICAgICAgICAgIC8vIHRoZSBkb2N1bWVudCdzIERPQ1RZUEUuIFNwYWNlIHByZXNlcnZpbmcgZGVmYXVsdHMKLSAgICAgICAgICAgIC8vIHRvIHRoYXQgb2YgdGhlIG91dHB1dCBmb3JtYXQuCi0KLSAgICAgICAgICAgIGlmICghIF9zdGFydGVkKSB7Ci0gICAgICAgICAgICAgICAgc3RhcnREb2N1bWVudCggdGFnTmFtZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAvLyBGb3IgYW55IG90aGVyIGVsZW1lbnQsIGlmIGZpcnN0IGluIHBhcmVudCwgdGhlbgotICAgICAgICAgICAgLy8gY2xvc2UgcGFyZW50J3Mgb3BlbmluZyB0YWcgYW5kIHVzZSB0aGUgcGFyZW50J3MKLSAgICAgICAgICAgIC8vIHNwYWNlIHByZXNlcnZpbmcuCi0gICAgICAgICAgICBpZiAoc3RhdGUuZW1wdHkpCi0gICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAnPicgKTsKLSAgICAgICAgICAgIC8vIE11c3QgbGVhdmUgQ0RhdGEgc2VjdGlvbiBmaXJzdAotICAgICAgICAgICAgaWYgKHN0YXRlLmluQ0RhdGEpIHsKLSAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoICJdXT4iICk7Ci0gICAgICAgICAgICAgICAgc3RhdGUuaW5DRGF0YSA9IGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gSW5kZW50IHRoaXMgZWxlbWVudCBvbiBhIG5ldyBsaW5lIGlmIHRoZSBmaXJzdAotICAgICAgICAgICAgLy8gY29udGVudCBvZiB0aGUgcGFyZW50IGVsZW1lbnQgb3IgaW1tZWRpYXRlbHkKLSAgICAgICAgICAgIC8vIGZvbGxvd2luZyBhbiBlbGVtZW50LgotICAgICAgICAgICAgaWYgKF9pbmRlbnRpbmcgJiYgISBzdGF0ZS5wcmVzZXJ2ZVNwYWNlICYmCi0gICAgICAgICAgICAgICAgKCBzdGF0ZS5lbXB0eSB8fCBzdGF0ZS5hZnRlckVsZW1lbnQgfHwgc3RhdGUuYWZ0ZXJDb21tZW50KSkKLSAgICAgICAgICAgICAgICBfcHJpbnRlci5icmVha0xpbmUoKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIERvIG5vdCBjaGFuZ2UgdGhlIGN1cnJlbnQgZWxlbWVudCBzdGF0ZSB5ZXQuCi0gICAgICAgIC8vIFRoaXMgb25seSBoYXBwZW5zIGluIGVuZEVsZW1lbnQoKS4KLSAgICAgICAgZlByZXNlcnZlU3BhY2UgPSBzdGF0ZS5wcmVzZXJ2ZVNwYWNlOwotCi0KLSAgICAgICAgaW50IGxlbmd0aCA9IDA7Ci0gICAgICAgIGF0dHJNYXAgPSBudWxsOwotICAgICAgICAvLyByZXRyaWV2ZSBhdHRyaWJ1dGVzCi0gICAgICAgIGlmIChlbGVtLmhhc0F0dHJpYnV0ZXMoKSkgewotICAgICAgICAgICAgYXR0ck1hcCA9IGVsZW0uZ2V0QXR0cmlidXRlcygpOwotICAgICAgICAgICAgbGVuZ3RoID0gYXR0ck1hcC5nZXRMZW5ndGgoKTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmICghZk5hbWVzcGFjZXMpIHsgLy8gbm8gbmFtZXNwYWNlIGZpeHVwIHNob3VsZCBiZSBwZXJmb3JtZWQKLQotICAgICAgICAgICAgLy8gc2VyaWFsaXplIGVsZW1lbnQgbmFtZQotICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAnPCcgKTsKLSAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggdGFnTmFtZSApOwotICAgICAgICAgICAgX3ByaW50ZXIuaW5kZW50KCk7Ci0KLSAgICAgICAgICAgIC8vIEZvciBlYWNoIGF0dHJpYnV0ZSBwcmludCBpdCdzIG5hbWUgYW5kIHZhbHVlIGFzIG9uZSBwYXJ0LAotICAgICAgICAgICAgLy8gc2VwYXJhdGVkIHdpdGggYSBzcGFjZSBzbyB0aGUgZWxlbWVudCBjYW4gYmUgYnJva2VuIG9uCi0gICAgICAgICAgICAvLyBtdWx0aXBsZSBsaW5lcy4KLSAgICAgICAgICAgIGZvciAoIGkgPSAwIDsgaSA8IGxlbmd0aCA7ICsraSApIHsKLSAgICAgICAgICAgICAgICBhdHRyID0gKEF0dHIpIGF0dHJNYXAuaXRlbSggaSApOwotICAgICAgICAgICAgICAgIG5hbWUgPSBhdHRyLmdldE5hbWUoKTsKLSAgICAgICAgICAgICAgICB2YWx1ZSA9IGF0dHIuZ2V0VmFsdWUoKTsKLSAgICAgICAgICAgICAgICBpZiAoIHZhbHVlID09IG51bGwgKQotICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9ICIiOwotICAgICAgICAgICAgICAgIHByaW50QXR0cmlidXRlIChuYW1lLCB2YWx1ZSwgYXR0ci5nZXRTcGVjaWZpZWQoKSwgYXR0cik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gZWxzZSB7IC8vIGRvIG5hbWVzcGFjZSBmaXh1cAotCi0gICAgICAgICAgICAvLyBSRVZJU0lUOiBzb21lIG9wdGltaXphdGlvbiBjb3VsZCBwcm9iYWJseSBiZSBkb25lIHRvIGF2b2lkIHRyYXZlcnNpbmcKLSAgICAgICAgICAgIC8vICAgICAgICAgIGF0dHJpYnV0ZXMgdHdpY2UuCi0gICAgICAgICAgICAvLwotCi0gICAgICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICAgICAgICAgIC8vIHJlY29yZCBhbGwgdmFsaWQgbmFtZXNwYWNlIGRlY2xhcmF0aW9ucwotICAgICAgICAgICAgLy8gYmVmb3JlIGF0dGVtcHRpbmcgdG8gZml4IGVsZW1lbnQncyBuYW1lc3BhY2UKLSAgICAgICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotCi0gICAgICAgICAgICBmb3IgKGkgPSAwO2kgPCBsZW5ndGg7aSsrKSB7Ci0KLSAgICAgICAgICAgICAgICBhdHRyID0gKEF0dHIpIGF0dHJNYXAuaXRlbSggaSApOwotICAgICAgICAgICAgICAgIHVyaSA9IGF0dHIuZ2V0TmFtZXNwYWNlVVJJKCk7Ci0gICAgICAgICAgICAgICAgLy8gY2hlY2sgaWYgYXR0cmlidXRlIGlzIGEgbmFtZXNwYWNlIGRlY2wKLSAgICAgICAgICAgICAgICBpZiAodXJpICE9IG51bGwgJiYgdXJpLmVxdWFscyhOYW1lc3BhY2VDb250ZXh0LlhNTE5TX1VSSSkpIHsKLQotICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IGF0dHIuZ2V0Tm9kZVZhbHVlKCk7Ci0gICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZT1YTUxTeW1ib2xzLkVNUFRZX1NUUklORzsKLSAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZS5lcXVhbHMoTmFtZXNwYWNlQ29udGV4dC5YTUxOU19VUkkpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZkRPTUVycm9ySGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG1zZyA9IERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZSgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLCJDYW50QmluZFhNTE5TIixudWxsICk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kaWZ5RE9NRXJyb3IobXNnLCAgRE9NRXJyb3IuU0VWRVJJVFlfRVJST1IsIG51bGwsIGF0dHIpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gY29udGludWVQcm9jZXNzID0gZkRPTUVycm9ySGFuZGxlci5oYW5kbGVFcnJvcihmRE9NRXJyb3IpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghY29udGludWVQcm9jZXNzKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHN0b3AgdGhlIG5hbWVzcGFjZSBmaXh1cCBhbmQgdmFsaWRhdGlvbgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZSgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuU0VSSUFMSVpFUl9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU2VyaWFsaXphdGlvblN0b3BwZWQiLCBudWxsKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgcHJlZml4ID0gYXR0ci5nZXRQcmVmaXgoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHByZWZpeCA9IChwcmVmaXggPT0gbnVsbCB8fAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZWZpeC5sZW5ndGgoKSA9PSAwKSA/IFhNTFN5bWJvbHMuRU1QVFlfU1RSSU5HIDpmU3ltYm9sVGFibGUuYWRkU3ltYm9sKHByZWZpeCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbG9jYWxwYXJ0ID0gZlN5bWJvbFRhYmxlLmFkZFN5bWJvbCggYXR0ci5nZXRMb2NhbE5hbWUoKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAocHJlZml4ID09IFhNTFN5bWJvbHMuUFJFRklYX1hNTE5TKSB7IC8veG1sbnM6cHJlZml4Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBmU3ltYm9sVGFibGUuYWRkU3ltYm9sKHZhbHVlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyByZWNvcmQgdmFsaWQgZGVjbAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZS5sZW5ndGgoKSAhPSAwKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZOU0JpbmRlci5kZWNsYXJlUHJlZml4KGxvY2FscGFydCwgdmFsdWUpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJFVklTSVQ6IGlzc3VlIGVycm9yIG9uIGludmFsaWQgZGVjbGFyYXRpb25zCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgICAgICAgIHhtbG5zOmZvbyA9ICIiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsgLy8geG1sbnMKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBlbXB0eSBwcmVmaXggaXMgYWx3YXlzIGJvdW5kICgiIiBvciBzb21lIHN0cmluZykKLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlID0gZlN5bWJvbFRhYmxlLmFkZFN5bWJvbCh2YWx1ZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZk5TQmluZGVyLmRlY2xhcmVQcmVmaXgoWE1MU3ltYm9scy5FTVBUWV9TVFJJTkcsIHZhbHVlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfSAgLy8gZW5kLWVsc2U6IHZhbGlkIGRlY2xhcmF0aW9uCi0gICAgICAgICAgICAgICAgfSAvLyBlbmQtaWY6IG5hbWVzcGFjZSBkZWNsYXJhdGlvbgotICAgICAgICAgICAgfSAgLy8gZW5kLWZvcgotCi0gICAgICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgICAgICAgICAvLyBnZXQgZWxlbWVudCB1cmkvcHJlZml4Ci0gICAgICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgICAgICAgICB1cmkgPSBlbGVtLmdldE5hbWVzcGFjZVVSSSgpOwotICAgICAgICAgICAgcHJlZml4ID0gZWxlbS5nZXRQcmVmaXgoKTsKLQotICAgICAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgICAgICAgICAvLyBvdXRwdXQgZWxlbWVudCBuYW1lCi0gICAgICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICAgICAgICAgIC8vIFJFVklTSVQ6IHRoaXMgY291bGQgYmUgcmVtb3ZlZCBpZiB3ZSBhbHdheXMgY29udmVydCBlbXB0eSBzdHJpbmcgdG8gbnVsbAotICAgICAgICAgICAgLy8gICAgICAgICAgZm9yIHRoZSBuYW1lc3BhY2VzLgotICAgICAgICAgICAgaWYgKCh1cmkgIT1udWxsICYmIHByZWZpeCAhPW51bGwgKSAmJiB1cmkubGVuZ3RoKCkgPT0gMCAmJiBwcmVmaXgubGVuZ3RoKCkhPTApIHsKLSAgICAgICAgICAgICAgICAvLyB1cmkgaXMgYW4gZW1wdHkgc3RyaW5nIGFuZCBlbGVtZW50IGhhcyBzb21lIHByZWZpeAotICAgICAgICAgICAgICAgIC8vIHRoZSBuYW1lc3BhY2UgYWxnIGxhdGVyIHdpbGwgZml4IHVwIHRoZSBuYW1lc3BhY2UgYXR0cmlidXRlcwotICAgICAgICAgICAgICAgIC8vIHJlbW92ZSBlbGVtZW50IHByZWZpeAotICAgICAgICAgICAgICAgIHByZWZpeCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAnPCcgKTsKLSAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoIGVsZW0uZ2V0TG9jYWxOYW1lKCkgKTsKLSAgICAgICAgICAgICAgICBfcHJpbnRlci5pbmRlbnQoKTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAnPCcgKTsKLSAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoIHRhZ05hbWUgKTsKLSAgICAgICAgICAgICAgICBfcHJpbnRlci5pbmRlbnQoKTsKLSAgICAgICAgICAgIH0KLQotCi0gICAgICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICAgICAgICAgIC8vIEZpeCB1cCBuYW1lc3BhY2VzIGZvciBlbGVtZW50OiBwZXIgRE9NIEwzCi0gICAgICAgICAgICAvLyBOZWVkIHRvIGNvbnNpZGVyIHRoZSBmb2xsb3dpbmcgY2FzZXM6Ci0gICAgICAgICAgICAvLwotICAgICAgICAgICAgLy8gY2FzZSAxOiA8Zm9vOmVsZW0geG1sbnM6bnMxPSJteVVSSSIgeG1sbnM9ImRlZmF1bHQiLz4KLSAgICAgICAgICAgIC8vIEFzc3VtZSAiZm9vIiwgIm5zMSIgYXJlIGRlY2xhcmVkIG9uIHRoZSBwYXJlbnQuIFdlIHNob3VsZCBub3QgbWlzcwotICAgICAgICAgICAgLy8gcmVkZWNsYXJhdGlvbiBmb3IgYm90aCAibnMxIiBhbmQgZGVmYXVsdCBuYW1lc3BhY2UuIFRvIHNvbHZlIHRoaXMKLSAgICAgICAgICAgIC8vIHdlIGFkZCBhIGxvY2FsIGJpbmRlciB0aGF0IHN0b3JlcyBkZWNsYXJhdGlvbiBvbmx5IGZvciBjdXJyZW50IGVsZW1lbnQuCi0gICAgICAgICAgICAvLyBUaGlzIHdheSB3ZSBhdm9pZCBvdXRwdXRpbmcgZHVwbGljYXRlIGRlY2xhcmF0aW9ucyBmb3IgdGhlIHNhbWUgZWxlbWVudAotICAgICAgICAgICAgLy8gYXMgd2VsbCBhcyB3ZSBhcmUgbm90IG9taXR0aW5nIHJlZGVjbGFyYXRpb25zLgotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIC8vIGNhc2UgMjogPGVsZW0geG1sbnM9IiIgeG1sbnM9ImRlZmF1bHQiLz4KLSAgICAgICAgICAgIC8vIFdlIG5lZWQgdG8gYmluZCBkZWZhdWx0IG5hbWVzcGFjZSB0byBlbXB0eSBzdHJpbmcsIHRvIGJlIGFibGUgdG8KLSAgICAgICAgICAgIC8vIG9taXQgZHVwbGljYXRlIGRlY2xhcmF0aW9ucyBmb3IgdGhlIHNhbWUgZWxlbWVudAotICAgICAgICAgICAgLy8KLSAgICAgICAgICAgIC8vIGNhc2UgMzogPHhzbDpzdHlsZXNoZWV0IHhtbG5zOnhzbD0iaHR0cDovL3hzbCI+Ci0gICAgICAgICAgICAvLyBXZSBjcmVhdGUgYW5vdGhlciBlbGVtZW50IGJvZHkgYm91bmQgdG8gdGhlICJodHRwOi8veHNsIiBuYW1lc3BhY2UKLSAgICAgICAgICAgIC8vIGFzIHdlbGwgYXMgbmFtZXNwYWNlIGF0dHJpYnV0ZSByZWJvdW5kaW5nIHhzbCB0byBhbm90aGVyIG5hbWVzcGFjZS4KLSAgICAgICAgICAgIC8vIDx4c2w6Ym9keSB4bWxuczp4c2w9Imh0dHA6Ly9hbm90aGVyIj4KLSAgICAgICAgICAgIC8vIE5lZWQgdG8gbWFrZSBzdXJlIHRoYXQgdGhlIG5ldyBuYW1lc3BhY2UgZGVjbCB2YWx1ZSBpcyBjaGFuZ2VkIHRvCi0gICAgICAgICAgICAvLyAiaHR0cDovL3hzbCIKLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICAgICAgICAgIC8vIGNoZWNrIGlmIHByZWZpeC9uYW1lc3BhY2UgaXMgY29ycmVjdCBmb3IgY3VycmVudCBlbGVtZW50Ci0gICAgICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLQotCi0gICAgICAgICAgICBpZiAodXJpICE9IG51bGwpIHsgIC8vIEVsZW1lbnQgaGFzIGEgbmFtZXNwYWNlCi0gICAgICAgICAgICAgICAgdXJpID0gZlN5bWJvbFRhYmxlLmFkZFN5bWJvbCh1cmkpOwotICAgICAgICAgICAgICAgIHByZWZpeCA9IChwcmVmaXggPT0gbnVsbCB8fAotICAgICAgICAgICAgICAgICAgICAgICAgICBwcmVmaXgubGVuZ3RoKCkgPT0gMCkgPyBYTUxTeW1ib2xzLkVNUFRZX1NUUklORyA6ZlN5bWJvbFRhYmxlLmFkZFN5bWJvbChwcmVmaXgpOwotICAgICAgICAgICAgICAgIGlmIChmTlNCaW5kZXIuZ2V0VVJJKHByZWZpeCkgPT0gdXJpKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIFRoZSB4bWxuczpwcmVmaXg9bmFtZXNwYWNlIG9yIHhtbG5zPSJkZWZhdWx0IiB3YXMgZGVjbGFyZWQgYXQgcGFyZW50LgotICAgICAgICAgICAgICAgICAgICAvLyBUaGUgYmluZGVyIGFsd2F5cyBzdG9yZXMgbWFwcGluZyBvZiBlbXB0eSBwcmVmaXggdG8gIiIuCi0gICAgICAgICAgICAgICAgICAgIC8vIChOT1RFOiBsb2NhbCBiaW5kZXIgZG9lcyBub3Qgc3RvcmUgdGhpcyBraW5kIG9mIGJpbmRpbmchKQotICAgICAgICAgICAgICAgICAgICAvLyBUaHVzIHRoZSBjYXNlIHdoZXJlIGVsZW1lbnQgd2FzIGRlY2xhcmVkIHdpdGggdXJpPSIiICh3aXRoIG9yIHdpdGhvdXQgYSBwcmVmaXgpCi0gICAgICAgICAgICAgICAgICAgIC8vIHdpbGwgYmUgY292ZXJlZCBoZXJlLgotCi0gICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gdGhlIHByZWZpeCBpcyBlaXRoZXIgdW5kZWNsYXJlZAotICAgICAgICAgICAgICAgICAgICAvLyBvcgotICAgICAgICAgICAgICAgICAgICAvLyBjb25mbGljdDogdGhlIHByZWZpeCBpcyBib3VuZCB0byBhbm90aGVyIFVSSQotICAgICAgICAgICAgICAgICAgICBpZiAoZk5hbWVzcGFjZVByZWZpeGVzKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBwcmludE5hbWVzcGFjZUF0dHIocHJlZml4LCB1cmkpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGZMb2NhbE5TQmluZGVyLmRlY2xhcmVQcmVmaXgocHJlZml4LCB1cmkpOwotICAgICAgICAgICAgICAgICAgICBmTlNCaW5kZXIuZGVjbGFyZVByZWZpeChwcmVmaXgsIHVyaSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfSBlbHNlIHsgLy8gRWxlbWVudCBoYXMgbm8gbmFtZXNwYWNlCi0gICAgICAgICAgICAgICAgaWYgKGVsZW0uZ2V0TG9jYWxOYW1lKCkgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAvLyAgRE9NIExldmVsIDEgbm9kZSEKLSAgICAgICAgICAgICAgICAgICAgaWYgKGZET01FcnJvckhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG1zZyA9IERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZSgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sICJOdWxsTG9jYWxFbGVtZW50TmFtZSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtde2VsZW0uZ2V0Tm9kZU5hbWUoKX0pOwotICAgICAgICAgICAgICAgICAgICAgICAgbW9kaWZ5RE9NRXJyb3IobXNnLERPTUVycm9yLlNFVkVSSVRZX0VSUk9SLCBudWxsLCBlbGVtKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gY29udGludWVQcm9jZXNzID0gZkRPTUVycm9ySGFuZGxlci5oYW5kbGVFcnJvcihmRE9NRXJyb3IpOwotICAgICAgICAgICAgICAgICAgICAgICAgLy8gUkVWSVNJVDogc2hvdWxkIHdlIHRlcm1pbmF0ZSB1cG9uIHJlcXVlc3Q/Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWNvbnRpbnVlUHJvY2VzcykgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuU0VSSUFMSVpFUl9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNlcmlhbGl6YXRpb25TdG9wcGVkIiwgbnVsbCkpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfSBlbHNlIHsgLy8gdXJpPW51bGwgYW5kIG5vIGNvbG9uIChET00gTDIgbm9kZSkKLSAgICAgICAgICAgICAgICAgICAgdXJpID0gZk5TQmluZGVyLmdldFVSSShYTUxTeW1ib2xzLkVNUFRZX1NUUklORyk7Ci0KLSAgICAgICAgICAgICAgICAgICAgaWYgKHVyaSAhPW51bGwgJiYgdXJpLmxlbmd0aCgpID4gMCkgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhlcmUgaXMgYSBkZWZhdWx0IG5hbWVzcGFjZSBkZWNsIHRoYXQgaXMgYm91bmQgdG8KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIG5vbi16ZXJvIGxlbmd0aCB1cmksIG91dHB1dCB4bWxucz0iIgotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZOYW1lc3BhY2VQcmVmaXhlcykgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaW50TmFtZXNwYWNlQXR0cihYTUxTeW1ib2xzLkVNUFRZX1NUUklORywgWE1MU3ltYm9scy5FTVBUWV9TVFJJTkcpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgZkxvY2FsTlNCaW5kZXIuZGVjbGFyZVByZWZpeChYTUxTeW1ib2xzLkVNUFRZX1NUUklORywgWE1MU3ltYm9scy5FTVBUWV9TVFJJTkcpOwotICAgICAgICAgICAgICAgICAgICAgICAgZk5TQmluZGVyLmRlY2xhcmVQcmVmaXgoWE1MU3ltYm9scy5FTVBUWV9TVFJJTkcsIFhNTFN5bWJvbHMuRU1QVFlfU1RSSU5HKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotCi0gICAgICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgICAgICAgICAgLy8gRml4IHVwIG5hbWVzcGFjZXMgZm9yIGF0dHJpYnV0ZXM6IHBlciBET00gTDMKLSAgICAgICAgICAgIC8vIGNoZWNrIGlmIHByZWZpeC9uYW1lc3BhY2UgaXMgY29ycmVjdCB0aGUgYXR0cmlidXRlcwotICAgICAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLQotICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7Ci0KLSAgICAgICAgICAgICAgICBhdHRyID0gKEF0dHIpIGF0dHJNYXAuaXRlbSggaSApOwotICAgICAgICAgICAgICAgIHZhbHVlID0gYXR0ci5nZXRWYWx1ZSgpOwotICAgICAgICAgICAgICAgIG5hbWUgPSBhdHRyLmdldE5vZGVOYW1lKCk7Ci0KLSAgICAgICAgICAgICAgICB1cmkgPSBhdHRyLmdldE5hbWVzcGFjZVVSSSgpOwotCi0gICAgICAgICAgICAgICAgLy8gRml4IGF0dHJpYnV0ZSB0aGF0IHdhcyBkZWNsYXJlZCB3aXRoIGEgcHJlZml4IGFuZCBuYW1lc3BhY2U9IiIKLSAgICAgICAgICAgICAgICBpZiAodXJpICE9bnVsbCAmJiB1cmkubGVuZ3RoKCkgPT0gMCkgewotICAgICAgICAgICAgICAgICAgICB1cmk9bnVsbDsKLSAgICAgICAgICAgICAgICAgICAgLy8gd2UgbXVzdCByZW1vdmUgcHJlZml4IGZvciB0aGlzIGF0dHJpYnV0ZQotICAgICAgICAgICAgICAgICAgICBuYW1lPWF0dHIuZ2V0TG9jYWxOYW1lKCk7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgaWYgKERFQlVHKSB7Ci0gICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiPT0+cHJvY2VzcyBhdHRyaWJ1dGU6ICIrYXR0ci5nZXROb2RlTmFtZSgpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLy8gbWFrZSBzdXJlIHRoYXQgdmFsdWUgaXMgbmV2ZXIgbnVsbC4KLSAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICB2YWx1ZT1YTUxTeW1ib2xzLkVNUFRZX1NUUklORzsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBpZiAodXJpICE9IG51bGwpIHsgIC8vIGF0dHJpYnV0ZSBoYXMgbmFtZXNwYWNlICE9bnVsbAotICAgICAgICAgICAgICAgICAgICBwcmVmaXggPSBhdHRyLmdldFByZWZpeCgpOwotICAgICAgICAgICAgICAgICAgICBwcmVmaXggPSBwcmVmaXggPT0gbnVsbCA/IFhNTFN5bWJvbHMuRU1QVFlfU1RSSU5HIDpmU3ltYm9sVGFibGUuYWRkU3ltYm9sKHByZWZpeCk7Ci0gICAgICAgICAgICAgICAgICAgIFN0cmluZyBsb2NhbHBhcnQgPSBmU3ltYm9sVGFibGUuYWRkU3ltYm9sKCBhdHRyLmdldExvY2FsTmFtZSgpKTsKLQotCi0KLSAgICAgICAgICAgICAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgICAgICAgICAgICAgICAgIC8vIHByaW50IG5hbWVzcGFjZSBkZWNsYXJhdGlvbnMgbmFtZXNwYWNlIGRlY2xhcmF0aW9ucwotICAgICAgICAgICAgICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICAgICAgICAgICAgICAgICAgaWYgKHVyaSAhPSBudWxsICYmIHVyaS5lcXVhbHMoTmFtZXNwYWNlQ29udGV4dC5YTUxOU19VUkkpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBjaGVjayBpZiB3ZSBuZWVkIHRvIG91dHB1dCB0aGlzIGRlY2xhcmF0aW9uCi0gICAgICAgICAgICAgICAgICAgICAgICBwcmVmaXggPSBhdHRyLmdldFByZWZpeCgpOwotICAgICAgICAgICAgICAgICAgICAgICAgcHJlZml4ID0gKHByZWZpeCA9PSBudWxsIHx8Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJlZml4Lmxlbmd0aCgpID09IDApID8gWE1MU3ltYm9scy5FTVBUWV9TVFJJTkcgOiBmU3ltYm9sVGFibGUuYWRkU3ltYm9sKHByZWZpeCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBsb2NhbHBhcnQgPSBmU3ltYm9sVGFibGUuYWRkU3ltYm9sKCBhdHRyLmdldExvY2FsTmFtZSgpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwcmVmaXggPT0gWE1MU3ltYm9scy5QUkVGSVhfWE1MTlMpIHsgLy94bWxuczpwcmVmaXgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhbFVyaSA9IGZMb2NhbE5TQmluZGVyLmdldFVSSShsb2NhbHBhcnQpOyAgLy8gbG9jYWwgcHJlZml4IG1hcHBpbmcKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IGZTeW1ib2xUYWJsZS5hZGRTeW1ib2wodmFsdWUpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZS5sZW5ndGgoKSAhPSAwICkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobG9jYWxVcmkgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZGVjbGFyYXRpb24gd2FzIG5vdCBwcmludGVkIHdoaWxlIGZpeGluZyBlbGVtZW50IG5hbWVzcGFjZSBiaW5kaW5nCi0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIElmIHRoZSBET00gTGV2ZWwgMyBuYW1lc3BhY2UtcHJlZml4ZXMgZmVhdHVyZSBpcyBzZXQgdG8gZmFsc2UKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGRvIG5vdCBwcmludCB4bWxucyBhdHRyaWJ1dGVzCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZk5hbWVzcGFjZVByZWZpeGVzKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnROYW1lc3BhY2VBdHRyKGxvY2FscGFydCwgdmFsdWUpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjYXNlIDQ6IDxlbGVtIHhtbG5zOnh4PSJmb28iIHh4OmF0dHI9IiIvPgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gd2hlcmUgYXR0cmlidXRlIGlzIGJvdW5kIHRvICJiYXIiLgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSWYgdGhlIHhtbG5zOnh4IGlzIG91dHB1dCBoZXJlIGZpcnN0LCBsYXRlciB3ZSBzaG91bGQgbm90Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyByZWRlY2xhcmUgInh4IiBwcmVmaXguIEluc3RlYWQgd2Ugd291bGQgcGljayB1cCBkaWZmZXJlbnQgcHJlZml4Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBmb3IgdGhlIGF0dHJpYnV0ZS4KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZpbmFsOiA8ZWxlbSB4bWxuczp4eD0iZm9vIiBOUzE6YXR0cj0iIiB4bWxuczpOUzE9ImJhciIvPgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkxvY2FsTlNCaW5kZXIuZGVjbGFyZVByZWZpeChsb2NhbHBhcnQsIHZhbHVlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJFVklTSVQ6IGlzc3VlIGVycm9yIG9uIGludmFsaWQgZGVjbGFyYXRpb25zCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgICAgICAgIHhtbG5zOmZvbyA9ICIiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsgLy8geG1sbnMKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBlbXB0eSBwcmVmaXggaXMgYWx3YXlzIGJvdW5kICgiIiBvciBzb21lIHN0cmluZykKLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVyaSA9IGZOU0JpbmRlci5nZXRVUkkoWE1MU3ltYm9scy5FTVBUWV9TVFJJTkcpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2FsVXJpPWZMb2NhbE5TQmluZGVyLmdldFVSSShYTUxTeW1ib2xzLkVNUFRZX1NUUklORyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBmU3ltYm9sVGFibGUuYWRkU3ltYm9sKHZhbHVlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobG9jYWxVcmkgPT0gbnVsbCApewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBkZWNsYXJhdGlvbiB3YXMgbm90IHByaW50ZWQgd2hpbGUgZml4aW5nIGVsZW1lbnQgbmFtZXNwYWNlIGJpbmRpbmcKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZOYW1lc3BhY2VQcmVmaXhlcykgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnROYW1lc3BhY2VBdHRyKFhNTFN5bWJvbHMuRU1QVFlfU1RSSU5HLCB2YWx1ZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2FzZSA0IGRvZXMgbm90IGFwcGx5IGhlcmUgc2luY2UgYXR0cmlidXRlcyBjYW4ndCB1c2UKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZGVmYXVsdCBuYW1lc3BhY2UKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB1cmkgPSBmU3ltYm9sVGFibGUuYWRkU3ltYm9sKHVyaSk7Ci0KLSAgICAgICAgICAgICAgICAgICAgLy8gZmluZCBpZiBmb3IgdGhpcyBwcmVmaXggYSBVUkkgd2FzIGFscmVhZHkgZGVjbGFyZWQKLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGRlY2xhcmVkVVJJID0gIGZOU0JpbmRlci5nZXRVUkkocHJlZml4KTsKLQotICAgICAgICAgICAgICAgICAgICBpZiAocHJlZml4ID09IFhNTFN5bWJvbHMuRU1QVFlfU1RSSU5HIHx8IGRlY2xhcmVkVVJJICE9IHVyaSkgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gYXR0cmlidXRlIGhhcyBubyBwcmVmaXggKGRlZmF1bHQgbmFtZXNwYWNlIGRlY2wgZG9lcyBub3QgYXBwbHkgdG8gYXR0cmlidXRlcykKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9SCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBhdHRyaWJ1dGUgcHJlZml4IGlzIG5vdCBkZWNsYXJlZAotICAgICAgICAgICAgICAgICAgICAgICAgLy8gT1IKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNvbmZsaWN0OiBhdHRyIFVSSSBkb2VzIG5vdCBtYXRjaCB0aGUgcHJlZml4IGluIHNjb3BlCi0KLSAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUgID0gYXR0ci5nZXROb2RlTmFtZSgpOwotICAgICAgICAgICAgICAgICAgICAgICAgLy8gRmluZCBpZiBhbnkgcHJlZml4IGZvciBhdHRyaWJ1dGVzIG5hbWVzcGFjZSBVUkkgaXMgYXZhaWxhYmxlCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBpbiB0aGUgc2NvcGUKLSAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBkZWNsYXJlZFByZWZpeCA9IGZOU0JpbmRlci5nZXRQcmVmaXgodXJpKTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRlY2xhcmVkUHJlZml4ICE9bnVsbCAmJiBkZWNsYXJlZFByZWZpeCAhPVhNTFN5bWJvbHMuRU1QVFlfU1RSSU5HKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdXNlIHRoZSBwcmVmaXggdGhhdCB3YXMgZm91bmQKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmVmaXggPSBkZWNsYXJlZFByZWZpeDsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lPXByZWZpeCsiOiIrbG9jYWxwYXJ0OwotICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoREVCVUcpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCI9PT4gY291bmQgbm90IGZpbmQgcHJlZml4IGZvciB0aGUgYXR0cmlidXRlOiAiICtwcmVmaXgpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwcmVmaXggIT0gWE1MU3ltYm9scy5FTVBUWV9TVFJJTkcgJiYgZkxvY2FsTlNCaW5kZXIuZ2V0VVJJKHByZWZpeCkgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGUgY3VycmVudCBwcmVmaXggaXMgbm90IG51bGwgYW5kIGl0IGhhcyBubyBpbiBzY29wZSBkZWNsYXJhdGlvbgotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHVzZSB0aGlzIHByZWZpeAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZpbmQgYSBwcmVmaXggZm9sbG93aW5nIHRoZSBwYXR0ZXJuICJOUyIgK2luZGV4IChzdGFydGluZyBhdCAxKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBtYWtlIHN1cmUgdGhpcyBwcmVmaXggaXMgbm90IGRlY2xhcmVkIGluIHRoZSBjdXJyZW50IHNjb3BlLgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgY291bnRlciA9IDE7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZWZpeCA9IGZTeW1ib2xUYWJsZS5hZGRTeW1ib2woUFJFRklYICsgY291bnRlcisrKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGZMb2NhbE5TQmluZGVyLmdldFVSSShwcmVmaXgpIT1udWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmVmaXggPSBmU3ltYm9sVGFibGUuYWRkU3ltYm9sKFBSRUZJWCArY291bnRlcisrKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lPXByZWZpeCsiOiIrbG9jYWxwYXJ0OwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBhZGQgZGVjbGFyYXRpb24gZm9yIHRoZSBuZXcgcHJlZml4Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZOYW1lc3BhY2VQcmVmaXhlcykgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmludE5hbWVzcGFjZUF0dHIocHJlZml4LCB1cmkpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IGZTeW1ib2xUYWJsZS5hZGRTeW1ib2wodmFsdWUpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZMb2NhbE5TQmluZGVyLmRlY2xhcmVQcmVmaXgocHJlZml4LCB2YWx1ZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZk5TQmluZGVyLmRlY2xhcmVQcmVmaXgocHJlZml4LCB1cmkpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBjaGFuZ2UgcHJlZml4IGZvciB0aGlzIGF0dHJpYnV0ZQotICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgcHJpbnRBdHRyaWJ1dGUgKG5hbWUsICh2YWx1ZT09bnVsbCk/WE1MU3ltYm9scy5FTVBUWV9TVFJJTkc6dmFsdWUsIGF0dHIuZ2V0U3BlY2lmaWVkKCksIGF0dHIpOwotICAgICAgICAgICAgICAgIH0gZWxzZSB7IC8vIGF0dHJpYnV0ZSB1cmkgPT0gbnVsbAotICAgICAgICAgICAgICAgICAgICBpZiAoYXR0ci5nZXRMb2NhbE5hbWUoKSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZkRPTUVycm9ySGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG1zZyA9IERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZSgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRE9NTWVzc2FnZUZvcm1hdHRlci5ET01fRE9NQUlOLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTnVsbExvY2FsQXR0ck5hbWUiLCBuZXcgT2JqZWN0W117YXR0ci5nZXROb2RlTmFtZSgpfSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kaWZ5RE9NRXJyb3IobXNnLCBET01FcnJvci5TRVZFUklUWV9FUlJPUiwgbnVsbCwgYXR0cik7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBjb250aW51ZVByb2Nlc3MgPSBmRE9NRXJyb3JIYW5kbGVyLmhhbmRsZUVycm9yKGZET01FcnJvcik7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFjb250aW51ZVByb2Nlc3MpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc3RvcCB0aGUgbmFtZXNwYWNlIGZpeHVwIGFuZCB2YWxpZGF0aW9uCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBET01NZXNzYWdlRm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuU0VSSUFMSVpFUl9ET01BSU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTZXJpYWxpemF0aW9uU3RvcHBlZCIsIG51bGwpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBwcmludEF0dHJpYnV0ZSAobmFtZSwgdmFsdWUsIGF0dHIuZ2V0U3BlY2lmaWVkKCksIGF0dHIpOwotICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeyAvLyB1cmk9bnVsbCBhbmQgbm8gY29sb24KLQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gbm8gZml4IHVwIGlzIG5lZWRlZDogZGVmYXVsdCBuYW1lc3BhY2UgZGVjbCBkb2VzIG5vdAotICAgICAgICAgICAgICAgICAgICAgICAgLy8gYXBwbHkgdG8gYXR0cmlidXRlcwotICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnRBdHRyaWJ1dGUgKG5hbWUsIHZhbHVlLCBhdHRyLmdldFNwZWNpZmllZCgpLCBhdHRyKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0gLy8gZW5kIGxvb3AgZm9yIGF0dHJpYnV0ZXMKLQotICAgICAgICB9Ly8gZW5kIG5hbWVzcGFjZSBmaXh1cCBhbGdvcml0aG0KLQotCi0gICAgICAgIC8vIElmIGVsZW1lbnQgaGFzIGNoaWxkcmVuLCB0aGVuIHNlcmlhbGl6ZSB0aGVtLCBvdGhlcndpc2UKLSAgICAgICAgLy8gc2VyaWFsaXplIGVuIGVtcHR5IHRhZy4KLSAgICAgICAgaWYgKGVsZW0uaGFzQ2hpbGROb2RlcygpKSB7Ci0gICAgICAgICAgICAvLyBFbnRlciBhbiBlbGVtZW50IHN0YXRlLCBhbmQgc2VyaWFsaXplIHRoZSBjaGlsZHJlbgotICAgICAgICAgICAgLy8gb25lIGJ5IG9uZS4gRmluYWxseSwgZW5kIHRoZSBlbGVtZW50LgotICAgICAgICAgICAgc3RhdGUgPSBlbnRlckVsZW1lbnRTdGF0ZSggbnVsbCwgbnVsbCwgdGFnTmFtZSwgZlByZXNlcnZlU3BhY2UgKTsKLSAgICAgICAgICAgIHN0YXRlLmRvQ0RhdGEgPSBfZm9ybWF0LmlzQ0RhdGFFbGVtZW50KCB0YWdOYW1lICk7Ci0gICAgICAgICAgICBzdGF0ZS51bmVzY2FwZWQgPSBfZm9ybWF0LmlzTm9uRXNjYXBpbmdFbGVtZW50KCB0YWdOYW1lICk7Ci0gICAgICAgICAgICBjaGlsZCA9IGVsZW0uZ2V0Rmlyc3RDaGlsZCgpOwotICAgICAgICAgICAgd2hpbGUgKGNoaWxkICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBzZXJpYWxpemVOb2RlKCBjaGlsZCApOwotICAgICAgICAgICAgICAgIGNoaWxkID0gY2hpbGQuZ2V0TmV4dFNpYmxpbmcoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChmTmFtZXNwYWNlcykgewotICAgICAgICAgICAgICAgIGZOU0JpbmRlci5wb3BDb250ZXh0KCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbmRFbGVtZW50SU8oIG51bGwsIG51bGwsIHRhZ05hbWUgKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIGlmIChERUJVRykgewotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiPT0+ZW5kRWxlbWVudDogIiArZWxlbS5nZXROb2RlTmFtZSgpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChmTmFtZXNwYWNlcykgewotICAgICAgICAgICAgICAgIGZOU0JpbmRlci5wb3BDb250ZXh0KCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBfcHJpbnRlci51bmluZGVudCgpOwotICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAiLz4iICk7Ci0gICAgICAgICAgICAvLyBBZnRlciBlbGVtZW50IGJ1dCBwYXJlbnQgZWxlbWVudCBpcyBubyBsb25nZXIgZW1wdHkuCi0gICAgICAgICAgICBzdGF0ZS5hZnRlckVsZW1lbnQgPSB0cnVlOwotICAgICAgICAgICAgc3RhdGUuYWZ0ZXJDb21tZW50ID0gZmFsc2U7Ci0gICAgICAgICAgICBzdGF0ZS5lbXB0eSA9IGZhbHNlOwotICAgICAgICAgICAgaWYgKGlzRG9jdW1lbnRTdGF0ZSgpKQotICAgICAgICAgICAgICAgIF9wcmludGVyLmZsdXNoKCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotCi0gICAgLyoqCi0gICAgICogU2VyaWFsaXplcyBhIG5hbWVzcGFjZSBhdHRyaWJ1dGUgd2l0aCB0aGUgZ2l2ZW4gcHJlZml4IGFuZCB2YWx1ZSBmb3IgVVJJLgotICAgICAqIEluIGNhc2UgcHJlZml4IGlzIGVtcHR5IHdpbGwgc2VyaWFsaXplIGRlZmF1bHQgbmFtZXNwYWNlIGRlY2xhcmF0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIHByZWZpeAotICAgICAqIEBwYXJhbSB1cmkKLSAgICAgKiBAZXhjZXB0aW9uIElPRXhjZXB0aW9uCi0gICAgICovCi0KLSAgICBwcml2YXRlIHZvaWQgcHJpbnROYW1lc3BhY2VBdHRyKFN0cmluZyBwcmVmaXgsIFN0cmluZyB1cmkpIHRocm93cyBJT0V4Y2VwdGlvbnsKLSAgICAgICAgX3ByaW50ZXIucHJpbnRTcGFjZSgpOwotICAgICAgICBpZiAocHJlZml4ID09IFhNTFN5bWJvbHMuRU1QVFlfU1RSSU5HKSB7Ci0gICAgICAgICAgICBpZiAoREVCVUcpIHsKLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIj0+YWRkIHhtbG5zPVwiIit1cmkrIlwiIGRlY2xhcmF0aW9uIik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoIFhNTFN5bWJvbHMuUFJFRklYX1hNTE5TICk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBpZiAoREVCVUcpIHsKLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIj0+YWRkIHhtbG5zOiIrcHJlZml4KyI9XCIiK3VyaSsiXCIgZGVjbGFyYXRpb24iKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggInhtbG5zOiIrcHJlZml4ICk7Ci0gICAgICAgIH0KLSAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAiPVwiIiApOwotICAgICAgICBwcmludEVzY2FwZWQoIHVyaSApOwotICAgICAgICBfcHJpbnRlci5wcmludFRleHQoICciJyApOwotICAgIH0KLQotCi0KLSAgICAvKioKLSAgICAgKiBQcmludHMgYXR0cmlidXRlLgotICAgICAqIE5PVEU6IHhtbDpzcGFjZSBhdHRyaWJ1dGUgbW9kaWZpZXMgb3V0cHV0IGZvcm1hdAotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUKLSAgICAgKiBAcGFyYW0gdmFsdWUKLSAgICAgKiBAcGFyYW0gaXNTcGVjaWZpZWQKLSAgICAgKiBAZXhjZXB0aW9uIElPRXhjZXB0aW9uCi0gICAgICovCi0gICAgcHJpdmF0ZSB2b2lkIHByaW50QXR0cmlidXRlIChTdHJpbmcgbmFtZSwgU3RyaW5nIHZhbHVlLCBib29sZWFuIGlzU3BlY2lmaWVkLCBBdHRyIGF0dHIpIHRocm93cyBJT0V4Y2VwdGlvbnsKLQotICAgICAgICBpZiAoaXNTcGVjaWZpZWQgfHwgKGZlYXR1cmVzICYgRE9NU2VyaWFsaXplckltcGwuRElTQ0FSRERFRkFVTFQpID09IDApIHsKLSAgICAgICAgICAgIGlmIChmRE9NRmlsdGVyICE9bnVsbCAmJgotICAgICAgICAgICAgICAgIChmRE9NRmlsdGVyLmdldFdoYXRUb1Nob3coKSAmIE5vZGVGaWx0ZXIuU0hPV19BVFRSSUJVVEUpIT0gMCkgewotICAgICAgICAgICAgICAgIHNob3J0IGNvZGUgPSBmRE9NRmlsdGVyLmFjY2VwdE5vZGUoYXR0cik7Ci0gICAgICAgICAgICAgICAgc3dpdGNoIChjb2RlKSB7Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgTm9kZUZpbHRlci5GSUxURVJfUkVKRUNUOgotICAgICAgICAgICAgICAgICAgICBjYXNlIE5vZGVGaWx0ZXIuRklMVEVSX1NLSVA6IHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OiB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBmYWxsIHRocm91Z2gKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIF9wcmludGVyLnByaW50U3BhY2UoKTsKLSAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggbmFtZSApOwotICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAiPVwiIiApOwotICAgICAgICAgICAgcHJpbnRFc2NhcGVkKCB2YWx1ZSApOwotICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCAnIicgKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIElmIHRoZSBhdHRyaWJ1dGUgeG1sOnNwYWNlIGV4aXN0cywgZGV0ZXJtaW5lIHdoZXRoZXIKLSAgICAgICAgLy8gdG8gcHJlc2VydmUgc3BhY2VzIGluIHRoaXMgYW5kIGNoaWxkIG5vZGVzIGJhc2VkIG9uCi0gICAgICAgIC8vIGl0cyB2YWx1ZS4KLSAgICAgICAgaWYgKG5hbWUuZXF1YWxzKCAieG1sOnNwYWNlIiApKSB7Ci0gICAgICAgICAgICBpZiAodmFsdWUuZXF1YWxzKCAicHJlc2VydmUiICkpCi0gICAgICAgICAgICAgICAgZlByZXNlcnZlU3BhY2UgPSB0cnVlOwotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIGZQcmVzZXJ2ZVNwYWNlID0gX2Zvcm1hdC5nZXRQcmVzZXJ2ZVNwYWNlKCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwcm90ZWN0ZWQgU3RyaW5nIGdldEVudGl0eVJlZiggaW50IGNoICkgewotICAgICAgICAvLyBFbmNvZGUgc3BlY2lhbCBYTUwgY2hhcmFjdGVycyBpbnRvIHRoZSBlcXVpdmFsZW50IGNoYXJhY3RlciByZWZlcmVuY2VzLgotICAgICAgICAvLyBUaGVzZSBmaXZlIGFyZSBkZWZpbmVkIGJ5IGRlZmF1bHQgZm9yIGFsbCBYTUwgZG9jdW1lbnRzLgotICAgICAgICBzd2l0Y2ggKGNoKSB7Ci0gICAgICAgIGNhc2UgJzwnOgotICAgICAgICAgICAgcmV0dXJuICJsdCI7Ci0gICAgICAgIGNhc2UgJz4nOgotICAgICAgICAgICAgcmV0dXJuICJndCI7Ci0gICAgICAgIGNhc2UgJyInOgotICAgICAgICAgICAgcmV0dXJuICJxdW90IjsKLSAgICAgICAgY2FzZSAnXCcnOgotICAgICAgICAgICAgcmV0dXJuICJhcG9zIjsKLSAgICAgICAgY2FzZSAnJic6Ci0gICAgICAgICAgICByZXR1cm4gImFtcCI7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0KLSAgICAvKiogUmV0cmlldmUgYW5kIHJlbW92ZSB0aGUgbmFtZXNwYWNlcyBkZWNsYXJhdGlvbnMgZnJvbSB0aGUgbGlzdCBvZiBhdHRyaWJ1dGVzLgotICAgICAqCi0gICAgICovCi0gICAgcHJpdmF0ZSBBdHRyaWJ1dGVzIGV4dHJhY3ROYW1lc3BhY2VzKCBBdHRyaWJ1dGVzIGF0dHJzICkKLSAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBBdHRyaWJ1dGVzSW1wbCBhdHRyc09ubHk7Ci0gICAgICAgIFN0cmluZyAgICAgICAgIHJhd05hbWU7Ci0gICAgICAgIGludCAgICAgICAgICAgIGk7Ci0gICAgICAgIGludCAgICAgICAgICAgIGluZGV4Q29sb247Ci0gICAgICAgIFN0cmluZyAgICAgICAgIHByZWZpeDsKLSAgICAgICAgaW50ICAgICAgICAgICAgbGVuZ3RoOwotCi0gICAgICAgIGlmIChhdHRycyA9PSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotICAgICAgICBsZW5ndGggPSBhdHRycy5nZXRMZW5ndGgoKTsKLSAgICAgICAgYXR0cnNPbmx5ID0gbmV3IEF0dHJpYnV0ZXNJbXBsKCBhdHRycyApOwotCi0gICAgICAgIGZvciAoaSA9IGxlbmd0aCAtIDEgOyBpID49IDAgOyAtLWkpIHsKLSAgICAgICAgICAgIHJhd05hbWUgPSBhdHRyc09ubHkuZ2V0UU5hbWUoIGkgKTsKLQotICAgICAgICAgICAgLy9XZSBoYXZlIHRvIGV4Y2x1ZGUgdGhlIG5hbWVzcGFjZXMgZGVjbGFyYXRpb25zIGZyb20gdGhlIGF0dHJpYnV0ZXMKLSAgICAgICAgICAgIC8vQXBwZW5kIG9ubHkgd2hlbiB0aGUgZmVhdHVyZSBodHRwOi8veG1sLm9yZy9zYXgvZmVhdHVyZXMvbmFtZXNwYWNlLXByZWZpeGVzIgotICAgICAgICAgICAgLy9pcyBUUlVFCi0gICAgICAgICAgICBpZiAocmF3TmFtZS5zdGFydHNXaXRoKCAieG1sbnMiICkpIHsKLSAgICAgICAgICAgICAgICBpZiAocmF3TmFtZS5sZW5ndGgoKSA9PSA1KSB7Ci0gICAgICAgICAgICAgICAgICAgIHN0YXJ0UHJlZml4TWFwcGluZyggIiIsIGF0dHJzLmdldFZhbHVlKCBpICkgKTsKLSAgICAgICAgICAgICAgICAgICAgYXR0cnNPbmx5LnJlbW92ZUF0dHJpYnV0ZSggaSApOwotICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocmF3TmFtZS5jaGFyQXQoNSkgPT0gJzonKSB7Ci0gICAgICAgICAgICAgICAgICAgIHN0YXJ0UHJlZml4TWFwcGluZyhyYXdOYW1lLnN1YnN0cmluZyg2KSwgYXR0cnMuZ2V0VmFsdWUoaSkpOwotICAgICAgICAgICAgICAgICAgICBhdHRyc09ubHkucmVtb3ZlQXR0cmlidXRlKCBpICk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBhdHRyc09ubHk7Ci0gICAgfQotCi0gICAgLy8KLSAgICAvLyBQcmludGluZyBhdHRyaWJ1dGUgdmFsdWUKLSAgICAvLwotICAgIHByb3RlY3RlZCB2b2lkIHByaW50RXNjYXBlZChTdHJpbmcgc291cmNlKSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgICAgICBpbnQgbGVuZ3RoID0gc291cmNlLmxlbmd0aCgpOwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7Ci0gICAgICAgICAgICBpbnQgY2ggPSBzb3VyY2UuY2hhckF0KGkpOwotICAgICAgICAgICAgaWYgKCFYTUxDaGFyLmlzVmFsaWQoY2gpKSB7Ci0gICAgICAgICAgICAgICAgaWYgKCsraSA8IGxlbmd0aCkgewotICAgICAgICAgICAgICAgICAgICBzdXJyb2dhdGVzKGNoLCBzb3VyY2UuY2hhckF0KGkpKTsKLSAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICBmYXRhbEVycm9yKCJUaGUgY2hhcmFjdGVyICciICsgKGNoYXIpIGNoICsgIicgaXMgYW4gaW52YWxpZCBYTUwgY2hhcmFjdGVyIik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gZXNjYXBlIE5MLCBDUiwgVEFCCi0gICAgICAgICAgICBpZiAoY2ggPT0gJ1xuJyB8fCBjaCA9PSAnXHInIHx8IGNoID09ICdcdCcpIHsKLSAgICAgICAgICAgICAgICBwcmludEhleChjaCk7Ci0gICAgICAgICAgICB9IGVsc2UgaWYgKGNoID09ICc8JykgewotICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCgiJmx0OyIpOwotICAgICAgICAgICAgfSBlbHNlIGlmIChjaCA9PSAnJicpIHsKLSAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoIiZhbXA7Iik7Ci0gICAgICAgICAgICB9IGVsc2UgaWYgKGNoID09ICciJykgewotICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCgiJnF1b3Q7Iik7Ci0gICAgICAgICAgICB9IGVsc2UgaWYgKChjaCA+PSAnICcgJiYgX2VuY29kaW5nSW5mby5pc1ByaW50YWJsZSgoY2hhcikgY2gpKSkgewotICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCgoY2hhcikgY2gpOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBwcmludEhleChjaCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKiogcHJpbnQgdGV4dCBkYXRhICovCi0gICAgcHJvdGVjdGVkIHZvaWQgcHJpbnRYTUxDaGFyKCBpbnQgY2gpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChjaCA9PSAnXHInKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBwcmludEhleChjaCk7Ci0gICAgICAgIH0gZWxzZSBpZiAoIGNoID09ICc8JykgewotICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCImbHQ7Iik7Ci0gICAgICAgIH0gZWxzZSBpZiAoY2ggPT0gJyYnKSB7Ci0gICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoIiZhbXA7Iik7Ci0gICAgICAgIH0gZWxzZSBpZiAoY2ggPT0gJz4nKXsKLSAgICAgICAgICAgICAgICAvLyBjaGFyYWN0ZXIgc2VxdWVuY2UgIl1dPiIgY2FuJ3QgYXBwZWFyIGluIGNvbnRlbnQsIHRoZXJlZm9yZQotICAgICAgICAgICAgICAgIC8vIHdlIHNob3VsZCBlc2NhcGUgJz4nCi0gICAgICAgICAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoIiZndDsiKTsKLSAgICAgICAgfSBlbHNlIGlmICggY2ggPT0gJ1xuJyB8fCAgY2ggPT0gJ1x0JyB8fAotICAgICAgICAgICAgICAgICAgICAoIGNoID49ICcgJyAmJiBfZW5jb2RpbmdJbmZvLmlzUHJpbnRhYmxlKChjaGFyKWNoKSkpIHsKLSAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCgoY2hhciljaCk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBwcmludEhleChjaCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwcm90ZWN0ZWQgdm9pZCBwcmludFRleHQoIFN0cmluZyB0ZXh0LCBib29sZWFuIHByZXNlcnZlU3BhY2UsIGJvb2xlYW4gdW5lc2NhcGVkICkKLSAgICB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgICAgICBpbnQgaW5kZXg7Ci0gICAgICAgIGNoYXIgY2g7Ci0gICAgICAgIGludCBsZW5ndGggPSB0ZXh0Lmxlbmd0aCgpOwotICAgICAgICBpZiAoIHByZXNlcnZlU3BhY2UgKSB7Ci0gICAgICAgICAgICAvLyBQcmVzZXJ2aW5nIHNwYWNlczogdGhlIHRleHQgbXVzdCBwcmludCBleGFjdGx5IGFzIGl0IGlzLAotICAgICAgICAgICAgLy8gd2l0aG91dCBicmVha2luZyB3aGVuIHNwYWNlcyBhcHBlYXIgaW4gdGhlIHRleHQgYW5kIHdpdGhvdXQKLSAgICAgICAgICAgIC8vIGNvbnNvbGlkYXRpbmcgc3BhY2VzLiBJZiBhIGxpbmUgdGVybWluYXRvciBpcyB1c2VkLCBhIGxpbmUKLSAgICAgICAgICAgIC8vIGJyZWFrIHdpbGwgb2NjdXIuCi0gICAgICAgICAgICBmb3IgKCBpbmRleCA9IDAgOyBpbmRleCA8IGxlbmd0aCA7ICsraW5kZXggKSB7Ci0gICAgICAgICAgICAgICAgY2ggPSB0ZXh0LmNoYXJBdCggaW5kZXggKTsKLSAgICAgICAgICAgICAgICBpZiAoIVhNTENoYXIuaXNWYWxpZChjaCkpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gY2hlY2sgaWYgaXQgaXMgc3Vycm9nYXRlCi0gICAgICAgICAgICAgICAgICAgIGlmICgrK2luZGV4IDxsZW5ndGgpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHN1cnJvZ2F0ZXMoY2gsIHRleHQuY2hhckF0KGluZGV4KSk7Ci0gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmYXRhbEVycm9yKCJUaGUgY2hhcmFjdGVyICciKyhjaGFyKWNoKyInIGlzIGFuIGludmFsaWQgWE1MIGNoYXJhY3RlciIpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpZiAoIHVuZXNjYXBlZCApIHsKLSAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCBjaCApOwotICAgICAgICAgICAgICAgIH0gZWxzZQotICAgICAgICAgICAgICAgICAgICBwcmludFhNTENoYXIoIGNoICk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAvLyBOb3QgcHJlc2VydmluZyBzcGFjZXM6IHByaW50IG9uZSBwYXJ0IGF0IGEgdGltZSwgYW5kCi0gICAgICAgICAgICAvLyB1c2Ugc3BhY2VzIGJldHdlZW4gcGFydHMgdG8gYnJlYWsgdGhlbSBpbnRvIGRpZmZlcmVudAotICAgICAgICAgICAgLy8gbGluZXMuIFNwYWNlcyBhdCBiZWdpbm5pbmcgb2YgbGluZSB3aWxsIGJlIHN0cmlwcGVkCi0gICAgICAgICAgICAvLyBieSBwcmludGluZyBtZWNoYW5pc20uIExpbmUgdGVybWluYXRvciBpcyB0cmVhdGVkCi0gICAgICAgICAgICAvLyBubyBkaWZmZXJlbnQgdGhhbiBvdGhlciB0ZXh0IHBhcnQuCi0gICAgICAgICAgICBmb3IgKCBpbmRleCA9IDAgOyBpbmRleCA8IGxlbmd0aCA7ICsraW5kZXggKSB7Ci0gICAgICAgICAgICAgICAgY2ggPSB0ZXh0LmNoYXJBdCggaW5kZXggKTsKLSAgICAgICAgICAgICAgICBpZiAoIVhNTENoYXIuaXNWYWxpZChjaCkpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gY2hlY2sgaWYgaXQgaXMgc3Vycm9nYXRlCi0gICAgICAgICAgICAgICAgICAgIGlmICgrK2luZGV4IDxsZW5ndGgpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHN1cnJvZ2F0ZXMoY2gsIHRleHQuY2hhckF0KGluZGV4KSk7Ci0gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmYXRhbEVycm9yKCJUaGUgY2hhcmFjdGVyICciKyhjaGFyKWNoKyInIGlzIGFuIGludmFsaWQgWE1MIGNoYXJhY3RlciIpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIHVuZXNjYXBlZCApCi0gICAgICAgICAgICAgICAgICAgIF9wcmludGVyLnByaW50VGV4dCggY2ggKTsKLSAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgIHByaW50WE1MQ2hhciggY2gpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0KLQotICAgIHByb3RlY3RlZCB2b2lkIHByaW50VGV4dCggY2hhcltdIGNoYXJzLCBpbnQgc3RhcnQsIGludCBsZW5ndGgsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIHByZXNlcnZlU3BhY2UsIGJvb2xlYW4gdW5lc2NhcGVkICkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLSAgICAgICAgaW50IGluZGV4OwotICAgICAgICBjaGFyIGNoOwotCi0gICAgICAgIGlmICggcHJlc2VydmVTcGFjZSApIHsKLSAgICAgICAgICAgIC8vIFByZXNlcnZpbmcgc3BhY2VzOiB0aGUgdGV4dCBtdXN0IHByaW50IGV4YWN0bHkgYXMgaXQgaXMsCi0gICAgICAgICAgICAvLyB3aXRob3V0IGJyZWFraW5nIHdoZW4gc3BhY2VzIGFwcGVhciBpbiB0aGUgdGV4dCBhbmQgd2l0aG91dAotICAgICAgICAgICAgLy8gY29uc29saWRhdGluZyBzcGFjZXMuIElmIGEgbGluZSB0ZXJtaW5hdG9yIGlzIHVzZWQsIGEgbGluZQotICAgICAgICAgICAgLy8gYnJlYWsgd2lsbCBvY2N1ci4KLSAgICAgICAgICAgIHdoaWxlICggbGVuZ3RoLS0gPiAwICkgewotICAgICAgICAgICAgICAgIGNoID0gY2hhcnNbc3RhcnQrK107Ci0gICAgICAgICAgICAgICAgaWYgKCFYTUxDaGFyLmlzVmFsaWQoY2gpKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIGNoZWNrIGlmIGl0IGlzIHN1cnJvZ2F0ZQotICAgICAgICAgICAgICAgICAgICBpZiAoIGxlbmd0aC0tID4gMCApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHN1cnJvZ2F0ZXMoY2gsIGNoYXJzW3N0YXJ0KytdKTsKLSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZhdGFsRXJyb3IoIlRoZSBjaGFyYWN0ZXIgJyIrKGNoYXIpY2grIicgaXMgYW4gaW52YWxpZCBYTUwgY2hhcmFjdGVyIik7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGlmICggdW5lc2NhcGVkICkKLSAgICAgICAgICAgICAgICAgICAgX3ByaW50ZXIucHJpbnRUZXh0KCBjaCApOwotICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgICAgcHJpbnRYTUxDaGFyKCBjaCApOwotICAgICAgICAgICAgfQotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgLy8gTm90IHByZXNlcnZpbmcgc3BhY2VzOiBwcmludCBvbmUgcGFydCBhdCBhIHRpbWUsIGFuZAotICAgICAgICAgICAgLy8gdXNlIHNwYWNlcyBiZXR3ZWVuIHBhcnRzIHRvIGJyZWFrIHRoZW0gaW50byBkaWZmZXJlbnQKLSAgICAgICAgICAgIC8vIGxpbmVzLiBTcGFjZXMgYXQgYmVnaW5uaW5nIG9mIGxpbmUgd2lsbCBiZSBzdHJpcHBlZAotICAgICAgICAgICAgLy8gYnkgcHJpbnRpbmcgbWVjaGFuaXNtLiBMaW5lIHRlcm1pbmF0b3IgaXMgdHJlYXRlZAotICAgICAgICAgICAgLy8gbm8gZGlmZmVyZW50IHRoYW4gb3RoZXIgdGV4dCBwYXJ0LgotICAgICAgICAgICAgd2hpbGUgKCBsZW5ndGgtLSA+IDAgKSB7Ci0gICAgICAgICAgICAgICAgY2ggPSBjaGFyc1tzdGFydCsrXTsKLSAgICAgICAgICAgICAgICBpZiAoIVhNTENoYXIuaXNWYWxpZChjaCkpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gY2hlY2sgaWYgaXQgaXMgc3Vycm9nYXRlCi0gICAgICAgICAgICAgICAgICAgIGlmICggbGVuZ3RoLS0gPiAwICkgewotICAgICAgICAgICAgICAgICAgICAgICAgc3Vycm9nYXRlcyhjaCwgY2hhcnNbc3RhcnQrK10pOwotICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgZmF0YWxFcnJvcigiVGhlIGNoYXJhY3RlciAnIisoY2hhciljaCsiJyBpcyBhbiBpbnZhbGlkIFhNTCBjaGFyYWN0ZXIiKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaWYgKCB1bmVzY2FwZWQgKQotICAgICAgICAgICAgICAgICAgICBfcHJpbnRlci5wcmludFRleHQoIGNoICk7Ci0gICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICBwcmludFhNTENoYXIoIGNoICk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgLyoqCi0gICAgKiBET00gTGV2ZWwgMzoKLSAgICAqIENoZWNrIGEgbm9kZSB0byBkZXRlcm1pbmUgaWYgaXQgY29udGFpbnMgdW5ib3VuZCBuYW1lc3BhY2UgcHJlZml4ZXMuCi0gICAgKgotICAgICogQHBhcmFtIG5vZGUgVGhlIG5vZGUgdG8gY2hlY2sgZm9yIHVuYm91bmQgbmFtZXNwYWNlIHByZWZpY2VzCi0gICAgKi8KLSAgICAgICAgcHJvdGVjdGVkIHZvaWQgY2hlY2tVbmJvdW5kTmFtZXNwYWNlUHJlZml4ZWROb2RlIChOb2RlIG5vZGUpIHRocm93cyBJT0V4Y2VwdGlvbnsKLQotICAgICAgICAgICAgICAgIGlmIChmTmFtZXNwYWNlcykgewotCi0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoREVCVUcpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIj09PnNlcmlhbGl6ZU5vZGUoIitub2RlLmdldE5vZGVOYW1lKCkrIikgW0VudGl0eSBSZWZlcmVuY2UgLSBOYW1lc3BhY2VzIG9uXSIpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIj09PkRlY2xhcmVkIFByZWZpeCBDb3VudDogIiArIGZOU0JpbmRlci5nZXREZWNsYXJlZFByZWZpeENvdW50KCkpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIj09Pk5vZGUgTmFtZTogIiArIG5vZGUuZ2V0Tm9kZU5hbWUoKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiPT0+Rmlyc3QgQ2hpbGQgTm9kZSBOYW1lOiAiICsgbm9kZS5nZXRGaXJzdENoaWxkKCkuZ2V0Tm9kZU5hbWUoKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiPT0+Rmlyc3QgQ2hpbGQgTm9kZSBQcmVmaXg6ICIgKyBub2RlLmdldEZpcnN0Q2hpbGQoKS5nZXRQcmVmaXgoKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiPT0+Rmlyc3QgQ2hpbGQgTm9kZSBOYW1lc3BhY2VVUkk6ICIgKyBub2RlLmdldEZpcnN0Q2hpbGQoKS5nZXROYW1lc3BhY2VVUkkoKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0KLQotICAgICAgICAgICAgICAgICAgICAgICAgTm9kZSBjaGlsZCwgbmV4dDsKLSAgICAgICAgICAgICAgICBmb3IgKGNoaWxkID0gbm9kZS5nZXRGaXJzdENoaWxkKCk7IGNoaWxkICE9IG51bGw7IGNoaWxkID0gbmV4dCkgewotICAgICAgICAgICAgICAgICAgICBuZXh0ID0gY2hpbGQuZ2V0TmV4dFNpYmxpbmcoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoREVCVUcpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCI9PT5zZXJpYWxpemVOb2RlKCIrY2hpbGQuZ2V0Tm9kZU5hbWUoKSsiKSBbQ2hpbGQgTm9kZV0iKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCI9PT5zZXJpYWxpemVOb2RlKCIrY2hpbGQuZ2V0UHJlZml4KCkrIikgW0NoaWxkIE5vZGUgUHJlZml4XSIpOwotICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL0lmIGEgTmFtZXNwYWNlVVJJIGlzIG5vdCBkZWNsYXJlZCBmb3IgdGhlIGN1cnJlbnQKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL25vZGUncyBwcmVmaXgsIHJhaXNlIGEgZmF0YWwgZXJyb3IuCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHByZWZpeCA9IGNoaWxkLmdldFByZWZpeCgpOwotICAgICAgICAgICAgICAgIHByZWZpeCA9IChwcmVmaXggPT0gbnVsbCB8fAotICAgICAgICAgICAgICAgICAgICAgICAgcHJlZml4Lmxlbmd0aCgpID09IDApID8gWE1MU3ltYm9scy5FTVBUWV9TVFJJTkcgOiBmU3ltYm9sVGFibGUuYWRkU3ltYm9sKHByZWZpeCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZOU0JpbmRlci5nZXRVUkkocHJlZml4KSA9PSBudWxsICYmIHByZWZpeCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmF0YWxFcnJvcigiVGhlIHJlcGxhY2VtZW50IHRleHQgb2YgdGhlIGVudGl0eSBub2RlICciCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBub2RlLmdldE5vZGVOYW1lKCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICInIGNvbnRhaW5zIGFuIGVsZW1lbnQgbm9kZSAnIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgY2hpbGQuZ2V0Tm9kZU5hbWUoKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIicgd2l0aCBhbiB1bmRlY2xhcmVkIHByZWZpeCAnIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgcHJlZml4ICsgIicuIik7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjaGlsZC5nZXROb2RlVHlwZSgpID09IE5vZGUuRUxFTUVOVF9OT0RFKSB7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOYW1lZE5vZGVNYXAgYXR0cnMgPSBjaGlsZC5nZXRBdHRyaWJ1dGVzKCk7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaTwgYXR0cnMuZ2V0TGVuZ3RoKCk7IGkrKyApIHsKLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgYXR0clByZWZpeCA9IGF0dHJzLml0ZW0oaSkuZ2V0UHJlZml4KCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBhdHRyUHJlZml4ID0gKGF0dHJQcmVmaXggPT0gbnVsbCB8fAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyUHJlZml4Lmxlbmd0aCgpID09IDApID8gWE1MU3ltYm9scy5FTVBUWV9TVFJJTkcgOiBmU3ltYm9sVGFibGUuYWRkU3ltYm9sKGF0dHJQcmVmaXgpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZk5TQmluZGVyLmdldFVSSShhdHRyUHJlZml4KSA9PSBudWxsICYmIGF0dHJQcmVmaXggIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYXRhbEVycm9yKCJUaGUgcmVwbGFjZW1lbnQgdGV4dCBvZiB0aGUgZW50aXR5IG5vZGUgJyIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBub2RlLmdldE5vZGVOYW1lKCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiJyBjb250YWlucyBhbiBlbGVtZW50IG5vZGUgJyIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBjaGlsZC5nZXROb2RlTmFtZSgpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIicgd2l0aCBhbiBhdHRyaWJ1dGUgJyIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBhdHRycy5pdGVtKGkpLmdldE5vZGVOYW1lKCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiJyBhbiB1bmRlY2xhcmVkIHByZWZpeCAnIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGF0dHJQcmVmaXggKyAiJy4iKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2hpbGQuaGFzQ2hpbGROb2RlcygpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tVbmJvdW5kTmFtZXNwYWNlUHJlZml4ZWROb2RlKGNoaWxkKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIHJlc2V0KCkgewotICAgICAgICBzdXBlci5yZXNldCgpOwotICAgICAgICBpZiAoZk5TQmluZGVyICE9IG51bGwpewotICAgICAgICAgICAgZk5TQmluZGVyLnJlc2V0KCk7Ci0gICAgICAgICAgICAvLyBkdXJpbmcgc2VyaWFsaXphdGlvbiBhbHdheXMgaGF2ZSBhIG1hcHBpbmcgdG8gZW1wdHkgc3RyaW5nCi0gICAgICAgICAgICAvLyBzbyB3ZSBhc3N1bWUgdGhlcmUgaXMgYSBkZWNsYXJhdGlvbi4KLSAgICAgICAgICAgIGZOU0JpbmRlci5kZWNsYXJlUHJlZml4KFhNTFN5bWJvbHMuRU1QVFlfU1RSSU5HLCBYTUxTeW1ib2xzLkVNUFRZX1NUUklORyk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL0F0dHJpYnV0ZXNJbXBsU2VyaWFsaXplci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9BdHRyaWJ1dGVzSW1wbFNlcmlhbGl6ZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYTNjZGFhOS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL0F0dHJpYnV0ZXNJbXBsU2VyaWFsaXplci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjM4ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKi8KLS8qCi0gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKLSAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAotICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgotICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKLSAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCi0gKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogQXR0cmlidXRlc0ltcGxTZXJpYWxpemVyLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTUgMDg6MTU6MTQgc3VyZXNoX2VtYWlsaWQgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplcjsKLQotaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwotaW1wb3J0IGphdmEudXRpbC5NYXA7Ci1pbXBvcnQgb3JnLnhtbC5zYXguQXR0cmlidXRlczsKLWltcG9ydCBvcmcueG1sLnNheC5oZWxwZXJzLkF0dHJpYnV0ZXNJbXBsOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgZXh0ZW5kcyBvcmcueG1sLnNheC5oZWxwZXJzLkF0dHJpYnV0ZXNJbXBsIHdoaWNoIGltcGxlbWVudHMgb3JnLgotICogeG1sLnNheC5BdHRyaWJ1dGVzLiBCdXQgZm9yIG9wdGltaXphdGlvbiB0aGlzIGNsYXNzIGFkZHMgYSBNYXAgZm9yCi0gKiBmYXN0ZXIgbG9va3VwIG9mIGFuIGluZGV4IGJ5IHFOYW1lLCB3aGljaCBpcyBjb21tb25seSBkb25lIGluIHRoZSBzdHJlYW0KLSAqIHNlcmlhbGl6ZXIuCi0gKgotICogQHNlZSBvcmcueG1sLnNheC5BdHRyaWJ1dGVzCi0gKgotICogQHhzbC51c2FnZSBpbnRlcm5hbAotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgQXR0cmlidXRlc0ltcGxTZXJpYWxpemVyIGV4dGVuZHMgQXR0cmlidXRlc0ltcGwKLXsKLSAgICAvKioKLSAgICAgKiBIYXNoIHRhYmxlIG9mIHFOYW1lL2luZGV4IHZhbHVlcyB0byBxdWlja2x5IGxvb2t1cCB0aGUgaW5kZXgKLSAgICAgKiBvZiBhbiBhdHRyaWJ1dGVzIHFOYW1lLiAgcU5hbWVzIGFyZSBpbiB1cHBlcmNhc2UgaW4gdGhlIGhhc2ggdGFibGUKLSAgICAgKiB0byBtYWtlIHRoZSBzZWFyY2ggY2FzZSBpbnNlbnNpdGl2ZS4KLSAgICAgKgotICAgICAqIFRoZSBrZXlzIHRvIHRoZSBoYXNodGFibGUgdG8gZmluZCB0aGUgaW5kZXggYXJlIGVpdGhlcgotICAgICAqICJwcmVmaXg6bG9jYWxOYW1lIiAgb3IgInt1cml9bG9jYWxOYW1lIi4KLSAgICAgKi8KLSAgICBwcml2YXRlIGZpbmFsIE1hcDxTdHJpbmcsIEludGVnZXI+IG1faW5kZXhGcm9tUU5hbWUgPSBuZXcgSGFzaE1hcDw+KCk7Ci0KLSAgICBwcml2YXRlIGZpbmFsIFN0cmluZ0J1ZmZlciBtX2J1ZmYgPSBuZXcgU3RyaW5nQnVmZmVyKCk7Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIGlzIHRoZSBudW1iZXIgb2YgYXR0cmlidXRlcyBiZWZvcmUgc3dpdGNoaW5nIHRvIHRoZSBoYXNoIHRhYmxlLAotICAgICAqIGFuZCBjYW4gYmUgdHVuZWQsIGJ1dCAxMiBzZWVtcyBnb29kIGZvciBub3cgLSBCcmlhbiBNLgotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBNQVggPSAxMjsKLQotICAgIC8qKgotICAgICAqIE9uZSBsZXNzIHRoYW4gdGhlIG51bWJlciBvZiBhdHRyaWJ1dGVzIGJlZm9yZSBzd2l0Y2hpbmcgdG8KLSAgICAgKiB0aGUgTWFwLgotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBNQVhNaW51czEgPSBNQVggLSAxOwotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgZ2V0cyB0aGUgaW5kZXggb2YgYW4gYXR0cmlidXRlIGdpdmVuIGl0cyBxTmFtZS4KLSAgICAgKiBAcGFyYW0gcW5hbWUgdGhlIHF1YWxpZmllZCBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUsIGUuZy4gInByZWZpeDE6bG9jTmFtZTEiCi0gICAgICogQHJldHVybiB0aGUgaW50ZWdlciBpbmRleCBvZiB0aGUgYXR0cmlidXRlLgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQXR0cmlidXRlcyNnZXRJbmRleChTdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIGludCBnZXRJbmRleChTdHJpbmcgcW5hbWUpCi0gICAgewotICAgICAgICBpbnQgaW5kZXg7Ci0KLSAgICAgICAgaWYgKHN1cGVyLmdldExlbmd0aCgpIDwgTUFYKQotICAgICAgICB7Ci0gICAgICAgICAgICAvLyBpZiB3ZSBoYXZlbid0IGdvdCB0b28gbWFueSBhdHRyaWJ1dGVzIGxldCB0aGUKLSAgICAgICAgICAgIC8vIHN1cGVyIGNsYXNzIGxvb2sgaXQgdXAKLSAgICAgICAgICAgIGluZGV4ID0gc3VwZXIuZ2V0SW5kZXgocW5hbWUpOwotICAgICAgICAgICAgcmV0dXJuIGluZGV4OwotICAgICAgICB9Ci0gICAgICAgIC8vIHdlIGhhdmUgdG9vIG1hbnkgYXR0cmlidXRlcyBhbmQgdGhlIHN1cGVyIGNsYXNzIGlzIHNsb3cKLSAgICAgICAgLy8gc28gZmluZCBpdCBxdWlja2x5IHVzaW5nIG91ciBNYXAuCi0gICAgICAgIEludGVnZXIgaSA9IG1faW5kZXhGcm9tUU5hbWUuZ2V0KHFuYW1lKTsKLSAgICAgICAgaWYgKGkgPT0gbnVsbCkKLSAgICAgICAgICAgIGluZGV4ID0gLTE7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICAgIGluZGV4ID0gaS5pbnRWYWx1ZSgpOwotICAgICAgICByZXR1cm4gaW5kZXg7Ci0gICAgfQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIGFkZHMgdGhlIGF0dHJpYnV0ZSwgYnV0IGFsc28gcmVjb3JkcyBpdHMgcU5hbWUvaW5kZXggcGFpciBpbgotICAgICAqIHRoZSBoYXNodGFibGUgZm9yIGZhc3QgbG9va3VwIGJ5IGdldEluZGV4KHFOYW1lKS4KLSAgICAgKiBAcGFyYW0gdXJpIHRoZSBVUkkgb2YgdGhlIGF0dHJpYnV0ZQotICAgICAqIEBwYXJhbSBsb2NhbCB0aGUgbG9jYWwgbmFtZSBvZiB0aGUgYXR0cmlidXRlCi0gICAgICogQHBhcmFtIHFuYW1lIHRoZSBxdWFsaWZpZWQgbmFtZSBvZiB0aGUgYXR0cmlidXRlCi0gICAgICogQHBhcmFtIHR5cGUgdGhlIHR5cGUgb2YgdGhlIGF0dHJpYnV0ZQotICAgICAqIEBwYXJhbSB2YWwgdGhlIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUKLSAgICAgKgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguaGVscGVycy5BdHRyaWJ1dGVzSW1wbCNhZGRBdHRyaWJ1dGUoU3RyaW5nLCBTdHJpbmcsIFN0cmluZywgU3RyaW5nLCBTdHJpbmcpCi0gICAgICogQHNlZSAjZ2V0SW5kZXgoU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyBmaW5hbCB2b2lkIGFkZEF0dHJpYnV0ZSgKLSAgICAgICAgU3RyaW5nIHVyaSwKLSAgICAgICAgU3RyaW5nIGxvY2FsLAotICAgICAgICBTdHJpbmcgcW5hbWUsCi0gICAgICAgIFN0cmluZyB0eXBlLAotICAgICAgICBTdHJpbmcgdmFsKQotICAgIHsKLSAgICAgICAgaW50IGluZGV4ID0gc3VwZXIuZ2V0TGVuZ3RoKCk7Ci0gICAgICAgIHN1cGVyLmFkZEF0dHJpYnV0ZSh1cmksIGxvY2FsLCBxbmFtZSwgdHlwZSwgdmFsKTsKLSAgICAgICAgLy8gKGluZGV4ICsgMSkgaXMgbm93IHRoZSBudW1iZXIgb2YgYXR0cmlidXRlcwotICAgICAgICAvLyBzbyBlaXRoZXIgY29tcGFyZSAoaW5kZXgrMSkgdG8gTUFYLCBvciBjb21wYXJlIGluZGV4IHRvIChNQVgtMSkKLQotICAgICAgICBpZiAoaW5kZXggPCBNQVhNaW51czEpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChpbmRleCA9PSBNQVhNaW51czEpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHN3aXRjaE92ZXJUb0hhc2goTUFYKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgIHsKLSAgICAgICAgICAgIC8qIGFkZCB0aGUga2V5IHdpdGggdGhlIGZvcm1hdCBvZiAicHJlZml4OmxvY2FsTmFtZSIgKi8KLSAgICAgICAgICAgIC8qIHdlIGhhdmUganVzdCBhZGRlZCB0aGUgYXR0aWJ1dGUsIGl0cyBpbmRleCBpcyB0aGUgb2xkIGxlbmd0aCAqLwotICAgICAgICAgICAgSW50ZWdlciBpID0gaW5kZXg7Ci0gICAgICAgICAgICBtX2luZGV4RnJvbVFOYW1lLnB1dChxbmFtZSwgaSk7Ci0KLSAgICAgICAgICAgIC8qIG5vdyBhZGQgd2l0aCBrZXkgb2YgdGhlIGZvcm1hdCAie3VyaX1sb2NhbE5hbWUiICovCi0gICAgICAgICAgICBtX2J1ZmYuc2V0TGVuZ3RoKDApOwotICAgICAgICAgICAgbV9idWZmLmFwcGVuZCgneycpLmFwcGVuZCh1cmkpLmFwcGVuZCgnfScpLmFwcGVuZChsb2NhbCk7Ci0gICAgICAgICAgICBTdHJpbmcga2V5ID0gbV9idWZmLnRvU3RyaW5nKCk7Ci0gICAgICAgICAgICBtX2luZGV4RnJvbVFOYW1lLnB1dChrZXksIGkpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogV2UgYXJlIHN3aXRjaGluZyBvdmVyIHRvIGhhdmluZyBhIGhhc2ggdGFibGUgZm9yIHF1aWNrIGxvb2sKLSAgICAgKiB1cCBvZiBhdHRyaWJ1dGVzLCBidXQgdXAgdW50aWwgbm93IHdlIGhhdmVuJ3Qga2VwdCBhbnkKLSAgICAgKiBpbmZvcm1hdGlvbiBpbiB0aGUgTWFwLCBzbyB3ZSBub3cgdXBkYXRlIHRoZSBNYXAuCi0gICAgICogRnV0dXJlIGFkZGl0aW9uYWwgYXR0cmlidXRlcyB3aWxsIHVwZGF0ZSB0aGUgTWFwIGFzCi0gICAgICogdGhleSBhcmUgYWRkZWQuCi0gICAgICogQHBhcmFtIG51bUF0dHMKLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgc3dpdGNoT3ZlclRvSGFzaChpbnQgbnVtQXR0cykKLSAgICB7Ci0gICAgICAgIGZvciAoaW50IGluZGV4ID0gMDsgaW5kZXggPCBudW1BdHRzOyBpbmRleCsrKQotICAgICAgICB7Ci0gICAgICAgICAgICBTdHJpbmcgcU5hbWUgPSBzdXBlci5nZXRRTmFtZShpbmRleCk7Ci0gICAgICAgICAgICBJbnRlZ2VyIGkgPSBpbmRleDsKLSAgICAgICAgICAgIG1faW5kZXhGcm9tUU5hbWUucHV0KHFOYW1lLCBpKTsKLQotICAgICAgICAgICAgLy8gQWRkIHF1aWNrIGxvb2stdXAgdG8gZmluZCB3aXRoIHVyaS9sb2NhbCBuYW1lIHBhaXIKLSAgICAgICAgICAgIFN0cmluZyB1cmkgPSBzdXBlci5nZXRVUkkoaW5kZXgpOwotICAgICAgICAgICAgU3RyaW5nIGxvY2FsID0gc3VwZXIuZ2V0TG9jYWxOYW1lKGluZGV4KTsKLSAgICAgICAgICAgIG1fYnVmZi5zZXRMZW5ndGgoMCk7Ci0gICAgICAgICAgICBtX2J1ZmYuYXBwZW5kKCd7JykuYXBwZW5kKHVyaSkuYXBwZW5kKCd9JykuYXBwZW5kKGxvY2FsKTsKLSAgICAgICAgICAgIFN0cmluZyBrZXkgPSBtX2J1ZmYudG9TdHJpbmcoKTsKLSAgICAgICAgICAgIG1faW5kZXhGcm9tUU5hbWUucHV0KGtleSwgaSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBjbGVhcnMgdGhlIGFjY3VtdWxhdGVkIGF0dHJpYnV0ZXMuCi0gICAgICoKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LmhlbHBlcnMuQXR0cmlidXRlc0ltcGwjY2xlYXIoKQotICAgICAqLwotICAgIHB1YmxpYyBmaW5hbCB2b2lkIGNsZWFyKCkKLSAgICB7Ci0KLSAgICAgICAgaW50IGxlbiA9IHN1cGVyLmdldExlbmd0aCgpOwotICAgICAgICBzdXBlci5jbGVhcigpOwotICAgICAgICBpZiAoTUFYIDw9IGxlbikKLSAgICAgICAgewotICAgICAgICAgICAgLy8gaWYgd2UgaGF2ZSBoYWQgZW5vdWdoIGF0dHJpYnV0ZXMgYW5kIGFyZQotICAgICAgICAgICAgLy8gdXNpbmcgdGhlIE1hcCwgdGhlbiBjbGVhciB0aGUgTWFwIHRvby4KLSAgICAgICAgICAgIG1faW5kZXhGcm9tUU5hbWUuY2xlYXIoKTsKLSAgICAgICAgfQotCi0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2Qgc2V0cyB0aGUgYXR0cmlidXRlcywgcHJldmlvdXMgYXR0cmlidXRlcyBhcmUgY2xlYXJlZCwKLSAgICAgKiBpdCBhbHNvIGtlZXBzIHRoZSBoYXNodGFibGUgdXAgdG8gZGF0ZSBmb3IgcXVpY2sgbG9va3VwIHZpYQotICAgICAqIGdldEluZGV4KHFOYW1lKS4KLSAgICAgKiBAcGFyYW0gYXR0cyB0aGUgYXR0cmlidXRlcyB0byBjb3B5IGludG8gdGhlc2UgYXR0cmlidXRlcy4KLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LmhlbHBlcnMuQXR0cmlidXRlc0ltcGwjc2V0QXR0cmlidXRlcyhBdHRyaWJ1dGVzKQotICAgICAqIEBzZWUgI2dldEluZGV4KFN0cmluZykKLSAgICAgKi8KLSAgICBwdWJsaWMgZmluYWwgdm9pZCBzZXRBdHRyaWJ1dGVzKEF0dHJpYnV0ZXMgYXR0cykKLSAgICB7Ci0KLSAgICAgICAgc3VwZXIuc2V0QXR0cmlidXRlcyhhdHRzKTsKLQotICAgICAgICAvLyB3ZSd2ZSBsZXQgdGhlIHN1cGVyIGNsYXNzIGFkZCB0aGUgYXR0cmlidXRlcywgYnV0Ci0gICAgICAgIC8vIHdlIG5lZWQgdG8ga2VlcCB0aGUgaGFzaCB0YWJsZSB1cCB0byBkYXRlIG91cnNlbHZlcyBmb3IgdGhlCi0gICAgICAgIC8vIHBvdGVudGlhbGx5IG5ldyBxTmFtZS9pbmRleCBwYWlycyBmb3IgcXVpY2sgbG9va3VwLgotICAgICAgICBpbnQgbnVtQXR0cyA9IGF0dHMuZ2V0TGVuZ3RoKCk7Ci0gICAgICAgIGlmIChNQVggPD0gbnVtQXR0cykKLSAgICAgICAgICAgIHN3aXRjaE92ZXJUb0hhc2gobnVtQXR0cyk7Ci0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBnZXRzIHRoZSBpbmRleCBvZiBhbiBhdHRyaWJ1dGUgZ2l2ZW4gaXRzIHVyaSBhbmQgbG9jYW5OYW1lLgotICAgICAqIEBwYXJhbSB1cmkgdGhlIFVSSSBvZiB0aGUgYXR0cmlidXRlIG5hbWUuCi0gICAgICogQHBhcmFtIGxvY2FsTmFtZSB0aGUgbG9jYWwgbmFtZXIgKGFmdGVyIHRoZSAnOicgKSBvZiB0aGUgYXR0cmlidXRlIG5hbWUuCi0gICAgICogQHJldHVybiB0aGUgaW50ZWdlciBpbmRleCBvZiB0aGUgYXR0cmlidXRlLgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQXR0cmlidXRlcyNnZXRJbmRleChTdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIGludCBnZXRJbmRleChTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxOYW1lKQotICAgIHsKLSAgICAgICAgaW50IGluZGV4OwotCi0gICAgICAgIGlmIChzdXBlci5nZXRMZW5ndGgoKSA8IE1BWCkKLSAgICAgICAgewotICAgICAgICAgICAgLy8gaWYgd2UgaGF2ZW4ndCBnb3QgdG9vIG1hbnkgYXR0cmlidXRlcyBsZXQgdGhlCi0gICAgICAgICAgICAvLyBzdXBlciBjbGFzcyBsb29rIGl0IHVwCi0gICAgICAgICAgICBpbmRleCA9IHN1cGVyLmdldEluZGV4KHVyaSxsb2NhbE5hbWUpOwotICAgICAgICAgICAgcmV0dXJuIGluZGV4OwotICAgICAgICB9Ci0gICAgICAgIC8vIHdlIGhhdmUgdG9vIG1hbnkgYXR0cmlidXRlcyBhbmQgdGhlIHN1cGVyIGNsYXNzIGlzIHNsb3cKLSAgICAgICAgLy8gc28gZmluZCBpdCBxdWlja2x5IHVzaW5nIG91ciBNYXAuCi0gICAgICAgIC8vIEZvcm0gdGhlIGtleSBvZiBmb3JtYXQgInt1cml9bG9jYWxOYW1lIgotICAgICAgICBtX2J1ZmYuc2V0TGVuZ3RoKDApOwotICAgICAgICBtX2J1ZmYuYXBwZW5kKCd7JykuYXBwZW5kKHVyaSkuYXBwZW5kKCd9JykuYXBwZW5kKGxvY2FsTmFtZSk7Ci0gICAgICAgIFN0cmluZyBrZXkgPSBtX2J1ZmYudG9TdHJpbmcoKTsKLSAgICAgICAgSW50ZWdlciBpID0gbV9pbmRleEZyb21RTmFtZS5nZXQoa2V5KTsKLSAgICAgICAgaWYgKGkgPT0gbnVsbCkKLSAgICAgICAgICAgIGluZGV4ID0gLTE7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICAgIGluZGV4ID0gaTsKLSAgICAgICAgcmV0dXJuIGluZGV4OwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvQ2hhckluZm8uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvQ2hhckluZm8uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDRlNzdkNi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL0NoYXJJbmZvLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3NDYgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogQ2hhckluZm8uamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNSAwODoxNToxNCBzdXJlc2hfZW1haWxpZCBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC51dGlscy5TZWN1cml0eVN1cHBvcnQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyLnV0aWxzLk1zZ0tleTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXIudXRpbHMuU3lzdGVtSURSZXNvbHZlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXIudXRpbHMuVXRpbHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyLnV0aWxzLldyYXBwZWRSdW50aW1lRXhjZXB0aW9uOwotaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRSZWFkZXI7Ci1pbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKLWltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtUmVhZGVyOwotaW1wb3J0IGphdmEuaW8uVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLm5ldC5VUkw7Ci1pbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOwotaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwotaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7Ci1pbXBvcnQgamF2YS51dGlsLlByb3BlcnR5UmVzb3VyY2VCdW5kbGU7Ci1pbXBvcnQgamF2YS51dGlsLlJlc291cmNlQnVuZGxlOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci0KLS8qKgotICogVGhpcyBjbGFzcyBwcm92aWRlcyBzZXJ2aWNlcyB0aGF0IHRlbGwgaWYgYSBjaGFyYWN0ZXIgc2hvdWxkIGhhdmUKLSAqIHNwZWNpYWwgdHJlYXRlbWVudCwgc3VjaCBhcyBlbnRpdHkgcmVmZXJlbmNlIHN1YnN0aXR1dGlvbiBvciBub3JtYWxpemF0aW9uCi0gKiBvZiBhIG5ld2xpbmUgY2hhcmFjdGVyLiAgSXQgYWxzbyBwcm92aWRlcyBjaGFyYWN0ZXIgdG8gZW50aXR5IHJlZmVyZW5jZQotICogbG9va3VwLgotICoKLSAqIERFVkVMT1BFUlM6IFNlZSBLbm93biBJc3N1ZSBpbiB0aGUgY29uc3RydWN0b3IuCi0gKgotICogQHhzbC51c2FnZSBpbnRlcm5hbAotICovCi1maW5hbCBjbGFzcyBDaGFySW5mbwotewotICAgIC8qKiBHaXZlbiBhIGNoYXJhY3RlciwgbG9va3VwIGEgU3RyaW5nIHRvIG91dHB1dCAoZS5nLiBhIGRlY29yYXRlZCBlbnRpdHkgcmVmZXJlbmNlKS4gKi8KLSAgICBwcml2YXRlIEhhc2hNYXAgbV9jaGFyVG9TdHJpbmcgPSBuZXcgSGFzaE1hcCgpOwotCi0gICAgLyoqCi0gICAgICogVGhlIG5hbWUgb2YgdGhlIEhUTUwgZW50aXRpZXMgZmlsZS4KLSAgICAgKiBJZiBzcGVjaWZpZWQsIHRoZSBmaWxlIHdpbGwgYmUgcmVzb3VyY2UgbG9hZGVkIHdpdGggdGhlIGRlZmF1bHQgY2xhc3MgbG9hZGVyLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEhUTUxfRU5USVRJRVNfUkVTT1VSQ0UgPQotICAgICAgICAgICAgICAgICJjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXIuSFRNTEVudGl0aWVzIjsKLQotICAgIC8qKgotICAgICAqIFRoZSBuYW1lIG9mIHRoZSBYTUwgZW50aXRpZXMgZmlsZS4KLSAgICAgKiBJZiBzcGVjaWZpZWQsIHRoZSBmaWxlIHdpbGwgYmUgcmVzb3VyY2UgbG9hZGVkIHdpdGggdGhlIGRlZmF1bHQgY2xhc3MgbG9hZGVyLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFhNTF9FTlRJVElFU19SRVNPVVJDRSA9Ci0gICAgICAgICAgICAgICAgImNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplci5YTUxFbnRpdGllcyI7Ci0KLSAgICAvKiogVGhlIGhvcml6b250YWwgdGFiIGNoYXJhY3Rlciwgd2hpY2ggdGhlIHBhcnNlciBzaG91bGQgYWx3YXlzIG5vcm1hbGl6ZS4gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNoYXIgU19IT1JJWk9OQUxfVEFCID0gMHgwOTsKLQotICAgIC8qKiBUaGUgbGluZWZlZWQgY2hhcmFjdGVyLCB3aGljaCB0aGUgcGFyc2VyIHNob3VsZCBhbHdheXMgbm9ybWFsaXplLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2hhciBTX0xJTkVGRUVEID0gMHgwQTsKLQotICAgIC8qKiBUaGUgY2FycmlhZ2UgcmV0dXJuIGNoYXJhY3Rlciwgd2hpY2ggdGhlIHBhcnNlciBzaG91bGQgYWx3YXlzIG5vcm1hbGl6ZS4gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNoYXIgU19DQVJSSUFHRVJFVFVSTiA9IDB4MEQ7Ci0KLSAgICAvKiogVGhpcyBmbGFnIGlzIGFuIG9wdGltaXphdGlvbiBmb3IgSFRNTCBlbnRpdGllcy4gSXQgZmFsc2UgaWYgZW50aXRpZXMKLSAgICAgKiBvdGhlciB0aGFuIHF1b3QgKDM0KSwgYW1wICgzOCksIGx0ICg2MCkgYW5kIGd0ICg2MikgYXJlIGRlZmluZWQKLSAgICAgKiBpbiB0aGUgcmFuZ2UgMCB0byAxMjcuCi0gICAgICogQHhzbC51c2FnZSBpbnRlcm5hbAotICAgICAqLwotICAgIGZpbmFsIGJvb2xlYW4gb25seVF1b3RBbXBMdEd0OwotCi0gICAgLyoqIENvcHkgdGhlIGZpcnN0IDAsMSAuLi4gQVNDSUlfTUFYIHZhbHVlcyBpbnRvIGFuIGFycmF5ICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEFTQ0lJX01BWCA9IDEyODsKLQotICAgIC8qKiBBcnJheSBvZiB2YWx1ZXMgaXMgZmFzdGVyIGFjY2VzcyB0aGFuIGEgc2V0IG9mIGJpdHMKLSAgICAgKiB0byBxdWlja2x5IGNoZWNrIEFTQ0lJIGNoYXJhY3RlcnMgaW4gYXR0cmlidXRlIHZhbHVlcy4KLSAgICAgKi8KLSAgICBwcml2YXRlIGJvb2xlYW5bXSBpc1NwZWNpYWxBdHRyQVNDSUkgPSBuZXcgYm9vbGVhbltBU0NJSV9NQVhdOwotCi0gICAgLyoqIEFycmF5IG9mIHZhbHVlcyBpcyBmYXN0ZXIgYWNjZXNzIHRoYW4gYSBzZXQgb2YgYml0cwotICAgICAqIHRvIHF1aWNrbHkgY2hlY2sgQVNDSUkgY2hhcmFjdGVycyBpbiB0ZXh0IG5vZGVzLgotICAgICAqLwotICAgIHByaXZhdGUgYm9vbGVhbltdIGlzU3BlY2lhbFRleHRBU0NJSSA9IG5ldyBib29sZWFuW0FTQ0lJX01BWF07Ci0KLSAgICBwcml2YXRlIGJvb2xlYW5bXSBpc0NsZWFuVGV4dEFTQ0lJID0gbmV3IGJvb2xlYW5bQVNDSUlfTUFYXTsKLQotICAgIC8qKiBBbiBhcnJheSBvZiBiaXRzIHRvIHJlY29yZCBpZiB0aGUgY2hhcmFjdGVyIGlzIGluIHRoZSBzZXQuCi0gICAgICogQWx0aG91Z2ggaW5mb3JtYXRpb24gaW4gdGhpcyBhcnJheSBpcyBjb21wbGV0ZSwgdGhlCi0gICAgICogaXNTcGVjaWFsQXR0ckFTQ0lJIGFycmF5IGlzIHVzZWQgZmlyc3QgYmVjYXVzZSBhY2Nlc3MgdG8gaXRzIHZhbHVlcwotICAgICAqIGlzIGNvbW1vbiBhbmQgZmFzdGVyLgotICAgICAqLwotICAgIHByaXZhdGUgaW50IGFycmF5X29mX2JpdHNbXSA9IGNyZWF0ZUVtcHR5U2V0T2ZJbnRlZ2Vycyg2NTUzNSk7Ci0KLQotICAgIC8vIDUgZm9yIDMyIGJpdCB3b3JkcywgIDYgZm9yIDY0IGJpdCB3b3JkcyAuLi4KLSAgICAvKgotICAgICAqIFRoaXMgY29uc3RhbnQgaXMgdXNlZCB0byBzaGlmdCBhbiBpbnRlZ2VyIHRvIHF1aWNrbHkKLSAgICAgKiBjYWxjdWxhdGUgd2hpY2ggZWxlbWVudCBpdHMgYml0IGlzIHN0b3JlZCBpbi4KLSAgICAgKiA1IGZvciAzMiBiaXQgd29yZHMgKGludCkgLCAgNiBmb3IgNjQgYml0IHdvcmRzIChsb25nKQotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBTSElGVF9QRVJfV09SRCA9IDU7Ci0KLSAgICAvKgotICAgICAqIEEgbWFzayB0byBnZXQgdGhlIGxvdyBvcmRlciBiaXRzIHdoaWNoIGFyZSB1c2VkIHRvCi0gICAgICogY2FsY3VsYXRlIHRoZSB2YWx1ZSBvZiB0aGUgYml0IHdpdGhpbiBhIGdpdmVuIHdvcmQsCi0gICAgICogdGhhdCB3aWxsIHJlcHJlc2VudCB0aGUgcHJlc2VuY2Ugb2YgdGhlIGludGVnZXIgaW4gdGhlCi0gICAgICogc2V0LgotICAgICAqCi0gICAgICogMHgxRiBmb3IgMzIgYml0IHdvcmRzIChpbnQpLAotICAgICAqIG9yIDB4M0YgZm9yIDY0IGJpdCB3b3JkcyAobG9uZykKLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTE9XX09SREVSX0JJVE1BU0sgPSAweDFmOwotCi0gICAgLyoKLSAgICAgKiBUaGlzIGlzIHVzZWQgZm9yIG9wdGltaXppbmcgdGhlIGxvb2t1cCBvZiBiaXRzIHJlcHJlc2VudGluZwotICAgICAqIHRoZSBpbnRlZ2VycyBpbiB0aGUgc2V0LiBJdCBpcyB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IGVsZW1lbnQKLSAgICAgKiBpbiB0aGUgYXJyYXkgYXJyYXlfb2ZfYml0c1tdIHRoYXQgaXMgbm90IHVzZWQuCi0gICAgICovCi0gICAgcHJpdmF0ZSBpbnQgZmlyc3RXb3JkTm90VXNlZDsKLQotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0b3IgdGhhdCByZWFkcyBpbiBhIHJlc291cmNlIGZpbGUgdGhhdCBkZXNjcmliZXMgdGhlIG1hcHBpbmcgb2YKLSAgICAgKiBjaGFyYWN0ZXJzIHRvIGVudGl0eSByZWZlcmVuY2VzLgotICAgICAqIFRoaXMgY29uc3RydWN0b3IgaXMgcHJpdmF0ZSwganVzdCB0byBmb3JjZSB0aGUgdXNlCi0gICAgICogb2YgdGhlIGdldENoYXJJbmZvKGVudGl0aWVzUmVzb3VyY2UpIGZhY3RvcnkKLSAgICAgKgotICAgICAqIFJlc291cmNlIGZpbGVzIG11c3QgYmUgZW5jb2RlZCBpbiBVVEYtOCBhbmQgY2FuIGVpdGhlciBiZSBwcm9wZXJ0aWVzCi0gICAgICogZmlsZXMgd2l0aCBhIC5wcm9wZXJ0aWVzIGV4dGVuc2lvbiBhc3N1bWVkLiAgQWx0ZXJuYXRpdmVseSwgdGhleSBjYW4KLSAgICAgKiBoYXZlIHRoZSBmb2xsb3dpbmcgZm9ybSwgd2l0aCBubyBwYXJ0aWN1bGFyIGV4dGVuc2lvbiBhc3N1bWVkOgotICAgICAqCi0gICAgICogPHByZT4KLSAgICAgKiAjIEZpcnN0IGNoYXIgIyBpcyBhIGNvbW1lbnQKLSAgICAgKiBFbnRpdHkgbnVtZXJpY1ZhbHVlCi0gICAgICogcXVvdCAzNAotICAgICAqIGFtcCAzOAotICAgICAqIDwvcHJlPgotICAgICAqCi0gICAgICogQHBhcmFtIGVudGl0aWVzUmVzb3VyY2UgTmFtZSBvZiBwcm9wZXJ0aWVzIG9yIHJlc291cmNlIGZpbGUgdGhhdCBzaG91bGQKLSAgICAgKiBiZSBsb2FkZWQsIHdoaWNoIGRlc2NyaWJlcyB0aGF0IG1hcHBpbmcgb2YgY2hhcmFjdGVycyB0byBlbnRpdHkKLSAgICAgKiByZWZlcmVuY2VzLgotICAgICAqLwotICAgIHByaXZhdGUgQ2hhckluZm8oU3RyaW5nIGVudGl0aWVzUmVzb3VyY2UsIFN0cmluZyBtZXRob2QpCi0gICAgewotICAgICAgICB0aGlzKGVudGl0aWVzUmVzb3VyY2UsIG1ldGhvZCwgZmFsc2UpOwotICAgIH0KLQotICAgIHByaXZhdGUgQ2hhckluZm8oU3RyaW5nIGVudGl0aWVzUmVzb3VyY2UsIFN0cmluZyBtZXRob2QsIGJvb2xlYW4gaW50ZXJuYWwpCi0gICAgewotICAgICAgICBSZXNvdXJjZUJ1bmRsZSBlbnRpdGllcyA9IG51bGw7Ci0gICAgICAgIGJvb2xlYW4gbm9FeHRyYUVudGl0aWVzID0gdHJ1ZTsKLQotICAgICAgICAvLyBNYWtlIHZhcmlvdXMgYXR0ZW1wdHMgdG8gaW50ZXJwcmV0IHRoZSBwYXJhbWV0ZXIgYXMgYSBwcm9wZXJ0aWVzCi0gICAgICAgIC8vIGZpbGUgb3IgcmVzb3VyY2UgZmlsZSwgYXMgZm9sbG93czoKLSAgICAgICAgLy8KLSAgICAgICAgLy8gICAxKSBhdHRlbXB0IHRvIGxvYWQgLnByb3BlcnRpZXMgZmlsZSB1c2luZyBSZXNvdXJjZUJ1bmRsZQotICAgICAgICAvLyAgIDIpIHRyeSB1c2luZyB0aGUgY2xhc3MgbG9hZGVyIHRvIGZpbmQgdGhlIHNwZWNpZmllZCBmaWxlIGEgcmVzb3VyY2UKLSAgICAgICAgLy8gICAgICBmaWxlCi0gICAgICAgIC8vICAgMykgdHJ5IHRyZWF0aW5nIHRoZSByZXNvdXJjZSBhIFVSSQotCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBpZiAoaW50ZXJuYWwpIHsKLSAgICAgICAgICAgICAgICAvLyBMb2FkIGVudGl0eSBwcm9wZXJ0eSBmaWxlcyBieSB1c2luZyBQcm9wZXJ0eVJlc291cmNlQnVuZGxlLAotICAgICAgICAgICAgICAgIC8vIGNhdXNlIG9mIHNlY3VyaXR5IGlzc3VyZSBmb3IgYXBwbGV0cwotICAgICAgICAgICAgICAgIGVudGl0aWVzID0gUHJvcGVydHlSZXNvdXJjZUJ1bmRsZS5nZXRCdW5kbGUoZW50aXRpZXNSZXNvdXJjZSk7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIENsYXNzTG9hZGVyIGNsID0gU2VjdXJpdHlTdXBwb3J0LmdldENvbnRleHRDbGFzc0xvYWRlcigpOwotICAgICAgICAgICAgICAgIGlmIChjbCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGVudGl0aWVzID0gUHJvcGVydHlSZXNvdXJjZUJ1bmRsZS5nZXRCdW5kbGUoZW50aXRpZXNSZXNvdXJjZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBMb2NhbGUuZ2V0RGVmYXVsdCgpLCBjbCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkge30KLQotICAgICAgICBpZiAoZW50aXRpZXMgIT0gbnVsbCkgewotICAgICAgICAgICAgRW51bWVyYXRpb24ga2V5cyA9IGVudGl0aWVzLmdldEtleXMoKTsKLSAgICAgICAgICAgIHdoaWxlIChrZXlzLmhhc01vcmVFbGVtZW50cygpKXsKLSAgICAgICAgICAgICAgICBTdHJpbmcgbmFtZSA9IChTdHJpbmcpIGtleXMubmV4dEVsZW1lbnQoKTsKLSAgICAgICAgICAgICAgICBTdHJpbmcgdmFsdWUgPSBlbnRpdGllcy5nZXRTdHJpbmcobmFtZSk7Ci0gICAgICAgICAgICAgICAgaW50IGNvZGUgPSBJbnRlZ2VyLnBhcnNlSW50KHZhbHVlKTsKLSAgICAgICAgICAgICAgICBkZWZpbmVFbnRpdHkobmFtZSwgKGNoYXIpIGNvZGUpOwotICAgICAgICAgICAgICAgIGlmIChleHRyYUVudGl0eShjb2RlKSkKLSAgICAgICAgICAgICAgICAgICAgbm9FeHRyYUVudGl0aWVzID0gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBzZXQoU19MSU5FRkVFRCk7Ci0gICAgICAgICAgICBzZXQoU19DQVJSSUFHRVJFVFVSTik7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBJbnB1dFN0cmVhbSBpcyA9IG51bGw7Ci0gICAgICAgICAgICBTdHJpbmcgZXJyID0gbnVsbDsKLQotICAgICAgICAgICAgLy8gTG9hZCB1c2VyIHNwZWNpZmllZCByZXNvdXJjZSBmaWxlIGJ5IHVzaW5nIFVSTCBsb2FkaW5nLCBpdAotICAgICAgICAgICAgLy8gcmVxdWlyZXMgYSB2YWxpZCBVUkkgYXMgcGFyYW1ldGVyCi0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIGlmIChpbnRlcm5hbCkgewotICAgICAgICAgICAgICAgICAgICBpcyA9IENoYXJJbmZvLmNsYXNzLmdldFJlc291cmNlQXNTdHJlYW0oZW50aXRpZXNSZXNvdXJjZSk7Ci0gICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgQ2xhc3NMb2FkZXIgY2wgPSBTZWN1cml0eVN1cHBvcnQuZ2V0Q29udGV4dENsYXNzTG9hZGVyKCk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChjbCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzID0gY2wuZ2V0UmVzb3VyY2VBc1N0cmVhbShlbnRpdGllc1Jlc291cmNlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyID0gZS5nZXRNZXNzYWdlKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICBpZiAoaXMgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBVUkwgdXJsID0gbmV3IFVSTChlbnRpdGllc1Jlc291cmNlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpcyA9IHVybC5vcGVuU3RyZWFtKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVyciA9IGUuZ2V0TWVzc2FnZSgpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgaWYgKGlzID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgICAgICBVdGlscy5tZXNzYWdlcy5jcmVhdGVNZXNzYWdlKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1zZ0tleS5FUl9SRVNPVVJDRV9DT1VMRF9OT1RfRklORCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10ge2VudGl0aWVzUmVzb3VyY2UsIGVycn0pKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyBGaXggQnVnemlsbGEjNDAwMDogZm9yY2UgcmVhZGluZyBpbiBVVEYtOAotICAgICAgICAgICAgICAgIC8vICBUaGlzIGNyZWF0ZXMgdGhlIGRlIGZhY3RvIHN0YW5kYXJkIHRoYXQgWGFsYW4ncyByZXNvdXJjZQotICAgICAgICAgICAgICAgIC8vICBmaWxlcyBtdXN0IGJlIGVuY29kZWQgaW4gVVRGLTguIFRoaXMgc2hvdWxkIHdvcmsgaW4gYWxsCi0gICAgICAgICAgICAgICAgLy8gSlZNcy4KLSAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgIC8vICVSRVZJRVclIEtOT1dOIElTU1VFOiBJVCBGQUlMUyBJTiBNSUNST1NPRlQgVkorKywgd2hpY2gKLSAgICAgICAgICAgICAgICAvLyBkaWRuJ3QgaW1wbGVtZW50IHRoZSBVVEYtOCBlbmNvZGluZy4gVGhlb3JldGljYWxseSwgd2Ugc2hvdWxkCi0gICAgICAgICAgICAgICAgLy8gc2ltcGx5IGxldCBpdCBmYWlsIGluIHRoYXQgY2FzZSwgc2luY2UgdGhlIEpWTSBpcyBvYnZpb3VzbHkKLSAgICAgICAgICAgICAgICAvLyBicm9rZW4gaWYgaXQgZG9lc24ndCBzdXBwb3J0IHN1Y2ggYSBiYXNpYyBzdGFuZGFyZC4gIEJ1dAotICAgICAgICAgICAgICAgIC8vIHNpbmNlIHRoZXJlIGFyZSBzdGlsbCBzb21lIHVzZXJzIGF0dGVtcHRpbmcgdG8gdXNlIFZKKysgZm9yCi0gICAgICAgICAgICAgICAgLy8gZGV2ZWxvcG1lbnQsIHdlIGhhdmUgZHJvcHBlZCBpbiBhIGZhbGxiYWNrIHdoaWNoIG1ha2VzIGEKLSAgICAgICAgICAgICAgICAvLyBzZWNvbmQgYXR0ZW1wdCB1c2luZyB0aGUgcGxhdGZvcm0ncyBkZWZhdWx0IGVuY29kaW5nLiBJbiBWSisrCi0gICAgICAgICAgICAgICAgLy8gdGhpcyBpcyBhcHBhcmVudGx5IEFTQ0lJLCB3aGljaCBpcyBzdWJzZXQgb2YgVVRGLTguLi4gYW5kCi0gICAgICAgICAgICAgICAgLy8gc2luY2UgdGhlIHN0cmluZ3Mgd2UnbGwgYmUgcmVhZGluZyBoZXJlIGFyZSBhbHNvIHByaW1hcmlseQotICAgICAgICAgICAgICAgIC8vIGxpbWl0ZWQgdG8gdGhlIDctYml0IEFTQ0lJIHJhbmdlIChhdCBsZWFzdCwgaW4gRW5nbGlzaAotICAgICAgICAgICAgICAgIC8vIHZlcnNpb25zIG9mIFhhbGFuKSwgdGhpcyBzaG91bGQgd29yayB3ZWxsIGVub3VnaCB0byBrZWVwIHVzCi0gICAgICAgICAgICAgICAgLy8gb24gdGhlIGFpciB1bnRpbCB3ZSdyZSByZWFkeSB0byBvZmZpY2lhbGx5IGRlY29tbWl0IGZyb20KLSAgICAgICAgICAgICAgICAvLyBWSisrLgotCi0gICAgICAgICAgICAgICAgQnVmZmVyZWRSZWFkZXIgcmVhZGVyOwotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgIHJlYWRlciA9IG5ldyBCdWZmZXJlZFJlYWRlcihuZXcgSW5wdXRTdHJlYW1SZWFkZXIoaXMsICJVVEYtOCIpKTsKLSAgICAgICAgICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICAgICAgcmVhZGVyID0gbmV3IEJ1ZmZlcmVkUmVhZGVyKG5ldyBJbnB1dFN0cmVhbVJlYWRlcihpcykpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIFN0cmluZyBsaW5lID0gcmVhZGVyLnJlYWRMaW5lKCk7Ci0KLSAgICAgICAgICAgICAgICB3aGlsZSAobGluZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChsaW5lLmxlbmd0aCgpID09IDAgfHwgbGluZS5jaGFyQXQoMCkgPT0gJyMnKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBsaW5lID0gcmVhZGVyLnJlYWRMaW5lKCk7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgaW50IGluZGV4ID0gbGluZS5pbmRleE9mKCcgJyk7Ci0KLSAgICAgICAgICAgICAgICAgICAgaWYgKGluZGV4ID4gMSkgewotICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG5hbWUgPSBsaW5lLnN1YnN0cmluZygwLCBpbmRleCk7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICsraW5kZXg7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbmRleCA8IGxpbmUubGVuZ3RoKCkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdmFsdWUgPSBsaW5lLnN1YnN0cmluZyhpbmRleCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXggPSB2YWx1ZS5pbmRleE9mKCcgJyk7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5kZXggPiAwKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlID0gdmFsdWUuc3Vic3RyaW5nKDAsIGluZGV4KTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgY29kZSA9IEludGVnZXIucGFyc2VJbnQodmFsdWUpOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmaW5lRW50aXR5KG5hbWUsIChjaGFyKSBjb2RlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXh0cmFFbnRpdHkoY29kZSkpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vRXh0cmFFbnRpdGllcyA9IGZhbHNlOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgbGluZSA9IHJlYWRlci5yZWFkTGluZSgpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIGlzLmNsb3NlKCk7Ci0gICAgICAgICAgICAgICAgc2V0KFNfTElORUZFRUQpOwotICAgICAgICAgICAgICAgIHNldChTX0NBUlJJQUdFUkVUVVJOKTsKLSAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgIFV0aWxzLm1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoCi0gICAgICAgICAgICAgICAgICAgICAgICBNc2dLZXkuRVJfUkVTT1VSQ0VfQ09VTERfTk9UX0xPQUQsCi0gICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBlbnRpdGllc1Jlc291cmNlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZS50b1N0cmluZygpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW50aXRpZXNSZXNvdXJjZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGUudG9TdHJpbmcoKX0pKTsKLSAgICAgICAgICAgIH0gZmluYWxseSB7Ci0gICAgICAgICAgICAgICAgaWYgKGlzICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlzLmNsb3NlKCk7Ci0gICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleGNlcHQpIHt9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLyogaW5pdGlhbGl6ZSB0aGUgYXJyYXkgaXNDbGVhblRleHRBU0NJSVtdIHdpdGggYSBjYWNoZSBvZiB2YWx1ZXMKLSAgICAgICAgICogZm9yIHVzZSBieSBUb1N0cmVhbS5jaGFyYWN0ZXIoY2hhcltdLCBpbnQgLCBpbnQpCi0gICAgICAgICAqIGFuZCB0aGUgYXJyYXkgaXNTcGVjaWFsVGV4dEFTQ0lJW10gd2l0aCB0aGUgb3Bwb3NpdGUgdmFsdWVzCi0gICAgICAgICAqIChhbGwgaW4gdGhlIG5hbWUgb2YgcGVyZm9ybWFuY2UhKQotICAgICAgICAgKi8KLSAgICAgICAgZm9yIChpbnQgY2ggPSAwOyBjaCA8QVNDSUlfTUFYOyBjaCsrKQotICAgICAgICBpZigoKCgweDIwIDw9IGNoIHx8ICgweDBBID09IGNoIHx8IDB4MEQgPT0gY2ggfHwgMHgwOSA9PSBjaCkpKQotICAgICAgICAgICAgICYmICghZ2V0KGNoKSkpIHx8ICgnIicgPT0gY2gpKQotICAgICAgICB7Ci0gICAgICAgICAgICBpc0NsZWFuVGV4dEFTQ0lJW2NoXSA9IHRydWU7Ci0gICAgICAgICAgICBpc1NwZWNpYWxUZXh0QVNDSUlbY2hdID0gZmFsc2U7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBpc0NsZWFuVGV4dEFTQ0lJW2NoXSA9IGZhbHNlOwotICAgICAgICAgICAgaXNTcGVjaWFsVGV4dEFTQ0lJW2NoXSA9IHRydWU7Ci0gICAgICAgIH0KLQotCi0KLSAgICAgICAgb25seVF1b3RBbXBMdEd0ID0gbm9FeHRyYUVudGl0aWVzOwotCi0gICAgICAgIC8vIGluaXRpYWxpemUgdGhlIGFycmF5IHdpdGggYSBjYWNoZSBvZiB0aGUgQml0U2V0IHZhbHVlcwotICAgICAgICBmb3IgKGludCBpPTA7IGk8QVNDSUlfTUFYOyBpKyspCi0gICAgICAgICAgICBpc1NwZWNpYWxBdHRyQVNDSUlbaV0gPSBnZXQoaSk7Ci0KLSAgICAgICAgLyogTm93IHRoYXQgd2UndmUgdXNlZCBnZXQoY2gpIGp1c3QgYWJvdmUgdG8gaW5pdGlhbGl6ZSB0aGUKLSAgICAgICAgICogdHdvIGFycmF5cyB3ZSB3aWxsIGNoYW5nZSBieSBhZGRpbmcgYSB0YWIgdG8gdGhlIHNldCBvZgotICAgICAgICAgKiBzcGVjaWFsIGNoYXJzIGZvciBYTUwgKGJ1dCBub3QgSFRNTCEpLgotICAgICAgICAgKiBXZSBkbyB0aGlzIGJlY2F1c2UgYSB0YWIgaXMgYWx3YXlzIGEKLSAgICAgICAgICogc3BlY2lhbCBjaGFyYWN0ZXIgaW4gYW4gWE1MIGF0dHJpYnV0ZSwKLSAgICAgICAgICogYnV0IG9ubHkgYSBzcGVjaWFsIGNoYXJhY3RlciBpbiBYTUwgdGV4dAotICAgICAgICAgKiBpZiBpdCBoYXMgYW4gZW50aXR5IGRlZmluZWQgZm9yIGl0LgotICAgICAgICAgKiBUaGlzIGlzIHRoZSByZWFzb24gZm9yIHRoaXMgZGVsYXkuCi0gICAgICAgICAqLwotICAgICAgICBpZiAoTWV0aG9kLlhNTC5lcXVhbHMobWV0aG9kKSkKLSAgICAgICAgewotICAgICAgICAgICAgaXNTcGVjaWFsQXR0ckFTQ0lJW1NfSE9SSVpPTkFMX1RBQl0gPSB0cnVlOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRGVmaW5lcyBhIG5ldyBjaGFyYWN0ZXIgcmVmZXJlbmNlLiBUaGUgcmVmZXJlbmNlJ3MgbmFtZSBhbmQgdmFsdWUgYXJlCi0gICAgICogc3VwcGxpZWQuIE5vdGhpbmcgaGFwcGVucyBpZiB0aGUgY2hhcmFjdGVyIHJlZmVyZW5jZSBpcyBhbHJlYWR5IGRlZmluZWQuCi0gICAgICogPHA+VW5saWtlIGludGVybmFsIGVudGl0aWVzLCBjaGFyYWN0ZXIgcmVmZXJlbmNlcyBhcmUgYSBzdHJpbmcgdG8gc2luZ2xlCi0gICAgICogY2hhcmFjdGVyIG1hcHBpbmcuIFRoZXkgYXJlIHVzZWQgdG8gbWFwIG5vbi1BU0NJSSBjaGFyYWN0ZXJzIGJvdGggb24KLSAgICAgKiBwYXJzaW5nIGFuZCBwcmludGluZywgcHJpbWFyaWx5IGZvciBIVE1MIGRvY3VtZW50cy4gJyZsdDthbXA7JyBpcyBhbgotICAgICAqIGV4YW1wbGUgb2YgYSBjaGFyYWN0ZXIgcmVmZXJlbmNlLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBlbnRpdHkncyBuYW1lCi0gICAgICogQHBhcmFtIHZhbHVlIFRoZSBlbnRpdHkncyB2YWx1ZQotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCBkZWZpbmVFbnRpdHkoU3RyaW5nIG5hbWUsIGNoYXIgdmFsdWUpCi0gICAgewotICAgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoIiYiKTsKLSAgICAgICAgc2IuYXBwZW5kKG5hbWUpOwotICAgICAgICBzYi5hcHBlbmQoJzsnKTsKLSAgICAgICAgU3RyaW5nIGVudGl0eVN0cmluZyA9IHNiLnRvU3RyaW5nKCk7Ci0KLSAgICAgICAgZGVmaW5lQ2hhcjJTdHJpbmdNYXBwaW5nKGVudGl0eVN0cmluZywgdmFsdWUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIE1hcCBhIGNoYXJhY3RlciB0byBhIFN0cmluZy4gRm9yIGV4YW1wbGUgZ2l2ZW4KLSAgICAgKiB0aGUgY2hhcmFjdGVyICc+JyB0aGlzIG1ldGhvZCB3b3VsZCByZXR1cm4gdGhlIGZ1bGx5IGRlY29yYXRlZAotICAgICAqIGVudGl0eSBuYW1lICImbHQ7Ii4KLSAgICAgKiBTdHJpbmdzIGZvciBlbnRpdHkgcmVmZXJlbmNlcyBhcmUgbG9hZGVkIGZyb20gYSBwcm9wZXJ0aWVzIGZpbGUsCi0gICAgICogYnV0IGFkZGl0aW9uYWwgbWFwcGluZ3MgZGVmaW5lZCB0aHJvdWdoIGNhbGxzIHRvIGRlZmluZUNoYXIyU3RyaW5nKCkKLSAgICAgKiBhcmUgcG9zc2libGUuIFN1Y2ggZW50aXR5IHJlZmVyZW5jZSBtYXBwaW5ncyBjb3VsZCBiZSBvdmVyLXJpZGRlbi4KLSAgICAgKgotICAgICAqIFRoaXMgaXMgcmV1c2luZyBhIHN0b3JlZCBrZXkgb2JqZWN0LCBpbiBhbiBlZmZvcnQgdG8gYXZvaWQKLSAgICAgKiBoZWFwIGFjdGl2aXR5LiBVbmZvcnR1bmF0ZWx5LCB0aGF0IGludHJvZHVjZXMgYSB0aHJlYWRpbmcgcmlzay4KLSAgICAgKiBTaW1wbGVzdCBmaXggZm9yIG5vdyBpcyB0byBtYWtlIGl0IGEgc3luY2hyb25pemVkIG1ldGhvZCwgb3IgdG8gZ2l2ZQotICAgICAqIHVwIHRoZSByZXVzZTsgSSBzZWUgdmVyeSBsaXR0bGUgcGVyZm9ybWFuY2UgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZW0uCi0gICAgICogTG9uZy10ZXJtIHNvbHV0aW9uIHdvdWxkIGJlIHRvIHJlcGxhY2UgdGhlIGhhc2h0YWJsZSB3aXRoIGEgc3BhcnNlIGFycmF5Ci0gICAgICoga2V5ZWQgZGlyZWN0bHkgZnJvbSB0aGUgY2hhcmFjdGVyJ3MgaW50ZWdlciB2YWx1ZTsgc2VlIERUTSdzCi0gICAgICogc3RyaW5nIHBvb2wgZm9yIGEgcmVsYXRlZCBzb2x1dGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgY2hhcmFjdGVyIHRoYXQgc2hvdWxkIGJlIHJlc29sdmVkIHRvCi0gICAgICogYSBTdHJpbmcsIGUuZy4gcmVzb2x2ZSAnPicgdG8gICImbHQ7Ii4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIFN0cmluZyB0aGF0IHRoZSBjaGFyYWN0ZXIgaXMgbWFwcGVkIHRvLCBvciBudWxsIGlmIG5vdCBmb3VuZC4KLSAgICAgKiBAeHNsLnVzYWdlIGludGVybmFsCi0gICAgICovCi0gICAgU3RyaW5nIGdldE91dHB1dFN0cmluZ0ZvckNoYXIoY2hhciB2YWx1ZSkKLSAgICB7Ci0gICAgICAgIENoYXJLZXkgY2hhcktleSA9IG5ldyBDaGFyS2V5KCk7Ci0gICAgICAgIGNoYXJLZXkuc2V0Q2hhcih2YWx1ZSk7Ci0gICAgICAgIHJldHVybiAoU3RyaW5nKSBtX2NoYXJUb1N0cmluZy5nZXQoY2hhcktleSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGVsbCBpZiB0aGUgY2hhcmFjdGVyIGFyZ3VtZW50IHRoYXQgaXMgZnJvbQotICAgICAqIGFuIGF0dHJpYnV0ZSB2YWx1ZSBzaG91bGQgaGF2ZSBzcGVjaWFsIHRyZWF0bWVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSB2YWx1ZSB0aGUgdmFsdWUgb2YgYSBjaGFyYWN0ZXIgdGhhdCBpcyBpbiBhbiBhdHRyaWJ1dGUgdmFsdWUKLSAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGNoYXJhY3RlciBzaG91bGQgaGF2ZSBhbnkgc3BlY2lhbCB0cmVhdG1lbnQsCi0gICAgICogc3VjaCBhcyB3aGVuIHdyaXRpbmcgb3V0IGF0dHJpYnV0ZSB2YWx1ZXMsCi0gICAgICogb3IgZW50aXR5IHJlZmVyZW5jZXMuCi0gICAgICogQHhzbC51c2FnZSBpbnRlcm5hbAotICAgICAqLwotICAgIGZpbmFsIGJvb2xlYW4gaXNTcGVjaWFsQXR0ckNoYXIoaW50IHZhbHVlKQotICAgIHsKLSAgICAgICAgLy8gZm9yIHBlcmZvcm1hbmNlIHRyeSB0aGUgdmFsdWVzIGluIHRoZSBib29sZWFuIGFycmF5IGZpcnN0LAotICAgICAgICAvLyB0aGlzIGlzIGZhc3RlciBhY2Nlc3MgdGhhbiB0aGUgQml0U2V0IGZvciBjb21tb24gQVNDSUkgdmFsdWVzCi0KLSAgICAgICAgaWYgKHZhbHVlIDwgQVNDSUlfTUFYKQotICAgICAgICAgICAgcmV0dXJuIGlzU3BlY2lhbEF0dHJBU0NJSVt2YWx1ZV07Ci0KLSAgICAgICAgLy8gcmF0aGVyIHRoYW4gamF2YS51dGlsLkJpdFNldCwgb3VyIHByaXZhdGUKLSAgICAgICAgLy8gaW1wbGVtZW50YXRpb24gaXMgZmFzdGVyIChhbmQgbGVzcyBnZW5lcmFsKS4KLSAgICAgICAgcmV0dXJuIGdldCh2YWx1ZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGVsbCBpZiB0aGUgY2hhcmFjdGVyIGFyZ3VtZW50IHRoYXQgaXMgZnJvbSBhCi0gICAgICogdGV4dCBub2RlIHNob3VsZCBoYXZlIHNwZWNpYWwgdHJlYXRtZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIHZhbHVlIHRoZSB2YWx1ZSBvZiBhIGNoYXJhY3RlciB0aGF0IGlzIGluIGEgdGV4dCBub2RlCi0gICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBjaGFyYWN0ZXIgc2hvdWxkIGhhdmUgYW55IHNwZWNpYWwgdHJlYXRtZW50LAotICAgICAqIHN1Y2ggYXMgd2hlbiB3cml0aW5nIG91dCBhdHRyaWJ1dGUgdmFsdWVzLAotICAgICAqIG9yIGVudGl0eSByZWZlcmVuY2VzLgotICAgICAqIEB4c2wudXNhZ2UgaW50ZXJuYWwKLSAgICAgKi8KLSAgICBmaW5hbCBib29sZWFuIGlzU3BlY2lhbFRleHRDaGFyKGludCB2YWx1ZSkKLSAgICB7Ci0gICAgICAgIC8vIGZvciBwZXJmb3JtYW5jZSB0cnkgdGhlIHZhbHVlcyBpbiB0aGUgYm9vbGVhbiBhcnJheSBmaXJzdCwKLSAgICAgICAgLy8gdGhpcyBpcyBmYXN0ZXIgYWNjZXNzIHRoYW4gdGhlIEJpdFNldCBmb3IgY29tbW9uIEFTQ0lJIHZhbHVlcwotCi0gICAgICAgIGlmICh2YWx1ZSA8IEFTQ0lJX01BWCkKLSAgICAgICAgICAgIHJldHVybiBpc1NwZWNpYWxUZXh0QVNDSUlbdmFsdWVdOwotCi0gICAgICAgIC8vIHJhdGhlciB0aGFuIGphdmEudXRpbC5CaXRTZXQsIG91ciBwcml2YXRlCi0gICAgICAgIC8vIGltcGxlbWVudGF0aW9uIGlzIGZhc3RlciAoYW5kIGxlc3MgZ2VuZXJhbCkuCi0gICAgICAgIHJldHVybiBnZXQodmFsdWUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIGlzIHVzZWQgdG8gZGV0ZXJtaW5lIGlmIGFuIEFTQ0lJIGNoYXJhY3RlciBpbgotICAgICAqIGEgdGV4dCBub2RlIChub3QgYW4gYXR0cmlidXRlIHZhbHVlKSBpcyAiY2xlYW4iLgotICAgICAqIEBwYXJhbSB2YWx1ZSB0aGUgY2hhcmFjdGVyIHRvIGNoZWNrICgwIHRvIDEyNykuCi0gICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBjaGFyYWN0ZXIgY2FuIGdvIHRvIHRoZSB3cml0ZXIgYXMtaXMKLSAgICAgKiBAeHNsLnVzYWdlIGludGVybmFsCi0gICAgICovCi0gICAgZmluYWwgYm9vbGVhbiBpc1RleHRBU0NJSUNsZWFuKGludCB2YWx1ZSkKLSAgICB7Ci0gICAgICAgIHJldHVybiBpc0NsZWFuVGV4dEFTQ0lJW3ZhbHVlXTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFJlYWQgYW4gaW50ZXJuYWwgcmVzb3VyY2UgZmlsZSB0aGF0IGRlc2NyaWJlcyB0aGUgbWFwcGluZyBvZgotICAgICAqIGNoYXJhY3RlcnMgdG8gZW50aXR5IHJlZmVyZW5jZXM7IENvbnN0cnVjdCBhIENoYXJJbmZvIG9iamVjdC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlbnRpdGllc0ZpbGVOYW1lIE5hbWUgb2YgZW50aXRpZXMgcmVzb3VyY2UgZmlsZSB0aGF0IHNob3VsZAotICAgICAqIGJlIGxvYWRlZCwgd2hpY2ggZGVzY3JpYmVzIHRoZSBtYXBwaW5nIG9mIGNoYXJhY3RlcnMgdG8gZW50aXR5IHJlZmVyZW5jZXMuCi0gICAgICogQHBhcmFtIG1ldGhvZCB0aGUgb3V0cHV0IG1ldGhvZCB0eXBlLCB3aGljaCBzaG91bGQgYmUgb25lIG9mICJ4bWwiLCAiaHRtbCIsIGFuZCAidGV4dCIuCi0gICAgICogQHJldHVybiBhbiBpbnN0YW5jZSBvZiBDaGFySW5mbwotICAgICAqCi0gICAgICogQHhzbC51c2FnZSBpbnRlcm5hbAotICAgICAqLwotICAgIHN0YXRpYyBDaGFySW5mbyBnZXRDaGFySW5mb0ludGVybmFsKFN0cmluZyBlbnRpdGllc0ZpbGVOYW1lLCBTdHJpbmcgbWV0aG9kKQotICAgIHsKLSAgICAgICAgQ2hhckluZm8gY2hhckluZm8gPSAoQ2hhckluZm8pIG1fZ2V0Q2hhckluZm9DYWNoZS5nZXQoZW50aXRpZXNGaWxlTmFtZSk7Ci0gICAgICAgIGlmIChjaGFySW5mbyAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gY2hhckluZm87Ci0gICAgICAgIH0KLQotICAgICAgICBjaGFySW5mbyA9IG5ldyBDaGFySW5mbyhlbnRpdGllc0ZpbGVOYW1lLCBtZXRob2QsIHRydWUpOwotICAgICAgICBtX2dldENoYXJJbmZvQ2FjaGUucHV0KGVudGl0aWVzRmlsZU5hbWUsIGNoYXJJbmZvKTsKLSAgICAgICAgcmV0dXJuIGNoYXJJbmZvOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHMgYSBDaGFySW5mbyBvYmplY3QgdXNpbmcgdGhlIGZvbGxvd2luZyBwcm9jZXNzIHRvIHRyeSByZWFkaW5nCi0gICAgICogdGhlIGVudGl0aWVzRmlsZU5hbWUgcGFyYW1ldGVyOgotICAgICAqCi0gICAgICogICAxKSBhdHRlbXB0IHRvIGxvYWQgaXQgYXMgYSBSZXNvdXJjZUJ1bmRsZQotICAgICAqICAgMikgdHJ5IHVzaW5nIHRoZSBjbGFzcyBsb2FkZXIgdG8gZmluZCB0aGUgc3BlY2lmaWVkIGZpbGUKLSAgICAgKiAgIDMpIHRyeSBvcGVuaW5nIGl0IGFzIGFuIFVSSQotICAgICAqCi0gICAgICogSW4gY2FzZSBvZiAyIGFuZCAzLCB0aGUgcmVzb3VyY2UgZmlsZSBtdXN0IGJlIGVuY29kZWQgaW4gVVRGLTggYW5kIGhhdmUgdGhlCi0gICAgICogZm9sbG93aW5nIGZvcm1hdDoKLSAgICAgKiA8cHJlPgotICAgICAqICMgRmlyc3QgY2hhciAjIGlzIGEgY29tbWVudAotICAgICAqIEVudGl0eSBudW1lcmljVmFsdWUKLSAgICAgKiBxdW90IDM0Ci0gICAgICogYW1wIDM4Ci0gICAgICogPC9wcmU+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gZW50aXRpZXNGaWxlTmFtZSBOYW1lIG9mIGVudGl0aWVzIHJlc291cmNlIGZpbGUgdGhhdCBzaG91bGQKLSAgICAgKiBiZSBsb2FkZWQsIHdoaWNoIGRlc2NyaWJlcyB0aGUgbWFwcGluZyBvZiBjaGFyYWN0ZXJzIHRvIGVudGl0eSByZWZlcmVuY2VzLgotICAgICAqIEBwYXJhbSBtZXRob2QgdGhlIG91dHB1dCBtZXRob2QgdHlwZSwgd2hpY2ggc2hvdWxkIGJlIG9uZSBvZiAieG1sIiwgImh0bWwiLCBhbmQgInRleHQiLgotICAgICAqIEByZXR1cm4gYW4gaW5zdGFuY2Ugb2YgQ2hhckluZm8KLSAgICAgKi8KLSAgICBzdGF0aWMgQ2hhckluZm8gZ2V0Q2hhckluZm8oU3RyaW5nIGVudGl0aWVzRmlsZU5hbWUsIFN0cmluZyBtZXRob2QpCi0gICAgewotICAgICAgICB0cnkgewotICAgICAgICAgICAgcmV0dXJuIG5ldyBDaGFySW5mbyhlbnRpdGllc0ZpbGVOYW1lLCBtZXRob2QsIGZhbHNlKTsKLSAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHt9Ci0KLSAgICAgICAgU3RyaW5nIGFic29sdXRlRW50aXRpZXNGaWxlTmFtZTsKLQotICAgICAgICBpZiAoZW50aXRpZXNGaWxlTmFtZS5pbmRleE9mKCc6JykgPCAwKSB7Ci0gICAgICAgICAgICBhYnNvbHV0ZUVudGl0aWVzRmlsZU5hbWUgPQotICAgICAgICAgICAgICAgIFN5c3RlbUlEUmVzb2x2ZXIuZ2V0QWJzb2x1dGVVUklGcm9tUmVsYXRpdmUoZW50aXRpZXNGaWxlTmFtZSk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIGFic29sdXRlRW50aXRpZXNGaWxlTmFtZSA9Ci0gICAgICAgICAgICAgICAgICAgIFN5c3RlbUlEUmVzb2x2ZXIuZ2V0QWJzb2x1dGVVUkkoZW50aXRpZXNGaWxlTmFtZSwgbnVsbCk7Ci0gICAgICAgICAgICB9IGNhdGNoIChUcmFuc2Zvcm1lckV4Y2VwdGlvbiB0ZSkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBXcmFwcGVkUnVudGltZUV4Y2VwdGlvbih0ZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gbmV3IENoYXJJbmZvKGFic29sdXRlRW50aXRpZXNGaWxlTmFtZSwgbWV0aG9kLCBmYWxzZSk7Ci0gICAgfQotCi0gICAgLyoqIFRhYmxlIG9mIHVzZXItc3BlY2lmaWVkIGNoYXIgaW5mb3MuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgSGFzaE1hcCBtX2dldENoYXJJbmZvQ2FjaGUgPSBuZXcgSGFzaE1hcCgpOwotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgYXJyYXkgZWxlbWVudCBob2xkaW5nIHRoZSBiaXQgdmFsdWUgZm9yIHRoZQotICAgICAqIGdpdmVuIGludGVnZXIKLSAgICAgKiBAcGFyYW0gaSB0aGUgaW50ZWdlciB0aGF0IG1pZ2h0IGJlIGluIHRoZSBzZXQgb2YgaW50ZWdlcnMKLSAgICAgKgotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIGludCBhcnJheUluZGV4KGludCBpKSB7Ci0gICAgICAgIHJldHVybiAoaSA+PiBTSElGVF9QRVJfV09SRCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRm9yIGEgZ2l2ZW4gaW50ZWdlciBpbiB0aGUgc2V0IGl0IHJldHVybnMgdGhlIHNpbmdsZSBiaXQKLSAgICAgKiB2YWx1ZSB1c2VkIHdpdGhpbiBhIGdpdmVuIHdvcmQgdGhhdCByZXByZXNlbnRzIHdoZXRoZXIKLSAgICAgKiB0aGUgaW50ZWdlciBpcyBpbiB0aGUgc2V0IG9yIG5vdC4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBpbnQgYml0KGludCBpKSB7Ci0gICAgICAgIGludCByZXQgPSAoMSA8PCAoaSAmIExPV19PUkRFUl9CSVRNQVNLKSk7Ci0gICAgICAgIHJldHVybiByZXQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlcyBhIG5ldyBlbXB0eSBzZXQgb2YgaW50ZWdlcnMgKGNoYXJhY3RlcnMpCi0gICAgICogQHBhcmFtIG1heCB0aGUgbWF4aW11bSBpbnRlZ2VyIHRvIGJlIGluIHRoZSBzZXQuCi0gICAgICovCi0gICAgcHJpdmF0ZSBpbnRbXSBjcmVhdGVFbXB0eVNldE9mSW50ZWdlcnMoaW50IG1heCkgewotICAgICAgICBmaXJzdFdvcmROb3RVc2VkID0gMDsgLy8gYW4gb3B0aW1pemF0aW9uCi0KLSAgICAgICAgaW50W10gYXJyID0gbmV3IGludFthcnJheUluZGV4KG1heCAtIDEpICsgMV07Ci0gICAgICAgICAgICByZXR1cm4gYXJyOwotCi0gICAgfQotCi0gICAgLyoqCi0gICAgICogQWRkcyB0aGUgaW50ZWdlciAoY2hhcmFjdGVyKSB0byB0aGUgc2V0IG9mIGludGVnZXJzLgotICAgICAqIEBwYXJhbSBpIHRoZSBpbnRlZ2VyIHRvIGFkZCB0byB0aGUgc2V0LCB2YWxpZCB2YWx1ZXMgYXJlCi0gICAgICogMCwgMSwgMiAuLi4gdXAgdG8gdGhlIG1heGltdW0gdGhhdCB3YXMgc3BlY2lmaWVkIGF0Ci0gICAgICogdGhlIGNyZWF0aW9uIG9mIHRoZSBzZXQuCi0gICAgICovCi0gICAgcHJpdmF0ZSBmaW5hbCB2b2lkIHNldChpbnQgaSkgewotICAgICAgICBzZXRBU0NJSWRpcnR5KGkpOwotCi0gICAgICAgIGludCBqID0gKGkgPj4gU0hJRlRfUEVSX1dPUkQpOyAvLyB0aGlzIHdvcmQgaXMgdXNlZAotICAgICAgICBpbnQgayA9IGogKyAxOwotCi0gICAgICAgIGlmKGZpcnN0V29yZE5vdFVzZWQgPCBrKSAvLyBmb3Igb3B0aW1pemF0aW9uIHB1cnBvc2VzLgotICAgICAgICAgICAgZmlyc3RXb3JkTm90VXNlZCA9IGs7Ci0KLSAgICAgICAgYXJyYXlfb2ZfYml0c1tqXSB8PSAoMSA8PCAoaSAmIExPV19PUkRFUl9CSVRNQVNLKSk7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdHJ1ZSBpZiB0aGUgaW50ZWdlciAoY2hhcmFjdGVyKWlzIGluIHRoZSBzZXQgb2YgaW50ZWdlcnMuCi0gICAgICoKLSAgICAgKiBUaGlzIGltcGxlbWVudGF0aW9uIHVzZXMgYW4gYXJyYXkgb2YgaW50ZWdlcnMgd2l0aCAzMiBiaXRzIHBlcgotICAgICAqIGludGVnZXIuICBJZiBhIGJpdCBpcyBzZXQgdG8gMSB0aGUgY29ycmVzcG9uZGluZyBpbnRlZ2VyIGlzCi0gICAgICogaW4gdGhlIHNldCBvZiBpbnRlZ2Vycy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBpIGFuIGludGVnZXIgdGhhdCBpcyB0ZXN0ZWQgdG8gc2VlIGlmIGl0IGlzIHRoZQotICAgICAqIHNldCBvZiBpbnRlZ2Vycywgb3Igbm90LgotICAgICAqLwotICAgIHByaXZhdGUgZmluYWwgYm9vbGVhbiBnZXQoaW50IGkpIHsKLQotICAgICAgICBib29sZWFuIGluX3RoZV9zZXQgPSBmYWxzZTsKLSAgICAgICAgaW50IGogPSAoaSA+PiBTSElGVF9QRVJfV09SRCk7IC8vIHdvcmRJbmRleChpKQotICAgICAgICAvLyBhbiBvcHRpbWl6YXRpb24gaGVyZSwgLi4uIGEgcXVpY2sgdGVzdCB0byBzZWUKLSAgICAgICAgLy8gaWYgdGhpcyBpbnRlZ2VyIGlzIGJleW9uZCBhbnkgb2YgdGhlIHdvcmRzIGluIHVzZQotICAgICAgICBpZihqIDwgZmlyc3RXb3JkTm90VXNlZCkKLSAgICAgICAgICAgIGluX3RoZV9zZXQgPSAoYXJyYXlfb2ZfYml0c1tqXSAmCi0gICAgICAgICAgICAgICAgICAgICAgICAgICgxIDw8IChpICYgTE9XX09SREVSX0JJVE1BU0spKQotICAgICAgICAgICAgKSAhPSAwOyAgLy8gMEwgZm9yIDY0IGJpdCB3b3JkcwotICAgICAgICByZXR1cm4gaW5fdGhlX3NldDsKLSAgICB9Ci0KLSAgICAvLyByZWNvcmQgaWYgdGhlcmUgYXJlIGFueSBlbnRpdGllcyBvdGhlciB0aGFuCi0gICAgLy8gcXVvdCwgYW1wLCBsdCwgZ3QgIChwcm9iYWJseSB1c2VyIGRlZmluZWQpCi0gICAgLyoqCi0gICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBlbnRpdHkKLSAgICAgKiBAcGFyYW0gY29kZSBUaGUgdmFsdWUgb2YgdGhlIGNoYXJhY3RlciB0aGF0IGhhcyBhbiBlbnRpdHkgZGVmaW5lZAotICAgICAqIGZvciBpdC4KLSAgICAgKi8KLSAgICBwcml2YXRlIGJvb2xlYW4gZXh0cmFFbnRpdHkoaW50IGVudGl0eVZhbHVlKQotICAgIHsKLSAgICAgICAgYm9vbGVhbiBleHRyYSA9IGZhbHNlOwotICAgICAgICBpZiAoZW50aXR5VmFsdWUgPCAxMjgpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHN3aXRjaCAoZW50aXR5VmFsdWUpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgY2FzZSAzNCA6IC8vIHF1b3QKLSAgICAgICAgICAgICAgICBjYXNlIDM4IDogLy8gYW1wCi0gICAgICAgICAgICAgICAgY2FzZSA2MCA6IC8vIGx0Ci0gICAgICAgICAgICAgICAgY2FzZSA2MiA6IC8vIGd0Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGRlZmF1bHQgOiAvLyBvdGhlciBlbnRpdHkgaW4gcmFuZ2UgMCB0byAxMjcKLSAgICAgICAgICAgICAgICAgICAgZXh0cmEgPSB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBleHRyYTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJZiB0aGUgY2hhcmFjdGVyIGlzIGEgcHJpbnRhYmxlIEFTQ0lJIGNoYXJhY3RlciB0aGVuCi0gICAgICogbWFyayBpdCBhcyBub3QgY2xlYW4gYW5kIG5lZWRpbmcgcmVwbGFjZW1lbnQgd2l0aAotICAgICAqIGEgU3RyaW5nIG9uIG91dHB1dC4KLSAgICAgKiBAcGFyYW0gY2gKLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgc2V0QVNDSUlkaXJ0eShpbnQgaikKLSAgICB7Ci0gICAgICAgIGlmICgwIDw9IGogJiYgaiA8IEFTQ0lJX01BWCkKLSAgICAgICAgewotICAgICAgICAgICAgaXNDbGVhblRleHRBU0NJSVtqXSA9IGZhbHNlOwotICAgICAgICAgICAgaXNTcGVjaWFsVGV4dEFTQ0lJW2pdID0gdHJ1ZTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIElmIHRoZSBjaGFyYWN0ZXIgaXMgYSBwcmludGFibGUgQVNDSUkgY2hhcmFjdGVyIHRoZW4KLSAgICAgKiBtYXJrIGl0IGFzIGFuZCBub3QgbmVlZGluZyByZXBsYWNlbWVudCB3aXRoCi0gICAgICogYSBTdHJpbmcgb24gb3V0cHV0LgotICAgICAqIEBwYXJhbSBjaAotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCBzZXRBU0NJSWNsZWFuKGludCBqKQotICAgIHsKLSAgICAgICAgaWYgKDAgPD0gaiAmJiBqIDwgQVNDSUlfTUFYKQotICAgICAgICB7Ci0gICAgICAgICAgICBpc0NsZWFuVGV4dEFTQ0lJW2pdID0gdHJ1ZTsKLSAgICAgICAgICAgIGlzU3BlY2lhbFRleHRBU0NJSVtqXSA9IGZhbHNlOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIGRlZmluZUNoYXIyU3RyaW5nTWFwcGluZyhTdHJpbmcgb3V0cHV0U3RyaW5nLCBjaGFyIGlucHV0Q2hhcikKLSAgICB7Ci0gICAgICAgIENoYXJLZXkgY2hhcmFjdGVyID0gbmV3IENoYXJLZXkoaW5wdXRDaGFyKTsKLSAgICAgICAgbV9jaGFyVG9TdHJpbmcucHV0KGNoYXJhY3Rlciwgb3V0cHV0U3RyaW5nKTsKLSAgICAgICAgc2V0KGlucHV0Q2hhcik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2ltcGxlIGNsYXNzIGZvciBmYXN0IGxvb2t1cCBvZiBjaGFyIHZhbHVlcywgd2hlbiB1c2VkIHdpdGgKLSAgICAgKiBoYXNodGFibGVzLiAgWW91IGNhbiBzZXQgdGhlIGNoYXIsIHRoZW4gdXNlIGl0IGFzIGEga2V5LgotICAgICAqCi0gICAgICogVGhpcyBjbGFzcyBpcyBhIGNvcHkgb2YgdGhlIG9uZSBpbiBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLgotICAgICAqIEl0IGV4aXN0cyB0byBjdXQgdGhlIHNlcmlhbGl6ZXJzIGRlcGVuZGFuY3kgb24gdGhhdCBwYWNrYWdlLgotICAgICAqCi0gICAgICogQHhzbC51c2FnZSBpbnRlcm5hbAotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIENoYXJLZXkgZXh0ZW5kcyBPYmplY3QKLSAgICB7Ci0KLSAgICAgIC8qKiBTdHJpbmcgdmFsdWUgICAgICAgICAgKi8KLSAgICAgIHByaXZhdGUgY2hhciBtX2NoYXI7Ci0KLSAgICAgIC8qKgotICAgICAgICogQ29uc3RydWN0b3IgQ2hhcktleQotICAgICAgICoKLSAgICAgICAqIEBwYXJhbSBrZXkgY2hhciB2YWx1ZSBvZiB0aGlzIG9iamVjdC4KLSAgICAgICAqLwotICAgICAgcHVibGljIENoYXJLZXkoY2hhciBrZXkpCi0gICAgICB7Ci0gICAgICAgIG1fY2hhciA9IGtleTsKLSAgICAgIH0KLQotICAgICAgLyoqCi0gICAgICAgKiBEZWZhdWx0IGNvbnN0cnVjdG9yIGZvciBhIENoYXJLZXkuCi0gICAgICAgKgotICAgICAgICogQHBhcmFtIGtleSBjaGFyIHZhbHVlIG9mIHRoaXMgb2JqZWN0LgotICAgICAgICovCi0gICAgICBwdWJsaWMgQ2hhcktleSgpCi0gICAgICB7Ci0gICAgICB9Ci0KLSAgICAgIC8qKgotICAgICAgICogR2V0IHRoZSBoYXNoIHZhbHVlIG9mIHRoZSBjaGFyYWN0ZXIuCi0gICAgICAgKgotICAgICAgICogQHJldHVybiBoYXNoIHZhbHVlIG9mIHRoZSBjaGFyYWN0ZXIuCi0gICAgICAgKi8KLSAgICAgIHB1YmxpYyBmaW5hbCB2b2lkIHNldENoYXIoY2hhciBjKQotICAgICAgewotICAgICAgICBtX2NoYXIgPSBjOwotICAgICAgfQotCi0KLQotICAgICAgLyoqCi0gICAgICAgKiBHZXQgdGhlIGhhc2ggdmFsdWUgb2YgdGhlIGNoYXJhY3Rlci4KLSAgICAgICAqCi0gICAgICAgKiBAcmV0dXJuIGhhc2ggdmFsdWUgb2YgdGhlIGNoYXJhY3Rlci4KLSAgICAgICAqLwotICAgICAgcHVibGljIGZpbmFsIGludCBoYXNoQ29kZSgpCi0gICAgICB7Ci0gICAgICAgIHJldHVybiAoaW50KW1fY2hhcjsKLSAgICAgIH0KLQotICAgICAgLyoqCi0gICAgICAgKiBPdmVycmlkZSBvZiBlcXVhbHMoKSBmb3IgdGhpcyBvYmplY3QKLSAgICAgICAqCi0gICAgICAgKiBAcGFyYW0gb2JqIHRvIGNvbXBhcmUgdG8KLSAgICAgICAqCi0gICAgICAgKiBAcmV0dXJuIFRydWUgaWYgdGhpcyBvYmplY3QgZXF1YWxzIHRoaXMgc3RyaW5nIHZhbHVlCi0gICAgICAgKi8KLSAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqKQotICAgICAgewotICAgICAgICByZXR1cm4gKChDaGFyS2V5KW9iaikubV9jaGFyID09IG1fY2hhcjsKLSAgICAgIH0KLSAgICB9Ci0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9ET01TZXJpYWxpemVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL0RPTVNlcmlhbGl6ZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZTg3YzJjMi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL0RPTVNlcmlhbGl6ZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDY4ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IERPTVNlcmlhbGl6ZXIuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNSAwODoxNToxNSBzdXJlc2hfZW1haWxpZCBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplcjsKLQotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotCi0vKioKLSAqIEludGVyZmFjZSBmb3IgYSBET00gc2VyaWFsaXplciBpbXBsZW1lbnRhdGlvbi4KLSAqIDxwPgotICogVGhlIERPTVNlcmlhbGl6ZXIgaXMgYSBmYWNldCBvZiBhIHNlcmlhbGl6ZXIgYW5kIGlzIG9idGFpbmVkIGZyb20gdGhlCi0gKiBhc0RPTVNlcmlhbGl6ZXIoKSBtZXRob2Qgb2YgdGhlIFNlcmlhbGl6ZXIgaW50ZXJmYWNlLgotICogQSBzZXJpYWxpemVyIG1heSBvciBtYXkgbm90IHN1cHBvcnQgYSBET00gc2VyaWFsaXplciwgaWYgaXQgZG9lcyBub3QgdGhlbiB0aGUKLSAqIHJldHVybiB2YWx1ZSBmcm9tIGFzRE9NU2VyaWFsaXplcigpIGlzIG51bGwuCi0gKiA8cD4KLSAqIEV4YW1wbGU6Ci0gKiA8cHJlPgotICogRG9jdW1lbnQgICAgIGRvYzsKLSAqIFNlcmlhbGl6ZXIgICBzZXI7Ci0gKiBPdXRwdXRTdHJlYW0gb3M7Ci0gKgotICogc2VyID0gLi4uOwotICogb3MgPSAuLi47Ci0gKgotICogc2VyLnNldE91dHB1dFN0cmVhbSggb3MgKTsKLSAqIERPTVNlcmlhbHppZXIgZHNlciA9IHNlci5hc0RPTVNlcmlhbGl6ZXIoKTsKLSAqIGRzZXIuc2VyaWFsaXplKGRvYyk7Ci0gKiA8L3ByZT4KLSAqCi0gKiBAc2VlIFNlcmlhbGl6ZXIKLSAqCi0gKiBAeHNsLnVzYWdlIGdlbmVyYWwKLSAqCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgRE9NU2VyaWFsaXplcgotewotICAgIC8qKgotICAgICAqIFNlcmlhbGl6ZXMgdGhlIERPTSBub2RlLiBUaHJvd3MgYW4gZXhjZXB0aW9uIG9ubHkgaWYgYW4gSS9PCi0gICAgICogZXhjZXB0aW9uIG9jY3VyZWQgd2hpbGUgc2VyaWFsaXppbmcuCi0gICAgICoKLSAgICAgKiBUaGlzIGludGVyZmFjZSBpcyBhIHB1YmxpYyBBUEkuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbm9kZSB0aGUgRE9NIG5vZGUgdG8gc2VyaWFsaXplCi0gICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiBhbiBJL08gZXhjZXB0aW9uIG9jY3VyZWQgd2hpbGUgc2VyaWFsaXppbmcKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXJpYWxpemUoTm9kZSBub2RlKSB0aHJvd3MgSU9FeGNlcHRpb247Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL0VsZW1Db250ZXh0LmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL0VsZW1Db250ZXh0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDgwNWQ3YzcuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9FbGVtQ29udGV4dC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjIxICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDMtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IEVsZW1Db250ZXh0LmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTUgMDg6MTU6MTUgc3VyZXNoX2VtYWlsaWQgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXI7Ci0KLS8qKgotICogVGhpcyBjbGFzcyBpcyBhIHN0YWNrIGZyYW1lIHRoYXQgY29uc2lzdHMgb2YKLSAqIGluZm9ybWF0aW9uIGFib3V0IHRoZSBlbGVtZW50IGN1cnJlbnRseSBiZWluZyBwcm9jZXNzZWQKLSAqIGJ5IGEgc2VyaWFsaXplci4gQ29uc2lkZXIgdGhpcyBleGFtcGxlOgotICogPHByZT4KLSAqICAgPEE+Ci0gKiAgICAgPEIxPgotICogICAgIDwvQjE+Ci0gKiAgICAgPEIyPgotICogICAgIDwvQjI+Ci0gKiAgIDxBPgotICogPC9wcmU+Ci0gKgotICogQSBzdGFjayBmcmFtZSB3aWxsIGJlIHB1c2hlZCBmb3IgIkEiIGF0IGRlcHRoIDEsCi0gKiB0aGVuIGFub3RoZXIgb25lIGZvciAiQjEiIGF0IGRlcHRoIDIuCi0gKiBUaGVuICJCMSIgc3RhY2tmcmFtZSBpcyBwb3BwZWQuICBXaGVuIHRoZSBzdGFjayBmcmFtZSBmb3IgIkIyIiBpcwotICogcHVzaGVkLCB0aGlzIGltcGxlbWVudGF0aW9uIHJlLXVzZXMgdGhlIG9sZCBzdGFjayBmcmFtIG9iamVjdCB1c2VkCi0gKiBieSAiQjEiIHRvIGJlIGVmZmljaWVudCBhdCBub3QgY3JlYXRpbmcgdG9vIG1hbnkgb2YgdGhlc2Ugb2JqZWN0LgotICoKLSAqIFRoaXMgaXMgYnkgbm8gbWVhbnMgYSBwdWJsaWMgY2xhc3MsIGFuZCBuZWl0aGVyIGFyZSBpdHMgZmllbGRzIG9yIG1ldGhvZHMsCi0gKiB0aGV5IGFyZSBhbGwgaGVscGVyIGZpZWxkcyBmb3IgYSBzZXJpYWxpemVyLgotICoKLSAqIFRoZSBwdXJwb3NlIG9mIHRoaXMgY2xhc3MgaXMgdG8gYmUgbW9yZSBjb25zaXN0ZW50IHdpdGggcHVzaGluZyBpbmZvcm1hdGlvbgotICogd2hlbiBhIG5ldyBlbGVtZW50IGlzIGJlaW5nIHNlcmlhbGl6ZWQgYW5kIG1vcmUgcXVpY2tseSByZXN0b3JpbmcgdGhlIG9sZAotICogaW5mb3JtYXRpb24gYWJvdXQgdGhlIHBhcmVudCBlbGVtZW50IHdpdGggYSBzaW1wbGUgcG9wKCkgd2hlbiB0aGUKLSAqIGNoaWxkIGVsZW1lbnQgaXMgZG9uZS4gIFByZXZpb3VzbHkgdGhlcmUgd2FzIHNvbWUgcmVkdW5kYW50IGFuZCBlcnJvci1wcm9uZQotICogY2FsY3VsYXRpb25zIGdvaW5nIG9uIHRvIHJldG9yZSBpbmZvcm1hdGlvbi4KLSAqCi0gKiBAeHNsLnVzYWdlIGludGVybmFsCi0gKi8KLWZpbmFsIGNsYXNzIEVsZW1Db250ZXh0Ci17Ci0gICAgLy8gRmllbGRzIHRoYXQgZm9ybSB0aGUgY29udGV4dCBvZiB0aGUgZWxlbWVudAotCi0gICAgLyoqCi0gICAgICogVGhlIG5lc3RpbmcgZGVwdGggb2YgdGhlIGVsZW1lbnQgaW5zaWRlIG90aGVyIGVsZW1lbnRzLgotICAgICAqLwotICAgIGZpbmFsIGludCBtX2N1cnJlbnRFbGVtRGVwdGg7Ci0KLSAgICAvKiogSFRNTCBmaWVsZCwgdGhlIGVsZW1lbnQgZGVzY3JpcHRpb24gb2YgdGhlIEhUTUwgZWxlbWVudCAqLwotICAgIEVsZW1EZXNjIG1fZWxlbWVudERlc2MgPSBudWxsOwotCi0gICAgLyoqCi0gICAgICogVGhlIGxvY2FsIG5hbWUgb2YgdGhlIGVsZW1lbnQuCi0gICAgICovCi0gICAgU3RyaW5nIG1fZWxlbWVudExvY2FsTmFtZSA9IG51bGw7Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgZnVsbHkgcXVhbGlmaWVkIG5hbWUgb2YgdGhlIGVsZW1lbnQgKHdpdGggcHJlZml4LCBpZiBhbnkpLgotICAgICAqLwotICAgIFN0cmluZyBtX2VsZW1lbnROYW1lID0gbnVsbDsKLQotICAgIC8qKgotICAgICAqIFRoZSBVUkkgb2YgdGhlIGVsZW1lbnQuCi0gICAgICovCi0gICAgU3RyaW5nIG1fZWxlbWVudFVSSSA9IG51bGw7Ci0KLSAgICAvKiogSWYgdGhlIGVsZW1lbnQgaXMgaW4gdGhlIGNkYXRhLXNlY3Rpb24tbmFtZXMgbGlzdAotICAgICAqIHRoZW4gdGhlIHZhbHVlIGlzIHRydWUuIElmIGl0IGlzIHRydWUgdGhlIHRleHQgY2hpbGRyZW4gb2YgdGhlIGVsZW1lbnQKLSAgICAgKiBzaG91bGQgYmUgb3V0cHV0IGluIENEQVRBIHNlY3Rpb24gYmxvY2tzLgotICAgICAqLwotICAgIGJvb2xlYW4gbV9pc0NkYXRhU2VjdGlvbjsKLQotICAgIC8qKiBUcnVlIGlmIHRoZSBjdXJyZW50IGVsZW1lbnQgaGFzIG91dHB1dCBlc2NhcGluZyBkaXNhYmxlZC4KLSAgICAgKiBUaGlzIGlzIHRydWUgZm9yIFNDUklQVCBhbmQgU1RZTEUgZWxlbWVudHMuCi0gICAgICovCi0gICAgYm9vbGVhbiBtX2lzUmF3ID0gZmFsc2U7Ci0KLSAgICAvKiogVGhlIG5leHQgZWxlbWVudCAic3RhY2sgZnJhbWUiLiBUaGlzIHZhbHVlIHdpbGwgb25seSBiZQotICAgICAqIHNldCBvbmNlIGFzIGRlZXBlciBzdGFjayBmcmFtZXMgYXJlIG5vdCBkZWxldGVkIHdoZW4gcG9wcGVkIG9mZiwKLSAgICAgKiBidXQgYXJlIHJhdGhlciByZS11c2VkIHdoZW4gYSBwdXNoIGlzIHJlcXVpcmVkLgotICAgICAqCi0gICAgICogVGhpcyBtYWtlcyBmb3IgdmVyeSBmYXN0IHB1c2hpbmcgYW5kIHBvcHBpbmcgb2Ygc3RhY2sgZnJhbWVzCi0gICAgICogYmVjYXVzZSB2ZXJ5IGZldyBzdGFjayBmcmFtZSBvYmplY3RzIGFyZSBldmVyIGNyZWF0ZWQsIHRoZXkgYXJlCi0gICAgICogbW9zdGx5IHJlLXVzZWQuICBUaGlzIHJlLXVzZSBzYXZlcyBvYmplY3QgY3JlYXRpb24gYnV0IGl0IGFsc28gbWVhbnMKLSAgICAgKiB0aGF0IGNvbm5lY3Rpb25zIGJldHdlZW4gdGhlIGZyYW1lcyB2aWEgbV9uZXh0IGFuZCBtX3ByZXYKLSAgICAgKiBuZXZlciBjaGFuZ2VzIGVpdGhlci4gSnVzdCB0aGUgY29udGVudHMgb2YgdGhlIGZyYW1lcyBjaGFuZ2UKLSAgICAgKiBhcyB0aGV5IGFyZSByZS11c2VkLiBPbmx5IHRoZSByZWZlcmVuY2UgdG8gdGhlIGN1cnJlbnQgc3RhY2sgZnJhbWUsIHdoaWNoCi0gICAgICogaXMgaGVsZCBieSB0aGUgc2VyaWFsaXplciBpcyBjaGFuZ2VkIHZpYSBhIHF1aWNrIHBvcCgpIG9yIHB1c2goKS4KLSAgICAgKi8KLSAgICBwcml2YXRlIEVsZW1Db250ZXh0IG1fbmV4dDsKLQotICAgIC8qKiBUaGUgcHJldmlvdXMgZWxlbWVudCAic3RhY2sgZnJhbWUiLiAqLwotICAgIGZpbmFsIEVsZW1Db250ZXh0IG1fcHJldjsKLQotICAgIC8qKgotICAgICAqIFNldCB0byB0cnVlIHdoZW4gYSBzdGFydCB0YWcgaXMgc3RhcnRlZCwgb3Igb3BlbiwgYnV0IG5vdCBhbGwgdGhlCi0gICAgICogYXR0cmlidXRlcyBvciBuYW1lc3BhY2UgaW5mb3JtYXRpb24gaXMgeWV0IGNvbGxlY3RlZC4KLSAgICAgKi8KLSAgICBib29sZWFuIG1fc3RhcnRUYWdPcGVuID0gZmFsc2U7Ci0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RvciB0byBjcmVhdGUgdGhlIHJvb3Qgb2YgdGhlIGVsZW1lbnQgY29udGV4dHMuCi0gICAgICoKLSAgICAgKi8KLSAgICBFbGVtQ29udGV4dCgpCi0gICAgewotICAgICAgICAvLyB0aGlzIGFzc2lnbm1lbnQgbWVhbnMgY2FuIG5ldmVyIHBvcCB0aGlzIGNvbnRleHQgb2ZmCi0gICAgICAgIG1fcHJldiA9IHRoaXM7Ci0gICAgICAgIC8vIGRlcHRoIDAgYmVjYXVzZSBpdCBkb2Vzbid0IGNvcnJlc3BvbmQgdG8gYW55IGVsZW1lbnQKLSAgICAgICAgbV9jdXJyZW50RWxlbURlcHRoID0gMDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RvciB0byBjcmVhdGUgdGhlICJzdGFjayBmcmFtZSIgZm9yIGEgZ2l2ZW4gZWxlbWVudCBkZXB0aC4KLSAgICAgKgotICAgICAqIFRoaXMgaW1wbGVtZW50YXRpb24gd2lsbCByZS11c2UgdGhlIGNvbnRleHQgYXQgZWFjaCBkZXB0aC4gSWYKLSAgICAgKiBhIGRvY3VtZW50cyBkZWVwZXN0IGVsZW1lbnQgZGVwdGggaXMgTiB0aGVuIHRoZXJlIHdpbGwgYmUgKE4rMSkKLSAgICAgKiBzdWNoIG9iamVjdHMgY3JlYXRlZCwgbm8gbW9yZSB0aGFuIHRoYXQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcHJldmlvdXMgVGhlICJzdGFjayBmcmFtZSIgY29ycmVzcG9uZGluZyB0byB0aGUgbmV3Ci0gICAgICogZWxlbWVudHMgcGFyZW50IGVsZW1lbnQuCi0gICAgICovCi0gICAgcHJpdmF0ZSBFbGVtQ29udGV4dChmaW5hbCBFbGVtQ29udGV4dCBwcmV2aW91cykKLSAgICB7Ci0gICAgICAgIG1fcHJldiA9IHByZXZpb3VzOwotICAgICAgICBtX2N1cnJlbnRFbGVtRGVwdGggPSBwcmV2aW91cy5tX2N1cnJlbnRFbGVtRGVwdGggKyAxOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFBvcCB0aGUgY3VycmVudCAic3RhY2sgZnJhbWUiLgotICAgICAqIEByZXR1cm4gUmV0dXJucyB0aGUgcGFyZW50ICJzdGFjayBmcmFtZSIgb2YgdGhlIG9uZSBwb3BwZWQuCi0gICAgICovCi0gICAgZmluYWwgRWxlbUNvbnRleHQgcG9wKCkKLSAgICB7Ci0gICAgICAgIC8qIGEgdmVyeSBzaW1wbGUgcG9wLiAgTm8gY2xlYW4gdXAgaXMgZG9uZSBvZiB0aGUgZGVlcGVyCi0gICAgICAgICAqIHN0YWNrIGZyYW1lLiAgQWxsIGRlZXBlciBzdGFjayBmcmFtZXMgYXJlIHN0aWxsIGF0dGFjaGVkCi0gICAgICAgICAqIGJ1dCBkb3JtYW50LCBqdXN0IHdhaXRpbmcgdG8gYmUgcmUtdXNlZC4KLSAgICAgICAgICovCi0gICAgICAgIHJldHVybiB0aGlzLm1fcHJldjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBwdXNoZXMgYW4gZWxlbWVudCAic3RhY2sgZnJhbWUiCi0gICAgICogYnV0IHdpdGggbm8gaW5pdGlhbGl6YXRpb24gb2YgdmFsdWVzIGluIHRoYXQgZnJhbWUuCi0gICAgICogVGhpcyBtZXRob2QgaXMgdXNlZCBmb3Igb3B0aW1pemF0aW9uIHB1cnBvc2VzLCBsaWtlIHdoZW4gcHVzaGluZwotICAgICAqIGEgc3RhY2sgZnJhbWUgZm9yIGFuIEhUTUwgIklNRyIgdGFnIHdoaWNoIGhhcyBubyBjaGlsZHJlbiBhbmQKLSAgICAgKiB0aGUgc3RhY2sgZnJhbWUgd2lsbCBhbG1vc3QgaW1tZWRpYXRlbHkgYmUgcG9wcGVkLgotICAgICAqLwotICAgIGZpbmFsIEVsZW1Db250ZXh0IHB1c2goKQotICAgIHsKLSAgICAgICAgRWxlbUNvbnRleHQgZnJhbWUgPSB0aGlzLm1fbmV4dDsKLSAgICAgICAgaWYgKGZyYW1lID09IG51bGwpCi0gICAgICAgIHsKLSAgICAgICAgICAgIC8qIFdlIGhhdmUgbmV2ZXIgYmVlbiBhdCB0aGlzIGRlcHRoIHlldCwgYW5kIHRoZXJlIGlzIG5vCi0gICAgICAgICAgICAgKiBzdGFjayBmcmFtZSB0byByZS11c2UsIHNvIHdlIG5vdyBtYWtlIGEgbmV3IG9uZS4KLSAgICAgICAgICAgICAqLwotICAgICAgICAgICAgZnJhbWUgPSBuZXcgRWxlbUNvbnRleHQodGhpcyk7Ci0gICAgICAgICAgICB0aGlzLm1fbmV4dCA9IGZyYW1lOwotICAgICAgICB9Ci0gICAgICAgIC8qCi0gICAgICAgICAqIFdlIHNob3VsZG4ndCBuZWVkIHRvIHNldCB0aGlzIHRydWUgYmVjYXVzZSB3ZSBzaG91bGQganVzdAotICAgICAgICAgKiBiZSBwdXNoaW5nIGEgZHVtbXkgc3RhY2sgZnJhbWUgdGhhdCB3aWxsIGJlIGluc3RhbnRseSBwb3BwZWQuCi0gICAgICAgICAqIFlldCB3ZSBuZWVkIHRvIGJlIHJlYWR5IGluIGNhc2UgdGhpcyBlbGVtZW50IGRvZXMgaGF2ZQotICAgICAgICAgKiB1bmV4cGVjdGVkIGNoaWxkcmVuLgotICAgICAgICAgKi8KLSAgICAgICAgZnJhbWUubV9zdGFydFRhZ09wZW4gPSB0cnVlOwotICAgICAgICByZXR1cm4gZnJhbWU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUHVzaCBhbiBlbGVtZW50IGNvbnRleHQgb24gdGhlIHN0YWNrLiBUaGlzIGNvbnRleHQga2VlcHMgdHJhY2sgb2YKLSAgICAgKiBpbmZvcm1hdGlvbiBnYXRoZXJlZCBhYm91dCB0aGUgZWxlbWVudC4KLSAgICAgKiBAcGFyYW0gdXJpIFRoZSBVUkkgZm9yIHRoZSBuYW1lc3BhY2UgZm9yIHRoZSBlbGVtZW50IG5hbWUsCi0gICAgICogY2FuIGJlIG51bGwgaWYgaXQgaXMgbm90IHlldCBrbm93bi4KLSAgICAgKiBAcGFyYW0gbG9jYWxOYW1lIFRoZSBsb2NhbCBuYW1lIG9mIHRoZSBlbGVtZW50IChubyBwcmVmaXgpLAotICAgICAqIGNhbiBiZSBudWxsLgotICAgICAqIEBwYXJhbSBxTmFtZSBUaGUgcXVhbGlmaWVkIG5hbWUgKHdpdGggcHJlZml4LCBpZiBhbnkpCi0gICAgICogb2YgdGhlIGVsZW1lbnQsIHRoaXMgcGFyYW1ldGVyIGlzIHJlcXVpcmVkLgotICAgICAqLwotICAgIGZpbmFsIEVsZW1Db250ZXh0IHB1c2goCi0gICAgICAgIGZpbmFsIFN0cmluZyB1cmksCi0gICAgICAgIGZpbmFsIFN0cmluZyBsb2NhbE5hbWUsCi0gICAgICAgIGZpbmFsIFN0cmluZyBxTmFtZSkKLSAgICB7Ci0gICAgICAgIEVsZW1Db250ZXh0IGZyYW1lID0gdGhpcy5tX25leHQ7Ci0gICAgICAgIGlmIChmcmFtZSA9PSBudWxsKQotICAgICAgICB7Ci0gICAgICAgICAgICAvKiBXZSBoYXZlIG5ldmVyIGJlZW4gYXQgdGhpcyBkZXB0aCB5ZXQsIGFuZCB0aGVyZSBpcyBubwotICAgICAgICAgICAgICogc3RhY2sgZnJhbWUgdG8gcmUtdXNlLCBzbyB3ZSBub3cgbWFrZSBhIG5ldyBvbmUuCi0gICAgICAgICAgICAgKi8KLSAgICAgICAgICAgIGZyYW1lID0gbmV3IEVsZW1Db250ZXh0KHRoaXMpOwotICAgICAgICAgICAgdGhpcy5tX25leHQgPSBmcmFtZTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIEluaXRpYWxpemUsIG9yIHJlc2V0IHZhbHVlcyBpbiB0aGUgbmV3IG9yIHJlLXVzZWQgc3RhY2sgZnJhbWUuCi0gICAgICAgIGZyYW1lLm1fZWxlbWVudE5hbWUgPSBxTmFtZTsKLSAgICAgICAgZnJhbWUubV9lbGVtZW50TG9jYWxOYW1lID0gbG9jYWxOYW1lOwotICAgICAgICBmcmFtZS5tX2VsZW1lbnRVUkkgPSB1cmk7Ci0gICAgICAgIGZyYW1lLm1faXNDZGF0YVNlY3Rpb24gPSBmYWxzZTsKLSAgICAgICAgZnJhbWUubV9zdGFydFRhZ09wZW4gPSB0cnVlOwotCi0gICAgICAgIC8vIGlzX1JhdyBpcyBhbHJlYWR5IHNldCBpbiB0aGUgSFRNTCBzdGFydEVsZW1lbnQoKSBtZXRob2QKLSAgICAgICAgLy8gZnJhbWUubV9pc1JhdyA9IGZhbHNlOwotICAgICAgICByZXR1cm4gZnJhbWU7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9FbGVtRGVzYy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9FbGVtRGVzYy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1NjcwOTUyLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvRWxlbURlc2MuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE4MCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBFbGVtRGVzYy5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE1IDA4OjE1OjE1IHN1cmVzaF9lbWFpbGlkIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyLnV0aWxzLlN0cmluZ1RvSW50VGFibGU7Ci0KLS8qKgotICogVGhpcyBjbGFzcyBoYXMgYSBzZXJpZXMgb2YgZmxhZ3MgKGJpdCB2YWx1ZXMpIHRoYXQgZGVzY3JpYmUgYW4gSFRNTCBlbGVtZW50Ci0gKgotICogVGhpcyBjbGFzcyBpcyBwdWJsaWMgYmVjYXVzZSBYU0xUQyB1c2VzIGl0LCBpdCBpcyBub3QgYSBwdWJsaWMgQVBJLgotICoKLSAqIEB4c2wudXNhZ2UgaW50ZXJuYWwKLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIEVsZW1EZXNjCi17Ci0gICAgLyoqIEJpdCBmbGFncyB0byB0ZWxsIGFib3V0IHRoaXMgZWxlbWVudCB0eXBlLiAqLwotICAgIHByaXZhdGUgaW50IG1fZmxhZ3M7Ci0KLSAgICAvKioKLSAgICAgKiBUYWJsZSBvZiBhdHRyaWJ1dGUgbmFtZXMgdG8gaW50ZWdlcnMsIHdoaWNoIGNvbnRhaW4gYml0IGZsYWdzIHRlbGxpbmcgYWJvdXQKLSAgICAgKiAgdGhlIGF0dHJpYnV0ZXMuCi0gICAgICovCi0gICAgcHJpdmF0ZSBTdHJpbmdUb0ludFRhYmxlIG1fYXR0cnMgPSBudWxsOwotCi0gICAgLyoqIEJpdCBwb3NpdGlvbiBpZiB0aGlzIGVsZW1lbnQgdHlwZSBpcyBlbXB0eS4gKi8KLSAgICBzdGF0aWMgZmluYWwgaW50IEVNUFRZID0gKDEgPDwgMSk7Ci0KLSAgICAvKiogQml0IHBvc2l0aW9uIGlmIHRoaXMgZWxlbWVudCB0eXBlIGlzIGEgZmxvdy4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgRkxPVyA9ICgxIDw8IDIpOwotCi0gICAgLyoqIEJpdCBwb3NpdGlvbiBpZiB0aGlzIGVsZW1lbnQgdHlwZSBpcyBhIGJsb2NrLiAqLwotICAgIHN0YXRpYyBmaW5hbCBpbnQgQkxPQ0sgPSAoMSA8PCAzKTsKLQotICAgIC8qKiBCaXQgcG9zaXRpb24gaWYgdGhpcyBlbGVtZW50IHR5cGUgaXMgYSBibG9jayBmb3JtLiAqLwotICAgIHN0YXRpYyBmaW5hbCBpbnQgQkxPQ0tGT1JNID0gKDEgPDwgNCk7Ci0KLSAgICAvKiogQml0IHBvc2l0aW9uIGlmIHRoaXMgZWxlbWVudCB0eXBlIGlzIGEgYmxvY2sgZm9ybSBmaWVsZCBzZXQuICovCi0gICAgc3RhdGljIGZpbmFsIGludCBCTE9DS0ZPUk1GSUVMRFNFVCA9ICgxIDw8IDUpOwotCi0gICAgLyoqIEJpdCBwb3NpdGlvbiBpZiB0aGlzIGVsZW1lbnQgdHlwZSBpcyBDREFUQS4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQ0RBVEEgPSAoMSA8PCA2KTsKLQotICAgIC8qKiBCaXQgcG9zaXRpb24gaWYgdGhpcyBlbGVtZW50IHR5cGUgaXMgUENEQVRBLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBQQ0RBVEEgPSAoMSA8PCA3KTsKLQotICAgIC8qKiBCaXQgcG9zaXRpb24gaWYgdGhpcyBlbGVtZW50IHR5cGUgaXMgc2hvdWxkIGJlIHJhdyBjaGFyYWN0ZXJzLiAqLwotICAgIHN0YXRpYyBmaW5hbCBpbnQgUkFXID0gKDEgPDwgOCk7Ci0KLSAgICAvKiogQml0IHBvc2l0aW9uIGlmIHRoaXMgZWxlbWVudCB0eXBlIHNob3VsZCBiZSBpbmxpbmVkLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBJTkxJTkUgPSAoMSA8PCA5KTsKLQotICAgIC8qKiBCaXQgcG9zaXRpb24gaWYgdGhpcyBlbGVtZW50IHR5cGUgaXMgSU5MSU5FQS4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgSU5MSU5FQSA9ICgxIDw8IDEwKTsKLQotICAgIC8qKiBCaXQgcG9zaXRpb24gaWYgdGhpcyBlbGVtZW50IHR5cGUgaXMgYW4gaW5saW5lIGxhYmVsLiAqLwotICAgIHN0YXRpYyBmaW5hbCBpbnQgSU5MSU5FTEFCRUwgPSAoMSA8PCAxMSk7Ci0KLSAgICAvKiogQml0IHBvc2l0aW9uIGlmIHRoaXMgZWxlbWVudCB0eXBlIGlzIGEgZm9udCBzdHlsZS4gKi8KLSAgICBzdGF0aWMgZmluYWwgaW50IEZPTlRTVFlMRSA9ICgxIDw8IDEyKTsKLQotICAgIC8qKiBCaXQgcG9zaXRpb24gaWYgdGhpcyBlbGVtZW50IHR5cGUgaXMgYSBwaHJhc2UuICovCi0gICAgc3RhdGljIGZpbmFsIGludCBQSFJBU0UgPSAoMSA8PCAxMyk7Ci0KLSAgICAvKiogQml0IHBvc2l0aW9uIGlmIHRoaXMgZWxlbWVudCB0eXBlIGlzIGEgZm9ybSBjb250cm9sLiAqLwotICAgIHN0YXRpYyBmaW5hbCBpbnQgRk9STUNUUkwgPSAoMSA8PCAxNCk7Ci0KLSAgICAvKiogQml0IHBvc2l0aW9uIGlmIHRoaXMgZWxlbWVudCB0eXBlIGlzID8/Py4gKi8KLSAgICBzdGF0aWMgZmluYWwgaW50IFNQRUNJQUwgPSAoMSA8PCAxNSk7Ci0KLSAgICAvKiogQml0IHBvc2l0aW9uIGlmIHRoaXMgZWxlbWVudCB0eXBlIGlzID8/Py4gKi8KLSAgICBzdGF0aWMgZmluYWwgaW50IEFTUEVDSUFMID0gKDEgPDwgMTYpOwotCi0gICAgLyoqIEJpdCBwb3NpdGlvbiBpZiB0aGlzIGVsZW1lbnQgdHlwZSBpcyBhbiBvZGQgaGVhZGVyIGVsZW1lbnQuICovCi0gICAgc3RhdGljIGZpbmFsIGludCBIRUFETUlTQyA9ICgxIDw8IDE3KTsKLQotICAgIC8qKiBCaXQgcG9zaXRpb24gaWYgdGhpcyBlbGVtZW50IHR5cGUgaXMgYSBoZWFkIGVsZW1lbnQgKGkuZS4gSDEsIEgyLCBldGMuKSAqLwotICAgIHN0YXRpYyBmaW5hbCBpbnQgSEVBRCA9ICgxIDw8IDE4KTsKLQotICAgIC8qKiBCaXQgcG9zaXRpb24gaWYgdGhpcyBlbGVtZW50IHR5cGUgaXMgYSBsaXN0LiAqLwotICAgIHN0YXRpYyBmaW5hbCBpbnQgTElTVCA9ICgxIDw8IDE5KTsKLQotICAgIC8qKiBCaXQgcG9zaXRpb24gaWYgdGhpcyBlbGVtZW50IHR5cGUgaXMgYSBwcmVmb3JtYXR0ZWQgdHlwZS4gKi8KLSAgICBzdGF0aWMgZmluYWwgaW50IFBSRUZPUk1BVFRFRCA9ICgxIDw8IDIwKTsKLQotICAgIC8qKiBCaXQgcG9zaXRpb24gaWYgdGhpcyBlbGVtZW50IHR5cGUgaXMgd2hpdGVzcGFjZSBzZW5zaXRpdmUuICovCi0gICAgc3RhdGljIGZpbmFsIGludCBXSElURVNQQUNFU0VOU0lUSVZFID0gKDEgPDwgMjEpOwotCi0gICAgLyoqIEJpdCBwb3NpdGlvbiBpZiB0aGlzIGVsZW1lbnQgdHlwZSBpcyBhIGhlYWRlciBlbGVtZW50IChpLmUuIEhFQUQpLiAqLwotICAgIHN0YXRpYyBmaW5hbCBpbnQgSEVBREVMRU0gPSAoMSA8PCAyMik7Ci0KLSAgICAvKiogQml0IHBvc2l0aW9uIGlmIHRoaXMgZWxlbWVudCBpcyB0aGUgIkhUTUwiIGVsZW1lbnQgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgSFRNTEVMRU0gPSAoMSA8PCAyMyk7Ci0KLSAgICAvKiogQml0IHBvc2l0aW9uIGlmIHRoaXMgYXR0cmlidXRlIHR5cGUgaXMgYSBVUkwuICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQVRUUlVSTCA9ICgxIDw8IDEpOwotCi0gICAgLyoqIEJpdCBwb3NpdGlvbiBpZiB0aGlzIGF0dHJpYnV0ZSB0eXBlIGlzIGFuIGVtcHR5IHR5cGUuICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQVRUUkVNUFRZID0gKDEgPDwgMik7Ci0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3QgYW4gRWxlbURlc2MgZnJvbSBhIHNldCBvZiBiaXQgZmxhZ3MuCi0gICAgICoKLSAgICAgKgotICAgICAqIEBwYXJhbSBmbGFncyBCaXQgZmxhZ3MgdGhhdCBkZXNjcmliZSB0aGUgYmFzaWMgcHJvcGVydGllcyBvZiB0aGlzIGVsZW1lbnQgdHlwZS4KLSAgICAgKi8KLSAgICBFbGVtRGVzYyhpbnQgZmxhZ3MpCi0gICAgewotICAgICAgICBtX2ZsYWdzID0gZmxhZ3M7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGVsbCBpZiB0aGlzIGVsZW1lbnQgdHlwZSBoYXMgdGhlIGJhc2ljIGJpdCBwcm9wZXJ0aWVzIHRoYXQgYXJlIHBhc3NlZAotICAgICAqIGFzIGFuIGFyZ3VtZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIGZsYWdzIEJpdCBmbGFncyB0aGF0IGRlc2NyaWJlIHRoZSBiYXNpYyBwcm9wZXJ0aWVzIG9mIGludGVyZXN0LgotICAgICAqCi0gICAgICogQHJldHVybiB0cnVlIGlmIGFueSBvZiB0aGUgZmxhZyBiaXRzIGFyZSB0cnVlLgotICAgICAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBpcyhpbnQgZmxhZ3MpCi0gICAgewotCi0gICAgICAgIC8vIGludCB3aGljaCA9IChtX2ZsYWdzICYgZmxhZ3MpOwotICAgICAgICByZXR1cm4gKG1fZmxhZ3MgJiBmbGFncykgIT0gMDsKLSAgICB9Ci0KLSAgICBpbnQgZ2V0RmxhZ3MoKSB7Ci0gICAgICAgIHJldHVybiBtX2ZsYWdzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldCBhbiBhdHRyaWJ1dGUgbmFtZSBhbmQgaXQncyBiaXQgcHJvcGVydGllcy4KLSAgICAgKgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgbm9uLW51bGwgbmFtZSBvZiBhdHRyaWJ1dGUsIGluIHVwcGVyIGNhc2UuCi0gICAgICogQHBhcmFtIGZsYWdzIGZsYWcgYml0cy4KLSAgICAgKi8KLSAgICB2b2lkIHNldEF0dHIoU3RyaW5nIG5hbWUsIGludCBmbGFncykKLSAgICB7Ci0KLSAgICAgICAgaWYgKG51bGwgPT0gbV9hdHRycykKLSAgICAgICAgICAgIG1fYXR0cnMgPSBuZXcgU3RyaW5nVG9JbnRUYWJsZSgpOwotCi0gICAgICAgIG1fYXR0cnMucHV0KG5hbWUsIGZsYWdzKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUZWxsIGlmIGFueSBvZiB0aGUgYml0cyBvZiBpbnRlcmVzdCBhcmUgc2V0IGZvciBhIG5hbWVkIGF0dHJpYnV0ZSB0eXBlLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGF0dHJpYnV0ZSBuYW1lLCBpbiBhbnkgY2FzZS4KLSAgICAgKiBAcGFyYW0gZmxhZ3MgZmxhZyBtYXNrLgotICAgICAqCi0gICAgICogQHJldHVybiB0cnVlIGlmIGFueSBvZiB0aGUgZmxhZ3MgYXJlIHNldCBmb3IgdGhlIG5hbWVkIGF0dHJpYnV0ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0F0dHJGbGFnU2V0KFN0cmluZyBuYW1lLCBpbnQgZmxhZ3MpCi0gICAgewotICAgICAgICByZXR1cm4gKG51bGwgIT0gbV9hdHRycykKLSAgICAgICAgICAgID8gKChtX2F0dHJzLmdldElnbm9yZUNhc2UobmFtZSkgJiBmbGFncykgIT0gMCkKLSAgICAgICAgICAgIDogZmFsc2U7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9FbXB0eVNlcmlhbGl6ZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvRW1wdHlTZXJpYWxpemVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDU0OTJkZTUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9FbXB0eVNlcmlhbGl6ZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDc1MiArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDE1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICovCi0vKgotICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCi0gKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKLSAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KLSAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCi0gKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAotICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IEVtcHR5U2VyaWFsaXplci5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE1IDA4OjE1OjE2IHN1cmVzaF9lbWFpbGlkIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyOwotCi1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKLWltcG9ydCBqYXZhLmlvLldyaXRlcjsKLWltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uU291cmNlTG9jYXRvcjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyOwotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci1pbXBvcnQgb3JnLnhtbC5zYXguQXR0cmlidXRlczsKLWltcG9ydCBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5Mb2NhdG9yOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhQYXJzZUV4Y2VwdGlvbjsKLQotCi0vKioKLSAqIFRoaXMgY2xhc3MgaXMgYW4gYWRhcHRlciBjbGFzcy4gSXRzIG9ubHkgcHVycG9zZSBpcyB0byBiZSBleHRlbmRlZCBhbmQKLSAqIGZvciB0aGF0IGV4dGVuZGVkIGNsYXNzIHRvIG92ZXItcmlkZSBhbGwgbWV0aG9kcyB0aGF0IGFyZSB0byBiZSB1c2VkLgotICoKLSAqIFRoaXMgY2xhc3MgaXMgbm90IGEgcHVibGljIEFQSSwgaXQgaXMgb25seSBwdWJsaWMgYmVjYXVzZSBpdCBpcyB1c2VkCi0gKiBhY3Jvc3MgcGFja2FnZSBib3VuZGFyaWVzLgotICoKLSAqIEB4c2wudXNhZ2UgaW50ZXJuYWwKLSAqLwotcHVibGljIGNsYXNzIEVtcHR5U2VyaWFsaXplciBpbXBsZW1lbnRzIFNlcmlhbGl6YXRpb25IYW5kbGVyCi17Ci0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJSID0gIkVtcHR5U2VyaWFsaXplciBtZXRob2Qgbm90IG92ZXItcmlkZGVuIjsKLSAgICAvKioKLSAgICAgKiBAc2VlIFNlcmlhbGl6YXRpb25IYW5kbGVyI2FzQ29udGVudEhhbmRsZXIoKQotICAgICAqLwotCi0gICAgcHJvdGVjdGVkIHZvaWQgY291bGRUaHJvd0lPRXhjZXB0aW9uKCkgdGhyb3dzIElPRXhjZXB0aW9uCi0gICAgewotICAgICAgICByZXR1cm47IC8vIGRvbid0IGRvIGFueXRoaW5nLgotICAgIH0KLQotICAgIHByb3RlY3RlZCB2b2lkIGNvdWxkVGhyb3dTQVhFeGNlcHRpb24oKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICByZXR1cm47IC8vIGRvbid0IGRvIGFueXRoaW5nLgotICAgIH0KLQotICAgIHByb3RlY3RlZCB2b2lkIGNvdWxkVGhyb3dTQVhFeGNlcHRpb24oY2hhcltdIGNoYXJzLCBpbnQgb2ZmLCBpbnQgbGVuKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICByZXR1cm47IC8vIGRvbid0IGRvIGFueXRoaW5nLgotICAgIH0KLQotICAgIHByb3RlY3RlZCB2b2lkIGNvdWxkVGhyb3dTQVhFeGNlcHRpb24oU3RyaW5nIGVsZW1RTmFtZSkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgcmV0dXJuOyAvLyBkb24ndCBkbyBhbnl0aGluZy4KLSAgICB9Ci0KLSAgICB2b2lkIGFNZXRob2RJc0NhbGxlZCgpCi0gICAgewotCi0gICAgICAgIC8vIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGVycik7Ci0gICAgICAgIHJldHVybjsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIEBzZWUgU2VyaWFsaXphdGlvbkhhbmRsZXIjYXNDb250ZW50SGFuZGxlcigpCi0gICAgICovCi0gICAgcHVibGljIENvbnRlbnRIYW5kbGVyIGFzQ29udGVudEhhbmRsZXIoKSB0aHJvd3MgSU9FeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGNvdWxkVGhyb3dJT0V4Y2VwdGlvbigpOwotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0gICAgLyoqCi0gICAgICogQHNlZSBTZXJpYWxpemF0aW9uSGFuZGxlciNzZXRDb250ZW50SGFuZGxlcihvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcikKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRDb250ZW50SGFuZGxlcihDb250ZW50SGFuZGxlciBjaCkKLSAgICB7Ci0gICAgICAgIGFNZXRob2RJc0NhbGxlZCgpOwotICAgIH0KLSAgICAvKioKLSAgICAgKiBAc2VlIFNlcmlhbGl6YXRpb25IYW5kbGVyI2Nsb3NlKCkKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBjbG9zZSgpCi0gICAgewotICAgICAgICBhTWV0aG9kSXNDYWxsZWQoKTsKLSAgICB9Ci0gICAgLyoqCi0gICAgICogQHNlZSBTZXJpYWxpemF0aW9uSGFuZGxlciNnZXRPdXRwdXRGb3JtYXQoKQotICAgICAqLwotICAgIHB1YmxpYyBQcm9wZXJ0aWVzIGdldE91dHB1dEZvcm1hdCgpCi0gICAgewotICAgICAgICBhTWV0aG9kSXNDYWxsZWQoKTsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotICAgIC8qKgotICAgICAqIEBzZWUgU2VyaWFsaXphdGlvbkhhbmRsZXIjZ2V0T3V0cHV0U3RyZWFtKCkKLSAgICAgKi8KLSAgICBwdWJsaWMgT3V0cHV0U3RyZWFtIGdldE91dHB1dFN0cmVhbSgpCi0gICAgewotICAgICAgICBhTWV0aG9kSXNDYWxsZWQoKTsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotICAgIC8qKgotICAgICAqIEBzZWUgU2VyaWFsaXphdGlvbkhhbmRsZXIjZ2V0V3JpdGVyKCkKLSAgICAgKi8KLSAgICBwdWJsaWMgV3JpdGVyIGdldFdyaXRlcigpCi0gICAgewotICAgICAgICBhTWV0aG9kSXNDYWxsZWQoKTsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotICAgIC8qKgotICAgICAqIEBzZWUgU2VyaWFsaXphdGlvbkhhbmRsZXIjcmVzZXQoKQotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIHJlc2V0KCkKLSAgICB7Ci0gICAgICAgIGFNZXRob2RJc0NhbGxlZCgpOwotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotICAgIC8qKgotICAgICAqIEBzZWUgU2VyaWFsaXphdGlvbkhhbmRsZXIjc2VyaWFsaXplKG9yZy53M2MuZG9tLk5vZGUpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2VyaWFsaXplKE5vZGUgbm9kZSkgdGhyb3dzIElPRXhjZXB0aW9uCi0gICAgewotICAgICAgICBjb3VsZFRocm93SU9FeGNlcHRpb24oKTsKLSAgICB9Ci0gICAgLyoqCi0gICAgICogQHNlZSBTZXJpYWxpemF0aW9uSGFuZGxlciNzZXRDZGF0YVNlY3Rpb25FbGVtZW50cyhqYXZhLnV0aWwuVmVjdG9yKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldENkYXRhU2VjdGlvbkVsZW1lbnRzKFZlY3RvciBVUklfYW5kX2xvY2FsTmFtZXMpCi0gICAgewotICAgICAgICBhTWV0aG9kSXNDYWxsZWQoKTsKLSAgICB9Ci0gICAgLyoqCi0gICAgICogQHNlZSBTZXJpYWxpemF0aW9uSGFuZGxlciNzZXRFc2NhcGluZyhib29sZWFuKQotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIHNldEVzY2FwaW5nKGJvb2xlYW4gZXNjYXBlKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBjb3VsZFRocm93U0FYRXhjZXB0aW9uKCk7Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0gICAgLyoqCi0gICAgICogQHNlZSBTZXJpYWxpemF0aW9uSGFuZGxlciNzZXRJbmRlbnQoYm9vbGVhbikKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRJbmRlbnQoYm9vbGVhbiBpbmRlbnQpCi0gICAgewotICAgICAgICBhTWV0aG9kSXNDYWxsZWQoKTsKLSAgICB9Ci0gICAgLyoqCi0gICAgICogQHNlZSBTZXJpYWxpemF0aW9uSGFuZGxlciNzZXRJbmRlbnRBbW91bnQoaW50KQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEluZGVudEFtb3VudChpbnQgc3BhY2VzKQotICAgIHsKLSAgICAgICAgYU1ldGhvZElzQ2FsbGVkKCk7Ci0gICAgfQotICAgIC8qKgotICAgICAqIEBzZWUgU2VyaWFsaXphdGlvbkhhbmRsZXIjc2V0SXNTdGFuZGFsb25lKGJvb2xlYW4pCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0SXNTdGFuZGFsb25lKGJvb2xlYW4gaXNTdGFuZGFsb25lKQotICAgIHsKLSAgICAgICAgYU1ldGhvZElzQ2FsbGVkKCk7Ci0gICAgfQotICAgIC8qKgotICAgICAqIEBzZWUgU2VyaWFsaXphdGlvbkhhbmRsZXIjc2V0T3V0cHV0Rm9ybWF0KGphdmEudXRpbC5Qcm9wZXJ0aWVzKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldE91dHB1dEZvcm1hdChQcm9wZXJ0aWVzIGZvcm1hdCkKLSAgICB7Ci0gICAgICAgIGFNZXRob2RJc0NhbGxlZCgpOwotICAgIH0KLSAgICAvKioKLSAgICAgKiBAc2VlIFNlcmlhbGl6YXRpb25IYW5kbGVyI3NldE91dHB1dFN0cmVhbShqYXZhLmlvLk91dHB1dFN0cmVhbSkKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRPdXRwdXRTdHJlYW0oT3V0cHV0U3RyZWFtIG91dHB1dCkKLSAgICB7Ci0gICAgICAgIGFNZXRob2RJc0NhbGxlZCgpOwotICAgIH0KLSAgICAvKioKLSAgICAgKiBAc2VlIFNlcmlhbGl6YXRpb25IYW5kbGVyI3NldFZlcnNpb24oamF2YS5sYW5nLlN0cmluZykKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRWZXJzaW9uKFN0cmluZyB2ZXJzaW9uKQotICAgIHsKLSAgICAgICAgYU1ldGhvZElzQ2FsbGVkKCk7Ci0gICAgfQotICAgIC8qKgotICAgICAqIEBzZWUgU2VyaWFsaXphdGlvbkhhbmRsZXIjc2V0V3JpdGVyKGphdmEuaW8uV3JpdGVyKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFdyaXRlcihXcml0ZXIgd3JpdGVyKQotICAgIHsKLSAgICAgICAgYU1ldGhvZElzQ2FsbGVkKCk7Ci0gICAgfQotICAgIC8qKgotICAgICAqIEBzZWUgU2VyaWFsaXphdGlvbkhhbmRsZXIjc2V0VHJhbnNmb3JtZXIoamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lcikKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRUcmFuc2Zvcm1lcihUcmFuc2Zvcm1lciB0cmFuc2Zvcm1lcikKLSAgICB7Ci0gICAgICAgIGFNZXRob2RJc0NhbGxlZCgpOwotICAgIH0KLSAgICAvKioKLSAgICAgKiBAc2VlIFNlcmlhbGl6YXRpb25IYW5kbGVyI2dldFRyYW5zZm9ybWVyKCkKLSAgICAgKi8KLSAgICBwdWJsaWMgVHJhbnNmb3JtZXIgZ2V0VHJhbnNmb3JtZXIoKQotICAgIHsKLSAgICAgICAgYU1ldGhvZElzQ2FsbGVkKCk7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLSAgICAvKioKLSAgICAgKiBAc2VlIFNlcmlhbGl6YXRpb25IYW5kbGVyI2ZsdXNoUGVuZGluZygpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZmx1c2hQZW5kaW5nKCkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgY291bGRUaHJvd1NBWEV4Y2VwdGlvbigpOwotICAgIH0KLSAgICAvKioKLSAgICAgKiBAc2VlIEV4dGVuZGVkQ29udGVudEhhbmRsZXIjYWRkQXR0cmlidXRlKGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgYWRkQXR0cmlidXRlKAotICAgICAgICBTdHJpbmcgdXJpLAotICAgICAgICBTdHJpbmcgbG9jYWxOYW1lLAotICAgICAgICBTdHJpbmcgcmF3TmFtZSwKLSAgICAgICAgU3RyaW5nIHR5cGUsCi0gICAgICAgIFN0cmluZyB2YWx1ZSwKLSAgICAgICAgYm9vbGVhbiBYU0xBdHRyaWJ1dGUpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGNvdWxkVGhyb3dTQVhFeGNlcHRpb24oKTsKLSAgICB9Ci0gICAgLyoqCi0gICAgICogQHNlZSBFeHRlbmRlZENvbnRlbnRIYW5kbGVyI2FkZEF0dHJpYnV0ZXMob3JnLnhtbC5zYXguQXR0cmlidXRlcykKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBhZGRBdHRyaWJ1dGVzKEF0dHJpYnV0ZXMgYXR0cykgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgY291bGRUaHJvd1NBWEV4Y2VwdGlvbigpOwotICAgIH0KLSAgICAvKioKLSAgICAgKiBAc2VlIEV4dGVuZGVkQ29udGVudEhhbmRsZXIjYWRkQXR0cmlidXRlKGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgYWRkQXR0cmlidXRlKFN0cmluZyBuYW1lLCBTdHJpbmcgdmFsdWUpCi0gICAgewotICAgICAgICBhTWV0aG9kSXNDYWxsZWQoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAc2VlIEV4dGVuZGVkQ29udGVudEhhbmRsZXIjY2hhcmFjdGVycyhqYXZhLmxhbmcuU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGNoYXJhY3RlcnMoU3RyaW5nIGNoYXJzKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBjb3VsZFRocm93U0FYRXhjZXB0aW9uKCk7Ci0gICAgfQotICAgIC8qKgotICAgICAqIEBzZWUgRXh0ZW5kZWRDb250ZW50SGFuZGxlciNlbmRFbGVtZW50KGphdmEubGFuZy5TdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kRWxlbWVudChTdHJpbmcgZWxlbU5hbWUpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGNvdWxkVGhyb3dTQVhFeGNlcHRpb24oKTsKLSAgICB9Ci0gICAgLyoqCi0gICAgICogQHNlZSBFeHRlbmRlZENvbnRlbnRIYW5kbGVyI3N0YXJ0RG9jdW1lbnQoKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RG9jdW1lbnQoKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBjb3VsZFRocm93U0FYRXhjZXB0aW9uKCk7Ci0gICAgfQotICAgIC8qKgotICAgICAqIEBzZWUgRXh0ZW5kZWRDb250ZW50SGFuZGxlciNzdGFydEVsZW1lbnQoamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZykKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSwgU3RyaW5nIHFOYW1lKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBjb3VsZFRocm93U0FYRXhjZXB0aW9uKHFOYW1lKTsKLSAgICB9Ci0gICAgLyoqCi0gICAgICogQHNlZSBFeHRlbmRlZENvbnRlbnRIYW5kbGVyI3N0YXJ0RWxlbWVudChqYXZhLmxhbmcuU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudChTdHJpbmcgcU5hbWUpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGNvdWxkVGhyb3dTQVhFeGNlcHRpb24ocU5hbWUpOwotICAgIH0KLSAgICAvKioKLSAgICAgKiBAc2VlIEV4dGVuZGVkQ29udGVudEhhbmRsZXIjbmFtZXNwYWNlQWZ0ZXJTdGFydEVsZW1lbnQoamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZykKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBuYW1lc3BhY2VBZnRlclN0YXJ0RWxlbWVudChTdHJpbmcgdXJpLCBTdHJpbmcgcHJlZml4KQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBjb3VsZFRocm93U0FYRXhjZXB0aW9uKCk7Ci0gICAgfQotICAgIC8qKgotICAgICAqIEBzZWUgRXh0ZW5kZWRDb250ZW50SGFuZGxlciNzdGFydFByZWZpeE1hcHBpbmcoamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZywgYm9vbGVhbikKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBzdGFydFByZWZpeE1hcHBpbmcoCi0gICAgICAgIFN0cmluZyBwcmVmaXgsCi0gICAgICAgIFN0cmluZyB1cmksCi0gICAgICAgIGJvb2xlYW4gc2hvdWxkRmx1c2gpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGNvdWxkVGhyb3dTQVhFeGNlcHRpb24oKTsKLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLSAgICAvKioKLSAgICAgKiBAc2VlIEV4dGVuZGVkQ29udGVudEhhbmRsZXIjZW50aXR5UmVmZXJlbmNlKGphdmEubGFuZy5TdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW50aXR5UmVmZXJlbmNlKFN0cmluZyBlbnRpdHlOYW1lKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBjb3VsZFRocm93U0FYRXhjZXB0aW9uKCk7Ci0gICAgfQotICAgIC8qKgotICAgICAqIEBzZWUgRXh0ZW5kZWRDb250ZW50SGFuZGxlciNnZXROYW1lc3BhY2VNYXBwaW5ncygpCi0gICAgICovCi0gICAgcHVibGljIE5hbWVzcGFjZU1hcHBpbmdzIGdldE5hbWVzcGFjZU1hcHBpbmdzKCkKLSAgICB7Ci0gICAgICAgIGFNZXRob2RJc0NhbGxlZCgpOwotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0gICAgLyoqCi0gICAgICogQHNlZSBFeHRlbmRlZENvbnRlbnRIYW5kbGVyI2dldFByZWZpeChqYXZhLmxhbmcuU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0UHJlZml4KFN0cmluZyB1cmkpCi0gICAgewotICAgICAgICBhTWV0aG9kSXNDYWxsZWQoKTsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotICAgIC8qKgotICAgICAqIEBzZWUgRXh0ZW5kZWRDb250ZW50SGFuZGxlciNnZXROYW1lc3BhY2VVUkkoamF2YS5sYW5nLlN0cmluZywgYm9vbGVhbikKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWVzcGFjZVVSSShTdHJpbmcgbmFtZSwgYm9vbGVhbiBpc0VsZW1lbnQpCi0gICAgewotICAgICAgICBhTWV0aG9kSXNDYWxsZWQoKTsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotICAgIC8qKgotICAgICAqIEBzZWUgRXh0ZW5kZWRDb250ZW50SGFuZGxlciNnZXROYW1lc3BhY2VVUklGcm9tUHJlZml4KGphdmEubGFuZy5TdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXROYW1lc3BhY2VVUklGcm9tUHJlZml4KFN0cmluZyBwcmVmaXgpCi0gICAgewotICAgICAgICBhTWV0aG9kSXNDYWxsZWQoKTsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotICAgIC8qKgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjc2V0RG9jdW1lbnRMb2NhdG9yKG9yZy54bWwuc2F4LkxvY2F0b3IpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RG9jdW1lbnRMb2NhdG9yKExvY2F0b3IgYXJnMCkKLSAgICB7Ci0gICAgICAgIGFNZXRob2RJc0NhbGxlZCgpOwotICAgIH0KLSAgICAvKioKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI2VuZERvY3VtZW50KCkKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbmREb2N1bWVudCgpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGNvdWxkVGhyb3dTQVhFeGNlcHRpb24oKTsKLSAgICB9Ci0gICAgLyoqCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNzdGFydFByZWZpeE1hcHBpbmcoamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZykKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydFByZWZpeE1hcHBpbmcoU3RyaW5nIGFyZzAsIFN0cmluZyBhcmcxKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBjb3VsZFRocm93U0FYRXhjZXB0aW9uKCk7Ci0gICAgfQotICAgIC8qKgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjZW5kUHJlZml4TWFwcGluZyhqYXZhLmxhbmcuU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZFByZWZpeE1hcHBpbmcoU3RyaW5nIGFyZzApIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGNvdWxkVGhyb3dTQVhFeGNlcHRpb24oKTsKLSAgICB9Ci0gICAgLyoqCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNzdGFydEVsZW1lbnQoamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZywgb3JnLnhtbC5zYXguQXR0cmlidXRlcykKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQoCi0gICAgICAgIFN0cmluZyBhcmcwLAotICAgICAgICBTdHJpbmcgYXJnMSwKLSAgICAgICAgU3RyaW5nIGFyZzIsCi0gICAgICAgIEF0dHJpYnV0ZXMgYXJnMykKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgY291bGRUaHJvd1NBWEV4Y2VwdGlvbigpOwotICAgIH0KLSAgICAvKioKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI2VuZEVsZW1lbnQoamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZykKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbmRFbGVtZW50KFN0cmluZyBhcmcwLCBTdHJpbmcgYXJnMSwgU3RyaW5nIGFyZzIpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGNvdWxkVGhyb3dTQVhFeGNlcHRpb24oKTsKLSAgICB9Ci0gICAgLyoqCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNjaGFyYWN0ZXJzKGNoYXJbXSwgaW50LCBpbnQpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY2hhcmFjdGVycyhjaGFyW10gYXJnMCwgaW50IGFyZzEsIGludCBhcmcyKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBjb3VsZFRocm93U0FYRXhjZXB0aW9uKGFyZzAsIGFyZzEsIGFyZzIpOwotICAgIH0KLSAgICAvKioKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI2lnbm9yYWJsZVdoaXRlc3BhY2UoY2hhcltdLCBpbnQsIGludCkKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBpZ25vcmFibGVXaGl0ZXNwYWNlKGNoYXJbXSBhcmcwLCBpbnQgYXJnMSwgaW50IGFyZzIpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGNvdWxkVGhyb3dTQVhFeGNlcHRpb24oKTsKLSAgICB9Ci0gICAgLyoqCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZykKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oU3RyaW5nIGFyZzAsIFN0cmluZyBhcmcxKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBjb3VsZFRocm93U0FYRXhjZXB0aW9uKCk7Ci0gICAgfQotICAgIC8qKgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjc2tpcHBlZEVudGl0eShqYXZhLmxhbmcuU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNraXBwZWRFbnRpdHkoU3RyaW5nIGFyZzApIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGNvdWxkVGhyb3dTQVhFeGNlcHRpb24oKTsKLSAgICB9Ci0gICAgLyoqCi0gICAgICogQHNlZSBFeHRlbmRlZExleGljYWxIYW5kbGVyI2NvbW1lbnQoamF2YS5sYW5nLlN0cmluZykKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBjb21tZW50KFN0cmluZyBjb21tZW50KSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBjb3VsZFRocm93U0FYRXhjZXB0aW9uKCk7Ci0gICAgfQotICAgIC8qKgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguZXh0LkxleGljYWxIYW5kbGVyI3N0YXJ0RFREKGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnREVEQoU3RyaW5nIGFyZzAsIFN0cmluZyBhcmcxLCBTdHJpbmcgYXJnMikKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgY291bGRUaHJvd1NBWEV4Y2VwdGlvbigpOwotICAgIH0KLSAgICAvKioKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LmV4dC5MZXhpY2FsSGFuZGxlciNlbmREVEQoKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZERURCgpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGNvdWxkVGhyb3dTQVhFeGNlcHRpb24oKTsKLSAgICB9Ci0gICAgLyoqCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXIjc3RhcnRFbnRpdHkoamF2YS5sYW5nLlN0cmluZykKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydEVudGl0eShTdHJpbmcgYXJnMCkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgY291bGRUaHJvd1NBWEV4Y2VwdGlvbigpOwotICAgIH0KLSAgICAvKioKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LmV4dC5MZXhpY2FsSGFuZGxlciNlbmRFbnRpdHkoamF2YS5sYW5nLlN0cmluZykKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbmRFbnRpdHkoU3RyaW5nIGFyZzApIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGNvdWxkVGhyb3dTQVhFeGNlcHRpb24oKTsKLSAgICB9Ci0gICAgLyoqCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXIjc3RhcnRDREFUQSgpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnRDREFUQSgpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGNvdWxkVGhyb3dTQVhFeGNlcHRpb24oKTsKLSAgICB9Ci0gICAgLyoqCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXIjZW5kQ0RBVEEoKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZENEQVRBKCkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgY291bGRUaHJvd1NBWEV4Y2VwdGlvbigpOwotICAgIH0KLSAgICAvKioKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LmV4dC5MZXhpY2FsSGFuZGxlciNjb21tZW50KGNoYXJbXSwgaW50LCBpbnQpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY29tbWVudChjaGFyW10gYXJnMCwgaW50IGFyZzEsIGludCBhcmcyKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBjb3VsZFRocm93U0FYRXhjZXB0aW9uKCk7Ci0gICAgfQotICAgIC8qKgotICAgICAqIEBzZWUgWFNMT3V0cHV0QXR0cmlidXRlcyNnZXREb2N0eXBlUHVibGljKCkKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldERvY3R5cGVQdWJsaWMoKQotICAgIHsKLSAgICAgICAgYU1ldGhvZElzQ2FsbGVkKCk7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLSAgICAvKioKLSAgICAgKiBAc2VlIFhTTE91dHB1dEF0dHJpYnV0ZXMjZ2V0RG9jdHlwZVN5c3RlbSgpCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXREb2N0eXBlU3lzdGVtKCkKLSAgICB7Ci0gICAgICAgIGFNZXRob2RJc0NhbGxlZCgpOwotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0gICAgLyoqCi0gICAgICogQHNlZSBYU0xPdXRwdXRBdHRyaWJ1dGVzI2dldEVuY29kaW5nKCkKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEVuY29kaW5nKCkKLSAgICB7Ci0gICAgICAgIGFNZXRob2RJc0NhbGxlZCgpOwotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0gICAgLyoqCi0gICAgICogQHNlZSBYU0xPdXRwdXRBdHRyaWJ1dGVzI2dldEluZGVudCgpCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0SW5kZW50KCkKLSAgICB7Ci0gICAgICAgIGFNZXRob2RJc0NhbGxlZCgpOwotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotICAgIC8qKgotICAgICAqIEBzZWUgWFNMT3V0cHV0QXR0cmlidXRlcyNnZXRJbmRlbnRBbW91bnQoKQotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0SW5kZW50QW1vdW50KCkKLSAgICB7Ci0gICAgICAgIGFNZXRob2RJc0NhbGxlZCgpOwotICAgICAgICByZXR1cm4gMDsKLSAgICB9Ci0gICAgLyoqCi0gICAgICogQHNlZSBYU0xPdXRwdXRBdHRyaWJ1dGVzI2dldE1lZGlhVHlwZSgpCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRNZWRpYVR5cGUoKQotICAgIHsKLSAgICAgICAgYU1ldGhvZElzQ2FsbGVkKCk7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLSAgICAvKioKLSAgICAgKiBAc2VlIFhTTE91dHB1dEF0dHJpYnV0ZXMjZ2V0T21pdFhNTERlY2xhcmF0aW9uKCkKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXRPbWl0WE1MRGVjbGFyYXRpb24oKQotICAgIHsKLSAgICAgICAgYU1ldGhvZElzQ2FsbGVkKCk7Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0gICAgLyoqCi0gICAgICogQHNlZSBYU0xPdXRwdXRBdHRyaWJ1dGVzI2dldFN0YW5kYWxvbmUoKQotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3RhbmRhbG9uZSgpCi0gICAgewotICAgICAgICBhTWV0aG9kSXNDYWxsZWQoKTsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotICAgIC8qKgotICAgICAqIEBzZWUgWFNMT3V0cHV0QXR0cmlidXRlcyNnZXRWZXJzaW9uKCkKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFZlcnNpb24oKQotICAgIHsKLSAgICAgICAgYU1ldGhvZElzQ2FsbGVkKCk7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLSAgICAvKioKLSAgICAgKiBAc2VlIFhTTE91dHB1dEF0dHJpYnV0ZXMjc2V0RG9jdHlwZShqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldERvY3R5cGUoU3RyaW5nIHN5c3RlbSwgU3RyaW5nIHB1YikKLSAgICB7Ci0gICAgICAgIGFNZXRob2RJc0NhbGxlZCgpOwotICAgIH0KLSAgICAvKioKLSAgICAgKiBAc2VlIFhTTE91dHB1dEF0dHJpYnV0ZXMjc2V0RG9jdHlwZVB1YmxpYyhqYXZhLmxhbmcuU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldERvY3R5cGVQdWJsaWMoU3RyaW5nIGRvY3R5cGUpCi0gICAgewotICAgICAgICBhTWV0aG9kSXNDYWxsZWQoKTsKLSAgICB9Ci0gICAgLyoqCi0gICAgICogQHNlZSBYU0xPdXRwdXRBdHRyaWJ1dGVzI3NldERvY3R5cGVTeXN0ZW0oamF2YS5sYW5nLlN0cmluZykKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXREb2N0eXBlU3lzdGVtKFN0cmluZyBkb2N0eXBlKQotICAgIHsKLSAgICAgICAgYU1ldGhvZElzQ2FsbGVkKCk7Ci0gICAgfQotICAgIC8qKgotICAgICAqIEBzZWUgWFNMT3V0cHV0QXR0cmlidXRlcyNzZXRFbmNvZGluZyhqYXZhLmxhbmcuU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEVuY29kaW5nKFN0cmluZyBlbmNvZGluZykKLSAgICB7Ci0gICAgICAgIGFNZXRob2RJc0NhbGxlZCgpOwotICAgIH0KLSAgICAvKioKLSAgICAgKiBAc2VlIFhTTE91dHB1dEF0dHJpYnV0ZXMjc2V0TWVkaWFUeXBlKGphdmEubGFuZy5TdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0TWVkaWFUeXBlKFN0cmluZyBtZWRpYXR5cGUpCi0gICAgewotICAgICAgICBhTWV0aG9kSXNDYWxsZWQoKTsKLSAgICB9Ci0gICAgLyoqCi0gICAgICogQHNlZSBYU0xPdXRwdXRBdHRyaWJ1dGVzI3NldE9taXRYTUxEZWNsYXJhdGlvbihib29sZWFuKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldE9taXRYTUxEZWNsYXJhdGlvbihib29sZWFuIGIpCi0gICAgewotICAgICAgICBhTWV0aG9kSXNDYWxsZWQoKTsKLSAgICB9Ci0gICAgLyoqCi0gICAgICogQHNlZSBYU0xPdXRwdXRBdHRyaWJ1dGVzI3NldFN0YW5kYWxvbmUoamF2YS5sYW5nLlN0cmluZykKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRTdGFuZGFsb25lKFN0cmluZyBzdGFuZGFsb25lKQotICAgIHsKLSAgICAgICAgYU1ldGhvZElzQ2FsbGVkKCk7Ci0gICAgfQotICAgIC8qKgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguZXh0LkRlY2xIYW5kbGVyI2VsZW1lbnREZWNsKGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZWxlbWVudERlY2woU3RyaW5nIGFyZzAsIFN0cmluZyBhcmcxKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBjb3VsZFRocm93U0FYRXhjZXB0aW9uKCk7Ci0gICAgfQotICAgIC8qKgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguZXh0LkRlY2xIYW5kbGVyI2F0dHJpYnV0ZURlY2woamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZykKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBhdHRyaWJ1dGVEZWNsKAotICAgICAgICBTdHJpbmcgYXJnMCwKLSAgICAgICAgU3RyaW5nIGFyZzEsCi0gICAgICAgIFN0cmluZyBhcmcyLAotICAgICAgICBTdHJpbmcgYXJnMywKLSAgICAgICAgU3RyaW5nIGFyZzQpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGNvdWxkVGhyb3dTQVhFeGNlcHRpb24oKTsKLSAgICB9Ci0gICAgLyoqCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5leHQuRGVjbEhhbmRsZXIjaW50ZXJuYWxFbnRpdHlEZWNsKGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgaW50ZXJuYWxFbnRpdHlEZWNsKFN0cmluZyBhcmcwLCBTdHJpbmcgYXJnMSkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgY291bGRUaHJvd1NBWEV4Y2VwdGlvbigpOwotICAgIH0KLSAgICAvKioKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LmV4dC5EZWNsSGFuZGxlciNleHRlcm5hbEVudGl0eURlY2woamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZykKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBleHRlcm5hbEVudGl0eURlY2woU3RyaW5nIGFyZzAsIFN0cmluZyBhcmcxLCBTdHJpbmcgYXJnMikKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgY291bGRUaHJvd1NBWEV4Y2VwdGlvbigpOwotICAgIH0KLSAgICAvKioKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkVycm9ySGFuZGxlciN3YXJuaW5nKG9yZy54bWwuc2F4LlNBWFBhcnNlRXhjZXB0aW9uKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHdhcm5pbmcoU0FYUGFyc2VFeGNlcHRpb24gYXJnMCkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgY291bGRUaHJvd1NBWEV4Y2VwdGlvbigpOwotICAgIH0KLSAgICAvKioKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkVycm9ySGFuZGxlciNlcnJvcihvcmcueG1sLnNheC5TQVhQYXJzZUV4Y2VwdGlvbikKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlcnJvcihTQVhQYXJzZUV4Y2VwdGlvbiBhcmcwKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBjb3VsZFRocm93U0FYRXhjZXB0aW9uKCk7Ci0gICAgfQotICAgIC8qKgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguRXJyb3JIYW5kbGVyI2ZhdGFsRXJyb3Iob3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb24pCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZmF0YWxFcnJvcihTQVhQYXJzZUV4Y2VwdGlvbiBhcmcwKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBjb3VsZFRocm93U0FYRXhjZXB0aW9uKCk7Ci0gICAgfQotICAgIC8qKgotICAgICAqIEBzZWUgU2VyaWFsaXplciNhc0RPTVNlcmlhbGl6ZXIoKQotICAgICAqLwotICAgIHB1YmxpYyBET01TZXJpYWxpemVyIGFzRE9NU2VyaWFsaXplcigpIHRocm93cyBJT0V4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgY291bGRUaHJvd0lPRXhjZXB0aW9uKCk7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgU2VyaWFsaXphdGlvbkhhbmRsZXIjc2V0TmFtZXNwYWNlTWFwcGluZ3MoTmFtZXNwYWNlTWFwcGluZ3MpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0TmFtZXNwYWNlTWFwcGluZ3MoTmFtZXNwYWNlTWFwcGluZ3MgbWFwcGluZ3MpIHsKLSAgICAgICAgYU1ldGhvZElzQ2FsbGVkKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBFeHRlbmRlZENvbnRlbnRIYW5kbGVyI3NldFNvdXJjZUxvY2F0b3IoamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2VMb2NhdG9yKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFNvdXJjZUxvY2F0b3IoU291cmNlTG9jYXRvciBsb2NhdG9yKQotICAgIHsKLSAgICAgICAgYU1ldGhvZElzQ2FsbGVkKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBFeHRlbmRlZENvbnRlbnRIYW5kbGVyI2FkZFVuaXF1ZUF0dHJpYnV0ZShqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nLCBpbnQpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgYWRkVW5pcXVlQXR0cmlidXRlKFN0cmluZyBuYW1lLCBTdHJpbmcgdmFsdWUsIGludCBmbGFncykKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgY291bGRUaHJvd1NBWEV4Y2VwdGlvbigpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgRXh0ZW5kZWRDb250ZW50SGFuZGxlciNjaGFyYWN0ZXJzKG9yZy53M2MuZG9tLk5vZGUpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY2hhcmFjdGVycyhOb2RlIG5vZGUpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGNvdWxkVGhyb3dTQVhFeGNlcHRpb24oKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAc2VlIEV4dGVuZGVkQ29udGVudEhhbmRsZXIjYWRkWFNMQXR0cmlidXRlKGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgYWRkWFNMQXR0cmlidXRlKFN0cmluZyBxTmFtZSwgU3RyaW5nIHZhbHVlLCBTdHJpbmcgdXJpKQotICAgIHsKLSAgICAgICAgYU1ldGhvZElzQ2FsbGVkKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBFeHRlbmRlZENvbnRlbnRIYW5kbGVyI2FkZEF0dHJpYnV0ZShqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGFkZEF0dHJpYnV0ZShTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxOYW1lLCBTdHJpbmcgcmF3TmFtZSwgU3RyaW5nIHR5cGUsIFN0cmluZyB2YWx1ZSkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgY291bGRUaHJvd1NBWEV4Y2VwdGlvbigpOwotICAgIH0KLSAgICAvKioKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkRUREhhbmRsZXIjbm90YXRpb25EZWNsKGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgbm90YXRpb25EZWNsKFN0cmluZyBhcmcwLCBTdHJpbmcgYXJnMSwgU3RyaW5nIGFyZzIpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGNvdWxkVGhyb3dTQVhFeGNlcHRpb24oKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkRUREhhbmRsZXIjdW5wYXJzZWRFbnRpdHlEZWNsKGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdW5wYXJzZWRFbnRpdHlEZWNsKAotICAgICAgICBTdHJpbmcgYXJnMCwKLSAgICAgICAgU3RyaW5nIGFyZzEsCi0gICAgICAgIFN0cmluZyBhcmcyLAotICAgICAgICBTdHJpbmcgYXJnMykKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0gICAgICAgIGNvdWxkVGhyb3dTQVhFeGNlcHRpb24oKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAc2VlIFNlcmlhbGl6YXRpb25IYW5kbGVyI3NldERUREVudGl0eUV4cGFuc2lvbihib29sZWFuKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldERUREVudGl0eUV4cGFuc2lvbihib29sZWFuIGV4cGFuZCkgewotICAgICAgICBhTWV0aG9kSXNDYWxsZWQoKTsKLQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvRW5jb2RpbmdJbmZvLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL0VuY29kaW5nSW5mby5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2MGQ1MDNkLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvRW5jb2RpbmdJbmZvLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw1MTQgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRW5jb2RpbmdJbmZvLmphdmEsdiAxLjIuNC4yIDIwMDUvMDkvMTUgMTI6MDE6MjQgc3VyZXNoX2VtYWlsaWQgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXI7Ci0KLWltcG9ydCBqYXZhLmlvLlVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb247Ci0KLS8qKgotICogSG9sZHMgaW5mb3JtYXRpb24gYWJvdXQgYSBnaXZlbiBlbmNvZGluZywgd2hpY2ggaXMgdGhlIEphdmEgbmFtZSBmb3IgdGhlCi0gKiBlbmNvZGluZywgdGhlIGVxdWl2YWxlbnQgSVNPIG5hbWUuCi0gKiA8cD4KLSAqIEFuIG9iamVjdCBvZiB0aGlzIHR5cGUgaGFzIHR3byB1c2VmdWwgbWV0aG9kcwotICogPHByZT4KLSAqIGlzSW5FbmNvZGluZyhjaGFyIGNoKTsKLSAqIDwvcHJlPgotICogd2hpY2ggY2FuIGJlIGNhbGxlZCBpZiB0aGUgY2hhcmFjdGVyIGlzIG5vdCB0aGUgaGlnaCBvbmUgaW4KLSAqIGEgc3Vycm9nYXRlIHBhaXIgYW5kOgotICogPHByZT4KLSAqIGlzSW5FbmNvZGluZyhjaGFyIGhpZ2gsIGNoYXIgbG93KTsKLSAqIDwvcHJlPgotICogd2hpY2ggY2FuIGJlIGNhbGxlZCBpZiB0aGUgdHdvIGNoYXJhY3RlcnMgZnJvbSBhIGhpZ2gvbG93IHN1cnJvZ2F0ZSBwYWlyLgotICogPHA+Ci0gKiBBbiBFbmNvZGluZ0luZm8gb2JqZWN0IGlzIGEgbm9kZSBpbiBhIGJpbmFyeSBzZWFyY2ggdHJlZS4gU3VjaCBhIG5vZGUKLSAqIHdpbGwgYW5zd2VyIGlmIGEgY2hhcmFjdGVyIGlzIGluIHRoZSBlbmNvZGluZywgYW5kIGRvIHNvIGZvciBhIGdpdmVuCi0gKiByYW5nZSBvZiB1bmljb2RlIHZhbHVlcyAoPGNvZGU+bV9maXJzdDwvY29kZT4gdG8KLSAqIDxjb2RlPm1fbGFzdDwvY29kZT4pLiBJdCB3aWxsIGhhbmRsZSBhIGNlcnRhaW4gcmFuZ2Ugb2YgdmFsdWVzCi0gKiBleHBsaWNpdGx5ICg8Y29kZT5tX2V4cGxGaXJzdDwvY29kZT4gdG8gPGNvZGU+bV9leHBsTGFzdDwvY29kZT4pLgotICogSWYgdGhlIHVuaWNvZGUgcG9pbnQgaXMgYmVmb3JlIHRoYXQgZXhwbGljaXQgcmFuZ2UsIHRoYXQgaXMgaXQKLSAqIGlzIGluIHRoZSByYW5nZSA8Y29kZT5tX2ZpcnN0IDw9IHZhbHVlIDwgbV9leHBsRmlyc3Q8L2NvZGU+LCB0aGVuIGl0IHdpbGwgZGVsZWdhdGUgdG8gYW5vdGhlciBFbmNvZGluZ0luZm8gb2JqZWN0IGZvciBUaGUgcm9vdAotICogb2Ygc3VjaCBhIHRyZWUsIG1fYmVmb3JlLiAgTGlrZXdpc2UgZm9yIHZhbHVlcyBpbiB0aGUgcmFuZ2UKLSAqIDxjb2RlPm1fZXhwbExhc3QgPCB2YWx1ZSA8PSBtX2xhc3Q8L2NvZGU+LCBidXQgZGVsZ2F0aW5nIHRvIDxjb2RlPm1fYWZ0ZXI8L2NvZGU+Ci0gKiA8cD4KLSAqIEFjdHVhbGx5IGZpZ3VyaW5nIG91dCBpZiBhIGNvZGUgcG9pbnQgaXMgaW4gdGhlIGVuY29kaW5nIGlzIGV4cGVuc2l2ZS4gU28gdGhlCi0gKiBwdXJwb3NlIG9mIHRoaXMgdHJlZSBpcyB0byBjYWNoZSBzdWNoIGRldGVybWluYXRpb25zLCBhbmQgbm90IHRvIGJ1aWxkIHRoZQotICogZW50aXJlIHRyZWUgb2YgaW5mb3JtYXRpb24gYXQgdGhlIHN0YXJ0LCBidXQgb25seSBidWlsZCB1cCBhcyBtdWNoIG9mIHRoZQotICogdHJlZSBhcyBpcyB1c2VkIGR1cmluZyB0aGUgdHJhbnNmb3JtYXRpb24uCi0gKiA8cD4KLSAqIFRoaXMgQ2xhc3MgaXMgbm90IGEgcHVibGljIEFQSSwgYW5kIHNob3VsZCBvbmx5IGJlIHVzZWQgaW50ZXJuYWxseSB3aXRoaW4KLSAqIHRoZSBzZXJpYWxpemVyLgotICoKLSAqIEB4c2wudXNhZ2UgaW50ZXJuYWwKLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIEVuY29kaW5nSW5mbyBleHRlbmRzIE9iamVjdAotewotCi0gICAgLyoqCi0gICAgICogVGhlIElTTyBlbmNvZGluZyBuYW1lLgotICAgICAqLwotICAgIGZpbmFsIFN0cmluZyBuYW1lOwotCi0gICAgLyoqCi0gICAgICogVGhlIG5hbWUgdXNlZCBieSB0aGUgSmF2YSBjb252ZXJ0b3IuCi0gICAgICovCi0gICAgZmluYWwgU3RyaW5nIGphdmFOYW1lOwotCi0gICAgLyoqCi0gICAgICogQSBoZWxwZXIgb2JqZWN0IHRoYXQgd2UgY2FuIGFzayBpZiBhCi0gICAgICogc2luZ2xlIGNoYXIsIG9yIGEgc3Vycm9nYXRlIFVURi0xNiBwYWlyCi0gICAgICogb2YgY2hhcnMgdGhhdCBmb3JtIGEgc2luZ2xlIGNoYXJhY3RlciwKLSAgICAgKiBpcyBpbiB0aGlzIGVuY29kaW5nLgotICAgICAqLwotICAgIHByaXZhdGUgSW5FbmNvZGluZyBtX2VuY29kaW5nOwotCi0gICAgLyoqCi0gICAgICogVGhpcyBpcyBub3QgYSBwdWJsaWMgQVBJLiBJdCByZXR1cm5zIHRydWUgaWYgdGhlCi0gICAgICogY2hhciBpbiBxdWVzdGlvbiBpcyBpbiB0aGUgZW5jb2RpbmcuCi0gICAgICogQHBhcmFtIGNoIHRoZSBjaGFyIGluIHF1ZXN0aW9uLgotICAgICAqIEB4c2wudXNhZ2UgaW50ZXJuYWwKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0luRW5jb2RpbmcoY2hhciBjaCkgewotICAgICAgICBpZiAobV9lbmNvZGluZyA9PSBudWxsKSB7Ci0gICAgICAgICAgICBtX2VuY29kaW5nID0gbmV3IEVuY29kaW5nSW1wbCgpOwotCi0gICAgICAgICAgICAvLyBPbmUgY291bGQgcHV0IGFsdGVybmF0ZSBsb2dpYyBpbiBoZXJlIHRvCi0gICAgICAgICAgICAvLyBpbnN0YW50aWF0ZSBhbm90aGVyIG9iamVjdCB0aGF0IGltcGxlbWVudHMgdGhlCi0gICAgICAgICAgICAvLyBJbkVuY29kaW5nIGludGVyZmFjZS4gRm9yIGV4YW1wbGUgaWYgdGhlIEpSRSBpcyAxLjQgb3IgdXAKLSAgICAgICAgICAgIC8vIHdlIGNvdWxkIGhhdmUgYW4gb2JqZWN0IHRoYXQgdXNlcyBKUkUgMS40IG1ldGhvZHMKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbV9lbmNvZGluZy5pc0luRW5jb2RpbmcoY2gpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgaXMgbm90IGEgcHVibGljIEFQSS4gSXQgcmV0dXJucyB0cnVlIGlmIHRoZQotICAgICAqIGNoYXJhY3RlciBmb3JtZWQgYnkgdGhlIGhpZ2gvbG93IHBhaXIgaXMgaW4gdGhlIGVuY29kaW5nLgotICAgICAqIEBwYXJhbSBoaWdoIGEgY2hhciB0aGF0IHRoZSBhIGhpZ2ggY2hhciBvZiBhIGhpZ2gvbG93IHN1cnJvZ2F0ZSBwYWlyLgotICAgICAqIEBwYXJhbSBsb3cgYSBjaGFyIHRoYXQgaXMgdGhlIGxvdyBjaGFyIG9mIGEgaGlnaC9sb3cgc3Vycm9nYXRlIHBhaXIuCi0gICAgICogQHhzbC51c2FnZSBpbnRlcm5hbAotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzSW5FbmNvZGluZyhjaGFyIGhpZ2gsIGNoYXIgbG93KSB7Ci0gICAgICAgIGlmIChtX2VuY29kaW5nID09IG51bGwpIHsKLSAgICAgICAgICAgIG1fZW5jb2RpbmcgPSBuZXcgRW5jb2RpbmdJbXBsKCk7Ci0KLSAgICAgICAgICAgIC8vIE9uZSBjb3VsZCBwdXQgYWx0ZXJuYXRlIGxvZ2ljIGluIGhlcmUgdG8KLSAgICAgICAgICAgIC8vIGluc3RhbnRpYXRlIGFub3RoZXIgb2JqZWN0IHRoYXQgaW1wbGVtZW50cyB0aGUKLSAgICAgICAgICAgIC8vIEluRW5jb2RpbmcgaW50ZXJmYWNlLiBGb3IgZXhhbXBsZSBpZiB0aGUgSlJFIGlzIDEuNCBvciB1cAotICAgICAgICAgICAgLy8gd2UgY291bGQgaGF2ZSBhbiBvYmplY3QgdGhhdCB1c2VzIEpSRSAxLjQgbWV0aG9kcwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBtX2VuY29kaW5nLmlzSW5FbmNvZGluZyhoaWdoLCBsb3cpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENyZWF0ZSBhbiBFbmNvZGluZ0luZm8gb2JqZWN0IGJhc2VkIG9uIHRoZSBJU08gbmFtZSBhbmQgSmF2YSBuYW1lLgotICAgICAqIElmIGJvdGggcGFyYW1ldGVycyBhcmUgbnVsbCBhbnkgY2hhcmFjdGVyIHdpbGwgYmUgY29uc2lkZXJlZCB0bwotICAgICAqIGJlIGluIHRoZSBlbmNvZGluZy4gVGhpcyBpcyB1c2VmdWwgZm9yIHdoZW4gdGhlIHNlcmlhbGl6ZXIgaXMgaW4KLSAgICAgKiB0ZW1wb3Jhcnkgb3V0cHV0IHN0YXRlLCBhbmQgaGFzIG5vIGFzc2NpYXRlZCBlbmNvZGluZy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lIHJlZmVyZW5jZSB0byB0aGUgSVNPIG5hbWUuCi0gICAgICogQHBhcmFtIGphdmFOYW1lIHJlZmVyZW5jZSB0byB0aGUgSmF2YSBlbmNvZGluZyBuYW1lLgotICAgICAqLwotICAgIHB1YmxpYyBFbmNvZGluZ0luZm8oU3RyaW5nIG5hbWUsIFN0cmluZyBqYXZhTmFtZSkKLSAgICB7Ci0KLSAgICAgICAgdGhpcy5uYW1lID0gbmFtZTsKLSAgICAgICAgdGhpcy5qYXZhTmFtZSA9IGphdmFOYW1lOwotICAgIH0KLQotCi0KLSAgICAvKioKLSAgICAgKiBBIHNpbXBsZSBpbnRlcmZhY2UgdG8gaXNvbGF0ZSB0aGUgaW1wbGVtZW50YXRpb24uCi0gICAgICogV2UgY291bGQgYWxzbyB1c2Ugc29tZSBuZXcgSlJFIDEuNCBtZXRob2RzIGluIGFub3RoZXIgaW1wbGVtZW50YXRpb24KLSAgICAgKiBwcm92aWRlZCB3ZSB1c2UgcmVmbGVjdGlvbiB3aXRoIHRoZW0uCi0gICAgICogPHA+Ci0gICAgICogVGhpcyBpbnRlcmZhY2UgaXMgbm90IGEgcHVibGljIEFQSSwKLSAgICAgKiBhbmQgc2hvdWxkIG9ubHkgYmUgdXNlZCBpbnRlcm5hbGx5IHdpdGhpbiB0aGUgc2VyaWFsaXplci4KLSAgICAgKiBAeHNsLnVzYWdlIGludGVybmFsCi0gICAgICovCi0gICAgcHJpdmF0ZSBpbnRlcmZhY2UgSW5FbmNvZGluZyB7Ci0gICAgICAgIC8qKgotICAgICAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIGNoYXIgaXMgaW4gdGhlIGVuY29kaW5nCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc0luRW5jb2RpbmcoY2hhciBjaCk7Ci0gICAgICAgIC8qKgotICAgICAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIGhpZ2gvbG93IHN1cnJvZ2F0ZSBwYWlyIGZvcm1zCi0gICAgICAgICAqIGEgY2hhcmFjdGVyIHRoYXQgaXMgaW4gdGhlIGVuY29kaW5nLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIGJvb2xlYW4gaXNJbkVuY29kaW5nKGNoYXIgaGlnaCwgY2hhciBsb3cpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgY2xhc3MgaW1wbGVtZW50cyB0aGUKLSAgICAgKi8KLSAgICBwcml2YXRlIGNsYXNzIEVuY29kaW5nSW1wbCBpbXBsZW1lbnRzIEluRW5jb2RpbmcgewotCi0KLQotICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc0luRW5jb2RpbmcoY2hhciBjaDEpIHsKLSAgICAgICAgICAgIGZpbmFsIGJvb2xlYW4gcmV0OwotICAgICAgICAgICAgaW50IGNvZGVQb2ludCA9IEVuY29kaW5ncy50b0NvZGVQb2ludChjaDEpOwotICAgICAgICAgICAgaWYgKGNvZGVQb2ludCA8IG1fZXhwbEZpcnN0KSB7Ci0gICAgICAgICAgICAgICAgLy8gVGhlIHVuaWNvZGUgdmFsdWUgaXMgYmVmb3JlIHRoZSByYW5nZQotICAgICAgICAgICAgICAgIC8vIHRoYXQgd2UgZXhwbGljdGx5IG1hbmFnZSwgc28gd2UgZGVsZWdhdGUgdGhlIGFuc3dlci4KLQotICAgICAgICAgICAgICAgIC8vIElmIHdlIGRvbid0IGhhdmUgYW4gbV9iZWZvcmUgb2JqZWN0IHRvIGRlbGVnYXRlIHRvLCBtYWtlIG9uZS4KLSAgICAgICAgICAgICAgICBpZiAobV9iZWZvcmUgPT0gbnVsbCkKLSAgICAgICAgICAgICAgICAgICAgbV9iZWZvcmUgPQotICAgICAgICAgICAgICAgICAgICAgICAgbmV3IEVuY29kaW5nSW1wbCgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX2VuY29kaW5nLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fZmlyc3QsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbV9leHBsRmlyc3QgLSAxLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvZGVQb2ludCk7Ci0gICAgICAgICAgICAgICAgcmV0ID0gbV9iZWZvcmUuaXNJbkVuY29kaW5nKGNoMSk7Ci0gICAgICAgICAgICB9IGVsc2UgaWYgKG1fZXhwbExhc3QgPCBjb2RlUG9pbnQpIHsKLSAgICAgICAgICAgICAgICAvLyBUaGUgdW5pY29kZSB2YWx1ZSBpcyBhZnRlciB0aGUgcmFuZ2UKLSAgICAgICAgICAgICAgICAvLyB0aGF0IHdlIGV4cGxpY3RseSBtYW5hZ2UsIHNvIHdlIGRlbGVnYXRlIHRoZSBhbnN3ZXIuCi0KLSAgICAgICAgICAgICAgICAvLyBJZiB3ZSBkb24ndCBoYXZlIGFuIG1fYWZ0ZXIgb2JqZWN0IHRvIGRlbGVnYXRlIHRvLCBtYWtlIG9uZS4KLSAgICAgICAgICAgICAgICBpZiAobV9hZnRlciA9PSBudWxsKQotICAgICAgICAgICAgICAgICAgICBtX2FmdGVyID0KLSAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBFbmNvZGluZ0ltcGwoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbV9lbmNvZGluZywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX2V4cGxMYXN0ICsgMSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX2xhc3QsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29kZVBvaW50KTsKLSAgICAgICAgICAgICAgICByZXQgPSBtX2FmdGVyLmlzSW5FbmNvZGluZyhjaDEpOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAvLyBUaGUgdW5pY29kZSB2YWx1ZSBpcyBpbiB0aGUgcmFuZ2Ugd2UgZXhwbGl0bHkgaGFuZGxlCi0gICAgICAgICAgICAgICAgZmluYWwgaW50IGlkeCA9IGNvZGVQb2ludCAtIG1fZXhwbEZpcnN0OwotCi0gICAgICAgICAgICAgICAgLy8gSWYgd2UgYWxyZWFkeSBrbm93IHRoZSBhbnN3ZXIsIGp1c3QgcmV0dXJuIGl0LgotICAgICAgICAgICAgICAgIGlmIChtX2FscmVhZHlLbm93bltpZHhdKQotICAgICAgICAgICAgICAgICAgICByZXQgPSBtX2lzSW5FbmNvZGluZ1tpZHhdOwotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAvLyBXZSBkb24ndCBrbm93IHRoZSBhbnN3ZXIsIHNvIGZpbmQgb3V0LAotICAgICAgICAgICAgICAgICAgICAvLyB3aGljaCBtYXkgYmUgZXhwZW5zaXZlLCB0aGVuIGNhY2hlIHRoZSBhbnN3ZXIKLSAgICAgICAgICAgICAgICAgICAgcmV0ID0gaW5FbmNvZGluZyhjaDEsIG1fZW5jb2RpbmcpOwotICAgICAgICAgICAgICAgICAgICBtX2FscmVhZHlLbm93bltpZHhdID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgbV9pc0luRW5jb2RpbmdbaWR4XSA9IHJldDsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gcmV0OwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIGJvb2xlYW4gaXNJbkVuY29kaW5nKGNoYXIgaGlnaCwgY2hhciBsb3cpIHsKLSAgICAgICAgICAgIGZpbmFsIGJvb2xlYW4gcmV0OwotICAgICAgICAgICAgaW50IGNvZGVQb2ludCA9IEVuY29kaW5ncy50b0NvZGVQb2ludChoaWdoLGxvdyk7Ci0gICAgICAgICAgICBpZiAoY29kZVBvaW50IDwgbV9leHBsRmlyc3QpIHsKLSAgICAgICAgICAgICAgICAvLyBUaGUgdW5pY29kZSB2YWx1ZSBpcyBiZWZvcmUgdGhlIHJhbmdlCi0gICAgICAgICAgICAgICAgLy8gdGhhdCB3ZSBleHBsaWN0bHkgbWFuYWdlLCBzbyB3ZSBkZWxlZ2F0ZSB0aGUgYW5zd2VyLgotCi0gICAgICAgICAgICAgICAgLy8gSWYgd2UgZG9uJ3QgaGF2ZSBhbiBtX2JlZm9yZSBvYmplY3QgdG8gZGVsZWdhdGUgdG8sIG1ha2Ugb25lLgotICAgICAgICAgICAgICAgIGlmIChtX2JlZm9yZSA9PSBudWxsKQotICAgICAgICAgICAgICAgICAgICBtX2JlZm9yZSA9Ci0gICAgICAgICAgICAgICAgICAgICAgICBuZXcgRW5jb2RpbmdJbXBsKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fZW5jb2RpbmcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbV9maXJzdCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX2V4cGxGaXJzdCAtIDEsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29kZVBvaW50KTsKLSAgICAgICAgICAgICAgICByZXQgPSBtX2JlZm9yZS5pc0luRW5jb2RpbmcoaGlnaCxsb3cpOwotICAgICAgICAgICAgfSBlbHNlIGlmIChtX2V4cGxMYXN0IDwgY29kZVBvaW50KSB7Ci0gICAgICAgICAgICAgICAgLy8gVGhlIHVuaWNvZGUgdmFsdWUgaXMgYWZ0ZXIgdGhlIHJhbmdlCi0gICAgICAgICAgICAgICAgLy8gdGhhdCB3ZSBleHBsaWN0bHkgbWFuYWdlLCBzbyB3ZSBkZWxlZ2F0ZSB0aGUgYW5zd2VyLgotCi0gICAgICAgICAgICAgICAgLy8gSWYgd2UgZG9uJ3QgaGF2ZSBhbiBtX2FmdGVyIG9iamVjdCB0byBkZWxlZ2F0ZSB0bywgbWFrZSBvbmUuCi0gICAgICAgICAgICAgICAgaWYgKG1fYWZ0ZXIgPT0gbnVsbCkKLSAgICAgICAgICAgICAgICAgICAgbV9hZnRlciA9Ci0gICAgICAgICAgICAgICAgICAgICAgICBuZXcgRW5jb2RpbmdJbXBsKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fZW5jb2RpbmcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbV9leHBsTGFzdCArIDEsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbV9sYXN0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvZGVQb2ludCk7Ci0gICAgICAgICAgICAgICAgcmV0ID0gbV9hZnRlci5pc0luRW5jb2RpbmcoaGlnaCxsb3cpOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAvLyBUaGUgdW5pY29kZSB2YWx1ZSBpcyBpbiB0aGUgcmFuZ2Ugd2UgZXhwbGl0bHkgaGFuZGxlCi0gICAgICAgICAgICAgICAgZmluYWwgaW50IGlkeCA9IGNvZGVQb2ludCAtIG1fZXhwbEZpcnN0OwotCi0gICAgICAgICAgICAgICAgLy8gSWYgd2UgYWxyZWFkeSBrbm93IHRoZSBhbnN3ZXIsIGp1c3QgcmV0dXJuIGl0LgotICAgICAgICAgICAgICAgIGlmIChtX2FscmVhZHlLbm93bltpZHhdKQotICAgICAgICAgICAgICAgICAgICByZXQgPSBtX2lzSW5FbmNvZGluZ1tpZHhdOwotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAvLyBXZSBkb24ndCBrbm93IHRoZSBhbnN3ZXIsIHNvIGZpbmQgb3V0LAotICAgICAgICAgICAgICAgICAgICAvLyB3aGljaCBtYXkgYmUgZXhwZW5zaXZlLCB0aGVuIGNhY2hlIHRoZSBhbnN3ZXIKLSAgICAgICAgICAgICAgICAgICAgcmV0ID0gaW5FbmNvZGluZyhoaWdoLCBsb3csIG1fZW5jb2RpbmcpOwotICAgICAgICAgICAgICAgICAgICBtX2FscmVhZHlLbm93bltpZHhdID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgbV9pc0luRW5jb2RpbmdbaWR4XSA9IHJldDsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gcmV0OwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFRoZSBlbmNvZGluZy4KLSAgICAgICAgICovCi0gICAgICAgIGZpbmFsIHByaXZhdGUgU3RyaW5nIG1fZW5jb2Rpbmc7Ci0gICAgICAgIC8qKgotICAgICAgICAgKiBtX2ZpcnN0IHRocm91Z2ggbV9sYXN0IGlzIHRoZSByYW5nZSBvZiB1bmljb2RlCi0gICAgICAgICAqIHZhbHVlcyB0aGF0IHRoaXMgb2JqZWN0IHdpbGwgcmV0dXJuIGFuIGFuc3dlciBvbi4KLSAgICAgICAgICogSXQgbWF5IGRlbGVnYXRlIHRvIGEgc2ltaWxhciBvYmplY3Qgd2l0aCBhIGRpZmZlcmVudAotICAgICAgICAgKiByYW5nZQotICAgICAgICAgKi8KLSAgICAgICAgZmluYWwgcHJpdmF0ZSBpbnQgbV9maXJzdDsKLQotICAgICAgICAvKioKLSAgICAgICAgICogbV9leHBsRmlyc3QgdGhyb3VnaCBtX2V4cGxMYXN0IGlzIHRoZSByYW5nZSBvZiB1bmljb2RlCi0gICAgICAgICAqIHZhbHVlIHRoYXQgdGhpcyBvYmplY3QgaGFuZGxlcyBleHBsaWNpdGx5IGFuZCBkb2VzIG5vdAotICAgICAgICAgKiBkZWxlZ2F0ZSB0byBhIHNpbWlsYXIgb2JqZWN0LgotICAgICAgICAgKi8KLSAgICAgICAgZmluYWwgcHJpdmF0ZSBpbnQgbV9leHBsRmlyc3Q7Ci0gICAgICAgIGZpbmFsIHByaXZhdGUgaW50IG1fZXhwbExhc3Q7Ci0gICAgICAgIGZpbmFsIHByaXZhdGUgaW50IG1fbGFzdDsKLQotICAgICAgICAvKioKLSAgICAgICAgICogVGhlIG9iamVjdCwgb2YgdGhlIHNhbWUgdHlwZSBhcyB0aGlzIG9uZSwKLSAgICAgICAgICogdGhhdCBoYW5kbGVzIHVuaWNvZGUgdmFsdWVzIGluIGEgcmFuZ2UgYmVmb3JlCi0gICAgICAgICAqIHRoZSByYW5nZSBleHBsaWN0bHkgaGFuZGxlZCBieSB0aGlzIG9iamVjdCwgYW5kCi0gICAgICAgICAqIHRvIHdoaWNoIHRoaXMgb2JqZWN0IG1heSBkZWxlZ2F0ZS4KLSAgICAgICAgICovCi0gICAgICAgIHByaXZhdGUgSW5FbmNvZGluZyBtX2JlZm9yZTsKLSAgICAgICAgLyoqCi0gICAgICAgICAqIFRoZSBvYmplY3QsIG9mIHRoZSBzYW1lIHR5cGUgYXMgdGhpcyBvbmUsCi0gICAgICAgICAqIHRoYXQgaGFuZGxlcyB1bmljb2RlIHZhbHVlcyBpbiBhIHJhbmdlIGFmdGVyCi0gICAgICAgICAqIHRoZSByYW5nZSBleHBsaWN0bHkgaGFuZGxlZCBieSB0aGlzIG9iamVjdCwgYW5kCi0gICAgICAgICAqIHRvIHdoaWNoIHRoaXMgb2JqZWN0IG1heSBkZWxlZ2F0ZS4KLSAgICAgICAgICovCi0gICAgICAgIHByaXZhdGUgSW5FbmNvZGluZyBtX2FmdGVyOwotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBUaGUgbnVtYmVyIG9mIHVuaWNvZGUgdmFsdWVzIGV4cGxpY2l0bHkgaGFuZGxlZAotICAgICAgICAgKiBieSBhIHNpbmdsZSBFbmNvZGluZ0luZm8gb2JqZWN0LiBUaGlzIHZhbHVlIGlzCi0gICAgICAgICAqIHR1bmVhYmxlLCBidXQgaXMgc2V0IHRvIDEyOCBiZWNhdXNlIHRoYXQgY292ZXJzIHRoZQotICAgICAgICAgKiBlbnRpcmUgbG93IHJhbmdlIG9mIEFTQ0lJIHR5cGUgY2hhcnMgd2l0aGluIGEgc2luZ2xlCi0gICAgICAgICAqIG9iamVjdC4KLSAgICAgICAgICovCi0gICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBSQU5HRSA9IDEyODsKLQotICAgICAgICAvKioKLSAgICAgICAgICogQSBmbGFnIHRvIHJlY29yZCBpZiB3ZSBhbHJlYWR5IGtub3cgdGhlIGFuc3dlcgotICAgICAgICAgKiBmb3IgdGhlIGdpdmVuIHVuaWNvZGUgdmFsdWUuCi0gICAgICAgICAqLwotICAgICAgICBmaW5hbCBwcml2YXRlIGJvb2xlYW4gbV9hbHJlYWR5S25vd25bXSA9IG5ldyBib29sZWFuW1JBTkdFXTsKLSAgICAgICAgLyoqCi0gICAgICAgICAqIEEgdGFibGUgaG9sZGluZyB0aGUgYW5zd2VyIG9uIHdoZXRoZXIgdGhlIGdpdmVuIHVuaWNvZGUKLSAgICAgICAgICogdmFsdWUgaXMgaW4gdGhlIGVuY29kaW5nLgotICAgICAgICAgKi8KLSAgICAgICAgZmluYWwgcHJpdmF0ZSBib29sZWFuIG1faXNJbkVuY29kaW5nW10gPSBuZXcgYm9vbGVhbltSQU5HRV07Ci0KLSAgICAgICAgcHJpdmF0ZSBFbmNvZGluZ0ltcGwoKSB7Ci0gICAgICAgICAgICAvLyBUaGlzIG9iamVjdCB3aWxsIGFuc3dlciB3aGV0aGVyIGFueSB1bmljb2RlIHZhbHVlCi0gICAgICAgICAgICAvLyBpcyBpbiB0aGUgZW5jb2RpbmcsIGl0IGhhbmRsZXMgdmFsdWVzIDAgdGhyb3VnaCBJbnRlZ2VyLk1BWF9WQUxVRQotICAgICAgICAgICAgdGhpcyhqYXZhTmFtZSwgMCwgSW50ZWdlci5NQVhfVkFMVUUsIChjaGFyKSAwKTsKLSAgICAgICAgfQotCi0gICAgICAgIHByaXZhdGUgRW5jb2RpbmdJbXBsKFN0cmluZyBlbmNvZGluZywgaW50IGZpcnN0LCBpbnQgbGFzdCwgaW50IGNvZGVQb2ludCkgewotICAgICAgICAgICAgLy8gU2V0IHRoZSByYW5nZSBvZiB1bmljb2RlIHZhbHVlcyB0aGF0IHRoaXMgb2JqZWN0IG1hbmFnZXMKLSAgICAgICAgICAgIC8vIGVpdGhlciBleHBsaWNpdGx5IG9yIGltcGxpY2l0bHkuCi0gICAgICAgICAgICBtX2ZpcnN0ID0gZmlyc3Q7Ci0gICAgICAgICAgICBtX2xhc3QgPSBsYXN0OwotCi0gICAgICAgICAgICAvLyBTZXQgdGhlIHJhbmdlIG9mIHVuaWNvZGUgdmFsdWVzIHRoYXQgdGhpcyBvYmplY3QKLSAgICAgICAgICAgIC8vIGV4cGxpY2l0bHkgbWFuYWdlcy4gQWxpZ24gdGhlIGV4cGxpY2l0bHkgbWFuYWdlZCB2YWx1ZXMKLSAgICAgICAgICAgIC8vIHRvIFJBTkdFIHNvIG11bHRpcGxlIEVuY29kaW5nSW1wbCBvYmplY3RzIGRvbnQgbWFuYWdlIHRoZSBzYW1lCi0gICAgICAgICAgICAvLyB2YWx1ZXMuCi0gICAgICAgICAgICBtX2V4cGxGaXJzdCA9IGNvZGVQb2ludCAvIFJBTkdFICogUkFOR0U7Ci0gICAgICAgICAgICBtX2V4cGxMYXN0ID0gbV9leHBsRmlyc3QgKyAoUkFOR0UtMSk7Ci0KLSAgICAgICAgICAgIG1fZW5jb2RpbmcgPSBlbmNvZGluZzsKLQotICAgICAgICAgICAgaWYgKGphdmFOYW1lICE9IG51bGwpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgLy8gU29tZSBvcHRpbWl6YXRpb24uCi0gICAgICAgICAgICAgICAgaWYgKDAgPD0gbV9leHBsRmlyc3QgJiYgbV9leHBsRmlyc3QgPD0gMTI3KSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIFRoaXMgcGFydGljdWxhciBFbmNvZGluZ0ltcGwgZXhwbGljaXRseSBoYW5kbGVzCi0gICAgICAgICAgICAgICAgICAgIC8vIGNoYXJhY3RlcnMgaW4gdGhlIGxvdyByYW5nZS4KLSAgICAgICAgICAgICAgICAgICAgaWYgKCJVVEY4Ii5lcXVhbHMoamF2YU5hbWUpCi0gICAgICAgICAgICAgICAgICAgICAgICB8fCAiVVRGLTE2Ii5lcXVhbHMoamF2YU5hbWUpCi0gICAgICAgICAgICAgICAgICAgICAgICB8fCAiQVNDSUkiLmVxdWFscyhqYXZhTmFtZSkKLSAgICAgICAgICAgICAgICAgICAgICAgIHx8ICJVUy1BU0NJSSIuZXF1YWxzKGphdmFOYW1lKQotICAgICAgICAgICAgICAgICAgICAgICAgfHwgIlVuaWNvZGUiLmVxdWFscyhqYXZhTmFtZSkKLSAgICAgICAgICAgICAgICAgICAgICAgIHx8ICJVTklDT0RFIi5lcXVhbHMoamF2YU5hbWUpCi0gICAgICAgICAgICAgICAgICAgICAgICB8fCBqYXZhTmFtZS5zdGFydHNXaXRoKCJJU084ODU5IikpIHsKLQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gTm90IG9ubHkgZG9lcyB0aGlzIEVuY29kaW5nSW1wbCBvYmplY3QgZXhwbGljaXRseQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gaGFuZGxlIGNocmFjdGVycyBpbiB0aGUgbG93IHJhbmdlLCBpdCBpcwotICAgICAgICAgICAgICAgICAgICAgICAgLy8gYWxzbyBvbmUgdGhhdCB3ZSBrbm93IHNvbWV0aGluZyBhYm91dCwgd2l0aG91dAotICAgICAgICAgICAgICAgICAgICAgICAgLy8gbmVlZGluZyB0byBjYWxsIGluRW5jb2RpbmcoY2hhciBjaCwgU3RyaW5nIGVuY29kaW5nKQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gZm9yIHRoaXMgbG93IHJhbmdlCi0gICAgICAgICAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgICAgICAgICAgLy8gQnkgaW5pdGlhbGl6aW5nIHRoZSB0YWJsZSBhaGVhZCBvZiB0aW1lCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBmb3IgdGhlc2UgbG93IHZhbHVlcywgd2UgcHJldmVudCB0aGUgZXhwZW5zaXZlCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBpbkVuY29kaW5nKGNoYXIgY2gsIFN0cmluZyBlbmNvZGluZykKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZyb20gYmVpbmcgY2FsbGVkLCBhdCBsZWFzdCBmb3IgdGhlc2UgY29tbW9uCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBlbmNvZGluZ3MuCi0gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGludCB1bmljb2RlID0gMTsgdW5pY29kZSA8IDEyNzsgdW5pY29kZSsrKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IGlkeCA9IHVuaWNvZGUgLSBtX2V4cGxGaXJzdDsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoMCA8PSBpZHggJiYgaWR4IDwgUkFOR0UpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbV9hbHJlYWR5S25vd25baWR4XSA9IHRydWU7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1faXNJbkVuY29kaW5nW2lkeF0gPSB0cnVlOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8qIEEgbGl0dGxlIGJpdCBtb3JlIHRoYW4gb3B0aW1pemF0aW9uLgotICAgICAgICAgICAgICAgICAqCi0gICAgICAgICAgICAgICAgICogV2Ugd2lsbCBzYXkgdGhhdCBhbnkgY2hhcmFjdGVyIGlzIGluIHRoZSBlbmNvZGluZyBpZgotICAgICAgICAgICAgICAgICAqIHdlIGRvbid0IGhhdmUgYW4gZW5jb2RpbmcuCi0gICAgICAgICAgICAgICAgICogVGhpcyBpcyBtZWFuaW5nZnVsIHdoZW4gdGhlIHNlcmlhbGl6ZXIgaXMgYmVpbmcgdXNlZAotICAgICAgICAgICAgICAgICAqIGluIHRlbXBvcmFyeSBvdXRwdXQgc3RhdGUsIHdoZXJlIHdlIGFyZSBub3Qgd3JpdGluZyB0bwotICAgICAgICAgICAgICAgICAqIHRoZSBmaW5hbCBvdXRwdXQgdHJlZS4gIEl0IGlzIHdoZW4gd3JpdGluZyB0byB0aGUKLSAgICAgICAgICAgICAgICAgKiBmaW5hbCBvdXRwdXQgdHJlZSB0aGF0IHdlIG5lZWQgdG8gd29ycnkgYWJvdXQgdGhlIG91dHB1dAotICAgICAgICAgICAgICAgICAqIGVuY29kaW5nCi0gICAgICAgICAgICAgICAgICovCi0gICAgICAgICAgICAgICAgaWYgKGphdmFOYW1lID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaWR4ID0gMDsgaWR4IDwgbV9hbHJlYWR5S25vd24ubGVuZ3RoOyBpZHgrKykgewotICAgICAgICAgICAgICAgICAgICAgICAgbV9hbHJlYWR5S25vd25baWR4XSA9IHRydWU7Ci0gICAgICAgICAgICAgICAgICAgICAgICBtX2lzSW5FbmNvZGluZ1tpZHhdID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgaXMgaGVhcnQgb2YgdGhlIGNvZGUgdGhhdCBkZXRlcm1pbmVzIGlmIGEgZ2l2ZW4gY2hhcmFjdGVyCi0gICAgICogaXMgaW4gdGhlIGdpdmVuIGVuY29kaW5nLiBUaGlzIG1ldGhvZCBpcyBwcm9iYWJseSBleHBlbnNpdmUsCi0gICAgICogYW5kIHRoZSBhbnN3ZXIgc2hvdWxkIGJlIGNhY2hlZC4KLSAgICAgKiA8cD4KLSAgICAgKiBUaGlzIG1ldGhvZCBpcyBub3QgYSBwdWJsaWMgQVBJLAotICAgICAqIGFuZCBzaG91bGQgb25seSBiZSB1c2VkIGludGVybmFsbHkgd2l0aGluIHRoZSBzZXJpYWxpemVyLgotICAgICAqIEBwYXJhbSBjaCB0aGUgY2hhciBpbiBxdWVzdGlvbiwgdGhhdCBpcyBub3QgYSBoaWdoIGNoYXIgb2YKLSAgICAgKiBhIGhpZ2gvbG93IHN1cnJvZ2F0ZSBwYWlyLgotICAgICAqIEBwYXJhbSBlbmNvZGluZyB0aGUgSmF2YSBuYW1lIG9mIHRoZSBlbm9jZGluZy4KLSAgICAgKgotICAgICAqIEB4c2wudXNhZ2UgaW50ZXJuYWwKLSAgICAgKgotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaW5FbmNvZGluZyhjaGFyIGNoLCBTdHJpbmcgZW5jb2RpbmcpIHsKLSAgICAgICAgYm9vbGVhbiBpc0luRW5jb2Rpbmc7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBjaGFyIGNBcnJheVtdID0gbmV3IGNoYXJbMV07Ci0gICAgICAgICAgICBjQXJyYXlbMF0gPSBjaDsKLSAgICAgICAgICAgIC8vIENvbnN0cnVjdCBhIFN0cmluZyBmcm9tIHRoZSBjaGFyCi0gICAgICAgICAgICBTdHJpbmcgcyA9IG5ldyBTdHJpbmcoY0FycmF5KTsKLSAgICAgICAgICAgIC8vIEVuY29kZSB0aGUgU3RyaW5nIGludG8gYSBzZXF1ZW5jZSBvZiBieXRlcwotICAgICAgICAgICAgLy8gdXNpbmcgdGhlIGdpdmVuLCBuYW1lZCBjaGFyc2V0LgotICAgICAgICAgICAgYnl0ZVtdIGJBcnJheSA9IHMuZ2V0Qnl0ZXMoZW5jb2RpbmcpOwotICAgICAgICAgICAgaXNJbkVuY29kaW5nID0gaW5FbmNvZGluZyhjaCwgYkFycmF5KTsKLQotICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgaXNJbkVuY29kaW5nID0gZmFsc2U7Ci0KLSAgICAgICAgICAgIC8vIElmIGZvciBzb21lIHJlYXNvbiB0aGUgZW5jb2RpbmcgaXMgbnVsbCwgZS5nLgotICAgICAgICAgICAgLy8gZm9yIGEgdGVtcG9yYXJ5IHJlc3VsdCB0cmVlLCB3ZSBzaG91bGQganVzdAotICAgICAgICAgICAgLy8gc2F5IHRoYXQgZXZlcnkgY2hhcmFjdGVyIGlzIGluIHRoZSBlbmNvZGluZy4KLSAgICAgICAgICAgIGlmIChlbmNvZGluZyA9PSBudWxsKQotICAgICAgICAgICAgICAgIGlzSW5FbmNvZGluZyA9IHRydWU7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGlzSW5FbmNvZGluZzsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIGlzIGhlYXJ0IG9mIHRoZSBjb2RlIHRoYXQgZGV0ZXJtaW5lcyBpZiBhIGdpdmVuIGhpZ2gvbG93Ci0gICAgICogc3Vycm9nYXRlIHBhaXIgZm9ybXMgYSBjaGFyYWN0ZXIgdGhhdCBpcyBpbiB0aGUgZ2l2ZW4gZW5jb2RpbmcuCi0gICAgICogVGhpcyBtZXRob2QgaXMgcHJvYmFibHkgZXhwZW5zaXZlLCBhbmQgdGhlIGFuc3dlciBzaG91bGQgYmUgY2FjaGVkLgotICAgICAqIDxwPgotICAgICAqIFRoaXMgbWV0aG9kIGlzIG5vdCBhIHB1YmxpYyBBUEksCi0gICAgICogYW5kIHNob3VsZCBvbmx5IGJlIHVzZWQgaW50ZXJuYWxseSB3aXRoaW4gdGhlIHNlcmlhbGl6ZXIuCi0gICAgICogQHBhcmFtIGhpZ2ggdGhlIGhpZ2ggY2hhciBvZgotICAgICAqIGEgaGlnaC9sb3cgc3Vycm9nYXRlIHBhaXIuCi0gICAgICogQHBhcmFtIGxvdyB0aGUgbG93IGNoYXIgb2YgYSBoaWdoL2xvdyBzdXJyb2dhdGUgcGFpci4KLSAgICAgKiBAcGFyYW0gZW5jb2RpbmcgdGhlIEphdmEgbmFtZSBvZiB0aGUgZW5jb2RpbmcuCi0gICAgICoKLSAgICAgKiBAeHNsLnVzYWdlIGludGVybmFsCi0gICAgICoKLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGluRW5jb2RpbmcoY2hhciBoaWdoLCBjaGFyIGxvdywgU3RyaW5nIGVuY29kaW5nKSB7Ci0gICAgICAgIGJvb2xlYW4gaXNJbkVuY29kaW5nOwotICAgICAgICB0cnkgewotICAgICAgICAgICAgY2hhciBjQXJyYXlbXSA9IG5ldyBjaGFyWzJdOwotICAgICAgICAgICAgY0FycmF5WzBdID0gaGlnaDsKLSAgICAgICAgICAgIGNBcnJheVsxXSA9IGxvdzsKLSAgICAgICAgICAgIC8vIENvbnN0cnVjdCBhIFN0cmluZyBmcm9tIHRoZSBjaGFyCi0gICAgICAgICAgICBTdHJpbmcgcyA9IG5ldyBTdHJpbmcoY0FycmF5KTsKLSAgICAgICAgICAgIC8vIEVuY29kZSB0aGUgU3RyaW5nIGludG8gYSBzZXF1ZW5jZSBvZiBieXRlcwotICAgICAgICAgICAgLy8gdXNpbmcgdGhlIGdpdmVuLCBuYW1lZCBjaGFyc2V0LgotICAgICAgICAgICAgYnl0ZVtdIGJBcnJheSA9IHMuZ2V0Qnl0ZXMoZW5jb2RpbmcpOwotICAgICAgICAgICAgaXNJbkVuY29kaW5nID0gaW5FbmNvZGluZyhoaWdoLGJBcnJheSk7Ci0gICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICBpc0luRW5jb2RpbmcgPSBmYWxzZTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBpc0luRW5jb2Rpbmc7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgaXMgdGhlIGNvcmUgb2YgZGV0ZXJtaW5pbmcgaWYgY2hhcmFjdGVyCi0gICAgICogaXMgaW4gdGhlIGVuY29kaW5nLiBUaGUgbWV0aG9kIGlzIG5vdCBmb29scHJvb2YsIGJlY2F1c2UKLSAgICAgKiBzLmdldEJ5dGVzKGVuY29kaW5nKSBoYXMgc3BlY2lmaWVkIGJlaGF2aW9yIG9ubHkgaWYgdGhlCi0gICAgICogY2hhcmFjdGVycyBhcmUgaW4gdGhlIHNwZWNpZmllZCBlbmNvZGluZy4gSG93ZXZlciB0aGlzCi0gICAgICogbWV0aG9kIHRyaWVzIGl0J3MgYmVzdC4KLSAgICAgKiBAcGFyYW0gY2ggdGhlIGNoYXIgdGhhdCB3YXMgY29udmVydGVkIHVzaW5nIGdldEJ5dGVzLCBvcgotICAgICAqIHRoZSBmaXJzdCBjaGFyIG9mIGEgaGlnaC9sb3cgcGFpciB0aGF0IHdhcyBjb252ZXJ0ZWQuCi0gICAgICogQHBhcmFtIGRhdGEgdGhlIGJ5dGVzIHdyaXR0ZW4gb3V0IGJ5IHRoZSBjYWxsIHRvIHMuZ2V0Qnl0ZXMoZW5jb2RpbmcpOwotICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgY2hhcmFjdGVyIGlzIGluIHRoZSBlbmNvZGluZy4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGluRW5jb2RpbmcoY2hhciBjaCwgYnl0ZVtdIGRhdGEpIHsKLSAgICAgICAgZmluYWwgYm9vbGVhbiBpc0luRW5jb2Rpbmc7Ci0gICAgICAgIC8vIElmIHRoZSBzdHJpbmcgd3JpdHRlbiBvdXQgYXMgZGF0YSBpcyBub3QgaW4gdGhlIGVuY29kaW5nLAotICAgICAgICAvLyB0aGUgb3V0cHV0IGlzIG5vdCBzcGVjaWZpZWQgYWNjb3JkaW5nIHRvIHRoZSBkb2N1bWVudGF0aW9uCi0gICAgICAgIC8vIG9uIHRoZSBTdHJpbmcuZ2V0Qnl0ZXMoZW5jb2RpbmcpIG1ldGhvZCwKLSAgICAgICAgLy8gYnV0IHdlIGRvIG91ciBiZXN0IGhlcmUuCi0gICAgICAgIGlmIChkYXRhPT1udWxsIHx8IGRhdGEubGVuZ3RoID09IDApIHsKLSAgICAgICAgICAgIGlzSW5FbmNvZGluZyA9IGZhbHNlOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgaWYgKGRhdGFbMF0gPT0gMCkKLSAgICAgICAgICAgICAgICBpc0luRW5jb2RpbmcgPSBmYWxzZTsKLSAgICAgICAgICAgIGVsc2UgaWYgKGRhdGFbMF0gPT0gJz8nICYmIGNoICE9ICc/JykKLSAgICAgICAgICAgICAgICBpc0luRW5jb2RpbmcgPSBmYWxzZTsKLSAgICAgICAgICAgIC8qCi0gICAgICAgICAgICAgKiBlbHNlIGlmIChpc0phcGFuZXNlKSB7Ci0gICAgICAgICAgICAgKiAgIC8vIGlzSmFwYW5lc2UgaXMgcmVhbGx5Ci0gICAgICAgICAgICAgKiAgIC8vICAgKCAgICAiRVVDLUpQIi5lcXVhbHMoamF2YU5hbWUpCi0gICAgICAgICAgICAgKiAgIC8vICAgIHx8ICAiRVVDX0pQIi5lcXVhbHMoamF2YU5hbWUpCi0gICAgICAgICAgICAgKiAgLy8gICAgIHx8ICAiU0pJUyIuZXF1YWxzKGphdmFOYW1lKSAgICkKLSAgICAgICAgICAgICAqCi0gICAgICAgICAgICAgKiAgIC8vIFdvcmsgYXJvdW5kIHNvbWUgYnVncyBpbiBKUkUgZm9yIEphcGFuZXNlCi0gICAgICAgICAgICAgKiAgIGlmKGRhdGFbMF0gPT0gMHgyMSkKLSAgICAgICAgICAgICAqICAgICBpc0luRW5jb2RpbmcgPSBmYWxzZTsKLSAgICAgICAgICAgICAqICAgZWxzZSBpZiAoY2ggPT0gMHhBNSkKLSAgICAgICAgICAgICAqICAgICBpc0luRW5jb2RpbmcgPSBmYWxzZTsKLSAgICAgICAgICAgICAqICAgZWxzZQotICAgICAgICAgICAgICogICAgIGlzSW5FbmNvZGluZyA9IHRydWU7Ci0gICAgICAgICAgICAgKiB9Ci0gICAgICAgICAgICAgKi8KLQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgLy8gV2UgZG9uJ3Qga25vdyBmb3Igc3VyZSwgYnV0IGl0IGxvb2tzIGxpa2UgaXQgaXMgaW4gdGhlIGVuY29kaW5nCi0gICAgICAgICAgICAgICAgaXNJbkVuY29kaW5nID0gdHJ1ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gaXNJbkVuY29kaW5nOwotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9FbmNvZGluZ3MuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvRW5jb2RpbmdzLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGQ0ZDk1ZmYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9FbmNvZGluZ3MuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDU2NiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBFbmNvZGluZ3MuamF2YSx2IDEuMyAyMDA1LzA5LzI4IDEzOjQ5OjA0IHB2ZWR1bGEgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXI7Ci0KLWltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtV3JpdGVyOwotaW1wb3J0IGphdmEuaW8uVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLldyaXRlcjsKLWltcG9ydCBqYXZhLmlvLkJ1ZmZlcmVkV3JpdGVyOwotaW1wb3J0IGphdmEubmV0LlVSTDsKLWltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247Ci1pbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7Ci1pbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7Ci1pbXBvcnQgamF2YS51dGlsLlN0cmluZ1Rva2VuaXplcjsKLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotaW1wb3J0IGphdmEubmV0Lk1hbGZvcm1lZFVSTEV4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXQ7Ci1pbXBvcnQgamF2YS5uaW8uY2hhcnNldC5JbGxlZ2FsQ2hhcnNldE5hbWVFeGNlcHRpb247Ci1pbXBvcnQgamF2YS5uaW8uY2hhcnNldC5VbnN1cHBvcnRlZENoYXJzZXRFeGNlcHRpb247Ci1pbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOwotaW1wb3J0IGphdmEudXRpbC5NYXA7Ci1pbXBvcnQgamF2YS51dGlsLk1hcC5FbnRyeTsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC51dGlscy5TZWN1cml0eVN1cHBvcnQ7Ci0KLS8qKgotICogUHJvdmlkZXMgaW5mb3JtYXRpb24gYWJvdXQgZW5jb2RpbmdzLiBEZXBlbmRzIG9uIHRoZSBKYXZhIHJ1bnRpbWUKLSAqIHRvIHByb3ZpZGVzIHdyaXRlcnMgZm9yIHRoZSBkaWZmZXJlbnQgZW5jb2RpbmdzLCBidXQgY2FuIGJlIHVzZWQKLSAqIHRvIG92ZXJyaWRlIGVuY29kaW5nIG5hbWVzIGFuZCBwcm92aWRlIHRoZSBsYXN0IHByaW50YWJsZSBjaGFyYWN0ZXIKLSAqIGZvciBlYWNoIGVuY29kaW5nLgotICoKLSAqIEB2ZXJzaW9uICRSZXZpc2lvbjogMS4xMSAkICREYXRlOiAyMDEwLTExLTAxIDA0OjM0OjQ0ICQKLSAqIEBhdXRob3IgPGEgaHJlZj0ibWFpbHRvOmFya2luQGludGFsaW8uY29tIj5Bc3NhZiBBcmtpbjwvYT4KLSAqLwotCi1wdWJsaWMgZmluYWwgY2xhc3MgRW5jb2RpbmdzIGV4dGVuZHMgT2JqZWN0Ci17Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgbGFzdCBwcmludGFibGUgY2hhcmFjdGVyIGZvciB1bmtub3duIGVuY29kaW5ncy4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgbV9kZWZhdWx0TGFzdFByaW50YWJsZSA9IDB4N0Y7Ci0KLSAgICAvKioKLSAgICAgKiBTdGFuZGFyZCBmaWxlbmFtZSBmb3IgcHJvcGVydGllcyBmaWxlIHdpdGggZW5jb2RpbmdzIGRhdGEuCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEVOQ09ESU5HU19GSUxFID0gImNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9FbmNvZGluZ3MucHJvcGVydGllcyI7Ci0KLSAgICAvKioKLSAgICAgKiBTdGFuZGFyZCBmaWxlbmFtZSBmb3IgcHJvcGVydGllcyBmaWxlIHdpdGggZW5jb2RpbmdzIGRhdGEuCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEVOQ09ESU5HU19QUk9QID0gImNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC5zZXJpYWxpemUuZW5jb2RpbmdzIjsKLQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhIHdyaXRlciBmb3IgdGhlIHNwZWNpZmllZCBlbmNvZGluZyBiYXNlZCBvbgotICAgICAqIGFuIG91dHB1dCBzdHJlYW0uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gb3V0cHV0IFRoZSBvdXRwdXQgc3RyZWFtCi0gICAgICogQHBhcmFtIGVuY29kaW5nIFRoZSBlbmNvZGluZwotICAgICAqIEByZXR1cm4gQSBzdWl0YWJsZSB3cml0ZXIKLSAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gVGhlcmUgaXMgbm8gY29udmVydG9yCi0gICAgICogIHRvIHN1cHBvcnQgdGhpcyBlbmNvZGluZwotICAgICAqLwotICAgIHN0YXRpYyBXcml0ZXIgZ2V0V3JpdGVyKE91dHB1dFN0cmVhbSBvdXRwdXQsIFN0cmluZyBlbmNvZGluZykKLSAgICAgICAgdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24KLSAgICB7Ci0KLSAgICAgICAgZmluYWwgRW5jb2RpbmdJbmZvIGVpID0gX2VuY29kaW5nSW5mb3MuZmluZEVuY29kaW5nKHRvVXBwZXJDYXNlRmFzdChlbmNvZGluZykpOwotICAgICAgICBpZiAoZWkgIT0gbnVsbCkgewotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEJ1ZmZlcmVkV3JpdGVyKG5ldyBPdXRwdXRTdHJlYW1Xcml0ZXIoCi0gICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXQsIGVpLmphdmFOYW1lKSk7Ci0gICAgICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIHVzZWUpIHsKLSAgICAgICAgICAgICAgICAvLyBrZWVwIHRyeWluZwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIG5ldyBCdWZmZXJlZFdyaXRlcihuZXcgT3V0cHV0U3RyZWFtV3JpdGVyKG91dHB1dCwgZW5jb2RpbmcpKTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIGxhc3QgcHJpbnRhYmxlIGNoYXJhY3RlciBmb3IgYW4gdW5zcGVjaWZpZWQKLSAgICAgKiBlbmNvZGluZy4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdGhlIGRlZmF1bHQgc2l6ZQotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgaW50IGdldExhc3RQcmludGFibGUoKQotICAgIHsKLSAgICAgICAgcmV0dXJuIG1fZGVmYXVsdExhc3RQcmludGFibGU7Ci0gICAgfQotCi0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIEVuY29kaW5nSW5mbyBvYmplY3QgZm9yIHRoZSBzcGVjaWZpZWQKLSAgICAgKiBlbmNvZGluZy4KLSAgICAgKiA8cD4KLSAgICAgKiBUaGlzIGlzIG5vdCBhIHB1YmxpYyBBUEkuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZW5jb2RpbmcgVGhlIGVuY29kaW5nCi0gICAgICogQHJldHVybiBUaGUgb2JqZWN0IHRoYXQgaXMgdXNlZCB0byBkZXRlcm1pbmUgaWYKLSAgICAgKiBjaGFyYWN0ZXJzIGFyZSBpbiB0aGUgZ2l2ZW4gZW5jb2RpbmcuCi0gICAgICogQHhzbC51c2FnZSBpbnRlcm5hbAotICAgICAqLwotICAgIHN0YXRpYyBFbmNvZGluZ0luZm8gZ2V0RW5jb2RpbmdJbmZvKFN0cmluZyBlbmNvZGluZykKLSAgICB7Ci0gICAgICAgIEVuY29kaW5nSW5mbyBlaTsKLQotICAgICAgICBTdHJpbmcgbm9ybWFsaXplZEVuY29kaW5nID0gdG9VcHBlckNhc2VGYXN0KGVuY29kaW5nKTsKLSAgICAgICAgZWkgPSBfZW5jb2RpbmdJbmZvcy5maW5kRW5jb2Rpbmcobm9ybWFsaXplZEVuY29kaW5nKTsKLSAgICAgICAgaWYgKGVpID09IG51bGwpIHsKLSAgICAgICAgICAgIC8vIFdlIHNob3VsZG4ndCBoYXZlIHRvIGRvIHRoaXMsIGJ1dCBqdXN0IGluIGNhc2UuCi0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIC8vIFRoaXMgbWF5IGhhcHBlbiBpZiB0aGUgY2FsbGVyIHRyaWVzIHRvIHVzZQotICAgICAgICAgICAgICAgIC8vIGFuIGVuY29kaW5nIHRoYXQgd2Fzbid0IHJlZ2lzdGVyZWQgaW4gdGhlCi0gICAgICAgICAgICAgICAgLy8gKGphdmEgbmFtZSktPihwcmVmZXJyZWQgbWltZSBuYW1lKSBtYXBwaW5nIGZpbGUuCi0gICAgICAgICAgICAgICAgLy8gSW4gdGhhdCBjYXNlIHdlIGF0dGVtcHQgdG8gbG9hZCB0aGUgY2hhcnNldCBmb3IgdGhlCi0gICAgICAgICAgICAgICAgLy8gZ2l2ZW4gZW5jb2RpbmcsIGFuZCBpZiB0aGF0IHN1Y2NlZWRzIC0gd2UgY3JlYXRlIGEgbmV3Ci0gICAgICAgICAgICAgICAgLy8gRW5jb2RpbmdJbmZvIGluc3RhbmNlIC0gYXNzdW1pbmcgdGhlIGNhbm9uaWNhbCBuYW1lCi0gICAgICAgICAgICAgICAgLy8gb2YgdGhlIGNoYXJzZXQgY2FuIGJlIHVzZWQgYXMgdGhlIG1pbWUgbmFtZS4KLSAgICAgICAgICAgICAgICBmaW5hbCBDaGFyc2V0IGMgPSBDaGFyc2V0LmZvck5hbWUoZW5jb2RpbmcpOwotICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBuYW1lID0gYy5uYW1lKCk7Ci0gICAgICAgICAgICAgICAgZWkgPSBuZXcgRW5jb2RpbmdJbmZvKG5hbWUsIG5hbWUpOwotICAgICAgICAgICAgICAgIF9lbmNvZGluZ0luZm9zLnB1dEVuY29kaW5nKG5vcm1hbGl6ZWRFbmNvZGluZywgZWkpOwotICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbENoYXJzZXROYW1lRXhjZXB0aW9uIHwgVW5zdXBwb3J0ZWRDaGFyc2V0RXhjZXB0aW9uIHgpIHsKLSAgICAgICAgICAgICAgICBlaSA9IG5ldyBFbmNvZGluZ0luZm8obnVsbCxudWxsKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBlaTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBIGZhc3QgYW5kIGNoZWFwIHdheSB0byB1cHBlcmNhc2UgYSBTdHJpbmcgdGhhdCBpcwotICAgICAqIG9ubHkgbWFkZSBvZiBwcmludGFibGUgQVNDSUkgY2hhcmFjdGVycy4KLSAgICAgKiA8cD4KLSAgICAgKiBUaGlzIGlzIG5vdCBhIHB1YmxpYyBBUEkuCi0gICAgICogQHBhcmFtIHMgYSBTdHJpbmcgb2YgQVNDSUkgY2hhcmFjdGVycwotICAgICAqIEByZXR1cm4gYW4gdXBwZXJjYXNlZCB2ZXJzaW9uIG9mIHRoZSBpbnB1dCBTdHJpbmcsCi0gICAgICogcG9zc2libHkgdGhlIHNhbWUgU3RyaW5nLgotICAgICAqIEB4c2wudXNhZ2UgaW50ZXJuYWwKLSAgICAgKi8KLSAgICBzdGF0aWMgcHJpdmF0ZSBTdHJpbmcgdG9VcHBlckNhc2VGYXN0KGZpbmFsIFN0cmluZyBzKSB7Ci0KLSAgICAgICAgYm9vbGVhbiBkaWZmZXJlbnQgPSBmYWxzZTsKLSAgICAgICAgZmluYWwgaW50IG14ID0gcy5sZW5ndGgoKTsKLSAgICAgICAgICAgICAgICBjaGFyW10gY2hhcnMgPSBuZXcgY2hhcltteF07Ci0gICAgICAgIGZvciAoaW50IGk9MDsgaSA8IG14OyBpKyspIHsKLSAgICAgICAgICAgICAgICBjaGFyIGNoID0gcy5jaGFyQXQoaSk7Ci0gICAgICAgICAgICAvLyBpcyB0aGUgY2hhcmFjdGVyIGEgbG93ZXIgY2FzZSBBU0NJSSBvbmU/Ci0gICAgICAgICAgICAgICAgaWYgKCdhJyA8PSBjaCAmJiBjaCA8PSAneicpIHsKLSAgICAgICAgICAgICAgICAvLyBhIGNoZWFwIGFuZCBmYXN0IHdheSB0byB1cHBlcmNhc2UgdGhhdCBpcyBnb29kIGVub3VnaAotICAgICAgICAgICAgICAgICAgICAgICAgY2ggPSAoY2hhcikgKGNoICsgKCdBJyAtICdhJykpOwotICAgICAgICAgICAgICAgICAgICAgICAgZGlmZmVyZW50ID0gdHJ1ZTsgLy8gdGhlIHVwcGVyY2FzZWQgU3RyaW5nIGlzIGRpZmZlcmVudAotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBjaGFyc1tpXSA9IGNoOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gQSBsaXR0bGUgb3B0aW1pemF0aW9uLCBkb24ndCBjYWxsIFN0cmluZy52YWx1ZU9mKCkgaWYKLSAgICAgICAgLy8gdGhlIHVwcGVyY2FzZWQgc3RyaW5nIGlzIHRoZSBzYW1lIGFzIHRoZSBpbnB1dCBzdHJpbmcuCi0gICAgICAgIGZpbmFsIFN0cmluZyB1cHBlcjsKLSAgICAgICAgaWYgKGRpZmZlcmVudCkKLSAgICAgICAgICAgICAgICB1cHBlciA9IFN0cmluZy52YWx1ZU9mKGNoYXJzKTsKLSAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIHVwcGVyID0gczsKLQotICAgICAgICByZXR1cm4gdXBwZXI7Ci0gICAgfQotCi0gICAgLyoqIFRoZSBkZWZhdWx0IGVuY29kaW5nLCBJU08gc3R5bGUsIElTTyBzdHlsZS4gICAqLwotICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgREVGQVVMVF9NSU1FX0VOQ09ESU5HID0gIlVURi04IjsKLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgcHJvcGVyIG1pbWUgZW5jb2RpbmcuICBGcm9tIHRoZSBYU0xUIHJlY29tbWVuZGF0aW9uOiAiVGhlIGVuY29kaW5nCi0gICAgICogYXR0cmlidXRlIHNwZWNpZmllcyB0aGUgcHJlZmVycmVkIGVuY29kaW5nIHRvIHVzZSBmb3Igb3V0cHV0dGluZyB0aGUgcmVzdWx0Ci0gICAgICogdHJlZS4gWFNMVCBwcm9jZXNzb3JzIGFyZSByZXF1aXJlZCB0byByZXNwZWN0IHZhbHVlcyBvZiBVVEYtOCBhbmQgVVRGLTE2LgotICAgICAqIEZvciBvdGhlciB2YWx1ZXMsIGlmIHRoZSBYU0xUIHByb2Nlc3NvciBkb2VzIG5vdCBzdXBwb3J0IHRoZSBzcGVjaWZpZWQKLSAgICAgKiBlbmNvZGluZyBpdCBtYXkgc2lnbmFsIGFuIGVycm9yOyBpZiBpdCBkb2VzIG5vdCBzaWduYWwgYW4gZXJyb3IgaXQgc2hvdWxkCi0gICAgICogdXNlIFVURi04IG9yIFVURi0xNiBpbnN0ZWFkLiBUaGUgWFNMVCBwcm9jZXNzb3IgbXVzdCBub3QgdXNlIGFuIGVuY29kaW5nCi0gICAgICogd2hvc2UgbmFtZSBkb2VzIG5vdCBtYXRjaCB0aGUgRW5jTmFtZSBwcm9kdWN0aW9uIG9mIHRoZSBYTUwgUmVjb21tZW5kYXRpb24KLSAgICAgKiBbWE1MXS4gSWYgbm8gZW5jb2RpbmcgYXR0cmlidXRlIGlzIHNwZWNpZmllZCwgdGhlbiB0aGUgWFNMVCBwcm9jZXNzb3Igc2hvdWxkCi0gICAgICogdXNlIGVpdGhlciBVVEYtOCBvciBVVEYtMTYuIgotICAgICAqCi0gICAgICogQHBhcmFtIGVuY29kaW5nIFJlZmVyZW5jZSB0byBqYXZhLXN0eWxlIGVuY29kaW5nIHN0cmluZywgd2hpY2ggbWF5IGJlIG51bGwsCi0gICAgICogaW4gd2hpY2ggY2FzZSBhIGRlZmF1bHQgd2lsbCBiZSBmb3VuZC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIElTTy1zdHlsZSBlbmNvZGluZyBzdHJpbmcsIG9yIG51bGwgaWYgZmFpbHVyZS4KLSAgICAgKi8KLSAgICBzdGF0aWMgU3RyaW5nIGdldE1pbWVFbmNvZGluZyhTdHJpbmcgZW5jb2RpbmcpCi0gICAgewotCi0gICAgICAgIGlmIChudWxsID09IGVuY29kaW5nKQotICAgICAgICB7Ci0gICAgICAgICAgICB0cnkKLSAgICAgICAgICAgIHsKLQotICAgICAgICAgICAgICAgIC8vIEdldCB0aGUgZGVmYXVsdCBzeXN0ZW0gY2hhcmFjdGVyIGVuY29kaW5nLiAgVGhpcyBtYXkgYmUKLSAgICAgICAgICAgICAgICAvLyBpbmNvcnJlY3QgaWYgdGhleSBwYXNzZWQgaW4gYSB3cml0ZXIsIGJ1dCByaWdodCBub3cgdGhlcmUKLSAgICAgICAgICAgICAgICAvLyBzZWVtcyB0byBiZSBubyB3YXkgdG8gZ2V0IHRoZSBlbmNvZGluZyBmcm9tIGEgd3JpdGVyLgotICAgICAgICAgICAgICAgIGVuY29kaW5nID0gU2VjdXJpdHlTdXBwb3J0LmdldFN5c3RlbVByb3BlcnR5KCJmaWxlLmVuY29kaW5nIiwgIlVURjgiKTsKLQotICAgICAgICAgICAgICAgIGlmIChudWxsICE9IGVuY29kaW5nKQotICAgICAgICAgICAgICAgIHsKLQotICAgICAgICAgICAgICAgICAgICAvKgotICAgICAgICAgICAgICAgICAgICAqIFNlZSBpZiB0aGUgbWltZSB0eXBlIGlzIGVxdWFsIHRvIFVURjguICBJZiB5b3UgZG9uJ3QKLSAgICAgICAgICAgICAgICAgICAgKiBkbyB0aGF0LCB0aGVuICBjb252ZXJ0SmF2YTJNaW1lRW5jb2Rpbmcgd2lsbCBjb252ZXJ0Ci0gICAgICAgICAgICAgICAgICAgICogODg1OV8xIHRvICJJU08tODg1OS0xIiwgd2hpY2ggaXMgbm90IHdoYXQgd2Ugd2FudCwKLSAgICAgICAgICAgICAgICAgICAgKiBJIHRoaW5rLCBhbmQgSSBkb24ndCB0aGluayBJIHdhbnQgdG8gYWx0ZXIgdGhlIHRhYmxlcwotICAgICAgICAgICAgICAgICAgICAqIHRvIGNvbnZlcnQgZXZlcnl0aGluZyB0byBVVEYtOC4KLSAgICAgICAgICAgICAgICAgICAgKi8KLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGplbmNvZGluZyA9Ci0gICAgICAgICAgICAgICAgICAgICAgICAoZW5jb2RpbmcuZXF1YWxzSWdub3JlQ2FzZSgiQ3AxMjUyIikKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCBlbmNvZGluZy5lcXVhbHNJZ25vcmVDYXNlKCJJU084ODU5XzEiKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IGVuY29kaW5nLmVxdWFsc0lnbm9yZUNhc2UoIjg4NTlfMSIpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgZW5jb2RpbmcuZXF1YWxzSWdub3JlQ2FzZSgiVVRGOCIpKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gREVGQVVMVF9NSU1FX0VOQ09ESU5HCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBjb252ZXJ0SmF2YTJNaW1lRW5jb2RpbmcoZW5jb2RpbmcpOwotCi0gICAgICAgICAgICAgICAgICAgIGVuY29kaW5nID0KLSAgICAgICAgICAgICAgICAgICAgICAgIChudWxsICE9IGplbmNvZGluZykgPyBqZW5jb2RpbmcgOiBERUZBVUxUX01JTUVfRU5DT0RJTkc7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIGVuY29kaW5nID0gREVGQVVMVF9NSU1FX0VOQ09ESU5HOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBzZSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBlbmNvZGluZyA9IERFRkFVTFRfTUlNRV9FTkNPRElORzsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgIHsKLSAgICAgICAgICAgIGVuY29kaW5nID0gY29udmVydEphdmEyTWltZUVuY29kaW5nKGVuY29kaW5nKTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBlbmNvZGluZzsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcnkgdGhlIGJlc3Qgd2UgY2FuIHRvIGNvbnZlcnQgYSBKYXZhIGVuY29kaW5nIHRvIGEgWE1MLXN0eWxlIGVuY29kaW5nLgotICAgICAqCi0gICAgICogQHBhcmFtIGVuY29kaW5nIG5vbi1udWxsIHJlZmVyZW5jZSB0byBlbmNvZGluZyBzdHJpbmcsIGphdmEgc3R5bGUuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIElTTy1zdHlsZSBlbmNvZGluZyBzdHJpbmcuCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGNvbnZlcnRKYXZhMk1pbWVFbmNvZGluZyhTdHJpbmcgZW5jb2RpbmcpCi0gICAgewotICAgICAgICBmaW5hbCBFbmNvZGluZ0luZm8gZW5jID0KLSAgICAgICAgICAgICBfZW5jb2RpbmdJbmZvcy5nZXRFbmNvZGluZ0Zyb21KYXZhS2V5KHRvVXBwZXJDYXNlRmFzdChlbmNvZGluZykpOwotICAgICAgICBpZiAobnVsbCAhPSBlbmMpCi0gICAgICAgICAgICByZXR1cm4gZW5jLm5hbWU7Ci0gICAgICAgIHJldHVybiBlbmNvZGluZzsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcnkgdGhlIGJlc3Qgd2UgY2FuIHRvIGNvbnZlcnQgYSBKYXZhIGVuY29kaW5nIHRvIGEgWE1MLXN0eWxlIGVuY29kaW5nLgotICAgICAqCi0gICAgICogQHBhcmFtIGVuY29kaW5nIG5vbi1udWxsIHJlZmVyZW5jZSB0byBlbmNvZGluZyBzdHJpbmcsIGphdmEgc3R5bGUuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIElTTy1zdHlsZSBlbmNvZGluZyBzdHJpbmcuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBTdHJpbmcgY29udmVydE1pbWUySmF2YUVuY29kaW5nKFN0cmluZyBlbmNvZGluZykKLSAgICB7Ci0gICAgICAgIGZpbmFsIEVuY29kaW5nSW5mbyBpbmZvID0gX2VuY29kaW5nSW5mb3MuZmluZEVuY29kaW5nKHRvVXBwZXJDYXNlRmFzdChlbmNvZGluZykpOwotICAgICAgICByZXR1cm4gaW5mbyAhPSBudWxsID8gaW5mby5qYXZhTmFtZSA6IGVuY29kaW5nOwotICAgIH0KLQotICAgIC8vIFVzaW5nIGFuIGlubmVyIHN0YXRpYyBjbGFzcyBoZXJlIHByZXZlbnQgaW5pdGlhbGl6YXRpb24gcmFjZXMKLSAgICAvLyB3aGVyZSB0aGUgaGFzaCBtYXBzIGNvdWxkIGJlIHVzZWQgYmVmb3JlIHRoZXkgd2VyZSBwb3B1bGF0ZWQuCi0gICAgLy8KLSAgICBwcml2YXRlIGZpbmFsIHN0YXRpYyBjbGFzcyBFbmNvZGluZ0luZm9zIHsKLSAgICAgICAgLy8gVGhlc2UgbWFwcyBhcmUgZmluYWwgYW5kIG5vdCBtb2RpZmllZCBhZnRlciBpbml0aWFsaXphdGlvbi4KLSAgICAgICAgcHJpdmF0ZSBmaW5hbCBNYXA8U3RyaW5nLCBFbmNvZGluZ0luZm8+IF9lbmNvZGluZ1RhYmxlS2V5SmF2YSA9IG5ldyBIYXNoTWFwPD4oKTsKLSAgICAgICAgcHJpdmF0ZSBmaW5hbCBNYXA8U3RyaW5nLCBFbmNvZGluZ0luZm8+IF9lbmNvZGluZ1RhYmxlS2V5TWltZSA9IG5ldyBIYXNoTWFwPD4oKTsKLSAgICAgICAgLy8gVGhpcyBtYXAgd2lsbCBiZSBhZGRlZCB0byBhZnRlciBpbml0aWFsaXphdGlvbjogbWFrZSBzdXJlIGl0J3MKLSAgICAgICAgLy8gdGhyZWFkLXNhZmUuIFRoaXMgbWFwIHNob3VsZCBub3QgYmUgdXNlZCBmcmVxdWVudGx5IC0gb25seSBpbiBjYXNlcwotICAgICAgICAvLyB3aGVyZSB0aGUgbWFwcGluZyByZXF1ZXN0ZWQgd2FzIG5vdCBkZWNsYXJlZCBpbiB0aGUgRW5jb2RpbmdzLnByb3BlcnRpZXMKLSAgICAgICAgLy8gZmlsZS4KLSAgICAgICAgcHJpdmF0ZSBmaW5hbCBNYXA8U3RyaW5nLCBFbmNvZGluZ0luZm8+IF9lbmNvZGluZ0R5bmFtaWNUYWJsZSA9Ci0gICAgICAgICAgICAgICAgQ29sbGVjdGlvbnMuc3luY2hyb25pemVkTWFwKG5ldyBIYXNoTWFwPFN0cmluZywgRW5jb2RpbmdJbmZvPigpKTsKLQotICAgICAgICBwcml2YXRlIEVuY29kaW5nSW5mb3MoKSB7Ci0gICAgICAgICAgICBsb2FkRW5jb2RpbmdJbmZvKCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBPcGVucyB0aGUgZmlsZS9yZXNvdXJjZSBjb250YWluaW5nIGphdmEgY2hhcnNldCBuYW1lIC0+IHByZWZlcnJlZCBtaW1lCi0gICAgICAgIC8vIG5hbWUgbWFwcGluZyBhbmQgcmV0dXJucyBpdCBhcyBhbiBJbnB1dFN0cmVhbS4KLSAgICAgICAgcHJpdmF0ZSBJbnB1dFN0cmVhbSBvcGVuRW5jb2RpbmdzRmlsZVN0cmVhbSgpIHRocm93cyBNYWxmb3JtZWRVUkxFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKLSAgICAgICAgICAgIFN0cmluZyB1cmxTdHJpbmcgPSBudWxsOwotICAgICAgICAgICAgSW5wdXRTdHJlYW0gaXMgPSBudWxsOwotCi0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIHVybFN0cmluZyA9IFNlY3VyaXR5U3VwcG9ydC5nZXRTeXN0ZW1Qcm9wZXJ0eShFTkNPRElOR1NfUFJPUCwgIiIpOwotICAgICAgICAgICAgfSBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAodXJsU3RyaW5nICE9IG51bGwgJiYgdXJsU3RyaW5nLmxlbmd0aCgpID4gMCkgewotICAgICAgICAgICAgICAgIFVSTCB1cmwgPSBuZXcgVVJMKHVybFN0cmluZyk7Ci0gICAgICAgICAgICAgICAgaXMgPSB1cmwub3BlblN0cmVhbSgpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAoaXMgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGlzID0gU2VjdXJpdHlTdXBwb3J0LmdldFJlc291cmNlQXNTdHJlYW0oRU5DT0RJTkdTX0ZJTEUpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIGlzOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gTG9hZHMgdGhlIFByb3BlcnRpZXMgcmVzb3VyY2UgY29udGFpbmluZyB0aGUgbWFwcGluZzoKLSAgICAgICAgLy8gICAgamF2YSBjaGFyc2V0IG5hbWUgLT4gcHJlZmVycmVkIG1pbWUgbmFtZQotICAgICAgICAvLyBhbmQgcmV0dXJucyBpdC4KLSAgICAgICAgcHJpdmF0ZSBQcm9wZXJ0aWVzIGxvYWRQcm9wZXJ0aWVzKCkgdGhyb3dzIE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewotICAgICAgICAgICAgUHJvcGVydGllcyBwcm9wcyA9IG5ldyBQcm9wZXJ0aWVzKCk7Ci0gICAgICAgICAgICB0cnkgKElucHV0U3RyZWFtIGlzID0gb3BlbkVuY29kaW5nc0ZpbGVTdHJlYW0oKSkgewotICAgICAgICAgICAgICAgIGlmIChpcyAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIHByb3BzLmxvYWQoaXMpOwotICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIFNlZW1zIHRvIGJlIG5vIHJlYWwgbmVlZCB0byBmb3JjZSBmYWlsdXJlIGhlcmUsIGxldCB0aGUKLSAgICAgICAgICAgICAgICAgICAgLy8gc3lzdGVtIGRvIGl0cyBiZXN0Li4uIFRoZSBpc3N1ZSBpcyBub3QgcmVhbGx5IHZlcnkgY3JpdGljYWwsCi0gICAgICAgICAgICAgICAgICAgIC8vIGFuZCB0aGUgb3V0cHV0IHdpbGwgYmUgaW4gYW55IGNhc2UgX2NvcnJlY3RfIHRob3VnaCBtYXliZSBub3QKLSAgICAgICAgICAgICAgICAgICAgLy8gYWx3YXlzIGh1bWFuLWZyaWVuZGx5Li4uIDopCi0gICAgICAgICAgICAgICAgICAgIC8vIEJ1dCBtYXliZSByZXBvcnQvbG9nIHRoZSByZXNvdXJjZSBwcm9ibGVtPwotICAgICAgICAgICAgICAgICAgICAvLyBBbnkgc3RhbmRhcmQgd2F5cyB0byByZXBvcnQvbG9nIGVycm9ycyAoaW4gc3RhdGljIGNvbnRleHQpPwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiBwcm9wczsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIFBhcnNlcyB0aGUgbWltZSBsaXN0IGFzc29jaWF0ZWQgdG8gYSBqYXZhIGNoYXJzZXQgbmFtZS4KLSAgICAgICAgLy8gVGhlIGZpcnN0IG1pbWUgbmFtZSBpbiB0aGUgbGlzdCBpcyBzdXBwb3NlZCB0byBiZSB0aGUgcHJlZmVycmVkCi0gICAgICAgIC8vIG1pbWUgbmFtZS4KLSAgICAgICAgcHJpdmF0ZSBTdHJpbmdbXSBwYXJzZU1pbWVUeXBlcyhTdHJpbmcgdmFsKSB7Ci0gICAgICAgICAgICBpbnQgcG9zID0gdmFsLmluZGV4T2YoJyAnKTsKLSAgICAgICAgICAgIC8vaW50IGxhc3RQcmludGFibGU7Ci0gICAgICAgICAgICBpZiAocG9zIDwgMCkgewotICAgICAgICAgICAgICAgIC8vIE1heWJlIHJlcG9ydC9sb2cgdGhpcyBwcm9ibGVtPwotICAgICAgICAgICAgICAgIC8vICAiTGFzdCBwcmludGFibGUgY2hhcmFjdGVyIG5vdCBkZWZpbmVkIGZvciBlbmNvZGluZyAiICsKLSAgICAgICAgICAgICAgICAvLyAgbWltZU5hbWUgKyAiICgiICsgdmFsICsgIikiIC4uLgotICAgICAgICAgICAgICAgIHJldHVybiBuZXcgU3RyaW5nW10geyB2YWwgfTsKLSAgICAgICAgICAgICAgICAvL2xhc3RQcmludGFibGUgPSAweDAwRkY7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvL2xhc3RQcmludGFibGUgPQotICAgICAgICAgICAgLy8gICAgSW50ZWdlci5kZWNvZGUodmFsLnN1YnN0cmluZyhwb3MpLnRyaW0oKSkuaW50VmFsdWUoKTsKLSAgICAgICAgICAgIFN0cmluZ1Rva2VuaXplciBzdCA9Ci0gICAgICAgICAgICAgICAgICAgIG5ldyBTdHJpbmdUb2tlbml6ZXIodmFsLnN1YnN0cmluZygwLCBwb3MpLCAiLCIpOwotICAgICAgICAgICAgU3RyaW5nW10gdmFsdWVzID0gbmV3IFN0cmluZ1tzdC5jb3VudFRva2VucygpXTsKLSAgICAgICAgICAgIGZvciAoaW50IGk9MDsgc3QuaGFzTW9yZVRva2VucygpOyBpKyspIHsKLSAgICAgICAgICAgICAgICB2YWx1ZXNbaV0gPSBzdC5uZXh0VG9rZW4oKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiB2YWx1ZXM7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBUaGlzIG1ldGhvZCBoZXJlIGF0dGVtcHRzIHRvIGZpbmQgdGhlIGNhbm9uaWNhbCBjaGFyc2V0IG5hbWUgZm9yIHRoZQotICAgICAgICAvLyB0aGUgZ2l2ZW4gbmFtZSAtIHdoaWNoIGlzIHN1cHBvc2VkIHRvIGJlIGVpdGhlciBhIGphdmEgbmFtZSBvciBhIG1pbWUKLSAgICAgICAgLy8gbmFtZS4KLSAgICAgICAgLy8gRm9yIHRoYXQsIGl0IGF0dGVtcHRzIHRvIGxvYWQgdGhlIGNoYXJzZXQgdXNpbmcgdGhlIGdpdmVuIG5hbWUsIGFuZAotICAgICAgICAvLyB0aGVuIHJldHVybnMgdGhlIGNoYXJzZXQncyBjYW5vbmljYWwgbmFtZS4KLSAgICAgICAgLy8gSWYgdGhlIGNoYXJzZXQgY291bGQgbm90IGJlIGxvYWRlZCBmcm9tIHRoZSBnaXZlbiBuYW1lLAotICAgICAgICAvLyB0aGUgbWV0aG9kIHJldHVybnMgbnVsbC4KLSAgICAgICAgcHJpdmF0ZSBTdHJpbmcgZmluZENoYXJzZXROYW1lRm9yKFN0cmluZyBuYW1lKSB7Ci0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIHJldHVybiBDaGFyc2V0LmZvck5hbWUobmFtZSkubmFtZSgpOwotICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIHgpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIFRoaXMgbWV0aG9kIGhlcmUgYXR0ZW1wdHMgdG8gZmluZCB0aGUgY2Fub25pY2FsIGNoYXJzZXQgbmFtZSBmb3IgdGhlCi0gICAgICAgIC8vIHRoZSBzZXQgamF2YU5hbWUrbWltZU5hbWVzIC0gd2hpY2ggYXJlIHN1cHBvc2VkIHRvIGFsbCByZWZlciB0byB0aGUKLSAgICAgICAgLy8gc2FtZSBjaGFyc2V0LgotICAgICAgICAvLyBGb3IgdGhhdCBpdCBhdHRlbXB0cyB0byBsb2FkIHRoZSBjaGFyc2V0IHVzaW5nIHRoZSBqYXZhTmFtZSwgYW5kIGlmCi0gICAgICAgIC8vIG5vdCBmb3VuZCwgYXR0ZW1wdHMgYWdhaW4gdXNpbmcgZWFjaCBvZiB0aGUgbWltZSBuYW1lcyBpbiB0dXJuLgotICAgICAgICAvLyBJZiB0aGUgY2hhcnNldCBjb3VsZCBiZSBsb2FkZWQgZnJvbSB0aGUgamF2YU5hbWUsIHRoZW4gdGhlIGphdmFOYW1lCi0gICAgICAgIC8vIGl0c2VsZiBpcyByZXR1cm5lZCBhcyBjaGFyc2V0IG5hbWUuIE90aGVyd2lzZSwgZWFjaCBvZiB0aGUgbWltZSBuYW1lcwotICAgICAgICAvLyBpcyB0cmllZCBpbiB0dXJuLCB1bnRpbCBhIGNoYXJzZXQgY2FuIGJlIGxvYWRlZCBmcm9tIG9uZSBvZiB0aGUgbmFtZXMsCi0gICAgICAgIC8vIGFuZCB0aGUgbG9hZGVkIGNoYXJzZXQncyBjYW5vbmljYWwgbmFtZSBpcyByZXR1cm5lZC4KLSAgICAgICAgLy8gSWYgbm8gY2hhcnNldCBjYW4gYmUgbG9hZGVkIGZyb20gZWl0aGVyIHRoZSBqYXZhTmFtZSBvciBvbmUgb2YgdGhlCi0gICAgICAgIC8vIG1pbWUgbmFtZXMsIHRoZW4gbnVsbCBpcyByZXR1cm5lZC4KLSAgICAgICAgLy8KLSAgICAgICAgLy8gTm90ZSB0aGF0IHRoZSByZXR1cm5lZCBuYW1lIGlzIHRoZSAnamF2YScgbmFtZSB0aGF0IHdpbGwgYmUgdXNlZCBpbgotICAgICAgICAvLyBpbnN0YW5jZXMgb2YgRW5jb2RpbmdJbmZvLgotICAgICAgICAvLyBUaGlzIGlzIGltcG9ydGFudCBiZWNhdXNlIEVuY29kaW5nSW5mbyB1c2VzIHRoYXQgJ2phdmEgbmFtZScgbGF0ZXIgb24KLSAgICAgICAgLy8gaW4gY2FsbHMgdG8gU3RyaW5nLmdldEJ5dGVzKGphdmFOYW1lKS4KLSAgICAgICAgLy8gQXMgaXQgaGFwcGVucywgc29tZXRpbWVzIG9ubHkgb25lIGVsZW1lbnQgb2YgdGhlIHNldCBtaW1lIG5hbWVzL2phdmFOYW1lCi0gICAgICAgIC8vIGlzIGtub3duIGJ5IENoYXJzZXQ6IHNvbWV0aW1lcyBvbmx5IG9uZSBvZiB0aGUgbWltZSBuYW1lcyBpcyBrbm93biwKLSAgICAgICAgLy8gc29tZXRpbWUgb25seSB0aGUgamF2YU5hbWUgaXMga25vd24sIHNvbWV0aW1lcyBhbGwgYXJlIGtub3duLgotICAgICAgICAvLwotICAgICAgICAvLyBCeSB1c2luZyB0aGlzIG1ldGhvZCBoZXJlLCB3ZSBmaXggdGhlIHByb2JsZW0gd2hlcmUgb25lIG9mIHRoZSBtaW1lCi0gICAgICAgIC8vIG5hbWVzIGlzIGtub3duIGJ1dCB0aGUgamF2YU5hbWUgaXMgdW5rbm93biwgYnkgYXNzb2NpYXRpbmcgdGhlIGNoYXJzZXQKLSAgICAgICAgLy8gbG9hZGVkIGZyb20gb25lIG9mIHRoZSBtaW1lIG5hbWVzIHdpdGggdGhlIHVucmVjb2duaXplZCBqYXZhTmFtZS4KLSAgICAgICAgLy8KLSAgICAgICAgLy8gV2hlbiBub25lIG9mIHRoZSBtaW1lIG5hbWVzIG9yIGphdmFOYW1lIGFyZSBrbm93biAtIHRoZXJlJ3Mgbm90IG11Y2ggd2UgY2FuCi0gICAgICAgIC8vIGRvLi4uIEl0IGNhbiBtZWFuIHRoYXQgdGhpcyBlbmNvZGluZyBpcyBub3Qgc3VwcG9ydGVkIGZvciB0aGlzCi0gICAgICAgIC8vIE9TLiBJZiBzdWNoIGEgY2hhcnNldCBpcyBldmVyIHVzZSBpdCB3aWxsIHJlc3VsdCBpbiBoYXZpbmcgYWxsIGNoYXJhY3RlcnMKLSAgICAgICAgLy8gZXNjYXBlZC4KLSAgICAgICAgLy8KLSAgICAgICAgcHJpdmF0ZSBTdHJpbmcgZmluZENoYXJzZXROYW1lRm9yKFN0cmluZyBqYXZhTmFtZSwgU3RyaW5nW10gbWltZXMpIHsKLSAgICAgICAgICAgIFN0cmluZyBjcyA9IGZpbmRDaGFyc2V0TmFtZUZvcihqYXZhTmFtZSk7Ci0gICAgICAgICAgICBpZiAoY3MgIT0gbnVsbCkgcmV0dXJuIGphdmFOYW1lOwotICAgICAgICAgICAgZm9yIChTdHJpbmcgbSA6IG1pbWVzKSB7Ci0gICAgICAgICAgICAgICAgY3MgPSBmaW5kQ2hhcnNldE5hbWVGb3IobSk7Ci0gICAgICAgICAgICAgICAgaWYgKGNzICE9IG51bGwpIGJyZWFrOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIGNzOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIExvYWRzIGEgbGlzdCBvZiBhbGwgdGhlIHN1cHBvcnRlZCBlbmNvZGluZ3MuCi0gICAgICAgICAqCi0gICAgICAgICAqIFN5c3RlbSBwcm9wZXJ0eSAiZW5jb2RpbmdzIiBmb3JtYXR0ZWQgdXNpbmcgVVJMIHN5bnRheCBtYXkgZGVmaW5lIGFuCi0gICAgICAgICAqIGV4dGVybmFsIGVuY29kaW5ncyBsaXN0LiBUaGFua3MgdG8gU2VyZ2V5IFVzaGFrb3YgZm9yIHRoZSBjb2RlCi0gICAgICAgICAqIGNvbnRyaWJ1dGlvbiEKLSAgICAgICAgICovCi0gICAgICAgIHByaXZhdGUgdm9pZCBsb2FkRW5jb2RpbmdJbmZvKCkgewotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAvLyBsb2FkIChqYXZhIG5hbWUpLT4ocHJlZmVycmVkIG1pbWUgbmFtZSkgbWFwcGluZy4KLSAgICAgICAgICAgICAgICBmaW5hbCBQcm9wZXJ0aWVzIHByb3BzID0gbG9hZFByb3BlcnRpZXMoKTsKLQotICAgICAgICAgICAgICAgIC8vIGNyZWF0ZSBpbnN0YW5jZXMgb2YgRW5jb2RpbmdJbmZvIGZyb20gdGhlIGxvYWRlZCBtYXBwaW5nCi0gICAgICAgICAgICAgICAgRW51bWVyYXRpb24ga2V5cyA9IHByb3BzLmtleXMoKTsKLSAgICAgICAgICAgICAgICBNYXA8U3RyaW5nLCBFbmNvZGluZ0luZm8+IGNhbm9uaWNhbHMgPSBuZXcgSGFzaE1hcDw+KCk7Ci0gICAgICAgICAgICAgICAgd2hpbGUgKGtleXMuaGFzTW9yZUVsZW1lbnRzKCkpIHsKLSAgICAgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIGphdmFOYW1lID0gKFN0cmluZykga2V5cy5uZXh0RWxlbWVudCgpOwotICAgICAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmdbXSBtaW1lcyA9IHBhcnNlTWltZVR5cGVzKHByb3BzLmdldFByb3BlcnR5KGphdmFOYW1lKSk7Ci0KLSAgICAgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIGNoYXJzZXROYW1lID0gZmluZENoYXJzZXROYW1lRm9yKGphdmFOYW1lLCBtaW1lcyk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChjaGFyc2V0TmFtZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcga2ogPSB0b1VwcGVyQ2FzZUZhc3QoamF2YU5hbWUpOwotICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIGtjID0gdG9VcHBlckNhc2VGYXN0KGNoYXJzZXROYW1lKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbWltZXMubGVuZ3RoOyArK2kpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgbWltZU5hbWUgPSBtaW1lc1tpXTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcga20gPSB0b1VwcGVyQ2FzZUZhc3QobWltZU5hbWUpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVuY29kaW5nSW5mbyBpbmZvID0gbmV3IEVuY29kaW5nSW5mbyhtaW1lTmFtZSwgY2hhcnNldE5hbWUpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9lbmNvZGluZ1RhYmxlS2V5TWltZS5wdXQoa20sIGluZm8pOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghY2Fub25pY2Fscy5jb250YWluc0tleShrYykpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2Fub25pY2FscyB3aWxsIG1hcCB0aGUgY2hhcnNldCBuYW1lIHRvCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgdGhlIGluZm8gY29udGFpbmluZyB0aGUgcHJlZmVyZWQgbWltZSBuYW1lCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgKHRoZSBwcmVmZXJyZWQgbWltZSBuYW1lIGlzIHRoZSBmaXJzdCBtaW1lCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgbmFtZSBpbiB0aGUgbGlzdCkuCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbm9uaWNhbHMucHV0KGtjLCBpbmZvKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2VuY29kaW5nVGFibGVLZXlKYXZhLnB1dChrYywgaW5mbyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9lbmNvZGluZ1RhYmxlS2V5SmF2YS5wdXQoa2osIGluZm8pOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gTm9uZSBvZiB0aGUgamF2YSBvciBtaW1lIG5hbWVzIG9uIHRoZSBsaW5lIHdlcmUKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIHJlY29nbml6ZWQgPT4gdGhpcyBjaGFyc2V0IGlzIG5vdCBzdXBwb3J0ZWQ/Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyBGaXggdXAgdGhlIF9lbmNvZGluZ1RhYmxlS2V5SmF2YSBzbyB0aGF0IHRoZSBpbmZvIG1hcHBlZCB0bwotICAgICAgICAgICAgICAgIC8vIHRoZSBqYXZhIG5hbWUgY29udGFpbnMgdGhlIHByZWZlcnJlZCBtaW1lIG5hbWUuCi0gICAgICAgICAgICAgICAgLy8gKGEgZ2l2ZW4gamF2YSBuYW1lIGNhbiBjb3JyZXNwb25kIHRvIHNldmVyYWwgbWltZSBuYW1lLAotICAgICAgICAgICAgICAgIC8vICBidXQgd2Ugd2FudCB0aGUgX2VuY29kaW5nVGFibGVLZXlKYXZhIHRvIHBvaW50IHRvIHRoZQotICAgICAgICAgICAgICAgIC8vICBwcmVmZXJyZWQgbWltZSBuYW1lKS4KLSAgICAgICAgICAgICAgICBmb3IgKEVudHJ5PFN0cmluZywgRW5jb2RpbmdJbmZvPiBlIDogX2VuY29kaW5nVGFibGVLZXlKYXZhLmVudHJ5U2V0KCkpIHsKLSAgICAgICAgICAgICAgICAgICAgZS5zZXRWYWx1ZShjYW5vbmljYWxzLmdldCh0b1VwcGVyQ2FzZUZhc3QoZS5nZXRWYWx1ZSgpLmphdmFOYW1lKSkpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgfSBjYXRjaCAoamF2YS5uZXQuTWFsZm9ybWVkVVJMRXhjZXB0aW9uIG11ZSkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXIudXRpbHMuV3JhcHBlZFJ1bnRpbWVFeGNlcHRpb24obXVlKTsKLSAgICAgICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gaW9lKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplci51dGlscy5XcmFwcGVkUnVudGltZUV4Y2VwdGlvbihpb2UpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgRW5jb2RpbmdJbmZvIGZpbmRFbmNvZGluZyhTdHJpbmcgbm9ybWFsaXplZEVuY29kaW5nKSB7Ci0gICAgICAgICAgICBFbmNvZGluZ0luZm8gaW5mbyA9IF9lbmNvZGluZ1RhYmxlS2V5SmF2YS5nZXQobm9ybWFsaXplZEVuY29kaW5nKTsKLSAgICAgICAgICAgIGlmIChpbmZvID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBpbmZvID0gX2VuY29kaW5nVGFibGVLZXlNaW1lLmdldChub3JtYWxpemVkRW5jb2RpbmcpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKGluZm8gPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGluZm8gPSBfZW5jb2RpbmdEeW5hbWljVGFibGUuZ2V0KG5vcm1hbGl6ZWRFbmNvZGluZyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gaW5mbzsKLSAgICAgICAgfQotCi0gICAgICAgIEVuY29kaW5nSW5mbyBnZXRFbmNvZGluZ0Zyb21NaW1lS2V5KFN0cmluZyBub3JtYWxpemVkTWltZU5hbWUpIHsKLSAgICAgICAgICAgIHJldHVybiBfZW5jb2RpbmdUYWJsZUtleU1pbWUuZ2V0KG5vcm1hbGl6ZWRNaW1lTmFtZSk7Ci0gICAgICAgIH0KLQotICAgICAgICBFbmNvZGluZ0luZm8gZ2V0RW5jb2RpbmdGcm9tSmF2YUtleShTdHJpbmcgbm9ybWFsaXplZEphdmFOYW1lKSB7Ci0gICAgICAgICAgICByZXR1cm4gX2VuY29kaW5nVGFibGVLZXlKYXZhLmdldChub3JtYWxpemVkSmF2YU5hbWUpOwotICAgICAgICB9Ci0KLSAgICAgICAgdm9pZCBwdXRFbmNvZGluZyhTdHJpbmcga2V5LCBFbmNvZGluZ0luZm8gaW5mbykgewotICAgICAgICAgICAgX2VuY29kaW5nRHluYW1pY1RhYmxlLnB1dChrZXksIGluZm8pOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRydWUgaWYgdGhlIGNoYXJhY3RlciBpcyB0aGUgaGlnaCBtZW1iZXIgb2YgYSBzdXJyb2dhdGUgcGFpci4KLSAgICAgKiA8cD4KLSAgICAgKiBUaGlzIGlzIG5vdCBhIHB1YmxpYyBBUEkuCi0gICAgICogQHBhcmFtIGNoIHRoZSBjaGFyYWN0ZXIgdG8gdGVzdAotICAgICAqIEB4c2wudXNhZ2UgaW50ZXJuYWwKLSAgICAgKi8KLSAgICBzdGF0aWMgYm9vbGVhbiBpc0hpZ2hVVEYxNlN1cnJvZ2F0ZShjaGFyIGNoKSB7Ci0gICAgICAgIHJldHVybiAoJ1x1RDgwMCcgPD0gY2ggJiYgY2ggPD0gJ1x1REJGRicpOwotICAgIH0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdHJ1ZSBpZiB0aGUgY2hhcmFjdGVyIGlzIHRoZSBsb3cgbWVtYmVyIG9mIGEgc3Vycm9nYXRlIHBhaXIuCi0gICAgICogPHA+Ci0gICAgICogVGhpcyBpcyBub3QgYSBwdWJsaWMgQVBJLgotICAgICAqIEBwYXJhbSBjaCB0aGUgY2hhcmFjdGVyIHRvIHRlc3QKLSAgICAgKiBAeHNsLnVzYWdlIGludGVybmFsCi0gICAgICovCi0gICAgc3RhdGljIGJvb2xlYW4gaXNMb3dVVEYxNlN1cnJvZ2F0ZShjaGFyIGNoKSB7Ci0gICAgICAgIHJldHVybiAoJ1x1REMwMCcgPD0gY2ggJiYgY2ggPD0gJ1x1REZGRicpOwotICAgIH0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIHVuaWNvZGUgY29kZSBwb2ludCByZXByZXNlbnRlZCBieSB0aGUgaGlnaC9sb3cgc3Vycm9nYXRlIHBhaXIuCi0gICAgICogPHA+Ci0gICAgICogVGhpcyBpcyBub3QgYSBwdWJsaWMgQVBJLgotICAgICAqIEBwYXJhbSBoaWdoU3Vycm9nYXRlIHRoZSBoaWdoIGNoYXIgb2YgdGhlIGhpZ2gvbG93IHBhaXIKLSAgICAgKiBAcGFyYW0gbG93U3Vycm9nYXRlIHRoZSBsb3cgY2hhciBvZiB0aGUgaGlnaC9sb3cgcGFpcgotICAgICAqIEB4c2wudXNhZ2UgaW50ZXJuYWwKLSAgICAgKi8KLSAgICBzdGF0aWMgaW50IHRvQ29kZVBvaW50KGNoYXIgaGlnaFN1cnJvZ2F0ZSwgY2hhciBsb3dTdXJyb2dhdGUpIHsKLSAgICAgICAgaW50IGNvZGVQb2ludCA9Ci0gICAgICAgICAgICAoKGhpZ2hTdXJyb2dhdGUgLSAweGQ4MDApIDw8IDEwKQotICAgICAgICAgICAgICAgICsgKGxvd1N1cnJvZ2F0ZSAtIDB4ZGMwMCkKLSAgICAgICAgICAgICAgICArIDB4MTAwMDA7Ci0gICAgICAgIHJldHVybiBjb2RlUG9pbnQ7Ci0gICAgfQotICAgIC8qKgotICAgICAqIFJldHVybiB0aGUgdW5pY29kZSBjb2RlIHBvaW50IHJlcHJlc2VudGVkIGJ5IHRoZSBjaGFyLgotICAgICAqIEEgYml0IG9mIGEgZHVtbXkgbWV0aG9kLCBzaW5jZSBhbGwgaXQgZG9lcyBpcyByZXR1cm4gdGhlIGNoYXIsCi0gICAgICogYnV0IGFzIGFuIGludCB2YWx1ZS4KLSAgICAgKiA8cD4KLSAgICAgKiBUaGlzIGlzIG5vdCBhIHB1YmxpYyBBUEkuCi0gICAgICogQHBhcmFtIGNoIHRoZSBjaGFyLgotICAgICAqIEB4c2wudXNhZ2UgaW50ZXJuYWwKLSAgICAgKi8KLSAgICBzdGF0aWMgaW50IHRvQ29kZVBvaW50KGNoYXIgY2gpIHsKLSAgICAgICAgaW50IGNvZGVQb2ludCA9IGNoOwotICAgICAgICByZXR1cm4gY29kZVBvaW50OwotICAgIH0KLQotICAgIHByaXZhdGUgZmluYWwgc3RhdGljIEVuY29kaW5nSW5mb3MgX2VuY29kaW5nSW5mb3MgPSBuZXcgRW5jb2RpbmdJbmZvcygpOwotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL0VuY29kaW5ncy5wcm9wZXJ0aWVzIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9FbmNvZGluZ3MucHJvcGVydGllcwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZTM4MGY3Ny4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL0VuY29kaW5ncy5wcm9wZXJ0aWVzCisrKyAvZGV2L251bGwKQEAgLTEsMTE4ICswLDAgQEAKLSMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwotIyBDb3B5cmlnaHQgMjAwMy0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSMKLSMgTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0jIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSMgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0jCi0jICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSMKLSMgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotIyBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotIyBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSMgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotIyBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCi0jCi0jICRJZCQKLSMKLSMgPEpBVkEgbmFtZSBlbmNvZGluZz4sIDxQUkVGRVJSRUQgbmFtZSBNSU1FPgotIyBQZXRlciBTbW9saWsKLUNwMTI1MCBXSU5ET1dTLTEyNTAgMHgwMEZGCi0jIFBhdGNoIGF0dHJpYnV0ZWQgdG8gaGF2YXJkd0B1bmRlcmR1c2tlbi5ubyAoSOV2YXJkIFdpZ3RpbCkKLUNwMTI1MSBXSU5ET1dTLTEyNTEgMHgwMEZGCi1DcDEyNTIgV0lORE9XUy0xMjUyIDB4MDBGRgotSVNPODg1OV8xIElTTy04ODU5LTEgMHgwMEZGCi0jIFBhdGNoIGF0dHJpYnV0ZWQgdG8gaGF2YXJkd0B1bmRlcmR1c2tlbi5ubyAoSOV2YXJkIFdpZ3RpbCkKLUlTTzg4NTktMSBJU08tODg1OS0xIDB4MDBGRgotSVNPODg1OV8yIElTTy04ODU5LTIgMHgwMEZGCi0jIEknbSBnb2luZyB0byBhcHBseSAiSVNPODg1OS1YIiB2YXJpYW50IHRvIGFsbCB0aGVzZSwgdG8gYmUgc2FmZS4KLUlTTzg4NTktMiBJU08tODg1OS0yIDB4MDBGRgotSVNPODg1OV8zIElTTy04ODU5LTMgMHgwMEZGCi1JU084ODU5LTMgSVNPLTg4NTktMyAweDAwRkYKLUlTTzg4NTlfNCBJU08tODg1OS00IDB4MDBGRgotSVNPODg1OS00IElTTy04ODU5LTQgMHgwMEZGCi1JU084ODU5XzUgSVNPLTg4NTktNSAweDAwRkYKLUlTTzg4NTktNSBJU08tODg1OS01IDB4MDBGRgotSVNPODg1OV82IElTTy04ODU5LTYgMHgwMEZGCi1JU084ODU5LTYgSVNPLTg4NTktNiAweDAwRkYKLUlTTzg4NTlfNyBJU08tODg1OS03IDB4MDBGRgotSVNPODg1OS03IElTTy04ODU5LTcgMHgwMEZGCi1JU084ODU5XzggSVNPLTg4NTktOCAweDAwRkYKLUlTTzg4NTktOCBJU08tODg1OS04IDB4MDBGRgotSVNPODg1OV85IElTTy04ODU5LTkgMHgwMEZGCi1JU084ODU5LTkgSVNPLTg4NTktOSAweDAwRkYKLUlTTzg4NTlfMTAgSVNPLTg4NTktMTAgMHgwMEZGCi1JU084ODU5LTEwIElTTy04ODU5LTEwIDB4MDBGRgotSVNPODg1OV8xMSBJU08tODg1OS0xMSAweDAwRkYKLUlTTzg4NTktMTEgSVNPLTg4NTktMTEgMHgwMEZGCi1JU084ODU5XzEyIElTTy04ODU5LTEyIDB4MDBGRgotSVNPODg1OS0xMiBJU08tODg1OS0xMiAweDAwRkYKLUlTTzg4NTlfMTMgSVNPLTg4NTktMTMgMHgwMEZGCi1JU084ODU5LTEzIElTTy04ODU5LTEzIDB4MDBGRgotSVNPODg1OV8xNCBJU08tODg1OS0xNCAweDAwRkYKLUlTTzg4NTktMTQgSVNPLTg4NTktMTQgMHgwMEZGCi1JU084ODU5XzE1IElTTy04ODU5LTE1IDB4MDBGRgotSVNPODg1OS0xNSBJU08tODg1OS0xNSAweDAwRkYKLSMgIyA/Ci04ODU5XzEgSVNPLTg4NTktMSAweDAwRkYKLTg4NTlfMiBJU08tODg1OS0yIDB4MDBGRgotODg1OV8zIElTTy04ODU5LTMgMHgwMEZGCi04ODU5XzQgSVNPLTg4NTktNCAweDAwRkYKLTg4NTlfNSBJU08tODg1OS01IDB4MDBGRgotODg1OV82IElTTy04ODU5LTYgMHgwMEZGCi04ODU5XzcgSVNPLTg4NTktNyAweDAwRkYKLTg4NTlfOCBJU08tODg1OS04IDB4MDBGRgotODg1OV85IElTTy04ODU5LTkgMHgwMEZGCi04ODU5LTEgSVNPLTg4NTktMSAweDAwRkYKLTg4NTktMiBJU08tODg1OS0yIDB4MDBGRgotODg1OS0zIElTTy04ODU5LTMgMHgwMEZGCi04ODU5LTQgSVNPLTg4NTktNCAweDAwRkYKLTg4NTktNSBJU08tODg1OS01IDB4MDBGRgotODg1OS02IElTTy04ODU5LTYgMHgwMEZGCi04ODU5LTcgSVNPLTg4NTktNyAweDAwRkYKLTg4NTktOCBJU08tODg1OS04IDB4MDBGRgotODg1OS05IElTTy04ODU5LTkgMHgwMEZGCi1KSVMgSVNPLTIwMjItSlAgMHhGRkZGCi1JU08yMDIyS1IgSVNPLTIwMjItS1IgMHhGRkZGCi1TSklTIFNISUZUX0pJUyAweEZGRkYKLUVVQ19KUCBFVUMtSlAgMHhGRkZGCi1FVUNfS1IgRVVDLUtSIDB4RkZGRgotRVVDX0NOIEVVQy1DTiAweEZGRkYKLUVVQ19UVyBFVUMtVFcgMHhGRkZGCi1FVUNfQ04gR0IyMzEyIDB4RkZGRgotRVVDLUpQIEVVQy1KUCAweEZGRkYKLUVVQy1LUiBFVUMtS1IgMHhGRkZGCi1FVUMtQ04gRVVDLUNOIDB4RkZGRgotRVVDLVRXIEVVQy1UVyAweEZGRkYKLUVVQy1DTiBHQjIzMTIgMHhGRkZGCi1HQjIzMTIgR0IyMzEyIDB4RkZGRgotQmlnNSBCSUc1IDB4RkZGRgotRVVDSklTIEVVQy1KUCAweEZGRkYKLUtTQzU2MDEgRVVDLUtSIDB4RkZGRgotS09JOF9SIEtPSTgtUiAweEZGRkYKLUNwMDM3IEVCQ0RJQy1DUC1VUyxFQkNESUMtQ1AtQ0EsRUJDRElDLUNQLU5MIDB4MDBGRgotQ3AyNzcgRUJDRElDLUNQLURLLEVCQ0RJQy1DUC1OTyAweDAwRkYKLUNwMjc4IEVCQ0RJQy1DUC1GSSxFQkNESUMtQ1AtU0UgMHgwMEZGCi1DcDI4MCBFQkNESUMtQ1AtSVQgMHgwMEZGCi1DcDI4NCBFQkNESUMtQ1AtRVMgMHgwMEZGCi1DcDI4NSBFQkNESUMtQ1AtR0IgMHgwMEZGCi1DcDI5NyBFQkNESUMtQ1AtRlIgMHgwMEZGCi1DcDQyMCBFQkNESUMtQ1AtQVIxIDB4MDBGRgotQ3A0MjQgRUJDRElDLUNQLUhFIDB4MDBGRgotQ3A1MDAgRUJDRElDLUNQLUNIIDB4MDBGRgotQ3A4NTAgODUwLGNzUEM4NTBNdWx0aWxpbmd1YWwgMHhGRkZGCi1DcDg2MCA4NjAsY3NJQk04NjAgMHhGRkZGCi1DcDg3MCBFQkNESUMtQ1AtUk9FQ0UsRUJDRElDLUNQLVlVIDB4MDBGRgotQ3A4NzEgRUJDRElDLUNQLUlTIDB4MDBGRgotQ3A5MTggRUJDRElDLUNQLUFSMiAweDAwRkYKLUNwMTA0NyBJQk0xMDQ3LElCTS0xMDQ3IDB4MDBGRgotTWFjVEVDIE1hY1JvbWFuIDB4MDBGRgotQVNDSUkgQVNDSUksVVMtQVNDSUkgMHgwMDdGCi1Vbmljb2RlIFVOSUNPREUsVVRGLTE2IDB4RkZGRgotVVRGOCBVVEYtOCAweEZGRkYKLSMgcGF0Y2ggYXR0cmlidXRlZCB0byBKaW5zdW5nIExlZQotS1NfQ181NjAxLTE5ODcgS1NfQ181NjAxLTE5ODcsaXNvLWlyLTE0OSxLU19DXzU2MDEtMTk4OSxLU0NfNTYwMSxjc0tTQzU2MDExOTg3IDB4RkZGRgotIyBub3RlIHRoYXQgbW9yZSBjaGFyYWN0ZXIgc2V0IG5hbWVzIGFuZCB0aGVpciBhbGlhc2VzCi0jIGNhbiBiZSBmb3VuZCBhdCBodHRwOi8vd3d3LmlhbmEub3JnL2Fzc2lnbm1lbnRzL2NoYXJhY3Rlci1zZXRzCi0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvRXh0ZW5kZWRDb250ZW50SGFuZGxlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9FeHRlbmRlZENvbnRlbnRIYW5kbGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDZkZWVmYjIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9FeHRlbmRlZENvbnRlbnRIYW5kbGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyNzMgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMy0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRXh0ZW5kZWRDb250ZW50SGFuZGxlci5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE1IDA4OjE1OjE3IHN1cmVzaF9lbWFpbGlkIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2VMb2NhdG9yOwotCi1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotCi0vKioKLSAqIFRoaXMgaW50ZXJmYWNlIGRlc2NyaWJlcyBleHRlbnNpb25zIHRvIHRoZSBTQVggQ29udGVudEhhbmRsZXIgaW50ZXJmYWNlLgotICogSXQgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBieSBhIHNlcmlhbGl6ZXIuIFRoZSBtZXRob2RzIG9uIHRoaXMgaW50ZXJmYWNlIHdpbGwKLSAqIGltcGxlbWVudCBTQVgtIGxpa2UgYmVoYXZpb3IuIFRoaXMgYWxsb3dzIHRoZSBncmFkdWFsIGNvbGxlY3Rpb24gb2YKLSAqIGluZm9ybWF0aW9uIHJhdGhlciB0aGFuIGhhdmluZyBpdCBhbGwgdXAgZnJvbnQuIEZvciBleGFtcGxlIHRoZSBjYWxsCi0gKiA8cHJlPgotICogc3RhcnRFbGVtZW50KG5hbWVzcGFjZVVSSSxsb2NhbE5hbWUscU5hbWUsYXR0cykKLSAqIDwvcHJlPgotICogY291bGQgYmUgcmVwbGFjZWQgd2l0aCB0aGUgY2FsbHMKLSAqIDxwcmU+Ci0gKiBzdGFydEVsZW1lbnQobmFtZXNwYWNlVVJJLGxvY2FsTmFtZSxxTmFtZSkKLSAqIGFkZEF0dHJpYnV0ZXMoYXR0cykKLSAqIDwvcHJlPgotICogSWYgdGhlcmUgYXJlIG5vIGF0dHJpYnV0ZXMgdGhlIHNlY29uZCBjYWxsIGNhbiBiZSBkcm9wcGVkLiBJZiBhdHRyaWJ1dGVzIGFyZQotICogdG8gYmUgYWRkZWQgb25lIGF0IGEgdGltZSB3aXRoIGNhbGxzIHRvCi0gKiA8cHJlPgotICogYWRkQXR0cmlidXRlKG5hbWVzcGFjZVVSSSwgbG9jYWxOYW1lLCBxTmFtZSwgdHlwZSwgdmFsdWUpCi0gKiA8L3ByZT4KLSAqIEB4c2wudXNhZ2UgaW50ZXJuYWwKLSAqLwotYWJzdHJhY3QgaW50ZXJmYWNlIEV4dGVuZGVkQ29udGVudEhhbmRsZXIgZXh0ZW5kcyBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcgotewotICAgIC8qKgotICAgICAqIEFkZCBhdCBhdHRyaWJ1dGUgdG8gdGhlIGN1cnJlbnQgZWxlbWVudAotICAgICAqIEBwYXJhbSB1cmkgdGhlIG5hbWVzcGFjZSBVUkkgb2YgdGhlIGF0dHJpYnV0ZSBuYW1lCi0gICAgICogQHBhcmFtIGxvY2FsTmFtZSB0aGUgbG9jYWwgbmFtZSBvZiB0aGUgYXR0cmlidXRlICh3aXRob3V0IHByZWZpeCkKLSAgICAgKiBAcGFyYW0gcmF3TmFtZSB0aGUgcXVhbGlmaWVkIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZQotICAgICAqIEBwYXJhbSB0eXBlIHRoZSBhdHRyaWJ1dGUgdHlwZSB0eXBpY2FsbHkgY2hhcmFjdGVyIGRhdGEgKENEQVRBKQotICAgICAqIEBwYXJhbSB2YWx1ZSB0aGUgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZQotICAgICAqIEBwYXJhbSBYU0xBdHRyaWJ1dGUgdHJ1ZSBpZiB0aGUgYWRkZWQgYXR0cmlidXRlIGlzIGNvbWluZyBmcm9tIGFuIHhzbDphdHRyaWJ1dGUgZWxlbWVudAotICAgICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgYWRkQXR0cmlidXRlKAotICAgICAgICBTdHJpbmcgdXJpLAotICAgICAgICBTdHJpbmcgbG9jYWxOYW1lLAotICAgICAgICBTdHJpbmcgcmF3TmFtZSwKLSAgICAgICAgU3RyaW5nIHR5cGUsCi0gICAgICAgIFN0cmluZyB2YWx1ZSwKLSAgICAgICAgYm9vbGVhbiBYU0xBdHRyaWJ1dGUpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb247Ci0gICAgLyoqCi0gICAgICogQWRkIGF0dHJpYnV0ZXMgdG8gdGhlIGN1cnJlbnQgZWxlbWVudAotICAgICAqIEBwYXJhbSBhdHRzIHRoZSBhdHRyaWJ1dGVzIHRvIGFkZC4KLSAgICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGFkZEF0dHJpYnV0ZXMob3JnLnhtbC5zYXguQXR0cmlidXRlcyBhdHRzKQotICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotICAgIC8qKgotICAgICAqIEFkZCBhbiBhdHRyaWJ1dGUgdG8gdGhlIGN1cnJlbnQgZWxlbWVudC4gVGhlIG5hbWVzcGFjZSBVUkkgb2YgdGhlCi0gICAgICogYXR0cmlidXRlIHdpbGwgYmUgY2FsY3VsYXRlZCBmcm9tIHRoZSBwcmVmaXggb2YgcU5hbWUuIFRoZSBsb2NhbCBuYW1lCi0gICAgICogd2lsbCBiZSBkZXJpdmVkIGZyb20gcU5hbWUgYW5kIHRoZSB0eXBlIHdpbGwgYmUgYXNzdW1lZCB0byBiZSAiQ0RBVEEiLgotICAgICAqIEBwYXJhbSBxTmFtZQotICAgICAqIEBwYXJhbSB2YWx1ZQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGFkZEF0dHJpYnV0ZShTdHJpbmcgcU5hbWUsIFN0cmluZyB2YWx1ZSk7Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBpcyB1c2VkIHRvIG5vdGlmeSBvZiBhIGNoYXJhY3RlciBldmVudCwgYnV0IHBhc3NpbmcgdGhlIGRhdGEKLSAgICAgKiBhcyBhIGNoYXJhY3RlciBTdHJpbmcgcmF0aGVyIHRoYW4gdGhlIHN0YW5kYXJkIGNoYXJhY3RlciBhcnJheS4KLSAgICAgKiBAcGFyYW0gY2hhcnMgdGhlIGNoYXJhY3RlciBkYXRhCi0gICAgICogQHRocm93cyBTQVhFeGNlcHRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBjaGFyYWN0ZXJzKFN0cmluZyBjaGFycykgdGhyb3dzIFNBWEV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIGlzIHVzZWQgdG8gbm90aWZ5IG9mIGEgY2hhcmFjdGVyIGV2ZW50LCBidXQgcGFzc2luZyB0aGUgZGF0YQotICAgICAqIGFzIGEgRE9NIE5vZGUgcmF0aGVyIHRoYW4gdGhlIHN0YW5kYXJkIGNoYXJhY3RlciBhcnJheS4KLSAgICAgKiBAcGFyYW0gbm9kZSBhIERPTSBOb2RlIGNvbnRhaW5pbmcgdGV4dC4KLSAgICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGNoYXJhY3RlcnMob3JnLnczYy5kb20uTm9kZSBub2RlKSB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIGlzIHVzZWQgdG8gbm90aWZ5IHRoYXQgYW4gZWxlbWVudCBoYXMgZW5kZWQuIFVubGlrZSB0aGUKLSAgICAgKiBzdGFuZGFyZCBTQVggbWV0aG9kCi0gICAgICogPHByZT4KLSAgICAgKiBlbmRFbGVtZW50KG5hbWVzcGFjZVVSSSxsb2NhbE5hbWUscU5hbWUpCi0gICAgICogPC9wcmU+Ci0gICAgICogb25seSB0aGUgbGFzdCBwYXJhbWV0ZXIgaXMgcGFzc2VkLiBJZiBuZWVkZWQgdGhlIHNlcmlhbGl6ZXIgY2FuIGRlcml2ZQotICAgICAqIHRoZSBsb2NhbE5hbWUgZnJvbSB0aGUgcXVhbGlmaWVkIG5hbWUgYW5kIGRlcml2ZSB0aGUgbmFtZXNwYWNlVVJJIGZyb20KLSAgICAgKiBpdHMgaW1wbGVtZW50YXRpb24uCi0gICAgICogQHBhcmFtIGVsZW1OYW1lIHRoZSBmdWxseSBxdWFsaWZpZWQgZWxlbWVudCBuYW1lLgotICAgICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kRWxlbWVudChTdHJpbmcgZWxlbU5hbWUpIHRocm93cyBTQVhFeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBpcyB1c2VkIHRvIG5vdGlmeSB0aGF0IGFuIGVsZW1lbnQgaXMgc3RhcnRpbmcuCi0gICAgICogVGhpcyBtZXRob2QgaXMganVzdCBsaWtlIHRoZSBzdGFuZGFyZCBTQVggbWV0aG9kCi0gICAgICogPHByZT4KLSAgICAgKiBzdGFydEVsZW1lbnQodXJpLGxvY2FsTmFtZSxxbmFtZSxhdHRzKQotICAgICAqIDwvcHJlPgotICAgICAqIGJ1dCB3aXRob3V0IHRoZSBhdHRyaWJ1dGVzLgotICAgICAqIEBwYXJhbSB1cmkgdGhlIG5hbWVzcGFjZSBVUkkgb2YgdGhlIGVsZW1lbnQKLSAgICAgKiBAcGFyYW0gbG9jYWxOYW1lIHRoZSBsb2NhbCBuYW1lICh3aXRob3V0IHByZWZpeCkgb2YgdGhlIGVsZW1lbnQKLSAgICAgKiBAcGFyYW0gcU5hbWUgdGhlIHF1YWxpZmllZCBuYW1lIG9mIHRoZSBlbGVtZW50Ci0gICAgICoKLSAgICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudChTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxOYW1lLCBTdHJpbmcgcU5hbWUpCi0gICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBpcyB1c2VkIHRvIG5vdGlmeSBvZiB0aGUgc3RhcnQgb2YgYW4gZWxlbWVudAotICAgICAqIEBwYXJhbSBxTmFtZSB0aGUgZnVsbHkgcXVhbGlmaWVkIG5hbWUgb2YgdGhlIGVsZW1lbnQKLSAgICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudChTdHJpbmcgcU5hbWUpIHRocm93cyBTQVhFeGNlcHRpb247Ci0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgaXMgdXNlZCB0byBub3RpZnkgdGhhdCBhIHByZWZpeCBtYXBwaW5nIGlzIHRvIHN0YXJ0LCBidXQKLSAgICAgKiBhZnRlciBhbiBlbGVtZW50IGlzIHN0YXJ0ZWQuIFRoZSBTQVggbWV0aG9kIGNhbGwKLSAgICAgKiA8cHJlPgotICAgICAqIHN0YXJ0UHJlZml4TWFwcGluZyhwcmVmaXgsdXJpKQotICAgICAqIDwvcHJlPgotICAgICAqIGlzIHVzZWQganVzdCBiZWZvcmUgYW4gZWxlbWVudCBzdGFydHMgYW5kIGFwcGxpZXMgdG8gdGhlIGVsZW1lbnQgdG8gY29tZSwKLSAgICAgKiBub3QgdG8gdGhlIGN1cnJlbnQgZWxlbWVudC4gIFRoaXMgbWV0aG9kIGFwcGxpZXMgdG8gdGhlIGN1cnJlbnQgZWxlbWVudC4KLSAgICAgKiBGb3IgZXhhbXBsZSBvbmUgY291bGQgbWFrZSB0aGUgY2FsbHMgaW4gdGhpcyBvcmRlcjoKLSAgICAgKiA8cHJlPgotICAgICAqIHN0YXJ0RWxlbWVudCgicHJmeDg6ZWxlbTkiKQotICAgICAqIG5hbWVzcGFjZUFmdGVyU3RhcnRFbGVtZW50KCJodHRwOi8vbmFtZXNwYWNlOCIsInByZng4IikKLSAgICAgKiA8L3ByZT4KLSAgICAgKgotICAgICAqIEBwYXJhbSB1cmkgdGhlIG5hbWVzcGFjZSBVUkkgYmVpbmcgZGVjbGFyZWQKLSAgICAgKiBAcGFyYW0gcHJlZml4IHRoZSBwcmVmaXggdGhhdCBtYXBzIHRvIHRoZSBnaXZlbiBuYW1lc3BhY2UKLSAgICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIG5hbWVzcGFjZUFmdGVyU3RhcnRFbGVtZW50KFN0cmluZyB1cmksIFN0cmluZyBwcmVmaXgpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBpcyB1c2VkIHRvIG5vdGlmeSB0aGF0IGEgcHJlZml4IG1hcGluZyBpcyB0byBzdGFydCwgd2hpY2ggY2FuCi0gICAgICogYmUgZm9yIHRoZSBjdXJyZW50IGVsZW1lbnQsIG9yIGZvciB0aGUgb25lIHRvIGNvbWUuCi0gICAgICogQHBhcmFtIHByZWZpeCB0aGUgcHJlZml4IHRoYXQgbWFwcyB0byB0aGUgZ2l2ZW4gVVJJCi0gICAgICogQHBhcmFtIHVyaSB0aGUgbmFtZXNwYWNlIFVSSSBvZiB0aGUgZ2l2ZW4gcHJlZml4Ci0gICAgICogQHBhcmFtIHNob3VsZEZsdXNoIGlmIHRydWUgdGhpcyBjYWxsIGlzIGxpa2UgdGhlIFNBWAotICAgICAqIHN0YXJ0UHJlZml4TWFwcGluZyhwcmVmaXgsdXJpKSBjYWxsIGFuZCB0aGUgbWFwcGluZyBhcHBsaWVzIHRvIHRoZQotICAgICAqIGVsZW1lbnQgdG8gY29tZS4gIElmIGZhbHNlIHRoZSBtYXBwaW5nIGFwcGxpZXMgdG8gdGhlIGN1cnJlbnQgZWxlbWVudC4KLSAgICAgKiBAcmV0dXJuIGJvb2xlYW4gZmFsc2UgaWYgdGhlIHByZWZpeCBtYXBwaW5nIHdhcyBhbHJlYWR5IGluIGVmZmVjdCAoaW4KLSAgICAgKiBvdGhlciB3b3JkcyB3ZSBhcmUganVzdCByZS1kZWNsYXJpbmcpLCB0cnVlIGlmIHRoaXMgaXMgYSBuZXcsIG5ldmVyCi0gICAgICogYmVmb3JlIHNlZW4gbWFwcGluZyBmb3IgdGhlIGVsZW1lbnQuCi0gICAgICogQHRocm93cyBTQVhFeGNlcHRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBzdGFydFByZWZpeE1hcHBpbmcoCi0gICAgICAgIFN0cmluZyBwcmVmaXgsCi0gICAgICAgIFN0cmluZyB1cmksCi0gICAgICAgIGJvb2xlYW4gc2hvdWxkRmx1c2gpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb247Ci0gICAgLyoqCi0gICAgICogTm90aWZ5IG9mIGFuIGVudGl0eSByZWZlcmVuY2UuCi0gICAgICogQHBhcmFtIGVudGl0eU5hbWUgdGhlIG5hbWUgb2YgdGhlIGVudGl0eQotICAgICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW50aXR5UmVmZXJlbmNlKFN0cmluZyBlbnRpdHlOYW1lKSB0aHJvd3MgU0FYRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgcmV0dXJucyBhbiBvYmplY3QgdGhhdCBoYXMgdGhlIGN1cnJlbnQgbmFtZXNwYWNlIG1hcHBpbmdzIGluCi0gICAgICogZWZmZWN0LgotICAgICAqCi0gICAgICogQHJldHVybiBOYW1lc3BhY2VNYXBwaW5ncyBhbiBvYmplY3QgdGhhdCBoYXMgdGhlIGN1cnJlbnQgbmFtZXNwYWNlCi0gICAgICogbWFwcGluZ3MgaW4gZWZmZWN0LgotICAgICAqLwotICAgIHB1YmxpYyBOYW1lc3BhY2VNYXBwaW5ncyBnZXROYW1lc3BhY2VNYXBwaW5ncygpOwotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIHJldHVybnMgdGhlIHByZWZpeCB0aGF0IGN1cnJlbnRseSBtYXBzIHRvIHRoZSBnaXZlbiBuYW1lc3BhY2UKLSAgICAgKiBVUkkuCi0gICAgICogQHBhcmFtIHVyaSB0aGUgbmFtZXNwYWNlIFVSSQotICAgICAqIEByZXR1cm4gU3RyaW5nIHRoZSBwcmVmaXggdGhhdCBjdXJyZW50bHkgbWFwcyB0byB0aGUgZ2l2ZW4gVVJJLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0UHJlZml4KFN0cmluZyB1cmkpOwotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIGdldHMgdGhlIHByZWZpeCBhc3NvY2lhdGVkIHdpdGggYSBjdXJyZW50IGVsZW1lbnQgb3IKLSAgICAgKiBhdHRyaWJ1dGUgbmFtZS4KLSAgICAgKiBAcGFyYW0gbmFtZSB0aGUgcXVhbGlmaWVkIG5hbWUgb2YgYW4gZWxlbWVudCwgb3IgYXR0cmlidXRlCi0gICAgICogQHBhcmFtIGlzRWxlbWVudCB0cnVlIGlmIGl0IGlzIGFuIGVsZW1lbnQgbmFtZSwgZmFsc2UgaWYgaXQgaXMgYW4KLSAgICAgKiBhdHR0cmlidXRlIG5hbWUKLSAgICAgKiBAcmV0dXJuIFN0cmluZyB0aGUgbmFtZXNwYWNlIFVSSSBhc3NvY2lhdGVkIHdpdGggdGhlIGVsZW1lbnQgb3IKLSAgICAgKiBhdHRyaWJ1dGUuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXROYW1lc3BhY2VVUkkoU3RyaW5nIG5hbWUsIGJvb2xlYW4gaXNFbGVtZW50KTsKLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCByZXR1cm5zIHRoZSBuYW1lc3BhY2UgVVJJIGN1cnJlbnRseSBhc3NvY2lhdGVkIHdpdGggdGhlCi0gICAgICogcHJlZml4LgotICAgICAqIEBwYXJhbSBwcmVmaXggYSBwcmVmaXggb2YgYW4gZWxlbWVudCBvciBhdHRyaWJ1dGUuCi0gICAgICogQHJldHVybiBTdHJpbmcgdGhlIG5hbWVzcGFjZSBVUkkgY3VycmVudGx5IGFzc29jaWF0ZWQgd2l0aCB0aGUgcHJlZml4LgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZXNwYWNlVVJJRnJvbVByZWZpeChTdHJpbmcgcHJlZml4KTsKLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIGlzIHVzZWQgdG8gc2V0IHRoZSBzb3VyY2UgbG9jYXRvciwgd2hpY2ggbWlnaHQgYmUgdXNlZCB0bwotICAgICAqIGdlbmVyYXRlZCBhbiBlcnJvciBtZXNzYWdlLgotICAgICAqIEBwYXJhbSBsb2NhdG9yIHRoZSBzb3VyY2UgbG9jYXRvcgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFNvdXJjZUxvY2F0b3IoU291cmNlTG9jYXRvciBsb2NhdG9yKTsKLQotICAgIC8vIEJpdCBjb25zdGFudHMgZm9yIGFkZFVuaXF1ZUF0dHJpYnV0ZSgpLgotCi0gICAgLy8gVGhlIGF0dHJpYnV0ZSB2YWx1ZSBjb250YWlucyBubyBiYWQgY2hhcmFjdGVycy4gQSAiYmFkIiBjaGFyYWN0ZXIgaXMgb25lIHdoaWNoCi0gICAgLy8gaXMgZ3JlYXRlciB0aGFuIDEyNiBvciBpdCBpcyBvbmUgb2YgJzwnLCAnPicsICcmJyBvciAnIicuCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTk9fQkFEX0NIQVJTID0gMHgxOwotCi0gICAgLy8gQW4gSFRNTCBlbXB0eSBhdHRyaWJ1dGUgKGUuZy4gPE9QVElPTiBzZWxlY3RlZD4pLgotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEhUTUxfQVRUUkVNUFRZID0gMHgyOwotCi0gICAgLy8gQW4gSFRNTCBVUkwgYXR0cmlidXRlCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSFRNTF9BVFRSVVJMID0gMHg0OwotCi0gICAgLyoqCi0gICAgICogQWRkIGEgdW5pcXVlIGF0dHJpYnV0ZSB0byB0aGUgY3VycmVudCBlbGVtZW50LgotICAgICAqIFRoZSBhdHRyaWJ1dGUgaXMgZ3VhcmFudGVlZCB0byBiZSB1bmlxdWUgaGVyZS4gVGhlIHNlcmlhbGl6ZXIgY2FuIHdyaXRlCi0gICAgICogaXQgb3V0IGltbWVkaWF0ZWx5IHdpdGhvdXQgc2F2aW5nIGl0IGluIGEgdGFibGUgZmlyc3QuIFRoZSBpbnRlZ2VyCi0gICAgICogZmxhZyBjb250YWlucyBpbmZvcm1hdGlvbiBhYm91dCB0aGUgYXR0cmlidXRlLCB3aGljaCBoZWxwcyB0aGUgc2VyaWFsaXplcgotICAgICAqIHRvIGRlY2lkZSB3aGV0aGVyIGEgcGFydGljdWxhciBwcm9jZXNzaW5nIGlzIG5lZWRlZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBxTmFtZSB0aGUgZnVsbHkgcXVhbGlmaWVkIGF0dHJpYnV0ZSBuYW1lLgotICAgICAqIEBwYXJhbSB2YWx1ZSB0aGUgYXR0cmlidXRlIHZhbHVlCi0gICAgICogQHBhcmFtIGZsYWdzIGEgYml0d2lzZSBmbGFnCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgYWRkVW5pcXVlQXR0cmlidXRlKFN0cmluZyBxTmFtZSwgU3RyaW5nIHZhbHVlLCBpbnQgZmxhZ3MpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBBZGQgYW4gYXR0cmlidXRlIGZyb20gYW4geHNsOmF0dHJpYnV0ZSBlbGVtZW50LgotICAgICAqIEBwYXJhbSBxTmFtZSB0aGUgcXVhbGlmaWVkIGF0dHJpYnV0ZSBuYW1lIChwcmVmaXg6bG9jYWxOYW1lKQotICAgICAqIEBwYXJhbSB2YWx1ZSB0aGUgYXR0cmlidXRlcyB2YWx1ZQotICAgICAqIEBwYXJhbSB1cmkgdGhlIHVyaSB0aGF0IHRoZSBwcmVmaXggb2YgdGhlIHFOYW1lIGlzIG1hcHBlZCB0by4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBhZGRYU0xBdHRyaWJ1dGUoU3RyaW5nIHFOYW1lLCBmaW5hbCBTdHJpbmcgdmFsdWUsIGZpbmFsIFN0cmluZyB1cmkpOwotCi0gICAgLyoqCi0gICAgICogQWRkIGF0IGF0dHJpYnV0ZSB0byB0aGUgY3VycmVudCBlbGVtZW50LCBub3QgZnJvbSBhbiB4c2w6YXR0cmlidXRlCi0gICAgICogZWxlbWVudC4KLSAgICAgKiBAcGFyYW0gdXJpIHRoZSBuYW1lc3BhY2UgVVJJIG9mIHRoZSBhdHRyaWJ1dGUgbmFtZQotICAgICAqIEBwYXJhbSBsb2NhbE5hbWUgdGhlIGxvY2FsIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZSAod2l0aG91dCBwcmVmaXgpCi0gICAgICogQHBhcmFtIHJhd05hbWUgdGhlIHF1YWxpZmllZCBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUKLSAgICAgKiBAcGFyYW0gdHlwZSB0aGUgYXR0cmlidXRlIHR5cGUgdHlwaWNhbGx5IGNoYXJhY3RlciBkYXRhIChDREFUQSkKLSAgICAgKiBAcGFyYW0gdmFsdWUgdGhlIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUKLSAgICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGFkZEF0dHJpYnV0ZSgKLSAgICAgICAgU3RyaW5nIHVyaSwKLSAgICAgICAgU3RyaW5nIGxvY2FsTmFtZSwKLSAgICAgICAgU3RyaW5nIHJhd05hbWUsCi0gICAgICAgIFN0cmluZyB0eXBlLAotICAgICAgICBTdHJpbmcgdmFsdWUpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb247Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL0V4dGVuZGVkTGV4aWNhbEhhbmRsZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvRXh0ZW5kZWRMZXhpY2FsSGFuZGxlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0OTgzZGJlLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvRXh0ZW5kZWRMZXhpY2FsSGFuZGxlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDEgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMy0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRXh0ZW5kZWRMZXhpY2FsSGFuZGxlci5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE1IDA4OjE1OjE4IHN1cmVzaF9lbWFpbGlkIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyOwotCi1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotCi0vKioKLSAqIFRoaXMgaW50ZXJmYWNlIGhhcyBleHRlbnNpb25zIHRvIHRoZSBzdGFuZGFyZCBTQVggTGV4aWNhbEhhbmRsZXIgaW50ZXJmYWNlLgotICogVGhpcyBpbnRlcmZhY2UgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBieSBhIHNlcmlhbGl6ZXIuCi0gKiBAeHNsLnVzYWdlIGludGVybmFsCi0gKi8KLWFic3RyYWN0IGludGVyZmFjZSBFeHRlbmRlZExleGljYWxIYW5kbGVyIGV4dGVuZHMgb3JnLnhtbC5zYXguZXh0LkxleGljYWxIYW5kbGVyCi17Ci0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgaXMgdXNlZCB0byBub3RpZnkgb2YgYSBjb21tZW50Ci0gICAgICogQHBhcmFtIGNvbW1lbnQgdGhlIGNvbW1lbnQsIGJ1dCB1bmxpa2UgdGhlIFNBWCBjb21tZW50KCkgbWV0aG9kIHRoaXMKLSAgICAgKiBtZXRob2QgdGFrZXMgYSBTdHJpbmcgcmF0aGVyIHRoYW4gYSBjaGFyYWN0ZXIgYXJyYXkuCi0gICAgICogQHRocm93cyBTQVhFeGNlcHRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBjb21tZW50KFN0cmluZyBjb21tZW50KSB0aHJvd3MgU0FYRXhjZXB0aW9uOwotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9IVE1MRW50aXRpZXMucHJvcGVydGllcyBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvSFRNTEVudGl0aWVzLnByb3BlcnRpZXMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDVjMjcyYzkuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9IVE1MRW50aXRpZXMucHJvcGVydGllcworKysgL2Rldi9udWxsCkBAIC0xLDMxNCArMCwwIEBACi0jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKLSMgcmVzZXJ2ZWQgY29tbWVudCBibG9jawotIyBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCi0jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKLSMgQ29weXJpZ2h0IDIwMDMtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0jCi0jIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotIyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0jIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotIwotIyAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0jCi0jIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSMgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0jIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSMgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwotIwotIyAkSWQ6IEhUTUxFbnRpdGllcy5wcm9wZXJ0aWVzLHYgMS4yLjQuMSAyMDA1LzA5LzE1IDA4OjE1OjE5IHN1cmVzaF9lbWFpbGlkIEV4cCAkCi0jIGluIC4vamF2YS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyCi0jCi0jIEBhdXRob3IgPGEgaHJlZj0ibWFpbHRvOmFya2luQGludGFsaW8uY29tIj5Bc3NhZiBBcmtpbjwvYT4KLSMgVGhpcyBmaWxlIG11c3QgYmUgZW5jb2RlZCBpbiBVVEYtODsgc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplci5DaGFySW5mbwotIwotIyBDaGFyYWN0ZXIgZW50aXR5IHJlZmVyZW5jZXMgZm9yIG1hcmt1cC1zaWduaWZpY2FudAotIwotcXVvdD0zNAotYW1wPTM4Ci1sdD02MAotZ3Q9NjIKLW5ic3A9MTYwCi0jCi0jIENoYXJhY3RlciBlbnRpdHkgcmVmZXJlbmNlcyBmb3IgSVNPIDg4NTktMSBjaGFyYWN0ZXJzCi0jCi1pZXhjbD0xNjEKLWNlbnQ9MTYyCi1wb3VuZD0xNjMKLWN1cnJlbj0xNjQKLXllbj0xNjUKLWJydmJhcj0xNjYKLXNlY3Q9MTY3Ci11bWw9MTY4Ci1jb3B5PTE2OQotb3JkZj0xNzAKLWxhcXVvPTE3MQotbm90PTE3Mgotc2h5PTE3MwotcmVnPTE3NAotbWFjcj0xNzUKLWRlZz0xNzYKLXBsdXNtbj0xNzcKLXN1cDI9MTc4Ci1zdXAzPTE3OQotYWN1dGU9MTgwCi1taWNybz0xODEKLXBhcmE9MTgyCi1taWRkb3Q9MTgzCi1jZWRpbD0xODQKLXN1cDE9MTg1Ci1vcmRtPTE4NgotcmFxdW89MTg3Ci1mcmFjMTQ9MTg4Ci1mcmFjMTI9MTg5Ci1mcmFjMzQ9MTkwCi1pcXVlc3Q9MTkxCi1BZ3JhdmU9MTkyCi1BYWN1dGU9MTkzCi1BY2lyYz0xOTQKLUF0aWxkZT0xOTUKLUF1bWw9MTk2Ci1BcmluZz0xOTcKLUFFbGlnPTE5OAotQ2NlZGlsPTE5OQotRWdyYXZlPTIwMAotRWFjdXRlPTIwMQotRWNpcmM9MjAyCi1FdW1sPTIwMwotSWdyYXZlPTIwNAotSWFjdXRlPTIwNQotSWNpcmM9MjA2Ci1JdW1sPTIwNwotRVRIPTIwOAotTnRpbGRlPTIwOQotT2dyYXZlPTIxMAotT2FjdXRlPTIxMQotT2NpcmM9MjEyCi1PdGlsZGU9MjEzCi1PdW1sPTIxNAotdGltZXM9MjE1Ci1Pc2xhc2g9MjE2Ci1VZ3JhdmU9MjE3Ci1VYWN1dGU9MjE4Ci1VY2lyYz0yMTkKLVV1bWw9MjIwCi1ZYWN1dGU9MjIxCi1USE9STj0yMjIKLXN6bGlnPTIyMwotYWdyYXZlPTIyNAotYWFjdXRlPTIyNQotYWNpcmM9MjI2Ci1hdGlsZGU9MjI3Ci1hdW1sPTIyOAotYXJpbmc9MjI5Ci1hZWxpZz0yMzAKLWNjZWRpbD0yMzEKLWVncmF2ZT0yMzIKLWVhY3V0ZT0yMzMKLWVjaXJjPTIzNAotZXVtbD0yMzUKLWlncmF2ZT0yMzYKLWlhY3V0ZT0yMzcKLWljaXJjPTIzOAotaXVtbD0yMzkKLWV0aD0yNDAKLW50aWxkZT0yNDEKLW9ncmF2ZT0yNDIKLW9hY3V0ZT0yNDMKLW9jaXJjPTI0NAotb3RpbGRlPTI0NQotb3VtbD0yNDYKLWRpdmlkZT0yNDcKLW9zbGFzaD0yNDgKLXVncmF2ZT0yNDkKLXVhY3V0ZT0yNTAKLXVjaXJjPTI1MQotdXVtbD0yNTIKLXlhY3V0ZT0yNTMKLXRob3JuPTI1NAoteXVtbD0yNTUKLSMKLSMgQ2hhcmFjdGVyIGVudGl0eSByZWZlcmVuY2VzIGZvciBzeW1ib2xzLCBtYXRoZW1hdGljYWwgc3ltYm9scywgYW5kIEdyZWVrIGxldHRlcnMKLSMKLSMgTGF0aW4gRXh0ZW5kZWQgLS0gTmV0c2NhcGUgY2FuJ3QgaGFuZGxlCi0jIGZub2YgNDAyCi0jCi0jIEdyZWVrIC0gTmV0c2NhcGUgY2FuJ3QgaGFuZGxlIHRoZXNlCi0jIEFscGhhIDkxMwotIyBCZXRhIDkxNAotIyBHYW1tYSA5MTUKLSMgRGVsdGEgOTE2Ci0jIEVwc2lsb24gOTE3Ci0jIFpldGEgOTE4Ci0jIEV0YSA5MTkKLSMgVGhldGEgOTIwCi0jIElvdGEgOTIxCi0jIEthcHBhIDkyMgotIyBMYW1iZGEgOTIzCi0jIE11IDkyNAotIyBOdSA5MjUKLSMgWGkgOTI2Ci0jIE9taWNyb24gOTI3Ci0jIFBpIDkyOAotIyBSaG8gOTI5Ci0jIFNpZ21hIDkzMQotIyBUYXUgOTMyCi0jIFVwc2lsb24gOTMzCi0jIFBoaSA5MzQKLSMgQ2hpIDkzNQotIyBQc2kgOTM2Ci0jIE9tZWdhIDkzNwotIyBhbHBoYSA5NDUKLSMgYmV0YSA5NDYKLSMgZ2FtbWEgOTQ3Ci0jIGRlbHRhIDk0OAotIyBlcHNpbG9uIDk0OQotIyB6ZXRhIDk1MAotIyBldGEgOTUxCi0jIHRoZXRhIDk1MgotIyBpb3RhIDk1MwotIyBrYXBwYSA5NTQKLSMgbGFtYmRhIDk1NQotIyBtdSA5NTYKLSMgbnUgOTU3Ci0jIHhpIDk1OAotIyBvbWljcm9uIDk1OQotIyBwaSA5NjAKLSMgcmhvIDk2MQotIyBzaWdtYWYgOTYyCi0jIHNpZ21hIDk2MwotIyB0YXUgOTY0Ci0jIHVwc2lsb24gOTY1Ci0jIHBoaSA5NjYKLSMgY2hpIDk2NwotIyBwc2kgOTY4Ci0jIG9tZWdhIDk2OQotIyB0aGV0YXN5bSA5NzcKLSMgdXBzaWggOTc4Ci0jIHBpdiA5ODIKLSMKLSMgR2VuZXJhbCBQdW5jdHVhdGlvbgotYnVsbD04MjI2Ci1oZWxsaXA9ODIzMAotcHJpbWU9ODI0MgotUHJpbWU9ODI0Mwotb2xpbmU9ODI1NAotZnJhc2w9ODI2MAotIwotIyBMZXR0ZXJsaWtlIFN5bWJvbHMKLXdlaWVycD04NDcyCi1pbWFnZT04NDY1Ci1yZWFsPTg0NzYKLXRyYWRlPTg0ODIKLWFsZWZzeW09ODUwMQotIwotIyBBcnJvd3MKLWxhcnI9ODU5MgotdWFycj04NTkzCi1yYXJyPTg1OTQKLWRhcnI9ODU5NQotaGFycj04NTk2Ci1jcmFycj04NjI5Ci1sQXJyPTg2NTYKLXVBcnI9ODY1NwotckFycj04NjU4Ci1kQXJyPTg2NTkKLWhBcnI9ODY2MAotIwotIyBNYXRoZW1hdGljYWwgT3BlcmF0b3JzCi1mb3JhbGw9ODcwNAotcGFydD04NzA2Ci1leGlzdD04NzA3Ci1lbXB0eT04NzA5Ci1uYWJsYT04NzExCi1pc2luPTg3MTIKLW5vdGluPTg3MTMKLW5pPTg3MTUKLXByb2Q9ODcxOQotc3VtPTg3MjEKLW1pbnVzPTg3MjIKLWxvd2FzdD04NzI3Ci1yYWRpYz04NzMwCi1wcm9wPTg3MzMKLWluZmluPTg3MzQKLWFuZz04NzM2Ci1hbmQ9ODc0Mwotb3I9ODc0NAotY2FwPTg3NDUKLWN1cD04NzQ2Ci1pbnQ9ODc0NwotdGhlcmU0PTg3NTYKLXNpbT04NzY0Ci1jb25nPTg3NzMKLWFzeW1wPTg3NzYKLW5lPTg4MDAKLWVxdWl2PTg4MDEKLWxlPTg4MDQKLWdlPTg4MDUKLXN1Yj04ODM0Ci1zdXA9ODgzNQotbnN1Yj04ODM2Ci1zdWJlPTg4MzgKLXN1cGU9ODgzOQotb3BsdXM9ODg1Mwotb3RpbWVzPTg4NTUKLXBlcnA9ODg2OQotc2RvdD04OTAxCi0jCi0jIE1pc2NlbGxhbmVvdXMgVGVjaG5pY2FsCi1sY2VpbD04OTY4Ci1yY2VpbD04OTY5Ci1sZmxvb3I9ODk3MAotcmZsb29yPTg5NzEKLWxhbmc9OTAwMQotcmFuZz05MDAyCi0jCi0jIEdlb21ldHJpYyBTaGFwZXMKLWxvej05Njc0Ci0jCi0jIE1pc2NlbGxhbmVvdXMgU3ltYm9scwotc3BhZGVzPTk4MjQKLWNsdWJzPTk4MjcKLWhlYXJ0cz05ODI5Ci1kaWFtcz05ODMwCi0jCi0jIENoYXJhY3RlciBlbnRpdHkgcmVmZXJlbmNlcyBmb3IgaW50ZXJuYXRpb25hbGl6YXRpb24gY2hhcmFjdGVycwotIwotIyBMYXRpbiBFeHRlbmRlZC1BCi0jIE5ldHNjYXBlIGNhbid0IGhhbmRsZSEKLSMgT0VsaWcgMzM4Ci0jIG9lbGlnIDMzOQotCi0jLS0gTk4gNC43IGRvZXMgbm90IHNlZW0gdG8gc3VwcG9ydCB0aGVzZSwgc28gdGhleSBtaWdodCBvdWdodCB0byBiZSBjb21tZW50ZWQuCi0jIFNjYXJvbiAzNTIKLSMgc2Nhcm9uIDM1MwotIyBZdW1sIDM3NgotIwotIyBTcGFjaW5nIE1vZGlmaWVyIExldHRlcnMgLS0gTmV0c2NhcGUgY2FuJ3QgaGFuZGxlCi0jIGNpcmMgNzEwCi0jIHRpbGRlIDczMgotIwotIyBHZW5lcmFsIFB1bmN0dWF0aW9uCi1lbnNwPTgxOTQKLWVtc3A9ODE5NQotdGhpbnNwPTgyMDEKLXp3bmo9ODIwNAotendqPTgyMDUKLWxybT04MjA2Ci1ybG09ODIwNwotbmRhc2g9ODIxMQotbWRhc2g9ODIxMgotbHNxdW89ODIxNgotcnNxdW89ODIxNwotc2JxdW89ODIxOAotbGRxdW89ODIyMAotcmRxdW89ODIyMQotYmRxdW89ODIyMgotZGFnZ2VyPTgyMjQKLURhZ2dlcj04MjI1Ci1wZXJtaWw9ODI0MAotbHNhcXVvPTgyNDkKLXJzYXF1bz04MjUwCi1ldXJvPTgzNjQKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvTWV0aG9kLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL01ldGhvZC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjZWNhY2MxLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvTWV0aG9kLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3OCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBNZXRob2QuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNSAwODoxNToxOSBzdXJlc2hfZW1haWxpZCBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplcjsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGRlZmluZXMgdGhlIGNvbnN0YW50cyB3aGljaCBhcmUgdGhlIG5hbWVzIG9mIHRoZSBmb3VyIGRlZmF1bHQKLSAqIG91dHB1dCBtZXRob2RzLgotICogPHA+Ci0gKiBUaHJlZSBkZWZhdWx0IG91dHB1dCBtZXRob2RzIGFyZSBkZWZpbmVkOiBYTUwsIEhUTUwsIGFuZCBURVhULgotICogVGhlc2UgY29uc3RhbnRzIGNhbiBiZSB1c2VkIGFzIGFuIGFyZ3VtZW50IHRvIHRoZQotICogT3V0cHV0UHJvcGVydGllc0ZhY3RvcnkuZ2V0RGVmYXVsdE1ldGhvZFByb3BlcnRpZXMoKSBtZXRob2QgdG8gZ2V0Ci0gKiB0aGUgcHJvcGVydGllcyB0byBjcmVhdGUgYSBzZXJpYWxpemVyLgotICoKLSAqIFRoaXMgY2xhc3MgaXMgYSBwdWJsaWMgQVBJLgotICoKLSAqIEBzZWUgT3V0cHV0UHJvcGVydGllc0ZhY3RvcnkKLSAqIEBzZWUgU2VyaWFsaXplcgotICoKLSAqIEB4c2wudXNhZ2UgZ2VuZXJhbAotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgTWV0aG9kCi17Ci0gICAgLyoqCi0gICAgICogQSBwcml2YXRlIGNvbnN0cnVjdG9yIHRvIHByZXZlbnQgdGhlIGNyZWF0aW9uIG9mIHN1Y2ggYSBjbGFzcy4KLSAgICAgKi8KLSAgICBwcml2YXRlIE1ldGhvZCgpIHsKLQotICAgIH0KLQotICAvKioKLSAgICogVGhlIG91dHB1dCBtZXRob2QgdHlwZSBmb3IgWE1MIGRvY3VtZW50czogPHR0PnhtbDwvdHQ+LgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MID0gInhtbCI7Ci0KLSAgLyoqCi0gICAqIFRoZSBvdXRwdXQgbWV0aG9kIHR5cGUgZm9yIEhUTUwgZG9jdW1lbnRzOiA8dHQ+aHRtbDwvdHQ+LgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSFRNTCA9ICJodG1sIjsKLQotICAvKioKLSAgICogVGhlIG91dHB1dCBtZXRob2QgZm9yIFhIVE1MIGRvY3VtZW50cywKLSAgICogdGhpcyBtZXRob2QgdHlwZSBpcyBub3QgY3VycmVudGx5IHN1cHBvcnRlZDogPHR0PnhodG1sPC90dD4uCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBYSFRNTCA9ICJ4aHRtbCI7Ci0KLSAgLyoqCi0gICAqIFRoZSBvdXRwdXQgbWV0aG9kIHR5cGUgZm9yIHRleHQgZG9jdW1lbnRzOiA8dHQ+dGV4dDwvdHQ+LgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgVEVYVCA9ICJ0ZXh0IjsKLQotICAvKioKLSAgICogVGhlICJpbnRlcm5hbCIgbWV0aG9kLCBqdXN0IHVzZWQgd2hlbiBubyBtZXRob2QgaXMKLSAgICogc3BlY2lmaWVkIGluIHRoZSBzdHlsZSBzaGVldCwgYW5kIGEgc2VyaWFsaXplciBvZiB0aGlzIHR5cGUgd3JhcHMgZWl0aGVyIGFuCi0gICAqIFhNTCBvciBIVE1MIHR5cGUgKGRlcGVuZGluZyBvbiB0aGUgZmlyc3QgdGFnIGluIHRoZSBvdXRwdXQgYmVpbmcgaHRtbCBvcgotICAgKiBub3QpCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBVTktOT1dOID0gIiI7Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL05hbWVzcGFjZU1hcHBpbmdzLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL05hbWVzcGFjZU1hcHBpbmdzLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDVkZjgzYzEuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9OYW1lc3BhY2VNYXBwaW5ncy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzI3ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDMtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IE5hbWVzcGFjZU1hcHBpbmdzLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTUgMDg6MTU6MTkgc3VyZXNoX2VtYWlsaWQgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXI7Ci0KLWltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKLWltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7Ci1pbXBvcnQgamF2YS51dGlsLlN0YWNrOwotCi1pbXBvcnQgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotCi0vKioKLSAqIFRoaXMgY2xhc3Mga2VlcHMgdHJhY2sgb2YgdGhlIGN1cnJlbnRseSBkZWZpbmVkIG5hbWVzcGFjZXMuIENvbmNlcHR1YWxseSB0aGUKLSAqIHByZWZpeC91cmkvZGVwdGggdHJpcGxldHMgYXJlIHB1c2hlZCBvbiBhIHN0YWNrIHB1c2hlZCBvbiBhIHN0YWNrLiBUaGUgZGVwdGgKLSAqIGluZGljYXRlcyB0aGUgbmVzdGluZyBkZXB0aCBvZiB0aGUgZWxlbWVudCBmb3Igd2hpY2ggdGhlIG1hcHBpbmcgd2FzIG1hZGUuCi0gKgotICogPHA+Rm9yIGV4YW1wbGU6Ci0gKiA8cHJlPgotICogPGNoYXB0ZXIgeG1sbnM6cDE9ImRlZiI+Ci0gKiAgIDxwYXJhZ3JhcGggeG1sbnM6cDI9ImdoaSI+Ci0gKiAgICAgIDxzZW50YW5jZSB4bWxuczpwMz0iamtsIj4KLSAqICAgICAgPC9zZW50YW5jZT4KLSAqICAgIDwvcGFyYWdyYXBoPgotICogICAgPHBhcmFncmFwaCB4bG1uczpwND0ibW5vIj4KLSAqICAgIDwvcGFyYWdyYXBoPgotICogPC9jaGFwdGVyPgotICogPC9wcmU+Ci0gKgotICogV2hlbiB0aGUgPGNoYXB0ZXI+IGVsZW1lbnQgaXMgZW5jb3VudGVkIHRoZSBwcmVmaXggInAxIiBhc3NvY2lhdGVkIHdpdGggdXJpCi0gKiAiZGVmIiBpcyBwdXNoZWQgb24gdGhlIHN0YWNrIHdpdGggZGVwdGggMS4KLSAqIFdoZW4gdGhlIGZpcnN0IDxwYXJhZ3JhcGg+IGlzIGVuY291bnRlcmVkICJwMiIgYW5kICJnaGkiIGFyZSBwdXNoZWQgd2l0aAotICogZGVwdGggMi4KLSAqIFdoZW4gdGhlIDxzZW50YW5jZT4gaXMgZW5jb3VudGVyZWQgInAzIiBhbmQgImprbCIgYXJlIHB1c2hlZCB3aXRoIGRlcHRoIDMuCi0gKiBXaGVuIDwvc2VudGFuY2U+IG9jY3VycyB0aGUgcG9wTmFtZXNwYWNlcygzKSB3aWxsIHBvcCAicDMiLyJqa2wiIG9mZiB0aGUKLSAqIHN0YWNrLiAgT2YgY291cnNlIHBvcE5hbWVzcGFjZXMoMikgd291bGQgcG9wIGFueXRoaW5nIHdpdGggZGVwdGggMiBvcgotICogZ3JlYXRlci4KLSAqCi0gKiBTbyBwcmVmaXgvdXJpIHBhaXJzIGFyZSBwdXNoZWQgYW5kIHBvcGVkIG9mZiB0aGUgc3RhY2sgYXMgZWxlbWVudHMgYXJlCi0gKiBwcm9jZXNzZWQuICBBdCBhbnkgZ2l2ZW4gbW9tZW50IG9mIHByb2Nlc3NpbmcgdGhlIGN1cnJlbnRseSB2aXNpYmxlIHByZWZpeGVzCi0gKiBhcmUgb24gdGhlIHN0YWNrIGFuZCBhIHByZWZpeCBjYW4gYmUgZm91bmQgZ2l2ZW4gYSB1cmksIG9yIGEgdXJpIGNhbiBiZSBmb3VuZAotICogZ2l2ZW4gYSBwcmVmaXguCi0gKgotICogVGhpcyBjbGFzcyBpcyBwdWJsaWMgb25seSBiZWNhdXNlIGl0IGlzIHVzZWQgYnkgWGFsYW4uIEl0IGlzIG5vdCBhIHB1YmxpYyBBUEkKLSAqCi0gKiBAeHNsLnVzYWdlIGludGVybmFsCi0gKi8KLXB1YmxpYyBjbGFzcyBOYW1lc3BhY2VNYXBwaW5ncwotewotICAgIC8qKgotICAgICAqIFRoaXMgbWVtYmVyIGlzIGNvbnRpbnVhbGx5IGluY3JlbWVudGVkIHdoZW4gbmV3IHByZWZpeGVzIG5lZWQgdG8gYmUKLSAgICAgKiBnZW5lcmF0ZWQuICgibnMwIiAgIm5zMSIgLi4uKQotICAgICAqLwotICAgIHByaXZhdGUgaW50IGNvdW50OwotCi0gICAgLyoqCi0gICAgICogRWFjaCBlbnRyeSAocHJlZml4KSBpbiB0aGlzIGhhc2htYXAgcG9pbnRzIHRvIGEgU3RhY2sgb2YgVVJJcwotICAgICAqIFRoaXMgbWFwcyBhIHByZWZpeCAoU3RyaW5nKSB0byBhIFN0YWNrIG9mIHByZWZpeCBtYXBwaW5ncy4KLSAgICAgKiBBbGwgbWFwcGluZ3MgaW4gdGhhdCByZXRyaWV2ZWQgc3RhY2sgaGF2ZSB0aGUgc2FtZSBwcmVmaXgsCi0gICAgICogdGhvdWdoIHBvc3NpYmx5IGRpZmZlcmVudCBVUkkncyBvciBkZXB0aHMuIFN1Y2ggYSBzdGFjayBtdXN0IGhhdmUKLSAgICAgKiBtYXBwaW5ncyBhdCBkZWVwZXIgZGVwdGhzIHB1c2ggbGF0ZXIgb24gc3VjaCBhIHN0YWNrLiAgTWFwcGluZ3MgcHVzaGVkCi0gICAgICogZWFybGllciBvbiB0aGUgc3RhY2sgd2lsbCBoYXZlIHNtYWxsZXIgdmFsdWVzIGZvciBNYXBwaW5nUmVjb3JkLm1fZGVjbGFyYXRpb25EZXB0aC4KLSAgICAgKi8KLSAgICBwcml2YXRlIEhhc2hNYXAgbV9uYW1lc3BhY2VzID0gbmV3IEhhc2hNYXAoKTsKLQotICAgIC8qKgotICAgICAqIFRoZSB0b3Agb2YgdGhpcyBzdGFjayBjb250YWlucyB0aGUgTWFwUmVjb3JkCi0gICAgICogb2YgdGhlIGxhc3QgZGVjbGFyZWQgYSBuYW1lc3BhY2UuCi0gICAgICogVXNlZCB0byBrbm93IGhvdyBtYW55IHByZWZpeCBtYXBwaW5ncyB0byBwb3Agd2hlbiBsZWF2aW5nCi0gICAgICogdGhlIGN1cnJlbnQgZWxlbWVudCBkZXB0aC4KLSAgICAgKiBGb3IgZXZlcnkgcHJlZml4IG1hcHBpbmcgdGhlIGN1cnJlbnQgZWxlbWVudCBkZXB0aCBpcwotICAgICAqIHB1c2hlZCBvbiB0aGlzIHN0YWNrLgotICAgICAqIFRoYXQgd2F5IGFsbCBwcmVmaXhlcyBwdXNoZWQgYXQgdGhlIGN1cnJlbnQgZGVwdGggY2FuIGJlCi0gICAgICogcmVtb3ZlZCBhdCB0aGUgc2FtZSB0aW1lLgotICAgICAqIFVzZWQgdG8gZW5zdXJlIHByZWZpeC91cmkgbWFwIHNjb3BlcyBhcmUgY2xvc2VkIGNvcnJlY3RseQotICAgICAqCi0gICAgICovCi0gICAgcHJpdmF0ZSBTdGFjayBtX25vZGVTdGFjayA9IG5ldyBTdGFjaygpOwotCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEVNUFRZU1RSSU5HID0gIiI7Ci0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFhNTF9QUkVGSVggPSAieG1sIjsgLy8gd2FzICJ4bWxucyIKLQotICAgIC8qKgotICAgICAqIERlZmF1bHQgY29uc3RydWN0b3IKLSAgICAgKiBAc2VlIGphdmEubGFuZy5PYmplY3QjT2JqZWN0KCkKLSAgICAgKi8KLSAgICBwdWJsaWMgTmFtZXNwYWNlTWFwcGluZ3MoKQotICAgIHsKLSAgICAgICAgaW5pdE5hbWVzcGFjZXMoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBpbml0aWFsaXplcyB0aGUgbmFtZXNwYWNlIG9iamVjdCB3aXRoIGFwcHJvcHJpYXRlIHN0YWNrcwotICAgICAqIGFuZCBwcmVkZWZpbmVzIGEgZmV3IHByZWZpeC91cmkgcGFpcnMgd2hpY2ggYWx3YXlzIGV4aXN0LgotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCBpbml0TmFtZXNwYWNlcygpCi0gICAgewotCi0KLSAgICAgICAgLy8gRGVmaW5lIHRoZSBkZWZhdWx0IG5hbWVzcGFjZSAoaW5pdGlhbGx5IG1hcHMgdG8gIiIgdXJpKQotICAgICAgICBTdGFjayBzdGFjazsKLSAgICAgICAgbV9uYW1lc3BhY2VzLnB1dChFTVBUWVNUUklORywgc3RhY2sgPSBuZXcgU3RhY2soKSk7Ci0gICAgICAgIHN0YWNrLnB1c2gobmV3IE1hcHBpbmdSZWNvcmQoRU1QVFlTVFJJTkcsRU1QVFlTVFJJTkcsMCkpOwotCi0gICAgICAgIG1fbmFtZXNwYWNlcy5wdXQoWE1MX1BSRUZJWCwgc3RhY2sgPSBuZXcgU3RhY2soKSk7Ci0gICAgICAgIHN0YWNrLnB1c2gobmV3IE1hcHBpbmdSZWNvcmQoIFhNTF9QUkVGSVgsCi0gICAgICAgICAgICAiaHR0cDovL3d3dy53My5vcmcvWE1MLzE5OTgvbmFtZXNwYWNlIiwwKSk7Ci0KLSAgICAgICAgbV9ub2RlU3RhY2sucHVzaChuZXcgTWFwcGluZ1JlY29yZChudWxsLG51bGwsLTEpKTsKLQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFVzZSBhIG5hbWVzcGFjZSBwcmVmaXggdG8gbG9va3VwIGEgbmFtZXNwYWNlIFVSSS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBwcmVmaXggU3RyaW5nIHRoZSBwcmVmaXggb2YgdGhlIG5hbWVzcGFjZQotICAgICAqIEByZXR1cm4gdGhlIFVSSSBjb3JyZXNwb25kaW5nIHRvIHRoZSBwcmVmaXgKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGxvb2t1cE5hbWVzcGFjZShTdHJpbmcgcHJlZml4KQotICAgIHsKLSAgICAgICAgZmluYWwgU3RhY2sgc3RhY2sgPSAoU3RhY2spIG1fbmFtZXNwYWNlcy5nZXQocHJlZml4KTsKLSAgICAgICAgcmV0dXJuIHN0YWNrICE9IG51bGwgJiYgIXN0YWNrLmlzRW1wdHkoKSA/Ci0gICAgICAgICAgICAoKE1hcHBpbmdSZWNvcmQpIHN0YWNrLnBlZWsoKSkubV91cmkgOiBudWxsOwotICAgIH0KLQotICAgIE1hcHBpbmdSZWNvcmQgZ2V0TWFwcGluZ0Zyb21QcmVmaXgoU3RyaW5nIHByZWZpeCkgewotICAgICAgICBmaW5hbCBTdGFjayBzdGFjayA9IChTdGFjaykgbV9uYW1lc3BhY2VzLmdldChwcmVmaXgpOwotICAgICAgICByZXR1cm4gc3RhY2sgIT0gbnVsbCAmJiAhc3RhY2suaXNFbXB0eSgpID8KLSAgICAgICAgICAgICgoTWFwcGluZ1JlY29yZCkgc3RhY2sucGVlaygpKSA6IG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2l2ZW4gYSBuYW1lc3BhY2UgdXJpLCBhbmQgdGhlIG5hbWVzcGFjZXMgbWFwcGluZ3MgZm9yIHRoZQotICAgICAqIGN1cnJlbnQgZWxlbWVudCwgcmV0dXJuIHRoZSBjdXJyZW50IHByZWZpeCBmb3IgdGhhdCB1cmkuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdXJpIHRoZSBuYW1lc3BhY2UgVVJJIHRvIGJlIHNlYXJjaCBmb3IKLSAgICAgKiBAcmV0dXJuIGFuIGV4aXN0aW5nIHByZWZpeCB0aGF0IG1hcHMgdG8gdGhlIGdpdmVuIFVSSSwgbnVsbCBpZiBubyBwcmVmaXgKLSAgICAgKiBtYXBzIHRvIHRoZSBnaXZlbiBuYW1lc3BhY2UgVVJJLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgbG9va3VwUHJlZml4KFN0cmluZyB1cmkpCi0gICAgewotICAgICAgICBTdHJpbmcgZm91bmRQcmVmaXggPSBudWxsOwotICAgICAgICBJdGVyYXRvcjxTdHJpbmc+IGl0ciA9IG1fbmFtZXNwYWNlcy5rZXlTZXQoKS5pdGVyYXRvcigpOwotICAgICAgICB3aGlsZSAoaXRyLmhhc05leHQoKSkgewotICAgICAgICAgICAgU3RyaW5nIHByZWZpeCA9IGl0ci5uZXh0KCk7Ci0gICAgICAgICAgICBTdHJpbmcgdXJpMiA9IGxvb2t1cE5hbWVzcGFjZShwcmVmaXgpOwotICAgICAgICAgICAgaWYgKHVyaTIgIT0gbnVsbCAmJiB1cmkyLmVxdWFscyh1cmkpKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIGZvdW5kUHJlZml4ID0gcHJlZml4OwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmb3VuZFByZWZpeDsKLSAgICB9Ci0KLSAgICBNYXBwaW5nUmVjb3JkIGdldE1hcHBpbmdGcm9tVVJJKFN0cmluZyB1cmkpCi0gICAgewotICAgICAgICBNYXBwaW5nUmVjb3JkIGZvdW5kTWFwID0gbnVsbDsKLSAgICAgICAgSXRlcmF0b3I8U3RyaW5nPiBpdHIgPSBtX25hbWVzcGFjZXMua2V5U2V0KCkuaXRlcmF0b3IoKTsKLSAgICAgICAgd2hpbGUgKGl0ci5oYXNOZXh0KCkpCi0gICAgICAgIHsKLSAgICAgICAgICAgIFN0cmluZyBwcmVmaXggPSBpdHIubmV4dCgpOwotICAgICAgICAgICAgTWFwcGluZ1JlY29yZCBtYXAyID0gZ2V0TWFwcGluZ0Zyb21QcmVmaXgocHJlZml4KTsKLSAgICAgICAgICAgIGlmIChtYXAyICE9IG51bGwgJiYgKG1hcDIubV91cmkpLmVxdWFscyh1cmkpKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIGZvdW5kTWFwID0gbWFwMjsKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZm91bmRNYXA7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVW5kZWNsYXJlIHRoZSBuYW1lc3BhY2UgdGhhdCBpcyBjdXJyZW50bHkgcG9pbnRlZCB0byBieSBhIGdpdmVuIHByZWZpeAotICAgICAqLwotICAgIGJvb2xlYW4gcG9wTmFtZXNwYWNlKFN0cmluZyBwcmVmaXgpCi0gICAgewotICAgICAgICAvLyBQcmVmaXhlcyAieG1sIiBhbmQgInhtbG5zIiBjYW5ub3QgYmUgcmVkZWZpbmVkCi0gICAgICAgIGlmIChwcmVmaXguc3RhcnRzV2l0aChYTUxfUFJFRklYKSkKLSAgICAgICAgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0KLSAgICAgICAgU3RhY2sgc3RhY2s7Ci0gICAgICAgIGlmICgoc3RhY2sgPSAoU3RhY2spIG1fbmFtZXNwYWNlcy5nZXQocHJlZml4KSkgIT0gbnVsbCkKLSAgICAgICAgewotICAgICAgICAgICAgc3RhY2sucG9wKCk7Ci0gICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRGVjbGFyZSBhIG1hcHBpbmcgb2YgYSBwcmVmaXggdG8gbmFtZXNwYWNlIFVSSSBhdCB0aGUgZ2l2ZW4gZWxlbWVudCBkZXB0aC4KLSAgICAgKiBAcGFyYW0gcHJlZml4IGEgU3RyaW5nIHdpdGggdGhlIHByZWZpeCBmb3IgYSBxdWFsaWZpZWQgbmFtZQotICAgICAqIEBwYXJhbSB1cmkgYSBTdHJpbmcgd2l0aCB0aGUgdXJpIHRvIHdoaWNoIHRoZSBwcmVmaXggaXMgdG8gbWFwCi0gICAgICogQHBhcmFtIGVsZW1EZXB0aCB0aGUgZGVwdGggb2YgY3VycmVudCBkZWNsYXJhdGlvbgotICAgICAqLwotICAgIGJvb2xlYW4gcHVzaE5hbWVzcGFjZShTdHJpbmcgcHJlZml4LCBTdHJpbmcgdXJpLCBpbnQgZWxlbURlcHRoKQotICAgIHsKLSAgICAgICAgLy8gUHJlZml4ZXMgInhtbCIgYW5kICJ4bWxucyIgY2Fubm90IGJlIHJlZGVmaW5lZAotICAgICAgICBpZiAocHJlZml4LnN0YXJ0c1dpdGgoWE1MX1BSRUZJWCkpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotCi0gICAgICAgIFN0YWNrIHN0YWNrOwotICAgICAgICAvLyBHZXQgdGhlIHN0YWNrIHRoYXQgY29udGFpbnMgVVJJcyBmb3IgdGhlIHNwZWNpZmllZCBwcmVmaXgKLSAgICAgICAgaWYgKChzdGFjayA9IChTdGFjaykgbV9uYW1lc3BhY2VzLmdldChwcmVmaXgpKSA9PSBudWxsKQotICAgICAgICB7Ci0gICAgICAgICAgICBtX25hbWVzcGFjZXMucHV0KHByZWZpeCwgc3RhY2sgPSBuZXcgU3RhY2soKSk7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoIXN0YWNrLmVtcHR5KCkgJiYgdXJpLmVxdWFscygoKE1hcHBpbmdSZWNvcmQpc3RhY2sucGVlaygpKS5tX3VyaSkpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotICAgICAgICBNYXBwaW5nUmVjb3JkIG1hcCA9IG5ldyBNYXBwaW5nUmVjb3JkKHByZWZpeCx1cmksZWxlbURlcHRoKTsKLSAgICAgICAgc3RhY2sucHVzaChtYXApOwotICAgICAgICBtX25vZGVTdGFjay5wdXNoKG1hcCk7Ci0gICAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFBvcCwgb3IgdW5kZWNsYXJlIGFsbCBuYW1lc3BhY2UgZGVmaW5pdGlvbnMgdGhhdCBhcmUgY3VycmVudGx5Ci0gICAgICogZGVjbGFyZWQgYXQgdGhlIGdpdmVuIGVsZW1lbnQgZGVwdGgsIG9yIGRlZXB0ZXIuCi0gICAgICogQHBhcmFtIGVsZW1EZXB0aCB0aGUgZWxlbWVudCBkZXB0aCBmb3Igd2hpY2ggbWFwcGluZ3MgZGVjbGFyZWQgYXQgdGhpcwotICAgICAqIGRlcHRoIG9yIGRlZXBlciB3aWxsIG5vIGxvbmdlciBiZSB2YWxpZAotICAgICAqIEBwYXJhbSBzYXhIYW5kbGVyIFRoZSBDb250ZW50SGFuZGxlciB0byBub3RpZnkgb2YgYW55IGVuZFByZWZpeE1hcHBpbmcoKQotICAgICAqIGNhbGxzLiAgVGhpcyBwYXJhbWV0ZXIgY2FuIGJlIG51bGwuCi0gICAgICovCi0gICAgdm9pZCBwb3BOYW1lc3BhY2VzKGludCBlbGVtRGVwdGgsIENvbnRlbnRIYW5kbGVyIHNheEhhbmRsZXIpCi0gICAgewotICAgICAgICB3aGlsZSAodHJ1ZSkKLSAgICAgICAgewotICAgICAgICAgICAgaWYgKG1fbm9kZVN0YWNrLmlzRW1wdHkoKSkKLSAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICBNYXBwaW5nUmVjb3JkIG1hcCA9IChNYXBwaW5nUmVjb3JkKShtX25vZGVTdGFjay5wZWVrKCkpOwotICAgICAgICAgICAgaW50IGRlcHRoID0gbWFwLm1fZGVjbGFyYXRpb25EZXB0aDsKLSAgICAgICAgICAgIGlmIChkZXB0aCA8IGVsZW1EZXB0aCkKLSAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICAvKiB0aGUgZGVwdGggb2YgdGhlIGRlY2xhcmVkIG1hcHBpbmcgaXMgZWxlbURlcHRoIG9yIGRlZXBlcgotICAgICAgICAgICAgICogc28gZ2V0IHJpZCBvZiBpdAotICAgICAgICAgICAgICovCi0KLSAgICAgICAgICAgIG1hcCA9IChNYXBwaW5nUmVjb3JkKSBtX25vZGVTdGFjay5wb3AoKTsKLSAgICAgICAgICAgIGZpbmFsIFN0cmluZyBwcmVmaXggPSBtYXAubV9wcmVmaXg7Ci0gICAgICAgICAgICBwb3BOYW1lc3BhY2UocHJlZml4KTsKLSAgICAgICAgICAgIGlmIChzYXhIYW5kbGVyICE9IG51bGwpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgdHJ5Ci0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICBzYXhIYW5kbGVyLmVuZFByZWZpeE1hcHBpbmcocHJlZml4KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gbm90IG11Y2ggd2UgY2FuIGRvIGlmIHRoZXkgYXJlbid0IHdpbGxpbmcgdG8gbGlzdGVuCi0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZW5lcmF0ZSBhIG5ldyBuYW1lc3BhY2UgcHJlZml4ICggbnMwLCBuczEgLi4uKSBub3QgdXNlZCBiZWZvcmUKLSAgICAgKiBAcmV0dXJuIFN0cmluZyBhIG5ldyBuYW1lc3BhY2UgcHJlZml4ICggbnMwLCBuczEsIG5zMiAuLi4pCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZW5lcmF0ZU5leHRQcmVmaXgoKQotICAgIHsKLSAgICAgICAgcmV0dXJuICJucyIgKyAoY291bnQrKyk7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBtYWtlcyBhIGNsb25lIG9mIHRoaXMgb2JqZWN0LgotICAgICAqCi0gICAgICovCi0gICAgcHVibGljIE9iamVjdCBjbG9uZSgpIHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiB7Ci0gICAgICAgIE5hbWVzcGFjZU1hcHBpbmdzIGNsb25lID0gbmV3IE5hbWVzcGFjZU1hcHBpbmdzKCk7Ci0gICAgICAgIGNsb25lLm1fbm9kZVN0YWNrID0gKFN0YWNrKSBtX25vZGVTdGFjay5jbG9uZSgpOwotICAgICAgICBjbG9uZS5tX25hbWVzcGFjZXMgPSAoSGFzaE1hcCkgbV9uYW1lc3BhY2VzLmNsb25lKCk7Ci0gICAgICAgIGNsb25lLmNvdW50ID0gY291bnQ7Ci0gICAgICAgIHJldHVybiBjbG9uZTsKLQotICAgIH0KLQotICAgIGZpbmFsIHZvaWQgcmVzZXQoKQotICAgIHsKLSAgICAgICAgdGhpcy5jb3VudCA9IDA7Ci0gICAgICAgIHRoaXMubV9uYW1lc3BhY2VzLmNsZWFyKCk7Ci0gICAgICAgIHRoaXMubV9ub2RlU3RhY2suY2xlYXIoKTsKLSAgICAgICAgaW5pdE5hbWVzcGFjZXMoKTsKLSAgICB9Ci0KLSAgICBjbGFzcyBNYXBwaW5nUmVjb3JkIHsKLSAgICAgICAgZmluYWwgU3RyaW5nIG1fcHJlZml4OyAgLy8gdGhlIHByZWZpeAotICAgICAgICBmaW5hbCBTdHJpbmcgbV91cmk7ICAgICAvLyB0aGUgdXJpCi0gICAgICAgIC8vIHRoZSBkZXB0aCBvZiB0aGUgZWxlbWVudCB3aGVyZSBkZWNsYXJ0aW9uIHdhcyBtYWRlCi0gICAgICAgIGZpbmFsIGludCBtX2RlY2xhcmF0aW9uRGVwdGg7Ci0gICAgICAgIE1hcHBpbmdSZWNvcmQoU3RyaW5nIHByZWZpeCwgU3RyaW5nIHVyaSwgaW50IGRlcHRoKSB7Ci0gICAgICAgICAgICBtX3ByZWZpeCA9IHByZWZpeDsKLSAgICAgICAgICAgIG1fdXJpID0gdXJpOwotICAgICAgICAgICAgbV9kZWNsYXJhdGlvbkRlcHRoID0gZGVwdGg7Ci0KLSAgICAgICAgfQotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9PdXRwdXRQcm9wZXJ0aWVzRmFjdG9yeS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9PdXRwdXRQcm9wZXJ0aWVzRmFjdG9yeS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwZDkxYjdhLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvT3V0cHV0UHJvcGVydGllc0ZhY3RvcnkuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDUzOSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBPdXRwdXRQcm9wZXJ0aWVzRmFjdG9yeS5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE1IDA4OjE1OjIxIHN1cmVzaF9lbWFpbGlkIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnV0aWxzLlNlY3VyaXR5U3VwcG9ydDsKLWltcG9ydCBqYXZhLmlvLkJ1ZmZlcmVkSW5wdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOwotaW1wb3J0IGphdmEuc2VjdXJpdHkuQWNjZXNzQ29udHJvbGxlcjsKLWltcG9ydCBqYXZhLnNlY3VyaXR5LlByaXZpbGVnZWRBY3Rpb247Ci1pbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOwotaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0aWVzOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5PdXRwdXRLZXlzOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyLnV0aWxzLk1zZ0tleTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXIudXRpbHMuVXRpbHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyLnV0aWxzLldyYXBwZWRSdW50aW1lRXhjZXB0aW9uOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgaXMgYSBmYWN0b3J5IHRvIGdlbmVyYXRlIGEgc2V0IG9mIGRlZmF1bHQgcHJvcGVydGllcwotICogb2Yga2V5L3ZhbHVlIHBhaXJzIHRoYXQgYXJlIHVzZWQgdG8gY3JlYXRlIGEgc2VyaWFsaXplciB0aHJvdWdoIHRoZQotICogZmFjdG9yeSB7QGxpbmsgU2VyaWFsaXplckZhY3RvcnkgU2VyaWxpemVyRmFjdG9yeX0uCi0gKiBUaGUgcHJvcGVydGllcyBnZW5lcmF0ZWQgYnkgdGhpcyBmYWN0b3J5Ci0gKiBtYXkgYmUgbW9kaWZpZWQgdG8gbm9uLWRlZmF1bHQgdmFsdWVzIGJlZm9yZSB0aGUgU2VyaWFsaXplckZhY3RvcnkgaXMgdXNlZCB0bwotICogY3JlYXRlIGEgU2VyaWFsaXplci4KLSAqIDxwPgotICogVGhlIGdpdmVuIG91dHB1dCB0eXBlcyBzdXBwb3J0ZWQgYXJlICJ4bWwiLCAidGV4dCIsIGFuZCAiaHRtbCIuCi0gKiBUaGVzZSB0eXBlIHN0cmluZ3MgY2FuIGJlIG9idGFpbmVkIGZyb20gdGhlCi0gKiB7QGxpbmsgTWV0aG9kIE1ldGhvZH0gY2xhc3MgaW4gdGhpcyBwYWNrYWdlLgotICogPHA+Ci0gKiBPdGhlciBjb25zdGFudHMgZGVmaW5lZCBpbiB0aGlzIGNsYXNzIGFyZSB0aGUgbm9uLXN0YW5kYXJkIHByb3BlcnR5IGtleXMKLSAqIHRoYXQgY2FuIGJlIHVzZWQgdG8gc2V0IG5vbi1zdGFuZGFyZCBwcm9wZXJ0eSB2YWx1ZXMgb24gYSBqYXZhLnV0aWwuUHJvcGVydGllcyBvYmplY3QKLSAqIHRoYXQgaXMgdXNlZCB0byBjcmVhdGUgb3IgY29uZmlndXJlIGEgc2VyaWFsaXplci4gSGVyZSBhcmUgdGhlIG5vbi1zdGFuZGFyZCBrZXlzOgotICogPHVsPgotICogPGxpPiA8Yj5TX0tFWV9JTkRFTlRfQU1PVU5UIDwvYj4gLQotICogVGhlIG5vbi1zdGFuZGFyZCBwcm9wZXJ0eSBrZXkgdG8gdXNlIHRvIHNldCB0aGUgaW5kZW50YXRpb24gYW1vdW50LgotICogVGhlICJpbmRlbnQiIGtleSBuZWVkcyB0byBoYXZlIGEgdmFsdWUgb2YgInllcyIsIGFuZCB0aGlzCi0gKiBwcm9wZXJ0aWVzIHZhbHVlIGlzIGEgdGhlIG51bWJlciBvZiB3aGl0ZXNwYWNlcyB0byBpbmRlbnQgYnkgcGVyCi0gKiBpbmRlbnRhdGlvbiBsZXZlbC4KLSAqCi0gKiA8bGk+IDxiPlNfS0VZX0NPTlRFTlRfSEFORExFUiA8L2I+IC0KLSAqIFRoaXMgbm9uLXN0YW5kYXJkIHByb3BlcnR5IGtleSBpcyB1c2VkIHRvIHNldCB0aGUgbmFtZSBvZiB0aGUgZnVsbHkgcXVhbGlmaWVkCi0gKiBKYXZhIGNsYXNzIHRoYXQgaW1wbGVtZW50cyB0aGUgQ29udGVudEhhbmRsZXIgaW50ZXJmYWNlLgotICogVGhlIG91dHB1dCBvZiB0aGUgc2VyaWFsaXplciB3aWxsIGJlIFNBWCBldmVudHMgc2VudCB0byB0aGlzIGFuCi0gKiBvYmplY3Qgb2YgdGhpcyBjbGFzcy4KLSAqCi0gKiA8bGk+IDxiPlNfS0VZX0VOVElUSUVTIDwvYj4gLQotICogVGhpcyBub24tc3RhbmRhcmQgcHJvcGVydHkga2V5IGlzIHVzZWQgdG8gc3BlY2lmeSB0aGUgbmFtZSBvZiB0aGUgcHJvcGVydHkgZmlsZQotICogdGhhdCBzcGVjaWZpZXMgY2hhcmFjdGVyIHRvIGVudGl0eSByZWZlcmVuY2UgbWFwcGluZ3MuIEEgbGluZSBpbiBzdWNoIGEKLSAqIGZpbGUgaXMgaGFzIHRoZSBuYW1lIG9mIHRoZSBlbnRpdHkgYW5kIHRoZSBudW1lcmljIChiYXNlIDEwKSB2YWx1ZQotICogb2YgdGhlIGNvcnJlc3BvbmRpbmcgY2hhcmFjdGVyLCBsaWtlIHRoaXMgb25lOiA8YnI+IHF1b3Q9MzQgPGJyPgotICoKLSAqIDxsaT4gPGI+U19VU0VfVVJMX0VTQ0FQSU5HIDwvYj4gLQotICogVGhpcyBub24tc3RhbmRhcmQgcHJvcGVydHkga2V5IGlzIHVzZWQgdG8gc2V0IGEgdmFsdWUgb2YgInllcyIgaWYgdGhlIGhyZWYgdmFsdWVzIGZvciBIVE1MIHNlcmlhbGl6YXRpb24gc2hvdWxkCi0gKiAgdXNlICV4eCBlc2NhcGluZy4KLSAqCi0gKiA8bGk+IDxiPlNfT01JVF9NRVRBX1RBRyA8L2I+IC0KLSAqIFRoaXMgbm9uLXN0YW5kYXJkIHByb3BlcnR5IGtleSBpcyB1c2VkIHRvIHNldCBhIHZhbHVlIG9mICJ5ZXMiIGlmIHRoZSBNRVRBIHRhZyBzaG91bGQgYmUgb21pdHRlZCB3aGVyZSBpdCB3b3VsZAotICogIG90aGVyd2lzZSBiZSBzdXBwbGllZC4KLSAqIDwvdWw+Ci0gKgotICogQHNlZSBTZXJpYWxpemVyRmFjdG9yeQotICogQHNlZSBNZXRob2QKLSAqIEBzZWUgU2VyaWFsaXplcgotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgT3V0cHV0UHJvcGVydGllc0ZhY3RvcnkKLXsKLSAgICAvKiogU19CVUlMVElOX0VYVEVOU0lPTlNfVVJMIGlzIGEgbW5lbW9uaWMgZm9yIHRoZSBYTUwgTmFtZXNwYWNlCi0gICAgICooaHR0cDovL3htbC5hcGFjaGUub3JnL3hhbGFuKSBwcmVkZWZpbmVkIHRvIHNpZ25pZnkgWGFsYW4ncwotICAgICAqIGJ1aWx0LWluIFhTTFQgRXh0ZW5zaW9ucy4gV2hlbiB1c2VkIGluIHN0eWxlc2hlZXRzLCB0aGlzIGlzIG9mdGVuCi0gICAgICogYm91bmQgdG8gdGhlICJ4YWxhbjoiIHByZWZpeC4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcKLSAgICAgIFNfQlVJTFRJTl9FWFRFTlNJT05TX1VSTCA9ICJodHRwOi8veG1sLmFwYWNoZS5vcmcveGFsYW4iOwotCi0gICAgLyoqCi0gICAgICogVGhlIG9sZCBidWlsdC1pbiBleHRlbnNpb24gdXJsLiBJdCBpcyBzdGlsbCBzdXBwb3J0ZWQgZm9yCi0gICAgICogYmFja3dhcmQgY29tcGF0aWJpbGl0eS4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcKLSAgICAgIFNfQlVJTFRJTl9PTERfRVhURU5TSU9OU19VUkwgPSAiaHR0cDovL3htbC5hcGFjaGUub3JnL3hzbHQiOwotCi0gICAgLy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLSAgICAvLyogIFBVQkxJQyBDT05TVEFOVFMKLSAgICAvLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgotICAgIC8qKgotICAgICAqIFRoaXMgaXMgbm90IGEgcHVibGljIEFQSS4KLSAgICAgKiBUaGlzIGlzIHRoZSBidWlsdC1pbiBleHRlbnNpb25zIG5hbWVzcGFjZSwKLSAgICAgKiByZWV4cHJlc3NlZCBpbiB7bmFtZXNwYWNlVVJJfSBzeW50YXgKLSAgICAgKiBzdWl0YWJsZSBmb3IgcHJlcGVuZGluZyB0byBhIGxvY2FsbmFtZSB0byBwcm9kdWNlIGEgInVuaXZlcnNhbAotICAgICAqIG5hbWUiLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFNfQlVJTFRJTl9FWFRFTlNJT05TX1VOSVZFUlNBTCA9Ci0gICAgICAgICJ7IiArIFNfQlVJTFRJTl9FWFRFTlNJT05TX1VSTCArICJ9IjsKLQotICAgIC8vIFNvbWUgc3BlY2lhbCBYYWxhbiBrZXlzLgotCi0gICAgLyoqCi0gICAgICogVGhlIG5vbi1zdGFuZGFyZCBwcm9wZXJ0eSBrZXkgdG8gdXNlIHRvIHNldCB0aGUKLSAgICAgKiBudW1iZXIgb2Ygd2hpdGVwYWNlcyB0byBpbmRlbnQgYnksIHBlciBpbmRlbnRhdGlvbiBsZXZlbCwKLSAgICAgKiBpZiBpbmRlbnQ9InllcyIuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU19LRVlfSU5ERU5UX0FNT1VOVCA9Ci0gICAgICAgIFNfQlVJTFRJTl9FWFRFTlNJT05TX1VOSVZFUlNBTCArICJpbmRlbnQtYW1vdW50IjsKLQotICAgIC8qKgotICAgICAqIFRoZSBub24tc3RhbmRhcmQgcHJvcGVydHkga2V5IHRvIHVzZSB0byBzZXQgdGhlCi0gICAgICogbnVtYmVyIG9mIHdoaXRlcGFjZXMgdG8gaW5kZW50IGJ5LCBwZXIgaW5kZW50YXRpb24gbGV2ZWwsCi0gICAgICogaWYgaW5kZW50PSJ5ZXMiLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFNfS0VZX0xJTkVfU0VQQVJBVE9SID0KLSAgICAgICAgU19CVUlMVElOX0VYVEVOU0lPTlNfVU5JVkVSU0FMICsgImxpbmUtc2VwYXJhdG9yIjsKLQotICAgIC8qKiBUaGlzIG5vbi1zdGFuZGFyZCBwcm9wZXJ0eSBrZXkgaXMgdXNlZCB0byBzZXQgdGhlIG5hbWUgb2YgdGhlIGZ1bGx5IHF1YWxpZmllZAotICAgICAqIEphdmEgY2xhc3MgdGhhdCBpbXBsZW1lbnRzIHRoZSBDb250ZW50SGFuZGxlciBpbnRlcmZhY2UuCi0gICAgICogRnVsbHkgcXVhbGlmaWVkIG5hbWUgb2YgY2xhc3Mgd2l0aCBhIGRlZmF1bHQgY29uc3RydWN0b3IgdGhhdAotICAgICAqICBpbXBsZW1lbnRzIHRoZSBDb250ZW50SGFuZGxlciBpbnRlcmZhY2UsIHdoZXJlIHRoZSByZXN1bHQgdHJlZSBldmVudHMKLSAgICAgKiAgd2lsbCBiZSBzZW50IHRvLgotICAgICAqLwotCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU19LRVlfQ09OVEVOVF9IQU5ETEVSID0KLSAgICAgICAgU19CVUlMVElOX0VYVEVOU0lPTlNfVU5JVkVSU0FMICsgImNvbnRlbnQtaGFuZGxlciI7Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG5vbi1zdGFuZGFyZCBwcm9wZXJ0eSBrZXkgaXMgdXNlZCB0byBzcGVjaWZ5IHRoZSBuYW1lIG9mIHRoZSBwcm9wZXJ0eSBmaWxlCi0gICAgICogdGhhdCBzcGVjaWZpZXMgY2hhcmFjdGVyIHRvIGVudGl0eSByZWZlcmVuY2UgbWFwcGluZ3MuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU19LRVlfRU5USVRJRVMgPQotICAgICAgICBTX0JVSUxUSU5fRVhURU5TSU9OU19VTklWRVJTQUwgKyAiZW50aXRpZXMiOwotCi0gICAgLyoqCi0gICAgICogVGhpcyBub24tc3RhbmRhcmQgcHJvcGVydHkga2V5IGlzIHVzZWQgdG8gc2V0IGEgdmFsdWUgb2YgInllcyIgaWYgdGhlIGhyZWYgdmFsdWVzIGZvciBIVE1MIHNlcmlhbGl6YXRpb24gc2hvdWxkCi0gICAgICogIHVzZSAleHggZXNjYXBpbmcuICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU19VU0VfVVJMX0VTQ0FQSU5HID0KLSAgICAgICAgU19CVUlMVElOX0VYVEVOU0lPTlNfVU5JVkVSU0FMICsgInVzZS11cmwtZXNjYXBpbmciOwotCi0gICAgLyoqCi0gICAgICogVGhpcyBub24tc3RhbmRhcmQgcHJvcGVydHkga2V5IGlzIHVzZWQgdG8gc2V0IGEgdmFsdWUgb2YgInllcyIgaWYgdGhlIE1FVEEgdGFnIHNob3VsZCBiZSBvbWl0dGVkIHdoZXJlIGl0IHdvdWxkCi0gICAgICogIG90aGVyd2lzZSBiZSBzdXBwbGllZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBTX09NSVRfTUVUQV9UQUcgPQotICAgICAgICBTX0JVSUxUSU5fRVhURU5TSU9OU19VTklWRVJTQUwgKyAib21pdC1tZXRhLXRhZyI7Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgb2xkIGJ1aWx0LWluIGV4dGVuc2lvbiBuYW1lc3BhY2UsIHRoaXMgaXMgbm90IGEgcHVibGljIEFQSS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBTX0JVSUxUSU5fT0xEX0VYVEVOU0lPTlNfVU5JVkVSU0FMID0KLSAgICAgICAgInsiICsgU19CVUlMVElOX09MRF9FWFRFTlNJT05TX1VSTCArICJ9IjsKLQotICAgIC8qKgotICAgICAqIFRoaXMgaXMgbm90IGEgcHVibGljIEFQSSwgaXQgaXMgb25seSBwdWJsaWMgYmVjYXVzZSBpdCBpcyB1c2VkCi0gICAgICogYnkgb3V0c2lkZSBvZiB0aGlzIHBhY2thZ2UsCi0gICAgICogaXQgaXMgdGhlIGxlbmd0aCBvZiB0aGUgb2xkIGJ1aWx0LWluIGV4dGVuc2lvbiBuYW1lc3BhY2UuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU19CVUlMVElOX09MRF9FWFRFTlNJT05TX1VOSVZFUlNBTF9MRU4gPQotICAgICAgICBTX0JVSUxUSU5fT0xEX0VYVEVOU0lPTlNfVU5JVkVSU0FMLmxlbmd0aCgpOwotCi0gICAgLyoqCi0gICAgICogVGhpcyBub24tc3RhbmRhcmQsIE9yYWNsZS1pbXBsIG9ubHkgcHJvcGVydHkga2V5IGlzIHVzZWQgYXMgaWYgT3V0cHV0S2V5cy5TVEFOREFMT05FIGlzIHNwZWNpZmllZCBidXQKLSAgICAgKiB3aXRob3V0IHdyaXRpbmcgaXQgb3V0IGluIHRoZSBkZWNsYXJhdGlvbjsgSXQgY2FuIGJlIHVzZWQgdG8gcmV2ZXJzZSB0aGUgY2hhbmdlIGJ5IFhhbGFuIHBhdGNoIDE0OTUuCi0gICAgICogU2luY2UgWGFsYW4gcGF0Y2ggMTQ5NSBjYW4gY2F1c2UgaW5jb21wYXRpYmxlIGJlaGF2aW9yLCB0aGlzIHByb3BlcnR5IGlzIGFkZCBmb3IgYXBwbGljYXRpb24gdG8gbmV1dHJhbGl6ZQotICAgICAqIHRoZSBlZmZlY3Qgb2YgWGFsYW4gcGF0Y2ggMTQ5NQotICAgICAqLwotICAgICAgICAvKioKLSAgICAgICAgICogPHA+SXMgU3RhbmRhbG9uZTwvcD4KLSAgICAgICAgICoKLSAgICAgICAgICogPHVsPgotICAgICAgICAgKiAgIDxsaT4KLSAgICAgICAgICogICAgIDxjb2RlPnllczwvY29kZT4gdG8gaW5kaWNhdGUgdGhlIG91dHB1dCBpcyBpbnRlbmRlZCB0byBiZSB1c2VkIGFzIHN0YW5kYWxvbmUKLSAgICAgICAgICogICA8L2xpPgotICAgICAgICAgKiAgIDxsaT4KLSAgICAgICAgICogICAgIDxjb2RlPm5vPC9jb2RlPiBoYXMgbm8gZWZmZWN0LgotICAgICAgICAgKiAgIDwvbGk+Ci0gICAgICAgICAqIDwvdWw+Ci0gICAgICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIE9SQUNMRV9JU19TVEFOREFMT05FID0gImh0dHA6Ly93d3cub3JhY2xlLmNvbS94bWwvaXMtc3RhbmRhbG9uZSI7Ci0KLSAgICAvLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgotICAgIC8vKiAgUFJJVkFURSBDT05TVEFOVFMKLSAgICAvLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgotCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFNfWFNMVF9QUkVGSVggPSAieHNsdC5vdXRwdXQuIjsKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgU19YU0xUX1BSRUZJWF9MRU4gPSBTX1hTTFRfUFJFRklYLmxlbmd0aCgpOwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBTX1hBTEFOX1BSRUZJWCA9ICJvcmcuYXBhY2hlLnhzbHQuIjsKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgU19YQUxBTl9QUkVGSVhfTEVOID0gU19YQUxBTl9QUkVGSVgubGVuZ3RoKCk7Ci0KLSAgICAvKiogU3luY2hyb25pemF0aW9uIG9iamVjdCBmb3IgbGF6eSBpbml0aWFsaXphdGlvbiBvZiB0aGUgYWJvdmUgdGFibGVzLiAqLwotICAgIHByaXZhdGUgc3RhdGljIEludGVnZXIgbV9zeW5jaF9vYmplY3QgPSBuZXcgSW50ZWdlcigxKTsKLQotICAgIC8qKiB0aGUgZGlyZWN0b3J5IGluIHdoaWNoIHRoZSB2YXJpb3VzIG1ldGhvZCBwcm9wZXJ0eSBmaWxlcyBhcmUgbG9jYXRlZCAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBQUk9QX0RJUiA9ICJjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvIjsKLSAgICAvKiogcHJvcGVydHkgZmlsZSBmb3IgZGVmYXVsdCBYTUwgcHJvcGVydGllcyAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBQUk9QX0ZJTEVfWE1MID0gIm91dHB1dF94bWwucHJvcGVydGllcyI7Ci0gICAgLyoqIHByb3BlcnR5IGZpbGUgZm9yIGRlZmF1bHQgVEVYVCBwcm9wZXJ0aWVzICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFBST1BfRklMRV9URVhUID0gIm91dHB1dF90ZXh0LnByb3BlcnRpZXMiOwotICAgIC8qKiBwcm9wZXJ0eSBmaWxlIGZvciBkZWZhdWx0IEhUTUwgcHJvcGVydGllcyAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBQUk9QX0ZJTEVfSFRNTCA9ICJvdXRwdXRfaHRtbC5wcm9wZXJ0aWVzIjsKLSAgICAvKiogcHJvcGVydHkgZmlsZSBmb3IgZGVmYXVsdCBVTktOT1dOIChFaXRoZXIgWE1MIG9yIEhUTUwsIHRvIGJlIGRldGVybWluZWQgbGF0ZXIpIHByb3BlcnRpZXMgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgUFJPUF9GSUxFX1VOS05PV04gPSAib3V0cHV0X3Vua25vd24ucHJvcGVydGllcyI7Ci0KLSAgICAvLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgotICAgIC8vKiAgUFJJVkFURSBTVEFUSUMgRklFTERTCi0gICAgLy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLQotICAgIC8qKiBUaGUgZGVmYXVsdCBwcm9wZXJ0aWVzIG9mIGFsbCBvdXRwdXQgZmlsZXMuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgUHJvcGVydGllcyBtX3htbF9wcm9wZXJ0aWVzID0gbnVsbDsKLQotICAgIC8qKiBUaGUgZGVmYXVsdCBwcm9wZXJ0aWVzIHdoZW4gbWV0aG9kPSJodG1sIi4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBQcm9wZXJ0aWVzIG1faHRtbF9wcm9wZXJ0aWVzID0gbnVsbDsKLQotICAgIC8qKiBUaGUgZGVmYXVsdCBwcm9wZXJ0aWVzIHdoZW4gbWV0aG9kPSJ0ZXh0Ii4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBQcm9wZXJ0aWVzIG1fdGV4dF9wcm9wZXJ0aWVzID0gbnVsbDsKLQotICAgIC8qKiBUaGUgcHJvcGVydGllcyB3aGVuIG1ldGhvZD0iIiBmb3IgdGhlICJ1bmtub3duIiB3cmFwcGVyICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgUHJvcGVydGllcyBtX3Vua25vd25fcHJvcGVydGllcyA9IG51bGw7Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBDbGFzcwotICAgICAgICBBQ0NFU1NfQ09OVFJPTExFUl9DTEFTUyA9IGZpbmRBY2Nlc3NDb250cm9sbGVyQ2xhc3MoKTsKLQotICAgIHByaXZhdGUgc3RhdGljIENsYXNzIGZpbmRBY2Nlc3NDb250cm9sbGVyQ2xhc3MoKSB7Ci0gICAgICAgIHRyeQotICAgICAgICB7Ci0gICAgICAgICAgICAvLyBUaGlzIENsYXNzIHdhcyBpbnRyb2R1Y2VkIGluIEpESyAxLjIuIFdpdGggdGhlIHJlLWFyY2hpdGVjdHVyZSBvZgotICAgICAgICAgICAgLy8gc2VjdXJpdHkgbWVjaGFuaXNtICggc3RhcnRpbmcgaW4gSkRLIDEuMiApLCB3ZSBoYXZlIG9wdGlvbiBvZgotICAgICAgICAgICAgLy8gZ2l2aW5nIHByaXZpbGVnZXMgdG8gY2VydGFpbiBwYXJ0IG9mIGNvZGUgdXNpbmcgZG9Qcml2aWxlZ2VkIGJsb2NrLgotICAgICAgICAgICAgLy8gSW4gSkRLMS4xLlggYXBwbGljYXRpb25zIHdvbid0IGJlIGhhdmluZyBzZWN1cml0eSBtYW5hZ2VyIGFuZCBpZgotICAgICAgICAgICAgLy8gdGhlcmUgaXMgc2VjdXJpdHkgbWFuYWdlciAoIGluIGFwcGxldHMgKSwgY29kZSBuZWVkIHRvIGJlIHNpZ25lZAotICAgICAgICAgICAgLy8gYW5kIHRydXN0ZWQgZm9yIGhhdmluZyBhY2Nlc3MgdG8gcmVzb3VyY2VzLgotCi0gICAgICAgICAgICByZXR1cm4gQ2xhc3MuZm9yTmFtZSgiamF2YS5zZWN1cml0eS5BY2Nlc3NDb250cm9sbGVyIik7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKQotICAgICAgICB7Ci0gICAgICAgICAgICAvL1VzZXIgbWF5IGJlIHVzaW5nIG9sZGVyIEpESyAoIEpESyA8MS4yICkuIEFsbG93IGhpbS9oZXIgdG8gdXNlIGl0LgotICAgICAgICAgICAgLy8gQnV0IGRvbid0IHRyeSB0byB1c2UgZG9Qcml2aWxlZ2VkCi0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGVzIGFuIGVtcHR5IE91dHB1dFByb3BlcnRpZXMgd2l0aCB0aGUgcHJvcGVydHkga2V5L3ZhbHVlIGRlZmF1bHRzIHNwZWNpZmllZCBieQotICAgICAqIGEgcHJvcGVydHkgZmlsZS4gIFRoZSBtZXRob2QgYXJndW1lbnQgaXMgdXNlZCB0byBjb25zdHJ1Y3QgYSBzdHJpbmcgb2YKLSAgICAgKiB0aGUgZm9ybSBvdXRwdXRfW21ldGhvZF0ucHJvcGVydGllcyAoZm9yIGluc3RhbmNlLCBvdXRwdXRfaHRtbC5wcm9wZXJ0aWVzKS4KLSAgICAgKiBUaGUgb3V0cHV0X3htbC5wcm9wZXJ0aWVzIGZpbGUgaXMgYWx3YXlzIHVzZWQgYXMgdGhlIGJhc2UuCi0gICAgICoKLSAgICAgKiA8cD5Bbnl0aGluZyBvdGhlciB0aGFuICd0ZXh0JywgJ3htbCcsIGFuZCAnaHRtbCcsIHdpbGwKLSAgICAgKiB1c2UgdGhlIG91dHB1dF94bWwucHJvcGVydGllcyBmaWxlLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSAgIG1ldGhvZCBub24tbnVsbCByZWZlcmVuY2UgdG8gbWV0aG9kIG5hbWUuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFByb3BlcnRpZXMgb2JqZWN0IHRoYXQgaG9sZHMgdGhlIGRlZmF1bHRzIGZvciB0aGUgZ2l2ZW4gbWV0aG9kLgotICAgICAqLwotICAgIHN0YXRpYyBwdWJsaWMgZmluYWwgUHJvcGVydGllcyBnZXREZWZhdWx0TWV0aG9kUHJvcGVydGllcyhTdHJpbmcgbWV0aG9kKQotICAgIHsKLSAgICAgICAgU3RyaW5nIGZpbGVOYW1lID0gbnVsbDsKLSAgICAgICAgUHJvcGVydGllcyBkZWZhdWx0UHJvcGVydGllcyA9IG51bGw7Ci0gICAgICAgIC8vIEFjY29yZGluZyB0byB0aGlzIGFydGljbGUgOiBEb3VibGUtY2hlY2sgbG9ja2luZyBkb2VzIG5vdCB3b3JrCi0gICAgICAgIC8vIGh0dHA6Ly93d3cuamF2YXdvcmxkLmNvbS9qYXZhd29ybGQvanctMDItMjAwMS9qdy0wMjA5LXRvb2xib3guaHRtbAotICAgICAgICB0cnkKLSAgICAgICAgewotICAgICAgICAgICAgc3luY2hyb25pemVkIChtX3N5bmNoX29iamVjdCkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBpZiAobnVsbCA9PSBtX3htbF9wcm9wZXJ0aWVzKSAvLyBkb3VibGUgY2hlY2sKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIGZpbGVOYW1lID0gUFJPUF9GSUxFX1hNTDsKLSAgICAgICAgICAgICAgICAgICAgbV94bWxfcHJvcGVydGllcyA9IGxvYWRQcm9wZXJ0aWVzRmlsZShmaWxlTmFtZSwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAobWV0aG9kLmVxdWFscyhNZXRob2QuWE1MKSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBkZWZhdWx0UHJvcGVydGllcyA9IG1feG1sX3Byb3BlcnRpZXM7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChtZXRob2QuZXF1YWxzKE1ldGhvZC5IVE1MKSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBpZiAobnVsbCA9PSBtX2h0bWxfcHJvcGVydGllcykgLy8gZG91YmxlIGNoZWNrCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICBmaWxlTmFtZSA9IFBST1BfRklMRV9IVE1MOwotICAgICAgICAgICAgICAgICAgICBtX2h0bWxfcHJvcGVydGllcyA9Ci0gICAgICAgICAgICAgICAgICAgICAgICBsb2FkUHJvcGVydGllc0ZpbGUoZmlsZU5hbWUsIG1feG1sX3Byb3BlcnRpZXMpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIGRlZmF1bHRQcm9wZXJ0aWVzID0gbV9odG1sX3Byb3BlcnRpZXM7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChtZXRob2QuZXF1YWxzKE1ldGhvZC5URVhUKSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBpZiAobnVsbCA9PSBtX3RleHRfcHJvcGVydGllcykgLy8gZG91YmxlIGNoZWNrCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICBmaWxlTmFtZSA9IFBST1BfRklMRV9URVhUOwotICAgICAgICAgICAgICAgICAgICBtX3RleHRfcHJvcGVydGllcyA9Ci0gICAgICAgICAgICAgICAgICAgICAgICBsb2FkUHJvcGVydGllc0ZpbGUoZmlsZU5hbWUsIG1feG1sX3Byb3BlcnRpZXMpOwotICAgICAgICAgICAgICAgICAgICBpZiAobnVsbAotICAgICAgICAgICAgICAgICAgICAgICAgPT0gbV90ZXh0X3Byb3BlcnRpZXMuZ2V0UHJvcGVydHkoT3V0cHV0S2V5cy5FTkNPRElORykpCi0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBtaW1lRW5jb2RpbmcgPSBFbmNvZGluZ3MuZ2V0TWltZUVuY29kaW5nKG51bGwpOwotICAgICAgICAgICAgICAgICAgICAgICAgbV90ZXh0X3Byb3BlcnRpZXMucHV0KAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIE91dHB1dEtleXMuRU5DT0RJTkcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWltZUVuY29kaW5nKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIGRlZmF1bHRQcm9wZXJ0aWVzID0gbV90ZXh0X3Byb3BlcnRpZXM7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChtZXRob2QuZXF1YWxzKGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplci5NZXRob2QuVU5LTk9XTikpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgaWYgKG51bGwgPT0gbV91bmtub3duX3Byb3BlcnRpZXMpIC8vIGRvdWJsZSBjaGVjawotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgZmlsZU5hbWUgPSBQUk9QX0ZJTEVfVU5LTk9XTjsKLSAgICAgICAgICAgICAgICAgICAgbV91bmtub3duX3Byb3BlcnRpZXMgPQotICAgICAgICAgICAgICAgICAgICAgICAgbG9hZFByb3BlcnRpZXNGaWxlKGZpbGVOYW1lLCBtX3htbF9wcm9wZXJ0aWVzKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBkZWZhdWx0UHJvcGVydGllcyA9IG1fdW5rbm93bl9wcm9wZXJ0aWVzOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIC8vIFRPRE86IENhbGN1bGF0ZSByZXMgZmlsZSBmcm9tIG5hbWUuCi0gICAgICAgICAgICAgICAgZGVmYXVsdFByb3BlcnRpZXMgPSBtX3htbF9wcm9wZXJ0aWVzOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChJT0V4Y2VwdGlvbiBpb2UpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBXcmFwcGVkUnVudGltZUV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICBVdGlscy5tZXNzYWdlcy5jcmVhdGVNZXNzYWdlKAotICAgICAgICAgICAgICAgICAgICBNc2dLZXkuRVJfQ09VTERfTk9UX0xPQURfTUVUSE9EX1BST1BFUlRZLAotICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBmaWxlTmFtZSwgbWV0aG9kIH0pLAotICAgICAgICAgICAgICAgIGlvZSk7Ci0gICAgICAgIH0KLSAgICAgICAgLy8gd3JhcCB0aGVzZSBjYWNoZWQgZGVmYXVsdFByb3BlcnRpZXMgaW4gYSBuZXcgUHJvcGVydHkgb2JqZWN0IGp1c3Qgc28KLSAgICAgICAgLy8gdGhhdCB0aGUgY2FsbGVyIG9mIHRoaXMgbWV0aG9kIGNhbid0IG1vZGlmeSB0aGUgZGVmYXVsdCB2YWx1ZXMKLSAgICAgICAgcmV0dXJuIG5ldyBQcm9wZXJ0aWVzKGRlZmF1bHRQcm9wZXJ0aWVzKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBMb2FkIHRoZSBwcm9wZXJ0aWVzIGZpbGUgZnJvbSBhIHJlc291cmNlIHN0cmVhbS4gIElmIGEKLSAgICAgKiBrZXkgbmFtZSBzdWNoIGFzICJvcmcuYXBhY2hlLnhzbHQueHh4IiwgZml4IHVwIHRoZSBzdGFydCBvZgotICAgICAqIHN0cmluZyB0byBiZSBhIGN1cmx5IG5hbWVzcGFjZS4gIElmIGEga2V5IG5hbWUgc3RhcnRzIHdpdGgKLSAgICAgKiAieHNsdC5vdXRwdXQueHh4IiwgY2xpcCBvZmYgInhzbHQub3V0cHV0LiIuICBJZiBhIGtleSBuYW1lICpvciogYQotICAgICAqIGtleSB2YWx1ZSBpcyBkaXNjb3ZlcmVkLCBjaGVjayBmb3IgXHUwMDNhIGluIHRoZSB0ZXh0LCBhbmQKLSAgICAgKiBmaXggaXQgdXAgdG8gYmUgIjoiLCBzaW5jZSBlYXJsaWVyIHZlcnNpb25zIG9mIHRoZSBKREsgZG8gbm90Ci0gICAgICogaGFuZGxlIHRoZSBlc2NhcGUgc2VxdWVuY2UgKGF0IGxlYXN0IGluIGtleSBuYW1lcykuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcmVzb3VyY2VOYW1lIG5vbi1udWxsIHJlZmVyZW5jZSB0byByZXNvdXJjZSBuYW1lLgotICAgICAqIEBwYXJhbSBkZWZhdWx0cyBEZWZhdWx0IHByb3BlcnRpZXMsIHdoaWNoIG1heSBiZSBudWxsLgotICAgICAqLwotICAgIHN0YXRpYyBwcml2YXRlIFByb3BlcnRpZXMgbG9hZFByb3BlcnRpZXNGaWxlKAotICAgICAgICBmaW5hbCBTdHJpbmcgcmVzb3VyY2VOYW1lLAotICAgICAgICBQcm9wZXJ0aWVzIGRlZmF1bHRzKQotICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24KLSAgICB7Ci0KLSAgICAgICAgLy8gVGhpcyBzdGF0aWMgbWV0aG9kIHNob3VsZCBldmVudHVhbGx5IGJlIG1vdmVkIHRvIGEgdGhyZWFkLXNwZWNpZmljIGNsYXNzCi0gICAgICAgIC8vIHNvIHRoYXQgd2UgY2FuIGNhY2hlIHRoZSBDb250ZXh0Q2xhc3NMb2FkZXIgYW5kIGJvdHRsZW5lY2sgYWxsIHByb3BlcnRpZXMgZmlsZQotICAgICAgICAvLyBsb2FkaW5nIHRocm91Z2hvdXQgWGFsYW4uCi0KLSAgICAgICAgUHJvcGVydGllcyBwcm9wcyA9IG5ldyBQcm9wZXJ0aWVzKGRlZmF1bHRzKTsKLQotICAgICAgICBJbnB1dFN0cmVhbSBpcyA9IG51bGw7Ci0gICAgICAgIEJ1ZmZlcmVkSW5wdXRTdHJlYW0gYmlzID0gbnVsbDsKLQotICAgICAgICB0cnkKLSAgICAgICAgewotICAgICAgICAgICAgaWYgKEFDQ0VTU19DT05UUk9MTEVSX0NMQVNTICE9IG51bGwpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgaXMgPSAoSW5wdXRTdHJlYW0pIEFjY2Vzc0NvbnRyb2xsZXIKLSAgICAgICAgICAgICAgICAgICAgLmRvUHJpdmlsZWdlZChuZXcgUHJpdmlsZWdlZEFjdGlvbigpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHB1YmxpYyBPYmplY3QgcnVuKCkKLSAgICAgICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gT3V0cHV0UHJvcGVydGllc0ZhY3RvcnkuY2xhc3MKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmdldFJlc291cmNlQXNTdHJlYW0ocmVzb3VyY2VOYW1lKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgLy8gVXNlciBtYXkgYmUgdXNpbmcgb2xkZXIgSkRLICggSkRLIDwgMS4yICkKLSAgICAgICAgICAgICAgICBpcyA9IE91dHB1dFByb3BlcnRpZXNGYWN0b3J5LmNsYXNzCi0gICAgICAgICAgICAgICAgICAgIC5nZXRSZXNvdXJjZUFzU3RyZWFtKHJlc291cmNlTmFtZSk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGJpcyA9IG5ldyBCdWZmZXJlZElucHV0U3RyZWFtKGlzKTsKLSAgICAgICAgICAgIHByb3BzLmxvYWQoYmlzKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoSU9FeGNlcHRpb24gaW9lKQotICAgICAgICB7Ci0gICAgICAgICAgICBpZiAoZGVmYXVsdHMgPT0gbnVsbCkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBpb2U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFdyYXBwZWRSdW50aW1lRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICBVdGlscy5tZXNzYWdlcy5jcmVhdGVNZXNzYWdlKAotICAgICAgICAgICAgICAgICAgICAgICAgTXNnS2V5LkVSX0NPVUxEX05PVF9MT0FEX1JFU09VUkNFLAotICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgcmVzb3VyY2VOYW1lIH0pLAotICAgICAgICAgICAgICAgICAgICBpb2UpOwotICAgICAgICAgICAgICAgIC8vIkNvdWxkIG5vdCBsb2FkICciK3Jlc291cmNlTmFtZSsiJyAoY2hlY2sgQ0xBU1NQQVRIKSwgbm93IHVzaW5nIGp1c3QgdGhlIGRlZmF1bHRzICIsIGlvZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIHNlKQotICAgICAgICB7Ci0gICAgICAgICAgICAvLyBSZXBlYXQgSU9FeGNlcHRpb24gaGFuZGxpbmcgZm9yIHNhbmRib3gvYXBwbGV0IGNhc2UgLXNjCi0gICAgICAgICAgICBpZiAoZGVmYXVsdHMgPT0gbnVsbCkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgV3JhcHBlZFJ1bnRpbWVFeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgIFV0aWxzLm1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoCi0gICAgICAgICAgICAgICAgICAgICAgICBNc2dLZXkuRVJfQ09VTERfTk9UX0xPQURfUkVTT1VSQ0UsCi0gICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyByZXNvdXJjZU5hbWUgfSksCi0gICAgICAgICAgICAgICAgICAgIHNlKTsKLSAgICAgICAgICAgICAgICAvLyJDb3VsZCBub3QgbG9hZCAnIityZXNvdXJjZU5hbWUrIicgKGNoZWNrIENMQVNTUEFUSCwgYXBwbGV0IHNlY3VyaXR5KSwgbm93IHVzaW5nIGp1c3QgdGhlIGRlZmF1bHRzICIsIHNlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBmaW5hbGx5Ci0gICAgICAgIHsKLSAgICAgICAgICAgIGlmIChiaXMgIT0gbnVsbCkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBiaXMuY2xvc2UoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChpcyAhPSBudWxsKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIGlzLmNsb3NlKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBOb3RlIHRoYXQgd2UncmUgd29ya2luZyBhdCB0aGUgSGFzaFRhYmxlIGxldmVsIGhlcmUsCi0gICAgICAgIC8vIGFuZCBub3QgYXQgdGhlIFByb3BlcnRpZXMgbGV2ZWwhICBUaGlzIGlzIGltcG9ydGFudAotICAgICAgICAvLyBiZWNhdXNlIHdlIGRvbid0IHdhbnQgdG8gbW9kaWZ5IHRoZSBkZWZhdWx0IHByb3BlcnRpZXMuCi0gICAgICAgIC8vIE5COiBJZiBmaXh1cFByb3BlcnR5U3RyaW5nIGVuZHMgdXAgY2hhbmdpbmcgdGhlIHByb3BlcnR5Ci0gICAgICAgIC8vIG5hbWUgb3IgdmFsdWUsIHdlIG5lZWQgdG8gcmVtb3ZlIHRoZSBvbGQga2V5IGFuZCByZS1hZGQKLSAgICAgICAgLy8gd2l0aCB0aGUgbmV3IGtleSBhbmQgdmFsdWUuICBIb3dldmVyLCB0aGVuIG91ciBFbnVtZXJhdGlvbgotICAgICAgICAvLyBjb3VsZCBsb3NlIGl0cyBwbGFjZSBpbiB0aGUgSGFzaFRhYmxlLiAgU28sIHdlIGZpcnN0Ci0gICAgICAgIC8vIGNsb25lIHRoZSBIYXNoVGFibGUgYW5kIGVudW1lcmF0ZSBvdmVyIHRoYXQgc2luY2UgdGhlCi0gICAgICAgIC8vIGNsb25lIHdpbGwgbm90IGNoYW5nZS4gIFdoZW4gd2UgbWlncmF0ZSB0byBDb2xsZWN0aW9ucywKLSAgICAgICAgLy8gdGhpcyBjb2RlIHNob3VsZCBiZSByZXZpc2l0ZWQgYW5kIGNsZWFuZWQgdXAgdG8gdXNlCi0gICAgICAgIC8vIGFuIEl0ZXJhdG9yIHdoaWNoIG1heSAob3IgbWF5IG5vdCkgYWxsZXZpYXRlIHRoZSBuZWVkIGZvcgotICAgICAgICAvLyB0aGUgY2xvbmUuICBNYW55IHRoYW5rcyB0byBQYWRyYWlnIE8naEljZWFkaGEKLSAgICAgICAgLy8gPHBhZHJhaWdAZ3JhZGllbnQuaWU+IGZvciBmaW5kaW5nIHRoaXMgcHJvYmxlbS4gIEJ1Z3ppbGxhIDIwMDAuCi0KLSAgICAgICAgRW51bWVyYXRpb24ga2V5cyA9ICgoUHJvcGVydGllcykgcHJvcHMuY2xvbmUoKSkua2V5cygpOwotICAgICAgICB3aGlsZSAoa2V5cy5oYXNNb3JlRWxlbWVudHMoKSkKLSAgICAgICAgewotICAgICAgICAgICAgU3RyaW5nIGtleSA9IChTdHJpbmcpIGtleXMubmV4dEVsZW1lbnQoKTsKLSAgICAgICAgICAgIC8vIE5vdyBjaGVjayBpZiB0aGUgZ2l2ZW4ga2V5IHdhcyBzcGVjaWZpZWQgYXMgYQotICAgICAgICAgICAgLy8gU3lzdGVtIHByb3BlcnR5LiBJZiBzbywgdGhlIHN5c3RlbSBwcm9wZXJ0eQotICAgICAgICAgICAgLy8gb3ZlcmlkZXMgdGhlIGRlZmF1bHQgdmFsdWUgaW4gdGhlIHByb3BlcnkgZmlsZS4KLSAgICAgICAgICAgIFN0cmluZyB2YWx1ZSA9IG51bGw7Ci0gICAgICAgICAgICB0cnkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICB2YWx1ZSA9IFNlY3VyaXR5U3VwcG9ydC5nZXRTeXN0ZW1Qcm9wZXJ0eShrZXkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIHNlKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIC8vIE5vLW9wIGZvciBzYW5kYm94L2FwcGxldCBjYXNlLCBsZWF2ZSBudWxsIC1zYwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpCi0gICAgICAgICAgICAgICAgdmFsdWUgPSAoU3RyaW5nKSBwcm9wcy5nZXQoa2V5KTsKLQotICAgICAgICAgICAgU3RyaW5nIG5ld0tleSA9IGZpeHVwUHJvcGVydHlTdHJpbmcoa2V5LCB0cnVlKTsKLSAgICAgICAgICAgIFN0cmluZyBuZXdWYWx1ZSA9IG51bGw7Ci0gICAgICAgICAgICB0cnkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBuZXdWYWx1ZSA9IFNlY3VyaXR5U3VwcG9ydC5nZXRTeXN0ZW1Qcm9wZXJ0eShuZXdLZXkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIHNlKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIC8vIE5vLW9wIGZvciBzYW5kYm94L2FwcGxldCBjYXNlLCBsZWF2ZSBudWxsIC1zYwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKG5ld1ZhbHVlID09IG51bGwpCi0gICAgICAgICAgICAgICAgbmV3VmFsdWUgPSBmaXh1cFByb3BlcnR5U3RyaW5nKHZhbHVlLCBmYWxzZSk7Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgbmV3VmFsdWUgPSBmaXh1cFByb3BlcnR5U3RyaW5nKG5ld1ZhbHVlLCBmYWxzZSk7Ci0KLSAgICAgICAgICAgIGlmIChrZXkgIT0gbmV3S2V5IHx8IHZhbHVlICE9IG5ld1ZhbHVlKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIHByb3BzLnJlbW92ZShrZXkpOwotICAgICAgICAgICAgICAgIHByb3BzLnB1dChuZXdLZXksIG5ld1ZhbHVlKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIHByb3BzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEZpeCB1cCBhIHN0cmluZyBpbiBhbiBvdXRwdXQgcHJvcGVydGllcyBmaWxlIGFjY29yZGluZyB0bwotICAgICAqIHRoZSBydWxlcyBvZiB7QGxpbmsgI2xvYWRQcm9wZXJ0aWVzRmlsZX0uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcyBub24tbnVsbCByZWZlcmVuY2UgdG8gc3RyaW5nIHRoYXQgbWF5IG5lZWQgdG8gYmUgZml4ZWQgdXAuCi0gICAgICogQHJldHVybiBBIG5ldyBzdHJpbmcgaWYgZml4dXAgb2NjdXJlZCwgb3RoZXJ3aXNlIHRoZSBzIGFyZ3VtZW50LgotICAgICAqLwotICAgIHN0YXRpYyBwcml2YXRlIFN0cmluZyBmaXh1cFByb3BlcnR5U3RyaW5nKFN0cmluZyBzLCBib29sZWFuIGRvQ2xpcHBpbmcpCi0gICAgewotICAgICAgICBpbnQgaW5kZXg7Ci0gICAgICAgIGlmIChkb0NsaXBwaW5nICYmIHMuc3RhcnRzV2l0aChTX1hTTFRfUFJFRklYKSkKLSAgICAgICAgewotICAgICAgICAgICAgcyA9IHMuc3Vic3RyaW5nKFNfWFNMVF9QUkVGSVhfTEVOKTsKLSAgICAgICAgfQotICAgICAgICBpZiAocy5zdGFydHNXaXRoKFNfWEFMQU5fUFJFRklYKSkKLSAgICAgICAgewotICAgICAgICAgICAgcyA9Ci0gICAgICAgICAgICAgICAgU19CVUlMVElOX0VYVEVOU0lPTlNfVU5JVkVSU0FMCi0gICAgICAgICAgICAgICAgICAgICsgcy5zdWJzdHJpbmcoU19YQUxBTl9QUkVGSVhfTEVOKTsKLSAgICAgICAgfQotICAgICAgICBpZiAoKGluZGV4ID0gcy5pbmRleE9mKCJcXHUwMDNhIikpID4gMCkKLSAgICAgICAgewotICAgICAgICAgICAgU3RyaW5nIHRlbXAgPSBzLnN1YnN0cmluZyhpbmRleCArIDYpOwotICAgICAgICAgICAgcyA9IHMuc3Vic3RyaW5nKDAsIGluZGV4KSArICI6IiArIHRlbXA7Ci0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gczsKLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvT3V0cHV0UHJvcGVydHlVdGlscy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9PdXRwdXRQcm9wZXJ0eVV0aWxzLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDdlNGNjYjkuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9PdXRwdXRQcm9wZXJ0eVV0aWxzLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4NSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBPdXRwdXRQcm9wZXJ0eVV0aWxzLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTUgMDg6MTU6MjEgc3VyZXNoX2VtYWlsaWQgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXI7Ci0KLWltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGNvbnRhaW5zIHNvbWUgc3RhdGljIG1ldGhvZHMgdGhhdCBhY3QgYXMgaGVscGVycyB3aGVuIHBhcnNpbmcgYQotICogSmF2YSBQcm9wZXJ0eSBvYmplY3QuCi0gKgotICogVGhpcyBjbGFzcyBpcyBub3QgYSBwdWJsaWMgQVBJLgotICogSXQgaXMgb25seSBwdWJsaWMgYmVjYXVzZSBpdCBpcyB1c2VkIG91dHNpZGUgb2YgdGhpcyBwYWNrYWdlLgotICoKLSAqIEBzZWUgamF2YS51dGlsLlByb3BlcnRpZXMKLSAqIEB4c2wudXNhZ2UgaW50ZXJuYWwKLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIE91dHB1dFByb3BlcnR5VXRpbHMKLXsKLSAgICAvKioKLSAgICAgICogU2VhcmNoZXMgZm9yIHRoZSBib29sZWFuIHByb3BlcnR5IHdpdGggdGhlIHNwZWNpZmllZCBrZXkgaW4gdGhlIHByb3BlcnR5IGxpc3QuCi0gICAgICAqIElmIHRoZSBrZXkgaXMgbm90IGZvdW5kIGluIHRoaXMgcHJvcGVydHkgbGlzdCwgdGhlIGRlZmF1bHQgcHJvcGVydHkgbGlzdCwKLSAgICAgICogYW5kIGl0cyBkZWZhdWx0cywgcmVjdXJzaXZlbHksIGFyZSB0aGVuIGNoZWNrZWQuIFRoZSBtZXRob2QgcmV0dXJucwotICAgICAgKiA8Y29kZT5mYWxzZTwvY29kZT4gaWYgdGhlIHByb3BlcnR5IGlzIG5vdCBmb3VuZCwgb3IgaWYgdGhlIHZhbHVlIGlzIG90aGVyCi0gICAgICAqIHRoYW4gInllcyIuCi0gICAgICAqCi0gICAgICAqIEBwYXJhbSAgIGtleSAgIHRoZSBwcm9wZXJ0eSBrZXkuCi0gICAgICAqIEBwYXJhbSAgIHByb3BzICAgdGhlIGxpc3Qgb2YgcHJvcGVydGllcyB0aGF0IHdpbGwgYmUgc2VhcmNoZWQuCi0gICAgICAqIEByZXR1cm4gIHRoZSB2YWx1ZSBpbiB0aGlzIHByb3BlcnR5IGxpc3QgYXMgYSBib29sZWFuIHZhbHVlLCBvciBmYWxzZQotICAgICAgKiBpZiBudWxsIG9yIG5vdCAieWVzIi4KLSAgICAgICovCi0gICAgcHVibGljIHN0YXRpYyBib29sZWFuIGdldEJvb2xlYW5Qcm9wZXJ0eShTdHJpbmcga2V5LCBQcm9wZXJ0aWVzIHByb3BzKQotICAgIHsKLQotICAgICAgICBTdHJpbmcgcyA9IHByb3BzLmdldFByb3BlcnR5KGtleSk7Ci0KLSAgICAgICAgaWYgKG51bGwgPT0gcyB8fCAhcy5lcXVhbHMoInllcyIpKQotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICBlbHNlCi0gICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZWFyY2hlcyBmb3IgdGhlIGludCBwcm9wZXJ0eSB3aXRoIHRoZSBzcGVjaWZpZWQga2V5IGluIHRoZSBwcm9wZXJ0eSBsaXN0LgotICAgICAqIElmIHRoZSBrZXkgaXMgbm90IGZvdW5kIGluIHRoaXMgcHJvcGVydHkgbGlzdCwgdGhlIGRlZmF1bHQgcHJvcGVydHkgbGlzdCwKLSAgICAgKiBhbmQgaXRzIGRlZmF1bHRzLCByZWN1cnNpdmVseSwgYXJlIHRoZW4gY2hlY2tlZC4gVGhlIG1ldGhvZCByZXR1cm5zCi0gICAgICogPGNvZGU+ZmFsc2U8L2NvZGU+IGlmIHRoZSBwcm9wZXJ0eSBpcyBub3QgZm91bmQsIG9yIGlmIHRoZSB2YWx1ZSBpcyBvdGhlcgotICAgICAqIHRoYW4gInllcyIuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gICBrZXkgICB0aGUgcHJvcGVydHkga2V5LgotICAgICAqIEBwYXJhbSAgIHByb3BzICAgdGhlIGxpc3Qgb2YgcHJvcGVydGllcyB0aGF0IHdpbGwgYmUgc2VhcmNoZWQuCi0gICAgICogQHJldHVybiAgdGhlIHZhbHVlIGluIHRoaXMgcHJvcGVydHkgbGlzdCBhcyBhIGludCB2YWx1ZSwgb3IgMAotICAgICAqIGlmIG51bGwgb3Igbm90IGEgbnVtYmVyLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgaW50IGdldEludFByb3BlcnR5KFN0cmluZyBrZXksIFByb3BlcnRpZXMgcHJvcHMpCi0gICAgewotCi0gICAgICAgIFN0cmluZyBzID0gcHJvcHMuZ2V0UHJvcGVydHkoa2V5KTsKLQotICAgICAgICBpZiAobnVsbCA9PSBzKQotICAgICAgICAgICAgcmV0dXJuIDA7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICAgIHJldHVybiBJbnRlZ2VyLnBhcnNlSW50KHMpOwotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxZTkxODU1Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEzNCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAzLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBTZXJpYWxpemF0aW9uSGFuZGxlci5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE1IDA4OjE1OjIyIHN1cmVzaF9lbWFpbGlkIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyOwotCi1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXI7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotaW1wb3J0IG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LkVycm9ySGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguZXh0LkRlY2xIYW5kbGVyOwotCi0vKioKLSAqIFRoaXMgaW50ZXJmYWNlIGlzIHRoZSBvbmUgdGhhdCBhIHNlcmlhbGl6ZXIgaW1wbGVtZW50cy4gSXQgaXMgYSBncm91cCBvZgotICogb3RoZXIgaW50ZXJmYWNlcywgc3VjaCBhcyBFeHRlbmRlZENvbnRlbnRIYW5kbGVyLCBFeHRlbmRlZExleGljYWxIYW5kbGVyIGV0Yy4KLSAqIEluIGFkZGl0aW9uIHRoZXJlIGFyZSBvdGhlciBtZXRob2RzLCBzdWNoIGFzIHJlc2V0KCkuCi0gKgotICogVGhpcyBjbGFzcyBpcyBwdWJsaWMgb25seSBiZWNhdXNlIGl0IGlzIHVzZWQgaW4gYW5vdGhlciBwYWNrYWdlLAotICogaXQgaXMgbm90IGEgcHVibGljIEFQSS4KLSAqCi0gKiBAeHNsLnVzYWdlIGludGVybmFsCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgU2VyaWFsaXphdGlvbkhhbmRsZXIKLSAgICBleHRlbmRzCi0gICAgICAgIEV4dGVuZGVkQ29udGVudEhhbmRsZXIsCi0gICAgICAgIEV4dGVuZGVkTGV4aWNhbEhhbmRsZXIsCi0gICAgICAgIFhTTE91dHB1dEF0dHJpYnV0ZXMsCi0gICAgICAgIERlY2xIYW5kbGVyLAotICAgICAgICBvcmcueG1sLnNheC5EVERIYW5kbGVyLAotICAgICAgICBFcnJvckhhbmRsZXIsCi0gICAgICAgIERPTVNlcmlhbGl6ZXIsCi0gICAgICAgIFNlcmlhbGl6ZXIKLXsKLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIFNBWCBDb250ZW50IGhhbmRsZXIgdGhhdCB0aGUgc2VyaWFsaXplciBzZW5kcyBpdHMgb3V0cHV0IHRvLiBUaGlzCi0gICAgICogbWV0aG9kIG9ubHkgYXBwbGllcyB0byBhIFRvU0FYSGFuZGxlciwgbm90IHRvIGEgVG9TdHJlYW0gc2VyaWFsaXplci4KLSAgICAgKgotICAgICAqIEBzZWUgU2VyaWFsaXplciNhc0NvbnRlbnRIYW5kbGVyKCkKLSAgICAgKiBAc2VlIFRvU0FYSGFuZGxlcgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldENvbnRlbnRIYW5kbGVyKENvbnRlbnRIYW5kbGVyIGNoKTsKLQotICAgIHB1YmxpYyB2b2lkIGNsb3NlKCk7Ci0KLSAgICAvKioKLSAgICAgKiBOb3RpZnkgdGhhdCB0aGUgc2VyaWFsaXplciBzaG91bGQgdGFrZSB0aGlzIERPTSBub2RlIGFzIGlucHV0IHRvIGJlCi0gICAgICogc2VyaWFsaXplZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBub2RlIHRoZSBET00gbm9kZSB0byBiZSBzZXJpYWxpemVkLgotICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXJpYWxpemUoTm9kZSBub2RlKSB0aHJvd3MgSU9FeGNlcHRpb247Ci0gICAgLyoqCi0gICAgICogVHVybnMgc3BlY2lhbCBjaGFyYWN0ZXIgZXNjYXBpbmcgb24vb2ZmLgotICAgICAqCi0gICAgICogTm90ZSB0aGF0IGNoYXJhY3RlcnMgd2lsbAotICAgICAqIG5ldmVyLCBldmVuIGlmIHRoaXMgb3B0aW9uIGlzIHNldCB0byAndHJ1ZScsIGJlIGVzY2FwZWQgd2l0aGluCi0gICAgICogQ0RBVEEgc2VjdGlvbnMgaW4gb3V0cHV0IFhNTCBkb2N1bWVudHMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZXNjYXBlIHRydWUgaWYgZXNjYXBpbmcgaXMgdG8gYmUgc2V0IG9uLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIHNldEVzY2FwaW5nKGJvb2xlYW4gZXNjYXBlKSB0aHJvd3MgU0FYRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSBudW1iZXIgb2Ygc3BhY2VzIHRvIGluZGVudCBmb3IgZWFjaCBpbmRlbnRhdGlvbiBsZXZlbC4KLSAgICAgKiBAcGFyYW0gc3BhY2VzIHRoZSBudW1iZXIgb2Ygc3BhY2VzIHRvIGluZGVudCBmb3IgZWFjaCBpbmRlbnRhdGlvbiBsZXZlbC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRJbmRlbnRBbW91bnQoaW50IHNwYWNlcyk7Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIHRyYW5zZm9ybWVyIGFzc29jaWF0ZWQgd2l0aCB0aGUgc2VyaWFsaXplci4KLSAgICAgKiBAcGFyYW0gdHJhbnNmb3JtZXIgdGhlIHRyYW5zZm9ybWVyIGFzc29jaWF0ZWQgd2l0aCB0aGUgc2VyaWFsaXplci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRUcmFuc2Zvcm1lcihUcmFuc2Zvcm1lciB0cmFuc2Zvcm1lcik7Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIHRyYW5zZm9ybWVyIGFzc29jaWF0ZWQgd2l0aCB0aGUgc2VyaWFsaXplci4KLSAgICAgKiBAcmV0dXJuIFRyYW5zZm9ybWVyIHRoZSB0cmFuc2Zvcm1lciBhc3NvY2lhdGVkIHdpdGggdGhlIHNlcmlhbGl6ZXIuCi0gICAgICovCi0gICAgcHVibGljIFRyYW5zZm9ybWVyIGdldFRyYW5zZm9ybWVyKCk7Ci0KLSAgICAvKioKLSAgICAgKiBVc2VkIG9ubHkgYnkgVHJhbnNmb3JtZXJTbmFwc2hvdEltcGwgdG8gcmVzdG9yZSB0aGUgc2VyaWFsaXphdGlvbgotICAgICAqIHRvIGEgcHJldmlvdXMgc3RhdGUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbWFwcGluZ3MgTmFtZXNwYWNlTWFwcGluZ3MKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXROYW1lc3BhY2VNYXBwaW5ncyhOYW1lc3BhY2VNYXBwaW5ncyBtYXBwaW5ncyk7Ci0KLSAgICAvKioKLSAgICAgKiBGbHVzaCBhbnkgcGVuZGluZyBldmVudHMgY3VycmVudGx5IHF1ZXVlZCB1cCBpbiB0aGUgc2VyaWFsaXplci4gVGhpcyB3aWxsCi0gICAgICogZmx1c2ggYW55IGlucHV0IHRoYXQgdGhlIHNlcmlhbGl6ZXIgaGFzIHdoaWNoIGl0IGhhcyBub3QgeWV0IHNlbnQgYXMKLSAgICAgKiBvdXRwdXQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZmx1c2hQZW5kaW5nKCkgdGhyb3dzIFNBWEV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIERlZmF1bHQgYmVoYXZpb3IgaXMgdG8gZXhwYW5kIERURCBlbnRpdGllcywKLSAgICAgKiB0aGF0IGlzIHRoZSBpbml0YWxsIGRlZmF1bHQgdmFsdWUgaXMgdHJ1ZS4KLSAgICAgKiBAcGFyYW0gZXhwYW5kIHRydWUgaWYgRFREIGVudGl0aWVzIGFyZSB0byBiZSBleHBhbmRlZCwKLSAgICAgKiBmYWxzZSBpZiB0aGV5IGFyZSB0byBiZSBsZWZ0IGFzIERURCBlbnRpdHkgcmVmZXJlbmNlcy4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXREVERFbnRpdHlFeHBhbnNpb24oYm9vbGVhbiBleHBhbmQpOwotCi0gICAgLyoqCi0gICAgICogU3BlY2lmeSBpZiB0aGUgb3V0cHV0IHdpbGwgYmUgdHJlYXRlZCBhcyBhIHN0YW5kYWxvbmUgIHByb3BlcnR5Ci0gICAgICogQHBhcmFtIGlzU3RhbmRhbG9uZSB0cnVlIGlmIHRoZSBodHRwOi8vd3d3Lm9yYWNsZS5jb20veG1sL2lzLXN0YW5kYWxvbmUgaXMgc2V0IHRvIHllcwotICAgICAqIEBzZWUgT3V0cHV0UHJvcGVydGllc0ZhY3RvcnkgT1JBQ0xFX0lTX1NUQU5EQUxPTkUKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRJc1N0YW5kYWxvbmUoYm9vbGVhbiBiKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6ZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOWNhZTJkMi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6ZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIyMyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBTZXJpYWxpemVyLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTUgMDg6MTU6MjIgc3VyZXNoX2VtYWlsaWQgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXI7Ci1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKLWltcG9ydCBqYXZhLmlvLldyaXRlcjsKLWltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKLQotaW1wb3J0IG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyOwotCi0vKioKLSAqIFRoZSBTZXJpYWxpemVyIGludGVyZmFjZSBpcyBpbXBsZW1lbnRlZCBieSBhIHNlcmlhbGl6ZXIgdG8gZW5hYmxlIHVzZXJzIHRvOgotICogPHVsPgotICogPGxpPmdldCBhbmQgc2V0IHN0cmVhbXMgb3Igd3JpdGVycwotICogPGxpPmNvbmZpZ3VyZSB0aGUgc2VyaWFsaXplciB3aXRoIGtleS92YWx1ZSBwcm9wZXJ0aWVzCi0gKiA8bGk+Z2V0IGFuIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyIG9yIGEgRE9NU2VyaWFsaXplciB0byBwcm92aWRlIGlucHV0IHRvCi0gKiA8L3VsPgotICoKLSAqIDxwPgotICogSGVyZSBpcyBhbiBleGFtcGxlIHVzaW5nIHRoZSBhc0NvbnRlbnRIYW5kbGVyKCkgbWV0aG9kOgotICogPHByZT4KLSAqIGphdmEudXRpbC5Qcm9wZXJ0aWVzIHByb3BzID0KLSAqICAgT3V0cHV0UHJvcGVydGllc0ZhY3RvcnkuZ2V0RGVmYXVsdE1ldGhvZFByb3BlcnRpZXMoTWV0aG9kLlRFWFQpOwotICogU2VyaWFsaXplciBzZXIgPSBTZXJpYWxpemVyRmFjdG9yeS5nZXRTZXJpYWxpemVyKHByb3BzKTsKLSAqIGphdmEuaW8uUHJpbnRTdHJlYW0gb3N0cmVhbSA9IFN5c3RlbS5vdXQ7Ci0gKiBzZXIuc2V0T3V0cHV0U3RyZWFtKG9zdHJlYW0pOwotICoKLSAqIC8vIFByb3ZpZGUgdGhlIFNBWCBpbnB1dCBldmVudHMKLSAqIENvbnRlbnRIYW5kbGVyIGhhbmRsZXIgPSBzZXIuYXNDb250ZW50SGFuZGxlcigpOwotICogaGFuZGxlci5zdGFydERvY3VtZW50KCk7Ci0gKiBjaGFyW10gY2hhcnMgPSB7ICdhJywgJ2InLCAnYycgfTsKLSAqIGhhbmRsZXIuY2hhcmFjdGVycyhjaGFycywgMCwgY2hhcnMubGVuZ3RoKTsKLSAqIGhhbmRsZXIuZW5kRG9jdW1lbnQoKTsKLSAqCi0gKiBzZXIucmVzZXQoKTsgLy8gZ2V0IHJlYWR5IHRvIHVzZSB0aGUgc2VyaWFsaXplciBmb3IgYW5vdGhlciBkb2N1bWVudAotICogICAgICAgICAgICAgIC8vIG9mIHRoZSBzYW1lIG91dHB1dCBtZXRob2QgKFRFWFQpLgotICogPC9wcmU+Ci0gKgotICogPHA+Ci0gKiBBcyBhbiBhbHRlcm5hdGUgdG8gc3VwcGx5aW5nIGEgc2VyaWVzIG9mIFNBWCBldmVudHMgYXMgaW5wdXQgdGhyb3VnaCB0aGUKLSAqIENvbnRlbnRIYW5kbGVyIGludGVyZmFjZSwgdGhlIGlucHV0IHRvIHNlcmlhbGl6ZSBtYXkgYmUgZ2l2ZW4gYXMgYSBET00uCi0gKiA8cD4KLSAqIEZvciBleGFtcGxlOgotICogPHByZT4KLSAqIG9yZy53M2MuZG9tLkRvY3VtZW50ICAgICBpbnB1dERvYzsKLSAqIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplci5TZXJpYWxpemVyICAgc2VyOwotICogamF2YS5pby5Xcml0ZXIgb3dyaXRlcjsKLSAqCi0gKiBqYXZhLnV0aWwuUHJvcGVydGllcyBwcm9wcyA9Ci0gKiAgIE91dHB1dFByb3BlcnRpZXNGYWN0b3J5LmdldERlZmF1bHRNZXRob2RQcm9wZXJ0aWVzKE1ldGhvZC5YTUwpOwotICogU2VyaWFsaXplciBzZXIgPSBTZXJpYWxpemVyRmFjdG9yeS5nZXRTZXJpYWxpemVyKHByb3BzKTsKLSAqIG93cml0ZXIgPSAuLi47ICAvLyBjcmVhdGUgYSB3cml0ZXIgdG8gc2VyaWFsaXplIHRoZSBkb2N1bWVudCB0bwotICogc2VyLnNldFdyaXRlciggb3dyaXRlciApOwotICoKLSAqIGlucHV0RG9jID0gLi4uOyAvLyBjcmVhdGUgdGhlIERPTSBkb2N1bWVudCB0byBiZSBzZXJpYWxpemVkCi0gKiBET01TZXJpYWxpemVyIGRzZXIgPSBzZXIuYXNET01TZXJpYWxpemVyKCk7IC8vIGEgRE9NIHdpbGwgYmUgc2VyaWFsaXplZAotICogZHNlci5zZXJpYWxpemUoaW5wdXREb2MpOyAvLyBzZXJpYWxpemUgdGhlIERPTSwgc2VuZGluZyBvdXRwdXQgdG8gb3dyaXRlcgotICoKLSAqIHNlci5yZXNldCgpOyAvLyBnZXQgcmVhZHkgdG8gdXNlIHRoZSBzZXJpYWxpemVyIGZvciBhbm90aGVyIGRvY3VtZW50Ci0gKiAgICAgICAgICAgICAgLy8gb2YgdGhlIHNhbWUgb3V0cHV0IG1ldGhvZC4KLSAqIDwvcHJlPgotICoKLSAqIFRoaXMgaW50ZXJmYWNlIGlzIGEgcHVibGljIEFQSS4KLSAqCi0gKiBAc2VlIE1ldGhvZAotICogQHNlZSBPdXRwdXRQcm9wZXJ0aWVzRmFjdG9yeQotICogQHNlZSBTZXJpYWxpemVyRmFjdG9yeQotICogQHNlZSBET01TZXJpYWxpemVyCi0gKiBAc2VlIENvbnRlbnRIYW5kbGVyCi0gKgotICogQHhzbC51c2FnZSBnZW5lcmFsCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgU2VyaWFsaXplciB7Ci0KLSAgICAvKioKLSAgICAgKiBTcGVjaWZpZXMgYW4gb3V0cHV0IHN0cmVhbSB0byB3aGljaCB0aGUgZG9jdW1lbnQgc2hvdWxkIGJlCi0gICAgICogc2VyaWFsaXplZC4gVGhpcyBtZXRob2Qgc2hvdWxkIG5vdCBiZSBjYWxsZWQgd2hpbGUgdGhlCi0gICAgICogc2VyaWFsaXplciBpcyBpbiB0aGUgcHJvY2VzcyBvZiBzZXJpYWxpemluZyBhIGRvY3VtZW50LgotICAgICAqIDxwPgotICAgICAqIFRoZSBlbmNvZGluZyBzcGVjaWZpZWQgaW4gdGhlIG91dHB1dCB7QGxpbmsgUHJvcGVydGllc30gaXMgdXNlZCwgb3IKLSAgICAgKiBpZiBubyBlbmNvZGluZyB3YXMgc3BlY2lmaWVkLCB0aGUgZGVmYXVsdCBmb3IgdGhlIHNlbGVjdGVkCi0gICAgICogb3V0cHV0IG1ldGhvZC4KLSAgICAgKiA8cD4KLSAgICAgKiBPbmx5IG9uZSBvZiBzZXRXcml0ZXIoKSBvciBzZXRPdXRwdXRTdHJlYW0oKSBzaG91bGQgYmUgY2FsbGVkLgotICAgICAqCi0gICAgICogQHBhcmFtIG91dHB1dCBUaGUgb3V0cHV0IHN0cmVhbQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldE91dHB1dFN0cmVhbShPdXRwdXRTdHJlYW0gb3V0cHV0KTsKLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgb3V0cHV0IHN0cmVhbSB3aGVyZSB0aGUgZXZlbnRzIHdpbGwgYmUgc2VyaWFsaXplZCB0by4KLSAgICAgKgotICAgICAqIEByZXR1cm4gcmVmZXJlbmNlIHRvIHRoZSByZXN1bHQgc3RyZWFtLCBvciBudWxsIGlmIG9ubHkgYSB3cml0ZXIgd2FzCi0gICAgICogc2V0LgotICAgICAqLwotICAgIHB1YmxpYyBPdXRwdXRTdHJlYW0gZ2V0T3V0cHV0U3RyZWFtKCk7Ci0KLSAgICAvKioKLSAgICAgKiBTcGVjaWZpZXMgYSB3cml0ZXIgdG8gd2hpY2ggdGhlIGRvY3VtZW50IHNob3VsZCBiZSBzZXJpYWxpemVkLgotICAgICAqIFRoaXMgbWV0aG9kIHNob3VsZCBub3QgYmUgY2FsbGVkIHdoaWxlIHRoZSBzZXJpYWxpemVyIGlzIGluCi0gICAgICogdGhlIHByb2Nlc3Mgb2Ygc2VyaWFsaXppbmcgYSBkb2N1bWVudC4KLSAgICAgKiA8cD4KLSAgICAgKiBUaGUgZW5jb2Rpbmcgc3BlY2lmaWVkIGZvciB0aGUgb3V0cHV0IHtAbGluayBQcm9wZXJ0aWVzfSBtdXN0IGJlCi0gICAgICogaWRlbnRpY2FsIHRvIHRoZSBvdXRwdXQgZm9ybWF0IHVzZWQgd2l0aCB0aGUgd3JpdGVyLgotICAgICAqCi0gICAgICogPHA+Ci0gICAgICogT25seSBvbmUgb2Ygc2V0V3JpdGVyKCkgb3Igc2V0T3V0cHV0U3RyZWFtKCkgc2hvdWxkIGJlIGNhbGxlZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSB3cml0ZXIgVGhlIG91dHB1dCB3cml0ZXIgc3RyZWFtCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0V3JpdGVyKFdyaXRlciB3cml0ZXIpOwotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBjaGFyYWN0ZXIgc3RyZWFtIHdoZXJlIHRoZSBldmVudHMgd2lsbCBiZSBzZXJpYWxpemVkIHRvLgotICAgICAqCi0gICAgICogQHJldHVybiBSZWZlcmVuY2UgdG8gdGhlIHJlc3VsdCBXcml0ZXIsIG9yIG51bGwuCi0gICAgICovCi0gICAgcHVibGljIFdyaXRlciBnZXRXcml0ZXIoKTsKLQotICAgIC8qKgotICAgICAqIFNwZWNpZmllcyBhbiBvdXRwdXQgZm9ybWF0IGZvciB0aGlzIHNlcmlhbGl6ZXIuIEl0IHRoZQotICAgICAqIHNlcmlhbGl6ZXIgaGFzIGFscmVhZHkgYmVlbiBhc3NvY2lhdGVkIHdpdGggYW4gb3V0cHV0IGZvcm1hdCwKLSAgICAgKiBpdCB3aWxsIHN3aXRjaCB0byB0aGUgbmV3IGZvcm1hdC4gVGhpcyBtZXRob2Qgc2hvdWxkIG5vdCBiZQotICAgICAqIGNhbGxlZCB3aGlsZSB0aGUgc2VyaWFsaXplciBpcyBpbiB0aGUgcHJvY2VzcyBvZiBzZXJpYWxpemluZwotICAgICAqIGEgZG9jdW1lbnQuCi0gICAgICogPHA+Ci0gICAgICogVGhlIHN0YW5kYXJkIHByb3BlcnR5IGtleXMgc3VwcG9ydGVkIGFyZTogIm1ldGhvZCIsICJ2ZXJzaW9uIiwgImVuY29kaW5nIiwKLSAgICAgKiAib21pdC14bWwtZGVjbGFyYXRpb24iLCAic3RhbmRhbG9uZSIsIGRvY3R5cGUtcHVibGljIiwKLSAgICAgKiAiZG9jdHlwZS1zeXN0ZW0iLCAiY2RhdGEtc2VjdGlvbi1lbGVtZW50cyIsICJpbmRlbnQiLCAibWVkaWEtdHlwZSIuCi0gICAgICogVGhlc2UgcHJvcGVydHkga2V5cyBhbmQgdGhlaXIgdmFsdWVzIGFyZSBkZXNjcmliZWQgaW4gdGhlIFhTTFQgcmVjb21tZW5kYXRpb24sCi0gICAgICogc2VlIHtAbGluayA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk5L1JFQy14c2x0LTE5OTkxMTE2Ij4gWFNMVCAxLjAgcmVjb21tZW5kYXRpb248L2E+fQotICAgICAqIDxwPgotICAgICAqIFRoZSBub24tc3RhbmRhcmQgcHJvcGVydHkga2V5cyBzdXBwb3J0ZWQgYXJlIGRlZmluZWQgaW4ge0BsaW5rIE91dHB1dFByb3BlcnRpZXNGYWN0b3J5fS4KLSAgICAgKgotICAgICAqIDxwPgotICAgICAqIFRoaXMgbWV0aG9kIGNhbiBiZSBjYWxsZWQgbXVsdGlwbGUgdGltZXMgYmVmb3JlIGEgZG9jdW1lbnQgaXMgc2VyaWFsaXplZC4gRWFjaAotICAgICAqIHRpbWUgaXQgaXMgY2FsbGVkIG1vcmUsIG9yIG92ZXItcmlkaW5nIHByb3BlcnR5IHZhbHVlcywgY2FuIGJlIHNwZWNpZmllZC4gT25lCi0gICAgICogcHJvcGVydHkgdmFsdWUgdGhhdCBjYW4gbm90IGJlIGNoYW5nZWQgaXMgdGhhdCBvZiB0aGUgIm1ldGhvZCIgcHJvcGVydHkga2V5LgotICAgICAqIDxwPgotICAgICAqIFRoZSB2YWx1ZSBvZiB0aGUgImNkYXRhLXNlY3Rpb24tZWxlbWVudHMiIHByb3BlcnR5IGtleSBpcyBhIHdoaXRlc3BhY2UKLSAgICAgKiBzZXBhcmF0ZWQgbGlzdCBvZiBlbGVtZW50cy4gSWYgdGhlIGVsZW1lbnQgaXMgaW4gYSBuYW1lc3BhY2UgdGhlbgotICAgICAqIHZhbHVlIGlzIHBhc3NlZCBpbiB0aGlzIGZvcm1hdDoge3VyaX1sb2NhbE5hbWUKLSAgICAgKiA8cD4KLSAgICAgKiBJZiB0aGUgImNkYXRhLXNlY3Rpb24tZWxlbWVudHMiIGtleSBpcyBzcGVjaWZpZWQgb24gbXVsdGlwbGUgY2FsbHMKLSAgICAgKiB0byB0aGlzIG1ldGhvZCB0aGUgc2V0IG9mIGVsZW1lbnRzIHNwZWNpZmllZCBpbiB0aGUgdmFsdWUKLSAgICAgKiBpcyBub3QgcmVwbGFjZWQgZnJvbSBvbmUgY2FsbCB0byB0aGUKLSAgICAgKiBuZXh0LCBidXQgaXQgaXMgY3VtdWxhdGl2ZSBhY3Jvc3MgdGhlIGNhbGxzLgotICAgICAqCi0gICAgICogQHBhcmFtIGZvcm1hdCBUaGUgb3V0cHV0IGZvcm1hdCB0byB1c2UsIGFzIGEgc2V0IG9mIGtleS92YWx1ZSBwYWlycy4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRPdXRwdXRGb3JtYXQoUHJvcGVydGllcyBmb3JtYXQpOwotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgb3V0cHV0IGZvcm1hdCBwcm9wZXJ0aWVzIGZvciB0aGlzIHNlcmlhbGl6ZXIuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBvdXRwdXQgZm9ybWF0IGtleS92YWx1ZSBwYWlycyBpbiB1c2UuCi0gICAgICovCi0gICAgcHVibGljIFByb3BlcnRpZXMgZ2V0T3V0cHV0Rm9ybWF0KCk7Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gYSB7QGxpbmsgQ29udGVudEhhbmRsZXJ9IGludGVyZmFjZSB0byBwcm92aWRlIFNBWCBpbnB1dCB0by4KLSAgICAgKiBUaHJvdWdoIHRoZSByZXR1cm5lZCBvYmplY3QgdGhlIGRvY3VtZW50IHRvIGJlIHNlcmFpbGl6ZWQsCi0gICAgICogYXMgYSBzZXJpZXMgb2YgU0FYIGV2ZW50cywgY2FuIGJlIHByb3ZpZGVkIHRvIHRoZSBzZXJpYWx6aWVyLgotICAgICAqIElmIHRoZSBzZXJpYWxpemVyIGRvZXMgbm90IHN1cHBvcnQgdGhlIHtAbGluayBDb250ZW50SGFuZGxlcn0KLSAgICAgKiBpbnRlcmZhY2UsIGl0IHdpbGwgcmV0dXJuIG51bGwuCi0gICAgICogPHA+Ci0gICAgICogSW4gcHJpbmNpcGxlIG9ubHkgb25lIG9mIGFzRE9NU2VyaWFsaXplcigpIG9yIGFzQ29udGVudEhhbmRlcigpCi0gICAgICogc2hvdWxkIGJlIGNhbGxlZC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gQSB7QGxpbmsgQ29udGVudEhhbmRsZXJ9IGludGVyZmFjZSBpbnRvIHRoaXMgc2VyaWFsaXplciwKLSAgICAgKiAgb3IgbnVsbCBpZiB0aGUgc2VyaWFsaXplciBpcyBub3QgU0FYIDIgY2FwYWJsZQotICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gQW4gSS9PIGV4Y2VwdGlvbiBvY2N1cmVkCi0gICAgICovCi0gICAgcHVibGljIENvbnRlbnRIYW5kbGVyIGFzQ29udGVudEhhbmRsZXIoKSB0aHJvd3MgSU9FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gYSB7QGxpbmsgRE9NU2VyaWFsaXplcn0gaW50ZXJmYWNlIGludG8gdGhpcyBzZXJpYWxpemVyLgotICAgICAqIFRocm91Z2ggdGhlIHJldHVybmVkIG9iamVjdCB0aGUgZG9jdW1lbnQgdG8gYmUgc2VyaWFsaXplZCwKLSAgICAgKiBhIERPTSwgY2FuIGJlIHByb3ZpZGVkIHRvIHRoZSBzZXJpYWxpemVyLgotICAgICAqIElmIHRoZSBzZXJpYWxpemVyIGRvZXMgbm90IHN1cHBvcnQgdGhlIHtAbGluayBET01TZXJpYWxpemVyfQotICAgICAqIGludGVyZmFjZSwgaXQgc2hvdWxkIHJldHVybiBudWxsLgotICAgICAqIDxwPgotICAgICAqIEluIHByaW5jaXBsZSBvbmx5IG9uZSBvZiBhc0RPTVNlcmlhbGl6ZXIoKSBvciBhc0NvbnRlbnRIYW5kZXIoKQotICAgICAqIHNob3VsZCBiZSBjYWxsZWQuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIEEge0BsaW5rIERPTVNlcmlhbGl6ZXJ9IGludGVyZmFjZSBpbnRvIHRoaXMgc2VyaWFsaXplciwKLSAgICAgKiAgb3IgbnVsbCBpZiB0aGUgc2VyaWFsaXplciBpcyBub3QgRE9NIGNhcGFibGUKLSAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIEFuIEkvTyBleGNlcHRpb24gb2NjdXJlZAotICAgICAqLwotICAgIHB1YmxpYyBET01TZXJpYWxpemVyIGFzRE9NU2VyaWFsaXplcigpIHRocm93cyBJT0V4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIHJlc2V0cyB0aGUgc2VyaWFsaXplci4KLSAgICAgKiBJZiB0aGlzIG1ldGhvZCByZXR1cm5zIHRydWUsIHRoZQotICAgICAqIHNlcmlhbGl6ZXIgbWF5IGJlIHVzZWQgZm9yIHN1YnNlcXVlbnQgc2VyaWFsaXphdGlvbiBvZiBuZXcKLSAgICAgKiBkb2N1bWVudHMuIEl0IGlzIHBvc3NpYmxlIHRvIGNoYW5nZSB0aGUgb3V0cHV0IGZvcm1hdCBhbmQKLSAgICAgKiBvdXRwdXQgc3RyZWFtIHByaW9yIHRvIHNlcmlhbGl6aW5nLCBvciB0byByZXVzZSB0aGUgZXhpc3RpbmcKLSAgICAgKiBvdXRwdXQgZm9ybWF0IGFuZCBvdXRwdXQgc3RyZWFtIG9yIHdyaXRlci4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVHJ1ZSBpZiBzZXJpYWxpemVyIGhhcyBiZWVuIHJlc2V0IGFuZCBjYW4gYmUgcmV1c2VkCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gcmVzZXQoKTsKLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXplckJhc2UuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXplckJhc2UuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYTQ3Nzg5MC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6ZXJCYXNlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNDAyICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFNlcmlhbGl6ZXJCYXNlLmphdmEsdiAxLjUgMjAwNi8wNC8xNCAxMjowOToxOSBzdW5pdGhhcmVkZHkgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXI7Ci0KLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlNvdXJjZUxvY2F0b3I7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplci51dGlscy5Nc2dLZXk7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyLnV0aWxzLlV0aWxzOwotaW1wb3J0IG9yZy54bWwuc2F4LkF0dHJpYnV0ZXM7Ci1pbXBvcnQgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguTG9jYXRvcjsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguZXh0LkxvY2F0b3IyOwotCi0KLS8qKgotICogVGhpcyBjbGFzcyBhY3RzIGFzIGEgYmFzZSBjbGFzcyBmb3IgdGhlIFhNTCAic2VyaWFsaXplcnMiCi0gKiBhbmQgdGhlIHN0cmVhbSBzZXJpYWxpemVycy4KLSAqIEl0IGNvbnRhaW5zIGEgbnVtYmVyIG9mIGNvbW1vbiBmaWVsZHMgYW5kIG1ldGhvZHMuCi0gKgotICogQHhzbC51c2FnZSBpbnRlcm5hbAotICovCi1wdWJsaWMgYWJzdHJhY3QgY2xhc3MgU2VyaWFsaXplckJhc2UKLSAgICBpbXBsZW1lbnRzIFNlcmlhbGl6YXRpb25IYW5kbGVyLCBTZXJpYWxpemVyQ29uc3RhbnRzCi17Ci0KLQotICAgIC8qKgotICAgICAqIFRvIGZpcmUgb2ZmIHRoZSBlbmQgZWxlbWVudCB0cmFjZSBldmVudAotICAgICAqIEBwYXJhbSBuYW1lIE5hbWUgb2YgZWxlbWVudAotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIGZpcmVFbmRFbGVtKFN0cmluZyBuYW1lKQotICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAobV90cmFjZXIgIT0gbnVsbCkKLSAgICAgICAgewotICAgICAgICAgICAgZmx1c2hNeVdyaXRlcigpOwotICAgICAgICAgICAgbV90cmFjZXIuZmlyZUdlbmVyYXRlRXZlbnQoU2VyaWFsaXplclRyYWNlLkVWRU5UVFlQRV9FTkRFTEVNRU5ULG5hbWUsIChBdHRyaWJ1dGVzKW51bGwpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmVwb3J0IHRoZSBjaGFyYWN0ZXJzIHRyYWNlIGV2ZW50Ci0gICAgICogQHBhcmFtIGNoYXJzICBjb250ZW50IG9mIGNoYXJhY3RlcnMKLSAgICAgKiBAcGFyYW0gc3RhcnQgIHN0YXJ0aW5nIGluZGV4IG9mIGNoYXJhY3RlcnMgdG8gb3V0cHV0Ci0gICAgICogQHBhcmFtIGxlbmd0aCAgbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gb3V0cHV0Ci0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgZmlyZUNoYXJFdmVudChjaGFyW10gY2hhcnMsIGludCBzdGFydCwgaW50IGxlbmd0aCkKLSAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaWYgKG1fdHJhY2VyICE9IG51bGwpCi0gICAgICAgIHsKLSAgICAgICAgICAgIGZsdXNoTXlXcml0ZXIoKTsKLSAgICAgICAgICAgIG1fdHJhY2VyLmZpcmVHZW5lcmF0ZUV2ZW50KFNlcmlhbGl6ZXJUcmFjZS5FVkVOVFRZUEVfQ0hBUkFDVEVSUywgY2hhcnMsIHN0YXJ0LGxlbmd0aCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiB0cnVlIGlmIHdlIHN0aWxsIG5lZWQgdG8gY2FsbCBzdGFydERvY3VtZW50SW50ZXJuYWwoKQotICAgICAgICAgKi8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBtX25lZWRUb0NhbGxTdGFydERvY3VtZW50ID0gdHJ1ZTsKLQotICAgIC8qKiBUcnVlIGlmIGEgdHJhaWxpbmcgIl1dPiIgc3RpbGwgbmVlZHMgdG8gYmUgd3JpdHRlbiB0byBiZQotICAgICAqIHdyaXR0ZW4gb3V0LiBVc2VkIHRvIG1lcmdlIGFkamFjZW50IENEQVRBIHNlY3Rpb25zCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gbV9jZGF0YVRhZ09wZW4gPSBmYWxzZTsKLQotICAgIC8qKgotICAgICAqIEFsbCB0aGUgYXR0cmlidXRlcyBvZiB0aGUgY3VycmVudCBlbGVtZW50LCBjb2xsZWN0ZWQgZnJvbQotICAgICAqIHN0YXJ0UHJlZml4TWFwcGluZygpIGNhbGxzLCBvciBhZGRBZGR0cmlidXRlKCkgY2FsbHMsIG9yCi0gICAgICogZnJvbSB0aGUgU0FYIGF0dHJpYnV0ZXMgaW4gYSBzdGFydEVsZW1lbnQoKSBjYWxsLgotICAgICAqLwotICAgIHByb3RlY3RlZCBBdHRyaWJ1dGVzSW1wbFNlcmlhbGl6ZXIgbV9hdHRyaWJ1dGVzID0gbmV3IEF0dHJpYnV0ZXNJbXBsU2VyaWFsaXplcigpOwotCi0gICAgLyoqCi0gICAgICogVGVsbHMgaWYgd2UncmUgaW4gYW4gRW50aXR5UmVmIGV2ZW50LgotICAgICAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIG1faW5FbnRpdHlSZWYgPSBmYWxzZTsKLQotICAgIC8qKiBUaGlzIGZsYWcgaXMgc2V0IHdoaWxlIHJlY2VpdmluZyBldmVudHMgZnJvbSB0aGUgZXh0ZXJuYWwgRFREICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gbV9pbkV4dGVybmFsRFREID0gZmFsc2U7Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgU3lzdGVtIElEIGZvciB0aGUgZG9jIHR5cGUuCi0gICAgICovCi0gICAgcHJpdmF0ZSBTdHJpbmcgbV9kb2N0eXBlU3lzdGVtOwotCi0gICAgLyoqCi0gICAgICogVGhlIHB1YmxpYyBJRCBmb3IgdGhlIGRvYyB0eXBlLgotICAgICAqLwotICAgIHByaXZhdGUgU3RyaW5nIG1fZG9jdHlwZVB1YmxpYzsKLQotICAgIC8qKgotICAgICAqIEZsYWcgdG8gdGVsbCB0aGF0IHdlIG5lZWQgdG8gYWRkIHRoZSBkb2N0eXBlIGRlY2wsIHdoaWNoIHdlIGNhbid0IGRvCi0gICAgICogdW50aWwgdGhlIGZpcnN0IGVsZW1lbnQgaXMgZW5jb3VudGVyZWQuCi0gICAgICovCi0gICAgYm9vbGVhbiBtX25lZWRUb091dHB1dERvY1R5cGVEZWNsID0gdHJ1ZTsKLQotICAgIC8qKgotICAgICAqIFRoZSBjaGFyYWN0ZXIgZW5jb2RpbmcuICBNdXN0IG1hdGNoIHRoZSBlbmNvZGluZyB1c2VkIGZvciB0aGUKLSAgICAgKiBwcmludFdyaXRlci4KLSAgICAgKi8KLSAgICBwcml2YXRlIFN0cmluZyBtX2VuY29kaW5nID0gbnVsbDsKLQotICAgIC8qKgotICAgICAqIFRlbGxzIGlmIHdlIHNob3VsZCB3cml0ZSB0aGUgWE1MIGRlY2xhcmF0aW9uLgotICAgICAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBtX3Nob3VsZE5vdFdyaXRlWE1MSGVhZGVyID0gZmFsc2U7Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgc3RhbmRhbG9uZSB2YWx1ZSBmb3IgdGhlIGRvY3R5cGUuCi0gICAgICovCi0gICAgcHJpdmF0ZSBTdHJpbmcgbV9zdGFuZGFsb25lOwotCi0gICAgLyoqCi0gICAgICogVHJ1ZSBpZiBzdGFuZGFsb25lIHdhcyBzcGVjaWZpZWQuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gbV9zdGFuZGFsb25lV2FzU3BlY2lmaWVkID0gZmFsc2U7Ci0KLSAgICAvKioKLSAgICAgKiBEZXRlcm1pbmUgaWYgdGhlIG91dHB1dCBpcyBhIHN0YW5kYWxvbmUuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gbV9pc1N0YW5kYWxvbmUgPSBmYWxzZTsKLQotICAgIC8qKgotICAgICAqIEZsYWcgdG8gdGVsbCBpZiBpbmRlbnRpbmcgKHByZXR0eS1wcmludGluZykgaXMgb24uCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gbV9kb0luZGVudCA9IGZhbHNlOwotICAgIC8qKgotICAgICAqIEFtb3VudCB0byBpbmRlbnQuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGludCBtX2luZGVudEFtb3VudCA9IDA7Ci0KLSAgICAvKioKLSAgICAgKiBUZWxscyB0aGUgWE1MIHZlcnNpb24sIGZvciB3cml0aW5nIG91dCB0byB0aGUgWE1MIGRlY2wuCi0gICAgICovCi0gICAgcHJpdmF0ZSBTdHJpbmcgbV92ZXJzaW9uID0gbnVsbDsKLQotICAgIC8qKgotICAgICAqIFRoZSBtZWRpYXR5cGUuICBOb3QgdXNlZCByaWdodCBub3cuCi0gICAgICovCi0gICAgcHJpdmF0ZSBTdHJpbmcgbV9tZWRpYXR5cGU7Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgdHJhbnNmb3JtZXIgdGhhdCB3YXMgYXJvdW5kIHdoZW4gdGhpcyBvdXRwdXQgaGFuZGxlciB3YXMgY3JlYXRlZCAoaWYKLSAgICAgKiBhbnkpLgotICAgICAqLwotICAgIHByaXZhdGUgVHJhbnNmb3JtZXIgbV90cmFuc2Zvcm1lcjsKLQotICAgIC8qKgotICAgICAqIFBhaXJzIG9mIGxvY2FsIG5hbWVzIGFuZCBjb3JyZXNwb25kaW5nIFVSSXMgb2YgQ0RBVEEgc2VjdGlvbnMuIFRoaXMgbGlzdAotICAgICAqIGNvbWVzIGZyb20gdGhlIGNkYXRhLXNlY3Rpb24tZWxlbWVudHMgYXR0cmlidXRlLiBFdmVyeSBzZWNvbmQgb25lIGlzIGEKLSAgICAgKiBsb2NhbCBuYW1lLCBhbmQgZXZlcnkgb3RoZXIgc2Vjb25kIG9uZSBpcyB0aGUgVVJJIGZvciB0aGUgbG9jYWwgbmFtZS4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgVmVjdG9yIG1fY2RhdGFTZWN0aW9uRWxlbWVudHMgPSBudWxsOwotCi0gICAgLyoqCi0gICAgICogTmFtZXNwYWNlIHN1cHBvcnQsIHRoYXQga2VlcHMgdHJhY2sgb2YgY3VycmVudGx5IGRlZmluZWQKLSAgICAgKiBwcmVmaXgvdXJpIG1hcHBpbmdzLiBBcyBwcm9jZXNzZWQgZWxlbWVudHMgY29tZSBhbmQgZ28sIHNvIGRvCi0gICAgICogdGhlIGFzc29jaWF0ZWQgbWFwcGluZ3MgZm9yIHRoYXQgZWxlbWVudC4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgTmFtZXNwYWNlTWFwcGluZ3MgbV9wcmVmaXhNYXA7Ci0KLSAgICAvKioKLSAgICAgKiBIYW5kbGUgZm9yIGZpcmluZyBnZW5lcmF0ZSBldmVudHMuICBUaGlzIGludGVyZmFjZSBtYXkgYmUgaW1wbGVtZW50ZWQKLSAgICAgKiBieSB0aGUgcmVmZXJlbmNlZCB0cmFuc2Zvcm1lciBvYmplY3QuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIFNlcmlhbGl6ZXJUcmFjZSBtX3RyYWNlcjsKLQotICAgIHByb3RlY3RlZCBTb3VyY2VMb2NhdG9yIG1fc291cmNlTG9jYXRvcjsKLQotCi0gICAgLyoqCi0gICAgICogVGhlIHdyaXRlciB0byBzZW5kIG91dHB1dCB0by4gVGhpcyBmaWVsZCBpcyBvbmx5IHVzZWQgaW4gdGhlIFRvU3RyZWFtCi0gICAgICogc2VyaWFsaXplcnMsIGJ1dCBleGlzdHMgaGVyZSBqdXN0IHNvIHRoYXQgdGhlIGZpcmVTdGFydERvYygpIGFuZAotICAgICAqIG90aGVyIGZpcmUuLi4gbWV0aG9kcyBjYW4gZmx1c2ggdGhpcyB3cml0ZXIgd2hlbiB0cmFjaW5nLgotICAgICAqLwotICAgIHByb3RlY3RlZCBqYXZhLmlvLldyaXRlciBtX3dyaXRlciA9IG51bGw7Ci0KLSAgICAvKioKLSAgICAgKiBBIHJlZmVyZW5jZSB0byAic3RhY2sgZnJhbWUiIGNvcnJlc3BvbmRpbmcgdG8KLSAgICAgKiB0aGUgY3VycmVudCBlbGVtZW50LiBTdWNoIGEgZnJhbWUgaXMgcHVzaGVkIGF0IGEgc3RhcnRFbGVtZW50KCkKLSAgICAgKiBhbmQgcG9wcGVkIGF0IGFuIGVuZEVsZW1lbnQoKS4gVGhpcyBmcmFtZSBjb250YWlucyBpbmZvcm1hdGlvbiBhYm91dAotICAgICAqIHRoZSBlbGVtZW50LCBzdWNoIGFzIGl0cyBuYW1lc3BhY2UgVVJJLgotICAgICAqLwotICAgIHByb3RlY3RlZCBFbGVtQ29udGV4dCBtX2VsZW1Db250ZXh0ID0gbmV3IEVsZW1Db250ZXh0KCk7Ci0KLSAgICAvKioKLSAgICAgKiBBIHV0aWxpdHkgYnVmZmVyIGZvciBjb252ZXJ0aW5nIFN0cmluZ3MgcGFzc2VkIHRvCi0gICAgICogY2hhcmFjdGVyKCkgbWV0aG9kcyB0byBjaGFyYWN0ZXIgYXJyYXlzLgotICAgICAqIFJldXNpbmcgdGhpcyBidWZmZXIgbWVhbnMgbm90IGNyZWF0aW5nIGEgbmV3IGNoYXJhY3RlciBhcnJheQotICAgICAqIGV2ZXJ5dGltZSBhbmQgaXQgcnVucyBmYXN0ZXIuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGNoYXJbXSBtX2NoYXJzQnVmZiA9IG5ldyBjaGFyWzYwXTsKLQotICAgIC8qKgotICAgICAqIEEgdXRpbGl0eSBidWZmZXIgZm9yIGNvbnZlcnRpbmcgU3RyaW5ncyBwYXNzZWQgdG8KLSAgICAgKiBhdHRyaWJ1dGUgbWV0aG9kcyB0byBjaGFyYWN0ZXIgYXJyYXlzLgotICAgICAqIFJldXNpbmcgdGhpcyBidWZmZXIgbWVhbnMgbm90IGNyZWF0aW5nIGEgbmV3IGNoYXJhY3RlciBhcnJheQotICAgICAqIGV2ZXJ5dGltZSBhbmQgaXQgcnVucyBmYXN0ZXIuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGNoYXJbXSBtX2F0dHJCdWZmID0gbmV3IGNoYXJbMzBdOwotCi0gICAgcHJpdmF0ZSBMb2NhdG9yIG1fbG9jYXRvciA9IG51bGw7Ci0KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBtX25lZWRUb0NhbGxTZXREb2N1bWVudEluZm8gPSB0cnVlOwotCi0gICAgLyoqCi0gICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgYSBjb21tZW50LgotICAgICAqCi0gICAgICogQHNlZSBFeHRlbmRlZExleGljYWxIYW5kbGVyI2NvbW1lbnQoU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGNvbW1lbnQoU3RyaW5nIGRhdGEpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGZpbmFsIGludCBsZW5ndGggPSBkYXRhLmxlbmd0aCgpOwotICAgICAgICBpZiAobGVuZ3RoID4gbV9jaGFyc0J1ZmYubGVuZ3RoKQotICAgICAgICB7Ci0gICAgICAgICAgICBtX2NoYXJzQnVmZiA9IG5ldyBjaGFyW2xlbmd0aCAqIDIgKyAxXTsKLSAgICAgICAgfQotICAgICAgICBkYXRhLmdldENoYXJzKDAsIGxlbmd0aCwgbV9jaGFyc0J1ZmYsIDApOwotICAgICAgICBjb21tZW50KG1fY2hhcnNCdWZmLCAwLCBsZW5ndGgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIElmIGF0IHJ1bnRpbWUsIHdoZW4gdGhlIHFuYW1lIG9mIHRoZSBhdHRyaWJ1dGUgaXMKLSAgICAgKiBrbm93biwgYW5vdGhlciBwcmVmaXggaXMgc3BlY2lmaWVkIGZvciB0aGUgYXR0cmlidXRlLCB0aGVuIHdlIGNhbgotICAgICAqIHBhdGNoIG9yIGhhY2sgdGhlIG5hbWUgd2l0aCB0aGlzIG1ldGhvZC4gRm9yCi0gICAgICogYSBxbmFtZSBvZiB0aGUgZm9ybSAibnM/Om90aGVycHJlZml4Om5hbWUiLCB0aGlzIGZ1bmN0aW9uIHBhdGNoZXMgdGhlCi0gICAgICogcW5hbWUgYnkgc2ltcGx5IGlnbm9yaW5nICJvdGhlcnByZWZpeCIuCi0gICAgICogVE9ETzogVGhpcyBtZXRob2QgaXMgYSBIQUNLISBXZSBkbyBub3QgaGF2ZSBhY2Nlc3MgdG8gdGhlCi0gICAgICogWE1MIGZpbGUsIGl0IHNvbWV0aW1lcyBnZW5lcmF0ZXMgYSBOUyBwcmVmaXggb2YgdGhlIGZvcm0gIm5zPyIgZm9yCi0gICAgICogYW4gYXR0cmlidXRlLgotICAgICAqLwotICAgIHByb3RlY3RlZCBTdHJpbmcgcGF0Y2hOYW1lKFN0cmluZyBxbmFtZSkKLSAgICB7Ci0KLQotICAgICAgICBmaW5hbCBpbnQgbGFzdENvbG9uID0gcW5hbWUubGFzdEluZGV4T2YoJzonKTsKLQotICAgICAgICBpZiAobGFzdENvbG9uID4gMCkgewotICAgICAgICAgICAgZmluYWwgaW50IGZpcnN0Q29sb24gPSBxbmFtZS5pbmRleE9mKCc6Jyk7Ci0gICAgICAgICAgICBmaW5hbCBTdHJpbmcgcHJlZml4ID0gcW5hbWUuc3Vic3RyaW5nKDAsIGZpcnN0Q29sb24pOwotICAgICAgICAgICAgZmluYWwgU3RyaW5nIGxvY2FsTmFtZSA9IHFuYW1lLnN1YnN0cmluZyhsYXN0Q29sb24gKyAxKTsKLQotICAgICAgICAvLyBJZiB1cmkgaXMgIiIgdGhlbiBpZ25vcmUgcHJlZml4Ci0gICAgICAgICAgICBmaW5hbCBTdHJpbmcgdXJpID0gbV9wcmVmaXhNYXAubG9va3VwTmFtZXNwYWNlKHByZWZpeCk7Ci0gICAgICAgICAgICBpZiAodXJpICE9IG51bGwgJiYgdXJpLmxlbmd0aCgpID09IDApIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gbG9jYWxOYW1lOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoZmlyc3RDb2xvbiAhPSBsYXN0Q29sb24pIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gcHJlZml4ICsgJzonICsgbG9jYWxOYW1lOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBxbmFtZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBsb2NhbCBuYW1lIG9mIGEgcXVhbGlmaWVkIG5hbWUuIElmIHRoZSBuYW1lIGhhcyBubyBwcmVmaXgsCi0gICAgICogdGhlbiBpdCB3b3JrcyBhcyB0aGUgaWRlbnRpdHkgKFNBWDIpLgotICAgICAqIEBwYXJhbSBxbmFtZSB0aGUgcXVhbGlmaWVkIG5hbWUKLSAgICAgKiBAcmV0dXJuIHRoZSBuYW1lLCBidXQgZXhjbHVkaW5nIGFueSBwcmVmaXggYW5kIGNvbG9uLgotICAgICAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgU3RyaW5nIGdldExvY2FsTmFtZShTdHJpbmcgcW5hbWUpCi0gICAgewotICAgICAgICBmaW5hbCBpbnQgY29sID0gcW5hbWUubGFzdEluZGV4T2YoJzonKTsKLSAgICAgICAgcmV0dXJuIChjb2wgPiAwKSA/IHFuYW1lLnN1YnN0cmluZyhjb2wgKyAxKSA6IHFuYW1lOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJlY2VpdmUgYW4gb2JqZWN0IGZvciBsb2NhdGluZyB0aGUgb3JpZ2luIG9mIFNBWCBkb2N1bWVudCBldmVudHMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbG9jYXRvciBBbiBvYmplY3QgdGhhdCBjYW4gcmV0dXJuIHRoZSBsb2NhdGlvbiBvZiBhbnkgU0FYIGRvY3VtZW50Ci0gICAgICogZXZlbnQuCi0gICAgICoKLSAgICAgKiBSZWNlaXZlIGFuIG9iamVjdCBmb3IgbG9jYXRpbmcgdGhlIG9yaWdpbiBvZiBTQVggZG9jdW1lbnQgZXZlbnRzLgotICAgICAqCi0gICAgICogPHA+U0FYIHBhcnNlcnMgYXJlIHN0cm9uZ2x5IGVuY291cmFnZWQgKHRob3VnaCBub3QgYWJzb2x1dGVseQotICAgICAqIHJlcXVpcmVkKSB0byBzdXBwbHkgYSBsb2NhdG9yOiBpZiBpdCBkb2VzIHNvLCBpdCBtdXN0IHN1cHBseQotICAgICAqIHRoZSBsb2NhdG9yIHRvIHRoZSBhcHBsaWNhdGlvbiBieSBpbnZva2luZyB0aGlzIG1ldGhvZCBiZWZvcmUKLSAgICAgKiBpbnZva2luZyBhbnkgb2YgdGhlIG90aGVyIG1ldGhvZHMgaW4gdGhlIERvY3VtZW50SGFuZGxlcgotICAgICAqIGludGVyZmFjZS48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5UaGUgbG9jYXRvciBhbGxvd3MgdGhlIGFwcGxpY2F0aW9uIHRvIGRldGVybWluZSB0aGUgZW5kCi0gICAgICogcG9zaXRpb24gb2YgYW55IGRvY3VtZW50LXJlbGF0ZWQgZXZlbnQsIGV2ZW4gaWYgdGhlIHBhcnNlciBpcwotICAgICAqIG5vdCByZXBvcnRpbmcgYW4gZXJyb3IuICBUeXBpY2FsbHksIHRoZSBhcHBsaWNhdGlvbiB3aWxsCi0gICAgICogdXNlIHRoaXMgaW5mb3JtYXRpb24gZm9yIHJlcG9ydGluZyBpdHMgb3duIGVycm9ycyAoc3VjaCBhcwotICAgICAqIGNoYXJhY3RlciBjb250ZW50IHRoYXQgZG9lcyBub3QgbWF0Y2ggYW4gYXBwbGljYXRpb24ncwotICAgICAqIGJ1c2luZXNzIHJ1bGVzKS4gIFRoZSBpbmZvcm1hdGlvbiByZXR1cm5lZCBieSB0aGUgbG9jYXRvcgotICAgICAqIGlzIHByb2JhYmx5IG5vdCBzdWZmaWNpZW50IGZvciB1c2Ugd2l0aCBhIHNlYXJjaCBlbmdpbmUuPC9wPgotICAgICAqCi0gICAgICogPHA+Tm90ZSB0aGF0IHRoZSBsb2NhdG9yIHdpbGwgcmV0dXJuIGNvcnJlY3QgaW5mb3JtYXRpb24gb25seQotICAgICAqIGR1cmluZyB0aGUgaW52b2NhdGlvbiBvZiB0aGUgZXZlbnRzIGluIHRoaXMgaW50ZXJmYWNlLiAgVGhlCi0gICAgICogYXBwbGljYXRpb24gc2hvdWxkIG5vdCBhdHRlbXB0IHRvIHVzZSBpdCBhdCBhbnkgb3RoZXIgdGltZS48L3A+Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RG9jdW1lbnRMb2NhdG9yKExvY2F0b3IgbG9jYXRvcikKLSAgICB7Ci0gICAgICAgIG1fbG9jYXRvciA9IGxvY2F0b3I7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQWRkcyB0aGUgZ2l2ZW4gYXR0cmlidXRlIHRvIHRoZSBzZXQgb2YgY29sbGVjdGVkIGF0dHJpYnV0ZXMgLCBidXQgb25seSBpZgotICAgICAqIHRoZXJlIGlzIGEgY3VycmVudGx5IG9wZW4gZWxlbWVudC4KLSAgICAgKgotICAgICAqIEFuIGVsZW1lbnQgaXMgY3VycmVudGx5IG9wZW4gaWYgYSBzdGFydEVsZW1lbnQoKSBub3RpZmljYXRpb24gaGFzCi0gICAgICogb2NjdXJlZCBidXQgdGhlIHN0YXJ0IG9mIHRoZSBlbGVtZW50IGhhcyBub3QgeWV0IGJlZW4gd3JpdHRlbiB0byB0aGUKLSAgICAgKiBvdXRwdXQuICBJbiB0aGUgc3RyZWFtIGNhc2UgdGhpcyBtZWFucyB0aGF0IHdlIGhhdmUgbm90IHlldCBiZWVuIGZvcmNlZAotICAgICAqIHRvIGNsb3NlIHRoZSBlbGVtZW50cyBvcGVuaW5nIHRhZyBieSBhbm90aGVyIG5vdGlmaWNhdGlvbiwgc3VjaCBhcyBhCi0gICAgICogY2hhcmFjdGVyIG5vdGlmaWNhdGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSB1cmkgdGhlIFVSSSBvZiB0aGUgYXR0cmlidXRlCi0gICAgICogQHBhcmFtIGxvY2FsTmFtZSB0aGUgbG9jYWwgbmFtZSBvZiB0aGUgYXR0cmlidXRlCi0gICAgICogQHBhcmFtIHJhd05hbWUgICAgdGhlIHF1YWxpZmllZCBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUKLSAgICAgKiBAcGFyYW0gdHlwZSB0aGUgdHlwZSBvZiB0aGUgYXR0cmlidXRlIChwcm9iYWJseSBDREFUQSkKLSAgICAgKiBAcGFyYW0gdmFsdWUgdGhlIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUKLSAgICAgKiBAcGFyYW0gWFNMQXR0cmlidXRlIHRydWUgaWYgdGhpcyBhdHRyaWJ1dGUgaXMgY29taW5nIGZyb20gYW4geHNsOmF0dHJpdXRlIGVsZW1lbnQKLSAgICAgKiBAc2VlIEV4dGVuZGVkQ29udGVudEhhbmRsZXIjYWRkQXR0cmlidXRlKFN0cmluZywgU3RyaW5nLCBTdHJpbmcsIFN0cmluZywgU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGFkZEF0dHJpYnV0ZSgKLSAgICAgICAgU3RyaW5nIHVyaSwKLSAgICAgICAgU3RyaW5nIGxvY2FsTmFtZSwKLSAgICAgICAgU3RyaW5nIHJhd05hbWUsCi0gICAgICAgIFN0cmluZyB0eXBlLAotICAgICAgICBTdHJpbmcgdmFsdWUsCi0gICAgICAgIGJvb2xlYW4gWFNMQXR0cmlidXRlKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAobV9lbGVtQ29udGV4dC5tX3N0YXJ0VGFnT3BlbikKLSAgICAgICAgewotICAgICAgICAgICAgYWRkQXR0cmlidXRlQWx3YXlzKHVyaSwgbG9jYWxOYW1lLCByYXdOYW1lLCB0eXBlLCB2YWx1ZSwgWFNMQXR0cmlidXRlKTsKLSAgICAgICAgfQotCi0gICAgfQotCi0gICAgLyoqCi0gICAgICogQWRkcyB0aGUgZ2l2ZW4gYXR0cmlidXRlIHRvIHRoZSBzZXQgb2YgYXR0cmlidXRlcywgZXZlbiBpZiB0aGVyZSBpcwotICAgICAqIG5vIGN1cnJlbnRseSBvcGVuIGVsZW1lbnQuIFRoaXMgaXMgdXNlZnVsIGlmIGEgU0FYIHN0YXJ0UHJlZml4TWFwcGluZygpCi0gICAgICogc2hvdWxkIG5lZWQgdG8gYWRkIGFuIGF0dHJpYnV0ZSBiZWZvcmUgdGhlIGVsZW1lbnQgbmFtZSBpcyBzZWVuLgotICAgICAqCi0gICAgICogQHBhcmFtIHVyaSB0aGUgVVJJIG9mIHRoZSBhdHRyaWJ1dGUKLSAgICAgKiBAcGFyYW0gbG9jYWxOYW1lIHRoZSBsb2NhbCBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUKLSAgICAgKiBAcGFyYW0gcmF3TmFtZSAgIHRoZSBxdWFsaWZpZWQgbmFtZSBvZiB0aGUgYXR0cmlidXRlCi0gICAgICogQHBhcmFtIHR5cGUgdGhlIHR5cGUgb2YgdGhlIGF0dHJpYnV0ZSAocHJvYmFibHkgQ0RBVEEpCi0gICAgICogQHBhcmFtIHZhbHVlIHRoZSB2YWx1ZSBvZiB0aGUgYXR0cmlidXRlCi0gICAgICogQHBhcmFtIFhTTEF0dHJpYnV0ZSB0cnVlIGlmIHRoaXMgYXR0cmlidXRlIGlzIGNvbWluZyBmcm9tIGFuIHhzbDphdHRyaWJ1dGUgZWxlbWVudAotICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgYXR0cmlidXRlIHdhcyBhZGRlZCwKLSAgICAgKiBmYWxzZSBpZiBhbiBleGlzdGluZyB2YWx1ZSB3YXMgcmVwbGFjZWQuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gYWRkQXR0cmlidXRlQWx3YXlzKAotICAgICAgICBTdHJpbmcgdXJpLAotICAgICAgICBTdHJpbmcgbG9jYWxOYW1lLAotICAgICAgICBTdHJpbmcgcmF3TmFtZSwKLSAgICAgICAgU3RyaW5nIHR5cGUsCi0gICAgICAgIFN0cmluZyB2YWx1ZSwKLSAgICAgICAgYm9vbGVhbiBYU0xBdHRyaWJ1dGUpCi0gICAgewotICAgICAgICBib29sZWFuIHdhc19hZGRlZDsKLS8vICAgICAgICAgICAgZmluYWwgaW50IGluZGV4ID0KLS8vICAgICAgICAgICAgICAgIChsb2NhbE5hbWUgPT0gbnVsbCB8fCB1cmkgPT0gbnVsbCkgPwotLy8gICAgICAgICAgICAgICAgbV9hdHRyaWJ1dGVzLmdldEluZGV4KHJhd05hbWUpOm1fYXR0cmlidXRlcy5nZXRJbmRleCh1cmksIGxvY2FsTmFtZSk7Ci0gICAgICAgICAgICBpbnQgaW5kZXg7Ci0vLyAgICAgICAgICAgIGlmIChsb2NhbE5hbWUgPT0gbnVsbCB8fCB1cmkgPT0gbnVsbCl7Ci0vLyAgICAgICAgICAgICAgICBpbmRleCA9IG1fYXR0cmlidXRlcy5nZXRJbmRleChyYXdOYW1lKTsKLS8vICAgICAgICAgICAgfQotLy8gICAgICAgICAgICBlbHNlIHsKLS8vICAgICAgICAgICAgICAgIGluZGV4ID0gbV9hdHRyaWJ1dGVzLmdldEluZGV4KHVyaSwgbG9jYWxOYW1lKTsKLS8vICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAobG9jYWxOYW1lID09IG51bGwgfHwgdXJpID09IG51bGwgfHwgdXJpLmxlbmd0aCgpID09IDApCi0gICAgICAgICAgICAgICAgaW5kZXggPSBtX2F0dHJpYnV0ZXMuZ2V0SW5kZXgocmF3TmFtZSk7Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBpbmRleCA9IG1fYXR0cmlidXRlcy5nZXRJbmRleCh1cmksbG9jYWxOYW1lKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChpbmRleCA+PSAwKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIC8qIFdlJ3ZlIHNlZW4gdGhlIGF0dHJpYnV0ZSBiZWZvcmUuCi0gICAgICAgICAgICAgICAgICogV2UgbWF5IGhhdmUgYSBudWxsIHVyaSBvciBsb2NhbE5hbWUsIGJ1dCBhbGwKLSAgICAgICAgICAgICAgICAgKiB3ZSByZWFsbHkgd2FudCB0byByZS1zZXQgaXMgdGhlIHZhbHVlIGFueXdheS4KLSAgICAgICAgICAgICAgICAgKi8KLSAgICAgICAgICAgICAgICBtX2F0dHJpYnV0ZXMuc2V0VmFsdWUoaW5kZXgsdmFsdWUpOwotICAgICAgICAgICAgICAgIHdhc19hZGRlZCA9IGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIC8vIHRoZSBhdHRyaWJ1dGUgZG9lc24ndCBleGlzdCB5ZXQsIGNyZWF0ZSBpdAotICAgICAgICAgICAgICAgIG1fYXR0cmlidXRlcy5hZGRBdHRyaWJ1dGUodXJpLCBsb2NhbE5hbWUsIHJhd05hbWUsIHR5cGUsIHZhbHVlKTsKLSAgICAgICAgICAgICAgICB3YXNfYWRkZWQgPSB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIHdhc19hZGRlZDsKLQotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogIEFkZHMgIHRoZSBnaXZlbiBhdHRyaWJ1dGUgdG8gdGhlIHNldCBvZiBjb2xsZWN0ZWQgYXR0cmlidXRlcywKLSAgICAgKiBidXQgb25seSBpZiB0aGVyZSBpcyBhIGN1cnJlbnRseSBvcGVuIGVsZW1lbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSB0aGUgYXR0cmlidXRlJ3MgcXVhbGlmaWVkIG5hbWUKLSAgICAgKiBAcGFyYW0gdmFsdWUgdGhlIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBhZGRBdHRyaWJ1dGUoU3RyaW5nIG5hbWUsIGZpbmFsIFN0cmluZyB2YWx1ZSkKLSAgICB7Ci0gICAgICAgIGlmIChtX2VsZW1Db250ZXh0Lm1fc3RhcnRUYWdPcGVuKQotICAgICAgICB7Ci0gICAgICAgICAgICBmaW5hbCBTdHJpbmcgcGF0Y2hlZE5hbWUgPSBwYXRjaE5hbWUobmFtZSk7Ci0gICAgICAgICAgICBmaW5hbCBTdHJpbmcgbG9jYWxOYW1lID0gZ2V0TG9jYWxOYW1lKHBhdGNoZWROYW1lKTsKLSAgICAgICAgICAgIGZpbmFsIFN0cmluZyB1cmkgPSBnZXROYW1lc3BhY2VVUkkocGF0Y2hlZE5hbWUsIGZhbHNlKTsKLQotICAgICAgICAgICAgYWRkQXR0cmlidXRlQWx3YXlzKHVyaSxsb2NhbE5hbWUsIHBhdGNoZWROYW1lLCAiQ0RBVEEiLCB2YWx1ZSwgZmFsc2UpOwotICAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEFkZHMgdGhlIGdpdmVuIHhzbDphdHRyaWJ1dGUgdG8gdGhlIHNldCBvZiBjb2xsZWN0ZWQgYXR0cmlidXRlcywKLSAgICAgKiBidXQgb25seSBpZiB0aGVyZSBpcyBhIGN1cnJlbnRseSBvcGVuIGVsZW1lbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSB0aGUgYXR0cmlidXRlJ3MgcXVhbGlmaWVkIG5hbWUgKHByZWZpeDpsb2NhbE5hbWUpCi0gICAgICogQHBhcmFtIHZhbHVlIHRoZSB2YWx1ZSBvZiB0aGUgYXR0cmlidXRlCi0gICAgICogQHBhcmFtIHVyaSB0aGUgVVJJIHRoYXQgdGhlIHByZWZpeCBvZiB0aGUgbmFtZSBwb2ludHMgdG8KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBhZGRYU0xBdHRyaWJ1dGUoU3RyaW5nIG5hbWUsIGZpbmFsIFN0cmluZyB2YWx1ZSwgZmluYWwgU3RyaW5nIHVyaSkKLSAgICB7Ci0gICAgICAgIGlmIChtX2VsZW1Db250ZXh0Lm1fc3RhcnRUYWdPcGVuKQotICAgICAgICB7Ci0gICAgICAgICAgICBmaW5hbCBTdHJpbmcgcGF0Y2hlZE5hbWUgPSBwYXRjaE5hbWUobmFtZSk7Ci0gICAgICAgICAgICBmaW5hbCBTdHJpbmcgbG9jYWxOYW1lID0gZ2V0TG9jYWxOYW1lKHBhdGNoZWROYW1lKTsKLQotICAgICAgICAgICAgYWRkQXR0cmlidXRlQWx3YXlzKHVyaSxsb2NhbE5hbWUsIHBhdGNoZWROYW1lLCAiQ0RBVEEiLCB2YWx1ZSwgdHJ1ZSk7Ci0gICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQWRkIHRoZSBnaXZlbiBhdHRyaWJ1dGVzIHRvIHRoZSBjdXJyZW50bHkgY29sbGVjdGVkIG9uZXMuIFRoZXNlCi0gICAgICogYXR0cmlidXRlcyBhcmUgYWx3YXlzIGFkZGVkLCByZWdhcmRsZXNzIG9mIHdoZXRoZXIgb24gbm90IGFuIGVsZW1lbnQKLSAgICAgKiBpcyBjdXJyZW50bHkgb3Blbi4KLSAgICAgKiBAcGFyYW0gYXR0cyBMaXN0IG9mIGF0dHJpYnV0ZXMgdG8gYWRkIHRvIHRoaXMgbGlzdAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGFkZEF0dHJpYnV0ZXMoQXR0cmlidXRlcyBhdHRzKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotCi0gICAgICAgIGludCBuQXR0cyA9IGF0dHMuZ2V0TGVuZ3RoKCk7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbkF0dHM7IGkrKykKLSAgICAgICAgewotICAgICAgICAgICAgU3RyaW5nIHVyaSA9IGF0dHMuZ2V0VVJJKGkpOwotCi0gICAgICAgICAgICBpZiAobnVsbCA9PSB1cmkpCi0gICAgICAgICAgICAgICAgdXJpID0gIiI7Ci0KLSAgICAgICAgICAgIGFkZEF0dHJpYnV0ZUFsd2F5cygKLSAgICAgICAgICAgICAgICB1cmksCi0gICAgICAgICAgICAgICAgYXR0cy5nZXRMb2NhbE5hbWUoaSksCi0gICAgICAgICAgICAgICAgYXR0cy5nZXRRTmFtZShpKSwKLSAgICAgICAgICAgICAgICBhdHRzLmdldFR5cGUoaSksCi0gICAgICAgICAgICAgICAgYXR0cy5nZXRWYWx1ZShpKSwKLSAgICAgICAgICAgICAgICBmYWxzZSk7Ci0KLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybiBhIHtAbGluayBDb250ZW50SGFuZGxlcn0gaW50ZXJmYWNlIGludG8gdGhpcyBzZXJpYWxpemVyLgotICAgICAqIElmIHRoZSBzZXJpYWxpemVyIGRvZXMgbm90IHN1cHBvcnQgdGhlIHtAbGluayBDb250ZW50SGFuZGxlcn0KLSAgICAgKiBpbnRlcmZhY2UsIGl0IHNob3VsZCByZXR1cm4gbnVsbC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gQSB7QGxpbmsgQ29udGVudEhhbmRsZXJ9IGludGVyZmFjZSBpbnRvIHRoaXMgc2VyaWFsaXplciwKLSAgICAgKiAgb3IgbnVsbCBpZiB0aGUgc2VyaWFsaXplciBpcyBub3QgU0FYIDIgY2FwYWJsZQotICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gQW4gSS9PIGV4Y2VwdGlvbiBvY2N1cmVkCi0gICAgICovCi0gICAgcHVibGljIENvbnRlbnRIYW5kbGVyIGFzQ29udGVudEhhbmRsZXIoKSB0aHJvd3MgSU9FeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIHJldHVybiB0aGlzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJlcG9ydCB0aGUgZW5kIG9mIGFuIGVudGl0eS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBlbnRpdHkgdGhhdCBpcyBlbmRpbmcuCi0gICAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gVGhlIGFwcGxpY2F0aW9uIG1heSByYWlzZSBhbiBleGNlcHRpb24uCi0gICAgICogQHNlZSAjc3RhcnRFbnRpdHkKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbmRFbnRpdHkoU3RyaW5nIG5hbWUpIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGlmIChuYW1lLmVxdWFscygiW2R0ZF0iKSkKLSAgICAgICAgICAgIG1faW5FeHRlcm5hbERURCA9IGZhbHNlOwotICAgICAgICBtX2luRW50aXR5UmVmID0gZmFsc2U7Ci0KLSAgICAgICAgaWYgKG1fdHJhY2VyICE9IG51bGwpCi0gICAgICAgICAgICB0aGlzLmZpcmVFbmRFbnRpdHkobmFtZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRmx1c2ggYW5kIGNsb3NlIHRoZSB1bmRlcmx5aW5nIGphdmEuaW8uV3JpdGVyLiBUaGlzIG1ldGhvZCBhcHBsaWVzIHRvCi0gICAgICogVG9TdHJlYW0gc2VyaWFsaXplcnMsIG5vdCBUb1NBWEhhbmRsZXIgc2VyaWFsaXplcnMuCi0gICAgICogQHNlZSBUb1N0cmVhbQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkKLSAgICB7Ci0gICAgICAgIC8vIGRvIG5vdGhpbmcgKGJhc2UgYmVoYXZpb3IpCi0gICAgfQotCi0gICAgLyoqCi0gICAgICogSW5pdGlhbGl6ZSBnbG9iYWwgdmFyaWFibGVzCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgaW5pdENEQVRBKCkKLSAgICB7Ci0gICAgICAgIC8vIENEQVRBIHN0YWNrCi0gICAgICAgIC8vICAgICAgICBfY2RhdGFTdGFjayA9IG5ldyBTdGFjaygpOwotICAgICAgICAvLyAgICAgICAgX2NkYXRhU3RhY2sucHVzaChuZXcgSW50ZWdlcigtMSkpOyAvLyBwdXNoIGR1bW15IHZhbHVlCi0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgY2hhcmFjdGVyIGVuY29kaW5nIHRvIGJlIHVzZWQgaW4gdGhlIG91dHB1dCBkb2N1bWVudC4KLSAgICAgKiBAcmV0dXJuIHRoZSBjaGFyYWN0ZXIgZW5jb2RpbmcgdG8gYmUgdXNlZCBpbiB0aGUgb3V0cHV0IGRvY3VtZW50LgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0RW5jb2RpbmcoKQotICAgIHsKLSAgICAgICAgcmV0dXJuIG1fZW5jb2Rpbmc7Ci0gICAgfQotCi0gICAvKioKLSAgICAgKiBTZXRzIHRoZSBjaGFyYWN0ZXIgZW5jb2RpbmcgY29taW5nIGZyb20gdGhlIHhzbDpvdXRwdXQgZW5jb2Rpbmcgc3R5bGVzaGVldCBhdHRyaWJ1dGUuCi0gICAgICogQHBhcmFtIG1fZW5jb2RpbmcgdGhlIGNoYXJhY3RlciBlbmNvZGluZwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEVuY29kaW5nKFN0cmluZyBtX2VuY29kaW5nKQotICAgIHsKLSAgICAgICAgdGhpcy5tX2VuY29kaW5nID0gbV9lbmNvZGluZzsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSB2YWx1ZSBjb21pbmcgZnJvbSB0aGUgeHNsOm91dHB1dCBvbWl0LXhtbC1kZWNsYXJhdGlvbiBzdHlsZXNoZWV0IGF0dHJpYnV0ZQotICAgICAqIEBwYXJhbSBiIHRydWUgaWYgdGhlIFhNTCBkZWNsYXJhdGlvbiBpcyB0byBiZSBvbWl0dGVkIGZyb20gdGhlIG91dHB1dAotICAgICAqIGRvY3VtZW50LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldE9taXRYTUxEZWNsYXJhdGlvbihib29sZWFuIGIpCi0gICAgewotICAgICAgICB0aGlzLm1fc2hvdWxkTm90V3JpdGVYTUxIZWFkZXIgPSBiOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBYTUwgZGVjbGFyYXRpb24gaXMgdG8gYmUgb21pdHRlZCBmcm9tIHRoZSBvdXRwdXQKLSAgICAgKiBkb2N1bWVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXRPbWl0WE1MRGVjbGFyYXRpb24oKQotICAgIHsKLSAgICAgICAgcmV0dXJuIG1fc2hvdWxkTm90V3JpdGVYTUxIZWFkZXI7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgcHJldmlvdXNseSBzZXQgdmFsdWUgb2YgdGhlIHZhbHVlIHRvIGJlIHVzZWQgYXMgdGhlIHB1YmxpYwotICAgICAqIGlkZW50aWZpZXIgaW4gdGhlIGRvY3VtZW50IHR5cGUgZGVjbGFyYXRpb24gKERURCkuCi0gICAgICoKLSAgICAgKkByZXR1cm4gdGhlIHB1YmxpYyBpZGVudGlmaWVyIHRvIGJlIHVzZWQgaW4gdGhlIERPQ1RZUEUgZGVjbGFyYXRpb24gaW4gdGhlCi0gICAgICogb3V0cHV0IGRvY3VtZW50LgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0RG9jdHlwZVB1YmxpYygpCi0gICAgewotICAgICAgICByZXR1cm4gbV9kb2N0eXBlUHVibGljOwotICAgIH0KLQotICAgIC8qKiBTZXQgdGhlIHZhbHVlIGNvbWluZyBmcm9tIHRoZSB4c2w6b3V0cHV0IGRvY3R5cGUtcHVibGljIHN0eWxlc2hlZXQgYXR0cmlidXRlLgotICAgICAgKiBAcGFyYW0gZG9jdHlwZVB1YmxpYyB0aGUgcHVibGljIGlkZW50aWZpZXIgdG8gYmUgdXNlZCBpbiB0aGUgRE9DVFlQRQotICAgICAgKiBkZWNsYXJhdGlvbiBpbiB0aGUgb3V0cHV0IGRvY3VtZW50LgotICAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXREb2N0eXBlUHVibGljKFN0cmluZyBkb2N0eXBlUHVibGljKQotICAgIHsKLSAgICAgICAgdGhpcy5tX2RvY3R5cGVQdWJsaWMgPSBkb2N0eXBlUHVibGljOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgcHJldmlvdXNseSBzZXQgdmFsdWUgb2YgdGhlIHZhbHVlIHRvIGJlIHVzZWQKLSAgICAgKiBhcyB0aGUgc3lzdGVtIGlkZW50aWZpZXIgaW4gdGhlIGRvY3VtZW50IHR5cGUgZGVjbGFyYXRpb24gKERURCkuCi0gICAgICAgICAqIEByZXR1cm4gdGhlIHN5c3RlbSBpZGVudGlmaWVyIHRvIGJlIHVzZWQgaW4gdGhlIERPQ1RZUEUgZGVjbGFyYXRpb24gaW4KLSAgICAgICAgICogdGhlIG91dHB1dCBkb2N1bWVudC4KLSAgICAgKgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0RG9jdHlwZVN5c3RlbSgpCi0gICAgewotICAgICAgICByZXR1cm4gbV9kb2N0eXBlU3lzdGVtOwotICAgIH0KLQotICAgIC8qKiBTZXQgdGhlIHZhbHVlIGNvbWluZyBmcm9tIHRoZSB4c2w6b3V0cHV0IGRvY3R5cGUtc3lzdGVtIHN0eWxlc2hlZXQgYXR0cmlidXRlLgotICAgICAgKiBAcGFyYW0gZG9jdHlwZVN5c3RlbSB0aGUgc3lzdGVtIGlkZW50aWZpZXIgdG8gYmUgdXNlZCBpbiB0aGUgRE9DVFlQRQotICAgICAgKiBkZWNsYXJhdGlvbiBpbiB0aGUgb3V0cHV0IGRvY3VtZW50LgotICAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXREb2N0eXBlU3lzdGVtKFN0cmluZyBkb2N0eXBlU3lzdGVtKQotICAgIHsKLSAgICAgICAgdGhpcy5tX2RvY3R5cGVTeXN0ZW0gPSBkb2N0eXBlU3lzdGVtOwotICAgIH0KLQotICAgIC8qKiBTZXQgdGhlIHZhbHVlIGNvbWluZyBmcm9tIHRoZSB4c2w6b3V0cHV0IGRvY3R5cGUtcHVibGljIGFuZCBkb2N0eXBlLXN5c3RlbSBzdHlsZXNoZWV0IHByb3BlcnRpZXMKLSAgICAgKiBAcGFyYW0gZG9jdHlwZVN5c3RlbSB0aGUgc3lzdGVtIGlkZW50aWZpZXIgdG8gYmUgdXNlZCBpbiB0aGUgRE9DVFlQRQotICAgICAqIGRlY2xhcmF0aW9uIGluIHRoZSBvdXRwdXQgZG9jdW1lbnQuCi0gICAgICogQHBhcmFtIGRvY3R5cGVQdWJsaWMgdGhlIHB1YmxpYyBpZGVudGlmaWVyIHRvIGJlIHVzZWQgaW4gdGhlIERPQ1RZUEUKLSAgICAgKiBkZWNsYXJhdGlvbiBpbiB0aGUgb3V0cHV0IGRvY3VtZW50LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldERvY3R5cGUoU3RyaW5nIGRvY3R5cGVTeXN0ZW0sIFN0cmluZyBkb2N0eXBlUHVibGljKQotICAgIHsKLSAgICAgICAgdGhpcy5tX2RvY3R5cGVTeXN0ZW0gPSBkb2N0eXBlU3lzdGVtOwotICAgICAgICB0aGlzLm1fZG9jdHlwZVB1YmxpYyA9IGRvY3R5cGVQdWJsaWM7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0cyB0aGUgdmFsdWUgY29taW5nIGZyb20gdGhlIHhzbDpvdXRwdXQgc3RhbmRhbG9uZSBzdHlsZXNoZWV0IGF0dHJpYnV0ZS4KLSAgICAgKiBAcGFyYW0gc3RhbmRhbG9uZSBhIHZhbHVlIG9mICJ5ZXMiIGluZGljYXRlcyB0aGF0IHRoZQotICAgICAqIDxjb2RlPnN0YW5kYWxvbmU8L2NvZGU+IGRlbGFyYXRpb24gaXMgdG8gYmUgaW5jbHVkZWQgaW4gdGhlIG91dHB1dAotICAgICAqIGRvY3VtZW50LiBUaGlzIG1ldGhvZCByZW1lbWJlcnMgaWYgdGhlIHZhbHVlIHdhcyBleHBsaWNpdGx5IHNldCB1c2luZwotICAgICAqIHRoaXMgbWV0aG9kLCB2ZXJzZXMgaWYgdGhlIHZhbHVlIGlzIHRoZSBkZWZhdWx0IHZhbHVlLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFN0YW5kYWxvbmUoU3RyaW5nIHN0YW5kYWxvbmUpCi0gICAgewotICAgICAgICBpZiAoc3RhbmRhbG9uZSAhPSBudWxsKQotICAgICAgICB7Ci0gICAgICAgICAgICBtX3N0YW5kYWxvbmVXYXNTcGVjaWZpZWQgPSB0cnVlOwotICAgICAgICAgICAgc2V0U3RhbmRhbG9uZUludGVybmFsKHN0YW5kYWxvbmUpOwotICAgICAgICB9Ci0gICAgfQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIFhTTCBzdGFuZGFsb25lIGF0dHJpYnV0ZSwgYnV0IGRvZXMgbm90IHJlbWVtYmVyIGlmIHRoaXMgaXMgYQotICAgICAqIGRlZmF1bHQgb3IgZXhwbGljaXRlIHNldHRpbmcuCi0gICAgICogQHBhcmFtIHN0YW5kYWxvbmUgInllcyIgfCAibm8iCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgc2V0U3RhbmRhbG9uZUludGVybmFsKFN0cmluZyBzdGFuZGFsb25lKQotICAgIHsKLSAgICAgICAgaWYgKCJ5ZXMiLmVxdWFscyhzdGFuZGFsb25lKSkKLSAgICAgICAgICAgIG1fc3RhbmRhbG9uZSA9ICJ5ZXMiOwotICAgICAgICBlbHNlCi0gICAgICAgICAgICBtX3N0YW5kYWxvbmUgPSAibm8iOwotCi0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0cyB0aGUgWFNMIHN0YW5kYWxvbmUgYXR0cmlidXRlCi0gICAgICogQHJldHVybiBhIHZhbHVlIG9mICJ5ZXMiIGlmIHRoZSA8Y29kZT5zdGFuZGFsb25lPC9jb2RlPiBkZWxhcmF0aW9uIGlzIHRvCi0gICAgICogYmUgaW5jbHVkZWQgaW4gdGhlIG91dHB1dCBkb2N1bWVudC4KLSAgICAgKiAgQHNlZSBYU0xPdXRwdXRBdHRyaWJ1dGVzI2dldFN0YW5kYWxvbmUoKQotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3RhbmRhbG9uZSgpCi0gICAgewotICAgICAgICByZXR1cm4gbV9zdGFuZGFsb25lOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgb3V0cHV0IGRvY3VtZW50IHNob3VsZCBiZSBpbmRlbnRlZCB0byB2aXN1YWxseQotICAgICAqIGluZGljYXRlIGl0cyBzdHJ1Y3R1cmUuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0SW5kZW50KCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBtX2RvSW5kZW50OwotICAgIH0KLSAgICAvKioKLSAgICAgKiBHZXRzIHRoZSBtZWRpYXR5cGUgdGhlIG1lZGlhLXR5cGUgb3IgTUlNRSB0eXBlIGFzc29jaWF0ZWQgd2l0aCB0aGUgb3V0cHV0Ci0gICAgICogZG9jdW1lbnQuCi0gICAgICogQHJldHVybiB0aGUgbWVkaWF0eXBlIHRoZSBtZWRpYS10eXBlIG9yIE1JTUUgdHlwZSBhc3NvY2lhdGVkIHdpdGggdGhlCi0gICAgICogb3V0cHV0IGRvY3VtZW50LgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TWVkaWFUeXBlKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBtX21lZGlhdHlwZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXRzIHRoZSB2ZXJzaW9uIG9mIHRoZSBvdXRwdXQgZm9ybWF0LgotICAgICAqIEByZXR1cm4gdGhlIHZlcnNpb24gb2YgdGhlIG91dHB1dCBmb3JtYXQuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRWZXJzaW9uKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBtX3ZlcnNpb247Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0cyB0aGUgdmFsdWUgY29taW5nIGZyb20gdGhlIHhzbDpvdXRwdXQgdmVyc2lvbiBhdHRyaWJ1dGUuCi0gICAgICogQHBhcmFtIHZlcnNpb24gdGhlIHZlcnNpb24gb2YgdGhlIG91dHB1dCBmb3JtYXQuCi0gICAgICogQHNlZSBTZXJpYWxpemF0aW9uSGFuZGxlciNzZXRWZXJzaW9uKFN0cmluZykKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRWZXJzaW9uKFN0cmluZyB2ZXJzaW9uKQotICAgIHsKLSAgICAgICAgbV92ZXJzaW9uID0gdmVyc2lvbjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSB2YWx1ZSBjb21pbmcgZnJvbSB0aGUgeHNsOm91dHB1dCBtZWRpYS10eXBlIHN0eWxlc2hlZXQgYXR0cmlidXRlLgotICAgICAqIEBwYXJhbSBtZWRpYVR5cGUgdGhlIG5vbi1udWxsIG1lZGlhLXR5cGUgb3IgTUlNRSB0eXBlIGFzc29jaWF0ZWQgd2l0aCB0aGUKLSAgICAgKiBvdXRwdXQgZG9jdW1lbnQuCi0gICAgICogQHNlZSBqYXZheC54bWwudHJhbnNmb3JtLk91dHB1dEtleXMjTUVESUFfVFlQRQotICAgICAqIEBzZWUgU2VyaWFsaXphdGlvbkhhbmRsZXIjc2V0TWVkaWFUeXBlKFN0cmluZykKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRNZWRpYVR5cGUoU3RyaW5nIG1lZGlhVHlwZSkKLSAgICB7Ci0gICAgICAgIG1fbWVkaWF0eXBlID0gbWVkaWFUeXBlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBzcGFjZXMgdG8gaW5kZW50IGZvciBlYWNoIGluZGVudGF0aW9uIGxldmVsLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0SW5kZW50QW1vdW50KCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBtX2luZGVudEFtb3VudDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSBpbmRlbnRhdGlvbiBhbW91bnQuCi0gICAgICogQHBhcmFtIG1faW5kZW50QW1vdW50IFRoZSBtX2luZGVudEFtb3VudCB0byBzZXQKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRJbmRlbnRBbW91bnQoaW50IG1faW5kZW50QW1vdW50KQotICAgIHsKLSAgICAgICAgdGhpcy5tX2luZGVudEFtb3VudCA9IG1faW5kZW50QW1vdW50OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIHZhbHVlIGNvbWluZyBmcm9tIHRoZSB4c2w6b3V0cHV0IGluZGVudCBzdHlsZXNoZWV0Ci0gICAgICogYXR0cmlidXRlLgotICAgICAqIEBwYXJhbSBkb0luZGVudCB0cnVlIGlmIHRoZSBvdXRwdXQgZG9jdW1lbnQgc2hvdWxkIGJlIGluZGVudGVkIHRvCi0gICAgICogdmlzdWFsbHkgaW5kaWNhdGUgaXRzIHN0cnVjdHVyZS4KLSAgICAgKiBAc2VlIFhTTE91dHB1dEF0dHJpYnV0ZXMjc2V0SW5kZW50KGJvb2xlYW4pCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0SW5kZW50KGJvb2xlYW4gZG9JbmRlbnQpCi0gICAgewotICAgICAgICBtX2RvSW5kZW50ID0gZG9JbmRlbnQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0cyB0aGUgaXNTdGFuZGFsb25lIHByb3BlcnR5Ci0gICAgICogQHBhcmFtIGlzU3RhbmRhbG9uZSB0cnVlIGlmIHRoZSBPUkFDTEVfSVNfU1RBTkRBTE9ORSBpcyBzZXQgdG8geWVzCi0gICAgICogQHNlZSBPdXRwdXRQcm9wZXJ0aWVzRmFjdG9yeSBPUkFDTEVfSVNfU1RBTkRBTE9ORQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldElzU3RhbmRhbG9uZShib29sZWFuIGlzU3RhbmRhbG9uZSkKLSAgICB7Ci0gICAgICAgbV9pc1N0YW5kYWxvbmUgPSBpc1N0YW5kYWxvbmU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgaXMgdXNlZCB3aGVuIGEgcHJlZml4L3VyaSBuYW1lc3BhY2UgbWFwcGluZwotICAgICAqIGlzIGluZGljYXRlZCBhZnRlciB0aGUgZWxlbWVudCB3YXMgc3RhcnRlZCB3aXRoIGEKLSAgICAgKiBzdGFydEVsZW1lbnQoKSBhbmQgYmVmb3JlIGFuZCBlbmRFbGVtZW50KCkuCi0gICAgICogc3RhcnRQcmVmaXhNYXBwaW5nKHByZWZpeCx1cmkpIHdvdWxkIGJlIHVzZWQgYmVmb3JlIHRoZQotICAgICAqIHN0YXJ0RWxlbWVudCgpIGNhbGwuCi0gICAgICogQHBhcmFtIHVyaSB0aGUgVVJJIG9mIHRoZSBuYW1lc3BhY2UKLSAgICAgKiBAcGFyYW0gcHJlZml4IHRoZSBwcmVmaXggYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBVUkkuCi0gICAgICoKLSAgICAgKiBAc2VlIEV4dGVuZGVkQ29udGVudEhhbmRsZXIjbmFtZXNwYWNlQWZ0ZXJTdGFydEVsZW1lbnQoU3RyaW5nLCBTdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgbmFtZXNwYWNlQWZ0ZXJTdGFydEVsZW1lbnQoU3RyaW5nIHVyaSwgU3RyaW5nIHByZWZpeCkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgLy8gZGVmYXVsdCBiZWhhdmlvciBpcyB0byBkbyBub3RoaW5nCi0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIGEge0BsaW5rIERPTVNlcmlhbGl6ZXJ9IGludGVyZmFjZSBpbnRvIHRoaXMgc2VyaWFsaXplci4gSWYgdGhlCi0gICAgICogc2VyaWFsaXplciBkb2VzIG5vdCBzdXBwb3J0IHRoZSB7QGxpbmsgRE9NU2VyaWFsaXplcn0gaW50ZXJmYWNlLCBpdCBzaG91bGQKLSAgICAgKiByZXR1cm4gbnVsbC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gQSB7QGxpbmsgRE9NU2VyaWFsaXplcn0gaW50ZXJmYWNlIGludG8gdGhpcyBzZXJpYWxpemVyLCAgb3IgbnVsbAotICAgICAqIGlmIHRoZSBzZXJpYWxpemVyIGlzIG5vdCBET00gY2FwYWJsZQotICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gQW4gSS9PIGV4Y2VwdGlvbiBvY2N1cmVkCi0gICAgICogQHNlZSBTZXJpYWxpemVyI2FzRE9NU2VyaWFsaXplcigpCi0gICAgICovCi0gICAgcHVibGljIERPTVNlcmlhbGl6ZXIgYXNET01TZXJpYWxpemVyKCkgdGhyb3dzIElPRXhjZXB0aW9uCi0gICAgewotICAgICAgICByZXR1cm4gdGhpczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBQdXNoIGEgYm9vbGVhbiBzdGF0ZSBiYXNlZCBvbiBpZiB0aGUgbmFtZSBvZiB0aGUgY3VycmVudCBlbGVtZW50Ci0gICAgICogaXMgZm91bmQgaW4gdGhlIGxpc3Qgb2YgcW5hbWVzLiAgQSBzdGF0ZSBpcyBvbmx5IHB1c2hlZCBpZgotICAgICAqIHRoZXJlIHdlcmUgc29tZSBjZGF0YS1zZWN0aW9uLW5hbWVzIHdlcmUgc3BlY2lmaWVkLgotICAgICAqIDxwPgotICAgICAqIEhpZGRlbiBwYXJhbWV0ZXJzIGFyZSB0aGUgdmVjdG9yIG9mIHF1YWxpZmllZCBlbGVtZW50cyBzcGVjaWZpZWQgaW4KLSAgICAgKiBjZGF0YS1zZWN0aW9uLW5hbWVzIGF0dHJpYnV0ZSwgYW5kIHRoZSBtX2NkYXRhU2VjdGlvblN0YXRlcyBzdGFjawotICAgICAqIG9udG8gd2hpY2ggd2hldGhlciB0aGUgY3VycmVudCBlbGVtZW50IGlzIGluIHRoZSBsaXN0IGlzIHB1c2hlZCAodHJ1ZSBvcgotICAgICAqIGZhbHNlKS4gT3RoZXIgaGlkZGVuIHBhcmFtZXRlcnMgYXJlIHRoZSBjdXJyZW50IGVsZW1lbnRzIG5hbWVzcGFjZVVSSSwKLSAgICAgKiBsb2NhbE5hbWUgYW5kIHFOYW1lCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gaXNDZGF0YVNlY3Rpb24oKQotICAgIHsKLQotICAgICAgICBib29sZWFuIGIgPSBmYWxzZTsKLQotICAgICAgICBpZiAobnVsbCAhPSBtX2NkYXRhU2VjdGlvbkVsZW1lbnRzKQotICAgICAgICB7Ci0gICAgICAgICAgICBpZiAobV9lbGVtQ29udGV4dC5tX2VsZW1lbnRMb2NhbE5hbWUgPT0gbnVsbCkKLSAgICAgICAgICAgICAgICBtX2VsZW1Db250ZXh0Lm1fZWxlbWVudExvY2FsTmFtZSA9Ci0gICAgICAgICAgICAgICAgICAgIGdldExvY2FsTmFtZShtX2VsZW1Db250ZXh0Lm1fZWxlbWVudE5hbWUpOwotICAgICAgICAgICAgaWYgKG1fZWxlbUNvbnRleHQubV9lbGVtZW50VVJJID09IG51bGwpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIHByZWZpeCA9IGdldFByZWZpeFBhcnQobV9lbGVtQ29udGV4dC5tX2VsZW1lbnROYW1lKTsKLSAgICAgICAgICAgICAgICBpZiAocHJlZml4ICE9IG51bGwpCi0gICAgICAgICAgICAgICAgICAgIG1fZWxlbUNvbnRleHQubV9lbGVtZW50VVJJID0KLSAgICAgICAgICAgICAgICAgICAgICAgIG1fcHJlZml4TWFwLmxvb2t1cE5hbWVzcGFjZShwcmVmaXgpOwotCi0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmICgobnVsbCAhPSBtX2VsZW1Db250ZXh0Lm1fZWxlbWVudFVSSSkKLSAgICAgICAgICAgICAgICAmJiBtX2VsZW1Db250ZXh0Lm1fZWxlbWVudFVSSS5sZW5ndGgoKSA9PSAwKQotICAgICAgICAgICAgICAgIG1fZWxlbUNvbnRleHQubV9lbGVtZW50VVJJID0gbnVsbDsKLQotICAgICAgICAgICAgaW50IG5FbGVtcyA9IG1fY2RhdGFTZWN0aW9uRWxlbWVudHMuc2l6ZSgpOwotCi0gICAgICAgICAgICAvLyBsb29wIHRocm91Z2ggMiBhdCBhIHRpbWUsIGFzIHRoZXNlIGFyZSBwYWlycyBvZiBVUkkgYW5kIGxvY2FsTmFtZQotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuRWxlbXM7IGkgKz0gMikKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgdXJpID0gKFN0cmluZykgbV9jZGF0YVNlY3Rpb25FbGVtZW50cy5lbGVtZW50QXQoaSk7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIGxvYyA9IChTdHJpbmcpIG1fY2RhdGFTZWN0aW9uRWxlbWVudHMuZWxlbWVudEF0KGkgKyAxKTsKLSAgICAgICAgICAgICAgICBpZiAobG9jLmVxdWFscyhtX2VsZW1Db250ZXh0Lm1fZWxlbWVudExvY2FsTmFtZSkKLSAgICAgICAgICAgICAgICAgICAgJiYgc3ViUGFydE1hdGNoKG1fZWxlbUNvbnRleHQubV9lbGVtZW50VVJJLCB1cmkpKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgYiA9IHRydWU7Ci0KLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBiOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRlbGwgaWYgdHdvIHN0cmluZ3MgYXJlIGVxdWFsLCB3aXRob3V0IHdvcnJ5IGlmIHRoZSBmaXJzdCBzdHJpbmcgaXMgbnVsbC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBwIFN0cmluZyByZWZlcmVuY2UsIHdoaWNoIG1heSBiZSBudWxsLgotICAgICAqIEBwYXJhbSB0IFN0cmluZyByZWZlcmVuY2UsIHdoaWNoIG1heSBiZSBudWxsLgotICAgICAqCi0gICAgICogQHJldHVybiB0cnVlIGlmIHN0cmluZ3MgYXJlIGVxdWFsLgotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW4gc3ViUGFydE1hdGNoKFN0cmluZyBwLCBTdHJpbmcgdCkKLSAgICB7Ci0gICAgICAgIHJldHVybiAocCA9PSB0KSB8fCAoKG51bGwgIT0gcCkgJiYgKHAuZXF1YWxzKHQpKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgbG9jYWwgbmFtZSBvZiBhIHF1YWxpZmllZCBuYW1lLgotICAgICAqIElmIHRoZSBuYW1lIGhhcyBubyBwcmVmaXgsCi0gICAgICogdGhlbiBpdCB3b3JrcyBhcyB0aGUgaWRlbnRpdHkgKFNBWDIpLgotICAgICAqCi0gICAgICogQHBhcmFtIHFuYW1lIGEgcXVhbGlmaWVkIG5hbWUKLSAgICAgKiBAcmV0dXJuIHJldHVybnMgdGhlIHByZWZpeCBvZiB0aGUgcXVhbGlmaWVkIG5hbWUsCi0gICAgICogb3IgbnVsbCBpZiB0aGVyZSBpcyBubyBwcmVmaXguCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgZ2V0UHJlZml4UGFydChTdHJpbmcgcW5hbWUpCi0gICAgewotICAgICAgICBmaW5hbCBpbnQgY29sID0gcW5hbWUuaW5kZXhPZignOicpOwotICAgICAgICByZXR1cm4gKGNvbCA+IDApID8gcW5hbWUuc3Vic3RyaW5nKDAsIGNvbCkgOiBudWxsOwotICAgICAgICAvL3JldHVybiAoY29sID4gMCkgPyBxbmFtZS5zdWJzdHJpbmcoMCxjb2wpIDogIiI7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU29tZSB1c2VycyBvZiB0aGUgc2VyaWFsaXplciBtYXkgbmVlZCB0aGUgY3VycmVudCBuYW1lc3BhY2UgbWFwcGluZ3MKLSAgICAgKiBAcmV0dXJuIHRoZSBjdXJyZW50IG5hbWVzcGFjZSBtYXBwaW5ncyAocHJlZml4L3VyaSkKLSAgICAgKiBAc2VlIEV4dGVuZGVkQ29udGVudEhhbmRsZXIjZ2V0TmFtZXNwYWNlTWFwcGluZ3MoKQotICAgICAqLwotICAgIHB1YmxpYyBOYW1lc3BhY2VNYXBwaW5ncyBnZXROYW1lc3BhY2VNYXBwaW5ncygpCi0gICAgewotICAgICAgICByZXR1cm4gbV9wcmVmaXhNYXA7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgcHJlZml4IGN1cnJlbnRseSBwb2ludGluZyB0byB0aGUgZ2l2ZW4gVVJJIChpZiBhbnkpLgotICAgICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkgdGhlIHVyaSBvZiB0aGUgbmFtZXNwYWNlIGluIHF1ZXN0aW9uCi0gICAgICogQHJldHVybiBhIHByZWZpeCBwb2ludGluZyB0byB0aGUgZ2l2ZW4gVVJJIChpZiBhbnkpLgotICAgICAqIEBzZWUgRXh0ZW5kZWRDb250ZW50SGFuZGxlciNnZXRQcmVmaXgoU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0UHJlZml4KFN0cmluZyBuYW1lc3BhY2VVUkkpCi0gICAgewotICAgICAgICBTdHJpbmcgcHJlZml4ID0gbV9wcmVmaXhNYXAubG9va3VwUHJlZml4KG5hbWVzcGFjZVVSSSk7Ci0gICAgICAgIHJldHVybiBwcmVmaXg7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgVVJJIG9mIGFuIGVsZW1lbnQgb3IgYXR0cmlidXRlLiBOb3RlIHRoYXQgZGVmYXVsdCBuYW1lc3BhY2VzCi0gICAgICogZG8gbm90IGFwcGx5IGRpcmVjdGx5IHRvIGF0dHJpYnV0ZXMuCi0gICAgICogQHBhcmFtIHFuYW1lIGEgcXVhbGlmaWVkIG5hbWUKLSAgICAgKiBAcGFyYW0gaXNFbGVtZW50IHRydWUgaWYgdGhlIHF1YWxpZmllZCBuYW1lIGlzIHRoZSBuYW1lIG9mCi0gICAgICogYW4gZWxlbWVudC4KLSAgICAgKiBAcmV0dXJuIHJldHVybnMgdGhlIG5hbWVzcGFjZSBVUkkgYXNzb2NpYXRlZCB3aXRoIHRoZSBxdWFsaWZpZWQgbmFtZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWVzcGFjZVVSSShTdHJpbmcgcW5hbWUsIGJvb2xlYW4gaXNFbGVtZW50KQotICAgIHsKLSAgICAgICAgU3RyaW5nIHVyaSA9IEVNUFRZU1RSSU5HOwotICAgICAgICBpbnQgY29sID0gcW5hbWUubGFzdEluZGV4T2YoJzonKTsKLSAgICAgICAgZmluYWwgU3RyaW5nIHByZWZpeCA9IChjb2wgPiAwKSA/IHFuYW1lLnN1YnN0cmluZygwLCBjb2wpIDogRU1QVFlTVFJJTkc7Ci0KLSAgICAgICAgaWYgKCFFTVBUWVNUUklORy5lcXVhbHMocHJlZml4KSB8fCBpc0VsZW1lbnQpCi0gICAgICAgIHsKLSAgICAgICAgICAgIGlmIChtX3ByZWZpeE1hcCAhPSBudWxsKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIHVyaSA9IG1fcHJlZml4TWFwLmxvb2t1cE5hbWVzcGFjZShwcmVmaXgpOwotICAgICAgICAgICAgICAgIGlmICh1cmkgPT0gbnVsbCAmJiAhcHJlZml4LmVxdWFscyhYTUxOU19QUkVGSVgpKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgICAgICBVdGlscy5tZXNzYWdlcy5jcmVhdGVNZXNzYWdlKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1zZ0tleS5FUl9OQU1FU1BBQ0VfUFJFRklYLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7IHFuYW1lLnN1YnN0cmluZygwLCBjb2wpIH0gICkpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gdXJpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIFVSSSBvZiBwcmVmaXggKGlmIGFueSkKLSAgICAgKgotICAgICAgICAgKiBAcGFyYW0gcHJlZml4IHRoZSBwcmVmaXggd2hvc2UgVVJJIGlzIHNlYXJjaGVkIGZvcgotICAgICAqIEByZXR1cm4gdGhlIG5hbWVzcGFjZSBVUkkgY3VycmVudGx5IGFzc29jaWF0ZWQgd2l0aCB0aGUKLSAgICAgKiBwcmVmaXgsIG51bGwgaWYgdGhlIHByZWZpeCBpcyB1bmRlZmluZWQuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXROYW1lc3BhY2VVUklGcm9tUHJlZml4KFN0cmluZyBwcmVmaXgpCi0gICAgewotICAgICAgICBTdHJpbmcgdXJpID0gbnVsbDsKLSAgICAgICAgaWYgKG1fcHJlZml4TWFwICE9IG51bGwpCi0gICAgICAgICAgICB1cmkgPSBtX3ByZWZpeE1hcC5sb29rdXBOYW1lc3BhY2UocHJlZml4KTsKLSAgICAgICAgcmV0dXJuIHVyaTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBFbnRpdHkgcmVmZXJlbmNlIGV2ZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgTmFtZSBvZiBlbnRpdHkKLSAgICAgKgotICAgICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW50aXR5UmVmZXJlbmNlKFN0cmluZyBuYW1lKSB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAgewotCi0gICAgICAgIGZsdXNoUGVuZGluZygpOwotCi0gICAgICAgIHN0YXJ0RW50aXR5KG5hbWUpOwotICAgICAgICBlbmRFbnRpdHkobmFtZSk7Ci0KLSAgICAgICAgaWYgKG1fdHJhY2VyICE9IG51bGwpCi0gICAgICAgICAgICAgICAgICAgIGZpcmVFbnRpdHlSZWZlcmVuY2UobmFtZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0cyB0aGUgdHJhbnNmb3JtZXIgYXNzb2NpYXRlZCB3aXRoIHRoaXMgc2VyaWFsaXplcgotICAgICAqIEBwYXJhbSB0IHRoZSB0cmFuc2Zvcm1lciBhc3NvY2lhdGVkIHdpdGggdGhpcyBzZXJpYWxpemVyLgotICAgICAqIEBzZWUgU2VyaWFsaXphdGlvbkhhbmRsZXIjc2V0VHJhbnNmb3JtZXIoVHJhbnNmb3JtZXIpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0VHJhbnNmb3JtZXIoVHJhbnNmb3JtZXIgdCkKLSAgICB7Ci0gICAgICAgIG1fdHJhbnNmb3JtZXIgPSB0OwotCi0gICAgICAgIC8vIElmIHRoaXMgdHJhbnNmb3JtZXIgb2JqZWN0IGltcGxlbWVudHMgdGhlIFNlcmlhbGl6ZXJUcmFjZSBpbnRlcmZhY2UKLSAgICAgICAgLy8gdGhlbiBhc3NpZ24gbV90cmFjZXIgdG8gdGhlIHRyYW5zZm9ybWVyIG9iamVjdCBzbyBpdCBjYW4gYmUgdXNlZAotICAgICAgICAvLyB0byBmaXJlIHRyYWNlIGV2ZW50cy4KLSAgICAgICAgaWYgKChtX3RyYW5zZm9ybWVyIGluc3RhbmNlb2YgU2VyaWFsaXplclRyYWNlKSAmJgotICAgICAgICAgICAgKCgoU2VyaWFsaXplclRyYWNlKSBtX3RyYW5zZm9ybWVyKS5oYXNUcmFjZUxpc3RlbmVycygpKSkgewotICAgICAgICAgICBtX3RyYWNlciA9IChTZXJpYWxpemVyVHJhY2UpIG1fdHJhbnNmb3JtZXI7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgIG1fdHJhY2VyID0gbnVsbDsKLSAgICAgICAgfQotICAgIH0KLSAgICAvKioKLSAgICAgKiBHZXRzIHRoZSB0cmFuc2Zvcm1lciBhc3NvY2lhdGVkIHdpdGggdGhpcyBzZXJpYWxpemVyCi0gICAgICogQHJldHVybiByZXR1cm5zIHRoZSB0cmFuc2Zvcm1lciBhc3NvY2lhdGVkIHdpdGggdGhpcyBzZXJpYWxpemVyLgotICAgICAqIEBzZWUgU2VyaWFsaXphdGlvbkhhbmRsZXIjZ2V0VHJhbnNmb3JtZXIoKQotICAgICAqLwotICAgIHB1YmxpYyBUcmFuc2Zvcm1lciBnZXRUcmFuc2Zvcm1lcigpCi0gICAgewotICAgICAgICByZXR1cm4gbV90cmFuc2Zvcm1lcjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBnZXRzIHRoZSBub2RlcyB2YWx1ZSBhcyBhIFN0cmluZyBhbmQgdXNlcyB0aGF0IFN0cmluZyBhcyBpZgotICAgICAqIGl0IHdlcmUgYW4gaW5wdXQgY2hhcmFjdGVyIG5vdGlmaWNhdGlvbi4KLSAgICAgKiBAcGFyYW0gbm9kZSB0aGUgTm9kZSB0byBzZXJpYWxpemUKLSAgICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGNoYXJhY3RlcnMob3JnLnczYy5kb20uTm9kZSBub2RlKQotICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBmbHVzaFBlbmRpbmcoKTsKLSAgICAgICAgU3RyaW5nIGRhdGEgPSBub2RlLmdldE5vZGVWYWx1ZSgpOwotICAgICAgICBpZiAoZGF0YSAhPSBudWxsKQotICAgICAgICB7Ci0gICAgICAgICAgICBmaW5hbCBpbnQgbGVuZ3RoID0gZGF0YS5sZW5ndGgoKTsKLSAgICAgICAgICAgIGlmIChsZW5ndGggPiBtX2NoYXJzQnVmZi5sZW5ndGgpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgbV9jaGFyc0J1ZmYgPSBuZXcgY2hhcltsZW5ndGggKiAyICsgMV07Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBkYXRhLmdldENoYXJzKDAsIGxlbmd0aCwgbV9jaGFyc0J1ZmYsIDApOwotICAgICAgICAgICAgY2hhcmFjdGVycyhtX2NoYXJzQnVmZiwgMCwgbGVuZ3RoKTsKLSAgICAgICAgfQotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5FcnJvckhhbmRsZXIjZXJyb3IoU0FYUGFyc2VFeGNlcHRpb24pCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZXJyb3IoU0FYUGFyc2VFeGNlcHRpb24gZXhjKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkVycm9ySGFuZGxlciNmYXRhbEVycm9yKFNBWFBhcnNlRXhjZXB0aW9uKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGZhdGFsRXJyb3IoU0FYUGFyc2VFeGNlcHRpb24gZXhjKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLQotICAgICAgbV9lbGVtQ29udGV4dC5tX3N0YXJ0VGFnT3BlbiA9IGZhbHNlOwotCi0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5FcnJvckhhbmRsZXIjd2FybmluZyhTQVhQYXJzZUV4Y2VwdGlvbikKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB3YXJuaW5nKFNBWFBhcnNlRXhjZXB0aW9uIGV4YykgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUbyBmaXJlIG9mZiBzdGFydCBlbnRpdHkgdHJhY2UgZXZlbnQKLSAgICAgKiBAcGFyYW0gbmFtZSBOYW1lIG9mIGVudGl0eQotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIGZpcmVTdGFydEVudGl0eShTdHJpbmcgbmFtZSkKLSAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaWYgKG1fdHJhY2VyICE9IG51bGwpCi0gICAgICAgIHsKLSAgICAgICAgICAgIGZsdXNoTXlXcml0ZXIoKTsKLSAgICAgICAgICAgIG1fdHJhY2VyLmZpcmVHZW5lcmF0ZUV2ZW50KFNlcmlhbGl6ZXJUcmFjZS5FVkVOVFRZUEVfRU5USVRZUkVGLCBuYW1lKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJlcG9ydCB0aGUgY2hhcmFjdGVycyBldmVudAotICAgICAqIEBwYXJhbSBjaGFycyAgY29udGVudCBvZiBjaGFyYWN0ZXJzCi0gICAgICogQHBhcmFtIHN0YXJ0ICBzdGFydGluZyBpbmRleCBvZiBjaGFyYWN0ZXJzIHRvIG91dHB1dAotICAgICAqIEBwYXJhbSBsZW5ndGggIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIG91dHB1dAotICAgICAqLwotLy8gICAgcHJvdGVjdGVkIHZvaWQgZmlyZUNoYXJFdmVudChjaGFyW10gY2hhcnMsIGludCBzdGFydCwgaW50IGxlbmd0aCkKLS8vICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0vLyAgICB7Ci0vLyAgICAgICAgaWYgKG1fdHJhY2VyICE9IG51bGwpCi0vLyAgICAgICAgICAgIG1fdHJhY2VyLmZpcmVHZW5lcmF0ZUV2ZW50KFNlcmlhbGl6ZXJUcmFjZS5FVkVOVFRZUEVfQ0hBUkFDVEVSUywgY2hhcnMsIHN0YXJ0LGxlbmd0aCk7Ci0vLyAgICB9Ci0vLwotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgaXMgb25seSB1c2VkIGludGVybmFsbHkgd2hlbiBmbHVzaGluZyB0aGUgd3JpdGVyIGZyb20gdGhlCi0gICAgICogdmFyaW91cyBmaXJlLi4uKCkgdHJhY2UgZXZlbnRzLiAgRHVlIHRvIHRoZSB3cml0ZXIgYmVpbmcgd3JhcHBlZCB3aXRoCi0gICAgICogU2VyaWFsaXplclRyYWNlV3JpdGVyIGl0IG1heSBjYXVzZSB0aGUgZmx1c2ggb2YgdGhlc2UgdHJhY2UgZXZlbnRzOgotICAgICAqIEVWRU5UVFlQRV9PVVRQVVRfUFNFVURPX0NIQVJBQ1RFUlMKLSAgICAgKiBFVkVOVFRZUEVfT1VUUFVUX0NIQVJBQ1RFUlMKLSAgICAgKiB3aGljaCB0cmFjZSB0aGUgb3V0cHV0IHdyaXR0ZW4gdG8gdGhlIG91dHB1dCBzdHJlYW0uCi0gICAgICoKLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgZmx1c2hNeVdyaXRlcigpCi0gICAgewotICAgICAgICBpZiAobV93cml0ZXIgIT0gbnVsbCkKLSAgICAgICAgewotICAgICAgICAgICAgdHJ5Ci0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgbV93cml0ZXIuZmx1c2goKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhdGNoKElPRXhjZXB0aW9uIGlvZSkKLSAgICAgICAgICAgIHsKLQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotICAgIC8qKgotICAgICAqIFJlcG9ydCB0aGUgQ0RBVEEgdHJhY2UgZXZlbnQKLSAgICAgKiBAcGFyYW0gY2hhcnMgIGNvbnRlbnQgb2YgQ0RBVEEKLSAgICAgKiBAcGFyYW0gc3RhcnQgIHN0YXJ0aW5nIGluZGV4IG9mIGNoYXJhY3RlcnMgdG8gb3V0cHV0Ci0gICAgICogQHBhcmFtIGxlbmd0aCAgbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gb3V0cHV0Ci0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgZmlyZUNEQVRBRXZlbnQoY2hhcltdIGNoYXJzLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpCi0gICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgICAgICAgICAgaWYgKG1fdHJhY2VyICE9IG51bGwpCi0gICAgICAgIHsKLSAgICAgICAgICAgIGZsdXNoTXlXcml0ZXIoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIG1fdHJhY2VyLmZpcmVHZW5lcmF0ZUV2ZW50KFNlcmlhbGl6ZXJUcmFjZS5FVkVOVFRZUEVfQ0RBVEEsIGNoYXJzLCBzdGFydCxsZW5ndGgpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmVwb3J0IHRoZSBjb21tZW50IHRyYWNlIGV2ZW50Ci0gICAgICogQHBhcmFtIGNoYXJzICBjb250ZW50IG9mIGNvbW1lbnQKLSAgICAgKiBAcGFyYW0gc3RhcnQgIHN0YXJ0aW5nIGluZGV4IG9mIGNvbW1lbnQgdG8gb3V0cHV0Ci0gICAgICogQHBhcmFtIGxlbmd0aCAgbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gb3V0cHV0Ci0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgZmlyZUNvbW1lbnRFdmVudChjaGFyW10gY2hhcnMsIGludCBzdGFydCwgaW50IGxlbmd0aCkKLSAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgICAgICAgICBpZiAobV90cmFjZXIgIT0gbnVsbCkKLSAgICAgICAgewotICAgICAgICAgICAgZmx1c2hNeVdyaXRlcigpOwotICAgICAgICAgICAgICAgICAgICAgICAgbV90cmFjZXIuZmlyZUdlbmVyYXRlRXZlbnQoU2VyaWFsaXplclRyYWNlLkVWRU5UVFlQRV9DT01NRU5ULCBuZXcgU3RyaW5nKGNoYXJzLCBzdGFydCwgbGVuZ3RoKSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFRvIGZpcmUgb2ZmIGVuZCBlbnRpdHkgdHJhY2UgZXZlbnQKLSAgICAgKiBAcGFyYW0gbmFtZSBOYW1lIG9mIGVudGl0eQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGZpcmVFbmRFbnRpdHkoU3RyaW5nIG5hbWUpCi0gICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGlmIChtX3RyYWNlciAhPSBudWxsKQotICAgICAgICAgICAgZmx1c2hNeVdyaXRlcigpOwotICAgICAgICAvLyB3ZSBkbyBub3QgbmVlZCB0byBoYW5kbGUgdGhpcy4KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUbyBmaXJlIG9mZiBzdGFydCBkb2N1bWVudCB0cmFjZSAgZXZlbnQKLSAgICAgKi8KLSAgICAgcHJvdGVjdGVkIHZvaWQgZmlyZVN0YXJ0RG9jKCkKLSAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaWYgKG1fdHJhY2VyICE9IG51bGwpCi0gICAgICAgIHsKLSAgICAgICAgICAgIGZsdXNoTXlXcml0ZXIoKTsKLSAgICAgICAgICAgIG1fdHJhY2VyLmZpcmVHZW5lcmF0ZUV2ZW50KFNlcmlhbGl6ZXJUcmFjZS5FVkVOVFRZUEVfU1RBUlRET0NVTUVOVCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFRvIGZpcmUgb2ZmIGVuZCBkb2N1bWVudCB0cmFjZSBldmVudAotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIGZpcmVFbmREb2MoKQotICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAobV90cmFjZXIgIT0gbnVsbCkKLSAgICAgICAgewotICAgICAgICAgICAgZmx1c2hNeVdyaXRlcigpOwotICAgICAgICAgICAgbV90cmFjZXIuZmlyZUdlbmVyYXRlRXZlbnQoU2VyaWFsaXplclRyYWNlLkVWRU5UVFlQRV9FTkRET0NVTUVOVCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXBvcnQgdGhlIHN0YXJ0IGVsZW1lbnQgdHJhY2UgZXZlbnQuIFRoaXMgdHJhY2UgbWV0aG9kIG5lZWRzIHRvIGJlCi0gICAgICogY2FsbGVkIGp1c3QgYmVmb3JlIHRoZSBhdHRyaWJ1dGVzIGFyZSBjbGVhcmVkLgotICAgICAqCi0gICAgICogQHBhcmFtIGVsZW1OYW1lIHRoZSBxdWFsaWZpZWQgbmFtZSBvZiB0aGUgZWxlbWVudAotICAgICAqCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgZmlyZVN0YXJ0RWxlbShTdHJpbmcgZWxlbU5hbWUpCi0gICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGlmIChtX3RyYWNlciAhPSBudWxsKQotICAgICAgICB7Ci0gICAgICAgICAgICBmbHVzaE15V3JpdGVyKCk7Ci0gICAgICAgICAgICBtX3RyYWNlci5maXJlR2VuZXJhdGVFdmVudChTZXJpYWxpemVyVHJhY2UuRVZFTlRUWVBFX1NUQVJURUxFTUVOVCwKLSAgICAgICAgICAgICAgICBlbGVtTmFtZSwgbV9hdHRyaWJ1dGVzKTsKLSAgICAgICAgfQotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogVG8gZmlyZSBvZmYgdGhlIGVuZCBlbGVtZW50IGV2ZW50Ci0gICAgICogQHBhcmFtIG5hbWUgTmFtZSBvZiBlbGVtZW50Ci0gICAgICovCi0vLyAgICBwcm90ZWN0ZWQgdm9pZCBmaXJlRW5kRWxlbShTdHJpbmcgbmFtZSkKLS8vICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0vLyAgICB7Ci0vLyAgICAgICAgaWYgKG1fdHJhY2VyICE9IG51bGwpCi0vLyAgICAgICAgICAgIG1fdHJhY2VyLmZpcmVHZW5lcmF0ZUV2ZW50KFNlcmlhbGl6ZXJUcmFjZS5FVkVOVFRZUEVfRU5ERUxFTUVOVCxuYW1lLCAoQXR0cmlidXRlcyludWxsKTsKLS8vICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogVG8gZmlyZSBvZmYgdGhlIFBJIHRyYWNlIGV2ZW50Ci0gICAgICogQHBhcmFtIG5hbWUgTmFtZSBvZiBQSQotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIGZpcmVFc2NhcGluZ0V2ZW50KFN0cmluZyBuYW1lLCBTdHJpbmcgZGF0YSkKLSAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgIHsKLQotICAgICAgICBpZiAobV90cmFjZXIgIT0gbnVsbCkKLSAgICAgICAgewotICAgICAgICAgICAgZmx1c2hNeVdyaXRlcigpOwotICAgICAgICAgICAgbV90cmFjZXIuZmlyZUdlbmVyYXRlRXZlbnQoU2VyaWFsaXplclRyYWNlLkVWRU5UVFlQRV9QSSxuYW1lLCBkYXRhKTsKLSAgICAgICAgfQotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogVG8gZmlyZSBvZmYgdGhlIGVudGl0eSByZWZlcmVuY2UgdHJhY2UgZXZlbnQKLSAgICAgKiBAcGFyYW0gbmFtZSBOYW1lIG9mIGVudGl0eSByZWZlcmVuY2UKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCBmaXJlRW50aXR5UmVmZXJlbmNlKFN0cmluZyBuYW1lKQotICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAobV90cmFjZXIgIT0gbnVsbCkKLSAgICAgICAgewotICAgICAgICAgICAgZmx1c2hNeVdyaXRlcigpOwotICAgICAgICAgICAgbV90cmFjZXIuZmlyZUdlbmVyYXRlRXZlbnQoU2VyaWFsaXplclRyYWNlLkVWRU5UVFlQRV9FTlRJVFlSRUYsbmFtZSwgKEF0dHJpYnV0ZXMpbnVsbCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiB0aGUgYmVnaW5uaW5nIG9mIGEgZG9jdW1lbnQuCi0gICAgICogVGhpcyBtZXRob2QgaXMgbmV2ZXIgYSBzZWxmIGdlbmVyYXRlZCBjYWxsLAotICAgICAqIGJ1dCBvbmx5IGNhbGxlZCBleHRlcm5hbGx5LgotICAgICAqCi0gICAgICogPHA+VGhlIFNBWCBwYXJzZXIgd2lsbCBpbnZva2UgdGhpcyBtZXRob2Qgb25seSBvbmNlLCBiZWZvcmUgYW55Ci0gICAgICogb3RoZXIgbWV0aG9kcyBpbiB0aGlzIGludGVyZmFjZSBvciBpbiBEVERIYW5kbGVyIChleGNlcHQgZm9yCi0gICAgICogc2V0RG9jdW1lbnRMb2NhdG9yKS48L3A+Ci0gICAgICoKLSAgICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgICAqCi0gICAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydERvY3VtZW50KCkgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgIHsKLQotICAgICAgICAvLyBpZiB3ZSBkbyBnZXQgY2FsbGVkIHdpdGggc3RhcnREb2N1bWVudCgpLCBoYW5kbGUgaXQgcmlnaHQgYXdheQotICAgICAgICBzdGFydERvY3VtZW50SW50ZXJuYWwoKTsKLSAgICAgICAgbV9uZWVkVG9DYWxsU3RhcnREb2N1bWVudCA9IGZhbHNlOwotICAgICAgICByZXR1cm47Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgaGFuZGxlcyB3aGF0IG5lZWRzIHRvIGJlIGRvbmUgYXQgYSBzdGFydERvY3VtZW50KCkgY2FsbCwKLSAgICAgKiB3aGV0aGVyIGZyb20gYW4gZXh0ZXJuYWwgY2FsbGVyLCBvciBpbnRlcm5hbGx5IGNhbGxlZCBpbiB0aGUKLSAgICAgKiBzZXJpYWxpemVyLiAgRm9yIGhpc3RvcmljYWwgcmVhc29ucyB0aGUgc2VyaWFsaXplciBpcyBmbGV4aWJsZSB0bwotICAgICAqIHN0YXJ0RG9jdW1lbnQoKSBub3QgYWx3YXlzIGJlaW5nIGNhbGxlZC4KLSAgICAgKiBFdmVuIGlmIG5vIGV4dGVybmFsIGNhbGwgaXMKLSAgICAgKiBtYWRlIGludG8gc3RhcnREb2N1bWVudCgpIHRoaXMgbWV0aG9kIHdpbGwgYWx3YXlzIGJlIGNhbGxlZCBhcyBhIHNlbGYKLSAgICAgKiBnZW5lcmF0ZWQgaW50ZXJuYWwgc3RhcnREb2N1bWVudCwgaXQgaGFuZGxlcyB3aGF0IG5lZWRzIHRvIGJlIGRvbmUgYXQgYQotICAgICAqIHN0YXJ0RG9jdW1lbnQoKSBjYWxsLgotICAgICAqCi0gICAgICogVGhpcyBtZXRob2QgZXhpc3RzIGp1c3QgdG8gbWFrZSBzdXJlIHRoYXQgc3RhcnREb2N1bWVudCgpIGlzIG9ubHkgZXZlcgotICAgICAqIGNhbGxlZCBmcm9tIGFuIGV4dGVybmFsIGNhbGxlciwgd2hpY2ggaW4gcHJpbmNpcGxlIGlzIGp1c3QgYSBtYXR0ZXIgb2YKLSAgICAgKiBzdHlsZS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgc3RhcnREb2N1bWVudEludGVybmFsKCkgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaWYgKG1fdHJhY2VyICE9IG51bGwpCi0gICAgICAgICAgICB0aGlzLmZpcmVTdGFydERvYygpOwotCi0gICAgfQotCi0gICAgLyogVGhpcyBtZXRob2QgZXh0cmFjdHMgdmVyc2lvbiBhbmQgZW5jb2RpbmcgaW5mb3JtYXRpb24gZnJvbSBTQVggZXZlbnRzLgotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIHNldERvY3VtZW50SW5mbygpIHsKLSAgICAgICAgaWYgKG1fbG9jYXRvciA9PSBudWxsKQotICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgdHJ5ewotICAgICAgICAgICAgU3RyaW5nIHN0clZlcnNpb24gPSAoKExvY2F0b3IyKW1fbG9jYXRvcikuZ2V0WE1MVmVyc2lvbigpOwotICAgICAgICAgICAgaWYgKHN0clZlcnNpb24gIT0gbnVsbCkKLSAgICAgICAgICAgICAgICBzZXRWZXJzaW9uKHN0clZlcnNpb24pOwotICAgICAgICAgICAgLypTdHJpbmcgc3RyRW5jb2RpbmcgPSAoKExvY2F0b3IyKW1fbG9jYXRvcikuZ2V0RW5jb2RpbmcoKTsKLSAgICAgICAgICAgIGlmIChzdHJFbmNvZGluZyAhPSBudWxsKQotICAgICAgICAgICAgICAgIHNldEVuY29kaW5nKHN0ckVuY29kaW5nKTsgKi8KLQotICAgICAgICB9Y2F0Y2goQ2xhc3NDYXN0RXhjZXB0aW9uIGUpe30KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBpcyB1c2VkIHRvIHNldCB0aGUgc291cmNlIGxvY2F0b3IsIHdoaWNoIG1pZ2h0IGJlIHVzZWQgdG8KLSAgICAgKiBnZW5lcmF0ZWQgYW4gZXJyb3IgbWVzc2FnZS4KLSAgICAgKiBAcGFyYW0gbG9jYXRvciB0aGUgc291cmNlIGxvY2F0b3IKLSAgICAgKgotICAgICAqIEBzZWUgRXh0ZW5kZWRDb250ZW50SGFuZGxlciNzZXRTb3VyY2VMb2NhdG9yKGphdmF4LnhtbC50cmFuc2Zvcm0uU291cmNlTG9jYXRvcikKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRTb3VyY2VMb2NhdG9yKFNvdXJjZUxvY2F0b3IgbG9jYXRvcikKLSAgICB7Ci0gICAgICAgIG1fc291cmNlTG9jYXRvciA9IGxvY2F0b3I7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBVc2VkIG9ubHkgYnkgVHJhbnNmb3JtZXJTbmFwc2hvdEltcGwgdG8gcmVzdG9yZSB0aGUgc2VyaWFsaXphdGlvbgotICAgICAqIHRvIGEgcHJldmlvdXMgc3RhdGUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbWFwcGluZ3MgTmFtZXNwYWNlTWFwcGluZ3MKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXROYW1lc3BhY2VNYXBwaW5ncyhOYW1lc3BhY2VNYXBwaW5ncyBtYXBwaW5ncykgewotICAgICAgICBtX3ByZWZpeE1hcCA9IG1hcHBpbmdzOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIHJlc2V0KCkKLSAgICB7Ci0gICAgICAgIHJlc2V0U2VyaWFsaXplckJhc2UoKTsKLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmVzZXQgYWxsIG9mIHRoZSBmaWVsZHMgb3duZWQgYnkgU2VyaWFsaXplckJhc2UKLSAgICAgKgotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCByZXNldFNlcmlhbGl6ZXJCYXNlKCkKLSAgICB7Ci0gICAgICAgIHRoaXMubV9hdHRyaWJ1dGVzLmNsZWFyKCk7Ci0gICAgICAgIHRoaXMubV9jZGF0YVNlY3Rpb25FbGVtZW50cyA9IG51bGw7Ci0gICAgICAgIHRoaXMubV9lbGVtQ29udGV4dCA9IG5ldyBFbGVtQ29udGV4dCgpOwotICAgICAgICB0aGlzLm1fZG9jdHlwZVB1YmxpYyA9IG51bGw7Ci0gICAgICAgIHRoaXMubV9kb2N0eXBlU3lzdGVtID0gbnVsbDsKLSAgICAgICAgdGhpcy5tX2RvSW5kZW50ID0gZmFsc2U7Ci0gICAgICAgIHRoaXMubV9lbmNvZGluZyA9IG51bGw7Ci0gICAgICAgIHRoaXMubV9pbmRlbnRBbW91bnQgPSAwOwotICAgICAgICB0aGlzLm1faW5FbnRpdHlSZWYgPSBmYWxzZTsKLSAgICAgICAgdGhpcy5tX2luRXh0ZXJuYWxEVEQgPSBmYWxzZTsKLSAgICAgICAgdGhpcy5tX21lZGlhdHlwZSA9IG51bGw7Ci0gICAgICAgIHRoaXMubV9uZWVkVG9DYWxsU3RhcnREb2N1bWVudCA9IHRydWU7Ci0gICAgICAgIHRoaXMubV9uZWVkVG9PdXRwdXREb2NUeXBlRGVjbCA9IGZhbHNlOwotICAgICAgICBpZiAodGhpcy5tX3ByZWZpeE1hcCAhPSBudWxsKQotICAgICAgICAgICAgdGhpcy5tX3ByZWZpeE1hcC5yZXNldCgpOwotICAgICAgICB0aGlzLm1fc2hvdWxkTm90V3JpdGVYTUxIZWFkZXIgPSBmYWxzZTsKLSAgICAgICAgdGhpcy5tX3NvdXJjZUxvY2F0b3IgPSBudWxsOwotICAgICAgICB0aGlzLm1fc3RhbmRhbG9uZSA9IG51bGw7Ci0gICAgICAgIHRoaXMubV9zdGFuZGFsb25lV2FzU3BlY2lmaWVkID0gZmFsc2U7Ci0gICAgICAgIHRoaXMubV90cmFjZXIgPSBudWxsOwotICAgICAgICB0aGlzLm1fdHJhbnNmb3JtZXIgPSBudWxsOwotICAgICAgICB0aGlzLm1fdmVyc2lvbiA9IG51bGw7Ci0gICAgICAgIC8vIGRvbid0IHNldCB3cml0ZXIgdG8gbnVsbCwgc28gdGhhdCBpdCBtaWdodCBiZSByZS11c2VkCi0gICAgICAgIC8vdGhpcy5tX3dyaXRlciA9IG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBzZXJpYWxpemVyIGlzIHVzZWQgZm9yIHRlbXBvcmFyeSBvdXRwdXQgcmF0aGVyIHRoYW4KLSAgICAgKiBmaW5hbCBvdXRwdXQuCi0gICAgICoKLSAgICAgKiBUaGlzIGNvbmNlcHQgaXMgbWFkZSBjbGVhciBpbiB0aGUgWFNMVCAyLjAgZHJhZnQuCi0gICAgICovCi0gICAgZmluYWwgYm9vbGVhbiBpblRlbXBvcmFyeU91dHB1dFN0YXRlKCkKLSAgICB7Ci0gICAgICAgIC8qIFRoaXMgaXMgYSBoYWNrLiBXZSBzaG91bGQgcmVhbGx5IGJlIGxldHRpbmcgdGhlIHNlcmlhbGl6ZXIga25vdwotICAgICAgICAgKiB0aGF0IGl0IGlzIGluIHRlbXBvcmFyeSBvdXRwdXQgc3RhdGUgd2l0aCBhbiBleHBsaWNpdCBjYWxsLCBidXQKLSAgICAgICAgICogZnJvbSBhIHByYWdtYXRpYyBwb2ludCBvZiB2aWV3IChmb3Igbm93IGFueXdheXMpIGhhdmluZyBubyBvdXRwdXQKLSAgICAgICAgICogZW5jb2RpbmcgYXQgYWxsLCBub3QgZXZlbiB0aGUgZGVmYXVsdCBVVEYtOCBpbmRpY2F0ZXMgdGhhdCB0aGUgc2VyaWFsaXplcgotICAgICAgICAgKiBpcyBiZWluZyB1c2VkIGZvciB0ZW1wb3JhcnkgUlRGLgotICAgICAgICAgKi8KLSAgICAgICAgcmV0dXJuIChnZXRFbmNvZGluZygpID09IG51bGwpOwotCi0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgYWRkcyBhbiBhdHRyaWJ1dGUgdGhlIHRoZSBjdXJyZW50IGVsZW1lbnQsCi0gICAgICogYnV0IHNob3VsZCBub3QgYmUgdXNlZCBmb3IgYW4geHNsOmF0dHJpYnV0ZSBjaGlsZC4KLSAgICAgKiBAc2VlIEV4dGVuZGVkQ29udGVudEhhbmRsZXIjYWRkQXR0cmlidXRlKGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgYWRkQXR0cmlidXRlKFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUsIFN0cmluZyByYXdOYW1lLCBTdHJpbmcgdHlwZSwgU3RyaW5nIHZhbHVlKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAobV9lbGVtQ29udGV4dC5tX3N0YXJ0VGFnT3BlbikKLSAgICAgICAgewotICAgICAgICAgICAgYWRkQXR0cmlidXRlQWx3YXlzKHVyaSwgbG9jYWxOYW1lLCByYXdOYW1lLCB0eXBlLCB2YWx1ZSwgZmFsc2UpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5EVERIYW5kbGVyI25vdGF0aW9uRGVjbChqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIG5vdGF0aW9uRGVjbChTdHJpbmcgYXJnMCwgU3RyaW5nIGFyZzEsIFN0cmluZyBhcmcyKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICAgICAgLy8gVGhpcyBtZXRob2QganVzdCBwcm92aWRlcyBhIGRlZmluaXRpb24gdG8gc2F0aXNmeSB0aGUgaW50ZXJmYWNlCi0gICAgICAgIC8vIEEgcGFydGljdWxhciBzdWItY2xhc3Mgb2YgU2VyaWFsaXplckJhc2UgcHJvdmlkZXMgdGhlIGltcGxlbWVudGF0aW9uIChpZiBkZXNpcmVkKQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguRFRESGFuZGxlciN1bnBhcnNlZEVudGl0eURlY2woamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZykKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB1bnBhcnNlZEVudGl0eURlY2woCi0gICAgICAgIFN0cmluZyBhcmcwLAotICAgICAgICBTdHJpbmcgYXJnMSwKLSAgICAgICAgU3RyaW5nIGFyZzIsCi0gICAgICAgIFN0cmluZyBhcmczKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICAgICAgLy8gVGhpcyBtZXRob2QganVzdCBwcm92aWRlcyBhIGRlZmluaXRpb24gdG8gc2F0aXNmeSB0aGUgaW50ZXJmYWNlCi0gICAgICAgIC8vIEEgcGFydGljdWxhciBzdWItY2xhc3Mgb2YgU2VyaWFsaXplckJhc2UgcHJvdmlkZXMgdGhlIGltcGxlbWVudGF0aW9uIChpZiBkZXNpcmVkKQotICAgIH0KLQotICAgIC8qKgotICAgICAqIElmIHNldCB0byBmYWxzZSB0aGUgc2VyaWFsaXplciBkb2VzIG5vdCBleHBhbmQgRFREIGVudGl0aWVzLAotICAgICAqIGJ1dCBsZWF2ZXMgdGhlbSBhcyBpcywgdGhlIGRlZmF1bHQgdmFsdWUgaXMgdHJ1ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXREVERFbnRpdHlFeHBhbnNpb24oYm9vbGVhbiBleHBhbmQpIHsKLSAgICAgICAgLy8gVGhpcyBtZXRob2QganVzdCBwcm92aWRlcyBhIGRlZmluaXRpb24gdG8gc2F0aXNmeSB0aGUgaW50ZXJmYWNlCi0gICAgICAgIC8vIEEgcGFydGljdWxhciBzdWItY2xhc3Mgb2YgU2VyaWFsaXplckJhc2UgcHJvdmlkZXMgdGhlIGltcGxlbWVudGF0aW9uIChpZiBkZXNpcmVkKQotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemVyQ29uc3RhbnRzLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6ZXJDb25zdGFudHMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYzhhNGZjZS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6ZXJDb25zdGFudHMuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDYxICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFNlcmlhbGl6ZXJDb25zdGFudHMuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNSAwODoxNToyMyBzdXJlc2hfZW1haWxpZCBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplcjsKLQotLyoqCi0gKiBDb25zdGFudHMgdXNlZCBpbiBzZXJpYWxpemF0aW9uLCBzdWNoIGFzIHRoZSBzdHJpbmcgInhtbG5zIgotICogQHhzbC51c2FnZSBpbnRlcm5hbAotICovCi1pbnRlcmZhY2UgU2VyaWFsaXplckNvbnN0YW50cwotewotCi0gICAgLyoqIFRvIGluc2VydCBdXT4gaW4gYSBDREFUQSBzZWN0aW9uIGJ5IGVuZGluZyB0aGUgbGFzdCBDREFUQSBzZWN0aW9uIHdpdGgKLSAgICAgKiBdXSBhbmQgc3RhcnRpbmcgdGhlIG5leHQgQ0RBVEEgc2VjdGlvbiB3aXRoID4KLSAgICAgKi8KLSAgICBzdGF0aWMgZmluYWwgU3RyaW5nIENEQVRBX0NPTlRJTlVFID0gIl1dXV0+PCFbQ0RBVEFbPiI7Ci0gICAgLyoqCi0gICAgICogVGhlIGNvbnN0YW50ICJdXT4iCi0gICAgICovCi0gICAgc3RhdGljIGZpbmFsIFN0cmluZyBDREFUQV9ERUxJTUlURVJfQ0xPU0UgPSAiXV0+IjsKLSAgICBzdGF0aWMgZmluYWwgU3RyaW5nIENEQVRBX0RFTElNSVRFUl9PUEVOID0gIjwhW0NEQVRBWyI7Ci0KLSAgICBzdGF0aWMgZmluYWwgU3RyaW5nIEVNUFRZU1RSSU5HID0gIiI7Ci0KLSAgICBzdGF0aWMgZmluYWwgU3RyaW5nIEVOVElUWV9BTVAgPSAiJmFtcDsiOwotICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgRU5USVRZX0NSTEYgPSAiJiN4QTsiOwotICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgRU5USVRZX0dUID0gIiZndDsiOwotICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgRU5USVRZX0xUID0gIiZsdDsiOwotICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgRU5USVRZX1FVT1QgPSAiJnF1b3Q7IjsKLQotICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MX1BSRUZJWCA9ICJ4bWwiOwotICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MTlNfUFJFRklYID0gInhtbG5zIjsKLSAgICBzdGF0aWMgZmluYWwgU3RyaW5nIFhNTE5TX1VSSSA9ICJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3htbG5zLyI7Ci0KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBERUZBVUxUX1NBWF9TRVJJQUxJWkVSPSJjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXIuVG9YTUxTQVhIYW5kbGVyIjsKLQotICAgIC8qKgotICAgICAqIERlZmluZSB0aGUgWE1MIHZlcnNpb24uCi0gICAgICovCi0gICAgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxWRVJTSU9OMTEgPSAiMS4xIjsKLSAgICBzdGF0aWMgZmluYWwgU3RyaW5nIFhNTFZFUlNJT04xMCA9ICIxLjAiOwotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemVyRmFjdG9yeS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemVyRmFjdG9yeS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyODEzOWMzLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXplckZhY3RvcnkuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE3OSArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDE1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICovCi0vKgotICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCi0gKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKLSAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KLSAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCi0gKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAotICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFNlcmlhbGl6ZXJGYWN0b3J5LmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTUgMDg6MTU6MjQgc3VyZXNoX2VtYWlsaWQgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXI7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwudXRpbHMuT2JqZWN0RmFjdG9yeTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXIudXRpbHMuTXNnS2V5OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplci51dGlscy5VdGlsczsKLWltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLk91dHB1dEtleXM7Ci1pbXBvcnQgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXI7Ci0KLS8qKgotICogVGhpcyBjbGFzcyBpcyBhIHB1YmxpYyBBUEksIGl0IGlzIGEgZmFjdG9yeSBmb3IgY3JlYXRpbmcgc2VyaWFsaXplcnMuCi0gICAqCi0gICAqIFRoZSBwcm9wZXJ0aWVzIG9iamVjdCBwYXNzZWQgdG8gdGhlIGdldFNlcmlhbGl6ZXIoKSBtZXRob2Qgc2hvdWxkIGJlIGNyZWF0ZWQgYnkKLSAgICogdGhlIE91dHB1dFByb3BlcnRpZXNGYWN0b3J5LiBBbHRob3VnaCB0aGUgcHJvcGVydGllcyBvYmplY3QKLSAgICogdXNlZCB0byBjcmVhdGUgYSBzZXJpYWxpemVyIGRvZXMgbm90IG5lZWQgdG8gYmUgb2J0YWluZWQKLSAgICogZnJvbSBPdXRwdXRQcm9wZXJ0aWVzRmFjdG9yeSwKLSAgICogdXNpbmcgdGhpcyBmYWN0b3J5IGVuc3VyZXMgdGhhdCB0aGUgZGVmYXVsdCBrZXkvdmFsdWUgcHJvcGVydGllcwotICAgKiBhcmUgc2V0IGZvciB0aGUgZ2l2ZW4gb3V0cHV0ICJtZXRob2QiLgotICAgKgotICAgKiA8cD4KLSAgICogVGhlIHN0YW5kYXJkIHByb3BlcnR5IGtleXMgc3VwcG9ydGVkIGFyZTogIm1ldGhvZCIsICJ2ZXJzaW9uIiwgImVuY29kaW5nIiwKLSAgICogIm9taXQteG1sLWRlY2xhcmF0aW9uIiwgInN0YW5kYWxvbmUiLCBkb2N0eXBlLXB1YmxpYyIsCi0gICAqICJkb2N0eXBlLXN5c3RlbSIsICJjZGF0YS1zZWN0aW9uLWVsZW1lbnRzIiwgImluZGVudCIsICJtZWRpYS10eXBlIi4KLSAgICogVGhlc2UgcHJvcGVydHkga2V5cyBhbmQgdGhlaXIgdmFsdWVzIGFyZSBkZXNjcmliZWQgaW4gdGhlIFhTTFQgcmVjb21tZW5kYXRpb24sCi0gICAqIHNlZSB7QGxpbmsgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OS9SRUMteHNsdC0xOTk5MTExNiI+IFhTTFQgMS4wIHJlY29tbWVuZGF0aW9uPC9hPn0KLSAgICoKLSAgICogPHA+Ci0gICAqIFRoZSB2YWx1ZSBvZiB0aGUgImNkYXRhLXNlY3Rpb24tZWxlbWVudHMiIHByb3BlcnR5IGtleSBpcyBhIHdoaXRlc3BhY2UKLSAgICogc2VwYXJhdGVkIGxpc3Qgb2YgZWxlbWVudHMuIElmIHRoZSBlbGVtZW50IGlzIGluIGEgbmFtZXNwYWNlIHRoZW4KLSAgICogdmFsdWUgaXMgcGFzc2VkIGluIHRoaXMgZm9ybWF0OiB7dXJpfWxvY2FsTmFtZQotICAgKgotICAgKiA8cD4KLSAgICogVGhlIG5vbi1zdGFuZGFyZCBwcm9wZXJ0eSBrZXlzIHN1cHBvcnRlZCBhcmUgZGVmaW5lZCBpbiB7QGxpbmsgT3V0cHV0UHJvcGVydGllc0ZhY3Rvcnl9LgotICAgKgotICAgKiBAc2VlIE91dHB1dFByb3BlcnRpZXNGYWN0b3J5Ci0gICAqIEBzZWUgTWV0aG9kCi0gICAqIEBzZWUgU2VyaWFsaXplcgotICAgKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBTZXJpYWxpemVyRmFjdG9yeQotewotICAvKioKLSAgICogVGhpcyBjb25zdHJ1Y3RvciBpcyBwcml2YXRlIGp1c3QgdG8gcHJldmVudCB0aGUgY3JlYXRpb24gb2Ygc3VjaCBhbiBvYmplY3QuCi0gICAqLwotCi0gIHByaXZhdGUgU2VyaWFsaXplckZhY3RvcnkoKSB7Ci0KLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIGEgc2VyaWFsaXplciBmb3IgdGhlIHNwZWNpZmllZCBvdXRwdXQgbWV0aG9kLiBUaGUgb3V0cHV0IG1ldGhvZAotICAgKiBpcyBzcGVjaWZpZWQgYnkgdGhlIHZhbHVlIG9mIHRoZSBwcm9wZXJ0eSBhc3NvY2lhdGVkIHdpdGggdGhlICJtZXRob2QiIGtleS4KLSAgICogSWYgbm8gaW1wbGVtZW50YXRpb24gZXhpc3RzIHRoYXQgc3VwcG9ydHMgdGhlIHNwZWNpZmllZCBvdXRwdXQgbWV0aG9kCi0gICAqIGFuIGV4Y2VwdGlvbiBvZiBzb21lIHR5cGUgd2lsbCBiZSB0aHJvd24uCi0gICAqIEZvciBhIGxpc3Qgb2YgdGhlIG91dHB1dCAibWV0aG9kIiBrZXkgdmFsdWVzIHNlZSB7QGxpbmsgTWV0aG9kfS4KLSAgICoKLSAgICogQHBhcmFtIGZvcm1hdCBUaGUgb3V0cHV0IGZvcm1hdCwgbWluaW1hbGx5IHRoZSAibWV0aG9kIiBwcm9wZXJ0eSBtdXN0IGJlIHNldC4KLSAgICogQHJldHVybiBBIHN1aXRhYmxlIHNlcmlhbGl6ZXIuCi0gICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIG1ldGhvZCBpcwotICAgKiBudWxsIG9yIGFuIGFwcHJvcHJpYXRlIHNlcmlhbGl6ZXIgY2FuJ3QgYmUgZm91bmQKLSAgICogQHRocm93cyBFeGNlcHRpb24gaWYgdGhlIGNsYXNzIGZvciB0aGUgc2VyaWFsaXplciBpcyBmb3VuZCBidXQgZG9lcyBub3QKLSAgICogaW1wbGVtZW50IENvbnRlbnRIYW5kbGVyLgotICAgKiBAdGhyb3dzIFdyYXBwZWRSdW50aW1lRXhjZXB0aW9uIGlmIGFuIGV4Y2VwdGlvbiBpcyB0aHJvd24gd2hpbGUgdHJ5aW5nIHRvIGZpbmQgc2VyaWFsaXplcgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBTZXJpYWxpemVyIGdldFNlcmlhbGl6ZXIoUHJvcGVydGllcyBmb3JtYXQpCi0gIHsKLSAgICAgIFNlcmlhbGl6ZXIgc2VyOwotCi0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgU3RyaW5nIG1ldGhvZCA9IGZvcm1hdC5nZXRQcm9wZXJ0eShPdXRwdXRLZXlzLk1FVEhPRCk7Ci0KLSAgICAgICAgaWYgKG1ldGhvZCA9PSBudWxsKSB7Ci0gICAgICAgICAgICBTdHJpbmcgbXNnID0gVXRpbHMubWVzc2FnZXMuY3JlYXRlTWVzc2FnZSgKLSAgICAgICAgICAgICAgICBNc2dLZXkuRVJfRkFDVE9SWV9QUk9QRVJUWV9NSVNTSU5HLAotICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7IE91dHB1dEtleXMuTUVUSE9EfSk7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKG1zZyk7Ci0gICAgICAgIH0KLQotICAgICAgICBTdHJpbmcgY2xhc3NOYW1lID0KLSAgICAgICAgICAgIGZvcm1hdC5nZXRQcm9wZXJ0eShPdXRwdXRQcm9wZXJ0aWVzRmFjdG9yeS5TX0tFWV9DT05URU5UX0hBTkRMRVIpOwotCi0KLSAgICAgICAgaWYgKG51bGwgPT0gY2xhc3NOYW1lKQotICAgICAgICB7Ci0gICAgICAgICAgICAvLyBNaXNzaW5nIENvbnRlbnQgSGFuZGxlciBwcm9wZXJ0eSwgbG9hZCBkZWZhdWx0IHVzaW5nIE91dHB1dFByb3BlcnRpZXNGYWN0b3J5Ci0gICAgICAgICAgICBQcm9wZXJ0aWVzIG1ldGhvZERlZmF1bHRzID0KLSAgICAgICAgICAgICAgICBPdXRwdXRQcm9wZXJ0aWVzRmFjdG9yeS5nZXREZWZhdWx0TWV0aG9kUHJvcGVydGllcyhtZXRob2QpOwotICAgICAgICAgICAgY2xhc3NOYW1lID0KLSAgICAgICAgICAgIG1ldGhvZERlZmF1bHRzLmdldFByb3BlcnR5KE91dHB1dFByb3BlcnRpZXNGYWN0b3J5LlNfS0VZX0NPTlRFTlRfSEFORExFUik7Ci0gICAgICAgICAgICBpZiAobnVsbCA9PSBjbGFzc05hbWUpIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgbXNnID0gVXRpbHMubWVzc2FnZXMuY3JlYXRlTWVzc2FnZSgKLSAgICAgICAgICAgICAgICAgICAgTXNnS2V5LkVSX0ZBQ1RPUllfUFJPUEVSVFlfTUlTU0lORywKLSAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgT3V0cHV0UHJvcGVydGllc0ZhY3RvcnkuU19LRVlfQ09OVEVOVF9IQU5ETEVSfSk7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihtc2cpOwotICAgICAgICAgICAgfQotCi0gICAgICAgIH0KLQotCi0KLSAgICAgICAgQ2xhc3MgY2xzID0gT2JqZWN0RmFjdG9yeS5maW5kUHJvdmlkZXJDbGFzcyhjbGFzc05hbWUsIHRydWUpOwotCi0gICAgICAgIC8vIF9zZXJpYWxpemVycy5wdXQobWV0aG9kLCBjbHMpOwotCi0gICAgICAgIE9iamVjdCBvYmogPSBjbHMubmV3SW5zdGFuY2UoKTsKLQotICAgICAgICBpZiAob2JqIGluc3RhbmNlb2YgU2VyaWFsaXphdGlvbkhhbmRsZXIpCi0gICAgICAgIHsKLSAgICAgICAgICAgICAgLy8gdGhpcyBpcyBvbmUgb2YgdGhlIHN1cHBsaWVkIHNlcmlhbGl6ZXJzCi0gICAgICAgICAgICBzZXIgPSAoU2VyaWFsaXplcikgY2xzLm5ld0luc3RhbmNlKCk7Ci0gICAgICAgICAgICBzZXIuc2V0T3V0cHV0Rm9ybWF0KGZvcm1hdCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICB7Ci0gICAgICAgICAgICAgIC8qCi0gICAgICAgICAgICAgICAqICBUaGlzICBtdXN0IGJlIGEgdXNlciBkZWZpbmVkIFNlcmlhbGl6ZXIuCi0gICAgICAgICAgICAgICAqICBJdCBoYWQgYmV0dGVyIGltcGxlbWVudCBDb250ZW50SGFuZGxlci4KLSAgICAgICAgICAgICAgICovCi0gICAgICAgICAgICAgICBpZiAob2JqIGluc3RhbmNlb2YgQ29udGVudEhhbmRsZXIpCi0gICAgICAgICAgICAgICB7Ci0KLSAgICAgICAgICAgICAgICAgIC8qCi0gICAgICAgICAgICAgICAgICAgKiBUaGUgdXNlciBkZWZpbmVkIHNlcmlhbGl6ZXIgZGVmaW5lcyBDb250ZW50SGFuZGxlciwKLSAgICAgICAgICAgICAgICAgICAqIGJ1dCB3ZSBuZWVkIHRvIHdyYXAgaXQgd2l0aCBUb1hNTFNBWEhhbmRsZXIgd2hpY2gKLSAgICAgICAgICAgICAgICAgICAqIHdpbGwgY29sbGVjdCBTQVgtbGlrZSBldmVudHMgYW5kIGVtaXQgdHJ1ZQotICAgICAgICAgICAgICAgICAgICogU0FYIENvbnRlbnRIYW5kbGVyIGV2ZW50cyB0byB0aGUgdXNlcnMgaGFuZGxlci4KLSAgICAgICAgICAgICAgICAgICAqLwotICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lID0gU2VyaWFsaXplckNvbnN0YW50cy5ERUZBVUxUX1NBWF9TRVJJQUxJWkVSOwotICAgICAgICAgICAgICAgICAgY2xzID0gT2JqZWN0RmFjdG9yeS5maW5kUHJvdmlkZXJDbGFzcyhjbGFzc05hbWUsIHRydWUpOwotICAgICAgICAgICAgICAgICAgU2VyaWFsaXphdGlvbkhhbmRsZXIgc2ggPQotICAgICAgICAgICAgICAgICAgICAgIChTZXJpYWxpemF0aW9uSGFuZGxlcikgY2xzLm5ld0luc3RhbmNlKCk7Ci0gICAgICAgICAgICAgICAgICBzaC5zZXRDb250ZW50SGFuZGxlciggKENvbnRlbnRIYW5kbGVyKSBvYmopOwotICAgICAgICAgICAgICAgICAgc2guc2V0T3V0cHV0Rm9ybWF0KGZvcm1hdCk7Ci0KLSAgICAgICAgICAgICAgICAgIHNlciA9IHNoOwotICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgLy8gdXNlciBkZWZpbmVkIHNlcmlhbGl6ZXIgZG9lcyBub3QgaW1wbGVtZW50Ci0gICAgICAgICAgICAgICAgICAvLyBDb250ZW50SGFuZGxlciwgLi4uIHZlcnkgYmFkCi0gICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgICAgVXRpbHMubWVzc2FnZXMuY3JlYXRlTWVzc2FnZSgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgIE1zZ0tleS5FUl9TRVJJQUxJWkVSX05PVF9DT05URU5USEFORExFUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBjbGFzc05hbWV9KSk7Ci0gICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgfQotICAgICAgfQotICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKQotICAgICAgewotICAgICAgICB0aHJvdyBuZXcgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyLnV0aWxzLldyYXBwZWRSdW50aW1lRXhjZXB0aW9uKGUpOwotICAgICAgfQotCi0gICAgICAvLyBJZiB3ZSBtYWtlIGl0IHRvIGhlcmUgc2VyIGlzIG5vdCBudWxsLgotICAgICAgcmV0dXJuIHNlcjsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemVyVHJhY2UuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXplclRyYWNlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDA3MTA0MTIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemVyVHJhY2UuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE1NSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBTZXJpYWxpemVyVHJhY2UuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNSAwODoxNToyNCBzdXJlc2hfZW1haWxpZCBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplcjsKLQotaW1wb3J0IG9yZy54bWwuc2F4LkF0dHJpYnV0ZXM7Ci0KLS8qKgotICogVGhpcyBpbnRlcmZhY2UgZGVmaW5lcyBhIHNldCBvZiBpbnRlZ2VyIGNvbnN0YW50cyB0aGF0IGlkZW50aWZ5IHRyYWNlIGV2ZW50Ci0gKiB0eXBlcy4KLSAqCi0gKiBAeHNsLnVzYWdlIGludGVybmFsCi0gKi8KLQotcHVibGljIGludGVyZmFjZSBTZXJpYWxpemVyVHJhY2UgewotCi0gIC8qKgotICAgKiBFdmVudCB0eXBlIGdlbmVyYXRlZCB3aGVuIGEgZG9jdW1lbnQgYmVnaW5zLgotICAgKgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVZFTlRUWVBFX1NUQVJURE9DVU1FTlQgPSAxOwotCi0gIC8qKgotICAgKiBFdmVudCB0eXBlIGdlbmVyYXRlZCB3aGVuIGEgZG9jdW1lbnQgZW5kcy4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVWRU5UVFlQRV9FTkRET0NVTUVOVCA9IDI7Ci0KLSAgLyoqCi0gICAqIEV2ZW50IHR5cGUgZ2VuZXJhdGVkIHdoZW4gYW4gZWxlbWVudCBiZWdpbnMgKGFmdGVyIHRoZSBhdHRyaWJ1dGVzIGhhdmUgYmVlbiBwcm9jZXNzZWQgYnV0IGJlZm9yZSB0aGUgY2hpbGRyZW4gaGF2ZSBiZWVuIGFkZGVkKS4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVWRU5UVFlQRV9TVEFSVEVMRU1FTlQgPSAzOwotCi0gIC8qKgotICAgKiBFdmVudCB0eXBlIGdlbmVyYXRlZCB3aGVuIGFuIGVsZW1lbnQgZW5kcywgYWZ0ZXIgaXQncyBjaGlsZHJlbiBoYXZlIGJlZW4gYWRkZWQuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFVkVOVFRZUEVfRU5ERUxFTUVOVCA9IDQ7Ci0KLSAgLyoqCi0gICAqIEV2ZW50IHR5cGUgZ2VuZXJhdGVkIGZvciBjaGFyYWN0ZXIgZGF0YSAoQ0RBVEEgYW5kIElnbm9yYWJsZSBXaGl0ZXNwYWNlIGhhdmUgdGhlaXIgb3duIGV2ZW50cykuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFVkVOVFRZUEVfQ0hBUkFDVEVSUyA9IDU7Ci0KLSAgLyoqCi0gICAqIEV2ZW50IHR5cGUgZ2VuZXJhdGVkIGZvciBpZ25vcmFibGUgd2hpdGVzcGFjZSAoSSdtIG5vdCBzdXJlIGhvdyBtdWNoIHRoaXMgaXMgYWN0dWFsbHkgY2FsbGVkLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVZFTlRUWVBFX0lHTk9SQUJMRVdISVRFU1BBQ0UgPSA2OwotCi0gIC8qKgotICAgKiBFdmVudCB0eXBlIGdlbmVyYXRlZCBmb3IgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbnMuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFVkVOVFRZUEVfUEkgPSA3OwotCi0gIC8qKgotICAgKiBFdmVudCB0eXBlIGdlbmVyYXRlZCBhZnRlciBhIGNvbW1lbnQgaGFzIGJlZW4gYWRkZWQuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFVkVOVFRZUEVfQ09NTUVOVCA9IDg7Ci0KLSAgLyoqCi0gICAqIEV2ZW50IHR5cGUgZ2VuZXJhdGUgYWZ0ZXIgYW4gZW50aXR5IHJlZiBpcyBjcmVhdGVkLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVZFTlRUWVBFX0VOVElUWVJFRiA9IDk7Ci0KLSAgLyoqCi0gICAqIEV2ZW50IHR5cGUgZ2VuZXJhdGVkIGFmdGVyIENEQVRBIGlzIGdlbmVyYXRlZC4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVWRU5UVFlQRV9DREFUQSA9IDEwOwotCi0gIC8qKgotICAgKiBFdmVudCB0eXBlIGdlbmVyYXRlZCB3aGVuIGNoYXJhY3RlcnMgbWlnaHQgYmUgd3JpdHRlbiB0byBhbiBvdXRwdXQgc3RyZWFtLAotICAgKiAgYnV0ICB0aGVzZSBjaGFyYWN0ZXJzIG5ldmVyIGFyZS4gVGhleSB3aWxsIHVsdGltYXRlbHkgYmUgd3JpdHRlbiBvdXQgdmlhCi0gICAqIEVWRU5UVFlQRV9PVVRQVVRfQ0hBUkFDVEVSUy4gVGhpcyB0eXBlIGlzIHVzZWQgYXMgYXR0cmlidXRlcyBhcmUgY29sbGVjdGVkLgotICAgKiBXaGVuZXZlciB0aGUgYXR0cmlidXRlcyBjaGFuZ2UgdGhpcyBldmVudCB0eXBlIGlzIGZpcmVkLiBBdCB0aGUgdmVyeSBlbmQKLSAgICogaG93ZXZlciwgd2hlbiB0aGUgYXR0cmlidXRlcyBkbyBub3QgY2hhbmdlIGFueW1vcmUgYW5kIGFyZSBnb2luZyB0byBiZQotICAgKiBvdXB1dCB0byB0aGUgZG9jdW1lbnQgdGhlIHJlYWwgY2hhcmFjdGVycyB3aWxsIGJlIHdyaXR0ZW4gb3V0IHVzaW5nIHRoZQotICAgKiBFVkVOVFRZUEVfT1VUUFVUX0NIQVJBQ1RFUlMuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFVkVOVFRZUEVfT1VUUFVUX1BTRVVET19DSEFSQUNURVJTID0gMTE7Ci0KLSAgLyoqCi0gICAqIEV2ZW50IHR5cGUgZ2VuZXJhdGVkIHdoZW4gY2hhcmFjdGVycyBhcmUgd3JpdHRlbiB0byBhbiBvdXRwdXQgc3RyZWFtLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVZFTlRUWVBFX09VVFBVVF9DSEFSQUNURVJTID0gMTI7Ci0KLQotICAvKioKLSAgICogVGVsbCBpZiB0cmFjZSBsaXN0ZW5lcnMgYXJlIHByZXNlbnQuCi0gICAqCi0gICAqIEByZXR1cm4gVHJ1ZSBpZiB0aGVyZSBhcmUgdHJhY2UgbGlzdGVuZXJzCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBoYXNUcmFjZUxpc3RlbmVycygpOwotCi0gIC8qKgotICAgKiBGaXJlIHN0YXJ0RG9jdW1lbnQsIGVuZERvY3VtZW50IGV2ZW50cy4KLSAgICoKLSAgICogQHBhcmFtIGV2ZW50VHlwZSBPbmUgb2YgdGhlIEVWRU5UVFlQRV9YWFggY29uc3RhbnRzLgotICAgKi8KLSAgcHVibGljIHZvaWQgZmlyZUdlbmVyYXRlRXZlbnQoaW50IGV2ZW50VHlwZSk7Ci0KLSAgLyoqCi0gICAqIEZpcmUgc3RhcnRFbGVtZW50LCBlbmRFbGVtZW50IGV2ZW50cy4KLSAgICoKLSAgICogQHBhcmFtIGV2ZW50VHlwZSBPbmUgb2YgdGhlIEVWRU5UVFlQRV9YWFggY29uc3RhbnRzLgotICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgZWxlbWVudC4KLSAgICogQHBhcmFtIGF0dHMgVGhlIFNBWCBhdHRyaWJ1dGUgbGlzdC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGZpcmVHZW5lcmF0ZUV2ZW50KGludCBldmVudFR5cGUsIFN0cmluZyBuYW1lLCBBdHRyaWJ1dGVzIGF0dHMpOwotCi0gIC8qKgotICAgKiBGaXJlIGNoYXJhY3RlcnMsIGNkYXRhIGV2ZW50cy4KLSAgICoKLSAgICogQHBhcmFtIGV2ZW50VHlwZSBPbmUgb2YgdGhlIEVWRU5UVFlQRV9YWFggY29uc3RhbnRzLgotICAgKiBAcGFyYW0gY2ggVGhlIGNoYXIgYXJyYXkgZnJvbSB0aGUgU0FYIGV2ZW50LgotICAgKiBAcGFyYW0gc3RhcnQgVGhlIHN0YXJ0IG9mZnNldCB0byBiZSB1c2VkIGluIHRoZSBjaGFyIGFycmF5LgotICAgKiBAcGFyYW0gbGVuZ3RoIFRoZSBlbmQgb2Zmc2V0IHRvIGJlIHVzZWQgaW4gdGhlIGNoYXJhIGFycmF5LgotICAgKi8KLSAgcHVibGljIHZvaWQgZmlyZUdlbmVyYXRlRXZlbnQoaW50IGV2ZW50VHlwZSwgY2hhciBjaFtdLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpOwotCi0gIC8qKgotICAgKiBGaXJlIHByb2Nlc3NpbmdJbnN0cnVjdGlvbiBldmVudHMuCi0gICAqCi0gICAqIEBwYXJhbSBldmVudFR5cGUgT25lIG9mIHRoZSBFVkVOVFRZUEVfWFhYIGNvbnN0YW50cy4KLSAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24uCi0gICAqIEBwYXJhbSBkYXRhIFRoZSBwcm9jZXNzaW5nIGluc3RydWN0aW9uIGRhdGEuCi0gICAqLwotICBwdWJsaWMgdm9pZCBmaXJlR2VuZXJhdGVFdmVudChpbnQgZXZlbnRUeXBlLCBTdHJpbmcgbmFtZSwgU3RyaW5nIGRhdGEpOwotCi0KLSAgLyoqCi0gICAqIEZpcmUgY29tbWVudCBhbmQgZW50aXR5IHJlZiBldmVudHMuCi0gICAqCi0gICAqIEBwYXJhbSBldmVudFR5cGUgT25lIG9mIHRoZSBFVkVOVFRZUEVfWFhYIGNvbnN0YW50cy4KLSAgICogQHBhcmFtIGRhdGEgVGhlIGNvbW1lbnQgb3IgZW50aXR5IHJlZiBkYXRhLgotICAgKi8KLSAgcHVibGljIHZvaWQgZmlyZUdlbmVyYXRlRXZlbnQoaW50IGV2ZW50VHlwZSwgU3RyaW5nIGRhdGEpOwotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6ZXJUcmFjZVdyaXRlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemVyVHJhY2VXcml0ZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNDgyZmFhZC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6ZXJUcmFjZVdyaXRlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzQzICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDMtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFNlcmlhbGl6ZXJUcmFjZVdyaXRlci5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE1IDA4OjE1OjI1IHN1cmVzaF9lbWFpbGlkIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyOwotCi1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKLWltcG9ydCBqYXZhLmlvLldyaXRlcjsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIHdyYXBzIHRoZSByZWFsIHdyaXRlciwgaXQgb25seSBwdXJwb3NlIGlzIHRvIHNlbmQKLSAqIENIQVJBQ1RFUlRPU1RSRUFNIGV2ZW50cyB0byB0aGUgdHJhY2UgbGlzdGVuZXIuCi0gKiBFYWNoIG1ldGhvZCBpbW1lZGlhdGVseSBzZW5kcyB0aGUgY2FsbCB0byB0aGUgd3JhcHBlZCB3cml0ZXIgdW5jaGFuZ2VkLCBidXQKLSAqIGluIGFkZGl0aW9uIGl0IGNvbGxlY3RzIGNoYXJhY3RlcnMgdG8gYmUgaXNzdWVkIHRvIGEgdHJhY2UgbGlzdGVuZXIuCi0gKgotICogSW4gdGhpcyB3YXkgdGhlIHRyYWNlCi0gKiBsaXN0ZW5lciBrbm93cyB3aGF0IGNoYXJhY3RlcnMgaGF2ZSBiZWVuIHdyaXR0ZW4gdG8gdGhlIG91dHB1dCBXcml0ZXIuCi0gKgotICogVGhlcmUgbWF5IHN0aWxsIGJlIGRpZmZlcmVuY2VzIGluIHdoYXQgdGhlIHRyYWNlIGV2ZW50cyBzYXkgaXMgZ29pbmcgdG8gdGhlCi0gKiBvdXRwdXQgd3JpdGVyIGFuZCB3aGF0IGlzIHJlYWxseSBnb2luZyB0aGVyZS4gVGhlc2UgZGlmZmVyZW5jZXMgd2lsbCBiZSBkdWUKLSAqIHRvIHRoZSBmYWN0IHRoYXQgdGhpcyBjbGFzcyBpcyBVVEYtOCBlbmNvZGluZyBiZWZvcmUgZW1pdGluZyB0aGUgdHJhY2UgZXZlbnQKLSAqIGFuZCB0aGUgdW5kZXJseWluZyB3cml0ZXIgbWF5IG5vdCBiZSBVVEYtOCBlbmNvZGluZy4gVGhlcmUgbWF5IGFsc28gYmUKLSAqIGVuY29kaW5nIGRpZmZlcmVuY2VzLiAgU28gdGhlIG1haW4gcHVwb3NlIG9mIHRoaXMgY2xhc3MgaXMgdG8gcHJvdmlkZSBhCi0gKiByZXNvbmFibGUgZmFjc2ltaWxlIG9mIHRoZSB0cnVlIG91dHB1dC4KLSAqCi0gKiBAeHNsLnVzYWdlIGludGVybmFsCi0gKi8KLWZpbmFsIGNsYXNzIFNlcmlhbGl6ZXJUcmFjZVdyaXRlciBleHRlbmRzIFdyaXRlciBpbXBsZW1lbnRzIFdyaXRlckNoYWluCi17Ci0KLSAgICAvKiogVGhlIHJlYWwgd3JpdGVyIHRvIGltbWVkaWF0ZWx5IHdyaXRlIHRvLgotICAgICAqIFRoaXMgcmVmZXJlbmNlIG1heSBiZSBudWxsLCBpbiB3aGljaCBjYXNlIG5vdGhpbmcgaXMgd3JpdHRlbiBvdXQsIGJ1dAotICAgICAqIG9ubHkgdGhlIHRyYWNlIGV2ZW50cyBhcmUgZmlyZWQgZm9yIG91dHB1dC4KLSAgICAgKi8KLSAgICBwcml2YXRlIGZpbmFsIGphdmEuaW8uV3JpdGVyIG1fd3JpdGVyOwotCi0gICAgLyoqIFRoZSB0cmFjZXIgdG8gc2VuZCBldmVudHMgdG8gKi8KLSAgICBwcml2YXRlIGZpbmFsIFNlcmlhbGl6ZXJUcmFjZSBtX3RyYWNlcjsKLQotICAgIC8qKiBUaGUgc2l6ZSBvZiB0aGUgaW50ZXJuYWwgYnVmZmVyLCBqdXN0IHRvIGtlZXAgdG9vIG1hbnkKLSAgICAgKiBldmVudHMgZnJvbSBiZWluZyBzZW50IHRvIHRoZSB0cmFjZXIKLSAgICAgKi8KLSAgICBwcml2YXRlIGludCBidWZfbGVuZ3RoOwotCi0gICAgLyoqCi0gICAgICogSW50ZXJuYWwgYnVmZmVyIHRvIGNvbGxlY3QgdGhlIGNoYXJhY3RlcnMgdG8gZ28gdG8gdGhlIHRyYWNlIGxpc3RlbmVyLgotICAgICAqCi0gICAgICovCi0gICAgcHJpdmF0ZSBieXRlIGJ1ZltdOwotCi0gICAgLyoqCi0gICAgICogSG93IG1hbnkgYnl0ZXMgaGF2ZSBiZWVuIGNvbGxlY3RlZCBhbmQgc3RpbGwgbmVlZCB0byBnbyB0byB0cmFjZQotICAgICAqIGxpc3RlbmVyLgotICAgICAqLwotICAgIHByaXZhdGUgaW50IGNvdW50OwotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlcyBvciByZXBsYWNlcyB0aGUgaW50ZXJuYWwgYnVmZmVyLCBhbmQgbWFrZXMgc3VyZSBpdCBoYXMgYSBmZXcKLSAgICAgKiBleHRyYSBieXRlcyBzbGlnaHQgb3ZlcmZsb3cgb2YgdGhlIGxhc3QgVVRGOCBlbmNvZGVkIGNoYXJhY3Rlci4KLSAgICAgKiBAcGFyYW0gc2l6ZQotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCBzZXRCdWZmZXJTaXplKGludCBzaXplKQotICAgIHsKLSAgICAgICAgYnVmID0gbmV3IGJ5dGVbc2l6ZSArIDNdOwotICAgICAgICBidWZfbGVuZ3RoID0gc2l6ZTsKLSAgICAgICAgY291bnQgPSAwOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdG9yLgotICAgICAqIElmIHRoZSB3cml0ZXIgcGFzc2VkIGluIGlzIG51bGwsIHRoZW4gdGhpcyBTZXJpYWxpemVyVHJhY2VXcml0ZXIgd2lsbAotICAgICAqIG9ubHkgc2lnbmFsIHRyYWNlIGV2ZW50cyBvZiB3aGF0IHdvdWxkIGhhdmUgYmVlbiB3cml0dGVuIHRvIHRoYXQgd3JpdGVyLgotICAgICAqIElmIHRoZSB3cml0ZXIgcGFzc2VkIGluIGlzIG5vdCBudWxsIHRoZW4gdGhlIHRyYWNlIGV2ZW50cyB3aWxsIG1pcnJvcgotICAgICAqIHdoYXQgaXMgZ29pbmcgdG8gdGhhdCB3cml0ZXIuIEluIHRoaXMgd2F5IHRvb2xzLCBzdWNoIGFzIGEgZGVidWdnZXIsIGNhbgotICAgICAqIGdhdGhlciBpbmZvcm1hdGlvbiBvbiB3aGF0IGlzIGJlaW5nIHdyaXR0ZW4gb3V0LgotICAgICAqCi0gICAgICogQHBhcmFtIG91dCB0aGUgV3JpdGVyIHRvIHdyaXRlIHRvIChwb3NzaWJseSBudWxsKQotICAgICAqIEBwYXJhbSB0cmFjZXIgdGhlIHRyYWNlciB0byBpbmZvcm0gdGhhdCBjaGFyYWN0ZXJzIGFyZSBiZWluZyB3cml0dGVuCi0gICAgICovCi0gICAgcHVibGljIFNlcmlhbGl6ZXJUcmFjZVdyaXRlcihXcml0ZXIgb3V0LCBTZXJpYWxpemVyVHJhY2UgdHJhY2VyKQotICAgIHsKLSAgICAgICAgbV93cml0ZXIgPSBvdXQ7Ci0gICAgICAgIG1fdHJhY2VyID0gdHJhY2VyOwotICAgICAgICBzZXRCdWZmZXJTaXplKDEwMjQpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEZsdXNoIG91dCB0aGUgY29sbGVjdGVkIGNoYXJhY3RlcnMgYnkgc2VuZGluZyB0aGVtIHRvIHRoZSB0cmFjZQotICAgICAqIGxpc3RlbmVyLiAgVGhlc2UgY2hhcmFjdGVycyBhcmUgbmV2ZXIgd3JpdHRlbiB0byB0aGUgcmVhbCB3cml0ZXIKLSAgICAgKiAobV93cml0ZXIpIGJlY2F1c2UgdGhhdCBoYXMgYWxyZWFkeSBoYXBwZW5lZCB3aXRoIGV2ZXJ5IG1ldGhvZAotICAgICAqIGNhbGwuIFRoaXMgbWV0aG9kIHNpbXBsZSBpbmZvcm1zIHRoZSBsaXN0ZW5lciBvZiB3aGF0IGhhcyBhbHJlYWR5Ci0gICAgICogaGFwcGVuZWQuCi0gICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCBmbHVzaEJ1ZmZlcigpIHRocm93cyBJT0V4Y2VwdGlvbgotICAgIHsKLQotICAgICAgICAvLyBKdXN0IGZvciB0cmFjaW5nIHB1cnBvc2VzCi0gICAgICAgIGlmIChjb3VudCA+IDApCi0gICAgICAgIHsKLSAgICAgICAgICAgIGNoYXJbXSBjaGFycyA9IG5ldyBjaGFyW2NvdW50XTsKLSAgICAgICAgICAgIGZvcihpbnQgaT0wOyBpPGNvdW50OyBpKyspCi0gICAgICAgICAgICAgICAgY2hhcnNbaV0gPSAoY2hhcikgYnVmW2ldOwotCi0gICAgICAgICAgICBpZiAobV90cmFjZXIgIT0gbnVsbCkKLSAgICAgICAgICAgICAgICBtX3RyYWNlci5maXJlR2VuZXJhdGVFdmVudCgKLSAgICAgICAgICAgICAgICAgICAgU2VyaWFsaXplclRyYWNlLkVWRU5UVFlQRV9PVVRQVVRfQ0hBUkFDVEVSUywKLSAgICAgICAgICAgICAgICAgICAgY2hhcnMsCi0gICAgICAgICAgICAgICAgICAgIDAsCi0gICAgICAgICAgICAgICAgICAgIGNoYXJzLmxlbmd0aCk7Ci0KLSAgICAgICAgICAgIGNvdW50ID0gMDsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEZsdXNoIHRoZSBpbnRlcm5hbCBidWZmZXIgYW5kIGZsdXNoIHRoZSBXcml0ZXIKLSAgICAgKiBAc2VlIGphdmEuaW8uV3JpdGVyI2ZsdXNoKCkKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBmbHVzaCgpIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uCi0gICAgewotICAgICAgICAvLyBzZW5kIHRvIHRoZSByZWFsIHdyaXRlcgotICAgICAgICBpZiAobV93cml0ZXIgIT0gbnVsbCkKLSAgICAgICAgICAgIG1fd3JpdGVyLmZsdXNoKCk7Ci0KLSAgICAgICAgLy8gZnJvbSBoZXJlIG9uIGp1c3QgZm9yIHRyYWNpbmcgcHVycG9zZXMKLSAgICAgICAgZmx1c2hCdWZmZXIoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBGbHVzaCB0aGUgaW50ZXJuYWwgYnVmZmVyIGFuZCBjbG9zZSB0aGUgV3JpdGVyCi0gICAgICogQHNlZSBqYXZhLmlvLldyaXRlciNjbG9zZSgpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgLy8gc2VuZCB0byB0aGUgcmVhbCB3cml0ZXIKLSAgICAgICAgaWYgKG1fd3JpdGVyICE9IG51bGwpCi0gICAgICAgICAgICBtX3dyaXRlci5jbG9zZSgpOwotCi0gICAgICAgIC8vIGZyb20gaGVyZSBvbiBqdXN0IGZvciB0cmFjaW5nIHB1cnBvc2VzCi0gICAgICAgIGZsdXNoQnVmZmVyKCk7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBXcml0ZSBhIHNpbmdsZSBjaGFyYWN0ZXIuICBUaGUgY2hhcmFjdGVyIHRvIGJlIHdyaXR0ZW4gaXMgY29udGFpbmVkIGluCi0gICAgICogdGhlIDE2IGxvdy1vcmRlciBiaXRzIG9mIHRoZSBnaXZlbiBpbnRlZ2VyIHZhbHVlOyB0aGUgMTYgaGlnaC1vcmRlciBiaXRzCi0gICAgICogYXJlIGlnbm9yZWQuCi0gICAgICoKLSAgICAgKiA8cD4gU3ViY2xhc3NlcyB0aGF0IGludGVuZCB0byBzdXBwb3J0IGVmZmljaWVudCBzaW5nbGUtY2hhcmFjdGVyIG91dHB1dAotICAgICAqIHNob3VsZCBvdmVycmlkZSB0aGlzIG1ldGhvZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjICBpbnQgc3BlY2lmeWluZyBhIGNoYXJhY3RlciB0byBiZSB3cml0dGVuLgotICAgICAqIEBleGNlcHRpb24gIElPRXhjZXB0aW9uICBJZiBhbiBJL08gZXJyb3Igb2NjdXJzCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgd3JpdGUoZmluYWwgaW50IGMpIHRocm93cyBJT0V4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgLy8gc2VuZCB0byB0aGUgcmVhbCB3cml0ZXIKLSAgICAgICAgaWYgKG1fd3JpdGVyICE9IG51bGwpCi0gICAgICAgICAgICBtX3dyaXRlci53cml0ZShjKTsKLQotICAgICAgICAvLyAtLS0tLS0tLS0tIGZyb20gaGVyZSBvbiBqdXN0IGNvbGxlY3QgZm9yIHRyYWNpbmcgcHVycG9zZXMKLQotICAgICAgICAvKiBJZiB3ZSBhcmUgY2xvc2UgdG8gdGhlIGVuZCBvZiB0aGUgYnVmZmVyIHRoZW4gZmx1c2ggaXQuCi0gICAgICAgICAqIFJlbWVtYmVyIHRoZSBidWZmZXIgY2FuIGhvbGQgYSBmZXcgbW9yZSBjaGFyYWN0ZXJzIHRoYW4gYnVmX2xlbmd0aAotICAgICAgICAgKi8KLSAgICAgICAgaWYgKGNvdW50ID49IGJ1Zl9sZW5ndGgpCi0gICAgICAgICAgICBmbHVzaEJ1ZmZlcigpOwotCi0gICAgICAgIGlmIChjIDwgMHg4MCkKLSAgICAgICAgewotICAgICAgICAgICAgYnVmW2NvdW50KytdID0gKGJ5dGUpIChjKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChjIDwgMHg4MDApCi0gICAgICAgIHsKLSAgICAgICAgICAgIGJ1Zltjb3VudCsrXSA9IChieXRlKSAoMHhjMCArIChjID4+IDYpKTsKLSAgICAgICAgICAgIGJ1Zltjb3VudCsrXSA9IChieXRlKSAoMHg4MCArIChjICYgMHgzZikpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotICAgICAgICAgICAgYnVmW2NvdW50KytdID0gKGJ5dGUpICgweGUwICsgKGMgPj4gMTIpKTsKLSAgICAgICAgICAgIGJ1Zltjb3VudCsrXSA9IChieXRlKSAoMHg4MCArICgoYyA+PiA2KSAmIDB4M2YpKTsKLSAgICAgICAgICAgIGJ1Zltjb3VudCsrXSA9IChieXRlKSAoMHg4MCArIChjICYgMHgzZikpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogV3JpdGUgYSBwb3J0aW9uIG9mIGFuIGFycmF5IG9mIGNoYXJhY3RlcnMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gIGNoYXJzICBBcnJheSBvZiBjaGFyYWN0ZXJzCi0gICAgICogQHBhcmFtICBzdGFydCAgIE9mZnNldCBmcm9tIHdoaWNoIHRvIHN0YXJ0IHdyaXRpbmcgY2hhcmFjdGVycwotICAgICAqIEBwYXJhbSAgbGVuZ3RoICAgTnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gd3JpdGUKLSAgICAgKgotICAgICAqIEBleGNlcHRpb24gIElPRXhjZXB0aW9uICBJZiBhbiBJL08gZXJyb3Igb2NjdXJzCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB3cml0ZShmaW5hbCBjaGFyIGNoYXJzW10sIGZpbmFsIGludCBzdGFydCwgZmluYWwgaW50IGxlbmd0aCkKLSAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIC8vIHNlbmQgdG8gdGhlIHJlYWwgd3JpdGVyCi0gICAgICAgIGlmIChtX3dyaXRlciAhPSBudWxsKQotICAgICAgICAgICAgbV93cml0ZXIud3JpdGUoY2hhcnMsIHN0YXJ0LCBsZW5ndGgpOwotCi0gICAgICAgIC8vIGZyb20gaGVyZSBvbiBqdXN0IGNvbGxlY3QgZm9yIHRyYWNpbmcgcHVycG9zZXMKLSAgICAgICAgaW50IGxlbmd0aHgzID0gKGxlbmd0aCA8PCAxKSArIGxlbmd0aDsKLQotICAgICAgICBpZiAobGVuZ3RoeDMgPj0gYnVmX2xlbmd0aCkKLSAgICAgICAgewotCi0gICAgICAgICAgICAvKiBJZiB0aGUgcmVxdWVzdCBsZW5ndGggZXhjZWVkcyB0aGUgc2l6ZSBvZiB0aGUgb3V0cHV0IGJ1ZmZlciwKLSAgICAgICAgICAgICAgKiBmbHVzaCB0aGUgb3V0cHV0IGJ1ZmZlciBhbmQgbWFrZSB0aGUgYnVmZmVyIGJpZ2dlciB0byBoYW5kbGUuCi0gICAgICAgICAgICAgICovCi0KLSAgICAgICAgICAgIGZsdXNoQnVmZmVyKCk7Ci0gICAgICAgICAgICBzZXRCdWZmZXJTaXplKDIgKiBsZW5ndGh4Myk7Ci0KLSAgICAgICAgfQotCi0gICAgICAgIGlmIChsZW5ndGh4MyA+IGJ1Zl9sZW5ndGggLSBjb3VudCkKLSAgICAgICAgewotICAgICAgICAgICAgZmx1c2hCdWZmZXIoKTsKLSAgICAgICAgfQotCi0gICAgICAgIGZpbmFsIGludCBuID0gbGVuZ3RoICsgc3RhcnQ7Ci0gICAgICAgIGZvciAoaW50IGkgPSBzdGFydDsgaSA8IG47IGkrKykKLSAgICAgICAgewotICAgICAgICAgICAgZmluYWwgY2hhciBjID0gY2hhcnNbaV07Ci0KLSAgICAgICAgICAgIGlmIChjIDwgMHg4MCkKLSAgICAgICAgICAgICAgICBidWZbY291bnQrK10gPSAoYnl0ZSkgKGMpOwotICAgICAgICAgICAgZWxzZSBpZiAoYyA8IDB4ODAwKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIGJ1Zltjb3VudCsrXSA9IChieXRlKSAoMHhjMCArIChjID4+IDYpKTsKLSAgICAgICAgICAgICAgICBidWZbY291bnQrK10gPSAoYnl0ZSkgKDB4ODAgKyAoYyAmIDB4M2YpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBidWZbY291bnQrK10gPSAoYnl0ZSkgKDB4ZTAgKyAoYyA+PiAxMikpOwotICAgICAgICAgICAgICAgIGJ1Zltjb3VudCsrXSA9IChieXRlKSAoMHg4MCArICgoYyA+PiA2KSAmIDB4M2YpKTsKLSAgICAgICAgICAgICAgICBidWZbY291bnQrK10gPSAoYnl0ZSkgKDB4ODAgKyAoYyAmIDB4M2YpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgfQotCi0gICAgLyoqCi0gICAgICogV3JpdGUgYSBzdHJpbmcuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gIHMgIFN0cmluZyB0byBiZSB3cml0dGVuCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uICBJT0V4Y2VwdGlvbiAgSWYgYW4gSS9PIGVycm9yIG9jY3VycwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHdyaXRlKGZpbmFsIFN0cmluZyBzKSB0aHJvd3MgSU9FeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIC8vIHNlbmQgdG8gdGhlIHJlYWwgd3JpdGVyCi0gICAgICAgIGlmIChtX3dyaXRlciAhPSBudWxsKQotICAgICAgICAgICAgbV93cml0ZXIud3JpdGUocyk7Ci0KLSAgICAgICAgLy8gZnJvbSBoZXJlIG9uIGp1c3QgY29sbGVjdCBmb3IgdHJhY2luZyBwdXJwb3NlcwotICAgICAgICBmaW5hbCBpbnQgbGVuZ3RoID0gcy5sZW5ndGgoKTsKLQotICAgICAgICAvLyBXZSBtdWx0aXBseSB0aGUgbGVuZ3RoIGJ5IHRocmVlIHNpbmNlIHRoaXMgaXMgdGhlIG1heGltdW0gbGVuZ3RoCi0gICAgICAgIC8vIG9mIHRoZSBjaGFyYWN0ZXJzIHRoYXQgd2UgY2FuIHB1dCBpbnRvIHRoZSBidWZmZXIuICBJdCBpcyBwb3NzaWJsZQotICAgICAgICAvLyBmb3IgZWFjaCBVbmljb2RlIGNoYXJhY3RlciB0byBleHBhbmQgdG8gdGhyZWUgYnl0ZXMuCi0KLSAgICAgICAgaW50IGxlbmd0aHgzID0gKGxlbmd0aCA8PCAxKSArIGxlbmd0aDsKLQotICAgICAgICBpZiAobGVuZ3RoeDMgPj0gYnVmX2xlbmd0aCkKLSAgICAgICAgewotCi0gICAgICAgICAgICAvKiBJZiB0aGUgcmVxdWVzdCBsZW5ndGggZXhjZWVkcyB0aGUgc2l6ZSBvZiB0aGUgb3V0cHV0IGJ1ZmZlciwKLSAgICAgICAgICAgICAgKiBmbHVzaCB0aGUgb3V0cHV0IGJ1ZmZlciBhbmQgbWFrZSB0aGUgYnVmZmVyIGJpZ2dlciB0byBoYW5kbGUuCi0gICAgICAgICAgICAgICovCi0KLSAgICAgICAgICAgIGZsdXNoQnVmZmVyKCk7Ci0gICAgICAgICAgICBzZXRCdWZmZXJTaXplKDIgKiBsZW5ndGh4Myk7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAobGVuZ3RoeDMgPiBidWZfbGVuZ3RoIC0gY291bnQpCi0gICAgICAgIHsKLSAgICAgICAgICAgIGZsdXNoQnVmZmVyKCk7Ci0gICAgICAgIH0KLQotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKQotICAgICAgICB7Ci0gICAgICAgICAgICBmaW5hbCBjaGFyIGMgPSBzLmNoYXJBdChpKTsKLQotICAgICAgICAgICAgaWYgKGMgPCAweDgwKQotICAgICAgICAgICAgICAgIGJ1Zltjb3VudCsrXSA9IChieXRlKSAoYyk7Ci0gICAgICAgICAgICBlbHNlIGlmIChjIDwgMHg4MDApCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgYnVmW2NvdW50KytdID0gKGJ5dGUpICgweGMwICsgKGMgPj4gNikpOwotICAgICAgICAgICAgICAgIGJ1Zltjb3VudCsrXSA9IChieXRlKSAoMHg4MCArIChjICYgMHgzZikpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIGJ1Zltjb3VudCsrXSA9IChieXRlKSAoMHhlMCArIChjID4+IDEyKSk7Ci0gICAgICAgICAgICAgICAgYnVmW2NvdW50KytdID0gKGJ5dGUpICgweDgwICsgKChjID4+IDYpICYgMHgzZikpOwotICAgICAgICAgICAgICAgIGJ1Zltjb3VudCsrXSA9IChieXRlKSAoMHg4MCArIChjICYgMHgzZikpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSB3cml0ZXIgdGhhdCB0aGlzIG9uZSBkaXJlY3RseSB3cmFwcy4KLSAgICAgKi8KLSAgICBwdWJsaWMgV3JpdGVyIGdldFdyaXRlcigpCi0gICAgewotICAgICAgICByZXR1cm4gbV93cml0ZXI7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBPdXRwdXRTdHJlYW0gdGhhdCBpcyB0aGUgYXQgdGhlIGVuZCBvZiB0aGUKLSAgICAgKiBjaGFpbiBvZiB3cml0ZXJzLgotICAgICAqLwotICAgIHB1YmxpYyBPdXRwdXRTdHJlYW0gZ2V0T3V0cHV0U3RyZWFtKCkKLSAgICB7Ci0gICAgICAgIE91dHB1dFN0cmVhbSByZXR2YWwgPSBudWxsOwotICAgICAgICBpZiAobV93cml0ZXIgaW5zdGFuY2VvZiBXcml0ZXJDaGFpbikKLSAgICAgICAgICAgIHJldHZhbCA9ICgoV3JpdGVyQ2hhaW4pIG1fd3JpdGVyKS5nZXRPdXRwdXRTdHJlYW0oKTsKLSAgICAgICAgcmV0dXJuIHJldHZhbDsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1RvSFRNTFNBWEhhbmRsZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvVG9IVE1MU0FYSGFuZGxlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1OTZhNjQxLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvVG9IVE1MU0FYSGFuZGxlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNzQ3ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFRvSFRNTFNBWEhhbmRsZXIuamF2YSx2IDEuMyAyMDA1LzA5LzI4IDEzOjQ5OjA3IHB2ZWR1bGEgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplcjsKLQotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci1pbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5pby5Xcml0ZXI7Ci1pbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlJlc3VsdDsKLQotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci1pbXBvcnQgb3JnLnhtbC5zYXguQXR0cmlidXRlczsKLWltcG9ydCBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5Mb2NhdG9yOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXI7Ci0KLS8qKgotICogVGhpcyBjbGFzcyBhY2NlcHRzIFNBWC1saWtlIGNhbGxzLCB0aGVuIHNlbmRzIHRydWUgU0FYIGNhbGxzIHRvIGEKLSAqIHdyYXBwZWQgU0FYIGhhbmRsZXIuICBUaGVyZSBpcyBvcHRpbWl6YXRpb24gZG9uZSBrbm93aW5nIHRoYXQgdGhlIHVsdGltYXRlCi0gKiBvdXRwdXQgaXMgSFRNTC4KLSAqCi0gKiBUaGlzIGNsYXNzIGlzIG5vdCBhIHB1YmxpYyBBUEkuCi0gKgotICogQHhzbC51c2FnZSBpbnRlcm5hbAotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgVG9IVE1MU0FYSGFuZGxlciBleHRlbmRzIFRvU0FYSGFuZGxlcgotewotICAgICAgICAvKioKLSAgICAgICAgICogIEhhbmRsZSBkb2N1bWVudCB0eXBlIGRlY2xhcmF0aW9uIChmb3IgZmlyc3QgZWxlbWVudCBvbmx5KQotICAgICAgICAgKi8KLSAgICAgICAgcHJpdmF0ZSBib29sZWFuIG1fZHRkSGFuZGxlZCA9IGZhbHNlOwotCi0gICAgLyoqCi0gICAgICogS2VlcHMgdHJhY2sgb2Ygd2hldGhlciBvdXRwdXQgZXNjYXBpbmcgaXMgY3VycmVudGx5IGVuYWJsZWQKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBtX2VzY2FwZVNldHRpbmcgPSB0cnVlOwotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBudWxsLgotICAgICAqIEByZXR1cm4gbnVsbAotICAgICAqIEBzZWUgU2VyaWFsaXplciNnZXRPdXRwdXRGb3JtYXQoKQotICAgICAqLwotICAgIHB1YmxpYyBQcm9wZXJ0aWVzIGdldE91dHB1dEZvcm1hdCgpCi0gICAgewotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXVybnMgbnVsbAotICAgICAqIEByZXR1cm4gbnVsbAotICAgICAqIEBzZWUgU2VyaWFsaXplciNnZXRPdXRwdXRTdHJlYW0oKQotICAgICAqLwotICAgIHB1YmxpYyBPdXRwdXRTdHJlYW0gZ2V0T3V0cHV0U3RyZWFtKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgbnVsbAotICAgICAqIEByZXR1cm4gbnVsbAotICAgICAqIEBzZWUgU2VyaWFsaXplciNnZXRXcml0ZXIoKQotICAgICAqLwotICAgIHB1YmxpYyBXcml0ZXIgZ2V0V3JpdGVyKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIERvZXMgbm90aGluZy4KLSAgICAgKgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGluZGVudChpbnQgbikgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBEb2VzIG5vdGhpbmcuCi0gICAgICogQHNlZSBET01TZXJpYWxpemVyI3NlcmlhbGl6ZShOb2RlKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNlcmlhbGl6ZShOb2RlIG5vZGUpIHRocm93cyBJT0V4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgcmV0dXJuOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFR1cm5zIHNwZWNpYWwgY2hhcmFjdGVyIGVzY2FwaW5nIG9uL29mZi4KLSAgICAgKgotICAgICAqCi0gICAgICogQHBhcmFtIGVzY2FwZSB0cnVlIGlmIGVzY2FwaW5nIGlzIHRvIGJlIHNldCBvbi4KLSAgICAgKgotICAgICAqIEBzZWUgU2VyaWFsaXphdGlvbkhhbmRsZXIjc2V0RXNjYXBpbmcoYm9vbGVhbikKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBzZXRFc2NhcGluZyhib29sZWFuIGVzY2FwZSkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgYm9vbGVhbiBvbGRFc2NhcGVTZXR0aW5nID0gbV9lc2NhcGVTZXR0aW5nOwotICAgICAgICBtX2VzY2FwZVNldHRpbmcgPSBlc2NhcGU7Ci0KLSAgICAgICAgaWYgKGVzY2FwZSkgewotICAgICAgICAgICAgcHJvY2Vzc2luZ0luc3RydWN0aW9uKFJlc3VsdC5QSV9FTkFCTEVfT1VUUFVUX0VTQ0FQSU5HLCAiIik7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oUmVzdWx0LlBJX0RJU0FCTEVfT1VUUFVUX0VTQ0FQSU5HLCAiIik7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gb2xkRXNjYXBlU2V0dGluZzsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBEb2VzIG5vdGhpbmcKLSAgICAgKiBAcGFyYW0gaW5kZW50IHRoZSBudW1iZXIgb2Ygc3BhY2VzIHRvIGluZGVudCBwZXIgaW5kZW50YXRpb24gbGV2ZWwKLSAgICAgKiAoaWdub3JlZCkKLSAgICAgKiBAc2VlIFNlcmlhbGl6YXRpb25IYW5kbGVyI3NldEluZGVudChib29sZWFuKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEluZGVudChib29sZWFuIGluZGVudCkKLSAgICB7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRG9lcyBub3RoaW5nLgotICAgICAqIEBwYXJhbSBmb3JtYXQgdGhpcyBwYXJhbWV0ZXIgaXMgbm90IHVzZWQKLSAgICAgKiBAc2VlIFNlcmlhbGl6ZXIjc2V0T3V0cHV0Rm9ybWF0KFByb3BlcnRpZXMpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0T3V0cHV0Rm9ybWF0KFByb3BlcnRpZXMgZm9ybWF0KQotICAgIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBEb2VzIG5vdGhpbmcuCi0gICAgICogQHBhcmFtIG91dHB1dCB0aGlzIHBhcmFtZXRlciBpcyBpZ25vcmVkCi0gICAgICogQHNlZSBTZXJpYWxpemVyI3NldE91dHB1dFN0cmVhbShPdXRwdXRTdHJlYW0pCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0T3V0cHV0U3RyZWFtKE91dHB1dFN0cmVhbSBvdXRwdXQpCi0gICAgewotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogRG9lcyBub3RoaW5nLgotICAgICAqIEBwYXJhbSB3cml0ZXIgdGhpcyBwYXJhbWV0ZXIgaXMgaWdub3JlZC4KLSAgICAgKiBAc2VlIFNlcmlhbGl6ZXIjc2V0V3JpdGVyKFdyaXRlcikKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRXcml0ZXIoV3JpdGVyIHdyaXRlcikKLSAgICB7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5leHQuRGVjbEhhbmRsZXIjYXR0cmlidXRlRGVjbChTdHJpbmcsIFN0cmluZywgU3RyaW5nLCBTdHJpbmcsIFN0cmluZykKLSAgICAgKi8KLSAgICAvKioKLSAgICAgKiBEb2VzIG5vdGhpbmcuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZU5hbWUgdGhpcyBwYXJhbWV0ZXIgaXMgaWdub3JlZAotICAgICAqIEBwYXJhbSBhTmFtZSB0aGlzIHBhcmFtZXRlciBpcyBpZ25vcmVkCi0gICAgICogQHBhcmFtIHR5cGUgdGhpcyBwYXJhbWV0ZXIgaXMgaWdub3JlZAotICAgICAqIEBwYXJhbSB2YWx1ZURlZmF1bHQgdGhpcyBwYXJhbWV0ZXIgaXMgaWdub3JlZAotICAgICAqIEBwYXJhbSB2YWx1ZSB0aGlzIHBhcmFtZXRlciBpcyBpZ25vcmVkCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5leHQuRGVjbEhhbmRsZXIjYXR0cmlidXRlRGVjbChTdHJpbmcsIFN0cmluZywgU3RyaW5nLFN0cmluZyxTdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgYXR0cmlidXRlRGVjbCgKLSAgICAgICAgU3RyaW5nIGVOYW1lLAotICAgICAgICBTdHJpbmcgYU5hbWUsCi0gICAgICAgIFN0cmluZyB0eXBlLAotICAgICAgICBTdHJpbmcgdmFsdWVEZWZhdWx0LAotICAgICAgICBTdHJpbmcgdmFsdWUpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBEb2VzIG5vdGhpbmcuCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5leHQuRGVjbEhhbmRsZXIjZWxlbWVudERlY2woU3RyaW5nLCBTdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZWxlbWVudERlY2woU3RyaW5nIG5hbWUsIFN0cmluZyBtb2RlbCkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgcmV0dXJuOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguZXh0LkRlY2xIYW5kbGVyI2V4dGVybmFsRW50aXR5RGVjbChTdHJpbmcsIFN0cmluZywgU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGV4dGVybmFsRW50aXR5RGVjbChTdHJpbmcgYXJnMCwgU3RyaW5nIGFyZzEsIFN0cmluZyBhcmcyKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgIH0KLQotICAgIC8qKgotICAgICAqIERvZXMgbm90aGluZy4KLSAgICAgKgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguRFRESGFuZGxlciN1bnBhcnNlZEVudGl0eURlY2wKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBpbnRlcm5hbEVudGl0eURlY2woU3RyaW5nIG5hbWUsIFN0cmluZyB2YWx1ZSkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiB0aGUgZW5kIG9mIGFuIGVsZW1lbnQuCi0gICAgICoKLSAgICAgKiA8cD5UaGUgU0FYIHBhcnNlciB3aWxsIGludm9rZSB0aGlzIG1ldGhvZCBhdCB0aGUgZW5kIG9mIGV2ZXJ5Ci0gICAgICogZWxlbWVudCBpbiB0aGUgWE1MIGRvY3VtZW50OyB0aGVyZSB3aWxsIGJlIGEgY29ycmVzcG9uZGluZwotICAgICAqIHN0YXJ0RWxlbWVudCgpIGV2ZW50IGZvciBldmVyeSBlbmRFbGVtZW50KCkgZXZlbnQgKGV2ZW4gd2hlbiB0aGUKLSAgICAgKiBlbGVtZW50IGlzIGVtcHR5KS48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5JZiB0aGUgZWxlbWVudCBuYW1lIGhhcyBhIG5hbWVzcGFjZSBwcmVmaXgsIHRoZSBwcmVmaXggd2lsbAotICAgICAqIHN0aWxsIGJlIGF0dGFjaGVkIHRvIHRoZSBuYW1lLjwvcD4KLSAgICAgKgotICAgICAqCi0gICAgICogQHBhcmFtIHVyaSBUaGUgTmFtZXNwYWNlIFVSSSwgb3IgdGhlIGVtcHR5IHN0cmluZyBpZiB0aGUKLSAgICAgKiAgICAgICAgZWxlbWVudCBoYXMgbm8gTmFtZXNwYWNlIFVSSSBvciBpZiBOYW1lc3BhY2UKLSAgICAgKiAgICAgICAgcHJvY2Vzc2luZyBpcyBub3QgYmVpbmcgcGVyZm9ybWVkLgotICAgICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGxvY2FsIG5hbWUgKHdpdGhvdXQgcHJlZml4KSwgb3IgdGhlCi0gICAgICogICAgICAgIGVtcHR5IHN0cmluZyBpZiBOYW1lc3BhY2UgcHJvY2Vzc2luZyBpcyBub3QgYmVpbmcKLSAgICAgKiAgICAgICAgcGVyZm9ybWVkLgotICAgICAqIEBwYXJhbSBxTmFtZSBUaGUgcXVhbGlmaWVkIG5hbWUgKHdpdGggcHJlZml4KSwgb3IgdGhlCi0gICAgICogICAgICAgIGVtcHR5IHN0cmluZyBpZiBxdWFsaWZpZWQgbmFtZXMgYXJlIG5vdCBhdmFpbGFibGUuCi0gICAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI2VuZEVsZW1lbnQoU3RyaW5nLCBTdHJpbmcsIFN0cmluZykKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbmRFbGVtZW50KFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUsIFN0cmluZyBxTmFtZSkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgZmx1c2hQZW5kaW5nKCk7Ci0gICAgICAgIG1fc2F4SGFuZGxlci5lbmRFbGVtZW50KHVyaSwgbG9jYWxOYW1lLCBxTmFtZSk7Ci0KLSAgICAgICAgLy8gdGltZSB0byBmaXJlIG9mZiBlbmRFbGVtZW50IGV2ZW50Ci0gICAgICAgIGlmIChtX3RyYWNlciAhPSBudWxsKQotICAgICAgICAgICAgc3VwZXIuZmlyZUVuZEVsZW0ocU5hbWUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIERvZXMgbm90aGluZy4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbmRQcmVmaXhNYXBwaW5nKFN0cmluZyBwcmVmaXgpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRG9lcyBub3RoaW5nLgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjaWdub3JhYmxlV2hpdGVzcGFjZShjaGFyW10sIGludCwgaW50KQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGlnbm9yYWJsZVdoaXRlc3BhY2UoY2hhcltdIGNoLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgYSBwcm9jZXNzaW5nIGluc3RydWN0aW9uLgotICAgICAqCi0gICAgICogPHA+VGhlIFBhcnNlciB3aWxsIGludm9rZSB0aGlzIG1ldGhvZCBvbmNlIGZvciBlYWNoIHByb2Nlc3NpbmcKLSAgICAgKiBpbnN0cnVjdGlvbiBmb3VuZDogbm90ZSB0aGF0IHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb25zIG1heSBvY2N1cgotICAgICAqIGJlZm9yZSBvciBhZnRlciB0aGUgbWFpbiBkb2N1bWVudCBlbGVtZW50LjwvcD4KLSAgICAgKgotICAgICAqIDxwPkEgU0FYIHBhcnNlciBzaG91bGQgbmV2ZXIgcmVwb3J0IGFuIFhNTCBkZWNsYXJhdGlvbiAoWE1MIDEuMCwKLSAgICAgKiBzZWN0aW9uIDIuOCkgb3IgYSB0ZXh0IGRlY2xhcmF0aW9uIChYTUwgMS4wLCBzZWN0aW9uIDQuMy4xKQotICAgICAqIHVzaW5nIHRoaXMgbWV0aG9kLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSB0YXJnZXQgVGhlIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gdGFyZ2V0LgotICAgICAqIEBwYXJhbSBkYXRhIFRoZSBwcm9jZXNzaW5nIGluc3RydWN0aW9uIGRhdGEsIG9yIG51bGwgaWYKLSAgICAgKiAgICAgICAgbm9uZSB3YXMgc3VwcGxpZWQuCi0gICAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICAgKgotICAgICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oU3RyaW5nLCBTdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcHJvY2Vzc2luZ0luc3RydWN0aW9uKFN0cmluZyB0YXJnZXQsIFN0cmluZyBkYXRhKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBmbHVzaFBlbmRpbmcoKTsKLSAgICAgICAgbV9zYXhIYW5kbGVyLnByb2Nlc3NpbmdJbnN0cnVjdGlvbih0YXJnZXQsZGF0YSk7Ci0KLSAgICAgICAgICAgICAgICAvLyB0aW1lIHRvIGZpcmUgb2ZmIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gZXZlbnQKLQotICAgICAgICBpZiAobV90cmFjZXIgIT0gbnVsbCkKLSAgICAgICAgICAgICAgICAgICAgc3VwZXIuZmlyZUVzY2FwaW5nRXZlbnQodGFyZ2V0LGRhdGEpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIERvZXMgbm90aGluZy4KLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI3NldERvY3VtZW50TG9jYXRvcihMb2NhdG9yKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldERvY3VtZW50TG9jYXRvcihMb2NhdG9yIGFyZzApCi0gICAgewotICAgICAgICBzdXBlci5zZXREb2N1bWVudExvY2F0b3IoYXJnMCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRG9lcyBub3RoaW5nLgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjc2tpcHBlZEVudGl0eShTdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2tpcHBlZEVudGl0eShTdHJpbmcgYXJnMCkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiB0aGUgYmVnaW5uaW5nIG9mIGFuIGVsZW1lbnQsIGFsdGhvdWdoIHRoaXMgaXMgYQotICAgICAqIFNBWCBtZXRob2QgYWRkaXRpb25hbCBuYW1lc3BhY2Ugb3IgYXR0cmlidXRlIGluZm9ybWF0aW9uIGNhbiBvY2N1ciBiZWZvcmUKLSAgICAgKiBvciBhZnRlciB0aGlzIGNhbGwsIHRoYXQgaXMgYXNzb2NpYXRlZCB3aXRoIHRoaXMgZWxlbWVudC4KLSAgICAgKgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWVzcGFjZVVSSSBUaGUgTmFtZXNwYWNlIFVSSSwgb3IgdGhlIGVtcHR5IHN0cmluZyBpZiB0aGUKLSAgICAgKiAgICAgICAgZWxlbWVudCBoYXMgbm8gTmFtZXNwYWNlIFVSSSBvciBpZiBOYW1lc3BhY2UKLSAgICAgKiAgICAgICAgcHJvY2Vzc2luZyBpcyBub3QgYmVpbmcgcGVyZm9ybWVkLgotICAgICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGxvY2FsIG5hbWUgKHdpdGhvdXQgcHJlZml4KSwgb3IgdGhlCi0gICAgICogICAgICAgIGVtcHR5IHN0cmluZyBpZiBOYW1lc3BhY2UgcHJvY2Vzc2luZyBpcyBub3QgYmVpbmcKLSAgICAgKiAgICAgICAgcGVyZm9ybWVkLgotICAgICAqIEBwYXJhbSBxTmFtZSBUaGUgZWxlbWVudHMgbmFtZS4KLSAgICAgKiBAcGFyYW0gYXR0cyBUaGUgYXR0cmlidXRlcyBhdHRhY2hlZCB0byB0aGUgZWxlbWVudCwgaWYgYW55LgotICAgICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNzdGFydEVsZW1lbnQKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI2VuZEVsZW1lbnQKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkF0dHJpYnV0ZUxpc3QKLSAgICAgKgotICAgICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAgICoKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI3N0YXJ0RWxlbWVudChTdHJpbmcsIFN0cmluZywgU3RyaW5nLCBBdHRyaWJ1dGVzKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudCgKLSAgICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSwKLSAgICAgICAgU3RyaW5nIGxvY2FsTmFtZSwKLSAgICAgICAgU3RyaW5nIHFOYW1lLAotICAgICAgICBBdHRyaWJ1dGVzIGF0dHMpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGZsdXNoUGVuZGluZygpOwotICAgICAgICBzdXBlci5zdGFydEVsZW1lbnQobmFtZXNwYWNlVVJJLCBsb2NhbE5hbWUsIHFOYW1lLCBhdHRzKTsKLSAgICAgICAgbV9zYXhIYW5kbGVyLnN0YXJ0RWxlbWVudChuYW1lc3BhY2VVUkksIGxvY2FsTmFtZSwgcU5hbWUsIGF0dHMpOwotICAgICAgICBtX2VsZW1Db250ZXh0Lm1fc3RhcnRUYWdPcGVuID0gZmFsc2U7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgYSBjb21tZW50IGFueXdoZXJlIGluIHRoZSBkb2N1bWVudC4gVGhpcyBjYWxsYmFjawotICAgICAqIHdpbGwgYmUgdXNlZCBmb3IgY29tbWVudHMgaW5zaWRlIG9yIG91dHNpZGUgdGhlIGRvY3VtZW50IGVsZW1lbnQuCi0gICAgICogQHBhcmFtIGNoIEFuIGFycmF5IGhvbGRpbmcgdGhlIGNoYXJhY3RlcnMgaW4gdGhlIGNvbW1lbnQuCi0gICAgICogQHBhcmFtIHN0YXJ0IFRoZSBzdGFydGluZyBwb3NpdGlvbiBpbiB0aGUgYXJyYXkuCi0gICAgICogQHBhcmFtIGxlbmd0aCBUaGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gdXNlIGZyb20gdGhlIGFycmF5LgotICAgICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIFRoZSBhcHBsaWNhdGlvbiBtYXkgcmFpc2UgYW4gZXhjZXB0aW9uLgotICAgICAqCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXIjY29tbWVudChjaGFyW10sIGludCwgaW50KQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGNvbW1lbnQoY2hhcltdIGNoLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGZsdXNoUGVuZGluZygpOwotICAgICAgICBpZiAobV9sZXhIYW5kbGVyICE9IG51bGwpCi0gICAgICAgICAgICBtX2xleEhhbmRsZXIuY29tbWVudChjaCwgc3RhcnQsIGxlbmd0aCk7Ci0KLSAgICAgICAgLy8gdGltZSB0byBmaXJlIG9mZiBjb21tZW50IGV2ZW50Ci0gICAgICAgIGlmIChtX3RyYWNlciAhPSBudWxsKQotICAgICAgICAgICAgc3VwZXIuZmlyZUNvbW1lbnRFdmVudChjaCwgc3RhcnQsIGxlbmd0aCk7Ci0gICAgICAgIHJldHVybjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBEb2VzIG5vdGhpbmcuCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXIjZW5kQ0RBVEEoKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZENEQVRBKCkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgcmV0dXJuOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIERvZXMgbm90aGluZy4KLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LmV4dC5MZXhpY2FsSGFuZGxlciNlbmREVEQoKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZERURCgpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRG9lcyBub3RoaW5nLgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguZXh0LkxleGljYWxIYW5kbGVyI3N0YXJ0Q0RBVEEoKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0Q0RBVEEoKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgIH0KLQotICAgIC8qKgotICAgICAqIERvZXMgbm90aGluZy4KLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LmV4dC5MZXhpY2FsSGFuZGxlciNzdGFydEVudGl0eShTdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnRFbnRpdHkoU3RyaW5nIGFyZzApIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIGVuZCBvZiBhIGRvY3VtZW50LgotICAgICAqCi0gICAgICogPHA+VGhlIFNBWCBwYXJzZXIgd2lsbCBpbnZva2UgdGhpcyBtZXRob2Qgb25seSBvbmNlLCBhbmQgaXQgd2lsbAotICAgICAqIGJlIHRoZSBsYXN0IG1ldGhvZCBpbnZva2VkIGR1cmluZyB0aGUgcGFyc2UuICBUaGUgcGFyc2VyIHNoYWxsCi0gICAgICogbm90IGludm9rZSB0aGlzIG1ldGhvZCB1bnRpbCBpdCBoYXMgZWl0aGVyIGFiYW5kb25lZCBwYXJzaW5nCi0gICAgICogKGJlY2F1c2Ugb2YgYW4gdW5yZWNvdmVyYWJsZSBlcnJvcikgb3IgcmVhY2hlZCB0aGUgZW5kIG9mCi0gICAgICogaW5wdXQuPC9wPgotICAgICAqCi0gICAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICAgKgotICAgICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAgICoKLSAgICAgKgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZERvY3VtZW50KCkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgZmx1c2hQZW5kaW5nKCk7Ci0KLSAgICAgICAgLy8gQ2xvc2Ugb3V0cHV0IGRvY3VtZW50Ci0gICAgICAgIG1fc2F4SGFuZGxlci5lbmREb2N1bWVudCgpOwotCi0gICAgICAgIGlmIChtX3RyYWNlciAhPSBudWxsKQotICAgICAgICAgICAgc3VwZXIuZmlyZUVuZERvYygpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCB3aGVuIGFsbCB0aGUgZGF0YSBuZWVkZWQgZm9yIGEgY2FsbCB0byB0aGUKLSAgICAgKiBTQVggaGFuZGxlcidzIHN0YXJ0RWxlbWVudCgpIG1ldGhvZCBoYXMgYmVlbiBnYXRoZXJlZC4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCBjbG9zZVN0YXJ0VGFnKCkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLQotICAgICAgICBtX2VsZW1Db250ZXh0Lm1fc3RhcnRUYWdPcGVuID0gZmFsc2U7Ci0KLSAgICAgICAgLy8gTm93IGlzIHRpbWUgdG8gc2VuZCB0aGUgc3RhcnRFbGVtZW50IGV2ZW50Ci0gICAgICAgIG1fc2F4SGFuZGxlci5zdGFydEVsZW1lbnQoCi0gICAgICAgICAgICBFTVBUWVNUUklORywKLSAgICAgICAgICAgIG1fZWxlbUNvbnRleHQubV9lbGVtZW50TmFtZSwKLSAgICAgICAgICAgIG1fZWxlbUNvbnRleHQubV9lbGVtZW50TmFtZSwKLSAgICAgICAgICAgIG1fYXR0cmlidXRlcyk7Ci0gICAgICAgIG1fYXR0cmlidXRlcy5jbGVhcigpOwotCi0gICAgfQotCi0gICAgLyoqCi0gICAgICogRG8gbm90aGluZy4KLSAgICAgKiBAc2VlIFNlcmlhbGl6YXRpb25IYW5kbGVyI2Nsb3NlKCkKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBjbG9zZSgpCi0gICAgewotICAgICAgICByZXR1cm47Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgY2hhcmFjdGVyIGRhdGEuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY2hhcnMgVGhlIHN0cmluZyBvZiBjaGFyYWN0ZXJzIHRvIHByb2Nlc3MuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgICAqCi0gICAgICogQHNlZSBFeHRlbmRlZENvbnRlbnRIYW5kbGVyI2NoYXJhY3RlcnMoU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGNoYXJhY3RlcnMoZmluYWwgU3RyaW5nIGNoYXJzKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBmaW5hbCBpbnQgbGVuZ3RoID0gY2hhcnMubGVuZ3RoKCk7Ci0gICAgICAgIGlmIChsZW5ndGggPiBtX2NoYXJzQnVmZi5sZW5ndGgpCi0gICAgICAgIHsKLSAgICAgICAgICAgIG1fY2hhcnNCdWZmID0gbmV3IGNoYXJbbGVuZ3RoICogMiArIDFdOwotICAgICAgICB9Ci0gICAgICAgIGNoYXJzLmdldENoYXJzKDAsIGxlbmd0aCwgbV9jaGFyc0J1ZmYsIDApOwotICAgICAgICB0aGlzLmNoYXJhY3RlcnMobV9jaGFyc0J1ZmYsIDAsIGxlbmd0aCk7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBBIGNvbnN0cnVjdG9yCi0gICAgICogQHBhcmFtIGhhbmRsZXIgdGhlIHdyYXBwZWQgU0FYIGNvbnRlbnQgaGFuZGxlcgotICAgICAqIEBwYXJhbSBlbmNvZGluZyB0aGUgZW5jb2Rpbmcgb2YgdGhlIG91dHB1dCBIVE1MIGRvY3VtZW50Ci0gICAgICovCi0gICAgcHVibGljIFRvSFRNTFNBWEhhbmRsZXIoQ29udGVudEhhbmRsZXIgaGFuZGxlciwgU3RyaW5nIGVuY29kaW5nKQotICAgIHsKLSAgICAgICAgc3VwZXIoaGFuZGxlcixlbmNvZGluZyk7Ci0gICAgfQotICAgIC8qKgotICAgICAqIEEgY29uc3RydWN0b3IuCi0gICAgICogQHBhcmFtIGhhbmRsZXIgdGhlIHdyYXBwZWQgU0FYIGNvbnRlbnQgaGFuZGxlcgotICAgICAqIEBwYXJhbSBsZXggdGhlIHdyYXBwZWQgbGV4aWNhbCBoYW5kbGVyCi0gICAgICogQHBhcmFtIGVuY29kaW5nIHRoZSBlbmNvZGluZyBvZiB0aGUgb3V0cHV0IEhUTUwgZG9jdW1lbnQKLSAgICAgKi8KLSAgICBwdWJsaWMgVG9IVE1MU0FYSGFuZGxlcigKLSAgICAgICAgQ29udGVudEhhbmRsZXIgaGFuZGxlciwKLSAgICAgICAgTGV4aWNhbEhhbmRsZXIgbGV4LAotICAgICAgICBTdHJpbmcgZW5jb2RpbmcpCi0gICAgewotICAgICAgICBzdXBlcihoYW5kbGVyLGxleCxlbmNvZGluZyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQW4gZWxlbWVudCBzdGFydHMsIGJ1dCBhdHRyaWJ1dGVzIGFyZSBub3QgZnVsbHkga25vd24geWV0LgotICAgICAqCi0gICAgICogQHBhcmFtIGVsZW1lbnROYW1lc3BhY2VVUkkgdGhlIFVSSSBvZiB0aGUgbmFtZXNwYWNlIG9mIHRoZSBlbGVtZW50Ci0gICAgICogKG9wdGlvbmFsKQotICAgICAqIEBwYXJhbSBlbGVtZW50TG9jYWxOYW1lIHRoZSBlbGVtZW50IG5hbWUsIGJ1dCB3aXRob3V0IHByZWZpeAotICAgICAqIChvcHRpb25hbCkKLSAgICAgKiBAcGFyYW0gZWxlbWVudE5hbWUgdGhlIGVsZW1lbnQgbmFtZSwgd2l0aCBwcmVmaXgsIGlmIGFueSAocmVxdWlyZWQpCi0gICAgICoKLSAgICAgKiBAc2VlIEV4dGVuZGVkQ29udGVudEhhbmRsZXIjc3RhcnRFbGVtZW50KFN0cmluZykKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQoCi0gICAgICAgIFN0cmluZyBlbGVtZW50TmFtZXNwYWNlVVJJLAotICAgICAgICBTdHJpbmcgZWxlbWVudExvY2FsTmFtZSwKLSAgICAgICAgU3RyaW5nIGVsZW1lbnROYW1lKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotCi0gICAgICAgIHN1cGVyLnN0YXJ0RWxlbWVudChlbGVtZW50TmFtZXNwYWNlVVJJLCBlbGVtZW50TG9jYWxOYW1lLCBlbGVtZW50TmFtZSk7Ci0KLSAgICAgICAgZmx1c2hQZW5kaW5nKCk7Ci0KLSAgICAgICAgLy8gSGFuZGxlIGRvY3VtZW50IHR5cGUgZGVjbGFyYXRpb24gKGZvciBmaXJzdCBlbGVtZW50IG9ubHkpCi0gICAgICAgIGlmICghbV9kdGRIYW5kbGVkKQotICAgICAgICB7Ci0gICAgICAgICAgICBTdHJpbmcgZG9jdHlwZVN5c3RlbSA9IGdldERvY3R5cGVTeXN0ZW0oKTsKLSAgICAgICAgICAgIFN0cmluZyBkb2N0eXBlUHVibGljID0gZ2V0RG9jdHlwZVB1YmxpYygpOwotICAgICAgICAgICAgaWYgKChkb2N0eXBlU3lzdGVtICE9IG51bGwpIHx8IChkb2N0eXBlUHVibGljICE9IG51bGwpKSB7Ci0gICAgICAgICAgICAgICAgaWYgKG1fbGV4SGFuZGxlciAhPSBudWxsKQotICAgICAgICAgICAgICAgICAgICBtX2xleEhhbmRsZXIuc3RhcnREVEQoCi0gICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50TmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgIGRvY3R5cGVQdWJsaWMsCi0gICAgICAgICAgICAgICAgICAgICAgICBkb2N0eXBlU3lzdGVtKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIG1fZHRkSGFuZGxlZCA9IHRydWU7Ci0gICAgICAgIH0KLSAgICAgICAgbV9lbGVtQ29udGV4dCA9IG1fZWxlbUNvbnRleHQucHVzaChlbGVtZW50TmFtZXNwYWNlVVJJLCBlbGVtZW50TG9jYWxOYW1lLCBlbGVtZW50TmFtZSk7Ci0gICAgfQotICAgIC8qKgotICAgICAqIEFuIGVsZW1lbnQgc3RhcnRzLCBidXQgYXR0cmlidXRlcyBhcmUgbm90IGZ1bGx5IGtub3duIHlldC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlbGVtZW50TmFtZSB0aGUgZWxlbWVudCBuYW1lLCB3aXRoIHByZWZpeCwgaWYgYW55Ci0gICAgICoKLSAgICAgKiBAc2VlIEV4dGVuZGVkQ29udGVudEhhbmRsZXIjc3RhcnRFbGVtZW50KFN0cmluZykKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQoU3RyaW5nIGVsZW1lbnROYW1lKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICB0aGlzLnN0YXJ0RWxlbWVudChudWxsLG51bGwsIGVsZW1lbnROYW1lKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiB0aGUgZW5kIG9mIGFuIGVsZW1lbnQuCi0gICAgICogQHBhcmFtIGVsZW1lbnROYW1lIFRoZSBlbGVtZW50IHR5cGUgbmFtZQotICAgICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgICAqICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICAgKgotICAgICAqIEBzZWUgRXh0ZW5kZWRDb250ZW50SGFuZGxlciNlbmRFbGVtZW50KFN0cmluZykKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbmRFbGVtZW50KFN0cmluZyBlbGVtZW50TmFtZSkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgZmx1c2hQZW5kaW5nKCk7Ci0gICAgICAgIG1fc2F4SGFuZGxlci5lbmRFbGVtZW50KEVNUFRZU1RSSU5HLCBlbGVtZW50TmFtZSwgZWxlbWVudE5hbWUpOwotCi0gICAgICAgIC8vIHRpbWUgdG8gZmlyZSBvZmYgZW5kRWxlbWVudCBldmVudAotICAgICAgICAgICAgICAgIGlmIChtX3RyYWNlciAhPSBudWxsKQotICAgICAgICAgICAgc3VwZXIuZmlyZUVuZEVsZW0oZWxlbWVudE5hbWUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGNoYXJhY3RlciBkYXRhLgotICAgICAqCi0gICAgICogPHA+VGhlIFBhcnNlciB3aWxsIGNhbGwgdGhpcyBtZXRob2QgdG8gcmVwb3J0IGVhY2ggY2h1bmsgb2YKLSAgICAgKiBjaGFyYWN0ZXIgZGF0YS4gIFNBWCBwYXJzZXJzIG1heSByZXR1cm4gYWxsIGNvbnRpZ3VvdXMgY2hhcmFjdGVyCi0gICAgICogZGF0YSBpbiBhIHNpbmdsZSBjaHVuaywgb3IgdGhleSBtYXkgc3BsaXQgaXQgaW50byBzZXZlcmFsCi0gICAgICogY2h1bmtzOyBob3dldmVyLCBhbGwgb2YgdGhlIGNoYXJhY3RlcnMgaW4gYW55IHNpbmdsZSBldmVudAotICAgICAqIG11c3QgY29tZSBmcm9tIHRoZSBzYW1lIGV4dGVybmFsIGVudGl0eSwgc28gdGhhdCB0aGUgTG9jYXRvcgotICAgICAqIHByb3ZpZGVzIHVzZWZ1bCBpbmZvcm1hdGlvbi48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5UaGUgYXBwbGljYXRpb24gbXVzdCBub3QgYXR0ZW1wdCB0byByZWFkIGZyb20gdGhlIGFycmF5Ci0gICAgICogb3V0c2lkZSBvZiB0aGUgc3BlY2lmaWVkIHJhbmdlLjwvcD4KLSAgICAgKgotICAgICAqIDxwPk5vdGUgdGhhdCBzb21lIHBhcnNlcnMgd2lsbCByZXBvcnQgd2hpdGVzcGFjZSB1c2luZyB0aGUKLSAgICAgKiBpZ25vcmFibGVXaGl0ZXNwYWNlKCkgbWV0aG9kIHJhdGhlciB0aGFuIHRoaXMgb25lICh2YWxpZGF0aW5nCi0gICAgICogcGFyc2VycyBtdXN0IGRvIHNvKS48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gY2ggVGhlIGNoYXJhY3RlcnMgZnJvbSB0aGUgWE1MIGRvY3VtZW50LgotICAgICAqIEBwYXJhbSBvZmYgVGhlIHN0YXJ0IHBvc2l0aW9uIGluIHRoZSBhcnJheS4KLSAgICAgKiBAcGFyYW0gbGVuIFRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyB0byByZWFkIGZyb20gdGhlIGFycmF5LgotICAgICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAgICogQHNlZSAjaWdub3JhYmxlV2hpdGVzcGFjZQotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguTG9jYXRvcgotICAgICAqCi0gICAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICAgKgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjY2hhcmFjdGVycyhjaGFyW10sIGludCwgaW50KQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGNoYXJhY3RlcnMoY2hhcltdIGNoLCBpbnQgb2ZmLCBpbnQgbGVuKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotCi0gICAgICAgIGZsdXNoUGVuZGluZygpOwotICAgICAgICBtX3NheEhhbmRsZXIuY2hhcmFjdGVycyhjaCwgb2ZmLCBsZW4pOwotCi0gICAgICAgIC8vIHRpbWUgdG8gZmlyZSBvZmYgY2hhcmFjdGVycyBldmVudAotICAgICAgICAgICAgICAgIGlmIChtX3RyYWNlciAhPSBudWxsKQotICAgICAgICAgICAgc3VwZXIuZmlyZUNoYXJFdmVudChjaCwgb2ZmLCBsZW4pOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIGZsdXNoZXMgYW55IHBlbmRpbmcgZXZlbnRzLCB3aGljaCBjYW4gYmUgc3RhcnREb2N1bWVudCgpCi0gICAgICogY2xvc2luZyB0aGUgb3BlbmluZyB0YWcgb2YgYW4gZWxlbWVudCwgb3IgY2xvc2luZyBhbiBvcGVuIENEQVRBIHNlY3Rpb24uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZmx1c2hQZW5kaW5nKCkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgICAgICAgICBpZiAobV9uZWVkVG9DYWxsU3RhcnREb2N1bWVudCkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzdGFydERvY3VtZW50SW50ZXJuYWwoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIG1fbmVlZFRvQ2FsbFN0YXJ0RG9jdW1lbnQgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgIC8vIENsb3NlIGFueSBvcGVuIGVsZW1lbnQKLSAgICAgICAgaWYgKG1fZWxlbUNvbnRleHQubV9zdGFydFRhZ09wZW4pCi0gICAgICAgIHsKLSAgICAgICAgICAgIGNsb3NlU3RhcnRUYWcoKTsKLSAgICAgICAgICAgIG1fZWxlbUNvbnRleHQubV9zdGFydFRhZ09wZW4gPSBmYWxzZTsKLSAgICAgICAgfQotICAgIH0KLSAgICAvKioKLSAgICAgKiBIYW5kbGUgYSBwcmVmaXgvdXJpIG1hcHBpbmcsIHdoaWNoIGlzIGFzc29jaWF0ZWQgd2l0aCBhIHN0YXJ0RWxlbWVudCgpCi0gICAgICogdGhhdCBpcyBzb29uIHRvIGZvbGxvdy4gTmVlZCB0byBjbG9zZSBhbnkgb3BlbiBzdGFydCB0YWcgdG8gbWFrZQotICAgICAqIHN1cmUgdGhhbiBhbnkgbmFtZSBzcGFjZSBhdHRyaWJ1dGVzIGR1ZSB0byB0aGlzIGV2ZW50IGFyZSBhc3NvY2lhdGVkIHdpaAotICAgICAqIHRoZSB1cCBjb21taW5nIGVsZW1lbnQsIG5vdCB0aGUgY3VycmVudCBvbmUuCi0gICAgICogQHNlZSBFeHRlbmRlZENvbnRlbnRIYW5kbGVyI3N0YXJ0UHJlZml4TWFwcGluZwotICAgICAqCi0gICAgICogQHBhcmFtIHByZWZpeCBUaGUgTmFtZXNwYWNlIHByZWZpeCBiZWluZyBkZWNsYXJlZC4KLSAgICAgKiBAcGFyYW0gdXJpIFRoZSBOYW1lc3BhY2UgVVJJIHRoZSBwcmVmaXggaXMgbWFwcGVkIHRvLgotICAgICAqIEBwYXJhbSBzaG91bGRGbHVzaCB0cnVlIGlmIGFueSBvcGVuIHRhZ3MgbmVlZCB0byBiZSBjbG9zZWQgZmlyc3QsIHRoaXMKLSAgICAgKiB3aWxsIGltcGFjdCB3aGljaCBlbGVtZW50IHRoZSBtYXBwaW5nIGFwcGxpZXMgdG8gKG9wZW4gcGFyZW50LCBvciBpdHMgdXAKLSAgICAgKiBjb21taW5nIGNoaWxkKQotICAgICAqIEByZXR1cm4gcmV0dXJucyB0cnVlIGlmIHRoZSBjYWxsIG1hZGUgYSBjaGFuZ2UgdG8gdGhlIGN1cnJlbnQKLSAgICAgKiBuYW1lc3BhY2UgaW5mb3JtYXRpb24sIGZhbHNlIGlmIGl0IGRpZCBub3QgY2hhbmdlIGFueXRoaW5nLCBlLmcuIGlmIHRoZQotICAgICAqIHByZWZpeC9uYW1lc3BhY2UgbWFwcGluZyB3YXMgYWxyZWFkeSBpbiBzY29wZSBmcm9tIGJlZm9yZS4KLSAgICAgKgotICAgICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIFRoZSBjbGllbnQgbWF5IHRocm93Ci0gICAgICogICAgICAgICAgICBhbiBleGNlcHRpb24gZHVyaW5nIHByb2Nlc3NpbmcuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gc3RhcnRQcmVmaXhNYXBwaW5nKAotICAgICAgICBTdHJpbmcgcHJlZml4LAotICAgICAgICBTdHJpbmcgdXJpLAotICAgICAgICBib29sZWFuIHNob3VsZEZsdXNoKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICAvLyBubyBuYW1lc3BhY2Ugc3VwcG9ydCBmb3IgSFRNTAotICAgICAgICBpZiAoc2hvdWxkRmx1c2gpCi0gICAgICAgICAgICBmbHVzaFBlbmRpbmcoKTsKLSAgICAgICAgbV9zYXhIYW5kbGVyLnN0YXJ0UHJlZml4TWFwcGluZyhwcmVmaXgsdXJpKTsKLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEJlZ2luIHRoZSBzY29wZSBvZiBhIHByZWZpeC1VUkkgTmFtZXNwYWNlIG1hcHBpbmcKLSAgICAgKiBqdXN0IGJlZm9yZSBhbm90aGVyIGVsZW1lbnQgaXMgYWJvdXQgdG8gc3RhcnQuCi0gICAgICogVGhpcyBjYWxsIHdpbGwgY2xvc2UgYW55IG9wZW4gdGFncyBzbyB0aGF0IHRoZSBwcmVmaXggbWFwcGluZwotICAgICAqIHdpbGwgbm90IGFwcGx5IHRvIHRoZSBjdXJyZW50IGVsZW1lbnQsIGJ1dCB0aGUgdXAgY29tbWluZyBjaGlsZC4KLSAgICAgKgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjc3RhcnRQcmVmaXhNYXBwaW5nCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcHJlZml4IFRoZSBOYW1lc3BhY2UgcHJlZml4IGJlaW5nIGRlY2xhcmVkLgotICAgICAqIEBwYXJhbSB1cmkgVGhlIE5hbWVzcGFjZSBVUkkgdGhlIHByZWZpeCBpcyBtYXBwZWQgdG8uCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBUaGUgY2xpZW50IG1heSB0aHJvdwotICAgICAqICAgICAgICAgICAgYW4gZXhjZXB0aW9uIGR1cmluZyBwcm9jZXNzaW5nLgotICAgICAqCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnRQcmVmaXhNYXBwaW5nKFN0cmluZyBwcmVmaXgsIFN0cmluZyB1cmkpCi0gICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIHN0YXJ0UHJlZml4TWFwcGluZyhwcmVmaXgsdXJpLHRydWUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIGlzIHVzZWQgd2hlbiBhIHByZWZpeC91cmkgbmFtZXNwYWNlIG1hcHBpbmcKLSAgICAgKiBpcyBpbmRpY2F0ZWQgYWZ0ZXIgdGhlIGVsZW1lbnQgd2FzIHN0YXJ0ZWQgd2l0aCBhCi0gICAgICogc3RhcnRFbGVtZW50KCkgYW5kIGJlZm9yZSBhbmQgZW5kRWxlbWVudCgpLgotICAgICAqIHN0YXJ0UHJlZml4TWFwcGluZyhwcmVmaXgsdXJpKSB3b3VsZCBiZSB1c2VkIGJlZm9yZSB0aGUKLSAgICAgKiBzdGFydEVsZW1lbnQoKSBjYWxsLgotICAgICAqIEBwYXJhbSBwcmVmaXggdGhlIHByZWZpeCBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIFVSSS4KLSAgICAgKiBAcGFyYW0gdXJpIHRoZSBVUkkgb2YgdGhlIG5hbWVzcGFjZQotICAgICAqCi0gICAgICogQHNlZSBFeHRlbmRlZENvbnRlbnRIYW5kbGVyI25hbWVzcGFjZUFmdGVyU3RhcnRFbGVtZW50KFN0cmluZywgU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIG5hbWVzcGFjZUFmdGVyU3RhcnRFbGVtZW50KAotICAgICAgICBmaW5hbCBTdHJpbmcgcHJlZml4LAotICAgICAgICBmaW5hbCBTdHJpbmcgdXJpKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICAvLyBoYWNrIGZvciBYU0xUQyB3aXRoIGZpbmRpbmcgVVJJIGZvciBkZWZhdWx0IG5hbWVzcGFjZQotICAgICAgICBpZiAobV9lbGVtQ29udGV4dC5tX2VsZW1lbnRVUkkgPT0gbnVsbCkKLSAgICAgICAgewotICAgICAgICAgICAgU3RyaW5nIHByZWZpeDEgPSBnZXRQcmVmaXhQYXJ0KG1fZWxlbUNvbnRleHQubV9lbGVtZW50TmFtZSk7Ci0gICAgICAgICAgICBpZiAocHJlZml4MSA9PSBudWxsICYmIEVNUFRZU1RSSU5HLmVxdWFscyhwcmVmaXgpKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIC8vIHRoZSBlbGVtZW50cyBVUkkgaXMgbm90IGtub3duIHlldCwgYW5kIGl0Ci0gICAgICAgICAgICAgICAgLy8gZG9lc24ndCBoYXZlIGEgcHJlZml4LCBhbmQgd2UgYXJlIGN1cnJlbnRseQotICAgICAgICAgICAgICAgIC8vIHNldHRpbmcgdGhlIHVyaSBmb3IgcHJlZml4ICIiLCBzbyB3ZSBoYXZlCi0gICAgICAgICAgICAgICAgLy8gdGhlIHVyaSBmb3IgdGhlIGVsZW1lbnQuLi4gbGV0cyByZW1lbWJlciBpdAotICAgICAgICAgICAgICAgIG1fZWxlbUNvbnRleHQubV9lbGVtZW50VVJJID0gdXJpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHN0YXJ0UHJlZml4TWFwcGluZyhwcmVmaXgsdXJpLGZhbHNlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcnkncyB0byByZXNldCB0aGUgc3VwZXIgY2xhc3MgYW5kIHJlc2V0IHRoaXMgY2xhc3MgZm9yCi0gICAgICogcmUtdXNlLCBzbyB0aGF0IHlvdSBkb24ndCBuZWVkIHRvIGNyZWF0ZSBhIG5ldyBzZXJpYWxpemVyCi0gICAgICogKG1vc3RseSBmb3IgcGVyZm9ybWFuY2UgcmVhc29ucykuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGNsYXNzIHdhcyBzdWNjZXNzZnVseSByZXNldC4KLSAgICAgKiBAc2VlIFNlcmlhbGl6ZXIjcmVzZXQoKQotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIHJlc2V0KCkKLSAgICB7Ci0gICAgICAgIGJvb2xlYW4gd2FzUmVzZXQgPSBmYWxzZTsKLSAgICAgICAgaWYgKHN1cGVyLnJlc2V0KCkpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHJlc2V0VG9IVE1MU0FYSGFuZGxlcigpOwotICAgICAgICAgICAgd2FzUmVzZXQgPSB0cnVlOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiB3YXNSZXNldDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXNldCBhbGwgb2YgdGhlIGZpZWxkcyBvd25lZCBieSBUb0hUTUxTQVhIYW5kbGVyIGNsYXNzCi0gICAgICoKLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgcmVzZXRUb0hUTUxTQVhIYW5kbGVyKCkKLSAgICB7Ci0gICAgICAgIHRoaXMubV9lc2NhcGVTZXR0aW5nID0gdHJ1ZTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1RvSFRNTFN0cmVhbS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9Ub0hUTUxTdHJlYW0uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYTY4ZWM2ZC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1RvSFRNTFN0cmVhbS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjMyMCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAxLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBUb0hUTUxTdHJlYW0uamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNSAwODoxNToyNiBzdXJlc2hfZW1haWxpZCBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplcjsKLQotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci1pbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5pby5VbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uOwotaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0aWVzOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5SZXN1bHQ7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXIudXRpbHMuTXNnS2V5OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplci51dGlscy5VdGlsczsKLWltcG9ydCBvcmcueG1sLnNheC5BdHRyaWJ1dGVzOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKLQotLyoqCi0gKiBUaGlzIHNlcmlhbGl6ZXIgdGFrZXMgYSBzZXJpZXMgb2YgU0FYIG9yCi0gKiBTQVgtbGlrZSBldmVudHMgYW5kIHdyaXRlcyBpdHMgb3V0cHV0Ci0gKiB0byB0aGUgZ2l2ZW4gc3RyZWFtLgotICoKLSAqIFRoaXMgY2xhc3MgaXMgbm90IGEgcHVibGljIEFQSSwgaXQgaXMgcHVibGljCi0gKiBiZWNhdXNlIGl0IGlzIHVzZWQgZnJvbSBhbm90aGVyIHBhY2thZ2UuCi0gKgotICogQHhzbC51c2FnZSBpbnRlcm5hbAotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgVG9IVE1MU3RyZWFtIGV4dGVuZHMgVG9TdHJlYW0KLXsKLQotICAgIC8qKiBUaGlzIGZsYWcgaXMgc2V0IHdoaWxlIHJlY2VpdmluZyBldmVudHMgZnJvbSB0aGUgRFREICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gbV9pbkRURCA9IGZhbHNlOwotCi0gICAgLyoqIFRydWUgaWYgdGhlIGN1cnJlbnQgZWxlbWVudCBpcyBhIGJsb2NrIGVsZW1lbnQuICAoc2VlbXMgbGlrZQotICAgICAqICB0aGlzIG5lZWRzIHRvIGJlIGEgc3RhY2suIC1zYikuICovCi0gICAgcHJpdmF0ZSBib29sZWFuIG1faW5CbG9ja0VsZW0gPSBmYWxzZTsKLQotICAgIC8qKgotICAgICAqIE1hcCB0aGF0IHRlbGxzIHdoaWNoIFhNTCBjaGFyYWN0ZXJzIHNob3VsZCBoYXZlIHNwZWNpYWwgdHJlYXRtZW50LCBhbmQgaXQKLSAgICAgKiAgcHJvdmlkZXMgY2hhcmFjdGVyIHRvIGVudGl0eSBuYW1lIGxvb2t1cC4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBDaGFySW5mbyBtX2h0bWxjaGFySW5mbyA9Ci0vLyAgICAgICAgbmV3IENoYXJJbmZvKENoYXJJbmZvLkhUTUxfRU5USVRJRVNfUkVTT1VSQ0UpOwotICAgICAgICBDaGFySW5mby5nZXRDaGFySW5mb0ludGVybmFsKENoYXJJbmZvLkhUTUxfRU5USVRJRVNfUkVTT1VSQ0UsIE1ldGhvZC5IVE1MKTsKLQotICAgIC8qKiBBIGRpZ2l0YWwgc2VhcmNoIHRyaWUgZm9yIGZhc3QsIGNhc2UgaW5zZW5zaXRpdmUgbG9va3VwIG9mIEVsZW1EZXNjIG9iamVjdHMuICovCi0gICAgc3RhdGljIGZpbmFsIFRyaWUgbV9lbGVtZW50RmxhZ3MgPSBuZXcgVHJpZSgpOwotCi0gICAgc3RhdGljIHsKLSAgICAgICAgaW5pdFRhZ1JlZmVyZW5jZShtX2VsZW1lbnRGbGFncyk7Ci0gICAgfQotICAgIHN0YXRpYyB2b2lkIGluaXRUYWdSZWZlcmVuY2UoVHJpZSBtX2VsZW1lbnRGbGFncykgewotCi0gICAgICAgIC8vIEhUTUwgNC4wIGxvb3NlIERURAotICAgICAgICBtX2VsZW1lbnRGbGFncy5wdXQoIkJBU0VGT05UIiwgbmV3IEVsZW1EZXNjKDAgfCBFbGVtRGVzYy5FTVBUWSkpOwotICAgICAgICBtX2VsZW1lbnRGbGFncy5wdXQoCi0gICAgICAgICAgICAiRlJBTUUiLAotICAgICAgICAgICAgbmV3IEVsZW1EZXNjKDAgfCBFbGVtRGVzYy5FTVBUWSB8IEVsZW1EZXNjLkJMT0NLKSk7Ci0gICAgICAgIG1fZWxlbWVudEZsYWdzLnB1dCgiRlJBTUVTRVQiLCBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLkJMT0NLKSk7Ci0gICAgICAgIG1fZWxlbWVudEZsYWdzLnB1dCgiTk9GUkFNRVMiLCBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLkJMT0NLKSk7Ci0gICAgICAgIG1fZWxlbWVudEZsYWdzLnB1dCgKLSAgICAgICAgICAgICJJU0lOREVYIiwKLSAgICAgICAgICAgIG5ldyBFbGVtRGVzYygwIHwgRWxlbURlc2MuRU1QVFkgfCBFbGVtRGVzYy5CTE9DSykpOwotICAgICAgICBtX2VsZW1lbnRGbGFncy5wdXQoCi0gICAgICAgICAgICAiQVBQTEVUIiwKLSAgICAgICAgICAgIG5ldyBFbGVtRGVzYygwIHwgRWxlbURlc2MuV0hJVEVTUEFDRVNFTlNJVElWRSkpOwotICAgICAgICBtX2VsZW1lbnRGbGFncy5wdXQoIkNFTlRFUiIsIG5ldyBFbGVtRGVzYygwIHwgRWxlbURlc2MuQkxPQ0spKTsKLSAgICAgICAgbV9lbGVtZW50RmxhZ3MucHV0KCJESVIiLCBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLkJMT0NLKSk7Ci0gICAgICAgIG1fZWxlbWVudEZsYWdzLnB1dCgiTUVOVSIsIG5ldyBFbGVtRGVzYygwIHwgRWxlbURlc2MuQkxPQ0spKTsKLQotICAgICAgICAvLyBIVE1MIDQuMCBzdHJpY3QgRFRECi0gICAgICAgIG1fZWxlbWVudEZsYWdzLnB1dCgiVFQiLCBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLkZPTlRTVFlMRSkpOwotICAgICAgICBtX2VsZW1lbnRGbGFncy5wdXQoIkkiLCBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLkZPTlRTVFlMRSkpOwotICAgICAgICBtX2VsZW1lbnRGbGFncy5wdXQoIkIiLCBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLkZPTlRTVFlMRSkpOwotICAgICAgICBtX2VsZW1lbnRGbGFncy5wdXQoIkJJRyIsIG5ldyBFbGVtRGVzYygwIHwgRWxlbURlc2MuRk9OVFNUWUxFKSk7Ci0gICAgICAgIG1fZWxlbWVudEZsYWdzLnB1dCgiU01BTEwiLCBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLkZPTlRTVFlMRSkpOwotICAgICAgICBtX2VsZW1lbnRGbGFncy5wdXQoIkVNIiwgbmV3IEVsZW1EZXNjKDAgfCBFbGVtRGVzYy5QSFJBU0UpKTsKLSAgICAgICAgbV9lbGVtZW50RmxhZ3MucHV0KCJTVFJPTkciLCBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLlBIUkFTRSkpOwotICAgICAgICBtX2VsZW1lbnRGbGFncy5wdXQoIkRGTiIsIG5ldyBFbGVtRGVzYygwIHwgRWxlbURlc2MuUEhSQVNFKSk7Ci0gICAgICAgIG1fZWxlbWVudEZsYWdzLnB1dCgiQ09ERSIsIG5ldyBFbGVtRGVzYygwIHwgRWxlbURlc2MuUEhSQVNFKSk7Ci0gICAgICAgIG1fZWxlbWVudEZsYWdzLnB1dCgiU0FNUCIsIG5ldyBFbGVtRGVzYygwIHwgRWxlbURlc2MuUEhSQVNFKSk7Ci0gICAgICAgIG1fZWxlbWVudEZsYWdzLnB1dCgiS0JEIiwgbmV3IEVsZW1EZXNjKDAgfCBFbGVtRGVzYy5QSFJBU0UpKTsKLSAgICAgICAgbV9lbGVtZW50RmxhZ3MucHV0KCJWQVIiLCBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLlBIUkFTRSkpOwotICAgICAgICBtX2VsZW1lbnRGbGFncy5wdXQoIkNJVEUiLCBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLlBIUkFTRSkpOwotICAgICAgICBtX2VsZW1lbnRGbGFncy5wdXQoIkFCQlIiLCBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLlBIUkFTRSkpOwotICAgICAgICBtX2VsZW1lbnRGbGFncy5wdXQoIkFDUk9OWU0iLCBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLlBIUkFTRSkpOwotICAgICAgICBtX2VsZW1lbnRGbGFncy5wdXQoCi0gICAgICAgICAgICAiU1VQIiwKLSAgICAgICAgICAgIG5ldyBFbGVtRGVzYygwIHwgRWxlbURlc2MuU1BFQ0lBTCB8IEVsZW1EZXNjLkFTUEVDSUFMKSk7Ci0gICAgICAgIG1fZWxlbWVudEZsYWdzLnB1dCgKLSAgICAgICAgICAgICJTVUIiLAotICAgICAgICAgICAgbmV3IEVsZW1EZXNjKDAgfCBFbGVtRGVzYy5TUEVDSUFMIHwgRWxlbURlc2MuQVNQRUNJQUwpKTsKLSAgICAgICAgbV9lbGVtZW50RmxhZ3MucHV0KAotICAgICAgICAgICAgIlNQQU4iLAotICAgICAgICAgICAgbmV3IEVsZW1EZXNjKDAgfCBFbGVtRGVzYy5TUEVDSUFMIHwgRWxlbURlc2MuQVNQRUNJQUwpKTsKLSAgICAgICAgbV9lbGVtZW50RmxhZ3MucHV0KAotICAgICAgICAgICAgIkJETyIsCi0gICAgICAgICAgICBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLlNQRUNJQUwgfCBFbGVtRGVzYy5BU1BFQ0lBTCkpOwotICAgICAgICBtX2VsZW1lbnRGbGFncy5wdXQoCi0gICAgICAgICAgICAiQlIiLAotICAgICAgICAgICAgbmV3IEVsZW1EZXNjKAotICAgICAgICAgICAgICAgIDAKLSAgICAgICAgICAgICAgICAgICAgfCBFbGVtRGVzYy5TUEVDSUFMCi0gICAgICAgICAgICAgICAgICAgIHwgRWxlbURlc2MuQVNQRUNJQUwKLSAgICAgICAgICAgICAgICAgICAgfCBFbGVtRGVzYy5FTVBUWQotICAgICAgICAgICAgICAgICAgICB8IEVsZW1EZXNjLkJMT0NLKSk7Ci0gICAgICAgIG1fZWxlbWVudEZsYWdzLnB1dCgiQk9EWSIsIG5ldyBFbGVtRGVzYygwIHwgRWxlbURlc2MuQkxPQ0spKTsKLSAgICAgICAgbV9lbGVtZW50RmxhZ3MucHV0KAotICAgICAgICAgICAgIkFERFJFU1MiLAotICAgICAgICAgICAgbmV3IEVsZW1EZXNjKAotICAgICAgICAgICAgICAgIDAKLSAgICAgICAgICAgICAgICAgICAgfCBFbGVtRGVzYy5CTE9DSwotICAgICAgICAgICAgICAgICAgICB8IEVsZW1EZXNjLkJMT0NLRk9STQotICAgICAgICAgICAgICAgICAgICB8IEVsZW1EZXNjLkJMT0NLRk9STUZJRUxEU0VUKSk7Ci0gICAgICAgIG1fZWxlbWVudEZsYWdzLnB1dCgKLSAgICAgICAgICAgICJESVYiLAotICAgICAgICAgICAgbmV3IEVsZW1EZXNjKAotICAgICAgICAgICAgICAgIDAKLSAgICAgICAgICAgICAgICAgICAgfCBFbGVtRGVzYy5CTE9DSwotICAgICAgICAgICAgICAgICAgICB8IEVsZW1EZXNjLkJMT0NLRk9STQotICAgICAgICAgICAgICAgICAgICB8IEVsZW1EZXNjLkJMT0NLRk9STUZJRUxEU0VUKSk7Ci0gICAgICAgIG1fZWxlbWVudEZsYWdzLnB1dCgiQSIsIG5ldyBFbGVtRGVzYygwIHwgRWxlbURlc2MuU1BFQ0lBTCkpOwotICAgICAgICBtX2VsZW1lbnRGbGFncy5wdXQoCi0gICAgICAgICAgICAiTUFQIiwKLSAgICAgICAgICAgIG5ldyBFbGVtRGVzYygKLSAgICAgICAgICAgICAgICAwIHwgRWxlbURlc2MuU1BFQ0lBTCB8IEVsZW1EZXNjLkFTUEVDSUFMIHwgRWxlbURlc2MuQkxPQ0spKTsKLSAgICAgICAgbV9lbGVtZW50RmxhZ3MucHV0KAotICAgICAgICAgICAgIkFSRUEiLAotICAgICAgICAgICAgbmV3IEVsZW1EZXNjKDAgfCBFbGVtRGVzYy5FTVBUWSB8IEVsZW1EZXNjLkJMT0NLKSk7Ci0gICAgICAgIG1fZWxlbWVudEZsYWdzLnB1dCgKLSAgICAgICAgICAgICJMSU5LIiwKLSAgICAgICAgICAgIG5ldyBFbGVtRGVzYygKLSAgICAgICAgICAgICAgICAwIHwgRWxlbURlc2MuSEVBRE1JU0MgfCBFbGVtRGVzYy5FTVBUWSB8IEVsZW1EZXNjLkJMT0NLKSk7Ci0gICAgICAgIG1fZWxlbWVudEZsYWdzLnB1dCgKLSAgICAgICAgICAgICJJTUciLAotICAgICAgICAgICAgbmV3IEVsZW1EZXNjKAotICAgICAgICAgICAgICAgIDAKLSAgICAgICAgICAgICAgICAgICAgfCBFbGVtRGVzYy5TUEVDSUFMCi0gICAgICAgICAgICAgICAgICAgIHwgRWxlbURlc2MuQVNQRUNJQUwKLSAgICAgICAgICAgICAgICAgICAgfCBFbGVtRGVzYy5FTVBUWQotICAgICAgICAgICAgICAgICAgICB8IEVsZW1EZXNjLldISVRFU1BBQ0VTRU5TSVRJVkUpKTsKLSAgICAgICAgbV9lbGVtZW50RmxhZ3MucHV0KAotICAgICAgICAgICAgIk9CSkVDVCIsCi0gICAgICAgICAgICBuZXcgRWxlbURlc2MoCi0gICAgICAgICAgICAgICAgMAotICAgICAgICAgICAgICAgICAgICB8IEVsZW1EZXNjLlNQRUNJQUwKLSAgICAgICAgICAgICAgICAgICAgfCBFbGVtRGVzYy5BU1BFQ0lBTAotICAgICAgICAgICAgICAgICAgICB8IEVsZW1EZXNjLkhFQURNSVNDCi0gICAgICAgICAgICAgICAgICAgIHwgRWxlbURlc2MuV0hJVEVTUEFDRVNFTlNJVElWRSkpOwotICAgICAgICBtX2VsZW1lbnRGbGFncy5wdXQoIlBBUkFNIiwgbmV3IEVsZW1EZXNjKDAgfCBFbGVtRGVzYy5FTVBUWSkpOwotICAgICAgICBtX2VsZW1lbnRGbGFncy5wdXQoCi0gICAgICAgICAgICAiSFIiLAotICAgICAgICAgICAgbmV3IEVsZW1EZXNjKAotICAgICAgICAgICAgICAgIDAKLSAgICAgICAgICAgICAgICAgICAgfCBFbGVtRGVzYy5CTE9DSwotICAgICAgICAgICAgICAgICAgICB8IEVsZW1EZXNjLkJMT0NLRk9STQotICAgICAgICAgICAgICAgICAgICB8IEVsZW1EZXNjLkJMT0NLRk9STUZJRUxEU0VUCi0gICAgICAgICAgICAgICAgICAgIHwgRWxlbURlc2MuRU1QVFkpKTsKLSAgICAgICAgbV9lbGVtZW50RmxhZ3MucHV0KAotICAgICAgICAgICAgIlAiLAotICAgICAgICAgICAgbmV3IEVsZW1EZXNjKAotICAgICAgICAgICAgICAgIDAKLSAgICAgICAgICAgICAgICAgICAgfCBFbGVtRGVzYy5CTE9DSwotICAgICAgICAgICAgICAgICAgICB8IEVsZW1EZXNjLkJMT0NLRk9STQotICAgICAgICAgICAgICAgICAgICB8IEVsZW1EZXNjLkJMT0NLRk9STUZJRUxEU0VUKSk7Ci0gICAgICAgIG1fZWxlbWVudEZsYWdzLnB1dCgKLSAgICAgICAgICAgICJIMSIsCi0gICAgICAgICAgICBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLkhFQUQgfCBFbGVtRGVzYy5CTE9DSykpOwotICAgICAgICBtX2VsZW1lbnRGbGFncy5wdXQoCi0gICAgICAgICAgICAiSDIiLAotICAgICAgICAgICAgbmV3IEVsZW1EZXNjKDAgfCBFbGVtRGVzYy5IRUFEIHwgRWxlbURlc2MuQkxPQ0spKTsKLSAgICAgICAgbV9lbGVtZW50RmxhZ3MucHV0KAotICAgICAgICAgICAgIkgzIiwKLSAgICAgICAgICAgIG5ldyBFbGVtRGVzYygwIHwgRWxlbURlc2MuSEVBRCB8IEVsZW1EZXNjLkJMT0NLKSk7Ci0gICAgICAgIG1fZWxlbWVudEZsYWdzLnB1dCgKLSAgICAgICAgICAgICJINCIsCi0gICAgICAgICAgICBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLkhFQUQgfCBFbGVtRGVzYy5CTE9DSykpOwotICAgICAgICBtX2VsZW1lbnRGbGFncy5wdXQoCi0gICAgICAgICAgICAiSDUiLAotICAgICAgICAgICAgbmV3IEVsZW1EZXNjKDAgfCBFbGVtRGVzYy5IRUFEIHwgRWxlbURlc2MuQkxPQ0spKTsKLSAgICAgICAgbV9lbGVtZW50RmxhZ3MucHV0KAotICAgICAgICAgICAgIkg2IiwKLSAgICAgICAgICAgIG5ldyBFbGVtRGVzYygwIHwgRWxlbURlc2MuSEVBRCB8IEVsZW1EZXNjLkJMT0NLKSk7Ci0gICAgICAgIG1fZWxlbWVudEZsYWdzLnB1dCgKLSAgICAgICAgICAgICJQUkUiLAotICAgICAgICAgICAgbmV3IEVsZW1EZXNjKDAgfCBFbGVtRGVzYy5QUkVGT1JNQVRURUQgfCBFbGVtRGVzYy5CTE9DSykpOwotICAgICAgICBtX2VsZW1lbnRGbGFncy5wdXQoCi0gICAgICAgICAgICAiUSIsCi0gICAgICAgICAgICBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLlNQRUNJQUwgfCBFbGVtRGVzYy5BU1BFQ0lBTCkpOwotICAgICAgICBtX2VsZW1lbnRGbGFncy5wdXQoCi0gICAgICAgICAgICAiQkxPQ0tRVU9URSIsCi0gICAgICAgICAgICBuZXcgRWxlbURlc2MoCi0gICAgICAgICAgICAgICAgMAotICAgICAgICAgICAgICAgICAgICB8IEVsZW1EZXNjLkJMT0NLCi0gICAgICAgICAgICAgICAgICAgIHwgRWxlbURlc2MuQkxPQ0tGT1JNCi0gICAgICAgICAgICAgICAgICAgIHwgRWxlbURlc2MuQkxPQ0tGT1JNRklFTERTRVQpKTsKLSAgICAgICAgbV9lbGVtZW50RmxhZ3MucHV0KCJJTlMiLCBuZXcgRWxlbURlc2MoMCkpOwotICAgICAgICBtX2VsZW1lbnRGbGFncy5wdXQoIkRFTCIsIG5ldyBFbGVtRGVzYygwKSk7Ci0gICAgICAgIG1fZWxlbWVudEZsYWdzLnB1dCgKLSAgICAgICAgICAgICJETCIsCi0gICAgICAgICAgICBuZXcgRWxlbURlc2MoCi0gICAgICAgICAgICAgICAgMAotICAgICAgICAgICAgICAgICAgICB8IEVsZW1EZXNjLkJMT0NLCi0gICAgICAgICAgICAgICAgICAgIHwgRWxlbURlc2MuQkxPQ0tGT1JNCi0gICAgICAgICAgICAgICAgICAgIHwgRWxlbURlc2MuQkxPQ0tGT1JNRklFTERTRVQpKTsKLSAgICAgICAgbV9lbGVtZW50RmxhZ3MucHV0KCJEVCIsIG5ldyBFbGVtRGVzYygwIHwgRWxlbURlc2MuQkxPQ0spKTsKLSAgICAgICAgbV9lbGVtZW50RmxhZ3MucHV0KCJERCIsIG5ldyBFbGVtRGVzYygwIHwgRWxlbURlc2MuQkxPQ0spKTsKLSAgICAgICAgbV9lbGVtZW50RmxhZ3MucHV0KAotICAgICAgICAgICAgIk9MIiwKLSAgICAgICAgICAgIG5ldyBFbGVtRGVzYygwIHwgRWxlbURlc2MuTElTVCB8IEVsZW1EZXNjLkJMT0NLKSk7Ci0gICAgICAgIG1fZWxlbWVudEZsYWdzLnB1dCgKLSAgICAgICAgICAgICJVTCIsCi0gICAgICAgICAgICBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLkxJU1QgfCBFbGVtRGVzYy5CTE9DSykpOwotICAgICAgICBtX2VsZW1lbnRGbGFncy5wdXQoIkxJIiwgbmV3IEVsZW1EZXNjKDAgfCBFbGVtRGVzYy5CTE9DSykpOwotICAgICAgICBtX2VsZW1lbnRGbGFncy5wdXQoIkZPUk0iLCBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLkJMT0NLKSk7Ci0gICAgICAgIG1fZWxlbWVudEZsYWdzLnB1dCgiTEFCRUwiLCBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLkZPUk1DVFJMKSk7Ci0gICAgICAgIG1fZWxlbWVudEZsYWdzLnB1dCgKLSAgICAgICAgICAgICJJTlBVVCIsCi0gICAgICAgICAgICBuZXcgRWxlbURlc2MoCi0gICAgICAgICAgICAgICAgMCB8IEVsZW1EZXNjLkZPUk1DVFJMIHwgRWxlbURlc2MuSU5MSU5FTEFCRUwgfCBFbGVtRGVzYy5FTVBUWSkpOwotICAgICAgICBtX2VsZW1lbnRGbGFncy5wdXQoCi0gICAgICAgICAgICAiU0VMRUNUIiwKLSAgICAgICAgICAgIG5ldyBFbGVtRGVzYygwIHwgRWxlbURlc2MuRk9STUNUUkwgfCBFbGVtRGVzYy5JTkxJTkVMQUJFTCkpOwotICAgICAgICBtX2VsZW1lbnRGbGFncy5wdXQoIk9QVEdST1VQIiwgbmV3IEVsZW1EZXNjKDApKTsKLSAgICAgICAgbV9lbGVtZW50RmxhZ3MucHV0KCJPUFRJT04iLCBuZXcgRWxlbURlc2MoMCkpOwotICAgICAgICBtX2VsZW1lbnRGbGFncy5wdXQoCi0gICAgICAgICAgICAiVEVYVEFSRUEiLAotICAgICAgICAgICAgbmV3IEVsZW1EZXNjKDAgfCBFbGVtRGVzYy5GT1JNQ1RSTCB8IEVsZW1EZXNjLklOTElORUxBQkVMKSk7Ci0gICAgICAgIG1fZWxlbWVudEZsYWdzLnB1dCgKLSAgICAgICAgICAgICJGSUVMRFNFVCIsCi0gICAgICAgICAgICBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLkJMT0NLIHwgRWxlbURlc2MuQkxPQ0tGT1JNKSk7Ci0gICAgICAgIG1fZWxlbWVudEZsYWdzLnB1dCgiTEVHRU5EIiwgbmV3IEVsZW1EZXNjKDApKTsKLSAgICAgICAgbV9lbGVtZW50RmxhZ3MucHV0KAotICAgICAgICAgICAgIkJVVFRPTiIsCi0gICAgICAgICAgICBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLkZPUk1DVFJMIHwgRWxlbURlc2MuSU5MSU5FTEFCRUwpKTsKLSAgICAgICAgbV9lbGVtZW50RmxhZ3MucHV0KAotICAgICAgICAgICAgIlRBQkxFIiwKLSAgICAgICAgICAgIG5ldyBFbGVtRGVzYygKLSAgICAgICAgICAgICAgICAwCi0gICAgICAgICAgICAgICAgICAgIHwgRWxlbURlc2MuQkxPQ0sKLSAgICAgICAgICAgICAgICAgICAgfCBFbGVtRGVzYy5CTE9DS0ZPUk0KLSAgICAgICAgICAgICAgICAgICAgfCBFbGVtRGVzYy5CTE9DS0ZPUk1GSUVMRFNFVCkpOwotICAgICAgICBtX2VsZW1lbnRGbGFncy5wdXQoIkNBUFRJT04iLCBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLkJMT0NLKSk7Ci0gICAgICAgIG1fZWxlbWVudEZsYWdzLnB1dCgiVEhFQUQiLCBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLkJMT0NLKSk7Ci0gICAgICAgIG1fZWxlbWVudEZsYWdzLnB1dCgiVEZPT1QiLCBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLkJMT0NLKSk7Ci0gICAgICAgIG1fZWxlbWVudEZsYWdzLnB1dCgiVEJPRFkiLCBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLkJMT0NLKSk7Ci0gICAgICAgIG1fZWxlbWVudEZsYWdzLnB1dCgiQ09MR1JPVVAiLCBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLkJMT0NLKSk7Ci0gICAgICAgIG1fZWxlbWVudEZsYWdzLnB1dCgKLSAgICAgICAgICAgICJDT0wiLAotICAgICAgICAgICAgbmV3IEVsZW1EZXNjKDAgfCBFbGVtRGVzYy5FTVBUWSB8IEVsZW1EZXNjLkJMT0NLKSk7Ci0gICAgICAgIG1fZWxlbWVudEZsYWdzLnB1dCgiVFIiLCBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLkJMT0NLKSk7Ci0gICAgICAgIG1fZWxlbWVudEZsYWdzLnB1dCgiVEgiLCBuZXcgRWxlbURlc2MoMCkpOwotICAgICAgICBtX2VsZW1lbnRGbGFncy5wdXQoIlREIiwgbmV3IEVsZW1EZXNjKDApKTsKLSAgICAgICAgbV9lbGVtZW50RmxhZ3MucHV0KAotICAgICAgICAgICAgIkhFQUQiLAotICAgICAgICAgICAgbmV3IEVsZW1EZXNjKDAgfCBFbGVtRGVzYy5CTE9DSyB8IEVsZW1EZXNjLkhFQURFTEVNKSk7Ci0gICAgICAgIG1fZWxlbWVudEZsYWdzLnB1dCgiVElUTEUiLCBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLkJMT0NLKSk7Ci0gICAgICAgIG1fZWxlbWVudEZsYWdzLnB1dCgKLSAgICAgICAgICAgICJCQVNFIiwKLSAgICAgICAgICAgIG5ldyBFbGVtRGVzYygwIHwgRWxlbURlc2MuRU1QVFkgfCBFbGVtRGVzYy5CTE9DSykpOwotICAgICAgICBtX2VsZW1lbnRGbGFncy5wdXQoCi0gICAgICAgICAgICAiTUVUQSIsCi0gICAgICAgICAgICBuZXcgRWxlbURlc2MoCi0gICAgICAgICAgICAgICAgMCB8IEVsZW1EZXNjLkhFQURNSVNDIHwgRWxlbURlc2MuRU1QVFkgfCBFbGVtRGVzYy5CTE9DSykpOwotICAgICAgICBtX2VsZW1lbnRGbGFncy5wdXQoCi0gICAgICAgICAgICAiU1RZTEUiLAotICAgICAgICAgICAgbmV3IEVsZW1EZXNjKAotICAgICAgICAgICAgICAgIDAgfCBFbGVtRGVzYy5IRUFETUlTQyB8IEVsZW1EZXNjLlJBVyB8IEVsZW1EZXNjLkJMT0NLKSk7Ci0gICAgICAgIG1fZWxlbWVudEZsYWdzLnB1dCgKLSAgICAgICAgICAgICJTQ1JJUFQiLAotICAgICAgICAgICAgbmV3IEVsZW1EZXNjKAotICAgICAgICAgICAgICAgIDAKLSAgICAgICAgICAgICAgICAgICAgfCBFbGVtRGVzYy5TUEVDSUFMCi0gICAgICAgICAgICAgICAgICAgIHwgRWxlbURlc2MuQVNQRUNJQUwKLSAgICAgICAgICAgICAgICAgICAgfCBFbGVtRGVzYy5IRUFETUlTQwotICAgICAgICAgICAgICAgICAgICB8IEVsZW1EZXNjLlJBVykpOwotICAgICAgICBtX2VsZW1lbnRGbGFncy5wdXQoCi0gICAgICAgICAgICAiTk9TQ1JJUFQiLAotICAgICAgICAgICAgbmV3IEVsZW1EZXNjKAotICAgICAgICAgICAgICAgIDAKLSAgICAgICAgICAgICAgICAgICAgfCBFbGVtRGVzYy5CTE9DSwotICAgICAgICAgICAgICAgICAgICB8IEVsZW1EZXNjLkJMT0NLRk9STQotICAgICAgICAgICAgICAgICAgICB8IEVsZW1EZXNjLkJMT0NLRk9STUZJRUxEU0VUKSk7Ci0gICAgICAgIG1fZWxlbWVudEZsYWdzLnB1dCgiSFRNTCIsIG5ldyBFbGVtRGVzYygwIHwgRWxlbURlc2MuQkxPQ0spKTsKLQotICAgICAgICAvLyBGcm9tICJKb2huIEt5IiA8aGFuZEBzeWQuc3BlZWRuZXQuY29tLmF1Ci0gICAgICAgIC8vIFRyYW5zaXRpb25hbCBEb2N1bWVudCBUeXBlIERlZmluaXRpb24gKCkKLSAgICAgICAgLy8gZmlsZTovLy9DOi9Eb2N1bWVudHMlMjBhbmQlMjBTZXR0aW5ncy9zYm9hZy5CT0FHNjAwRS9NeSUyMERvY3VtZW50cy9odG1sL3NnbWwvbG9vc2VkdGQuaHRtbCNiYXNlZm9udAotICAgICAgICBtX2VsZW1lbnRGbGFncy5wdXQoIkZPTlQiLCBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLkZPTlRTVFlMRSkpOwotCi0gICAgICAgIC8vIGZpbGU6Ly8vQzovRG9jdW1lbnRzJTIwYW5kJTIwU2V0dGluZ3Mvc2JvYWcuQk9BRzYwMEUvTXklMjBEb2N1bWVudHMvaHRtbC9wcmVzZW50L2dyYXBoaWNzLmh0bWwjZWRlZi1TVFJJS0UKLSAgICAgICAgbV9lbGVtZW50RmxhZ3MucHV0KCJTIiwgbmV3IEVsZW1EZXNjKDAgfCBFbGVtRGVzYy5GT05UU1RZTEUpKTsKLSAgICAgICAgbV9lbGVtZW50RmxhZ3MucHV0KCJTVFJJS0UiLCBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLkZPTlRTVFlMRSkpOwotCi0gICAgICAgIC8vIGZpbGU6Ly8vQzovRG9jdW1lbnRzJTIwYW5kJTIwU2V0dGluZ3Mvc2JvYWcuQk9BRzYwMEUvTXklMjBEb2N1bWVudHMvaHRtbC9wcmVzZW50L2dyYXBoaWNzLmh0bWwjZWRlZi1VCi0gICAgICAgIG1fZWxlbWVudEZsYWdzLnB1dCgiVSIsIG5ldyBFbGVtRGVzYygwIHwgRWxlbURlc2MuRk9OVFNUWUxFKSk7Ci0KLSAgICAgICAgLy8gRnJvbSAiSm9obiBLeSIgPGhhbmRAc3lkLnNwZWVkbmV0LmNvbS5hdQotICAgICAgICBtX2VsZW1lbnRGbGFncy5wdXQoIk5PQlIiLCBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLkZPTlRTVFlMRSkpOwotCi0gICAgICAgIC8vIEhUTUwgNC4wLCBzZWN0aW9uIDE2LjUKLSAgICAgICAgbV9lbGVtZW50RmxhZ3MucHV0KAotICAgICAgICAgICAgIklGUkFNRSIsCi0gICAgICAgICAgICBuZXcgRWxlbURlc2MoCi0gICAgICAgICAgICAgICAgMAotICAgICAgICAgICAgICAgICAgICB8IEVsZW1EZXNjLkJMT0NLCi0gICAgICAgICAgICAgICAgICAgIHwgRWxlbURlc2MuQkxPQ0tGT1JNCi0gICAgICAgICAgICAgICAgICAgIHwgRWxlbURlc2MuQkxPQ0tGT1JNRklFTERTRVQpKTsKLQotICAgICAgICAvLyBOZXRzY2FwZSA0IGV4dGVuc2lvbgotICAgICAgICBtX2VsZW1lbnRGbGFncy5wdXQoCi0gICAgICAgICAgICAiTEFZRVIiLAotICAgICAgICAgICAgbmV3IEVsZW1EZXNjKAotICAgICAgICAgICAgICAgIDAKLSAgICAgICAgICAgICAgICAgICAgfCBFbGVtRGVzYy5CTE9DSwotICAgICAgICAgICAgICAgICAgICB8IEVsZW1EZXNjLkJMT0NLRk9STQotICAgICAgICAgICAgICAgICAgICB8IEVsZW1EZXNjLkJMT0NLRk9STUZJRUxEU0VUKSk7Ci0gICAgICAgIC8vIE5ldHNjYXBlIDQgZXh0ZW5zaW9uCi0gICAgICAgIG1fZWxlbWVudEZsYWdzLnB1dCgKLSAgICAgICAgICAgICJJTEFZRVIiLAotICAgICAgICAgICAgbmV3IEVsZW1EZXNjKAotICAgICAgICAgICAgICAgIDAKLSAgICAgICAgICAgICAgICAgICAgfCBFbGVtRGVzYy5CTE9DSwotICAgICAgICAgICAgICAgICAgICB8IEVsZW1EZXNjLkJMT0NLRk9STQotICAgICAgICAgICAgICAgICAgICB8IEVsZW1EZXNjLkJMT0NLRk9STUZJRUxEU0VUKSk7Ci0KLQotICAgICAgICAvLyBOT1cgRk9SIEFUVFJJQlVURSBJTkZPUk1BVElPTiAuIC4gLgotICAgICAgICBFbGVtRGVzYyBlbGVtRGVzYzsKLQotCi0gICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICAgICAgZWxlbURlc2MgPSAoRWxlbURlc2MpIG1fZWxlbWVudEZsYWdzLmdldCgiQSIpOwotICAgICAgICBlbGVtRGVzYy5zZXRBdHRyKCJIUkVGIiwgRWxlbURlc2MuQVRUUlVSTCk7Ci0gICAgICAgIGVsZW1EZXNjLnNldEF0dHIoIk5BTUUiLCBFbGVtRGVzYy5BVFRSVVJMKTsKLQotICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgICAgIGVsZW1EZXNjID0gKEVsZW1EZXNjKSBtX2VsZW1lbnRGbGFncy5nZXQoIkFSRUEiKTsKLSAgICAgICAgZWxlbURlc2Muc2V0QXR0cigiSFJFRiIsIEVsZW1EZXNjLkFUVFJVUkwpOwotICAgICAgICBlbGVtRGVzYy5zZXRBdHRyKCJOT0hSRUYiLCBFbGVtRGVzYy5BVFRSRU1QVFkpOwotCi0gICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICAgICAgZWxlbURlc2MgPSAoRWxlbURlc2MpIG1fZWxlbWVudEZsYWdzLmdldCgiQkFTRSIpOwotICAgICAgICBlbGVtRGVzYy5zZXRBdHRyKCJIUkVGIiwgRWxlbURlc2MuQVRUUlVSTCk7Ci0KLSAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgICAgICBlbGVtRGVzYyA9IChFbGVtRGVzYykgbV9lbGVtZW50RmxhZ3MuZ2V0KCJCVVRUT04iKTsKLSAgICAgICAgZWxlbURlc2Muc2V0QXR0cigiRElTQUJMRUQiLCBFbGVtRGVzYy5BVFRSRU1QVFkpOwotCi0gICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICAgICAgZWxlbURlc2MgPSAoRWxlbURlc2MpIG1fZWxlbWVudEZsYWdzLmdldCgiQkxPQ0tRVU9URSIpOwotICAgICAgICBlbGVtRGVzYy5zZXRBdHRyKCJDSVRFIiwgRWxlbURlc2MuQVRUUlVSTCk7Ci0KLSAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgICAgICBlbGVtRGVzYyA9IChFbGVtRGVzYykgbV9lbGVtZW50RmxhZ3MuZ2V0KCJERUwiKTsKLSAgICAgICAgZWxlbURlc2Muc2V0QXR0cigiQ0lURSIsIEVsZW1EZXNjLkFUVFJVUkwpOwotCi0gICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICAgICAgZWxlbURlc2MgPSAoRWxlbURlc2MpIG1fZWxlbWVudEZsYWdzLmdldCgiRElSIik7Ci0gICAgICAgIGVsZW1EZXNjLnNldEF0dHIoIkNPTVBBQ1QiLCBFbGVtRGVzYy5BVFRSRU1QVFkpOwotCi0gICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLQotICAgICAgICBlbGVtRGVzYyA9IChFbGVtRGVzYykgbV9lbGVtZW50RmxhZ3MuZ2V0KCJESVYiKTsKLSAgICAgICAgZWxlbURlc2Muc2V0QXR0cigiU1JDIiwgRWxlbURlc2MuQVRUUlVSTCk7IC8vIE5ldHNjYXBlIDQgZXh0ZW5zaW9uCi0gICAgICAgIGVsZW1EZXNjLnNldEF0dHIoIk5PV1JBUCIsIEVsZW1EZXNjLkFUVFJFTVBUWSk7IC8vIEludGVybmV0LUV4cGxvcmVyIGV4dGVuc2lvbgotCi0gICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICAgICAgZWxlbURlc2MgPSAoRWxlbURlc2MpIG1fZWxlbWVudEZsYWdzLmdldCgiREwiKTsKLSAgICAgICAgZWxlbURlc2Muc2V0QXR0cigiQ09NUEFDVCIsIEVsZW1EZXNjLkFUVFJFTVBUWSk7Ci0KLSAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgICAgICBlbGVtRGVzYyA9IChFbGVtRGVzYykgbV9lbGVtZW50RmxhZ3MuZ2V0KCJGT1JNIik7Ci0gICAgICAgIGVsZW1EZXNjLnNldEF0dHIoIkFDVElPTiIsIEVsZW1EZXNjLkFUVFJVUkwpOwotCi0gICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICAgICAgLy8gQXR0cmlidXRpb24gdG86ICJWb3l0ZW5rbywgRGltaXRyeSIgPERWb3l0ZW5rb0BTRUNUT1JCQVNFLkNPTT4KLSAgICAgICAgZWxlbURlc2MgPSAoRWxlbURlc2MpIG1fZWxlbWVudEZsYWdzLmdldCgiRlJBTUUiKTsKLSAgICAgICAgZWxlbURlc2Muc2V0QXR0cigiU1JDIiwgRWxlbURlc2MuQVRUUlVSTCk7Ci0gICAgICAgIGVsZW1EZXNjLnNldEF0dHIoIkxPTkdERVNDIiwgRWxlbURlc2MuQVRUUlVSTCk7Ci0gICAgICAgIGVsZW1EZXNjLnNldEF0dHIoIk5PUkVTSVpFIixFbGVtRGVzYy5BVFRSRU1QVFkpOwotCi0gICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICAgICAgZWxlbURlc2MgPSAoRWxlbURlc2MpIG1fZWxlbWVudEZsYWdzLmdldCgiSEVBRCIpOwotICAgICAgICBlbGVtRGVzYy5zZXRBdHRyKCJQUk9GSUxFIiwgRWxlbURlc2MuQVRUUlVSTCk7Ci0KLSAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgICAgICBlbGVtRGVzYyA9IChFbGVtRGVzYykgbV9lbGVtZW50RmxhZ3MuZ2V0KCJIUiIpOwotICAgICAgICBlbGVtRGVzYy5zZXRBdHRyKCJOT1NIQURFIiwgRWxlbURlc2MuQVRUUkVNUFRZKTsKLQotICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgICAgIC8vIEhUTUwgNC4wLCBzZWN0aW9uIDE2LjUKLSAgICAgICAgZWxlbURlc2MgPSAoRWxlbURlc2MpIG1fZWxlbWVudEZsYWdzLmdldCgiSUZSQU1FIik7Ci0gICAgICAgIGVsZW1EZXNjLnNldEF0dHIoIlNSQyIsIEVsZW1EZXNjLkFUVFJVUkwpOwotICAgICAgICBlbGVtRGVzYy5zZXRBdHRyKCJMT05HREVTQyIsIEVsZW1EZXNjLkFUVFJVUkwpOwotCi0gICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICAgICAgLy8gTmV0c2NhcGUgNCBleHRlbnNpb24KLSAgICAgICAgZWxlbURlc2MgPSAoRWxlbURlc2MpIG1fZWxlbWVudEZsYWdzLmdldCgiSUxBWUVSIik7Ci0gICAgICAgIGVsZW1EZXNjLnNldEF0dHIoIlNSQyIsIEVsZW1EZXNjLkFUVFJVUkwpOwotCi0gICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICAgICAgZWxlbURlc2MgPSAoRWxlbURlc2MpIG1fZWxlbWVudEZsYWdzLmdldCgiSU1HIik7Ci0gICAgICAgIGVsZW1EZXNjLnNldEF0dHIoIlNSQyIsIEVsZW1EZXNjLkFUVFJVUkwpOwotICAgICAgICBlbGVtRGVzYy5zZXRBdHRyKCJMT05HREVTQyIsIEVsZW1EZXNjLkFUVFJVUkwpOwotICAgICAgICBlbGVtRGVzYy5zZXRBdHRyKCJVU0VNQVAiLCBFbGVtRGVzYy5BVFRSVVJMKTsKLSAgICAgICAgZWxlbURlc2Muc2V0QXR0cigiSVNNQVAiLCBFbGVtRGVzYy5BVFRSRU1QVFkpOwotCi0gICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICAgICAgZWxlbURlc2MgPSAoRWxlbURlc2MpIG1fZWxlbWVudEZsYWdzLmdldCgiSU5QVVQiKTsKLSAgICAgICAgZWxlbURlc2Muc2V0QXR0cigiU1JDIiwgRWxlbURlc2MuQVRUUlVSTCk7Ci0gICAgICAgIGVsZW1EZXNjLnNldEF0dHIoIlVTRU1BUCIsIEVsZW1EZXNjLkFUVFJVUkwpOwotICAgICAgICBlbGVtRGVzYy5zZXRBdHRyKCJDSEVDS0VEIiwgRWxlbURlc2MuQVRUUkVNUFRZKTsKLSAgICAgICAgZWxlbURlc2Muc2V0QXR0cigiRElTQUJMRUQiLCBFbGVtRGVzYy5BVFRSRU1QVFkpOwotICAgICAgICBlbGVtRGVzYy5zZXRBdHRyKCJJU01BUCIsIEVsZW1EZXNjLkFUVFJFTVBUWSk7Ci0gICAgICAgIGVsZW1EZXNjLnNldEF0dHIoIlJFQURPTkxZIiwgRWxlbURlc2MuQVRUUkVNUFRZKTsKLQotICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgICAgIGVsZW1EZXNjID0gKEVsZW1EZXNjKSBtX2VsZW1lbnRGbGFncy5nZXQoIklOUyIpOwotICAgICAgICBlbGVtRGVzYy5zZXRBdHRyKCJDSVRFIiwgRWxlbURlc2MuQVRUUlVSTCk7Ci0KLSAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgICAgICAvLyBOZXRzY2FwZSA0IGV4dGVuc2lvbgotICAgICAgICBlbGVtRGVzYyA9IChFbGVtRGVzYykgbV9lbGVtZW50RmxhZ3MuZ2V0KCJMQVlFUiIpOwotICAgICAgICBlbGVtRGVzYy5zZXRBdHRyKCJTUkMiLCBFbGVtRGVzYy5BVFRSVVJMKTsKLQotICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgICAgIGVsZW1EZXNjID0gKEVsZW1EZXNjKSBtX2VsZW1lbnRGbGFncy5nZXQoIkxJTksiKTsKLSAgICAgICAgZWxlbURlc2Muc2V0QXR0cigiSFJFRiIsIEVsZW1EZXNjLkFUVFJVUkwpOwotCi0gICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICAgICAgZWxlbURlc2MgPSAoRWxlbURlc2MpIG1fZWxlbWVudEZsYWdzLmdldCgiTUVOVSIpOwotICAgICAgICBlbGVtRGVzYy5zZXRBdHRyKCJDT01QQUNUIiwgRWxlbURlc2MuQVRUUkVNUFRZKTsKLQotICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgICAgIGVsZW1EZXNjID0gKEVsZW1EZXNjKSBtX2VsZW1lbnRGbGFncy5nZXQoIk9CSkVDVCIpOwotICAgICAgICBlbGVtRGVzYy5zZXRBdHRyKCJDTEFTU0lEIiwgRWxlbURlc2MuQVRUUlVSTCk7Ci0gICAgICAgIGVsZW1EZXNjLnNldEF0dHIoIkNPREVCQVNFIiwgRWxlbURlc2MuQVRUUlVSTCk7Ci0gICAgICAgIGVsZW1EZXNjLnNldEF0dHIoIkRBVEEiLCBFbGVtRGVzYy5BVFRSVVJMKTsKLSAgICAgICAgZWxlbURlc2Muc2V0QXR0cigiQVJDSElWRSIsIEVsZW1EZXNjLkFUVFJVUkwpOwotICAgICAgICBlbGVtRGVzYy5zZXRBdHRyKCJVU0VNQVAiLCBFbGVtRGVzYy5BVFRSVVJMKTsKLSAgICAgICAgZWxlbURlc2Muc2V0QXR0cigiREVDTEFSRSIsIEVsZW1EZXNjLkFUVFJFTVBUWSk7Ci0KLSAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgICAgICBlbGVtRGVzYyA9IChFbGVtRGVzYykgbV9lbGVtZW50RmxhZ3MuZ2V0KCJPTCIpOwotICAgICAgICBlbGVtRGVzYy5zZXRBdHRyKCJDT01QQUNUIiwgRWxlbURlc2MuQVRUUkVNUFRZKTsKLQotICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgICAgIGVsZW1EZXNjID0gKEVsZW1EZXNjKSBtX2VsZW1lbnRGbGFncy5nZXQoIk9QVEdST1VQIik7Ci0gICAgICAgIGVsZW1EZXNjLnNldEF0dHIoIkRJU0FCTEVEIiwgRWxlbURlc2MuQVRUUkVNUFRZKTsKLQotICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgICAgIGVsZW1EZXNjID0gKEVsZW1EZXNjKSBtX2VsZW1lbnRGbGFncy5nZXQoIk9QVElPTiIpOwotICAgICAgICBlbGVtRGVzYy5zZXRBdHRyKCJTRUxFQ1RFRCIsIEVsZW1EZXNjLkFUVFJFTVBUWSk7Ci0gICAgICAgIGVsZW1EZXNjLnNldEF0dHIoIkRJU0FCTEVEIiwgRWxlbURlc2MuQVRUUkVNUFRZKTsKLQotICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgICAgIGVsZW1EZXNjID0gKEVsZW1EZXNjKSBtX2VsZW1lbnRGbGFncy5nZXQoIlEiKTsKLSAgICAgICAgZWxlbURlc2Muc2V0QXR0cigiQ0lURSIsIEVsZW1EZXNjLkFUVFJVUkwpOwotCi0gICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICAgICAgZWxlbURlc2MgPSAoRWxlbURlc2MpIG1fZWxlbWVudEZsYWdzLmdldCgiU0NSSVBUIik7Ci0gICAgICAgIGVsZW1EZXNjLnNldEF0dHIoIlNSQyIsIEVsZW1EZXNjLkFUVFJVUkwpOwotICAgICAgICBlbGVtRGVzYy5zZXRBdHRyKCJGT1IiLCBFbGVtRGVzYy5BVFRSVVJMKTsKLSAgICAgICAgZWxlbURlc2Muc2V0QXR0cigiREVGRVIiLCBFbGVtRGVzYy5BVFRSRU1QVFkpOwotCi0gICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICAgICAgZWxlbURlc2MgPSAoRWxlbURlc2MpIG1fZWxlbWVudEZsYWdzLmdldCgiU0VMRUNUIik7Ci0gICAgICAgIGVsZW1EZXNjLnNldEF0dHIoIkRJU0FCTEVEIiwgRWxlbURlc2MuQVRUUkVNUFRZKTsKLSAgICAgICAgZWxlbURlc2Muc2V0QXR0cigiTVVMVElQTEUiLCBFbGVtRGVzYy5BVFRSRU1QVFkpOwotCi0gICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICAgICAgZWxlbURlc2MgPSAoRWxlbURlc2MpIG1fZWxlbWVudEZsYWdzLmdldCgiVEFCTEUiKTsKLSAgICAgICAgZWxlbURlc2Muc2V0QXR0cigiTk9XUkFQIiwgRWxlbURlc2MuQVRUUkVNUFRZKTsgLy8gSW50ZXJuZXQtRXhwbG9yZXIgZXh0ZW5zaW9uCi0KLSAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgICAgICBlbGVtRGVzYyA9IChFbGVtRGVzYykgbV9lbGVtZW50RmxhZ3MuZ2V0KCJURCIpOwotICAgICAgICBlbGVtRGVzYy5zZXRBdHRyKCJOT1dSQVAiLCBFbGVtRGVzYy5BVFRSRU1QVFkpOwotCi0gICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICAgICAgZWxlbURlc2MgPSAoRWxlbURlc2MpIG1fZWxlbWVudEZsYWdzLmdldCgiVEVYVEFSRUEiKTsKLSAgICAgICAgZWxlbURlc2Muc2V0QXR0cigiRElTQUJMRUQiLCBFbGVtRGVzYy5BVFRSRU1QVFkpOwotICAgICAgICBlbGVtRGVzYy5zZXRBdHRyKCJSRUFET05MWSIsIEVsZW1EZXNjLkFUVFJFTVBUWSk7Ci0KLSAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgICAgICBlbGVtRGVzYyA9IChFbGVtRGVzYykgbV9lbGVtZW50RmxhZ3MuZ2V0KCJUSCIpOwotICAgICAgICBlbGVtRGVzYy5zZXRBdHRyKCJOT1dSQVAiLCBFbGVtRGVzYy5BVFRSRU1QVFkpOwotCi0gICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICAgICAgLy8gVGhlIG5vd3JhcCBhdHRyaWJ1dGUgb2YgYSB0ciBlbGVtZW50IGlzIGJvdGgKLSAgICAgICAgLy8gYSBOZXRzY2FwZSBhbmQgSW50ZXJuZXQtRXhwbG9yZXIgZXh0ZW5zaW9uCi0gICAgICAgIGVsZW1EZXNjID0gKEVsZW1EZXNjKSBtX2VsZW1lbnRGbGFncy5nZXQoIlRSIik7Ci0gICAgICAgIGVsZW1EZXNjLnNldEF0dHIoIk5PV1JBUCIsIEVsZW1EZXNjLkFUVFJFTVBUWSk7Ci0KLSAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgICAgICBlbGVtRGVzYyA9IChFbGVtRGVzYykgbV9lbGVtZW50RmxhZ3MuZ2V0KCJVTCIpOwotICAgICAgICBlbGVtRGVzYy5zZXRBdHRyKCJDT01QQUNUIiwgRWxlbURlc2MuQVRUUkVNUFRZKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBEdW1teSBlbGVtZW50IGZvciBlbGVtZW50cyBub3QgZm91bmQuCi0gICAgICovCi0gICAgc3RhdGljIHByaXZhdGUgZmluYWwgRWxlbURlc2MgbV9kdW1teSA9IG5ldyBFbGVtRGVzYygwIHwgRWxlbURlc2MuQkxPQ0spOwotCi0gICAgLyoqIFRydWUgaWYgVVJMcyBzaG91bGQgYmUgc3BlY2lhbGx5IGVzY2FwZWQgd2l0aCB0aGUgJXh4IGZvcm0uICovCi0gICAgcHJpdmF0ZSBib29sZWFuIG1fc3BlY2lhbEVzY2FwZVVSTHMgPSB0cnVlOwotCi0gICAgLyoqIFRydWUgaWYgdGhlIE1FVEEgdGFnIHNob3VsZCBiZSBvbWl0dGVkLiAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBtX29taXRNZXRhVGFnID0gZmFsc2U7Ci0KLSAgICAvKioKLSAgICAgKiBUZWxscyBpZiB0aGUgZm9ybWF0dGVyIHNob3VsZCB1c2Ugc3BlY2lhbCBVUkwgZXNjYXBpbmcuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYm9vbCBUcnVlIGlmIFVSTHMgc2hvdWxkIGJlIHNwZWNpYWxseSBlc2NhcGVkIHdpdGggdGhlICV4eCBmb3JtLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFNwZWNpYWxFc2NhcGVVUkxzKGJvb2xlYW4gYm9vbCkKLSAgICB7Ci0gICAgICAgIG1fc3BlY2lhbEVzY2FwZVVSTHMgPSBib29sOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRlbGxzIGlmIHRoZSBmb3JtYXR0ZXIgc2hvdWxkIG9taXQgdGhlIE1FVEEgdGFnLgotICAgICAqCi0gICAgICogQHBhcmFtIGJvb2wgVHJ1ZSBpZiB0aGUgTUVUQSB0YWcgc2hvdWxkIGJlIG9taXR0ZWQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0T21pdE1ldGFUYWcoYm9vbGVhbiBib29sKQotICAgIHsKLSAgICAgICAgbV9vbWl0TWV0YVRhZyA9IGJvb2w7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU3BlY2lmaWVzIGFuIG91dHB1dCBmb3JtYXQgZm9yIHRoaXMgc2VyaWFsaXplci4gSXQgdGhlCi0gICAgICogc2VyaWFsaXplciBoYXMgYWxyZWFkeSBiZWVuIGFzc29jaWF0ZWQgd2l0aCBhbiBvdXRwdXQgZm9ybWF0LAotICAgICAqIGl0IHdpbGwgc3dpdGNoIHRvIHRoZSBuZXcgZm9ybWF0LiBUaGlzIG1ldGhvZCBzaG91bGQgbm90IGJlCi0gICAgICogY2FsbGVkIHdoaWxlIHRoZSBzZXJpYWxpemVyIGlzIGluIHRoZSBwcm9jZXNzIG9mIHNlcmlhbGl6aW5nCi0gICAgICogYSBkb2N1bWVudC4KLSAgICAgKgotICAgICAqIFRoaXMgbWV0aG9kIGNhbiBiZSBjYWxsZWQgbXVsdGlwbGUgdGltZXMgYmVmb3JlIHN0YXJ0aW5nCi0gICAgICogdGhlIHNlcmlhbGl6YXRpb24gb2YgYSBwYXJ0aWN1bGFyIHJlc3VsdC10cmVlLiBJbiBwcmluY2lwbGUKLSAgICAgKiBhbGwgc2VyaWFsaXphdGlvbiBwYXJhbWV0ZXJzIGNhbiBiZSBjaGFuZ2VkLCB3aXRoIHRoZSBleGNlcHRpb24KLSAgICAgKiBvZiBtZXRob2Q9Imh0bWwiIChpdCBtdXN0IGJlIG1ldGhvZD0iaHRtbCIgb3RoZXJ3aXNlIHdlCi0gICAgICogc2hvdWxkbid0IGV2ZW4gaGF2ZSBhIFRvSFRNTFN0cmVhbSBvYmplY3QgaGVyZSEpCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZm9ybWF0IFRoZSBvdXRwdXQgZm9ybWF0IG9yIHNlcmlhbHphdGlvbiBwYXJhbWV0ZXJzCi0gICAgICogdG8gdXNlLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldE91dHB1dEZvcm1hdChQcm9wZXJ0aWVzIGZvcm1hdCkKLSAgICB7Ci0KLSAgICAgICAgbV9zcGVjaWFsRXNjYXBlVVJMcyA9Ci0gICAgICAgICAgICBPdXRwdXRQcm9wZXJ0eVV0aWxzLmdldEJvb2xlYW5Qcm9wZXJ0eSgKLSAgICAgICAgICAgICAgICBPdXRwdXRQcm9wZXJ0aWVzRmFjdG9yeS5TX1VTRV9VUkxfRVNDQVBJTkcsCi0gICAgICAgICAgICAgICAgZm9ybWF0KTsKLQotICAgICAgICBtX29taXRNZXRhVGFnID0KLSAgICAgICAgICAgIE91dHB1dFByb3BlcnR5VXRpbHMuZ2V0Qm9vbGVhblByb3BlcnR5KAotICAgICAgICAgICAgICAgIE91dHB1dFByb3BlcnRpZXNGYWN0b3J5LlNfT01JVF9NRVRBX1RBRywKLSAgICAgICAgICAgICAgICBmb3JtYXQpOwotCi0gICAgICAgIHN1cGVyLnNldE91dHB1dEZvcm1hdChmb3JtYXQpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRlbGxzIGlmIHRoZSBmb3JtYXR0ZXIgc2hvdWxkIHVzZSBzcGVjaWFsIFVSTCBlc2NhcGluZy4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVHJ1ZSBpZiBVUkxzIHNob3VsZCBiZSBzcGVjaWFsbHkgZXNjYXBlZCB3aXRoIHRoZSAleHggZm9ybS4KLSAgICAgKi8KLSAgICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gZ2V0U3BlY2lhbEVzY2FwZVVSTHMoKQotICAgIHsKLSAgICAgICAgcmV0dXJuIG1fc3BlY2lhbEVzY2FwZVVSTHM7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGVsbHMgaWYgdGhlIGZvcm1hdHRlciBzaG91bGQgb21pdCB0aGUgTUVUQSB0YWcuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRydWUgaWYgdGhlIE1FVEEgdGFnIHNob3VsZCBiZSBvbWl0dGVkLgotICAgICAqLwotICAgIHByaXZhdGUgZmluYWwgYm9vbGVhbiBnZXRPbWl0TWV0YVRhZygpCi0gICAgewotICAgICAgICByZXR1cm4gbV9vbWl0TWV0YVRhZzsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgYSBkZXNjcmlwdGlvbiBvZiB0aGUgZ2l2ZW4gZWxlbWVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lIG5vbi1udWxsIG5hbWUgb2YgZWxlbWVudCwgY2FzZSBpbnNlbnNpdGl2ZS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gbm9uLW51bGwgcmVmZXJlbmNlIHRvIEVsZW1EZXNjLCB3aGljaCBtYXkgYmUgbV9kdW1teSBpZiBubwotICAgICAqICAgICAgICAgZWxlbWVudCBkZXNjcmlwdGlvbiBtYXRjaGVzIHRoZSBnaXZlbiBuYW1lLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgRWxlbURlc2MgZ2V0RWxlbURlc2MoU3RyaW5nIG5hbWUpCi0gICAgewotICAgICAgICAvKiB0aGlzIG1ldGhvZCB1c2VkIHRvIHJldHVybiBtX2R1bW15ICB3aGVuIG5hbWUgd2FzIG51bGwKLSAgICAgICAgICogYnV0IG5vdyBpdCBkb2Vzbid0IGNoZWNrIGFuZCBhbmQgcmVxdWlyZXMgbm9uLW51bGwgbmFtZS4KLSAgICAgICAgICovCi0gICAgICAgIE9iamVjdCBvYmogPSBtX2VsZW1lbnRGbGFncy5nZXQobmFtZSk7Ci0gICAgICAgIGlmIChudWxsICE9IG9iaikKLSAgICAgICAgICAgIHJldHVybiAoRWxlbURlc2Mpb2JqOwotICAgICAgICByZXR1cm4gbV9kdW1teTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBIFRyaWUgdGhhdCBpcyBqdXN0IGEgY29weSBvZiB0aGUgInN0YXRpYyIgb25lLgotICAgICAqIFdlIG5lZWQgdGhpcyBvbmUgdG8gYmUgYWJsZSB0byB1c2UgdGhlIGZhc3RlciwgYnV0IG5vdCB0aHJlYWQtc2FmZQotICAgICAqIG1ldGhvZCBUcmllLmdldDIobmFtZSkKLSAgICAgKi8KLSAgICBwcml2YXRlIFRyaWUgbV9odG1sSW5mbyA9IG5ldyBUcmllKG1fZWxlbWVudEZsYWdzKTsKLSAgICAvKioKLSAgICAgKiBDYWxscyB0byB0aGlzIG1ldGhvZCBjb3VsZCBiZSByZXBsYWNlZCB3aXRoIGNhbGxzIHRvCi0gICAgICogZ2V0RWxlbURlc2MobmFtZSksIGJ1dCB0aGlzIG9uZSBzaG91bGQgYmUgZmFzdGVyLgotICAgICAqLwotICAgIHByaXZhdGUgRWxlbURlc2MgZ2V0RWxlbURlc2MyKFN0cmluZyBuYW1lKQotICAgIHsKLSAgICAgICAgT2JqZWN0IG9iaiA9IG1faHRtbEluZm8uZ2V0MihuYW1lKTsKLSAgICAgICAgaWYgKG51bGwgIT0gb2JqKQotICAgICAgICAgICAgcmV0dXJuIChFbGVtRGVzYylvYmo7Ci0gICAgICAgIHJldHVybiBtX2R1bW15OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIERlZmF1bHQgY29uc3RydWN0b3IuCi0gICAgICovCi0gICAgcHVibGljIFRvSFRNTFN0cmVhbSgpCi0gICAgewotCi0gICAgICAgIHN1cGVyKCk7Ci0gICAgICAgIG1fY2hhckluZm8gPSBtX2h0bWxjaGFySW5mbzsKLSAgICAgICAgLy8gaW5pdGlhbGl6ZSBuYW1lc3BhY2VzCi0gICAgICAgIG1fcHJlZml4TWFwID0gbmV3IE5hbWVzcGFjZU1hcHBpbmdzKCk7Ci0KLSAgICB9Ci0KLSAgICAvKiogVGhlIG5hbWUgb2YgdGhlIGN1cnJlbnQgZWxlbWVudC4gKi8KLS8vICAgIHByaXZhdGUgU3RyaW5nIG1fY3VycmVudEVsZW1lbnROYW1lID0gbnVsbDsKLQotICAgIC8qKgotICAgICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIHRoZSBiZWdpbm5pbmcgb2YgYSBkb2N1bWVudC4KLSAgICAgKgotICAgICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIHN0YXJ0RG9jdW1lbnRJbnRlcm5hbCgpIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIHN1cGVyLnN0YXJ0RG9jdW1lbnRJbnRlcm5hbCgpOwotCi0gICAgICAgIG1fbmVlZFRvQ2FsbFN0YXJ0RG9jdW1lbnQgPSBmYWxzZTsKLSAgICAgICAgbV9uZWVkVG9PdXRwdXREb2NUeXBlRGVjbCA9IHRydWU7Ci0gICAgICAgIG1fc3RhcnROZXdMaW5lID0gZmFsc2U7Ci0gICAgICAgIHNldE9taXRYTUxEZWNsYXJhdGlvbih0cnVlKTsKLQotICAgICAgICBpZiAodHJ1ZSA9PSBtX25lZWRUb091dHB1dERvY1R5cGVEZWNsKQotICAgICAgICB7Ci0gICAgICAgICAgICBTdHJpbmcgZG9jdHlwZVN5c3RlbSA9IGdldERvY3R5cGVTeXN0ZW0oKTsKLSAgICAgICAgICAgIFN0cmluZyBkb2N0eXBlUHVibGljID0gZ2V0RG9jdHlwZVB1YmxpYygpOwotICAgICAgICAgICAgaWYgKChudWxsICE9IGRvY3R5cGVTeXN0ZW0pIHx8IChudWxsICE9IGRvY3R5cGVQdWJsaWMpKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIGZpbmFsIGphdmEuaW8uV3JpdGVyIHdyaXRlciA9IG1fd3JpdGVyOwotICAgICAgICAgICAgICAgIHRyeQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoIjwhRE9DVFlQRSBodG1sIik7Ci0KLSAgICAgICAgICAgICAgICBpZiAobnVsbCAhPSBkb2N0eXBlUHVibGljKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKCIgUFVCTElDIFwiIik7Ci0gICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZShkb2N0eXBlUHVibGljKTsKLSAgICAgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKCciJyk7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgaWYgKG51bGwgIT0gZG9jdHlwZVN5c3RlbSkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChudWxsID09IGRvY3R5cGVQdWJsaWMpCi0gICAgICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoIiBTWVNURU0gXCIiKTsKLSAgICAgICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKCIgXCIiKTsKLQotICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoZG9jdHlwZVN5c3RlbSk7Ci0gICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZSgnIicpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZSgnPicpOwotICAgICAgICAgICAgICAgIG91dHB1dExpbmVTZXAoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgY2F0Y2goSU9FeGNlcHRpb24gZSkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgbV9uZWVkVG9PdXRwdXREb2NUeXBlRGVjbCA9IGZhbHNlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIHRoZSBlbmQgb2YgYSBkb2N1bWVudC4KLSAgICAgKgotICAgICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgICAqLwotICAgIHB1YmxpYyBmaW5hbCB2b2lkIGVuZERvY3VtZW50KCkgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgIHsKLQotICAgICAgICBmbHVzaFBlbmRpbmcoKTsKLSAgICAgICAgaWYgKG1fZG9JbmRlbnQgJiYgIW1faXNwcmV2dGV4dCkKLSAgICAgICAgewotICAgICAgICAgICAgdHJ5Ci0gICAgICAgICAgICB7Ci0gICAgICAgICAgICBvdXRwdXRMaW5lU2VwKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXRjaChJT0V4Y2VwdGlvbiBlKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBmbHVzaFdyaXRlcigpOwotICAgICAgICBpZiAobV90cmFjZXIgIT0gbnVsbCkKLSAgICAgICAgICAgIHN1cGVyLmZpcmVFbmREb2MoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiAgUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIGJlZ2lubmluZyBvZiBhbiBlbGVtZW50LgotICAgICAqCi0gICAgICoKLSAgICAgKiAgQHBhcmFtIG5hbWVzcGFjZVVSSQotICAgICAqICBAcGFyYW0gbG9jYWxOYW1lCi0gICAgICogIEBwYXJhbSBuYW1lIFRoZSBlbGVtZW50IHR5cGUgbmFtZS4KLSAgICAgKiAgQHBhcmFtIGF0dHMgVGhlIGF0dHJpYnV0ZXMgYXR0YWNoZWQgdG8gdGhlIGVsZW1lbnQsIGlmIGFueS4KLSAgICAgKiAgQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAgICogICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAgICogIEBzZWUgI2VuZEVsZW1lbnQKLSAgICAgKiAgQHNlZSBvcmcueG1sLnNheC5BdHRyaWJ1dGVMaXN0Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnRFbGVtZW50KAotICAgICAgICBTdHJpbmcgbmFtZXNwYWNlVVJJLAotICAgICAgICBTdHJpbmcgbG9jYWxOYW1lLAotICAgICAgICBTdHJpbmcgbmFtZSwKLSAgICAgICAgQXR0cmlidXRlcyBhdHRzKQotICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAgewotCi0gICAgICAgIEVsZW1Db250ZXh0IGVsZW1Db250ZXh0ID0gbV9lbGVtQ29udGV4dDsKLQotICAgICAgICAvLyBjbGVhbiB1cCBhbnkgcGVuZGluZyB0aGluZ3MgZmlyc3QKLSAgICAgICAgaWYgKGVsZW1Db250ZXh0Lm1fc3RhcnRUYWdPcGVuKQotICAgICAgICB7Ci0gICAgICAgICAgICBjbG9zZVN0YXJ0VGFnKCk7Ci0gICAgICAgICAgICBlbGVtQ29udGV4dC5tX3N0YXJ0VGFnT3BlbiA9IGZhbHNlOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKG1fY2RhdGFUYWdPcGVuKQotICAgICAgICB7Ci0gICAgICAgICAgICBjbG9zZUNEQVRBKCk7Ci0gICAgICAgICAgICBtX2NkYXRhVGFnT3BlbiA9IGZhbHNlOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKG1fbmVlZFRvQ2FsbFN0YXJ0RG9jdW1lbnQpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHN0YXJ0RG9jdW1lbnRJbnRlcm5hbCgpOwotICAgICAgICAgICAgbV9uZWVkVG9DYWxsU3RhcnREb2N1bWVudCA9IGZhbHNlOwotICAgICAgICB9Ci0KLQotICAgICAgICAvLyBpZiB0aGlzIGVsZW1lbnQgaGFzIGEgbmFtZXNwYWNlIHRoZW4gdHJlYXQgaXQgbGlrZSBYTUwKLSAgICAgICAgaWYgKG51bGwgIT0gbmFtZXNwYWNlVVJJICYmIG5hbWVzcGFjZVVSSS5sZW5ndGgoKSA+IDApCi0gICAgICAgIHsKLSAgICAgICAgICAgIHN1cGVyLnN0YXJ0RWxlbWVudChuYW1lc3BhY2VVUkksIGxvY2FsTmFtZSwgbmFtZSwgYXR0cyk7Ci0KLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotCi0gICAgICAgIHRyeQotICAgICAgICB7Ci0gICAgICAgICAgICAvLyBnZXRFbGVtRGVzYzIobmFtZSkgaXMgZmFzdGVyIHRoYW4gZ2V0RWxlbURlc2MobmFtZSkKLSAgICAgICAgICAgIEVsZW1EZXNjIGVsZW1EZXNjID0gZ2V0RWxlbURlc2MyKG5hbWUpOwotICAgICAgICAgICAgaW50IGVsZW1GbGFncyA9IGVsZW1EZXNjLmdldEZsYWdzKCk7Ci0KLSAgICAgICAgICAgIC8vIGRlYWwgd2l0aCBpbmRlbnRhdGlvbiBpc3N1ZXMgZmlyc3QKLSAgICAgICAgICAgIGlmIChtX2RvSW5kZW50KQotICAgICAgICAgICAgewotCi0gICAgICAgICAgICAgICAgYm9vbGVhbiBpc0Jsb2NrRWxlbWVudCA9IChlbGVtRmxhZ3MgJiBFbGVtRGVzYy5CTE9DSykgIT0gMDsKLSAgICAgICAgICAgICAgICBpZiAobV9pc3ByZXNlcnZlKQotICAgICAgICAgICAgICAgICAgICBtX2lzcHJlc2VydmUgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICBlbHNlIGlmICgKLSAgICAgICAgICAgICAgICAgICAgKG51bGwgIT0gZWxlbUNvbnRleHQubV9lbGVtZW50TmFtZSkKLSAgICAgICAgICAgICAgICAgICAgJiYgKCFtX2luQmxvY2tFbGVtCi0gICAgICAgICAgICAgICAgICAgICAgICB8fCBpc0Jsb2NrRWxlbWVudCkgLyogJiYgIWlzV2hpdGVTcGFjZVNlbnNpdGl2ZSAqLwotICAgICAgICAgICAgICAgICAgICApCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICBtX3N0YXJ0TmV3TGluZSA9IHRydWU7Ci0KLSAgICAgICAgICAgICAgICAgICAgaW5kZW50KCk7Ci0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgbV9pbkJsb2NrRWxlbSA9ICFpc0Jsb2NrRWxlbWVudDsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gc2F2ZSBhbnkgYXR0cmlidXRlcyBmb3IgbGF0ZXIgcHJvY2Vzc2luZwotICAgICAgICAgICAgaWYgKGF0dHMgIT0gbnVsbCkKLSAgICAgICAgICAgICAgICBhZGRBdHRyaWJ1dGVzKGF0dHMpOwotCi0gICAgICAgICAgICBtX2lzcHJldnRleHQgPSBmYWxzZTsKLSAgICAgICAgICAgIGZpbmFsIGphdmEuaW8uV3JpdGVyIHdyaXRlciA9IG1fd3JpdGVyOwotICAgICAgICAgICAgd3JpdGVyLndyaXRlKCc8Jyk7Ci0gICAgICAgICAgICB3cml0ZXIud3JpdGUobmFtZSk7Ci0KLQotCi0gICAgICAgICAgICBpZiAobV90cmFjZXIgIT0gbnVsbCkKLSAgICAgICAgICAgICAgICBmaXJlUHNldWRvQXR0cmlidXRlcygpOwotCi0gICAgICAgICAgICBpZiAoKGVsZW1GbGFncyAmIEVsZW1EZXNjLkVNUFRZKSAhPSAwKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIC8vIGFuIG9wdGltaXphdGlvbiBmb3IgZWxlbWVudHMgd2hpY2ggYXJlIGV4cGVjdGVkCi0gICAgICAgICAgICAgICAgLy8gdG8gYmUgZW1wdHkuCi0gICAgICAgICAgICAgICAgbV9lbGVtQ29udGV4dCA9IGVsZW1Db250ZXh0LnB1c2goKTsKLSAgICAgICAgICAgICAgICAvKiBYU0xUQyBzb21ldGltZXMgY2FsbHMgbmFtZXNwYWNlQWZ0ZXJTdGFydEVsZW1lbnQoKQotICAgICAgICAgICAgICAgICAqIHNvIHdlIG5lZWQgdG8gcmVtZW1iZXIgdGhlIG5hbWUKLSAgICAgICAgICAgICAgICAgKi8KLSAgICAgICAgICAgICAgICBtX2VsZW1Db250ZXh0Lm1fZWxlbWVudE5hbWUgPSBuYW1lOwotICAgICAgICAgICAgICAgIG1fZWxlbUNvbnRleHQubV9lbGVtZW50RGVzYyA9IGVsZW1EZXNjOwotICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBlbGVtQ29udGV4dCA9IGVsZW1Db250ZXh0LnB1c2gobmFtZXNwYWNlVVJJLGxvY2FsTmFtZSxuYW1lKTsKLSAgICAgICAgICAgICAgICBtX2VsZW1Db250ZXh0ID0gZWxlbUNvbnRleHQ7Ci0gICAgICAgICAgICAgICAgZWxlbUNvbnRleHQubV9lbGVtZW50RGVzYyA9IGVsZW1EZXNjOwotICAgICAgICAgICAgICAgIGVsZW1Db250ZXh0Lm1faXNSYXcgPSAoZWxlbUZsYWdzICYgRWxlbURlc2MuUkFXKSAhPSAwOwotICAgICAgICAgICAgfQotCi0KLSAgICAgICAgICAgIGlmICgoZWxlbUZsYWdzICYgRWxlbURlc2MuSEVBREVMRU0pICE9IDApCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgLy8gVGhpcyBpcyB0aGUgPEhFQUQ+IGVsZW1lbnQsIGRvIHNvbWUgc3BlY2lhbCBwcm9jZXNzaW5nCi0gICAgICAgICAgICAgICAgY2xvc2VTdGFydFRhZygpOwotICAgICAgICAgICAgICAgIGVsZW1Db250ZXh0Lm1fc3RhcnRUYWdPcGVuID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgaWYgKCFtX29taXRNZXRhVGFnKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKG1fZG9JbmRlbnQpCi0gICAgICAgICAgICAgICAgICAgICAgICBpbmRlbnQoKTsKLSAgICAgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKAotICAgICAgICAgICAgICAgICAgICAgICAgIjxNRVRBIGh0dHAtZXF1aXY9XCJDb250ZW50LVR5cGVcIiBjb250ZW50PVwidGV4dC9odG1sOyBjaGFyc2V0PSIpOwotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgZW5jb2RpbmcgPSBnZXRFbmNvZGluZygpOwotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgZW5jb2RlID0gRW5jb2RpbmdzLmdldE1pbWVFbmNvZGluZyhlbmNvZGluZyk7Ci0gICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZShlbmNvZGUpOwotICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoIlwiPiIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoSU9FeGNlcHRpb24gZSkKLSAgICAgICAgewotICAgICAgICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbihlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqICBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiB0aGUgZW5kIG9mIGFuIGVsZW1lbnQuCi0gICAgICoKLSAgICAgKgotICAgICAqICBAcGFyYW0gbmFtZXNwYWNlVVJJCi0gICAgICogIEBwYXJhbSBsb2NhbE5hbWUKLSAgICAgKiAgQHBhcmFtIG5hbWUgVGhlIGVsZW1lbnQgdHlwZSBuYW1lCi0gICAgICogIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgICAqICAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBmaW5hbCB2b2lkIGVuZEVsZW1lbnQoCi0gICAgICAgIGZpbmFsIFN0cmluZyBuYW1lc3BhY2VVUkksCi0gICAgICAgIGZpbmFsIFN0cmluZyBsb2NhbE5hbWUsCi0gICAgICAgIGZpbmFsIFN0cmluZyBuYW1lKQotICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICAvLyBkZWFsIHdpdGggYW55IHBlbmRpbmcgaXNzdWVzCi0gICAgICAgIGlmIChtX2NkYXRhVGFnT3BlbikKLSAgICAgICAgICAgIGNsb3NlQ0RBVEEoKTsKLQotICAgICAgICAvLyBpZiB0aGUgZWxlbWVudCBoYXMgYSBuYW1lc3BhY2UsIHRyZWF0IGl0IGxpa2UgWE1MLCBub3QgSFRNTAotICAgICAgICBpZiAobnVsbCAhPSBuYW1lc3BhY2VVUkkgJiYgbmFtZXNwYWNlVVJJLmxlbmd0aCgpID4gMCkKLSAgICAgICAgewotICAgICAgICAgICAgc3VwZXIuZW5kRWxlbWVudChuYW1lc3BhY2VVUkksIGxvY2FsTmFtZSwgbmFtZSk7Ci0KLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotCi0gICAgICAgIHRyeQotICAgICAgICB7Ci0KLSAgICAgICAgICAgIEVsZW1Db250ZXh0IGVsZW1Db250ZXh0ID0gbV9lbGVtQ29udGV4dDsKLSAgICAgICAgICAgIGZpbmFsIEVsZW1EZXNjIGVsZW1EZXNjID0gZWxlbUNvbnRleHQubV9lbGVtZW50RGVzYzsKLSAgICAgICAgICAgIGZpbmFsIGludCBlbGVtRmxhZ3MgPSBlbGVtRGVzYy5nZXRGbGFncygpOwotICAgICAgICAgICAgZmluYWwgYm9vbGVhbiBlbGVtRW1wdHkgPSAoZWxlbUZsYWdzICYgRWxlbURlc2MuRU1QVFkpICE9IDA7Ci0KLSAgICAgICAgICAgIC8vIGRlYWwgd2l0aCBhbnkgaW5kZW50YXRpb24gaXNzdWVzCi0gICAgICAgICAgICBpZiAobV9kb0luZGVudCkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBmaW5hbCBib29sZWFuIGlzQmxvY2tFbGVtZW50ID0gKGVsZW1GbGFncyZFbGVtRGVzYy5CTE9DSykgIT0gMDsKLSAgICAgICAgICAgICAgICBib29sZWFuIHNob3VsZEluZGVudCA9IGZhbHNlOwotCi0gICAgICAgICAgICAgICAgaWYgKG1faXNwcmVzZXJ2ZSkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIG1faXNwcmVzZXJ2ZSA9IGZhbHNlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIGlmIChtX2RvSW5kZW50ICYmICghbV9pbkJsb2NrRWxlbSB8fCBpc0Jsb2NrRWxlbWVudCkpCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICBtX3N0YXJ0TmV3TGluZSA9IHRydWU7Ci0gICAgICAgICAgICAgICAgICAgIHNob3VsZEluZGVudCA9IHRydWU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGlmICghZWxlbUNvbnRleHQubV9zdGFydFRhZ09wZW4gJiYgc2hvdWxkSW5kZW50KQotICAgICAgICAgICAgICAgICAgICBpbmRlbnQoZWxlbUNvbnRleHQubV9jdXJyZW50RWxlbURlcHRoIC0gMSk7Ci0gICAgICAgICAgICAgICAgbV9pbkJsb2NrRWxlbSA9ICFpc0Jsb2NrRWxlbWVudDsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgZmluYWwgamF2YS5pby5Xcml0ZXIgd3JpdGVyID0gbV93cml0ZXI7Ci0gICAgICAgICAgICBpZiAoIWVsZW1Db250ZXh0Lm1fc3RhcnRUYWdPcGVuKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZSgiPC8iKTsKLSAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUobmFtZSk7Ci0gICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKCc+Jyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgLy8gdGhlIHN0YXJ0LXRhZyBvcGVuIHdoZW4gdGhpcyBtZXRob2Qgd2FzIGNhbGxlZCwKLSAgICAgICAgICAgICAgICAvLyBzbyB3ZSBuZWVkIHRvIHByb2Nlc3MgaXQgbm93LgotCi0gICAgICAgICAgICAgICAgaWYgKG1fdHJhY2VyICE9IG51bGwpCi0gICAgICAgICAgICAgICAgICAgIHN1cGVyLmZpcmVTdGFydEVsZW0obmFtZSk7Ci0KLSAgICAgICAgICAgICAgICAvLyB0aGUgc3RhcnRpbmcgdGFnIHdhcyBzdGlsbCBvcGVuIHdoZW4gd2UgcmVjZWl2ZWQgdGhpcyBlbmRFbGVtZW50KCkgY2FsbAotICAgICAgICAgICAgICAgIC8vIHNvIHdlIG5lZWQgdG8gcHJvY2VzcyBhbnkgZ2F0aGVyZWQgYXR0cmlidXRlcyBOT1csIGJlZm9yZSB0aGV5IGdvIGF3YXkuCi0gICAgICAgICAgICAgICAgaW50IG5BdHRycyA9IG1fYXR0cmlidXRlcy5nZXRMZW5ndGgoKTsKLSAgICAgICAgICAgICAgICBpZiAobkF0dHJzID4gMCkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIHByb2Nlc3NBdHRyaWJ1dGVzKG1fd3JpdGVyLCBuQXR0cnMpOwotICAgICAgICAgICAgICAgICAgICAvLyBjbGVhciBhdHRyaWJ1dGVzIG9iamVjdCBmb3IgcmUtdXNlIHdpdGggbmV4dCBlbGVtZW50Ci0gICAgICAgICAgICAgICAgICAgIG1fYXR0cmlidXRlcy5jbGVhcigpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpZiAoIWVsZW1FbXB0eSkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIEFzIHBlciBEYXZlL1BhdWwgcmVjb21tZW5kYXRpb24gMTIvMDYvMjAwMAotICAgICAgICAgICAgICAgICAgICAvLyBpZiAoc2hvdWxkSW5kZW50KQotICAgICAgICAgICAgICAgICAgICAvLyB3cml0ZXIud3JpdGUoJz4nKTsKLSAgICAgICAgICAgICAgICAgICAgLy8gIGluZGVudChtX2N1cnJlbnRJbmRlbnQpOwotCi0gICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZSgiPjwvIik7Ci0gICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZShuYW1lKTsKLSAgICAgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKCc+Jyk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZSgnPicpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gY2xlYW4gdXAgYmVjYXVzZSB0aGUgZWxlbWVudCBoYXMgZW5kZWQKLSAgICAgICAgICAgIGlmICgoZWxlbUZsYWdzICYgRWxlbURlc2MuV0hJVEVTUEFDRVNFTlNJVElWRSkgIT0gMCkKLSAgICAgICAgICAgICAgICBtX2lzcHJlc2VydmUgPSB0cnVlOwotICAgICAgICAgICAgbV9pc3ByZXZ0ZXh0ID0gZmFsc2U7Ci0KLSAgICAgICAgICAgIC8vIGZpcmUgb2ZmIHRoZSBlbmQgZWxlbWVudCBldmVudAotICAgICAgICAgICAgaWYgKG1fdHJhY2VyICE9IG51bGwpCi0gICAgICAgICAgICAgICAgc3VwZXIuZmlyZUVuZEVsZW0obmFtZSk7Ci0KLSAgICAgICAgICAgIC8vIE9QVElNSVpFLUVNUFRZCi0gICAgICAgICAgICBpZiAoZWxlbUVtcHR5KQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIC8vIGEgcXVpY2sgZXhpdCBpZiB0aGUgSFRNTCBlbGVtZW50IGhhZCBubyBjaGlsZHJlbi4KLSAgICAgICAgICAgICAgICAvLyBUaGlzIGJsb2NrIG9mIGNvZGUgY2FuIGJlIHJlbW92ZWQgaWYgdGhlIGNvcnJlc3BvbmRpbmcgYmxvY2sgb2YgY29kZQotICAgICAgICAgICAgICAgIC8vIGluIHN0YXJ0RWxlbWVudCgpIGFsc28gbGFiZWxlZCB3aXRoICJPUFRJTUlaRS1FTVBUWSIgaXMgYWxzbyByZW1vdmVkCi0gICAgICAgICAgICAgICAgbV9lbGVtQ29udGV4dCA9IGVsZW1Db250ZXh0Lm1fcHJldjsKLSAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIHNvbWUgbW9yZSBjbGVhbiBiZWNhdXNlIHRoZSBlbGVtZW50IGhhcyBlbmRlZC4KLSAgICAgICAgICAgIGlmICghZWxlbUNvbnRleHQubV9zdGFydFRhZ09wZW4pCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgaWYgKG1fZG9JbmRlbnQgJiYgIW1fcHJlc2VydmVzLmlzRW1wdHkoKSkKLSAgICAgICAgICAgICAgICAgICAgbV9wcmVzZXJ2ZXMucG9wKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBtX2VsZW1Db250ZXh0ID0gZWxlbUNvbnRleHQubV9wcmV2OwotLy8gICAgICAgICAgICBtX2lzUmF3U3RhY2sucG9wKCk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKElPRXhjZXB0aW9uIGUpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBQcm9jZXNzIGFuIGF0dHJpYnV0ZS4KLSAgICAgKiBAcGFyYW0gICB3cml0ZXIgVGhlIHdyaXRlciB0byB3cml0ZSB0aGUgcHJvY2Vzc2VkIG91dHB1dCB0by4KLSAgICAgKiBAcGFyYW0gICBuYW1lICAgVGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgKiBAcGFyYW0gICB2YWx1ZSAgIFRoZSB2YWx1ZSBvZiB0aGUgYXR0cmlidXRlLgotICAgICAqIEBwYXJhbSAgIGVsZW1EZXNjIFRoZSBkZXNjcmlwdGlvbiBvZiB0aGUgSFRNTCBlbGVtZW50Ci0gICAgICogICAgICAgICAgIHRoYXQgaGFzIHRoaXMgYXR0cmlidXRlLgotICAgICAqCi0gICAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCBwcm9jZXNzQXR0cmlidXRlKAotICAgICAgICBqYXZhLmlvLldyaXRlciB3cml0ZXIsCi0gICAgICAgIFN0cmluZyBuYW1lLAotICAgICAgICBTdHJpbmcgdmFsdWUsCi0gICAgICAgIEVsZW1EZXNjIGVsZW1EZXNjKQotICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIHdyaXRlci53cml0ZSgnICcpOwotCi0gICAgICAgIGlmICggICAoKHZhbHVlLmxlbmd0aCgpID09IDApIHx8IHZhbHVlLmVxdWFsc0lnbm9yZUNhc2UobmFtZSkpCi0gICAgICAgICAgICAmJiBlbGVtRGVzYyAhPSBudWxsCi0gICAgICAgICAgICAmJiBlbGVtRGVzYy5pc0F0dHJGbGFnU2V0KG5hbWUsIEVsZW1EZXNjLkFUVFJFTVBUWSkpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHdyaXRlci53cml0ZShuYW1lKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgIHsKLSAgICAgICAgICAgIC8vICVSRVZJRVclICVPUFQlCi0gICAgICAgICAgICAvLyBUd28gY2FsbHMgdG8gc2luZ2xlLWNoYXIgd3JpdGUgbWF5IE5PVAotICAgICAgICAgICAgLy8gYmUgbW9yZSBlZmZpY2llbnQgdGhhbiBvbmUgdG8gc3RyaW5nLXdyaXRlLi4uCi0gICAgICAgICAgICB3cml0ZXIud3JpdGUobmFtZSk7Ci0gICAgICAgICAgICB3cml0ZXIud3JpdGUoIj1cIiIpOwotICAgICAgICAgICAgaWYgKCAgIGVsZW1EZXNjICE9IG51bGwKLSAgICAgICAgICAgICAgICAmJiBlbGVtRGVzYy5pc0F0dHJGbGFnU2V0KG5hbWUsIEVsZW1EZXNjLkFUVFJVUkwpKQotICAgICAgICAgICAgICAgIHdyaXRlQXR0clVSSSh3cml0ZXIsIHZhbHVlLCBtX3NwZWNpYWxFc2NhcGVVUkxzKTsKLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICB3cml0ZUF0dHJTdHJpbmcod3JpdGVyLCB2YWx1ZSwgdGhpcy5nZXRFbmNvZGluZygpKTsKLSAgICAgICAgICAgIHdyaXRlci53cml0ZSgnIicpOwotCi0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUZWxsIGlmIGEgY2hhcmFjdGVyIGlzIGFuIEFTQ0lJIGRpZ2l0LgotICAgICAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBpc0FTQ0lJRGlnaXQoY2hhciBjKQotICAgIHsKLSAgICAgICAgcmV0dXJuIChjID49ICcwJyAmJiBjIDw9ICc5Jyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogTWFrZSBhbiBpbnRlZ2VyIGludG8gYW4gSEggaGV4IHZhbHVlLgotICAgICAqIERvZXMgbm8gY2hlY2tpbmcgb24gdGhlIHNpemUgb2YgdGhlIGlucHV0LCBzaW5jZSB0aGlzCi0gICAgICogaXMgb25seSBtZWFudCB0byBiZSB1c2VkIGxvY2FsbHkgYnkgd3JpdGVBdHRyVVJJLgotICAgICAqCi0gICAgICogQHBhcmFtIGkgbXVzdCBiZSBhIHZhbHVlIGxlc3MgdGhhbiAyNTUuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHNob3VsZCBiZSBhIHR3byBjaGFyYWN0ZXIgc3RyaW5nLgotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBtYWtlSEhTdHJpbmcoaW50IGkpCi0gICAgewotICAgICAgICBTdHJpbmcgcyA9IEludGVnZXIudG9IZXhTdHJpbmcoaSkudG9VcHBlckNhc2UoKTsKLSAgICAgICAgaWYgKHMubGVuZ3RoKCkgPT0gMSkKLSAgICAgICAgewotICAgICAgICAgICAgcyA9ICIwIiArIHM7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHM7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgKiBEbWl0cmkgSWx5aW46IE1ha2VzIHN1cmUgaWYgdGhlIFN0cmluZyBpcyBISCBlbmNvZGVkIHNpZ24uCi0gICAgKiBAcGFyYW0gc3RyIG11c3QgYmUgMiBjaGFyYWN0ZXJzIGxvbmcKLSAgICAqCi0gICAgKiBAcmV0dXJuIHRydWUgb3IgZmFsc2UKLSAgICAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBpc0hIU2lnbihTdHJpbmcgc3RyKQotICAgIHsKLSAgICAgICAgYm9vbGVhbiBzaWduID0gdHJ1ZTsKLSAgICAgICAgdHJ5Ci0gICAgICAgIHsKLSAgICAgICAgICAgIGNoYXIgciA9IChjaGFyKSBJbnRlZ2VyLnBhcnNlSW50KHN0ciwgMTYpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZSkKLSAgICAgICAgewotICAgICAgICAgICAgc2lnbiA9IGZhbHNlOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBzaWduOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFdyaXRlIHRoZSBzcGVjaWZpZWQgPHZhcj5zdHJpbmc8L3Zhcj4gYWZ0ZXIgc3Vic3RpdHV0aW5nIG5vbiBBU0NJSSBjaGFyYWN0ZXJzLAotICAgICAqIHdpdGggPENPREU+JUhIPC9DT0RFPiwgd2hlcmUgSEggaXMgdGhlIGhleCBvZiB0aGUgYnl0ZSB2YWx1ZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSAgIHN0cmluZyAgICAgIFN0cmluZyB0byBjb252ZXJ0IHRvIFhNTCBmb3JtYXQuCi0gICAgICogQHBhcmFtIGRvVVJMRXNjYXBpbmcgVHJ1ZSBpZiB3ZSBzaG91bGQgdHJ5IHRvIGVuY29kZSBhcwotICAgICAqICAgICAgICAgICAgICAgICAgICAgIHBlciBodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyMzk2LnR4dC4KLSAgICAgKgotICAgICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIGlmIGEgYmFkIHN1cnJvZ2F0ZSBwYWlyIGlzIGRldGVjdGVkLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHdyaXRlQXR0clVSSSgKLSAgICAgICAgZmluYWwgamF2YS5pby5Xcml0ZXIgd3JpdGVyLCBTdHJpbmcgc3RyaW5nLCBib29sZWFuIGRvVVJMRXNjYXBpbmcpCi0gICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgLy8gaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjM5Ni50eHQgc2F5czoKLSAgICAgICAgLy8gQSBVUkkgaXMgYWx3YXlzIGluIGFuICJlc2NhcGVkIiBmb3JtLCBzaW5jZSBlc2NhcGluZyBvciB1bmVzY2FwaW5nIGEKLSAgICAgICAgLy8gY29tcGxldGVkIFVSSSBtaWdodCBjaGFuZ2UgaXRzIHNlbWFudGljcy4gIE5vcm1hbGx5LCB0aGUgb25seSB0aW1lCi0gICAgICAgIC8vIGVzY2FwZSBlbmNvZGluZ3MgY2FuIHNhZmVseSBiZSBtYWRlIGlzIHdoZW4gdGhlIFVSSSBpcyBiZWluZyBjcmVhdGVkCi0gICAgICAgIC8vIGZyb20gaXRzIGNvbXBvbmVudCBwYXJ0czsgZWFjaCBjb21wb25lbnQgbWF5IGhhdmUgaXRzIG93biBzZXQgb2YKLSAgICAgICAgLy8gY2hhcmFjdGVycyB0aGF0IGFyZSByZXNlcnZlZCwgc28gb25seSB0aGUgbWVjaGFuaXNtIHJlc3BvbnNpYmxlIGZvcgotICAgICAgICAvLyBnZW5lcmF0aW5nIG9yIGludGVycHJldGluZyB0aGF0IGNvbXBvbmVudCBjYW4gZGV0ZXJtaW5lIHdoZXRoZXIgb3IKLSAgICAgICAgLy8gbm90IGVzY2FwaW5nIGEgY2hhcmFjdGVyIHdpbGwgY2hhbmdlIGl0cyBzZW1hbnRpY3MuIExpa2V3aXNlLCBhIFVSSQotICAgICAgICAvLyBtdXN0IGJlIHNlcGFyYXRlZCBpbnRvIGl0cyBjb21wb25lbnRzIGJlZm9yZSB0aGUgZXNjYXBlZCBjaGFyYWN0ZXJzCi0gICAgICAgIC8vIHdpdGhpbiB0aG9zZSBjb21wb25lbnRzIGNhbiBiZSBzYWZlbHkgZGVjb2RlZC4KLSAgICAgICAgLy8KLSAgICAgICAgLy8gLi4uU28gd2UgZG8gb3VyIGJlc3QgdG8gZG8gbGltaXRlZCBlc2NhcGluZyBvZiB0aGUgVVJMLCB3aXRob3V0Ci0gICAgICAgIC8vIGNhdXNpbmcgZGFtYWdlLiAgSWYgdGhlIFVSTCBpcyBhbHJlYWR5IHByb3Blcmx5IGVzY2FwZWQsIGluIHRoZW9yeSwgdGhpcwotICAgICAgICAvLyBmdW5jdGlvbiBzaG91bGQgbm90IGNoYW5nZSB0aGUgc3RyaW5nIHZhbHVlLgotCi0gICAgICAgIGZpbmFsIGludCBlbmQgPSBzdHJpbmcubGVuZ3RoKCk7Ci0gICAgICAgIGlmIChlbmQgPiBtX2F0dHJCdWZmLmxlbmd0aCkKLSAgICAgICAgewotICAgICAgICAgICBtX2F0dHJCdWZmID0gbmV3IGNoYXJbZW5kKjIgKyAxXTsKLSAgICAgICAgfQotICAgICAgICBzdHJpbmcuZ2V0Q2hhcnMoMCxlbmQsIG1fYXR0ckJ1ZmYsIDApOwotICAgICAgICBmaW5hbCBjaGFyW10gY2hhcnMgPSBtX2F0dHJCdWZmOwotCi0gICAgICAgIGludCBjbGVhblN0YXJ0ID0gMDsKLSAgICAgICAgaW50IGNsZWFuTGVuZ3RoID0gMDsKLQotCi0gICAgICAgIGNoYXIgY2ggPSAwOwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGVuZDsgaSsrKQotICAgICAgICB7Ci0gICAgICAgICAgICBjaCA9IGNoYXJzW2ldOwotCi0gICAgICAgICAgICBpZiAoKGNoIDwgMzIpIHx8IChjaCA+IDEyNikpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgaWYgKGNsZWFuTGVuZ3RoID4gMCkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZShjaGFycywgY2xlYW5TdGFydCwgY2xlYW5MZW5ndGgpOwotICAgICAgICAgICAgICAgICAgICBjbGVhbkxlbmd0aCA9IDA7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGlmIChkb1VSTEVzY2FwaW5nKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gRW5jb2RlIFVURjE2IHRvIFVURjguCi0gICAgICAgICAgICAgICAgICAgIC8vIFJlZmVyZW5jZSBpcyBVbmljb2RlLCBBIFByaW1lciwgYnkgVG9ueSBHcmFoYW0uCi0gICAgICAgICAgICAgICAgICAgIC8vIFBhZ2UgOTIuCi0KLSAgICAgICAgICAgICAgICAgICAgLy8gTm90ZSB0aGF0IEtheSBkb2Vzbid0IGVzY2FwZSAweDIwLi4uCi0gICAgICAgICAgICAgICAgICAgIC8vICBpZihjaCA9PSAweDIwKSAvLyBOb3Qgc3VyZSBhYm91dCB0aGlzLi4uIC1zYgotICAgICAgICAgICAgICAgICAgICAvLyAgewotICAgICAgICAgICAgICAgICAgICAvLyAgICB3cml0ZXIud3JpdGUoY2gpOwotICAgICAgICAgICAgICAgICAgICAvLyAgfQotICAgICAgICAgICAgICAgICAgICAvLyAgZWxzZQotICAgICAgICAgICAgICAgICAgICBpZiAoY2ggPD0gMHg3RikKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKCclJyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUobWFrZUhIU3RyaW5nKGNoKSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoY2ggPD0gMHg3RkYpCi0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIENsZWFyIGxvdyA2IGJpdHMgYmVmb3JlIHJvdGF0ZSwgcHV0IGhpZ2ggNCBiaXRzIGluIGxvdyBieXRlLAotICAgICAgICAgICAgICAgICAgICAgICAgLy8gYW5kIHNldCB0d28gaGlnaCBiaXRzLgotICAgICAgICAgICAgICAgICAgICAgICAgaW50IGhpZ2ggPSAoY2ggPj4gNikgfCAweEMwOwotICAgICAgICAgICAgICAgICAgICAgICAgaW50IGxvdyA9IChjaCAmIDB4M0YpIHwgMHg4MDsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIEZpcnN0IDYgYml0cywgKyBoaWdoIGJpdAotICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKCclJyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUobWFrZUhIU3RyaW5nKGhpZ2gpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZSgnJScpOwotICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKG1ha2VISFN0cmluZyhsb3cpKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChFbmNvZGluZ3MuaXNIaWdoVVRGMTZTdXJyb2dhdGUoY2gpKSAvLyBoaWdoIHN1cnJvZ2F0ZQotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBJJ20gc3VyZSB0aGlzIGNhbiBiZSBkb25lIGluIDMgaW5zdHJ1Y3Rpb25zLCBidXQgSSBjaG9vc2UKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRvIHRyeSBhbmQgZG8gaXQgZXhhY3RseSBsaWtlIGl0IGlzIGRvbmUgaW4gdGhlIGJvb2ssIGF0IGxlYXN0Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyB1bnRpbCB3ZSBhcmUgc3VyZSB0aGlzIGlzIHRvdGFsbHkgY2xlYW4uICBJIGRvbid0IHRoaW5rIHBlcmZvcm1hbmNlCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBpcyBhIGJpZyBpc3N1ZSB3aXRoIHRoaXMgcGFydGljdWxhciBmdW5jdGlvbiwgdGhvdWdoIEkgY291bGQgYmUKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIHdyb25nLiAgQWxzbywgdGhlIHN0dWZmIGJlbG93IGNsZWFybHkgZG9lcyBtb3JlIG1hc2tpbmcgdGhhbgotICAgICAgICAgICAgICAgICAgICAgICAgLy8gaXQgbmVlZHMgdG8gZG8uCi0KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIENsZWFyIGhpZ2ggNiBiaXRzLgotICAgICAgICAgICAgICAgICAgICAgICAgaW50IGhpZ2hTdXJyb2dhdGUgPSAoKGludCkgY2gpICYgMHgwM0ZGOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBNaWRkbGUgNCBiaXRzICh3d3d3KSArIDEKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vICJOb3RlIHRoYXQgdGhlIHZhbHVlIG9mIHd3d3cgZnJvbSB0aGUgaGlnaCBzdXJyb2dhdGUgYml0IHBhdHRlcm4KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlzIGluY3JlbWVudGVkIHRvIG1ha2UgdGhlIHV1dXV1IGJpdCBwYXR0ZXJuIGluIHRoZSBzY2FsYXIgdmFsdWUKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNvIHRoZSBzdXJyb2dhdGUgcGFpciBkb24ndCBhZGRyZXNzIHRoZSBCTVAuIgotICAgICAgICAgICAgICAgICAgICAgICAgaW50IHd3d3cgPSAoKGhpZ2hTdXJyb2dhdGUgJiAweDAzQzApID4+IDYpOwotICAgICAgICAgICAgICAgICAgICAgICAgaW50IHV1dXV1ID0gd3d3dyArIDE7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIG5leHQgNCBiaXRzCi0gICAgICAgICAgICAgICAgICAgICAgICBpbnQgenp6eiA9IChoaWdoU3Vycm9nYXRlICYgMHgwMDNDKSA+PiAyOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBsb3cgMiBiaXRzCi0gICAgICAgICAgICAgICAgICAgICAgICBpbnQgeXl5eXl5ID0gKChoaWdoU3Vycm9nYXRlICYgMHgwMDAzKSA8PCA0KSAmIDB4MzA7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIEdldCBsb3cgc3Vycm9nYXRlIGNoYXJhY3Rlci4KLSAgICAgICAgICAgICAgICAgICAgICAgIGNoID0gY2hhcnNbKytpXTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ2xlYXIgaGlnaCA2IGJpdHMuCi0gICAgICAgICAgICAgICAgICAgICAgICBpbnQgbG93U3Vycm9nYXRlID0gKChpbnQpIGNoKSAmIDB4MDNGRjsKLQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gcHV0IHRoZSBtaWRkbGUgNCBiaXRzIGludG8gdGhlIGJvdHRvbSBvZiB5eXl5eXkgKGJ5dGUgMykKLSAgICAgICAgICAgICAgICAgICAgICAgIHl5eXl5eSA9IHl5eXl5eSB8ICgobG93U3Vycm9nYXRlICYgMHgwM0MwKSA+PiA2KTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gYm90dG9tIDYgYml0cy4KLSAgICAgICAgICAgICAgICAgICAgICAgIGludCB4eHh4eHggPSAobG93U3Vycm9nYXRlICYgMHgwMDNGKTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgaW50IGJ5dGUxID0gMHhGMCB8ICh1dXV1dSA+PiAyKTsgLy8gdG9wIDMgYml0cyBvZiB1dXV1dQotICAgICAgICAgICAgICAgICAgICAgICAgaW50IGJ5dGUyID0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDgwIHwgKCgodXV1dXUgJiAweDAzKSA8PCA0KSAmIDB4MzApIHwgenp6ejsKLSAgICAgICAgICAgICAgICAgICAgICAgIGludCBieXRlMyA9IDB4ODAgfCB5eXl5eXk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpbnQgYnl0ZTQgPSAweDgwIHwgeHh4eHh4OwotCi0gICAgICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoJyUnKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZShtYWtlSEhTdHJpbmcoYnl0ZTEpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZSgnJScpOwotICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKG1ha2VISFN0cmluZyhieXRlMikpOwotICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKCclJyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUobWFrZUhIU3RyaW5nKGJ5dGUzKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoJyUnKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZShtYWtlSEhTdHJpbmcoYnl0ZTQpKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGludCBoaWdoID0gKGNoID4+IDEyKSB8IDB4RTA7IC8vIHRvcCA0IGJpdHMKLSAgICAgICAgICAgICAgICAgICAgICAgIGludCBtaWRkbGUgPSAoKGNoICYgMHgwRkMwKSA+PiA2KSB8IDB4ODA7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBtaWRkbGUgNiBiaXRzCi0gICAgICAgICAgICAgICAgICAgICAgICBpbnQgbG93ID0gKGNoICYgMHgzRikgfCAweDgwOwotICAgICAgICAgICAgICAgICAgICAgICAgLy8gRmlyc3QgNiBiaXRzLCArIGhpZ2ggYml0Ci0gICAgICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoJyUnKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZShtYWtlSEhTdHJpbmcoaGlnaCkpOwotICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKCclJyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUobWFrZUhIU3RyaW5nKG1pZGRsZSkpOwotICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKCclJyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUobWFrZUhIU3RyaW5nKGxvdykpOwotICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSBpZiAoZXNjYXBpbmdOb3ROZWVkZWQoY2gpKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKGNoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKCImIyIpOwotICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoSW50ZWdlci50b1N0cmluZyhjaCkpOwotICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoJzsnKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLy8gSW4gdGhpcyBjaGFyYWN0ZXIgcmFuZ2Ugd2UgaGF2ZSBmaXJzdCB3cml0dGVuIG91dCBhbnkgcHJldmlvdXNseSBhY2N1bXVsYXRlZAotICAgICAgICAgICAgICAgIC8vICJjbGVhbiIgY2hhcmFjdGVycywgdGhlbiBwcm9jZXNzZWQgdGhlIGN1cnJlbnQgbW9yZSBjb21wbGljYXRlZCBjaGFyYWN0ZXIsCi0gICAgICAgICAgICAgICAgLy8gd2hpY2ggbWF5IGhhdmUgaW5jcmVtZW50ZWQgImkiLgotICAgICAgICAgICAgICAgIC8vIFdlIG5vdyB3ZSByZXNldCB0aGUgbmV4dCBwb3NzaWJsZSBjbGVhbiBjaGFyYWN0ZXIuCi0gICAgICAgICAgICAgICAgY2xlYW5TdGFydCA9IGkgKyAxOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gU2luY2UgaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjM5Ni50eHQgcmVmZXJzIHRvIHRoZSBVUkkgZ3JhbW1hciBhcwotICAgICAgICAgICAgLy8gbm90IGFsbG93aW5nIHF1b3RlcyBpbiB0aGUgVVJJIHByb3BlciBzeW50YXgsIG5vciBpbiB0aGUgZnJhZ21lbnQKLSAgICAgICAgICAgIC8vIGlkZW50aWZpZXIsIHdlIGJlbGlldmUgdGhhdCBpdCdzIE9LIHRvIGRvdWJsZSBlc2NhcGUgcXVvdGVzLgotICAgICAgICAgICAgZWxzZSBpZiAoY2ggPT0gJyInKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIC8vIElmIHRoZSBjaGFyYWN0ZXIgaXMgYSAnJScgbnVtYmVyIG51bWJlciwgdHJ5IHRvIGF2b2lkIGRvdWJsZS1lc2NhcGluZy4KLSAgICAgICAgICAgICAgICAvLyBUaGVyZSBpcyBhIHF1ZXN0aW9uIGlmIHRoaXMgaXMgbGVnYWwgYmVoYXZpb3IuCi0KLSAgICAgICAgICAgICAgICAvLyBEbWl0cmkgSWx5aW46IHRvIGNoZWNrIGlmICclJyBudW1iZXIgbnVtYmVyIGlzIGludmFsaWQuIEl0IG11c3QgYmUgY2hlY2tlZCBpZiAleHggaXMgYSBzaWduLCB0aGF0IHdvdWxkIGJlIGVuY29kZWQKLSAgICAgICAgICAgICAgICAvLyBUaGUgZW5jb2RlZCBzaWduZXMgYXJlIGluIEhleCBmb3JtLiBTbyAleHggbXkgYmUgaW4gZm9ybSAlM0MgdGhhdCBpcyAiPCIgc2lnbi4gSSB3aWxsIHRyeSB0byBjaGFuZ2UgaGVyZSBhIGxpdHRsZS4KLQotICAgICAgICAgICAgICAgIC8vICAgICAgICBpZiggKChpKzIpIDwgbGVuKSAmJiBpc0FTQ0lJRGlnaXQoc3RyaW5nQXJyYXlbaSsxXSkgJiYgaXNBU0NJSURpZ2l0KHN0cmluZ0FycmF5W2krMl0pICkKLQotICAgICAgICAgICAgICAgIC8vIFdlIGFyZSBubyBsb25nZXIgZXNjYXBpbmcgJyUnCi0KLSAgICAgICAgICAgICAgICBpZiAoY2xlYW5MZW5ndGggPiAwKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKGNoYXJzLCBjbGVhblN0YXJ0LCBjbGVhbkxlbmd0aCk7Ci0gICAgICAgICAgICAgICAgICAgIGNsZWFuTGVuZ3RoID0gMDsKLSAgICAgICAgICAgICAgICB9Ci0KLQotICAgICAgICAgICAgICAgIC8vIE1pa2UgS2F5IGVuY29kZXMgdGhpcyBhcyAmIzM0Oywgc28gaGUgbWF5IGtub3cgc29tZXRoaW5nIEkgZG9uJ3Q/Ci0gICAgICAgICAgICAgICAgaWYgKGRvVVJMRXNjYXBpbmcpCi0gICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZSgiJTIyIik7Ci0gICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoIiZxdW90OyIpOyAvLyB3ZSBoYXZlIHRvIGVzY2FwZSB0aGlzLCBJIGd1ZXNzLgotCi0gICAgICAgICAgICAgICAgLy8gV2UgaGF2ZSB3cml0dGVuIG91dCBhbnkgY2xlYW4gY2hhcmFjdGVycywgdGhlbiB0aGUgZXNjYXBlZCAnJScgYW5kIG5vdyB3ZQotICAgICAgICAgICAgICAgIC8vIFdlIG5vdyB3ZSByZXNldCB0aGUgbmV4dCBwb3NzaWJsZSBjbGVhbiBjaGFyYWN0ZXIuCi0gICAgICAgICAgICAgICAgY2xlYW5TdGFydCA9IGkgKyAxOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoY2ggPT0gJyYnKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIC8vIEhUTUwgNC4wMSByZWFkcywgIkF1dGhvcnMgc2hvdWxkIHVzZSAiJmFtcDsiIChBU0NJSSBkZWNpbWFsIDM4KQotICAgICAgICAgICAgICAgIC8vIGluc3RlYWQgb2YgIiYiIHRvIGF2b2lkIGNvbmZ1c2lvbiB3aXRoIHRoZSBiZWdpbm5pbmcgb2YgYSBjaGFyYWN0ZXIKLSAgICAgICAgICAgICAgICAvLyByZWZlcmVuY2UgKGVudGl0eSByZWZlcmVuY2Ugb3BlbiBkZWxpbWl0ZXIpLgotICAgICAgICAgICAgICAgIGlmIChjbGVhbkxlbmd0aCA+IDApCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoY2hhcnMsIGNsZWFuU3RhcnQsIGNsZWFuTGVuZ3RoKTsKLSAgICAgICAgICAgICAgICAgICAgY2xlYW5MZW5ndGggPSAwOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoIiZhbXA7Iik7Ci0gICAgICAgICAgICAgICAgY2xlYW5TdGFydCA9IGkgKyAxOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIC8vIG5vIHByb2Nlc3NpbmcgZm9yIHRoaXMgY2hhcmFjdGVyLCBqdXN0IGNvdW50IGhvdwotICAgICAgICAgICAgICAgIC8vIG1hbnkgY2hhcmFjdGVycyBpbiBhIHJvdyB0aGF0IHdlIGhhdmUgdGhhdCBuZWVkIG5vIHByb2Nlc3NpbmcKLSAgICAgICAgICAgICAgICBjbGVhbkxlbmd0aCsrOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gYXJlIHRoZXJlIGFueSBjbGVhbiBjaGFyYWN0ZXJzIGF0IHRoZSBlbmQgb2YgdGhlIGFycmF5Ci0gICAgICAgIC8vIHRoYXQgd2UgaGF2ZW4ndCBwcm9jZXNzZWQgeWV0PwotICAgICAgICBpZiAoY2xlYW5MZW5ndGggPiAxKQotICAgICAgICB7Ci0gICAgICAgICAgICAvLyBpZiB0aGUgd2hvbGUgc3RyaW5nIGNhbiBiZSB3cml0dGVuIG91dCBhcy1pcyBkbyBzbwotICAgICAgICAgICAgLy8gb3RoZXJ3aXNlIHdyaXRlIG91dCB0aGUgY2xlYW4gY2hhcnMgYXQgdGhlIGVuZCBvZiB0aGUKLSAgICAgICAgICAgIC8vIGFycmF5Ci0gICAgICAgICAgICBpZiAoY2xlYW5TdGFydCA9PSAwKQotICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZShzdHJpbmcpOwotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZShjaGFycywgY2xlYW5TdGFydCwgY2xlYW5MZW5ndGgpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKGNsZWFuTGVuZ3RoID09IDEpCi0gICAgICAgIHsKLSAgICAgICAgICAgIC8vIGEgbGl0dGxlIG9wdGltaXphdGlvbiBmb3IgMSBjbGVhbiBjaGFyYWN0ZXIKLSAgICAgICAgICAgIC8vICh3ZSBjb3VsZCBoYXZlIGxldCB0aGUgcHJldmlvdXMgaWYoLi4uKSBoYW5kbGUgdGhlbSBhbGwpCi0gICAgICAgICAgICB3cml0ZXIud3JpdGUoY2gpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogV3JpdGVzIHRoZSBzcGVjaWZpZWQgPHZhcj5zdHJpbmc8L3Zhcj4gYWZ0ZXIgc3Vic3RpdHV0aW5nIDxWQVI+c3BlY2lhbHM8L1ZBUj4sCi0gICAgICogYW5kIFVURi0xNiBzdXJyb2dhdGVzIGZvciBjaGFyYWN0ZXIgcmVmZXJlbmNlcyA8Q09ERT4mYW1wOyN4bm48L0NPREU+LgotICAgICAqCi0gICAgICogQHBhcmFtICAgc3RyaW5nICAgICAgU3RyaW5nIHRvIGNvbnZlcnQgdG8gWE1MIGZvcm1hdC4KLSAgICAgKiBAcGFyYW0gICBlbmNvZGluZyAgICBDVVJSRU5UTFkgTk9UIElNUExFTUVOVEVELgotICAgICAqCi0gICAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB3cml0ZUF0dHJTdHJpbmcoCi0gICAgICAgIGZpbmFsIGphdmEuaW8uV3JpdGVyIHdyaXRlciwgU3RyaW5nIHN0cmluZywgU3RyaW5nIGVuY29kaW5nKQotICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGZpbmFsIGludCBlbmQgPSBzdHJpbmcubGVuZ3RoKCk7Ci0gICAgICAgIGlmIChlbmQgPiBtX2F0dHJCdWZmLmxlbmd0aCkKLSAgICAgICAgewotICAgICAgICAgICAgbV9hdHRyQnVmZiA9IG5ldyBjaGFyW2VuZCAqIDIgKyAxXTsKLSAgICAgICAgfQotICAgICAgICBzdHJpbmcuZ2V0Q2hhcnMoMCwgZW5kLCBtX2F0dHJCdWZmLCAwKTsKLSAgICAgICAgZmluYWwgY2hhcltdIGNoYXJzID0gbV9hdHRyQnVmZjsKLQotCi0KLSAgICAgICAgaW50IGNsZWFuU3RhcnQgPSAwOwotICAgICAgICBpbnQgY2xlYW5MZW5ndGggPSAwOwotCi0gICAgICAgIGNoYXIgY2ggPSAwOwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGVuZDsgaSsrKQotICAgICAgICB7Ci0gICAgICAgICAgICBjaCA9IGNoYXJzW2ldOwotCi0gICAgICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIlNQRUNJQUxTU0laRTogIitTUEVDSUFMU1NJWkUpOwotICAgICAgICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJjaDogIisoaW50KWNoKTsKLSAgICAgICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigibV9tYXhDaGFyYWN0ZXI6ICIrKGludCltX21heENoYXJhY3Rlcik7Ci0gICAgICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIm1fYXR0ckNoYXJzTWFwW2NoXTogIisoaW50KW1fYXR0ckNoYXJzTWFwW2NoXSk7Ci0gICAgICAgICAgICBpZiAoZXNjYXBpbmdOb3ROZWVkZWQoY2gpICYmICghbV9jaGFySW5mby5pc1NwZWNpYWxBdHRyQ2hhcihjaCkpKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIGNsZWFuTGVuZ3RoKys7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmICgnPCcgPT0gY2ggfHwgJz4nID09IGNoKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIGNsZWFuTGVuZ3RoKys7IC8vIG5vIGVzY2FwaW5nIGluIHRoaXMgY2FzZSwgYXMgc3BlY2lmaWVkIGluIDE1LjIKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKAotICAgICAgICAgICAgICAgICgnJicgPT0gY2gpICYmICgoaSArIDEpIDwgZW5kKSAmJiAoJ3snID09IGNoYXJzW2kgKyAxXSkpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgY2xlYW5MZW5ndGgrKzsgLy8gbm8gZXNjYXBpbmcgaW4gdGhpcyBjYXNlLCBhcyBzcGVjaWZpZWQgaW4gMTUuMgotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIGlmIChjbGVhbkxlbmd0aCA+IDApCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoY2hhcnMsY2xlYW5TdGFydCxjbGVhbkxlbmd0aCk7Ci0gICAgICAgICAgICAgICAgICAgIGNsZWFuTGVuZ3RoID0gMDsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaW50IHBvcyA9IGFjY3VtRGVmYXVsdEVudGl0eSh3cml0ZXIsIGNoLCBpLCBjaGFycywgZW5kLCBmYWxzZSwgdHJ1ZSk7Ci0KLSAgICAgICAgICAgICAgICBpZiAoaSAhPSBwb3MpCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICBpID0gcG9zIC0gMTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKEVuY29kaW5ncy5pc0hpZ2hVVEYxNlN1cnJvZ2F0ZShjaCkpCi0gICAgICAgICAgICAgICAgICAgIHsKLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlVVRGMTZTdXJyb2dhdGUoY2gsIGNoYXJzLCBpLCBlbmQpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkrKzsgLy8gdHdvIGlucHV0IGNoYXJhY3RlcnMgcHJvY2Vzc2VkCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGlzIGluY3JlbWVudHMgYnkgb25lIGFuZCB0aGUgZm9yKCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGxvb3AgaXRzZWxmIGluY3JlbWVudHMgYnkgYW5vdGhlciBvbmUuCi0gICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAvLyBUaGUgbmV4dCBpcyBraW5kIG9mIGEgaGFjayB0byBrZWVwIGZyb20gZXNjYXBpbmcgaW4gdGhlIGNhc2UKLSAgICAgICAgICAgICAgICAgICAgLy8gb2YgU2hpZnRfSklTIGFuZCB0aGUgbGlrZS4KLQotICAgICAgICAgICAgICAgICAgICAvKgotICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICgoY2ggPCBtX21heENoYXJhY3RlcikgJiYgKG1fbWF4Q2hhcmFjdGVyID09IDB4RkZGRikKLSAgICAgICAgICAgICAgICAgICAgJiYgKGNoICE9IDE2MCkpCi0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKGNoKTsgIC8vIG5vIGVzY2FwaW5nIGluIHRoaXMgY2FzZQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgICAgKi8KLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG91dHB1dFN0cmluZ0ZvckNoYXIgPSBtX2NoYXJJbmZvLmdldE91dHB1dFN0cmluZ0ZvckNoYXIoY2gpOwotICAgICAgICAgICAgICAgICAgICBpZiAobnVsbCAhPSBvdXRwdXRTdHJpbmdGb3JDaGFyKQotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUob3V0cHV0U3RyaW5nRm9yQ2hhcik7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoZXNjYXBpbmdOb3ROZWVkZWQoY2gpKQotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoY2gpOyAvLyBubyBlc2NhcGluZyBpbiB0aGlzIGNhc2UKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZSgiJiMiKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZShJbnRlZ2VyLnRvU3RyaW5nKGNoKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoJzsnKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBjbGVhblN0YXJ0ID0gaSArIDE7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gLy8gZW5kIG9mIGZvcigpCi0KLSAgICAgICAgLy8gYXJlIHRoZXJlIGFueSBjbGVhbiBjaGFyYWN0ZXJzIGF0IHRoZSBlbmQgb2YgdGhlIGFycmF5Ci0gICAgICAgIC8vIHRoYXQgd2UgaGF2ZW4ndCBwcm9jZXNzZWQgeWV0PwotICAgICAgICBpZiAoY2xlYW5MZW5ndGggPiAxKQotICAgICAgICB7Ci0gICAgICAgICAgICAvLyBpZiB0aGUgd2hvbGUgc3RyaW5nIGNhbiBiZSB3cml0dGVuIG91dCBhcy1pcyBkbyBzbwotICAgICAgICAgICAgLy8gb3RoZXJ3aXNlIHdyaXRlIG91dCB0aGUgY2xlYW4gY2hhcnMgYXQgdGhlIGVuZCBvZiB0aGUKLSAgICAgICAgICAgIC8vIGFycmF5Ci0gICAgICAgICAgICBpZiAoY2xlYW5TdGFydCA9PSAwKQotICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZShzdHJpbmcpOwotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZShjaGFycywgY2xlYW5TdGFydCwgY2xlYW5MZW5ndGgpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKGNsZWFuTGVuZ3RoID09IDEpCi0gICAgICAgIHsKLSAgICAgICAgICAgIC8vIGEgbGl0dGxlIG9wdGltaXphdGlvbiBmb3IgMSBjbGVhbiBjaGFyYWN0ZXIKLSAgICAgICAgICAgIC8vICh3ZSBjb3VsZCBoYXZlIGxldCB0aGUgcHJldmlvdXMgaWYoLi4uKSBoYW5kbGUgdGhlbSBhbGwpCi0gICAgICAgICAgICB3cml0ZXIud3JpdGUoY2gpOwotICAgICAgICB9Ci0gICAgfQotCi0KLQotICAgIC8qKgotICAgICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGNoYXJhY3RlciBkYXRhLgotICAgICAqCi0gICAgICogPHA+VGhlIFBhcnNlciB3aWxsIGNhbGwgdGhpcyBtZXRob2QgdG8gcmVwb3J0IGVhY2ggY2h1bmsgb2YKLSAgICAgKiBjaGFyYWN0ZXIgZGF0YS4gIFNBWCBwYXJzZXJzIG1heSByZXR1cm4gYWxsIGNvbnRpZ3VvdXMgY2hhcmFjdGVyCi0gICAgICogZGF0YSBpbiBhIHNpbmdsZSBjaHVuaywgb3IgdGhleSBtYXkgc3BsaXQgaXQgaW50byBzZXZlcmFsCi0gICAgICogY2h1bmtzOyBob3dldmVyLCBhbGwgb2YgdGhlIGNoYXJhY3RlcnMgaW4gYW55IHNpbmdsZSBldmVudAotICAgICAqIG11c3QgY29tZSBmcm9tIHRoZSBzYW1lIGV4dGVybmFsIGVudGl0eSwgc28gdGhhdCB0aGUgTG9jYXRvcgotICAgICAqIHByb3ZpZGVzIHVzZWZ1bCBpbmZvcm1hdGlvbi48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5UaGUgYXBwbGljYXRpb24gbXVzdCBub3QgYXR0ZW1wdCB0byByZWFkIGZyb20gdGhlIGFycmF5Ci0gICAgICogb3V0c2lkZSBvZiB0aGUgc3BlY2lmaWVkIHJhbmdlLjwvcD4KLSAgICAgKgotICAgICAqIDxwPk5vdGUgdGhhdCBzb21lIHBhcnNlcnMgd2lsbCByZXBvcnQgd2hpdGVzcGFjZSB1c2luZyB0aGUKLSAgICAgKiBpZ25vcmFibGVXaGl0ZXNwYWNlKCkgbWV0aG9kIHJhdGhlciB0aGFuIHRoaXMgb25lICh2YWxpZGF0aW5nCi0gICAgICogcGFyc2VycyBtdXN0IGRvIHNvKS48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gY2hhcnMgVGhlIGNoYXJhY3RlcnMgZnJvbSB0aGUgWE1MIGRvY3VtZW50LgotICAgICAqIEBwYXJhbSBzdGFydCBUaGUgc3RhcnQgcG9zaXRpb24gaW4gdGhlIGFycmF5LgotICAgICAqIEBwYXJhbSBsZW5ndGggVGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHJlYWQgZnJvbSB0aGUgYXJyYXkuCi0gICAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICAgKiBAc2VlICNpZ25vcmFibGVXaGl0ZXNwYWNlCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5Mb2NhdG9yCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgICAqLwotICAgIHB1YmxpYyBmaW5hbCB2b2lkIGNoYXJhY3RlcnMoY2hhciBjaGFyc1tdLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpCi0gICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICB7Ci0KLSAgICAgICAgaWYgKG1fZWxlbUNvbnRleHQubV9pc1JhdykKLSAgICAgICAgewotICAgICAgICAgICAgdHJ5Ci0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgaWYgKG1fZWxlbUNvbnRleHQubV9zdGFydFRhZ09wZW4pCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICBjbG9zZVN0YXJ0VGFnKCk7Ci0gICAgICAgICAgICAgICAgICAgIG1fZWxlbUNvbnRleHQubV9zdGFydFRhZ09wZW4gPSBmYWxzZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgbV9pc3ByZXNlcnZlID0gdHJ1ZTsKLQotLy8gICAgICAgICAgICAgIFdpdGggbV9pc3ByZXNlcnZlIGp1c3Qgc2V0IHRydWUgaXQgbG9va3MgbGlrZSBzaG91bGRJbmRlbnQoKQotLy8gICAgICAgICAgICAgIHdpbGwgYWx3YXlzIHJldHVybiBmYWxzZSwgc28gZHJvcCBhbnkgcG9zc2libGUgaW5kZW50YXRpb24uCi0vLyAgICAgICAgICAgICAgaWYgKHNob3VsZEluZGVudCgpKQotLy8gICAgICAgICAgICAgICAgICBpbmRlbnQoKTsKLQotICAgICAgICAgICAgICAgIC8vIHdyaXRlci53cml0ZSgiPCFbQ0RBVEFbIik7Ci0gICAgICAgICAgICAgICAgLy8gd3JpdGVyLndyaXRlKGNoYXJzLCBzdGFydCwgbGVuZ3RoKTsKLSAgICAgICAgICAgICAgICB3cml0ZU5vcm1hbGl6ZWRDaGFycyhjaGFycywgc3RhcnQsIGxlbmd0aCwgZmFsc2UsIG1fbGluZVNlcFVzZSk7Ci0KLSAgICAgICAgICAgICAgICAvLyB3cml0ZXIud3JpdGUoIl1dPiIpOwotCi0gICAgICAgICAgICAgICAgLy8gdGltZSB0byBnZW5lcmF0ZSBjaGFyYWN0ZXJzIGV2ZW50Ci0gICAgICAgICAgICAgICAgaWYgKG1fdHJhY2VyICE9IG51bGwpCi0gICAgICAgICAgICAgICAgICAgIHN1cGVyLmZpcmVDaGFyRXZlbnQoY2hhcnMsIHN0YXJ0LCBsZW5ndGgpOwotCi0gICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2F0Y2ggKElPRXhjZXB0aW9uIGlvZSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICBVdGlscy5tZXNzYWdlcy5jcmVhdGVNZXNzYWdlKAotICAgICAgICAgICAgICAgICAgICAgICAgTXNnS2V5LkVSX09JRVJST1IsCi0gICAgICAgICAgICAgICAgICAgICAgICBudWxsKSwKLSAgICAgICAgICAgICAgICAgICAgaW9lKTsKLSAgICAgICAgICAgICAgICAvLyJJTyBlcnJvciIsIGlvZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICB7Ci0gICAgICAgICAgICBzdXBlci5jaGFyYWN0ZXJzKGNoYXJzLCBzdGFydCwgbGVuZ3RoKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqICBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBjZGF0YS4KLSAgICAgKgotICAgICAqICA8cD5UaGUgUGFyc2VyIHdpbGwgY2FsbCB0aGlzIG1ldGhvZCB0byByZXBvcnQgZWFjaCBjaHVuayBvZgotICAgICAqICBjaGFyYWN0ZXIgZGF0YS4gIFNBWCBwYXJzZXJzIG1heSByZXR1cm4gYWxsIGNvbnRpZ3VvdXMgY2hhcmFjdGVyCi0gICAgICogIGRhdGEgaW4gYSBzaW5nbGUgY2h1bmssIG9yIHRoZXkgbWF5IHNwbGl0IGl0IGludG8gc2V2ZXJhbAotICAgICAqICBjaHVua3M7IGhvd2V2ZXIsIGFsbCBvZiB0aGUgY2hhcmFjdGVycyBpbiBhbnkgc2luZ2xlIGV2ZW50Ci0gICAgICogIG11c3QgY29tZSBmcm9tIHRoZSBzYW1lIGV4dGVybmFsIGVudGl0eSwgc28gdGhhdCB0aGUgTG9jYXRvcgotICAgICAqICBwcm92aWRlcyB1c2VmdWwgaW5mb3JtYXRpb24uPC9wPgotICAgICAqCi0gICAgICogIDxwPlRoZSBhcHBsaWNhdGlvbiBtdXN0IG5vdCBhdHRlbXB0IHRvIHJlYWQgZnJvbSB0aGUgYXJyYXkKLSAgICAgKiAgb3V0c2lkZSBvZiB0aGUgc3BlY2lmaWVkIHJhbmdlLjwvcD4KLSAgICAgKgotICAgICAqICA8cD5Ob3RlIHRoYXQgc29tZSBwYXJzZXJzIHdpbGwgcmVwb3J0IHdoaXRlc3BhY2UgdXNpbmcgdGhlCi0gICAgICogIGlnbm9yYWJsZVdoaXRlc3BhY2UoKSBtZXRob2QgcmF0aGVyIHRoYW4gdGhpcyBvbmUgKHZhbGlkYXRpbmcKLSAgICAgKiAgcGFyc2VycyBtdXN0IGRvIHNvKS48L3A+Ci0gICAgICoKLSAgICAgKiAgQHBhcmFtIGNoIFRoZSBjaGFyYWN0ZXJzIGZyb20gdGhlIFhNTCBkb2N1bWVudC4KLSAgICAgKiAgQHBhcmFtIHN0YXJ0IFRoZSBzdGFydCBwb3NpdGlvbiBpbiB0aGUgYXJyYXkuCi0gICAgICogIEBwYXJhbSBsZW5ndGggVGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHJlYWQgZnJvbSB0aGUgYXJyYXkuCi0gICAgICogIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgICAqICAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgICAqICBAc2VlICNpZ25vcmFibGVXaGl0ZXNwYWNlCi0gICAgICogIEBzZWUgb3JnLnhtbC5zYXguTG9jYXRvcgotICAgICAqCi0gICAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgZmluYWwgdm9pZCBjZGF0YShjaGFyIGNoW10sIGludCBzdGFydCwgaW50IGxlbmd0aCkKLSAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgIHsKLQotICAgICAgICBpZiAoKG51bGwgIT0gbV9lbGVtQ29udGV4dC5tX2VsZW1lbnROYW1lKQotICAgICAgICAgICAgJiYgKG1fZWxlbUNvbnRleHQubV9lbGVtZW50TmFtZS5lcXVhbHNJZ25vcmVDYXNlKCJTQ1JJUFQiKQotICAgICAgICAgICAgICAgIHx8IG1fZWxlbUNvbnRleHQubV9lbGVtZW50TmFtZS5lcXVhbHNJZ25vcmVDYXNlKCJTVFlMRSIpKSkKLSAgICAgICAgewotICAgICAgICAgICAgdHJ5Ci0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgaWYgKG1fZWxlbUNvbnRleHQubV9zdGFydFRhZ09wZW4pCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICBjbG9zZVN0YXJ0VGFnKCk7Ci0gICAgICAgICAgICAgICAgICAgIG1fZWxlbUNvbnRleHQubV9zdGFydFRhZ09wZW4gPSBmYWxzZTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBtX2lzcHJlc2VydmUgPSB0cnVlOwotCi0gICAgICAgICAgICAgICAgaWYgKHNob3VsZEluZGVudCgpKQotICAgICAgICAgICAgICAgICAgICBpbmRlbnQoKTsKLQotICAgICAgICAgICAgICAgIC8vIHdyaXRlci53cml0ZShjaCwgc3RhcnQsIGxlbmd0aCk7Ci0gICAgICAgICAgICAgICAgd3JpdGVOb3JtYWxpemVkQ2hhcnMoY2gsIHN0YXJ0LCBsZW5ndGgsIHRydWUsIG1fbGluZVNlcFVzZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXRjaCAoSU9FeGNlcHRpb24gaW9lKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgIFV0aWxzLm1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoCi0gICAgICAgICAgICAgICAgICAgICAgICBNc2dLZXkuRVJfT0lFUlJPUiwKLSAgICAgICAgICAgICAgICAgICAgICAgIG51bGwpLAotICAgICAgICAgICAgICAgICAgICBpb2UpOwotICAgICAgICAgICAgICAgIC8vIklPIGVycm9yIiwgaW9lKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgIHsKLSAgICAgICAgICAgIHN1cGVyLmNkYXRhKGNoLCBzdGFydCwgbGVuZ3RoKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqICBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBhIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24uCi0gICAgICoKLSAgICAgKiAgQHBhcmFtIHRhcmdldCBUaGUgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiB0YXJnZXQuCi0gICAgICogIEBwYXJhbSBkYXRhIFRoZSBwcm9jZXNzaW5nIGluc3RydWN0aW9uIGRhdGEsIG9yIG51bGwgaWYKLSAgICAgKiAgICAgICAgIG5vbmUgd2FzIHN1cHBsaWVkLgotICAgICAqICBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICAgKiAgICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICAgKgotICAgICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcHJvY2Vzc2luZ0luc3RydWN0aW9uKFN0cmluZyB0YXJnZXQsIFN0cmluZyBkYXRhKQotICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAgewotCi0gICAgICAgIC8vIFByb2Nlc3MgYW55IHBlbmRpbmcgc3RhckRvY3VtZW50IGFuZCBzdGFydEVsZW1lbnQgZmlyc3QuCi0gICAgICAgIGZsdXNoUGVuZGluZygpOwotCi0gICAgICAgIC8vIFVzZSBhIGZhaXJseSBuYXN0eSBoYWNrIHRvIHRlbGwgaWYgdGhlIG5leHQgbm9kZSBpcyBzdXBwb3NlZCB0byBiZQotICAgICAgICAvLyB1bmVzY2FwZWQgdGV4dC4KLSAgICAgICAgaWYgKHRhcmdldC5lcXVhbHMoUmVzdWx0LlBJX0RJU0FCTEVfT1VUUFVUX0VTQ0FQSU5HKSkKLSAgICAgICAgewotICAgICAgICAgICAgc3RhcnROb25Fc2NhcGluZygpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKHRhcmdldC5lcXVhbHMoUmVzdWx0LlBJX0VOQUJMRV9PVVRQVVRfRVNDQVBJTkcpKQotICAgICAgICB7Ci0gICAgICAgICAgICBlbmROb25Fc2NhcGluZygpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotICAgICAgICAgICAgdHJ5Ci0gICAgICAgICAgICB7Ci0gICAgICAgICAgICBpZiAobV9lbGVtQ29udGV4dC5tX3N0YXJ0VGFnT3BlbikKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBjbG9zZVN0YXJ0VGFnKCk7Ci0gICAgICAgICAgICAgICAgbV9lbGVtQ29udGV4dC5tX3N0YXJ0VGFnT3BlbiA9IGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAobV9uZWVkVG9DYWxsU3RhcnREb2N1bWVudCkKLSAgICAgICAgICAgICAgICBzdGFydERvY3VtZW50SW50ZXJuYWwoKTsKLQotICAgICAgICAgICAgaWYgKHNob3VsZEluZGVudCgpKQotICAgICAgICAgICAgICAgIGluZGVudCgpOwotCi0gICAgICAgICAgICBmaW5hbCBqYXZhLmlvLldyaXRlciB3cml0ZXIgPSBtX3dyaXRlcjsKLSAgICAgICAgICAgIC8vd3JpdGVyLndyaXRlKCI8PyIgKyB0YXJnZXQpOwotICAgICAgICAgICAgd3JpdGVyLndyaXRlKCI8PyIpOwotICAgICAgICAgICAgd3JpdGVyLndyaXRlKHRhcmdldCk7Ci0KLSAgICAgICAgICAgIGlmIChkYXRhLmxlbmd0aCgpID4gMCAmJiAhQ2hhcmFjdGVyLmlzU3BhY2VDaGFyKGRhdGEuY2hhckF0KDApKSkKLSAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoJyAnKTsKLQotICAgICAgICAgICAgLy93cml0ZXIud3JpdGUoZGF0YSArICI+Iik7IC8vIGRpZmZlcmVudCBmcm9tIFhNTAotICAgICAgICAgICAgd3JpdGVyLndyaXRlKGRhdGEpOyAvLyBkaWZmZXJlbnQgZnJvbSBYTUwKLSAgICAgICAgICAgIHdyaXRlci53cml0ZSgnPicpOyAvLyBkaWZmZXJlbnQgZnJvbSBYTUwKLQotICAgICAgICAgICAgLy8gQWx3YXlzIG91dHB1dCBhIG5ld2xpbmUgY2hhciBpZiBub3QgaW5zaWRlIG9mIGFuCi0gICAgICAgICAgICAvLyBlbGVtZW50LiBUaGUgd2hpdGVzcGFjZSBpcyBub3Qgc2lnbmlmaWNhbnQgaW4gdGhhdAotICAgICAgICAgICAgLy8gY2FzZS4KLSAgICAgICAgICAgIGlmIChtX2VsZW1Db250ZXh0Lm1fY3VycmVudEVsZW1EZXB0aCA8PSAwKQotICAgICAgICAgICAgICAgIG91dHB1dExpbmVTZXAoKTsKLQotICAgICAgICAgICAgbV9zdGFydE5ld0xpbmUgPSB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2F0Y2goSU9FeGNlcHRpb24gZSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKGUpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gbm93IGdlbmVyYXRlIHRoZSBQSSBldmVudAotICAgICAgICBpZiAobV90cmFjZXIgIT0gbnVsbCkKLSAgICAgICAgICAgIHN1cGVyLmZpcmVFc2NhcGluZ0V2ZW50KHRhcmdldCwgZGF0YSk7Ci0gICAgIH0KLQotICAgIC8qKgotICAgICAqIFJlY2VpdmUgbm90aXZpY2F0aW9uIG9mIGEgZW50aXR5UmVmZXJlbmNlLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGVudGl0eSBuYW1lIHN0cmluZy4KLSAgICAgKgotICAgICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIHZvaWQgZW50aXR5UmVmZXJlbmNlKFN0cmluZyBuYW1lKQotICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICB0cnkKLSAgICAgICAgewotCi0gICAgICAgIGZpbmFsIGphdmEuaW8uV3JpdGVyIHdyaXRlciA9IG1fd3JpdGVyOwotICAgICAgICB3cml0ZXIud3JpdGUoJyYnKTsKLSAgICAgICAgd3JpdGVyLndyaXRlKG5hbWUpOwotICAgICAgICB3cml0ZXIud3JpdGUoJzsnKTsKLQotICAgICAgICB9IGNhdGNoKElPRXhjZXB0aW9uIGUpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0gICAgLyoqCi0gICAgICogQHNlZSBFeHRlbmRlZENvbnRlbnRIYW5kbGVyI2VuZEVsZW1lbnQoU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyBmaW5hbCB2b2lkIGVuZEVsZW1lbnQoU3RyaW5nIGVsZW1OYW1lKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBlbmRFbGVtZW50KG51bGwsIG51bGwsIGVsZW1OYW1lKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBQcm9jZXNzIHRoZSBhdHRyaWJ1dGVzLCB3aGljaCBtZWFucyB0byB3cml0ZSBvdXQgdGhlIGN1cnJlbnRseQotICAgICAqIGNvbGxlY3RlZCBhdHRyaWJ1dGVzIHRvIHRoZSB3cml0ZXIuIFRoZSBhdHRyaWJ1dGVzIGFyZSBub3QKLSAgICAgKiBjbGVhcmVkIGJ5IHRoaXMgbWV0aG9kCi0gICAgICoKLSAgICAgKiBAcGFyYW0gd3JpdGVyIHRoZSB3cml0ZXIgdG8gd3JpdGUgcHJvY2Vzc2VkIGF0dHJpYnV0ZXMgdG8uCi0gICAgICogQHBhcmFtIG5BdHRycyB0aGUgbnVtYmVyIG9mIGF0dHJpYnV0ZXMgaW4gbV9hdHRyaWJ1dGVzCi0gICAgICogdG8gYmUgcHJvY2Vzc2VkCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHByb2Nlc3NBdHRyaWJ1dGVzKGphdmEuaW8uV3JpdGVyIHdyaXRlciwgaW50IG5BdHRycykKLSAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgICAgIC8qCi0gICAgICAgICAgICAgKiBwcm9jZXNzIHRoZSBjb2xsZWN0ZWQgYXR0cmlidXRlcwotICAgICAgICAgICAgICovCi0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG5BdHRyczsgaSsrKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIHByb2Nlc3NBdHRyaWJ1dGUoCi0gICAgICAgICAgICAgICAgICAgIHdyaXRlciwKLSAgICAgICAgICAgICAgICAgICAgbV9hdHRyaWJ1dGVzLmdldFFOYW1lKGkpLAotICAgICAgICAgICAgICAgICAgICBtX2F0dHJpYnV0ZXMuZ2V0VmFsdWUoaSksCi0gICAgICAgICAgICAgICAgICAgIG1fZWxlbUNvbnRleHQubV9lbGVtZW50RGVzYyk7Ci0gICAgICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRm9yIHRoZSBlbmNsb3NpbmcgZWxlbWVudHMgc3RhcnRpbmcgdGFnIHdyaXRlIG91dCBvdXQgYW55IGF0dHJpYnV0ZXMKLSAgICAgKiBmb2xsb3dlZCBieSAiPiIKLSAgICAgKgotICAgICAqQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCBjbG9zZVN0YXJ0VGFnKCkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgICAgIHRyeQotICAgICAgICAgICAgewotCi0gICAgICAgICAgICAvLyBmaW5pc2ggcHJvY2Vzc2luZyBhdHRyaWJ1dGVzLCB0aW1lIHRvIGZpcmUgb2ZmIHRoZSBzdGFydCBlbGVtZW50IGV2ZW50Ci0gICAgICAgICAgICBpZiAobV90cmFjZXIgIT0gbnVsbCkKLSAgICAgICAgICAgICAgICBzdXBlci5maXJlU3RhcnRFbGVtKG1fZWxlbUNvbnRleHQubV9lbGVtZW50TmFtZSk7Ci0KLSAgICAgICAgICAgIGludCBuQXR0cnMgPSBtX2F0dHJpYnV0ZXMuZ2V0TGVuZ3RoKCk7Ci0gICAgICAgICAgICBpZiAobkF0dHJzPjApCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgcHJvY2Vzc0F0dHJpYnV0ZXMobV93cml0ZXIsIG5BdHRycyk7Ci0gICAgICAgICAgICAgICAgLy8gY2xlYXIgYXR0cmlidXRlcyBvYmplY3QgZm9yIHJlLXVzZSB3aXRoIG5leHQgZWxlbWVudAotICAgICAgICAgICAgICAgIG1fYXR0cmlidXRlcy5jbGVhcigpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBtX3dyaXRlci53cml0ZSgnPicpOwotCi0gICAgICAgICAgICAvKiB3aGV0aGVyIFhhbGFuIG9yIFhTTFRDLCB3ZSBoYXZlIHRoZSBwcmVmaXggbWFwcGluZ3Mgbm93LCBzbwotICAgICAgICAgICAgICogbGV0cyBkZXRlcm1pbmUgaWYgdGhlIGN1cnJlbnQgZWxlbWVudCBpcyBzcGVjaWZpZWQgaW4gdGhlIGNkYXRhLQotICAgICAgICAgICAgICogc2VjdGlvbi1lbGVtZW50cyBsaXN0LgotICAgICAgICAgICAgICovCi0gICAgICAgICAgICBpZiAobV9jZGF0YVNlY3Rpb25FbGVtZW50cyAhPSBudWxsKQotICAgICAgICAgICAgICAgIG1fZWxlbUNvbnRleHQubV9pc0NkYXRhU2VjdGlvbiA9IGlzQ2RhdGFTZWN0aW9uKCk7Ci0gICAgICAgICAgICBpZiAobV9kb0luZGVudCkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBtX2lzcHJldnRleHQgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICBtX3ByZXNlcnZlcy5wdXNoKG1faXNwcmVzZXJ2ZSk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhdGNoKElPRXhjZXB0aW9uIGUpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbihlKTsKLSAgICAgICAgICAgIH0KLSAgICB9Ci0gICAgLyoqCi0gICAgICogSW5pdGlhbGl6ZSB0aGUgc2VyaWFsaXplciB3aXRoIHRoZSBzcGVjaWZpZWQgb3V0cHV0IHN0cmVhbSBhbmQgb3V0cHV0Ci0gICAgICogZm9ybWF0LiBNdXN0IGJlIGNhbGxlZCBiZWZvcmUgY2FsbGluZyBhbnkgb2YgdGhlIHNlcmlhbGl6ZSBtZXRob2RzLgotICAgICAqCi0gICAgICogQHBhcmFtIG91dHB1dCBUaGUgb3V0cHV0IHN0cmVhbSB0byB1c2UKLSAgICAgKiBAcGFyYW0gZm9ybWF0IFRoZSBvdXRwdXQgZm9ybWF0Ci0gICAgICogQHRocm93cyBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIFRoZSBlbmNvZGluZyBzcGVjaWZpZWQgICBpbiB0aGUKLSAgICAgKiBvdXRwdXQgZm9ybWF0IGlzIG5vdCBzdXBwb3J0ZWQKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgc3luY2hyb25pemVkIHZvaWQgaW5pdChPdXRwdXRTdHJlYW0gb3V0cHV0LCBQcm9wZXJ0aWVzIGZvcm1hdCkKLSAgICAgICAgdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGlmIChudWxsID09IGZvcm1hdCkKLSAgICAgICAgewotICAgICAgICAgICAgZm9ybWF0ID0gT3V0cHV0UHJvcGVydGllc0ZhY3RvcnkuZ2V0RGVmYXVsdE1ldGhvZFByb3BlcnRpZXMoTWV0aG9kLkhUTUwpOwotICAgICAgICAgfQotICAgICAgICBzdXBlci5pbml0KG91dHB1dCxmb3JtYXQsIGZhbHNlKTsKLSAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFNwZWNpZmllcyBhbiBvdXRwdXQgc3RyZWFtIHRvIHdoaWNoIHRoZSBkb2N1bWVudCBzaG91bGQgYmUKLSAgICAgICAgICogc2VyaWFsaXplZC4gVGhpcyBtZXRob2Qgc2hvdWxkIG5vdCBiZSBjYWxsZWQgd2hpbGUgdGhlCi0gICAgICAgICAqIHNlcmlhbGl6ZXIgaXMgaW4gdGhlIHByb2Nlc3Mgb2Ygc2VyaWFsaXppbmcgYSBkb2N1bWVudC4KLSAgICAgICAgICogPHA+Ci0gICAgICAgICAqIFRoZSBlbmNvZGluZyBzcGVjaWZpZWQgaW4gdGhlIG91dHB1dCBwcm9wZXJ0aWVzIGlzIHVzZWQsIG9yCi0gICAgICAgICAqIGlmIG5vIGVuY29kaW5nIHdhcyBzcGVjaWZpZWQsIHRoZSBkZWZhdWx0IGZvciB0aGUgc2VsZWN0ZWQKLSAgICAgICAgICogb3V0cHV0IG1ldGhvZC4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIG91dHB1dCBUaGUgb3V0cHV0IHN0cmVhbQotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIHZvaWQgc2V0T3V0cHV0U3RyZWFtKE91dHB1dFN0cmVhbSBvdXRwdXQpCi0gICAgICAgIHsKLQotICAgICAgICAgICAgdHJ5Ci0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgUHJvcGVydGllcyBmb3JtYXQ7Ci0gICAgICAgICAgICAgICAgaWYgKG51bGwgPT0gbV9mb3JtYXQpCi0gICAgICAgICAgICAgICAgICAgIGZvcm1hdCA9IE91dHB1dFByb3BlcnRpZXNGYWN0b3J5LmdldERlZmF1bHRNZXRob2RQcm9wZXJ0aWVzKE1ldGhvZC5IVE1MKTsKLSAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgIGZvcm1hdCA9IG1fZm9ybWF0OwotICAgICAgICAgICAgICAgIGluaXQob3V0cHV0LCBmb3JtYXQsIHRydWUpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2F0Y2ggKFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gdWVlKQotICAgICAgICAgICAgewotCi0gICAgICAgICAgICAgICAgLy8gU2hvdWxkIGhhdmUgYmVlbiB3YXJuZWQgaW4gaW5pdCwgSSBndWVzcy4uLgotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIC8qKgotICAgICAgICAgKiBUaGlzIG1ldGhvZCBpcyB1c2VkIHdoZW4gYSBwcmVmaXgvdXJpIG5hbWVzcGFjZSBtYXBwaW5nCi0gICAgICAgICAqIGlzIGluZGljYXRlZCBhZnRlciB0aGUgZWxlbWVudCB3YXMgc3RhcnRlZCB3aXRoIGEKLSAgICAgICAgICogc3RhcnRFbGVtZW50KCkgYW5kIGJlZm9yZSBhbmQgZW5kRWxlbWVudCgpLgotICAgICAgICAgKiBzdGFydFByZWZpeE1hcHBpbmcocHJlZml4LHVyaSkgd291bGQgYmUgdXNlZCBiZWZvcmUgdGhlCi0gICAgICAgICAqIHN0YXJ0RWxlbWVudCgpIGNhbGwuCi0gICAgICAgICAqIEBwYXJhbSB1cmkgdGhlIFVSSSBvZiB0aGUgbmFtZXNwYWNlCi0gICAgICAgICAqIEBwYXJhbSBwcmVmaXggdGhlIHByZWZpeCBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIFVSSS4KLSAgICAgICAgICoKLSAgICAgICAgICogQHNlZSBFeHRlbmRlZENvbnRlbnRIYW5kbGVyI25hbWVzcGFjZUFmdGVyU3RhcnRFbGVtZW50KFN0cmluZywgU3RyaW5nKQotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIHZvaWQgbmFtZXNwYWNlQWZ0ZXJTdGFydEVsZW1lbnQoU3RyaW5nIHByZWZpeCwgU3RyaW5nIHVyaSkKLSAgICAgICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICAgICAgewotICAgICAgICAgICAgLy8gaGFjayBmb3IgWFNMVEMgd2l0aCBmaW5kaW5nIFVSSSBmb3IgZGVmYXVsdCBuYW1lc3BhY2UKLSAgICAgICAgICAgIGlmIChtX2VsZW1Db250ZXh0Lm1fZWxlbWVudFVSSSA9PSBudWxsKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIFN0cmluZyBwcmVmaXgxID0gZ2V0UHJlZml4UGFydChtX2VsZW1Db250ZXh0Lm1fZWxlbWVudE5hbWUpOwotICAgICAgICAgICAgICAgIGlmIChwcmVmaXgxID09IG51bGwgJiYgRU1QVFlTVFJJTkcuZXF1YWxzKHByZWZpeCkpCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAvLyB0aGUgZWxlbWVudHMgVVJJIGlzIG5vdCBrbm93biB5ZXQsIGFuZCBpdAotICAgICAgICAgICAgICAgICAgICAvLyBkb2Vzbid0IGhhdmUgYSBwcmVmaXgsIGFuZCB3ZSBhcmUgY3VycmVudGx5Ci0gICAgICAgICAgICAgICAgICAgIC8vIHNldHRpbmcgdGhlIHVyaSBmb3IgcHJlZml4ICIiLCBzbyB3ZSBoYXZlCi0gICAgICAgICAgICAgICAgICAgIC8vIHRoZSB1cmkgZm9yIHRoZSBlbGVtZW50Li4uIGxldHMgcmVtZW1iZXIgaXQKLSAgICAgICAgICAgICAgICAgICAgbV9lbGVtQ29udGV4dC5tX2VsZW1lbnRVUkkgPSB1cmk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgc3RhcnRQcmVmaXhNYXBwaW5nKHByZWZpeCx1cmksZmFsc2UpOwotICAgICAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzdGFydERURChTdHJpbmcgbmFtZSwgU3RyaW5nIHB1YmxpY0lkLCBTdHJpbmcgc3lzdGVtSWQpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIG1faW5EVEQgPSB0cnVlOwotICAgICAgICBzdXBlci5zdGFydERURChuYW1lLCBwdWJsaWNJZCwgc3lzdGVtSWQpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJlcG9ydCB0aGUgZW5kIG9mIERURCBkZWNsYXJhdGlvbnMuCi0gICAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gVGhlIGFwcGxpY2F0aW9uIG1heSByYWlzZSBhbiBleGNlcHRpb24uCi0gICAgICogQHNlZSAjc3RhcnREVEQKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbmREVEQoKSB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBtX2luRFREID0gZmFsc2U7Ci0gICAgICAgIC8qIGZvciBUb0hUTUxTdHJlYW0gdGhlIERPQ1RZUEUgaXMgZW50aXJlbHkgb3V0cHV0IGluIHRoZQotICAgICAgICAgKiBzdGFydERvY3VtZW50SW50ZXJuYWwoKSBtZXRob2QsIHNvIGRvbid0IGRvIGFueXRoaW5nIGhlcmUKLSAgICAgICAgICovCi0gICAgfQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIGRvZXMgbm90aGluZy4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBhdHRyaWJ1dGVEZWNsKAotICAgICAgICBTdHJpbmcgZU5hbWUsCi0gICAgICAgIFN0cmluZyBhTmFtZSwKLSAgICAgICAgU3RyaW5nIHR5cGUsCi0gICAgICAgIFN0cmluZyB2YWx1ZURlZmF1bHQsCi0gICAgICAgIFN0cmluZyB2YWx1ZSkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgLy8gVGhlIGludGVybmFsIERURCBzdWJzZXQgaXMgbm90IHNlcmlhbGl6ZWQgYnkgdGhlIFRvSFRNTFN0cmVhbSBzZXJpYWxpemVyCi0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgZG9lcyBub3RoaW5nLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVsZW1lbnREZWNsKFN0cmluZyBuYW1lLCBTdHJpbmcgbW9kZWwpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIC8vIFRoZSBpbnRlcm5hbCBEVEQgc3Vic2V0IGlzIG5vdCBzZXJpYWxpemVkIGJ5IHRoZSBUb0hUTUxTdHJlYW0gc2VyaWFsaXplcgotICAgIH0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBkb2VzIG5vdGhpbmcuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgaW50ZXJuYWxFbnRpdHlEZWNsKFN0cmluZyBuYW1lLCBTdHJpbmcgdmFsdWUpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIC8vIFRoZSBpbnRlcm5hbCBEVEQgc3Vic2V0IGlzIG5vdCBzZXJpYWxpemVkIGJ5IHRoZSBUb0hUTUxTdHJlYW0gc2VyaWFsaXplcgotICAgIH0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBkb2VzIG5vdGhpbmcuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZXh0ZXJuYWxFbnRpdHlEZWNsKAotICAgICAgICBTdHJpbmcgbmFtZSwKLSAgICAgICAgU3RyaW5nIHB1YmxpY0lkLAotICAgICAgICBTdHJpbmcgc3lzdGVtSWQpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIC8vIFRoZSBpbnRlcm5hbCBEVEQgc3Vic2V0IGlzIG5vdCBzZXJpYWxpemVkIGJ5IHRoZSBUb0hUTUxTdHJlYW0gc2VyaWFsaXplcgotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIGlzIHVzZWQgdG8gYWRkIGFuIGF0dHJpYnV0ZSB0byB0aGUgY3VycmVudGx5IG9wZW4gZWxlbWVudC4KLSAgICAgKiBUaGUgY2FsbGVyIGhhcyBndWFyYW50ZWQgdGhhdCB0aGlzIGF0dHJpYnV0ZSBpcyB1bmlxdWUsIHdoaWNoIG1lYW5zIHRoYXQgaXQKLSAgICAgKiBub3QgYmVlbiBzZWVuIGJlZm9yZSBhbmQgd2lsbCBub3QgYmUgc2VlbiBhZ2Fpbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lIHRoZSBxdWFsaWZpZWQgbmFtZSBvZiB0aGUgYXR0cmlidXRlCi0gICAgICogQHBhcmFtIHZhbHVlIHRoZSB2YWx1ZSBvZiB0aGUgYXR0cmlidXRlIHdoaWNoIGNhbiBjb250YWluIG9ubHkKLSAgICAgKiBBU0NJSSBwcmludGFibGUgY2hhcmFjdGVycyBjaGFyYWN0ZXJzIGluIHRoZSByYW5nZSAzMiB0byAxMjcgaW5jbHVzaXZlLgotICAgICAqIEBwYXJhbSBmbGFncyB0aGUgYml0IHZhbHVlcyBvZiB0aGlzIGludGVnZXIgZ2l2ZSBvcHRpbWl6YXRpb24gaW5mb3JtYXRpb24uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgYWRkVW5pcXVlQXR0cmlidXRlKFN0cmluZyBuYW1lLCBTdHJpbmcgdmFsdWUsIGludCBmbGFncykKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgdHJ5Ci0gICAgICAgIHsKLSAgICAgICAgICAgIGZpbmFsIGphdmEuaW8uV3JpdGVyIHdyaXRlciA9IG1fd3JpdGVyOwotICAgICAgICAgICAgaWYgKChmbGFncyAmIE5PX0JBRF9DSEFSUykgPiAwICYmIG1faHRtbGNoYXJJbmZvLm9ubHlRdW90QW1wTHRHdCkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAvLyAiZmxhZ3MiIGhhcyBpbmRpY2F0ZWQgdGhhdCB0aGUgY2hhcmFjdGVycwotICAgICAgICAgICAgICAgIC8vICc+JyAgJzwnICAgJyYnICBhbmQgJyInIGFyZSBub3QgaW4gdGhlIHZhbHVlIGFuZAotICAgICAgICAgICAgICAgIC8vIG1faHRtbGNoYXJJbmZvIGhhcyByZWNvcmRlZCB0aGF0IHRoZXJlIGFyZSBubyBvdGhlcgotICAgICAgICAgICAgICAgIC8vIGVudGl0aWVzIGluIHRoZSByYW5nZSAwIHRvIDEyNyBzbyB3ZSB3cml0ZSBvdXQgdGhlCi0gICAgICAgICAgICAgICAgLy8gdmFsdWUgZGlyZWN0bHkKLSAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoJyAnKTsKLSAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUobmFtZSk7Ci0gICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKCI9XCIiKTsKLSAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUodmFsdWUpOwotICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZSgnIicpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoCi0gICAgICAgICAgICAgICAgKGZsYWdzICYgSFRNTF9BVFRSRU1QVFkpID4gMAotICAgICAgICAgICAgICAgICAgICAmJiAodmFsdWUubGVuZ3RoKCkgPT0gMCB8fCB2YWx1ZS5lcXVhbHNJZ25vcmVDYXNlKG5hbWUpKSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoJyAnKTsKLSAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUobmFtZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKCcgJyk7Ci0gICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKG5hbWUpOwotICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZSgiPVwiIik7Ci0gICAgICAgICAgICAgICAgaWYgKChmbGFncyAmIEhUTUxfQVRUUlVSTCkgPiAwKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgd3JpdGVBdHRyVVJJKHdyaXRlciwgdmFsdWUsIG1fc3BlY2lhbEVzY2FwZVVSTHMpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICB3cml0ZUF0dHJTdHJpbmcod3JpdGVyLCB2YWx1ZSwgdGhpcy5nZXRFbmNvZGluZygpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKCciJyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBjb21tZW50KGNoYXIgY2hbXSwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKQotICAgICAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgLy8gVGhlIGludGVybmFsIERURCBzdWJzZXQgaXMgbm90IHNlcmlhbGl6ZWQgYnkgdGhlIFRvSFRNTFN0cmVhbSBzZXJpYWxpemVyCi0gICAgICAgIGlmIChtX2luRFREKQotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICBzdXBlci5jb21tZW50KGNoLCBzdGFydCwgbGVuZ3RoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiByZXNldCgpCi0gICAgewotICAgICAgICBib29sZWFuIHJldCA9IHN1cGVyLnJlc2V0KCk7Ci0gICAgICAgIGlmICghcmV0KQotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICBpbml0VG9IVE1MU3RyZWFtKCk7Ci0gICAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBpbml0VG9IVE1MU3RyZWFtKCkKLSAgICB7Ci0vLyAgICAgICAgbV9lbGVtZW50RGVzYyA9IG51bGw7Ci0gICAgICAgIG1faW5CbG9ja0VsZW0gPSBmYWxzZTsKLSAgICAgICAgbV9pbkRURCA9IGZhbHNlOwotLy8gICAgICAgIG1faXNSYXdTdGFjay5jbGVhcigpOwotICAgICAgICBtX29taXRNZXRhVGFnID0gZmFsc2U7Ci0gICAgICAgIG1fc3BlY2lhbEVzY2FwZVVSTHMgPSB0cnVlOwotICAgIH0KLQotICAgIHN0YXRpYyBjbGFzcyBUcmllCi0gICAgewotICAgICAgICAvKioKLSAgICAgICAgICogQSBkaWdpdGFsIHNlYXJjaCB0cmllIGZvciA3LWJpdCBBU0NJSSB0ZXh0Ci0gICAgICAgICAqIFRoZSBBUEkgaXMgYSBzdWJzZXQgb2YgamF2YS51dGlsLkhhc2h0YWJsZQotICAgICAgICAgKiBUaGUga2V5IG11c3QgYmUgYSA3LWJpdCBBU0NJSSBzdHJpbmcKLSAgICAgICAgICogVGhlIHZhbHVlIG1heSBiZSBhbnkgSmF2YSBPYmplY3QKLSAgICAgICAgICogT25lIGNhbiBnZXQgYW4gb2JqZWN0IHN0b3JlZCBpbiBhIHRyaWUgZnJvbSBpdHMga2V5LAotICAgICAgICAgKiBidXQgdGhlIHNlYXJjaCBpcyBlaXRoZXIgY2FzZSBzZW5zaXRpdmUgb3IgY2FzZQotICAgICAgICAgKiBpbnNlbnNpdGl2ZSB0byB0aGUgY2hhcmFjdGVycyBpbiB0aGUga2V5LCBhbmQgdGhpcwotICAgICAgICAgKiBjaG9pY2Ugb2Ygc2Vuc2l0aXZpdHkgb3IgaW5zZW5zaXRpdml0eSBpcyBtYWRlIHdoZW4KLSAgICAgICAgICogdGhlIFRyaWUgaXMgY3JlYXRlZCwgYmVmb3JlIGFueSBvYmplY3RzIGFyZSBwdXQgaW4gaXQuCi0gICAgICAgICAqCi0gICAgICAgICAqIFRoaXMgY2xhc3MgaXMgYSBjb3B5IG9mIHRoZSBvbmUgaW4gY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy4KLSAgICAgICAgICogSXQgZXhpc3RzIHRvIGN1dCB0aGUgc2VyaWFsaXplcnMgZGVwZW5kYW5jeSBvbiB0aGF0IHBhY2thZ2UuCi0gICAgICAgICAqCi0gICAgICAgICAqIEB4c2wudXNhZ2UgaW50ZXJuYWwKLSAgICAgICAgICovCi0KLSAgICAgICAgLyoqIFNpemUgb2YgdGhlIG1fbmV4dENoYXIgYXJyYXkuICAqLwotICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBTFBIQV9TSVpFID0gMTI4OwotCi0gICAgICAgIC8qKiBUaGUgcm9vdCBub2RlIG9mIHRoZSB0cmVlLiAgICAqLwotICAgICAgICBmaW5hbCBOb2RlIG1fUm9vdDsKLQotICAgICAgICAvKiogaGVscGVyIGJ1ZmZlciB0byBjb252ZXJ0IFN0cmluZ3MgdG8gY2hhciBhcnJheXMgKi8KLSAgICAgICAgcHJpdmF0ZSBjaGFyW10gbV9jaGFyQnVmZmVyID0gbmV3IGNoYXJbMF07Ci0KLSAgICAgICAgLyoqIHRydWUgaWYgdGhlIHNlYXJjaCBmb3IgYW4gb2JqZWN0IGlzIGxvd2VyIGNhc2Ugb25seSB3aXRoIHRoZSBrZXkgKi8KLSAgICAgICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIG1fbG93ZXJDYXNlT25seTsKLQotICAgICAgICAvKioKLSAgICAgICAgICogQ29uc3RydWN0IHRoZSB0cmllIHRoYXQgaGFzIGEgY2FzZSBpbnNlbnNpdGl2ZSBzZWFyY2guCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgVHJpZSgpCi0gICAgICAgIHsKLSAgICAgICAgICAgIG1fUm9vdCA9IG5ldyBOb2RlKCk7Ci0gICAgICAgICAgICBtX2xvd2VyQ2FzZU9ubHkgPSBmYWxzZTsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBDb25zdHJ1Y3QgdGhlIHRyaWUgZ2l2ZW4gdGhlIGRlc2lyZWQgY2FzZSBzZW5zaXRpdml0eSB3aXRoIHRoZSBrZXkuCi0gICAgICAgICAqIEBwYXJhbSBsb3dlckNhc2VPbmx5IHRydWUgaWYgdGhlIHNlYXJjaCBrZXlzIGFyZSB0byBiZSBsb3NlciBjYXNlIG9ubHksCi0gICAgICAgICAqIG5vdCBjYXNlIGluc2Vuc2l0aXZlLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIFRyaWUoYm9vbGVhbiBsb3dlckNhc2VPbmx5KQotICAgICAgICB7Ci0gICAgICAgICAgICBtX1Jvb3QgPSBuZXcgTm9kZSgpOwotICAgICAgICAgICAgbV9sb3dlckNhc2VPbmx5ID0gbG93ZXJDYXNlT25seTsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBQdXQgYW4gb2JqZWN0IGludG8gdGhlIHRyaWUgZm9yIGxvb2t1cC4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIGtleSBtdXN0IGJlIGEgNy1iaXQgQVNDSUkgc3RyaW5nCi0gICAgICAgICAqIEBwYXJhbSB2YWx1ZSBhbnkgamF2YSBvYmplY3QuCi0gICAgICAgICAqCi0gICAgICAgICAqIEByZXR1cm4gVGhlIG9sZCBvYmplY3QgdGhhdCBtYXRjaGVkIGtleSwgb3IgbnVsbC4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBPYmplY3QgcHV0KFN0cmluZyBrZXksIE9iamVjdCB2YWx1ZSkKLSAgICAgICAgewotCi0gICAgICAgICAgICBmaW5hbCBpbnQgbGVuID0ga2V5Lmxlbmd0aCgpOwotICAgICAgICAgICAgaWYgKGxlbiA+IG1fY2hhckJ1ZmZlci5sZW5ndGgpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgLy8gbWFrZSB0aGUgYmlnZ2VzdCBidWZmZXIgZXZlciBuZWVkZWQgaW4gZ2V0KFN0cmluZykKLSAgICAgICAgICAgICAgICBtX2NoYXJCdWZmZXIgPSBuZXcgY2hhcltsZW5dOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBOb2RlIG5vZGUgPSBtX1Jvb3Q7Ci0KLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuOyBpKyspCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgTm9kZSBuZXh0Tm9kZSA9Ci0gICAgICAgICAgICAgICAgICAgIG5vZGUubV9uZXh0Q2hhcltDaGFyYWN0ZXIudG9Mb3dlckNhc2Uoa2V5LmNoYXJBdChpKSldOwotCi0gICAgICAgICAgICAgICAgaWYgKG5leHROb2RlICE9IG51bGwpCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICBub2RlID0gbmV4dE5vZGU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIGZvciAoOyBpIDwgbGVuOyBpKyspCi0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIE5vZGUgbmV3Tm9kZSA9IG5ldyBOb2RlKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAobV9sb3dlckNhc2VPbmx5KQotICAgICAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHB1dCB0aGlzIHZhbHVlIGludG8gdGhlIHRyZWUgb25seSB3aXRoIGEgbG93ZXIgY2FzZSBrZXkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlLm1fbmV4dENoYXJbQ2hhcmFjdGVyLnRvTG93ZXJDYXNlKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXkuY2hhckF0KGkpKV0gPQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdOb2RlOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHB1dCB0aGlzIHZhbHVlIGludG8gdGhlIHRyZWUgd2l0aCBhIGNhc2UgaW5zZW5zaXRpdmUga2V5Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZS5tX25leHRDaGFyW0NoYXJhY3Rlci50b1VwcGVyQ2FzZSgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5LmNoYXJBdChpKSldID0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3Tm9kZTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlLm1fbmV4dENoYXJbQ2hhcmFjdGVyLnRvTG93ZXJDYXNlKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXkuY2hhckF0KGkpKV0gPQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdOb2RlOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgbm9kZSA9IG5ld05vZGU7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBPYmplY3QgcmV0ID0gbm9kZS5tX1ZhbHVlOwotCi0gICAgICAgICAgICBub2RlLm1fVmFsdWUgPSB2YWx1ZTsKLQotICAgICAgICAgICAgcmV0dXJuIHJldDsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBHZXQgYW4gb2JqZWN0IHRoYXQgbWF0Y2hlcyB0aGUga2V5LgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0ga2V5IG11c3QgYmUgYSA3LWJpdCBBU0NJSSBzdHJpbmcKLSAgICAgICAgICoKLSAgICAgICAgICogQHJldHVybiBUaGUgb2JqZWN0IHRoYXQgbWF0Y2hlcyB0aGUga2V5LCBvciBudWxsLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIE9iamVjdCBnZXQoZmluYWwgU3RyaW5nIGtleSkKLSAgICAgICAgewotCi0gICAgICAgICAgICBmaW5hbCBpbnQgbGVuID0ga2V5Lmxlbmd0aCgpOwotCi0gICAgICAgICAgICAvKiBJZiB0aGUgbmFtZSBpcyB0b28gbG9uZywgd2Ugd29uJ3QgZmluZCBpdCwgdGhpcyBhbHNvIGtlZXBzIHVzCi0gICAgICAgICAgICAgKiBmcm9tIG92ZXJmbG93aW5nIG1fY2hhckJ1ZmZlcgotICAgICAgICAgICAgICovCi0gICAgICAgICAgICBpZiAobV9jaGFyQnVmZmVyLmxlbmd0aCA8IGxlbikKLSAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLQotICAgICAgICAgICAgTm9kZSBub2RlID0gbV9Sb290OwotICAgICAgICAgICAgc3dpdGNoIChsZW4pIC8vIG9wdGltaXplIHRoZSBsb29rIHVwIGJhc2VkIG9uIHRoZSBudW1iZXIgb2YgY2hhcnMKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAvLyBjYXNlIDAgbG9va3Mgc2lsbHksIGJ1dCB0aGUgZ2VuZXJhdGVkIGJ5dGVjb2RlIHJ1bnMKLSAgICAgICAgICAgICAgICAvLyBmYXN0ZXIgZm9yIGxvb2t1cCBvZiBlbGVtZW50cyBvZiBsZW5ndGggMiB3aXRoIHRoaXMgaW4KLSAgICAgICAgICAgICAgICAvLyBhbmQgYSBmYWlyIGJpdCBmYXN0ZXIuICBEb24ndCBrbm93IHdoeS4KLSAgICAgICAgICAgICAgICBjYXNlIDAgOgotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgY2FzZSAxIDoKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgY2hhciBjaCA9IGtleS5jaGFyQXQoMCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2ggPCBBTFBIQV9TSVpFKQotICAgICAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUgPSBub2RlLm1fbmV4dENoYXJbY2hdOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChub2RlICE9IG51bGwpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBub2RlLm1fVmFsdWU7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAvLyAgICAgICAgICAgICAgICBjb21tZW50IG91dCBjYXNlIDIgYmVjYXVzZSB0aGUgZGVmYXVsdCBpcyBmYXN0ZXIKLSAgICAgICAgICAgICAgICAgICAgLy8gICAgICAgICAgICAgICAgY2FzZSAyIDoKLSAgICAgICAgICAgICAgICAgICAgLy8gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBjaGFyIGNoMCA9IGtleS5jaGFyQXQoMCk7Ci0gICAgICAgICAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgY2hhciBjaDEgPSBrZXkuY2hhckF0KDEpOwotICAgICAgICAgICAgICAgICAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjaDAgPCBBTFBIQV9TSVpFICYmIGNoMSA8IEFMUEhBX1NJWkUpCi0gICAgICAgICAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlID0gbm9kZS5tX25leHRDaGFyW2NoMF07Ci0gICAgICAgICAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChub2RlICE9IG51bGwpCi0gICAgICAgICAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICAgICAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjaDEgPCBBTFBIQV9TSVpFKQotICAgICAgICAgICAgICAgICAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUgPSBub2RlLm1fbmV4dENoYXJbY2gxXTsKLSAgICAgICAgICAgICAgICAgICAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobm9kZSAhPSBudWxsKQotICAgICAgICAgICAgICAgICAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbm9kZS5tX1ZhbHVlOwotICAgICAgICAgICAgICAgICAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICAgICAgICAgICAgICAvLyAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZGVmYXVsdCA6Ci0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuOyBpKyspCi0gICAgICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQSB0aHJlYWQtc2FmZSB3YXkgdG8gbG9vcCBvdmVyIHRoZSBjaGFyYWN0ZXJzCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgY2hhciBjaCA9IGtleS5jaGFyQXQoaSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKEFMUEhBX1NJWkUgPD0gY2gpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGUga2V5IGlzIG5vdCA3LWJpdCBBU0NJSSBzbyB3ZSB3b24ndCBmaW5kIGl0IGhlcmUKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZSA9IG5vZGUubV9uZXh0Q2hhcltjaF07Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5vZGUgPT0gbnVsbCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBub2RlLm1fVmFsdWU7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBUaGUgbm9kZSByZXByZXNlbnRhdGlvbiBmb3IgdGhlIHRyaWUuCi0gICAgICAgICAqIEB4c2wudXNhZ2UgaW50ZXJuYWwKLSAgICAgICAgICovCi0gICAgICAgIHByaXZhdGUgY2xhc3MgTm9kZQotICAgICAgICB7Ci0KLSAgICAgICAgICAgIC8qKgotICAgICAgICAgICAgICogQ29uc3RydWN0b3IsIGNyZWF0ZXMgYSBOb2RlW0FMUEhBX1NJWkVdLgotICAgICAgICAgICAgICovCi0gICAgICAgICAgICBOb2RlKCkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBtX25leHRDaGFyID0gbmV3IE5vZGVbQUxQSEFfU0laRV07Ci0gICAgICAgICAgICAgICAgbV9WYWx1ZSA9IG51bGw7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8qKiBUaGUgbmV4dCBub2Rlcy4gICAqLwotICAgICAgICAgICAgZmluYWwgTm9kZSBtX25leHRDaGFyW107Ci0KLSAgICAgICAgICAgIC8qKiBUaGUgdmFsdWUuICAgKi8KLSAgICAgICAgICAgIE9iamVjdCBtX1ZhbHVlOwotICAgICAgICB9Ci0gICAgICAgIC8qKgotICAgICAgICAgKiBDb25zdHJ1Y3QgdGhlIHRyaWUgZnJvbSBhbm90aGVyIFRyaWUuCi0gICAgICAgICAqIEJvdGggdGhlIGV4aXN0aW5nIFRyaWUgYW5kIHRoaXMgbmV3IG9uZSBzaGFyZSB0aGUgc2FtZSB0YWJsZSBmb3IKLSAgICAgICAgICogbG9va3VwLCBhbmQgaXQgaXMgYXNzdW1lZCB0aGF0IHRoZSB0YWJsZSBpcyBmdWxseSBwb3B1bGF0ZWQgYW5kCi0gICAgICAgICAqIG5vdCBjaGFuZ2luZyBhbnltb3JlLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gZXhpc3RpbmdUcmllIHRoZSBUcmllIHRoYXQgdGhpcyBvbmUgaXMgYSBjb3B5IG9mLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIFRyaWUoVHJpZSBleGlzdGluZ1RyaWUpCi0gICAgICAgIHsKLSAgICAgICAgICAgIC8vIGNvcHkgc29tZSBmaWVsZHMgZnJvbSB0aGUgZXhpc3RpbmcgVHJpZSBpbnRvIHRoaXMgb25lLgotICAgICAgICAgICAgbV9Sb290ID0gZXhpc3RpbmdUcmllLm1fUm9vdDsKLSAgICAgICAgICAgIG1fbG93ZXJDYXNlT25seSA9IGV4aXN0aW5nVHJpZS5tX2xvd2VyQ2FzZU9ubHk7Ci0KLSAgICAgICAgICAgIC8vIGdldCBhIGJ1ZmZlciBqdXN0IGJpZyBlbm91Z2ggdG8gaG9sZCB0aGUgbG9uZ2VzdCBrZXkgaW4gdGhlIHRhYmxlLgotICAgICAgICAgICAgaW50IG1heCA9IGV4aXN0aW5nVHJpZS5nZXRMb25nZXN0S2V5TGVuZ3RoKCk7Ci0gICAgICAgICAgICBtX2NoYXJCdWZmZXIgPSBuZXcgY2hhclttYXhdOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIEdldCBhbiBvYmplY3QgdGhhdCBtYXRjaGVzIHRoZSBrZXkuCi0gICAgICAgICAqIFRoaXMgbWV0aG9kIGlzIGZhc3RlciB0aGFuIGdldCgpLCBidXQgaXMgbm90IHRocmVhZC1zYWZlLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0ga2V5IG11c3QgYmUgYSA3LWJpdCBBU0NJSSBzdHJpbmcKLSAgICAgICAgICoKLSAgICAgICAgICogQHJldHVybiBUaGUgb2JqZWN0IHRoYXQgbWF0Y2hlcyB0aGUga2V5LCBvciBudWxsLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIE9iamVjdCBnZXQyKGZpbmFsIFN0cmluZyBrZXkpCi0gICAgICAgIHsKLQotICAgICAgICAgICAgZmluYWwgaW50IGxlbiA9IGtleS5sZW5ndGgoKTsKLQotICAgICAgICAgICAgLyogSWYgdGhlIG5hbWUgaXMgdG9vIGxvbmcsIHdlIHdvbid0IGZpbmQgaXQsIHRoaXMgYWxzbyBrZWVwcyB1cwotICAgICAgICAgICAgICogZnJvbSBvdmVyZmxvd2luZyBtX2NoYXJCdWZmZXIKLSAgICAgICAgICAgICAqLwotICAgICAgICAgICAgaWYgKG1fY2hhckJ1ZmZlci5sZW5ndGggPCBsZW4pCi0gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0KLSAgICAgICAgICAgIE5vZGUgbm9kZSA9IG1fUm9vdDsKLSAgICAgICAgICAgIHN3aXRjaCAobGVuKSAvLyBvcHRpbWl6ZSB0aGUgbG9vayB1cCBiYXNlZCBvbiB0aGUgbnVtYmVyIG9mIGNoYXJzCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgLy8gY2FzZSAwIGxvb2tzIHNpbGx5LCBidXQgdGhlIGdlbmVyYXRlZCBieXRlY29kZSBydW5zCi0gICAgICAgICAgICAgICAgLy8gZmFzdGVyIGZvciBsb29rdXAgb2YgZWxlbWVudHMgb2YgbGVuZ3RoIDIgd2l0aCB0aGlzIGluCi0gICAgICAgICAgICAgICAgLy8gYW5kIGEgZmFpciBiaXQgZmFzdGVyLiAgRG9uJ3Qga25vdyB3aHkuCi0gICAgICAgICAgICAgICAgY2FzZSAwIDoKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIGNhc2UgMSA6Ci0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGNoYXIgY2ggPSBrZXkuY2hhckF0KDApOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNoIDwgQUxQSEFfU0laRSkKLSAgICAgICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlID0gbm9kZS5tX25leHRDaGFyW2NoXTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobm9kZSAhPSBudWxsKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbm9kZS5tX1ZhbHVlOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBkZWZhdWx0IDoKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgLyogQ29weSBzdHJpbmcgaW50byBhcnJheS4gVGhpcyBpcyBub3QgdGhyZWFkLXNhZmUgYmVjYXVzZQotICAgICAgICAgICAgICAgICAgICAgICAgICogaXQgbW9kaWZpZXMgdGhlIGNvbnRlbnRzIG9mIG1fY2hhckJ1ZmZlci4gSWYgbXVsdGlwbGUKLSAgICAgICAgICAgICAgICAgICAgICAgICAqIHRocmVhZHMgd2VyZSB0byB1c2UgdGhpcyBUcmllIHRoZXkgYWxsIHdvdWxkIGJlCi0gICAgICAgICAgICAgICAgICAgICAgICAgKiB1c2luZyB0aGlzIHNhbWUgYXJyYXkgKG5vdCBnb29kKS4gU28gdGhpcwotICAgICAgICAgICAgICAgICAgICAgICAgICogbWV0aG9kIGlzIG5vdCB0aHJlYWQtc2FmZSwgYnV0IGl0IGlzIGZhc3RlciBiZWNhdXNlCi0gICAgICAgICAgICAgICAgICAgICAgICAgKiBjb252ZXJ0aW5nIHRvIGEgY2hhcltdIGFuZCBsb29waW5nIG92ZXIgZWxlbWVudHMgb2YKLSAgICAgICAgICAgICAgICAgICAgICAgICAqIHRoZSBhcnJheSBpcyBmYXN0ZXIgdGhhbiBhIFN0cmluZydzIGNoYXJBdChpKS4KLSAgICAgICAgICAgICAgICAgICAgICAgICAqLwotICAgICAgICAgICAgICAgICAgICAgICAga2V5LmdldENoYXJzKDAsIGxlbiwgbV9jaGFyQnVmZmVyLCAwKTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW47IGkrKykKLSAgICAgICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBjaGFyIGNoID0gbV9jaGFyQnVmZmVyW2ldOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChBTFBIQV9TSVpFIDw9IGNoKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhlIGtleSBpcyBub3QgNy1iaXQgQVNDSUkgc28gd2Ugd29uJ3QgZmluZCBpdCBoZXJlCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUgPSBub2RlLm1fbmV4dENoYXJbY2hdOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChub2RlID09IG51bGwpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbm9kZS5tX1ZhbHVlOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogR2V0IHRoZSBsZW5ndGggb2YgdGhlIGxvbmdlc3Qga2V5IHVzZWQgaW4gdGhlIHRhYmxlLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIGludCBnZXRMb25nZXN0S2V5TGVuZ3RoKCkKLSAgICAgICAgewotICAgICAgICAgICAgcmV0dXJuIG1fY2hhckJ1ZmZlci5sZW5ndGg7Ci0gICAgICAgIH0KLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1RvU0FYSGFuZGxlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9Ub1NBWEhhbmRsZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZTZiYzcwYS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1RvU0FYSGFuZGxlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDQwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFRvU0FYSGFuZGxlci5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzIyIDExOjAzOjE1IHB2ZWR1bGEgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXI7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgb3JnLnhtbC5zYXguQXR0cmlidXRlczsKLWltcG9ydCBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5FcnJvckhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWFBhcnNlRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LmV4dC5MZXhpY2FsSGFuZGxlcjsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGlzIHVzZWQgdG8gcHJvdmlkZSBhIGJhc2UgYmVoYXZpb3IgdG8gYmUgaW5oZXJpdGVkCi0gKiBieSBvdGhlciBUby4uLlNBWEhhbmRsZXIgc2VyaWFsaXplcnMuCi0gKgotICogVGhpcyBjbGFzcyBpcyBub3QgYSBwdWJsaWMgQVBJLgotICoKLSAqIEB4c2wudXNhZ2UgaW50ZXJuYWwKLSAqLwotcHVibGljIGFic3RyYWN0IGNsYXNzIFRvU0FYSGFuZGxlciBleHRlbmRzIFNlcmlhbGl6ZXJCYXNlCi17Ci0gICAgcHVibGljIFRvU0FYSGFuZGxlcigpCi0gICAgewotICAgIH0KLQotICAgIHB1YmxpYyBUb1NBWEhhbmRsZXIoCi0gICAgICAgIENvbnRlbnRIYW5kbGVyIGhkbHIsCi0gICAgICAgIExleGljYWxIYW5kbGVyIGxleCwKLSAgICAgICAgU3RyaW5nIGVuY29kaW5nKQotICAgIHsKLSAgICAgICAgc2V0Q29udGVudEhhbmRsZXIoaGRscik7Ci0gICAgICAgIHNldExleEhhbmRsZXIobGV4KTsKLSAgICAgICAgc2V0RW5jb2RpbmcoZW5jb2RpbmcpOwotICAgIH0KLSAgICBwdWJsaWMgVG9TQVhIYW5kbGVyKENvbnRlbnRIYW5kbGVyIGhhbmRsZXIsIFN0cmluZyBlbmNvZGluZykKLSAgICB7Ci0gICAgICAgIHNldENvbnRlbnRIYW5kbGVyKGhhbmRsZXIpOwotICAgICAgICBzZXRFbmNvZGluZyhlbmNvZGluZyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVW5kZXJseWluZyBTQVggaGFuZGxlci4gVGFrZW4gZnJvbSBYU0xUQwotICAgICAqLwotICAgIHByb3RlY3RlZCBDb250ZW50SGFuZGxlciBtX3NheEhhbmRsZXI7Ci0KLSAgICAvKioKLSAgICAgKiBVbmRlcmx5aW5nIExleGljYWxIYW5kbGVyLiBUYWtlbiBmcm9tIFhTTFRDCi0gICAgICovCi0gICAgcHJvdGVjdGVkIExleGljYWxIYW5kbGVyIG1fbGV4SGFuZGxlcjsKLQotICAgIC8qKgotICAgICAqIEEgc3RhcnRQcmVmaXhNYXBwaW5nKCkgY2FsbCBvbiBhIFRvU0FYSGFuZGxlciB3aWxsIHBhc3MgdGhhdCBjYWxsCi0gICAgICogb24gdG8gdGhlIHdyYXBwZWQgQ29udGVudEhhbmRsZXIsIGJ1dCBzaG91bGQgd2UgYWxzbyBtaXJyb3IgdGhlc2UgY2FsbHMKLSAgICAgKiB3aXRoIG1hdGNoaW5nIGF0dHJpYnV0ZXMsIGlmIHNvIHRoaXMgZmllbGQgaXMgdHJ1ZS4KLSAgICAgKiBGb3IgZXhhbXBsZSBpZiB0aGlzIGZpZWxkIGlzIHRydWUgdGhlbiBhIGNhbGwgc3VjaCBhcwotICAgICAqIHN0YXJ0UHJlZml4TWFwcGluZygicHJlZml4MSIsInVyaTEiKSB3aWxsIGFsc28gY2F1c2UgdGhlIGFkZGl0aW9uYWwKLSAgICAgKiBpbnRlcm5hbGx5IGdlbmVyYXRlZCBhdHRyaWJ1dGUgeG1sbnM6cHJlZml4MT0idXJpMSIgdG8gYmUgZWZmZWN0aXZlbHkgYWRkZWQKLSAgICAgKiB0byB0aGUgYXR0cmlidXRlcyBwYXNzZWQgdG8gdGhlIHdyYXBwZWQgQ29udGVudEhhbmRsZXIuCi0gICAgICovCi0gICAgcHJpdmF0ZSBib29sZWFuIG1fc2hvdWxkR2VuZXJhdGVOU0F0dHJpYnV0ZSA9IHRydWU7Ci0KLSAgICAvKiogSWYgdGhpcyBpcyB0cnVlLCB0aGVuIHRoZSBjb250ZW50IGhhbmRsZXIgd3JhcHBlZCBieSB0aGlzCi0gICAgICogc2VyaWFsaXplciBpbXBsZW1lbnRzIHRoZSBUcmFuc2Zvcm1TdGF0ZSBpbnRlcmZhY2Ugd2hpY2gKLSAgICAgKiB3aWxsIGdpdmUgdGhlIGNvbnRlbnQgaGFuZGxlciBhY2Nlc3MgdG8gdGhlIHN0YXRlIG9mCi0gICAgICogdGhlIHRyYW5zZm9ybS4gKi8KLSAgICBwcm90ZWN0ZWQgVHJhbnNmb3JtU3RhdGVTZXR0ZXIgbV9zdGF0ZSA9IG51bGw7Ci0KLSAgICAvKioKLSAgICAgKiBQYXNzIGNhbGxiYWNrIHRvIHRoZSBTQVggSGFuZGxlcgotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIHN0YXJ0RG9jdW1lbnRJbnRlcm5hbCgpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGlmIChtX25lZWRUb0NhbGxTdGFydERvY3VtZW50KQotICAgICAgICB7Ci0gICAgICAgICAgICBzdXBlci5zdGFydERvY3VtZW50SW50ZXJuYWwoKTsKLQotICAgICAgICAgICAgbV9zYXhIYW5kbGVyLnN0YXJ0RG9jdW1lbnQoKTsKLSAgICAgICAgICAgIG1fbmVlZFRvQ2FsbFN0YXJ0RG9jdW1lbnQgPSBmYWxzZTsKLSAgICAgICAgfQotICAgIH0KLSAgICAvKioKLSAgICAgKiBEbyBub3RoaW5nLgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguZXh0LkxleGljYWxIYW5kbGVyI3N0YXJ0RFREKFN0cmluZywgU3RyaW5nLCBTdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnREVEQoU3RyaW5nIGFyZzAsIFN0cmluZyBhcmcxLCBTdHJpbmcgYXJnMikKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgLy8gZG8gbm90aGluZyBmb3Igbm93Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgY2hhcmFjdGVyIGRhdGEuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY2hhcmFjdGVycyBUaGUgc3RyaW5nIG9mIGNoYXJhY3RlcnMgdG8gcHJvY2Vzcy4KLSAgICAgKgotICAgICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAgICoKLSAgICAgKiBAc2VlIEV4dGVuZGVkQ29udGVudEhhbmRsZXIjY2hhcmFjdGVycyhTdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY2hhcmFjdGVycyhTdHJpbmcgY2hhcmFjdGVycykgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgZmluYWwgaW50IGxlbiA9IGNoYXJhY3RlcnMubGVuZ3RoKCk7Ci0gICAgICAgIGlmIChsZW4gPiBtX2NoYXJzQnVmZi5sZW5ndGgpCi0gICAgICAgIHsKLSAgICAgICAgICAgbV9jaGFyc0J1ZmYgPSBuZXcgY2hhcltsZW4qMiArIDFdOwotICAgICAgICB9Ci0gICAgICAgIGNoYXJhY3RlcnMuZ2V0Q2hhcnMoMCxsZW4sIG1fY2hhcnNCdWZmLCAwKTsKLSAgICAgICAgY2hhcmFjdGVycyhtX2NoYXJzQnVmZiwgMCwgbGVuKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBhIGNvbW1lbnQuCi0gICAgICoKLSAgICAgKiBAc2VlIEV4dGVuZGVkTGV4aWNhbEhhbmRsZXIjY29tbWVudChTdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY29tbWVudChTdHJpbmcgY29tbWVudCkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgZmx1c2hQZW5kaW5nKCk7Ci0KLSAgICAgICAgLy8gSWdub3JlIGlmIGEgbGV4aWNhbCBoYW5kbGVyIGhhcyBub3QgYmVlbiBzZXQKLSAgICAgICAgaWYgKG1fbGV4SGFuZGxlciAhPSBudWxsKQotICAgICAgICB7Ci0gICAgICAgICAgICBmaW5hbCBpbnQgbGVuID0gY29tbWVudC5sZW5ndGgoKTsKLSAgICAgICAgICAgIGlmIChsZW4gPiBtX2NoYXJzQnVmZi5sZW5ndGgpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICBtX2NoYXJzQnVmZiA9IG5ldyBjaGFyW2xlbioyICsgMV07Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjb21tZW50LmdldENoYXJzKDAsbGVuLCBtX2NoYXJzQnVmZiwgMCk7Ci0gICAgICAgICAgICBtX2xleEhhbmRsZXIuY29tbWVudChtX2NoYXJzQnVmZiwgMCwgbGVuKTsKLSAgICAgICAgICAgIC8vIHRpbWUgdG8gZmlyZSBvZmYgY29tbWVudCBldmVudAotICAgICAgICAgICAgaWYgKG1fdHJhY2VyICE9IG51bGwpCi0gICAgICAgICAgICAgICAgc3VwZXIuZmlyZUNvbW1lbnRFdmVudChtX2NoYXJzQnVmZiwgMCwgbGVuKTsKLSAgICAgICAgfQotCi0gICAgfQotCi0gICAgLyoqCi0gICAgICogRG8gbm90aGluZyBhcyB0aGlzIGlzIGFuIGFic3RyYWN0IGNsYXNzLiBBbGwgc3ViY2xhc3NlcyB3aWxsIG5lZWQgdG8KLSAgICAgKiBkZWZpbmUgdGhlaXIgYmVoYXZpb3IgaWYgaXQgaXMgZGlmZmVyZW50LgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjcHJvY2Vzc2luZ0luc3RydWN0aW9uKFN0cmluZywgU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHByb2Nlc3NpbmdJbnN0cnVjdGlvbihTdHJpbmcgdGFyZ2V0LCBTdHJpbmcgZGF0YSkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgLy8gUmVkZWZpbmVkIGluIFNBWFhNTE91dHB1dAotICAgIH0KLQotICAgIHByb3RlY3RlZCB2b2lkIGNsb3NlU3RhcnRUYWcoKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgIH0KLQotICAgIHByb3RlY3RlZCB2b2lkIGNsb3NlQ0RBVEEoKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICAvLyBSZWRlZmluZWQgaW4gU0FYWE1MT3V0cHV0Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIGJlZ2lubmluZyBvZiBhbiBlbGVtZW50LCBhbHRob3VnaCB0aGlzIGlzIGEKLSAgICAgKiBTQVggbWV0aG9kIGFkZGl0aW9uYWwgbmFtZXNwYWNlIG9yIGF0dHJpYnV0ZSBpbmZvcm1hdGlvbiBjYW4gb2NjdXIgYmVmb3JlCi0gICAgICogb3IgYWZ0ZXIgdGhpcyBjYWxsLCB0aGF0IGlzIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGVsZW1lbnQuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjc3RhcnRFbGVtZW50Ci0gICAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNlbmRFbGVtZW50Ci0gICAgICogQHNlZSBvcmcueG1sLnNheC5BdHRyaWJ1dGVMaXN0Ci0gICAgICoKLSAgICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgICAqCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNzdGFydEVsZW1lbnQoU3RyaW5nLFN0cmluZyxTdHJpbmcsQXR0cmlidXRlcykKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQoCi0gICAgICAgIFN0cmluZyBhcmcwLAotICAgICAgICBTdHJpbmcgYXJnMSwKLSAgICAgICAgU3RyaW5nIGFyZzIsCi0gICAgICAgIEF0dHJpYnV0ZXMgYXJnMykKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaWYgKG1fc3RhdGUgIT0gbnVsbCkgewotICAgICAgICAgICAgbV9zdGF0ZS5yZXNldFN0YXRlKGdldFRyYW5zZm9ybWVyKCkpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gZmlyZSBvZmYgdGhlIHN0YXJ0IGVsZW1lbnQgZXZlbnQKLSAgICAgICAgaWYgKG1fdHJhY2VyICE9IG51bGwpCi0gICAgICAgICAgICBzdXBlci5maXJlU3RhcnRFbGVtKGFyZzIpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIExleGljYWxIYW5kbGVyLgotICAgICAqIEBwYXJhbSBfbGV4SGFuZGxlciBUaGUgTGV4aWNhbEhhbmRsZXIgdG8gc2V0Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0TGV4SGFuZGxlcihMZXhpY2FsSGFuZGxlciBfbGV4SGFuZGxlcikKLSAgICB7Ci0gICAgICAgIHRoaXMubV9sZXhIYW5kbGVyID0gX2xleEhhbmRsZXI7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0cyB0aGUgU0FYIENvbnRlbnRIYW5kbGVyLgotICAgICAqIEBwYXJhbSBfc2F4SGFuZGxlciBUaGUgQ29udGVudEhhbmRsZXIgdG8gc2V0Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0Q29udGVudEhhbmRsZXIoQ29udGVudEhhbmRsZXIgX3NheEhhbmRsZXIpCi0gICAgewotICAgICAgICB0aGlzLm1fc2F4SGFuZGxlciA9IF9zYXhIYW5kbGVyOwotICAgICAgICBpZiAobV9sZXhIYW5kbGVyID09IG51bGwgJiYgX3NheEhhbmRsZXIgaW5zdGFuY2VvZiBMZXhpY2FsSGFuZGxlcikKLSAgICAgICAgewotICAgICAgICAgICAgLy8gd2UgYXJlIG5vdCBvdmVyd3JpdGluZyBhbiBleGlzdGluZyBMZXhpY2FsSGFuZGxlciwgYW5kIF9zYXhIYW5kbGVyCi0gICAgICAgICAgICAvLyBpcyBhbHNvIGltcGxlbWVudHMgTGV4aWNhbEhhbmRsZXIsIHNvIGxldHMgdXNlIGl0Ci0gICAgICAgICAgICBtX2xleEhhbmRsZXIgPSAoTGV4aWNhbEhhbmRsZXIpIF9zYXhIYW5kbGVyOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRG9lcyBub3RoaW5nLiBUaGUgc2V0dGluZyBvZiBDREFUQSBzZWN0aW9uIGVsZW1lbnRzIGhhcyBhbiBpbXBhY3Qgb24KLSAgICAgKiBzdHJlYW0gc2VyaWFsaXplcnMuCi0gICAgICogQHNlZSBTZXJpYWxpemF0aW9uSGFuZGxlciNzZXRDZGF0YVNlY3Rpb25FbGVtZW50cyhqYXZhLnV0aWwuVmVjdG9yKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldENkYXRhU2VjdGlvbkVsZW1lbnRzKFZlY3RvciBVUklfYW5kX2xvY2FsTmFtZXMpCi0gICAgewotICAgICAgICAvLyBkbyBub3RoaW5nCi0gICAgfQotCi0gICAgLyoqIFNldCB3aGV0aGVyIG9yIG5vdCBuYW1lc3BhY2UgZGVjbGFyYXRpb25zIChlLmcuCi0gICAgICogeG1sbnM6Zm9vKSBzaG91bGQgYXBwZWFyIGFzIGF0dHJpYnV0ZXMgb2YKLSAgICAgKiBlbGVtZW50cwotICAgICAqIEBwYXJhbSBkb091dHB1dE5TQXR0ciB3aGV0aGVyIG9yIG5vdCBuYW1lc3BhY2UgZGVjbGFyYXRpb25zCi0gICAgICogc2hvdWxkIGFwcGVhciBhcyBhdHRyaWJ1dGVzCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0U2hvdWxkT3V0cHV0TlNBdHRyKGJvb2xlYW4gZG9PdXRwdXROU0F0dHIpCi0gICAgewotICAgICAgICBtX3Nob3VsZEdlbmVyYXRlTlNBdHRyaWJ1dGUgPSBkb091dHB1dE5TQXR0cjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRydWUgaWYgbmFtZXNwYWNlIGRlY2xhcmF0aW9ucyBmcm9tIGNhbGxzIHN1Y2ggYXMKLSAgICAgKiBzdGFydFByZWZpeE1hcHBpbmcoInByZWZpeDEiLCJ1cmkxIikgc2hvdWxkCi0gICAgICogYWxzbyBiZSBtaXJyb3JlZCB3aXRoIHNlbGYgZ2VuZXJhdGVkIGFkZGl0aW9uYWwgYXR0cmlidXRlcyBvZiBlbGVtZW50cwotICAgICAqIHRoYXQgZGVjbGFyZSB0aGUgbmFtZXNwYWNlLCBmb3IgZXhhbXBsZSB0aGUgYXR0cmlidXRlIHhtbG5zOnByZWZpeDE9InVyaTEiCi0gICAgICovCi0gICAgYm9vbGVhbiBnZXRTaG91bGRPdXRwdXROU0F0dHIoKQotICAgIHsKLSAgICAgICAgcmV0dXJuIG1fc2hvdWxkR2VuZXJhdGVOU0F0dHJpYnV0ZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBmbHVzaGVzIGFueSBwZW5kaW5nIGV2ZW50cywgd2hpY2ggY2FuIGJlIHN0YXJ0RG9jdW1lbnQoKQotICAgICAqIGNsb3NpbmcgdGhlIG9wZW5pbmcgdGFnIG9mIGFuIGVsZW1lbnQsIG9yIGNsb3NpbmcgYW4gb3BlbiBDREFUQSBzZWN0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGZsdXNoUGVuZGluZygpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0KLSAgICAgICAgICAgIGlmIChtX25lZWRUb0NhbGxTdGFydERvY3VtZW50KQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIHN0YXJ0RG9jdW1lbnRJbnRlcm5hbCgpOwotICAgICAgICAgICAgICAgIG1fbmVlZFRvQ2FsbFN0YXJ0RG9jdW1lbnQgPSBmYWxzZTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKG1fZWxlbUNvbnRleHQubV9zdGFydFRhZ09wZW4pCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgY2xvc2VTdGFydFRhZygpOwotICAgICAgICAgICAgICAgIG1fZWxlbUNvbnRleHQubV9zdGFydFRhZ09wZW4gPSBmYWxzZTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKG1fY2RhdGFUYWdPcGVuKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIGNsb3NlQ0RBVEEoKTsKLSAgICAgICAgICAgICAgICBtX2NkYXRhVGFnT3BlbiA9IGZhbHNlOwotICAgICAgICAgICAgfQotCi0gICAgfQotCi0gICAgLyoqCi0gICAgICogUGFzcyBpbiBhIHJlZmVyZW5jZSB0byBhIFRyYW5zZm9ybVN0YXRlIG9iamVjdCwgd2hpY2gKLSAgICAgKiBjYW4gYmUgdXNlZCBkdXJpbmcgU0FYIENvbnRlbnRIYW5kbGVyIGV2ZW50cyB0byBvYnRhaW4KLSAgICAgKiBpbmZvcm1hdGlvbiBhYm91dCBoZSBzdGF0ZSBvZiB0aGUgdHJhbnNmb3JtYXRpb24uIFRoaXMKLSAgICAgKiBtZXRob2Qgd2lsbCBiZSBjYWxsZWQgIGJlZm9yZSBlYWNoIHN0YXJ0RG9jdW1lbnQgZXZlbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdHMgQSByZWZlcmVuY2UgdG8gYSBUcmFuc2Zvcm1TdGF0ZSBvYmplY3QKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRUcmFuc2Zvcm1TdGF0ZShUcmFuc2Zvcm1TdGF0ZVNldHRlciB0cykgewotICAgICAgICB0aGlzLm1fc3RhdGUgPSB0czsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZWNlaXZlcyBub3RpZmljYXRpb24gdGhhdCBhbiBlbGVtZW50IHN0YXJ0cywgYnV0IGF0dHJpYnV0ZXMgYXJlIG5vdAotICAgICAqIGZ1bGx5IGtub3duIHlldC4KLSAgICAgKgotICAgICAqIEBwYXJhbSB1cmkgdGhlIFVSSSBvZiB0aGUgbmFtZXNwYWNlIG9mIHRoZSBlbGVtZW50IChvcHRpb25hbCkKLSAgICAgKiBAcGFyYW0gbG9jYWxOYW1lIHRoZSBlbGVtZW50IG5hbWUsIGJ1dCB3aXRob3V0IHByZWZpeCAob3B0aW9uYWwpCi0gICAgICogQHBhcmFtIHFOYW1lIHRoZSBlbGVtZW50IG5hbWUsIHdpdGggcHJlZml4LCBpZiBhbnkgKHJlcXVpcmVkKQotICAgICAqCi0gICAgICogQHNlZSBFeHRlbmRlZENvbnRlbnRIYW5kbGVyI3N0YXJ0RWxlbWVudChTdHJpbmcsIFN0cmluZywgU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudChTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxOYW1lLCBTdHJpbmcgcU5hbWUpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24gewotCi0gICAgICAgIGlmIChtX3N0YXRlICE9IG51bGwpIHsKLSAgICAgICAgICAgIG1fc3RhdGUucmVzZXRTdGF0ZShnZXRUcmFuc2Zvcm1lcigpKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIGZpcmUgb2ZmIHRoZSBzdGFydCBlbGVtZW50IGV2ZW50Ci0gICAgICAgIGlmIChtX3RyYWNlciAhPSBudWxsKQotICAgICAgICAgICAgc3VwZXIuZmlyZVN0YXJ0RWxlbShxTmFtZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQW4gZWxlbWVudCBzdGFydHMsIGJ1dCBhdHRyaWJ1dGVzIGFyZSBub3QgZnVsbHkga25vd24geWV0LgotICAgICAqCi0gICAgICogQHBhcmFtIHFOYW1lIHRoZSBlbGVtZW50IG5hbWUsIHdpdGggcHJlZml4IChpZiBhbnkpLgotCi0gICAgICogQHNlZSBFeHRlbmRlZENvbnRlbnRIYW5kbGVyI3N0YXJ0RWxlbWVudChTdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnRFbGVtZW50KFN0cmluZyBxTmFtZSkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChtX3N0YXRlICE9IG51bGwpIHsKLSAgICAgICAgICAgIG1fc3RhdGUucmVzZXRTdGF0ZShnZXRUcmFuc2Zvcm1lcigpKTsKLSAgICAgICAgfQotICAgICAgICAvLyBmaXJlIG9mZiB0aGUgc3RhcnQgZWxlbWVudCBldmVudAotICAgICAgICBpZiAobV90cmFjZXIgIT0gbnVsbCkKLSAgICAgICAgICAgIHN1cGVyLmZpcmVTdGFydEVsZW0ocU5hbWUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIGdldHMgdGhlIG5vZGUncyB2YWx1ZSBhcyBhIFN0cmluZyBhbmQgdXNlcyB0aGF0IFN0cmluZyBhcyBpZgotICAgICAqIGl0IHdlcmUgYW4gaW5wdXQgY2hhcmFjdGVyIG5vdGlmaWNhdGlvbi4KLSAgICAgKiBAcGFyYW0gbm9kZSB0aGUgTm9kZSB0byBzZXJpYWxpemUKLSAgICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGNoYXJhY3RlcnMob3JnLnczYy5kb20uTm9kZSBub2RlKQotICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICAvLyByZW1lbWJlciB0aGUgY3VycmVudCBub2RlCi0gICAgICAgIGlmIChtX3N0YXRlICE9IG51bGwpCi0gICAgICAgIHsKLSAgICAgICAgICAgIG1fc3RhdGUuc2V0Q3VycmVudE5vZGUobm9kZSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBHZXQgdGhlIG5vZGUncyB2YWx1ZSBhcyBhIFN0cmluZyBhbmQgdXNlIHRoYXQgU3RyaW5nIGFzIGlmCi0gICAgICAgIC8vIGl0IHdlcmUgYW4gaW5wdXQgY2hhcmFjdGVyIG5vdGlmaWNhdGlvbi4KLSAgICAgICAgU3RyaW5nIGRhdGEgPSBub2RlLmdldE5vZGVWYWx1ZSgpOwotICAgICAgICBpZiAoZGF0YSAhPSBudWxsKSB7Ci0gICAgICAgICAgICB0aGlzLmNoYXJhY3RlcnMoZGF0YSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkVycm9ySGFuZGxlciNmYXRhbEVycm9yKFNBWFBhcnNlRXhjZXB0aW9uKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGZhdGFsRXJyb3IoU0FYUGFyc2VFeGNlcHRpb24gZXhjKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICAgICAgc3VwZXIuZmF0YWxFcnJvcihleGMpOwotCi0gICAgICAgIG1fbmVlZFRvQ2FsbFN0YXJ0RG9jdW1lbnQgPSBmYWxzZTsKLQotICAgICAgICBpZiAobV9zYXhIYW5kbGVyIGluc3RhbmNlb2YgRXJyb3JIYW5kbGVyKSB7Ci0gICAgICAgICAgICAoKEVycm9ySGFuZGxlciltX3NheEhhbmRsZXIpLmZhdGFsRXJyb3IoZXhjKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguRXJyb3JIYW5kbGVyI2Vycm9yKFNBWFBhcnNlRXhjZXB0aW9uKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVycm9yKFNBWFBhcnNlRXhjZXB0aW9uIGV4YykgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0gICAgICAgIHN1cGVyLmVycm9yKGV4Yyk7Ci0KLSAgICAgICAgaWYgKG1fc2F4SGFuZGxlciBpbnN0YW5jZW9mIEVycm9ySGFuZGxlcikKLSAgICAgICAgICAgICgoRXJyb3JIYW5kbGVyKW1fc2F4SGFuZGxlcikuZXJyb3IoZXhjKTsKLQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguRXJyb3JIYW5kbGVyI3dhcm5pbmcoU0FYUGFyc2VFeGNlcHRpb24pCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgd2FybmluZyhTQVhQYXJzZUV4Y2VwdGlvbiBleGMpIHRocm93cyBTQVhFeGNlcHRpb24gewotICAgICAgICBzdXBlci53YXJuaW5nKGV4Yyk7Ci0KLSAgICAgICAgaWYgKG1fc2F4SGFuZGxlciBpbnN0YW5jZW9mIEVycm9ySGFuZGxlcikKLSAgICAgICAgICAgICgoRXJyb3JIYW5kbGVyKW1fc2F4SGFuZGxlcikud2FybmluZyhleGMpOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogVHJ5J3MgdG8gcmVzZXQgdGhlIHN1cGVyIGNsYXNzIGFuZCByZXNldCB0aGlzIGNsYXNzIGZvcgotICAgICAqIHJlLXVzZSwgc28gdGhhdCB5b3UgZG9uJ3QgbmVlZCB0byBjcmVhdGUgYSBuZXcgc2VyaWFsaXplcgotICAgICAqIChtb3N0bHkgZm9yIHBlcmZvcm1hbmNlIHJlYXNvbnMpLgotICAgICAqCi0gICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBjbGFzcyB3YXMgc3VjY2Vzc2Z1bHkgcmVzZXQuCi0gICAgICogQHNlZSBTZXJpYWxpemVyI3Jlc2V0KCkKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiByZXNldCgpCi0gICAgewotICAgICAgICBib29sZWFuIHdhc1Jlc2V0ID0gZmFsc2U7Ci0gICAgICAgIGlmIChzdXBlci5yZXNldCgpKQotICAgICAgICB7Ci0gICAgICAgICAgICByZXNldFRvU0FYSGFuZGxlcigpOwotICAgICAgICAgICAgd2FzUmVzZXQgPSB0cnVlOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiB3YXNSZXNldDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXNldCBhbGwgb2YgdGhlIGZpZWxkcyBvd25lZCBieSBUb1NBWEhhbmRsZXIgY2xhc3MKLSAgICAgKgotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCByZXNldFRvU0FYSGFuZGxlcigpCi0gICAgewotICAgICAgICB0aGlzLm1fbGV4SGFuZGxlciA9IG51bGw7Ci0gICAgICAgIHRoaXMubV9zYXhIYW5kbGVyID0gbnVsbDsKLSAgICAgICAgdGhpcy5tX3N0YXRlID0gbnVsbDsKLSAgICAgICAgdGhpcy5tX3Nob3VsZEdlbmVyYXRlTlNBdHRyaWJ1dGUgPSBmYWxzZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBZGQgYSB1bmlxdWUgYXR0cmlidXRlCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgYWRkVW5pcXVlQXR0cmlidXRlKFN0cmluZyBxTmFtZSwgU3RyaW5nIHZhbHVlLCBpbnQgZmxhZ3MpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGFkZEF0dHJpYnV0ZShxTmFtZSwgdmFsdWUpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvVG9TdHJlYW0uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvVG9TdHJlYW0uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMjMwMTc2My4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1RvU3RyZWFtLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzMzg5ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDEtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFRvU3RyZWFtLmphdmEsdiAxLjQgMjAwNS8xMS8xMCAwNjo0MzoyNiBzdXJlc2hfZW1haWxpZCBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC51dGlscy5TZWN1cml0eVN1cHBvcnQ7Ci1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKLWltcG9ydCBqYXZhLmlvLlVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb247Ci1pbXBvcnQgamF2YS5pby5Xcml0ZXI7Ci1pbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7Ci1pbXBvcnQgamF2YS51dGlsLlN0cmluZ1Rva2VuaXplcjsKLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5FcnJvckxpc3RlbmVyOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uT3V0cHV0S2V5czsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXIudXRpbHMuTXNnS2V5OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplci51dGlscy5VdGlsczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXIudXRpbHMuV3JhcHBlZFJ1bnRpbWVFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcueG1sLnNheC5BdHRyaWJ1dGVzOwotaW1wb3J0IG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKLQotLy9pbXBvcnQgY29tLnN1bi5tZWRpYS5zb3VuZC5JRVNlY3VyaXR5OwotCi0vKioKLSAqIFRoaXMgYWJzdHJhY3QgY2xhc3MgaXMgYSBiYXNlIGNsYXNzIGZvciBvdGhlciBzdHJlYW0KLSAqIHNlcmlhbGl6ZXJzICh4bWwsIGh0bWwsIHRleHQgLi4uKSB0aGF0IHdyaXRlIG91dHB1dCB0byBhIHN0cmVhbS4KLSAqCi0gKiBAeHNsLnVzYWdlIGludGVybmFsCi0gKi8KLWFic3RyYWN0IHB1YmxpYyBjbGFzcyBUb1N0cmVhbSBleHRlbmRzIFNlcmlhbGl6ZXJCYXNlCi17Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ09NTUVOVF9CRUdJTiA9ICI8IS0tIjsKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ09NTUVOVF9FTkQgPSAiLS0+IjsKLQotICAgIC8qKiBTdGFjayB0byBrZWVwIHRyYWNrIG9mIGRpc2FibGluZyBvdXRwdXQgZXNjYXBpbmcuICovCi0gICAgcHJvdGVjdGVkIEJvb2xTdGFjayBtX2Rpc2FibGVPdXRwdXRFc2NhcGluZ1N0YXRlcyA9IG5ldyBCb29sU3RhY2soKTsKLQotCi0gICAgLyoqCi0gICAgICogVGhlIGVuY29kaW5nIGluZm9ybWF0aW9uIGFzc29jaWF0ZWQgd2l0aCB0aGlzIHNlcmlhbGl6ZXIuCi0gICAgICogQWx0aG91Z2ggaW5pdGlhbGx5IHRoZXJlIGlzIG5vIGVuY29kaW5nLAotICAgICAqIHRoZXJlIGlzIGEgZHVtbXkgRW5jb2RpbmdJbmZvIG9iamVjdCB0aGF0IHdpbGwgc2F5Ci0gICAgICogdGhhdCBldmVyeSBjaGFyYWN0ZXIgaXMgaW4gdGhlIGVuY29kaW5nLiBUaGlzIGlzIHVzZWZ1bAotICAgICAqIGZvciBhIHNlcmlhbGl6ZXIgdGhhdCBpcyBpbiB0ZW1wb3Jhcnkgb3V0cHV0IHN0YXRlIGFuZCBoYXMKLSAgICAgKiBubyBhc3NvY2lhdGVkIGVuY29kaW5nLiBBIHNlcmlhbGl6ZXIgaW4gZmluYWwgb3V0cHV0IHN0YXRlCi0gICAgICogd2lsbCBoYXZlIGFuIGVuY29kaW5nLCBhbmQgd2lsbCB3b3JyeSBhYm91dCB3aGV0aGVyCi0gICAgICogc2luZ2xlIGNoYXJzIG9yIHN1cnJvZ2F0ZSBwYWlycyBvZiBoaWdoL2xvdyBjaGFycyBmb3JtCi0gICAgICogY2hhcmFjdGVycyBpbiB0aGUgb3V0cHV0IGVuY29kaW5nLgotICAgICAqLwotICAgIEVuY29kaW5nSW5mbyBtX2VuY29kaW5nSW5mbyA9IG5ldyBFbmNvZGluZ0luZm8obnVsbCxudWxsKTsKLQotICAgIC8qKgotICAgICAqIE1ldGhvZCByZWZlcmVuY2UgdG8gdGhlIHN1bi5pby5DaGFyVG9CeXRlQ29udmVydGVyI2NhbkNvbnZlcnQgbWV0aG9kCi0gICAgICogZm9yIHRoaXMgZW5jb2RpbmcuICBJbnZhbGlkIGlmIG1fY2hhclRvQnl0ZUNvbnZlcnRlciBpcyBudWxsLgotICAgICAqLwotICAgIGphdmEubGFuZy5yZWZsZWN0Lk1ldGhvZCBtX2NhbkNvbnZlcnRNZXRoOwotCi0KLQotICAgIC8qKgotICAgICAqIEJvb2xlYW4gdGhhdCB0ZWxscyBpZiB3ZSBhbHJlYWR5IHRyaWVkIHRvIGdldCB0aGUgY29udmVydGVyLgotICAgICAqLwotICAgIGJvb2xlYW4gbV90cmllZFRvR2V0Q29udmVydGVyID0gZmFsc2U7Ci0KLQotICAgIC8qKgotICAgICAqIE9wYXF1ZSByZWZlcmVuY2UgdG8gdGhlIHN1bi5pby5DaGFyVG9CeXRlQ29udmVydGVyIGZvciB0aGlzCi0gICAgICogZW5jb2RpbmcuCi0gICAgICovCi0gICAgT2JqZWN0IG1fY2hhclRvQnl0ZUNvbnZlcnRlciA9IG51bGw7Ci0KLQotICAgIC8qKgotICAgICAqIFN0YWNrIHRvIGtlZXAgdHJhY2sgb2Ygd2hldGhlciBvciBub3Qgd2UgbmVlZCB0bwotICAgICAqIHByZXNlcnZlIHdoaXRlc3BhY2UuCi0gICAgICoKLSAgICAgKiBVc2VkIHRvIHB1c2gvcG9wIHZhbHVlcyB1c2VkIGZvciB0aGUgZmllbGQgbV9pc3ByZXNlcnZlLCBidXQKLSAgICAgKiBtX2lzcHJlc2VydmUgaXMgb25seSByZWxldmFudCBpZiBtX2RvSW5kZW50IGlzIHRydWUuCi0gICAgICogSWYgbV9kb0luZGVudCBpcyBmYWxzZSB0aGlzIGZpZWxkIGhhcyBubyBpbXBhY3QuCi0gICAgICoKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgQm9vbFN0YWNrIG1fcHJlc2VydmVzID0gbmV3IEJvb2xTdGFjaygpOwotCi0gICAgLyoqCi0gICAgICogU3RhdGUgZmxhZyB0byB0ZWxsIGlmIHByZXNlcnZhdGlvbiBvZiB3aGl0ZXNwYWNlCi0gICAgICogaXMgaW1wb3J0YW50LgotICAgICAqCi0gICAgICogVXNlZCBvbmx5IGluIHNob3VsZEluZGVudCgpIGJ1dCBvbmx5IGlmIG1fZG9JbmRlbnQgaXMgdHJ1ZS4KLSAgICAgKiBJZiBtX2RvSW5kZW50IGlzIGZhbHNlIHRoaXMgZmxhZyBoYXMgbm8gaW1wYWN0LgotICAgICAqCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gbV9pc3ByZXNlcnZlID0gZmFsc2U7Ci0KLSAgICAvKioKLSAgICAgKiBTdGF0ZSBmbGFnIHRoYXQgdGVsbHMgaWYgdGhlIHByZXZpb3VzIG5vZGUgcHJvY2Vzc2VkCi0gICAgICogd2FzIHRleHQsIHNvIHdlIGNhbiB0ZWxsIGlmIHdlIHNob3VsZCBwcmVzZXJ2ZSB3aGl0ZXNwYWNlLgotICAgICAqCi0gICAgICogVXNlZCBpbiBlbmREb2N1bWVudCgpIGFuZCBzaG91bGRJbmRlbnQoKSBidXQKLSAgICAgKiBvbmx5IGlmIG1fZG9JbmRlbnQgaXMgdHJ1ZS4KLSAgICAgKiBJZiBtX2RvSW5kZW50IGlzIGZhbHNlIHRoaXMgZmxhZyBoYXMgbm8gaW1wYWN0LgotICAgICAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIG1faXNwcmV2dGV4dCA9IGZhbHNlOwotCi0gICAgLyoqCi0gICAgICogVGhlIG1heGltdW0gY2hhcmFjdGVyIHNpemUgYmVmb3JlIHdlIGhhdmUgdG8gcmVzb3J0Ci0gICAgICogdG8gZXNjYXBpbmcuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGludCBtX21heENoYXJhY3RlciA9IEVuY29kaW5ncy5nZXRMYXN0UHJpbnRhYmxlKCk7Ci0KLQotICAgIC8qKgotICAgICAqIFRoZSBzeXN0ZW0gbGluZSBzZXBhcmF0b3IgZm9yIHdyaXRpbmcgb3V0IGxpbmUgYnJlYWtzLgotICAgICAqIFRoZSBkZWZhdWx0IHZhbHVlIGlzIGZyb20gdGhlIHN5c3RlbSBwcm9wZXJ0eSwKLSAgICAgKiBidXQgdGhpcyB2YWx1ZSBjYW4gYmUgc2V0IHRocm91Z2ggdGhlIHhzbDpvdXRwdXQKLSAgICAgKiBleHRlbnNpb24gYXR0cmlidXRlIHhhbGFuOmxpbmUtc2VwYXJhdG9yLgotICAgICAqLwotICAgIHByb3RlY3RlZCBjaGFyW10gbV9saW5lU2VwID0KLSAgICAgICAgU2VjdXJpdHlTdXBwb3J0LmdldFN5c3RlbVByb3BlcnR5KCJsaW5lLnNlcGFyYXRvciIpLnRvQ2hhckFycmF5KCk7Ci0KLSAgICAvKioKLSAgICAgKiBUcnVlIGlmIHRoZSB0aGUgc3lzdGVtIGxpbmUgc2VwYXJhdG9yIGlzIHRvIGJlIHVzZWQuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gbV9saW5lU2VwVXNlID0gdHJ1ZTsKLQotICAgIC8qKgotICAgICAqIFRoZSBsZW5ndGggb2YgdGhlIGxpbmUgc2VwZXJhdG9yLCBzaW5jZSB0aGUgd3JpdGUgaXMgZG9uZQotICAgICAqIG9uZSBjaGFyYWN0ZXIgYXQgYSB0aW1lLgotICAgICAqLwotICAgIHByb3RlY3RlZCBpbnQgbV9saW5lU2VwTGVuID0gbV9saW5lU2VwLmxlbmd0aDsKLQotICAgIC8qKgotICAgICAqIE1hcCB0aGF0IHRlbGxzIHdoaWNoIGNoYXJhY3RlcnMgc2hvdWxkIGhhdmUgc3BlY2lhbCB0cmVhdG1lbnQsIGFuZCBpdAotICAgICAqICBwcm92aWRlcyBjaGFyYWN0ZXIgdG8gZW50aXR5IG5hbWUgbG9va3VwLgotICAgICAqLwotICAgIHByb3RlY3RlZCBDaGFySW5mbyBtX2NoYXJJbmZvOwotCi0gICAgLyoqIFRydWUgaWYgd2UgY29udHJvbCB0aGUgYnVmZmVyLCBhbmQgd2Ugc2hvdWxkIGZsdXNoIHRoZSBvdXRwdXQgb24gZW5kRG9jdW1lbnQuICovCi0gICAgYm9vbGVhbiBtX3Nob3VsZEZsdXNoID0gdHJ1ZTsKLQotICAgIC8qKgotICAgICAqIEFkZCBzcGFjZSBiZWZvcmUgJy8+JyBmb3IgWEhUTUwuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gbV9zcGFjZUJlZm9yZUNsb3NlID0gZmFsc2U7Ci0KLSAgICAvKioKLSAgICAgKiBGbGFnIHRvIHNpZ25hbCB0aGF0IGEgbmV3bGluZSBzaG91bGQgYmUgYWRkZWQuCi0gICAgICoKLSAgICAgKiBVc2VkIG9ubHkgaW4gaW5kZW50KCkgd2hpY2ggaXMgY2FsbGVkIG9ubHkgaWYgbV9kb0luZGVudCBpcyB0cnVlLgotICAgICAqIElmIG1fZG9JbmRlbnQgaXMgZmFsc2UgdGhpcyBmbGFnIGhhcyBubyBpbXBhY3QuCi0gICAgICovCi0gICAgYm9vbGVhbiBtX3N0YXJ0TmV3TGluZTsKLQotICAgIC8qKgotICAgICAqIFRlbGxzIGlmIHdlJ3JlIGluIGFuIGludGVybmFsIGRvY3VtZW50IHR5cGUgc3Vic2V0LgotICAgICAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIG1faW5Eb2N0eXBlID0gZmFsc2U7Ci0KLSAgICAvKioKLSAgICAgICAqIEZsYWcgdG8gcXVpY2tseSB0ZWxsIGlmIHRoZSBlbmNvZGluZyBpcyBVVEY4LgotICAgICAgICovCi0gICAgYm9vbGVhbiBtX2lzVVRGOCA9IGZhbHNlOwotCi0gICAgLyoqIFRoZSB4c2w6b3V0cHV0IHByb3BlcnRpZXMuICovCi0gICAgcHJvdGVjdGVkIFByb3BlcnRpZXMgbV9mb3JtYXQ7Ci0KLSAgICAvKioKLSAgICAgKiByZW1lbWJlcnMgaWYgd2UgYXJlIGluIGJldHdlZW4gdGhlIHN0YXJ0Q0RBVEEoKSBhbmQgZW5kQ0RBVEEoKSBjYWxsYmFja3MKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBtX2NkYXRhU3RhcnRDYWxsZWQgPSBmYWxzZTsKLQotICAgIC8qKgotICAgICAqIElmIHRoaXMgZmxhZyBpcyB0cnVlIERURCBlbnRpdHkgcmVmZXJlbmNlcyBhcmUgbm90IGxlZnQgYXMtaXMsCi0gICAgICogd2hpY2ggaXMgZXhpdGluZyBvbGRlciBiZWhhdmlvci4KLSAgICAgKi8KLSAgICBwcml2YXRlIGJvb2xlYW4gbV9leHBhbmREVERFbnRpdGllcyA9IHRydWU7Ci0KLQotICAgIC8qKgotICAgICAqIERlZmF1bHQgY29uc3RydWN0b3IKLSAgICAgKi8KLSAgICBwdWJsaWMgVG9TdHJlYW0oKQotICAgIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIGhlbHBlciBtZXRob2QgdG8gd3JpdGVzIG91dCAiXV0+IiB3aGVuIGNsb3NpbmcgYSBDREFUQSBzZWN0aW9uLgotICAgICAqCi0gICAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCBjbG9zZUNEQVRBKCkgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgdHJ5Ci0gICAgICAgIHsKLSAgICAgICAgICAgIG1fd3JpdGVyLndyaXRlKENEQVRBX0RFTElNSVRFUl9DTE9TRSk7Ci0gICAgICAgICAgICAvLyB3cml0ZSBvdXQgYSBDREFUQSBzZWN0aW9uIGNsb3NpbmcgIl1dPiIKLSAgICAgICAgICAgIG1fY2RhdGFUYWdPcGVuID0gZmFsc2U7IC8vIFJlbWVtYmVyIHRoYXQgd2UgaGF2ZSBkb25lIHNvLgotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChJT0V4Y2VwdGlvbiBlKQotICAgICAgICB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKGUpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2VyaWFsaXplcyB0aGUgRE9NIG5vZGUuIFRocm93cyBhbiBleGNlcHRpb24gb25seSBpZiBhbiBJL08KLSAgICAgKiBleGNlcHRpb24gb2NjdXJlZCB3aGlsZSBzZXJpYWxpemluZy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBub2RlIE5vZGUgdG8gc2VyaWFsaXplLgotICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gQW4gSS9PIGV4Y2VwdGlvbiBvY2N1cmVkIHdoaWxlIHNlcmlhbGl6aW5nCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2VyaWFsaXplKE5vZGUgbm9kZSkgdGhyb3dzIElPRXhjZXB0aW9uCi0gICAgewotCi0gICAgICAgIHRyeQotICAgICAgICB7Ci0gICAgICAgICAgICBUcmVlV2Fsa2VyIHdhbGtlciA9Ci0gICAgICAgICAgICAgICAgbmV3IFRyZWVXYWxrZXIodGhpcyk7Ci0KLSAgICAgICAgICAgIHdhbGtlci50cmF2ZXJzZShub2RlKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAob3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIHNlKQotICAgICAgICB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgV3JhcHBlZFJ1bnRpbWVFeGNlcHRpb24oc2UpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRydWUgaWYgdGhlIGNoYXJhY3RlciBpcyB0aGUgaGlnaCBtZW1iZXIgb2YgYSBzdXJyb2dhdGUgcGFpci4KLSAgICAgKgotICAgICAqIE5FRURTRE9DIEBwYXJhbSBjCi0gICAgICoKLSAgICAgKiBORUVEU0RPQyAoJG9iamVjdE5hbWUkKSBAcmV0dXJuCi0gICAgICovCi0gICAgc3RhdGljIGZpbmFsIGJvb2xlYW4gaXNVVEYxNlN1cnJvZ2F0ZShjaGFyIGMpCi0gICAgewotICAgICAgICByZXR1cm4gKGMgJiAweEZDMDApID09IDB4RDgwMDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUYWtlbiBmcm9tIFhTTFRDCi0gICAgICovCi0gICAgcHJpdmF0ZSBib29sZWFuIG1fZXNjYXBpbmcgPSB0cnVlOwotCi0gICAgLyoqCi0gICAgICogRmx1c2ggdGhlIGZvcm1hdHRlcidzIHJlc3VsdCBzdHJlYW0uCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgICAqLwotICAgIHByb3RlY3RlZCBmaW5hbCB2b2lkIGZsdXNoV3JpdGVyKCkgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgZmluYWwgamF2YS5pby5Xcml0ZXIgd3JpdGVyID0gbV93cml0ZXI7Ci0gICAgICAgIGlmIChudWxsICE9IHdyaXRlcikKLSAgICAgICAgewotICAgICAgICAgICAgdHJ5Ci0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgaWYgKHdyaXRlciBpbnN0YW5jZW9mIFdyaXRlclRvVVRGOEJ1ZmZlcmVkKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKG1fc2hvdWxkRmx1c2gpCi0gICAgICAgICAgICAgICAgICAgICAgICAgKChXcml0ZXJUb1VURjhCdWZmZXJlZCkgd3JpdGVyKS5mbHVzaCgpOwotICAgICAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgICAgICAgKChXcml0ZXJUb1VURjhCdWZmZXJlZCkgd3JpdGVyKS5mbHVzaEJ1ZmZlcigpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpZiAod3JpdGVyIGluc3RhbmNlb2YgV3JpdGVyVG9BU0NJKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKG1fc2hvdWxkRmx1c2gpCi0gICAgICAgICAgICAgICAgICAgICAgICB3cml0ZXIuZmx1c2goKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gRmx1c2ggYWx3YXlzLgotICAgICAgICAgICAgICAgICAgICAvLyBOb3QgYSBncmVhdCB0aGluZyBpZiB0aGUgd3JpdGVyIHdhcyBjcmVhdGVkCi0gICAgICAgICAgICAgICAgICAgIC8vIGJ5IHRoaXMgY2xhc3MsIGJ1dCBkb24ndCBoYXZlIGEgY2hvaWNlLgotICAgICAgICAgICAgICAgICAgICB3cml0ZXIuZmx1c2goKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXRjaCAoSU9FeGNlcHRpb24gaW9lKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24oaW9lKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgb3V0cHV0IHN0cmVhbSB3aGVyZSB0aGUgZXZlbnRzIHdpbGwgYmUgc2VyaWFsaXplZCB0by4KLSAgICAgKgotICAgICAqIEByZXR1cm4gcmVmZXJlbmNlIHRvIHRoZSByZXN1bHQgc3RyZWFtLCBvciBudWxsIG9mIG9ubHkgYSB3cml0ZXIgd2FzCi0gICAgICogc2V0LgotICAgICAqLwotICAgIHB1YmxpYyBPdXRwdXRTdHJlYW0gZ2V0T3V0cHV0U3RyZWFtKCkKLSAgICB7Ci0KLSAgICAgICAgaWYgKG1fd3JpdGVyIGluc3RhbmNlb2YgV3JpdGVyVG9VVEY4QnVmZmVyZWQpCi0gICAgICAgICAgICByZXR1cm4gKChXcml0ZXJUb1VURjhCdWZmZXJlZCkgbV93cml0ZXIpLmdldE91dHB1dFN0cmVhbSgpOwotICAgICAgICBpZiAobV93cml0ZXIgaW5zdGFuY2VvZiBXcml0ZXJUb0FTQ0kpCi0gICAgICAgICAgICByZXR1cm4gKChXcml0ZXJUb0FTQ0kpIG1fd3JpdGVyKS5nZXRPdXRwdXRTdHJlYW0oKTsKLSAgICAgICAgZWxzZQotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLy8gSW1wbGVtZW50IERlY2xIYW5kbGVyCi0KLSAgICAvKioKLSAgICAgKiAgIFJlcG9ydCBhbiBlbGVtZW50IHR5cGUgZGVjbGFyYXRpb24uCi0gICAgICoKLSAgICAgKiAgIDxwPlRoZSBjb250ZW50IG1vZGVsIHdpbGwgY29uc2lzdCBvZiB0aGUgc3RyaW5nICJFTVBUWSIsIHRoZQotICAgICAqICAgc3RyaW5nICJBTlkiLCBvciBhIHBhcmVudGhlc2lzZWQgZ3JvdXAsIG9wdGlvbmFsbHkgZm9sbG93ZWQKLSAgICAgKiAgIGJ5IGFuIG9jY3VycmVuY2UgaW5kaWNhdG9yLiAgVGhlIG1vZGVsIHdpbGwgYmUgbm9ybWFsaXplZCBzbwotICAgICAqICAgdGhhdCBhbGwgd2hpdGVzcGFjZSBpcyByZW1vdmVkLGFuZCB3aWxsIGluY2x1ZGUgdGhlIGVuY2xvc2luZwotICAgICAqICAgcGFyZW50aGVzZXMuPC9wPgotICAgICAqCi0gICAgICogICBAcGFyYW0gbmFtZSBUaGUgZWxlbWVudCB0eXBlIG5hbWUuCi0gICAgICogICBAcGFyYW0gbW9kZWwgVGhlIGNvbnRlbnQgbW9kZWwgYXMgYSBub3JtYWxpemVkIHN0cmluZy4KLSAgICAgKiAgIEBleGNlcHRpb24gU0FYRXhjZXB0aW9uIFRoZSBhcHBsaWNhdGlvbiBtYXkgcmFpc2UgYW4gZXhjZXB0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVsZW1lbnREZWNsKFN0cmluZyBuYW1lLCBTdHJpbmcgbW9kZWwpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIC8vIERvIG5vdCBpbmxpbmUgZXh0ZXJuYWwgRFRECi0gICAgICAgIGlmIChtX2luRXh0ZXJuYWxEVEQpCi0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIHRyeQotICAgICAgICB7Ci0gICAgICAgICAgICBmaW5hbCBqYXZhLmlvLldyaXRlciB3cml0ZXIgPSBtX3dyaXRlcjsKLSAgICAgICAgICAgIERURHByb2xvZygpOwotCi0gICAgICAgICAgICB3cml0ZXIud3JpdGUoIjwhRUxFTUVOVCAiKTsKLSAgICAgICAgICAgIHdyaXRlci53cml0ZShuYW1lKTsKLSAgICAgICAgICAgIHdyaXRlci53cml0ZSgnICcpOwotICAgICAgICAgICAgd3JpdGVyLndyaXRlKG1vZGVsKTsKLSAgICAgICAgICAgIHdyaXRlci53cml0ZSgnPicpOwotICAgICAgICAgICAgd3JpdGVyLndyaXRlKG1fbGluZVNlcCwgMCwgbV9saW5lU2VwTGVuKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoSU9FeGNlcHRpb24gZSkKLSAgICAgICAgewotICAgICAgICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbihlKTsKLSAgICAgICAgfQotCi0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmVwb3J0IGFuIGludGVybmFsIGVudGl0eSBkZWNsYXJhdGlvbi4KLSAgICAgKgotICAgICAqIDxwPk9ubHkgdGhlIGVmZmVjdGl2ZSAoZmlyc3QpIGRlY2xhcmF0aW9uIGZvciBlYWNoIGVudGl0eQotICAgICAqIHdpbGwgYmUgcmVwb3J0ZWQuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGVudGl0eS4gIElmIGl0IGlzIGEgcGFyYW1ldGVyCi0gICAgICogICAgICAgIGVudGl0eSwgdGhlIG5hbWUgd2lsbCBiZWdpbiB3aXRoICclJy4KLSAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGxhY2VtZW50IHRleHQgb2YgdGhlIGVudGl0eS4KLSAgICAgKiBAZXhjZXB0aW9uIFNBWEV4Y2VwdGlvbiBUaGUgYXBwbGljYXRpb24gbWF5IHJhaXNlIGFuIGV4Y2VwdGlvbi4KLSAgICAgKiBAc2VlICNleHRlcm5hbEVudGl0eURlY2wKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkRUREhhbmRsZXIjdW5wYXJzZWRFbnRpdHlEZWNsCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgaW50ZXJuYWxFbnRpdHlEZWNsKFN0cmluZyBuYW1lLCBTdHJpbmcgdmFsdWUpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIC8vIERvIG5vdCBpbmxpbmUgZXh0ZXJuYWwgRFRECi0gICAgICAgIGlmIChtX2luRXh0ZXJuYWxEVEQpCi0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIHRyeQotICAgICAgICB7Ci0gICAgICAgICAgICBEVERwcm9sb2coKTsKLSAgICAgICAgICAgIG91dHB1dEVudGl0eURlY2wobmFtZSwgdmFsdWUpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChJT0V4Y2VwdGlvbiBlKQotICAgICAgICB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKGUpOwotICAgICAgICB9Ci0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBPdXRwdXQgdGhlIGRvYyB0eXBlIGRlY2xhcmF0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGRvY3VtZW50IHR5cGUgbmFtZS4KLSAgICAgKiBORUVEU0RPQyBAcGFyYW0gdmFsdWUKLSAgICAgKgotICAgICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAgICovCi0gICAgdm9pZCBvdXRwdXRFbnRpdHlEZWNsKFN0cmluZyBuYW1lLCBTdHJpbmcgdmFsdWUpIHRocm93cyBJT0V4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgZmluYWwgamF2YS5pby5Xcml0ZXIgd3JpdGVyID0gbV93cml0ZXI7Ci0gICAgICAgIHdyaXRlci53cml0ZSgiPCFFTlRJVFkgIik7Ci0gICAgICAgIHdyaXRlci53cml0ZShuYW1lKTsKLSAgICAgICAgd3JpdGVyLndyaXRlKCIgXCIiKTsKLSAgICAgICAgd3JpdGVyLndyaXRlKHZhbHVlKTsKLSAgICAgICAgd3JpdGVyLndyaXRlKCJcIj4iKTsKLSAgICAgICAgd3JpdGVyLndyaXRlKG1fbGluZVNlcCwgMCwgbV9saW5lU2VwTGVuKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBPdXRwdXQgYSBzeXN0ZW0tZGVwZW5kZW50IGxpbmUgYnJlYWsuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgICAqLwotICAgIHByb3RlY3RlZCBmaW5hbCB2b2lkIG91dHB1dExpbmVTZXAoKSB0aHJvd3MgSU9FeGNlcHRpb24KLSAgICB7Ci0KLSAgICAgICAgbV93cml0ZXIud3JpdGUobV9saW5lU2VwLCAwLCBtX2xpbmVTZXBMZW4pOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNwZWNpZmllcyBhbiBvdXRwdXQgZm9ybWF0IGZvciB0aGlzIHNlcmlhbGl6ZXIuIEl0IHRoZQotICAgICAqIHNlcmlhbGl6ZXIgaGFzIGFscmVhZHkgYmVlbiBhc3NvY2lhdGVkIHdpdGggYW4gb3V0cHV0IGZvcm1hdCwKLSAgICAgKiBpdCB3aWxsIHN3aXRjaCB0byB0aGUgbmV3IGZvcm1hdC4gVGhpcyBtZXRob2Qgc2hvdWxkIG5vdCBiZQotICAgICAqIGNhbGxlZCB3aGlsZSB0aGUgc2VyaWFsaXplciBpcyBpbiB0aGUgcHJvY2VzcyBvZiBzZXJpYWxpemluZwotICAgICAqIGEgZG9jdW1lbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZm9ybWF0IFRoZSBvdXRwdXQgZm9ybWF0IHRvIHVzZQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldE91dHB1dEZvcm1hdChQcm9wZXJ0aWVzIGZvcm1hdCkKLSAgICB7Ci0KLSAgICAgICAgYm9vbGVhbiBzaG91bGRGbHVzaCA9IG1fc2hvdWxkRmx1c2g7Ci0KLSAgICAgICAgaW5pdChtX3dyaXRlciwgZm9ybWF0LCBmYWxzZSwgZmFsc2UpOwotCi0gICAgICAgIG1fc2hvdWxkRmx1c2ggPSBzaG91bGRGbHVzaDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJbml0aWFsaXplIHRoZSBzZXJpYWxpemVyIHdpdGggdGhlIHNwZWNpZmllZCB3cml0ZXIgYW5kIG91dHB1dCBmb3JtYXQuCi0gICAgICogTXVzdCBiZSBjYWxsZWQgYmVmb3JlIGNhbGxpbmcgYW55IG9mIHRoZSBzZXJpYWxpemUgbWV0aG9kcy4KLSAgICAgKiBUaGlzIG1ldGhvZCBjYW4gYmUgY2FsbGVkIG11bHRpcGxlIHRpbWVzIGFuZCB0aGUgeHNsOm91dHB1dCBwcm9wZXJ0aWVzCi0gICAgICogcGFzc2VkIGluIHRoZSAnZm9ybWF0JyBwYXJhbWV0ZXIgYXJlIGFjY3VtdWxhdGVkIGFjcm9zcyBjYWxscy4KLSAgICAgKgotICAgICAqIEBwYXJhbSB3cml0ZXIgVGhlIHdyaXRlciB0byB1c2UKLSAgICAgKiBAcGFyYW0gZm9ybWF0IFRoZSBvdXRwdXQgZm9ybWF0Ci0gICAgICogQHBhcmFtIHNob3VsZEZsdXNoIFRydWUgaWYgdGhlIHdyaXRlciBzaG91bGQgYmUgZmx1c2hlZCBhdCBFbmREb2N1bWVudC4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN5bmNocm9uaXplZCB2b2lkIGluaXQoCi0gICAgICAgIFdyaXRlciB3cml0ZXIsCi0gICAgICAgIFByb3BlcnRpZXMgZm9ybWF0LAotICAgICAgICBib29sZWFuIGRlZmF1bHRQcm9wZXJ0aWVzLAotICAgICAgICBib29sZWFuIHNob3VsZEZsdXNoKQotICAgIHsKLQotICAgICAgICBtX3Nob3VsZEZsdXNoID0gc2hvdWxkRmx1c2g7Ci0KLQotICAgICAgICAvLyBpZiB3ZSBhcmUgdHJhY2luZyBldmVudHMgd2UgbmVlZCB0byB0cmFjZSB3aGF0Ci0gICAgICAgIC8vIGNoYXJhY3RlcnMgYXJlIHdyaXR0ZW4gdG8gdGhlIG91dHB1dCB3cml0ZXIuCi0gICAgICAgIGlmIChtX3RyYWNlciAhPSBudWxsCi0gICAgICAgICAmJiAhKHdyaXRlciBpbnN0YW5jZW9mIFNlcmlhbGl6ZXJUcmFjZVdyaXRlcikgICkKLSAgICAgICAgICAgIG1fd3JpdGVyID0gbmV3IFNlcmlhbGl6ZXJUcmFjZVdyaXRlcih3cml0ZXIsIG1fdHJhY2VyKTsKLSAgICAgICAgZWxzZQotICAgICAgICAgICAgbV93cml0ZXIgPSB3cml0ZXI7Ci0KLQotICAgICAgICBtX2Zvcm1hdCA9IGZvcm1hdDsKLSAgICAgICAgLy8gICAgICAgIG1fY2RhdGFTZWN0aW9uTmFtZXMgPQotICAgICAgICAvLyAgICAgICAgICAgIE91dHB1dFByb3BlcnRpZXMuZ2V0UU5hbWVQcm9wZXJ0aWVzKAotICAgICAgICAvLyAgICAgICAgICAgICAgICBPdXRwdXRLZXlzLkNEQVRBX1NFQ1RJT05fRUxFTUVOVFMsCi0gICAgICAgIC8vICAgICAgICAgICAgICAgIGZvcm1hdCk7Ci0gICAgICAgIHNldENkYXRhU2VjdGlvbkVsZW1lbnRzKE91dHB1dEtleXMuQ0RBVEFfU0VDVElPTl9FTEVNRU5UUywgZm9ybWF0KTsKLQotICAgICAgICBzZXRJbmRlbnRBbW91bnQoCi0gICAgICAgICAgICBPdXRwdXRQcm9wZXJ0eVV0aWxzLmdldEludFByb3BlcnR5KAotICAgICAgICAgICAgICAgIE91dHB1dFByb3BlcnRpZXNGYWN0b3J5LlNfS0VZX0lOREVOVF9BTU9VTlQsCi0gICAgICAgICAgICAgICAgZm9ybWF0KSk7Ci0gICAgICAgIHNldEluZGVudCgKLSAgICAgICAgICAgIE91dHB1dFByb3BlcnR5VXRpbHMuZ2V0Qm9vbGVhblByb3BlcnR5KE91dHB1dEtleXMuSU5ERU5ULCBmb3JtYXQpKTsKLQotICAgICAgICB7Ci0gICAgICAgICAgICBTdHJpbmcgc2VwID0KLSAgICAgICAgICAgICAgICAgICAgZm9ybWF0LmdldFByb3BlcnR5KE91dHB1dFByb3BlcnRpZXNGYWN0b3J5LlNfS0VZX0xJTkVfU0VQQVJBVE9SKTsKLSAgICAgICAgICAgIGlmIChzZXAgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIG1fbGluZVNlcCA9IHNlcC50b0NoYXJBcnJheSgpOwotICAgICAgICAgICAgICAgIG1fbGluZVNlcExlbiA9IHNlcC5sZW5ndGgoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGJvb2xlYW4gc2hvdWxkTm90V3JpdGVYTUxIZWFkZXIgPQotICAgICAgICAgICAgT3V0cHV0UHJvcGVydHlVdGlscy5nZXRCb29sZWFuUHJvcGVydHkoCi0gICAgICAgICAgICAgICAgT3V0cHV0S2V5cy5PTUlUX1hNTF9ERUNMQVJBVElPTiwKLSAgICAgICAgICAgICAgICBmb3JtYXQpOwotICAgICAgICBzZXRPbWl0WE1MRGVjbGFyYXRpb24oc2hvdWxkTm90V3JpdGVYTUxIZWFkZXIpOwotICAgICAgICBzZXREb2N0eXBlU3lzdGVtKGZvcm1hdC5nZXRQcm9wZXJ0eShPdXRwdXRLZXlzLkRPQ1RZUEVfU1lTVEVNKSk7Ci0gICAgICAgIFN0cmluZyBkb2N0eXBlUHVibGljID0gZm9ybWF0LmdldFByb3BlcnR5KE91dHB1dEtleXMuRE9DVFlQRV9QVUJMSUMpOwotICAgICAgICBzZXREb2N0eXBlUHVibGljKGRvY3R5cGVQdWJsaWMpOwotCi0gICAgICAgIC8vIGlmIHN0YW5kYWxvbmUgd2FzIGV4cGxpY2l0bHkgc3BlY2lmaWVkCi0gICAgICAgIGlmIChmb3JtYXQuZ2V0KE91dHB1dEtleXMuU1RBTkRBTE9ORSkgIT0gbnVsbCkKLSAgICAgICAgewotICAgICAgICAgICAgU3RyaW5nIHZhbCA9IGZvcm1hdC5nZXRQcm9wZXJ0eShPdXRwdXRLZXlzLlNUQU5EQUxPTkUpOwotICAgICAgICAgICAgaWYgKGRlZmF1bHRQcm9wZXJ0aWVzKQotICAgICAgICAgICAgICAgIHNldFN0YW5kYWxvbmVJbnRlcm5hbCh2YWwpOwotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIHNldFN0YW5kYWxvbmUodmFsKTsKLSAgICAgICAgfQotCi0gICAgICAgIHNldE1lZGlhVHlwZShmb3JtYXQuZ2V0UHJvcGVydHkoT3V0cHV0S2V5cy5NRURJQV9UWVBFKSk7Ci0KLSAgICAgICAgaWYgKG51bGwgIT0gZG9jdHlwZVB1YmxpYykKLSAgICAgICAgewotICAgICAgICAgICAgaWYgKGRvY3R5cGVQdWJsaWMuc3RhcnRzV2l0aCgiLS8vVzNDLy9EVEQgWEhUTUwiKSkKLSAgICAgICAgICAgICAgICBtX3NwYWNlQmVmb3JlQ2xvc2UgPSB0cnVlOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoKLSAgICAgICAgICogVGhpcyBjb2RlIGlzIGFkZGVkIGZvciBYTUwgMS4xIFZlcnNpb24gb3V0cHV0LgotICAgICAgICAgKi8KLSAgICAgICAgU3RyaW5nIHZlcnNpb24gPSBnZXRWZXJzaW9uKCk7Ci0gICAgICAgIGlmIChudWxsID09IHZlcnNpb24pCi0gICAgICAgIHsKLSAgICAgICAgICAgIHZlcnNpb24gPSBmb3JtYXQuZ2V0UHJvcGVydHkoT3V0cHV0S2V5cy5WRVJTSU9OKTsKLSAgICAgICAgICAgIHNldFZlcnNpb24odmVyc2lvbik7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBpbml0Q2hhcnNNYXAoKTsKLSAgICAgICAgU3RyaW5nIGVuY29kaW5nID0gZ2V0RW5jb2RpbmcoKTsKLSAgICAgICAgaWYgKG51bGwgPT0gZW5jb2RpbmcpCi0gICAgICAgIHsKLSAgICAgICAgICAgIGVuY29kaW5nID0KLSAgICAgICAgICAgICAgICBFbmNvZGluZ3MuZ2V0TWltZUVuY29kaW5nKAotICAgICAgICAgICAgICAgICAgICBmb3JtYXQuZ2V0UHJvcGVydHkoT3V0cHV0S2V5cy5FTkNPRElORykpOwotICAgICAgICAgICAgc2V0RW5jb2RpbmcoZW5jb2RpbmcpOwotICAgICAgICB9Ci0KLSAgICAgICAgbV9pc1VURjggPSBlbmNvZGluZy5lcXVhbHMoRW5jb2RpbmdzLkRFRkFVTFRfTUlNRV9FTkNPRElORyk7Ci0KLSAgICAgICAgLy8gQWNjZXNzIHRoaXMgb25seSBmcm9tIHRoZSBIYXNodGFibGUgbGV2ZWwuLi4gd2UgZG9uJ3Qgd2FudCB0bwotICAgICAgICAvLyBnZXQgZGVmYXVsdCBwcm9wZXJ0aWVzLgotICAgICAgICBTdHJpbmcgZW50aXRpZXNGaWxlTmFtZSA9Ci0gICAgICAgICAgICAoU3RyaW5nKSBmb3JtYXQuZ2V0KE91dHB1dFByb3BlcnRpZXNGYWN0b3J5LlNfS0VZX0VOVElUSUVTKTsKLQotICAgICAgICBpZiAobnVsbCAhPSBlbnRpdGllc0ZpbGVOYW1lKQotICAgICAgICB7Ci0KLSAgICAgICAgICAgIFN0cmluZyBtZXRob2QgPQotICAgICAgICAgICAgICAgIChTdHJpbmcpIGZvcm1hdC5nZXQoT3V0cHV0S2V5cy5NRVRIT0QpOwotCi0gICAgICAgICAgICBtX2NoYXJJbmZvID0gQ2hhckluZm8uZ2V0Q2hhckluZm8oZW50aXRpZXNGaWxlTmFtZSwgbWV0aG9kKTsKLSAgICAgICAgfQotCi0gICAgfQotCi0gICAgLyoqCi0gICAgICogSW5pdGlhbGl6ZSB0aGUgc2VyaWFsaXplciB3aXRoIHRoZSBzcGVjaWZpZWQgd3JpdGVyIGFuZCBvdXRwdXQgZm9ybWF0LgotICAgICAqIE11c3QgYmUgY2FsbGVkIGJlZm9yZSBjYWxsaW5nIGFueSBvZiB0aGUgc2VyaWFsaXplIG1ldGhvZHMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gd3JpdGVyIFRoZSB3cml0ZXIgdG8gdXNlCi0gICAgICogQHBhcmFtIGZvcm1hdCBUaGUgb3V0cHV0IGZvcm1hdAotICAgICAqLwotICAgIHByaXZhdGUgc3luY2hyb25pemVkIHZvaWQgaW5pdChXcml0ZXIgd3JpdGVyLCBQcm9wZXJ0aWVzIGZvcm1hdCkKLSAgICB7Ci0gICAgICAgIGluaXQod3JpdGVyLCBmb3JtYXQsIGZhbHNlLCBmYWxzZSk7Ci0gICAgfQotICAgIC8qKgotICAgICAqIEluaXRpYWxpemUgdGhlIHNlcmlhbGl6ZXIgd2l0aCB0aGUgc3BlY2lmaWVkIG91dHB1dCBzdHJlYW0gYW5kIG91dHB1dAotICAgICAqIGZvcm1hdC4gTXVzdCBiZSBjYWxsZWQgYmVmb3JlIGNhbGxpbmcgYW55IG9mIHRoZSBzZXJpYWxpemUgbWV0aG9kcy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBvdXRwdXQgVGhlIG91dHB1dCBzdHJlYW0gdG8gdXNlCi0gICAgICogQHBhcmFtIGZvcm1hdCBUaGUgb3V0cHV0IGZvcm1hdAotICAgICAqIEBwYXJhbSBkZWZhdWx0UHJvcGVydGllcyB0cnVlIGlmIHRoZSBwcm9wZXJ0aWVzIGFyZSB0aGUgZGVmYXVsdAotICAgICAqIHByb3BlcnRpZXMKLSAgICAgKgotICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBUaGUgZW5jb2Rpbmcgc3BlY2lmaWVkICAgaW4gdGhlCi0gICAgICogb3V0cHV0IGZvcm1hdCBpcyBub3Qgc3VwcG9ydGVkCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHN5bmNocm9uaXplZCB2b2lkIGluaXQoCi0gICAgICAgIE91dHB1dFN0cmVhbSBvdXRwdXQsCi0gICAgICAgIFByb3BlcnRpZXMgZm9ybWF0LAotICAgICAgICBib29sZWFuIGRlZmF1bHRQcm9wZXJ0aWVzKQotICAgICAgICB0aHJvd3MgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbgotICAgIHsKLQotICAgICAgICBTdHJpbmcgZW5jb2RpbmcgPSBnZXRFbmNvZGluZygpOwotICAgICAgICBpZiAoZW5jb2RpbmcgPT0gbnVsbCkKLSAgICAgICAgewotICAgICAgICAgICAgLy8gaWYgbm90IGFscmVhZHkgc2V0IHRoZW4gZ2V0IGl0IGZyb20gdGhlIHByb3BlcnRpZXMKLSAgICAgICAgICAgIGVuY29kaW5nID0KLSAgICAgICAgICAgICAgICBFbmNvZGluZ3MuZ2V0TWltZUVuY29kaW5nKAotICAgICAgICAgICAgICAgICAgICBmb3JtYXQuZ2V0UHJvcGVydHkoT3V0cHV0S2V5cy5FTkNPRElORykpOwotICAgICAgICAgICAgc2V0RW5jb2RpbmcoZW5jb2RpbmcpOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKGVuY29kaW5nLmVxdWFsc0lnbm9yZUNhc2UoIlVURi04IikpCi0gICAgICAgIHsKLSAgICAgICAgICAgIG1faXNVVEY4ID0gdHJ1ZTsKLSAgICAgICAgICAgIC8vICAgICAgICAgICAgaWYgKG91dHB1dCBpbnN0YW5jZW9mIGphdmEuaW8uQnVmZmVyZWRPdXRwdXRTdHJlYW0pCi0gICAgICAgICAgICAvLyAgICAgICAgICAgIHsKLSAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgIGluaXQobmV3IFdyaXRlclRvVVRGOChvdXRwdXQpLCBmb3JtYXQsIGRlZmF1bHRQcm9wZXJ0aWVzLCB0cnVlKTsKLSAgICAgICAgICAgIC8vICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gICAgICAgICAgICBlbHNlIGlmIChvdXRwdXQgaW5zdGFuY2VvZiBqYXZhLmlvLkZpbGVPdXRwdXRTdHJlYW0pCi0gICAgICAgICAgICAvLyAgICAgICAgICAgIHsKLSAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgIGluaXQobmV3IFdyaXRlclRvVVRGOEJ1ZmZlcmVkKG91dHB1dCksIGZvcm1hdCwgZGVmYXVsdFByb3BlcnRpZXMsIHRydWUpOwotICAgICAgICAgICAgLy8gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgIC8vICAgICAgICAgICAgewotICAgICAgICAgICAgLy8gICAgICAgICAgICAgICAgLy8gTm90IHN1cmUgd2hhdCB0byBkbyBpbiB0aGlzIGNhc2UuICBJJ20gZ29pbmcgdG8gYmUgY29uc2VydmF0aXZlCi0gICAgICAgICAgICAvLyAgICAgICAgICAgICAgICAvLyBhbmQgbm90IGJ1ZmZlci4KLSAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgIGluaXQobmV3IFdyaXRlclRvVVRGOChvdXRwdXQpLCBmb3JtYXQsIGRlZmF1bHRQcm9wZXJ0aWVzLCB0cnVlKTsKLSAgICAgICAgICAgIC8vICAgICAgICAgICAgfQotCi0KLSAgICAgICAgICAgICAgICBpbml0KAotICAgICAgICAgICAgICAgICAgICBuZXcgV3JpdGVyVG9VVEY4QnVmZmVyZWQob3V0cHV0KSwKLSAgICAgICAgICAgICAgICAgICAgZm9ybWF0LAotICAgICAgICAgICAgICAgICAgICBkZWZhdWx0UHJvcGVydGllcywKLSAgICAgICAgICAgICAgICAgICAgdHJ1ZSk7Ci0KLQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKAotICAgICAgICAgICAgZW5jb2RpbmcuZXF1YWxzKCJXSU5ET1dTLTEyNTAiKQotICAgICAgICAgICAgICAgIHx8IGVuY29kaW5nLmVxdWFscygiVVMtQVNDSUkiKQotICAgICAgICAgICAgICAgIHx8IGVuY29kaW5nLmVxdWFscygiQVNDSUkiKSkKLSAgICAgICAgewotICAgICAgICAgICAgaW5pdChuZXcgV3JpdGVyVG9BU0NJKG91dHB1dCksIGZvcm1hdCwgZGVmYXVsdFByb3BlcnRpZXMsIHRydWUpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotICAgICAgICAgICAgV3JpdGVyIG9zdzsKLQotICAgICAgICAgICAgdHJ5Ci0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgb3N3ID0gRW5jb2RpbmdzLmdldFdyaXRlcihvdXRwdXQsIGVuY29kaW5nKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhdGNoIChVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIHVlZSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oCi0gICAgICAgICAgICAgICAgICAgICJXYXJuaW5nOiBlbmNvZGluZyBcIiIKLSAgICAgICAgICAgICAgICAgICAgICAgICsgZW5jb2RpbmcKLSAgICAgICAgICAgICAgICAgICAgICAgICsgIlwiIG5vdCBzdXBwb3J0ZWQiCi0gICAgICAgICAgICAgICAgICAgICAgICArICIsIHVzaW5nICIKLSAgICAgICAgICAgICAgICAgICAgICAgICsgRW5jb2RpbmdzLkRFRkFVTFRfTUlNRV9FTkNPRElORyk7Ci0KLSAgICAgICAgICAgICAgICBlbmNvZGluZyA9IEVuY29kaW5ncy5ERUZBVUxUX01JTUVfRU5DT0RJTkc7Ci0gICAgICAgICAgICAgICAgc2V0RW5jb2RpbmcoZW5jb2RpbmcpOwotICAgICAgICAgICAgICAgIG9zdyA9IEVuY29kaW5ncy5nZXRXcml0ZXIob3V0cHV0LCBlbmNvZGluZyk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGluaXQob3N3LCBmb3JtYXQsIGRlZmF1bHRQcm9wZXJ0aWVzLCB0cnVlKTsKLSAgICAgICAgfQotCi0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgb3V0cHV0IGZvcm1hdCBmb3IgdGhpcyBzZXJpYWxpemVyLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgb3V0cHV0IGZvcm1hdCBpbiB1c2UKLSAgICAgKi8KLSAgICBwdWJsaWMgUHJvcGVydGllcyBnZXRPdXRwdXRGb3JtYXQoKQotICAgIHsKLSAgICAgICAgcmV0dXJuIG1fZm9ybWF0OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNwZWNpZmllcyBhIHdyaXRlciB0byB3aGljaCB0aGUgZG9jdW1lbnQgc2hvdWxkIGJlIHNlcmlhbGl6ZWQuCi0gICAgICogVGhpcyBtZXRob2Qgc2hvdWxkIG5vdCBiZSBjYWxsZWQgd2hpbGUgdGhlIHNlcmlhbGl6ZXIgaXMgaW4KLSAgICAgKiB0aGUgcHJvY2VzcyBvZiBzZXJpYWxpemluZyBhIGRvY3VtZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIHdyaXRlciBUaGUgb3V0cHV0IHdyaXRlciBzdHJlYW0KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRXcml0ZXIoV3JpdGVyIHdyaXRlcikKLSAgICB7Ci0gICAgICAgIC8vIGlmIHdlIGFyZSB0cmFjaW5nIGV2ZW50cyB3ZSBuZWVkIHRvIHRyYWNlIHdoYXQKLSAgICAgICAgLy8gY2hhcmFjdGVycyBhcmUgd3JpdHRlbiB0byB0aGUgb3V0cHV0IHdyaXRlci4KLSAgICAgICAgaWYgKG1fdHJhY2VyICE9IG51bGwKLSAgICAgICAgICYmICEod3JpdGVyIGluc3RhbmNlb2YgU2VyaWFsaXplclRyYWNlV3JpdGVyKSAgKQotICAgICAgICAgICAgbV93cml0ZXIgPSBuZXcgU2VyaWFsaXplclRyYWNlV3JpdGVyKHdyaXRlciwgbV90cmFjZXIpOwotICAgICAgICBlbHNlCi0gICAgICAgICAgICBtX3dyaXRlciA9IHdyaXRlcjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgaWYgdGhlIG9wZXJhdGluZyBzeXN0ZW1zIGVuZC1vZi1saW5lIGxpbmUgc2VwYXJhdG9yIHNob3VsZAotICAgICAqIGJlIHVzZWQgd2hlbiBzZXJpYWxpemluZy4gIElmIHNldCBmYWxzZSBOTCBjaGFyYWN0ZXIKLSAgICAgKiAoZGVjaW1hbCAxMCkgaXMgbGVmdCBhbG9uZSwgb3RoZXJ3aXNlIHRoZSBuZXctbGluZSB3aWxsIGJlIHJlcGxhY2VkIG9uCi0gICAgICogb3V0cHV0IHdpdGggdGhlIHN5c3RlbXMgbGluZSBzZXBhcmF0b3IuIEZvciBleGFtcGxlIG9uIFVOSVggdGhpcyBpcwotICAgICAqIE5MLCB3aGlsZSBvbiBXaW5kb3dzIGl0IGlzIHR3byBjaGFyYWN0ZXJzLCBDUiBOTCwgd2hlcmUgQ1IgaXMgdGhlCi0gICAgICogY2FycmlhZ2UtcmV0dXJuIChkZWNpbWFsIDEzKS4KLSAgICAgKgotICAgICAqIEBwYXJhbSB1c2Vfc3l0ZW1fbGluZV9icmVhayBUcnVlIGlmIGFuIGlucHV0IE5MIGlzIHJlcGxhY2VkIHdpdGggdGhlCi0gICAgICogb3BlcmF0aW5nIHN5c3RlbXMgZW5kLW9mLWxpbmUgc2VwYXJhdG9yLgotICAgICAqIEByZXR1cm4gVGhlIHByZXZpb3VzbHkgc2V0IHZhbHVlIG9mIHRoZSBzZXJpYWxpemVyLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIHNldExpbmVTZXBVc2UoYm9vbGVhbiB1c2Vfc3l0ZW1fbGluZV9icmVhaykKLSAgICB7Ci0gICAgICAgIGJvb2xlYW4gb2xkVmFsdWUgPSBtX2xpbmVTZXBVc2U7Ci0gICAgICAgIG1fbGluZVNlcFVzZSA9IHVzZV9zeXRlbV9saW5lX2JyZWFrOwotICAgICAgICByZXR1cm4gb2xkVmFsdWU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU3BlY2lmaWVzIGFuIG91dHB1dCBzdHJlYW0gdG8gd2hpY2ggdGhlIGRvY3VtZW50IHNob3VsZCBiZQotICAgICAqIHNlcmlhbGl6ZWQuIFRoaXMgbWV0aG9kIHNob3VsZCBub3QgYmUgY2FsbGVkIHdoaWxlIHRoZQotICAgICAqIHNlcmlhbGl6ZXIgaXMgaW4gdGhlIHByb2Nlc3Mgb2Ygc2VyaWFsaXppbmcgYSBkb2N1bWVudC4KLSAgICAgKiA8cD4KLSAgICAgKiBUaGUgZW5jb2Rpbmcgc3BlY2lmaWVkIGluIHRoZSBvdXRwdXQgcHJvcGVydGllcyBpcyB1c2VkLCBvcgotICAgICAqIGlmIG5vIGVuY29kaW5nIHdhcyBzcGVjaWZpZWQsIHRoZSBkZWZhdWx0IGZvciB0aGUgc2VsZWN0ZWQKLSAgICAgKiBvdXRwdXQgbWV0aG9kLgotICAgICAqCi0gICAgICogQHBhcmFtIG91dHB1dCBUaGUgb3V0cHV0IHN0cmVhbQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldE91dHB1dFN0cmVhbShPdXRwdXRTdHJlYW0gb3V0cHV0KQotICAgIHsKLQotICAgICAgICB0cnkKLSAgICAgICAgewotICAgICAgICAgICAgUHJvcGVydGllcyBmb3JtYXQ7Ci0gICAgICAgICAgICBpZiAobnVsbCA9PSBtX2Zvcm1hdCkKLSAgICAgICAgICAgICAgICBmb3JtYXQgPQotICAgICAgICAgICAgICAgICAgICBPdXRwdXRQcm9wZXJ0aWVzRmFjdG9yeS5nZXREZWZhdWx0TWV0aG9kUHJvcGVydGllcygKLSAgICAgICAgICAgICAgICAgICAgICAgIE1ldGhvZC5YTUwpOwotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIGZvcm1hdCA9IG1fZm9ybWF0OwotICAgICAgICAgICAgaW5pdChvdXRwdXQsIGZvcm1hdCwgdHJ1ZSk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gdWVlKQotICAgICAgICB7Ci0KLSAgICAgICAgICAgIC8vIFNob3VsZCBoYXZlIGJlZW4gd2FybmVkIGluIGluaXQsIEkgZ3Vlc3MuLi4KLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgU2VyaWFsaXphdGlvbkhhbmRsZXIjc2V0RXNjYXBpbmcoYm9vbGVhbikKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBzZXRFc2NhcGluZyhib29sZWFuIGVzY2FwZSkKLSAgICB7Ci0gICAgICAgIGZpbmFsIGJvb2xlYW4gdGVtcCA9IG1fZXNjYXBpbmc7Ci0gICAgICAgIG1fZXNjYXBpbmcgPSBlc2NhcGU7Ci0gICAgICAgIHJldHVybiB0ZW1wOwotCi0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBNaWdodCBwcmludCBhIG5ld2xpbmUgY2hhcmFjdGVyIGFuZCB0aGUgaW5kZW50YXRpb24gYW1vdW50Ci0gICAgICogb2YgdGhlIGdpdmVuIGRlcHRoLgotICAgICAqCi0gICAgICogQHBhcmFtIGRlcHRoIHRoZSBpbmRlbnRhdGlvbiBkZXB0aCAoZWxlbWVudCBuZXN0aW5nIGRlcHRoKQotICAgICAqCi0gICAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gaWYgYW4gZXJyb3Igb2NjdXJzIGR1cmluZyB3cml0aW5nLgotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIGluZGVudChpbnQgZGVwdGgpIHRocm93cyBJT0V4Y2VwdGlvbgotICAgIHsKLQotICAgICAgICBpZiAobV9zdGFydE5ld0xpbmUpCi0gICAgICAgICAgICBvdXRwdXRMaW5lU2VwKCk7Ci0gICAgICAgIC8qIEZvciBtX2luZGVudEFtb3VudCA+IDAgdGhpcyBleHRyYSB0ZXN0IG1pZ2h0IGJlIHNsb3dlcgotICAgICAgICAgKiBidXQgWGFsYW4ncyBkZWZhdWx0IHZhbHVlIGlzIDAsIHNvIHRoaXMgZXh0cmEgdGVzdAotICAgICAgICAgKiB3aWxsIHJ1biBmYXN0ZXIgaW4gdGhhdCBzaXR1YXRpb24uCi0gICAgICAgICAqLwotICAgICAgICBpZiAobV9pbmRlbnRBbW91bnQgPiAwKQotICAgICAgICAgICAgcHJpbnRTcGFjZShkZXB0aCAqIG1faW5kZW50QW1vdW50KTsKLQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEluZGVudCBhdCB0aGUgY3VycmVudCBlbGVtZW50IG5lc3RpbmcgZGVwdGguCi0gICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIGluZGVudCgpIHRocm93cyBJT0V4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaW5kZW50KG1fZWxlbUNvbnRleHQubV9jdXJyZW50RWxlbURlcHRoKTsKLSAgICB9Ci0gICAgLyoqCi0gICAgICogUHJpbnRzIDx2YXI+bjwvdmFyPiBzcGFjZXMuCi0gICAgICogQHBhcmFtIG4gICAgICAgICBOdW1iZXIgb2Ygc3BhY2VzIHRvIHByaW50LgotICAgICAqCi0gICAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gaWYgYW4gZXJyb3Igb2NjdXJzIHdoZW4gd3JpdGluZy4KLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgcHJpbnRTcGFjZShpbnQgbikgdGhyb3dzIElPRXhjZXB0aW9uCi0gICAgewotICAgICAgICBmaW5hbCBqYXZhLmlvLldyaXRlciB3cml0ZXIgPSBtX3dyaXRlcjsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspCi0gICAgICAgIHsKLSAgICAgICAgICAgIHdyaXRlci53cml0ZSgnICcpOwotICAgICAgICB9Ci0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXBvcnQgYW4gYXR0cmlidXRlIHR5cGUgZGVjbGFyYXRpb24uCi0gICAgICoKLSAgICAgKiA8cD5Pbmx5IHRoZSBlZmZlY3RpdmUgKGZpcnN0KSBkZWNsYXJhdGlvbiBmb3IgYW4gYXR0cmlidXRlIHdpbGwKLSAgICAgKiBiZSByZXBvcnRlZC4gIFRoZSB0eXBlIHdpbGwgYmUgb25lIG9mIHRoZSBzdHJpbmdzICJDREFUQSIsCi0gICAgICogIklEIiwgIklEUkVGIiwgIklEUkVGUyIsICJOTVRPS0VOIiwgIk5NVE9LRU5TIiwgIkVOVElUWSIsCi0gICAgICogIkVOVElUSUVTIiwgb3IgIk5PVEFUSU9OIiwgb3IgYSBwYXJlbnRoZXNpemVkIHRva2VuIGdyb3VwIHdpdGgKLSAgICAgKiB0aGUgc2VwYXJhdG9yICJ8IiBhbmQgYWxsIHdoaXRlc3BhY2UgcmVtb3ZlZC48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gZU5hbWUgVGhlIG5hbWUgb2YgdGhlIGFzc29jaWF0ZWQgZWxlbWVudC4KLSAgICAgKiBAcGFyYW0gYU5hbWUgVGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgKiBAcGFyYW0gdHlwZSBBIHN0cmluZyByZXByZXNlbnRpbmcgdGhlIGF0dHJpYnV0ZSB0eXBlLgotICAgICAqIEBwYXJhbSB2YWx1ZURlZmF1bHQgQSBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBhdHRyaWJ1dGUgZGVmYXVsdAotICAgICAqICAgICAgICAoIiNJTVBMSUVEIiwgIiNSRVFVSVJFRCIsIG9yICIjRklYRUQiKSBvciBudWxsIGlmCi0gICAgICogICAgICAgIG5vbmUgb2YgdGhlc2UgYXBwbGllcy4KLSAgICAgKiBAcGFyYW0gdmFsdWUgQSBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBhdHRyaWJ1dGUncyBkZWZhdWx0IHZhbHVlLAotICAgICAqICAgICAgICBvciBudWxsIGlmIHRoZXJlIGlzIG5vbmUuCi0gICAgICogQGV4Y2VwdGlvbiBTQVhFeGNlcHRpb24gVGhlIGFwcGxpY2F0aW9uIG1heSByYWlzZSBhbiBleGNlcHRpb24uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgYXR0cmlidXRlRGVjbCgKLSAgICAgICAgU3RyaW5nIGVOYW1lLAotICAgICAgICBTdHJpbmcgYU5hbWUsCi0gICAgICAgIFN0cmluZyB0eXBlLAotICAgICAgICBTdHJpbmcgdmFsdWVEZWZhdWx0LAotICAgICAgICBTdHJpbmcgdmFsdWUpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIC8vIERvIG5vdCBpbmxpbmUgZXh0ZXJuYWwgRFRECi0gICAgICAgIGlmIChtX2luRXh0ZXJuYWxEVEQpCi0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIHRyeQotICAgICAgICB7Ci0gICAgICAgICAgICBmaW5hbCBqYXZhLmlvLldyaXRlciB3cml0ZXIgPSBtX3dyaXRlcjsKLSAgICAgICAgICAgIERURHByb2xvZygpOwotCi0gICAgICAgICAgICB3cml0ZXIud3JpdGUoIjwhQVRUTElTVCAiKTsKLSAgICAgICAgICAgIHdyaXRlci53cml0ZShlTmFtZSk7Ci0gICAgICAgICAgICB3cml0ZXIud3JpdGUoJyAnKTsKLQotICAgICAgICAgICAgd3JpdGVyLndyaXRlKGFOYW1lKTsKLSAgICAgICAgICAgIHdyaXRlci53cml0ZSgnICcpOwotICAgICAgICAgICAgd3JpdGVyLndyaXRlKHR5cGUpOwotICAgICAgICAgICAgaWYgKHZhbHVlRGVmYXVsdCAhPSBudWxsKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZSgnICcpOwotICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZSh2YWx1ZURlZmF1bHQpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvL3dyaXRlci53cml0ZSgiICIpOwotICAgICAgICAgICAgLy93cml0ZXIud3JpdGUodmFsdWUpOwotICAgICAgICAgICAgd3JpdGVyLndyaXRlKCc+Jyk7Ci0gICAgICAgICAgICB3cml0ZXIud3JpdGUobV9saW5lU2VwLCAwLCBtX2xpbmVTZXBMZW4pOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChJT0V4Y2VwdGlvbiBlKQotICAgICAgICB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKGUpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBjaGFyYWN0ZXIgc3RyZWFtIHdoZXJlIHRoZSBldmVudHMgd2lsbCBiZSBzZXJpYWxpemVkIHRvLgotICAgICAqCi0gICAgICogQHJldHVybiBSZWZlcmVuY2UgdG8gdGhlIHJlc3VsdCBXcml0ZXIsIG9yIG51bGwuCi0gICAgICovCi0gICAgcHVibGljIFdyaXRlciBnZXRXcml0ZXIoKQotICAgIHsKLSAgICAgICAgcmV0dXJuIG1fd3JpdGVyOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJlcG9ydCBhIHBhcnNlZCBleHRlcm5hbCBlbnRpdHkgZGVjbGFyYXRpb24uCi0gICAgICoKLSAgICAgKiA8cD5Pbmx5IHRoZSBlZmZlY3RpdmUgKGZpcnN0KSBkZWNsYXJhdGlvbiBmb3IgZWFjaCBlbnRpdHkKLSAgICAgKiB3aWxsIGJlIHJlcG9ydGVkLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBlbnRpdHkuICBJZiBpdCBpcyBhIHBhcmFtZXRlcgotICAgICAqICAgICAgICBlbnRpdHksIHRoZSBuYW1lIHdpbGwgYmVnaW4gd2l0aCAnJScuCi0gICAgICogQHBhcmFtIHB1YmxpY0lkIFRoZSBkZWNsYXJlZCBwdWJsaWMgaWRlbnRpZmllciBvZiB0aGUgZW50aXR5LCBvcgotICAgICAqICAgICAgICBudWxsIGlmIG5vbmUgd2FzIGRlY2xhcmVkLgotICAgICAqIEBwYXJhbSBzeXN0ZW1JZCBUaGUgZGVjbGFyZWQgc3lzdGVtIGlkZW50aWZpZXIgb2YgdGhlIGVudGl0eS4KLSAgICAgKiBAZXhjZXB0aW9uIFNBWEV4Y2VwdGlvbiBUaGUgYXBwbGljYXRpb24gbWF5IHJhaXNlIGFuIGV4Y2VwdGlvbi4KLSAgICAgKiBAc2VlICNpbnRlcm5hbEVudGl0eURlY2wKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkRUREhhbmRsZXIjdW5wYXJzZWRFbnRpdHlEZWNsCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZXh0ZXJuYWxFbnRpdHlEZWNsKAotICAgICAgICBTdHJpbmcgbmFtZSwKLSAgICAgICAgU3RyaW5nIHB1YmxpY0lkLAotICAgICAgICBTdHJpbmcgc3lzdGVtSWQpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBEVERwcm9sb2coKTsKLQotICAgICAgICAgICAgbV93cml0ZXIud3JpdGUoIjwhRU5USVRZICIpOwotICAgICAgICAgICAgbV93cml0ZXIud3JpdGUobmFtZSk7Ci0gICAgICAgICAgICBpZiAocHVibGljSWQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIG1fd3JpdGVyLndyaXRlKCIgUFVCTElDIFwiIik7Ci0gICAgICAgICAgICAgICAgbV93cml0ZXIud3JpdGUocHVibGljSWQpOwotCi0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBtX3dyaXRlci53cml0ZSgiIFNZU1RFTSBcIiIpOwotICAgICAgICAgICAgICAgIG1fd3JpdGVyLndyaXRlKHN5c3RlbUlkKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIG1fd3JpdGVyLndyaXRlKCJcIiA+Iik7Ci0gICAgICAgICAgICBtX3dyaXRlci53cml0ZShtX2xpbmVTZXAsIDAsIG1fbGluZVNlcExlbik7Ci0gICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIC8vIFRPRE8gQXV0by1nZW5lcmF0ZWQgY2F0Y2ggYmxvY2sKLSAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgIH0KLQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRlbGwgaWYgdGhpcyBjaGFyYWN0ZXIgY2FuIGJlIHdyaXR0ZW4gd2l0aG91dCBlc2NhcGluZy4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBlc2NhcGluZ05vdE5lZWRlZChjaGFyIGNoKQotICAgIHsKLSAgICAgICAgZmluYWwgYm9vbGVhbiByZXQ7Ci0gICAgICAgIGlmIChjaCA8IDEyNykKLSAgICAgICAgewotICAgICAgICAgICAgLy8gVGhpcyBpcyB0aGUgb2xkL2Zhc3QgY29kZSBoZXJlLCBidXQgaXMgdGhpcwotICAgICAgICAgICAgLy8gY29ycmVjdCBmb3IgYWxsIGVuY29kaW5ncz8KLSAgICAgICAgICAgIGlmIChjaCA+PSAweDIwIHx8ICgweDBBID09IGNoIHx8IDB4MEQgPT0gY2ggfHwgMHgwOSA9PSBjaCkpCi0gICAgICAgICAgICAgICAgcmV0PSB0cnVlOwotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIHJldCA9IGZhbHNlOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgcmV0ID0gbV9lbmNvZGluZ0luZm8uaXNJbkVuY29kaW5nKGNoKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gcmV0OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIE9uY2UgYSBzdXJyb2dhdGUgaGFzIGJlZW4gZGV0ZWN0ZWQsIHdyaXRlIG91dCB0aGUgcGFpciBvZgotICAgICAqIGNoYXJhY3RlcnMgaWYgaXQgaXMgaW4gdGhlIGVuY29kaW5nLCBvciBpZiB0aGVyZSBpcyBubwotICAgICAqIGVuY29kaW5nLCBvdGhlcndpc2Ugd3JpdGUgb3V0IGFuIGVudGl0eSByZWZlcmVuY2UKLSAgICAgKiBvZiB0aGUgdmFsdWUgb2YgdGhlIHVuaWNvZGUgY29kZSBwb2ludCBvZiB0aGUgY2hhcmFjdGVyCi0gICAgICogcmVwcmVzZW50ZWQgYnkgdGhlIGhpZ2gvbG93IHN1cnJvZ2F0ZSBwYWlyLgotICAgICAqIDxwPgotICAgICAqIEFuIGV4Y2VwdGlvbiBpcyB0aHJvd24gaWYgdGhlcmUgaXMgbm8gbG93IHN1cnJvZ2F0ZSBpbiB0aGUgcGFpciwKLSAgICAgKiBiZWNhdXNlIHRoZSBhcnJheSBlbmRzIHVuZXhwZWN0ZWx5LCBvciBpZiB0aGUgbG93IGNoYXIgaXMgdGhlcmUKLSAgICAgKiBidXQgaXRzIHZhbHVlIGlzIHN1Y2ggdGhhdCBpdCBpcyBub3QgYSBsb3cgc3Vycm9nYXRlLgotICAgICAqCi0gICAgICogQHBhcmFtIGMgdGhlIGZpcnN0IChoaWdoKSBwYXJ0IG9mIHRoZSBzdXJyb2dhdGUsIHdoaWNoCi0gICAgICogbXVzdCBiZSBjb25maXJtZWQgYmVmb3JlIGNhbGxpbmcgdGhpcyBtZXRob2QuCi0gICAgICogQHBhcmFtIGNoIENoYXJhY3RlciBhcnJheS4KLSAgICAgKiBAcGFyYW0gaSBwb3NpdGlvbiBXaGVyZSB0aGUgc3Vycm9nYXRlIHdhcyBkZXRlY3RlZC4KLSAgICAgKiBAcGFyYW0gZW5kIFRoZSBlbmQgaW5kZXggb2YgdGhlIHNpZ25pZmljYW50IGNoYXJhY3RlcnMuCi0gICAgICogQHJldHVybiAwIGlmIHRoZSBwYWlyIG9mIGNoYXJhY3RlcnMgd2FzIHdyaXR0ZW4gb3V0IGFzLWlzLAotICAgICAqIHRoZSB1bmljb2RlIGNvZGUgcG9pbnQgb2YgdGhlIGNoYXJhY3RlciByZXByZXNlbnRlZCBieQotICAgICAqIHRoZSBzdXJyb2dhdGUgcGFpciBpZiBhbiBlbnRpdHkgcmVmZXJlbmNlIHdpdGggdGhhdCB2YWx1ZQotICAgICAqIHdhcyB3cml0dGVuIG91dC4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLSAgICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBpZiBpbnZhbGlkIFVURi0xNiBzdXJyb2dhdGUgZGV0ZWN0ZWQuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGludCB3cml0ZVVURjE2U3Vycm9nYXRlKGNoYXIgYywgY2hhciBjaFtdLCBpbnQgaSwgaW50IGVuZCkKLSAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uCi0gICAgewotICAgICAgICBpbnQgY29kZVBvaW50ID0gMDsKLSAgICAgICAgaWYgKGkgKyAxID49IGVuZCkKLSAgICAgICAgewotICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgIFV0aWxzLm1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoCi0gICAgICAgICAgICAgICAgICAgIE1zZ0tleS5FUl9JTlZBTElEX1VURjE2X1NVUlJPR0FURSwKLSAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgSW50ZWdlci50b0hleFN0cmluZygoaW50KSBjKX0pKTsKLSAgICAgICAgfQotCi0gICAgICAgIGZpbmFsIGNoYXIgaGlnaCA9IGM7Ci0gICAgICAgIGZpbmFsIGNoYXIgbG93ID0gY2hbaSsxXTsKLSAgICAgICAgaWYgKCFFbmNvZGluZ3MuaXNMb3dVVEYxNlN1cnJvZ2F0ZShsb3cpKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgVXRpbHMubWVzc2FnZXMuY3JlYXRlTWVzc2FnZSgKLSAgICAgICAgICAgICAgICAgICAgTXNnS2V5LkVSX0lOVkFMSURfVVRGMTZfU1VSUk9HQVRFLAotICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10gewotICAgICAgICAgICAgICAgICAgICAgICAgSW50ZWdlci50b0hleFN0cmluZygoaW50KSBjKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiAiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBJbnRlZ2VyLnRvSGV4U3RyaW5nKGxvdyl9KSk7Ci0gICAgICAgIH0KLQotICAgICAgICBmaW5hbCBqYXZhLmlvLldyaXRlciB3cml0ZXIgPSBtX3dyaXRlcjsKLQotICAgICAgICAvLyBJZiB3ZSBtYWtlIGl0IHRvIGhlcmUgd2UgaGF2ZSBhIHZhbGlkIGhpZ2gsIGxvdyBzdXJyb2dhdGUgcGFpcgotICAgICAgICBpZiAobV9lbmNvZGluZ0luZm8uaXNJbkVuY29kaW5nKGMsbG93KSkgewotICAgICAgICAgICAgLy8gSWYgdGhlIGNoYXJhY3RlciBmb3JtZWQgYnkgdGhlIHN1cnJvZ2F0ZSBwYWlyCi0gICAgICAgICAgICAvLyBpcyBpbiB0aGUgZW5jb2RpbmcsIHNvIGp1c3Qgd3JpdGUgaXQgb3V0Ci0gICAgICAgICAgICB3cml0ZXIud3JpdGUoY2gsaSwyKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIC8vIERvbid0IGtub3cgd2hhdCB0byBkbyB3aXRoIHRoaXMgY2hhciwgaXQgaXMKLSAgICAgICAgICAgIC8vIG5vdCBpbiB0aGUgZW5jb2RpbmcgYW5kIG5vdCBhIGhpZ2ggY2hhciBpbgotICAgICAgICAgICAgLy8gYSBzdXJyb2dhdGUgcGFpciwgc28gd3JpdGUgb3V0IGFzIGFuIGVudGl0eSByZWYKLSAgICAgICAgICAgIGZpbmFsIFN0cmluZyBlbmNvZGluZyA9IGdldEVuY29kaW5nKCk7Ci0gICAgICAgICAgICBpZiAoZW5jb2RpbmcgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIC8qIFRoZSBvdXRwdXQgZW5jb2RpbmcgaXMga25vd24sCi0gICAgICAgICAgICAgICAgICogc28gc29tdGhpbmcgaXMgd3JvbmcuCi0gICAgICAgICAgICAgICAgICAqLwotICAgICAgICAgICAgICAgIGNvZGVQb2ludCA9IEVuY29kaW5ncy50b0NvZGVQb2ludChoaWdoLCBsb3cpOwotICAgICAgICAgICAgICAgIC8vIG5vdCBpbiB0aGUgZW5jb2RpbmcsIHNvIHdyaXRlIG91dCBhIGNoYXJhY3RlciByZWZlcmVuY2UKLSAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoJyYnKTsKLSAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoJyMnKTsKLSAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoSW50ZWdlci50b1N0cmluZyhjb2RlUG9pbnQpKTsKLSAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoJzsnKTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgLyogVGhlIG91dHB1dCBlbmNvZGluZyBpcyBub3Qga25vd24sCi0gICAgICAgICAgICAgICAgICogc28ganVzdCB3cml0ZSBpdCBvdXQgYXMtaXMuCi0gICAgICAgICAgICAgICAgICovCi0gICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKGNoLCBpLCAyKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICAvLyBub24temVybyBvbmx5IGlmIGNoYXJhY3RlciByZWZlcmVuY2Ugd2FzIHdyaXR0ZW4gb3V0LgotICAgICAgICByZXR1cm4gY29kZVBvaW50OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEhhbmRsZSBvbmUgb2YgdGhlIGRlZmF1bHQgZW50aXRpZXMsIHJldHVybiBmYWxzZSBpZiBpdAotICAgICAqIGlzIG5vdCBhIGRlZmF1bHQgZW50aXR5LgotICAgICAqCi0gICAgICogQHBhcmFtIGNoIGNoYXJhY3RlciB0byBiZSBlc2NhcGVkLgotICAgICAqIEBwYXJhbSBpIGluZGV4IGludG8gY2hhcmFjdGVyIGFycmF5LgotICAgICAqIEBwYXJhbSBjaGFycyBub24tbnVsbCByZWZlcmVuY2UgdG8gY2hhcmFjdGVyIGFycmF5LgotICAgICAqIEBwYXJhbSBsZW4gbGVuZ3RoIG9mIGNoYXJzLgotICAgICAqIEBwYXJhbSBmcm9tVGV4dE5vZGUgdHJ1ZSBpZiB0aGUgY2hhcmFjdGVycyBiZWluZyBwcm9jZXNzZWQKLSAgICAgKiBhcmUgZnJvbSBhIHRleHQgbm9kZSwgZmFsc2UgaWYgdGhleSBhcmUgZnJvbSBhbiBhdHRyaWJ1dGUgdmFsdWUKLSAgICAgKiBAcGFyYW0gZXNjTEYgdHJ1ZSBpZiB0aGUgbGluZWZlZWQgc2hvdWxkIGJlIGVzY2FwZWQuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIGkrMSBpZiB0aGUgY2hhcmFjdGVyIHdhcyB3cml0dGVuLCBlbHNlIGkuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgaW50IGFjY3VtRGVmYXVsdEVudGl0eSgKLSAgICAgICAgamF2YS5pby5Xcml0ZXIgd3JpdGVyLAotICAgICAgICBjaGFyIGNoLAotICAgICAgICBpbnQgaSwKLSAgICAgICAgY2hhcltdIGNoYXJzLAotICAgICAgICBpbnQgbGVuLAotICAgICAgICBib29sZWFuIGZyb21UZXh0Tm9kZSwKLSAgICAgICAgYm9vbGVhbiBlc2NMRikKLSAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uCi0gICAgewotCi0gICAgICAgIGlmICghZXNjTEYgJiYgQ2hhckluZm8uU19MSU5FRkVFRCA9PSBjaCkKLSAgICAgICAgewotICAgICAgICAgICAgd3JpdGVyLndyaXRlKG1fbGluZVNlcCwgMCwgbV9saW5lU2VwTGVuKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgIHsKLSAgICAgICAgICAgIC8vIGlmIHRoaXMgaXMgdGV4dCBub2RlIGNoYXJhY3RlciBhbmQgYSBzcGVjaWFsIG9uZSBvZiB0aG9zZSwKLSAgICAgICAgICAgIC8vIG9yIGlmIHRoaXMgaXMgYSBjaGFyYWN0ZXIgZnJvbSBhdHRyaWJ1dGUgdmFsdWUgYW5kIGEgc3BlY2lhbCBvbmUgb2YgdGhvc2UKLSAgICAgICAgICAgIGlmICgoZnJvbVRleHROb2RlICYmIG1fY2hhckluZm8uaXNTcGVjaWFsVGV4dENoYXIoY2gpKSB8fCAoIWZyb21UZXh0Tm9kZSAmJiBtX2NoYXJJbmZvLmlzU3BlY2lhbEF0dHJDaGFyKGNoKSkpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIG91dHB1dFN0cmluZ0ZvckNoYXIgPSBtX2NoYXJJbmZvLmdldE91dHB1dFN0cmluZ0ZvckNoYXIoY2gpOwotCi0gICAgICAgICAgICAgICAgaWYgKG51bGwgIT0gb3V0cHV0U3RyaW5nRm9yQ2hhcikKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZShvdXRwdXRTdHJpbmdGb3JDaGFyKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICByZXR1cm4gaTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICByZXR1cm4gaTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBpICsgMTsKLQotICAgIH0KLSAgICAvKioKLSAgICAgKiBOb3JtYWxpemUgdGhlIGNoYXJhY3RlcnMsIGJ1dCBkb24ndCBlc2NhcGUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY2ggVGhlIGNoYXJhY3RlcnMgZnJvbSB0aGUgWE1MIGRvY3VtZW50LgotICAgICAqIEBwYXJhbSBzdGFydCBUaGUgc3RhcnQgcG9zaXRpb24gaW4gdGhlIGFycmF5LgotICAgICAqIEBwYXJhbSBsZW5ndGggVGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHJlYWQgZnJvbSB0aGUgYXJyYXkuCi0gICAgICogQHBhcmFtIGlzQ0RhdGEgdHJ1ZSBpZiBhIENEQVRBIGJsb2NrIHNob3VsZCBiZSBidWlsdCBhcm91bmQgdGhlIGNoYXJhY3RlcnMuCi0gICAgICogQHBhcmFtIHVzZVN5c3RlbUxpbmVTZXBhcmF0b3IgdHJ1ZSBpZiB0aGUgb3BlcmF0aW5nIHN5c3RlbXMKLSAgICAgKiBlbmQtb2YtbGluZSBzZXBhcmF0b3Igc2hvdWxkIGJlIG91dHB1dCByYXRoZXIgdGhhbiBhIG5ldy1saW5lIGNoYXJhY3Rlci4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLSAgICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgICAqLwotICAgIHZvaWQgd3JpdGVOb3JtYWxpemVkQ2hhcnMoCi0gICAgICAgIGNoYXIgY2hbXSwKLSAgICAgICAgaW50IHN0YXJ0LAotICAgICAgICBpbnQgbGVuZ3RoLAotICAgICAgICBib29sZWFuIGlzQ0RhdGEsCi0gICAgICAgIGJvb2xlYW4gdXNlU3lzdGVtTGluZVNlcGFyYXRvcikKLSAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGZpbmFsIGphdmEuaW8uV3JpdGVyIHdyaXRlciA9IG1fd3JpdGVyOwotICAgICAgICBpbnQgZW5kID0gc3RhcnQgKyBsZW5ndGg7Ci0KLSAgICAgICAgZm9yIChpbnQgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpKyspCi0gICAgICAgIHsKLSAgICAgICAgICAgIGNoYXIgYyA9IGNoW2ldOwotCi0gICAgICAgICAgICBpZiAoQ2hhckluZm8uU19MSU5FRkVFRCA9PSBjICYmIHVzZVN5c3RlbUxpbmVTZXBhcmF0b3IpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKG1fbGluZVNlcCwgMCwgbV9saW5lU2VwTGVuKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKGlzQ0RhdGEgJiYgKCFlc2NhcGluZ05vdE5lZWRlZChjKSkpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgLy8gICAgICAgICAgICAgICAgaWYgKGkgIT0gMCkKLSAgICAgICAgICAgICAgICBpZiAobV9jZGF0YVRhZ09wZW4pCi0gICAgICAgICAgICAgICAgICAgIGNsb3NlQ0RBVEEoKTsKLQotICAgICAgICAgICAgICAgIC8vIFRoaXMgbmVlZHMgdG8gZ28gaW50byBhIGZ1bmN0aW9uLi4uCi0gICAgICAgICAgICAgICAgaWYgKEVuY29kaW5ncy5pc0hpZ2hVVEYxNlN1cnJvZ2F0ZShjKSkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIHdyaXRlVVRGMTZTdXJyb2dhdGUoYywgY2gsIGksIGVuZCk7Ci0gICAgICAgICAgICAgICAgICAgIGkrKyA7IC8vIHByb2Nlc3MgdHdvIGlucHV0IGNoYXJhY3RlcnMKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKCImIyIpOwotCi0gICAgICAgICAgICAgICAgICAgIFN0cmluZyBpbnRTdHIgPSBJbnRlZ2VyLnRvU3RyaW5nKChpbnQpIGMpOwotCi0gICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZShpbnRTdHIpOwotICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoJzsnKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyAgICAgICAgICAgICAgICBpZiAoKGkgIT0gMCkgJiYgKGkgPCAoZW5kIC0gMSkpKQotICAgICAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgIGlmICghbV9jZGF0YVRhZ09wZW4gJiYgKGkgPCAoZW5kIC0gMSkpKQotICAgICAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAvLyAgICAgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKENEQVRBX0RFTElNSVRFUl9PUEVOKTsKLSAgICAgICAgICAgICAgICAvLyAgICAgICAgICAgICAgICAgICAgbV9jZGF0YVRhZ09wZW4gPSB0cnVlOwotICAgICAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKAotICAgICAgICAgICAgICAgIGlzQ0RhdGEKLSAgICAgICAgICAgICAgICAgICAgJiYgKChpIDwgKGVuZCAtIDIpKQotICAgICAgICAgICAgICAgICAgICAgICAgJiYgKCddJyA9PSBjKQotICAgICAgICAgICAgICAgICAgICAgICAgJiYgKCddJyA9PSBjaFtpICsgMV0pCi0gICAgICAgICAgICAgICAgICAgICAgICAmJiAoJz4nID09IGNoW2kgKyAyXSkpKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZShDREFUQV9DT05USU5VRSk7Ci0KLSAgICAgICAgICAgICAgICBpICs9IDI7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgaWYgKGVzY2FwaW5nTm90TmVlZGVkKGMpKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGlzQ0RhdGEgJiYgIW1fY2RhdGFUYWdPcGVuKQotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoQ0RBVEFfREVMSU1JVEVSX09QRU4pOwotICAgICAgICAgICAgICAgICAgICAgICAgbV9jZGF0YVRhZ09wZW4gPSB0cnVlOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZShjKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvLyBUaGlzIG5lZWRzIHRvIGdvIGludG8gYSBmdW5jdGlvbi4uLgotICAgICAgICAgICAgICAgIGVsc2UgaWYgKEVuY29kaW5ncy5pc0hpZ2hVVEYxNlN1cnJvZ2F0ZShjKSkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChtX2NkYXRhVGFnT3BlbikKLSAgICAgICAgICAgICAgICAgICAgICAgIGNsb3NlQ0RBVEEoKTsKLSAgICAgICAgICAgICAgICAgICAgd3JpdGVVVEYxNlN1cnJvZ2F0ZShjLCBjaCwgaSwgZW5kKTsKLSAgICAgICAgICAgICAgICAgICAgaSsrOyAvLyBwcm9jZXNzIHR3byBpbnB1dCBjaGFyYWN0ZXJzCi0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChtX2NkYXRhVGFnT3BlbikKLSAgICAgICAgICAgICAgICAgICAgICAgIGNsb3NlQ0RBVEEoKTsKLSAgICAgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKCImIyIpOwotCi0gICAgICAgICAgICAgICAgICAgIFN0cmluZyBpbnRTdHIgPSBJbnRlZ2VyLnRvU3RyaW5nKChpbnQpIGMpOwotCi0gICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZShpbnRTdHIpOwotICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoJzsnKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEVuZHMgYW4gdW4tZXNjYXBpbmcgc2VjdGlvbi4KLSAgICAgKgotICAgICAqIEBzZWUgI3N0YXJ0Tm9uRXNjYXBpbmcKLSAgICAgKgotICAgICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kTm9uRXNjYXBpbmcoKSB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBtX2Rpc2FibGVPdXRwdXRFc2NhcGluZ1N0YXRlcy5wb3AoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTdGFydHMgYW4gdW4tZXNjYXBpbmcgc2VjdGlvbi4gQWxsIGNoYXJhY3RlcnMgcHJpbnRlZCB3aXRoaW4gYW4gdW4tCi0gICAgICogZXNjYXBpbmcgc2VjdGlvbiBhcmUgcHJpbnRlZCBhcyBpcywgd2l0aG91dCBlc2NhcGluZyBzcGVjaWFsIGNoYXJhY3RlcnMKLSAgICAgKiBpbnRvIGVudGl0eSByZWZlcmVuY2VzLiBPbmx5IFhNTCBhbmQgSFRNTCBzZXJpYWxpemVycyBuZWVkIHRvIHN1cHBvcnQKLSAgICAgKiB0aGlzIG1ldGhvZC4KLSAgICAgKiA8cD4gVGhlIGNvbnRlbnRzIG9mIHRoZSB1bi1lc2NhcGluZyBzZWN0aW9uIHdpbGwgYmUgZGVsaXZlcmVkIHRocm91Z2ggdGhlCi0gICAgICogcmVndWxhciA8dHQ+Y2hhcmFjdGVyczwvdHQ+IGV2ZW50LgotICAgICAqCi0gICAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydE5vbkVzY2FwaW5nKCkgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgbV9kaXNhYmxlT3V0cHV0RXNjYXBpbmdTdGF0ZXMucHVzaCh0cnVlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBjZGF0YS4KLSAgICAgKgotICAgICAqIDxwPlRoZSBQYXJzZXIgd2lsbCBjYWxsIHRoaXMgbWV0aG9kIHRvIHJlcG9ydCBlYWNoIGNodW5rIG9mCi0gICAgICogY2hhcmFjdGVyIGRhdGEuICBTQVggcGFyc2VycyBtYXkgcmV0dXJuIGFsbCBjb250aWd1b3VzIGNoYXJhY3RlcgotICAgICAqIGRhdGEgaW4gYSBzaW5nbGUgY2h1bmssIG9yIHRoZXkgbWF5IHNwbGl0IGl0IGludG8gc2V2ZXJhbAotICAgICAqIGNodW5rczsgaG93ZXZlciwgYWxsIG9mIHRoZSBjaGFyYWN0ZXJzIGluIGFueSBzaW5nbGUgZXZlbnQKLSAgICAgKiBtdXN0IGNvbWUgZnJvbSB0aGUgc2FtZSBleHRlcm5hbCBlbnRpdHksIHNvIHRoYXQgdGhlIExvY2F0b3IKLSAgICAgKiBwcm92aWRlcyB1c2VmdWwgaW5mb3JtYXRpb24uPC9wPgotICAgICAqCi0gICAgICogPHA+VGhlIGFwcGxpY2F0aW9uIG11c3Qgbm90IGF0dGVtcHQgdG8gcmVhZCBmcm9tIHRoZSBhcnJheQotICAgICAqIG91dHNpZGUgb2YgdGhlIHNwZWNpZmllZCByYW5nZS48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5Ob3RlIHRoYXQgc29tZSBwYXJzZXJzIHdpbGwgcmVwb3J0IHdoaXRlc3BhY2UgdXNpbmcgdGhlCi0gICAgICogaWdub3JhYmxlV2hpdGVzcGFjZSgpIG1ldGhvZCByYXRoZXIgdGhhbiB0aGlzIG9uZSAodmFsaWRhdGluZwotICAgICAqIHBhcnNlcnMgbXVzdCBkbyBzbykuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGNoIFRoZSBjaGFyYWN0ZXJzIGZyb20gdGhlIFhNTCBkb2N1bWVudC4KLSAgICAgKiBAcGFyYW0gc3RhcnQgVGhlIHN0YXJ0IHBvc2l0aW9uIGluIHRoZSBhcnJheS4KLSAgICAgKiBAcGFyYW0gbGVuZ3RoIFRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyB0byByZWFkIGZyb20gdGhlIGFycmF5LgotICAgICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAgICogQHNlZSAjaWdub3JhYmxlV2hpdGVzcGFjZQotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguTG9jYXRvcgotICAgICAqCi0gICAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCBjZGF0YShjaGFyIGNoW10sIGludCBzdGFydCwgZmluYWwgaW50IGxlbmd0aCkKLSAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgIHsKLQotICAgICAgICB0cnkKLSAgICAgICAgewotICAgICAgICAgICAgZmluYWwgaW50IG9sZF9zdGFydCA9IHN0YXJ0OwotICAgICAgICAgICAgaWYgKG1fZWxlbUNvbnRleHQubV9zdGFydFRhZ09wZW4pCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgY2xvc2VTdGFydFRhZygpOwotICAgICAgICAgICAgICAgIG1fZWxlbUNvbnRleHQubV9zdGFydFRhZ09wZW4gPSBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIG1faXNwcmVzZXJ2ZSA9IHRydWU7Ci0KLSAgICAgICAgICAgIGlmIChzaG91bGRJbmRlbnQoKSkKLSAgICAgICAgICAgICAgICBpbmRlbnQoKTsKLQotICAgICAgICAgICAgYm9vbGVhbiB3cml0ZUNEYXRhQnJhY2tldHMgPQotICAgICAgICAgICAgICAgICgoKGxlbmd0aCA+PSAxKSAmJiBlc2NhcGluZ05vdE5lZWRlZChjaFtzdGFydF0pKSk7Ci0KLSAgICAgICAgICAgIC8qIFdyaXRlIG91dCB0aGUgQ0RBVEEgb3BlbmluZyBkZWxpbWl0ZXIgb25seSBpZgotICAgICAgICAgICAgICogd2UgYXJlIHN1cHBvc2VkIHRvLCBhbmQgaWYgd2UgYXJlIG5vdCBhbHJlYWR5IGluCi0gICAgICAgICAgICAgKiB0aGUgbWlkZGxlIG9mIGEgQ0RBVEEgc2VjdGlvbgotICAgICAgICAgICAgICovCi0gICAgICAgICAgICBpZiAod3JpdGVDRGF0YUJyYWNrZXRzICYmICFtX2NkYXRhVGFnT3BlbikKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBtX3dyaXRlci53cml0ZShDREFUQV9ERUxJTUlURVJfT1BFTik7Ci0gICAgICAgICAgICAgICAgbV9jZGF0YVRhZ09wZW4gPSB0cnVlOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyB3cml0ZXIud3JpdGUoY2gsIHN0YXJ0LCBsZW5ndGgpOwotICAgICAgICAgICAgaWYgKGlzRXNjYXBpbmdEaXNhYmxlZCgpKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIGNoYXJhY3RlcnNSYXcoY2gsIHN0YXJ0LCBsZW5ndGgpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIHdyaXRlTm9ybWFsaXplZENoYXJzKGNoLCBzdGFydCwgbGVuZ3RoLCB0cnVlLCBtX2xpbmVTZXBVc2UpOwotCi0gICAgICAgICAgICAvKiB1c2VkIHRvIGFsd2F5cyB3cml0ZSBvdXQgQ0RBVEEgY2xvc2luZyBkZWxpbWl0ZXIgaGVyZSwKLSAgICAgICAgICAgICAqIGJ1dCBub3cgd2UgZGVsYXksIHNvIHRoYXQgd2UgY2FuIG1lcmdlIENEQVRBIHNlY3Rpb25zIG9uIG91dHB1dC4KLSAgICAgICAgICAgICAqIG5lZWQgdG8gd3JpdGUgY2xvc2luZyBkZWxpbWl0ZXIgbGF0ZXIKLSAgICAgICAgICAgICAqLwotICAgICAgICAgICAgaWYgKHdyaXRlQ0RhdGFCcmFja2V0cykKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAvKiBpZiB0aGUgQ0RBVEEgc2VjdGlvbiBlbmRzIHdpdGggXSBkb24ndCBsZWF2ZSBpdCBvcGVuCi0gICAgICAgICAgICAgICAgICogYXMgdGhlcmUgaXMgYSBjaGFuY2UgdGhhdCBhbiBhZGphY2VudCBDREFUQSBzZWN0aW9ucwotICAgICAgICAgICAgICAgICAqIHN0YXJ0cyB3aXRoIF0+LgotICAgICAgICAgICAgICAgICAqIFdlIGRvbid0IHdhbnQgdG8gbWVyZ2UgXV0gd2l0aCA+ICwgb3IgXSB3aXRoIF0+Ci0gICAgICAgICAgICAgICAgICovCi0gICAgICAgICAgICAgICAgaWYgKGNoW3N0YXJ0ICsgbGVuZ3RoIC0gMV0gPT0gJ10nKQotICAgICAgICAgICAgICAgICAgICBjbG9zZUNEQVRBKCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIHRpbWUgdG8gZmlyZSBvZmYgQ0RBVEEgZXZlbnQKLSAgICAgICAgICAgIGlmIChtX3RyYWNlciAhPSBudWxsKQotICAgICAgICAgICAgICAgIHN1cGVyLmZpcmVDREFUQUV2ZW50KGNoLCBvbGRfc3RhcnQsIGxlbmd0aCk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKElPRXhjZXB0aW9uIGlvZSkKLSAgICAgICAgewotICAgICAgICAgICAgdGhyb3cgbmV3IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICBVdGlscy5tZXNzYWdlcy5jcmVhdGVNZXNzYWdlKAotICAgICAgICAgICAgICAgICAgICBNc2dLZXkuRVJfT0lFUlJPUiwKLSAgICAgICAgICAgICAgICAgICAgbnVsbCksCi0gICAgICAgICAgICAgICAgaW9lKTsKLSAgICAgICAgICAgIC8vIklPIGVycm9yIiwgaW9lKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRlbGwgaWYgdGhlIGNoYXJhY3RlciBlc2NhcGluZyBzaG91bGQgYmUgZGlzYWJsZWQgZm9yIHRoZSBjdXJyZW50IHN0YXRlLgotICAgICAqCi0gICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBjaGFyYWN0ZXIgZXNjYXBpbmcgc2hvdWxkIGJlIGRpc2FibGVkLgotICAgICAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBpc0VzY2FwaW5nRGlzYWJsZWQoKQotICAgIHsKLSAgICAgICAgcmV0dXJuIG1fZGlzYWJsZU91dHB1dEVzY2FwaW5nU3RhdGVzLnBlZWtPckZhbHNlKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSWYgYXZhaWxhYmxlLCB3aGVuIHRoZSBkaXNhYmxlLW91dHB1dC1lc2NhcGluZyBhdHRyaWJ1dGUgaXMgdXNlZCwKLSAgICAgKiBvdXRwdXQgcmF3IHRleHQgd2l0aG91dCBlc2NhcGluZy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjaCBUaGUgY2hhcmFjdGVycyBmcm9tIHRoZSBYTUwgZG9jdW1lbnQuCi0gICAgICogQHBhcmFtIHN0YXJ0IFRoZSBzdGFydCBwb3NpdGlvbiBpbiB0aGUgYXJyYXkuCi0gICAgICogQHBhcmFtIGxlbmd0aCBUaGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gcmVhZCBmcm9tIHRoZSBhcnJheS4KLSAgICAgKgotICAgICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgY2hhcmFjdGVyc1JhdyhjaGFyIGNoW10sIGludCBzdGFydCwgaW50IGxlbmd0aCkKLSAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgIHsKLQotICAgICAgICBpZiAobV9pbkVudGl0eVJlZikKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgdHJ5Ci0gICAgICAgIHsKLSAgICAgICAgICAgIGlmIChtX2VsZW1Db250ZXh0Lm1fc3RhcnRUYWdPcGVuKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIGNsb3NlU3RhcnRUYWcoKTsKLSAgICAgICAgICAgICAgICBtX2VsZW1Db250ZXh0Lm1fc3RhcnRUYWdPcGVuID0gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIG1faXNwcmVzZXJ2ZSA9IHRydWU7Ci0KLSAgICAgICAgICAgIG1fd3JpdGVyLndyaXRlKGNoLCBzdGFydCwgbGVuZ3RoKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoSU9FeGNlcHRpb24gZSkKLSAgICAgICAgewotICAgICAgICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbihlKTsKLSAgICAgICAgfQotCi0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgY2hhcmFjdGVyIGRhdGEuCi0gICAgICoKLSAgICAgKiA8cD5UaGUgUGFyc2VyIHdpbGwgY2FsbCB0aGlzIG1ldGhvZCB0byByZXBvcnQgZWFjaCBjaHVuayBvZgotICAgICAqIGNoYXJhY3RlciBkYXRhLiAgU0FYIHBhcnNlcnMgbWF5IHJldHVybiBhbGwgY29udGlndW91cyBjaGFyYWN0ZXIKLSAgICAgKiBkYXRhIGluIGEgc2luZ2xlIGNodW5rLCBvciB0aGV5IG1heSBzcGxpdCBpdCBpbnRvIHNldmVyYWwKLSAgICAgKiBjaHVua3M7IGhvd2V2ZXIsIGFsbCBvZiB0aGUgY2hhcmFjdGVycyBpbiBhbnkgc2luZ2xlIGV2ZW50Ci0gICAgICogbXVzdCBjb21lIGZyb20gdGhlIHNhbWUgZXh0ZXJuYWwgZW50aXR5LCBzbyB0aGF0IHRoZSBMb2NhdG9yCi0gICAgICogcHJvdmlkZXMgdXNlZnVsIGluZm9ybWF0aW9uLjwvcD4KLSAgICAgKgotICAgICAqIDxwPlRoZSBhcHBsaWNhdGlvbiBtdXN0IG5vdCBhdHRlbXB0IHRvIHJlYWQgZnJvbSB0aGUgYXJyYXkKLSAgICAgKiBvdXRzaWRlIG9mIHRoZSBzcGVjaWZpZWQgcmFuZ2UuPC9wPgotICAgICAqCi0gICAgICogPHA+Tm90ZSB0aGF0IHNvbWUgcGFyc2VycyB3aWxsIHJlcG9ydCB3aGl0ZXNwYWNlIHVzaW5nIHRoZQotICAgICAqIGlnbm9yYWJsZVdoaXRlc3BhY2UoKSBtZXRob2QgcmF0aGVyIHRoYW4gdGhpcyBvbmUgKHZhbGlkYXRpbmcKLSAgICAgKiBwYXJzZXJzIG11c3QgZG8gc28pLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjaGFycyBUaGUgY2hhcmFjdGVycyBmcm9tIHRoZSBYTUwgZG9jdW1lbnQuCi0gICAgICogQHBhcmFtIHN0YXJ0IFRoZSBzdGFydCBwb3NpdGlvbiBpbiB0aGUgYXJyYXkuCi0gICAgICogQHBhcmFtIGxlbmd0aCBUaGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gcmVhZCBmcm9tIHRoZSBhcnJheS4KLSAgICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgICAqIEBzZWUgI2lnbm9yYWJsZVdoaXRlc3BhY2UKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkxvY2F0b3IKLSAgICAgKgotICAgICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY2hhcmFjdGVycyhmaW5hbCBjaGFyIGNoYXJzW10sIGZpbmFsIGludCBzdGFydCwgZmluYWwgaW50IGxlbmd0aCkKLSAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgLy8gSXQgZG9lcyBub3QgbWFrZSBzZW5zZSB0byBjb250aW51ZSB3aXRoIHJlc3Qgb2YgdGhlIG1ldGhvZCBpZiB0aGUgbnVtYmVyIG9mCi0gICAgICAgIC8vIGNoYXJhY3RlcnMgdG8gcmVhZCBmcm9tIGFycmF5IGlzIDAuCi0gICAgICAgIC8vIFNlY3Rpb24gNy42LjEgb2YgWFNMVCAxLjAgKGh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjdmFsdWUtb2YpIHN1Z2dlc3Qgbm8gdGV4dCBub2RlCi0gICAgICAgIC8vIGlzIGNyZWF0ZWQgaWYgc3RyaW5nIGlzIGVtcHR5LgotICAgICAgICBpZiAobGVuZ3RoID09IDAgfHwgKG1faW5FbnRpdHlSZWYgJiYgIW1fZXhwYW5kRFRERW50aXRpZXMpKQotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICBpZiAobV9lbGVtQ29udGV4dC5tX3N0YXJ0VGFnT3BlbikKLSAgICAgICAgewotICAgICAgICAgICAgY2xvc2VTdGFydFRhZygpOwotICAgICAgICAgICAgbV9lbGVtQ29udGV4dC5tX3N0YXJ0VGFnT3BlbiA9IGZhbHNlOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKG1fbmVlZFRvQ2FsbFN0YXJ0RG9jdW1lbnQpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHN0YXJ0RG9jdW1lbnRJbnRlcm5hbCgpOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKG1fY2RhdGFTdGFydENhbGxlZCB8fCBtX2VsZW1Db250ZXh0Lm1faXNDZGF0YVNlY3Rpb24pCi0gICAgICAgIHsKLSAgICAgICAgICAgIC8qIGVpdGhlciBkdWUgdG8gc3RhcnRDREFUQSgpIGJlaW5nIGNhbGxlZCBvciBkdWUgdG8KLSAgICAgICAgICAgICAqIGNkYXRhLXNlY3Rpb24tZWxlbWVudHMgYXRyaWJ1dGUsIHdlIG5lZWQgdGhpcyBhcyBjZGF0YQotICAgICAgICAgICAgICovCi0gICAgICAgICAgICBjZGF0YShjaGFycywgc3RhcnQsIGxlbmd0aCk7Ci0KLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChtX2NkYXRhVGFnT3BlbikKLSAgICAgICAgICAgIGNsb3NlQ0RBVEEoKTsKLSAgICAgICAgLy8gdGhlIGNoZWNrIHdpdGggX2VzY2FwaW5nIGlzIGEgYml0IG9mIGEgaGFjayBmb3IgWExTVEMKLQotICAgICAgICBpZiAobV9kaXNhYmxlT3V0cHV0RXNjYXBpbmdTdGF0ZXMucGVla09yRmFsc2UoKSB8fCAoIW1fZXNjYXBpbmcpKQotICAgICAgICB7Ci0gICAgICAgICAgICBjaGFyYWN0ZXJzUmF3KGNoYXJzLCBzdGFydCwgbGVuZ3RoKTsKLQotICAgICAgICAgICAgLy8gdGltZSB0byBmaXJlIG9mZiBjaGFyYWN0ZXJzIGdlbmVyYXRpb24gZXZlbnQKLSAgICAgICAgICAgIGlmIChtX3RyYWNlciAhPSBudWxsKQotICAgICAgICAgICAgICAgIHN1cGVyLmZpcmVDaGFyRXZlbnQoY2hhcnMsIHN0YXJ0LCBsZW5ndGgpOwotCi0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAobV9lbGVtQ29udGV4dC5tX3N0YXJ0VGFnT3BlbikKLSAgICAgICAgewotICAgICAgICAgICAgY2xvc2VTdGFydFRhZygpOwotICAgICAgICAgICAgbV9lbGVtQ29udGV4dC5tX3N0YXJ0VGFnT3BlbiA9IGZhbHNlOwotICAgICAgICB9Ci0KLQotICAgICAgICB0cnkKLSAgICAgICAgewotICAgICAgICAgICAgaW50IGk7Ci0gICAgICAgICAgICBjaGFyIGNoMTsKLSAgICAgICAgICAgIGludCBzdGFydENsZWFuOwotCi0gICAgICAgICAgICAvLyBza2lwIGFueSBsZWFkaW5nIHdoaXRzcGFjZQotICAgICAgICAgICAgLy8gZG9uJ3QgZ28gb2ZmIHRoZSBlbmQgYW5kIHVzZSBhIGhhbmQgaW5saW5lZCB2ZXJzaW9uCi0gICAgICAgICAgICAvLyBvZiBpc1doaXRlc3BhY2UoY2gpCi0gICAgICAgICAgICBmaW5hbCBpbnQgZW5kID0gc3RhcnQgKyBsZW5ndGg7Ci0gICAgICAgICAgICBpbnQgbGFzdERpcnR5ID0gc3RhcnQgLSAxOyAvLyBsYXN0IGNoYXJhY3RlciB0aGF0IG5lZWRlZCBwcm9jZXNzaW5nCi0gICAgICAgICAgICBmb3IgKGkgPSBzdGFydDsKLSAgICAgICAgICAgICAgICAoKGkgPCBlbmQpCi0gICAgICAgICAgICAgICAgICAgICYmICgoY2gxID0gY2hhcnNbaV0pID09IDB4MjAKLSAgICAgICAgICAgICAgICAgICAgICAgIHx8IChjaDEgPT0gMHhBICYmIG1fbGluZVNlcFVzZSkKLSAgICAgICAgICAgICAgICAgICAgICAgIHx8IGNoMSA9PSAweEQKLSAgICAgICAgICAgICAgICAgICAgICAgIHx8IGNoMSA9PSAweDA5KSk7Ci0gICAgICAgICAgICAgICAgaSsrKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIC8qCi0gICAgICAgICAgICAgICAgICogV2UgYXJlIHByb2Nlc3NpbmcgbGVhZGluZyB3aGl0ZXNwYWNlLCBidXQgYXJlIGRvaW5nIHRoZSBzYW1lCi0gICAgICAgICAgICAgICAgICogcHJvY2Vzc2luZyBmb3IgZGlydHkgY2hhcmFjdGVycyBoZXJlIGFzIGZvciBub24td2hpdGVzcGFjZS4KLSAgICAgICAgICAgICAgICAgKgotICAgICAgICAgICAgICAgICAqLwotICAgICAgICAgICAgICAgIGlmICghbV9jaGFySW5mby5pc1RleHRBU0NJSUNsZWFuKGNoMSkpCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICBsYXN0RGlydHkgPSBwcm9jZXNzRGlydHkoY2hhcnMsZW5kLCBpLGNoMSwgbGFzdERpcnR5LCB0cnVlKTsKLSAgICAgICAgICAgICAgICAgICAgaSA9IGxhc3REaXJ0eTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvKiBJZiB0aGVyZSBpcyBzb21lIG5vbi13aGl0ZXNwYWNlLCBtYXJrIHRoYXQgd2UgbWF5IG5lZWQKLSAgICAgICAgICAgICAqIHRvIHByZXNlcnZlIHRoaXMuIFRoaXMgaXMgb25seSBpbXBvcnRhbnQgaWYgd2UgaGF2ZSBpbmRlbnRhdGlvbiBvbi4KLSAgICAgICAgICAgICAqLwotICAgICAgICAgICAgaWYgKGkgPCBlbmQpCi0gICAgICAgICAgICAgICAgbV9pc3ByZXNlcnZlID0gdHJ1ZTsKLQotCi0vLyAgICAgICAgICAgIGludCBsZW5ndGhDbGVhbjsgICAgLy8gbnVtYmVyIG9mIGNsZWFuIGNoYXJhY3RlcnMgaW4gYSByb3cKLS8vICAgICAgICAgICAgZmluYWwgYm9vbGVhbltdIGlzQXNjaWlDbGVhbiA9IG1fY2hhckluZm8uZ2V0QVNDSUlDbGVhbigpOwotCi0gICAgICAgICAgICBmaW5hbCBib29sZWFuIGlzWE1MMTAgPSBYTUxWRVJTSU9OMTAuZXF1YWxzKGdldFZlcnNpb24oKSk7Ci0gICAgICAgICAgICAvLyB3ZSd2ZSBza2lwcGVkIHRoZSBsZWFkaW5nIHdoaXRlc3BhY2UsIG5vdyBkZWFsIHdpdGggdGhlIHJlc3QKLSAgICAgICAgICAgIGZvciAoOyBpIDwgZW5kOyBpKyspCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAvLyBBIHRpZ2h0IGxvb3AgdG8gc2tpcCBvdmVyIGNvbW1vbiBjbGVhbiBjaGFycwotICAgICAgICAgICAgICAgICAgICAvLyBUaGlzIHRpZ2h0IGxvb3AgbWFrZXMgaXQgZWFzaWVyIGZvciB0aGUgSklUCi0gICAgICAgICAgICAgICAgICAgIC8vIHRvIG9wdGltaXplLgotICAgICAgICAgICAgICAgICAgICBjaGFyIGNoMjsKLSAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGk8ZW5kCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgKChjaDIgPSBjaGFyc1tpXSk8MTI3KQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmIG1fY2hhckluZm8uaXNUZXh0QVNDSUlDbGVhbihjaDIpKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkrKzsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGkgPT0gZW5kKQotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgZmluYWwgY2hhciBjaCA9IGNoYXJzW2ldOwotICAgICAgICAgICAgICAgIC8qICBUaGUgY2hlY2sgZm9yIGlzQ2hhcmFjdGVySW5DMG9yQzFSYW5nZXIgYW5kCi0gICAgICAgICAgICAgICAgICogIGlzTkVMb3JMU0VQQ2hhcmFjdGVyIGhhcyBiZWVuIGFkZGVkCi0gICAgICAgICAgICAgICAgICogIHRvIHN1cHBvcnQgQ29udHJvbCBDaGFyYWN0ZXJzIGluIFhNTCAxLjEKLSAgICAgICAgICAgICAgICAgKi8KLSAgICAgICAgICAgICAgICBpZiAoIWlzQ2hhcmFjdGVySW5DMG9yQzFSYW5nZShjaCkgJiYKLSAgICAgICAgICAgICAgICAgICAgKGlzWE1MMTAgfHwgIWlzTkVMb3JMU0VQQ2hhcmFjdGVyKGNoKSkgJiYKLSAgICAgICAgICAgICAgICAgICAgKGVzY2FwaW5nTm90TmVlZGVkKGNoKSAmJiAoIW1fY2hhckluZm8uaXNTcGVjaWFsVGV4dENoYXIoY2gpKSkKLSAgICAgICAgICAgICAgICAgICAgICAgIHx8ICgnIicgPT0gY2gpKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgOyAvLyBhIGNoYXJhY3RlciBuZWVkaW5nIG5vIHNwZWNpYWwgcHJvY2Vzc2luZwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICBsYXN0RGlydHkgPSBwcm9jZXNzRGlydHkoY2hhcnMsZW5kLCBpLCBjaCwgbGFzdERpcnR5LCB0cnVlKTsKLSAgICAgICAgICAgICAgICAgICAgaSA9IGxhc3REaXJ0eTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIHdlJ3ZlIHJlYWNoZWQgdGhlIGVuZC4gQW55IGNsZWFuIGNoYXJhY3RlcnMgYXQgdGhlCi0gICAgICAgICAgICAvLyBlbmQgb2YgdGhlIGFycmF5IHRoYW4gbmVlZCB0byBiZSB3cml0dGVuIG91dD8KLSAgICAgICAgICAgIHN0YXJ0Q2xlYW4gPSBsYXN0RGlydHkgKyAxOwotICAgICAgICAgICAgaWYgKGkgPiBzdGFydENsZWFuKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIGludCBsZW5ndGhDbGVhbiA9IGkgLSBzdGFydENsZWFuOwotICAgICAgICAgICAgICAgIG1fd3JpdGVyLndyaXRlKGNoYXJzLCBzdGFydENsZWFuLCBsZW5ndGhDbGVhbik7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIEZvciBpbmRlbnRhdGlvbiBwdXJwb3NlcywgbWFyayB0aGF0IHdlJ3ZlIGp1c3Qgd3JpdGVuIHRleHQgb3V0Ci0gICAgICAgICAgICBtX2lzcHJldnRleHQgPSB0cnVlOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChJT0V4Y2VwdGlvbiBlKQotICAgICAgICB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKGUpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gdGltZSB0byBmaXJlIG9mZiBjaGFyYWN0ZXJzIGdlbmVyYXRpb24gZXZlbnQKLSAgICAgICAgaWYgKG1fdHJhY2VyICE9IG51bGwpCi0gICAgICAgICAgICBzdXBlci5maXJlQ2hhckV2ZW50KGNoYXJzLCBzdGFydCwgbGVuZ3RoKTsKLSAgICB9Ci0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgY2hlY2tzIGlmIGEgZ2l2ZW4gY2hhcmFjdGVyIGlzIGJldHdlZW4gQzAgb3IgQzEgcmFuZ2UKLSAgICAgKiBvZiBDb250cm9sIGNoYXJhY3RlcnMuCi0gICAgICogVGhpcyBtZXRob2QgaXMgYWRkZWQgdG8gc3VwcG9ydCBDb250cm9sIENoYXJhY3RlcnMgZm9yIFhNTCAxLjEKLSAgICAgKiBJZiBhIGdpdmVuIGNoYXJhY3RlciBpcyBUQUIgKDB4MDkpLCBMRiAoMHgwQSkgb3IgQ1IgKDB4MEQpLCB0aGlzIG1ldGhvZAotICAgICAqIHJldHVybiBmYWxzZS4gU2luY2UgdGhleSBhcmUgd2hpdGVzcGFjZSBjaGFyYWN0ZXJzLCBubyBzcGVjaWFsIHByb2Nlc3NpbmcgaXMgbmVlZGVkLgotICAgICAqCi0gICAgICogQHBhcmFtIGNoCi0gICAgICogQHJldHVybiBib29sZWFuCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBpc0NoYXJhY3RlckluQzBvckMxUmFuZ2UoY2hhciBjaCkKLSAgICB7Ci0gICAgICAgIGlmKGNoID09IDB4MDkgfHwgY2ggPT0gMHgwQSB8fCBjaCA9PSAweDBEKQotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIHJldHVybiAoY2ggPj0gMHg3RiAmJiBjaCA8PSAweDlGKXx8IChjaCA+PSAweDAxICYmIGNoIDw9IDB4MUYpOwotICAgIH0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBjaGVja3MgaWYgYSBnaXZlbiBjaGFyYWN0ZXIgZWl0aGVyIE5FTCAoMHg4NSkgb3IgTFNFUCAoMHgyMDI4KQotICAgICAqIFRoZXNlIGFyZSBuZXcgZW5kIG9mIGxpbmUgY2hhcmN0ZXJzIGFkZGVkIGluIFhNTCAxLjEuICBUaGVzZSBjaGFyYWN0ZXJzIG11c3QgYmUKLSAgICAgKiB3cml0dGVuIGFzIE51bWVyaWMgQ2hhcmFjdGVyIFJlZmVyZW5jZXMgKE5DUikgaW4gWE1MIDEuMSBvdXRwdXQgZG9jdW1lbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY2gKLSAgICAgKiBAcmV0dXJuIGJvb2xlYW4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGlzTkVMb3JMU0VQQ2hhcmFjdGVyKGNoYXIgY2gpCi0gICAgewotICAgICAgICByZXR1cm4gKGNoID09IDB4ODUgfHwgY2ggPT0gMHgyMDI4KTsKLSAgICB9Ci0gICAgLyoqCi0gICAgICogUHJvY2VzcyBhIGRpcnR5IGNoYXJhY3RlciBhbmQgYW55IHByZWVjZWRpbmcgY2xlYW4gY2hhcmFjdGVycwotICAgICAqIHRoYXQgd2VyZSBub3QgeWV0IHByb2Nlc3NlZC4KLSAgICAgKiBAcGFyYW0gY2hhcnMgYXJyYXkgb2YgY2hhcmFjdGVycyBiZWluZyBwcm9jZXNzZWQKLSAgICAgKiBAcGFyYW0gZW5kIG9uZSAoMSkgYmV5b25kIHRoZSBsYXN0IGNoYXJhY3RlcgotICAgICAqIGluIGNoYXJzIHRvIGJlIHByb2Nlc3NlZAotICAgICAqIEBwYXJhbSBpIHRoZSBpbmRleCBvZiB0aGUgZGlydHkgY2hhcmFjdGVyCi0gICAgICogQHBhcmFtIGNoIHRoZSBjaGFyYWN0ZXIgaW4gY2hhcnNbaV0KLSAgICAgKiBAcGFyYW0gbGFzdERpcnR5IHRoZSBsYXN0IGRpcnR5IGNoYXJhY3RlciBwcmV2aW91cyB0byBpCi0gICAgICogQHBhcmFtIGZyb21UZXh0Tm9kZSB0cnVlIGlmIHRoZSBjaGFyYWN0ZXJzIGJlaW5nIHByb2Nlc3NlZCBhcmUKLSAgICAgKiBmcm9tIGEgdGV4dCBub2RlLCBmYWxzZSBpZiB0aGV5IGFyZSBmcm9tIGFuIGF0dHJpYnV0ZSB2YWx1ZS4KLSAgICAgKiBAcmV0dXJuIHRoZSBpbmRleCBvZiB0aGUgbGFzdCBjaGFyYWN0ZXIgcHJvY2Vzc2VkCi0gICAgICovCi0gICAgcHJpdmF0ZSBpbnQgcHJvY2Vzc0RpcnR5KAotICAgICAgICBjaGFyW10gY2hhcnMsCi0gICAgICAgIGludCBlbmQsCi0gICAgICAgIGludCBpLAotICAgICAgICBjaGFyIGNoLAotICAgICAgICBpbnQgbGFzdERpcnR5LAotICAgICAgICBib29sZWFuIGZyb21UZXh0Tm9kZSkgdGhyb3dzIElPRXhjZXB0aW9uCi0gICAgewotICAgICAgICBpbnQgc3RhcnRDbGVhbiA9IGxhc3REaXJ0eSArIDE7Ci0gICAgICAgIC8vIGlmIHdlIGhhdmUgc29tZSBjbGVhbiBjaGFyYWN0ZXJzIGFjY3VtdWxhdGVkCi0gICAgICAgIC8vIHByb2Nlc3MgdGhlbSBiZWZvcmUgdGhlIGRpcnR5IG9uZS4KLSAgICAgICAgaWYgKGkgPiBzdGFydENsZWFuKQotICAgICAgICB7Ci0gICAgICAgICAgICBpbnQgbGVuZ3RoQ2xlYW4gPSBpIC0gc3RhcnRDbGVhbjsKLSAgICAgICAgICAgIG1fd3JpdGVyLndyaXRlKGNoYXJzLCBzdGFydENsZWFuLCBsZW5ndGhDbGVhbik7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBwcm9jZXNzIHRoZSAiZGlydHkiIGNoYXJhY3RlcgotICAgICAgICBpZiAoQ2hhckluZm8uU19MSU5FRkVFRCA9PSBjaCAmJiBmcm9tVGV4dE5vZGUpCi0gICAgICAgIHsKLSAgICAgICAgICAgIG1fd3JpdGVyLndyaXRlKG1fbGluZVNlcCwgMCwgbV9saW5lU2VwTGVuKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgIHsKLSAgICAgICAgICAgIHN0YXJ0Q2xlYW4gPQotICAgICAgICAgICAgICAgIGFjY3VtRGVmYXVsdEVzY2FwZSgKLSAgICAgICAgICAgICAgICAgICAgbV93cml0ZXIsCi0gICAgICAgICAgICAgICAgICAgIChjaGFyKWNoLAotICAgICAgICAgICAgICAgICAgICBpLAotICAgICAgICAgICAgICAgICAgICBjaGFycywKLSAgICAgICAgICAgICAgICAgICAgZW5kLAotICAgICAgICAgICAgICAgICAgICBmcm9tVGV4dE5vZGUsCi0gICAgICAgICAgICAgICAgICAgIGZhbHNlKTsKLSAgICAgICAgICAgIGkgPSBzdGFydENsZWFuIC0gMTsKLSAgICAgICAgfQotICAgICAgICAvLyBSZXR1cm4gdGhlIGluZGV4IG9mIHRoZSBsYXN0IGNoYXJhY3RlciB0aGF0IHdlIGp1c3QgcHJvY2Vzc2VkCi0gICAgICAgIC8vIHdoaWNoIGlzIGEgZGlydHkgY2hhcmFjdGVyLgotICAgICAgICByZXR1cm4gaTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBjaGFyYWN0ZXIgZGF0YS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzIFRoZSBzdHJpbmcgb2YgY2hhcmFjdGVycyB0byBwcm9jZXNzLgotICAgICAqCi0gICAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBjaGFyYWN0ZXJzKFN0cmluZyBzKSB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAobV9pbkVudGl0eVJlZiAmJiAhbV9leHBhbmREVERFbnRpdGllcykKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgZmluYWwgaW50IGxlbmd0aCA9IHMubGVuZ3RoKCk7Ci0gICAgICAgIGlmIChsZW5ndGggPiBtX2NoYXJzQnVmZi5sZW5ndGgpCi0gICAgICAgIHsKLSAgICAgICAgICAgIG1fY2hhcnNCdWZmID0gbmV3IGNoYXJbbGVuZ3RoICogMiArIDFdOwotICAgICAgICB9Ci0gICAgICAgIHMuZ2V0Q2hhcnMoMCwgbGVuZ3RoLCBtX2NoYXJzQnVmZiwgMCk7Ci0gICAgICAgIGNoYXJhY3RlcnMobV9jaGFyc0J1ZmYsIDAsIGxlbmd0aCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRXNjYXBlIGFuZCB3cml0ZXIud3JpdGUgYSBjaGFyYWN0ZXIuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY2ggY2hhcmFjdGVyIHRvIGJlIGVzY2FwZWQuCi0gICAgICogQHBhcmFtIGkgaW5kZXggaW50byBjaGFyYWN0ZXIgYXJyYXkuCi0gICAgICogQHBhcmFtIGNoYXJzIG5vbi1udWxsIHJlZmVyZW5jZSB0byBjaGFyYWN0ZXIgYXJyYXkuCi0gICAgICogQHBhcmFtIGxlbiBsZW5ndGggb2YgY2hhcnMuCi0gICAgICogQHBhcmFtIGZyb21UZXh0Tm9kZSB0cnVlIGlmIHRoZSBjaGFyYWN0ZXJzIGJlaW5nIHByb2Nlc3NlZCBhcmUKLSAgICAgKiBmcm9tIGEgdGV4dCBub2RlLCBmYWxzZSBpZiB0aGUgY2hhcmFjdGVycyBiZWluZyBwcm9jZXNzZWQgYXJlIGZyb20KLSAgICAgKiBhbiBhdHRyaWJ1dGUgdmFsdWUuCi0gICAgICogQHBhcmFtIGVzY0xGIHRydWUgaWYgdGhlIGxpbmVmZWVkIHNob3VsZCBiZSBlc2NhcGVkLgotICAgICAqCi0gICAgICogQHJldHVybiBpKzEgaWYgYSBjaGFyYWN0ZXIgd2FzIHdyaXR0ZW4sIGkrMiBpZiB0d28gY2hhcmFjdGVycwotICAgICAqIHdlcmUgd3JpdHRlbiBvdXQsIGVsc2UgcmV0dXJuIGkuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgICAqLwotICAgIHByb3RlY3RlZCBpbnQgYWNjdW1EZWZhdWx0RXNjYXBlKAotICAgICAgICBXcml0ZXIgd3JpdGVyLAotICAgICAgICBjaGFyIGNoLAotICAgICAgICBpbnQgaSwKLSAgICAgICAgY2hhcltdIGNoYXJzLAotICAgICAgICBpbnQgbGVuLAotICAgICAgICBib29sZWFuIGZyb21UZXh0Tm9kZSwKLSAgICAgICAgYm9vbGVhbiBlc2NMRikKLSAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uCi0gICAgewotCi0gICAgICAgIGludCBwb3MgPSBhY2N1bURlZmF1bHRFbnRpdHkod3JpdGVyLCBjaCwgaSwgY2hhcnMsIGxlbiwgZnJvbVRleHROb2RlLCBlc2NMRik7Ci0KLSAgICAgICAgaWYgKGkgPT0gcG9zKQotICAgICAgICB7Ci0gICAgICAgICAgICBpZiAoRW5jb2RpbmdzLmlzSGlnaFVURjE2U3Vycm9nYXRlKGNoKSkKLSAgICAgICAgICAgIHsKLQotICAgICAgICAgICAgICAgIC8vIFNob3VsZCBiZSB0aGUgVVRGLTE2IGxvdyBzdXJyb2dhdGUgb2YgdGhlIGhpZy9sb3cgcGFpci4KLSAgICAgICAgICAgICAgICBjaGFyIG5leHQ7Ci0gICAgICAgICAgICAgICAgLy8gVW5pY29kZSBjb2RlIHBvaW50IGZvcm1lZCBmcm9tIHRoZSBoaWdoL2xvdyBwYWlyLgotICAgICAgICAgICAgICAgIGludCBjb2RlUG9pbnQgPSAwOwotCi0gICAgICAgICAgICAgICAgaWYgKGkgKyAxID49IGxlbikKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgICAgIFV0aWxzLm1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgTXNnS2V5LkVSX0lOVkFMSURfVVRGMTZfU1VSUk9HQVRFLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7IEludGVnZXIudG9IZXhTdHJpbmcoY2gpfSkpOwotICAgICAgICAgICAgICAgICAgICAvLyJJbnZhbGlkIFVURi0xNiBzdXJyb2dhdGUgZGV0ZWN0ZWQ6ICIKLQotICAgICAgICAgICAgICAgICAgICAvLytJbnRlZ2VyLnRvSGV4U3RyaW5nKGNoKSsgIiA/Iik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIG5leHQgPSBjaGFyc1srK2ldOwotCi0gICAgICAgICAgICAgICAgICAgIGlmICghKEVuY29kaW5ncy5pc0xvd1VURjE2U3Vycm9nYXRlKG5leHQpKSkKLSAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBVdGlscy5tZXNzYWdlcy5jcmVhdGVNZXNzYWdlKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNc2dLZXkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5FUl9JTlZBTElEX1VURjE2X1NVUlJPR0FURSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEludGVnZXIudG9IZXhTdHJpbmcoY2gpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiICIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIEludGVnZXIudG9IZXhTdHJpbmcobmV4dCl9KSk7Ci0gICAgICAgICAgICAgICAgICAgIC8vIkludmFsaWQgVVRGLTE2IHN1cnJvZ2F0ZSBkZXRlY3RlZDogIgotCi0gICAgICAgICAgICAgICAgICAgIC8vK0ludGVnZXIudG9IZXhTdHJpbmcoY2gpKyIgIitJbnRlZ2VyLnRvSGV4U3RyaW5nKG5leHQpKTsKLSAgICAgICAgICAgICAgICAgICAgY29kZVBvaW50ID0gRW5jb2RpbmdzLnRvQ29kZVBvaW50KGNoLG5leHQpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZSgiJiMiKTsKLSAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoSW50ZWdlci50b1N0cmluZyhjb2RlUG9pbnQpKTsKLSAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoJzsnKTsKLSAgICAgICAgICAgICAgICBwb3MgKz0gMjsgLy8gY291bnQgdGhlIHR3byBjaGFyYWN0ZXJzIHRoYXQgd2VudCBpbnRvIHdyaXRpbmcgb3V0IHRoaXMgZW50aXR5Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgLyogIFRoaXMgaWYgY2hlY2sgaXMgYWRkZWQgdG8gc3VwcG9ydCBjb250cm9sIGNoYXJhY3RlcnMgaW4gWE1MIDEuMS4KLSAgICAgICAgICAgICAgICAgKiAgSWYgYSBjaGFyYWN0ZXIgaXMgYSBDb250cm9sIENoYXJhY3RlciB3aXRoaW4gQzAgYW5kIEMxIHJhbmdlLCBpdCBpcyBkZXNpcmFibGUKLSAgICAgICAgICAgICAgICAgKiAgdG8gd3JpdGUgaXQgb3V0IGFzIE51bWVyaWMgQ2hhcmFjdGVyIFJlZmVyZW5jZShOQ1IpIHJlZ2FyZGxlc3Mgb2YgWE1MIFZlcnNpb24KLSAgICAgICAgICAgICAgICAgKiAgYmVpbmcgdXNlZCBmb3Igb3V0cHV0IGRvY3VtZW50LgotICAgICAgICAgICAgICAgICAqLwotICAgICAgICAgICAgICAgIGlmIChpc0NoYXJhY3RlckluQzBvckMxUmFuZ2UoY2gpIHx8Ci0gICAgICAgICAgICAgICAgICAgICAgICAoWE1MVkVSU0lPTjExLmVxdWFscyhnZXRWZXJzaW9uKCkpICYmIGlzTkVMb3JMU0VQQ2hhcmFjdGVyKGNoKSkpCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoIiYjIik7Ci0gICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZShJbnRlZ2VyLnRvU3RyaW5nKGNoKSk7Ci0gICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZSgnOycpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIGlmICgoIWVzY2FwaW5nTm90TmVlZGVkKGNoKSB8fAotICAgICAgICAgICAgICAgICAgICAoICAoZnJvbVRleHROb2RlICYmIG1fY2hhckluZm8uaXNTcGVjaWFsVGV4dENoYXIoY2gpKQotICAgICAgICAgICAgICAgICAgICAgfHwgKCFmcm9tVGV4dE5vZGUgJiYgbV9jaGFySW5mby5pc1NwZWNpYWxBdHRyQ2hhcihjaCkpKSkKLSAgICAgICAgICAgICAgICAmJiBtX2VsZW1Db250ZXh0Lm1fY3VycmVudEVsZW1EZXB0aCA+IDApCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoIiYjIik7Ci0gICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZShJbnRlZ2VyLnRvU3RyaW5nKGNoKSk7Ci0gICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZSgnOycpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoY2gpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBwb3MrKzsgIC8vIGNvdW50IHRoZSBzaW5nbGUgY2hhcmFjdGVyIHRoYXQgd2FzIHByb2Nlc3NlZAotICAgICAgICAgICAgfQotCi0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHBvczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiB0aGUgYmVnaW5uaW5nIG9mIGFuIGVsZW1lbnQsIGFsdGhvdWdoIHRoaXMgaXMgYQotICAgICAqIFNBWCBtZXRob2QgYWRkaXRpb25hbCBuYW1lc3BhY2Ugb3IgYXR0cmlidXRlIGluZm9ybWF0aW9uIGNhbiBvY2N1ciBiZWZvcmUKLSAgICAgKiBvciBhZnRlciB0aGlzIGNhbGwsIHRoYXQgaXMgYXNzb2NpYXRlZCB3aXRoIHRoaXMgZWxlbWVudC4KLSAgICAgKgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWVzcGFjZVVSSSBUaGUgTmFtZXNwYWNlIFVSSSwgb3IgdGhlIGVtcHR5IHN0cmluZyBpZiB0aGUKLSAgICAgKiAgICAgICAgZWxlbWVudCBoYXMgbm8gTmFtZXNwYWNlIFVSSSBvciBpZiBOYW1lc3BhY2UKLSAgICAgKiAgICAgICAgcHJvY2Vzc2luZyBpcyBub3QgYmVpbmcgcGVyZm9ybWVkLgotICAgICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGxvY2FsIG5hbWUgKHdpdGhvdXQgcHJlZml4KSwgb3IgdGhlCi0gICAgICogICAgICAgIGVtcHR5IHN0cmluZyBpZiBOYW1lc3BhY2UgcHJvY2Vzc2luZyBpcyBub3QgYmVpbmcKLSAgICAgKiAgICAgICAgcGVyZm9ybWVkLgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBlbGVtZW50IHR5cGUgbmFtZS4KLSAgICAgKiBAcGFyYW0gYXR0cyBUaGUgYXR0cmlidXRlcyBhdHRhY2hlZCB0byB0aGUgZWxlbWVudCwgaWYgYW55LgotICAgICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNzdGFydEVsZW1lbnQKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI2VuZEVsZW1lbnQKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkF0dHJpYnV0ZUxpc3QKLSAgICAgKgotICAgICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnRFbGVtZW50KAotICAgICAgICBTdHJpbmcgbmFtZXNwYWNlVVJJLAotICAgICAgICBTdHJpbmcgbG9jYWxOYW1lLAotICAgICAgICBTdHJpbmcgbmFtZSwKLSAgICAgICAgQXR0cmlidXRlcyBhdHRzKQotICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAobV9pbkVudGl0eVJlZikKLSAgICAgICAgICAgIHJldHVybjsKLQotICAgICAgICBpZiAobV9uZWVkVG9DYWxsU3RhcnREb2N1bWVudCkKLSAgICAgICAgewotICAgICAgICAgICAgc3RhcnREb2N1bWVudEludGVybmFsKCk7Ci0gICAgICAgICAgICBtX25lZWRUb0NhbGxTdGFydERvY3VtZW50ID0gZmFsc2U7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAobV9jZGF0YVRhZ09wZW4pCi0gICAgICAgICAgICBjbG9zZUNEQVRBKCk7Ci0gICAgICAgIHRyeQotICAgICAgICB7Ci0gICAgICAgICAgICBpZiAoKHRydWUgPT0gbV9uZWVkVG9PdXRwdXREb2NUeXBlRGVjbCkKLSAgICAgICAgICAgICAgICAmJiAobnVsbCAhPSBnZXREb2N0eXBlU3lzdGVtKCkpKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIG91dHB1dERvY1R5cGVEZWNsKG5hbWUsIHRydWUpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBtX25lZWRUb091dHB1dERvY1R5cGVEZWNsID0gZmFsc2U7Ci0KLSAgICAgICAgICAgIC8qIGJlZm9yZSB3ZSBvdmVyLXdyaXRlIHRoZSBjdXJyZW50IGVsZW1lbnRMb2NhbE5hbWUgZXRjLgotICAgICAgICAgICAgICogbGV0cyBjbG9zZSBvdXQgdGhlIG9sZCBvbmUgKGlmIHdlIHN0aWxsIG5lZWQgdG8pCi0gICAgICAgICAgICAgKi8KLSAgICAgICAgICAgIGlmIChtX2VsZW1Db250ZXh0Lm1fc3RhcnRUYWdPcGVuKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIGNsb3NlU3RhcnRUYWcoKTsKLSAgICAgICAgICAgICAgICBtX2VsZW1Db250ZXh0Lm1fc3RhcnRUYWdPcGVuID0gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmIChuYW1lc3BhY2VVUkkgIT0gbnVsbCkKLSAgICAgICAgICAgICAgICBlbnN1cmVQcmVmaXhJc0RlY2xhcmVkKG5hbWVzcGFjZVVSSSwgbmFtZSk7Ci0KLSAgICAgICAgICAgIG1faXNwcmVzZXJ2ZSA9IGZhbHNlOwotCi0gICAgICAgICAgICBpZiAoc2hvdWxkSW5kZW50KCkgJiYgbV9zdGFydE5ld0xpbmUpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgaW5kZW50KCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIG1fc3RhcnROZXdMaW5lID0gdHJ1ZTsKLQotICAgICAgICAgICAgZmluYWwgamF2YS5pby5Xcml0ZXIgd3JpdGVyID0gbV93cml0ZXI7Ci0gICAgICAgICAgICB3cml0ZXIud3JpdGUoJzwnKTsKLSAgICAgICAgICAgIHdyaXRlci53cml0ZShuYW1lKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoSU9FeGNlcHRpb24gZSkKLSAgICAgICAgewotICAgICAgICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbihlKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIHByb2Nlc3MgdGhlIGF0dHJpYnV0ZXMgbm93LCBiZWNhdXNlIGFmdGVyIHRoaXMgU0FYIGNhbGwgdGhleSBtaWdodCBiZSBnb25lCi0gICAgICAgIGlmIChhdHRzICE9IG51bGwpCi0gICAgICAgICAgICBhZGRBdHRyaWJ1dGVzKGF0dHMpOwotCi0gICAgICAgIG1fZWxlbUNvbnRleHQgPSBtX2VsZW1Db250ZXh0LnB1c2gobmFtZXNwYWNlVVJJLGxvY2FsTmFtZSxuYW1lKTsKLSAgICAgICAgbV9pc3ByZXZ0ZXh0ID0gZmFsc2U7Ci0KLSAgICAgICAgaWYgKG1fdHJhY2VyICE9IG51bGwpewotICAgICAgICAgICAgZmlyZVBzZXVkb0F0dHJpYnV0ZXMoKTsKLSAgICAgICAgfQotCi0gICAgfQotCi0gICAgLyoqCi0gICAgICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIHRoZSBiZWdpbm5pbmcgb2YgYW4gZWxlbWVudCwgYWRkaXRpb25hbAotICAgICAgKiBuYW1lc3BhY2Ugb3IgYXR0cmlidXRlIGluZm9ybWF0aW9uIGNhbiBvY2N1ciBiZWZvcmUgb3IgYWZ0ZXIgdGhpcyBjYWxsLAotICAgICAgKiB0aGF0IGlzIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGVsZW1lbnQuCi0gICAgICAqCi0gICAgICAqCi0gICAgICAqIEBwYXJhbSBlbGVtZW50TmFtZXNwYWNlVVJJIFRoZSBOYW1lc3BhY2UgVVJJLCBvciB0aGUgZW1wdHkgc3RyaW5nIGlmIHRoZQotICAgICAgKiAgICAgICAgZWxlbWVudCBoYXMgbm8gTmFtZXNwYWNlIFVSSSBvciBpZiBOYW1lc3BhY2UKLSAgICAgICogICAgICAgIHByb2Nlc3NpbmcgaXMgbm90IGJlaW5nIHBlcmZvcm1lZC4KLSAgICAgICogQHBhcmFtIGVsZW1lbnRMb2NhbE5hbWUgVGhlIGxvY2FsIG5hbWUgKHdpdGhvdXQgcHJlZml4KSwgb3IgdGhlCi0gICAgICAqICAgICAgICBlbXB0eSBzdHJpbmcgaWYgTmFtZXNwYWNlIHByb2Nlc3NpbmcgaXMgbm90IGJlaW5nCi0gICAgICAqICAgICAgICBwZXJmb3JtZWQuCi0gICAgICAqIEBwYXJhbSBlbGVtZW50TmFtZSBUaGUgZWxlbWVudCB0eXBlIG5hbWUuCi0gICAgICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI3N0YXJ0RWxlbWVudAotICAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI2VuZEVsZW1lbnQKLSAgICAgICogQHNlZSBvcmcueG1sLnNheC5BdHRyaWJ1dGVMaXN0Ci0gICAgICAqCi0gICAgICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudCgKLSAgICAgICAgU3RyaW5nIGVsZW1lbnROYW1lc3BhY2VVUkksCi0gICAgICAgIFN0cmluZyBlbGVtZW50TG9jYWxOYW1lLAotICAgICAgICBTdHJpbmcgZWxlbWVudE5hbWUpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIHN0YXJ0RWxlbWVudChlbGVtZW50TmFtZXNwYWNlVVJJLCBlbGVtZW50TG9jYWxOYW1lLCBlbGVtZW50TmFtZSwgbnVsbCk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc3RhcnRFbGVtZW50KFN0cmluZyBlbGVtZW50TmFtZSkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgc3RhcnRFbGVtZW50KG51bGwsIG51bGwsIGVsZW1lbnROYW1lLCBudWxsKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBPdXRwdXQgdGhlIGRvYyB0eXBlIGRlY2xhcmF0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGRvY3VtZW50IHR5cGUgbmFtZS4KLSAgICAgKiBORUVEU0RPQyBAcGFyYW0gY2xvc2VEZWNsCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24KLSAgICAgKi8KLSAgICB2b2lkIG91dHB1dERvY1R5cGVEZWNsKFN0cmluZyBuYW1lLCBib29sZWFuIGNsb3NlRGVjbCkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaWYgKG1fY2RhdGFUYWdPcGVuKQotICAgICAgICAgICAgY2xvc2VDREFUQSgpOwotICAgICAgICB0cnkKLSAgICAgICAgewotICAgICAgICAgICAgZmluYWwgamF2YS5pby5Xcml0ZXIgd3JpdGVyID0gbV93cml0ZXI7Ci0gICAgICAgICAgICB3cml0ZXIud3JpdGUoIjwhRE9DVFlQRSAiKTsKLSAgICAgICAgICAgIHdyaXRlci53cml0ZShuYW1lKTsKLQotICAgICAgICAgICAgU3RyaW5nIGRvY3R5cGVQdWJsaWMgPSBnZXREb2N0eXBlUHVibGljKCk7Ci0gICAgICAgICAgICBpZiAobnVsbCAhPSBkb2N0eXBlUHVibGljKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZSgiIFBVQkxJQyBcIiIpOwotICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZShkb2N0eXBlUHVibGljKTsKLSAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoJ1wiJyk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIFN0cmluZyBkb2N0eXBlU3lzdGVtID0gZ2V0RG9jdHlwZVN5c3RlbSgpOwotICAgICAgICAgICAgaWYgKG51bGwgIT0gZG9jdHlwZVN5c3RlbSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBpZiAobnVsbCA9PSBkb2N0eXBlUHVibGljKQotICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoIiBTWVNURU0gXCIiKTsKLSAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZSgiIFwiIik7Ci0KLSAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoZG9jdHlwZVN5c3RlbSk7Ci0KLSAgICAgICAgICAgICAgICBpZiAoY2xvc2VEZWNsKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKCJcIj4iKTsKLSAgICAgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKG1fbGluZVNlcCwgMCwgbV9saW5lU2VwTGVuKTsKLSAgICAgICAgICAgICAgICAgICAgY2xvc2VEZWNsID0gZmFsc2U7IC8vIGRvbmUgY2xvc2luZwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZSgnXCInKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGJvb2xlYW4gZG90aGlzID0gZmFsc2U7Ci0gICAgICAgICAgICBpZiAoZG90aGlzKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIC8vIGF0IG9uZSBwb2ludCB0aGlzIGNvZGUgc2VlbWVkIHJpZ2h0LAotICAgICAgICAgICAgICAgIC8vIGJ1dCBub3QgYW55bW9yZSAtIEJyaWFuIE0uCi0gICAgICAgICAgICAgICAgaWYgKGNsb3NlRGVjbCkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZSgnPicpOwotICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUobV9saW5lU2VwLCAwLCBtX2xpbmVTZXBMZW4pOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoSU9FeGNlcHRpb24gZSkKLSAgICAgICAgewotICAgICAgICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbihlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFByb2Nlc3MgdGhlIGF0dHJpYnV0ZXMsIHdoaWNoIG1lYW5zIHRvIHdyaXRlIG91dCB0aGUgY3VycmVudGx5Ci0gICAgICogY29sbGVjdGVkIGF0dHJpYnV0ZXMgdG8gdGhlIHdyaXRlci4gVGhlIGF0dHJpYnV0ZXMgYXJlIG5vdAotICAgICAqIGNsZWFyZWQgYnkgdGhpcyBtZXRob2QKLSAgICAgKgotICAgICAqIEBwYXJhbSB3cml0ZXIgdGhlIHdyaXRlciB0byB3cml0ZSBwcm9jZXNzZWQgYXR0cmlidXRlcyB0by4KLSAgICAgKiBAcGFyYW0gbkF0dHJzIHRoZSBudW1iZXIgb2YgYXR0cmlidXRlcyBpbiBtX2F0dHJpYnV0ZXMKLSAgICAgKiB0byBiZSBwcm9jZXNzZWQKLSAgICAgKgotICAgICAqIEB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbgotICAgICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcHJvY2Vzc0F0dHJpYnV0ZXMoamF2YS5pby5Xcml0ZXIgd3JpdGVyLCBpbnQgbkF0dHJzKSB0aHJvd3MgSU9FeGNlcHRpb24sIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgICAgIC8qIHJlYWwgU0FYIGF0dHJpYnV0ZXMgYXJlIG5vdCBwYXNzZWQgaW4sIHNvIHByb2Nlc3MgdGhlCi0gICAgICAgICAgICAgKiBhdHRyaWJ1dGVzIHRoYXQgd2VyZSBjb2xsZWN0ZWQgYWZ0ZXIgdGhlIHN0YXJ0RWxlbWVudCBjYWxsLgotICAgICAgICAgICAgICogX2F0dHJpYlZlY3RvciBpcyBhICJjaGVhcCIgbGlzdCBmb3IgU3RyZWFtIHNlcmlhbGl6ZXIgb3V0cHV0Ci0gICAgICAgICAgICAgKiBhY2N1bXVsYXRlZCBvdmVyIGEgc2VyaWVzIG9mIGNhbGxzIHRvIGF0dHJpYnV0ZShuYW1lLHZhbHVlKQotICAgICAgICAgICAgICovCi0gICAgICAgICAgICBTdHJpbmcgZW5jb2RpbmcgPSBnZXRFbmNvZGluZygpOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuQXR0cnM7IGkrKykKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAvLyBlbGVtZW50QXQgaXMgSkRLIDEuMS44Ci0gICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIG5hbWUgPSBtX2F0dHJpYnV0ZXMuZ2V0UU5hbWUoaSk7Ci0gICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIHZhbHVlID0gbV9hdHRyaWJ1dGVzLmdldFZhbHVlKGkpOwotICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZSgnICcpOwotICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZShuYW1lKTsKLSAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoIj1cIiIpOwotICAgICAgICAgICAgICAgIHdyaXRlQXR0clN0cmluZyh3cml0ZXIsIHZhbHVlLCBlbmNvZGluZyk7Ci0gICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKCdcIicpOwotICAgICAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIHNwZWNpZmllZCA8dmFyPnN0cmluZzwvdmFyPiBhZnRlciBzdWJzdGl0dXRpbmcgPFZBUj5zcGVjaWFsczwvVkFSPiwKLSAgICAgKiBhbmQgVVRGLTE2IHN1cnJvZ2F0ZXMgZm9yIGNocmFjdGVyIHJlZmVyZW5jZXMgPENPREU+JmFtcDsjeG5uPC9DT0RFPi4KLSAgICAgKgotICAgICAqIEBwYXJhbSAgIHN0cmluZyAgICAgIFN0cmluZyB0byBjb252ZXJ0IHRvIFhNTCBmb3JtYXQuCi0gICAgICogQHBhcmFtICAgZW5jb2RpbmcgICAgQ1VSUkVOVExZIE5PVCBJTVBMRU1FTlRFRC4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHdyaXRlQXR0clN0cmluZygKLSAgICAgICAgV3JpdGVyIHdyaXRlciwKLSAgICAgICAgU3RyaW5nIHN0cmluZywKLSAgICAgICAgU3RyaW5nIGVuY29kaW5nKQotICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGZpbmFsIGludCBsZW4gPSBzdHJpbmcubGVuZ3RoKCk7Ci0gICAgICAgIGlmIChsZW4gPiBtX2F0dHJCdWZmLmxlbmd0aCkKLSAgICAgICAgewotICAgICAgICAgICBtX2F0dHJCdWZmID0gbmV3IGNoYXJbbGVuKjIgKyAxXTsKLSAgICAgICAgfQotICAgICAgICBzdHJpbmcuZ2V0Q2hhcnMoMCxsZW4sIG1fYXR0ckJ1ZmYsIDApOwotICAgICAgICBmaW5hbCBjaGFyW10gc3RyaW5nQ2hhcnMgPSBtX2F0dHJCdWZmOwotCi0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuOyApCi0gICAgICAgIHsKLSAgICAgICAgICAgIGNoYXIgY2ggPSBzdHJpbmdDaGFyc1tpXTsKLSAgICAgICAgICAgIGlmIChlc2NhcGluZ05vdE5lZWRlZChjaCkgJiYgKCFtX2NoYXJJbmZvLmlzU3BlY2lhbEF0dHJDaGFyKGNoKSkpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKGNoKTsKLSAgICAgICAgICAgICAgICBpKys7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICB7IC8vIEkgZ3Vlc3MgdGhlIHBhcnNlciBkb2Vzbid0IG5vcm1hbGl6ZSBjci9sZiBpbiBhdHRyaWJ1dGVzLiAtc2IKLS8vICAgICAgICAgICAgICAgIGlmICgoQ2hhckluZm8uU19DQVJSSUFHRVJFVFVSTiA9PSBjaCkKLS8vICAgICAgICAgICAgICAgICAgICAmJiAoKGkgKyAxKSA8IGxlbikKLS8vICAgICAgICAgICAgICAgICAgICAmJiAoQ2hhckluZm8uU19MSU5FRkVFRCA9PSBzdHJpbmdDaGFyc1tpICsgMV0pKQotLy8gICAgICAgICAgICAgICAgewotLy8gICAgICAgICAgICAgICAgICAgIGkrKzsKLS8vICAgICAgICAgICAgICAgICAgICBjaCA9IENoYXJJbmZvLlNfTElORUZFRUQ7Ci0vLyAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBpID0gYWNjdW1EZWZhdWx0RXNjYXBlKHdyaXRlciwgY2gsIGksIHN0cmluZ0NoYXJzLCBsZW4sIGZhbHNlLCB0cnVlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIGVuZCBvZiBhbiBlbGVtZW50LgotICAgICAqCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZXNwYWNlVVJJIFRoZSBOYW1lc3BhY2UgVVJJLCBvciB0aGUgZW1wdHkgc3RyaW5nIGlmIHRoZQotICAgICAqICAgICAgICBlbGVtZW50IGhhcyBubyBOYW1lc3BhY2UgVVJJIG9yIGlmIE5hbWVzcGFjZQotICAgICAqICAgICAgICBwcm9jZXNzaW5nIGlzIG5vdCBiZWluZyBwZXJmb3JtZWQuCi0gICAgICogQHBhcmFtIGxvY2FsTmFtZSBUaGUgbG9jYWwgbmFtZSAod2l0aG91dCBwcmVmaXgpLCBvciB0aGUKLSAgICAgKiAgICAgICAgZW1wdHkgc3RyaW5nIGlmIE5hbWVzcGFjZSBwcm9jZXNzaW5nIGlzIG5vdCBiZWluZwotICAgICAqICAgICAgICBwZXJmb3JtZWQuCi0gICAgICogQHBhcmFtIG5hbWUgVGhlIGVsZW1lbnQgdHlwZSBuYW1lCi0gICAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICAgKgotICAgICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kRWxlbWVudChTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgbG9jYWxOYW1lLCBTdHJpbmcgbmFtZSkKLSAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgIHsKLQotICAgICAgICBpZiAobV9pbkVudGl0eVJlZikKLSAgICAgICAgICAgIHJldHVybjsKLQotICAgICAgICAvLyBuYW1lc3BhY2VzIGRlY2xhcmVkIGF0IHRoZSBjdXJyZW50IGRlcHRoIGFyZSBubyBsb25nZXIgdmFsaWQKLSAgICAgICAgLy8gc28gZ2V0IHJpZCBvZiB0aGVtCi0gICAgICAgIG1fcHJlZml4TWFwLnBvcE5hbWVzcGFjZXMobV9lbGVtQ29udGV4dC5tX2N1cnJlbnRFbGVtRGVwdGgsIG51bGwpOwotCi0gICAgICAgIHRyeQotICAgICAgICB7Ci0gICAgICAgICAgICBmaW5hbCBqYXZhLmlvLldyaXRlciB3cml0ZXIgPSBtX3dyaXRlcjsKLSAgICAgICAgICAgIGlmIChtX2VsZW1Db250ZXh0Lm1fc3RhcnRUYWdPcGVuKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIGlmIChtX3RyYWNlciAhPSBudWxsKQotICAgICAgICAgICAgICAgICAgICBzdXBlci5maXJlU3RhcnRFbGVtKG1fZWxlbUNvbnRleHQubV9lbGVtZW50TmFtZSk7Ci0gICAgICAgICAgICAgICAgaW50IG5BdHRycyA9IG1fYXR0cmlidXRlcy5nZXRMZW5ndGgoKTsKLSAgICAgICAgICAgICAgICBpZiAobkF0dHJzID4gMCkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIHByb2Nlc3NBdHRyaWJ1dGVzKG1fd3JpdGVyLCBuQXR0cnMpOwotICAgICAgICAgICAgICAgICAgICAvLyBjbGVhciBhdHRyaWJ1dGVzIG9iamVjdCBmb3IgcmUtdXNlIHdpdGggbmV4dCBlbGVtZW50Ci0gICAgICAgICAgICAgICAgICAgIG1fYXR0cmlidXRlcy5jbGVhcigpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpZiAobV9zcGFjZUJlZm9yZUNsb3NlKQotICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoIiAvPiIpOwotICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKCIvPiIpOwotICAgICAgICAgICAgICAgIC8qIGRvbid0IG5lZWQgdG8gcG9wIGNkYXRhU2VjdGlvblN0YXRlIGJlY2F1c2UKLSAgICAgICAgICAgICAgICAgKiB0aGlzIGVsZW1lbnQgZW5kZWQgc28gcXVpY2tseSB0aGF0IHdlIGRpZG4ndCBnZXQKLSAgICAgICAgICAgICAgICAgKiB0byBwdXNoIHRoZSBzdGF0ZS4KLSAgICAgICAgICAgICAgICAgKi8KLQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIGlmIChtX2NkYXRhVGFnT3BlbikKLSAgICAgICAgICAgICAgICAgICAgY2xvc2VDREFUQSgpOwotCi0gICAgICAgICAgICAgICAgaWYgKHNob3VsZEluZGVudCgpKQotICAgICAgICAgICAgICAgICAgICBpbmRlbnQobV9lbGVtQ29udGV4dC5tX2N1cnJlbnRFbGVtRGVwdGggLSAxKTsKLSAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoJzwnKTsKLSAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoJy8nKTsKLSAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUobmFtZSk7Ci0gICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKCc+Jyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKElPRXhjZXB0aW9uIGUpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oZSk7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoIW1fZWxlbUNvbnRleHQubV9zdGFydFRhZ09wZW4gJiYgbV9kb0luZGVudCkKLSAgICAgICAgewotICAgICAgICAgICAgbV9pc3ByZXNlcnZlID0gbV9wcmVzZXJ2ZXMuaXNFbXB0eSgpID8gZmFsc2UgOiBtX3ByZXNlcnZlcy5wb3AoKTsKLSAgICAgICAgfQotCi0gICAgICAgIG1faXNwcmV2dGV4dCA9IGZhbHNlOwotCi0gICAgICAgIC8vIGZpcmUgb2ZmIHRoZSBlbmQgZWxlbWVudCBldmVudAotICAgICAgICBpZiAobV90cmFjZXIgIT0gbnVsbCkKLSAgICAgICAgICAgIHN1cGVyLmZpcmVFbmRFbGVtKG5hbWUpOwotICAgICAgICBtX2VsZW1Db250ZXh0ID0gbV9lbGVtQ29udGV4dC5tX3ByZXY7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIGVuZCBvZiBhbiBlbGVtZW50LgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBlbGVtZW50IHR5cGUgbmFtZQotICAgICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgICAqICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbmRFbGVtZW50KFN0cmluZyBuYW1lKSB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBlbmRFbGVtZW50KG51bGwsIG51bGwsIG5hbWUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEJlZ2luIHRoZSBzY29wZSBvZiBhIHByZWZpeC1VUkkgTmFtZXNwYWNlIG1hcHBpbmcKLSAgICAgKiBqdXN0IGJlZm9yZSBhbm90aGVyIGVsZW1lbnQgaXMgYWJvdXQgdG8gc3RhcnQuCi0gICAgICogVGhpcyBjYWxsIHdpbGwgY2xvc2UgYW55IG9wZW4gdGFncyBzbyB0aGF0IHRoZSBwcmVmaXggbWFwcGluZwotICAgICAqIHdpbGwgbm90IGFwcGx5IHRvIHRoZSBjdXJyZW50IGVsZW1lbnQsIGJ1dCB0aGUgdXAgY29tbWluZyBjaGlsZC4KLSAgICAgKgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjc3RhcnRQcmVmaXhNYXBwaW5nCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcHJlZml4IFRoZSBOYW1lc3BhY2UgcHJlZml4IGJlaW5nIGRlY2xhcmVkLgotICAgICAqIEBwYXJhbSB1cmkgVGhlIE5hbWVzcGFjZSBVUkkgdGhlIHByZWZpeCBpcyBtYXBwZWQgdG8uCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBUaGUgY2xpZW50IG1heSB0aHJvdwotICAgICAqICAgICAgICAgICAgYW4gZXhjZXB0aW9uIGR1cmluZyBwcm9jZXNzaW5nLgotICAgICAqCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnRQcmVmaXhNYXBwaW5nKFN0cmluZyBwcmVmaXgsIFN0cmluZyB1cmkpCi0gICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIC8vIHRoZSAidHJ1ZSIgY2F1c2VzIHRoZSBmbHVzaCBvZiBhbnkgb3BlbiB0YWdzCi0gICAgICAgIHN0YXJ0UHJlZml4TWFwcGluZyhwcmVmaXgsIHVyaSwgdHJ1ZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSGFuZGxlIGEgcHJlZml4L3VyaSBtYXBwaW5nLCB3aGljaCBpcyBhc3NvY2lhdGVkIHdpdGggYSBzdGFydEVsZW1lbnQoKQotICAgICAqIHRoYXQgaXMgc29vbiB0byBmb2xsb3cuIE5lZWQgdG8gY2xvc2UgYW55IG9wZW4gc3RhcnQgdGFnIHRvIG1ha2UKLSAgICAgKiBzdXJlIHRoYW4gYW55IG5hbWUgc3BhY2UgYXR0cmlidXRlcyBkdWUgdG8gdGhpcyBldmVudCBhcmUgYXNzb2NpYXRlZCB3aWgKLSAgICAgKiB0aGUgdXAgY29tbWluZyBlbGVtZW50LCBub3QgdGhlIGN1cnJlbnQgb25lLgotICAgICAqIEBzZWUgRXh0ZW5kZWRDb250ZW50SGFuZGxlciNzdGFydFByZWZpeE1hcHBpbmcKLSAgICAgKgotICAgICAqIEBwYXJhbSBwcmVmaXggVGhlIE5hbWVzcGFjZSBwcmVmaXggYmVpbmcgZGVjbGFyZWQuCi0gICAgICogQHBhcmFtIHVyaSBUaGUgTmFtZXNwYWNlIFVSSSB0aGUgcHJlZml4IGlzIG1hcHBlZCB0by4KLSAgICAgKiBAcGFyYW0gc2hvdWxkRmx1c2ggdHJ1ZSBpZiBhbnkgb3BlbiB0YWdzIG5lZWQgdG8gYmUgY2xvc2VkIGZpcnN0LCB0aGlzCi0gICAgICogd2lsbCBpbXBhY3Qgd2hpY2ggZWxlbWVudCB0aGUgbWFwcGluZyBhcHBsaWVzIHRvIChvcGVuIHBhcmVudCwgb3IgaXRzIHVwCi0gICAgICogY29tbWluZyBjaGlsZCkKLSAgICAgKiBAcmV0dXJuIHJldHVybnMgdHJ1ZSBpZiB0aGUgY2FsbCBtYWRlIGEgY2hhbmdlIHRvIHRoZSBjdXJyZW50Ci0gICAgICogbmFtZXNwYWNlIGluZm9ybWF0aW9uLCBmYWxzZSBpZiBpdCBkaWQgbm90IGNoYW5nZSBhbnl0aGluZywgZS5nLiBpZiB0aGUKLSAgICAgKiBwcmVmaXgvbmFtZXNwYWNlIG1hcHBpbmcgd2FzIGFscmVhZHkgaW4gc2NvcGUgZnJvbSBiZWZvcmUuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBUaGUgY2xpZW50IG1heSB0aHJvdwotICAgICAqICAgICAgICAgICAgYW4gZXhjZXB0aW9uIGR1cmluZyBwcm9jZXNzaW5nLgotICAgICAqCi0gICAgICoKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBzdGFydFByZWZpeE1hcHBpbmcoCi0gICAgICAgIFN0cmluZyBwcmVmaXgsCi0gICAgICAgIFN0cmluZyB1cmksCi0gICAgICAgIGJvb2xlYW4gc2hvdWxkRmx1c2gpCi0gICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICB7Ci0KLSAgICAgICAgLyogUmVtZW1iZXIgdGhlIG1hcHBpbmcsIGFuZCBhdCB3aGF0IGRlcHRoIGl0IHdhcyBkZWNsYXJlZAotICAgICAgICAgKiBUaGlzIGlzIG9uZSBncmVhdGVyIHRoYW4gdGhlIGN1cnJlbnQgZGVwdGggYmVjYXVzZSB0aGVzZQotICAgICAgICAgKiBtYXBwaW5ncyB3aWxsIGFwcGx5IHRvIHRoZSBuZXh0IGRlcHRoLiBUaGlzIGlzIGluCi0gICAgICAgICAqIGNvbnNpZGVyYXRpb24gdGhhdCBzdGFydEVsZW1lbnQoKSB3aWxsIHNvb24gYmUgY2FsbGVkCi0gICAgICAgICAqLwotCi0gICAgICAgIGJvb2xlYW4gcHVzaGVkOwotICAgICAgICBpbnQgcHVzaERlcHRoOwotICAgICAgICBpZiAoc2hvdWxkRmx1c2gpCi0gICAgICAgIHsKLSAgICAgICAgICAgIGZsdXNoUGVuZGluZygpOwotICAgICAgICAgICAgLy8gdGhlIHByZWZpeCBtYXBwaW5nIGFwcGxpZXMgdG8gdGhlIGNoaWxkIGVsZW1lbnQgKG9uZSBkZWVwZXIpCi0gICAgICAgICAgICBwdXNoRGVwdGggPSBtX2VsZW1Db250ZXh0Lm1fY3VycmVudEVsZW1EZXB0aCArIDE7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICB7Ci0gICAgICAgICAgICAvLyB0aGUgcHJlZml4IG1hcHBpbmcgYXBwbGllcyB0byB0aGUgY3VycmVudCBlbGVtZW50Ci0gICAgICAgICAgICBwdXNoRGVwdGggPSBtX2VsZW1Db250ZXh0Lm1fY3VycmVudEVsZW1EZXB0aDsKLSAgICAgICAgfQotICAgICAgICBwdXNoZWQgPSBtX3ByZWZpeE1hcC5wdXNoTmFtZXNwYWNlKHByZWZpeCwgdXJpLCBwdXNoRGVwdGgpOwotCi0gICAgICAgIGlmIChwdXNoZWQpCi0gICAgICAgIHsKLSAgICAgICAgICAgIC8qIEJyaWFuIE0uOiBkb24ndCBrbm93IGlmIHdlIHJlYWxseSBuZWVkdG8gZG8gdGhpcy4gVGhlCi0gICAgICAgICAgICAgKiBjYWxsZXJzIG9mIHRoaXMgb2JqZWN0IHNob3VsZCBoYXZlIGluamVjdGVkIGJvdGgKLSAgICAgICAgICAgICAqIHN0YXJ0UHJlZml4TWFwcGluZyBhbmQgdGhlIGF0dHJpYnV0ZXMuICBXZSBhcmUKLSAgICAgICAgICAgICAqIGp1c3QgY292ZXJpbmcgb3VyIGJ1dHQgaGVyZS4KLSAgICAgICAgICAgICAqLwotICAgICAgICAgICAgU3RyaW5nIG5hbWU7Ci0gICAgICAgICAgICBpZiAoRU1QVFlTVFJJTkcuZXF1YWxzKHByZWZpeCkpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgbmFtZSA9ICJ4bWxucyI7Ci0gICAgICAgICAgICAgICAgYWRkQXR0cmlidXRlQWx3YXlzKFhNTE5TX1VSSSwgbmFtZSwgbmFtZSwgIkNEQVRBIiwgdXJpLCBmYWxzZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgaWYgKCFFTVBUWVNUUklORy5lcXVhbHModXJpKSkKLSAgICAgICAgICAgICAgICAgICAgLy8gaGFjayBmb3IgWFNMVEMgYXR0cmlic2V0MTYgdGVzdAotICAgICAgICAgICAgICAgIHsgLy8gdGhhdCBtYXBzIG5zMSBwcmVmaXggdG8gIiIgVVJJCi0gICAgICAgICAgICAgICAgICAgIG5hbWUgPSAieG1sbnM6IiArIHByZWZpeDsKLQotICAgICAgICAgICAgICAgICAgICAvKiBmb3Igc29tZXRoaW5nIGxpa2UgeG1sbnM6YWJjPSJ3My5wcmV0ZW5kLm9yZyIKLSAgICAgICAgICAgICAgICAgICAgICogIHRoZSAgICAgIHVyaSBpcyB0aGUgdmFsdWUsIHRoYXQgaXMgd2h5IHdlIHBhc3MgaXQgaW4gdGhlCi0gICAgICAgICAgICAgICAgICAgICAqIHZhbHVlLCBvciA1dGggc2xvdCBvZiBhZGRBdHRyaWJ1dGVBbHdheXMoKQotICAgICAgICAgICAgICAgICAgICAgKi8KLSAgICAgICAgICAgICAgICAgICAgYWRkQXR0cmlidXRlQWx3YXlzKFhNTE5TX1VSSSwgcHJlZml4LCBuYW1lLCAiQ0RBVEEiLCB1cmksIGZhbHNlKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHB1c2hlZDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBhbiBYTUwgY29tbWVudCBhbnl3aGVyZSBpbiB0aGUgZG9jdW1lbnQuIFRoaXMKLSAgICAgKiBjYWxsYmFjayB3aWxsIGJlIHVzZWQgZm9yIGNvbW1lbnRzIGluc2lkZSBvciBvdXRzaWRlIHRoZSBkb2N1bWVudAotICAgICAqIGVsZW1lbnQsIGluY2x1ZGluZyBjb21tZW50cyBpbiB0aGUgZXh0ZXJuYWwgRFREIHN1YnNldCAoaWYgcmVhZCkuCi0gICAgICogQHBhcmFtIGNoIEFuIGFycmF5IGhvbGRpbmcgdGhlIGNoYXJhY3RlcnMgaW4gdGhlIGNvbW1lbnQuCi0gICAgICogQHBhcmFtIHN0YXJ0IFRoZSBzdGFydGluZyBwb3NpdGlvbiBpbiB0aGUgYXJyYXkuCi0gICAgICogQHBhcmFtIGxlbmd0aCBUaGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gdXNlIGZyb20gdGhlIGFycmF5LgotICAgICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIFRoZSBhcHBsaWNhdGlvbiBtYXkgcmFpc2UgYW4gZXhjZXB0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGNvbW1lbnQoY2hhciBjaFtdLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpCi0gICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICB7Ci0KLSAgICAgICAgaW50IHN0YXJ0X29sZCA9IHN0YXJ0OwotICAgICAgICBpZiAobV9pbkVudGl0eVJlZikKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgaWYgKG1fZWxlbUNvbnRleHQubV9zdGFydFRhZ09wZW4pCi0gICAgICAgIHsKLSAgICAgICAgICAgIGNsb3NlU3RhcnRUYWcoKTsKLSAgICAgICAgICAgIG1fZWxlbUNvbnRleHQubV9zdGFydFRhZ09wZW4gPSBmYWxzZTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChtX25lZWRUb0NhbGxTdGFydERvY3VtZW50KQotICAgICAgICB7Ci0gICAgICAgICAgICBzdGFydERvY3VtZW50SW50ZXJuYWwoKTsKLSAgICAgICAgICAgIG1fbmVlZFRvQ2FsbFN0YXJ0RG9jdW1lbnQgPSBmYWxzZTsKLSAgICAgICAgfQotCi0gICAgICAgIHRyeQotICAgICAgICB7Ci0gICAgICAgICAgICBpZiAoc2hvdWxkSW5kZW50KCkgJiYgbV9pc1N0YW5kYWxvbmUpCi0gICAgICAgICAgICAgICAgaW5kZW50KCk7Ci0KLSAgICAgICAgICAgIGZpbmFsIGludCBsaW1pdCA9IHN0YXJ0ICsgbGVuZ3RoOwotICAgICAgICAgICAgYm9vbGVhbiB3YXNEYXNoID0gZmFsc2U7Ci0gICAgICAgICAgICBpZiAobV9jZGF0YVRhZ09wZW4pCi0gICAgICAgICAgICAgICAgY2xvc2VDREFUQSgpOwotCi0gICAgICAgICAgICBpZiAoc2hvdWxkSW5kZW50KCkgJiYgIW1faXNTdGFuZGFsb25lKQotICAgICAgICAgICAgICAgIGluZGVudCgpOwotCi0gICAgICAgICAgICBmaW5hbCBqYXZhLmlvLldyaXRlciB3cml0ZXIgPSBtX3dyaXRlcjsKLSAgICAgICAgICAgIHdyaXRlci53cml0ZShDT01NRU5UX0JFR0lOKTsKLSAgICAgICAgICAgIC8vIERldGVjdCBvY2N1cnJlbmNlcyBvZiB0d28gY29uc2VjdXRpdmUgZGFzaGVzLCBoYW5kbGUgYXMgbmVjZXNzYXJ5LgotICAgICAgICAgICAgZm9yIChpbnQgaSA9IHN0YXJ0OyBpIDwgbGltaXQ7IGkrKykKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBpZiAod2FzRGFzaCAmJiBjaFtpXSA9PSAnLScpCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoY2gsIHN0YXJ0LCBpIC0gc3RhcnQpOwotICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoIiAtIik7Ci0gICAgICAgICAgICAgICAgICAgIHN0YXJ0ID0gaSArIDE7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHdhc0Rhc2ggPSAoY2hbaV0gPT0gJy0nKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gaWYgd2UgaGF2ZSBzb21lIGNoYXJzIGluIHRoZSBjb21tZW50Ci0gICAgICAgICAgICBpZiAobGVuZ3RoID4gMCkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAvLyBPdXRwdXQgdGhlIHJlbWFpbmluZyBjaGFyYWN0ZXJzIChpZiBhbnkpCi0gICAgICAgICAgICAgICAgZmluYWwgaW50IHJlbWFpbmluZ0NoYXJzID0gKGxpbWl0IC0gc3RhcnQpOwotICAgICAgICAgICAgICAgIGlmIChyZW1haW5pbmdDaGFycyA+IDApCi0gICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZShjaCwgc3RhcnQsIHJlbWFpbmluZ0NoYXJzKTsKLSAgICAgICAgICAgICAgICAvLyBQcm90ZWN0IGNvbW1lbnQgZW5kIGZyb20gYSBzaW5nbGUgdHJhaWxpbmcgZGFzaAotICAgICAgICAgICAgICAgIGlmIChjaFtsaW1pdCAtIDFdID09ICctJykKLSAgICAgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKCcgJyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICB3cml0ZXIud3JpdGUoQ09NTUVOVF9FTkQpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChJT0V4Y2VwdGlvbiBlKQotICAgICAgICB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKGUpOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoKLSAgICAgICAgICogRG9uJ3Qgd3JpdGUgb3V0IGFueSBpbmRlbnRhdGlvbiB3aGl0ZXNwYWNlIG5vdywKLSAgICAgICAgICogYmVjYXVzZSB0aGVyZSBtYXkgYmUgbm9uLXdoaXRlc3BhY2UgdGV4dCBhZnRlciB0aGlzLgotICAgICAgICAgKgotICAgICAgICAgKiBTaW1wbHkgbWFyayB0aGF0IGF0IHRoaXMgcG9pbnQgaWYgd2UgZG8gZGVjaWRlCi0gICAgICAgICAqIHRvIGluZGVudCB0aGF0IHdlIHNob3VsZAotICAgICAgICAgKiBhZGQgYSBuZXdsaW5lIG9uIHRoZSBlbmQgb2YgdGhlIGN1cnJlbnQgbGluZSBiZWZvcmUKLSAgICAgICAgICogdGhlIGluZGVudGF0aW9uIGF0IHRoZSBzdGFydCBvZiB0aGUgbmV4dCBsaW5lLgotICAgICAgICAgKi8KLSAgICAgICAgbV9zdGFydE5ld0xpbmUgPSB0cnVlOwotICAgICAgICAvLyB0aW1lIHRvIGdlbmVyYXRlIGNvbW1lbnQgZXZlbnQKLSAgICAgICAgaWYgKG1fdHJhY2VyICE9IG51bGwpCi0gICAgICAgICAgICBzdXBlci5maXJlQ29tbWVudEV2ZW50KGNoLCBzdGFydF9vbGQsbGVuZ3RoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXBvcnQgdGhlIGVuZCBvZiBhIENEQVRBIHNlY3Rpb24uCi0gICAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gVGhlIGFwcGxpY2F0aW9uIG1heSByYWlzZSBhbiBleGNlcHRpb24uCi0gICAgICoKLSAgICAgKiAgQHNlZSAgI3N0YXJ0Q0RBVEEKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbmRDREFUQSgpIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGlmIChtX2NkYXRhVGFnT3BlbikKLSAgICAgICAgICAgIGNsb3NlQ0RBVEEoKTsKLSAgICAgICAgbV9jZGF0YVN0YXJ0Q2FsbGVkID0gZmFsc2U7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmVwb3J0IHRoZSBlbmQgb2YgRFREIGRlY2xhcmF0aW9ucy4KLSAgICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBUaGUgYXBwbGljYXRpb24gbWF5IHJhaXNlIGFuIGV4Y2VwdGlvbi4KLSAgICAgKiBAc2VlICNzdGFydERURAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZERURCgpIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIHRyeQotICAgICAgICB7Ci0gICAgICAgICAgICAvLyBEb24ndCBvdXRwdXQgZG9jdHlwZSBkZWNsYXJhdGlvbiB1bnRpbCBzdGFydERvY3VtZW50SW50ZXJuYWwKLSAgICAgICAgICAgIC8vIGhhcyBiZWVuIGNhbGxlZC4gT3RoZXJ3aXNlLCBpdCBjYW4gYXBwZWFyIGJlZm9yZSBYTUwgZGVjbC4KLSAgICAgICAgICAgIGlmIChtX25lZWRUb0NhbGxTdGFydERvY3VtZW50KSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAobV9uZWVkVG9PdXRwdXREb2NUeXBlRGVjbCkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBvdXRwdXREb2NUeXBlRGVjbChtX2VsZW1Db250ZXh0Lm1fZWxlbWVudE5hbWUsIGZhbHNlKTsKLSAgICAgICAgICAgICAgICBtX25lZWRUb091dHB1dERvY1R5cGVEZWNsID0gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmaW5hbCBqYXZhLmlvLldyaXRlciB3cml0ZXIgPSBtX3dyaXRlcjsKLSAgICAgICAgICAgIGlmICghbV9pbkRvY3R5cGUpCi0gICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKCJdPiIpOwotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZSgnPicpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICB3cml0ZXIud3JpdGUobV9saW5lU2VwLCAwLCBtX2xpbmVTZXBMZW4pOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChJT0V4Y2VwdGlvbiBlKQotICAgICAgICB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKGUpOwotICAgICAgICB9Ci0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBFbmQgdGhlIHNjb3BlIG9mIGEgcHJlZml4LVVSSSBOYW1lc3BhY2UgbWFwcGluZy4KLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI2VuZFByZWZpeE1hcHBpbmcKLSAgICAgKgotICAgICAqIEBwYXJhbSBwcmVmaXggVGhlIHByZWZpeCB0aGF0IHdhcyBiZWluZyBtYXBwaW5nLgotICAgICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIFRoZSBjbGllbnQgbWF5IHRocm93Ci0gICAgICogICAgICAgICAgICBhbiBleGNlcHRpb24gZHVyaW5nIHByb2Nlc3NpbmcuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kUHJlZml4TWFwcGluZyhTdHJpbmcgcHJlZml4KSB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAgeyAvLyBkbyBub3RoaW5nCi0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgaWdub3JhYmxlIHdoaXRlc3BhY2UgaW4gZWxlbWVudCBjb250ZW50LgotICAgICAqCi0gICAgICogTm90IHN1cmUgaG93IHRvIGdldCB0aGlzIGludm9rZWQgcXVpdGUgeWV0LgotICAgICAqCi0gICAgICogQHBhcmFtIGNoIFRoZSBjaGFyYWN0ZXJzIGZyb20gdGhlIFhNTCBkb2N1bWVudC4KLSAgICAgKiBAcGFyYW0gc3RhcnQgVGhlIHN0YXJ0IHBvc2l0aW9uIGluIHRoZSBhcnJheS4KLSAgICAgKiBAcGFyYW0gbGVuZ3RoIFRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyB0byByZWFkIGZyb20gdGhlIGFycmF5LgotICAgICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAgICogQHNlZSAjY2hhcmFjdGVycwotICAgICAqCi0gICAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBpZ25vcmFibGVXaGl0ZXNwYWNlKGNoYXIgY2hbXSwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKQotICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAgewotCi0gICAgICAgIGlmICgwID09IGxlbmd0aCkKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgY2hhcmFjdGVycyhjaCwgc3RhcnQsIGxlbmd0aCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgYSBza2lwcGVkIGVudGl0eS4KLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI3NraXBwZWRFbnRpdHkKLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBza2lwcGVkIGVudGl0eS4gIElmIGl0IGlzIGEKLSAgICAgKiAgICAgICBwYXJhbWV0ZXIgICAgICAgICAgICAgICAgICAgZW50aXR5LCB0aGUgbmFtZSB3aWxsIGJlZ2luIHdpdGggJyUnLAotICAgICAqIGFuZCBpZiBpdCBpcyB0aGUgZXh0ZXJuYWwgRFREIHN1YnNldCwgaXQgd2lsbCBiZSB0aGUgc3RyaW5nCi0gICAgICogIltkdGRdIi4KLSAgICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkgd3JhcHBpbmcKLSAgICAgKiBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBza2lwcGVkRW50aXR5KFN0cmluZyBuYW1lKSB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAgeyAvLyBUT0RPOiBTaG91bGQgaGFuZGxlCi0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmVwb3J0IHRoZSBzdGFydCBvZiBhIENEQVRBIHNlY3Rpb24uCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBUaGUgYXBwbGljYXRpb24gbWF5IHJhaXNlIGFuIGV4Y2VwdGlvbi4KLSAgICAgKiBAc2VlICNlbmRDREFUQQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0Q0RBVEEoKSB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBtX2NkYXRhU3RhcnRDYWxsZWQgPSB0cnVlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJlcG9ydCB0aGUgYmVnaW5uaW5nIG9mIGFuIGVudGl0eS4KLSAgICAgKgotICAgICAqIFRoZSBzdGFydCBhbmQgZW5kIG9mIHRoZSBkb2N1bWVudCBlbnRpdHkgYXJlIG5vdCByZXBvcnRlZC4KLSAgICAgKiBUaGUgc3RhcnQgYW5kIGVuZCBvZiB0aGUgZXh0ZXJuYWwgRFREIHN1YnNldCBhcmUgcmVwb3J0ZWQKLSAgICAgKiB1c2luZyB0aGUgcHNldWRvLW5hbWUgIltkdGRdIi4gIEFsbCBvdGhlciBldmVudHMgbXVzdCBiZQotICAgICAqIHByb3Blcmx5IG5lc3RlZCB3aXRoaW4gc3RhcnQvZW5kIGVudGl0eSBldmVudHMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgZW50aXR5LiAgSWYgaXQgaXMgYSBwYXJhbWV0ZXIKLSAgICAgKiAgICAgICAgZW50aXR5LCB0aGUgbmFtZSB3aWxsIGJlZ2luIHdpdGggJyUnLgotICAgICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIFRoZSBhcHBsaWNhdGlvbiBtYXkgcmFpc2UgYW4gZXhjZXB0aW9uLgotICAgICAqIEBzZWUgI2VuZEVudGl0eQotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguZXh0LkRlY2xIYW5kbGVyI2ludGVybmFsRW50aXR5RGVjbAotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguZXh0LkRlY2xIYW5kbGVyI2V4dGVybmFsRW50aXR5RGVjbAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RW50aXR5KFN0cmluZyBuYW1lKSB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAobmFtZS5lcXVhbHMoIltkdGRdIikpCi0gICAgICAgICAgICBtX2luRXh0ZXJuYWxEVEQgPSB0cnVlOwotCi0gICAgICAgIGlmICghbV9leHBhbmREVERFbnRpdGllcyAmJiAhbV9pbkV4dGVybmFsRFREKSB7Ci0gICAgICAgICAgICAvKiBPbmx5IGxlYXZlIHRoZSBlbnRpdHkgYXMtaXMgaWYKLSAgICAgICAgICAgICAqIHdlJ3ZlIGJlZW4gdG9sZCBub3QgdG8gZXhwYW5kIHRoZW0KLSAgICAgICAgICAgICAqIGFuZCB0aGlzIGlzIG5vdCB0aGUgbWFnaWMgW2R0ZF0gbmFtZS4KLSAgICAgICAgICAgICAqLwotICAgICAgICAgICAgc3RhcnROb25Fc2NhcGluZygpOwotICAgICAgICAgICAgY2hhcmFjdGVycygiJiIgKyBuYW1lICsgJzsnKTsKLSAgICAgICAgICAgIGVuZE5vbkVzY2FwaW5nKCk7Ci0gICAgICAgIH0KLQotICAgICAgICBtX2luRW50aXR5UmVmID0gdHJ1ZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBGb3IgdGhlIGVuY2xvc2luZyBlbGVtZW50cyBzdGFydGluZyB0YWcgd3JpdGUgb3V0Ci0gICAgICogb3V0IGFueSBhdHRyaWJ1dGVzIGZvbGxvd2VkIGJ5ICI+IgotICAgICAqCi0gICAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCBjbG9zZVN0YXJ0VGFnKCkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaWYgKG1fZWxlbUNvbnRleHQubV9zdGFydFRhZ09wZW4pCi0gICAgICAgIHsKLQotICAgICAgICAgICAgdHJ5Ci0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgaWYgKG1fdHJhY2VyICE9IG51bGwpCi0gICAgICAgICAgICAgICAgICAgIHN1cGVyLmZpcmVTdGFydEVsZW0obV9lbGVtQ29udGV4dC5tX2VsZW1lbnROYW1lKTsKLSAgICAgICAgICAgICAgICBpbnQgbkF0dHJzID0gbV9hdHRyaWJ1dGVzLmdldExlbmd0aCgpOwotICAgICAgICAgICAgICAgIGlmIChuQXR0cnMgPiAwKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgIHByb2Nlc3NBdHRyaWJ1dGVzKG1fd3JpdGVyLCBuQXR0cnMpOwotICAgICAgICAgICAgICAgICAgICAvLyBjbGVhciBhdHRyaWJ1dGVzIG9iamVjdCBmb3IgcmUtdXNlIHdpdGggbmV4dCBlbGVtZW50Ci0gICAgICAgICAgICAgICAgICAgIG1fYXR0cmlidXRlcy5jbGVhcigpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBtX3dyaXRlci53cml0ZSgnPicpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2F0Y2ggKElPRXhjZXB0aW9uIGUpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbihlKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLyogd2hldGhlciBYYWxhbiBvciBYU0xUQywgd2UgaGF2ZSB0aGUgcHJlZml4IG1hcHBpbmdzIG5vdywgc28KLSAgICAgICAgICAgICAqIGxldHMgZGV0ZXJtaW5lIGlmIHRoZSBjdXJyZW50IGVsZW1lbnQgaXMgc3BlY2lmaWVkIGluIHRoZSBjZGF0YS0KLSAgICAgICAgICAgICAqIHNlY3Rpb24tZWxlbWVudHMgbGlzdC4KLSAgICAgICAgICAgICAqLwotICAgICAgICAgICAgaWYgKG1fY2RhdGFTZWN0aW9uRWxlbWVudHMgIT0gbnVsbCkKLSAgICAgICAgICAgICAgICBtX2VsZW1Db250ZXh0Lm1faXNDZGF0YVNlY3Rpb24gPSBpc0NkYXRhU2VjdGlvbigpOwotCi0gICAgICAgICAgICBpZiAobV9kb0luZGVudCkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBtX2lzcHJldnRleHQgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICBtX3ByZXNlcnZlcy5wdXNoKG1faXNwcmVzZXJ2ZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJlcG9ydCB0aGUgc3RhcnQgb2YgRFREIGRlY2xhcmF0aW9ucywgaWYgYW55LgotICAgICAqCi0gICAgICogQW55IGRlY2xhcmF0aW9ucyBhcmUgYXNzdW1lZCB0byBiZSBpbiB0aGUgaW50ZXJuYWwgc3Vic2V0IHVubGVzcwotICAgICAqIG90aGVyd2lzZSBpbmRpY2F0ZWQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgZG9jdW1lbnQgdHlwZSBuYW1lLgotICAgICAqIEBwYXJhbSBwdWJsaWNJZCBUaGUgZGVjbGFyZWQgcHVibGljIGlkZW50aWZpZXIgZm9yIHRoZQotICAgICAqICAgICAgICBleHRlcm5hbCBEVEQgc3Vic2V0LCBvciBudWxsIGlmIG5vbmUgd2FzIGRlY2xhcmVkLgotICAgICAqIEBwYXJhbSBzeXN0ZW1JZCBUaGUgZGVjbGFyZWQgc3lzdGVtIGlkZW50aWZpZXIgZm9yIHRoZQotICAgICAqICAgICAgICBleHRlcm5hbCBEVEQgc3Vic2V0LCBvciBudWxsIGlmIG5vbmUgd2FzIGRlY2xhcmVkLgotICAgICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIFRoZSBhcHBsaWNhdGlvbiBtYXkgcmFpc2UgYW4KLSAgICAgKiAgICAgICAgICAgIGV4Y2VwdGlvbi4KLSAgICAgKiBAc2VlICNlbmREVEQKLSAgICAgKiBAc2VlICNzdGFydEVudGl0eQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RFREKFN0cmluZyBuYW1lLCBTdHJpbmcgcHVibGljSWQsIFN0cmluZyBzeXN0ZW1JZCkKLSAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgc2V0RG9jdHlwZVN5c3RlbShzeXN0ZW1JZCk7Ci0gICAgICAgIHNldERvY3R5cGVQdWJsaWMocHVibGljSWQpOwotCi0gICAgICAgIG1fZWxlbUNvbnRleHQubV9lbGVtZW50TmFtZSA9IG5hbWU7Ci0gICAgICAgIG1faW5Eb2N0eXBlID0gdHJ1ZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBtX2luZGVudEFtb3VudC4KLSAgICAgKiBAcmV0dXJuIGludAotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0SW5kZW50QW1vdW50KCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBtX2luZGVudEFtb3VudDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSBtX2luZGVudEFtb3VudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBtX2luZGVudEFtb3VudCBUaGUgbV9pbmRlbnRBbW91bnQgdG8gc2V0Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0SW5kZW50QW1vdW50KGludCBtX2luZGVudEFtb3VudCkKLSAgICB7Ci0gICAgICAgIHRoaXMubV9pbmRlbnRBbW91bnQgPSBtX2luZGVudEFtb3VudDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUZWxsIGlmLCBiYXNlZCBvbiBzcGFjZSBwcmVzZXJ2YXRpb24gY29uc3RyYWludHMgYW5kIHRoZSBkb0luZGVudCBwcm9wZXJ0eSwKLSAgICAgKiBpZiBhbiBpbmRlbnQgc2hvdWxkIG9jY3VyLgotICAgICAqCi0gICAgICogQHJldHVybiBUcnVlIGlmIGFuIGluZGVudCBzaG91bGQgb2NjdXIuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gc2hvdWxkSW5kZW50KCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBtX2RvSW5kZW50ICYmICghbV9pc3ByZXNlcnZlICYmICFtX2lzcHJldnRleHQpICYmIChtX2VsZW1Db250ZXh0Lm1fY3VycmVudEVsZW1EZXB0aCA+IDAgfHwgbV9pc1N0YW5kYWxvbmUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNlYXJjaGVzIGZvciB0aGUgbGlzdCBvZiBxbmFtZSBwcm9wZXJ0aWVzIHdpdGggdGhlIHNwZWNpZmllZCBrZXkgaW4gdGhlCi0gICAgICogcHJvcGVydHkgbGlzdC4gSWYgdGhlIGtleSBpcyBub3QgZm91bmQgaW4gdGhpcyBwcm9wZXJ0eSBsaXN0LCB0aGUgZGVmYXVsdAotICAgICAqIHByb3BlcnR5IGxpc3QsIGFuZCBpdHMgZGVmYXVsdHMsIHJlY3Vyc2l2ZWx5LCBhcmUgdGhlbiBjaGVja2VkLiBUaGUKLSAgICAgKiBtZXRob2QgcmV0dXJucyA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGUgcHJvcGVydHkgaXMgbm90IGZvdW5kLgotICAgICAqCi0gICAgICogQHBhcmFtICAga2V5ICAgdGhlIHByb3BlcnR5IGtleS4KLSAgICAgKiBAcGFyYW0gcHJvcHMgdGhlIGxpc3Qgb2YgcHJvcGVydGllcyB0byBzZWFyY2ggaW4uCi0gICAgICoKLSAgICAgKiBTZXRzIHRoZSB2ZWN0b3Igb2YgbG9jYWwtbmFtZS9VUkkgcGFpcnMgb2YgdGhlIGNkYXRhIHNlY3Rpb24gZWxlbWVudHMKLSAgICAgKiBzcGVjaWZpZWQgaW4gdGhlIGNkYXRhLXNlY3Rpb24tZWxlbWVudHMgcHJvcGVydHkuCi0gICAgICoKLSAgICAgKiBUaGlzIG1ldGhvZCBpcyBlc3NlbnRpYWxseSBhIGNvcHkgb2YgZ2V0UU5hbWVQcm9wZXJ0aWVzKCkgZnJvbQotICAgICAqIE91dHB1dFByb3BlcnRpZXMuIEV2ZW50dWFsbHkgdGhpcyBtZXRob2Qgc2hvdWxkIGdvIGF3YXkgYW5kIGEgY2FsbAotICAgICAqIHRvIHNldENkYXRhU2VjdGlvbkVsZW1lbnRzKFZlY3RvciB2KSBzaG91bGQgYmUgbWFkZSBkaXJlY3RseS4KLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgc2V0Q2RhdGFTZWN0aW9uRWxlbWVudHMoU3RyaW5nIGtleSwgUHJvcGVydGllcyBwcm9wcykKLSAgICB7Ci0KLSAgICAgICAgU3RyaW5nIHMgPSBwcm9wcy5nZXRQcm9wZXJ0eShrZXkpOwotCi0gICAgICAgIGlmIChudWxsICE9IHMpCi0gICAgICAgIHsKLSAgICAgICAgICAgIC8vIFZlY3RvciBvZiBVUkkvTG9jYWxOYW1lIHBhaXJzCi0gICAgICAgICAgICBWZWN0b3IgdiA9IG5ldyBWZWN0b3IoKTsKLSAgICAgICAgICAgIGludCBsID0gcy5sZW5ndGgoKTsKLSAgICAgICAgICAgIGJvb2xlYW4gaW5DdXJseSA9IGZhbHNlOwotICAgICAgICAgICAgU3RyaW5nQnVmZmVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLQotICAgICAgICAgICAgLy8gcGFyc2UgdGhyb3VnaCBzdHJpbmcsIGJyZWFraW5nIG9uIHdoaXRlc3BhY2VzLiAgSSBkbyB0aGlzIGluc3RlYWQKLSAgICAgICAgICAgIC8vIG9mIGEgdG9rZW5pemVyIHNvIEkgY2FuIHRyYWNrIHdoaXRlc3BhY2UgaW5zaWRlIG9mIGN1cmx5IGJyYWNrZXRzLAotICAgICAgICAgICAgLy8gd2hpY2ggdGhlb3JldGljYWxseSBzaG91bGRuJ3QgaGFwcGVuIGlmIHRoZXkgY29udGFpbiBsZWdhbCBVUkxzLgotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsOyBpKyspCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgY2hhciBjID0gcy5jaGFyQXQoaSk7Ci0KLSAgICAgICAgICAgICAgICBpZiAoQ2hhcmFjdGVyLmlzV2hpdGVzcGFjZShjKSkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIGlmICghaW5DdXJseSkKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGJ1Zi5sZW5ndGgoKSA+IDApCi0gICAgICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkQ2RhdGFTZWN0aW9uRWxlbWVudChidWYudG9TdHJpbmcoKSwgdik7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnVmLnNldExlbmd0aCgwKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgaWYgKCd7JyA9PSBjKQotICAgICAgICAgICAgICAgICAgICBpbkN1cmx5ID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICBlbHNlIGlmICgnfScgPT0gYykKLSAgICAgICAgICAgICAgICAgICAgaW5DdXJseSA9IGZhbHNlOwotCi0gICAgICAgICAgICAgICAgYnVmLmFwcGVuZChjKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKGJ1Zi5sZW5ndGgoKSA+IDApCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgYWRkQ2RhdGFTZWN0aW9uRWxlbWVudChidWYudG9TdHJpbmcoKSwgdik7Ci0gICAgICAgICAgICAgICAgYnVmLnNldExlbmd0aCgwKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vIGNhbGwgdGhlIG9mZmljaWFsLCBwdWJsaWMgbWV0aG9kIHRvIHNldCB0aGUgY29sbGVjdGVkIG5hbWVzCi0gICAgICAgICAgICBzZXRDZGF0YVNlY3Rpb25FbGVtZW50cyh2KTsKLSAgICAgICAgfQotCi0gICAgfQotCi0gICAgLyoqCi0gICAgICogQWRkcyBhIFVSSS9Mb2NhbE5hbWUgcGFpciBvZiBzdHJpbmdzIHRvIHRoZSBsaXN0LgotICAgICAqCi0gICAgICogQHBhcmFtIFVSSV9hbmRfbG9jYWxOYW1lIFN0cmluZyBvZiB0aGUgZm9ybSAie3VyaX1sb2NhbCIgb3IgImxvY2FsIgotICAgICAqCi0gICAgICogQHJldHVybiBhIFFOYW1lIG9iamVjdAotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCBhZGRDZGF0YVNlY3Rpb25FbGVtZW50KFN0cmluZyBVUklfYW5kX2xvY2FsTmFtZSwgVmVjdG9yIHYpCi0gICAgewotCi0gICAgICAgIFN0cmluZ1Rva2VuaXplciB0b2tlbml6ZXIgPQotICAgICAgICAgICAgbmV3IFN0cmluZ1Rva2VuaXplcihVUklfYW5kX2xvY2FsTmFtZSwgInt9IiwgZmFsc2UpOwotICAgICAgICBTdHJpbmcgczEgPSB0b2tlbml6ZXIubmV4dFRva2VuKCk7Ci0gICAgICAgIFN0cmluZyBzMiA9IHRva2VuaXplci5oYXNNb3JlVG9rZW5zKCkgPyB0b2tlbml6ZXIubmV4dFRva2VuKCkgOiBudWxsOwotCi0gICAgICAgIGlmIChudWxsID09IHMyKQotICAgICAgICB7Ci0gICAgICAgICAgICAvLyBhZGQgbnVsbCBVUkkgYW5kIHRoZSBsb2NhbCBuYW1lCi0gICAgICAgICAgICB2LmFkZEVsZW1lbnQobnVsbCk7Ci0gICAgICAgICAgICB2LmFkZEVsZW1lbnQoczEpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotICAgICAgICAgICAgLy8gYWRkIFVSSSwgdGhlbiBsb2NhbCBuYW1lCi0gICAgICAgICAgICB2LmFkZEVsZW1lbnQoczEpOwotICAgICAgICAgICAgdi5hZGRFbGVtZW50KHMyKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJlbWVtYmVycyB0aGUgY2RhdGEgc2VjdGlvbnMgc3BlY2lmaWVkIGluIHRoZSBjZGF0YS1zZWN0aW9uLWVsZW1lbnRzLgotICAgICAqIFRoZSAib2ZmaWNpYWwgd2F5IHRvIHNldCBVUkkgYW5kIGxvY2FsTmFtZSBwYWlycy4KLSAgICAgKiBUaGlzIG1ldGhvZCBzaG91bGQgYmUgdXNlZCBieSBib3RoIFhhbGFuIGFuZCBYU0xUQy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBVUklfYW5kX2xvY2FsTmFtZXMgYSB2ZWN0b3Igb2YgcGFpcnMgb2YgU3RyaW5ncyAoVVJJL2xvY2FsKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldENkYXRhU2VjdGlvbkVsZW1lbnRzKFZlY3RvciBVUklfYW5kX2xvY2FsTmFtZXMpCi0gICAgewotICAgICAgICBtX2NkYXRhU2VjdGlvbkVsZW1lbnRzID0gVVJJX2FuZF9sb2NhbE5hbWVzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIE1ha2VzIHN1cmUgdGhhdCB0aGUgbmFtZXNwYWNlIFVSSSBmb3IgdGhlIGdpdmVuIHF1YWxpZmllZCBhdHRyaWJ1dGUgbmFtZQotICAgICAqIGlzIGRlY2xhcmVkLgotICAgICAqIEBwYXJhbSBucyB0aGUgbmFtZXNwYWNlIFVSSQotICAgICAqIEBwYXJhbSByYXdOYW1lIHRoZSBxdWFsaWZpZWQgbmFtZQotICAgICAqIEByZXR1cm4gcmV0dXJucyBudWxsIGlmIG5vIGFjdGlvbiBpcyB0YWtlbiwgb3RoZXJ3aXNlIGl0IHJldHVybnMgdGhlCi0gICAgICogcHJlZml4IHVzZWQgaW4gZGVjbGFyaW5nIHRoZSBuYW1lc3BhY2UuCi0gICAgICogQHRocm93cyBTQVhFeGNlcHRpb24KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgU3RyaW5nIGVuc3VyZUF0dHJpYnV0ZXNOYW1lc3BhY2VJc0RlY2xhcmVkKAotICAgICAgICBTdHJpbmcgbnMsCi0gICAgICAgIFN0cmluZyBsb2NhbE5hbWUsCi0gICAgICAgIFN0cmluZyByYXdOYW1lKQotICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAgewotCi0gICAgICAgIGlmIChucyAhPSBudWxsICYmIG5zLmxlbmd0aCgpID4gMCkKLSAgICAgICAgewotCi0gICAgICAgICAgICAvLyBleHRyYWN0IHRoZSBwcmVmaXggaW4gZnJvbnQgb2YgdGhlIHJhdyBuYW1lCi0gICAgICAgICAgICBpbnQgaW5kZXggPSAwOwotICAgICAgICAgICAgU3RyaW5nIHByZWZpeEZyb21SYXdOYW1lID0KLSAgICAgICAgICAgICAgICAoaW5kZXggPSByYXdOYW1lLmluZGV4T2YoIjoiKSkgPCAwCi0gICAgICAgICAgICAgICAgICAgID8gIiIKLSAgICAgICAgICAgICAgICAgICAgOiByYXdOYW1lLnN1YnN0cmluZygwLCBpbmRleCk7Ci0KLSAgICAgICAgICAgIGlmIChpbmRleCA+IDApCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgLy8gd2UgaGF2ZSBhIHByZWZpeCwgbGV0cyBzZWUgaWYgaXQgbWFwcyB0byBhIG5hbWVzcGFjZQotICAgICAgICAgICAgICAgIFN0cmluZyB1cmkgPSBtX3ByZWZpeE1hcC5sb29rdXBOYW1lc3BhY2UocHJlZml4RnJvbVJhd05hbWUpOwotICAgICAgICAgICAgICAgIGlmICh1cmkgIT0gbnVsbCAmJiB1cmkuZXF1YWxzKG5zKSkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIHRoZSBwcmVmaXggaW4gdGhlIHJhdyBuYW1lIGlzIGFscmVhZHkgbWFwcyB0byB0aGUgZ2l2ZW4gbmFtZXNwYWNlIHVyaQotICAgICAgICAgICAgICAgICAgICAvLyBzbyB3ZSBkb24ndCBuZWVkIHRvIGRvIGFueXRoaW5nCi0gICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAvLyBUaGUgdXJpIGRvZXMgbm90IG1hcCB0byB0aGUgcHJlZml4IGluIHRoZSByYXcgbmFtZSwKLSAgICAgICAgICAgICAgICAgICAgLy8gc28gbGV0cyBtYWtlIHRoZSBtYXBwaW5nLgotICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXJ0UHJlZml4TWFwcGluZyhwcmVmaXhGcm9tUmF3TmFtZSwgbnMsIGZhbHNlKTsKLSAgICAgICAgICAgICAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGUoCi0gICAgICAgICAgICAgICAgICAgICAgICAiaHR0cDovL3d3dy53My5vcmcvMjAwMC94bWxucy8iLAotICAgICAgICAgICAgICAgICAgICAgICAgcHJlZml4RnJvbVJhd05hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAieG1sbnM6IiArIHByZWZpeEZyb21SYXdOYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgIkNEQVRBIiwKLSAgICAgICAgICAgICAgICAgICAgICAgIG5zLCBmYWxzZSk7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBwcmVmaXhGcm9tUmF3TmFtZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgLy8gd2UgZG9uJ3QgaGF2ZSBhIHByZWZpeCBpbiB0aGUgcmF3IG5hbWUuCi0gICAgICAgICAgICAgICAgLy8gRG9lcyB0aGUgVVJJIG1hcCB0byBhIHByZWZpeCBhbHJlYWR5PwotICAgICAgICAgICAgICAgIFN0cmluZyBwcmVmaXggPSBtX3ByZWZpeE1hcC5sb29rdXBQcmVmaXgobnMpOwotICAgICAgICAgICAgICAgIGlmIChwcmVmaXggPT0gbnVsbCkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIHVyaSBpcyBub3QgYXNzb2NpYXRlZCB3aXRoIGEgcHJlZml4LAotICAgICAgICAgICAgICAgICAgICAvLyBzbyBsZXRzIGdlbmVyYXRlIGEgbmV3IHByZWZpeCB0byB1c2UKLSAgICAgICAgICAgICAgICAgICAgcHJlZml4ID0gbV9wcmVmaXhNYXAuZ2VuZXJhdGVOZXh0UHJlZml4KCk7Ci0gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhcnRQcmVmaXhNYXBwaW5nKHByZWZpeCwgbnMsIGZhbHNlKTsKLSAgICAgICAgICAgICAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGUoCi0gICAgICAgICAgICAgICAgICAgICAgICAiaHR0cDovL3d3dy53My5vcmcvMjAwMC94bWxucy8iLAotICAgICAgICAgICAgICAgICAgICAgICAgcHJlZml4LAotICAgICAgICAgICAgICAgICAgICAgICAgInhtbG5zOiIgKyBwcmVmaXgsCi0gICAgICAgICAgICAgICAgICAgICAgICAiQ0RBVEEiLAotICAgICAgICAgICAgICAgICAgICAgICAgbnMsIGZhbHNlKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICByZXR1cm4gcHJlZml4OwotCi0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgdm9pZCBlbnN1cmVQcmVmaXhJc0RlY2xhcmVkKFN0cmluZyBucywgU3RyaW5nIHJhd05hbWUpCi0gICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICB7Ci0KLSAgICAgICAgaWYgKG5zICE9IG51bGwgJiYgbnMubGVuZ3RoKCkgPiAwKQotICAgICAgICB7Ci0gICAgICAgICAgICBpbnQgaW5kZXg7Ci0gICAgICAgICAgICBmaW5hbCBib29sZWFuIG5vX3ByZWZpeCA9ICgoaW5kZXggPSByYXdOYW1lLmluZGV4T2YoIjoiKSkgPCAwKTsKLSAgICAgICAgICAgIFN0cmluZyBwcmVmaXggPSAobm9fcHJlZml4KSA/ICIiIDogcmF3TmFtZS5zdWJzdHJpbmcoMCwgaW5kZXgpOwotCi0gICAgICAgICAgICBpZiAobnVsbCAhPSBwcmVmaXgpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIGZvdW5kVVJJID0gbV9wcmVmaXhNYXAubG9va3VwTmFtZXNwYWNlKHByZWZpeCk7Ci0KLSAgICAgICAgICAgICAgICBpZiAoKG51bGwgPT0gZm91bmRVUkkpIHx8ICFmb3VuZFVSSS5lcXVhbHMobnMpKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGFydFByZWZpeE1hcHBpbmcocHJlZml4LCBucyk7Ci0KLSAgICAgICAgICAgICAgICAgICAgLy8gQnVnemlsbGExMTMzOiBHZW5lcmF0ZSBhdHRyaWJ1dGUgYXMgd2VsbCBhcyBuYW1lc3BhY2UgZXZlbnQuCi0gICAgICAgICAgICAgICAgICAgIC8vIFNBWCBkb2VzIGV4cGVjdCBib3RoLgotCi0gICAgICAgICAgICAgICAgICAgIHRoaXMuYWRkQXR0cmlidXRlQWx3YXlzKAotICAgICAgICAgICAgICAgICAgICAgICAgImh0dHA6Ly93d3cudzMub3JnLzIwMDAveG1sbnMvIiwKLSAgICAgICAgICAgICAgICAgICAgICAgIG5vX3ByZWZpeCA/ICJ4bWxucyIgOiBwcmVmaXgsICAvLyBsb2NhbCBuYW1lCi0gICAgICAgICAgICAgICAgICAgICAgICBub19wcmVmaXggPyAieG1sbnMiIDogKCJ4bWxuczoiKyBwcmVmaXgpLCAvLyBxbmFtZQotICAgICAgICAgICAgICAgICAgICAgICAgIkNEQVRBIiwKLSAgICAgICAgICAgICAgICAgICAgICAgIG5zLAotICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgZmx1c2hlcyBhbnkgcGVuZGluZyBldmVudHMsIHdoaWNoIGNhbiBiZSBzdGFydERvY3VtZW50KCkKLSAgICAgKiBjbG9zaW5nIHRoZSBvcGVuaW5nIHRhZyBvZiBhbiBlbGVtZW50LCBvciBjbG9zaW5nIGFuIG9wZW4gQ0RBVEEgc2VjdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBmbHVzaFBlbmRpbmcoKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICAgICAgaWYgKG1fbmVlZFRvQ2FsbFN0YXJ0RG9jdW1lbnQpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgc3RhcnREb2N1bWVudEludGVybmFsKCk7Ci0gICAgICAgICAgICAgICAgbV9uZWVkVG9DYWxsU3RhcnREb2N1bWVudCA9IGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKG1fZWxlbUNvbnRleHQubV9zdGFydFRhZ09wZW4pCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgY2xvc2VTdGFydFRhZygpOwotICAgICAgICAgICAgICAgIG1fZWxlbUNvbnRleHQubV9zdGFydFRhZ09wZW4gPSBmYWxzZTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKG1fY2RhdGFUYWdPcGVuKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIGNsb3NlQ0RBVEEoKTsKLSAgICAgICAgICAgICAgICBtX2NkYXRhVGFnT3BlbiA9IGZhbHNlOwotICAgICAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldENvbnRlbnRIYW5kbGVyKENvbnRlbnRIYW5kbGVyIGNoKQotICAgIHsKLSAgICAgICAgLy8gdGhpcyBtZXRob2QgaXMgcmVhbGx5IG9ubHkgdXNlZnVsIGluIHRoZSBUb1NBWEhhbmRsZXIgY2xhc3NlcyBidXQgaXQgaXMKLSAgICAgICAgLy8gaW4gdGhlIGludGVyZmFjZS4gIElmIHRoZSBtZXRob2QgZGVmaW5lZCBoZXJlIGlzIGV2ZXIgY2FsbGVkCi0gICAgICAgIC8vIHdlIGFyZSBwcm9iYWJseSBpbiB0cm91YmxlLgotICAgIH0KLQotICAgIC8qKgotICAgICAqIEFkZHMgdGhlIGdpdmVuIGF0dHJpYnV0ZSB0byB0aGUgc2V0IG9mIGF0dHJpYnV0ZXMsIGV2ZW4gaWYgdGhlcmUgaXMKLSAgICAgKiBubyBjdXJyZW50bHkgb3BlbiBlbGVtZW50LiBUaGlzIGlzIHVzZWZ1bCBpZiBhIFNBWCBzdGFydFByZWZpeE1hcHBpbmcoKQotICAgICAqIHNob3VsZCBuZWVkIHRvIGFkZCBhbiBhdHRyaWJ1dGUgYmVmb3JlIHRoZSBlbGVtZW50IG5hbWUgaXMgc2Vlbi4KLSAgICAgKgotICAgICAqIFRoaXMgbWV0aG9kIGlzIGEgY29weSBvZiBpdHMgc3VwZXIgY2xhc3NlcyBtZXRob2QsIGV4Y2VwdCB0aGF0IHNvbWUKLSAgICAgKiB0cmFjaW5nIG9mIGV2ZW50cyBpcyBkb25lLiAgVGhpcyBpcyBzbyB0aGUgdHJhY2luZyBpcyBvbmx5IGRvbmUgZm9yCi0gICAgICogc3RyZWFtIHNlcmlhbGl6ZXJzLCBub3QgZm9yIFNBWCBvbmVzLgotICAgICAqCi0gICAgICogQHBhcmFtIHVyaSB0aGUgVVJJIG9mIHRoZSBhdHRyaWJ1dGUKLSAgICAgKiBAcGFyYW0gbG9jYWxOYW1lIHRoZSBsb2NhbCBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUKLSAgICAgKiBAcGFyYW0gcmF3TmFtZSAgIHRoZSBxdWFsaWZpZWQgbmFtZSBvZiB0aGUgYXR0cmlidXRlCi0gICAgICogQHBhcmFtIHR5cGUgdGhlIHR5cGUgb2YgdGhlIGF0dHJpYnV0ZSAocHJvYmFibHkgQ0RBVEEpCi0gICAgICogQHBhcmFtIHZhbHVlIHRoZSB2YWx1ZSBvZiB0aGUgYXR0cmlidXRlCi0gICAgICogQHBhcmFtIHhzbEF0dHJpYnV0ZSB0cnVlIGlmIHRoaXMgYXR0cmlidXRlIGlzIGNvbWluZyBmcm9tIGFuIHhzbDphdHRyaWJ1dGUgZWxlbWVudC4KLSAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGF0dHJpYnV0ZSB2YWx1ZSB3YXMgYWRkZWQsCi0gICAgICogZmFsc2UgaWYgdGhlIGF0dHJpYnV0ZSBhbHJlYWR5IGV4aXN0ZWQgYW5kIHRoZSB2YWx1ZSB3YXMKLSAgICAgKiByZXBsYWNlZCB3aXRoIHRoZSBuZXcgdmFsdWUuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gYWRkQXR0cmlidXRlQWx3YXlzKAotICAgICAgICBTdHJpbmcgdXJpLAotICAgICAgICBTdHJpbmcgbG9jYWxOYW1lLAotICAgICAgICBTdHJpbmcgcmF3TmFtZSwKLSAgICAgICAgU3RyaW5nIHR5cGUsCi0gICAgICAgIFN0cmluZyB2YWx1ZSwKLSAgICAgICAgYm9vbGVhbiB4c2xBdHRyaWJ1dGUpCi0gICAgewotICAgICAgICBib29sZWFuIHdhc19hZGRlZDsKLSAgICAgICAgaW50IGluZGV4OwotICAgICAgICAvL2lmICh1cmkgPT0gbnVsbCB8fCBsb2NhbE5hbWUgPT0gbnVsbCB8fCB1cmkubGVuZ3RoKCkgPT0gMCkKLSAgICAgICAgICAgIGluZGV4ID0gbV9hdHRyaWJ1dGVzLmdldEluZGV4KHJhd05hbWUpOwotICAgICAgICAvLyBEb24ndCB1c2UgJ2xvY2FsTmFtZScgYXMgaXQgZ2l2ZXMgaW5jb3JyZWN0IHZhbHVlLCByZWx5IG9ubHkgb24gJ3Jhd05hbWUnCi0gICAgICAgIC8qZWxzZSB7Ci0gICAgICAgICAgICBpbmRleCA9IG1fYXR0cmlidXRlcy5nZXRJbmRleCh1cmksIGxvY2FsTmFtZSk7Ci0gICAgICAgIH0qLwotICAgICAgICBpZiAoaW5kZXggPj0gMCkKLSAgICAgICAgewotICAgICAgICAgICAgU3RyaW5nIG9sZF92YWx1ZSA9IG51bGw7Ci0gICAgICAgICAgICBpZiAobV90cmFjZXIgIT0gbnVsbCkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBvbGRfdmFsdWUgPSBtX2F0dHJpYnV0ZXMuZ2V0VmFsdWUoaW5kZXgpOwotICAgICAgICAgICAgICAgIGlmICh2YWx1ZS5lcXVhbHMob2xkX3ZhbHVlKSkKLSAgICAgICAgICAgICAgICAgICAgb2xkX3ZhbHVlID0gbnVsbDsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLyogV2UndmUgc2VlbiB0aGUgYXR0cmlidXRlIGJlZm9yZS4KLSAgICAgICAgICAgICAqIFdlIG1heSBoYXZlIGEgbnVsbCB1cmkgb3IgbG9jYWxOYW1lLCBidXQgYWxsIHdlIHJlYWxseQotICAgICAgICAgICAgICogd2FudCB0byByZS1zZXQgaXMgdGhlIHZhbHVlIGFueXdheS4KLSAgICAgICAgICAgICAqLwotICAgICAgICAgICAgbV9hdHRyaWJ1dGVzLnNldFZhbHVlKGluZGV4LCB2YWx1ZSk7Ci0gICAgICAgICAgICB3YXNfYWRkZWQgPSBmYWxzZTsKLSAgICAgICAgICAgIGlmIChvbGRfdmFsdWUgIT0gbnVsbCl7Ci0gICAgICAgICAgICAgICAgZmlyZVBzZXVkb0F0dHJpYnV0ZXMoKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotICAgICAgICAgICAgLy8gdGhlIGF0dHJpYnV0ZSBkb2Vzbid0IGV4aXN0IHlldCwgY3JlYXRlIGl0Ci0gICAgICAgICAgICBpZiAoeHNsQXR0cmlidXRlKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIC8qCi0gICAgICAgICAgICAgICAgICogVGhpcyBhdHRyaWJ1dGUgaXMgZnJvbSBhbiB4c2w6YXR0cmlidXRlIGVsZW1lbnQgc28gd2UgdGFrZSBzb21lIGNhcmUgaW4KLSAgICAgICAgICAgICAgICAgKiBhZGRpbmcgaXQsIGUuZy4KLSAgICAgICAgICAgICAgICAgKiAgIDxlbGVtMSAgZm9vOmF0dHIxPSIxIiB4bWxuczpmb289InVyaTEiPgotICAgICAgICAgICAgICAgICAqICAgICAgIDx4c2w6YXR0cmlidXRlIG5hbWU9ImZvbzphdHRyMiI+MjwveHNsOmF0dHJpYnV0ZT4KLSAgICAgICAgICAgICAgICAgKiAgIDwvZWxlbTE+Ci0gICAgICAgICAgICAgICAgICoKLSAgICAgICAgICAgICAgICAgKiBXZSBhcmUgYWRkaW5nIGF0dHIxIGFuZCBhdHRyMiBib3RoIGFzIGF0dHJpYnV0ZXMgb2YgZWxlbTEsCi0gICAgICAgICAgICAgICAgICogYW5kIHRoaXMgY29kZSBpcyBhZGRpbmcgYXR0cjIgKHRoZSB4c2w6YXR0cmlidXRlICkuCi0gICAgICAgICAgICAgICAgICogV2UgY291bGQgaGF2ZSBhIGNvbGxpc2lvbiB3aXRoIHRoZSBwcmVmaXggbGlrZSBpbiB0aGUgZXhhbXBsZSBhYm92ZS4KLSAgICAgICAgICAgICAgICAgKi8KLQotICAgICAgICAgICAgICAgIC8vIEluIHRoZSBleGFtcGxlIGFib3ZlLCBpcyB0aGVyZSBhIHByZWZpeCBsaWtlIGZvbyA/Ci0gICAgICAgICAgICAgICAgZmluYWwgaW50IGNvbG9uSW5kZXggPSByYXdOYW1lLmluZGV4T2YoJzonKTsKLSAgICAgICAgICAgICAgICBpZiAoY29sb25JbmRleCA+IDApCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcHJlZml4ID0gcmF3TmFtZS5zdWJzdHJpbmcoMCxjb2xvbkluZGV4KTsKLSAgICAgICAgICAgICAgICAgICAgTmFtZXNwYWNlTWFwcGluZ3MuTWFwcGluZ1JlY29yZCBleGlzdGluZ19tYXBwaW5nID0gbV9wcmVmaXhNYXAuZ2V0TWFwcGluZ0Zyb21QcmVmaXgocHJlZml4KTsKLQotICAgICAgICAgICAgICAgICAgICAvKiBCZWZvcmUgYWRkaW5nIHRoaXMgYXR0cmlidXRlIChmb286YXR0cjIpLAotICAgICAgICAgICAgICAgICAgICAgKiBpcyB0aGUgcHJlZml4IGZvciBpdCAoZm9vKSBhbHJlYWR5IG1hcHBlZCBhdCB0aGUgY3VycmVudCBkZXB0aD8KLSAgICAgICAgICAgICAgICAgICAgICovCi0gICAgICAgICAgICAgICAgICAgIGlmIChleGlzdGluZ19tYXBwaW5nICE9IG51bGwKLSAgICAgICAgICAgICAgICAgICAgJiYgZXhpc3RpbmdfbWFwcGluZy5tX2RlY2xhcmF0aW9uRGVwdGggPT0gbV9lbGVtQ29udGV4dC5tX2N1cnJlbnRFbGVtRGVwdGgKLSAgICAgICAgICAgICAgICAgICAgJiYgIWV4aXN0aW5nX21hcHBpbmcubV91cmkuZXF1YWxzKHVyaSkpCi0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8qCi0gICAgICAgICAgICAgICAgICAgICAgICAgKiBUaGVyZSBpcyBhbiBleGlzdGluZyBtYXBwaW5nIG9mIHRoaXMgcHJlZml4LAotICAgICAgICAgICAgICAgICAgICAgICAgICogaXQgZGlmZmVycyBmcm9tIHRoZSBvbmUgd2UgbmVlZCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAqIGFuZCB1bmZvcnR1bmF0ZWx5IGl0IGlzIGF0IHRoZSBjdXJyZW50IGRlcHRoIHNvIHdlCi0gICAgICAgICAgICAgICAgICAgICAgICAgKiBjYW4gbm90IG92ZXItcmlkZSBpdC4KLSAgICAgICAgICAgICAgICAgICAgICAgICAqLwotCi0gICAgICAgICAgICAgICAgICAgICAgICAvKgotICAgICAgICAgICAgICAgICAgICAgICAgICogQXJlIHdlIGx1Y2t5IGVub3VnaCB0aGF0IGFuIGV4aXN0aW5nIG90aGVyIHByZWZpeCBtYXBzIHRvIHRoaXMgVVJJID8KLSAgICAgICAgICAgICAgICAgICAgICAgICAqLwotICAgICAgICAgICAgICAgICAgICAgICAgcHJlZml4ID0gbV9wcmVmaXhNYXAubG9va3VwUHJlZml4KHVyaSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAocHJlZml4ID09IG51bGwpCi0gICAgICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogVW5mb3J0dW5hdGVseSB0aGVyZSBpcyBubyBleGlzdGluZyBwcmVmaXggdGhhdCBoYXBwZW5zIHRvIG1hcCB0byBvdXJzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIHNvIHRvIGF2b2lkIGEgcHJlZml4IGNvbGxpc2lvbiB3ZSBtdXN0IGdlbmVyYXRlZCBhIG5ldyBwcmVmaXggdG8gdXNlLgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIFRoaXMgaXMgT0sgYmVjYXVzZSB0aGUgcHJlZml4IFVSSSBtYXBwaW5nCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICogZGVmaW5lZCBpbiB0aGUgeHNsOmF0dHJpYnV0ZSBpcyBzaG9ydCBpbiBzY29wZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBqdXN0IHRoZSB4c2w6YXR0cmlidXRlIGVsZW1lbnQgaXRzZWxmLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIGFuZCBhdCB0aGlzIHBvaW50IGluIHNlcmlhbGl6YXRpb24gdGhlIGJvZHkgb2YgdGhlCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICogeHNsOmF0dHJpYnV0ZSwgaWYgYW55LCBpcyBqdXN0IGEgU3RyaW5nLiBSaWdodD8KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiAgIC4gLiAuIEkgc3VyZSBob3BlIHNvIC0gQnJpYW4gTS4KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmVmaXggPSBtX3ByZWZpeE1hcC5nZW5lcmF0ZU5leHRQcmVmaXgoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAgICAgcmF3TmFtZSA9IHByZWZpeCArICc6JyArIGxvY2FsTmFtZTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIHRyeQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgLyogVGhpcyBpcyBvdXIgbGFzdCBjaGFuY2UgdG8gbWFrZSBzdXJlIHRoZSBuYW1lc3BhY2UgZm9yIHRoaXMKLSAgICAgICAgICAgICAgICAgICAgICogYXR0cmlidXRlIGlzIGRlY2xhcmVkLCBlc3BlY2lhbGx5IGlmIHdlIGp1c3QgZ2VuZXJhdGVkIGFuIGFsdGVybmF0ZQotICAgICAgICAgICAgICAgICAgICAgKiBwcmVmaXggdG8gYXZvaWQgYSBjb2xsaXNpb24gKHRoZSBuZXcgcHJlZml4L3Jhd05hbWUgd2lsbCBnbyBvdXQgb2Ygc2NvcGUKLSAgICAgICAgICAgICAgICAgICAgICogc29vbiBhbmQgYmUgbG9zdCAuLi4gIGxhc3QgY2hhbmNlIGhlcmUuCi0gICAgICAgICAgICAgICAgICAgICAqLwotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcHJlZml4VXNlZCA9Ci0gICAgICAgICAgICAgICAgICAgICAgICBlbnN1cmVBdHRyaWJ1dGVzTmFtZXNwYWNlSXNEZWNsYXJlZCgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cmksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWxOYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhd05hbWUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAvLyBUT0RPIEF1dG8tZ2VuZXJhdGVkIGNhdGNoIGJsb2NrCi0gICAgICAgICAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgbV9hdHRyaWJ1dGVzLmFkZEF0dHJpYnV0ZSh1cmksIGxvY2FsTmFtZSwgcmF3TmFtZSwgdHlwZSwgdmFsdWUpOwotICAgICAgICAgICAgd2FzX2FkZGVkID0gdHJ1ZTsKLSAgICAgICAgICAgIGlmIChtX3RyYWNlciAhPSBudWxsKXsKLSAgICAgICAgICAgICAgICBmaXJlUHNldWRvQXR0cmlidXRlcygpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiB3YXNfYWRkZWQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVG8gZmlyZSBvZmYgdGhlIHBzZXVkbyBjaGFyYWN0ZXJzIG9mIGF0dHJpYnV0ZXMsIGFzIHRoZXkgY3VycmVudGx5Ci0gICAgICogZXhpc3QuIFRoaXMgbWV0aG9kIHNob3VsZCBiZSBjYWxsZWQgZXZlcnl0aW1lIGFuIGF0dHJpYnV0ZSBpcyBhZGRlZCwKLSAgICAgKiBvciB3aGVuIGFuIGF0dHJpYnV0ZSB2YWx1ZSBpcyBjaGFuZ2VkLCBvciBhbiBlbGVtZW50IGlzIGNyZWF0ZWQuCi0gICAgICovCi0KLSAgICBwcm90ZWN0ZWQgdm9pZCBmaXJlUHNldWRvQXR0cmlidXRlcygpCi0gICAgewotICAgICAgICBpZiAobV90cmFjZXIgIT0gbnVsbCkKLSAgICAgICAgewotICAgICAgICAgICAgdHJ5Ci0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgLy8gZmx1c2ggb3V0IHRoZSAiPGVsZW1OYW1lIiBpZiBub3QgYWxyZWFkeSBmbHVzaGVkCi0gICAgICAgICAgICAgICAgbV93cml0ZXIuZmx1c2goKTsKLQotICAgICAgICAgICAgICAgIC8vIG1ha2UgYSBTdHJpbmdCdWZmZXIgdG8gd3JpdGUgdGhlIG5hbWU9InZhbHVlIiBwYWlycyB0by4KLSAgICAgICAgICAgICAgICBTdHJpbmdCdWZmZXIgc2IgPSBuZXcgU3RyaW5nQnVmZmVyKCk7Ci0gICAgICAgICAgICAgICAgaW50IG5BdHRycyA9IG1fYXR0cmlidXRlcy5nZXRMZW5ndGgoKTsKLSAgICAgICAgICAgICAgICBpZiAobkF0dHJzID4gMCkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIG1ha2UgYSB3cml0ZXIgdGhhdCBpbnRlcm5hbGx5IGFwcGVuZHMgdG8gdGhlIHNhbWUKLSAgICAgICAgICAgICAgICAgICAgLy8gU3RyaW5nQnVmZmVyCi0gICAgICAgICAgICAgICAgICAgIGphdmEuaW8uV3JpdGVyIHdyaXRlciA9Ci0gICAgICAgICAgICAgICAgICAgICAgICBuZXcgVG9TdHJlYW0uV3JpdGVydG9TdHJpbmdCdWZmZXIoc2IpOwotCi0gICAgICAgICAgICAgICAgICAgIHByb2Nlc3NBdHRyaWJ1dGVzKHdyaXRlciwgbkF0dHJzKTsKLSAgICAgICAgICAgICAgICAgICAgLy8gRG9uJ3QgY2xlYXIgdGhlIGF0dHJpYnV0ZXMhCi0gICAgICAgICAgICAgICAgICAgIC8vIFdlIG9ubHkgd2FudCB0byBzZWUgd2hhdCB3b3VsZCBiZSB3cml0dGVuIG91dAotICAgICAgICAgICAgICAgICAgICAvLyBhdCB0aGlzIHBvaW50LCB3ZSBkb24ndCB3YW50IHRvIGxvb3NlIHRoZW0uCi0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHNiLmFwcGVuZCgnPicpOyAgLy8gdGhlIHBvdGVudGlhbCA+IGFmdGVyIHRoZSBhdHRyaWJ1dGVzLgotICAgICAgICAgICAgICAgIC8vIGNvbnZlcnQgdGhlIFN0cmluZ0J1ZmZlciB0byBhIGNoYXIgYXJyYXkgYW5kCi0gICAgICAgICAgICAgICAgLy8gZW1pdCB0aGUgdHJhY2UgZXZlbnQgdGhhdCB0aGVzZSBjaGFyYWN0ZXJzICJtaWdodCIKLSAgICAgICAgICAgICAgICAvLyBiZSB3cml0dGVuCi0gICAgICAgICAgICAgICAgY2hhciBjaFtdID0gc2IudG9TdHJpbmcoKS50b0NoYXJBcnJheSgpOwotICAgICAgICAgICAgICAgIG1fdHJhY2VyLmZpcmVHZW5lcmF0ZUV2ZW50KAotICAgICAgICAgICAgICAgICAgICBTZXJpYWxpemVyVHJhY2UuRVZFTlRUWVBFX09VVFBVVF9QU0VVRE9fQ0hBUkFDVEVSUywKLSAgICAgICAgICAgICAgICAgICAgY2gsCi0gICAgICAgICAgICAgICAgICAgIDAsCi0gICAgICAgICAgICAgICAgICAgIGNoLmxlbmd0aCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXRjaCAoSU9FeGNlcHRpb24gaW9lKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIC8vIGlnbm9yZSA/Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXRjaCAoU0FYRXhjZXB0aW9uIHNlKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIC8vIGlnbm9yZSA/Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIGlubmVyIGNsYXNzIGlzIHVzZWQgb25seSB0byBjb2xsZWN0IGF0dHJpYnV0ZSB2YWx1ZXMKLSAgICAgKiB3cml0dGVuIGJ5IHRoZSBtZXRob2Qgd3JpdGVBdHRyU3RyaW5nKCkgaW50byBhIHN0cmluZyBidWZmZXIuCi0gICAgICogSW4gdGhpcyBtYW5uZXIgdHJhY2UgZXZlbnRzLCBhbmQgdGhlIHJlYWwgd3JpdGluZyBvZiBhdHRyaWJ1dGVzIHdpbGwgdXNlCi0gICAgICogdGhlIHNhbWUgY29kZS4KLSAgICAgKi8KLSAgICBwcml2YXRlIGNsYXNzIFdyaXRlcnRvU3RyaW5nQnVmZmVyIGV4dGVuZHMgamF2YS5pby5Xcml0ZXIKLSAgICB7Ci0gICAgICAgIGZpbmFsIHByaXZhdGUgU3RyaW5nQnVmZmVyIG1fc3RyaW5nYnVmOwotICAgICAgICAvKioKLSAgICAgICAgICogQHNlZSBqYXZhLmlvLldyaXRlciN3cml0ZShjaGFyW10sIGludCwgaW50KQotICAgICAgICAgKi8KLSAgICAgICAgV3JpdGVydG9TdHJpbmdCdWZmZXIoU3RyaW5nQnVmZmVyIHNiKQotICAgICAgICB7Ci0gICAgICAgICAgICBtX3N0cmluZ2J1ZiA9IHNiOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIHZvaWQgd3JpdGUoY2hhcltdIGFyZzAsIGludCBhcmcxLCBpbnQgYXJnMikgdGhyb3dzIElPRXhjZXB0aW9uCi0gICAgICAgIHsKLSAgICAgICAgICAgIG1fc3RyaW5nYnVmLmFwcGVuZChhcmcwLCBhcmcxLCBhcmcyKTsKLSAgICAgICAgfQotICAgICAgICAvKioKLSAgICAgICAgICogQHNlZSBqYXZhLmlvLldyaXRlciNmbHVzaCgpCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgdm9pZCBmbHVzaCgpIHRocm93cyBJT0V4Y2VwdGlvbgotICAgICAgICB7Ci0gICAgICAgIH0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIEBzZWUgamF2YS5pby5Xcml0ZXIjY2xvc2UoKQotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24KLSAgICAgICAgewotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIHZvaWQgd3JpdGUoaW50IGkpCi0gICAgICAgIHsKLSAgICAgICAgICAgIG1fc3RyaW5nYnVmLmFwcGVuZCgoY2hhcikgaSk7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCB3cml0ZShTdHJpbmcgcykKLSAgICAgICAgewotICAgICAgICAgICAgbV9zdHJpbmdidWYuYXBwZW5kKHMpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBTZXJpYWxpemF0aW9uSGFuZGxlciNzZXRUcmFuc2Zvcm1lcihUcmFuc2Zvcm1lcikKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRUcmFuc2Zvcm1lcihUcmFuc2Zvcm1lciB0cmFuc2Zvcm1lcikgewotICAgICAgICBzdXBlci5zZXRUcmFuc2Zvcm1lcih0cmFuc2Zvcm1lcik7Ci0gICAgICAgIGlmIChtX3RyYWNlciAhPSBudWxsCi0gICAgICAgICAmJiAhKG1fd3JpdGVyIGluc3RhbmNlb2YgU2VyaWFsaXplclRyYWNlV3JpdGVyKSAgKQotICAgICAgICAgICAgbV93cml0ZXIgPSBuZXcgU2VyaWFsaXplclRyYWNlV3JpdGVyKG1fd3JpdGVyLCBtX3RyYWNlcik7Ci0KLQotICAgIH0KLSAgICAvKioKLSAgICAgKiBUcnkncyB0byByZXNldCB0aGUgc3VwZXIgY2xhc3MgYW5kIHJlc2V0IHRoaXMgY2xhc3MgZm9yCi0gICAgICogcmUtdXNlLCBzbyB0aGF0IHlvdSBkb24ndCBuZWVkIHRvIGNyZWF0ZSBhIG5ldyBzZXJpYWxpemVyCi0gICAgICogKG1vc3RseSBmb3IgcGVyZm9ybWFuY2UgcmVhc29ucykuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGNsYXNzIHdhcyBzdWNjZXNzZnVseSByZXNldC4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiByZXNldCgpCi0gICAgewotICAgICAgICBib29sZWFuIHdhc1Jlc2V0ID0gZmFsc2U7Ci0gICAgICAgIGlmIChzdXBlci5yZXNldCgpKQotICAgICAgICB7Ci0gICAgICAgICAgICByZXNldFRvU3RyZWFtKCk7Ci0gICAgICAgICAgICB3YXNSZXNldCA9IHRydWU7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHdhc1Jlc2V0OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJlc2V0IGFsbCBvZiB0aGUgZmllbGRzIG93bmVkIGJ5IFRvU3RyZWFtIGNsYXNzCi0gICAgICoKLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgcmVzZXRUb1N0cmVhbSgpCi0gICAgewotICAgICAgICAgdGhpcy5tX2NkYXRhU3RhcnRDYWxsZWQgPSBmYWxzZTsKLSAgICAgICAgIC8qIFRoZSBzdHJlYW0gaXMgYmVpbmcgcmVzZXQuIEl0IGlzIG9uZSBvZgotICAgICAgICAgICogVG9YTUxTdHJlYW0sIFRvSFRNTFN0cmVhbSAuLi4gYW5kIHRoaXMgdHlwZSBjYW4ndCBiZSBjaGFuZ2VkCi0gICAgICAgICAgKiBzbyBuZWl0aGVyIHNob3VsZCBtX2NoYXJJbmZvIHdoaWNoIGlzIGFzc29jaWF0ZWQgd2l0aCB0aGUKLSAgICAgICAgICAqIHR5cGUgb2YgU3RyZWFtLiBKdXN0IGxlYXZlIG1fY2hhckluZm8gYXMtaXMgZm9yIHRoZSBuZXh0IHJlLXVzZS4KLSAgICAgICAgICAqCi0gICAgICAgICAgKi8KLSAgICAgICAgIC8vIHRoaXMubV9jaGFySW5mbyA9IG51bGw7IC8vIGRvbid0IHNldCB0byBudWxsCi0KLSAgICAgICAgIHRoaXMubV9kaXNhYmxlT3V0cHV0RXNjYXBpbmdTdGF0ZXMuY2xlYXIoKTsKLQotICAgICAgICAgdGhpcy5tX2VzY2FwaW5nID0gdHJ1ZTsKLSAgICAgICAgIC8vIExlYXZlIG1fZm9ybWF0IGFsb25lIGZvciBub3cgLSBCcmlhbiBNLgotICAgICAgICAgLy8gdGhpcy5tX2Zvcm1hdCA9IG51bGw7Ci0gICAgICAgICB0aGlzLm1faW5Eb2N0eXBlID0gZmFsc2U7Ci0gICAgICAgICB0aGlzLm1faXNwcmVzZXJ2ZSA9IGZhbHNlOwotICAgICAgICAgdGhpcy5tX2lzcHJlc2VydmUgPSBmYWxzZTsKLSAgICAgICAgIHRoaXMubV9pc3ByZXZ0ZXh0ID0gZmFsc2U7Ci0gICAgICAgICB0aGlzLm1faXNVVEY4ID0gZmFsc2U7IC8vICA/PyB1c2VkIGFueXdoZXJlID8/Ci0gICAgICAgICB0aGlzLm1fcHJlc2VydmVzLmNsZWFyKCk7Ci0gICAgICAgICB0aGlzLm1fc2hvdWxkRmx1c2ggPSB0cnVlOwotICAgICAgICAgdGhpcy5tX3NwYWNlQmVmb3JlQ2xvc2UgPSBmYWxzZTsKLSAgICAgICAgIHRoaXMubV9zdGFydE5ld0xpbmUgPSBmYWxzZTsKLSAgICAgICAgIHRoaXMubV9saW5lU2VwVXNlID0gdHJ1ZTsKLSAgICAgICAgIC8vIERPTidUIFNFVCBUSEUgV1JJVEVSIFRPIE5VTEwsIElUIE1BWSBCRSBSRVVTRUQgISEKLSAgICAgICAgIC8vIHRoaXMubV93cml0ZXIgPSBudWxsOwotICAgICAgICAgdGhpcy5tX2V4cGFuZERUREVudGl0aWVzID0gdHJ1ZTsKLQotICAgIH0KLQotICAgIC8qKgotICAgICAgKiBTZXRzIHRoZSBjaGFyYWN0ZXIgZW5jb2RpbmcgY29taW5nIGZyb20gdGhlIHhzbDpvdXRwdXQgZW5jb2Rpbmcgc3R5bGVzaGVldCBhdHRyaWJ1dGUuCi0gICAgICAqIEBwYXJhbSBlbmNvZGluZyB0aGUgY2hhcmFjdGVyIGVuY29kaW5nCi0gICAgICAqLwotICAgICBwdWJsaWMgdm9pZCBzZXRFbmNvZGluZyhTdHJpbmcgZW5jb2RpbmcpCi0gICAgIHsKLSAgICAgICAgIFN0cmluZyBvbGQgPSBnZXRFbmNvZGluZygpOwotICAgICAgICAgc3VwZXIuc2V0RW5jb2RpbmcoZW5jb2RpbmcpOwotICAgICAgICAgaWYgKG9sZCA9PSBudWxsIHx8ICFvbGQuZXF1YWxzKGVuY29kaW5nKSkgewotICAgICAgICAgICAgLy8gSWYgd2UgaGF2ZSBjaGFuZ2VkIHRoZSBzZXR0aW5nIG9mIHRoZQotICAgICAgICAgICAgbV9lbmNvZGluZ0luZm8gPSBFbmNvZGluZ3MuZ2V0RW5jb2RpbmdJbmZvKGVuY29kaW5nKTsKLQotICAgICAgICAgICAgaWYgKGVuY29kaW5nICE9IG51bGwgJiYgbV9lbmNvZGluZ0luZm8ubmFtZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgLy8gV2UgdHJpZWQgdG8gZ2V0IGFuIEVuY29kaW5nSW5mbyBmb3IgT2JqZWN0IGZvciB0aGUgZ2l2ZW4KLSAgICAgICAgICAgICAgICAvLyBlbmNvZGluZywgYnV0IGl0IGNhbWUgYmFjayB3aXRoIGFuIGludGVybmFsbCBudWxsIG5hbWUKLSAgICAgICAgICAgICAgICAvLyBzbyB0aGUgZW5jb2RpbmcgaXMgbm90IHN1cHBvcnRlZCBieSB0aGUgSkRLLCBpc3N1ZSBhIG1lc3NhZ2UuCi0gICAgICAgICAgICAgICAgU3RyaW5nIG1zZyA9IFV0aWxzLm1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1zZ0tleS5FUl9FTkNPRElOR19OT1RfU1VQUE9SVEVELG5ldyBPYmplY3RbXXsgZW5jb2RpbmcgfSk7Ci0gICAgICAgICAgICAgICAgdHJ5Ci0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gUHJlcGFyZSB0byBpc3N1ZSB0aGUgd2FybmluZyBtZXNzYWdlCi0gICAgICAgICAgICAgICAgICAgICAgICBUcmFuc2Zvcm1lciB0cmFuID0gc3VwZXIuZ2V0VHJhbnNmb3JtZXIoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0cmFuICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRXJyb3JMaXN0ZW5lciBlcnJIYW5kbGVyID0gdHJhbi5nZXRFcnJvckxpc3RlbmVyKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIElzc3VlIHRoZSB3YXJuaW5nIG1lc3NhZ2UKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG51bGwgIT0gZXJySGFuZGxlciAmJiBtX3NvdXJjZUxvY2F0b3IgIT0gbnVsbCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJIYW5kbGVyLndhcm5pbmcobmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKG1zZywgbV9zb3VyY2VMb2NhdG9yKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4obXNnKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4obXNnKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKXt9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICB9Ci0gICAgICAgICByZXR1cm47Ci0gICAgIH0KLQotICAgIC8qKgotICAgICAqIFNpbXBsZSBzdGFjayBmb3IgYm9vbGVhbiB2YWx1ZXMuCi0gICAgICoKLSAgICAgKiBUaGlzIGNsYXNzIGlzIGEgY29weSBvZiB0aGUgb25lIGluIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuCi0gICAgICogSXQgZXhpc3RzIHRvIGN1dCB0aGUgc2VyaWFsaXplcnMgZGVwZW5kYW5jeSBvbiB0aGF0IHBhY2thZ2UuCi0gICAgICogQSBtaW5vciBjaGFuZ2VzIGZyb20gdGhhdCBwYWNrYWdlIGFyZToKLSAgICAgKiBkb2Vzbid0IGltcGxlbWVudCBDbG9uYWJsZQotICAgICAqCi0gICAgICogQHhzbC51c2FnZSBpbnRlcm5hbAotICAgICAqLwotICAgIHN0YXRpYyBmaW5hbCBjbGFzcyBCb29sU3RhY2sKLSAgICB7Ci0KLSAgICAgIC8qKiBBcnJheSBvZiBib29sZWFuIHZhbHVlcyAgICAgICAgICAqLwotICAgICAgcHJpdmF0ZSBib29sZWFuIG1fdmFsdWVzW107Ci0KLSAgICAgIC8qKiBBcnJheSBzaXplIGFsbG9jYXRlZCAgICAgICAgICAgKi8KLSAgICAgIHByaXZhdGUgaW50IG1fYWxsb2NhdGVkU2l6ZTsKLQotICAgICAgLyoqIEluZGV4IGludG8gdGhlIGFycmF5IG9mIGJvb2xlYW5zICAgICAgICAgICovCi0gICAgICBwcml2YXRlIGludCBtX2luZGV4OwotCi0gICAgICAvKioKLSAgICAgICAqIERlZmF1bHQgY29uc3RydWN0b3IuICBOb3RlIHRoYXQgdGhlIGRlZmF1bHQKLSAgICAgICAqIGJsb2NrIHNpemUgaXMgdmVyeSBzbWFsbCwgZm9yIHNtYWxsIGxpc3RzLgotICAgICAgICovCi0gICAgICBwdWJsaWMgQm9vbFN0YWNrKCkKLSAgICAgIHsKLSAgICAgICAgdGhpcygzMik7Ci0gICAgICB9Ci0KLSAgICAgIC8qKgotICAgICAgICogQ29uc3RydWN0IGEgSW50VmVjdG9yLCB1c2luZyB0aGUgZ2l2ZW4gYmxvY2sgc2l6ZS4KLSAgICAgICAqCi0gICAgICAgKiBAcGFyYW0gc2l6ZSBhcnJheSBzaXplIHRvIGFsbG9jYXRlCi0gICAgICAgKi8KLSAgICAgIHB1YmxpYyBCb29sU3RhY2soaW50IHNpemUpCi0gICAgICB7Ci0KLSAgICAgICAgbV9hbGxvY2F0ZWRTaXplID0gc2l6ZTsKLSAgICAgICAgbV92YWx1ZXMgPSBuZXcgYm9vbGVhbltzaXplXTsKLSAgICAgICAgbV9pbmRleCA9IC0xOwotICAgICAgfQotCi0gICAgICAvKioKLSAgICAgICAqIEdldCB0aGUgbGVuZ3RoIG9mIHRoZSBsaXN0LgotICAgICAgICoKLSAgICAgICAqIEByZXR1cm4gQ3VycmVudCBsZW5ndGggb2YgdGhlIGxpc3QKLSAgICAgICAqLwotICAgICAgcHVibGljIGZpbmFsIGludCBzaXplKCkKLSAgICAgIHsKLSAgICAgICAgcmV0dXJuIG1faW5kZXggKyAxOwotICAgICAgfQotCi0gICAgICAvKioKLSAgICAgICAqIENsZWFycyB0aGUgc3RhY2suCi0gICAgICAgKgotICAgICAgICovCi0gICAgICBwdWJsaWMgZmluYWwgdm9pZCBjbGVhcigpCi0gICAgICB7Ci0gICAgICAgIG1faW5kZXggPSAtMTsKLSAgICAgIH0KLQotICAgICAgLyoqCi0gICAgICAgKiBQdXNoZXMgYW4gaXRlbSBvbnRvIHRoZSB0b3Agb2YgdGhpcyBzdGFjay4KLSAgICAgICAqCi0gICAgICAgKgotICAgICAgICogQHBhcmFtIHZhbCB0aGUgYm9vbGVhbiB0byBiZSBwdXNoZWQgb250byB0aGlzIHN0YWNrLgotICAgICAgICogQHJldHVybiAgdGhlIDxjb2RlPml0ZW08L2NvZGU+IGFyZ3VtZW50LgotICAgICAgICovCi0gICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBwdXNoKGJvb2xlYW4gdmFsKQotICAgICAgewotCi0gICAgICAgIGlmIChtX2luZGV4ID09IG1fYWxsb2NhdGVkU2l6ZSAtIDEpCi0gICAgICAgICAgZ3JvdygpOwotCi0gICAgICAgIHJldHVybiAobV92YWx1ZXNbKyttX2luZGV4XSA9IHZhbCk7Ci0gICAgICB9Ci0KLSAgICAgIC8qKgotICAgICAgICogUmVtb3ZlcyB0aGUgb2JqZWN0IGF0IHRoZSB0b3Agb2YgdGhpcyBzdGFjayBhbmQgcmV0dXJucyB0aGF0Ci0gICAgICAgKiBvYmplY3QgYXMgdGhlIHZhbHVlIG9mIHRoaXMgZnVuY3Rpb24uCi0gICAgICAgKgotICAgICAgICogQHJldHVybiAgICAgVGhlIG9iamVjdCBhdCB0aGUgdG9wIG9mIHRoaXMgc3RhY2suCi0gICAgICAgKiBAdGhyb3dzICBFbXB0eVN0YWNrRXhjZXB0aW9uICBpZiB0aGlzIHN0YWNrIGlzIGVtcHR5LgotICAgICAgICovCi0gICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBwb3AoKQotICAgICAgewotICAgICAgICByZXR1cm4gbV92YWx1ZXNbbV9pbmRleC0tXTsKLSAgICAgIH0KLQotICAgICAgLyoqCi0gICAgICAgKiBSZW1vdmVzIHRoZSBvYmplY3QgYXQgdGhlIHRvcCBvZiB0aGlzIHN0YWNrIGFuZCByZXR1cm5zIHRoZQotICAgICAgICogbmV4dCBvYmplY3QgYXQgdGhlIHRvcCBhcyB0aGUgdmFsdWUgb2YgdGhpcyBmdW5jdGlvbi4KLSAgICAgICAqCi0gICAgICAgKgotICAgICAgICogQHJldHVybiBOZXh0IG9iamVjdCB0byB0aGUgdG9wIG9yIGZhbHNlIGlmIG5vbmUgdGhlcmUKLSAgICAgICAqLwotICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gcG9wQW5kVG9wKCkKLSAgICAgIHsKLQotICAgICAgICBtX2luZGV4LS07Ci0KLSAgICAgICAgcmV0dXJuIChtX2luZGV4ID49IDApID8gbV92YWx1ZXNbbV9pbmRleF0gOiBmYWxzZTsKLSAgICAgIH0KLQotICAgICAgLyoqCi0gICAgICAgKiBTZXQgdGhlIGl0ZW0gYXQgdGhlIHRvcCBvZiB0aGlzIHN0YWNrCi0gICAgICAgKgotICAgICAgICoKLSAgICAgICAqIEBwYXJhbSBiIE9iamVjdCB0byBzZXQgYXQgdGhlIHRvcCBvZiB0aGlzIHN0YWNrCi0gICAgICAgKi8KLSAgICAgIHB1YmxpYyBmaW5hbCB2b2lkIHNldFRvcChib29sZWFuIGIpCi0gICAgICB7Ci0gICAgICAgIG1fdmFsdWVzW21faW5kZXhdID0gYjsKLSAgICAgIH0KLQotICAgICAgLyoqCi0gICAgICAgKiBMb29rcyBhdCB0aGUgb2JqZWN0IGF0IHRoZSB0b3Agb2YgdGhpcyBzdGFjayB3aXRob3V0IHJlbW92aW5nIGl0Ci0gICAgICAgKiBmcm9tIHRoZSBzdGFjay4KLSAgICAgICAqCi0gICAgICAgKiBAcmV0dXJuICAgICB0aGUgb2JqZWN0IGF0IHRoZSB0b3Agb2YgdGhpcyBzdGFjay4KLSAgICAgICAqIEB0aHJvd3MgIEVtcHR5U3RhY2tFeGNlcHRpb24gIGlmIHRoaXMgc3RhY2sgaXMgZW1wdHkuCi0gICAgICAgKi8KLSAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIHBlZWsoKQotICAgICAgewotICAgICAgICByZXR1cm4gbV92YWx1ZXNbbV9pbmRleF07Ci0gICAgICB9Ci0KLSAgICAgIC8qKgotICAgICAgICogTG9va3MgYXQgdGhlIG9iamVjdCBhdCB0aGUgdG9wIG9mIHRoaXMgc3RhY2sgd2l0aG91dCByZW1vdmluZyBpdAotICAgICAgICogZnJvbSB0aGUgc3RhY2suICBJZiB0aGUgc3RhY2sgaXMgZW1wdHksIGl0IHJldHVybnMgZmFsc2UuCi0gICAgICAgKgotICAgICAgICogQHJldHVybiAgICAgdGhlIG9iamVjdCBhdCB0aGUgdG9wIG9mIHRoaXMgc3RhY2suCi0gICAgICAgKi8KLSAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIHBlZWtPckZhbHNlKCkKLSAgICAgIHsKLSAgICAgICAgcmV0dXJuIChtX2luZGV4ID4gLTEpID8gbV92YWx1ZXNbbV9pbmRleF0gOiBmYWxzZTsKLSAgICAgIH0KLQotICAgICAgLyoqCi0gICAgICAgKiBMb29rcyBhdCB0aGUgb2JqZWN0IGF0IHRoZSB0b3Agb2YgdGhpcyBzdGFjayB3aXRob3V0IHJlbW92aW5nIGl0Ci0gICAgICAgKiBmcm9tIHRoZSBzdGFjay4gIElmIHRoZSBzdGFjayBpcyBlbXB0eSwgaXQgcmV0dXJucyB0cnVlLgotICAgICAgICoKLSAgICAgICAqIEByZXR1cm4gICAgIHRoZSBvYmplY3QgYXQgdGhlIHRvcCBvZiB0aGlzIHN0YWNrLgotICAgICAgICovCi0gICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBwZWVrT3JUcnVlKCkKLSAgICAgIHsKLSAgICAgICAgcmV0dXJuIChtX2luZGV4ID4gLTEpID8gbV92YWx1ZXNbbV9pbmRleF0gOiB0cnVlOwotICAgICAgfQotCi0gICAgICAvKioKLSAgICAgICAqIFRlc3RzIGlmIHRoaXMgc3RhY2sgaXMgZW1wdHkuCi0gICAgICAgKgotICAgICAgICogQHJldHVybiAgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhpcyBzdGFjayBpcyBlbXB0eTsKLSAgICAgICAqICAgICAgICAgIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuCi0gICAgICAgKi8KLSAgICAgIHB1YmxpYyBib29sZWFuIGlzRW1wdHkoKQotICAgICAgewotICAgICAgICByZXR1cm4gKG1faW5kZXggPT0gLTEpOwotICAgICAgfQotCi0gICAgICAvKioKLSAgICAgICAqIEdyb3dzIHRoZSBzaXplIG9mIHRoZSBzdGFjawotICAgICAgICoKLSAgICAgICAqLwotICAgICAgcHJpdmF0ZSB2b2lkIGdyb3coKQotICAgICAgewotCi0gICAgICAgIG1fYWxsb2NhdGVkU2l6ZSAqPSAyOwotCi0gICAgICAgIGJvb2xlYW4gbmV3VmVjdG9yW10gPSBuZXcgYm9vbGVhblttX2FsbG9jYXRlZFNpemVdOwotCi0gICAgICAgIFN5c3RlbS5hcnJheWNvcHkobV92YWx1ZXMsIDAsIG5ld1ZlY3RvciwgMCwgbV9pbmRleCArIDEpOwotCi0gICAgICAgIG1fdmFsdWVzID0gbmV3VmVjdG9yOwotICAgICAgfQotICAgIH0KLQotICAgIC8vIEltcGxlbWVudCBEVERIYW5kbGVyCi0gICAgLyoqCi0gICAgICogSWYgdGhpcyBtZXRob2QgaXMgY2FsbGVkLCB0aGUgc2VyaWFsaXplciBpcyB1c2VkIGFzIGEKLSAgICAgKiBEVERIYW5kbGVyLCB3aGljaCBjaGFuZ2VzIGJlaGF2aW9yIGhvdyB0aGUgc2VyaWFsaXplcgotICAgICAqIGhhbmRsZXMgZG9jdW1lbnQgZW50aXRpZXMuCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5EVERIYW5kbGVyI25vdGF0aW9uRGVjbChqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIG5vdGF0aW9uRGVjbChTdHJpbmcgbmFtZSwgU3RyaW5nIHB1YklELCBTdHJpbmcgc3lzSUQpIHRocm93cyBTQVhFeGNlcHRpb24gewotICAgICAgICAvLyBUT0RPIEF1dG8tZ2VuZXJhdGVkIG1ldGhvZCBzdHViCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBEVERwcm9sb2coKTsKLQotICAgICAgICAgICAgbV93cml0ZXIud3JpdGUoIjwhTk9UQVRJT04gIik7Ci0gICAgICAgICAgICBtX3dyaXRlci53cml0ZShuYW1lKTsKLSAgICAgICAgICAgIGlmIChwdWJJRCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgbV93cml0ZXIud3JpdGUoIiBQVUJMSUMgXCIiKTsKLSAgICAgICAgICAgICAgICBtX3dyaXRlci53cml0ZShwdWJJRCk7Ci0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIG1fd3JpdGVyLndyaXRlKCIgU1lTVEVNIFwiIik7Ci0gICAgICAgICAgICAgICAgbV93cml0ZXIud3JpdGUoc3lzSUQpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgbV93cml0ZXIud3JpdGUoIlwiID4iKTsKLSAgICAgICAgICAgIG1fd3JpdGVyLndyaXRlKG1fbGluZVNlcCwgMCwgbV9saW5lU2VwTGVuKTsKLSAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewotICAgICAgICAgICAgLy8gVE9ETyBBdXRvLWdlbmVyYXRlZCBjYXRjaCBibG9jawotICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIElmIHRoaXMgbWV0aG9kIGlzIGNhbGxlZCwgdGhlIHNlcmlhbGl6ZXIgaXMgdXNlZCBhcyBhCi0gICAgICogRFRESGFuZGxlciwgd2hpY2ggY2hhbmdlcyBiZWhhdmlvciBob3cgdGhlIHNlcmlhbGl6ZXIKLSAgICAgKiBoYW5kbGVzIGRvY3VtZW50IGVudGl0aWVzLgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguRFRESGFuZGxlciN1bnBhcnNlZEVudGl0eURlY2woamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZykKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB1bnBhcnNlZEVudGl0eURlY2woU3RyaW5nIG5hbWUsIFN0cmluZyBwdWJJRCwgU3RyaW5nIHN5c0lELCBTdHJpbmcgbm90YXRpb25OYW1lKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICAgICAgLy8gVE9ETyBBdXRvLWdlbmVyYXRlZCBtZXRob2Qgc3R1YgotICAgICAgICB0cnkgewotICAgICAgICAgICAgRFREcHJvbG9nKCk7Ci0KLSAgICAgICAgICAgIG1fd3JpdGVyLndyaXRlKCI8IUVOVElUWSAiKTsKLSAgICAgICAgICAgIG1fd3JpdGVyLndyaXRlKG5hbWUpOwotICAgICAgICAgICAgaWYgKHB1YklEICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBtX3dyaXRlci53cml0ZSgiIFBVQkxJQyBcIiIpOwotICAgICAgICAgICAgICAgIG1fd3JpdGVyLndyaXRlKHB1YklEKTsKLQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgbV93cml0ZXIud3JpdGUoIiBTWVNURU0gXCIiKTsKLSAgICAgICAgICAgICAgICBtX3dyaXRlci53cml0ZShzeXNJRCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBtX3dyaXRlci53cml0ZSgiXCIgTkRBVEEgIik7Ci0gICAgICAgICAgICBtX3dyaXRlci53cml0ZShub3RhdGlvbk5hbWUpOwotICAgICAgICAgICAgbV93cml0ZXIud3JpdGUoIiA+Iik7Ci0gICAgICAgICAgICBtX3dyaXRlci53cml0ZShtX2xpbmVTZXAsIDAsIG1fbGluZVNlcExlbik7Ci0gICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIC8vIFRPRE8gQXV0by1nZW5lcmF0ZWQgY2F0Y2ggYmxvY2sKLSAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBIHByaXZhdGUgaGVscGVyIG1ldGhvZCB0byBvdXRwdXQgdGhlCi0gICAgICogQHRocm93cyBTQVhFeGNlcHRpb24KLSAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0gICAgICovCi0gICAgcHJpdmF0ZSB2b2lkIERURHByb2xvZygpIHRocm93cyBTQVhFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKLSAgICAgICAgZmluYWwgamF2YS5pby5Xcml0ZXIgd3JpdGVyID0gbV93cml0ZXI7Ci0gICAgICAgIGlmIChtX25lZWRUb091dHB1dERvY1R5cGVEZWNsKQotICAgICAgICB7Ci0gICAgICAgICAgICBvdXRwdXREb2NUeXBlRGVjbChtX2VsZW1Db250ZXh0Lm1fZWxlbWVudE5hbWUsIGZhbHNlKTsKLSAgICAgICAgICAgIG1fbmVlZFRvT3V0cHV0RG9jVHlwZURlY2wgPSBmYWxzZTsKLSAgICAgICAgfQotICAgICAgICBpZiAobV9pbkRvY3R5cGUpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHdyaXRlci53cml0ZSgiIFsiKTsKLSAgICAgICAgICAgIHdyaXRlci53cml0ZShtX2xpbmVTZXAsIDAsIG1fbGluZVNlcExlbik7Ci0gICAgICAgICAgICBtX2luRG9jdHlwZSA9IGZhbHNlOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSWYgc2V0IHRvIGZhbHNlIHRoZSBzZXJpYWxpemVyIGRvZXMgbm90IGV4cGFuZCBEVEQgZW50aXRpZXMsCi0gICAgICogYnV0IGxlYXZlcyB0aGVtIGFzIGlzLCB0aGUgZGVmYXVsdCB2YWx1ZSBpcyB0cnVlOwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldERUREVudGl0eUV4cGFuc2lvbihib29sZWFuIGV4cGFuZCkgewotICAgICAgICBtX2V4cGFuZERUREVudGl0aWVzID0gZXhwYW5kOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvVG9UZXh0U0FYSGFuZGxlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9Ub1RleHRTQVhIYW5kbGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGY3NmM1NTIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9Ub1RleHRTQVhIYW5kbGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0MTQgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogVG9UZXh0U0FYSGFuZGxlci5qYXZhLHYgMS4zIDIwMDUvMDkvMjggMTM6NDk6MDggcHZlZHVsYSBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplcjsKLQotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci1pbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5pby5Xcml0ZXI7Ci1pbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotaW1wb3J0IG9yZy54bWwuc2F4LkF0dHJpYnV0ZXM7Ci1pbXBvcnQgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguTG9jYXRvcjsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguZXh0LkxleGljYWxIYW5kbGVyOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgY29udmVydHMgU0FYLWxpa2UgZXZlbnQgdG8gU0FYIGV2ZW50cyBmb3IKLSAqIHhzbDpvdXRwdXQgbWV0aG9kICJ0ZXh0Ii4KLSAqCi0gKiBUaGlzIGNsYXNzIGlzIG9ubHkgdG8gYmUgdXNlZCBpbnRlcm5hbGx5LiBUaGlzIGNsYXNzIGlzIG5vdCBhIHB1YmxpYyBBUEkuCi0gKgotICogQHhzbC51c2FnZSBpbnRlcm5hbAotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgVG9UZXh0U0FYSGFuZGxlciBleHRlbmRzIFRvU0FYSGFuZGxlcgotewotICAgIC8qKgotICAgICAqIEZyb20gWFNMVEMKLSAgICAgKiBAc2VlIEV4dGVuZGVkQ29udGVudEhhbmRsZXIjZW5kRWxlbWVudChTdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kRWxlbWVudChTdHJpbmcgZWxlbU5hbWUpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGlmIChtX3RyYWNlciAhPSBudWxsKQotICAgICAgICAgICAgc3VwZXIuZmlyZUVuZEVsZW0oZWxlbU5hbWUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjZW5kRWxlbWVudChTdHJpbmcsIFN0cmluZywgU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZEVsZW1lbnQoU3RyaW5nIGFyZzAsIFN0cmluZyBhcmcxLCBTdHJpbmcgYXJnMikKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgICAgICAgICBpZiAobV90cmFjZXIgIT0gbnVsbCkKLSAgICAgICAgICAgIHN1cGVyLmZpcmVFbmRFbGVtKGFyZzIpOwotICAgIH0KLQotICAgIHB1YmxpYyBUb1RleHRTQVhIYW5kbGVyKENvbnRlbnRIYW5kbGVyIGhkbHIsIExleGljYWxIYW5kbGVyIGxleCwgU3RyaW5nIGVuY29kaW5nKQotICAgIHsKLSAgICAgICAgc3VwZXIoaGRsciwgbGV4LCBlbmNvZGluZyk7Ci0gICAgfQotCi0gICAgICAgIC8qKgotICAgICAqIEZyb20gWFNMVEMKLSAgICAgKi8KLSAgICBwdWJsaWMgVG9UZXh0U0FYSGFuZGxlcihDb250ZW50SGFuZGxlciBoYW5kbGVyLCBTdHJpbmcgZW5jb2RpbmcpCi0gICAgewotICAgICAgICBzdXBlcihoYW5kbGVyLGVuY29kaW5nKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBjb21tZW50KGNoYXIgY2hbXSwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKQotICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAobV90cmFjZXIgIT0gbnVsbCkKLSAgICAgICAgICAgIHN1cGVyLmZpcmVDb21tZW50RXZlbnQoY2gsIHN0YXJ0LCBsZW5ndGgpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGNvbW1lbnQoU3RyaW5nIGRhdGEpIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGZpbmFsIGludCBsZW5ndGggPSBkYXRhLmxlbmd0aCgpOwotICAgICAgICBpZiAobGVuZ3RoID4gbV9jaGFyc0J1ZmYubGVuZ3RoKQotICAgICAgICB7Ci0gICAgICAgICAgICBtX2NoYXJzQnVmZiA9IG5ldyBjaGFyW2xlbmd0aCoyICsgMV07Ci0gICAgICAgIH0KLSAgICAgICAgZGF0YS5nZXRDaGFycygwLCBsZW5ndGgsIG1fY2hhcnNCdWZmLCAwKTsKLSAgICAgICAgY29tbWVudChtX2NoYXJzQnVmZiwgMCwgbGVuZ3RoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAc2VlIFNlcmlhbGl6ZXIjZ2V0T3V0cHV0Rm9ybWF0KCkKLSAgICAgKi8KLSAgICBwdWJsaWMgUHJvcGVydGllcyBnZXRPdXRwdXRGb3JtYXQoKQotICAgIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBTZXJpYWxpemVyI2dldE91dHB1dFN0cmVhbSgpCi0gICAgICovCi0gICAgcHVibGljIE91dHB1dFN0cmVhbSBnZXRPdXRwdXRTdHJlYW0oKQotICAgIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBTZXJpYWxpemVyI2dldFdyaXRlcigpCi0gICAgICovCi0gICAgcHVibGljIFdyaXRlciBnZXRXcml0ZXIoKQotICAgIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRG9lcyBub3RoaW5nIGJlY2F1c2UKLSAgICAgKiB0aGUgaW5kZW50IGF0dHJpYnV0ZSBpcyBpZ25vcmVkIGZvciB0ZXh0IG91dHB1dC4KLSAgICAgKgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGluZGVudChpbnQgbikgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAc2VlIFNlcmlhbGl6ZXIjcmVzZXQoKQotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIHJlc2V0KCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAc2VlIERPTVNlcmlhbGl6ZXIjc2VyaWFsaXplKE5vZGUpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2VyaWFsaXplKE5vZGUgbm9kZSkgdGhyb3dzIElPRXhjZXB0aW9uCi0gICAgewotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgU2VyaWFsaXphdGlvbkhhbmRsZXIjc2V0RXNjYXBpbmcoYm9vbGVhbikKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBzZXRFc2NhcGluZyhib29sZWFuIGVzY2FwZSkKLSAgICB7Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAc2VlIFNlcmlhbGl6YXRpb25IYW5kbGVyI3NldEluZGVudChib29sZWFuKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEluZGVudChib29sZWFuIGluZGVudCkKLSAgICB7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBTZXJpYWxpemVyI3NldE91dHB1dEZvcm1hdChQcm9wZXJ0aWVzKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldE91dHB1dEZvcm1hdChQcm9wZXJ0aWVzIGZvcm1hdCkKLSAgICB7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBTZXJpYWxpemVyI3NldE91dHB1dFN0cmVhbShPdXRwdXRTdHJlYW0pCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0T3V0cHV0U3RyZWFtKE91dHB1dFN0cmVhbSBvdXRwdXQpCi0gICAgewotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgU2VyaWFsaXplciNzZXRXcml0ZXIoV3JpdGVyKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFdyaXRlcihXcml0ZXIgd3JpdGVyKQotICAgIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAc2VlIEV4dGVuZGVkQ29udGVudEhhbmRsZXIjYWRkQXR0cmlidXRlKFN0cmluZywgU3RyaW5nLCBTdHJpbmcsIFN0cmluZywgU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGFkZEF0dHJpYnV0ZSgKLSAgICAgICAgU3RyaW5nIHVyaSwKLSAgICAgICAgU3RyaW5nIGxvY2FsTmFtZSwKLSAgICAgICAgU3RyaW5nIHJhd05hbWUsCi0gICAgICAgIFN0cmluZyB0eXBlLAotICAgICAgICBTdHJpbmcgdmFsdWUsCi0gICAgICAgIGJvb2xlYW4gWFNMQXR0cmlidXRlKQotICAgIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LmV4dC5EZWNsSGFuZGxlciNhdHRyaWJ1dGVEZWNsKFN0cmluZywgU3RyaW5nLCBTdHJpbmcsIFN0cmluZywgU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGF0dHJpYnV0ZURlY2woCi0gICAgICAgIFN0cmluZyBhcmcwLAotICAgICAgICBTdHJpbmcgYXJnMSwKLSAgICAgICAgU3RyaW5nIGFyZzIsCi0gICAgICAgIFN0cmluZyBhcmczLAotICAgICAgICBTdHJpbmcgYXJnNCkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LmV4dC5EZWNsSGFuZGxlciNlbGVtZW50RGVjbChTdHJpbmcsIFN0cmluZykKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbGVtZW50RGVjbChTdHJpbmcgYXJnMCwgU3RyaW5nIGFyZzEpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5leHQuRGVjbEhhbmRsZXIjZXh0ZXJuYWxFbnRpdHlEZWNsKFN0cmluZywgU3RyaW5nLCBTdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZXh0ZXJuYWxFbnRpdHlEZWNsKFN0cmluZyBhcmcwLCBTdHJpbmcgYXJnMSwgU3RyaW5nIGFyZzIpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5leHQuRGVjbEhhbmRsZXIjaW50ZXJuYWxFbnRpdHlEZWNsKFN0cmluZywgU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGludGVybmFsRW50aXR5RGVjbChTdHJpbmcgYXJnMCwgU3RyaW5nIGFyZzEpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNlbmRQcmVmaXhNYXBwaW5nKFN0cmluZykKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbmRQcmVmaXhNYXBwaW5nKFN0cmluZyBhcmcwKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjaWdub3JhYmxlV2hpdGVzcGFjZShjaGFyW10sIGludCwgaW50KQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGlnbm9yYWJsZVdoaXRlc3BhY2UoY2hhcltdIGFyZzAsIGludCBhcmcxLCBpbnQgYXJnMikKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBGcm9tIFhTTFRDCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oU3RyaW5nLCBTdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcHJvY2Vzc2luZ0luc3RydWN0aW9uKFN0cmluZyBhcmcwLCBTdHJpbmcgYXJnMSkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaWYgKG1fdHJhY2VyICE9IG51bGwpCi0gICAgICAgICAgICBzdXBlci5maXJlRXNjYXBpbmdFdmVudChhcmcwLCBhcmcxKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI3NldERvY3VtZW50TG9jYXRvcihMb2NhdG9yKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldERvY3VtZW50TG9jYXRvcihMb2NhdG9yIGFyZzApCi0gICAgewotICAgICAgICBzdXBlci5zZXREb2N1bWVudExvY2F0b3IoYXJnMCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNza2lwcGVkRW50aXR5KFN0cmluZykKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBza2lwcGVkRW50aXR5KFN0cmluZyBhcmcwKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjc3RhcnRFbGVtZW50KFN0cmluZywgU3RyaW5nLCBTdHJpbmcsIEF0dHJpYnV0ZXMpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnRFbGVtZW50KAotICAgICAgICBTdHJpbmcgYXJnMCwKLSAgICAgICAgU3RyaW5nIGFyZzEsCi0gICAgICAgIFN0cmluZyBhcmcyLAotICAgICAgICBBdHRyaWJ1dGVzIGFyZzMpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGZsdXNoUGVuZGluZygpOwotICAgICAgICBzdXBlci5zdGFydEVsZW1lbnQoYXJnMCwgYXJnMSwgYXJnMiwgYXJnMyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXIjZW5kQ0RBVEEoKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZENEQVRBKCkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LmV4dC5MZXhpY2FsSGFuZGxlciNlbmREVEQoKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZERURCgpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXIjc3RhcnRDREFUQSgpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnRDREFUQSgpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LmV4dC5MZXhpY2FsSGFuZGxlciNzdGFydEVudGl0eShTdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnRFbnRpdHkoU3RyaW5nIGFyZzApIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBGcm9tIFhTTFRDCi0gICAgICogQHNlZSBFeHRlbmRlZENvbnRlbnRIYW5kbGVyI3N0YXJ0RWxlbWVudChTdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnRFbGVtZW50KAotICAgIFN0cmluZyBlbGVtZW50TmFtZXNwYWNlVVJJLAotICAgIFN0cmluZyBlbGVtZW50TG9jYWxOYW1lLAotICAgIFN0cmluZyBlbGVtZW50TmFtZSkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgc3VwZXIuc3RhcnRFbGVtZW50KGVsZW1lbnROYW1lc3BhY2VVUkksIGVsZW1lbnRMb2NhbE5hbWUsIGVsZW1lbnROYW1lKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQoCi0gICAgU3RyaW5nIGVsZW1lbnROYW1lKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBzdXBlci5zdGFydEVsZW1lbnQoZWxlbWVudE5hbWUpOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogRnJvbSBYU0xUQwotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjZW5kRG9jdW1lbnQoKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZERvY3VtZW50KCkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgZmx1c2hQZW5kaW5nKCk7Ci0gICAgICAgIG1fc2F4SGFuZGxlci5lbmREb2N1bWVudCgpOwotCi0gICAgICAgIGlmIChtX3RyYWNlciAhPSBudWxsKQotICAgICAgICAgICAgc3VwZXIuZmlyZUVuZERvYygpOwotICAgIH0KLQotICAgIC8qKgotICAgICAgICAgKgotICAgICAqIEBzZWUgRXh0ZW5kZWRDb250ZW50SGFuZGxlciNjaGFyYWN0ZXJzKFN0cmluZykKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBjaGFyYWN0ZXJzKFN0cmluZyBjaGFyYWN0ZXJzKQotICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGZpbmFsIGludCBsZW5ndGggPSBjaGFyYWN0ZXJzLmxlbmd0aCgpOwotICAgICAgICBpZiAobGVuZ3RoID4gbV9jaGFyc0J1ZmYubGVuZ3RoKQotICAgICAgICB7Ci0gICAgICAgICAgICBtX2NoYXJzQnVmZiA9IG5ldyBjaGFyW2xlbmd0aCoyICsgMV07Ci0gICAgICAgIH0KLSAgICAgICAgY2hhcmFjdGVycy5nZXRDaGFycygwLCBsZW5ndGgsIG1fY2hhcnNCdWZmLCAwKTsKLQotICAgICAgICBtX3NheEhhbmRsZXIuY2hhcmFjdGVycyhtX2NoYXJzQnVmZiwgMCwgbGVuZ3RoKTsKLQotICAgIH0KLSAgICAvKioKLSAgICAgICAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNjaGFyYWN0ZXJzKGNoYXJbXSwgaW50LCBpbnQpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY2hhcmFjdGVycyhjaGFyW10gY2hhcmFjdGVycywgaW50IG9mZnNldCwgaW50IGxlbmd0aCkKLSAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotCi0gICAgICAgIG1fc2F4SGFuZGxlci5jaGFyYWN0ZXJzKGNoYXJhY3RlcnMsIG9mZnNldCwgbGVuZ3RoKTsKLQotICAgICAgICAvLyB0aW1lIHRvIGZpcmUgb2ZmIGNoYXJhY3RlcnMgZXZlbnQKLSAgICAgICAgICAgICAgICBpZiAobV90cmFjZXIgIT0gbnVsbCkKLSAgICAgICAgICAgIHN1cGVyLmZpcmVDaGFyRXZlbnQoY2hhcmFjdGVycywgb2Zmc2V0LCBsZW5ndGgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEZyb20gWFNMVEMKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBhZGRBdHRyaWJ1dGUoU3RyaW5nIG5hbWUsIFN0cmluZyB2YWx1ZSkKLSAgICB7Ci0gICAgICAgIC8vIGRvIG5vdGhpbmcKLSAgICB9Ci0KLQotICAgIHB1YmxpYyBib29sZWFuIHN0YXJ0UHJlZml4TWFwcGluZygKLSAgICAgICAgU3RyaW5nIHByZWZpeCwKLSAgICAgICAgU3RyaW5nIHVyaSwKLSAgICAgICAgYm9vbGVhbiBzaG91bGRGbHVzaCkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgLy8gbm8gbmFtZXNwYWNlIHN1cHBvcnQgZm9yIEhUTUwKLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotCi0gICAgcHVibGljIHZvaWQgc3RhcnRQcmVmaXhNYXBwaW5nKFN0cmluZyBwcmVmaXgsIFN0cmluZyB1cmkpCi0gICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIC8vIG5vIG5hbWVzcGFjZSBzdXBwb3J0IGZvciBIVE1MCi0gICAgfQotCi0KLSAgICBwdWJsaWMgdm9pZCBuYW1lc3BhY2VBZnRlclN0YXJ0RWxlbWVudCgKLSAgICAgICAgZmluYWwgU3RyaW5nIHByZWZpeCwKLSAgICAgICAgZmluYWwgU3RyaW5nIHVyaSkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgLy8gbm8gbmFtZXNwYWNlIHN1cHBvcnQgZm9yIEhUTUwKLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvVG9UZXh0U3RyZWFtLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1RvVGV4dFN0cmVhbS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA5ZTM5Yjg5Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvVG9UZXh0U3RyZWFtLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw2MzYgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogVG9UZXh0U3RyZWFtLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMjEgMTA6MzU6MzQgcHZlZHVsYSBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplcjsKLQotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXIudXRpbHMuTXNnS2V5OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplci51dGlscy5VdGlsczsKLWltcG9ydCBvcmcueG1sLnNheC5BdHRyaWJ1dGVzOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGlzIG5vdCBhIHB1YmxpYyBBUEkuCi0gKiBJdCBpcyBvbmx5IHB1YmxpYyBiZWNhdXNlIGl0IGlzIHVzZWQgaW4gb3RoZXIgcGFja2FnZXMuCi0gKiBUaGlzIGNsYXNzIGNvbnZlcnRzIFNBWCBvciBTQVgtbGlrZSBjYWxscyB0byBhCi0gKiBzZXJpYWxpemVkIGRvY3VtZW50IGZvciB4c2w6b3V0cHV0IG1ldGhvZCBvZiAidGV4dCIuCi0gKiBAeHNsLnVzYWdlIGludGVybmFsCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBUb1RleHRTdHJlYW0gZXh0ZW5kcyBUb1N0cmVhbQotewotCi0KLSAgLyoqCi0gICAqIERlZmF1bHQgY29uc3RydWN0b3IuCi0gICAqLwotICBwdWJsaWMgVG9UZXh0U3RyZWFtKCkKLSAgewotICAgIHN1cGVyKCk7Ci0gIH0KLQotCi0KLSAgLyoqCi0gICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIHRoZSBiZWdpbm5pbmcgb2YgYSBkb2N1bWVudC4KLSAgICoKLSAgICogPHA+VGhlIFNBWCBwYXJzZXIgd2lsbCBpbnZva2UgdGhpcyBtZXRob2Qgb25seSBvbmNlLCBiZWZvcmUgYW55Ci0gICAqIG90aGVyIG1ldGhvZHMgaW4gdGhpcyBpbnRlcmZhY2Ugb3IgaW4gRFRESGFuZGxlciAoZXhjZXB0IGZvcgotICAgKiBzZXREb2N1bWVudExvY2F0b3IpLjwvcD4KLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBzdGFydERvY3VtZW50SW50ZXJuYWwoKSB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBzdXBlci5zdGFydERvY3VtZW50SW50ZXJuYWwoKTsKLQotICAgIG1fbmVlZFRvQ2FsbFN0YXJ0RG9jdW1lbnQgPSBmYWxzZTsKLQotICAgIC8vIE5vIGFjdGlvbiBmb3IgdGhlIG1vbWVudC4KLSAgfQotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiB0aGUgZW5kIG9mIGEgZG9jdW1lbnQuCi0gICAqCi0gICAqIDxwPlRoZSBTQVggcGFyc2VyIHdpbGwgaW52b2tlIHRoaXMgbWV0aG9kIG9ubHkgb25jZSwgYW5kIGl0IHdpbGwKLSAgICogYmUgdGhlIGxhc3QgbWV0aG9kIGludm9rZWQgZHVyaW5nIHRoZSBwYXJzZS4gIFRoZSBwYXJzZXIgc2hhbGwKLSAgICogbm90IGludm9rZSB0aGlzIG1ldGhvZCB1bnRpbCBpdCBoYXMgZWl0aGVyIGFiYW5kb25lZCBwYXJzaW5nCi0gICAqIChiZWNhdXNlIG9mIGFuIHVucmVjb3ZlcmFibGUgZXJyb3IpIG9yIHJlYWNoZWQgdGhlIGVuZCBvZgotICAgKiBpbnB1dC48L3A+Ci0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgKgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgZW5kRG9jdW1lbnQoKSB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBmbHVzaFBlbmRpbmcoKTsKLSAgICBmbHVzaFdyaXRlcigpOwotICAgIGlmIChtX3RyYWNlciAhPSBudWxsKQotICAgICAgICBzdXBlci5maXJlRW5kRG9jKCk7Ci0gIH0KLQotICAvKioKLSAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIGJlZ2lubmluZyBvZiBhbiBlbGVtZW50LgotICAgKgotICAgKiA8cD5UaGUgUGFyc2VyIHdpbGwgaW52b2tlIHRoaXMgbWV0aG9kIGF0IHRoZSBiZWdpbm5pbmcgb2YgZXZlcnkKLSAgICogZWxlbWVudCBpbiB0aGUgWE1MIGRvY3VtZW50OyB0aGVyZSB3aWxsIGJlIGEgY29ycmVzcG9uZGluZwotICAgKiBlbmRFbGVtZW50KCkgZXZlbnQgZm9yIGV2ZXJ5IHN0YXJ0RWxlbWVudCgpIGV2ZW50IChldmVuIHdoZW4gdGhlCi0gICAqIGVsZW1lbnQgaXMgZW1wdHkpLiBBbGwgb2YgdGhlIGVsZW1lbnQncyBjb250ZW50IHdpbGwgYmUKLSAgICogcmVwb3J0ZWQsIGluIG9yZGVyLCBiZWZvcmUgdGhlIGNvcnJlc3BvbmRpbmcgZW5kRWxlbWVudCgpCi0gICAqIGV2ZW50LjwvcD4KLSAgICoKLSAgICogPHA+SWYgdGhlIGVsZW1lbnQgbmFtZSBoYXMgYSBuYW1lc3BhY2UgcHJlZml4LCB0aGUgcHJlZml4IHdpbGwKLSAgICogc3RpbGwgYmUgYXR0YWNoZWQuICBOb3RlIHRoYXQgdGhlIGF0dHJpYnV0ZSBsaXN0IHByb3ZpZGVkIHdpbGwKLSAgICogY29udGFpbiBvbmx5IGF0dHJpYnV0ZXMgd2l0aCBleHBsaWNpdCB2YWx1ZXMgKHNwZWNpZmllZCBvcgotICAgKiBkZWZhdWx0ZWQpOiAjSU1QTElFRCBhdHRyaWJ1dGVzIHdpbGwgYmUgb21pdHRlZC48L3A+Ci0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkgVGhlIE5hbWVzcGFjZSBVUkksIG9yIHRoZSBlbXB0eSBzdHJpbmcgaWYgdGhlCi0gICAqICAgICAgICBlbGVtZW50IGhhcyBubyBOYW1lc3BhY2UgVVJJIG9yIGlmIE5hbWVzcGFjZQotICAgKiAgICAgICAgcHJvY2Vzc2luZyBpcyBub3QgYmVpbmcgcGVyZm9ybWVkLgotICAgKiBAcGFyYW0gbG9jYWxOYW1lIFRoZSBsb2NhbCBuYW1lICh3aXRob3V0IHByZWZpeCksIG9yIHRoZQotICAgKiAgICAgICAgZW1wdHkgc3RyaW5nIGlmIE5hbWVzcGFjZSBwcm9jZXNzaW5nIGlzIG5vdCBiZWluZwotICAgKiAgICAgICAgcGVyZm9ybWVkLgotICAgKiBAcGFyYW0gbmFtZSBUaGUgcXVhbGlmaWVkIG5hbWUgKHdpdGggcHJlZml4KSwgb3IgdGhlCi0gICAqICAgICAgICBlbXB0eSBzdHJpbmcgaWYgcXVhbGlmaWVkIG5hbWVzIGFyZSBub3QgYXZhaWxhYmxlLgotICAgKiBAcGFyYW0gYXR0cyBUaGUgYXR0cmlidXRlcyBhdHRhY2hlZCB0byB0aGUgZWxlbWVudCwgaWYgYW55LgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICogQHNlZSAjZW5kRWxlbWVudAotICAgKiBAc2VlIG9yZy54bWwuc2F4LkF0dHJpYnV0ZUxpc3QKLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudCgKLSAgICAgICAgICBTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgbG9jYWxOYW1lLCBTdHJpbmcgbmFtZSwgQXR0cmlidXRlcyBhdHRzKQotICAgICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgLy8gdGltZSB0byBmaXJlIG9mZiBzdGFydEVsZW1lbnQgZXZlbnQKLSAgICBpZiAobV90cmFjZXIgIT0gbnVsbCkgewotICAgICAgICBzdXBlci5maXJlU3RhcnRFbGVtKG5hbWUpOwotICAgICAgICB0aGlzLmZpcmVQc2V1ZG9BdHRyaWJ1dGVzKCk7Ci0gICAgfQotICAgIHJldHVybjsKLSAgfQotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiB0aGUgZW5kIG9mIGFuIGVsZW1lbnQuCi0gICAqCi0gICAqIDxwPlRoZSBTQVggcGFyc2VyIHdpbGwgaW52b2tlIHRoaXMgbWV0aG9kIGF0IHRoZSBlbmQgb2YgZXZlcnkKLSAgICogZWxlbWVudCBpbiB0aGUgWE1MIGRvY3VtZW50OyB0aGVyZSB3aWxsIGJlIGEgY29ycmVzcG9uZGluZwotICAgKiBzdGFydEVsZW1lbnQoKSBldmVudCBmb3IgZXZlcnkgZW5kRWxlbWVudCgpIGV2ZW50IChldmVuIHdoZW4gdGhlCi0gICAqIGVsZW1lbnQgaXMgZW1wdHkpLjwvcD4KLSAgICoKLSAgICogPHA+SWYgdGhlIGVsZW1lbnQgbmFtZSBoYXMgYSBuYW1lc3BhY2UgcHJlZml4LCB0aGUgcHJlZml4IHdpbGwKLSAgICogc3RpbGwgYmUgYXR0YWNoZWQgdG8gdGhlIG5hbWUuPC9wPgotICAgKgotICAgKgotICAgKiBAcGFyYW0gbmFtZXNwYWNlVVJJIFRoZSBOYW1lc3BhY2UgVVJJLCBvciB0aGUgZW1wdHkgc3RyaW5nIGlmIHRoZQotICAgKiAgICAgICAgZWxlbWVudCBoYXMgbm8gTmFtZXNwYWNlIFVSSSBvciBpZiBOYW1lc3BhY2UKLSAgICogICAgICAgIHByb2Nlc3NpbmcgaXMgbm90IGJlaW5nIHBlcmZvcm1lZC4KLSAgICogQHBhcmFtIGxvY2FsTmFtZSBUaGUgbG9jYWwgbmFtZSAod2l0aG91dCBwcmVmaXgpLCBvciB0aGUKLSAgICogICAgICAgIGVtcHR5IHN0cmluZyBpZiBOYW1lc3BhY2UgcHJvY2Vzc2luZyBpcyBub3QgYmVpbmcKLSAgICogICAgICAgIHBlcmZvcm1lZC4KLSAgICogQHBhcmFtIG5hbWUgVGhlIHF1YWxpZmllZCBuYW1lICh3aXRoIHByZWZpeCksIG9yIHRoZQotICAgKiAgICAgICAgZW1wdHkgc3RyaW5nIGlmIHF1YWxpZmllZCBuYW1lcyBhcmUgbm90IGF2YWlsYWJsZS4KLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBlbmRFbGVtZW50KFN0cmluZyBuYW1lc3BhY2VVUkksIFN0cmluZyBsb2NhbE5hbWUsIFN0cmluZyBuYW1lKQotICAgICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgICAgICBpZiAobV90cmFjZXIgIT0gbnVsbCkKLSAgICAgICAgICAgIHN1cGVyLmZpcmVFbmRFbGVtKG5hbWUpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGNoYXJhY3RlciBkYXRhLgotICAgKgotICAgKiA8cD5UaGUgUGFyc2VyIHdpbGwgY2FsbCB0aGlzIG1ldGhvZCB0byByZXBvcnQgZWFjaCBjaHVuayBvZgotICAgKiBjaGFyYWN0ZXIgZGF0YS4gIFNBWCBwYXJzZXJzIG1heSByZXR1cm4gYWxsIGNvbnRpZ3VvdXMgY2hhcmFjdGVyCi0gICAqIGRhdGEgaW4gYSBzaW5nbGUgY2h1bmssIG9yIHRoZXkgbWF5IHNwbGl0IGl0IGludG8gc2V2ZXJhbAotICAgKiBjaHVua3M7IGhvd2V2ZXIsIGFsbCBvZiB0aGUgY2hhcmFjdGVycyBpbiBhbnkgc2luZ2xlIGV2ZW50Ci0gICAqIG11c3QgY29tZSBmcm9tIHRoZSBzYW1lIGV4dGVybmFsIGVudGl0eSwgc28gdGhhdCB0aGUgTG9jYXRvcgotICAgKiBwcm92aWRlcyB1c2VmdWwgaW5mb3JtYXRpb24uPC9wPgotICAgKgotICAgKiA8cD5UaGUgYXBwbGljYXRpb24gbXVzdCBub3QgYXR0ZW1wdCB0byByZWFkIGZyb20gdGhlIGFycmF5Ci0gICAqIG91dHNpZGUgb2YgdGhlIHNwZWNpZmllZCByYW5nZS48L3A+Ci0gICAqCi0gICAqIDxwPk5vdGUgdGhhdCBzb21lIHBhcnNlcnMgd2lsbCByZXBvcnQgd2hpdGVzcGFjZSB1c2luZyB0aGUKLSAgICogaWdub3JhYmxlV2hpdGVzcGFjZSgpIG1ldGhvZCByYXRoZXIgdGhhbiB0aGlzIG9uZSAodmFsaWRhdGluZwotICAgKiBwYXJzZXJzIG11c3QgZG8gc28pLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIGNoIFRoZSBjaGFyYWN0ZXJzIGZyb20gdGhlIFhNTCBkb2N1bWVudC4KLSAgICogQHBhcmFtIHN0YXJ0IFRoZSBzdGFydCBwb3NpdGlvbiBpbiB0aGUgYXJyYXkuCi0gICAqIEBwYXJhbSBsZW5ndGggVGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHJlYWQgZnJvbSB0aGUgYXJyYXkuCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgKiBAc2VlICNpZ25vcmFibGVXaGl0ZXNwYWNlCi0gICAqIEBzZWUgb3JnLnhtbC5zYXguTG9jYXRvcgotICAgKi8KLSAgcHVibGljIHZvaWQgY2hhcmFjdGVycyhjaGFyIGNoW10sIGludCBzdGFydCwgaW50IGxlbmd0aCkKLSAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIGZsdXNoUGVuZGluZygpOwotCi0gICAgdHJ5Ci0gICAgewotICAgICAgICBpZiAoaW5UZW1wb3JhcnlPdXRwdXRTdGF0ZSgpKSB7Ci0gICAgICAgICAgICAvKiBsZWF2ZSBjaGFyYWN0ZXJzIHVuLXByb2Nlc3NlZCBhcyB3ZSBhcmUKLSAgICAgICAgICAgICAqIGNyZWF0aW5nIHRlbXBvcmFyeSBvdXRwdXQsIHRoZSBvdXRwdXQgZ2VuZXJhdGVkIGJ5Ci0gICAgICAgICAgICAgKiB0aGlzIHNlcmlhbGl6ZXIgd2lsbCBiZSBpbnB1dCB0byBhIGZpbmFsIHNlcmlhbGl6ZXIKLSAgICAgICAgICAgICAqIGxhdGVyIG9uIGFuZCBpdCB3aWxsIGRvIHRoZSBwcm9jZXNzaW5nIGluIGZpbmFsCi0gICAgICAgICAgICAgKiBvdXRwdXQgc3RhdGUgKG5vdCB0ZW1wb3Jhcnkgb3V0cHV0IHN0YXRlKS4KLSAgICAgICAgICAgICAqCi0gICAgICAgICAgICAgKiBBICJ0ZW1wb3JhcnkiIFRvVGV4dFN0cmVhbSBzZXJpYWxpemVyIGlzIHVzZWQgdG8KLSAgICAgICAgICAgICAqIGV2YWx1YXRlIGF0dHJpYnV0ZSB2YWx1ZSB0ZW1wbGF0ZXMgKGZvciBleGFtcGxlKSwKLSAgICAgICAgICAgICAqIGFuZCB0aGUgcmVzdWx0IG9mIGV2YWx1YXRpbmcgc3VjaCBhIHRoaW5nCi0gICAgICAgICAgICAgKiBpcyBmZWQgaW50byBhIGZpbmFsIHNlcmlhbGl6ZXIgbGF0ZXIgb24uCi0gICAgICAgICAgICAgKi8KLSAgICAgICAgICAgIG1fd3JpdGVyLndyaXRlKGNoLCBzdGFydCwgbGVuZ3RoKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIC8vIEluIGZpbmFsIG91dHB1dCBzdGF0ZSB3ZSBkbyBwcm9jZXNzIHRoZSBjaGFyYWN0ZXJzIQotICAgICAgICAgICAgd3JpdGVOb3JtYWxpemVkQ2hhcnMoY2gsIHN0YXJ0LCBsZW5ndGgsIG1fbGluZVNlcFVzZSk7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAobV90cmFjZXIgIT0gbnVsbCkKLSAgICAgICAgICAgIHN1cGVyLmZpcmVDaGFyRXZlbnQoY2gsIHN0YXJ0LCBsZW5ndGgpOwotICAgIH0KLSAgICBjYXRjaChJT0V4Y2VwdGlvbiBpb2UpCi0gICAgewotICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbihpb2UpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBJZiBhdmFpbGFibGUsIHdoZW4gdGhlIGRpc2FibGUtb3V0cHV0LWVzY2FwaW5nIGF0dHJpYnV0ZSBpcyB1c2VkLAotICAgKiBvdXRwdXQgcmF3IHRleHQgd2l0aG91dCBlc2NhcGluZy4KLSAgICoKLSAgICogQHBhcmFtIGNoIFRoZSBjaGFyYWN0ZXJzIGZyb20gdGhlIFhNTCBkb2N1bWVudC4KLSAgICogQHBhcmFtIHN0YXJ0IFRoZSBzdGFydCBwb3NpdGlvbiBpbiB0aGUgYXJyYXkuCi0gICAqIEBwYXJhbSBsZW5ndGggVGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHJlYWQgZnJvbSB0aGUgYXJyYXkuCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgKi8KLSAgcHVibGljIHZvaWQgY2hhcmFjdGVyc1JhdyhjaGFyIGNoW10sIGludCBzdGFydCwgaW50IGxlbmd0aCkKLSAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIHdyaXRlTm9ybWFsaXplZENoYXJzKGNoLCBzdGFydCwgbGVuZ3RoLCBtX2xpbmVTZXBVc2UpOwotICAgIH0KLSAgICBjYXRjaChJT0V4Y2VwdGlvbiBpb2UpCi0gICAgewotICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbihpb2UpOwotICAgIH0KLSAgfQotCi0gICAgLyoqCi0gICAgICogTm9ybWFsaXplIHRoZSBjaGFyYWN0ZXJzLCBidXQgZG9uJ3QgZXNjYXBlLiAgRGlmZmVyZW50IGZyb20KLSAgICAgKiBTZXJpYWxpemVyVG9YTUwjd3JpdGVOb3JtYWxpemVkQ2hhcnMgYmVjYXVzZSBpdCBkb2VzIG5vdCBhdHRlbXB0IHRvIGRvCi0gICAgICogWE1MIGVzY2FwaW5nIGF0IGFsbC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjaCBUaGUgY2hhcmFjdGVycyBmcm9tIHRoZSBYTUwgZG9jdW1lbnQuCi0gICAgICogQHBhcmFtIHN0YXJ0IFRoZSBzdGFydCBwb3NpdGlvbiBpbiB0aGUgYXJyYXkuCi0gICAgICogQHBhcmFtIGxlbmd0aCBUaGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gcmVhZCBmcm9tIHRoZSBhcnJheS4KLSAgICAgKiBAcGFyYW0gdXNlTGluZVNlcCB0cnVlIGlmIHRoZSBvcGVyYXRpbmcgc3lzdGVtcwotICAgICAqIGVuZC1vZi1saW5lIHNlcGFyYXRvciBzaG91bGQgYmUgb3V0cHV0IHJhdGhlciB0aGFuIGEgbmV3LWxpbmUgY2hhcmFjdGVyLgotICAgICAqCi0gICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgotICAgICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAgICovCi0gICAgdm9pZCB3cml0ZU5vcm1hbGl6ZWRDaGFycygKLSAgICAgICAgZmluYWwgY2hhciBjaFtdLAotICAgICAgICAgICAgZmluYWwgaW50IHN0YXJ0LAotICAgICAgICAgICAgZmluYWwgaW50IGxlbmd0aCwKLSAgICAgICAgICAgIGZpbmFsIGJvb2xlYW4gdXNlTGluZVNlcCkKLSAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBmaW5hbCBTdHJpbmcgZW5jb2RpbmcgPSBnZXRFbmNvZGluZygpOwotICAgICAgICBmaW5hbCBqYXZhLmlvLldyaXRlciB3cml0ZXIgPSBtX3dyaXRlcjsKLSAgICAgICAgZmluYWwgaW50IGVuZCA9IHN0YXJ0ICsgbGVuZ3RoOwotCi0gICAgICAgIC8qIGNvcHkgYSBmZXcgImNvbnN0YW50cyIgYmVmb3JlIHRoZSBsb29wIGZvciBwZXJmb3JtYW5jZSAqLwotICAgICAgICBmaW5hbCBjaGFyIFNfTElORUZFRUQgPSBDaGFySW5mby5TX0xJTkVGRUVEOwotCi0gICAgICAgIC8vIFRoaXMgZm9yKCkgbG9vcCBhbHdheXMgaW5jcmVtZW50cyBpIGJ5IG9uZSBhdCB0aGUgZW5kCi0gICAgICAgIC8vIG9mIHRoZSBsb29wLiAgQWRkaXRpb25hbCBpbmNyZW1lbnRzIG9mIGkgYWRqdXN0IGZvciB3aGVuCi0gICAgICAgIC8vIHR3byBpbnB1dCBjaGFyYWN0ZXJzIChhIGhpZ2gvbG93IFVURjE2IHN1cnJvZ2F0ZSBwYWlyKQotICAgICAgICAvLyBhcmUgcHJvY2Vzc2VkLgotICAgICAgICBmb3IgKGludCBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykgewotICAgICAgICAgICAgZmluYWwgY2hhciBjID0gY2hbaV07Ci0KLSAgICAgICAgICAgIGlmIChTX0xJTkVGRUVEID09IGMgJiYgdXNlTGluZVNlcCkgewotICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZShtX2xpbmVTZXAsIDAsIG1fbGluZVNlcExlbik7Ci0gICAgICAgICAgICAgICAgLy8gb25lIGlucHV0IGNoYXIgcHJvY2Vzc2VkCi0gICAgICAgICAgICB9IGVsc2UgaWYgKG1fZW5jb2RpbmdJbmZvLmlzSW5FbmNvZGluZyhjKSkgewotICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZShjKTsKLSAgICAgICAgICAgICAgICAvLyBvbmUgaW5wdXQgY2hhciBwcm9jZXNzZWQKLSAgICAgICAgICAgIH0gZWxzZSBpZiAoRW5jb2RpbmdzLmlzSGlnaFVURjE2U3Vycm9nYXRlKGMpKSB7Ci0gICAgICAgICAgICAgICAgZmluYWwgaW50IGNvZGVQb2ludCA9IHdyaXRlVVRGMTZTdXJyb2dhdGUoYywgY2gsIGksIGVuZCk7Ci0gICAgICAgICAgICAgICAgaWYgKGNvZGVQb2ludCAhPSAwKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIEkgdGhpbmsgd2UgY2FuIGp1c3QgZW1pdCB0aGUgbWVzc2FnZSwKLSAgICAgICAgICAgICAgICAgICAgLy8gbm90IGNyYXNoIGFuZCBidXJuLgotICAgICAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgaW50ZWdyYWxWYWx1ZSA9IEludGVnZXIudG9TdHJpbmcoY29kZVBvaW50KTsKLSAgICAgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIG1zZyA9IFV0aWxzLm1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoCi0gICAgICAgICAgICAgICAgICAgICAgICBNc2dLZXkuRVJfSUxMRUdBTF9DSEFSQUNURVIsCi0gICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBpbnRlZ3JhbFZhbHVlLCBlbmNvZGluZyB9KTsKLQotICAgICAgICAgICAgICAgICAgICAvL09sZGVyIGJlaGF2aW9yIHdhcyB0byB0aHJvdyB0aGUgbWVzc2FnZSwKLSAgICAgICAgICAgICAgICAgICAgLy9idXQgbmV3ZXIgZ2VudGxlciBiZWhhdmlvciBpcyB0byB3cml0ZSBhIG1lc3NhZ2UgdG8gU3lzdGVtLmVycgotICAgICAgICAgICAgICAgICAgICAvL3Rocm93IG5ldyBTQVhFeGNlcHRpb24obXNnKTsKLSAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKG1zZyk7Ci0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaSsrOyAvLyB0d28gaW5wdXQgY2hhcnMgcHJvY2Vzc2VkCi0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIC8vIERvbid0IGtub3cgd2hhdCB0byBkbyB3aXRoIHRoaXMgY2hhciwgaXQgaXMKLSAgICAgICAgICAgICAgICAvLyBub3QgaW4gdGhlIGVuY29kaW5nIGFuZCBub3QgYSBoaWdoIGNoYXIgaW4KLSAgICAgICAgICAgICAgICAvLyBhIHN1cnJvZ2F0ZSBwYWlyLCBzbyB3cml0ZSBvdXQgYXMgYW4gZW50aXR5IHJlZgotICAgICAgICAgICAgICAgIGlmIChlbmNvZGluZyAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8qIFRoZSBvdXRwdXQgZW5jb2RpbmcgaXMga25vd24sCi0gICAgICAgICAgICAgICAgICAgICAqIHNvIHNvbXRoaW5nIGlzIHdyb25nLgotICAgICAgICAgICAgICAgICAgICAgKi8KLQotICAgICAgICAgICAgICAgICAgICAvLyBub3QgaW4gdGhlIGVuY29kaW5nLCBzbyB3cml0ZSBvdXQgYSBjaGFyYWN0ZXIgcmVmZXJlbmNlCi0gICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZSgnJicpOwotICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoJyMnKTsKLSAgICAgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKEludGVnZXIudG9TdHJpbmcoYykpOwotICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoJzsnKTsKLQotICAgICAgICAgICAgICAgICAgICAvLyBJIHRoaW5rIHdlIGNhbiBqdXN0IGVtaXQgdGhlIG1lc3NhZ2UsCi0gICAgICAgICAgICAgICAgICAgIC8vIG5vdCBjcmFzaCBhbmQgYnVybi4KLSAgICAgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIGludGVncmFsVmFsdWUgPSBJbnRlZ2VyLnRvU3RyaW5nKGMpOwotICAgICAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgbXNnID0gVXRpbHMubWVzc2FnZXMuY3JlYXRlTWVzc2FnZSgKLSAgICAgICAgICAgICAgICAgICAgICAgIE1zZ0tleS5FUl9JTExFR0FMX0NIQVJBQ1RFUiwKLSAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7IGludGVncmFsVmFsdWUsIGVuY29kaW5nIH0pOwotCi0gICAgICAgICAgICAgICAgICAgIC8vT2xkZXIgYmVoYXZpb3Igd2FzIHRvIHRocm93IHRoZSBtZXNzYWdlLAotICAgICAgICAgICAgICAgICAgICAvL2J1dCBuZXdlciBnZW50bGVyIGJlaGF2aW9yIGlzIHRvIHdyaXRlIGEgbWVzc2FnZSB0byBTeXN0ZW0uZXJyCi0gICAgICAgICAgICAgICAgICAgIC8vdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbihtc2cpOwotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4obXNnKTsKLSAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAvKiBUaGUgb3V0cHV0IGVuY29kaW5nIGlzIG5vdCBrbm93biwKLSAgICAgICAgICAgICAgICAgICAgICogc28ganVzdCB3cml0ZSBpdCBvdXQgYXMtaXMuCi0gICAgICAgICAgICAgICAgICAgICAqLwotICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoYyk7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgLy8gb25lIGlucHV0IGNoYXIgd2FzIHByb2Nlc3NlZAotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBjZGF0YS4KLSAgICoKLSAgICogPHA+VGhlIFBhcnNlciB3aWxsIGNhbGwgdGhpcyBtZXRob2QgdG8gcmVwb3J0IGVhY2ggY2h1bmsgb2YKLSAgICogY2hhcmFjdGVyIGRhdGEuICBTQVggcGFyc2VycyBtYXkgcmV0dXJuIGFsbCBjb250aWd1b3VzIGNoYXJhY3RlcgotICAgKiBkYXRhIGluIGEgc2luZ2xlIGNodW5rLCBvciB0aGV5IG1heSBzcGxpdCBpdCBpbnRvIHNldmVyYWwKLSAgICogY2h1bmtzOyBob3dldmVyLCBhbGwgb2YgdGhlIGNoYXJhY3RlcnMgaW4gYW55IHNpbmdsZSBldmVudAotICAgKiBtdXN0IGNvbWUgZnJvbSB0aGUgc2FtZSBleHRlcm5hbCBlbnRpdHksIHNvIHRoYXQgdGhlIExvY2F0b3IKLSAgICogcHJvdmlkZXMgdXNlZnVsIGluZm9ybWF0aW9uLjwvcD4KLSAgICoKLSAgICogPHA+VGhlIGFwcGxpY2F0aW9uIG11c3Qgbm90IGF0dGVtcHQgdG8gcmVhZCBmcm9tIHRoZSBhcnJheQotICAgKiBvdXRzaWRlIG9mIHRoZSBzcGVjaWZpZWQgcmFuZ2UuPC9wPgotICAgKgotICAgKiA8cD5Ob3RlIHRoYXQgc29tZSBwYXJzZXJzIHdpbGwgcmVwb3J0IHdoaXRlc3BhY2UgdXNpbmcgdGhlCi0gICAqIGlnbm9yYWJsZVdoaXRlc3BhY2UoKSBtZXRob2QgcmF0aGVyIHRoYW4gdGhpcyBvbmUgKHZhbGlkYXRpbmcKLSAgICogcGFyc2VycyBtdXN0IGRvIHNvKS48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBjaCBUaGUgY2hhcmFjdGVycyBmcm9tIHRoZSBYTUwgZG9jdW1lbnQuCi0gICAqIEBwYXJhbSBzdGFydCBUaGUgc3RhcnQgcG9zaXRpb24gaW4gdGhlIGFycmF5LgotICAgKiBAcGFyYW0gbGVuZ3RoIFRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyB0byByZWFkIGZyb20gdGhlIGFycmF5LgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICogQHNlZSAjaWdub3JhYmxlV2hpdGVzcGFjZQotICAgKiBAc2VlIG9yZy54bWwuc2F4LkxvY2F0b3IKLSAgICovCi0gIHB1YmxpYyB2b2lkIGNkYXRhKGNoYXIgY2hbXSwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKQotICAgICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIHRyeQotICAgIHsKLSAgICAgICAgd3JpdGVOb3JtYWxpemVkQ2hhcnMoY2gsIHN0YXJ0LCBsZW5ndGgsIG1fbGluZVNlcFVzZSk7Ci0gICAgICAgIGlmIChtX3RyYWNlciAhPSBudWxsKQotICAgICAgICAgICAgc3VwZXIuZmlyZUNEQVRBRXZlbnQoY2gsIHN0YXJ0LCBsZW5ndGgpOwotICAgIH0KLSAgICBjYXRjaChJT0V4Y2VwdGlvbiBpb2UpCi0gICAgewotICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbihpb2UpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBpZ25vcmFibGUgd2hpdGVzcGFjZSBpbiBlbGVtZW50IGNvbnRlbnQuCi0gICAqCi0gICAqIDxwPlZhbGlkYXRpbmcgUGFyc2VycyBtdXN0IHVzZSB0aGlzIG1ldGhvZCB0byByZXBvcnQgZWFjaCBjaHVuawotICAgKiBvZiBpZ25vcmFibGUgd2hpdGVzcGFjZSAoc2VlIHRoZSBXM0MgWE1MIDEuMCByZWNvbW1lbmRhdGlvbiwKLSAgICogc2VjdGlvbiAyLjEwKTogbm9uLXZhbGlkYXRpbmcgcGFyc2VycyBtYXkgYWxzbyB1c2UgdGhpcyBtZXRob2QKLSAgICogaWYgdGhleSBhcmUgY2FwYWJsZSBvZiBwYXJzaW5nIGFuZCB1c2luZyBjb250ZW50IG1vZGVscy48L3A+Ci0gICAqCi0gICAqIDxwPlNBWCBwYXJzZXJzIG1heSByZXR1cm4gYWxsIGNvbnRpZ3VvdXMgd2hpdGVzcGFjZSBpbiBhIHNpbmdsZQotICAgKiBjaHVuaywgb3IgdGhleSBtYXkgc3BsaXQgaXQgaW50byBzZXZlcmFsIGNodW5rczsgaG93ZXZlciwgYWxsIG9mCi0gICAqIHRoZSBjaGFyYWN0ZXJzIGluIGFueSBzaW5nbGUgZXZlbnQgbXVzdCBjb21lIGZyb20gdGhlIHNhbWUKLSAgICogZXh0ZXJuYWwgZW50aXR5LCBzbyB0aGF0IHRoZSBMb2NhdG9yIHByb3ZpZGVzIHVzZWZ1bAotICAgKiBpbmZvcm1hdGlvbi48L3A+Ci0gICAqCi0gICAqIDxwPlRoZSBhcHBsaWNhdGlvbiBtdXN0IG5vdCBhdHRlbXB0IHRvIHJlYWQgZnJvbSB0aGUgYXJyYXkKLSAgICogb3V0c2lkZSBvZiB0aGUgc3BlY2lmaWVkIHJhbmdlLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIGNoIFRoZSBjaGFyYWN0ZXJzIGZyb20gdGhlIFhNTCBkb2N1bWVudC4KLSAgICogQHBhcmFtIHN0YXJ0IFRoZSBzdGFydCBwb3NpdGlvbiBpbiB0aGUgYXJyYXkuCi0gICAqIEBwYXJhbSBsZW5ndGggVGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHJlYWQgZnJvbSB0aGUgYXJyYXkuCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgKiBAc2VlICNjaGFyYWN0ZXJzCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBpZ25vcmFibGVXaGl0ZXNwYWNlKGNoYXIgY2hbXSwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKQotICAgICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgdHJ5Ci0gICAgewotICAgICAgd3JpdGVOb3JtYWxpemVkQ2hhcnMoY2gsIHN0YXJ0LCBsZW5ndGgsIG1fbGluZVNlcFVzZSk7Ci0gICAgfQotICAgIGNhdGNoKElPRXhjZXB0aW9uIGlvZSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKGlvZSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGEgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbi4KLSAgICoKLSAgICogPHA+VGhlIFBhcnNlciB3aWxsIGludm9rZSB0aGlzIG1ldGhvZCBvbmNlIGZvciBlYWNoIHByb2Nlc3NpbmcKLSAgICogaW5zdHJ1Y3Rpb24gZm91bmQ6IG5vdGUgdGhhdCBwcm9jZXNzaW5nIGluc3RydWN0aW9ucyBtYXkgb2NjdXIKLSAgICogYmVmb3JlIG9yIGFmdGVyIHRoZSBtYWluIGRvY3VtZW50IGVsZW1lbnQuPC9wPgotICAgKgotICAgKiA8cD5BIFNBWCBwYXJzZXIgc2hvdWxkIG5ldmVyIHJlcG9ydCBhbiBYTUwgZGVjbGFyYXRpb24gKFhNTCAxLjAsCi0gICAqIHNlY3Rpb24gMi44KSBvciBhIHRleHQgZGVjbGFyYXRpb24gKFhNTCAxLjAsIHNlY3Rpb24gNC4zLjEpCi0gICAqIHVzaW5nIHRoaXMgbWV0aG9kLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIHRhcmdldCBUaGUgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiB0YXJnZXQuCi0gICAqIEBwYXJhbSBkYXRhIFRoZSBwcm9jZXNzaW5nIGluc3RydWN0aW9uIGRhdGEsIG9yIG51bGwgaWYKLSAgICogICAgICAgIG5vbmUgd2FzIHN1cHBsaWVkLgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHByb2Nlc3NpbmdJbnN0cnVjdGlvbihTdHJpbmcgdGFyZ2V0LCBTdHJpbmcgZGF0YSkKLSAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICAvLyBmbHVzaCBhbnl0aGluZyBwZW5kaW5nIGZpcnN0Ci0gICAgZmx1c2hQZW5kaW5nKCk7Ci0KLSAgICBpZiAobV90cmFjZXIgIT0gbnVsbCkKLSAgICAgICAgc3VwZXIuZmlyZUVzY2FwaW5nRXZlbnQodGFyZ2V0LCBkYXRhKTsKLSAgfQotCi0gIC8qKgotICAgKiBDYWxsZWQgd2hlbiBhIENvbW1lbnQgaXMgdG8gYmUgY29uc3RydWN0ZWQuCi0gICAqIE5vdGUgdGhhdCBYYWxhbiB3aWxsIG5vcm1hbGx5IGludm9rZSB0aGUgb3RoZXIgdmVyc2lvbiBvZiB0aGlzIG1ldGhvZC4KLSAgICogJVJFVklFVyUgSW4gZmFjdCwgaXMgdGhpcyBvbmUgZXZlciBuZWVkZWQsIG9yIHdhcyBpdCBhIG1pc3Rha2U/Ci0gICAqCi0gICAqIEBwYXJhbSAgIGRhdGEgIFRoZSBjb21tZW50IGRhdGEuCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgKi8KLSAgcHVibGljIHZvaWQgY29tbWVudChTdHJpbmcgZGF0YSkgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgICBmaW5hbCBpbnQgbGVuZ3RoID0gZGF0YS5sZW5ndGgoKTsKLSAgICAgIGlmIChsZW5ndGggPiBtX2NoYXJzQnVmZi5sZW5ndGgpCi0gICAgICB7Ci0gICAgICAgICAgbV9jaGFyc0J1ZmYgPSBuZXcgY2hhcltsZW5ndGgqMiArIDFdOwotICAgICAgfQotICAgICAgZGF0YS5nZXRDaGFycygwLCBsZW5ndGgsIG1fY2hhcnNCdWZmLCAwKTsKLSAgICAgIGNvbW1lbnQobV9jaGFyc0J1ZmYsIDAsIGxlbmd0aCk7Ci0gIH0KLQotICAvKioKLSAgICogUmVwb3J0IGFuIFhNTCBjb21tZW50IGFueXdoZXJlIGluIHRoZSBkb2N1bWVudC4KLSAgICoKLSAgICogVGhpcyBjYWxsYmFjayB3aWxsIGJlIHVzZWQgZm9yIGNvbW1lbnRzIGluc2lkZSBvciBvdXRzaWRlIHRoZQotICAgKiBkb2N1bWVudCBlbGVtZW50LCBpbmNsdWRpbmcgY29tbWVudHMgaW4gdGhlIGV4dGVybmFsIERURAotICAgKiBzdWJzZXQgKGlmIHJlYWQpLgotICAgKgotICAgKiBAcGFyYW0gY2ggQW4gYXJyYXkgaG9sZGluZyB0aGUgY2hhcmFjdGVycyBpbiB0aGUgY29tbWVudC4KLSAgICogQHBhcmFtIHN0YXJ0IFRoZSBzdGFydGluZyBwb3NpdGlvbiBpbiB0aGUgYXJyYXkuCi0gICAqIEBwYXJhbSBsZW5ndGggVGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHVzZSBmcm9tIHRoZSBhcnJheS4KLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gVGhlIGFwcGxpY2F0aW9uIG1heSByYWlzZSBhbiBleGNlcHRpb24uCi0gICAqLwotICBwdWJsaWMgdm9pZCBjb21tZW50KGNoYXIgY2hbXSwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKQotICAgICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgZmx1c2hQZW5kaW5nKCk7Ci0gICAgaWYgKG1fdHJhY2VyICE9IG51bGwpCi0gICAgICAgIHN1cGVyLmZpcmVDb21tZW50RXZlbnQoY2gsIHN0YXJ0LCBsZW5ndGgpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlY2VpdmUgbm90aXZpY2F0aW9uIG9mIGEgZW50aXR5UmVmZXJlbmNlLgotICAgKgotICAgKiBAcGFyYW0gbmFtZSBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIG5hbWUgb2YgdGhlIGVudGl0eS4KLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGVudGl0eVJlZmVyZW5jZShTdHJpbmcgbmFtZSkgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgICAgIGlmIChtX3RyYWNlciAhPSBudWxsKQotICAgICAgICAgICAgc3VwZXIuZmlyZUVudGl0eVJlZmVyZW5jZShuYW1lKTsKLSAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBFeHRlbmRlZENvbnRlbnRIYW5kbGVyI2FkZEF0dHJpYnV0ZShTdHJpbmcsIFN0cmluZywgU3RyaW5nLCBTdHJpbmcsIFN0cmluZykKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBhZGRBdHRyaWJ1dGUoCi0gICAgICAgIFN0cmluZyB1cmksCi0gICAgICAgIFN0cmluZyBsb2NhbE5hbWUsCi0gICAgICAgIFN0cmluZyByYXdOYW1lLAotICAgICAgICBTdHJpbmcgdHlwZSwKLSAgICAgICAgU3RyaW5nIHZhbHVlLAotICAgICAgICBib29sZWFuIFhTTEF0dHJpYnV0ZSkKLSAgICB7Ci0gICAgICAgIC8vIGRvIG5vdGhpbmcsIGp1c3QgZm9yZ2V0IGFsbCBhYm91dCB0aGUgYXR0cmlidXRlCi0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXIjZW5kQ0RBVEEoKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZENEQVRBKCkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgLy8gZG8gbm90aGluZwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgRXh0ZW5kZWRDb250ZW50SGFuZGxlciNlbmRFbGVtZW50KFN0cmluZykKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbmRFbGVtZW50KFN0cmluZyBlbGVtTmFtZSkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaWYgKG1fdHJhY2VyICE9IG51bGwpCi0gICAgICAgICAgICBzdXBlci5maXJlRW5kRWxlbShlbGVtTmFtZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRnJvbSBYU0xUQwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudCgKLSAgICBTdHJpbmcgZWxlbWVudE5hbWVzcGFjZVVSSSwKLSAgICBTdHJpbmcgZWxlbWVudExvY2FsTmFtZSwKLSAgICBTdHJpbmcgZWxlbWVudE5hbWUpCi0gICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaWYgKG1fbmVlZFRvQ2FsbFN0YXJ0RG9jdW1lbnQpCi0gICAgICAgICAgICBzdGFydERvY3VtZW50SW50ZXJuYWwoKTsKLSAgICAgICAgLy8gdGltZSB0byBmaXJlIG9mZiBzdGFydGxlbWVudCBldmVudC4KLSAgICAgICAgaWYgKG1fdHJhY2VyICE9IG51bGwpIHsKLSAgICAgICAgICAgIHN1cGVyLmZpcmVTdGFydEVsZW0oZWxlbWVudE5hbWUpOwotICAgICAgICAgICAgdGhpcy5maXJlUHNldWRvQXR0cmlidXRlcygpOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogRnJvbSBYU0xUQwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGNoYXJhY3RlcnMoU3RyaW5nIGNoYXJhY3RlcnMpCi0gICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgZmluYWwgaW50IGxlbmd0aCA9IGNoYXJhY3RlcnMubGVuZ3RoKCk7Ci0gICAgICAgIGlmIChsZW5ndGggPiBtX2NoYXJzQnVmZi5sZW5ndGgpCi0gICAgICAgIHsKLSAgICAgICAgICAgIG1fY2hhcnNCdWZmID0gbmV3IGNoYXJbbGVuZ3RoKjIgKyAxXTsKLSAgICAgICAgfQotICAgICAgICBjaGFyYWN0ZXJzLmdldENoYXJzKDAsIGxlbmd0aCwgbV9jaGFyc0J1ZmYsIDApOwotICAgICAgICBjaGFyYWN0ZXJzKG1fY2hhcnNCdWZmLCAwLCBsZW5ndGgpOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogRnJvbSBYU0xUQwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGFkZEF0dHJpYnV0ZShTdHJpbmcgbmFtZSwgU3RyaW5nIHZhbHVlKQotICAgIHsKLSAgICAgICAgLy8gZG8gbm90aGluZywgZm9yZ2V0IGFib3V0IHRoZSBhdHRyaWJ1dGUKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBZGQgYSB1bmlxdWUgYXR0cmlidXRlCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgYWRkVW5pcXVlQXR0cmlidXRlKFN0cmluZyBxTmFtZSwgU3RyaW5nIHZhbHVlLCBpbnQgZmxhZ3MpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIC8vIGRvIG5vdGhpbmcsIGZvcmdldCBhYm91dCB0aGUgYXR0cmlidXRlCi0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gc3RhcnRQcmVmaXhNYXBwaW5nKAotICAgICAgICBTdHJpbmcgcHJlZml4LAotICAgICAgICBTdHJpbmcgdXJpLAotICAgICAgICBib29sZWFuIHNob3VsZEZsdXNoKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICAvLyBubyBuYW1lc3BhY2Ugc3VwcG9ydCBmb3IgSFRNTAotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgdm9pZCBzdGFydFByZWZpeE1hcHBpbmcoU3RyaW5nIHByZWZpeCwgU3RyaW5nIHVyaSkKLSAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgLy8gbm8gbmFtZXNwYWNlIHN1cHBvcnQgZm9yIEhUTUwKLSAgICB9Ci0KLQotICAgIHB1YmxpYyB2b2lkIG5hbWVzcGFjZUFmdGVyU3RhcnRFbGVtZW50KAotICAgICAgICBmaW5hbCBTdHJpbmcgcHJlZml4LAotICAgICAgICBmaW5hbCBTdHJpbmcgdXJpKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICAvLyBubyBuYW1lc3BhY2Ugc3VwcG9ydCBmb3IgSFRNTAotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGZsdXNoUGVuZGluZygpIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgICAgICBpZiAobV9uZWVkVG9DYWxsU3RhcnREb2N1bWVudCkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBzdGFydERvY3VtZW50SW50ZXJuYWwoKTsKLSAgICAgICAgICAgICAgICBtX25lZWRUb0NhbGxTdGFydERvY3VtZW50ID0gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9Ub1Vua25vd25TdHJlYW0uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvVG9Vbmtub3duU3RyZWFtLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGY4MmU5YzAuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9Ub1Vua25vd25TdHJlYW0uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEzMzggKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogVG9Vbmtub3duU3RyZWFtLmphdmEsdiAxLjMgMjAwNS8wOS8yOCAxMzo0OTowOCBwdmVkdWxhIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyOwotCi1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKLWltcG9ydCBqYXZhLmlvLldyaXRlcjsKLWltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2VMb2NhdG9yOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXI7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotaW1wb3J0IG9yZy54bWwuc2F4LkF0dHJpYnV0ZXM7Ci1pbXBvcnQgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguTG9jYXRvcjsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci0KLQotLyoqCi0gKlRoaXMgY2xhc3Mgd3JhcHMgYW5vdGhlciBTZXJpYWxpemF0aW9uSGFuZGxlci4gVGhlIHdyYXBwZWQgb2JqZWN0IHdpbGwgZWl0aGVyCi0gKiBoYW5kbGVyIFhNTCBvciBIVE1MLCB3aGljaCBpcyBub3Qga25vd24gdW50aWwgYSBsaXR0bGUgbGF0ZXIgd2hlbiB0aGUgZmlyc3QgWE1MCi0gKiB0YWcgaXMgc2Vlbi4gIElmIHRoZSBmaXJzdCB0YWcgaXMgPGh0bWw+IHRoZW4gdGhlIHdyYXBwZWQgb2JqZWN0IGlzIGFuIEhUTUwKLSAqIGhhbmRsZXIsIG90aGVyd2lzZSBpdCBpcyBhbiBYTUwgaGFuZGxlci4KLSAqCi0gKiBUaGlzIGNsYXNzIGVmZmVjdGl2ZWx5IGNhY2hlcyB0aGUgZmlyc3QgZmV3IGNhbGxzIHRvIGl0IHRoZW4gcGFzc2VzIHRoZW0KLSAqIG9uIHRvIHRoZSB3cmFwcGVkIGhhbmRsZXIgKG9uY2UgaXQgZXhpc3RzKS4gIEFmdGVyIHRoYXQgc3Vic2VxdWVudCBjYWxscyBhCi0gKiBzaW1wbHkgcGFzc2VkIGRpcmVjdGx5IHRvIHRoZSB3cmFwcGVkIGhhbmRsZXIuCi0gKgotICogVGhlIHVzZXIgb2YgdGhpcyBjbGFzcyBkb2Vzbid0IGtub3cgaWYgdGhlIG91dHB1dCBpcyB1bHRpbWF0bGV5IFhNTCBvciBIVE1MLgotICoKLSAqIFRoaXMgY2xhc3MgaXMgbm90IGEgcHVibGljIEFQSSwgaXQgaXMgcHVibGljIGJlY2F1c2UgaXQgaXMgdXNlZCB3aXRoaW4gWGFsYW4uCi0gKiBAeHNsLnVzYWdlIGludGVybmFsCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBUb1Vua25vd25TdHJlYW0gZXh0ZW5kcyBTZXJpYWxpemVyQmFzZQotewotCi0gICAgLyoqCi0gICAgICogVGhlIHdyYXBwZWQgaGFuZGxlciwgaW5pdGlhbGx5IFhNTCBidXQgcG9zc2libHkgc3dpdGNoZWQgdG8gSFRNTAotICAgICAqLwotICAgIHByaXZhdGUgU2VyaWFsaXphdGlvbkhhbmRsZXIgbV9oYW5kbGVyOwotCi0gICAgLyoqCi0gICAgICogQSBTdHJpbmcgd2l0aCBubyBjaGFyYWN0ZXJzCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEVNUFRZU1RSSU5HID0gIiI7Ci0KLSAgICAvKioKLSAgICAgKiB0cnVlIGlmIHRoZSB1bmRlcmx5aW5nIGhhbmRsZXIgKFhNTCBvciBIVE1MKSBpcyBmdWxseSBpbml0aWFsaXplZAotICAgICAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBtX3dyYXBwZWRfaGFuZGxlcl9ub3RfaW5pdGlhbGl6ZWQgPSBmYWxzZTsKLQotCi0gICAgLyoqCi0gICAgICogdGhlIHByZWZpeCBvZiB0aGUgdmVyeSBmaXJzdCB0YWcgaW4gdGhlIGRvY3VtZW50Ci0gICAgICovCi0gICAgcHJpdmF0ZSBTdHJpbmcgbV9maXJzdEVsZW1lbnRQcmVmaXg7Ci0gICAgLyoqCi0gICAgICogdGhlIGVsZW1lbnQgbmFtZSAoaW5jbHVkaW5nIGFueSBwcmVmaXgpIG9mIHRoZSB2ZXJ5IGZpcnN0IHRhZyBpbiB0aGUgZG9jdW1lbnQKLSAgICAgKi8KLSAgICBwcml2YXRlIFN0cmluZyBtX2ZpcnN0RWxlbWVudE5hbWU7Ci0KLSAgICAvKioKLSAgICAgKiB0aGUgbmFtZXNwYWNlIFVSSSBhc3NvY2lhdGVkIHdpdGggdGhlIGZpcnN0IGVsZW1lbnQKLSAgICAgKi8KLSAgICBwcml2YXRlIFN0cmluZyBtX2ZpcnN0RWxlbWVudFVSSTsKLQotICAgIC8qKgotICAgICAqIHRoZSBsb2NhbCBuYW1lIChubyBwcmVmaXgpIGFzc29jaWF0ZWQgd2l0aCB0aGUgZmlyc3QgZWxlbWVudAotICAgICAqLwotICAgIHByaXZhdGUgU3RyaW5nIG1fZmlyc3RFbGVtZW50TG9jYWxOYW1lID0gbnVsbDsKLQotICAgIC8qKgotICAgICAqIHRydWUgaWYgdGhlIGZpcnN0IHRhZyBoYXMgYmVlbiBlbWl0dGVkIHRvIHRoZSB3cmFwcGVkIGhhbmRsZXIKLSAgICAgKi8KLSAgICBwcml2YXRlIGJvb2xlYW4gbV9maXJzdFRhZ05vdEVtaXR0ZWQgPSB0cnVlOwotCi0gICAgLyoqCi0gICAgICogQSBjb2xsZWN0aW9uIG9mIG5hbWVzcGFjZSBVUkkncyAob25seSBmb3IgZmlyc3QgZWxlbWVudCkuCi0gICAgICogX25hbWVzcGFjZVByZWZpeCBoYXMgdGhlIG1hdGNoaW5nIHByZWZpeCBmb3IgdGhlc2UgVVJJJ3MKLSAgICAgKi8KLSAgICBwcml2YXRlIFZlY3RvciBtX25hbWVzcGFjZVVSSSA9IG51bGw7Ci0gICAgLyoqCi0gICAgICogQSBjb2xsZWN0aW9uIG9mIG5hbWVzcGFjZSBQcmVmaXggKG9ubHkgZm9yIGZpcnN0IGVsZW1lbnQpCi0gICAgICogX25hbWVzcGFjZVVSSSBoYXMgdGhlIG1hdGNoaW5nIFVSSXMgZm9yIHRoZXNlIHByZWZpeCcKLSAgICAgKi8KLSAgICBwcml2YXRlIFZlY3RvciBtX25hbWVzcGFjZVByZWZpeCA9IG51bGw7Ci0KLSAgICAvKioKLSAgICAgKiB0cnVlIGlmIHN0YXJ0RG9jdW1lbnQoKSB3YXMgY2FsbGVkIGJlZm9yZSB0aGUgdW5kZXJseWluZyBoYW5kbGVyCi0gICAgICogd2FzIGluaXRpYWxpemVkCi0gICAgICovCi0gICAgcHJpdmF0ZSBib29sZWFuIG1fbmVlZFRvQ2FsbFN0YXJ0RG9jdW1lbnQgPSBmYWxzZTsKLSAgICAvKioKLSAgICAgKiB0cnVlIGlmIHNldFZlcnNpb24oKSB3YXMgY2FsbGVkIGJlZm9yZSB0aGUgdW5kZXJseWluZyBoYW5kbGVyCi0gICAgICogd2FzIGluaXRpYWxpemVkCi0gICAgICovCi0gICAgcHJpdmF0ZSBib29sZWFuIG1fc2V0VmVyc2lvbl9jYWxsZWQgPSBmYWxzZTsKLSAgICAvKioKLSAgICAgKiB0cnVlIGlmIHNldERvY3R5cGVTeXN0ZW0oKSB3YXMgY2FsbGVkIGJlZm9yZSB0aGUgdW5kZXJseWluZyBoYW5kbGVyCi0gICAgICogd2FzIGluaXRpYWxpemVkCi0gICAgICovCi0gICAgcHJpdmF0ZSBib29sZWFuIG1fc2V0RG9jdHlwZVN5c3RlbV9jYWxsZWQgPSBmYWxzZTsKLSAgICAvKioKLSAgICAgKiB0cnVlIGlmIHNldERvY3R5cGVQdWJsaWMoKSB3YXMgY2FsbGVkIGJlZm9yZSB0aGUgdW5kZXJseWluZyBoYW5kbGVyCi0gICAgICogd2FzIGluaXRpYWxpemVkCi0gICAgICovCi0gICAgcHJpdmF0ZSBib29sZWFuIG1fc2V0RG9jdHlwZVB1YmxpY19jYWxsZWQgPSBmYWxzZTsKLSAgICAvKioKLSAgICAgKiB0cnVlIGlmIHNldE1lZGlhVHlwZSgpIHdhcyBjYWxsZWQgYmVmb3JlIHRoZSB1bmRlcmx5aW5nIGhhbmRsZXIKLSAgICAgKiB3YXMgaW5pdGlhbGl6ZWQKLSAgICAgKi8KLSAgICBwcml2YXRlIGJvb2xlYW4gbV9zZXRNZWRpYVR5cGVfY2FsbGVkID0gZmFsc2U7Ci0KLSAgICAvKioKLSAgICAgKiBEZWZhdWx0IGNvbnN0cnVjdG9yLgotICAgICAqIEluaXRpYWxseSB0aGlzIG9iamVjdCB3cmFwcyBhbiBYTUwgU3RyZWFtIG9iamVjdCwgc28gX2hhbmRsZXIgaXMgbmV2ZXIgbnVsbC4KLSAgICAgKiBUaGF0IG1heSBjaGFuZ2UgbGF0ZXIgdG8gYW4gSFRNTCBTdHJlYW0gb2JqZWN0LgotICAgICAqLwotICAgIHB1YmxpYyBUb1Vua25vd25TdHJlYW0oKQotICAgIHsKLSAgICAgICAgbV9oYW5kbGVyID0gbmV3IFRvWE1MU3RyZWFtKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBTZXJpYWxpemVyI2FzQ29udGVudEhhbmRsZXIoKQotICAgICAqIEByZXR1cm4gdGhlIHdyYXBwZWQgWE1MIG9yIEhUTUwgaGFuZGxlcgotICAgICAqLwotICAgIHB1YmxpYyBDb250ZW50SGFuZGxlciBhc0NvbnRlbnRIYW5kbGVyKCkgdGhyb3dzIElPRXhjZXB0aW9uCi0gICAgewotICAgICAgICAvKiBkb24ndCByZXR1cm4gdGhlIHJlYWwgaGFuZGxlciAoIG1faGFuZGxlciApIGJlY2F1c2UKLSAgICAgICAgICogdGhhdCB3b3VsZCBleHBvc2UgdGhlIHJlYWwgaGFuZGxlciB0byB0aGUgb3V0c2lkZS4KLSAgICAgICAgICogS2VlcCBtX2hhbmRsZXIgcHJpdmF0ZSBzbyBpdCBjYW4gYmUgaW50ZXJuYWxseSBzd2FwcGVkCi0gICAgICAgICAqIHRvIGFuIEhUTUwgaGFuZGxlci4KLSAgICAgICAgICovCi0gICAgICAgIHJldHVybiB0aGlzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgU2VyaWFsaXphdGlvbkhhbmRsZXIjY2xvc2UoKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkKLSAgICB7Ci0gICAgICAgIG1faGFuZGxlci5jbG9zZSgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgU2VyaWFsaXplciNnZXRPdXRwdXRGb3JtYXQoKQotICAgICAqIEByZXR1cm4gdGhlIHByb3BlcnRpZXMgb2YgdGhlIHVuZGVybHlpbmcgaGFuZGxlcgotICAgICAqLwotICAgIHB1YmxpYyBQcm9wZXJ0aWVzIGdldE91dHB1dEZvcm1hdCgpCi0gICAgewotICAgICAgICByZXR1cm4gbV9oYW5kbGVyLmdldE91dHB1dEZvcm1hdCgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgU2VyaWFsaXplciNnZXRPdXRwdXRTdHJlYW0oKQotICAgICAqIEByZXR1cm4gdGhlIE91dHB1dFN0cmVhbSBvZiB0aGUgdW5kZXJseWluZyBYTUwgb3IgSFRNTCBoYW5kbGVyCi0gICAgICovCi0gICAgcHVibGljIE91dHB1dFN0cmVhbSBnZXRPdXRwdXRTdHJlYW0oKQotICAgIHsKLSAgICAgICAgcmV0dXJuIG1faGFuZGxlci5nZXRPdXRwdXRTdHJlYW0oKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAc2VlIFNlcmlhbGl6ZXIjZ2V0V3JpdGVyKCkKLSAgICAgKiBAcmV0dXJuIHRoZSBXcml0ZXIgb2YgdGhlIHVuZGVybHlpbmcgWE1MIG9yIEhUTUwgaGFuZGxlcgotICAgICAqLwotICAgIHB1YmxpYyBXcml0ZXIgZ2V0V3JpdGVyKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBtX2hhbmRsZXIuZ2V0V3JpdGVyKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogcGFzc2VzIHRoZSBjYWxsIG9uIHRvIHRoZSB1bmRlcmx5aW5nIEhUTUwgb3IgWE1MIGhhbmRsZXIKLSAgICAgKiBAc2VlIFNlcmlhbGl6ZXIjcmVzZXQoKQotICAgICAqIEByZXR1cm4gPz8/Ci0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gcmVzZXQoKQotICAgIHsKLSAgICAgICAgcmV0dXJuIG1faGFuZGxlci5yZXNldCgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbnZlcnRzIHRoZSBET00gbm9kZSB0byBvdXRwdXQKLSAgICAgKiBAcGFyYW0gbm9kZSB0aGUgRE9NIG5vZGUgdG8gdHJhbnNmb3JtIHRvIG91dHB1dAotICAgICAqIEBzZWUgRE9NU2VyaWFsaXplciNzZXJpYWxpemUoTm9kZSkKLSAgICAgKgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNlcmlhbGl6ZShOb2RlIG5vZGUpIHRocm93cyBJT0V4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaWYgKG1fZmlyc3RUYWdOb3RFbWl0dGVkKQotICAgICAgICB7Ci0gICAgICAgICAgICBmbHVzaCgpOwotICAgICAgICB9Ci0gICAgICAgIG1faGFuZGxlci5zZXJpYWxpemUobm9kZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBTZXJpYWxpemF0aW9uSGFuZGxlciNzZXRFc2NhcGluZyhib29sZWFuKQotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIHNldEVzY2FwaW5nKGJvb2xlYW4gZXNjYXBlKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICByZXR1cm4gbV9oYW5kbGVyLnNldEVzY2FwaW5nKGVzY2FwZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSBwcm9wZXJ0aWVzIG9mIHRoZSBoYW5kbGVyCi0gICAgICogQHBhcmFtIGZvcm1hdCB0aGUgb3V0cHV0IHByb3BlcnRpZXMgdG8gc2V0Ci0gICAgICogQHNlZSBTZXJpYWxpemVyI3NldE91dHB1dEZvcm1hdChQcm9wZXJ0aWVzKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldE91dHB1dEZvcm1hdChQcm9wZXJ0aWVzIGZvcm1hdCkKLSAgICB7Ci0gICAgICAgIG1faGFuZGxlci5zZXRPdXRwdXRGb3JtYXQoZm9ybWF0KTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSBvdXRwdXQgc3RyZWFtIHRvIHdyaXRlIHRvCi0gICAgICogQHBhcmFtIG91dHB1dCB0aGUgT3V0cHV0U3RyZWFtIHRvIHdyaXRlIHRvCi0gICAgICogQHNlZSBTZXJpYWxpemVyI3NldE91dHB1dFN0cmVhbShPdXRwdXRTdHJlYW0pCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0T3V0cHV0U3RyZWFtKE91dHB1dFN0cmVhbSBvdXRwdXQpCi0gICAgewotICAgICAgICBtX2hhbmRsZXIuc2V0T3V0cHV0U3RyZWFtKG91dHB1dCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0cyB0aGUgd3JpdGVyIHRvIHdyaXRlIHRvCi0gICAgICogQHBhcmFtIHdyaXRlciB0aGUgd3JpdGVyIHRvIHdyaXRlIHRvCi0gICAgICogQHNlZSBTZXJpYWxpemVyI3NldFdyaXRlcihXcml0ZXIpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0V3JpdGVyKFdyaXRlciB3cml0ZXIpCi0gICAgewotICAgICAgICBtX2hhbmRsZXIuc2V0V3JpdGVyKHdyaXRlcik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQWRkcyBhbiBhdHRyaWJ1dGUgdG8gdGhlIGN1cnJlbmx5IG9wZW4gdGFnCi0gICAgICogQHBhcmFtIHVyaSB0aGUgVVJJIG9mIGEgbmFtZXNwYWNlCi0gICAgICogQHBhcmFtIGxvY2FsTmFtZSB0aGUgYXR0cmlidXRlIG5hbWUsIHdpdGhvdXQgcHJlZml4Ci0gICAgICogQHBhcmFtIHJhd05hbWUgdGhlIGF0dHJpYnV0ZSBuYW1lLCB3aXRoIHByZWZpeCAoaWYgYW55KQotICAgICAqIEBwYXJhbSB0eXBlIHRoZSB0eXBlIG9mIHRoZSBhdHRyaWJ1dGUsIHR5cGljYWxseSAiQ0RBVEEiCi0gICAgICogQHBhcmFtIHZhbHVlIHRoZSB2YWx1ZSBvZiB0aGUgcGFyYW1ldGVyCi0gICAgICogQHBhcmFtIFhTTEF0dHJpYnV0ZSB0cnVlIGlmIHRoaXMgYXR0cmlidXRlIGlzIGNvbWluZyBmcm9tIGFuIHhzbDphdHRyaWJ1dGUgZWxlbWVudAotICAgICAqIEBzZWUgRXh0ZW5kZWRDb250ZW50SGFuZGxlciNhZGRBdHRyaWJ1dGUoU3RyaW5nLCBTdHJpbmcsIFN0cmluZywgU3RyaW5nLCBTdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgYWRkQXR0cmlidXRlKAotICAgICAgICBTdHJpbmcgdXJpLAotICAgICAgICBTdHJpbmcgbG9jYWxOYW1lLAotICAgICAgICBTdHJpbmcgcmF3TmFtZSwKLSAgICAgICAgU3RyaW5nIHR5cGUsCi0gICAgICAgIFN0cmluZyB2YWx1ZSkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgYWRkQXR0cmlidXRlKHVyaSwgbG9jYWxOYW1lLCByYXdOYW1lLCB0eXBlLCB2YWx1ZSwgZmFsc2UpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEFkZHMgYW4gYXR0cmlidXRlIHRvIHRoZSBjdXJyZW5seSBvcGVuIHRhZwotICAgICAqIEBwYXJhbSB1cmkgdGhlIFVSSSBvZiBhIG5hbWVzcGFjZQotICAgICAqIEBwYXJhbSBsb2NhbE5hbWUgdGhlIGF0dHJpYnV0ZSBuYW1lLCB3aXRob3V0IHByZWZpeAotICAgICAqIEBwYXJhbSByYXdOYW1lIHRoZSBhdHRyaWJ1dGUgbmFtZSwgd2l0aCBwcmVmaXggKGlmIGFueSkKLSAgICAgKiBAcGFyYW0gdHlwZSB0aGUgdHlwZSBvZiB0aGUgYXR0cmlidXRlLCB0eXBpY2FsbHkgIkNEQVRBIgotICAgICAqIEBwYXJhbSB2YWx1ZSB0aGUgdmFsdWUgb2YgdGhlIHBhcmFtZXRlcgotICAgICAqIEBwYXJhbSBYU0xBdHRyaWJ1dGUgdHJ1ZSBpZiB0aGlzIGF0dHJpYnV0ZSBpcyBjb21pbmcgZnJvbSBhbiB4c2w6YXR0cmlidXRlIGVsZW1lbnQKLSAgICAgKiBAc2VlIEV4dGVuZGVkQ29udGVudEhhbmRsZXIjYWRkQXR0cmlidXRlKFN0cmluZywgU3RyaW5nLCBTdHJpbmcsIFN0cmluZywgU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGFkZEF0dHJpYnV0ZSgKLSAgICAgICAgU3RyaW5nIHVyaSwKLSAgICAgICAgU3RyaW5nIGxvY2FsTmFtZSwKLSAgICAgICAgU3RyaW5nIHJhd05hbWUsCi0gICAgICAgIFN0cmluZyB0eXBlLAotICAgICAgICBTdHJpbmcgdmFsdWUsCi0gICAgICAgIGJvb2xlYW4gWFNMQXR0cmlidXRlKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAobV9maXJzdFRhZ05vdEVtaXR0ZWQpCi0gICAgICAgIHsKLSAgICAgICAgICAgIGZsdXNoKCk7Ci0gICAgICAgIH0KLSAgICAgICAgbV9oYW5kbGVyLmFkZEF0dHJpYnV0ZSh1cmksIGxvY2FsTmFtZSwgcmF3TmFtZSwgdHlwZSwgdmFsdWUsIFhTTEF0dHJpYnV0ZSk7Ci0gICAgfQotICAgIC8qKgotICAgICAqIEFkZHMgYW4gYXR0cmlidXRlIHRvIHRoZSBjdXJyZW5seSBvcGVuIHRhZwotICAgICAqIEBwYXJhbSByYXdOYW1lIHRoZSBhdHRyaWJ1dGUgbmFtZSwgd2l0aCBwcmVmaXggKGlmIGFueSkKLSAgICAgKiBAcGFyYW0gdmFsdWUgdGhlIHZhbHVlIG9mIHRoZSBwYXJhbWV0ZXIKLSAgICAgKiBAc2VlIEV4dGVuZGVkQ29udGVudEhhbmRsZXIjYWRkQXR0cmlidXRlKFN0cmluZywgU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGFkZEF0dHJpYnV0ZShTdHJpbmcgcmF3TmFtZSwgU3RyaW5nIHZhbHVlKQotICAgIHsKLSAgICAgICAgaWYgKG1fZmlyc3RUYWdOb3RFbWl0dGVkKQotICAgICAgICB7Ci0gICAgICAgICAgICBmbHVzaCgpOwotICAgICAgICB9Ci0gICAgICAgIG1faGFuZGxlci5hZGRBdHRyaWJ1dGUocmF3TmFtZSwgdmFsdWUpOwotCi0gICAgfQotCi0gICAgLyoqCi0gICAgICogQWRkcyBhIHVuaXF1ZSBhdHRyaWJ1dGUgdG8gdGhlIGN1cnJlbmx5IG9wZW4gdGFnCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgYWRkVW5pcXVlQXR0cmlidXRlKFN0cmluZyByYXdOYW1lLCBTdHJpbmcgdmFsdWUsIGludCBmbGFncykKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaWYgKG1fZmlyc3RUYWdOb3RFbWl0dGVkKQotICAgICAgICB7Ci0gICAgICAgICAgICBmbHVzaCgpOwotICAgICAgICB9Ci0gICAgICAgIG1faGFuZGxlci5hZGRVbmlxdWVBdHRyaWJ1dGUocmF3TmFtZSwgdmFsdWUsIGZsYWdzKTsKLQotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbnZlcnRzIHRoZSBTdHJpbmcgdG8gYSBjaGFyYWN0ZXIgYXJyYXkgYW5kIGNhbGxzIHRoZSBTQVggbWV0aG9kCi0gICAgICogY2hhcmFjdGVycyhjaGFyW10saW50LGludCk7Ci0gICAgICoKLSAgICAgKiBAc2VlIEV4dGVuZGVkQ29udGVudEhhbmRsZXIjY2hhcmFjdGVycyhTdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY2hhcmFjdGVycyhTdHJpbmcgY2hhcnMpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGZpbmFsIGludCBsZW5ndGggPSBjaGFycy5sZW5ndGgoKTsKLSAgICAgICAgaWYgKGxlbmd0aCA+IG1fY2hhcnNCdWZmLmxlbmd0aCkKLSAgICAgICAgewotICAgICAgICAgICAgbV9jaGFyc0J1ZmYgPSBuZXcgY2hhcltsZW5ndGgqMiArIDFdOwotICAgICAgICB9Ci0gICAgICAgIGNoYXJzLmdldENoYXJzKDAsIGxlbmd0aCwgbV9jaGFyc0J1ZmYsIDApOwotICAgICAgICB0aGlzLmNoYXJhY3RlcnMobV9jaGFyc0J1ZmYsIDAsIGxlbmd0aCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUGFzcyB0aGUgY2FsbCBvbiB0byB0aGUgdW5kZXJseWluZyBoYW5kbGVyCi0gICAgICogQHNlZSBFeHRlbmRlZENvbnRlbnRIYW5kbGVyI2VuZEVsZW1lbnQoU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZEVsZW1lbnQoU3RyaW5nIGVsZW1lbnROYW1lKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAobV9maXJzdFRhZ05vdEVtaXR0ZWQpCi0gICAgICAgIHsKLSAgICAgICAgICAgIGZsdXNoKCk7Ci0gICAgICAgIH0KLSAgICAgICAgbV9oYW5kbGVyLmVuZEVsZW1lbnQoZWxlbWVudE5hbWUpOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNzdGFydFByZWZpeE1hcHBpbmcoU3RyaW5nLCBTdHJpbmcpCi0gICAgICogQHBhcmFtIHByZWZpeCBUaGUgcHJlZml4IHRoYXQgbWFwcyB0byB0aGUgVVJJCi0gICAgICogQHBhcmFtIHVyaSBUaGUgVVJJIGZvciB0aGUgbmFtZXNwYWNlCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnRQcmVmaXhNYXBwaW5nKFN0cmluZyBwcmVmaXgsIFN0cmluZyB1cmkpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIHRoaXMuc3RhcnRQcmVmaXhNYXBwaW5nKHByZWZpeCx1cmksIHRydWUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIGlzIHVzZWQgd2hlbiBhIHByZWZpeC91cmkgbmFtZXNwYWNlIG1hcHBpbmcKLSAgICAgKiBpcyBpbmRpY2F0ZWQgYWZ0ZXIgdGhlIGVsZW1lbnQgd2FzIHN0YXJ0ZWQgd2l0aCBhCi0gICAgICogc3RhcnRFbGVtZW50KCkgYW5kIGJlZm9yZSBhbmQgZW5kRWxlbWVudCgpLgotICAgICAqIHN0YXJ0UHJlZml4TWFwcGluZyhwcmVmaXgsdXJpKSB3b3VsZCBiZSB1c2VkIGJlZm9yZSB0aGUKLSAgICAgKiBzdGFydEVsZW1lbnQoKSBjYWxsLgotICAgICAqIEBwYXJhbSB1cmkgdGhlIFVSSSBvZiB0aGUgbmFtZXNwYWNlCi0gICAgICogQHBhcmFtIHByZWZpeCB0aGUgcHJlZml4IGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gVVJJLgotICAgICAqCi0gICAgICogQHNlZSBFeHRlbmRlZENvbnRlbnRIYW5kbGVyI25hbWVzcGFjZUFmdGVyU3RhcnRFbGVtZW50KFN0cmluZywgU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIG5hbWVzcGFjZUFmdGVyU3RhcnRFbGVtZW50KFN0cmluZyBwcmVmaXgsIFN0cmluZyB1cmkpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIC8vIGhhY2sgZm9yIFhTTFRDIHdpdGggZmluZGluZyBVUkkgZm9yIGRlZmF1bHQgbmFtZXNwYWNlCi0gICAgICAgIGlmIChtX2ZpcnN0VGFnTm90RW1pdHRlZCAmJiBtX2ZpcnN0RWxlbWVudFVSSSA9PSBudWxsICYmIG1fZmlyc3RFbGVtZW50TmFtZSAhPSBudWxsKQotICAgICAgICB7Ci0gICAgICAgICAgICBTdHJpbmcgcHJlZml4MSA9IGdldFByZWZpeFBhcnQobV9maXJzdEVsZW1lbnROYW1lKTsKLSAgICAgICAgICAgIGlmIChwcmVmaXgxID09IG51bGwgJiYgRU1QVFlTVFJJTkcuZXF1YWxzKHByZWZpeCkpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgLy8gdGhlIGVsZW1lbnRzIFVSSSBpcyBub3Qga25vd24geWV0LCBhbmQgaXQKLSAgICAgICAgICAgICAgICAvLyBkb2Vzbid0IGhhdmUgYSBwcmVmaXgsIGFuZCB3ZSBhcmUgY3VycmVudGx5Ci0gICAgICAgICAgICAgICAgLy8gc2V0dGluZyB0aGUgdXJpIGZvciBwcmVmaXggIiIsIHNvIHdlIGhhdmUKLSAgICAgICAgICAgICAgICAvLyB0aGUgdXJpIGZvciB0aGUgZWxlbWVudC4uLiBsZXRzIHJlbWVtYmVyIGl0Ci0gICAgICAgICAgICAgICAgbV9maXJzdEVsZW1lbnRVUkkgPSB1cmk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgc3RhcnRQcmVmaXhNYXBwaW5nKHByZWZpeCx1cmksIGZhbHNlKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBzdGFydFByZWZpeE1hcHBpbmcoU3RyaW5nIHByZWZpeCwgU3RyaW5nIHVyaSwgYm9vbGVhbiBzaG91bGRGbHVzaCkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgYm9vbGVhbiBwdXNoZWQgPSBmYWxzZTsKLSAgICAgICAgaWYgKG1fZmlyc3RUYWdOb3RFbWl0dGVkKQotICAgICAgICB7Ci0gICAgICAgICAgICBpZiAobV9maXJzdEVsZW1lbnROYW1lICE9IG51bGwgJiYgc2hvdWxkRmx1c2gpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgLyogd2UndmUgYWxyZWFkeSBzZWVuIGEgc3RhcnRFbGVtZW50LCBhbmQgdGhpcyBpcyBhIHByZWZpeCBtYXBwaW5nCi0gICAgICAgICAgICAgICAgICogZm9yIHRoZSB1cCBjb21pbmcgZWxlbWVudCwgc28gZmx1c2ggdGhlIG9sZCBlbGVtZW50Ci0gICAgICAgICAgICAgICAgICogdGhlbiBzZW5kIHRoaXMgZXZlbnQgb24gaXRzIHdheS4KLSAgICAgICAgICAgICAgICAgKi8KLSAgICAgICAgICAgICAgICBmbHVzaCgpOwotICAgICAgICAgICAgICAgIHB1c2hlZCA9IG1faGFuZGxlci5zdGFydFByZWZpeE1hcHBpbmcocHJlZml4LCB1cmksIHNob3VsZEZsdXNoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBpZiAobV9uYW1lc3BhY2VQcmVmaXggPT0gbnVsbCkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIG1fbmFtZXNwYWNlUHJlZml4ID0gbmV3IFZlY3RvcigpOwotICAgICAgICAgICAgICAgICAgICBtX25hbWVzcGFjZVVSSSA9IG5ldyBWZWN0b3IoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgbV9uYW1lc3BhY2VQcmVmaXguYWRkRWxlbWVudChwcmVmaXgpOwotICAgICAgICAgICAgICAgIG1fbmFtZXNwYWNlVVJJLmFkZEVsZW1lbnQodXJpKTsKLQotICAgICAgICAgICAgICAgIGlmIChtX2ZpcnN0RWxlbWVudFVSSSA9PSBudWxsKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKHByZWZpeC5lcXVhbHMobV9maXJzdEVsZW1lbnRQcmVmaXgpKQotICAgICAgICAgICAgICAgICAgICAgICAgbV9maXJzdEVsZW1lbnRVUkkgPSB1cmk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICB7Ci0gICAgICAgICAgIHB1c2hlZCA9IG1faGFuZGxlci5zdGFydFByZWZpeE1hcHBpbmcocHJlZml4LCB1cmksIHNob3VsZEZsdXNoKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gcHVzaGVkOwotICAgIH0KLQotICAgIC8qKgotICAgICAgKiBUaGlzIG1ldGhvZCBjYW5ub3QgYmUgY2FjaGVkIGJlY2F1c2UgZGVmYXVsdCBpcyBkaWZmZXJlbnQgaW4KLSAgICAgICogSFRNTCBhbmQgWE1MICh3ZSBuZWVkIG1vcmUgdGhhbiBhIGJvb2xlYW4pLgotICAgICAgKi8KLQotICAgIHB1YmxpYyB2b2lkIHNldFZlcnNpb24oU3RyaW5nIHZlcnNpb24pCi0gICAgewotICAgICAgICBtX2hhbmRsZXIuc2V0VmVyc2lvbih2ZXJzaW9uKTsKLQotICAgICAgICAvLyBDYWNoZSBjYWxsIHRvIHNldFZlcnNpb24oKQotICAgICAgICAvLyAgICAgICBzdXBlci5zZXRWZXJzaW9uKHZlcnNpb24pOwotICAgICAgICBtX3NldFZlcnNpb25fY2FsbGVkID0gdHJ1ZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI3N0YXJ0RG9jdW1lbnQoKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RG9jdW1lbnQoKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBtX25lZWRUb0NhbGxTdGFydERvY3VtZW50ID0gdHJ1ZTsKLSAgICB9Ci0KLQotCi0gICAgcHVibGljIHZvaWQgc3RhcnRFbGVtZW50KFN0cmluZyBxTmFtZSkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgdGhpcy5zdGFydEVsZW1lbnQobnVsbCwgbnVsbCwgcU5hbWUsIG51bGwpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudChTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgbG9jYWxOYW1lLCBTdHJpbmcgcU5hbWUpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIHRoaXMuc3RhcnRFbGVtZW50KG5hbWVzcGFjZVVSSSwgbG9jYWxOYW1lLCBxTmFtZSwgbnVsbCk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc3RhcnRFbGVtZW50KAotICAgICAgICBTdHJpbmcgbmFtZXNwYWNlVVJJLAotICAgICAgICBTdHJpbmcgbG9jYWxOYW1lLAotICAgICAgICBTdHJpbmcgZWxlbWVudE5hbWUsCi0gICAgICAgIEF0dHJpYnV0ZXMgYXR0cykgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLQotICAgICAgICBpZiAobV9uZWVkVG9DYWxsU2V0RG9jdW1lbnRJbmZvKXsKLSAgICAgICAgICAgIHN1cGVyLnNldERvY3VtZW50SW5mbygpOwotICAgICAgICAgICAgbV9uZWVkVG9DYWxsU2V0RG9jdW1lbnRJbmZvID0gZmFsc2U7Ci0gICAgICAgIH0KLQotICAgICAgICAvKiB3ZSBhcmUgbm90aWZpZWQgb2YgdGhlIHN0YXJ0IG9mIGFuIGVsZW1lbnQgKi8KLSAgICAgICAgaWYgKG1fZmlyc3RUYWdOb3RFbWl0dGVkKQotICAgICAgICB7Ci0gICAgICAgICAgICAvKiB3ZSBoYXZlIG5vdCB5ZXQgc2VudCB0aGUgZmlyc3QgZWxlbWVudCBvbiBpdHMgd2F5ICovCi0gICAgICAgICAgICBpZiAobV9maXJzdEVsZW1lbnROYW1lICE9IG51bGwpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgLyogdGhpcyBpcyBub3QgdGhlIGZpcnN0IGVsZW1lbnQsIGJ1dCBhIGxhdGVyIG9uZS4KLSAgICAgICAgICAgICAgICAgKiBCdXQgd2UgaGF2ZSB0aGUgb2xkIGVsZW1lbnQgcGVuZGluZywgc28gZmx1c2ggaXQgb3V0LAotICAgICAgICAgICAgICAgICAqIHRoZW4gc2VuZCB0aGlzIG9uZSBvbiBpdHMgd2F5LgotICAgICAgICAgICAgICAgICAqLwotICAgICAgICAgICAgICAgIGZsdXNoKCk7Ci0gICAgICAgICAgICAgICAgbV9oYW5kbGVyLnN0YXJ0RWxlbWVudChuYW1lc3BhY2VVUkksIGxvY2FsTmFtZSwgZWxlbWVudE5hbWUsICBhdHRzKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAvKiB0aGlzIGlzIHRoZSB2ZXJ5IGZpcnN0IGVsZW1lbnQgdGhhdCB3ZSBoYXZlIHNlZW4sCi0gICAgICAgICAgICAgICAgICogc28gc2F2ZSBpdCBmb3IgZmx1c2hpbmcgbGF0ZXIuICBXZSBtYXkgeWV0IGdldCB0byBrbm93IGl0cwotICAgICAgICAgICAgICAgICAqIFVSSSBkdWUgdG8gYWRkZWQgYXR0cmlidXRlcy4KLSAgICAgICAgICAgICAgICAgKi8KLQotICAgICAgICAgICAgICAgIG1fd3JhcHBlZF9oYW5kbGVyX25vdF9pbml0aWFsaXplZCA9IHRydWU7Ci0gICAgICAgICAgICAgICAgbV9maXJzdEVsZW1lbnROYW1lID0gZWxlbWVudE5hbWU7Ci0KLSAgICAgICAgICAgICAgICAvLyBudWxsIGlmIG5vdCBrbm93bgotICAgICAgICAgICAgICAgIG1fZmlyc3RFbGVtZW50UHJlZml4ID0gZ2V0UHJlZml4UGFydFVua25vd24oZWxlbWVudE5hbWUpOwotCi0gICAgICAgICAgICAgICAgLy8gbnVsbCBpZiBub3Qga25vd24KLSAgICAgICAgICAgICAgICBtX2ZpcnN0RWxlbWVudFVSSSA9IG5hbWVzcGFjZVVSSTsKLQotICAgICAgICAgICAgICAgIC8vIG51bGwgaWYgbm90IGtub3duCi0gICAgICAgICAgICAgICAgbV9maXJzdEVsZW1lbnRMb2NhbE5hbWUgPSBsb2NhbE5hbWU7Ci0KLSAgICAgICAgICAgICAgICBpZiAobV90cmFjZXIgIT0gbnVsbCkKLSAgICAgICAgICAgICAgICAgICAgZmlyZVBzZXVkb0VsZW1lbnQoZWxlbWVudE5hbWUpOwotCi0gICAgICAgICAgICAgICAgLyogd2UgZG9uJ3Qgd2FudCB0byBjYWxsIG91ciBvd24gYWRkQXR0cmlidXRlcywgd2hpY2gKLSAgICAgICAgICAgICAgICAgKiBtZXJlbHkgZGVsZWdhdGVzIHRvIHRoZSB3cmFwcGVkIGhhbmRsZXIsIGJ1dCB3ZSB3YW50IHRvCi0gICAgICAgICAgICAgICAgICogYWRkIHRoZXNlIGF0dHJpYnV0ZXMgdG8gbV9hdHRyaWJ1dGVzLiBTbyBtZSBtdXN0IGNhbGwgc3VwZXIuCi0gICAgICAgICAgICAgICAgICogYWRkQXR0cmlidXRlcygpIEluIHRoaXMgY2FzZSBtX2F0dHJpYnV0ZXMgaXMgb25seSB1c2VkIGZvciB0aGUKLSAgICAgICAgICAgICAgICAgKiBmaXJzdCBlbGVtZW50LCBhZnRlciB0aGF0IHRoaXMgY2xhc3MgdG90YWxseSBkZWxlZ2F0ZXMgdG8gdGhlCi0gICAgICAgICAgICAgICAgICogd3JhcHBlZCBoYW5kbGVyIHdoaWNoIGlzIGVpdGhlciBYTUwgb3IgSFRNTC4KLSAgICAgICAgICAgICAgICAgKi8KLSAgICAgICAgICAgICAgICBpZiAoYXR0cyAhPSBudWxsKQotICAgICAgICAgICAgICAgICAgICBzdXBlci5hZGRBdHRyaWJ1dGVzKGF0dHMpOwotCi0gICAgICAgICAgICAgICAgLy8gaWYgdGhlcmUgYXJlIGF0dHJpYnV0ZXMsIHRoZW4gbGV0cyBtYWtlIHRoZSBmbHVzaCgpCi0gICAgICAgICAgICAgICAgLy8gY2FsbCB0aGUgc3RhcnRFbGVtZW50IG9uIHRoZSBoYW5kbGVyIGFuZCBzZW5kIHRoZQotICAgICAgICAgICAgICAgIC8vIGF0dHJpYnV0ZXMgb24gdGhlaXIgd2F5LgotICAgICAgICAgICAgICAgIGlmIChhdHRzICE9IG51bGwpCi0gICAgICAgICAgICAgICAgICAgIGZsdXNoKCk7Ci0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgIHsKLSAgICAgICAgICAgIC8vIHRoaXMgaXMgbm90IHRoZSBmaXJzdCBlbGVtZW50LCBidXQgYSBsYXRlciBvbmUsIHNvIGp1c3QKLSAgICAgICAgICAgIC8vIHNlbmQgaXQgb24gaXRzIHdheS4KLSAgICAgICAgICAgIG1faGFuZGxlci5zdGFydEVsZW1lbnQobmFtZXNwYWNlVVJJLCBsb2NhbE5hbWUsIGVsZW1lbnROYW1lLCAgYXR0cyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBQYXNzIHRoZSBjYWxsIG9uIHRvIHRoZSB1bmRlcmx5aW5nIGhhbmRsZXIKLSAgICAgKiBAc2VlIEV4dGVuZGVkTGV4aWNhbEhhbmRsZXIjY29tbWVudChTdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY29tbWVudChTdHJpbmcgY29tbWVudCkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaWYgKG1fZmlyc3RUYWdOb3RFbWl0dGVkICYmIG1fZmlyc3RFbGVtZW50TmFtZSAhPSBudWxsKQotICAgICAgICB7Ci0gICAgICAgICAgICBlbWl0Rmlyc3RUYWcoKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChtX25lZWRUb0NhbGxTdGFydERvY3VtZW50KQotICAgICAgICB7Ci0gICAgICAgICAgICBtX2hhbmRsZXIuc3RhcnREb2N1bWVudCgpOwotICAgICAgICAgICAgbV9uZWVkVG9DYWxsU3RhcnREb2N1bWVudCA9IGZhbHNlOwotICAgICAgICB9Ci0KLSAgICAgICAgbV9oYW5kbGVyLmNvbW1lbnQoY29tbWVudCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUGFzcyB0aGUgY2FsbCBvbiB0byB0aGUgdW5kZXJseWluZyBoYW5kbGVyCi0gICAgICogQHNlZSBYU0xPdXRwdXRBdHRyaWJ1dGVzI2dldERvY3R5cGVQdWJsaWMoKQotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0RG9jdHlwZVB1YmxpYygpCi0gICAgewotCi0gICAgICAgIHJldHVybiBtX2hhbmRsZXIuZ2V0RG9jdHlwZVB1YmxpYygpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFBhc3MgdGhlIGNhbGwgb24gdG8gdGhlIHVuZGVybHlpbmcgaGFuZGxlcgotICAgICAqIEBzZWUgWFNMT3V0cHV0QXR0cmlidXRlcyNnZXREb2N0eXBlU3lzdGVtKCkKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldERvY3R5cGVTeXN0ZW0oKQotICAgIHsKLSAgICAgICAgcmV0dXJuIG1faGFuZGxlci5nZXREb2N0eXBlU3lzdGVtKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUGFzcyB0aGUgY2FsbCBvbiB0byB0aGUgdW5kZXJseWluZyBoYW5kbGVyCi0gICAgICogQHNlZSBYU0xPdXRwdXRBdHRyaWJ1dGVzI2dldEVuY29kaW5nKCkKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEVuY29kaW5nKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBtX2hhbmRsZXIuZ2V0RW5jb2RpbmcoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBQYXNzIHRoZSBjYWxsIG9uIHRvIHRoZSB1bmRlcmx5aW5nIGhhbmRsZXIKLSAgICAgKiBAc2VlIFhTTE91dHB1dEF0dHJpYnV0ZXMjZ2V0SW5kZW50KCkKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXRJbmRlbnQoKQotICAgIHsKLSAgICAgICAgcmV0dXJuIG1faGFuZGxlci5nZXRJbmRlbnQoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBQYXNzIHRoZSBjYWxsIG9uIHRvIHRoZSB1bmRlcmx5aW5nIGhhbmRsZXIKLSAgICAgKiBAc2VlIFhTTE91dHB1dEF0dHJpYnV0ZXMjZ2V0SW5kZW50QW1vdW50KCkKLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldEluZGVudEFtb3VudCgpCi0gICAgewotICAgICAgICByZXR1cm4gbV9oYW5kbGVyLmdldEluZGVudEFtb3VudCgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFBhc3MgdGhlIGNhbGwgb24gdG8gdGhlIHVuZGVybHlpbmcgaGFuZGxlcgotICAgICAqIEBzZWUgWFNMT3V0cHV0QXR0cmlidXRlcyNnZXRNZWRpYVR5cGUoKQotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TWVkaWFUeXBlKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBtX2hhbmRsZXIuZ2V0TWVkaWFUeXBlKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUGFzcyB0aGUgY2FsbCBvbiB0byB0aGUgdW5kZXJseWluZyBoYW5kbGVyCi0gICAgICogQHNlZSBYU0xPdXRwdXRBdHRyaWJ1dGVzI2dldE9taXRYTUxEZWNsYXJhdGlvbigpCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0T21pdFhNTERlY2xhcmF0aW9uKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBtX2hhbmRsZXIuZ2V0T21pdFhNTERlY2xhcmF0aW9uKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUGFzcyB0aGUgY2FsbCBvbiB0byB0aGUgdW5kZXJseWluZyBoYW5kbGVyCi0gICAgICogQHNlZSBYU0xPdXRwdXRBdHRyaWJ1dGVzI2dldFN0YW5kYWxvbmUoKQotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3RhbmRhbG9uZSgpCi0gICAgewotICAgICAgICByZXR1cm4gbV9oYW5kbGVyLmdldFN0YW5kYWxvbmUoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBQYXNzIHRoZSBjYWxsIG9uIHRvIHRoZSB1bmRlcmx5aW5nIGhhbmRsZXIKLSAgICAgKiBAc2VlIFhTTE91dHB1dEF0dHJpYnV0ZXMjZ2V0VmVyc2lvbigpCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRWZXJzaW9uKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBtX2hhbmRsZXIuZ2V0VmVyc2lvbigpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgWFNMT3V0cHV0QXR0cmlidXRlcyNzZXREb2N0eXBlKFN0cmluZywgU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldERvY3R5cGUoU3RyaW5nIHN5c3RlbSwgU3RyaW5nIHB1YikKLSAgICB7Ci0gICAgICAgIG1faGFuZGxlci5zZXREb2N0eXBlUHVibGljKHB1Yik7Ci0gICAgICAgIG1faGFuZGxlci5zZXREb2N0eXBlU3lzdGVtKHN5c3RlbSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSBkb2N0eXBlIGluIHRoZSB1bmRlcmx5aW5nIFhNTCBoYW5kbGVyLiBSZW1lbWJlciB0aGF0IHRoaXMgbWV0aG9kCi0gICAgICogd2FzIGNhbGxlZCwganVzdCBpbiBjYXNlIHdlIG5lZWQgdG8gdHJhbnNmZXIgdGhpcyBkb2N0eXBlIHRvIGFuIEhUTUwgaGFuZGxlcgotICAgICAqIEBwYXJhbSBkb2N0eXBlIHRoZSBwdWJsaWMgZG9jdHlwZSB0byBzZXQKLSAgICAgKiBAc2VlIFhTTE91dHB1dEF0dHJpYnV0ZXMjc2V0RG9jdHlwZVB1YmxpYyhTdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RG9jdHlwZVB1YmxpYyhTdHJpbmcgZG9jdHlwZSkKLSAgICB7Ci0gICAgICAgIG1faGFuZGxlci5zZXREb2N0eXBlUHVibGljKGRvY3R5cGUpOwotICAgICAgICBtX3NldERvY3R5cGVQdWJsaWNfY2FsbGVkID0gdHJ1ZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIGRvY3R5cGUgaW4gdGhlIHVuZGVybHlpbmcgWE1MIGhhbmRsZXIuIFJlbWVtYmVyIHRoYXQgdGhpcyBtZXRob2QKLSAgICAgKiB3YXMgY2FsbGVkLCBqdXN0IGluIGNhc2Ugd2UgbmVlZCB0byB0cmFuc2ZlciB0aGlzIGRvY3R5cGUgdG8gYW4gSFRNTCBoYW5kbGVyCi0gICAgICogQHBhcmFtIGRvY3R5cGUgdGhlIHN5c3RlbSBkb2N0eXBlIHRvIHNldAotICAgICAqIEBzZWUgWFNMT3V0cHV0QXR0cmlidXRlcyNzZXREb2N0eXBlU3lzdGVtKFN0cmluZykKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXREb2N0eXBlU3lzdGVtKFN0cmluZyBkb2N0eXBlKQotICAgIHsKLSAgICAgICAgbV9oYW5kbGVyLnNldERvY3R5cGVTeXN0ZW0oZG9jdHlwZSk7Ci0gICAgICAgIG1fc2V0RG9jdHlwZVN5c3RlbV9jYWxsZWQgPSB0cnVlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFBhc3MgdGhlIGNhbGwgb24gdG8gdGhlIHVuZGVybHlpbmcgaGFuZGxlcgotICAgICAqIEBzZWUgWFNMT3V0cHV0QXR0cmlidXRlcyNzZXRFbmNvZGluZyhTdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RW5jb2RpbmcoU3RyaW5nIGVuY29kaW5nKQotICAgIHsKLSAgICAgICAgbV9oYW5kbGVyLnNldEVuY29kaW5nKGVuY29kaW5nKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBQYXNzIHRoZSBjYWxsIG9uIHRvIHRoZSB1bmRlcmx5aW5nIGhhbmRsZXIKLSAgICAgKiBAc2VlIFhTTE91dHB1dEF0dHJpYnV0ZXMjc2V0SW5kZW50KGJvb2xlYW4pCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0SW5kZW50KGJvb2xlYW4gaW5kZW50KQotICAgIHsKLSAgICAgICAgbV9oYW5kbGVyLnNldEluZGVudChpbmRlbnQpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFBhc3MgdGhlIGNhbGwgb24gdG8gdGhlIHVuZGVybHlpbmcgaGFuZGxlcgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEluZGVudEFtb3VudChpbnQgdmFsdWUpCi0gICAgewotICAgICAgICBtX2hhbmRsZXIuc2V0SW5kZW50QW1vdW50KHZhbHVlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAc2VlIFhTTE91dHB1dEF0dHJpYnV0ZXMjc2V0TWVkaWFUeXBlKFN0cmluZykKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRNZWRpYVR5cGUoU3RyaW5nIG1lZGlhVHlwZSkKLSAgICB7Ci0gICAgICAgIG1faGFuZGxlci5zZXRNZWRpYVR5cGUobWVkaWFUeXBlKTsKLSAgICAgICAgbV9zZXRNZWRpYVR5cGVfY2FsbGVkID0gdHJ1ZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBQYXNzIHRoZSBjYWxsIG9uIHRvIHRoZSB1bmRlcmx5aW5nIGhhbmRsZXIKLSAgICAgKiBAc2VlIFhTTE91dHB1dEF0dHJpYnV0ZXMjc2V0T21pdFhNTERlY2xhcmF0aW9uKGJvb2xlYW4pCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0T21pdFhNTERlY2xhcmF0aW9uKGJvb2xlYW4gYikKLSAgICB7Ci0gICAgICAgIG1faGFuZGxlci5zZXRPbWl0WE1MRGVjbGFyYXRpb24oYik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUGFzcyB0aGUgY2FsbCBvbiB0byB0aGUgdW5kZXJseWluZyBoYW5kbGVyCi0gICAgICogQHNlZSBYU0xPdXRwdXRBdHRyaWJ1dGVzI3NldFN0YW5kYWxvbmUoU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFN0YW5kYWxvbmUoU3RyaW5nIHN0YW5kYWxvbmUpCi0gICAgewotICAgICAgICBtX2hhbmRsZXIuc2V0U3RhbmRhbG9uZShzdGFuZGFsb25lKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAc2VlIFhTTE91dHB1dEF0dHJpYnV0ZXMjc2V0VmVyc2lvbihTdHJpbmcpCi0gICAgICovCi0KLSAgICAvKioKLSAgICAgKiBQYXNzIHRoZSBjYWxsIG9uIHRvIHRoZSB1bmRlcmx5aW5nIGhhbmRsZXIKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LmV4dC5EZWNsSGFuZGxlciNhdHRyaWJ1dGVEZWNsKFN0cmluZywgU3RyaW5nLCBTdHJpbmcsIFN0cmluZywgU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGF0dHJpYnV0ZURlY2woCi0gICAgICAgIFN0cmluZyBhcmcwLAotICAgICAgICBTdHJpbmcgYXJnMSwKLSAgICAgICAgU3RyaW5nIGFyZzIsCi0gICAgICAgIFN0cmluZyBhcmczLAotICAgICAgICBTdHJpbmcgYXJnNCkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgbV9oYW5kbGVyLmF0dHJpYnV0ZURlY2woYXJnMCwgYXJnMSwgYXJnMiwgYXJnMywgYXJnNCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUGFzcyB0aGUgY2FsbCBvbiB0byB0aGUgdW5kZXJseWluZyBoYW5kbGVyCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5leHQuRGVjbEhhbmRsZXIjZWxlbWVudERlY2woU3RyaW5nLCBTdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZWxlbWVudERlY2woU3RyaW5nIGFyZzAsIFN0cmluZyBhcmcxKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAobV9maXJzdFRhZ05vdEVtaXR0ZWQpCi0gICAgICAgIHsKLSAgICAgICAgICAgIGVtaXRGaXJzdFRhZygpOwotICAgICAgICB9Ci0gICAgICAgIG1faGFuZGxlci5lbGVtZW50RGVjbChhcmcwLCBhcmcxKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBQYXNzIHRoZSBjYWxsIG9uIHRvIHRoZSB1bmRlcmx5aW5nIGhhbmRsZXIKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LmV4dC5EZWNsSGFuZGxlciNleHRlcm5hbEVudGl0eURlY2woU3RyaW5nLCBTdHJpbmcsIFN0cmluZykKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBleHRlcm5hbEVudGl0eURlY2woCi0gICAgICAgIFN0cmluZyBuYW1lLAotICAgICAgICBTdHJpbmcgcHVibGljSWQsCi0gICAgICAgIFN0cmluZyBzeXN0ZW1JZCkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaWYgKG1fZmlyc3RUYWdOb3RFbWl0dGVkKQotICAgICAgICB7Ci0gICAgICAgICAgICBmbHVzaCgpOwotICAgICAgICB9Ci0gICAgICAgIG1faGFuZGxlci5leHRlcm5hbEVudGl0eURlY2wobmFtZSwgcHVibGljSWQsIHN5c3RlbUlkKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBQYXNzIHRoZSBjYWxsIG9uIHRvIHRoZSB1bmRlcmx5aW5nIGhhbmRsZXIKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LmV4dC5EZWNsSGFuZGxlciNpbnRlcm5hbEVudGl0eURlY2woU3RyaW5nLCBTdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgaW50ZXJuYWxFbnRpdHlEZWNsKFN0cmluZyBhcmcwLCBTdHJpbmcgYXJnMSkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaWYgKG1fZmlyc3RUYWdOb3RFbWl0dGVkKQotICAgICAgICB7Ci0gICAgICAgICAgICBmbHVzaCgpOwotICAgICAgICB9Ci0gICAgICAgIG1faGFuZGxlci5pbnRlcm5hbEVudGl0eURlY2woYXJnMCwgYXJnMSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUGFzcyB0aGUgY2FsbCBvbiB0byB0aGUgdW5kZXJseWluZyBoYW5kbGVyCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNjaGFyYWN0ZXJzKGNoYXJbXSwgaW50LCBpbnQpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY2hhcmFjdGVycyhjaGFyW10gY2hhcmFjdGVycywgaW50IG9mZnNldCwgaW50IGxlbmd0aCkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaWYgKG1fZmlyc3RUYWdOb3RFbWl0dGVkKQotICAgICAgICB7Ci0gICAgICAgICAgICBmbHVzaCgpOwotICAgICAgICB9Ci0KLSAgICAgICAgbV9oYW5kbGVyLmNoYXJhY3RlcnMoY2hhcmFjdGVycywgb2Zmc2V0LCBsZW5ndGgpOwotCi0gICAgfQotCi0gICAgLyoqCi0gICAgICogUGFzcyB0aGUgY2FsbCBvbiB0byB0aGUgdW5kZXJseWluZyBoYW5kbGVyCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNlbmREb2N1bWVudCgpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kRG9jdW1lbnQoKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAobV9maXJzdFRhZ05vdEVtaXR0ZWQpCi0gICAgICAgIHsKLSAgICAgICAgICAgIGZsdXNoKCk7Ci0gICAgICAgIH0KLQotICAgICAgICBtX2hhbmRsZXIuZW5kRG9jdW1lbnQoKTsKLQotCi0gICAgfQotCi0gICAgLyoqCi0gICAgICogUGFzcyB0aGUgY2FsbCBvbiB0byB0aGUgdW5kZXJseWluZyBoYW5kbGVyCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNlbmRFbGVtZW50KFN0cmluZywgU3RyaW5nLCBTdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kRWxlbWVudChTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgbG9jYWxOYW1lLCBTdHJpbmcgcU5hbWUpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGlmIChtX2ZpcnN0VGFnTm90RW1pdHRlZCkKLSAgICAgICAgewotICAgICAgICAgICAgZmx1c2goKTsKLSAgICAgICAgICAgIGlmIChuYW1lc3BhY2VVUkkgPT0gbnVsbCAmJiBtX2ZpcnN0RWxlbWVudFVSSSAhPSBudWxsKQotICAgICAgICAgICAgICAgIG5hbWVzcGFjZVVSSSA9IG1fZmlyc3RFbGVtZW50VVJJOwotCi0KLSAgICAgICAgICAgIGlmIChsb2NhbE5hbWUgPT0gbnVsbCAmJiBtX2ZpcnN0RWxlbWVudExvY2FsTmFtZSAhPSBudWxsKQotICAgICAgICAgICAgICAgIGxvY2FsTmFtZSA9IG1fZmlyc3RFbGVtZW50TG9jYWxOYW1lOwotICAgICAgICB9Ci0KLSAgICAgICAgbV9oYW5kbGVyLmVuZEVsZW1lbnQobmFtZXNwYWNlVVJJLCBsb2NhbE5hbWUsIHFOYW1lKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBQYXNzIHRoZSBjYWxsIG9uIHRvIHRoZSB1bmRlcmx5aW5nIGhhbmRsZXIKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI2VuZFByZWZpeE1hcHBpbmcoU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZFByZWZpeE1hcHBpbmcoU3RyaW5nIHByZWZpeCkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgbV9oYW5kbGVyLmVuZFByZWZpeE1hcHBpbmcocHJlZml4KTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBQYXNzIHRoZSBjYWxsIG9uIHRvIHRoZSB1bmRlcmx5aW5nIGhhbmRsZXIKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI2lnbm9yYWJsZVdoaXRlc3BhY2UoY2hhcltdLCBpbnQsIGludCkKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBpZ25vcmFibGVXaGl0ZXNwYWNlKGNoYXJbXSBjaCwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAobV9maXJzdFRhZ05vdEVtaXR0ZWQpCi0gICAgICAgIHsKLSAgICAgICAgICAgIGZsdXNoKCk7Ci0gICAgICAgIH0KLSAgICAgICAgbV9oYW5kbGVyLmlnbm9yYWJsZVdoaXRlc3BhY2UoY2gsIHN0YXJ0LCBsZW5ndGgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFBhc3MgdGhlIGNhbGwgb24gdG8gdGhlIHVuZGVybHlpbmcgaGFuZGxlcgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjcHJvY2Vzc2luZ0luc3RydWN0aW9uKFN0cmluZywgU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHByb2Nlc3NpbmdJbnN0cnVjdGlvbihTdHJpbmcgdGFyZ2V0LCBTdHJpbmcgZGF0YSkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgICBpZiAobV9maXJzdFRhZ05vdEVtaXR0ZWQpCi0gICAgICAgIHsKLSAgICAgICAgICAgIGZsdXNoKCk7Ci0gICAgICAgIH0KLQotICAgICAgICBtX2hhbmRsZXIucHJvY2Vzc2luZ0luc3RydWN0aW9uKHRhcmdldCwgZGF0YSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUGFzcyB0aGUgY2FsbCBvbiB0byB0aGUgdW5kZXJseWluZyBoYW5kbGVyCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNzZXREb2N1bWVudExvY2F0b3IoTG9jYXRvcikKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXREb2N1bWVudExvY2F0b3IoTG9jYXRvciBsb2NhdG9yKQotICAgIHsKLSAgICAgICAgc3VwZXIuc2V0RG9jdW1lbnRMb2NhdG9yKGxvY2F0b3IpOwotICAgICAgICBtX2hhbmRsZXIuc2V0RG9jdW1lbnRMb2NhdG9yKGxvY2F0b3IpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFBhc3MgdGhlIGNhbGwgb24gdG8gdGhlIHVuZGVybHlpbmcgaGFuZGxlcgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjc2tpcHBlZEVudGl0eShTdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2tpcHBlZEVudGl0eShTdHJpbmcgbmFtZSkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgbV9oYW5kbGVyLnNraXBwZWRFbnRpdHkobmFtZSk7Ci0gICAgfQotCi0KLQotICAgIC8qKgotICAgICAqIFBhc3MgdGhlIGNhbGwgb24gdG8gdGhlIHVuZGVybHlpbmcgaGFuZGxlcgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguZXh0LkxleGljYWxIYW5kbGVyI2NvbW1lbnQoY2hhcltdLCBpbnQsIGludCkKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBjb21tZW50KGNoYXJbXSBjaCwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAobV9maXJzdFRhZ05vdEVtaXR0ZWQpCi0gICAgICAgIHsKLSAgICAgICAgICAgIGZsdXNoKCk7Ci0gICAgICAgIH0KLQotICAgICAgICBtX2hhbmRsZXIuY29tbWVudChjaCwgc3RhcnQsIGxlbmd0aCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUGFzcyB0aGUgY2FsbCBvbiB0byB0aGUgdW5kZXJseWluZyBoYW5kbGVyCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXIjZW5kQ0RBVEEoKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZENEQVRBKCkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLQotICAgICAgICBtX2hhbmRsZXIuZW5kQ0RBVEEoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBQYXNzIHRoZSBjYWxsIG9uIHRvIHRoZSB1bmRlcmx5aW5nIGhhbmRsZXIKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LmV4dC5MZXhpY2FsSGFuZGxlciNlbmREVEQoKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZERURCgpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0KLSAgICAgICAgbV9oYW5kbGVyLmVuZERURCgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFBhc3MgdGhlIGNhbGwgb24gdG8gdGhlIHVuZGVybHlpbmcgaGFuZGxlcgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguZXh0LkxleGljYWxIYW5kbGVyI2VuZEVudGl0eShTdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kRW50aXR5KFN0cmluZyBuYW1lKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAobV9maXJzdFRhZ05vdEVtaXR0ZWQpCi0gICAgICAgIHsKLSAgICAgICAgICAgIGVtaXRGaXJzdFRhZygpOwotICAgICAgICB9Ci0gICAgICAgIG1faGFuZGxlci5lbmRFbnRpdHkobmFtZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUGFzcyB0aGUgY2FsbCBvbiB0byB0aGUgdW5kZXJseWluZyBoYW5kbGVyCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXIjc3RhcnRDREFUQSgpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnRDREFUQSgpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIG1faGFuZGxlci5zdGFydENEQVRBKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUGFzcyB0aGUgY2FsbCBvbiB0byB0aGUgdW5kZXJseWluZyBoYW5kbGVyCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXIjc3RhcnREVEQoU3RyaW5nLCBTdHJpbmcsIFN0cmluZykKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydERURChTdHJpbmcgbmFtZSwgU3RyaW5nIHB1YmxpY0lkLCBTdHJpbmcgc3lzdGVtSWQpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIG1faGFuZGxlci5zdGFydERURChuYW1lLCBwdWJsaWNJZCwgc3lzdGVtSWQpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFBhc3MgdGhlIGNhbGwgb24gdG8gdGhlIHVuZGVybHlpbmcgaGFuZGxlcgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguZXh0LkxleGljYWxIYW5kbGVyI3N0YXJ0RW50aXR5KFN0cmluZykKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydEVudGl0eShTdHJpbmcgbmFtZSkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgbV9oYW5kbGVyLnN0YXJ0RW50aXR5KG5hbWUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEluaXRpYWxpemUgdGhlIHdyYXBwZWQgb3V0cHV0IHN0cmVhbSAoWE1MIG9yIEhUTUwpLgotICAgICAqIElmIHRoZSBzdHJlYW0gaGFuZGxlciBzaG91bGQgYmUgSFRNTCwgdGhlbiByZXBsYWNlIHRoZSBYTUwgaGFuZGxlciB3aXRoCi0gICAgICogYW4gSFRNTCBoYW5kbGVyLiBBZnRlciB0aGFuIHNlbmQgdGhlIHN0YXJ0aW5nIG1ldGhvZCBjYWxscyB0aGF0IHdlcmUgY2FjaGVkCi0gICAgICogdG8gdGhlIHdyYXBwZWQgaGFuZGxlci4KLSAgICAgKgotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCBpbml0U3RyZWFtT3V0cHV0KCkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLQotICAgICAgICAvLyBUcnkgdG8gcnVsZSBvdXQgaWYgdGhpcyBpcyBhbiBub3QgdG8gYmUgYW4gSFRNTCBkb2N1bWVudCBiYXNlZCBvbiBwcmVmaXgKLSAgICAgICAgYm9vbGVhbiBmaXJzdEVsZW1lbnRJc0hUTUwgPSBpc0ZpcnN0RWxlbUhUTUwoKTsKLQotICAgICAgICBpZiAoZmlyc3RFbGVtZW50SXNIVE1MKQotICAgICAgICB7Ci0gICAgICAgICAgICAvLyBjcmVhdGUgYW4gSFRNTCBvdXRwdXQgaGFuZGxlciwgYW5kIGluaXRpYWxpemUgaXQKLQotICAgICAgICAgICAgLy8ga2VlcCBhIHJlZmVyZW5jZSB0byB0aGUgb2xkIGhhbmRsZXIsIC4uLiBpdCB3aWxsIHNvb24gYmUgZ29uZQotICAgICAgICAgICAgU2VyaWFsaXphdGlvbkhhbmRsZXIgb2xkSGFuZGxlciA9IG1faGFuZGxlcjsKLQotICAgICAgICAgICAgLyogV2UgaGF2ZSB0byBtYWtlIHN1cmUgd2UgZ2V0IGFuIG91dHB1dCBwcm9wZXJ0aWVzIHdpdGggdGhlIHByb3BlcgotICAgICAgICAgICAgICogZGVmYXVsdHMgZm9yIHRoZSBIVE1MIG1ldGhvZC4gIFRoZSBlYXNpZXN0IHdheSB0byBkbyB0aGlzIGlzIHRvCi0gICAgICAgICAgICAgKiBoYXZlIHRoZSBPdXRwdXRQcm9wZXJ0aWVzIGNsYXNzIGRvIGl0LgotICAgICAgICAgICAgICovCi0KLSAgICAgICAgICAgIFByb3BlcnRpZXMgaHRtbFByb3BlcnRpZXMgPQotICAgICAgICAgICAgICAgIE91dHB1dFByb3BlcnRpZXNGYWN0b3J5LmdldERlZmF1bHRNZXRob2RQcm9wZXJ0aWVzKE1ldGhvZC5IVE1MKTsKLSAgICAgICAgICAgIFNlcmlhbGl6ZXIgc2VyaWFsaXplciA9Ci0gICAgICAgICAgICAgICAgU2VyaWFsaXplckZhY3RvcnkuZ2V0U2VyaWFsaXplcihodG1sUHJvcGVydGllcyk7Ci0KLSAgICAgICAgICAgIC8vIFRoZSBmYWN0b3J5IHNob3VsZCBiZSByZXR1cm5pbmcgYSBUb1N0cmVhbQotICAgICAgICAgICAgLy8gRG9uJ3Qga25vdyB3aGF0IHRvIGRvIGlmIGl0IGRvZXNuJ3QKLSAgICAgICAgICAgIC8vIGkuZS4gdGhlIHVzZXIgaGFzIG92ZXItcmlkZGVuIHRoZSBjb250ZW50LWhhbmRsZXIgcHJvcGVydHkKLSAgICAgICAgICAgIC8vIGZvciBodG1sCi0gICAgICAgICAgICBtX2hhbmRsZXIgPSAoU2VyaWFsaXphdGlvbkhhbmRsZXIpIHNlcmlhbGl6ZXI7Ci0gICAgICAgICAgICAvL21faGFuZGxlciA9IG5ldyBUb0hUTUxTdHJlYW0oKTsKLQotICAgICAgICAgICAgV3JpdGVyIHdyaXRlciA9IG9sZEhhbmRsZXIuZ2V0V3JpdGVyKCk7Ci0KLSAgICAgICAgICAgIGlmIChudWxsICE9IHdyaXRlcikKLSAgICAgICAgICAgICAgICBtX2hhbmRsZXIuc2V0V3JpdGVyKHdyaXRlcik7Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgT3V0cHV0U3RyZWFtIG9zID0gb2xkSGFuZGxlci5nZXRPdXRwdXRTdHJlYW0oKTsKLQotICAgICAgICAgICAgICAgIGlmIChudWxsICE9IG9zKQotICAgICAgICAgICAgICAgICAgICBtX2hhbmRsZXIuc2V0T3V0cHV0U3RyZWFtKG9zKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gbmVlZCB0byBjb3B5IHRoaW5ncyBmcm9tIHRoZSBvbGQgaGFuZGxlciB0byB0aGUgbmV3IG9uZSBoZXJlCi0KLSAgICAgICAgICAgIC8vICAgICAgICAgICAgaWYgKF9zZXRWZXJzaW9uX2NhbGxlZCkKLSAgICAgICAgICAgIC8vICAgICAgICAgICAgewotICAgICAgICAgICAgbV9oYW5kbGVyLnNldFZlcnNpb24ob2xkSGFuZGxlci5nZXRWZXJzaW9uKCkpOwotICAgICAgICAgICAgLy8gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyAgICAgICAgICAgIGlmIChfc2V0RG9jdHlwZVN5c3RlbV9jYWxsZWQpCi0gICAgICAgICAgICAvLyAgICAgICAgICAgIHsKLSAgICAgICAgICAgIG1faGFuZGxlci5zZXREb2N0eXBlU3lzdGVtKG9sZEhhbmRsZXIuZ2V0RG9jdHlwZVN5c3RlbSgpKTsKLSAgICAgICAgICAgIC8vICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gICAgICAgICAgICBpZiAoX3NldERvY3R5cGVQdWJsaWNfY2FsbGVkKQotICAgICAgICAgICAgLy8gICAgICAgICAgICB7Ci0gICAgICAgICAgICBtX2hhbmRsZXIuc2V0RG9jdHlwZVB1YmxpYyhvbGRIYW5kbGVyLmdldERvY3R5cGVQdWJsaWMoKSk7Ci0gICAgICAgICAgICAvLyAgICAgICAgICAgIH0KLSAgICAgICAgICAgIC8vICAgICAgICAgICAgaWYgKF9zZXRNZWRpYVR5cGVfY2FsbGVkKQotICAgICAgICAgICAgLy8gICAgICAgICAgICB7Ci0gICAgICAgICAgICBtX2hhbmRsZXIuc2V0TWVkaWFUeXBlKG9sZEhhbmRsZXIuZ2V0TWVkaWFUeXBlKCkpOwotICAgICAgICAgICAgLy8gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIG1faGFuZGxlci5zZXRUcmFuc2Zvcm1lcihvbGRIYW5kbGVyLmdldFRyYW5zZm9ybWVyKCkpOwotICAgICAgICB9Ci0KLSAgICAgICAgLyogTm93IHRoYXQgd2UgaGF2ZSBhIHJlYWwgd3JhcHBlZCBoYW5kbGVyIChYTUwgb3IgSFRNTCkgbGV0cwotICAgICAgICAgKiBwYXNzIGFueSBjYWNoZWQgY2FsbHMgdG8gaXQKLSAgICAgICAgICovCi0gICAgICAgIC8vIENhbGwgc3RhcnREb2N1bWVudCgpIGlmIG5lY2Vzc2FyeQotICAgICAgICBpZiAobV9uZWVkVG9DYWxsU3RhcnREb2N1bWVudCkKLSAgICAgICAgewotICAgICAgICAgICAgbV9oYW5kbGVyLnN0YXJ0RG9jdW1lbnQoKTsKLSAgICAgICAgICAgIG1fbmVlZFRvQ2FsbFN0YXJ0RG9jdW1lbnQgPSBmYWxzZTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIHRoZSB3cmFwcGVkIGhhbmRsZXIgaXMgbm93IGZ1bGx5IGluaXRpYWxpemVkCi0gICAgICAgIG1fd3JhcHBlZF9oYW5kbGVyX25vdF9pbml0aWFsaXplZCA9IGZhbHNlOwotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBlbWl0Rmlyc3RUYWcoKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAobV9maXJzdEVsZW1lbnROYW1lICE9IG51bGwpCi0gICAgICAgIHsKLSAgICAgICAgICAgIGlmIChtX3dyYXBwZWRfaGFuZGxlcl9ub3RfaW5pdGlhbGl6ZWQpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgaW5pdFN0cmVhbU91dHB1dCgpOwotICAgICAgICAgICAgICAgIG1fd3JhcHBlZF9oYW5kbGVyX25vdF9pbml0aWFsaXplZCA9IGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gT3V0cHV0IGZpcnN0IHRhZwotICAgICAgICAgICAgbV9oYW5kbGVyLnN0YXJ0RWxlbWVudChtX2ZpcnN0RWxlbWVudFVSSSwgbnVsbCwgbV9maXJzdEVsZW1lbnROYW1lLCBtX2F0dHJpYnV0ZXMpOwotICAgICAgICAgICAgLy8gZG9uJ3QgbmVlZCB0aGUgY29sbGVjdGVkIGF0dHJpYnV0ZXMgb2YgdGhlIGZpcnN0IGVsZW1lbnQgYW55bW9yZS4KLSAgICAgICAgICAgIG1fYXR0cmlidXRlcyA9IG51bGw7Ci0KLSAgICAgICAgICAgIC8vIE91dHB1dCBuYW1lc3BhY2VzIG9mIGZpcnN0IHRhZwotICAgICAgICAgICAgaWYgKG1fbmFtZXNwYWNlUHJlZml4ICE9IG51bGwpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgZmluYWwgaW50IG4gPSBtX25hbWVzcGFjZVByZWZpeC5zaXplKCk7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgcHJlZml4ID0KLSAgICAgICAgICAgICAgICAgICAgICAgIChTdHJpbmcpIG1fbmFtZXNwYWNlUHJlZml4LmVsZW1lbnRBdChpKTsKLSAgICAgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIHVyaSA9IChTdHJpbmcpIG1fbmFtZXNwYWNlVVJJLmVsZW1lbnRBdChpKTsKLSAgICAgICAgICAgICAgICAgICAgbV9oYW5kbGVyLnN0YXJ0UHJlZml4TWFwcGluZyhwcmVmaXgsIHVyaSwgZmFsc2UpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBtX25hbWVzcGFjZVByZWZpeCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgbV9uYW1lc3BhY2VVUkkgPSBudWxsOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgbV9maXJzdFRhZ05vdEVtaXR0ZWQgPSBmYWxzZTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFV0aWxpdHkgZnVuY3Rpb24gZm9yIGNhbGxzIHRvIGxvY2FsLW5hbWUoKS4KLSAgICAgKgotICAgICAqIERvbid0IHdhbnQgdG8gb3ZlcnJpZGUgc3RhdGljIGZ1bmN0aW9uIG9uIFNlcmlhbGl6ZXJCYXNlCi0gICAgICogU28gYWRkZWQgVW5rbm93biBzdWZmaXggdG8gbWV0aG9kIG5hbWUuCi0gICAgICovCi0gICAgcHJpdmF0ZSBTdHJpbmcgZ2V0TG9jYWxOYW1lVW5rbm93bihTdHJpbmcgdmFsdWUpCi0gICAgewotICAgICAgICBpbnQgaWR4ID0gdmFsdWUubGFzdEluZGV4T2YoJzonKTsKLSAgICAgICAgaWYgKGlkeCA+PSAwKQotICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZS5zdWJzdHJpbmcoaWR4ICsgMSk7Ci0gICAgICAgIGlkeCA9IHZhbHVlLmxhc3RJbmRleE9mKCdAJyk7Ci0gICAgICAgIGlmIChpZHggPj0gMCkKLSAgICAgICAgICAgIHZhbHVlID0gdmFsdWUuc3Vic3RyaW5nKGlkeCArIDEpOwotICAgICAgICByZXR1cm4gKHZhbHVlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgICAgICogVXRpbGl0eSBmdW5jdGlvbiB0byByZXR1cm4gcHJlZml4Ci0gICAgICAgICAqCi0gICAgICAgICAqIERvbid0IHdhbnQgdG8gb3ZlcnJpZGUgc3RhdGljIGZ1bmN0aW9uIG9uIFNlcmlhbGl6ZXJCYXNlCi0gICAgICAgICAqIFNvIGFkZGVkIFVua25vd24gc3VmZml4IHRvIG1ldGhvZCBuYW1lLgotICAgICAgICAgKi8KLSAgICBwcml2YXRlIFN0cmluZyBnZXRQcmVmaXhQYXJ0VW5rbm93bihTdHJpbmcgcW5hbWUpCi0gICAgewotICAgICAgICBmaW5hbCBpbnQgaW5kZXggPSBxbmFtZS5pbmRleE9mKCc6Jyk7Ci0gICAgICAgIHJldHVybiAoaW5kZXggPiAwKSA/IHFuYW1lLnN1YnN0cmluZygwLCBpbmRleCkgOiBFTVBUWVNUUklORzsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBEZXRlcm1pbmUgaWYgdGhlIGZpcnRzIGVsZW1lbnQgaW4gdGhlIGRvY3VtZW50IGlzIDxodG1sPiBvciA8SFRNTD4KLSAgICAgKiBUaGlzIHVzZXMgdGhlIGNhY2hlZCBmaXJzdCBlbGVtZW50IG5hbWUsIGZpcnN0IGVsZW1lbnQgcHJlZml4IGFuZCB0aGUKLSAgICAgKiBjYWNoZWQgbmFtZXNwYWNlcyBmcm9tIHByZXZpb3VzIG1ldGhvZCBjYWxscwotICAgICAqCi0gICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBmaXJzdCBlbGVtZW50IGlzIGFuIG9wZW5pbmcgPGh0bWw+IHRhZwotICAgICAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBpc0ZpcnN0RWxlbUhUTUwoKQotICAgIHsKLSAgICAgICAgYm9vbGVhbiBpc0hUTUw7Ci0KLSAgICAgICAgLy8gaXMgdGhlIGZpcnN0IHRhZyBodG1sLCBub3QgY29uc2lkZXJpbmcgdGhlIHByZWZpeCA/Ci0gICAgICAgIGlzSFRNTCA9Ci0gICAgICAgICAgICBnZXRMb2NhbE5hbWVVbmtub3duKG1fZmlyc3RFbGVtZW50TmFtZSkuZXF1YWxzSWdub3JlQ2FzZSgiaHRtbCIpOwotCi0gICAgICAgIC8vIFRyeSB0byBydWxlIG91dCBpZiB0aGlzIGlzIG5vdCB0byBiZSBhbiBIVE1MIGRvY3VtZW50IGJhc2VkIG9uIFVSSQotICAgICAgICBpZiAoaXNIVE1MCi0gICAgICAgICAgICAmJiBtX2ZpcnN0RWxlbWVudFVSSSAhPSBudWxsCi0gICAgICAgICAgICAmJiAhRU1QVFlTVFJJTkcuZXF1YWxzKG1fZmlyc3RFbGVtZW50VVJJKSkKLSAgICAgICAgewotICAgICAgICAgICAgLy8gdGhlIDxodG1sPiBlbGVtZW50IGhhcyBhIG5vbi10cml2aWFsIG5hbWVzcGFjZQotICAgICAgICAgICAgaXNIVE1MID0gZmFsc2U7Ci0gICAgICAgIH0KLSAgICAgICAgLy8gVHJ5IHRvIHJ1bGUgb3V0IGlmIHRoaXMgaXMgYW4gbm90IHRvIGJlIGFuIEhUTUwgZG9jdW1lbnQgYmFzZWQgb24gcHJlZml4Ci0gICAgICAgIGlmIChpc0hUTUwgJiYgbV9uYW1lc3BhY2VQcmVmaXggIT0gbnVsbCkKLSAgICAgICAgewotICAgICAgICAgICAgLyogdGhlIGZpcnN0IGVsZW1lbnQgaGFzIGEgbmFtZSBvZiAiaHRtbCIsIGJ1dCBsZXRzIGNoZWNrIHRoZSBwcmVmaXguCi0gICAgICAgICAgICAgKiBJZiB0aGUgcHJlZml4IHBvaW50cyB0byBhIG5hbWVzcGFjZSB3aXRoIGEgVVJMIHRoYXQgaXMgbm90ICIiCi0gICAgICAgICAgICAgKiB0aGVuIHRoZSBkb2VjdW1lbnQgZG9lc24ndCBzdGFydCB3aXRoIGFuIDxodG1sPiB0YWcsIGFuZCBpc24ndCBodG1sCi0gICAgICAgICAgICAgKi8KLSAgICAgICAgICAgIGZpbmFsIGludCBtYXggPSBtX25hbWVzcGFjZVByZWZpeC5zaXplKCk7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1heDsgaSsrKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBwcmVmaXggPSAoU3RyaW5nKSBtX25hbWVzcGFjZVByZWZpeC5lbGVtZW50QXQoaSk7Ci0gICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIHVyaSA9IChTdHJpbmcpIG1fbmFtZXNwYWNlVVJJLmVsZW1lbnRBdChpKTsKLQotICAgICAgICAgICAgICAgIGlmIChtX2ZpcnN0RWxlbWVudFByZWZpeCAhPSBudWxsCi0gICAgICAgICAgICAgICAgICAgICYmIG1fZmlyc3RFbGVtZW50UHJlZml4LmVxdWFscyhwcmVmaXgpCi0gICAgICAgICAgICAgICAgICAgICYmICFFTVBUWVNUUklORy5lcXVhbHModXJpKSkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIFRoZSBmaXJzdCBlbGVtZW50IGhhcyBhIHByZWZpeCwgc28gaXQgY2FuJ3QgYmUgPGh0bWw+Ci0gICAgICAgICAgICAgICAgICAgIGlzSFRNTCA9IGZhbHNlOwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gaXNIVE1MOwotICAgIH0KLSAgICAvKioKLSAgICAgKiBAc2VlIFNlcmlhbGl6ZXIjYXNET01TZXJpYWxpemVyKCkKLSAgICAgKi8KLSAgICBwdWJsaWMgRE9NU2VyaWFsaXplciBhc0RPTVNlcmlhbGl6ZXIoKSB0aHJvd3MgSU9FeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIHJldHVybiBtX2hhbmRsZXIuYXNET01TZXJpYWxpemVyKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHBhcmFtIFVSSV9hbmRfbG9jYWxOYW1lcyBWZWN0b3IgYSBsaXN0IG9mIHBhaXJzIG9mIFVSSS9sb2NhbE5hbWUKLSAgICAgKiBzcGVjaWZpZWQgaW4gdGhlIGNkYXRhLXNlY3Rpb24tZWxlbWVudHMgYXR0cmlidXRlLgotICAgICAqIEBzZWUgU2VyaWFsaXphdGlvbkhhbmRsZXIjc2V0Q2RhdGFTZWN0aW9uRWxlbWVudHMoamF2YS51dGlsLlZlY3RvcikKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRDZGF0YVNlY3Rpb25FbGVtZW50cyhWZWN0b3IgVVJJX2FuZF9sb2NhbE5hbWVzKQotICAgIHsKLSAgICAgICAgbV9oYW5kbGVyLnNldENkYXRhU2VjdGlvbkVsZW1lbnRzKFVSSV9hbmRfbG9jYWxOYW1lcyk7Ci0gICAgfQotICAgIC8qKgotICAgICAqIEBzZWUgRXh0ZW5kZWRDb250ZW50SGFuZGxlciNhZGRBdHRyaWJ1dGVzKG9yZy54bWwuc2F4LkF0dHJpYnV0ZXMpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgYWRkQXR0cmlidXRlcyhBdHRyaWJ1dGVzIGF0dHMpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIG1faGFuZGxlci5hZGRBdHRyaWJ1dGVzKGF0dHMpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgY3VycmVudCBuYW1lc3BhY2UgbWFwcGluZ3MuCi0gICAgICogU2ltcGx5IHJldHVybnMgdGhlIG1hcHBpbmdzIG9mIHRoZSB3cmFwcGVkIGhhbmRsZXIuCi0gICAgICogQHNlZSBFeHRlbmRlZENvbnRlbnRIYW5kbGVyI2dldE5hbWVzcGFjZU1hcHBpbmdzKCkKLSAgICAgKi8KLSAgICBwdWJsaWMgTmFtZXNwYWNlTWFwcGluZ3MgZ2V0TmFtZXNwYWNlTWFwcGluZ3MoKQotICAgIHsKLSAgICAgICAgTmFtZXNwYWNlTWFwcGluZ3MgbWFwcGluZ3MgPSBudWxsOwotICAgICAgICBpZiAobV9oYW5kbGVyICE9IG51bGwpCi0gICAgICAgIHsKLSAgICAgICAgICAgIG1hcHBpbmdzID0gbV9oYW5kbGVyLmdldE5hbWVzcGFjZU1hcHBpbmdzKCk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG1hcHBpbmdzOwotICAgIH0KLSAgICAvKioKLSAgICAgKiBAc2VlIFNlcmlhbGl6YXRpb25IYW5kbGVyI2ZsdXNoUGVuZGluZygpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZmx1c2hQZW5kaW5nKCkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLQotICAgICAgICBmbHVzaCgpOwotCi0gICAgICAgIG1faGFuZGxlci5mbHVzaFBlbmRpbmcoKTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgZmx1c2goKQotICAgIHsKLSAgICAgICAgdHJ5Ci0gICAgICAgIHsKLSAgICAgICAgaWYgKG1fZmlyc3RUYWdOb3RFbWl0dGVkKQotICAgICAgICB7Ci0gICAgICAgICAgICBlbWl0Rmlyc3RUYWcoKTsKLSAgICAgICAgfQotICAgICAgICBpZiAobV9uZWVkVG9DYWxsU3RhcnREb2N1bWVudCkKLSAgICAgICAgewotICAgICAgICAgICAgbV9oYW5kbGVyLnN0YXJ0RG9jdW1lbnQoKTsKLSAgICAgICAgICAgIG1fbmVlZFRvQ2FsbFN0YXJ0RG9jdW1lbnQgPSBmYWxzZTsKLSAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGNhdGNoKFNBWEV4Y2VwdGlvbiBlKQotICAgICAgICB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihlLnRvU3RyaW5nKCkpOwotICAgICAgICB9Ci0KLQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgRXh0ZW5kZWRDb250ZW50SGFuZGxlciNnZXRQcmVmaXgKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFByZWZpeChTdHJpbmcgbmFtZXNwYWNlVVJJKQotICAgIHsKLSAgICAgICAgcmV0dXJuIG1faGFuZGxlci5nZXRQcmVmaXgobmFtZXNwYWNlVVJJKTsKLSAgICB9Ci0gICAgLyoqCi0gICAgICogQHNlZSBFeHRlbmRlZENvbnRlbnRIYW5kbGVyI2VudGl0eVJlZmVyZW5jZShqYXZhLmxhbmcuU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVudGl0eVJlZmVyZW5jZShTdHJpbmcgZW50aXR5TmFtZSkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgbV9oYW5kbGVyLmVudGl0eVJlZmVyZW5jZShlbnRpdHlOYW1lKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAc2VlIEV4dGVuZGVkQ29udGVudEhhbmRsZXIjZ2V0TmFtZXNwYWNlVVJJKGphdmEubGFuZy5TdHJpbmcsIGJvb2xlYW4pCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXROYW1lc3BhY2VVUkkoU3RyaW5nIHFuYW1lLCBib29sZWFuIGlzRWxlbWVudCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBtX2hhbmRsZXIuZ2V0TmFtZXNwYWNlVVJJKHFuYW1lLCBpc0VsZW1lbnQpOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZXNwYWNlVVJJRnJvbVByZWZpeChTdHJpbmcgcHJlZml4KQotICAgIHsKLSAgICAgICAgcmV0dXJuIG1faGFuZGxlci5nZXROYW1lc3BhY2VVUklGcm9tUHJlZml4KHByZWZpeCk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0VHJhbnNmb3JtZXIoVHJhbnNmb3JtZXIgdCkKLSAgICB7Ci0gICAgICAgIG1faGFuZGxlci5zZXRUcmFuc2Zvcm1lcih0KTsKLSAgICAgICAgaWYgKCh0IGluc3RhbmNlb2YgU2VyaWFsaXplclRyYWNlKSAmJgotICAgICAgICAgICAgKCgoU2VyaWFsaXplclRyYWNlKSB0KS5oYXNUcmFjZUxpc3RlbmVycygpKSkgewotICAgICAgICAgICBtX3RyYWNlciA9IChTZXJpYWxpemVyVHJhY2UpIHQ7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgIG1fdHJhY2VyID0gbnVsbDsKLSAgICAgICAgfQotICAgIH0KLSAgICBwdWJsaWMgVHJhbnNmb3JtZXIgZ2V0VHJhbnNmb3JtZXIoKQotICAgIHsKLSAgICAgICAgcmV0dXJuIG1faGFuZGxlci5nZXRUcmFuc2Zvcm1lcigpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgU2VyaWFsaXphdGlvbkhhbmRsZXIjc2V0Q29udGVudEhhbmRsZXIob3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0Q29udGVudEhhbmRsZXIoQ29udGVudEhhbmRsZXIgY2gpCi0gICAgewotICAgICAgICBtX2hhbmRsZXIuc2V0Q29udGVudEhhbmRsZXIoY2gpOwotICAgIH0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBpcyB1c2VkIHRvIHNldCB0aGUgc291cmNlIGxvY2F0b3IsIHdoaWNoIG1pZ2h0IGJlIHVzZWQgdG8KLSAgICAgKiBnZW5lcmF0ZWQgYW4gZXJyb3IgbWVzc2FnZS4KLSAgICAgKiBAcGFyYW0gbG9jYXRvciB0aGUgc291cmNlIGxvY2F0b3IKLSAgICAgKgotICAgICAqIEBzZWUgRXh0ZW5kZWRDb250ZW50SGFuZGxlciNzZXRTb3VyY2VMb2NhdG9yKGphdmF4LnhtbC50cmFuc2Zvcm0uU291cmNlTG9jYXRvcikKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRTb3VyY2VMb2NhdG9yKFNvdXJjZUxvY2F0b3IgbG9jYXRvcikKLSAgICB7Ci0gICAgICAgIG1faGFuZGxlci5zZXRTb3VyY2VMb2NhdG9yKGxvY2F0b3IpOwotICAgIH0KLQotICAgIHByb3RlY3RlZCB2b2lkIGZpcmVQc2V1ZG9FbGVtZW50KFN0cmluZyBlbGVtZW50TmFtZSkKLSAgICB7Ci0KLSAgICAgICAgaWYgKG1fdHJhY2VyICE9IG51bGwpIHsKLSAgICAgICAgICAgIFN0cmluZ0J1ZmZlciBzYiA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLQotICAgICAgICAgICAgc2IuYXBwZW5kKCc8Jyk7Ci0gICAgICAgICAgICBzYi5hcHBlbmQoZWxlbWVudE5hbWUpOwotCi0gICAgICAgICAgICAvLyBjb252ZXJ0IHRoZSBTdHJpbmdCdWZmZXIgdG8gYSBjaGFyIGFycmF5IGFuZAotICAgICAgICAgICAgLy8gZW1pdCB0aGUgdHJhY2UgZXZlbnQgdGhhdCB0aGVzZSBjaGFyYWN0ZXJzICJtaWdodCIKLSAgICAgICAgICAgIC8vIGJlIHdyaXR0ZW4KLSAgICAgICAgICAgIGNoYXIgY2hbXSA9IHNiLnRvU3RyaW5nKCkudG9DaGFyQXJyYXkoKTsKLSAgICAgICAgICAgIG1fdHJhY2VyLmZpcmVHZW5lcmF0ZUV2ZW50KAotICAgICAgICAgICAgICAgIFNlcmlhbGl6ZXJUcmFjZS5FVkVOVFRZUEVfT1VUUFVUX1BTRVVET19DSEFSQUNURVJTLAotICAgICAgICAgICAgICAgIGNoLAotICAgICAgICAgICAgICAgIDAsCi0gICAgICAgICAgICAgICAgY2gubGVuZ3RoKTsKLSAgICAgICAgfQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvVG9YTUxTQVhIYW5kbGVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1RvWE1MU0FYSGFuZGxlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3YjE2NWU0Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvVG9YTUxTQVhIYW5kbGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3NzggKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogVG9YTUxTQVhIYW5kbGVyLmphdmEsdiAxLjMgMjAwNS8wOS8yOCAxMzo0OTowOCBwdmVkdWxhIEV4cCAkCi0gKi8KLSBwYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplcjsKLQotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci1pbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5pby5Xcml0ZXI7Ci1pbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlJlc3VsdDsKLQotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci1pbXBvcnQgb3JnLnhtbC5zYXguQXR0cmlidXRlczsKLWltcG9ydCBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5Mb2NhdG9yOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXI7Ci0KLS8qKgotICogVGhpcyBjbGFzcyByZWNlaXZlcyBub3RpZmljYXRpb24gb2YgU0FYLWxpa2UgZXZlbnRzLCBhbmQgd2l0aCBnYXRoZXJlZAotICogaW5mb3JtYXRpb24gb3ZlciB0aGVzZSBjYWxscyBpdCB3aWxsIGludm9rZSB0aGUgZXF1aXZhbGVudCBTQVggbWV0aG9kcwotICogb24gYSBoYW5kbGVyLCB0aGUgdWx0aW1hdGUgeHNsOm91dHB1dCBtZXRob2QgaXMga25vd24gdG8gYmUgInhtbCIuCi0gKgotICogVGhpcyBjbGFzcyBpcyBub3QgYSBwdWJsaWMgQVBJLCBpdCBpcyBvbmx5IHB1YmxpYyBiZWNhdXNlIGl0IGlzIHVzZWQgYnkgWGFsYW4uCi0gKiBAeHNsLnVzYWdlIGludGVybmFsCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBUb1hNTFNBWEhhbmRsZXIgZXh0ZW5kcyBUb1NBWEhhbmRsZXIKLXsKLQotICAgIC8qKgotICAgICAqIEtlZXBzIHRyYWNrIG9mIHdoZXRoZXIgb3V0cHV0IGVzY2FwaW5nIGlzIGN1cnJlbnRseSBlbmFibGVkCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gbV9lc2NhcGVTZXR0aW5nID0gdHJ1ZTsKLQotICAgIHB1YmxpYyBUb1hNTFNBWEhhbmRsZXIoKQotICAgIHsKLSAgICAgICAgLy8gZGVmYXVsdCBjb25zdHJ1Y3RvciAobmVlZCB0byBzZXQgY29udGVudCBoYW5kbGVyIEFTQVAgISkKLSAgICAgICAgbV9wcmVmaXhNYXAgPSBuZXcgTmFtZXNwYWNlTWFwcGluZ3MoKTsKLSAgICAgICAgaW5pdENEQVRBKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBTZXJpYWxpemVyI2dldE91dHB1dEZvcm1hdCgpCi0gICAgICovCi0gICAgcHVibGljIFByb3BlcnRpZXMgZ2V0T3V0cHV0Rm9ybWF0KCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgU2VyaWFsaXplciNnZXRPdXRwdXRTdHJlYW0oKQotICAgICAqLwotICAgIHB1YmxpYyBPdXRwdXRTdHJlYW0gZ2V0T3V0cHV0U3RyZWFtKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgU2VyaWFsaXplciNnZXRXcml0ZXIoKQotICAgICAqLwotICAgIHB1YmxpYyBXcml0ZXIgZ2V0V3JpdGVyKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIERvIG5vdGhpbmcgZm9yIFNBWC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBpbmRlbnQoaW50IG4pIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBAc2VlIERPTVNlcmlhbGl6ZXIjc2VyaWFsaXplKE5vZGUpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2VyaWFsaXplKE5vZGUgbm9kZSkgdGhyb3dzIElPRXhjZXB0aW9uCi0gICAgewotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgU2VyaWFsaXphdGlvbkhhbmRsZXIjc2V0RXNjYXBpbmcoYm9vbGVhbikKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBzZXRFc2NhcGluZyhib29sZWFuIGVzY2FwZSkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgYm9vbGVhbiBvbGRFc2NhcGVTZXR0aW5nID0gbV9lc2NhcGVTZXR0aW5nOwotICAgICAgICBtX2VzY2FwZVNldHRpbmcgPSBlc2NhcGU7Ci0KLSAgICAgICAgaWYgKGVzY2FwZSkgewotICAgICAgICAgICAgcHJvY2Vzc2luZ0luc3RydWN0aW9uKFJlc3VsdC5QSV9FTkFCTEVfT1VUUFVUX0VTQ0FQSU5HLCAiIik7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oUmVzdWx0LlBJX0RJU0FCTEVfT1VUUFVUX0VTQ0FQSU5HLCAiIik7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gb2xkRXNjYXBlU2V0dGluZzsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAc2VlIFNlcmlhbGl6ZXIjc2V0T3V0cHV0Rm9ybWF0KFByb3BlcnRpZXMpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0T3V0cHV0Rm9ybWF0KFByb3BlcnRpZXMgZm9ybWF0KQotICAgIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAc2VlIFNlcmlhbGl6ZXIjc2V0T3V0cHV0U3RyZWFtKE91dHB1dFN0cmVhbSkKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRPdXRwdXRTdHJlYW0oT3V0cHV0U3RyZWFtIG91dHB1dCkKLSAgICB7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBTZXJpYWxpemVyI3NldFdyaXRlcihXcml0ZXIpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0V3JpdGVyKFdyaXRlciB3cml0ZXIpCi0gICAgewotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguZXh0LkRlY2xIYW5kbGVyI2F0dHJpYnV0ZURlY2woU3RyaW5nLCBTdHJpbmcsIFN0cmluZywgU3RyaW5nLCBTdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgYXR0cmlidXRlRGVjbCgKLSAgICAgICAgU3RyaW5nIGFyZzAsCi0gICAgICAgIFN0cmluZyBhcmcxLAotICAgICAgICBTdHJpbmcgYXJnMiwKLSAgICAgICAgU3RyaW5nIGFyZzMsCi0gICAgICAgIFN0cmluZyBhcmc0KQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguZXh0LkRlY2xIYW5kbGVyI2VsZW1lbnREZWNsKFN0cmluZywgU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVsZW1lbnREZWNsKFN0cmluZyBhcmcwLCBTdHJpbmcgYXJnMSkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LmV4dC5EZWNsSGFuZGxlciNleHRlcm5hbEVudGl0eURlY2woU3RyaW5nLCBTdHJpbmcsIFN0cmluZykKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBleHRlcm5hbEVudGl0eURlY2woU3RyaW5nIGFyZzAsIFN0cmluZyBhcmcxLCBTdHJpbmcgYXJnMikKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LmV4dC5EZWNsSGFuZGxlciNpbnRlcm5hbEVudGl0eURlY2woU3RyaW5nLCBTdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgaW50ZXJuYWxFbnRpdHlEZWNsKFN0cmluZyBhcmcwLCBTdHJpbmcgYXJnMSkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZWNlaXZlcyBub3RpZmljYXRpb24gb2YgdGhlIGVuZCBvZiB0aGUgZG9jdW1lbnQuCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNlbmREb2N1bWVudCgpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kRG9jdW1lbnQoKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotCi0gICAgICAgIGZsdXNoUGVuZGluZygpOwotCi0gICAgICAgIC8vIENsb3NlIG91dHB1dCBkb2N1bWVudAotICAgICAgICBtX3NheEhhbmRsZXIuZW5kRG9jdW1lbnQoKTsKLQotICAgICAgICBpZiAobV90cmFjZXIgIT0gbnVsbCkKLSAgICAgICAgICAgIHN1cGVyLmZpcmVFbmREb2MoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgd2hlbiBhbGwgdGhlIGRhdGEgbmVlZGVkIGZvciBhIGNhbGwgdG8gdGhlCi0gICAgICogU0FYIGhhbmRsZXIncyBzdGFydEVsZW1lbnQoKSBtZXRob2QgaGFzIGJlZW4gZ2F0aGVyZWQuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgY2xvc2VTdGFydFRhZygpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0KLSAgICAgICAgbV9lbGVtQ29udGV4dC5tX3N0YXJ0VGFnT3BlbiA9IGZhbHNlOwotCi0gICAgICAgIGZpbmFsIFN0cmluZyBsb2NhbE5hbWUgPSBnZXRMb2NhbE5hbWUobV9lbGVtQ29udGV4dC5tX2VsZW1lbnROYW1lKTsKLSAgICAgICAgZmluYWwgU3RyaW5nIHVyaSA9IGdldE5hbWVzcGFjZVVSSShtX2VsZW1Db250ZXh0Lm1fZWxlbWVudE5hbWUsIHRydWUpOwotCi0gICAgICAgIC8vIE5vdyBpcyB0aW1lIHRvIHNlbmQgdGhlIHN0YXJ0RWxlbWVudCBldmVudAotICAgICAgICBpZiAobV9uZWVkVG9DYWxsU3RhcnREb2N1bWVudCkKLSAgICAgICAgewotICAgICAgICAgICAgc3RhcnREb2N1bWVudEludGVybmFsKCk7Ci0gICAgICAgIH0KLSAgICAgICAgbV9zYXhIYW5kbGVyLnN0YXJ0RWxlbWVudCh1cmksIGxvY2FsTmFtZSwgbV9lbGVtQ29udGV4dC5tX2VsZW1lbnROYW1lLCBtX2F0dHJpYnV0ZXMpOwotICAgICAgICAvLyB3ZSd2ZSBzZW50IHRoZSBvZmZpY2lhbCBTQVggYXR0cmlidXRlcyBvbiB0aGVpciB3YXksCi0gICAgICAgIC8vIG5vdyB3ZSBkb24ndCBuZWVkIHRoZW0gYW55bW9yZS4KLSAgICAgICAgbV9hdHRyaWJ1dGVzLmNsZWFyKCk7Ci0KLSAgICAgICAgaWYobV9zdGF0ZSAhPSBudWxsKQotICAgICAgICAgIG1fc3RhdGUuc2V0Q3VycmVudE5vZGUobnVsbCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ2xvc2VzIGFuZSBvcGVuIGNkYXRhIHRhZywgYW5kCi0gICAgICogdW5saWtlIHRoZSB0aGlzLmVuZENEQVRBKCkgbWV0aG9kIChmcm9tIHRoZSBMZXhpY2FsSGFuZGxlcikgaW50ZXJmYWNlLAotICAgICAqIHRoaXMgImludGVybmFsIiBtZXRob2Qgd2lsbCBzZW5kIHRoZSBlbmRDREFUQSgpIGNhbGwgdG8gdGhlIHdyYXBwZWQKLSAgICAgKiBoYW5kbGVyLgotICAgICAqCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY2xvc2VDREFUQSgpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0KLSAgICAgICAgLy8gT3V0cHV0IGNsb3NpbmcgYnJhY2tldCAtICJdXT4iCi0gICAgICAgIGlmIChtX2xleEhhbmRsZXIgIT0gbnVsbCAmJiBtX2NkYXRhVGFnT3BlbikgewotICAgICAgICAgICAgbV9sZXhIYW5kbGVyLmVuZENEQVRBKCk7Ci0gICAgICAgIH0KLQotCi0gICAgICAgIC8vIFRoZXJlIGFyZSBubyBsb25nZXIgYW55IGNhbGxzIG1hZGUgdG8KLSAgICAgICAgLy8gbV9sZXhIYW5kbGVyLnN0YXJ0Q0RBVEEoKSB3aXRob3V0IGEgYmFsYW5jaW5nIGNhbGwgdG8KLSAgICAgICAgLy8gbV9sZXhIYW5kbGVyLmVuZENEQVRBKCkKLSAgICAgICAgLy8gc28gd2Ugc2V0IG1fY2RhdGFUYWdPcGVuIHRvIGZhbHNlIHRvIHJlbWVtYmVyIHRoaXMuCi0gICAgICAgIG1fY2RhdGFUYWdPcGVuID0gZmFsc2U7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNlbmRFbGVtZW50KFN0cmluZywgU3RyaW5nLCBTdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kRWxlbWVudChTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgbG9jYWxOYW1lLCBTdHJpbmcgcU5hbWUpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIC8vIENsb3NlIGFueSBvcGVuIGVsZW1lbnRzIGV0Yy4KLSAgICAgICAgZmx1c2hQZW5kaW5nKCk7Ci0KLSAgICAgICAgaWYgKG5hbWVzcGFjZVVSSSA9PSBudWxsKQotICAgICAgICB7Ci0gICAgICAgICAgICBpZiAobV9lbGVtQ29udGV4dC5tX2VsZW1lbnRVUkkgIT0gbnVsbCkKLSAgICAgICAgICAgICAgICBuYW1lc3BhY2VVUkkgPSBtX2VsZW1Db250ZXh0Lm1fZWxlbWVudFVSSTsKLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICBuYW1lc3BhY2VVUkkgPSBnZXROYW1lc3BhY2VVUkkocU5hbWUsIHRydWUpOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKGxvY2FsTmFtZSA9PSBudWxsKQotICAgICAgICB7Ci0gICAgICAgICAgICBpZiAobV9lbGVtQ29udGV4dC5tX2VsZW1lbnRMb2NhbE5hbWUgIT0gbnVsbCkKLSAgICAgICAgICAgICAgICBsb2NhbE5hbWUgPSBtX2VsZW1Db250ZXh0Lm1fZWxlbWVudExvY2FsTmFtZTsKLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICBsb2NhbE5hbWUgPSBnZXRMb2NhbE5hbWUocU5hbWUpOwotICAgICAgICB9Ci0KLSAgICAgICAgbV9zYXhIYW5kbGVyLmVuZEVsZW1lbnQobmFtZXNwYWNlVVJJLCBsb2NhbE5hbWUsIHFOYW1lKTsKLQotICAgICAgICBpZiAobV90cmFjZXIgIT0gbnVsbCkKLSAgICAgICAgICAgIHN1cGVyLmZpcmVFbmRFbGVtKHFOYW1lKTsKLQotICAgICAgICAvKiBQb3AgYWxsIG5hbWVzcGFjZXMgYXQgdGhlIGN1cnJlbnQgZWxlbWVudCBkZXB0aC4KLSAgICAgICAgICogV2UgYXJlIG5vdCB3YWl0aW5nIGZvciBvZmZpY2lhbCBlbmRQcmVmaXhNYXBwaW5nKCkgY2FsbHMuCi0gICAgICAgICAqLwotICAgICAgICBtX3ByZWZpeE1hcC5wb3BOYW1lc3BhY2VzKG1fZWxlbUNvbnRleHQubV9jdXJyZW50RWxlbURlcHRoLAotICAgICAgICAgICAgbV9zYXhIYW5kbGVyKTsKLSAgICAgICAgbV9lbGVtQ29udGV4dCA9IG1fZWxlbUNvbnRleHQubV9wcmV2OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjZW5kUHJlZml4TWFwcGluZyhTdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kUHJlZml4TWFwcGluZyhTdHJpbmcgcHJlZml4KSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICAvKiBwb3BpbmcgYWxsIHByZWZpeCBtYXBwaW5ncyBzaG91bGQgaGF2ZSBiZWVuIGRvbmUKLSAgICAgICAgICogaW4gZW5kRWxlbWVudCgpIGFscmVhZHkKLSAgICAgICAgICovCi0gICAgICAgICByZXR1cm47Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNpZ25vcmFibGVXaGl0ZXNwYWNlKGNoYXJbXSwgaW50LCBpbnQpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgaWdub3JhYmxlV2hpdGVzcGFjZShjaGFyW10gYXJnMCwgaW50IGFyZzEsIGludCBhcmcyKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBtX3NheEhhbmRsZXIuaWdub3JhYmxlV2hpdGVzcGFjZShhcmcwLGFyZzEsYXJnMik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNzZXREb2N1bWVudExvY2F0b3IoTG9jYXRvcikKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXREb2N1bWVudExvY2F0b3IoTG9jYXRvciBhcmcwKQotICAgIHsKLSAgICAgICAgc3VwZXIuc2V0RG9jdW1lbnRMb2NhdG9yKGFyZzApOwotICAgICAgICBtX3NheEhhbmRsZXIuc2V0RG9jdW1lbnRMb2NhdG9yKGFyZzApOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjc2tpcHBlZEVudGl0eShTdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2tpcHBlZEVudGl0eShTdHJpbmcgYXJnMCkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgbV9zYXhIYW5kbGVyLnNraXBwZWRFbnRpdHkoYXJnMCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNzdGFydFByZWZpeE1hcHBpbmcoU3RyaW5nLCBTdHJpbmcpCi0gICAgICogQHBhcmFtIHByZWZpeCBUaGUgcHJlZml4IHRoYXQgbWFwcyB0byB0aGUgVVJJCi0gICAgICogQHBhcmFtIHVyaSBUaGUgVVJJIGZvciB0aGUgbmFtZXNwYWNlCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnRQcmVmaXhNYXBwaW5nKFN0cmluZyBwcmVmaXgsIFN0cmluZyB1cmkpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgc3RhcnRQcmVmaXhNYXBwaW5nKHByZWZpeCwgdXJpLCB0cnVlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZW1lbWJlciB0aGUgcHJlZml4L3VyaSBtYXBwaW5nIGF0IHRoZSBjdXJyZW50IG5lc3RlZCBlbGVtZW50IGRlcHRoLgotICAgICAqCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNzdGFydFByZWZpeE1hcHBpbmcoU3RyaW5nLCBTdHJpbmcpCi0gICAgICogQHBhcmFtIHByZWZpeCBUaGUgcHJlZml4IHRoYXQgbWFwcyB0byB0aGUgVVJJCi0gICAgICogQHBhcmFtIHVyaSBUaGUgVVJJIGZvciB0aGUgbmFtZXNwYWNlCi0gICAgICogQHBhcmFtIHNob3VsZEZsdXNoIGEgZmxhZyBpbmRpY2F0aW5nIGlmIHRoZSBtYXBwaW5nIGFwcGxpZXMgdG8gdGhlCi0gICAgICogY3VycmVudCBlbGVtZW50IG9yIGFuIHVwIGNvbWluZyBjaGlsZCAobm90IHVzZWQpLgotICAgICAqLwotCi0gICAgcHVibGljIGJvb2xlYW4gc3RhcnRQcmVmaXhNYXBwaW5nKAotICAgICAgICBTdHJpbmcgcHJlZml4LAotICAgICAgICBTdHJpbmcgdXJpLAotICAgICAgICBib29sZWFuIHNob3VsZEZsdXNoKQotICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAgewotCi0gICAgICAgIC8qIFJlbWVtYmVyIHRoZSBtYXBwaW5nLCBhbmQgYXQgd2hhdCBkZXB0aCBpdCB3YXMgZGVjbGFyZWQKLSAgICAgICAgICogVGhpcyBpcyBvbmUgZ3JlYXRlciB0aGFuIHRoZSBjdXJyZW50IGRlcHRoIGJlY2F1c2UgdGhlc2UKLSAgICAgICAgICogbWFwcGluZ3Mgd2lsbCBhcHBseSB0byB0aGUgbmV4dCBkZXB0aC4gVGhpcyBpcyBpbgotICAgICAgICAgKiBjb25zaWRlcmF0aW9uIHRoYXQgc3RhcnRFbGVtZW50KCkgd2lsbCBzb29uIGJlIGNhbGxlZAotICAgICAgICAgKi8KLQotICAgICAgICBib29sZWFuIHB1c2hlZDsKLSAgICAgICAgaW50IHB1c2hEZXB0aDsKLSAgICAgICAgaWYgKHNob3VsZEZsdXNoKQotICAgICAgICB7Ci0gICAgICAgICAgICBmbHVzaFBlbmRpbmcoKTsKLSAgICAgICAgICAgIC8vIHRoZSBwcmVmaXggbWFwcGluZyBhcHBsaWVzIHRvIHRoZSBjaGlsZCBlbGVtZW50IChvbmUgZGVlcGVyKQotICAgICAgICAgICAgcHVzaERlcHRoID0gbV9lbGVtQ29udGV4dC5tX2N1cnJlbnRFbGVtRGVwdGggKyAxOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotICAgICAgICAgICAgLy8gdGhlIHByZWZpeCBtYXBwaW5nIGFwcGxpZXMgdG8gdGhlIGN1cnJlbnQgZWxlbWVudAotICAgICAgICAgICAgcHVzaERlcHRoID0gbV9lbGVtQ29udGV4dC5tX2N1cnJlbnRFbGVtRGVwdGg7Ci0gICAgICAgIH0KLSAgICAgICAgcHVzaGVkID0gbV9wcmVmaXhNYXAucHVzaE5hbWVzcGFjZShwcmVmaXgsIHVyaSwgcHVzaERlcHRoKTsKLQotICAgICAgICBpZiAocHVzaGVkKQotICAgICAgICB7Ci0gICAgICAgICAgICBtX3NheEhhbmRsZXIuc3RhcnRQcmVmaXhNYXBwaW5nKHByZWZpeCx1cmkpOwotCi0gICAgICAgICAgICBpZiAoZ2V0U2hvdWxkT3V0cHV0TlNBdHRyKCkpCi0gICAgICAgICAgICB7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAvKiBCcmlhbiBNLjogZG9uJ3Qga25vdyBpZiB3ZSByZWFsbHkgbmVlZHRvIGRvIHRoaXMuIFRoZQotICAgICAgICAgICAgICAgICAgICAgICAqIGNhbGxlcnMgb2YgdGhpcyBvYmplY3Qgc2hvdWxkIGhhdmUgaW5qZWN0ZWQgYm90aAotICAgICAgICAgICAgICAgICAgICAgICAqIHN0YXJ0UHJlZml4TWFwcGluZyBhbmQgdGhlIGF0dHJpYnV0ZXMuICBXZSBhcmUKLSAgICAgICAgICAgICAgICAgICAgICAgKiBqdXN0IGNvdmVyaW5nIG91ciBidXR0IGhlcmUuCi0gICAgICAgICAgICAgICAgICAgICAgICovCi0gICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG5hbWU7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChFTVBUWVNUUklORy5lcXVhbHMocHJlZml4KSkKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSA9ICJ4bWxucyI7Ci0gICAgICAgICAgICAgICAgICAgICAgICBhZGRBdHRyaWJ1dGVBbHdheXMoWE1MTlNfVVJJLCBuYW1lLCBuYW1lLCJDREFUQSIsdXJpLCBmYWxzZSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmICghRU1QVFlTVFJJTkcuZXF1YWxzKHVyaSkpIC8vIGhhY2sgZm9yIFhTTFRDIGF0dHJpYnNldDE2IHRlc3QKLSAgICAgICAgICAgICAgICAgICAgICAgIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoYXQgbWFwcyBuczEgcHJlZml4IHRvICIiIFVSSQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUgPSAieG1sbnM6IiArIHByZWZpeDsKLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGZvciBzb21ldGhpbmcgbGlrZSB4bWxuczphYmM9InczLnByZXRlbmQub3JnIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogIHRoZSB1cmkgaXMgdGhlIHZhbHVlLCB0aGF0IGlzIHdoeSB3ZSBwYXNzIGl0IGluIHRoZQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogdmFsdWUsIG9yIDV0aCBzbG90IG9mIGFkZEF0dHJpYnV0ZUFsd2F5cygpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkQXR0cmlidXRlQWx3YXlzKFhNTE5TX1VSSSwgcHJlZml4LCBuYW1lLCJDREFUQSIsdXJpLCBmYWxzZSApOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHB1c2hlZDsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguZXh0LkxleGljYWxIYW5kbGVyI2NvbW1lbnQoY2hhcltdLCBpbnQsIGludCkKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBjb21tZW50KGNoYXJbXSBhcmcwLCBpbnQgYXJnMSwgaW50IGFyZzIpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGZsdXNoUGVuZGluZygpOwotICAgICAgICBpZiAobV9sZXhIYW5kbGVyICE9IG51bGwpCi0gICAgICAgICAgICBtX2xleEhhbmRsZXIuY29tbWVudChhcmcwLCBhcmcxLCBhcmcyKTsKLQotICAgICAgICBpZiAobV90cmFjZXIgIT0gbnVsbCkKLSAgICAgICAgICAgIHN1cGVyLmZpcmVDb21tZW50RXZlbnQoYXJnMCwgYXJnMSwgYXJnMik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXIjZW5kQ0RBVEEoKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZENEQVRBKCkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgLyogTm9ybWFsbHkgd2Ugd291bGQgZG8gc29tdGhpbmcgd2l0aCB0aGlzIGJ1dCB3ZSBpZ25vcmUgaXQuCi0gICAgICAgICAqIFRoZSBuZWNjZXNzYXJ5IGNhbGwgdG8gbV9sZXhIYW5kbGVyLmVuZENEQVRBKCkgd2lsbCBiZSBtYWRlCi0gICAgICAgICAqIGluIGZsdXNoUGVuZGluZygpLgotICAgICAgICAgKgotICAgICAgICAgKiBUaGlzIGlzIHNvIHRoYXQgaWYgd2UgZ2V0IGNhbGxzIGxpa2UgdGhlc2U6Ci0gICAgICAgICAqICAgdGhpcy5zdGFydENEQVRBKCk7Ci0gICAgICAgICAqICAgdGhpcy5jaGFyYWN0ZXJzKGNoYXJzMSwgb2ZmMSwgbGVuMSk7Ci0gICAgICAgICAqICAgdGhpcy5lbmRDREFUQSgpOwotICAgICAgICAgKiAgIHRoaXMuc3RhcnRDREFUQSgpOwotICAgICAgICAgKiAgIHRoaXMuY2hhcmFjdGVycyhjaGFyczIsIG9mZjIsIGxlbjIpOwotICAgICAgICAgKiAgIHRoaXMuZW5kQ0RBVEEoKTsKLSAgICAgICAgICoKLSAgICAgICAgICogdGhhdCB3ZSB3aWxsIG9ubHkgbWFrZSB0aGVzZSBjYWxscyB0byB0aGUgd3JhcHBlZCBoYW5kbGVyczoKLSAgICAgICAgICoKLSAgICAgICAgICogICBtX2xleEhhbmRsZXIuc3RhcnRDREFUQSgpOwotICAgICAgICAgKiAgIG1fc2F4SGFuZGxlci5jaGFyYWN0ZXJzKGNoYXJzMSwgb2ZmMSwgbGVuMSk7Ci0gICAgICAgICAqICAgbV9zYXhIYW5kbGVyLmNoYXJhY3RlcnMoY2hhcnMxLCBvZmYyLCBsZW4yKTsKLSAgICAgICAgICogICBtX2xleEhhbmRsZXIuZW5kQ0RBVEEoKTsKLSAgICAgICAgICoKLSAgICAgICAgICogV2Ugd2lsbCBtZXJnZSBhZGphY2VudCBDREFUQSBibG9ja3MuCi0gICAgICAgICAqLwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguZXh0LkxleGljYWxIYW5kbGVyI2VuZERURCgpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kRFREKCkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaWYgKG1fbGV4SGFuZGxlciAhPSBudWxsKQotICAgICAgICAgICAgbV9sZXhIYW5kbGVyLmVuZERURCgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguZXh0LkxleGljYWxIYW5kbGVyI3N0YXJ0RW50aXR5KFN0cmluZykKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydEVudGl0eShTdHJpbmcgYXJnMCkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaWYgKG1fbGV4SGFuZGxlciAhPSBudWxsKQotICAgICAgICAgICAgbV9sZXhIYW5kbGVyLnN0YXJ0RW50aXR5KGFyZzApOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgRXh0ZW5kZWRDb250ZW50SGFuZGxlciNjaGFyYWN0ZXJzKFN0cmluZykKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBjaGFyYWN0ZXJzKFN0cmluZyBjaGFycykgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgZmluYWwgaW50IGxlbmd0aCA9IGNoYXJzLmxlbmd0aCgpOwotICAgICAgICBpZiAobGVuZ3RoID4gbV9jaGFyc0J1ZmYubGVuZ3RoKQotICAgICAgICB7Ci0gICAgICAgICAgICBtX2NoYXJzQnVmZiA9IG5ldyBjaGFyW2xlbmd0aCoyICsgMV07Ci0gICAgICAgIH0KLSAgICAgICAgY2hhcnMuZ2V0Q2hhcnMoMCwgbGVuZ3RoLCBtX2NoYXJzQnVmZiwgMCk7Ci0gICAgICAgIHRoaXMuY2hhcmFjdGVycyhtX2NoYXJzQnVmZiwgMCwgbGVuZ3RoKTsKLSAgICB9Ci0KLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vIGZyb20gWFNMVEMgLy8vLy8vLy8vLy8vLy8KLSAgICBwdWJsaWMgVG9YTUxTQVhIYW5kbGVyKENvbnRlbnRIYW5kbGVyIGhhbmRsZXIsIFN0cmluZyBlbmNvZGluZykKLSAgICB7Ci0gICAgICAgIHN1cGVyKGhhbmRsZXIsIGVuY29kaW5nKTsKLQotICAgICAgICBpbml0Q0RBVEEoKTsKLSAgICAgICAgLy8gaW5pdE5hbWVzcGFjZXMoKTsKLSAgICAgICAgbV9wcmVmaXhNYXAgPSBuZXcgTmFtZXNwYWNlTWFwcGluZ3MoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgVG9YTUxTQVhIYW5kbGVyKAotICAgICAgICBDb250ZW50SGFuZGxlciBoYW5kbGVyLAotICAgICAgICBMZXhpY2FsSGFuZGxlciBsZXgsCi0gICAgICAgIFN0cmluZyBlbmNvZGluZykKLSAgICB7Ci0gICAgICAgIHN1cGVyKGhhbmRsZXIsIGxleCwgZW5jb2RpbmcpOwotCi0gICAgICAgIGluaXRDREFUQSgpOwotICAgICAgICAvLyAgICAgIGluaXROYW1lc3BhY2VzKCk7Ci0gICAgICAgIG1fcHJlZml4TWFwID0gbmV3IE5hbWVzcGFjZU1hcHBpbmdzKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU3RhcnQgYW4gZWxlbWVudCBpbiB0aGUgb3V0cHV0IGRvY3VtZW50LiBUaGlzIG1pZ2h0IGJlIGFuIFhNTCBlbGVtZW50Ci0gICAgICogKDxlbGVtPmRhdGE8L2VsZW0+IHR5cGUpIG9yIGEgQ0RBVEEgc2VjdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQoCi0gICAgU3RyaW5nIGVsZW1lbnROYW1lc3BhY2VVUkksCi0gICAgU3RyaW5nIGVsZW1lbnRMb2NhbE5hbWUsCi0gICAgU3RyaW5nIGVsZW1lbnROYW1lKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBzdGFydEVsZW1lbnQoCi0gICAgICAgICAgICBlbGVtZW50TmFtZXNwYWNlVVJJLGVsZW1lbnRMb2NhbE5hbWUsZWxlbWVudE5hbWUsIG51bGwpOwotCi0KLSAgICB9Ci0gICAgcHVibGljIHZvaWQgc3RhcnRFbGVtZW50KFN0cmluZyBlbGVtZW50TmFtZSkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgc3RhcnRFbGVtZW50KG51bGwsIG51bGwsIGVsZW1lbnROYW1lLCBudWxsKTsKLSAgICB9Ci0KLQotICAgIHB1YmxpYyB2b2lkIGNoYXJhY3RlcnMoY2hhcltdIGNoLCBpbnQgb2ZmLCBpbnQgbGVuKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICAvLyBXZSBkbyB0aGUgZmlyc3QgdHdvIHRoaW5ncyBpbiBmbHVzaFBlbmRpbmcoKSBidXQgd2UgZG9uJ3QKLSAgICAgICAgLy8gY2xvc2UgYW55IG9wZW4gQ0RBVEEgY2FsbHMuCi0gICAgICAgIGlmIChtX25lZWRUb0NhbGxTdGFydERvY3VtZW50KQotICAgICAgICB7Ci0gICAgICAgICAgICBzdGFydERvY3VtZW50SW50ZXJuYWwoKTsKLSAgICAgICAgICAgIG1fbmVlZFRvQ2FsbFN0YXJ0RG9jdW1lbnQgPSBmYWxzZTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChtX2VsZW1Db250ZXh0Lm1fc3RhcnRUYWdPcGVuKQotICAgICAgICB7Ci0gICAgICAgICAgICBjbG9zZVN0YXJ0VGFnKCk7Ci0gICAgICAgICAgICBtX2VsZW1Db250ZXh0Lm1fc3RhcnRUYWdPcGVuID0gZmFsc2U7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAobV9lbGVtQ29udGV4dC5tX2lzQ2RhdGFTZWN0aW9uICYmICFtX2NkYXRhVGFnT3BlbgotICAgICAgICAmJiBtX2xleEhhbmRsZXIgIT0gbnVsbCkKLSAgICAgICAgewotICAgICAgICAgICAgbV9sZXhIYW5kbGVyLnN0YXJ0Q0RBVEEoKTsKLSAgICAgICAgICAgIC8vIFdlIGhhdmUgbWFkZSBhIGNhbGwgdG8gbV9sZXhIYW5kbGVyLnN0YXJ0Q0RBVEEoKSB3aXRoCi0gICAgICAgICAgICAvLyBubyBiYWxhbmNpbmcgY2FsbCB0byBtX2xleEhhbmRsZXIuZW5kQ0RBVEEoKQotICAgICAgICAgICAgLy8gc28gd2Ugc2V0IG1fY2RhdGFUYWdPcGVuIHRydWUgdG8gcmVtZW1iZXIgdGhpcy4KLSAgICAgICAgICAgIG1fY2RhdGFUYWdPcGVuID0gdHJ1ZTsKLSAgICAgICAgfQotCi0gICAgICAgIC8qIElmIHRoZXJlIGFyZSBhbnkgb2NjdXJhbmNlcyBvZiAiXV0+IiBpbiB0aGUgY2hhcmFjdGVyIGRhdGEKLSAgICAgICAgICogbGV0IG1fc2F4SGFuZGxlciB3b3JyeSBhYm91dCBpdCwgd2UndmUgYWxyZWFkeSB3YXJuZWQgdGhlbSB3aXRoCi0gICAgICAgICAqIHRoZSBwcmV2aW91cyBjYWxsIG9mIG1fbGV4SGFuZGxlci5zdGFydENEQVRBKCk7Ci0gICAgICAgICAqLwotICAgICAgICBtX3NheEhhbmRsZXIuY2hhcmFjdGVycyhjaCwgb2ZmLCBsZW4pOwotCi0gICAgICAgIC8vIHRpbWUgdG8gZ2VuZXJhdGUgY2hhcmFjdGVycyBldmVudAotICAgICAgICBpZiAobV90cmFjZXIgIT0gbnVsbCkKLSAgICAgICAgICAgIGZpcmVDaGFyRXZlbnQoY2gsIG9mZiwgbGVuKTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIEBzZWUgRXh0ZW5kZWRDb250ZW50SGFuZGxlciNlbmRFbGVtZW50KFN0cmluZykKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbmRFbGVtZW50KFN0cmluZyBlbGVtTmFtZSkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgZW5kRWxlbWVudChudWxsLCBudWxsLCBlbGVtTmFtZSk7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBTZW5kIGEgbmFtZXNwYWNlIGRlY2xhcmF0aW9uIGluIHRoZSBvdXRwdXQgZG9jdW1lbnQuIFRoZSBuYW1lc3BhY2UKLSAgICAgKiBkZWNsYXJhdGlvbiB3aWxsIG5vdCBiZSBpbmNsdWRlIGlmIHRoZSBuYW1lc3BhY2UgaXMgYWxyZWFkeSBpbiBzY29wZQotICAgICAqIHdpdGggdGhlIHNhbWUgcHJlZml4LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIG5hbWVzcGFjZUFmdGVyU3RhcnRFbGVtZW50KAotICAgICAgICBmaW5hbCBTdHJpbmcgcHJlZml4LAotICAgICAgICBmaW5hbCBTdHJpbmcgdXJpKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBzdGFydFByZWZpeE1hcHBpbmcocHJlZml4LHVyaSxmYWxzZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICoKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI3Byb2Nlc3NpbmdJbnN0cnVjdGlvbihTdHJpbmcsIFN0cmluZykKLSAgICAgKiBTZW5kIGEgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiB0byB0aGUgb3V0cHV0IGRvY3VtZW50Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgcHJvY2Vzc2luZ0luc3RydWN0aW9uKFN0cmluZyB0YXJnZXQsIFN0cmluZyBkYXRhKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBmbHVzaFBlbmRpbmcoKTsKLQotICAgICAgICAvLyBQYXNzIHRoZSBwcm9jZXNzaW5nIGluc3RydWN0aW9uIHRvIHRoZSBTQVggaGFuZGxlcgotICAgICAgICBtX3NheEhhbmRsZXIucHJvY2Vzc2luZ0luc3RydWN0aW9uKHRhcmdldCwgZGF0YSk7Ci0KLSAgICAgICAgLy8gd2UgZG9uJ3Qgd2FudCB0byBsZWF2ZSBzZXJpYWxpemVyIHRvIGZpcmUgb2ZmIHRoaXMgZXZlbnQsCi0gICAgICAgIC8vIHNvIGRvIGl0IGhlcmUuCi0gICAgICAgIGlmIChtX3RyYWNlciAhPSBudWxsKQotICAgICAgICAgICAgc3VwZXIuZmlyZUVzY2FwaW5nRXZlbnQodGFyZ2V0LCBkYXRhKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBVbmRlY2xhcmUgdGhlIG5hbWVzcGFjZSB0aGF0IGlzIGN1cnJlbnRseSBwb2ludGVkIHRvIGJ5IGEgZ2l2ZW4KLSAgICAgKiBwcmVmaXguIEluZm9ybSBTQVggaGFuZGxlciBpZiBwcmVmaXggd2FzIHByZXZpb3VzbHkgbWFwcGVkLgotICAgICAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIHBvcE5hbWVzcGFjZShTdHJpbmcgcHJlZml4KQotICAgIHsKLSAgICAgICAgdHJ5Ci0gICAgICAgIHsKLSAgICAgICAgICAgIGlmIChtX3ByZWZpeE1hcC5wb3BOYW1lc3BhY2UocHJlZml4KSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBtX3NheEhhbmRsZXIuZW5kUHJlZml4TWFwcGluZyhwcmVmaXgpOwotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChTQVhFeGNlcHRpb24gZSkKLSAgICAgICAgewotICAgICAgICAgICAgLy8gZmFsbHMgdGhyb3VnaAotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzdGFydENEQVRBKCkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgLyogbV9jZGF0YVRhZ09wZW4gY2FuIG9ubHkgYmUgdHJ1ZSBoZXJlIGlmIHdlIGhhdmUgaWdub3JlZCB0aGUKLSAgICAgICAgICogcHJldmlvdXMgY2FsbCB0byB0aGlzLmVuZENEQVRBKCkgYW5kIHRoZSBwcmV2aW91cyBjYWxsCi0gICAgICAgICAqIHRoaXMuc3RhcnRDREFUQSgpIGJlZm9yZSB0aGF0IGlzIHN0aWxsICJvcGVuIi4gSW4gdGhpcyB3YXkKLSAgICAgICAgICogd2UgbWVyZ2UgYWRqYWNlbnQgQ0RBVEEuIElmIGFueXRoaW5nIGVsc2UgaGFwcGVuZWQgYWZ0ZXIgdGhlCi0gICAgICAgICAqIGlnbm9yZWQgY2FsbCB0byB0aGlzLmVuZENEQVRBKCkgYW5kIHRoaXMgY2FsbCB0aGVuIGEgY2FsbCB0bwotICAgICAgICAgKiBmbHVzaFBlbmRpbmcoKSB3b3VsZCBoYXZlIGJlZW4gbWFkZSB3aGljaCB3b3VsZCBoYXZlCi0gICAgICAgICAqIGNsb3NlZCB0aGUgQ0RBVEEgYW5kIHNldCBtX2NkYXRhVGFnT3BlbiB0byBmYWxzZS4KLSAgICAgICAgICovCi0gICAgICAgIGlmICghbV9jZGF0YVRhZ09wZW4gKQotICAgICAgICB7Ci0gICAgICAgICAgICBmbHVzaFBlbmRpbmcoKTsKLSAgICAgICAgICAgIGlmIChtX2xleEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIG1fbGV4SGFuZGxlci5zdGFydENEQVRBKCk7Ci0KLSAgICAgICAgICAgICAgICAvLyBXZSBoYXZlIG1hZGUgYSBjYWxsIHRvIG1fbGV4SGFuZGxlci5zdGFydENEQVRBKCkgd2l0aAotICAgICAgICAgICAgICAgIC8vIG5vIGJhbGFuY2luZyBjYWxsIHRvIG1fbGV4SGFuZGxlci5lbmRDREFUQSgpCi0gICAgICAgICAgICAgICAgLy8gc28gd2Ugc2V0IG1fY2RhdGFUYWdPcGVuIHRydWUgdG8gcmVtZW1iZXIgdGhpcy4KLSAgICAgICAgICAgICAgICBtX2NkYXRhVGFnT3BlbiA9IHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI3N0YXJ0RWxlbWVudChTdHJpbmcsIFN0cmluZywgU3RyaW5nLCBBdHRyaWJ1dGVzKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudCgKLSAgICBTdHJpbmcgbmFtZXNwYWNlVVJJLAotICAgIFN0cmluZyBsb2NhbE5hbWUsCi0gICAgU3RyaW5nIG5hbWUsCi0gICAgQXR0cmlidXRlcyBhdHRzKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBmbHVzaFBlbmRpbmcoKTsKLSAgICAgICAgc3VwZXIuc3RhcnRFbGVtZW50KG5hbWVzcGFjZVVSSSwgbG9jYWxOYW1lLCBuYW1lLCBhdHRzKTsKLQotICAgICAgICAvLyBIYW5kbGUgZG9jdW1lbnQgdHlwZSBkZWNsYXJhdGlvbiAoZm9yIGZpcnN0IGVsZW1lbnQgb25seSkKLSAgICAgICAgIGlmIChtX25lZWRUb091dHB1dERvY1R5cGVEZWNsKQotICAgICAgICAgewotICAgICAgICAgICAgIFN0cmluZyBkb2N0eXBlU3lzdGVtID0gZ2V0RG9jdHlwZVN5c3RlbSgpOwotICAgICAgICAgICAgIGlmIChkb2N0eXBlU3lzdGVtICE9IG51bGwgJiYgbV9sZXhIYW5kbGVyICE9IG51bGwpCi0gICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICBTdHJpbmcgZG9jdHlwZVB1YmxpYyA9IGdldERvY3R5cGVQdWJsaWMoKTsKLSAgICAgICAgICAgICAgICAgaWYgKGRvY3R5cGVTeXN0ZW0gIT0gbnVsbCkKLSAgICAgICAgICAgICAgICAgICAgIG1fbGV4SGFuZGxlci5zdGFydERURCgKLSAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgIGRvY3R5cGVQdWJsaWMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgZG9jdHlwZVN5c3RlbSk7Ci0gICAgICAgICAgICAgfQotICAgICAgICAgICAgIG1fbmVlZFRvT3V0cHV0RG9jVHlwZURlY2wgPSBmYWxzZTsKLSAgICAgICAgIH0KLSAgICAgICAgbV9lbGVtQ29udGV4dCA9IG1fZWxlbUNvbnRleHQucHVzaChuYW1lc3BhY2VVUkksIGxvY2FsTmFtZSwgbmFtZSk7Ci0KLSAgICAgICAgLy8gZW5zdXJlUHJlZml4SXNEZWNsYXJlZCBkZXBlbmRzIG9uIHRoZSBjdXJyZW50IGRlcHRoLCBzbwotICAgICAgICAvLyB0aGUgcHJldmlvdXMgaW5jcmVtZW50IGlzIG5lY2Vzc2FyeSB3aGVyZSBpdCBpcy4KLSAgICAgICAgaWYgKG5hbWVzcGFjZVVSSSAhPSBudWxsKQotICAgICAgICAgICAgZW5zdXJlUHJlZml4SXNEZWNsYXJlZChuYW1lc3BhY2VVUkksIG5hbWUpOwotCi0gICAgICAgIC8vIGFkZCB0aGUgYXR0cmlidXRlcyB0byB0aGUgY29sbGVjdGVkIG9uZXMKLSAgICAgICAgaWYgKGF0dHMgIT0gbnVsbCkKLSAgICAgICAgICAgIGFkZEF0dHJpYnV0ZXMoYXR0cyk7Ci0KLQotICAgICAgICAvLyBkbyB3ZSByZWFsbHkgbmVlZCB0aGlzIENEQVRBIHNlY3Rpb24gc3RhdGU/Ci0gICAgICAgIG1fZWxlbUNvbnRleHQubV9pc0NkYXRhU2VjdGlvbiA9IGlzQ2RhdGFTZWN0aW9uKCk7Ci0KLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgZW5zdXJlUHJlZml4SXNEZWNsYXJlZChTdHJpbmcgbnMsIFN0cmluZyByYXdOYW1lKQotICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAgewotCi0gICAgICAgIGlmIChucyAhPSBudWxsICYmIG5zLmxlbmd0aCgpID4gMCkKLSAgICAgICAgewotICAgICAgICAgICAgaW50IGluZGV4OwotICAgICAgICAgICAgZmluYWwgYm9vbGVhbiBub19wcmVmaXggPSAoKGluZGV4ID0gcmF3TmFtZS5pbmRleE9mKCI6IikpIDwgMCk7Ci0gICAgICAgICAgICBTdHJpbmcgcHJlZml4ID0gKG5vX3ByZWZpeCkgPyAiIiA6IHJhd05hbWUuc3Vic3RyaW5nKDAsIGluZGV4KTsKLQotCi0gICAgICAgICAgICBpZiAobnVsbCAhPSBwcmVmaXgpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIGZvdW5kVVJJID0gbV9wcmVmaXhNYXAubG9va3VwTmFtZXNwYWNlKHByZWZpeCk7Ci0KLSAgICAgICAgICAgICAgICBpZiAoKG51bGwgPT0gZm91bmRVUkkpIHx8ICFmb3VuZFVSSS5lcXVhbHMobnMpKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGFydFByZWZpeE1hcHBpbmcocHJlZml4LCBucywgZmFsc2UpOwotCi0gICAgICAgICAgICAgICAgICAgIGlmIChnZXRTaG91bGRPdXRwdXROU0F0dHIoKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gQnVnemlsbGExMTMzOiBHZW5lcmF0ZSBhdHRyaWJ1dGUgYXMgd2VsbCBhcyBuYW1lc3BhY2UgZXZlbnQuCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBTQVggZG9lcyBleHBlY3QgYm90aC4KLSAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYWRkQXR0cmlidXRlQWx3YXlzKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3htbG5zLyIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9fcHJlZml4ID8gInhtbG5zIiA6IHByZWZpeCwgIC8vIGxvY2FsIG5hbWUKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBub19wcmVmaXggPyAieG1sbnMiIDogKCJ4bWxuczoiKyBwcmVmaXgpLCAvLyBxbmFtZQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDREFUQSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbnMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0gICAgLyoqCi0gICAgICogQWRkcyB0aGUgZ2l2ZW4gYXR0cmlidXRlIHRvIHRoZSBzZXQgb2YgYXR0cmlidXRlcywgYW5kIGFsc28gbWFrZXMgc3VyZQotICAgICAqIHRoYXQgdGhlIG5lZWRlZCBwcmVmaXgvdXJpIG1hcHBpbmcgaXMgZGVjbGFyZWQsIGJ1dCBvbmx5IGlmIHRoZXJlIGlzIGEKLSAgICAgKiBjdXJyZW50bHkgb3BlbiBlbGVtZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIHVyaSB0aGUgVVJJIG9mIHRoZSBhdHRyaWJ1dGUKLSAgICAgKiBAcGFyYW0gbG9jYWxOYW1lIHRoZSBsb2NhbCBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUKLSAgICAgKiBAcGFyYW0gcmF3TmFtZSAgICB0aGUgcXVhbGlmaWVkIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZQotICAgICAqIEBwYXJhbSB0eXBlIHRoZSB0eXBlIG9mIHRoZSBhdHRyaWJ1dGUgKHByb2JhYmx5IENEQVRBKQotICAgICAqIEBwYXJhbSB2YWx1ZSB0aGUgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZQotICAgICAqIEBwYXJhbSBYU0xBdHRyaWJ1dGUgdHJ1ZSBpZiB0aGlzIGF0dHJpYnV0ZSBpcyBjb21pbmcgZnJvbSBhbiB4c2w6YXR0cmlidXRlIGVsZW1lbnQKLSAgICAgKiBAc2VlIEV4dGVuZGVkQ29udGVudEhhbmRsZXIjYWRkQXR0cmlidXRlKFN0cmluZywgU3RyaW5nLCBTdHJpbmcsIFN0cmluZywgU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGFkZEF0dHJpYnV0ZSgKLSAgICAgICAgU3RyaW5nIHVyaSwKLSAgICAgICAgU3RyaW5nIGxvY2FsTmFtZSwKLSAgICAgICAgU3RyaW5nIHJhd05hbWUsCi0gICAgICAgIFN0cmluZyB0eXBlLAotICAgICAgICBTdHJpbmcgdmFsdWUsCi0gICAgICAgIGJvb2xlYW4gWFNMQXR0cmlidXRlKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAobV9lbGVtQ29udGV4dC5tX3N0YXJ0VGFnT3BlbikKLSAgICAgICAgewotICAgICAgICAgICAgZW5zdXJlUHJlZml4SXNEZWNsYXJlZCh1cmksIHJhd05hbWUpOwotICAgICAgICAgICAgYWRkQXR0cmlidXRlQWx3YXlzKHVyaSwgbG9jYWxOYW1lLCByYXdOYW1lLCB0eXBlLCB2YWx1ZSwgZmFsc2UpOwotICAgICAgICB9Ci0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcnkncyB0byByZXNldCB0aGUgc3VwZXIgY2xhc3MgYW5kIHJlc2V0IHRoaXMgY2xhc3MgZm9yCi0gICAgICogcmUtdXNlLCBzbyB0aGF0IHlvdSBkb24ndCBuZWVkIHRvIGNyZWF0ZSBhIG5ldyBzZXJpYWxpemVyCi0gICAgICogKG1vc3RseSBmb3IgcGVyZm9ybWFuY2UgcmVhc29ucykuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGNsYXNzIHdhcyBzdWNjZXNzZnVseSByZXNldC4KLSAgICAgKiBAc2VlIFNlcmlhbGl6ZXIjcmVzZXQoKQotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIHJlc2V0KCkKLSAgICB7Ci0gICAgICAgIGJvb2xlYW4gd2FzUmVzZXQgPSBmYWxzZTsKLSAgICAgICAgaWYgKHN1cGVyLnJlc2V0KCkpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHJlc2V0VG9YTUxTQVhIYW5kbGVyKCk7Ci0gICAgICAgICAgICB3YXNSZXNldCA9IHRydWU7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHdhc1Jlc2V0OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJlc2V0IGFsbCBvZiB0aGUgZmllbGRzIG93bmVkIGJ5IFRvWE1MU0FYSGFuZGxlciBjbGFzcwotICAgICAqCi0gICAgICovCi0gICAgcHJpdmF0ZSB2b2lkIHJlc2V0VG9YTUxTQVhIYW5kbGVyKCkKLSAgICB7Ci0gICAgICAgIHRoaXMubV9lc2NhcGVTZXR0aW5nID0gdHJ1ZTsKLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvVG9YTUxTdHJlYW0uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvVG9YTUxTdHJlYW0uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDA0NjNiYy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1RvWE1MU3RyZWFtLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw2NTYgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogVG9YTUxTdHJlYW0uamF2YSx2IDEuMi40LjIgMjAwNS8wOS8xNSAxMjowMToyNSBzdXJlc2hfZW1haWxpZCBFeHAgJAotICovCi0gcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXI7Ci0KLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5FcnJvckxpc3RlbmVyOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uUmVzdWx0OwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXI7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplci51dGlscy5Nc2dLZXk7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyLnV0aWxzLlV0aWxzOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGNvbnZlcnRzIFNBWCBvciBTQVgtbGlrZSBjYWxscyB0byBhCi0gKiBzZXJpYWxpemVkIHhtbCBkb2N1bWVudC4gIFRoZSB4c2w6b3V0cHV0IG1ldGhvZCBpcyAieG1sIi4KLSAqCi0gKiBUaGlzIGNsYXNzIGlzIHVzZWQgZXhwbGljaXRseSBpbiBjb2RlIGdlbmVyYXRlZCBieSBYU0xUQywKLSAqIHNvIGl0IGlzICJwdWJsaWMiLCBidXQgaXQgc2hvdWxkCi0gKiBiZSB2aWV3ZWQgYXMgaW50ZXJuYWwgb3IgcGFja2FnZSBwcml2YXRlLCB0aGlzIGlzIG5vdCBhbiBBUEkuCi0gKgotICogQHhzbC51c2FnZSBpbnRlcm5hbAotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgVG9YTUxTdHJlYW0gZXh0ZW5kcyBUb1N0cmVhbQotewotCi0gICAgLyoqCi0gICAgICogcmVtZW1iZXJzIGlmIHdlIG5lZWQgdG8gd3JpdGUgb3V0ICJdXT4iIHRvIGNsb3NlIHRoZSBDREFUQQotICAgICAqLwotICAgIGJvb2xlYW4gbV9jZGF0YVRhZ09wZW4gPSBmYWxzZTsKLQotCi0gICAgLyoqCi0gICAgICogTWFwIHRoYXQgdGVsbHMgd2hpY2ggWE1MIGNoYXJhY3RlcnMgc2hvdWxkIGhhdmUgc3BlY2lhbCB0cmVhdG1lbnQsIGFuZCBpdAotICAgICAqICBwcm92aWRlcyBjaGFyYWN0ZXIgdG8gZW50aXR5IG5hbWUgbG9va3VwLgotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIENoYXJJbmZvIG1feG1sY2hhckluZm8gPQotLy8gICAgICBuZXcgQ2hhckluZm8oQ2hhckluZm8uWE1MX0VOVElUSUVTX1JFU09VUkNFKTsKLSAgICAgICAgQ2hhckluZm8uZ2V0Q2hhckluZm9JbnRlcm5hbChDaGFySW5mby5YTUxfRU5USVRJRVNfUkVTT1VSQ0UsIE1ldGhvZC5YTUwpOwotCi0gICAgLyoqCi0gICAgICogRGVmYXVsdCBjb25zdHJ1Y3Rvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgVG9YTUxTdHJlYW0oKQotICAgIHsKLSAgICAgICAgbV9jaGFySW5mbyA9IG1feG1sY2hhckluZm87Ci0KLSAgICAgICAgaW5pdENEQVRBKCk7Ci0gICAgICAgIC8vIGluaXRpYWxpemUgbmFtZXNwYWNlcwotICAgICAgICBtX3ByZWZpeE1hcCA9IG5ldyBOYW1lc3BhY2VNYXBwaW5ncygpOwotCi0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29weSBwcm9wZXJ0aWVzIGZyb20gYW5vdGhlciBTZXJpYWxpemVyVG9YTUwuCi0gICAgICoKLSAgICAgKiBAcGFyYW0geG1sTGlzdGVuZXIgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGEgU2VyaWFsaXplclRvWE1MIG9iamVjdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBDb3B5RnJvbShUb1hNTFN0cmVhbSB4bWxMaXN0ZW5lcikKLSAgICB7Ci0KLSAgICAgICAgbV93cml0ZXIgPSB4bWxMaXN0ZW5lci5tX3dyaXRlcjsKLQotCi0gICAgICAgIC8vIG1fb3V0cHV0U3RyZWFtID0geG1sTGlzdGVuZXIubV9vdXRwdXRTdHJlYW07Ci0gICAgICAgIFN0cmluZyBlbmNvZGluZyA9IHhtbExpc3RlbmVyLmdldEVuY29kaW5nKCk7Ci0gICAgICAgIHNldEVuY29kaW5nKGVuY29kaW5nKTsKLQotICAgICAgICBzZXRPbWl0WE1MRGVjbGFyYXRpb24oeG1sTGlzdGVuZXIuZ2V0T21pdFhNTERlY2xhcmF0aW9uKCkpOwotCi0gICAgICAgIG1faXNwcmVzZXJ2ZSA9IHhtbExpc3RlbmVyLm1faXNwcmVzZXJ2ZTsKLSAgICAgICAgbV9wcmVzZXJ2ZXMgPSB4bWxMaXN0ZW5lci5tX3ByZXNlcnZlczsKLSAgICAgICAgbV9pc3ByZXZ0ZXh0ID0geG1sTGlzdGVuZXIubV9pc3ByZXZ0ZXh0OwotICAgICAgICBtX2RvSW5kZW50ID0geG1sTGlzdGVuZXIubV9kb0luZGVudDsKLSAgICAgICAgc2V0SW5kZW50QW1vdW50KHhtbExpc3RlbmVyLmdldEluZGVudEFtb3VudCgpKTsKLSAgICAgICAgbV9zdGFydE5ld0xpbmUgPSB4bWxMaXN0ZW5lci5tX3N0YXJ0TmV3TGluZTsKLSAgICAgICAgbV9uZWVkVG9PdXRwdXREb2NUeXBlRGVjbCA9IHhtbExpc3RlbmVyLm1fbmVlZFRvT3V0cHV0RG9jVHlwZURlY2w7Ci0gICAgICAgIHNldERvY3R5cGVTeXN0ZW0oeG1sTGlzdGVuZXIuZ2V0RG9jdHlwZVN5c3RlbSgpKTsKLSAgICAgICAgc2V0RG9jdHlwZVB1YmxpYyh4bWxMaXN0ZW5lci5nZXREb2N0eXBlUHVibGljKCkpOwotICAgICAgICBzZXRTdGFuZGFsb25lKHhtbExpc3RlbmVyLmdldFN0YW5kYWxvbmUoKSk7Ci0gICAgICAgIHNldE1lZGlhVHlwZSh4bWxMaXN0ZW5lci5nZXRNZWRpYVR5cGUoKSk7Ci0gICAgICAgIG1fbWF4Q2hhcmFjdGVyID0geG1sTGlzdGVuZXIubV9tYXhDaGFyYWN0ZXI7Ci0gICAgICAgIG1fZW5jb2RpbmdJbmZvID0geG1sTGlzdGVuZXIubV9lbmNvZGluZ0luZm87Ci0gICAgICAgIG1fc3BhY2VCZWZvcmVDbG9zZSA9IHhtbExpc3RlbmVyLm1fc3BhY2VCZWZvcmVDbG9zZTsKLSAgICAgICAgbV9jZGF0YVN0YXJ0Q2FsbGVkID0geG1sTGlzdGVuZXIubV9jZGF0YVN0YXJ0Q2FsbGVkOwotCi0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIGJlZ2lubmluZyBvZiBhIGRvY3VtZW50LgotICAgICAqCi0gICAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICAgKgotICAgICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnREb2N1bWVudEludGVybmFsKCkgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgIHsKLQotICAgICAgICBpZiAobV9uZWVkVG9DYWxsU3RhcnREb2N1bWVudCkKLSAgICAgICAgewotICAgICAgICAgICAgc3VwZXIuc3RhcnREb2N1bWVudEludGVybmFsKCk7Ci0gICAgICAgICAgICBtX25lZWRUb0NhbGxTdGFydERvY3VtZW50ID0gZmFsc2U7Ci0KLSAgICAgICAgICAgIGlmIChtX2luRW50aXR5UmVmKQotICAgICAgICAgICAgICAgIHJldHVybjsKLQotICAgICAgICAgICAgbV9uZWVkVG9PdXRwdXREb2NUeXBlRGVjbCA9IHRydWU7Ci0gICAgICAgICAgICBtX3N0YXJ0TmV3TGluZSA9IGZhbHNlOwotICAgICAgICAgICAgLyogVGhlIGNhbGwgdG8gZ2V0WE1MVmVyc2lvbigpIG1pZ2h0IGVtaXQgYW4gZXJyb3IgbWVzc2FnZQotICAgICAgICAgICAgICogYW5kIHdlIHNob3VsZCBlbWl0IHRoaXMgbWVzc2FnZSByZWdhcmRsZXNzIG9mIGlmIHdlIGFyZQotICAgICAgICAgICAgICogd3JpdGluZyBvdXQgYW4gWE1MIGhlYWRlciBvciBub3QuCi0gICAgICAgICAgICAgKi8KLSAgICAgICAgICAgIGlmIChnZXRPbWl0WE1MRGVjbGFyYXRpb24oKSA9PSBmYWxzZSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgZW5jb2RpbmcgPSBFbmNvZGluZ3MuZ2V0TWltZUVuY29kaW5nKGdldEVuY29kaW5nKCkpOwotICAgICAgICAgICAgICAgIFN0cmluZyB2ZXJzaW9uID0gZ2V0VmVyc2lvbigpOwotICAgICAgICAgICAgICAgIGlmICh2ZXJzaW9uID09IG51bGwpCi0gICAgICAgICAgICAgICAgICAgIHZlcnNpb24gPSAiMS4wIjsKLSAgICAgICAgICAgICAgICBTdHJpbmcgc3RhbmRhbG9uZTsKLQotICAgICAgICAgICAgICAgIGlmIChtX3N0YW5kYWxvbmVXYXNTcGVjaWZpZWQpCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICBzdGFuZGFsb25lID0gIiBzdGFuZGFsb25lPVwiIiArIGdldFN0YW5kYWxvbmUoKSArICJcIiI7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIHN0YW5kYWxvbmUgPSAiIjsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICB0cnkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIGZpbmFsIGphdmEuaW8uV3JpdGVyIHdyaXRlciA9IG1fd3JpdGVyOwotICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoIjw/eG1sIHZlcnNpb249XCIiKTsKLSAgICAgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKHZlcnNpb24pOwotICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoIlwiIGVuY29kaW5nPVwiIik7Ci0gICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZShlbmNvZGluZyk7Ci0gICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZSgnXCInKTsKLSAgICAgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKHN0YW5kYWxvbmUpOwotICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoIj8+Iik7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChtX2RvSW5kZW50KSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAobV9zdGFuZGFsb25lV2FzU3BlY2lmaWVkCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IGdldERvY3R5cGVQdWJsaWMoKSAhPSBudWxsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IGdldERvY3R5cGVTeXN0ZW0oKSAhPSBudWxsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IG1faXNTdGFuZGFsb25lKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gV2UgYWxtb3N0IG5ldmVyIHB1dCBhIG5ld2xpbmUgYWZ0ZXIgdGhlIFhNTAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGhlYWRlciBiZWNhdXNlIHRoaXMgWE1MIGNvdWxkIGJlIHVzZWQgYXMKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBhbiBleHRlbmFsIGdlbmVyYWwgcGFyc2VkIGVudGl0eQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFuZCB3ZSBkb24ndCBrbm93IHRoZSBjb250ZXh0IGludG8gd2hpY2ggaXQKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB3aWxsIGJlIHVzZWQgaW4gdGhlIGZ1dHVyZS4gIE9ubHkgd2hlbgotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHN0YW5kYWxvbmUsIG9yIGEgZG9jdHlwZSBzeXN0ZW0gb3IgcHVibGljIGlzCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc3BlY2lmaWVkIGFyZSB3ZSBmcmVlIHRvIGluc2VydCBhIG5ldyBsaW5lCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYWZ0ZXIgdGhlIGhlYWRlci4gIElzIGl0IGV2ZW4gd29ydGggYm90aGVyaW5nCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaW4gdGhlc2UgcmFyZSBjYXNlcz8KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUobV9saW5lU2VwLCAwLCBtX2xpbmVTZXBMZW4pOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGNhdGNoKElPRXhjZXB0aW9uIGUpCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKGUpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIGVuZCBvZiBhIGRvY3VtZW50LgotICAgICAqCi0gICAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICAgKgotICAgICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kRG9jdW1lbnQoKSB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBmbHVzaFBlbmRpbmcoKTsKLSAgICAgICAgaWYgKG1fZG9JbmRlbnQgJiYgIW1faXNwcmV2dGV4dCkKLSAgICAgICAgewotICAgICAgICAgICAgdHJ5Ci0gICAgICAgICAgICB7Ci0gICAgICAgICAgICBvdXRwdXRMaW5lU2VwKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXRjaChJT0V4Y2VwdGlvbiBlKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBmbHVzaFdyaXRlcigpOwotCi0gICAgICAgIGlmIChtX3RyYWNlciAhPSBudWxsKQotICAgICAgICAgICAgc3VwZXIuZmlyZUVuZERvYygpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFN0YXJ0cyBhIHdoaXRlc3BhY2UgcHJlc2VydmluZyBzZWN0aW9uLiBBbGwgY2hhcmFjdGVycyBwcmludGVkCi0gICAgICogd2l0aGluIGEgcHJlc2VydmluZyBzZWN0aW9uIGFyZSBwcmludGVkIHdpdGhvdXQgaW5kZW50YXRpb24gYW5kCi0gICAgICogd2l0aG91dCBjb25zb2xpZGF0aW5nIG11bHRpcGxlIHNwYWNlcy4gVGhpcyBpcyBlcXVpdmFsZW50IHRvCi0gICAgICogdGhlIDx0dD54bWw6c3BhY2U9JnF1b3Q7cHJlc2VydmUmcXVvdDs8L3R0PiBhdHRyaWJ1dGUuIE9ubHkgWE1MCi0gICAgICogYW5kIEhUTUwgc2VyaWFsaXplcnMgbmVlZCB0byBzdXBwb3J0IHRoaXMgbWV0aG9kLgotICAgICAqIDxwPgotICAgICAqIFRoZSBjb250ZW50cyBvZiB0aGUgd2hpdGVzcGFjZSBwcmVzZXJ2aW5nIHNlY3Rpb24gd2lsbCBiZSBkZWxpdmVyZWQKLSAgICAgKiB0aHJvdWdoIHRoZSByZWd1bGFyIDx0dD5jaGFyYWN0ZXJzPC90dD4gZXZlbnQuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0UHJlc2VydmluZygpIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICB7Ci0KLSAgICAgICAgLy8gTm90IHN1cmUgdGhpcyBpcyByZWFsbHkgd2hhdCB3ZSB3YW50LiAgLXNiCi0gICAgICAgIG1fcHJlc2VydmVzLnB1c2godHJ1ZSk7Ci0KLSAgICAgICAgbV9pc3ByZXNlcnZlID0gdHJ1ZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBFbmRzIGEgd2hpdGVzcGFjZSBwcmVzZXJ2aW5nIHNlY3Rpb24uCi0gICAgICoKLSAgICAgKiBAc2VlICNzdGFydFByZXNlcnZpbmcKLSAgICAgKgotICAgICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kUHJlc2VydmluZygpIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICB7Ci0KLSAgICAgICAgLy8gTm90IHN1cmUgdGhpcyBpcyByZWFsbHkgd2hhdCB3ZSB3YW50LiAgLXNiCi0gICAgICAgIG1faXNwcmVzZXJ2ZSA9IG1fcHJlc2VydmVzLmlzRW1wdHkoKSA/IGZhbHNlIDogbV9wcmVzZXJ2ZXMucG9wKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgYSBwcm9jZXNzaW5nIGluc3RydWN0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIHRhcmdldCBUaGUgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiB0YXJnZXQuCi0gICAgICogQHBhcmFtIGRhdGEgVGhlIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gZGF0YSwgb3IgbnVsbCBpZgotICAgICAqICAgICAgICBub25lIHdhcyBzdXBwbGllZC4KLSAgICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgICAqCi0gICAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oU3RyaW5nIHRhcmdldCwgU3RyaW5nIGRhdGEpCi0gICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGlmIChtX2luRW50aXR5UmVmKQotICAgICAgICAgICAgcmV0dXJuOwotCi0gICAgICAgIGZsdXNoUGVuZGluZygpOwotCi0gICAgICAgIGlmICh0YXJnZXQuZXF1YWxzKFJlc3VsdC5QSV9ESVNBQkxFX09VVFBVVF9FU0NBUElORykpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHN0YXJ0Tm9uRXNjYXBpbmcoKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICh0YXJnZXQuZXF1YWxzKFJlc3VsdC5QSV9FTkFCTEVfT1VUUFVUX0VTQ0FQSU5HKSkKLSAgICAgICAgewotICAgICAgICAgICAgZW5kTm9uRXNjYXBpbmcoKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgIHsKLSAgICAgICAgICAgIHRyeQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIGlmIChtX2VsZW1Db250ZXh0Lm1fc3RhcnRUYWdPcGVuKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgY2xvc2VTdGFydFRhZygpOwotICAgICAgICAgICAgICAgICAgICBtX2VsZW1Db250ZXh0Lm1fc3RhcnRUYWdPcGVuID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgaWYgKG1fbmVlZFRvQ2FsbFN0YXJ0RG9jdW1lbnQpCi0gICAgICAgICAgICAgICAgICAgIHN0YXJ0RG9jdW1lbnRJbnRlcm5hbCgpOwotCi0gICAgICAgICAgICAgICAgaWYgKHNob3VsZEluZGVudCgpKQotICAgICAgICAgICAgICAgICAgICBpbmRlbnQoKTsKLQotICAgICAgICAgICAgICAgIGZpbmFsIGphdmEuaW8uV3JpdGVyIHdyaXRlciA9IG1fd3JpdGVyOwotICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZSgiPD8iKTsKLSAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUodGFyZ2V0KTsKLQotICAgICAgICAgICAgICAgIGlmIChkYXRhLmxlbmd0aCgpID4gMAotICAgICAgICAgICAgICAgICAgICAmJiAhQ2hhcmFjdGVyLmlzU3BhY2VDaGFyKGRhdGEuY2hhckF0KDApKSkKLSAgICAgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKCcgJyk7Ci0KLSAgICAgICAgICAgICAgICBpbnQgaW5kZXhPZlFMVCA9IGRhdGEuaW5kZXhPZigiPz4iKTsKLQotICAgICAgICAgICAgICAgIGlmIChpbmRleE9mUUxUID49IDApCi0gICAgICAgICAgICAgICAgewotCi0gICAgICAgICAgICAgICAgICAgIC8vIFNlZSBYU0xUIHNwZWMgb24gZXJyb3IgcmVjb3Zlcnkgb2YgIj8+IiBpbiBQSXMuCi0gICAgICAgICAgICAgICAgICAgIGlmIChpbmRleE9mUUxUID4gMCkKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKGRhdGEuc3Vic3RyaW5nKDAsIGluZGV4T2ZRTFQpKTsKLSAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZSgiPyA+Iik7IC8vIGFkZCBzcGFjZSBiZXR3ZWVuLgotCi0gICAgICAgICAgICAgICAgICAgIGlmICgoaW5kZXhPZlFMVCArIDIpIDwgZGF0YS5sZW5ndGgoKSkKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKGRhdGEuc3Vic3RyaW5nKGluZGV4T2ZRTFQgKyAyKSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKGRhdGEpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZSgnPycpOwotICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZSgnPicpOwotCi0gICAgICAgICAgICAgICAgLyoqCi0gICAgICAgICAgICAgICAgICogQmVmb3JlIFhhbGFuIDE0OTcsIGEgbmV3bGluZSBjaGFyIHdhcyBwcmludGVkIG91dCBpZiBub3QgaW5zaWRlIG9mIGFuCi0gICAgICAgICAgICAgICAgICogZWxlbWVudC4gVGhlIHdoaXRlc3BhY2UgaXMgbm90IHNpZ25pZmljYW50IGlzIHRoZSBvdXRwdXQgaXMgc3RhbmRhbG9uZQotICAgICAgICAgICAgICAgICovCi0gICAgICAgICAgICAgICAgaWYgKG1fZWxlbUNvbnRleHQubV9jdXJyZW50RWxlbURlcHRoIDw9IDAgJiYgbV9pc1N0YW5kYWxvbmUpCi0gICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZShtX2xpbmVTZXAsIDAsIG1fbGluZVNlcExlbik7Ci0KLQotICAgICAgICAgICAgICAgIC8qCi0gICAgICAgICAgICAgICAgICogRG9uJ3Qgd3JpdGUgb3V0IGFueSBpbmRlbnRhdGlvbiB3aGl0ZXNwYWNlIG5vdywKLSAgICAgICAgICAgICAgICAgKiBiZWNhdXNlIHRoZXJlIG1heSBiZSBub24td2hpdGVzcGFjZSB0ZXh0IGFmdGVyIHRoaXMuCi0gICAgICAgICAgICAgICAgICoKLSAgICAgICAgICAgICAgICAgKiBTaW1wbHkgbWFyayB0aGF0IGF0IHRoaXMgcG9pbnQgaWYgd2UgZG8gZGVjaWRlCi0gICAgICAgICAgICAgICAgICogdG8gaW5kZW50IHRoYXQgd2Ugc2hvdWxkCi0gICAgICAgICAgICAgICAgICogYWRkIGEgbmV3bGluZSBvbiB0aGUgZW5kIG9mIHRoZSBjdXJyZW50IGxpbmUgYmVmb3JlCi0gICAgICAgICAgICAgICAgICogdGhlIGluZGVudGF0aW9uIGF0IHRoZSBzdGFydCBvZiB0aGUgbmV4dCBsaW5lLgotICAgICAgICAgICAgICAgICAqLwotICAgICAgICAgICAgICAgIG1fc3RhcnROZXdMaW5lID0gdHJ1ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhdGNoKElPRXhjZXB0aW9uIGUpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbihlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGlmIChtX3RyYWNlciAhPSBudWxsKQotICAgICAgICAgICAgc3VwZXIuZmlyZUVzY2FwaW5nRXZlbnQodGFyZ2V0LCBkYXRhKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZWNlaXZlIG5vdGl2aWNhdGlvbiBvZiBhIGVudGl0eVJlZmVyZW5jZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBlbnRpdHkuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVudGl0eVJlZmVyZW5jZShTdHJpbmcgbmFtZSkgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaWYgKG1fZWxlbUNvbnRleHQubV9zdGFydFRhZ09wZW4pCi0gICAgICAgIHsKLSAgICAgICAgICAgIGNsb3NlU3RhcnRUYWcoKTsKLSAgICAgICAgICAgIG1fZWxlbUNvbnRleHQubV9zdGFydFRhZ09wZW4gPSBmYWxzZTsKLSAgICAgICAgfQotCi0gICAgICAgIHRyeQotICAgICAgICB7Ci0gICAgICAgICAgICBpZiAoc2hvdWxkSW5kZW50KCkpCi0gICAgICAgICAgICAgICAgaW5kZW50KCk7Ci0KLSAgICAgICAgICAgIGZpbmFsIGphdmEuaW8uV3JpdGVyIHdyaXRlciA9IG1fd3JpdGVyOwotICAgICAgICAgICAgd3JpdGVyLndyaXRlKCcmJyk7Ci0gICAgICAgICAgICB3cml0ZXIud3JpdGUobmFtZSk7Ci0gICAgICAgICAgICB3cml0ZXIud3JpdGUoJzsnKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaChJT0V4Y2VwdGlvbiBlKQotICAgICAgICB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKGUpOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKG1fdHJhY2VyICE9IG51bGwpCi0gICAgICAgICAgICBzdXBlci5maXJlRW50aXR5UmVmZXJlbmNlKG5hbWUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIGlzIHVzZWQgdG8gYWRkIGFuIGF0dHJpYnV0ZSB0byB0aGUgY3VycmVudGx5IG9wZW4gZWxlbWVudC4KLSAgICAgKiBUaGUgY2FsbGVyIGhhcyBndWFyYW50ZWQgdGhhdCB0aGlzIGF0dHJpYnV0ZSBpcyB1bmlxdWUsIHdoaWNoIG1lYW5zIHRoYXQgaXQKLSAgICAgKiBub3QgYmVlbiBzZWVuIGJlZm9yZSBhbmQgd2lsbCBub3QgYmUgc2VlbiBhZ2Fpbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lIHRoZSBxdWFsaWZpZWQgbmFtZSBvZiB0aGUgYXR0cmlidXRlCi0gICAgICogQHBhcmFtIHZhbHVlIHRoZSB2YWx1ZSBvZiB0aGUgYXR0cmlidXRlIHdoaWNoIGNhbiBjb250YWluIG9ubHkKLSAgICAgKiBBU0NJSSBwcmludGFibGUgY2hhcmFjdGVycyBjaGFyYWN0ZXJzIGluIHRoZSByYW5nZSAzMiB0byAxMjcgaW5jbHVzaXZlLgotICAgICAqIEBwYXJhbSBmbGFncyB0aGUgYml0IHZhbHVlcyBvZiB0aGlzIGludGVnZXIgZ2l2ZSBvcHRpbWl6YXRpb24gaW5mb3JtYXRpb24uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgYWRkVW5pcXVlQXR0cmlidXRlKFN0cmluZyBuYW1lLCBTdHJpbmcgdmFsdWUsIGludCBmbGFncykKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaWYgKG1fZWxlbUNvbnRleHQubV9zdGFydFRhZ09wZW4pCi0gICAgICAgIHsKLQotICAgICAgICAgICAgdHJ5Ci0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIHBhdGNoZWROYW1lID0gcGF0Y2hOYW1lKG5hbWUpOwotICAgICAgICAgICAgICAgIGZpbmFsIGphdmEuaW8uV3JpdGVyIHdyaXRlciA9IG1fd3JpdGVyOwotICAgICAgICAgICAgICAgIGlmICgoZmxhZ3MgJiBOT19CQURfQ0hBUlMpID4gMCAmJiBtX3htbGNoYXJJbmZvLm9ubHlRdW90QW1wTHRHdCkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIC8vICJmbGFncyIgaGFzIGluZGljYXRlZCB0aGF0IHRoZSBjaGFyYWN0ZXJzCi0gICAgICAgICAgICAgICAgICAgIC8vICc+JyAgJzwnICAgJyYnICBhbmQgJyInIGFyZSBub3QgaW4gdGhlIHZhbHVlIGFuZAotICAgICAgICAgICAgICAgICAgICAvLyBtX2h0bWxjaGFySW5mbyBoYXMgcmVjb3JkZWQgdGhhdCB0aGVyZSBhcmUgbm8gb3RoZXIKLSAgICAgICAgICAgICAgICAgICAgLy8gZW50aXRpZXMgaW4gdGhlIHJhbmdlIDMyIHRvIDEyNyBzbyB3ZSB3cml0ZSBvdXQgdGhlCi0gICAgICAgICAgICAgICAgICAgIC8vIHZhbHVlIGRpcmVjdGx5Ci0KLSAgICAgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKCcgJyk7Ci0gICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZShwYXRjaGVkTmFtZSk7Ci0gICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZSgiPVwiIik7Ci0gICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZSh2YWx1ZSk7Ci0gICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZSgnIicpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoJyAnKTsKLSAgICAgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKHBhdGNoZWROYW1lKTsKLSAgICAgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKCI9XCIiKTsKLSAgICAgICAgICAgICAgICAgICAgd3JpdGVBdHRyU3RyaW5nKHdyaXRlciwgdmFsdWUsIHRoaXMuZ2V0RW5jb2RpbmcoKSk7Ci0gICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZSgnIicpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKGUpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQWRkIGFuIGF0dHJpYnV0ZSB0byB0aGUgY3VycmVudCBlbGVtZW50LgotICAgICAqIEBwYXJhbSB1cmkgdGhlIFVSSSBhc3NvY2lhdGVkIHdpdGggdGhlIGVsZW1lbnQgbmFtZQotICAgICAqIEBwYXJhbSBsb2NhbE5hbWUgbG9jYWwgcGFydCBvZiB0aGUgYXR0cmlidXRlIG5hbWUKLSAgICAgKiBAcGFyYW0gcmF3TmFtZSAgIHByZWZpeDpsb2NhbE5hbWUKLSAgICAgKiBAcGFyYW0gdHlwZQotICAgICAqIEBwYXJhbSB2YWx1ZSB0aGUgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZQotICAgICAqIEBwYXJhbSB4c2xBdHRyaWJ1dGUgdHJ1ZSBpZiB0aGlzIGF0dHJpYnV0ZSBpcyBmcm9tIGFuIHhzbDphdHRyaWJ1dGUsCi0gICAgICogZmFsc2UgaWYgZGVjbGFyZWQgd2l0aGluIHRoZSBlbGVtZW50cyBvcGVuaW5nIHRhZy4KLSAgICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGFkZEF0dHJpYnV0ZSgKLSAgICAgICAgU3RyaW5nIHVyaSwKLSAgICAgICAgU3RyaW5nIGxvY2FsTmFtZSwKLSAgICAgICAgU3RyaW5nIHJhd05hbWUsCi0gICAgICAgIFN0cmluZyB0eXBlLAotICAgICAgICBTdHJpbmcgdmFsdWUsCi0gICAgICAgIGJvb2xlYW4geHNsQXR0cmlidXRlKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAobV9lbGVtQ29udGV4dC5tX3N0YXJ0VGFnT3BlbikKLSAgICAgICAgewotICAgICAgICAgICAgYm9vbGVhbiB3YXNfYWRkZWQgPSBhZGRBdHRyaWJ1dGVBbHdheXModXJpLCBsb2NhbE5hbWUsIHJhd05hbWUsIHR5cGUsIHZhbHVlLCB4c2xBdHRyaWJ1dGUpOwotCi0KLSAgICAgICAgICAgIC8qCi0gICAgICAgICAgICAgKiBXZSBkb24ndCBydW4gdGhpcyBibG9jayBvZiBjb2RlIGlmOgotICAgICAgICAgICAgICogMS4gVGhlIGF0dHJpYnV0ZSB2YWx1ZSB3YXMgb25seSByZXBsYWNlZCAod2FzX2FkZGVkIGlzIGZhbHNlKS4KLSAgICAgICAgICAgICAqIDIuIFRoZSBhdHRyaWJ1dGUgaXMgZnJvbSBhbiB4c2w6YXR0cmlidXRlIGVsZW1lbnQgKHRoYXQgaXMgaGFuZGxlZAotICAgICAgICAgICAgICogICAgaW4gdGhlIGFkZEF0dHJpYnV0ZUFsd2F5cygpIGNhbGwganVzdCBhYm92ZS4KLSAgICAgICAgICAgICAqIDMuIFRoZSBuYW1lIHN0YXJ0cyB3aXRoICJ4bWxucyIsIGkuZS4gaXQgaXMgYSBuYW1lc3BhY2UgZGVjbGFyYXRpb24uCi0gICAgICAgICAgICAgKi8KLSAgICAgICAgICAgIGlmICh3YXNfYWRkZWQgJiYgIXhzbEF0dHJpYnV0ZSAmJiAhcmF3TmFtZS5zdGFydHNXaXRoKCJ4bWxucyIpKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIFN0cmluZyBwcmVmaXhVc2VkID0KLSAgICAgICAgICAgICAgICAgICAgZW5zdXJlQXR0cmlidXRlc05hbWVzcGFjZUlzRGVjbGFyZWQoCi0gICAgICAgICAgICAgICAgICAgICAgICB1cmksCi0gICAgICAgICAgICAgICAgICAgICAgICBsb2NhbE5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICByYXdOYW1lKTsKLSAgICAgICAgICAgICAgICBpZiAocHJlZml4VXNlZCAhPSBudWxsCi0gICAgICAgICAgICAgICAgICAgICYmIHJhd05hbWUgIT0gbnVsbAotICAgICAgICAgICAgICAgICAgICAmJiAhcmF3TmFtZS5zdGFydHNXaXRoKHByZWZpeFVzZWQpKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gdXNlIGEgZGlmZmVyZW50IHJhdyBuYW1lLCB3aXRoIHRoZSBwcmVmaXggdXNlZCBpbiB0aGUKLSAgICAgICAgICAgICAgICAgICAgLy8gZ2VuZXJhdGVkIG5hbWVzcGFjZSBkZWNsYXJhdGlvbgotICAgICAgICAgICAgICAgICAgICByYXdOYW1lID0gcHJlZml4VXNlZCArICI6IiArIGxvY2FsTmFtZTsKLQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGFkZEF0dHJpYnV0ZUFsd2F5cyh1cmksIGxvY2FsTmFtZSwgcmF3TmFtZSwgdHlwZSwgdmFsdWUsIHhzbEF0dHJpYnV0ZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICB7Ci0gICAgICAgICAgICAvKgotICAgICAgICAgICAgICogVGhlIHN0YXJ0VGFnIGlzIGNsb3NlZCwgeWV0IHdlIGFyZSBhZGRpbmcgYW4gYXR0cmlidXRlPwotICAgICAgICAgICAgICoKLSAgICAgICAgICAgICAqIFNlY3Rpb246IDcuMS4zIENyZWF0aW5nIEF0dHJpYnV0ZXMgQWRkaW5nIGFuIGF0dHJpYnV0ZSB0byBhbgotICAgICAgICAgICAgICogZWxlbWVudCBhZnRlciBhIFBJIChmb3IgZXhhbXBsZSkgaGFzIGJlZW4gYWRkZWQgdG8gaXQgaXMgYW4KLSAgICAgICAgICAgICAqIGVycm9yLiBUaGUgYXR0cmlidXRlcyBjYW4gYmUgaWdub3JlZC4gVGhlIHNwZWMgZG9lc24ndCBleHBsaWNpdGx5Ci0gICAgICAgICAgICAgKiBzYXkgdGhpcyBpcyBkaXNhbGxvd2VkLCBhcyBpdCBkb2VzIGZvciBjaGlsZCBlbGVtZW50cywgYnV0IGl0Ci0gICAgICAgICAgICAgKiBtYWtlcyBzZW5zZSB0byBoYXZlIHRoZSBzYW1lIHRyZWF0bWVudC4KLSAgICAgICAgICAgICAqCi0gICAgICAgICAgICAgKiBXZSBjaG9vc2UgdG8gaWdub3JlIHRoZSBhdHRyaWJ1dGUgd2hpY2ggaXMgYWRkZWQgdG9vIGxhdGUuCi0gICAgICAgICAgICAgKi8KLSAgICAgICAgICAgIC8vIEdlbmVyYXRlIGEgd2FybmluZyBvZiB0aGUgaWdub3JlZCBhdHRyaWJ1dGVzCi0KLSAgICAgICAgICAgIC8vIENyZWF0ZSB0aGUgd2FybmluZyBtZXNzYWdlCi0gICAgICAgICAgICBTdHJpbmcgbXNnID0gVXRpbHMubWVzc2FnZXMuY3JlYXRlTWVzc2FnZSgKLSAgICAgICAgICAgICAgICAgICAgTXNnS2V5LkVSX0lMTEVHQUxfQVRUUklCVVRFX1BPU0lUSU9OLG5ldyBPYmplY3RbXXsgbG9jYWxOYW1lIH0pOwotCi0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIC8vIFByZXBhcmUgdG8gaXNzdWUgdGhlIHdhcm5pbmcgbWVzc2FnZQotICAgICAgICAgICAgICAgIFRyYW5zZm9ybWVyIHRyYW4gPSBzdXBlci5nZXRUcmFuc2Zvcm1lcigpOwotICAgICAgICAgICAgICAgIEVycm9yTGlzdGVuZXIgZXJySGFuZGxlciA9IHRyYW4uZ2V0RXJyb3JMaXN0ZW5lcigpOwotCi0KLSAgICAgICAgICAgICAgICAvLyBJc3N1ZSB0aGUgd2FybmluZyBtZXNzYWdlCi0gICAgICAgICAgICAgICAgaWYgKG51bGwgIT0gZXJySGFuZGxlciAmJiBtX3NvdXJjZUxvY2F0b3IgIT0gbnVsbCkKLSAgICAgICAgICAgICAgICAgIGVyckhhbmRsZXIud2FybmluZyhuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24obXNnLCBtX3NvdXJjZUxvY2F0b3IpKTsKLSAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4obXNnKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGUpe30KLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgRXh0ZW5kZWRDb250ZW50SGFuZGxlciNlbmRFbGVtZW50KFN0cmluZykKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbmRFbGVtZW50KFN0cmluZyBlbGVtTmFtZSkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgZW5kRWxlbWVudChudWxsLCBudWxsLCBlbGVtTmFtZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgaXMgdXNlZCB0byBub3RpZnkgdGhlIHNlcmlhbGl6ZXIgb2YgYSBuYW1lc3BhY2UgbWFwcGluZyAob3Igbm9kZSkKLSAgICAgKiB0aGF0IGFwcGxpZXMgdG8gdGhlIGN1cnJlbnQgZWxlbWVudCB3aG9zZSBzdGFydEVsZW1lbnQoKSBjYWxsIGhhcyBhbHJlYWR5IGJlZW4gc2Vlbi4KLSAgICAgKiBUaGUgb2ZmaWNpYWwgU0FYIHN0YXJ0UHJlZml4TWFwcGluZyhwcmVmaXgsdXJpKSBpcyB0byBkZWZpbmUgYSBtYXBwaW5nIGZvciBhIGNoaWxkCi0gICAgICogZWxlbWVudCB0aGF0IGlzIHNvb24gdG8gYmUgc2VlbiB3aXRoIGEgc3RhcnRFbGVtZW50KCkgY2FsbC4gVGhlIG9mZmljaWFsIFNBWCBjYWxsCi0gICAgICogZG9lcyBub3QgYXBwbHkgdG8gdGhlIGN1cnJlbnQgZWxlbWVudCwgaGVuY2UgdGhlIHJlYXNvbiBmb3IgdGhpcyBtZXRob2QuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgbmFtZXNwYWNlQWZ0ZXJTdGFydEVsZW1lbnQoCi0gICAgICAgIGZpbmFsIFN0cmluZyBwcmVmaXgsCi0gICAgICAgIGZpbmFsIFN0cmluZyB1cmkpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0KLSAgICAgICAgLy8gaGFjayBmb3IgWFNMVEMgd2l0aCBmaW5kaW5nIFVSSSBmb3IgZGVmYXVsdCBuYW1lc3BhY2UKLSAgICAgICAgaWYgKG1fZWxlbUNvbnRleHQubV9lbGVtZW50VVJJID09IG51bGwpCi0gICAgICAgIHsKLSAgICAgICAgICAgIFN0cmluZyBwcmVmaXgxID0gZ2V0UHJlZml4UGFydChtX2VsZW1Db250ZXh0Lm1fZWxlbWVudE5hbWUpOwotICAgICAgICAgICAgaWYgKHByZWZpeDEgPT0gbnVsbCAmJiBFTVBUWVNUUklORy5lcXVhbHMocHJlZml4KSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAvLyB0aGUgZWxlbWVudHMgVVJJIGlzIG5vdCBrbm93biB5ZXQsIGFuZCBpdAotICAgICAgICAgICAgICAgIC8vIGRvZXNuJ3QgaGF2ZSBhIHByZWZpeCwgYW5kIHdlIGFyZSBjdXJyZW50bHkKLSAgICAgICAgICAgICAgICAvLyBzZXR0aW5nIHRoZSB1cmkgZm9yIHByZWZpeCAiIiwgc28gd2UgaGF2ZQotICAgICAgICAgICAgICAgIC8vIHRoZSB1cmkgZm9yIHRoZSBlbGVtZW50Li4uIGxldHMgcmVtZW1iZXIgaXQKLSAgICAgICAgICAgICAgICBtX2VsZW1Db250ZXh0Lm1fZWxlbWVudFVSSSA9IHVyaTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBzdGFydFByZWZpeE1hcHBpbmcocHJlZml4LHVyaSxmYWxzZSk7Ci0gICAgICAgIHJldHVybjsKLQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEZyb20gWFNMVEMKLSAgICAgKiBEZWNsYXJlIGEgcHJlZml4IHRvIHBvaW50IHRvIGEgbmFtZXNwYWNlIFVSSS4gSW5mb3JtIFNBWCBoYW5kbGVyCi0gICAgICogaWYgdGhpcyBpcyBhIG5ldyBwcmVmaXggbWFwcGluZy4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBwdXNoTmFtZXNwYWNlKFN0cmluZyBwcmVmaXgsIFN0cmluZyB1cmkpCi0gICAgewotICAgICAgICB0cnkKLSAgICAgICAgewotICAgICAgICAgICAgaWYgKG1fcHJlZml4TWFwLnB1c2hOYW1lc3BhY2UoCi0gICAgICAgICAgICAgICAgcHJlZml4LCB1cmksIG1fZWxlbUNvbnRleHQubV9jdXJyZW50RWxlbURlcHRoKSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBzdGFydFByZWZpeE1hcHBpbmcocHJlZml4LCB1cmkpOwotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChTQVhFeGNlcHRpb24gZSkKLSAgICAgICAgewotICAgICAgICAgICAgLy8gZmFsbHMgdGhyb3VnaAotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0gICAgLyoqCi0gICAgICogVHJ5J3MgdG8gcmVzZXQgdGhlIHN1cGVyIGNsYXNzIGFuZCByZXNldCB0aGlzIGNsYXNzIGZvcgotICAgICAqIHJlLXVzZSwgc28gdGhhdCB5b3UgZG9uJ3QgbmVlZCB0byBjcmVhdGUgYSBuZXcgc2VyaWFsaXplcgotICAgICAqIChtb3N0bHkgZm9yIHBlcmZvcm1hbmNlIHJlYXNvbnMpLgotICAgICAqCi0gICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBjbGFzcyB3YXMgc3VjY2Vzc2Z1bHkgcmVzZXQuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gcmVzZXQoKQotICAgIHsKLSAgICAgICAgYm9vbGVhbiB3YXNSZXNldCA9IGZhbHNlOwotICAgICAgICBpZiAoc3VwZXIucmVzZXQoKSkKLSAgICAgICAgewotICAgICAgICAgICAgcmVzZXRUb1hNTFN0cmVhbSgpOwotICAgICAgICAgICAgd2FzUmVzZXQgPSB0cnVlOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiB3YXNSZXNldDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXNldCBhbGwgb2YgdGhlIGZpZWxkcyBvd25lZCBieSBUb1N0cmVhbSBjbGFzcwotICAgICAqCi0gICAgICovCi0gICAgcHJpdmF0ZSB2b2lkIHJlc2V0VG9YTUxTdHJlYW0oKQotICAgIHsKLSAgICAgICAgdGhpcy5tX2NkYXRhVGFnT3BlbiA9IGZhbHNlOwotCi0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgY2hlY2tzIGZvciB0aGUgWE1MIHZlcnNpb24gb2Ygb3V0cHV0IGRvY3VtZW50LgotICAgICAqIElmIFhNTCB2ZXJzaW9uIG9mIG91dHB1dCBkb2N1bWVudCBpcyBub3Qgc3BlY2lmaWVkLCB0aGVuIG91dHB1dAotICAgICAqIGRvY3VtZW50IGlzIG9mIHZlcnNpb24gWE1MIDEuMC4KLSAgICAgKiBJZiBYTUwgdmVyc2lvbiBvZiBvdXRwdXQgZG91Y21lbnQgaXMgc3BlY2lmaWVkLCBidXQgaXQgaXMgbm90IGVpdGhlcgotICAgICAqIFhNTCAxLjAgb3IgWE1MIDEuMSwgYSB3YXJuaW5nIG1lc3NhZ2UgaXMgZ2VuZXJhdGVkLCB0aGUgWE1MIFZlcnNpb24gb2YKLSAgICAgKiBvdXRwdXQgZG9jdW1lbnQgaXMgc2V0IHRvIFhNTCAxLjAgYW5kIHByb2Nlc3NpbmcgY29udGludWVzLgotICAgICAqIEByZXR1cm4gc3RyaW5nIChYTUwgdmVyc2lvbikKLSAgICAgKi8KLSAgICBwcml2YXRlIFN0cmluZyBnZXRYTUxWZXJzaW9uKCkKLSAgICB7Ci0gICAgICAgIFN0cmluZyB4bWxWZXJzaW9uID0gZ2V0VmVyc2lvbigpOwotICAgICAgICBpZih4bWxWZXJzaW9uID09IG51bGwgfHwgeG1sVmVyc2lvbi5lcXVhbHMoWE1MVkVSU0lPTjEwKSkKLSAgICAgICAgewotICAgICAgICAgICAgeG1sVmVyc2lvbiA9IFhNTFZFUlNJT04xMDsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmKHhtbFZlcnNpb24uZXF1YWxzKFhNTFZFUlNJT04xMSkpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHhtbFZlcnNpb24gPSBYTUxWRVJTSU9OMTE7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICB7Ci0gICAgICAgICAgICBTdHJpbmcgbXNnID0gVXRpbHMubWVzc2FnZXMuY3JlYXRlTWVzc2FnZSgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNc2dLZXkuRVJfWE1MX1ZFUlNJT05fTk9UX1NVUFBPUlRFRCxuZXcgT2JqZWN0W117IHhtbFZlcnNpb24gfSk7Ci0gICAgICAgICAgICB0cnkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAvLyBQcmVwYXJlIHRvIGlzc3VlIHRoZSB3YXJuaW5nIG1lc3NhZ2UKLSAgICAgICAgICAgICAgICBUcmFuc2Zvcm1lciB0cmFuID0gc3VwZXIuZ2V0VHJhbnNmb3JtZXIoKTsKLSAgICAgICAgICAgICAgICBFcnJvckxpc3RlbmVyIGVyckhhbmRsZXIgPSB0cmFuLmdldEVycm9yTGlzdGVuZXIoKTsKLSAgICAgICAgICAgICAgICAvLyBJc3N1ZSB0aGUgd2FybmluZyBtZXNzYWdlCi0gICAgICAgICAgICAgICAgaWYgKG51bGwgIT0gZXJySGFuZGxlciAmJiBtX3NvdXJjZUxvY2F0b3IgIT0gbnVsbCkKLSAgICAgICAgICAgICAgICAgICAgZXJySGFuZGxlci53YXJuaW5nKG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihtc2csIG1fc291cmNlTG9jYXRvcikpOwotICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKG1zZyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGUpe30KLSAgICAgICAgICAgIHhtbFZlcnNpb24gPSBYTUxWRVJTSU9OMTA7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHhtbFZlcnNpb247Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9UcmFuc2Zvcm1TdGF0ZVNldHRlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9UcmFuc2Zvcm1TdGF0ZVNldHRlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjYjhkNGU1Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvVHJhbnNmb3JtU3RhdGVTZXR0ZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDU4ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFRyYW5zZm9ybVN0YXRlU2V0dGVyLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTUgMDg6MTU6Mjkgc3VyZXNoX2VtYWlsaWQgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXI7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyOwotCi1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLS8qKgotICogVGhpcyBpbnRlcmZhY2UgaXMgbWVhbnQgdG8gYmUgdXNlZCBieSBhIGJhc2UgaW50ZXJmYWNlIHRvCi0gKiBUcmFuc2Zvcm1TdGF0ZSwgYnV0IHdoaWNoIGFzIG9ubHkgdGhlIHNldHRlcnMgd2hpY2ggaGF2ZSBub24gWGFsYW4KLSAqIHNwZWNpZmljIHR5cGVzIGluIHRoZWlyIHNpZ25hdHVyZSwgc28gdGhhdCB0aGVyZSBhcmUgbm8gZGVwZW5kYW5jaWVzCi0gKiBvZiB0aGUgc2VyaWFsaXplciBvbiBYYWxhbi4KLSAqCi0gKiBUaGlzIGludGVyZmFjZSBpcyBub3QgYSBwdWJsaWMgQVBJLCBpdCBpcyBvbmx5IHB1YmxpYyBiZWNhdXNlIGl0IGlzCi0gKiB1c2VkIGJ5IFhhbGFuLgotICoKLSAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnRyYW5zZm9ybWVyLlRyYW5zZm9ybVN0YXRlCi0gKiBAeHNsLnVzYWdlIGludGVybmFsCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgVHJhbnNmb3JtU3RhdGVTZXR0ZXIKLXsKLQotCi0gIC8qKgotICAgKiBTZXQgdGhlIGN1cnJlbnQgbm9kZS4KLSAgICoKLSAgICogQHBhcmFtIG4gVGhlIGN1cnJlbnQgbm9kZS4KLSAgICovCi0gIHZvaWQgc2V0Q3VycmVudE5vZGUoTm9kZSBuKTsKLQotICAvKioKLSAgICogUmVzZXQgdGhlIHN0YXRlIG9uIHRoZSBnaXZlbiB0cmFuc2Zvcm1lciBvYmplY3QuCi0gICAqCi0gICAqIEBwYXJhbSB0cmFuc2Zvcm1lcgotICAgKi8KLSAgdm9pZCByZXNldFN0YXRlKFRyYW5zZm9ybWVyIHRyYW5zZm9ybWVyKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9UcmVlV2Fsa2VyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1RyZWVXYWxrZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMzdmNmM3YS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1RyZWVXYWxrZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDUxMCArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDE1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICovCi0vKgotICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCi0gKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKLSAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KLSAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCi0gKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAotICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnV0aWxzLlNlY3VyaXR5U3VwcG9ydDsKLWltcG9ydCBqYXZhLmlvLkZpbGU7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXIudXRpbHMuQXR0TGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXIudXRpbHMuRE9NMkhlbHBlcjsKLWltcG9ydCBvcmcudzNjLmRvbS5Db21tZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLkVsZW1lbnQ7Ci1pbXBvcnQgb3JnLnczYy5kb20uRW50aXR5UmVmZXJlbmNlOwotaW1wb3J0IG9yZy53M2MuZG9tLk5hbWVkTm9kZU1hcDsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotaW1wb3J0IG9yZy53M2MuZG9tLlByb2Nlc3NpbmdJbnN0cnVjdGlvbjsKLWltcG9ydCBvcmcudzNjLmRvbS5UZXh0OwotCi1pbXBvcnQgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguTG9jYXRvcjsKLWltcG9ydCBvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguaGVscGVycy5Mb2NhdG9ySW1wbDsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGRvZXMgYSBwcmUtb3JkZXIgd2FsayBvZiB0aGUgRE9NIHRyZWUsIGNhbGxpbmcgYSBDb250ZW50SGFuZGxlcgotICogaW50ZXJmYWNlIGFzIGl0IGdvZXMuCi0gKgotICogVGhpcyBjbGFzcyBpcyBhIGNvcHkgb2YgdGhlIG9uZSBpbiBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLgotICogSXQgZXhpc3RzIHRvIGN1dCB0aGUgc2VyaWFsaXplcnMgZGVwZW5kYW5jeSBvbiB0aGF0IHBhY2thZ2UuCi0gKgotICogQHhzbC51c2FnZSBpbnRlcm5hbAotICovCi0KLXB1YmxpYyBmaW5hbCBjbGFzcyBUcmVlV2Fsa2VyCi17Ci0KLSAgLyoqIExvY2FsIHJlZmVyZW5jZSB0byBhIENvbnRlbnRIYW5kbGVyICAgICAgICAgICovCi0gIGZpbmFsIHByaXZhdGUgQ29udGVudEhhbmRsZXIgbV9jb250ZW50SGFuZGxlcjsKLSAgLyoqCi0gICAqIElmIG1fY29udGVudEhhbmRsZXIgaXMgYSBTZXJpYWxpemF0aW9uSGFuZGxlciwgdGhlbiB0aGlzIGlzCi0gICAqIGEgcmVmZXJlbmNlIHRvIHRoZSBzYW1lIG9iamVjdC4KLSAgICovCi0gIGZpbmFsIHByaXZhdGUgU2VyaWFsaXphdGlvbkhhbmRsZXIgbV9TZXJpYWxpemVyOwotCi0gIC8vIEFSR0hIISEgIEpBWFAgVXNlcyBYZXJjZXMgd2l0aG91dCBzZXR0aW5nIHRoZSBuYW1lc3BhY2UgcHJvY2Vzc2luZyB0byBPTiEKLSAgLy8gRE9NMkhlbHBlciBtX2RoID0gbmV3IERPTTJIZWxwZXIoKTsKLQotICAvKiogRG9tSGVscGVyIGZvciB0aGlzIFRyZWVXYWxrZXIgICAgICAgICAgKi8KLSAgZmluYWwgcHJvdGVjdGVkIERPTTJIZWxwZXIgbV9kaDsKLQotICAvKiogTG9jYXRvciBvYmplY3QgZm9yIHRoaXMgVHJlZVdhbGtlciAgICAgICAgICAqLwotICBmaW5hbCBwcml2YXRlIExvY2F0b3JJbXBsIG1fbG9jYXRvciA9IG5ldyBMb2NhdG9ySW1wbCgpOwotCi0gIC8qKgotICAgKiBHZXQgdGhlIENvbnRlbnRIYW5kbGVyIHVzZWQgZm9yIHRoZSB0cmVlIHdhbGsuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIENvbnRlbnRIYW5kbGVyIHVzZWQgZm9yIHRoZSB0cmVlIHdhbGsKLSAgICovCi0gIHB1YmxpYyBDb250ZW50SGFuZGxlciBnZXRDb250ZW50SGFuZGxlcigpCi0gIHsKLSAgICByZXR1cm4gbV9jb250ZW50SGFuZGxlcjsKLSAgfQotCi0gIHB1YmxpYyBUcmVlV2Fsa2VyKENvbnRlbnRIYW5kbGVyIGNoKSB7Ci0gICAgICB0aGlzKGNoLG51bGwpOwotICB9Ci0gIC8qKgotICAgKiBDb25zdHJ1Y3Rvci4KLSAgICogQHBhcmFtICAgY29udGVudEhhbmRsZXIgVGhlIGltcGxlbWVudGlvbiBvZiB0aGUKLSAgICogY29udGVudEhhbmRsZXIgb3BlcmF0aW9uICh0b1hNTFN0cmluZywgZGlnZXN0LCAuLi4pCi0gICAqLwotICBwdWJsaWMgVHJlZVdhbGtlcihDb250ZW50SGFuZGxlciBjb250ZW50SGFuZGxlciwgU3RyaW5nIHN5c3RlbUlkKQotICB7Ci0gICAgICAvLyBTZXQgdGhlIGNvbnRlbnQgaGFuZGxlcgotICAgICAgbV9jb250ZW50SGFuZGxlciA9IGNvbnRlbnRIYW5kbGVyOwotICAgICAgaWYgKG1fY29udGVudEhhbmRsZXIgaW5zdGFuY2VvZiBTZXJpYWxpemF0aW9uSGFuZGxlcikgewotICAgICAgICAgIG1fU2VyaWFsaXplciA9IChTZXJpYWxpemF0aW9uSGFuZGxlcikgbV9jb250ZW50SGFuZGxlcjsKLSAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgbV9TZXJpYWxpemVyID0gbnVsbDsKLSAgICAgIH0KLQotICAgICAgLy8gU2V0IHRoZSBzeXN0ZW0gSUQsIGlmIGl0IGlzIGdpdmVuCi0gICAgICBtX2NvbnRlbnRIYW5kbGVyLnNldERvY3VtZW50TG9jYXRvcihtX2xvY2F0b3IpOwotICAgICAgaWYgKHN5c3RlbUlkICE9IG51bGwpIHsKLSAgICAgICAgICBtX2xvY2F0b3Iuc2V0U3lzdGVtSWQoc3lzdGVtSWQpOwotICAgICAgfQotCi0gICAgICBtX2RoID0gbmV3IERPTTJIZWxwZXIoKTsKLSAgfQotCi0gIC8qKgotICAgKiBQZXJmb3JtIGEgcHJlLW9yZGVyIHRyYXZlcnNhbCBub24tcmVjdXJzaXZlIHN0eWxlLgotICAgKgotICAgKiBOb3RlIHRoYXQgVHJlZVdhbGtlciBhc3N1bWVzIHRoYXQgdGhlIHN1YnRyZWUgaXMgaW50ZW5kZWQgdG8gcmVwcmVzZW50Ci0gICAqIGEgY29tcGxldGUgKHRob3VnaCBub3QgbmVjZXNzYXJpbHkgd2VsbC1mb3JtZWQpIGRvY3VtZW50IGFuZCwgZHVyaW5nIGEKLSAgICogdHJhdmVyc2FsLCBzdGFydERvY3VtZW50IGFuZCBlbmREb2N1bWVudCB3aWxsIGFsd2F5cyBiZSBpc3N1ZWQgdG8gdGhlCi0gICAqIFNBWCBsaXN0ZW5lci4KLSAgICoKLSAgICogQHBhcmFtIHBvcyBOb2RlIGluIHRoZSB0cmVlIHdoZXJlIHRvIHN0YXJ0IHRyYXZlcnNhbAotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCB0cmF2ZXJzZShOb2RlIHBvcykgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICB0aGlzLm1fY29udGVudEhhbmRsZXIuc3RhcnREb2N1bWVudCgpOwotCi0gICAgTm9kZSB0b3AgPSBwb3M7Ci0KLSAgICB3aGlsZSAobnVsbCAhPSBwb3MpCi0gICAgewotICAgICAgc3RhcnROb2RlKHBvcyk7Ci0KLSAgICAgIE5vZGUgbmV4dE5vZGUgPSBwb3MuZ2V0Rmlyc3RDaGlsZCgpOwotCi0gICAgICB3aGlsZSAobnVsbCA9PSBuZXh0Tm9kZSkKLSAgICAgIHsKLSAgICAgICAgZW5kTm9kZShwb3MpOwotCi0gICAgICAgIGlmICh0b3AuZXF1YWxzKHBvcykpCi0gICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgbmV4dE5vZGUgPSBwb3MuZ2V0TmV4dFNpYmxpbmcoKTsKLQotICAgICAgICBpZiAobnVsbCA9PSBuZXh0Tm9kZSkKLSAgICAgICAgewotICAgICAgICAgIHBvcyA9IHBvcy5nZXRQYXJlbnROb2RlKCk7Ci0KLSAgICAgICAgICBpZiAoKG51bGwgPT0gcG9zKSB8fCAodG9wLmVxdWFscyhwb3MpKSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBpZiAobnVsbCAhPSBwb3MpCi0gICAgICAgICAgICAgIGVuZE5vZGUocG9zKTsKLQotICAgICAgICAgICAgbmV4dE5vZGUgPSBudWxsOwotCi0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgIH0KLQotICAgICAgcG9zID0gbmV4dE5vZGU7Ci0gICAgfQotICAgIHRoaXMubV9jb250ZW50SGFuZGxlci5lbmREb2N1bWVudCgpOwotICB9Ci0KLSAgLyoqCi0gICAqIFBlcmZvcm0gYSBwcmUtb3JkZXIgdHJhdmVyc2FsIG5vbi1yZWN1cnNpdmUgc3R5bGUuCi0KLSAgICogTm90ZSB0aGF0IFRyZWVXYWxrZXIgYXNzdW1lcyB0aGF0IHRoZSBzdWJ0cmVlIGlzIGludGVuZGVkIHRvIHJlcHJlc2VudAotICAgKiBhIGNvbXBsZXRlICh0aG91Z2ggbm90IG5lY2Vzc2FyaWx5IHdlbGwtZm9ybWVkKSBkb2N1bWVudCBhbmQsIGR1cmluZyBhCi0gICAqIHRyYXZlcnNhbCwgc3RhcnREb2N1bWVudCBhbmQgZW5kRG9jdW1lbnQgd2lsbCBhbHdheXMgYmUgaXNzdWVkIHRvIHRoZQotICAgKiBTQVggbGlzdGVuZXIuCi0gICAqCi0gICAqIEBwYXJhbSBwb3MgTm9kZSBpbiB0aGUgdHJlZSB3aGVyZSB0byBzdGFydCB0cmF2ZXJzYWwKLSAgICogQHBhcmFtIHRvcCBOb2RlIGluIHRoZSB0cmVlIHdoZXJlIHRvIGVuZCB0cmF2ZXJzYWwKLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgdHJhdmVyc2UoTm9kZSBwb3MsIE5vZGUgdG9wKSB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIHRoaXMubV9jb250ZW50SGFuZGxlci5zdGFydERvY3VtZW50KCk7Ci0KLSAgICB3aGlsZSAobnVsbCAhPSBwb3MpCi0gICAgewotICAgICAgc3RhcnROb2RlKHBvcyk7Ci0KLSAgICAgIE5vZGUgbmV4dE5vZGUgPSBwb3MuZ2V0Rmlyc3RDaGlsZCgpOwotCi0gICAgICB3aGlsZSAobnVsbCA9PSBuZXh0Tm9kZSkKLSAgICAgIHsKLSAgICAgICAgZW5kTm9kZShwb3MpOwotCi0gICAgICAgIGlmICgobnVsbCAhPSB0b3ApICYmIHRvcC5lcXVhbHMocG9zKSkKLSAgICAgICAgICBicmVhazsKLQotICAgICAgICBuZXh0Tm9kZSA9IHBvcy5nZXROZXh0U2libGluZygpOwotCi0gICAgICAgIGlmIChudWxsID09IG5leHROb2RlKQotICAgICAgICB7Ci0gICAgICAgICAgcG9zID0gcG9zLmdldFBhcmVudE5vZGUoKTsKLQotICAgICAgICAgIGlmICgobnVsbCA9PSBwb3MpIHx8ICgobnVsbCAhPSB0b3ApICYmIHRvcC5lcXVhbHMocG9zKSkpCi0gICAgICAgICAgewotICAgICAgICAgICAgbmV4dE5vZGUgPSBudWxsOwotCi0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgIH0KLQotICAgICAgcG9zID0gbmV4dE5vZGU7Ci0gICAgfQotICAgIHRoaXMubV9jb250ZW50SGFuZGxlci5lbmREb2N1bWVudCgpOwotICB9Ci0KLSAgLyoqIEZsYWcgaW5kaWNhdGluZyB3aGV0aGVyIGZvbGxvd2luZyB0ZXh0IHRvIGJlIHByb2Nlc3NlZCBpcyByYXcgdGV4dCAgICAgICAgICAqLwotICBib29sZWFuIG5leHRJc1JhdyA9IGZhbHNlOwotCi0gIC8qKgotICAgKiBPcHRpbWl6ZWQgZGlzcGF0Y2ggb2YgY2hhcmFjdGVycy4KLSAgICovCi0gIHByaXZhdGUgZmluYWwgdm9pZCBkaXNwYXRhY2hDaGFycyhOb2RlIG5vZGUpCi0gICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIGlmKG1fU2VyaWFsaXplciAhPSBudWxsKQotICAgIHsKLSAgICAgIHRoaXMubV9TZXJpYWxpemVyLmNoYXJhY3RlcnMobm9kZSk7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBTdHJpbmcgZGF0YSA9ICgoVGV4dCkgbm9kZSkuZ2V0RGF0YSgpOwotICAgICAgdGhpcy5tX2NvbnRlbnRIYW5kbGVyLmNoYXJhY3RlcnMoZGF0YS50b0NoYXJBcnJheSgpLCAwLCBkYXRhLmxlbmd0aCgpKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogU3RhcnQgcHJvY2Vzc2luZyBnaXZlbiBub2RlCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBub2RlIE5vZGUgdG8gcHJvY2VzcwotICAgKgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgc3RhcnROb2RlKE5vZGUgbm9kZSkgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLS8vICAgVE9ETzogPFJFVklFVz4KLS8vICAgIEEgU2VyaWFsaXplciBpbXBsZW1lbnRzIENvbnRlbnRIYW5kbGVyLCBidXQgbm90IE5vZGVDb25zdW1lcgotLy8gICAgc28gZHJvcCB0aGlzIHJlZmVyZW5jZSB0byBOb2RlQ29uc3VtZXIgd2hpY2ggd291bGQgb3RoZXJ3aXNlCi0vLyAgICBwdWxsIGluIGFsbCBzb3J0cyBvZiB0aGluZ3MKLS8vICAgIGlmIChtX2NvbnRlbnRIYW5kbGVyIGluc3RhbmNlb2YgTm9kZUNvbnN1bWVyKQotLy8gICAgewotLy8gICAgICAoKE5vZGVDb25zdW1lcikgbV9jb250ZW50SGFuZGxlcikuc2V0T3JpZ2luYXRpbmdOb2RlKG5vZGUpOwotLy8gICAgfQotLy8gICAgVE9ETzogPC9SRVZJRVc+Ci0KLSAgICAgICAgICAgICAgICBpZiAobm9kZSBpbnN0YW5jZW9mIExvY2F0b3IpCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgTG9jYXRvciBsb2MgPSAoTG9jYXRvcilub2RlOwotICAgICAgICAgICAgICAgICAgICAgICAgbV9sb2NhdG9yLnNldENvbHVtbk51bWJlcihsb2MuZ2V0Q29sdW1uTnVtYmVyKCkpOwotICAgICAgICAgICAgICAgICAgICAgICAgbV9sb2NhdG9yLnNldExpbmVOdW1iZXIobG9jLmdldExpbmVOdW1iZXIoKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBtX2xvY2F0b3Iuc2V0UHVibGljSWQobG9jLmdldFB1YmxpY0lkKCkpOwotICAgICAgICAgICAgICAgICAgICAgICAgbV9sb2NhdG9yLnNldFN5c3RlbUlkKGxvYy5nZXRTeXN0ZW1JZCgpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIG1fbG9jYXRvci5zZXRDb2x1bW5OdW1iZXIoMCk7Ci0gICAgICBtX2xvY2F0b3Iuc2V0TGluZU51bWJlcigwKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICBzd2l0Y2ggKG5vZGUuZ2V0Tm9kZVR5cGUoKSkKLSAgICB7Ci0gICAgY2FzZSBOb2RlLkNPTU1FTlRfTk9ERSA6Ci0gICAgewotICAgICAgU3RyaW5nIGRhdGEgPSAoKENvbW1lbnQpIG5vZGUpLmdldERhdGEoKTsKLQotICAgICAgaWYgKG1fY29udGVudEhhbmRsZXIgaW5zdGFuY2VvZiBMZXhpY2FsSGFuZGxlcikKLSAgICAgIHsKLSAgICAgICAgTGV4aWNhbEhhbmRsZXIgbGggPSAoKExleGljYWxIYW5kbGVyKSB0aGlzLm1fY29udGVudEhhbmRsZXIpOwotCi0gICAgICAgIGxoLmNvbW1lbnQoZGF0YS50b0NoYXJBcnJheSgpLCAwLCBkYXRhLmxlbmd0aCgpKTsKLSAgICAgIH0KLSAgICB9Ci0gICAgYnJlYWs7Ci0gICAgY2FzZSBOb2RlLkRPQ1VNRU5UX0ZSQUdNRU5UX05PREUgOgotCi0gICAgICAvLyA/PzsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgTm9kZS5ET0NVTUVOVF9OT0RFIDoKLQotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBOb2RlLkVMRU1FTlRfTk9ERSA6Ci0gICAgICBFbGVtZW50IGVsZW1fbm9kZSA9IChFbGVtZW50KSBub2RlOwotICAgICAgewotICAgICAgICAgIC8vIE1ha2Ugc3VyZSB0aGUgbmFtZXNwYWNlIG5vZGUKLSAgICAgICAgICAvLyBmb3IgdGhlIGVsZW1lbnQgaXRzZWxmIGlzIGRlY2xhcmVkCi0gICAgICAgICAgLy8gdG8gdGhlIENvbnRlbnRIYW5kbGVyCi0gICAgICAgICAgU3RyaW5nIHVyaSA9IGVsZW1fbm9kZS5nZXROYW1lc3BhY2VVUkkoKTsKLSAgICAgICAgICBpZiAodXJpICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgU3RyaW5nIHByZWZpeCA9IGVsZW1fbm9kZS5nZXRQcmVmaXgoKTsKLSAgICAgICAgICAgICAgaWYgKHByZWZpeD09bnVsbCkKLSAgICAgICAgICAgICAgICBwcmVmaXg9IiI7Ci0gICAgICAgICAgICAgIHRoaXMubV9jb250ZW50SGFuZGxlci5zdGFydFByZWZpeE1hcHBpbmcocHJlZml4LHVyaSk7Ci0gICAgICAgICAgfQotICAgICAgfQotICAgICAgTmFtZWROb2RlTWFwIGF0dHMgPSBlbGVtX25vZGUuZ2V0QXR0cmlidXRlcygpOwotICAgICAgaW50IG5BdHRycyA9IGF0dHMuZ2V0TGVuZ3RoKCk7Ci0gICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIlRyZWVXYWxrZXIjc3RhcnROb2RlOiAiK25vZGUuZ2V0Tm9kZU5hbWUoKSk7Ci0KLQotICAgICAgLy8gTWFrZSBzdXJlIHRoZSBuYW1lc3BhY2Ugbm9kZSBvZgotICAgICAgLy8gZWFjaCBhdHRyaWJ1dGUgaXMgZGVjbGFyZWQgdG8gdGhlIENvbnRlbnRIYW5kbGVyCi0gICAgICBmb3IgKGludCBpID0gMDsgaSA8IG5BdHRyczsgaSsrKQotICAgICAgewotICAgICAgICBmaW5hbCBOb2RlIGF0dHIgPSBhdHRzLml0ZW0oaSk7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBhdHRyTmFtZSA9IGF0dHIuZ2V0Tm9kZU5hbWUoKTsKLSAgICAgICAgZmluYWwgaW50IGNvbG9uID0gYXR0ck5hbWUuaW5kZXhPZignOicpOwotICAgICAgICBmaW5hbCBTdHJpbmcgcHJlZml4OwotCi0gICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiVHJlZVdhbGtlciNzdGFydE5vZGU6IGF0dHJbIitpKyJdID0gIithdHRyTmFtZSsiLCAiK2F0dHIuZ2V0Tm9kZVZhbHVlKCkpOwotICAgICAgICBpZiAoYXR0ck5hbWUuZXF1YWxzKCJ4bWxucyIpIHx8IGF0dHJOYW1lLnN0YXJ0c1dpdGgoInhtbG5zOiIpKQotICAgICAgICB7Ci0gICAgICAgICAgLy8gVXNlICIiIGluc3RlYWQgb2YgbnVsbCwgYXMgWGVyY2VzIGxpa2VzICIiIGZvciB0aGUKLSAgICAgICAgICAvLyBuYW1lIG9mIHRoZSBkZWZhdWx0IG5hbWVzcGFjZS4gIEZpeCBhdHRyaWJ1dGVkCi0gICAgICAgICAgLy8gdG8gIlN0ZXZlbiBNdXJyYXkiIDxzbXVycmF5QGVidC5jb20+LgotICAgICAgICAgIGlmIChjb2xvbiA8IDApCi0gICAgICAgICAgICBwcmVmaXggPSAiIjsKLSAgICAgICAgICBlbHNlCi0gICAgICAgICAgICBwcmVmaXggPSBhdHRyTmFtZS5zdWJzdHJpbmcoY29sb24gKyAxKTsKLQotICAgICAgICAgIHRoaXMubV9jb250ZW50SGFuZGxlci5zdGFydFByZWZpeE1hcHBpbmcocHJlZml4LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0ci5nZXROb2RlVmFsdWUoKSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoY29sb24gPiAwKSB7Ci0gICAgICAgICAgICBwcmVmaXggPSBhdHRyTmFtZS5zdWJzdHJpbmcoMCxjb2xvbik7Ci0gICAgICAgICAgICBTdHJpbmcgdXJpID0gYXR0ci5nZXROYW1lc3BhY2VVUkkoKTsKLSAgICAgICAgICAgIGlmICh1cmkgIT0gbnVsbCkKLSAgICAgICAgICAgICAgICB0aGlzLm1fY29udGVudEhhbmRsZXIuc3RhcnRQcmVmaXhNYXBwaW5nKHByZWZpeCx1cmkpOwotICAgICAgICB9Ci0gICAgICB9Ci0KLSAgICAgIFN0cmluZyBucyA9IG1fZGguZ2V0TmFtZXNwYWNlT2ZOb2RlKG5vZGUpOwotICAgICAgaWYobnVsbCA9PSBucykKLSAgICAgICAgbnMgPSAiIjsKLSAgICAgIHRoaXMubV9jb250ZW50SGFuZGxlci5zdGFydEVsZW1lbnQobnMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fZGguZ2V0TG9jYWxOYW1lT2ZOb2RlKG5vZGUpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlLmdldE5vZGVOYW1lKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBBdHRMaXN0KGF0dHMsIG1fZGgpKTsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgTm9kZS5QUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREUgOgotICAgIHsKLSAgICAgIFByb2Nlc3NpbmdJbnN0cnVjdGlvbiBwaSA9IChQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24pIG5vZGU7Ci0gICAgICBTdHJpbmcgbmFtZSA9IHBpLmdldE5vZGVOYW1lKCk7Ci0KLSAgICAgIC8vIFN0cmluZyBkYXRhID0gcGkuZ2V0RGF0YSgpOwotICAgICAgaWYgKG5hbWUuZXF1YWxzKCJ4c2x0LW5leHQtaXMtcmF3IikpCi0gICAgICB7Ci0gICAgICAgIG5leHRJc1JhdyA9IHRydWU7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIHRoaXMubV9jb250ZW50SGFuZGxlci5wcm9jZXNzaW5nSW5zdHJ1Y3Rpb24ocGkuZ2V0Tm9kZU5hbWUoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaS5nZXREYXRhKCkpOwotICAgICAgfQotICAgIH0KLSAgICBicmVhazsKLSAgICBjYXNlIE5vZGUuQ0RBVEFfU0VDVElPTl9OT0RFIDoKLSAgICB7Ci0gICAgICBib29sZWFuIGlzTGV4SCA9IChtX2NvbnRlbnRIYW5kbGVyIGluc3RhbmNlb2YgTGV4aWNhbEhhbmRsZXIpOwotICAgICAgTGV4aWNhbEhhbmRsZXIgbGggPSBpc0xleEgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgPyAoKExleGljYWxIYW5kbGVyKSB0aGlzLm1fY29udGVudEhhbmRsZXIpIDogbnVsbDsKLQotICAgICAgaWYgKGlzTGV4SCkKLSAgICAgIHsKLSAgICAgICAgbGguc3RhcnRDREFUQSgpOwotICAgICAgfQotCi0gICAgICBkaXNwYXRhY2hDaGFycyhub2RlKTsKLQotICAgICAgewotICAgICAgICBpZiAoaXNMZXhIKQotICAgICAgICB7Ci0gICAgICAgICAgbGguZW5kQ0RBVEEoKTsKLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLSAgICBicmVhazsKLSAgICBjYXNlIE5vZGUuVEVYVF9OT0RFIDoKLSAgICB7Ci0gICAgICAvL1N0cmluZyBkYXRhID0gKChUZXh0KSBub2RlKS5nZXREYXRhKCk7Ci0KLSAgICAgIGlmIChuZXh0SXNSYXcpCi0gICAgICB7Ci0gICAgICAgIG5leHRJc1JhdyA9IGZhbHNlOwotCi0gICAgICAgIG1fY29udGVudEhhbmRsZXIucHJvY2Vzc2luZ0luc3RydWN0aW9uKGphdmF4LnhtbC50cmFuc2Zvcm0uUmVzdWx0LlBJX0RJU0FCTEVfT1VUUFVUX0VTQ0FQSU5HLCAiIik7Ci0gICAgICAgIGRpc3BhdGFjaENoYXJzKG5vZGUpOwotICAgICAgICBtX2NvbnRlbnRIYW5kbGVyLnByb2Nlc3NpbmdJbnN0cnVjdGlvbihqYXZheC54bWwudHJhbnNmb3JtLlJlc3VsdC5QSV9FTkFCTEVfT1VUUFVUX0VTQ0FQSU5HLCAiIik7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIGRpc3BhdGFjaENoYXJzKG5vZGUpOwotICAgICAgfQotICAgIH0KLSAgICBicmVhazsKLSAgICBjYXNlIE5vZGUuRU5USVRZX1JFRkVSRU5DRV9OT0RFIDoKLSAgICB7Ci0gICAgICBFbnRpdHlSZWZlcmVuY2UgZXJlZiA9IChFbnRpdHlSZWZlcmVuY2UpIG5vZGU7Ci0KLSAgICAgIGlmIChtX2NvbnRlbnRIYW5kbGVyIGluc3RhbmNlb2YgTGV4aWNhbEhhbmRsZXIpCi0gICAgICB7Ci0gICAgICAgICgoTGV4aWNhbEhhbmRsZXIpIHRoaXMubV9jb250ZW50SGFuZGxlcikuc3RhcnRFbnRpdHkoCi0gICAgICAgICAgZXJlZi5nZXROb2RlTmFtZSgpKTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLQotICAgICAgICAvLyB3YXJuaW5nKCJDYW4gbm90IG91dHB1dCBlbnRpdHkgdG8gYSBwdXJlIFNBWCBDb250ZW50SGFuZGxlciIpOwotICAgICAgfQotICAgIH0KLSAgICBicmVhazsKLSAgICBkZWZhdWx0IDoKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogRW5kIHByb2Nlc3Npbmcgb2YgZ2l2ZW4gbm9kZQotICAgKgotICAgKgotICAgKiBAcGFyYW0gbm9kZSBOb2RlIHdlIGp1c3QgZmluaXNoZWQgcHJvY2Vzc2luZwotICAgKgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgZW5kTm9kZShOb2RlIG5vZGUpIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgc3dpdGNoIChub2RlLmdldE5vZGVUeXBlKCkpCi0gICAgewotICAgIGNhc2UgTm9kZS5ET0NVTUVOVF9OT0RFIDoKLSAgICAgIGJyZWFrOwotCi0gICAgY2FzZSBOb2RlLkVMRU1FTlRfTk9ERSA6Ci0gICAgICBTdHJpbmcgbnMgPSBtX2RoLmdldE5hbWVzcGFjZU9mTm9kZShub2RlKTsKLSAgICAgIGlmKG51bGwgPT0gbnMpCi0gICAgICAgIG5zID0gIiI7Ci0gICAgICB0aGlzLm1fY29udGVudEhhbmRsZXIuZW5kRWxlbWVudChucywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbV9kaC5nZXRMb2NhbE5hbWVPZk5vZGUobm9kZSksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUuZ2V0Tm9kZU5hbWUoKSk7Ci0KLSAgICAgIGlmIChtX1NlcmlhbGl6ZXIgPT0gbnVsbCkgewotICAgICAgLy8gRG9uJ3QgYm90aGVyIHdpdGggZW5kUHJlZml4TWFwcGluZyBjYWxscyBpZiB0aGUgQ29udGVudEhhbmRsZXIgaXMgYQotICAgICAgLy8gU2VyaWFsaXphdGlvbkhhbmRsZXIgYmVjYXVzZSBTZXJpYWxpemF0aW9uSGFuZGxlcidzIGlnbm9yZSB0aGUKLSAgICAgIC8vIGVuZFByZWZpeE1hcHBpbmcoKSBjYWxscyBhbnl3YXlzLiAuIC4gLiAgVGhpcyBpcyBhbiBvcHRpbWl6YXRpb24uCi0gICAgICBFbGVtZW50IGVsZW1fbm9kZSA9IChFbGVtZW50KSBub2RlOwotICAgICAgTmFtZWROb2RlTWFwIGF0dHMgPSBlbGVtX25vZGUuZ2V0QXR0cmlidXRlcygpOwotICAgICAgaW50IG5BdHRycyA9IGF0dHMuZ2V0TGVuZ3RoKCk7Ci0KLSAgICAgIC8vIGRvIHRoZSBlbmRQcmVmaXhNYXBwaW5nIGNhbGxzIGluIHJldmVyc2Ugb3JkZXIKLSAgICAgIC8vIG9mIHRoZSBzdGFydFByZWZpeE1hcHBpbmcgY2FsbHMKLSAgICAgIGZvciAoaW50IGkgPSAobkF0dHJzLTEpOyAwIDw9IGk7IGktLSkKLSAgICAgIHsKLSAgICAgICAgZmluYWwgTm9kZSBhdHRyID0gYXR0cy5pdGVtKGkpOwotICAgICAgICBmaW5hbCBTdHJpbmcgYXR0ck5hbWUgPSBhdHRyLmdldE5vZGVOYW1lKCk7Ci0gICAgICAgIGZpbmFsIGludCBjb2xvbiA9IGF0dHJOYW1lLmluZGV4T2YoJzonKTsKLSAgICAgICAgZmluYWwgU3RyaW5nIHByZWZpeDsKLQotICAgICAgICBpZiAoYXR0ck5hbWUuZXF1YWxzKCJ4bWxucyIpIHx8IGF0dHJOYW1lLnN0YXJ0c1dpdGgoInhtbG5zOiIpKQotICAgICAgICB7Ci0gICAgICAgICAgLy8gVXNlICIiIGluc3RlYWQgb2YgbnVsbCwgYXMgWGVyY2VzIGxpa2VzICIiIGZvciB0aGUKLSAgICAgICAgICAvLyBuYW1lIG9mIHRoZSBkZWZhdWx0IG5hbWVzcGFjZS4gIEZpeCBhdHRyaWJ1dGVkCi0gICAgICAgICAgLy8gdG8gIlN0ZXZlbiBNdXJyYXkiIDxzbXVycmF5QGVidC5jb20+LgotICAgICAgICAgIGlmIChjb2xvbiA8IDApCi0gICAgICAgICAgICBwcmVmaXggPSAiIjsKLSAgICAgICAgICBlbHNlCi0gICAgICAgICAgICBwcmVmaXggPSBhdHRyTmFtZS5zdWJzdHJpbmcoY29sb24gKyAxKTsKLQotICAgICAgICAgIHRoaXMubV9jb250ZW50SGFuZGxlci5lbmRQcmVmaXhNYXBwaW5nKHByZWZpeCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoY29sb24gPiAwKSB7Ci0gICAgICAgICAgICBwcmVmaXggPSBhdHRyTmFtZS5zdWJzdHJpbmcoMCwgY29sb24pOwotICAgICAgICAgICAgdGhpcy5tX2NvbnRlbnRIYW5kbGVyLmVuZFByZWZpeE1hcHBpbmcocHJlZml4KTsKLSAgICAgICAgfQotICAgICAgfQotICAgICAgewotICAgICAgICAgIFN0cmluZyB1cmkgPSBlbGVtX25vZGUuZ2V0TmFtZXNwYWNlVVJJKCk7Ci0gICAgICAgICAgaWYgKHVyaSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgIFN0cmluZyBwcmVmaXggPSBlbGVtX25vZGUuZ2V0UHJlZml4KCk7Ci0gICAgICAgICAgICAgIGlmIChwcmVmaXg9PW51bGwpCi0gICAgICAgICAgICAgICAgcHJlZml4PSIiOwotICAgICAgICAgICAgICB0aGlzLm1fY29udGVudEhhbmRsZXIuZW5kUHJlZml4TWFwcGluZyhwcmVmaXgpOwotICAgICAgICAgIH0KLSAgICAgIH0KLSAgICAgIH0KLSAgICAgIGJyZWFrOwotICAgIGNhc2UgTm9kZS5DREFUQV9TRUNUSU9OX05PREUgOgotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBOb2RlLkVOVElUWV9SRUZFUkVOQ0VfTk9ERSA6Ci0gICAgewotICAgICAgRW50aXR5UmVmZXJlbmNlIGVyZWYgPSAoRW50aXR5UmVmZXJlbmNlKSBub2RlOwotCi0gICAgICBpZiAobV9jb250ZW50SGFuZGxlciBpbnN0YW5jZW9mIExleGljYWxIYW5kbGVyKQotICAgICAgewotICAgICAgICBMZXhpY2FsSGFuZGxlciBsaCA9ICgoTGV4aWNhbEhhbmRsZXIpIHRoaXMubV9jb250ZW50SGFuZGxlcik7Ci0KLSAgICAgICAgbGguZW5kRW50aXR5KGVyZWYuZ2V0Tm9kZU5hbWUoKSk7Ci0gICAgICB9Ci0gICAgfQotICAgIGJyZWFrOwotICAgIGRlZmF1bHQgOgotICAgIH0KLSAgfQotfSAgLy9UcmVlV2Fsa2VyCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1ZlcnNpb24uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvVmVyc2lvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkZmRkZTBjLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvVmVyc2lvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTUyICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBWZXJzaW9uLmphdmEsdiAxLjIgMjAwNS8wOS8yOCAxMzo0OTowOSBwdmVkdWxhIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyOwotCi0vKioKLSAqIEFkbWluaXN0cmF0aXZlIGNsYXNzIHRvIGtlZXAgdHJhY2sgb2YgdGhlIHZlcnNpb24gbnVtYmVyIG9mCi0gKiB0aGUgU2VyaWFsaXplciByZWxlYXNlLgotICogPFA+VGhpcyBjbGFzcyBpbXBsZW1lbnRzIHRoZSB1cGNvbWluZyBzdGFuZGFyZCBvZiBoYXZpbmcKLSAqIG9yZy5hcGFjaGUucHJvamVjdC1uYW1lLlZlcnNpb24uZ2V0VmVyc2lvbigpIGJlIGEgc3RhbmRhcmQgd2F5Ci0gKiB0byBnZXQgdmVyc2lvbiBpbmZvcm1hdGlvbi48L1A+Ci0gKiBAeHNsLnVzYWdlIGdlbmVyYWwKLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIFZlcnNpb24KLXsKLQotICAvKioKLSAgICogR2V0IHRoZSBiYXNpYyB2ZXJzaW9uIHN0cmluZyBmb3IgdGhlIGN1cnJlbnQgU2VyaWFsaXplci4KLSAgICogVmVyc2lvbiBTdHJpbmcgZm9ybWF0dGVkIGxpa2UKLSAgICogPENPREU+IjxCPlNlcmlhbGl6ZXI8L0I+IDxCPkphdmE8L0I+IHYuclsuZGR8IDxCPkQ8L0I+bm5dIjwvQ09ERT4uCi0gICAqCi0gICAqIEZ1dHVyZXdvcms6IGhhdmUgdGhpcyByZWFkIHZlcnNpb24gaW5mbyBmcm9tIGphciBtYW5pZmVzdC4KLSAgICoKLSAgICogQHJldHVybiBTdHJpbmcgZGVub3Rpbmcgb3VyIGN1cnJlbnQgdmVyc2lvbgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0VmVyc2lvbigpCi0gIHsKLSAgICAgcmV0dXJuIGdldFByb2R1Y3QoKSsiICIrZ2V0SW1wbGVtZW50YXRpb25MYW5ndWFnZSgpKyIgIgotICAgICAgICAgICArZ2V0TWFqb3JWZXJzaW9uTnVtKCkrIi4iK2dldFJlbGVhc2VWZXJzaW9uTnVtKCkrIi4iCi0gICAgICAgICAgICsoIChnZXREZXZlbG9wbWVudFZlcnNpb25OdW0oKSA+IDApID8KLSAgICAgICAgICAgICAgICgiRCIrZ2V0RGV2ZWxvcG1lbnRWZXJzaW9uTnVtKCkpIDogKCIiK2dldE1haW50ZW5hbmNlVmVyc2lvbk51bSgpKSk7Ci0gIH0KLQotICAvKioKLSAgICogUHJpbnQgdGhlIHByb2Nlc3NvciB2ZXJzaW9uIHRvIHRoZSBjb21tYW5kIGxpbmUuCi0gICAqCi0gICAqIEBwYXJhbSBhcmd2IGNvbW1hbmQgbGluZSBhcmd1bWVudHMsIHVudXNlZC4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgdm9pZCBfbWFpbihTdHJpbmcgYXJndltdKQotICB7Ci0gICAgU3lzdGVtLm91dC5wcmludGxuKGdldFZlcnNpb24oKSk7Ci0gIH0KLQotICAvKioKLSAgICogTmFtZSBvZiBwcm9kdWN0OiBTZXJpYWxpemVyLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0UHJvZHVjdCgpCi0gIHsKLSAgICByZXR1cm4gIlNlcmlhbGl6ZXIiOwotICB9Ci0KLSAgLyoqCi0gICAqIEltcGxlbWVudGF0aW9uIExhbmd1YWdlOiBKYXZhLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0SW1wbGVtZW50YXRpb25MYW5ndWFnZSgpCi0gIHsKLSAgICByZXR1cm4gIkphdmEiOwotICB9Ci0KLQotICAvKioKLSAgICogTWFqb3IgdmVyc2lvbiBudW1iZXIuCi0gICAqIFZlcnNpb24gbnVtYmVyLiBUaGlzIGNoYW5nZXMgb25seSB3aGVuIHRoZXJlIGlzIGEKLSAgICogICAgICAgICAgc2lnbmlmaWNhbnQsIGV4dGVybmFsbHkgYXBwYXJlbnQgZW5oYW5jZW1lbnQgZnJvbQotICAgKiAgICAgICAgICB0aGUgcHJldmlvdXMgcmVsZWFzZS4gJ24nIHJlcHJlc2VudHMgdGhlIG4ndGgKLSAgICogICAgICAgICAgdmVyc2lvbi4KLSAgICoKLSAgICogICAgICAgICAgQ2xpZW50cyBzaG91bGQgY2FyZWZ1bGx5IGNvbnNpZGVyIHRoZSBpbXBsaWNhdGlvbnMKLSAgICogICAgICAgICAgb2YgbmV3IHZlcnNpb25zIGFzIGV4dGVybmFsIGludGVyZmFjZXMgYW5kIGJlaGF2aW91cgotICAgKiAgICAgICAgICBtYXkgaGF2ZSBjaGFuZ2VkLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBpbnQgZ2V0TWFqb3JWZXJzaW9uTnVtKCkKLSAgewotICAgIHJldHVybiAyOwotCi0gIH0KLQotICAvKioKLSAgICogUmVsZWFzZSBOdW1iZXIuCi0gICAqIFJlbGVhc2UgbnVtYmVyLiBUaGlzIGNoYW5nZXMgd2hlbjoKLSAgICogICAgICAgICAgICAtICBhIG5ldyBzZXQgb2YgZnVuY3Rpb25hbGl0eSBpcyB0byBiZSBhZGRlZCwgZWcsCi0gICAqICAgICAgICAgICAgICAgaW1wbGVtZW50YXRpb24gb2YgYSBuZXcgVzNDIHNwZWNpZmljYXRpb24uCi0gICAqICAgICAgICAgICAgLSAgQVBJIG9yIGJlaGF2aW91ciBjaGFuZ2UuCi0gICAqICAgICAgICAgICAgLSAgaXRzIGRlc2lnbmF0ZWQgYXMgYSByZWZlcmVuY2UgcmVsZWFzZS4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgaW50IGdldFJlbGVhc2VWZXJzaW9uTnVtKCkKLSAgewotICAgIHJldHVybiA3OwotICB9Ci0KLSAgLyoqCi0gICAqIE1haW50ZW5hbmNlIERyb3AgTnVtYmVyLgotICAgKiBPcHRpb25hbCBpZGVudGlmaWVyIHVzZWQgdG8gZGVzaWduYXRlIG1haW50ZW5hbmNlCi0gICAqICAgICAgICAgIGRyb3AgYXBwbGllZCB0byBhIHNwZWNpZmljIHJlbGVhc2UgYW5kIGNvbnRhaW5zCi0gICAqICAgICAgICAgIGZpeGVzIGZvciBkZWZlY3RzIHJlcG9ydGVkLiBJdCBtYWludGFpbnMgY29tcGF0aWJpbGl0eQotICAgKiAgICAgICAgICB3aXRoIHRoZSByZWxlYXNlIGFuZCBjb250YWlucyBubyBBUEkgY2hhbmdlcy4KLSAgICogICAgICAgICAgV2hlbiBtaXNzaW5nLCBpdCBkZXNpZ25hdGVzIHRoZSBmaW5hbCBhbmQgY29tcGxldGUKLSAgICogICAgICAgICAgZGV2ZWxvcG1lbnQgZHJvcCBmb3IgYSByZWxlYXNlLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBpbnQgZ2V0TWFpbnRlbmFuY2VWZXJzaW9uTnVtKCkKLSAgewotICAgIHJldHVybiAwOwotICB9Ci0KLSAgLyoqCi0gICAqIERldmVsb3BtZW50IERyb3AgTnVtYmVyLgotICAgKiBPcHRpb25hbCBpZGVudGlmaWVyIGRlc2lnbmF0ZXMgZGV2ZWxvcG1lbnQgZHJvcCBvZgotICAgKiAgICAgICAgICBhIHNwZWNpZmljIHJlbGVhc2UuIEQwMSBpcyB0aGUgZmlyc3QgZGV2ZWxvcG1lbnQgZHJvcAotICAgKiAgICAgICAgICBvZiBhIG5ldyByZWxlYXNlLgotICAgKgotICAgKiAgICAgICAgICBEZXZlbG9wbWVudCBkcm9wcyBhcmUgd29ya3MgaW4gcHJvZ3Jlc3MgdG93YXJkcyBhCi0gICAqICAgICAgICAgIGNvbXBlbGV0ZWQsIGZpbmFsIHJlbGVhc2UuIEEgc3BlY2lmaWMgZGV2ZWxvcG1lbnQgZHJvcAotICAgKiAgICAgICAgICBtYXkgbm90IGNvbXBsZXRlbHkgaW1wbGVtZW50IGFsbCBhc3BlY3RzIG9mIGEgbmV3Ci0gICAqICAgICAgICAgIGZlYXR1cmUsIHdoaWNoIG1heSB0YWtlIHNldmVyYWwgZGV2ZWxvcG1lbnQgZHJvcHMgdG8KLSAgICogICAgICAgICAgY29tcGxldGUuIEF0IHRoZSBwb2ludCBvZiB0aGUgZmluYWwgZHJvcCBmb3IgdGhlCi0gICAqICAgICAgICAgIHJlbGVhc2UsIHRoZSBEIHN1ZmZpeCB3aWxsIGJlIG9taXR0ZWQuCi0gICAqCi0gICAqICAgICAgICAgIEVhY2ggJ0QnIGRyb3BzIGNhbiBjb250YWluIGZ1bmN0aW9uYWwgZW5oYW5jZW1lbnRzIGFzCi0gICAqICAgICAgICAgIHdlbGwgYXMgZGVmZWN0IGZpeGVzLiAnRCcgZHJvcHMgbWF5IG5vdCBiZSBhcyBzdGFibGUgYXMKLSAgICogICAgICAgICAgdGhlIGZpbmFsIHJlbGVhc2VzLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBpbnQgZ2V0RGV2ZWxvcG1lbnRWZXJzaW9uTnVtKCkKLSAgewotICAgIHRyeSB7Ci0gICAgICAgIGlmICgobmV3IFN0cmluZygiIikpLmxlbmd0aCgpID09IDApCi0gICAgICAgICAgcmV0dXJuIDA7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICByZXR1cm4gSW50ZWdlci5wYXJzZUludCgiIik7Ci0gICAgfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIG5mZSkgewotICAgICAgICAgICByZXR1cm4gMDsKLSAgICB9Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvV3JpdGVyQ2hhaW4uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvV3JpdGVyQ2hhaW4uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYmY1ZDQ2Ni4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1dyaXRlckNoYWluLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4NCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogV3JpdGVyQ2hhaW4uamF2YSx2IDEuMS40LjEgMjAwNS8wOS8wOCAxMDo1ODo0NCBzdXJlc2hfZW1haWxpZCBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplcjsKLQotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci0KLS8qKgotICogSXQgaXMgdW5mb3J0dW5hdGUgdGhhdCBqYXZhLmlvLldyaXRlciBpcyBhIGNsYXNzIHJhdGhlciB0aGFuIGFuIGludGVyZmFjZS4KLSAqIFRoZSBzZXJpYWxpemVyIGhhcyBhIG51bWJlciBvZiBjbGFzc2VzIHRoYXQgZXh0ZW5kIGphdmEuaW8uV3JpdGVyCi0gKiBhbmQgd2hpY2ggc2VuZCB0aGVpciBvdXB1dCB0byBhIHlldCBhbm90aGVyIHdyYXBwZWQgV3JpdGVyIG9yIE91dHB1dFN0cmVhbS4KLSAqCi0gKiBUaGUgcHVycG9zZSBvZiB0aGlzIGludGVyZmFjZSBpcyB0byBmb3JjZSBzdWNoIGNsYXNzZXMgdG8gb3Zlci1yaWRlIGFsbCBvZgotICogdGhlIGltcG9ydGFudCBtZXRob2RzIGRlZmluZWQgb24gdGhlIGphdmEuaW8uV3JpdGVyIGNsYXNzLCBuYW1lbHkgdGhlc2U6Ci0gKiA8Y29kZT4KLSAqIHdyaXRlKGludCB2YWwpCi0gKiB3cml0ZShjaGFyW10gY2hhcnMpCi0gKiB3cml0ZShjaGFyW10gY2hhcnMsIGludCBzdGFydCwgaW50IGNvdW50KQotICogd3JpdGUoU3RyaW5nIGNoYXJzKQotICogd3JpdGUoU3RyaW5nIGNoYXJzLCBpbnQgc3RhcnQsIGludCBjb3VudCkKLSAqIGZsdXNoKCkKLSAqIGNsb3NlKCkKLSAqIDwvY29kZT4KLSAqIEluIHRoaXMgbWFubmVyIG5vdGhpbmcgd2lsbCBhY2NpZGVudGFsbHkgZ28gZGlyZWN0bHkgdG8KLSAqIHRoZSBiYXNlIGNsYXNzIHJhdGhlciB0aGFuIHRvIHRoZSB3cmFwcGVkIFdyaXRlciBvciBPdXRwdXRTdHJlYW0uCi0gKgotICogVGhlIHB1cnBvc2Ugb2YgdGhpcyBjbGFzcyBpcyB0byBoYXZlIGEgdW5pZm9ybSB3YXkgb2YgY2hhaW5pbmcgdGhlIG91dHB1dCBvZiBvbmUgd3JpdGVyIHRvCi0gKiB0aGUgbmV4dCB3cml0ZXIgaW4gdGhlIGNoYWluLiBJbiBhZGRpdGlvbiB0aGVyZSBhcmUgbWV0aG9kcyB0byBvYnRhaW4gdGhlIFdyaXRlciBvcgotICogT3V0cHV0U3RyZWFtIHRoYXQgdGhpcyBvYmplY3Qgc2VuZHMgaXRzIG91dHB1dCB0by4KLSAqCi0gKiBUaGlzIGludGVyZmFjZSBpcyBvbmx5IGZvciBpbnRlcm5hbCB1c2Ugd2l0aGluZyB0aGUgc2VyaWFsaXplci4KLSAqIEB4c2wudXNhZ2UgaW50ZXJuYWwKLSAqLwotaW50ZXJmYWNlIFdyaXRlckNoYWluCi17Ci0gICAgLyoqIFRoaXMgbWV0aG9kIGZvcmNlcyB1cyB0byBvdmVyLXJpZGUgdGhlIG1ldGhvZCBkZWZpbmVkIGluIGphdmEuaW8uV3JpdGVyICovCi0gICAgcHVibGljIHZvaWQgd3JpdGUoaW50IHZhbCkgdGhyb3dzIElPRXhjZXB0aW9uOwotICAgIC8qKiBUaGlzIG1ldGhvZCBmb3JjZXMgdXMgdG8gb3Zlci1yaWRlIHRoZSBtZXRob2QgZGVmaW5lZCBpbiBqYXZhLmlvLldyaXRlciAqLwotICAgIHB1YmxpYyB2b2lkIHdyaXRlKGNoYXJbXSBjaGFycykgdGhyb3dzIElPRXhjZXB0aW9uOwotICAgIC8qKiBUaGlzIG1ldGhvZCBmb3JjZXMgdXMgdG8gb3Zlci1yaWRlIHRoZSBtZXRob2QgZGVmaW5lZCBpbiBqYXZhLmlvLldyaXRlciAqLwotICAgIHB1YmxpYyB2b2lkIHdyaXRlKGNoYXJbXSBjaGFycywgaW50IHN0YXJ0LCBpbnQgY291bnQpIHRocm93cyBJT0V4Y2VwdGlvbjsKLSAgICAvKiogVGhpcyBtZXRob2QgZm9yY2VzIHVzIHRvIG92ZXItcmlkZSB0aGUgbWV0aG9kIGRlZmluZWQgaW4gamF2YS5pby5Xcml0ZXIgKi8KLSAgICBwdWJsaWMgdm9pZCB3cml0ZShTdHJpbmcgY2hhcnMpIHRocm93cyBJT0V4Y2VwdGlvbjsKLSAgICAvKiogVGhpcyBtZXRob2QgZm9yY2VzIHVzIHRvIG92ZXItcmlkZSB0aGUgbWV0aG9kIGRlZmluZWQgaW4gamF2YS5pby5Xcml0ZXIgKi8KLSAgICBwdWJsaWMgdm9pZCB3cml0ZShTdHJpbmcgY2hhcnMsIGludCBzdGFydCwgaW50IGNvdW50KSB0aHJvd3MgSU9FeGNlcHRpb247Ci0gICAgLyoqIFRoaXMgbWV0aG9kIGZvcmNlcyB1cyB0byBvdmVyLXJpZGUgdGhlIG1ldGhvZCBkZWZpbmVkIGluIGphdmEuaW8uV3JpdGVyICovCi0gICAgcHVibGljIHZvaWQgZmx1c2goKSB0aHJvd3MgSU9FeGNlcHRpb247Ci0gICAgLyoqIFRoaXMgbWV0aG9kIGZvcmNlcyB1cyB0byBvdmVyLXJpZGUgdGhlIG1ldGhvZCBkZWZpbmVkIGluIGphdmEuaW8uV3JpdGVyICovCi0gICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBJZiB0aGlzIG1ldGhvZCByZXR1cm5zIG51bGwsIGdldE91dHB1dFN0cmVhbSgpIG11c3QgcmV0dXJuIG5vbi1udWxsLgotICAgICAqIEdldCB0aGUgd3JpdGVyIHRoYXQgdGhpcyB3cml0ZXIgc2VuZHMgaXRzIG91dHB1dCB0by4KLSAgICAgKgotICAgICAqIEl0IGlzIHBvc3NpYmxlIHRoYXQgdGhlIFdyaXRlciByZXR1cm5lZCBieSB0aGlzIG1ldGhvZCBkb2VzIG5vdAotICAgICAqIGltcGxlbWVudCB0aGUgV3JpdGVyQ2hhaW4gaW50ZXJmYWNlLgotICAgICAqLwotICAgIHB1YmxpYyBqYXZhLmlvLldyaXRlciBnZXRXcml0ZXIoKTsKLQotICAgIC8qKgotICAgICAqIElmIHRoaXMgbWV0aG9kIHJldHVybnMgbnVsbCwgZ2V0V3JpdGVyKCkgbXVzdCByZXR1cm4gbm9uLW51bGwuCi0gICAgICogR2V0IHRoZSBPdXRwdXRTdHJlYW0gdGhhdCB0aGlzIHdyaXRlciBzZW5kcyBpdHMgb3V0cHV0IHRvLgotICAgICAqLwotICAgIHB1YmxpYyBqYXZhLmlvLk91dHB1dFN0cmVhbSBnZXRPdXRwdXRTdHJlYW0oKTsKLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvV3JpdGVyVG9BU0NJLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1dyaXRlclRvQVNDSS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjZmJiZDljLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvV3JpdGVyVG9BU0NJLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNTcgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogV3JpdGVyVG9BU0NJLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTUgMDg6MTU6MzEgc3VyZXNoX2VtYWlsaWQgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXI7Ci0KLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uV3JpdGVyOwotCi0KLQotLyoqCi0gKiBUaGlzIGNsYXNzIHdyaXRlcyBBU0NJSSB0byBhIGJ5dGUgc3RyZWFtIGFzIHF1aWNrbHkgYXMgcG9zc2libGUuICBGb3IgdGhlCi0gKiBtb21lbnQgaXQgZG9lcyBub3QgZG8gYnVmZmVyaW5nLCB0aG91Z2ggSSByZXNlcnZlIHRoZSByaWdodCB0byBkbyBzb21lCi0gKiBidWZmZXJpbmcgZG93biB0aGUgbGluZSBpZiBJIGNhbiBwcm92ZSB0aGF0IGl0IHdpbGwgYmUgZmFzdGVyIGV2ZW4gaWYgdGhlCi0gKiBvdXRwdXQgc3RyZWFtIGlzIGJ1ZmZlcmVkLgotICoKLSAqIFRoaXMgY2xhc3MgaXMgb25seSB1c2VkIGludGVybmFsbHkgd2l0aGluIFhhbGFuLgotICoKLSAqIEB4c2wudXNhZ2UgaW50ZXJuYWwKLSAqLwotY2xhc3MgV3JpdGVyVG9BU0NJIGV4dGVuZHMgV3JpdGVyIGltcGxlbWVudHMgV3JpdGVyQ2hhaW4KLXsKLQotICAvKiogVGhlIGJ5dGUgc3RyZWFtIHRvIHdyaXRlIHRvLiAgKi8KLSAgcHJpdmF0ZSBmaW5hbCBPdXRwdXRTdHJlYW0gbV9vczsKLQotICAvKioKLSAgICogQ3JlYXRlIGFuIHVuYnVmZmVyZWQgQVNDSUkgd3JpdGVyLgotICAgKgotICAgKgotICAgKiBAcGFyYW0gb3MgVGhlIGJ5dGUgc3RyZWFtIHRvIHdyaXRlIHRvLgotICAgKi8KLSAgcHVibGljIFdyaXRlclRvQVNDSShPdXRwdXRTdHJlYW0gb3MpCi0gIHsKLSAgICBtX29zID0gb3M7Ci0gIH0KLQotICAvKioKLSAgICogV3JpdGUgYSBwb3J0aW9uIG9mIGFuIGFycmF5IG9mIGNoYXJhY3RlcnMuCi0gICAqCi0gICAqIEBwYXJhbSAgY2hhcnMgIEFycmF5IG9mIGNoYXJhY3RlcnMKLSAgICogQHBhcmFtICBzdGFydCAgIE9mZnNldCBmcm9tIHdoaWNoIHRvIHN0YXJ0IHdyaXRpbmcgY2hhcmFjdGVycwotICAgKiBAcGFyYW0gIGxlbmd0aCAgIE51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHdyaXRlCi0gICAqCi0gICAqIEBleGNlcHRpb24gIElPRXhjZXB0aW9uICBJZiBhbiBJL08gZXJyb3Igb2NjdXJzCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgd3JpdGUoY2hhciBjaGFyc1tdLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpCi0gICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24KLSAgewotCi0gICAgaW50IG4gPSBsZW5ndGgrc3RhcnQ7Ci0KLSAgICBmb3IgKGludCBpID0gc3RhcnQ7IGkgPCBuOyBpKyspCi0gICAgewotICAgICAgbV9vcy53cml0ZShjaGFyc1tpXSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFdyaXRlIGEgc2luZ2xlIGNoYXJhY3Rlci4gIFRoZSBjaGFyYWN0ZXIgdG8gYmUgd3JpdHRlbiBpcyBjb250YWluZWQgaW4KLSAgICogdGhlIDE2IGxvdy1vcmRlciBiaXRzIG9mIHRoZSBnaXZlbiBpbnRlZ2VyIHZhbHVlOyB0aGUgMTYgaGlnaC1vcmRlciBiaXRzCi0gICAqIGFyZSBpZ25vcmVkLgotICAgKgotICAgKiA8cD4gU3ViY2xhc3NlcyB0aGF0IGludGVuZCB0byBzdXBwb3J0IGVmZmljaWVudCBzaW5nbGUtY2hhcmFjdGVyIG91dHB1dAotICAgKiBzaG91bGQgb3ZlcnJpZGUgdGhpcyBtZXRob2QuCi0gICAqCi0gICAqIEBwYXJhbSBjICBpbnQgc3BlY2lmeWluZyBhIGNoYXJhY3RlciB0byBiZSB3cml0dGVuLgotICAgKiBAZXhjZXB0aW9uICBJT0V4Y2VwdGlvbiAgSWYgYW4gSS9PIGVycm9yIG9jY3VycwotICAgKi8KLSAgcHVibGljIHZvaWQgd3JpdGUoaW50IGMpIHRocm93cyBJT0V4Y2VwdGlvbgotICB7Ci0gICAgbV9vcy53cml0ZShjKTsKLSAgfQotCi0gIC8qKgotICAgKiBXcml0ZSBhIHN0cmluZy4KLSAgICoKLSAgICogQHBhcmFtICBzIFN0cmluZyB0byBiZSB3cml0dGVuCi0gICAqCi0gICAqIEBleGNlcHRpb24gIElPRXhjZXB0aW9uICBJZiBhbiBJL08gZXJyb3Igb2NjdXJzCi0gICAqLwotICBwdWJsaWMgdm9pZCB3cml0ZShTdHJpbmcgcykgdGhyb3dzIElPRXhjZXB0aW9uCi0gIHsKLSAgICBpbnQgbiA9IHMubGVuZ3RoKCk7Ci0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspCi0gICAgewotICAgICAgbV9vcy53cml0ZShzLmNoYXJBdChpKSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEZsdXNoIHRoZSBzdHJlYW0uICBJZiB0aGUgc3RyZWFtIGhhcyBzYXZlZCBhbnkgY2hhcmFjdGVycyBmcm9tIHRoZQotICAgKiB2YXJpb3VzIHdyaXRlKCkgbWV0aG9kcyBpbiBhIGJ1ZmZlciwgd3JpdGUgdGhlbSBpbW1lZGlhdGVseSB0byB0aGVpcgotICAgKiBpbnRlbmRlZCBkZXN0aW5hdGlvbi4gIFRoZW4sIGlmIHRoYXQgZGVzdGluYXRpb24gaXMgYW5vdGhlciBjaGFyYWN0ZXIgb3IKLSAgICogYnl0ZSBzdHJlYW0sIGZsdXNoIGl0LiAgVGh1cyBvbmUgZmx1c2goKSBpbnZvY2F0aW9uIHdpbGwgZmx1c2ggYWxsIHRoZQotICAgKiBidWZmZXJzIGluIGEgY2hhaW4gb2YgV3JpdGVycyBhbmQgT3V0cHV0U3RyZWFtcy4KLSAgICoKLSAgICogQGV4Y2VwdGlvbiAgSU9FeGNlcHRpb24gIElmIGFuIEkvTyBlcnJvciBvY2N1cnMKLSAgICovCi0gIHB1YmxpYyB2b2lkIGZsdXNoKCkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24KLSAgewotICAgIG1fb3MuZmx1c2goKTsKLSAgfQotCi0gIC8qKgotICAgKiBDbG9zZSB0aGUgc3RyZWFtLCBmbHVzaGluZyBpdCBmaXJzdC4gIE9uY2UgYSBzdHJlYW0gaGFzIGJlZW4gY2xvc2VkLAotICAgKiBmdXJ0aGVyIHdyaXRlKCkgb3IgZmx1c2goKSBpbnZvY2F0aW9ucyB3aWxsIGNhdXNlIGFuIElPRXhjZXB0aW9uIHRvIGJlCi0gICAqIHRocm93bi4gIENsb3NpbmcgYSBwcmV2aW91c2x5LWNsb3NlZCBzdHJlYW0sIGhvd2V2ZXIsIGhhcyBubyBlZmZlY3QuCi0gICAqCi0gICAqIEBleGNlcHRpb24gIElPRXhjZXB0aW9uICBJZiBhbiBJL08gZXJyb3Igb2NjdXJzCi0gICAqLwotICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uCi0gIHsKLSAgICBtX29zLmNsb3NlKCk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBvdXRwdXQgc3RyZWFtIHdoZXJlIHRoZSBldmVudHMgd2lsbCBiZSBzZXJpYWxpemVkIHRvLgotICAgKgotICAgKiBAcmV0dXJuIHJlZmVyZW5jZSB0byB0aGUgcmVzdWx0IHN0cmVhbSwgb3IgbnVsbCBvZiBvbmx5IGEgd3JpdGVyIHdhcwotICAgKiBzZXQuCi0gICAqLwotICBwdWJsaWMgT3V0cHV0U3RyZWFtIGdldE91dHB1dFN0cmVhbSgpCi0gIHsKLSAgICByZXR1cm4gbV9vczsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIHdyaXRlciB0aGF0IHRoaXMgd3JpdGVyIGRpcmVjdGx5IGNoYWlucyB0by4KLSAgICovCi0gIHB1YmxpYyBXcml0ZXIgZ2V0V3JpdGVyKCkKLSAgewotICAgICAgcmV0dXJuIG51bGw7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvV3JpdGVyVG9VVEY4QnVmZmVyZWQuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvV3JpdGVyVG9VVEY4QnVmZmVyZWQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYjkyOTFjYy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1dyaXRlclRvVVRGOEJ1ZmZlcmVkLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw1MDUgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogV3JpdGVyVG9VVEY4QnVmZmVyZWQuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNSAwODoxNTozMSBzdXJlc2hfZW1haWxpZCBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplcjsKLQotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci1pbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5pby5VbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uOwotaW1wb3J0IGphdmEuaW8uV3JpdGVyOwotCi0KLS8qKgotICogVGhpcyBjbGFzcyB3cml0ZXMgdW5pY29kZSBjaGFyYWN0ZXJzIHRvIGEgYnl0ZSBzdHJlYW0gKGphdmEuaW8uT3V0cHV0U3RyZWFtKQotICogYXMgcXVpY2tseSBhcyBwb3NzaWJsZS4gSXQgYnVmZmVycyB0aGUgb3V0cHV0IGluIGFuIGludGVybmFsCi0gKiBidWZmZXIgd2hpY2ggbXVzdCBiZSBmbHVzaGVkIHRvIHRoZSBPdXRwdXRTdHJlYW0gd2hlbiBkb25lLiBUaGlzIGZsdXNoaW5nCi0gKiBpcyBkb25lIHZpYSB0aGUgY2xvc2UoKSBmbHVzaCgpIG9yIGZsdXNoQnVmZmVyKCkgbWV0aG9kLgotICoKLSAqIFRoaXMgY2xhc3MgaXMgb25seSB1c2VkIGludGVybmFsbHkgd2l0aGluIFhhbGFuLgotICoKLSAqIEB4c2wudXNhZ2UgaW50ZXJuYWwKLSAqLwotZmluYWwgY2xhc3MgV3JpdGVyVG9VVEY4QnVmZmVyZWQgZXh0ZW5kcyBXcml0ZXIgaW1wbGVtZW50cyBXcml0ZXJDaGFpbgotewotCi0gIC8qKiBudW1iZXIgb2YgYnl0ZXMgdGhhdCB0aGUgYnl0ZSBidWZmZXIgY2FuIGhvbGQuCi0gICAqIFRoaXMgaXMgYSBmaXhlZCBjb25zdGFudCBpcyB1c2VkIHJhdGhlciB0aGFuIG1fb3V0cHV0Qnl0ZXMubGVuZ2h0IGZvciBwZXJmb3JtYW5jZS4KLSAgICovCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBCWVRFU19NQVg9MTYqMTAyNDsKLSAgLyoqIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRoYXQgdGhlIGNoYXJhY3RlciBidWZmZXIgY2FuIGhvbGQuCi0gICAqIFRoaXMgaXMgMS8zIG9mIHRoZSBudW1iZXIgb2YgYnl0ZXMgYmVjYXVzZSBVVEYtOCBlbmNvZGluZwotICAgKiBjYW4gZXhwYW5kIG9uZSB1bmljb2RlIGNoYXJhY3RlciBieSB1cCB0byAzIGJ5dGVzLgotICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IENIQVJTX01BWD0oQllURVNfTUFYLzMpOwotCi0gLy8gcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50Ci0KLSAgLyoqIFRoZSBieXRlIHN0cmVhbSB0byB3cml0ZSB0by4gKHNjICYgc2IgcmVtb3ZlIGZpbmFsIHRvIGNvbXBpbGUgaW4gSkRLIDEuMS44KSAqLwotICBwcml2YXRlIGZpbmFsIE91dHB1dFN0cmVhbSBtX29zOwotCi0gIC8qKgotICAgKiBUaGUgaW50ZXJuYWwgYnVmZmVyIHdoZXJlIGRhdGEgaXMgc3RvcmVkLgotICAgKiAoc2MgJiBzYiByZW1vdmUgZmluYWwgdG8gY29tcGlsZSBpbiBKREsgMS4xLjgpCi0gICAqLwotICBwcml2YXRlIGZpbmFsIGJ5dGUgbV9vdXRwdXRCeXRlc1tdOwotCi0gIHByaXZhdGUgZmluYWwgY2hhciBtX2lucHV0Q2hhcnNbXTsKLQotICAvKioKLSAgICogVGhlIG51bWJlciBvZiB2YWxpZCBieXRlcyBpbiB0aGUgYnVmZmVyLiBUaGlzIHZhbHVlIGlzIGFsd2F5cwotICAgKiBpbiB0aGUgcmFuZ2UgPHR0PjA8L3R0PiB0aHJvdWdoIDx0dD5tX291dHB1dEJ5dGVzLmxlbmd0aDwvdHQ+OyBlbGVtZW50cwotICAgKiA8dHQ+bV9vdXRwdXRCeXRlc1swXTwvdHQ+IHRocm91Z2ggPHR0Pm1fb3V0cHV0Qnl0ZXNbY291bnQtMV08L3R0PiBjb250YWluIHZhbGlkCi0gICAqIGJ5dGUgZGF0YS4KLSAgICovCi0gIHByaXZhdGUgaW50IGNvdW50OwotCi0gIC8qKgotICAgKiBDcmVhdGUgYW4gYnVmZmVyZWQgVVRGLTggd3JpdGVyLgotICAgKgotICAgKgotICAgKiBAcGFyYW0gICBvdXQgICAgdGhlIHVuZGVybHlpbmcgb3V0cHV0IHN0cmVhbS4KLSAgICoKLSAgICogQHRocm93cyBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgV3JpdGVyVG9VVEY4QnVmZmVyZWQoT3V0cHV0U3RyZWFtIG91dCkKLSAgICAgICAgICB0aHJvd3MgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbgotICB7Ci0gICAgICBtX29zID0gb3V0OwotICAgICAgLy8gZ2V0IDMgZXh0cmEgYnl0ZXMgdG8gbWFrZSBidWZmZXIgb3ZlcmZsb3cgY2hlY2tpbmcgc2ltcGxlciBhbmQgZmFzdGVyCi0gICAgICAvLyB3ZSB3b24ndCBoYXZlIHRvIGtlZXAgY2hlY2tpbmcgZm9yIGEgZmV3IGV4dHJhIGNoYXJhY3RlcnMKLSAgICAgIG1fb3V0cHV0Qnl0ZXMgPSBuZXcgYnl0ZVtCWVRFU19NQVggKyAzXTsKLQotICAgICAgLy8gQmlnIGVub3VnaCB0byBob2xkIHRoZSBpbnB1dCBjaGFycyB0aGF0IHdpbGwgYmUgdHJhbnNmb3JtZWQKLSAgICAgIC8vIGludG8gb3V0cHV0IGJ5dGVzIGluIG1fb3VwdXRCeXRlcy4KLSAgICAgIG1faW5wdXRDaGFycyA9IG5ldyBjaGFyW0NIQVJTX01BWCArIDJdOwotICAgICAgY291bnQgPSAwOwotCi0vLyAgICAgIHRoZSBvbGQgYm9keSBvZiB0aGlzIGNvbnN0cnVjdG9yLCBiZWZvcmUgdGhlIGJ1ZmZlcnNpemUgd2FzIGNoYW5nZWQgdG8gYSBjb25zdGFudAotLy8gICAgICB0aGlzKG91dCwgOCoxMDI0KTsKLSAgfQotCi0gIC8qKgotICAgKiBDcmVhdGUgYW4gYnVmZmVyZWQgVVRGLTggd3JpdGVyIHRvIHdyaXRlIGRhdGEgdG8gdGhlCi0gICAqIHNwZWNpZmllZCB1bmRlcmx5aW5nIG91dHB1dCBzdHJlYW0gd2l0aCB0aGUgc3BlY2lmaWVkIGJ1ZmZlcgotICAgKiBzaXplLgotICAgKgotICAgKiBAcGFyYW0gICBvdXQgICAgdGhlIHVuZGVybHlpbmcgb3V0cHV0IHN0cmVhbS4KLSAgICogQHBhcmFtICAgc2l6ZSAgIHRoZSBidWZmZXIgc2l6ZS4KLSAgICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgc2l6ZSA8PSAwLgotICAgKi8KLS8vICBwdWJsaWMgV3JpdGVyVG9VVEY4QnVmZmVyZWQoZmluYWwgT3V0cHV0U3RyZWFtIG91dCwgZmluYWwgaW50IHNpemUpCi0vLyAgewotLy8KLS8vICAgIG1fb3MgPSBvdXQ7Ci0vLwotLy8gICAgaWYgKHNpemUgPD0gMCkKLS8vICAgIHsKLS8vICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKLS8vICAgICAgICBTZXJpYWxpemVyTWVzc2FnZXMuY3JlYXRlTWVzc2FnZShTZXJpYWxpemVyRXJyb3JSZXNvdXJjZXMuRVJfQlVGRkVSX1NJWkVfTEVTU1RIQU5fWkVSTywgbnVsbCkpOyAvLyJCdWZmZXIgc2l6ZSA8PSAwIik7Ci0vLyAgICB9Ci0vLwotLy8gICAgbV9vdXRwdXRCeXRlcyA9IG5ldyBieXRlW3NpemVdOwotLy8gICAgY291bnQgPSAwOwotLy8gIH0KLQotICAvKioKLSAgICogV3JpdGUgYSBzaW5nbGUgY2hhcmFjdGVyLiAgVGhlIGNoYXJhY3RlciB0byBiZSB3cml0dGVuIGlzIGNvbnRhaW5lZCBpbgotICAgKiB0aGUgMTYgbG93LW9yZGVyIGJpdHMgb2YgdGhlIGdpdmVuIGludGVnZXIgdmFsdWU7IHRoZSAxNiBoaWdoLW9yZGVyIGJpdHMKLSAgICogYXJlIGlnbm9yZWQuCi0gICAqCi0gICAqIDxwPiBTdWJjbGFzc2VzIHRoYXQgaW50ZW5kIHRvIHN1cHBvcnQgZWZmaWNpZW50IHNpbmdsZS1jaGFyYWN0ZXIgb3V0cHV0Ci0gICAqIHNob3VsZCBvdmVycmlkZSB0aGlzIG1ldGhvZC4KLSAgICoKLSAgICogQHBhcmFtIGMgIGludCBzcGVjaWZ5aW5nIGEgY2hhcmFjdGVyIHRvIGJlIHdyaXR0ZW4uCi0gICAqIEBleGNlcHRpb24gIElPRXhjZXB0aW9uICBJZiBhbiBJL08gZXJyb3Igb2NjdXJzCi0gICAqLwotICBwdWJsaWMgdm9pZCB3cml0ZShmaW5hbCBpbnQgYykgdGhyb3dzIElPRXhjZXB0aW9uCi0gIHsKLQotICAgIC8qIElmIHdlIGFyZSBjbG9zZSB0byB0aGUgZW5kIG9mIHRoZSBidWZmZXIgdGhlbiBmbHVzaCBpdC4KLSAgICAgKiBSZW1lbWJlciB0aGUgYnVmZmVyIGNhbiBob2xkIGEgZmV3IG1vcmUgYnl0ZXMgdGhhbiBCWVRFU19NQVgKLSAgICAgKi8KLSAgICBpZiAoY291bnQgPj0gQllURVNfTUFYKQotICAgICAgICBmbHVzaEJ1ZmZlcigpOwotCi0gICAgaWYgKGMgPCAweDgwKQotICAgIHsKLSAgICAgICBtX291dHB1dEJ5dGVzW2NvdW50KytdID0gKGJ5dGUpIChjKTsKLSAgICB9Ci0gICAgZWxzZSBpZiAoYyA8IDB4ODAwKQotICAgIHsKLSAgICAgIG1fb3V0cHV0Qnl0ZXNbY291bnQrK10gPSAoYnl0ZSkgKDB4YzAgKyAoYyA+PiA2KSk7Ci0gICAgICBtX291dHB1dEJ5dGVzW2NvdW50KytdID0gKGJ5dGUpICgweDgwICsgKGMgJiAweDNmKSk7Ci0gICAgfQotICAgIGVsc2UgaWYgKGMgPCAweDEwMDAwKQotICAgIHsKLSAgICAgIG1fb3V0cHV0Qnl0ZXNbY291bnQrK10gPSAoYnl0ZSkgKDB4ZTAgKyAoYyA+PiAxMikpOwotICAgICAgbV9vdXRwdXRCeXRlc1tjb3VudCsrXSA9IChieXRlKSAoMHg4MCArICgoYyA+PiA2KSAmIDB4M2YpKTsKLSAgICAgIG1fb3V0cHV0Qnl0ZXNbY291bnQrK10gPSAoYnl0ZSkgKDB4ODAgKyAoYyAmIDB4M2YpKTsKLSAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotICAgICAgICAgIG1fb3V0cHV0Qnl0ZXNbY291bnQrK10gPSAoYnl0ZSkgKDB4ZjAgKyAoYyA+PiAxOCkpOwotICAgICAgICAgIG1fb3V0cHV0Qnl0ZXNbY291bnQrK10gPSAoYnl0ZSkgKDB4ODAgKyAoKGMgPj4gMTIpICYgMHgzZikpOwotICAgICAgICAgIG1fb3V0cHV0Qnl0ZXNbY291bnQrK10gPSAoYnl0ZSkgKDB4ODAgKyAoKGMgPj4gNikgJiAweDNmKSk7Ci0gICAgICAgICAgbV9vdXRwdXRCeXRlc1tjb3VudCsrXSA9IChieXRlKSAoMHg4MCArIChjICYgMHgzZikpOwotICAgICAgICB9Ci0KLSAgfQotCi0KLSAgLyoqCi0gICAqIFdyaXRlIGEgcG9ydGlvbiBvZiBhbiBhcnJheSBvZiBjaGFyYWN0ZXJzLgotICAgKgotICAgKiBAcGFyYW0gIGNoYXJzICBBcnJheSBvZiBjaGFyYWN0ZXJzCi0gICAqIEBwYXJhbSAgc3RhcnQgICBPZmZzZXQgZnJvbSB3aGljaCB0byBzdGFydCB3cml0aW5nIGNoYXJhY3RlcnMKLSAgICogQHBhcmFtICBsZW5ndGggICBOdW1iZXIgb2YgY2hhcmFjdGVycyB0byB3cml0ZQotICAgKgotICAgKiBAZXhjZXB0aW9uICBJT0V4Y2VwdGlvbiAgSWYgYW4gSS9PIGVycm9yIG9jY3VycwotICAgKgotICAgKiBAdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHdyaXRlKGZpbmFsIGNoYXIgY2hhcnNbXSwgZmluYWwgaW50IHN0YXJ0LCBmaW5hbCBpbnQgbGVuZ3RoKQotICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uCi0gIHsKLQotICAgIC8vIFdlIG11bHRpcGx5IHRoZSBsZW5ndGggYnkgdGhyZWUgc2luY2UgdGhpcyBpcyB0aGUgbWF4aW11bSBsZW5ndGgKLSAgICAvLyBvZiB0aGUgY2hhcmFjdGVycyB0aGF0IHdlIGNhbiBwdXQgaW50byB0aGUgYnVmZmVyLiAgSXQgaXMgcG9zc2libGUKLSAgICAvLyBmb3IgZWFjaCBVbmljb2RlIGNoYXJhY3RlciB0byBleHBhbmQgdG8gdGhyZWUgYnl0ZXMuCi0KLSAgICBpbnQgbGVuZ3RoeDMgPSAzKmxlbmd0aDsKLQotICAgIGlmIChsZW5ndGh4MyA+PSBCWVRFU19NQVggLSBjb3VudCkKLSAgICB7Ci0gICAgICAvLyBUaGUgcmVxdWVzdGVkIGxlbmd0aCBpcyBncmVhdGVyIHRoYW4gdGhlIHVudXNlZCBwYXJ0IG9mIHRoZSBidWZmZXIKLSAgICAgIGZsdXNoQnVmZmVyKCk7Ci0KLSAgICAgIGlmIChsZW5ndGh4MyA+IEJZVEVTX01BWCkKLSAgICAgIHsKLSAgICAgICAgLyoKLSAgICAgICAgICogVGhlIHJlcXVlc3RlZCBsZW5ndGggZXhjZWVkcyB0aGUgc2l6ZSBvZiB0aGUgYnVmZmVyLgotICAgICAgICAgKiBDdXQgdGhlIGJ1ZmZlciB1cCBpbnRvIGNodW5rcywgZWFjaCBvZiB3aGljaCB3aWxsCi0gICAgICAgICAqIG5vdCBjYXVzZSBhbiBvdmVyZmxvdyB0byB0aGUgb3V0cHV0IGJ1ZmZlciBtX291dHB1dEJ5dGVzLAotICAgICAgICAgKiBhbmQgbWFrZSBtdWx0aXBsZSByZWN1cnNpdmUgY2FsbHMuCi0gICAgICAgICAqIEJlIGNhcmVmdWwgYWJvdXQgaW50ZWdlciBvdmVyZmxvd3MgaW4gbXVsdGlwbGljYXRpb24uCi0gICAgICAgICAqLwotICAgICAgICBpbnQgc3BsaXQgPSBsZW5ndGgvQ0hBUlNfTUFYOwotICAgICAgICBmaW5hbCBpbnQgY2h1bmtzOwotICAgICAgICBpZiAobGVuZ3RoICUgQ0hBUlNfTUFYID4gMCkKLSAgICAgICAgICAgIGNodW5rcyA9IHNwbGl0ICsgMTsKLSAgICAgICAgZWxzZQotICAgICAgICAgICAgY2h1bmtzID0gc3BsaXQ7Ci0gICAgICAgIGludCBlbmRfY2h1bmsgPSBzdGFydDsKLSAgICAgICAgZm9yIChpbnQgY2h1bmsgPSAxOyBjaHVuayA8PSBjaHVua3M7IGNodW5rKyspCi0gICAgICAgIHsKLSAgICAgICAgICAgIGludCBzdGFydF9jaHVuayA9IGVuZF9jaHVuazsKLSAgICAgICAgICAgIGVuZF9jaHVuayA9IHN0YXJ0ICsgKGludCkgKCgoKGxvbmcpIGxlbmd0aCkgKiBjaHVuaykgLyBjaHVua3MpOwotCi0gICAgICAgICAgICAvLyBBZGp1c3QgdGhlIGVuZCBvZiB0aGUgY2h1bmsgaWYgaXQgZW5kcyBvbiBhIGhpZ2ggY2hhcgotICAgICAgICAgICAgLy8gb2YgYSBVbmljb2RlIHN1cnJvZ2F0ZSBwYWlyIGFuZCBsb3cgY2hhciBvZiB0aGUgcGFpcgotICAgICAgICAgICAgLy8gaXMgbm90IGdvaW5nIHRvIGJlIGluIHRoZSBzYW1lIGNodW5rCi0gICAgICAgICAgICBmaW5hbCBjaGFyIGMgPSBjaGFyc1tlbmRfY2h1bmsgLSAxXTsKLSAgICAgICAgICAgIGludCBpYyA9IGNoYXJzW2VuZF9jaHVuayAtIDFdOwotICAgICAgICAgICAgaWYgKGMgPj0gMHhEODAwICYmIGMgPD0gMHhEQkZGKSB7Ci0gICAgICAgICAgICAgICAgLy8gVGhlIGxhc3QgSmF2YSBjaGFyIHRoYXQgd2Ugd2VyZSBnb2luZwotICAgICAgICAgICAgICAgIC8vIHRvIHByb2Nlc3MgaXMgdGhlIGZpcnN0IG9mIGEKLSAgICAgICAgICAgICAgICAvLyBKYXZhIHN1cnJvZ2F0ZSBjaGFyIHBhaXIgdGhhdAotICAgICAgICAgICAgICAgIC8vIHJlcHJlc2VudCBhIFVuaWNvZGUgY2hhcmFjdGVyLgotCi0gICAgICAgICAgICAgICAgaWYgKGVuZF9jaHVuayA8IHN0YXJ0ICsgbGVuZ3RoKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIEF2b2lkIHNwYW5uaW5nIGJ5IGluY2x1ZGluZyB0aGUgbG93Ci0gICAgICAgICAgICAgICAgICAgIC8vIGNoYXIgaW4gdGhlIGN1cnJlbnQgY2h1bmsgb2YgY2hhcnMuCi0gICAgICAgICAgICAgICAgICAgIGVuZF9jaHVuaysrOwotICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIC8qIFRoaXMgaXMgdGhlIGxhc3QgY2hhciBvZiB0aGUgbGFzdCBjaHVuaywKLSAgICAgICAgICAgICAgICAgICAgICogYW5kIGl0IGlzIHRoZSBoaWdoIGNoYXIgb2YgYSBoaWdoL2xvdyBwYWlyIHdpdGgKLSAgICAgICAgICAgICAgICAgICAgICogbm8gbG93IGNoYXIgcHJvdmlkZWQuCi0gICAgICAgICAgICAgICAgICAgICAqIFRPRE86IGVycm9yIG1lc3NhZ2UgbmVlZGVkLgotICAgICAgICAgICAgICAgICAgICAgKiBUaGUgY2hhciBhcnJheSBpbmNvcnJlY3RseSBlbmRzIGluIGEgaGlnaCBjaGFyCi0gICAgICAgICAgICAgICAgICAgICAqIG9mIGEgaGlnaC9sb3cgc3Vycm9nYXRlIHBhaXIsIGJ1dCB0aGVyZSBpcwotICAgICAgICAgICAgICAgICAgICAgKiBubyBjb3JyZXNwb25kaW5nIGxvdyBhcyB0aGUgaGlnaCBpcyB0aGUgbGFzdCBjaGFyCi0gICAgICAgICAgICAgICAgICAgICAqLwotICAgICAgICAgICAgICAgICAgICBlbmRfY2h1bmstLTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLQotICAgICAgICAgICAgaW50IGxlbl9jaHVuayA9IChlbmRfY2h1bmsgLSBzdGFydF9jaHVuayk7Ci0gICAgICAgICAgICB0aGlzLndyaXRlKGNoYXJzLHN0YXJ0X2NodW5rLCBsZW5fY2h1bmspOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybjsKLSAgICAgIH0KLSAgICB9Ci0KLQotCi0gICAgZmluYWwgaW50IG4gPSBsZW5ndGgrc3RhcnQ7Ci0gICAgZmluYWwgYnl0ZVtdIGJ1Zl9sb2MgPSBtX291dHB1dEJ5dGVzOyAvLyBsb2NhbCByZWZlcmVuY2UgZm9yIGZhc3RlciBhY2Nlc3MKLSAgICBpbnQgY291bnRfbG9jID0gY291bnQ7ICAgICAgLy8gbG9jYWwgaW50ZWdlciBmb3IgZmFzdGVyIGFjY2VzcwotICAgIGludCBpID0gc3RhcnQ7Ci0gICAgewotICAgICAgICAvKiBUaGlzIGJsb2NrIGNvdWxkIGJlIG9taXR0ZWQgYW5kIHRoZSBjb2RlIHdvdWxkIHByb2R1Y2UKLSAgICAgICAgICogdGhlIHNhbWUgcmVzdWx0LiBCdXQgdGhpcyBibG9jayBleGlzdHMgdG8gZ2l2ZSB0aGUgSklUCi0gICAgICAgICAqIGEgYmV0dGVyIGNoYW5jZSBvZiBvcHRpbWl6aW5nIGEgdGlnaHQgYW5kIGNvbW1vbiBsb29wIHdoaWNoCi0gICAgICAgICAqIG9jY3VycyB3aGVuIHdyaXRpbmcgb3V0IEFTQ0lJIGNoYXJhY3RlcnMuCi0gICAgICAgICAqLwotICAgICAgICBjaGFyIGM7Ci0gICAgICAgIGZvcig7IGkgPCBuICYmIChjID0gY2hhcnNbaV0pPCAweDgwIDsgaSsrICkKLSAgICAgICAgICAgIGJ1Zl9sb2NbY291bnRfbG9jKytdID0gKGJ5dGUpYzsKLSAgICB9Ci0gICAgZm9yICg7IGkgPCBuOyBpKyspCi0gICAgewotCi0gICAgICBmaW5hbCBjaGFyIGMgPSBjaGFyc1tpXTsKLQotICAgICAgaWYgKGMgPCAweDgwKQotICAgICAgICBidWZfbG9jW2NvdW50X2xvYysrXSA9IChieXRlKSAoYyk7Ci0gICAgICBlbHNlIGlmIChjIDwgMHg4MDApCi0gICAgICB7Ci0gICAgICAgIGJ1Zl9sb2NbY291bnRfbG9jKytdID0gKGJ5dGUpICgweGMwICsgKGMgPj4gNikpOwotICAgICAgICBidWZfbG9jW2NvdW50X2xvYysrXSA9IChieXRlKSAoMHg4MCArIChjICYgMHgzZikpOwotICAgICAgfQotICAgICAgLyoqCi0gICAgICAgICogVGhlIGZvbGxvd2luZyBlbHNlIGlmIGNvbmRpdGlvbiBpcyBhZGRlZCB0byBzdXBwb3J0IFhNTCAxLjEgQ2hhcmFjdGVycyBmb3IKLSAgICAgICAgKiBVVEYtODogICBbMTExMSAwdXV1XSBbMTB1dSB6enp6XSBbMTB5eSB5eXl5XSBbMTB4eCB4eHh4XSoKLSAgICAgICAgKiBVbmljb2RlOiBbMTEwMSAxMHd3XSBbd3d6eiB6enl5XSAoaGlnaCBzdXJyb2dhdGUpCi0gICAgICAgICogICAgICAgICAgWzExMDEgMTF5eV0gW3l5eHggeHh4eF0gKGxvdyBzdXJyb2dhdGUpCi0gICAgICAgICogICAgICAgICAgKiB1dXV1dSA9IHd3d3cgKyAxCi0gICAgICAgICovCi0gICAgICBlbHNlIGlmIChjID49IDB4RDgwMCAmJiBjIDw9IDB4REJGRikKLSAgICAgIHsKLSAgICAgICAgICBjaGFyIGhpZ2gsIGxvdzsKLSAgICAgICAgICBoaWdoID0gYzsKLSAgICAgICAgICBpKys7Ci0gICAgICAgICAgbG93ID0gY2hhcnNbaV07Ci0KLSAgICAgICAgICBidWZfbG9jW2NvdW50X2xvYysrXSA9IChieXRlKSAoMHhGMCB8ICgoKGhpZ2ggKyAweDQwKSA+PiA4KSAmIDB4ZjApKTsKLSAgICAgICAgICBidWZfbG9jW2NvdW50X2xvYysrXSA9IChieXRlKSAoMHg4MCB8ICgoKGhpZ2ggKyAweDQwKSA+PiAyKSAmIDB4M2YpKTsKLSAgICAgICAgICBidWZfbG9jW2NvdW50X2xvYysrXSA9IChieXRlKSAoMHg4MCB8ICgobG93ID4+IDYpICYgMHgwZikgKyAoKGhpZ2ggPDwgNCkgJiAweDMwKSk7Ci0gICAgICAgICAgYnVmX2xvY1tjb3VudF9sb2MrK10gPSAoYnl0ZSkgKDB4ODAgfCAobG93ICYgMHgzZikpOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBidWZfbG9jW2NvdW50X2xvYysrXSA9IChieXRlKSAoMHhlMCArIChjID4+IDEyKSk7Ci0gICAgICAgIGJ1Zl9sb2NbY291bnRfbG9jKytdID0gKGJ5dGUpICgweDgwICsgKChjID4+IDYpICYgMHgzZikpOwotICAgICAgICBidWZfbG9jW2NvdW50X2xvYysrXSA9IChieXRlKSAoMHg4MCArIChjICYgMHgzZikpOwotICAgICAgfQotICAgIH0KLSAgICAvLyBTdG9yZSB0aGUgbG9jYWwgaW50ZWdlciBiYWNrIGludG8gdGhlIGluc3RhbmNlIHZhcmlhYmxlCi0gICAgY291bnQgPSBjb3VudF9sb2M7Ci0KLSAgfQotCi0gIC8qKgotICAgKiBXcml0ZSBhIHN0cmluZy4KLSAgICoKLSAgICogQHBhcmFtICBzICBTdHJpbmcgdG8gYmUgd3JpdHRlbgotICAgKgotICAgKiBAZXhjZXB0aW9uICBJT0V4Y2VwdGlvbiAgSWYgYW4gSS9PIGVycm9yIG9jY3VycwotICAgKi8KLSAgcHVibGljIHZvaWQgd3JpdGUoZmluYWwgU3RyaW5nIHMpIHRocm93cyBJT0V4Y2VwdGlvbgotICB7Ci0KLSAgICAvLyBXZSBtdWx0aXBseSB0aGUgbGVuZ3RoIGJ5IHRocmVlIHNpbmNlIHRoaXMgaXMgdGhlIG1heGltdW0gbGVuZ3RoCi0gICAgLy8gb2YgdGhlIGNoYXJhY3RlcnMgdGhhdCB3ZSBjYW4gcHV0IGludG8gdGhlIGJ1ZmZlci4gIEl0IGlzIHBvc3NpYmxlCi0gICAgLy8gZm9yIGVhY2ggVW5pY29kZSBjaGFyYWN0ZXIgdG8gZXhwYW5kIHRvIHRocmVlIGJ5dGVzLgotICAgIGZpbmFsIGludCBsZW5ndGggPSBzLmxlbmd0aCgpOwotICAgIGludCBsZW5ndGh4MyA9IDMqbGVuZ3RoOwotCi0gICAgaWYgKGxlbmd0aHgzID49IEJZVEVTX01BWCAtIGNvdW50KQotICAgIHsKLSAgICAgIC8vIFRoZSByZXF1ZXN0ZWQgbGVuZ3RoIGlzIGdyZWF0ZXIgdGhhbiB0aGUgdW51c2VkIHBhcnQgb2YgdGhlIGJ1ZmZlcgotICAgICAgZmx1c2hCdWZmZXIoKTsKLQotICAgICAgaWYgKGxlbmd0aHgzID4gQllURVNfTUFYKQotICAgICAgewotICAgICAgICAvKgotICAgICAgICAgKiBUaGUgcmVxdWVzdGVkIGxlbmd0aCBleGNlZWRzIHRoZSBzaXplIG9mIHRoZSBidWZmZXIsCi0gICAgICAgICAqIHNvIGJyZWFrIGl0IHVwIGluIGNodW5rcyB0aGF0IGRvbid0IGV4Y2VlZCB0aGUgYnVmZmVyIHNpemUuCi0gICAgICAgICAqLwotICAgICAgICAgZmluYWwgaW50IHN0YXJ0ID0gMDsKLSAgICAgICAgIGludCBzcGxpdCA9IGxlbmd0aC9DSEFSU19NQVg7Ci0gICAgICAgICBmaW5hbCBpbnQgY2h1bmtzOwotICAgICAgICAgaWYgKGxlbmd0aCAlIENIQVJTX01BWCA+IDApCi0gICAgICAgICAgICAgY2h1bmtzID0gc3BsaXQgKyAxOwotICAgICAgICAgZWxzZQotICAgICAgICAgICAgIGNodW5rcyA9IHNwbGl0OwotICAgICAgICAgaW50IGVuZF9jaHVuayA9IDA7Ci0gICAgICAgICBmb3IgKGludCBjaHVuayA9IDE7IGNodW5rIDw9IGNodW5rczsgY2h1bmsrKykKLSAgICAgICAgIHsKLSAgICAgICAgICAgICBpbnQgc3RhcnRfY2h1bmsgPSBlbmRfY2h1bms7Ci0gICAgICAgICAgICAgZW5kX2NodW5rID0gc3RhcnQgKyAoaW50KSAoKCgobG9uZykgbGVuZ3RoKSAqIGNodW5rKSAvIGNodW5rcyk7Ci0gICAgICAgICAgICAgcy5nZXRDaGFycyhzdGFydF9jaHVuayxlbmRfY2h1bmssIG1faW5wdXRDaGFycywwKTsKLSAgICAgICAgICAgICBpbnQgbGVuX2NodW5rID0gKGVuZF9jaHVuayAtIHN0YXJ0X2NodW5rKTsKLQotICAgICAgICAgICAgIC8vIEFkanVzdCB0aGUgZW5kIG9mIHRoZSBjaHVuayBpZiBpdCBlbmRzIG9uIGEgaGlnaCBjaGFyCi0gICAgICAgICAgICAgLy8gb2YgYSBVbmljb2RlIHN1cnJvZ2F0ZSBwYWlyIGFuZCBsb3cgY2hhciBvZiB0aGUgcGFpcgotICAgICAgICAgICAgIC8vIGlzIG5vdCBnb2luZyB0byBiZSBpbiB0aGUgc2FtZSBjaHVuawotICAgICAgICAgICAgIGZpbmFsIGNoYXIgYyA9IG1faW5wdXRDaGFyc1tsZW5fY2h1bmsgLSAxXTsKLSAgICAgICAgICAgICBpZiAoYyA+PSAweEQ4MDAgJiYgYyA8PSAweERCRkYpIHsKLSAgICAgICAgICAgICAgICAgLy8gRXhjbHVkZSBjaGFyIGluIHRoaXMgY2h1bmssCi0gICAgICAgICAgICAgICAgIC8vIHRvIGF2b2lkIHNwYW5uaW5nIGEgVW5pY29kZSBjaGFyYWN0ZXIKLSAgICAgICAgICAgICAgICAgLy8gdGhhdCBpcyBpbiB0d28gSmF2YSBjaGFycyBhcyBhIGhpZ2gvbG93IHN1cnJvZ2F0ZQotICAgICAgICAgICAgICAgICBlbmRfY2h1bmstLTsKLSAgICAgICAgICAgICAgICAgbGVuX2NodW5rLS07Ci0gICAgICAgICAgICAgICAgIGlmIChjaHVuayA9PSBjaHVua3MpIHsKLSAgICAgICAgICAgICAgICAgICAgIC8qIFRPRE86IGVycm9yIG1lc3NhZ2UgbmVlZGVkLgotICAgICAgICAgICAgICAgICAgICAgICogVGhlIFN0cmluZyBpbmNvcnJlY3RseSBlbmRzIGluIGEgaGlnaCBjaGFyCi0gICAgICAgICAgICAgICAgICAgICAgKiBvZiBhIGhpZ2gvbG93IHN1cnJvZ2F0ZSBwYWlyLCBidXQgdGhlcmUgaXMKLSAgICAgICAgICAgICAgICAgICAgICAqIG5vIGNvcnJlc3BvbmRpbmcgbG93IGFzIHRoZSBoaWdoIGlzIHRoZSBsYXN0IGNoYXIKLSAgICAgICAgICAgICAgICAgICAgICAqIFJlY292ZXIgYnkgaWdub3JpbmcgdGhpcyBsYXN0IGNoYXIuCi0gICAgICAgICAgICAgICAgICAgICAgKi8KLSAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgIHRoaXMud3JpdGUobV9pbnB1dENoYXJzLDAsIGxlbl9jaHVuayk7Ci0gICAgICAgICB9Ci0gICAgICAgICByZXR1cm47Ci0gICAgICB9Ci0gICAgfQotCi0KLSAgICBzLmdldENoYXJzKDAsIGxlbmd0aCAsIG1faW5wdXRDaGFycywgMCk7Ci0gICAgZmluYWwgY2hhcltdIGNoYXJzID0gbV9pbnB1dENoYXJzOwotICAgIGZpbmFsIGludCBuID0gbGVuZ3RoOwotICAgIGZpbmFsIGJ5dGVbXSBidWZfbG9jID0gbV9vdXRwdXRCeXRlczsgLy8gbG9jYWwgcmVmZXJlbmNlIGZvciBmYXN0ZXIgYWNjZXNzCi0gICAgaW50IGNvdW50X2xvYyA9IGNvdW50OyAgICAgIC8vIGxvY2FsIGludGVnZXIgZm9yIGZhc3RlciBhY2Nlc3MKLSAgICBpbnQgaSA9IDA7Ci0gICAgewotICAgICAgICAvKiBUaGlzIGJsb2NrIGNvdWxkIGJlIG9taXR0ZWQgYW5kIHRoZSBjb2RlIHdvdWxkIHByb2R1Y2UKLSAgICAgICAgICogdGhlIHNhbWUgcmVzdWx0LiBCdXQgdGhpcyBibG9jayBleGlzdHMgdG8gZ2l2ZSB0aGUgSklUCi0gICAgICAgICAqIGEgYmV0dGVyIGNoYW5jZSBvZiBvcHRpbWl6aW5nIGEgdGlnaHQgYW5kIGNvbW1vbiBsb29wIHdoaWNoCi0gICAgICAgICAqIG9jY3VycyB3aGVuIHdyaXRpbmcgb3V0IEFTQ0lJIGNoYXJhY3RlcnMuCi0gICAgICAgICAqLwotICAgICAgICBjaGFyIGM7Ci0gICAgICAgIGZvcig7IGkgPCBuICYmIChjID0gY2hhcnNbaV0pPCAweDgwIDsgaSsrICkKLSAgICAgICAgICAgIGJ1Zl9sb2NbY291bnRfbG9jKytdID0gKGJ5dGUpYzsKLSAgICB9Ci0gICAgZm9yICg7IGkgPCBuOyBpKyspCi0gICAgewotCi0gICAgICBmaW5hbCBjaGFyIGMgPSBjaGFyc1tpXTsKLQotICAgICAgaWYgKGMgPCAweDgwKQotICAgICAgICBidWZfbG9jW2NvdW50X2xvYysrXSA9IChieXRlKSAoYyk7Ci0gICAgICBlbHNlIGlmIChjIDwgMHg4MDApCi0gICAgICB7Ci0gICAgICAgIGJ1Zl9sb2NbY291bnRfbG9jKytdID0gKGJ5dGUpICgweGMwICsgKGMgPj4gNikpOwotICAgICAgICBidWZfbG9jW2NvdW50X2xvYysrXSA9IChieXRlKSAoMHg4MCArIChjICYgMHgzZikpOwotICAgICAgfQotICAgIC8qKgotICAgICAgKiBUaGUgZm9sbG93aW5nIGVsc2UgaWYgY29uZGl0aW9uIGlzIGFkZGVkIHRvIHN1cHBvcnQgWE1MIDEuMSBDaGFyYWN0ZXJzIGZvcgotICAgICAgKiBVVEYtODogICBbMTExMSAwdXV1XSBbMTB1dSB6enp6XSBbMTB5eSB5eXl5XSBbMTB4eCB4eHh4XSoKLSAgICAgICogVW5pY29kZTogWzExMDEgMTB3d10gW3d3enogenp5eV0gKGhpZ2ggc3Vycm9nYXRlKQotICAgICAgKiAgICAgICAgICBbMTEwMSAxMXl5XSBbeXl4eCB4eHh4XSAobG93IHN1cnJvZ2F0ZSkKLSAgICAgICogICAgICAgICAgKiB1dXV1dSA9IHd3d3cgKyAxCi0gICAgICAqLwotICAgIGVsc2UgaWYgKGMgPj0gMHhEODAwICYmIGMgPD0gMHhEQkZGKQotICAgIHsKLSAgICAgICAgY2hhciBoaWdoLCBsb3c7Ci0gICAgICAgIGhpZ2ggPSBjOwotICAgICAgICBpKys7Ci0gICAgICAgIGxvdyA9IGNoYXJzW2ldOwotCi0gICAgICAgIGJ1Zl9sb2NbY291bnRfbG9jKytdID0gKGJ5dGUpICgweEYwIHwgKCgoaGlnaCArIDB4NDApID4+IDgpICYgMHhmMCkpOwotICAgICAgICBidWZfbG9jW2NvdW50X2xvYysrXSA9IChieXRlKSAoMHg4MCB8ICgoKGhpZ2ggKyAweDQwKSA+PiAyKSAmIDB4M2YpKTsKLSAgICAgICAgYnVmX2xvY1tjb3VudF9sb2MrK10gPSAoYnl0ZSkgKDB4ODAgfCAoKGxvdyA+PiA2KSAmIDB4MGYpICsgKChoaWdoIDw8IDQpICYgMHgzMCkpOwotICAgICAgICBidWZfbG9jW2NvdW50X2xvYysrXSA9IChieXRlKSAoMHg4MCB8IChsb3cgJiAweDNmKSk7Ci0gICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBidWZfbG9jW2NvdW50X2xvYysrXSA9IChieXRlKSAoMHhlMCArIChjID4+IDEyKSk7Ci0gICAgICAgIGJ1Zl9sb2NbY291bnRfbG9jKytdID0gKGJ5dGUpICgweDgwICsgKChjID4+IDYpICYgMHgzZikpOwotICAgICAgICBidWZfbG9jW2NvdW50X2xvYysrXSA9IChieXRlKSAoMHg4MCArIChjICYgMHgzZikpOwotICAgICAgfQotICAgIH0KLSAgICAvLyBTdG9yZSB0aGUgbG9jYWwgaW50ZWdlciBiYWNrIGludG8gdGhlIGluc3RhbmNlIHZhcmlhYmxlCi0gICAgY291bnQgPSBjb3VudF9sb2M7Ci0KLSAgfQotCi0gIC8qKgotICAgKiBGbHVzaCB0aGUgaW50ZXJuYWwgYnVmZmVyCi0gICAqCi0gICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGZsdXNoQnVmZmVyKCkgdGhyb3dzIElPRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChjb3VudCA+IDApCi0gICAgewotICAgICAgbV9vcy53cml0ZShtX291dHB1dEJ5dGVzLCAwLCBjb3VudCk7Ci0KLSAgICAgIGNvdW50ID0gMDsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogRmx1c2ggdGhlIHN0cmVhbS4gIElmIHRoZSBzdHJlYW0gaGFzIHNhdmVkIGFueSBjaGFyYWN0ZXJzIGZyb20gdGhlCi0gICAqIHZhcmlvdXMgd3JpdGUoKSBtZXRob2RzIGluIGEgYnVmZmVyLCB3cml0ZSB0aGVtIGltbWVkaWF0ZWx5IHRvIHRoZWlyCi0gICAqIGludGVuZGVkIGRlc3RpbmF0aW9uLiAgVGhlbiwgaWYgdGhhdCBkZXN0aW5hdGlvbiBpcyBhbm90aGVyIGNoYXJhY3RlciBvcgotICAgKiBieXRlIHN0cmVhbSwgZmx1c2ggaXQuICBUaHVzIG9uZSBmbHVzaCgpIGludm9jYXRpb24gd2lsbCBmbHVzaCBhbGwgdGhlCi0gICAqIGJ1ZmZlcnMgaW4gYSBjaGFpbiBvZiBXcml0ZXJzIGFuZCBPdXRwdXRTdHJlYW1zLgotICAgKgotICAgKiBAZXhjZXB0aW9uICBJT0V4Y2VwdGlvbiAgSWYgYW4gSS9PIGVycm9yIG9jY3VycwotICAgKgotICAgKiBAdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGZsdXNoKCkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24KLSAgewotICAgIGZsdXNoQnVmZmVyKCk7Ci0gICAgbV9vcy5mbHVzaCgpOwotICB9Ci0KLSAgLyoqCi0gICAqIENsb3NlIHRoZSBzdHJlYW0sIGZsdXNoaW5nIGl0IGZpcnN0LiAgT25jZSBhIHN0cmVhbSBoYXMgYmVlbiBjbG9zZWQsCi0gICAqIGZ1cnRoZXIgd3JpdGUoKSBvciBmbHVzaCgpIGludm9jYXRpb25zIHdpbGwgY2F1c2UgYW4gSU9FeGNlcHRpb24gdG8gYmUKLSAgICogdGhyb3duLiAgQ2xvc2luZyBhIHByZXZpb3VzbHktY2xvc2VkIHN0cmVhbSwgaG93ZXZlciwgaGFzIG5vIGVmZmVjdC4KLSAgICoKLSAgICogQGV4Y2VwdGlvbiAgSU9FeGNlcHRpb24gIElmIGFuIEkvTyBlcnJvciBvY2N1cnMKLSAgICoKLSAgICogQHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uCi0gIHsKLSAgICBmbHVzaEJ1ZmZlcigpOwotICAgIG1fb3MuY2xvc2UoKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIG91dHB1dCBzdHJlYW0gd2hlcmUgdGhlIGV2ZW50cyB3aWxsIGJlIHNlcmlhbGl6ZWQgdG8uCi0gICAqCi0gICAqIEByZXR1cm4gcmVmZXJlbmNlIHRvIHRoZSByZXN1bHQgc3RyZWFtLCBvciBudWxsIG9mIG9ubHkgYSB3cml0ZXIgd2FzCi0gICAqIHNldC4KLSAgICovCi0gIHB1YmxpYyBPdXRwdXRTdHJlYW0gZ2V0T3V0cHV0U3RyZWFtKCkKLSAgewotICAgIHJldHVybiBtX29zOwotICB9Ci0KLSAgcHVibGljIFdyaXRlciBnZXRXcml0ZXIoKQotICB7Ci0gICAgLy8gT25seSBvbmUgb2YgZ2V0V3JpdGVyKCkgb3IgZ2V0T3V0cHV0U3RyZWFtKCkgY2FuIHJldHVybiBudWxsCi0gICAgLy8gVGhpcyB0eXBlIG9mIHdyaXRlciB3cmFwcyBhbiBPdXRwdXRTdHJlYW0sIG5vdCBhIFdyaXRlci4KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9YTUxFbnRpdGllcy5wcm9wZXJ0aWVzIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9YTUxFbnRpdGllcy5wcm9wZXJ0aWVzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1NDcxZGU0Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvWE1MRW50aXRpZXMucHJvcGVydGllcworKysgL2Rldi9udWxsCkBAIC0xLDMyICswLDAgQEAKLSMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwotIyByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0jIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKLSMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwotIyBDb3B5cmlnaHQgMjAwMy0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSMKLSMgTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0jIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSMgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0jCi0jICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSMKLSMgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotIyBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotIyBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSMgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotIyBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCi0jCi0jICRJZDogWE1MRW50aXRpZXMucHJvcGVydGllcyx2IDEuMi40LjEgMjAwNS8wOS8xNSAwODoxNTozMiBzdXJlc2hfZW1haWxpZCBFeHAgJAotIwotIyBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzphcmtpbkBpbnRhbGlvLmNvbSI+QXNzYWYgQXJraW48L2E+Ci0jIFRoaXMgZmlsZSBtdXN0IGJlIGVuY29kZWQgaW4gVVRGLTg7IHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXIuQ2hhckluZm8KLSMKLSMgQ2hhcmFjdGVyIGVudGl0eSByZWZlcmVuY2VzIGZvciBtYXJrdXAtc2lnbmlmaWNhbnQKLSMKLXF1b3Q9MzQKLWFtcD0zOAotbHQ9NjAKLWd0PTYyCi0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvWFNMT3V0cHV0QXR0cmlidXRlcy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9YU0xPdXRwdXRBdHRyaWJ1dGVzLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDRmYjliNGIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9YU0xPdXRwdXRBdHRyaWJ1dGVzLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxODQgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMy0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogWFNMT3V0cHV0QXR0cmlidXRlcy5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE1IDA4OjE1OjMyIHN1cmVzaF9lbWFpbGlkIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotLyoqCi0gKiBUaGlzIGludGVyZmFjZSBoYXMgbWV0aG9kcyBhc3NvY2lhdGVkIHdpdGggdGhlIFhTTFQgeHNsOm91dHB1dCBhdHRyaWJ1ZXMKLSAqIHNwZWNpZmllZCBpbiB0aGUgc3R5bGVzaGVldCB0aGF0IGVmZmVjdCB0aGUgZm9ybWF0IG9mIHRoZSBkb2N1bWVudCBvdXRwdXQuCi0gKgotICogSW4gYW4gWFNMVCBzdHlsZXNoZWV0IHRoZXNlIGF0dHJpYnV0ZXMgYXBwZWFyIGZvciBleGFtcGxlIGFzOgotICogPHByZT4KLSAqIDx4c2w6b3V0cHV0IG1ldGhvZD0ieG1sIiBvbWl0LXhtbC1kZWNsYXJhdGlvbj0ibm8iIGluZGVudD0ieWVzIi8+Ci0gKiA8L3ByZT4KLSAqIFRoZSB4c2w6b3V0cHV0IGF0dHJpYnV0ZXMgY292ZXJlZCBpbiB0aGlzIGludGVyZmFjZSBhcmU6Ci0gKiA8cHJlPgotICogdmVyc2lvbgotICogZW5jb2RpbmcKLSAqIG9taXQteG1sLWRlY2xhcmF0aW9ucwotICogc3RhbmRhbG9uZQotICogZG9jdHlwZS1wdWJsaWMKLSAqIGRvY3R5cGUtc3lzdGVtCi0gKiBjZGF0YS1zZWN0aW9uLWVsZW1lbnRzCi0gKiBpbmRlbnQKLSAqIG1lZGlhLXR5cGUKLSAqIDwvcHJlPgotICoKLSAqIFRoZSBvbmUgYXR0cmlidXRlIG5vdCBjb3ZlcmVkIGluIHRoaXMgaW50ZXJmYWNlIGlzIDxjb2RlPm1ldGhvZDwvY29kZT4gYXMKLSAqIHRoaXMgdmFsdWUgaXMgaW1wbGljaXRseSBjaG9zZW4gYnkgdGhlIHNlcmlhbGl6ZXIgdGhhdCBpcyBjcmVhdGVkLCBmb3IKLSAqIGV4YW1wbGUgVG9YTUxTdHJlYW0gdnMuIFRvSFRNTFN0cmVhbSBvciBhbm90aGVyIG9uZS4KLSAqCi0gKiBUaGlzIGludGVyZmFjZSBpcyBvbmx5IHVzZWQgaW50ZXJuYWxseSB3aXRoaW4gWGFsYW4uCi0gKgotICogQHhzbC51c2FnZSBpbnRlcm5hbAotICovCi1pbnRlcmZhY2UgWFNMT3V0cHV0QXR0cmlidXRlcwotewotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIHByZXZpb3VzbHkgc2V0IHZhbHVlIG9mIHRoZSB2YWx1ZSB0byBiZSB1c2VkIGFzIHRoZSBwdWJsaWMKLSAgICAgKiBpZGVudGlmaWVyIGluIHRoZSBkb2N1bWVudCB0eXBlIGRlY2xhcmF0aW9uIChEVEQpLgotICAgICAqCi0gICAgICpAcmV0dXJuIHRoZSBwdWJsaWMgaWRlbnRpZmllciB0byBiZSB1c2VkIGluIHRoZSBET0NUWVBFIGRlY2xhcmF0aW9uIGluIHRoZQotICAgICAqIG91dHB1dCBkb2N1bWVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldERvY3R5cGVQdWJsaWMoKTsKLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBwcmV2aW91c2x5IHNldCB2YWx1ZSBvZiB0aGUgdmFsdWUgdG8gYmUgdXNlZAotICAgICAqIGFzIHRoZSBzeXN0ZW0gaWRlbnRpZmllciBpbiB0aGUgZG9jdW1lbnQgdHlwZSBkZWNsYXJhdGlvbiAoRFREKS4KLSAgICAgKiBAcmV0dXJuIHRoZSBzeXN0ZW0gaWRlbnRpZmllciB0byBiZSB1c2VkIGluIHRoZSBET0NUWVBFIGRlY2xhcmF0aW9uIGluCi0gICAgICogdGhlIG91dHB1dCBkb2N1bWVudC4KLSAgICAgKgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0RG9jdHlwZVN5c3RlbSgpOwotICAgIC8qKgotICAgICAqIEByZXR1cm4gdGhlIGNoYXJhY3RlciBlbmNvZGluZyB0byBiZSB1c2VkIGluIHRoZSBvdXRwdXQgZG9jdW1lbnQuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRFbmNvZGluZygpOwotICAgIC8qKgotICAgICAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIG91dHB1dCBkb2N1bWVudCBzaG91bGQgYmUgaW5kZW50ZWQgdG8gdmlzdWFsbHkKLSAgICAgICAgICogaW5kaWNhdGUgaXRzIHN0cnVjdHVyZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXRJbmRlbnQoKTsKLQotICAgIC8qKgotICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBzcGFjZXMgdG8gaW5kZW50IGZvciBlYWNoIGluZGVudGF0aW9uIGxldmVsLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0SW5kZW50QW1vdW50KCk7Ci0gICAgLyoqCi0gICAgICogQHJldHVybiB0aGUgbWVkaWF0eXBlIHRoZSBtZWRpYS10eXBlIG9yIE1JTUUgdHlwZSBhc3NvY2lhdGVkIHdpdGggdGhlCi0gICAgICogb3V0cHV0IGRvY3VtZW50LgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TWVkaWFUeXBlKCk7Ci0gICAgLyoqCi0gICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBYTUwgZGVjbGFyYXRpb24gaXMgdG8gYmUgb21pdHRlZCBmcm9tIHRoZSBvdXRwdXQKLSAgICAgKiBkb2N1bWVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXRPbWl0WE1MRGVjbGFyYXRpb24oKTsKLSAgICAvKioKLSAgICAgICogQHJldHVybiBhIHZhbHVlIG9mICJ5ZXMiIGlmIHRoZSA8Y29kZT5zdGFuZGFsb25lPC9jb2RlPiBkZWxhcmF0aW9uIGlzIHRvCi0gICAgICAqIGJlIGluY2x1ZGVkIGluIHRoZSBvdXRwdXQgZG9jdW1lbnQuCi0gICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3RhbmRhbG9uZSgpOwotICAgIC8qKgotICAgICAqIEByZXR1cm4gdGhlIHZlcnNpb24gb2YgdGhlIG91dHB1dCBmb3JtYXQuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRWZXJzaW9uKCk7Ci0KLQotCi0KLQotCi0gICAgLyoqCi0gICAgICogU2V0cyB0aGUgdmFsdWUgY29taW5nIGZyb20gdGhlIHhzbDpvdXRwdXQgY2RhdGEtc2VjdGlvbi1lbGVtZW50cwotICAgICAqIHN0eWxlc2hlZXQgcHJvcGVydHkuCi0gICAgICoKLSAgICAgKiBUaGlzIHNldHMgdGhlIGVsZW1lbnRzIHdob3NlIHRleHQgZWxlbWVudHMgYXJlIHRvIGJlIG91dHB1dCBhcyBDREFUQQotICAgICAqIHNlY3Rpb25zLgotICAgICAqIEBwYXJhbSBVUklfYW5kX2xvY2FsTmFtZXMgcGFpcnMgb2YgbmFtZXNwYWNlIFVSSSBhbmQgbG9jYWwgbmFtZXMgdGhhdAotICAgICAqIGlkZW50aWZ5IGVsZW1lbnRzIHdob3NlIHRleHQgZWxlbWVudHMgYXJlIHRvIGJlIG91dHB1dCBhcyBDREFUQSBzZWN0aW9ucy4KLSAgICAgKiBUaGUgbmFtZXNwYWNlIG9mIHRoZSBsb2NhbCBlbGVtZW50IG11c3QgYmUgdGhlIGdpdmVuIFVSSSB0byBtYXRjaC4gVGhlCi0gICAgICogcU5hbWUgaXMgbm90IGdpdmVuIGJlY2F1c2UgdGhlIHByZWZpeCBkb2VzIG5vdCBtYXR0ZXIsIG9ubHkgdGhlIG5hbWVzcGFjZQotICAgICAqIFVSSSB0byB3aGljaCB0aGF0IHByZWZpeCB3b3VsZCBtYXAgbWF0dGVycywgc28gdGhlIHByZWZpeCBpdHNlbGYgaXMgbm90Ci0gICAgICogcmVsZXZhbnQgaW4gc3BlY2lmeWluZyB3aGljaCBlbGVtZW50cyBoYXZlIHRoZWlyIHRleHQgdG8gYmUgb3V0cHV0IGFzCi0gICAgICogQ0RBVEEgc2VjdGlvbnMuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0Q2RhdGFTZWN0aW9uRWxlbWVudHMoVmVjdG9yIFVSSV9hbmRfbG9jYWxOYW1lcyk7Ci0KLSAgICAvKiogU2V0IHRoZSB2YWx1ZSBjb21pbmcgZnJvbSB0aGUgeHNsOm91dHB1dCBkb2N0eXBlLXB1YmxpYyBhbmQgZG9jdHlwZS1zeXN0ZW0gc3R5bGVzaGVldCBwcm9wZXJ0aWVzCi0gICAgICogQHBhcmFtIHN5c3RlbSB0aGUgc3lzdGVtIGlkZW50aWZpZXIgdG8gYmUgdXNlZCBpbiB0aGUgRE9DVFlQRSBkZWNsYXJhdGlvbgotICAgICAqIGluIHRoZSBvdXRwdXQgZG9jdW1lbnQuCi0gICAgICogQHBhcmFtIHB1YiB0aGUgcHVibGljIGlkZW50aWZpZXIgdG8gYmUgdXNlZCBpbiB0aGUgRE9DVFlQRSBkZWNsYXJhdGlvbiBpbgotICAgICAqIHRoZSBvdXRwdXQgZG9jdW1lbnQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RG9jdHlwZShTdHJpbmcgc3lzdGVtLCBTdHJpbmcgcHViKTsKLQotICAgIC8qKiBTZXQgdGhlIHZhbHVlIGNvbWluZyBmcm9tIHRoZSB4c2w6b3V0cHV0IGRvY3R5cGUtcHVibGljIHN0eWxlc2hlZXQgYXR0cmlidXRlLgotICAgICAgKiBAcGFyYW0gZG9jdHlwZSB0aGUgcHVibGljIGlkZW50aWZpZXIgdG8gYmUgdXNlZCBpbiB0aGUgRE9DVFlQRQotICAgICAgKiBkZWNsYXJhdGlvbiBpbiB0aGUgb3V0cHV0IGRvY3VtZW50LgotICAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXREb2N0eXBlUHVibGljKFN0cmluZyBkb2N0eXBlKTsKLSAgICAvKiogU2V0IHRoZSB2YWx1ZSBjb21pbmcgZnJvbSB0aGUgeHNsOm91dHB1dCBkb2N0eXBlLXN5c3RlbSBzdHlsZXNoZWV0IGF0dHJpYnV0ZS4KLSAgICAgICogQHBhcmFtIGRvY3R5cGUgdGhlIHN5c3RlbSBpZGVudGlmaWVyIHRvIGJlIHVzZWQgaW4gdGhlIERPQ1RZUEUKLSAgICAgICogZGVjbGFyYXRpb24gaW4gdGhlIG91dHB1dCBkb2N1bWVudC4KLSAgICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RG9jdHlwZVN5c3RlbShTdHJpbmcgZG9jdHlwZSk7Ci0gICAgLyoqCi0gICAgICogU2V0cyB0aGUgY2hhcmFjdGVyIGVuY29kaW5nIGNvbWluZyBmcm9tIHRoZSB4c2w6b3V0cHV0IGVuY29kaW5nIHN0eWxlc2hlZXQgYXR0cmlidXRlLgotICAgICAqIEBwYXJhbSBlbmNvZGluZyB0aGUgY2hhcmFjdGVyIGVuY29kaW5nCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RW5jb2RpbmcoU3RyaW5nIGVuY29kaW5nKTsKLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSB2YWx1ZSBjb21pbmcgZnJvbSB0aGUgeHNsOm91dHB1dCBpbmRlbnQgc3R5bGVzaGVldAotICAgICAqIGF0dHJpYnV0ZS4KLSAgICAgKiBAcGFyYW0gaW5kZW50IHRydWUgaWYgdGhlIG91dHB1dCBkb2N1bWVudCBzaG91bGQgYmUgaW5kZW50ZWQgdG8gdmlzdWFsbHkKLSAgICAgKiBpbmRpY2F0ZSBpdHMgc3RydWN0dXJlLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEluZGVudChib29sZWFuIGluZGVudCk7Ci0gICAgLyoqCi0gICAgICogU2V0cyB0aGUgdmFsdWUgY29taW5nIGZyb20gdGhlIHhzbDpvdXRwdXQgbWVkaWEtdHlwZSBzdHlsZXNoZWV0IGF0dHJpYnV0ZS4KLSAgICAgKiBAcGFyYW0gbWVkaWF0eXBlIHRoZSBtZWRpYS10eXBlIG9yIE1JTUUgdHlwZSBhc3NvY2lhdGVkIHdpdGggdGhlIG91dHB1dAotICAgICAqIGRvY3VtZW50LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldE1lZGlhVHlwZShTdHJpbmcgbWVkaWF0eXBlKTsKLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSB2YWx1ZSBjb21pbmcgZnJvbSB0aGUgeHNsOm91dHB1dCBvbWl0LXhtbC1kZWNsYXJhdGlvbiBzdHlsZXNoZWV0IGF0dHJpYnV0ZQotICAgICAqIEBwYXJhbSBiIHRydWUgaWYgdGhlIFhNTCBkZWNsYXJhdGlvbiBpcyB0byBiZSBvbWl0dGVkIGZyb20gdGhlIG91dHB1dAotICAgICAqIGRvY3VtZW50LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldE9taXRYTUxEZWNsYXJhdGlvbihib29sZWFuIGIpOwotICAgIC8qKgotICAgICAqIFNldHMgdGhlIHZhbHVlIGNvbWluZyBmcm9tIHRoZSB4c2w6b3V0cHV0IHN0YW5kYWxvbmUgc3R5bGVzaGVldCBhdHRyaWJ1dGUuCi0gICAgICogQHBhcmFtIHN0YW5kYWxvbmUgYSB2YWx1ZSBvZiAieWVzIiBpbmRpY2F0ZXMgdGhhdCB0aGUKLSAgICAgKiA8Y29kZT5zdGFuZGFsb25lPC9jb2RlPiBkZWxhcmF0aW9uIGlzIHRvIGJlIGluY2x1ZGVkIGluIHRoZSBvdXRwdXQKLSAgICAgKiBkb2N1bWVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRTdGFuZGFsb25lKFN0cmluZyBzdGFuZGFsb25lKTsKLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSB2YWx1ZSBjb21pbmcgZnJvbSB0aGUgeHNsOm91dHB1dCB2ZXJzaW9uIGF0dHJpYnV0ZS4KLSAgICAgKiBAcGFyYW0gdmVyc2lvbiB0aGUgdmVyc2lvbiBvZiB0aGUgb3V0cHV0IGZvcm1hdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRWZXJzaW9uKFN0cmluZyB2ZXJzaW9uKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9vdXRwdXRfaHRtbC5wcm9wZXJ0aWVzIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9vdXRwdXRfaHRtbC5wcm9wZXJ0aWVzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmZjE2YzY1Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvb3V0cHV0X2h0bWwucHJvcGVydGllcworKysgL2Rldi9udWxsCkBAIC0xLDQ2ICswLDAgQEAKLSMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwotIyByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0jIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKLSMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwotIyBDb3B5cmlnaHQgMjAwMy0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSMKLSMgTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0jIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSMgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0jCi0jICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSMKLSMgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotIyBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotIyBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSMgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotIyBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCi0jCi0jICRJZDogb3V0cHV0X2h0bWwucHJvcGVydGllcyx2IDEuMi40LjEgMjAwNS8wOS8xNSAwODoxNTozMiBzdXJlc2hfZW1haWxpZCBFeHAgJAotIwotIyBTcGVjaWZ5IGRlZmF1bHRzIHdoZW4gbWV0aG9kPSJodG1sIi4gIFRoZXNlIGRlZmF1bHRzIHVzZSBvdXRwdXRfeG1sLnByb3BlcnRpZXMgCi0jIGFzIGEgYmFzZS4KLSMKLQotIyBYU0xUIHByb3BlcnRpZXMgZG8gbm90IG5lZWQgbmFtZXNwYWNlIHF1YWxpZmljYXRpb24uCi1tZXRob2Q9aHRtbAotaW5kZW50PXllcwotbWVkaWEtdHlwZT10ZXh0L2h0bWwKLXZlcnNpb249NC4wCi0KLSMgWGFsYW4tc3BlY2lmaWMgb3V0cHV0IHByb3BlcnRpZXMuICBUaGVzZSBjYW4gYmUgb3ZlcnJpZGRlbiBpbiB0aGUgc3R5bGVzaGVldCAKLSMgYXNzaWduaW5nIGEgeGFsYW4gbmFtZXNwYWNlLiAgRm9yIGV4YW1wbGU6Ci0jIDx4c2w6c3R5bGVzaGVldCB2ZXJzaW9uPSIxLjAiCi0jICAgICAgICAgIHhtbG5zOnhzbD0iaHR0cDovL3d3dy53My5vcmcvMTk5OS9YU0wvVHJhbnNmb3JtIgotIyAgICAgICAgICB4bWxuczp4YWxhbj0iaHR0cDovL3htbC5hcGFjaGUub3JnL3hhbGFuIj4KLSMgIDx4c2w6b3V0cHV0IG1ldGhvZD0iaHRtbCIgZW5jb2Rpbmc9IlVURi04IgotIyAgICAgICAgICAgICAgeGFsYW46Y29udGVudC1oYW5kbGVyPSJNeUNvbnRlbnRIYW5kbGVyIi8+Ci0jICAuLi4KLSMgTm90ZSB0aGF0IHRoZSBjb2xvbiBhZnRlciB0aGUgcHJvdG9jb2wgbmVlZHMgdG8gYmUgZXNjYXBlZC4KLXtodHRwXHUwMDNhLy94bWwuYXBhY2hlLm9yZy94YWxhbn1pbmRlbnQtYW1vdW50PTAKLXtodHRwXHUwMDNhLy94bWwuYXBhY2hlLm9yZy94YWxhbn1jb250ZW50LWhhbmRsZXI9Y29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyLlRvSFRNTFN0cmVhbQote2h0dHBcdTAwM2EvL3htbC5hcGFjaGUub3JnL3hhbGFufWVudGl0aWVzPWNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9IVE1MRW50aXRpZXMKLXtodHRwXHUwMDNhLy94bWwuYXBhY2hlLm9yZy94YWxhbn11c2UtdXJsLWVzY2FwaW5nPXllcwote2h0dHBcdTAwM2EvL3htbC5hcGFjaGUub3JnL3hhbGFufW9taXQtbWV0YS10YWc9bm8KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvb3V0cHV0X3RleHQucHJvcGVydGllcyBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvb3V0cHV0X3RleHQucHJvcGVydGllcwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZDNkMmJhZi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL291dHB1dF90ZXh0LnByb3BlcnRpZXMKKysrIC9kZXYvbnVsbApAQCAtMSwzOSArMCwwIEBACi0jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKLSMgcmVzZXJ2ZWQgY29tbWVudCBibG9jawotIyBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCi0jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwotIyBDb3B5cmlnaHQgMjAwMy0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSMKLSMgTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0jIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSMgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0jCi0jICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSMKLSMgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotIyBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotIyBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSMgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotIyBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCi0jCi0jICRJZDogb3V0cHV0X3RleHQucHJvcGVydGllcyx2IDEuMyAyMDA1LzA5LzI4IDEzOjQ5OjEwIHB2ZWR1bGEgRXhwICQKLSMKLSMgU3BlY2lmeSBkZWZhdWx0cyB3aGVuIG1ldGhvZD0idGV4dCIuCi0jCi0KLSMgWFNMVCBwcm9wZXJ0aWVzIGRvIG5vdCBuZWVkIG5hbWVzcGFjZSBxdWFsaWZpY2F0aW9uLgotbWV0aG9kPXRleHQKLW1lZGlhLXR5cGU9dGV4dC9wbGFpbgotCi0jIFhhbGFuLXNwZWNpZmljIG91dHB1dCBwcm9wZXJ0aWVzLiAgVGhlc2UgY2FuIGJlIG92ZXJyaWRkZW4gaW4gdGhlIHN0eWxlc2hlZXQgCi0jIGFzc2lnbmluZyBhIHhhbGFuIG5hbWVzcGFjZS4gIEZvciBleGFtcGxlOgotIyA8eHNsOnN0eWxlc2hlZXQgdmVyc2lvbj0iMS4wIgotIyAgICAgICAgICB4bWxuczp4c2w9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvWFNML1RyYW5zZm9ybSIKLSMgICAgICAgICAgeG1sbnM6eGFsYW49Imh0dHA6Ly94bWwuYXBhY2hlLm9yZy94YWxhbiI+Ci0jICA8eHNsOm91dHB1dCBtZXRob2Q9Imh0bWwiIGVuY29kaW5nPSJVVEYtOCIKLSMgICAgICAgICAgICAgIHhhbGFuOmNvbnRlbnQtaGFuZGxlcj0iTXlDb250ZW50SGFuZGxlciIvPgotIyAgLi4uCi0jIE5vdGUgdGhhdCB0aGUgY29sb24gYWZ0ZXIgdGhlIHByb3RvY29sIG5lZWRzIHRvIGJlIGVzY2FwZWQuCi17aHR0cFx1MDAzYS8veG1sLmFwYWNoZS5vcmcveGFsYW59Y29udGVudC1oYW5kbGVyPWNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplci5Ub1RleHRTdHJlYW0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvb3V0cHV0X3Vua25vd24ucHJvcGVydGllcyBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvb3V0cHV0X3Vua25vd24ucHJvcGVydGllcwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMTE4ZDQ2OS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL291dHB1dF91bmtub3duLnByb3BlcnRpZXMKKysrIC9kZXYvbnVsbApAQCAtMSw0OCArMCwwIEBACi0jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKLSMgcmVzZXJ2ZWQgY29tbWVudCBibG9jawotIyBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCi0jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKLSMgQ29weXJpZ2h0IDIwMDMtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0jCi0jIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotIyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0jIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotIwotIyAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0jCi0jIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSMgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0jIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSMgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwotIwotIyAkSWQ6IG91dHB1dF91bmtub3duLnByb3BlcnRpZXMsdiAxLjIuNC4xIDIwMDUvMDkvMTUgMDg6MTU6MzMgc3VyZXNoX2VtYWlsaWQgRXhwICQKLSMKLSMgU3BlY2lmeSBkZWZhdWx0cyB3aGVuIG5vIG1ldGhvZD0iLi4uIiBpcyBzcGVjaWZpZWQuCi0jIFRoaXMgdHlwZSBvZiBvdXRwdXQgd2lsbCBxdWlja2x5IHN3aXRjaCB0byAieG1sIiBvciAiaHRtbCIKLSMgZGVwZW5kaW5nIG9uIHRoZSBmaXJzdCBlbGVtZW50IG5hbWUuCi0jCi0KLSMgWFNMVCBwcm9wZXJ0aWVzIGRvIG5vdCBuZWVkIG5hbWVzcGFjZSBxdWFsaWZpY2F0aW9uLgotbWV0aG9kPXhtbAotdmVyc2lvbj0xLjAKLWVuY29kaW5nPVVURi04Ci1pbmRlbnQ9bm8KLW9taXQteG1sLWRlY2xhcmF0aW9uPW5vCi1zdGFuZGFsb25lPW5vCi1tZWRpYS10eXBlPXRleHQveG1sCi0KLSMgWGFsYW4tc3BlY2lmaWMgb3V0cHV0IHByb3BlcnRpZXMuICBUaGVzZSBjYW4gYmUgb3ZlcnJpZGRlbiBpbiB0aGUgc3R5bGVzaGVldCAKLSMgYXNzaWduaW5nIGEgeGFsYW4gbmFtZXNwYWNlLiAgRm9yIGV4YW1wbGU6Ci0jIDx4c2w6c3R5bGVzaGVldCB2ZXJzaW9uPSIxLjAiCi0jICAgICAgICAgIHhtbG5zOnhzbD0iaHR0cDovL3d3dy53My5vcmcvMTk5OS9YU0wvVHJhbnNmb3JtIgotIyAgICAgICAgICB4bWxuczp4YWxhbj0iaHR0cDovL3htbC5hcGFjaGUub3JnL3hhbGFuIj4KLSMgIDx4c2w6b3V0cHV0IG1ldGhvZD0iaHRtbCIgZW5jb2Rpbmc9IlVURi04IgotIyAgICAgICAgICAgICAgeGFsYW46Y29udGVudC1oYW5kbGVyPSJNeUNvbnRlbnRIYW5kbGVyIi8+Ci0jICAuLi4KLSMgTm90ZSB0aGF0IHRoZSBjb2xvbiBhZnRlciB0aGUgcHJvdG9jb2wgbmVlZHMgdG8gYmUgZXNjYXBlZC4KLXtodHRwXHUwMDNhLy94bWwuYXBhY2hlLm9yZy94YWxhbn1pbmRlbnQtYW1vdW50PTAKLXtodHRwXHUwMDNhLy94bWwuYXBhY2hlLm9yZy94YWxhbn1jb250ZW50LWhhbmRsZXI9Y29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyLlRvVW5rbm93blN0cmVhbQotCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL291dHB1dF94bWwucHJvcGVydGllcyBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvb3V0cHV0X3htbC5wcm9wZXJ0aWVzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmZDAxNmY3Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvb3V0cHV0X3htbC5wcm9wZXJ0aWVzCisrKyAvZGV2L251bGwKQEAgLTEsNDggKzAsMCBAQAotIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCi0jIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSMgRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwotIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCi0jIENvcHlyaWdodCAyMDAzLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotIwotIyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSMgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotIyBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSMKLSMgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotIwotIyBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0jIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0jIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotIyBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0jIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKLSMKLSMgJElkOiBvdXRwdXRfeG1sLnByb3BlcnRpZXMsdiAxLjIuNC4xIDIwMDUvMDkvMTUgMDg6MTU6MzMgc3VyZXNoX2VtYWlsaWQgRXhwICQKLSMKLSMgU3BlY2lmeSBkZWZhdWx0cyB3aGVuIG1ldGhvZD0ieG1sIi4gIFRoZXNlIGRlZmF1bHRzIHNlcnZlIGFzIGEgYmFzZSBmb3IgCi0jIG90aGVyIGRlZmF1bHRzLCBzdWNoIGFzIG91dHB1dF9odG1sIGFuZCBvdXRwdXRfdGV4dC4KLSMKLQotIyBYU0xUIHByb3BlcnRpZXMgZG8gbm90IG5lZWQgbmFtZXNwYWNlIHF1YWxpZmljYXRpb24uCi1tZXRob2Q9eG1sCi12ZXJzaW9uPTEuMAotZW5jb2Rpbmc9VVRGLTgKLWluZGVudD1ubwotb21pdC14bWwtZGVjbGFyYXRpb249bm8KLXN0YW5kYWxvbmU9bm8KLW1lZGlhLXR5cGU9dGV4dC94bWwKLQotIyBYYWxhbi1zcGVjaWZpYyBvdXRwdXQgcHJvcGVydGllcy4gIFRoZXNlIGNhbiBiZSBvdmVycmlkZGVuIGluIHRoZSBzdHlsZXNoZWV0IAotIyBhc3NpZ25pbmcgYSB4YWxhbiBuYW1lc3BhY2UuICBGb3IgZXhhbXBsZToKLSMgPHhzbDpzdHlsZXNoZWV0IHZlcnNpb249IjEuMCIKLSMgICAgICAgICAgeG1sbnM6eHNsPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L1hTTC9UcmFuc2Zvcm0iCi0jICAgICAgICAgIHhtbG5zOnhhbGFuPSJodHRwOi8veG1sLmFwYWNoZS5vcmcveGFsYW4iPgotIyAgPHhzbDpvdXRwdXQgbWV0aG9kPSJodG1sIiBlbmNvZGluZz0iVVRGLTgiCi0jICAgICAgICAgICAgICB4YWxhbjpjb250ZW50LWhhbmRsZXI9Ik15Q29udGVudEhhbmRsZXIiLz4KLSMgIC4uLgotIyBOb3RlIHRoYXQgdGhlIGNvbG9uIGFmdGVyIHRoZSBwcm90b2NvbCBuZWVkcyB0byBiZSBlc2NhcGVkLgote2h0dHBcdTAwM2EvL3htbC5hcGFjaGUub3JnL3hhbGFufWluZGVudC1hbW91bnQ9MAote2h0dHBcdTAwM2EvL3htbC5hcGFjaGUub3JnL3hhbGFufWNvbnRlbnQtaGFuZGxlcj1jb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXIuVG9YTUxTdHJlYW0KLXtodHRwXHUwMDNhLy94bWwuYXBhY2hlLm9yZy94YWxhbn1lbnRpdGllcz1jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvWE1MRW50aXRpZXMKLQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9wYWNrYWdlLmh0bWwgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL3BhY2thZ2UuaHRtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZWQ4NGZlOC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL3BhY2thZ2UuaHRtbAorKysgL2Rldi9udWxsCkBAIC0xLDQ1ICswLDAgQEAKLTwhLS0KLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0tLT4KLTwhLS0KLSAqIENvcHlyaWdodCAyMDAzLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotLS0+Ci08IS0tICRJZDogcGFja2FnZS5odG1sLHYgMS4yLjQuMSAyMDA1LzA5LzE1IDA4OjE1OjM0IHN1cmVzaF9lbWFpbGlkIEV4cCAkIC0tPgotPGh0bWw+Ci0gIDx0aXRsZT5YYWxhbiBTZXJpYWxpemVyIFBhY2thZ2UuPC90aXRsZT4KLSAgPGJvZHk+Ci0gICAgPHA+UHJvY2Vzc2VzIFNBWCBldmVudHMgaW50byBzdHJlYW1zLjwvcD4KLSAgICAKLSAgICA8cD5UaGUge0BsaW5rIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplci5TZXJpYWxpemVyRmFjdG9yeX0gaXMgdXNlZCB0byAKLSAgICBjcmVhdGUgYSB7QGxpbmsgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyLlNlcmlhbGl6ZXJ9IGZyb20gYSBzZXQgb2YgCi0gICAgb3V0cHV0IHByb3BlcnRpZXMgKHNlZSB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5PdXRwdXRLZXlzfSkuPC9wPgotICAgIDxwPntAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXIuVG9TdHJlYW19IGFjdHMgYXMgdGhlIG1haW4gCi0gICAgYmFzZWNsYXNzIGZvciB0aGUgWGFsYW4gc2VyaWFsaXplciBpbXBsZW1lbnRhdGlvbnMuICAKLSAgICB7QGxpbmsgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyLlRvSFRNTFN0cmVhbX0gZGVyaXZlcyBmcm9tIHRoaXMgCi0gICAgdG8gaW1wbGVtZW50IEhUTUwgc2VyaWFsaXphdGlvbi4gIAotICAgIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXIuVG9UZXh0U3RyZWFtfQotICAgIGltcGxlbWVudHMgcGxhaW4gdGV4dCBzZXJpYWxpemF0aW9uLgotICAgIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXIuVG9YTUxTdHJlYW19Ci0gICAgaW1wbGVtZW50cyBYTUwgc2VyaWFsaXphdGlvbi4KLSAgICA8L3A+Ci0gICAgPHA+WE1MIG1hcHBpbmcgZnJvbSBjaGFyYWN0ZXJzIHRvIGVudGl0eSByZWZlcmVuY2VzIGlzIGRlZmluZWQgaW4gCi0gICAgWE1MRW50aXRpZXMucmVzLiAgSFRNTCBlbnRpdHkgcmVmZXJlbmNlIG1hcHBpbmcgaXMgZGVmaW5lZCBpbiBIVE1MRW50aXRpZXMucmVzLgotICAgIDwvcD4KLSAgICA8cD5FbmNvZGluZyBpbmZvcm1hdGlvbiBpcyBkZWZpbmVkIGluIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXIuRW5jb2RpbmdzfS48L3A+Ci0gPC9ib2R5PgotPC9odG1sPgotCi0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvdXRpbHMvQXR0TGlzdC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci91dGlscy9BdHRMaXN0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDk0YjQ0MjIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci91dGlscy9BdHRMaXN0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyNjUgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogQXR0TGlzdC5qYXZhLHYgMS4xLjQuMSAyMDA1LzA5LzA4IDExOjAzOjA4IHN1cmVzaF9lbWFpbGlkIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyLnV0aWxzOwotCi1pbXBvcnQgb3JnLnczYy5kb20uQXR0cjsKLWltcG9ydCBvcmcudzNjLmRvbS5OYW1lZE5vZGVNYXA7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLQotaW1wb3J0IG9yZy54bWwuc2F4LkF0dHJpYnV0ZXM7Ci0KLS8qKgotICogV3JhcHMgYSBET00gYXR0cmlidXRlIGxpc3QgaW4gYSBTQVggQXR0cmlidXRlcy4KLSAqCi0gKiBUaGlzIGNsYXNzIGlzIGEgY29weSBvZiB0aGUgb25lIGluIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuCi0gKiBJdCBleGlzdHMgdG8gY3V0IHRoZSBzZXJpYWxpemVycyBkZXBlbmRhbmN5IG9uIHRoYXQgcGFja2FnZS4KLSAqIEEgbWlub3IgY2hhbmdlcyBmcm9tIHRoYXQgcGFja2FnZSBhcmU6Ci0gKiBET01IZWxwZXIgcmVmZXJlbmNlIGNoYW5nZWQgdG8gRE9NMkhlbHBlciwgY2xhc3MgaXMgbm90ICJwdWJsaWMiCi0gKgotICogVGhpcyBjbGFzcyBpcyBub3QgYSBwdWJsaWMgQVBJLCBpdCBpcyBvbmx5IHB1YmxpYyBiZWNhdXNlIGl0IGlzCi0gKiB1c2VkIGluIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplci4KLSAqCi0gKiBAeHNsLnVzYWdlIGludGVybmFsCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBBdHRMaXN0IGltcGxlbWVudHMgQXR0cmlidXRlcwotewotCi0gIC8qKiBMaXN0IG9mIGF0dHJpYnV0ZSBub2RlcyAgICAgICAgICAqLwotICBOYW1lZE5vZGVNYXAgbV9hdHRyczsKLQotICAvKiogSW5kZXggb2YgbGFzdCBhdHRyaWJ1dGUgbm9kZSAgICAgICAgICAqLwotICBpbnQgbV9sYXN0SW5kZXg7Ci0KLSAgLy8gQVJHSEghISAgSkFYUCBVc2VzIFhlcmNlcyB3aXRob3V0IHNldHRpbmcgdGhlIG5hbWVzcGFjZSBwcm9jZXNzaW5nIHRvIE9OIQotICAvLyBET00ySGVscGVyIG1fZGggPSBuZXcgRE9NMkhlbHBlcigpOwotCi0gIC8qKiBMb2NhbCByZWZlcmVuY2UgdG8gRE9NSGVscGVyICAgICAgICAgICovCi0gIERPTTJIZWxwZXIgbV9kaDsKLQotLy8gIC8qKgotLy8gICAqIENvbnN0cnVjdG9yIEF0dExpc3QKLS8vICAgKgotLy8gICAqCi0vLyAgICogQHBhcmFtIGF0dHJzIExpc3Qgb2YgYXR0cmlidXRlcyB0aGlzIHdpbGwgY29udGFpbgotLy8gICAqLwotLy8gIHB1YmxpYyBBdHRMaXN0KE5hbWVkTm9kZU1hcCBhdHRycykKLS8vICB7Ci0vLwotLy8gICAgbV9hdHRycyA9IGF0dHJzOwotLy8gICAgbV9sYXN0SW5kZXggPSBtX2F0dHJzLmdldExlbmd0aCgpIC0gMTsKLS8vICAgIG1fZGggPSBuZXcgRE9NMkhlbHBlcigpOwotLy8gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0b3IgQXR0TGlzdAotICAgKgotICAgKgotICAgKiBAcGFyYW0gYXR0cnMgTGlzdCBvZiBhdHRyaWJ1dGVzIHRoaXMgd2lsbCBjb250YWluCi0gICAqIEBwYXJhbSBkaCBET01IZWxwZXIKLSAgICovCi0gIHB1YmxpYyBBdHRMaXN0KE5hbWVkTm9kZU1hcCBhdHRycywgRE9NMkhlbHBlciBkaCkKLSAgewotCi0gICAgbV9hdHRycyA9IGF0dHJzOwotICAgIG1fbGFzdEluZGV4ID0gbV9hdHRycy5nZXRMZW5ndGgoKSAtIDE7Ci0gICAgbV9kaCA9IGRoOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbnVtYmVyIG9mIGF0dHJpYnV0ZSBub2RlcyBpbiB0aGUgbGlzdAotICAgKgotICAgKgotICAgKiBAcmV0dXJuIG51bWJlciBvZiBhdHRyaWJ1dGUgbm9kZXMKLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0TGVuZ3RoKCkKLSAgewotICAgIHJldHVybiBtX2F0dHJzLmdldExlbmd0aCgpOwotICB9Ci0KLSAgLyoqCi0gICAqIExvb2sgdXAgYW4gYXR0cmlidXRlJ3MgTmFtZXNwYWNlIFVSSSBieSBpbmRleC4KLSAgICoKLSAgICogQHBhcmFtIGluZGV4IFRoZSBhdHRyaWJ1dGUgaW5kZXggKHplcm8tYmFzZWQpLgotICAgKiBAcmV0dXJuIFRoZSBOYW1lc3BhY2UgVVJJLCBvciB0aGUgZW1wdHkgc3RyaW5nIGlmIG5vbmUKLSAgICogICAgICAgICBpcyBhdmFpbGFibGUsIG9yIG51bGwgaWYgdGhlIGluZGV4IGlzIG91dCBvZgotICAgKiAgICAgICAgIHJhbmdlLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRVUkkoaW50IGluZGV4KQotICB7Ci0gICAgU3RyaW5nIG5zID0gbV9kaC5nZXROYW1lc3BhY2VPZk5vZGUoKChBdHRyKSBtX2F0dHJzLml0ZW0oaW5kZXgpKSk7Ci0gICAgaWYobnVsbCA9PSBucykKLSAgICAgIG5zID0gIiI7Ci0gICAgcmV0dXJuIG5zOwotICB9Ci0KLSAgLyoqCi0gICAqIExvb2sgdXAgYW4gYXR0cmlidXRlJ3MgbG9jYWwgbmFtZSBieSBpbmRleC4KLSAgICoKLSAgICogQHBhcmFtIGluZGV4IFRoZSBhdHRyaWJ1dGUgaW5kZXggKHplcm8tYmFzZWQpLgotICAgKiBAcmV0dXJuIFRoZSBsb2NhbCBuYW1lLCBvciB0aGUgZW1wdHkgc3RyaW5nIGlmIE5hbWVzcGFjZQotICAgKiAgICAgICAgIHByb2Nlc3NpbmcgaXMgbm90IGJlaW5nIHBlcmZvcm1lZCwgb3IgbnVsbAotICAgKiAgICAgICAgIGlmIHRoZSBpbmRleCBpcyBvdXQgb2YgcmFuZ2UuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldExvY2FsTmFtZShpbnQgaW5kZXgpCi0gIHsKLSAgICByZXR1cm4gbV9kaC5nZXRMb2NhbE5hbWVPZk5vZGUoKChBdHRyKSBtX2F0dHJzLml0ZW0oaW5kZXgpKSk7Ci0gIH0KLQotICAvKioKLSAgICogTG9vayB1cCBhbiBhdHRyaWJ1dGUncyBxdWFsaWZpZWQgbmFtZSBieSBpbmRleC4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIGkgVGhlIGF0dHJpYnV0ZSBpbmRleCAoemVyby1iYXNlZCkuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGF0dHJpYnV0ZSdzIHF1YWxpZmllZCBuYW1lCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFFOYW1lKGludCBpKQotICB7Ci0gICAgcmV0dXJuICgoQXR0cikgbV9hdHRycy5pdGVtKGkpKS5nZXROYW1lKCk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBhdHRyaWJ1dGUncyBub2RlIHR5cGUgYnkgaW5kZXgKLSAgICoKLSAgICoKLSAgICogQHBhcmFtIGkgVGhlIGF0dHJpYnV0ZSBpbmRleCAoemVyby1iYXNlZCkKLSAgICoKLSAgICogQHJldHVybiB0aGUgYXR0cmlidXRlJ3Mgbm9kZSB0eXBlCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFR5cGUoaW50IGkpCi0gIHsKLSAgICByZXR1cm4gIkNEQVRBIjsgIC8vIGZvciB0aGUgbW9tZW50Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBhdHRyaWJ1dGUncyBub2RlIHZhbHVlIGJ5IGluZGV4Ci0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBpIFRoZSBhdHRyaWJ1dGUgaW5kZXggKHplcm8tYmFzZWQpCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIGF0dHJpYnV0ZSdzIG5vZGUgdmFsdWUKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0VmFsdWUoaW50IGkpCi0gIHsKLSAgICByZXR1cm4gKChBdHRyKSBtX2F0dHJzLml0ZW0oaSkpLmdldFZhbHVlKCk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBhdHRyaWJ1dGUncyBub2RlIHR5cGUgYnkgbmFtZQotICAgKgotICAgKgotICAgKiBAcGFyYW0gbmFtZSBBdHRyaWJ1dGUgbmFtZQotICAgKgotICAgKiBAcmV0dXJuIHRoZSBhdHRyaWJ1dGUncyBub2RlIHR5cGUKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0VHlwZShTdHJpbmcgbmFtZSkKLSAgewotICAgIHJldHVybiAiQ0RBVEEiOyAgLy8gZm9yIHRoZSBtb21lbnQKLSAgfQotCi0gIC8qKgotICAgKiBMb29rIHVwIGFuIGF0dHJpYnV0ZSdzIHR5cGUgYnkgTmFtZXNwYWNlIG5hbWUuCi0gICAqCi0gICAqIEBwYXJhbSB1cmkgVGhlIE5hbWVzcGFjZSBVUkksIG9yIHRoZSBlbXB0eSBTdHJpbmcgaWYgdGhlCi0gICAqICAgICAgICBuYW1lIGhhcyBubyBOYW1lc3BhY2UgVVJJLgotICAgKiBAcGFyYW0gbG9jYWxOYW1lIFRoZSBsb2NhbCBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUuCi0gICAqIEByZXR1cm4gVGhlIGF0dHJpYnV0ZSB0eXBlIGFzIGEgc3RyaW5nLCBvciBudWxsIGlmIHRoZQotICAgKiAgICAgICAgIGF0dHJpYnV0ZSBpcyBub3QgaW4gdGhlIGxpc3Qgb3IgaWYgTmFtZXNwYWNlCi0gICAqICAgICAgICAgcHJvY2Vzc2luZyBpcyBub3QgYmVpbmcgcGVyZm9ybWVkLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRUeXBlKFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUpCi0gIHsKLSAgICByZXR1cm4gIkNEQVRBIjsgIC8vIGZvciB0aGUgbW9tZW50Ci0gIH0KLQotICAvKioKLSAgICogTG9vayB1cCBhbiBhdHRyaWJ1dGUncyB2YWx1ZSBieSBuYW1lLgotICAgKgotICAgKgotICAgKiBAcGFyYW0gbmFtZSBUaGUgYXR0cmlidXRlIG5vZGUncyBuYW1lCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGF0dHJpYnV0ZSBub2RlJ3MgdmFsdWUKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0VmFsdWUoU3RyaW5nIG5hbWUpCi0gIHsKLSAgICBBdHRyIGF0dHIgPSAoKEF0dHIpIG1fYXR0cnMuZ2V0TmFtZWRJdGVtKG5hbWUpKTsKLSAgICByZXR1cm4gKG51bGwgIT0gYXR0cikKLSAgICAgICAgICA/IGF0dHIuZ2V0VmFsdWUoKSA6IG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogTG9vayB1cCBhbiBhdHRyaWJ1dGUncyB2YWx1ZSBieSBOYW1lc3BhY2UgbmFtZS4KLSAgICoKLSAgICogQHBhcmFtIHVyaSBUaGUgTmFtZXNwYWNlIFVSSSwgb3IgdGhlIGVtcHR5IFN0cmluZyBpZiB0aGUKLSAgICogICAgICAgIG5hbWUgaGFzIG5vIE5hbWVzcGFjZSBVUkkuCi0gICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGxvY2FsIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICogQHJldHVybiBUaGUgYXR0cmlidXRlIHZhbHVlIGFzIGEgc3RyaW5nLCBvciBudWxsIGlmIHRoZQotICAgKiAgICAgICAgIGF0dHJpYnV0ZSBpcyBub3QgaW4gdGhlIGxpc3QuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFZhbHVlKFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUpCi0gIHsKLSAgICAgICAgTm9kZSBhPW1fYXR0cnMuZ2V0TmFtZWRJdGVtTlModXJpLGxvY2FsTmFtZSk7Ci0gICAgICAgIHJldHVybiAoYT09bnVsbCkgPyBudWxsIDogYS5nZXROb2RlVmFsdWUoKTsKLSAgfQotCi0gIC8qKgotICAgKiBMb29rIHVwIHRoZSBpbmRleCBvZiBhbiBhdHRyaWJ1dGUgYnkgTmFtZXNwYWNlIG5hbWUuCi0gICAqCi0gICAqIEBwYXJhbSB1cmkgVGhlIE5hbWVzcGFjZSBVUkksIG9yIHRoZSBlbXB0eSBzdHJpbmcgaWYKLSAgICogICAgICAgIHRoZSBuYW1lIGhhcyBubyBOYW1lc3BhY2UgVVJJLgotICAgKiBAcGFyYW0gbG9jYWxQYXJ0IFRoZSBhdHRyaWJ1dGUncyBsb2NhbCBuYW1lLgotICAgKiBAcmV0dXJuIFRoZSBpbmRleCBvZiB0aGUgYXR0cmlidXRlLCBvciAtMSBpZiBpdCBkb2VzIG5vdAotICAgKiAgICAgICAgIGFwcGVhciBpbiB0aGUgbGlzdC4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0SW5kZXgoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsUGFydCkKLSAgewotICAgIGZvcihpbnQgaT1tX2F0dHJzLmdldExlbmd0aCgpLTE7aT49MDstLWkpCi0gICAgewotICAgICAgTm9kZSBhPW1fYXR0cnMuaXRlbShpKTsKLSAgICAgIFN0cmluZyB1PWEuZ2V0TmFtZXNwYWNlVVJJKCk7Ci0gICAgICBpZiggKHU9PW51bGwgPyB1cmk9PW51bGwgOiB1LmVxdWFscyh1cmkpKQotICAgICAgJiYKLSAgICAgIGEuZ2V0TG9jYWxOYW1lKCkuZXF1YWxzKGxvY2FsUGFydCkgKQotICAgIHJldHVybiBpOwotICAgIH0KLSAgICByZXR1cm4gLTE7Ci0gIH0KLQotICAvKioKLSAgICogTG9vayB1cCB0aGUgaW5kZXggb2YgYW4gYXR0cmlidXRlIGJ5IHJhdyBYTUwgMS4wIG5hbWUuCi0gICAqCi0gICAqIEBwYXJhbSBxTmFtZSBUaGUgcXVhbGlmaWVkIChwcmVmaXhlZCkgbmFtZS4KLSAgICogQHJldHVybiBUaGUgaW5kZXggb2YgdGhlIGF0dHJpYnV0ZSwgb3IgLTEgaWYgaXQgZG9lcyBub3QKLSAgICogICAgICAgICBhcHBlYXIgaW4gdGhlIGxpc3QuCi0gICAqLwotICBwdWJsaWMgaW50IGdldEluZGV4KFN0cmluZyBxTmFtZSkKLSAgewotICAgIGZvcihpbnQgaT1tX2F0dHJzLmdldExlbmd0aCgpLTE7aT49MDstLWkpCi0gICAgewotICAgICAgTm9kZSBhPW1fYXR0cnMuaXRlbShpKTsKLSAgICAgIGlmKGEuZ2V0Tm9kZU5hbWUoKS5lcXVhbHMocU5hbWUpICkKLSAgICByZXR1cm4gaTsKLSAgICB9Ci0gICAgcmV0dXJuIC0xOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL3V0aWxzL0Jvb2xTdGFjay5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci91dGlscy9Cb29sU3RhY2suamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZDIwZDRkNS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL3V0aWxzL0Jvb2xTdGFjay5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjA2ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IEJvb2xTdGFjay5qYXZhLHYgMS4xLjQuMSAyMDA1LzA5LzA4IDExOjAzOjA4IHN1cmVzaF9lbWFpbGlkIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyLnV0aWxzOwotCi0KLS8qKgotICogU2ltcGxlIHN0YWNrIGZvciBib29sZWFuIHZhbHVlcy4KLSAqCi0gKiBUaGlzIGNsYXNzIGlzIGEgY29weSBvZiB0aGUgb25lIGluIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuCi0gKiBJdCBleGlzdHMgdG8gY3V0IHRoZSBzZXJpYWxpemVycyBkZXBlbmRhbmN5IG9uIHRoYXQgcGFja2FnZS4KLSAqIEEgbWlub3IgY2hhbmdlcyBmcm9tIHRoYXQgcGFja2FnZSBhcmU6Ci0gKiBkb2Vzbid0IGltcGxlbWVudCBDbG9uYWJsZQotICoKLSAqIFRoaXMgY2xhc3MgaXMgbm90IGEgcHVibGljIEFQSSwgaXQgaXMgb25seSBwdWJsaWMgYmVjYXVzZSBpdCBpcwotICogdXNlZCBpbiBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXIuCi0gKgotICogQHhzbC51c2FnZSBpbnRlcm5hbAotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgQm9vbFN0YWNrCi17Ci0KLSAgLyoqIEFycmF5IG9mIGJvb2xlYW4gdmFsdWVzICAgICAgICAgICovCi0gIHByaXZhdGUgYm9vbGVhbiBtX3ZhbHVlc1tdOwotCi0gIC8qKiBBcnJheSBzaXplIGFsbG9jYXRlZCAgICAgICAgICAgKi8KLSAgcHJpdmF0ZSBpbnQgbV9hbGxvY2F0ZWRTaXplOwotCi0gIC8qKiBJbmRleCBpbnRvIHRoZSBhcnJheSBvZiBib29sZWFucyAgICAgICAgICAqLwotICBwcml2YXRlIGludCBtX2luZGV4OwotCi0gIC8qKgotICAgKiBEZWZhdWx0IGNvbnN0cnVjdG9yLiAgTm90ZSB0aGF0IHRoZSBkZWZhdWx0Ci0gICAqIGJsb2NrIHNpemUgaXMgdmVyeSBzbWFsbCwgZm9yIHNtYWxsIGxpc3RzLgotICAgKi8KLSAgcHVibGljIEJvb2xTdGFjaygpCi0gIHsKLSAgICB0aGlzKDMyKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBJbnRWZWN0b3IsIHVzaW5nIHRoZSBnaXZlbiBibG9jayBzaXplLgotICAgKgotICAgKiBAcGFyYW0gc2l6ZSBhcnJheSBzaXplIHRvIGFsbG9jYXRlCi0gICAqLwotICBwdWJsaWMgQm9vbFN0YWNrKGludCBzaXplKQotICB7Ci0KLSAgICBtX2FsbG9jYXRlZFNpemUgPSBzaXplOwotICAgIG1fdmFsdWVzID0gbmV3IGJvb2xlYW5bc2l6ZV07Ci0gICAgbV9pbmRleCA9IC0xOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbGVuZ3RoIG9mIHRoZSBsaXN0LgotICAgKgotICAgKiBAcmV0dXJuIEN1cnJlbnQgbGVuZ3RoIG9mIHRoZSBsaXN0Ci0gICAqLwotICBwdWJsaWMgZmluYWwgaW50IHNpemUoKQotICB7Ci0gICAgcmV0dXJuIG1faW5kZXggKyAxOwotICB9Ci0KLSAgLyoqCi0gICAqIENsZWFycyB0aGUgc3RhY2suCi0gICAqCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBjbGVhcigpCi0gIHsKLSAgICBtX2luZGV4ID0gLTE7Ci0gIH0KLQotICAvKioKLSAgICogUHVzaGVzIGFuIGl0ZW0gb250byB0aGUgdG9wIG9mIHRoaXMgc3RhY2suCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSB2YWwgdGhlIGJvb2xlYW4gdG8gYmUgcHVzaGVkIG9udG8gdGhpcyBzdGFjay4KLSAgICogQHJldHVybiAgdGhlIDxjb2RlPml0ZW08L2NvZGU+IGFyZ3VtZW50LgotICAgKi8KLSAgcHVibGljIGZpbmFsIGJvb2xlYW4gcHVzaChib29sZWFuIHZhbCkKLSAgewotCi0gICAgaWYgKG1faW5kZXggPT0gbV9hbGxvY2F0ZWRTaXplIC0gMSkKLSAgICAgIGdyb3coKTsKLQotICAgIHJldHVybiAobV92YWx1ZXNbKyttX2luZGV4XSA9IHZhbCk7Ci0gIH0KLQotICAvKioKLSAgICogUmVtb3ZlcyB0aGUgb2JqZWN0IGF0IHRoZSB0b3Agb2YgdGhpcyBzdGFjayBhbmQgcmV0dXJucyB0aGF0Ci0gICAqIG9iamVjdCBhcyB0aGUgdmFsdWUgb2YgdGhpcyBmdW5jdGlvbi4KLSAgICoKLSAgICogQHJldHVybiAgICAgVGhlIG9iamVjdCBhdCB0aGUgdG9wIG9mIHRoaXMgc3RhY2suCi0gICAqIEB0aHJvd3MgIEVtcHR5U3RhY2tFeGNlcHRpb24gIGlmIHRoaXMgc3RhY2sgaXMgZW1wdHkuCi0gICAqLwotICBwdWJsaWMgZmluYWwgYm9vbGVhbiBwb3AoKQotICB7Ci0gICAgcmV0dXJuIG1fdmFsdWVzW21faW5kZXgtLV07Ci0gIH0KLQotICAvKioKLSAgICogUmVtb3ZlcyB0aGUgb2JqZWN0IGF0IHRoZSB0b3Agb2YgdGhpcyBzdGFjayBhbmQgcmV0dXJucyB0aGUKLSAgICogbmV4dCBvYmplY3QgYXQgdGhlIHRvcCBhcyB0aGUgdmFsdWUgb2YgdGhpcyBmdW5jdGlvbi4KLSAgICoKLSAgICoKLSAgICogQHJldHVybiBOZXh0IG9iamVjdCB0byB0aGUgdG9wIG9yIGZhbHNlIGlmIG5vbmUgdGhlcmUKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBib29sZWFuIHBvcEFuZFRvcCgpCi0gIHsKLQotICAgIG1faW5kZXgtLTsKLQotICAgIHJldHVybiAobV9pbmRleCA+PSAwKSA/IG1fdmFsdWVzW21faW5kZXhdIDogZmFsc2U7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBpdGVtIGF0IHRoZSB0b3Agb2YgdGhpcyBzdGFjawotICAgKgotICAgKgotICAgKiBAcGFyYW0gYiBPYmplY3QgdG8gc2V0IGF0IHRoZSB0b3Agb2YgdGhpcyBzdGFjawotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgc2V0VG9wKGJvb2xlYW4gYikKLSAgewotICAgIG1fdmFsdWVzW21faW5kZXhdID0gYjsKLSAgfQotCi0gIC8qKgotICAgKiBMb29rcyBhdCB0aGUgb2JqZWN0IGF0IHRoZSB0b3Agb2YgdGhpcyBzdGFjayB3aXRob3V0IHJlbW92aW5nIGl0Ci0gICAqIGZyb20gdGhlIHN0YWNrLgotICAgKgotICAgKiBAcmV0dXJuICAgICB0aGUgb2JqZWN0IGF0IHRoZSB0b3Agb2YgdGhpcyBzdGFjay4KLSAgICogQHRocm93cyAgRW1wdHlTdGFja0V4Y2VwdGlvbiAgaWYgdGhpcyBzdGFjayBpcyBlbXB0eS4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBib29sZWFuIHBlZWsoKQotICB7Ci0gICAgcmV0dXJuIG1fdmFsdWVzW21faW5kZXhdOwotICB9Ci0KLSAgLyoqCi0gICAqIExvb2tzIGF0IHRoZSBvYmplY3QgYXQgdGhlIHRvcCBvZiB0aGlzIHN0YWNrIHdpdGhvdXQgcmVtb3ZpbmcgaXQKLSAgICogZnJvbSB0aGUgc3RhY2suICBJZiB0aGUgc3RhY2sgaXMgZW1wdHksIGl0IHJldHVybnMgZmFsc2UuCi0gICAqCi0gICAqIEByZXR1cm4gICAgIHRoZSBvYmplY3QgYXQgdGhlIHRvcCBvZiB0aGlzIHN0YWNrLgotICAgKi8KLSAgcHVibGljIGZpbmFsIGJvb2xlYW4gcGVla09yRmFsc2UoKQotICB7Ci0gICAgcmV0dXJuIChtX2luZGV4ID4gLTEpID8gbV92YWx1ZXNbbV9pbmRleF0gOiBmYWxzZTsKLSAgfQotCi0gIC8qKgotICAgKiBMb29rcyBhdCB0aGUgb2JqZWN0IGF0IHRoZSB0b3Agb2YgdGhpcyBzdGFjayB3aXRob3V0IHJlbW92aW5nIGl0Ci0gICAqIGZyb20gdGhlIHN0YWNrLiAgSWYgdGhlIHN0YWNrIGlzIGVtcHR5LCBpdCByZXR1cm5zIHRydWUuCi0gICAqCi0gICAqIEByZXR1cm4gICAgIHRoZSBvYmplY3QgYXQgdGhlIHRvcCBvZiB0aGlzIHN0YWNrLgotICAgKi8KLSAgcHVibGljIGZpbmFsIGJvb2xlYW4gcGVla09yVHJ1ZSgpCi0gIHsKLSAgICByZXR1cm4gKG1faW5kZXggPiAtMSkgPyBtX3ZhbHVlc1ttX2luZGV4XSA6IHRydWU7Ci0gIH0KLQotICAvKioKLSAgICogVGVzdHMgaWYgdGhpcyBzdGFjayBpcyBlbXB0eS4KLSAgICoKLSAgICogQHJldHVybiAgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhpcyBzdGFjayBpcyBlbXB0eTsKLSAgICogICAgICAgICAgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzRW1wdHkoKQotICB7Ci0gICAgcmV0dXJuIChtX2luZGV4ID09IC0xKTsKLSAgfQotCi0gIC8qKgotICAgKiBHcm93cyB0aGUgc2l6ZSBvZiB0aGUgc3RhY2sKLSAgICoKLSAgICovCi0gIHByaXZhdGUgdm9pZCBncm93KCkKLSAgewotCi0gICAgbV9hbGxvY2F0ZWRTaXplICo9IDI7Ci0KLSAgICBib29sZWFuIG5ld1ZlY3RvcltdID0gbmV3IGJvb2xlYW5bbV9hbGxvY2F0ZWRTaXplXTsKLQotICAgIFN5c3RlbS5hcnJheWNvcHkobV92YWx1ZXMsIDAsIG5ld1ZlY3RvciwgMCwgbV9pbmRleCArIDEpOwotCi0gICAgbV92YWx1ZXMgPSBuZXdWZWN0b3I7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvdXRpbHMvRE9NMkhlbHBlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci91dGlscy9ET00ySGVscGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDczOTU5MDMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci91dGlscy9ET00ySGVscGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMzYgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IERPTTJIZWxwZXIuamF2YSx2IDEuMS40LjEgMjAwNS8wOS8wOCAxMTowMzowOSBzdXJlc2hfZW1haWxpZCBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplci51dGlsczsKLQotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci0KLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXI7Ci1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy5QYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5BdHRyOwotaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLkVsZW1lbnQ7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLQotaW1wb3J0IG9yZy54bWwuc2F4LklucHV0U291cmNlOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgcHJvdmlkZXMgYSBET00gbGV2ZWwgMiAiaGVscGVyIiwgd2hpY2ggcHJvdmlkZXMgc2VydmljZXMgY3VycmVudGx5Ci0gKiBub3QgcHJvdmlkZWQgYmUgdGhlIERPTSBzdGFuZGFyZC4KLSAqCi0gKiBUaGlzIGNsYXNzIGlzIGEgY29weSBvZiB0aGUgb25lIGluIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuCi0gKiBJdCBleGlzdHMgdG8gY3V0IHRoZSBzZXJpYWxpemVycyBkZXBlbmRhbmN5IG9uIHRoYXQgcGFja2FnZS4KLSAqCi0gKiBUaGUgZGlmZmVyZW5jZXMgZnJvbSB0aGUgb3JpZ2luYWwgY2xhc3MgYXJlOgotICogaXQgZG9lc24ndCBleHRlbmQgRE9NSGVscGVyLCBub3QgZGVwcmljYXRlZCwKLSAqIGRyb3BwZWQgbWV0aG9kIGlzTm9kZUFmdGVyKE5vZGUgbm9kZTEsIE5vZGUgbm9kZTIpCi0gKiBkcm9wcGVkIG1ldGhvZCBwYXJzZShJbnB1dFNvdXJjZSkKLSAqIGRyb3BwZWQgbWV0aG9kIHN1cHBvcnRTQVgoKQotICogZHJvcHBlZCBtZXRob2Qgc2V0RG9jdW1lbnQoZG9jKQotICogZHJvcHBlZCBtZXRob2QgY2hlY2tOb2RlKE5vZGUpCi0gKiBkcm9wcGVkIG1ldGhvZCBnZXREb2N1bWVudCgpCi0gKiBkcm9wcGVkIG1ldGhvZCBnZXRFbGVtZW50QnlJRChTdHJpbmcgaWQsIERvY3VtZW50IGRvYykKLSAqIGRyb3BwZWQgbWV0aG9kIGdldFBhcmVudE9mTm9kZShOb2RlIG5vZGUpCi0gKiBkcm9wcGVkIGZpZWxkIERvY3VtZW50IG1fZG9jOwotICogbWFkZSBjbGFzcyBub24tcHVibGljCi0gKgotICogVGhpcyBjbGFzcyBpcyBub3QgYSBwdWJsaWMgQVBJLCBpdCBpcyBvbmx5IHB1YmxpYyBiZWNhdXNlIGl0IGlzCi0gKiB1c2VkIGluIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplci4KLSAqCi0gKiBAeHNsLnVzYWdlIGludGVybmFsCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBET00ySGVscGVyCi17Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhbiBpbnN0YW5jZS4KLSAgICovCi0gIHB1YmxpYyBET00ySGVscGVyKCl7fQotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBsb2NhbCBuYW1lIG9mIHRoZSBnaXZlbiBub2RlLCBhcyBkZWZpbmVkIGJ5IHRoZQotICAgKiBYTUwgTmFtZXNwYWNlcyBzcGVjaWZpY2F0aW9uLiBUaGlzIGlzIHByZXBhcmVkIHRvIGhhbmRsZSBkb2N1bWVudHMKLSAgICogYnVpbHQgdXNpbmcgRE9NIExldmVsIDEgbWV0aG9kcyBieSBmYWxsaW5nIGJhY2sgdXBvbiBleHBsaWNpdGx5Ci0gICAqIHBhcnNpbmcgdGhlIG5vZGUgbmFtZS4KLSAgICoKLSAgICogQHBhcmFtIG4gTm9kZSB0byBiZSBleGFtaW5lZAotICAgKgotICAgKiBAcmV0dXJuIFN0cmluZyBjb250YWluaW5nIHRoZSBsb2NhbCBuYW1lLCBvciBudWxsIGlmIHRoZSBub2RlCi0gICAqIHdhcyBub3QgYXNzaWduZWQgYSBOYW1lc3BhY2UuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldExvY2FsTmFtZU9mTm9kZShOb2RlIG4pCi0gIHsKLQotICAgIFN0cmluZyBuYW1lID0gbi5nZXRMb2NhbE5hbWUoKTsKLQotICAgIHJldHVybiAobnVsbCA9PSBuYW1lKSA/IGdldExvY2FsTmFtZU9mTm9kZUZhbGxiYWNrKG4pIDogbmFtZTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBsb2NhbCBuYW1lIG9mIHRoZSBnaXZlbiBub2RlLiBJZiB0aGUgbm9kZSdzIG5hbWUgYmVnaW5zCi0gICAqIHdpdGggYSBuYW1lc3BhY2UgcHJlZml4LCB0aGlzIGlzIHRoZSBwYXJ0IGFmdGVyIHRoZSBjb2xvbjsgb3RoZXJ3aXNlCi0gICAqIGl0J3MgdGhlIGZ1bGwgbm9kZSBuYW1lLgotICAgKgotICAgKiBUaGlzIG1ldGhvZCBpcyBjb3BpZWQgZnJvbSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLkRPTUhlbHBlcgotICAgKgotICAgKiBAcGFyYW0gbiB0aGUgbm9kZSB0byBiZSBleGFtaW5lZC4KLSAgICoKLSAgICogQHJldHVybiBTdHJpbmcgY29udGFpbmluZyB0aGUgTG9jYWwgTmFtZQotICAgKi8KLSAgcHJpdmF0ZSBTdHJpbmcgZ2V0TG9jYWxOYW1lT2ZOb2RlRmFsbGJhY2soTm9kZSBuKQotICB7Ci0KLSAgICBTdHJpbmcgcW5hbWUgPSBuLmdldE5vZGVOYW1lKCk7Ci0gICAgaW50IGluZGV4ID0gcW5hbWUuaW5kZXhPZignOicpOwotCi0gICAgcmV0dXJuIChpbmRleCA8IDApID8gcW5hbWUgOiBxbmFtZS5zdWJzdHJpbmcoaW5kZXggKyAxKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBOYW1lc3BhY2UgTmFtZSAoTmFtZXNwYWNlIFVSSSkgZm9yIHRoZSBnaXZlbiBub2RlLgotICAgKiBJbiBhIExldmVsIDIgRE9NLCB5b3UgY2FuIGFzayB0aGUgbm9kZSBpdHNlbGYuIE5vdGUsIGhvd2V2ZXIsIHRoYXQKLSAgICogZG9pbmcgc28gY29uZmxpY3RzIHdpdGggb3VyIGRlY2lzaW9uIGluIGdldExvY2FsTmFtZU9mTm9kZSBub3QKLSAgICogdG8gdHJ1c3QgdGhlIHRoYXQgdGhlIERPTSB3YXMgaW5kZWVkIGNyZWF0ZWQgdXNpbmcgdGhlIExldmVsIDIKLSAgICogbWV0aG9kcy4gSWYgTGV2ZWwgMSBtZXRob2RzIHdlcmUgdXNlZCwgdGhlc2UgdHdvIGZ1bmN0aW9ucyB3aWxsCi0gICAqIGRpc2FncmVlIHdpdGggZWFjaCBvdGhlci4KLSAgICogPHA+Ci0gICAqIFRPRE86IFJlY29uY2lsZSB3aXRoIGdldExvY2FsTmFtZU9mTm9kZS4KLSAgICoKLSAgICogQHBhcmFtIG4gTm9kZSB0byBiZSBleGFtaW5lZAotICAgKgotICAgKiBAcmV0dXJuIFN0cmluZyBjb250YWluaW5nIHRoZSBOYW1lc3BhY2UgVVJJIGJvdW5kIHRvIHRoaXMgRE9NIG5vZGUKLSAgICogYXQgdGhlIHRpbWUgdGhlIE5vZGUgd2FzIGNyZWF0ZWQuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldE5hbWVzcGFjZU9mTm9kZShOb2RlIG4pCi0gIHsKLSAgICByZXR1cm4gbi5nZXROYW1lc3BhY2VVUkkoKTsKLSAgfQotCi0gIC8qKiBGaWVsZCBtX3VzZURPTTJnZXROYW1lc3BhY2VVUkkgaXMgYSBjb21waWxlLXRpbWUgZmxhZyB3aGljaAotICAgKiAgZ2F0ZXMgc29tZSBvZiB0aGUgcGFyc2VyIG9wdGlvbnMgdXNlZCB0byBidWlsZCBhIERPTSAtLSBidXQKLSAgICogdGhhdCBjb2RlIGlzIGNvbW1lbnRlZCBvdXQgYXQgdGhpcyB0aW1lIGFuZCBub2JvZHkgZWxzZQotICAgKiByZWZlcmVuY2VzIGl0LCBzbyBJJ3ZlIGNvbW1lbnRlZCB0aGlzIG91dCBhcyB3ZWxsLiAqLwotICAvL3ByaXZhdGUgYm9vbGVhbiBtX3VzZURPTTJnZXROYW1lc3BhY2VVUkkgPSBmYWxzZTsKLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvdXRpbHMvTWVzc2FnZXMuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvdXRpbHMvTWVzc2FnZXMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggODRmNGM5OC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL3V0aWxzL01lc3NhZ2VzLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyNzIgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IE1lc3NhZ2VzLmphdmEsdiAxLjEuNC4xIDIwMDUvMDkvMDggMTE6MDM6MTAgc3VyZXNoX2VtYWlsaWQgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXIudXRpbHM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwudXRpbHMuU2VjdXJpdHlTdXBwb3J0OwotaW1wb3J0IGphdmEudXRpbC5MaXN0UmVzb3VyY2VCdW5kbGU7Ci1pbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKLWltcG9ydCBqYXZhLnV0aWwuTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uOwotaW1wb3J0IGphdmEudXRpbC5SZXNvdXJjZUJ1bmRsZTsKLQotLyoqCi0gKiBBIHV0aWxpdHkgY2xhc3MgZm9yIGlzc3VpbmcgZXJyb3IgbWVzc2FnZXMuCi0gKgotICogQSB1c2VyIG9mIHRoaXMgY2xhc3Mgbm9ybWFsbHkgd291bGQgY3JlYXRlIGEgc2luZ2xldG9uCi0gKiBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzLCBwYXNzaW5nIHRoZSBuYW1lCi0gKiBvZiB0aGUgbWVzc2FnZSBjbGFzcyBvbiB0aGUgY29uc3RydWN0b3IuIEZvciBleGFtcGxlOgotICogPENPREU+Ci0gKiBzdGF0aWMgTWVzc2FnZXMgeCA9IG5ldyBNZXNzYWdlcygib3JnLnBhY2thZ2UuTXlNZXNzYWdlcyIpOwotICogPC9DT0RFPgotICogTGF0ZXIgdGhlIG1lc3NhZ2UgaXMgdHlwaWNhbGx5IGdlbmVyYXRlZCB0aGlzIHdheSBpZiB0aGVyZSBhcmUgbm8KLSAqIHN1YnN0aXR1dGlvbiBhcmd1bWVudHM6Ci0gKiA8Q09ERT4KLSAqIFN0cmluZyBtc2cgPSB4LmNyZWF0ZU1lc3NhZ2Uob3JnLnBhY2thZ2UuTXlNZXNzYWdlcy5LRVlfT05FLCBudWxsKTsKLSAqIDwvQ09ERT4KLSAqIElmIHRoZXJlIGFyZSBhcmd1bWVudHMgc3Vic3RpdHV0aW9ucyB0aGVuIHNvbWV0aGluZyBsaWtlIHRoaXM6Ci0gKiA8Q09ERT4KLSAqIFN0cmluZyBmaWxlbmFtZSA9IC4uLjsKLSAqIFN0cmluZyBkaXJlY3RvcnkgPSAuLi47Ci0gKiBTdHJpbmcgbXNnID0geC5jcmVhdGVNZXNzYWdlKG9yZy5wYWNrYWdlLk15TWVzc2FnZXMuS0VZX1RXTywKLSAqICAgbmV3IE9iamVjdFtdIHtmaWxlbmFtZSwgZGlyZWN0b3J5KSApOwotICogPC9DT0RFPgotICoKLSAqIFRoZSBjb25zdHJ1Y3RvciBvZiBhbiBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIG11c3QgYmUgZ2l2ZW4KLSAqIHRoZSBjbGFzcyBuYW1lIG9mIGEgY2xhc3MgdGhhdCBleHRlbmRzIGphdmEudXRpbC5MaXN0UmVzb3VyY2VCdW5kbGUKLSAqICgib3JnLnBhY2thZ2UuTXlNZXNzYWdlcyIgaW4gdGhlIGV4YW1wbGUgYWJvdmUpLgotICogVGhlIG5hbWUgc2hvdWxkIG5vdCBoYXZlIGFueSBsYW5ndWFnZSBzdWZmaXgKLSAqIHdoaWNoIHdpbGwgYmUgYWRkZWQgYXV0b21hdGljYWxseSBieSB0aGlzIHV0aWxpdHkgY2xhc3MuCi0gKgotICogVGhlIG1lc3NhZ2UgY2xhc3MgKCJvcmcucGFja2FnZS5NeU1lc3NhZ2VzIikKLSAqIG11c3QgZGVmaW5lIHRoZSBhYnN0cmFjdCBtZXRob2QgZ2V0Q29udGVudHMoKSB0aGF0IGlzCi0gKiBkZWNsYXJlZCBpbiBpdHMgYmFzZSBjbGFzcywgZm9yIGV4YW1wbGU6Ci0gKiA8Q09ERT4KLSAqIHB1YmxpYyBPYmplY3RbXVtdIGdldENvbnRlbnRzKCkge3JldHVybiBjb250ZW50czt9Ci0gKiA8L0NPREU+Ci0gKgotICogSXQgaXMgc3VnZ2VzdGVkIHRoYXQgdGhlIG1lc3NhZ2UgY2xhc3MgZXhwb3NlIGl0cwotICogbWVzc2FnZSBrZXlzIGxpa2UgdGhpczoKLSAqIDxDT0RFPgotICogICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBLRVlfT05FID0gIktFWTEiOwotICogICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBLRVlfVFdPID0gIktFWTIiOwotICogICAuIC4gLgotICogPC9DT0RFPgotICogYW5kIHVzZWQgdGhyb3VnaCB0aGVpciBuYW1lcyAoS0VZX09ORSAuLi4pIHJhdGhlciB0aGFuCi0gKiB0aGVpciB2YWx1ZXMgKCJLRVkxIiAuLi4pLgotICoKLSAqIFRoZSBmaWVsZCBjb250ZW50cyAocmV0dXJuZWQgYnkgZ2V0Q29udGVudHMoKQotICogc2hvdWxkIGJlIGluaXRpYWxpemVkIHNvbWV0aGluZyBsaWtlIHRoaXM6Ci0gKiA8Q09ERT4KLSAqIHB1YmxpYyBzdGF0aWMgZmluYWwgT2JqZWN0W11bXSBjb250ZW50cyA9IHsKLSAqIHsgS0VZX09ORSwgIlNvbWV0aGluZyBoYXMgZ29uZSB3cm9uZyEiIH0sCi0gKiB7IEtFWV9UV08sICJUaGUgZmlsZSAnJ3swfScnIGRvZXMgbm90IGV4aXN0IGluIGRpcmVjdG9yeSAnJ3sxfScnLiIgfSwKLSAqIC4gLiAuCi0gKiB7IEtFWV9OLCAiTWVzc2FnZSBOIiB9ICB9Ci0gKiA8L0NPREU+Ci0gKgotICogV2hlcmUgdGhhdCBzZWN0aW9uIG9mIGNvZGUgd2l0aCB0aGUgS0VZIHRvIE1lc3NhZ2UgbWFwcGluZ3MKLSAqICh3aGVyZSB0aGUgbWVzc2FnZSBjbGFzc2VzICdjb250ZW50cycgZmllbGQgaXMgaW5pdGlhbGl6ZWQpCi0gKiBjYW4gaGF2ZSB0aGUgTWVzc2FnZSBzdHJpbmdzIHRyYW5zbGF0ZWQgaW4gYW4gYWx0ZXJuYXRlIGxhbmd1YWdlCi0gKiBpbiBhIGVycm9yUmVzb3VyY2VDbGFzcyB3aXRoIGEgbGFuZ3VhZ2Ugc3VmZml4LgotICoKLSAqCi0gKiBUaGlzIGNsYXNzIGlzIG5vdCBhIHB1YmxpYyBBUEksIGl0IGlzIG9ubHkgcHVibGljIGJlY2F1c2UgaXQgaXMKLSAqIHVzZWQgaW4gY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyLgotICoKLSAqICBAeHNsLnVzYWdlIGludGVybmFsCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBNZXNzYWdlcwotewotICAgIC8qKiBUaGUgbG9jYWwgb2JqZWN0IHRvIHVzZS4gICovCi0gICAgcHJpdmF0ZSBmaW5hbCBMb2NhbGUgbV9sb2NhbGUgPSBMb2NhbGUuZ2V0RGVmYXVsdCgpOwotCi0gICAgLyoqIFRoZSBsYW5ndWFnZSBzcGVjaWZpYyByZXNvdXJjZSBvYmplY3QgZm9yIG1lc3NhZ2VzLiAgKi8KLSAgICBwcml2YXRlIExpc3RSZXNvdXJjZUJ1bmRsZSBtX3Jlc291cmNlQnVuZGxlOwotCi0gICAgLyoqIFRoZSBjbGFzcyBuYW1lIG9mIHRoZSBlcnJvciBtZXNzYWdlIHN0cmluZyB0YWJsZSB3aXRoIG5vIGxhbmd1YWdlIHN1ZmZpeC4gKi8KLSAgICBwcml2YXRlIFN0cmluZyBtX3Jlc291cmNlQnVuZGxlTmFtZTsKLQotCi0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3Rvci4KLSAgICAgKiBAcGFyYW0gcmVzb3VyY2VCdW5kbGUgdGhlIGNsYXNzIG5hbWUgb2YgdGhlIExpc3RSZXNvdXJjZUJ1bmRsZQotICAgICAqIHRoYXQgdGhlIGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgaXMgYXNzb2NpYXRlZCB3aXRoIGFuZCB3aWxsIHVzZSB3aGVuCi0gICAgICogY3JlYXRpbmcgbWVzc2FnZXMuCi0gICAgICogVGhlIGNsYXNzIG5hbWUgaXMgd2l0aG91dCBhIGxhbmd1YWdlIHN1ZmZpeC4gSWYgdGhlIHZhbHVlIHBhc3NlZAotICAgICAqIGlzIG51bGwgdGhlbiBsb2FkUmVzb3VyY2VCdW5kbGUoZXJyb3JSZXNvdXJjZUNsYXNzKSBuZWVkcyB0byBiZSBjYWxsZWQKLSAgICAgKiBleHBsaWNpdGx5IGJlZm9yZSBhbnkgbWVzc2FnZXMgYXJlIGNyZWF0ZWQuCi0gICAgICoKLSAgICAgKiBAeHNsLnVzYWdlIGludGVybmFsCi0gICAgICovCi0gICAgTWVzc2FnZXMoU3RyaW5nIHJlc291cmNlQnVuZGxlKQotICAgIHsKLQotICAgICAgICBtX3Jlc291cmNlQnVuZGxlTmFtZSA9IHJlc291cmNlQnVuZGxlOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBMb2NhbGUgb2JqZWN0IHRoYXQgaXMgYmVpbmcgdXNlZC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gbm9uLW51bGwgcmVmZXJlbmNlIHRvIExvY2FsZSBvYmplY3QuCi0gICAgICogQHhzbC51c2FnZSBpbnRlcm5hbAotICAgICAqLwotICAgIHByaXZhdGUgTG9jYWxlIGdldExvY2FsZSgpCi0gICAgewotICAgICAgICByZXR1cm4gbV9sb2NhbGU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlcyBhIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIGtleSBhbmQgcmVwbGFjZW1lbnQKLSAgICAgKiBhcmd1bWVudHMsIGxvY2FsaXplZCB0byB0aGUgZ2l2ZW4gbG9jYWxlLgotICAgICAqCi0gICAgICogQHBhcmFtIG1zZ0tleSAgVGhlIGtleSBmb3IgdGhlIG1lc3NhZ2UgdGV4dC4KLSAgICAgKiBAcGFyYW0gYXJncyAgICBUaGUgYXJndW1lbnRzIHRvIGJlIHVzZWQgYXMgcmVwbGFjZW1lbnQgdGV4dAotICAgICAqIGluIHRoZSBtZXNzYWdlIGNyZWF0ZWQuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBmb3JtYXR0ZWQgbWVzc2FnZSBzdHJpbmcuCi0gICAgICogQHhzbC51c2FnZSBpbnRlcm5hbAotICAgICAqLwotICAgIHB1YmxpYyBmaW5hbCBTdHJpbmcgY3JlYXRlTWVzc2FnZShTdHJpbmcgbXNnS2V5LCBPYmplY3QgYXJnc1tdKQotICAgIHsKLSAgICAgICAgaWYgKG1fcmVzb3VyY2VCdW5kbGUgPT0gbnVsbCkKLSAgICAgICAgICAgIG1fcmVzb3VyY2VCdW5kbGUgPSBTZWN1cml0eVN1cHBvcnQuZ2V0UmVzb3VyY2VCdW5kbGUobV9yZXNvdXJjZUJ1bmRsZU5hbWUpOwotCi0gICAgICAgIGlmIChtX3Jlc291cmNlQnVuZGxlICE9IG51bGwpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHJldHVybiBjcmVhdGVNc2cobV9yZXNvdXJjZUJ1bmRsZSwgbXNnS2V5LCBhcmdzKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgICAgICByZXR1cm4gIkNvdWxkIG5vdCBsb2FkIHRoZSByZXNvdXJjZSBidW5kbGVzOiAiKyBtX3Jlc291cmNlQnVuZGxlTmFtZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGVzIGEgbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQga2V5IGFuZCByZXBsYWNlbWVudAotICAgICAqIGFyZ3VtZW50cywgbG9jYWxpemVkIHRvIHRoZSBnaXZlbiBsb2NhbGUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZXJyb3JDb2RlIFRoZSBrZXkgZm9yIHRoZSBtZXNzYWdlIHRleHQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZlJlc291cmNlQnVuZGxlIFRoZSByZXNvdXJjZSBidW5kbGUgdG8gdXNlLgotICAgICAqIEBwYXJhbSBtc2dLZXkgIFRoZSBtZXNzYWdlIGtleSB0byB1c2UuCi0gICAgICogQHBhcmFtIGFyZ3MgICAgICBUaGUgYXJndW1lbnRzIHRvIGJlIHVzZWQgYXMgcmVwbGFjZW1lbnQgdGV4dAotICAgICAqICAgICAgICAgICAgICAgICAgaW4gdGhlIG1lc3NhZ2UgY3JlYXRlZC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIGZvcm1hdHRlZCBtZXNzYWdlIHN0cmluZy4KLSAgICAgKiBAeHNsLnVzYWdlIGludGVybmFsCi0gICAgICovCi0gICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgY3JlYXRlTXNnKAotICAgICAgICBMaXN0UmVzb3VyY2VCdW5kbGUgZlJlc291cmNlQnVuZGxlLAotICAgICAgICBTdHJpbmcgbXNnS2V5LAotICAgICAgICBPYmplY3QgYXJnc1tdKSAvL3Rocm93cyBFeGNlcHRpb24KLSAgICB7Ci0KLSAgICAgICAgU3RyaW5nIGZtc2cgPSBudWxsOwotICAgICAgICBib29sZWFuIHRocm93ZXggPSBmYWxzZTsKLSAgICAgICAgU3RyaW5nIG1zZyA9IG51bGw7Ci0KLSAgICAgICAgaWYgKG1zZ0tleSAhPSBudWxsKQotICAgICAgICAgICAgbXNnID0gZlJlc291cmNlQnVuZGxlLmdldFN0cmluZyhtc2dLZXkpOwotICAgICAgICBlbHNlCi0gICAgICAgICAgICBtc2dLZXkgPSAiIjsKLQotICAgICAgICBpZiAobXNnID09IG51bGwpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHRocm93ZXggPSB0cnVlOwotICAgICAgICAgICAgLyogVGhlIG1lc3NhZ2UgaXMgbm90IGluIHRoZSBidW5kbGUgLiAuIC4gdGhpcyBpcyBiYWQsCi0gICAgICAgICAgICAgKiBzbyB0cnkgdG8gZ2V0IHRoZSBtZXNzYWdlIHRoYXQgdGhlIG1lc3NhZ2UgaXMgbm90IGluIHRoZSBidW5kbGUKLSAgICAgICAgICAgICAqLwotICAgICAgICAgICAgdHJ5Ci0gICAgICAgICAgICB7Ci0KLSAgICAgICAgICAgICAgICBtc2cgPQotICAgICAgICAgICAgICAgICAgICBqYXZhLnRleHQuTWVzc2FnZUZvcm1hdC5mb3JtYXQoCi0gICAgICAgICAgICAgICAgICAgICAgICBNc2dLZXkuQkFEX01TR0tFWSwKLSAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7IG1zZ0tleSwgbV9yZXNvdXJjZUJ1bmRsZU5hbWUgfSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGUpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgLyogZXZlbiB0aGUgbWVzc2FnZSB0aGF0IHRoZSBtZXNzYWdlIGlzIG5vdCBpbiB0aGUgYnVuZGxlIGlzCi0gICAgICAgICAgICAgICAgICogbm90IHRoZXJlIC4uLiB0aGlzIGlzIHJlYWxseSBiYWQKLSAgICAgICAgICAgICAgICAgKi8KLSAgICAgICAgICAgICAgICBtc2cgPQotICAgICAgICAgICAgICAgICAgICAiVGhlIG1lc3NhZ2Uga2V5ICciCi0gICAgICAgICAgICAgICAgICAgICAgICArIG1zZ0tleQotICAgICAgICAgICAgICAgICAgICAgICAgKyAiJyBpcyBub3QgaW4gdGhlIG1lc3NhZ2UgY2xhc3MgJyIKLSAgICAgICAgICAgICAgICAgICAgICAgICsgbV9yZXNvdXJjZUJ1bmRsZU5hbWUrIiciOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKGFyZ3MgIT0gbnVsbCkKLSAgICAgICAgewotICAgICAgICAgICAgdHJ5Ci0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgLy8gRG8gdGhpcyB0byBrZWVwIGZvcm1hdCBmcm9tIGNyeWluZy4KLSAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIGJldHRlciB0aGFuIG1ha2luZyBhIGJ1bmNoIG9mIGNvbmRpdGlvbmFsCi0gICAgICAgICAgICAgICAgLy8gY29kZSBhbGwgb3ZlciB0aGUgcGxhY2UuCi0gICAgICAgICAgICAgICAgaW50IG4gPSBhcmdzLmxlbmd0aDsKLQotICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKG51bGwgPT0gYXJnc1tpXSkKLSAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3NbaV0gPSAiIjsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBmbXNnID0gamF2YS50ZXh0Lk1lc3NhZ2VGb3JtYXQuZm9ybWF0KG1zZywgYXJncyk7Ci0gICAgICAgICAgICAgICAgLy8gaWYgd2UgZ2V0IHBhc3QgdGhlIGxpbmUgYWJvdmUgd2UgaGF2ZSBjcmVhdGUgdGhlIG1lc3NhZ2UgLi4uIGh1cnJheSEKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhdGNoIChFeGNlcHRpb24gZSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICB0aHJvd2V4ID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICB0cnkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIEdldCB0aGUgbWVzc2FnZSB0aGF0IHRoZSBmb3JtYXQgZmFpbGVkLgotICAgICAgICAgICAgICAgICAgICBmbXNnID0KLSAgICAgICAgICAgICAgICAgICAgICAgIGphdmEudGV4dC5NZXNzYWdlRm9ybWF0LmZvcm1hdCgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBNc2dLZXkuQkFEX01TR0ZPUk1BVCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBtc2dLZXksIG1fcmVzb3VyY2VCdW5kbGVOYW1lIH0pOwotICAgICAgICAgICAgICAgICAgICBmbXNnICs9ICIgIiArIG1zZzsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBmb3JtYXRmYWlsZWQpCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAvLyBXZSBjb3VsZG4ndCBldmVuIGdldCB0aGUgbWVzc2FnZSB0aGF0IHRoZSBmb3JtYXQgb2YKLSAgICAgICAgICAgICAgICAgICAgLy8gdGhlIG1lc3NhZ2UgZmFpbGVkIC4uLiBzbyBmYWxsIGJhY2sgdG8gRW5nbGlzaC4KLSAgICAgICAgICAgICAgICAgICAgZm1zZyA9Ci0gICAgICAgICAgICAgICAgICAgICAgICAiVGhlIGZvcm1hdCBvZiBtZXNzYWdlICciCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBtc2dLZXkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICArICInIGluIG1lc3NhZ2UgY2xhc3MgJyIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICArIG1fcmVzb3VyY2VCdW5kbGVOYW1lCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiJyBmYWlsZWQuIjsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICAgICAgZm1zZyA9IG1zZzsKLQotICAgICAgICBpZiAodGhyb3dleCkKLSAgICAgICAgewotICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZm1zZyk7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gZm1zZzsKLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvdXRpbHMvTXNnS2V5LmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL3V0aWxzL01zZ0tleS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhNGI2NmFlLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvdXRpbHMvTXNnS2V5LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMDIgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IE1zZ0tleS5qYXZhLHYgMS4xLjQuMSAyMDA1LzA5LzA4IDExOjAzOjExIHN1cmVzaF9lbWFpbGlkIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyLnV0aWxzOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgaXMgbm90IGEgcHVibGljIEFQSSwKLSAqIEl0IGlzIHVzZWQgaW50ZXJuYWxseSBieSBzZXJpYWxpemVyIGFuZCBpcyBwdWJsaWMsCi0gKiBpbiB0aGUgSmF2YSBzZW5zZSwgb25seSBiZWNhdXNlIGl0cyB1c2UgY3Jvc3NlcwotICogcGFja2FnZSBib3VuZGFyaWVzLgotICogPHA+Ci0gKiBUaGlzIGNsYXNzIGhvbGRzIG9ubHkgdGhlIG1lc3NhZ2Uga2V5cyB1c2VkCi0gKiB3aGVuIGdlbmVyYXRpbmcgbWVzc2FnZXMuCi0gKi8KLXB1YmxpYyBjbGFzcyBNc2dLZXkgewotCi0gICAgLyoqIEFuIGludGVybmFsIGVycm9yIHdpdGggdGhlIG1lc3NhZ2VzLAotICAgICAqIHRoaXMgaXMgdGhlIG1lc3NhZ2UgdG8gdXNlIGlmIHRoZSBtZXNzYWdlIGtleSBjYW4ndCBiZSBmb3VuZAotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEJBRF9NU0dLRVkgPSAiQkFEX01TR0tFWSI7Ci0KLSAgICAvKioKLSAgICAgKiBBbiBpbnRlcm5hbCBlcnJvciB3aXRoIHRoZSBtZXNzYWdlcywKLSAgICAgKiB0aGlzIGlzIHRoZSBtZXNzYWdlIHRvIHVzZSBpZiB0aGUgbWVzc2FnZSBmb3JtYXQgb3BlcmF0aW9uIGZhaWxlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBCQURfTVNHRk9STUFUID0gIkJBRF9NU0dGT1JNQVQiOwotCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUkVTT1VSQ0VfQ09VTERfTk9UX0ZJTkQgPQotICAgICAgICAiRVJfUkVTT1VSQ0VfQ09VTERfTk9UX0ZJTkQiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1JFU09VUkNFX0NPVUxEX05PVF9MT0FEID0KLSAgICAgICAgIkVSX1JFU09VUkNFX0NPVUxEX05PVF9MT0FEIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9CVUZGRVJfU0laRV9MRVNTVEhBTl9aRVJPID0KLSAgICAgICAgIkVSX0JVRkZFUl9TSVpFX0xFU1NUSEFOX1pFUk8iOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfVVRGMTZfU1VSUk9HQVRFID0KLSAgICAgICAgIkVSX0lOVkFMSURfVVRGMTZfU1VSUk9HQVRFIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9PSUVSUk9SID0gIkVSX09JRVJST1IiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05BTUVTUEFDRV9QUkVGSVggPSAiRVJfTkFNRVNQQUNFX1BSRUZJWCI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU1RSQVlfQVRUUklCVVRFID0gIkVSX1NUUkFZX0FUVFJJQlVURSI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU1RSQVlfTkFNRVNQQUNFID0gIkVSX1NUUkFZX05BTUVTUEFDRSI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTERfTk9UX0xPQURfUkVTT1VSQ0UgPQotICAgICAgICAiRVJfQ09VTERfTk9UX0xPQURfUkVTT1VSQ0UiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxEX05PVF9MT0FEX01FVEhPRF9QUk9QRVJUWSA9Ci0gICAgICAgICJFUl9DT1VMRF9OT1RfTE9BRF9NRVRIT0RfUFJPUEVSVFkiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NFUklBTElaRVJfTk9UX0NPTlRFTlRIQU5ETEVSID0KLSAgICAgICAgIkVSX1NFUklBTElaRVJfTk9UX0NPTlRFTlRIQU5ETEVSIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTExFR0FMX0FUVFJJQlVURV9QT1NJVElPTiA9Ci0gICAgICAgICJFUl9JTExFR0FMX0FUVFJJQlVURV9QT1NJVElPTiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSUxMRUdBTF9DSEFSQUNURVIgPSAiRVJfSUxMRUdBTF9DSEFSQUNURVIiOwotCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9QT1JUID0gIkVSX0lOVkFMSURfUE9SVCI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUE9SVF9XSEVOX0hPU1RfTlVMTCA9Ci0gICAgICAgICJFUl9QT1JUX1dIRU5fSE9TVF9OVUxMIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9IT1NUX0FERFJFU1NfTk9UX1dFTExGT1JNRUQgPQotICAgICAgICAiRVJfSE9TVF9BRERSRVNTX05PVF9XRUxMRk9STUVEIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TQ0hFTUVfTk9UX0NPTkZPUk1BTlQgPQotICAgICAgICAiRVJfU0NIRU1FX05PVF9DT05GT1JNQU5UIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TQ0hFTUVfRlJPTV9OVUxMX1NUUklORyA9Ci0gICAgICAgICJFUl9TQ0hFTUVfRlJPTV9OVUxMX1NUUklORyI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUEFUSF9DT05UQUlOU19JTlZBTElEX0VTQ0FQRV9TRVFVRU5DRSA9Ci0gICAgICAgICJFUl9QQVRIX0NPTlRBSU5TX0lOVkFMSURfRVNDQVBFX1NFUVVFTkNFIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QQVRIX0lOVkFMSURfQ0hBUiA9ICJFUl9QQVRIX0lOVkFMSURfQ0hBUiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fU0NIRU1FX0lOVVJJID0gIkVSX05PX1NDSEVNRV9JTlVSSSI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRlJBR19JTlZBTElEX0NIQVIgPSAiRVJfRlJBR19JTlZBTElEX0NIQVIiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZSQUdfV0hFTl9QQVRIX05VTEwgPQotICAgICAgICAiRVJfRlJBR19XSEVOX1BBVEhfTlVMTCI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRlJBR19GT1JfR0VORVJJQ19VUkkgPQotICAgICAgICAiRVJfRlJBR19GT1JfR0VORVJJQ19VUkkiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1NDSEVNRV9JTl9VUkkgPSAiRVJfTk9fU0NIRU1FX0lOX1VSSSI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX0lOSVRfVVJJX0VNUFRZX1BBUk1TID0KLSAgICAgICAgIkVSX0NBTk5PVF9JTklUX1VSSV9FTVBUWV9QQVJNUyI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9fRlJBR01FTlRfU1RSSU5HX0lOX1BBVEggPQotICAgICAgICAiRVJfTk9fRlJBR01FTlRfU1RSSU5HX0lOX1BBVEgiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PX1FVRVJZX1NUUklOR19JTl9QQVRIID0KLSAgICAgICAgIkVSX05PX1FVRVJZX1NUUklOR19JTl9QQVRIIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19QT1JUX0lGX05PX0hPU1QgPSAiRVJfTk9fUE9SVF9JRl9OT19IT1NUIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT19VU0VSSU5GT19JRl9OT19IT1NUID0KLSAgICAgICAgIkVSX05PX1VTRVJJTkZPX0lGX05PX0hPU1QiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NDSEVNRV9SRVFVSVJFRCA9ICJFUl9TQ0hFTUVfUkVRVUlSRUQiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hNTF9WRVJTSU9OX05PVF9TVVBQT1JURUQgPSAiRVJfWE1MX1ZFUlNJT05fTk9UX1NVUFBPUlRFRCI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRkFDVE9SWV9QUk9QRVJUWV9NSVNTSU5HID0gIkVSX0ZBQ1RPUllfUFJPUEVSVFlfTUlTU0lORyI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRU5DT0RJTkdfTk9UX1NVUFBPUlRFRCA9ICJFUl9FTkNPRElOR19OT1RfU1VQUE9SVEVEIjsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci91dGlscy9TZXJpYWxpemVyTWVzc2FnZXMuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvdXRpbHMvU2VyaWFsaXplck1lc3NhZ2VzLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDg1ODg2ODYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci91dGlscy9TZXJpYWxpemVyTWVzc2FnZXMuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIwNSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXIudXRpbHM7Ci0KLWltcG9ydCBqYXZhLnV0aWwuTGlzdFJlc291cmNlQnVuZGxlOwotaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7Ci1pbXBvcnQgamF2YS51dGlsLk1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuUmVzb3VyY2VCdW5kbGU7Ci0KLS8qKgotICogQW4gaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcyBpcyBhIExpc3RSZXNvdXJjZUJ1bmRsZSB0aGF0Ci0gKiBoYXMgdGhlIHJlcXVpcmVkIGdldENvbnRlbnRzKCkgbWV0aG9kIHRoYXQgcmV0dXJucwotICogYW4gYXJyYXkgb2YgbWVzc2FnZS1rZXkvbWVzc2FnZSBhc3NvY2lhdGlvbnMuCi0gKiA8cD4KLSAqIFRoZSBtZXNzYWdlIGtleXMgYXJlIGRlZmluZWQgaW4ge0BsaW5rIE1zZ0tleX0uIFRoZQotICogbWVzc2FnZXMgdGhhdCB0aG9zZSBrZXlzIG1hcCB0byBhcmUgZGVmaW5lZCBoZXJlLgotICogPHA+Ci0gKiBUaGUgbWVzc2FnZXMgaW4gdGhlIEVuZ2xpc2ggdmVyc2lvbiBhcmUgaW50ZW5kZWQgdG8gYmUKLSAqIHRyYW5zbGF0ZWQuCi0gKgotICogVGhpcyBjbGFzcyBpcyBub3QgYSBwdWJsaWMgQVBJLCBpdCBpcyBvbmx5IHB1YmxpYyBiZWNhdXNlIGl0IGlzCi0gKiB1c2VkIGluIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplci4KLSAqCi0gKiBAeHNsLnVzYWdlIGludGVybmFsCi0gKi8KLXB1YmxpYyBjbGFzcyBTZXJpYWxpemVyTWVzc2FnZXMgZXh0ZW5kcyBMaXN0UmVzb3VyY2VCdW5kbGUgewotCi0gICAgLyoKLSAgICAgKiBUaGlzIGZpbGUgY29udGFpbnMgZXJyb3IgYW5kIHdhcm5pbmcgbWVzc2FnZXMgcmVsYXRlZCB0bwotICAgICAqIFNlcmlhbGl6ZXIgRXJyb3IgSGFuZGxpbmcuCi0gICAgICoKLSAgICAgKiAgR2VuZXJhbCBub3RlcyB0byB0cmFuc2xhdG9yczoKLQotICAgICAqICAxKSBBIHN0eWxlc2hlZXQgaXMgYSBkZXNjcmlwdGlvbiBvZiBob3cgdG8gdHJhbnNmb3JtIGFuIGlucHV0IFhNTCBkb2N1bWVudAotICAgICAqICAgICBpbnRvIGEgcmVzdWx0YW50IFhNTCBkb2N1bWVudCAob3IgSFRNTCBkb2N1bWVudCBvciB0ZXh0KS4gIFRoZQotICAgICAqICAgICBzdHlsZXNoZWV0IGl0c2VsZiBpcyBkZXNjcmliZWQgaW4gdGhlIGZvcm0gb2YgYW4gWE1MIGRvY3VtZW50LgotCi0gICAgICoKLSAgICAgKiAgMikgQW4gZWxlbWVudCBpcyBhIG1hcmstdXAgdGFnIGluIGFuIFhNTCBkb2N1bWVudDsgYW4gYXR0cmlidXRlIGlzIGEKLSAgICAgKiAgICAgbW9kaWZpZXIgb24gdGhlIHRhZy4gIEZvciBleGFtcGxlLCBpbiA8ZWxlbSBhdHRyPSd2YWwnIGF0dHIyPSd2YWwyJz4KLSAgICAgKiAgICAgImVsZW0iIGlzIGFuIGVsZW1lbnQgbmFtZSwgImF0dHIiIGFuZCAiYXR0cjIiIGFyZSBhdHRyaWJ1dGUgbmFtZXMgd2l0aAotICAgICAqICAgICB0aGUgdmFsdWVzICJ2YWwiIGFuZCAidmFsMiIsIHJlc3BlY3RpdmVseS4KLSAgICAgKgotICAgICAqICAzKSBBIG5hbWVzcGFjZSBkZWNsYXJhdGlvbiBpcyBhIHNwZWNpYWwgYXR0cmlidXRlIHRoYXQgaXMgdXNlZCB0byBhc3NvY2lhdGUKLSAgICAgKiAgICAgYSBwcmVmaXggd2l0aCBhIFVSSSAodGhlIG5hbWVzcGFjZSkuICBUaGUgbWVhbmluZ3Mgb2YgZWxlbWVudCBuYW1lcyBhbmQKLSAgICAgKiAgICAgYXR0cmlidXRlIG5hbWVzIHRoYXQgdXNlIHRoYXQgcHJlZml4IGFyZSBkZWZpbmVkIHdpdGggcmVzcGVjdCB0byB0aGF0Ci0gICAgICogICAgIG5hbWVzcGFjZS4KLSAgICAgKgotICAgICAqCi0gICAgICovCi0KLSAgICAvKiogVGhlIGxvb2t1cCB0YWJsZSBmb3IgZXJyb3IgbWVzc2FnZXMuICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0W11bXSBnZXRDb250ZW50cygpIHsKLSAgICAgICAgT2JqZWN0W11bXSBjb250ZW50cyA9IG5ldyBPYmplY3RbXVtdIHsKLSAgICAgICAgICAgIHsgICBNc2dLZXkuQkFEX01TR0tFWSwKLSAgICAgICAgICAgICAgICAiVGhlIG1lc3NhZ2Uga2V5ICcnezB9JycgaXMgbm90IGluIHRoZSBtZXNzYWdlIGNsYXNzICcnezF9JyciIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuQkFEX01TR0ZPUk1BVCwKLSAgICAgICAgICAgICAgICAiVGhlIGZvcm1hdCBvZiBtZXNzYWdlICcnezB9JycgaW4gbWVzc2FnZSBjbGFzcyAnJ3sxfScnIGZhaWxlZC4iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfU0VSSUFMSVpFUl9OT1RfQ09OVEVOVEhBTkRMRVIsCi0gICAgICAgICAgICAgICAgIlRoZSBzZXJpYWxpemVyIGNsYXNzICcnezB9JycgZG9lcyBub3QgaW1wbGVtZW50IG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyLiIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9SRVNPVVJDRV9DT1VMRF9OT1RfRklORCwKLSAgICAgICAgICAgICAgICAgICAgIlRoZSByZXNvdXJjZSBbIHswfSBdIGNvdWxkIG5vdCBiZSBmb3VuZC5cbiB7MX0iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfUkVTT1VSQ0VfQ09VTERfTk9UX0xPQUQsCi0gICAgICAgICAgICAgICAgICAgICJUaGUgcmVzb3VyY2UgWyB7MH0gXSBjb3VsZCBub3QgbG9hZDogezF9IFxuIHsyfSBcdCB7M30iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfQlVGRkVSX1NJWkVfTEVTU1RIQU5fWkVSTywKLSAgICAgICAgICAgICAgICAgICAgIkJ1ZmZlciBzaXplIDw9MCIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9JTlZBTElEX1VURjE2X1NVUlJPR0FURSwKLSAgICAgICAgICAgICAgICAgICAgIkludmFsaWQgVVRGLTE2IHN1cnJvZ2F0ZSBkZXRlY3RlZDogezB9ID8iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfT0lFUlJPUiwKLSAgICAgICAgICAgICAgICAiSU8gZXJyb3IiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfSUxMRUdBTF9BVFRSSUJVVEVfUE9TSVRJT04sCi0gICAgICAgICAgICAgICAgIkNhbm5vdCBhZGQgYXR0cmlidXRlIHswfSBhZnRlciBjaGlsZCBub2RlcyBvciBiZWZvcmUgYW4gZWxlbWVudCBpcyBwcm9kdWNlZC4gIEF0dHJpYnV0ZSB3aWxsIGJlIGlnbm9yZWQuIiB9LAotCi0gICAgICAgICAgICAvKgotICAgICAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IGNvbnRhaW5lZCBhIHJlZmVyZW5jZSB0byBhCi0gICAgICAgICAgICAgKiBuYW1lc3BhY2UgcHJlZml4IHRoYXQgd2FzIHVuZGVmaW5lZC4gIFRoZSB2YWx1ZSBvZiB0aGUgc3Vic3RpdHV0aW9uCi0gICAgICAgICAgICAgKiB0ZXh0IGlzIHRoZSBuYW1lIG9mIHRoZSBwcmVmaXguCi0gICAgICAgICAgICAgKi8KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfTkFNRVNQQUNFX1BSRUZJWCwKLSAgICAgICAgICAgICAgICAiTmFtZXNwYWNlIGZvciBwcmVmaXggJyd7MH0nJyBoYXMgbm90IGJlZW4gZGVjbGFyZWQuIiB9LAotCi0gICAgICAgICAgICAvKgotICAgICAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyByZXBvcnRlZCBpZiB0aGUgc3R5bGVzaGVldAotICAgICAgICAgICAgICogYmVpbmcgcHJvY2Vzc2VkIGF0dGVtcHRlZCB0byBjb25zdHJ1Y3QgYW4gWE1MIGRvY3VtZW50IHdpdGggYW4KLSAgICAgICAgICAgICAqIGF0dHJpYnV0ZSBpbiBhIHBsYWNlIG90aGVyIHRoYW4gb24gYW4gZWxlbWVudC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICAgICAgICogc3BlY2lmaWVzIHRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUuCi0gICAgICAgICAgICAgKi8KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfU1RSQVlfQVRUUklCVVRFLAotICAgICAgICAgICAgICAgICJBdHRyaWJ1dGUgJyd7MH0nJyBvdXRzaWRlIG9mIGVsZW1lbnQuIiB9LAotCi0gICAgICAgICAgICAvKgotICAgICAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFzIHdpdGggdGhlIHByZWNlZGluZyBtZXNzYWdlLCBhIG5hbWVzcGFjZQotICAgICAgICAgICAgICogZGVjbGFyYXRpb24gaGFzIHRoZSBmb3JtIG9mIGFuIGF0dHJpYnV0ZSBhbmQgaXMgb25seSBwZXJtaXR0ZWQgdG8KLSAgICAgICAgICAgICAqIGFwcGVhciBvbiBhbiBlbGVtZW50LiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHswfSBpcyB0aGUgbmFtZXNwYWNlCi0gICAgICAgICAgICAgKiBwcmVmaXggYW5kIHsxfSBpcyB0aGUgVVJJIHRoYXQgd2FzIGJlaW5nIHVzZWQgaW4gdGhlIGVycm9uZW91cwotICAgICAgICAgICAgICogbmFtZXNwYWNlIGRlY2xhcmF0aW9uLgotICAgICAgICAgICAgICovCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX1NUUkFZX05BTUVTUEFDRSwKLSAgICAgICAgICAgICAgICAiTmFtZXNwYWNlIGRlY2xhcmF0aW9uICcnezB9Jyc9Jyd7MX0nJyBvdXRzaWRlIG9mIGVsZW1lbnQuIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0NPVUxEX05PVF9MT0FEX1JFU09VUkNFLAotICAgICAgICAgICAgICAgICJDb3VsZCBub3QgbG9hZCAnJ3swfScnIChjaGVjayBDTEFTU1BBVEgpLCBub3cgdXNpbmcganVzdCB0aGUgZGVmYXVsdHMiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfSUxMRUdBTF9DSEFSQUNURVIsCi0gICAgICAgICAgICAgICAgIkF0dGVtcHQgdG8gb3V0cHV0IGNoYXJhY3RlciBvZiBpbnRlZ3JhbCB2YWx1ZSB7MH0gdGhhdCBpcyBub3QgcmVwcmVzZW50ZWQgaW4gc3BlY2lmaWVkIG91dHB1dCBlbmNvZGluZyBvZiB7MX0uIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0NPVUxEX05PVF9MT0FEX01FVEhPRF9QUk9QRVJUWSwKLSAgICAgICAgICAgICAgICAiQ291bGQgbm90IGxvYWQgdGhlIHByb3BlcnkgZmlsZSAnJ3swfScnIGZvciBvdXRwdXQgbWV0aG9kICcnezF9JycgKGNoZWNrIENMQVNTUEFUSCkiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfSU5WQUxJRF9QT1JULAotICAgICAgICAgICAgICAgICJJbnZhbGlkIHBvcnQgbnVtYmVyIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX1BPUlRfV0hFTl9IT1NUX05VTEwsCi0gICAgICAgICAgICAgICAgIlBvcnQgY2Fubm90IGJlIHNldCB3aGVuIGhvc3QgaXMgbnVsbCIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9IT1NUX0FERFJFU1NfTk9UX1dFTExGT1JNRUQsCi0gICAgICAgICAgICAgICAgIkhvc3QgaXMgbm90IGEgd2VsbCBmb3JtZWQgYWRkcmVzcyIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9TQ0hFTUVfTk9UX0NPTkZPUk1BTlQsCi0gICAgICAgICAgICAgICAgIlRoZSBzY2hlbWUgaXMgbm90IGNvbmZvcm1hbnQuIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX1NDSEVNRV9GUk9NX05VTExfU1RSSU5HLAotICAgICAgICAgICAgICAgICJDYW5ub3Qgc2V0IHNjaGVtZSBmcm9tIG51bGwgc3RyaW5nIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX1BBVEhfQ09OVEFJTlNfSU5WQUxJRF9FU0NBUEVfU0VRVUVOQ0UsCi0gICAgICAgICAgICAgICAgIlBhdGggY29udGFpbnMgaW52YWxpZCBlc2NhcGUgc2VxdWVuY2UiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfUEFUSF9JTlZBTElEX0NIQVIsCi0gICAgICAgICAgICAgICAgIlBhdGggY29udGFpbnMgaW52YWxpZCBjaGFyYWN0ZXI6IHswfSIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9GUkFHX0lOVkFMSURfQ0hBUiwKLSAgICAgICAgICAgICAgICAiRnJhZ21lbnQgY29udGFpbnMgaW52YWxpZCBjaGFyYWN0ZXIiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfRlJBR19XSEVOX1BBVEhfTlVMTCwKLSAgICAgICAgICAgICAgICAiRnJhZ21lbnQgY2Fubm90IGJlIHNldCB3aGVuIHBhdGggaXMgbnVsbCIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9GUkFHX0ZPUl9HRU5FUklDX1VSSSwKLSAgICAgICAgICAgICAgICAiRnJhZ21lbnQgY2FuIG9ubHkgYmUgc2V0IGZvciBhIGdlbmVyaWMgVVJJIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX05PX1NDSEVNRV9JTl9VUkksCi0gICAgICAgICAgICAgICAgIk5vIHNjaGVtZSBmb3VuZCBpbiBVUkkiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfQ0FOTk9UX0lOSVRfVVJJX0VNUFRZX1BBUk1TLAotICAgICAgICAgICAgICAgICJDYW5ub3QgaW5pdGlhbGl6ZSBVUkkgd2l0aCBlbXB0eSBwYXJhbWV0ZXJzIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX05PX0ZSQUdNRU5UX1NUUklOR19JTl9QQVRILAotICAgICAgICAgICAgICAgICJGcmFnbWVudCBjYW5ub3QgYmUgc3BlY2lmaWVkIGluIGJvdGggdGhlIHBhdGggYW5kIGZyYWdtZW50IiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX05PX1FVRVJZX1NUUklOR19JTl9QQVRILAotICAgICAgICAgICAgICAgICJRdWVyeSBzdHJpbmcgY2Fubm90IGJlIHNwZWNpZmllZCBpbiBwYXRoIGFuZCBxdWVyeSBzdHJpbmciIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfTk9fUE9SVF9JRl9OT19IT1NULAotICAgICAgICAgICAgICAgICJQb3J0IG1heSBub3QgYmUgc3BlY2lmaWVkIGlmIGhvc3QgaXMgbm90IHNwZWNpZmllZCIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9OT19VU0VSSU5GT19JRl9OT19IT1NULAotICAgICAgICAgICAgICAgICJVc2VyaW5mbyBtYXkgbm90IGJlIHNwZWNpZmllZCBpZiBob3N0IGlzIG5vdCBzcGVjaWZpZWQiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfWE1MX1ZFUlNJT05fTk9UX1NVUFBPUlRFRCwKLSAgICAgICAgICAgICAgICAiV2FybmluZzogIFRoZSB2ZXJzaW9uIG9mIHRoZSBvdXRwdXQgZG9jdW1lbnQgaXMgcmVxdWVzdGVkIHRvIGJlICcnezB9JycuICBUaGlzIHZlcnNpb24gb2YgWE1MIGlzIG5vdCBzdXBwb3J0ZWQuICBUaGUgdmVyc2lvbiBvZiB0aGUgb3V0cHV0IGRvY3VtZW50IHdpbGwgYmUgJycxLjAnJy4iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfU0NIRU1FX1JFUVVJUkVELAotICAgICAgICAgICAgICAgICJTY2hlbWUgaXMgcmVxdWlyZWQhIiB9LAotCi0gICAgICAgICAgICAvKgotICAgICAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSB3b3JkcyAnUHJvcGVydGllcycgYW5kCi0gICAgICAgICAgICAgKiAnU2VyaWFsaXplckZhY3RvcnknIGluIHRoaXMgbWVzc2FnZSBhcmUgSmF2YSBjbGFzcyBuYW1lcwotICAgICAgICAgICAgICogYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICAgICAgICAgICAqLwotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9GQUNUT1JZX1BST1BFUlRZX01JU1NJTkcsCi0gICAgICAgICAgICAgICAgIlRoZSBQcm9wZXJ0aWVzIG9iamVjdCBwYXNzZWQgdG8gdGhlIFNlcmlhbGl6ZXJGYWN0b3J5IGRvZXMgbm90IGhhdmUgYSAnJ3swfScnIHByb3BlcnR5LiIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9FTkNPRElOR19OT1RfU1VQUE9SVEVELAotICAgICAgICAgICAgICAgICJXYXJuaW5nOiAgVGhlIGVuY29kaW5nICcnezB9JycgaXMgbm90IHN1cHBvcnRlZCBieSB0aGUgSmF2YSBydW50aW1lLiIgfSwKLQotCi0gICAgICAgIH07Ci0KLSAgICAgICAgcmV0dXJuIGNvbnRlbnRzOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvdXRpbHMvU2VyaWFsaXplck1lc3NhZ2VzX2NhLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL3V0aWxzL1NlcmlhbGl6ZXJNZXNzYWdlc19jYS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1NTMzNzkzLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvdXRpbHMvU2VyaWFsaXplck1lc3NhZ2VzX2NhLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMzAgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogU2VyaWFsaXplck1lc3NhZ2VzX2NhLmphdmEsdiAxLjEuNC4xIDIwMDUvMDkvMDggMTE6MDM6MTEgc3VyZXNoX2VtYWlsaWQgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplci51dGlsczsKLQotaW1wb3J0IGphdmEudXRpbC5MaXN0UmVzb3VyY2VCdW5kbGU7Ci0KLXB1YmxpYyBjbGFzcyBTZXJpYWxpemVyTWVzc2FnZXNfY2EgZXh0ZW5kcyBMaXN0UmVzb3VyY2VCdW5kbGUgewotICBwdWJsaWMgT2JqZWN0W11bXSBnZXRDb250ZW50cygpIHsKLSAgICBPYmplY3RbXVtdIGNvbnRlbnRzID0gIG5ldyBPYmplY3RbXVtdIHsKLSAgICAgIHsgTXNnS2V5LkJBRF9NU0dLRVksCi0gICAgICAgICJUaGUgbWVzc2FnZSBrZXkgJyd7MH0nJyBpcyBub3QgaW4gdGhlIG1lc3NhZ2UgY2xhc3MgJyd7MX0nJyJ9LAotCi0gICAgICB7IE1zZ0tleS5CQURfTVNHRk9STUFULAotICAgICAgICAiVGhlIGZvcm1hdCBvZiBtZXNzYWdlICcnezB9JycgaW4gbWVzc2FnZSBjbGFzcyAnJ3sxfScnIGZhaWxlZC4ifSwKLQotICAgICAgeyBNc2dLZXkuRVJfU0VSSUFMSVpFUl9OT1RfQ09OVEVOVEhBTkRMRVIsCi0gICAgICAgICJUaGUgc2VyaWFsaXplciBjbGFzcyAnJ3swfScnIGRvZXMgbm90IGltcGxlbWVudCBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlci4ifSwKLQotICAgICAgeyBNc2dLZXkuRVJfUkVTT1VSQ0VfQ09VTERfTk9UX0ZJTkQsCi0gICAgICAgICJUaGUgcmVzb3VyY2UgWyB7MH0gXSBjb3VsZCBub3QgYmUgZm91bmQuXG4gezF9In0sCi0KLSAgICAgIHsgTXNnS2V5LkVSX1JFU09VUkNFX0NPVUxEX05PVF9MT0FELAotICAgICAgICAiVGhlIHJlc291cmNlIFsgezB9IF0gY291bGQgbm90IGxvYWQ6IHsxfSBcbiB7Mn0gXG4gezN9In0sCi0KLSAgICAgIHsgTXNnS2V5LkVSX0JVRkZFUl9TSVpFX0xFU1NUSEFOX1pFUk8sCi0gICAgICAgICJCdWZmZXIgc2l6ZSA8PTAifSwKLQotICAgICAgeyBNc2dLZXkuRVJfSU5WQUxJRF9VVEYxNl9TVVJST0dBVEUsCi0gICAgICAgICJJbnZhbGlkIFVURi0xNiBzdXJyb2dhdGUgZGV0ZWN0ZWQ6IHswfSA/In0sCi0KLSAgICAgIHsgTXNnS2V5LkVSX09JRVJST1IsCi0gICAgICAgICJJTyBlcnJvciJ9LAotCi0gICAgICB7IE1zZ0tleS5FUl9JTExFR0FMX0FUVFJJQlVURV9QT1NJVElPTiwKLSAgICAgICAgIkNhbm5vdCBhZGQgYXR0cmlidXRlIHswfSBhZnRlciBjaGlsZCBub2RlcyBvciBiZWZvcmUgYW4gZWxlbWVudCBpcyBwcm9kdWNlZC4gIEF0dHJpYnV0ZSB3aWxsIGJlIGlnbm9yZWQuIn0sCi0KLSAgICAgIHsgTXNnS2V5LkVSX05BTUVTUEFDRV9QUkVGSVgsCi0gICAgICAgICJOYW1lc3BhY2UgZm9yIHByZWZpeCAnJ3swfScnIGhhcyBub3QgYmVlbiBkZWNsYXJlZC4ifSwKLQotICAgICAgeyBNc2dLZXkuRVJfU1RSQVlfQVRUUklCVVRFLAotICAgICAgICAiQXR0cmlidXRlICcnezB9Jycgb3V0c2lkZSBvZiBlbGVtZW50LiJ9LAotCi0gICAgICB7IE1zZ0tleS5FUl9TVFJBWV9OQU1FU1BBQ0UsCi0gICAgICAgICJOYW1lc3BhY2UgZGVjbGFyYXRpb24gJyd7MH0nJz0nJ3sxfScnIG91dHNpZGUgb2YgZWxlbWVudC4ifSwKLQotICAgICAgeyBNc2dLZXkuRVJfQ09VTERfTk9UX0xPQURfUkVTT1VSQ0UsCi0gICAgICAgICJDb3VsZCBub3QgbG9hZCAnJ3swfScnIChjaGVjayBDTEFTU1BBVEgpLCBub3cgdXNpbmcganVzdCB0aGUgZGVmYXVsdHMifSwKLQotICAgICAgeyBNc2dLZXkuRVJfSUxMRUdBTF9DSEFSQUNURVIsCi0gICAgICAgICJBdHRlbXB0IHRvIG91dHB1dCBjaGFyYWN0ZXIgb2YgaW50ZWdyYWwgdmFsdWUgezB9IHRoYXQgaXMgbm90IHJlcHJlc2VudGVkIGluIHNwZWNpZmllZCBvdXRwdXQgZW5jb2Rpbmcgb2YgezF9LiJ9LAotCi0gICAgICB7IE1zZ0tleS5FUl9DT1VMRF9OT1RfTE9BRF9NRVRIT0RfUFJPUEVSVFksCi0gICAgICAgICJDb3VsZCBub3QgbG9hZCB0aGUgcHJvcGVyeSBmaWxlICcnezB9JycgZm9yIG91dHB1dCBtZXRob2QgJyd7MX0nJyAoY2hlY2sgQ0xBU1NQQVRIKSJ9LAotCi0gICAgICB7IE1zZ0tleS5FUl9JTlZBTElEX1BPUlQsCi0gICAgICAgICJJbnZhbGlkIHBvcnQgbnVtYmVyIn0sCi0KLSAgICAgIHsgTXNnS2V5LkVSX1BPUlRfV0hFTl9IT1NUX05VTEwsCi0gICAgICAgICJQb3J0IGNhbm5vdCBiZSBzZXQgd2hlbiBob3N0IGlzIG51bGwifSwKLQotICAgICAgeyBNc2dLZXkuRVJfSE9TVF9BRERSRVNTX05PVF9XRUxMRk9STUVELAotICAgICAgICAiSG9zdCBpcyBub3QgYSB3ZWxsIGZvcm1lZCBhZGRyZXNzIn0sCi0KLSAgICAgIHsgTXNnS2V5LkVSX1NDSEVNRV9OT1RfQ09ORk9STUFOVCwKLSAgICAgICAgIlRoZSBzY2hlbWUgaXMgbm90IGNvbmZvcm1hbnQuIn0sCi0KLSAgICAgIHsgTXNnS2V5LkVSX1NDSEVNRV9GUk9NX05VTExfU1RSSU5HLAotICAgICAgICAiQ2Fubm90IHNldCBzY2hlbWUgZnJvbSBudWxsIHN0cmluZyJ9LAotCi0gICAgICB7IE1zZ0tleS5FUl9QQVRIX0NPTlRBSU5TX0lOVkFMSURfRVNDQVBFX1NFUVVFTkNFLAotICAgICAgICAiUGF0aCBjb250YWlucyBpbnZhbGlkIGVzY2FwZSBzZXF1ZW5jZSJ9LAotCi0gICAgICB7IE1zZ0tleS5FUl9QQVRIX0lOVkFMSURfQ0hBUiwKLSAgICAgICAgIlBhdGggY29udGFpbnMgaW52YWxpZCBjaGFyYWN0ZXI6IHswfSJ9LAotCi0gICAgICB7IE1zZ0tleS5FUl9GUkFHX0lOVkFMSURfQ0hBUiwKLSAgICAgICAgIkZyYWdtZW50IGNvbnRhaW5zIGludmFsaWQgY2hhcmFjdGVyIn0sCi0KLSAgICAgIHsgTXNnS2V5LkVSX0ZSQUdfV0hFTl9QQVRIX05VTEwsCi0gICAgICAgICJGcmFnbWVudCBjYW5ub3QgYmUgc2V0IHdoZW4gcGF0aCBpcyBudWxsIn0sCi0KLSAgICAgIHsgTXNnS2V5LkVSX0ZSQUdfRk9SX0dFTkVSSUNfVVJJLAotICAgICAgICAiRnJhZ21lbnQgY2FuIG9ubHkgYmUgc2V0IGZvciBhIGdlbmVyaWMgVVJJIn0sCi0KLSAgICAgIHsgTXNnS2V5LkVSX05PX1NDSEVNRV9JTl9VUkksCi0gICAgICAgICJObyBzY2hlbWUgZm91bmQgaW4gVVJJIn0sCi0KLSAgICAgIHsgTXNnS2V5LkVSX0NBTk5PVF9JTklUX1VSSV9FTVBUWV9QQVJNUywKLSAgICAgICAgIkNhbm5vdCBpbml0aWFsaXplIFVSSSB3aXRoIGVtcHR5IHBhcmFtZXRlcnMifSwKLQotICAgICAgeyBNc2dLZXkuRVJfTk9fRlJBR01FTlRfU1RSSU5HX0lOX1BBVEgsCi0gICAgICAgICJGcmFnbWVudCBjYW5ub3QgYmUgc3BlY2lmaWVkIGluIGJvdGggdGhlIHBhdGggYW5kIGZyYWdtZW50In0sCi0KLSAgICAgIHsgTXNnS2V5LkVSX05PX1FVRVJZX1NUUklOR19JTl9QQVRILAotICAgICAgICAiUXVlcnkgc3RyaW5nIGNhbm5vdCBiZSBzcGVjaWZpZWQgaW4gcGF0aCBhbmQgcXVlcnkgc3RyaW5nIn0sCi0KLSAgICAgIHsgTXNnS2V5LkVSX05PX1BPUlRfSUZfTk9fSE9TVCwKLSAgICAgICAgIlBvcnQgbWF5IG5vdCBiZSBzcGVjaWZpZWQgaWYgaG9zdCBpcyBub3Qgc3BlY2lmaWVkIn0sCi0KLSAgICAgIHsgTXNnS2V5LkVSX05PX1VTRVJJTkZPX0lGX05PX0hPU1QsCi0gICAgICAgICJVc2VyaW5mbyBtYXkgbm90IGJlIHNwZWNpZmllZCBpZiBob3N0IGlzIG5vdCBzcGVjaWZpZWQifSwKLQotICAgICAgeyBNc2dLZXkuRVJfU0NIRU1FX1JFUVVJUkVELAotICAgICAgICAiU2NoZW1lIGlzIHJlcXVpcmVkISJ9Ci0KLSAgICB9OwotICAgIHJldHVybiBjb250ZW50czsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci91dGlscy9TZXJpYWxpemVyTWVzc2FnZXNfY3MuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvdXRpbHMvU2VyaWFsaXplck1lc3NhZ2VzX2NzLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDVjNjk3N2MuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci91dGlscy9TZXJpYWxpemVyTWVzc2FnZXNfY3MuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEyMiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBTZXJpYWxpemVyTWVzc2FnZXNfY3MuamF2YSx2IDEuMS40LjEgMjAwNS8wOS8wOCAxMTowMzoxMiBzdXJlc2hfZW1haWxpZCBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyLnV0aWxzOwotCi1pbXBvcnQgamF2YS51dGlsLkxpc3RSZXNvdXJjZUJ1bmRsZTsKLQotcHVibGljIGNsYXNzIFNlcmlhbGl6ZXJNZXNzYWdlc19jcyBleHRlbmRzIExpc3RSZXNvdXJjZUJ1bmRsZSB7Ci0gIHB1YmxpYyBPYmplY3RbXVtdIGdldENvbnRlbnRzKCkgewotICAgIE9iamVjdFtdW10gY29udGVudHMgPSAgbmV3IE9iamVjdFtdW10gewotICAgICAgICAvLyBCQURfTVNHS0VZIG5lZWRzIHRyYW5zbGF0aW9uCi0gICAgICAgIC8vIEJBRF9NU0dGT1JNQVQgbmVlZHMgdHJhbnNsYXRpb24KLSAgICAgIHsgTXNnS2V5LkVSX1NFUklBTElaRVJfTk9UX0NPTlRFTlRIQU5ETEVSLAotICAgICAgICAiVFx1MDE1OVx1MDBlZGRhIHNlcmlhbGl6YWNlICcnezB9JycgbmVpbXBsZW1lbnR1amUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIuIn0sCi0KLSAgICAgIHsgTXNnS2V5LkVSX1JFU09VUkNFX0NPVUxEX05PVF9GSU5ELAotICAgICAgICAiTmVsemUgbmFqXHUwMGVkdCB6ZHJvaiBbIHswfSBdLlxuIHsxfSJ9LAotCi0gICAgICB7IE1zZ0tleS5FUl9SRVNPVVJDRV9DT1VMRF9OT1RfTE9BRCwKLSAgICAgICAgIk5lbHplIHphdlx1MDBlOXN0IHpkcm9qIFsgezB9IF06IHsxfSBcbiB7Mn0gXG4gezN9In0sCi0KLSAgICAgIHsgTXNnS2V5LkVSX0JVRkZFUl9TSVpFX0xFU1NUSEFOX1pFUk8sCi0gICAgICAgICJWZWxpa29zdCB2eXJvdm5cdTAwZTF2YWNcdTAwZWQgcGFtXHUwMTFidGkgPD0wIn0sCi0KLSAgICAgIHsgTXNnS2V5LkVSX0lOVkFMSURfVVRGMTZfU1VSUk9HQVRFLAotICAgICAgICAiQnlsYSB6amlcdTAxNjF0XHUwMTFibmEgbmVwbGF0blx1MDBlMSBuXHUwMGUxaHJhZGEgVVRGLTE2OiB7MH0gPyJ9LAotCi0gICAgICB7IE1zZ0tleS5FUl9PSUVSUk9SLAotICAgICAgICAiQ2h5YmEgdnN0dXB1L3ZcdTAwZmRzdHVwdSJ9LAotCi0gICAgICB7IE1zZ0tleS5FUl9JTExFR0FMX0FUVFJJQlVURV9QT1NJVElPTiwKLSAgICAgICAgIk5lbHplIHBcdTAxNTlpZGF0IGF0cmlidXQgezB9IHBvIHV6bGVjaCBwb3RvbWtcdTAxNmYgYW5pIHBcdTAxNTllZCB0XHUwMGVkbSwgbmVcdTAxN2UgamUgdnl0dm9cdTAxNTllbiBwcnZlay4gQXRyaWJ1dCBidWRlIGlnbm9yb3ZcdTAwZTFuLiJ9LAotCi0gICAgICB7IE1zZ0tleS5FUl9OQU1FU1BBQ0VfUFJFRklYLAotICAgICAgICAiT2JvciBuXHUwMGUxenZcdTAxNmYgcHJvIHBcdTAxNTllZHBvbnUgJyd7MH0nJyBuZWJ5bCBkZWtsYXJvdlx1MDBlMW4uIn0sCi0KLSAgICAgICAgLy8gRVJfU1RSQVlfQVRUUklCVVRFIG5lZWRzIHRyYW5zbGF0aW9uCi0gICAgICB7IE1zZ0tleS5FUl9TVFJBWV9OQU1FU1BBQ0UsCi0gICAgICAgICJEZWtsYXJhY2Ugb2JvcnUgblx1MDBlMXp2XHUwMTZmICcnezB9Jyc9Jyd7MX0nJyBqZSB2blx1MDExYiBwcnZrdS4ifSwKLQotICAgICAgeyBNc2dLZXkuRVJfQ09VTERfTk9UX0xPQURfUkVTT1VSQ0UsCi0gICAgICAgICJOZWx6ZSB6YXZcdTAwZTlzdCAnJ3swfScnICh6a29udHJvbHVqdGUgcHJvbVx1MDExYm5ub3UgQ0xBU1NQQVRIKSwgcHJvdG8gc2UgcG91XHUwMTdlXHUwMGVkdmFqXHUwMGVkIHBvdXplIHZcdTAwZmRjaG96XHUwMGVkIGhvZG5vdHkifSwKLQotICAgICAgICAvLyBFUl9JTExFR0FMX0NIQVJBQ1RFUiBuZWVkcyB0cmFuc2xhdGlvbgotICAgICAgeyBNc2dLZXkuRVJfQ09VTERfTk9UX0xPQURfTUVUSE9EX1BST1BFUlRZLAotICAgICAgICAiTmVsemUgbmFcdTAxMGRcdTAwZWRzdCBzb3Vib3Igdmxhc3Rub3N0XHUwMGVkICcnezB9JycgcHJvIHZcdTAwZmRzdHVwblx1MDBlZCBtZXRvZHUgJyd7MX0nJyAoemtvbnRyb2x1anRlIHByb21cdTAxMWJubm91IENMQVNTUEFUSCkuIn0sCi0KLSAgICAgIHsgTXNnS2V5LkVSX0lOVkFMSURfUE9SVCwKLSAgICAgICAgIk5lcGxhdG5cdTAwZTkgXHUwMTBkXHUwMGVkc2xvIHBvcnR1LiJ9LAotCi0gICAgICB7IE1zZ0tleS5FUl9QT1JUX1dIRU5fSE9TVF9OVUxMLAotICAgICAgICAiTVx1MDBlMS1saSBob3N0aXRlbCBob2Rub3R1IG51bGwsIG5lbHplIG5hc3Rhdml0IHBvcnQuIn0sCi0KLSAgICAgIHsgTXNnS2V5LkVSX0hPU1RfQUREUkVTU19OT1RfV0VMTEZPUk1FRCwKLSAgICAgICAgIkFkcmVzYSBob3N0aXRlbGUgbVx1MDBlMSBuZXNwclx1MDBlMXZuXHUwMGZkIGZvcm1cdTAwZTF0LiJ9LAotCi0gICAgICB7IE1zZ0tleS5FUl9TQ0hFTUVfTk9UX0NPTkZPUk1BTlQsCi0gICAgICAgICJTY2hcdTAwZTltYSBuZXZ5aG92dWplLiJ9LAotCi0gICAgICB7IE1zZ0tleS5FUl9TQ0hFTUVfRlJPTV9OVUxMX1NUUklORywKLSAgICAgICAgIk5lbHplIG5hc3Rhdml0IHNjaFx1MDBlOW1hIFx1MDE1OWV0XHUwMTFiemNlIHMgaG9kbm90b3UgbnVsbC4ifSwKLQotICAgICAgeyBNc2dLZXkuRVJfUEFUSF9DT05UQUlOU19JTlZBTElEX0VTQ0FQRV9TRVFVRU5DRSwKLSAgICAgICAgIkNlc3RhIG9ic2FodWplIG5lcGxhdG5vdSBlc2NhcGUgc2VrdmVuY2kifSwKLQotICAgICAgeyBNc2dLZXkuRVJfUEFUSF9JTlZBTElEX0NIQVIsCi0gICAgICAgICJDZXN0YSBvYnNhaHVqZSBuZXBsYXRuXHUwMGZkIHpuYWs6IHswfSJ9LAotCi0gICAgICB7IE1zZ0tleS5FUl9GUkFHX0lOVkFMSURfQ0hBUiwKLSAgICAgICAgIkZyYWdtZW50IG9ic2FodWplIG5lcGxhdG5cdTAwZmQgem5hay4ifSwKLQotICAgICAgeyBNc2dLZXkuRVJfRlJBR19XSEVOX1BBVEhfTlVMTCwKLSAgICAgICAgIk1cdTAwZTEtbGkgY2VzdGEgaG9kbm90dSBudWxsLCBuZWx6ZSBuYXN0YXZpdCBmcmFnbWVudC4ifSwKLQotICAgICAgeyBNc2dLZXkuRVJfRlJBR19GT1JfR0VORVJJQ19VUkksCi0gICAgICAgICJGcmFnbWVudCBsemUgbmFzdGF2aXQgamVuIHUgZ2VuZXJpY2tcdTAwZTlobyBVUkkuIn0sCi0KLSAgICAgIHsgTXNnS2V5LkVSX05PX1NDSEVNRV9JTl9VUkksCi0gICAgICAgICJWIFVSSSBuZWJ5bG8gbmFsZXplbm8gXHUwMTdlXHUwMGUxZG5cdTAwZTkgc2NoXHUwMGU5bWE6IHswfSJ9LAotCi0gICAgICB7IE1zZ0tleS5FUl9DQU5OT1RfSU5JVF9VUklfRU1QVFlfUEFSTVMsCi0gICAgICAgICJVUkkgbmVsemUgaW5pY2lhbGl6b3ZhdCBzIHByXHUwMGUxemRuXHUwMGZkbWkgcGFyYW1ldHJ5LiJ9LAotCi0gICAgICB7IE1zZ0tleS5FUl9OT19GUkFHTUVOVF9TVFJJTkdfSU5fUEFUSCwKLSAgICAgICAgIkZyYWdtZW50IG5lbHplIHVyXHUwMTBkaXQgelx1MDBlMXJvdmVcdTAxNDggdiBjZXN0XHUwMTFiIGkgdmUgZnJhZ21lbnR1LiJ9LAotCi0gICAgICB7IE1zZ0tleS5FUl9OT19RVUVSWV9TVFJJTkdfSU5fUEFUSCwKLSAgICAgICAgIlYgXHUwMTU5ZXRcdTAxMWJ6Y2kgY2VzdHkgYSBkb3RhenUgbmVsemUgemFkYXQgXHUwMTU5ZXRcdTAxMWJ6ZWMgZG90YXp1LiJ9LAotCi0gICAgICB7IE1zZ0tleS5FUl9OT19QT1JUX0lGX05PX0hPU1QsCi0gICAgICAgICJOZW5cdTAwZWQtbGkgdXJcdTAxMGRlbiBob3N0aXRlbCwgbmVsemUgemFkYXQgcG9ydC4ifSwKLQotICAgICAgeyBNc2dLZXkuRVJfTk9fVVNFUklORk9fSUZfTk9fSE9TVCwKLSAgICAgICAgIk5lblx1MDBlZC1saSB1clx1MDEwZGVuIGhvc3RpdGVsLCBuZWx6ZSB6YWRhdCBcdTAwZmFkYWplIG8gdVx1MDE3ZWl2YXRlbGkuIn0sCi0KLSAgICAgIHsgTXNnS2V5LkVSX1NDSEVNRV9SRVFVSVJFRCwKLSAgICAgICAgIkplIHZ5XHUwMTdlYWRvdlx1MDBlMW5vIHNjaFx1MDBlOW1hISJ9Ci0KLSAgICB9OwotICAgIHJldHVybiBjb250ZW50czsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci91dGlscy9TZXJpYWxpemVyTWVzc2FnZXNfZGUuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvdXRpbHMvU2VyaWFsaXplck1lc3NhZ2VzX2RlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDk1ZjZmM2YuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci91dGlscy9TZXJpYWxpemVyTWVzc2FnZXNfZGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIwNSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXIudXRpbHM7Ci0KLWltcG9ydCBqYXZhLnV0aWwuTGlzdFJlc291cmNlQnVuZGxlOwotaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7Ci1pbXBvcnQgamF2YS51dGlsLk1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuUmVzb3VyY2VCdW5kbGU7Ci0KLS8qKgotICogQW4gaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcyBpcyBhIExpc3RSZXNvdXJjZUJ1bmRsZSB0aGF0Ci0gKiBoYXMgdGhlIHJlcXVpcmVkIGdldENvbnRlbnRzKCkgbWV0aG9kIHRoYXQgcmV0dXJucwotICogYW4gYXJyYXkgb2YgbWVzc2FnZS1rZXkvbWVzc2FnZSBhc3NvY2lhdGlvbnMuCi0gKiA8cD4KLSAqIFRoZSBtZXNzYWdlIGtleXMgYXJlIGRlZmluZWQgaW4ge0BsaW5rIE1zZ0tleX0uIFRoZQotICogbWVzc2FnZXMgdGhhdCB0aG9zZSBrZXlzIG1hcCB0byBhcmUgZGVmaW5lZCBoZXJlLgotICogPHA+Ci0gKiBUaGUgbWVzc2FnZXMgaW4gdGhlIEVuZ2xpc2ggdmVyc2lvbiBhcmUgaW50ZW5kZWQgdG8gYmUKLSAqIHRyYW5zbGF0ZWQuCi0gKgotICogVGhpcyBjbGFzcyBpcyBub3QgYSBwdWJsaWMgQVBJLCBpdCBpcyBvbmx5IHB1YmxpYyBiZWNhdXNlIGl0IGlzCi0gKiB1c2VkIGluIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplci4KLSAqCi0gKiBAeHNsLnVzYWdlIGludGVybmFsCi0gKi8KLXB1YmxpYyBjbGFzcyBTZXJpYWxpemVyTWVzc2FnZXNfZGUgZXh0ZW5kcyBMaXN0UmVzb3VyY2VCdW5kbGUgewotCi0gICAgLyoKLSAgICAgKiBUaGlzIGZpbGUgY29udGFpbnMgZXJyb3IgYW5kIHdhcm5pbmcgbWVzc2FnZXMgcmVsYXRlZCB0bwotICAgICAqIFNlcmlhbGl6ZXIgRXJyb3IgSGFuZGxpbmcuCi0gICAgICoKLSAgICAgKiAgR2VuZXJhbCBub3RlcyB0byB0cmFuc2xhdG9yczoKLQotICAgICAqICAxKSBBIHN0eWxlc2hlZXQgaXMgYSBkZXNjcmlwdGlvbiBvZiBob3cgdG8gdHJhbnNmb3JtIGFuIGlucHV0IFhNTCBkb2N1bWVudAotICAgICAqICAgICBpbnRvIGEgcmVzdWx0YW50IFhNTCBkb2N1bWVudCAob3IgSFRNTCBkb2N1bWVudCBvciB0ZXh0KS4gIFRoZQotICAgICAqICAgICBzdHlsZXNoZWV0IGl0c2VsZiBpcyBkZXNjcmliZWQgaW4gdGhlIGZvcm0gb2YgYW4gWE1MIGRvY3VtZW50LgotCi0gICAgICoKLSAgICAgKiAgMikgQW4gZWxlbWVudCBpcyBhIG1hcmstdXAgdGFnIGluIGFuIFhNTCBkb2N1bWVudDsgYW4gYXR0cmlidXRlIGlzIGEKLSAgICAgKiAgICAgbW9kaWZpZXIgb24gdGhlIHRhZy4gIEZvciBleGFtcGxlLCBpbiA8ZWxlbSBhdHRyPSd2YWwnIGF0dHIyPSd2YWwyJz4KLSAgICAgKiAgICAgImVsZW0iIGlzIGFuIGVsZW1lbnQgbmFtZSwgImF0dHIiIGFuZCAiYXR0cjIiIGFyZSBhdHRyaWJ1dGUgbmFtZXMgd2l0aAotICAgICAqICAgICB0aGUgdmFsdWVzICJ2YWwiIGFuZCAidmFsMiIsIHJlc3BlY3RpdmVseS4KLSAgICAgKgotICAgICAqICAzKSBBIG5hbWVzcGFjZSBkZWNsYXJhdGlvbiBpcyBhIHNwZWNpYWwgYXR0cmlidXRlIHRoYXQgaXMgdXNlZCB0byBhc3NvY2lhdGUKLSAgICAgKiAgICAgYSBwcmVmaXggd2l0aCBhIFVSSSAodGhlIG5hbWVzcGFjZSkuICBUaGUgbWVhbmluZ3Mgb2YgZWxlbWVudCBuYW1lcyBhbmQKLSAgICAgKiAgICAgYXR0cmlidXRlIG5hbWVzIHRoYXQgdXNlIHRoYXQgcHJlZml4IGFyZSBkZWZpbmVkIHdpdGggcmVzcGVjdCB0byB0aGF0Ci0gICAgICogICAgIG5hbWVzcGFjZS4KLSAgICAgKgotICAgICAqCi0gICAgICovCi0KLSAgICAvKiogVGhlIGxvb2t1cCB0YWJsZSBmb3IgZXJyb3IgbWVzc2FnZXMuICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0W11bXSBnZXRDb250ZW50cygpIHsKLSAgICAgICAgT2JqZWN0W11bXSBjb250ZW50cyA9IG5ldyBPYmplY3RbXVtdIHsKLSAgICAgICAgICAgIHsgICBNc2dLZXkuQkFEX01TR0tFWSwKLSAgICAgICAgICAgICAgICAiRGVyIE5hY2hyaWNodGVuc2NobFx1MDBGQ3NzZWwgXCJ7MH1cIiBpc3QgbmljaHQgaW4gZGVyIE5hY2hyaWNodGVua2xhc3NlIFwiezF9XCIgZW50aGFsdGVuIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkJBRF9NU0dGT1JNQVQsCi0gICAgICAgICAgICAgICAgIkRhcyBGb3JtYXQgZGVyIE5hY2hyaWNodCBcInswfVwiIGluIGRlciBOYWNocmljaHRlbmtsYXNzZSBcInsxfVwiIHdhciBuaWNodCBlcmZvbGdyZWljaC4iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfU0VSSUFMSVpFUl9OT1RfQ09OVEVOVEhBTkRMRVIsCi0gICAgICAgICAgICAgICAgIlNlcmlhbGl6ZXItS2xhc3NlIFwiezB9XCIgaW1wbGVtZW50aWVydCBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciBuaWNodC4iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfUkVTT1VSQ0VfQ09VTERfTk9UX0ZJTkQsCi0gICAgICAgICAgICAgICAgICAgICJSZXNzb3VyY2UgWyB7MH0gXSBrb25udGUgbmljaHQgZ2VmdW5kZW4gd2VyZGVuLlxuIHsxfSIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9SRVNPVVJDRV9DT1VMRF9OT1RfTE9BRCwKLSAgICAgICAgICAgICAgICAgICAgIlJlc3NvdXJjZSBbIHswfSBdIGtvbm50ZSBuaWNodCBnZWxhZGVuIHdlcmRlbjogezF9IFxuIHsyfSBcdCB7M30iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfQlVGRkVSX1NJWkVfTEVTU1RIQU5fWkVSTywKLSAgICAgICAgICAgICAgICAgICAgIlB1ZmZlcmdyXHUwMEY2XHUwMERGZSA8PTAiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfSU5WQUxJRF9VVEYxNl9TVVJST0dBVEUsCi0gICAgICAgICAgICAgICAgICAgICJVbmdcdTAwRkNsdGlnZSBVVEYtMTYtRXJzZXR6dW5nIGZlc3RnZXN0ZWxsdDogezB9PyIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9PSUVSUk9SLAotICAgICAgICAgICAgICAgICJJL08tRmVobGVyIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0lMTEVHQUxfQVRUUklCVVRFX1BPU0lUSU9OLAotICAgICAgICAgICAgICAgICJBdHRyaWJ1dCB7MH0ga2FubiBuaWNodCBuYWNoIHVudGVyZ2VvcmRuZXRlbiBLbm90ZW4gb2RlciB2b3IgZGVtIEVyc3RlbGxlbiBlaW5lcyBFbGVtZW50cyBoaW56dWdlZlx1MDBGQ2d0IHdlcmRlbi4gQXR0cmlidXQgd2lyZCBpZ25vcmllcnQuIiB9LAotCi0gICAgICAgICAgICAvKgotICAgICAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IGNvbnRhaW5lZCBhIHJlZmVyZW5jZSB0byBhCi0gICAgICAgICAgICAgKiBuYW1lc3BhY2UgcHJlZml4IHRoYXQgd2FzIHVuZGVmaW5lZC4gIFRoZSB2YWx1ZSBvZiB0aGUgc3Vic3RpdHV0aW9uCi0gICAgICAgICAgICAgKiB0ZXh0IGlzIHRoZSBuYW1lIG9mIHRoZSBwcmVmaXguCi0gICAgICAgICAgICAgKi8KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfTkFNRVNQQUNFX1BSRUZJWCwKLSAgICAgICAgICAgICAgICAiTmFtZXNwYWNlIGZcdTAwRkNyIFByXHUwMEU0Zml4IFwiezB9XCIgd3VyZGUgbmljaHQgZGVrbGFyaWVydC4iIH0sCi0KLSAgICAgICAgICAgIC8qCi0gICAgICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIHJlcG9ydGVkIGlmIHRoZSBzdHlsZXNoZWV0Ci0gICAgICAgICAgICAgKiBiZWluZyBwcm9jZXNzZWQgYXR0ZW1wdGVkIHRvIGNvbnN0cnVjdCBhbiBYTUwgZG9jdW1lbnQgd2l0aCBhbgotICAgICAgICAgICAgICogYXR0cmlidXRlIGluIGEgcGxhY2Ugb3RoZXIgdGhhbiBvbiBhbiBlbGVtZW50LiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgICAgICAgKiBzcGVjaWZpZXMgdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgICAgICAgICAqLwotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9TVFJBWV9BVFRSSUJVVEUsCi0gICAgICAgICAgICAgICAgIkF0dHJpYnV0IFwiezB9XCIgYXVcdTAwREZlcmhhbGIgZGVzIEVsZW1lbnRzLiIgfSwKLQotICAgICAgICAgICAgLyoKLSAgICAgICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBcyB3aXRoIHRoZSBwcmVjZWRpbmcgbWVzc2FnZSwgYSBuYW1lc3BhY2UKLSAgICAgICAgICAgICAqIGRlY2xhcmF0aW9uIGhhcyB0aGUgZm9ybSBvZiBhbiBhdHRyaWJ1dGUgYW5kIGlzIG9ubHkgcGVybWl0dGVkIHRvCi0gICAgICAgICAgICAgKiBhcHBlYXIgb24gYW4gZWxlbWVudC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCB7MH0gaXMgdGhlIG5hbWVzcGFjZQotICAgICAgICAgICAgICogcHJlZml4IGFuZCB7MX0gaXMgdGhlIFVSSSB0aGF0IHdhcyBiZWluZyB1c2VkIGluIHRoZSBlcnJvbmVvdXMKLSAgICAgICAgICAgICAqIG5hbWVzcGFjZSBkZWNsYXJhdGlvbi4KLSAgICAgICAgICAgICAqLwotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9TVFJBWV9OQU1FU1BBQ0UsCi0gICAgICAgICAgICAgICAgIk5hbWVzcGFjZS1EZWtsYXJhdGlvbiB7MH09ezF9IGF1XHUwMERGZXJoYWxiIGRlcyBFbGVtZW50cy4iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfQ09VTERfTk9UX0xPQURfUkVTT1VSQ0UsCi0gICAgICAgICAgICAgICAgIlwiezB9XCIga29ubnRlIG5pY2h0IGdlbGFkZW4gd2VyZGVuIChDTEFTU1BBVEggcHJcdTAwRkNmZW4pLiBEaWUgU3RhbmRhcmR3ZXJ0ZSB3ZXJkZW4gdmVyd2VuZGV0IiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0lMTEVHQUxfQ0hBUkFDVEVSLAotICAgICAgICAgICAgICAgICJWZXJzdWNoLCBaZWljaGVuIG1pdCBJbnRlZ3JhbHdlcnQgezB9IGF1c3p1Z2ViZW4sIGRhcyBuaWNodCBpbiBkZXIgc3BlemllbGxlbiBBdXNnYWJlY29kaWVydW5nIHZvbiB7MX0gZGFyZ2VzdGVsbHQgd2lyZC4iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfQ09VTERfTk9UX0xPQURfTUVUSE9EX1BST1BFUlRZLAotICAgICAgICAgICAgICAgICJQcm9wZXJ0eS1EYXRlaSBcInswfVwiIGtvbm50ZSBmXHUwMEZDciBBdXNnYWJlbWV0aG9kZSBcInsxfVwiIG5pY2h0IGdlbGFkZW4gd2VyZGVuIChDTEFTU1BBVEggcHJcdTAwRkNmZW4pIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0lOVkFMSURfUE9SVCwKLSAgICAgICAgICAgICAgICAiVW5nXHUwMEZDbHRpZ2UgUG9ydG51bW1lciIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9QT1JUX1dIRU5fSE9TVF9OVUxMLAotICAgICAgICAgICAgICAgICJQb3J0IGthbm4gbmljaHQgZmVzdGdlbGVndCB3ZXJkZW4sIHdlbm4gZGVyIEhvc3QgbnVsbCBpc3QiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfSE9TVF9BRERSRVNTX05PVF9XRUxMRk9STUVELAotICAgICAgICAgICAgICAgICJIb3N0IGlzdCBrZWluZSB3b2hsZ2Vmb3JtdGUgQWRyZXNzZSIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9TQ0hFTUVfTk9UX0NPTkZPUk1BTlQsCi0gICAgICAgICAgICAgICAgIlNjaGVtYSBpc3QgbmljaHQga29uZm9ybS4iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfU0NIRU1FX0ZST01fTlVMTF9TVFJJTkcsCi0gICAgICAgICAgICAgICAgIlNjaGVtYSBrYW5uIG5pY2h0IHZvbiBOdWxsemVpY2hlbmZvbGdlIGZlc3RnZWxlZ3Qgd2VyZGVuIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX1BBVEhfQ09OVEFJTlNfSU5WQUxJRF9FU0NBUEVfU0VRVUVOQ0UsCi0gICAgICAgICAgICAgICAgIlBmYWQgZW50aFx1MDBFNGx0IGVpbmUgdW5nXHUwMEZDbHRpZ2UgRXNjYXBlc2VxdWVueiIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9QQVRIX0lOVkFMSURfQ0hBUiwKLSAgICAgICAgICAgICAgICAiUGZhZCBlbnRoXHUwMEU0bHQgdW5nXHUwMEZDbHRpZ2VzIFplaWNoZW46IHswfSIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9GUkFHX0lOVkFMSURfQ0hBUiwKLSAgICAgICAgICAgICAgICAiRnJhZ21lbnQgZW50aFx1MDBFNGx0IGVpbiB1bmdcdTAwRkNsdGlnZXMgWmVpY2hlbiIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9GUkFHX1dIRU5fUEFUSF9OVUxMLAotICAgICAgICAgICAgICAgICJGcmFnbWVudCBrYW5uIG5pY2h0IGZlc3RnZWxlZ3Qgd2VyZGVuLCB3ZW5uIGRlciBQZmFkIG51bGwgaXN0IiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0ZSQUdfRk9SX0dFTkVSSUNfVVJJLAotICAgICAgICAgICAgICAgICJGcmFnbWVudCBrYW5uIG51ciBmXHUwMEZDciBlaW5lbiBnZW5lcmlzY2hlbiBVUkkgZmVzdGdlbGVndCB3ZXJkZW4iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfTk9fU0NIRU1FX0lOX1VSSSwKLSAgICAgICAgICAgICAgICAiS2VpbiBTY2hlbWEgZ2VmdW5kZW4gaW4gVVJJIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0NBTk5PVF9JTklUX1VSSV9FTVBUWV9QQVJNUywKLSAgICAgICAgICAgICAgICAiVVJJIGthbm4gbmljaHQgbWl0IGxlZXJlbiBQYXJhbWV0ZXJuIGluaXRpYWxpc2llcnQgd2VyZGVuIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX05PX0ZSQUdNRU5UX1NUUklOR19JTl9QQVRILAotICAgICAgICAgICAgICAgICJGcmFnbWVudCBrYW5uIG5pY2h0IGltIFBmYWQgdW5kIGltIEZyYWdtZW50IGFuZ2VnZWJlbiB3ZXJkZW4iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfTk9fUVVFUllfU1RSSU5HX0lOX1BBVEgsCi0gICAgICAgICAgICAgICAgIkFiZnJhZ2V6ZWljaGVuZm9sZ2Uga2FubiBuaWNodCBpbSBQZmFkIHVuZCBpbiBkZXIgQWJmcmFnZXplaWNoZW5mb2xnZSBhbmdlZ2ViZW4gd2VyZGVuIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX05PX1BPUlRfSUZfTk9fSE9TVCwKLSAgICAgICAgICAgICAgICAiUG9ydCBrYW5uIG5pY2h0IGFuZ2VnZWJlbiB3ZXJkZW4sIHdlbm4gZGVyIEhvc3QgbmljaHQgYW5nZWdlYmVuIHd1cmRlIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX05PX1VTRVJJTkZPX0lGX05PX0hPU1QsCi0gICAgICAgICAgICAgICAgIkJlbnV0emVyaW5mb3JtYXRpb25lbiBrXHUwMEY2bm5lbiBuaWNodCBhbmdlZ2ViZW4gd2VyZGVuLCB3ZW5uIGRlciBIb3N0IG5pY2h0IGFuZ2VnZWJlbiB3dXJkZSIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9YTUxfVkVSU0lPTl9OT1RfU1VQUE9SVEVELAotICAgICAgICAgICAgICAgICJXYXJudW5nOiBEaWUgVmVyc2lvbiBkZXMgQXVzZ2FiZWRva3VtZW50cyBzb2xsIFwiezB9XCIgc2Vpbi4gRGllc2UgVmVyc2lvbiB2b24gWE1MIHdpcmQgbmljaHQgdW50ZXJzdFx1MDBGQ3R6dC4gRGllIFZlcnNpb24gZGVzIEF1c2dhYmVkb2t1bWVudHMgd2lyZCBcIjEuMFwiIHNlaW4uIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX1NDSEVNRV9SRVFVSVJFRCwKLSAgICAgICAgICAgICAgICAiU2NoZW1hIGlzdCBlcmZvcmRlcmxpY2guIiB9LAotCi0gICAgICAgICAgICAvKgotICAgICAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSB3b3JkcyAnUHJvcGVydGllcycgYW5kCi0gICAgICAgICAgICAgKiAnU2VyaWFsaXplckZhY3RvcnknIGluIHRoaXMgbWVzc2FnZSBhcmUgSmF2YSBjbGFzcyBuYW1lcwotICAgICAgICAgICAgICogYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICAgICAgICAgICAqLwotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9GQUNUT1JZX1BST1BFUlRZX01JU1NJTkcsCi0gICAgICAgICAgICAgICAgIkRhcyBhbiBkaWUgU2VyaWFsaXplckZhY3RvcnkgXHUwMEZDYmVyZ2ViZW5lIFByb3BlcnRpZXMtT2JqZWt0IHZlcmZcdTAwRkNndCBcdTAwRkNiZXIga2VpbmUgRWlnZW5zY2hhZnQgXCJ7MH1cIi4iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfRU5DT0RJTkdfTk9UX1NVUFBPUlRFRCwKLSAgICAgICAgICAgICAgICAiV2FybnVuZzogRGllIENvZGllcnVuZyBcInswfVwiIHdpcmQgbmljaHQgdm9uIGRlciBKYXZhLUxhdWZ6ZWl0IHVudGVyc3RcdTAwRkN0enQuIiB9LAotCi0KLSAgICAgICAgfTsKLQotICAgICAgICByZXR1cm4gY29udGVudHM7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci91dGlscy9TZXJpYWxpemVyTWVzc2FnZXNfZW4uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvdXRpbHMvU2VyaWFsaXplck1lc3NhZ2VzX2VuLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDM3ODlhMTcuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci91dGlscy9TZXJpYWxpemVyTWVzc2FnZXNfZW4uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDMyICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBTZXJpYWxpemVyTWVzc2FnZXNfZW4uamF2YSx2IDEuMS40LjEgMjAwNS8wOS8wOCAxMTowMzoxMyBzdXJlc2hfZW1haWxpZCBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplci51dGlsczsKLQotCi0vKioKLSAqIERlZmF1bHQgaW1wbGVtZW50YXRpb24uICBUaGlzIGlzIGp1c3QgYW4gZW1wdHkgY2xhc3MuCi0gKiBAeHNsLnVzYWdlIGludGVybmFsCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBTZXJpYWxpemVyTWVzc2FnZXNfZW4gZXh0ZW5kcyBTZXJpYWxpemVyTWVzc2FnZXMKLXsKLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvdXRpbHMvU2VyaWFsaXplck1lc3NhZ2VzX2VzLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL3V0aWxzL1NlcmlhbGl6ZXJNZXNzYWdlc19lcy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1N2U4MDFlLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvdXRpbHMvU2VyaWFsaXplck1lc3NhZ2VzX2VzLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMDUgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyLnV0aWxzOwotCi1pbXBvcnQgamF2YS51dGlsLkxpc3RSZXNvdXJjZUJ1bmRsZTsKLWltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwotaW1wb3J0IGphdmEudXRpbC5NaXNzaW5nUmVzb3VyY2VFeGNlcHRpb247Ci1pbXBvcnQgamF2YS51dGlsLlJlc291cmNlQnVuZGxlOwotCi0vKioKLSAqIEFuIGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgaXMgYSBMaXN0UmVzb3VyY2VCdW5kbGUgdGhhdAotICogaGFzIHRoZSByZXF1aXJlZCBnZXRDb250ZW50cygpIG1ldGhvZCB0aGF0IHJldHVybnMKLSAqIGFuIGFycmF5IG9mIG1lc3NhZ2Uta2V5L21lc3NhZ2UgYXNzb2NpYXRpb25zLgotICogPHA+Ci0gKiBUaGUgbWVzc2FnZSBrZXlzIGFyZSBkZWZpbmVkIGluIHtAbGluayBNc2dLZXl9LiBUaGUKLSAqIG1lc3NhZ2VzIHRoYXQgdGhvc2Uga2V5cyBtYXAgdG8gYXJlIGRlZmluZWQgaGVyZS4KLSAqIDxwPgotICogVGhlIG1lc3NhZ2VzIGluIHRoZSBFbmdsaXNoIHZlcnNpb24gYXJlIGludGVuZGVkIHRvIGJlCi0gKiB0cmFuc2xhdGVkLgotICoKLSAqIFRoaXMgY2xhc3MgaXMgbm90IGEgcHVibGljIEFQSSwgaXQgaXMgb25seSBwdWJsaWMgYmVjYXVzZSBpdCBpcwotICogdXNlZCBpbiBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXIuCi0gKgotICogQHhzbC51c2FnZSBpbnRlcm5hbAotICovCi1wdWJsaWMgY2xhc3MgU2VyaWFsaXplck1lc3NhZ2VzX2VzIGV4dGVuZHMgTGlzdFJlc291cmNlQnVuZGxlIHsKLQotICAgIC8qCi0gICAgICogVGhpcyBmaWxlIGNvbnRhaW5zIGVycm9yIGFuZCB3YXJuaW5nIG1lc3NhZ2VzIHJlbGF0ZWQgdG8KLSAgICAgKiBTZXJpYWxpemVyIEVycm9yIEhhbmRsaW5nLgotICAgICAqCi0gICAgICogIEdlbmVyYWwgbm90ZXMgdG8gdHJhbnNsYXRvcnM6Ci0KLSAgICAgKiAgMSkgQSBzdHlsZXNoZWV0IGlzIGEgZGVzY3JpcHRpb24gb2YgaG93IHRvIHRyYW5zZm9ybSBhbiBpbnB1dCBYTUwgZG9jdW1lbnQKLSAgICAgKiAgICAgaW50byBhIHJlc3VsdGFudCBYTUwgZG9jdW1lbnQgKG9yIEhUTUwgZG9jdW1lbnQgb3IgdGV4dCkuICBUaGUKLSAgICAgKiAgICAgc3R5bGVzaGVldCBpdHNlbGYgaXMgZGVzY3JpYmVkIGluIHRoZSBmb3JtIG9mIGFuIFhNTCBkb2N1bWVudC4KLQotICAgICAqCi0gICAgICogIDIpIEFuIGVsZW1lbnQgaXMgYSBtYXJrLXVwIHRhZyBpbiBhbiBYTUwgZG9jdW1lbnQ7IGFuIGF0dHJpYnV0ZSBpcyBhCi0gICAgICogICAgIG1vZGlmaWVyIG9uIHRoZSB0YWcuICBGb3IgZXhhbXBsZSwgaW4gPGVsZW0gYXR0cj0ndmFsJyBhdHRyMj0ndmFsMic+Ci0gICAgICogICAgICJlbGVtIiBpcyBhbiBlbGVtZW50IG5hbWUsICJhdHRyIiBhbmQgImF0dHIyIiBhcmUgYXR0cmlidXRlIG5hbWVzIHdpdGgKLSAgICAgKiAgICAgdGhlIHZhbHVlcyAidmFsIiBhbmQgInZhbDIiLCByZXNwZWN0aXZlbHkuCi0gICAgICoKLSAgICAgKiAgMykgQSBuYW1lc3BhY2UgZGVjbGFyYXRpb24gaXMgYSBzcGVjaWFsIGF0dHJpYnV0ZSB0aGF0IGlzIHVzZWQgdG8gYXNzb2NpYXRlCi0gICAgICogICAgIGEgcHJlZml4IHdpdGggYSBVUkkgKHRoZSBuYW1lc3BhY2UpLiAgVGhlIG1lYW5pbmdzIG9mIGVsZW1lbnQgbmFtZXMgYW5kCi0gICAgICogICAgIGF0dHJpYnV0ZSBuYW1lcyB0aGF0IHVzZSB0aGF0IHByZWZpeCBhcmUgZGVmaW5lZCB3aXRoIHJlc3BlY3QgdG8gdGhhdAotICAgICAqICAgICBuYW1lc3BhY2UuCi0gICAgICoKLSAgICAgKgotICAgICAqLwotCi0gICAgLyoqIFRoZSBsb29rdXAgdGFibGUgZm9yIGVycm9yIG1lc3NhZ2VzLiAgICovCi0gICAgcHVibGljIE9iamVjdFtdW10gZ2V0Q29udGVudHMoKSB7Ci0gICAgICAgIE9iamVjdFtdW10gY29udGVudHMgPSBuZXcgT2JqZWN0W11bXSB7Ci0gICAgICAgICAgICB7ICAgTXNnS2V5LkJBRF9NU0dLRVksCi0gICAgICAgICAgICAgICAgIkxhIGNsYXZlIGRlIG1lbnNhamUgJyd7MH0nJyBubyBlc3RcdTAwRTEgZW4gbGEgY2xhc2UgZGUgbWVuc2FqZSAnJ3sxfScnIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkJBRF9NU0dGT1JNQVQsCi0gICAgICAgICAgICAgICAgIkZhbGxvIGRlIGZvcm1hdG8gZGVsIG1lbnNhamUgJyd7MH0nJyBlbiBsYSBjbGFzZSBkZSBtZW5zYWplICcnezF9JycuIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX1NFUklBTElaRVJfTk9UX0NPTlRFTlRIQU5ETEVSLAotICAgICAgICAgICAgICAgICJMYSBjbGFzZSBkZSBzZXJpYWxpemFkb3IgJyd7MH0nJyBubyBpbXBsYW50YSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlci4iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfUkVTT1VSQ0VfQ09VTERfTk9UX0ZJTkQsCi0gICAgICAgICAgICAgICAgICAgICJObyBzZSBoYSBlbmNvbnRyYWRvIGVsIHJlY3Vyc28gWyB7MH0gXS5cbiB7MX0iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfUkVTT1VSQ0VfQ09VTERfTk9UX0xPQUQsCi0gICAgICAgICAgICAgICAgICAgICJObyBzZSBoYSBwb2RpZG8gY2FyZ2FyIGVsIHJlY3Vyc28gWyB7MH0gXTogezF9IFxuIHsyfSBcdCB7M30iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfQlVGRkVSX1NJWkVfTEVTU1RIQU5fWkVSTywKLSAgICAgICAgICAgICAgICAgICAgIlRhbWFcdTAwRjFvIGRlIGJ1ZmZlciBtZW5vciBvIGlndWFsIHF1ZSAwIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0lOVkFMSURfVVRGMTZfU1VSUk9HQVRFLAotICAgICAgICAgICAgICAgICAgICAiXHUwMEJGU2UgaGEgZGV0ZWN0YWRvIHVuIHN1c3RpdHV0byBVVEYtMTYgbm8gdlx1MDBFMWxpZG86IHswfT8iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfT0lFUlJPUiwKLSAgICAgICAgICAgICAgICAiRXJyb3IgZGUgRS9TIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0lMTEVHQUxfQVRUUklCVVRFX1BPU0lUSU9OLAotICAgICAgICAgICAgICAgICJObyBzZSBwdWVkZSBhZ3JlZ2FyIGVsIGF0cmlidXRvIHswfSBkZXNwdVx1MDBFOXMgZGUgbm9kb3Mgc2VjdW5kYXJpb3MgbyBhbnRlcyBkZSBxdWUgc2UgcHJvZHV6Y2EgdW4gZWxlbWVudG8uIFNlIGlnbm9yYXJcdTAwRTEgZWwgYXRyaWJ1dG8uIiB9LAotCi0gICAgICAgICAgICAvKgotICAgICAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IGNvbnRhaW5lZCBhIHJlZmVyZW5jZSB0byBhCi0gICAgICAgICAgICAgKiBuYW1lc3BhY2UgcHJlZml4IHRoYXQgd2FzIHVuZGVmaW5lZC4gIFRoZSB2YWx1ZSBvZiB0aGUgc3Vic3RpdHV0aW9uCi0gICAgICAgICAgICAgKiB0ZXh0IGlzIHRoZSBuYW1lIG9mIHRoZSBwcmVmaXguCi0gICAgICAgICAgICAgKi8KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfTkFNRVNQQUNFX1BSRUZJWCwKLSAgICAgICAgICAgICAgICAiTm8gc2UgaGEgZGVjbGFyYWRvIGVsIGVzcGFjaW8gZGUgbm9tYnJlcyBwYXJhIGVsIHByZWZpam8gJyd7MH0nJy4iIH0sCi0KLSAgICAgICAgICAgIC8qCi0gICAgICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIHJlcG9ydGVkIGlmIHRoZSBzdHlsZXNoZWV0Ci0gICAgICAgICAgICAgKiBiZWluZyBwcm9jZXNzZWQgYXR0ZW1wdGVkIHRvIGNvbnN0cnVjdCBhbiBYTUwgZG9jdW1lbnQgd2l0aCBhbgotICAgICAgICAgICAgICogYXR0cmlidXRlIGluIGEgcGxhY2Ugb3RoZXIgdGhhbiBvbiBhbiBlbGVtZW50LiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgICAgICAgKiBzcGVjaWZpZXMgdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgICAgICAgICAqLwotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9TVFJBWV9BVFRSSUJVVEUsCi0gICAgICAgICAgICAgICAgIkVsIGF0cmlidXRvICcnezB9JycgZXN0XHUwMEUxIGZ1ZXJhIGRlbCBlbGVtZW50by4iIH0sCi0KLSAgICAgICAgICAgIC8qCi0gICAgICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQXMgd2l0aCB0aGUgcHJlY2VkaW5nIG1lc3NhZ2UsIGEgbmFtZXNwYWNlCi0gICAgICAgICAgICAgKiBkZWNsYXJhdGlvbiBoYXMgdGhlIGZvcm0gb2YgYW4gYXR0cmlidXRlIGFuZCBpcyBvbmx5IHBlcm1pdHRlZCB0bwotICAgICAgICAgICAgICogYXBwZWFyIG9uIGFuIGVsZW1lbnQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgezB9IGlzIHRoZSBuYW1lc3BhY2UKLSAgICAgICAgICAgICAqIHByZWZpeCBhbmQgezF9IGlzIHRoZSBVUkkgdGhhdCB3YXMgYmVpbmcgdXNlZCBpbiB0aGUgZXJyb25lb3VzCi0gICAgICAgICAgICAgKiBuYW1lc3BhY2UgZGVjbGFyYXRpb24uCi0gICAgICAgICAgICAgKi8KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfU1RSQVlfTkFNRVNQQUNFLAotICAgICAgICAgICAgICAgICJEZWNsYXJhY2lcdTAwRjNuIGRlbCBlc3BhY2lvIGRlIG5vbWJyZXMgJyd7MH0nJz0nJ3sxfScnIGZ1ZXJhIGRlbCBlbGVtZW50by4iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfQ09VTERfTk9UX0xPQURfUkVTT1VSQ0UsCi0gICAgICAgICAgICAgICAgIk5vIHNlIGhhIHBvZGlkbyBjYXJnYXIgJyd7MH0nJyAoY29tcHJ1ZWJlIGxhIENMQVNTUEFUSCksIGFob3JhIHNcdTAwRjNsbyBzZSBlc3RcdTAwRTFuIHV0aWxpemFuZG8gbG9zIHZhbG9yZXMgcG9yIGRlZmVjdG8iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfSUxMRUdBTF9DSEFSQUNURVIsCi0gICAgICAgICAgICAgICAgIkludGVudG8gZGUgcmVhbGl6YXIgbGEgc2FsaWRhIGRlbCBjYXJcdTAwRTFjdGVyIGRlbCB2YWxvciBpbnRlZ3JhbCB7MH0sIHF1ZSBubyBlc3RcdTAwRTEgcmVwcmVzZW50YWRvIGVuIGxhIGNvZGlmaWNhY2lcdTAwRjNuIGRlIHNhbGlkYSBkZSB7MX0uIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0NPVUxEX05PVF9MT0FEX01FVEhPRF9QUk9QRVJUWSwKLSAgICAgICAgICAgICAgICAiTm8gc2UgaGEgcG9kaWRvIGNhcmdhciBlbCBhcmNoaXZvIGRlIHByb3BpZWRhZGVzICcnezB9JycgcGFyYSBlbCBtXHUwMEU5dG9kbyBkZSBzYWxpZGEgJyd7MX0nJyAoY29tcHJ1ZWJlIGxhIENMQVNTUEFUSCkiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfSU5WQUxJRF9QT1JULAotICAgICAgICAgICAgICAgICJOXHUwMEZBbWVybyBkZSBwdWVydG8gbm8gdlx1MDBFMWxpZG8iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfUE9SVF9XSEVOX0hPU1RfTlVMTCwKLSAgICAgICAgICAgICAgICAiTm8gc2UgcHVlZGUgZGVmaW5pciBlbCBwdWVydG8gc2kgZWwgaG9zdCBlcyBudWxvIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0hPU1RfQUREUkVTU19OT1RfV0VMTEZPUk1FRCwKLSAgICAgICAgICAgICAgICAiRWwgZm9ybWF0byBkZSBsYSBkaXJlY2NpXHUwMEYzbiBkZSBob3N0IG5vIGVzIGNvcnJlY3RvIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX1NDSEVNRV9OT1RfQ09ORk9STUFOVCwKLSAgICAgICAgICAgICAgICAiRWwgZXNxdWVtYSBubyBlcyB2XHUwMEUxbGlkby4iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfU0NIRU1FX0ZST01fTlVMTF9TVFJJTkcsCi0gICAgICAgICAgICAgICAgIk5vIHNlIHB1ZWRlIGRlZmluaXIgdW4gZXNxdWVtYSBhIHBhcnRpciBkZSB1bmEgY2FkZW5hIG51bGEiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfUEFUSF9DT05UQUlOU19JTlZBTElEX0VTQ0FQRV9TRVFVRU5DRSwKLSAgICAgICAgICAgICAgICAiTGEgcnV0YSBkZSBhY2Nlc28gY29udGllbmUgdW5hIHNlY3VlbmNpYSBkZSBlc2NhcGUgbm8gdlx1MDBFMWxpZGEiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfUEFUSF9JTlZBTElEX0NIQVIsCi0gICAgICAgICAgICAgICAgIkxhIHJ1dGEgZGUgYWNjZXNvIGNvbnRpZW5lIHVuIGNhclx1MDBFMWN0ZXIgbm8gdlx1MDBFMWxpZG86IHswfSIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9GUkFHX0lOVkFMSURfQ0hBUiwKLSAgICAgICAgICAgICAgICAiRWwgZnJhZ21lbnRvIGNvbnRpZW5lIHVuIGNhclx1MDBFMWN0ZXIgbm8gdlx1MDBFMWxpZG8iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfRlJBR19XSEVOX1BBVEhfTlVMTCwKLSAgICAgICAgICAgICAgICAiTm8gc2UgcHVlZGUgZGVmaW5pciBlbCBmcmFnbWVudG8gc2kgbGEgcnV0YSBkZSBhY2Nlc28gZXMgbnVsYSIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9GUkFHX0ZPUl9HRU5FUklDX1VSSSwKLSAgICAgICAgICAgICAgICAiU1x1MDBGM2xvIHNlIHB1ZWRlIGRlZmluaXIgZWwgZnJhZ21lbnRvIHBhcmEgdW4gVVJJIGdlblx1MDBFOXJpY28iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfTk9fU0NIRU1FX0lOX1VSSSwKLSAgICAgICAgICAgICAgICAiTm8gc2UgaGEgZW5jb250cmFkbyB1biBlc3F1ZW1hIGVuIGVsIFVSSSIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9DQU5OT1RfSU5JVF9VUklfRU1QVFlfUEFSTVMsCi0gICAgICAgICAgICAgICAgIk5vIHNlIHB1ZWRlIGluaWNpYWxpemFyIGVsIFVSSSBjb24gcGFyXHUwMEUxbWV0cm9zIHZhY1x1MDBFRG9zIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX05PX0ZSQUdNRU5UX1NUUklOR19JTl9QQVRILAotICAgICAgICAgICAgICAgICJObyBzZSBwdWVkZSBlc3BlY2lmaWNhciBlbCBmcmFnbWVudG8gZW4gbGEgcnV0YSBkZSBhY2Nlc28geSBlbiBlbCBmcmFnbWVudG8iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfTk9fUVVFUllfU1RSSU5HX0lOX1BBVEgsCi0gICAgICAgICAgICAgICAgIk5vIHNlIHB1ZWRlIGVzcGVjaWZpY2FyIGxhIGNhZGVuYSBkZSBjb25zdWx0YSBlbiBsYSBydXRhIGRlIGFjY2VzbyB5IGVuIGxhIGNhZGVuYSBkZSBjb25zdWx0YSIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9OT19QT1JUX0lGX05PX0hPU1QsCi0gICAgICAgICAgICAgICAgIk5vIHNlIHB1ZWRlIGVzcGVjaWZpY2FyIGVsIHB1ZXJ0byBzaSBubyBzZSBoYSBlc3BlY2lmaWNhZG8gZWwgaG9zdCIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9OT19VU0VSSU5GT19JRl9OT19IT1NULAotICAgICAgICAgICAgICAgICJObyBzZSBwdWVkZSBlc3BlY2lmaWNhciBsYSBpbmZvcm1hY2lcdTAwRjNuIGRlIHVzdWFyaW8gc2kgbm8gc2UgaGEgZXNwZWNpZmljYWRvIGVsIGhvc3QiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfWE1MX1ZFUlNJT05fTk9UX1NVUFBPUlRFRCwKLSAgICAgICAgICAgICAgICAiQWR2ZXJ0ZW5jaWE6IGVzIG5lY2VzYXJpbyBxdWUgbGEgdmVyc2lcdTAwRjNuIGRlbCBkb2N1bWVudG8gZGUgc2FsaWRhIHNlYSAnJ3swfScnLiBFc3RhIHZlcnNpXHUwMEYzbiBkZSBYTUwgbm8gZXN0XHUwMEUxIHNvcG9ydGFkYS4gTGEgdmVyc2lcdTAwRjNuIGRlbCBkb2N1bWVudG8gZGUgc2FsaWRhIHNlclx1MDBFMSAnJzEuMCcnLiIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9TQ0hFTUVfUkVRVUlSRUQsCi0gICAgICAgICAgICAgICAgIlNlIG5lY2VzaXRhIHVuIGVzcXVlbWEuIiB9LAotCi0gICAgICAgICAgICAvKgotICAgICAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSB3b3JkcyAnUHJvcGVydGllcycgYW5kCi0gICAgICAgICAgICAgKiAnU2VyaWFsaXplckZhY3RvcnknIGluIHRoaXMgbWVzc2FnZSBhcmUgSmF2YSBjbGFzcyBuYW1lcwotICAgICAgICAgICAgICogYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICAgICAgICAgICAqLwotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9GQUNUT1JZX1BST1BFUlRZX01JU1NJTkcsCi0gICAgICAgICAgICAgICAgIkVsIG9iamV0byBkZSBwcm9waWVkYWRlcyB0cmFuc2ZlcmlkbyBhIFNlcmlhbGl6ZXJGYWN0b3J5IG5vIHRpZW5lIHVuYSBwcm9waWVkYWQgJyd7MH0nJy4iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfRU5DT0RJTkdfTk9UX1NVUFBPUlRFRCwKLSAgICAgICAgICAgICAgICAiQWR2ZXJ0ZW5jaWE6IGVsIHRpZW1wbyBkZSBlamVjdWNpXHUwMEYzbiBkZSBKYXZhIG5vIHNvcG9ydGEgbGEgY29kaWZpY2FjaVx1MDBGM24gJyd7MH0nJy4iIH0sCi0KLQotICAgICAgICB9OwotCi0gICAgICAgIHJldHVybiBjb250ZW50czsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL3V0aWxzL1NlcmlhbGl6ZXJNZXNzYWdlc19mci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci91dGlscy9TZXJpYWxpemVyTWVzc2FnZXNfZnIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNmE2NDI0ZC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL3V0aWxzL1NlcmlhbGl6ZXJNZXNzYWdlc19mci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjA1ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplci51dGlsczsKLQotaW1wb3J0IGphdmEudXRpbC5MaXN0UmVzb3VyY2VCdW5kbGU7Ci1pbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKLWltcG9ydCBqYXZhLnV0aWwuTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uOwotaW1wb3J0IGphdmEudXRpbC5SZXNvdXJjZUJ1bmRsZTsKLQotLyoqCi0gKiBBbiBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIGlzIGEgTGlzdFJlc291cmNlQnVuZGxlIHRoYXQKLSAqIGhhcyB0aGUgcmVxdWlyZWQgZ2V0Q29udGVudHMoKSBtZXRob2QgdGhhdCByZXR1cm5zCi0gKiBhbiBhcnJheSBvZiBtZXNzYWdlLWtleS9tZXNzYWdlIGFzc29jaWF0aW9ucy4KLSAqIDxwPgotICogVGhlIG1lc3NhZ2Uga2V5cyBhcmUgZGVmaW5lZCBpbiB7QGxpbmsgTXNnS2V5fS4gVGhlCi0gKiBtZXNzYWdlcyB0aGF0IHRob3NlIGtleXMgbWFwIHRvIGFyZSBkZWZpbmVkIGhlcmUuCi0gKiA8cD4KLSAqIFRoZSBtZXNzYWdlcyBpbiB0aGUgRW5nbGlzaCB2ZXJzaW9uIGFyZSBpbnRlbmRlZCB0byBiZQotICogdHJhbnNsYXRlZC4KLSAqCi0gKiBUaGlzIGNsYXNzIGlzIG5vdCBhIHB1YmxpYyBBUEksIGl0IGlzIG9ubHkgcHVibGljIGJlY2F1c2UgaXQgaXMKLSAqIHVzZWQgaW4gY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyLgotICoKLSAqIEB4c2wudXNhZ2UgaW50ZXJuYWwKLSAqLwotcHVibGljIGNsYXNzIFNlcmlhbGl6ZXJNZXNzYWdlc19mciBleHRlbmRzIExpc3RSZXNvdXJjZUJ1bmRsZSB7Ci0KLSAgICAvKgotICAgICAqIFRoaXMgZmlsZSBjb250YWlucyBlcnJvciBhbmQgd2FybmluZyBtZXNzYWdlcyByZWxhdGVkIHRvCi0gICAgICogU2VyaWFsaXplciBFcnJvciBIYW5kbGluZy4KLSAgICAgKgotICAgICAqICBHZW5lcmFsIG5vdGVzIHRvIHRyYW5zbGF0b3JzOgotCi0gICAgICogIDEpIEEgc3R5bGVzaGVldCBpcyBhIGRlc2NyaXB0aW9uIG9mIGhvdyB0byB0cmFuc2Zvcm0gYW4gaW5wdXQgWE1MIGRvY3VtZW50Ci0gICAgICogICAgIGludG8gYSByZXN1bHRhbnQgWE1MIGRvY3VtZW50IChvciBIVE1MIGRvY3VtZW50IG9yIHRleHQpLiAgVGhlCi0gICAgICogICAgIHN0eWxlc2hlZXQgaXRzZWxmIGlzIGRlc2NyaWJlZCBpbiB0aGUgZm9ybSBvZiBhbiBYTUwgZG9jdW1lbnQuCi0KLSAgICAgKgotICAgICAqICAyKSBBbiBlbGVtZW50IGlzIGEgbWFyay11cCB0YWcgaW4gYW4gWE1MIGRvY3VtZW50OyBhbiBhdHRyaWJ1dGUgaXMgYQotICAgICAqICAgICBtb2RpZmllciBvbiB0aGUgdGFnLiAgRm9yIGV4YW1wbGUsIGluIDxlbGVtIGF0dHI9J3ZhbCcgYXR0cjI9J3ZhbDInPgotICAgICAqICAgICAiZWxlbSIgaXMgYW4gZWxlbWVudCBuYW1lLCAiYXR0ciIgYW5kICJhdHRyMiIgYXJlIGF0dHJpYnV0ZSBuYW1lcyB3aXRoCi0gICAgICogICAgIHRoZSB2YWx1ZXMgInZhbCIgYW5kICJ2YWwyIiwgcmVzcGVjdGl2ZWx5LgotICAgICAqCi0gICAgICogIDMpIEEgbmFtZXNwYWNlIGRlY2xhcmF0aW9uIGlzIGEgc3BlY2lhbCBhdHRyaWJ1dGUgdGhhdCBpcyB1c2VkIHRvIGFzc29jaWF0ZQotICAgICAqICAgICBhIHByZWZpeCB3aXRoIGEgVVJJICh0aGUgbmFtZXNwYWNlKS4gIFRoZSBtZWFuaW5ncyBvZiBlbGVtZW50IG5hbWVzIGFuZAotICAgICAqICAgICBhdHRyaWJ1dGUgbmFtZXMgdGhhdCB1c2UgdGhhdCBwcmVmaXggYXJlIGRlZmluZWQgd2l0aCByZXNwZWN0IHRvIHRoYXQKLSAgICAgKiAgICAgbmFtZXNwYWNlLgotICAgICAqCi0gICAgICoKLSAgICAgKi8KLQotICAgIC8qKiBUaGUgbG9va3VwIHRhYmxlIGZvciBlcnJvciBtZXNzYWdlcy4gICAqLwotICAgIHB1YmxpYyBPYmplY3RbXVtdIGdldENvbnRlbnRzKCkgewotICAgICAgICBPYmplY3RbXVtdIGNvbnRlbnRzID0gbmV3IE9iamVjdFtdW10gewotICAgICAgICAgICAgeyAgIE1zZ0tleS5CQURfTVNHS0VZLAotICAgICAgICAgICAgICAgICJMYSBjbFx1MDBFOSBkZSBtZXNzYWdlICcnezB9JycgbmUgZmlndXJlIHBhcyBkYW5zIGxhIGNsYXNzZSBkZSBtZXNzYWdlcyAnJ3sxfScnIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkJBRF9NU0dGT1JNQVQsCi0gICAgICAgICAgICAgICAgIkVjaGVjIGR1IGZvcm1hdCBkZSBtZXNzYWdlICcnezB9JycgZGFucyBsYSBjbGFzc2UgZGUgbWVzc2FnZXMgJyd7MX0nJy4iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfU0VSSUFMSVpFUl9OT1RfQ09OVEVOVEhBTkRMRVIsCi0gICAgICAgICAgICAgICAgIkxhIGNsYXNzZSBkZSBzZXJpYWxpemVyICcnezB9JycgbicnaW1wbFx1MDBFOW1lbnRlIHBhcyBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlci4iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfUkVTT1VSQ0VfQ09VTERfTk9UX0ZJTkQsCi0gICAgICAgICAgICAgICAgICAgICJMYSByZXNzb3VyY2UgWyB7MH0gXSBlc3QgaW50cm91dmFibGUuXG4gezF9IiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX1JFU09VUkNFX0NPVUxEX05PVF9MT0FELAotICAgICAgICAgICAgICAgICAgICAiTGEgcmVzc291cmNlIFsgezB9IF0gbicnYSBwYXMgcHUgY2hhcmdlciA6IHsxfSBcbiB7Mn0gXHQgezN9IiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0JVRkZFUl9TSVpFX0xFU1NUSEFOX1pFUk8sCi0gICAgICAgICAgICAgICAgICAgICJUYWlsbGUgZHUgdGFtcG9uIDw9MCIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9JTlZBTElEX1VURjE2X1NVUlJPR0FURSwKLSAgICAgICAgICAgICAgICAgICAgIlN1YnN0aXR1dCBVVEYtMTYgbm9uIHZhbGlkZSBkXHUwMEU5dGVjdFx1MDBFOSA6IHswfSA/IiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX09JRVJST1IsCi0gICAgICAgICAgICAgICAgIkVycmV1ciBkJ0UvUyIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9JTExFR0FMX0FUVFJJQlVURV9QT1NJVElPTiwKLSAgICAgICAgICAgICAgICAiSW1wb3NzaWJsZSBkJydham91dGVyIGwnJ2F0dHJpYnV0IHswfSBhcHJcdTAwRThzIGRlcyBub2V1ZHMgZW5mYW50IG91IGF2YW50IGxhIHByb2R1Y3Rpb24gZCcndW4gXHUwMEU5bFx1MDBFOW1lbnQuIEwnJ2F0dHJpYnV0IGVzdCBpZ25vclx1MDBFOS4iIH0sCi0KLSAgICAgICAgICAgIC8qCi0gICAgICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN0eWxlc2hlZXQgY29udGFpbmVkIGEgcmVmZXJlbmNlIHRvIGEKLSAgICAgICAgICAgICAqIG5hbWVzcGFjZSBwcmVmaXggdGhhdCB3YXMgdW5kZWZpbmVkLiAgVGhlIHZhbHVlIG9mIHRoZSBzdWJzdGl0dXRpb24KLSAgICAgICAgICAgICAqIHRleHQgaXMgdGhlIG5hbWUgb2YgdGhlIHByZWZpeC4KLSAgICAgICAgICAgICAqLwotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9OQU1FU1BBQ0VfUFJFRklYLAotICAgICAgICAgICAgICAgICJMJydlc3BhY2UgZGUgbm9tcyBkdSBwclx1MDBFOWZpeGUgJyd7MH0nJyBuJydhIHBhcyBcdTAwRTl0XHUwMEU5IGRcdTAwRTljbGFyXHUwMEU5LiIgfSwKLQotICAgICAgICAgICAgLyoKLSAgICAgICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgcmVwb3J0ZWQgaWYgdGhlIHN0eWxlc2hlZXQKLSAgICAgICAgICAgICAqIGJlaW5nIHByb2Nlc3NlZCBhdHRlbXB0ZWQgdG8gY29uc3RydWN0IGFuIFhNTCBkb2N1bWVudCB3aXRoIGFuCi0gICAgICAgICAgICAgKiBhdHRyaWJ1dGUgaW4gYSBwbGFjZSBvdGhlciB0aGFuIG9uIGFuIGVsZW1lbnQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQKLSAgICAgICAgICAgICAqIHNwZWNpZmllcyB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlLgotICAgICAgICAgICAgICovCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX1NUUkFZX0FUVFJJQlVURSwKLSAgICAgICAgICAgICAgICAiQXR0cmlidXQgJyd7MH0nJyBlbiBkZWhvcnMgZGUgbCcnXHUwMEU5bFx1MDBFOW1lbnQuIiB9LAotCi0gICAgICAgICAgICAvKgotICAgICAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFzIHdpdGggdGhlIHByZWNlZGluZyBtZXNzYWdlLCBhIG5hbWVzcGFjZQotICAgICAgICAgICAgICogZGVjbGFyYXRpb24gaGFzIHRoZSBmb3JtIG9mIGFuIGF0dHJpYnV0ZSBhbmQgaXMgb25seSBwZXJtaXR0ZWQgdG8KLSAgICAgICAgICAgICAqIGFwcGVhciBvbiBhbiBlbGVtZW50LiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHswfSBpcyB0aGUgbmFtZXNwYWNlCi0gICAgICAgICAgICAgKiBwcmVmaXggYW5kIHsxfSBpcyB0aGUgVVJJIHRoYXQgd2FzIGJlaW5nIHVzZWQgaW4gdGhlIGVycm9uZW91cwotICAgICAgICAgICAgICogbmFtZXNwYWNlIGRlY2xhcmF0aW9uLgotICAgICAgICAgICAgICovCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX1NUUkFZX05BTUVTUEFDRSwKLSAgICAgICAgICAgICAgICAiTGEgZFx1MDBFOWNsYXJhdGlvbiBkJydlc3BhY2UgZGUgbm9tcyAnJ3swfScnPScnezF9JycgZXN0IFx1MDBFMCBsJydleHRcdTAwRTlyaWV1ciBkZSBsJydcdTAwRTlsXHUwMEU5bWVudC4iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfQ09VTERfTk9UX0xPQURfUkVTT1VSQ0UsCi0gICAgICAgICAgICAgICAgIkltcG9zc2libGUgZGUgY2hhcmdlciAnJ3swfScnICh2XHUwMEU5cmlmaWVyIENMQVNTUEFUSCksIGxlcyB2YWxldXJzIHBhciBkXHUwMEU5ZmF1dCBzb250IGRvbmMgZW1wbG95XHUwMEU5ZXMiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfSUxMRUdBTF9DSEFSQUNURVIsCi0gICAgICAgICAgICAgICAgIlRlbnRhdGl2ZSBkZSBzb3J0aWUgZCcndW4gY2FyYWN0XHUwMEU4cmUgYXZlYyB1bmUgdmFsZXVyIGVudGlcdTAwRThyZSB7MH0sIG5vbiByZXByXHUwMEU5c2VudFx1MDBFOSBkYW5zIGwnJ2VuY29kYWdlIGRlIHNvcnRpZSBzcFx1MDBFOWNpZmlcdTAwRTkgcG91ciB7MX0uIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0NPVUxEX05PVF9MT0FEX01FVEhPRF9QUk9QRVJUWSwKLSAgICAgICAgICAgICAgICAiSW1wb3NzaWJsZSBkZSBjaGFyZ2VyIGxlIGZpY2hpZXIgZGUgcHJvcHJpXHUwMEU5dFx1MDBFOXMgJyd7MH0nJyBwb3VyIGxhIG1cdTAwRTl0aG9kZSBkZSBzb3J0aWUgJyd7MX0nJyAodlx1MDBFOXJpZmllciBDTEFTU1BBVEgpIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0lOVkFMSURfUE9SVCwKLSAgICAgICAgICAgICAgICAiTnVtXHUwMEU5cm8gZGUgcG9ydCBub24gdmFsaWRlIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX1BPUlRfV0hFTl9IT1NUX05VTEwsCi0gICAgICAgICAgICAgICAgIkltcG9zc2libGUgZGUgZFx1MDBFOWZpbmlyIGxlIHBvcnQgcXVhbmQgbCdoXHUwMEY0dGUgZXN0IE5VTEwiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfSE9TVF9BRERSRVNTX05PVF9XRUxMRk9STUVELAotICAgICAgICAgICAgICAgICJMZSBmb3JtYXQgZGUgbCdhZHJlc3NlIGRlIGwnaFx1MDBGNHRlIG4nZXN0IHBhcyBjb3JyZWN0IiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX1NDSEVNRV9OT1RfQ09ORk9STUFOVCwKLSAgICAgICAgICAgICAgICAiTGUgbW9kXHUwMEU4bGUgbidlc3QgcGFzIGNvbmZvcm1lLiIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9TQ0hFTUVfRlJPTV9OVUxMX1NUUklORywKLSAgICAgICAgICAgICAgICAiSW1wb3NzaWJsZSBkZSBkXHUwMEU5ZmluaXIgbGUgbW9kXHUwMEU4bGUgXHUwMEUwIHBhcnRpciBkZSBsYSBjaGFcdTAwRUVuZSBOVUxMIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX1BBVEhfQ09OVEFJTlNfSU5WQUxJRF9FU0NBUEVfU0VRVUVOQ0UsCi0gICAgICAgICAgICAgICAgIkxlIGNoZW1pbiBkJ2FjY1x1MDBFOHMgY29udGllbnQgdW5lIHNcdTAwRTlxdWVuY2UgZCdcdTAwRTljaGFwcGVtZW50IG5vbiB2YWxpZGUiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfUEFUSF9JTlZBTElEX0NIQVIsCi0gICAgICAgICAgICAgICAgIkxlIGNoZW1pbiBjb250aWVudCB1biBjYXJhY3RcdTAwRThyZSBub24gdmFsaWRlIDogezB9IiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0ZSQUdfSU5WQUxJRF9DSEFSLAotICAgICAgICAgICAgICAgICJMZSBmcmFnbWVudCBjb250aWVudCB1biBjYXJhY3RcdTAwRThyZSBub24gdmFsaWRlIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0ZSQUdfV0hFTl9QQVRIX05VTEwsCi0gICAgICAgICAgICAgICAgIkltcG9zc2libGUgZGUgZFx1MDBFOWZpbmlyIGxlIGZyYWdtZW50IHF1YW5kIGxlIGNoZW1pbiBkJ2FjY1x1MDBFOHMgZXN0IE5VTEwiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfRlJBR19GT1JfR0VORVJJQ19VUkksCi0gICAgICAgICAgICAgICAgIkxlIGZyYWdtZW50IG5lIHBldXQgXHUwMEVBdHJlIGRcdTAwRTlmaW5pIHF1ZSBwb3VyIHVuIFVSSSBnXHUwMEU5blx1MDBFOXJpcXVlIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX05PX1NDSEVNRV9JTl9VUkksCi0gICAgICAgICAgICAgICAgIk1vZFx1MDBFOGxlIGludHJvdXZhYmxlIGRhbnMgbCdVUkkiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfQ0FOTk9UX0lOSVRfVVJJX0VNUFRZX1BBUk1TLAotICAgICAgICAgICAgICAgICJJbXBvc3NpYmxlIGQnaW5pdGlhbGlzZXIgbCdVUkkgYXZlYyBkZXMgcGFyYW1cdTAwRTh0cmVzIHZpZGVzIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX05PX0ZSQUdNRU5UX1NUUklOR19JTl9QQVRILAotICAgICAgICAgICAgICAgICJMZSBmcmFnbWVudCBuZSBkb2l0IHBhcyBcdTAwRUF0cmUgaW5kaXF1XHUwMEU5IFx1MDBFMCBsYSBmb2lzIGRhbnMgbGUgY2hlbWluIGV0IGRhbnMgbGUgZnJhZ21lbnQiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfTk9fUVVFUllfU1RSSU5HX0lOX1BBVEgsCi0gICAgICAgICAgICAgICAgIkxhIGNoYVx1MDBFRW5lIGRlIHJlcXVcdTAwRUF0ZSBuZSBkb2l0IHBhcyBmaWd1cmVyIGRhbnMgdW4gY2hlbWluIGV0IHVuZSBjaGFcdTAwRUVuZSBkZSByZXF1XHUwMEVBdGUiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfTk9fUE9SVF9JRl9OT19IT1NULAotICAgICAgICAgICAgICAgICJMZSBwb3J0IHBldXQgbmUgcGFzIFx1MDBFQXRyZSBzcFx1MDBFOWNpZmlcdTAwRTkgc2kgbCdoXHUwMEY0dGUgbmUgbCdlc3QgcGFzIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX05PX1VTRVJJTkZPX0lGX05PX0hPU1QsCi0gICAgICAgICAgICAgICAgIlVzZXJpbmZvIHBldXQgbmUgcGFzIFx1MDBFQXRyZSBzcFx1MDBFOWNpZmlcdTAwRTkgc2kgbCdoXHUwMEY0dGUgbmUgbCdlc3QgcGFzIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX1hNTF9WRVJTSU9OX05PVF9TVVBQT1JURUQsCi0gICAgICAgICAgICAgICAgIkF2ZXJ0aXNzZW1lbnQgOiBsYSB2ZXJzaW9uIGR1IGRvY3VtZW50IGRlIHNvcnRpZSBkb2l0IFx1MDBFQXRyZSAnJ3swfScnLiBDZXR0ZSB2ZXJzaW9uIFhNTCBuJydlc3QgcGFzIHByaXNlIGVuIGNoYXJnZS4gTGEgdmVyc2lvbiBkdSBkb2N1bWVudCBkZSBzb3J0aWUgc2VyYSAnJzEuMCcnLiIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9TQ0hFTUVfUkVRVUlSRUQsCi0gICAgICAgICAgICAgICAgIk1vZFx1MDBFOGxlIG9ibGlnYXRvaXJlLiIgfSwKLQotICAgICAgICAgICAgLyoKLSAgICAgICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgd29yZHMgJ1Byb3BlcnRpZXMnIGFuZAotICAgICAgICAgICAgICogJ1NlcmlhbGl6ZXJGYWN0b3J5JyBpbiB0aGlzIG1lc3NhZ2UgYXJlIEphdmEgY2xhc3MgbmFtZXMKLSAgICAgICAgICAgICAqIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAgICAgKi8KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfRkFDVE9SWV9QUk9QRVJUWV9NSVNTSU5HLAotICAgICAgICAgICAgICAgICJMJydvYmpldCBkZSBwcm9wcmlcdTAwRTl0XHUwMEU5cyB0cmFuc21pcyBcdTAwRTAgU2VyaWFsaXplckZhY3RvcnkgbmUgY29tcG9ydGUgYXVjdW5lIHByb3ByaVx1MDBFOXRcdTAwRTkgJyd7MH0nJy4iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfRU5DT0RJTkdfTk9UX1NVUFBPUlRFRCwKLSAgICAgICAgICAgICAgICAiQXZlcnRpc3NlbWVudCA6IGwnJ2VuY29kYWdlICcnezB9JycgbicnZXN0IHBhcyBwcmlzIGVuIGNoYXJnZSBwYXIgbCcnZXhcdTAwRTljdXRpb24gSmF2YS4iIH0sCi0KLQotICAgICAgICB9OwotCi0gICAgICAgIHJldHVybiBjb250ZW50czsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL3V0aWxzL1NlcmlhbGl6ZXJNZXNzYWdlc19pdC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci91dGlscy9TZXJpYWxpemVyTWVzc2FnZXNfaXQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZmM1ZWU4ZS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL3V0aWxzL1NlcmlhbGl6ZXJNZXNzYWdlc19pdC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjA1ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplci51dGlsczsKLQotaW1wb3J0IGphdmEudXRpbC5MaXN0UmVzb3VyY2VCdW5kbGU7Ci1pbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKLWltcG9ydCBqYXZhLnV0aWwuTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uOwotaW1wb3J0IGphdmEudXRpbC5SZXNvdXJjZUJ1bmRsZTsKLQotLyoqCi0gKiBBbiBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIGlzIGEgTGlzdFJlc291cmNlQnVuZGxlIHRoYXQKLSAqIGhhcyB0aGUgcmVxdWlyZWQgZ2V0Q29udGVudHMoKSBtZXRob2QgdGhhdCByZXR1cm5zCi0gKiBhbiBhcnJheSBvZiBtZXNzYWdlLWtleS9tZXNzYWdlIGFzc29jaWF0aW9ucy4KLSAqIDxwPgotICogVGhlIG1lc3NhZ2Uga2V5cyBhcmUgZGVmaW5lZCBpbiB7QGxpbmsgTXNnS2V5fS4gVGhlCi0gKiBtZXNzYWdlcyB0aGF0IHRob3NlIGtleXMgbWFwIHRvIGFyZSBkZWZpbmVkIGhlcmUuCi0gKiA8cD4KLSAqIFRoZSBtZXNzYWdlcyBpbiB0aGUgRW5nbGlzaCB2ZXJzaW9uIGFyZSBpbnRlbmRlZCB0byBiZQotICogdHJhbnNsYXRlZC4KLSAqCi0gKiBUaGlzIGNsYXNzIGlzIG5vdCBhIHB1YmxpYyBBUEksIGl0IGlzIG9ubHkgcHVibGljIGJlY2F1c2UgaXQgaXMKLSAqIHVzZWQgaW4gY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyLgotICoKLSAqIEB4c2wudXNhZ2UgaW50ZXJuYWwKLSAqLwotcHVibGljIGNsYXNzIFNlcmlhbGl6ZXJNZXNzYWdlc19pdCBleHRlbmRzIExpc3RSZXNvdXJjZUJ1bmRsZSB7Ci0KLSAgICAvKgotICAgICAqIFRoaXMgZmlsZSBjb250YWlucyBlcnJvciBhbmQgd2FybmluZyBtZXNzYWdlcyByZWxhdGVkIHRvCi0gICAgICogU2VyaWFsaXplciBFcnJvciBIYW5kbGluZy4KLSAgICAgKgotICAgICAqICBHZW5lcmFsIG5vdGVzIHRvIHRyYW5zbGF0b3JzOgotCi0gICAgICogIDEpIEEgc3R5bGVzaGVldCBpcyBhIGRlc2NyaXB0aW9uIG9mIGhvdyB0byB0cmFuc2Zvcm0gYW4gaW5wdXQgWE1MIGRvY3VtZW50Ci0gICAgICogICAgIGludG8gYSByZXN1bHRhbnQgWE1MIGRvY3VtZW50IChvciBIVE1MIGRvY3VtZW50IG9yIHRleHQpLiAgVGhlCi0gICAgICogICAgIHN0eWxlc2hlZXQgaXRzZWxmIGlzIGRlc2NyaWJlZCBpbiB0aGUgZm9ybSBvZiBhbiBYTUwgZG9jdW1lbnQuCi0KLSAgICAgKgotICAgICAqICAyKSBBbiBlbGVtZW50IGlzIGEgbWFyay11cCB0YWcgaW4gYW4gWE1MIGRvY3VtZW50OyBhbiBhdHRyaWJ1dGUgaXMgYQotICAgICAqICAgICBtb2RpZmllciBvbiB0aGUgdGFnLiAgRm9yIGV4YW1wbGUsIGluIDxlbGVtIGF0dHI9J3ZhbCcgYXR0cjI9J3ZhbDInPgotICAgICAqICAgICAiZWxlbSIgaXMgYW4gZWxlbWVudCBuYW1lLCAiYXR0ciIgYW5kICJhdHRyMiIgYXJlIGF0dHJpYnV0ZSBuYW1lcyB3aXRoCi0gICAgICogICAgIHRoZSB2YWx1ZXMgInZhbCIgYW5kICJ2YWwyIiwgcmVzcGVjdGl2ZWx5LgotICAgICAqCi0gICAgICogIDMpIEEgbmFtZXNwYWNlIGRlY2xhcmF0aW9uIGlzIGEgc3BlY2lhbCBhdHRyaWJ1dGUgdGhhdCBpcyB1c2VkIHRvIGFzc29jaWF0ZQotICAgICAqICAgICBhIHByZWZpeCB3aXRoIGEgVVJJICh0aGUgbmFtZXNwYWNlKS4gIFRoZSBtZWFuaW5ncyBvZiBlbGVtZW50IG5hbWVzIGFuZAotICAgICAqICAgICBhdHRyaWJ1dGUgbmFtZXMgdGhhdCB1c2UgdGhhdCBwcmVmaXggYXJlIGRlZmluZWQgd2l0aCByZXNwZWN0IHRvIHRoYXQKLSAgICAgKiAgICAgbmFtZXNwYWNlLgotICAgICAqCi0gICAgICoKLSAgICAgKi8KLQotICAgIC8qKiBUaGUgbG9va3VwIHRhYmxlIGZvciBlcnJvciBtZXNzYWdlcy4gICAqLwotICAgIHB1YmxpYyBPYmplY3RbXVtdIGdldENvbnRlbnRzKCkgewotICAgICAgICBPYmplY3RbXVtdIGNvbnRlbnRzID0gbmV3IE9iamVjdFtdW10gewotICAgICAgICAgICAgeyAgIE1zZ0tleS5CQURfTVNHS0VZLAotICAgICAgICAgICAgICAgICJMYSBjaGlhdmUgZGkgbWVzc2FnZ2lvICcnezB9Jycgbm9uIHNpIHRyb3ZhIG5lbGxhIGNsYXNzZSBtZXNzYWdnaW8gJyd7MX0nJyIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5CQURfTVNHRk9STUFULAotICAgICAgICAgICAgICAgICJGb3JtYXRvIGRpIG1lc3NhZ2dpbyAnJ3swfScnIGluIGNsYXNzZSBtZXNzYWdnaW8gJyd7MX0nJyBub24gcml1c2NpdG8uIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX1NFUklBTElaRVJfTk9UX0NPTlRFTlRIQU5ETEVSLAotICAgICAgICAgICAgICAgICJMYSBjbGFzc2Ugc2VyaWFsaXp6YXRvcmUgJyd7MH0nJyBub24gaW1wbGVtZW50YSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlci4iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfUkVTT1VSQ0VfQ09VTERfTk9UX0ZJTkQsCi0gICAgICAgICAgICAgICAgICAgICJSaXNvcnNhIFsgezB9IF0gbm9uIHRyb3ZhdGEuXG4gezF9IiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX1JFU09VUkNFX0NPVUxEX05PVF9MT0FELAotICAgICAgICAgICAgICAgICAgICAiSW1wb3NzaWJpbGUgY2FyaWNhcmUgbGEgcmlzb3JzYSBbIHswfSBdOiB7MX0gXG4gezJ9IFx0IHszfSIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9CVUZGRVJfU0laRV9MRVNTVEhBTl9aRVJPLAotICAgICAgICAgICAgICAgICAgICAiRGltZW5zaW9uZSBidWZmZXIgPD0wIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0lOVkFMSURfVVRGMTZfU1VSUk9HQVRFLAotICAgICAgICAgICAgICAgICAgICAiUmlsZXZhdG8gc3Vycm9nYXRvIFVURi0xNiBub24gdmFsaWRvOiB7MH0/IiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX09JRVJST1IsCi0gICAgICAgICAgICAgICAgIkVycm9yZSBkaSBJL08iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfSUxMRUdBTF9BVFRSSUJVVEVfUE9TSVRJT04sCi0gICAgICAgICAgICAgICAgIkltcG9zc2liaWxlIGFnZ2l1bmdlcmUgbCcnYXR0cmlidXRvIHswfSBkb3BvIGkgbm9kaSBmaWdsaW8gbyBwcmltYSBjaGUgc2lhIHByb2RvdHRvIHVuIGVsZW1lbnRvLiBMJydhdHRyaWJ1dG8gdmVyclx1MDBFMCBpZ25vcmF0by4iIH0sCi0KLSAgICAgICAgICAgIC8qCi0gICAgICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN0eWxlc2hlZXQgY29udGFpbmVkIGEgcmVmZXJlbmNlIHRvIGEKLSAgICAgICAgICAgICAqIG5hbWVzcGFjZSBwcmVmaXggdGhhdCB3YXMgdW5kZWZpbmVkLiAgVGhlIHZhbHVlIG9mIHRoZSBzdWJzdGl0dXRpb24KLSAgICAgICAgICAgICAqIHRleHQgaXMgdGhlIG5hbWUgb2YgdGhlIHByZWZpeC4KLSAgICAgICAgICAgICAqLwotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9OQU1FU1BBQ0VfUFJFRklYLAotICAgICAgICAgICAgICAgICJMbyBzcGF6aW8gZGkgbm9taSBwZXIgaWwgcHJlZmlzc28gJyd7MH0nJyBub24gXHUwMEU4IHN0YXRvIGRpY2hpYXJhdG8uIiB9LAotCi0gICAgICAgICAgICAvKgotICAgICAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyByZXBvcnRlZCBpZiB0aGUgc3R5bGVzaGVldAotICAgICAgICAgICAgICogYmVpbmcgcHJvY2Vzc2VkIGF0dGVtcHRlZCB0byBjb25zdHJ1Y3QgYW4gWE1MIGRvY3VtZW50IHdpdGggYW4KLSAgICAgICAgICAgICAqIGF0dHJpYnV0ZSBpbiBhIHBsYWNlIG90aGVyIHRoYW4gb24gYW4gZWxlbWVudC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICAgICAgICogc3BlY2lmaWVzIHRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUuCi0gICAgICAgICAgICAgKi8KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfU1RSQVlfQVRUUklCVVRFLAotICAgICAgICAgICAgICAgICJBdHRyaWJ1dG8gJyd7MH0nJyBhbCBkaSBmdW9yaSBkZWxsJydlbGVtZW50by4iIH0sCi0KLSAgICAgICAgICAgIC8qCi0gICAgICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQXMgd2l0aCB0aGUgcHJlY2VkaW5nIG1lc3NhZ2UsIGEgbmFtZXNwYWNlCi0gICAgICAgICAgICAgKiBkZWNsYXJhdGlvbiBoYXMgdGhlIGZvcm0gb2YgYW4gYXR0cmlidXRlIGFuZCBpcyBvbmx5IHBlcm1pdHRlZCB0bwotICAgICAgICAgICAgICogYXBwZWFyIG9uIGFuIGVsZW1lbnQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgezB9IGlzIHRoZSBuYW1lc3BhY2UKLSAgICAgICAgICAgICAqIHByZWZpeCBhbmQgezF9IGlzIHRoZSBVUkkgdGhhdCB3YXMgYmVpbmcgdXNlZCBpbiB0aGUgZXJyb25lb3VzCi0gICAgICAgICAgICAgKiBuYW1lc3BhY2UgZGVjbGFyYXRpb24uCi0gICAgICAgICAgICAgKi8KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfU1RSQVlfTkFNRVNQQUNFLAotICAgICAgICAgICAgICAgICJEaWNoaWFyYXppb25lIGRlbGxvIHNwYXppbyBkaSBub21pICcnezB9Jyc9Jyd7MX0nJyBhbCBkaSBmdW9yaSBkZWxsJydlbGVtZW50by4iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfQ09VTERfTk9UX0xPQURfUkVTT1VSQ0UsCi0gICAgICAgICAgICAgICAgIkltcG9zc2liaWxlIGNhcmljYXJlICcnezB9JycgKHZlcmlmaWNhcmUgQ0xBU1NQQVRIKTsgdmVycmFubm8gdXRpbGl6emF0aSBpIHZhbG9yaSBwcmVkZWZpbml0aSIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9JTExFR0FMX0NIQVJBQ1RFUiwKLSAgICAgICAgICAgICAgICAiVGVudGF0aXZvIGRpIGVzZWd1aXJlIGwnJ291dHB1dCBkaSB1biBjYXJhdHRlcmUgZGkgdmFsb3JlIGludGVncmFsZSB7MH0gbm9uIHJhcHByZXNlbnRhdG8gbmVsbGEgY29kaWZpY2EgZGkgb3V0cHV0IHsxfSBzcGVjaWZpY2F0YS4iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfQ09VTERfTk9UX0xPQURfTUVUSE9EX1BST1BFUlRZLAotICAgICAgICAgICAgICAgICJJbXBvc3NpYmlsZSBjYXJpY2FyZSBpbCBmaWxlIGRlbGxlIHByb3ByaWV0XHUwMEUwICcnezB9JycgcGVyIGlsIG1ldG9kbyBkaSBlbWlzc2lvbmUgJyd7MX0nJyAodmVyaWZpY2FyZSBDTEFTU1BBVEgpIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0lOVkFMSURfUE9SVCwKLSAgICAgICAgICAgICAgICAiTnVtZXJvIGRpIHBvcnRhIG5vbiB2YWxpZG8iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfUE9SVF9XSEVOX0hPU1RfTlVMTCwKLSAgICAgICAgICAgICAgICAiTGEgcG9ydGEgbm9uIHB1XHUwMEYyIGVzc2VyZSBpbXBvc3RhdGEgc2UgbCdob3N0IFx1MDBFOCBudWxsbyIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9IT1NUX0FERFJFU1NfTk9UX1dFTExGT1JNRUQsCi0gICAgICAgICAgICAgICAgIkhvc3Qgbm9uIFx1MDBFOCB1biBpbmRpcml6em8gY29ycmV0dG8iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfU0NIRU1FX05PVF9DT05GT1JNQU5ULAotICAgICAgICAgICAgICAgICJMbyBzY2hlbWEgbm9uIFx1MDBFOCBjb25mb3JtZS4iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfU0NIRU1FX0ZST01fTlVMTF9TVFJJTkcsCi0gICAgICAgICAgICAgICAgIkltcG9zc2liaWxlIGltcG9zdGFyZSBsbyBzY2hlbWEgZGEgdW5hIHN0cmluZ2EgbnVsbGEiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfUEFUSF9DT05UQUlOU19JTlZBTElEX0VTQ0FQRV9TRVFVRU5DRSwKLSAgICAgICAgICAgICAgICAiSWwgcGVyY29yc28gY29udGllbmUgc2VxdWVuemEgZGkgZXNjYXBlIG5vbiB2YWxpZGEiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfUEFUSF9JTlZBTElEX0NIQVIsCi0gICAgICAgICAgICAgICAgIklsIHBlcmNvcnNvIGNvbnRpZW5lIHVuIGNhcmF0dGVyZSBub24gdmFsaWRvOiB7MH0iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfRlJBR19JTlZBTElEX0NIQVIsCi0gICAgICAgICAgICAgICAgIklsIGZyYW1tZW50byBjb250aWVuZSB1biBjYXJhdHRlcmUgbm9uIHZhbGlkbyIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9GUkFHX1dIRU5fUEFUSF9OVUxMLAotICAgICAgICAgICAgICAgICJJbCBmcmFtbWVudG8gbm9uIHB1XHUwMEYyIGVzc2VyZSBpbXBvc3RhdG8gc2UgaWwgcGVyY29yc28gXHUwMEU4IG51bGxvIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0ZSQUdfRk9SX0dFTkVSSUNfVVJJLAotICAgICAgICAgICAgICAgICJJbCBmcmFtbWVudG8gcHVcdTAwRjIgZXNzZXJlIGltcG9zdGF0byBzb2xvIHBlciB1biBVUkkgZ2VuZXJpY28iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfTk9fU0NIRU1FX0lOX1VSSSwKLSAgICAgICAgICAgICAgICAiTmVzc3VubyBzY2hlbWEgdHJvdmF0byBuZWxsJ1VSSSIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9DQU5OT1RfSU5JVF9VUklfRU1QVFlfUEFSTVMsCi0gICAgICAgICAgICAgICAgIkltcG9zc2liaWxlIGluaXppYWxpenphcmUgbCdVUkkgY29uIGkgcGFyYW1ldHJpIHZ1b3RpIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX05PX0ZSQUdNRU5UX1NUUklOR19JTl9QQVRILAotICAgICAgICAgICAgICAgICJJbCBmcmFtbWVudG8gbm9uIHB1XHUwMEYyIGVzc2VyZSBzcGVjaWZpY2F0byBzaWEgbmVsIHBlcmNvcnNvIGNoZSBuZWwgZnJhbW1lbnRvIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX05PX1FVRVJZX1NUUklOR19JTl9QQVRILAotICAgICAgICAgICAgICAgICJMYSBzdHJpbmdhIGRpIHF1ZXJ5IG5vbiBwdVx1MDBGMiBlc3NlcmUgc3BlY2lmaWNhdGEgbmVsbGEgc3RyaW5nYSBkaSBwZXJjb3JzbyBlIHF1ZXJ5LiIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9OT19QT1JUX0lGX05PX0hPU1QsCi0gICAgICAgICAgICAgICAgIkxhIHBvcnRhIG5vbiBwdVx1MDBGMiBlc3NlcmUgc3BlY2lmaWNhdGEgc2UgbCdob3N0IG5vbiBcdTAwRTggc3BlY2lmaWNhdG8iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfTk9fVVNFUklORk9fSUZfTk9fSE9TVCwKLSAgICAgICAgICAgICAgICAiVXNlcmluZm8gbm9uIHB1XHUwMEYyIGVzc2VyZSBzcGVjaWZpY2F0byBzZSBsJ2hvc3Qgbm9uIFx1MDBFOCBzcGVjaWZpY2F0byIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9YTUxfVkVSU0lPTl9OT1RfU1VQUE9SVEVELAotICAgICAgICAgICAgICAgICJBdnZlcnRlbnphOiBsYSB2ZXJzaW9uZSBkZWwgZG9jdW1lbnRvIGRpIG91dHB1dCBkZXZlIGVzc2VyZSAnJ3swfScnLiBRdWVzdGEgdmVyc2lvbmUgZGkgWE1MIG5vbiBcdTAwRTggc3VwcG9ydGF0YS4gTGEgdmVyc2lvbmUgZGVsIGRvY3VtZW50byBkaSBvdXRwdXQgc2FyXHUwMEUwICcnMS4wJycuIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX1NDSEVNRV9SRVFVSVJFRCwKLSAgICAgICAgICAgICAgICAiTG8gc2NoZW1hIFx1MDBFOCBvYmJsaWdhdG9yaW8uIiB9LAotCi0gICAgICAgICAgICAvKgotICAgICAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSB3b3JkcyAnUHJvcGVydGllcycgYW5kCi0gICAgICAgICAgICAgKiAnU2VyaWFsaXplckZhY3RvcnknIGluIHRoaXMgbWVzc2FnZSBhcmUgSmF2YSBjbGFzcyBuYW1lcwotICAgICAgICAgICAgICogYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICAgICAgICAgICAqLwotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9GQUNUT1JZX1BST1BFUlRZX01JU1NJTkcsCi0gICAgICAgICAgICAgICAgIkwnJ29nZ2V0dG8gUHJvcGVydGllcyBwYXNzYXRvIGEgU2VyaWFsaXplckZhY3Rvcnkgbm9uIGRpc3BvbmUgZGkgdW5hIHByb3ByaWV0XHUwMEUwICcnezB9JycuIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0VOQ09ESU5HX05PVF9TVVBQT1JURUQsCi0gICAgICAgICAgICAgICAgIkF2dmVydGVuemE6IGxhIGNvZGlmaWNhICcnezB9Jycgbm9uIFx1MDBFOCBzdXBwb3J0YXRhIGRhIEphdmEgUnVudGltZS4iIH0sCi0KLQotICAgICAgICB9OwotCi0gICAgICAgIHJldHVybiBjb250ZW50czsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL3V0aWxzL1NlcmlhbGl6ZXJNZXNzYWdlc19qYS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci91dGlscy9TZXJpYWxpemVyTWVzc2FnZXNfamEuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZWE3NGMyZi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL3V0aWxzL1NlcmlhbGl6ZXJNZXNzYWdlc19qYS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjA1ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplci51dGlsczsKLQotaW1wb3J0IGphdmEudXRpbC5MaXN0UmVzb3VyY2VCdW5kbGU7Ci1pbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKLWltcG9ydCBqYXZhLnV0aWwuTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uOwotaW1wb3J0IGphdmEudXRpbC5SZXNvdXJjZUJ1bmRsZTsKLQotLyoqCi0gKiBBbiBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIGlzIGEgTGlzdFJlc291cmNlQnVuZGxlIHRoYXQKLSAqIGhhcyB0aGUgcmVxdWlyZWQgZ2V0Q29udGVudHMoKSBtZXRob2QgdGhhdCByZXR1cm5zCi0gKiBhbiBhcnJheSBvZiBtZXNzYWdlLWtleS9tZXNzYWdlIGFzc29jaWF0aW9ucy4KLSAqIDxwPgotICogVGhlIG1lc3NhZ2Uga2V5cyBhcmUgZGVmaW5lZCBpbiB7QGxpbmsgTXNnS2V5fS4gVGhlCi0gKiBtZXNzYWdlcyB0aGF0IHRob3NlIGtleXMgbWFwIHRvIGFyZSBkZWZpbmVkIGhlcmUuCi0gKiA8cD4KLSAqIFRoZSBtZXNzYWdlcyBpbiB0aGUgRW5nbGlzaCB2ZXJzaW9uIGFyZSBpbnRlbmRlZCB0byBiZQotICogdHJhbnNsYXRlZC4KLSAqCi0gKiBUaGlzIGNsYXNzIGlzIG5vdCBhIHB1YmxpYyBBUEksIGl0IGlzIG9ubHkgcHVibGljIGJlY2F1c2UgaXQgaXMKLSAqIHVzZWQgaW4gY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyLgotICoKLSAqIEB4c2wudXNhZ2UgaW50ZXJuYWwKLSAqLwotcHVibGljIGNsYXNzIFNlcmlhbGl6ZXJNZXNzYWdlc19qYSBleHRlbmRzIExpc3RSZXNvdXJjZUJ1bmRsZSB7Ci0KLSAgICAvKgotICAgICAqIFRoaXMgZmlsZSBjb250YWlucyBlcnJvciBhbmQgd2FybmluZyBtZXNzYWdlcyByZWxhdGVkIHRvCi0gICAgICogU2VyaWFsaXplciBFcnJvciBIYW5kbGluZy4KLSAgICAgKgotICAgICAqICBHZW5lcmFsIG5vdGVzIHRvIHRyYW5zbGF0b3JzOgotCi0gICAgICogIDEpIEEgc3R5bGVzaGVldCBpcyBhIGRlc2NyaXB0aW9uIG9mIGhvdyB0byB0cmFuc2Zvcm0gYW4gaW5wdXQgWE1MIGRvY3VtZW50Ci0gICAgICogICAgIGludG8gYSByZXN1bHRhbnQgWE1MIGRvY3VtZW50IChvciBIVE1MIGRvY3VtZW50IG9yIHRleHQpLiAgVGhlCi0gICAgICogICAgIHN0eWxlc2hlZXQgaXRzZWxmIGlzIGRlc2NyaWJlZCBpbiB0aGUgZm9ybSBvZiBhbiBYTUwgZG9jdW1lbnQuCi0KLSAgICAgKgotICAgICAqICAyKSBBbiBlbGVtZW50IGlzIGEgbWFyay11cCB0YWcgaW4gYW4gWE1MIGRvY3VtZW50OyBhbiBhdHRyaWJ1dGUgaXMgYQotICAgICAqICAgICBtb2RpZmllciBvbiB0aGUgdGFnLiAgRm9yIGV4YW1wbGUsIGluIDxlbGVtIGF0dHI9J3ZhbCcgYXR0cjI9J3ZhbDInPgotICAgICAqICAgICAiZWxlbSIgaXMgYW4gZWxlbWVudCBuYW1lLCAiYXR0ciIgYW5kICJhdHRyMiIgYXJlIGF0dHJpYnV0ZSBuYW1lcyB3aXRoCi0gICAgICogICAgIHRoZSB2YWx1ZXMgInZhbCIgYW5kICJ2YWwyIiwgcmVzcGVjdGl2ZWx5LgotICAgICAqCi0gICAgICogIDMpIEEgbmFtZXNwYWNlIGRlY2xhcmF0aW9uIGlzIGEgc3BlY2lhbCBhdHRyaWJ1dGUgdGhhdCBpcyB1c2VkIHRvIGFzc29jaWF0ZQotICAgICAqICAgICBhIHByZWZpeCB3aXRoIGEgVVJJICh0aGUgbmFtZXNwYWNlKS4gIFRoZSBtZWFuaW5ncyBvZiBlbGVtZW50IG5hbWVzIGFuZAotICAgICAqICAgICBhdHRyaWJ1dGUgbmFtZXMgdGhhdCB1c2UgdGhhdCBwcmVmaXggYXJlIGRlZmluZWQgd2l0aCByZXNwZWN0IHRvIHRoYXQKLSAgICAgKiAgICAgbmFtZXNwYWNlLgotICAgICAqCi0gICAgICoKLSAgICAgKi8KLQotICAgIC8qKiBUaGUgbG9va3VwIHRhYmxlIGZvciBlcnJvciBtZXNzYWdlcy4gICAqLwotICAgIHB1YmxpYyBPYmplY3RbXVtdIGdldENvbnRlbnRzKCkgewotICAgICAgICBPYmplY3RbXVtdIGNvbnRlbnRzID0gbmV3IE9iamVjdFtdW10gewotICAgICAgICAgICAgeyAgIE1zZ0tleS5CQURfTVNHS0VZLAotICAgICAgICAgICAgICAgICJcdTMwRTFcdTMwQzNcdTMwQkJcdTMwRkNcdTMwQjhcdTMwRkJcdTMwQURcdTMwRkMnJ3swfScnXHUzMDZGXHUzMDAxXHUzMEUxXHUzMEMzXHUzMEJCXHUzMEZDXHUzMEI4XHUzMEZCXHUzMEFGXHUzMEU5XHUzMEI5Jyd7MX0nJ1x1MzA2N1x1MzA2Rlx1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5MyIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5CQURfTVNHRk9STUFULAotICAgICAgICAgICAgICAgICJcdTMwRTFcdTMwQzNcdTMwQkJcdTMwRkNcdTMwQjhcdTMwRkJcdTMwQUZcdTMwRTlcdTMwQjknJ3sxfScnXHUzMDZFXHUzMEUxXHUzMEMzXHUzMEJCXHUzMEZDXHUzMEI4Jyd7MH0nJ1x1MzA2RVx1MzBENVx1MzBBOVx1MzBGQ1x1MzBERVx1MzBDM1x1MzBDOFx1MzA0Q1x1NTkzMVx1NjU1N1x1MzA1N1x1MzA3RVx1MzA1N1x1MzA1Rlx1MzAwMiIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9TRVJJQUxJWkVSX05PVF9DT05URU5USEFORExFUiwKLSAgICAgICAgICAgICAgICAiXHUzMEI3XHUzMEVBXHUzMEEyXHUzMEU5XHUzMEE0XHUzMEI2XHUzMEZCXHUzMEFGXHUzMEU5XHUzMEI5Jyd7MH0nJ1x1MzA2Rm9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyXHUzMDkyXHU1QjlGXHU4OEM1XHUzMDU3XHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX1JFU09VUkNFX0NPVUxEX05PVF9GSU5ELAotICAgICAgICAgICAgICAgICAgICAiXHUzMEVBXHUzMEJEXHUzMEZDXHUzMEI5WyB7MH0gXVx1MzA2Rlx1ODk4Qlx1MzA2NFx1MzA0Qlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5M1x1MzA2N1x1MzA1N1x1MzA1Rlx1MzAwMlxuIHsxfSIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9SRVNPVVJDRV9DT1VMRF9OT1RfTE9BRCwKLSAgICAgICAgICAgICAgICAgICAgIlx1MzBFQVx1MzBCRFx1MzBGQ1x1MzBCOVsgezB9IF1cdTMwOTJcdTMwRURcdTMwRkNcdTMwQzlcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwNjdcdTMwNTdcdTMwNUY6IHsxfSBcbiB7Mn0gXHQgezN9IiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0JVRkZFUl9TSVpFX0xFU1NUSEFOX1pFUk8sCi0gICAgICAgICAgICAgICAgICAgICJcdTMwRDBcdTMwQzNcdTMwRDVcdTMwQTFcdTMwRkJcdTMwQjVcdTMwQTRcdTMwQkE8PTAiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfSU5WQUxJRF9VVEYxNl9TVVJST0dBVEUsCi0gICAgICAgICAgICAgICAgICAgICJcdTcxMjFcdTUyQjlcdTMwNkFVVEYtMTZcdTMwQjVcdTMwRURcdTMwQjJcdTMwRkNcdTMwQzhcdTMwNENcdTY5MUNcdTUxRkFcdTMwNTVcdTMwOENcdTMwN0VcdTMwNTdcdTMwNUY6IHswfVx1MzAwMiIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9PSUVSUk9SLAotICAgICAgICAgICAgICAgICJJT1x1MzBBOFx1MzBFOVx1MzBGQyIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9JTExFR0FMX0FUVFJJQlVURV9QT1NJVElPTiwKLSAgICAgICAgICAgICAgICAiXHU1QjUwXHUzMENFXHUzMEZDXHUzMEM5XHUzMDZFXHU1RjhDXHUzMDdFXHUzMDVGXHUzMDZGXHU4OTgxXHU3RDIwXHUzMDRDXHU3NTFGXHU2MjEwXHUzMDU1XHUzMDhDXHUzMDhCXHU1MjREXHUzMDZCXHU1QzVFXHU2MDI3ezB9XHUzMDkyXHU4RkZEXHU1MkEwXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyXHU1QzVFXHU2MDI3XHUzMDZGXHU3MTIxXHU4OTk2XHUzMDU1XHUzMDhDXHUzMDdFXHUzMDU5XHUzMDAyIiB9LAotCi0gICAgICAgICAgICAvKgotICAgICAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IGNvbnRhaW5lZCBhIHJlZmVyZW5jZSB0byBhCi0gICAgICAgICAgICAgKiBuYW1lc3BhY2UgcHJlZml4IHRoYXQgd2FzIHVuZGVmaW5lZC4gIFRoZSB2YWx1ZSBvZiB0aGUgc3Vic3RpdHV0aW9uCi0gICAgICAgICAgICAgKiB0ZXh0IGlzIHRoZSBuYW1lIG9mIHRoZSBwcmVmaXguCi0gICAgICAgICAgICAgKi8KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfTkFNRVNQQUNFX1BSRUZJWCwKLSAgICAgICAgICAgICAgICAiXHU2M0E1XHU5ODJEXHU4RjlFJyd7MH0nJ1x1MzA2RVx1MzBDRFx1MzBGQ1x1MzBFMFx1MzBCOVx1MzBEQVx1MzBGQ1x1MzBCOVx1MzA0Q1x1NUJBM1x1OEEwMFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMiIgfSwKLQotICAgICAgICAgICAgLyoKLSAgICAgICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGlzIG1lc3NhZ2UgaXMgcmVwb3J0ZWQgaWYgdGhlIHN0eWxlc2hlZXQKLSAgICAgICAgICAgICAqIGJlaW5nIHByb2Nlc3NlZCBhdHRlbXB0ZWQgdG8gY29uc3RydWN0IGFuIFhNTCBkb2N1bWVudCB3aXRoIGFuCi0gICAgICAgICAgICAgKiBhdHRyaWJ1dGUgaW4gYSBwbGFjZSBvdGhlciB0aGFuIG9uIGFuIGVsZW1lbnQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQKLSAgICAgICAgICAgICAqIHNwZWNpZmllcyB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlLgotICAgICAgICAgICAgICovCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX1NUUkFZX0FUVFJJQlVURSwKLSAgICAgICAgICAgICAgICAiXHU1QzVFXHU2MDI3Jyd7MH0nJ1x1MzA0Q1x1ODk4MVx1N0QyMFx1MzA2RVx1NTkxNlx1NTA3NFx1MzA2Qlx1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMiIgfSwKLQotICAgICAgICAgICAgLyoKLSAgICAgICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBcyB3aXRoIHRoZSBwcmVjZWRpbmcgbWVzc2FnZSwgYSBuYW1lc3BhY2UKLSAgICAgICAgICAgICAqIGRlY2xhcmF0aW9uIGhhcyB0aGUgZm9ybSBvZiBhbiBhdHRyaWJ1dGUgYW5kIGlzIG9ubHkgcGVybWl0dGVkIHRvCi0gICAgICAgICAgICAgKiBhcHBlYXIgb24gYW4gZWxlbWVudC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCB7MH0gaXMgdGhlIG5hbWVzcGFjZQotICAgICAgICAgICAgICogcHJlZml4IGFuZCB7MX0gaXMgdGhlIFVSSSB0aGF0IHdhcyBiZWluZyB1c2VkIGluIHRoZSBlcnJvbmVvdXMKLSAgICAgICAgICAgICAqIG5hbWVzcGFjZSBkZWNsYXJhdGlvbi4KLSAgICAgICAgICAgICAqLwotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9TVFJBWV9OQU1FU1BBQ0UsCi0gICAgICAgICAgICAgICAgIlx1MzBDRFx1MzBGQ1x1MzBFMFx1MzBCOVx1MzBEQVx1MzBGQ1x1MzBCOVx1NUJBM1x1OEEwMCcnezB9Jyc9Jyd7MX0nJ1x1MzA0Q1x1ODk4MVx1N0QyMFx1MzA2RVx1NTkxNlx1NTA3NFx1MzA2Qlx1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMiIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9DT1VMRF9OT1RfTE9BRF9SRVNPVVJDRSwKLSAgICAgICAgICAgICAgICAiJyd7MH0nJ1x1MzA5Mlx1MzBFRFx1MzBGQ1x1MzBDOVx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzA2N1x1MzA1N1x1MzA1RihDTEFTU1BBVEhcdTMwOTJcdTc4QkFcdThBOERcdTMwNTdcdTMwNjZcdTMwNEZcdTMwNjBcdTMwNTVcdTMwNDQpXHUzMDAyXHU3M0ZFXHU1NzI4XHUzMDZGXHU1MzU4XHUzMDZCXHUzMEM3XHUzMEQ1XHUzMEE5XHUzMEVCXHUzMEM4XHUzMDkyXHU0RjdGXHU3NTI4XHUzMDU3XHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5IiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0lMTEVHQUxfQ0hBUkFDVEVSLAotICAgICAgICAgICAgICAgICJ7MX1cdTMwNkVcdTYzMDdcdTVCOUFcdTMwNTVcdTMwOENcdTMwNUZcdTUxRkFcdTUyOUJcdTMwQThcdTMwRjNcdTMwQjNcdTMwRkNcdTMwQzdcdTMwQTNcdTMwRjNcdTMwQjBcdTMwNjdcdTc5M0FcdTMwNTVcdTMwOENcdTMwNkFcdTMwNDRcdTY1NzRcdTY1NzBcdTUwMjR7MH1cdTMwNkVcdTY1ODdcdTVCNTdcdTMwOTJcdTUxRkFcdTUyOUJcdTMwNTdcdTMwODhcdTMwNDZcdTMwNjhcdTMwNTdcdTMwN0VcdTMwNTdcdTMwNUZcdTMwMDIiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfQ09VTERfTk9UX0xPQURfTUVUSE9EX1BST1BFUlRZLAotICAgICAgICAgICAgICAgICJcdTUxRkFcdTUyOUJcdTMwRTFcdTMwQkRcdTMwQzNcdTMwQzknJ3sxfScnXHUzMDZFXHUzMEQ3XHUzMEVEXHUzMEQxXHUzMEM2XHUzMEEzXHUzMEZCXHUzMEQ1XHUzMEExXHUzMEE0XHUzMEVCJyd7MH0nJ1x1MzA5Mlx1MzBFRFx1MzBGQ1x1MzBDOVx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzA2N1x1MzA1N1x1MzA1RihDTEFTU1BBVEhcdTMwOTJcdTc4QkFcdThBOERcdTMwNTdcdTMwNjZcdTMwNEZcdTMwNjBcdTMwNTVcdTMwNDQpIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0lOVkFMSURfUE9SVCwKLSAgICAgICAgICAgICAgICAiXHU3MTIxXHU1MkI5XHUzMDZBXHUzMEREXHUzMEZDXHUzMEM4XHU3NTZBXHU1M0Y3IiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX1BPUlRfV0hFTl9IT1NUX05VTEwsCi0gICAgICAgICAgICAgICAgIlx1MzBEQlx1MzBCOVx1MzBDOFx1MzA0Q251bGxcdTMwNkVcdTU4MzRcdTU0MDhcdTMwNkZcdTMwRERcdTMwRkNcdTMwQzhcdTMwOTJcdThBMkRcdTVCOUFcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTMiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfSE9TVF9BRERSRVNTX05PVF9XRUxMRk9STUVELAotICAgICAgICAgICAgICAgICJcdTMwREJcdTMwQjlcdTMwQzhcdTMwNkZcdTY1NzRcdTVGNjJcdTVGMEZcdTMwNkVcdTMwQTJcdTMwQzlcdTMwRUNcdTMwQjlcdTMwNjdcdTMwNkZcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTMiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfU0NIRU1FX05PVF9DT05GT1JNQU5ULAotICAgICAgICAgICAgICAgICJcdTMwQjlcdTMwQURcdTMwRkNcdTMwRTBcdTMwNENcdTY1NzRcdTU0MDhcdTMwNTdcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfU0NIRU1FX0ZST01fTlVMTF9TVFJJTkcsCi0gICAgICAgICAgICAgICAgIm51bGxcdTY1ODdcdTVCNTdcdTUyMTdcdTMwNEJcdTMwODlcdTMwNkZcdTMwQjlcdTMwQURcdTMwRkNcdTMwRTBcdTMwOTJcdThBMkRcdTVCOUFcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTMiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfUEFUSF9DT05UQUlOU19JTlZBTElEX0VTQ0FQRV9TRVFVRU5DRSwKLSAgICAgICAgICAgICAgICAiXHUzMEQxXHUzMEI5XHUzMDZCXHU3MTIxXHU1MkI5XHUzMDZBXHUzMEE4XHUzMEI5XHUzMEIxXHUzMEZDXHUzMEQ3XHUzMEZCXHUzMEI3XHUzMEZDXHUzMEIxXHUzMEYzXHUzMEI5XHUzMDRDXHU1NDJCXHUzMDdFXHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5IiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX1BBVEhfSU5WQUxJRF9DSEFSLAotICAgICAgICAgICAgICAgICJcdTMwRDFcdTMwQjlcdTMwNkJcdTcxMjFcdTUyQjlcdTMwNkFcdTY1ODdcdTVCNTdcdTMwNENcdTU0MkJcdTMwN0VcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTk6IHswfSIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9GUkFHX0lOVkFMSURfQ0hBUiwKLSAgICAgICAgICAgICAgICAiXHUzMEQ1XHUzMEU5XHUzMEIwXHUzMEUxXHUzMEYzXHUzMEM4XHUzMDZCXHU3MTIxXHU1MkI5XHU2NTg3XHU1QjU3XHUzMDRDXHU1NDJCXHUzMDdFXHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5IiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0ZSQUdfV0hFTl9QQVRIX05VTEwsCi0gICAgICAgICAgICAgICAgIlx1MzBEMVx1MzBCOVx1MzA0Q251bGxcdTMwNkVcdTU4MzRcdTU0MDhcdTMwNkZcdTMwRDVcdTMwRTlcdTMwQjBcdTMwRTFcdTMwRjNcdTMwQzhcdTMwOTJcdThBMkRcdTVCOUFcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTMiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfRlJBR19GT1JfR0VORVJJQ19VUkksCi0gICAgICAgICAgICAgICAgIlx1NkM0RVx1NzUyOFVSSVx1MzA2RVx1MzBENVx1MzBFOVx1MzBCMFx1MzBFMVx1MzBGM1x1MzBDOFx1MzA2RVx1MzA3Rlx1OEEyRFx1NUI5QVx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1OSIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9OT19TQ0hFTUVfSU5fVVJJLAotICAgICAgICAgICAgICAgICJcdTMwQjlcdTMwQURcdTMwRkNcdTMwRTBcdTMwNENVUklcdTMwNkJcdTg5OEJcdTMwNjRcdTMwNEJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTMiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfQ0FOTk9UX0lOSVRfVVJJX0VNUFRZX1BBUk1TLAotICAgICAgICAgICAgICAgICJVUklcdTMwNkZcdTdBN0FcdTMwNkVcdTMwRDFcdTMwRTlcdTMwRTFcdTMwRkNcdTMwQkZcdTMwOTJcdTRGN0ZcdTc1MjhcdTMwNTdcdTMwNjZcdTUyMURcdTY3MUZcdTUzMTZcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTMiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfTk9fRlJBR01FTlRfU1RSSU5HX0lOX1BBVEgsCi0gICAgICAgICAgICAgICAgIlx1MzBENVx1MzBFOVx1MzBCMFx1MzBFMVx1MzBGM1x1MzBDOFx1MzA2Rlx1MzBEMVx1MzBCOVx1MzA2OFx1MzBENVx1MzBFOVx1MzBCMFx1MzBFMVx1MzBGM1x1MzBDOFx1MzA2RVx1NEUyMVx1NjVCOVx1MzA2Qlx1NjMwN1x1NUI5QVx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MyIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9OT19RVUVSWV9TVFJJTkdfSU5fUEFUSCwKLSAgICAgICAgICAgICAgICAiXHU1NTRGXHU1NDA4XHUzMDVCXHU2NTg3XHU1QjU3XHU1MjE3XHUzMDZGXHUzMEQxXHUzMEI5XHUzMDRBXHUzMDg4XHUzMDczXHU1NTRGXHU1NDA4XHUzMDVCXHU2NTg3XHU1QjU3XHU1MjE3XHU1MTg1XHUzMDZCXHU2MzA3XHU1QjlBXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX05PX1BPUlRfSUZfTk9fSE9TVCwKLSAgICAgICAgICAgICAgICAiXHUzMERCXHUzMEI5XHUzMEM4XHUzMDRDXHU2MzA3XHU1QjlBXHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDZBXHUzMDQ0XHU1ODM0XHU1NDA4XHUzMDZGXHUzMEREXHUzMEZDXHUzMEM4XHUzMDkyXHU2MzA3XHU1QjlBXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX05PX1VTRVJJTkZPX0lGX05PX0hPU1QsCi0gICAgICAgICAgICAgICAgIlx1MzBEQlx1MzBCOVx1MzBDOFx1MzA0Q1x1NjMwN1x1NUI5QVx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA2QVx1MzA0NFx1NTgzNFx1NTQwOFx1MzA2RlVzZXJpbmZvXHUzMDkyXHU2MzA3XHU1QjlBXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX1hNTF9WRVJTSU9OX05PVF9TVVBQT1JURUQsCi0gICAgICAgICAgICAgICAgIlx1OEI2Nlx1NTQ0QTogXHU1MUZBXHU1MjlCXHUzMEM5XHUzMEFEXHUzMEU1XHUzMEUxXHUzMEYzXHUzMEM4XHUzMDZFXHUzMEQwXHUzMEZDXHUzMEI4XHUzMEU3XHUzMEYzXHUzMDZGXHUzMDAxJyd7MH0nJ1x1MzA2N1x1MzA0Mlx1MzA4Qlx1MzA1M1x1MzA2OFx1MzA0Q1x1MzBFQVx1MzBBRlx1MzBBOFx1MzBCOVx1MzBDOFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OVx1MzAwMlhNTFx1MzA2RVx1MzA1M1x1MzA2RVx1MzBEMFx1MzBGQ1x1MzBCOFx1MzBFN1x1MzBGM1x1MzA2Rlx1MzBCNVx1MzBERFx1MzBGQ1x1MzBDOFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMlx1NTFGQVx1NTI5Qlx1MzBDOVx1MzBBRFx1MzBFNVx1MzBFMVx1MzBGM1x1MzBDOFx1MzA2RVx1MzBEMFx1MzBGQ1x1MzBCOFx1MzBFN1x1MzBGM1x1MzA2Rlx1MzAwMScnMS4wJydcdTMwNkJcdTMwNkFcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfU0NIRU1FX1JFUVVJUkVELAotICAgICAgICAgICAgICAgICJcdTMwQjlcdTMwQURcdTMwRkNcdTMwRTBcdTMwNENcdTVGQzVcdTg5ODFcdTMwNjdcdTMwNTlcdTMwMDIiIH0sCi0KLSAgICAgICAgICAgIC8qCi0gICAgICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHdvcmRzICdQcm9wZXJ0aWVzJyBhbmQKLSAgICAgICAgICAgICAqICdTZXJpYWxpemVyRmFjdG9yeScgaW4gdGhpcyBtZXNzYWdlIGFyZSBKYXZhIGNsYXNzIG5hbWVzCi0gICAgICAgICAgICAgKiBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLgotICAgICAgICAgICAgICovCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0ZBQ1RPUllfUFJPUEVSVFlfTUlTU0lORywKLSAgICAgICAgICAgICAgICAiU2VyaWFsaXplckZhY3RvcnlcdTMwNkJcdTZFMjFcdTMwNTVcdTMwOENcdTMwOEJcdTMwRDdcdTMwRURcdTMwRDFcdTMwQzZcdTMwQTNcdTMwRkJcdTMwQUFcdTMwRDZcdTMwQjhcdTMwQTdcdTMwQUZcdTMwQzhcdTMwNkJcdTMwMDEnJ3swfScnXHUzMEQ3XHUzMEVEXHUzMEQxXHUzMEM2XHUzMEEzXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0VOQ09ESU5HX05PVF9TVVBQT1JURUQsCi0gICAgICAgICAgICAgICAgIlx1OEI2Nlx1NTQ0QTogIFx1MzBBOFx1MzBGM1x1MzBCM1x1MzBGQ1x1MzBDN1x1MzBBM1x1MzBGM1x1MzBCMCcnezB9JydcdTMwNkZcdTMwMDFKYXZhXHUzMEU5XHUzMEYzXHUzMEJGXHUzMEE0XHUzMEUwXHUzMDY3XHUzMEI1XHUzMEREXHUzMEZDXHUzMEM4XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyIiB9LAotCi0KLSAgICAgICAgfTsKLQotICAgICAgICByZXR1cm4gY29udGVudHM7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci91dGlscy9TZXJpYWxpemVyTWVzc2FnZXNfa28uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvdXRpbHMvU2VyaWFsaXplck1lc3NhZ2VzX2tvLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDRmMTI2MDcuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci91dGlscy9TZXJpYWxpemVyTWVzc2FnZXNfa28uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIwNSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXIudXRpbHM7Ci0KLWltcG9ydCBqYXZhLnV0aWwuTGlzdFJlc291cmNlQnVuZGxlOwotaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7Ci1pbXBvcnQgamF2YS51dGlsLk1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuUmVzb3VyY2VCdW5kbGU7Ci0KLS8qKgotICogQW4gaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcyBpcyBhIExpc3RSZXNvdXJjZUJ1bmRsZSB0aGF0Ci0gKiBoYXMgdGhlIHJlcXVpcmVkIGdldENvbnRlbnRzKCkgbWV0aG9kIHRoYXQgcmV0dXJucwotICogYW4gYXJyYXkgb2YgbWVzc2FnZS1rZXkvbWVzc2FnZSBhc3NvY2lhdGlvbnMuCi0gKiA8cD4KLSAqIFRoZSBtZXNzYWdlIGtleXMgYXJlIGRlZmluZWQgaW4ge0BsaW5rIE1zZ0tleX0uIFRoZQotICogbWVzc2FnZXMgdGhhdCB0aG9zZSBrZXlzIG1hcCB0byBhcmUgZGVmaW5lZCBoZXJlLgotICogPHA+Ci0gKiBUaGUgbWVzc2FnZXMgaW4gdGhlIEVuZ2xpc2ggdmVyc2lvbiBhcmUgaW50ZW5kZWQgdG8gYmUKLSAqIHRyYW5zbGF0ZWQuCi0gKgotICogVGhpcyBjbGFzcyBpcyBub3QgYSBwdWJsaWMgQVBJLCBpdCBpcyBvbmx5IHB1YmxpYyBiZWNhdXNlIGl0IGlzCi0gKiB1c2VkIGluIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplci4KLSAqCi0gKiBAeHNsLnVzYWdlIGludGVybmFsCi0gKi8KLXB1YmxpYyBjbGFzcyBTZXJpYWxpemVyTWVzc2FnZXNfa28gZXh0ZW5kcyBMaXN0UmVzb3VyY2VCdW5kbGUgewotCi0gICAgLyoKLSAgICAgKiBUaGlzIGZpbGUgY29udGFpbnMgZXJyb3IgYW5kIHdhcm5pbmcgbWVzc2FnZXMgcmVsYXRlZCB0bwotICAgICAqIFNlcmlhbGl6ZXIgRXJyb3IgSGFuZGxpbmcuCi0gICAgICoKLSAgICAgKiAgR2VuZXJhbCBub3RlcyB0byB0cmFuc2xhdG9yczoKLQotICAgICAqICAxKSBBIHN0eWxlc2hlZXQgaXMgYSBkZXNjcmlwdGlvbiBvZiBob3cgdG8gdHJhbnNmb3JtIGFuIGlucHV0IFhNTCBkb2N1bWVudAotICAgICAqICAgICBpbnRvIGEgcmVzdWx0YW50IFhNTCBkb2N1bWVudCAob3IgSFRNTCBkb2N1bWVudCBvciB0ZXh0KS4gIFRoZQotICAgICAqICAgICBzdHlsZXNoZWV0IGl0c2VsZiBpcyBkZXNjcmliZWQgaW4gdGhlIGZvcm0gb2YgYW4gWE1MIGRvY3VtZW50LgotCi0gICAgICoKLSAgICAgKiAgMikgQW4gZWxlbWVudCBpcyBhIG1hcmstdXAgdGFnIGluIGFuIFhNTCBkb2N1bWVudDsgYW4gYXR0cmlidXRlIGlzIGEKLSAgICAgKiAgICAgbW9kaWZpZXIgb24gdGhlIHRhZy4gIEZvciBleGFtcGxlLCBpbiA8ZWxlbSBhdHRyPSd2YWwnIGF0dHIyPSd2YWwyJz4KLSAgICAgKiAgICAgImVsZW0iIGlzIGFuIGVsZW1lbnQgbmFtZSwgImF0dHIiIGFuZCAiYXR0cjIiIGFyZSBhdHRyaWJ1dGUgbmFtZXMgd2l0aAotICAgICAqICAgICB0aGUgdmFsdWVzICJ2YWwiIGFuZCAidmFsMiIsIHJlc3BlY3RpdmVseS4KLSAgICAgKgotICAgICAqICAzKSBBIG5hbWVzcGFjZSBkZWNsYXJhdGlvbiBpcyBhIHNwZWNpYWwgYXR0cmlidXRlIHRoYXQgaXMgdXNlZCB0byBhc3NvY2lhdGUKLSAgICAgKiAgICAgYSBwcmVmaXggd2l0aCBhIFVSSSAodGhlIG5hbWVzcGFjZSkuICBUaGUgbWVhbmluZ3Mgb2YgZWxlbWVudCBuYW1lcyBhbmQKLSAgICAgKiAgICAgYXR0cmlidXRlIG5hbWVzIHRoYXQgdXNlIHRoYXQgcHJlZml4IGFyZSBkZWZpbmVkIHdpdGggcmVzcGVjdCB0byB0aGF0Ci0gICAgICogICAgIG5hbWVzcGFjZS4KLSAgICAgKgotICAgICAqCi0gICAgICovCi0KLSAgICAvKiogVGhlIGxvb2t1cCB0YWJsZSBmb3IgZXJyb3IgbWVzc2FnZXMuICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0W11bXSBnZXRDb250ZW50cygpIHsKLSAgICAgICAgT2JqZWN0W11bXSBjb250ZW50cyA9IG5ldyBPYmplY3RbXVtdIHsKLSAgICAgICAgICAgIHsgICBNc2dLZXkuQkFEX01TR0tFWSwKLSAgICAgICAgICAgICAgICAiXHVCQTU0XHVDMkRDXHVDOUMwIFx1RDBBNCAnJ3swfScnXHVDNzc0KFx1QUMwMCkgXHVCQTU0XHVDMkRDXHVDOUMwIFx1RDA3NFx1Qjc5OFx1QzJBNCAnJ3sxfScnXHVDNUQwIFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuQkFEX01TR0ZPUk1BVCwKLSAgICAgICAgICAgICAgICAiXHVCQTU0XHVDMkRDXHVDOUMwIFx1RDA3NFx1Qjc5OFx1QzJBNCAnJ3sxfScnXHVDNUQwXHVDMTFDICcnezB9JycgXHVCQTU0XHVDMkRDXHVDOUMwXHVDNzU4IFx1RDYxNVx1QzJERFx1Qzc3NCBcdUM3OThcdUJBQkJcdUI0MThcdUM1QzhcdUMyQjVcdUIyQzhcdUIyRTQuIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX1NFUklBTElaRVJfTk9UX0NPTlRFTlRIQU5ETEVSLAotICAgICAgICAgICAgICAgICJTZXJpYWxpemVyIFx1RDA3NFx1Qjc5OFx1QzJBNCAnJ3swfScnXHVDNzc0KFx1QUMwMCkgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXJcdUI5N0MgXHVBRDZDXHVENjA0XHVENTU4XHVDOUMwIFx1QzU0QVx1QzU1OFx1QzJCNVx1QjJDOFx1QjJFNC4iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfUkVTT1VSQ0VfQ09VTERfTk9UX0ZJTkQsCi0gICAgICAgICAgICAgICAgICAgICJbezB9XSBcdUI5QUNcdUMxOENcdUMyQTRcdUI5N0MgXHVDQzNFXHVDNzQ0IFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuXG4gezF9IiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX1JFU09VUkNFX0NPVUxEX05PVF9MT0FELAotICAgICAgICAgICAgICAgICAgICAiW3swfV0gXHVCOUFDXHVDMThDXHVDMkE0XHVBQzAwIFx1QjJFNFx1Qzc0Q1x1Qzc0NCBcdUI4NUNcdUI0RENcdUQ1NjAgXHVDMjE4IFx1QzVDNlx1Qzc0QzogezF9IFxuIHsyfSBcdCB7M30iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfQlVGRkVSX1NJWkVfTEVTU1RIQU5fWkVSTywKLSAgICAgICAgICAgICAgICAgICAgIlx1QkM4NFx1RDM3QyBcdUQwNkNcdUFFMzAgPD0wIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0lOVkFMSURfVVRGMTZfU1VSUk9HQVRFLAotICAgICAgICAgICAgICAgICAgICAiXHVCRDgwXHVDODAxXHVENTY5XHVENTVDIFVURi0xNiBcdUIzMDBcdUI5QUMgXHVDNjk0XHVDMThDXHVBQzAwIFx1QUMxMFx1QzlDMFx1QjQyODogezB9IiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX09JRVJST1IsCi0gICAgICAgICAgICAgICAgIklPIFx1QzYyNFx1Qjk1OCIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9JTExFR0FMX0FUVFJJQlVURV9QT1NJVElPTiwKLSAgICAgICAgICAgICAgICAiXHVENTU4XHVDNzA0IFx1QjE3OFx1QjREQ1x1QUMwMCBcdUMwRERcdUMxMzFcdUI0MUMgXHVENkM0IFx1QjYxMFx1QjI5NCBcdUM2OTRcdUMxOENcdUFDMDAgXHVDMEREXHVDMTMxXHVCNDE4XHVBRTMwIFx1QzgwNFx1QzVEMCB7MH0gXHVDMThEXHVDMTMxXHVDNzQ0IFx1Q0Q5NFx1QUMwMFx1RDU2MCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiBcdUMxOERcdUMxMzFcdUM3NzQgXHVCQjM0XHVDMkRDXHVCNDI5XHVCMkM4XHVCMkU0LiIgfSwKLQotICAgICAgICAgICAgLyoKLSAgICAgICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3R5bGVzaGVldCBjb250YWluZWQgYSByZWZlcmVuY2UgdG8gYQotICAgICAgICAgICAgICogbmFtZXNwYWNlIHByZWZpeCB0aGF0IHdhcyB1bmRlZmluZWQuICBUaGUgdmFsdWUgb2YgdGhlIHN1YnN0aXR1dGlvbgotICAgICAgICAgICAgICogdGV4dCBpcyB0aGUgbmFtZSBvZiB0aGUgcHJlZml4LgotICAgICAgICAgICAgICovCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX05BTUVTUEFDRV9QUkVGSVgsCi0gICAgICAgICAgICAgICAgIicnezB9JycgXHVDODExXHVCNDUwXHVDNUI0XHVDNUQwIFx1QjMwMFx1RDU1QyBcdUIxMjRcdUM3ODRcdUMyQTRcdUQzOThcdUM3NzRcdUMyQTRcdUFDMDAgXHVDMTIwXHVDNUI4XHVCNDE4XHVDOUMwIFx1QzU0QVx1QzU1OFx1QzJCNVx1QjJDOFx1QjJFNC4iIH0sCi0KLSAgICAgICAgICAgIC8qCi0gICAgICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIHJlcG9ydGVkIGlmIHRoZSBzdHlsZXNoZWV0Ci0gICAgICAgICAgICAgKiBiZWluZyBwcm9jZXNzZWQgYXR0ZW1wdGVkIHRvIGNvbnN0cnVjdCBhbiBYTUwgZG9jdW1lbnQgd2l0aCBhbgotICAgICAgICAgICAgICogYXR0cmlidXRlIGluIGEgcGxhY2Ugb3RoZXIgdGhhbiBvbiBhbiBlbGVtZW50LiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgICAgICAgKiBzcGVjaWZpZXMgdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgICAgICAgICAqLwotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9TVFJBWV9BVFRSSUJVVEUsCi0gICAgICAgICAgICAgICAgIicnezB9JycgXHVDMThEXHVDMTMxXHVDNzc0IFx1QzY5NFx1QzE4Q1x1QzVEMCBcdUQzRUNcdUQ1NjhcdUI0MThcdUM1QjQgXHVDNzg4XHVDOUMwIFx1QzU0QVx1QzJCNVx1QjJDOFx1QjJFNC4iIH0sCi0KLSAgICAgICAgICAgIC8qCi0gICAgICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQXMgd2l0aCB0aGUgcHJlY2VkaW5nIG1lc3NhZ2UsIGEgbmFtZXNwYWNlCi0gICAgICAgICAgICAgKiBkZWNsYXJhdGlvbiBoYXMgdGhlIGZvcm0gb2YgYW4gYXR0cmlidXRlIGFuZCBpcyBvbmx5IHBlcm1pdHRlZCB0bwotICAgICAgICAgICAgICogYXBwZWFyIG9uIGFuIGVsZW1lbnQuICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgezB9IGlzIHRoZSBuYW1lc3BhY2UKLSAgICAgICAgICAgICAqIHByZWZpeCBhbmQgezF9IGlzIHRoZSBVUkkgdGhhdCB3YXMgYmVpbmcgdXNlZCBpbiB0aGUgZXJyb25lb3VzCi0gICAgICAgICAgICAgKiBuYW1lc3BhY2UgZGVjbGFyYXRpb24uCi0gICAgICAgICAgICAgKi8KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfU1RSQVlfTkFNRVNQQUNFLAotICAgICAgICAgICAgICAgICJcdUIxMjRcdUM3ODRcdUMyQTRcdUQzOThcdUM3NzRcdUMyQTQgXHVDMTIwXHVDNUI4ICcnezB9Jyc9Jyd7MX0nJ1x1Qzc3NChcdUFDMDApIFx1QzY5NFx1QzE4Q1x1QzVEMCBcdUQzRUNcdUQ1NjhcdUI0MThcdUM1QjQgXHVDNzg4XHVDOUMwIFx1QzU0QVx1QzJCNVx1QjJDOFx1QjJFNC4iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfQ09VTERfTk9UX0xPQURfUkVTT1VSQ0UsCi0gICAgICAgICAgICAgICAgInswfVx1Qzc0NChcdUI5N0MpIFx1Qjg1Q1x1QjREQ1x1RDU2MCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiBDTEFTU1BBVEhcdUI5N0MgXHVENjU1XHVDNzc4XHVENTU4XHVDMkVEXHVDMkRDXHVDNjI0LiBcdUQ2MDRcdUM3QUMgXHVBRTMwXHVCQ0Y4XHVBQzEyXHVCOUNDIFx1QzBBQ1x1QzZBOVx1RDU1OFx1QjI5NCBcdUM5MTFcdUM3ODVcdUIyQzhcdUIyRTQuIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0lMTEVHQUxfQ0hBUkFDVEVSLAotICAgICAgICAgICAgICAgICJ7MX1cdUM3NTggXHVDOUMwXHVDODE1XHVCNDFDIFx1Q0Q5Q1x1QjgyNSBcdUM3NzhcdUNGNTRcdUI1MjlcdUM1RDBcdUMxMUMgXHVENDVDXHVDMkRDXHVCNDE4XHVDOUMwIFx1QzU0QVx1QjI5NCBcdUM4MTVcdUMyMTggXHVBQzEyIHswfVx1Qzc1OCBcdUJCMzhcdUM3OTBcdUI5N0MgXHVDRDlDXHVCODI1XHVENTU4XHVCODI0XHVBQ0UwIFx1QzJEQ1x1QjNDNFx1RDU4OFx1QzJCNVx1QjJDOFx1QjJFNC4iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfQ09VTERfTk9UX0xPQURfTUVUSE9EX1BST1BFUlRZLAotICAgICAgICAgICAgICAgICJcdUNEOUNcdUI4MjUgXHVCQTU0XHVDMThDXHVCNERDICcnezF9JydcdUM1RDAgXHVCMzAwXHVENTVDIFx1QzE4RFx1QzEzMSBcdUQzMENcdUM3N0MgJyd7MH0nJ1x1Qzc0NChcdUI5N0MpIFx1Qjg1Q1x1QjREQ1x1RDU2MCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiBDTEFTU1BBVEhcdUI5N0MgXHVENjU1XHVDNzc4XHVENTU4XHVDMkVEXHVDMkRDXHVDNjI0LiIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9JTlZBTElEX1BPUlQsCi0gICAgICAgICAgICAgICAgIlx1RDNFQ1x1RDJCOCBcdUJDODhcdUQ2MzhcdUFDMDAgXHVCRDgwXHVDODAxXHVENTY5XHVENTY5XHVCMkM4XHVCMkU0LiIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9QT1JUX1dIRU5fSE9TVF9OVUxMLAotICAgICAgICAgICAgICAgICJcdUQ2MzhcdUMyQTRcdUQyQjhcdUFDMDAgXHVCMTEwXHVDNzdDIFx1QUNCRFx1QzZCMCBcdUQzRUNcdUQyQjhcdUI5N0MgXHVDMTI0XHVDODE1XHVENTYwIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0hPU1RfQUREUkVTU19OT1RfV0VMTEZPUk1FRCwKLSAgICAgICAgICAgICAgICAiXHVENjM4XHVDMkE0XHVEMkI4XHVBQzAwIFx1QzY0NFx1QzgwNFx1RDU1QyBcdUM4RkNcdUMxOENcdUFDMDAgXHVDNTQ0XHVCMkQ5XHVCMkM4XHVCMkU0LiIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9TQ0hFTUVfTk9UX0NPTkZPUk1BTlQsCi0gICAgICAgICAgICAgICAgIlx1Q0NCNFx1QUNDNFx1QUMwMCBcdUM3N0NcdUNFNThcdUQ1NThcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0LiIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9TQ0hFTUVfRlJPTV9OVUxMX1NUUklORywKLSAgICAgICAgICAgICAgICAiXHVCMTEwIFx1QkIzOFx1Qzc5MFx1QzVGNFx1QzVEMFx1QzExQyBcdUNDQjRcdUFDQzRcdUI5N0MgXHVDMTI0XHVDODE1XHVENTYwIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX1BBVEhfQ09OVEFJTlNfSU5WQUxJRF9FU0NBUEVfU0VRVUVOQ0UsCi0gICAgICAgICAgICAgICAgIlx1QUNCRFx1Qjg1Q1x1QzVEMCBcdUJEODBcdUM4MDFcdUQ1NjlcdUQ1NUMgXHVDNzc0XHVDMkE0XHVDRjAwXHVDNzc0XHVENTA0IFx1QzJEQ1x1RDAwMFx1QzJBNFx1QUMwMCBcdUQzRUNcdUQ1NjhcdUI0MThcdUM1QjQgXHVDNzg4XHVDMkI1XHVCMkM4XHVCMkU0LiIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9QQVRIX0lOVkFMSURfQ0hBUiwKLSAgICAgICAgICAgICAgICAiXHVBQ0JEXHVCODVDXHVDNUQwIFx1QkQ4MFx1QzgwMVx1RDU2OVx1RDU1QyBcdUJCMzhcdUM3OTBcdUFDMDAgXHVEM0VDXHVENTY4XHVCNDI4OiB7MH0iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfRlJBR19JTlZBTElEX0NIQVIsCi0gICAgICAgICAgICAgICAgIlx1QkQ4MFx1QkQ4NFx1QzVEMCBcdUJEODBcdUM4MDFcdUQ1NjlcdUQ1NUMgXHVCQjM4XHVDNzkwXHVBQzAwIFx1RDNFQ1x1RDU2OFx1QjQxOFx1QzVCNCBcdUM3ODhcdUMyQjVcdUIyQzhcdUIyRTQuIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0ZSQUdfV0hFTl9QQVRIX05VTEwsCi0gICAgICAgICAgICAgICAgIlx1QUNCRFx1Qjg1Q1x1QUMwMCBcdUIxMTBcdUM3N0MgXHVBQ0JEXHVDNkIwIFx1QkQ4MFx1QkQ4NFx1Qzc0NCBcdUMxMjRcdUM4MTVcdUQ1NjAgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfRlJBR19GT1JfR0VORVJJQ19VUkksCi0gICAgICAgICAgICAgICAgIlx1Qzc3Q1x1QkMxOCBVUklcdUM1RDAgXHVCMzAwXHVENTc0XHVDMTFDXHVCOUNDIFx1QkQ4MFx1QkQ4NFx1Qzc0NCBcdUMxMjRcdUM4MTVcdUQ1NjAgXHVDMjE4IFx1Qzc4OFx1QzJCNVx1QjJDOFx1QjJFNC4iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfTk9fU0NIRU1FX0lOX1VSSSwKLSAgICAgICAgICAgICAgICAiVVJJXHVDNUQwXHVDMTFDIFx1Q0NCNFx1QUNDNFx1Qjk3QyBcdUNDM0VcdUM3NDQgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfQ0FOTk9UX0lOSVRfVVJJX0VNUFRZX1BBUk1TLAotICAgICAgICAgICAgICAgICJcdUJFNDggXHVCOUU0XHVBQzFDXHVCQ0MwXHVDMjE4XHVCODVDIFVSSVx1Qjk3QyBcdUNEMDhcdUFFMzBcdUQ2NTRcdUQ1NjAgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfTk9fRlJBR01FTlRfU1RSSU5HX0lOX1BBVEgsCi0gICAgICAgICAgICAgICAgIlx1QUNCRFx1Qjg1Q1x1QzY0MCBcdUJEODBcdUJEODRcdUM1RDAgXHVCQUE4XHVCNDUwIFx1QkQ4MFx1QkQ4NFx1Qzc0NCBcdUM5QzBcdUM4MTVcdUQ1NjAgXHVDMjE4XHVCMjk0IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfTk9fUVVFUllfU1RSSU5HX0lOX1BBVEgsCi0gICAgICAgICAgICAgICAgIlx1QUNCRFx1Qjg1QyBcdUJDMEYgXHVDOUM4XHVDNzU4IFx1QkIzOFx1Qzc5MFx1QzVGNFx1QzVEMCBcdUM5QzhcdUM3NTggXHVCQjM4XHVDNzkwXHVDNUY0XHVDNzQ0IFx1QzlDMFx1QzgxNVx1RDU2MCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9OT19QT1JUX0lGX05PX0hPU1QsCi0gICAgICAgICAgICAgICAgIlx1RDYzOFx1QzJBNFx1RDJCOFx1Qjk3QyBcdUM5QzBcdUM4MTVcdUQ1NThcdUM5QzAgXHVDNTRBXHVDNzQwIFx1QUNCRFx1QzZCMFx1QzVEMFx1QjI5NCBcdUQzRUNcdUQyQjhcdUI5N0MgXHVDOUMwXHVDODE1XHVENTYwIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX05PX1VTRVJJTkZPX0lGX05PX0hPU1QsCi0gICAgICAgICAgICAgICAgIlx1RDYzOFx1QzJBNFx1RDJCOFx1Qjk3QyBcdUM5QzBcdUM4MTVcdUQ1NThcdUM5QzAgXHVDNTRBXHVDNzQwIFx1QUNCRFx1QzZCMFx1QzVEMFx1QjI5NCBVc2VyaW5mb1x1Qjk3QyBcdUM5QzBcdUM4MTVcdUQ1NjAgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfWE1MX1ZFUlNJT05fTk9UX1NVUFBPUlRFRCwKLSAgICAgICAgICAgICAgICAiXHVBQ0JEXHVBQ0UwOiBcdUNEOUNcdUI4MjUgXHVCQjM4XHVDMTFDXHVDNzU4IFx1QkM4NFx1QzgwNFx1Qzc3NCAnJ3swfScnXHVDNzc0KFx1QUMwMCkgXHVCNDE4XHVCM0M0XHVCODVEIFx1QzY5NFx1Q0NBRFx1RDU4OFx1QzJCNVx1QjJDOFx1QjJFNC4gXHVDNzc0IFx1QkM4NFx1QzgwNFx1Qzc1OCBYTUxcdUM3NDAgXHVDOUMwXHVDNkQwXHVCNDE4XHVDOUMwIFx1QzU0QVx1QzJCNVx1QjJDOFx1QjJFNC4gXHVDRDlDXHVCODI1IFx1QkIzOFx1QzExQ1x1Qzc1OCBcdUJDODRcdUM4MDRcdUM3NDAgJycxLjAnJ1x1Qzc3NCBcdUI0MjlcdUIyQzhcdUIyRTQuIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX1NDSEVNRV9SRVFVSVJFRCwKLSAgICAgICAgICAgICAgICAiXHVDQ0I0XHVBQ0M0XHVBQzAwIFx1RDU0NFx1QzY5NFx1RDU2OVx1QjJDOFx1QjJFNCEiIH0sCi0KLSAgICAgICAgICAgIC8qCi0gICAgICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHdvcmRzICdQcm9wZXJ0aWVzJyBhbmQKLSAgICAgICAgICAgICAqICdTZXJpYWxpemVyRmFjdG9yeScgaW4gdGhpcyBtZXNzYWdlIGFyZSBKYXZhIGNsYXNzIG5hbWVzCi0gICAgICAgICAgICAgKiBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLgotICAgICAgICAgICAgICovCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0ZBQ1RPUllfUFJPUEVSVFlfTUlTU0lORywKLSAgICAgICAgICAgICAgICAiU2VyaWFsaXplckZhY3RvcnlcdUM1RDAgXHVDODA0XHVCMkVDXHVCNDFDIFByb3BlcnRpZXMgXHVBQzFEXHVDQ0I0XHVDNUQwICcnezB9JycgXHVDMThEXHVDMTMxXHVDNzc0IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfRU5DT0RJTkdfTk9UX1NVUFBPUlRFRCwKLSAgICAgICAgICAgICAgICAiXHVBQ0JEXHVBQ0UwOiBcdUM3NzhcdUNGNTRcdUI1MjkgJyd7MH0nJ1x1Qzc0MChcdUIyOTQpIEphdmEgXHVCN0YwXHVEMEMwXHVDNzg0XHVDNUQwIFx1QzlDMFx1QzZEMFx1QjQxOFx1QzlDMCBcdUM1NEFcdUMyQjVcdUIyQzhcdUIyRTQuIiB9LAotCi0KLSAgICAgICAgfTsKLQotICAgICAgICByZXR1cm4gY29udGVudHM7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci91dGlscy9TZXJpYWxpemVyTWVzc2FnZXNfcHRfQlIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvdXRpbHMvU2VyaWFsaXplck1lc3NhZ2VzX3B0X0JSLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDkyNDhmZDMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci91dGlscy9TZXJpYWxpemVyTWVzc2FnZXNfcHRfQlIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIwNSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXIudXRpbHM7Ci0KLWltcG9ydCBqYXZhLnV0aWwuTGlzdFJlc291cmNlQnVuZGxlOwotaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7Ci1pbXBvcnQgamF2YS51dGlsLk1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuUmVzb3VyY2VCdW5kbGU7Ci0KLS8qKgotICogQW4gaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcyBpcyBhIExpc3RSZXNvdXJjZUJ1bmRsZSB0aGF0Ci0gKiBoYXMgdGhlIHJlcXVpcmVkIGdldENvbnRlbnRzKCkgbWV0aG9kIHRoYXQgcmV0dXJucwotICogYW4gYXJyYXkgb2YgbWVzc2FnZS1rZXkvbWVzc2FnZSBhc3NvY2lhdGlvbnMuCi0gKiA8cD4KLSAqIFRoZSBtZXNzYWdlIGtleXMgYXJlIGRlZmluZWQgaW4ge0BsaW5rIE1zZ0tleX0uIFRoZQotICogbWVzc2FnZXMgdGhhdCB0aG9zZSBrZXlzIG1hcCB0byBhcmUgZGVmaW5lZCBoZXJlLgotICogPHA+Ci0gKiBUaGUgbWVzc2FnZXMgaW4gdGhlIEVuZ2xpc2ggdmVyc2lvbiBhcmUgaW50ZW5kZWQgdG8gYmUKLSAqIHRyYW5zbGF0ZWQuCi0gKgotICogVGhpcyBjbGFzcyBpcyBub3QgYSBwdWJsaWMgQVBJLCBpdCBpcyBvbmx5IHB1YmxpYyBiZWNhdXNlIGl0IGlzCi0gKiB1c2VkIGluIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplci4KLSAqCi0gKiBAeHNsLnVzYWdlIGludGVybmFsCi0gKi8KLXB1YmxpYyBjbGFzcyBTZXJpYWxpemVyTWVzc2FnZXNfcHRfQlIgZXh0ZW5kcyBMaXN0UmVzb3VyY2VCdW5kbGUgewotCi0gICAgLyoKLSAgICAgKiBUaGlzIGZpbGUgY29udGFpbnMgZXJyb3IgYW5kIHdhcm5pbmcgbWVzc2FnZXMgcmVsYXRlZCB0bwotICAgICAqIFNlcmlhbGl6ZXIgRXJyb3IgSGFuZGxpbmcuCi0gICAgICoKLSAgICAgKiAgR2VuZXJhbCBub3RlcyB0byB0cmFuc2xhdG9yczoKLQotICAgICAqICAxKSBBIHN0eWxlc2hlZXQgaXMgYSBkZXNjcmlwdGlvbiBvZiBob3cgdG8gdHJhbnNmb3JtIGFuIGlucHV0IFhNTCBkb2N1bWVudAotICAgICAqICAgICBpbnRvIGEgcmVzdWx0YW50IFhNTCBkb2N1bWVudCAob3IgSFRNTCBkb2N1bWVudCBvciB0ZXh0KS4gIFRoZQotICAgICAqICAgICBzdHlsZXNoZWV0IGl0c2VsZiBpcyBkZXNjcmliZWQgaW4gdGhlIGZvcm0gb2YgYW4gWE1MIGRvY3VtZW50LgotCi0gICAgICoKLSAgICAgKiAgMikgQW4gZWxlbWVudCBpcyBhIG1hcmstdXAgdGFnIGluIGFuIFhNTCBkb2N1bWVudDsgYW4gYXR0cmlidXRlIGlzIGEKLSAgICAgKiAgICAgbW9kaWZpZXIgb24gdGhlIHRhZy4gIEZvciBleGFtcGxlLCBpbiA8ZWxlbSBhdHRyPSd2YWwnIGF0dHIyPSd2YWwyJz4KLSAgICAgKiAgICAgImVsZW0iIGlzIGFuIGVsZW1lbnQgbmFtZSwgImF0dHIiIGFuZCAiYXR0cjIiIGFyZSBhdHRyaWJ1dGUgbmFtZXMgd2l0aAotICAgICAqICAgICB0aGUgdmFsdWVzICJ2YWwiIGFuZCAidmFsMiIsIHJlc3BlY3RpdmVseS4KLSAgICAgKgotICAgICAqICAzKSBBIG5hbWVzcGFjZSBkZWNsYXJhdGlvbiBpcyBhIHNwZWNpYWwgYXR0cmlidXRlIHRoYXQgaXMgdXNlZCB0byBhc3NvY2lhdGUKLSAgICAgKiAgICAgYSBwcmVmaXggd2l0aCBhIFVSSSAodGhlIG5hbWVzcGFjZSkuICBUaGUgbWVhbmluZ3Mgb2YgZWxlbWVudCBuYW1lcyBhbmQKLSAgICAgKiAgICAgYXR0cmlidXRlIG5hbWVzIHRoYXQgdXNlIHRoYXQgcHJlZml4IGFyZSBkZWZpbmVkIHdpdGggcmVzcGVjdCB0byB0aGF0Ci0gICAgICogICAgIG5hbWVzcGFjZS4KLSAgICAgKgotICAgICAqCi0gICAgICovCi0KLSAgICAvKiogVGhlIGxvb2t1cCB0YWJsZSBmb3IgZXJyb3IgbWVzc2FnZXMuICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0W11bXSBnZXRDb250ZW50cygpIHsKLSAgICAgICAgT2JqZWN0W11bXSBjb250ZW50cyA9IG5ldyBPYmplY3RbXVtdIHsKLSAgICAgICAgICAgIHsgICBNc2dLZXkuQkFEX01TR0tFWSwKLSAgICAgICAgICAgICAgICAiQSBjaGF2ZSBkZSBtZW5zYWdlbSAnJ3swfScnIG5cdTAwRTNvIGVzdFx1MDBFMSBuYSBjbGFzc2UgZGUgbWVuc2FnZW0gJyd7MX0nJyIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5CQURfTVNHRk9STUFULAotICAgICAgICAgICAgICAgICJIb3V2ZSBmYWxoYSBubyBmb3JtYXRvIGRhIG1lbnNhZ2VtICcnezB9JycgbmEgY2xhc3NlIGRlIG1lbnNhZ2VtICcnezF9JycuIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX1NFUklBTElaRVJfTk9UX0NPTlRFTlRIQU5ETEVSLAotICAgICAgICAgICAgICAgICJBIGNsYXNzZSAnJ3swfScnIGRvIHNlcmlhbGl6YWRvciBuXHUwMEUzbyBpbXBsZW1lbnRhIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyLiIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9SRVNPVVJDRV9DT1VMRF9OT1RfRklORCwKLSAgICAgICAgICAgICAgICAgICAgIk5cdTAwRTNvIGZvaSBwb3NzXHUwMEVEdmVsIGVuY29udHJhciBvIHJlY3Vyc28gWyB7MH0gXS5cbiB7MX0iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfUkVTT1VSQ0VfQ09VTERfTk9UX0xPQUQsCi0gICAgICAgICAgICAgICAgICAgICJPIHJlY3Vyc28gWyB7MH0gXSBuXHUwMEUzbyBmb2kgY2FycmVnYWRvOiB7MX0gXG4gezJ9IFx0IHszfSIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9CVUZGRVJfU0laRV9MRVNTVEhBTl9aRVJPLAotICAgICAgICAgICAgICAgICAgICAiVGFtYW5obyBkbyBidWZmZXIgPD0wIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0lOVkFMSURfVVRGMTZfU1VSUk9HQVRFLAotICAgICAgICAgICAgICAgICAgICAiRm9pIGRldGVjdGFkbyB1bSBzdWJzdGl0dXRvIGRlIFVURi0xNiBpbnZcdTAwRTFsaWRvOiB7MH0gPyIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9PSUVSUk9SLAotICAgICAgICAgICAgICAgICJFcnJvIGRlIEUvUyIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9JTExFR0FMX0FUVFJJQlVURV9QT1NJVElPTiwKLSAgICAgICAgICAgICAgICAiTlx1MDBFM28gXHUwMEU5IHBvc3NcdTAwRUR2ZWwgYWRpY2lvbmFyIG8gYXRyaWJ1dG8gezB9IGRlcG9pcyBkb3Mgblx1MDBGM3MgZmlsaG9zIG91IGFudGVzIHF1ZSB1bSBlbGVtZW50byBzZWphIHByb2R1emlkby4gTyBhdHJpYnV0byBzZXJcdTAwRTEgaWdub3JhZG8uIiB9LAotCi0gICAgICAgICAgICAvKgotICAgICAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IGNvbnRhaW5lZCBhIHJlZmVyZW5jZSB0byBhCi0gICAgICAgICAgICAgKiBuYW1lc3BhY2UgcHJlZml4IHRoYXQgd2FzIHVuZGVmaW5lZC4gIFRoZSB2YWx1ZSBvZiB0aGUgc3Vic3RpdHV0aW9uCi0gICAgICAgICAgICAgKiB0ZXh0IGlzIHRoZSBuYW1lIG9mIHRoZSBwcmVmaXguCi0gICAgICAgICAgICAgKi8KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfTkFNRVNQQUNFX1BSRUZJWCwKLSAgICAgICAgICAgICAgICAiTyBuYW1lc3BhY2UgZG8gcHJlZml4byAnJ3swfScnIG5cdTAwRTNvIGZvaSBkZWNsYXJhZG8uIiB9LAotCi0gICAgICAgICAgICAvKgotICAgICAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoaXMgbWVzc2FnZSBpcyByZXBvcnRlZCBpZiB0aGUgc3R5bGVzaGVldAotICAgICAgICAgICAgICogYmVpbmcgcHJvY2Vzc2VkIGF0dGVtcHRlZCB0byBjb25zdHJ1Y3QgYW4gWE1MIGRvY3VtZW50IHdpdGggYW4KLSAgICAgICAgICAgICAqIGF0dHJpYnV0ZSBpbiBhIHBsYWNlIG90aGVyIHRoYW4gb24gYW4gZWxlbWVudC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dAotICAgICAgICAgICAgICogc3BlY2lmaWVzIHRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUuCi0gICAgICAgICAgICAgKi8KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfU1RSQVlfQVRUUklCVVRFLAotICAgICAgICAgICAgICAgICJBdHJpYnV0byAnJ3swfScnIGZvcmEgZG8gZWxlbWVudG8uIiB9LAotCi0gICAgICAgICAgICAvKgotICAgICAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIEFzIHdpdGggdGhlIHByZWNlZGluZyBtZXNzYWdlLCBhIG5hbWVzcGFjZQotICAgICAgICAgICAgICogZGVjbGFyYXRpb24gaGFzIHRoZSBmb3JtIG9mIGFuIGF0dHJpYnV0ZSBhbmQgaXMgb25seSBwZXJtaXR0ZWQgdG8KLSAgICAgICAgICAgICAqIGFwcGVhciBvbiBhbiBlbGVtZW50LiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHswfSBpcyB0aGUgbmFtZXNwYWNlCi0gICAgICAgICAgICAgKiBwcmVmaXggYW5kIHsxfSBpcyB0aGUgVVJJIHRoYXQgd2FzIGJlaW5nIHVzZWQgaW4gdGhlIGVycm9uZW91cwotICAgICAgICAgICAgICogbmFtZXNwYWNlIGRlY2xhcmF0aW9uLgotICAgICAgICAgICAgICovCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX1NUUkFZX05BTUVTUEFDRSwKLSAgICAgICAgICAgICAgICAiRGVjbGFyYVx1MDBFN1x1MDBFM28gZGUgbmFtZXNwYWNlICcnezB9Jyc9Jyd7MX0nJyBmb3JhIGRvIGVsZW1lbnRvLiIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9DT1VMRF9OT1RfTE9BRF9SRVNPVVJDRSwKLSAgICAgICAgICAgICAgICAiTlx1MDBFM28gZm9pIHBvc3NcdTAwRUR2ZWwgY2FycmVnYXIgJyd7MH0nJyAodmVyaWZpY2FyIENMQVNTUEFUSCk7IHVzYW5kbyBhZ29yYSBhcGVuYXMgb3MgcGFkclx1MDBGNWVzIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0lMTEVHQUxfQ0hBUkFDVEVSLAotICAgICAgICAgICAgICAgICJUZW50YXRpdmEgZGUgZXhpYmlyIHVtIGNhcmFjdGVyZSBkZSB2YWxvciBpbnRlZ3JhbCB7MH0gcXVlIG5cdTAwRTNvIGVzdFx1MDBFMSByZXByZXNlbnRhZG8gbmEgY29kaWZpY2FcdTAwRTdcdTAwRTNvIGRlIHNhXHUwMEVEZGEgZXNwZWNpZmljYWRhIGRlIHsxfS4iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfQ09VTERfTk9UX0xPQURfTUVUSE9EX1BST1BFUlRZLAotICAgICAgICAgICAgICAgICJOXHUwMEUzbyBmb2kgcG9zc1x1MDBFRHZlbCBjYXJyZWdhciBvIGFycXVpdm8gZGUgcHJvcHJpZWRhZGUgJyd7MH0nJyBwYXJhIG8gbVx1MDBFOXRvZG8gZGUgc2FcdTAwRURkYSAnJ3sxfScnICh2ZXJpZmljYXIgQ0xBU1NQQVRIKSIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9JTlZBTElEX1BPUlQsCi0gICAgICAgICAgICAgICAgIk5cdTAwRkFtZXJvIGRlIHBvcnRhIGludlx1MDBFMWxpZG8iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfUE9SVF9XSEVOX0hPU1RfTlVMTCwKLSAgICAgICAgICAgICAgICAiQSBwb3J0YSBuXHUwMEUzbyBwb2RlIHNlciBkZWZpbmlkYSBxdWFuZG8gbyBob3N0IFx1MDBFOSBudWxvIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0hPU1RfQUREUkVTU19OT1RfV0VMTEZPUk1FRCwKLSAgICAgICAgICAgICAgICAiTyBob3N0IG5cdTAwRTNvIFx1MDBFOSB1bSBlbmRlcmVcdTAwRTdvIGNvcnJldG8iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfU0NIRU1FX05PVF9DT05GT1JNQU5ULAotICAgICAgICAgICAgICAgICJPIGVzcXVlbWEgblx1MDBFM28gXHUwMEU5IGNvbXBhdFx1MDBFRHZlbC4iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfU0NIRU1FX0ZST01fTlVMTF9TVFJJTkcsCi0gICAgICAgICAgICAgICAgIk5cdTAwRTNvIFx1MDBFOSBwb3NzXHUwMEVEdmVsIGRlZmluaXIgbyBlc3F1ZW1hIGRlIHVtYSBzdHJpbmcgbnVsYSIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9QQVRIX0NPTlRBSU5TX0lOVkFMSURfRVNDQVBFX1NFUVVFTkNFLAotICAgICAgICAgICAgICAgICJPIGNhbWluaG8gY29udFx1MDBFOW0gdW1hIHNlcXVcdTAwRUFuY2lhIGludlx1MDBFMWxpZGEgZGUgY2FyYWN0ZXJlcyBkZSBlc2NhcGUiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfUEFUSF9JTlZBTElEX0NIQVIsCi0gICAgICAgICAgICAgICAgIk8gY2FtaW5obyBjb250XHUwMEU5bSB1bSBjYXJhY3RlcmUgaW52XHUwMEUxbGlkbzogezB9IiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0ZSQUdfSU5WQUxJRF9DSEFSLAotICAgICAgICAgICAgICAgICJPIGZyYWdtZW50byBjb250XHUwMEU5bSB1bSBjYXJhY3RlcmUgaW52XHUwMEUxbGlkbyIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9GUkFHX1dIRU5fUEFUSF9OVUxMLAotICAgICAgICAgICAgICAgICJPIGZyYWdtZW50byBuXHUwMEUzbyBwb2RlIHNlciBkZWZpbmlkbyBxdWFuZG8gbyBjYW1pbmhvIFx1MDBFOSBudWxvIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0ZSQUdfRk9SX0dFTkVSSUNfVVJJLAotICAgICAgICAgICAgICAgICJPIGZyYWdtZW50byBzXHUwMEYzIHBvZGUgc2VyIGRlZmluaWRvIHBhcmEgdW0gVVJJIGdlblx1MDBFOXJpY28iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfTk9fU0NIRU1FX0lOX1VSSSwKLSAgICAgICAgICAgICAgICAiTmVuaHVtIGVzcXVlbWEgZW5jb250cmFkbyBubyBVUkkiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfQ0FOTk9UX0lOSVRfVVJJX0VNUFRZX1BBUk1TLAotICAgICAgICAgICAgICAgICJOXHUwMEUzbyBcdTAwRTkgcG9zc1x1MDBFRHZlbCBpbmljaWFsaXphciBvIFVSSSBjb20gcGFyXHUwMEUybWV0cm9zIHZhemlvcyIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9OT19GUkFHTUVOVF9TVFJJTkdfSU5fUEFUSCwKLSAgICAgICAgICAgICAgICAiTyBmcmFnbWVudG8gblx1MDBFM28gcG9kZSBzZXIgZXNwZWNpZmljYWRvIG5vIGNhbWluaG8gbmVtIG5vIGZyYWdtZW50byIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9OT19RVUVSWV9TVFJJTkdfSU5fUEFUSCwKLSAgICAgICAgICAgICAgICAiQSBzdHJpbmcgZGUgY29uc3VsdGEgblx1MDBFM28gcG9kZSBzZXIgZXNwZWNpZmljYWRhIG5vIGNhbWluaG8gbmVtIG5hIHN0cmluZyBkZSBjb25zdWx0YSIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9OT19QT1JUX0lGX05PX0hPU1QsCi0gICAgICAgICAgICAgICAgIkEgcG9ydGEgblx1MDBFM28gcG9kZSBzZXIgZXNwZWNpZmljYWRhIHNlIG8gaG9zdCBuXHUwMEUzbyB0aXZlciBzaWRvIGVzcGVjaWZpY2FkbyIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9OT19VU0VSSU5GT19JRl9OT19IT1NULAotICAgICAgICAgICAgICAgICJBcyBpbmZvcm1hXHUwMEU3XHUwMEY1ZXMgZG8gdXN1XHUwMEUxcmlvIG5cdTAwRTNvIHBvZGVtIHNlciBlc3BlY2lmaWNhZGFzIHNlIG8gaG9zdCBuXHUwMEUzbyB0aXZlciBzaWRvIGVzcGVjaWZpY2FkbyIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9YTUxfVkVSU0lPTl9OT1RfU1VQUE9SVEVELAotICAgICAgICAgICAgICAgICJBZHZlcnRcdTAwRUFuY2lhOiBhIHZlcnNcdTAwRTNvIGRvIGRvY3VtZW50byBkZSBzYVx1MDBFRGRhIGRldmUgc2VyIG9icmlnYXRvcmlhbWVudGUgJyd7MH0nJy4gRXN0YSB2ZXJzXHUwMEUzbyBkbyBYTUwgblx1MDBFM28gXHUwMEU5IHN1cG9ydGFkYS4gQSB2ZXJzXHUwMEUzbyBkbyBkb2N1bWVudG8gZGUgc2FcdTAwRURkYSBzZXJcdTAwRTEgJycxLjAnJy4iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfU0NIRU1FX1JFUVVJUkVELAotICAgICAgICAgICAgICAgICJPIGVzcXVlbWEgXHUwMEU5IG9icmlnYXRcdTAwRjNyaW8hIiB9LAotCi0gICAgICAgICAgICAvKgotICAgICAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSB3b3JkcyAnUHJvcGVydGllcycgYW5kCi0gICAgICAgICAgICAgKiAnU2VyaWFsaXplckZhY3RvcnknIGluIHRoaXMgbWVzc2FnZSBhcmUgSmF2YSBjbGFzcyBuYW1lcwotICAgICAgICAgICAgICogYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICAgICAgICAgICAqLwotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9GQUNUT1JZX1BST1BFUlRZX01JU1NJTkcsCi0gICAgICAgICAgICAgICAgIk8gb2JqZXRvIFByb3BlcnRpZXMgZXNwZWNpZmljYWRvIHBhcmEgYSBTZXJpYWxpemVyRmFjdG9yeSBuXHUwMEUzbyB0ZW0gdW1hIHByb3ByaWVkYWRlICcnezB9JycuIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0VOQ09ESU5HX05PVF9TVVBQT1JURUQsCi0gICAgICAgICAgICAgICAgIkFkdmVydFx1MDBFQW5jaWE6IGEgY29kaWZpY2FcdTAwRTdcdTAwRTNvICcnezB9Jycgblx1MDBFM28gXHUwMEU5IHN1cG9ydGFkYSBwZWxvIEphdmEgcnVudGltZS4iIH0sCi0KLQotICAgICAgICB9OwotCi0gICAgICAgIHJldHVybiBjb250ZW50czsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL3V0aWxzL1NlcmlhbGl6ZXJNZXNzYWdlc19zdi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci91dGlscy9TZXJpYWxpemVyTWVzc2FnZXNfc3YuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZGNhZWFmNC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL3V0aWxzL1NlcmlhbGl6ZXJNZXNzYWdlc19zdi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjA1ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplci51dGlsczsKLQotaW1wb3J0IGphdmEudXRpbC5MaXN0UmVzb3VyY2VCdW5kbGU7Ci1pbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKLWltcG9ydCBqYXZhLnV0aWwuTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uOwotaW1wb3J0IGphdmEudXRpbC5SZXNvdXJjZUJ1bmRsZTsKLQotLyoqCi0gKiBBbiBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIGlzIGEgTGlzdFJlc291cmNlQnVuZGxlIHRoYXQKLSAqIGhhcyB0aGUgcmVxdWlyZWQgZ2V0Q29udGVudHMoKSBtZXRob2QgdGhhdCByZXR1cm5zCi0gKiBhbiBhcnJheSBvZiBtZXNzYWdlLWtleS9tZXNzYWdlIGFzc29jaWF0aW9ucy4KLSAqIDxwPgotICogVGhlIG1lc3NhZ2Uga2V5cyBhcmUgZGVmaW5lZCBpbiB7QGxpbmsgTXNnS2V5fS4gVGhlCi0gKiBtZXNzYWdlcyB0aGF0IHRob3NlIGtleXMgbWFwIHRvIGFyZSBkZWZpbmVkIGhlcmUuCi0gKiA8cD4KLSAqIFRoZSBtZXNzYWdlcyBpbiB0aGUgRW5nbGlzaCB2ZXJzaW9uIGFyZSBpbnRlbmRlZCB0byBiZQotICogdHJhbnNsYXRlZC4KLSAqCi0gKiBUaGlzIGNsYXNzIGlzIG5vdCBhIHB1YmxpYyBBUEksIGl0IGlzIG9ubHkgcHVibGljIGJlY2F1c2UgaXQgaXMKLSAqIHVzZWQgaW4gY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyLgotICoKLSAqIEB4c2wudXNhZ2UgaW50ZXJuYWwKLSAqLwotcHVibGljIGNsYXNzIFNlcmlhbGl6ZXJNZXNzYWdlc19zdiBleHRlbmRzIExpc3RSZXNvdXJjZUJ1bmRsZSB7Ci0KLSAgICAvKgotICAgICAqIFRoaXMgZmlsZSBjb250YWlucyBlcnJvciBhbmQgd2FybmluZyBtZXNzYWdlcyByZWxhdGVkIHRvCi0gICAgICogU2VyaWFsaXplciBFcnJvciBIYW5kbGluZy4KLSAgICAgKgotICAgICAqICBHZW5lcmFsIG5vdGVzIHRvIHRyYW5zbGF0b3JzOgotCi0gICAgICogIDEpIEEgc3R5bGVzaGVldCBpcyBhIGRlc2NyaXB0aW9uIG9mIGhvdyB0byB0cmFuc2Zvcm0gYW4gaW5wdXQgWE1MIGRvY3VtZW50Ci0gICAgICogICAgIGludG8gYSByZXN1bHRhbnQgWE1MIGRvY3VtZW50IChvciBIVE1MIGRvY3VtZW50IG9yIHRleHQpLiAgVGhlCi0gICAgICogICAgIHN0eWxlc2hlZXQgaXRzZWxmIGlzIGRlc2NyaWJlZCBpbiB0aGUgZm9ybSBvZiBhbiBYTUwgZG9jdW1lbnQuCi0KLSAgICAgKgotICAgICAqICAyKSBBbiBlbGVtZW50IGlzIGEgbWFyay11cCB0YWcgaW4gYW4gWE1MIGRvY3VtZW50OyBhbiBhdHRyaWJ1dGUgaXMgYQotICAgICAqICAgICBtb2RpZmllciBvbiB0aGUgdGFnLiAgRm9yIGV4YW1wbGUsIGluIDxlbGVtIGF0dHI9J3ZhbCcgYXR0cjI9J3ZhbDInPgotICAgICAqICAgICAiZWxlbSIgaXMgYW4gZWxlbWVudCBuYW1lLCAiYXR0ciIgYW5kICJhdHRyMiIgYXJlIGF0dHJpYnV0ZSBuYW1lcyB3aXRoCi0gICAgICogICAgIHRoZSB2YWx1ZXMgInZhbCIgYW5kICJ2YWwyIiwgcmVzcGVjdGl2ZWx5LgotICAgICAqCi0gICAgICogIDMpIEEgbmFtZXNwYWNlIGRlY2xhcmF0aW9uIGlzIGEgc3BlY2lhbCBhdHRyaWJ1dGUgdGhhdCBpcyB1c2VkIHRvIGFzc29jaWF0ZQotICAgICAqICAgICBhIHByZWZpeCB3aXRoIGEgVVJJICh0aGUgbmFtZXNwYWNlKS4gIFRoZSBtZWFuaW5ncyBvZiBlbGVtZW50IG5hbWVzIGFuZAotICAgICAqICAgICBhdHRyaWJ1dGUgbmFtZXMgdGhhdCB1c2UgdGhhdCBwcmVmaXggYXJlIGRlZmluZWQgd2l0aCByZXNwZWN0IHRvIHRoYXQKLSAgICAgKiAgICAgbmFtZXNwYWNlLgotICAgICAqCi0gICAgICoKLSAgICAgKi8KLQotICAgIC8qKiBUaGUgbG9va3VwIHRhYmxlIGZvciBlcnJvciBtZXNzYWdlcy4gICAqLwotICAgIHB1YmxpYyBPYmplY3RbXVtdIGdldENvbnRlbnRzKCkgewotICAgICAgICBPYmplY3RbXVtdIGNvbnRlbnRzID0gbmV3IE9iamVjdFtdW10gewotICAgICAgICAgICAgeyAgIE1zZ0tleS5CQURfTVNHS0VZLAotICAgICAgICAgICAgICAgICJNZWRkZWxhbmRlbnlja2VsbiAnJ3swfScnIFx1MDBFNHIgaW50ZSBpIG1lZGRlbGFuZGVrbGFzc2VuICcnezF9JyciIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuQkFEX01TR0ZPUk1BVCwKLSAgICAgICAgICAgICAgICAiRm9ybWF0ZXQgcFx1MDBFNSBtZWRkZWxhbmRldCAnJ3swfScnIGkgbWVkZGVsYW5kZWtsYXNzZW4gJyd7MX0nJyB1bmRlcmtcdTAwRTRuZGVzLiIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9TRVJJQUxJWkVSX05PVF9DT05URU5USEFORExFUiwKLSAgICAgICAgICAgICAgICAiU2VyaWFsaXplcmtsYXNzZW4gJyd7MH0nJyBpbXBsZW1lbnRlcmFyIGludGUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIuIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX1JFU09VUkNFX0NPVUxEX05PVF9GSU5ELAotICAgICAgICAgICAgICAgICAgICAiUmVzdXJzZW4gWyB7MH0gXSBrdW5kZSBpbnRlIGhcdTAwRTRtdGFzLlxuIHsxfSIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9SRVNPVVJDRV9DT1VMRF9OT1RfTE9BRCwKLSAgICAgICAgICAgICAgICAgICAgIlJlc3Vyc2VuIFsgezB9IF0ga3VuZGUgaW50ZSBsYWRkYXM6IHsxfSBcbiB7Mn0gXHQgezN9IiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0JVRkZFUl9TSVpFX0xFU1NUSEFOX1pFUk8sCi0gICAgICAgICAgICAgICAgICAgICJCdWZmZXJ0c3RvcmxlayA8PTAiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfSU5WQUxJRF9VVEYxNl9TVVJST0dBVEUsCi0gICAgICAgICAgICAgICAgICAgICJPZ2lsdGlndCBVVEYtMTYtc3Vycm9nYXQgdXBwdFx1MDBFNGNrdDogezB9ID8iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfT0lFUlJPUiwKLSAgICAgICAgICAgICAgICAiSU8tZmVsIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0lMTEVHQUxfQVRUUklCVVRFX1BPU0lUSU9OLAotICAgICAgICAgICAgICAgICJLYW4gaW50ZSBsXHUwMEU0Z2dhIHRpbGwgYXR0cmlidXRldCB7MH0gZWZ0ZXIgdW5kZXJvcmRuYWRlIG5vZGVyIGVsbGVyIGlubmFuIGV0dCBlbGVtZW50IGhhciBza2FwYXRzLiBBdHRyaWJ1dGV0IGlnbm9yZXJhcy4iIH0sCi0KLSAgICAgICAgICAgIC8qCi0gICAgICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN0eWxlc2hlZXQgY29udGFpbmVkIGEgcmVmZXJlbmNlIHRvIGEKLSAgICAgICAgICAgICAqIG5hbWVzcGFjZSBwcmVmaXggdGhhdCB3YXMgdW5kZWZpbmVkLiAgVGhlIHZhbHVlIG9mIHRoZSBzdWJzdGl0dXRpb24KLSAgICAgICAgICAgICAqIHRleHQgaXMgdGhlIG5hbWUgb2YgdGhlIHByZWZpeC4KLSAgICAgICAgICAgICAqLwotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9OQU1FU1BBQ0VfUFJFRklYLAotICAgICAgICAgICAgICAgICJOYW1ucnltZCBmXHUwMEY2ciBwcmVmaXggJyd7MH0nJyBoYXIgaW50ZSBkZWtsYXJlcmF0cy4iIH0sCi0KLSAgICAgICAgICAgIC8qCi0gICAgICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIHJlcG9ydGVkIGlmIHRoZSBzdHlsZXNoZWV0Ci0gICAgICAgICAgICAgKiBiZWluZyBwcm9jZXNzZWQgYXR0ZW1wdGVkIHRvIGNvbnN0cnVjdCBhbiBYTUwgZG9jdW1lbnQgd2l0aCBhbgotICAgICAgICAgICAgICogYXR0cmlidXRlIGluIGEgcGxhY2Ugb3RoZXIgdGhhbiBvbiBhbiBlbGVtZW50LiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgICAgICAgKiBzcGVjaWZpZXMgdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgICAgICAgICAqLwotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9TVFJBWV9BVFRSSUJVVEUsCi0gICAgICAgICAgICAgICAgIkF0dHJpYnV0ZXQgJyd7MH0nJyBmaW5ucyB1dGFuZlx1MDBGNnIgZWxlbWVudGV0LiIgfSwKLQotICAgICAgICAgICAgLyoKLSAgICAgICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBcyB3aXRoIHRoZSBwcmVjZWRpbmcgbWVzc2FnZSwgYSBuYW1lc3BhY2UKLSAgICAgICAgICAgICAqIGRlY2xhcmF0aW9uIGhhcyB0aGUgZm9ybSBvZiBhbiBhdHRyaWJ1dGUgYW5kIGlzIG9ubHkgcGVybWl0dGVkIHRvCi0gICAgICAgICAgICAgKiBhcHBlYXIgb24gYW4gZWxlbWVudC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCB7MH0gaXMgdGhlIG5hbWVzcGFjZQotICAgICAgICAgICAgICogcHJlZml4IGFuZCB7MX0gaXMgdGhlIFVSSSB0aGF0IHdhcyBiZWluZyB1c2VkIGluIHRoZSBlcnJvbmVvdXMKLSAgICAgICAgICAgICAqIG5hbWVzcGFjZSBkZWNsYXJhdGlvbi4KLSAgICAgICAgICAgICAqLwotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9TVFJBWV9OQU1FU1BBQ0UsCi0gICAgICAgICAgICAgICAgIk5hbW5yeW1kc2Rla2xhcmF0aW9uZW4gJyd7MH0nJz0nJ3sxfScnIGZpbm5zIHV0YW5mXHUwMEY2ciBlbGVtZW50LiIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9DT1VMRF9OT1RfTE9BRF9SRVNPVVJDRSwKLSAgICAgICAgICAgICAgICAiS3VuZGUgaW50ZSBsYWRkYSAnJ3swfScnIChrb250cm9sbGVyYSBDTEFTU1BBVEgpLCBhbnZcdTAwRTRuZGVyIG51IGVuYmFydCBzdGFuZGFyZHZcdTAwRTRyZGVuIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0lMTEVHQUxfQ0hBUkFDVEVSLAotICAgICAgICAgICAgICAgICJGXHUwMEY2cnNcdTAwRjZrIGF0dCBza3JpdmEgdXRkYXRhdGVja2VuIG1lZCBpbnRlZ3JhbHZcdTAwRTRyZGV0IHswfSBzb20gaW50ZSBcdTAwRTRyIHJlcHJlc2VudGVyYXQgaSBhbmdpdmVuIHV0ZGF0YWtvZG5pbmcgYXYgezF9LiIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9DT1VMRF9OT1RfTE9BRF9NRVRIT0RfUFJPUEVSVFksCi0gICAgICAgICAgICAgICAgIkt1bmRlIGludGUgbGFkZGEgZWdlbnNrYXBzZmlsZW4gJyd7MH0nJyBmXHUwMEY2ciB1dGRhdGFtZXRvZGVuICcnezF9JycgKGtvbnRyb2xsZXJhIENMQVNTUEFUSCkiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfSU5WQUxJRF9QT1JULAotICAgICAgICAgICAgICAgICJPZ2lsdGlndCBwb3J0bnVtbWVyIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX1BPUlRfV0hFTl9IT1NUX05VTEwsCi0gICAgICAgICAgICAgICAgIlBvcnQga2FuIGludGUgc3RcdTAwRTRsbGFzIGluIG5cdTAwRTRyIHZcdTAwRTRyZCBcdTAwRTRyIG51bGwiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfSE9TVF9BRERSRVNTX05PVF9XRUxMRk9STUVELAotICAgICAgICAgICAgICAgICJWXHUwMEU0cmQgXHUwMEU0ciBpbnRlIGVuIHZcdTAwRTRsZm9ybXVsZXJhZCBhZHJlc3MiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfU0NIRU1FX05PVF9DT05GT1JNQU5ULAotICAgICAgICAgICAgICAgICJTY2hlbWF0IFx1MDBFNHIgaW50ZSBsaWtmb3JtaWd0LiIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9TQ0hFTUVfRlJPTV9OVUxMX1NUUklORywKLSAgICAgICAgICAgICAgICAiS2FuIGludGUgc3RcdTAwRTRsbGEgaW4gc2NoZW1hIGZyXHUwMEU1biBudWxsLXN0clx1MDBFNG5nIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX1BBVEhfQ09OVEFJTlNfSU5WQUxJRF9FU0NBUEVfU0VRVUVOQ0UsCi0gICAgICAgICAgICAgICAgIlNcdTAwRjZrdlx1MDBFNGdlbiBpbm5laFx1MDBFNWxsZXIgZW4gb2dpbHRpZyBlc2NhcGUtc2VrdmVucyIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9QQVRIX0lOVkFMSURfQ0hBUiwKLSAgICAgICAgICAgICAgICAiU1x1MDBGNmt2XHUwMEU0Z2VuIGlubmVoXHUwMEU1bGxlciBldHQgb2dpbHRpZ3QgdGVja2VuOiB7MH0iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfRlJBR19JTlZBTElEX0NIQVIsCi0gICAgICAgICAgICAgICAgIkZyYWdtZW50IGlubmVoXHUwMEU1bGxlciBldHQgb2dpbHRpZ3QgdGVja2VuIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0ZSQUdfV0hFTl9QQVRIX05VTEwsCi0gICAgICAgICAgICAgICAgIkZyYWdtZW50IGthbiBpbnRlIHN0XHUwMEU0bGxhcyBpbiBuXHUwMEU0ciBzXHUwMEY2a3ZcdTAwRTRnIFx1MDBFNHIgbnVsbCIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9GUkFHX0ZPUl9HRU5FUklDX1VSSSwKLSAgICAgICAgICAgICAgICAiRnJhZ21lbnQga2FuIGJhcmEgc3RcdTAwRTRsbGFzIGluIGZcdTAwRjZyIGVuIGFsbG1cdTAwRTRuIFVSSSIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9OT19TQ0hFTUVfSU5fVVJJLAotICAgICAgICAgICAgICAgICJTY2hlbWEgc2FrbmFzIGkgVVJJIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0NBTk5PVF9JTklUX1VSSV9FTVBUWV9QQVJNUywKLSAgICAgICAgICAgICAgICAiS2FuIGludGUgaW5pdGllcmEgVVJJIG1lZCB0b21tYSBwYXJhbWV0cmFyIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX05PX0ZSQUdNRU5UX1NUUklOR19JTl9QQVRILAotICAgICAgICAgICAgICAgICJGcmFnbWVudCBrYW4gaW50ZSBhbmdlcyBpIGJcdTAwRTVkZSBzXHUwMEY2a3ZcdTAwRTRnZW4gb2NoIGZyYWdtZW50ZXQiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfTk9fUVVFUllfU1RSSU5HX0lOX1BBVEgsCi0gICAgICAgICAgICAgICAgIkZyXHUwMEU1Z2VzdHJcdTAwRTRuZyBrYW4gaW50ZSBhbmdlcyBpIGJcdTAwRTVkZSBzXHUwMEY2a3ZcdTAwRTRnZW4gb2NoIGZyXHUwMEU1Z2VzdHJcdTAwRTRuZ2VuIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX05PX1BPUlRfSUZfTk9fSE9TVCwKLSAgICAgICAgICAgICAgICAiUG9ydCBmXHUwMEU1ciBpbnRlIGFuZ2VzIG9tIHZcdTAwRTRyZGVuIGludGUgXHUwMEU0ciBhbmdpdmVuIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX05PX1VTRVJJTkZPX0lGX05PX0hPU1QsCi0gICAgICAgICAgICAgICAgIkFudlx1MDBFNG5kYXJpbmZvIGZcdTAwRTVyIGludGUgYW5nZXMgb20gdlx1MDBFNHJkZW4gaW50ZSBcdTAwRTRyIGFuZ2l2ZW4iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfWE1MX1ZFUlNJT05fTk9UX1NVUFBPUlRFRCwKLSAgICAgICAgICAgICAgICAiVmFybmluZzogIFZlcnNpb25lbiBhdiB1dGRhdGFkb2t1bWVudGV0IHNvbSBiZWdcdTAwRTRydHMgXHUwMEU0ciAnJ3swfScnLiAgRGVuIGhcdTAwRTRyIHZlcnNpb25lbiBhdiBYTUwgc3RcdTAwRjZkcyBpbnRlLiAgVmVyc2lvbmVuIGF2IHV0ZGF0YWRva3VtZW50ZXQga29tbWVyIGF0dCB2YXJhICcnMS4wJycuIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX1NDSEVNRV9SRVFVSVJFRCwKLSAgICAgICAgICAgICAgICAiU2NoZW1hIGtyXHUwMEU0dnMhIiB9LAotCi0gICAgICAgICAgICAvKgotICAgICAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSB3b3JkcyAnUHJvcGVydGllcycgYW5kCi0gICAgICAgICAgICAgKiAnU2VyaWFsaXplckZhY3RvcnknIGluIHRoaXMgbWVzc2FnZSBhcmUgSmF2YSBjbGFzcyBuYW1lcwotICAgICAgICAgICAgICogYW5kIHNob3VsZCBub3QgYmUgdHJhbnNsYXRlZC4KLSAgICAgICAgICAgICAqLwotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9GQUNUT1JZX1BST1BFUlRZX01JU1NJTkcsCi0gICAgICAgICAgICAgICAgIkVnZW5za2Fwc29iamVrdGV0IHNvbSBcdTAwRjZ2ZXJmXHUwMEY2cnRzIHRpbGwgU2VyaWFsaXplckZhY3RvcnkgaGFyIGluZ2VuICcnezB9JyctZWdlbnNrYXAuIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0VOQ09ESU5HX05PVF9TVVBQT1JURUQsCi0gICAgICAgICAgICAgICAgIlZhcm5pbmc6IEtvZG5pbmdlbiAnJ3swfScnIHN0XHUwMEY2ZHMgaW50ZSBhdiBKYXZhIHJ1bnRpbWUuIiB9LAotCi0KLSAgICAgICAgfTsKLQotICAgICAgICByZXR1cm4gY29udGVudHM7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci91dGlscy9TZXJpYWxpemVyTWVzc2FnZXNfemhfQ04uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvdXRpbHMvU2VyaWFsaXplck1lc3NhZ2VzX3poX0NOLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDdlNWRhN2YuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci91dGlscy9TZXJpYWxpemVyTWVzc2FnZXNfemhfQ04uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIwNSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXIudXRpbHM7Ci0KLWltcG9ydCBqYXZhLnV0aWwuTGlzdFJlc291cmNlQnVuZGxlOwotaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7Ci1pbXBvcnQgamF2YS51dGlsLk1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuUmVzb3VyY2VCdW5kbGU7Ci0KLS8qKgotICogQW4gaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcyBpcyBhIExpc3RSZXNvdXJjZUJ1bmRsZSB0aGF0Ci0gKiBoYXMgdGhlIHJlcXVpcmVkIGdldENvbnRlbnRzKCkgbWV0aG9kIHRoYXQgcmV0dXJucwotICogYW4gYXJyYXkgb2YgbWVzc2FnZS1rZXkvbWVzc2FnZSBhc3NvY2lhdGlvbnMuCi0gKiA8cD4KLSAqIFRoZSBtZXNzYWdlIGtleXMgYXJlIGRlZmluZWQgaW4ge0BsaW5rIE1zZ0tleX0uIFRoZQotICogbWVzc2FnZXMgdGhhdCB0aG9zZSBrZXlzIG1hcCB0byBhcmUgZGVmaW5lZCBoZXJlLgotICogPHA+Ci0gKiBUaGUgbWVzc2FnZXMgaW4gdGhlIEVuZ2xpc2ggdmVyc2lvbiBhcmUgaW50ZW5kZWQgdG8gYmUKLSAqIHRyYW5zbGF0ZWQuCi0gKgotICogVGhpcyBjbGFzcyBpcyBub3QgYSBwdWJsaWMgQVBJLCBpdCBpcyBvbmx5IHB1YmxpYyBiZWNhdXNlIGl0IGlzCi0gKiB1c2VkIGluIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplci4KLSAqCi0gKiBAeHNsLnVzYWdlIGludGVybmFsCi0gKi8KLXB1YmxpYyBjbGFzcyBTZXJpYWxpemVyTWVzc2FnZXNfemhfQ04gZXh0ZW5kcyBMaXN0UmVzb3VyY2VCdW5kbGUgewotCi0gICAgLyoKLSAgICAgKiBUaGlzIGZpbGUgY29udGFpbnMgZXJyb3IgYW5kIHdhcm5pbmcgbWVzc2FnZXMgcmVsYXRlZCB0bwotICAgICAqIFNlcmlhbGl6ZXIgRXJyb3IgSGFuZGxpbmcuCi0gICAgICoKLSAgICAgKiAgR2VuZXJhbCBub3RlcyB0byB0cmFuc2xhdG9yczoKLQotICAgICAqICAxKSBBIHN0eWxlc2hlZXQgaXMgYSBkZXNjcmlwdGlvbiBvZiBob3cgdG8gdHJhbnNmb3JtIGFuIGlucHV0IFhNTCBkb2N1bWVudAotICAgICAqICAgICBpbnRvIGEgcmVzdWx0YW50IFhNTCBkb2N1bWVudCAob3IgSFRNTCBkb2N1bWVudCBvciB0ZXh0KS4gIFRoZQotICAgICAqICAgICBzdHlsZXNoZWV0IGl0c2VsZiBpcyBkZXNjcmliZWQgaW4gdGhlIGZvcm0gb2YgYW4gWE1MIGRvY3VtZW50LgotCi0gICAgICoKLSAgICAgKiAgMikgQW4gZWxlbWVudCBpcyBhIG1hcmstdXAgdGFnIGluIGFuIFhNTCBkb2N1bWVudDsgYW4gYXR0cmlidXRlIGlzIGEKLSAgICAgKiAgICAgbW9kaWZpZXIgb24gdGhlIHRhZy4gIEZvciBleGFtcGxlLCBpbiA8ZWxlbSBhdHRyPSd2YWwnIGF0dHIyPSd2YWwyJz4KLSAgICAgKiAgICAgImVsZW0iIGlzIGFuIGVsZW1lbnQgbmFtZSwgImF0dHIiIGFuZCAiYXR0cjIiIGFyZSBhdHRyaWJ1dGUgbmFtZXMgd2l0aAotICAgICAqICAgICB0aGUgdmFsdWVzICJ2YWwiIGFuZCAidmFsMiIsIHJlc3BlY3RpdmVseS4KLSAgICAgKgotICAgICAqICAzKSBBIG5hbWVzcGFjZSBkZWNsYXJhdGlvbiBpcyBhIHNwZWNpYWwgYXR0cmlidXRlIHRoYXQgaXMgdXNlZCB0byBhc3NvY2lhdGUKLSAgICAgKiAgICAgYSBwcmVmaXggd2l0aCBhIFVSSSAodGhlIG5hbWVzcGFjZSkuICBUaGUgbWVhbmluZ3Mgb2YgZWxlbWVudCBuYW1lcyBhbmQKLSAgICAgKiAgICAgYXR0cmlidXRlIG5hbWVzIHRoYXQgdXNlIHRoYXQgcHJlZml4IGFyZSBkZWZpbmVkIHdpdGggcmVzcGVjdCB0byB0aGF0Ci0gICAgICogICAgIG5hbWVzcGFjZS4KLSAgICAgKgotICAgICAqCi0gICAgICovCi0KLSAgICAvKiogVGhlIGxvb2t1cCB0YWJsZSBmb3IgZXJyb3IgbWVzc2FnZXMuICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0W11bXSBnZXRDb250ZW50cygpIHsKLSAgICAgICAgT2JqZWN0W11bXSBjb250ZW50cyA9IG5ldyBPYmplY3RbXVtdIHsKLSAgICAgICAgICAgIHsgICBNc2dLZXkuQkFEX01TR0tFWSwKLSAgICAgICAgICAgICAgICAiXHU2RDg4XHU2MDZGXHU1MTczXHU5NTJFXHU1QjU3ICcnezB9JycgXHU0RTBEXHU1NzI4XHU2RDg4XHU2MDZGXHU3QzdCICcnezF9JycgXHU0RTJEIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkJBRF9NU0dGT1JNQVQsCi0gICAgICAgICAgICAgICAgIlx1NkQ4OFx1NjA2Rlx1N0M3QiAnJ3sxfScnIFx1NEUyRFx1NkQ4OFx1NjA2RiAnJ3swfScnIFx1NzY4NFx1NjgzQ1x1NUYwRlx1NTMxNlx1NTkzMVx1OEQyNVx1MzAwMiIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9TRVJJQUxJWkVSX05PVF9DT05URU5USEFORExFUiwKLSAgICAgICAgICAgICAgICAiXHU0RTMyXHU4ODRDXHU1NjY4XHU3QzdCICcnezB9JycgXHU0RTBEXHU1QjlFXHU3M0IwIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyXHUzMDAyIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX1JFU09VUkNFX0NPVUxEX05PVF9GSU5ELAotICAgICAgICAgICAgICAgICAgICAiXHU2MjdFXHU0RTBEXHU1MjMwXHU4RDQ0XHU2RTkwIFsgezB9IF1cdTMwMDJcbiB7MX0iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfUkVTT1VSQ0VfQ09VTERfTk9UX0xPQUQsCi0gICAgICAgICAgICAgICAgICAgICJcdThENDRcdTZFOTAgWyB7MH0gXSBcdTY1RTBcdTZDRDVcdTUyQTBcdThGN0Q6IHsxfSBcbiB7Mn0gXHQgezN9IiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0JVRkZFUl9TSVpFX0xFU1NUSEFOX1pFUk8sCi0gICAgICAgICAgICAgICAgICAgICJcdTdGMTNcdTUxQjJcdTUzM0FcdTU5MjdcdTVDMEYgPD0wIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0lOVkFMSURfVVRGMTZfU1VSUk9HQVRFLAotICAgICAgICAgICAgICAgICAgICAiXHU2OEMwXHU2RDRCXHU1MjMwXHU2NUUwXHU2NTQ4XHU3Njg0IFVURi0xNiBcdTRFRTNcdTc0MDY6IHswfT8iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfT0lFUlJPUiwKLSAgICAgICAgICAgICAgICAiSU8gXHU5NTE5XHU4QkVGIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0lMTEVHQUxfQVRUUklCVVRFX1BPU0lUSU9OLAotICAgICAgICAgICAgICAgICJcdTU3MjhcdTc1MUZcdTYyMTBcdTVCNTBcdTgyODJcdTcwQjlcdTRFNEJcdTU0MEVcdTYyMTZcdTU3MjhcdTc1MUZcdTYyMTBcdTUxNDNcdTdEMjBcdTRFNEJcdTUyNERcdTY1RTBcdTZDRDVcdTZERkJcdTUyQTBcdTVDNUVcdTYwMjcgezB9XHUzMDAyXHU1QzA2XHU1RkZEXHU3NTY1XHU1QzVFXHU2MDI3XHUzMDAyIiB9LAotCi0gICAgICAgICAgICAvKgotICAgICAgICAgICAgICogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdHlsZXNoZWV0IGNvbnRhaW5lZCBhIHJlZmVyZW5jZSB0byBhCi0gICAgICAgICAgICAgKiBuYW1lc3BhY2UgcHJlZml4IHRoYXQgd2FzIHVuZGVmaW5lZC4gIFRoZSB2YWx1ZSBvZiB0aGUgc3Vic3RpdHV0aW9uCi0gICAgICAgICAgICAgKiB0ZXh0IGlzIHRoZSBuYW1lIG9mIHRoZSBwcmVmaXguCi0gICAgICAgICAgICAgKi8KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfTkFNRVNQQUNFX1BSRUZJWCwKLSAgICAgICAgICAgICAgICAiXHU2Q0ExXHU2NzA5XHU4QkY0XHU2NjBFXHU1NDBEXHU3OUYwXHU3QTdBXHU5NUY0XHU1MjREXHU3RjAwICcnezB9JydcdTMwMDIiIH0sCi0KLSAgICAgICAgICAgIC8qCi0gICAgICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIHJlcG9ydGVkIGlmIHRoZSBzdHlsZXNoZWV0Ci0gICAgICAgICAgICAgKiBiZWluZyBwcm9jZXNzZWQgYXR0ZW1wdGVkIHRvIGNvbnN0cnVjdCBhbiBYTUwgZG9jdW1lbnQgd2l0aCBhbgotICAgICAgICAgICAgICogYXR0cmlidXRlIGluIGEgcGxhY2Ugb3RoZXIgdGhhbiBvbiBhbiBlbGVtZW50LiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgICAgICAgKiBzcGVjaWZpZXMgdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgICAgICAgICAqLwotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9TVFJBWV9BVFRSSUJVVEUsCi0gICAgICAgICAgICAgICAgIlx1NUM1RVx1NjAyNyAnJ3swfScnIFx1NTcyOFx1NTE0M1x1N0QyMFx1NTkxNlx1OTBFOFx1MzAwMiIgfSwKLQotICAgICAgICAgICAgLyoKLSAgICAgICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBcyB3aXRoIHRoZSBwcmVjZWRpbmcgbWVzc2FnZSwgYSBuYW1lc3BhY2UKLSAgICAgICAgICAgICAqIGRlY2xhcmF0aW9uIGhhcyB0aGUgZm9ybSBvZiBhbiBhdHRyaWJ1dGUgYW5kIGlzIG9ubHkgcGVybWl0dGVkIHRvCi0gICAgICAgICAgICAgKiBhcHBlYXIgb24gYW4gZWxlbWVudC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCB7MH0gaXMgdGhlIG5hbWVzcGFjZQotICAgICAgICAgICAgICogcHJlZml4IGFuZCB7MX0gaXMgdGhlIFVSSSB0aGF0IHdhcyBiZWluZyB1c2VkIGluIHRoZSBlcnJvbmVvdXMKLSAgICAgICAgICAgICAqIG5hbWVzcGFjZSBkZWNsYXJhdGlvbi4KLSAgICAgICAgICAgICAqLwotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9TVFJBWV9OQU1FU1BBQ0UsCi0gICAgICAgICAgICAgICAgIlx1NTQwRFx1NzlGMFx1N0E3QVx1OTVGNFx1NThGMFx1NjYwRSAnJ3swfScnPScnezF9JycgXHU1NzI4XHU1MTQzXHU3RDIwXHU1OTE2XHU5MEU4XHUzMDAyIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0NPVUxEX05PVF9MT0FEX1JFU09VUkNFLAotICAgICAgICAgICAgICAgICJcdTY1RTBcdTZDRDVcdTUyQTBcdThGN0QgJyd7MH0nJyAoXHU2OEMwXHU2N0U1IENMQVNTUEFUSCksIFx1NzNCMFx1NTcyOFx1NTNFQVx1NEY3Rlx1NzUyOFx1OUVEOFx1OEJBNFx1NTAzQyIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9JTExFR0FMX0NIQVJBQ1RFUiwKLSAgICAgICAgICAgICAgICAiXHU1QzFEXHU4QkQ1XHU4RjkzXHU1MUZBXHU2NzJBXHU0RUU1ezF9XHU3Njg0XHU2MzA3XHU1QjlBXHU4RjkzXHU1MUZBXHU3RjE2XHU3ODAxXHU4ODY4XHU3OTNBXHU3Njg0XHU2NTc0XHU2NTcwXHU1MDNDIHswfSBcdTc2ODRcdTVCNTdcdTdCMjZcdTMwMDIiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfQ09VTERfTk9UX0xPQURfTUVUSE9EX1BST1BFUlRZLAotICAgICAgICAgICAgICAgICJcdTY1RTBcdTZDRDVcdTRFM0FcdThGOTNcdTUxRkFcdTY1QjlcdTZDRDUgJyd7MX0nJyBcdTUyQTBcdThGN0RcdTVDNUVcdTYwMjdcdTY1ODdcdTRFRjYgJyd7MH0nJyAoXHU2OEMwXHU2N0U1IENMQVNTUEFUSCkiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfSU5WQUxJRF9QT1JULAotICAgICAgICAgICAgICAgICJcdTY1RTBcdTY1NDhcdTc2ODRcdTdBRUZcdTUzRTNcdTUzRjciIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfUE9SVF9XSEVOX0hPU1RfTlVMTCwKLSAgICAgICAgICAgICAgICAiXHU0RTNCXHU2NzNBXHU0RTNBXHU3QTdBXHU2NUY2LCBcdTY1RTBcdTZDRDVcdThCQkVcdTdGNkVcdTdBRUZcdTUzRTMiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfSE9TVF9BRERSRVNTX05PVF9XRUxMRk9STUVELAotICAgICAgICAgICAgICAgICJcdTRFM0JcdTY3M0FcdTRFMERcdTY2MkZcdTY4M0NcdTVGMEZcdTgyNkZcdTU5N0RcdTc2ODRcdTU3MzBcdTU3NDAiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfU0NIRU1FX05PVF9DT05GT1JNQU5ULAotICAgICAgICAgICAgICAgICJcdTY1QjlcdTY4NDhcdTRFMERcdTRFMDBcdTgxRjRcdTMwMDIiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfU0NIRU1FX0ZST01fTlVMTF9TVFJJTkcsCi0gICAgICAgICAgICAgICAgIlx1NjVFMFx1NkNENVx1NEVDRVx1N0E3QVx1NUI1N1x1N0IyNlx1NEUzMlx1OEJCRVx1N0Y2RVx1NjVCOVx1Njg0OCIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9QQVRIX0NPTlRBSU5TX0lOVkFMSURfRVNDQVBFX1NFUVVFTkNFLAotICAgICAgICAgICAgICAgICJcdThERUZcdTVGODRcdTUzMDVcdTU0MkJcdTY1RTBcdTY1NDhcdTc2ODRcdThGNkNcdTRFNDlcdTVFOEZcdTUyMTciIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfUEFUSF9JTlZBTElEX0NIQVIsCi0gICAgICAgICAgICAgICAgIlx1OERFRlx1NUY4NFx1NTMwNVx1NTQyQlx1NjVFMFx1NjU0OFx1NzY4NFx1NUI1N1x1N0IyNjogezB9IiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0ZSQUdfSU5WQUxJRF9DSEFSLAotICAgICAgICAgICAgICAgICJcdTcyNDdcdTZCQjVcdTUzMDVcdTU0MkJcdTY1RTBcdTY1NDhcdTc2ODRcdTVCNTdcdTdCMjYiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfRlJBR19XSEVOX1BBVEhfTlVMTCwKLSAgICAgICAgICAgICAgICAiXHU4REVGXHU1Rjg0XHU0RTNBXHU3QTdBXHU2NUY2LCBcdTY1RTBcdTZDRDVcdThCQkVcdTdGNkVcdTcyNDdcdTZCQjUiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfRlJBR19GT1JfR0VORVJJQ19VUkksCi0gICAgICAgICAgICAgICAgIlx1NTNFQVx1ODBGRFx1NEUzQVx1NEUwMFx1ODIyQyBVUkkgXHU4QkJFXHU3RjZFXHU3MjQ3XHU2QkI1IiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX05PX1NDSEVNRV9JTl9VUkksCi0gICAgICAgICAgICAgICAgIlx1NTcyOCBVUkkgXHU0RTJEXHU2MjdFXHU0RTBEXHU1MjMwXHU2NUI5XHU2ODQ4IiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0NBTk5PVF9JTklUX1VSSV9FTVBUWV9QQVJNUywKLSAgICAgICAgICAgICAgICAiXHU2NUUwXHU2Q0Q1XHU0RUU1XHU3QTdBXHU1M0MyXHU2NTcwXHU1MjFEXHU1OUNCXHU1MzE2IFVSSSIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9OT19GUkFHTUVOVF9TVFJJTkdfSU5fUEFUSCwKLSAgICAgICAgICAgICAgICAiXHU4REVGXHU1Rjg0XHU1NDhDXHU3MjQ3XHU2QkI1XHU0RTJEXHU5MEZEXHU2NUUwXHU2Q0Q1XHU2MzA3XHU1QjlBXHU3MjQ3XHU2QkI1IiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX05PX1FVRVJZX1NUUklOR19JTl9QQVRILAotICAgICAgICAgICAgICAgICJcdThERUZcdTVGODRcdTU0OENcdTY3RTVcdThCRTJcdTVCNTdcdTdCMjZcdTRFMzJcdTRFMkRcdTRFMERcdTgwRkRcdTYzMDdcdTVCOUFcdTY3RTVcdThCRTJcdTVCNTdcdTdCMjZcdTRFMzIiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfTk9fUE9SVF9JRl9OT19IT1NULAotICAgICAgICAgICAgICAgICJcdTU5ODJcdTY3OUNcdTZDQTFcdTY3MDlcdTYzMDdcdTVCOUFcdTRFM0JcdTY3M0EsIFx1NTIxOVx1NEUwRFx1NTNFRlx1NEVFNVx1NjMwN1x1NUI5QVx1N0FFRlx1NTNFMyIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9OT19VU0VSSU5GT19JRl9OT19IT1NULAotICAgICAgICAgICAgICAgICJcdTU5ODJcdTY3OUNcdTZDQTFcdTY3MDlcdTYzMDdcdTVCOUFcdTRFM0JcdTY3M0EsIFx1NTIxOVx1NEUwRFx1NTNFRlx1NEVFNVx1NjMwN1x1NUI5QSBVc2VyaW5mbyIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9YTUxfVkVSU0lPTl9OT1RfU1VQUE9SVEVELAotICAgICAgICAgICAgICAgICJcdThCNjZcdTU0NEE6IFx1OEY5M1x1NTFGQVx1NjU4N1x1Njg2M1x1NzY4NFx1NzI0OFx1NjcyQ1x1NUU5NFx1NEUzQSAnJ3swfScnXHUzMDAyXHU0RTBEXHU2NTJGXHU2MzAxXHU2QjY0XHU3MjQ4XHU2NzJDXHU3Njg0IFhNTFx1MzAwMlx1OEY5M1x1NTFGQVx1NjU4N1x1Njg2M1x1NzY4NFx1NzI0OFx1NjcyQ1x1NUMwNlx1NEUzQSAnJzEuMCcnXHUzMDAyIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX1NDSEVNRV9SRVFVSVJFRCwKLSAgICAgICAgICAgICAgICAiXHU2NUI5XHU2ODQ4XHU2NjJGXHU1RkM1XHU5NzAwXHU3Njg0ISIgfSwKLQotICAgICAgICAgICAgLyoKLSAgICAgICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgd29yZHMgJ1Byb3BlcnRpZXMnIGFuZAotICAgICAgICAgICAgICogJ1NlcmlhbGl6ZXJGYWN0b3J5JyBpbiB0aGlzIG1lc3NhZ2UgYXJlIEphdmEgY2xhc3MgbmFtZXMKLSAgICAgICAgICAgICAqIGFuZCBzaG91bGQgbm90IGJlIHRyYW5zbGF0ZWQuCi0gICAgICAgICAgICAgKi8KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfRkFDVE9SWV9QUk9QRVJUWV9NSVNTSU5HLAotICAgICAgICAgICAgICAgICJcdTRGMjBcdTkwMTJcdTUyMzAgU2VyaWFsaXplckZhY3RvcnkgXHU3Njg0IFByb3BlcnRpZXMgXHU1QkY5XHU4QzYxXHU2Q0ExXHU2NzA5ICcnezB9JycgXHU1QzVFXHU2MDI3XHUzMDAyIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0VOQ09ESU5HX05PVF9TVVBQT1JURUQsCi0gICAgICAgICAgICAgICAgIlx1OEI2Nlx1NTQ0QTogSmF2YSBcdThGRDBcdTg4NENcdTY1RjZcdTRFMERcdTY1MkZcdTYzMDFcdTdGMTZcdTc4MDEgJyd7MH0nJ1x1MzAwMiIgfSwKLQotCi0gICAgICAgIH07Ci0KLSAgICAgICAgcmV0dXJuIGNvbnRlbnRzOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvdXRpbHMvU2VyaWFsaXplck1lc3NhZ2VzX3poX1RXLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL3V0aWxzL1NlcmlhbGl6ZXJNZXNzYWdlc196aF9UVy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2YTU0MzIwLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvdXRpbHMvU2VyaWFsaXplck1lc3NhZ2VzX3poX1RXLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMDUgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyLnV0aWxzOwotCi1pbXBvcnQgamF2YS51dGlsLkxpc3RSZXNvdXJjZUJ1bmRsZTsKLWltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwotaW1wb3J0IGphdmEudXRpbC5NaXNzaW5nUmVzb3VyY2VFeGNlcHRpb247Ci1pbXBvcnQgamF2YS51dGlsLlJlc291cmNlQnVuZGxlOwotCi0vKioKLSAqIEFuIGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgaXMgYSBMaXN0UmVzb3VyY2VCdW5kbGUgdGhhdAotICogaGFzIHRoZSByZXF1aXJlZCBnZXRDb250ZW50cygpIG1ldGhvZCB0aGF0IHJldHVybnMKLSAqIGFuIGFycmF5IG9mIG1lc3NhZ2Uta2V5L21lc3NhZ2UgYXNzb2NpYXRpb25zLgotICogPHA+Ci0gKiBUaGUgbWVzc2FnZSBrZXlzIGFyZSBkZWZpbmVkIGluIHtAbGluayBNc2dLZXl9LiBUaGUKLSAqIG1lc3NhZ2VzIHRoYXQgdGhvc2Uga2V5cyBtYXAgdG8gYXJlIGRlZmluZWQgaGVyZS4KLSAqIDxwPgotICogVGhlIG1lc3NhZ2VzIGluIHRoZSBFbmdsaXNoIHZlcnNpb24gYXJlIGludGVuZGVkIHRvIGJlCi0gKiB0cmFuc2xhdGVkLgotICoKLSAqIFRoaXMgY2xhc3MgaXMgbm90IGEgcHVibGljIEFQSSwgaXQgaXMgb25seSBwdWJsaWMgYmVjYXVzZSBpdCBpcwotICogdXNlZCBpbiBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXIuCi0gKgotICogQHhzbC51c2FnZSBpbnRlcm5hbAotICovCi1wdWJsaWMgY2xhc3MgU2VyaWFsaXplck1lc3NhZ2VzX3poX1RXIGV4dGVuZHMgTGlzdFJlc291cmNlQnVuZGxlIHsKLQotICAgIC8qCi0gICAgICogVGhpcyBmaWxlIGNvbnRhaW5zIGVycm9yIGFuZCB3YXJuaW5nIG1lc3NhZ2VzIHJlbGF0ZWQgdG8KLSAgICAgKiBTZXJpYWxpemVyIEVycm9yIEhhbmRsaW5nLgotICAgICAqCi0gICAgICogIEdlbmVyYWwgbm90ZXMgdG8gdHJhbnNsYXRvcnM6Ci0KLSAgICAgKiAgMSkgQSBzdHlsZXNoZWV0IGlzIGEgZGVzY3JpcHRpb24gb2YgaG93IHRvIHRyYW5zZm9ybSBhbiBpbnB1dCBYTUwgZG9jdW1lbnQKLSAgICAgKiAgICAgaW50byBhIHJlc3VsdGFudCBYTUwgZG9jdW1lbnQgKG9yIEhUTUwgZG9jdW1lbnQgb3IgdGV4dCkuICBUaGUKLSAgICAgKiAgICAgc3R5bGVzaGVldCBpdHNlbGYgaXMgZGVzY3JpYmVkIGluIHRoZSBmb3JtIG9mIGFuIFhNTCBkb2N1bWVudC4KLQotICAgICAqCi0gICAgICogIDIpIEFuIGVsZW1lbnQgaXMgYSBtYXJrLXVwIHRhZyBpbiBhbiBYTUwgZG9jdW1lbnQ7IGFuIGF0dHJpYnV0ZSBpcyBhCi0gICAgICogICAgIG1vZGlmaWVyIG9uIHRoZSB0YWcuICBGb3IgZXhhbXBsZSwgaW4gPGVsZW0gYXR0cj0ndmFsJyBhdHRyMj0ndmFsMic+Ci0gICAgICogICAgICJlbGVtIiBpcyBhbiBlbGVtZW50IG5hbWUsICJhdHRyIiBhbmQgImF0dHIyIiBhcmUgYXR0cmlidXRlIG5hbWVzIHdpdGgKLSAgICAgKiAgICAgdGhlIHZhbHVlcyAidmFsIiBhbmQgInZhbDIiLCByZXNwZWN0aXZlbHkuCi0gICAgICoKLSAgICAgKiAgMykgQSBuYW1lc3BhY2UgZGVjbGFyYXRpb24gaXMgYSBzcGVjaWFsIGF0dHJpYnV0ZSB0aGF0IGlzIHVzZWQgdG8gYXNzb2NpYXRlCi0gICAgICogICAgIGEgcHJlZml4IHdpdGggYSBVUkkgKHRoZSBuYW1lc3BhY2UpLiAgVGhlIG1lYW5pbmdzIG9mIGVsZW1lbnQgbmFtZXMgYW5kCi0gICAgICogICAgIGF0dHJpYnV0ZSBuYW1lcyB0aGF0IHVzZSB0aGF0IHByZWZpeCBhcmUgZGVmaW5lZCB3aXRoIHJlc3BlY3QgdG8gdGhhdAotICAgICAqICAgICBuYW1lc3BhY2UuCi0gICAgICoKLSAgICAgKgotICAgICAqLwotCi0gICAgLyoqIFRoZSBsb29rdXAgdGFibGUgZm9yIGVycm9yIG1lc3NhZ2VzLiAgICovCi0gICAgcHVibGljIE9iamVjdFtdW10gZ2V0Q29udGVudHMoKSB7Ci0gICAgICAgIE9iamVjdFtdW10gY29udGVudHMgPSBuZXcgT2JqZWN0W11bXSB7Ci0gICAgICAgICAgICB7ICAgTXNnS2V5LkJBRF9NU0dLRVksCi0gICAgICAgICAgICAgICAgIlx1OEEwQVx1NjA2Rlx1N0QyMlx1NUYxNVx1OTM3NSAnJ3swfScnIFx1NzY4NFx1OEEwQVx1NjA2Rlx1OTg1RVx1NTIyNVx1NEUwRFx1NjYyRiAnJ3sxfScnIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkJBRF9NU0dGT1JNQVQsCi0gICAgICAgICAgICAgICAgIlx1OEEwQVx1NjA2Rlx1OTg1RVx1NTIyNSAnJ3sxfScnIFx1NEUyRFx1NzY4NFx1OEEwQVx1NjA2RiAnJ3swfScnIFx1NjgzQ1x1NUYwRlx1NEUwRFx1NkI2M1x1NzhCQVx1MzAwMiIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9TRVJJQUxJWkVSX05PVF9DT05URU5USEFORExFUiwKLSAgICAgICAgICAgICAgICAic2VyaWFsaXplciBcdTk4NUVcdTUyMjUgJyd7MH0nJyBcdTRFMERcdTVCRTZcdTg4NEMgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXJcdTMwMDIiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfUkVTT1VSQ0VfQ09VTERfTk9UX0ZJTkQsCi0gICAgICAgICAgICAgICAgICAgICJcdTYyN0VcdTRFMERcdTUyMzBcdThDQzdcdTZFOTAgWyB7MH0gXVx1MzAwMlxuezF9IiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX1JFU09VUkNFX0NPVUxEX05PVF9MT0FELAotICAgICAgICAgICAgICAgICAgICAiXHU3MTIxXHU2Q0Q1XHU4RjA5XHU1MTY1XHU4Q0M3XHU2RTkwIFsgezB9IF06IHsxfSBcbiB7Mn0gXHQgezN9IiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0JVRkZFUl9TSVpFX0xFU1NUSEFOX1pFUk8sCi0gICAgICAgICAgICAgICAgICAgICJcdTdERTlcdTg4NURcdTUzNDBcdTU5MjdcdTVDMEYgPD0wIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0lOVkFMSURfVVRGMTZfU1VSUk9HQVRFLAotICAgICAgICAgICAgICAgICAgICAiXHU1MDc1XHU2RTJDXHU1MjMwXHU3MTIxXHU2NTQ4XHU3Njg0IFVURi0xNiBcdTRFRTNcdTc0MDY6IHswfVx1RkYxRiIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9PSUVSUk9SLAotICAgICAgICAgICAgICAgICJJTyBcdTkzMkZcdThBQTQiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfSUxMRUdBTF9BVFRSSUJVVEVfUE9TSVRJT04sCi0gICAgICAgICAgICAgICAgIlx1NTcyOFx1NzUyMlx1NzUxRlx1NUI1MFx1OTgwNVx1N0JDMFx1OUVERVx1NEU0Qlx1NUY4Q1x1RkYwQ1x1NjIxNlx1NTcyOFx1NzUyMlx1NzUxRlx1NTE0M1x1N0QyMFx1NEU0Qlx1NTI0RFx1RkYwQ1x1NEUwRFx1NTNFRlx1NjVCMFx1NTg5RVx1NUM2Q1x1NjAyNyB7MH1cdTMwMDJcdTVDNkNcdTYwMjdcdTY3MDNcdTg4QUJcdTVGRkRcdTc1NjVcdTMwMDIiIH0sCi0KLSAgICAgICAgICAgIC8qCi0gICAgICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN0eWxlc2hlZXQgY29udGFpbmVkIGEgcmVmZXJlbmNlIHRvIGEKLSAgICAgICAgICAgICAqIG5hbWVzcGFjZSBwcmVmaXggdGhhdCB3YXMgdW5kZWZpbmVkLiAgVGhlIHZhbHVlIG9mIHRoZSBzdWJzdGl0dXRpb24KLSAgICAgICAgICAgICAqIHRleHQgaXMgdGhlIG5hbWUgb2YgdGhlIHByZWZpeC4KLSAgICAgICAgICAgICAqLwotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9OQU1FU1BBQ0VfUFJFRklYLAotICAgICAgICAgICAgICAgICJcdTVCNTdcdTk5OTYgJyd7MH0nJyBcdTc2ODRcdTU0N0RcdTU0MERcdTdBN0FcdTk1OTNcdTVDMUFcdTY3MkFcdTVCQTNcdTU0NEFcdTMwMDIiIH0sCi0KLSAgICAgICAgICAgIC8qCi0gICAgICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhpcyBtZXNzYWdlIGlzIHJlcG9ydGVkIGlmIHRoZSBzdHlsZXNoZWV0Ci0gICAgICAgICAgICAgKiBiZWluZyBwcm9jZXNzZWQgYXR0ZW1wdGVkIHRvIGNvbnN0cnVjdCBhbiBYTUwgZG9jdW1lbnQgd2l0aCBhbgotICAgICAgICAgICAgICogYXR0cmlidXRlIGluIGEgcGxhY2Ugb3RoZXIgdGhhbiBvbiBhbiBlbGVtZW50LiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0Ci0gICAgICAgICAgICAgKiBzcGVjaWZpZXMgdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgICAgICAgICAqLwotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9TVFJBWV9BVFRSSUJVVEUsCi0gICAgICAgICAgICAgICAgIlx1NUM2Q1x1NjAyNyAnJ3swfScnIFx1NTcyOFx1NTE0M1x1N0QyMFx1NEU0Qlx1NTkxNlx1MzAwMiIgfSwKLQotICAgICAgICAgICAgLyoKLSAgICAgICAgICAgICAqIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBcyB3aXRoIHRoZSBwcmVjZWRpbmcgbWVzc2FnZSwgYSBuYW1lc3BhY2UKLSAgICAgICAgICAgICAqIGRlY2xhcmF0aW9uIGhhcyB0aGUgZm9ybSBvZiBhbiBhdHRyaWJ1dGUgYW5kIGlzIG9ubHkgcGVybWl0dGVkIHRvCi0gICAgICAgICAgICAgKiBhcHBlYXIgb24gYW4gZWxlbWVudC4gIFRoZSBzdWJzdGl0dXRpb24gdGV4dCB7MH0gaXMgdGhlIG5hbWVzcGFjZQotICAgICAgICAgICAgICogcHJlZml4IGFuZCB7MX0gaXMgdGhlIFVSSSB0aGF0IHdhcyBiZWluZyB1c2VkIGluIHRoZSBlcnJvbmVvdXMKLSAgICAgICAgICAgICAqIG5hbWVzcGFjZSBkZWNsYXJhdGlvbi4KLSAgICAgICAgICAgICAqLwotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9TVFJBWV9OQU1FU1BBQ0UsCi0gICAgICAgICAgICAgICAgIlx1NTQ3RFx1NTQwRFx1N0E3QVx1OTU5M1x1NUJBM1x1NTQ0QSAnJ3swfScnPScnezF9JycgXHU4RDg1XHU1MUZBXHU1MTQzXHU3RDIwXHU1OTE2XHUzMDAyIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0NPVUxEX05PVF9MT0FEX1JFU09VUkNFLAotICAgICAgICAgICAgICAgICJcdTcxMjFcdTZDRDVcdThGMDlcdTUxNjUgJyd7MH0nJyAoXHU2QUEyXHU2N0U1IENMQVNTUEFUSClcdUZGMENcdTc2RUVcdTUyNERcdTUzRUFcdTRGN0ZcdTc1MjhcdTk4MTBcdThBMkRcdTUwM0MiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfSUxMRUdBTF9DSEFSQUNURVIsCi0gICAgICAgICAgICAgICAgIlx1NTYxN1x1OEE2Nlx1OEYzOFx1NTFGQVx1NjU3NFx1NjU3OFx1NTAzQyB7MH0gXHU3Njg0XHU1QjU3XHU1MTQzXHVGRjBDXHU0RjQ2XHU2NjJGXHU1QjgzXHU0RTBEXHU2NjJGXHU0RUU1XHU2MzA3XHU1QjlBXHU3Njg0IHsxfSBcdThGMzhcdTUxRkFcdTdERThcdTc4QkNcdTU0NDhcdTczRkVcdTMwMDIiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfQ09VTERfTk9UX0xPQURfTUVUSE9EX1BST1BFUlRZLAotICAgICAgICAgICAgICAgICJcdTcxMjFcdTZDRDVcdThGMDlcdTUxNjVcdThGMzhcdTUxRkFcdTY1QjlcdTZDRDUgJyd7MX0nJyBcdTc2ODRcdTVDNkNcdTYwMjdcdTZBOTQgJyd7MH0nJyAoXHU2QUEyXHU2N0U1IENMQVNTUEFUSCkiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfSU5WQUxJRF9QT1JULAotICAgICAgICAgICAgICAgICJcdTcxMjFcdTY1NDhcdTc2ODRcdTkwMjNcdTYzQTVcdTU3RTBcdTg2NUZcdTc4QkMiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfUE9SVF9XSEVOX0hPU1RfTlVMTCwKLSAgICAgICAgICAgICAgICAiXHU0RTNCXHU2QTVGXHU3MEJBXHU3QTdBXHU1MDNDXHU2NjQyXHVGRjBDXHU3MTIxXHU2Q0Q1XHU4QTJEXHU1QjlBXHU5MDIzXHU2M0E1XHU1N0UwIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0hPU1RfQUREUkVTU19OT1RfV0VMTEZPUk1FRCwKLSAgICAgICAgICAgICAgICAiXHU0RTNCXHU2QTVGXHU2QzkyXHU2NzA5XHU1QjhDXHU2NTc0XHU3Njg0XHU0RjREXHU1NzQwIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX1NDSEVNRV9OT1RfQ09ORk9STUFOVCwKLSAgICAgICAgICAgICAgICAiXHU5MTREXHU3RjZFXHU0RTBEXHU0RTAwXHU4MUY0XHUzMDAyIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX1NDSEVNRV9GUk9NX05VTExfU1RSSU5HLAotICAgICAgICAgICAgICAgICJcdTcxMjFcdTZDRDVcdTVGOUVcdTdBN0FcdTUwM0NcdTVCNTdcdTRFMzJcdThBMkRcdTVCOUFcdTkxNERcdTdGNkUiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfUEFUSF9DT05UQUlOU19JTlZBTElEX0VTQ0FQRV9TRVFVRU5DRSwKLSAgICAgICAgICAgICAgICAiXHU4REVGXHU1RjkxXHU1MzA1XHU1NDJCXHU3MTIxXHU2NTQ4XHU3Njg0XHU5MDQxXHU5NkUyXHU1RThGXHU1MjE3IiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX1BBVEhfSU5WQUxJRF9DSEFSLAotICAgICAgICAgICAgICAgICJcdThERUZcdTVGOTFcdTUzMDVcdTU0MkJcdTcxMjFcdTY1NDhcdTc2ODRcdTVCNTdcdTUxNDM6IHswfSIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9GUkFHX0lOVkFMSURfQ0hBUiwKLSAgICAgICAgICAgICAgICAiXHU3MjQ3XHU2QkI1XHU1MzA1XHU1NDJCXHU3MTIxXHU2NTQ4XHU3Njg0XHU1QjU3XHU1MTQzIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0ZSQUdfV0hFTl9QQVRIX05VTEwsCi0gICAgICAgICAgICAgICAgIlx1OERFRlx1NUY5MVx1NzBCQVx1N0E3QVx1NTAzQ1x1NjY0Mlx1RkYwQ1x1NzEyMVx1NkNENVx1OEEyRFx1NUI5QVx1NzI0N1x1NkJCNSIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9GUkFHX0ZPUl9HRU5FUklDX1VSSSwKLSAgICAgICAgICAgICAgICAiXHU1M0VBXHU4MEZEXHU1QzBEXHU0RTAwXHU4MjJDIFVSSSBcdThBMkRcdTVCOUFcdTcyNDdcdTZCQjUiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfTk9fU0NIRU1FX0lOX1VSSSwKLSAgICAgICAgICAgICAgICAiXHU1NzI4IFVSSSBcdTYyN0VcdTRFMERcdTUyMzBcdTkxNERcdTdGNkUiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfQ0FOTk9UX0lOSVRfVVJJX0VNUFRZX1BBUk1TLAotICAgICAgICAgICAgICAgICJcdTcxMjFcdTZDRDVcdTRFRTVcdTdBN0FcdTc2N0RcdTUzQzNcdTY1NzhcdThENzdcdTU5Q0JcdThBMkRcdTVCOUEgVVJJIiB9LAotCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX05PX0ZSQUdNRU5UX1NUUklOR19JTl9QQVRILAotICAgICAgICAgICAgICAgICJcdThERUZcdTVGOTFcdTU0OENcdTcyNDdcdTZCQjVcdTRFMERcdTgwRkRcdTU0MENcdTY2NDJcdTYzMDdcdTVCOUFcdTcyNDdcdTZCQjUiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfTk9fUVVFUllfU1RSSU5HX0lOX1BBVEgsCi0gICAgICAgICAgICAgICAgIlx1NTcyOFx1OERFRlx1NUY5MVx1NTNDQVx1NjdFNVx1OEE2Mlx1NUI1N1x1NEUzMlx1NEUyRFx1NEUwRFx1NTNFRlx1NjMwN1x1NUI5QVx1NjdFNVx1OEE2Mlx1NUI1N1x1NEUzMiIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9OT19QT1JUX0lGX05PX0hPU1QsCi0gICAgICAgICAgICAgICAgIlx1NTk4Mlx1Njc5Q1x1NkM5Mlx1NjcwOVx1NjMwN1x1NUI5QVx1NEUzQlx1NkE1Rlx1RkYwQ1x1NEUwRFx1NTNFRlx1NjMwN1x1NUI5QVx1OTAyM1x1NjNBNVx1NTdFMCIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9OT19VU0VSSU5GT19JRl9OT19IT1NULAotICAgICAgICAgICAgICAgICJcdTU5ODJcdTY3OUNcdTZDOTJcdTY3MDlcdTYzMDdcdTVCOUFcdTRFM0JcdTZBNUZcdUZGMENcdTRFMERcdTUzRUZcdTYzMDdcdTVCOUEgVXNlcmluZm8iIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfWE1MX1ZFUlNJT05fTk9UX1NVUFBPUlRFRCwKLSAgICAgICAgICAgICAgICAiXHU4QjY2XHU1NDRBOiAgXHU4OTgxXHU2QzQyXHU3Njg0XHU4RjM4XHU1MUZBXHU2NTg3XHU0RUY2XHU3MjQ4XHU2NzJDXHU3MEJBICcnezB9JydcdTMwMDJcdTRFMERcdTY1MkZcdTYzRjRcdTZCNjRcdTcyNDhcdTY3MkNcdTc2ODQgWE1MXHUzMDAyXHU4RjM4XHU1MUZBXHU2NTg3XHU0RUY2XHU3Njg0XHU3MjQ4XHU2NzJDXHU1QzA3XHU2NzAzXHU2NjJGICcnMS4wJydcdTMwMDIiIH0sCi0KLSAgICAgICAgICAgIHsgICBNc2dLZXkuRVJfU0NIRU1FX1JFUVVJUkVELAotICAgICAgICAgICAgICAgICJcdTVGQzVcdTk4MDhcdTY3MDlcdTkxNERcdTdGNkVcdUZGMDEiIH0sCi0KLSAgICAgICAgICAgIC8qCi0gICAgICAgICAgICAgKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHdvcmRzICdQcm9wZXJ0aWVzJyBhbmQKLSAgICAgICAgICAgICAqICdTZXJpYWxpemVyRmFjdG9yeScgaW4gdGhpcyBtZXNzYWdlIGFyZSBKYXZhIGNsYXNzIG5hbWVzCi0gICAgICAgICAgICAgKiBhbmQgc2hvdWxkIG5vdCBiZSB0cmFuc2xhdGVkLgotICAgICAgICAgICAgICovCi0gICAgICAgICAgICB7ICAgTXNnS2V5LkVSX0ZBQ1RPUllfUFJPUEVSVFlfTUlTU0lORywKLSAgICAgICAgICAgICAgICAiXHU1MEIzXHU5MDVFXHU3RDY2IFNlcmlhbGl6ZXJGYWN0b3J5IFx1NzY4NCBQcm9wZXJ0aWVzIFx1NzI2OVx1NEVGNlx1NkM5Mlx1NjcwOSAnJ3swfScnIFx1NUM2Q1x1NjAyN1x1MzAwMiIgfSwKLQotICAgICAgICAgICAgeyAgIE1zZ0tleS5FUl9FTkNPRElOR19OT1RfU1VQUE9SVEVELAotICAgICAgICAgICAgICAgICJcdThCNjZcdTU0NEE6ICBKYXZhIFJ1bnRpbWUgXHU0RTBEXHU2NTJGXHU2M0Y0XHU3REU4XHU3OEJDICcnezB9JydcdTMwMDIiIH0sCi0KLQotICAgICAgICB9OwotCi0gICAgICAgIHJldHVybiBjb250ZW50czsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL3V0aWxzL1N0cmluZ1RvSW50VGFibGUuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvdXRpbHMvU3RyaW5nVG9JbnRUYWJsZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwNDE0MGZmLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvdXRpbHMvU3RyaW5nVG9JbnRUYWJsZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjA1ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFN0cmluZ1RvSW50VGFibGUuamF2YSx2IDEuMS40LjEgMjAwNS8wOS8wOCAxMTowMzoxOSBzdXJlc2hfZW1haWxpZCBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplci51dGlsczsKLQotLyoqCi0gKiBBIHZlcnkgc2ltcGxlIGxvb2t1cCB0YWJsZSB0aGF0IHN0b3JlcyBhIGxpc3Qgb2Ygc3RyaW5ncywgdGhlIGV2ZW4KLSAqIG51bWJlciBzdHJpbmdzIGJlaW5nIGtleXMsIGFuZCB0aGUgb2RkIG51bWJlciBzdHJpbmdzIGJlaW5nIHZhbHVlcy4KLSAqCi0gKiBUaGlzIGNsYXNzIGlzIGEgY29weSBvZiB0aGUgb25lIGluIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuCi0gKiBJdCBleGlzdHMgdG8gY3V0IHRoZSBzZXJpYWxpemVycyBkZXBlbmRhbmN5IG9uIHRoYXQgcGFja2FnZS4KLSAqCi0gKiBUaGlzIGNsYXNzIGlzIG5vdCBhIHB1YmxpYyBBUEksIGl0IGlzIG9ubHkgcHVibGljIHNvIGl0IGNhbiBiZSB1c2VkCi0gKiBpbiBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXIuCi0gKgotICogQHhzbC51c2FnZSBpbnRlcm5hbAotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgU3RyaW5nVG9JbnRUYWJsZQotewotCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElOVkFMSURfS0VZID0gLTEwMDAwOwotCi0gIC8qKiBCbG9jayBzaXplIHRvIGFsbG9jYXRlICAgICAgICAgICovCi0gIHByaXZhdGUgaW50IG1fYmxvY2tzaXplOwotCi0gIC8qKiBBcnJheSBvZiBzdHJpbmdzIHRoaXMgdGFibGUgcG9pbnRzIHRvLiBBc3NvY2lhdGVkIHdpdGggaW50cwotICAgKiBpbiBtX3ZhbHVlcyAgICAgICAgICovCi0gIHByaXZhdGUgU3RyaW5nIG1fbWFwW107Ci0KLSAgLyoqIEFycmF5IG9mIGludHMgdGhpcyB0YWJsZSBwb2ludHMuIEFzc29jaWF0ZWQgd2l0aCBzdHJpbmdzIGZyb20KLSAgICogbV9tYXAuICAgICAgICAgKi8KLSAgcHJpdmF0ZSBpbnQgbV92YWx1ZXNbXTsKLQotICAvKiogTnVtYmVyIG9mIGludHMgaW4gdGhlIHRhYmxlICAgICAgICAgICovCi0gIHByaXZhdGUgaW50IG1fZmlyc3RGcmVlID0gMDsKLQotICAvKiogU2l6ZSBvZiB0aGlzIHRhYmxlICAgICAgICAgKi8KLSAgcHJpdmF0ZSBpbnQgbV9tYXBTaXplOwotCi0gIC8qKgotICAgKiBEZWZhdWx0IGNvbnN0cnVjdG9yLiAgTm90ZSB0aGF0IHRoZSBkZWZhdWx0Ci0gICAqIGJsb2NrIHNpemUgaXMgdmVyeSBzbWFsbCwgZm9yIHNtYWxsIGxpc3RzLgotICAgKi8KLSAgcHVibGljIFN0cmluZ1RvSW50VGFibGUoKQotICB7Ci0KLSAgICBtX2Jsb2Nrc2l6ZSA9IDg7Ci0gICAgbV9tYXBTaXplID0gbV9ibG9ja3NpemU7Ci0gICAgbV9tYXAgPSBuZXcgU3RyaW5nW21fYmxvY2tzaXplXTsKLSAgICBtX3ZhbHVlcyA9IG5ldyBpbnRbbV9ibG9ja3NpemVdOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhIFN0cmluZ1RvSW50VGFibGUsIHVzaW5nIHRoZSBnaXZlbiBibG9jayBzaXplLgotICAgKgotICAgKiBAcGFyYW0gYmxvY2tzaXplIFNpemUgb2YgYmxvY2sgdG8gYWxsb2NhdGUKLSAgICovCi0gIHB1YmxpYyBTdHJpbmdUb0ludFRhYmxlKGludCBibG9ja3NpemUpCi0gIHsKLQotICAgIG1fYmxvY2tzaXplID0gYmxvY2tzaXplOwotICAgIG1fbWFwU2l6ZSA9IGJsb2Nrc2l6ZTsKLSAgICBtX21hcCA9IG5ldyBTdHJpbmdbYmxvY2tzaXplXTsKLSAgICBtX3ZhbHVlcyA9IG5ldyBpbnRbbV9ibG9ja3NpemVdOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbGVuZ3RoIG9mIHRoZSBsaXN0LgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBsZW5ndGggb2YgdGhlIGxpc3QKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBpbnQgZ2V0TGVuZ3RoKCkKLSAgewotICAgIHJldHVybiBtX2ZpcnN0RnJlZTsKLSAgfQotCi0gIC8qKgotICAgKiBBcHBlbmQgYSBzdHJpbmcgb250byB0aGUgdmVjdG9yLgotICAgKgotICAgKiBAcGFyYW0ga2V5IFN0cmluZyB0byBhcHBlbmQKLSAgICogQHBhcmFtIHZhbHVlIFRoZSBpbnQgdmFsdWUgb2YgdGhlIHN0cmluZwotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgcHV0KFN0cmluZyBrZXksIGludCB2YWx1ZSkKLSAgewotCi0gICAgaWYgKChtX2ZpcnN0RnJlZSArIDEpID49IG1fbWFwU2l6ZSkKLSAgICB7Ci0gICAgICBtX21hcFNpemUgKz0gbV9ibG9ja3NpemU7Ci0KLSAgICAgIFN0cmluZyBuZXdNYXBbXSA9IG5ldyBTdHJpbmdbbV9tYXBTaXplXTsKLQotICAgICAgU3lzdGVtLmFycmF5Y29weShtX21hcCwgMCwgbmV3TWFwLCAwLCBtX2ZpcnN0RnJlZSArIDEpOwotCi0gICAgICBtX21hcCA9IG5ld01hcDsKLQotICAgICAgaW50IG5ld1ZhbHVlc1tdID0gbmV3IGludFttX21hcFNpemVdOwotCi0gICAgICBTeXN0ZW0uYXJyYXljb3B5KG1fdmFsdWVzLCAwLCBuZXdWYWx1ZXMsIDAsIG1fZmlyc3RGcmVlICsgMSk7Ci0KLSAgICAgIG1fdmFsdWVzID0gbmV3VmFsdWVzOwotICAgIH0KLQotICAgIG1fbWFwW21fZmlyc3RGcmVlXSA9IGtleTsKLSAgICBtX3ZhbHVlc1ttX2ZpcnN0RnJlZV0gPSB2YWx1ZTsKLQotICAgIG1fZmlyc3RGcmVlKys7Ci0gIH0KLQotICAvKioKLSAgICogVGVsbCBpZiB0aGUgdGFibGUgY29udGFpbnMgdGhlIGdpdmVuIHN0cmluZy4KLSAgICoKLSAgICogQHBhcmFtIGtleSBTdHJpbmcgdG8gbG9vayBmb3IKLSAgICoKLSAgICogQHJldHVybiBUaGUgU3RyaW5nJ3MgaW50IHZhbHVlCi0gICAqCi0gICAqLwotICBwdWJsaWMgZmluYWwgaW50IGdldChTdHJpbmcga2V5KQotICB7Ci0KLSAgICBmb3IgKGludCBpID0gMDsgaSA8IG1fZmlyc3RGcmVlOyBpKyspCi0gICAgewotICAgICAgaWYgKG1fbWFwW2ldLmVxdWFscyhrZXkpKQotICAgICAgICByZXR1cm4gbV92YWx1ZXNbaV07Ci0gICAgfQotCi0gICAgcmV0dXJuIElOVkFMSURfS0VZOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgdGhlIHRhYmxlIGNvbnRhaW5zIHRoZSBnaXZlbiBzdHJpbmcuIElnbm9yZSBjYXNlLgotICAgKgotICAgKiBAcGFyYW0ga2V5IFN0cmluZyB0byBsb29rIGZvcgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBzdHJpbmcncyBpbnQgdmFsdWUKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBpbnQgZ2V0SWdub3JlQ2FzZShTdHJpbmcga2V5KQotICB7Ci0KLSAgICBpZiAobnVsbCA9PSBrZXkpCi0gICAgICAgIHJldHVybiBJTlZBTElEX0tFWTsKLQotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbV9maXJzdEZyZWU7IGkrKykKLSAgICB7Ci0gICAgICBpZiAobV9tYXBbaV0uZXF1YWxzSWdub3JlQ2FzZShrZXkpKQotICAgICAgICByZXR1cm4gbV92YWx1ZXNbaV07Ci0gICAgfQotCi0gICAgcmV0dXJuIElOVkFMSURfS0VZOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgdGhlIHRhYmxlIGNvbnRhaW5zIHRoZSBnaXZlbiBzdHJpbmcuCi0gICAqCi0gICAqIEBwYXJhbSBrZXkgU3RyaW5nIHRvIGxvb2sgZm9yCi0gICAqCi0gICAqIEByZXR1cm4gVHJ1ZSBpZiB0aGUgc3RyaW5nIGlzIGluIHRoZSB0YWJsZQotICAgKi8KLSAgcHVibGljIGZpbmFsIGJvb2xlYW4gY29udGFpbnMoU3RyaW5nIGtleSkKLSAgewotCi0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtX2ZpcnN0RnJlZTsgaSsrKQotICAgIHsKLSAgICAgIGlmIChtX21hcFtpXS5lcXVhbHMoa2V5KSkKLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotCi0gICAgcmV0dXJuIGZhbHNlOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiBhcnJheSBvZiBrZXlzIGluIHRoZSB0YWJsZS4KLSAgICoKLSAgICogQHJldHVybiBBcnJheSBvZiBzdHJpbmdzCi0gICAqLwotICBwdWJsaWMgZmluYWwgU3RyaW5nW10ga2V5cygpCi0gIHsKLSAgICBTdHJpbmcgW10ga2V5c0FyciA9IG5ldyBTdHJpbmdbbV9maXJzdEZyZWVdOwotCi0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtX2ZpcnN0RnJlZTsgaSsrKQotICAgIHsKLSAgICAgIGtleXNBcnJbaV0gPSBtX21hcFtpXTsKLSAgICB9Ci0KLSAgICByZXR1cm4ga2V5c0FycjsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci91dGlscy9TeXN0ZW1JRFJlc29sdmVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL3V0aWxzL1N5c3RlbUlEUmVzb2x2ZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZTVjMzhlYi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL3V0aWxzL1N5c3RlbUlEUmVzb2x2ZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDMwNCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBTeXN0ZW1JRFJlc29sdmVyLmphdmEsdiAxLjEuNC4xIDIwMDUvMDkvMDggMTE6MDM6MjAgc3VyZXNoX2VtYWlsaWQgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXIudXRpbHM7Ci0KLWltcG9ydCBqYXZhLmlvLkZpbGU7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyLnV0aWxzLlVSSS5NYWxmb3JtZWRVUklFeGNlcHRpb247Ci0KLS8qKgotICogVGhpcyBjbGFzcyBpcyB1c2VkIHRvIHJlc29sdmUgcmVsYXRpdmUgVVJJcyBhbmQgU3lzdGVtSUQKLSAqIHN0cmluZ3MgaW50byBhYnNvbHV0ZSBVUklzLgotICoKLSAqIDxwPlRoaXMgaXMgYSBnZW5lcmljIHV0aWxpdHkgZm9yIHJlc29sdmluZyBVUklzLCBvdGhlciB0aGFuIHRoZQotICogZmFjdCB0aGF0IGl0J3MgZGVjbGFyZWQgdG8gdGhyb3cgVHJhbnNmb3JtZXJFeGNlcHRpb24uICBQbGVhc2UKLSAqIHNlZSBjb2RlIGNvbW1lbnRzIGZvciBkZXRhaWxzIG9uIGhvdyByZXNvbHV0aW9uIGlzIHBlcmZvcm1lZC48L3A+Ci0gKgotICogVGhpcyBjbGFzcyBpcyBhIGNvcHkgb2YgdGhlIG9uZSBpbiBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLgotICogSXQgZXhpc3RzIHRvIGN1dCB0aGUgc2VyaWFsaXplcnMgZGVwZW5kYW5jeSBvbiB0aGF0IHBhY2thZ2UuCi0gKgotICogVGhpcyBjbGFzcyBpcyBub3QgYSBwdWJsaWMgQVBJLCBpdCBpcyBvbmx5IHB1YmxpYyBiZWNhdXNlIGl0IGlzCi0gKiB1c2VkIGluIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplci4KLSAqCi0gKiBAeHNsLnVzYWdlIGludGVybmFsCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBTeXN0ZW1JRFJlc29sdmVyCi17Ci0KLSAgLyoqCi0gICAqIEdldCBhbiBhYnNvbHV0ZSBVUkkgZnJvbSBhIGdpdmVuIHJlbGF0aXZlIFVSSSAobG9jYWwgcGF0aCkuCi0gICAqCi0gICAqIDxwPlRoZSByZWxhdGl2ZSBVUkkgaXMgYSBsb2NhbCBmaWxlc3lzdGVtIHBhdGguIFRoZSBwYXRoIGNhbiBiZQotICAgKiBhYnNvbHV0ZSBvciByZWxhdGl2ZS4gSWYgaXQgaXMgYSByZWxhdGl2ZSBwYXRoLCBpdCBpcyByZXNvbHZlZCByZWxhdGl2ZQotICAgKiB0byB0aGUgc3lzdGVtIHByb3BlcnR5ICJ1c2VyLmRpciIgaWYgaXQgaXMgYXZhaWxhYmxlOyBpZiBub3QgKGkuZS4gaW4gYW4KLSAgICogQXBwbGV0IHBlcmhhcHMgd2hpY2ggdGhyb3dzIFNlY3VyaXR5RXhjZXB0aW9uKSB0aGVuIHdlIGp1c3QgcmV0dXJuIHRoZQotICAgKiByZWxhdGl2ZSBwYXRoLiBUaGUgc3BhY2UgYW5kIGJhY2tzbGFzaCBjaGFyYWN0ZXJzIGFyZSBhbHNvIHJlcGxhY2VkIHRvCi0gICAqIGdlbmVyYXRlIGEgZ29vZCBhYnNvbHV0ZSBVUkkuPC9wPgotICAgKgotICAgKiBAcGFyYW0gbG9jYWxQYXRoIFRoZSByZWxhdGl2ZSBVUkkgdG8gcmVzb2x2ZQotICAgKgotICAgKiBAcmV0dXJuIFJlc29sdmVkIGFic29sdXRlIFVSSQotICAgKi8KLSAgcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0QWJzb2x1dGVVUklGcm9tUmVsYXRpdmUoU3RyaW5nIGxvY2FsUGF0aCkKLSAgewotICAgIGlmIChsb2NhbFBhdGggPT0gbnVsbCB8fCBsb2NhbFBhdGgubGVuZ3RoKCkgPT0gMCkKLSAgICAgIHJldHVybiAiIjsKLQotICAgIC8vIElmIHRoZSBsb2NhbCBwYXRoIGlzIGEgcmVsYXRpdmUgcGF0aCwgdGhlbiBpdCBpcyByZXNvbHZlZCBhZ2FpbnN0Ci0gICAgLy8gdGhlICJ1c2VyLmRpciIgc3lzdGVtIHByb3BlcnR5LgotICAgIFN0cmluZyBhYnNvbHV0ZVBhdGggPSBsb2NhbFBhdGg7Ci0gICAgaWYgKCFpc0Fic29sdXRlUGF0aChsb2NhbFBhdGgpKQotICAgIHsKLSAgICAgIHRyeQotICAgICAgewotICAgICAgICBhYnNvbHV0ZVBhdGggPSBnZXRBYnNvbHV0ZVBhdGhGcm9tUmVsYXRpdmVQYXRoKGxvY2FsUGF0aCk7Ci0gICAgICB9Ci0gICAgICAvLyB1c2VyLmRpciBub3QgYWNjZXNzaWJsZSBmcm9tIGFwcGxldAotICAgICAgY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIHNlKQotICAgICAgewotICAgICAgICByZXR1cm4gImZpbGU6IiArIGxvY2FsUGF0aDsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICBTdHJpbmcgdXJsU3RyaW5nOwotICAgIGlmIChudWxsICE9IGFic29sdXRlUGF0aCkKLSAgICB7Ci0gICAgICBpZiAoYWJzb2x1dGVQYXRoLnN0YXJ0c1dpdGgoRmlsZS5zZXBhcmF0b3IpKQotICAgICAgICB1cmxTdHJpbmcgPSAiZmlsZTovLyIgKyBhYnNvbHV0ZVBhdGg7Ci0gICAgICBlbHNlCi0gICAgICAgIHVybFN0cmluZyA9ICJmaWxlOi8vLyIgKyBhYnNvbHV0ZVBhdGg7Ci0gICAgfQotICAgIGVsc2UKLSAgICAgIHVybFN0cmluZyA9ICJmaWxlOiIgKyBsb2NhbFBhdGg7Ci0KLSAgICByZXR1cm4gcmVwbGFjZUNoYXJzKHVybFN0cmluZyk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIGFuIGFic29sdXRlIHBhdGggZnJvbSBhIHJlbGF0aXZlIHBhdGguCi0gICAqCi0gICAqIEBwYXJhbSByZWxhdGl2ZVBhdGggQSByZWxhdGl2ZSBwYXRoCi0gICAqIEByZXR1cm4gVGhlIGFic29sdXRlIHBhdGgKLSAgICovCi0gIHByaXZhdGUgc3RhdGljIFN0cmluZyBnZXRBYnNvbHV0ZVBhdGhGcm9tUmVsYXRpdmVQYXRoKFN0cmluZyByZWxhdGl2ZVBhdGgpCi0gIHsKLSAgICByZXR1cm4gbmV3IEZpbGUocmVsYXRpdmVQYXRoKS5nZXRBYnNvbHV0ZVBhdGgoKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdHJ1ZSBpZiB0aGUgc3lzdGVtSWQgZGVub3RlcyBhbiBhYnNvbHV0ZSBVUkkgLgotICAgKgotICAgKiBAcGFyYW0gc3lzdGVtSWQgVGhlIHN5c3RlbUlkIHN0cmluZwotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHN5c3RlbUlkIGlzIGFuIGFuIGFic29sdXRlIFVSSQotICAgKi8KLSAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzQWJzb2x1dGVVUkkoU3RyaW5nIHN5c3RlbUlkKQotICB7Ci0gICAgIC8qKiBodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyMzk2LnR4dAotICAgICAgKiAgIEF1dGhvcnMgc2hvdWxkIGJlIGF3YXJlIHRoYXQgYSBwYXRoIHNlZ21lbnQgd2hpY2ggY29udGFpbnMgYSBjb2xvbgotICAgICAgKiBjaGFyYWN0ZXIgY2Fubm90IGJlIHVzZWQgYXMgdGhlIGZpcnN0IHNlZ21lbnQgb2YgYSByZWxhdGl2ZSBVUkkgcGF0aAotICAgICAgKiAoZS5nLiwgInRoaXM6dGhhdCIpLCBiZWNhdXNlIGl0IHdvdWxkIGJlIG1pc3Rha2VuIGZvciBhIHNjaGVtZSBuYW1lLgotICAgICAqKi8KLSAgICAgLyoqCi0gICAgICAqICVSRVZJRVclIENhbiB3ZSBhc3N1bWUgaGVyZSB0aGF0IHN5c3RlbUlkIGlzIGEgdmFsaWQgVVJJPwotICAgICAgKiBJdCBsb29rcyBsaWtlIHdlIGNhbm5vdCAoIFNlZSBkaXNjdXNzaW9uIG9mIHRoaXMgY29tbW9uIHByb2JsZW0gaW4KLSAgICAgICogQnVnemlsbGEgQnVnIDIyNzc3ICkuCi0gICAgICoqLwotICAgICAvLyJmaXgiIGZvciBCdWd6aWxsYSBCdWcgMjI3NzcKLSAgICBpZihpc1dpbmRvd3NBYnNvbHV0ZVBhdGgoc3lzdGVtSWQpKXsKLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICB9Ci0KLSAgICBmaW5hbCBpbnQgZnJhZ21lbnRJbmRleCA9IHN5c3RlbUlkLmluZGV4T2YoJyMnKTsKLSAgICBmaW5hbCBpbnQgcXVlcnlJbmRleCA9IHN5c3RlbUlkLmluZGV4T2YoJz8nKTsKLSAgICBmaW5hbCBpbnQgc2xhc2hJbmRleCA9IHN5c3RlbUlkLmluZGV4T2YoJy8nKTsKLSAgICBmaW5hbCBpbnQgY29sb25JbmRleCA9IHN5c3RlbUlkLmluZGV4T2YoJzonKTsKLQotICAgIC8vZmluZGluZyBzdWJzdHJpbmcgIGJlZm9yZSAnIycsICc/JywgYW5kICcvJwotICAgIGludCBpbmRleCA9IHN5c3RlbUlkLmxlbmd0aCgpIC0xOwotICAgIGlmKGZyYWdtZW50SW5kZXggPiAwKQotICAgICAgICBpbmRleCA9IGZyYWdtZW50SW5kZXg7Ci0gICAgaWYoKHF1ZXJ5SW5kZXggPiAwKSAmJiAocXVlcnlJbmRleCA8aW5kZXgpKQotICAgICAgICBpbmRleCA9IHF1ZXJ5SW5kZXg7Ci0gICAgaWYoKHNsYXNoSW5kZXggPiAwKSAmJiAoc2xhc2hJbmRleCA8aW5kZXgpKQotICAgICAgICBpbmRleCA9IHNsYXNoSW5kZXg7Ci0gICAgLy8gcmV0dXJuIHRydWUgaWYgdGhlcmUgaXMgJzonIGJlZm9yZSAnIycsICc/JywgYW5kICcvJwotICAgIHJldHVybiAoKGNvbG9uSW5kZXggPjApICYmIChjb2xvbkluZGV4PGluZGV4KSk7Ci0KLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdHJ1ZSBpZiB0aGUgbG9jYWwgcGF0aCBpcyBhbiBhYnNvbHV0ZSBwYXRoLgotICAgKgotICAgKiBAcGFyYW0gc3lzdGVtSWQgVGhlIHBhdGggc3RyaW5nCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgcGF0aCBpcyBhYnNvbHV0ZQotICAgKi8KLSAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzQWJzb2x1dGVQYXRoKFN0cmluZyBzeXN0ZW1JZCkKLSAgewotICAgIGlmKHN5c3RlbUlkID09IG51bGwpCi0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICBmaW5hbCBGaWxlIGZpbGUgPSBuZXcgRmlsZShzeXN0ZW1JZCk7Ci0gICAgcmV0dXJuIGZpbGUuaXNBYnNvbHV0ZSgpOwotCi0gIH0KLQotICAgLyoqCi0gICAqIFJldHVybiB0cnVlIGlmIHRoZSBsb2NhbCBwYXRoIGlzIGEgV2luZG93cyBhYnNvbHV0ZSBwYXRoLgotICAgKgotICAgKiBAcGFyYW0gc3lzdGVtSWQgVGhlIHBhdGggc3RyaW5nCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgcGF0aCBpcyBhIFdpbmRvd3MgYWJzb2x1dGUgcGF0aAotICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGlzV2luZG93c0Fic29sdXRlUGF0aChTdHJpbmcgc3lzdGVtSWQpCi0gIHsKLSAgICBpZighaXNBYnNvbHV0ZVBhdGgoc3lzdGVtSWQpKQotICAgICAgcmV0dXJuIGZhbHNlOwotICAgIC8vIE9uIFdpbmRvd3MsIGFuIGFic29sdXRlIHBhdGggc3RhcnRzIHdpdGggIltkcml2ZV9sZXR0ZXJdOlwiLgotICAgIGlmIChzeXN0ZW1JZC5sZW5ndGgoKSA+IDIKLSAgICAgICAgJiYgc3lzdGVtSWQuY2hhckF0KDEpID09ICc6JwotICAgICAgICAmJiBDaGFyYWN0ZXIuaXNMZXR0ZXIoc3lzdGVtSWQuY2hhckF0KDApKQotICAgICAgICAmJiAoc3lzdGVtSWQuY2hhckF0KDIpID09ICdcXCcgfHwgc3lzdGVtSWQuY2hhckF0KDIpID09ICcvJykpCi0gICAgICByZXR1cm4gdHJ1ZTsKLSAgICBlbHNlCi0gICAgICByZXR1cm4gZmFsc2U7Ci0gIH0KLQotICAvKioKLSAgICogUmVwbGFjZSBzcGFjZXMgd2l0aCAiJTIwIiBhbmQgYmFja3NsYXNoZXMgd2l0aCBmb3J3YXJkIHNsYXNoZXMgaW4KLSAgICogdGhlIGlucHV0IHN0cmluZyB0byBnZW5lcmF0ZSBhIHdlbGwtZm9ybWVkIFVSSSBzdHJpbmcuCi0gICAqCi0gICAqIEBwYXJhbSBzdHIgVGhlIGlucHV0IHN0cmluZwotICAgKiBAcmV0dXJuIFRoZSBzdHJpbmcgYWZ0ZXIgY29udmVyc2lvbgotICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIHJlcGxhY2VDaGFycyhTdHJpbmcgc3RyKQotICB7Ci0gICAgU3RyaW5nQnVmZmVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWZmZXIoc3RyKTsKLSAgICBpbnQgbGVuZ3RoID0gYnVmLmxlbmd0aCgpOwotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspCi0gICAgewotICAgICAgY2hhciBjdXJyZW50Q2hhciA9IGJ1Zi5jaGFyQXQoaSk7Ci0gICAgICAvLyBSZXBsYWNlIHNwYWNlIHdpdGggIiUyMCIKLSAgICAgIGlmIChjdXJyZW50Q2hhciA9PSAnICcpCi0gICAgICB7Ci0gICAgICAgIGJ1Zi5zZXRDaGFyQXQoaSwgJyUnKTsKLSAgICAgICAgYnVmLmluc2VydChpKzEsICIyMCIpOwotICAgICAgICBsZW5ndGggPSBsZW5ndGggKyAyOwotICAgICAgICBpID0gaSArIDI7Ci0gICAgICB9Ci0gICAgICAvLyBSZXBsYWNlIGJhY2tzbGFzaCB3aXRoIGZvcndhcmQgc2xhc2gKLSAgICAgIGVsc2UgaWYgKGN1cnJlbnRDaGFyID09ICdcXCcpCi0gICAgICB7Ci0gICAgICAgIGJ1Zi5zZXRDaGFyQXQoaSwgJy8nKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gYnVmLnRvU3RyaW5nKCk7Ci0gIH0KLQotICAvKioKLSAgICogVGFrZSBhIFN5c3RlbUlEIHN0cmluZyBhbmQgdHJ5IHRvIHR1cm4gaXQgaW50byBhIGdvb2QgYWJzb2x1dGUgVVJJLgotICAgKgotICAgKiBAcGFyYW0gc3lzdGVtSWQgQSBVUkkgc3RyaW5nLCB3aGljaCBtYXkgYmUgYWJzb2x1dGUgb3IgcmVsYXRpdmUuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHJlc29sdmVkIGFic29sdXRlIFVSSQotICAgKi8KLSAgcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0QWJzb2x1dGVVUkkoU3RyaW5nIHN5c3RlbUlkKQotICB7Ci0gICAgU3RyaW5nIGFic29sdXRlVVJJID0gc3lzdGVtSWQ7Ci0gICAgaWYgKGlzQWJzb2x1dGVVUkkoc3lzdGVtSWQpKQotICAgIHsKLSAgICAgIC8vIE9ubHkgcHJvY2VzcyB0aGUgc3lzdGVtSWQgaWYgaXQgc3RhcnRzIHdpdGggImZpbGU6Ii4KLSAgICAgIGlmIChzeXN0ZW1JZC5zdGFydHNXaXRoKCJmaWxlOiIpKQotICAgICAgewotICAgICAgICBTdHJpbmcgc3RyID0gc3lzdGVtSWQuc3Vic3RyaW5nKDUpOwotCi0gICAgICAgIC8vIFJlc29sdmUgdGhlIGFic29sdXRlIHBhdGggaWYgdGhlIHN5c3RlbUlkIHN0YXJ0cyB3aXRoICJmaWxlOi8vLyIKLSAgICAgICAgLy8gb3IgImZpbGU6LyIuIERvbid0IGRvIGFueXRoaW5nIGlmIGl0IG9ubHkgc3RhcnRzIHdpdGggImZpbGU6Ly8iLgotICAgICAgICBpZiAoc3RyICE9IG51bGwgJiYgc3RyLnN0YXJ0c1dpdGgoIi8iKSkKLSAgICAgICAgewotICAgICAgICAgIGlmIChzdHIuc3RhcnRzV2l0aCgiLy8vIikgfHwgIXN0ci5zdGFydHNXaXRoKCIvLyIpKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIC8vIEEgV2luZG93cyBwYXRoIGNvbnRhaW5pbmcgYSBkcml2ZSBsZXR0ZXIgY2FuIGJlIHJlbGF0aXZlLgotICAgICAgICAgICAgLy8gQSBVbml4IHBhdGggc3RhcnRpbmcgd2l0aCAiZmlsZTovIiBpcyBhbHdheXMgYWJzb2x1dGUuCi0gICAgICAgICAgICBpbnQgc2Vjb25kQ29sb25JbmRleCA9IHN5c3RlbUlkLmluZGV4T2YoJzonLCA1KTsKLSAgICAgICAgICAgIGlmIChzZWNvbmRDb2xvbkluZGV4ID4gMCkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgU3RyaW5nIGxvY2FsUGF0aCA9IHN5c3RlbUlkLnN1YnN0cmluZyhzZWNvbmRDb2xvbkluZGV4LTEpOwotICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIGlmICghaXNBYnNvbHV0ZVBhdGgobG9jYWxQYXRoKSkKLSAgICAgICAgICAgICAgICAgIGFic29sdXRlVVJJID0gc3lzdGVtSWQuc3Vic3RyaW5nKDAsIHNlY29uZENvbG9uSW5kZXgtMSkgKwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRBYnNvbHV0ZVBhdGhGcm9tUmVsYXRpdmVQYXRoKGxvY2FsUGF0aCk7Ci0gICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIHNlKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHN5c3RlbUlkOwotICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotICAgICAgICAgIHJldHVybiBnZXRBYnNvbHV0ZVVSSUZyb21SZWxhdGl2ZShzeXN0ZW1JZC5zdWJzdHJpbmcoNSkpOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIHJlcGxhY2VDaGFycyhhYnNvbHV0ZVVSSSk7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICAgIHJldHVybiBzeXN0ZW1JZDsKLSAgICB9Ci0gICAgZWxzZQotICAgICAgcmV0dXJuIGdldEFic29sdXRlVVJJRnJvbVJlbGF0aXZlKHN5c3RlbUlkKTsKLQotICB9Ci0KLQotICAvKioKLSAgICogVGFrZSBhIFN5c3RlbUlEIHN0cmluZyBhbmQgdHJ5IHRvIHR1cm4gaXQgaW50byBhIGdvb2QgYWJzb2x1dGUgVVJJLgotICAgKgotICAgKiBAcGFyYW0gdXJsU3RyaW5nIFN5c3RlbUlEIHN0cmluZwotICAgKiBAcGFyYW0gYmFzZSBUaGUgVVJJIHN0cmluZyB1c2VkIGFzIHRoZSBiYXNlIGZvciByZXNvbHZpbmcgdGhlIHN5c3RlbUlECi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHJlc29sdmVkIGFic29sdXRlIFVSSQotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uIHRocm93biBpZiB0aGUgc3RyaW5nIGNhbid0IGJlIHR1cm5lZCBpbnRvIGEgVVJJLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0QWJzb2x1dGVVUkkoU3RyaW5nIHVybFN0cmluZywgU3RyaW5nIGJhc2UpCi0gICAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICBpZiAoYmFzZSA9PSBudWxsKQotICAgICAgcmV0dXJuIGdldEFic29sdXRlVVJJKHVybFN0cmluZyk7Ci0KLSAgICBTdHJpbmcgYWJzb2x1dGVCYXNlID0gZ2V0QWJzb2x1dGVVUkkoYmFzZSk7Ci0gICAgVVJJIHVyaSA9IG51bGw7Ci0gICAgdHJ5Ci0gICAgewotICAgICAgVVJJIGJhc2VVUkkgPSBuZXcgVVJJKGFic29sdXRlQmFzZSk7Ci0gICAgICB1cmkgPSBuZXcgVVJJKGJhc2VVUkksIHVybFN0cmluZyk7Ci0gICAgfQotICAgIGNhdGNoIChNYWxmb3JtZWRVUklFeGNlcHRpb24gbXVlKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihtdWUpOwotICAgIH0KLQotICAgIHJldHVybiByZXBsYWNlQ2hhcnModXJpLnRvU3RyaW5nKCkpOwotICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvdXRpbHMvVVJJLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL3V0aWxzL1VSSS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0ZDUzNzVhLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvdXRpbHMvVVJJLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNjcxICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFVSSS5qYXZhLHYgMS4xLjQuMSAyMDA1LzA5LzA4IDExOjAzOjIwIHN1cmVzaF9lbWFpbGlkIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyLnV0aWxzOwotCi1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuT2JqZWN0czsKLQotCi0vKioKLSAqIEEgY2xhc3MgdG8gcmVwcmVzZW50IGEgVW5pZm9ybSBSZXNvdXJjZSBJZGVudGlmaWVyIChVUkkpLiBUaGlzIGNsYXNzCi0gKiBpcyBkZXNpZ25lZCB0byBoYW5kbGUgdGhlIHBhcnNpbmcgb2YgVVJJcyBhbmQgcHJvdmlkZSBhY2Nlc3MgdG8KLSAqIHRoZSB2YXJpb3VzIGNvbXBvbmVudHMgKHNjaGVtZSwgaG9zdCwgcG9ydCwgdXNlcmluZm8sIHBhdGgsIHF1ZXJ5Ci0gKiBzdHJpbmcgYW5kIGZyYWdtZW50KSB0aGF0IG1heSBjb25zdGl0dXRlIGEgVVJJLgotICogPHA+Ci0gKiBQYXJzaW5nIG9mIGEgVVJJIHNwZWNpZmljYXRpb24gaXMgZG9uZSBhY2NvcmRpbmcgdG8gdGhlIFVSSQotICogc3ludGF4IGRlc2NyaWJlZCBpbiBSRkMgMjM5NgotICogPGh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzIzOTYudHh0P251bWJlcj0yMzk2Pi4gRXZlcnkgVVJJIGNvbnNpc3RzCi0gKiBvZiBhIHNjaGVtZSwgZm9sbG93ZWQgYnkgYSBjb2xvbiAoJzonKSwgZm9sbG93ZWQgYnkgYSBzY2hlbWUtc3BlY2lmaWMKLSAqIHBhcnQuIEZvciBVUklzIHRoYXQgZm9sbG93IHRoZSAiZ2VuZXJpYyBVUkkiIHN5bnRheCwgdGhlIHNjaGVtZS0KLSAqIHNwZWNpZmljIHBhcnQgYmVnaW5zIHdpdGggdHdvIHNsYXNoZXMgKCIvLyIpIGFuZCBtYXkgYmUgZm9sbG93ZWQKLSAqIGJ5IGFuIGF1dGhvcml0eSBzZWdtZW50IChjb21wcmlzZWQgb2YgdXNlciBpbmZvcm1hdGlvbiwgaG9zdCwgYW5kCi0gKiBwb3J0KSwgcGF0aCBzZWdtZW50LCBxdWVyeSBzZWdtZW50IGFuZCBmcmFnbWVudC4gTm90ZSB0aGF0IFJGQyAyMzk2Ci0gKiBubyBsb25nZXIgc3BlY2lmaWVzIHRoZSB1c2Ugb2YgdGhlIHBhcmFtZXRlcnMgc2VnbWVudCBhbmQgZXhjbHVkZXMKLSAqIHRoZSAidXNlcjpwYXNzd29yZCIgc3ludGF4IGFzIHBhcnQgb2YgdGhlIGF1dGhvcml0eSBzZWdtZW50LiBJZgotICogInVzZXI6cGFzc3dvcmQiIGFwcGVhcnMgaW4gYSBVUkksIHRoZSBlbnRpcmUgdXNlci9wYXNzd29yZCBzdHJpbmcKLSAqIGlzIHN0b3JlZCBhcyB1c2VyaW5mby4KLSAqIDxwPgotICogRm9yIFVSSXMgdGhhdCBkbyBub3QgZm9sbG93IHRoZSAiZ2VuZXJpYyBVUkkiIHN5bnRheCAoZS5nLiBtYWlsdG8pLAotICogdGhlIGVudGlyZSBzY2hlbWUtc3BlY2lmaWMgcGFydCBpcyB0cmVhdGVkIGFzIHRoZSAicGF0aCIgcG9ydGlvbgotICogb2YgdGhlIFVSSS4KLSAqIDxwPgotICogTm90ZSB0aGF0LCB1bmxpa2UgdGhlIGphdmEubmV0LlVSTCBjbGFzcywgdGhpcyBjbGFzcyBkb2VzIG5vdCBwcm92aWRlCi0gKiBhbnkgYnVpbHQtaW4gbmV0d29yayBhY2Nlc3MgZnVuY3Rpb25hbGl0eSBub3IgZG9lcyBpdCBwcm92aWRlIGFueQotICogc2NoZW1lLXNwZWNpZmljIGZ1bmN0aW9uYWxpdHkgKGZvciBleGFtcGxlLCBpdCBkb2VzIG5vdCBrbm93IGEKLSAqIGRlZmF1bHQgcG9ydCBmb3IgYSBzcGVjaWZpYyBzY2hlbWUpLiBSYXRoZXIsIGl0IG9ubHkga25vd3MgdGhlCi0gKiBncmFtbWFyIGFuZCBiYXNpYyBzZXQgb2Ygb3BlcmF0aW9ucyB0aGF0IGNhbiBiZSBhcHBsaWVkIHRvIGEgVVJJLgotICoKLSAqIFRoaXMgY2xhc3MgaXMgYSBjb3B5IG9mIHRoZSBvbmUgaW4gY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy4KLSAqIEl0IGV4aXN0cyB0byBjdXQgdGhlIHNlcmlhbGl6ZXJzIGRlcGVuZGFuY3kgb24gdGhhdCBwYWNrYWdlLgotICoKLSAqIEEgbWlub3IgY2hhbmdlIGZyb20gdGhlIG9yaWdpbmFsIGlzIHRoYXQgdGhpcyBjbGFzcyBubyBsb25nZXIgaW1wbGVtZW50cwotICogU2VyaWFsaXphYmxlLCBhbmQgdGhlIHNlcmlhbFZlcnNpb25VSUQgbWFnaWMgZmllbGQgaXMgZHJvcHBlZCwgYW5kCi0gKiB0aGUgY2xhc3MgaXMgbm8gbG9uZ2VyICJwdWJsaWMiLgotICoKLSAqIEB4c2wudXNhZ2UgaW50ZXJuYWwKLSAqLwotZmluYWwgY2xhc3MgVVJJCi17Ci0gIC8qKgotICAgKiBNYWxmb3JtZWRVUklFeGNlcHRpb25zIGFyZSB0aHJvd24gaW4gdGhlIHByb2Nlc3Mgb2YgYnVpbGRpbmcgYSBVUkkKLSAgICogb3Igc2V0dGluZyBmaWVsZHMgb24gYSBVUkkgd2hlbiBhbiBvcGVyYXRpb24gd291bGQgcmVzdWx0IGluIGFuCi0gICAqIGludmFsaWQgVVJJIHNwZWNpZmljYXRpb24uCi0gICAqCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGNsYXNzIE1hbGZvcm1lZFVSSUV4Y2VwdGlvbiBleHRlbmRzIElPRXhjZXB0aW9uCi0gIHsKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHMgYSA8Y29kZT5NYWxmb3JtZWRVUklFeGNlcHRpb248L2NvZGU+IHdpdGggbm8gc3BlY2lmaWVkCi0gICAgICogZGV0YWlsIG1lc3NhZ2UuCi0gICAgICovCi0gICAgcHVibGljIE1hbGZvcm1lZFVSSUV4Y2VwdGlvbigpCi0gICAgewotICAgICAgc3VwZXIoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RzIGEgPGNvZGU+TWFsZm9ybWVkVVJJRXhjZXB0aW9uPC9jb2RlPiB3aXRoIHRoZQotICAgICAqIHNwZWNpZmllZCBkZXRhaWwgbWVzc2FnZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBwX21zZyB0aGUgZGV0YWlsIG1lc3NhZ2UuCi0gICAgICovCi0gICAgcHVibGljIE1hbGZvcm1lZFVSSUV4Y2VwdGlvbihTdHJpbmcgcF9tc2cpCi0gICAgewotICAgICAgc3VwZXIocF9tc2cpOwotICAgIH0KLSAgfQotCi0gIC8qKiByZXNlcnZlZCBjaGFyYWN0ZXJzICovCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBSRVNFUlZFRF9DSEFSQUNURVJTID0gIjsvPzpAJj0rJCwiOwotCi0gIC8qKgotICAgKiBVUkkgcHVuY3R1YXRpb24gbWFyayBjaGFyYWN0ZXJzIC0gdGhlc2UsIGNvbWJpbmVkIHdpdGgKLSAgICogICBhbHBoYW51bWVyaWNzLCBjb25zdGl0dXRlIHRoZSAidW5yZXNlcnZlZCIgY2hhcmFjdGVycwotICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIE1BUktfQ0hBUkFDVEVSUyA9ICItXy4hfionKCkgIjsKLQotICAvKiogc2NoZW1lIGNhbiBiZSBjb21wb3NlZCBvZiBhbHBoYW51bWVyaWNzIGFuZCB0aGVzZSBjaGFyYWN0ZXJzICovCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBTQ0hFTUVfQ0hBUkFDVEVSUyA9ICIrLS4iOwotCi0gIC8qKgotICAgKiB1c2VyaW5mbyBjYW4gYmUgY29tcG9zZWQgb2YgdW5yZXNlcnZlZCwgZXNjYXBlZCBhbmQgdGhlc2UKLSAgICogICBjaGFyYWN0ZXJzCi0gICAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgVVNFUklORk9fQ0hBUkFDVEVSUyA9ICI7OiY9KyQsIjsKLQotICAvKiogU3RvcmVzIHRoZSBzY2hlbWUgKHVzdWFsbHkgdGhlIHByb3RvY29sKSBmb3IgdGhpcyBVUkkuCi0gICAqICBAc2VyaWFsICovCi0gIHByaXZhdGUgU3RyaW5nIG1fc2NoZW1lID0gbnVsbDsKLQotICAvKiogSWYgc3BlY2lmaWVkLCBzdG9yZXMgdGhlIHVzZXJpbmZvIGZvciB0aGlzIFVSSTsgb3RoZXJ3aXNlIG51bGwuCi0gICAqICBAc2VyaWFsICovCi0gIHByaXZhdGUgU3RyaW5nIG1fdXNlcmluZm8gPSBudWxsOwotCi0gIC8qKiBJZiBzcGVjaWZpZWQsIHN0b3JlcyB0aGUgaG9zdCBmb3IgdGhpcyBVUkk7IG90aGVyd2lzZSBudWxsLgotICAgKiAgQHNlcmlhbCAqLwotICBwcml2YXRlIFN0cmluZyBtX2hvc3QgPSBudWxsOwotCi0gIC8qKiBJZiBzcGVjaWZpZWQsIHN0b3JlcyB0aGUgcG9ydCBmb3IgdGhpcyBVUkk7IG90aGVyd2lzZSAtMS4KLSAgICogIEBzZXJpYWwgKi8KLSAgcHJpdmF0ZSBpbnQgbV9wb3J0ID0gLTE7Ci0KLSAgLyoqIElmIHNwZWNpZmllZCwgc3RvcmVzIHRoZSBwYXRoIGZvciB0aGlzIFVSSTsgb3RoZXJ3aXNlIG51bGwuCi0gICAqICBAc2VyaWFsICovCi0gIHByaXZhdGUgU3RyaW5nIG1fcGF0aCA9IG51bGw7Ci0KLSAgLyoqCi0gICAqIElmIHNwZWNpZmllZCwgc3RvcmVzIHRoZSBxdWVyeSBzdHJpbmcgZm9yIHRoaXMgVVJJOyBvdGhlcndpc2UKLSAgICogICBudWxsLgotICAgKiBAc2VyaWFsCi0gICAqLwotICBwcml2YXRlIFN0cmluZyBtX3F1ZXJ5U3RyaW5nID0gbnVsbDsKLQotICAvKiogSWYgc3BlY2lmaWVkLCBzdG9yZXMgdGhlIGZyYWdtZW50IGZvciB0aGlzIFVSSTsgb3RoZXJ3aXNlIG51bGwuCi0gICAqICBAc2VyaWFsICovCi0gIHByaXZhdGUgU3RyaW5nIG1fZnJhZ21lbnQgPSBudWxsOwotCi0gIC8qKiBJbmRpY2F0ZSB3aGV0aGVyIGluIERFQlVHIG1vZGUgICAgICAgICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBERUJVRyA9IGZhbHNlOwotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBuZXcgYW5kIHVuaW5pdGlhbGl6ZWQgVVJJLgotICAgKi8KLSAgcHVibGljIFVSSSgpe30KLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgbmV3IFVSSSBmcm9tIGFub3RoZXIgVVJJLiBBbGwgZmllbGRzIGZvciB0aGlzIFVSSSBhcmUKLSAgICogc2V0IGVxdWFsIHRvIHRoZSBmaWVsZHMgb2YgdGhlIFVSSSBwYXNzZWQgaW4uCi0gICAqCi0gICAqIEBwYXJhbSBwX290aGVyIHRoZSBVUkkgdG8gY29weSAoY2Fubm90IGJlIG51bGwpCi0gICAqLwotICBwdWJsaWMgVVJJKFVSSSBwX290aGVyKQotICB7Ci0gICAgaW5pdGlhbGl6ZShwX290aGVyKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBuZXcgVVJJIGZyb20gYSBVUkkgc3BlY2lmaWNhdGlvbiBzdHJpbmcuIElmIHRoZQotICAgKiBzcGVjaWZpY2F0aW9uIGZvbGxvd3MgdGhlICJnZW5lcmljIFVSSSIgc3ludGF4LCAodHdvIHNsYXNoZXMKLSAgICogZm9sbG93aW5nIHRoZSBmaXJzdCBjb2xvbiksIHRoZSBzcGVjaWZpY2F0aW9uIHdpbGwgYmUgcGFyc2VkCi0gICAqIGFjY29yZGluZ2x5IC0gc2V0dGluZyB0aGUgc2NoZW1lLCB1c2VyaW5mbywgaG9zdCxwb3J0LCBwYXRoLCBxdWVyeQotICAgKiBzdHJpbmcgYW5kIGZyYWdtZW50IGZpZWxkcyBhcyBuZWNlc3NhcnkuIElmIHRoZSBzcGVjaWZpY2F0aW9uIGRvZXMKLSAgICogbm90IGZvbGxvdyB0aGUgImdlbmVyaWMgVVJJIiBzeW50YXgsIHRoZSBzcGVjaWZpY2F0aW9uIGlzIHBhcnNlZAotICAgKiBpbnRvIGEgc2NoZW1lIGFuZCBzY2hlbWUtc3BlY2lmaWMgcGFydCAoc3RvcmVkIGFzIHRoZSBwYXRoKSBvbmx5LgotICAgKgotICAgKiBAcGFyYW0gcF91cmlTcGVjIHRoZSBVUkkgc3BlY2lmaWNhdGlvbiBzdHJpbmcgKGNhbm5vdCBiZSBudWxsIG9yCi0gICAqICAgICAgICAgICAgICAgICAgZW1wdHkpCi0gICAqCi0gICAqIEB0aHJvd3MgTWFsZm9ybWVkVVJJRXhjZXB0aW9uIGlmIHBfdXJpU3BlYyB2aW9sYXRlcyBhbnkgc3ludGF4Ci0gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBydWxlcwotICAgKi8KLSAgcHVibGljIFVSSShTdHJpbmcgcF91cmlTcGVjKSB0aHJvd3MgTWFsZm9ybWVkVVJJRXhjZXB0aW9uCi0gIHsKLSAgICB0aGlzKChVUkkpIG51bGwsIHBfdXJpU3BlYyk7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgbmV3IFVSSSBmcm9tIGEgYmFzZSBVUkkgYW5kIGEgVVJJIHNwZWNpZmljYXRpb24gc3RyaW5nLgotICAgKiBUaGUgVVJJIHNwZWNpZmljYXRpb24gc3RyaW5nIG1heSBiZSBhIHJlbGF0aXZlIFVSSS4KLSAgICoKLSAgICogQHBhcmFtIHBfYmFzZSB0aGUgYmFzZSBVUkkgKGNhbm5vdCBiZSBudWxsIGlmIHBfdXJpU3BlYyBpcyBudWxsIG9yCi0gICAqICAgICAgICAgICAgICAgZW1wdHkpCi0gICAqIEBwYXJhbSBwX3VyaVNwZWMgdGhlIFVSSSBzcGVjaWZpY2F0aW9uIHN0cmluZyAoY2Fubm90IGJlIG51bGwgb3IKLSAgICogICAgICAgICAgICAgICAgICBlbXB0eSBpZiBwX2Jhc2UgaXMgbnVsbCkKLSAgICoKLSAgICogQHRocm93cyBNYWxmb3JtZWRVUklFeGNlcHRpb24gaWYgcF91cmlTcGVjIHZpb2xhdGVzIGFueSBzeW50YXgKLSAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcnVsZXMKLSAgICovCi0gIHB1YmxpYyBVUkkoVVJJIHBfYmFzZSwgU3RyaW5nIHBfdXJpU3BlYykgdGhyb3dzIE1hbGZvcm1lZFVSSUV4Y2VwdGlvbgotICB7Ci0gICAgaW5pdGlhbGl6ZShwX2Jhc2UsIHBfdXJpU3BlYyk7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgbmV3IFVSSSB0aGF0IGRvZXMgbm90IGZvbGxvdyB0aGUgZ2VuZXJpYyBVUkkgc3ludGF4LgotICAgKiBPbmx5IHRoZSBzY2hlbWUgYW5kIHNjaGVtZS1zcGVjaWZpYyBwYXJ0IChzdG9yZWQgYXMgdGhlIHBhdGgpIGFyZQotICAgKiBpbml0aWFsaXplZC4KLSAgICoKLSAgICogQHBhcmFtIHBfc2NoZW1lIHRoZSBVUkkgc2NoZW1lIChjYW5ub3QgYmUgbnVsbCBvciBlbXB0eSkKLSAgICogQHBhcmFtIHBfc2NoZW1lU3BlY2lmaWNQYXJ0IHRoZSBzY2hlbWUtc3BlY2lmaWMgcGFydCAoY2Fubm90IGJlCi0gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsIG9yIGVtcHR5KQotICAgKgotICAgKiBAdGhyb3dzIE1hbGZvcm1lZFVSSUV4Y2VwdGlvbiBpZiBwX3NjaGVtZSB2aW9sYXRlcyBhbnkKLSAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ludGF4IHJ1bGVzCi0gICAqLwotICBwdWJsaWMgVVJJKFN0cmluZyBwX3NjaGVtZSwgU3RyaW5nIHBfc2NoZW1lU3BlY2lmaWNQYXJ0KQotICAgICAgICAgIHRocm93cyBNYWxmb3JtZWRVUklFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKHBfc2NoZW1lID09IG51bGwgfHwgcF9zY2hlbWUudHJpbSgpLmxlbmd0aCgpID09IDApCi0gICAgewotICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVSSUV4Y2VwdGlvbigKLSAgICAgICAgIkNhbm5vdCBjb25zdHJ1Y3QgVVJJIHdpdGggbnVsbC9lbXB0eSBzY2hlbWUhIik7Ci0gICAgfQotCi0gICAgaWYgKHBfc2NoZW1lU3BlY2lmaWNQYXJ0ID09IG51bGwKLSAgICAgICAgICAgIHx8IHBfc2NoZW1lU3BlY2lmaWNQYXJ0LnRyaW0oKS5sZW5ndGgoKSA9PSAwKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVUklFeGNlcHRpb24oCi0gICAgICAgICJDYW5ub3QgY29uc3RydWN0IFVSSSB3aXRoIG51bGwvZW1wdHkgc2NoZW1lLXNwZWNpZmljIHBhcnQhIik7Ci0gICAgfQotCi0gICAgc2V0U2NoZW1lKHBfc2NoZW1lKTsKLSAgICBzZXRQYXRoKHBfc2NoZW1lU3BlY2lmaWNQYXJ0KTsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBuZXcgVVJJIHRoYXQgZm9sbG93cyB0aGUgZ2VuZXJpYyBVUkkgc3ludGF4IGZyb20gaXRzCi0gICAqIGNvbXBvbmVudCBwYXJ0cy4gRWFjaCBjb21wb25lbnQgaXMgdmFsaWRhdGVkIGZvciBzeW50YXggYW5kIHNvbWUKLSAgICogYmFzaWMgc2VtYW50aWMgY2hlY2tzIGFyZSBwZXJmb3JtZWQgYXMgd2VsbC4gIFNlZSB0aGUgaW5kaXZpZHVhbAotICAgKiBzZXR0ZXIgbWV0aG9kcyBmb3Igc3BlY2lmaWNzLgotICAgKgotICAgKiBAcGFyYW0gcF9zY2hlbWUgdGhlIFVSSSBzY2hlbWUgKGNhbm5vdCBiZSBudWxsIG9yIGVtcHR5KQotICAgKiBAcGFyYW0gcF9ob3N0IHRoZSBob3N0bmFtZSBvciBJUHY0IGFkZHJlc3MgZm9yIHRoZSBVUkkKLSAgICogQHBhcmFtIHBfcGF0aCB0aGUgVVJJIHBhdGggLSBpZiB0aGUgcGF0aCBjb250YWlucyAnPycgb3IgJyMnLAotICAgKiAgICAgICAgICAgICAgIHRoZW4gdGhlIHF1ZXJ5IHN0cmluZyBhbmQvb3IgZnJhZ21lbnQgd2lsbCBiZQotICAgKiAgICAgICAgICAgICAgIHNldCBmcm9tIHRoZSBwYXRoOyBob3dldmVyLCBpZiB0aGUgcXVlcnkgYW5kCi0gICAqICAgICAgICAgICAgICAgZnJhZ21lbnQgYXJlIHNwZWNpZmllZCBib3RoIGluIHRoZSBwYXRoIGFuZCBhcwotICAgKiAgICAgICAgICAgICAgIHNlcGFyYXRlIHBhcmFtZXRlcnMsIGFuIGV4Y2VwdGlvbiBpcyB0aHJvd24KLSAgICogQHBhcmFtIHBfcXVlcnlTdHJpbmcgdGhlIFVSSSBxdWVyeSBzdHJpbmcgKGNhbm5vdCBiZSBzcGVjaWZpZWQKLSAgICogICAgICAgICAgICAgICAgICAgICAgaWYgcGF0aCBpcyBudWxsKQotICAgKiBAcGFyYW0gcF9mcmFnbWVudCB0aGUgVVJJIGZyYWdtZW50IChjYW5ub3QgYmUgc3BlY2lmaWVkIGlmIHBhdGgKLSAgICogICAgICAgICAgICAgICAgICAgaXMgbnVsbCkKLSAgICoKLSAgICogQHRocm93cyBNYWxmb3JtZWRVUklFeGNlcHRpb24gaWYgYW55IG9mIHRoZSBwYXJhbWV0ZXJzIHZpb2xhdGVzCi0gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bnRheCBydWxlcyBvciBzZW1hbnRpYyBydWxlcwotICAgKi8KLSAgcHVibGljIFVSSShTdHJpbmcgcF9zY2hlbWUsIFN0cmluZyBwX2hvc3QsIFN0cmluZyBwX3BhdGgsIFN0cmluZyBwX3F1ZXJ5U3RyaW5nLCBTdHJpbmcgcF9mcmFnbWVudCkKLSAgICAgICAgICB0aHJvd3MgTWFsZm9ybWVkVVJJRXhjZXB0aW9uCi0gIHsKLSAgICB0aGlzKHBfc2NoZW1lLCBudWxsLCBwX2hvc3QsIC0xLCBwX3BhdGgsIHBfcXVlcnlTdHJpbmcsIHBfZnJhZ21lbnQpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhIG5ldyBVUkkgdGhhdCBmb2xsb3dzIHRoZSBnZW5lcmljIFVSSSBzeW50YXggZnJvbSBpdHMKLSAgICogY29tcG9uZW50IHBhcnRzLiBFYWNoIGNvbXBvbmVudCBpcyB2YWxpZGF0ZWQgZm9yIHN5bnRheCBhbmQgc29tZQotICAgKiBiYXNpYyBzZW1hbnRpYyBjaGVja3MgYXJlIHBlcmZvcm1lZCBhcyB3ZWxsLiAgU2VlIHRoZSBpbmRpdmlkdWFsCi0gICAqIHNldHRlciBtZXRob2RzIGZvciBzcGVjaWZpY3MuCi0gICAqCi0gICAqIEBwYXJhbSBwX3NjaGVtZSB0aGUgVVJJIHNjaGVtZSAoY2Fubm90IGJlIG51bGwgb3IgZW1wdHkpCi0gICAqIEBwYXJhbSBwX3VzZXJpbmZvIHRoZSBVUkkgdXNlcmluZm8gKGNhbm5vdCBiZSBzcGVjaWZpZWQgaWYgaG9zdAotICAgKiAgICAgICAgICAgICAgICAgICBpcyBudWxsKQotICAgKiBAcGFyYW0gcF9ob3N0IHRoZSBob3N0bmFtZSBvciBJUHY0IGFkZHJlc3MgZm9yIHRoZSBVUkkKLSAgICogQHBhcmFtIHBfcG9ydCB0aGUgVVJJIHBvcnQgKG1heSBiZSAtMSBmb3IgInVuc3BlY2lmaWVkIjsgY2Fubm90Ci0gICAqICAgICAgICAgICAgICAgYmUgc3BlY2lmaWVkIGlmIGhvc3QgaXMgbnVsbCkKLSAgICogQHBhcmFtIHBfcGF0aCB0aGUgVVJJIHBhdGggLSBpZiB0aGUgcGF0aCBjb250YWlucyAnPycgb3IgJyMnLAotICAgKiAgICAgICAgICAgICAgIHRoZW4gdGhlIHF1ZXJ5IHN0cmluZyBhbmQvb3IgZnJhZ21lbnQgd2lsbCBiZQotICAgKiAgICAgICAgICAgICAgIHNldCBmcm9tIHRoZSBwYXRoOyBob3dldmVyLCBpZiB0aGUgcXVlcnkgYW5kCi0gICAqICAgICAgICAgICAgICAgZnJhZ21lbnQgYXJlIHNwZWNpZmllZCBib3RoIGluIHRoZSBwYXRoIGFuZCBhcwotICAgKiAgICAgICAgICAgICAgIHNlcGFyYXRlIHBhcmFtZXRlcnMsIGFuIGV4Y2VwdGlvbiBpcyB0aHJvd24KLSAgICogQHBhcmFtIHBfcXVlcnlTdHJpbmcgdGhlIFVSSSBxdWVyeSBzdHJpbmcgKGNhbm5vdCBiZSBzcGVjaWZpZWQKLSAgICogICAgICAgICAgICAgICAgICAgICAgaWYgcGF0aCBpcyBudWxsKQotICAgKiBAcGFyYW0gcF9mcmFnbWVudCB0aGUgVVJJIGZyYWdtZW50IChjYW5ub3QgYmUgc3BlY2lmaWVkIGlmIHBhdGgKLSAgICogICAgICAgICAgICAgICAgICAgaXMgbnVsbCkKLSAgICoKLSAgICogQHRocm93cyBNYWxmb3JtZWRVUklFeGNlcHRpb24gaWYgYW55IG9mIHRoZSBwYXJhbWV0ZXJzIHZpb2xhdGVzCi0gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bnRheCBydWxlcyBvciBzZW1hbnRpYyBydWxlcwotICAgKi8KLSAgcHVibGljIFVSSShTdHJpbmcgcF9zY2hlbWUsIFN0cmluZyBwX3VzZXJpbmZvLCBTdHJpbmcgcF9ob3N0LCBpbnQgcF9wb3J0LCBTdHJpbmcgcF9wYXRoLCBTdHJpbmcgcF9xdWVyeVN0cmluZywgU3RyaW5nIHBfZnJhZ21lbnQpCi0gICAgICAgICAgdGhyb3dzIE1hbGZvcm1lZFVSSUV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAocF9zY2hlbWUgPT0gbnVsbCB8fCBwX3NjaGVtZS50cmltKCkubGVuZ3RoKCkgPT0gMCkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVVJJRXhjZXB0aW9uKFV0aWxzLm1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoTXNnS2V5LkVSX1NDSEVNRV9SRVFVSVJFRCwgbnVsbCkpOyAvLyJTY2hlbWUgaXMgcmVxdWlyZWQhIik7Ci0gICAgfQotCi0gICAgaWYgKHBfaG9zdCA9PSBudWxsKQotICAgIHsKLSAgICAgIGlmIChwX3VzZXJpbmZvICE9IG51bGwpCi0gICAgICB7Ci0gICAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVUklFeGNlcHRpb24oCi0gICAgICAgICAgVXRpbHMubWVzc2FnZXMuY3JlYXRlTWVzc2FnZShNc2dLZXkuRVJfTk9fVVNFUklORk9fSUZfTk9fSE9TVCwgbnVsbCkpOyAvLyJVc2VyaW5mbyBtYXkgbm90IGJlIHNwZWNpZmllZCBpZiBob3N0IGlzIG5vdCBzcGVjaWZpZWQhIik7Ci0gICAgICB9Ci0KLSAgICAgIGlmIChwX3BvcnQgIT0gLTEpCi0gICAgICB7Ci0gICAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVUklFeGNlcHRpb24oCi0gICAgICAgICAgVXRpbHMubWVzc2FnZXMuY3JlYXRlTWVzc2FnZShNc2dLZXkuRVJfTk9fUE9SVF9JRl9OT19IT1NULCBudWxsKSk7IC8vIlBvcnQgbWF5IG5vdCBiZSBzcGVjaWZpZWQgaWYgaG9zdCBpcyBub3Qgc3BlY2lmaWVkISIpOwotICAgICAgfQotICAgIH0KLQotICAgIGlmIChwX3BhdGggIT0gbnVsbCkKLSAgICB7Ci0gICAgICBpZiAocF9wYXRoLmluZGV4T2YoJz8nKSAhPSAtMSAmJiBwX3F1ZXJ5U3RyaW5nICE9IG51bGwpCi0gICAgICB7Ci0gICAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVUklFeGNlcHRpb24oCi0gICAgICAgICAgVXRpbHMubWVzc2FnZXMuY3JlYXRlTWVzc2FnZShNc2dLZXkuRVJfTk9fUVVFUllfU1RSSU5HX0lOX1BBVEgsIG51bGwpKTsgLy8iUXVlcnkgc3RyaW5nIGNhbm5vdCBiZSBzcGVjaWZpZWQgaW4gcGF0aCBhbmQgcXVlcnkgc3RyaW5nISIpOwotICAgICAgfQotCi0gICAgICBpZiAocF9wYXRoLmluZGV4T2YoJyMnKSAhPSAtMSAmJiBwX2ZyYWdtZW50ICE9IG51bGwpCi0gICAgICB7Ci0gICAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVUklFeGNlcHRpb24oCi0gICAgICAgICAgVXRpbHMubWVzc2FnZXMuY3JlYXRlTWVzc2FnZShNc2dLZXkuRVJfTk9fRlJBR01FTlRfU1RSSU5HX0lOX1BBVEgsIG51bGwpKTsgLy8iRnJhZ21lbnQgY2Fubm90IGJlIHNwZWNpZmllZCBpbiBib3RoIHRoZSBwYXRoIGFuZCBmcmFnbWVudCEiKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICBzZXRTY2hlbWUocF9zY2hlbWUpOwotICAgIHNldEhvc3QocF9ob3N0KTsKLSAgICBzZXRQb3J0KHBfcG9ydCk7Ci0gICAgc2V0VXNlcmluZm8ocF91c2VyaW5mbyk7Ci0gICAgc2V0UGF0aChwX3BhdGgpOwotICAgIHNldFF1ZXJ5U3RyaW5nKHBfcXVlcnlTdHJpbmcpOwotICAgIHNldEZyYWdtZW50KHBfZnJhZ21lbnQpOwotICB9Ci0KLSAgLyoqCi0gICAqIEluaXRpYWxpemUgYWxsIGZpZWxkcyBvZiB0aGlzIFVSSSBmcm9tIGFub3RoZXIgVVJJLgotICAgKgotICAgKiBAcGFyYW0gcF9vdGhlciB0aGUgVVJJIHRvIGNvcHkgKGNhbm5vdCBiZSBudWxsKQotICAgKi8KLSAgcHJpdmF0ZSB2b2lkIGluaXRpYWxpemUoVVJJIHBfb3RoZXIpCi0gIHsKLQotICAgIG1fc2NoZW1lID0gcF9vdGhlci5nZXRTY2hlbWUoKTsKLSAgICBtX3VzZXJpbmZvID0gcF9vdGhlci5nZXRVc2VyaW5mbygpOwotICAgIG1faG9zdCA9IHBfb3RoZXIuZ2V0SG9zdCgpOwotICAgIG1fcG9ydCA9IHBfb3RoZXIuZ2V0UG9ydCgpOwotICAgIG1fcGF0aCA9IHBfb3RoZXIuZ2V0UGF0aCgpOwotICAgIG1fcXVlcnlTdHJpbmcgPSBwX290aGVyLmdldFF1ZXJ5U3RyaW5nKCk7Ci0gICAgbV9mcmFnbWVudCA9IHBfb3RoZXIuZ2V0RnJhZ21lbnQoKTsKLSAgfQotCi0gIC8qKgotICAgKiBJbml0aWFsaXplcyB0aGlzIFVSSSBmcm9tIGEgYmFzZSBVUkkgYW5kIGEgVVJJIHNwZWNpZmljYXRpb24gc3RyaW5nLgotICAgKiBTZWUgUkZDIDIzOTYgU2VjdGlvbiA0IGFuZCBBcHBlbmRpeCBCIGZvciBzcGVjaWZpY2F0aW9ucyBvbiBwYXJzaW5nCi0gICAqIHRoZSBVUkkgYW5kIFNlY3Rpb24gNSBmb3Igc3BlY2lmaWNhdGlvbnMgb24gcmVzb2x2aW5nIHJlbGF0aXZlIFVSSXMKLSAgICogYW5kIHJlbGF0aXZlIHBhdGhzLgotICAgKgotICAgKiBAcGFyYW0gcF9iYXNlIHRoZSBiYXNlIFVSSSAobWF5IGJlIG51bGwgaWYgcF91cmlTcGVjIGlzIGFuIGFic29sdXRlCi0gICAqICAgICAgICAgICAgICAgVVJJKQotICAgKiBAcGFyYW0gcF91cmlTcGVjIHRoZSBVUkkgc3BlYyBzdHJpbmcgd2hpY2ggbWF5IGJlIGFuIGFic29sdXRlIG9yCi0gICAqICAgICAgICAgICAgICAgICAgcmVsYXRpdmUgVVJJIChjYW4gb25seSBiZSBudWxsL2VtcHR5IGlmIHBfYmFzZQotICAgKiAgICAgICAgICAgICAgICAgIGlzIG5vdCBudWxsKQotICAgKgotICAgKiBAdGhyb3dzIE1hbGZvcm1lZFVSSUV4Y2VwdGlvbiBpZiBwX2Jhc2UgaXMgbnVsbCBhbmQgcF91cmlTcGVjCi0gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzIG5vdCBhbiBhYnNvbHV0ZSBVUkkgb3IgaWYKLSAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcF91cmlTcGVjIHZpb2xhdGVzIHN5bnRheCBydWxlcwotICAgKi8KLSAgcHJpdmF0ZSB2b2lkIGluaXRpYWxpemUoVVJJIHBfYmFzZSwgU3RyaW5nIHBfdXJpU3BlYykKLSAgICAgICAgICB0aHJvd3MgTWFsZm9ybWVkVVJJRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChwX2Jhc2UgPT0gbnVsbAotICAgICAgICAgICAgJiYgKHBfdXJpU3BlYyA9PSBudWxsIHx8IHBfdXJpU3BlYy50cmltKCkubGVuZ3RoKCkgPT0gMCkpCi0gICAgewotICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVSSUV4Y2VwdGlvbigKLSAgICAgICAgVXRpbHMubWVzc2FnZXMuY3JlYXRlTWVzc2FnZShNc2dLZXkuRVJfQ0FOTk9UX0lOSVRfVVJJX0VNUFRZX1BBUk1TLCBudWxsKSk7IC8vIkNhbm5vdCBpbml0aWFsaXplIFVSSSB3aXRoIGVtcHR5IHBhcmFtZXRlcnMuIik7Ci0gICAgfQotCi0gICAgLy8ganVzdCBtYWtlIGEgY29weSBvZiB0aGUgYmFzZSBpZiBzcGVjIGlzIGVtcHR5Ci0gICAgaWYgKHBfdXJpU3BlYyA9PSBudWxsIHx8IHBfdXJpU3BlYy50cmltKCkubGVuZ3RoKCkgPT0gMCkKLSAgICB7Ci0gICAgICBpbml0aWFsaXplKHBfYmFzZSk7Ci0KLSAgICAgIHJldHVybjsKLSAgICB9Ci0KLSAgICBTdHJpbmcgdXJpU3BlYyA9IHBfdXJpU3BlYy50cmltKCk7Ci0gICAgaW50IHVyaVNwZWNMZW4gPSB1cmlTcGVjLmxlbmd0aCgpOwotICAgIGludCBpbmRleCA9IDA7Ci0KLSAgICAvLyBjaGVjayBmb3Igc2NoZW1lCi0gICAgaW50IGNvbG9uSW5kZXggPSB1cmlTcGVjLmluZGV4T2YoJzonKTsKLSAgICBpZiAoY29sb25JbmRleCA8IDApCi0gICAgewotICAgICAgaWYgKHBfYmFzZSA9PSBudWxsKQotICAgICAgewotICAgICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVVJJRXhjZXB0aW9uKFV0aWxzLm1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoTXNnS2V5LkVSX05PX1NDSEVNRV9JTl9VUkksIG5ldyBPYmplY3RbXXt1cmlTcGVjfSkpOyAvLyJObyBzY2hlbWUgZm91bmQgaW4gVVJJOiAiK3VyaVNwZWMpOwotICAgICAgfQotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgaW5pdGlhbGl6ZVNjaGVtZSh1cmlTcGVjKTsKLSAgICAgIHVyaVNwZWMgPSB1cmlTcGVjLnN1YnN0cmluZyhjb2xvbkluZGV4KzEpOwotICAgICAgdXJpU3BlY0xlbiA9IHVyaVNwZWMubGVuZ3RoKCk7Ci0gICAgfQotCi0gICAgLy8gdHdvIHNsYXNoZXMgbWVhbnMgZ2VuZXJpYyBVUkkgc3ludGF4LCBzbyB3ZSBnZXQgdGhlIGF1dGhvcml0eQotICAgIGlmICgoKGluZGV4ICsgMSkgPCB1cmlTcGVjTGVuKQotICAgICAgICAgICAgJiYgKHVyaVNwZWMuc3Vic3RyaW5nKGluZGV4KS5zdGFydHNXaXRoKCIvLyIpKSkKLSAgICB7Ci0gICAgICBpbmRleCArPSAyOwotCi0gICAgICBpbnQgc3RhcnRQb3MgPSBpbmRleDsKLQotICAgICAgLy8gZ2V0IGF1dGhvcml0eSAtIGV2ZXJ5dGhpbmcgdXAgdG8gcGF0aCwgcXVlcnkgb3IgZnJhZ21lbnQKLSAgICAgIGNoYXIgdGVzdENoYXIgPSAnXDAnOwotCi0gICAgICB3aGlsZSAoaW5kZXggPCB1cmlTcGVjTGVuKQotICAgICAgewotICAgICAgICB0ZXN0Q2hhciA9IHVyaVNwZWMuY2hhckF0KGluZGV4KTsKLQotICAgICAgICBpZiAodGVzdENoYXIgPT0gJy8nIHx8IHRlc3RDaGFyID09ICc/JyB8fCB0ZXN0Q2hhciA9PSAnIycpCi0gICAgICAgIHsKLSAgICAgICAgICBicmVhazsKLSAgICAgICAgfQotCi0gICAgICAgIGluZGV4Kys7Ci0gICAgICB9Ci0KLSAgICAgIC8vIGlmIHdlIGZvdW5kIGF1dGhvcml0eSwgcGFyc2UgaXQgb3V0LCBvdGhlcndpc2Ugd2Ugc2V0IHRoZQotICAgICAgLy8gaG9zdCB0byBlbXB0eSBzdHJpbmcKLSAgICAgIGlmIChpbmRleCA+IHN0YXJ0UG9zKQotICAgICAgewotICAgICAgICBpbml0aWFsaXplQXV0aG9yaXR5KHVyaVNwZWMuc3Vic3RyaW5nKHN0YXJ0UG9zLCBpbmRleCkpOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBtX2hvc3QgPSAiIjsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICBpbml0aWFsaXplUGF0aCh1cmlTcGVjLnN1YnN0cmluZyhpbmRleCkpOwotCi0gICAgLy8gUmVzb2x2ZSByZWxhdGl2ZSBVUkkgdG8gYmFzZSBVUkkgLSBzZWUgUkZDIDIzOTYgU2VjdGlvbiA1LjIKLSAgICAvLyBJbiBzb21lIGNhc2VzLCBpdCBtaWdodCBtYWtlIG1vcmUgc2Vuc2UgdG8gdGhyb3cgYW4gZXhjZXB0aW9uCi0gICAgLy8gKHdoZW4gc2NoZW1lIGlzIHNwZWNpZmllZCBpcyB0aGUgc3RyaW5nIHNwZWMgYW5kIHRoZSBiYXNlIFVSSQotICAgIC8vIGlzIGFsc28gc3BlY2lmaWVkLCBmb3IgZXhhbXBsZSksIGJ1dCB3ZSdyZSBqdXN0IGZvbGxvd2luZyB0aGUKLSAgICAvLyBSRkMgc3BlY2lmaWNhdGlvbnMKLSAgICBpZiAocF9iYXNlICE9IG51bGwpCi0gICAgewotCi0gICAgICAvLyBjaGVjayB0byBzZWUgaWYgdGhpcyBpcyB0aGUgY3VycmVudCBkb2MgLSBSRkMgMjM5NiA1LjIgIzIKLSAgICAgIC8vIG5vdGUgdGhhdCB0aGlzIGlzIHNsaWdodGx5IGRpZmZlcmVudCBmcm9tIHRoZSBSRkMgc3BlYyBpbiB0aGF0Ci0gICAgICAvLyB3ZSBkb24ndCBpbmNsdWRlIHRoZSBjaGVjayBmb3IgcXVlcnkgc3RyaW5nIGJlaW5nIG51bGwKLSAgICAgIC8vIC0gdGhpcyBoYW5kbGVzIGNhc2VzIHdoZXJlIHRoZSB1cmlzcGVjIGlzIGp1c3QgYSBxdWVyeQotICAgICAgLy8gc3RyaW5nIG9yIGEgZnJhZ21lbnQgKGUuZy4gIj95IiBvciAiI3MiKSAtCi0gICAgICAvLyBzZWUgPGh0dHA6Ly93d3cuaWNzLnVjaS5lZHUvfmZpZWxkaW5nL3VybC90ZXN0MS5odG1sPiB3aGljaAotICAgICAgLy8gaWRlbnRpZmllZCB0aGlzIGFzIGEgYnVnIGluIHRoZSBSRkMKLSAgICAgIGlmIChtX3BhdGgubGVuZ3RoKCkgPT0gMCAmJiBtX3NjaGVtZSA9PSBudWxsICYmIG1faG9zdCA9PSBudWxsKQotICAgICAgewotICAgICAgICBtX3NjaGVtZSA9IHBfYmFzZS5nZXRTY2hlbWUoKTsKLSAgICAgICAgbV91c2VyaW5mbyA9IHBfYmFzZS5nZXRVc2VyaW5mbygpOwotICAgICAgICBtX2hvc3QgPSBwX2Jhc2UuZ2V0SG9zdCgpOwotICAgICAgICBtX3BvcnQgPSBwX2Jhc2UuZ2V0UG9ydCgpOwotICAgICAgICBtX3BhdGggPSBwX2Jhc2UuZ2V0UGF0aCgpOwotCi0gICAgICAgIGlmIChtX3F1ZXJ5U3RyaW5nID09IG51bGwpCi0gICAgICAgIHsKLSAgICAgICAgICBtX3F1ZXJ5U3RyaW5nID0gcF9iYXNlLmdldFF1ZXJ5U3RyaW5nKCk7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm47Ci0gICAgICB9Ci0KLSAgICAgIC8vIGNoZWNrIGZvciBzY2hlbWUgLSBSRkMgMjM5NiA1LjIgIzMKLSAgICAgIC8vIGlmIHdlIGZvdW5kIGEgc2NoZW1lLCBpdCBtZWFucyBhYnNvbHV0ZSBVUkksIHNvIHdlJ3JlIGRvbmUKLSAgICAgIGlmIChtX3NjaGVtZSA9PSBudWxsKQotICAgICAgewotICAgICAgICBtX3NjaGVtZSA9IHBfYmFzZS5nZXRTY2hlbWUoKTsKLSAgICAgIH0KLQotICAgICAgLy8gY2hlY2sgZm9yIGF1dGhvcml0eSAtIFJGQyAyMzk2IDUuMiAjNAotICAgICAgLy8gaWYgd2UgZm91bmQgYSBob3N0LCB0aGVuIHdlJ3ZlIGdvdCBhIG5ldHdvcmsgcGF0aCwgc28gd2UncmUgZG9uZQotICAgICAgaWYgKG1faG9zdCA9PSBudWxsKQotICAgICAgewotICAgICAgICBtX3VzZXJpbmZvID0gcF9iYXNlLmdldFVzZXJpbmZvKCk7Ci0gICAgICAgIG1faG9zdCA9IHBfYmFzZS5nZXRIb3N0KCk7Ci0gICAgICAgIG1fcG9ydCA9IHBfYmFzZS5nZXRQb3J0KCk7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIHJldHVybjsKLSAgICAgIH0KLQotICAgICAgLy8gY2hlY2sgZm9yIGFic29sdXRlIHBhdGggLSBSRkMgMjM5NiA1LjIgIzUKLSAgICAgIGlmIChtX3BhdGgubGVuZ3RoKCkgPiAwICYmIG1fcGF0aC5zdGFydHNXaXRoKCIvIikpCi0gICAgICB7Ci0gICAgICAgIHJldHVybjsKLSAgICAgIH0KLQotICAgICAgLy8gaWYgd2UgZ2V0IHRvIHRoaXMgcG9pbnQsIHdlIG5lZWQgdG8gcmVzb2x2ZSByZWxhdGl2ZSBwYXRoCi0gICAgICAvLyBSRkMgMjM5NiA1LjIgIzYKLSAgICAgIFN0cmluZyBwYXRoID0gIiI7Ci0gICAgICBTdHJpbmcgYmFzZVBhdGggPSBwX2Jhc2UuZ2V0UGF0aCgpOwotCi0gICAgICAvLyA2YSAtIGdldCBhbGwgYnV0IHRoZSBsYXN0IHNlZ21lbnQgb2YgdGhlIGJhc2UgVVJJIHBhdGgKLSAgICAgIGlmIChiYXNlUGF0aCAhPSBudWxsKQotICAgICAgewotICAgICAgICBpbnQgbGFzdFNsYXNoID0gYmFzZVBhdGgubGFzdEluZGV4T2YoJy8nKTsKLQotICAgICAgICBpZiAobGFzdFNsYXNoICE9IC0xKQotICAgICAgICB7Ci0gICAgICAgICAgcGF0aCA9IGJhc2VQYXRoLnN1YnN0cmluZygwLCBsYXN0U2xhc2ggKyAxKTsKLSAgICAgICAgfQotICAgICAgfQotCi0gICAgICAvLyA2YiAtIGFwcGVuZCB0aGUgcmVsYXRpdmUgVVJJIHBhdGgKLSAgICAgIHBhdGggPSBwYXRoLmNvbmNhdChtX3BhdGgpOwotCi0gICAgICAvLyA2YyAtIHJlbW92ZSBhbGwgIi4vIiB3aGVyZSAiLiIgaXMgYSBjb21wbGV0ZSBwYXRoIHNlZ21lbnQKLSAgICAgIGluZGV4ID0gLTE7Ci0KLSAgICAgIHdoaWxlICgoaW5kZXggPSBwYXRoLmluZGV4T2YoIi8uLyIpKSAhPSAtMSkKLSAgICAgIHsKLSAgICAgICAgcGF0aCA9IHBhdGguc3Vic3RyaW5nKDAsIGluZGV4ICsgMSkuY29uY2F0KHBhdGguc3Vic3RyaW5nKGluZGV4ICsgMykpOwotICAgICAgfQotCi0gICAgICAvLyA2ZCAtIHJlbW92ZSAiLiIgaWYgcGF0aCBlbmRzIHdpdGggIi4iIGFzIGEgY29tcGxldGUgcGF0aCBzZWdtZW50Ci0gICAgICBpZiAocGF0aC5lbmRzV2l0aCgiLy4iKSkKLSAgICAgIHsKLSAgICAgICAgcGF0aCA9IHBhdGguc3Vic3RyaW5nKDAsIHBhdGgubGVuZ3RoKCkgLSAxKTsKLSAgICAgIH0KLQotICAgICAgLy8gNmUgLSByZW1vdmUgYWxsICI8c2VnbWVudD4vLi4vIiB3aGVyZSAiPHNlZ21lbnQ+IiBpcyBhIGNvbXBsZXRlCi0gICAgICAvLyBwYXRoIHNlZ21lbnQgbm90IGVxdWFsIHRvICIuLiIKLSAgICAgIGluZGV4ID0gLTE7Ci0KLSAgICAgIGludCBzZWdJbmRleCA9IC0xOwotICAgICAgU3RyaW5nIHRlbXBTdHJpbmcgPSBudWxsOwotCi0gICAgICB3aGlsZSAoKGluZGV4ID0gcGF0aC5pbmRleE9mKCIvLi4vIikpID4gMCkKLSAgICAgIHsKLSAgICAgICAgdGVtcFN0cmluZyA9IHBhdGguc3Vic3RyaW5nKDAsIHBhdGguaW5kZXhPZigiLy4uLyIpKTsKLSAgICAgICAgc2VnSW5kZXggPSB0ZW1wU3RyaW5nLmxhc3RJbmRleE9mKCcvJyk7Ci0KLSAgICAgICAgaWYgKHNlZ0luZGV4ICE9IC0xKQotICAgICAgICB7Ci0gICAgICAgICAgaWYgKCF0ZW1wU3RyaW5nLnN1YnN0cmluZyhzZWdJbmRleCsrKS5lcXVhbHMoIi4uIikpCi0gICAgICAgICAgewotICAgICAgICAgICAgcGF0aCA9IHBhdGguc3Vic3RyaW5nKDAsIHNlZ0luZGV4KS5jb25jYXQocGF0aC5zdWJzdHJpbmcoaW5kZXgKLSAgICAgICAgICAgICAgICAgICAgKyA0KSk7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICB9Ci0KLSAgICAgIC8vIDZmIC0gcmVtb3ZlIGVuZGluZyAiPHNlZ21lbnQ+Ly4uIiB3aGVyZSAiPHNlZ21lbnQ+IiBpcyBhCi0gICAgICAvLyBjb21wbGV0ZSBwYXRoIHNlZ21lbnQKLSAgICAgIGlmIChwYXRoLmVuZHNXaXRoKCIvLi4iKSkKLSAgICAgIHsKLSAgICAgICAgdGVtcFN0cmluZyA9IHBhdGguc3Vic3RyaW5nKDAsIHBhdGgubGVuZ3RoKCkgLSAzKTsKLSAgICAgICAgc2VnSW5kZXggPSB0ZW1wU3RyaW5nLmxhc3RJbmRleE9mKCcvJyk7Ci0KLSAgICAgICAgaWYgKHNlZ0luZGV4ICE9IC0xKQotICAgICAgICB7Ci0gICAgICAgICAgcGF0aCA9IHBhdGguc3Vic3RyaW5nKDAsIHNlZ0luZGV4ICsgMSk7Ci0gICAgICAgIH0KLSAgICAgIH0KLQotICAgICAgbV9wYXRoID0gcGF0aDsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogSW5pdGlhbGl6ZSB0aGUgc2NoZW1lIGZvciB0aGlzIFVSSSBmcm9tIGEgVVJJIHN0cmluZyBzcGVjLgotICAgKgotICAgKiBAcGFyYW0gcF91cmlTcGVjIHRoZSBVUkkgc3BlY2lmaWNhdGlvbiAoY2Fubm90IGJlIG51bGwpCi0gICAqCi0gICAqIEB0aHJvd3MgTWFsZm9ybWVkVVJJRXhjZXB0aW9uIGlmIFVSSSBkb2VzIG5vdCBoYXZlIGEgY29uZm9ybWFudAotICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2hlbWUKLSAgICovCi0gIHByaXZhdGUgdm9pZCBpbml0aWFsaXplU2NoZW1lKFN0cmluZyBwX3VyaVNwZWMpIHRocm93cyBNYWxmb3JtZWRVUklFeGNlcHRpb24KLSAgewotCi0gICAgaW50IHVyaVNwZWNMZW4gPSBwX3VyaVNwZWMubGVuZ3RoKCk7Ci0gICAgaW50IGluZGV4ID0gMDsKLSAgICBTdHJpbmcgc2NoZW1lID0gbnVsbDsKLSAgICBjaGFyIHRlc3RDaGFyID0gJ1wwJzsKLQotICAgIHdoaWxlIChpbmRleCA8IHVyaVNwZWNMZW4pCi0gICAgewotICAgICAgdGVzdENoYXIgPSBwX3VyaVNwZWMuY2hhckF0KGluZGV4KTsKLQotICAgICAgaWYgKHRlc3RDaGFyID09ICc6JyB8fCB0ZXN0Q2hhciA9PSAnLycgfHwgdGVzdENoYXIgPT0gJz8nCi0gICAgICAgICAgICAgIHx8IHRlc3RDaGFyID09ICcjJykKLSAgICAgIHsKLSAgICAgICAgYnJlYWs7Ci0gICAgICB9Ci0KLSAgICAgIGluZGV4Kys7Ci0gICAgfQotCi0gICAgc2NoZW1lID0gcF91cmlTcGVjLnN1YnN0cmluZygwLCBpbmRleCk7Ci0KLSAgICBpZiAoc2NoZW1lLmxlbmd0aCgpID09IDApCi0gICAgewotICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVSSUV4Y2VwdGlvbihVdGlscy5tZXNzYWdlcy5jcmVhdGVNZXNzYWdlKE1zZ0tleS5FUl9OT19TQ0hFTUVfSU5VUkksIG51bGwpKTsgLy8iTm8gc2NoZW1lIGZvdW5kIGluIFVSSS4iKTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIHNldFNjaGVtZShzY2hlbWUpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBJbml0aWFsaXplIHRoZSBhdXRob3JpdHkgKHVzZXJpbmZvLCBob3N0IGFuZCBwb3J0KSBmb3IgdGhpcwotICAgKiBVUkkgZnJvbSBhIFVSSSBzdHJpbmcgc3BlYy4KLSAgICoKLSAgICogQHBhcmFtIHBfdXJpU3BlYyB0aGUgVVJJIHNwZWNpZmljYXRpb24gKGNhbm5vdCBiZSBudWxsKQotICAgKgotICAgKiBAdGhyb3dzIE1hbGZvcm1lZFVSSUV4Y2VwdGlvbiBpZiBwX3VyaVNwZWMgdmlvbGF0ZXMgc3ludGF4IHJ1bGVzCi0gICAqLwotICBwcml2YXRlIHZvaWQgaW5pdGlhbGl6ZUF1dGhvcml0eShTdHJpbmcgcF91cmlTcGVjKQotICAgICAgICAgIHRocm93cyBNYWxmb3JtZWRVUklFeGNlcHRpb24KLSAgewotCi0gICAgaW50IGluZGV4ID0gMDsKLSAgICBpbnQgc3RhcnQgPSAwOwotICAgIGludCBlbmQgPSBwX3VyaVNwZWMubGVuZ3RoKCk7Ci0gICAgY2hhciB0ZXN0Q2hhciA9ICdcMCc7Ci0gICAgU3RyaW5nIHVzZXJpbmZvID0gbnVsbDsKLQotICAgIC8vIHVzZXJpbmZvIGlzIGV2ZXJ5dGhpbmcgdXAgQAotICAgIGlmIChwX3VyaVNwZWMuaW5kZXhPZignQCcsIHN0YXJ0KSAhPSAtMSkKLSAgICB7Ci0gICAgICB3aGlsZSAoaW5kZXggPCBlbmQpCi0gICAgICB7Ci0gICAgICAgIHRlc3RDaGFyID0gcF91cmlTcGVjLmNoYXJBdChpbmRleCk7Ci0KLSAgICAgICAgaWYgKHRlc3RDaGFyID09ICdAJykKLSAgICAgICAgewotICAgICAgICAgIGJyZWFrOwotICAgICAgICB9Ci0KLSAgICAgICAgaW5kZXgrKzsKLSAgICAgIH0KLQotICAgICAgdXNlcmluZm8gPSBwX3VyaVNwZWMuc3Vic3RyaW5nKHN0YXJ0LCBpbmRleCk7Ci0KLSAgICAgIGluZGV4Kys7Ci0gICAgfQotCi0gICAgLy8gaG9zdCBpcyBldmVyeXRoaW5nIHVwIHRvICc6JwotICAgIFN0cmluZyBob3N0ID0gbnVsbDsKLQotICAgIHN0YXJ0ID0gaW5kZXg7Ci0KLSAgICB3aGlsZSAoaW5kZXggPCBlbmQpCi0gICAgewotICAgICAgdGVzdENoYXIgPSBwX3VyaVNwZWMuY2hhckF0KGluZGV4KTsKLQotICAgICAgaWYgKHRlc3RDaGFyID09ICc6JykKLSAgICAgIHsKLSAgICAgICAgYnJlYWs7Ci0gICAgICB9Ci0KLSAgICAgIGluZGV4Kys7Ci0gICAgfQotCi0gICAgaG9zdCA9IHBfdXJpU3BlYy5zdWJzdHJpbmcoc3RhcnQsIGluZGV4KTsKLQotICAgIGludCBwb3J0ID0gLTE7Ci0KLSAgICBpZiAoaG9zdC5sZW5ndGgoKSA+IDApCi0gICAgewotCi0gICAgICAvLyBwb3J0Ci0gICAgICBpZiAodGVzdENoYXIgPT0gJzonKQotICAgICAgewotICAgICAgICBpbmRleCsrOwotCi0gICAgICAgIHN0YXJ0ID0gaW5kZXg7Ci0KLSAgICAgICAgd2hpbGUgKGluZGV4IDwgZW5kKQotICAgICAgICB7Ci0gICAgICAgICAgaW5kZXgrKzsKLSAgICAgICAgfQotCi0gICAgICAgIFN0cmluZyBwb3J0U3RyID0gcF91cmlTcGVjLnN1YnN0cmluZyhzdGFydCwgaW5kZXgpOwotCi0gICAgICAgIGlmIChwb3J0U3RyLmxlbmd0aCgpID4gMCkKLSAgICAgICAgewotICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcG9ydFN0ci5sZW5ndGgoKTsgaSsrKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGlmICghaXNEaWdpdChwb3J0U3RyLmNoYXJBdChpKSkpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVUklFeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgcG9ydFN0ciArICIgaXMgaW52YWxpZC4gUG9ydCBzaG91bGQgb25seSBjb250YWluIGRpZ2l0cyEiKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICB9Ci0KLSAgICAgICAgICB0cnkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBwb3J0ID0gSW50ZWdlci5wYXJzZUludChwb3J0U3RyKTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBuZmUpCi0gICAgICAgICAgewotCi0gICAgICAgICAgICAvLyBjYW4ndCBoYXBwZW4KLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICB9Ci0KLSAgICBzZXRIb3N0KGhvc3QpOwotICAgIHNldFBvcnQocG9ydCk7Ci0gICAgc2V0VXNlcmluZm8odXNlcmluZm8pOwotICB9Ci0KLSAgLyoqCi0gICAqIEluaXRpYWxpemUgdGhlIHBhdGggZm9yIHRoaXMgVVJJIGZyb20gYSBVUkkgc3RyaW5nIHNwZWMuCi0gICAqCi0gICAqIEBwYXJhbSBwX3VyaVNwZWMgdGhlIFVSSSBzcGVjaWZpY2F0aW9uIChjYW5ub3QgYmUgbnVsbCkKLSAgICoKLSAgICogQHRocm93cyBNYWxmb3JtZWRVUklFeGNlcHRpb24gaWYgcF91cmlTcGVjIHZpb2xhdGVzIHN5bnRheCBydWxlcwotICAgKi8KLSAgcHJpdmF0ZSB2b2lkIGluaXRpYWxpemVQYXRoKFN0cmluZyBwX3VyaVNwZWMpIHRocm93cyBNYWxmb3JtZWRVUklFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKHBfdXJpU3BlYyA9PSBudWxsKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVUklFeGNlcHRpb24oCi0gICAgICAgICJDYW5ub3QgaW5pdGlhbGl6ZSBwYXRoIGZyb20gbnVsbCBzdHJpbmchIik7Ci0gICAgfQotCi0gICAgaW50IGluZGV4ID0gMDsKLSAgICBpbnQgc3RhcnQgPSAwOwotICAgIGludCBlbmQgPSBwX3VyaVNwZWMubGVuZ3RoKCk7Ci0gICAgY2hhciB0ZXN0Q2hhciA9ICdcMCc7Ci0KLSAgICAvLyBwYXRoIC0gZXZlcnl0aGluZyB1cCB0byBxdWVyeSBzdHJpbmcgb3IgZnJhZ21lbnQKLSAgICB3aGlsZSAoaW5kZXggPCBlbmQpCi0gICAgewotICAgICAgdGVzdENoYXIgPSBwX3VyaVNwZWMuY2hhckF0KGluZGV4KTsKLQotICAgICAgaWYgKHRlc3RDaGFyID09ICc/JyB8fCB0ZXN0Q2hhciA9PSAnIycpCi0gICAgICB7Ci0gICAgICAgIGJyZWFrOwotICAgICAgfQotCi0gICAgICAvLyBjaGVjayBmb3IgdmFsaWQgZXNjYXBlIHNlcXVlbmNlCi0gICAgICBpZiAodGVzdENoYXIgPT0gJyUnKQotICAgICAgewotICAgICAgICBpZiAoaW5kZXggKyAyID49IGVuZCB8fCFpc0hleChwX3VyaVNwZWMuY2hhckF0KGluZGV4ICsgMSkpCi0gICAgICAgICAgICAgICAgfHwhaXNIZXgocF91cmlTcGVjLmNoYXJBdChpbmRleCArIDIpKSkKLSAgICAgICAgewotICAgICAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVUklFeGNlcHRpb24oCi0gICAgICAgICAgICBVdGlscy5tZXNzYWdlcy5jcmVhdGVNZXNzYWdlKE1zZ0tleS5FUl9QQVRIX0NPTlRBSU5TX0lOVkFMSURfRVNDQVBFX1NFUVVFTkNFLCBudWxsKSk7IC8vIlBhdGggY29udGFpbnMgaW52YWxpZCBlc2NhcGUgc2VxdWVuY2UhIik7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICAgIGVsc2UgaWYgKCFpc1Jlc2VydmVkQ2hhcmFjdGVyKHRlc3RDaGFyKQotICAgICAgICAgICAgICAgJiYhaXNVbnJlc2VydmVkQ2hhcmFjdGVyKHRlc3RDaGFyKSkKLSAgICAgIHsKLSAgICAgICAgaWYgKCdcXCcgIT0gdGVzdENoYXIpCi0gICAgICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVSSUV4Y2VwdGlvbihVdGlscy5tZXNzYWdlcy5jcmVhdGVNZXNzYWdlKE1zZ0tleS5FUl9QQVRIX0lOVkFMSURfQ0hBUiwgbmV3IE9iamVjdFtde1N0cmluZy52YWx1ZU9mKHRlc3RDaGFyKX0pKTsgLy8iUGF0aCBjb250YWlucyBpbnZhbGlkIGNoYXJhY3RlcjogIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8rIHRlc3RDaGFyKTsKLSAgICAgIH0KLQotICAgICAgaW5kZXgrKzsKLSAgICB9Ci0KLSAgICBtX3BhdGggPSBwX3VyaVNwZWMuc3Vic3RyaW5nKHN0YXJ0LCBpbmRleCk7Ci0KLSAgICAvLyBxdWVyeSAtIHN0YXJ0cyB3aXRoID8gYW5kIHVwIHRvIGZyYWdtZW50IG9yIGVuZAotICAgIGlmICh0ZXN0Q2hhciA9PSAnPycpCi0gICAgewotICAgICAgaW5kZXgrKzsKLQotICAgICAgc3RhcnQgPSBpbmRleDsKLQotICAgICAgd2hpbGUgKGluZGV4IDwgZW5kKQotICAgICAgewotICAgICAgICB0ZXN0Q2hhciA9IHBfdXJpU3BlYy5jaGFyQXQoaW5kZXgpOwotCi0gICAgICAgIGlmICh0ZXN0Q2hhciA9PSAnIycpCi0gICAgICAgIHsKLSAgICAgICAgICBicmVhazsKLSAgICAgICAgfQotCi0gICAgICAgIGlmICh0ZXN0Q2hhciA9PSAnJScpCi0gICAgICAgIHsKLSAgICAgICAgICBpZiAoaW5kZXggKyAyID49IGVuZCB8fCFpc0hleChwX3VyaVNwZWMuY2hhckF0KGluZGV4ICsgMSkpCi0gICAgICAgICAgICAgICAgICB8fCFpc0hleChwX3VyaVNwZWMuY2hhckF0KGluZGV4ICsgMikpKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVUklFeGNlcHRpb24oCi0gICAgICAgICAgICAgICJRdWVyeSBzdHJpbmcgY29udGFpbnMgaW52YWxpZCBlc2NhcGUgc2VxdWVuY2UhIik7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKCFpc1Jlc2VydmVkQ2hhcmFjdGVyKHRlc3RDaGFyKQotICAgICAgICAgICAgICAgICAmJiFpc1VucmVzZXJ2ZWRDaGFyYWN0ZXIodGVzdENoYXIpKQotICAgICAgICB7Ci0gICAgICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVSSUV4Y2VwdGlvbigKLSAgICAgICAgICAgICJRdWVyeSBzdHJpbmcgY29udGFpbnMgaW52YWxpZCBjaGFyYWN0ZXI6IiArIHRlc3RDaGFyKTsKLSAgICAgICAgfQotCi0gICAgICAgIGluZGV4Kys7Ci0gICAgICB9Ci0KLSAgICAgIG1fcXVlcnlTdHJpbmcgPSBwX3VyaVNwZWMuc3Vic3RyaW5nKHN0YXJ0LCBpbmRleCk7Ci0gICAgfQotCi0gICAgLy8gZnJhZ21lbnQgLSBzdGFydHMgd2l0aCAjCi0gICAgaWYgKHRlc3RDaGFyID09ICcjJykKLSAgICB7Ci0gICAgICBpbmRleCsrOwotCi0gICAgICBzdGFydCA9IGluZGV4OwotCi0gICAgICB3aGlsZSAoaW5kZXggPCBlbmQpCi0gICAgICB7Ci0gICAgICAgIHRlc3RDaGFyID0gcF91cmlTcGVjLmNoYXJBdChpbmRleCk7Ci0KLSAgICAgICAgaWYgKHRlc3RDaGFyID09ICclJykKLSAgICAgICAgewotICAgICAgICAgIGlmIChpbmRleCArIDIgPj0gZW5kIHx8IWlzSGV4KHBfdXJpU3BlYy5jaGFyQXQoaW5kZXggKyAxKSkKLSAgICAgICAgICAgICAgICAgIHx8IWlzSGV4KHBfdXJpU3BlYy5jaGFyQXQoaW5kZXggKyAyKSkpCi0gICAgICAgICAgewotICAgICAgICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVSSUV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgIkZyYWdtZW50IGNvbnRhaW5zIGludmFsaWQgZXNjYXBlIHNlcXVlbmNlISIpOwotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICghaXNSZXNlcnZlZENoYXJhY3Rlcih0ZXN0Q2hhcikKLSAgICAgICAgICAgICAgICAgJiYhaXNVbnJlc2VydmVkQ2hhcmFjdGVyKHRlc3RDaGFyKSkKLSAgICAgICAgewotICAgICAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVUklFeGNlcHRpb24oCi0gICAgICAgICAgICAiRnJhZ21lbnQgY29udGFpbnMgaW52YWxpZCBjaGFyYWN0ZXI6IiArIHRlc3RDaGFyKTsKLSAgICAgICAgfQotCi0gICAgICAgIGluZGV4Kys7Ci0gICAgICB9Ci0KLSAgICAgIG1fZnJhZ21lbnQgPSBwX3VyaVNwZWMuc3Vic3RyaW5nKHN0YXJ0LCBpbmRleCk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgc2NoZW1lIGZvciB0aGlzIFVSSS4KLSAgICoKLSAgICogQHJldHVybiB0aGUgc2NoZW1lIGZvciB0aGlzIFVSSQotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRTY2hlbWUoKQotICB7Ci0gICAgcmV0dXJuIG1fc2NoZW1lOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgc2NoZW1lLXNwZWNpZmljIHBhcnQgZm9yIHRoaXMgVVJJIChldmVyeXRoaW5nIGZvbGxvd2luZyB0aGUKLSAgICogc2NoZW1lIGFuZCB0aGUgZmlyc3QgY29sb24pLiBTZWUgUkZDIDIzOTYgU2VjdGlvbiA1LjIgZm9yIHNwZWMuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIHNjaGVtZS1zcGVjaWZpYyBwYXJ0IGZvciB0aGlzIFVSSQotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRTY2hlbWVTcGVjaWZpY1BhcnQoKQotICB7Ci0KLSAgICBmaW5hbCBTdHJpbmdCdWlsZGVyIHNjaGVtZXNwZWMgPSBuZXcgU3RyaW5nQnVpbGRlcigpOwotCi0gICAgaWYgKG1fdXNlcmluZm8gIT0gbnVsbCB8fCBtX2hvc3QgIT0gbnVsbCB8fCBtX3BvcnQgIT0gLTEpCi0gICAgewotICAgICAgc2NoZW1lc3BlYy5hcHBlbmQoIi8vIik7Ci0gICAgfQotCi0gICAgaWYgKG1fdXNlcmluZm8gIT0gbnVsbCkKLSAgICB7Ci0gICAgICBzY2hlbWVzcGVjLmFwcGVuZChtX3VzZXJpbmZvKTsKLSAgICAgIHNjaGVtZXNwZWMuYXBwZW5kKCdAJyk7Ci0gICAgfQotCi0gICAgaWYgKG1faG9zdCAhPSBudWxsKQotICAgIHsKLSAgICAgIHNjaGVtZXNwZWMuYXBwZW5kKG1faG9zdCk7Ci0gICAgfQotCi0gICAgaWYgKG1fcG9ydCAhPSAtMSkKLSAgICB7Ci0gICAgICBzY2hlbWVzcGVjLmFwcGVuZCgnOicpOwotICAgICAgc2NoZW1lc3BlYy5hcHBlbmQobV9wb3J0KTsKLSAgICB9Ci0KLSAgICBpZiAobV9wYXRoICE9IG51bGwpCi0gICAgewotICAgICAgc2NoZW1lc3BlYy5hcHBlbmQoKG1fcGF0aCkpOwotICAgIH0KLQotICAgIGlmIChtX3F1ZXJ5U3RyaW5nICE9IG51bGwpCi0gICAgewotICAgICAgc2NoZW1lc3BlYy5hcHBlbmQoJz8nKTsKLSAgICAgIHNjaGVtZXNwZWMuYXBwZW5kKG1fcXVlcnlTdHJpbmcpOwotICAgIH0KLQotICAgIGlmIChtX2ZyYWdtZW50ICE9IG51bGwpCi0gICAgewotICAgICAgc2NoZW1lc3BlYy5hcHBlbmQoJyMnKTsKLSAgICAgIHNjaGVtZXNwZWMuYXBwZW5kKG1fZnJhZ21lbnQpOwotICAgIH0KLQotICAgIHJldHVybiBzY2hlbWVzcGVjLnRvU3RyaW5nKCk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSB1c2VyaW5mbyBmb3IgdGhpcyBVUkkuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIHVzZXJpbmZvIGZvciB0aGlzIFVSSSAobnVsbCBpZiBub3Qgc3BlY2lmaWVkKS4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0VXNlcmluZm8oKQotICB7Ci0gICAgcmV0dXJuIG1fdXNlcmluZm87Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBob3N0IGZvciB0aGlzIFVSSS4KLSAgICoKLSAgICogQHJldHVybiB0aGUgaG9zdCBmb3IgdGhpcyBVUkkgKG51bGwgaWYgbm90IHNwZWNpZmllZCkuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldEhvc3QoKQotICB7Ci0gICAgcmV0dXJuIG1faG9zdDsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIHBvcnQgZm9yIHRoaXMgVVJJLgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBwb3J0IGZvciB0aGlzIFVSSSAoLTEgaWYgbm90IHNwZWNpZmllZCkuCi0gICAqLwotICBwdWJsaWMgaW50IGdldFBvcnQoKQotICB7Ci0gICAgcmV0dXJuIG1fcG9ydDsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIHBhdGggZm9yIHRoaXMgVVJJIChvcHRpb25hbGx5IHdpdGggdGhlIHF1ZXJ5IHN0cmluZyBhbmQKLSAgICogZnJhZ21lbnQpLgotICAgKgotICAgKiBAcGFyYW0gcF9pbmNsdWRlUXVlcnlTdHJpbmcgaWYgdHJ1ZSAoYW5kIHF1ZXJ5IHN0cmluZyBpcyBub3QgbnVsbCksCi0gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGEgIj8iIGZvbGxvd2VkIGJ5IHRoZSBxdWVyeSBzdHJpbmcKLSAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpbGwgYmUgYXBwZW5kZWQKLSAgICogQHBhcmFtIHBfaW5jbHVkZUZyYWdtZW50IGlmIHRydWUgKGFuZCBmcmFnbWVudCBpcyBub3QgbnVsbCksCi0gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGEgIiMiIGZvbGxvd2VkIGJ5IHRoZSBmcmFnbWVudAotICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lsbCBiZSBhcHBlbmRlZAotICAgKgotICAgKiBAcmV0dXJuIHRoZSBwYXRoIGZvciB0aGlzIFVSSSBwb3NzaWJseSBpbmNsdWRpbmcgdGhlIHF1ZXJ5IHN0cmluZwotICAgKiAgICAgICAgIGFuZCBmcmFnbWVudAotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRQYXRoKGJvb2xlYW4gcF9pbmNsdWRlUXVlcnlTdHJpbmcsCi0gICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIHBfaW5jbHVkZUZyYWdtZW50KQotICB7Ci0KLSAgICBmaW5hbCBTdHJpbmdCdWlsZGVyIHBhdGhTdHJpbmcgPSBuZXcgU3RyaW5nQnVpbGRlcihtX3BhdGgpOwotCi0gICAgaWYgKHBfaW5jbHVkZVF1ZXJ5U3RyaW5nICYmIG1fcXVlcnlTdHJpbmcgIT0gbnVsbCkKLSAgICB7Ci0gICAgICBwYXRoU3RyaW5nLmFwcGVuZCgnPycpOwotICAgICAgcGF0aFN0cmluZy5hcHBlbmQobV9xdWVyeVN0cmluZyk7Ci0gICAgfQotCi0gICAgaWYgKHBfaW5jbHVkZUZyYWdtZW50ICYmIG1fZnJhZ21lbnQgIT0gbnVsbCkKLSAgICB7Ci0gICAgICBwYXRoU3RyaW5nLmFwcGVuZCgnIycpOwotICAgICAgcGF0aFN0cmluZy5hcHBlbmQobV9mcmFnbWVudCk7Ci0gICAgfQotCi0gICAgcmV0dXJuIHBhdGhTdHJpbmcudG9TdHJpbmcoKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIHBhdGggZm9yIHRoaXMgVVJJLiBOb3RlIHRoYXQgdGhlIHZhbHVlIHJldHVybmVkIGlzIHRoZSBwYXRoCi0gICAqIG9ubHkgYW5kIGRvZXMgbm90IGluY2x1ZGUgdGhlIHF1ZXJ5IHN0cmluZyBvciBmcmFnbWVudC4KLSAgICoKLSAgICogQHJldHVybiB0aGUgcGF0aCBmb3IgdGhpcyBVUkkuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFBhdGgoKQotICB7Ci0gICAgcmV0dXJuIG1fcGF0aDsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIHF1ZXJ5IHN0cmluZyBmb3IgdGhpcyBVUkkuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIHF1ZXJ5IHN0cmluZyBmb3IgdGhpcyBVUkkuIE51bGwgaXMgcmV0dXJuZWQgaWYgdGhlcmUKLSAgICogICAgICAgICB3YXMgbm8gIj8iIGluIHRoZSBVUkkgc3BlYywgZW1wdHkgc3RyaW5nIGlmIHRoZXJlIHdhcyBhCi0gICAqICAgICAgICAgIj8iIGJ1dCBubyBxdWVyeSBzdHJpbmcgZm9sbG93aW5nIGl0LgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRRdWVyeVN0cmluZygpCi0gIHsKLSAgICByZXR1cm4gbV9xdWVyeVN0cmluZzsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGZyYWdtZW50IGZvciB0aGlzIFVSSS4KLSAgICoKLSAgICogQHJldHVybiB0aGUgZnJhZ21lbnQgZm9yIHRoaXMgVVJJLiBOdWxsIGlzIHJldHVybmVkIGlmIHRoZXJlCi0gICAqICAgICAgICAgd2FzIG5vICIjIiBpbiB0aGUgVVJJIHNwZWMsIGVtcHR5IHN0cmluZyBpZiB0aGVyZSB3YXMgYQotICAgKiAgICAgICAgICIjIiBidXQgbm8gZnJhZ21lbnQgZm9sbG93aW5nIGl0LgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRGcmFnbWVudCgpCi0gIHsKLSAgICByZXR1cm4gbV9mcmFnbWVudDsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIHNjaGVtZSBmb3IgdGhpcyBVUkkuIFRoZSBzY2hlbWUgaXMgY29udmVydGVkIHRvIGxvd2VyY2FzZQotICAgKiBiZWZvcmUgaXQgaXMgc2V0LgotICAgKgotICAgKiBAcGFyYW0gcF9zY2hlbWUgdGhlIHNjaGVtZSBmb3IgdGhpcyBVUkkgKGNhbm5vdCBiZSBudWxsKQotICAgKgotICAgKiBAdGhyb3dzIE1hbGZvcm1lZFVSSUV4Y2VwdGlvbiBpZiBwX3NjaGVtZSBpcyBub3QgYSBjb25mb3JtYW50Ci0gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjaGVtZSBuYW1lCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRTY2hlbWUoU3RyaW5nIHBfc2NoZW1lKSB0aHJvd3MgTWFsZm9ybWVkVVJJRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChwX3NjaGVtZSA9PSBudWxsKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVUklFeGNlcHRpb24oVXRpbHMubWVzc2FnZXMuY3JlYXRlTWVzc2FnZShNc2dLZXkuRVJfU0NIRU1FX0ZST01fTlVMTF9TVFJJTkcsIG51bGwpKTsgLy8iQ2Fubm90IHNldCBzY2hlbWUgZnJvbSBudWxsIHN0cmluZyEiKTsKLSAgICB9Ci0KLSAgICBpZiAoIWlzQ29uZm9ybWFudFNjaGVtZU5hbWUocF9zY2hlbWUpKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVUklFeGNlcHRpb24oVXRpbHMubWVzc2FnZXMuY3JlYXRlTWVzc2FnZShNc2dLZXkuRVJfU0NIRU1FX05PVF9DT05GT1JNQU5ULCBudWxsKSk7IC8vIlRoZSBzY2hlbWUgaXMgbm90IGNvbmZvcm1hbnQuIik7Ci0gICAgfQotCi0gICAgbV9zY2hlbWUgPSBwX3NjaGVtZS50b0xvd2VyQ2FzZSgpOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgdXNlcmluZm8gZm9yIHRoaXMgVVJJLiBJZiBhIG5vbi1udWxsIHZhbHVlIGlzIHBhc3NlZCBpbiBhbmQKLSAgICogdGhlIGhvc3QgdmFsdWUgaXMgbnVsbCwgdGhlbiBhbiBleGNlcHRpb24gaXMgdGhyb3duLgotICAgKgotICAgKiBAcGFyYW0gcF91c2VyaW5mbyB0aGUgdXNlcmluZm8gZm9yIHRoaXMgVVJJCi0gICAqCi0gICAqIEB0aHJvd3MgTWFsZm9ybWVkVVJJRXhjZXB0aW9uIGlmIHBfdXNlcmluZm8gY29udGFpbnMgaW52YWxpZAotICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFyYWN0ZXJzCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRVc2VyaW5mbyhTdHJpbmcgcF91c2VyaW5mbykgdGhyb3dzIE1hbGZvcm1lZFVSSUV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAocF91c2VyaW5mbyA9PSBudWxsKQotICAgIHsKLSAgICAgIG1fdXNlcmluZm8gPSBudWxsOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgaWYgKG1faG9zdCA9PSBudWxsKQotICAgICAgewotICAgICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVVJJRXhjZXB0aW9uKAotICAgICAgICAgICJVc2VyaW5mbyBjYW5ub3QgYmUgc2V0IHdoZW4gaG9zdCBpcyBudWxsISIpOwotICAgICAgfQotCi0gICAgICAvLyB1c2VyaW5mbyBjYW4gY29udGFpbiBhbHBoYW51bWVyaWNzLCBtYXJrIGNoYXJhY3RlcnMsIGVzY2FwZWQKLSAgICAgIC8vIGFuZCAnOycsJzonLCcmJywnPScsJysnLCckJywnLCcKLSAgICAgIGludCBpbmRleCA9IDA7Ci0gICAgICBpbnQgZW5kID0gcF91c2VyaW5mby5sZW5ndGgoKTsKLSAgICAgIGNoYXIgdGVzdENoYXIgPSAnXDAnOwotCi0gICAgICB3aGlsZSAoaW5kZXggPCBlbmQpCi0gICAgICB7Ci0gICAgICAgIHRlc3RDaGFyID0gcF91c2VyaW5mby5jaGFyQXQoaW5kZXgpOwotCi0gICAgICAgIGlmICh0ZXN0Q2hhciA9PSAnJScpCi0gICAgICAgIHsKLSAgICAgICAgICBpZiAoaW5kZXggKyAyID49IGVuZCB8fCFpc0hleChwX3VzZXJpbmZvLmNoYXJBdChpbmRleCArIDEpKQotICAgICAgICAgICAgICAgICAgfHwhaXNIZXgocF91c2VyaW5mby5jaGFyQXQoaW5kZXggKyAyKSkpCi0gICAgICAgICAgewotICAgICAgICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVSSUV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgIlVzZXJpbmZvIGNvbnRhaW5zIGludmFsaWQgZXNjYXBlIHNlcXVlbmNlISIpOwotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICghaXNVbnJlc2VydmVkQ2hhcmFjdGVyKHRlc3RDaGFyKQotICAgICAgICAgICAgICAgICAmJiBVU0VSSU5GT19DSEFSQUNURVJTLmluZGV4T2YodGVzdENoYXIpID09IC0xKQotICAgICAgICB7Ci0gICAgICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVSSUV4Y2VwdGlvbigKLSAgICAgICAgICAgICJVc2VyaW5mbyBjb250YWlucyBpbnZhbGlkIGNoYXJhY3RlcjoiICsgdGVzdENoYXIpOwotICAgICAgICB9Ci0KLSAgICAgICAgaW5kZXgrKzsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICBtX3VzZXJpbmZvID0gcF91c2VyaW5mbzsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIGhvc3QgZm9yIHRoaXMgVVJJLiBJZiBudWxsIGlzIHBhc3NlZCBpbiwgdGhlIHVzZXJpbmZvCi0gICAqIGZpZWxkIGlzIGFsc28gc2V0IHRvIG51bGwgYW5kIHRoZSBwb3J0IGlzIHNldCB0byAtMS4KLSAgICoKLSAgICogQHBhcmFtIHBfaG9zdCB0aGUgaG9zdCBmb3IgdGhpcyBVUkkKLSAgICoKLSAgICogQHRocm93cyBNYWxmb3JtZWRVUklFeGNlcHRpb24gaWYgcF9ob3N0IGlzIG5vdCBhIHZhbGlkIElQCi0gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZHJlc3Mgb3IgRE5TIGhvc3RuYW1lLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0SG9zdChTdHJpbmcgcF9ob3N0KSB0aHJvd3MgTWFsZm9ybWVkVVJJRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChwX2hvc3QgPT0gbnVsbCB8fCBwX2hvc3QudHJpbSgpLmxlbmd0aCgpID09IDApCi0gICAgewotICAgICAgbV9ob3N0ID0gcF9ob3N0OwotICAgICAgbV91c2VyaW5mbyA9IG51bGw7Ci0gICAgICBtX3BvcnQgPSAtMTsKLSAgICB9Ci0gICAgZWxzZSBpZiAoIWlzV2VsbEZvcm1lZEFkZHJlc3MocF9ob3N0KSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVVJJRXhjZXB0aW9uKFV0aWxzLm1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoTXNnS2V5LkVSX0hPU1RfQUREUkVTU19OT1RfV0VMTEZPUk1FRCwgbnVsbCkpOyAvLyJIb3N0IGlzIG5vdCBhIHdlbGwgZm9ybWVkIGFkZHJlc3MhIik7Ci0gICAgfQotCi0gICAgbV9ob3N0ID0gcF9ob3N0OwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgcG9ydCBmb3IgdGhpcyBVUkkuIC0xIGlzIHVzZWQgdG8gaW5kaWNhdGUgdGhhdCB0aGUgcG9ydCBpcwotICAgKiBub3Qgc3BlY2lmaWVkLCBvdGhlcndpc2UgdmFsaWQgcG9ydCBudW1iZXJzIGFyZSAgYmV0d2VlbiAwIGFuZCA2NTUzNS4KLSAgICogSWYgYSB2YWxpZCBwb3J0IG51bWJlciBpcyBwYXNzZWQgaW4gYW5kIHRoZSBob3N0IGZpZWxkIGlzIG51bGwsCi0gICAqIGFuIGV4Y2VwdGlvbiBpcyB0aHJvd24uCi0gICAqCi0gICAqIEBwYXJhbSBwX3BvcnQgdGhlIHBvcnQgbnVtYmVyIGZvciB0aGlzIFVSSQotICAgKgotICAgKiBAdGhyb3dzIE1hbGZvcm1lZFVSSUV4Y2VwdGlvbiBpZiBwX3BvcnQgaXMgbm90IC0xIGFuZCBub3QgYQotICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWxpZCBwb3J0IG51bWJlcgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0UG9ydChpbnQgcF9wb3J0KSB0aHJvd3MgTWFsZm9ybWVkVVJJRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChwX3BvcnQgPj0gMCAmJiBwX3BvcnQgPD0gNjU1MzUpCi0gICAgewotICAgICAgaWYgKG1faG9zdCA9PSBudWxsKQotICAgICAgewotICAgICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVVJJRXhjZXB0aW9uKAotICAgICAgICAgIFV0aWxzLm1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoTXNnS2V5LkVSX1BPUlRfV0hFTl9IT1NUX05VTEwsIG51bGwpKTsgLy8iUG9ydCBjYW5ub3QgYmUgc2V0IHdoZW4gaG9zdCBpcyBudWxsISIpOwotICAgICAgfQotICAgIH0KLSAgICBlbHNlIGlmIChwX3BvcnQgIT0gLTEpCi0gICAgewotICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVSSUV4Y2VwdGlvbihVdGlscy5tZXNzYWdlcy5jcmVhdGVNZXNzYWdlKE1zZ0tleS5FUl9JTlZBTElEX1BPUlQsIG51bGwpKTsgLy8iSW52YWxpZCBwb3J0IG51bWJlciEiKTsKLSAgICB9Ci0KLSAgICBtX3BvcnQgPSBwX3BvcnQ7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBwYXRoIGZvciB0aGlzIFVSSS4gSWYgdGhlIHN1cHBsaWVkIHBhdGggaXMgbnVsbCwgdGhlbiB0aGUKLSAgICogcXVlcnkgc3RyaW5nIGFuZCBmcmFnbWVudCBhcmUgc2V0IHRvIG51bGwgYXMgd2VsbC4gSWYgdGhlIHN1cHBsaWVkCi0gICAqIHBhdGggaW5jbHVkZXMgYSBxdWVyeSBzdHJpbmcgYW5kL29yIGZyYWdtZW50LCB0aGVzZSBmaWVsZHMgd2lsbCBiZQotICAgKiBwYXJzZWQgYW5kIHNldCBhcyB3ZWxsLiBOb3RlIHRoYXQsIGZvciBVUklzIGZvbGxvd2luZyB0aGUgImdlbmVyaWMKLSAgICogVVJJIiBzeW50YXgsIHRoZSBwYXRoIHNwZWNpZmllZCBzaG91bGQgc3RhcnQgd2l0aCBhIHNsYXNoLgotICAgKiBGb3IgVVJJcyB0aGF0IGRvIG5vdCBmb2xsb3cgdGhlIGdlbmVyaWMgVVJJIHN5bnRheCwgdGhpcyBtZXRob2QKLSAgICogc2V0cyB0aGUgc2NoZW1lLXNwZWNpZmljIHBhcnQuCi0gICAqCi0gICAqIEBwYXJhbSBwX3BhdGggdGhlIHBhdGggZm9yIHRoaXMgVVJJIChtYXkgYmUgbnVsbCkKLSAgICoKLSAgICogQHRocm93cyBNYWxmb3JtZWRVUklFeGNlcHRpb24gaWYgcF9wYXRoIGNvbnRhaW5zIGludmFsaWQKLSAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhcmFjdGVycwotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0UGF0aChTdHJpbmcgcF9wYXRoKSB0aHJvd3MgTWFsZm9ybWVkVVJJRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChwX3BhdGggPT0gbnVsbCkKLSAgICB7Ci0gICAgICBtX3BhdGggPSBudWxsOwotICAgICAgbV9xdWVyeVN0cmluZyA9IG51bGw7Ci0gICAgICBtX2ZyYWdtZW50ID0gbnVsbDsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIGluaXRpYWxpemVQYXRoKHBfcGF0aCk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEFwcGVuZCB0byB0aGUgZW5kIG9mIHRoZSBwYXRoIG9mIHRoaXMgVVJJLiBJZiB0aGUgY3VycmVudCBwYXRoIGRvZXMKLSAgICogbm90IGVuZCBpbiBhIHNsYXNoIGFuZCB0aGUgcGF0aCB0byBiZSBhcHBlbmRlZCBkb2VzIG5vdCBiZWdpbiB3aXRoCi0gICAqIGEgc2xhc2gsIGEgc2xhc2ggd2lsbCBiZSBhcHBlbmRlZCB0byB0aGUgY3VycmVudCBwYXRoIGJlZm9yZSB0aGUKLSAgICogbmV3IHNlZ21lbnQgaXMgYWRkZWQuIEFsc28sIGlmIHRoZSBjdXJyZW50IHBhdGggZW5kcyBpbiBhIHNsYXNoCi0gICAqIGFuZCB0aGUgbmV3IHNlZ21lbnQgYmVnaW5zIHdpdGggYSBzbGFzaCwgdGhlIGV4dHJhIHNsYXNoIHdpbGwgYmUKLSAgICogcmVtb3ZlZCBiZWZvcmUgdGhlIG5ldyBzZWdtZW50IGlzIGFwcGVuZGVkLgotICAgKgotICAgKiBAcGFyYW0gcF9hZGRUb1BhdGggdGhlIG5ldyBzZWdtZW50IHRvIGJlIGFkZGVkIHRvIHRoZSBjdXJyZW50IHBhdGgKLSAgICoKLSAgICogQHRocm93cyBNYWxmb3JtZWRVUklFeGNlcHRpb24gaWYgcF9hZGRUb1BhdGggY29udGFpbnMgc3ludGF4Ci0gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9ycwotICAgKi8KLSAgcHVibGljIHZvaWQgYXBwZW5kUGF0aChTdHJpbmcgcF9hZGRUb1BhdGgpIHRocm93cyBNYWxmb3JtZWRVUklFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKHBfYWRkVG9QYXRoID09IG51bGwgfHwgcF9hZGRUb1BhdGgudHJpbSgpLmxlbmd0aCgpID09IDApCi0gICAgewotICAgICAgcmV0dXJuOwotICAgIH0KLQotICAgIGlmICghaXNVUklTdHJpbmcocF9hZGRUb1BhdGgpKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVUklFeGNlcHRpb24oVXRpbHMubWVzc2FnZXMuY3JlYXRlTWVzc2FnZShNc2dLZXkuRVJfUEFUSF9JTlZBTElEX0NIQVIsIG5ldyBPYmplY3RbXXtwX2FkZFRvUGF0aH0pKTsgLy8iUGF0aCBjb250YWlucyBpbnZhbGlkIGNoYXJhY3RlciEiKTsKLSAgICB9Ci0KLSAgICBpZiAobV9wYXRoID09IG51bGwgfHwgbV9wYXRoLnRyaW0oKS5sZW5ndGgoKSA9PSAwKQotICAgIHsKLSAgICAgIGlmIChwX2FkZFRvUGF0aC5zdGFydHNXaXRoKCIvIikpCi0gICAgICB7Ci0gICAgICAgIG1fcGF0aCA9IHBfYWRkVG9QYXRoOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBtX3BhdGggPSAiLyIgKyBwX2FkZFRvUGF0aDsKLSAgICAgIH0KLSAgICB9Ci0gICAgZWxzZSBpZiAobV9wYXRoLmVuZHNXaXRoKCIvIikpCi0gICAgewotICAgICAgaWYgKHBfYWRkVG9QYXRoLnN0YXJ0c1dpdGgoIi8iKSkKLSAgICAgIHsKLSAgICAgICAgbV9wYXRoID0gbV9wYXRoLmNvbmNhdChwX2FkZFRvUGF0aC5zdWJzdHJpbmcoMSkpOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBtX3BhdGggPSBtX3BhdGguY29uY2F0KHBfYWRkVG9QYXRoKTsKLSAgICAgIH0KLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIGlmIChwX2FkZFRvUGF0aC5zdGFydHNXaXRoKCIvIikpCi0gICAgICB7Ci0gICAgICAgIG1fcGF0aCA9IG1fcGF0aC5jb25jYXQocF9hZGRUb1BhdGgpOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBtX3BhdGggPSBtX3BhdGguY29uY2F0KCIvIiArIHBfYWRkVG9QYXRoKTsKLSAgICAgIH0KLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBxdWVyeSBzdHJpbmcgZm9yIHRoaXMgVVJJLiBBIG5vbi1udWxsIHZhbHVlIGlzIHZhbGlkIG9ubHkKLSAgICogaWYgdGhpcyBpcyBhbiBVUkkgY29uZm9ybWluZyB0byB0aGUgZ2VuZXJpYyBVUkkgc3ludGF4IGFuZAotICAgKiB0aGUgcGF0aCB2YWx1ZSBpcyBub3QgbnVsbC4KLSAgICoKLSAgICogQHBhcmFtIHBfcXVlcnlTdHJpbmcgdGhlIHF1ZXJ5IHN0cmluZyBmb3IgdGhpcyBVUkkKLSAgICoKLSAgICogQHRocm93cyBNYWxmb3JtZWRVUklFeGNlcHRpb24gaWYgcF9xdWVyeVN0cmluZyBpcyBub3QgbnVsbCBhbmQgdGhpcwotICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVUkkgZG9lcyBub3QgY29uZm9ybSB0byB0aGUgZ2VuZXJpYwotICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVUkkgc3ludGF4IG9yIGlmIHRoZSBwYXRoIGlzIG51bGwKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFF1ZXJ5U3RyaW5nKFN0cmluZyBwX3F1ZXJ5U3RyaW5nKQotICAgICAgICAgIHRocm93cyBNYWxmb3JtZWRVUklFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKHBfcXVlcnlTdHJpbmcgPT0gbnVsbCkKLSAgICB7Ci0gICAgICBtX3F1ZXJ5U3RyaW5nID0gbnVsbDsKLSAgICB9Ci0gICAgZWxzZSBpZiAoIWlzR2VuZXJpY1VSSSgpKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVUklFeGNlcHRpb24oCi0gICAgICAgICJRdWVyeSBzdHJpbmcgY2FuIG9ubHkgYmUgc2V0IGZvciBhIGdlbmVyaWMgVVJJISIpOwotICAgIH0KLSAgICBlbHNlIGlmIChnZXRQYXRoKCkgPT0gbnVsbCkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVVJJRXhjZXB0aW9uKAotICAgICAgICAiUXVlcnkgc3RyaW5nIGNhbm5vdCBiZSBzZXQgd2hlbiBwYXRoIGlzIG51bGwhIik7Ci0gICAgfQotICAgIGVsc2UgaWYgKCFpc1VSSVN0cmluZyhwX3F1ZXJ5U3RyaW5nKSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVVJJRXhjZXB0aW9uKAotICAgICAgICAiUXVlcnkgc3RyaW5nIGNvbnRhaW5zIGludmFsaWQgY2hhcmFjdGVyISIpOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgbV9xdWVyeVN0cmluZyA9IHBfcXVlcnlTdHJpbmc7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgZnJhZ21lbnQgZm9yIHRoaXMgVVJJLiBBIG5vbi1udWxsIHZhbHVlIGlzIHZhbGlkIG9ubHkKLSAgICogaWYgdGhpcyBpcyBhIFVSSSBjb25mb3JtaW5nIHRvIHRoZSBnZW5lcmljIFVSSSBzeW50YXggYW5kCi0gICAqIHRoZSBwYXRoIHZhbHVlIGlzIG5vdCBudWxsLgotICAgKgotICAgKiBAcGFyYW0gcF9mcmFnbWVudCB0aGUgZnJhZ21lbnQgZm9yIHRoaXMgVVJJCi0gICAqCi0gICAqIEB0aHJvd3MgTWFsZm9ybWVkVVJJRXhjZXB0aW9uIGlmIHBfZnJhZ21lbnQgaXMgbm90IG51bGwgYW5kIHRoaXMKLSAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVVJJIGRvZXMgbm90IGNvbmZvcm0gdG8gdGhlIGdlbmVyaWMKLSAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVVJJIHN5bnRheCBvciBpZiB0aGUgcGF0aCBpcyBudWxsCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRGcmFnbWVudChTdHJpbmcgcF9mcmFnbWVudCkgdGhyb3dzIE1hbGZvcm1lZFVSSUV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAocF9mcmFnbWVudCA9PSBudWxsKQotICAgIHsKLSAgICAgIG1fZnJhZ21lbnQgPSBudWxsOwotICAgIH0KLSAgICBlbHNlIGlmICghaXNHZW5lcmljVVJJKCkpCi0gICAgewotICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVSSUV4Y2VwdGlvbigKLSAgICAgICAgVXRpbHMubWVzc2FnZXMuY3JlYXRlTWVzc2FnZShNc2dLZXkuRVJfRlJBR19GT1JfR0VORVJJQ19VUkksIG51bGwpKTsgLy8iRnJhZ21lbnQgY2FuIG9ubHkgYmUgc2V0IGZvciBhIGdlbmVyaWMgVVJJISIpOwotICAgIH0KLSAgICBlbHNlIGlmIChnZXRQYXRoKCkgPT0gbnVsbCkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVVJJRXhjZXB0aW9uKAotICAgICAgICBVdGlscy5tZXNzYWdlcy5jcmVhdGVNZXNzYWdlKE1zZ0tleS5FUl9GUkFHX1dIRU5fUEFUSF9OVUxMLCBudWxsKSk7IC8vIkZyYWdtZW50IGNhbm5vdCBiZSBzZXQgd2hlbiBwYXRoIGlzIG51bGwhIik7Ci0gICAgfQotICAgIGVsc2UgaWYgKCFpc1VSSVN0cmluZyhwX2ZyYWdtZW50KSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVVJJRXhjZXB0aW9uKFV0aWxzLm1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoTXNnS2V5LkVSX0ZSQUdfSU5WQUxJRF9DSEFSLCBudWxsKSk7IC8vIkZyYWdtZW50IGNvbnRhaW5zIGludmFsaWQgY2hhcmFjdGVyISIpOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgbV9mcmFnbWVudCA9IHBfZnJhZ21lbnQ7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIERldGVybWluZXMgaWYgdGhlIHBhc3NlZC1pbiBPYmplY3QgaXMgZXF1aXZhbGVudCB0byB0aGlzIFVSSS4KLSAgICoKLSAgICogQHBhcmFtIHBfdGVzdCB0aGUgT2JqZWN0IHRvIHRlc3QgZm9yIGVxdWFsaXR5LgotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYgcF90ZXN0IGlzIGEgVVJJIHdpdGggYWxsIHZhbHVlcyBlcXVhbCB0byB0aGlzCi0gICAqICAgICAgICAgVVJJLCBmYWxzZSBvdGhlcndpc2UKLSAgICovCi0gIEBPdmVycmlkZQotICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IHBfdGVzdCkKLSAgewotCi0gICAgaWYgKHBfdGVzdCBpbnN0YW5jZW9mIFVSSSkKLSAgICB7Ci0gICAgICBVUkkgdGVzdFVSSSA9IChVUkkpIHBfdGVzdDsKLQotICAgICAgaWYgKCgobV9zY2hlbWUgPT0gbnVsbCAmJiB0ZXN0VVJJLm1fc2NoZW1lID09IG51bGwpIHx8IChtX3NjaGVtZSAhPSBudWxsICYmIHRlc3RVUkkubV9zY2hlbWUgIT0gbnVsbCAmJiBtX3NjaGVtZS5lcXVhbHMoCi0gICAgICAgICAgICAgIHRlc3RVUkkubV9zY2hlbWUpKSkgJiYgKChtX3VzZXJpbmZvID09IG51bGwgJiYgdGVzdFVSSS5tX3VzZXJpbmZvID09IG51bGwpIHx8IChtX3VzZXJpbmZvICE9IG51bGwgJiYgdGVzdFVSSS5tX3VzZXJpbmZvICE9IG51bGwgJiYgbV91c2VyaW5mby5lcXVhbHMoCi0gICAgICAgICAgICAgIHRlc3RVUkkubV91c2VyaW5mbykpKSAmJiAoKG1faG9zdCA9PSBudWxsICYmIHRlc3RVUkkubV9ob3N0ID09IG51bGwpIHx8IChtX2hvc3QgIT0gbnVsbCAmJiB0ZXN0VVJJLm1faG9zdCAhPSBudWxsICYmIG1faG9zdC5lcXVhbHMoCi0gICAgICAgICAgICAgIHRlc3RVUkkubV9ob3N0KSkpICYmIG1fcG9ydCA9PSB0ZXN0VVJJLm1fcG9ydCAmJiAoKG1fcGF0aCA9PSBudWxsICYmIHRlc3RVUkkubV9wYXRoID09IG51bGwpIHx8IChtX3BhdGggIT0gbnVsbCAmJiB0ZXN0VVJJLm1fcGF0aCAhPSBudWxsICYmIG1fcGF0aC5lcXVhbHMoCi0gICAgICAgICAgICAgIHRlc3RVUkkubV9wYXRoKSkpICYmICgobV9xdWVyeVN0cmluZyA9PSBudWxsICYmIHRlc3RVUkkubV9xdWVyeVN0cmluZyA9PSBudWxsKSB8fCAobV9xdWVyeVN0cmluZyAhPSBudWxsICYmIHRlc3RVUkkubV9xdWVyeVN0cmluZyAhPSBudWxsICYmIG1fcXVlcnlTdHJpbmcuZXF1YWxzKAotICAgICAgICAgICAgICB0ZXN0VVJJLm1fcXVlcnlTdHJpbmcpKSkgJiYgKChtX2ZyYWdtZW50ID09IG51bGwgJiYgdGVzdFVSSS5tX2ZyYWdtZW50ID09IG51bGwpIHx8IChtX2ZyYWdtZW50ICE9IG51bGwgJiYgdGVzdFVSSS5tX2ZyYWdtZW50ICE9IG51bGwgJiYgbV9mcmFnbWVudC5lcXVhbHMoCi0gICAgICAgICAgICAgIHRlc3RVUkkubV9mcmFnbWVudCkpKSkKLSAgICAgIHsKLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgcmV0dXJuIGZhbHNlOwotICB9Ci0KLSAgQE92ZXJyaWRlCi0gIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7Ci0gICAgaW50IGhhc2ggPSA1OwotICAgIGhhc2ggPSA0MSAqIGhhc2ggKyBPYmplY3RzLmhhc2hDb2RlKHRoaXMubV9zY2hlbWUpOwotICAgIGhhc2ggPSA0MSAqIGhhc2ggKyBPYmplY3RzLmhhc2hDb2RlKHRoaXMubV91c2VyaW5mbyk7Ci0gICAgaGFzaCA9IDQxICogaGFzaCArIE9iamVjdHMuaGFzaENvZGUodGhpcy5tX2hvc3QpOwotICAgIGhhc2ggPSA0MSAqIGhhc2ggKyB0aGlzLm1fcG9ydDsKLSAgICBoYXNoID0gNDEgKiBoYXNoICsgT2JqZWN0cy5oYXNoQ29kZSh0aGlzLm1fcGF0aCk7Ci0gICAgaGFzaCA9IDQxICogaGFzaCArIE9iamVjdHMuaGFzaENvZGUodGhpcy5tX3F1ZXJ5U3RyaW5nKTsKLSAgICBoYXNoID0gNDEgKiBoYXNoICsgT2JqZWN0cy5oYXNoQ29kZSh0aGlzLm1fZnJhZ21lbnQpOwotICAgIHJldHVybiBoYXNoOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgVVJJIGFzIGEgc3RyaW5nIHNwZWNpZmljYXRpb24uIFNlZSBSRkMgMjM5NiBTZWN0aW9uIDUuMi4KLSAgICoKLSAgICogQHJldHVybiB0aGUgVVJJIHN0cmluZyBzcGVjaWZpY2F0aW9uCi0gICAqLwotICBAT3ZlcnJpZGUKLSAgcHVibGljIFN0cmluZyB0b1N0cmluZygpCi0gIHsKLQotICAgIGZpbmFsIFN0cmluZ0J1aWxkZXIgdXJpU3BlY1N0cmluZyA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7Ci0KLSAgICBpZiAobV9zY2hlbWUgIT0gbnVsbCkKLSAgICB7Ci0gICAgICB1cmlTcGVjU3RyaW5nLmFwcGVuZChtX3NjaGVtZSk7Ci0gICAgICB1cmlTcGVjU3RyaW5nLmFwcGVuZCgnOicpOwotICAgIH0KLQotICAgIHVyaVNwZWNTdHJpbmcuYXBwZW5kKGdldFNjaGVtZVNwZWNpZmljUGFydCgpKTsKLQotICAgIHJldHVybiB1cmlTcGVjU3RyaW5nLnRvU3RyaW5nKCk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBpbmRpY2F0b3IgYXMgdG8gd2hldGhlciB0aGlzIFVSSSB1c2VzIHRoZSAiZ2VuZXJpYyBVUkkiCi0gICAqIHN5bnRheC4KLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHRoaXMgVVJJIHVzZXMgdGhlICJnZW5lcmljIFVSSSIgc3ludGF4LCBmYWxzZQotICAgKiAgICAgICAgIG90aGVyd2lzZQotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNHZW5lcmljVVJJKCkKLSAgewotCi0gICAgLy8gcHJlc2VuY2Ugb2YgdGhlIGhvc3QgKHdoZXRoZXIgdmFsaWQgb3IgZW1wdHkpIG1lYW5zCi0gICAgLy8gZG91YmxlLXNsYXNoZXMgd2hpY2ggbWVhbnMgZ2VuZXJpYyB1cmkKLSAgICByZXR1cm4gKG1faG9zdCAhPSBudWxsKTsKLSAgfQotCi0gIC8qKgotICAgKiBEZXRlcm1pbmUgd2hldGhlciBhIHNjaGVtZSBjb25mb3JtcyB0byB0aGUgcnVsZXMgZm9yIGEgc2NoZW1lIG5hbWUuCi0gICAqIEEgc2NoZW1lIGlzIGNvbmZvcm1hbnQgaWYgaXQgc3RhcnRzIHdpdGggYW4gYWxwaGFudW1lcmljLCBhbmQKLSAgICogY29udGFpbnMgb25seSBhbHBoYW51bWVyaWNzLCAnKycsJy0nIGFuZCAnLicuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBwX3NjaGVtZSBUaGUgc2hlbWUgbmFtZSB0byBjaGVjawotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHNjaGVtZSBpcyBjb25mb3JtYW50LCBmYWxzZSBvdGhlcndpc2UKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0NvbmZvcm1hbnRTY2hlbWVOYW1lKFN0cmluZyBwX3NjaGVtZSkKLSAgewotCi0gICAgaWYgKHBfc2NoZW1lID09IG51bGwgfHwgcF9zY2hlbWUudHJpbSgpLmxlbmd0aCgpID09IDApCi0gICAgewotICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIGlmICghaXNBbHBoYShwX3NjaGVtZS5jaGFyQXQoMCkpKQotICAgIHsKLSAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICBjaGFyIHRlc3RDaGFyOwotCi0gICAgZm9yIChpbnQgaSA9IDE7IGkgPCBwX3NjaGVtZS5sZW5ndGgoKTsgaSsrKQotICAgIHsKLSAgICAgIHRlc3RDaGFyID0gcF9zY2hlbWUuY2hhckF0KGkpOwotCi0gICAgICBpZiAoIWlzQWxwaGFudW0odGVzdENoYXIpICYmIFNDSEVNRV9DSEFSQUNURVJTLmluZGV4T2YodGVzdENoYXIpID09IC0xKQotICAgICAgewotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgcmV0dXJuIHRydWU7Ci0gIH0KLQotICAvKioKLSAgICogRGV0ZXJtaW5lIHdoZXRoZXIgYSBzdHJpbmcgaXMgc3ludGFjdGljYWxseSBjYXBhYmxlIG9mIHJlcHJlc2VudGluZwotICAgKiBhIHZhbGlkIElQdjQgYWRkcmVzcyBvciB0aGUgZG9tYWluIG5hbWUgb2YgYSBuZXR3b3JrIGhvc3QuIEEgdmFsaWQKLSAgICogSVB2NCBhZGRyZXNzIGNvbnNpc3RzIG9mIGZvdXIgZGVjaW1hbCBkaWdpdCBncm91cHMgc2VwYXJhdGVkIGJ5IGEKLSAgICogJy4nLiBBIGhvc3RuYW1lIGNvbnNpc3RzIG9mIGRvbWFpbiBsYWJlbHMgKGVhY2ggb2Ygd2hpY2ggbXVzdAotICAgKiBiZWdpbiBhbmQgZW5kIHdpdGggYW4gYWxwaGFudW1lcmljIGJ1dCBtYXkgY29udGFpbiAnLScpIHNlcGFyYXRlZAotICAgKiAmIGJ5IGEgJy4nLiBTZWUgUkZDIDIzOTYgU2VjdGlvbiAzLjIuMi4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHBfYWRkcmVzcyBUaGUgYWRkcmVzcyBzdHJpbmcgdG8gY2hlY2sKLSAgICogQHJldHVybiB0cnVlIGlmIHRoZSBzdHJpbmcgaXMgYSBzeW50YWN0aWNhbGx5IHZhbGlkIElQdjQgYWRkcmVzcwotICAgKiAgICAgICAgICAgICAgb3IgaG9zdG5hbWUKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc1dlbGxGb3JtZWRBZGRyZXNzKFN0cmluZyBwX2FkZHJlc3MpCi0gIHsKLQotICAgIGlmIChwX2FkZHJlc3MgPT0gbnVsbCkKLSAgICB7Ci0gICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgU3RyaW5nIGFkZHJlc3MgPSBwX2FkZHJlc3MudHJpbSgpOwotICAgIGludCBhZGRyTGVuZ3RoID0gYWRkcmVzcy5sZW5ndGgoKTsKLQotICAgIGlmIChhZGRyTGVuZ3RoID09IDAgfHwgYWRkckxlbmd0aCA+IDI1NSkKLSAgICB7Ci0gICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgaWYgKGFkZHJlc3Muc3RhcnRzV2l0aCgiLiIpIHx8IGFkZHJlc3Muc3RhcnRzV2l0aCgiLSIpKQotICAgIHsKLSAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICAvLyByaWdodG1vc3QgZG9tYWluIGxhYmVsIHN0YXJ0aW5nIHdpdGggZGlnaXQgaW5kaWNhdGVzIElQIGFkZHJlc3MKLSAgICAvLyBzaW5jZSB0b3AgbGV2ZWwgZG9tYWluIGxhYmVsIGNhbiBvbmx5IHN0YXJ0IHdpdGggYW4gYWxwaGEKLSAgICAvLyBzZWUgUkZDIDIzOTYgU2VjdGlvbiAzLjIuMgotICAgIGludCBpbmRleCA9IGFkZHJlc3MubGFzdEluZGV4T2YoJy4nKTsKLQotICAgIGlmIChhZGRyZXNzLmVuZHNXaXRoKCIuIikpCi0gICAgewotICAgICAgaW5kZXggPSBhZGRyZXNzLnN1YnN0cmluZygwLCBpbmRleCkubGFzdEluZGV4T2YoJy4nKTsKLSAgICB9Ci0KLSAgICBpZiAoaW5kZXggKyAxIDwgYWRkckxlbmd0aCAmJiBpc0RpZ2l0KHBfYWRkcmVzcy5jaGFyQXQoaW5kZXggKyAxKSkpCi0gICAgewotICAgICAgY2hhciB0ZXN0Q2hhcjsKLSAgICAgIGludCBudW1Eb3RzID0gMDsKLQotICAgICAgLy8gbWFrZSBzdXJlIHRoYXQgMSkgd2Ugc2VlIG9ubHkgZGlnaXRzIGFuZCBkb3Qgc2VwYXJhdG9ycywgMikgdGhhdAotICAgICAgLy8gYW55IGRvdCBzZXBhcmF0b3IgaXMgcHJlY2VkZWQgYW5kIGZvbGxvd2VkIGJ5IGEgZGlnaXQgYW5kCi0gICAgICAvLyAzKSB0aGF0IHdlIGZpbmQgMyBkb3RzCi0gICAgICBmb3IgKGludCBpID0gMDsgaSA8IGFkZHJMZW5ndGg7IGkrKykKLSAgICAgIHsKLSAgICAgICAgdGVzdENoYXIgPSBhZGRyZXNzLmNoYXJBdChpKTsKLQotICAgICAgICBpZiAodGVzdENoYXIgPT0gJy4nKQotICAgICAgICB7Ci0gICAgICAgICAgaWYgKCFpc0RpZ2l0KGFkZHJlc3MuY2hhckF0KGkgLSAxKSkKLSAgICAgICAgICAgICAgICAgIHx8IChpICsgMSA8IGFkZHJMZW5ndGggJiYhaXNEaWdpdChhZGRyZXNzLmNoYXJBdChpICsgMSkpKSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgfQotCi0gICAgICAgICAgbnVtRG90cysrOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKCFpc0RpZ2l0KHRlc3RDaGFyKSkKLSAgICAgICAgewotICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotICAgICAgfQotCi0gICAgICBpZiAobnVtRG90cyAhPSAzKQotICAgICAgewotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICB9Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0KLSAgICAgIC8vIGRvbWFpbiBsYWJlbHMgY2FuIGNvbnRhaW4gYWxwaGFudW1lcmljcyBhbmQgJy0iCi0gICAgICAvLyBidXQgbXVzdCBzdGFydCBhbmQgZW5kIHdpdGggYW4gYWxwaGFudW1lcmljCi0gICAgICBjaGFyIHRlc3RDaGFyOwotCi0gICAgICBmb3IgKGludCBpID0gMDsgaSA8IGFkZHJMZW5ndGg7IGkrKykKLSAgICAgIHsKLSAgICAgICAgdGVzdENoYXIgPSBhZGRyZXNzLmNoYXJBdChpKTsKLQotICAgICAgICBpZiAodGVzdENoYXIgPT0gJy4nKQotICAgICAgICB7Ci0gICAgICAgICAgaWYgKCFpc0FscGhhbnVtKGFkZHJlc3MuY2hhckF0KGkgLSAxKSkpCi0gICAgICAgICAgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgIH0KLQotICAgICAgICAgIGlmIChpICsgMSA8IGFkZHJMZW5ndGggJiYhaXNBbHBoYW51bShhZGRyZXNzLmNoYXJBdChpICsgMSkpKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoIWlzQWxwaGFudW0odGVzdENoYXIpICYmIHRlc3RDaGFyICE9ICctJykKLSAgICAgICAgewotICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiB0cnVlOwotICB9Ci0KLSAgLyoqCi0gICAqIERldGVybWluZSB3aGV0aGVyIGEgY2hhciBpcyBhIGRpZ2l0LgotICAgKgotICAgKgotICAgKiBAcGFyYW0gcF9jaGFyIHRoZSBjaGFyYWN0ZXIgdG8gY2hlY2sKLSAgICogQHJldHVybiB0cnVlIGlmIHRoZSBjaGFyIGlzIGJldHdlZWVuICcwJyBhbmQgJzknLCBmYWxzZSBvdGhlcndpc2UKLSAgICovCi0gIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNEaWdpdChjaGFyIHBfY2hhcikKLSAgewotICAgIHJldHVybiBwX2NoYXIgPj0gJzAnICYmIHBfY2hhciA8PSAnOSc7Ci0gIH0KLQotICAvKioKLSAgICogRGV0ZXJtaW5lIHdoZXRoZXIgYSBjaGFyYWN0ZXIgaXMgYSBoZXhhZGVjaW1hbCBjaGFyYWN0ZXIuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBwX2NoYXIgdGhlIGNoYXJhY3RlciB0byBjaGVjawotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGNoYXIgaXMgYmV0d2VlbiAnMCcgYW5kICc5JywgJ2EnIGFuZCAnZicKLSAgICogICAgICAgICBvciAnQScgYW5kICdGJywgZmFsc2Ugb3RoZXJ3aXNlCi0gICAqLwotICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGlzSGV4KGNoYXIgcF9jaGFyKQotICB7Ci0gICAgcmV0dXJuIChpc0RpZ2l0KHBfY2hhcikgfHwgKHBfY2hhciA+PSAnYScgJiYgcF9jaGFyIDw9ICdmJykKLSAgICAgICAgICAgIHx8IChwX2NoYXIgPj0gJ0EnICYmIHBfY2hhciA8PSAnRicpKTsKLSAgfQotCi0gIC8qKgotICAgKiBEZXRlcm1pbmUgd2hldGhlciBhIGNoYXIgaXMgYW4gYWxwaGFiZXRpYyBjaGFyYWN0ZXI6IGEteiBvciBBLVoKLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHBfY2hhciB0aGUgY2hhcmFjdGVyIHRvIGNoZWNrCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgY2hhciBpcyBhbHBoYWJldGljLCBmYWxzZSBvdGhlcndpc2UKLSAgICovCi0gIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNBbHBoYShjaGFyIHBfY2hhcikKLSAgewotICAgIHJldHVybiAoKHBfY2hhciA+PSAnYScgJiYgcF9jaGFyIDw9ICd6JykKLSAgICAgICAgICAgIHx8IChwX2NoYXIgPj0gJ0EnICYmIHBfY2hhciA8PSAnWicpKTsKLSAgfQotCi0gIC8qKgotICAgKiBEZXRlcm1pbmUgd2hldGhlciBhIGNoYXIgaXMgYW4gYWxwaGFudW1lcmljOiAwLTksIGEteiBvciBBLVoKLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHBfY2hhciB0aGUgY2hhcmFjdGVyIHRvIGNoZWNrCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgY2hhciBpcyBhbHBoYW51bWVyaWMsIGZhbHNlIG90aGVyd2lzZQotICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBpc0FscGhhbnVtKGNoYXIgcF9jaGFyKQotICB7Ci0gICAgcmV0dXJuIChpc0FscGhhKHBfY2hhcikgfHwgaXNEaWdpdChwX2NoYXIpKTsKLSAgfQotCi0gIC8qKgotICAgKiBEZXRlcm1pbmUgd2hldGhlciBhIGNoYXJhY3RlciBpcyBhIHJlc2VydmVkIGNoYXJhY3RlcjoKLSAgICogJzsnLCAnLycsICc/JywgJzonLCAnQCcsICcmJywgJz0nLCAnKycsICckJyBvciAnLCcKLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHBfY2hhciB0aGUgY2hhcmFjdGVyIHRvIGNoZWNrCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgc3RyaW5nIGNvbnRhaW5zIGFueSByZXNlcnZlZCBjaGFyYWN0ZXJzCi0gICAqLwotICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGlzUmVzZXJ2ZWRDaGFyYWN0ZXIoY2hhciBwX2NoYXIpCi0gIHsKLSAgICByZXR1cm4gUkVTRVJWRURfQ0hBUkFDVEVSUy5pbmRleE9mKHBfY2hhcikgIT0gLTE7Ci0gIH0KLQotICAvKioKLSAgICogRGV0ZXJtaW5lIHdoZXRoZXIgYSBjaGFyIGlzIGFuIHVucmVzZXJ2ZWQgY2hhcmFjdGVyLgotICAgKgotICAgKgotICAgKiBAcGFyYW0gcF9jaGFyIHRoZSBjaGFyYWN0ZXIgdG8gY2hlY2sKLSAgICogQHJldHVybiB0cnVlIGlmIHRoZSBjaGFyIGlzIHVucmVzZXJ2ZWQsIGZhbHNlIG90aGVyd2lzZQotICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBpc1VucmVzZXJ2ZWRDaGFyYWN0ZXIoY2hhciBwX2NoYXIpCi0gIHsKLSAgICByZXR1cm4gKGlzQWxwaGFudW0ocF9jaGFyKSB8fCBNQVJLX0NIQVJBQ1RFUlMuaW5kZXhPZihwX2NoYXIpICE9IC0xKTsKLSAgfQotCi0gIC8qKgotICAgKiBEZXRlcm1pbmUgd2hldGhlciBhIGdpdmVuIHN0cmluZyBjb250YWlucyBvbmx5IFVSSSBjaGFyYWN0ZXJzIChhbHNvCi0gICAqIGNhbGxlZCAidXJpYyIgaW4gUkZDIDIzOTYpLiB1cmljIGNvbnNpc3Qgb2YgYWxsIHJlc2VydmVkCi0gICAqIGNoYXJhY3RlcnMsIHVucmVzZXJ2ZWQgY2hhcmFjdGVycyBhbmQgZXNjYXBlZCBjaGFyYWN0ZXJzLgotICAgKgotICAgKgotICAgKiBAcGFyYW0gcF91cmljIFVSSSBzdHJpbmcKLSAgICogQHJldHVybiB0cnVlIGlmIHRoZSBzdHJpbmcgaXMgY29tcHJpc2VkIG9mIHVyaWMsIGZhbHNlIG90aGVyd2lzZQotICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBpc1VSSVN0cmluZyhTdHJpbmcgcF91cmljKQotICB7Ci0KLSAgICBpZiAocF91cmljID09IG51bGwpCi0gICAgewotICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIGludCBlbmQgPSBwX3VyaWMubGVuZ3RoKCk7Ci0gICAgY2hhciB0ZXN0Q2hhciA9ICdcMCc7Ci0KLSAgICBmb3IgKGludCBpID0gMDsgaSA8IGVuZDsgaSsrKQotICAgIHsKLSAgICAgIHRlc3RDaGFyID0gcF91cmljLmNoYXJBdChpKTsKLQotICAgICAgaWYgKHRlc3RDaGFyID09ICclJykKLSAgICAgIHsKLSAgICAgICAgaWYgKGkgKyAyID49IGVuZCB8fCFpc0hleChwX3VyaWMuY2hhckF0KGkgKyAxKSkKLSAgICAgICAgICAgICAgICB8fCFpc0hleChwX3VyaWMuY2hhckF0KGkgKyAyKSkpCi0gICAgICAgIHsKLSAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICB7Ci0gICAgICAgICAgaSArPSAyOwotCi0gICAgICAgICAgY29udGludWU7Ci0gICAgICAgIH0KLSAgICAgIH0KLQotICAgICAgaWYgKGlzUmVzZXJ2ZWRDaGFyYWN0ZXIodGVzdENoYXIpIHx8IGlzVW5yZXNlcnZlZENoYXJhY3Rlcih0ZXN0Q2hhcikpCi0gICAgICB7Ci0gICAgICAgIGNvbnRpbnVlOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgcmV0dXJuIHRydWU7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvdXRpbHMvVXRpbHMuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvdXRpbHMvVXRpbHMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNTdiZTNjYS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL3V0aWxzL1V0aWxzLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0MyArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDE1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICovCi0vKgotICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCi0gKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKLSAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KLSAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCi0gKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAotICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFV0aWxzLmphdmEsdiAxLjEuNC4xIDIwMDUvMDkvMDggMTE6MDM6MjEgc3VyZXNoX2VtYWlsaWQgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXIudXRpbHM7Ci0KLS8qKgotICogVGhpcyBjbGFzcyBjb250YWlucyB1dGlsaXRpZXMgdXNlZCBieSB0aGUgc2VyaWFsaXplci4KLSAqCi0gKiBUaGlzIGNsYXNzIGlzIG5vdCBhIHB1YmxpYyBBUEksIGl0IGlzIG9ubHkgcHVibGljIGJlY2F1c2UgaXQgaXMKLSAqIHVzZWQgYnkgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyLgotICoKLSAqIEB4c2wudXNhZ2UgaW50ZXJuYWwKLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIFV0aWxzCi17Ci0gICAgLyoqCi0gICAgICogQSBzaW5nbGV0b24gTWVzc2FnZXMgb2JqZWN0IGlzIHVzZWQgdG8gbG9hZCB0aGUKLSAgICAgKiBnaXZlbiByZXNvdXJjZSBidW5kbGUganVzdCBvbmNlLCBpdCBpcwotICAgICAqIHVzZWQgYnkgbXVsdGlwbGUgdHJhbnNmb3JtYXRpb25zIGFzIGxvbmcgYXMgdGhlIEpWTSBzdGF5cyB1cC4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplci51dGlscy5NZXNzYWdlcyBtZXNzYWdlcz0KLSAgICAgICAgbmV3IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplci51dGlscy5NZXNzYWdlcygKLSAgICAgICAgICAgICJjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXIudXRpbHMuU2VyaWFsaXplck1lc3NhZ2VzIik7Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL3V0aWxzL1dyYXBwZWRSdW50aW1lRXhjZXB0aW9uLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL3V0aWxzL1dyYXBwZWRSdW50aW1lRXhjZXB0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDc1OGUzMGYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci91dGlscy9XcmFwcGVkUnVudGltZUV4Y2VwdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsODMgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogV3JhcHBlZFJ1bnRpbWVFeGNlcHRpb24uamF2YSx2IDEuMS40LjEgMjAwNS8wOS8wOCAxMTowMzoyMSBzdXJlc2hfZW1haWxpZCBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplci51dGlsczsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGlzIGZvciB0aHJvd2luZyBpbXBvcnRhbnQgY2hlY2tlZCBleGNlcHRpb25zCi0gKiBvdmVyIG5vbi1jaGVja2VkIG1ldGhvZHMuICBJdCBzaG91bGQgYmUgdXNlZCB3aXRoIGNhcmUsCi0gKiBhbmQgaW4gbGltaXRlZCBjaXJjdW1zdGFuY2VzLgotICoKLSAqIFRoaXMgY2xhc3MgaXMgYSBjb3B5IG9mIHRoZSBvbmUgaW4gY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy4KLSAqIEl0IGV4aXN0cyB0byBjdXQgdGhlIHNlcmlhbGl6ZXJzIGRlcGVuZGFuY3kgb24gdGhhdCBwYWNrYWdlLgotICoKLSAqIFRoaXMgY2xhc3MgaXMgbm90IGEgcHVibGljIEFQSSwgaXQgaXMgb25seSBwdWJsaWMgYmVjYXVzZSBpdCBpcwotICogdXNlZCBieSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXIuCi0gKiBAeHNsLnVzYWdlIGludGVybmFsCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBXcmFwcGVkUnVudGltZUV4Y2VwdGlvbiBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24KLXsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNzE0MDQxNDQ1NjcxNDY1ODA3M0w7Ci0KLSAgLyoqIFByaW1hcnkgY2hlY2tlZCBleGNlcHRpb24uCi0gICAqICBAc2VyaWFsICAgICAgICAgICovCi0gIHByaXZhdGUgRXhjZXB0aW9uIG1fZXhjZXB0aW9uOwotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBXcmFwcGVkUnVudGltZUV4Y2VwdGlvbiBmcm9tIGEKLSAgICogY2hlY2tlZCBleGNlcHRpb24uCi0gICAqCi0gICAqIEBwYXJhbSBlIFByaW1hcnkgY2hlY2tlZCBleGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBXcmFwcGVkUnVudGltZUV4Y2VwdGlvbihFeGNlcHRpb24gZSkKLSAgewotCi0gICAgc3VwZXIoZS5nZXRNZXNzYWdlKCkpOwotCi0gICAgbV9leGNlcHRpb24gPSBlOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdG9yIFdyYXBwZWRSdW50aW1lRXhjZXB0aW9uCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBtc2cgRXhjZXB0aW9uIGluZm9ybWF0aW9uLgotICAgKiBAcGFyYW0gZSBQcmltYXJ5IGNoZWNrZWQgZXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgV3JhcHBlZFJ1bnRpbWVFeGNlcHRpb24oU3RyaW5nIG1zZywgRXhjZXB0aW9uIGUpCi0gIHsKLQotICAgIHN1cGVyKG1zZyk7Ci0KLSAgICBtX2V4Y2VwdGlvbiA9IGU7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBjaGVja2VkIGV4Y2VwdGlvbiB0aGF0IHRoaXMgcnVudGltZSBleGNlcHRpb24gd3JhcHMuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHByaW1hcnkgY2hlY2tlZCBleGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBFeGNlcHRpb24gZ2V0RXhjZXB0aW9uKCkKLSAgewotICAgIHJldHVybiBtX2V4Y2VwdGlvbjsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvQXR0TGlzdC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvQXR0TGlzdC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4NDM3ZmZkLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL0F0dExpc3QuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI1NiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBBdHRMaXN0LmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTUgMDg6MTU6MzUgc3VyZXNoX2VtYWlsaWQgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzOwotCi1pbXBvcnQgb3JnLnczYy5kb20uQXR0cjsKLWltcG9ydCBvcmcudzNjLmRvbS5OYW1lZE5vZGVNYXA7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLQotaW1wb3J0IG9yZy54bWwuc2F4LkF0dHJpYnV0ZXM7Ci0KLS8qKgotICogV3JhcHMgYSBET00gYXR0cmlidXRlIGxpc3QgaW4gYSBTQVggQXR0cmlidXRlcy4KLSAqIEB4c2wudXNhZ2UgaW50ZXJuYWwKLSAqLwotcHVibGljIGNsYXNzIEF0dExpc3QgaW1wbGVtZW50cyBBdHRyaWJ1dGVzCi17Ci0KLSAgLyoqIExpc3Qgb2YgYXR0cmlidXRlIG5vZGVzICAgICAgICAgICovCi0gIE5hbWVkTm9kZU1hcCBtX2F0dHJzOwotCi0gIC8qKiBJbmRleCBvZiBsYXN0IGF0dHJpYnV0ZSBub2RlICAgICAgICAgICovCi0gIGludCBtX2xhc3RJbmRleDsKLQotICAvLyBBUkdISCEhICBKQVhQIFVzZXMgWGVyY2VzIHdpdGhvdXQgc2V0dGluZyB0aGUgbmFtZXNwYWNlIHByb2Nlc3NpbmcgdG8gT04hCi0gIC8vIERPTTJIZWxwZXIgbV9kaCA9IG5ldyBET00ySGVscGVyKCk7Ci0KLSAgLyoqIExvY2FsIHJlZmVyZW5jZSB0byBET01IZWxwZXIgICAgICAgICAgKi8KLSAgRE9NSGVscGVyIG1fZGg7Ci0KLS8vICAvKioKLS8vICAgKiBDb25zdHJ1Y3RvciBBdHRMaXN0Ci0vLyAgICoKLS8vICAgKgotLy8gICAqIEBwYXJhbSBhdHRycyBMaXN0IG9mIGF0dHJpYnV0ZXMgdGhpcyB3aWxsIGNvbnRhaW4KLS8vICAgKi8KLS8vICBwdWJsaWMgQXR0TGlzdChOYW1lZE5vZGVNYXAgYXR0cnMpCi0vLyAgewotLy8KLS8vICAgIG1fYXR0cnMgPSBhdHRyczsKLS8vICAgIG1fbGFzdEluZGV4ID0gbV9hdHRycy5nZXRMZW5ndGgoKSAtIDE7Ci0vLyAgICBtX2RoID0gbmV3IERPTTJIZWxwZXIoKTsKLS8vICB9Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdG9yIEF0dExpc3QKLSAgICoKLSAgICoKLSAgICogQHBhcmFtIGF0dHJzIExpc3Qgb2YgYXR0cmlidXRlcyB0aGlzIHdpbGwgY29udGFpbgotICAgKiBAcGFyYW0gZGggRE9NSGVscGVyCi0gICAqLwotICBwdWJsaWMgQXR0TGlzdChOYW1lZE5vZGVNYXAgYXR0cnMsIERPTUhlbHBlciBkaCkKLSAgewotCi0gICAgbV9hdHRycyA9IGF0dHJzOwotICAgIG1fbGFzdEluZGV4ID0gbV9hdHRycy5nZXRMZW5ndGgoKSAtIDE7Ci0gICAgbV9kaCA9IGRoOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbnVtYmVyIG9mIGF0dHJpYnV0ZSBub2RlcyBpbiB0aGUgbGlzdAotICAgKgotICAgKgotICAgKiBAcmV0dXJuIG51bWJlciBvZiBhdHRyaWJ1dGUgbm9kZXMKLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0TGVuZ3RoKCkKLSAgewotICAgIHJldHVybiBtX2F0dHJzLmdldExlbmd0aCgpOwotICB9Ci0KLSAgLyoqCi0gICAqIExvb2sgdXAgYW4gYXR0cmlidXRlJ3MgTmFtZXNwYWNlIFVSSSBieSBpbmRleC4KLSAgICoKLSAgICogQHBhcmFtIGluZGV4IFRoZSBhdHRyaWJ1dGUgaW5kZXggKHplcm8tYmFzZWQpLgotICAgKiBAcmV0dXJuIFRoZSBOYW1lc3BhY2UgVVJJLCBvciB0aGUgZW1wdHkgc3RyaW5nIGlmIG5vbmUKLSAgICogICAgICAgICBpcyBhdmFpbGFibGUsIG9yIG51bGwgaWYgdGhlIGluZGV4IGlzIG91dCBvZgotICAgKiAgICAgICAgIHJhbmdlLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRVUkkoaW50IGluZGV4KQotICB7Ci0gICAgU3RyaW5nIG5zID0gbV9kaC5nZXROYW1lc3BhY2VPZk5vZGUoKChBdHRyKSBtX2F0dHJzLml0ZW0oaW5kZXgpKSk7Ci0gICAgaWYobnVsbCA9PSBucykKLSAgICAgIG5zID0gIiI7Ci0gICAgcmV0dXJuIG5zOwotICB9Ci0KLSAgLyoqCi0gICAqIExvb2sgdXAgYW4gYXR0cmlidXRlJ3MgbG9jYWwgbmFtZSBieSBpbmRleC4KLSAgICoKLSAgICogQHBhcmFtIGluZGV4IFRoZSBhdHRyaWJ1dGUgaW5kZXggKHplcm8tYmFzZWQpLgotICAgKiBAcmV0dXJuIFRoZSBsb2NhbCBuYW1lLCBvciB0aGUgZW1wdHkgc3RyaW5nIGlmIE5hbWVzcGFjZQotICAgKiAgICAgICAgIHByb2Nlc3NpbmcgaXMgbm90IGJlaW5nIHBlcmZvcm1lZCwgb3IgbnVsbAotICAgKiAgICAgICAgIGlmIHRoZSBpbmRleCBpcyBvdXQgb2YgcmFuZ2UuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldExvY2FsTmFtZShpbnQgaW5kZXgpCi0gIHsKLSAgICByZXR1cm4gbV9kaC5nZXRMb2NhbE5hbWVPZk5vZGUoKChBdHRyKSBtX2F0dHJzLml0ZW0oaW5kZXgpKSk7Ci0gIH0KLQotICAvKioKLSAgICogTG9vayB1cCBhbiBhdHRyaWJ1dGUncyBxdWFsaWZpZWQgbmFtZSBieSBpbmRleC4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIGkgVGhlIGF0dHJpYnV0ZSBpbmRleCAoemVyby1iYXNlZCkuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGF0dHJpYnV0ZSdzIHF1YWxpZmllZCBuYW1lCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFFOYW1lKGludCBpKQotICB7Ci0gICAgcmV0dXJuICgoQXR0cikgbV9hdHRycy5pdGVtKGkpKS5nZXROYW1lKCk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBhdHRyaWJ1dGUncyBub2RlIHR5cGUgYnkgaW5kZXgKLSAgICoKLSAgICoKLSAgICogQHBhcmFtIGkgVGhlIGF0dHJpYnV0ZSBpbmRleCAoemVyby1iYXNlZCkKLSAgICoKLSAgICogQHJldHVybiB0aGUgYXR0cmlidXRlJ3Mgbm9kZSB0eXBlCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFR5cGUoaW50IGkpCi0gIHsKLSAgICByZXR1cm4gIkNEQVRBIjsgIC8vIGZvciB0aGUgbW9tZW50Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBhdHRyaWJ1dGUncyBub2RlIHZhbHVlIGJ5IGluZGV4Ci0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBpIFRoZSBhdHRyaWJ1dGUgaW5kZXggKHplcm8tYmFzZWQpCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIGF0dHJpYnV0ZSdzIG5vZGUgdmFsdWUKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0VmFsdWUoaW50IGkpCi0gIHsKLSAgICByZXR1cm4gKChBdHRyKSBtX2F0dHJzLml0ZW0oaSkpLmdldFZhbHVlKCk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBhdHRyaWJ1dGUncyBub2RlIHR5cGUgYnkgbmFtZQotICAgKgotICAgKgotICAgKiBAcGFyYW0gbmFtZSBBdHRyaWJ1dGUgbmFtZQotICAgKgotICAgKiBAcmV0dXJuIHRoZSBhdHRyaWJ1dGUncyBub2RlIHR5cGUKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0VHlwZShTdHJpbmcgbmFtZSkKLSAgewotICAgIHJldHVybiAiQ0RBVEEiOyAgLy8gZm9yIHRoZSBtb21lbnQKLSAgfQotCi0gIC8qKgotICAgKiBMb29rIHVwIGFuIGF0dHJpYnV0ZSdzIHR5cGUgYnkgTmFtZXNwYWNlIG5hbWUuCi0gICAqCi0gICAqIEBwYXJhbSB1cmkgVGhlIE5hbWVzcGFjZSBVUkksIG9yIHRoZSBlbXB0eSBTdHJpbmcgaWYgdGhlCi0gICAqICAgICAgICBuYW1lIGhhcyBubyBOYW1lc3BhY2UgVVJJLgotICAgKiBAcGFyYW0gbG9jYWxOYW1lIFRoZSBsb2NhbCBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUuCi0gICAqIEByZXR1cm4gVGhlIGF0dHJpYnV0ZSB0eXBlIGFzIGEgc3RyaW5nLCBvciBudWxsIGlmIHRoZQotICAgKiAgICAgICAgIGF0dHJpYnV0ZSBpcyBub3QgaW4gdGhlIGxpc3Qgb3IgaWYgTmFtZXNwYWNlCi0gICAqICAgICAgICAgcHJvY2Vzc2luZyBpcyBub3QgYmVpbmcgcGVyZm9ybWVkLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRUeXBlKFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUpCi0gIHsKLSAgICByZXR1cm4gIkNEQVRBIjsgIC8vIGZvciB0aGUgbW9tZW50Ci0gIH0KLQotICAvKioKLSAgICogTG9vayB1cCBhbiBhdHRyaWJ1dGUncyB2YWx1ZSBieSBuYW1lLgotICAgKgotICAgKgotICAgKiBAcGFyYW0gbmFtZSBUaGUgYXR0cmlidXRlIG5vZGUncyBuYW1lCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGF0dHJpYnV0ZSBub2RlJ3MgdmFsdWUKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0VmFsdWUoU3RyaW5nIG5hbWUpCi0gIHsKLSAgICBBdHRyIGF0dHIgPSAoKEF0dHIpIG1fYXR0cnMuZ2V0TmFtZWRJdGVtKG5hbWUpKTsKLSAgICByZXR1cm4gKG51bGwgIT0gYXR0cikKLSAgICAgICAgICA/IGF0dHIuZ2V0VmFsdWUoKSA6IG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogTG9vayB1cCBhbiBhdHRyaWJ1dGUncyB2YWx1ZSBieSBOYW1lc3BhY2UgbmFtZS4KLSAgICoKLSAgICogQHBhcmFtIHVyaSBUaGUgTmFtZXNwYWNlIFVSSSwgb3IgdGhlIGVtcHR5IFN0cmluZyBpZiB0aGUKLSAgICogICAgICAgIG5hbWUgaGFzIG5vIE5hbWVzcGFjZSBVUkkuCi0gICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGxvY2FsIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICogQHJldHVybiBUaGUgYXR0cmlidXRlIHZhbHVlIGFzIGEgc3RyaW5nLCBvciBudWxsIGlmIHRoZQotICAgKiAgICAgICAgIGF0dHJpYnV0ZSBpcyBub3QgaW4gdGhlIGxpc3QuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFZhbHVlKFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUpCi0gIHsKLSAgICAgICAgICAgICAgICBOb2RlIGE9bV9hdHRycy5nZXROYW1lZEl0ZW1OUyh1cmksbG9jYWxOYW1lKTsKLSAgICAgICAgICAgICAgICByZXR1cm4gKGE9PW51bGwpID8gbnVsbCA6IGEuZ2V0Tm9kZVZhbHVlKCk7Ci0gIH0KLQotICAvKioKLSAgICogTG9vayB1cCB0aGUgaW5kZXggb2YgYW4gYXR0cmlidXRlIGJ5IE5hbWVzcGFjZSBuYW1lLgotICAgKgotICAgKiBAcGFyYW0gdXJpIFRoZSBOYW1lc3BhY2UgVVJJLCBvciB0aGUgZW1wdHkgc3RyaW5nIGlmCi0gICAqICAgICAgICB0aGUgbmFtZSBoYXMgbm8gTmFtZXNwYWNlIFVSSS4KLSAgICogQHBhcmFtIGxvY2FsUGFydCBUaGUgYXR0cmlidXRlJ3MgbG9jYWwgbmFtZS4KLSAgICogQHJldHVybiBUaGUgaW5kZXggb2YgdGhlIGF0dHJpYnV0ZSwgb3IgLTEgaWYgaXQgZG9lcyBub3QKLSAgICogICAgICAgICBhcHBlYXIgaW4gdGhlIGxpc3QuCi0gICAqLwotICBwdWJsaWMgaW50IGdldEluZGV4KFN0cmluZyB1cmksIFN0cmluZyBsb2NhbFBhcnQpCi0gIHsKLSAgICBmb3IoaW50IGk9bV9hdHRycy5nZXRMZW5ndGgoKS0xO2k+PTA7LS1pKQotICAgIHsKLSAgICAgIE5vZGUgYT1tX2F0dHJzLml0ZW0oaSk7Ci0gICAgICBTdHJpbmcgdT1hLmdldE5hbWVzcGFjZVVSSSgpOwotICAgICAgaWYoICh1PT1udWxsID8gdXJpPT1udWxsIDogdS5lcXVhbHModXJpKSkKLSAgICAgICAgICAmJgotICAgICAgICAgIGEuZ2V0TG9jYWxOYW1lKCkuZXF1YWxzKGxvY2FsUGFydCkgKQotICAgICAgICByZXR1cm4gaTsKLSAgICB9Ci0gICAgcmV0dXJuIC0xOwotICB9Ci0KLSAgLyoqCi0gICAqIExvb2sgdXAgdGhlIGluZGV4IG9mIGFuIGF0dHJpYnV0ZSBieSByYXcgWE1MIDEuMCBuYW1lLgotICAgKgotICAgKiBAcGFyYW0gcU5hbWUgVGhlIHF1YWxpZmllZCAocHJlZml4ZWQpIG5hbWUuCi0gICAqIEByZXR1cm4gVGhlIGluZGV4IG9mIHRoZSBhdHRyaWJ1dGUsIG9yIC0xIGlmIGl0IGRvZXMgbm90Ci0gICAqICAgICAgICAgYXBwZWFyIGluIHRoZSBsaXN0LgotICAgKi8KLSAgcHVibGljIGludCBnZXRJbmRleChTdHJpbmcgcU5hbWUpCi0gIHsKLSAgICBmb3IoaW50IGk9bV9hdHRycy5nZXRMZW5ndGgoKS0xO2k+PTA7LS1pKQotICAgIHsKLSAgICAgIE5vZGUgYT1tX2F0dHJzLml0ZW0oaSk7Ci0gICAgICBpZihhLmdldE5vZGVOYW1lKCkuZXF1YWxzKHFOYW1lKSApCi0gICAgICAgIHJldHVybiBpOwotICAgIH0KLSAgICByZXR1cm4gLTE7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL0Jvb2xTdGFjay5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvQm9vbFN0YWNrLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGI0N2RjNWMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvQm9vbFN0YWNrLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMDQgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogQm9vbFN0YWNrLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTUgMDg6MTU6MzUgc3VyZXNoX2VtYWlsaWQgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzOwotCi0KLS8qKgotICogU2ltcGxlIHN0YWNrIGZvciBib29sZWFuIHZhbHVlcy4KLSAqIEB4c2wudXNhZ2UgaW50ZXJuYWwKLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIEJvb2xTdGFjayBpbXBsZW1lbnRzIENsb25lYWJsZQotewotCi0gIC8qKiBBcnJheSBvZiBib29sZWFuIHZhbHVlcyAgICAgICAgICAqLwotICBwcml2YXRlIGJvb2xlYW4gbV92YWx1ZXNbXTsKLQotICAvKiogQXJyYXkgc2l6ZSBhbGxvY2F0ZWQgICAgICAgICAgICovCi0gIHByaXZhdGUgaW50IG1fYWxsb2NhdGVkU2l6ZTsKLQotICAvKiogSW5kZXggaW50byB0aGUgYXJyYXkgb2YgYm9vbGVhbnMgICAgICAgICAgKi8KLSAgcHJpdmF0ZSBpbnQgbV9pbmRleDsKLQotICAvKioKLSAgICogRGVmYXVsdCBjb25zdHJ1Y3Rvci4gIE5vdGUgdGhhdCB0aGUgZGVmYXVsdAotICAgKiBibG9jayBzaXplIGlzIHZlcnkgc21hbGwsIGZvciBzbWFsbCBsaXN0cy4KLSAgICovCi0gIHB1YmxpYyBCb29sU3RhY2soKQotICB7Ci0gICAgdGhpcygzMik7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgSW50VmVjdG9yLCB1c2luZyB0aGUgZ2l2ZW4gYmxvY2sgc2l6ZS4KLSAgICoKLSAgICogQHBhcmFtIHNpemUgYXJyYXkgc2l6ZSB0byBhbGxvY2F0ZQotICAgKi8KLSAgcHVibGljIEJvb2xTdGFjayhpbnQgc2l6ZSkKLSAgewotCi0gICAgbV9hbGxvY2F0ZWRTaXplID0gc2l6ZTsKLSAgICBtX3ZhbHVlcyA9IG5ldyBib29sZWFuW3NpemVdOwotICAgIG1faW5kZXggPSAtMTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGxlbmd0aCBvZiB0aGUgbGlzdC4KLSAgICoKLSAgICogQHJldHVybiBDdXJyZW50IGxlbmd0aCBvZiB0aGUgbGlzdAotICAgKi8KLSAgcHVibGljIGZpbmFsIGludCBzaXplKCkKLSAgewotICAgIHJldHVybiBtX2luZGV4ICsgMTsKLSAgfQotCi0gIC8qKgotICAgKiBDbGVhcnMgdGhlIHN0YWNrLgotICAgKgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgY2xlYXIoKQotICB7Ci0gICAgICAgIG1faW5kZXggPSAtMTsKLSAgfQotCi0gIC8qKgotICAgKiBQdXNoZXMgYW4gaXRlbSBvbnRvIHRoZSB0b3Agb2YgdGhpcyBzdGFjay4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHZhbCB0aGUgYm9vbGVhbiB0byBiZSBwdXNoZWQgb250byB0aGlzIHN0YWNrLgotICAgKiBAcmV0dXJuICB0aGUgPGNvZGU+aXRlbTwvY29kZT4gYXJndW1lbnQuCi0gICAqLwotICBwdWJsaWMgZmluYWwgYm9vbGVhbiBwdXNoKGJvb2xlYW4gdmFsKQotICB7Ci0KLSAgICBpZiAobV9pbmRleCA9PSBtX2FsbG9jYXRlZFNpemUgLSAxKQotICAgICAgZ3JvdygpOwotCi0gICAgcmV0dXJuIChtX3ZhbHVlc1srK21faW5kZXhdID0gdmFsKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZW1vdmVzIHRoZSBvYmplY3QgYXQgdGhlIHRvcCBvZiB0aGlzIHN0YWNrIGFuZCByZXR1cm5zIHRoYXQKLSAgICogb2JqZWN0IGFzIHRoZSB2YWx1ZSBvZiB0aGlzIGZ1bmN0aW9uLgotICAgKgotICAgKiBAcmV0dXJuICAgICBUaGUgb2JqZWN0IGF0IHRoZSB0b3Agb2YgdGhpcyBzdGFjay4KLSAgICogQHRocm93cyAgRW1wdHlTdGFja0V4Y2VwdGlvbiAgaWYgdGhpcyBzdGFjayBpcyBlbXB0eS4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBib29sZWFuIHBvcCgpCi0gIHsKLSAgICByZXR1cm4gbV92YWx1ZXNbbV9pbmRleC0tXTsKLSAgfQotCi0gIC8qKgotICAgKiBSZW1vdmVzIHRoZSBvYmplY3QgYXQgdGhlIHRvcCBvZiB0aGlzIHN0YWNrIGFuZCByZXR1cm5zIHRoZQotICAgKiBuZXh0IG9iamVjdCBhdCB0aGUgdG9wIGFzIHRoZSB2YWx1ZSBvZiB0aGlzIGZ1bmN0aW9uLgotICAgKgotICAgKgotICAgKiBAcmV0dXJuIE5leHQgb2JqZWN0IHRvIHRoZSB0b3Agb3IgZmFsc2UgaWYgbm9uZSB0aGVyZQotICAgKi8KLSAgcHVibGljIGZpbmFsIGJvb2xlYW4gcG9wQW5kVG9wKCkKLSAgewotCi0gICAgbV9pbmRleC0tOwotCi0gICAgcmV0dXJuIChtX2luZGV4ID49IDApID8gbV92YWx1ZXNbbV9pbmRleF0gOiBmYWxzZTsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIGl0ZW0gYXQgdGhlIHRvcCBvZiB0aGlzIHN0YWNrCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBiIE9iamVjdCB0byBzZXQgYXQgdGhlIHRvcCBvZiB0aGlzIHN0YWNrCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBzZXRUb3AoYm9vbGVhbiBiKQotICB7Ci0gICAgbV92YWx1ZXNbbV9pbmRleF0gPSBiOwotICB9Ci0KLSAgLyoqCi0gICAqIExvb2tzIGF0IHRoZSBvYmplY3QgYXQgdGhlIHRvcCBvZiB0aGlzIHN0YWNrIHdpdGhvdXQgcmVtb3ZpbmcgaXQKLSAgICogZnJvbSB0aGUgc3RhY2suCi0gICAqCi0gICAqIEByZXR1cm4gICAgIHRoZSBvYmplY3QgYXQgdGhlIHRvcCBvZiB0aGlzIHN0YWNrLgotICAgKiBAdGhyb3dzICBFbXB0eVN0YWNrRXhjZXB0aW9uICBpZiB0aGlzIHN0YWNrIGlzIGVtcHR5LgotICAgKi8KLSAgcHVibGljIGZpbmFsIGJvb2xlYW4gcGVlaygpCi0gIHsKLSAgICByZXR1cm4gbV92YWx1ZXNbbV9pbmRleF07Ci0gIH0KLQotICAvKioKLSAgICogTG9va3MgYXQgdGhlIG9iamVjdCBhdCB0aGUgdG9wIG9mIHRoaXMgc3RhY2sgd2l0aG91dCByZW1vdmluZyBpdAotICAgKiBmcm9tIHRoZSBzdGFjay4gIElmIHRoZSBzdGFjayBpcyBlbXB0eSwgaXQgcmV0dXJucyBmYWxzZS4KLSAgICoKLSAgICogQHJldHVybiAgICAgdGhlIG9iamVjdCBhdCB0aGUgdG9wIG9mIHRoaXMgc3RhY2suCi0gICAqLwotICBwdWJsaWMgZmluYWwgYm9vbGVhbiBwZWVrT3JGYWxzZSgpCi0gIHsKLSAgICByZXR1cm4gKG1faW5kZXggPiAtMSkgPyBtX3ZhbHVlc1ttX2luZGV4XSA6IGZhbHNlOwotICB9Ci0KLSAgLyoqCi0gICAqIExvb2tzIGF0IHRoZSBvYmplY3QgYXQgdGhlIHRvcCBvZiB0aGlzIHN0YWNrIHdpdGhvdXQgcmVtb3ZpbmcgaXQKLSAgICogZnJvbSB0aGUgc3RhY2suICBJZiB0aGUgc3RhY2sgaXMgZW1wdHksIGl0IHJldHVybnMgdHJ1ZS4KLSAgICoKLSAgICogQHJldHVybiAgICAgdGhlIG9iamVjdCBhdCB0aGUgdG9wIG9mIHRoaXMgc3RhY2suCi0gICAqLwotICBwdWJsaWMgZmluYWwgYm9vbGVhbiBwZWVrT3JUcnVlKCkKLSAgewotICAgIHJldHVybiAobV9pbmRleCA+IC0xKSA/IG1fdmFsdWVzW21faW5kZXhdIDogdHJ1ZTsKLSAgfQotCi0gIC8qKgotICAgKiBUZXN0cyBpZiB0aGlzIHN0YWNrIGlzIGVtcHR5LgotICAgKgotICAgKiBAcmV0dXJuICA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGlzIHN0YWNrIGlzIGVtcHR5OwotICAgKiAgICAgICAgICA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNFbXB0eSgpCi0gIHsKLSAgICByZXR1cm4gKG1faW5kZXggPT0gLTEpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdyb3dzIHRoZSBzaXplIG9mIHRoZSBzdGFjawotICAgKgotICAgKi8KLSAgcHJpdmF0ZSB2b2lkIGdyb3coKQotICB7Ci0KLSAgICBtX2FsbG9jYXRlZFNpemUgKj0gMjsKLQotICAgIGJvb2xlYW4gbmV3VmVjdG9yW10gPSBuZXcgYm9vbGVhblttX2FsbG9jYXRlZFNpemVdOwotCi0gICAgU3lzdGVtLmFycmF5Y29weShtX3ZhbHVlcywgMCwgbmV3VmVjdG9yLCAwLCBtX2luZGV4ICsgMSk7Ci0KLSAgICBtX3ZhbHVlcyA9IG5ld1ZlY3RvcjsKLSAgfQotCi0gIHB1YmxpYyBPYmplY3QgY2xvbmUoKQotICAgIHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7Ci0gIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvQ2hhcktleS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvQ2hhcktleS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2NGM5NDA2Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL0NoYXJLZXkuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDg2ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IENoYXJLZXkuamF2YSx2IDEuMyAyMDA1LzA5LzI4IDEzOjQ5OjE4IHB2ZWR1bGEgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzOwotCi0vKioKLSAqIFNpbXBsZSBjbGFzcyBmb3IgZmFzdCBsb29rdXAgb2YgY2hhciB2YWx1ZXMsIHdoZW4gdXNlZCB3aXRoCi0gKiBoYXNodGFibGVzLiAgWW91IGNhbiBzZXQgdGhlIGNoYXIsIHRoZW4gdXNlIGl0IGFzIGEga2V5LgotICogQHhzbC51c2FnZSBpbnRlcm5hbAotICovCi1wdWJsaWMgY2xhc3MgQ2hhcktleSBleHRlbmRzIE9iamVjdAotewotCi0gIC8qKiBTdHJpbmcgdmFsdWUgICAgICAgICAgKi8KLSAgcHJpdmF0ZSBjaGFyIG1fY2hhcjsKLQotICAvKioKLSAgICogQ29uc3RydWN0b3IgQ2hhcktleQotICAgKgotICAgKiBAcGFyYW0ga2V5IGNoYXIgdmFsdWUgb2YgdGhpcyBvYmplY3QuCi0gICAqLwotICBwdWJsaWMgQ2hhcktleShjaGFyIGtleSkKLSAgewotICAgIG1fY2hhciA9IGtleTsKLSAgfQotCi0gIC8qKgotICAgKiBEZWZhdWx0IGNvbnN0cnVjdG9yIGZvciBhIENoYXJLZXkuCi0gICAqLwotICBwdWJsaWMgQ2hhcktleSgpCi0gIHsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGhhc2ggdmFsdWUgb2YgdGhlIGNoYXJhY3Rlci4KLSAgICoKLSAgICogQHJldHVybiBoYXNoIHZhbHVlIG9mIHRoZSBjaGFyYWN0ZXIuCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBzZXRDaGFyKGNoYXIgYykKLSAgewotICAgIG1fY2hhciA9IGM7Ci0gIH0KLQotCi0KLSAgLyoqCi0gICAqIEdldCB0aGUgaGFzaCB2YWx1ZSBvZiB0aGUgY2hhcmFjdGVyLgotICAgKgotICAgKiBAcmV0dXJuIGhhc2ggdmFsdWUgb2YgdGhlIGNoYXJhY3Rlci4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBpbnQgaGFzaENvZGUoKQotICB7Ci0gICAgcmV0dXJuIChpbnQpbV9jaGFyOwotICB9Ci0KLSAgLyoqCi0gICAqIE92ZXJyaWRlIG9mIGVxdWFscygpIGZvciB0aGlzIG9iamVjdAotICAgKgotICAgKiBAcGFyYW0gb2JqIHRvIGNvbXBhcmUgdG8KLSAgICoKLSAgICogQHJldHVybiBUcnVlIGlmIHRoaXMgb2JqZWN0IGVxdWFscyB0aGlzIHN0cmluZyB2YWx1ZQotICAgKi8KLSAgcHVibGljIGZpbmFsIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmopCi0gIHsKLSAgICByZXR1cm4gKChDaGFyS2V5KW9iaikubV9jaGFyID09IG1fY2hhcjsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvQ29uc3RhbnRzLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9Db25zdGFudHMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYzAyNzIzNC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9Db25zdGFudHMuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExNCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBDb25zdGFudHMuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNSAwODoxNTozNyBzdXJlc2hfZW1haWxpZCBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHM7Ci0KLS8qKgotICogUHJpbWFyeSBjb25zdGFudHMgdXNlZCBieSB0aGUgWFNMVCBQcm9jZXNzb3IKLSAqIEB4c2wudXNhZ2UgYWR2YW5jZWQKLSAqLwotcHVibGljIGNsYXNzIENvbnN0YW50cwotewotCi0gIC8qKgotICAgKiBNbmVtb25pY3MgZm9yIHN0YW5kYXJkIFhNTCBOYW1lc3BhY2UgVVJJcywgYXMgSmF2YSBTdHJpbmdzOgotICAgKiA8dWw+Ci0gICAqIDxsaT5TX1hNTE5BTUVTUEFDRVVSSSAoaHR0cDovL3d3dy53My5vcmcvWE1MLzE5OTgvbmFtZXNwYWNlKSBpcyB0aGUKLSAgICogVVJJIHBlcm1hbmFudGx5IGFzc2lnbmVkIHRvIHRoZSAieG1sOiIgcHJlZml4LiBUaGlzIGlzIHVzZWQgZm9yIHNvbWUKLSAgICogZmVhdHVyZXMgYnVpbHQgaW50byB0aGUgWE1MIHNwZWNpZmljYXRpb24gaXRzZWxmLCBzdWNoIGFzIHhtbDpzcGFjZQotICAgKiBhbmQgeG1sOmxhbmcuIEl0IHdhcyBkZWZpbmVkIGJ5IHRoZSBXM0MncyBYTUwgTmFtZXNwYWNlcyBzcGVjLjwvbGk+Ci0gICAqIDxsaT5TX1hTTE5BTUVTUEFDRVVSTCAoaHR0cDovL3d3dy53My5vcmcvMTk5OS9YU0wvVHJhbnNmb3JtKSBpcyB0aGUKLSAgICogVVJJIHdoaWNoIGluZGljYXRlcyB0aGF0IGEgbmFtZSBtYXkgYmUgYW4gWFNMVCBkaXJlY3RpdmUuIEluIG1vc3QKLSAgICogWFNMVCBzdHlsZXNoZWV0cywgdGhpcyBpcyBib3VuZCB0byB0aGUgInhzbDoiIHByZWZpeC4gSXQncyBkZWZpbmVkCi0gICAqIGJ5IHRoZSBXM0MncyBYU0xUIFJlY29tbWVuZGF0aW9uLjwvbGk+Ci0gICAqIDxsaT5TX09MRFhTTE5BTUVTUEFDRVVSTCAoaHR0cDovL3d3dy53My5vcmcvWFNML1RyYW5zZm9ybS8xLjApIHdhcwotICAgKiB1c2VkIGluIGVhcmx5IHByb3RvdHlwZXMgb2YgWFNMVCBwcm9jZXNzb3JzIGZvciBtdWNoIHRoZSBzYW1lIHB1cnBvc2UKLSAgICogYXMgU19YU0xOQU1FU1BBQ0VVUkwuIEl0IGlzIG5vdyBjb25zaWRlcmVkIG9ic29sZXRlLCBhbmQgdGhlIHZlcnNpb24KLSAgICogb2YgWFNMVCB3aGljaCBpdCBzaWduaWZpZWQgaXMgbm90IGZ1bGx5IGNvbXBhdGFibGUgd2l0aCB0aGUgZmluYWwKLSAgICogWFNMVCBSZWNvbW1lbmRhdGlvbiwgc28gd2hhdCBpdCByZWFsbHkgc2lnbmlmaWVzIGlzIGEgYmFkbHkgb2Jzb2xldGUKLSAgICogc3R5bGVzaGVldC48L2xpPgotICAgKiA8L3VsPiAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZwotICAgICAgICBTX1hNTE5BTUVTUEFDRVVSSSA9ICJodHRwOi8vd3d3LnczLm9yZy9YTUwvMTk5OC9uYW1lc3BhY2UiLAotICAgICAgICBTX1hTTE5BTUVTUEFDRVVSTCA9ICJodHRwOi8vd3d3LnczLm9yZy8xOTk5L1hTTC9UcmFuc2Zvcm0iLAotICAgICAgICBTX09MRFhTTE5BTUVTUEFDRVVSTCA9ICJodHRwOi8vd3d3LnczLm9yZy9YU0wvVHJhbnNmb3JtLzEuMCI7Ci0KLSAgLyoqIEF1dGhvcnNoaXAgbW5lbW9uaWNzLCBhcyBKYXZhIFN0cmluZ3MuIE5vdCBzdGFuZGFyZGl6ZWQsCi0gICAqIGFzIGZhciBhcyBJIGtub3cuCi0gICAqIDx1bD4KLSAgICogPGxpPlNfVkVORE9SIC0tIHRoZSBuYW1lIG9mIHRoZSBvcmdhbml6YXRpb24vaW5kaXZpZHVhbCB3aG8gcHVibGlzaGVkCi0gICAqIHRoaXMgWFNMVCBwcm9jZXNzb3IuIDwvbGk+Ci0gICAqIDxsaT5TX1ZFTkRPUlVSTCAtLSBVUkwgd2hlcmUgb25lIGNhbiBhdHRlbXB0IHRvIHJldHJpZXZlIG1vcmUKLSAgICogaW5mb3JtYXRpb24gYWJvdXQgdGhpcyBwdWJsaXNoZXIgYW5kIHByb2R1Y3QuPC9saT4KLSAgICogPC91bD4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nCi0gICAgICAgIFNfVkVORE9SID0gIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiwKLSAgICAgICAgU19WRU5ET1JVUkwgPSAiaHR0cDovL3htbC5hcGFjaGUub3JnIjsKLQotICAvKiogU19CVUlMVElOX0VYVEVOU0lPTlNfVVJMIGlzIGEgbW5lbW9uaWMgZm9yIHRoZSBYTUwgTmFtZXNwYWNlCi0gICAqKGh0dHA6Ly94bWwuYXBhY2hlLm9yZy94YWxhbikgcHJlZGVmaW5lZCB0byBzaWduaWZ5IFhhbGFuJ3MKLSAgICogYnVpbHQtaW4gWFNMVCBFeHRlbnNpb25zLiBXaGVuIHVzZWQgaW4gc3R5bGVzaGVldHMsIHRoaXMgaXMgb2Z0ZW4KLSAgICogYm91bmQgdG8gdGhlICJ4YWxhbjoiIHByZWZpeC4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nCi0gICAgU19CVUlMVElOX0VYVEVOU0lPTlNfVVJMID0gImh0dHA6Ly94bWwuYXBhY2hlLm9yZy94YWxhbiI7Ci0KLSAgLyoqCi0gICAqIFRoZSBvbGQgYnVpbHQtaW4gZXh0ZW5zaW9uIHVybC4gSXQgaXMgc3RpbGwgc3VwcG9ydGVkIGZvcgotICAgKiBiYWNrd2FyZCBjb21wYXRpYmlsaXR5LgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcKLSAgICBTX0JVSUxUSU5fT0xEX0VYVEVOU0lPTlNfVVJMID0gImh0dHA6Ly94bWwuYXBhY2hlLm9yZy94c2x0IjsKLQotICAvKioKLSAgICogWGFsYW4gZXh0ZW5zaW9uIG5hbWVzcGFjZXMuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZwotICAgIC8vIFRoZSBvbGQgbmFtZXNwYWNlIGZvciBKYXZhIGV4dGVuc2lvbgotICAgIFNfRVhURU5TSU9OU19PTERfSkFWQV9VUkwgPSAiaHR0cDovL3htbC5hcGFjaGUub3JnL3hzbHQvamF2YSIsCi0gICAgLy8gVGhlIG5ldyBuYW1lc3BhY2UgZm9yIEphdmEgZXh0ZW5zaW9uCi0gICAgU19FWFRFTlNJT05TX0pBVkFfVVJMID0gImh0dHA6Ly94bWwuYXBhY2hlLm9yZy94YWxhbi9qYXZhIiwKLSAgICBTX0VYVEVOU0lPTlNfTE9UVVNYU0xfSkFWQV9VUkwgPSAiaHR0cDovL3hzbC5sb3R1cy5jb20vamF2YSIsCi0gICAgU19FWFRFTlNJT05TX1hBTEFOTElCX1VSTCA9ICJodHRwOi8veG1sLmFwYWNoZS5vcmcveGFsYW4iLAotICAgIFNfRVhURU5TSU9OU19SRURJUkVDVF9VUkwgPSAiaHR0cDovL3htbC5hcGFjaGUub3JnL3hhbGFuL3JlZGlyZWN0IiwKLSAgICBTX0VYVEVOU0lPTlNfUElQRV9VUkwgPSAiaHR0cDovL3htbC5hcGFjaGUub3JnL3hhbGFuL1BpcGVEb2N1bWVudCIsCi0gICAgU19FWFRFTlNJT05TX1NRTF9VUkwgPSAiaHR0cDovL3htbC5hcGFjaGUub3JnL3hhbGFuL3NxbCI7Ci0KLSAgLyoqCi0gICAqIEVYU0xUIGV4dGVuc2lvbiBuYW1lc3BhY2VzLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcKLSAgICBTX0VYU0xUX0NPTU1PTl9VUkwgPSAiaHR0cDovL2V4c2x0Lm9yZy9jb21tb24iLAotICAgIFNfRVhTTFRfTUFUSF9VUkwgPSAiaHR0cDovL2V4c2x0Lm9yZy9tYXRoIiwKLSAgICBTX0VYU0xUX1NFVFNfVVJMID0gImh0dHA6Ly9leHNsdC5vcmcvc2V0cyIsCi0gICAgU19FWFNMVF9EQVRFVElNRV9VUkwgPSAiaHR0cDovL2V4c2x0Lm9yZy9kYXRlcy1hbmQtdGltZXMiLAotICAgIFNfRVhTTFRfRlVOQ1RJT05TX1VSTCA9ICJodHRwOi8vZXhzbHQub3JnL2Z1bmN0aW9ucyIsCi0gICAgU19FWFNMVF9EWU5BTUlDX1VSTCA9ICJodHRwOi8vZXhzbHQub3JnL2R5bmFtaWMiLAotICAgIFNfRVhTTFRfU1RSSU5HU19VUkwgPSAiaHR0cDovL2V4c2x0Lm9yZy9zdHJpbmdzIjsKLQotCi0gIC8qKgotICAgKiBUaGUgbWluaW11bSB2ZXJzaW9uIG9mIFhTTFQgc3VwcG9ydGVkIGJ5IHRoaXMgcHJvY2Vzc29yLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBkb3VibGUgWFNMVFZFUlNVUFBPUlRFRCA9IDEuMDsKLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL0RPTTJIZWxwZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL0RPTTJIZWxwZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYzIzZjA4ZS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9ET00ySGVscGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzMTYgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRE9NMkhlbHBlci5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE1IDA4OjE1OjM3IHN1cmVzaF9lbWFpbGlkIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlsczsKLQotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci0KLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXI7Ci1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy5QYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5BdHRyOwotaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLkVsZW1lbnQ7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLQotaW1wb3J0IG9yZy54bWwuc2F4LklucHV0U291cmNlOwotCi0vKioKLSAqIEBkZXByZWNhdGVkIFNpbmNlIHRoZSBpbnRyb2R1Y3Rpb24gb2YgdGhlIERUTSwgdGhpcyBjbGFzcyB3aWxsIGJlIHJlbW92ZWQuCi0gKiBUaGlzIGNsYXNzIHByb3ZpZGVzIGEgRE9NIGxldmVsIDIgImhlbHBlciIsIHdoaWNoIHByb3ZpZGVzIHNlcnZpY2VzIGN1cnJlbnRseQotICogbm90IHByb3ZpZGVkIGJlIHRoZSBET00gc3RhbmRhcmQuCi0gKi8KLXB1YmxpYyBjbGFzcyBET00ySGVscGVyIGV4dGVuZHMgRE9NSGVscGVyCi17Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhbiBpbnN0YW5jZS4KLSAgICovCi0gIHB1YmxpYyBET00ySGVscGVyKCl7fQotCi0gIC8qKgotICAgKiBDaGVjayBub2RlIHRvIHNlZSBpZiBpdCB3YXMgY3JlYXRlZCBieSBhIERPTSBpbXBsZW1lbnRhdGlvbgotICAgKiB0aGF0IHRoaXMgaGVscGVyIGlzIGludGVuZGVkIHRvIHN1cHBvcnQuIFRoaXMgaXMgY3VycmVudGx5Ci0gICAqIGRpc2FibGVkLCBhbmQgYXNzdW1lcyBhbGwgbm9kZXMgYXJlIGFjY2VwdGFibGUgcmF0aGVyIHRoYW4gY2hlY2tpbmcKLSAgICogdGhhdCB0aGV5IGltcGxlbWVudCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbS5Ob2RlSW1wbC4KLSAgICoKLSAgICogQHBhcmFtIG5vZGUgVGhlIG5vZGUgdG8gYmUgdGVzdGVkLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uIGlmIHRoZSBub2RlIGlzIG5vdCBvbmUgd2hpY2ggdGhpcwotICAgKiBET00ySGVscGVyIGNhbiBzdXBwb3J0LiBJZiB3ZSByZXR1cm4gd2l0aG91dCB0aHJvd2luZyB0aGUgZXhjZXB0aW9uLAotICAgKiB0aGUgbm9kZSBpcyBjb21wYXRhYmxlLgotICAgKiBAeHNsLnVzYWdlIGludGVybmFsCi0gICAqLwotICBwdWJsaWMgdm9pZCBjaGVja05vZGUoTm9kZSBub2RlKSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgLy8gaWYoIShub2RlIGluc3RhbmNlb2YgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5kb20uTm9kZUltcGwpKQotICAgIC8vICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfWEVSQ0VTX0NBTk5PVF9IQU5ETEVfTk9ERVMsIG5ldyBPYmplY3RbXXsoKE9iamVjdClub2RlKS5nZXRDbGFzcygpfSkpOyAvLyJET00ySGVscGVyIGNhbiBub3QgaGFuZGxlIG5vZGVzIG9mIHR5cGUiCi0gICAgLy8rKChPYmplY3Qpbm9kZSkuZ2V0Q2xhc3MoKSk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBET00gaW1wbGVtZW50YXRpb24gaGFuZGxlZCBieSB0aGlzIGhlbHBlcgotICAgKiBzdXBwb3J0cyB0aGUgU0FYIENvbnRlbnRIYW5kbGVyIGludGVyZmFjZS4KLSAgICoKLSAgICogQHJldHVybiB0cnVlIChzaW5jZSBYZXJjZXMgZG9lcykuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBzdXBwb3J0c1NBWCgpCi0gIHsKLSAgICByZXR1cm4gdHJ1ZTsKLSAgfQotCi0gIC8qKiBGaWVsZCBtX2RvYzogRG9jdW1lbnQgTm9kZSBmb3IgdGhlIGRvY3VtZW50IHRoaXMgaGVscGVyIGlzIGN1cnJlbnRseQotICAgKiBhY2Nlc3Npbmcgb3IgYnVpbGRpbmcKLSAgICogQHNlZSAjc2V0RG9jdW1lbnQKLSAgICogQHNlZSAjZ2V0RG9jdW1lbnQKLSAgICogICovCi0gIHByaXZhdGUgRG9jdW1lbnQgbV9kb2M7Ci0KLSAgLyoqCi0gICAqIFNwZWNpZnkgd2hpY2ggZG9jdW1lbnQgdGhpcyBoZWxwZXIgaXMgY3VycmVudGx5IG9wZXJhdGluZyBvbi4KLSAgICoKLSAgICogQHBhcmFtIGRvYyBUaGUgRE9NIERvY3VtZW50IG5vZGUgZm9yIHRoaXMgZG9jdW1lbnQuCi0gICAqIEBzZWUgI2dldERvY3VtZW50Ci0gICAqLwotICBwdWJsaWMgdm9pZCBzZXREb2N1bWVudChEb2N1bWVudCBkb2MpCi0gIHsKLSAgICBtX2RvYyA9IGRvYzsKLSAgfQotCi0gIC8qKgotICAgKiBRdWVyeSB3aGljaCBkb2N1bWVudCB0aGlzIGhlbHBlciBpcyBjdXJyZW50bHkgb3BlcmF0aW5nIG9uLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBET00gRG9jdW1lbnQgbm9kZSBmb3IgdGhpcyBkb2N1bWVudC4KLSAgICogQHNlZSAjc2V0RG9jdW1lbnQKLSAgICovCi0gIHB1YmxpYyBEb2N1bWVudCBnZXREb2N1bWVudCgpCi0gIHsKLSAgICByZXR1cm4gbV9kb2M7Ci0gIH0KLQotICAvKioKLSAgICogUGFyc2UgYW4gWE1MIGRvY3VtZW50LgotICAgKgotICAgKiA8cD5SaWdodCBub3cgdGhlIFhlcmNlcyBET01QYXJzZXIgY2xhc3MgaXMgdXNlZC4gIFRoaXMgbmVlZHMKLSAgICogZml4aW5nLCBlaXRoZXIgdmlhIGpheHAsIG9yIHZpYSBzb21lIG90aGVyLCBzdGFuZGFyZCBtZXRob2QuPC9wPgotICAgKgotICAgKiA8cD5UaGUgYXBwbGljYXRpb24gY2FuIHVzZSB0aGlzIG1ldGhvZCB0byBpbnN0cnVjdCB0aGUgU0FYIHBhcnNlcgotICAgKiB0byBiZWdpbiBwYXJzaW5nIGFuIFhNTCBkb2N1bWVudCBmcm9tIGFueSB2YWxpZCBpbnB1dAotICAgKiBzb3VyY2UgKGEgY2hhcmFjdGVyIHN0cmVhbSwgYSBieXRlIHN0cmVhbSwgb3IgYSBVUkkpLjwvcD4KLSAgICoKLSAgICogPHA+QXBwbGljYXRpb25zIG1heSBub3QgaW52b2tlIHRoaXMgbWV0aG9kIHdoaWxlIGEgcGFyc2UgaXMgaW4KLSAgICogcHJvZ3Jlc3MgKHRoZXkgc2hvdWxkIGNyZWF0ZSBhIG5ldyBQYXJzZXIgaW5zdGVhZCBmb3IgZWFjaAotICAgKiBhZGRpdGlvbmFsIFhNTCBkb2N1bWVudCkuICBPbmNlIGEgcGFyc2UgaXMgY29tcGxldGUsIGFuCi0gICAqIGFwcGxpY2F0aW9uIG1heSByZXVzZSB0aGUgc2FtZSBQYXJzZXIgb2JqZWN0LCBwb3NzaWJseSB3aXRoIGEKLSAgICogZGlmZmVyZW50IGlucHV0IHNvdXJjZS48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBzb3VyY2UgVGhlIGlucHV0IHNvdXJjZSBmb3IgdGhlIHRvcC1sZXZlbCBvZiB0aGUKLSAgICogICAgICAgIFhNTCBkb2N1bWVudC4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBpZiBhbnkgY2hlY2tlZCBleGNlcHRpb24gaXMgdGhyb3duLgotICAgKiBAeHNsLnVzYWdlIGludGVybmFsCi0gICAqLwotICBwdWJsaWMgdm9pZCBwYXJzZShJbnB1dFNvdXJjZSBzb3VyY2UpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICB0cnkKLSAgICB7Ci0KLSAgICAgIC8vIEkgZ3Vlc3MgSSBzaG91bGQgdXNlIEpBWFAgZmFjdG9yeSBoZXJlLi4uIHdoZW4gaXQncyBsZWdhbC4KLSAgICAgIC8vIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwucGFyc2Vycy5ET01QYXJzZXIgcGFyc2VyCi0gICAgICAvLyAgPSBuZXcgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5wYXJzZXJzLkRPTVBhcnNlcigpOwotICAgICAgRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBidWlsZGVyRmFjdG9yeSA9Ci0gICAgICAgIERvY3VtZW50QnVpbGRlckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKLQotICAgICAgYnVpbGRlckZhY3Rvcnkuc2V0TmFtZXNwYWNlQXdhcmUodHJ1ZSk7Ci0gICAgICBidWlsZGVyRmFjdG9yeS5zZXRWYWxpZGF0aW5nKHRydWUpOwotCi0gICAgICBEb2N1bWVudEJ1aWxkZXIgcGFyc2VyID0gYnVpbGRlckZhY3RvcnkubmV3RG9jdW1lbnRCdWlsZGVyKCk7Ci0KLSAgICAgIC8qCi0gICAgICAvLyBkb21QYXJzZXIuc2V0RmVhdHVyZSgiaHR0cDovL2FwYWNoZS5vcmcveG1sL2ZlYXR1cmVzL2RvbS9jcmVhdGUtZW50aXR5LXJlZi1ub2RlcyIsIGdldFNob3VsZEV4cGFuZEVudGl0eVJlZnMoKT8gZmFsc2UgOiB0cnVlKTsKLSAgICAgIGlmKG1fdXNlRE9NMmdldE5hbWVzcGFjZVVSSSkKLSAgICAgIHsKLSAgICAgIHBhcnNlci5zZXRGZWF0dXJlKCJodHRwOi8vYXBhY2hlLm9yZy94bWwvZmVhdHVyZXMvZG9tL2RlZmVyLW5vZGUtZXhwYW5zaW9uIiwgdHJ1ZSk7Ci0gICAgICBwYXJzZXIuc2V0RmVhdHVyZSgiaHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL25hbWVzcGFjZXMiLCB0cnVlKTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgIHBhcnNlci5zZXRGZWF0dXJlKCJodHRwOi8vYXBhY2hlLm9yZy94bWwvZmVhdHVyZXMvZG9tL2RlZmVyLW5vZGUtZXhwYW5zaW9uIiwgZmFsc2UpOwotICAgICAgfQotCi0gICAgICBwYXJzZXIuc2V0RmVhdHVyZSgiaHR0cDovL2FwYWNoZS5vcmcveG1sL2ZlYXR1cmVzL2FsbG93LWphdmEtZW5jb2RpbmdzIiwgdHJ1ZSk7Ci0gICAgICAqLwotCi0gICAgICBwYXJzZXIuc2V0RXJyb3JIYW5kbGVyKAotICAgICAgICBuZXcgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5EZWZhdWx0RXJyb3JIYW5kbGVyKCkpOwotCi0gICAgICAvLyBpZihudWxsICE9IG1fZW50aXR5UmVzb2x2ZXIpCi0gICAgICAvLyB7Ci0gICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIlNldHRpbmcgdGhlIGVudGl0eSByZXNvbHZlci4iKTsKLSAgICAgIC8vICBwYXJzZXIuc2V0RW50aXR5UmVzb2x2ZXIobV9lbnRpdHlSZXNvbHZlcik7Ci0gICAgICAvLyB9Ci0gICAgICBzZXREb2N1bWVudChwYXJzZXIucGFyc2Uoc291cmNlKSk7Ci0gICAgfQotICAgIGNhdGNoIChvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gc2UpCi0gICAgewotICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKHNlKTsKLSAgICB9Ci0gICAgY2F0Y2ggKFBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gcGNlKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihwY2UpOwotICAgIH0KLSAgICBjYXRjaCAoSU9FeGNlcHRpb24gaW9lKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihpb2UpOwotICAgIH0KLQotICAgIC8vIHNldERvY3VtZW50KCgoY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5wYXJzZXJzLkRPTVBhcnNlcilwYXJzZXIpLmdldERvY3VtZW50KCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGFuIFhNTCBJRCwgcmV0dXJuIHRoZSBlbGVtZW50LiBUaGlzIHJlcXVpcmVzIGFzc2lzdGFuY2UgZnJvbSB0aGUKLSAgICogRE9NIGFuZCBwYXJzZXIsIGFuZCBpcyBtZWFuaW5nZnVsIG9ubHkgaW4gdGhlIGNvbnRleHQgb2YgYSBEVEQKLSAgICogb3Igc2NoZW1hIHdoaWNoIGRlY2xhcmVzIGF0dHJpYnV0ZXMgYXMgYmVpbmcgb2YgdHlwZSBJRC4gVGhpcwotICAgKiBpbmZvcm1hdGlvbiBtYXkgb3IgbWF5IG5vdCBiZSBhdmFpbGFibGUgaW4gYWxsIHBhcnNlcnMsIG1heSBvcgotICAgKiBtYXkgbm90IGJlIGF2YWlsYWJsZSBmb3Igc3BlY2lmaWMgZG9jdW1lbnRzLCBhbmQgbWF5IG9yIG1heSBub3QKLSAgICogYmUgYXZhaWxhYmxlIHdoZW4gdmFsaWRhdGlvbiBpcyBub3QgdHVybmVkIG9uLgotICAgKgotICAgKiBAcGFyYW0gaWQgVGhlIElEIHRvIHNlYXJjaCBmb3IsIGFzIGEgU3RyaW5nLgotICAgKiBAcGFyYW0gZG9jIFRoZSBkb2N1bWVudCB0byBzZWFyY2ggd2l0aGluLCBhcyBhIERPTSBEb2N1bWVudCBub2RlLgotICAgKiBAcmV0dXJuIERPTSBFbGVtZW50IG5vZGUgd2l0aCBhbiBhdHRyaWJ1dGUgb2YgdHlwZSBJRCB3aG9zZSB2YWx1ZQotICAgKiB1bmlxdWVseSBtYXRjaGVzIHRoZSByZXF1ZXN0ZWQgaWQgc3RyaW5nLCBvciBudWxsIGlmIHRoZXJlIGlzbid0Ci0gICAqIHN1Y2ggYW4gZWxlbWVudCBvciBpZiB0aGUgRE9NIGNhbid0IGFuc3dlciB0aGUgcXVlc3Rpb24gZm9yIG90aGVyCi0gICAqIHJlYXNvbnMuCi0gICAqLwotICBwdWJsaWMgRWxlbWVudCBnZXRFbGVtZW50QnlJRChTdHJpbmcgaWQsIERvY3VtZW50IGRvYykKLSAgewotICAgIHJldHVybiBkb2MuZ2V0RWxlbWVudEJ5SWQoaWQpOwotICB9Ci0KLSAgLyoqCi0gICAqIEZpZ3VyZSBvdXQgd2hldGhlciBub2RlMiBzaG91bGQgYmUgY29uc2lkZXJlZCBhcyBiZWluZyBsYXRlcgotICAgKiBpbiB0aGUgZG9jdW1lbnQgdGhhbiBub2RlMSwgaW4gRG9jdW1lbnQgT3JkZXIgYXMgZGVmaW5lZAotICAgKiBieSB0aGUgWFBhdGggbW9kZWwuIFRoaXMgbWF5IG5vdCBhZ3JlZSB3aXRoIHRoZSBvcmRlcmluZyBkZWZpbmVkCi0gICAqIGJ5IG90aGVyIFhNTCBhcHBsaWNhdGlvbnMuCi0gICAqIDxwPgotICAgKiBUaGVyZSBhcmUgc29tZSBjYXNlcyB3aGVyZSBvcmRlcmluZyBpc24ndCBkZWZpbmVkLCBhbmQgbmVpdGhlciBhcmUKLSAgICogdGhlIHJlc3VsdHMgb2YgdGhpcyBmdW5jdGlvbiAtLSB0aG91Z2ggd2UnbGwgZ2VuZXJhbGx5IHJldHVybiB0cnVlLgotICAgKiA8cD4KLSAgICogVE9ETzogTWFrZSBzdXJlIHRoaXMgZG9lcyB0aGUgcmlnaHQgdGhpbmcgd2l0aCBhdHRyaWJ1dGUgbm9kZXMhISEKLSAgICoKLSAgICogQHBhcmFtIG5vZGUxIERPTSBOb2RlIHRvIHBlcmZvcm0gcG9zaXRpb24gY29tcGFyaXNvbiBvbi4KLSAgICogQHBhcmFtIG5vZGUyIERPTSBOb2RlIHRvIHBlcmZvcm0gcG9zaXRpb24gY29tcGFyaXNvbiBvbiAuCi0gICAqCi0gICAqIEByZXR1cm4gZmFsc2UgaWYgbm9kZTIgY29tZXMgYmVmb3JlIG5vZGUxLCBvdGhlcndpc2UgcmV0dXJuIHRydWUuCi0gICAqIFlvdSBjYW4gdGhpbmsgb2YgdGhpcyBhcwotICAgKiA8Y29kZT4obm9kZTEuZG9jdW1lbnRPcmRlclBvc2l0aW9uICZsdDs9IG5vZGUyLmRvY3VtZW50T3JkZXJQb3NpdGlvbik8L2NvZGU+LgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzTm9kZUFmdGVyKE5vZGUgbm9kZTEsIE5vZGUgbm9kZTIpCi0gIHsKLQotICAgIC8vIEFzc3VtZSBmaXJzdCB0aGF0IHRoZSBub2RlcyBhcmUgRFRNIG5vZGVzLCBzaW5jZSBkaXNjb3ZlcmluZyBub2RlCi0gICAgLy8gb3JkZXIgaXMgbWFzc2l2bHkgZmFzdGVyIGZvciB0aGUgRFRNLgotICAgIGlmKG5vZGUxIGluc3RhbmNlb2YgRE9NT3JkZXIgJiYgbm9kZTIgaW5zdGFuY2VvZiBET01PcmRlcikKLSAgICB7Ci0gICAgICBpbnQgaW5kZXgxID0gKChET01PcmRlcikgbm9kZTEpLmdldFVpZCgpOwotICAgICAgaW50IGluZGV4MiA9ICgoRE9NT3JkZXIpIG5vZGUyKS5nZXRVaWQoKTsKLQotICAgICAgcmV0dXJuIGluZGV4MSA8PSBpbmRleDI7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0KLSAgICAgIC8vIGlzTm9kZUFmdGVyIHdpbGwgcmV0dXJuIHRydWUgaWYgbm9kZSBpcyBhZnRlciBjb3VudGVkTm9kZQotICAgICAgLy8gaW4gZG9jdW1lbnQgb3JkZXIuIFRoZSBiYXNlIGlzTm9kZUFmdGVyIGlzIHNsb29vb3cgKHJlbGF0aXZlbHkpLgotICAgICAgcmV0dXJuIERPTUhlbHBlci5pc05vZGVBZnRlcihub2RlMSwgbm9kZTIpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIFhQYXRoLW1vZGVsIHBhcmVudCBvZiBhIG5vZGUuICBUaGlzIHZlcnNpb24gdGFrZXMgYWR2YW50YWdlCi0gICAqIG9mIHRoZSBET00gTGV2ZWwgMiBBdHRyLm93bmVyRWxlbWVudCgpIG1ldGhvZDsgdGhlIGJhc2UgdmVyc2lvbiB3ZQotICAgKiB3b3VsZCBvdGhlcndpc2UgaW5oZXJpdCBpcyBwcmVwYXJlZCB0byBmYWxsIGJhY2sgb24gZXhoYXVzdGl2ZWx5Ci0gICAqIHdhbGtpbmcgdGhlIGRvY3VtZW50IHRvIGZpbmQgYW4gQXR0cidzIHBhcmVudC4KLSAgICoKLSAgICogQHBhcmFtIG5vZGUgTm9kZSB0byBiZSBleGFtaW5lZAotICAgKgotICAgKiBAcmV0dXJuIHRoZSBET00gcGFyZW50IG9mIHRoZSBpbnB1dCBub2RlLCBpZiB0aGVyZSBpcyBvbmUsIG9yIHRoZQotICAgKiBvd25lckVsZW1lbnQgaWYgdGhlIGlucHV0IG5vZGUgaXMgYW4gQXR0ciwgb3IgbnVsbCBpZiB0aGUgbm9kZSBpcwotICAgKiBhIERvY3VtZW50LCBhIERvY3VtZW50RnJhZ21lbnQsIG9yIGFuIG9ycGhhbi4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgTm9kZSBnZXRQYXJlbnRPZk5vZGUoTm9kZSBub2RlKQotICB7Ci0gICAgICAgICAgTm9kZSBwYXJlbnQ9bm9kZS5nZXRQYXJlbnROb2RlKCk7Ci0gICAgICAgICAgaWYocGFyZW50PT1udWxsICYmIChOb2RlLkFUVFJJQlVURV9OT0RFID09IG5vZGUuZ2V0Tm9kZVR5cGUoKSkgKQotICAgICAgICAgICBwYXJlbnQ9KChBdHRyKSBub2RlKS5nZXRPd25lckVsZW1lbnQoKTsKLSAgICAgICAgICByZXR1cm4gcGFyZW50OwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIGxvY2FsIG5hbWUgb2YgdGhlIGdpdmVuIG5vZGUsIGFzIGRlZmluZWQgYnkgdGhlCi0gICAqIFhNTCBOYW1lc3BhY2VzIHNwZWNpZmljYXRpb24uIFRoaXMgaXMgcHJlcGFyZWQgdG8gaGFuZGxlIGRvY3VtZW50cwotICAgKiBidWlsdCB1c2luZyBET00gTGV2ZWwgMSBtZXRob2RzIGJ5IGZhbGxpbmcgYmFjayB1cG9uIGV4cGxpY2l0bHkKLSAgICogcGFyc2luZyB0aGUgbm9kZSBuYW1lLgotICAgKgotICAgKiBAcGFyYW0gbiBOb2RlIHRvIGJlIGV4YW1pbmVkCi0gICAqCi0gICAqIEByZXR1cm4gU3RyaW5nIGNvbnRhaW5pbmcgdGhlIGxvY2FsIG5hbWUsIG9yIG51bGwgaWYgdGhlIG5vZGUKLSAgICogd2FzIG5vdCBhc3NpZ25lZCBhIE5hbWVzcGFjZS4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0TG9jYWxOYW1lT2ZOb2RlKE5vZGUgbikKLSAgewotCi0gICAgU3RyaW5nIG5hbWUgPSBuLmdldExvY2FsTmFtZSgpOwotCi0gICAgcmV0dXJuIChudWxsID09IG5hbWUpID8gc3VwZXIuZ2V0TG9jYWxOYW1lT2ZOb2RlKG4pIDogbmFtZTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBOYW1lc3BhY2UgTmFtZSAoTmFtZXNwYWNlIFVSSSkgZm9yIHRoZSBnaXZlbiBub2RlLgotICAgKiBJbiBhIExldmVsIDIgRE9NLCB5b3UgY2FuIGFzayB0aGUgbm9kZSBpdHNlbGYuIE5vdGUsIGhvd2V2ZXIsIHRoYXQKLSAgICogZG9pbmcgc28gY29uZmxpY3RzIHdpdGggb3VyIGRlY2lzaW9uIGluIGdldExvY2FsTmFtZU9mTm9kZSBub3QKLSAgICogdG8gdHJ1c3QgdGhlIHRoYXQgdGhlIERPTSB3YXMgaW5kZWVkIGNyZWF0ZWQgdXNpbmcgdGhlIExldmVsIDIKLSAgICogbWV0aG9kcy4gSWYgTGV2ZWwgMSBtZXRob2RzIHdlcmUgdXNlZCwgdGhlc2UgdHdvIGZ1bmN0aW9ucyB3aWxsCi0gICAqIGRpc2FncmVlIHdpdGggZWFjaCBvdGhlci4KLSAgICogPHA+Ci0gICAqIFRPRE86IFJlY29uY2lsZSB3aXRoIGdldExvY2FsTmFtZU9mTm9kZS4KLSAgICoKLSAgICogQHBhcmFtIG4gTm9kZSB0byBiZSBleGFtaW5lZAotICAgKgotICAgKiBAcmV0dXJuIFN0cmluZyBjb250YWluaW5nIHRoZSBOYW1lc3BhY2UgVVJJIGJvdW5kIHRvIHRoaXMgRE9NIG5vZGUKLSAgICogYXQgdGhlIHRpbWUgdGhlIE5vZGUgd2FzIGNyZWF0ZWQuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldE5hbWVzcGFjZU9mTm9kZShOb2RlIG4pCi0gIHsKLSAgICByZXR1cm4gbi5nZXROYW1lc3BhY2VVUkkoKTsKLSAgfQotCi0gIC8qKiBGaWVsZCBtX3VzZURPTTJnZXROYW1lc3BhY2VVUkkgaXMgYSBjb21waWxlLXRpbWUgZmxhZyB3aGljaAotICAgKiAgZ2F0ZXMgc29tZSBvZiB0aGUgcGFyc2VyIG9wdGlvbnMgdXNlZCB0byBidWlsZCBhIERPTSAtLSBidXQKLSAgICogdGhhdCBjb2RlIGlzIGNvbW1lbnRlZCBvdXQgYXQgdGhpcyB0aW1lIGFuZCBub2JvZHkgZWxzZQotICAgKiByZWZlcmVuY2VzIGl0LCBzbyBJJ3ZlIGNvbW1lbnRlZCB0aGlzIG91dCBhcyB3ZWxsLiAqLwotICAvL3ByaXZhdGUgYm9vbGVhbiBtX3VzZURPTTJnZXROYW1lc3BhY2VVUkkgPSBmYWxzZTsKLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL0RPTUJ1aWxkZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL0RPTUJ1aWxkZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOWRhZGFjOS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9ET01CdWlsZGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3OTAgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRE9NQnVpbGRlci5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE1IDA4OjE1OjM5IHN1cmVzaF9lbWFpbGlkIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlsczsKLQotaW1wb3J0IGphdmEudXRpbC5TdGFjazsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzLlhNTEVycm9yUmVzb3VyY2VzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzLlhNTE1lc3NhZ2VzOwotCi1pbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7Ci1pbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnRGcmFnbWVudDsKLWltcG9ydCBvcmcudzNjLmRvbS5FbGVtZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci1pbXBvcnQgb3JnLnczYy5kb20uVGV4dDsKLWltcG9ydCBvcmcudzNjLmRvbS5DREFUQVNlY3Rpb247Ci0KLWltcG9ydCBvcmcueG1sLnNheC5BdHRyaWJ1dGVzOwotaW1wb3J0IG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LkxvY2F0b3I7Ci1pbXBvcnQgb3JnLnhtbC5zYXguZXh0LkxleGljYWxIYW5kbGVyOwotLyoqCi0gKiBUaGlzIGNsYXNzIHRha2VzIFNBWCBldmVudHMgKGluIGFkZGl0aW9uIHRvIHNvbWUgZXh0cmEgZXZlbnRzCi0gKiB0aGF0IFNBWCBkb2Vzbid0IGhhbmRsZSB5ZXQpIGFuZCBhZGRzIHRoZSByZXN1bHQgdG8gYSBkb2N1bWVudAotICogb3IgZG9jdW1lbnQgZnJhZ21lbnQuCi0gKiBAeHNsLnVzYWdlIGdlbmVyYWwKLSAqLwotcHVibGljIGNsYXNzIERPTUJ1aWxkZXIKLSAgICAgICAgaW1wbGVtZW50cyBDb250ZW50SGFuZGxlciwgTGV4aWNhbEhhbmRsZXIKLXsKLQotICAvKiogUm9vdCBkb2N1bWVudCAgICAgICAgICAqLwotICBwdWJsaWMgRG9jdW1lbnQgbV9kb2M7Ci0KLSAgLyoqIEN1cnJlbnQgbm9kZSAgICAgICAgICAgKi8KLSAgcHJvdGVjdGVkIE5vZGUgbV9jdXJyZW50Tm9kZSA9IG51bGw7Ci0KLSAgLyoqIFRoZSByb290IG5vZGUgICAgICAgICAgKi8KLSAgcHJvdGVjdGVkIE5vZGUgbV9yb290ID0gbnVsbDsKLQotICAvKiogVGhlIG5leHQgc2libGluZyBub2RlICAqLwotICBwcm90ZWN0ZWQgTm9kZSBtX25leHRTaWJsaW5nID0gbnVsbDsKLQotICAvKiogRmlyc3Qgbm9kZSBvZiBkb2N1bWVudCBmcmFnbWVudCBvciBudWxsIGlmIG5vdCBhIERvY3VtZW50RnJhZ21lbnQgICAgICovCi0gIHB1YmxpYyBEb2N1bWVudEZyYWdtZW50IG1fZG9jRnJhZyA9IG51bGw7Ci0KLSAgLyoqIFZlY3RvciBvZiBlbGVtZW50IG5vZGVzICAgICAgICAgICovCi0gIHByb3RlY3RlZCBTdGFjayBtX2VsZW1TdGFjayA9IG5ldyBTdGFjaygpOwotCi0gIC8qKgotICAgKiBET01CdWlsZGVyIGluc3RhbmNlIGNvbnN0cnVjdG9yLi4uIGl0IHdpbGwgYWRkIHRoZSBET00gbm9kZXMKLSAgICogdG8gdGhlIGRvY3VtZW50IGZyYWdtZW50LgotICAgKgotICAgKiBAcGFyYW0gZG9jIFJvb3QgZG9jdW1lbnQKLSAgICogQHBhcmFtIG5vZGUgQ3VycmVudCBub2RlCi0gICAqLwotICBwdWJsaWMgRE9NQnVpbGRlcihEb2N1bWVudCBkb2MsIE5vZGUgbm9kZSkKLSAgewotICAgIG1fZG9jID0gZG9jOwotICAgIG1fY3VycmVudE5vZGUgPSBtX3Jvb3QgPSBub2RlOwotCi0gICAgaWYgKG5vZGUgaW5zdGFuY2VvZiBFbGVtZW50KQotICAgICAgbV9lbGVtU3RhY2sucHVzaChub2RlKTsKLSAgfQotCi0gIC8qKgotICAgKiBET01CdWlsZGVyIGluc3RhbmNlIGNvbnN0cnVjdG9yLi4uIGl0IHdpbGwgYWRkIHRoZSBET00gbm9kZXMKLSAgICogdG8gdGhlIGRvY3VtZW50IGZyYWdtZW50LgotICAgKgotICAgKiBAcGFyYW0gZG9jIFJvb3QgZG9jdW1lbnQKLSAgICogQHBhcmFtIGRvY0ZyYWcgRG9jdW1lbnQgZnJhZ21lbnQKLSAgICovCi0gIHB1YmxpYyBET01CdWlsZGVyKERvY3VtZW50IGRvYywgRG9jdW1lbnRGcmFnbWVudCBkb2NGcmFnKQotICB7Ci0gICAgbV9kb2MgPSBkb2M7Ci0gICAgbV9kb2NGcmFnID0gZG9jRnJhZzsKLSAgfQotCi0gIC8qKgotICAgKiBET01CdWlsZGVyIGluc3RhbmNlIGNvbnN0cnVjdG9yLi4uIGl0IHdpbGwgYWRkIHRoZSBET00gbm9kZXMKLSAgICogdG8gdGhlIGRvY3VtZW50LgotICAgKgotICAgKiBAcGFyYW0gZG9jIFJvb3QgZG9jdW1lbnQKLSAgICovCi0gIHB1YmxpYyBET01CdWlsZGVyKERvY3VtZW50IGRvYykKLSAgewotICAgIG1fZG9jID0gZG9jOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgcm9vdCBkb2N1bWVudCBvciBEb2N1bWVudEZyYWdtZW50IG9mIHRoZSBET00gYmVpbmcgY3JlYXRlZC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgcm9vdCBkb2N1bWVudCBvciBkb2N1bWVudCBmcmFnbWVudCBpZiBub3QgbnVsbAotICAgKi8KLSAgcHVibGljIE5vZGUgZ2V0Um9vdERvY3VtZW50KCkKLSAgewotICAgIHJldHVybiAobnVsbCAhPSBtX2RvY0ZyYWcpID8gKE5vZGUpIG1fZG9jRnJhZyA6IChOb2RlKSBtX2RvYzsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIHJvb3Qgbm9kZSBvZiB0aGUgRE9NIHRyZWUuCi0gICAqLwotICBwdWJsaWMgTm9kZSBnZXRSb290Tm9kZSgpCi0gIHsKLSAgICByZXR1cm4gbV9yb290OwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbm9kZSBjdXJyZW50bHkgYmVpbmcgcHJvY2Vzc2VkLgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBjdXJyZW50IG5vZGUgYmVpbmcgcHJvY2Vzc2VkCi0gICAqLwotICBwdWJsaWMgTm9kZSBnZXRDdXJyZW50Tm9kZSgpCi0gIHsKLSAgICByZXR1cm4gbV9jdXJyZW50Tm9kZTsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIG5leHQgc2libGluZyBub2RlLCB3aGljaCBpcyB3aGVyZSB0aGUgcmVzdWx0IG5vZGVzCi0gICAqIHNob3VsZCBiZSBpbnNlcnRlZCBiZWZvcmUuCi0gICAqCi0gICAqIEBwYXJhbSBuZXh0U2libGluZyB0aGUgbmV4dCBzaWJsaW5nIG5vZGUuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXROZXh0U2libGluZyhOb2RlIG5leHRTaWJsaW5nKQotICB7Ci0gICAgbV9uZXh0U2libGluZyA9IG5leHRTaWJsaW5nOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgbmV4dCBzaWJsaW5nIG5vZGUuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIG5leHQgc2libGluZyBub2RlLgotICAgKi8KLSAgcHVibGljIE5vZGUgZ2V0TmV4dFNpYmxpbmcoKQotICB7Ci0gICAgcmV0dXJuIG1fbmV4dFNpYmxpbmc7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIG51bGwgc2luY2UgdGhlcmUgaXMgbm8gV3JpdGVyIGZvciB0aGlzIGNsYXNzLgotICAgKgotICAgKiBAcmV0dXJuIG51bGwKLSAgICovCi0gIHB1YmxpYyBqYXZhLmlvLldyaXRlciBnZXRXcml0ZXIoKQotICB7Ci0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogQXBwZW5kIGEgbm9kZSB0byB0aGUgY3VycmVudCBjb250YWluZXIuCi0gICAqCi0gICAqIEBwYXJhbSBuZXdOb2RlIE5ldyBub2RlIHRvIGFwcGVuZAotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgYXBwZW5kKE5vZGUgbmV3Tm9kZSkgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICBOb2RlIGN1cnJlbnROb2RlID0gbV9jdXJyZW50Tm9kZTsKLQotICAgIGlmIChudWxsICE9IGN1cnJlbnROb2RlKQotICAgIHsKLSAgICAgIGlmIChjdXJyZW50Tm9kZSA9PSBtX3Jvb3QgJiYgbV9uZXh0U2libGluZyAhPSBudWxsKQotICAgICAgICBjdXJyZW50Tm9kZS5pbnNlcnRCZWZvcmUobmV3Tm9kZSwgbV9uZXh0U2libGluZyk7Ci0gICAgICBlbHNlCi0gICAgICAgIGN1cnJlbnROb2RlLmFwcGVuZENoaWxkKG5ld05vZGUpOwotCi0gICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4obmV3Tm9kZS5nZXROb2RlTmFtZSgpKTsKLSAgICB9Ci0gICAgZWxzZSBpZiAobnVsbCAhPSBtX2RvY0ZyYWcpCi0gICAgewotICAgICAgaWYgKG1fbmV4dFNpYmxpbmcgIT0gbnVsbCkKLSAgICAgICAgbV9kb2NGcmFnLmluc2VydEJlZm9yZShuZXdOb2RlLCBtX25leHRTaWJsaW5nKTsKLSAgICAgIGVsc2UKLSAgICAgICAgbV9kb2NGcmFnLmFwcGVuZENoaWxkKG5ld05vZGUpOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgYm9vbGVhbiBvayA9IHRydWU7Ci0gICAgICBzaG9ydCB0eXBlID0gbmV3Tm9kZS5nZXROb2RlVHlwZSgpOwotCi0gICAgICBpZiAodHlwZSA9PSBOb2RlLlRFWFRfTk9ERSkKLSAgICAgIHsKLSAgICAgICAgU3RyaW5nIGRhdGEgPSBuZXdOb2RlLmdldE5vZGVWYWx1ZSgpOwotCi0gICAgICAgIGlmICgobnVsbCAhPSBkYXRhKSAmJiAoZGF0YS50cmltKCkubGVuZ3RoKCkgPiAwKSkKLSAgICAgICAgewotICAgICAgICAgIHRocm93IG5ldyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24oCi0gICAgICAgICAgICBYTUxNZXNzYWdlcy5jcmVhdGVYTUxNZXNzYWdlKAotICAgICAgICAgICAgICBYTUxFcnJvclJlc291cmNlcy5FUl9DQU5UX09VVFBVVF9URVhUX0JFRk9SRV9ET0MsIG51bGwpKTsgIC8vIldhcm5pbmc6IGNhbid0IG91dHB1dCB0ZXh0IGJlZm9yZSBkb2N1bWVudCBlbGVtZW50ISAgSWdub3JpbmcuLi4iKTsKLSAgICAgICAgfQotCi0gICAgICAgIG9rID0gZmFsc2U7Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmICh0eXBlID09IE5vZGUuRUxFTUVOVF9OT0RFKQotICAgICAgewotICAgICAgICBpZiAobV9kb2MuZ2V0RG9jdW1lbnRFbGVtZW50KCkgIT0gbnVsbCkKLSAgICAgICAgewotICAgICAgICAgIG9rID0gZmFsc2U7Ci0KLSAgICAgICAgICB0aHJvdyBuZXcgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uKAotICAgICAgICAgICAgWE1MTWVzc2FnZXMuY3JlYXRlWE1MTWVzc2FnZSgKLSAgICAgICAgICAgICAgWE1MRXJyb3JSZXNvdXJjZXMuRVJfQ0FOVF9IQVZFX01PUkVfVEhBTl9PTkVfUk9PVCwgbnVsbCkpOyAgLy8iQ2FuJ3QgaGF2ZSBtb3JlIHRoYW4gb25lIHJvb3Qgb24gYSBET00hIik7Ci0gICAgICAgIH0KLSAgICAgIH0KLQotICAgICAgaWYgKG9rKQotICAgICAgewotICAgICAgICBpZiAobV9uZXh0U2libGluZyAhPSBudWxsKQotICAgICAgICAgIG1fZG9jLmluc2VydEJlZm9yZShuZXdOb2RlLCBtX25leHRTaWJsaW5nKTsKLSAgICAgICAgZWxzZQotICAgICAgICAgIG1fZG9jLmFwcGVuZENoaWxkKG5ld05vZGUpOwotICAgICAgfQotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBSZWNlaXZlIGFuIG9iamVjdCBmb3IgbG9jYXRpbmcgdGhlIG9yaWdpbiBvZiBTQVggZG9jdW1lbnQgZXZlbnRzLgotICAgKgotICAgKiA8cD5TQVggcGFyc2VycyBhcmUgc3Ryb25nbHkgZW5jb3VyYWdlZCAodGhvdWdoIG5vdCBhYnNvbHV0ZWx5Ci0gICAqIHJlcXVpcmVkKSB0byBzdXBwbHkgYSBsb2NhdG9yOiBpZiBpdCBkb2VzIHNvLCBpdCBtdXN0IHN1cHBseQotICAgKiB0aGUgbG9jYXRvciB0byB0aGUgYXBwbGljYXRpb24gYnkgaW52b2tpbmcgdGhpcyBtZXRob2QgYmVmb3JlCi0gICAqIGludm9raW5nIGFueSBvZiB0aGUgb3RoZXIgbWV0aG9kcyBpbiB0aGUgQ29udGVudEhhbmRsZXIKLSAgICogaW50ZXJmYWNlLjwvcD4KLSAgICoKLSAgICogPHA+VGhlIGxvY2F0b3IgYWxsb3dzIHRoZSBhcHBsaWNhdGlvbiB0byBkZXRlcm1pbmUgdGhlIGVuZAotICAgKiBwb3NpdGlvbiBvZiBhbnkgZG9jdW1lbnQtcmVsYXRlZCBldmVudCwgZXZlbiBpZiB0aGUgcGFyc2VyIGlzCi0gICAqIG5vdCByZXBvcnRpbmcgYW4gZXJyb3IuICBUeXBpY2FsbHksIHRoZSBhcHBsaWNhdGlvbiB3aWxsCi0gICAqIHVzZSB0aGlzIGluZm9ybWF0aW9uIGZvciByZXBvcnRpbmcgaXRzIG93biBlcnJvcnMgKHN1Y2ggYXMKLSAgICogY2hhcmFjdGVyIGNvbnRlbnQgdGhhdCBkb2VzIG5vdCBtYXRjaCBhbiBhcHBsaWNhdGlvbidzCi0gICAqIGJ1c2luZXNzIHJ1bGVzKS4gIFRoZSBpbmZvcm1hdGlvbiByZXR1cm5lZCBieSB0aGUgbG9jYXRvcgotICAgKiBpcyBwcm9iYWJseSBub3Qgc3VmZmljaWVudCBmb3IgdXNlIHdpdGggYSBzZWFyY2ggZW5naW5lLjwvcD4KLSAgICoKLSAgICogPHA+Tm90ZSB0aGF0IHRoZSBsb2NhdG9yIHdpbGwgcmV0dXJuIGNvcnJlY3QgaW5mb3JtYXRpb24gb25seQotICAgKiBkdXJpbmcgdGhlIGludm9jYXRpb24gb2YgdGhlIGV2ZW50cyBpbiB0aGlzIGludGVyZmFjZS4gIFRoZQotICAgKiBhcHBsaWNhdGlvbiBzaG91bGQgbm90IGF0dGVtcHQgdG8gdXNlIGl0IGF0IGFueSBvdGhlciB0aW1lLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIGxvY2F0b3IgQW4gb2JqZWN0IHRoYXQgY2FuIHJldHVybiB0aGUgbG9jYXRpb24gb2YKLSAgICogICAgICAgICAgICAgICAgYW55IFNBWCBkb2N1bWVudCBldmVudC4KLSAgICogQHNlZSBvcmcueG1sLnNheC5Mb2NhdG9yCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXREb2N1bWVudExvY2F0b3IoTG9jYXRvciBsb2NhdG9yKQotICB7Ci0KLSAgICAvLyBObyBhY3Rpb24gZm9yIHRoZSBtb21lbnQuCi0gIH0KLQotICAvKioKLSAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIGJlZ2lubmluZyBvZiBhIGRvY3VtZW50LgotICAgKgotICAgKiA8cD5UaGUgU0FYIHBhcnNlciB3aWxsIGludm9rZSB0aGlzIG1ldGhvZCBvbmx5IG9uY2UsIGJlZm9yZSBhbnkKLSAgICogb3RoZXIgbWV0aG9kcyBpbiB0aGlzIGludGVyZmFjZSBvciBpbiBEVERIYW5kbGVyIChleGNlcHQgZm9yCi0gICAqIHNldERvY3VtZW50TG9jYXRvcikuPC9wPgotICAgKi8KLSAgcHVibGljIHZvaWQgc3RhcnREb2N1bWVudCgpIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgLy8gTm8gYWN0aW9uIGZvciB0aGUgbW9tZW50LgotICB9Ci0KLSAgLyoqCi0gICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIHRoZSBlbmQgb2YgYSBkb2N1bWVudC4KLSAgICoKLSAgICogPHA+VGhlIFNBWCBwYXJzZXIgd2lsbCBpbnZva2UgdGhpcyBtZXRob2Qgb25seSBvbmNlLCBhbmQgaXQgd2lsbAotICAgKiBiZSB0aGUgbGFzdCBtZXRob2QgaW52b2tlZCBkdXJpbmcgdGhlIHBhcnNlLiAgVGhlIHBhcnNlciBzaGFsbAotICAgKiBub3QgaW52b2tlIHRoaXMgbWV0aG9kIHVudGlsIGl0IGhhcyBlaXRoZXIgYWJhbmRvbmVkIHBhcnNpbmcKLSAgICogKGJlY2F1c2Ugb2YgYW4gdW5yZWNvdmVyYWJsZSBlcnJvcikgb3IgcmVhY2hlZCB0aGUgZW5kIG9mCi0gICAqIGlucHV0LjwvcD4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGVuZERvY3VtZW50KCkgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICAvLyBObyBhY3Rpb24gZm9yIHRoZSBtb21lbnQuCi0gIH0KLQotICAvKioKLSAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIGJlZ2lubmluZyBvZiBhbiBlbGVtZW50LgotICAgKgotICAgKiA8cD5UaGUgUGFyc2VyIHdpbGwgaW52b2tlIHRoaXMgbWV0aG9kIGF0IHRoZSBiZWdpbm5pbmcgb2YgZXZlcnkKLSAgICogZWxlbWVudCBpbiB0aGUgWE1MIGRvY3VtZW50OyB0aGVyZSB3aWxsIGJlIGEgY29ycmVzcG9uZGluZwotICAgKiBlbmRFbGVtZW50KCkgZXZlbnQgZm9yIGV2ZXJ5IHN0YXJ0RWxlbWVudCgpIGV2ZW50IChldmVuIHdoZW4gdGhlCi0gICAqIGVsZW1lbnQgaXMgZW1wdHkpLiBBbGwgb2YgdGhlIGVsZW1lbnQncyBjb250ZW50IHdpbGwgYmUKLSAgICogcmVwb3J0ZWQsIGluIG9yZGVyLCBiZWZvcmUgdGhlIGNvcnJlc3BvbmRpbmcgZW5kRWxlbWVudCgpCi0gICAqIGV2ZW50LjwvcD4KLSAgICoKLSAgICogPHA+SWYgdGhlIGVsZW1lbnQgbmFtZSBoYXMgYSBuYW1lc3BhY2UgcHJlZml4LCB0aGUgcHJlZml4IHdpbGwKLSAgICogc3RpbGwgYmUgYXR0YWNoZWQuICBOb3RlIHRoYXQgdGhlIGF0dHJpYnV0ZSBsaXN0IHByb3ZpZGVkIHdpbGwKLSAgICogY29udGFpbiBvbmx5IGF0dHJpYnV0ZXMgd2l0aCBleHBsaWNpdCB2YWx1ZXMgKHNwZWNpZmllZCBvcgotICAgKiBkZWZhdWx0ZWQpOiAjSU1QTElFRCBhdHRyaWJ1dGVzIHdpbGwgYmUgb21pdHRlZC48L3A+Ci0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBucyBUaGUgbmFtZXNwYWNlIG9mIHRoZSBub2RlCi0gICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGxvY2FsIHBhcnQgb2YgdGhlIHF1YWxpZmllZCBuYW1lCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBlbGVtZW50IG5hbWUuCi0gICAqIEBwYXJhbSBhdHRzIFRoZSBhdHRyaWJ1dGVzIGF0dGFjaGVkIHRvIHRoZSBlbGVtZW50LCBpZiBhbnkuCi0gICAqIEBzZWUgI2VuZEVsZW1lbnQKLSAgICogQHNlZSBvcmcueG1sLnNheC5BdHRyaWJ1dGVzCi0gICAqLwotICBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQoCi0gICAgICAgICAgU3RyaW5nIG5zLCBTdHJpbmcgbG9jYWxOYW1lLCBTdHJpbmcgbmFtZSwgQXR0cmlidXRlcyBhdHRzKQotICAgICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICBFbGVtZW50IGVsZW07Ci0KLSAgICAgICAgLy8gTm90ZSB0aGF0IHRoZSBuYW1lc3BhY2UtYXdhcmUgY2FsbCBtdXN0IGJlIHVzZWQgdG8gY29ycmVjdGx5Ci0gICAgICAgIC8vIGNvbnN0cnVjdCBhIExldmVsIDIgRE9NLCBldmVuIGZvciBub24tbmFtZXNwYWNlZCBub2Rlcy4KLSAgICBpZiAoKG51bGwgPT0gbnMpIHx8IChucy5sZW5ndGgoKSA9PSAwKSkKLSAgICAgIGVsZW0gPSBtX2RvYy5jcmVhdGVFbGVtZW50TlMobnVsbCxuYW1lKTsKLSAgICBlbHNlCi0gICAgICBlbGVtID0gbV9kb2MuY3JlYXRlRWxlbWVudE5TKG5zLCBuYW1lKTsKLQotICAgIGFwcGVuZChlbGVtKTsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIGludCBuQXR0cyA9IGF0dHMuZ2V0TGVuZ3RoKCk7Ci0KLSAgICAgIGlmICgwICE9IG5BdHRzKQotICAgICAgewotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG5BdHRzOyBpKyspCi0gICAgICAgIHsKLQotICAgICAgICAgIC8vU3lzdGVtLm91dC5wcmludGxuKCJ0eXBlICIgKyBhdHRzLmdldFR5cGUoaSkgKyAiIG5hbWUgIiArIGF0dHMuZ2V0TG9jYWxOYW1lKGkpICk7Ci0gICAgICAgICAgLy8gRmlyc3QgaGFuZGxlIGEgcG9zc2libGUgSUQgYXR0cmlidXRlCi0gICAgICAgICAgaWYgKGF0dHMuZ2V0VHlwZShpKS5lcXVhbHNJZ25vcmVDYXNlKCJJRCIpKQotICAgICAgICAgICAgc2V0SURBdHRyaWJ1dGUoYXR0cy5nZXRWYWx1ZShpKSwgZWxlbSk7Ci0KLSAgICAgICAgICBTdHJpbmcgYXR0ck5TID0gYXR0cy5nZXRVUkkoaSk7Ci0KLSAgICAgICAgICBpZigiIi5lcXVhbHMoYXR0ck5TKSkKLSAgICAgICAgICAgIGF0dHJOUyA9IG51bGw7IC8vIERPTSByZXByZXNlbnRzIG5vLW5hbWVzcGFjZSBhcyBudWxsCi0KLSAgICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oImF0dHJOUzogIithdHRyTlMrIiwgbG9jYWxOYW1lOiAiK2F0dHMuZ2V0UU5hbWUoaSkKLSAgICAgICAgICAvLyAgICAgICAgICAgICAgICAgICArIiwgcW5hbWU6ICIrYXR0cy5nZXRRTmFtZShpKSsiLCB2YWx1ZTogIithdHRzLmdldFZhbHVlKGkpKTsKLSAgICAgICAgICAvLyBDcmltc29uIHdvbid0IGxldCB1cyBzZXQgYW4geG1sbnM6IGF0dHJpYnV0ZSBvbiB0aGUgRE9NLgotICAgICAgICAgIFN0cmluZyBhdHRyUU5hbWUgPSBhdHRzLmdldFFOYW1lKGkpOwotCi0gICAgICAgICAgLy8gSW4gU0FYLCB4bWxuc1s6XSBhdHRyaWJ1dGVzIGhhdmUgYW4gZW1wdHkgbmFtZXNwYWNlLCB3aGlsZSBpbiBET00gdGhleQotICAgICAgICAgIC8vIHNob3VsZCBoYXZlIHRoZSB4bWxucyBuYW1lc3BhY2UKLSAgICAgICAgICBpZiAoYXR0clFOYW1lLnN0YXJ0c1dpdGgoInhtbG5zOiIpIHx8IGF0dHJRTmFtZS5lcXVhbHMoInhtbG5zIikpIHsKLSAgICAgICAgICAgIGF0dHJOUyA9ICJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3htbG5zLyI7Ci0gICAgICAgICAgfQotCi0gICAgICAgICAgLy8gQUxXQVlTIHVzZSB0aGUgRE9NIExldmVsIDIgY2FsbCEKLSAgICAgICAgICBlbGVtLnNldEF0dHJpYnV0ZU5TKGF0dHJOUyxhdHRyUU5hbWUsIGF0dHMuZ2V0VmFsdWUoaSkpOwotICAgICAgICB9Ci0gICAgICB9Ci0KLSAgICAgIC8vIGFwcGVuZChlbGVtKTsKLQotICAgICAgbV9lbGVtU3RhY2sucHVzaChlbGVtKTsKLQotICAgICAgbV9jdXJyZW50Tm9kZSA9IGVsZW07Ci0KLSAgICAgIC8vIGFwcGVuZChlbGVtKTsKLSAgICB9Ci0gICAgY2F0Y2goamF2YS5sYW5nLkV4Y2VwdGlvbiBkZSkKLSAgICB7Ci0gICAgICAvLyBkZS5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgIHRocm93IG5ldyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24oZGUpOwotICAgIH0KLQotICB9Ci0KLSAgLyoqCi0KLQotCi0gICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIHRoZSBlbmQgb2YgYW4gZWxlbWVudC4KLSAgICoKLSAgICogPHA+VGhlIFNBWCBwYXJzZXIgd2lsbCBpbnZva2UgdGhpcyBtZXRob2QgYXQgdGhlIGVuZCBvZiBldmVyeQotICAgKiBlbGVtZW50IGluIHRoZSBYTUwgZG9jdW1lbnQ7IHRoZXJlIHdpbGwgYmUgYSBjb3JyZXNwb25kaW5nCi0gICAqIHN0YXJ0RWxlbWVudCgpIGV2ZW50IGZvciBldmVyeSBlbmRFbGVtZW50KCkgZXZlbnQgKGV2ZW4gd2hlbiB0aGUKLSAgICogZWxlbWVudCBpcyBlbXB0eSkuPC9wPgotICAgKgotICAgKiA8cD5JZiB0aGUgZWxlbWVudCBuYW1lIGhhcyBhIG5hbWVzcGFjZSBwcmVmaXgsIHRoZSBwcmVmaXggd2lsbAotICAgKiBzdGlsbCBiZSBhdHRhY2hlZCB0byB0aGUgbmFtZS48L3A+Ci0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBucyB0aGUgbmFtZXNwYWNlIG9mIHRoZSBlbGVtZW50Ci0gICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGxvY2FsIHBhcnQgb2YgdGhlIHF1YWxpZmllZCBuYW1lIG9mIHRoZSBlbGVtZW50Ci0gICAqIEBwYXJhbSBuYW1lIFRoZSBlbGVtZW50IG5hbWUKLSAgICovCi0gIHB1YmxpYyB2b2lkIGVuZEVsZW1lbnQoU3RyaW5nIG5zLCBTdHJpbmcgbG9jYWxOYW1lLCBTdHJpbmcgbmFtZSkKLSAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBtX2VsZW1TdGFjay5wb3AoKTsKLSAgICBtX2N1cnJlbnROb2RlID0gbV9lbGVtU3RhY2suaXNFbXB0eSgpID8gbnVsbCA6IChOb2RlKW1fZWxlbVN0YWNrLnBlZWsoKTsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgYW4gSUQgc3RyaW5nIHRvIG5vZGUgYXNzb2NpYXRpb24gaW4gdGhlIElEIHRhYmxlLgotICAgKgotICAgKiBAcGFyYW0gaWQgVGhlIElEIHN0cmluZy4KLSAgICogQHBhcmFtIGVsZW0gVGhlIGFzc29jaWF0ZWQgSUQuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRJREF0dHJpYnV0ZShTdHJpbmcgaWQsIEVsZW1lbnQgZWxlbSkKLSAgewotCi0gICAgLy8gRG8gbm90aGluZy4gVGhpcyBtZXRob2QgaXMgbWVhbnQgdG8gYmUgb3ZlcmlkZW4uCi0gIH0KLQotICAvKioKLSAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgY2hhcmFjdGVyIGRhdGEuCi0gICAqCi0gICAqIDxwPlRoZSBQYXJzZXIgd2lsbCBjYWxsIHRoaXMgbWV0aG9kIHRvIHJlcG9ydCBlYWNoIGNodW5rIG9mCi0gICAqIGNoYXJhY3RlciBkYXRhLiAgU0FYIHBhcnNlcnMgbWF5IHJldHVybiBhbGwgY29udGlndW91cyBjaGFyYWN0ZXIKLSAgICogZGF0YSBpbiBhIHNpbmdsZSBjaHVuaywgb3IgdGhleSBtYXkgc3BsaXQgaXQgaW50byBzZXZlcmFsCi0gICAqIGNodW5rczsgaG93ZXZlciwgYWxsIG9mIHRoZSBjaGFyYWN0ZXJzIGluIGFueSBzaW5nbGUgZXZlbnQKLSAgICogbXVzdCBjb21lIGZyb20gdGhlIHNhbWUgZXh0ZXJuYWwgZW50aXR5LCBzbyB0aGF0IHRoZSBMb2NhdG9yCi0gICAqIHByb3ZpZGVzIHVzZWZ1bCBpbmZvcm1hdGlvbi48L3A+Ci0gICAqCi0gICAqIDxwPlRoZSBhcHBsaWNhdGlvbiBtdXN0IG5vdCBhdHRlbXB0IHRvIHJlYWQgZnJvbSB0aGUgYXJyYXkKLSAgICogb3V0c2lkZSBvZiB0aGUgc3BlY2lmaWVkIHJhbmdlLjwvcD4KLSAgICoKLSAgICogPHA+Tm90ZSB0aGF0IHNvbWUgcGFyc2VycyB3aWxsIHJlcG9ydCB3aGl0ZXNwYWNlIHVzaW5nIHRoZQotICAgKiBpZ25vcmFibGVXaGl0ZXNwYWNlKCkgbWV0aG9kIHJhdGhlciB0aGFuIHRoaXMgb25lICh2YWxpZGF0aW5nCi0gICAqIHBhcnNlcnMgbXVzdCBkbyBzbykuPC9wPgotICAgKgotICAgKiBAcGFyYW0gY2ggVGhlIGNoYXJhY3RlcnMgZnJvbSB0aGUgWE1MIGRvY3VtZW50LgotICAgKiBAcGFyYW0gc3RhcnQgVGhlIHN0YXJ0IHBvc2l0aW9uIGluIHRoZSBhcnJheS4KLSAgICogQHBhcmFtIGxlbmd0aCBUaGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gcmVhZCBmcm9tIHRoZSBhcnJheS4KLSAgICogQHNlZSAjaWdub3JhYmxlV2hpdGVzcGFjZQotICAgKiBAc2VlIG9yZy54bWwuc2F4LkxvY2F0b3IKLSAgICovCi0gIHB1YmxpYyB2b2lkIGNoYXJhY3RlcnMoY2hhciBjaFtdLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIGlmKGlzT3V0c2lkZURvY0VsZW0oKQotICAgICAgICYmIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuWE1MQ2hhcmFjdGVyUmVjb2duaXplci5pc1doaXRlU3BhY2UoY2gsIHN0YXJ0LCBsZW5ndGgpKQotICAgICAgcmV0dXJuOyAgLy8gYXZvaWQgRE9NMDA2IEhpZXJhcmNoeSByZXF1ZXN0IGVycm9yCi0KLSAgICBpZiAobV9pbkNEYXRhKQotICAgIHsKLSAgICAgIGNkYXRhKGNoLCBzdGFydCwgbGVuZ3RoKTsKLQotICAgICAgcmV0dXJuOwotICAgIH0KLQotICAgIFN0cmluZyBzID0gbmV3IFN0cmluZyhjaCwgc3RhcnQsIGxlbmd0aCk7Ci0gICAgTm9kZSBjaGlsZE5vZGU7Ci0gICAgY2hpbGROb2RlID0gIG1fY3VycmVudE5vZGUgIT0gbnVsbCA/IG1fY3VycmVudE5vZGUuZ2V0TGFzdENoaWxkKCk6IG51bGw7Ci0gICAgaWYoIGNoaWxkTm9kZSAhPSBudWxsICYmIGNoaWxkTm9kZS5nZXROb2RlVHlwZSgpID09IE5vZGUuVEVYVF9OT0RFICl7Ci0gICAgICAgKChUZXh0KWNoaWxkTm9kZSkuYXBwZW5kRGF0YShzKTsKLSAgICB9Ci0gICAgZWxzZXsKLSAgICAgICBUZXh0IHRleHQgPSBtX2RvYy5jcmVhdGVUZXh0Tm9kZShzKTsKLSAgICAgICBhcHBlbmQodGV4dCk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIElmIGF2YWlsYWJsZSwgd2hlbiB0aGUgZGlzYWJsZS1vdXRwdXQtZXNjYXBpbmcgYXR0cmlidXRlIGlzIHVzZWQsCi0gICAqIG91dHB1dCByYXcgdGV4dCB3aXRob3V0IGVzY2FwaW5nLiAgQSBQSSB3aWxsIGJlIGluc2VydGVkIGluIGZyb250Ci0gICAqIG9mIHRoZSBub2RlIHdpdGggdGhlIG5hbWUgImxvdHVzeHNsLW5leHQtaXMtcmF3IiBhbmQgYSB2YWx1ZSBvZgotICAgKiAiZm9ybWF0dGVyLXRvLWRvbSIuCi0gICAqCi0gICAqIEBwYXJhbSBjaCBBcnJheSBjb250YWluaW5nIHRoZSBjaGFyYWN0ZXJzCi0gICAqIEBwYXJhbSBzdGFydCBJbmRleCB0byBzdGFydCBvZiBjaGFyYWN0ZXJzIGluIHRoZSBhcnJheQotICAgKiBAcGFyYW0gbGVuZ3RoIE51bWJlciBvZiBjaGFyYWN0ZXJzIGluIHRoZSBhcnJheQotICAgKi8KLSAgcHVibGljIHZvaWQgY2hhcmFjdGVyc1JhdyhjaGFyIGNoW10sIGludCBzdGFydCwgaW50IGxlbmd0aCkKLSAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBpZihpc091dHNpZGVEb2NFbGVtKCkKLSAgICAgICAmJiBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLlhNTENoYXJhY3RlclJlY29nbml6ZXIuaXNXaGl0ZVNwYWNlKGNoLCBzdGFydCwgbGVuZ3RoKSkKLSAgICAgIHJldHVybjsgIC8vIGF2b2lkIERPTTAwNiBIaWVyYXJjaHkgcmVxdWVzdCBlcnJvcgotCi0KLSAgICBTdHJpbmcgcyA9IG5ldyBTdHJpbmcoY2gsIHN0YXJ0LCBsZW5ndGgpOwotCi0gICAgYXBwZW5kKG1fZG9jLmNyZWF0ZVByb2Nlc3NpbmdJbnN0cnVjdGlvbigieHNsdC1uZXh0LWlzLXJhdyIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZm9ybWF0dGVyLXRvLWRvbSIpKTsKLSAgICBhcHBlbmQobV9kb2MuY3JlYXRlVGV4dE5vZGUocykpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlcG9ydCB0aGUgYmVnaW5uaW5nIG9mIGFuIGVudGl0eS4KLSAgICoKLSAgICogVGhlIHN0YXJ0IGFuZCBlbmQgb2YgdGhlIGRvY3VtZW50IGVudGl0eSBhcmUgbm90IHJlcG9ydGVkLgotICAgKiBUaGUgc3RhcnQgYW5kIGVuZCBvZiB0aGUgZXh0ZXJuYWwgRFREIHN1YnNldCBhcmUgcmVwb3J0ZWQKLSAgICogdXNpbmcgdGhlIHBzZXVkby1uYW1lICJbZHRkXSIuICBBbGwgb3RoZXIgZXZlbnRzIG11c3QgYmUKLSAgICogcHJvcGVybHkgbmVzdGVkIHdpdGhpbiBzdGFydC9lbmQgZW50aXR5IGV2ZW50cy4KLSAgICoKLSAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGVudGl0eS4gIElmIGl0IGlzIGEgcGFyYW1ldGVyCi0gICAqICAgICAgICBlbnRpdHksIHRoZSBuYW1lIHdpbGwgYmVnaW4gd2l0aCAnJScuCi0gICAqIEBzZWUgI2VuZEVudGl0eQotICAgKiBAc2VlIG9yZy54bWwuc2F4LmV4dC5EZWNsSGFuZGxlciNpbnRlcm5hbEVudGl0eURlY2wKLSAgICogQHNlZSBvcmcueG1sLnNheC5leHQuRGVjbEhhbmRsZXIjZXh0ZXJuYWxFbnRpdHlEZWNsCi0gICAqLwotICBwdWJsaWMgdm9pZCBzdGFydEVudGl0eShTdHJpbmcgbmFtZSkgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICAvLyBBbG1vc3QgY2VydGFpbmx5IHRoZSB3cm9uZyBiZWhhdmlvci4uLgotICAgIC8vIGVudGl0eVJlZmVyZW5jZShuYW1lKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXBvcnQgdGhlIGVuZCBvZiBhbiBlbnRpdHkuCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBlbnRpdHkgdGhhdCBpcyBlbmRpbmcuCi0gICAqIEBzZWUgI3N0YXJ0RW50aXR5Ci0gICAqLwotICBwdWJsaWMgdm9pZCBlbmRFbnRpdHkoU3RyaW5nIG5hbWUpIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb257fQotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGl2aWNhdGlvbiBvZiBhIGVudGl0eVJlZmVyZW5jZS4KLSAgICoKLSAgICogQHBhcmFtIG5hbWUgbmFtZSBvZiB0aGUgZW50aXR5IHJlZmVyZW5jZQotICAgKi8KLSAgcHVibGljIHZvaWQgZW50aXR5UmVmZXJlbmNlKFN0cmluZyBuYW1lKSB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBhcHBlbmQobV9kb2MuY3JlYXRlRW50aXR5UmVmZXJlbmNlKG5hbWUpKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBpZ25vcmFibGUgd2hpdGVzcGFjZSBpbiBlbGVtZW50IGNvbnRlbnQuCi0gICAqCi0gICAqIDxwPlZhbGlkYXRpbmcgUGFyc2VycyBtdXN0IHVzZSB0aGlzIG1ldGhvZCB0byByZXBvcnQgZWFjaCBjaHVuawotICAgKiBvZiBpZ25vcmFibGUgd2hpdGVzcGFjZSAoc2VlIHRoZSBXM0MgWE1MIDEuMCByZWNvbW1lbmRhdGlvbiwKLSAgICogc2VjdGlvbiAyLjEwKTogbm9uLXZhbGlkYXRpbmcgcGFyc2VycyBtYXkgYWxzbyB1c2UgdGhpcyBtZXRob2QKLSAgICogaWYgdGhleSBhcmUgY2FwYWJsZSBvZiBwYXJzaW5nIGFuZCB1c2luZyBjb250ZW50IG1vZGVscy48L3A+Ci0gICAqCi0gICAqIDxwPlNBWCBwYXJzZXJzIG1heSByZXR1cm4gYWxsIGNvbnRpZ3VvdXMgd2hpdGVzcGFjZSBpbiBhIHNpbmdsZQotICAgKiBjaHVuaywgb3IgdGhleSBtYXkgc3BsaXQgaXQgaW50byBzZXZlcmFsIGNodW5rczsgaG93ZXZlciwgYWxsIG9mCi0gICAqIHRoZSBjaGFyYWN0ZXJzIGluIGFueSBzaW5nbGUgZXZlbnQgbXVzdCBjb21lIGZyb20gdGhlIHNhbWUKLSAgICogZXh0ZXJuYWwgZW50aXR5LCBzbyB0aGF0IHRoZSBMb2NhdG9yIHByb3ZpZGVzIHVzZWZ1bAotICAgKiBpbmZvcm1hdGlvbi48L3A+Ci0gICAqCi0gICAqIDxwPlRoZSBhcHBsaWNhdGlvbiBtdXN0IG5vdCBhdHRlbXB0IHRvIHJlYWQgZnJvbSB0aGUgYXJyYXkKLSAgICogb3V0c2lkZSBvZiB0aGUgc3BlY2lmaWVkIHJhbmdlLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIGNoIFRoZSBjaGFyYWN0ZXJzIGZyb20gdGhlIFhNTCBkb2N1bWVudC4KLSAgICogQHBhcmFtIHN0YXJ0IFRoZSBzdGFydCBwb3NpdGlvbiBpbiB0aGUgYXJyYXkuCi0gICAqIEBwYXJhbSBsZW5ndGggVGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHJlYWQgZnJvbSB0aGUgYXJyYXkuCi0gICAqIEBzZWUgI2NoYXJhY3RlcnMKLSAgICovCi0gIHB1YmxpYyB2b2lkIGlnbm9yYWJsZVdoaXRlc3BhY2UoY2hhciBjaFtdLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpCi0gICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgaWYoaXNPdXRzaWRlRG9jRWxlbSgpKQotICAgICAgcmV0dXJuOyAgLy8gYXZvaWQgRE9NMDA2IEhpZXJhcmNoeSByZXF1ZXN0IGVycm9yCi0KLSAgICBTdHJpbmcgcyA9IG5ldyBTdHJpbmcoY2gsIHN0YXJ0LCBsZW5ndGgpOwotCi0gICAgYXBwZW5kKG1fZG9jLmNyZWF0ZVRleHROb2RlKHMpKTsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIGlmIHRoZSBjdXJyZW50IG5vZGUgaXMgb3V0c2lkZSB0aGUgZG9jdW1lbnQgZWxlbWVudC4KLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHRoZSBjdXJyZW50IG5vZGUgaXMgb3V0c2lkZSB0aGUgZG9jdW1lbnQgZWxlbWVudC4KLSAgICovCi0gICBwcml2YXRlIGJvb2xlYW4gaXNPdXRzaWRlRG9jRWxlbSgpCi0gICB7Ci0gICAgICByZXR1cm4gKG51bGwgPT0gbV9kb2NGcmFnKSAmJiBtX2VsZW1TdGFjay5zaXplKCkgPT0gMCAmJiAobnVsbCA9PSBtX2N1cnJlbnROb2RlIHx8IG1fY3VycmVudE5vZGUuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLkRPQ1VNRU5UX05PREUpOwotICAgfQotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBhIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24uCi0gICAqCi0gICAqIDxwPlRoZSBQYXJzZXIgd2lsbCBpbnZva2UgdGhpcyBtZXRob2Qgb25jZSBmb3IgZWFjaCBwcm9jZXNzaW5nCi0gICAqIGluc3RydWN0aW9uIGZvdW5kOiBub3RlIHRoYXQgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbnMgbWF5IG9jY3VyCi0gICAqIGJlZm9yZSBvciBhZnRlciB0aGUgbWFpbiBkb2N1bWVudCBlbGVtZW50LjwvcD4KLSAgICoKLSAgICogPHA+QSBTQVggcGFyc2VyIHNob3VsZCBuZXZlciByZXBvcnQgYW4gWE1MIGRlY2xhcmF0aW9uIChYTUwgMS4wLAotICAgKiBzZWN0aW9uIDIuOCkgb3IgYSB0ZXh0IGRlY2xhcmF0aW9uIChYTUwgMS4wLCBzZWN0aW9uIDQuMy4xKQotICAgKiB1c2luZyB0aGlzIG1ldGhvZC48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSB0YXJnZXQgVGhlIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gdGFyZ2V0LgotICAgKiBAcGFyYW0gZGF0YSBUaGUgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiBkYXRhLCBvciBudWxsIGlmCi0gICAqICAgICAgICBub25lIHdhcyBzdXBwbGllZC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHByb2Nlc3NpbmdJbnN0cnVjdGlvbihTdHJpbmcgdGFyZ2V0LCBTdHJpbmcgZGF0YSkKLSAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBhcHBlbmQobV9kb2MuY3JlYXRlUHJvY2Vzc2luZ0luc3RydWN0aW9uKHRhcmdldCwgZGF0YSkpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlcG9ydCBhbiBYTUwgY29tbWVudCBhbnl3aGVyZSBpbiB0aGUgZG9jdW1lbnQuCi0gICAqCi0gICAqIFRoaXMgY2FsbGJhY2sgd2lsbCBiZSB1c2VkIGZvciBjb21tZW50cyBpbnNpZGUgb3Igb3V0c2lkZSB0aGUKLSAgICogZG9jdW1lbnQgZWxlbWVudCwgaW5jbHVkaW5nIGNvbW1lbnRzIGluIHRoZSBleHRlcm5hbCBEVEQKLSAgICogc3Vic2V0IChpZiByZWFkKS4KLSAgICoKLSAgICogQHBhcmFtIGNoIEFuIGFycmF5IGhvbGRpbmcgdGhlIGNoYXJhY3RlcnMgaW4gdGhlIGNvbW1lbnQuCi0gICAqIEBwYXJhbSBzdGFydCBUaGUgc3RhcnRpbmcgcG9zaXRpb24gaW4gdGhlIGFycmF5LgotICAgKiBAcGFyYW0gbGVuZ3RoIFRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyB0byB1c2UgZnJvbSB0aGUgYXJyYXkuCi0gICAqLwotICBwdWJsaWMgdm9pZCBjb21tZW50KGNoYXIgY2hbXSwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKSB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBhcHBlbmQobV9kb2MuY3JlYXRlQ29tbWVudChuZXcgU3RyaW5nKGNoLCBzdGFydCwgbGVuZ3RoKSkpOwotICB9Ci0KLSAgLyoqIEZsYWcgaW5kaWNhdGluZyB0aGF0IHdlIGFyZSBwcm9jZXNzaW5nIGEgQ0RhdGEgc2VjdGlvbiAgICAgICAgICAqLwotICBwcm90ZWN0ZWQgYm9vbGVhbiBtX2luQ0RhdGEgPSBmYWxzZTsKLQotICAvKioKLSAgICogUmVwb3J0IHRoZSBzdGFydCBvZiBhIENEQVRBIHNlY3Rpb24uCi0gICAqCi0gICAqIEBzZWUgI2VuZENEQVRBCi0gICAqLwotICBwdWJsaWMgdm9pZCBzdGFydENEQVRBKCkgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgbV9pbkNEYXRhID0gdHJ1ZTsKLSAgICBhcHBlbmQobV9kb2MuY3JlYXRlQ0RBVEFTZWN0aW9uKCIiKSk7Ci0gIH0KLQotICAvKioKLSAgICogUmVwb3J0IHRoZSBlbmQgb2YgYSBDREFUQSBzZWN0aW9uLgotICAgKgotICAgKiBAc2VlICNzdGFydENEQVRBCi0gICAqLwotICBwdWJsaWMgdm9pZCBlbmRDREFUQSgpIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIG1faW5DRGF0YSA9IGZhbHNlOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGNkYXRhLgotICAgKgotICAgKiA8cD5UaGUgUGFyc2VyIHdpbGwgY2FsbCB0aGlzIG1ldGhvZCB0byByZXBvcnQgZWFjaCBjaHVuayBvZgotICAgKiBjaGFyYWN0ZXIgZGF0YS4gIFNBWCBwYXJzZXJzIG1heSByZXR1cm4gYWxsIGNvbnRpZ3VvdXMgY2hhcmFjdGVyCi0gICAqIGRhdGEgaW4gYSBzaW5nbGUgY2h1bmssIG9yIHRoZXkgbWF5IHNwbGl0IGl0IGludG8gc2V2ZXJhbAotICAgKiBjaHVua3M7IGhvd2V2ZXIsIGFsbCBvZiB0aGUgY2hhcmFjdGVycyBpbiBhbnkgc2luZ2xlIGV2ZW50Ci0gICAqIG11c3QgY29tZSBmcm9tIHRoZSBzYW1lIGV4dGVybmFsIGVudGl0eSwgc28gdGhhdCB0aGUgTG9jYXRvcgotICAgKiBwcm92aWRlcyB1c2VmdWwgaW5mb3JtYXRpb24uPC9wPgotICAgKgotICAgKiA8cD5UaGUgYXBwbGljYXRpb24gbXVzdCBub3QgYXR0ZW1wdCB0byByZWFkIGZyb20gdGhlIGFycmF5Ci0gICAqIG91dHNpZGUgb2YgdGhlIHNwZWNpZmllZCByYW5nZS48L3A+Ci0gICAqCi0gICAqIDxwPk5vdGUgdGhhdCBzb21lIHBhcnNlcnMgd2lsbCByZXBvcnQgd2hpdGVzcGFjZSB1c2luZyB0aGUKLSAgICogaWdub3JhYmxlV2hpdGVzcGFjZSgpIG1ldGhvZCByYXRoZXIgdGhhbiB0aGlzIG9uZSAodmFsaWRhdGluZwotICAgKiBwYXJzZXJzIG11c3QgZG8gc28pLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIGNoIFRoZSBjaGFyYWN0ZXJzIGZyb20gdGhlIFhNTCBkb2N1bWVudC4KLSAgICogQHBhcmFtIHN0YXJ0IFRoZSBzdGFydCBwb3NpdGlvbiBpbiB0aGUgYXJyYXkuCi0gICAqIEBwYXJhbSBsZW5ndGggVGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHJlYWQgZnJvbSB0aGUgYXJyYXkuCi0gICAqIEBzZWUgI2lnbm9yYWJsZVdoaXRlc3BhY2UKLSAgICogQHNlZSBvcmcueG1sLnNheC5Mb2NhdG9yCi0gICAqLwotICBwdWJsaWMgdm9pZCBjZGF0YShjaGFyIGNoW10sIGludCBzdGFydCwgaW50IGxlbmd0aCkgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgaWYoaXNPdXRzaWRlRG9jRWxlbSgpCi0gICAgICAgJiYgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5YTUxDaGFyYWN0ZXJSZWNvZ25pemVyLmlzV2hpdGVTcGFjZShjaCwgc3RhcnQsIGxlbmd0aCkpCi0gICAgICByZXR1cm47ICAvLyBhdm9pZCBET00wMDYgSGllcmFyY2h5IHJlcXVlc3QgZXJyb3IKLQotICAgIFN0cmluZyBzID0gbmV3IFN0cmluZyhjaCwgc3RhcnQsIGxlbmd0aCk7Ci0KLSAgICBDREFUQVNlY3Rpb24gc2VjdGlvbiAgPShDREFUQVNlY3Rpb24pIG1fY3VycmVudE5vZGUuZ2V0TGFzdENoaWxkKCk7Ci0gICAgc2VjdGlvbi5hcHBlbmREYXRhKHMpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlcG9ydCB0aGUgc3RhcnQgb2YgRFREIGRlY2xhcmF0aW9ucywgaWYgYW55LgotICAgKgotICAgKiBBbnkgZGVjbGFyYXRpb25zIGFyZSBhc3N1bWVkIHRvIGJlIGluIHRoZSBpbnRlcm5hbCBzdWJzZXQKLSAgICogdW5sZXNzIG90aGVyd2lzZSBpbmRpY2F0ZWQuCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBkb2N1bWVudCB0eXBlIG5hbWUuCi0gICAqIEBwYXJhbSBwdWJsaWNJZCBUaGUgZGVjbGFyZWQgcHVibGljIGlkZW50aWZpZXIgZm9yIHRoZQotICAgKiAgICAgICAgZXh0ZXJuYWwgRFREIHN1YnNldCwgb3IgbnVsbCBpZiBub25lIHdhcyBkZWNsYXJlZC4KLSAgICogQHBhcmFtIHN5c3RlbUlkIFRoZSBkZWNsYXJlZCBzeXN0ZW0gaWRlbnRpZmllciBmb3IgdGhlCi0gICAqICAgICAgICBleHRlcm5hbCBEVEQgc3Vic2V0LCBvciBudWxsIGlmIG5vbmUgd2FzIGRlY2xhcmVkLgotICAgKiBAc2VlICNlbmREVEQKLSAgICogQHNlZSAjc3RhcnRFbnRpdHkKLSAgICovCi0gIHB1YmxpYyB2b2lkIHN0YXJ0RFREKFN0cmluZyBuYW1lLCBTdHJpbmcgcHVibGljSWQsIFN0cmluZyBzeXN0ZW1JZCkKLSAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIC8vIERvIG5vdGhpbmcgZm9yIG5vdy4KLSAgfQotCi0gIC8qKgotICAgKiBSZXBvcnQgdGhlIGVuZCBvZiBEVEQgZGVjbGFyYXRpb25zLgotICAgKgotICAgKiBAc2VlICNzdGFydERURAotICAgKi8KLSAgcHVibGljIHZvaWQgZW5kRFREKCkgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICAvLyBEbyBub3RoaW5nIGZvciBub3cuCi0gIH0KLQotICAvKioKLSAgICogQmVnaW4gdGhlIHNjb3BlIG9mIGEgcHJlZml4LVVSSSBOYW1lc3BhY2UgbWFwcGluZy4KLSAgICoKLSAgICogPHA+VGhlIGluZm9ybWF0aW9uIGZyb20gdGhpcyBldmVudCBpcyBub3QgbmVjZXNzYXJ5IGZvcgotICAgKiBub3JtYWwgTmFtZXNwYWNlIHByb2Nlc3Npbmc6IHRoZSBTQVggWE1MIHJlYWRlciB3aWxsCi0gICAqIGF1dG9tYXRpY2FsbHkgcmVwbGFjZSBwcmVmaXhlcyBmb3IgZWxlbWVudCBhbmQgYXR0cmlidXRlCi0gICAqIG5hbWVzIHdoZW4gdGhlIGh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy9uYW1lc3BhY2VzCi0gICAqIGZlYXR1cmUgaXMgdHJ1ZSAodGhlIGRlZmF1bHQpLjwvcD4KLSAgICoKLSAgICogPHA+VGhlcmUgYXJlIGNhc2VzLCBob3dldmVyLCB3aGVuIGFwcGxpY2F0aW9ucyBuZWVkIHRvCi0gICAqIHVzZSBwcmVmaXhlcyBpbiBjaGFyYWN0ZXIgZGF0YSBvciBpbiBhdHRyaWJ1dGUgdmFsdWVzLAotICAgKiB3aGVyZSB0aGV5IGNhbm5vdCBzYWZlbHkgYmUgZXhwYW5kZWQgYXV0b21hdGljYWxseTsgdGhlCi0gICAqIHN0YXJ0L2VuZFByZWZpeE1hcHBpbmcgZXZlbnQgc3VwcGxpZXMgdGhlIGluZm9ybWF0aW9uCi0gICAqIHRvIHRoZSBhcHBsaWNhdGlvbiB0byBleHBhbmQgcHJlZml4ZXMgaW4gdGhvc2UgY29udGV4dHMKLSAgICogaXRzZWxmLCBpZiBuZWNlc3NhcnkuPC9wPgotICAgKgotICAgKiA8cD5Ob3RlIHRoYXQgc3RhcnQvZW5kUHJlZml4TWFwcGluZyBldmVudHMgYXJlIG5vdAotICAgKiBndWFyYW50ZWVkIHRvIGJlIHByb3Blcmx5IG5lc3RlZCByZWxhdGl2ZSB0byBlYWNoLW90aGVyOgotICAgKiBhbGwgc3RhcnRQcmVmaXhNYXBwaW5nIGV2ZW50cyB3aWxsIG9jY3VyIGJlZm9yZSB0aGUKLSAgICogY29ycmVzcG9uZGluZyBzdGFydEVsZW1lbnQgZXZlbnQsIGFuZCBhbGwgZW5kUHJlZml4TWFwcGluZwotICAgKiBldmVudHMgd2lsbCBvY2N1ciBhZnRlciB0aGUgY29ycmVzcG9uZGluZyBlbmRFbGVtZW50IGV2ZW50LAotICAgKiBidXQgdGhlaXIgb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQuPC9wPgotICAgKgotICAgKiBAcGFyYW0gcHJlZml4IFRoZSBOYW1lc3BhY2UgcHJlZml4IGJlaW5nIGRlY2xhcmVkLgotICAgKiBAcGFyYW0gdXJpIFRoZSBOYW1lc3BhY2UgVVJJIHRoZSBwcmVmaXggaXMgbWFwcGVkIHRvLgotICAgKiBAc2VlICNlbmRQcmVmaXhNYXBwaW5nCi0gICAqIEBzZWUgI3N0YXJ0RWxlbWVudAotICAgKi8KLSAgcHVibGljIHZvaWQgc3RhcnRQcmVmaXhNYXBwaW5nKFN0cmluZyBwcmVmaXgsIFN0cmluZyB1cmkpCi0gICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICAvKgotICAgIC8vIE5vdCBzdXJlIGlmIHRoaXMgaXMgbmVlZGVkIG9yIHdhbnRlZAotICAgIC8vIEFsc28sIGl0IGZhaWxzIGluIHRoZSBzdHJlZS4KLSAgICBpZigobnVsbCAhPSBtX2N1cnJlbnROb2RlKQotICAgICAgICYmIChtX2N1cnJlbnROb2RlLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5FTEVNRU5UX05PREUpKQotICAgIHsKLSAgICAgIFN0cmluZyBxbmFtZTsKLSAgICAgIGlmKCgobnVsbCAhPSBwcmVmaXgpICYmIChwcmVmaXgubGVuZ3RoKCkgPT0gMCkpCi0gICAgICAgICB8fCAobnVsbCA9PSBwcmVmaXgpKQotICAgICAgICBxbmFtZSA9ICJ4bWxucyI7Ci0gICAgICBlbHNlCi0gICAgICAgIHFuYW1lID0gInhtbG5zOiIrcHJlZml4OwotCi0gICAgICBFbGVtZW50IGVsZW0gPSAoRWxlbWVudCltX2N1cnJlbnROb2RlOwotICAgICAgU3RyaW5nIHZhbCA9IGVsZW0uZ2V0QXR0cmlidXRlKHFuYW1lKTsgLy8gT2Jzb2xldGUsIHNob3VsZCBiZSBET00yLi4uPwotICAgICAgaWYodmFsID09IG51bGwpCi0gICAgICB7Ci0gICAgICAgIGVsZW0uc2V0QXR0cmlidXRlTlMoImh0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcW5hbWUsIHVyaSk7Ci0gICAgICB9Ci0gICAgfQotICAgICovCi0gIH0KLQotICAvKioKLSAgICogRW5kIHRoZSBzY29wZSBvZiBhIHByZWZpeC1VUkkgbWFwcGluZy4KLSAgICoKLSAgICogPHA+U2VlIHN0YXJ0UHJlZml4TWFwcGluZyBmb3IgZGV0YWlscy4gIFRoaXMgZXZlbnQgd2lsbAotICAgKiBhbHdheXMgb2NjdXIgYWZ0ZXIgdGhlIGNvcnJlc3BvbmRpbmcgZW5kRWxlbWVudCBldmVudCwKLSAgICogYnV0IHRoZSBvcmRlciBvZiBlbmRQcmVmaXhNYXBwaW5nIGV2ZW50cyBpcyBub3Qgb3RoZXJ3aXNlCi0gICAqIGd1YXJhbnRlZWQuPC9wPgotICAgKgotICAgKiBAcGFyYW0gcHJlZml4IFRoZSBwcmVmaXggdGhhdCB3YXMgYmVpbmcgbWFwcGluZy4KLSAgICogQHNlZSAjc3RhcnRQcmVmaXhNYXBwaW5nCi0gICAqIEBzZWUgI2VuZEVsZW1lbnQKLSAgICovCi0gIHB1YmxpYyB2b2lkIGVuZFByZWZpeE1hcHBpbmcoU3RyaW5nIHByZWZpeCkgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbnt9Ci0KLSAgLyoqCi0gICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGEgc2tpcHBlZCBlbnRpdHkuCi0gICAqCi0gICAqIDxwPlRoZSBQYXJzZXIgd2lsbCBpbnZva2UgdGhpcyBtZXRob2Qgb25jZSBmb3IgZWFjaCBlbnRpdHkKLSAgICogc2tpcHBlZC4gIE5vbi12YWxpZGF0aW5nIHByb2Nlc3NvcnMgbWF5IHNraXAgZW50aXRpZXMgaWYgdGhleQotICAgKiBoYXZlIG5vdCBzZWVuIHRoZSBkZWNsYXJhdGlvbnMgKGJlY2F1c2UsIGZvciBleGFtcGxlLCB0aGUKLSAgICogZW50aXR5IHdhcyBkZWNsYXJlZCBpbiBhbiBleHRlcm5hbCBEVEQgc3Vic2V0KS4gIEFsbCBwcm9jZXNzb3JzCi0gICAqIG1heSBza2lwIGV4dGVybmFsIGVudGl0aWVzLCBkZXBlbmRpbmcgb24gdGhlIHZhbHVlcyBvZiB0aGUKLSAgICogaHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL2V4dGVybmFsLWdlbmVyYWwtZW50aXRpZXMgYW5kIHRoZQotICAgKiBodHRwOi8veG1sLm9yZy9zYXgvZmVhdHVyZXMvZXh0ZXJuYWwtcGFyYW1ldGVyLWVudGl0aWVzCi0gICAqIHByb3BlcnRpZXMuPC9wPgotICAgKgotICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgc2tpcHBlZCBlbnRpdHkuICBJZiBpdCBpcyBhCi0gICAqICAgICAgICBwYXJhbWV0ZXIgZW50aXR5LCB0aGUgbmFtZSB3aWxsIGJlZ2luIHdpdGggJyUnLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2tpcHBlZEVudGl0eShTdHJpbmcgbmFtZSkgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbnt9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9ET01IZWxwZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL0RPTUhlbHBlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0MTZjMjAwLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL0RPTUhlbHBlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTMzMCArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDE1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICovCi0vKgotICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCi0gKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKLSAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KLSAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCi0gKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAotICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IERPTUhlbHBlci5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE1IDA4OjE1OjQwIHN1cmVzaF9lbWFpbGlkIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlsczsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLnJlZi5EVE1Ob2RlUHJveHk7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXMuWE1MRXJyb3JSZXNvdXJjZXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXMuWE1MTWVzc2FnZXM7Ci1pbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7Ci1pbXBvcnQgamF2YS51dGlsLk1hcDsKLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotaW1wb3J0IGphdmF4LnhtbC5YTUxDb25zdGFudHM7Ci1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyOwotaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlckZhY3Rvcnk7Ci1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKLWltcG9ydCBvcmcudzNjLmRvbS5BdHRyOwotaW1wb3J0IG9yZy53M2MuZG9tLkRPTUltcGxlbWVudGF0aW9uOwotaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50VHlwZTsKLWltcG9ydCBvcmcudzNjLmRvbS5FbGVtZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLkVudGl0eTsKLWltcG9ydCBvcmcudzNjLmRvbS5OYW1lZE5vZGVNYXA7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcudzNjLmRvbS5UZXh0OwotCi0vKioKLSAqIEBkZXByZWNhdGVkIFNpbmNlIHRoZSBpbnRyb2R1Y3Rpb24gb2YgdGhlIERUTSwgdGhpcyBjbGFzcyB3aWxsIGJlIHJlbW92ZWQuCi0gKiBUaGlzIGNsYXNzIHByb3ZpZGVzIGEgZnJvbnQtZW5kIHRvIERPTSBpbXBsZW1lbnRhdGlvbnMsIHByb3ZpZGluZwotICogYSBudW1iZXIgb2YgdXRpbGl0eSBmdW5jdGlvbnMgdGhhdCBlaXRoZXIgYXJlbid0IHlldCBzdGFuZGFyZGl6ZWQKLSAqIGJ5IHRoZSBET00gc3BlYyBvciB0aGF0IGFyZSBkZWZpbmVkIGluIG9wdGlvbmFsIERPTSBtb2R1bGVzIGFuZAotICogaGVuY2UgbWF5IG5vdCBiZSBwcmVzZW50IGluIGFsbCBET01zLgotICovCi1wdWJsaWMgY2xhc3MgRE9NSGVscGVyCi17Ci0KLSAgLyoqCi0gICAqIERPTSBMZXZlbCAxIGRpZCBub3QgaGF2ZSBhIHN0YW5kYXJkIG1lY2hhbmlzbSBmb3IgY3JlYXRpbmcgYSBuZXcKLSAgICogRG9jdW1lbnQgb2JqZWN0LiBUaGlzIGZ1bmN0aW9uIHByb3ZpZGVzIGEgRE9NLWltcGxlbWVudGF0aW9uLWluZGVwZW5kZW50Ci0gICAqIGFic3RyYWN0aW9uIGZvciB0aGF0IGZvciB0aGF0IGNvbmNlcHQuIEl0J3MgdHlwaWNhbGx5IHVzZWQgd2hlbgotICAgKiBvdXRwdXR0aW5nIGEgbmV3IERPTSBhcyB0aGUgcmVzdWx0IG9mIGFuIG9wZXJhdGlvbi4KLSAgICogPHA+Ci0gICAqIFRPRE86IFRoaXMgaXNuJ3QgZGlyZWN0bHkgY29tcGF0YWJsZSB3aXRoIERPTSBMZXZlbCAyLgotICAgKiBUaGUgTGV2ZWwgMiBjcmVhdGVEb2N1bWVudCBjYWxsIGFsc28gY3JlYXRlcyB0aGUgcm9vdAotICAgKiBlbGVtZW50LCBhbmQgdGh1cyByZXF1aXJlcyB0aGF0IHlvdSBrbm93IHdoYXQgdGhhdCBlbGVtZW50IHdpbGwgYmUKLSAgICogYmVmb3JlIGNyZWF0aW5nIHRoZSBEb2N1bWVudC4gV2Ugc2hvdWxkIHRoaW5rIGFib3V0IHdoZXRoZXIgd2Ugd2FudAotICAgKiB0byBjaGFuZ2UgdGhpcyBjb2RlLCBhbmQgdGhlIGNhbGxlcnMsIHNvIHdlIGNhbiB1c2UgdGhlIERPTSdzIG93bgotICAgKiBtZXRob2QuIChJdCdzIGFsc28gcG9zc2libGUgdGhhdCBET00gTGV2ZWwgMyBtYXkgcmVsYXggdGhpcwotICAgKiBzZXF1ZW5jZSwgYnV0IHlvdSBtYXkgZ2l2ZSB1cCBzb21lIGludGVsbGlnZW5jZSBpbiB0aGUgRE9NIGJ5Ci0gICAqIGRvaW5nIHNvOyB0aGUgaW50ZW50IHdhcyB0aGF0IGtub3dpbmcgdGhlIGRvY3VtZW50IHR5cGUgYW5kIHJvb3QKLSAgICogZWxlbWVudCBtaWdodCBsZXQgdGhlIERPTSBhdXRvbWF0aWNhbGx5IHN3aXRjaCB0byBhIHNwZWNpYWxpemVkCi0gICAqIHN1YmNsYXNzIGZvciBwYXJ0aWN1bGFyIGtpbmRzIG9mIGRvY3VtZW50cy4pCi0gICAqCi0gICAqIEBwYXJhbSBpc1NlY3VyZVByb2Nlc3Npbmcgc3RhdGUgb2YgdGhlIHNlY3VyZSBwcm9jZXNzaW5nIGZlYXR1cmUuCi0gICAqIEByZXR1cm4gVGhlIG5ld2x5IGNyZWF0ZWQgRE9NIERvY3VtZW50IG9iamVjdCwgd2l0aCBubyBjaGlsZHJlbiwgb3IKLSAgICogbnVsbCBpZiB3ZSBjYW4ndCBmaW5kIGEgRE9NIGltcGxlbWVudGF0aW9uIHRoYXQgcGVybWl0cyBjcmVhdGluZwotICAgKiBuZXcgZW1wdHkgRG9jdW1lbnRzLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBEb2N1bWVudCBjcmVhdGVEb2N1bWVudChib29sZWFuIGlzU2VjdXJlUHJvY2Vzc2luZykKLSAgewotCi0gICAgdHJ5Ci0gICAgewotCi0gICAgICAvLyBVc2UgYW4gaW1wbGVtZW50YXRpb24gb2YgdGhlIEpBVkEgQVBJIGZvciBYTUwgUGFyc2luZyAxLjAgdG8KLSAgICAgIC8vIGNyZWF0ZSBhIERPTSBEb2N1bWVudCBub2RlIHRvIGNvbnRhaW4gdGhlIHJlc3VsdC4KLSAgICAgIERvY3VtZW50QnVpbGRlckZhY3RvcnkgZGZhY3RvcnkgPSBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCk7Ci0KLSAgICAgIGRmYWN0b3J5LnNldE5hbWVzcGFjZUF3YXJlKHRydWUpOwotICAgICAgZGZhY3Rvcnkuc2V0VmFsaWRhdGluZyh0cnVlKTsKLQotICAgICAgaWYgKGlzU2VjdXJlUHJvY2Vzc2luZykKLSAgICAgIHsKLSAgICAgICAgdHJ5Ci0gICAgICAgIHsKLSAgICAgICAgICBkZmFjdG9yeS5zZXRGZWF0dXJlKFhNTENvbnN0YW50cy5GRUFUVVJFX1NFQ1VSRV9QUk9DRVNTSU5HLCB0cnVlKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBwY2UpIHt9Ci0gICAgICB9Ci0KLSAgICAgIERvY3VtZW50QnVpbGRlciBkb2NCdWlsZGVyID0gZGZhY3RvcnkubmV3RG9jdW1lbnRCdWlsZGVyKCk7Ci0gICAgICBEb2N1bWVudCBvdXROb2RlID0gZG9jQnVpbGRlci5uZXdEb2N1bWVudCgpOwotCi0gICAgICByZXR1cm4gb3V0Tm9kZTsKLSAgICB9Ci0gICAgY2F0Y2ggKFBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gcGNlKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAotICAgICAgICBYTUxNZXNzYWdlcy5jcmVhdGVYTUxNZXNzYWdlKAotICAgICAgICAgIFhNTEVycm9yUmVzb3VyY2VzLkVSX0NSRUFURURPQ1VNRU5UX05PVF9TVVBQT1JURUQsIG51bGwpKTsgIC8vImNyZWF0ZURvY3VtZW50KCkgbm90IHN1cHBvcnRlZCBpbiBYUGF0aENvbnRleHQhIik7Ci0KLSAgICAgIC8vIHJldHVybiBudWxsOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBET00gTGV2ZWwgMSBkaWQgbm90IGhhdmUgYSBzdGFuZGFyZCBtZWNoYW5pc20gZm9yIGNyZWF0aW5nIGEgbmV3Ci0gICAqIERvY3VtZW50IG9iamVjdC4gVGhpcyBmdW5jdGlvbiBwcm92aWRlcyBhIERPTS1pbXBsZW1lbnRhdGlvbi1pbmRlcGVuZGVudAotICAgKiBhYnN0cmFjdGlvbiBmb3IgdGhhdCBmb3IgdGhhdCBjb25jZXB0LiBJdCdzIHR5cGljYWxseSB1c2VkIHdoZW4KLSAgICogb3V0cHV0dGluZyBhIG5ldyBET00gYXMgdGhlIHJlc3VsdCBvZiBhbiBvcGVyYXRpb24uCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIG5ld2x5IGNyZWF0ZWQgRE9NIERvY3VtZW50IG9iamVjdCwgd2l0aCBubyBjaGlsZHJlbiwgb3IKLSAgICogbnVsbCBpZiB3ZSBjYW4ndCBmaW5kIGEgRE9NIGltcGxlbWVudGF0aW9uIHRoYXQgcGVybWl0cyBjcmVhdGluZwotICAgKiBuZXcgZW1wdHkgRG9jdW1lbnRzLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBEb2N1bWVudCBjcmVhdGVEb2N1bWVudCgpCi0gIHsKLSAgICByZXR1cm4gY3JlYXRlRG9jdW1lbnQoZmFsc2UpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGxzLCB0aHJvdWdoIHRoZSBjb21iaW5hdGlvbiBvZiB0aGUgZGVmYXVsdC1zcGFjZSBhdHRyaWJ1dGUKLSAgICogb24geHNsOnN0eWxlc2hlZXQsIHhzbDpzdHJpcC1zcGFjZSwgeHNsOnByZXNlcnZlLXNwYWNlLCBhbmQgdGhlCi0gICAqIHhtbDpzcGFjZSBhdHRyaWJ1dGUsIHdoZXRoZXIgb3Igbm90IGV4dHJhIHdoaXRlc3BhY2Ugc2hvdWxkIGJlIHN0cmlwcGVkCi0gICAqIGZyb20gdGhlIG5vZGUuICBMaXRlcmFsIGVsZW1lbnRzIGZyb20gdGVtcGxhdGUgZWxlbWVudHMgc2hvdWxkCi0gICAqIDxlbT5ub3Q8L2VtPiBiZSB0ZXN0ZWQgd2l0aCB0aGlzIGZ1bmN0aW9uLgotICAgKiBAcGFyYW0gdGV4dE5vZGUgQSB0ZXh0IG5vZGUgZnJvbSB0aGUgc291cmNlIHRyZWUuCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgdGV4dCBub2RlIHNob3VsZCBiZSBzdHJpcHBlZCBvZiBleHRyYSB3aGl0ZXNwYWNlLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICogQHhzbC51c2FnZSBhZHZhbmNlZAotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gc2hvdWxkU3RyaXBTb3VyY2VOb2RlKE5vZGUgdGV4dE5vZGUpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgLy8gcmV0dXJuIChudWxsID09IG1fZW52U3VwcG9ydCkgPyBmYWxzZSA6IG1fZW52U3VwcG9ydC5zaG91bGRTdHJpcFNvdXJjZU5vZGUodGV4dE5vZGUpOwotICAgIHJldHVybiBmYWxzZTsKLSAgfQotCi0gIC8qKgotICAgKiBTdXBwb3J0cyB0aGUgWFBhdGggZnVuY3Rpb24gR2VuZXJhdGVJRCBieSByZXR1cm5pbmcgYSB1bmlxdWUKLSAgICogaWRlbnRpZmllciBzdHJpbmcgZm9yIGFueSBnaXZlbiBET00gTm9kZS4KLSAgICogPHA+Ci0gICAqIFdhcm5pbmc6IFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIHVzZXMgdGhlIE5vZGUgb2JqZWN0J3MgaGFzaENvZGUoKSwKLSAgICogd2hpY2ggaXMgTk9UIGd1YXJhbnRlZWQgdG8gYmUgdW5pcXVlLiBJZiB0aGF0IG1ldGhvZCBoYXNuJ3QgYmVlbgotICAgKiBvdmVycmlkZGVuIGluIHRoaXMgRE9NIGlwbWxlbWVudGF0aW9uLCBtb3N0IEphdmEgaW1wbGVtZW50aW9ucyB3aWxsCi0gICAqIGRlcml2ZSBpdCBmcm9tIHRoZSBvYmplY3QncyBhZGRyZXNzIGFuZCBzaG91bGQgYmUgT0suLi4gYnV0IGlmCi0gICAqIHlvdXIgRE9NIHVzZXMgYSBkaWZmZXJlbnQgZGVmaW5pdGlvbiBvZiBoYXNoQ29kZSAoZWcgaGFzaGluZyB0aGUKLSAgICogY29udGVudHMgb2YgdGhlIHN1YnRyZWUpLCBvciBpZiB5b3VyIERPTSBtYXkgaGF2ZSBtdWx0aXBsZSBvYmplY3RzCi0gICAqIHRoYXQgcmVwcmVzZW50IGEgc2luZ2xlIE5vZGUgaW4gdGhlIGRhdGEgc3RydWN0dXJlIChlZyB2aWEgcHJveHlpbmcpLAotICAgKiB5b3UgbWF5IG5lZWQgdG8gZmluZCBhbm90aGVyIHdheSB0byBhc3NpZ24gYSB1bmlxdWUgaWRlbnRpZmllci4KLSAgICogPHA+Ci0gICAqIEFsc28sIGJlIGF3YXJlIHRoYXQgaWYgbm9kZXMgYXJlIGRlc3Ryb3llZCBhbmQgcmVjcmVhdGVkLCB0aGVyZSBpcwotICAgKiBhbiBvcGVuIGlzc3VlIHJlZ2FyZGluZyB3aGV0aGVyIGFuIElEIG1heSBiZSByZXVzZWQuIEN1cnJlbnRseQotICAgKiB3ZSdyZSBhc3N1bWluZyB0aGF0IHRoZSBpbnB1dCBkb2N1bWVudCBpcyBzdGFibGUgZm9yIHRoZSBkdXJhdGlvbgotICAgKiBvZiB0aGUgWFBhdGgvWFNMVCBvcGVyYXRpb24sIHNvIHRoaXMgc2hvdWxkbid0IGFyaXNlIGluIHRoaXMgY29udGV4dC4KLSAgICogPHA+Ci0gICAqIChET00gTGV2ZWwgMyBpcyBpbnZlc3RpZ2F0aW5nIHByb3ZpZGluZyBhIHVuaXF1ZSBub2RlICJrZXkiLCBidXQKLSAgICogdGhhdCB3b24ndCBoZWxwIExldmVsIDEgYW5kIExldmVsIDIgaW1wbGVtZW50YXRpb25zLikKLSAgICoKLSAgICogQHBhcmFtIG5vZGUgd2hvc2UgaWRlbnRpZmllciB5b3Ugd2FudCB0byBvYnRhaW4KLSAgICoKLSAgICogQHJldHVybiBhIHN0cmluZyB3aGljaCBzaG91bGQgYmUgZGlmZmVyZW50IGZvciBldmVyeSBOb2RlIG9iamVjdC4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0VW5pcXVlSUQoTm9kZSBub2RlKQotICB7Ci0gICAgcmV0dXJuICJOIiArIEludGVnZXIudG9IZXhTdHJpbmcobm9kZS5oYXNoQ29kZSgpKS50b1VwcGVyQ2FzZSgpOwotICB9Ci0KLSAgLyoqCi0gICAqIEZpZ3VyZSBvdXQgd2hldGhlciBub2RlMiBzaG91bGQgYmUgY29uc2lkZXJlZCBhcyBiZWluZyBsYXRlcgotICAgKiBpbiB0aGUgZG9jdW1lbnQgdGhhbiBub2RlMSwgaW4gRG9jdW1lbnQgT3JkZXIgYXMgZGVmaW5lZAotICAgKiBieSB0aGUgWFBhdGggbW9kZWwuIFRoaXMgbWF5IG5vdCBhZ3JlZSB3aXRoIHRoZSBvcmRlcmluZyBkZWZpbmVkCi0gICAqIGJ5IG90aGVyIFhNTCBhcHBsaWNhdGlvbnMuCi0gICAqIDxwPgotICAgKiBUaGVyZSBhcmUgc29tZSBjYXNlcyB3aGVyZSBvcmRlcmluZyBpc24ndCBkZWZpbmVkLCBhbmQgbmVpdGhlciBhcmUKLSAgICogdGhlIHJlc3VsdHMgb2YgdGhpcyBmdW5jdGlvbiAtLSB0aG91Z2ggd2UnbGwgZ2VuZXJhbGx5IHJldHVybiB0cnVlLgotICAgKgotICAgKiBUT0RPOiBNYWtlIHN1cmUgdGhpcyBkb2VzIHRoZSByaWdodCB0aGluZyB3aXRoIGF0dHJpYnV0ZSBub2RlcyEhIQotICAgKgotICAgKiBAcGFyYW0gbm9kZTEgRE9NIE5vZGUgdG8gcGVyZm9ybSBwb3NpdGlvbiBjb21wYXJpc29uIG9uLgotICAgKiBAcGFyYW0gbm9kZTIgRE9NIE5vZGUgdG8gcGVyZm9ybSBwb3NpdGlvbiBjb21wYXJpc29uIG9uIC4KLSAgICoKLSAgICogQHJldHVybiBmYWxzZSBpZiBub2RlMiBjb21lcyBiZWZvcmUgbm9kZTEsIG90aGVyd2lzZSByZXR1cm4gdHJ1ZS4KLSAgICogWW91IGNhbiB0aGluayBvZiB0aGlzIGFzCi0gICAqIDxjb2RlPihub2RlMS5kb2N1bWVudE9yZGVyUG9zaXRpb24gJmx0Oz0gbm9kZTIuZG9jdW1lbnRPcmRlclBvc2l0aW9uKTwvY29kZT4uCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNOb2RlQWZ0ZXIoTm9kZSBub2RlMSwgTm9kZSBub2RlMikKLSAgewotICAgIGlmIChub2RlMSA9PSBub2RlMiB8fCBpc05vZGVUaGVTYW1lKG5vZGUxLCBub2RlMikpCi0gICAgICByZXR1cm4gdHJ1ZTsKLQotICAgICAgICAvLyBEZWZhdWx0IHJldHVybiB2YWx1ZSwgaWYgdGhlcmUgaXMgbm8gZGVmaW5lZCBvcmRlcmluZwotICAgIGJvb2xlYW4gaXNOb2RlQWZ0ZXIgPSB0cnVlOwotCi0gICAgTm9kZSBwYXJlbnQxID0gZ2V0UGFyZW50T2ZOb2RlKG5vZGUxKTsKLSAgICBOb2RlIHBhcmVudDIgPSBnZXRQYXJlbnRPZk5vZGUobm9kZTIpOwotCi0gICAgLy8gT3B0aW1pemUgZm9yIG1vc3QgY29tbW9uIGNhc2UKLSAgICBpZiAocGFyZW50MSA9PSBwYXJlbnQyIHx8IGlzTm9kZVRoZVNhbWUocGFyZW50MSwgcGFyZW50MikpICAvLyB0aGVuIHdlIGtub3cgdGhleSBhcmUgc2libGluZ3MKLSAgICB7Ci0gICAgICBpZiAobnVsbCAhPSBwYXJlbnQxKQotICAgICAgICBpc05vZGVBZnRlciA9IGlzTm9kZUFmdGVyU2libGluZyhwYXJlbnQxLCBub2RlMSwgbm9kZTIpOwotICAgICAgZWxzZQotICAgICAgewotICAgICAgICAgICAgICAgICAgLy8gSWYgYm90aCBwYXJlbnRzIGFyZSBudWxsLCBvcmRlcmluZyBpcyBub3QgZGVmaW5lZC4KLSAgICAgICAgICAgICAgICAgIC8vIFdlJ3JlIHJldHVybmluZyBhIHZhbHVlIGluIGxpZXUgb2YgdGhyb3dpbmcgYW4gZXhjZXB0aW9uLgotICAgICAgICAgICAgICAgICAgLy8gTm90IGEgY2FzZSB3ZSBleHBlY3QgdG8gYXJpc2UgaW4gWFBhdGgsIGJ1dCBiZXdhcmUgaWYgeW91Ci0gICAgICAgICAgICAgICAgICAvLyB0cnkgdG8gcmV1c2UgdGhpcyBtZXRob2QuCi0KLSAgICAgICAgICAgICAgICAgIC8vIFdlIGNhbiBqdXN0IGZhbGwgdGhyb3VnaCBpbiB0aGlzIGNhc2UsIHdoaWNoIGFsbG93cyB1cwotICAgICAgICAgICAgICAgICAgLy8gdG8gaGl0IHRoZSBkZWJ1Z2dpbmcgY29kZSBhdCB0aGUgZW5kIG9mIHRoZSBmdW5jdGlvbi4KLSAgICAgICAgICAvL3JldHVybiBpc05vZGVBZnRlcjsKLSAgICAgIH0KLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLQotICAgICAgLy8gR2VuZXJhbCBzdHJhdGVneTogRmlndXJlIG91dCB0aGUgbGVuZ3RocyBvZiB0aGUgdHdvCi0gICAgICAvLyBhbmNlc3RvciBjaGFpbnMsIHJlY29uY2lsZSB0aGUgbGVuZ3RocywgYW5kIGxvb2sgZm9yCi0gICAgICAgICAgLy8gdGhlIGxvd2VzdCBjb21tb24gYW5jZXN0b3IuIElmIHRoYXQgYW5jZXN0b3IgaXMgb25lIG9mCi0gICAgICAgICAgLy8gdGhlIG5vZGVzIGJlaW5nIGNvbXBhcmVkLCBpdCBjb21lcyBiZWZvcmUgdGhlIG90aGVyLgotICAgICAgLy8gT3RoZXJ3aXNlIHBlcmZvcm0gYSBzaWJsaW5nIGNvbXBhcmUuCi0gICAgICAgICAgICAgICAgLy8KLSAgICAgICAgICAgICAgICAvLyBOT1RFOiBJZiBubyBjb21tb24gYW5jZXN0b3IgaXMgZm91bmQsIG9yZGVyaW5nIGlzIHVuZGVmaW5lZAotICAgICAgICAgICAgICAgIC8vIGFuZCB3ZSByZXR1cm4gdGhlIGRlZmF1bHQgdmFsdWUgb2YgaXNOb2RlQWZ0ZXIuCi0KLSAgICAgIC8vIENvdW50IHBhcmVudHMgaW4gZWFjaCBhbmNlc3RvciBjaGFpbgotICAgICAgaW50IG5QYXJlbnRzMSA9IDIsIG5QYXJlbnRzMiA9IDI7ICAvLyBpbmNsdWRlIG5vZGUgJiBwYXJlbnQgb2J0YWluZWQgYWJvdmUKLQotICAgICAgd2hpbGUgKHBhcmVudDEgIT0gbnVsbCkKLSAgICAgIHsKLSAgICAgICAgblBhcmVudHMxKys7Ci0KLSAgICAgICAgcGFyZW50MSA9IGdldFBhcmVudE9mTm9kZShwYXJlbnQxKTsKLSAgICAgIH0KLQotICAgICAgd2hpbGUgKHBhcmVudDIgIT0gbnVsbCkKLSAgICAgIHsKLSAgICAgICAgblBhcmVudHMyKys7Ci0KLSAgICAgICAgcGFyZW50MiA9IGdldFBhcmVudE9mTm9kZShwYXJlbnQyKTsKLSAgICAgIH0KLQotICAgICAgICAgIC8vIEluaXRpYWxseSBhc3N1bWUgc2NhbiBmb3IgY29tbW9uIGFuY2VzdG9yIHN0YXJ0cyB3aXRoCi0gICAgICAgICAgLy8gdGhlIGlucHV0IG5vZGVzLgotICAgICAgTm9kZSBzdGFydE5vZGUxID0gbm9kZTEsIHN0YXJ0Tm9kZTIgPSBub2RlMjsKLQotICAgICAgLy8gSWYgb25lIGFuY2VzdG9yIGNoYWluIGlzIGxvbmdlciwgYWRqdXN0IGl0cyBzdGFydCBwb2ludAotICAgICAgICAgIC8vIHNvIHdlJ3JlIGNvbXBhcmluZyBhdCB0aGUgc2FtZSBkZXB0aHMKLSAgICAgIGlmIChuUGFyZW50czEgPCBuUGFyZW50czIpCi0gICAgICB7Ci0gICAgICAgIC8vIEFkanVzdCBzdGFydE5vZGUyIHRvIGRlcHRoIG9mIHN0YXJ0Tm9kZTEKLSAgICAgICAgaW50IGFkanVzdCA9IG5QYXJlbnRzMiAtIG5QYXJlbnRzMTsKLQotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGFkanVzdDsgaSsrKQotICAgICAgICB7Ci0gICAgICAgICAgc3RhcnROb2RlMiA9IGdldFBhcmVudE9mTm9kZShzdGFydE5vZGUyKTsKLSAgICAgICAgfQotICAgICAgfQotICAgICAgZWxzZSBpZiAoblBhcmVudHMxID4gblBhcmVudHMyKQotICAgICAgewotICAgICAgICAvLyBhZGp1c3Qgc3RhcnROb2RlMSB0byBkZXB0aCBvZiBzdGFydE5vZGUyCi0gICAgICAgIGludCBhZGp1c3QgPSBuUGFyZW50czEgLSBuUGFyZW50czI7Ci0KLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhZGp1c3Q7IGkrKykKLSAgICAgICAgewotICAgICAgICAgIHN0YXJ0Tm9kZTEgPSBnZXRQYXJlbnRPZk5vZGUoc3RhcnROb2RlMSk7Ci0gICAgICAgIH0KLSAgICAgIH0KLQotICAgICAgTm9kZSBwcmV2Q2hpbGQxID0gbnVsbCwgcHJldkNoaWxkMiA9IG51bGw7ICAvLyBzbyB3ZSBjYW4gImJhY2sgdXAiCi0KLSAgICAgIC8vIExvb3AgdXAgdGhlIGFuY2VzdG9yIGNoYWluIGxvb2tpbmcgZm9yIGNvbW1vbiBwYXJlbnQKLSAgICAgIHdoaWxlIChudWxsICE9IHN0YXJ0Tm9kZTEpCi0gICAgICB7Ci0gICAgICAgIGlmIChzdGFydE5vZGUxID09IHN0YXJ0Tm9kZTIgfHwgaXNOb2RlVGhlU2FtZShzdGFydE5vZGUxLCBzdGFydE5vZGUyKSkgIC8vIGNvbW1vbiBwYXJlbnQ/Ci0gICAgICAgIHsKLSAgICAgICAgICBpZiAobnVsbCA9PSBwcmV2Q2hpbGQxKSAgLy8gZmlyc3QgdGltZSBpbiBsb29wPwotICAgICAgICAgIHsKLQotICAgICAgICAgICAgLy8gRWRnZSBjb25kaXRpb246IG9uZSBpcyB0aGUgYW5jZXN0b3Igb2YgdGhlIG90aGVyLgotICAgICAgICAgICAgaXNOb2RlQWZ0ZXIgPSAoblBhcmVudHMxIDwgblBhcmVudHMyKSA/IHRydWUgOiBmYWxzZTsKLQotICAgICAgICAgICAgYnJlYWs7ICAvLyBmcm9tIHdoaWxlIGxvb3AKLSAgICAgICAgICB9Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIENvbXBhcmUgYW5jZXN0b3JzIGJlbG93IGxvd2VzdC1jb21tb24gYXMgc2libGluZ3MKLSAgICAgICAgICAgIGlzTm9kZUFmdGVyID0gaXNOb2RlQWZ0ZXJTaWJsaW5nKHN0YXJ0Tm9kZTEsIHByZXZDaGlsZDEsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmV2Q2hpbGQyKTsKLQotICAgICAgICAgICAgYnJlYWs7ICAvLyBmcm9tIHdoaWxlIGxvb3AKLSAgICAgICAgICB9Ci0gICAgICAgIH0gIC8vIGVuZCBpZihzdGFydE5vZGUxID09IHN0YXJ0Tm9kZTIpCi0KLSAgICAgICAgICAgICAgICAvLyBNb3ZlIHVwIG9uZSBsZXZlbCBhbmQgdHJ5IGFnYWluCi0gICAgICAgIHByZXZDaGlsZDEgPSBzdGFydE5vZGUxOwotICAgICAgICBzdGFydE5vZGUxID0gZ2V0UGFyZW50T2ZOb2RlKHN0YXJ0Tm9kZTEpOwotICAgICAgICBwcmV2Q2hpbGQyID0gc3RhcnROb2RlMjsKLSAgICAgICAgc3RhcnROb2RlMiA9IGdldFBhcmVudE9mTm9kZShzdGFydE5vZGUyKTsKLSAgICAgIH0gIC8vIGVuZCB3aGlsZShwYXJlbnRzIGV4aXN0IHRvIGV4YW1pbmUpCi0gICAgfSAgLy8gZW5kIGJpZyBlbHNlIChub3QgaW1tZWRpYXRlIHNpYmxpbmdzKQotCi0gICAgICAgIC8vIFdBUk5JTkc6IFRoZSBmb2xsb3dpbmcgZGlhZ25vc3RpYyB3b24ndCByZXBvcnQgdGhlIGVhcmx5Ci0gICAgICAgIC8vICJzYW1lIG5vZGUiIGNhc2UuIEZpeCBpZi93aGVuIG5lZWRlZC4KLQotICAgIC8qIC0tIHBsZWFzZSBkbyBub3QgcmVtb3ZlLi4uIHZlcnkgdXNlZnVsIGZvciBkaWFnbm9zdGljcyAtLQotICAgIFN5c3RlbS5vdXQucHJpbnRsbigibm9kZTEgPSAiK25vZGUxLmdldE5vZGVOYW1lKCkrIigiK25vZGUxLmdldE5vZGVUeXBlKCkrIikiKwotICAgICIsIG5vZGUyID0gIitub2RlMi5nZXROb2RlTmFtZSgpCi0gICAgKyIoIitub2RlMi5nZXROb2RlVHlwZSgpKyIpIisKLSAgICAiLCBpc05vZGVBZnRlciA9ICIraXNOb2RlQWZ0ZXIpOyAqLwotICAgIHJldHVybiBpc05vZGVBZnRlcjsKLSAgfSAgLy8gZW5kIGlzTm9kZUFmdGVyKE5vZGUgbm9kZTEsIE5vZGUgbm9kZTIpCi0KLSAgLyoqCi0gICAqIFVzZSBEVE1Ob2RlUHJveHkgdG8gZGV0ZXJtaW5lIHdoZXRoZXIgdHdvIG5vZGVzIGFyZSB0aGUgc2FtZS4KLSAgICoKLSAgICogQHBhcmFtIG5vZGUxIFRoZSBmaXJzdCBET00gbm9kZSB0byBjb21wYXJlLgotICAgKiBAcGFyYW0gbm9kZTIgVGhlIHNlY29uZCBET00gbm9kZSB0byBjb21wYXJlLgotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHR3byBub2RlcyBhcmUgdGhlIHNhbWUuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNOb2RlVGhlU2FtZShOb2RlIG5vZGUxLCBOb2RlIG5vZGUyKQotICB7Ci0gICAgaWYgKG5vZGUxIGluc3RhbmNlb2YgRFRNTm9kZVByb3h5ICYmIG5vZGUyIGluc3RhbmNlb2YgRFRNTm9kZVByb3h5KQotICAgICAgcmV0dXJuICgoRFRNTm9kZVByb3h5KW5vZGUxKS5lcXVhbHMoKERUTU5vZGVQcm94eSlub2RlMik7Ci0gICAgZWxzZQotICAgICAgcmV0dXJuIChub2RlMSA9PSBub2RlMik7Ci0gIH0KLQotICAvKioKLSAgICogRmlndXJlIG91dCBpZiBjaGlsZDIgaXMgYWZ0ZXIgY2hpbGQxIGluIGRvY3VtZW50IG9yZGVyLgotICAgKiA8cD4KLSAgICogV2FybmluZzogU29tZSBhc3BlY3RzIG9mICJkb2N1bWVudCBvcmRlciIgYXJlIG5vdCB3ZWxsIGRlZmluZWQuCi0gICAqIEZvciBleGFtcGxlLCB0aGUgb3JkZXIgb2YgYXR0cmlidXRlcyBpcyBjb25zaWRlcmVkCi0gICAqIG1lYW5pbmdsZXNzIGluIFhNTCwgYW5kIHRoZSBvcmRlciByZXBvcnRlZCBieSBvdXIgbW9kZWwgd2lsbAotICAgKiBiZSBjb25zaXN0YW50IGZvciBhIGdpdmVuIGludm9jYXRpb24gYnV0IG1heSBub3QKLSAgICogbWF0Y2ggdGhhdCBvZiBlaXRoZXIgdGhlIHNvdXJjZSBmaWxlIG9yIHRoZSBzZXJpYWxpemVkIG91dHB1dC4KLSAgICoKLSAgICogQHBhcmFtIHBhcmVudCBNdXN0IGJlIHRoZSBwYXJlbnQgb2YgYm90aCBjaGlsZDEgYW5kIGNoaWxkMi4KLSAgICogQHBhcmFtIGNoaWxkMSBNdXN0IGJlIHRoZSBjaGlsZCBvZiBwYXJlbnQgYW5kIG5vdCBlcXVhbCB0byBjaGlsZDIuCi0gICAqIEBwYXJhbSBjaGlsZDIgTXVzdCBiZSB0aGUgY2hpbGQgb2YgcGFyZW50IGFuZCBub3QgZXF1YWwgdG8gY2hpbGQxLgotICAgKiBAcmV0dXJuIHRydWUgaWYgY2hpbGQgMiBpcyBhZnRlciBjaGlsZDEgaW4gZG9jdW1lbnQgb3JkZXIuCi0gICAqLwotICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGlzTm9kZUFmdGVyU2libGluZyhOb2RlIHBhcmVudCwgTm9kZSBjaGlsZDEsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5vZGUgY2hpbGQyKQotICB7Ci0KLSAgICBib29sZWFuIGlzTm9kZUFmdGVyU2libGluZyA9IGZhbHNlOwotICAgIHNob3J0IGNoaWxkMXR5cGUgPSBjaGlsZDEuZ2V0Tm9kZVR5cGUoKTsKLSAgICBzaG9ydCBjaGlsZDJ0eXBlID0gY2hpbGQyLmdldE5vZGVUeXBlKCk7Ci0KLSAgICBpZiAoKE5vZGUuQVRUUklCVVRFX05PREUgIT0gY2hpbGQxdHlwZSkKLSAgICAgICAgICAgICYmIChOb2RlLkFUVFJJQlVURV9OT0RFID09IGNoaWxkMnR5cGUpKQotICAgIHsKLQotICAgICAgLy8gYWx3YXlzIHNvcnQgYXR0cmlidXRlcyBiZWZvcmUgbm9uLWF0dHJpYnV0ZXMuCi0gICAgICBpc05vZGVBZnRlclNpYmxpbmcgPSBmYWxzZTsKLSAgICB9Ci0gICAgZWxzZSBpZiAoKE5vZGUuQVRUUklCVVRFX05PREUgPT0gY2hpbGQxdHlwZSkKLSAgICAgICAgICAgICAmJiAoTm9kZS5BVFRSSUJVVEVfTk9ERSAhPSBjaGlsZDJ0eXBlKSkKLSAgICB7Ci0KLSAgICAgIC8vIGFsd2F5cyBzb3J0IGF0dHJpYnV0ZXMgYmVmb3JlIG5vbi1hdHRyaWJ1dGVzLgotICAgICAgaXNOb2RlQWZ0ZXJTaWJsaW5nID0gdHJ1ZTsKLSAgICB9Ci0gICAgZWxzZSBpZiAoTm9kZS5BVFRSSUJVVEVfTk9ERSA9PSBjaGlsZDF0eXBlKQotICAgIHsKLSAgICAgIE5hbWVkTm9kZU1hcCBjaGlsZHJlbiA9IHBhcmVudC5nZXRBdHRyaWJ1dGVzKCk7Ci0gICAgICBpbnQgbk5vZGVzID0gY2hpbGRyZW4uZ2V0TGVuZ3RoKCk7Ci0gICAgICBib29sZWFuIGZvdW5kMSA9IGZhbHNlLCBmb3VuZDIgPSBmYWxzZTsKLQotICAgICAgICAgIC8vIENvdW50IGZyb20gdGhlIHN0YXJ0IHVudGlsIHdlIGZpbmQgb25lIG9yIHRoZSBvdGhlci4KLSAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbk5vZGVzOyBpKyspCi0gICAgICB7Ci0gICAgICAgIE5vZGUgY2hpbGQgPSBjaGlsZHJlbi5pdGVtKGkpOwotCi0gICAgICAgIGlmIChjaGlsZDEgPT0gY2hpbGQgfHwgaXNOb2RlVGhlU2FtZShjaGlsZDEsIGNoaWxkKSkKLSAgICAgICAgewotICAgICAgICAgIGlmIChmb3VuZDIpCi0gICAgICAgICAgewotICAgICAgICAgICAgaXNOb2RlQWZ0ZXJTaWJsaW5nID0gZmFsc2U7Ci0KLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgIH0KLQotICAgICAgICAgIGZvdW5kMSA9IHRydWU7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoY2hpbGQyID09IGNoaWxkIHx8IGlzTm9kZVRoZVNhbWUoY2hpbGQyLCBjaGlsZCkpCi0gICAgICAgIHsKLSAgICAgICAgICBpZiAoZm91bmQxKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGlzTm9kZUFmdGVyU2libGluZyA9IHRydWU7Ci0KLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgIH0KLQotICAgICAgICAgIGZvdW5kMiA9IHRydWU7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgICAgICAgICAgICAvLyBUT0RPOiBDaGVjayBwZXJmb3JtYW5jZSBvZiBhbHRlcm5hdGUgc29sdXRpb246Ci0gICAgICAgICAgICAgICAgLy8gVGhlcmUgYXJlIHR3byBjaG9pY2VzIGhlcmU6IENvdW50IGZyb20gdGhlIHN0YXJ0IG9mCi0gICAgICAgICAgICAgICAgLy8gdGhlIGRvY3VtZW50IHVudGlsIHdlIGZpbmQgb25lIG9yIHRoZSBvdGhlciwgb3IgY291bnQKLSAgICAgICAgICAgICAgICAvLyBmcm9tIG9uZSB1bnRpbCB3ZSBmaW5kIG9yIGZhaWwgdG8gZmluZCB0aGUgb3RoZXIuCi0gICAgICAgICAgICAgICAgLy8gRWl0aGVyIGNhbiB3aW5kIHVwIHNjYW5uaW5nIGFsbCB0aGUgc2libGluZ3MgaW4gdGhlIHdvcnN0Ci0gICAgICAgICAgICAgICAgLy8gY2FzZSwgd2hpY2ggb24gYSB3aWRlIGRvY3VtZW50IGNhbiBiZSBhIGxvdCBvZiB3b3JrIGJ1dAotICAgICAgICAgICAgICAgIC8vIGlzIG1vcmUgdHlwaWNhbGx5IGlzIGEgc2hvcnQgbGlzdC4KLSAgICAgICAgICAgICAgICAvLyBTY2FubmluZyBmcm9tIHRoZSBzdGFydCBpbnZvbHZlcyB0d28gdGVzdHMgcGVyIGl0ZXJhdGlvbiwKLSAgICAgICAgICAgICAgICAvLyBidXQgaXQgaXNuJ3QgY2xlYXIgdGhhdCBzY2FubmluZyBmcm9tIHRoZSBtaWRkbGUgZG9lc24ndAotICAgICAgICAgICAgICAgIC8vIHlpZWxkIG1vcmUgaXRlcmF0aW9ucyBvbiBhdmVyYWdlLgotICAgICAgICAgICAgICAgIC8vIFdlIHNob3VsZCBydW4gc29tZSB0ZXN0Y2FzZXMuCi0gICAgICBOb2RlIGNoaWxkID0gcGFyZW50LmdldEZpcnN0Q2hpbGQoKTsKLSAgICAgIGJvb2xlYW4gZm91bmQxID0gZmFsc2UsIGZvdW5kMiA9IGZhbHNlOwotCi0gICAgICB3aGlsZSAobnVsbCAhPSBjaGlsZCkKLSAgICAgIHsKLQotICAgICAgICAvLyBOb2RlIGNoaWxkID0gY2hpbGRyZW4uaXRlbShpKTsKLSAgICAgICAgaWYgKGNoaWxkMSA9PSBjaGlsZCB8fCBpc05vZGVUaGVTYW1lKGNoaWxkMSwgY2hpbGQpKQotICAgICAgICB7Ci0gICAgICAgICAgaWYgKGZvdW5kMikKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBpc05vZGVBZnRlclNpYmxpbmcgPSBmYWxzZTsKLQotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgfQotCi0gICAgICAgICAgZm91bmQxID0gdHJ1ZTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChjaGlsZDIgPT0gY2hpbGQgfHwgaXNOb2RlVGhlU2FtZShjaGlsZDIsIGNoaWxkKSkKLSAgICAgICAgewotICAgICAgICAgIGlmIChmb3VuZDEpCi0gICAgICAgICAgewotICAgICAgICAgICAgaXNOb2RlQWZ0ZXJTaWJsaW5nID0gdHJ1ZTsKLQotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgfQotCi0gICAgICAgICAgZm91bmQyID0gdHJ1ZTsKLSAgICAgICAgfQotCi0gICAgICAgIGNoaWxkID0gY2hpbGQuZ2V0TmV4dFNpYmxpbmcoKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gaXNOb2RlQWZ0ZXJTaWJsaW5nOwotICB9ICAvLyBlbmQgaXNOb2RlQWZ0ZXJTaWJsaW5nKE5vZGUgcGFyZW50LCBOb2RlIGNoaWxkMSwgTm9kZSBjaGlsZDIpCi0KLSAgLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gIC8vIFNFQ1RJT046IE5hbWVzcGFjZSByZXNvbHV0aW9uCi0gIC8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGRlcHRoIGxldmVsIG9mIHRoaXMgbm9kZSBpbiB0aGUgdHJlZSAoZXF1YWxzIDEgZm9yCi0gICAqIGEgcGFyZW50bGVzcyBub2RlKS4KLSAgICoKLSAgICogQHBhcmFtIG4gTm9kZSB0byBiZSBleGFtaW5lZC4KLSAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGFuY2VzdG9ycywgcGx1cyBvbmUKLSAgICogQHhzbC51c2FnZSBpbnRlcm5hbAotICAgKi8KLSAgcHVibGljIHNob3J0IGdldExldmVsKE5vZGUgbikKLSAgewotCi0gICAgc2hvcnQgbGV2ZWwgPSAxOwotCi0gICAgd2hpbGUgKG51bGwgIT0gKG4gPSBnZXRQYXJlbnRPZk5vZGUobikpKQotICAgIHsKLSAgICAgIGxldmVsKys7Ci0gICAgfQotCi0gICAgcmV0dXJuIGxldmVsOwotICB9Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGFuIFhNTCBOYW1lc3BhY2UgcHJlZml4IGFuZCBhIGNvbnRleHQgaW4gd2hpY2ggdGhlIHByZWZpeAotICAgKiBpcyB0byBiZSBldmFsdWF0ZWQsIHJldHVybiB0aGUgTmFtZXNwYWNlIE5hbWUgdGhpcyBwcmVmaXggd2FzCi0gICAqIGJvdW5kIHRvLiBOb3RlIHRoYXQgRE9NIExldmVsIDMgaXMgZXhwZWN0ZWQgdG8gcHJvdmlkZSBhIHZlcnNpb24gb2YKLSAgICogdGhpcyB3aGljaCBkZWFscyB3aXRoIHRoZSBET00ncyAiZWFybHkgYmluZGluZyIgYmVoYXZpb3IuCi0gICAqCi0gICAqIERlZmF1bHQgaGFuZGxpbmc6Ci0gICAqCi0gICAqIEBwYXJhbSBwcmVmaXggU3RyaW5nIGNvbnRhaW5pbmcgbmFtZXNwYWNlIHByZWZpeCB0byBiZSByZXNvbHZlZCwKLSAgICogd2l0aG91dCB0aGUgJzonIHdoaWNoIHNlcGFyYXRlcyBpdCBmcm9tIHRoZSBsb2NhbG5hbWUgd2hlbiB1c2VkCi0gICAqIGluIGEgTm9kZSBOYW1lLiBUaGUgZW1wdHkgc3Rpbmcgc2lnbmlmaWVzIHRoZSBkZWZhdWx0IG5hbWVzcGFjZQotICAgKiBhdCB0aGlzIHBvaW50IGluIHRoZSBkb2N1bWVudC4KLSAgICogQHBhcmFtIG5hbWVzcGFjZUNvbnRleHQgRWxlbWVudCB3aGljaCBwcm92aWRlcyBjb250ZXh0IGZvciByZXNvbHV0aW9uLgotICAgKiAoV2UgY291bGQgZXh0ZW5kIHRoaXMgdG8gd29yayBmb3Igb3RoZXIgbm9kZXMgYnkgZmlyc3Qgc2Vla2luZyB0aGVpcgotICAgKiBuZWFyZXN0IEVsZW1lbnQgYW5jZXN0b3IuKQotICAgKgotICAgKiBAcmV0dXJuIGEgU3RyaW5nIGNvbnRhaW5pbmcgdGhlIE5hbWVzcGFjZSBVUkkgd2hpY2ggdGhpcyBwcmVmaXgKLSAgICogcmVwcmVzZW50cyBpbiB0aGUgc3BlY2lmaWVkIGNvbnRleHQuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldE5hbWVzcGFjZUZvclByZWZpeChTdHJpbmcgcHJlZml4LCBFbGVtZW50IG5hbWVzcGFjZUNvbnRleHQpCi0gIHsKLQotICAgIGludCB0eXBlOwotICAgIE5vZGUgcGFyZW50ID0gbmFtZXNwYWNlQ29udGV4dDsKLSAgICBTdHJpbmcgbmFtZXNwYWNlID0gbnVsbDsKLQotICAgIGlmIChwcmVmaXguZXF1YWxzKCJ4bWwiKSkKLSAgICB7Ci0gICAgICBuYW1lc3BhY2UgPSBRTmFtZS5TX1hNTE5BTUVTUEFDRVVSSTsgLy8gSGFyZGNvZGVkLCBwZXIgTmFtZXNwYWNlIHNwZWMKLSAgICB9Ci0gICAgICAgIGVsc2UgaWYocHJlZml4LmVxdWFscygieG1sbnMiKSkKLSAgICB7Ci0gICAgICAgICAgLy8gSGFyZGNvZGVkIGluIHRoZSBET00gc3BlYywgZXhwZWN0ZWQgdG8gYmUgYWRvcHRlZCBieQotICAgICAgICAgIC8vIE5hbWVzcGFjZSBzcGVjLiBOT1RFOiBOYW1lc3BhY2UgZGVjbGFyYXRpb25zIF9tdXN0XyB1c2UKLSAgICAgICAgICAvLyB0aGUgeG1sbnM6IHByZWZpeDsgb3RoZXIgcHJlZml4ZXMgZGVjbGFyZWQgYXMgYmVsb25naW5nCi0gICAgICAgICAgLy8gdG8gdGhpcyBuYW1lc3BhY2Ugd2lsbCBub3QgYmUgcmVjb2duaXplZCBhbmQgc2hvdWxkCi0gICAgICAgICAgLy8gcHJvYmFibHkgYmUgcmVqZWN0ZWQgYnkgcGFyc2VycyBhcyBlcnJvbmVvdXMgZGVjbGFyYXRpb25zLgotICAgICAgbmFtZXNwYWNlID0gImh0dHA6Ly93d3cudzMub3JnLzIwMDAveG1sbnMvIjsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgICAgICAvLyBBdHRyaWJ1dGUgbmFtZSBmb3IgdGhpcyBwcmVmaXgncyBkZWNsYXJhdGlvbgotICAgICAgICAgIFN0cmluZyBkZWNsbmFtZT0ocHJlZml4PT0iIikKLSAgICAgICAgICAgICAgICAgICAgICAgID8gInhtbG5zIgotICAgICAgICAgICAgICAgICAgICAgICAgOiAieG1sbnM6IitwcmVmaXg7Ci0KLSAgICAgICAgICAvLyBTY2FuIHVudGlsIHdlIHJ1biBvdXQgb2YgRWxlbWVudHMgb3IgaGF2ZSByZXNvbHZlZCB0aGUgbmFtZXNwYWNlCi0gICAgICB3aGlsZSAoKG51bGwgIT0gcGFyZW50KSAmJiAobnVsbCA9PSBuYW1lc3BhY2UpCi0gICAgICAgICAgICAgJiYgKCgodHlwZSA9IHBhcmVudC5nZXROb2RlVHlwZSgpKSA9PSBOb2RlLkVMRU1FTlRfTk9ERSkKLSAgICAgICAgICAgICAgICAgfHwgKHR5cGUgPT0gTm9kZS5FTlRJVFlfUkVGRVJFTkNFX05PREUpKSkKLSAgICAgIHsKLSAgICAgICAgaWYgKHR5cGUgPT0gTm9kZS5FTEVNRU5UX05PREUpCi0gICAgICAgIHsKLQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gTG9vayBmb3IgdGhlIGFwcHJvcHJpYXRlIE5hbWVzcGFjZSBEZWNsYXJhdGlvbiBhdHRyaWJ1dGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBlaXRoZXIgInhtbG5zOnByZWZpeCIgb3IgKGlmIHByZWZpeCBpcyAiIikgInhtbG5zIi4KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRPRE86IFRoaXMgZG9lcyBub3QgaGFuZGxlICJpbXBsaWNpdCBkZWNsYXJhdGlvbnMiCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyB3aGljaCBtYXkgYmUgY3JlYXRlZCB3aGVuIHRoZSBET00gaXMgZWRpdGVkLiBET00gTGV2ZWwKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIDMgd2lsbCBkZWZpbmUgaG93IHRob3NlIHNob3VsZCBiZSBpbnRlcnByZXRlZC4gQnV0Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGlzIGlzc3VlIHdvbid0IGFyaXNlIGluIGZyZXNobHktcGFyc2VkIERPTXMuCi0KLSAgICAgICAgICAgICAgICAvLyBOT1RFOiBkZWNsbmFtZSBpcyBzZXQgZWFybGllciwgb3V0c2lkZSB0aGUgbG9vcC4KLSAgICAgICAgICAgICAgICAgICAgICAgIEF0dHIgYXR0cj0oKEVsZW1lbnQpcGFyZW50KS5nZXRBdHRyaWJ1dGVOb2RlKGRlY2xuYW1lKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmKGF0dHIhPW51bGwpCi0gICAgICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgbmFtZXNwYWNlID0gYXR0ci5nZXROb2RlVmFsdWUoKTsKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgcGFyZW50ID0gZ2V0UGFyZW50T2ZOb2RlKHBhcmVudCk7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgcmV0dXJuIG5hbWVzcGFjZTsKLSAgfQotCi0gIC8qKgotICAgKiBBbiBleHBlcmltZW50IGZvciB0aGUgbW9tZW50LgotICAgKi8KLSAgTWFwPE5vZGUsIE5TSW5mbz4gbV9OU0luZm9zID0gbmV3IEhhc2hNYXA8PigpOwotCi0gIC8qKiBPYmplY3QgdG8gcHV0IGludG8gdGhlIG1fTlNJbmZvcyB0YWJsZSB0aGF0IHRlbGxzIHRoYXQgYSBub2RlIGhhcyBub3QgYmVlbgotICAgKiAgcHJvY2Vzc2VkLCBidXQgaGFzIHhtbG5zIG5hbWVzcGFjZSBkZWNscy4gICovCi0gIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgTlNJbmZvIG1fTlNJbmZvVW5Qcm9jV2l0aFhNTE5TID0gbmV3IE5TSW5mbyhmYWxzZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUpOwotCi0gIC8qKiBPYmplY3QgdG8gcHV0IGludG8gdGhlIG1fTlNJbmZvcyB0YWJsZSB0aGF0IHRlbGxzIHRoYXQgYSBub2RlIGhhcyBub3QgYmVlbgotICAgKiAgcHJvY2Vzc2VkLCBidXQgaGFzIG5vIHhtbG5zIG5hbWVzcGFjZSBkZWNscy4gICovCi0gIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgTlNJbmZvIG1fTlNJbmZvVW5Qcm9jV2l0aG91dFhNTE5TID0gbmV3IE5TSW5mbyhmYWxzZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlKTsKLQotICAvKiogT2JqZWN0IHRvIHB1dCBpbnRvIHRoZSBtX05TSW5mb3MgdGFibGUgdGhhdCB0ZWxscyB0aGF0IGEgbm9kZSBoYXMgbm90IGJlZW4KLSAgICogIHByb2Nlc3NlZCwgYW5kIGhhcyBubyB4bWxucyBuYW1lc3BhY2UgZGVjbHMsIGFuZCBoYXMgbm8gYW5jZXN0b3IgZGVjbHMuICAqLwotICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIE5TSW5mbyBtX05TSW5mb1VuUHJvY05vQW5jZXN0b3JYTUxOUyA9Ci0gICAgbmV3IE5TSW5mbyhmYWxzZSwgZmFsc2UsIE5TSW5mby5BTkNFU1RPUk5PWE1MTlMpOwotCi0gIC8qKiBPYmplY3QgdG8gcHV0IGludG8gdGhlIG1fTlNJbmZvcyB0YWJsZSB0aGF0IHRlbGxzIHRoYXQgYSBub2RlIGhhcyBiZWVuCi0gICAqICBwcm9jZXNzZWQsIGFuZCBoYXMgeG1sbnMgbmFtZXNwYWNlIGRlY2xzLiAgKi8KLSAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBOU0luZm8gbV9OU0luZm9OdWxsV2l0aFhNTE5TID0gbmV3IE5TSW5mbyh0cnVlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUpOwotCi0gIC8qKiBPYmplY3QgdG8gcHV0IGludG8gdGhlIG1fTlNJbmZvcyB0YWJsZSB0aGF0IHRlbGxzIHRoYXQgYSBub2RlIGhhcyBiZWVuCi0gICAqICBwcm9jZXNzZWQsIGFuZCBoYXMgbm8geG1sbnMgbmFtZXNwYWNlIGRlY2xzLiAgKi8KLSAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBOU0luZm8gbV9OU0luZm9OdWxsV2l0aG91dFhNTE5TID0gbmV3IE5TSW5mbyh0cnVlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlKTsKLQotICAvKiogT2JqZWN0IHRvIHB1dCBpbnRvIHRoZSBtX05TSW5mb3MgdGFibGUgdGhhdCB0ZWxscyB0aGF0IGEgbm9kZSBoYXMgYmVlbgotICAgKiAgcHJvY2Vzc2VkLCBhbmQgaGFzIG5vIHhtbG5zIG5hbWVzcGFjZSBkZWNscy4gYW5kIGhhcyBubyBhbmNlc3RvciBkZWNscy4gICovCi0gIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgTlNJbmZvIG1fTlNJbmZvTnVsbE5vQW5jZXN0b3JYTUxOUyA9Ci0gICAgbmV3IE5TSW5mbyh0cnVlLCBmYWxzZSwgTlNJbmZvLkFOQ0VTVE9STk9YTUxOUyk7Ci0KLSAgLyoqIFZlY3RvciBvZiBub2RlIChvZGQgaW5kZXhlcykgYW5kIE5TSW5mb3MgKGV2ZW4gaW5kZXhlcykgdGhhdCB0ZWxsIGlmCi0gICAqICB0aGUgZ2l2ZW4gbm9kZSBpcyBhIGNhbmRpZGF0ZSBmb3IgYW5jZXN0b3IgbmFtZXNwYWNlIHByb2Nlc3NpbmcuICAqLwotICBwcm90ZWN0ZWQgVmVjdG9yIG1fY2FuZGlkYXRlTm9BbmNlc3RvclhNTE5TID0gbmV3IFZlY3RvcigpOwotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBuYW1lc3BhY2Ugb2YgdGhlIGdpdmVuIG5vZGUuIERpZmZlcnMgZnJvbSBzaW1wbHkgZ2V0dGluZwotICAgKiB0aGUgbm9kZSdzIHByZWZpeCBhbmQgdXNpbmcgZ2V0TmFtZXNwYWNlRm9yUHJlZml4IGluIHRoYXQgaXQgYXR0ZW1wdHMKLSAgICogdG8gY2FjaGUgc29tZSBvZiB0aGUgZGF0YSBpbiBOU0lORk8gb2JqZWN0cywgdG8gYXZvaWQgcmVwZWF0ZWQgbG9va3VwLgotICAgKiBUT0RPOiBTaG91bGQgd2UgY29uc2lkZXIgbW92aW5nIHRoYXQgbG9naWMgaW50byBnZXROYW1lc3BhY2VGb3JQcmVmaXg/Ci0gICAqCi0gICAqIEBwYXJhbSBuIE5vZGUgdG8gYmUgZXhhbWluZWQuCi0gICAqCi0gICAqIEByZXR1cm4gU3RyaW5nIGNvbnRhaW5pbmcgdGhlIE5hbWVzcGFjZSBOYW1lICh1cmkpIGZvciB0aGlzIG5vZGUuCi0gICAqIE5vdGUgdGhhdCB0aGlzIGlzIHVuZGVmaW5lZCBmb3IgYW55IG5vZGVzIG90aGVyIHRoYW4gRWxlbWVudHMgYW5kCi0gICAqIEF0dHJpYnV0ZXMuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldE5hbWVzcGFjZU9mTm9kZShOb2RlIG4pCi0gIHsKLQotICAgIFN0cmluZyBuYW1lc3BhY2VPZlByZWZpeDsKLSAgICBib29sZWFuIGhhc1Byb2Nlc3NlZE5TOwotICAgIE5TSW5mbyBuc0luZm87Ci0gICAgc2hvcnQgbnR5cGUgPSBuLmdldE5vZGVUeXBlKCk7Ci0KLSAgICBpZiAoTm9kZS5BVFRSSUJVVEVfTk9ERSAhPSBudHlwZSkKLSAgICB7Ci0gICAgICBuc0luZm8gPSBtX05TSW5mb3MuZ2V0KG4pOwotICAgICAgaGFzUHJvY2Vzc2VkTlMgPSAobnNJbmZvID09IG51bGwpID8gZmFsc2UgOiBuc0luZm8ubV9oYXNQcm9jZXNzZWROUzsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIGhhc1Byb2Nlc3NlZE5TID0gZmFsc2U7Ci0gICAgICBuc0luZm8gPSBudWxsOwotICAgIH0KLQotICAgIGlmIChoYXNQcm9jZXNzZWROUykKLSAgICB7Ci0gICAgICBuYW1lc3BhY2VPZlByZWZpeCA9IG5zSW5mby5tX25hbWVzcGFjZTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIG5hbWVzcGFjZU9mUHJlZml4ID0gbnVsbDsKLQotICAgICAgU3RyaW5nIG5vZGVOYW1lID0gbi5nZXROb2RlTmFtZSgpOwotICAgICAgaW50IGluZGV4T2ZOU1NlcCA9IG5vZGVOYW1lLmluZGV4T2YoJzonKTsKLSAgICAgIFN0cmluZyBwcmVmaXg7Ci0KLSAgICAgIGlmIChOb2RlLkFUVFJJQlVURV9OT0RFID09IG50eXBlKQotICAgICAgewotICAgICAgICBpZiAoaW5kZXhPZk5TU2VwID4gMCkKLSAgICAgICAgewotICAgICAgICAgIHByZWZpeCA9IG5vZGVOYW1lLnN1YnN0cmluZygwLCBpbmRleE9mTlNTZXApOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotCi0gICAgICAgICAgLy8gQXR0cmlidXRlcyBkb24ndCB1c2UgdGhlIGRlZmF1bHQgbmFtZXNwYWNlLCBzbyBpZgotICAgICAgICAgIC8vIHRoZXJlIGlzbid0IGEgcHJlZml4LCB3ZSdyZSBkb25lLgotICAgICAgICAgIHJldHVybiBuYW1lc3BhY2VPZlByZWZpeDsKLSAgICAgICAgfQotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBwcmVmaXggPSAoaW5kZXhPZk5TU2VwID49IDApCi0gICAgICAgICAgICAgICAgID8gbm9kZU5hbWUuc3Vic3RyaW5nKDAsIGluZGV4T2ZOU1NlcCkgOiAiIjsKLSAgICAgIH0KLQotICAgICAgYm9vbGVhbiBhbmNlc3RvcnNIYXZlWE1MTlMgPSBmYWxzZTsKLSAgICAgIGJvb2xlYW4gbkhhc1hNTE5TID0gZmFsc2U7Ci0KLSAgICAgIGlmIChwcmVmaXguZXF1YWxzKCJ4bWwiKSkKLSAgICAgIHsKLSAgICAgICAgbmFtZXNwYWNlT2ZQcmVmaXggPSBRTmFtZS5TX1hNTE5BTUVTUEFDRVVSSTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgaW50IHBhcmVudFR5cGU7Ci0gICAgICAgIE5vZGUgcGFyZW50ID0gbjsKLQotICAgICAgICB3aGlsZSAoKG51bGwgIT0gcGFyZW50KSAmJiAobnVsbCA9PSBuYW1lc3BhY2VPZlByZWZpeCkpCi0gICAgICAgIHsKLSAgICAgICAgICBpZiAoKG51bGwgIT0gbnNJbmZvKQotICAgICAgICAgICAgICAgICAgJiYgKG5zSW5mby5tX2FuY2VzdG9ySGFzWE1MTlNBdHRycwotICAgICAgICAgICAgICAgICAgICAgID09IE5TSW5mby5BTkNFU1RPUk5PWE1MTlMpKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgIH0KLQotICAgICAgICAgIHBhcmVudFR5cGUgPSBwYXJlbnQuZ2V0Tm9kZVR5cGUoKTsKLQotICAgICAgICAgIGlmICgobnVsbCA9PSBuc0luZm8pIHx8IG5zSW5mby5tX2hhc1hNTE5TQXR0cnMpCi0gICAgICAgICAgewotICAgICAgICAgICAgYm9vbGVhbiBlbGVtZW50SGFzWE1MTlMgPSBmYWxzZTsKLQotICAgICAgICAgICAgaWYgKHBhcmVudFR5cGUgPT0gTm9kZS5FTEVNRU5UX05PREUpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIE5hbWVkTm9kZU1hcCBubm0gPSBwYXJlbnQuZ2V0QXR0cmlidXRlcygpOwotCi0gICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbm5tLmdldExlbmd0aCgpOyBpKyspCi0gICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBOb2RlIGF0dHIgPSBubm0uaXRlbShpKTsKLSAgICAgICAgICAgICAgICBTdHJpbmcgYW5hbWUgPSBhdHRyLmdldE5vZGVOYW1lKCk7Ci0KLSAgICAgICAgICAgICAgICBpZiAoYW5hbWUuY2hhckF0KDApID09ICd4JykKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICBib29sZWFuIGlzUHJlZml4ID0gYW5hbWUuc3RhcnRzV2l0aCgieG1sbnM6Iik7Ci0KLSAgICAgICAgICAgICAgICAgIGlmIChhbmFtZS5lcXVhbHMoInhtbG5zIikgfHwgaXNQcmVmaXgpCi0gICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChuID09IHBhcmVudCkKLSAgICAgICAgICAgICAgICAgICAgICBuSGFzWE1MTlMgPSB0cnVlOwotCi0gICAgICAgICAgICAgICAgICAgIGVsZW1lbnRIYXNYTUxOUyA9IHRydWU7Ci0gICAgICAgICAgICAgICAgICAgIGFuY2VzdG9yc0hhdmVYTUxOUyA9IHRydWU7Ci0KLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHAgPSBpc1ByZWZpeCA/IGFuYW1lLnN1YnN0cmluZyg2KSA6ICIiOwotCi0gICAgICAgICAgICAgICAgICAgIGlmIChwLmVxdWFscyhwcmVmaXgpKQotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgbmFtZXNwYWNlT2ZQcmVmaXggPSBhdHRyLmdldE5vZGVWYWx1ZSgpOwotCi0gICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKChOb2RlLkFUVFJJQlVURV9OT0RFICE9IHBhcmVudFR5cGUpICYmIChudWxsID09IG5zSW5mbykKLSAgICAgICAgICAgICAgICAgICAgJiYgKG4gIT0gcGFyZW50KSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgbnNJbmZvID0gZWxlbWVudEhhc1hNTE5TCi0gICAgICAgICAgICAgICAgICAgICAgID8gbV9OU0luZm9VblByb2NXaXRoWE1MTlMgOiBtX05TSW5mb1VuUHJvY1dpdGhvdXRYTUxOUzsKLQotICAgICAgICAgICAgICBtX05TSW5mb3MucHV0KHBhcmVudCwgbnNJbmZvKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICB9Ci0KLSAgICAgICAgICBpZiAoTm9kZS5BVFRSSUJVVEVfTk9ERSA9PSBwYXJlbnRUeXBlKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIHBhcmVudCA9IGdldFBhcmVudE9mTm9kZShwYXJlbnQpOwotICAgICAgICAgIH0KLSAgICAgICAgICBlbHNlCi0gICAgICAgICAgewotICAgICAgICAgICAgbV9jYW5kaWRhdGVOb0FuY2VzdG9yWE1MTlMuYWRkRWxlbWVudChwYXJlbnQpOwotICAgICAgICAgICAgbV9jYW5kaWRhdGVOb0FuY2VzdG9yWE1MTlMuYWRkRWxlbWVudChuc0luZm8pOwotCi0gICAgICAgICAgICBwYXJlbnQgPSBwYXJlbnQuZ2V0UGFyZW50Tm9kZSgpOwotICAgICAgICAgIH0KLQotICAgICAgICAgIGlmIChudWxsICE9IHBhcmVudCkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBuc0luZm8gPSBtX05TSW5mb3MuZ2V0KHBhcmVudCk7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgaW50IG5DYW5kaWRhdGVzID0gbV9jYW5kaWRhdGVOb0FuY2VzdG9yWE1MTlMuc2l6ZSgpOwotCi0gICAgICAgIGlmIChuQ2FuZGlkYXRlcyA+IDApCi0gICAgICAgIHsKLSAgICAgICAgICBpZiAoKGZhbHNlID09IGFuY2VzdG9yc0hhdmVYTUxOUykgJiYgKG51bGwgPT0gcGFyZW50KSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG5DYW5kaWRhdGVzOyBpICs9IDIpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIE9iamVjdCBjYW5kaWRhdGVJbmZvID0gbV9jYW5kaWRhdGVOb0FuY2VzdG9yWE1MTlMuZWxlbWVudEF0KGkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgMSk7Ci0KLSAgICAgICAgICAgICAgaWYgKGNhbmRpZGF0ZUluZm8gPT0gbV9OU0luZm9VblByb2NXaXRob3V0WE1MTlMpCi0gICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBtX05TSW5mb3MucHV0KChOb2RlKW1fY2FuZGlkYXRlTm9BbmNlc3RvclhNTE5TLmVsZW1lbnRBdChpKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fTlNJbmZvVW5Qcm9jTm9BbmNlc3RvclhNTE5TKTsKLSAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICBlbHNlIGlmIChjYW5kaWRhdGVJbmZvID09IG1fTlNJbmZvTnVsbFdpdGhvdXRYTUxOUykKLSAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIG1fTlNJbmZvcy5wdXQoKE5vZGUpbV9jYW5kaWRhdGVOb0FuY2VzdG9yWE1MTlMuZWxlbWVudEF0KGkpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbV9OU0luZm9OdWxsTm9BbmNlc3RvclhNTE5TKTsKLSAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgIH0KLQotICAgICAgICAgIG1fY2FuZGlkYXRlTm9BbmNlc3RvclhNTE5TLnJlbW92ZUFsbEVsZW1lbnRzKCk7Ci0gICAgICAgIH0KLSAgICAgIH0KLQotICAgICAgaWYgKE5vZGUuQVRUUklCVVRFX05PREUgIT0gbnR5cGUpCi0gICAgICB7Ci0gICAgICAgIGlmIChudWxsID09IG5hbWVzcGFjZU9mUHJlZml4KQotICAgICAgICB7Ci0gICAgICAgICAgaWYgKGFuY2VzdG9yc0hhdmVYTUxOUykKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBpZiAobkhhc1hNTE5TKQotICAgICAgICAgICAgICBtX05TSW5mb3MucHV0KG4sIG1fTlNJbmZvTnVsbFdpdGhYTUxOUyk7Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgIG1fTlNJbmZvcy5wdXQobiwgbV9OU0luZm9OdWxsV2l0aG91dFhNTE5TKTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgIHsKLSAgICAgICAgICAgIG1fTlNJbmZvcy5wdXQobiwgbV9OU0luZm9OdWxsTm9BbmNlc3RvclhNTE5TKTsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICB7Ci0gICAgICAgICAgbV9OU0luZm9zLnB1dChuLCBuZXcgTlNJbmZvKG5hbWVzcGFjZU9mUHJlZml4LCBuSGFzWE1MTlMpKTsKLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiBuYW1lc3BhY2VPZlByZWZpeDsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBsb2NhbCBuYW1lIG9mIHRoZSBnaXZlbiBub2RlLiBJZiB0aGUgbm9kZSdzIG5hbWUgYmVnaW5zCi0gICAqIHdpdGggYSBuYW1lc3BhY2UgcHJlZml4LCB0aGlzIGlzIHRoZSBwYXJ0IGFmdGVyIHRoZSBjb2xvbjsgb3RoZXJ3aXNlCi0gICAqIGl0J3MgdGhlIGZ1bGwgbm9kZSBuYW1lLgotICAgKgotICAgKiBAcGFyYW0gbiB0aGUgbm9kZSB0byBiZSBleGFtaW5lZC4KLSAgICoKLSAgICogQHJldHVybiBTdHJpbmcgY29udGFpbmluZyB0aGUgTG9jYWwgTmFtZQotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRMb2NhbE5hbWVPZk5vZGUoTm9kZSBuKQotICB7Ci0KLSAgICBTdHJpbmcgcW5hbWUgPSBuLmdldE5vZGVOYW1lKCk7Ci0gICAgaW50IGluZGV4ID0gcW5hbWUuaW5kZXhPZignOicpOwotCi0gICAgcmV0dXJuIChpbmRleCA8IDApID8gcW5hbWUgOiBxbmFtZS5zdWJzdHJpbmcoaW5kZXggKyAxKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBlbGVtZW50IG5hbWUgd2l0aCB0aGUgbmFtZXNwYWNlIHByZWZpeCAoaWYgYW55KSByZXBsYWNlZAotICAgKiBieSB0aGUgTmFtZXNwYWNlIFVSSSBpdCB3YXMgYm91bmQgdG8uIFRoaXMgaXMgbm90IGEgc3RhbmRhcmQKLSAgICogcmVwcmVzZW50YXRpb24gb2YgYSBub2RlIG5hbWUsIGJ1dCBpdCBhbGxvd3MgY29udmVuaWVudAotICAgKiBzaW5nbGUtc3RyaW5nIGNvbXBhcmlzb24gb2YgdGhlICJ1bml2ZXJzYWwiIG5hbWVzIG9mIHR3byBub2Rlcy4KLSAgICoKLSAgICogQHBhcmFtIGVsZW0gRWxlbWVudCB0byBiZSBleGFtaW5lZC4KLSAgICoKLSAgICogQHJldHVybiBTdHJpbmcgaW4gdGhlIGZvcm0gIm5hbWVzcGFjZVVSSTpsb2NhbG5hbWUiIGlmIHRoZSBub2RlCi0gICAqIGJlbG9uZ3MgdG8gYSBuYW1lc3BhY2UsIG9yIHNpbXBseSAibG9jYWxuYW1lIiBpZiBpdCBkb2Vzbid0LgotICAgKiBAc2VlICNnZXRFeHBhbmRlZEF0dHJpYnV0ZU5hbWUKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0RXhwYW5kZWRFbGVtZW50TmFtZShFbGVtZW50IGVsZW0pCi0gIHsKLQotICAgIFN0cmluZyBuYW1lc3BhY2UgPSBnZXROYW1lc3BhY2VPZk5vZGUoZWxlbSk7Ci0KLSAgICByZXR1cm4gKG51bGwgIT0gbmFtZXNwYWNlKQotICAgICAgICAgICA/IG5hbWVzcGFjZSArICI6IiArIGdldExvY2FsTmFtZU9mTm9kZShlbGVtKQotICAgICAgICAgICA6IGdldExvY2FsTmFtZU9mTm9kZShlbGVtKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBhdHRyaWJ1dGUgbmFtZSB3aXRoIHRoZSBuYW1lc3BhY2UgcHJlZml4IChpZiBhbnkpIHJlcGxhY2VkCi0gICAqIGJ5IHRoZSBOYW1lc3BhY2UgVVJJIGl0IHdhcyBib3VuZCB0by4gVGhpcyBpcyBub3QgYSBzdGFuZGFyZAotICAgKiByZXByZXNlbnRhdGlvbiBvZiBhIG5vZGUgbmFtZSwgYnV0IGl0IGFsbG93cyBjb252ZW5pZW50Ci0gICAqIHNpbmdsZS1zdHJpbmcgY29tcGFyaXNvbiBvZiB0aGUgInVuaXZlcnNhbCIgbmFtZXMgb2YgdHdvIG5vZGVzLgotICAgKgotICAgKiBAcGFyYW0gYXR0ciBBdHRyIHRvIGJlIGV4YW1pbmVkCi0gICAqCi0gICAqIEByZXR1cm4gU3RyaW5nIGluIHRoZSBmb3JtICJuYW1lc3BhY2VVUkk6bG9jYWxuYW1lIiBpZiB0aGUgbm9kZQotICAgKiBiZWxvbmdzIHRvIGEgbmFtZXNwYWNlLCBvciBzaW1wbHkgImxvY2FsbmFtZSIgaWYgaXQgZG9lc24ndC4KLSAgICogQHNlZSAjZ2V0RXhwYW5kZWRFbGVtZW50TmFtZQotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRFeHBhbmRlZEF0dHJpYnV0ZU5hbWUoQXR0ciBhdHRyKQotICB7Ci0KLSAgICBTdHJpbmcgbmFtZXNwYWNlID0gZ2V0TmFtZXNwYWNlT2ZOb2RlKGF0dHIpOwotCi0gICAgcmV0dXJuIChudWxsICE9IG5hbWVzcGFjZSkKLSAgICAgICAgICAgPyBuYW1lc3BhY2UgKyAiOiIgKyBnZXRMb2NhbE5hbWVPZk5vZGUoYXR0cikKLSAgICAgICAgICAgOiBnZXRMb2NhbE5hbWVPZk5vZGUoYXR0cik7Ci0gIH0KLQotICAvLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAgLy8gU0VDVElPTjogRE9NIEhlbHBlciBGdW5jdGlvbnMKLSAgLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgdGhlIG5vZGUgaXMgaWdub3JhYmxlIHdoaXRlc3BhY2UuIE5vdGUgdGhhdCB0aGlzIGNhbgotICAgKiBiZSBkZXRlcm1pbmVkIG9ubHkgaW4gdGhlIGNvbnRleHQgb2YgYSBEVEQgb3Igb3RoZXIgU2NoZW1hLAotICAgKiBhbmQgdGhhdCBET00gTGV2ZWwgMiBoYXMgbm9zdGFuZGFyZGl6ZWQgRE9NIEFQSSB3aGljaCBjYW4KLSAgICogcmV0dXJuIHRoYXQgaW5mb3JtYXRpb24uCi0gICAqIEBkZXByZWNhdGVkCi0gICAqCi0gICAqIEBwYXJhbSBub2RlIE5vZGUgdG8gYmUgZXhhbWluZWQKLSAgICoKLSAgICogQHJldHVybiBDVVJSRU5UTFkgSEFSRENPREVEIFRPIEZBTFNFLCBidXQgc2hvdWxkIHJldHVybiB0cnVlIGlmCi0gICAqIGFuZCBvbmx5IGlmIHRoZSBub2RlIGlzIG9mIHR5cGUgVGV4dCwgY29udGFpbnMgb25seSB3aGl0ZXNwYWNlLAotICAgKiBhbmQgZG9lcyBub3QgYXBwZWFyIGFzIHBhcnQgb2YgdGhlICNQQ0RBVEEgY29udGVudCBvZiBhbiBlbGVtZW50LgotICAgKiAoTm90ZSB0aGF0IGRldGVybWluaW5nIHRoaXMgbGFzdCBtYXkgcmVxdWlyZSBhbGxvd2luZyBmb3IKLSAgICogRW50aXR5IFJlZmVyZW5jZXMuKQotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNJZ25vcmFibGVXaGl0ZXNwYWNlKFRleHQgbm9kZSkKLSAgewotCi0gICAgYm9vbGVhbiBpc0lnbm9yYWJsZSA9IGZhbHNlOyAgLy8gcmV0dXJuIHZhbHVlCi0KLSAgICAvLyBUT0RPOiBJIGNhbiBwcm9iYWJseSBkbyBzb21ldGhpbmcgdG8gZmlndXJlIG91dCBpZiB0aGlzCi0gICAgLy8gc3BhY2UgaXMgaWdub3JhYmxlIGZyb20ganVzdCB0aGUgaW5mb3JtYXRpb24gaW4KLSAgICAvLyB0aGUgRE9NIHRyZWUuCi0gICAgICAgIC8vIC0tIFlvdSBuZWVkIHRvIGJlIGFibGUgdG8gZGlzdGluZ3Vpc2ggd2hpdGVzcGFjZQotICAgICAgICAvLyB0aGF0IGlzICNQQ0RBVEEgZnJvbSB3aGl0ZXNwYWNlIHRoYXQgaXNuJ3QuICBUaGF0IHJlcXVpcmVzCi0gICAgICAgIC8vIERURCBzdXBwb3J0LCB3aGljaCB3b24ndCBiZSBzdGFuZGFyZGl6ZWQgdW50aWwgRE9NIExldmVsIDMuCi0gICAgcmV0dXJuIGlzSWdub3JhYmxlOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgZmlyc3QgdW5wYXJlbnRlZCBub2RlIGluIHRoZSBhbmNlc3RvciBjaGFpbi4KLSAgICogQGRlcHJlY2F0ZWQKLSAgICoKLSAgICogQHBhcmFtIG5vZGUgU3RhcnRpbmcgbm9kZSwgdG8gc3BlY2lmeSB3aGljaCBjaGFpbiB0byBjaGFzZQotICAgKgotICAgKiBAcmV0dXJuIHRoZSB0b3Btb3N0IGFuY2VzdG9yLgotICAgKi8KLSAgcHVibGljIE5vZGUgZ2V0Um9vdChOb2RlIG5vZGUpCi0gIHsKLQotICAgIE5vZGUgcm9vdCA9IG51bGw7Ci0KLSAgICB3aGlsZSAobm9kZSAhPSBudWxsKQotICAgIHsKLSAgICAgIHJvb3QgPSBub2RlOwotICAgICAgbm9kZSA9IGdldFBhcmVudE9mTm9kZShub2RlKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gcm9vdDsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIHJvb3Qgbm9kZSBvZiB0aGUgZG9jdW1lbnQgdHJlZSwgcmVnYXJkbGVzcyBvZgotICAgKiB3aGV0aGVyIG9yIG5vdCB0aGUgbm9kZSBwYXNzZWQgaW4gaXMgYSBkb2N1bWVudCBub2RlLgotICAgKiA8cD4KLSAgICogVE9ETzogVGhpcyBkb2Vzbid0IGhhbmRsZSBEb2N1bWVudEZyYWdtZW50cyBvciAib3JwaGFuZWQiIHN1YnRyZWVzCi0gICAqIC0tIGl0J3MgY3VycmVudGx5IHJldHVybmluZyBvd25lckRvY3VtZW50IGV2ZW4gd2hlbiB0aGUgdHJlZSBpcwotICAgKiBub3QgYWN0dWFsbHkgcGFydCBvZiB0aGUgbWFpbiBEb2N1bWVudCB0cmVlLiBXZSBzaG91bGQgZWl0aGVyCi0gICAqIHJld3JpdGUgdGhlIGRlc2NyaXB0aW9uIHRvIHNheSB0aGF0IGl0IGZpbmRzIHRoZSBEb2N1bWVudCBub2RlLAotICAgKiBvciBjaGFuZ2UgdGhlIGNvZGUgdG8gd2FsayB1cCB0aGUgYW5jZXN0b3IgY2hhaW4uCi0KLSAgICoKLSAgICogQHBhcmFtIG4gTm9kZSB0byBiZSBleGFtaW5lZAotICAgKgotICAgKiBAcmV0dXJuIHRoZSBEb2N1bWVudCBub2RlLiBOb3RlIHRoYXQgdGhpcyBpcyBub3QgdGhlIGNvcnJlY3QgYW5zd2VyCi0gICAqIGlmIG4gd2FzIChvciB3YXMgYSBjaGlsZCBvZikgYSBEb2N1bWVudEZyYWdtZW50IG9yIGFuIG9ycGhhbmVkIG5vZGUsCi0gICAqIGFzIGNhbiBhcmlzZSBpZiB0aGUgRE9NIGhhcyBiZWVuIGVkaXRlZCByYXRoZXIgdGhhbiBiZWluZyBnZW5lcmF0ZWQKLSAgICogYnkgYSBwYXJzZXIuCi0gICAqLwotICBwdWJsaWMgTm9kZSBnZXRSb290Tm9kZShOb2RlIG4pCi0gIHsKLSAgICBpbnQgbnQgPSBuLmdldE5vZGVUeXBlKCk7Ci0gICAgcmV0dXJuICggKE5vZGUuRE9DVU1FTlRfTk9ERSA9PSBudCkgfHwgKE5vZGUuRE9DVU1FTlRfRlJBR01FTlRfTk9ERSA9PSBudCkgKQotICAgICAgICAgICA/IG4gOiBuLmdldE93bmVyRG9jdW1lbnQoKTsKLSAgfQotCi0gIC8qKgotICAgKiBUZXN0IHdoZXRoZXIgdGhlIGdpdmVuIG5vZGUgaXMgYSBuYW1lc3BhY2UgZGVjbCBub2RlLiBJbiBET00gTGV2ZWwgMgotICAgKiB0aGlzIGNhbiBiZSBkb25lIGluIGEgbmFtZXNwYWNlLWF3YXJlIG1hbm5lciwgYnV0IGluIExldmVsIDEgRE9NcwotICAgKiBpdCBoYXMgdG8gYmUgZG9uZSBieSB0ZXN0aW5nIHRoZSBub2RlIG5hbWUuCi0gICAqCi0gICAqIEBwYXJhbSBuIE5vZGUgdG8gYmUgZXhhbWluZWQuCi0gICAqCi0gICAqIEByZXR1cm4gYm9vbGVhbiAtLSB0cnVlIGlmZiB0aGUgbm9kZSBpcyBhbiBBdHRyIHdob3NlIG5hbWUgaXMKLSAgICogInhtbG5zIiBvciBoYXMgdGhlICJ4bWxuczoiIHByZWZpeC4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzTmFtZXNwYWNlTm9kZShOb2RlIG4pCi0gIHsKLQotICAgIGlmIChOb2RlLkFUVFJJQlVURV9OT0RFID09IG4uZ2V0Tm9kZVR5cGUoKSkKLSAgICB7Ci0gICAgICBTdHJpbmcgYXR0ck5hbWUgPSBuLmdldE5vZGVOYW1lKCk7Ci0KLSAgICAgIHJldHVybiAoYXR0ck5hbWUuc3RhcnRzV2l0aCgieG1sbnM6IikgfHwgYXR0ck5hbWUuZXF1YWxzKCJ4bWxucyIpKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gZmFsc2U7Ci0gIH0KLQotICAvKioKLSAgICogT2J0YWluIHRoZSBYUGF0aC1tb2RlbCBwYXJlbnQgb2YgYSBET00gbm9kZSAtLSBvd25lckVsZW1lbnQgZm9yIEF0dHJzLAotICAgKiBwYXJlbnQgZm9yIG90aGVyIG5vZGVzLgotICAgKiA8cD4KLSAgICogQmFja2dyb3VuZDogVGhlIERPTSBiZWxpZXZlcyB0aGF0IHlvdSBtdXN0IGJlIHlvdXIgUGFyZW50J3MKLSAgICogQ2hpbGQsIGFuZCB0aHVzIEF0dHJzIGRvbid0IGhhdmUgcGFyZW50cy4gWFBhdGggc2FpZCB0aGF0IEF0dHJzCi0gICAqIGRvIGhhdmUgdGhlaXIgb3duaW5nIEVsZW1lbnQgYXMgdGhlaXIgcGFyZW50LiBUaGlzIGZ1bmN0aW9uCi0gICAqIGJyaWRnZXMgdGhlIGRpZmZlcmVuY2UsIGVpdGhlciBieSB1c2luZyB0aGUgRE9NIExldmVsIDIgb3duZXJFbGVtZW50Ci0gICAqIGZ1bmN0aW9uIG9yIGJ5IHVzaW5nIGEgInNpbGx5IGFuZCBleHBlbnNpdmUgZnVuY3Rpb24iIGluIExldmVsIDEKLSAgICogRE9Ncy4KLSAgICogPHA+Ci0gICAqIChUaGVyZSdzIHNvbWUgZGlzY3Vzc2lvbiBvZiBmdXR1cmUgRE9NcyBnZW5lcmFsaXppbmcgb3duZXJFbGVtZW50Ci0gICAqIGludG8gb3duZXJOb2RlIGFuZCBtYWtpbmcgaXQgd29yayBvbiBhbGwgdHlwZXMgb2Ygbm9kZXMuIFRoaXMKLSAgICogc3RpbGwgd291bGRuJ3QgaGVscCB0aGUgdXNlcnMgb2YgTGV2ZWwgMSBvciBMZXZlbCAyIERPTXMpCi0gICAqIDxwPgotICAgKgotICAgKiBAcGFyYW0gbm9kZSBOb2RlIHdob3NlIFhQYXRoIHBhcmVudCB3ZSB3YW50IHRvIG9idGFpbgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBwYXJlbnQgb2YgdGhlIG5vZGUsIG9yIHRoZSBvd25lckVsZW1lbnQgaWYgaXQncyBhbgotICAgKiBBdHRyIG5vZGUsIG9yIG51bGwgaWYgdGhlIG5vZGUgaXMgYW4gb3JwaGFuLgotICAgKgotICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gaWYgdGhlIERvY3VtZW50IGhhcyBubyByb290IGVsZW1lbnQuCi0gICAqIFRoaXMgY2FuJ3QgYXJpc2UgaWYgdGhlIERvY3VtZW50IHdhcyBjcmVhdGVkCi0gICAqIHZpYSB0aGUgRE9NIExldmVsIDIgZmFjdG9yeSBtZXRob2RzLCBidXQgaXMgcG9zc2libGUgaWYgb3RoZXIKLSAgICogbWVjaGFuaXNtcyB3ZXJlIHVzZWQgdG8gb2J0YWluIGl0Ci0gICAqLwotICBwdWJsaWMgc3RhdGljIE5vZGUgZ2V0UGFyZW50T2ZOb2RlKE5vZGUgbm9kZSkgdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24KLSAgewotICAgIE5vZGUgcGFyZW50OwotICAgIHNob3J0IG5vZGVUeXBlID0gbm9kZS5nZXROb2RlVHlwZSgpOwotCi0gICAgaWYgKE5vZGUuQVRUUklCVVRFX05PREUgPT0gbm9kZVR5cGUpCi0gICAgewotICAgICAgRG9jdW1lbnQgZG9jID0gbm9kZS5nZXRPd25lckRvY3VtZW50KCk7Ci0gICAgICAgICAgLyoKLSAgICAgIFRCRDoKLSAgICAgIGlmKG51bGwgPT0gZG9jKQotICAgICAgewotICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoWFBBVEhFcnJvclJlc291cmNlcy5FUl9DSElMRF9IQVNfTk9fT1dORVJfRE9DVU1FTlQsIG51bGwpKTsvLyJBdHRyaWJ1dGUgY2hpbGQgZG9lcyBub3QgaGF2ZSBhbiBvd25lciBkb2N1bWVudCEiKTsKLSAgICAgIH0KLSAgICAgICovCi0KLSAgICAgICAgICAvLyBHaXZlbiBob3cgZXhwZW5zaXZlIHRoZSB0cmVlIHdhbGsgbWF5IGJlLCB3ZSBzaG91bGQgZmlyc3QgYXNrCi0gICAgICAgICAgLy8gd2hldGhlciB0aGlzIERPTSBjYW4gYW5zd2VyIHRoZSBxdWVzdGlvbiBmb3IgdXMuIFRoZSBhZGRpdGlvbmFsCi0gICAgICAgICAgLy8gdGVzdCBkb2VzIHNsb3cgZG93biBMZXZlbCAxIERPTXMgc2xpZ2h0bHkuIERPTUhlbHBlcjIsIHdoaWNoCi0gICAgICAgICAgLy8gaXMgY3VycmVudGx5IHNwZWNpYWxpemVkIGZvciBYZXJjZXMsIGFzc3VtZXMgaXQgY2FuIHVzZSB0aGUKLSAgICAgICAgICAvLyBMZXZlbCAyIHNvbHV0aW9uLiBXZSBtaWdodCB3YW50IHRvIGhhdmUgYW4gaW50ZXJtZWRpYXRlIHN0YWdlLAotICAgICAgICAgIC8vIHdoaWNoIHdvdWxkIGFzc3VtZSBET00gTGV2ZWwgMiBidXQgbm90IGFzc3VtZSBYZXJjZXMuCi0gICAgICAgICAgLy8KLSAgICAgICAgICAvLyAoU2hvdWxkbid0IGhhdmUgdG8gY2hlY2sgd2hldGhlciBpbXBsIGlzIG51bGwgaW4gYSBjb21wbGlhbnQgRE9NLAotICAgICAgICAgIC8vIGJ1dCBsZXQncyBiZSBwYXJhbm9pZCBmb3IgYSBtb21lbnQuLi4pCi0gICAgICAgICAgRE9NSW1wbGVtZW50YXRpb24gaW1wbD1kb2MuZ2V0SW1wbGVtZW50YXRpb24oKTsKLSAgICAgICAgICBpZihpbXBsIT1udWxsICYmIGltcGwuaGFzRmVhdHVyZSgiQ29yZSIsIjIuMCIpKQotICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgIHBhcmVudD0oKEF0dHIpbm9kZSkuZ2V0T3duZXJFbGVtZW50KCk7Ci0gICAgICAgICAgICAgICAgICByZXR1cm4gcGFyZW50OwotICAgICAgICAgIH0KLQotICAgICAgICAgIC8vIERPTSBMZXZlbCAxIHNvbHV0aW9uLCBhcyBmYWxsYmFjay4gSHVnZWx5IGV4cGVuc2l2ZS4KLQotICAgICAgRWxlbWVudCByb290RWxlbSA9IGRvYy5nZXREb2N1bWVudEVsZW1lbnQoKTsKLQotICAgICAgaWYgKG51bGwgPT0gcm9vdEVsZW0pCi0gICAgICB7Ci0gICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAotICAgICAgICAgIFhNTE1lc3NhZ2VzLmNyZWF0ZVhNTE1lc3NhZ2UoCi0gICAgICAgICAgICBYTUxFcnJvclJlc291cmNlcy5FUl9DSElMRF9IQVNfTk9fT1dORVJfRE9DVU1FTlRfRUxFTUVOVCwKLSAgICAgICAgICAgIG51bGwpKTsgIC8vIkF0dHJpYnV0ZSBjaGlsZCBkb2VzIG5vdCBoYXZlIGFuIG93bmVyIGRvY3VtZW50IGVsZW1lbnQhIik7Ci0gICAgICB9Ci0KLSAgICAgIHBhcmVudCA9IGxvY2F0ZUF0dHJQYXJlbnQocm9vdEVsZW0sIG5vZGUpOwotCi0gICAgICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgcGFyZW50ID0gbm9kZS5nZXRQYXJlbnROb2RlKCk7Ci0KLSAgICAgIC8vIGlmKChOb2RlLkRPQ1VNRU5UX05PREUgIT0gbm9kZVR5cGUpICYmIChudWxsID09IHBhcmVudCkpCi0gICAgICAvLyB7Ci0gICAgICAvLyAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJDaGlsZCBkb2VzIG5vdCBoYXZlIHBhcmVudCEiKTsKLSAgICAgIC8vIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gcGFyZW50OwotICB9Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGFuIElELCByZXR1cm4gdGhlIGVsZW1lbnQuIFRoaXMgY2FuIHdvcmsgb25seSBpZiB0aGUgZG9jdW1lbnQKLSAgICogaXMgaW50ZXJwcmV0ZWQgaW4gdGhlIGNvbnRleHQgb2YgYSBEVEQgb3IgU2NoZW1hLCBzaW5jZSBvdGhlcndpc2UKLSAgICogd2UgZG9uJ3Qga25vdyB3aGljaCBhdHRyaWJ1dGVzIGFyZSBvciBhcmVuJ3QgSURzLgotICAgKiA8cD4KLSAgICogTm90ZSB0aGF0IERPTSBMZXZlbCAxIGhhZCBubyBhYmlsaXR5IHRvIHJldHJpZXZlIHRoaXMgaW5mb3JtYXRpb24uCi0gICAqIERPTSBMZXZlbCAyIGludHJvZHVjZWQgaXQgYnV0IGRvZXMgbm90IHByb21pc2UgdGhhdCBpdCB3aWxsIGJlCi0gICAqIHN1cHBvcnRlZCBpbiBhbGwgRE9NczsgdGhvc2Ugd2hpY2ggY2FuJ3Qgc3VwcG9ydCBpdCB3aWxsIGFsd2F5cwotICAgKiByZXR1cm4gbnVsbC4KLSAgICogPHA+Ci0gICAqIFRPRE86IGdldEVsZW1lbnRCeUlEIGlzIGN1cnJlbnRseSB1bmltcGxlbWVudGVkLiBTdXBwb3J0IERPTSBMZXZlbCAyPwotICAgKgotICAgKiBAcGFyYW0gaWQgVGhlIHVuaXF1ZSBpZGVudGlmaWVyIHRvIGJlIHNlYXJjaGVkIGZvci4KLSAgICogQHBhcmFtIGRvYyBUaGUgZG9jdW1lbnQgdG8gc2VhcmNoIHdpdGhpbi4KLSAgICogQHJldHVybiBDVVJSRU5UTFkgSEFSRENPREVEIFRPIE5VTEwsIGJ1dCBpdCBzaG91bGQgYmU6Ci0gICAqIFRoZSBub2RlIHdoaWNoIGhhcyB0aGlzIHVuaXF1ZSBpZGVudGlmaWVyLCBvciBudWxsIGlmIHRoZXJlCi0gICAqIGlzIG5vIHN1Y2ggbm9kZSBvciB0aGlzIERPTSBjYW4ndCByZWxpYWJseSByZWNvZ25pemUgaXQuCi0gICAqLwotICBwdWJsaWMgRWxlbWVudCBnZXRFbGVtZW50QnlJRChTdHJpbmcgaWQsIERvY3VtZW50IGRvYykKLSAgewotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoZSBnZXRVbnBhcnNlZEVudGl0eVVSSSBmdW5jdGlvbiByZXR1cm5zIHRoZSBVUkkgb2YgdGhlIHVucGFyc2VkCi0gICAqIGVudGl0eSB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZSBpbiB0aGUgc2FtZSBkb2N1bWVudCBhcyB0aGUgY29udGV4dAotICAgKiBub2RlIChzZWUgWzMuMyBVbnBhcnNlZCBFbnRpdGllc10pLiBJdCByZXR1cm5zIHRoZSBlbXB0eSBzdHJpbmcgaWYKLSAgICogdGhlcmUgaXMgbm8gc3VjaCBlbnRpdHkuCi0gICAqIDxwPgotICAgKiBYTUwgcHJvY2Vzc29ycyBtYXkgY2hvb3NlIHRvIHVzZSB0aGUgU3lzdGVtIElkZW50aWZpZXIgKGlmIG9uZQotICAgKiBpcyBwcm92aWRlZCkgdG8gcmVzb2x2ZSB0aGUgZW50aXR5LCByYXRoZXIgdGhhbiB0aGUgVVJJIGluIHRoZQotICAgKiBQdWJsaWMgSWRlbnRpZmllci4gVGhlIGRldGFpbHMgYXJlIGRlcGVuZGVudCBvbiB0aGUgcHJvY2Vzc29yLCBhbmQKLSAgICogd2Ugd291bGQgaGF2ZSB0byBzdXBwb3J0IHNvbWUgZm9ybSBvZiBwbHVnLWluIHJlc29sdmVyIHRvIGhhbmRsZQotICAgKiB0aGlzIHByb3Blcmx5LiBDdXJyZW50bHksIHdlIHNpbXBseSByZXR1cm4gdGhlIFN5c3RlbSBJZGVudGlmaWVyIGlmCi0gICAqIHByZXNlbnQsIGFuZCBob3BlIHRoYXQgaXQgYSB1c2FibGUgVVJJIG9yIHRoYXQgb3VyIGNhbGxlciBjYW4KLSAgICogbWFwIGl0IHRvIG9uZS4KLSAgICogVE9ETzogUmVzb2x2ZSBQdWJsaWMgSWRlbnRpZmllcnMuLi4gb3IgY29uc2lkZXIgY2hhbmdpbmcgZnVuY3Rpb24gbmFtZS4KLSAgICogPHA+Ci0gICAqIElmIHdlIGZpbmQgYSByZWxhdGl2ZSBVUkkKLSAgICogcmVmZXJlbmNlLCBYTUwgZXhwZWN0cyBpdCB0byBiZSByZXNvbHZlZCBpbiB0ZXJtcyBvZiB0aGUgYmFzZSBVUkkKLSAgICogb2YgdGhlIGRvY3VtZW50LiBUaGUgRE9NIGRvZXNuJ3QgZG8gdGhhdCBmb3IgdXMsIGFuZCBpdCBpc24ndAotICAgKiBlbnRpcmVseSBjbGVhciB3aGV0aGVyIHRoYXQgc2hvdWxkIGJlIGRvbmUgaGVyZTsgY3VycmVudGx5IHRoYXQncwotICAgKiBwdXNoZWQgdXAgdG8gYSBoaWdoZXIgbGV2ZWxvZiBvdXIgYXBwbGljYXRpb24uIChOb3RlIHRoYXQgRE9NIExldmVsCi0gICAqIDEgZGlkbid0IHN0b3JlIHRoZSBkb2N1bWVudCdzIGJhc2UgVVJJLikKLSAgICogVE9ETzogQ29uc2lkZXIgcmVzb2x2aW5nIFJlbGF0aXZlIFVSSXMuCi0gICAqIDxwPgotICAgKiAoVGhlIERPTSdzIHN0YXRlbWVudCB0aGF0ICJBbiBYTUwgcHJvY2Vzc29yIG1heSBjaG9vc2UgdG8KLSAgICogY29tcGxldGVseSBleHBhbmQgZW50aXRpZXMgYmVmb3JlIHRoZSBzdHJ1Y3R1cmUgbW9kZWwgaXMgcGFzc2VkCi0gICAqIHRvIHRoZSBET00iIHJlZmVycyBvbmx5IHRvIHBhcnNlZCBlbnRpdGllcywgbm90IHVucGFyc2VkLCBhbmQgaGVuY2UKLSAgICogZG9lc24ndCBhZmZlY3QgdGhpcyBmdW5jdGlvbi4pCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lIEEgc3RyaW5nIGNvbnRhaW5pbmcgdGhlIEVudGl0eSBOYW1lIG9mIHRoZSB1bnBhcnNlZAotICAgKiBlbnRpdHkuCi0gICAqIEBwYXJhbSBkb2MgRG9jdW1lbnQgbm9kZSBmb3IgdGhlIGRvY3VtZW50IHRvIGJlIHNlYXJjaGVkLgotICAgKgotICAgKiBAcmV0dXJuIFN0cmluZyBjb250YWluaW5nIHRoZSBVUkkgb2YgdGhlIFVucGFyc2VkIEVudGl0eSwgb3IgYW4KLSAgICogZW1wdHkgc3RyaW5nIGlmIG5vIHN1Y2ggZW50aXR5IGV4aXN0cy4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0VW5wYXJzZWRFbnRpdHlVUkkoU3RyaW5nIG5hbWUsIERvY3VtZW50IGRvYykKLSAgewotCi0gICAgU3RyaW5nIHVybCA9ICIiOwotICAgIERvY3VtZW50VHlwZSBkb2N0eXBlID0gZG9jLmdldERvY3R5cGUoKTsKLQotICAgIGlmIChudWxsICE9IGRvY3R5cGUpCi0gICAgewotICAgICAgTmFtZWROb2RlTWFwIGVudGl0aWVzID0gZG9jdHlwZS5nZXRFbnRpdGllcygpOwotICAgICAgaWYobnVsbCA9PSBlbnRpdGllcykKLSAgICAgICAgcmV0dXJuIHVybDsKLSAgICAgIEVudGl0eSBlbnRpdHkgPSAoRW50aXR5KSBlbnRpdGllcy5nZXROYW1lZEl0ZW0obmFtZSk7Ci0gICAgICBpZihudWxsID09IGVudGl0eSkKLSAgICAgICAgcmV0dXJuIHVybDsKLQotICAgICAgU3RyaW5nIG5vdGF0aW9uTmFtZSA9IGVudGl0eS5nZXROb3RhdGlvbk5hbWUoKTsKLQotICAgICAgaWYgKG51bGwgIT0gbm90YXRpb25OYW1lKSAgLy8gdGhlbiBpdCdzIHVucGFyc2VkCi0gICAgICB7Ci0gICAgICAgIC8vIFRoZSBkcmFmdCBzYXlzOiAiVGhlIFhTTFQgcHJvY2Vzc29yIG1heSB1c2UgdGhlIHB1YmxpYwotICAgICAgICAvLyBpZGVudGlmaWVyIHRvIGdlbmVyYXRlIGEgVVJJIGZvciB0aGUgZW50aXR5IGluc3RlYWQgb2YgdGhlIFVSSQotICAgICAgICAvLyBzcGVjaWZpZWQgaW4gdGhlIHN5c3RlbSBpZGVudGlmaWVyLiBJZiB0aGUgWFNMVCBwcm9jZXNzb3IgZG9lcwotICAgICAgICAvLyBub3QgdXNlIHRoZSBwdWJsaWMgaWRlbnRpZmllciB0byBnZW5lcmF0ZSB0aGUgVVJJLCBpdCBtdXN0IHVzZQotICAgICAgICAvLyB0aGUgc3lzdGVtIGlkZW50aWZpZXI7IGlmIHRoZSBzeXN0ZW0gaWRlbnRpZmllciBpcyBhIHJlbGF0aXZlCi0gICAgICAgIC8vIFVSSSwgaXQgbXVzdCBiZSByZXNvbHZlZCBpbnRvIGFuIGFic29sdXRlIFVSSSB1c2luZyB0aGUgVVJJIG9mCi0gICAgICAgIC8vIHRoZSByZXNvdXJjZSBjb250YWluaW5nIHRoZSBlbnRpdHkgZGVjbGFyYXRpb24gYXMgdGhlIGJhc2UKLSAgICAgICAgLy8gVVJJIFtSRkMyMzk2XS4iCi0gICAgICAgIC8vIFNvIEknbSBmYWxsaW5nIGEgYml0IHNob3J0IGhlcmUuCi0gICAgICAgIHVybCA9IGVudGl0eS5nZXRTeXN0ZW1JZCgpOwotCi0gICAgICAgIGlmIChudWxsID09IHVybCkKLSAgICAgICAgewotICAgICAgICAgIHVybCA9IGVudGl0eS5nZXRQdWJsaWNJZCgpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotICAgICAgICAgIC8vIFRoaXMgc2hvdWxkIGJlIHJlc29sdmVkIHRvIGFuIGFic29sdXRlIFVSTCwgYnV0IHRoYXQncyBoYXJkCi0gICAgICAgICAgLy8gdG8gZG8gZnJvbSBoZXJlLgotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotCi0gICAgcmV0dXJuIHVybDsKLSAgfQotCi0gIC8qKgotICAgKiBTdXBwb3J0IGZvciBnZXRQYXJlbnRPZk5vZGU7IHdhbGtzIGEgRE9NIHRyZWUgdW50aWwgaXQgZmluZHMKLSAgICogdGhlIEVsZW1lbnQgd2hpY2ggb3ducyB0aGUgQXR0ci4gVGhpcyBpcyBodWdlbHkgZXhwZW5zaXZlLCBhbmQKLSAgICogaWYgYXQgYWxsIHBvc3NpYmxlIHlvdSBzaG91bGQgdXNlIHRoZSBET00gTGV2ZWwgMiBBdHRyLm93bmVyRWxlbWVudCgpCi0gICAqIG1ldGhvZCBpbnN0ZWFkLgotICAgKiAgPHA+Ci0gICAqIFRoZSBET00gTGV2ZWwgMSBkZXZlbG9wZXJzIGV4cGVjdGVkIHRoYXQgZm9sa3Mgd291bGQga2VlcCB0cmFjawotICAgKiBvZiB0aGUgbGFzdCBFbGVtZW50IHRoZXknZCBzZWVuIGFuZCBjb3VsZCByZWNvdmVyIHRoZSBpbmZvIGZyb20KLSAgICogdGhhdCBzb3VyY2UuIE9idmlvdXNseSB0aGF0IGRvZXNuJ3Qgd29yayB2ZXJ5IHdlbGwgaWYgdGhlIG9ubHkKLSAgICogaW5mb3JtYXRpb24geW91J3ZlIGJlZW4gcHJlc2VudGVkIHdpdGggaXMgdGhlIEF0dHIuIFRoZSBET00gTGV2ZWwgMgotICAgKiBnZXRPd25lckVsZW1lbnQoKSBtZXRob2QgZml4ZXMgdGhhdCwgYnV0IG9ubHkgZm9yIExldmVsIDIgYW5kCi0gICAqIGxhdGVyIERPTXMuCi0gICAqCi0gICAqIEBwYXJhbSBlbGVtIEVsZW1lbnQgd2hvc2Ugc3VidHJlZSBpcyB0byBiZSBzZWFyY2hlZCBmb3IgdGhpcyBBdHRyCi0gICAqIEBwYXJhbSBhdHRyIEF0dHIgd2hvc2Ugb3duZXIgaXMgdG8gYmUgbG9jYXRlZC4KLSAgICoKLSAgICogQHJldHVybiB0aGUgZmlyc3QgRWxlbWVudCB3aG9zZSBhdHRyaWJ1dGUgbGlzdCBpbmNsdWRlcyB0aGUgcHJvdmlkZWQKLSAgICogYXR0ci4gSW4gbW9kZXJuIERPTXMsIHRoaXMgd2lsbCBhbHNvIGJlIHRoZSBvbmx5IHN1Y2ggRWxlbWVudC4gKEVhcmx5Ci0gICAqIERPTXMgaGFkIHNvbWUgaG9wZSB0aGF0IEF0dHJzIG1pZ2h0IGJlIHNoYXJhYmxlLCBidXQgdGhpcyBpZGVhIGhhcwotICAgKiBiZWVuIGFiYW5kb25lZC4pCi0gICAqLwotICBwcml2YXRlIHN0YXRpYyBOb2RlIGxvY2F0ZUF0dHJQYXJlbnQoRWxlbWVudCBlbGVtLCBOb2RlIGF0dHIpCi0gIHsKLQotICAgIE5vZGUgcGFyZW50ID0gbnVsbDsKLQotICAgICAgICAvLyBUaGlzIHNob3VsZCBvbmx5IGJlIGNhbGxlZCBmb3IgTGV2ZWwgMSBET01zLCBzbyB3ZSBkb24ndCBoYXZlIHRvCi0gICAgICAgIC8vIHdvcnJ5IGFib3V0IG5hbWVzcGFjZSBpc3N1ZXMuIEluIGxhdGVyIGxldmVscywgaXQncyBwb3NzaWJsZQotICAgICAgICAvLyBmb3IgYSBET00gdG8gaGF2ZSB0d28gQXR0cnMgd2l0aCB0aGUgc2FtZSBOb2RlTmFtZSBidXQKLSAgICAgICAgLy8gZGlmZmVyZW50IG5hbWVzcGFjZXMsIGFuZCB3ZSdkIG5lZWQgdG8gZ2V0IGdldEF0dHJpYnV0ZU5vZGVOUy4uLgotICAgICAgICAvLyBidXQgbGF0ZXIgbGV2ZWxzIGFsc28gaGF2ZSBBdHRyLmdldE93bmVyRWxlbWVudC4KLSAgICAgICAgQXR0ciBjaGVjaz1lbGVtLmdldEF0dHJpYnV0ZU5vZGUoYXR0ci5nZXROb2RlTmFtZSgpKTsKLSAgICAgICAgaWYoY2hlY2s9PWF0dHIpCi0gICAgICAgICAgICAgICAgcGFyZW50ID0gZWxlbTsKLQotICAgIGlmIChudWxsID09IHBhcmVudCkKLSAgICB7Ci0gICAgICBmb3IgKE5vZGUgbm9kZSA9IGVsZW0uZ2V0Rmlyc3RDaGlsZCgpOyBudWxsICE9IG5vZGU7Ci0gICAgICAgICAgICAgIG5vZGUgPSBub2RlLmdldE5leHRTaWJsaW5nKCkpCi0gICAgICB7Ci0gICAgICAgIGlmIChOb2RlLkVMRU1FTlRfTk9ERSA9PSBub2RlLmdldE5vZGVUeXBlKCkpCi0gICAgICAgIHsKLSAgICAgICAgICBwYXJlbnQgPSBsb2NhdGVBdHRyUGFyZW50KChFbGVtZW50KSBub2RlLCBhdHRyKTsKLQotICAgICAgICAgIGlmIChudWxsICE9IHBhcmVudCkKLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotCi0gICAgcmV0dXJuIHBhcmVudDsKLSAgfQotCi0gIC8qKgotICAgKiBUaGUgZmFjdG9yeSBvYmplY3QgdXNlZCBmb3IgY3JlYXRpbmcgbm9kZXMKLSAgICogaW4gdGhlIHJlc3VsdCB0cmVlLgotICAgKi8KLSAgcHJvdGVjdGVkIERvY3VtZW50IG1fRE9NRmFjdG9yeSA9IG51bGw7Ci0KLSAgLyoqCi0gICAqIFN0b3JlIHRoZSBmYWN0b3J5IG9iamVjdCByZXF1aXJlZCB0byBjcmVhdGUgRE9NIG5vZGVzCi0gICAqIGluIHRoZSByZXN1bHQgdHJlZS4gSW4gZmFjdCwgdGhhdCdzIGp1c3QgdGhlIHJlc3VsdCB0cmVlJ3MKLSAgICogRG9jdW1lbnQgbm9kZS4uLgotICAgKgotICAgKiBAcGFyYW0gZG9tRmFjdG9yeSBUaGUgRE9NIERvY3VtZW50IE5vZGUgd2l0aGluIHdob3NlIGNvbnRleHQKLSAgICogdGhlIHJlc3VsdCB0cmVlIHdpbGwgYmUgYnVpbHQuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRET01GYWN0b3J5KERvY3VtZW50IGRvbUZhY3RvcnkpCi0gIHsKLSAgICB0aGlzLm1fRE9NRmFjdG9yeSA9IGRvbUZhY3Rvcnk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0cmlldmUgdGhlIGZhY3Rvcnkgb2JqZWN0IHJlcXVpcmVkIHRvIGNyZWF0ZSBET00gbm9kZXMKLSAgICogaW4gdGhlIHJlc3VsdCB0cmVlLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSByZXN1bHQgdHJlZSdzIERPTSBEb2N1bWVudCBOb2RlLgotICAgKi8KLSAgcHVibGljIERvY3VtZW50IGdldERPTUZhY3RvcnkoKQotICB7Ci0KLSAgICBpZiAobnVsbCA9PSB0aGlzLm1fRE9NRmFjdG9yeSkKLSAgICB7Ci0gICAgICB0aGlzLm1fRE9NRmFjdG9yeSA9IGNyZWF0ZURvY3VtZW50KCk7Ci0gICAgfQotCi0gICAgcmV0dXJuIHRoaXMubV9ET01GYWN0b3J5OwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgdGV4dHVhbCBjb250ZW50cyBvZiB0aGUgbm9kZS4gU2VlCi0gICAqIGdldE5vZGVEYXRhKE5vZGUsRmFzdFN0cmluZ0J1ZmZlcikgZm9yIGRpc2N1c3Npb24gb2YgaG93Ci0gICAqIHdoaXRlc3BhY2Ugbm9kZXMgYXJlIGhhbmRsZWQuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlIERPTSBOb2RlIHRvIGJlIGV4YW1pbmVkCi0gICAqIEByZXR1cm4gU3RyaW5nIGNvbnRhaW5pbmcgYSBjb25jYXRlbmF0aW9uIG9mIGFsbCB0aGUKLSAgICogdGV4dHVhbCBjb250ZW50IHdpdGhpbiB0aGF0IG5vZGUuCi0gICAqIEBzZWUgI2dldE5vZGVEYXRhKE5vZGUsRmFzdFN0cmluZ0J1ZmZlcikKLSAgICoKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldE5vZGVEYXRhKE5vZGUgbm9kZSkKLSAgewotCi0gICAgRmFzdFN0cmluZ0J1ZmZlciBidWYgPSBTdHJpbmdCdWZmZXJQb29sLmdldCgpOwotICAgIFN0cmluZyBzOwotCi0gICAgdHJ5Ci0gICAgewotICAgICAgZ2V0Tm9kZURhdGEobm9kZSwgYnVmKTsKLQotICAgICAgcyA9IChidWYubGVuZ3RoKCkgPiAwKSA/IGJ1Zi50b1N0cmluZygpIDogIiI7Ci0gICAgfQotICAgIGZpbmFsbHkKLSAgICB7Ci0gICAgICBTdHJpbmdCdWZmZXJQb29sLmZyZWUoYnVmKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gczsKLSAgfQotCi0gIC8qKgotICAgKiBSZXRyaWV2ZSB0aGUgdGV4dCBjb250ZW50IG9mIGEgRE9NIHN1YnRyZWUsIGFwcGVuZGluZyBpdCBpbnRvIGEKLSAgICogdXNlci1zdXBwbGllZCBGYXN0U3RyaW5nQnVmZmVyIG9iamVjdC4gTm90ZSB0aGF0IGF0dHJpYnV0ZXMgYXJlCi0gICAqIG5vdCBjb25zaWRlcmVkIHBhcnQgb2YgdGhlIGNvbnRlbnQgb2YgYW4gZWxlbWVudC4KLSAgICogPHA+Ci0gICAqIFRoZXJlIGFyZSBvcGVuIHF1ZXN0aW9ucyByZWdhcmRpbmcgd2hpdGVzcGFjZSBzdHJpcHBpbmcuCi0gICAqIEN1cnJlbnRseSB3ZSBtYWtlIG5vIHNwZWNpYWwgZWZmb3J0IGluIHRoYXQgcmVnYXJkLCBzaW5jZSB0aGUgc3RhbmRhcmQKLSAgICogRE9NIGRvZXNuJ3QgeWV0IHByb3ZpZGUgRFRELWJhc2VkIGluZm9ybWF0aW9uIHRvIGRpc3Rpbmd1aXNoCi0gICAqIHdoaXRlc3BhY2UtaW4tZWxlbWVudC1jb250ZXh0IGZyb20gZ2VudWluZSAjUENEQVRBLiBOb3RlIHRoYXQgd2UKLSAgICogc2hvdWxkIHByb2JhYmx5IGFsc28gY29uc2lkZXIgeG1sOnNwYWNlIGlmL3doZW4gd2UgYWRkcmVzcyB0aGlzLgotICAgKiBET00gTGV2ZWwgMyBtYXkgc29sdmUgdGhlIHByb2JsZW0gZm9yIHVzLgotICAgKgotICAgKiBAcGFyYW0gbm9kZSBOb2RlIHdob3NlIHN1YnRyZWUgaXMgdG8gYmUgd2Fsa2VkLCBnYXRoZXJpbmcgdGhlCi0gICAqIGNvbnRlbnRzIG9mIGFsbCBUZXh0IG9yIENEQVRBU2VjdGlvbiBub2Rlcy4KLSAgICogQHBhcmFtIGJ1ZiBGYXN0U3RyaW5nQnVmZmVyIGludG8gd2hpY2ggdGhlIGNvbnRlbnRzIG9mIHRoZSB0ZXh0Ci0gICAqIG5vZGVzIGFyZSB0byBiZSBjb25jYXRlbmF0ZWQuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIHZvaWQgZ2V0Tm9kZURhdGEoTm9kZSBub2RlLCBGYXN0U3RyaW5nQnVmZmVyIGJ1ZikKLSAgewotCi0gICAgc3dpdGNoIChub2RlLmdldE5vZGVUeXBlKCkpCi0gICAgewotICAgIGNhc2UgTm9kZS5ET0NVTUVOVF9GUkFHTUVOVF9OT0RFIDoKLSAgICBjYXNlIE5vZGUuRE9DVU1FTlRfTk9ERSA6Ci0gICAgY2FzZSBOb2RlLkVMRU1FTlRfTk9ERSA6Ci0gICAgewotICAgICAgZm9yIChOb2RlIGNoaWxkID0gbm9kZS5nZXRGaXJzdENoaWxkKCk7IG51bGwgIT0gY2hpbGQ7Ci0gICAgICAgICAgICAgIGNoaWxkID0gY2hpbGQuZ2V0TmV4dFNpYmxpbmcoKSkKLSAgICAgIHsKLSAgICAgICAgZ2V0Tm9kZURhdGEoY2hpbGQsIGJ1Zik7Ci0gICAgICB9Ci0gICAgfQotICAgIGJyZWFrOwotICAgIGNhc2UgTm9kZS5URVhUX05PREUgOgotICAgIGNhc2UgTm9kZS5DREFUQV9TRUNUSU9OX05PREUgOgotICAgICAgYnVmLmFwcGVuZChub2RlLmdldE5vZGVWYWx1ZSgpKTsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgTm9kZS5BVFRSSUJVVEVfTk9ERSA6Ci0gICAgICBidWYuYXBwZW5kKG5vZGUuZ2V0Tm9kZVZhbHVlKCkpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBOb2RlLlBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERSA6Ci0gICAgICAvLyB3YXJuaW5nKFhQQVRIRXJyb3JSZXNvdXJjZXMuV0dfUEFSU0lOR19BTkRfUFJFUEFSSU5HKTsKLSAgICAgIGJyZWFrOwotICAgIGRlZmF1bHQgOgotICAgICAgLy8gaWdub3JlCi0gICAgICBicmVhazsKLSAgICB9Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL0RPTU9yZGVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9ET01PcmRlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjYTc0Zjc3Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL0RPTU9yZGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0MyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBET01PcmRlci5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE1IDA4OjE1OjQxIHN1cmVzaF9lbWFpbGlkIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlsczsKLQotLyoqCi0gKiBAZGVwcmVjYXRlZCBTaW5jZSB0aGUgaW50cm9kdWN0aW9uIG9mIHRoZSBEVE0sIHRoaXMgY2xhc3Mgd2lsbCBiZSByZW1vdmVkLgotICogTm9kZXMgdGhhdCBpbXBsZW1lbnQgdGhpcyBpbmRleCBjYW4gcmV0dXJuIGEgZG9jdW1lbnQgb3JkZXIgaW5kZXguCi0gKiBFdmVudHVhbGx5LCB0aGlzIHdpbGwgYmUgcmVwbGFjZWQgYnkgRE9NIDMgbWV0aG9kcy4KLSAqIChjb21wYXJlRG9jdW1lbnRPcmRlciBhbmQvb3IgY29tcGFyZVRyZWVQb3NpdGlvbi4pCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgRE9NT3JkZXIKLXsKLQotICAvKioKLSAgICogR2V0IHRoZSBVSUQgKGRvY3VtZW50IG9yZGVyIGluZGV4KS4KLSAgICoKLSAgICogQHJldHVybiBpbnRlZ2VyIHdob3NlIHJlbGF0aXZlIHZhbHVlIGNvcnJlc3BvbmRzIHRvIGRvY3VtZW50IG9yZGVyCi0gICAqIC0tIHRoYXQgaXMsIGlmIG5vZGUxLmdldFVpZCgpPG5vZGUyLmdldFVpZCgpLCBub2RlMSBjb21lcyBiZWZvcmUKLSAgICogbm9kZTIsIGFuZCBpZiB0aGV5J3JlIGVxdWFsIG5vZGUxIGFuZCBub2RlMiBhcmUgdGhlIHNhbWUgbm9kZS4gTm8KLSAgICogcHJvbWlzZXMgYXJlIG1hZGUgYmV5b25kIHRoYXQuCi0gICAqLwotICBwdWJsaWMgaW50IGdldFVpZCgpOwotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvRGVmYXVsdEVycm9ySGFuZGxlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvRGVmYXVsdEVycm9ySGFuZGxlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjMDhmYmU4Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL0RlZmF1bHRFcnJvckhhbmRsZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDM0NCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBEZWZhdWx0RXJyb3JIYW5kbGVyLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTUgMDg6MTU6NDMgc3VyZXNoX2VtYWlsaWQgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzOwotCi1pbXBvcnQgamF2YS5pby5QcmludFN0cmVhbTsKLWltcG9ydCBqYXZhLmlvLlByaW50V3JpdGVyOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5FcnJvckxpc3RlbmVyOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uU291cmNlTG9jYXRvcjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXMuWE1MRXJyb3JSZXNvdXJjZXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXMuWE1MTWVzc2FnZXM7Ci0KLWltcG9ydCBvcmcueG1sLnNheC5FcnJvckhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWFBhcnNlRXhjZXB0aW9uOwotCi0KLS8qKgotICogSW1wbGVtZW50IFNBWCBlcnJvciBoYW5kbGVyIGZvciBkZWZhdWx0IHJlcG9ydGluZy4KLSAqIEB4c2wudXNhZ2UgZ2VuZXJhbAotICovCi1wdWJsaWMgY2xhc3MgRGVmYXVsdEVycm9ySGFuZGxlciBpbXBsZW1lbnRzIEVycm9ySGFuZGxlciwgRXJyb3JMaXN0ZW5lcgotewotICBQcmludFdyaXRlciBtX3B3OwotCi0gIC8qKgotICAgKiBpZiB0aGlzIGZsYWcgaXMgc2V0IHRvIHRydWUsIHdlIHdpbGwgcmV0aHJvdyB0aGUgZXhjZXB0aW9uIG9uCi0gICAqIHRoZSBlcnJvcigpIGFuZCBmYXRhbEVycm9yKCkgbWV0aG9kcy4gSWYgaXQgaXMgZmFsc2UsIHRoZSBlcnJvcnMKLSAgICogYXJlIHJlcG9ydGVkIHRvIFN5c3RlbS5lcnIuCi0gICAqLwotICBib29sZWFuIG1fdGhyb3dFeGNlcHRpb25PbkVycm9yID0gdHJ1ZTsKLQotICAvKioKLSAgICogQ29uc3RydWN0b3IgRGVmYXVsdEVycm9ySGFuZGxlcgotICAgKi8KLSAgcHVibGljIERlZmF1bHRFcnJvckhhbmRsZXIoUHJpbnRXcml0ZXIgcHcpCi0gIHsKLSAgICBtX3B3ID0gcHc7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0b3IgRGVmYXVsdEVycm9ySGFuZGxlcgotICAgKi8KLSAgcHVibGljIERlZmF1bHRFcnJvckhhbmRsZXIoUHJpbnRTdHJlYW0gcHcpCi0gIHsKLSAgICBtX3B3ID0gbmV3IFByaW50V3JpdGVyKHB3LCB0cnVlKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3RvciBEZWZhdWx0RXJyb3JIYW5kbGVyCi0gICAqLwotICBwdWJsaWMgRGVmYXVsdEVycm9ySGFuZGxlcigpCi0gIHsKLSAgICB0aGlzKHRydWUpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdG9yIERlZmF1bHRFcnJvckhhbmRsZXIKLSAgICovCi0gIHB1YmxpYyBEZWZhdWx0RXJyb3JIYW5kbGVyKGJvb2xlYW4gdGhyb3dFeGNlcHRpb25PbkVycm9yKQotICB7Ci0gICAgbV9wdyA9IG5ldyBQcmludFdyaXRlcihTeXN0ZW0uZXJyLCB0cnVlKTsKLSAgICBtX3Rocm93RXhjZXB0aW9uT25FcnJvciA9IHRocm93RXhjZXB0aW9uT25FcnJvcjsKLSAgfQotCi0KLSAgLyoqCi0gICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGEgd2FybmluZy4KLSAgICoKLSAgICogPHA+U0FYIHBhcnNlcnMgd2lsbCB1c2UgdGhpcyBtZXRob2QgdG8gcmVwb3J0IGNvbmRpdGlvbnMgdGhhdAotICAgKiBhcmUgbm90IGVycm9ycyBvciBmYXRhbCBlcnJvcnMgYXMgZGVmaW5lZCBieSB0aGUgWE1MIDEuMAotICAgKiByZWNvbW1lbmRhdGlvbi4gIFRoZSBkZWZhdWx0IGJlaGF2aW91ciBpcyB0byB0YWtlIG5vIGFjdGlvbi48L3A+Ci0gICAqCi0gICAqIDxwPlRoZSBTQVggcGFyc2VyIG11c3QgY29udGludWUgdG8gcHJvdmlkZSBub3JtYWwgcGFyc2luZyBldmVudHMKLSAgICogYWZ0ZXIgaW52b2tpbmcgdGhpcyBtZXRob2Q6IGl0IHNob3VsZCBzdGlsbCBiZSBwb3NzaWJsZSBmb3IgdGhlCi0gICAqIGFwcGxpY2F0aW9uIHRvIHByb2Nlc3MgdGhlIGRvY3VtZW50IHRocm91Z2ggdG8gdGhlIGVuZC48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBleGNlcHRpb24gVGhlIHdhcm5pbmcgaW5mb3JtYXRpb24gZW5jYXBzdWxhdGVkIGluIGEKLSAgICogICAgICAgICAgICAgICAgICBTQVggcGFyc2UgZXhjZXB0aW9uLgotICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHdhcm5pbmcoU0FYUGFyc2VFeGNlcHRpb24gZXhjZXB0aW9uKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBwcmludExvY2F0aW9uKG1fcHcsIGV4Y2VwdGlvbik7Ci0gICAgbV9wdy5wcmludGxuKCJQYXJzZXIgd2FybmluZzogIiArIGV4Y2VwdGlvbi5nZXRNZXNzYWdlKCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGEgcmVjb3ZlcmFibGUgZXJyb3IuCi0gICAqCi0gICAqIDxwPlRoaXMgY29ycmVzcG9uZHMgdG8gdGhlIGRlZmluaXRpb24gb2YgImVycm9yIiBpbiBzZWN0aW9uIDEuMgotICAgKiBvZiB0aGUgVzNDIFhNTCAxLjAgUmVjb21tZW5kYXRpb24uICBGb3IgZXhhbXBsZSwgYSB2YWxpZGF0aW5nCi0gICAqIHBhcnNlciB3b3VsZCB1c2UgdGhpcyBjYWxsYmFjayB0byByZXBvcnQgdGhlIHZpb2xhdGlvbiBvZiBhCi0gICAqIHZhbGlkaXR5IGNvbnN0cmFpbnQuICBUaGUgZGVmYXVsdCBiZWhhdmlvdXIgaXMgdG8gdGFrZSBubwotICAgKiBhY3Rpb24uPC9wPgotICAgKgotICAgKiA8cD5UaGUgU0FYIHBhcnNlciBtdXN0IGNvbnRpbnVlIHRvIHByb3ZpZGUgbm9ybWFsIHBhcnNpbmcgZXZlbnRzCi0gICAqIGFmdGVyIGludm9raW5nIHRoaXMgbWV0aG9kOiBpdCBzaG91bGQgc3RpbGwgYmUgcG9zc2libGUgZm9yIHRoZQotICAgKiBhcHBsaWNhdGlvbiB0byBwcm9jZXNzIHRoZSBkb2N1bWVudCB0aHJvdWdoIHRvIHRoZSBlbmQuICBJZiB0aGUKLSAgICogYXBwbGljYXRpb24gY2Fubm90IGRvIHNvLCB0aGVuIHRoZSBwYXJzZXIgc2hvdWxkIHJlcG9ydCBhIGZhdGFsCi0gICAqIGVycm9yIGV2ZW4gaWYgdGhlIFhNTCAxLjAgcmVjb21tZW5kYXRpb24gZG9lcyBub3QgcmVxdWlyZSBpdCB0bwotICAgKiBkbyBzby48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBleGNlcHRpb24gVGhlIGVycm9yIGluZm9ybWF0aW9uIGVuY2Fwc3VsYXRlZCBpbiBhCi0gICAqICAgICAgICAgICAgICAgICAgU0FYIHBhcnNlIGV4Y2VwdGlvbi4KLSAgICogQHRocm93cyBTQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAqLwotICBwdWJsaWMgdm9pZCBlcnJvcihTQVhQYXJzZUV4Y2VwdGlvbiBleGNlcHRpb24pIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotICAgIC8vcHJpbnRMb2NhdGlvbihleGNlcHRpb24pOwotICAgIC8vIG1fcHcucHJpbnRsbihleGNlcHRpb24uZ2V0TWVzc2FnZSgpKTsKLQotICAgIHRocm93IGV4Y2VwdGlvbjsKLSAgfQotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBhIG5vbi1yZWNvdmVyYWJsZSBlcnJvci4KLSAgICoKLSAgICogPHA+VGhpcyBjb3JyZXNwb25kcyB0byB0aGUgZGVmaW5pdGlvbiBvZiAiZmF0YWwgZXJyb3IiIGluCi0gICAqIHNlY3Rpb24gMS4yIG9mIHRoZSBXM0MgWE1MIDEuMCBSZWNvbW1lbmRhdGlvbi4gIEZvciBleGFtcGxlLCBhCi0gICAqIHBhcnNlciB3b3VsZCB1c2UgdGhpcyBjYWxsYmFjayB0byByZXBvcnQgdGhlIHZpb2xhdGlvbiBvZiBhCi0gICAqIHdlbGwtZm9ybWVkbmVzcyBjb25zdHJhaW50LjwvcD4KLSAgICoKLSAgICogPHA+VGhlIGFwcGxpY2F0aW9uIG11c3QgYXNzdW1lIHRoYXQgdGhlIGRvY3VtZW50IGlzIHVudXNhYmxlCi0gICAqIGFmdGVyIHRoZSBwYXJzZXIgaGFzIGludm9rZWQgdGhpcyBtZXRob2QsIGFuZCBzaG91bGQgY29udGludWUKLSAgICogKGlmIGF0IGFsbCkgb25seSBmb3IgdGhlIHNha2Ugb2YgY29sbGVjdGluZyBhZGRpdGlvbiBlcnJvcgotICAgKiBtZXNzYWdlczogaW4gZmFjdCwgU0FYIHBhcnNlcnMgYXJlIGZyZWUgdG8gc3RvcCByZXBvcnRpbmcgYW55Ci0gICAqIG90aGVyIGV2ZW50cyBvbmNlIHRoaXMgbWV0aG9kIGhhcyBiZWVuIGludm9rZWQuPC9wPgotICAgKgotICAgKiBAcGFyYW0gZXhjZXB0aW9uIFRoZSBlcnJvciBpbmZvcm1hdGlvbiBlbmNhcHN1bGF0ZWQgaW4gYQotICAgKiAgICAgICAgICAgICAgICAgIFNBWCBwYXJzZSBleGNlcHRpb24uCi0gICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgKi8KLSAgcHVibGljIHZvaWQgZmF0YWxFcnJvcihTQVhQYXJzZUV4Y2VwdGlvbiBleGNlcHRpb24pIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotICAgIC8vIHByaW50TG9jYXRpb24oZXhjZXB0aW9uKTsKLSAgICAvLyBtX3B3LnByaW50bG4oZXhjZXB0aW9uLmdldE1lc3NhZ2UoKSk7Ci0KLSAgICB0aHJvdyBleGNlcHRpb247Ci0gIH0KLQotICAvKioKLSAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgYSB3YXJuaW5nLgotICAgKgotICAgKiA8cD5TQVggcGFyc2VycyB3aWxsIHVzZSB0aGlzIG1ldGhvZCB0byByZXBvcnQgY29uZGl0aW9ucyB0aGF0Ci0gICAqIGFyZSBub3QgZXJyb3JzIG9yIGZhdGFsIGVycm9ycyBhcyBkZWZpbmVkIGJ5IHRoZSBYTUwgMS4wCi0gICAqIHJlY29tbWVuZGF0aW9uLiAgVGhlIGRlZmF1bHQgYmVoYXZpb3VyIGlzIHRvIHRha2Ugbm8gYWN0aW9uLjwvcD4KLSAgICoKLSAgICogPHA+VGhlIFNBWCBwYXJzZXIgbXVzdCBjb250aW51ZSB0byBwcm92aWRlIG5vcm1hbCBwYXJzaW5nIGV2ZW50cwotICAgKiBhZnRlciBpbnZva2luZyB0aGlzIG1ldGhvZDogaXQgc2hvdWxkIHN0aWxsIGJlIHBvc3NpYmxlIGZvciB0aGUKLSAgICogYXBwbGljYXRpb24gdG8gcHJvY2VzcyB0aGUgZG9jdW1lbnQgdGhyb3VnaCB0byB0aGUgZW5kLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIGV4Y2VwdGlvbiBUaGUgd2FybmluZyBpbmZvcm1hdGlvbiBlbmNhcHN1bGF0ZWQgaW4gYQotICAgKiAgICAgICAgICAgICAgICAgIFNBWCBwYXJzZSBleGNlcHRpb24uCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICogQHNlZSBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCB3YXJuaW5nKFRyYW5zZm9ybWVyRXhjZXB0aW9uIGV4Y2VwdGlvbikgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICBwcmludExvY2F0aW9uKG1fcHcsIGV4Y2VwdGlvbik7Ci0KLSAgICBtX3B3LnByaW50bG4oZXhjZXB0aW9uLmdldE1lc3NhZ2UoKSk7Ci0gIH0KLQotICAvKioKLSAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgYSByZWNvdmVyYWJsZSBlcnJvci4KLSAgICoKLSAgICogPHA+VGhpcyBjb3JyZXNwb25kcyB0byB0aGUgZGVmaW5pdGlvbiBvZiAiZXJyb3IiIGluIHNlY3Rpb24gMS4yCi0gICAqIG9mIHRoZSBXM0MgWE1MIDEuMCBSZWNvbW1lbmRhdGlvbi4gIEZvciBleGFtcGxlLCBhIHZhbGlkYXRpbmcKLSAgICogcGFyc2VyIHdvdWxkIHVzZSB0aGlzIGNhbGxiYWNrIHRvIHJlcG9ydCB0aGUgdmlvbGF0aW9uIG9mIGEKLSAgICogdmFsaWRpdHkgY29uc3RyYWludC4gIFRoZSBkZWZhdWx0IGJlaGF2aW91ciBpcyB0byB0YWtlIG5vCi0gICAqIGFjdGlvbi48L3A+Ci0gICAqCi0gICAqIDxwPlRoZSBTQVggcGFyc2VyIG11c3QgY29udGludWUgdG8gcHJvdmlkZSBub3JtYWwgcGFyc2luZyBldmVudHMKLSAgICogYWZ0ZXIgaW52b2tpbmcgdGhpcyBtZXRob2Q6IGl0IHNob3VsZCBzdGlsbCBiZSBwb3NzaWJsZSBmb3IgdGhlCi0gICAqIGFwcGxpY2F0aW9uIHRvIHByb2Nlc3MgdGhlIGRvY3VtZW50IHRocm91Z2ggdG8gdGhlIGVuZC4gIElmIHRoZQotICAgKiBhcHBsaWNhdGlvbiBjYW5ub3QgZG8gc28sIHRoZW4gdGhlIHBhcnNlciBzaG91bGQgcmVwb3J0IGEgZmF0YWwKLSAgICogZXJyb3IgZXZlbiBpZiB0aGUgWE1MIDEuMCByZWNvbW1lbmRhdGlvbiBkb2VzIG5vdCByZXF1aXJlIGl0IHRvCi0gICAqIGRvIHNvLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIGV4Y2VwdGlvbiBUaGUgZXJyb3IgaW5mb3JtYXRpb24gZW5jYXBzdWxhdGVkIGluIGEKLSAgICogICAgICAgICAgICAgICAgICBTQVggcGFyc2UgZXhjZXB0aW9uLgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAqIEBzZWUgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgZXJyb3IoVHJhbnNmb3JtZXJFeGNlcHRpb24gZXhjZXB0aW9uKSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIC8vIElmIHRoZSBtX3Rocm93RXhjZXB0aW9uT25FcnJvciBmbGFnIGlzIHRydWUsIHJldGhyb3cgdGhlIGV4Y2VwdGlvbi4KLSAgICAvLyBPdGhlcndpc2UgcmVwb3J0IHRoZSBlcnJvciB0byBTeXN0ZW0uZXJyLgotICAgIGlmIChtX3Rocm93RXhjZXB0aW9uT25FcnJvcikKLSAgICAgIHRocm93IGV4Y2VwdGlvbjsKLSAgICBlbHNlCi0gICAgewotICAgICAgcHJpbnRMb2NhdGlvbihtX3B3LCBleGNlcHRpb24pOwotICAgICAgbV9wdy5wcmludGxuKGV4Y2VwdGlvbi5nZXRNZXNzYWdlKCkpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBhIG5vbi1yZWNvdmVyYWJsZSBlcnJvci4KLSAgICoKLSAgICogPHA+VGhpcyBjb3JyZXNwb25kcyB0byB0aGUgZGVmaW5pdGlvbiBvZiAiZmF0YWwgZXJyb3IiIGluCi0gICAqIHNlY3Rpb24gMS4yIG9mIHRoZSBXM0MgWE1MIDEuMCBSZWNvbW1lbmRhdGlvbi4gIEZvciBleGFtcGxlLCBhCi0gICAqIHBhcnNlciB3b3VsZCB1c2UgdGhpcyBjYWxsYmFjayB0byByZXBvcnQgdGhlIHZpb2xhdGlvbiBvZiBhCi0gICAqIHdlbGwtZm9ybWVkbmVzcyBjb25zdHJhaW50LjwvcD4KLSAgICoKLSAgICogPHA+VGhlIGFwcGxpY2F0aW9uIG11c3QgYXNzdW1lIHRoYXQgdGhlIGRvY3VtZW50IGlzIHVudXNhYmxlCi0gICAqIGFmdGVyIHRoZSBwYXJzZXIgaGFzIGludm9rZWQgdGhpcyBtZXRob2QsIGFuZCBzaG91bGQgY29udGludWUKLSAgICogKGlmIGF0IGFsbCkgb25seSBmb3IgdGhlIHNha2Ugb2YgY29sbGVjdGluZyBhZGRpdGlvbiBlcnJvcgotICAgKiBtZXNzYWdlczogaW4gZmFjdCwgU0FYIHBhcnNlcnMgYXJlIGZyZWUgdG8gc3RvcCByZXBvcnRpbmcgYW55Ci0gICAqIG90aGVyIGV2ZW50cyBvbmNlIHRoaXMgbWV0aG9kIGhhcyBiZWVuIGludm9rZWQuPC9wPgotICAgKgotICAgKiBAcGFyYW0gZXhjZXB0aW9uIFRoZSBlcnJvciBpbmZvcm1hdGlvbiBlbmNhcHN1bGF0ZWQgaW4gYQotICAgKiAgICAgICAgICAgICAgICAgIFNBWCBwYXJzZSBleGNlcHRpb24uCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICogQHNlZSBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBmYXRhbEVycm9yKFRyYW5zZm9ybWVyRXhjZXB0aW9uIGV4Y2VwdGlvbikgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICAvLyBJZiB0aGUgbV90aHJvd0V4Y2VwdGlvbk9uRXJyb3IgZmxhZyBpcyB0cnVlLCByZXRocm93IHRoZSBleGNlcHRpb24uCi0gICAgLy8gT3RoZXJ3aXNlIHJlcG9ydCB0aGUgZXJyb3IgdG8gU3lzdGVtLmVyci4KLSAgICBpZiAobV90aHJvd0V4Y2VwdGlvbk9uRXJyb3IpCi0gICAgICB0aHJvdyBleGNlcHRpb247Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIHByaW50TG9jYXRpb24obV9wdywgZXhjZXB0aW9uKTsKLSAgICAgIG1fcHcucHJpbnRsbihleGNlcHRpb24uZ2V0TWVzc2FnZSgpKTsKLSAgICB9Ci0gIH0KLQotICBwdWJsaWMgc3RhdGljIHZvaWQgZW5zdXJlTG9jYXRpb25TZXQoVHJhbnNmb3JtZXJFeGNlcHRpb24gZXhjZXB0aW9uKQotICB7Ci0gICAgLy8gU291cmNlTG9jYXRvciBsb2NhdG9yID0gZXhjZXB0aW9uLmdldExvY2F0b3IoKTsKLSAgICBTb3VyY2VMb2NhdG9yIGxvY2F0b3IgPSBudWxsOwotICAgIFRocm93YWJsZSBjYXVzZSA9IGV4Y2VwdGlvbjsKLQotICAgIC8vIFRyeSB0byBmaW5kIHRoZSBsb2NhdG9yIGNsb3Nlc3QgdG8gdGhlIGNhdXNlLgotICAgIGRvCi0gICAgewotICAgICAgaWYoY2F1c2UgaW5zdGFuY2VvZiBTQVhQYXJzZUV4Y2VwdGlvbikKLSAgICAgIHsKLSAgICAgICAgbG9jYXRvciA9IG5ldyBTQVhTb3VyY2VMb2NhdG9yKChTQVhQYXJzZUV4Y2VwdGlvbiljYXVzZSk7Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmIChjYXVzZSBpbnN0YW5jZW9mIFRyYW5zZm9ybWVyRXhjZXB0aW9uKQotICAgICAgewotICAgICAgICBTb3VyY2VMb2NhdG9yIGNhdXNlTG9jYXRvciA9ICgoVHJhbnNmb3JtZXJFeGNlcHRpb24pY2F1c2UpLmdldExvY2F0b3IoKTsKLSAgICAgICAgaWYobnVsbCAhPSBjYXVzZUxvY2F0b3IpCi0gICAgICAgICAgbG9jYXRvciA9IGNhdXNlTG9jYXRvcjsKLSAgICAgIH0KLQotICAgICAgaWYoY2F1c2UgaW5zdGFuY2VvZiBUcmFuc2Zvcm1lckV4Y2VwdGlvbikKLSAgICAgICAgY2F1c2UgPSAoKFRyYW5zZm9ybWVyRXhjZXB0aW9uKWNhdXNlKS5nZXRDYXVzZSgpOwotICAgICAgZWxzZSBpZihjYXVzZSBpbnN0YW5jZW9mIFNBWEV4Y2VwdGlvbikKLSAgICAgICAgY2F1c2UgPSAoKFNBWEV4Y2VwdGlvbiljYXVzZSkuZ2V0RXhjZXB0aW9uKCk7Ci0gICAgICBlbHNlCi0gICAgICAgIGNhdXNlID0gbnVsbDsKLSAgICB9Ci0gICAgd2hpbGUobnVsbCAhPSBjYXVzZSk7Ci0KLSAgICBleGNlcHRpb24uc2V0TG9jYXRvcihsb2NhdG9yKTsKLSAgfQotCi0gIHB1YmxpYyBzdGF0aWMgdm9pZCBwcmludExvY2F0aW9uKFByaW50U3RyZWFtIHB3LCBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBleGNlcHRpb24pCi0gIHsKLSAgICBwcmludExvY2F0aW9uKG5ldyBQcmludFdyaXRlcihwdyksIGV4Y2VwdGlvbik7Ci0gIH0KLQotICBwdWJsaWMgc3RhdGljIHZvaWQgcHJpbnRMb2NhdGlvbihqYXZhLmlvLlByaW50U3RyZWFtIHB3LCBvcmcueG1sLnNheC5TQVhQYXJzZUV4Y2VwdGlvbiBleGNlcHRpb24pCi0gIHsKLSAgICBwcmludExvY2F0aW9uKG5ldyBQcmludFdyaXRlcihwdyksIGV4Y2VwdGlvbik7Ci0gIH0KLQotICBwdWJsaWMgc3RhdGljIHZvaWQgcHJpbnRMb2NhdGlvbihQcmludFdyaXRlciBwdywgVGhyb3dhYmxlIGV4Y2VwdGlvbikKLSAgewotICAgIFNvdXJjZUxvY2F0b3IgbG9jYXRvciA9IG51bGw7Ci0gICAgVGhyb3dhYmxlIGNhdXNlID0gZXhjZXB0aW9uOwotCi0gICAgLy8gVHJ5IHRvIGZpbmQgdGhlIGxvY2F0b3IgY2xvc2VzdCB0byB0aGUgY2F1c2UuCi0gICAgZG8KLSAgICB7Ci0gICAgICBpZihjYXVzZSBpbnN0YW5jZW9mIFNBWFBhcnNlRXhjZXB0aW9uKQotICAgICAgewotICAgICAgICBsb2NhdG9yID0gbmV3IFNBWFNvdXJjZUxvY2F0b3IoKFNBWFBhcnNlRXhjZXB0aW9uKWNhdXNlKTsKLSAgICAgIH0KLSAgICAgIGVsc2UgaWYgKGNhdXNlIGluc3RhbmNlb2YgVHJhbnNmb3JtZXJFeGNlcHRpb24pCi0gICAgICB7Ci0gICAgICAgIFNvdXJjZUxvY2F0b3IgY2F1c2VMb2NhdG9yID0gKChUcmFuc2Zvcm1lckV4Y2VwdGlvbiljYXVzZSkuZ2V0TG9jYXRvcigpOwotICAgICAgICBpZihudWxsICE9IGNhdXNlTG9jYXRvcikKLSAgICAgICAgICBsb2NhdG9yID0gY2F1c2VMb2NhdG9yOwotICAgICAgfQotICAgICAgaWYoY2F1c2UgaW5zdGFuY2VvZiBUcmFuc2Zvcm1lckV4Y2VwdGlvbikKLSAgICAgICAgY2F1c2UgPSAoKFRyYW5zZm9ybWVyRXhjZXB0aW9uKWNhdXNlKS5nZXRDYXVzZSgpOwotICAgICAgZWxzZSBpZihjYXVzZSBpbnN0YW5jZW9mIFdyYXBwZWRSdW50aW1lRXhjZXB0aW9uKQotICAgICAgICBjYXVzZSA9ICgoV3JhcHBlZFJ1bnRpbWVFeGNlcHRpb24pY2F1c2UpLmdldEV4Y2VwdGlvbigpOwotICAgICAgZWxzZSBpZihjYXVzZSBpbnN0YW5jZW9mIFNBWEV4Y2VwdGlvbikKLSAgICAgICAgY2F1c2UgPSAoKFNBWEV4Y2VwdGlvbiljYXVzZSkuZ2V0RXhjZXB0aW9uKCk7Ci0gICAgICBlbHNlCi0gICAgICAgIGNhdXNlID0gbnVsbDsKLSAgICB9Ci0gICAgd2hpbGUobnVsbCAhPSBjYXVzZSk7Ci0KLSAgICBpZihudWxsICE9IGxvY2F0b3IpCi0gICAgewotICAgICAgLy8gbV9wdy5wcmludGxuKCJQYXJzZXIgZmF0YWwgZXJyb3I6ICIrZXhjZXB0aW9uLmdldE1lc3NhZ2UoKSk7Ci0gICAgICBTdHJpbmcgaWQgPSAobnVsbCAhPSBsb2NhdG9yLmdldFB1YmxpY0lkKCkgKQotICAgICAgICAgICAgICAgICAgPyBsb2NhdG9yLmdldFB1YmxpY0lkKCkKLSAgICAgICAgICAgICAgICAgICAgOiAobnVsbCAhPSBsb2NhdG9yLmdldFN5c3RlbUlkKCkpCi0gICAgICAgICAgICAgICAgICAgICAgPyBsb2NhdG9yLmdldFN5c3RlbUlkKCkgOiBYTUxNZXNzYWdlcy5jcmVhdGVYTUxNZXNzYWdlKFhNTEVycm9yUmVzb3VyY2VzLkVSX1NZU1RFTUlEX1VOS05PV04sIG51bGwpOyAvLyJTeXN0ZW1JZCBVbmtub3duIjsKLQotICAgICAgcHcucHJpbnQoaWQgKyAiOyAiICtYTUxNZXNzYWdlcy5jcmVhdGVYTUxNZXNzYWdlKCJsaW5lIiwgbnVsbCkgKyBsb2NhdG9yLmdldExpbmVOdW1iZXIoKQotICAgICAgICAgICAgICAgICAgICAgICAgICsgIjsgIiArWE1MTWVzc2FnZXMuY3JlYXRlWE1MTWVzc2FnZSgiY29sdW1uIiwgbnVsbCkgKyBsb2NhdG9yLmdldENvbHVtbk51bWJlcigpKyI7ICIpOwotICAgIH0KLSAgICBlbHNlCi0gICAgICBwdy5wcmludCgiKCIrWE1MTWVzc2FnZXMuY3JlYXRlWE1MTWVzc2FnZShYTUxFcnJvclJlc291cmNlcy5FUl9MT0NBVElPTl9VTktOT1dOLCBudWxsKSsiKSIpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9FbGVtRGVzYy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvRWxlbURlc2MuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDIzN2IwMS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9FbGVtRGVzYy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTkzICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKi8KLS8qCi0gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKLSAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAotICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgotICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKLSAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCi0gKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRWxlbURlc2MuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNSAwODoxNTo0NCBzdXJlc2hfZW1haWxpZCBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHM7Ci0KLWltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKLWltcG9ydCBqYXZhLnV0aWwuTWFwOwotCi0KLS8qKgotICogVGhpcyBjbGFzcyBpcyBpbiBzdXBwb3J0IG9mIFNlcmlhbGl6ZXJUb0hUTUwsIGFuZCBhY3RzIGFzIGEgc29ydAotICogb2YgZWxlbWVudCByZXByZXNlbnRhdGl2ZSBmb3IgSFRNTCBlbGVtZW50cy4KLSAqIEB4c2wudXNhZ2UgaW50ZXJuYWwKLSAqLwotY2xhc3MgRWxlbURlc2MKLXsKLQotICAvKiogVGFibGUgb2YgYXR0cmlidXRlcyBmb3IgdGhlIGVsZW1lbnQgKi8KLSAgTWFwPFN0cmluZywgSW50ZWdlcj4gbV9hdHRycyA9IG51bGw7Ci0KLSAgLyoqIEVsZW1lbnQncyBmbGFncywgZGVzY3JpYmluZyB0aGUgcm9sZSB0aGlzIGVsZW1lbnQgcGxheXMgZHVyaW5nCi0gICAqIGZvcm1hdHRpbmcgb2YgdGhlIGRvY3VtZW50LiBUaGlzIGlzIHVzZWQgYXMgYSBiaXR2ZWN0b3I7IG1vcmUgdGhhbiBvbmUgZmxhZwotICAgKiBtYXkgYmUgc2V0IGF0IGEgdGltZSwgYml0d2lzZS1PUmVkIHRvZ2V0aGVyLiBNbmVtb25pYyBhbmQgYml0cwotICAgKiBoYXZlIGJlZW4gYXNzaWduZWQgdG8gdGhlIGZsYWcgdmFsdWVzLiBOT1RFOiBTb21lIGJpdHMgYXJlCi0gICAqIGN1cnJlbnRseSBhc3NpZ25lZCBtdWx0aXBsZSBtbmVtb25pY3M7IGl0IGlzIHRoZSBjYWxsZXIncwotICAgKiByZXNwb25zaWJpbGl0eSB0byBkaXNhbWJpZ3VhdGUgdGhlc2UgaWYgbmVjZXNzYXJ5LiAqLwotICBpbnQgbV9mbGFnczsKLQotICAvKiogRGVmaW5lcyBtbmVtb25pYyBhbmQgYml0LXZhbHVlIGZvciB0aGUgRU1QVFkgZmxhZyAqLwotICBzdGF0aWMgZmluYWwgaW50IEVNUFRZID0gKDEgPDwgMSk7Ci0KLSAgLyoqIERlZmluZXMgbW5lbW9uaWMgYW5kIGJpdC12YWx1ZSBmb3IgdGhlIEZMT1cgZmxhZyAgKi8KLSAgc3RhdGljIGZpbmFsIGludCBGTE9XID0gKDEgPDwgMik7Ci0KLSAgLyoqIERlZmluZXMgbW5lbW9uaWMgYW5kIGJpdC12YWx1ZSBmb3IgdGhlIEJMT0NLIGZsYWcgICAgICAgICAgKi8KLSAgc3RhdGljIGZpbmFsIGludCBCTE9DSyA9ICgxIDw8IDMpOwotCi0gIC8qKiBEZWZpbmVzIG1uZW1vbmljIGFuZCBiaXQtdmFsdWUgZm9yIHRoZSBCTE9DS0ZPUk0gIGZsYWcgICAgICAgICAqLwotICBzdGF0aWMgZmluYWwgaW50IEJMT0NLRk9STSA9ICgxIDw8IDQpOwotCi0gIC8qKiBEZWZpbmVzIG1uZW1vbmljIGFuZCBiaXQtdmFsdWUgZm9yIHRoZSBCTE9DS0ZPUk1GSUVMRFNFVCBmbGFnICAgICAgICAgICovCi0gIHN0YXRpYyBmaW5hbCBpbnQgQkxPQ0tGT1JNRklFTERTRVQgPSAoMSA8PCA1KTsKLQotICAvKiogRGVmaW5lcyBtbmVtb25pYyBhbmQgYml0LXZhbHVlIGZvciB0aGUgQ0RBVEEgZmxhZyAgICAgICAgICovCi0gIHN0YXRpYyBmaW5hbCBpbnQgQ0RBVEEgPSAoMSA8PCA2KTsKLQotICAvKiogRGVmaW5lcyBtbmVtb25pYyBhbmQgYml0LXZhbHVlIGZvciB0aGUgUENEQVRBIGZsYWcgICAgICAgICAgKi8KLSAgc3RhdGljIGZpbmFsIGludCBQQ0RBVEEgPSAoMSA8PCA3KTsKLQotICAvKiogRGVmaW5lcyBtbmVtb25pYyBhbmQgYml0LXZhbHVlIGZvciB0aGUgUkFXIGZsYWcgICAgICAgICAqLwotICBzdGF0aWMgZmluYWwgaW50IFJBVyA9ICgxIDw8IDgpOwotCi0gIC8qKiBEZWZpbmVzIG1uZW1vbmljIGFuZCBiaXQtdmFsdWUgZm9yIHRoZSBJTkxJTkUgZmxhZyAgICAgICAgICAqLwotICBzdGF0aWMgZmluYWwgaW50IElOTElORSA9ICgxIDw8IDkpOwotCi0gIC8qKiBEZWZpbmVzIG1uZW1vbmljIGFuZCBiaXQtdmFsdWUgZm9yIHRoZSBJTkxJTkVBIGZsYWcgICAgICAgICAgKi8KLSAgc3RhdGljIGZpbmFsIGludCBJTkxJTkVBID0gKDEgPDwgMTApOwotCi0gIC8qKiBEZWZpbmVzIG1uZW1vbmljIGFuZCBiaXQtdmFsdWUgZm9yIHRoZSBJTkxJTkVMQUJFTCBmbGFnICAgICAgICAgICovCi0gIHN0YXRpYyBmaW5hbCBpbnQgSU5MSU5FTEFCRUwgPSAoMSA8PCAxMSk7Ci0KLSAgLyoqIERlZmluZXMgbW5lbW9uaWMgYW5kIGJpdC12YWx1ZSBmb3IgdGhlIEZPTlRTVFlMRSBmbGFnICAgICAgICAgICovCi0gIHN0YXRpYyBmaW5hbCBpbnQgRk9OVFNUWUxFID0gKDEgPDwgMTIpOwotCi0gIC8qKiBEZWZpbmVzIG1uZW1vbmljIGFuZCBiaXQtdmFsdWUgZm9yIHRoZSBQSFJBU0UgZmxhZyAgICAgICAgICAqLwotICBzdGF0aWMgZmluYWwgaW50IFBIUkFTRSA9ICgxIDw8IDEzKTsKLQotICAvKiogRGVmaW5lcyBtbmVtb25pYyBhbmQgYml0LXZhbHVlIGZvciB0aGUgRk9STUNUUkwgZmxhZyAgICAgICAgICovCi0gIHN0YXRpYyBmaW5hbCBpbnQgRk9STUNUUkwgPSAoMSA8PCAxNCk7Ci0KLSAgLyoqIERlZmluZXMgbW5lbW9uaWMgYW5kIGJpdC12YWx1ZSBmb3IgdGhlIFNQRUNJQUwgZmxhZyAgICAgICAgICovCi0gIHN0YXRpYyBmaW5hbCBpbnQgU1BFQ0lBTCA9ICgxIDw8IDE1KTsKLQotICAvKiogRGVmaW5lcyBtbmVtb25pYyBhbmQgYml0LXZhbHVlIGZvciB0aGUgQVNQRUNJQUwgZmxhZyAgICAgICAgICovCi0gIHN0YXRpYyBmaW5hbCBpbnQgQVNQRUNJQUwgPSAoMSA8PCAxNik7Ci0KLSAgLyoqIERlZmluZXMgbW5lbW9uaWMgYW5kIGJpdC12YWx1ZSBmb3IgdGhlIEhFQURNSVNDIGZsYWcgICAgICAgICAqLwotICBzdGF0aWMgZmluYWwgaW50IEhFQURNSVNDID0gKDEgPDwgMTcpOwotCi0gIC8qKiBEZWZpbmVzIG1uZW1vbmljIGFuZCBiaXQtdmFsdWUgZm9yIHRoZSBIRUFEIGZsYWcgICAgICAgICAqLwotICBzdGF0aWMgZmluYWwgaW50IEhFQUQgPSAoMSA8PCAxOCk7Ci0KLSAgLyoqIERlZmluZXMgbW5lbW9uaWMgYW5kIGJpdC12YWx1ZSBmb3IgdGhlIExJU1QgZmxhZyAgICAgICAgICovCi0gIHN0YXRpYyBmaW5hbCBpbnQgTElTVCA9ICgxIDw8IDE5KTsKLQotICAvKiogRGVmaW5lcyBtbmVtb25pYyBhbmQgYml0LXZhbHVlIGZvciB0aGUgUFJFRk9STUFUVEVEIGZsYWcgICAgICAgICAqLwotICBzdGF0aWMgZmluYWwgaW50IFBSRUZPUk1BVFRFRCA9ICgxIDw8IDIwKTsKLQotICAvKiogRGVmaW5lcyBtbmVtb25pYyBhbmQgYml0LXZhbHVlIGZvciB0aGUgV0hJVEVTUEFDRVNFTlNJVElWRSBmbGFnICAgICAgICAgKi8KLSAgc3RhdGljIGZpbmFsIGludCBXSElURVNQQUNFU0VOU0lUSVZFID0gKDEgPDwgMjEpOwotCi0gIC8qKiBEZWZpbmVzIG1uZW1vbmljIGFuZCBiaXQtdmFsdWUgZm9yIHRoZSBBVFRSVVJMIGZsYWcgICAgICAgICAqLwotICBzdGF0aWMgZmluYWwgaW50IEFUVFJVUkwgPSAoMSA8PCAxKTsKLQotICAvKiogRGVmaW5lcyBtbmVtb25pYyBhbmQgYml0LXZhbHVlIGZvciB0aGUgQVRUUkVNUFRZIGZsYWcgICAgICAgICAqLwotICBzdGF0aWMgZmluYWwgaW50IEFUVFJFTVBUWSA9ICgxIDw8IDIpOwotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYW4gRWxlbWVudERlc2NyaXB0aW9uIHdpdGggYW4gaW5pdGlhbCBzZXQgb2YgZmxhZ3MuCi0gICAqCi0gICAqIEBwYXJhbSBmbGFncyBFbGVtZW50IGZsYWdzCi0gICAqIEBzZWUgbV9mbGFncwotICAgKi8KLSAgRWxlbURlc2MoaW50IGZsYWdzKQotICB7Ci0gICAgbV9mbGFncyA9IGZsYWdzOwotICB9Ci0KLSAgLyoqCi0gICAqICJpcyAodGhpcyBlbGVtZW50IGRlc2NyaWJlZCBieSB0aGVzZSBmbGFncykiLgotICAgKgotICAgKiBUaGlzIG1pZ2h0IG1vcmUgcHJvcGVybHkgYmUgY2FsbGVkIGFyZUZsYWdzU2V0KCkuIEl0IGFjY2VwdHMgYW4KLSAgICogaW50ZWdlciAoYmVpbmcgdXNlZCBhcyBhIGJpdHZlY3RvcikgYW5kIGNoZWNrcyB3aGV0aGVyIGFsbCB0aGUKLSAgICogY29ycmVzcG9uZGluZyBiaXRzIGFyZSBzZXQgaW4gb3VyIGludGVybmFsIGZsYWdzLiBOb3RlIHRoYXQgdGhpcwotICAgKiB0ZXN0IGlzIHBlcmZvcm1lZCBhcyBhIGJpdHdpc2UgQU5ELCBub3QgYW4gZXF1YWxpdHkgdGVzdCwgc28gYQotICAgKiAwIGJpdCBpbiB0aGUgaW5wdXQgbWVhbnMgImRvbid0IHRlc3QiLCBub3QgIm11c3QgYmUgc2V0IGZhbHNlIi4KLSAgICoKLSAgICogQHBhcmFtIGZsYWdzIFZlY3RvciBvZiBmbGFncyB0byBjb21wYXJlIGFnYWluc3QgdGhpcyBlbGVtZW50J3MgZmxhZ3MKLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHRoZSBmbGFncyBzZXQgaW4gdGhlIHBhcmFtZXRlciBhcmUgYWxzbyBzZXQgaW4gdGhlCi0gICAqIGVsZW1lbnQncyBzdG9yZWQgZmxhZ3MuCi0gICAqCi0gICAqIEBzZWUgbV9mbGFncwotICAgKiBAc2VlIGlzQXR0ckZsYWdTZXQKLSAgICovCi0gIGJvb2xlYW4gaXMoaW50IGZsYWdzKQotICB7Ci0gICAgLy8gaW50IHdoaWNoID0gKG1fZmxhZ3MgJiBmbGFncyk7Ci0gICAgcmV0dXJuIChtX2ZsYWdzICYgZmxhZ3MpICE9IDA7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IGEgbmV3IGF0dHJpYnV0ZSBmb3IgdGhpcyBlbGVtZW50Ci0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lIEF0dHJpYnV0ZSBuYW1lCi0gICAqIEBwYXJhbSBmbGFncyBBdHRpYnV0ZSBmbGFncwotICAgKi8KLSAgdm9pZCBzZXRBdHRyKFN0cmluZyBuYW1lLCBpbnQgZmxhZ3MpCi0gIHsKLQotICAgIGlmIChudWxsID09IG1fYXR0cnMpCi0gICAgICBtX2F0dHJzID0gbmV3IEhhc2hNYXA8PigpOwotCi0gICAgbV9hdHRycy5wdXQobmFtZSwgZmxhZ3MpOwotICB9Ci0KLSAgLyoqCi0gICAqIEZpbmQgb3V0IGlmIGEgZmxhZyBpcyBzZXQgaW4gYSBnaXZlbiBhdHRyaWJ1dGUgb2YgdGhpcyBlbGVtZW50Ci0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lIEF0dHJpYnV0ZSBuYW1lCi0gICAqIEBwYXJhbSBmbGFncyBGbGFnIHRvIGNoZWNrCi0gICAqCi0gICAqIEByZXR1cm4gVHJ1ZSBpZiB0aGUgZmxhZyBpcyBzZXQgaW4gdGhlIGF0dHJpYnV0ZS4gUmV0dXJucyBmYWxzZQotICAgKiBpZiB0aGUgYXR0cmlidXRlIGlzIG5vdCBmb3VuZAotICAgKiBAc2VlIG1fZmxhZ3MKLSAgICovCi0gIGJvb2xlYW4gaXNBdHRyRmxhZ1NldChTdHJpbmcgbmFtZSwgaW50IGZsYWdzKQotICB7Ci0KLSAgICBpZiAobnVsbCAhPSBtX2F0dHJzKQotICAgIHsKLSAgICAgIEludGVnZXIgX2ZsYWdzID0gbV9hdHRycy5nZXQobmFtZSk7Ci0KLSAgICAgIGlmIChudWxsICE9IF9mbGFncykKLSAgICAgIHsKLSAgICAgICAgcmV0dXJuIChfZmxhZ3MgJiBmbGFncykgIT0gMDsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gZmFsc2U7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL0Zhc3RTdHJpbmdCdWZmZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL0Zhc3RTdHJpbmdCdWZmZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYjhiOWE1MS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9GYXN0U3RyaW5nQnVmZmVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMjk4ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IEZhc3RTdHJpbmdCdWZmZXIuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNSAwODoxNTo0NCBzdXJlc2hfZW1haWxpZCBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHM7Ci0KLS8qKgotICogQmFyZS1ib25lcywgdW5zYWZlLCBmYXN0IHN0cmluZyBidWZmZXIuIE5vIHRocmVhZC1zYWZldHksIG5vCi0gKiBwYXJhbWV0ZXIgcmFuZ2UgY2hlY2tpbmcsIGV4cG9zZWQgZmllbGRzLiBOb3RlIHRoYXQgaW4gdHlwaWNhbAotICogYXBwbGljYXRpb25zLCB0aHJlYWQtc2FmZXR5IG9mIGEgU3RyaW5nQnVmZmVyIGlzIGEgc29tZXdoYXQKLSAqIGR1YmlvdXMgY29uY2VwdCBpbiBhbnkgY2FzZS4KLSAqIDxwPgotICogTm90ZSB0aGF0IFN0cmVlIGFuZCBEVE0gdXNlZCBhIHNpbmdsZSBGYXN0U3RyaW5nQnVmZmVyIGFzIGEgc3RyaW5nIHBvb2wsCi0gKiBieSByZWNvcmRpbmcgc3RhcnQgYW5kIGxlbmd0aCBpbmRpY2VzIHdpdGhpbiB0aGlzIHNpbmdsZSBidWZmZXIuIFRoaXMKLSAqIG1pbmltaXplcyBoZWFwIG92ZXJoZWFkLCBidXQgb2YgY291cnNlIHJlcXVpcmVzIG1vcmUgd29yayB3aGVuIHJldHJpZXZpbmcKLSAqIHRoZSBkYXRhLgotICogPHA+Ci0gKiBGYXN0U3RyaW5nQnVmZmVyIG9wZXJhdGVzIGFzIGEgImNodW5rZWQgYnVmZmVyIi4gRG9pbmcgc28KLSAqIHJlZHVjZXMgdGhlIG5lZWQgdG8gcmVjb3B5IGV4aXN0aW5nIGluZm9ybWF0aW9uIHdoZW4gYW4gYXBwZW5kCi0gKiBleGNlZWRzIHRoZSBzcGFjZSBhdmFpbGFibGU7IHdlIGp1c3QgYWxsb2NhdGUgYW5vdGhlciBjaHVuayBhbmQKLSAqIGZsb3cgYWNyb3NzIHRvIGl0LiAoVGhlIGFycmF5IG9mIGNodW5rcyBtYXkgbmVlZCB0byBncm93LAotICogYWRtaXR0ZWRseSwgYnV0IHRoYXQncyBhIG11Y2ggc21hbGxlciBvYmplY3QuKSBTb21lIGV4Y2VzcwotICogcmVjb3B5aW5nIG1heSBhcmlzZSB3aGVuIHdlIGV4dHJhY3QgU3RyaW5ncyB3aGljaCBjcm9zcyBjaHVuawotICogYm91bmRhcmllczsgbGFyZ2VyIGNodW5rcyBtYWtlIHRoYXQgbGVzcyBmcmVxdWVudC4KLSAqIDxwPgotICogVGhlIHNpemUgdmFsdWVzIGFyZSBwYXJhbWV0ZXJpemVkLCB0byBhbGxvdyB0dW5pbmcgdGhpcyBjb2RlLiBJbgotICogdGhlb3J5LCBSZXN1bHQgVHJlZSBGcmFnbWVudHMgbWlnaHQgd2FudCB0byBiZSB0dW5lZCBkaWZmZXJlbnRseQotICogZnJvbSB0aGUgbWFpbiBkb2N1bWVudCdzIHRleHQuCi0gKiA8cD4KLSAqICVSRVZJRVclIEFuIGV4cGVyaW1lbnQgaW4gc2VsZi10dW5pbmcgaXMKLSAqIGluY2x1ZGVkIGluIHRoZSBjb2RlICh1c2luZyBuZXN0ZWQgRmFzdFN0cmluZ0J1ZmZlcnMgdG8gYWNoaWV2ZQotICogdmFyaWF0aW9uIGluIGNodW5rIHNpemVzKSwgYnV0IHRoaXMgaW1wbGVtZW50YXRpb24gaGFzIHByb3ZlbiB0bwotICogYmUgcHJvYmxlbWF0aWMgd2hlbiBkYXRhIG1heSBiZSBiZWluZyBjb3BpZWQgZnJvbSB0aGUgRlNCIGludG8gaXRzZWxmLgotICogV2Ugc2hvdWxkIGVpdGhlciByZS1hcmNoaXRlY3QgdGhhdCB0byBtYWtlIHRoaXMgc2FmZSAoaWYgcG9zc2libGUpCi0gKiBvciByZW1vdmUgdGhhdCBjb2RlIGFuZCBjbGVhbiB1cCBmb3IgcGVyZm9ybWFuY2UvbWFpbnRhaW5hYmlsaXR5IHJlYXNvbnMuCi0gKiA8cD4KLSAqLwotcHVibGljIGNsYXNzIEZhc3RTdHJpbmdCdWZmZXIKLXsKLSAgLy8gSWYgbm9uemVybywgZm9yY2VzIHRoZSBpbmlhbCBjaHVuayBzaXplLgotICAvKiovc3RhdGljIGZpbmFsIGludCBERUJVR19GT1JDRV9JTklUX0JJVFM9MDsKLQotICAgICAgICAvLyAlQlVHJSAlUkVWSUVXJSAqKioqKlBST0JMRU0gU1VTUEVDVEVEOiBJZiBkYXRhIGZyb20gYW4gRlNCIGlzIGJlaW5nIGNvcGllZAotICAgICAgICAvLyBiYWNrIGludG8gdGhlIHNhbWUgRlNCICh2YXJpYWJsZSBzZXQgZnJvbSBwcmV2aW91cyB2YXJpYWJsZSwgZm9yIGV4YW1wbGUpCi0gICAgICAgIC8vIGFuZCBibG9ja3NpemUgY2hhbmdlcyBpbiBtaWQtY29weS4uLiB0aGVyZSdzIHJpc2sgb2Ygc2V2ZXJlIG1hbGZ1bmN0aW9uIGluCi0gICAgICAgIC8vIHRoZSByZWFkIHByb2Nlc3MsIGR1ZSB0byBob3cgdGhlIHJlc2l6aW5nIGNvZGUgcmUtamlnZ2VycyBzdG9yYWdlLiBBcmdnaC4KLSAgICAgICAgLy8gSWYgd2Ugd2FudCB0byByZXRhaW4gdGhlIHZhcmlhYmxlLXNpemUtYmxvY2sgZmVhdHVyZSwgd2UgbmVlZCB0byByZWNvbnNpZGVyCi0gICAgICAgIC8vIHRoYXQgaXNzdWUuIEZvciBub3csIEkgaGF2ZSBmb3JjZWQgdXMgaW50byBmaXhlZC1zaXplIG1vZGUuCi0gICAgc3RhdGljIGZpbmFsIGJvb2xlYW4gREVCVUdfRk9SQ0VfRklYRURfQ0hVTktTSVpFPXRydWU7Ci0KLSAgICAgICAgLyoqIE1hbmlmZXN0IGNvbnN0YW50OiBTdXBwcmVzcyBsZWFkaW5nIHdoaXRlc3BhY2UuCi0gICAgICAgICAqIFRoaXMgc2hvdWxkIGJlIHVzZWQgd2hlbiBub3JtYWxpemUtdG8tU0FYIGlzIGNhbGxlZCBmb3IgdGhlIGZpcnN0IGNodW5rIG9mIGEKLSAgICAgICAgICogbXVsdGktY2h1bmsgb3V0cHV0LCBvciBvbmUgZm9sbG93aW5nIHVuc3VwcHJlc3NlZCB3aGl0ZXNwYWNlIGluIGEgcHJldmlvdXMKLSAgICAgICAgICogY2h1bmsuCi0gICAgICAgICAqIEBzZWUgI3NlbmROb3JtYWxpemVkU0FYY2hhcmFjdGVycyhvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcixpbnQsaW50KQotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1VQUFJFU1NfTEVBRElOR19XUz0weDAxOwotCi0gICAgICAgIC8qKiBNYW5pZmVzdCBjb25zdGFudDogU3VwcHJlc3MgdHJhaWxpbmcgd2hpdGVzcGFjZS4KLSAgICAgICAgICogVGhpcyBzaG91bGQgYmUgdXNlZCB3aGVuIG5vcm1hbGl6ZS10by1TQVggaXMgY2FsbGVkIGZvciB0aGUgbGFzdCBjaHVuayBvZiBhCi0gICAgICAgICAqIG11bHRpLWNodW5rIG91dHB1dDsgaXQgbWF5IGhhdmUgdG8gYmUgb3InZWQgd2l0aCBTVVBQUkVTU19MRUFESU5HX1dTLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1VQUFJFU1NfVFJBSUxJTkdfV1M9MHgwMjsKLQotICAgICAgICAvKiogTWFuaWZlc3QgY29uc3RhbnQ6IFN1cHByZXNzIGJvdGggbGVhZGluZyBhbmQgdHJhaWxpbmcgd2hpdGVzcGFjZS4KLSAgICAgICAgICogVGhpcyBzaG91bGQgYmUgdXNlZCB3aGVuIG5vcm1hbGl6ZS10by1TQVggaXMgY2FsbGVkIGZvciBhIGNvbXBsZXRlIHN0cmluZy4KLSAgICAgICAgICogKEknbSBub3Qgd2lsZCBhYm91dCB0aGUgbmFtZSBvZiB0aGlzIG9uZS4gSWRlYXMgd2VsY29tZS4pCi0gICAgICAgICAqIEBzZWUgI3NlbmROb3JtYWxpemVkU0FYY2hhcmFjdGVycyhvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcixpbnQsaW50KQotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1VQUFJFU1NfQk9USAotICAgICAgICAgICAgICAgID0gU1VQUFJFU1NfTEVBRElOR19XUyB8IFNVUFBSRVNTX1RSQUlMSU5HX1dTOwotCi0gICAgICAgIC8qKiBNYW5pZmVzdCBjb25zdGFudDogQ2FycnkgdHJhaWxpbmcgd2hpdGVzcGFjZSBvZiBvbmUgY2h1bmsgYXMgbGVhZGluZwotICAgICAgICAgKiB3aGl0ZXNwYWNlIG9mIHRoZSBuZXh0IGNodW5rLiBVc2VkIGludGVybmFsbHk7IEkgZG9uJ3Qgc2VlIGFueSByZWFzb24KLSAgICAgICAgICogdG8gbWFrZSBpdCBwdWJsaWMgcmlnaHQgbm93LgotICAgICAgICAgKi8KLSAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IENBUlJZX1dTPTB4MDQ7Ci0KLSAgICAgICAgLyoqCi0gICAqIEZpZWxkIG1fY2h1bmtCaXRzIHNldHMgb3VyIGNodW5raW5nIHN0cmF0ZWd5LCBieSBzYXlpbmcgaG93IG1hbnkKLSAgICogYml0cyBvZiBpbmRleCBjYW4gYmUgdXNlZCB3aXRoaW4gYSBzaW5nbGUgY2h1bmsgYmVmb3JlIGZsb3dpbmcgb3ZlcgotICAgKiB0byB0aGUgbmV4dCBjaHVuay4gRm9yIGV4YW1wbGUsIGlmIG1fY2h1bmtiaXRzIGlzIHNldCB0byAxNSwgZWFjaAotICAgKiBjaHVuayBjYW4gY29udGFpbiB1cCB0byAyXjE1ICgzMkspIGNoYXJhY3RlcnMKLSAgICovCi0gIGludCBtX2NodW5rQml0cyA9IDE1OwotCi0gIC8qKgotICAgKiBGaWVsZCBtX21heENodW5rQml0cyBhZmZlY3RzIG91ciBjaHVuay1ncm93dGggc3RyYXRlZ3ksIGJ5IHNheWluZyB3aGF0Ci0gICAqIHRoZSBsYXJnZXN0IHBlcm1pc3NpYmxlIGNodW5rIHNpemUgaXMgaW4gdGhpcyBwYXJ0aWN1bGFyIEZhc3RTdHJpbmdCdWZmZXIKLSAgICogaGllcmFyY2h5LgotICAgKi8KLSAgaW50IG1fbWF4Q2h1bmtCaXRzID0gMTU7Ci0KLSAgLyoqCi0gICAqIEZpZWxkIG1fcmVjaHVua0JpdHMgYWZmZWN0cyBvdXIgY2h1bmstZ3Jvd3RoIHN0cmF0ZWd5LCBieSBzYXlpbmcgaG93Ci0gICAqIG1hbnkgY2h1bmtzIHNob3VsZCBiZSBhbGxvY2F0ZWQgYXQgb25lIHNpemUgYmVmb3JlIHdlIGVuY2Fwc3VsYXRlIHRoZW0KLSAgICogaW50byB0aGUgZmlyc3QgY2h1bmsgb2YgdGhlIG5leHQgc2l6ZSB1cC4gRm9yIGV4YW1wbGUsIGlmIG1fcmVjaHVua0JpdHMKLSAgICogaXMgc2V0IHRvIDMsIHRoZW4gYWZ0ZXIgOCBjaHVua3MgYXQgYSBnaXZlbiBzaXplIHdlIHdpbGwgcmVidW5kbGUKLSAgICogdGhlbSBhcyB0aGUgZmlyc3QgZWxlbWVudCBvZiBhIEZhc3RTdHJpbmdCdWZmZXIgdXNpbmcgYSBjaHVuayBzaXplCi0gICAqIDggdGltZXMgbGFyZ2VyIChjaHVua0JpdHMgc2hpZnRlZCBsZWZ0IHRocmVlIGJpdHMpLgotICAgKi8KLSAgaW50IG1fcmVidW5kbGVCaXRzID0gMjsKLQotICAvKioKLSAgICogRmllbGQgbV9jaHVua1NpemUgZXN0YWJsaXNoZXMgdGhlIG1heGltdW0gc2l6ZSBvZiBvbmUgY2h1bmsgb2YgdGhlIGFycmF5Ci0gICAqIGFzIDIqKmNodW5rYml0cyBjaGFyYWN0ZXJzLgotICAgKiAoV2hpY2ggbWF5IGFsc28gYmUgdGhlIG1pbmltdW0gc2l6ZSBpZiB3ZSBhcmVuJ3QgdHVuaW5nIGZvciBzdG9yYWdlKQotICAgKi8KLSAgaW50IG1fY2h1bmtTaXplOyAgLy8gPTE8PChtX2NodW5rQml0cy0xKTsKLQotICAvKioKLSAgICogRmllbGQgbV9jaHVua01hc2sgaXMgbV9jaHVua1NpemUtMSAtLSBpbiBvdGhlciB3b3JkcywgbV9jaHVua0JpdHMKLSAgICogd29ydGggb2YgbG93LW9yZGVyICcxJyBiaXRzLCB1c2VmdWwgZm9yIHNoaWZ0LWFuZC1tYXNrIGFkZHJlc3NpbmcKLSAgICogd2l0aGluIHRoZSBjaHVua3MuCi0gICAqLwotICBpbnQgbV9jaHVua01hc2s7ICAvLyA9bV9jaHVua1NpemUtMTsKLQotICAvKioKLSAgICogRmllbGQgbV9hcnJheSBob2xkcyB0aGUgc3RyaW5nIGJ1ZmZlcidzIHRleHQgY29udGVudHMsIHVzaW5nIGFuCi0gICAqIGFycmF5LW9mLWFycmF5cy4gTm90ZSB0aGF0IHRoaXMgYXJyYXksIGFuZCB0aGUgYXJyYXlzIGl0IGNvbnRhaW5zLCBtYXkgYmUKLSAgICogcmVhbGxvY2F0ZWQgd2hlbiBuZWNlc3NhcnkgaW4gb3JkZXIgdG8gYWxsb3cgdGhlIGJ1ZmZlciB0byBncm93OwotICAgKiByZWZlcmVuY2VzIHRvIHRoZW0gc2hvdWxkIGJlIGNvbnNpZGVyZWQgdG8gYmUgaW52YWxpZGF0ZWQgYWZ0ZXIgYW55Ci0gICAqIGFwcGVuZC4gSG93ZXZlciwgdGhlIG9ubHkgdGltZSB0aGVzZSBhcnJheXMgYXJlIGRpcmVjdGx5IGV4cG9zZWQKLSAgICogaXMgaW4gdGhlIHNlbmRTQVhjaGFyYWN0ZXJzIGNhbGwuCi0gICAqLwotICBjaGFyW11bXSBtX2FycmF5OwotCi0gIC8qKgotICAgKiBGaWVsZCBtX2xhc3RDaHVuayBpcyBhbiBpbmRleCBpbnRvIG1fYXJyYXlbXSwgcG9pbnRpbmcgdG8gdGhlIGxhc3QKLSAgICogY2h1bmsgb2YgdGhlIENodW5rZWQgQXJyYXkgY3VycmVudGx5IGluIHVzZS4gTm90ZSB0aGF0IGFkZGl0aW9uYWwKLSAgICogY2h1bmtzIG1heSBhY3R1YWxseSBiZSBhbGxvY2F0ZWQsIGVnIGlmIHRoZSBGYXN0U3RyaW5nQnVmZmVyIGhhZAotICAgKiBwcmV2aW91c2x5IGJlZW4gdHJ1bmNhdGVkIG9yIGlmIHNvbWVvbmUgaXNzdWVkIGFuIGVuc3VyZVNwYWNlIHJlcXVlc3QuCi0gICAqIDxwPgotICAgKiBUaGUgaW5zZXJ0aW9uIHBvaW50IGZvciBhcHBlbmQgb3BlcmF0aW9ucyBpcyBhZGRyZXNzZWQgYnkgdGhlIGNvbWJpbmF0aW9uCi0gICAqIG9mIG1fbGFzdENodW5rIGFuZCBtX2ZpcnN0RnJlZS4KLSAgICovCi0gIGludCBtX2xhc3RDaHVuayA9IDA7Ci0KLSAgLyoqCi0gICAqIEZpZWxkIG1fZmlyc3RGcmVlIGlzIGFuIGluZGV4IGludG8gbV9hcnJheVttX2xhc3RDaHVua11bXSwgcG9pbnRpbmcgdG8KLSAgICogdGhlIGZpcnN0IGNoYXJhY3RlciBpbiB0aGUgQ2h1bmtlZCBBcnJheSB3aGljaCBpcyBub3QgcGFydCBvZiB0aGUKLSAgICogRmFzdFN0cmluZ0J1ZmZlcidzIGN1cnJlbnQgY29udGVudC4gU2luY2UgbV9hcnJheVtdW10gaXMgemVyby1iYXNlZCwKLSAgICogdGhlIGxlbmd0aCBvZiB0aGF0IGNvbnRlbnQgY2FuIGJlIGNhbGN1bGF0ZWQgYXMKLSAgICogKG1fbGFzdENodW5rPDxtX2NodW5rQml0cykgKyBtX2ZpcnN0RnJlZQotICAgKi8KLSAgaW50IG1fZmlyc3RGcmVlID0gMDsKLQotICAvKioKLSAgICogRmllbGQgbV9pbm5lckZTQiwgd2hlbiBub24tbnVsbCwgaXMgYSBGYXN0U3RyaW5nQnVmZmVyIHdob3NlIHRvdGFsCi0gICAqIGxlbmd0aCBlcXVhbHMgbV9jaHVua1NpemUsIGFuZCB3aGljaCByZXBsYWNlcyBtX2FycmF5WzBdLiBUaGlzIGFsbG93cwotICAgKiBidWlsZGluZyBhIGhpZXJhcmNoeSBvZiBGYXN0U3RyaW5nQnVmZmVycywgd2hlcmUgZWFybHkgYXBwZW5kcyB1c2UKLSAgICogYSBzbWFsbGVyIGNodW5rU2l6ZSAoZm9yIGxlc3Mgd2FzdGVkIG1lbW9yeSBvdmVyaGVhZCkgYnV0IGxhdGVyCi0gICAqIG9uZXMgdXNlIGEgbGFyZ2VyIGNodW5rU2l6ZSAoZm9yIGxlc3MgaGVhcCBhY3Rpdml0eSBvdmVyaGVhZCkuCi0gICAqLwotICBGYXN0U3RyaW5nQnVmZmVyIG1faW5uZXJGU0IgPSBudWxsOwotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBGYXN0U3RyaW5nQnVmZmVyLCB3aXRoIGFsbG9jYXRpb24gcG9saWN5IGFzIHBlciBwYXJhbWV0ZXJzLgotICAgKiA8cD4KLSAgICogRm9yIGNvZGluZyBjb252ZW5pZW5jZSwgSSd2ZSBleHByZXNzZWQgYm90aCBhbGxvY2F0aW9uIHNpemVzIGluIHRlcm1zIG9mCi0gICAqIGEgbnVtYmVyIG9mIGJpdHMuIFRoYXQncyBuZWVkZWQgZm9yIHRoZSBmaW5hbCBzaXplIG9mIGEgY2h1bmssCi0gICAqIHRvIHBlcm1pdCBmYXN0IGFuZCBlZmZpY2llbnQgc2hpZnQtYW5kLW1hc2sgYWRkcmVzc2luZy4gSXQncyBsZXNzIGNyaXRpY2FsCi0gICAqIGZvciB0aGUgaW5pdGFsIHNpemUsIGFuZCBtYXkgYmUgcmVjb25zaWRlcmVkLgotICAgKiA8cD4KLSAgICogQW4gYWx0ZXJuYXRpdmUgd291bGQgYmUgdG8gYWNjZXB0IGludGVnZXIgc2l6ZXMgYW5kIHJvdW5kIHRvIHBvd2VycyBvZiB0d287Ci0gICAqIHRoYXQgcmVhbGx5IGRvZXNuJ3Qgc2VlbSB0byBidXkgdXMgbXVjaCwgaWYgYW55dGhpbmcuCi0gICAqCi0gICAqIEBwYXJhbSBpbml0Q2h1bmtCaXRzIExlbmd0aCBpbiBjaGFyYWN0ZXJzIG9mIHRoZSBpbml0aWFsIGFsbG9jYXRpb24KLSAgICogb2YgYSBjaHVuaywgZXhwcmVzc2VkIGluIGxvZy1iYXNlLTIuIChUaGF0IGlzLCAxMCBtZWFucyBhbGxvY2F0ZSAxMDI0Ci0gICAqIGNoYXJhY3RlcnMuKSBMYXRlciBjaHVua3Mgd2lsbCB1c2UgbGFyZ2VyIGFsbG9jYXRpb24gdW5pdHMsIHRvIHRyYWRlIG9mZgotICAgKiBhbGxvY2F0aW9uIHNwZWVkIG9mIGxhcmdlIGRvY3VtZW50IGFnYWluc3Qgc3RvcmFnZSBlZmZpY2llbmN5IG9mIHNtYWxsCi0gICAqIG9uZXMuCi0gICAqIEBwYXJhbSBtYXhDaHVua0JpdHMgTnVtYmVyIG9mIGNoYXJhY3Rlci1vZmZzZXQgYml0cyB0aGF0IHNob3VsZCBiZSB1c2VkIGZvcgotICAgKiBhZGRyZXNzaW5nIHdpdGhpbiBhIGNodW5rLiBNYXhpbXVtIGxlbmd0aCBvZiBhIGNodW5rIGlzIDJeY2h1bmtCaXRzCi0gICAqIGNoYXJhY3RlcnMuCi0gICAqIEBwYXJhbSByZWJ1bmRsZUJpdHMgTnVtYmVyIG9mIGNoYXJhY3Rlci1vZmZzZXQgYml0cyB0aGF0IGFkZHJlc3Npbmcgc2hvdWxkCi0gICAqIGFkdmFuY2UgYmVmb3JlIHdlIGF0dGVtcHQgdG8gdGFrZSBhIHN0ZXAgZnJvbSBpbml0Q2h1bmtCaXRzIHRvIG1heENodW5rQml0cwotICAgKi8KLSAgcHVibGljIEZhc3RTdHJpbmdCdWZmZXIoaW50IGluaXRDaHVua0JpdHMsIGludCBtYXhDaHVua0JpdHMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIGludCByZWJ1bmRsZUJpdHMpCi0gIHsKLSAgICBpZihERUJVR19GT1JDRV9JTklUX0JJVFMhPTApIGluaXRDaHVua0JpdHM9REVCVUdfRk9SQ0VfSU5JVF9CSVRTOwotCi0gICAgLy8gJVJFVklFVyUKLSAgICAvLyBTaG91bGQgdGhpcyBmb3JjZSB0byBsYXJnZXIgdmFsdWUsIG9yIHNtYWxsZXI/IFNtYWxsZXIgbGVzcyBlZmZpY2llbnQsIGJ1dCBpZgotICAgIC8vIHNvbWVvbmUgcmVxdWVzdGVkIHZhcmlhYmxlIG1vZGUgaXQncyBiZWNhdXNlIHRoZXkgY2FyZSBhYm91dCBzdG9yYWdlIHNwYWNlLgotICAgIC8vIE9uIHRoZSBvdGhlciBoYW5kLCBnaXZlbiB0aGUgb3RoZXIgY2hhbmdlcyBJJ20gbWFraW5nLCBvZGRzIGFyZSB0aGF0IHdlIHNob3VsZAotICAgIC8vIGFkb3B0IHRoZSBsYXJnZXIgc2l6ZS4gRGl0aGVyLCBkaXRoZXIsIGRpdGhlci4uLiBUaGlzIGlzIGp1c3Qgc3RvcGdhcCB3b3JrYXJvdW5kCi0gICAgLy8gYW55d2F5OyB3ZSBuZWVkIGEgcGVybWFuYW50IHNvbHV0aW9uLgotICAgIC8vCi0gICAgaWYoREVCVUdfRk9SQ0VfRklYRURfQ0hVTktTSVpFKSBtYXhDaHVua0JpdHM9aW5pdENodW5rQml0czsKLSAgICAvL2lmKERFQlVHX0ZPUkNFX0ZJWEVEX0NIVU5LU0laRSkgaW5pdENodW5rQml0cz1tYXhDaHVua0JpdHM7Ci0KLSAgICBtX2FycmF5ID0gbmV3IGNoYXJbMTZdW107Ci0KLSAgICAvLyBEb24ndCBiaXRlIG9mZiBtb3JlIHRoYW4gd2UncmUgcHJlcGFyZWQgdG8gc3dhbGxvdyEKLSAgICBpZiAoaW5pdENodW5rQml0cyA+IG1heENodW5rQml0cykKLSAgICAgIGluaXRDaHVua0JpdHMgPSBtYXhDaHVua0JpdHM7Ci0KLSAgICBtX2NodW5rQml0cyA9IGluaXRDaHVua0JpdHM7Ci0gICAgbV9tYXhDaHVua0JpdHMgPSBtYXhDaHVua0JpdHM7Ci0gICAgbV9yZWJ1bmRsZUJpdHMgPSByZWJ1bmRsZUJpdHM7Ci0gICAgbV9jaHVua1NpemUgPSAxIDw8IChpbml0Q2h1bmtCaXRzKTsKLSAgICBtX2NodW5rTWFzayA9IG1fY2h1bmtTaXplIC0gMTsKLSAgICBtX2FycmF5WzBdID0gbmV3IGNoYXJbbV9jaHVua1NpemVdOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhIEZhc3RTdHJpbmdCdWZmZXIsIHVzaW5nIGEgZGVmYXVsdCByZWJ1bmRsZUJpdHMgdmFsdWUuCi0gICAqCi0gICAqIE5FRURTRE9DIEBwYXJhbSBpbml0Q2h1bmtCaXRzCi0gICAqIE5FRURTRE9DIEBwYXJhbSBtYXhDaHVua0JpdHMKLSAgICovCi0gIHB1YmxpYyBGYXN0U3RyaW5nQnVmZmVyKGludCBpbml0Q2h1bmtCaXRzLCBpbnQgbWF4Q2h1bmtCaXRzKQotICB7Ci0gICAgdGhpcyhpbml0Q2h1bmtCaXRzLCBtYXhDaHVua0JpdHMsIDIpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhIEZhc3RTdHJpbmdCdWZmZXIsIHVzaW5nIGRlZmF1bHQgbWF4Q2h1bmtCaXRzIGFuZAotICAgKiByZWJ1bmRsZUJpdHMgdmFsdWVzLgotICAgKiA8cD4KLSAgICogSVNTVUU6IFNob3VsZCB0aGlzIGNhbGwgYXNzZXJ0IGluaXRpYWwgc2l6ZSwgb3IgZml4ZWQgc2l6ZT8KLSAgICogTm93IGNvbmZpZ3VyZWQgYXMgaW5pdGlhbCwgd2l0aCBhIGRlZmF1bHQgZm9yIGZpeGVkLgotICAgKgotICAgKiBORUVEU0RPQyBAcGFyYW0gaW5pdENodW5rQml0cwotICAgKi8KLSAgcHVibGljIEZhc3RTdHJpbmdCdWZmZXIoaW50IGluaXRDaHVua0JpdHMpCi0gIHsKLSAgICB0aGlzKGluaXRDaHVua0JpdHMsIDE1LCAyKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBGYXN0U3RyaW5nQnVmZmVyLCB1c2luZyBhIGRlZmF1bHQgYWxsb2NhdGlvbiBwb2xpY3kuCi0gICAqLwotICBwdWJsaWMgRmFzdFN0cmluZ0J1ZmZlcigpCi0gIHsKLQotICAgIC8vIDEwIGJpdHMgaXMgMUsuIDE1IGJpdHMgaXMgMzJLLiBSZW1lbWJlciB0aGF0IHRoZXNlIGFyZSBjaGFyYWN0ZXIKLSAgICAvLyBjb3VudHMsIHNvIGFjdHVhbCBtZW1vcnkgYWxsb2NhdGlvbiB1bml0IGlzIGRvdWJsZWQgZm9yIFVURi0xNiBjaGFycy4KLSAgICAvLwotICAgIC8vIEZvciByZWZlcmVuY2U6IEluIHRoZSBvcmlnaW5hbCBGYXN0U3RyaW5nQnVmZmVyLCB3ZSBzaW1wbHkKLSAgICAvLyBvdmVyYWxsb2NhdGVkIGJ5IGJsb2Nrc2l6ZSAoZGVmYXVsdCAxS0IpIG9uIGVhY2ggYnVmZmVyLWdyb3d0aC4KLSAgICB0aGlzKDEwLCAxNSwgMik7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBsZW5ndGggb2YgdGhlIGxpc3QuIFN5bm9ueW0gZm9yIGxlbmd0aCgpLgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyBpbiB0aGUgRmFzdFN0cmluZ0J1ZmZlcidzIGNvbnRlbnQuCi0gICAqLwotICBwdWJsaWMgZmluYWwgaW50IHNpemUoKQotICB7Ci0gICAgcmV0dXJuIChtX2xhc3RDaHVuayA8PCBtX2NodW5rQml0cykgKyBtX2ZpcnN0RnJlZTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGxlbmd0aCBvZiB0aGUgbGlzdC4gU3lub255bSBmb3Igc2l6ZSgpLgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyBpbiB0aGUgRmFzdFN0cmluZ0J1ZmZlcidzIGNvbnRlbnQuCi0gICAqLwotICBwdWJsaWMgZmluYWwgaW50IGxlbmd0aCgpCi0gIHsKLSAgICByZXR1cm4gKG1fbGFzdENodW5rIDw8IG1fY2h1bmtCaXRzKSArIG1fZmlyc3RGcmVlOwotICB9Ci0KLSAgLyoqCi0gICAqIERpc2NhcmQgdGhlIGNvbnRlbnQgb2YgdGhlIEZhc3RTdHJpbmdCdWZmZXIsIGFuZCBtb3N0IG9mIHRoZSBtZW1vcnkKLSAgICogdGhhdCB3YXMgYWxsb2NhdGVkIGJ5IGl0LCByZXN0b3JpbmcgdGhlIGluaXRpYWwgc3RhdGUuIE5vdGUgdGhhdCB0aGlzCi0gICAqIG1heSBldmVudHVhbGx5IGJlIGRpZmZlcmVudCBmcm9tIHNldExlbmd0aCgwKSwgd2hpY2ggc2VlLgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgcmVzZXQoKQotICB7Ci0KLSAgICBtX2xhc3RDaHVuayA9IDA7Ci0gICAgbV9maXJzdEZyZWUgPSAwOwotCi0gICAgLy8gUmVjb3ZlciB0aGUgb3JpZ2luYWwgY2h1bmsgc2l6ZQotICAgIEZhc3RTdHJpbmdCdWZmZXIgaW5uZXJtb3N0ID0gdGhpczsKLQotICAgIHdoaWxlIChpbm5lcm1vc3QubV9pbm5lckZTQiAhPSBudWxsKQotICAgIHsKLSAgICAgIGlubmVybW9zdCA9IGlubmVybW9zdC5tX2lubmVyRlNCOwotICAgIH0KLQotICAgIG1fY2h1bmtCaXRzID0gaW5uZXJtb3N0Lm1fY2h1bmtCaXRzOwotICAgIG1fY2h1bmtTaXplID0gaW5uZXJtb3N0Lm1fY2h1bmtTaXplOwotICAgIG1fY2h1bmtNYXNrID0gaW5uZXJtb3N0Lm1fY2h1bmtNYXNrOwotCi0gICAgLy8gRGlzY2FyZCB0aGUgaGllcmFyY2h5Ci0gICAgbV9pbm5lckZTQiA9IG51bGw7Ci0gICAgbV9hcnJheSA9IG5ldyBjaGFyWzE2XVswXTsKLSAgICBtX2FycmF5WzBdID0gbmV3IGNoYXJbbV9jaHVua1NpemVdOwotICB9Ci0KLSAgLyoqCi0gICAqIERpcmVjdGx5IHNldCBob3cgbXVjaCBvZiB0aGUgRmFzdFN0cmluZ0J1ZmZlcidzIHN0b3JhZ2UgaXMgdG8gYmUKLSAgICogY29uc2lkZXJlZCBwYXJ0IG9mIGl0cyBjb250ZW50LiBUaGlzIGlzIGEgZmFzdCBidXQgaGF6YXJkb3VzCi0gICAqIG9wZXJhdGlvbi4gSXQgaXMgbm90IHByb3RlY3RlZCBhZ2FpbnN0IG5lZ2F0aXZlIHZhbHVlcywgb3IgdmFsdWVzCi0gICAqIGdyZWF0ZXIgdGhhbiB0aGUgYW1vdW50IG9mIHN0b3JhZ2UgY3VycmVudGx5IGF2YWlsYWJsZS4uLiBhbmQgZXZlbgotICAgKiBpZiBhZGRpdGlvbmFsIHN0b3JhZ2UgZG9lcyBleGlzdCwgaXRzIGNvbnRlbnRzIGFyZSB1bnByZWRpY3RhYmxlLgotICAgKiBUaGUgb25seSBzYWZlIHVzZSBmb3Igb3VyIHNldExlbmd0aCgpIGlzIHRvIHRydW5jYXRlIHRoZSBGYXN0U3RyaW5nQnVmZmVyCi0gICAqIHRvIGEgc2hvcnRlciBzdHJpbmcuCi0gICAqCi0gICAqIEBwYXJhbSBsIE5ldyBsZW5ndGguIElmIGw8MCBvciBsPj1nZXRMZW5ndGgoKSwgdGhpcyBvcGVyYXRpb24gd2lsbAotICAgKiBub3QgcmVwb3J0IGFuIGVycm9yIGJ1dCBmdXR1cmUgb3BlcmF0aW9ucyB3aWxsIGFsbW9zdCBjZXJ0YWlubHkgZmFpbC4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHNldExlbmd0aChpbnQgbCkKLSAgewotICAgIG1fbGFzdENodW5rID0gbCA+Pj4gbV9jaHVua0JpdHM7Ci0KLSAgICBpZiAobV9sYXN0Q2h1bmsgPT0gMCAmJiBtX2lubmVyRlNCICE9IG51bGwpCi0gICAgewotICAgICAgLy8gUmVwbGFjZSB0aGlzIEZTQiB3aXRoIHRoZSBhcHByb3ByaWF0ZSBpbm5lciBGU0IsIHRydW5jYXRlZAotICAgICAgbV9pbm5lckZTQi5zZXRMZW5ndGgobCwgdGhpcyk7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBtX2ZpcnN0RnJlZSA9IGwgJiBtX2NodW5rTWFzazsKLQotICAgICAgICAgIC8vIFRoZXJlJ3MgYW4gZWRnZSBjYXNlIGlmIGwgaXMgYW4gZXhhY3QgbXVsdGlwbGUgb2YgbV9jaHVua0JpdHMsIHdoaWNoIHJpc2tzIGxlYXZpbmcKLSAgICAgICAgICAvLyB1cyBwb2ludGluZyBhdCB0aGUgc3RhcnQgb2YgYSBjaHVuayB3aGljaCBoYXMgbm90IHlldCBiZWVuIGFsbG9jYXRlZC4gUmF0aGVyIHRoYW4KLSAgICAgICAgICAvLyBwYXkgdGhlIGNvc3Qgb2YgZGVhbGluZyB3aXRoIHRoYXQgaW4gdGhlIGFwcGVuZCBsb29wcyAobW9yZSBzY2F0dGVyZWQgYW5kIG1vcmUKLSAgICAgICAgICAvLyBpbm5lci1sb29wKSwgd2UgY29ycmVjdCBpdCBoZXJlIGJ5IG1vdmluZyB0byB0aGUgc2FmZSBzaWRlIG9mIHRoYXQKLSAgICAgICAgICAvLyBsaW5lIC0tIGFzIHdlIHdvdWxkIGhhdmUgbGVmdCB0aGUgaW5kZXhlcyBoYWQgd2UgYXBwZW5kZWQgdXAgdG8gdGhhdCBwb2ludC4KLSAgICAgIGlmKG1fZmlyc3RGcmVlPT0wICYmIG1fbGFzdENodW5rPjApCi0gICAgICB7Ci0gICAgICAgIC0tbV9sYXN0Q2h1bms7Ci0gICAgICAgIG1fZmlyc3RGcmVlPW1fY2h1bmtTaXplOwotICAgICAgfQotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBTdWJyb3V0aW5lIGZvciB0aGUgcHVibGljIHNldExlbmd0aCgpIG1ldGhvZC4gRGVhbHMgd2l0aCB0aGUgZmFjdAotICAgKiB0aGF0IHRydW5jYXRpb24gbWF5IHJlcXVpcmUgcmVzdG9yaW5nIG9uZSBvZiB0aGUgaW5uZXJGU0JzCi0gICAqCi0gICAqIE5FRURTRE9DIEBwYXJhbSBsCi0gICAqIE5FRURTRE9DIEBwYXJhbSByb290RlNCCi0gICAqLwotICBwcml2YXRlIGZpbmFsIHZvaWQgc2V0TGVuZ3RoKGludCBsLCBGYXN0U3RyaW5nQnVmZmVyIHJvb3RGU0IpCi0gIHsKLQotICAgIG1fbGFzdENodW5rID0gbCA+Pj4gbV9jaHVua0JpdHM7Ci0KLSAgICBpZiAobV9sYXN0Q2h1bmsgPT0gMCAmJiBtX2lubmVyRlNCICE9IG51bGwpCi0gICAgewotICAgICAgbV9pbm5lckZTQi5zZXRMZW5ndGgobCwgcm9vdEZTQik7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0KLSAgICAgIC8vIFVuZG8gZW5jYXBzdWxhdGlvbiAtLSBwb3AgdGhlIGlubmVyRlNCIGRhdGEgYmFjayB1cCB0byByb290LgotICAgICAgLy8gSW5lZmZpY2llbnQsIGJ1dCBhdHRlbXB0cyB0byBrZWVwIHRoZSBjb2RlIHNpbXBsZS4KLSAgICAgIHJvb3RGU0IubV9jaHVua0JpdHMgPSBtX2NodW5rQml0czsKLSAgICAgIHJvb3RGU0IubV9tYXhDaHVua0JpdHMgPSBtX21heENodW5rQml0czsKLSAgICAgIHJvb3RGU0IubV9yZWJ1bmRsZUJpdHMgPSBtX3JlYnVuZGxlQml0czsKLSAgICAgIHJvb3RGU0IubV9jaHVua1NpemUgPSBtX2NodW5rU2l6ZTsKLSAgICAgIHJvb3RGU0IubV9jaHVua01hc2sgPSBtX2NodW5rTWFzazsKLSAgICAgIHJvb3RGU0IubV9hcnJheSA9IG1fYXJyYXk7Ci0gICAgICByb290RlNCLm1faW5uZXJGU0IgPSBtX2lubmVyRlNCOwotICAgICAgcm9vdEZTQi5tX2xhc3RDaHVuayA9IG1fbGFzdENodW5rOwotCi0gICAgICAvLyBGaW5hbGx5LCB0cnVuY2F0ZSB0aGlzIHN1Y2tlci4KLSAgICAgIHJvb3RGU0IubV9maXJzdEZyZWUgPSBsICYgbV9jaHVua01hc2s7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIE5vdGUgdGhhdCB0aGlzIG9wZXJhdGlvbiBoYXMgYmVlbiBzb21ld2hhdCBkZW9wdGltaXplZCBieSB0aGUgc2hpZnQgdG8gYQotICAgKiBjaHVua2VkIGFycmF5LCBhcyB0aGVyZSBpcyBubyBmYWN0b3J5IG1ldGhvZCB0byBwcm9kdWNlIGEgU3RyaW5nIG9iamVjdAotICAgKiBkaXJlY3RseSBmcm9tIGFuIGFycmF5IG9mIGFycmF5cyBhbmQgaGVuY2UgYSBkb3VibGUgY29weSBpcyBuZWVkZWQuCi0gICAqIEJ5IHVzaW5nIGVuc3VyZUNhcGFjaXR5IHdlIGhvcGUgdG8gbWluaW1pemUgdGhlIGhlYXAgb3ZlcmhlYWQgb2YgYnVpbGRpbmcKLSAgICogdGhlIGludGVybWVkaWF0ZSBTdHJpbmdCdWZmZXIuCi0gICAqIDxwPgotICAgKiAoSXQgcmVhbGx5IGlzIGEgcGl0eSB0aGF0IEphdmEgZGlkbid0IGRlc2lnbiBTdHJpbmcgYXMgYSBmaW5hbCBzdWJjbGFzcwotICAgKiBvZiBNdXRhYmxlU3RyaW5nLCByYXRoZXIgdGhhbiBoYXZpbmcgU3RyaW5nQnVmZmVyIGJlIGEgc2VwYXJhdGUgaGllcmFyY2h5LgotICAgKiBXZSdkIGF2b2lkIGEgPHN0cm9uZz5sb3Q8L3N0cm9uZz4gb2YgZG91YmxlLWJ1ZmZlcmluZy4pCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIGNvbnRlbnRzIG9mIHRoZSBGYXN0U3RyaW5nQnVmZmVyIGFzIGEgc3RhbmRhcmQgSmF2YSBzdHJpbmcuCi0gICAqLwotICBwdWJsaWMgZmluYWwgU3RyaW5nIHRvU3RyaW5nKCkKLSAgewotCi0gICAgaW50IGxlbmd0aCA9IChtX2xhc3RDaHVuayA8PCBtX2NodW5rQml0cykgKyBtX2ZpcnN0RnJlZTsKLQotICAgIHJldHVybiBnZXRTdHJpbmcobmV3IFN0cmluZ0J1ZmZlcihsZW5ndGgpLCAwLCAwLCBsZW5ndGgpLnRvU3RyaW5nKCk7Ci0gIH0KLQotICAvKioKLSAgICogQXBwZW5kIGEgc2luZ2xlIGNoYXJhY3RlciBvbnRvIHRoZSBGYXN0U3RyaW5nQnVmZmVyLCBncm93aW5nIHRoZQotICAgKiBzdG9yYWdlIGlmIG5lY2Vzc2FyeS4KLSAgICogPHA+Ci0gICAqIE5PVEUgVEhBVCBhZnRlciBjYWxsaW5nIGFwcGVuZCgpLCBwcmV2aW91c2x5IG9idGFpbmVkCi0gICAqIHJlZmVyZW5jZXMgdG8gbV9hcnJheVtdW10gbWF5IG5vIGxvbmdlciBiZSB2YWxpZC4uLi4KLSAgICogdGhvdWdoIGluIGZhY3QgdGhleSBzaG91bGQgYmUgaW4gdGhpcyBpbnN0YW5jZS4KLSAgICoKLSAgICogQHBhcmFtIHZhbHVlIGNoYXJhY3RlciB0byBiZSBhcHBlbmRlZC4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIGFwcGVuZChjaGFyIHZhbHVlKQotICB7Ci0KLSAgICBjaGFyW10gY2h1bms7Ci0KLSAgICAvLyBXZSBtYXkgaGF2ZSBwcmVhbGxvY2F0ZWQgY2h1bmtzLiBJZiBzbywgYWxsIGJ1dCBsYXN0IHNob3VsZAotICAgIC8vIGJlIGF0IGZ1bGwgc2l6ZS4KLSAgICBib29sZWFuIGxhc3RjaHVuayA9IChtX2xhc3RDaHVuayArIDEgPT0gbV9hcnJheS5sZW5ndGgpOwotCi0gICAgaWYgKG1fZmlyc3RGcmVlIDwgbV9jaHVua1NpemUpICAvLyBTaW1wbGlmaWVkIHRlc3Qgc2luZ2xlLWNoYXJhY3Rlci1maXRzCi0gICAgICBjaHVuayA9IG1fYXJyYXlbbV9sYXN0Q2h1bmtdOwotICAgIGVsc2UKLSAgICB7Ci0KLSAgICAgIC8vIEV4dGVuZCBhcnJheT8KLSAgICAgIGludCBpID0gbV9hcnJheS5sZW5ndGg7Ci0KLSAgICAgIGlmIChtX2xhc3RDaHVuayArIDEgPT0gaSkKLSAgICAgIHsKLSAgICAgICAgY2hhcltdW10gbmV3YXJyYXkgPSBuZXcgY2hhcltpICsgMTZdW107Ci0KLSAgICAgICAgU3lzdGVtLmFycmF5Y29weShtX2FycmF5LCAwLCBuZXdhcnJheSwgMCwgaSk7Ci0KLSAgICAgICAgbV9hcnJheSA9IG5ld2FycmF5OwotICAgICAgfQotCi0gICAgICAvLyBBZHZhbmNlIG9uZSBjaHVuawotICAgICAgY2h1bmsgPSBtX2FycmF5WysrbV9sYXN0Q2h1bmtdOwotCi0gICAgICBpZiAoY2h1bmsgPT0gbnVsbCkKLSAgICAgIHsKLQotICAgICAgICAvLyBIaWVyYXJjaGljYWwgZW5jYXBzdWxhdGlvbgotICAgICAgICBpZiAobV9sYXN0Q2h1bmsgPT0gMSA8PCBtX3JlYnVuZGxlQml0cwotICAgICAgICAgICAgICAgICYmIG1fY2h1bmtCaXRzIDwgbV9tYXhDaHVua0JpdHMpCi0gICAgICAgIHsKLQotICAgICAgICAgIC8vIFNob3VsZCBkbyBhbGwgdGhlIHdvcmsgb2YgYm90aCBlbmNhcHN1bGF0aW5nCi0gICAgICAgICAgLy8gZXhpc3RpbmcgZGF0YSBhbmQgZXN0YWJsaXNoaW5nIG5ldyBzaXplcy9vZmZzZXRzCi0gICAgICAgICAgbV9pbm5lckZTQiA9IG5ldyBGYXN0U3RyaW5nQnVmZmVyKHRoaXMpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gQWRkIGEgY2h1bmsuCi0gICAgICAgIGNodW5rID0gbV9hcnJheVttX2xhc3RDaHVua10gPSBuZXcgY2hhclttX2NodW5rU2l6ZV07Ci0gICAgICB9Ci0KLSAgICAgIG1fZmlyc3RGcmVlID0gMDsKLSAgICB9Ci0KLSAgICAvLyBTcGFjZSBleGlzdHMgaW4gdGhlIGNodW5rLiBBcHBlbmQgdGhlIGNoYXJhY3Rlci4KLSAgICBjaHVua1ttX2ZpcnN0RnJlZSsrXSA9IHZhbHVlOwotICB9Ci0KLSAgLyoqCi0gICAqIEFwcGVuZCB0aGUgY29udGVudHMgb2YgYSBTdHJpbmcgb250byB0aGUgRmFzdFN0cmluZ0J1ZmZlciwKLSAgICogZ3Jvd2luZyB0aGUgc3RvcmFnZSBpZiBuZWNlc3NhcnkuCi0gICAqIDxwPgotICAgKiBOT1RFIFRIQVQgYWZ0ZXIgY2FsbGluZyBhcHBlbmQoKSwgcHJldmlvdXNseSBvYnRhaW5lZAotICAgKiByZWZlcmVuY2VzIHRvIG1fYXJyYXlbXSBtYXkgbm8gbG9uZ2VyIGJlIHZhbGlkLgotICAgKgotICAgKiBAcGFyYW0gdmFsdWUgU3RyaW5nIHdob3NlIGNvbnRlbnRzIGFyZSB0byBiZSBhcHBlbmRlZC4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIGFwcGVuZChTdHJpbmcgdmFsdWUpCi0gIHsKLQotICAgIGlmICh2YWx1ZSA9PSBudWxsKQotICAgICAgcmV0dXJuOwotICAgIGludCBzdHJsZW4gPSB2YWx1ZS5sZW5ndGgoKTsKLQotICAgIGlmICgwID09IHN0cmxlbikKLSAgICAgIHJldHVybjsKLQotICAgIGludCBjb3B5ZnJvbSA9IDA7Ci0gICAgY2hhcltdIGNodW5rID0gbV9hcnJheVttX2xhc3RDaHVua107Ci0gICAgaW50IGF2YWlsYWJsZSA9IG1fY2h1bmtTaXplIC0gbV9maXJzdEZyZWU7Ci0KLSAgICAvLyBSZXBlYXQgd2hpbGUgZGF0YSByZW1haW5zIHRvIGJlIGNvcGllZAotICAgIHdoaWxlIChzdHJsZW4gPiAwKQotICAgIHsKLQotICAgICAgLy8gQ29weSB3aGF0IGZpdHMKLSAgICAgIGlmIChhdmFpbGFibGUgPiBzdHJsZW4pCi0gICAgICAgIGF2YWlsYWJsZSA9IHN0cmxlbjsKLQotICAgICAgdmFsdWUuZ2V0Q2hhcnMoY29weWZyb20sIGNvcHlmcm9tICsgYXZhaWxhYmxlLCBtX2FycmF5W21fbGFzdENodW5rXSwKLSAgICAgICAgICAgICAgICAgICAgIG1fZmlyc3RGcmVlKTsKLQotICAgICAgc3RybGVuIC09IGF2YWlsYWJsZTsKLSAgICAgIGNvcHlmcm9tICs9IGF2YWlsYWJsZTsKLQotICAgICAgLy8gSWYgdGhlcmUncyBtb3JlIGxlZnQsIGFsbG9jYXRlIGFub3RoZXIgY2h1bmsgYW5kIGNvbnRpbnVlCi0gICAgICBpZiAoc3RybGVuID4gMCkKLSAgICAgIHsKLQotICAgICAgICAvLyBFeHRlbmQgYXJyYXk/Ci0gICAgICAgIGludCBpID0gbV9hcnJheS5sZW5ndGg7Ci0KLSAgICAgICAgaWYgKG1fbGFzdENodW5rICsgMSA9PSBpKQotICAgICAgICB7Ci0gICAgICAgICAgY2hhcltdW10gbmV3YXJyYXkgPSBuZXcgY2hhcltpICsgMTZdW107Ci0KLSAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KG1fYXJyYXksIDAsIG5ld2FycmF5LCAwLCBpKTsKLQotICAgICAgICAgIG1fYXJyYXkgPSBuZXdhcnJheTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIEFkdmFuY2Ugb25lIGNodW5rCi0gICAgICAgIGNodW5rID0gbV9hcnJheVsrK21fbGFzdENodW5rXTsKLQotICAgICAgICBpZiAoY2h1bmsgPT0gbnVsbCkKLSAgICAgICAgewotCi0gICAgICAgICAgLy8gSGllcmFyY2hpY2FsIGVuY2Fwc3VsYXRpb24KLSAgICAgICAgICBpZiAobV9sYXN0Q2h1bmsgPT0gMSA8PCBtX3JlYnVuZGxlQml0cwotICAgICAgICAgICAgICAgICAgJiYgbV9jaHVua0JpdHMgPCBtX21heENodW5rQml0cykKLSAgICAgICAgICB7Ci0KLSAgICAgICAgICAgIC8vIFNob3VsZCBkbyBhbGwgdGhlIHdvcmsgb2YgYm90aCBlbmNhcHN1bGF0aW5nCi0gICAgICAgICAgICAvLyBleGlzdGluZyBkYXRhIGFuZCBlc3RhYmxpc2hpbmcgbmV3IHNpemVzL29mZnNldHMKLSAgICAgICAgICAgIG1faW5uZXJGU0IgPSBuZXcgRmFzdFN0cmluZ0J1ZmZlcih0aGlzKTsKLSAgICAgICAgICB9Ci0KLSAgICAgICAgICAvLyBBZGQgYSBjaHVuay4KLSAgICAgICAgICBjaHVuayA9IG1fYXJyYXlbbV9sYXN0Q2h1bmtdID0gbmV3IGNoYXJbbV9jaHVua1NpemVdOwotICAgICAgICB9Ci0KLSAgICAgICAgYXZhaWxhYmxlID0gbV9jaHVua1NpemU7Ci0gICAgICAgIG1fZmlyc3RGcmVlID0gMDsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICAvLyBBZGp1c3QgdGhlIGluc2VydCBwb2ludCBpbiB0aGUgbGFzdCBjaHVuaywgd2hlbiB3ZSd2ZSByZWFjaGVkIGl0LgotICAgIG1fZmlyc3RGcmVlICs9IGF2YWlsYWJsZTsKLSAgfQotCi0gIC8qKgotICAgKiBBcHBlbmQgdGhlIGNvbnRlbnRzIG9mIGEgU3RyaW5nQnVmZmVyIG9udG8gdGhlIEZhc3RTdHJpbmdCdWZmZXIsCi0gICAqIGdyb3dpbmcgdGhlIHN0b3JhZ2UgaWYgbmVjZXNzYXJ5LgotICAgKiA8cD4KLSAgICogTk9URSBUSEFUIGFmdGVyIGNhbGxpbmcgYXBwZW5kKCksIHByZXZpb3VzbHkgb2J0YWluZWQKLSAgICogcmVmZXJlbmNlcyB0byBtX2FycmF5W10gbWF5IG5vIGxvbmdlciBiZSB2YWxpZC4KLSAgICoKLSAgICogQHBhcmFtIHZhbHVlIFN0cmluZ0J1ZmZlciB3aG9zZSBjb250ZW50cyBhcmUgdG8gYmUgYXBwZW5kZWQuCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBhcHBlbmQoU3RyaW5nQnVmZmVyIHZhbHVlKQotICB7Ci0KLSAgICBpZiAodmFsdWUgPT0gbnVsbCkKLSAgICAgIHJldHVybjsKLSAgICBpbnQgc3RybGVuID0gdmFsdWUubGVuZ3RoKCk7Ci0KLSAgICBpZiAoMCA9PSBzdHJsZW4pCi0gICAgICByZXR1cm47Ci0KLSAgICBpbnQgY29weWZyb20gPSAwOwotICAgIGNoYXJbXSBjaHVuayA9IG1fYXJyYXlbbV9sYXN0Q2h1bmtdOwotICAgIGludCBhdmFpbGFibGUgPSBtX2NodW5rU2l6ZSAtIG1fZmlyc3RGcmVlOwotCi0gICAgLy8gUmVwZWF0IHdoaWxlIGRhdGEgcmVtYWlucyB0byBiZSBjb3BpZWQKLSAgICB3aGlsZSAoc3RybGVuID4gMCkKLSAgICB7Ci0KLSAgICAgIC8vIENvcHkgd2hhdCBmaXRzCi0gICAgICBpZiAoYXZhaWxhYmxlID4gc3RybGVuKQotICAgICAgICBhdmFpbGFibGUgPSBzdHJsZW47Ci0KLSAgICAgIHZhbHVlLmdldENoYXJzKGNvcHlmcm9tLCBjb3B5ZnJvbSArIGF2YWlsYWJsZSwgbV9hcnJheVttX2xhc3RDaHVua10sCi0gICAgICAgICAgICAgICAgICAgICBtX2ZpcnN0RnJlZSk7Ci0KLSAgICAgIHN0cmxlbiAtPSBhdmFpbGFibGU7Ci0gICAgICBjb3B5ZnJvbSArPSBhdmFpbGFibGU7Ci0KLSAgICAgIC8vIElmIHRoZXJlJ3MgbW9yZSBsZWZ0LCBhbGxvY2F0ZSBhbm90aGVyIGNodW5rIGFuZCBjb250aW51ZQotICAgICAgaWYgKHN0cmxlbiA+IDApCi0gICAgICB7Ci0KLSAgICAgICAgLy8gRXh0ZW5kIGFycmF5PwotICAgICAgICBpbnQgaSA9IG1fYXJyYXkubGVuZ3RoOwotCi0gICAgICAgIGlmIChtX2xhc3RDaHVuayArIDEgPT0gaSkKLSAgICAgICAgewotICAgICAgICAgIGNoYXJbXVtdIG5ld2FycmF5ID0gbmV3IGNoYXJbaSArIDE2XVtdOwotCi0gICAgICAgICAgU3lzdGVtLmFycmF5Y29weShtX2FycmF5LCAwLCBuZXdhcnJheSwgMCwgaSk7Ci0KLSAgICAgICAgICBtX2FycmF5ID0gbmV3YXJyYXk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBBZHZhbmNlIG9uZSBjaHVuawotICAgICAgICBjaHVuayA9IG1fYXJyYXlbKyttX2xhc3RDaHVua107Ci0KLSAgICAgICAgaWYgKGNodW5rID09IG51bGwpCi0gICAgICAgIHsKLQotICAgICAgICAgIC8vIEhpZXJhcmNoaWNhbCBlbmNhcHN1bGF0aW9uCi0gICAgICAgICAgaWYgKG1fbGFzdENodW5rID09IDEgPDwgbV9yZWJ1bmRsZUJpdHMKLSAgICAgICAgICAgICAgICAgICYmIG1fY2h1bmtCaXRzIDwgbV9tYXhDaHVua0JpdHMpCi0gICAgICAgICAgewotCi0gICAgICAgICAgICAvLyBTaG91bGQgZG8gYWxsIHRoZSB3b3JrIG9mIGJvdGggZW5jYXBzdWxhdGluZwotICAgICAgICAgICAgLy8gZXhpc3RpbmcgZGF0YSBhbmQgZXN0YWJsaXNoaW5nIG5ldyBzaXplcy9vZmZzZXRzCi0gICAgICAgICAgICBtX2lubmVyRlNCID0gbmV3IEZhc3RTdHJpbmdCdWZmZXIodGhpcyk7Ci0gICAgICAgICAgfQotCi0gICAgICAgICAgLy8gQWRkIGEgY2h1bmsuCi0gICAgICAgICAgY2h1bmsgPSBtX2FycmF5W21fbGFzdENodW5rXSA9IG5ldyBjaGFyW21fY2h1bmtTaXplXTsKLSAgICAgICAgfQotCi0gICAgICAgIGF2YWlsYWJsZSA9IG1fY2h1bmtTaXplOwotICAgICAgICBtX2ZpcnN0RnJlZSA9IDA7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgLy8gQWRqdXN0IHRoZSBpbnNlcnQgcG9pbnQgaW4gdGhlIGxhc3QgY2h1bmssIHdoZW4gd2UndmUgcmVhY2hlZCBpdC4KLSAgICBtX2ZpcnN0RnJlZSArPSBhdmFpbGFibGU7Ci0gIH0KLQotICAvKioKLSAgICogQXBwZW5kIHBhcnQgb2YgdGhlIGNvbnRlbnRzIG9mIGEgQ2hhcmFjdGVyIEFycmF5IG9udG8gdGhlCi0gICAqIEZhc3RTdHJpbmdCdWZmZXIsICBncm93aW5nIHRoZSBzdG9yYWdlIGlmIG5lY2Vzc2FyeS4KLSAgICogPHA+Ci0gICAqIE5PVEUgVEhBVCBhZnRlciBjYWxsaW5nIGFwcGVuZCgpLCBwcmV2aW91c2x5IG9idGFpbmVkCi0gICAqIHJlZmVyZW5jZXMgdG8gbV9hcnJheVtdIG1heSBubyBsb25nZXIgYmUgdmFsaWQuCi0gICAqCi0gICAqIEBwYXJhbSBjaGFycyBjaGFyYWN0ZXIgYXJyYXkgZnJvbSB3aGljaCBkYXRhIGlzIHRvIGJlIGNvcGllZAotICAgKiBAcGFyYW0gc3RhcnQgb2Zmc2V0IGluIGNoYXJzIG9mIGZpcnN0IGNoYXJhY3RlciB0byBiZSBjb3BpZWQsCi0gICAqIHplcm8tYmFzZWQuCi0gICAqIEBwYXJhbSBsZW5ndGggbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gYmUgY29waWVkCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBhcHBlbmQoY2hhcltdIGNoYXJzLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpCi0gIHsKLQotICAgIGludCBzdHJsZW4gPSBsZW5ndGg7Ci0KLSAgICBpZiAoMCA9PSBzdHJsZW4pCi0gICAgICByZXR1cm47Ci0KLSAgICBpbnQgY29weWZyb20gPSBzdGFydDsKLSAgICBjaGFyW10gY2h1bmsgPSBtX2FycmF5W21fbGFzdENodW5rXTsKLSAgICBpbnQgYXZhaWxhYmxlID0gbV9jaHVua1NpemUgLSBtX2ZpcnN0RnJlZTsKLQotICAgIC8vIFJlcGVhdCB3aGlsZSBkYXRhIHJlbWFpbnMgdG8gYmUgY29waWVkCi0gICAgd2hpbGUgKHN0cmxlbiA+IDApCi0gICAgewotCi0gICAgICAvLyBDb3B5IHdoYXQgZml0cwotICAgICAgaWYgKGF2YWlsYWJsZSA+IHN0cmxlbikKLSAgICAgICAgYXZhaWxhYmxlID0gc3RybGVuOwotCi0gICAgICBTeXN0ZW0uYXJyYXljb3B5KGNoYXJzLCBjb3B5ZnJvbSwgbV9hcnJheVttX2xhc3RDaHVua10sIG1fZmlyc3RGcmVlLAotICAgICAgICAgICAgICAgICAgICAgICBhdmFpbGFibGUpOwotCi0gICAgICBzdHJsZW4gLT0gYXZhaWxhYmxlOwotICAgICAgY29weWZyb20gKz0gYXZhaWxhYmxlOwotCi0gICAgICAvLyBJZiB0aGVyZSdzIG1vcmUgbGVmdCwgYWxsb2NhdGUgYW5vdGhlciBjaHVuayBhbmQgY29udGludWUKLSAgICAgIGlmIChzdHJsZW4gPiAwKQotICAgICAgewotCi0gICAgICAgIC8vIEV4dGVuZCBhcnJheT8KLSAgICAgICAgaW50IGkgPSBtX2FycmF5Lmxlbmd0aDsKLQotICAgICAgICBpZiAobV9sYXN0Q2h1bmsgKyAxID09IGkpCi0gICAgICAgIHsKLSAgICAgICAgICBjaGFyW11bXSBuZXdhcnJheSA9IG5ldyBjaGFyW2kgKyAxNl1bXTsKLQotICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkobV9hcnJheSwgMCwgbmV3YXJyYXksIDAsIGkpOwotCi0gICAgICAgICAgbV9hcnJheSA9IG5ld2FycmF5OwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gQWR2YW5jZSBvbmUgY2h1bmsKLSAgICAgICAgY2h1bmsgPSBtX2FycmF5WysrbV9sYXN0Q2h1bmtdOwotCi0gICAgICAgIGlmIChjaHVuayA9PSBudWxsKQotICAgICAgICB7Ci0KLSAgICAgICAgICAvLyBIaWVyYXJjaGljYWwgZW5jYXBzdWxhdGlvbgotICAgICAgICAgIGlmIChtX2xhc3RDaHVuayA9PSAxIDw8IG1fcmVidW5kbGVCaXRzCi0gICAgICAgICAgICAgICAgICAmJiBtX2NodW5rQml0cyA8IG1fbWF4Q2h1bmtCaXRzKQotICAgICAgICAgIHsKLQotICAgICAgICAgICAgLy8gU2hvdWxkIGRvIGFsbCB0aGUgd29yayBvZiBib3RoIGVuY2Fwc3VsYXRpbmcKLSAgICAgICAgICAgIC8vIGV4aXN0aW5nIGRhdGEgYW5kIGVzdGFibGlzaGluZyBuZXcgc2l6ZXMvb2Zmc2V0cwotICAgICAgICAgICAgbV9pbm5lckZTQiA9IG5ldyBGYXN0U3RyaW5nQnVmZmVyKHRoaXMpOwotICAgICAgICAgIH0KLQotICAgICAgICAgIC8vIEFkZCBhIGNodW5rLgotICAgICAgICAgIGNodW5rID0gbV9hcnJheVttX2xhc3RDaHVua10gPSBuZXcgY2hhclttX2NodW5rU2l6ZV07Ci0gICAgICAgIH0KLQotICAgICAgICBhdmFpbGFibGUgPSBtX2NodW5rU2l6ZTsKLSAgICAgICAgbV9maXJzdEZyZWUgPSAwOwotICAgICAgfQotICAgIH0KLQotICAgIC8vIEFkanVzdCB0aGUgaW5zZXJ0IHBvaW50IGluIHRoZSBsYXN0IGNodW5rLCB3aGVuIHdlJ3ZlIHJlYWNoZWQgaXQuCi0gICAgbV9maXJzdEZyZWUgKz0gYXZhaWxhYmxlOwotICB9Ci0KLSAgLyoqCi0gICAqIEFwcGVuZCB0aGUgY29udGVudHMgb2YgYW5vdGhlciBGYXN0U3RyaW5nQnVmZmVyIG9udG8KLSAgICogdGhpcyBGYXN0U3RyaW5nQnVmZmVyLCBncm93aW5nIHRoZSBzdG9yYWdlIGlmIG5lY2Vzc2FyeS4KLSAgICogPHA+Ci0gICAqIE5PVEUgVEhBVCBhZnRlciBjYWxsaW5nIGFwcGVuZCgpLCBwcmV2aW91c2x5IG9idGFpbmVkCi0gICAqIHJlZmVyZW5jZXMgdG8gbV9hcnJheVtdIG1heSBubyBsb25nZXIgYmUgdmFsaWQuCi0gICAqCi0gICAqIEBwYXJhbSB2YWx1ZSBGYXN0U3RyaW5nQnVmZmVyIHdob3NlIGNvbnRlbnRzIGFyZQotICAgKiB0byBiZSBhcHBlbmRlZC4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIGFwcGVuZChGYXN0U3RyaW5nQnVmZmVyIHZhbHVlKQotICB7Ci0KLSAgICAvLyBDb21wbGljYXRpbmcgZmFjdG9yIGhlcmUgaXMgdGhhdCB0aGUgdHdvIGJ1ZmZlcnMgbWF5IHVzZQotICAgIC8vIGRpZmZlcmVudCBjaHVuayBzaXplcywgYW5kIGV2ZW4gaWYgdGhleSdyZSB0aGUgc2FtZSB3ZSdyZQotICAgIC8vIHByb2JhYmx5IG9uIGEgZGlmZmVyZW50IGFsaWdubWVudCBkdWUgdG8gcHJldmlvdXNseSBhcHBlbmRlZAotICAgIC8vIGRhdGEuIFdlIGhhdmUgdG8gd29yayB0aHJvdWdoIHRoZSBzb3VyY2UgaW4gYml0ZS1zaXplZCBjaHVua3MuCi0gICAgaWYgKHZhbHVlID09IG51bGwpCi0gICAgICByZXR1cm47Ci0gICAgaW50IHN0cmxlbiA9IHZhbHVlLmxlbmd0aCgpOwotCi0gICAgaWYgKDAgPT0gc3RybGVuKQotICAgICAgcmV0dXJuOwotCi0gICAgaW50IGNvcHlmcm9tID0gMDsKLSAgICBjaGFyW10gY2h1bmsgPSBtX2FycmF5W21fbGFzdENodW5rXTsKLSAgICBpbnQgYXZhaWxhYmxlID0gbV9jaHVua1NpemUgLSBtX2ZpcnN0RnJlZTsKLQotICAgIC8vIFJlcGVhdCB3aGlsZSBkYXRhIHJlbWFpbnMgdG8gYmUgY29waWVkCi0gICAgd2hpbGUgKHN0cmxlbiA+IDApCi0gICAgewotCi0gICAgICAvLyBDb3B5IHdoYXQgZml0cwotICAgICAgaWYgKGF2YWlsYWJsZSA+IHN0cmxlbikKLSAgICAgICAgYXZhaWxhYmxlID0gc3RybGVuOwotCi0gICAgICBpbnQgc291cmNlY2h1bmsgPSAoY29weWZyb20gKyB2YWx1ZS5tX2NodW5rU2l6ZSAtIDEpCi0gICAgICAgICAgICAgICAgICAgICAgICA+Pj4gdmFsdWUubV9jaHVua0JpdHM7Ci0gICAgICBpbnQgc291cmNlY29sdW1uID0gY29weWZyb20gJiB2YWx1ZS5tX2NodW5rTWFzazsKLSAgICAgIGludCBydW5sZW5ndGggPSB2YWx1ZS5tX2NodW5rU2l6ZSAtIHNvdXJjZWNvbHVtbjsKLQotICAgICAgaWYgKHJ1bmxlbmd0aCA+IGF2YWlsYWJsZSkKLSAgICAgICAgcnVubGVuZ3RoID0gYXZhaWxhYmxlOwotCi0gICAgICBTeXN0ZW0uYXJyYXljb3B5KHZhbHVlLm1fYXJyYXlbc291cmNlY2h1bmtdLCBzb3VyY2Vjb2x1bW4sCi0gICAgICAgICAgICAgICAgICAgICAgIG1fYXJyYXlbbV9sYXN0Q2h1bmtdLCBtX2ZpcnN0RnJlZSwgcnVubGVuZ3RoKTsKLQotICAgICAgaWYgKHJ1bmxlbmd0aCAhPSBhdmFpbGFibGUpCi0gICAgICAgIFN5c3RlbS5hcnJheWNvcHkodmFsdWUubV9hcnJheVtzb3VyY2VjaHVuayArIDFdLCAwLAotICAgICAgICAgICAgICAgICAgICAgICAgIG1fYXJyYXlbbV9sYXN0Q2h1bmtdLCBtX2ZpcnN0RnJlZSArIHJ1bmxlbmd0aCwKLSAgICAgICAgICAgICAgICAgICAgICAgICBhdmFpbGFibGUgLSBydW5sZW5ndGgpOwotCi0gICAgICBzdHJsZW4gLT0gYXZhaWxhYmxlOwotICAgICAgY29weWZyb20gKz0gYXZhaWxhYmxlOwotCi0gICAgICAvLyBJZiB0aGVyZSdzIG1vcmUgbGVmdCwgYWxsb2NhdGUgYW5vdGhlciBjaHVuayBhbmQgY29udGludWUKLSAgICAgIGlmIChzdHJsZW4gPiAwKQotICAgICAgewotCi0gICAgICAgIC8vIEV4dGVuZCBhcnJheT8KLSAgICAgICAgaW50IGkgPSBtX2FycmF5Lmxlbmd0aDsKLQotICAgICAgICBpZiAobV9sYXN0Q2h1bmsgKyAxID09IGkpCi0gICAgICAgIHsKLSAgICAgICAgICBjaGFyW11bXSBuZXdhcnJheSA9IG5ldyBjaGFyW2kgKyAxNl1bXTsKLQotICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkobV9hcnJheSwgMCwgbmV3YXJyYXksIDAsIGkpOwotCi0gICAgICAgICAgbV9hcnJheSA9IG5ld2FycmF5OwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gQWR2YW5jZSBvbmUgY2h1bmsKLSAgICAgICAgY2h1bmsgPSBtX2FycmF5WysrbV9sYXN0Q2h1bmtdOwotCi0gICAgICAgIGlmIChjaHVuayA9PSBudWxsKQotICAgICAgICB7Ci0KLSAgICAgICAgICAvLyBIaWVyYXJjaGljYWwgZW5jYXBzdWxhdGlvbgotICAgICAgICAgIGlmIChtX2xhc3RDaHVuayA9PSAxIDw8IG1fcmVidW5kbGVCaXRzCi0gICAgICAgICAgICAgICAgICAmJiBtX2NodW5rQml0cyA8IG1fbWF4Q2h1bmtCaXRzKQotICAgICAgICAgIHsKLQotICAgICAgICAgICAgLy8gU2hvdWxkIGRvIGFsbCB0aGUgd29yayBvZiBib3RoIGVuY2Fwc3VsYXRpbmcKLSAgICAgICAgICAgIC8vIGV4aXN0aW5nIGRhdGEgYW5kIGVzdGFibGlzaGluZyBuZXcgc2l6ZXMvb2Zmc2V0cwotICAgICAgICAgICAgbV9pbm5lckZTQiA9IG5ldyBGYXN0U3RyaW5nQnVmZmVyKHRoaXMpOwotICAgICAgICAgIH0KLQotICAgICAgICAgIC8vIEFkZCBhIGNodW5rLgotICAgICAgICAgIGNodW5rID0gbV9hcnJheVttX2xhc3RDaHVua10gPSBuZXcgY2hhclttX2NodW5rU2l6ZV07Ci0gICAgICAgIH0KLQotICAgICAgICBhdmFpbGFibGUgPSBtX2NodW5rU2l6ZTsKLSAgICAgICAgbV9maXJzdEZyZWUgPSAwOwotICAgICAgfQotICAgIH0KLQotICAgIC8vIEFkanVzdCB0aGUgaW5zZXJ0IHBvaW50IGluIHRoZSBsYXN0IGNodW5rLCB3aGVuIHdlJ3ZlIHJlYWNoZWQgaXQuCi0gICAgbV9maXJzdEZyZWUgKz0gYXZhaWxhYmxlOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgc3BlY2lmaWVkIHJhbmdlIG9mIGNoYXJhY3RlcnMgYXJlIGFsbCB3aGl0ZXNwYWNlLAotICAgKiBhcyBkZWZpbmVkIGJ5IFhNTENoYXJhY3RlclJlY29nbml6ZXIuCi0gICAqIDxwPgotICAgKiBDVVJSRU5UTFkgRE9FUyBOT1QgQ0hFQ0sgRk9SIE9VVC1PRi1SQU5HRS4KLSAgICoKLSAgICogQHBhcmFtIHN0YXJ0IE9mZnNldCBvZiBmaXJzdCBjaGFyYWN0ZXIgaW4gdGhlIHJhbmdlLgotICAgKiBAcGFyYW0gbGVuZ3RoIE51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHNlbmQuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBpc1doaXRlc3BhY2UoaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKQotICB7Ci0KLSAgICBpbnQgc291cmNlY2h1bmsgPSBzdGFydCA+Pj4gbV9jaHVua0JpdHM7Ci0gICAgaW50IHNvdXJjZWNvbHVtbiA9IHN0YXJ0ICYgbV9jaHVua01hc2s7Ci0gICAgaW50IGF2YWlsYWJsZSA9IG1fY2h1bmtTaXplIC0gc291cmNlY29sdW1uOwotICAgIGJvb2xlYW4gY2h1bmtPSzsKLQotICAgIHdoaWxlIChsZW5ndGggPiAwKQotICAgIHsKLSAgICAgIGludCBydW5sZW5ndGggPSAobGVuZ3RoIDw9IGF2YWlsYWJsZSkgPyBsZW5ndGggOiBhdmFpbGFibGU7Ci0KLSAgICAgIGlmIChzb3VyY2VjaHVuayA9PSAwICYmIG1faW5uZXJGU0IgIT0gbnVsbCkKLSAgICAgICAgY2h1bmtPSyA9IG1faW5uZXJGU0IuaXNXaGl0ZXNwYWNlKHNvdXJjZWNvbHVtbiwgcnVubGVuZ3RoKTsKLSAgICAgIGVsc2UKLSAgICAgICAgY2h1bmtPSyA9IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuWE1MQ2hhcmFjdGVyUmVjb2duaXplci5pc1doaXRlU3BhY2UoCi0gICAgICAgICAgbV9hcnJheVtzb3VyY2VjaHVua10sIHNvdXJjZWNvbHVtbiwgcnVubGVuZ3RoKTsKLQotICAgICAgaWYgKCFjaHVua09LKQotICAgICAgICByZXR1cm4gZmFsc2U7Ci0KLSAgICAgIGxlbmd0aCAtPSBydW5sZW5ndGg7Ci0KLSAgICAgICsrc291cmNlY2h1bms7Ci0KLSAgICAgIHNvdXJjZWNvbHVtbiA9IDA7Ci0gICAgICBhdmFpbGFibGUgPSBtX2NodW5rU2l6ZTsKLSAgICB9Ci0KLSAgICByZXR1cm4gdHJ1ZTsKLSAgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gc3RhcnQgT2Zmc2V0IG9mIGZpcnN0IGNoYXJhY3RlciBpbiB0aGUgcmFuZ2UuCi0gICAqIEBwYXJhbSBsZW5ndGggTnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gc2VuZC4KLSAgICogQHJldHVybiBhIG5ldyBTdHJpbmcgb2JqZWN0IGluaXRpYWxpemVkIGZyb20gdGhlIHNwZWNpZmllZCByYW5nZSBvZgotICAgKiBjaGFyYWN0ZXJzLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRTdHJpbmcoaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKQotICB7Ci0gICAgaW50IHN0YXJ0Q29sdW1uID0gc3RhcnQgJiBtX2NodW5rTWFzazsKLSAgICBpbnQgc3RhcnRDaHVuayA9IHN0YXJ0ID4+PiBtX2NodW5rQml0czsKLSAgICBpZiAoc3RhcnRDb2x1bW4gKyBsZW5ndGggPCBtX2NodW5rTWFzayAmJiBtX2lubmVyRlNCID09IG51bGwpIHsKLSAgICAgIHJldHVybiBnZXRPbmVDaHVua1N0cmluZyhzdGFydENodW5rLCBzdGFydENvbHVtbiwgbGVuZ3RoKTsKLSAgICB9Ci0gICAgcmV0dXJuIGdldFN0cmluZyhuZXcgU3RyaW5nQnVmZmVyKGxlbmd0aCksIHN0YXJ0Q2h1bmssIHN0YXJ0Q29sdW1uLAotICAgICAgICAgICAgICAgICAgICAgbGVuZ3RoKS50b1N0cmluZygpOwotICB9Ci0KLSAgcHJvdGVjdGVkIFN0cmluZyBnZXRPbmVDaHVua1N0cmluZyhpbnQgc3RhcnRDaHVuaywgaW50IHN0YXJ0Q29sdW1uLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBsZW5ndGgpIHsKLSAgICByZXR1cm4gbmV3IFN0cmluZyhtX2FycmF5W3N0YXJ0Q2h1bmtdLCBzdGFydENvbHVtbiwgbGVuZ3RoKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gc2IgU3RyaW5nQnVmZmVyIHRvIGJlIGFwcGVuZGVkIHRvCi0gICAqIEBwYXJhbSBzdGFydCBPZmZzZXQgb2YgZmlyc3QgY2hhcmFjdGVyIGluIHRoZSByYW5nZS4KLSAgICogQHBhcmFtIGxlbmd0aCBOdW1iZXIgb2YgY2hhcmFjdGVycyB0byBzZW5kLgotICAgKiBAcmV0dXJuIHNiIHdpdGggdGhlIHJlcXVlc3RlZCB0ZXh0IGFwcGVuZGVkIHRvIGl0Ci0gICAqLwotICBTdHJpbmdCdWZmZXIgZ2V0U3RyaW5nKFN0cmluZ0J1ZmZlciBzYiwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKQotICB7Ci0gICAgcmV0dXJuIGdldFN0cmluZyhzYiwgc3RhcnQgPj4+IG1fY2h1bmtCaXRzLCBzdGFydCAmIG1fY2h1bmtNYXNrLCBsZW5ndGgpOwotICB9Ci0KLSAgLyoqCi0gICAqIEludGVybmFsIHN1cHBvcnQgZm9yIHRvU3RyaW5nKCkgYW5kIGdldFN0cmluZygpLgotICAgKiBQTEVBU0UgTk9URSBTSUdOQVRVUkUgQ0hBTkdFIGZyb20gZWFybGllciB2ZXJzaW9uczsgaXQgbm93IGFwcGVuZHMgaW50bwotICAgKiBhbmQgcmV0dXJucyBhIFN0cmluZ0J1ZmZlciBzdXBwbGllZCBieSB0aGUgY2FsbGVyLiBUaGlzIHNpbXBsaWZpZXMKLSAgICogbV9pbm5lckZTQiBzdXBwb3J0LgotICAgKiA8cD4KLSAgICogTm90ZSB0aGF0IHRoaXMgb3BlcmF0aW9uIGhhcyBiZWVuIHNvbWV3aGF0IGRlb3B0aW1pemVkIGJ5IHRoZSBzaGlmdCB0byBhCi0gICAqIGNodW5rZWQgYXJyYXksIGFzIHRoZXJlIGlzIG5vIGZhY3RvcnkgbWV0aG9kIHRvIHByb2R1Y2UgYSBTdHJpbmcgb2JqZWN0Ci0gICAqIGRpcmVjdGx5IGZyb20gYW4gYXJyYXkgb2YgYXJyYXlzIGFuZCBoZW5jZSBhIGRvdWJsZSBjb3B5IGlzIG5lZWRlZC4KLSAgICogQnkgcHJlc2V0dGluZyBsZW5ndGggd2UgaG9wZSB0byBtaW5pbWl6ZSB0aGUgaGVhcCBvdmVyaGVhZCBvZiBidWlsZGluZwotICAgKiB0aGUgaW50ZXJtZWRpYXRlIFN0cmluZ0J1ZmZlci4KLSAgICogPHA+Ci0gICAqIChJdCByZWFsbHkgaXMgYSBwaXR5IHRoYXQgSmF2YSBkaWRuJ3QgZGVzaWduIFN0cmluZyBhcyBhIGZpbmFsIHN1YmNsYXNzCi0gICAqIG9mIE11dGFibGVTdHJpbmcsIHJhdGhlciB0aGFuIGhhdmluZyBTdHJpbmdCdWZmZXIgYmUgYSBzZXBhcmF0ZSBoaWVyYXJjaHkuCi0gICAqIFdlJ2QgYXZvaWQgYSA8c3Ryb25nPmxvdDwvc3Ryb25nPiBvZiBkb3VibGUtYnVmZmVyaW5nLikKLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHNiCi0gICAqIEBwYXJhbSBzdGFydENodW5rCi0gICAqIEBwYXJhbSBzdGFydENvbHVtbgotICAgKiBAcGFyYW0gbGVuZ3RoCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIGNvbnRlbnRzIG9mIHRoZSBGYXN0U3RyaW5nQnVmZmVyIGFzIGEgc3RhbmRhcmQgSmF2YSBzdHJpbmcuCi0gICAqLwotICBTdHJpbmdCdWZmZXIgZ2V0U3RyaW5nKFN0cmluZ0J1ZmZlciBzYiwgaW50IHN0YXJ0Q2h1bmssIGludCBzdGFydENvbHVtbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoKQotICB7Ci0KLSAgICBpbnQgc3RvcCA9IChzdGFydENodW5rIDw8IG1fY2h1bmtCaXRzKSArIHN0YXJ0Q29sdW1uICsgbGVuZ3RoOwotICAgIGludCBzdG9wQ2h1bmsgPSBzdG9wID4+PiBtX2NodW5rQml0czsKLSAgICBpbnQgc3RvcENvbHVtbiA9IHN0b3AgJiBtX2NodW5rTWFzazsKLQotICAgIC8vIEZhY3RvcmVkIG91dAotICAgIC8vU3RyaW5nQnVmZmVyIHNiPW5ldyBTdHJpbmdCdWZmZXIobGVuZ3RoKTsKLSAgICBmb3IgKGludCBpID0gc3RhcnRDaHVuazsgaSA8IHN0b3BDaHVuazsgKytpKQotICAgIHsKLSAgICAgIGlmIChpID09IDAgJiYgbV9pbm5lckZTQiAhPSBudWxsKQotICAgICAgICBtX2lubmVyRlNCLmdldFN0cmluZyhzYiwgc3RhcnRDb2x1bW4sIG1fY2h1bmtTaXplIC0gc3RhcnRDb2x1bW4pOwotICAgICAgZWxzZQotICAgICAgICBzYi5hcHBlbmQobV9hcnJheVtpXSwgc3RhcnRDb2x1bW4sIG1fY2h1bmtTaXplIC0gc3RhcnRDb2x1bW4pOwotCi0gICAgICBzdGFydENvbHVtbiA9IDA7ICAvLyBhZnRlciBmaXJzdCBjaHVuawotICAgIH0KLQotICAgIGlmIChzdG9wQ2h1bmsgPT0gMCAmJiBtX2lubmVyRlNCICE9IG51bGwpCi0gICAgICBtX2lubmVyRlNCLmdldFN0cmluZyhzYiwgc3RhcnRDb2x1bW4sIHN0b3BDb2x1bW4gLSBzdGFydENvbHVtbik7Ci0gICAgZWxzZSBpZiAoc3RvcENvbHVtbiA+IHN0YXJ0Q29sdW1uKQotICAgICAgc2IuYXBwZW5kKG1fYXJyYXlbc3RvcENodW5rXSwgc3RhcnRDb2x1bW4sIHN0b3BDb2x1bW4gLSBzdGFydENvbHVtbik7Ci0KLSAgICByZXR1cm4gc2I7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IGEgc2luZ2xlIGNoYXJhY3RlciBmcm9tIHRoZSBzdHJpbmcgYnVmZmVyLgotICAgKgotICAgKgotICAgKiBAcGFyYW0gcG9zIGNoYXJhY3RlciBwb3NpdGlvbiByZXF1ZXN0ZWQuCi0gICAqIEByZXR1cm4gQSBjaGFyYWN0ZXIgZnJvbSB0aGUgcmVxdWVzdGVkIHBvc2l0aW9uLgotICAgKi8KLSAgcHVibGljIGNoYXIgY2hhckF0KGludCBwb3MpCi0gIHsKLSAgICBpbnQgc3RhcnRDaHVuayA9IHBvcyA+Pj4gbV9jaHVua0JpdHM7Ci0KLSAgICBpZiAoc3RhcnRDaHVuayA9PSAwICYmIG1faW5uZXJGU0IgIT0gbnVsbCkKLSAgICAgIHJldHVybiBtX2lubmVyRlNCLmNoYXJBdChwb3MgJiBtX2NodW5rTWFzayk7Ci0gICAgZWxzZQotICAgICAgcmV0dXJuIG1fYXJyYXlbc3RhcnRDaHVua11bcG9zICYgbV9jaHVua01hc2tdOwotICB9Ci0KLSAgLyoqCi0gICAqIFNlbmRzIHRoZSBzcGVjaWZpZWQgcmFuZ2Ugb2YgY2hhcmFjdGVycyBhcyBvbmUgb3IgbW9yZSBTQVggY2hhcmFjdGVycygpCi0gICAqIGV2ZW50cy4KLSAgICogTm90ZSB0aGF0IHRoZSBidWZmZXIgcmVmZXJlbmNlIHBhc3NlZCB0byB0aGUgQ29udGVudEhhbmRsZXIgbWF5IGJlCi0gICAqIGludmFsaWRhdGVkIGlmIHRoZSBGYXN0U3RyaW5nQnVmZmVyIGlzIGVkaXRlZDsgaXQncyB0aGUgdXNlcidzCi0gICAqIHJlc3BvbnNpYmlsaXR5IHRvIG1hbmFnZSBhY2Nlc3MgdG8gdGhlIEZhc3RTdHJpbmdCdWZmZXIgdG8gcHJldmVudCB0aGlzCi0gICAqIHByb2JsZW0gZnJvbSBhcmlzaW5nLgotICAgKiA8cD4KLSAgICogTm90ZSB0b28gdGhhdCB0aGVyZSBpcyBubyBwcm9taXNlIHRoYXQgdGhlIG91dHB1dCB3aWxsIGJlIHNlbnQgYXMgYQotICAgKiBzaW5nbGUgY2FsbC4gQXMgaXMgYWx3YXlzIHRydWUgaW4gU0FYLCBvbmUgbG9naWNhbCBzdHJpbmcgbWF5IGJlIHNwbGl0Ci0gICAqIGFjcm9zcyBtdWx0aXBsZSBibG9ja3Mgb2YgbWVtb3J5IGFuZCBoZW5jZSBkZWxpdmVyZWQgYXMgc2V2ZXJhbAotICAgKiBzdWNjZXNzaXZlIGV2ZW50cy4KLSAgICoKLSAgICogQHBhcmFtIGNoIFNBWCBDb250ZW50SGFuZGxlciBvYmplY3QgdG8gcmVjZWl2ZSB0aGUgZXZlbnQuCi0gICAqIEBwYXJhbSBzdGFydCBPZmZzZXQgb2YgZmlyc3QgY2hhcmFjdGVyIGluIHRoZSByYW5nZS4KLSAgICogQHBhcmFtIGxlbmd0aCBOdW1iZXIgb2YgY2hhcmFjdGVycyB0byBzZW5kLgotICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBtYXkgYmUgdGhyb3duIGJ5IGhhbmRsZXIncwotICAgKiBjaGFyYWN0ZXJzKCkgbWV0aG9kLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2VuZFNBWGNoYXJhY3RlcnMoCi0gICAgICAgICAgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIgY2gsIGludCBzdGFydCwgaW50IGxlbmd0aCkKLSAgICAgICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgaW50IHN0YXJ0Q2h1bmsgPSBzdGFydCA+Pj4gbV9jaHVua0JpdHM7Ci0gICAgaW50IHN0YXJ0Q29sdW1uID0gc3RhcnQgJiBtX2NodW5rTWFzazsKLSAgICBpZiAoc3RhcnRDb2x1bW4gKyBsZW5ndGggPCBtX2NodW5rTWFzayAmJiBtX2lubmVyRlNCID09IG51bGwpIHsKLSAgICAgICAgY2guY2hhcmFjdGVycyhtX2FycmF5W3N0YXJ0Q2h1bmtdLCBzdGFydENvbHVtbiwgbGVuZ3RoKTsKLSAgICAgICAgcmV0dXJuOwotICAgIH0KLQotICAgIGludCBzdG9wID0gc3RhcnQgKyBsZW5ndGg7Ci0gICAgaW50IHN0b3BDaHVuayA9IHN0b3AgPj4+IG1fY2h1bmtCaXRzOwotICAgIGludCBzdG9wQ29sdW1uID0gc3RvcCAmIG1fY2h1bmtNYXNrOwotCi0gICAgZm9yIChpbnQgaSA9IHN0YXJ0Q2h1bms7IGkgPCBzdG9wQ2h1bms7ICsraSkKLSAgICB7Ci0gICAgICBpZiAoaSA9PSAwICYmIG1faW5uZXJGU0IgIT0gbnVsbCkKLSAgICAgICAgbV9pbm5lckZTQi5zZW5kU0FYY2hhcmFjdGVycyhjaCwgc3RhcnRDb2x1bW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbV9jaHVua1NpemUgLSBzdGFydENvbHVtbik7Ci0gICAgICBlbHNlCi0gICAgICAgIGNoLmNoYXJhY3RlcnMobV9hcnJheVtpXSwgc3RhcnRDb2x1bW4sIG1fY2h1bmtTaXplIC0gc3RhcnRDb2x1bW4pOwotCi0gICAgICBzdGFydENvbHVtbiA9IDA7ICAvLyBhZnRlciBmaXJzdCBjaHVuawotICAgIH0KLQotICAgIC8vIExhc3QsIG9yIG9ubHksIGNodW5rCi0gICAgaWYgKHN0b3BDaHVuayA9PSAwICYmIG1faW5uZXJGU0IgIT0gbnVsbCkKLSAgICAgIG1faW5uZXJGU0Iuc2VuZFNBWGNoYXJhY3RlcnMoY2gsIHN0YXJ0Q29sdW1uLCBzdG9wQ29sdW1uIC0gc3RhcnRDb2x1bW4pOwotICAgIGVsc2UgaWYgKHN0b3BDb2x1bW4gPiBzdGFydENvbHVtbikKLSAgICB7Ci0gICAgICBjaC5jaGFyYWN0ZXJzKG1fYXJyYXlbc3RvcENodW5rXSwgc3RhcnRDb2x1bW4sCi0gICAgICAgICAgICAgICAgICAgIHN0b3BDb2x1bW4gLSBzdGFydENvbHVtbik7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFNlbmRzIHRoZSBzcGVjaWZpZWQgcmFuZ2Ugb2YgY2hhcmFjdGVycyBhcyBvbmUgb3IgbW9yZSBTQVggY2hhcmFjdGVycygpCi0gICAqIGV2ZW50cywgbm9ybWFsaXppbmcgdGhlIGNoYXJhY3RlcnMgYWNjb3JkaW5nIHRvIFhTTFQgcnVsZXMuCi0gICAqCi0gICAqIEBwYXJhbSBjaCBTQVggQ29udGVudEhhbmRsZXIgb2JqZWN0IHRvIHJlY2VpdmUgdGhlIGV2ZW50LgotICAgKiBAcGFyYW0gc3RhcnQgT2Zmc2V0IG9mIGZpcnN0IGNoYXJhY3RlciBpbiB0aGUgcmFuZ2UuCi0gICAqIEBwYXJhbSBsZW5ndGggTnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gc2VuZC4KLSAgICogQHJldHVybiBub3JtYWxpemF0aW9uIHN0YXR1cyB0byBhcHBseSB0byBuZXh0IGNodW5rIChiZWNhdXNlIHdlIG1heQotICAgKiBoYXZlIGJlZW4gY2FsbGVkIHJlY3Vyc2l2ZWx5IHRvIHByb2Nlc3MgYW4gaW5uZXIgRlNCKToKLSAgICogPGRsPgotICAgKiA8ZHQ+MDwvZHQ+Ci0gICAqIDxkZD5pZiB0aGlzIG91dHB1dCBkaWQgbm90IGVuZCBpbiByZXRhaW5lZCB3aGl0ZXNwYWNlLCBhbmQgdGh1cyB3aGl0ZXNwYWNlCi0gICAqIGF0IHRoZSBzdGFydCBvZiB0aGUgZm9sbG93aW5nIGNodW5rIChpZiBhbnkpIHNob3VsZCBiZSBjb252ZXJ0ZWQgdG8gYQotICAgKiBzaW5nbGUgc3BhY2UuCi0gICAqIDxkdD5TVVBQUkVTU19MRUFESU5HX1dTPC9kdD4KLSAgICogPGRkPmlmIHRoaXMgb3V0cHV0IGVuZGVkIGluIHJldGFpbmVkIHdoaXRlc3BhY2UsIGFuZCB0aHVzIHdoaXRlc3BhY2UKLSAgICogYXQgdGhlIHN0YXJ0IG9mIHRoZSBmb2xsb3dpbmcgY2h1bmsgKGlmIGFueSkgc2hvdWxkIGJlIGNvbXBsZXRlbHkKLSAgICogc3VwcHJlc3NlZC48L2RkPgotICAgKiA8L2RkPgotICAgKiA8L2RsPgotICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBtYXkgYmUgdGhyb3duIGJ5IGhhbmRsZXIncwotICAgKiBjaGFyYWN0ZXJzKCkgbWV0aG9kLgotICAgKi8KLSAgcHVibGljIGludCBzZW5kTm9ybWFsaXplZFNBWGNoYXJhY3RlcnMoCi0gICAgICAgICAgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIgY2gsIGludCBzdGFydCwgaW50IGxlbmd0aCkKLSAgICAgICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgICAgICAvLyBUaGlzIGNhbGwgYWx3YXlzIHN0YXJ0cyBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZQotICAgIC8vIHN0cmluZyBiZWluZyB3cml0dGVuIG91dCwgZWl0aGVyIGJlY2F1c2UgaXQgd2FzIGNhbGxlZCBkaXJlY3RseSBvcgotICAgIC8vIGJlY2F1c2UgaXQgd2FzIGFuIG1faW5uZXJGU0IgcmVjdXJzaW9uLiBUaGlzIGlzIGltcG9ydGFudCBzaW5jZQotICAgICAgICAvLyBpdCBnaXZlcyB1cyBhIHdlbGwta25vd24gaW5pdGlhbCBzdGF0ZSBmb3IgdGhpcyBmbGFnOgotICAgICAgICBpbnQgc3RhdGVGb3JOZXh0Q2h1bms9U1VQUFJFU1NfTEVBRElOR19XUzsKLQotICAgIGludCBzdG9wID0gc3RhcnQgKyBsZW5ndGg7Ci0gICAgaW50IHN0YXJ0Q2h1bmsgPSBzdGFydCA+Pj4gbV9jaHVua0JpdHM7Ci0gICAgaW50IHN0YXJ0Q29sdW1uID0gc3RhcnQgJiBtX2NodW5rTWFzazsKLSAgICBpbnQgc3RvcENodW5rID0gc3RvcCA+Pj4gbV9jaHVua0JpdHM7Ci0gICAgaW50IHN0b3BDb2x1bW4gPSBzdG9wICYgbV9jaHVua01hc2s7Ci0KLSAgICBmb3IgKGludCBpID0gc3RhcnRDaHVuazsgaSA8IHN0b3BDaHVuazsgKytpKQotICAgIHsKLSAgICAgIGlmIChpID09IDAgJiYgbV9pbm5lckZTQiAhPSBudWxsKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0ZUZvck5leHRDaHVuaz0KLSAgICAgICAgbV9pbm5lckZTQi5zZW5kTm9ybWFsaXplZFNBWGNoYXJhY3RlcnMoY2gsIHN0YXJ0Q29sdW1uLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fY2h1bmtTaXplIC0gc3RhcnRDb2x1bW4pOwotICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0ZUZvck5leHRDaHVuaz0KLSAgICAgICAgc2VuZE5vcm1hbGl6ZWRTQVhjaGFyYWN0ZXJzKG1fYXJyYXlbaV0sIHN0YXJ0Q29sdW1uLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbV9jaHVua1NpemUgLSBzdGFydENvbHVtbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoLHN0YXRlRm9yTmV4dENodW5rKTsKLQotICAgICAgc3RhcnRDb2x1bW4gPSAwOyAgLy8gYWZ0ZXIgZmlyc3QgY2h1bmsKLSAgICB9Ci0KLSAgICAvLyBMYXN0LCBvciBvbmx5LCBjaHVuawotICAgIGlmIChzdG9wQ2h1bmsgPT0gMCAmJiBtX2lubmVyRlNCICE9IG51bGwpCi0gICAgICAgICAgICAgICAgICAgICAgICBzdGF0ZUZvck5leHRDaHVuaz0gLy8gJVJFVklFVyUgSXMgdGhpcyB1cGRhdGUgcmVhbGx5IG5lZWRlZD8KLSAgICAgIG1faW5uZXJGU0Iuc2VuZE5vcm1hbGl6ZWRTQVhjaGFyYWN0ZXJzKGNoLCBzdGFydENvbHVtbiwgc3RvcENvbHVtbiAtIHN0YXJ0Q29sdW1uKTsKLSAgICBlbHNlIGlmIChzdG9wQ29sdW1uID4gc3RhcnRDb2x1bW4pCi0gICAgewotICAgICAgICAgICAgICAgICAgICAgICAgc3RhdGVGb3JOZXh0Q2h1bms9IC8vICVSRVZJRVclIElzIHRoaXMgdXBkYXRlIHJlYWxseSBuZWVkZWQ/Ci0gICAgICBzZW5kTm9ybWFsaXplZFNBWGNoYXJhY3RlcnMobV9hcnJheVtzdG9wQ2h1bmtdLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0Q29sdW1uLCBzdG9wQ29sdW1uIC0gc3RhcnRDb2x1bW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2gsIHN0YXRlRm9yTmV4dENodW5rIHwgU1VQUFJFU1NfVFJBSUxJTkdfV1MpOwotICAgIH0KLSAgICAgICAgICAgICAgICByZXR1cm4gc3RhdGVGb3JOZXh0Q2h1bms7Ci0gIH0KLQotICBzdGF0aWMgZmluYWwgY2hhcltdIFNJTkdMRV9TUEFDRSA9IHsnICd9OwotCi0gIC8qKgotICAgKiBJbnRlcm5hbCBtZXRob2QgdG8gZGlyZWN0bHkgbm9ybWFsaXplIGFuZCBkaXNwYXRjaCB0aGUgY2hhcmFjdGVyIGFycmF5LgotICAgKiBUaGlzIHZlcnNpb24gaXMgYXdhcmUgb2YgdGhlIGZhY3QgdGhhdCBpdCBtYXkgYmUgY2FsbGVkIHNldmVyYWwgdGltZXMKLSAgICogaW4gc3VjY2Vzc2lvbiBpZiB0aGUgZGF0YSBpcyBtYWRlIHVwIG9mIG11bHRpcGxlICJjaHVua3MiLCBhbmQgdGh1cwotICAgKiBtdXN0IGFjdGl2ZWx5IG1hbmFnZSB0aGUgaGFuZGxpbmcgb2YgbGVhZGluZyBhbmQgdHJhaWxpbmcgd2hpdGVzcGFjZS4KLSAgICoKLSAgICogTm90ZTogVGhlIHJlY3Vyc2lvbiBpcyBkdWUgdG8gdGhlIHBvc3NpYmxlIHJlY3Vyc2lvbiBvZiBpbm5lciBGU0JzLgotICAgKgotICAgKiBAcGFyYW0gY2ggVGhlIGNoYXJhY3RlcnMgZnJvbSB0aGUgWE1MIGRvY3VtZW50LgotICAgKiBAcGFyYW0gc3RhcnQgVGhlIHN0YXJ0IHBvc2l0aW9uIGluIHRoZSBhcnJheS4KLSAgICogQHBhcmFtIGxlbmd0aCBUaGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gcmVhZCBmcm9tIHRoZSBhcnJheS4KLSAgICogQHBhcmFtIGhhbmRsZXIgU0FYIENvbnRlbnRIYW5kbGVyIG9iamVjdCB0byByZWNlaXZlIHRoZSBldmVudC4KLSAgICogQHBhcmFtIGVkZ2VUcmVhdG1lbnRGbGFncyBIb3cgbGVhZGluZy90cmFpbGluZyBzcGFjZXMgc2hvdWxkIGJlIGhhbmRsZWQuCi0gICAqIFRoaXMgaXMgYSBiaXRmaWVsZCBjb250aW5pbmcgdHdvIGZsYWdzLCBiaXR3aXNlLU9SZWQgdG9nZXRoZXI6Ci0gICAqIDxkbD4KLSAgICogPGR0PlNVUFBSRVNTX0xFQURJTkdfV1M8L2R0PgotICAgKiA8ZGQ+V2hlbiBmYWxzZSwgY2F1c2VzIGxlYWRpbmcgd2hpdGVzcGFjZSB0byBiZSBjb252ZXJ0ZWQgdG8gYSBzaW5nbGUKLSAgICogc3BhY2U7IHdoZW4gdHJ1ZSwgY2F1c2VzIGl0IHRvIGJlIGRpc2NhcmRlZCBlbnRpcmVseS4KLSAgICogU2hvdWxkIGJlIHNldCBUUlVFIGZvciB0aGUgZmlyc3QgY2h1bmssIGFuZCAoaW4gbXVsdGktY2h1bmsgb3V0cHV0KQotICAgKiB3aGVuZXZlciB0aGUgcHJldmlvdXMgY2h1bmsgZW5kZWQgaW4gcmV0YWluZWQgd2hpdGVzcGFjZS48L2RkPgotICAgKiA8ZHQ+U1VQUFJFU1NfVFJBSUxJTkdfV1M8L2R0PgotICAgKiA8ZGQ+V2hlbiBmYWxzZSwgY2F1c2VzIHRyYWlsaW5nIHdoaXRlc3BhY2UgdG8gYmUgY29udmVydGVkIHRvIGEgc2luZ2xlCi0gICAqIHNwYWNlOyB3aGVuIHRydWUsIGNhdXNlcyBpdCB0byBiZSBkaXNjYXJkZWQgZW50aXJlbHkuCi0gICAqIFNob3VsZCBiZSBzZXQgVFJVRSBmb3IgdGhlIGxhc3Qgb3Igb25seSBjaHVuay4KLSAgICogPC9kZD4KLSAgICogPC9kbD4KLSAgICogQHJldHVybiBub3JtYWxpemF0aW9uIHN0YXR1cywgYXMgaW4gdGhlIGVkZ2VUcmVhdG1lbnRGbGFncyBwYXJhbWV0ZXI6Ci0gICAqIDxkbD4KLSAgICogPGR0PjA8L2R0PgotICAgKiA8ZGQ+aWYgdGhpcyBvdXRwdXQgZGlkIG5vdCBlbmQgaW4gcmV0YWluZWQgd2hpdGVzcGFjZSwgYW5kIHRodXMgd2hpdGVzcGFjZQotICAgKiBhdCB0aGUgc3RhcnQgb2YgdGhlIGZvbGxvd2luZyBjaHVuayAoaWYgYW55KSBzaG91bGQgYmUgY29udmVydGVkIHRvIGEKLSAgICogc2luZ2xlIHNwYWNlLgotICAgKiA8ZHQ+U1VQUFJFU1NfTEVBRElOR19XUzwvZHQ+Ci0gICAqIDxkZD5pZiB0aGlzIG91dHB1dCBlbmRlZCBpbiByZXRhaW5lZCB3aGl0ZXNwYWNlLCBhbmQgdGh1cyB3aGl0ZXNwYWNlCi0gICAqIGF0IHRoZSBzdGFydCBvZiB0aGUgZm9sbG93aW5nIGNodW5rIChpZiBhbnkpIHNob3VsZCBiZSBjb21wbGV0ZWx5Ci0gICAqIHN1cHByZXNzZWQuPC9kZD4KLSAgICogPC9kZD4KLSAgICogPC9kbD4KLSAgICoKLSAgICoKLSAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAqLwotICBzdGF0aWMgaW50IHNlbmROb3JtYWxpemVkU0FYY2hhcmFjdGVycyhjaGFyIGNoW10sCi0gICAgICAgICAgICAgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoLAotICAgICAgICAgICAgIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyIGhhbmRsZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGVkZ2VUcmVhdG1lbnRGbGFncykKLSAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICAgYm9vbGVhbiBwcm9jZXNzaW5nTGVhZGluZ1doaXRlc3BhY2UgPQotICAgICAgICAgICAgICAgICAgICAgICAoKGVkZ2VUcmVhdG1lbnRGbGFncyAmIFNVUFBSRVNTX0xFQURJTkdfV1MpICE9IDApOwotICAgICBib29sZWFuIHNlZW5XaGl0ZXNwYWNlID0gKChlZGdlVHJlYXRtZW50RmxhZ3MgJiBDQVJSWV9XUykgIT0gMCk7Ci0gICAgIGJvb2xlYW4gc3VwcHJlc3NUcmFpbGluZ1doaXRlc3BhY2UgPQotICAgICAgICAgICAgICAgICAgICAgICAoKGVkZ2VUcmVhdG1lbnRGbGFncyAmIFNVUFBSRVNTX1RSQUlMSU5HX1dTKSAhPSAwKTsKLSAgICAgaW50IGN1cnJQb3MgPSBzdGFydDsKLSAgICAgaW50IGxpbWl0ID0gc3RhcnQrbGVuZ3RoOwotCi0gICAgIC8vIFN0cmlwIGFueSBsZWFkaW5nIHNwYWNlcyBmaXJzdCwgaWYgcmVxdWlyZWQKLSAgICAgaWYgKHByb2Nlc3NpbmdMZWFkaW5nV2hpdGVzcGFjZSkgewotICAgICAgICAgZm9yICg7IGN1cnJQb3MgPCBsaW1pdAotICAgICAgICAgICAgICAgICYmIFhNTENoYXJhY3RlclJlY29nbml6ZXIuaXNXaGl0ZVNwYWNlKGNoW2N1cnJQb3NdKTsKLSAgICAgICAgICAgICAgY3VyclBvcysrKSB7IH0KLQotICAgICAgICAgLy8gSWYgd2UndmUgb25seSBlbmNvdW50ZXJlZCBsZWFkaW5nIHNwYWNlcywgdGhlCi0gICAgICAgICAvLyBjdXJyZW50IHN0YXRlIHJlbWFpbnMgdW5jaGFuZ2VkCi0gICAgICAgICBpZiAoY3VyclBvcyA9PSBsaW1pdCkgewotICAgICAgICAgICAgIHJldHVybiBlZGdlVHJlYXRtZW50RmxhZ3M7Ci0gICAgICAgICB9Ci0gICAgIH0KLQotICAgICAvLyBJZiB3ZSBnZXQgaGVyZSwgdGhlcmUgYXJlIG5vIG1vcmUgbGVhZGluZyBzcGFjZXMgdG8gc3RyaXAKLSAgICAgd2hpbGUgKGN1cnJQb3MgPCBsaW1pdCkgewotICAgICAgICAgaW50IHN0YXJ0Tm9uV2hpdGVzcGFjZSA9IGN1cnJQb3M7Ci0KLSAgICAgICAgIC8vIEdyYWIgYSBjaHVuayBvZiBub24td2hpdGVzcGFjZSBjaGFyYWN0ZXJzCi0gICAgICAgICBmb3IgKDsgY3VyclBvcyA8IGxpbWl0Ci0gICAgICAgICAgICAgICAgJiYgIVhNTENoYXJhY3RlclJlY29nbml6ZXIuaXNXaGl0ZVNwYWNlKGNoW2N1cnJQb3NdKTsKLSAgICAgICAgICAgICAgY3VyclBvcysrKSB7IH0KLQotICAgICAgICAgLy8gTm9uLXdoaXRlc3BhY2Ugc2VlbiAtIGVtaXQgdGhlbSwgYWxvbmcgd2l0aCBhIHNpbmdsZQotICAgICAgICAgLy8gc3BhY2UgZm9yIGFueSBwcmVjZWRpbmcgd2hpdGVzcGFjZSBjaGFyYWN0ZXJzCi0gICAgICAgICBpZiAoc3RhcnROb25XaGl0ZXNwYWNlICE9IGN1cnJQb3MpIHsKLSAgICAgICAgICAgICBpZiAoc2VlbldoaXRlc3BhY2UpIHsKLSAgICAgICAgICAgICAgICAgaGFuZGxlci5jaGFyYWN0ZXJzKFNJTkdMRV9TUEFDRSwgMCwgMSk7Ci0gICAgICAgICAgICAgICAgIHNlZW5XaGl0ZXNwYWNlID0gZmFsc2U7Ci0gICAgICAgICAgICAgfQotICAgICAgICAgICAgIGhhbmRsZXIuY2hhcmFjdGVycyhjaCwgc3RhcnROb25XaGl0ZXNwYWNlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyUG9zIC0gc3RhcnROb25XaGl0ZXNwYWNlKTsKLSAgICAgICAgIH0KLQotICAgICAgICAgaW50IHN0YXJ0V2hpdGVzcGFjZSA9IGN1cnJQb3M7Ci0KLSAgICAgICAgIC8vIENvbnN1bWUgYW55IHdoaXRlc3BhY2UgY2hhcmFjdGVycwotICAgICAgICAgZm9yICg7IGN1cnJQb3MgPCBsaW1pdAotICAgICAgICAgICAgICAgICYmIFhNTENoYXJhY3RlclJlY29nbml6ZXIuaXNXaGl0ZVNwYWNlKGNoW2N1cnJQb3NdKTsKLSAgICAgICAgICAgICAgY3VyclBvcysrKSB7IH0KLQotICAgICAgICAgaWYgKHN0YXJ0V2hpdGVzcGFjZSAhPSBjdXJyUG9zKSB7Ci0gICAgICAgICAgICAgc2VlbldoaXRlc3BhY2UgPSB0cnVlOwotICAgICAgICAgfQotICAgICB9Ci0KLSAgICAgcmV0dXJuIChzZWVuV2hpdGVzcGFjZSA/IENBUlJZX1dTIDogMCkKLSAgICAgICAgICAgIHwgKGVkZ2VUcmVhdG1lbnRGbGFncyAmIFNVUFBSRVNTX1RSQUlMSU5HX1dTKTsKLSAgfQotCi0gIC8qKgotICAgKiBEaXJlY3RseSBub3JtYWxpemUgYW5kIGRpc3BhdGNoIHRoZSBjaGFyYWN0ZXIgYXJyYXkuCi0gICAqCi0gICAqIEBwYXJhbSBjaCBUaGUgY2hhcmFjdGVycyBmcm9tIHRoZSBYTUwgZG9jdW1lbnQuCi0gICAqIEBwYXJhbSBzdGFydCBUaGUgc3RhcnQgcG9zaXRpb24gaW4gdGhlIGFycmF5LgotICAgKiBAcGFyYW0gbGVuZ3RoIFRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyB0byByZWFkIGZyb20gdGhlIGFycmF5LgotICAgKiBAcGFyYW0gaGFuZGxlciBTQVggQ29udGVudEhhbmRsZXIgb2JqZWN0IHRvIHJlY2VpdmUgdGhlIGV2ZW50LgotICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgdm9pZCBzZW5kTm9ybWFsaXplZFNBWGNoYXJhY3RlcnMoY2hhciBjaFtdLAotICAgICAgICAgICAgIGludCBzdGFydCwgaW50IGxlbmd0aCwKLSAgICAgICAgICAgICBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciBoYW5kbGVyKQotICAgICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgICAgICAgICAgICAgIHNlbmROb3JtYWxpemVkU0FYY2hhcmFjdGVycyhjaCwgc3RhcnQsIGxlbmd0aCwKLSAgICAgICAgICAgICBoYW5kbGVyLCBTVVBQUkVTU19CT1RIKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgKiBTZW5kcyB0aGUgc3BlY2lmaWVkIHJhbmdlIG9mIGNoYXJhY3RlcnMgYXMgc2F4IENvbW1lbnQuCi0gICAqIDxwPgotICAgKiBOb3RlIHRoYXQsIHVubGlrZSBzZW5kU0FYY2hhcmFjdGVycywgdGhpcyBoYXMgdG8gYmUgZG9uZSBhcyBhIHNpbmdsZQotICAgKiBjYWxsIHRvIExleGljYWxIYW5kbGVyI2NvbW1lbnQuCi0gICAqCi0gICAqIEBwYXJhbSBjaCBTQVggTGV4aWNhbEhhbmRsZXIgb2JqZWN0IHRvIHJlY2VpdmUgdGhlIGV2ZW50LgotICAgKiBAcGFyYW0gc3RhcnQgT2Zmc2V0IG9mIGZpcnN0IGNoYXJhY3RlciBpbiB0aGUgcmFuZ2UuCi0gICAqIEBwYXJhbSBsZW5ndGggTnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gc2VuZC4KLSAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gbWF5IGJlIHRocm93biBieSBoYW5kbGVyJ3MKLSAgICogY2hhcmFjdGVycygpIG1ldGhvZC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNlbmRTQVhDb21tZW50KAotICAgICAgICAgIG9yZy54bWwuc2F4LmV4dC5MZXhpY2FsSGFuZGxlciBjaCwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKQotICAgICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICAvLyAlT1BUJSBEbyBpdCB0aGlzIHdheSBmb3Igbm93Li4uCi0gICAgU3RyaW5nIGNvbW1lbnQgPSBnZXRTdHJpbmcoc3RhcnQsIGxlbmd0aCk7Ci0gICAgY2guY29tbWVudChjb21tZW50LnRvQ2hhckFycmF5KCksIDAsIGxlbmd0aCk7Ci0gIH0KLQotICAvKioKLSAgICogQ29waWVzIGNoYXJhY3RlcnMgZnJvbSB0aGlzIHN0cmluZyBpbnRvIHRoZSBkZXN0aW5hdGlvbiBjaGFyYWN0ZXIKLSAgICogYXJyYXkuCi0gICAqCi0gICAqIEBwYXJhbSAgICAgIHNyY0JlZ2luICAgaW5kZXggb2YgdGhlIGZpcnN0IGNoYXJhY3RlciBpbiB0aGUgc3RyaW5nCi0gICAqICAgICAgICAgICAgICAgICAgICAgICAgdG8gY29weS4KLSAgICogQHBhcmFtICAgICAgc3JjRW5kICAgICBpbmRleCBhZnRlciB0aGUgbGFzdCBjaGFyYWN0ZXIgaW4gdGhlIHN0cmluZwotICAgKiAgICAgICAgICAgICAgICAgICAgICAgIHRvIGNvcHkuCi0gICAqIEBwYXJhbSAgICAgIGRzdCAgICAgICAgdGhlIGRlc3RpbmF0aW9uIGFycmF5LgotICAgKiBAcGFyYW0gICAgICBkc3RCZWdpbiAgIHRoZSBzdGFydCBvZmZzZXQgaW4gdGhlIGRlc3RpbmF0aW9uIGFycmF5LgotICAgKiBAZXhjZXB0aW9uIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gSWYgYW55IG9mIHRoZSBmb2xsb3dpbmcKLSAgICogICAgICAgICAgICBpcyB0cnVlOgotICAgKiAgICAgICAgICAgIDx1bD48bGk+PGNvZGU+c3JjQmVnaW48L2NvZGU+IGlzIG5lZ2F0aXZlLgotICAgKiAgICAgICAgICAgIDxsaT48Y29kZT5zcmNCZWdpbjwvY29kZT4gaXMgZ3JlYXRlciB0aGFuIDxjb2RlPnNyY0VuZDwvY29kZT4KLSAgICogICAgICAgICAgICA8bGk+PGNvZGU+c3JjRW5kPC9jb2RlPiBpcyBncmVhdGVyIHRoYW4gdGhlIGxlbmd0aCBvZiB0aGlzCi0gICAqICAgICAgICAgICAgICAgIHN0cmluZwotICAgKiAgICAgICAgICAgIDxsaT48Y29kZT5kc3RCZWdpbjwvY29kZT4gaXMgbmVnYXRpdmUKLSAgICogICAgICAgICAgICA8bGk+PGNvZGU+ZHN0QmVnaW4rKHNyY0VuZC1zcmNCZWdpbik8L2NvZGU+IGlzIGxhcmdlciB0aGFuCi0gICAqICAgICAgICAgICAgICAgIDxjb2RlPmRzdC5sZW5ndGg8L2NvZGU+PC91bD4KLSAgICogQGV4Y2VwdGlvbiBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiA8Y29kZT5kc3Q8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+Ci0gICAqLwotICBwcml2YXRlIHZvaWQgZ2V0Q2hhcnMoaW50IHNyY0JlZ2luLCBpbnQgc3JjRW5kLCBjaGFyIGRzdFtdLCBpbnQgZHN0QmVnaW4pCi0gIHsKLSAgICAvLyAlVEJEJSBKb2UgbmVlZHMgdG8gd3JpdGUgdGhpcyBmdW5jdGlvbi4gIE1ha2UgcHVibGljIHdoZW4gaW1wbGVtZW50ZWQuCi0gIH0KLQotICAvKioKLSAgICogRW5jYXBzdWxhdGlvbiBjJ3Rvci4gQWZ0ZXIgdGhpcyBpcyBjYWxsZWQsIHRoZSBzb3VyY2UgRmFzdFN0cmluZ0J1ZmZlcgotICAgKiB3aWxsIGJlIHJlc2V0IHRvIHVzZSB0aGUgbmV3IG9iamVjdCBhcyBpdHMgbV9pbm5lckZTQiwgYW5kIHdpbGwgaGF2ZQotICAgKiBoYWQgaXRzIGNodW5rIHNpemUgcmVzZXQgYXBwcm9wcmlhdGVseS4gSVQgU0hPVUxEIE5FVkVSIEJFIENBTExFRAotICAgKiBFWENFUFQgV0hFTiBzb3VyY2UubGVuZ3RoKCk9PTE8PChzb3VyY2UubV9jaHVua0JpdHMrc291cmNlLm1fcmVidW5kbGVCaXRzKQotICAgKgotICAgKiBORUVEU0RPQyBAcGFyYW0gc291cmNlCi0gICAqLwotICBwcml2YXRlIEZhc3RTdHJpbmdCdWZmZXIoRmFzdFN0cmluZ0J1ZmZlciBzb3VyY2UpCi0gIHsKLQotICAgIC8vIENvcHkgZXhpc3RpbmcgaW5mb3JtYXRpb24gaW50byBuZXcgZW5jYXBzdWxhdGlvbgotICAgIG1fY2h1bmtCaXRzID0gc291cmNlLm1fY2h1bmtCaXRzOwotICAgIG1fbWF4Q2h1bmtCaXRzID0gc291cmNlLm1fbWF4Q2h1bmtCaXRzOwotICAgIG1fcmVidW5kbGVCaXRzID0gc291cmNlLm1fcmVidW5kbGVCaXRzOwotICAgIG1fY2h1bmtTaXplID0gc291cmNlLm1fY2h1bmtTaXplOwotICAgIG1fY2h1bmtNYXNrID0gc291cmNlLm1fY2h1bmtNYXNrOwotICAgIG1fYXJyYXkgPSBzb3VyY2UubV9hcnJheTsKLSAgICBtX2lubmVyRlNCID0gc291cmNlLm1faW5uZXJGU0I7Ci0KLSAgICAvLyBUaGVzZSBoYXZlIHRvIGJlIGFkanVzdGVkIGJlY2F1c2Ugd2UncmUgY2FsbGluZyBqdXN0IGF0IHRoZSB0aW1lCi0gICAgLy8gd2hlbiB3ZSB3b3VsZCBiZSBhYm91dCB0byBhbGxvY2F0ZSBhbm90aGVyIGNodW5rCi0gICAgbV9sYXN0Q2h1bmsgPSBzb3VyY2UubV9sYXN0Q2h1bmsgLSAxOwotICAgIG1fZmlyc3RGcmVlID0gc291cmNlLm1fY2h1bmtTaXplOwotCi0gICAgLy8gRXN0YWJsaXNoIGNhcHN1bGUgYXMgdGhlIElubmVyIEZTQiwgcmVzZXQgY2h1bmsgc2l6ZXMvYWRkcmVzc2luZwotICAgIHNvdXJjZS5tX2FycmF5ID0gbmV3IGNoYXJbMTZdW107Ci0gICAgc291cmNlLm1faW5uZXJGU0IgPSB0aGlzOwotCi0gICAgLy8gU2luY2Ugd2UgZW5jYXBzdWxhdGVkIGp1c3QgYXMgd2Ugd2VyZSBhYm91dCB0byBhcHBlbmQgYW5vdGhlcgotICAgIC8vIGNodW5rLCByZXR1cm4gcmVhZHkgdG8gY3JlYXRlIHRoZSBjaHVuayBhZnRlciB0aGUgaW5uZXJGU0IKLSAgICAvLyAtLSAxLCBub3QgMC4KLSAgICBzb3VyY2UubV9sYXN0Q2h1bmsgPSAxOwotICAgIHNvdXJjZS5tX2ZpcnN0RnJlZSA9IDA7Ci0gICAgc291cmNlLm1fY2h1bmtCaXRzICs9IG1fcmVidW5kbGVCaXRzOwotICAgIHNvdXJjZS5tX2NodW5rU2l6ZSA9IDEgPDwgKHNvdXJjZS5tX2NodW5rQml0cyk7Ci0gICAgc291cmNlLm1fY2h1bmtNYXNrID0gc291cmNlLm1fY2h1bmtTaXplIC0gMTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvSGFzaHRyZWUyTm9kZS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvSGFzaHRyZWUyTm9kZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4OTQ5MWY1Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL0hhc2h0cmVlMk5vZGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE0MiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAyLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBIYXNodHJlZTJOb2RlLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTUgMDg6MTU6NDUgc3VyZXNoX2VtYWlsaWQgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHM7Ci0KLWltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247Ci1pbXBvcnQgamF2YS51dGlsLkhhc2h0YWJsZTsKLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7Ci1pbXBvcnQgb3JnLnczYy5kb20uRWxlbWVudDsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotCi0vKioKLSAqIFNpbXBsZSBzdGF0aWMgdXRpbGl0eSB0byBjb252ZXJ0IEhhc2h0YWJsZSB0byBhIE5vZGUuCi0gKgotICogUGxlYXNlIG1haW50YWluIEpESyAxLjEueCBjb21wYXRpYmlsaXR5OyBubyBDb2xsZWN0aW9ucyEKLSAqCi0gKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0LkVudmlyb25tZW50Q2hlY2sKLSAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLmxpYi5FeHRlbnNpb25zCi0gKiBAYXV0aG9yIHNoYW5lX2N1cmN1cnVAdXMuaWJtLmNvbQotICogQHhzbC51c2FnZSBnZW5lcmFsCi0gKi8KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBIYXNodHJlZTJOb2RlCi17Ci0KLSAgICAvKioKLSAgICAgKiBDb252ZXJ0IGEgSGFzaHRhYmxlIGludG8gYSBOb2RlIHRyZWUuCi0gICAgICoKLSAgICAgKiA8cD5UaGUgaGFzaCBtYXkgaGF2ZSBlaXRoZXIgSGFzaHRhYmxlcyBhcyB2YWx1ZXMgKGluIHdoaWNoCi0gICAgICogY2FzZSB3ZSByZWN1cnNlKSBvciBvdGhlciB2YWx1ZXMsIGluIHdoaWNoIGNhc2Ugd2UgcHJpbnQgdGhlbQotICAgICAqIGFzICZsdDtpdGVtPiBlbGVtZW50cywgd2l0aCBhICdrZXknIGF0dHJpYnV0ZSB3aXRoIHRoZSB2YWx1ZQotICAgICAqIG9mIHRoZSBrZXksIGFuZCB0aGUgZWxlbWVudCBjb250ZW50cyBhcyB0aGUgdmFsdWUuPC9wPgotICAgICAqCi0gICAgICogPHA+SWYgYXJncyBhcmUgbnVsbCB3ZSBzaW1wbHkgcmV0dXJuIHdpdGhvdXQgZG9pbmcgYW55dGhpbmcuCi0gICAgICogSWYgd2UgZW5jb3VudGVyIGFuIGVycm9yLCB3ZSB3aWxsIGF0dGVtcHQgdG8gYWRkIGFuICdFUlJPUicKLSAgICAgKiBFbGVtZW50IHdpdGggZXhjZXB0aW9uIGluZm87IGlmIHRoYXQgZG9lc24ndCB3b3JrIHdlIHNpbXBseQotICAgICAqIHJldHVybiB3aXRob3V0IGRvaW5nIGFueXRoaW5nIGVsc2UgYnl0IHByaW50U3RhY2tUcmFjZSgpLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBoYXNoIHRvIGdldCBpbmZvIGZyb20gKG1heSBoYXZlIHN1Yi1oYXNodGFibGVzKQotICAgICAqIEBwYXJhbSBuYW1lIHRvIHVzZSBhcyBwYXJlbnQgZWxlbWVudCBmb3IgYXBwZW5kZWQgbm9kZQotICAgICAqIGZ1dHVyZXdvcmsgY291bGQgaGF2ZSBuYW1lc3BhY2UgYW5kIHByZWZpeCBhcyB3ZWxsCi0gICAgICogQHBhcmFtIGNvbnRhaW5lciBOb2RlIHRvIGFwcGVuZCBvdXIgcmVwb3J0IHRvCi0gICAgICogQHBhcmFtIGZhY3RvcnkgRG9jdW1lbnQgcHJvdmlkaW5nIGNyZWF0ZUVsZW1lbnQsIGV0Yy4gc2VydmljZXMKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIHZvaWQgYXBwZW5kSGFzaFRvTm9kZShIYXNodGFibGUgaGFzaCwgU3RyaW5nIG5hbWUsCi0gICAgICAgICAgICBOb2RlIGNvbnRhaW5lciwgRG9jdW1lbnQgZmFjdG9yeSkKLSAgICB7Ci0gICAgICAgIC8vIFJlcXVpcmVkIGFyZ3VtZW50cyBtdXN0IG5vdCBiZSBudWxsCi0gICAgICAgIGlmICgobnVsbCA9PSBjb250YWluZXIpIHx8IChudWxsID09IGZhY3RvcnkpIHx8IChudWxsID09IGhhc2gpKQotICAgICAgICB7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBuYW1lIHdlIHdpbGwgcHJvdmlkZSBhIGRlZmF1bHQgdmFsdWUgZm9yCi0gICAgICAgIFN0cmluZyBlbGVtTmFtZSA9IG51bGw7Ci0gICAgICAgIGlmICgobnVsbCA9PSBuYW1lKSB8fCAoIiIuZXF1YWxzKG5hbWUpKSkKLSAgICAgICAgICAgIGVsZW1OYW1lID0gImFwcGVuZEhhc2hUb05vZGUiOwotICAgICAgICBlbHNlCi0gICAgICAgICAgICBlbGVtTmFtZSA9IG5hbWU7Ci0KLSAgICAgICAgdHJ5Ci0gICAgICAgIHsKLSAgICAgICAgICAgIEVsZW1lbnQgaGFzaE5vZGUgPSBmYWN0b3J5LmNyZWF0ZUVsZW1lbnQoZWxlbU5hbWUpOwotICAgICAgICAgICAgY29udGFpbmVyLmFwcGVuZENoaWxkKGhhc2hOb2RlKTsKLQotICAgICAgICAgICAgRW51bWVyYXRpb24ga2V5cyA9IGhhc2gua2V5cygpOwotICAgICAgICAgICAgVmVjdG9yIHYgPSBuZXcgVmVjdG9yKCk7Ci0KLSAgICAgICAgICAgIHdoaWxlIChrZXlzLmhhc01vcmVFbGVtZW50cygpKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIE9iamVjdCBrZXkgPSBrZXlzLm5leHRFbGVtZW50KCk7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIGtleVN0ciA9IGtleS50b1N0cmluZygpOwotICAgICAgICAgICAgICAgIE9iamVjdCBpdGVtID0gaGFzaC5nZXQoa2V5KTsKLQotICAgICAgICAgICAgICAgIGlmIChpdGVtIGluc3RhbmNlb2YgSGFzaHRhYmxlKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gRW5zdXJlIGEgcHJlLW9yZGVyIHRyYXZlcnNhbDsgYWRkIHRoaXMgaGFzaGVzCi0gICAgICAgICAgICAgICAgICAgIC8vICBpdGVtcyBiZWZvcmUgcmVjdXJzaW5nIHRvIGNoaWxkIGhhc2hlcwotICAgICAgICAgICAgICAgICAgICAvLyBTYXZlIG5hbWUgYW5kIGhhc2ggaW4gdHdvIHN0ZXBzCi0gICAgICAgICAgICAgICAgICAgIHYuYWRkRWxlbWVudChrZXlTdHIpOwotICAgICAgICAgICAgICAgICAgICB2LmFkZEVsZW1lbnQoKEhhc2h0YWJsZSkgaXRlbSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIHRyeQotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBBZGQgaXRlbSB0byBub2RlCi0gICAgICAgICAgICAgICAgICAgICAgICBFbGVtZW50IG5vZGUgPSBmYWN0b3J5LmNyZWF0ZUVsZW1lbnQoIml0ZW0iKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUuc2V0QXR0cmlidXRlKCJrZXkiLCBrZXlTdHIpOwotICAgICAgICAgICAgICAgICAgICAgICAgbm9kZS5hcHBlbmRDaGlsZChmYWN0b3J5LmNyZWF0ZVRleHROb2RlKChTdHJpbmcpaXRlbSkpOwotICAgICAgICAgICAgICAgICAgICAgICAgaGFzaE5vZGUuYXBwZW5kQ2hpbGQobm9kZSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKQotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBFbGVtZW50IG5vZGUgPSBmYWN0b3J5LmNyZWF0ZUVsZW1lbnQoIml0ZW0iKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUuc2V0QXR0cmlidXRlKCJrZXkiLCBrZXlTdHIpOwotICAgICAgICAgICAgICAgICAgICAgICAgbm9kZS5hcHBlbmRDaGlsZChmYWN0b3J5LmNyZWF0ZVRleHROb2RlKCJFUlJPUjogUmVhZGluZyAiICsga2V5ICsgIiB0aHJldzogIiArIGUudG9TdHJpbmcoKSkpOwotICAgICAgICAgICAgICAgICAgICAgICAgaGFzaE5vZGUuYXBwZW5kQ2hpbGQobm9kZSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIE5vdyBnbyBiYWNrIGFuZCBkbyB0aGUgc2F2ZWQgaGFzaGVzCi0gICAgICAgICAgICBrZXlzID0gdi5lbGVtZW50cygpOwotICAgICAgICAgICAgd2hpbGUgKGtleXMuaGFzTW9yZUVsZW1lbnRzKCkpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgLy8gUmV0cmlldmUgbmFtZSBhbmQgaGFzaCBpbiB0d28gc3RlcHMKLSAgICAgICAgICAgICAgICBTdHJpbmcgbiA9IChTdHJpbmcpIGtleXMubmV4dEVsZW1lbnQoKTsKLSAgICAgICAgICAgICAgICBIYXNodGFibGUgaCA9IChIYXNodGFibGUpIGtleXMubmV4dEVsZW1lbnQoKTsKLQotICAgICAgICAgICAgICAgIGFwcGVuZEhhc2hUb05vZGUoaCwgbiwgaGFzaE5vZGUsIGZhY3RvcnkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChFeGNlcHRpb24gZTIpCi0gICAgICAgIHsKLSAgICAgICAgICAgIC8vIE9vb3BzLCBqdXN0IGJhaWwgKHN1Z2dlc3Rpb25zIGZvciBhIHNhZmUgdGhpbmcKLSAgICAgICAgICAgIC8vICB0byBkbyBpbiB0aGlzIGNhc2UgYXBwcmVjaWF0ZWQpCi0gICAgICAgICAgICBlMi5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgICAgfQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL0ludFN0YWNrLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9JbnRTdGFjay5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlYjE4YjNhLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL0ludFN0YWNrLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMTMgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogSW50U3RhY2suamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNSAwODoxNTo0NSBzdXJlc2hfZW1haWxpZCBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHM7Ci0KLWltcG9ydCBqYXZhLnV0aWwuRW1wdHlTdGFja0V4Y2VwdGlvbjsKLQotLyoqCi0gKiBJbXBsZW1lbnQgYSBzdGFjayBvZiBzaW1wbGUgaW50ZWdlcnMuCi0gKgotICogJU9QVCUKLSAqIFRoaXMgaXMgY3VycmVudGx5IGJhc2VkIG9uIEludFZlY3Rvciwgd2hpY2ggcGVybWl0cyBmYXN0IGFjZXNzIGJ1dCBwYXlzIGEKLSAqIGhlYXZ5IHJlY29weWluZyBwZW5hbHR5IGlmL3doZW4gaXRzIHNpemUgaXMgaW5jcmVhc2VkLiBJZiB3ZSBleHBlY3QgZGVlcAotICogc3RhY2tzLCB3ZSBzaG91bGQgY29uc2lkZXIgYSB2ZXJzaW9uIGJhc2VkIG9uIENodW5rZWRJbnRWZWN0b3IuCi0gKiBAeHNsLnVzYWdlIGludGVybmFsCi0gKi8KLXB1YmxpYyBjbGFzcyBJbnRTdGFjayBleHRlbmRzIEludFZlY3RvcgotewotCi0gIC8qKgotICAgKiBEZWZhdWx0IGNvbnN0cnVjdG9yLiAgTm90ZSB0aGF0IHRoZSBkZWZhdWx0Ci0gICAqIGJsb2NrIHNpemUgaXMgdmVyeSBzbWFsbCwgZm9yIHNtYWxsIGxpc3RzLgotICAgKi8KLSAgcHVibGljIEludFN0YWNrKCkKLSAgewotICAgIHN1cGVyKCk7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgSW50VmVjdG9yLCB1c2luZyB0aGUgZ2l2ZW4gYmxvY2sgc2l6ZS4KLSAgICoKLSAgICogQHBhcmFtIGJsb2Nrc2l6ZSBTaXplIG9mIGJsb2NrIHRvIGFsbG9jYXRlCi0gICAqLwotICBwdWJsaWMgSW50U3RhY2soaW50IGJsb2Nrc2l6ZSkKLSAgewotICAgIHN1cGVyKGJsb2Nrc2l6ZSk7Ci0gIH0KLQotICAvKioKLSAgICogQ29weSBjb25zdHJ1Y3RvciBmb3IgSW50U3RhY2sKLSAgICoKLSAgICogQHBhcmFtIHYgSW50U3RhY2sgdG8gY29weQotICAgKi8KLSAgcHVibGljIEludFN0YWNrIChJbnRTdGFjayB2KQotICB7Ci0gICAgICAgIHN1cGVyKHYpOwotICB9Ci0KLSAgLyoqCi0gICAqIFB1c2hlcyBhbiBpdGVtIG9udG8gdGhlIHRvcCBvZiB0aGlzIHN0YWNrLgotICAgKgotICAgKiBAcGFyYW0gICBpICAgdGhlIGludCB0byBiZSBwdXNoZWQgb250byB0aGlzIHN0YWNrLgotICAgKiBAcmV0dXJuICB0aGUgPGNvZGU+aXRlbTwvY29kZT4gYXJndW1lbnQuCi0gICAqLwotICBwdWJsaWMgaW50IHB1c2goaW50IGkpCi0gIHsKLQotICAgIGlmICgobV9maXJzdEZyZWUgKyAxKSA+PSBtX21hcFNpemUpCi0gICAgewotICAgICAgbV9tYXBTaXplICs9IG1fYmxvY2tzaXplOwotCi0gICAgICBpbnQgbmV3TWFwW10gPSBuZXcgaW50W21fbWFwU2l6ZV07Ci0KLSAgICAgIFN5c3RlbS5hcnJheWNvcHkobV9tYXAsIDAsIG5ld01hcCwgMCwgbV9maXJzdEZyZWUgKyAxKTsKLQotICAgICAgbV9tYXAgPSBuZXdNYXA7Ci0gICAgfQotCi0gICAgbV9tYXBbbV9maXJzdEZyZWVdID0gaTsKLQotICAgIG1fZmlyc3RGcmVlKys7Ci0KLSAgICByZXR1cm4gaTsKLSAgfQotCi0gIC8qKgotICAgKiBSZW1vdmVzIHRoZSBvYmplY3QgYXQgdGhlIHRvcCBvZiB0aGlzIHN0YWNrIGFuZCByZXR1cm5zIHRoYXQKLSAgICogb2JqZWN0IGFzIHRoZSB2YWx1ZSBvZiB0aGlzIGZ1bmN0aW9uLgotICAgKgotICAgKiBAcmV0dXJuICAgICBUaGUgb2JqZWN0IGF0IHRoZSB0b3Agb2YgdGhpcyBzdGFjay4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBpbnQgcG9wKCkKLSAgewotICAgIHJldHVybiBtX21hcFstLW1fZmlyc3RGcmVlXTsKLSAgfQotCi0gIC8qKgotICAgKiBRdWlja2x5IHBvcHMgYSBudW1iZXIgb2YgaXRlbXMgZnJvbSB0aGUgc3RhY2suCi0gICAqLwotCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHF1aWNrUG9wKGludCBuKQotICB7Ci0gICAgbV9maXJzdEZyZWUgLT0gbjsKLSAgfQotCi0gIC8qKgotICAgKiBMb29rcyBhdCB0aGUgb2JqZWN0IGF0IHRoZSB0b3Agb2YgdGhpcyBzdGFjayB3aXRob3V0IHJlbW92aW5nIGl0Ci0gICAqIGZyb20gdGhlIHN0YWNrLgotICAgKgotICAgKiBAcmV0dXJuICAgICB0aGUgb2JqZWN0IGF0IHRoZSB0b3Agb2YgdGhpcyBzdGFjay4KLSAgICogQHRocm93cyAgRW1wdHlTdGFja0V4Y2VwdGlvbiAgaWYgdGhpcyBzdGFjayBpcyBlbXB0eS4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBpbnQgcGVlaygpCi0gIHsKLSAgICB0cnkgewotICAgICAgcmV0dXJuIG1fbWFwW21fZmlyc3RGcmVlIC0gMV07Ci0gICAgfQotICAgIGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgRW1wdHlTdGFja0V4Y2VwdGlvbigpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBMb29rcyBhdCB0aGUgb2JqZWN0IGF0IHRoZSBwb3NpdGlvbiB0aGUgc3RhY2sgY291bnRpbmcgZG93biBuIGl0ZW1zLgotICAgKgotICAgKiBAcGFyYW0gbiBUaGUgbnVtYmVyIG9mIGl0ZW1zIGRvd24sIGluZGV4ZWQgZnJvbSB6ZXJvLgotICAgKiBAcmV0dXJuICAgICB0aGUgb2JqZWN0IGF0IG4gaXRlbXMgZG93bi4KLSAgICogQHRocm93cyAgRW1wdHlTdGFja0V4Y2VwdGlvbiAgaWYgdGhpcyBzdGFjayBpcyBlbXB0eS4KLSAgICovCi0gIHB1YmxpYyBpbnQgcGVlayhpbnQgbikKLSAgewotICAgIHRyeSB7Ci0gICAgICByZXR1cm4gbV9tYXBbbV9maXJzdEZyZWUtKDErbildOwotICAgIH0KLSAgICBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpCi0gICAgewotICAgICAgdGhyb3cgbmV3IEVtcHR5U3RhY2tFeGNlcHRpb24oKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogU2V0cyBhbiBvYmplY3QgYXQgYSB0aGUgdG9wIG9mIHRoZSBzdGF0Y2sKLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHZhbCBvYmplY3QgdG8gc2V0IGF0IHRoZSB0b3AKLSAgICogQHRocm93cyAgRW1wdHlTdGFja0V4Y2VwdGlvbiAgaWYgdGhpcyBzdGFjayBpcyBlbXB0eS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFRvcChpbnQgdmFsKQotICB7Ci0gICAgdHJ5IHsKLSAgICAgIG1fbWFwW21fZmlyc3RGcmVlIC0gMV0gPSB2YWw7Ci0gICAgfQotICAgIGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgRW1wdHlTdGFja0V4Y2VwdGlvbigpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBUZXN0cyBpZiB0aGlzIHN0YWNrIGlzIGVtcHR5LgotICAgKgotICAgKiBAcmV0dXJuICA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGlzIHN0YWNrIGlzIGVtcHR5OwotICAgKiAgICAgICAgICA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLgotICAgKiBAc2luY2UgICBKREsxLjAKLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGVtcHR5KCkKLSAgewotICAgIHJldHVybiBtX2ZpcnN0RnJlZSA9PSAwOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgd2hlcmUgYW4gb2JqZWN0IGlzIG9uIHRoaXMgc3RhY2suCi0gICAqCi0gICAqIEBwYXJhbSAgIG8gICB0aGUgZGVzaXJlZCBvYmplY3QuCi0gICAqIEByZXR1cm4gIHRoZSBkaXN0YW5jZSBmcm9tIHRoZSB0b3Agb2YgdGhlIHN0YWNrIHdoZXJlIHRoZSBvYmplY3QgaXNdCi0gICAqICAgICAgICAgIGxvY2F0ZWQ7IHRoZSByZXR1cm4gdmFsdWUgPGNvZGU+LTE8L2NvZGU+IGluZGljYXRlcyB0aGF0IHRoZQotICAgKiAgICAgICAgICBvYmplY3QgaXMgbm90IG9uIHRoZSBzdGFjay4KLSAgICogQHNpbmNlICAgSkRLMS4wCi0gICAqLwotICBwdWJsaWMgaW50IHNlYXJjaChpbnQgbykKLSAgewotCi0gICAgaW50IGkgPSBsYXN0SW5kZXhPZihvKTsKLQotICAgIGlmIChpID49IDApCi0gICAgewotICAgICAgcmV0dXJuIHNpemUoKSAtIGk7Ci0gICAgfQotCi0gICAgcmV0dXJuIC0xOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgY2xvbmUgb2YgY3VycmVudCBJbnRTdGFjawotICAgKgotICAgKiBAcmV0dXJuIGNsb25lIG9mIGN1cnJlbnQgSW50U3RhY2sKLSAgICovCi0gIHB1YmxpYyBPYmplY3QgY2xvbmUoKQotICAgIHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbgotICB7Ci0gICAgICAgIHJldHVybiAoSW50U3RhY2spIHN1cGVyLmNsb25lKCk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL0ludFZlY3Rvci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvSW50VmVjdG9yLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGQ4NzQ4YzQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvSW50VmVjdG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0MjEgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogSW50VmVjdG9yLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTUgMDg6MTU6NDUgc3VyZXNoX2VtYWlsaWQgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzOwotCi0vKioKLSAqIEEgdmVyeSBzaW1wbGUgdGFibGUgdGhhdCBzdG9yZXMgYSBsaXN0IG9mIGludC4KLSAqCi0gKiBUaGlzIHZlcnNpb24gaXMgYmFzZWQgb24gYSAicmVhbGxvYyIgc3RyYXRlZ3kgLS0gYSBzaW1sZSBhcnJheSBpcwotICogdXNlZCwgYW5kIHdoZW4gbW9yZSBzdG9yYWdlIGlzIG5lZWRlZCwgYSBsYXJnZXIgYXJyYXkgaXMgb2J0YWluZWQKLSAqIGFuZCBhbGwgZXhpc3RpbmcgZGF0YSBpcyByZWNvcGllZCBpbnRvIGl0LiBBcyBhIHJlc3VsdCwgcmVhZC93cml0ZQotICogYWNjZXNzIHRvIGV4aXN0aW5nIG5vZGVzIGlzIE8oMSkgZmFzdCBidXQgYXBwZW5kaW5nIG1heSBiZSBPKE4qKjIpCi0gKiBzbG93LiBTZWUgYWxzbyBTdWJhbGxvY2F0ZWRJbnRWZWN0b3IuCi0gKiBAeHNsLnVzYWdlIGludGVybmFsCi0gKi8KLXB1YmxpYyBjbGFzcyBJbnRWZWN0b3IgaW1wbGVtZW50cyBDbG9uZWFibGUKLXsKLQotICAvKiogU2l6ZSBvZiBibG9ja3MgdG8gYWxsb2NhdGUgICAgICAgICAgKi8KLSAgcHJvdGVjdGVkIGludCBtX2Jsb2Nrc2l6ZTsKLQotICAvKiogQXJyYXkgb2YgaW50cyAgICAgICAgICAqLwotICBwcm90ZWN0ZWQgaW50IG1fbWFwW107IC8vIEludFN0YWNrIGlzIHRyeWluZyB0byBzZWUgdGhpcyBkaXJlY3RseQotCi0gIC8qKiBOdW1iZXIgb2YgaW50cyBpbiBhcnJheSAgICAgICAgICAqLwotICBwcm90ZWN0ZWQgaW50IG1fZmlyc3RGcmVlID0gMDsKLQotICAvKiogU2l6ZSBvZiBhcnJheSAgICAgICAgICAqLwotICBwcm90ZWN0ZWQgaW50IG1fbWFwU2l6ZTsKLQotICAvKioKLSAgICogRGVmYXVsdCBjb25zdHJ1Y3Rvci4gIE5vdGUgdGhhdCB0aGUgZGVmYXVsdAotICAgKiBibG9jayBzaXplIGlzIHZlcnkgc21hbGwsIGZvciBzbWFsbCBsaXN0cy4KLSAgICovCi0gIHB1YmxpYyBJbnRWZWN0b3IoKQotICB7Ci0KLSAgICBtX2Jsb2Nrc2l6ZSA9IDMyOwotICAgIG1fbWFwU2l6ZSA9IG1fYmxvY2tzaXplOwotICAgIG1fbWFwID0gbmV3IGludFttX2Jsb2Nrc2l6ZV07Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgSW50VmVjdG9yLCB1c2luZyB0aGUgZ2l2ZW4gYmxvY2sgc2l6ZS4KLSAgICoKLSAgICogQHBhcmFtIGJsb2Nrc2l6ZSBTaXplIG9mIGJsb2NrIHRvIGFsbG9jYXRlCi0gICAqLwotICBwdWJsaWMgSW50VmVjdG9yKGludCBibG9ja3NpemUpCi0gIHsKLQotICAgIG1fYmxvY2tzaXplID0gYmxvY2tzaXplOwotICAgIG1fbWFwU2l6ZSA9IGJsb2Nrc2l6ZTsKLSAgICBtX21hcCA9IG5ldyBpbnRbYmxvY2tzaXplXTsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBJbnRWZWN0b3IsIHVzaW5nIHRoZSBnaXZlbiBibG9jayBzaXplLgotICAgKgotICAgKiBAcGFyYW0gYmxvY2tzaXplIFNpemUgb2YgYmxvY2sgdG8gYWxsb2NhdGUKLSAgICovCi0gIHB1YmxpYyBJbnRWZWN0b3IoaW50IGJsb2Nrc2l6ZSwgaW50IGluY3JlYXNlU2l6ZSkKLSAgewotCi0gICAgbV9ibG9ja3NpemUgPSBpbmNyZWFzZVNpemU7Ci0gICAgbV9tYXBTaXplID0gYmxvY2tzaXplOwotICAgIG1fbWFwID0gbmV3IGludFtibG9ja3NpemVdOwotICB9Ci0KLSAgLyoqCi0gICAqIENvcHkgY29uc3RydWN0b3IgZm9yIEludFZlY3RvcgotICAgKgotICAgKiBAcGFyYW0gdiBFeGlzdGluZyBJbnRWZWN0b3IgdG8gY29weQotICAgKi8KLSAgcHVibGljIEludFZlY3RvcihJbnRWZWN0b3IgdikKLSAgewotICAgICAgICBtX21hcCA9IG5ldyBpbnRbdi5tX21hcFNpemVdOwotICAgIG1fbWFwU2l6ZSA9IHYubV9tYXBTaXplOwotICAgIG1fZmlyc3RGcmVlID0gdi5tX2ZpcnN0RnJlZTsKLSAgICAgICAgbV9ibG9ja3NpemUgPSB2Lm1fYmxvY2tzaXplOwotICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHYubV9tYXAsIDAsIG1fbWFwLCAwLCBtX2ZpcnN0RnJlZSk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBsZW5ndGggb2YgdGhlIGxpc3QuCi0gICAqCi0gICAqIEByZXR1cm4gbGVuZ3RoIG9mIHRoZSBsaXN0Ci0gICAqLwotICBwdWJsaWMgZmluYWwgaW50IHNpemUoKQotICB7Ci0gICAgcmV0dXJuIG1fZmlyc3RGcmVlOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbGVuZ3RoIG9mIHRoZSBsaXN0LgotICAgKgotICAgKiBAcmV0dXJuIGxlbmd0aCBvZiB0aGUgbGlzdAotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgc2V0U2l6ZShpbnQgc3opCi0gIHsKLSAgICBtX2ZpcnN0RnJlZSA9IHN6OwotICB9Ci0KLQotICAvKioKLSAgICogQXBwZW5kIGEgaW50IG9udG8gdGhlIHZlY3Rvci4KLSAgICoKLSAgICogQHBhcmFtIHZhbHVlIEludCB0byBhZGQgdG8gdGhlIGxpc3QKLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIGFkZEVsZW1lbnQoaW50IHZhbHVlKQotICB7Ci0KLSAgICBpZiAoKG1fZmlyc3RGcmVlICsgMSkgPj0gbV9tYXBTaXplKQotICAgIHsKLSAgICAgIG1fbWFwU2l6ZSArPSBtX2Jsb2Nrc2l6ZTsKLQotICAgICAgaW50IG5ld01hcFtdID0gbmV3IGludFttX21hcFNpemVdOwotCi0gICAgICBTeXN0ZW0uYXJyYXljb3B5KG1fbWFwLCAwLCBuZXdNYXAsIDAsIG1fZmlyc3RGcmVlICsgMSk7Ci0KLSAgICAgIG1fbWFwID0gbmV3TWFwOwotICAgIH0KLQotICAgIG1fbWFwW21fZmlyc3RGcmVlXSA9IHZhbHVlOwotCi0gICAgbV9maXJzdEZyZWUrKzsKLSAgfQotCi0gIC8qKgotICAgKiBBcHBlbmQgc2V2ZXJhbCBpbnQgdmFsdWVzIG9udG8gdGhlIHZlY3Rvci4KLSAgICoKLSAgICogQHBhcmFtIHZhbHVlIEludCB0byBhZGQgdG8gdGhlIGxpc3QKLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIGFkZEVsZW1lbnRzKGludCB2YWx1ZSwgaW50IG51bWJlck9mRWxlbWVudHMpCi0gIHsKLQotICAgIGlmICgobV9maXJzdEZyZWUgKyBudW1iZXJPZkVsZW1lbnRzKSA+PSBtX21hcFNpemUpCi0gICAgewotICAgICAgbV9tYXBTaXplICs9IChtX2Jsb2Nrc2l6ZStudW1iZXJPZkVsZW1lbnRzKTsKLQotICAgICAgaW50IG5ld01hcFtdID0gbmV3IGludFttX21hcFNpemVdOwotCi0gICAgICBTeXN0ZW0uYXJyYXljb3B5KG1fbWFwLCAwLCBuZXdNYXAsIDAsIG1fZmlyc3RGcmVlICsgMSk7Ci0KLSAgICAgIG1fbWFwID0gbmV3TWFwOwotICAgIH0KLQotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtYmVyT2ZFbGVtZW50czsgaSsrKQotICAgIHsKLSAgICAgIG1fbWFwW21fZmlyc3RGcmVlXSA9IHZhbHVlOwotICAgICAgbV9maXJzdEZyZWUrKzsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogQXBwZW5kIHNldmVyYWwgc2xvdHMgb250byB0aGUgdmVjdG9yLCBidXQgZG8gbm90IHNldCB0aGUgdmFsdWVzLgotICAgKgotICAgKiBAcGFyYW0gbnVtYmVyT2ZFbGVtZW50cyBJbnQgdG8gYWRkIHRvIHRoZSBsaXN0Ci0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBhZGRFbGVtZW50cyhpbnQgbnVtYmVyT2ZFbGVtZW50cykKLSAgewotCi0gICAgaWYgKChtX2ZpcnN0RnJlZSArIG51bWJlck9mRWxlbWVudHMpID49IG1fbWFwU2l6ZSkKLSAgICB7Ci0gICAgICBtX21hcFNpemUgKz0gKG1fYmxvY2tzaXplK251bWJlck9mRWxlbWVudHMpOwotCi0gICAgICBpbnQgbmV3TWFwW10gPSBuZXcgaW50W21fbWFwU2l6ZV07Ci0KLSAgICAgIFN5c3RlbS5hcnJheWNvcHkobV9tYXAsIDAsIG5ld01hcCwgMCwgbV9maXJzdEZyZWUgKyAxKTsKLQotICAgICAgbV9tYXAgPSBuZXdNYXA7Ci0gICAgfQotCi0gICAgbV9maXJzdEZyZWUgKz0gbnVtYmVyT2ZFbGVtZW50czsKLSAgfQotCi0KLSAgLyoqCi0gICAqIEluc2VydHMgdGhlIHNwZWNpZmllZCBub2RlIGluIHRoaXMgdmVjdG9yIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXguCi0gICAqIEVhY2ggY29tcG9uZW50IGluIHRoaXMgdmVjdG9yIHdpdGggYW4gaW5kZXggZ3JlYXRlciBvciBlcXVhbCB0bwotICAgKiB0aGUgc3BlY2lmaWVkIGluZGV4IGlzIHNoaWZ0ZWQgdXB3YXJkIHRvIGhhdmUgYW4gaW5kZXggb25lIGdyZWF0ZXIKLSAgICogdGhhbiB0aGUgdmFsdWUgaXQgaGFkIHByZXZpb3VzbHkuCi0gICAqCi0gICAqIEBwYXJhbSB2YWx1ZSBJbnQgdG8gaW5zZXJ0Ci0gICAqIEBwYXJhbSBhdCBJbmRleCBvZiB3aGVyZSB0byBpbnNlcnQKLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIGluc2VydEVsZW1lbnRBdChpbnQgdmFsdWUsIGludCBhdCkKLSAgewotCi0gICAgaWYgKChtX2ZpcnN0RnJlZSArIDEpID49IG1fbWFwU2l6ZSkKLSAgICB7Ci0gICAgICBtX21hcFNpemUgKz0gbV9ibG9ja3NpemU7Ci0KLSAgICAgIGludCBuZXdNYXBbXSA9IG5ldyBpbnRbbV9tYXBTaXplXTsKLQotICAgICAgU3lzdGVtLmFycmF5Y29weShtX21hcCwgMCwgbmV3TWFwLCAwLCBtX2ZpcnN0RnJlZSArIDEpOwotCi0gICAgICBtX21hcCA9IG5ld01hcDsKLSAgICB9Ci0KLSAgICBpZiAoYXQgPD0gKG1fZmlyc3RGcmVlIC0gMSkpCi0gICAgewotICAgICAgU3lzdGVtLmFycmF5Y29weShtX21hcCwgYXQsIG1fbWFwLCBhdCArIDEsIG1fZmlyc3RGcmVlIC0gYXQpOwotICAgIH0KLQotICAgIG1fbWFwW2F0XSA9IHZhbHVlOwotCi0gICAgbV9maXJzdEZyZWUrKzsKLSAgfQotCi0gIC8qKgotICAgKiBJbnNlcnRzIHRoZSBzcGVjaWZpZWQgbm9kZSBpbiB0aGlzIHZlY3RvciBhdCB0aGUgc3BlY2lmaWVkIGluZGV4LgotICAgKiBFYWNoIGNvbXBvbmVudCBpbiB0aGlzIHZlY3RvciB3aXRoIGFuIGluZGV4IGdyZWF0ZXIgb3IgZXF1YWwgdG8KLSAgICogdGhlIHNwZWNpZmllZCBpbmRleCBpcyBzaGlmdGVkIHVwd2FyZCB0byBoYXZlIGFuIGluZGV4IG9uZSBncmVhdGVyCi0gICAqIHRoYW4gdGhlIHZhbHVlIGl0IGhhZCBwcmV2aW91c2x5LgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgcmVtb3ZlQWxsRWxlbWVudHMoKQotICB7Ci0KLSAgICBmb3IgKGludCBpID0gMDsgaSA8IG1fZmlyc3RGcmVlOyBpKyspCi0gICAgewotICAgICAgbV9tYXBbaV0gPSBqYXZhLmxhbmcuSW50ZWdlci5NSU5fVkFMVUU7Ci0gICAgfQotCi0gICAgbV9maXJzdEZyZWUgPSAwOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlbW92ZXMgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgdGhlIGFyZ3VtZW50IGZyb20gdGhpcyB2ZWN0b3IuCi0gICAqIElmIHRoZSBvYmplY3QgaXMgZm91bmQgaW4gdGhpcyB2ZWN0b3IsIGVhY2ggY29tcG9uZW50IGluIHRoZSB2ZWN0b3IKLSAgICogd2l0aCBhbiBpbmRleCBncmVhdGVyIG9yIGVxdWFsIHRvIHRoZSBvYmplY3QncyBpbmRleCBpcyBzaGlmdGVkCi0gICAqIGRvd253YXJkIHRvIGhhdmUgYW4gaW5kZXggb25lIHNtYWxsZXIgdGhhbiB0aGUgdmFsdWUgaXQgaGFkCi0gICAqIHByZXZpb3VzbHkuCi0gICAqCi0gICAqIEBwYXJhbSBzIEludCB0byByZW1vdmUgZnJvbSBhcnJheQotICAgKgotICAgKiBAcmV0dXJuIFRydWUgaWYgdGhlIGludCB3YXMgcmVtb3ZlZCwgZmFsc2UgaWYgaXQgd2FzIG5vdCBmb3VuZAotICAgKi8KLSAgcHVibGljIGZpbmFsIGJvb2xlYW4gcmVtb3ZlRWxlbWVudChpbnQgcykKLSAgewotCi0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtX2ZpcnN0RnJlZTsgaSsrKQotICAgIHsKLSAgICAgIGlmIChtX21hcFtpXSA9PSBzKQotICAgICAgewotICAgICAgICBpZiAoKGkgKyAxKSA8IG1fZmlyc3RGcmVlKQotICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkobV9tYXAsIGkgKyAxLCBtX21hcCwgaSAtIDEsIG1fZmlyc3RGcmVlIC0gaSk7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICBtX21hcFtpXSA9IGphdmEubGFuZy5JbnRlZ2VyLk1JTl9WQUxVRTsKLQotICAgICAgICBtX2ZpcnN0RnJlZS0tOwotCi0gICAgICAgIHJldHVybiB0cnVlOwotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiBmYWxzZTsKLSAgfQotCi0gIC8qKgotICAgKiBEZWxldGVzIHRoZSBjb21wb25lbnQgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4gRWFjaCBjb21wb25lbnQgaW4KLSAgICogdGhpcyB2ZWN0b3Igd2l0aCBhbiBpbmRleCBncmVhdGVyIG9yIGVxdWFsIHRvIHRoZSBzcGVjaWZpZWQKLSAgICogaW5kZXggaXMgc2hpZnRlZCBkb3dud2FyZCB0byBoYXZlIGFuIGluZGV4IG9uZSBzbWFsbGVyIHRoYW4KLSAgICogdGhlIHZhbHVlIGl0IGhhZCBwcmV2aW91c2x5LgotICAgKgotICAgKiBAcGFyYW0gaSBpbmRleCBvZiB3aGVyZSB0byByZW1vdmUgYW5kIGludAotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgcmVtb3ZlRWxlbWVudEF0KGludCBpKQotICB7Ci0KLSAgICBpZiAoaSA+IG1fZmlyc3RGcmVlKQotICAgICAgU3lzdGVtLmFycmF5Y29weShtX21hcCwgaSArIDEsIG1fbWFwLCBpLCBtX2ZpcnN0RnJlZSk7Ci0gICAgZWxzZQotICAgICAgbV9tYXBbaV0gPSBqYXZhLmxhbmcuSW50ZWdlci5NSU5fVkFMVUU7Ci0KLSAgICBtX2ZpcnN0RnJlZS0tOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldHMgdGhlIGNvbXBvbmVudCBhdCB0aGUgc3BlY2lmaWVkIGluZGV4IG9mIHRoaXMgdmVjdG9yIHRvIGJlIHRoZQotICAgKiBzcGVjaWZpZWQgb2JqZWN0LiBUaGUgcHJldmlvdXMgY29tcG9uZW50IGF0IHRoYXQgcG9zaXRpb24gaXMgZGlzY2FyZGVkLgotICAgKgotICAgKiBUaGUgaW5kZXggbXVzdCBiZSBhIHZhbHVlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAwIGFuZCBsZXNzCi0gICAqIHRoYW4gdGhlIGN1cnJlbnQgc2l6ZSBvZiB0aGUgdmVjdG9yLgotICAgKgotICAgKiBAcGFyYW0gdmFsdWUgb2JqZWN0IHRvIHNldAotICAgKiBAcGFyYW0gaW5kZXggSW5kZXggb2Ygd2hlcmUgdG8gc2V0IHRoZSBvYmplY3QKLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHNldEVsZW1lbnRBdChpbnQgdmFsdWUsIGludCBpbmRleCkKLSAgewotICAgIG1fbWFwW2luZGV4XSA9IHZhbHVlOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbnRoIGVsZW1lbnQuCi0gICAqCi0gICAqIEBwYXJhbSBpIGluZGV4IG9mIG9iamVjdCB0byBnZXQKLSAgICoKLSAgICogQHJldHVybiBvYmplY3QgYXQgZ2l2ZW4gaW5kZXgKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBpbnQgZWxlbWVudEF0KGludCBpKQotICB7Ci0gICAgcmV0dXJuIG1fbWFwW2ldOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgdGhlIHRhYmxlIGNvbnRhaW5zIHRoZSBnaXZlbiBub2RlLgotICAgKgotICAgKiBAcGFyYW0gcyBvYmplY3QgdG8gbG9vayBmb3IKLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHRoZSBvYmplY3QgaXMgaW4gdGhlIGxpc3QKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBib29sZWFuIGNvbnRhaW5zKGludCBzKQotICB7Ci0KLSAgICBmb3IgKGludCBpID0gMDsgaSA8IG1fZmlyc3RGcmVlOyBpKyspCi0gICAgewotICAgICAgaWYgKG1fbWFwW2ldID09IHMpCi0gICAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotICAgIHJldHVybiBmYWxzZTsKLSAgfQotCi0gIC8qKgotICAgKiBTZWFyY2hlcyBmb3IgdGhlIGZpcnN0IG9jY3VyZW5jZSBvZiB0aGUgZ2l2ZW4gYXJndW1lbnQsCi0gICAqIGJlZ2lubmluZyB0aGUgc2VhcmNoIGF0IGluZGV4LCBhbmQgdGVzdGluZyBmb3IgZXF1YWxpdHkKLSAgICogdXNpbmcgdGhlIGVxdWFscyBtZXRob2QuCi0gICAqCi0gICAqIEBwYXJhbSBlbGVtIG9iamVjdCB0byBsb29rIGZvcgotICAgKiBAcGFyYW0gaW5kZXggSW5kZXggb2Ygd2hlcmUgdG8gYmVnaW4gc2VhcmNoCi0gICAqIEByZXR1cm4gdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZSBvYmplY3QKLSAgICogYXJndW1lbnQgaW4gdGhpcyB2ZWN0b3IgYXQgcG9zaXRpb24gaW5kZXggb3IgbGF0ZXIgaW4gdGhlCi0gICAqIHZlY3RvcjsgcmV0dXJucyAtMSBpZiB0aGUgb2JqZWN0IGlzIG5vdCBmb3VuZC4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBpbnQgaW5kZXhPZihpbnQgZWxlbSwgaW50IGluZGV4KQotICB7Ci0KLSAgICBmb3IgKGludCBpID0gaW5kZXg7IGkgPCBtX2ZpcnN0RnJlZTsgaSsrKQotICAgIHsKLSAgICAgIGlmIChtX21hcFtpXSA9PSBlbGVtKQotICAgICAgICByZXR1cm4gaTsKLSAgICB9Ci0KLSAgICByZXR1cm4gamF2YS5sYW5nLkludGVnZXIuTUlOX1ZBTFVFOwotICB9Ci0KLSAgLyoqCi0gICAqIFNlYXJjaGVzIGZvciB0aGUgZmlyc3Qgb2NjdXJlbmNlIG9mIHRoZSBnaXZlbiBhcmd1bWVudCwKLSAgICogYmVnaW5uaW5nIHRoZSBzZWFyY2ggYXQgaW5kZXgsIGFuZCB0ZXN0aW5nIGZvciBlcXVhbGl0eQotICAgKiB1c2luZyB0aGUgZXF1YWxzIG1ldGhvZC4KLSAgICoKLSAgICogQHBhcmFtIGVsZW0gb2JqZWN0IHRvIGxvb2sgZm9yCi0gICAqIEByZXR1cm4gdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZSBvYmplY3QKLSAgICogYXJndW1lbnQgaW4gdGhpcyB2ZWN0b3IgYXQgcG9zaXRpb24gaW5kZXggb3IgbGF0ZXIgaW4gdGhlCi0gICAqIHZlY3RvcjsgcmV0dXJucyAtMSBpZiB0aGUgb2JqZWN0IGlzIG5vdCBmb3VuZC4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBpbnQgaW5kZXhPZihpbnQgZWxlbSkKLSAgewotCi0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtX2ZpcnN0RnJlZTsgaSsrKQotICAgIHsKLSAgICAgIGlmIChtX21hcFtpXSA9PSBlbGVtKQotICAgICAgICByZXR1cm4gaTsKLSAgICB9Ci0KLSAgICByZXR1cm4gamF2YS5sYW5nLkludGVnZXIuTUlOX1ZBTFVFOwotICB9Ci0KLSAgLyoqCi0gICAqIFNlYXJjaGVzIGZvciB0aGUgZmlyc3Qgb2NjdXJlbmNlIG9mIHRoZSBnaXZlbiBhcmd1bWVudCwKLSAgICogYmVnaW5uaW5nIHRoZSBzZWFyY2ggYXQgaW5kZXgsIGFuZCB0ZXN0aW5nIGZvciBlcXVhbGl0eQotICAgKiB1c2luZyB0aGUgZXF1YWxzIG1ldGhvZC4KLSAgICoKLSAgICogQHBhcmFtIGVsZW0gT2JqZWN0IHRvIGxvb2sgZm9yCi0gICAqIEByZXR1cm4gdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZSBvYmplY3QKLSAgICogYXJndW1lbnQgaW4gdGhpcyB2ZWN0b3IgYXQgcG9zaXRpb24gaW5kZXggb3IgbGF0ZXIgaW4gdGhlCi0gICAqIHZlY3RvcjsgcmV0dXJucyAtMSBpZiB0aGUgb2JqZWN0IGlzIG5vdCBmb3VuZC4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBpbnQgbGFzdEluZGV4T2YoaW50IGVsZW0pCi0gIHsKLQotICAgIGZvciAoaW50IGkgPSAobV9maXJzdEZyZWUgLSAxKTsgaSA+PSAwOyBpLS0pCi0gICAgewotICAgICAgaWYgKG1fbWFwW2ldID09IGVsZW0pCi0gICAgICAgIHJldHVybiBpOwotICAgIH0KLQotICAgIHJldHVybiBqYXZhLmxhbmcuSW50ZWdlci5NSU5fVkFMVUU7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyBjbG9uZSBvZiBjdXJyZW50IEludFZlY3RvcgotICAgKgotICAgKiBAcmV0dXJuIGNsb25lIG9mIGN1cnJlbnQgSW50VmVjdG9yCi0gICAqLwotICBwdWJsaWMgT2JqZWN0IGNsb25lKCkKLSAgICB0aHJvd3MgQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24KLSAgewotICAgICAgICByZXR1cm4gbmV3IEludFZlY3Rvcih0aGlzKTsKLSAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9MaXN0aW5nRXJyb3JIYW5kbGVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9MaXN0aW5nRXJyb3JIYW5kbGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDVkZGYxMzkuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvTGlzdGluZ0Vycm9ySGFuZGxlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTY3ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDAtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IExpc3RpbmdFcnJvckhhbmRsZXIuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNSAwODoxNTo0NiBzdXJlc2hfZW1haWxpZCBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlsczsKLQotaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRSZWFkZXI7Ci1pbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKLWltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtUmVhZGVyOwotaW1wb3J0IGphdmEuaW8uUHJpbnRXcml0ZXI7Ci1pbXBvcnQgamF2YS5uZXQuVVJMOwotaW1wb3J0IGphdmEubmV0LlVSTENvbm5lY3Rpb247Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLkVycm9yTGlzdGVuZXI7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2VMb2NhdG9yOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnJlcy5YTUxFcnJvclJlc291cmNlczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnJlcy5YTUxNZXNzYWdlczsKLQotaW1wb3J0IG9yZy54bWwuc2F4LkVycm9ySGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb247Ci0KLQotLyoqCi0gKiBTYW1wbGUgaW1wbGVtZW50YXRpb24gb2Ygc2ltaWxhciBTQVggRXJyb3JIYW5kbGVyIGFuZCBKQVhQIEVycm9yTGlzdGVuZXIuCi0gKgotICogPHA+VGhpcyBpbXBsZW1lbnRhdGlvbiBpcyBzdWl0YWJsZSBmb3IgdmFyaW91cyB1c2UgY2FzZXMsIGFuZAotICogcHJvdmlkZXMgc29tZSBiYXNpYyBjb25maWd1cmF0aW9uIEFQSSdzIGFzIHdlbGwgdG8gY29udHJvbAotICogd2hlbiB3ZSByZS10aHJvdyBlcnJvcnMsIGV0Yy48L3A+Ci0gKgotICogQGF1dGhvciBzaGFuZV9jdXJjdXJ1QHVzLmlibS5jb20KLSAqIEB4c2wudXNhZ2UgZ2VuZXJhbAotICovCi1wdWJsaWMgY2xhc3MgTGlzdGluZ0Vycm9ySGFuZGxlciBpbXBsZW1lbnRzIEVycm9ySGFuZGxlciwgRXJyb3JMaXN0ZW5lcgotewotICAgIHByb3RlY3RlZCBQcmludFdyaXRlciBtX3B3ID0gbnVsbDsKLQotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0b3IgTGlzdGluZ0Vycm9ySGFuZGxlcjsgdXNlci1zdXBwbGllZCBQcmludFdyaXRlci4KLSAgICAgKi8KLSAgICBwdWJsaWMgTGlzdGluZ0Vycm9ySGFuZGxlcihQcmludFdyaXRlciBwdykKLSAgICB7Ci0gICAgICAgIGlmIChudWxsID09IHB3KQotICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKFhNTE1lc3NhZ2VzLmNyZWF0ZVhNTE1lc3NhZ2UoWE1MRXJyb3JSZXNvdXJjZXMuRVJfRVJST1JIQU5ETEVSX0NSRUFURURfV0lUSF9OVUxMX1BSSU5UV1JJVEVSLCBudWxsKSk7Ci0gICAgICAgICAgICAvLyAiTGlzdGluZ0Vycm9ySGFuZGxlciBjcmVhdGVkIHdpdGggbnVsbCBQcmludFdyaXRlciEiKTsKLQotICAgICAgICBtX3B3ID0gcHc7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0b3IgTGlzdGluZ0Vycm9ySGFuZGxlcjsgdXNlcyBTeXN0ZW0uZXJyLgotICAgICAqLwotICAgIHB1YmxpYyBMaXN0aW5nRXJyb3JIYW5kbGVyKCkKLSAgICB7Ci0gICAgICAgIG1fcHcgPSBuZXcgUHJpbnRXcml0ZXIoU3lzdGVtLmVyciwgdHJ1ZSk7Ci0gICAgfQotCi0KLSAgICAvKiA9PT09PT09PSBJbXBsZW1lbnQgb3JnLnhtbC5zYXguRXJyb3JIYW5kbGVyID09PT09PT09ICovCi0gICAgLyoqCi0gICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgYSB3YXJuaW5nLgotICAgICAqCi0gICAgICogPHA+U0FYIHBhcnNlcnMgd2lsbCB1c2UgdGhpcyBtZXRob2QgdG8gcmVwb3J0IGNvbmRpdGlvbnMgdGhhdAotICAgICAqIGFyZSBub3QgZXJyb3JzIG9yIGZhdGFsIGVycm9ycyBhcyBkZWZpbmVkIGJ5IHRoZSBYTUwgMS4wCi0gICAgICogcmVjb21tZW5kYXRpb24uICBUaGUgZGVmYXVsdCBiZWhhdmlvdXIgaXMgdG8gdGFrZSBubyBhY3Rpb24uPC9wPgotICAgICAqCi0gICAgICogPHA+VGhlIFNBWCBwYXJzZXIgbXVzdCBjb250aW51ZSB0byBwcm92aWRlIG5vcm1hbCBwYXJzaW5nIGV2ZW50cwotICAgICAqIGFmdGVyIGludm9raW5nIHRoaXMgbWV0aG9kOiBpdCBzaG91bGQgc3RpbGwgYmUgcG9zc2libGUgZm9yIHRoZQotICAgICAqIGFwcGxpY2F0aW9uIHRvIHByb2Nlc3MgdGhlIGRvY3VtZW50IHRocm91Z2ggdG8gdGhlIGVuZC48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5GaWx0ZXJzIG1heSB1c2UgdGhpcyBtZXRob2QgdG8gcmVwb3J0IG90aGVyLCBub24tWE1MIHdhcm5pbmdzCi0gICAgICogYXMgd2VsbC48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gZXhjZXB0aW9uIFRoZSB3YXJuaW5nIGluZm9ybWF0aW9uIGVuY2Fwc3VsYXRlZCBpbiBhCi0gICAgICogICAgICAgICAgICAgICAgICBTQVggcGFyc2UgZXhjZXB0aW9uLgotICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgICAqIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uOyBvbmx5IGlmIHNldFRocm93T25XYXJuaW5nIGlzIHRydWUuCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5TQVhQYXJzZUV4Y2VwdGlvbgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHdhcm5pbmcgKFNBWFBhcnNlRXhjZXB0aW9uIGV4Y2VwdGlvbikKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgbG9nRXhjZXB0aW9uTG9jYXRpb24obV9wdywgZXhjZXB0aW9uKTsKLSAgICAgICAgLy8gTm90ZTogc2hvdWxkIHdlIHJlYWxseSBjYWxsIC50b1N0cmluZygpIGJlbG93LCBzaW5jZQotICAgICAgICAvLyAgc29tZXRpbWVzIHRoZSBtZXNzYWdlIGlzIG5vdCBwcm9wZXJseSBzZXQ/Ci0gICAgICAgIG1fcHcucHJpbnRsbigid2FybmluZzogIiArIGV4Y2VwdGlvbi5nZXRNZXNzYWdlKCkpOwotICAgICAgICBtX3B3LmZsdXNoKCk7Ci0KLSAgICAgICAgaWYgKGdldFRocm93T25XYXJuaW5nKCkpCi0gICAgICAgICAgICB0aHJvdyBleGNlcHRpb247Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBhIHJlY292ZXJhYmxlIGVycm9yLgotICAgICAqCi0gICAgICogPHA+VGhpcyBjb3JyZXNwb25kcyB0byB0aGUgZGVmaW5pdGlvbiBvZiAiZXJyb3IiIGluIHNlY3Rpb24gMS4yCi0gICAgICogb2YgdGhlIFczQyBYTUwgMS4wIFJlY29tbWVuZGF0aW9uLiAgRm9yIGV4YW1wbGUsIGEgdmFsaWRhdGluZwotICAgICAqIHBhcnNlciB3b3VsZCB1c2UgdGhpcyBjYWxsYmFjayB0byByZXBvcnQgdGhlIHZpb2xhdGlvbiBvZiBhCi0gICAgICogdmFsaWRpdHkgY29uc3RyYWludC4gIFRoZSBkZWZhdWx0IGJlaGF2aW91ciBpcyB0byB0YWtlIG5vCi0gICAgICogYWN0aW9uLjwvcD4KLSAgICAgKgotICAgICAqIDxwPlRoZSBTQVggcGFyc2VyIG11c3QgY29udGludWUgdG8gcHJvdmlkZSBub3JtYWwgcGFyc2luZyBldmVudHMKLSAgICAgKiBhZnRlciBpbnZva2luZyB0aGlzIG1ldGhvZDogaXQgc2hvdWxkIHN0aWxsIGJlIHBvc3NpYmxlIGZvciB0aGUKLSAgICAgKiBhcHBsaWNhdGlvbiB0byBwcm9jZXNzIHRoZSBkb2N1bWVudCB0aHJvdWdoIHRvIHRoZSBlbmQuICBJZiB0aGUKLSAgICAgKiBhcHBsaWNhdGlvbiBjYW5ub3QgZG8gc28sIHRoZW4gdGhlIHBhcnNlciBzaG91bGQgcmVwb3J0IGEgZmF0YWwKLSAgICAgKiBlcnJvciBldmVuIGlmIHRoZSBYTUwgMS4wIHJlY29tbWVuZGF0aW9uIGRvZXMgbm90IHJlcXVpcmUgaXQgdG8KLSAgICAgKiBkbyBzby48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5GaWx0ZXJzIG1heSB1c2UgdGhpcyBtZXRob2QgdG8gcmVwb3J0IG90aGVyLCBub24tWE1MIGVycm9ycwotICAgICAqIGFzIHdlbGwuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGV4Y2VwdGlvbiBUaGUgZXJyb3IgaW5mb3JtYXRpb24gZW5jYXBzdWxhdGVkIGluIGEKLSAgICAgKiAgICAgICAgICAgICAgICAgIFNBWCBwYXJzZSBleGNlcHRpb24uCi0gICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAgICogd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb247IG9ubHkgaWYgc2V0VGhyb3dPbkVycm9yaXMgdHJ1ZS4KLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LlNBWFBhcnNlRXhjZXB0aW9uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZXJyb3IgKFNBWFBhcnNlRXhjZXB0aW9uIGV4Y2VwdGlvbikKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgbG9nRXhjZXB0aW9uTG9jYXRpb24obV9wdywgZXhjZXB0aW9uKTsKLSAgICAgICAgbV9wdy5wcmludGxuKCJlcnJvcjogIiArIGV4Y2VwdGlvbi5nZXRNZXNzYWdlKCkpOwotICAgICAgICBtX3B3LmZsdXNoKCk7Ci0KLSAgICAgICAgaWYgKGdldFRocm93T25FcnJvcigpKQotICAgICAgICAgICAgdGhyb3cgZXhjZXB0aW9uOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgYSBub24tcmVjb3ZlcmFibGUgZXJyb3IuCi0gICAgICoKLSAgICAgKiA8cD5UaGlzIGNvcnJlc3BvbmRzIHRvIHRoZSBkZWZpbml0aW9uIG9mICJmYXRhbCBlcnJvciIgaW4KLSAgICAgKiBzZWN0aW9uIDEuMiBvZiB0aGUgVzNDIFhNTCAxLjAgUmVjb21tZW5kYXRpb24uICBGb3IgZXhhbXBsZSwgYQotICAgICAqIHBhcnNlciB3b3VsZCB1c2UgdGhpcyBjYWxsYmFjayB0byByZXBvcnQgdGhlIHZpb2xhdGlvbiBvZiBhCi0gICAgICogd2VsbC1mb3JtZWRuZXNzIGNvbnN0cmFpbnQuPC9wPgotICAgICAqCi0gICAgICogPHA+VGhlIGFwcGxpY2F0aW9uIG11c3QgYXNzdW1lIHRoYXQgdGhlIGRvY3VtZW50IGlzIHVudXNhYmxlCi0gICAgICogYWZ0ZXIgdGhlIHBhcnNlciBoYXMgaW52b2tlZCB0aGlzIG1ldGhvZCwgYW5kIHNob3VsZCBjb250aW51ZQotICAgICAqIChpZiBhdCBhbGwpIG9ubHkgZm9yIHRoZSBzYWtlIG9mIGNvbGxlY3RpbmcgYWRkaXRpb24gZXJyb3IKLSAgICAgKiBtZXNzYWdlczogaW4gZmFjdCwgU0FYIHBhcnNlcnMgYXJlIGZyZWUgdG8gc3RvcCByZXBvcnRpbmcgYW55Ci0gICAgICogb3RoZXIgZXZlbnRzIG9uY2UgdGhpcyBtZXRob2QgaGFzIGJlZW4gaW52b2tlZC48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gZXhjZXB0aW9uIFRoZSBlcnJvciBpbmZvcm1hdGlvbiBlbmNhcHN1bGF0ZWQgaW4gYQotICAgICAqICAgICAgICAgICAgICAgICAgU0FYIHBhcnNlIGV4Y2VwdGlvbi4KLSAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICAgKiB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbjsgb25seSBpZiBzZXRUaHJvd09uRmF0YWxFcnJvciBpcyB0cnVlLgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBmYXRhbEVycm9yIChTQVhQYXJzZUV4Y2VwdGlvbiBleGNlcHRpb24pCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGxvZ0V4Y2VwdGlvbkxvY2F0aW9uKG1fcHcsIGV4Y2VwdGlvbik7Ci0gICAgICAgIG1fcHcucHJpbnRsbigiZmF0YWxFcnJvcjogIiArIGV4Y2VwdGlvbi5nZXRNZXNzYWdlKCkpOwotICAgICAgICBtX3B3LmZsdXNoKCk7Ci0KLSAgICAgICAgaWYgKGdldFRocm93T25GYXRhbEVycm9yKCkpCi0gICAgICAgICAgICB0aHJvdyBleGNlcHRpb247Ci0gICAgfQotCi0KLSAgICAvKiA9PT09PT09PSBJbXBsZW1lbnQgamF2YXgueG1sLnRyYW5zZm9ybS5FcnJvckxpc3RlbmVyID09PT09PT09ICovCi0KLSAgICAvKioKLSAgICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBhIHdhcm5pbmcuCi0gICAgICoKLSAgICAgKiA8cD57QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lcn0gY2FuIHVzZSB0aGlzIG1ldGhvZCB0byByZXBvcnQKLSAgICAgKiBjb25kaXRpb25zIHRoYXQgYXJlIG5vdCBlcnJvcnMgb3IgZmF0YWwgZXJyb3JzLiAgVGhlIGRlZmF1bHQgYmVoYXZpb3VyCi0gICAgICogaXMgdG8gdGFrZSBubyBhY3Rpb24uPC9wPgotICAgICAqCi0gICAgICogPHA+QWZ0ZXIgaW52b2tpbmcgdGhpcyBtZXRob2QsIHRoZSBUcmFuc2Zvcm1lciBtdXN0IGNvbnRpbnVlIHdpdGgKLSAgICAgKiB0aGUgdHJhbnNmb3JtYXRpb24uIEl0IHNob3VsZCBzdGlsbCBiZSBwb3NzaWJsZSBmb3IgdGhlCi0gICAgICogYXBwbGljYXRpb24gdG8gcHJvY2VzcyB0aGUgZG9jdW1lbnQgdGhyb3VnaCB0byB0aGUgZW5kLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBleGNlcHRpb24gVGhlIHdhcm5pbmcgaW5mb3JtYXRpb24gZW5jYXBzdWxhdGVkIGluIGEKLSAgICAgKiAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybWVyIGV4Y2VwdGlvbi4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbiAgb25seSBpZgotICAgICAqIHNldFRocm93T25XYXJuaW5nIGlzIHRydWUuCi0gICAgICoKLSAgICAgKiBAc2VlIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB3YXJuaW5nKFRyYW5zZm9ybWVyRXhjZXB0aW9uIGV4Y2VwdGlvbikKLSAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAgewotICAgICAgICBsb2dFeGNlcHRpb25Mb2NhdGlvbihtX3B3LCBleGNlcHRpb24pOwotICAgICAgICBtX3B3LnByaW50bG4oIndhcm5pbmc6ICIgKyBleGNlcHRpb24uZ2V0TWVzc2FnZSgpKTsKLSAgICAgICAgbV9wdy5mbHVzaCgpOwotCi0gICAgICAgIGlmIChnZXRUaHJvd09uV2FybmluZygpKQotICAgICAgICAgICAgdGhyb3cgZXhjZXB0aW9uOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGEgcmVjb3ZlcmFibGUgZXJyb3IuCi0gICAgICoKLSAgICAgKiA8cD5UaGUgdHJhbnNmb3JtZXIgbXVzdCBjb250aW51ZSB0byB0cnkgYW5kIHByb3ZpZGUgbm9ybWFsIHRyYW5zZm9ybWF0aW9uCi0gICAgICogYWZ0ZXIgaW52b2tpbmcgdGhpcyBtZXRob2QuICBJdCBzaG91bGQgc3RpbGwgYmUgcG9zc2libGUgZm9yIHRoZQotICAgICAqIGFwcGxpY2F0aW9uIHRvIHByb2Nlc3MgdGhlIGRvY3VtZW50IHRocm91Z2ggdG8gdGhlIGVuZCBpZiBubyBvdGhlciBlcnJvcnMKLSAgICAgKiBhcmUgZW5jb3VudGVyZWQuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGV4Y2VwdGlvbiBUaGUgZXJyb3IgaW5mb3JtYXRpb24gZW5jYXBzdWxhdGVkIGluIGEKLSAgICAgKiAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybWVyIGV4Y2VwdGlvbi4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbiAgb25seSBpZgotICAgICAqIHNldFRocm93T25FcnJvciBpcyB0cnVlLgotICAgICAqCi0gICAgICogQHNlZSBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZXJyb3IoVHJhbnNmb3JtZXJFeGNlcHRpb24gZXhjZXB0aW9uKQotICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGxvZ0V4Y2VwdGlvbkxvY2F0aW9uKG1fcHcsIGV4Y2VwdGlvbik7Ci0gICAgICAgIG1fcHcucHJpbnRsbigiZXJyb3I6ICIgKyBleGNlcHRpb24uZ2V0TWVzc2FnZSgpKTsKLSAgICAgICAgbV9wdy5mbHVzaCgpOwotCi0gICAgICAgIGlmIChnZXRUaHJvd09uRXJyb3IoKSkKLSAgICAgICAgICAgIHRocm93IGV4Y2VwdGlvbjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBhIG5vbi1yZWNvdmVyYWJsZSBlcnJvci4KLSAgICAgKgotICAgICAqIDxwPlRoZSB0cmFuc2Zvcm1lciBtdXN0IGNvbnRpbnVlIHRvIHRyeSBhbmQgcHJvdmlkZSBub3JtYWwgdHJhbnNmb3JtYXRpb24KLSAgICAgKiBhZnRlciBpbnZva2luZyB0aGlzIG1ldGhvZC4gIEl0IHNob3VsZCBzdGlsbCBiZSBwb3NzaWJsZSBmb3IgdGhlCi0gICAgICogYXBwbGljYXRpb24gdG8gcHJvY2VzcyB0aGUgZG9jdW1lbnQgdGhyb3VnaCB0byB0aGUgZW5kIGlmIG5vIG90aGVyIGVycm9ycwotICAgICAqIGFyZSBlbmNvdW50ZXJlZCwgYnV0IHRoZXJlIGlzIG5vIGd1YXJhbnRlZSB0aGF0IHRoZSBvdXRwdXQgd2lsbCBiZQotICAgICAqIHVzZWFibGUuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGV4Y2VwdGlvbiBUaGUgZXJyb3IgaW5mb3JtYXRpb24gZW5jYXBzdWxhdGVkIGluIGEKLSAgICAgKiAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybWVyIGV4Y2VwdGlvbi4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbiAgb25seSBpZgotICAgICAqIHNldFRocm93T25FcnJvciBpcyB0cnVlLgotICAgICAqCi0gICAgICogQHNlZSBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZmF0YWxFcnJvcihUcmFuc2Zvcm1lckV4Y2VwdGlvbiBleGNlcHRpb24pCi0gICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgbG9nRXhjZXB0aW9uTG9jYXRpb24obV9wdywgZXhjZXB0aW9uKTsKLSAgICAgICAgbV9wdy5wcmludGxuKCJlcnJvcjogIiArIGV4Y2VwdGlvbi5nZXRNZXNzYWdlKCkpOwotICAgICAgICBtX3B3LmZsdXNoKCk7Ci0KLSAgICAgICAgaWYgKGdldFRocm93T25FcnJvcigpKQotICAgICAgICAgICAgdGhyb3cgZXhjZXB0aW9uOwotICAgIH0KLQotCi0KLSAgICAvKiA9PT09PT09PSBJbXBsZW1lbnQgd29ya2VyIG1ldGhvZHMgPT09PT09PT0gKi8KLQotCi0gICAgLyoqCi0gICAgICogUHJpbnQgb3V0IGxvY2F0aW9uIGluZm9ybWF0aW9uIGFib3V0IHRoZSBleGNlcHRpb24uCi0gICAgICoKLSAgICAgKiBDcmliYmVkIGZyb20gRGVmYXVsdEVycm9ySGFuZGxlci5wcmludExvY2F0aW9uKCkKLSAgICAgKiBAcGFyYW0gcHcgUHJpbnRXcml0ZXIgdG8gc2VuZCBvdXRwdXQgdG8KLSAgICAgKiBAcGFyYW0gZXhjZXB0aW9uIFRyYW5zZm9ybWVyRXhjZXB0aW9uIG9yIFNBWFBhcnNlRXhjZXB0aW9uCi0gICAgICogdG8gbG9nIGluZm9ybWF0aW9uIGFib3V0Ci0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyB2b2lkIGxvZ0V4Y2VwdGlvbkxvY2F0aW9uKFByaW50V3JpdGVyIHB3LCBUaHJvd2FibGUgZXhjZXB0aW9uKQotICAgIHsKLSAgICAgICAgaWYgKG51bGwgPT0gcHcpCi0gICAgICAgICAgICBwdyA9IG5ldyBQcmludFdyaXRlcihTeXN0ZW0uZXJyLCB0cnVlKTsKLQotICAgICAgICBTb3VyY2VMb2NhdG9yIGxvY2F0b3IgPSBudWxsOwotICAgICAgICBUaHJvd2FibGUgY2F1c2UgPSBleGNlcHRpb247Ci0KLSAgICAgICAgLy8gVHJ5IHRvIGZpbmQgdGhlIGxvY2F0b3IgY2xvc2VzdCB0byB0aGUgY2F1c2UuCi0gICAgICAgIGRvCi0gICAgICAgIHsKLSAgICAgICAgICAgIC8vIEZpbmQgdGhlIGN1cnJlbnQgbG9jYXRvciwgaWYgb25lIHByZXNlbnQKLSAgICAgICAgICAgIGlmKGNhdXNlIGluc3RhbmNlb2YgU0FYUGFyc2VFeGNlcHRpb24pCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgLy8gQSBTQVhTb3VyY2VMb2NhdG9yIGlzIGEgWGFsYW4gaGVscGVyIGNsYXNzCi0gICAgICAgICAgICAgICAgLy8gIHRoYXQgaW1wbGVtZW50cyBib3RoIGEgU291cmNlTG9jYXRvciBhbmQgYSBTQVggTG9jYXRvcgotICAgICAgICAgICAgICAgIC8vQHRvZG8gY2hlY2sgdGhhdCB0aGUgbmV3IGxvY2F0b3IgYWN0dWFsbHkgaGFzCi0gICAgICAgICAgICAgICAgLy8gIGFzIG11Y2ggb3IgbW9yZSBpbmZvcm1hdGlvbiBhcyB0aGUKLSAgICAgICAgICAgICAgICAvLyAgY3VycmVudCBvbmUgYWxyZWFkeSBkb2VzCi0gICAgICAgICAgICAgICAgbG9jYXRvciA9IG5ldyBTQVhTb3VyY2VMb2NhdG9yKChTQVhQYXJzZUV4Y2VwdGlvbiljYXVzZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChjYXVzZSBpbnN0YW5jZW9mIFRyYW5zZm9ybWVyRXhjZXB0aW9uKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIFNvdXJjZUxvY2F0b3IgY2F1c2VMb2NhdG9yID0gKChUcmFuc2Zvcm1lckV4Y2VwdGlvbiljYXVzZSkuZ2V0TG9jYXRvcigpOwotICAgICAgICAgICAgICAgIGlmKG51bGwgIT0gY2F1c2VMb2NhdG9yKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgbG9jYXRvciA9IGNhdXNlTG9jYXRvcjsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIFRoZW4gd2FsayBiYWNrIGRvd24gdGhlIGNoYWluIG9mIGV4Y2VwdGlvbnMKLSAgICAgICAgICAgIGlmKGNhdXNlIGluc3RhbmNlb2YgVHJhbnNmb3JtZXJFeGNlcHRpb24pCi0gICAgICAgICAgICAgICAgY2F1c2UgPSAoKFRyYW5zZm9ybWVyRXhjZXB0aW9uKWNhdXNlKS5nZXRDYXVzZSgpOwotICAgICAgICAgICAgZWxzZSBpZihjYXVzZSBpbnN0YW5jZW9mIFdyYXBwZWRSdW50aW1lRXhjZXB0aW9uKQotICAgICAgICAgICAgICAgIGNhdXNlID0gKChXcmFwcGVkUnVudGltZUV4Y2VwdGlvbiljYXVzZSkuZ2V0RXhjZXB0aW9uKCk7Ci0gICAgICAgICAgICBlbHNlIGlmKGNhdXNlIGluc3RhbmNlb2YgU0FYRXhjZXB0aW9uKQotICAgICAgICAgICAgICAgIGNhdXNlID0gKChTQVhFeGNlcHRpb24pY2F1c2UpLmdldEV4Y2VwdGlvbigpOwotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIGNhdXNlID0gbnVsbDsKLSAgICAgICAgfQotICAgICAgICB3aGlsZShudWxsICE9IGNhdXNlKTsKLQotICAgICAgICAvLyBGb3JtYXR0aW5nIG5vdGU6IG1pbWljIGphdmFjLWxpa2UgZXJyb3JzOgotICAgICAgICAvLyAgcGF0aFxmaWxlbmFtZToxMjM6IG1lc3NhZ2UtaGVyZQotICAgICAgICAvLyAgc3lzdGVtSWQ6TD0xO0M9MjogbWVzc2FnZS1oZXJlCi0gICAgICAgIGlmKG51bGwgIT0gbG9jYXRvcikKLSAgICAgICAgewotICAgICAgICAgICAgU3RyaW5nIGlkID0gKGxvY2F0b3IuZ2V0UHVibGljSWQoKSAhPSBsb2NhdG9yLmdldFB1YmxpY0lkKCkpCi0gICAgICAgICAgICAgICAgICAgICAgPyBsb2NhdG9yLmdldFB1YmxpY0lkKCkKLSAgICAgICAgICAgICAgICAgICAgICAgIDogKG51bGwgIT0gbG9jYXRvci5nZXRTeXN0ZW1JZCgpKQotICAgICAgICAgICAgICAgICAgICAgICAgICA/IGxvY2F0b3IuZ2V0U3lzdGVtSWQoKSA6ICJTeXN0ZW1JZC1Vbmtub3duIjsKLQotICAgICAgICAgICAgcHcucHJpbnQoaWQgKyAiOkxpbmU9IiArIGxvY2F0b3IuZ2V0TGluZU51bWJlcigpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIjtDb2x1bW49IiArIGxvY2F0b3IuZ2V0Q29sdW1uTnVtYmVyKCkrIjogIik7Ci0gICAgICAgICAgICBwdy5wcmludGxuKCJleGNlcHRpb246IiArIGV4Y2VwdGlvbi5nZXRNZXNzYWdlKCkpOwotICAgICAgICAgICAgcHcucHJpbnRsbigicm9vdC1jYXVzZToiCi0gICAgICAgICAgICAgICAgICAgICAgICsgKChudWxsICE9IGNhdXNlKSA/IGNhdXNlLmdldE1lc3NhZ2UoKSA6ICJudWxsIikpOwotICAgICAgICAgICAgbG9nU291cmNlTGluZShwdywgbG9jYXRvcik7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICB7Ci0gICAgICAgICAgICBwdy5wcmludCgiU3lzdGVtSWQtVW5rbm93bjpsb2NhdG9yLXVuYXZhaWxhYmxlOiAiKTsKLSAgICAgICAgICAgIHB3LnByaW50bG4oImV4Y2VwdGlvbjoiICsgZXhjZXB0aW9uLmdldE1lc3NhZ2UoKSk7Ci0gICAgICAgICAgICBwdy5wcmludGxuKCJyb290LWNhdXNlOiIKLSAgICAgICAgICAgICAgICAgICAgICAgKyAoKG51bGwgIT0gY2F1c2UpID8gY2F1c2UuZ2V0TWVzc2FnZSgpIDogIm51bGwiKSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFByaW50IG91dCB0aGUgc3BlY2lmaWMgc291cmNlIGxpbmUgdGhhdCBjYXVzZWQgdGhlIGV4Y2VwdGlvbiwKLSAgICAgKiBpZiBwb3NzaWJsZSB0byBsb2FkIGl0LgotICAgICAqCi0gICAgICogQHBhcmFtIHB3IFByaW50V3JpdGVyIHRvIHNlbmQgb3V0cHV0IHRvCi0gICAgICogQHBhcmFtIGxvY2F0b3IgWGFsYW4gd3JhcHBlciBmb3IgZWl0aGVyIGEgSkFYUCBvciBhIFNBWAotICAgICAqIHNvdXJjZSBsb2NhdGlvbiBvYmplY3QKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIHZvaWQgbG9nU291cmNlTGluZShQcmludFdyaXRlciBwdywgU291cmNlTG9jYXRvciBsb2NhdG9yKQotICAgIHsKLSAgICAgICAgaWYgKG51bGwgPT0gbG9jYXRvcikKLSAgICAgICAgICAgIHJldHVybjsKLQotICAgICAgICBpZiAobnVsbCA9PSBwdykKLSAgICAgICAgICAgIHB3ID0gbmV3IFByaW50V3JpdGVyKFN5c3RlbS5lcnIsIHRydWUpOwotCi0gICAgICAgIFN0cmluZyB1cmwgPSBsb2NhdG9yLmdldFN5c3RlbUlkKCk7Ci0gICAgICAgIC8vIEJhaWwgaW1tZWRpYXRlbHkgaWYgd2UgZ2V0IFN5c3RlbUlkLVVua25vd24KLSAgICAgICAgLy9AdG9kbyBmdXR1cmUgaW1wcm92ZW1lbnQ6IGF0dGVtcHQgdG8gZ2V0IHJlc291cmNlCi0gICAgICAgIC8vICBmcm9tIGEgcHVibGljSWQgaWYgcG9zc2libGUKLSAgICAgICAgaWYgKG51bGwgPT0gdXJsKQotICAgICAgICB7Ci0gICAgICAgICAgICBwdy5wcmludGxuKCJsaW5lOiAoTm8gc3lzdGVtSWQ7IGNhbm5vdCByZWFkIGZpbGUpIik7Ci0gICAgICAgICAgICBwdy5wcmludGxuKCk7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLQotICAgICAgICAvL0B0b2RvIGF0dGVtcHQgdG8gZ2V0IERPTSBiYWNrcG9pbnRlciBvciBvdGhlciBpZHMKLQotICAgICAgICB0cnkKLSAgICAgICAgewotICAgICAgICAgICAgaW50IGxpbmUgPSBsb2NhdG9yLmdldExpbmVOdW1iZXIoKTsKLSAgICAgICAgICAgIGludCBjb2x1bW4gPSBsb2NhdG9yLmdldENvbHVtbk51bWJlcigpOwotICAgICAgICAgICAgcHcucHJpbnRsbigibGluZTogIiArIGdldFNvdXJjZUxpbmUodXJsLCBsaW5lKSk7Ci0gICAgICAgICAgICBTdHJpbmdCdWZmZXIgYnVmID0gbmV3IFN0cmluZ0J1ZmZlcigibGluZTogIik7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMTsgaSA8IGNvbHVtbjsgaSsrKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoJyAnKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGJ1Zi5hcHBlbmQoJ14nKTsKLSAgICAgICAgICAgIHB3LnByaW50bG4oYnVmLnRvU3RyaW5nKCkpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChFeGNlcHRpb24gZSkKLSAgICAgICAgewotICAgICAgICAgICAgcHcucHJpbnRsbigibGluZTogbG9nU291cmNlTGluZSB1bmF2YWlsYWJsZSBkdWUgdG86ICIgKyBlLmdldE1lc3NhZ2UoKSk7Ci0gICAgICAgICAgICBwdy5wcmludGxuKCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFJldHVybiB0aGUgc3BlY2lmaWMgc291cmNlIGxpbmUgdGhhdCBjYXVzZWQgdGhlIGV4Y2VwdGlvbiwKLSAgICAgKiBpZiBwb3NzaWJsZSB0byBsb2FkIGl0OyBhbGxvdyBleGNlcHRpb25zIHRvIGJlIHRocm93bi4KLSAgICAgKgotICAgICAqIEBhdXRob3Igc2hhbmVfY3VyY3VydUB1cy5pYm0uY29tCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBTdHJpbmcgZ2V0U291cmNlTGluZShTdHJpbmcgc291cmNlVXJsLCBpbnQgbGluZU51bSkKLSAgICAgICAgICAgIHRocm93cyBFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIFVSTCB1cmwgPSBudWxsOwotICAgICAgICAvLyBHZXQgYSBVUkwgZnJvbSB0aGUgc291cmNlVXJsCi0gICAgICAgIHRyeQotICAgICAgICB7Ci0gICAgICAgICAgICAvLyBUcnkgdG8gZ2V0IGEgVVJMIGZyb20gaXQgYXMtaXMKLSAgICAgICAgICAgIHVybCA9IG5ldyBVUkwoc291cmNlVXJsKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoamF2YS5uZXQuTWFsZm9ybWVkVVJMRXhjZXB0aW9uIG11ZSkKLSAgICAgICAgewotICAgICAgICAgICAgaW50IGluZGV4T2ZDb2xvbiA9IHNvdXJjZVVybC5pbmRleE9mKCc6Jyk7Ci0gICAgICAgICAgICBpbnQgaW5kZXhPZlNsYXNoID0gc291cmNlVXJsLmluZGV4T2YoJy8nKTsKLQotICAgICAgICAgICAgaWYgKChpbmRleE9mQ29sb24gIT0gLTEpCi0gICAgICAgICAgICAgICAgJiYgKGluZGV4T2ZTbGFzaCAhPSAtMSkKLSAgICAgICAgICAgICAgICAmJiAoaW5kZXhPZkNvbG9uIDwgaW5kZXhPZlNsYXNoKSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAvLyBUaGUgdXJsIGlzIGFscmVhZHkgYWJzb2x1dGUsIGJ1dCB3ZSBjb3VsZCBub3QgZ2V0Ci0gICAgICAgICAgICAgICAgLy8gIHRoZSBzeXN0ZW0gdG8gZm9ybSBpdCwgc28gYmFpbAotICAgICAgICAgICAgICAgIHRocm93IG11ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAvLyBUaGUgdXJsIGlzIHJlbGF0aXZlLCBzbyBhdHRlbXB0IHRvIGdldCBhYnNvbHV0ZQotICAgICAgICAgICAgICAgIHVybCA9IG5ldyBVUkwoU3lzdGVtSURSZXNvbHZlci5nZXRBYnNvbHV0ZVVSSShzb3VyY2VVcmwpKTsKLSAgICAgICAgICAgICAgICAvLyBJZiB0aGlzIGZhaWxzLCBhbGxvdyB0aGUgZXhjZXB0aW9uIHRvIHByb3BhZ2F0ZQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgU3RyaW5nIGxpbmUgPSBudWxsOwotICAgICAgICBJbnB1dFN0cmVhbSBpcyA9IG51bGw7Ci0gICAgICAgIEJ1ZmZlcmVkUmVhZGVyIGJyID0gbnVsbDsKLSAgICAgICAgdHJ5Ci0gICAgICAgIHsKLSAgICAgICAgICAgIC8vIE9wZW4gdGhlIFVSTCBhbmQgcmVhZCB0byBvdXIgc3BlY2lmaWVkIGxpbmUKLSAgICAgICAgICAgIFVSTENvbm5lY3Rpb24gdWMgPSB1cmwub3BlbkNvbm5lY3Rpb24oKTsKLSAgICAgICAgICAgIGlzID0gdWMuZ2V0SW5wdXRTdHJlYW0oKTsKLSAgICAgICAgICAgIGJyID0gbmV3IEJ1ZmZlcmVkUmVhZGVyKG5ldyBJbnB1dFN0cmVhbVJlYWRlcihpcykpOwotCi0gICAgICAgICAgICAvLyBOb3QgdGhlIG1vc3QgZWZmaWNpZW50IHdheSwgYnV0IGl0IHdvcmtzCi0gICAgICAgICAgICAvLyAoRmVlbCBmcmVlIHRvIHBhdGNoIHRvIHNlZWsgdG8gdGhlIGFwcHJvcHJpYXRlIGxpbmUpCi0gICAgICAgICAgICBmb3IgKGludCBpID0gMTsgaSA8PSBsaW5lTnVtOyBpKyspCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgbGluZSA9IGJyLnJlYWRMaW5lKCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgfQotICAgICAgICAvLyBBbGxvdyBleGNlcHRpb25zIHRvIHByb3BhZ2F0ZSBmcm9tIGhlcmUsIGJ1dCBlbnN1cmUKLSAgICAgICAgLy8gIHN0cmVhbXMgYXJlIGNsb3NlZCEKLSAgICAgICAgZmluYWxseQotICAgICAgICB7Ci0gICAgICAgICAgICBici5jbG9zZSgpOwotICAgICAgICAgICAgaXMuY2xvc2UoKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIFJldHVybiB3aGF0ZXZlciB3ZSBmb3VuZAotICAgICAgICByZXR1cm4gbGluZTsKLSAgICB9Ci0KLQotICAgIC8qID09PT09PT09IEltcGxlbWVudCBzZXR0YWJsZSBwcm9wZXJ0aWVzID09PT09PT09ICovCi0KLSAgICAvKioKLSAgICAgKiBVc2VyLXNldHRhYmxlIGJlaGF2aW9yOiB3aGVuIHRvIHJlLXRocm93IGV4Y2VwdGlvbnMuCi0gICAgICoKLSAgICAgKiA8cD5UaGlzIGFsbG93cyBwZXItaW5zdGFuY2UgY29uZmlndXJhdGlvbiBvZgotICAgICAqIExpc3RpbmdFcnJvckhhbmRsZXJzLiAgWW91IGNhbiBhc2sgdXMgdG8gZWl0aGVyIHRocm93Ci0gICAgICogYW4gZXhjZXB0aW9uIHdoZW4gd2UncmUgY2FsbGVkIGZvciB2YXJpb3VzIHdhcm5pbmcgLwotICAgICAqIGVycm9yIC8gZmF0YWxFcnJvcnMsIG9yIHNpbXBseSBsb2cgdGhlbSBhbmQgY29udGludWUuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGIgaWYgd2Ugc2hvdWxkIHRocm93IGFuIGV4Y2VwdGlvbiBvbiB3YXJuaW5ncwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFRocm93T25XYXJuaW5nKGJvb2xlYW4gYikKLSAgICB7Ci0gICAgICAgIHRocm93T25XYXJuaW5nID0gYjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBVc2VyLXNldHRhYmxlIGJlaGF2aW9yOiB3aGVuIHRvIHJlLXRocm93IGV4Y2VwdGlvbnMuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIGlmIHdlIHRocm93IGFuIGV4Y2VwdGlvbiBvbiB3YXJuaW5ncwotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGdldFRocm93T25XYXJuaW5nKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiB0aHJvd09uV2FybmluZzsKLSAgICB9Ci0KLSAgICAvKiogSWYgd2Ugc2hvdWxkIHRocm93IGV4Y2VwdGlvbiBvbiB3YXJuaW5nczsgZGVmYXVsdDpmYWxzZS4gICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gdGhyb3dPbldhcm5pbmcgPSBmYWxzZTsKLQotCi0gICAgLyoqCi0gICAgICogVXNlci1zZXR0YWJsZSBiZWhhdmlvcjogd2hlbiB0byByZS10aHJvdyBleGNlcHRpb25zLgotICAgICAqCi0gICAgICogPHA+VGhpcyBhbGxvd3MgcGVyLWluc3RhbmNlIGNvbmZpZ3VyYXRpb24gb2YKLSAgICAgKiBMaXN0aW5nRXJyb3JIYW5kbGVycy4gIFlvdSBjYW4gYXNrIHVzIHRvIGVpdGhlciB0aHJvdwotICAgICAqIGFuIGV4Y2VwdGlvbiB3aGVuIHdlJ3JlIGNhbGxlZCBmb3IgdmFyaW91cyB3YXJuaW5nIC8KLSAgICAgKiBlcnJvciAvIGZhdGFsRXJyb3JzLCBvciBzaW1wbHkgbG9nIHRoZW0gYW5kIGNvbnRpbnVlLjwvcD4KLSAgICAgKgotICAgICAqIDxwPk5vdGUgdGhhdCB0aGUgYmVoYXZpb3Igb2YgbWFueSBwYXJzZXJzL3RyYW5zZm9ybWVycwotICAgICAqIGFmdGVyIGFuIGVycm9yIGlzIG5vdCBuZWNlc3NhcmlseSBkZWZpbmVkITwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBiIGlmIHdlIHNob3VsZCB0aHJvdyBhbiBleGNlcHRpb24gb24gZXJyb3JzCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0VGhyb3dPbkVycm9yKGJvb2xlYW4gYikKLSAgICB7Ci0gICAgICAgIHRocm93T25FcnJvciA9IGI7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVXNlci1zZXR0YWJsZSBiZWhhdmlvcjogd2hlbiB0byByZS10aHJvdyBleGNlcHRpb25zLgotICAgICAqCi0gICAgICogQHJldHVybiBpZiB3ZSB0aHJvdyBhbiBleGNlcHRpb24gb24gZXJyb3JzCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0VGhyb3dPbkVycm9yKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiB0aHJvd09uRXJyb3I7Ci0gICAgfQotCi0gICAgLyoqIElmIHdlIHNob3VsZCB0aHJvdyBleGNlcHRpb24gb24gZXJyb3JzOyBkZWZhdWx0OnRydWUuICAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIHRocm93T25FcnJvciA9IHRydWU7Ci0KLQotICAgIC8qKgotICAgICAqIFVzZXItc2V0dGFibGUgYmVoYXZpb3I6IHdoZW4gdG8gcmUtdGhyb3cgZXhjZXB0aW9ucy4KLSAgICAgKgotICAgICAqIDxwPlRoaXMgYWxsb3dzIHBlci1pbnN0YW5jZSBjb25maWd1cmF0aW9uIG9mCi0gICAgICogTGlzdGluZ0Vycm9ySGFuZGxlcnMuICBZb3UgY2FuIGFzayB1cyB0byBlaXRoZXIgdGhyb3cKLSAgICAgKiBhbiBleGNlcHRpb24gd2hlbiB3ZSdyZSBjYWxsZWQgZm9yIHZhcmlvdXMgd2FybmluZyAvCi0gICAgICogZXJyb3IgLyBmYXRhbEVycm9ycywgb3Igc2ltcGx5IGxvZyB0aGVtIGFuZCBjb250aW51ZS48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5Ob3RlIHRoYXQgdGhlIGJlaGF2aW9yIG9mIG1hbnkgcGFyc2Vycy90cmFuc2Zvcm1lcnMKLSAgICAgKiBhZnRlciBhIGZhdGFsRXJyb3IgaXMgbm90IG5lY2Vzc2FyaWx5IGRlZmluZWQsIG1vc3QKLSAgICAgKiBwcm9kdWN0cyB3aWxsIHByb2JhYmx5IGJhcmYgaWYgeW91IGNvbnRpbnVlLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBiIGlmIHdlIHNob3VsZCB0aHJvdyBhbiBleGNlcHRpb24gb24gZmF0YWxFcnJvcnMKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRUaHJvd09uRmF0YWxFcnJvcihib29sZWFuIGIpCi0gICAgewotICAgICAgICB0aHJvd09uRmF0YWxFcnJvciA9IGI7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVXNlci1zZXR0YWJsZSBiZWhhdmlvcjogd2hlbiB0byByZS10aHJvdyBleGNlcHRpb25zLgotICAgICAqCi0gICAgICogQHJldHVybiBpZiB3ZSB0aHJvdyBhbiBleGNlcHRpb24gb24gZmF0YWxFcnJvcnMKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXRUaHJvd09uRmF0YWxFcnJvcigpCi0gICAgewotICAgICAgICByZXR1cm4gdGhyb3dPbkZhdGFsRXJyb3I7Ci0gICAgfQotCi0gICAgLyoqIElmIHdlIHNob3VsZCB0aHJvdyBleGNlcHRpb24gb24gZmF0YWxFcnJvcnM7IGRlZmF1bHQ6dHJ1ZS4gICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gdGhyb3dPbkZhdGFsRXJyb3IgPSB0cnVlOwotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9Mb2NhbGVVdGlsaXR5LmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9Mb2NhbGVVdGlsaXR5LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDBhNWMzNTkuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvTG9jYWxlVXRpbGl0eS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsODggKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLQotCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IExvY2FsZVV0aWxpdHkuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNSAwODoxNTo0NyBzdXJlc2hfZW1haWxpZCBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlsczsKLQotaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7Ci0KLS8qKgotICogQGF1dGhvciBJZ29yIEhlcnNodCwgaWdvcmhAY2EuaWJtLmNvbQotICovCi1wdWJsaWMgY2xhc3MgTG9jYWxlVXRpbGl0eSB7Ci0gICAgLyoqCi0gICAgICogSUVURiBSRkMgMTc2NiB0YWcgc2VwYXJhdG9yCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIHN0YXRpYyBjaGFyIElFVEZfU0VQQVJBVE9SID0gJy0nOwotICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgU3RyaW5nIEVNUFRZX1NUUklORyA9ICIiOwotCi0KLSBwdWJsaWMgc3RhdGljIExvY2FsZSBsYW5nVG9Mb2NhbGUoU3RyaW5nIGxhbmcpIHsKLSAgICAgICBpZigobGFuZyA9PSBudWxsKSB8fCBsYW5nLmVxdWFscyhFTVBUWV9TVFJJTkcpKXsgLy8gbm90IHNwZWNpZmllZCA9PiBnZXREZWZhdWx0Ci0gICAgICAgICAgICByZXR1cm4gTG9jYWxlLmdldERlZmF1bHQoKTsKLSAgICAgICB9Ci0gICAgICAgIFN0cmluZyBsYW5ndWFnZSA9IEVNUFRZX1NUUklORzsKLSAgICAgICAgU3RyaW5nIGNvdW50cnkgPSAgRU1QVFlfU1RSSU5HOwotICAgICAgICBTdHJpbmcgdmFyaWFudCA9ICBFTVBUWV9TVFJJTkc7Ci0KLSAgICAgICAgaW50IGkxID0gbGFuZy5pbmRleE9mKElFVEZfU0VQQVJBVE9SKTsKLSAgICAgICAgaWYgKGkxIDwgMCkgewotICAgICAgICAgICAgbGFuZ3VhZ2UgPSBsYW5nOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgbGFuZ3VhZ2UgPSBsYW5nLnN1YnN0cmluZygwLCBpMSk7Ci0gICAgICAgICAgICArK2kxOwotICAgICAgICAgICAgaW50IGkyID0gbGFuZy5pbmRleE9mKElFVEZfU0VQQVJBVE9SLCBpMSk7Ci0gICAgICAgICAgICBpZiAoaTIgPCAwKSB7Ci0gICAgICAgICAgICAgICAgY291bnRyeSA9IGxhbmcuc3Vic3RyaW5nKGkxKTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgY291bnRyeSA9IGxhbmcuc3Vic3RyaW5nKGkxLCBpMik7Ci0gICAgICAgICAgICAgICAgdmFyaWFudCA9IGxhbmcuc3Vic3RyaW5nKGkyKzEpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgaWYobGFuZ3VhZ2UubGVuZ3RoKCkgPT0gMil7Ci0gICAgICAgICAgIGxhbmd1YWdlID0gbGFuZ3VhZ2UudG9Mb3dlckNhc2UoKTsKLSAgICAgICAgfWVsc2UgewotICAgICAgICAgIGxhbmd1YWdlID0gRU1QVFlfU1RSSU5HOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYoY291bnRyeS5sZW5ndGgoKSA9PSAyKXsKLSAgICAgICAgICAgY291bnRyeSA9IGNvdW50cnkudG9VcHBlckNhc2UoKTsKLSAgICAgICAgfWVsc2UgewotICAgICAgICAgIGNvdW50cnkgPSBFTVBUWV9TVFJJTkc7Ci0gICAgICAgIH0KLQotICAgICAgICBpZigodmFyaWFudC5sZW5ndGgoKSA+IDApICYmCi0gICAgICAgICgobGFuZ3VhZ2UubGVuZ3RoKCkgPT0gMikgfHwoY291bnRyeS5sZW5ndGgoKSA9PSAyKSkpewotICAgICAgICAgICB2YXJpYW50ID0gdmFyaWFudC50b1VwcGVyQ2FzZSgpOwotICAgICAgICB9ZWxzZXsKLSAgICAgICAgICAgIHZhcmlhbnQgPSBFTVBUWV9TVFJJTkc7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gbmV3IExvY2FsZShsYW5ndWFnZSwgY291bnRyeSwgdmFyaWFudCApOwotICAgIH0KLQotCi0KLSB9CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9NdXRhYmxlQXR0ckxpc3RJbXBsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9NdXRhYmxlQXR0ckxpc3RJbXBsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGU0NGQ4YjAuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvTXV0YWJsZUF0dHJMaXN0SW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTQxICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IE11dGFibGVBdHRyTGlzdEltcGwuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNSAwODoxNTo0NyBzdXJlc2hfZW1haWxpZCBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHM7Ci0KLWltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKLQotaW1wb3J0IG9yZy54bWwuc2F4LkF0dHJpYnV0ZXM7Ci1pbXBvcnQgb3JnLnhtbC5zYXguaGVscGVycy5BdHRyaWJ1dGVzSW1wbDsKLQotLyoqCi0gKiBNdXRhYmxlIHZlcnNpb24gb2YgQXR0cmlidXRlc0ltcGwuCi0gKiBAeHNsLnVzYWdlIGFkdmFuY2VkCi0gKi8KLXB1YmxpYyBjbGFzcyBNdXRhYmxlQXR0ckxpc3RJbXBsIGV4dGVuZHMgQXR0cmlidXRlc0ltcGwKLSAgICAgICAgaW1wbGVtZW50cyBTZXJpYWxpemFibGUKLXsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNjI4OTQ1MjAxMzQ0MjkzNDQ3MEw7Ci0KLS8qKgotICogQ29uc3RydWN0IGEgbmV3LCBlbXB0eSBBdHRyaWJ1dGVzSW1wbCBvYmplY3QuCi0gKi8KLQotcHVibGljIE11dGFibGVBdHRyTGlzdEltcGwoKQotICB7Ci0gICAgc3VwZXIoKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb3B5IGFuIGV4aXN0aW5nIEF0dHJpYnV0ZXMgb2JqZWN0LgotICAgKgotICAgKiA8cD5UaGlzIGNvbnN0cnVjdG9yIGlzIGVzcGVjaWFsbHkgdXNlZnVsIGluc2lkZSBhIHN0YXJ0Ci0gICAqIGVsZW1lbnQgZXZlbnQuPC9wPgotICAgKgotICAgKiBAcGFyYW0gYXR0cyBUaGUgZXhpc3RpbmcgQXR0cmlidXRlcyBvYmplY3QuCi0gICAqLwotICBwdWJsaWMgTXV0YWJsZUF0dHJMaXN0SW1wbChBdHRyaWJ1dGVzIGF0dHMpCi0gIHsKLSAgICBzdXBlcihhdHRzKTsKLSAgfQotCi0gIC8qKgotICAgKiBBZGQgYW4gYXR0cmlidXRlIHRvIHRoZSBlbmQgb2YgdGhlIGxpc3QuCi0gICAqCi0gICAqIDxwPkZvciB0aGUgc2FrZSBvZiBzcGVlZCwgdGhpcyBtZXRob2QgZG9lcyBubyBjaGVja2luZwotICAgKiB0byBzZWUgaWYgdGhlIGF0dHJpYnV0ZSBpcyBhbHJlYWR5IGluIHRoZSBsaXN0OiB0aGF0IGlzCi0gICAqIHRoZSByZXNwb25zaWJpbGl0eSBvZiB0aGUgYXBwbGljYXRpb24uPC9wPgotICAgKgotICAgKiBAcGFyYW0gdXJpIFRoZSBOYW1lc3BhY2UgVVJJLCBvciB0aGUgZW1wdHkgc3RyaW5nIGlmCi0gICAqICAgICAgICBub25lIGlzIGF2YWlsYWJsZSBvciBOYW1lc3BhY2UgcHJvY2Vzc2luZyBpcyBub3QKLSAgICogICAgICAgIGJlaW5nIHBlcmZvcm1lZC4KLSAgICogQHBhcmFtIGxvY2FsTmFtZSBUaGUgbG9jYWwgbmFtZSwgb3IgdGhlIGVtcHR5IHN0cmluZyBpZgotICAgKiAgICAgICAgTmFtZXNwYWNlIHByb2Nlc3NpbmcgaXMgbm90IGJlaW5nIHBlcmZvcm1lZC4KLSAgICogQHBhcmFtIHFOYW1lIFRoZSBxdWFsaWZpZWQgKHByZWZpeGVkKSBuYW1lLCBvciB0aGUgZW1wdHkgc3RyaW5nCi0gICAqICAgICAgICBpZiBxdWFsaWZpZWQgbmFtZXMgYXJlIG5vdCBhdmFpbGFibGUuCi0gICAqIEBwYXJhbSB0eXBlIFRoZSBhdHRyaWJ1dGUgdHlwZSBhcyBhIHN0cmluZy4KLSAgICogQHBhcmFtIHZhbHVlIFRoZSBhdHRyaWJ1dGUgdmFsdWUuCi0gICAqLwotICBwdWJsaWMgdm9pZCBhZGRBdHRyaWJ1dGUoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSwgU3RyaW5nIHFOYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHR5cGUsIFN0cmluZyB2YWx1ZSkKLSAgewotCi0gICAgaWYgKG51bGwgPT0gdXJpKQotICAgICAgdXJpID0gIiI7Ci0KLSAgICAvLyBnZXRJbmRleChxTmFtZSkgc2VlbXMgdG8gYmUgbW9yZSByZWxpYWJsZSB0aGFuIGdldEluZGV4KHVyaSwgbG9jYWxOYW1lKSwKLSAgICAvLyBpbiB0aGUgY2FzZSBvZiB0aGUgeG1sbnMgYXR0cmlidXRlIGFueXdheS4KLSAgICBpbnQgaW5kZXggPSB0aGlzLmdldEluZGV4KHFOYW1lKTsKLSAgICAvLyBpbnQgaW5kZXggPSB0aGlzLmdldEluZGV4KHVyaSwgbG9jYWxOYW1lKTsKLQotICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiTXV0YWJsZUF0dHJMaXN0SW1wbCNhZGRBdHRyaWJ1dGU6ICIrdXJpKyI6Iitsb2NhbE5hbWUrIiwgIitpbmRleCsiLCAiK3FOYW1lKyIsICIrdGhpcyk7Ci0KLSAgICBpZiAoaW5kZXggPj0gMCkKLSAgICAgIHRoaXMuc2V0QXR0cmlidXRlKGluZGV4LCB1cmksIGxvY2FsTmFtZSwgcU5hbWUsIHR5cGUsIHZhbHVlKTsKLSAgICBlbHNlCi0gICAgICBzdXBlci5hZGRBdHRyaWJ1dGUodXJpLCBsb2NhbE5hbWUsIHFOYW1lLCB0eXBlLCB2YWx1ZSk7Ci0gIH0KLQotICAvKioKLSAgICogQWRkIHRoZSBjb250ZW50cyBvZiB0aGUgYXR0cmlidXRlIGxpc3QgdG8gdGhpcyBsaXN0LgotICAgKgotICAgKiBAcGFyYW0gYXR0cyBMaXN0IG9mIGF0dHJpYnV0ZXMgdG8gYWRkIHRvIHRoaXMgbGlzdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWRkQXR0cmlidXRlcyhBdHRyaWJ1dGVzIGF0dHMpCi0gIHsKLQotICAgIGludCBuQXR0cyA9IGF0dHMuZ2V0TGVuZ3RoKCk7Ci0KLSAgICBmb3IgKGludCBpID0gMDsgaSA8IG5BdHRzOyBpKyspCi0gICAgewotICAgICAgU3RyaW5nIHVyaSA9IGF0dHMuZ2V0VVJJKGkpOwotCi0gICAgICBpZiAobnVsbCA9PSB1cmkpCi0gICAgICAgIHVyaSA9ICIiOwotCi0gICAgICBTdHJpbmcgbG9jYWxOYW1lID0gYXR0cy5nZXRMb2NhbE5hbWUoaSk7Ci0gICAgICBTdHJpbmcgcW5hbWUgPSBhdHRzLmdldFFOYW1lKGkpOwotICAgICAgaW50IGluZGV4ID0gdGhpcy5nZXRJbmRleCh1cmksIGxvY2FsTmFtZSk7Ci0gICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIk11dGFibGVBdHRyTGlzdEltcGwjYWRkQXR0cmlidXRlczogIit1cmkrIjoiK2xvY2FsTmFtZSsiLCAiK2luZGV4KyIsICIrYXR0cy5nZXRRTmFtZShpKSsiLCAiK3RoaXMpOwotICAgICAgaWYgKGluZGV4ID49IDApCi0gICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKGluZGV4LCB1cmksIGxvY2FsTmFtZSwgcW5hbWUsIGF0dHMuZ2V0VHlwZShpKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0cy5nZXRWYWx1ZShpKSk7Ci0gICAgICBlbHNlCi0gICAgICAgIGFkZEF0dHJpYnV0ZSh1cmksIGxvY2FsTmFtZSwgcW5hbWUsIGF0dHMuZ2V0VHlwZShpKSwKLSAgICAgICAgICAgICAgICAgICAgIGF0dHMuZ2V0VmFsdWUoaSkpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdHJ1ZSBpZiBsaXN0IGNvbnRhaW5zIHRoZSBnaXZlbiAocmF3KSBhdHRyaWJ1dGUgbmFtZS4KLSAgICoKLSAgICogQHBhcmFtIG5hbWUgUmF3IG5hbWUgb2YgYXR0cmlidXRlIHRvIGxvb2sgZm9yCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiBhbiBhdHRyaWJ1dGUgaXMgZm91bmQgd2l0aCB0aGlzIG5hbWUKLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKFN0cmluZyBuYW1lKQotICB7Ci0gICAgcmV0dXJuIGdldFZhbHVlKG5hbWUpICE9IG51bGw7Ci0gIH0KLX0KLQotLy8gZW5kIG9mIE11dGFibGVBdHRyTGlzdEltcGwuamF2YQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvTlNJbmZvLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9OU0luZm8uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNzM4ODZlYS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9OU0luZm8uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExMiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBOU0luZm8uamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNSAwODoxNTo0OCBzdXJlc2hfZW1haWxpZCBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHM7Ci0KLS8qKgotICogVGhpcyBjbGFzcyBob2xkcyBpbmZvcm1hdGlvbiBhYm91dCB0aGUgbmFtZXNwYWNlIGluZm8KLSAqIG9mIGEgbm9kZS4gIEl0IGlzIHVzZWQgdG8gb3B0aW1pemUgbmFtZXNwYWNlIGxvb2t1cCBpbgotICogYSBnZW5lcmljIERPTS4KLSAqIEB4c2wudXNhZ2UgaW50ZXJuYWwKLSAqLwotcHVibGljIGNsYXNzIE5TSW5mbwotewotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3RvciBOU0luZm8KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIGhhc1Byb2Nlc3NlZE5TIEZsYWcgaW5kaWNhdGluZyB3aGV0aGVyIG5hbWVzcGFjZXMKLSAgICogaGF2ZSBiZWVuIHByb2Nlc3NlZCBmb3IgdGhpcyBub2RlCi0gICAqIEBwYXJhbSBoYXNYTUxOU0F0dHJzIEZsYWcgaW5kaWNhdGluZyB3aGV0aGVyIHRoaXMgbm9kZQotICAgKiBoYXMgWE1MTlMgYXR0cmlidXRlcy4KLSAgICovCi0gIHB1YmxpYyBOU0luZm8oYm9vbGVhbiBoYXNQcm9jZXNzZWROUywgYm9vbGVhbiBoYXNYTUxOU0F0dHJzKQotICB7Ci0KLSAgICBtX2hhc1Byb2Nlc3NlZE5TID0gaGFzUHJvY2Vzc2VkTlM7Ci0gICAgbV9oYXNYTUxOU0F0dHJzID0gaGFzWE1MTlNBdHRyczsKLSAgICBtX25hbWVzcGFjZSA9IG51bGw7Ci0gICAgbV9hbmNlc3Rvckhhc1hNTE5TQXR0cnMgPSBBTkNFU1RPUlhNTE5TVU5QUk9DRVNTRUQ7Ci0gIH0KLQotICAvLyBVbnVzZWQgYXQgdGhlIG1vbWVudAotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3RvciBOU0luZm8KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIGhhc1Byb2Nlc3NlZE5TIEZsYWcgaW5kaWNhdGluZyB3aGV0aGVyIG5hbWVzcGFjZXMKLSAgICogaGF2ZSBiZWVuIHByb2Nlc3NlZCBmb3IgdGhpcyBub2RlCi0gICAqIEBwYXJhbSBoYXNYTUxOU0F0dHJzIEZsYWcgaW5kaWNhdGluZyB3aGV0aGVyIHRoaXMgbm9kZQotICAgKiBoYXMgWE1MTlMgYXR0cmlidXRlcy4KLSAgICogQHBhcmFtIGFuY2VzdG9ySGFzWE1MTlNBdHRycyBGbGFnIGluZGljYXRpbmcgd2hldGhlciBvbmUgb2YgdGhpcyBub2RlJ3MKLSAgICogYW5jZXN0b3IgaGFzIFhNTE5TIGF0dHJpYnV0ZXMuCi0gICAqLwotICBwdWJsaWMgTlNJbmZvKGJvb2xlYW4gaGFzUHJvY2Vzc2VkTlMsIGJvb2xlYW4gaGFzWE1MTlNBdHRycywKLSAgICAgICAgICAgICAgICBpbnQgYW5jZXN0b3JIYXNYTUxOU0F0dHJzKQotICB7Ci0KLSAgICBtX2hhc1Byb2Nlc3NlZE5TID0gaGFzUHJvY2Vzc2VkTlM7Ci0gICAgbV9oYXNYTUxOU0F0dHJzID0gaGFzWE1MTlNBdHRyczsKLSAgICBtX2FuY2VzdG9ySGFzWE1MTlNBdHRycyA9IGFuY2VzdG9ySGFzWE1MTlNBdHRyczsKLSAgICBtX25hbWVzcGFjZSA9IG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0b3IgTlNJbmZvCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lc3BhY2UgVGhlIG5hbWVzcGFjZSBVUkkKLSAgICogQHBhcmFtIGhhc1hNTE5TQXR0cnMgRmxhZyBpbmRpY2F0aW5nIHdoZXRoZXIgdGhpcyBub2RlCi0gICAqIGhhcyBYTUxOUyBhdHRyaWJ1dGVzLgotICAgKi8KLSAgcHVibGljIE5TSW5mbyhTdHJpbmcgbmFtZXNwYWNlLCBib29sZWFuIGhhc1hNTE5TQXR0cnMpCi0gIHsKLQotICAgIG1faGFzUHJvY2Vzc2VkTlMgPSB0cnVlOwotICAgIG1faGFzWE1MTlNBdHRycyA9IGhhc1hNTE5TQXR0cnM7Ci0gICAgbV9uYW1lc3BhY2UgPSBuYW1lc3BhY2U7Ci0gICAgbV9hbmNlc3Rvckhhc1hNTE5TQXR0cnMgPSBBTkNFU1RPUlhNTE5TVU5QUk9DRVNTRUQ7Ci0gIH0KLQotICAvKiogVGhlIG5hbWVzcGFjZSBVUkkgICAgICAgICAgKi8KLSAgcHVibGljIFN0cmluZyBtX25hbWVzcGFjZTsKLQotICAvKiogRmxhZyBpbmRpY2F0aW5nIHdoZXRoZXIgdGhpcyBub2RlIGhhcyBhbiBYTUxOUyBhdHRyaWJ1dGUgICAgICAgICAgKi8KLSAgcHVibGljIGJvb2xlYW4gbV9oYXNYTUxOU0F0dHJzOwotCi0gIC8qKiBGbGFnIGluZGljYXRpbmcgd2hldGhlciBuYW1lc3BhY2VzIGhhdmUgYmVlbiBwcm9jZXNzZWQgZm9yIHRoaXMgbm9kZSAqLwotICBwdWJsaWMgYm9vbGVhbiBtX2hhc1Byb2Nlc3NlZE5TOwotCi0gIC8qKiBGbGFnIGluZGljYXRpbmcgd2hldGhlciBvbmUgb2YgdGhpcyBub2RlJ3MgYW5jZXN0b3IgaGFzIGFuIFhNTE5TIGF0dHJpYnV0ZSAgICAgICAgICAqLwotICBwdWJsaWMgaW50IG1fYW5jZXN0b3JIYXNYTUxOU0F0dHJzOwotCi0gIC8qKiBDb25zdGFudCBmb3IgYW5jZXN0b3JzIFhNTE5TIGF0cmlidXRlcyBub3QgcHJvY2Vzc2VkICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFOQ0VTVE9SWE1MTlNVTlBST0NFU1NFRCA9IDA7Ci0KLSAgLyoqIENvbnN0YW50IGluZGljYXRpbmcgYW4gYW5jZXN0b3IgaGFzIGFuIFhNTE5TIGF0dHJpYnV0ZSAgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQU5DRVNUT1JIQVNYTUxOUyA9IDE7Ci0KLSAgLyoqIENvbnN0YW50IGluZGljYXRpbmcgYW5jZXN0b3JzIGRvbid0IGhhdmUgYW4gWE1MTlMgYXR0cmlidXRlICAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBTkNFU1RPUk5PWE1MTlMgPSAyOwotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvTmFtZVNwYWNlLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9OYW1lU3BhY2UuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYjI2MmU0My4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9OYW1lU3BhY2UuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDYxICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IE5hbWVTcGFjZS5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE1IDA4OjE1OjQ5IHN1cmVzaF9lbWFpbGlkIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlsczsKLQotaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOwotCi0vKioKLSAqIEEgcmVwcmVzZW50YXRpb24gb2YgYSBuYW1lc3BhY2UuICBPbmUgb2YgdGhlc2Ugd2lsbAotICogYmUgcHVzaGVkIG9uIHRoZSBuYW1lc3BhY2Ugc3RhY2sgZm9yIGVhY2gKLSAqIGVsZW1lbnQuCi0gKiBAeHNsLnVzYWdlIGFkdmFuY2VkCi0gKi8KLXB1YmxpYyBjbGFzcyBOYW1lU3BhY2UgaW1wbGVtZW50cyBTZXJpYWxpemFibGUKLXsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMTQ3MTIzMjkzOTE4NDg4MTgzOUw7Ci0KLSAgLyoqIE5leHQgTmFtZVNwYWNlIGVsZW1lbnQgb24gdGhlIHN0YWNrLgotICAgKiAgQHNlcmlhbCAgICAgICAgICAgICAqLwotICBwdWJsaWMgTmFtZVNwYWNlIG1fbmV4dCA9IG51bGw7Ci0KLSAgLyoqIFByZWZpeCBvZiB0aGlzIE5hbWVTcGFjZSBlbGVtZW50LgotICAgKiAgQHNlcmlhbCAgICAgICAgICAqLwotICBwdWJsaWMgU3RyaW5nIG1fcHJlZml4OwotCi0gIC8qKiBOYW1lc3BhY2UgVVJJIG9mIHRoaXMgTmFtZVNwYWNlIGVsZW1lbnQuCi0gICAqICBAc2VyaWFsICAgICAgICAgICAqLwotICBwdWJsaWMgU3RyaW5nIG1fdXJpOyAgLy8gaWYgbnVsbCwgdGhlbiBFbGVtZW50IG5hbWVzcGFjZSBpcyBlbXB0eS4KLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgbmFtZXNwYWNlIGZvciBwbGFjZW1lbnQgb24gdGhlCi0gICAqIHJlc3VsdCB0cmVlIG5hbWVzcGFjZSBzdGFjay4KLSAgICoKLSAgICogQHBhcmFtIHByZWZpeCBQcmVmaXggb2YgdGhpcyBlbGVtZW50Ci0gICAqIEBwYXJhbSB1cmkgVVJJIG9mICB0aGlzIGVsZW1lbnQKLSAgICovCi0gIHB1YmxpYyBOYW1lU3BhY2UoU3RyaW5nIHByZWZpeCwgU3RyaW5nIHVyaSkKLSAgewotICAgIG1fcHJlZml4ID0gcHJlZml4OwotICAgIG1fdXJpID0gdXJpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9Ob2RlQ29uc3VtZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL05vZGVDb25zdW1lci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmMGIzNmJjLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL05vZGVDb25zdW1lci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDIgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogTm9kZUNvbnN1bWVyLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTUgMDg6MTU6NTAgc3VyZXNoX2VtYWlsaWQgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzOwotCi1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLQotLyoqCi0gKiBUaGUgdHJlZSB3YWxrZXIgd2lsbCB0ZXN0IGZvciB0aGlzIGludGVyZmFjZSwgYW5kIGNhbGwKLSAqIHNldE9yaWdpbmF0aW5nTm9kZSBiZWZvcmUgY2FsbGluZyB0aGUgU0FYIGV2ZW50LiAgRm9yIGNyZWF0aW5nCi0gKiBET00gYmFja3BvaW50ZXJzIGZvciB0aGluZ3MgdGhhdCBhcmUgbm9ybWFsbHkgY3JlYXRlZCB2aWEKLSAqIFNBWCBldmVudHMuCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgTm9kZUNvbnN1bWVyCi17Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgbm9kZSB0aGF0IGlzIG9yaWdpbmF0aW5nIHRoZSBTQVggZXZlbnQuCi0gICAqCi0gICAqIEBwYXJhbSBuIFJlZmVyZW5jZSB0byBub2RlIHRoYXQgb3JpZ2luYXRlZCB0aGUgY3VycmVudCBldmVudC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldE9yaWdpbmF0aW5nTm9kZShOb2RlIG4pOwotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvTm9kZVZlY3Rvci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvTm9kZVZlY3Rvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4YmJhNmQ1Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL05vZGVWZWN0b3IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDc0MSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBOb2RlVmVjdG9yLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTUgMDg6MTU6NTAgc3VyZXNoX2VtYWlsaWQgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzOwotCi1pbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE07Ci0KLS8qKgotICogQSB2ZXJ5IHNpbXBsZSB0YWJsZSB0aGF0IHN0b3JlcyBhIGxpc3Qgb2YgTm9kZXMuCi0gKiBAeHNsLnVzYWdlIGludGVybmFsCi0gKi8KLXB1YmxpYyBjbGFzcyBOb2RlVmVjdG9yIGltcGxlbWVudHMgU2VyaWFsaXphYmxlLCBDbG9uZWFibGUKLXsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTcxMzQ3MzA5MjIwMDczMTg3MEw7Ci0KLSAgLyoqCi0gICAqIFNpemUgb2YgYmxvY2tzIHRvIGFsbG9jYXRlLgotICAgKiAgQHNlcmlhbAotICAgKi8KLSAgcHJpdmF0ZSBpbnQgbV9ibG9ja3NpemU7Ci0KLSAgLyoqCi0gICAqIEFycmF5IG9mIG5vZGVzIHRoaXMgcG9pbnRzIHRvLgotICAgKiAgQHNlcmlhbAotICAgKi8KLSAgcHJpdmF0ZSBpbnQgbV9tYXBbXTsKLQotICAvKioKLSAgICogTnVtYmVyIG9mIG5vZGVzIGluIHRoaXMgTm9kZVZlY3Rvci4KLSAgICogIEBzZXJpYWwKLSAgICovCi0gIHByb3RlY3RlZCBpbnQgbV9maXJzdEZyZWUgPSAwOwotCi0gIC8qKgotICAgKiBTaXplIG9mIHRoZSBhcnJheSB0aGlzIHBvaW50cyB0by4KLSAgICogIEBzZXJpYWwKLSAgICovCi0gIHByaXZhdGUgaW50IG1fbWFwU2l6ZTsgIC8vIGxhenkgaW5pdGlhbGl6YXRpb24KLQotICAvKioKLSAgICogRGVmYXVsdCBjb25zdHJ1Y3Rvci4KLSAgICovCi0gIHB1YmxpYyBOb2RlVmVjdG9yKCkKLSAgewotICAgIG1fYmxvY2tzaXplID0gMzI7Ci0gICAgbV9tYXBTaXplID0gMDsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBOb2RlVmVjdG9yLCB1c2luZyB0aGUgZ2l2ZW4gYmxvY2sgc2l6ZS4KLSAgICoKLSAgICogQHBhcmFtIGJsb2Nrc2l6ZSBTaXplIG9mIGJsb2NrcyB0byBhbGxvY2F0ZQotICAgKi8KLSAgcHVibGljIE5vZGVWZWN0b3IoaW50IGJsb2Nrc2l6ZSkKLSAgewotICAgIG1fYmxvY2tzaXplID0gYmxvY2tzaXplOwotICAgIG1fbWFwU2l6ZSA9IDA7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IGEgY2xvbmVkIExvY1BhdGhJdGVyYXRvci4KLSAgICoKLSAgICogQHJldHVybiBBIGNsb25lIG9mIHRoaXMKLSAgICoKLSAgICogQHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIE9iamVjdCBjbG9uZSgpIHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbgotICB7Ci0KLSAgICBOb2RlVmVjdG9yIGNsb25lID0gKE5vZGVWZWN0b3IpIHN1cGVyLmNsb25lKCk7Ci0KLSAgICBpZiAoKG51bGwgIT0gdGhpcy5tX21hcCkgJiYgKHRoaXMubV9tYXAgPT0gY2xvbmUubV9tYXApKQotICAgIHsKLSAgICAgIGNsb25lLm1fbWFwID0gbmV3IGludFt0aGlzLm1fbWFwLmxlbmd0aF07Ci0KLSAgICAgIFN5c3RlbS5hcnJheWNvcHkodGhpcy5tX21hcCwgMCwgY2xvbmUubV9tYXAsIDAsIHRoaXMubV9tYXAubGVuZ3RoKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gY2xvbmU7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBsZW5ndGggb2YgdGhlIGxpc3QuCi0gICAqCi0gICAqIEByZXR1cm4gTnVtYmVyIG9mIG5vZGVzIGluIHRoaXMgTm9kZVZlY3RvcgotICAgKi8KLSAgcHVibGljIGludCBzaXplKCkKLSAgewotICAgIHJldHVybiBtX2ZpcnN0RnJlZTsKLSAgfQotCi0gIC8qKgotICAgKiBBcHBlbmQgYSBOb2RlIG9udG8gdGhlIHZlY3Rvci4KLSAgICoKLSAgICogQHBhcmFtIHZhbHVlIE5vZGUgdG8gYWRkIHRvIHRoZSB2ZWN0b3IKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFkZEVsZW1lbnQoaW50IHZhbHVlKQotICB7Ci0KLSAgICBpZiAoKG1fZmlyc3RGcmVlICsgMSkgPj0gbV9tYXBTaXplKQotICAgIHsKLSAgICAgIGlmIChudWxsID09IG1fbWFwKQotICAgICAgewotICAgICAgICBtX21hcCA9IG5ldyBpbnRbbV9ibG9ja3NpemVdOwotICAgICAgICBtX21hcFNpemUgPSBtX2Jsb2Nrc2l6ZTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgbV9tYXBTaXplICs9IG1fYmxvY2tzaXplOwotCi0gICAgICAgIGludCBuZXdNYXBbXSA9IG5ldyBpbnRbbV9tYXBTaXplXTsKLQotICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KG1fbWFwLCAwLCBuZXdNYXAsIDAsIG1fZmlyc3RGcmVlICsgMSk7Ci0KLSAgICAgICAgbV9tYXAgPSBuZXdNYXA7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgbV9tYXBbbV9maXJzdEZyZWVdID0gdmFsdWU7Ci0KLSAgICBtX2ZpcnN0RnJlZSsrOwotICB9Ci0KLSAgLyoqCi0gICAqIEFwcGVuZCBhIE5vZGUgb250byB0aGUgdmVjdG9yLgotICAgKgotICAgKiBAcGFyYW0gdmFsdWUgTm9kZSB0byBhZGQgdG8gdGhlIHZlY3RvcgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgcHVzaChpbnQgdmFsdWUpCi0gIHsKLQotICAgIGludCBmZiA9IG1fZmlyc3RGcmVlOwotCi0gICAgaWYgKChmZiArIDEpID49IG1fbWFwU2l6ZSkKLSAgICB7Ci0gICAgICBpZiAobnVsbCA9PSBtX21hcCkKLSAgICAgIHsKLSAgICAgICAgbV9tYXAgPSBuZXcgaW50W21fYmxvY2tzaXplXTsKLSAgICAgICAgbV9tYXBTaXplID0gbV9ibG9ja3NpemU7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIG1fbWFwU2l6ZSArPSBtX2Jsb2Nrc2l6ZTsKLQotICAgICAgICBpbnQgbmV3TWFwW10gPSBuZXcgaW50W21fbWFwU2l6ZV07Ci0KLSAgICAgICAgU3lzdGVtLmFycmF5Y29weShtX21hcCwgMCwgbmV3TWFwLCAwLCBmZiArIDEpOwotCi0gICAgICAgIG1fbWFwID0gbmV3TWFwOwotICAgICAgfQotICAgIH0KLQotICAgIG1fbWFwW2ZmXSA9IHZhbHVlOwotCi0gICAgZmYrKzsKLQotICAgIG1fZmlyc3RGcmVlID0gZmY7Ci0gIH0KLQotICAvKioKLSAgICogUG9wIGEgbm9kZSBmcm9tIHRoZSB0YWlsIG9mIHRoZSB2ZWN0b3IgYW5kIHJldHVybiB0aGUgcmVzdWx0LgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBub2RlIGF0IHRoZSB0YWlsIG9mIHRoZSB2ZWN0b3IKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBpbnQgcG9wKCkKLSAgewotCi0gICAgbV9maXJzdEZyZWUtLTsKLQotICAgIGludCBuID0gbV9tYXBbbV9maXJzdEZyZWVdOwotCi0gICAgbV9tYXBbbV9maXJzdEZyZWVdID0gRFRNLk5VTEw7Ci0KLSAgICByZXR1cm4gbjsKLSAgfQotCi0gIC8qKgotICAgKiBQb3AgYSBub2RlIGZyb20gdGhlIHRhaWwgb2YgdGhlIHZlY3RvciBhbmQgcmV0dXJuIHRoZQotICAgKiB0b3Agb2YgdGhlIHN0YWNrIGFmdGVyIHRoZSBwb3AuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHRvcCBvZiB0aGUgc3RhY2sgYWZ0ZXIgaXQncyBiZWVuIHBvcHBlZAotICAgKi8KLSAgcHVibGljIGZpbmFsIGludCBwb3BBbmRUb3AoKQotICB7Ci0KLSAgICBtX2ZpcnN0RnJlZS0tOwotCi0gICAgbV9tYXBbbV9maXJzdEZyZWVdID0gRFRNLk5VTEw7Ci0KLSAgICByZXR1cm4gKG1fZmlyc3RGcmVlID09IDApID8gRFRNLk5VTEwgOiBtX21hcFttX2ZpcnN0RnJlZSAtIDFdOwotICB9Ci0KLSAgLyoqCi0gICAqIFBvcCBhIG5vZGUgZnJvbSB0aGUgdGFpbCBvZiB0aGUgdmVjdG9yLgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgcG9wUXVpY2soKQotICB7Ci0KLSAgICBtX2ZpcnN0RnJlZS0tOwotCi0gICAgbV9tYXBbbV9maXJzdEZyZWVdID0gRFRNLk5VTEw7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBub2RlIGF0IHRoZSB0b3Agb2YgdGhlIHN0YWNrIHdpdGhvdXQgcG9wcGluZyB0aGUgc3RhY2suCi0gICAqIFNwZWNpYWwgcHVycG9zZSBtZXRob2QgZm9yIFRyYW5zZm9ybWVySW1wbCwgcHVzaEVsZW1UZW1wbGF0ZUVsZW1lbnQuCi0gICAqIFBlcmZvcm1hbmNlIGNyaXRpY2FsLgotICAgKgotICAgKiBAcmV0dXJuIE5vZGUgYXQgdGhlIHRvcCBvZiB0aGUgc3RhY2sgb3IgbnVsbCBpZiBzdGFjayBpcyBlbXB0eS4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBpbnQgcGVlcE9yTnVsbCgpCi0gIHsKLSAgICByZXR1cm4gKChudWxsICE9IG1fbWFwKSAmJiAobV9maXJzdEZyZWUgPiAwKSkKLSAgICAgICAgICAgPyBtX21hcFttX2ZpcnN0RnJlZSAtIDFdIDogRFRNLk5VTEw7Ci0gIH0KLQotICAvKioKLSAgICogUHVzaCBhIHBhaXIgb2Ygbm9kZXMgaW50byB0aGUgc3RhY2suCi0gICAqIFNwZWNpYWwgcHVycG9zZSBtZXRob2QgZm9yIFRyYW5zZm9ybWVySW1wbCwgcHVzaEVsZW1UZW1wbGF0ZUVsZW1lbnQuCi0gICAqIFBlcmZvcm1hbmNlIGNyaXRpY2FsLgotICAgKgotICAgKiBAcGFyYW0gdjEgRmlyc3Qgbm9kZSB0byBhZGQgdG8gdmVjdG9yCi0gICAqIEBwYXJhbSB2MiBTZWNvbmQgbm9kZSB0byBhZGQgdG8gdmVjdG9yCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBwdXNoUGFpcihpbnQgdjEsIGludCB2MikKLSAgewotCi0gICAgaWYgKG51bGwgPT0gbV9tYXApCi0gICAgewotICAgICAgbV9tYXAgPSBuZXcgaW50W21fYmxvY2tzaXplXTsKLSAgICAgIG1fbWFwU2l6ZSA9IG1fYmxvY2tzaXplOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgaWYgKChtX2ZpcnN0RnJlZSArIDIpID49IG1fbWFwU2l6ZSkKLSAgICAgIHsKLSAgICAgICAgbV9tYXBTaXplICs9IG1fYmxvY2tzaXplOwotCi0gICAgICAgIGludCBuZXdNYXBbXSA9IG5ldyBpbnRbbV9tYXBTaXplXTsKLQotICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KG1fbWFwLCAwLCBuZXdNYXAsIDAsIG1fZmlyc3RGcmVlKTsKLQotICAgICAgICBtX21hcCA9IG5ld01hcDsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICBtX21hcFttX2ZpcnN0RnJlZV0gPSB2MTsKLSAgICBtX21hcFttX2ZpcnN0RnJlZSArIDFdID0gdjI7Ci0gICAgbV9maXJzdEZyZWUgKz0gMjsKLSAgfQotCi0gIC8qKgotICAgKiBQb3AgYSBwYWlyIG9mIG5vZGVzIGZyb20gdGhlIHRhaWwgb2YgdGhlIHN0YWNrLgotICAgKiBTcGVjaWFsIHB1cnBvc2UgbWV0aG9kIGZvciBUcmFuc2Zvcm1lckltcGwsIHB1c2hFbGVtVGVtcGxhdGVFbGVtZW50LgotICAgKiBQZXJmb3JtYW5jZSBjcml0aWNhbC4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHBvcFBhaXIoKQotICB7Ci0KLSAgICBtX2ZpcnN0RnJlZSAtPSAyOwotICAgIG1fbWFwW21fZmlyc3RGcmVlXSA9IERUTS5OVUxMOwotICAgIG1fbWFwW21fZmlyc3RGcmVlICsgMV0gPSBEVE0uTlVMTDsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIHRhaWwgb2YgdGhlIHN0YWNrIHRvIHRoZSBnaXZlbiBub2RlLgotICAgKiBTcGVjaWFsIHB1cnBvc2UgbWV0aG9kIGZvciBUcmFuc2Zvcm1lckltcGwsIHB1c2hFbGVtVGVtcGxhdGVFbGVtZW50LgotICAgKiBQZXJmb3JtYW5jZSBjcml0aWNhbC4KLSAgICoKLSAgICogQHBhcmFtIG4gTm9kZSB0byBzZXQgYXQgdGhlIHRhaWwgb2YgdmVjdG9yCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBzZXRUYWlsKGludCBuKQotICB7Ci0gICAgbV9tYXBbbV9maXJzdEZyZWUgLSAxXSA9IG47Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBnaXZlbiBub2RlIG9uZSBwb3NpdGlvbiBmcm9tIHRoZSB0YWlsLgotICAgKiBTcGVjaWFsIHB1cnBvc2UgbWV0aG9kIGZvciBUcmFuc2Zvcm1lckltcGwsIHB1c2hFbGVtVGVtcGxhdGVFbGVtZW50LgotICAgKiBQZXJmb3JtYW5jZSBjcml0aWNhbC4KLSAgICoKLSAgICogQHBhcmFtIG4gTm9kZSB0byBzZXQKLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHNldFRhaWxTdWIxKGludCBuKQotICB7Ci0gICAgbV9tYXBbbV9maXJzdEZyZWUgLSAyXSA9IG47Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBub2RlIGF0IHRoZSB0YWlsIG9mIHRoZSB2ZWN0b3Igd2l0aG91dCBwb3BwaW5nCi0gICAqIFNwZWNpYWwgcHVycG9zZSBtZXRob2QgZm9yIFRyYW5zZm9ybWVySW1wbCwgcHVzaEVsZW1UZW1wbGF0ZUVsZW1lbnQuCi0gICAqIFBlcmZvcm1hbmNlIGNyaXRpY2FsLgotICAgKgotICAgKiBAcmV0dXJuIE5vZGUgYXQgdGhlIHRhaWwgb2YgdGhlIHZlY3RvcgotICAgKi8KLSAgcHVibGljIGZpbmFsIGludCBwZWVwVGFpbCgpCi0gIHsKLSAgICByZXR1cm4gbV9tYXBbbV9maXJzdEZyZWUgLSAxXTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIG5vZGUgb25lIHBvc2l0aW9uIGZyb20gdGhlIHRhaWwgd2l0aG91dCBwb3BwaW5nLgotICAgKiBTcGVjaWFsIHB1cnBvc2UgbWV0aG9kIGZvciBUcmFuc2Zvcm1lckltcGwsIHB1c2hFbGVtVGVtcGxhdGVFbGVtZW50LgotICAgKiBQZXJmb3JtYW5jZSBjcml0aWNhbC4KLSAgICoKLSAgICogQHJldHVybiBOb2RlIG9uZSBhd2F5IGZyb20gdGhlIHRhaWwKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBpbnQgcGVlcFRhaWxTdWIxKCkKLSAgewotICAgIHJldHVybiBtX21hcFttX2ZpcnN0RnJlZSAtIDJdOwotICB9Ci0KLSAgLyoqCi0gICAqIEluc2VydCBhIG5vZGUgaW4gb3JkZXIgaW4gdGhlIGxpc3QuCi0gICAqCi0gICAqIEBwYXJhbSB2YWx1ZSBOb2RlIHRvIGluc2VydAotICAgKi8KLSAgcHVibGljIHZvaWQgaW5zZXJ0SW5PcmRlcihpbnQgdmFsdWUpCi0gIHsKLQotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbV9maXJzdEZyZWU7IGkrKykKLSAgICB7Ci0gICAgICBpZiAodmFsdWUgPCBtX21hcFtpXSkKLSAgICAgIHsKLSAgICAgICAgaW5zZXJ0RWxlbWVudEF0KHZhbHVlLCBpKTsKLQotICAgICAgICByZXR1cm47Ci0gICAgICB9Ci0gICAgfQotCi0gICAgYWRkRWxlbWVudCh2YWx1ZSk7Ci0gIH0KLQotICAvKioKLSAgICogSW5zZXJ0cyB0aGUgc3BlY2lmaWVkIG5vZGUgaW4gdGhpcyB2ZWN0b3IgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4KLSAgICogRWFjaCBjb21wb25lbnQgaW4gdGhpcyB2ZWN0b3Igd2l0aCBhbiBpbmRleCBncmVhdGVyIG9yIGVxdWFsIHRvCi0gICAqIHRoZSBzcGVjaWZpZWQgaW5kZXggaXMgc2hpZnRlZCB1cHdhcmQgdG8gaGF2ZSBhbiBpbmRleCBvbmUgZ3JlYXRlcgotICAgKiB0aGFuIHRoZSB2YWx1ZSBpdCBoYWQgcHJldmlvdXNseS4KLSAgICoKLSAgICogQHBhcmFtIHZhbHVlIE5vZGUgdG8gaW5zZXJ0Ci0gICAqIEBwYXJhbSBhdCBQb3NpdGlvbiB3aGVyZSB0byBpbnNlcnQKLSAgICovCi0gIHB1YmxpYyB2b2lkIGluc2VydEVsZW1lbnRBdChpbnQgdmFsdWUsIGludCBhdCkKLSAgewotCi0gICAgaWYgKG51bGwgPT0gbV9tYXApCi0gICAgewotICAgICAgbV9tYXAgPSBuZXcgaW50W21fYmxvY2tzaXplXTsKLSAgICAgIG1fbWFwU2l6ZSA9IG1fYmxvY2tzaXplOwotICAgIH0KLSAgICBlbHNlIGlmICgobV9maXJzdEZyZWUgKyAxKSA+PSBtX21hcFNpemUpCi0gICAgewotICAgICAgbV9tYXBTaXplICs9IG1fYmxvY2tzaXplOwotCi0gICAgICBpbnQgbmV3TWFwW10gPSBuZXcgaW50W21fbWFwU2l6ZV07Ci0KLSAgICAgIFN5c3RlbS5hcnJheWNvcHkobV9tYXAsIDAsIG5ld01hcCwgMCwgbV9maXJzdEZyZWUgKyAxKTsKLQotICAgICAgbV9tYXAgPSBuZXdNYXA7Ci0gICAgfQotCi0gICAgaWYgKGF0IDw9IChtX2ZpcnN0RnJlZSAtIDEpKQotICAgIHsKLSAgICAgIFN5c3RlbS5hcnJheWNvcHkobV9tYXAsIGF0LCBtX21hcCwgYXQgKyAxLCBtX2ZpcnN0RnJlZSAtIGF0KTsKLSAgICB9Ci0KLSAgICBtX21hcFthdF0gPSB2YWx1ZTsKLQotICAgIG1fZmlyc3RGcmVlKys7Ci0gIH0KLQotICAvKioKLSAgICogQXBwZW5kIHRoZSBub2RlcyB0byB0aGUgbGlzdC4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVzIE5vZGVWZWN0b3IgdG8gYXBwZW5kIHRvIHRoaXMgbGlzdAotICAgKi8KLSAgcHVibGljIHZvaWQgYXBwZW5kTm9kZXMoTm9kZVZlY3RvciBub2RlcykKLSAgewotCi0gICAgaW50IG5Ob2RlcyA9IG5vZGVzLnNpemUoKTsKLQotICAgIGlmIChudWxsID09IG1fbWFwKQotICAgIHsKLSAgICAgIG1fbWFwU2l6ZSA9IG5Ob2RlcyArIG1fYmxvY2tzaXplOwotICAgICAgbV9tYXAgPSBuZXcgaW50W21fbWFwU2l6ZV07Ci0gICAgfQotICAgIGVsc2UgaWYgKChtX2ZpcnN0RnJlZSArIG5Ob2RlcykgPj0gbV9tYXBTaXplKQotICAgIHsKLSAgICAgIG1fbWFwU2l6ZSArPSAobk5vZGVzICsgbV9ibG9ja3NpemUpOwotCi0gICAgICBpbnQgbmV3TWFwW10gPSBuZXcgaW50W21fbWFwU2l6ZV07Ci0KLSAgICAgIFN5c3RlbS5hcnJheWNvcHkobV9tYXAsIDAsIG5ld01hcCwgMCwgbV9maXJzdEZyZWUgKyBuTm9kZXMpOwotCi0gICAgICBtX21hcCA9IG5ld01hcDsKLSAgICB9Ci0KLSAgICBTeXN0ZW0uYXJyYXljb3B5KG5vZGVzLm1fbWFwLCAwLCBtX21hcCwgbV9maXJzdEZyZWUsIG5Ob2Rlcyk7Ci0KLSAgICBtX2ZpcnN0RnJlZSArPSBuTm9kZXM7Ci0gIH0KLQotICAvKioKLSAgICogSW5zZXJ0cyB0aGUgc3BlY2lmaWVkIG5vZGUgaW4gdGhpcyB2ZWN0b3IgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4KLSAgICogRWFjaCBjb21wb25lbnQgaW4gdGhpcyB2ZWN0b3Igd2l0aCBhbiBpbmRleCBncmVhdGVyIG9yIGVxdWFsIHRvCi0gICAqIHRoZSBzcGVjaWZpZWQgaW5kZXggaXMgc2hpZnRlZCB1cHdhcmQgdG8gaGF2ZSBhbiBpbmRleCBvbmUgZ3JlYXRlcgotICAgKiB0aGFuIHRoZSB2YWx1ZSBpdCBoYWQgcHJldmlvdXNseS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHJlbW92ZUFsbEVsZW1lbnRzKCkKLSAgewotCi0gICAgaWYgKG51bGwgPT0gbV9tYXApCi0gICAgICByZXR1cm47Ci0KLSAgICBmb3IgKGludCBpID0gMDsgaSA8IG1fZmlyc3RGcmVlOyBpKyspCi0gICAgewotICAgICAgbV9tYXBbaV0gPSBEVE0uTlVMTDsKLSAgICB9Ci0KLSAgICBtX2ZpcnN0RnJlZSA9IDA7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBsZW5ndGggdG8gemVybywgYnV0IGRvbid0IGNsZWFyIHRoZSBhcnJheS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIFJlbW92ZUFsbE5vQ2xlYXIoKQotICB7Ci0KLSAgICBpZiAobnVsbCA9PSBtX21hcCkKLSAgICAgIHJldHVybjsKLQotICAgIG1fZmlyc3RGcmVlID0gMDsKLSAgfQotCi0gIC8qKgotICAgKiBSZW1vdmVzIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZSBhcmd1bWVudCBmcm9tIHRoaXMgdmVjdG9yLgotICAgKiBJZiB0aGUgb2JqZWN0IGlzIGZvdW5kIGluIHRoaXMgdmVjdG9yLCBlYWNoIGNvbXBvbmVudCBpbiB0aGUgdmVjdG9yCi0gICAqIHdpdGggYW4gaW5kZXggZ3JlYXRlciBvciBlcXVhbCB0byB0aGUgb2JqZWN0J3MgaW5kZXggaXMgc2hpZnRlZAotICAgKiBkb3dud2FyZCB0byBoYXZlIGFuIGluZGV4IG9uZSBzbWFsbGVyIHRoYW4gdGhlIHZhbHVlIGl0IGhhZAotICAgKiBwcmV2aW91c2x5LgotICAgKgotICAgKiBAcGFyYW0gcyBOb2RlIHRvIHJlbW92ZSBmcm9tIHRoZSBsaXN0Ci0gICAqCi0gICAqIEByZXR1cm4gVHJ1ZSBpZiB0aGUgbm9kZSB3YXMgc3VjY2Vzc2Z1bGx5IHJlbW92ZWQKLSAgICovCi0gIHB1YmxpYyBib29sZWFuIHJlbW92ZUVsZW1lbnQoaW50IHMpCi0gIHsKLQotICAgIGlmIChudWxsID09IG1fbWFwKQotICAgICAgcmV0dXJuIGZhbHNlOwotCi0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtX2ZpcnN0RnJlZTsgaSsrKQotICAgIHsKLSAgICAgIGludCBub2RlID0gbV9tYXBbaV07Ci0KLSAgICAgIGlmIChub2RlID09IHMpCi0gICAgICB7Ci0gICAgICAgIGlmIChpID4gbV9maXJzdEZyZWUpCi0gICAgICAgICAgU3lzdGVtLmFycmF5Y29weShtX21hcCwgaSArIDEsIG1fbWFwLCBpIC0gMSwgbV9maXJzdEZyZWUgLSBpKTsKLSAgICAgICAgZWxzZQotICAgICAgICAgIG1fbWFwW2ldID0gRFRNLk5VTEw7Ci0KLSAgICAgICAgbV9maXJzdEZyZWUtLTsKLQotICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gZmFsc2U7Ci0gIH0KLQotICAvKioKLSAgICogRGVsZXRlcyB0aGUgY29tcG9uZW50IGF0IHRoZSBzcGVjaWZpZWQgaW5kZXguIEVhY2ggY29tcG9uZW50IGluCi0gICAqIHRoaXMgdmVjdG9yIHdpdGggYW4gaW5kZXggZ3JlYXRlciBvciBlcXVhbCB0byB0aGUgc3BlY2lmaWVkCi0gICAqIGluZGV4IGlzIHNoaWZ0ZWQgZG93bndhcmQgdG8gaGF2ZSBhbiBpbmRleCBvbmUgc21hbGxlciB0aGFuCi0gICAqIHRoZSB2YWx1ZSBpdCBoYWQgcHJldmlvdXNseS4KLSAgICoKLSAgICogQHBhcmFtIGkgSW5kZXggb2Ygbm9kZSB0byByZW1vdmUKLSAgICovCi0gIHB1YmxpYyB2b2lkIHJlbW92ZUVsZW1lbnRBdChpbnQgaSkKLSAgewotCi0gICAgaWYgKG51bGwgPT0gbV9tYXApCi0gICAgICByZXR1cm47Ci0KLSAgICBpZiAoaSA+IG1fZmlyc3RGcmVlKQotICAgICAgU3lzdGVtLmFycmF5Y29weShtX21hcCwgaSArIDEsIG1fbWFwLCBpIC0gMSwgbV9maXJzdEZyZWUgLSBpKTsKLSAgICBlbHNlCi0gICAgICBtX21hcFtpXSA9IERUTS5OVUxMOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldHMgdGhlIGNvbXBvbmVudCBhdCB0aGUgc3BlY2lmaWVkIGluZGV4IG9mIHRoaXMgdmVjdG9yIHRvIGJlIHRoZQotICAgKiBzcGVjaWZpZWQgb2JqZWN0LiBUaGUgcHJldmlvdXMgY29tcG9uZW50IGF0IHRoYXQgcG9zaXRpb24gaXMgZGlzY2FyZGVkLgotICAgKgotICAgKiBUaGUgaW5kZXggbXVzdCBiZSBhIHZhbHVlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAwIGFuZCBsZXNzCi0gICAqIHRoYW4gdGhlIGN1cnJlbnQgc2l6ZSBvZiB0aGUgdmVjdG9yLgotICAgKgotICAgKiBAcGFyYW0gbm9kZSBOb2RlIHRvIHNldAotICAgKiBAcGFyYW0gaW5kZXggSW5kZXggb2Ygd2hlcmUgdG8gc2V0IHRoZSBub2RlCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRFbGVtZW50QXQoaW50IG5vZGUsIGludCBpbmRleCkKLSAgewotCi0gICAgaWYgKG51bGwgPT0gbV9tYXApCi0gICAgewotICAgICAgbV9tYXAgPSBuZXcgaW50W21fYmxvY2tzaXplXTsKLSAgICAgIG1fbWFwU2l6ZSA9IG1fYmxvY2tzaXplOwotICAgIH0KLQotICAgIGlmKGluZGV4ID09IC0xKQotICAgICAgICBhZGRFbGVtZW50KG5vZGUpOwotCi0gICAgbV9tYXBbaW5kZXhdID0gbm9kZTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIG50aCBlbGVtZW50LgotICAgKgotICAgKiBAcGFyYW0gaSBJbmRleCBvZiBub2RlIHRvIGdldAotICAgKgotICAgKiBAcmV0dXJuIE5vZGUgYXQgc3BlY2lmaWVkIGluZGV4Ci0gICAqLwotICBwdWJsaWMgaW50IGVsZW1lbnRBdChpbnQgaSkKLSAgewotCi0gICAgaWYgKG51bGwgPT0gbV9tYXApCi0gICAgICByZXR1cm4gRFRNLk5VTEw7Ci0KLSAgICByZXR1cm4gbV9tYXBbaV07Ci0gIH0KLQotICAvKioKLSAgICogVGVsbCBpZiB0aGUgdGFibGUgY29udGFpbnMgdGhlIGdpdmVuIG5vZGUuCi0gICAqCi0gICAqIEBwYXJhbSBzIE5vZGUgdG8gbG9vayBmb3IKLSAgICoKLSAgICogQHJldHVybiBUcnVlIGlmIHRoZSBnaXZlbiBub2RlIHdhcyBmb3VuZC4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKGludCBzKQotICB7Ci0KLSAgICBpZiAobnVsbCA9PSBtX21hcCkKLSAgICAgIHJldHVybiBmYWxzZTsKLQotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbV9maXJzdEZyZWU7IGkrKykKLSAgICB7Ci0gICAgICBpbnQgbm9kZSA9IG1fbWFwW2ldOwotCi0gICAgICBpZiAobm9kZSA9PSBzKQotICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICB9Ci0KLSAgICByZXR1cm4gZmFsc2U7Ci0gIH0KLQotICAvKioKLSAgICogU2VhcmNoZXMgZm9yIHRoZSBmaXJzdCBvY2N1cmVuY2Ugb2YgdGhlIGdpdmVuIGFyZ3VtZW50LAotICAgKiBiZWdpbm5pbmcgdGhlIHNlYXJjaCBhdCBpbmRleCwgYW5kIHRlc3RpbmcgZm9yIGVxdWFsaXR5Ci0gICAqIHVzaW5nIHRoZSBlcXVhbHMgbWV0aG9kLgotICAgKgotICAgKiBAcGFyYW0gZWxlbSBOb2RlIHRvIGxvb2sgZm9yCi0gICAqIEBwYXJhbSBpbmRleCBJbmRleCBvZiB3aGVyZSB0byBzdGFydCB0aGUgc2VhcmNoCi0gICAqIEByZXR1cm4gdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZSBvYmplY3QKLSAgICogYXJndW1lbnQgaW4gdGhpcyB2ZWN0b3IgYXQgcG9zaXRpb24gaW5kZXggb3IgbGF0ZXIgaW4gdGhlCi0gICAqIHZlY3RvcjsgcmV0dXJucyAtMSBpZiB0aGUgb2JqZWN0IGlzIG5vdCBmb3VuZC4KLSAgICovCi0gIHB1YmxpYyBpbnQgaW5kZXhPZihpbnQgZWxlbSwgaW50IGluZGV4KQotICB7Ci0KLSAgICBpZiAobnVsbCA9PSBtX21hcCkKLSAgICAgIHJldHVybiAtMTsKLQotICAgIGZvciAoaW50IGkgPSBpbmRleDsgaSA8IG1fZmlyc3RGcmVlOyBpKyspCi0gICAgewotICAgICAgaW50IG5vZGUgPSBtX21hcFtpXTsKLQotICAgICAgaWYgKG5vZGUgPT0gZWxlbSkKLSAgICAgICAgcmV0dXJuIGk7Ci0gICAgfQotCi0gICAgcmV0dXJuIC0xOwotICB9Ci0KLSAgLyoqCi0gICAqIFNlYXJjaGVzIGZvciB0aGUgZmlyc3Qgb2NjdXJlbmNlIG9mIHRoZSBnaXZlbiBhcmd1bWVudCwKLSAgICogYmVnaW5uaW5nIHRoZSBzZWFyY2ggYXQgaW5kZXgsIGFuZCB0ZXN0aW5nIGZvciBlcXVhbGl0eQotICAgKiB1c2luZyB0aGUgZXF1YWxzIG1ldGhvZC4KLSAgICoKLSAgICogQHBhcmFtIGVsZW0gTm9kZSB0byBsb29rIGZvcgotICAgKiBAcmV0dXJuIHRoZSBpbmRleCBvZiB0aGUgZmlyc3Qgb2NjdXJyZW5jZSBvZiB0aGUgb2JqZWN0Ci0gICAqIGFyZ3VtZW50IGluIHRoaXMgdmVjdG9yIGF0IHBvc2l0aW9uIGluZGV4IG9yIGxhdGVyIGluIHRoZQotICAgKiB2ZWN0b3I7IHJldHVybnMgLTEgaWYgdGhlIG9iamVjdCBpcyBub3QgZm91bmQuCi0gICAqLwotICBwdWJsaWMgaW50IGluZGV4T2YoaW50IGVsZW0pCi0gIHsKLQotICAgIGlmIChudWxsID09IG1fbWFwKQotICAgICAgcmV0dXJuIC0xOwotCi0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtX2ZpcnN0RnJlZTsgaSsrKQotICAgIHsKLSAgICAgIGludCBub2RlID0gbV9tYXBbaV07Ci0KLSAgICAgIGlmIChub2RlID09IGVsZW0pCi0gICAgICAgIHJldHVybiBpOwotICAgIH0KLQotICAgIHJldHVybiAtMTsKLSAgfQotCi0gIC8qKgotICAgKiBTb3J0IGFuIGFycmF5IHVzaW5nIGEgcXVpY2tzb3J0IGFsZ29yaXRobS4KLSAgICoKLSAgICogQHBhcmFtIGEgVGhlIGFycmF5IHRvIGJlIHNvcnRlZC4KLSAgICogQHBhcmFtIGxvMCAgVGhlIGxvdyBpbmRleC4KLSAgICogQHBhcmFtIGhpMCAgVGhlIGhpZ2ggaW5kZXguCi0gICAqCi0gICAqIEB0aHJvd3MgRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBzb3J0KGludCBhW10sIGludCBsbzAsIGludCBoaTApIHRocm93cyBFeGNlcHRpb24KLSAgewotCi0gICAgaW50IGxvID0gbG8wOwotICAgIGludCBoaSA9IGhpMDsKLQotICAgIC8vIHBhdXNlKGxvLCBoaSk7Ci0gICAgaWYgKGxvID49IGhpKQotICAgIHsKLSAgICAgIHJldHVybjsKLSAgICB9Ci0gICAgZWxzZSBpZiAobG8gPT0gaGkgLSAxKQotICAgIHsKLQotICAgICAgLyoKLSAgICAgICAqICBzb3J0IGEgdHdvIGVsZW1lbnQgbGlzdCBieSBzd2FwcGluZyBpZiBuZWNlc3NhcnkKLSAgICAgICAqLwotICAgICAgaWYgKGFbbG9dID4gYVtoaV0pCi0gICAgICB7Ci0gICAgICAgIGludCBUID0gYVtsb107Ci0KLSAgICAgICAgYVtsb10gPSBhW2hpXTsKLSAgICAgICAgYVtoaV0gPSBUOwotICAgICAgfQotCi0gICAgICByZXR1cm47Ci0gICAgfQotCi0gICAgLyoKLSAgICAgKiAgUGljayBhIHBpdm90IGFuZCBtb3ZlIGl0IG91dCBvZiB0aGUgd2F5Ci0gICAgICovCi0gICAgaW50IHBpdm90ID0gYVsobG8gKyBoaSkgLyAyXTsKLQotICAgIGFbKGxvICsgaGkpIC8gMl0gPSBhW2hpXTsKLSAgICBhW2hpXSA9IHBpdm90OwotCi0gICAgd2hpbGUgKGxvIDwgaGkpCi0gICAgewotCi0gICAgICAvKgotICAgICAgICogIFNlYXJjaCBmb3J3YXJkIGZyb20gYVtsb10gdW50aWwgYW4gZWxlbWVudCBpcyBmb3VuZCB0aGF0Ci0gICAgICAgKiAgaXMgZ3JlYXRlciB0aGFuIHRoZSBwaXZvdCBvciBsbyA+PSBoaQotICAgICAgICovCi0gICAgICB3aGlsZSAoYVtsb10gPD0gcGl2b3QgJiYgbG8gPCBoaSkKLSAgICAgIHsKLSAgICAgICAgbG8rKzsKLSAgICAgIH0KLQotICAgICAgLyoKLSAgICAgICAqICBTZWFyY2ggYmFja3dhcmQgZnJvbSBhW2hpXSB1bnRpbCBlbGVtZW50IGlzIGZvdW5kIHRoYXQKLSAgICAgICAqICBpcyBsZXNzIHRoYW4gdGhlIHBpdm90LCBvciBsbyA+PSBoaQotICAgICAgICovCi0gICAgICB3aGlsZSAocGl2b3QgPD0gYVtoaV0gJiYgbG8gPCBoaSkKLSAgICAgIHsKLSAgICAgICAgaGktLTsKLSAgICAgIH0KLQotICAgICAgLyoKLSAgICAgICAqICBTd2FwIGVsZW1lbnRzIGFbbG9dIGFuZCBhW2hpXQotICAgICAgICovCi0gICAgICBpZiAobG8gPCBoaSkKLSAgICAgIHsKLSAgICAgICAgaW50IFQgPSBhW2xvXTsKLQotICAgICAgICBhW2xvXSA9IGFbaGldOwotICAgICAgICBhW2hpXSA9IFQ7Ci0KLSAgICAgICAgLy8gcGF1c2UoKTsKLSAgICAgIH0KLQotICAgICAgLy8gaWYgKHN0b3BSZXF1ZXN0ZWQpIHsKLSAgICAgIC8vICAgIHJldHVybjsKLSAgICAgIC8vIH0KLSAgICB9Ci0KLSAgICAvKgotICAgICAqICBQdXQgdGhlIG1lZGlhbiBpbiB0aGUgImNlbnRlciIgb2YgdGhlIGxpc3QKLSAgICAgKi8KLSAgICBhW2hpMF0gPSBhW2hpXTsKLSAgICBhW2hpXSA9IHBpdm90OwotCi0gICAgLyoKLSAgICAgKiAgUmVjdXJzaXZlIGNhbGxzLCBlbGVtZW50cyBhW2xvMF0gdG8gYVtsby0xXSBhcmUgbGVzcyB0aGFuIG9yCi0gICAgICogIGVxdWFsIHRvIHBpdm90LCBlbGVtZW50cyBhW2hpKzFdIHRvIGFbaGkwXSBhcmUgZ3JlYXRlciB0aGFuCi0gICAgICogIHBpdm90LgotICAgICAqLwotICAgIHNvcnQoYSwgbG8wLCBsbyAtIDEpOwotICAgIHNvcnQoYSwgaGkgKyAxLCBoaTApOwotICB9Ci0KLSAgLyoqCi0gICAqIFNvcnQgYW4gYXJyYXkgdXNpbmcgYSBxdWlja3NvcnQgYWxnb3JpdGhtLgotICAgKgotICAgKiBAdGhyb3dzIEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgc29ydCgpIHRocm93cyBFeGNlcHRpb24KLSAgewotICAgIHNvcnQobV9tYXAsIDAsIG1fZmlyc3RGcmVlIC0gMSk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL09iamVjdFBvb2wuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL09iamVjdFBvb2wuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZmI3NWJjNC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9PYmplY3RQb29sLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNzUgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogT2JqZWN0UG9vbC5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE1IDA4OjE1OjUwIHN1cmVzaF9lbWFpbGlkIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlsczsKLQotaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnJlcy5YTUxFcnJvclJlc291cmNlczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnJlcy5YTUxNZXNzYWdlczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwudXRpbHMuT2JqZWN0RmFjdG9yeTsKLQotCi0vKioKLSAqIFBvb2wgb2Ygb2JqZWN0IG9mIGEgZ2l2ZW4gdHlwZSB0byBwaWNrIGZyb20gdG8gaGVscCBtZW1vcnkgdXNhZ2UKLSAqIEB4c2wudXNhZ2UgaW50ZXJuYWwKLSAqLwotcHVibGljIGNsYXNzIE9iamVjdFBvb2wgaW1wbGVtZW50cyBqYXZhLmlvLlNlcmlhbGl6YWJsZQotewotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtODUxOTAxMzY5MTY2MDkzNjY0M0w7Ci0KLSAgLyoqIFR5cGUgb2Ygb2JqZWN0cyBpbiB0aGlzIHBvb2wuCi0gICAqICBAc2VyaWFsICAgICAgICAgICovCi0gIHByaXZhdGUgZmluYWwgQ2xhc3Mgb2JqZWN0VHlwZTsKLQotICAvKiogU3RhY2sgb2YgZ2l2ZW4gb2JqZWN0cyB0aGlzIHBvaW50cyB0by4KLSAgICogIEBzZXJpYWwgICAgICAgICAgKi8KLSAgcHJpdmF0ZSBmaW5hbCBBcnJheUxpc3QgZnJlZVN0YWNrOwotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3RvciBPYmplY3RQb29sCi0gICAqCi0gICAqIEBwYXJhbSB0eXBlIFR5cGUgb2Ygb2JqZWN0cyBmb3IgdGhpcyBwb29sCi0gICAqLwotICBwdWJsaWMgT2JqZWN0UG9vbChDbGFzcyB0eXBlKQotICB7Ci0gICAgb2JqZWN0VHlwZSA9IHR5cGU7Ci0gICAgZnJlZVN0YWNrID0gbmV3IEFycmF5TGlzdCgpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdG9yIE9iamVjdFBvb2wKLSAgICoKLSAgICogQHBhcmFtIGNsYXNzTmFtZSBGdWxseSBxdWFsaWZpZWQgbmFtZSBvZiB0aGUgdHlwZSBvZiBvYmplY3RzIGZvciB0aGlzIHBvb2wuCi0gICAqLwotICBwdWJsaWMgT2JqZWN0UG9vbChTdHJpbmcgY2xhc3NOYW1lKQotICB7Ci0gICAgdHJ5Ci0gICAgewotICAgICAgb2JqZWN0VHlwZSA9IE9iamVjdEZhY3RvcnkuZmluZFByb3ZpZGVyQ2xhc3MoY2xhc3NOYW1lLCB0cnVlKTsKLSAgICB9Ci0gICAgY2F0Y2goQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBjbmZlKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBXcmFwcGVkUnVudGltZUV4Y2VwdGlvbihjbmZlKTsKLSAgICB9Ci0gICAgZnJlZVN0YWNrID0gbmV3IEFycmF5TGlzdCgpOwotICB9Ci0KLQotICAvKioKLSAgICogQ29uc3RydWN0b3IgT2JqZWN0UG9vbAotICAgKgotICAgKgotICAgKiBAcGFyYW0gdHlwZSBUeXBlIG9mIG9iamVjdHMgZm9yIHRoaXMgcG9vbAotICAgKiBAcGFyYW0gc2l6ZSBTaXplIG9mIHZlY3RvciB0byBhbGxvY2F0ZQotICAgKi8KLSAgcHVibGljIE9iamVjdFBvb2woQ2xhc3MgdHlwZSwgaW50IHNpemUpCi0gIHsKLSAgICBvYmplY3RUeXBlID0gdHlwZTsKLSAgICBmcmVlU3RhY2sgPSBuZXcgQXJyYXlMaXN0KHNpemUpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdG9yIE9iamVjdFBvb2wKLSAgICoKLSAgICovCi0gIHB1YmxpYyBPYmplY3RQb29sKCkKLSAgewotICAgIG9iamVjdFR5cGUgPSBudWxsOwotICAgIGZyZWVTdGFjayA9IG5ldyBBcnJheUxpc3QoKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgYW4gaW5zdGFuY2Ugb2YgdGhlIGdpdmVuIG9iamVjdCBpbiB0aGlzIHBvb2wgaWYgYXZhaWxhYmxlCi0gICAqCi0gICAqCi0gICAqIEByZXR1cm4gYW4gaW5zdGFuY2Ugb2YgdGhlIGdpdmVuIG9iamVjdCBpZiBhdmFpbGFibGUgb3IgbnVsbAotICAgKi8KLSAgcHVibGljIHN5bmNocm9uaXplZCBPYmplY3QgZ2V0SW5zdGFuY2VJZkZyZWUoKQotICB7Ci0KLSAgICAvLyBDaGVjayBpZiB0aGUgcG9vbCBpcyBlbXB0eS4KLSAgICBpZiAoIWZyZWVTdGFjay5pc0VtcHR5KCkpCi0gICAgewotCi0gICAgICAvLyBSZW1vdmUgb2JqZWN0IGZyb20gZW5kIG9mIGZyZWUgcG9vbC4KLSAgICAgIE9iamVjdCByZXN1bHQgPSBmcmVlU3RhY2sucmVtb3ZlKGZyZWVTdGFjay5zaXplKCkgLSAxKTsKLSAgICAgIHJldHVybiByZXN1bHQ7Ci0gICAgfQotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IGFuIGluc3RhbmNlIG9mIHRoZSBnaXZlbiBvYmplY3QgaW4gdGhpcyBwb29sCi0gICAqCi0gICAqCi0gICAqIEByZXR1cm4gQW4gaW5zdGFuY2Ugb2YgdGhlIGdpdmVuIG9iamVjdAotICAgKi8KLSAgcHVibGljIHN5bmNocm9uaXplZCBPYmplY3QgZ2V0SW5zdGFuY2UoKQotICB7Ci0KLSAgICAvLyBDaGVjayBpZiB0aGUgcG9vbCBpcyBlbXB0eS4KLSAgICBpZiAoZnJlZVN0YWNrLmlzRW1wdHkoKSkKLSAgICB7Ci0KLSAgICAgIC8vIENyZWF0ZSBhIG5ldyBvYmplY3QgaWYgc28uCi0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgcmV0dXJuIG9iamVjdFR5cGUubmV3SW5zdGFuY2UoKTsKLSAgICAgIH0KLSAgICAgIGNhdGNoIChJbnN0YW50aWF0aW9uRXhjZXB0aW9uIGV4KXt9Ci0gICAgICBjYXRjaCAoSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBleCl7fQotCi0gICAgICAvLyBUaHJvdyB1bmNoZWNrZWQgZXhjZXB0aW9uIGZvciBlcnJvciBpbiBwb29sIGNvbmZpZ3VyYXRpb24uCi0gICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihYTUxNZXNzYWdlcy5jcmVhdGVYTUxNZXNzYWdlKFhNTEVycm9yUmVzb3VyY2VzLkVSX0VYQ0VQVElPTl9DUkVBVElOR19QT09MLCBudWxsKSk7IC8vImV4Y2VwdGlvbiBjcmVhdGluZyBuZXcgaW5zdGFuY2UgZm9yIHBvb2wiKTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLQotICAgICAgLy8gUmVtb3ZlIG9iamVjdCBmcm9tIGVuZCBvZiBmcmVlIHBvb2wuCi0gICAgICBPYmplY3QgcmVzdWx0ID0gZnJlZVN0YWNrLnJlbW92ZShmcmVlU3RhY2suc2l6ZSgpIC0gMSk7Ci0gICAgICByZXR1cm4gcmVzdWx0OwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBBZGQgYW4gaW5zdGFuY2Ugb2YgdGhlIGdpdmVuIG9iamVjdCB0byB0aGUgcG9vbAotICAgKgotICAgKgotICAgKiBAcGFyYW0gb2JqIE9iamVjdCB0byBhZGQuCi0gICAqLwotICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgZnJlZUluc3RhbmNlKE9iamVjdCBvYmopCi0gIHsKLQotICAgIC8vIE1ha2Ugc3VyZSB0aGUgb2JqZWN0IGlzIG9mIHRoZSBjb3JyZWN0IHR5cGUuCi0gICAgLy8gUmVtb3ZlIHNhZmV0eS4gIC1zYgotICAgIC8vIGlmIChvYmplY3RUeXBlLmlzSW5zdGFuY2Uob2JqKSkKLSAgICAvLyB7Ci0gICAgZnJlZVN0YWNrLmFkZChvYmopOwotICAgIC8vIH0KLSAgICAvLyBlbHNlCi0gICAgLy8gewotICAgIC8vICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJhcmd1bWVudCB0eXBlIGludmFsaWQgZm9yIHBvb2wiKTsKLSAgICAvLyB9Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL09iamVjdFN0YWNrLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9PYmplY3RTdGFjay5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmODA1MWI4Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL09iamVjdFN0YWNrLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMTcgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogT2JqZWN0U3RhY2suamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNSAwODoxNTo1MSBzdXJlc2hfZW1haWxpZCBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHM7Ci0KLWltcG9ydCBqYXZhLnV0aWwuRW1wdHlTdGFja0V4Y2VwdGlvbjsKLQotLyoqCi0gKiBJbXBsZW1lbnQgYSBzdGFjayBvZiBzaW1wbGUgaW50ZWdlcnMuCi0gKgotICogJU9QVCUKLSAqIFRoaXMgaXMgY3VycmVudGx5IGJhc2VkIG9uIE9iamVjdFZlY3Rvciwgd2hpY2ggcGVybWl0cyBmYXN0IGFjZXNzIGJ1dCBwYXlzIGEKLSAqIGhlYXZ5IHJlY29weWluZyBwZW5hbHR5IGlmL3doZW4gaXRzIHNpemUgaXMgaW5jcmVhc2VkLiBJZiB3ZSBleHBlY3QgZGVlcAotICogc3RhY2tzLCB3ZSBzaG91bGQgY29uc2lkZXIgYSB2ZXJzaW9uIGJhc2VkIG9uIENodW5rZWRPYmplY3RWZWN0b3IuCi0gKiBAeHNsLnVzYWdlIGludGVybmFsCi0gKi8KLXB1YmxpYyBjbGFzcyBPYmplY3RTdGFjayBleHRlbmRzIE9iamVjdFZlY3RvcgotewotCi0gIC8qKgotICAgKiBEZWZhdWx0IGNvbnN0cnVjdG9yLiAgTm90ZSB0aGF0IHRoZSBkZWZhdWx0Ci0gICAqIGJsb2NrIHNpemUgaXMgdmVyeSBzbWFsbCwgZm9yIHNtYWxsIGxpc3RzLgotICAgKi8KLSAgcHVibGljIE9iamVjdFN0YWNrKCkKLSAgewotICAgIHN1cGVyKCk7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgT2JqZWN0VmVjdG9yLCB1c2luZyB0aGUgZ2l2ZW4gYmxvY2sgc2l6ZS4KLSAgICoKLSAgICogQHBhcmFtIGJsb2Nrc2l6ZSBTaXplIG9mIGJsb2NrIHRvIGFsbG9jYXRlCi0gICAqLwotICBwdWJsaWMgT2JqZWN0U3RhY2soaW50IGJsb2Nrc2l6ZSkKLSAgewotICAgIHN1cGVyKGJsb2Nrc2l6ZSk7Ci0gIH0KLQotICAvKioKLSAgICogQ29weSBjb25zdHJ1Y3RvciBmb3IgT2JqZWN0U3RhY2sKLSAgICoKLSAgICogQHBhcmFtIHYgT2JqZWN0U3RhY2sgdG8gY29weQotICAgKi8KLSAgcHVibGljIE9iamVjdFN0YWNrIChPYmplY3RTdGFjayB2KQotICB7Ci0gICAgICAgIHN1cGVyKHYpOwotICB9Ci0KLSAgLyoqCi0gICAqIFB1c2hlcyBhbiBpdGVtIG9udG8gdGhlIHRvcCBvZiB0aGlzIHN0YWNrLgotICAgKgotICAgKiBAcGFyYW0gICBpICAgdGhlIGludCB0byBiZSBwdXNoZWQgb250byB0aGlzIHN0YWNrLgotICAgKiBAcmV0dXJuICB0aGUgPGNvZGU+aXRlbTwvY29kZT4gYXJndW1lbnQuCi0gICAqLwotICBwdWJsaWMgT2JqZWN0IHB1c2goT2JqZWN0IGkpCi0gIHsKLQotICAgIGlmICgobV9maXJzdEZyZWUgKyAxKSA+PSBtX21hcFNpemUpCi0gICAgewotICAgICAgbV9tYXBTaXplICs9IG1fYmxvY2tzaXplOwotCi0gICAgICBPYmplY3QgbmV3TWFwW10gPSBuZXcgT2JqZWN0W21fbWFwU2l6ZV07Ci0KLSAgICAgIFN5c3RlbS5hcnJheWNvcHkobV9tYXAsIDAsIG5ld01hcCwgMCwgbV9maXJzdEZyZWUgKyAxKTsKLQotICAgICAgbV9tYXAgPSBuZXdNYXA7Ci0gICAgfQotCi0gICAgbV9tYXBbbV9maXJzdEZyZWVdID0gaTsKLQotICAgIG1fZmlyc3RGcmVlKys7Ci0KLSAgICByZXR1cm4gaTsKLSAgfQotCi0gIC8qKgotICAgKiBSZW1vdmVzIHRoZSBvYmplY3QgYXQgdGhlIHRvcCBvZiB0aGlzIHN0YWNrIGFuZCByZXR1cm5zIHRoYXQKLSAgICogb2JqZWN0IGFzIHRoZSB2YWx1ZSBvZiB0aGlzIGZ1bmN0aW9uLgotICAgKgotICAgKiBAcmV0dXJuICAgICBUaGUgb2JqZWN0IGF0IHRoZSB0b3Agb2YgdGhpcyBzdGFjay4KLSAgICovCi0gIHB1YmxpYyBPYmplY3QgcG9wKCkKLSAgewotICAgIE9iamVjdCB2YWwgPSBtX21hcFstLW1fZmlyc3RGcmVlXTsKLSAgICBtX21hcFttX2ZpcnN0RnJlZV0gPSBudWxsOwotCi0gICAgcmV0dXJuIHZhbDsKLSAgfQotCi0gIC8qKgotICAgKiBRdWlja2x5IHBvcHMgYSBudW1iZXIgb2YgaXRlbXMgZnJvbSB0aGUgc3RhY2suCi0gICAqLwotCi0gIHB1YmxpYyB2b2lkIHF1aWNrUG9wKGludCBuKQotICB7Ci0gICAgbV9maXJzdEZyZWUgLT0gbjsKLSAgfQotCi0gIC8qKgotICAgKiBMb29rcyBhdCB0aGUgb2JqZWN0IGF0IHRoZSB0b3Agb2YgdGhpcyBzdGFjayB3aXRob3V0IHJlbW92aW5nIGl0Ci0gICAqIGZyb20gdGhlIHN0YWNrLgotICAgKgotICAgKiBAcmV0dXJuICAgICB0aGUgb2JqZWN0IGF0IHRoZSB0b3Agb2YgdGhpcyBzdGFjay4KLSAgICogQHRocm93cyAgRW1wdHlTdGFja0V4Y2VwdGlvbiAgaWYgdGhpcyBzdGFjayBpcyBlbXB0eS4KLSAgICovCi0gIHB1YmxpYyBPYmplY3QgcGVlaygpCi0gIHsKLSAgICB0cnkgewotICAgICAgcmV0dXJuIG1fbWFwW21fZmlyc3RGcmVlIC0gMV07Ci0gICAgfQotICAgIGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgRW1wdHlTdGFja0V4Y2VwdGlvbigpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBMb29rcyBhdCB0aGUgb2JqZWN0IGF0IHRoZSBwb3NpdGlvbiB0aGUgc3RhY2sgY291bnRpbmcgZG93biBuIGl0ZW1zLgotICAgKgotICAgKiBAcGFyYW0gbiBUaGUgbnVtYmVyIG9mIGl0ZW1zIGRvd24sIGluZGV4ZWQgZnJvbSB6ZXJvLgotICAgKiBAcmV0dXJuICAgICB0aGUgb2JqZWN0IGF0IG4gaXRlbXMgZG93bi4KLSAgICogQHRocm93cyAgRW1wdHlTdGFja0V4Y2VwdGlvbiAgaWYgdGhpcyBzdGFjayBpcyBlbXB0eS4KLSAgICovCi0gIHB1YmxpYyBPYmplY3QgcGVlayhpbnQgbikKLSAgewotICAgIHRyeSB7Ci0gICAgICByZXR1cm4gbV9tYXBbbV9maXJzdEZyZWUtKDErbildOwotICAgIH0KLSAgICBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpCi0gICAgewotICAgICAgdGhyb3cgbmV3IEVtcHR5U3RhY2tFeGNlcHRpb24oKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogU2V0cyBhbiBvYmplY3QgYXQgYSB0aGUgdG9wIG9mIHRoZSBzdGF0Y2sKLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHZhbCBvYmplY3QgdG8gc2V0IGF0IHRoZSB0b3AKLSAgICogQHRocm93cyAgRW1wdHlTdGFja0V4Y2VwdGlvbiAgaWYgdGhpcyBzdGFjayBpcyBlbXB0eS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFRvcChPYmplY3QgdmFsKQotICB7Ci0gICAgdHJ5IHsKLSAgICAgIG1fbWFwW21fZmlyc3RGcmVlIC0gMV0gPSB2YWw7Ci0gICAgfQotICAgIGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgRW1wdHlTdGFja0V4Y2VwdGlvbigpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBUZXN0cyBpZiB0aGlzIHN0YWNrIGlzIGVtcHR5LgotICAgKgotICAgKiBAcmV0dXJuICA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGlzIHN0YWNrIGlzIGVtcHR5OwotICAgKiAgICAgICAgICA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLgotICAgKiBAc2luY2UgICBKREsxLjAKLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGVtcHR5KCkKLSAgewotICAgIHJldHVybiBtX2ZpcnN0RnJlZSA9PSAwOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgd2hlcmUgYW4gb2JqZWN0IGlzIG9uIHRoaXMgc3RhY2suCi0gICAqCi0gICAqIEBwYXJhbSAgIG8gICB0aGUgZGVzaXJlZCBvYmplY3QuCi0gICAqIEByZXR1cm4gIHRoZSBkaXN0YW5jZSBmcm9tIHRoZSB0b3Agb2YgdGhlIHN0YWNrIHdoZXJlIHRoZSBvYmplY3QgaXNdCi0gICAqICAgICAgICAgIGxvY2F0ZWQ7IHRoZSByZXR1cm4gdmFsdWUgPGNvZGU+LTE8L2NvZGU+IGluZGljYXRlcyB0aGF0IHRoZQotICAgKiAgICAgICAgICBvYmplY3QgaXMgbm90IG9uIHRoZSBzdGFjay4KLSAgICogQHNpbmNlICAgSkRLMS4wCi0gICAqLwotICBwdWJsaWMgaW50IHNlYXJjaChPYmplY3QgbykKLSAgewotCi0gICAgaW50IGkgPSBsYXN0SW5kZXhPZihvKTsKLQotICAgIGlmIChpID49IDApCi0gICAgewotICAgICAgcmV0dXJuIHNpemUoKSAtIGk7Ci0gICAgfQotCi0gICAgcmV0dXJuIC0xOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgY2xvbmUgb2YgY3VycmVudCBPYmplY3RTdGFjawotICAgKgotICAgKiBAcmV0dXJuIGNsb25lIG9mIGN1cnJlbnQgT2JqZWN0U3RhY2sKLSAgICovCi0gIHB1YmxpYyBPYmplY3QgY2xvbmUoKQotICAgIHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbgotICB7Ci0gICAgICAgIHJldHVybiAoT2JqZWN0U3RhY2spIHN1cGVyLmNsb25lKCk7Ci0gIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvT2JqZWN0VmVjdG9yLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9PYmplY3RWZWN0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMTljNWFmOC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9PYmplY3RWZWN0b3IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQzMyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAyLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBPYmplY3RWZWN0b3IuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNSAwODoxNTo1MSBzdXJlc2hfZW1haWxpZCBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHM7Ci0KLS8qKgotICogQSB2ZXJ5IHNpbXBsZSB0YWJsZSB0aGF0IHN0b3JlcyBhIGxpc3Qgb2Ygb2JqZWN0cy4KLSAqCi0gKiBUaGlzIHZlcnNpb24gaXMgYmFzZWQgb24gYSAicmVhbGxvYyIgc3RyYXRlZ3kgLS0gYSBzaW1sZSBhcnJheSBpcwotICogdXNlZCwgYW5kIHdoZW4gbW9yZSBzdG9yYWdlIGlzIG5lZWRlZCwgYSBsYXJnZXIgYXJyYXkgaXMgb2J0YWluZWQKLSAqIGFuZCBhbGwgZXhpc3RpbmcgZGF0YSBpcyByZWNvcGllZCBpbnRvIGl0LiBBcyBhIHJlc3VsdCwgcmVhZC93cml0ZQotICogYWNjZXNzIHRvIGV4aXN0aW5nIG5vZGVzIGlzIE8oMSkgZmFzdCBidXQgYXBwZW5kaW5nIG1heSBiZSBPKE4qKjIpCi0gKiBzbG93LgotICogQHhzbC51c2FnZSBpbnRlcm5hbAotICovCi1wdWJsaWMgY2xhc3MgT2JqZWN0VmVjdG9yIGltcGxlbWVudHMgQ2xvbmVhYmxlCi17Ci0KLSAgLyoqIFNpemUgb2YgYmxvY2tzIHRvIGFsbG9jYXRlICAgICAgICAgICovCi0gIHByb3RlY3RlZCBpbnQgbV9ibG9ja3NpemU7Ci0KLSAgLyoqIEFycmF5IG9mIG9iamVjdHMgICAgICAgICAgKi8KLSAgcHJvdGVjdGVkIE9iamVjdCBtX21hcFtdOwotCi0gIC8qKiBOdW1iZXIgb2YgaW50cyBpbiBhcnJheSAgICAgICAgICAqLwotICBwcm90ZWN0ZWQgaW50IG1fZmlyc3RGcmVlID0gMDsKLQotICAvKiogU2l6ZSBvZiBhcnJheSAgICAgICAgICAqLwotICBwcm90ZWN0ZWQgaW50IG1fbWFwU2l6ZTsKLQotICAvKioKLSAgICogRGVmYXVsdCBjb25zdHJ1Y3Rvci4gIE5vdGUgdGhhdCB0aGUgZGVmYXVsdAotICAgKiBibG9jayBzaXplIGlzIHZlcnkgc21hbGwsIGZvciBzbWFsbCBsaXN0cy4KLSAgICovCi0gIHB1YmxpYyBPYmplY3RWZWN0b3IoKQotICB7Ci0KLSAgICBtX2Jsb2Nrc2l6ZSA9IDMyOwotICAgIG1fbWFwU2l6ZSA9IG1fYmxvY2tzaXplOwotICAgIG1fbWFwID0gbmV3IE9iamVjdFttX2Jsb2Nrc2l6ZV07Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgSW50VmVjdG9yLCB1c2luZyB0aGUgZ2l2ZW4gYmxvY2sgc2l6ZS4KLSAgICoKLSAgICogQHBhcmFtIGJsb2Nrc2l6ZSBTaXplIG9mIGJsb2NrIHRvIGFsbG9jYXRlCi0gICAqLwotICBwdWJsaWMgT2JqZWN0VmVjdG9yKGludCBibG9ja3NpemUpCi0gIHsKLQotICAgIG1fYmxvY2tzaXplID0gYmxvY2tzaXplOwotICAgIG1fbWFwU2l6ZSA9IGJsb2Nrc2l6ZTsKLSAgICBtX21hcCA9IG5ldyBPYmplY3RbYmxvY2tzaXplXTsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBJbnRWZWN0b3IsIHVzaW5nIHRoZSBnaXZlbiBibG9jayBzaXplLgotICAgKgotICAgKiBAcGFyYW0gYmxvY2tzaXplIFNpemUgb2YgYmxvY2sgdG8gYWxsb2NhdGUKLSAgICovCi0gIHB1YmxpYyBPYmplY3RWZWN0b3IoaW50IGJsb2Nrc2l6ZSwgaW50IGluY3JlYXNlU2l6ZSkKLSAgewotCi0gICAgbV9ibG9ja3NpemUgPSBpbmNyZWFzZVNpemU7Ci0gICAgbV9tYXBTaXplID0gYmxvY2tzaXplOwotICAgIG1fbWFwID0gbmV3IE9iamVjdFtibG9ja3NpemVdOwotICB9Ci0KLSAgLyoqCi0gICAqIENvcHkgY29uc3RydWN0b3IgZm9yIE9iamVjdFZlY3RvcgotICAgKgotICAgKiBAcGFyYW0gdiBFeGlzdGluZyBPYmplY3RWZWN0b3IgdG8gY29weQotICAgKi8KLSAgcHVibGljIE9iamVjdFZlY3RvcihPYmplY3RWZWN0b3IgdikKLSAgewotICAgICAgICBtX21hcCA9IG5ldyBPYmplY3Rbdi5tX21hcFNpemVdOwotICAgIG1fbWFwU2l6ZSA9IHYubV9tYXBTaXplOwotICAgIG1fZmlyc3RGcmVlID0gdi5tX2ZpcnN0RnJlZTsKLSAgICAgICAgbV9ibG9ja3NpemUgPSB2Lm1fYmxvY2tzaXplOwotICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHYubV9tYXAsIDAsIG1fbWFwLCAwLCBtX2ZpcnN0RnJlZSk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBsZW5ndGggb2YgdGhlIGxpc3QuCi0gICAqCi0gICAqIEByZXR1cm4gbGVuZ3RoIG9mIHRoZSBsaXN0Ci0gICAqLwotICBwdWJsaWMgZmluYWwgaW50IHNpemUoKQotICB7Ci0gICAgcmV0dXJuIG1fZmlyc3RGcmVlOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbGVuZ3RoIG9mIHRoZSBsaXN0LgotICAgKgotICAgKiBAcmV0dXJuIGxlbmd0aCBvZiB0aGUgbGlzdAotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgc2V0U2l6ZShpbnQgc3opCi0gIHsKLSAgICBtX2ZpcnN0RnJlZSA9IHN6OwotICB9Ci0KLQotICAvKioKLSAgICogQXBwZW5kIGFuIG9iamVjdCBvbnRvIHRoZSB2ZWN0b3IuCi0gICAqCi0gICAqIEBwYXJhbSB2YWx1ZSBPYmplY3QgdG8gYWRkIHRvIHRoZSBsaXN0Ci0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBhZGRFbGVtZW50KE9iamVjdCB2YWx1ZSkKLSAgewotCi0gICAgaWYgKChtX2ZpcnN0RnJlZSArIDEpID49IG1fbWFwU2l6ZSkKLSAgICB7Ci0gICAgICBtX21hcFNpemUgKz0gbV9ibG9ja3NpemU7Ci0KLSAgICAgIE9iamVjdCBuZXdNYXBbXSA9IG5ldyBPYmplY3RbbV9tYXBTaXplXTsKLQotICAgICAgU3lzdGVtLmFycmF5Y29weShtX21hcCwgMCwgbmV3TWFwLCAwLCBtX2ZpcnN0RnJlZSArIDEpOwotCi0gICAgICBtX21hcCA9IG5ld01hcDsKLSAgICB9Ci0KLSAgICBtX21hcFttX2ZpcnN0RnJlZV0gPSB2YWx1ZTsKLQotICAgIG1fZmlyc3RGcmVlKys7Ci0gIH0KLQotICAvKioKLSAgICogQXBwZW5kIHNldmVyYWwgT2JqZWN0IHZhbHVlcyBvbnRvIHRoZSB2ZWN0b3IuCi0gICAqCi0gICAqIEBwYXJhbSB2YWx1ZSBPYmplY3QgdG8gYWRkIHRvIHRoZSBsaXN0Ci0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBhZGRFbGVtZW50cyhPYmplY3QgdmFsdWUsIGludCBudW1iZXJPZkVsZW1lbnRzKQotICB7Ci0KLSAgICBpZiAoKG1fZmlyc3RGcmVlICsgbnVtYmVyT2ZFbGVtZW50cykgPj0gbV9tYXBTaXplKQotICAgIHsKLSAgICAgIG1fbWFwU2l6ZSArPSAobV9ibG9ja3NpemUrbnVtYmVyT2ZFbGVtZW50cyk7Ci0KLSAgICAgIE9iamVjdCBuZXdNYXBbXSA9IG5ldyBPYmplY3RbbV9tYXBTaXplXTsKLQotICAgICAgU3lzdGVtLmFycmF5Y29weShtX21hcCwgMCwgbmV3TWFwLCAwLCBtX2ZpcnN0RnJlZSArIDEpOwotCi0gICAgICBtX21hcCA9IG5ld01hcDsKLSAgICB9Ci0KLSAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bWJlck9mRWxlbWVudHM7IGkrKykKLSAgICB7Ci0gICAgICBtX21hcFttX2ZpcnN0RnJlZV0gPSB2YWx1ZTsKLSAgICAgIG1fZmlyc3RGcmVlKys7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEFwcGVuZCBzZXZlcmFsIHNsb3RzIG9udG8gdGhlIHZlY3RvciwgYnV0IGRvIG5vdCBzZXQgdGhlIHZhbHVlcy4KLSAgICoKLSAgICogQHBhcmFtIG51bWJlck9mRWxlbWVudHMgbnVtYmVyIG9mIHNsb3RzIHRvIGFwcGVuZAotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgYWRkRWxlbWVudHMoaW50IG51bWJlck9mRWxlbWVudHMpCi0gIHsKLQotICAgIGlmICgobV9maXJzdEZyZWUgKyBudW1iZXJPZkVsZW1lbnRzKSA+PSBtX21hcFNpemUpCi0gICAgewotICAgICAgbV9tYXBTaXplICs9IChtX2Jsb2Nrc2l6ZStudW1iZXJPZkVsZW1lbnRzKTsKLQotICAgICAgT2JqZWN0IG5ld01hcFtdID0gbmV3IE9iamVjdFttX21hcFNpemVdOwotCi0gICAgICBTeXN0ZW0uYXJyYXljb3B5KG1fbWFwLCAwLCBuZXdNYXAsIDAsIG1fZmlyc3RGcmVlICsgMSk7Ci0KLSAgICAgIG1fbWFwID0gbmV3TWFwOwotICAgIH0KLQotICAgIG1fZmlyc3RGcmVlICs9IG51bWJlck9mRWxlbWVudHM7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBJbnNlcnRzIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGluIHRoaXMgdmVjdG9yIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXguCi0gICAqIEVhY2ggY29tcG9uZW50IGluIHRoaXMgdmVjdG9yIHdpdGggYW4gaW5kZXggZ3JlYXRlciBvciBlcXVhbCB0bwotICAgKiB0aGUgc3BlY2lmaWVkIGluZGV4IGlzIHNoaWZ0ZWQgdXB3YXJkIHRvIGhhdmUgYW4gaW5kZXggb25lIGdyZWF0ZXIKLSAgICogdGhhbiB0aGUgdmFsdWUgaXQgaGFkIHByZXZpb3VzbHkuCi0gICAqCi0gICAqIEBwYXJhbSB2YWx1ZSBPYmplY3QgdG8gaW5zZXJ0Ci0gICAqIEBwYXJhbSBhdCBJbmRleCBvZiB3aGVyZSB0byBpbnNlcnQKLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIGluc2VydEVsZW1lbnRBdChPYmplY3QgdmFsdWUsIGludCBhdCkKLSAgewotCi0gICAgaWYgKChtX2ZpcnN0RnJlZSArIDEpID49IG1fbWFwU2l6ZSkKLSAgICB7Ci0gICAgICBtX21hcFNpemUgKz0gbV9ibG9ja3NpemU7Ci0KLSAgICAgIE9iamVjdCBuZXdNYXBbXSA9IG5ldyBPYmplY3RbbV9tYXBTaXplXTsKLQotICAgICAgU3lzdGVtLmFycmF5Y29weShtX21hcCwgMCwgbmV3TWFwLCAwLCBtX2ZpcnN0RnJlZSArIDEpOwotCi0gICAgICBtX21hcCA9IG5ld01hcDsKLSAgICB9Ci0KLSAgICBpZiAoYXQgPD0gKG1fZmlyc3RGcmVlIC0gMSkpCi0gICAgewotICAgICAgU3lzdGVtLmFycmF5Y29weShtX21hcCwgYXQsIG1fbWFwLCBhdCArIDEsIG1fZmlyc3RGcmVlIC0gYXQpOwotICAgIH0KLQotICAgIG1fbWFwW2F0XSA9IHZhbHVlOwotCi0gICAgbV9maXJzdEZyZWUrKzsKLSAgfQotCi0gIC8qKgotICAgKiBSZW1vdmUgYWxsIGVsZW1lbnRzIG9iamVjdHMgZnJvbSB0aGUgbGlzdC4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHJlbW92ZUFsbEVsZW1lbnRzKCkKLSAgewotCi0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtX2ZpcnN0RnJlZTsgaSsrKQotICAgIHsKLSAgICAgIG1fbWFwW2ldID0gbnVsbDsKLSAgICB9Ci0KLSAgICBtX2ZpcnN0RnJlZSA9IDA7Ci0gIH0KLQotICAvKioKLSAgICogUmVtb3ZlcyB0aGUgZmlyc3Qgb2NjdXJyZW5jZSBvZiB0aGUgYXJndW1lbnQgZnJvbSB0aGlzIHZlY3Rvci4KLSAgICogSWYgdGhlIG9iamVjdCBpcyBmb3VuZCBpbiB0aGlzIHZlY3RvciwgZWFjaCBjb21wb25lbnQgaW4gdGhlIHZlY3RvcgotICAgKiB3aXRoIGFuIGluZGV4IGdyZWF0ZXIgb3IgZXF1YWwgdG8gdGhlIG9iamVjdCdzIGluZGV4IGlzIHNoaWZ0ZWQKLSAgICogZG93bndhcmQgdG8gaGF2ZSBhbiBpbmRleCBvbmUgc21hbGxlciB0aGFuIHRoZSB2YWx1ZSBpdCBoYWQKLSAgICogcHJldmlvdXNseS4KLSAgICoKLSAgICogQHBhcmFtIHMgT2JqZWN0IHRvIHJlbW92ZSBmcm9tIGFycmF5Ci0gICAqCi0gICAqIEByZXR1cm4gVHJ1ZSBpZiB0aGUgb2JqZWN0IHdhcyByZW1vdmVkLCBmYWxzZSBpZiBpdCB3YXMgbm90IGZvdW5kCi0gICAqLwotICBwdWJsaWMgZmluYWwgYm9vbGVhbiByZW1vdmVFbGVtZW50KE9iamVjdCBzKQotICB7Ci0KLSAgICBmb3IgKGludCBpID0gMDsgaSA8IG1fZmlyc3RGcmVlOyBpKyspCi0gICAgewotICAgICAgaWYgKG1fbWFwW2ldID09IHMpCi0gICAgICB7Ci0gICAgICAgIGlmICgoaSArIDEpIDwgbV9maXJzdEZyZWUpCi0gICAgICAgICAgU3lzdGVtLmFycmF5Y29weShtX21hcCwgaSArIDEsIG1fbWFwLCBpIC0gMSwgbV9maXJzdEZyZWUgLSBpKTsKLSAgICAgICAgZWxzZQotICAgICAgICAgIG1fbWFwW2ldID0gbnVsbDsKLQotICAgICAgICBtX2ZpcnN0RnJlZS0tOwotCi0gICAgICAgIHJldHVybiB0cnVlOwotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiBmYWxzZTsKLSAgfQotCi0gIC8qKgotICAgKiBEZWxldGVzIHRoZSBjb21wb25lbnQgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4gRWFjaCBjb21wb25lbnQgaW4KLSAgICogdGhpcyB2ZWN0b3Igd2l0aCBhbiBpbmRleCBncmVhdGVyIG9yIGVxdWFsIHRvIHRoZSBzcGVjaWZpZWQKLSAgICogaW5kZXggaXMgc2hpZnRlZCBkb3dud2FyZCB0byBoYXZlIGFuIGluZGV4IG9uZSBzbWFsbGVyIHRoYW4KLSAgICogdGhlIHZhbHVlIGl0IGhhZCBwcmV2aW91c2x5LgotICAgKgotICAgKiBAcGFyYW0gaSBpbmRleCBvZiB3aGVyZSB0byByZW1vdmUgYW4gb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCByZW1vdmVFbGVtZW50QXQoaW50IGkpCi0gIHsKLQotICAgIGlmIChpID4gbV9maXJzdEZyZWUpCi0gICAgICBTeXN0ZW0uYXJyYXljb3B5KG1fbWFwLCBpICsgMSwgbV9tYXAsIGksIG1fZmlyc3RGcmVlKTsKLSAgICBlbHNlCi0gICAgICBtX21hcFtpXSA9IG51bGw7Ci0KLSAgICBtX2ZpcnN0RnJlZS0tOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldHMgdGhlIGNvbXBvbmVudCBhdCB0aGUgc3BlY2lmaWVkIGluZGV4IG9mIHRoaXMgdmVjdG9yIHRvIGJlIHRoZQotICAgKiBzcGVjaWZpZWQgb2JqZWN0LiBUaGUgcHJldmlvdXMgY29tcG9uZW50IGF0IHRoYXQgcG9zaXRpb24gaXMgZGlzY2FyZGVkLgotICAgKgotICAgKiBUaGUgaW5kZXggbXVzdCBiZSBhIHZhbHVlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAwIGFuZCBsZXNzCi0gICAqIHRoYW4gdGhlIGN1cnJlbnQgc2l6ZSBvZiB0aGUgdmVjdG9yLgotICAgKgotICAgKiBAcGFyYW0gdmFsdWUgb2JqZWN0IHRvIHNldAotICAgKiBAcGFyYW0gaW5kZXggSW5kZXggb2Ygd2hlcmUgdG8gc2V0IHRoZSBvYmplY3QKLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHNldEVsZW1lbnRBdChPYmplY3QgdmFsdWUsIGludCBpbmRleCkKLSAgewotICAgIG1fbWFwW2luZGV4XSA9IHZhbHVlOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbnRoIGVsZW1lbnQuCi0gICAqCi0gICAqIEBwYXJhbSBpIGluZGV4IG9mIG9iamVjdCB0byBnZXQKLSAgICoKLSAgICogQHJldHVybiBvYmplY3QgYXQgZ2l2ZW4gaW5kZXgKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBPYmplY3QgZWxlbWVudEF0KGludCBpKQotICB7Ci0gICAgcmV0dXJuIG1fbWFwW2ldOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgdGhlIHRhYmxlIGNvbnRhaW5zIHRoZSBnaXZlbiBPYmplY3QuCi0gICAqCi0gICAqIEBwYXJhbSBzIG9iamVjdCB0byBsb29rIGZvcgotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIG9iamVjdCBpcyBpbiB0aGUgbGlzdAotICAgKi8KLSAgcHVibGljIGZpbmFsIGJvb2xlYW4gY29udGFpbnMoT2JqZWN0IHMpCi0gIHsKLQotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbV9maXJzdEZyZWU7IGkrKykKLSAgICB7Ci0gICAgICBpZiAobV9tYXBbaV0gPT0gcykKLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotCi0gICAgcmV0dXJuIGZhbHNlOwotICB9Ci0KLSAgLyoqCi0gICAqIFNlYXJjaGVzIGZvciB0aGUgZmlyc3Qgb2NjdXJlbmNlIG9mIHRoZSBnaXZlbiBhcmd1bWVudCwKLSAgICogYmVnaW5uaW5nIHRoZSBzZWFyY2ggYXQgaW5kZXgsIGFuZCB0ZXN0aW5nIGZvciBlcXVhbGl0eQotICAgKiB1c2luZyB0aGUgZXF1YWxzIG1ldGhvZC4KLSAgICoKLSAgICogQHBhcmFtIGVsZW0gb2JqZWN0IHRvIGxvb2sgZm9yCi0gICAqIEBwYXJhbSBpbmRleCBJbmRleCBvZiB3aGVyZSB0byBiZWdpbiBzZWFyY2gKLSAgICogQHJldHVybiB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgdGhlIG9iamVjdAotICAgKiBhcmd1bWVudCBpbiB0aGlzIHZlY3RvciBhdCBwb3NpdGlvbiBpbmRleCBvciBsYXRlciBpbiB0aGUKLSAgICogdmVjdG9yOyByZXR1cm5zIC0xIGlmIHRoZSBvYmplY3QgaXMgbm90IGZvdW5kLgotICAgKi8KLSAgcHVibGljIGZpbmFsIGludCBpbmRleE9mKE9iamVjdCBlbGVtLCBpbnQgaW5kZXgpCi0gIHsKLQotICAgIGZvciAoaW50IGkgPSBpbmRleDsgaSA8IG1fZmlyc3RGcmVlOyBpKyspCi0gICAgewotICAgICAgaWYgKG1fbWFwW2ldID09IGVsZW0pCi0gICAgICAgIHJldHVybiBpOwotICAgIH0KLQotICAgIHJldHVybiBqYXZhLmxhbmcuSW50ZWdlci5NSU5fVkFMVUU7Ci0gIH0KLQotICAvKioKLSAgICogU2VhcmNoZXMgZm9yIHRoZSBmaXJzdCBvY2N1cmVuY2Ugb2YgdGhlIGdpdmVuIGFyZ3VtZW50LAotICAgKiBiZWdpbm5pbmcgdGhlIHNlYXJjaCBhdCBpbmRleCwgYW5kIHRlc3RpbmcgZm9yIGVxdWFsaXR5Ci0gICAqIHVzaW5nIHRoZSBlcXVhbHMgbWV0aG9kLgotICAgKgotICAgKiBAcGFyYW0gZWxlbSBvYmplY3QgdG8gbG9vayBmb3IKLSAgICogQHJldHVybiB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgdGhlIG9iamVjdAotICAgKiBhcmd1bWVudCBpbiB0aGlzIHZlY3RvciBhdCBwb3NpdGlvbiBpbmRleCBvciBsYXRlciBpbiB0aGUKLSAgICogdmVjdG9yOyByZXR1cm5zIC0xIGlmIHRoZSBvYmplY3QgaXMgbm90IGZvdW5kLgotICAgKi8KLSAgcHVibGljIGZpbmFsIGludCBpbmRleE9mKE9iamVjdCBlbGVtKQotICB7Ci0KLSAgICBmb3IgKGludCBpID0gMDsgaSA8IG1fZmlyc3RGcmVlOyBpKyspCi0gICAgewotICAgICAgaWYgKG1fbWFwW2ldID09IGVsZW0pCi0gICAgICAgIHJldHVybiBpOwotICAgIH0KLQotICAgIHJldHVybiBqYXZhLmxhbmcuSW50ZWdlci5NSU5fVkFMVUU7Ci0gIH0KLQotICAvKioKLSAgICogU2VhcmNoZXMgZm9yIHRoZSBmaXJzdCBvY2N1cmVuY2Ugb2YgdGhlIGdpdmVuIGFyZ3VtZW50LAotICAgKiBiZWdpbm5pbmcgdGhlIHNlYXJjaCBhdCBpbmRleCwgYW5kIHRlc3RpbmcgZm9yIGVxdWFsaXR5Ci0gICAqIHVzaW5nIHRoZSBlcXVhbHMgbWV0aG9kLgotICAgKgotICAgKiBAcGFyYW0gZWxlbSBPYmplY3QgdG8gbG9vayBmb3IKLSAgICogQHJldHVybiB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgdGhlIG9iamVjdAotICAgKiBhcmd1bWVudCBpbiB0aGlzIHZlY3RvciBhdCBwb3NpdGlvbiBpbmRleCBvciBsYXRlciBpbiB0aGUKLSAgICogdmVjdG9yOyByZXR1cm5zIC0xIGlmIHRoZSBvYmplY3QgaXMgbm90IGZvdW5kLgotICAgKi8KLSAgcHVibGljIGZpbmFsIGludCBsYXN0SW5kZXhPZihPYmplY3QgZWxlbSkKLSAgewotCi0gICAgZm9yIChpbnQgaSA9IChtX2ZpcnN0RnJlZSAtIDEpOyBpID49IDA7IGktLSkKLSAgICB7Ci0gICAgICBpZiAobV9tYXBbaV0gPT0gZWxlbSkKLSAgICAgICAgcmV0dXJuIGk7Ci0gICAgfQotCi0gICAgcmV0dXJuIGphdmEubGFuZy5JbnRlZ2VyLk1JTl9WQUxVRTsKLSAgfQotCi0gIC8qCi0gICAqIFJlc2V0IHRoZSBhcnJheSB0byB0aGUgc3VwcGxpZWQgc2l6ZS4KLSAgICoKLSAgICogQHBhcmFtIHNpemUKLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHNldFRvU2l6ZShpbnQgc2l6ZSkgewotCi0gICAgT2JqZWN0IG5ld01hcFtdID0gbmV3IE9iamVjdFtzaXplXTsKLQotICAgIFN5c3RlbS5hcnJheWNvcHkobV9tYXAsIDAsIG5ld01hcCwgMCwgbV9maXJzdEZyZWUpOwotICAgIG1fbWFwU2l6ZSA9IHNpemU7Ci0KLSAgICBtX21hcCA9IG5ld01hcDsKLQotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgY2xvbmUgb2YgY3VycmVudCBPYmplY3RWZWN0b3IKLSAgICoKLSAgICogQHJldHVybiBjbG9uZSBvZiBjdXJyZW50IE9iamVjdFZlY3RvcgotICAgKi8KLSAgcHVibGljIE9iamVjdCBjbG9uZSgpCi0gICAgdGhyb3dzIENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uCi0gIHsKLSAgICAgICAgcmV0dXJuIG5ldyBPYmplY3RWZWN0b3IodGhpcyk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL1ByZWZpeFJlc29sdmVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9QcmVmaXhSZXNvbHZlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmMDBkZTU5Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL1ByZWZpeFJlc29sdmVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3NCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBQcmVmaXhSZXNvbHZlci5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE1IDA4OjE1OjUxIHN1cmVzaF9lbWFpbGlkIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlsczsKLQotLyoqCi0gKiBUaGUgY2xhc3MgdGhhdCBpbXBsZW1lbnRzIHRoaXMgaW50ZXJmYWNlIGNhbiByZXNvbHZlIHByZWZpeGVzIHRvCi0gKiBuYW1lc3BhY2VzLiBFeGFtcGxlcyB3b3VsZCBpbmNsdWRlIHJlc29sdmluZyB0aGUgbWVhbmluZyBvZiBhCi0gKiBwcmVmaXggYXQgYSBwYXJ0aWN1bGFyIHBvaW50IGluIGEgZG9jdW1lbnQsIG9yIG1hcHBpbmcgdGhlIHByZWZpeGVzCi0gKiB1c2VkIGluIGFuIFhQYXRoIGV4cHJlc3Npb24uCi0gKiBAeHNsLnVzYWdlIGFkdmFuY2VkCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgUHJlZml4UmVzb2x2ZXIKLXsKLQotICAvKioKLSAgICogR2l2ZW4gYSBuYW1lc3BhY2UsIGdldCB0aGUgY29ycmlzcG9uZGluZyBwcmVmaXguICBUaGlzIGFzc3VtZXMgdGhhdAotICAgKiB0aGUgUHJlZml4UmVzb2x2ZXIgaG9sZHMgaXRzIG93biBuYW1lc3BhY2UgY29udGV4dCwgb3IgaXMgYSBuYW1lc3BhY2UKLSAgICogY29udGV4dCBpdHNlbGYuCi0gICAqCi0gICAqIEBwYXJhbSBwcmVmaXggVGhlIHByZWZpeCB0byBsb29rIHVwLCB3aGljaCBtYXkgYmUgYW4gZW1wdHkgc3RyaW5nICgiIikgZm9yIHRoZSBkZWZhdWx0IE5hbWVzcGFjZS4KLSAgICoKLSAgICogQHJldHVybiBUaGUgYXNzb2NpYXRlZCBOYW1lc3BhY2UgVVJJLCBvciBudWxsIGlmIHRoZSBwcmVmaXgKLSAgICogICAgICAgICBpcyB1bmRlY2xhcmVkIGluIHRoaXMgY29udGV4dC4KLSAgICovCi0gIFN0cmluZyBnZXROYW1lc3BhY2VGb3JQcmVmaXgoU3RyaW5nIHByZWZpeCk7Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgbmFtZXNwYWNlLCBnZXQgdGhlIGNvcnJlc3BvbmRpbmcgcHJlZml4LCBiYXNlZCBvbiB0aGUgY29udGV4dCBub2RlLgotICAgKgotICAgKiBAcGFyYW0gcHJlZml4IFRoZSBwcmVmaXggdG8gbG9vayB1cCwgd2hpY2ggbWF5IGJlIGFuIGVtcHR5IHN0cmluZyAoIiIpIGZvciB0aGUgZGVmYXVsdCBOYW1lc3BhY2UuCi0gICAqIEBwYXJhbSBjb250ZXh0IFRoZSBub2RlIGNvbnRleHQgZnJvbSB3aGljaCB0byBsb29rIHVwIHRoZSBVUkkuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGFzc29jaWF0ZWQgTmFtZXNwYWNlIFVSSSBhcyBhIHN0cmluZywgb3IgbnVsbCBpZiB0aGUgcHJlZml4Ci0gICAqICAgICAgICAgaXMgdW5kZWNsYXJlZCBpbiB0aGlzIGNvbnRleHQuCi0gICAqLwotICBTdHJpbmcgZ2V0TmFtZXNwYWNlRm9yUHJlZml4KFN0cmluZyBwcmVmaXgsIG9yZy53M2MuZG9tLk5vZGUgY29udGV4dCk7Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgYmFzZSBpZGVudGlmaWVyLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBiYXNlIGlkZW50aWZpZXIgZnJvbSB3aGVyZSByZWxhdGl2ZSBVUklzIHNob3VsZCBiZSBhYnNvbHV0aXplZCwgb3IgbnVsbAotICAgKiBpZiB0aGUgYmFzZSBJRCBpcyB1bmtub3duLgotICAgKiA8cD4KLSAgICogQ0FWRUFUOiBOb3RlIHRoYXQgdGhlIGJhc2UgVVJJIGluIGFuIFhNTCBkb2N1bWVudCBtYXkgdmFyeSB3aXRoIHdoZXJlCi0gICAqIHlvdSBhcmUgaW4gdGhlIGRvY3VtZW50LCBpZiBwYXJ0IG9mIHRoZSBkb2MncyBjb250ZW50cyB3ZXJlIGJyb3VnaHQgaW4KLSAgICogdmlhIGFuIGV4dGVybmFsIGVudGl0eSByZWZlcmVuY2Ugb3IgaWYgbWVjaGFuaXNtcyBzdWNoIGFzIHhtbDpiYXNlIGhhdmUKLSAgICogYmVlbiB1c2VkLiBVbmxlc3MgdGhpcyBQcmVmaXhSZXNvbHZlciBpcyBib3VuZCB0byBhIHNwZWNpZmljIHBvcnRpb24gb2YKLSAgICogdGhlIGRvY3VtZW50LCBvciBoYXMgYmVlbiBrZXB0IHVwIHRvIGRhdGUgdmlhIHNvbWUgb3RoZXIgbWVjaGFuaXNtLCBpdAotICAgKiBtYXkgbm90IGFjY3VyYXRlbHkgcmVmbGVjdCB0aGF0IGNvbnRleHQgaW5mb3JtYXRpb24uCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldEJhc2VJZGVudGlmaWVyKCk7Ci0KLSAgcHVibGljIGJvb2xlYW4gaGFuZGxlc051bGxQcmVmaXhlcygpOwotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvUHJlZml4UmVzb2x2ZXJEZWZhdWx0LmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9QcmVmaXhSZXNvbHZlckRlZmF1bHQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZDg5YTgzZS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9QcmVmaXhSZXNvbHZlckRlZmF1bHQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE0NyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBQcmVmaXhSZXNvbHZlckRlZmF1bHQuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNSAwODoxNTo1MSBzdXJlc2hfZW1haWxpZCBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHM7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5OYW1lZE5vZGVNYXA7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGltcGxlbWVudHMgYSBnZW5lcmljIFByZWZpeFJlc29sdmVyIHRoYXQKLSAqIGNhbiBiZSB1c2VkIHRvIHBlcmZvcm0gcHJlZml4LXRvLW5hbWVzcGFjZSBsb29rdXAKLSAqIGZvciB0aGUgWFBhdGggb2JqZWN0LgotICogQHhzbC51c2FnZSBnZW5lcmFsCi0gKi8KLXB1YmxpYyBjbGFzcyBQcmVmaXhSZXNvbHZlckRlZmF1bHQgaW1wbGVtZW50cyBQcmVmaXhSZXNvbHZlcgotewotCi0gIC8qKgotICAgKiBUaGUgY29udGV4dCB0byByZXNvbHZlIHRoZSBwcmVmaXggZnJvbSwgaWYgdGhlIGNvbnRleHQKLSAgICogaXMgbm90IGdpdmVuLgotICAgKi8KLSAgTm9kZSBtX2NvbnRleHQ7Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhIFByZWZpeFJlc29sdmVyRGVmYXVsdCBvYmplY3QuCi0gICAqIEBwYXJhbSB4cGF0aEV4cHJlc3Npb25Db250ZXh0IFRoZSBjb250ZXh0IGZyb20KLSAgICogd2hpY2ggWFBhdGggZXhwcmVzc2lvbiBwcmVmaXhlcyB3aWxsIGJlIHJlc29sdmVkLgotICAgKiBXYXJuaW5nOiBUaGlzIHdpbGwgbm90IHdvcmsgY29ycmVjdGx5IGlmIHhwYXRoRXhwcmVzc2lvbkNvbnRleHQKLSAgICogaXMgYW4gYXR0cmlidXRlIG5vZGUuCi0gICAqLwotICBwdWJsaWMgUHJlZml4UmVzb2x2ZXJEZWZhdWx0KE5vZGUgeHBhdGhFeHByZXNzaW9uQ29udGV4dCkKLSAgewotICAgIG1fY29udGV4dCA9IHhwYXRoRXhwcmVzc2lvbkNvbnRleHQ7Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYSBuYW1lc3BhY2UsIGdldCB0aGUgY29ycmlzcG9uZGluZyBwcmVmaXguICBUaGlzIGFzc3VtZXMgdGhhdAotICAgKiB0aGUgUHJldml4UmVzb2x2ZXIgaG9sZCdzIGl0J3Mgb3duIG5hbWVzcGFjZSBjb250ZXh0LCBvciBpcyBhIG5hbWVzcGFjZQotICAgKiBjb250ZXh0IGl0c2VsZi4KLSAgICogQHBhcmFtIHByZWZpeCBQcmVmaXggdG8gcmVzb2x2ZS4KLSAgICogQHJldHVybiBOYW1lc3BhY2UgdGhhdCBwcmVmaXggcmVzb2x2ZXMgdG8sIG9yIG51bGwgaWYgcHJlZml4Ci0gICAqIGlzIG5vdCBib3VuZC4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZXNwYWNlRm9yUHJlZml4KFN0cmluZyBwcmVmaXgpCi0gIHsKLSAgICByZXR1cm4gZ2V0TmFtZXNwYWNlRm9yUHJlZml4KHByZWZpeCwgbV9jb250ZXh0KTsKLSAgfQotCi0gIC8qKgotICAgKiBHaXZlbiBhIG5hbWVzcGFjZSwgZ2V0IHRoZSBjb3JyaXNwb25kaW5nIHByZWZpeC4KLSAgICogV2FybmluZzogVGhpcyB3aWxsIG5vdCB3b3JrIGNvcnJlY3RseSBpZiBuYW1lc3BhY2VDb250ZXh0Ci0gICAqIGlzIGFuIGF0dHJpYnV0ZSBub2RlLgotICAgKiBAcGFyYW0gcHJlZml4IFByZWZpeCB0byByZXNvbHZlLgotICAgKiBAcGFyYW0gbmFtZXNwYWNlQ29udGV4dCBOb2RlIGZyb20gd2hpY2ggdG8gc3RhcnQgc2VhcmNoaW5nIGZvciBhCi0gICAqIHhtbG5zIGF0dHJpYnV0ZSB0aGF0IGJpbmRzIGEgcHJlZml4IHRvIGEgbmFtZXNwYWNlLgotICAgKiBAcmV0dXJuIE5hbWVzcGFjZSB0aGF0IHByZWZpeCByZXNvbHZlcyB0bywgb3IgbnVsbCBpZiBwcmVmaXgKLSAgICogaXMgbm90IGJvdW5kLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXROYW1lc3BhY2VGb3JQcmVmaXgoU3RyaW5nIHByZWZpeCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JnLnczYy5kb20uTm9kZSBuYW1lc3BhY2VDb250ZXh0KQotICB7Ci0KLSAgICBOb2RlIHBhcmVudCA9IG5hbWVzcGFjZUNvbnRleHQ7Ci0gICAgU3RyaW5nIG5hbWVzcGFjZSA9IG51bGw7Ci0KLSAgICBpZiAocHJlZml4LmVxdWFscygieG1sIikpCi0gICAgewotICAgICAgbmFtZXNwYWNlID0gQ29uc3RhbnRzLlNfWE1MTkFNRVNQQUNFVVJJOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgaW50IHR5cGU7Ci0KLSAgICAgIHdoaWxlICgobnVsbCAhPSBwYXJlbnQpICYmIChudWxsID09IG5hbWVzcGFjZSkKLSAgICAgICAgICAgICAmJiAoKCh0eXBlID0gcGFyZW50LmdldE5vZGVUeXBlKCkpID09IE5vZGUuRUxFTUVOVF9OT0RFKQotICAgICAgICAgICAgICAgICB8fCAodHlwZSA9PSBOb2RlLkVOVElUWV9SRUZFUkVOQ0VfTk9ERSkpKQotICAgICAgewotICAgICAgICBpZiAodHlwZSA9PSBOb2RlLkVMRU1FTlRfTk9ERSkKLSAgICAgICAgewotICAgICAgICAgICAgICAgIGlmIChwYXJlbnQuZ2V0Tm9kZU5hbWUoKS5pbmRleE9mKHByZWZpeCsiOiIpID09IDApCi0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcGFyZW50LmdldE5hbWVzcGFjZVVSSSgpOwotICAgICAgICAgIE5hbWVkTm9kZU1hcCBubm0gPSBwYXJlbnQuZ2V0QXR0cmlidXRlcygpOwotCi0gICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBubm0uZ2V0TGVuZ3RoKCk7IGkrKykKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBOb2RlIGF0dHIgPSBubm0uaXRlbShpKTsKLSAgICAgICAgICAgIFN0cmluZyBhbmFtZSA9IGF0dHIuZ2V0Tm9kZU5hbWUoKTsKLSAgICAgICAgICAgIGJvb2xlYW4gaXNQcmVmaXggPSBhbmFtZS5zdGFydHNXaXRoKCJ4bWxuczoiKTsKLQotICAgICAgICAgICAgaWYgKGlzUHJlZml4IHx8IGFuYW1lLmVxdWFscygieG1sbnMiKSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgaW50IGluZGV4ID0gYW5hbWUuaW5kZXhPZignOicpOwotICAgICAgICAgICAgICBTdHJpbmcgcCA9IGlzUHJlZml4ID8gYW5hbWUuc3Vic3RyaW5nKGluZGV4ICsgMSkgOiAiIjsKLQotICAgICAgICAgICAgICBpZiAocC5lcXVhbHMocHJlZml4KSkKLSAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIG5hbWVzcGFjZSA9IGF0dHIuZ2V0Tm9kZVZhbHVlKCk7Ci0KLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHBhcmVudCA9IHBhcmVudC5nZXRQYXJlbnROb2RlKCk7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgcmV0dXJuIG5hbWVzcGFjZTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIGJhc2UgaWRlbnRpZmllci4KLSAgICoKLSAgICogQHJldHVybiBudWxsCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldEJhc2VJZGVudGlmaWVyKCkKLSAgewotICAgIHJldHVybiBudWxsOwotICB9Ci0gICAgICAgIC8qKgotICAgICAgICAgKiBAc2VlIFByZWZpeFJlc29sdmVyI2hhbmRsZXNOdWxsUHJlZml4ZXMoKQotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIGJvb2xlYW4gaGFuZGxlc051bGxQcmVmaXhlcygpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvUU5hbWUuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL1FOYW1lLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDQ3NGI3NjEuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvUU5hbWUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDcxMSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBRTmFtZS5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE1IDA4OjE1OjUyIHN1cmVzaF9lbWFpbGlkIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlsczsKLQotaW1wb3J0IGphdmEudXRpbC5TdGFjazsKLWltcG9ydCBqYXZhLnV0aWwuU3RyaW5nVG9rZW5pemVyOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXMuWE1MRXJyb3JSZXNvdXJjZXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXMuWE1MTWVzc2FnZXM7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5FbGVtZW50OwotCi0vKioKLSAqIENsYXNzIHRvIHJlcHJlc2VudCBhIHF1YWxpZmllZCBuYW1lOiAiVGhlIG5hbWUgb2YgYW4gaW50ZXJuYWwgWFNMVCBvYmplY3QsCi0gKiBzcGVjaWZpY2FsbHkgYSBuYW1lZCB0ZW1wbGF0ZSAoc2VlIFs3IE5hbWVkIFRlbXBsYXRlc10pLCBhIG1vZGUgKHNlZSBbNi43IE1vZGVzXSksCi0gKiBhbiBhdHRyaWJ1dGUgc2V0IChzZWUgWzguMS40IE5hbWVkIEF0dHJpYnV0ZSBTZXRzXSksIGEga2V5IChzZWUgWzE0LjIgS2V5c10pLAotICogYSBsb2NhbGUgKHNlZSBbMTQuMyBOdW1iZXIgRm9ybWF0dGluZ10pLCBhIHZhcmlhYmxlIG9yIGEgcGFyYW1ldGVyIChzZWUKLSAqIFsxMiBWYXJpYWJsZXMgYW5kIFBhcmFtZXRlcnNdKSBpcyBzcGVjaWZpZWQgYXMgYSBRTmFtZS4gSWYgaXQgaGFzIGEgcHJlZml4LAotICogdGhlbiB0aGUgcHJlZml4IGlzIGV4cGFuZGVkIGludG8gYSBVUkkgcmVmZXJlbmNlIHVzaW5nIHRoZSBuYW1lc3BhY2UgZGVjbGFyYXRpb25zCi0gKiBpbiBlZmZlY3Qgb24gdGhlIGF0dHJpYnV0ZSBpbiB3aGljaCB0aGUgbmFtZSBvY2N1cnMuIFRoZSBleHBhbmRlZCBuYW1lCi0gKiBjb25zaXN0aW5nIG9mIHRoZSBsb2NhbCBwYXJ0IG9mIHRoZSBuYW1lIGFuZCB0aGUgcG9zc2libHkgbnVsbCBVUkkgcmVmZXJlbmNlCi0gKiBpcyB1c2VkIGFzIHRoZSBuYW1lIG9mIHRoZSBvYmplY3QuIFRoZSBkZWZhdWx0IG5hbWVzcGFjZSBpcyBub3QgdXNlZCBmb3IKLSAqIHVucHJlZml4ZWQgbmFtZXMuIgotICogQHhzbC51c2FnZSBnZW5lcmFsCi0gKi8KLXB1YmxpYyBjbGFzcyBRTmFtZSBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlCi17Ci0gICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDQ2NzQzNDU4MTY1MjgyOTkyMEw7Ci0KLSAgLyoqCi0gICAqIFRoZSBsb2NhbCBuYW1lLgotICAgKiBAc2VyaWFsCi0gICAqLwotICBwcm90ZWN0ZWQgU3RyaW5nIF9sb2NhbE5hbWU7Ci0KLSAgLyoqCi0gICAqIFRoZSBuYW1lc3BhY2UgVVJJLgotICAgKiBAc2VyaWFsCi0gICAqLwotICBwcm90ZWN0ZWQgU3RyaW5nIF9uYW1lc3BhY2VVUkk7Ci0KLSAgLyoqCi0gICAqIFRoZSBuYW1lc3BhY2UgcHJlZml4LgotICAgKiBAc2VyaWFsCi0gICAqLwotICBwcm90ZWN0ZWQgU3RyaW5nIF9wcmVmaXg7Ci0KLSAgLyoqCi0gICAqIFRoZSBYTUwgbmFtZXNwYWNlLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU19YTUxOQU1FU1BBQ0VVUkkgPQotICAgICJodHRwOi8vd3d3LnczLm9yZy9YTUwvMTk5OC9uYW1lc3BhY2UiOwotCi0gIC8qKgotICAgKiBUaGUgY2FjaGVkIGhhc2hjb2RlLCB3aGljaCBpcyBjYWxjdWxhdGVkIGF0IGNvbnN0cnVjdGlvbiB0aW1lLgotICAgKiBAc2VyaWFsCi0gICAqLwotICBwcml2YXRlIGludCBtX2hhc2hDb2RlOwotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3RzIGFuIGVtcHR5IFFOYW1lLgotICAgKiAyMDAwMTAxOTogVHJ5IG1ha2luZyB0aGlzIHB1YmxpYywgdG8gc3VwcG9ydCBTZXJpYWxpemFibGU/IC0tIEpLRVNTCi0gICAqLwotICBwdWJsaWMgUU5hbWUoKXt9Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdHMgYSBuZXcgUU5hbWUgd2l0aCB0aGUgc3BlY2lmaWVkIG5hbWVzcGFjZSBVUkkgYW5kCi0gICAqIGxvY2FsIG5hbWUuCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkgVGhlIG5hbWVzcGFjZSBVUkkgaWYga25vd24sIG9yIG51bGwKLSAgICogQHBhcmFtIGxvY2FsTmFtZSBUaGUgbG9jYWwgbmFtZQotICAgKi8KLSAgcHVibGljIFFOYW1lKFN0cmluZyBuYW1lc3BhY2VVUkksIFN0cmluZyBsb2NhbE5hbWUpCi0gIHsKLSAgICB0aGlzKG5hbWVzcGFjZVVSSSwgbG9jYWxOYW1lLCBmYWxzZSk7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0cyBhIG5ldyBRTmFtZSB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZXNwYWNlIFVSSSBhbmQKLSAgICogbG9jYWwgbmFtZS4KLSAgICoKLSAgICogQHBhcmFtIG5hbWVzcGFjZVVSSSBUaGUgbmFtZXNwYWNlIFVSSSBpZiBrbm93biwgb3IgbnVsbAotICAgKiBAcGFyYW0gbG9jYWxOYW1lIFRoZSBsb2NhbCBuYW1lCi0gICAqIEBwYXJhbSB2YWxpZGF0ZSBJZiB0cnVlIHRoZSBuZXcgUU5hbWUgd2lsbCBiZSB2YWxpZGF0ZWQgYW5kIGFuIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3aWxsCi0gICAqICAgICAgICAgICAgICAgICBiZSB0aHJvd24gaWYgaXQgaXMgaW52YWxpZC4KLSAgICovCi0gIHB1YmxpYyBRTmFtZShTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgbG9jYWxOYW1lLCBib29sZWFuIHZhbGlkYXRlKQotICB7Ci0KLSAgICAvLyBUaGlzIGNoZWNrIHdhcyBhbHJlYWR5IGhlcmUuICBTbywgZm9yIG5vdywgSSB3aWxsIG5vdCBhZGQgaXQgdG8gdGhlIHZhbGlkYXRpb24KLSAgICAvLyB0aGF0IGlzIGRvbmUgd2hlbiB0aGUgdmFsaWRhdGUgcGFyYW1ldGVyIGlzIHRydWUuCi0gICAgaWYgKGxvY2FsTmFtZSA9PSBudWxsKQotICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihYTUxNZXNzYWdlcy5jcmVhdGVYTUxNZXNzYWdlKAotICAgICAgICAgICAgWE1MRXJyb3JSZXNvdXJjZXMuRVJfQVJHX0xPQ0FMTkFNRV9OVUxMLCBudWxsKSk7IC8vIkFyZ3VtZW50ICdsb2NhbE5hbWUnIGlzIG51bGwiKTsKLQotICAgIGlmICh2YWxpZGF0ZSkKLSAgICB7Ci0gICAgICAgIGlmICghWE1MMTFDaGFyLmlzWE1MMTFWYWxpZE5DTmFtZShsb2NhbE5hbWUpKQotICAgICAgICB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKFhNTE1lc3NhZ2VzLmNyZWF0ZVhNTE1lc3NhZ2UoCi0gICAgICAgICAgICBYTUxFcnJvclJlc291cmNlcy5FUl9BUkdfTE9DQUxOQU1FX0lOVkFMSUQsbnVsbCApKTsgLy8iQXJndW1lbnQgJ2xvY2FsTmFtZScgbm90IGEgdmFsaWQgTkNOYW1lIik7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBfbmFtZXNwYWNlVVJJID0gbmFtZXNwYWNlVVJJOwotICAgIF9sb2NhbE5hbWUgPSBsb2NhbE5hbWU7Ci0gICAgbV9oYXNoQ29kZSA9IHRvU3RyaW5nKCkuaGFzaENvZGUoKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3RzIGEgbmV3IFFOYW1lIHdpdGggdGhlIHNwZWNpZmllZCBuYW1lc3BhY2UgVVJJLCBwcmVmaXgKLSAgICogYW5kIGxvY2FsIG5hbWUuCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkgVGhlIG5hbWVzcGFjZSBVUkkgaWYga25vd24sIG9yIG51bGwKLSAgICogQHBhcmFtIHByZWZpeCBUaGUgbmFtZXNwYWNlIHByZWZpeCBpcyBrbm93biwgb3IgbnVsbAotICAgKiBAcGFyYW0gbG9jYWxOYW1lIFRoZSBsb2NhbCBuYW1lCi0gICAqCi0gICAqLwotICBwdWJsaWMgUU5hbWUoU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIHByZWZpeCwgU3RyaW5nIGxvY2FsTmFtZSkKLSAgewotICAgICB0aGlzKG5hbWVzcGFjZVVSSSwgcHJlZml4LCBsb2NhbE5hbWUsIGZhbHNlKTsKLSAgfQotCi0gLyoqCi0gICAqIENvbnN0cnVjdHMgYSBuZXcgUU5hbWUgd2l0aCB0aGUgc3BlY2lmaWVkIG5hbWVzcGFjZSBVUkksIHByZWZpeAotICAgKiBhbmQgbG9jYWwgbmFtZS4KLSAgICoKLSAgICogQHBhcmFtIG5hbWVzcGFjZVVSSSBUaGUgbmFtZXNwYWNlIFVSSSBpZiBrbm93biwgb3IgbnVsbAotICAgKiBAcGFyYW0gcHJlZml4IFRoZSBuYW1lc3BhY2UgcHJlZml4IGlzIGtub3duLCBvciBudWxsCi0gICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGxvY2FsIG5hbWUKLSAgICogQHBhcmFtIHZhbGlkYXRlIElmIHRydWUgdGhlIG5ldyBRTmFtZSB3aWxsIGJlIHZhbGlkYXRlZCBhbmQgYW4gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdpbGwKLSAgICogICAgICAgICAgICAgICAgIGJlIHRocm93biBpZiBpdCBpcyBpbnZhbGlkLgotICAgKi8KLSAgcHVibGljIFFOYW1lKFN0cmluZyBuYW1lc3BhY2VVUkksIFN0cmluZyBwcmVmaXgsIFN0cmluZyBsb2NhbE5hbWUsIGJvb2xlYW4gdmFsaWRhdGUpCi0gIHsKLQotICAgIC8vIFRoaXMgY2hlY2sgd2FzIGFscmVhZHkgaGVyZS4gIFNvLCBmb3Igbm93LCBJIHdpbGwgbm90IGFkZCBpdCB0byB0aGUgdmFsaWRhdGlvbgotICAgIC8vIHRoYXQgaXMgZG9uZSB3aGVuIHRoZSB2YWxpZGF0ZSBwYXJhbWV0ZXIgaXMgdHJ1ZS4KLSAgICBpZiAobG9jYWxOYW1lID09IG51bGwpCi0gICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKFhNTE1lc3NhZ2VzLmNyZWF0ZVhNTE1lc3NhZ2UoCi0gICAgICAgICAgICBYTUxFcnJvclJlc291cmNlcy5FUl9BUkdfTE9DQUxOQU1FX05VTEwsIG51bGwpKTsgLy8iQXJndW1lbnQgJ2xvY2FsTmFtZScgaXMgbnVsbCIpOwotCi0gICAgaWYgKHZhbGlkYXRlKQotICAgIHsKLSAgICAgICAgaWYgKCFYTUwxMUNoYXIuaXNYTUwxMVZhbGlkTkNOYW1lKGxvY2FsTmFtZSkpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oWE1MTWVzc2FnZXMuY3JlYXRlWE1MTWVzc2FnZSgKLSAgICAgICAgICAgIFhNTEVycm9yUmVzb3VyY2VzLkVSX0FSR19MT0NBTE5BTUVfSU5WQUxJRCxudWxsICkpOyAvLyJBcmd1bWVudCAnbG9jYWxOYW1lJyBub3QgYSB2YWxpZCBOQ05hbWUiKTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmICgobnVsbCAhPSBwcmVmaXgpICYmICghWE1MMTFDaGFyLmlzWE1MMTFWYWxpZE5DTmFtZShwcmVmaXgpKSkKLSAgICAgICAgewotICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihYTUxNZXNzYWdlcy5jcmVhdGVYTUxNZXNzYWdlKAotICAgICAgICAgICAgWE1MRXJyb3JSZXNvdXJjZXMuRVJfQVJHX1BSRUZJWF9JTlZBTElELG51bGwgKSk7IC8vIkFyZ3VtZW50ICdwcmVmaXgnIG5vdCBhIHZhbGlkIE5DTmFtZSIpOwotICAgICAgICB9Ci0KLSAgICB9Ci0gICAgX25hbWVzcGFjZVVSSSA9IG5hbWVzcGFjZVVSSTsKLSAgICBfcHJlZml4ID0gcHJlZml4OwotICAgIF9sb2NhbE5hbWUgPSBsb2NhbE5hbWU7Ci0gICAgbV9oYXNoQ29kZSA9IHRvU3RyaW5nKCkuaGFzaENvZGUoKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBRTmFtZSBmcm9tIGEgc3RyaW5nLCB3aXRob3V0IG5hbWVzcGFjZSByZXNvbHV0aW9uLiAgR29vZAotICAgKiBmb3IgYSBmZXcgb2RkIGNhc2VzLgotICAgKgotICAgKiBAcGFyYW0gbG9jYWxOYW1lIExvY2FsIHBhcnQgb2YgcXVhbGlmaWVkIG5hbWUKLSAgICoKLSAgICovCi0gIHB1YmxpYyBRTmFtZShTdHJpbmcgbG9jYWxOYW1lKQotICB7Ci0gICAgdGhpcyhsb2NhbE5hbWUsIGZhbHNlKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBRTmFtZSBmcm9tIGEgc3RyaW5nLCB3aXRob3V0IG5hbWVzcGFjZSByZXNvbHV0aW9uLiAgR29vZAotICAgKiBmb3IgYSBmZXcgb2RkIGNhc2VzLgotICAgKgotICAgKiBAcGFyYW0gbG9jYWxOYW1lIExvY2FsIHBhcnQgb2YgcXVhbGlmaWVkIG5hbWUKLSAgICogQHBhcmFtIHZhbGlkYXRlIElmIHRydWUgdGhlIG5ldyBRTmFtZSB3aWxsIGJlIHZhbGlkYXRlZCBhbmQgYW4gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdpbGwKLSAgICogICAgICAgICAgICAgICAgIGJlIHRocm93biBpZiBpdCBpcyBpbnZhbGlkLgotICAgKi8KLSAgcHVibGljIFFOYW1lKFN0cmluZyBsb2NhbE5hbWUsIGJvb2xlYW4gdmFsaWRhdGUpCi0gIHsKLQotICAgIC8vIFRoaXMgY2hlY2sgd2FzIGFscmVhZHkgaGVyZS4gIFNvLCBmb3Igbm93LCBJIHdpbGwgbm90IGFkZCBpdCB0byB0aGUgdmFsaWRhdGlvbgotICAgIC8vIHRoYXQgaXMgZG9uZSB3aGVuIHRoZSB2YWxpZGF0ZSBwYXJhbWV0ZXIgaXMgdHJ1ZS4KLSAgICBpZiAobG9jYWxOYW1lID09IG51bGwpCi0gICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKFhNTE1lc3NhZ2VzLmNyZWF0ZVhNTE1lc3NhZ2UoCi0gICAgICAgICAgICBYTUxFcnJvclJlc291cmNlcy5FUl9BUkdfTE9DQUxOQU1FX05VTEwsIG51bGwpKTsgLy8iQXJndW1lbnQgJ2xvY2FsTmFtZScgaXMgbnVsbCIpOwotCi0gICAgaWYgKHZhbGlkYXRlKQotICAgIHsKLSAgICAgICAgaWYgKCFYTUwxMUNoYXIuaXNYTUwxMVZhbGlkTkNOYW1lKGxvY2FsTmFtZSkpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oWE1MTWVzc2FnZXMuY3JlYXRlWE1MTWVzc2FnZSgKLSAgICAgICAgICAgIFhNTEVycm9yUmVzb3VyY2VzLkVSX0FSR19MT0NBTE5BTUVfSU5WQUxJRCxudWxsICkpOyAvLyJBcmd1bWVudCAnbG9jYWxOYW1lJyBub3QgYSB2YWxpZCBOQ05hbWUiKTsKLSAgICAgICAgfQotICAgIH0KLSAgICBfbmFtZXNwYWNlVVJJID0gbnVsbDsKLSAgICBfbG9jYWxOYW1lID0gbG9jYWxOYW1lOwotICAgIG1faGFzaENvZGUgPSB0b1N0cmluZygpLmhhc2hDb2RlKCk7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgUU5hbWUgZnJvbSBhIHN0cmluZywgcmVzb2x2aW5nIHRoZSBwcmVmaXgKLSAgICogdXNpbmcgdGhlIGdpdmVuIG5hbWVzcGFjZSBzdGFjay4gVGhlIGRlZmF1bHQgbmFtZXNwYWNlIGlzCi0gICAqIG5vdCByZXNvbHZlZC4KLSAgICoKLSAgICogQHBhcmFtIHFuYW1lIFF1YWxpZmllZCBuYW1lIHRvIHJlc29sdmUKLSAgICogQHBhcmFtIG5hbWVzcGFjZXMgTmFtZXNwYWNlIHN0YWNrIHRvIHVzZSB0byByZXNvbHZlIG5hbWVzcGFjZQotICAgKi8KLSAgcHVibGljIFFOYW1lKFN0cmluZyBxbmFtZSwgU3RhY2sgbmFtZXNwYWNlcykKLSAgewotICAgIHRoaXMocW5hbWUsIG5hbWVzcGFjZXMsIGZhbHNlKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBRTmFtZSBmcm9tIGEgc3RyaW5nLCByZXNvbHZpbmcgdGhlIHByZWZpeAotICAgKiB1c2luZyB0aGUgZ2l2ZW4gbmFtZXNwYWNlIHN0YWNrLiBUaGUgZGVmYXVsdCBuYW1lc3BhY2UgaXMKLSAgICogbm90IHJlc29sdmVkLgotICAgKgotICAgKiBAcGFyYW0gcW5hbWUgUXVhbGlmaWVkIG5hbWUgdG8gcmVzb2x2ZQotICAgKiBAcGFyYW0gbmFtZXNwYWNlcyBOYW1lc3BhY2Ugc3RhY2sgdG8gdXNlIHRvIHJlc29sdmUgbmFtZXNwYWNlCi0gICAqIEBwYXJhbSB2YWxpZGF0ZSBJZiB0cnVlIHRoZSBuZXcgUU5hbWUgd2lsbCBiZSB2YWxpZGF0ZWQgYW5kIGFuIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3aWxsCi0gICAqICAgICAgICAgICAgICAgICBiZSB0aHJvd24gaWYgaXQgaXMgaW52YWxpZC4KLSAgICovCi0gIHB1YmxpYyBRTmFtZShTdHJpbmcgcW5hbWUsIFN0YWNrIG5hbWVzcGFjZXMsIGJvb2xlYW4gdmFsaWRhdGUpCi0gIHsKLQotICAgIFN0cmluZyBuYW1lc3BhY2UgPSBudWxsOwotICAgIFN0cmluZyBwcmVmaXggPSBudWxsOwotICAgIGludCBpbmRleE9mTlNTZXAgPSBxbmFtZS5pbmRleE9mKCc6Jyk7Ci0KLSAgICBpZiAoaW5kZXhPZk5TU2VwID4gMCkKLSAgICB7Ci0gICAgICBwcmVmaXggPSBxbmFtZS5zdWJzdHJpbmcoMCwgaW5kZXhPZk5TU2VwKTsKLQotICAgICAgaWYgKHByZWZpeC5lcXVhbHMoInhtbCIpKQotICAgICAgewotICAgICAgICBuYW1lc3BhY2UgPSBTX1hNTE5BTUVTUEFDRVVSSTsKLSAgICAgIH0KLSAgICAgIC8vIERvIHdlIHdhbnQgdGhpcz8KLSAgICAgIGVsc2UgaWYgKHByZWZpeC5lcXVhbHMoInhtbG5zIikpCi0gICAgICB7Ci0gICAgICAgIHJldHVybjsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgaW50IGRlcHRoID0gbmFtZXNwYWNlcy5zaXplKCk7Ci0KLSAgICAgICAgZm9yIChpbnQgaSA9IGRlcHRoIC0gMTsgaSA+PSAwOyBpLS0pCi0gICAgICAgIHsKLSAgICAgICAgICBOYW1lU3BhY2UgbnMgPSAoTmFtZVNwYWNlKSBuYW1lc3BhY2VzLmVsZW1lbnRBdChpKTsKLQotICAgICAgICAgIHdoaWxlIChudWxsICE9IG5zKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGlmICgobnVsbCAhPSBucy5tX3ByZWZpeCkgJiYgcHJlZml4LmVxdWFscyhucy5tX3ByZWZpeCkpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIG5hbWVzcGFjZSA9IG5zLm1fdXJpOwotICAgICAgICAgICAgICBpID0gLTE7Ci0KLSAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIG5zID0gbnMubV9uZXh0OwotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgfQotCi0gICAgICBpZiAobnVsbCA9PSBuYW1lc3BhY2UpCi0gICAgICB7Ci0gICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAotICAgICAgICAgIFhNTE1lc3NhZ2VzLmNyZWF0ZVhNTE1lc3NhZ2UoCi0gICAgICAgICAgICBYTUxFcnJvclJlc291cmNlcy5FUl9QUkVGSVhfTVVTVF9SRVNPTFZFLAotICAgICAgICAgICAgbmV3IE9iamVjdFtdeyBwcmVmaXggfSkpOyAgLy8iUHJlZml4IG11c3QgcmVzb2x2ZSB0byBhIG5hbWVzcGFjZTogIitwcmVmaXgpOwotICAgICAgfQotICAgIH0KLQotICAgIF9sb2NhbE5hbWUgPSAoaW5kZXhPZk5TU2VwIDwgMCkKLSAgICAgICAgICAgICAgICAgPyBxbmFtZSA6IHFuYW1lLnN1YnN0cmluZyhpbmRleE9mTlNTZXAgKyAxKTsKLQotICAgIGlmICh2YWxpZGF0ZSkKLSAgICB7Ci0gICAgICAgIGlmICgoX2xvY2FsTmFtZSA9PSBudWxsKSB8fCAoIVhNTDExQ2hhci5pc1hNTDExVmFsaWROQ05hbWUoX2xvY2FsTmFtZSkpKQotICAgICAgICB7Ci0gICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oWE1MTWVzc2FnZXMuY3JlYXRlWE1MTWVzc2FnZSgKLSAgICAgICAgICAgIFhNTEVycm9yUmVzb3VyY2VzLkVSX0FSR19MT0NBTE5BTUVfSU5WQUxJRCxudWxsICkpOyAvLyJBcmd1bWVudCAnbG9jYWxOYW1lJyBub3QgYSB2YWxpZCBOQ05hbWUiKTsKLSAgICAgICAgfQotICAgIH0KLSAgICBfbmFtZXNwYWNlVVJJID0gbmFtZXNwYWNlOwotICAgIF9wcmVmaXggPSBwcmVmaXg7Ci0gICAgbV9oYXNoQ29kZSA9IHRvU3RyaW5nKCkuaGFzaENvZGUoKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBRTmFtZSBmcm9tIGEgc3RyaW5nLCByZXNvbHZpbmcgdGhlIHByZWZpeAotICAgKiB1c2luZyB0aGUgZ2l2ZW4gbmFtZXNwYWNlIGNvbnRleHQgYW5kIHByZWZpeCByZXNvbHZlci4KLSAgICogVGhlIGRlZmF1bHQgbmFtZXNwYWNlIGlzIG5vdCByZXNvbHZlZC4KLSAgICoKLSAgICogQHBhcmFtIHFuYW1lIFF1YWxpZmllZCBuYW1lIHRvIHJlc29sdmUKLSAgICogQHBhcmFtIG5hbWVzcGFjZUNvbnRleHQgTmFtZXNwYWNlIENvbnRleHQgdG8gdXNlCi0gICAqIEBwYXJhbSByZXNvbHZlciBQcmVmaXggcmVzb2x2ZXIgZm9yIHRoaXMgY29udGV4dAotICAgKi8KLSAgcHVibGljIFFOYW1lKFN0cmluZyBxbmFtZSwgRWxlbWVudCBuYW1lc3BhY2VDb250ZXh0LAotICAgICAgICAgICAgICAgUHJlZml4UmVzb2x2ZXIgcmVzb2x2ZXIpCi0gIHsKLSAgICAgIHRoaXMocW5hbWUsIG5hbWVzcGFjZUNvbnRleHQsIHJlc29sdmVyLCBmYWxzZSk7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgUU5hbWUgZnJvbSBhIHN0cmluZywgcmVzb2x2aW5nIHRoZSBwcmVmaXgKLSAgICogdXNpbmcgdGhlIGdpdmVuIG5hbWVzcGFjZSBjb250ZXh0IGFuZCBwcmVmaXggcmVzb2x2ZXIuCi0gICAqIFRoZSBkZWZhdWx0IG5hbWVzcGFjZSBpcyBub3QgcmVzb2x2ZWQuCi0gICAqCi0gICAqIEBwYXJhbSBxbmFtZSBRdWFsaWZpZWQgbmFtZSB0byByZXNvbHZlCi0gICAqIEBwYXJhbSBuYW1lc3BhY2VDb250ZXh0IE5hbWVzcGFjZSBDb250ZXh0IHRvIHVzZQotICAgKiBAcGFyYW0gcmVzb2x2ZXIgUHJlZml4IHJlc29sdmVyIGZvciB0aGlzIGNvbnRleHQKLSAgICogQHBhcmFtIHZhbGlkYXRlIElmIHRydWUgdGhlIG5ldyBRTmFtZSB3aWxsIGJlIHZhbGlkYXRlZCBhbmQgYW4gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdpbGwKLSAgICogICAgICAgICAgICAgICAgIGJlIHRocm93biBpZiBpdCBpcyBpbnZhbGlkLgotICAgKi8KLSAgcHVibGljIFFOYW1lKFN0cmluZyBxbmFtZSwgRWxlbWVudCBuYW1lc3BhY2VDb250ZXh0LAotICAgICAgICAgICAgICAgUHJlZml4UmVzb2x2ZXIgcmVzb2x2ZXIsIGJvb2xlYW4gdmFsaWRhdGUpCi0gIHsKLQotICAgIF9uYW1lc3BhY2VVUkkgPSBudWxsOwotCi0gICAgaW50IGluZGV4T2ZOU1NlcCA9IHFuYW1lLmluZGV4T2YoJzonKTsKLQotICAgIGlmIChpbmRleE9mTlNTZXAgPiAwKQotICAgIHsKLSAgICAgIGlmIChudWxsICE9IG5hbWVzcGFjZUNvbnRleHQpCi0gICAgICB7Ci0gICAgICAgIFN0cmluZyBwcmVmaXggPSBxbmFtZS5zdWJzdHJpbmcoMCwgaW5kZXhPZk5TU2VwKTsKLQotICAgICAgICBfcHJlZml4ID0gcHJlZml4OwotCi0gICAgICAgIGlmIChwcmVmaXguZXF1YWxzKCJ4bWwiKSkKLSAgICAgICAgewotICAgICAgICAgIF9uYW1lc3BhY2VVUkkgPSBTX1hNTE5BTUVTUEFDRVVSSTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIERvIHdlIHdhbnQgdGhpcz8KLSAgICAgICAgZWxzZSBpZiAocHJlZml4LmVxdWFscygieG1sbnMiKSkKLSAgICAgICAgewotICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgIHsKLSAgICAgICAgICBfbmFtZXNwYWNlVVJJID0gcmVzb2x2ZXIuZ2V0TmFtZXNwYWNlRm9yUHJlZml4KHByZWZpeCwKLSAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZUNvbnRleHQpOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKG51bGwgPT0gX25hbWVzcGFjZVVSSSkKLSAgICAgICAgewotICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAotICAgICAgICAgICAgWE1MTWVzc2FnZXMuY3JlYXRlWE1MTWVzc2FnZSgKLSAgICAgICAgICAgICAgWE1MRXJyb3JSZXNvdXJjZXMuRVJfUFJFRklYX01VU1RfUkVTT0xWRSwKLSAgICAgICAgICAgICAgbmV3IE9iamVjdFtdeyBwcmVmaXggfSkpOyAgLy8iUHJlZml4IG11c3QgcmVzb2x2ZSB0byBhIG5hbWVzcGFjZTogIitwcmVmaXgpOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0KLSAgICAgICAgLy8gVE9ETzogZXJyb3Igb3Igd2FybmluZy4uLgotICAgICAgfQotICAgIH0KLQotICAgIF9sb2NhbE5hbWUgPSAoaW5kZXhPZk5TU2VwIDwgMCkKLSAgICAgICAgICAgICAgICAgPyBxbmFtZSA6IHFuYW1lLnN1YnN0cmluZyhpbmRleE9mTlNTZXAgKyAxKTsKLQotICAgIGlmICh2YWxpZGF0ZSkKLSAgICB7Ci0gICAgICAgIGlmICgoX2xvY2FsTmFtZSA9PSBudWxsKSB8fCAoIVhNTDExQ2hhci5pc1hNTDExVmFsaWROQ05hbWUoX2xvY2FsTmFtZSkpKQotICAgICAgICB7Ci0gICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oWE1MTWVzc2FnZXMuY3JlYXRlWE1MTWVzc2FnZSgKLSAgICAgICAgICAgIFhNTEVycm9yUmVzb3VyY2VzLkVSX0FSR19MT0NBTE5BTUVfSU5WQUxJRCxudWxsICkpOyAvLyJBcmd1bWVudCAnbG9jYWxOYW1lJyBub3QgYSB2YWxpZCBOQ05hbWUiKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIG1faGFzaENvZGUgPSB0b1N0cmluZygpLmhhc2hDb2RlKCk7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBRTmFtZSBmcm9tIGEgc3RyaW5nLCByZXNvbHZpbmcgdGhlIHByZWZpeAotICAgKiB1c2luZyB0aGUgZ2l2ZW4gbmFtZXNwYWNlIHN0YWNrLiBUaGUgZGVmYXVsdCBuYW1lc3BhY2UgaXMKLSAgICogbm90IHJlc29sdmVkLgotICAgKgotICAgKiBAcGFyYW0gcW5hbWUgUXVhbGlmaWVkIG5hbWUgdG8gcmVzb2x2ZQotICAgKiBAcGFyYW0gcmVzb2x2ZXIgUHJlZml4IHJlc29sdmVyIGZvciB0aGlzIGNvbnRleHQKLSAgICovCi0gIHB1YmxpYyBRTmFtZShTdHJpbmcgcW5hbWUsIFByZWZpeFJlc29sdmVyIHJlc29sdmVyKQotICB7Ci0gICAgdGhpcyhxbmFtZSwgcmVzb2x2ZXIsIGZhbHNlKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBRTmFtZSBmcm9tIGEgc3RyaW5nLCByZXNvbHZpbmcgdGhlIHByZWZpeAotICAgKiB1c2luZyB0aGUgZ2l2ZW4gbmFtZXNwYWNlIHN0YWNrLiBUaGUgZGVmYXVsdCBuYW1lc3BhY2UgaXMKLSAgICogbm90IHJlc29sdmVkLgotICAgKgotICAgKiBAcGFyYW0gcW5hbWUgUXVhbGlmaWVkIG5hbWUgdG8gcmVzb2x2ZQotICAgKiBAcGFyYW0gcmVzb2x2ZXIgUHJlZml4IHJlc29sdmVyIGZvciB0aGlzIGNvbnRleHQKLSAgICogQHBhcmFtIHZhbGlkYXRlIElmIHRydWUgdGhlIG5ldyBRTmFtZSB3aWxsIGJlIHZhbGlkYXRlZCBhbmQgYW4gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdpbGwKLSAgICogICAgICAgICAgICAgICAgIGJlIHRocm93biBpZiBpdCBpcyBpbnZhbGlkLgotICAgKi8KLSAgcHVibGljIFFOYW1lKFN0cmluZyBxbmFtZSwgUHJlZml4UmVzb2x2ZXIgcmVzb2x2ZXIsIGJvb2xlYW4gdmFsaWRhdGUpCi0gIHsKLQotICAgICAgICBTdHJpbmcgcHJlZml4ID0gbnVsbDsKLSAgICBfbmFtZXNwYWNlVVJJID0gbnVsbDsKLQotICAgIGludCBpbmRleE9mTlNTZXAgPSBxbmFtZS5pbmRleE9mKCc6Jyk7Ci0KLSAgICBpZiAoaW5kZXhPZk5TU2VwID4gMCkKLSAgICB7Ci0gICAgICBwcmVmaXggPSBxbmFtZS5zdWJzdHJpbmcoMCwgaW5kZXhPZk5TU2VwKTsKLQotICAgICAgaWYgKHByZWZpeC5lcXVhbHMoInhtbCIpKQotICAgICAgewotICAgICAgICBfbmFtZXNwYWNlVVJJID0gU19YTUxOQU1FU1BBQ0VVUkk7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIF9uYW1lc3BhY2VVUkkgPSByZXNvbHZlci5nZXROYW1lc3BhY2VGb3JQcmVmaXgocHJlZml4KTsKLSAgICAgIH0KLQotICAgICAgaWYgKG51bGwgPT0gX25hbWVzcGFjZVVSSSkKLSAgICAgIHsKLSAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCi0gICAgICAgICAgWE1MTWVzc2FnZXMuY3JlYXRlWE1MTWVzc2FnZSgKLSAgICAgICAgICAgIFhNTEVycm9yUmVzb3VyY2VzLkVSX1BSRUZJWF9NVVNUX1JFU09MVkUsCi0gICAgICAgICAgICBuZXcgT2JqZWN0W117IHByZWZpeCB9KSk7ICAvLyJQcmVmaXggbXVzdCByZXNvbHZlIHRvIGEgbmFtZXNwYWNlOiAiK3ByZWZpeCk7Ci0gICAgICB9Ci0gICAgICBfbG9jYWxOYW1lID0gcW5hbWUuc3Vic3RyaW5nKGluZGV4T2ZOU1NlcCArIDEpOwotICAgIH0KLSAgICBlbHNlIGlmIChpbmRleE9mTlNTZXAgPT0gMCkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKLSAgICAgICAgIFhNTE1lc3NhZ2VzLmNyZWF0ZVhNTE1lc3NhZ2UoCi0gICAgICAgICAgIFhNTEVycm9yUmVzb3VyY2VzLkVSX05BTUVfQ0FOVF9TVEFSVF9XSVRIX0NPTE9OLAotICAgICAgICAgICBudWxsKSk7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBfbG9jYWxOYW1lID0gcW5hbWU7Ci0gICAgfQotCi0gICAgaWYgKHZhbGlkYXRlKQotICAgIHsKLSAgICAgICAgaWYgKChfbG9jYWxOYW1lID09IG51bGwpIHx8ICghWE1MMTFDaGFyLmlzWE1MMTFWYWxpZE5DTmFtZShfbG9jYWxOYW1lKSkpCi0gICAgICAgIHsKLSAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihYTUxNZXNzYWdlcy5jcmVhdGVYTUxNZXNzYWdlKAotICAgICAgICAgICAgWE1MRXJyb3JSZXNvdXJjZXMuRVJfQVJHX0xPQ0FMTkFNRV9JTlZBTElELG51bGwgKSk7IC8vIkFyZ3VtZW50ICdsb2NhbE5hbWUnIG5vdCBhIHZhbGlkIE5DTmFtZSIpOwotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICBtX2hhc2hDb2RlID0gdG9TdHJpbmcoKS5oYXNoQ29kZSgpOwotICAgIF9wcmVmaXggPSBwcmVmaXg7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgbmFtZXNwYWNlIFVSSS4gUmV0dXJucyBudWxsIGlmIHRoZSBuYW1lc3BhY2UgVVJJCi0gICAqIGlzIG5vdCBrbm93bi4KLSAgICoKLSAgICogQHJldHVybiBUaGUgbmFtZXNwYWNlIFVSSSwgb3IgbnVsbAotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXROYW1lc3BhY2VVUkkoKQotICB7Ci0gICAgcmV0dXJuIF9uYW1lc3BhY2VVUkk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgbmFtZXNwYWNlIHByZWZpeC4gUmV0dXJucyBudWxsIGlmIHRoZSBuYW1lc3BhY2UKLSAgICogcHJlZml4IGlzIG5vdCBrbm93bi4KLSAgICoKLSAgICogQHJldHVybiBUaGUgbmFtZXNwYWNlIHByZWZpeCwgb3IgbnVsbAotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRQcmVmaXgoKQotICB7Ci0gICAgcmV0dXJuIF9wcmVmaXg7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgbG9jYWwgcGFydCBvZiB0aGUgcXVhbGlmaWVkIG5hbWUuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGxvY2FsIHBhcnQgb2YgdGhlIHF1YWxpZmllZCBuYW1lCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldExvY2FsTmFtZSgpCi0gIHsKLSAgICByZXR1cm4gX2xvY2FsTmFtZTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgcXVhbGlmaWVkIG5hbWUsIHVzaW5nIHRoZQotICAgKiBwcmVmaXggaWYgYXZhaWxhYmxlLCBvciB0aGUgJ3tuc31mb28nIG5vdGF0aW9uIGlmIG5vdC4gUGVyZm9ybXMKLSAgICogc3RyaW5nIGNvbmNhdGVuYXRpb24sIHNvIGJld2FyZSBvZiBwZXJmb3JtYW5jZSBpc3N1ZXMuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgbmFtZXNwYWNlCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkKLSAgewotCi0gICAgcmV0dXJuIF9wcmVmaXggIT0gbnVsbAotICAgICAgICAgICA/IChfcHJlZml4ICsgIjoiICsgX2xvY2FsTmFtZSkKLSAgICAgICAgICAgOiAoX25hbWVzcGFjZVVSSSAhPSBudWxsCi0gICAgICAgICAgICAgID8gKCJ7IitfbmFtZXNwYWNlVVJJICsgIn0iICsgX2xvY2FsTmFtZSkgOiBfbG9jYWxOYW1lKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgcXVhbGlmaWVkIG5hbWUgdXNpbmcgdGhlCi0gICAqIHRoZSAne25zfWZvbycgbm90YXRpb24uIFBlcmZvcm1zCi0gICAqIHN0cmluZyBjb25jYXRlbmF0aW9uLCBzbyBiZXdhcmUgb2YgcGVyZm9ybWFuY2UgaXNzdWVzLgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIG5hbWVzcGFjZQotICAgKi8KLSAgcHVibGljIFN0cmluZyB0b05hbWVzcGFjZWRTdHJpbmcoKQotICB7Ci0KLSAgICByZXR1cm4gKF9uYW1lc3BhY2VVUkkgIT0gbnVsbAotICAgICAgICAgICAgICA/ICgieyIrX25hbWVzcGFjZVVSSSArICJ9IiArIF9sb2NhbE5hbWUpIDogX2xvY2FsTmFtZSk7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBHZXQgdGhlIG5hbWVzcGFjZSBvZiB0aGUgcXVhbGlmaWVkIG5hbWUuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIG5hbWVzcGFjZSBVUkkgb2YgdGhlIHF1YWxpZmllZCBuYW1lCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldE5hbWVzcGFjZSgpCi0gIHsKLSAgICByZXR1cm4gZ2V0TmFtZXNwYWNlVVJJKCk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBsb2NhbCBwYXJ0IG9mIHRoZSBxdWFsaWZpZWQgbmFtZS4KLSAgICoKLSAgICogQHJldHVybiB0aGUgbG9jYWwgcGFydCBvZiB0aGUgcXVhbGlmaWVkIG5hbWUKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0TG9jYWxQYXJ0KCkKLSAgewotICAgIHJldHVybiBnZXRMb2NhbE5hbWUoKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIGNhY2hlZCBoYXNoY29kZSBvZiB0aGUgcXVhbGlmaWVkIG5hbWUuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIGNhY2hlZCBoYXNoY29kZSBvZiB0aGUgcXVhbGlmaWVkIG5hbWUKLSAgICovCi0gIHB1YmxpYyBpbnQgaGFzaENvZGUoKQotICB7Ci0gICAgcmV0dXJuIG1faGFzaENvZGU7Ci0gIH0KLQotICAvKioKLSAgICogT3ZlcnJpZGUgZXF1YWxzIGFuZCBhZ3JlZSB0aGF0IHdlJ3JlIGVxdWFsIGlmCi0gICAqIHRoZSBwYXNzZWQgb2JqZWN0IGlzIGEgc3RyaW5nIGFuZCBpdCBtYXRjaGVzCi0gICAqIHRoZSBuYW1lIG9mIHRoZSBhcmcuCi0gICAqCi0gICAqIEBwYXJhbSBucyBOYW1lc3BhY2UgVVJJIHRvIGNvbXBhcmUgdG8KLSAgICogQHBhcmFtIGxvY2FsUGFydCBMb2NhbCBwYXJ0IG9mIHF1YWxpZmllZCBuYW1lIHRvIGNvbXBhcmUgdG8KLSAgICoKLSAgICogQHJldHVybiBUcnVlIGlmIHRoZSBsb2NhbCBuYW1lIGFuZCB1cmkgbWF0Y2gKLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGVxdWFscyhTdHJpbmcgbnMsIFN0cmluZyBsb2NhbFBhcnQpCi0gIHsKLQotICAgIFN0cmluZyB0aGlzbmFtZXNwYWNlID0gZ2V0TmFtZXNwYWNlVVJJKCk7Ci0KLSAgICByZXR1cm4gZ2V0TG9jYWxOYW1lKCkuZXF1YWxzKGxvY2FsUGFydCkKLSAgICAgICAgICAgJiYgKCgobnVsbCAhPSB0aGlzbmFtZXNwYWNlKSAmJiAobnVsbCAhPSBucykpCi0gICAgICAgICAgICAgICA/IHRoaXNuYW1lc3BhY2UuZXF1YWxzKG5zKQotICAgICAgICAgICAgICAgOiAoKG51bGwgPT0gdGhpc25hbWVzcGFjZSkgJiYgKG51bGwgPT0gbnMpKSk7Ci0gIH0KLQotICAvKioKLSAgICogT3ZlcnJpZGUgZXF1YWxzIGFuZCBhZ3JlZSB0aGF0IHdlJ3JlIGVxdWFsIGlmCi0gICAqIHRoZSBwYXNzZWQgb2JqZWN0IGlzIGEgUU5hbWUgYW5kIGl0IG1hdGNoZXMKLSAgICogdGhlIG5hbWUgb2YgdGhlIGFyZy4KLSAgICoKLSAgICogQHJldHVybiBUcnVlIGlmIHRoZSBxdWFsaWZpZWQgbmFtZXMgYXJlIGVxdWFsCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iamVjdCkKLSAgewotCi0gICAgaWYgKG9iamVjdCA9PSB0aGlzKQotICAgICAgcmV0dXJuIHRydWU7Ci0KLSAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgUU5hbWUpIHsKLSAgICAgIFFOYW1lIHFuYW1lID0gKFFOYW1lKSBvYmplY3Q7Ci0gICAgICBTdHJpbmcgdGhpc25hbWVzcGFjZSA9IGdldE5hbWVzcGFjZVVSSSgpOwotICAgICAgU3RyaW5nIHRoYXRuYW1lc3BhY2UgPSBxbmFtZS5nZXROYW1lc3BhY2VVUkkoKTsKLQotICAgICAgcmV0dXJuIGdldExvY2FsTmFtZSgpLmVxdWFscyhxbmFtZS5nZXRMb2NhbE5hbWUoKSkKLSAgICAgICAgICAgICAmJiAoKChudWxsICE9IHRoaXNuYW1lc3BhY2UpICYmIChudWxsICE9IHRoYXRuYW1lc3BhY2UpKQotICAgICAgICAgICAgICAgICA/IHRoaXNuYW1lc3BhY2UuZXF1YWxzKHRoYXRuYW1lc3BhY2UpCi0gICAgICAgICAgICAgICAgIDogKChudWxsID09IHRoaXNuYW1lc3BhY2UpICYmIChudWxsID09IHRoYXRuYW1lc3BhY2UpKSk7Ci0gICAgfQotICAgIGVsc2UKLSAgICAgIHJldHVybiBmYWxzZTsKLSAgfQotCi0gIC8qKgotICAgKiBHaXZlbiBhIHN0cmluZywgY3JlYXRlIGFuZCByZXR1cm4gYSBRTmFtZSBvYmplY3QKLSAgICoKLSAgICoKLSAgICogQHBhcmFtIG5hbWUgU3RyaW5nIHRvIHVzZSB0byBjcmVhdGUgUU5hbWUKLSAgICoKLSAgICogQHJldHVybiBhIFFOYW1lIG9iamVjdAotICAgKi8KLSAgcHVibGljIHN0YXRpYyBRTmFtZSBnZXRRTmFtZUZyb21TdHJpbmcoU3RyaW5nIG5hbWUpCi0gIHsKLQotICAgIFN0cmluZ1Rva2VuaXplciB0b2tlbml6ZXIgPSBuZXcgU3RyaW5nVG9rZW5pemVyKG5hbWUsICJ7fSIsIGZhbHNlKTsKLSAgICBRTmFtZSBxbmFtZTsKLSAgICBTdHJpbmcgczEgPSB0b2tlbml6ZXIubmV4dFRva2VuKCk7Ci0gICAgU3RyaW5nIHMyID0gdG9rZW5pemVyLmhhc01vcmVUb2tlbnMoKSA/IHRva2VuaXplci5uZXh0VG9rZW4oKSA6IG51bGw7Ci0KLSAgICBpZiAobnVsbCA9PSBzMikKLSAgICAgIHFuYW1lID0gbmV3IFFOYW1lKG51bGwsIHMxKTsKLSAgICBlbHNlCi0gICAgICBxbmFtZSA9IG5ldyBRTmFtZShzMSwgczIpOwotCi0gICAgcmV0dXJuIHFuYW1lOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoaXMgZnVuY3Rpb24gdGVsbHMgaWYgYSByYXcgYXR0cmlidXRlIG5hbWUgaXMgYQotICAgKiB4bWxucyBhdHRyaWJ1dGUuCi0gICAqCi0gICAqIEBwYXJhbSBhdHRSYXdOYW1lIFJhdyBuYW1lIG9mIGF0dHJpYnV0ZQotICAgKgotICAgKiBAcmV0dXJuIFRydWUgaWYgdGhlIGF0dHJpYnV0ZSBzdGFydHMgd2l0aCBvciBpcyBlcXVhbCB0byB4bWxucwotICAgKi8KLSAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzWE1MTlNEZWNsKFN0cmluZyBhdHRSYXdOYW1lKQotICB7Ci0KLSAgICByZXR1cm4gKGF0dFJhd05hbWUuc3RhcnRzV2l0aCgieG1sbnMiKQotICAgICAgICAgICAgJiYgKGF0dFJhd05hbWUuZXF1YWxzKCJ4bWxucyIpCi0gICAgICAgICAgICAgICAgfHwgYXR0UmF3TmFtZS5zdGFydHNXaXRoKCJ4bWxuczoiKSkpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoaXMgZnVuY3Rpb24gdGVsbHMgaWYgYSByYXcgYXR0cmlidXRlIG5hbWUgaXMgYQotICAgKiB4bWxucyBhdHRyaWJ1dGUuCi0gICAqCi0gICAqIEBwYXJhbSBhdHRSYXdOYW1lIFJhdyBuYW1lIG9mIGF0dHJpYnV0ZQotICAgKgotICAgKiBAcmV0dXJuIFByZWZpeCBvZiBhdHRyaWJ1dGUKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldFByZWZpeEZyb21YTUxOU0RlY2woU3RyaW5nIGF0dFJhd05hbWUpCi0gIHsKLQotICAgIGludCBpbmRleCA9IGF0dFJhd05hbWUuaW5kZXhPZignOicpOwotCi0gICAgcmV0dXJuIChpbmRleCA+PSAwKSA/IGF0dFJhd05hbWUuc3Vic3RyaW5nKGluZGV4ICsgMSkgOiAiIjsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBsb2NhbCBuYW1lIG9mIHRoZSBnaXZlbiBub2RlLgotICAgKgotICAgKiBAcGFyYW0gcW5hbWUgSW5wdXQgbmFtZQotICAgKgotICAgKiBAcmV0dXJuIExvY2FsIHBhcnQgb2YgdGhlIG5hbWUgaWYgcHJlZml4ZWQsIG9yIHRoZSBnaXZlbiBuYW1lIGlmIG5vdAotICAgKi8KLSAgcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0TG9jYWxQYXJ0KFN0cmluZyBxbmFtZSkKLSAgewotCi0gICAgaW50IGluZGV4ID0gcW5hbWUuaW5kZXhPZignOicpOwotCi0gICAgcmV0dXJuIChpbmRleCA8IDApID8gcW5hbWUgOiBxbmFtZS5zdWJzdHJpbmcoaW5kZXggKyAxKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBsb2NhbCBuYW1lIG9mIHRoZSBnaXZlbiBub2RlLgotICAgKgotICAgKiBAcGFyYW0gcW5hbWUgSW5wdXQgbmFtZQotICAgKgotICAgKiBAcmV0dXJuIFByZWZpeCBvZiBuYW1lIG9yIGVtcHR5IHN0cmluZyBpZiBub25lIHRoZXJlCi0gICAqLwotICBwdWJsaWMgc3RhdGljIFN0cmluZyBnZXRQcmVmaXhQYXJ0KFN0cmluZyBxbmFtZSkKLSAgewotCi0gICAgaW50IGluZGV4ID0gcW5hbWUuaW5kZXhPZignOicpOwotCi0gICAgcmV0dXJuIChpbmRleCA+PSAwKSA/IHFuYW1lLnN1YnN0cmluZygwLCBpbmRleCkgOiAiIjsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvUmF3Q2hhcmFjdGVySGFuZGxlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvUmF3Q2hhcmFjdGVySGFuZGxlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkMDFjZTg2Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL1Jhd0NoYXJhY3RlckhhbmRsZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQ0ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFJhd0NoYXJhY3RlckhhbmRsZXIuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNSAwODoxNTo1MiBzdXJlc2hfZW1haWxpZCBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHM7Ci0KLS8qKgotICogQW4gaW50ZXJmYWNlIHRoYXQgYSBTZXJpYWxpemVyL0NvbnRlbnRIYW5kbGVyL0NvbnRlbnRIYW5kbGVyIG11c3QKLSAqIGltcGxlbWVudCBpbiBvcmRlciBmb3IgZGlzYWJsZS1vdXRwdXQtZXNjYXBpbmcgdG8gd29yay4KLSAqIEB4c2wudXNhZ2UgYWR2YW5jZWQKLSAqLwotcHVibGljIGludGVyZmFjZSBSYXdDaGFyYWN0ZXJIYW5kbGVyCi17Ci0KLSAgLyoqCi0gICAqIFNlcmlhbGl6ZSB0aGUgY2hhcmFjdGVycyB3aXRob3V0IGVzY2FwaW5nLgotICAgKgotICAgKiBAcGFyYW0gY2ggQXJyYXkgb2YgY2hhcmFjdGVycwotICAgKiBAcGFyYW0gc3RhcnQgU3RhcnQgaW5kZXggb2YgY2hhcmFjdGVycyBpbiB0aGUgYXJyYXkKLSAgICogQHBhcmFtIGxlbmd0aCBOdW1iZXIgb2YgY2hhcmFjdGVycyBpbiB0aGUgYXJyYXkKLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBjaGFyYWN0ZXJzUmF3KGNoYXIgY2hbXSwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKQotICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvU0FYU291cmNlTG9jYXRvci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvU0FYU291cmNlTG9jYXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjOWY3NTc0Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL1NBWFNvdXJjZUxvY2F0b3IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE3MiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBTQVhTb3VyY2VMb2NhdG9yLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTUgMDg6MTU6NTIgc3VyZXNoX2VtYWlsaWQgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzOwotCi1pbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlNvdXJjZUxvY2F0b3I7Ci0KLWltcG9ydCBvcmcueG1sLnNheC5Mb2NhdG9yOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWFBhcnNlRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LmhlbHBlcnMuTG9jYXRvckltcGw7Ci0KLS8qKgotICogQ2xhc3MgU0FYU291cmNlTG9jYXRvciBleHRlbmRzIG9yZy54bWwuc2F4LmhlbHBlcnMuTG9jYXRvckltcGwKLSAqIGZvciB0aGUgcHVycG9zZSBvZiBpbXBsZW1lbnRpbmcgdGhlIFNvdXJjZUxvY2F0b3IgaW50ZXJmYWNlLAotICogYW5kIHRodXMgY2FuIGJlIGJvdGggYSBTb3VyY2VMb2NhdG9yIGFuZCBhIFNBWCBMb2NhdG9yLgotICovCi1wdWJsaWMgY2xhc3MgU0FYU291cmNlTG9jYXRvciBleHRlbmRzIExvY2F0b3JJbXBsCi0gICAgICAgIGltcGxlbWVudHMgU291cmNlTG9jYXRvciwgU2VyaWFsaXphYmxlCi17Ci0gICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDMxODE2ODA5NDYzMjExNjQxMTJMOwotICAvKiogVGhlIFNBWCBMb2NhdG9yIG9iamVjdC4KLSAgICogIEBzZXJpYWwKLSAgICovCi0gIExvY2F0b3IgbV9sb2NhdG9yOwotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3RvciBTQVhTb3VyY2VMb2NhdG9yCi0gICAqCi0gICAqLwotICBwdWJsaWMgU0FYU291cmNlTG9jYXRvcigpe30KLQotICAvKioKLSAgICogQ29uc3RydWN0b3IgU0FYU291cmNlTG9jYXRvcgotICAgKgotICAgKgotICAgKiBAcGFyYW0gbG9jYXRvciBTb3VyY2UgbG9jYXRvcgotICAgKi8KLSAgcHVibGljIFNBWFNvdXJjZUxvY2F0b3IoTG9jYXRvciBsb2NhdG9yKQotICB7Ci0gICAgbV9sb2NhdG9yID0gbG9jYXRvcjsKLSAgICB0aGlzLnNldENvbHVtbk51bWJlcihsb2NhdG9yLmdldENvbHVtbk51bWJlcigpKTsKLSAgICB0aGlzLnNldExpbmVOdW1iZXIobG9jYXRvci5nZXRMaW5lTnVtYmVyKCkpOwotICAgIHRoaXMuc2V0UHVibGljSWQobG9jYXRvci5nZXRQdWJsaWNJZCgpKTsKLSAgICB0aGlzLnNldFN5c3RlbUlkKGxvY2F0b3IuZ2V0U3lzdGVtSWQoKSk7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0b3IgU0FYU291cmNlTG9jYXRvcgotICAgKgotICAgKgotICAgKiBAcGFyYW0gbG9jYXRvciBTb3VyY2UgbG9jYXRvcgotICAgKi8KLSAgcHVibGljIFNBWFNvdXJjZUxvY2F0b3IoamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2VMb2NhdG9yIGxvY2F0b3IpCi0gIHsKLSAgICBtX2xvY2F0b3IgPSBudWxsOwotICAgIHRoaXMuc2V0Q29sdW1uTnVtYmVyKGxvY2F0b3IuZ2V0Q29sdW1uTnVtYmVyKCkpOwotICAgIHRoaXMuc2V0TGluZU51bWJlcihsb2NhdG9yLmdldExpbmVOdW1iZXIoKSk7Ci0gICAgdGhpcy5zZXRQdWJsaWNJZChsb2NhdG9yLmdldFB1YmxpY0lkKCkpOwotICAgIHRoaXMuc2V0U3lzdGVtSWQobG9jYXRvci5nZXRTeXN0ZW1JZCgpKTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIENvbnN0cnVjdG9yIFNBWFNvdXJjZUxvY2F0b3IKLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHNwZSBTQVhQYXJzZUV4Y2VwdGlvbiBleGNlcHRpb24uCi0gICAqLwotICBwdWJsaWMgU0FYU291cmNlTG9jYXRvcihTQVhQYXJzZUV4Y2VwdGlvbiBzcGUpCi0gIHsKLSAgICB0aGlzLnNldExpbmVOdW1iZXIoIHNwZS5nZXRMaW5lTnVtYmVyKCkgKTsKLSAgICB0aGlzLnNldENvbHVtbk51bWJlciggc3BlLmdldENvbHVtbk51bWJlcigpICk7Ci0gICAgdGhpcy5zZXRQdWJsaWNJZCggc3BlLmdldFB1YmxpY0lkKCkgKTsKLSAgICB0aGlzLnNldFN5c3RlbUlkKCBzcGUuZ2V0U3lzdGVtSWQoKSApOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgcHVibGljIGlkZW50aWZpZXIgZm9yIHRoZSBjdXJyZW50IGRvY3VtZW50IGV2ZW50LgotICAgKgotICAgKiA8cD5UaGUgcmV0dXJuIHZhbHVlIGlzIHRoZSBwdWJsaWMgaWRlbnRpZmllciBvZiB0aGUgZG9jdW1lbnQKLSAgICogZW50aXR5IG9yIG9mIHRoZSBleHRlcm5hbCBwYXJzZWQgZW50aXR5IGluIHdoaWNoIHRoZSBtYXJrdXAKLSAgICogdHJpZ2dlcmluZyB0aGUgZXZlbnQgYXBwZWFycy48L3A+Ci0gICAqCi0gICAqIEByZXR1cm4gQSBzdHJpbmcgY29udGFpbmluZyB0aGUgcHVibGljIGlkZW50aWZpZXIsIG9yCi0gICAqICAgICAgICAgbnVsbCBpZiBub25lIGlzIGF2YWlsYWJsZS4KLSAgICogQHNlZSAjZ2V0U3lzdGVtSWQKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0UHVibGljSWQoKQotICB7Ci0gICAgcmV0dXJuIChudWxsID09IG1fbG9jYXRvcikgPyBzdXBlci5nZXRQdWJsaWNJZCgpIDogbV9sb2NhdG9yLmdldFB1YmxpY0lkKCk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBzeXN0ZW0gaWRlbnRpZmllciBmb3IgdGhlIGN1cnJlbnQgZG9jdW1lbnQgZXZlbnQuCi0gICAqCi0gICAqIDxwPlRoZSByZXR1cm4gdmFsdWUgaXMgdGhlIHN5c3RlbSBpZGVudGlmaWVyIG9mIHRoZSBkb2N1bWVudAotICAgKiBlbnRpdHkgb3Igb2YgdGhlIGV4dGVybmFsIHBhcnNlZCBlbnRpdHkgaW4gd2hpY2ggdGhlIG1hcmt1cAotICAgKiB0cmlnZ2VyaW5nIHRoZSBldmVudCBhcHBlYXJzLjwvcD4KLSAgICoKLSAgICogPHA+SWYgdGhlIHN5c3RlbSBpZGVudGlmaWVyIGlzIGEgVVJMLCB0aGUgcGFyc2VyIG11c3QgcmVzb2x2ZSBpdAotICAgKiBmdWxseSBiZWZvcmUgcGFzc2luZyBpdCB0byB0aGUgYXBwbGljYXRpb24uPC9wPgotICAgKgotICAgKiBAcmV0dXJuIEEgc3RyaW5nIGNvbnRhaW5pbmcgdGhlIHN5c3RlbSBpZGVudGlmaWVyLCBvciBudWxsCi0gICAqICAgICAgICAgaWYgbm9uZSBpcyBhdmFpbGFibGUuCi0gICAqIEBzZWUgI2dldFB1YmxpY0lkCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFN5c3RlbUlkKCkKLSAgewotICAgIHJldHVybiAobnVsbCA9PSBtX2xvY2F0b3IpID8gc3VwZXIuZ2V0U3lzdGVtSWQoKSA6IG1fbG9jYXRvci5nZXRTeXN0ZW1JZCgpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgbGluZSBudW1iZXIgd2hlcmUgdGhlIGN1cnJlbnQgZG9jdW1lbnQgZXZlbnQgZW5kcy4KLSAgICoKLSAgICogPHA+PHN0cm9uZz5XYXJuaW5nOjwvc3Ryb25nPiBUaGUgcmV0dXJuIHZhbHVlIGZyb20gdGhlIG1ldGhvZAotICAgKiBpcyBpbnRlbmRlZCBvbmx5IGFzIGFuIGFwcHJveGltYXRpb24gZm9yIHRoZSBzYWtlIG9mIGVycm9yCi0gICAqIHJlcG9ydGluZzsgaXQgaXMgbm90IGludGVuZGVkIHRvIHByb3ZpZGUgc3VmZmljaWVudCBpbmZvcm1hdGlvbgotICAgKiB0byBlZGl0IHRoZSBjaGFyYWN0ZXIgY29udGVudCBvZiB0aGUgb3JpZ2luYWwgWE1MIGRvY3VtZW50LjwvcD4KLSAgICoKLSAgICogPHA+VGhlIHJldHVybiB2YWx1ZSBpcyBhbiBhcHByb3hpbWF0aW9uIG9mIHRoZSBsaW5lIG51bWJlcgotICAgKiBpbiB0aGUgZG9jdW1lbnQgZW50aXR5IG9yIGV4dGVybmFsIHBhcnNlZCBlbnRpdHkgd2hlcmUgdGhlCi0gICAqIG1hcmt1cCB0cmlnZ2VyaW5nIHRoZSBldmVudCBhcHBlYXJzLjwvcD4KLSAgICoKLSAgICogQHJldHVybiBUaGUgbGluZSBudW1iZXIsIG9yIC0xIGlmIG5vbmUgaXMgYXZhaWxhYmxlLgotICAgKiBAc2VlICNnZXRDb2x1bW5OdW1iZXIKLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0TGluZU51bWJlcigpCi0gIHsKLSAgICByZXR1cm4gKG51bGwgPT0gbV9sb2NhdG9yKSA/IHN1cGVyLmdldExpbmVOdW1iZXIoKSA6IG1fbG9jYXRvci5nZXRMaW5lTnVtYmVyKCk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBjb2x1bW4gbnVtYmVyIHdoZXJlIHRoZSBjdXJyZW50IGRvY3VtZW50IGV2ZW50IGVuZHMuCi0gICAqCi0gICAqIDxwPjxzdHJvbmc+V2FybmluZzo8L3N0cm9uZz4gVGhlIHJldHVybiB2YWx1ZSBmcm9tIHRoZSBtZXRob2QKLSAgICogaXMgaW50ZW5kZWQgb25seSBhcyBhbiBhcHByb3hpbWF0aW9uIGZvciB0aGUgc2FrZSBvZiBlcnJvcgotICAgKiByZXBvcnRpbmc7IGl0IGlzIG5vdCBpbnRlbmRlZCB0byBwcm92aWRlIHN1ZmZpY2llbnQgaW5mb3JtYXRpb24KLSAgICogdG8gZWRpdCB0aGUgY2hhcmFjdGVyIGNvbnRlbnQgb2YgdGhlIG9yaWdpbmFsIFhNTCBkb2N1bWVudC48L3A+Ci0gICAqCi0gICAqIDxwPlRoZSByZXR1cm4gdmFsdWUgaXMgYW4gYXBwcm94aW1hdGlvbiBvZiB0aGUgY29sdW1uIG51bWJlcgotICAgKiBpbiB0aGUgZG9jdW1lbnQgZW50aXR5IG9yIGV4dGVybmFsIHBhcnNlZCBlbnRpdHkgd2hlcmUgdGhlCi0gICAqIG1hcmt1cCB0cmlnZ2VyaW5nIHRoZSBldmVudCBhcHBlYXJzLjwvcD4KLSAgICoKLSAgICogQHJldHVybiBUaGUgY29sdW1uIG51bWJlciwgb3IgLTEgaWYgbm9uZSBpcyBhdmFpbGFibGUuCi0gICAqIEBzZWUgI2dldExpbmVOdW1iZXIKLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0Q29sdW1uTnVtYmVyKCkKLSAgewotICAgIHJldHVybiAobnVsbCA9PSBtX2xvY2F0b3IpID8gc3VwZXIuZ2V0Q29sdW1uTnVtYmVyKCkgOiBtX2xvY2F0b3IuZ2V0Q29sdW1uTnVtYmVyKCk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL1NlcmlhbGl6YWJsZUxvY2F0b3JJbXBsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9TZXJpYWxpemFibGVMb2NhdG9ySW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxYmIwMDdkLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL1NlcmlhbGl6YWJsZUxvY2F0b3JJbXBsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMjcgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogU2VyaWFsaXphYmxlTG9jYXRvckltcGwuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNSAwODoxNTo1NCBzdXJlc2hfZW1haWxpZCBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHM7Ci0KLQotLyoqCi0gKiBUaGUgc3RhbmRhcmQgU0FYIGltcGxlbWVudGF0aW9uIG9mIExvY2F0b3JJbXBsIGlzIG5vdCBzZXJpYWxpemFibGUsCi0gKiBsaW1pdGluZyBpdHMgdXRpbGl0eSBhcyAiYSBwZXJzaXN0ZW50IHNuYXBzaG90IG9mIGEgbG9jYXRvciIuCi0gKiBUaGlzIGlzIGEgcXVpY2sgaGFjayB0byBtYWtlIGl0IHNvLiBOb3RlIHRoYXQgaXQgbWFrZXMgbW9yZSBzZW5zZQotICogaW4gbWFueSBjYXNlcyB0byBzZXQgdXAgZmllbGRzIHRvIGhvbGQgdGhpcyBkYXRhIHJhdGhlciB0aGFuIHBvaW50aW5nCi0gKiBhdCBhbm90aGVyIG9iamVjdC4uLiBidXQgdGhhdCBkZWNpc2lvbiBzaG91bGQgYmUgbWFkZSBvbiBhcmNoaXRlY3R1cmFsCi0gKiBncm91bmRzIHJhdGhlciB0aGFuIHNlcmlhbGl6YWJpbGl0eS4KLSAqPHA+Ci0gKiBJdCBpc24ndCBjbGVhciB3aGV0aGVyIHN1YmNsYXNzaW5nIExvY2F0b3JJbXBsIGFuZCBhZGRpbmcgc2VyaWFsaXphdGlvbgotICogbWV0aG9kcyBtYWtlcyBtb3JlIHNlbnNlIHRoYW4gY29weWluZyBpdCBhbmQganVzdCBhZGRpbmcgU2VyaWFsaXphYmxlCi0gKiB0byBpdHMgaW50ZXJmYWNlLiBTaW5jZSBpdCdzIHNvIHNpbXBsZSwgSSd2ZSB0YWtlbiB0aGUgbGF0dGVyIGFwcHJvYWNoCi0gKiBmb3Igbm93LgotICoKLSAqIEBzZWUgb3JnLnhtbC5zYXguaGVscGVycy5Mb2NhdG9ySW1wbAotICogQHNlZSBvcmcueG1sLnNheC5Mb2NhdG9yIExvY2F0b3IKLSAqIEBzaW5jZSBYYWxhbkoyCi0gKiBAYXV0aG9yIEpvZSBLZXNzZWxtYW4KLSAqLwotcHVibGljIGNsYXNzIFNlcmlhbGl6YWJsZUxvY2F0b3JJbXBsCi1pbXBsZW1lbnRzIG9yZy54bWwuc2F4LkxvY2F0b3IsIGphdmEuaW8uU2VyaWFsaXphYmxlCi0KLXsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTI2NjAzMTI4ODg0NDYzNzE0NjBMOwotICAgIC8qKgotICAgICAqIFplcm8tYXJndW1lbnQgY29uc3RydWN0b3IuCi0gICAgICoKLSAgICAgKiA8cD5TQVggc2F5cyAiVGhpcyB3aWxsIG5vdCBub3JtYWxseSBiZSB1c2VmdWwsIHNpbmNlIHRoZSBtYWluIHB1cnBvc2UKLSAgICAgKiBvZiB0aGlzIGNsYXNzIGlzIHRvIG1ha2UgYSBzbmFwc2hvdCBvZiBhbiBleGlzdGluZyBMb2NhdG9yLiIgSW4gZmFjdCwKLSAgICAgKiBpdCBfaXNfIHNvbWV0aW1lcyB1c2VmdWwgd2hlbiB5b3Ugd2FudCB0byBjb25zdHJ1Y3QgYSBuZXcgTG9jYXRvcgotICAgICAqIHBvaW50aW5nIHRvIGEgc3BlY2lmaWMgbG9jYXRpb24uLi4gd2hpY2gsIGFmdGVyIGFsbCwgaXMgd2h5IHRoZQotICAgICAqIHNldHRlciBtZXRob2RzIGFyZSBwcm92aWRlZC4KLSAgICAgKiA8L3A+Ci0gICAgICovCi0gICAgcHVibGljIFNlcmlhbGl6YWJsZUxvY2F0b3JJbXBsICgpCi0gICAgewotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogQ29weSBjb25zdHJ1Y3Rvci4KLSAgICAgKgotICAgICAqIDxwPkNyZWF0ZSBhIHBlcnNpc3RlbnQgY29weSBvZiB0aGUgY3VycmVudCBzdGF0ZSBvZiBhIGxvY2F0b3IuCi0gICAgICogV2hlbiB0aGUgb3JpZ2luYWwgbG9jYXRvciBjaGFuZ2VzLCB0aGlzIGNvcHkgd2lsbCBzdGlsbCBrZWVwCi0gICAgICogdGhlIG9yaWdpbmFsIHZhbHVlcyAoYW5kIGl0IGNhbiBiZSB1c2VkIG91dHNpZGUgdGhlIHNjb3BlIG9mCi0gICAgICogRG9jdW1lbnRIYW5kbGVyIG1ldGhvZHMpLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBsb2NhdG9yIFRoZSBsb2NhdG9yIHRvIGNvcHkuCi0gICAgICovCi0gICAgcHVibGljIFNlcmlhbGl6YWJsZUxvY2F0b3JJbXBsIChvcmcueG1sLnNheC5Mb2NhdG9yIGxvY2F0b3IpCi0gICAgewotICAgICAgICBzZXRQdWJsaWNJZChsb2NhdG9yLmdldFB1YmxpY0lkKCkpOwotICAgICAgICBzZXRTeXN0ZW1JZChsb2NhdG9yLmdldFN5c3RlbUlkKCkpOwotICAgICAgICBzZXRMaW5lTnVtYmVyKGxvY2F0b3IuZ2V0TGluZU51bWJlcigpKTsKLSAgICAgICAgc2V0Q29sdW1uTnVtYmVyKGxvY2F0b3IuZ2V0Q29sdW1uTnVtYmVyKCkpOwotICAgIH0KLQotCi0gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLSAgICAvLyBJbXBsZW1lbnRhdGlvbiBvZiBvcmcueG1sLnNheC5Mb2NhdG9yCi0gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSBzYXZlZCBwdWJsaWMgaWRlbnRpZmllci4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIHB1YmxpYyBpZGVudGlmaWVyIGFzIGEgc3RyaW5nLCBvciBudWxsIGlmIG5vbmUKLSAgICAgKiAgICAgICAgIGlzIGF2YWlsYWJsZS4KLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkxvY2F0b3IjZ2V0UHVibGljSWQKLSAgICAgKiBAc2VlICNzZXRQdWJsaWNJZAotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0UHVibGljSWQgKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBwdWJsaWNJZDsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFJldHVybiB0aGUgc2F2ZWQgc3lzdGVtIGlkZW50aWZpZXIuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBzeXN0ZW0gaWRlbnRpZmllciBhcyBhIHN0cmluZywgb3IgbnVsbCBpZiBub25lCi0gICAgICogICAgICAgICBpcyBhdmFpbGFibGUuCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5Mb2NhdG9yI2dldFN5c3RlbUlkCi0gICAgICogQHNlZSAjc2V0U3lzdGVtSWQKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFN5c3RlbUlkICgpCi0gICAgewotICAgICAgICByZXR1cm4gc3lzdGVtSWQ7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIHNhdmVkIGxpbmUgbnVtYmVyICgxLWJhc2VkKS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIGxpbmUgbnVtYmVyIGFzIGFuIGludGVnZXIsIG9yIC0xIGlmIG5vbmUgaXMgYXZhaWxhYmxlLgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguTG9jYXRvciNnZXRMaW5lTnVtYmVyCi0gICAgICogQHNlZSAjc2V0TGluZU51bWJlcgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0TGluZU51bWJlciAoKQotICAgIHsKLSAgICAgICAgcmV0dXJuIGxpbmVOdW1iZXI7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIHNhdmVkIGNvbHVtbiBudW1iZXIgKDEtYmFzZWQpLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgY29sdW1uIG51bWJlciBhcyBhbiBpbnRlZ2VyLCBvciAtMSBpZiBub25lIGlzIGF2YWlsYWJsZS4KLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkxvY2F0b3IjZ2V0Q29sdW1uTnVtYmVyCi0gICAgICogQHNlZSAjc2V0Q29sdW1uTnVtYmVyCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRDb2x1bW5OdW1iZXIgKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBjb2x1bW5OdW1iZXI7Ci0gICAgfQotCi0KLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotICAgIC8vIFNldHRlcnMgZm9yIHRoZSBwcm9wZXJ0aWVzIChub3QgaW4gb3JnLnhtbC5zYXguTG9jYXRvcikKLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotCi0KLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIHB1YmxpYyBpZGVudGlmaWVyIGZvciB0aGlzIGxvY2F0b3IuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcHVibGljSWQgVGhlIG5ldyBwdWJsaWMgaWRlbnRpZmllciwgb3IgbnVsbAotICAgICAqICAgICAgICBpZiBub25lIGlzIGF2YWlsYWJsZS4KLSAgICAgKiBAc2VlICNnZXRQdWJsaWNJZAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFB1YmxpY0lkIChTdHJpbmcgcHVibGljSWQpCi0gICAgewotICAgICAgICB0aGlzLnB1YmxpY0lkID0gcHVibGljSWQ7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIHN5c3RlbSBpZGVudGlmaWVyIGZvciB0aGlzIGxvY2F0b3IuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc3lzdGVtSWQgVGhlIG5ldyBzeXN0ZW0gaWRlbnRpZmllciwgb3IgbnVsbAotICAgICAqICAgICAgICBpZiBub25lIGlzIGF2YWlsYWJsZS4KLSAgICAgKiBAc2VlICNnZXRTeXN0ZW1JZAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFN5c3RlbUlkIChTdHJpbmcgc3lzdGVtSWQpCi0gICAgewotICAgICAgICB0aGlzLnN5c3RlbUlkID0gc3lzdGVtSWQ7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIGxpbmUgbnVtYmVyIGZvciB0aGlzIGxvY2F0b3IgKDEtYmFzZWQpLgotICAgICAqCi0gICAgICogQHBhcmFtIGxpbmVOdW1iZXIgVGhlIGxpbmUgbnVtYmVyLCBvciAtMSBpZiBub25lIGlzIGF2YWlsYWJsZS4KLSAgICAgKiBAc2VlICNnZXRMaW5lTnVtYmVyCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0TGluZU51bWJlciAoaW50IGxpbmVOdW1iZXIpCi0gICAgewotICAgICAgICB0aGlzLmxpbmVOdW1iZXIgPSBsaW5lTnVtYmVyOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSBjb2x1bW4gbnVtYmVyIGZvciB0aGlzIGxvY2F0b3IgKDEtYmFzZWQpLgotICAgICAqCi0gICAgICogQHBhcmFtIGNvbHVtbk51bWJlciBUaGUgY29sdW1uIG51bWJlciwgb3IgLTEgaWYgbm9uZSBpcyBhdmFpbGFibGUuCi0gICAgICogQHNlZSAjZ2V0Q29sdW1uTnVtYmVyCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0Q29sdW1uTnVtYmVyIChpbnQgY29sdW1uTnVtYmVyKQotICAgIHsKLSAgICAgICAgdGhpcy5jb2x1bW5OdW1iZXIgPSBjb2x1bW5OdW1iZXI7Ci0gICAgfQotCi0KLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotICAgIC8vIEludGVybmFsIHN0YXRlLgotICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0KLSAgICAvKioKLSAgICAgKiBUaGUgcHVibGljIElELgotICAgICAqIEBzZXJpYWwKLSAgICAgKi8KLSAgICBwcml2YXRlIFN0cmluZyBwdWJsaWNJZDsKLQotICAgIC8qKgotICAgICAqIFRoZSBzeXN0ZW0gSUQuCi0gICAgICogQHNlcmlhbAotICAgICAqLwotICAgIHByaXZhdGUgU3RyaW5nIHN5c3RlbUlkOwotCi0gICAgLyoqCi0gICAgICogVGhlIGxpbmUgbnVtYmVyLgotICAgICAqIEBzZXJpYWwKLSAgICAgKi8KLSAgICBwcml2YXRlIGludCBsaW5lTnVtYmVyOwotCi0gICAgLyoqCi0gICAgICogVGhlIGNvbHVtbiBudW1iZXIuCi0gICAgICogQHNlcmlhbAotICAgICAqLwotICAgIHByaXZhdGUgaW50IGNvbHVtbk51bWJlcjsKLQotfQotCi0vLyBlbmQgb2YgTG9jYXRvckltcGwuamF2YQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvU3RvcFBhcnNlRXhjZXB0aW9uLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9TdG9wUGFyc2VFeGNlcHRpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYmMyOWJkMi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9TdG9wUGFyc2VFeGNlcHRpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQyICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFN0b3BQYXJzZUV4Y2VwdGlvbi5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE1IDA4OjE1OjU0IHN1cmVzaF9lbWFpbGlkIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlsczsKLQotLyoqCi0gKiBUaGlzIGlzIGEgc3BlY2lhbCBleGNlcHRpb24gdGhhdCBpcyB1c2VkIHRvIHN0b3AgcGFyc2luZyB3aGVuCi0gKiBzZWFyY2ggZm9yIGFuIGVsZW1lbnQuICBGb3IgaW5zdGFuY2UsIHdoZW4gc2VhcmNoaW5nIGZvciB4bWw6c3R5bGVzaGVldAotICogUElzLCBpdCBpcyB1c2VkIHRvIHN0b3AgdGhlIHBhcnNlIG9uY2UgdGhlIGRvY3VtZW50IGVsZW1lbnQgaXMgZm91bmQuCi0gKiBAc2VlIFN0eWxlc2hlZXRQSUhhbmRsZXIKLSAqIEB4c2wudXNhZ2UgaW50ZXJuYWwKLSAqLwotcHVibGljIGNsYXNzIFN0b3BQYXJzZUV4Y2VwdGlvbiBleHRlbmRzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotewotICAgICAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMjEwMTAyNDc5MjE4MjU4OTYxTDsKLSAgLyoqCi0gICAqIENvbnN0cnVjdG9yIFN0b3BQYXJzZUV4Y2VwdGlvbi4KLSAgICovCi0gIFN0b3BQYXJzZUV4Y2VwdGlvbigpCi0gIHsKLSAgICBzdXBlcigiU3R5bGVzaGVldCBQSXMgZm91bmQsIHN0b3AgdGhlIHBhcnNlIik7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL1N0cmluZ0J1ZmZlclBvb2wuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL1N0cmluZ0J1ZmZlclBvb2wuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMjk5MDQ4MC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9TdHJpbmdCdWZmZXJQb29sLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw2MiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBTdHJpbmdCdWZmZXJQb29sLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTUgMDg6MTU6NTQgc3VyZXNoX2VtYWlsaWQgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgcG9vbHMgc3RyaW5nIGJ1ZmZlcnMsIHNpbmNlIHRoZXkgYXJlIHJldXNlZCBzbyBvZnRlbi4KLSAqIFN0cmluZyBidWZmZXJzIGFyZSBnb29kIGNhbmRpZGF0ZXMgZm9yIHBvb2xpbmcsIGJlY2F1c2Ugb2YKLSAqIHRoZWlyIHN1cHBvcnRpbmcgY2hhcmFjdGVyIGFycmF5cy4KLSAqIEB4c2wudXNhZ2UgaW50ZXJuYWwKLSAqLwotcHVibGljIGNsYXNzIFN0cmluZ0J1ZmZlclBvb2wKLXsKLQotICAvKiogVGhlIGdsb2JhbCBwb29sIG9mIHN0cmluZyBidWZmZXJzLiAgICovCi0gIHByaXZhdGUgc3RhdGljIE9iamVjdFBvb2wgbV9zdHJpbmdCdWZQb29sID0KLSAgICBuZXcgT2JqZWN0UG9vbChjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLkZhc3RTdHJpbmdCdWZmZXIuY2xhc3MpOwotCi0gIC8qKgotICAgKiBHZXQgdGhlIGZpcnN0IGZyZWUgaW5zdGFuY2Ugb2YgYSBzdHJpbmcgYnVmZmVyLCBvciBjcmVhdGUgb25lCi0gICAqIGlmIHRoZXJlIGFyZSBubyBmcmVlIGluc3RhbmNlcy4KLSAgICoKLSAgICogQHJldHVybiBBIHN0cmluZyBidWZmZXIgcmVhZHkgZm9yIHVzZS4KLSAgICovCi0gIHB1YmxpYyBzeW5jaHJvbml6ZWQgc3RhdGljIEZhc3RTdHJpbmdCdWZmZXIgZ2V0KCkKLSAgewotICAgIHJldHVybiAoRmFzdFN0cmluZ0J1ZmZlcikgbV9zdHJpbmdCdWZQb29sLmdldEluc3RhbmNlKCk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIGEgc3RyaW5nIGJ1ZmZlciBiYWNrIHRvIHRoZSBwb29sLgotICAgKgotICAgKiBAcGFyYW0gc2IgTXVzdCBiZSBhIG5vbi1udWxsIHJlZmVyZW5jZSB0byBhIHN0cmluZyBidWZmZXIuCi0gICAqLwotICBwdWJsaWMgc3luY2hyb25pemVkIHN0YXRpYyB2b2lkIGZyZWUoRmFzdFN0cmluZ0J1ZmZlciBzYikKLSAgewotICAgIC8vIFNpbmNlIHRoaXMgaXNuJ3Qgc3luY2hyb25pemVkLCBzZXRMZW5ndGggbXVzdCBiZQotICAgIC8vIGRvbmUgYmVmb3JlIHRoZSBpbnN0YW5jZSBpcyBmcmVlZC4KLSAgICAvLyBGaXggYXR0cmlidXRlZCB0byBQZXRlciBTcGVjayA8c3BlY2tAcnVjLmRrPi4KLSAgICBzYi5zZXRMZW5ndGgoMCk7Ci0gICAgbV9zdHJpbmdCdWZQb29sLmZyZWVJbnN0YW5jZShzYik7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL1N0cmluZ0NvbXBhcmFibGUuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL1N0cmluZ0NvbXBhcmFibGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggODFjYzgzOC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9TdHJpbmdDb21wYXJhYmxlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMTUgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogU3RyaW5nQ29tcGFyYWJsZS5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE1IDA4OjE1OjU1IHN1cmVzaF9lbWFpbGlkIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLWltcG9ydCBqYXZhLnRleHQuQ29sbGF0b3I7Ci1pbXBvcnQgamF2YS50ZXh0LlJ1bGVCYXNlZENvbGxhdG9yOwotaW1wb3J0IGphdmEudGV4dC5Db2xsYXRpb25FbGVtZW50SXRlcmF0b3I7Ci1pbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKLWltcG9ydCBqYXZhLnRleHQuQ29sbGF0aW9uS2V5OwotCi0KLS8qKgotKiBJbnRlcm5hdGlvbmFsIGZyaWVuZGx5IHN0cmluZyBjb21wYXJpc29uIHdpdGggY2FzZS1vcmRlcgotICogQGF1dGhvciBJZ29yIEhlcnNodCwgaWdvcmhAY2EuaWJtLmNvbQotKi8KLXB1YmxpYyBjbGFzcyBTdHJpbmdDb21wYXJhYmxlIGltcGxlbWVudHMgQ29tcGFyYWJsZSAgewotCi0gICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgaW50IFVOS05PV05fQ0FTRSA9IC0xOwotICAgICBwdWJsaWMgZmluYWwgc3RhdGljIGludCBVUFBFUl9DQVNFID0gMTsKLSAgICAgcHVibGljIGZpbmFsIHN0YXRpYyBpbnQgTE9XRVJfQ0FTRSA9IDI7Ci0KLSAgICAgcHJpdmF0ZSAgU3RyaW5nIG1fdGV4dDsKLSAgICAgcHJpdmF0ZSAgTG9jYWxlIG1fbG9jYWxlOwotICAgICBwcml2YXRlIFJ1bGVCYXNlZENvbGxhdG9yIG1fY29sbGF0b3I7Ci0gICAgIHByaXZhdGUgU3RyaW5nIG1fY2FzZU9yZGVyOwotICAgICBwcml2YXRlIGludCBtX21hc2sgPSAweEZGRkZGRkZGOwotCi0gICAgcHVibGljIFN0cmluZ0NvbXBhcmFibGUoZmluYWwgU3RyaW5nIHRleHQsIGZpbmFsIExvY2FsZSBsb2NhbGUsIGZpbmFsIENvbGxhdG9yIGNvbGxhdG9yLCBmaW5hbCBTdHJpbmcgY2FzZU9yZGVyKXsKLSAgICAgICAgIG1fdGV4dCA9ICB0ZXh0OwotICAgICAgICAgbV9sb2NhbGUgPSBsb2NhbGU7Ci0gICAgICAgICBtX2NvbGxhdG9yID0gKFJ1bGVCYXNlZENvbGxhdG9yKWNvbGxhdG9yOwotICAgICAgICAgbV9jYXNlT3JkZXIgPSBjYXNlT3JkZXI7Ci0gICAgICAgICBtX21hc2sgPSBnZXRNYXNrKG1fY29sbGF0b3IuZ2V0U3RyZW5ndGgoKSk7Ci0gICAgfQotCi0gICBwdWJsaWMgZmluYWwgc3RhdGljIENvbXBhcmFibGUgZ2V0Q29tcGFyYXRvciggZmluYWwgU3RyaW5nIHRleHQsIGZpbmFsIExvY2FsZSBsb2NhbGUsIGZpbmFsIENvbGxhdG9yIGNvbGxhdG9yLCBmaW5hbCBTdHJpbmcgY2FzZU9yZGVyKXsKLSAgICAgICBpZigoY2FzZU9yZGVyID09IG51bGwpIHx8KGNhc2VPcmRlci5sZW5ndGgoKSA9PSAwKSl7Ly8gbm8gY2FzZS1vcmRlciBzcGVjaWZpZWQKLSAgICAgICAgICAgIHJldHVybiAgKChSdWxlQmFzZWRDb2xsYXRvciljb2xsYXRvcikuZ2V0Q29sbGF0aW9uS2V5KHRleHQpOwotICAgICAgIH1lbHNlewotICAgICAgICAgICAgcmV0dXJuIG5ldyBTdHJpbmdDb21wYXJhYmxlKHRleHQsIGxvY2FsZSwgY29sbGF0b3IsIGNhc2VPcmRlcik7Ci0gICAgICAgfQotICAgfQotCi0gICBwdWJsaWMgZmluYWwgU3RyaW5nIHRvU3RyaW5nKCl7cmV0dXJuIG1fdGV4dDt9Ci0KLSAgIHB1YmxpYyBpbnQgY29tcGFyZVRvKE9iamVjdCBvKSB7Ci0gICBmaW5hbCBTdHJpbmcgcGF0dGVybiA9ICgoU3RyaW5nQ29tcGFyYWJsZSlvKS50b1N0cmluZygpOwotICAgaWYobV90ZXh0LmVxdWFscyhwYXR0ZXJuKSl7Ly9Db2RlLXBvaW50IGVxdWFscwotICAgICAgcmV0dXJuIDA7Ci0gICB9Ci0gICBmaW5hbCBpbnQgc2F2ZWRTdHJlbmd0aCA9IG1fY29sbGF0b3IuZ2V0U3RyZW5ndGgoKTsKLSAgIGludCBjb21wID0gMDsKLSAgICAgIC8vIElzIHRoZXJlIGRpZmZlcmVuY2UgbW9yZSBzaWduaWZpY2FudCB0aGFuIGNhc2Utb3JkZXI/Ci0gICAgIGlmKCgoc2F2ZWRTdHJlbmd0aCA9PSBDb2xsYXRvci5QUklNQVJZKSB8fCAoc2F2ZWRTdHJlbmd0aCA9PSBDb2xsYXRvci5TRUNPTkRBUlkpKSl7Ci0gICAgICAgICBjb21wID0gbV9jb2xsYXRvci5jb21wYXJlKG1fdGV4dCwgcGF0dGVybiApOwotICAgICB9ZWxzZXsvLyBtb3JlIHRoYW4gU0VDT05EQVJZCi0gICAgICAgICBtX2NvbGxhdG9yLnNldFN0cmVuZ3RoKENvbGxhdG9yLlNFQ09OREFSWSk7Ci0gICAgICAgICBjb21wID0gbV9jb2xsYXRvci5jb21wYXJlKG1fdGV4dCwgcGF0dGVybiApOwotICAgICAgICAgbV9jb2xsYXRvci5zZXRTdHJlbmd0aChzYXZlZFN0cmVuZ3RoKTsKLSAgICAgfQotICAgICBpZihjb21wICE9IDApey8vRGlmZmVyZW5jZSBtb3JlIHNpZ25pZmljYW50IHRoYW4gY2FzZS1vcmRlcgotICAgICAgICByZXR1cm4gY29tcCA7Ci0gICAgIH0KLQotICAgICAgLy8gTm8gZGlmZmVyZW5jZSBtb3JlIHNpZ25pZmljYW50IHRoYW4gY2FzZS1vcmRlci4KLSAgICAgIC8vIEZpbmQgY2FzZSBkaWZmZXJlbmNlCi0gICAgICAgY29tcCA9IGdldENhc2VEaWZmKG1fdGV4dCwgcGF0dGVybik7Ci0gICAgICAgaWYoY29tcCAhPSAwKXsKLSAgICAgICAgICAgcmV0dXJuIGNvbXA7Ci0gICAgICAgfWVsc2V7Ly8gTm8gY2FzZSBkaWZmZXJlbmNlcy4gTGVzcyBzaWduaWZpY2FudCBkaWZmZXJlbmNlIGNvdWxkIGV4aXN0Ci0gICAgICAgICAgICByZXR1cm4gbV9jb2xsYXRvci5jb21wYXJlKG1fdGV4dCwgcGF0dGVybiApOwotICAgICAgIH0KLSAgfQotCi0KLSAgcHJpdmF0ZSBmaW5hbCBpbnQgZ2V0Q2FzZURpZmYgKGZpbmFsIFN0cmluZyB0ZXh0LCBmaW5hbCBTdHJpbmcgcGF0dGVybil7Ci0gICAgIGZpbmFsIGludCBzYXZlZFN0cmVuZ3RoID0gbV9jb2xsYXRvci5nZXRTdHJlbmd0aCgpOwotICAgICBmaW5hbCBpbnQgc2F2ZWREZWNvbXBvc2l0aW9uID0gbV9jb2xsYXRvci5nZXREZWNvbXBvc2l0aW9uKCk7Ci0gICAgIG1fY29sbGF0b3Iuc2V0U3RyZW5ndGgoQ29sbGF0b3IuVEVSVElBUlkpOy8vIG5vdCB0byBpZ25vcmUgY2FzZQotICAgICBtX2NvbGxhdG9yLnNldERlY29tcG9zaXRpb24oQ29sbGF0b3IuQ0FOT05JQ0FMX0RFQ09NUE9TSVRJT04gKTsvLyBjb3JyZXNwb25kcyBOREYKLQotICAgIGZpbmFsIGludCBkaWZmW10gPWdldEZpcnN0Q2FzZURpZmYgKHRleHQsIHBhdHRlcm4sIG1fbG9jYWxlKTsKLSAgICBtX2NvbGxhdG9yLnNldFN0cmVuZ3RoKHNhdmVkU3RyZW5ndGgpOy8vIHJlc3RvcmUKLSAgICBtX2NvbGxhdG9yLnNldERlY29tcG9zaXRpb24oc2F2ZWREZWNvbXBvc2l0aW9uKTsgLy9yZXN0b3JlCi0gICAgaWYoZGlmZiAhPSBudWxsKXsKLSAgICAgICBpZigobV9jYXNlT3JkZXIpLmVxdWFscygidXBwZXItZmlyc3QiKSl7Ci0gICAgICAgICAgICBpZihkaWZmWzBdID09IFVQUEVSX0NBU0UpewotICAgICAgICAgICAgICAgIHJldHVybiAtMTsKLSAgICAgICAgICAgIH1lbHNlewotICAgICAgICAgICAgICAgIHJldHVybiAxOwotICAgICAgICAgICAgfQotICAgICAgIH1lbHNley8vIGxvd2VyLWZpcnN0Ci0gICAgICAgICAgICBpZihkaWZmWzBdID09IExPV0VSX0NBU0UpewotICAgICAgICAgICAgICAgIHJldHVybiAtMTsKLSAgICAgICAgICAgIH1lbHNlewotICAgICAgICAgICAgICAgIHJldHVybiAxOwotICAgICAgICAgICAgfQotICAgICAgIH0KLSAgIH1lbHNley8vIE5vIGNhc2UgZGlmZmVyZW5jZXMKLSAgICAgICAgcmV0dXJuIDA7Ci0gICB9Ci0KLSAgfQotCi0KLQotICBwcml2YXRlIGZpbmFsIGludFtdIGdldEZpcnN0Q2FzZURpZmYoZmluYWwgU3RyaW5nIHRleHQsIGZpbmFsIFN0cmluZyBwYXR0ZXJuLCBmaW5hbCBMb2NhbGUgbG9jYWxlKXsKLQotICAgICAgICBmaW5hbCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IgdGFyZ0l0ZXIgPSBtX2NvbGxhdG9yLmdldENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcih0ZXh0KTsKLSAgICAgICAgZmluYWwgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yIHBhdEl0ZXIgPSBtX2NvbGxhdG9yLmdldENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcihwYXR0ZXJuKTsKLSAgICAgICAgaW50IHN0YXJ0VGFyZyA9IC0xOwotICAgICAgICBpbnQgZW5kVGFyZyA9IC0xOwotICAgICAgICBpbnQgc3RhcnRQYXR0ID0gLTE7Ci0gICAgICAgIGludCBlbmRQYXR0ID0gLTE7Ci0gICAgICAgIGZpbmFsIGludCBkb25lID0gZ2V0RWxlbWVudChDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuTlVMTE9SREVSKTsKLSAgICAgICAgaW50IHBhdHRlcm5FbGVtZW50ID0gMCwgdGFyZ2V0RWxlbWVudCA9IDA7Ci0gICAgICAgIGJvb2xlYW4gZ2V0UGF0dGVybiA9IHRydWUsIGdldFRhcmdldCA9IHRydWU7Ci0KLSAgICAgICAgd2hpbGUgKHRydWUpIHsKLSAgICAgICAgICAgIGlmIChnZXRQYXR0ZXJuKXsKLSAgICAgICAgICAgICAgICAgc3RhcnRQYXR0ID0gcGF0SXRlci5nZXRPZmZzZXQoKTsKLSAgICAgICAgICAgICAgICAgcGF0dGVybkVsZW1lbnQgPSBnZXRFbGVtZW50KHBhdEl0ZXIubmV4dCgpKTsKLSAgICAgICAgICAgICAgICAgZW5kUGF0dCA9IHBhdEl0ZXIuZ2V0T2Zmc2V0KCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoKGdldFRhcmdldCkpewotICAgICAgICAgICAgICAgICBzdGFydFRhcmcgID0gdGFyZ0l0ZXIuZ2V0T2Zmc2V0KCk7Ci0gICAgICAgICAgICAgICAgIHRhcmdldEVsZW1lbnQgICA9IGdldEVsZW1lbnQodGFyZ0l0ZXIubmV4dCgpKTsKLSAgICAgICAgICAgICAgICAgZW5kVGFyZyAgPSB0YXJnSXRlci5nZXRPZmZzZXQoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGdldFRhcmdldCA9IGdldFBhdHRlcm4gPSB0cnVlOwotICAgICAgICAgICAgaWYgKChwYXR0ZXJuRWxlbWVudCA9PSBkb25lKSB8fCggdGFyZ2V0RWxlbWVudCA9PSBkb25lKSkgewotICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICAgICAgfSBlbHNlIGlmICh0YXJnZXRFbGVtZW50ID09IDApIHsKLSAgICAgICAgICAgICAgZ2V0UGF0dGVybiA9IGZhbHNlOwotICAgICAgICAgICAgfSBlbHNlIGlmIChwYXR0ZXJuRWxlbWVudCA9PSAwKSB7Ci0gICAgICAgICAgICAgIGdldFRhcmdldCA9IGZhbHNlOwotICAgICAgICAgICAgfSBlbHNlIGlmICh0YXJnZXRFbGVtZW50ICE9IHBhdHRlcm5FbGVtZW50KSB7Ly8gbWlzbWF0Y2gKLSAgICAgICAgICAgICAgICBpZigoc3RhcnRQYXR0IDwgZW5kUGF0dCkgJiYgKHN0YXJ0VGFyZyA8IGVuZFRhcmcpKXsKLSAgICAgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nICBzdWJUZXh0ID0gdGV4dC5zdWJzdHJpbmcoc3RhcnRUYXJnLCBlbmRUYXJnKTsKLSAgICAgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nICBzdWJQYXR0ID0gcGF0dGVybi5zdWJzdHJpbmcoc3RhcnRQYXR0LCBlbmRQYXR0KTsKLSAgICAgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nICBzdWJUZXh0VXAgPSBzdWJUZXh0LnRvVXBwZXJDYXNlKGxvY2FsZSk7Ci0gICAgICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyAgc3ViUGF0dFVwID0gc3ViUGF0dC50b1VwcGVyQ2FzZShsb2NhbGUpOwotICAgICAgICAgICAgICAgICAgICBpZihtX2NvbGxhdG9yLmNvbXBhcmUoc3ViVGV4dFVwLCBzdWJQYXR0VXApICE9IDApeyAvLyBub3QgY2FzZSBkaWZmZmVyZW5jZQotICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICBpbnQgZGlmZltdID0ge1VOS05PV05fQ0FTRSwgVU5LTk9XTl9DQVNFfTsKLSAgICAgICAgICAgICAgICAgICAgaWYobV9jb2xsYXRvci5jb21wYXJlKHN1YlRleHQsIHN1YlRleHRVcCkgPT0gMCl7Ci0gICAgICAgICAgICAgICAgICAgICAgICBkaWZmWzBdID0gVVBQRVJfQ0FTRTsKLSAgICAgICAgICAgICAgICAgICAgfWVsc2UgaWYobV9jb2xsYXRvci5jb21wYXJlKHN1YlRleHQsIHN1YlRleHQudG9Mb3dlckNhc2UobG9jYWxlKSkgPT0gMCl7Ci0gICAgICAgICAgICAgICAgICAgICAgIGRpZmZbMF0gPSBMT1dFUl9DQVNFOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGlmKG1fY29sbGF0b3IuY29tcGFyZShzdWJQYXR0LCBzdWJQYXR0VXApID09IDApewotICAgICAgICAgICAgICAgICAgICAgICAgZGlmZlsxXSA9IFVQUEVSX0NBU0U7Ci0gICAgICAgICAgICAgICAgICAgIH1lbHNlIGlmKG1fY29sbGF0b3IuY29tcGFyZShzdWJQYXR0LCBzdWJQYXR0LnRvTG93ZXJDYXNlKGxvY2FsZSkpID09IDApewotICAgICAgICAgICAgICAgICAgICAgICBkaWZmWzFdID0gTE9XRVJfQ0FTRTsKLSAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgIGlmKCgoZGlmZlswXSA9PSBVUFBFUl9DQVNFKSAmJiAoIGRpZmZbMV0gPT0gTE9XRVJfQ0FTRSkpIHx8Ci0gICAgICAgICAgICAgICAgICAgICAgICgoZGlmZlswXSA9PSBMT1dFUl9DQVNFKSAmJiAoIGRpZmZbMV0gPT0gVVBQRVJfQ0FTRSkpKXsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBkaWZmOwotICAgICAgICAgICAgICAgICAgICB9ZWxzZXsvLyBub3QgY2FzZSBkaWZmCi0gICAgICAgICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9ZWxzZXsKLSAgICAgICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gIH0KLQotCi0gLy8gUmV0dXJuIGEgbWFzayBmb3IgdGhlIHBhcnQgb2YgdGhlIG9yZGVyIHdlJ3JlIGludGVyZXN0ZWQgaW4KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgZ2V0TWFzayhmaW5hbCBpbnQgc3RyZW5ndGgpIHsKLSAgICAgICAgc3dpdGNoIChzdHJlbmd0aCkgewotICAgICAgICAgICAgY2FzZSBDb2xsYXRvci5QUklNQVJZOgotICAgICAgICAgICAgICAgIHJldHVybiAweEZGRkYwMDAwOwotICAgICAgICAgICAgY2FzZSBDb2xsYXRvci5TRUNPTkRBUlk6Ci0gICAgICAgICAgICAgICAgcmV0dXJuIDB4RkZGRkZGMDA7Ci0gICAgICAgICAgICBkZWZhdWx0OgotICAgICAgICAgICAgICAgIHJldHVybiAweEZGRkZGRkZGOwotICAgICAgICB9Ci0gICAgfQotICAgIC8vZ2V0IGNvbGxhdGlvbiBlbGVtZW50IHdpdGggZ2l2ZW4gc3RyZW5ndGgKLSAgICAvLyBmcm9tIHRoZSBlbGVtZW50IHdpdGggbWF4IHN0cmVuZ3RoCi0gIHByaXZhdGUgZmluYWwgaW50IGdldEVsZW1lbnQoaW50IG1heFN0cmVuZ3RoRWxlbWVudCl7Ci0KLSAgICByZXR1cm4gKG1heFN0cmVuZ3RoRWxlbWVudCAmIG1fbWFzayk7Ci0gIH0KLQotfS8vU3RyaW5nQ29tcGFyYWJsZQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvU3RyaW5nVG9JbnRUYWJsZS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvU3RyaW5nVG9JbnRUYWJsZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwZTk5ODRkLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL1N0cmluZ1RvSW50VGFibGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE5OCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBTdHJpbmdUb0ludFRhYmxlLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTUgMDg6MTU6NTUgc3VyZXNoX2VtYWlsaWQgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzOwotCi0vKioKLSAqIEEgdmVyeSBzaW1wbGUgbG9va3VwIHRhYmxlIHRoYXQgc3RvcmVzIGEgbGlzdCBvZiBzdHJpbmdzLCB0aGUgZXZlbgotICogbnVtYmVyIHN0cmluZ3MgYmVpbmcga2V5cywgYW5kIHRoZSBvZGQgbnVtYmVyIHN0cmluZ3MgYmVpbmcgdmFsdWVzLgotICogQHhzbC51c2FnZSBpbnRlcm5hbAotICovCi1wdWJsaWMgY2xhc3MgU3RyaW5nVG9JbnRUYWJsZQotewotCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElOVkFMSURfS0VZID0gLTEwMDAwOwotCi0gIC8qKiBCbG9jayBzaXplIHRvIGFsbG9jYXRlICAgICAgICAgICovCi0gIHByaXZhdGUgaW50IG1fYmxvY2tzaXplOwotCi0gIC8qKiBBcnJheSBvZiBzdHJpbmdzIHRoaXMgdGFibGUgcG9pbnRzIHRvLiBBc3NvY2lhdGVkIHdpdGggaW50cwotICAgKiBpbiBtX3ZhbHVlcyAgICAgICAgICovCi0gIHByaXZhdGUgU3RyaW5nIG1fbWFwW107Ci0KLSAgLyoqIEFycmF5IG9mIGludHMgdGhpcyB0YWJsZSBwb2ludHMuIEFzc29jaWF0ZWQgd2l0aCBzdHJpbmdzIGZyb20KLSAgICogbV9tYXAuICAgICAgICAgKi8KLSAgcHJpdmF0ZSBpbnQgbV92YWx1ZXNbXTsKLQotICAvKiogTnVtYmVyIG9mIGludHMgaW4gdGhlIHRhYmxlICAgICAgICAgICovCi0gIHByaXZhdGUgaW50IG1fZmlyc3RGcmVlID0gMDsKLQotICAvKiogU2l6ZSBvZiB0aGlzIHRhYmxlICAgICAgICAgKi8KLSAgcHJpdmF0ZSBpbnQgbV9tYXBTaXplOwotCi0gIC8qKgotICAgKiBEZWZhdWx0IGNvbnN0cnVjdG9yLiAgTm90ZSB0aGF0IHRoZSBkZWZhdWx0Ci0gICAqIGJsb2NrIHNpemUgaXMgdmVyeSBzbWFsbCwgZm9yIHNtYWxsIGxpc3RzLgotICAgKi8KLSAgcHVibGljIFN0cmluZ1RvSW50VGFibGUoKQotICB7Ci0KLSAgICBtX2Jsb2Nrc2l6ZSA9IDg7Ci0gICAgbV9tYXBTaXplID0gbV9ibG9ja3NpemU7Ci0gICAgbV9tYXAgPSBuZXcgU3RyaW5nW21fYmxvY2tzaXplXTsKLSAgICBtX3ZhbHVlcyA9IG5ldyBpbnRbbV9ibG9ja3NpemVdOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhIFN0cmluZ1RvSW50VGFibGUsIHVzaW5nIHRoZSBnaXZlbiBibG9jayBzaXplLgotICAgKgotICAgKiBAcGFyYW0gYmxvY2tzaXplIFNpemUgb2YgYmxvY2sgdG8gYWxsb2NhdGUKLSAgICovCi0gIHB1YmxpYyBTdHJpbmdUb0ludFRhYmxlKGludCBibG9ja3NpemUpCi0gIHsKLQotICAgIG1fYmxvY2tzaXplID0gYmxvY2tzaXplOwotICAgIG1fbWFwU2l6ZSA9IGJsb2Nrc2l6ZTsKLSAgICBtX21hcCA9IG5ldyBTdHJpbmdbYmxvY2tzaXplXTsKLSAgICBtX3ZhbHVlcyA9IG5ldyBpbnRbbV9ibG9ja3NpemVdOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbGVuZ3RoIG9mIHRoZSBsaXN0LgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBsZW5ndGggb2YgdGhlIGxpc3QKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBpbnQgZ2V0TGVuZ3RoKCkKLSAgewotICAgIHJldHVybiBtX2ZpcnN0RnJlZTsKLSAgfQotCi0gIC8qKgotICAgKiBBcHBlbmQgYSBzdHJpbmcgb250byB0aGUgdmVjdG9yLgotICAgKgotICAgKiBAcGFyYW0ga2V5IFN0cmluZyB0byBhcHBlbmQKLSAgICogQHBhcmFtIHZhbHVlIFRoZSBpbnQgdmFsdWUgb2YgdGhlIHN0cmluZwotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgcHV0KFN0cmluZyBrZXksIGludCB2YWx1ZSkKLSAgewotCi0gICAgaWYgKChtX2ZpcnN0RnJlZSArIDEpID49IG1fbWFwU2l6ZSkKLSAgICB7Ci0gICAgICBtX21hcFNpemUgKz0gbV9ibG9ja3NpemU7Ci0KLSAgICAgIFN0cmluZyBuZXdNYXBbXSA9IG5ldyBTdHJpbmdbbV9tYXBTaXplXTsKLQotICAgICAgU3lzdGVtLmFycmF5Y29weShtX21hcCwgMCwgbmV3TWFwLCAwLCBtX2ZpcnN0RnJlZSArIDEpOwotCi0gICAgICBtX21hcCA9IG5ld01hcDsKLQotICAgICAgaW50IG5ld1ZhbHVlc1tdID0gbmV3IGludFttX21hcFNpemVdOwotCi0gICAgICBTeXN0ZW0uYXJyYXljb3B5KG1fdmFsdWVzLCAwLCBuZXdWYWx1ZXMsIDAsIG1fZmlyc3RGcmVlICsgMSk7Ci0KLSAgICAgIG1fdmFsdWVzID0gbmV3VmFsdWVzOwotICAgIH0KLQotICAgIG1fbWFwW21fZmlyc3RGcmVlXSA9IGtleTsKLSAgICBtX3ZhbHVlc1ttX2ZpcnN0RnJlZV0gPSB2YWx1ZTsKLQotICAgIG1fZmlyc3RGcmVlKys7Ci0gIH0KLQotICAvKioKLSAgICogVGVsbCBpZiB0aGUgdGFibGUgY29udGFpbnMgdGhlIGdpdmVuIHN0cmluZy4KLSAgICoKLSAgICogQHBhcmFtIGtleSBTdHJpbmcgdG8gbG9vayBmb3IKLSAgICoKLSAgICogQHJldHVybiBUaGUgU3RyaW5nJ3MgaW50IHZhbHVlCi0gICAqCi0gICAqLwotICBwdWJsaWMgZmluYWwgaW50IGdldChTdHJpbmcga2V5KQotICB7Ci0KLSAgICBmb3IgKGludCBpID0gMDsgaSA8IG1fZmlyc3RGcmVlOyBpKyspCi0gICAgewotICAgICAgaWYgKG1fbWFwW2ldLmVxdWFscyhrZXkpKQotICAgICAgICByZXR1cm4gbV92YWx1ZXNbaV07Ci0gICAgfQotCi0gICAgICAgIHJldHVybiBJTlZBTElEX0tFWTsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIGlmIHRoZSB0YWJsZSBjb250YWlucyB0aGUgZ2l2ZW4gc3RyaW5nLiBJZ25vcmUgY2FzZS4KLSAgICoKLSAgICogQHBhcmFtIGtleSBTdHJpbmcgdG8gbG9vayBmb3IKLSAgICoKLSAgICogQHJldHVybiBUaGUgc3RyaW5nJ3MgaW50IHZhbHVlCi0gICAqLwotICBwdWJsaWMgZmluYWwgaW50IGdldElnbm9yZUNhc2UoU3RyaW5nIGtleSkKLSAgewotCi0gICAgaWYgKG51bGwgPT0ga2V5KQotICAgICAgICByZXR1cm4gSU5WQUxJRF9LRVk7Ci0KLSAgICBmb3IgKGludCBpID0gMDsgaSA8IG1fZmlyc3RGcmVlOyBpKyspCi0gICAgewotICAgICAgaWYgKG1fbWFwW2ldLmVxdWFsc0lnbm9yZUNhc2Uoa2V5KSkKLSAgICAgICAgcmV0dXJuIG1fdmFsdWVzW2ldOwotICAgIH0KLQotICAgIHJldHVybiBJTlZBTElEX0tFWTsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIGlmIHRoZSB0YWJsZSBjb250YWlucyB0aGUgZ2l2ZW4gc3RyaW5nLgotICAgKgotICAgKiBAcGFyYW0ga2V5IFN0cmluZyB0byBsb29rIGZvcgotICAgKgotICAgKiBAcmV0dXJuIFRydWUgaWYgdGhlIHN0cmluZyBpcyBpbiB0aGUgdGFibGUKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBib29sZWFuIGNvbnRhaW5zKFN0cmluZyBrZXkpCi0gIHsKLQotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbV9maXJzdEZyZWU7IGkrKykKLSAgICB7Ci0gICAgICBpZiAobV9tYXBbaV0uZXF1YWxzKGtleSkpCi0gICAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotICAgIHJldHVybiBmYWxzZTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gYXJyYXkgb2Yga2V5cyBpbiB0aGUgdGFibGUuCi0gICAqCi0gICAqIEByZXR1cm4gQXJyYXkgb2Ygc3RyaW5ncwotICAgKi8KLSAgcHVibGljIGZpbmFsIFN0cmluZ1tdIGtleXMoKQotICB7Ci0gICAgU3RyaW5nIFtdIGtleXNBcnIgPSBuZXcgU3RyaW5nW21fZmlyc3RGcmVlXTsKLQotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbV9maXJzdEZyZWU7IGkrKykKLSAgICB7Ci0gICAgICBrZXlzQXJyW2ldID0gbV9tYXBbaV07Ci0gICAgfQotCi0gICAgcmV0dXJuIGtleXNBcnI7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL1N0cmluZ1RvU3RyaW5nVGFibGUuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL1N0cmluZ1RvU3RyaW5nVGFibGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDJmZTljZC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9TdHJpbmdUb1N0cmluZ1RhYmxlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyNDQgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogU3RyaW5nVG9TdHJpbmdUYWJsZS5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE1IDA4OjE1OjU2IHN1cmVzaF9lbWFpbGlkIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlsczsKLQotLyoqCi0gKiBBIHZlcnkgc2ltcGxlIGxvb2t1cCB0YWJsZSB0aGF0IHN0b3JlcyBhIGxpc3Qgb2Ygc3RyaW5ncywgdGhlIGV2ZW4KLSAqIG51bWJlciBzdHJpbmdzIGJlaW5nIGtleXMsIGFuZCB0aGUgb2RkIG51bWJlciBzdHJpbmdzIGJlaW5nIHZhbHVlcy4KLSAqIEB4c2wudXNhZ2UgaW50ZXJuYWwKLSAqLwotcHVibGljIGNsYXNzIFN0cmluZ1RvU3RyaW5nVGFibGUKLXsKLQotICAvKiogU2l6ZSBvZiBibG9ja3MgdG8gYWxsb2NhdGUgICAgICAgICAgKi8KLSAgcHJpdmF0ZSBpbnQgbV9ibG9ja3NpemU7Ci0KLSAgLyoqIEFycmF5IG9mIHN0cmluZ3MgdGhpcyBjb250YWlucyAgICAgICAgICAqLwotICBwcml2YXRlIFN0cmluZyBtX21hcFtdOwotCi0gIC8qKiBOdW1iZXIgb2Ygc3RyaW5ncyB0aGlzIGNvbnRhaW5zICAgICAgICAgICAqLwotICBwcml2YXRlIGludCBtX2ZpcnN0RnJlZSA9IDA7Ci0KLSAgLyoqIFNpemUgb2YgdGhpcyB0YWJsZSAgICAgICAgICAgKi8KLSAgcHJpdmF0ZSBpbnQgbV9tYXBTaXplOwotCi0gIC8qKgotICAgKiBEZWZhdWx0IGNvbnN0cnVjdG9yLiAgTm90ZSB0aGF0IHRoZSBkZWZhdWx0Ci0gICAqIGJsb2NrIHNpemUgaXMgdmVyeSBzbWFsbCwgZm9yIHNtYWxsIGxpc3RzLgotICAgKi8KLSAgcHVibGljIFN0cmluZ1RvU3RyaW5nVGFibGUoKQotICB7Ci0KLSAgICBtX2Jsb2Nrc2l6ZSA9IDE2OwotICAgIG1fbWFwU2l6ZSA9IG1fYmxvY2tzaXplOwotICAgIG1fbWFwID0gbmV3IFN0cmluZ1ttX2Jsb2Nrc2l6ZV07Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgU3RyaW5nVG9TdHJpbmdUYWJsZSwgdXNpbmcgdGhlIGdpdmVuIGJsb2NrIHNpemUuCi0gICAqCi0gICAqIEBwYXJhbSBibG9ja3NpemUgU2l6ZSBvZiBibG9ja3MgdG8gYWxsb2NhdGUKLSAgICovCi0gIHB1YmxpYyBTdHJpbmdUb1N0cmluZ1RhYmxlKGludCBibG9ja3NpemUpCi0gIHsKLQotICAgIG1fYmxvY2tzaXplID0gYmxvY2tzaXplOwotICAgIG1fbWFwU2l6ZSA9IGJsb2Nrc2l6ZTsKLSAgICBtX21hcCA9IG5ldyBTdHJpbmdbYmxvY2tzaXplXTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGxlbmd0aCBvZiB0aGUgbGlzdC4KLSAgICoKLSAgICogQHJldHVybiBOdW1iZXIgb2Ygc3RyaW5ncyBpbiB0aGUgbGlzdAotICAgKi8KLSAgcHVibGljIGZpbmFsIGludCBnZXRMZW5ndGgoKQotICB7Ci0gICAgcmV0dXJuIG1fZmlyc3RGcmVlOwotICB9Ci0KLSAgLyoqCi0gICAqIEFwcGVuZCBhIHN0cmluZyBvbnRvIHRoZSB2ZWN0b3IuCi0gICAqIFRoZSBzdHJpbmdzIGdvIHRvIHRoZSBldmVuIGxvY2F0aW9ucyBpbiB0aGUgYXJyYXkKLSAgICogYW5kIHRoZSB2YWx1ZXMgaW4gdGhlIG9kZC4KLSAgICoKLSAgICogQHBhcmFtIGtleSBTdHJpbmcgdG8gYWRkIHRvIHRoZSBsaXN0Ci0gICAqIEBwYXJhbSB2YWx1ZSBWYWx1ZSBvZiB0aGUgc3RyaW5nCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBwdXQoU3RyaW5nIGtleSwgU3RyaW5nIHZhbHVlKQotICB7Ci0KLSAgICBpZiAoKG1fZmlyc3RGcmVlICsgMikgPj0gbV9tYXBTaXplKQotICAgIHsKLSAgICAgIG1fbWFwU2l6ZSArPSBtX2Jsb2Nrc2l6ZTsKLQotICAgICAgU3RyaW5nIG5ld01hcFtdID0gbmV3IFN0cmluZ1ttX21hcFNpemVdOwotCi0gICAgICBTeXN0ZW0uYXJyYXljb3B5KG1fbWFwLCAwLCBuZXdNYXAsIDAsIG1fZmlyc3RGcmVlICsgMSk7Ci0KLSAgICAgIG1fbWFwID0gbmV3TWFwOwotICAgIH0KLQotICAgIG1fbWFwW21fZmlyc3RGcmVlXSA9IGtleTsKLQotICAgIG1fZmlyc3RGcmVlKys7Ci0KLSAgICBtX21hcFttX2ZpcnN0RnJlZV0gPSB2YWx1ZTsKLQotICAgIG1fZmlyc3RGcmVlKys7Ci0gIH0KLQotICAvKioKLSAgICogVGVsbCBpZiB0aGUgdGFibGUgY29udGFpbnMgdGhlIGdpdmVuIHN0cmluZy4KLSAgICoKLSAgICogQHBhcmFtIGtleSBTdHJpbmcgdG8gbG9vayB1cAotICAgKgotICAgKiBAcmV0dXJuIHJldHVybiB0aGUgdmFsdWUgb2YgdGhlIHN0cmluZyBvciBudWxsIGlmIG5vdCBmb3VuZC4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBTdHJpbmcgZ2V0KFN0cmluZyBrZXkpCi0gIHsKLQotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbV9maXJzdEZyZWU7IGkgKz0gMikKLSAgICB7Ci0gICAgICBpZiAobV9tYXBbaV0uZXF1YWxzKGtleSkpCi0gICAgICAgIHJldHVybiBtX21hcFtpICsgMV07Ci0gICAgfQotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogUmVtb3ZlIHRoZSBnaXZlbiBzdHJpbmcgYW5kIGl0cyB2YWx1ZSBmcm9tIHRoaXMgdGFibGUuCi0gICAqCi0gICAqIEBwYXJhbSBrZXkgU3RyaW5nIHRvIHJlbW92ZSBmcm9tIHRoZSB0YWJsZQotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgcmVtb3ZlKFN0cmluZyBrZXkpCi0gIHsKLQotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbV9maXJzdEZyZWU7IGkgKz0gMikKLSAgICB7Ci0gICAgICBpZiAobV9tYXBbaV0uZXF1YWxzKGtleSkpCi0gICAgICB7Ci0gICAgICAgIGlmICgoaSArIDIpIDwgbV9maXJzdEZyZWUpCi0gICAgICAgICAgU3lzdGVtLmFycmF5Y29weShtX21hcCwgaSArIDIsIG1fbWFwLCBpLCBtX2ZpcnN0RnJlZSAtIChpICsgMikpOwotCi0gICAgICAgIG1fZmlyc3RGcmVlIC09IDI7Ci0gICAgICAgIG1fbWFwW21fZmlyc3RGcmVlXSA9IG51bGw7Ci0gICAgICAgIG1fbWFwW21fZmlyc3RGcmVlICsgMV0gPSBudWxsOwotCi0gICAgICAgIGJyZWFrOwotICAgICAgfQotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIGlmIHRoZSB0YWJsZSBjb250YWlucyB0aGUgZ2l2ZW4gc3RyaW5nLiBJZ25vcmUgY2FzZQotICAgKgotICAgKiBAcGFyYW0ga2V5IFN0cmluZyB0byBsb29rIHVwCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHZhbHVlIG9mIHRoZSBzdHJpbmcgb3IgbnVsbCBpZiBub3QgZm91bmQKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBTdHJpbmcgZ2V0SWdub3JlQ2FzZShTdHJpbmcga2V5KQotICB7Ci0KLSAgICBpZiAobnVsbCA9PSBrZXkpCi0gICAgICByZXR1cm4gbnVsbDsKLQotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbV9maXJzdEZyZWU7IGkgKz0gMikKLSAgICB7Ci0gICAgICBpZiAobV9tYXBbaV0uZXF1YWxzSWdub3JlQ2FzZShrZXkpKQotICAgICAgICByZXR1cm4gbV9tYXBbaSArIDFdOwotICAgIH0KLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgdGhlIHRhYmxlIGNvbnRhaW5zIHRoZSBnaXZlbiBzdHJpbmcgaW4gdGhlIHZhbHVlLgotICAgKgotICAgKiBAcGFyYW0gdmFsIFZhbHVlIG9mIHRoZSBzdHJpbmcgdG8gbG9vayB1cAotICAgKgotICAgKiBAcmV0dXJuIHRoZSBzdHJpbmcgYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiB2YWx1ZSBvciBudWxsIGlmIG5vdCBmb3VuZAotICAgKi8KLSAgcHVibGljIGZpbmFsIFN0cmluZyBnZXRCeVZhbHVlKFN0cmluZyB2YWwpCi0gIHsKLQotICAgIGZvciAoaW50IGkgPSAxOyBpIDwgbV9maXJzdEZyZWU7IGkgKz0gMikKLSAgICB7Ci0gICAgICBpZiAobV9tYXBbaV0uZXF1YWxzKHZhbCkpCi0gICAgICAgIHJldHVybiBtX21hcFtpIC0gMV07Ci0gICAgfQotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBudGggZWxlbWVudC4KLSAgICoKLSAgICogQHBhcmFtIGkgaW5kZXggb2YgdGhlIHN0cmluZyB0byBsb29rIHVwLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBzdHJpbmcgYXQgdGhlIGdpdmVuIGluZGV4LgotICAgKi8KLSAgcHVibGljIGZpbmFsIFN0cmluZyBlbGVtZW50QXQoaW50IGkpCi0gIHsKLSAgICByZXR1cm4gbV9tYXBbaV07Ci0gIH0KLQotICAvKioKLSAgICogVGVsbCBpZiB0aGUgdGFibGUgY29udGFpbnMgdGhlIGdpdmVuIHN0cmluZy4KLSAgICoKLSAgICogQHBhcmFtIGtleSBTdHJpbmcgdG8gbG9vayB1cAotICAgKgotICAgKiBAcmV0dXJuIFRydWUgaWYgdGhlIGdpdmVuIHN0cmluZyBpcyBpbiB0aGlzIHRhYmxlCi0gICAqLwotICBwdWJsaWMgZmluYWwgYm9vbGVhbiBjb250YWlucyhTdHJpbmcga2V5KQotICB7Ci0KLSAgICBmb3IgKGludCBpID0gMDsgaSA8IG1fZmlyc3RGcmVlOyBpICs9IDIpCi0gICAgewotICAgICAgaWYgKG1fbWFwW2ldLmVxdWFscyhrZXkpKQotICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICB9Ci0KLSAgICByZXR1cm4gZmFsc2U7Ci0gIH0KLQotICAvKioKLSAgICogVGVsbCBpZiB0aGUgdGFibGUgY29udGFpbnMgdGhlIGdpdmVuIHN0cmluZy4KLSAgICoKLSAgICogQHBhcmFtIHZhbCB2YWx1ZSB0byBsb29rIHVwCi0gICAqCi0gICAqIEByZXR1cm4gVHJ1ZSBpZiB0aGUgZ2l2ZW4gdmFsdWUgaXMgaW4gdGhlIHRhYmxlLgotICAgKi8KLSAgcHVibGljIGZpbmFsIGJvb2xlYW4gY29udGFpbnNWYWx1ZShTdHJpbmcgdmFsKQotICB7Ci0KLSAgICBmb3IgKGludCBpID0gMTsgaSA8IG1fZmlyc3RGcmVlOyBpICs9IDIpCi0gICAgewotICAgICAgaWYgKG1fbWFwW2ldLmVxdWFscyh2YWwpKQotICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICB9Ci0KLSAgICByZXR1cm4gZmFsc2U7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL1N0cmluZ1RvU3RyaW5nVGFibGVWZWN0b3IuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL1N0cmluZ1RvU3RyaW5nVGFibGVWZWN0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMWVlZWM0Yy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9TdHJpbmdUb1N0cmluZ1RhYmxlVmVjdG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMDEgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogU3RyaW5nVG9TdHJpbmdUYWJsZVZlY3Rvci5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE1IDA4OjE1OjU2IHN1cmVzaF9lbWFpbGlkIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlsczsKLQotLyoqCi0gKiBBIHZlcnkgc2ltcGxlIHRhYmxlIHRoYXQgc3RvcmVzIGEgbGlzdCBvZiBTdHJpbmdUb1N0cmluZ1RhYmxlcywgb3B0aW1pemVkCi0gKiBmb3Igc21hbGwgbGlzdHMuCi0gKiBAeHNsLnVzYWdlIGludGVybmFsCi0gKi8KLXB1YmxpYyBjbGFzcyBTdHJpbmdUb1N0cmluZ1RhYmxlVmVjdG9yCi17Ci0KLSAgLyoqIFNpemUgb2YgYmxvY2tzIHRvIGFsbG9jYXRlICAgICAgICAgKi8KLSAgcHJpdmF0ZSBpbnQgbV9ibG9ja3NpemU7Ci0KLSAgLyoqIEFycmF5IG9mIFN0cmluZ1RvU3RyaW5nVGFibGUgb2JqZWN0cyAgICAgICAgICAqLwotICBwcml2YXRlIFN0cmluZ1RvU3RyaW5nVGFibGUgbV9tYXBbXTsKLQotICAvKiogTnVtYmVyIG9mIFN0cmluZ1RvU3RyaW5nVGFibGUgb2JqZWN0cyBpbiB0aGlzIGFycmF5ICAgICAgICAgICovCi0gIHByaXZhdGUgaW50IG1fZmlyc3RGcmVlID0gMDsKLQotICAvKiogU2l6ZSBvZiB0aGlzIGFycmF5ICAgICAgICAgICovCi0gIHByaXZhdGUgaW50IG1fbWFwU2l6ZTsKLQotICAvKioKLSAgICogRGVmYXVsdCBjb25zdHJ1Y3Rvci4gIE5vdGUgdGhhdCB0aGUgZGVmYXVsdAotICAgKiBibG9jayBzaXplIGlzIHZlcnkgc21hbGwsIGZvciBzbWFsbCBsaXN0cy4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmdUb1N0cmluZ1RhYmxlVmVjdG9yKCkKLSAgewotCi0gICAgbV9ibG9ja3NpemUgPSA4OwotICAgIG1fbWFwU2l6ZSA9IG1fYmxvY2tzaXplOwotICAgIG1fbWFwID0gbmV3IFN0cmluZ1RvU3RyaW5nVGFibGVbbV9ibG9ja3NpemVdOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhIFN0cmluZ1RvU3RyaW5nVGFibGVWZWN0b3IsIHVzaW5nIHRoZSBnaXZlbiBibG9jayBzaXplLgotICAgKgotICAgKiBAcGFyYW0gYmxvY2tzaXplIFNpemUgb2YgYmxvY2tzIHRvIGFsbG9jYXRlCi0gICAqLwotICBwdWJsaWMgU3RyaW5nVG9TdHJpbmdUYWJsZVZlY3RvcihpbnQgYmxvY2tzaXplKQotICB7Ci0KLSAgICBtX2Jsb2Nrc2l6ZSA9IGJsb2Nrc2l6ZTsKLSAgICBtX21hcFNpemUgPSBibG9ja3NpemU7Ci0gICAgbV9tYXAgPSBuZXcgU3RyaW5nVG9TdHJpbmdUYWJsZVtibG9ja3NpemVdOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbGVuZ3RoIG9mIHRoZSBsaXN0LgotICAgKgotICAgKiBAcmV0dXJuIE51bWJlciBvZiBTdHJpbmdUb1N0cmluZ1RhYmxlIG9iamVjdHMgaW4gdGhlIGxpc3QKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBpbnQgZ2V0TGVuZ3RoKCkKLSAgewotICAgIHJldHVybiBtX2ZpcnN0RnJlZTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGxlbmd0aCBvZiB0aGUgbGlzdC4KLSAgICoKLSAgICogQHJldHVybiBOdW1iZXIgb2YgU3RyaW5nVG9TdHJpbmdUYWJsZSBvYmplY3RzIGluIHRoZSBsaXN0Ci0gICAqLwotICBwdWJsaWMgZmluYWwgaW50IHNpemUoKQotICB7Ci0gICAgcmV0dXJuIG1fZmlyc3RGcmVlOwotICB9Ci0KLSAgLyoqCi0gICAqIEFwcGVuZCBhIFN0cmluZ1RvU3RyaW5nVGFibGUgb2JqZWN0IG9udG8gdGhlIHZlY3Rvci4KLSAgICoKLSAgICogQHBhcmFtIHZhbHVlIFN0cmluZ1RvU3RyaW5nVGFibGUgb2JqZWN0IHRvIGFkZAotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgYWRkRWxlbWVudChTdHJpbmdUb1N0cmluZ1RhYmxlIHZhbHVlKQotICB7Ci0KLSAgICBpZiAoKG1fZmlyc3RGcmVlICsgMSkgPj0gbV9tYXBTaXplKQotICAgIHsKLSAgICAgIG1fbWFwU2l6ZSArPSBtX2Jsb2Nrc2l6ZTsKLQotICAgICAgU3RyaW5nVG9TdHJpbmdUYWJsZSBuZXdNYXBbXSA9IG5ldyBTdHJpbmdUb1N0cmluZ1RhYmxlW21fbWFwU2l6ZV07Ci0KLSAgICAgIFN5c3RlbS5hcnJheWNvcHkobV9tYXAsIDAsIG5ld01hcCwgMCwgbV9maXJzdEZyZWUgKyAxKTsKLQotICAgICAgbV9tYXAgPSBuZXdNYXA7Ci0gICAgfQotCi0gICAgbV9tYXBbbV9maXJzdEZyZWVdID0gdmFsdWU7Ci0KLSAgICBtX2ZpcnN0RnJlZSsrOwotICB9Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgc3RyaW5nLCBmaW5kIHRoZSBsYXN0IGFkZGVkIG9jY3VyYW5jZSB2YWx1ZQotICAgKiB0aGF0IG1hdGNoZXMgdGhlIGtleS4KLSAgICoKLSAgICogQHBhcmFtIGtleSBTdHJpbmcgdG8gbG9vayB1cAotICAgKgotICAgKiBAcmV0dXJuIHRoZSBsYXN0IGFkZGVkIG9jY3VyYW5jZSB2YWx1ZSB0aGF0IG1hdGNoZXMgdGhlIGtleQotICAgKiBvciBudWxsIGlmIG5vdCBmb3VuZC4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBTdHJpbmcgZ2V0KFN0cmluZyBrZXkpCi0gIHsKLQotICAgIGZvciAoaW50IGkgPSBtX2ZpcnN0RnJlZSAtIDE7IGkgPj0gMDsgLS1pKQotICAgIHsKLSAgICAgIFN0cmluZyBuc3VyaSA9IG1fbWFwW2ldLmdldChrZXkpOwotCi0gICAgICBpZiAobnN1cmkgIT0gbnVsbCkKLSAgICAgICAgcmV0dXJuIG5zdXJpOwotICAgIH0KLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgc3RyaW5nLCBmaW5kIG91dCBpZiB0aGVyZSBpcyBhIHZhbHVlIGluIHRoaXMgdGFibGUKLSAgICogdGhhdCBtYXRjaGVzIHRoZSBrZXkuCi0gICAqCi0gICAqIEBwYXJhbSBrZXkgU3RyaW5nIHRvIGxvb2sgZm9yCi0gICAqCi0gICAqIEByZXR1cm4gVHJ1ZSBpZiB0aGUgc3RyaW5nIHdhcyBmb3VuZCBpbiB0YWJsZSwgbnVsbCBpZiBub3QKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBib29sZWFuIGNvbnRhaW5zS2V5KFN0cmluZyBrZXkpCi0gIHsKLQotICAgIGZvciAoaW50IGkgPSBtX2ZpcnN0RnJlZSAtIDE7IGkgPj0gMDsgLS1pKQotICAgIHsKLSAgICAgIGlmIChtX21hcFtpXS5nZXQoa2V5KSAhPSBudWxsKQotICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICB9Ci0KLSAgICByZXR1cm4gZmFsc2U7Ci0gIH0KLQotICAvKioKLSAgICogUmVtb3ZlIHRoZSBsYXN0IGVsZW1lbnQuCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCByZW1vdmVMYXN0RWxlbSgpCi0gIHsKLQotICAgIGlmIChtX2ZpcnN0RnJlZSA+IDApCi0gICAgewotICAgICAgbV9tYXBbbV9maXJzdEZyZWVdID0gbnVsbDsKLQotICAgICAgbV9maXJzdEZyZWUtLTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBudGggZWxlbWVudC4KLSAgICoKLSAgICogQHBhcmFtIGkgSW5kZXggb2YgZWxlbWVudCB0byBmaW5kCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIFN0cmluZ1RvU3RyaW5nVGFibGUgb2JqZWN0IGF0IHRoZSBnaXZlbiBpbmRleAotICAgKi8KLSAgcHVibGljIGZpbmFsIFN0cmluZ1RvU3RyaW5nVGFibGUgZWxlbWVudEF0KGludCBpKQotICB7Ci0gICAgcmV0dXJuIG1fbWFwW2ldOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgdGhlIHRhYmxlIGNvbnRhaW5zIHRoZSBnaXZlbiBTdHJpbmdUb1N0cmluZ1RhYmxlLgotICAgKgotICAgKiBAcGFyYW0gcyBUaGUgU3RyaW5nVG9TdHJpbmdUYWJsZSB0byBmaW5kCi0gICAqCi0gICAqIEByZXR1cm4gVHJ1ZSBpZiB0aGUgU3RyaW5nVG9TdHJpbmdUYWJsZSBpcyBmb3VuZAotICAgKi8KLSAgcHVibGljIGZpbmFsIGJvb2xlYW4gY29udGFpbnMoU3RyaW5nVG9TdHJpbmdUYWJsZSBzKQotICB7Ci0KLSAgICBmb3IgKGludCBpID0gMDsgaSA8IG1fZmlyc3RGcmVlOyBpKyspCi0gICAgewotICAgICAgaWYgKG1fbWFwW2ldLmVxdWFscyhzKSkKLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotCi0gICAgcmV0dXJuIGZhbHNlOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9TdHJpbmdWZWN0b3IuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL1N0cmluZ1ZlY3Rvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwYWNiYmMxLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL1N0cmluZ1ZlY3Rvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjI1ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFN0cmluZ1ZlY3Rvci5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE1IDA4OjE1OjU2IHN1cmVzaF9lbWFpbGlkIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlsczsKLQotLyoqCi0gKiBBIHZlcnkgc2ltcGxlIHRhYmxlIHRoYXQgc3RvcmVzIGEgbGlzdCBvZiBzdHJpbmdzLCBvcHRpbWl6ZWQKLSAqIGZvciBzbWFsbCBsaXN0cy4KLSAqIEB4c2wudXNhZ2UgaW50ZXJuYWwKLSAqLwotcHVibGljIGNsYXNzIFN0cmluZ1ZlY3RvciBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlCi17Ci0gICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDQ5OTUyMzQ5NzIwMzI5MTk3NDhMOwotCi0gIC8qKiBAc2VyaWFsIFNpemUgb2YgYmxvY2tzIHRvIGFsbG9jYXRlICAgICAgICAgICAqLwotICBwcm90ZWN0ZWQgaW50IG1fYmxvY2tzaXplOwotCi0gIC8qKiBAc2VyaWFsIEFycmF5IG9mIHN0cmluZ3MgdGhpcyBjb250YWlucyAgICAgICAgICAqLwotICBwcm90ZWN0ZWQgU3RyaW5nIG1fbWFwW107Ci0KLSAgLyoqIEBzZXJpYWwgTnVtYmVyIG9mIHN0cmluZ3MgdGhpcyBjb250YWlucyAgICAgICAgICAqLwotICBwcm90ZWN0ZWQgaW50IG1fZmlyc3RGcmVlID0gMDsKLQotICAvKiogQHNlcmlhbCBTaXplIG9mIHRoZSBhcnJheSAgICAgICAgICAqLwotICBwcm90ZWN0ZWQgaW50IG1fbWFwU2l6ZTsKLQotICAvKioKLSAgICogRGVmYXVsdCBjb25zdHJ1Y3Rvci4gIE5vdGUgdGhhdCB0aGUgZGVmYXVsdAotICAgKiBibG9jayBzaXplIGlzIHZlcnkgc21hbGwsIGZvciBzbWFsbCBsaXN0cy4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmdWZWN0b3IoKQotICB7Ci0KLSAgICBtX2Jsb2Nrc2l6ZSA9IDg7Ci0gICAgbV9tYXBTaXplID0gbV9ibG9ja3NpemU7Ci0gICAgbV9tYXAgPSBuZXcgU3RyaW5nW21fYmxvY2tzaXplXTsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBTdHJpbmdWZWN0b3IsIHVzaW5nIHRoZSBnaXZlbiBibG9jayBzaXplLgotICAgKgotICAgKiBAcGFyYW0gYmxvY2tzaXplIFNpemUgb2YgdGhlIGJsb2NrcyB0byBhbGxvY2F0ZQotICAgKi8KLSAgcHVibGljIFN0cmluZ1ZlY3RvcihpbnQgYmxvY2tzaXplKQotICB7Ci0KLSAgICBtX2Jsb2Nrc2l6ZSA9IGJsb2Nrc2l6ZTsKLSAgICBtX21hcFNpemUgPSBibG9ja3NpemU7Ci0gICAgbV9tYXAgPSBuZXcgU3RyaW5nW2Jsb2Nrc2l6ZV07Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBsZW5ndGggb2YgdGhlIGxpc3QuCi0gICAqCi0gICAqIEByZXR1cm4gTnVtYmVyIG9mIHN0cmluZ3MgaW4gdGhlIGxpc3QKLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0TGVuZ3RoKCkKLSAgewotICAgIHJldHVybiBtX2ZpcnN0RnJlZTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGxlbmd0aCBvZiB0aGUgbGlzdC4KLSAgICoKLSAgICogQHJldHVybiBOdW1iZXIgb2Ygc3RyaW5ncyBpbiB0aGUgbGlzdAotICAgKi8KLSAgcHVibGljIGZpbmFsIGludCBzaXplKCkKLSAgewotICAgIHJldHVybiBtX2ZpcnN0RnJlZTsKLSAgfQotCi0gIC8qKgotICAgKiBBcHBlbmQgYSBzdHJpbmcgb250byB0aGUgdmVjdG9yLgotICAgKgotICAgKiBAcGFyYW0gdmFsdWUgU3RpbmcgdG8gYWRkIHRvIHRoZSB2ZWN0b3IKLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIGFkZEVsZW1lbnQoU3RyaW5nIHZhbHVlKQotICB7Ci0KLSAgICBpZiAoKG1fZmlyc3RGcmVlICsgMSkgPj0gbV9tYXBTaXplKQotICAgIHsKLSAgICAgIG1fbWFwU2l6ZSArPSBtX2Jsb2Nrc2l6ZTsKLQotICAgICAgU3RyaW5nIG5ld01hcFtdID0gbmV3IFN0cmluZ1ttX21hcFNpemVdOwotCi0gICAgICBTeXN0ZW0uYXJyYXljb3B5KG1fbWFwLCAwLCBuZXdNYXAsIDAsIG1fZmlyc3RGcmVlICsgMSk7Ci0KLSAgICAgIG1fbWFwID0gbmV3TWFwOwotICAgIH0KLQotICAgIG1fbWFwW21fZmlyc3RGcmVlXSA9IHZhbHVlOwotCi0gICAgbV9maXJzdEZyZWUrKzsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIG50aCBlbGVtZW50LgotICAgKgotICAgKiBAcGFyYW0gaSBJbmRleCBvZiBzdHJpbmcgdG8gZmluZAotICAgKgotICAgKiBAcmV0dXJuIFN0cmluZyBhdCBnaXZlbiBpbmRleAotICAgKi8KLSAgcHVibGljIGZpbmFsIFN0cmluZyBlbGVtZW50QXQoaW50IGkpCi0gIHsKLSAgICByZXR1cm4gbV9tYXBbaV07Ci0gIH0KLQotICAvKioKLSAgICogVGVsbCBpZiB0aGUgdGFibGUgY29udGFpbnMgdGhlIGdpdmVuIHN0cmluZy4KLSAgICoKLSAgICogQHBhcmFtIHMgU3RyaW5nIHRvIGxvb2sgZm9yCi0gICAqCi0gICAqIEByZXR1cm4gVHJ1ZSBpZiB0aGUgc3RyaW5nIGlzIGluIHRoaXMgdGFibGUKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBib29sZWFuIGNvbnRhaW5zKFN0cmluZyBzKQotICB7Ci0KLSAgICBpZiAobnVsbCA9PSBzKQotICAgICAgcmV0dXJuIGZhbHNlOwotCi0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtX2ZpcnN0RnJlZTsgaSsrKQotICAgIHsKLSAgICAgIGlmIChtX21hcFtpXS5lcXVhbHMocykpCi0gICAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotICAgIHJldHVybiBmYWxzZTsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIGlmIHRoZSB0YWJsZSBjb250YWlucyB0aGUgZ2l2ZW4gc3RyaW5nLiBJZ25vcmUgY2FzZS4KLSAgICoKLSAgICogQHBhcmFtIHMgU3RyaW5nIHRvIGZpbmQKLSAgICoKLSAgICogQHJldHVybiBUcnVlIGlmIHRoZSBTdHJpbmcgaXMgaW4gdGhpcyB2ZWN0b3IKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBib29sZWFuIGNvbnRhaW5zSWdub3JlQ2FzZShTdHJpbmcgcykKLSAgewotCi0gICAgaWYgKG51bGwgPT0gcykKLSAgICAgIHJldHVybiBmYWxzZTsKLQotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbV9maXJzdEZyZWU7IGkrKykKLSAgICB7Ci0gICAgICBpZiAobV9tYXBbaV0uZXF1YWxzSWdub3JlQ2FzZShzKSkKLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotCi0gICAgcmV0dXJuIGZhbHNlOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgdGhlIHRhYmxlIGNvbnRhaW5zIHRoZSBnaXZlbiBzdHJpbmcuCi0gICAqCi0gICAqIEBwYXJhbSBzIFN0cmluZyB0byBwdXNoIGludG8gdGhlIHZlY3RvcgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgcHVzaChTdHJpbmcgcykKLSAgewotCi0gICAgaWYgKChtX2ZpcnN0RnJlZSArIDEpID49IG1fbWFwU2l6ZSkKLSAgICB7Ci0gICAgICBtX21hcFNpemUgKz0gbV9ibG9ja3NpemU7Ci0KLSAgICAgIFN0cmluZyBuZXdNYXBbXSA9IG5ldyBTdHJpbmdbbV9tYXBTaXplXTsKLQotICAgICAgU3lzdGVtLmFycmF5Y29weShtX21hcCwgMCwgbmV3TWFwLCAwLCBtX2ZpcnN0RnJlZSArIDEpOwotCi0gICAgICBtX21hcCA9IG5ld01hcDsKLSAgICB9Ci0KLSAgICBtX21hcFttX2ZpcnN0RnJlZV0gPSBzOwotCi0gICAgbV9maXJzdEZyZWUrKzsKLSAgfQotCi0gIC8qKgotICAgKiBQb3AgdGhlIHRhaWwgb2YgdGhpcyB2ZWN0b3IuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIFN0cmluZyBsYXN0IGFkZGVkIHRvIHRoaXMgdmVjdG9yIG9yIG51bGwgbm90IGZvdW5kLgotICAgKiBUaGUgc3RyaW5nIGlzIHJlbW92ZWQgZnJvbSB0aGUgdmVjdG9yLgotICAgKi8KLSAgcHVibGljIGZpbmFsIFN0cmluZyBwb3AoKQotICB7Ci0KLSAgICBpZiAobV9maXJzdEZyZWUgPD0gMCkKLSAgICAgIHJldHVybiBudWxsOwotCi0gICAgbV9maXJzdEZyZWUtLTsKLQotICAgIFN0cmluZyBzID0gbV9tYXBbbV9maXJzdEZyZWVdOwotCi0gICAgbV9tYXBbbV9maXJzdEZyZWVdID0gbnVsbDsKLQotICAgIHJldHVybiBzOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgc3RyaW5nIGF0IHRoZSB0YWlsIG9mIHRoaXMgdmVjdG9yIHdpdGhvdXQgcG9wcGluZy4KLSAgICoKLSAgICogQHJldHVybiBUaGUgc3RyaW5nIGF0IHRoZSB0YWlsIG9mIHRoaXMgdmVjdG9yLgotICAgKi8KLSAgcHVibGljIGZpbmFsIFN0cmluZyBwZWVrKCkKLSAgewotICAgIHJldHVybiAobV9maXJzdEZyZWUgPD0gMCkgPyBudWxsIDogbV9tYXBbbV9maXJzdEZyZWUgLSAxXTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvU3R5bGVzaGVldFBJSGFuZGxlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvU3R5bGVzaGVldFBJSGFuZGxlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4MTI3MzBmLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL1N0eWxlc2hlZXRQSUhhbmRsZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDM0MiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBTdHlsZXNoZWV0UElIYW5kbGVyLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTUgMDg6MTU6NTcgc3VyZXNoX2VtYWlsaWQgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzOwotCi1pbXBvcnQgamF2YS51dGlsLlN0cmluZ1Rva2VuaXplcjsKLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2U7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlVSSVJlc29sdmVyOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlNBWFNvdXJjZTsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuU3lzdGVtSURSZXNvbHZlcjsKLQotaW1wb3J0IG9yZy54bWwuc2F4LkF0dHJpYnV0ZXM7Ci1pbXBvcnQgb3JnLnhtbC5zYXguSW5wdXRTb3VyY2U7Ci1pbXBvcnQgb3JnLnhtbC5zYXguaGVscGVycy5EZWZhdWx0SGFuZGxlcjsKLQotLyoqCi0gKiBTZWFyY2ggZm9yIHRoZSB4bWwtc3R5bGVzaGVldCBwcm9jZXNzaW5nIGluc3RydWN0aW9ucyBpbiBhbiBYTUwgZG9jdW1lbnQuCi0gKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3htbC1zdHlsZXNoZWV0LyI+QXNzb2NpYXRpbmcgU3R5bGUgU2hlZXRzIHdpdGggWE1MIGRvY3VtZW50cywgVmVyc2lvbiAxLjA8L2E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBTdHlsZXNoZWV0UElIYW5kbGVyIGV4dGVuZHMgRGVmYXVsdEhhbmRsZXIKLXsKLSAgLyoqIFRoZSBiYXNlSUQgb2YgdGhlIGRvY3VtZW50IGJlaW5nIHByb2Nlc3NlZC4gICovCi0gIFN0cmluZyBtX2Jhc2VJRDsKLQotICAvKiogVGhlIGRlc2lyZWQgbWVkaWEgY3JpdGVyaWEuICovCi0gIFN0cmluZyBtX21lZGlhOwotCi0gIC8qKiBUaGUgZGVzaXJlZCB0aXRsZSBjcml0ZXJpYS4gICovCi0gIFN0cmluZyBtX3RpdGxlOwotCi0gIC8qKiBUaGUgZGVzaXJlZCBjaGFyYWN0ZXIgc2V0IGNyaXRlcmlhLiAgICovCi0gIFN0cmluZyBtX2NoYXJzZXQ7Ci0KLSAgLyoqIEEgbGlzdCBvZiBTQVhTb3VyY2Ugb2JqZWN0cyB0aGF0IG1hdGNoIHRoZSBjcml0ZXJpYS4gICovCi0gIFZlY3RvciBtX3N0eWxlc2hlZXRzID0gbmV3IFZlY3RvcigpOwotCi0gIC8vIEFkZCBjb2RlIHRvIHVzZSBhIFVSSVJlc29sdmVyLiBQYXRjaCBmcm9tIERtaXRyaSBJbHlpbi4KLQotICAvKioKLSAgICogVGhlIG9iamVjdCB0aGF0IGltcGxlbWVudHMgdGhlIFVSSVJlc29sdmVyIGludGVyZmFjZSwKLSAgICogb3IgbnVsbC4KLSAgICovCi0gIFVSSVJlc29sdmVyIG1fdXJpUmVzb2x2ZXI7Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgb2JqZWN0IHRoYXQgd2lsbCBiZSB1c2VkIHRvIHJlc29sdmUgVVJJcyBpbiBocmVmCi0gICAqIGluIHhtbC1zdHlsZXNoZWV0IHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24uCi0gICAqCi0gICAqIEBwYXJhbSByZXNvbHZlciBBbiBvYmplY3QgdGhhdCBpbXBsZW1lbnRzIHRoZSBVUklSZXNvbHZlciBpbnRlcmZhY2UsCi0gICAqIG9yIG51bGwuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRVUklSZXNvbHZlcihVUklSZXNvbHZlciByZXNvbHZlcikKLSAgewotICAgIG1fdXJpUmVzb2x2ZXIgPSByZXNvbHZlcjsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIG9iamVjdCB0aGF0IHdpbGwgYmUgdXNlZCB0byByZXNvbHZlIFVSSXMgaW4gaHJlZgotICAgKiBpbiB4bWwtc3R5bGVzaGVldCBwcm9jZXNzaW5nIGluc3RydWN0aW9uLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBVUklSZXNvbHZlciB0aGF0IHdhcyBzZXQgd2l0aCBzZXRVUklSZXNvbHZlci4KLSAgICovCi0gIHB1YmxpYyBVUklSZXNvbHZlciBnZXRVUklSZXNvbHZlcigpCi0gIHsKLSAgICByZXR1cm4gbV91cmlSZXNvbHZlcjsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBTdHlsZXNoZWV0UElIYW5kbGVyIGluc3RhbmNlIHRoYXQgd2lsbCBzZWFyY2gKLSAgICogZm9yIHhtbC1zdHlsZXNoZWV0IFBJcyBiYXNlZCBvbiB0aGUgZ2l2ZW4gY3JpdGVyaWEuCi0gICAqCi0gICAqIEBwYXJhbSBiYXNlSUQgVGhlIGJhc2UgSUQgb2YgdGhlIFhNTCBkb2N1bWVudCwgbmVlZGVkIHRvIHJlc29sdmUKLSAgICogICAgICAgICAgICAgICByZWxhdGl2ZSBJRHMuCi0gICAqIEBwYXJhbSBtZWRpYSBUaGUgZGVzaXJlZCBtZWRpYSBjcml0ZXJpYS4KLSAgICogQHBhcmFtIHRpdGxlIFRoZSBkZXNpcmVkIHRpdGxlIGNyaXRlcmlhLgotICAgKiBAcGFyYW0gY2hhcnNldCBUaGUgZGVzaXJlZCBjaGFyYWN0ZXIgc2V0IGNyaXRlcmlhLgotICAgKi8KLSAgcHVibGljIFN0eWxlc2hlZXRQSUhhbmRsZXIoU3RyaW5nIGJhc2VJRCwgU3RyaW5nIG1lZGlhLCBTdHJpbmcgdGl0bGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBjaGFyc2V0KQotICB7Ci0KLSAgICBtX2Jhc2VJRCA9IGJhc2VJRDsKLSAgICBtX21lZGlhID0gbWVkaWE7Ci0gICAgbV90aXRsZSA9IHRpdGxlOwotICAgIG1fY2hhcnNldCA9IGNoYXJzZXQ7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBsYXN0IHN0eWxlc2hlZXQgZm91bmQgdGhhdCBtYXRjaCB0aGUgY29uc3RyYWludHMuCi0gICAqCi0gICAqIEByZXR1cm4gU291cmNlIG9iamVjdCB0aGF0IHJlZmVyZW5jZXMgdGhlIGxhc3Qgc3R5bGVzaGVldCByZWZlcmVuY2UKLSAgICogICAgICAgICB0aGF0IG1hdGNoZXMgdGhlIGNvbnN0cmFpbnRzLgotICAgKi8KLSAgcHVibGljIFNvdXJjZSBnZXRBc3NvY2lhdGVkU3R5bGVzaGVldCgpCi0gIHsKLQotICAgIGludCBzeiA9IG1fc3R5bGVzaGVldHMuc2l6ZSgpOwotCi0gICAgaWYgKHN6ID4gMCkKLSAgICB7Ci0gICAgICBTb3VyY2Ugc291cmNlID0gKFNvdXJjZSkgbV9zdHlsZXNoZWV0cy5lbGVtZW50QXQoc3otMSk7Ci0gICAgICByZXR1cm4gc291cmNlOwotICAgIH0KLSAgICBlbHNlCi0gICAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBIYW5kbGUgdGhlIHhtbC1zdHlsZXNoZWV0IHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24uCi0gICAqCi0gICAqIEBwYXJhbSB0YXJnZXQgVGhlIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gdGFyZ2V0LgotICAgKiBAcGFyYW0gZGF0YSBUaGUgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiBkYXRhLCBvciBudWxsIGlmCi0gICAqICAgICAgICAgICAgIG5vbmUgaXMgc3VwcGxpZWQuCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI3Byb2Nlc3NpbmdJbnN0cnVjdGlvbgotICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3htbC1zdHlsZXNoZWV0LyI+QXNzb2NpYXRpbmcgU3R5bGUgU2hlZXRzIHdpdGggWE1MIGRvY3VtZW50cywgVmVyc2lvbiAxLjA8L2E+Ci0gICAqLwotICBwdWJsaWMgdm9pZCBwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oU3RyaW5nIHRhcmdldCwgU3RyaW5nIGRhdGEpCi0gICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAodGFyZ2V0LmVxdWFscygieG1sLXN0eWxlc2hlZXQiKSkKLSAgICB7Ci0gICAgICBTdHJpbmcgaHJlZiA9IG51bGw7ICAvLyBDREFUQSAjUkVRVUlSRUQKLSAgICAgIFN0cmluZyB0eXBlID0gbnVsbDsgIC8vIENEQVRBICNSRVFVSVJFRAotICAgICAgU3RyaW5nIHRpdGxlID0gbnVsbDsgIC8vIENEQVRBICNJTVBMSUVECi0gICAgICBTdHJpbmcgbWVkaWEgPSBudWxsOyAgLy8gQ0RBVEEgI0lNUExJRUQKLSAgICAgIFN0cmluZyBjaGFyc2V0ID0gbnVsbDsgIC8vIENEQVRBICNJTVBMSUVECi0gICAgICBib29sZWFuIGFsdGVybmF0ZSA9IGZhbHNlOyAgLy8gKHllc3xubykgIm5vIgotICAgICAgU3RyaW5nVG9rZW5pemVyIHRva2VuaXplciA9IG5ldyBTdHJpbmdUb2tlbml6ZXIoZGF0YSwgIiBcdD1cbiIsIHRydWUpOwotICAgICAgYm9vbGVhbiBsb29rZWRBaGVhZCA9IGZhbHNlOwotICAgICAgU291cmNlIHNvdXJjZSA9IG51bGw7Ci0KLSAgICAgIFN0cmluZyB0b2tlbiA9ICIiOwotICAgICAgd2hpbGUgKHRva2VuaXplci5oYXNNb3JlVG9rZW5zKCkpCi0gICAgICB7Ci0gICAgICAgIGlmICghbG9va2VkQWhlYWQpCi0gICAgICAgICAgdG9rZW4gPSB0b2tlbml6ZXIubmV4dFRva2VuKCk7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICBsb29rZWRBaGVhZCA9IGZhbHNlOwotICAgICAgICBpZiAodG9rZW5pemVyLmhhc01vcmVUb2tlbnMoKSAmJgotICAgICAgICAgICAgICAgKHRva2VuLmVxdWFscygiICIpIHx8IHRva2VuLmVxdWFscygiXHQiKSB8fCB0b2tlbi5lcXVhbHMoIj0iKSkpCi0gICAgICAgICAgY29udGludWU7Ci0KLSAgICAgICAgU3RyaW5nIG5hbWUgPSB0b2tlbjsKLSAgICAgICAgaWYgKG5hbWUuZXF1YWxzKCJ0eXBlIikpCi0gICAgICAgIHsKLSAgICAgICAgICB0b2tlbiA9IHRva2VuaXplci5uZXh0VG9rZW4oKTsKLSAgICAgICAgICB3aGlsZSAodG9rZW5pemVyLmhhc01vcmVUb2tlbnMoKSAmJgotICAgICAgICAgICAgICAgKHRva2VuLmVxdWFscygiICIgKSB8fCB0b2tlbi5lcXVhbHMoIlx0IikgfHwgdG9rZW4uZXF1YWxzKCI9IikpKQotICAgICAgICAgICAgdG9rZW4gPSB0b2tlbml6ZXIubmV4dFRva2VuKCk7Ci0gICAgICAgICAgdHlwZSA9IHRva2VuLnN1YnN0cmluZygxLCB0b2tlbi5sZW5ndGgoKSAtIDEpOwotCi0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAobmFtZS5lcXVhbHMoImhyZWYiKSkKLSAgICAgICAgewotICAgICAgICAgIHRva2VuID0gdG9rZW5pemVyLm5leHRUb2tlbigpOwotICAgICAgICAgIHdoaWxlICh0b2tlbml6ZXIuaGFzTW9yZVRva2VucygpICYmCi0gICAgICAgICAgICAgICAodG9rZW4uZXF1YWxzKCIgIiApIHx8IHRva2VuLmVxdWFscygiXHQiKSB8fCB0b2tlbi5lcXVhbHMoIj0iKSkpCi0gICAgICAgICAgICB0b2tlbiA9IHRva2VuaXplci5uZXh0VG9rZW4oKTsKLSAgICAgICAgICBocmVmID0gdG9rZW47Ci0gICAgICAgICAgaWYgKHRva2VuaXplci5oYXNNb3JlVG9rZW5zKCkpCi0gICAgICAgICAgewotICAgICAgICAgICAgdG9rZW4gPSB0b2tlbml6ZXIubmV4dFRva2VuKCk7Ci0gICAgICAgICAgICAvLyBJZiB0aGUgaHJlZiB2YWx1ZSBoYXMgcGFyYW1ldGVycyB0byBiZSBwYXNzZWQgdG8gYQotICAgICAgICAgICAgLy8gc2VydmxldChzb21ldGhpbmcgbGlrZSAiZm9vYmFyP2lkPTEyLi4uIiksCi0gICAgICAgICAgICAvLyB3ZSB3YW50IHRvIG1ha2Ugc3VyZSB3ZSBnZXQgdGhlbSBhZGRlZCB0bwotICAgICAgICAgICAgLy8gdGhlIGhyZWYgdmFsdWUuIFdpdGhvdXQgdGhpcyBjaGVjaywgd2Ugd291bGQgbW92ZSBvbgotICAgICAgICAgICAgLy8gdG8gdHJ5IHRvIHByb2Nlc3MgYW5vdGhlciBhdHRyaWJ1dGUgYW5kIHRoYXQgd291bGQgYmUKLSAgICAgICAgICAgIC8vIHdyb25nLgotICAgICAgICAgICAgLy8gV2UgbmVlZCB0byBzZXQgbG9va2VkQWhlYWQgaGVyZSB0byBmbGFnIHRoYXQgd2UKLSAgICAgICAgICAgIC8vIGFscmVhZHkgaGF2ZSB0aGUgbmV4dCB0b2tlbi4KLSAgICAgICAgICAgIHdoaWxlICggdG9rZW4uZXF1YWxzKCI9IikgJiYgdG9rZW5pemVyLmhhc01vcmVUb2tlbnMoKSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgaHJlZiA9IGhyZWYgKyB0b2tlbiArIHRva2VuaXplci5uZXh0VG9rZW4oKTsKLSAgICAgICAgICAgICAgaWYgKHRva2VuaXplci5oYXNNb3JlVG9rZW5zKCkpCi0gICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICB0b2tlbiA9IHRva2VuaXplci5uZXh0VG9rZW4oKTsKLSAgICAgICAgICAgICAgICBsb29rZWRBaGVhZCA9IHRydWU7Ci0gICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICB9Ci0gICAgICAgICAgaHJlZiA9IGhyZWYuc3Vic3RyaW5nKDEsIGhyZWYubGVuZ3RoKCkgLSAxKTsKLSAgICAgICAgICB0cnkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICAvLyBBZGQgY29kZSB0byB1c2UgYSBVUklSZXNvbHZlci4gUGF0Y2ggZnJvbSBEbWl0cmkgSWx5aW4uCi0gICAgICAgICAgICBpZiAobV91cmlSZXNvbHZlciAhPSBudWxsKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICBzb3VyY2UgPSBtX3VyaVJlc29sdmVyLnJlc29sdmUoaHJlZiwgbV9iYXNlSUQpOwotICAgICAgICAgICAgfQotICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIGhyZWYgPSBTeXN0ZW1JRFJlc29sdmVyLmdldEFic29sdXRlVVJJKGhyZWYsIG1fYmFzZUlEKTsKLSAgICAgICAgICAgICAgc291cmNlID0gbmV3IFNBWFNvdXJjZShuZXcgSW5wdXRTb3VyY2UoaHJlZikpOwotICAgICAgICAgICAgfQotICAgICAgICAgIH0KLSAgICAgICAgICBjYXRjaChUcmFuc2Zvcm1lckV4Y2VwdGlvbiB0ZSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uKHRlKTsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAobmFtZS5lcXVhbHMoInRpdGxlIikpCi0gICAgICAgIHsKLSAgICAgICAgICB0b2tlbiA9IHRva2VuaXplci5uZXh0VG9rZW4oKTsKLSAgICAgICAgICB3aGlsZSAodG9rZW5pemVyLmhhc01vcmVUb2tlbnMoKSAmJgotICAgICAgICAgICAgICAgKHRva2VuLmVxdWFscygiICIgKSB8fCB0b2tlbi5lcXVhbHMoIlx0IikgfHwgdG9rZW4uZXF1YWxzKCI9IikpKQotICAgICAgICAgICAgdG9rZW4gPSB0b2tlbml6ZXIubmV4dFRva2VuKCk7Ci0gICAgICAgICAgdGl0bGUgPSB0b2tlbi5zdWJzdHJpbmcoMSwgdG9rZW4ubGVuZ3RoKCkgLSAxKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFscygibWVkaWEiKSkKLSAgICAgICAgewotICAgICAgICAgIHRva2VuID0gdG9rZW5pemVyLm5leHRUb2tlbigpOwotICAgICAgICAgIHdoaWxlICh0b2tlbml6ZXIuaGFzTW9yZVRva2VucygpICYmCi0gICAgICAgICAgICAgICAodG9rZW4uZXF1YWxzKCIgIiApIHx8IHRva2VuLmVxdWFscygiXHQiKSB8fCB0b2tlbi5lcXVhbHMoIj0iKSkpCi0gICAgICAgICAgICB0b2tlbiA9IHRva2VuaXplci5uZXh0VG9rZW4oKTsKLSAgICAgICAgICBtZWRpYSA9IHRva2VuLnN1YnN0cmluZygxLCB0b2tlbi5sZW5ndGgoKSAtIDEpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzKCJjaGFyc2V0IikpCi0gICAgICAgIHsKLSAgICAgICAgICB0b2tlbiA9IHRva2VuaXplci5uZXh0VG9rZW4oKTsKLSAgICAgICAgICB3aGlsZSAodG9rZW5pemVyLmhhc01vcmVUb2tlbnMoKSAmJgotICAgICAgICAgICAgICAodG9rZW4uZXF1YWxzKCIgIiApIHx8IHRva2VuLmVxdWFscygiXHQiKSB8fCB0b2tlbi5lcXVhbHMoIj0iKSkpCi0gICAgICAgICAgICB0b2tlbiA9IHRva2VuaXplci5uZXh0VG9rZW4oKTsKLSAgICAgICAgICBjaGFyc2V0ID0gdG9rZW4uc3Vic3RyaW5nKDEsIHRva2VuLmxlbmd0aCgpIC0gMSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAobmFtZS5lcXVhbHMoImFsdGVybmF0ZSIpKQotICAgICAgICB7Ci0gICAgICAgICAgdG9rZW4gPSB0b2tlbml6ZXIubmV4dFRva2VuKCk7Ci0gICAgICAgICAgd2hpbGUgKHRva2VuaXplci5oYXNNb3JlVG9rZW5zKCkgJiYKLSAgICAgICAgICAgICAgICh0b2tlbi5lcXVhbHMoIiAiICkgfHwgdG9rZW4uZXF1YWxzKCJcdCIpIHx8IHRva2VuLmVxdWFscygiPSIpKSkKLSAgICAgICAgICAgIHRva2VuID0gdG9rZW5pemVyLm5leHRUb2tlbigpOwotICAgICAgICAgIGFsdGVybmF0ZSA9IHRva2VuLnN1YnN0cmluZygxLCB0b2tlbi5sZW5ndGgoKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLSAxKS5lcXVhbHMoInllcyIpOwotICAgICAgICB9Ci0KLSAgICAgIH0KLQotICAgICAgaWYgKChudWxsICE9IHR5cGUpCi0gICAgICAgICAgJiYgKHR5cGUuZXF1YWxzKCJ0ZXh0L3hzbCIpIHx8IHR5cGUuZXF1YWxzKCJ0ZXh0L3htbCIpIHx8IHR5cGUuZXF1YWxzKCJhcHBsaWNhdGlvbi94bWwreHNsdCIpKQotICAgICAgICAgICYmIChudWxsICE9IGhyZWYpKQotICAgICAgewotICAgICAgICBpZiAobnVsbCAhPSBtX21lZGlhKQotICAgICAgICB7Ci0gICAgICAgICAgaWYgKG51bGwgIT0gbWVkaWEpCi0gICAgICAgICAgewotICAgICAgICAgICAgaWYgKCFtZWRpYS5lcXVhbHMobV9tZWRpYSkpCi0gICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICB9Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKG51bGwgIT0gbV9jaGFyc2V0KQotICAgICAgICB7Ci0gICAgICAgICAgaWYgKG51bGwgIT0gY2hhcnNldCkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBpZiAoIWNoYXJzZXQuZXF1YWxzKG1fY2hhcnNldCkpCi0gICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICB9Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKG51bGwgIT0gbV90aXRsZSkKLSAgICAgICAgewotICAgICAgICAgIGlmIChudWxsICE9IHRpdGxlKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGlmICghdGl0bGUuZXF1YWxzKG1fdGl0bGUpKQotICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotCi0gICAgICAgIG1fc3R5bGVzaGVldHMuYWRkRWxlbWVudChzb3VyY2UpOwotICAgICAgfQotICAgIH0KLSAgfQotCi0KLSAgLyoqCi0gICAqIFRoZSBzcGVjIG5vdGVzIHRoYXQgIlRoZSB4bWwtc3R5bGVzaGVldCBwcm9jZXNzaW5nIGluc3RydWN0aW9uIGlzIGFsbG93ZWQgb25seSBpbiB0aGUgcHJvbG9nIG9mIGFuIFhNTCBkb2N1bWVudC4iLAotICAgKiBzbywgYXQgbGVhc3QgZm9yIHJpZ2h0IG5vdywgSSdtIGdvaW5nIHRvIGdvIGFoZWFkIGFuIHRocm93IGEgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICogaW4gb3JkZXIgdG8gc3RvcCB0aGUgcGFyc2UuCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkgVGhlIE5hbWVzcGFjZSBVUkksIG9yIGFuIGVtcHR5IHN0cmluZy4KLSAgICogQHBhcmFtIGxvY2FsTmFtZSBUaGUgbG9jYWwgbmFtZSAod2l0aG91dCBwcmVmaXgpLCBvciBlbXB0eSBzdHJpbmcgaWYgbm90IG5hbWVzcGFjZSBwcm9jZXNzaW5nLgotICAgKiBAcGFyYW0gcU5hbWUgVGhlIHF1YWxpZmllZCBuYW1lICh3aXRoIHByZWZpeCkuCi0gICAqIEBwYXJhbSBhdHRzICBUaGUgc3BlY2lmaWVkIG9yIGRlZmF1bHRlZCBhdHRyaWJ1dGVzLgotICAgKgotICAgKiBAdGhyb3dzIFN0b3BQYXJzZUV4Y2VwdGlvbiBzaW5jZSB0aGVyZSBjYW4gYmUgbm8gdmFsaWQgeG1sLXN0eWxlc2hlZXQgcHJvY2Vzc2luZwotICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnN0cnVjdGlvbnMgcGFzdCB0aGUgZmlyc3QgZWxlbWVudC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudCgKLSAgICAgICAgICBTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgbG9jYWxOYW1lLCBTdHJpbmcgcU5hbWUsIEF0dHJpYnV0ZXMgYXR0cykKLSAgICAgICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIHRocm93IG5ldyBTdG9wUGFyc2VFeGNlcHRpb24oKTsKLSAgfQotCi0gIC8qKgotICAgICogQWRkZWQgYWRkaXRpb25hbCBnZXR0ZXIgYW5kIHNldHRlciBtZXRob2RzIGZvciB0aGUgQmFzZSBJZAotICAgICogdG8gZml4IGJ1Z3ppbGxhIGJ1ZyAyNDE4NwotICAgICoKLSAgICAqLwotICAgcHVibGljIHZvaWQgc2V0QmFzZUlkKFN0cmluZyBiYXNlSWQpIHsKLSAgICAgICBtX2Jhc2VJRCA9IGJhc2VJZDsKLQotICAgfQotICAgcHVibGljIFN0cmluZyAgZ2V0QmFzZUlkKCkgewotICAgICAgIHJldHVybiBtX2Jhc2VJRCA7Ci0gICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL1N1YmFsbG9jYXRlZEJ5dGVWZWN0b3IuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL1N1YmFsbG9jYXRlZEJ5dGVWZWN0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNTYzODg2ZS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9TdWJhbGxvY2F0ZWRCeXRlVmVjdG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw1MDAgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogU3ViYWxsb2NhdGVkQnl0ZVZlY3Rvci5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE1IDA4OjE1OjU3IHN1cmVzaF9lbWFpbGlkIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlsczsKLQotLyoqCi0gKiBBIHZlcnkgc2ltcGxlIHRhYmxlIHRoYXQgc3RvcmVzIGEgbGlzdCBvZiBieXRlLiBWZXJ5IHNpbWlsYXIgQVBJIHRvIG91cgotICogSW50VmVjdG9yIGNsYXNzIChzYW1lIEFQSSk7IGRpZmZlcmVudCBpbnRlcm5hbCBzdG9yYWdlLgotICoKLSAqIFRoaXMgdmVyc2lvbiB1c2VzIGFuIGFycmF5LW9mLWFycmF5cyBzb2x1dGlvbi4gUmVhZC93cml0ZSBhY2Nlc3MgaXMgdGh1cwotICogYSBiaXQgc2xvd2VyIHRoYW4gdGhlIHNpbXBsZSBJbnRWZWN0b3IsIGFuZCBiYXNpYyBzdG9yYWdlIGlzIGEgdHJpZmxlCi0gKiBoaWdoZXIgZHVlIHRvIHRoZSB0b3AtbGV2ZWwgYXJyYXkgLS0gYnV0IGFwcGVuZGluZyBpcyBPKDEpIGZhc3QgcmF0aGVyCi0gKiB0aGFuIE8oTioqMikgc2xvdywgd2hpY2ggd2lsbCBzd2FtcCB0aG9zZSBjb3N0cyBpbiBzaXR1YXRpb25zIHdoZXJlCi0gKiBsb25nIHZlY3RvcnMgYXJlIGJlaW5nIGJ1aWx0IHVwLgotICoKLSAqIEtub3duIGlzc3VlczoKLSAqCi0gKiBTb21lIG1ldGhvZHMgYXJlIHByaXZhdGUgYmVjYXVzZSB0aGV5IGhhdmVuJ3QgeWV0IGJlZW4gdGVzdGVkIHByb3Blcmx5LgotICoKLSAqIElmIGFuIGVsZW1lbnQgaGFzIG5vdCBiZWVuIHNldCAoYmVjYXVzZSB3ZSBza2lwcGVkIGl0KSwgaXRzIHZhbHVlIHdpbGwKLSAqIGluaXRpYWxseSBiZSAwLiBTaG9ydGVuaW5nIHRoZSB2ZWN0b3IgZG9lcyBub3QgY2xlYXIgb2xkIHN0b3JhZ2U7IGlmIHlvdQotICogdGhlbiBza2lwIHZhbHVlcyBhbmQgc2V0RWxlbWVudEF0IGEgaGlnaGVyIGluZGV4IGFnYWluLCB5b3UgbWF5IHNlZSBvbGQgZGF0YQotICogcmVhcHBlYXIgaW4gdGhlIHRydW5jYXRlZC1hbmQtcmVzdG9yZWQgc2VjdGlvbi4gRG9pbmcgYW55dGhpbmcgZWxzZSB3b3VsZAotICogaGF2ZSBwZXJmb3JtYW5jZSBjb3N0cy4KLSAqIEB4c2wudXNhZ2UgaW50ZXJuYWwKLSAqLwotcHVibGljIGNsYXNzIFN1YmFsbG9jYXRlZEJ5dGVWZWN0b3IKLXsKLSAgLyoqIFNpemUgb2YgYmxvY2tzIHRvIGFsbG9jYXRlICAgICAgICAgICovCi0gIHByb3RlY3RlZCBpbnQgbV9ibG9ja3NpemU7Ci0KLSAgLyoqIE51bWJlciBvZiBibG9ja3MgdG8gKG92ZXIpYWxsb2NhdGUgYnkgKi8KLSAgcHJvdGVjdGVkICBpbnQgbV9udW1ibG9ja3M9MzI7Ci0KLSAgLyoqIEFycmF5IG9mIGFycmF5cyBvZiBieXRlcyAgICAgICAgICAqLwotICBwcm90ZWN0ZWQgYnl0ZSBtX21hcFtdW107Ci0KLSAgLyoqIE51bWJlciBvZiBieXRlcyBpbiBhcnJheSAgICAgICAgICAqLwotICBwcm90ZWN0ZWQgaW50IG1fZmlyc3RGcmVlID0gMDsKLQotICAvKiogIlNob3J0Y3V0IiBoYW5kbGUgdG8gbV9tYXBbMF0gKi8KLSAgcHJvdGVjdGVkIGJ5dGUgbV9tYXAwW107Ci0KLSAgLyoqCi0gICAqIERlZmF1bHQgY29uc3RydWN0b3IuICBOb3RlIHRoYXQgdGhlIGRlZmF1bHQKLSAgICogYmxvY2sgc2l6ZSBpcyB2ZXJ5IHNtYWxsLCBmb3Igc21hbGwgbGlzdHMuCi0gICAqLwotICBwdWJsaWMgU3ViYWxsb2NhdGVkQnl0ZVZlY3RvcigpCi0gIHsKLSAgICB0aGlzKDIwNDgpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhIEJ5dGVWZWN0b3IsIHVzaW5nIHRoZSBnaXZlbiBibG9jayBzaXplLgotICAgKgotICAgKiBAcGFyYW0gYmxvY2tzaXplIFNpemUgb2YgYmxvY2sgdG8gYWxsb2NhdGUKLSAgICovCi0gIHB1YmxpYyBTdWJhbGxvY2F0ZWRCeXRlVmVjdG9yKGludCBibG9ja3NpemUpCi0gIHsKLSAgICBtX2Jsb2Nrc2l6ZSA9IGJsb2Nrc2l6ZTsKLSAgICBtX21hcDA9bmV3IGJ5dGVbYmxvY2tzaXplXTsKLSAgICBtX21hcCA9IG5ldyBieXRlW21fbnVtYmxvY2tzXVtdOwotICAgIG1fbWFwWzBdPW1fbWFwMDsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBCeXRlVmVjdG9yLCB1c2luZyB0aGUgZ2l2ZW4gYmxvY2sgc2l6ZS4KLSAgICoKLSAgICogQHBhcmFtIGJsb2Nrc2l6ZSBTaXplIG9mIGJsb2NrIHRvIGFsbG9jYXRlCi0gICAqLwotICBwdWJsaWMgU3ViYWxsb2NhdGVkQnl0ZVZlY3RvcihpbnQgYmxvY2tzaXplLCBpbnQgaW5jcmVhc2VTaXplKQotICB7Ci0gICAgLy8gaW5jcmVhc2VTaXplIG5vdCBjdXJyZW50bHkgdXNlZC4KLSAgICB0aGlzKGJsb2Nrc2l6ZSk7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGxlbmd0aCBvZiB0aGUgbGlzdC4KLSAgICoKLSAgICogQHJldHVybiBsZW5ndGggb2YgdGhlIGxpc3QKLSAgICovCi0gIHB1YmxpYyBpbnQgc2l6ZSgpCi0gIHsKLSAgICByZXR1cm4gbV9maXJzdEZyZWU7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBsZW5ndGggb2YgdGhlIGxpc3QuCi0gICAqCi0gICAqIEByZXR1cm4gbGVuZ3RoIG9mIHRoZSBsaXN0Ci0gICAqLwotICBwcml2YXRlICB2b2lkIHNldFNpemUoaW50IHN6KQotICB7Ci0gICAgaWYobV9maXJzdEZyZWU8c3opCi0gICAgICBtX2ZpcnN0RnJlZSA9IHN6OwotICB9Ci0KLSAgLyoqCi0gICAqIEFwcGVuZCBhIGJ5dGUgb250byB0aGUgdmVjdG9yLgotICAgKgotICAgKiBAcGFyYW0gdmFsdWUgQnl0ZSB0byBhZGQgdG8gdGhlIGxpc3QKLSAgICovCi0gIHB1YmxpYyAgdm9pZCBhZGRFbGVtZW50KGJ5dGUgdmFsdWUpCi0gIHsKLSAgICBpZihtX2ZpcnN0RnJlZTxtX2Jsb2Nrc2l6ZSkKLSAgICAgIG1fbWFwMFttX2ZpcnN0RnJlZSsrXT12YWx1ZTsKLSAgICBlbHNlCi0gICAgewotICAgICAgaW50IGluZGV4PW1fZmlyc3RGcmVlL21fYmxvY2tzaXplOwotICAgICAgaW50IG9mZnNldD1tX2ZpcnN0RnJlZSVtX2Jsb2Nrc2l6ZTsKLSAgICAgICsrbV9maXJzdEZyZWU7Ci0KLSAgICAgIGlmKGluZGV4Pj1tX21hcC5sZW5ndGgpCi0gICAgICB7Ci0gICAgICAgIGludCBuZXdzaXplPWluZGV4K21fbnVtYmxvY2tzOwotICAgICAgICBieXRlW11bXSBuZXdNYXA9bmV3IGJ5dGVbbmV3c2l6ZV1bXTsKLSAgICAgICAgU3lzdGVtLmFycmF5Y29weShtX21hcCwgMCwgbmV3TWFwLCAwLCBtX21hcC5sZW5ndGgpOwotICAgICAgICBtX21hcD1uZXdNYXA7Ci0gICAgICB9Ci0gICAgICBieXRlW10gYmxvY2s9bV9tYXBbaW5kZXhdOwotICAgICAgaWYobnVsbD09YmxvY2spCi0gICAgICAgIGJsb2NrPW1fbWFwW2luZGV4XT1uZXcgYnl0ZVttX2Jsb2Nrc2l6ZV07Ci0gICAgICBibG9ja1tvZmZzZXRdPXZhbHVlOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBBcHBlbmQgc2V2ZXJhbCBieXRlIHZhbHVlcyBvbnRvIHRoZSB2ZWN0b3IuCi0gICAqCi0gICAqIEBwYXJhbSB2YWx1ZSBCeXRlIHRvIGFkZCB0byB0aGUgbGlzdAotICAgKi8KLSAgcHJpdmF0ZSAgdm9pZCBhZGRFbGVtZW50cyhieXRlIHZhbHVlLCBpbnQgbnVtYmVyT2ZFbGVtZW50cykKLSAgewotICAgIGlmKG1fZmlyc3RGcmVlK251bWJlck9mRWxlbWVudHM8bV9ibG9ja3NpemUpCi0gICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bWJlck9mRWxlbWVudHM7IGkrKykKLSAgICAgIHsKLSAgICAgICAgbV9tYXAwW21fZmlyc3RGcmVlKytdPXZhbHVlOwotICAgICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBpbnQgaW5kZXg9bV9maXJzdEZyZWUvbV9ibG9ja3NpemU7Ci0gICAgICBpbnQgb2Zmc2V0PW1fZmlyc3RGcmVlJW1fYmxvY2tzaXplOwotICAgICAgbV9maXJzdEZyZWUrPW51bWJlck9mRWxlbWVudHM7Ci0gICAgICB3aGlsZSggbnVtYmVyT2ZFbGVtZW50cz4wKQotICAgICAgewotICAgICAgICBpZihpbmRleD49bV9tYXAubGVuZ3RoKQotICAgICAgICB7Ci0gICAgICAgICAgaW50IG5ld3NpemU9aW5kZXgrbV9udW1ibG9ja3M7Ci0gICAgICAgICAgYnl0ZVtdW10gbmV3TWFwPW5ldyBieXRlW25ld3NpemVdW107Ci0gICAgICAgICAgU3lzdGVtLmFycmF5Y29weShtX21hcCwgMCwgbmV3TWFwLCAwLCBtX21hcC5sZW5ndGgpOwotICAgICAgICAgIG1fbWFwPW5ld01hcDsKLSAgICAgICAgfQotICAgICAgICBieXRlW10gYmxvY2s9bV9tYXBbaW5kZXhdOwotICAgICAgICBpZihudWxsPT1ibG9jaykKLSAgICAgICAgICBibG9jaz1tX21hcFtpbmRleF09bmV3IGJ5dGVbbV9ibG9ja3NpemVdOwotICAgICAgICBpbnQgY29waWVkPShtX2Jsb2Nrc2l6ZS1vZmZzZXQgPCBudW1iZXJPZkVsZW1lbnRzKQotICAgICAgICAgID8gbV9ibG9ja3NpemUtb2Zmc2V0IDogbnVtYmVyT2ZFbGVtZW50czsKLSAgICAgICAgbnVtYmVyT2ZFbGVtZW50cy09Y29waWVkOwotICAgICAgICB3aGlsZShjb3BpZWQtLSA+IDApCi0gICAgICAgICAgYmxvY2tbb2Zmc2V0KytdPXZhbHVlOwotCi0gICAgICAgICsraW5kZXg7b2Zmc2V0PTA7Ci0gICAgICB9Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEFwcGVuZCBzZXZlcmFsIHNsb3RzIG9udG8gdGhlIHZlY3RvciwgYnV0IGRvIG5vdCBzZXQgdGhlIHZhbHVlcy4KLSAgICogTm90ZTogIk5vdCBTZXQiIG1lYW5zIHRoZSB2YWx1ZSBpcyB1bnNwZWNpZmllZC4KLSAgICoKLSAgICogQHBhcmFtIG51bWJlck9mRWxlbWVudHMKLSAgICovCi0gIHByaXZhdGUgIHZvaWQgYWRkRWxlbWVudHMoaW50IG51bWJlck9mRWxlbWVudHMpCi0gIHsKLSAgICBpbnQgbmV3bGVuPW1fZmlyc3RGcmVlK251bWJlck9mRWxlbWVudHM7Ci0gICAgaWYobmV3bGVuPm1fYmxvY2tzaXplKQotICAgIHsKLSAgICAgIGludCBpbmRleD1tX2ZpcnN0RnJlZSVtX2Jsb2Nrc2l6ZTsKLSAgICAgIGludCBuZXdpbmRleD0obV9maXJzdEZyZWUrbnVtYmVyT2ZFbGVtZW50cyklbV9ibG9ja3NpemU7Ci0gICAgICBmb3IoaW50IGk9aW5kZXgrMTtpPD1uZXdpbmRleDsrK2kpCi0gICAgICAgIG1fbWFwW2ldPW5ldyBieXRlW21fYmxvY2tzaXplXTsKLSAgICB9Ci0gICAgbV9maXJzdEZyZWU9bmV3bGVuOwotICB9Ci0KLSAgLyoqCi0gICAqIEluc2VydHMgdGhlIHNwZWNpZmllZCBub2RlIGluIHRoaXMgdmVjdG9yIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXguCi0gICAqIEVhY2ggY29tcG9uZW50IGluIHRoaXMgdmVjdG9yIHdpdGggYW4gaW5kZXggZ3JlYXRlciBvciBlcXVhbCB0bwotICAgKiB0aGUgc3BlY2lmaWVkIGluZGV4IGlzIHNoaWZ0ZWQgdXB3YXJkIHRvIGhhdmUgYW4gaW5kZXggb25lIGdyZWF0ZXIKLSAgICogdGhhbiB0aGUgdmFsdWUgaXQgaGFkIHByZXZpb3VzbHkuCi0gICAqCi0gICAqIEluc2VydGlvbiBtYXkgYmUgYW4gRVhQRU5TSVZFIG9wZXJhdGlvbiEKLSAgICoKLSAgICogQHBhcmFtIHZhbHVlIEJ5dGUgdG8gaW5zZXJ0Ci0gICAqIEBwYXJhbSBhdCBJbmRleCBvZiB3aGVyZSB0byBpbnNlcnQKLSAgICovCi0gIHByaXZhdGUgIHZvaWQgaW5zZXJ0RWxlbWVudEF0KGJ5dGUgdmFsdWUsIGludCBhdCkKLSAgewotICAgIGlmKGF0PT1tX2ZpcnN0RnJlZSkKLSAgICAgIGFkZEVsZW1lbnQodmFsdWUpOwotICAgIGVsc2UgaWYgKGF0Pm1fZmlyc3RGcmVlKQotICAgIHsKLSAgICAgIGludCBpbmRleD1hdC9tX2Jsb2Nrc2l6ZTsKLSAgICAgIGlmKGluZGV4Pj1tX21hcC5sZW5ndGgpCi0gICAgICB7Ci0gICAgICAgIGludCBuZXdzaXplPWluZGV4K21fbnVtYmxvY2tzOwotICAgICAgICBieXRlW11bXSBuZXdNYXA9bmV3IGJ5dGVbbmV3c2l6ZV1bXTsKLSAgICAgICAgU3lzdGVtLmFycmF5Y29weShtX21hcCwgMCwgbmV3TWFwLCAwLCBtX21hcC5sZW5ndGgpOwotICAgICAgICBtX21hcD1uZXdNYXA7Ci0gICAgICB9Ci0gICAgICBieXRlW10gYmxvY2s9bV9tYXBbaW5kZXhdOwotICAgICAgaWYobnVsbD09YmxvY2spCi0gICAgICAgIGJsb2NrPW1fbWFwW2luZGV4XT1uZXcgYnl0ZVttX2Jsb2Nrc2l6ZV07Ci0gICAgICBpbnQgb2Zmc2V0PWF0JW1fYmxvY2tzaXplOwotICAgICAgYmxvY2tbb2Zmc2V0XT12YWx1ZTsKLSAgICAgIG1fZmlyc3RGcmVlPW9mZnNldCsxOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgaW50IGluZGV4PWF0L21fYmxvY2tzaXplOwotICAgICAgaW50IG1heGluZGV4PW1fZmlyc3RGcmVlKzEvbV9ibG9ja3NpemU7Ci0gICAgICArK21fZmlyc3RGcmVlOwotICAgICAgaW50IG9mZnNldD1hdCVtX2Jsb2Nrc2l6ZTsKLSAgICAgIGJ5dGUgcHVzaDsKLQotICAgICAgLy8gKioqKiogRWFzaWVyIHRvIHdvcmsgZG93biBmcm9tIHRvcD8KLSAgICAgIHdoaWxlKGluZGV4PD1tYXhpbmRleCkKLSAgICAgIHsKLSAgICAgICAgaW50IGNvcHlsZW49bV9ibG9ja3NpemUtb2Zmc2V0LTE7Ci0gICAgICAgIGJ5dGVbXSBibG9jaz1tX21hcFtpbmRleF07Ci0gICAgICAgIGlmKG51bGw9PWJsb2NrKQotICAgICAgICB7Ci0gICAgICAgICAgcHVzaD0wOwotICAgICAgICAgIGJsb2NrPW1fbWFwW2luZGV4XT1uZXcgYnl0ZVttX2Jsb2Nrc2l6ZV07Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICB7Ci0gICAgICAgICAgcHVzaD1ibG9ja1ttX2Jsb2Nrc2l6ZS0xXTsKLSAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGJsb2NrLCBvZmZzZXQgLCBibG9jaywgb2Zmc2V0KzEsIGNvcHlsZW4pOwotICAgICAgICB9Ci0gICAgICAgIGJsb2NrW29mZnNldF09dmFsdWU7Ci0gICAgICAgIHZhbHVlPXB1c2g7Ci0gICAgICAgIG9mZnNldD0wOwotICAgICAgICArK2luZGV4OwotICAgICAgfQotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBXaXBlIGl0IG91dC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHJlbW92ZUFsbEVsZW1lbnRzKCkKLSAgewotICAgIG1fZmlyc3RGcmVlID0gMDsKLSAgfQotCi0gIC8qKgotICAgKiBSZW1vdmVzIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZSBhcmd1bWVudCBmcm9tIHRoaXMgdmVjdG9yLgotICAgKiBJZiB0aGUgb2JqZWN0IGlzIGZvdW5kIGluIHRoaXMgdmVjdG9yLCBlYWNoIGNvbXBvbmVudCBpbiB0aGUgdmVjdG9yCi0gICAqIHdpdGggYW4gaW5kZXggZ3JlYXRlciBvciBlcXVhbCB0byB0aGUgb2JqZWN0J3MgaW5kZXggaXMgc2hpZnRlZAotICAgKiBkb3dud2FyZCB0byBoYXZlIGFuIGluZGV4IG9uZSBzbWFsbGVyIHRoYW4gdGhlIHZhbHVlIGl0IGhhZAotICAgKiBwcmV2aW91c2x5LgotICAgKgotICAgKiBAcGFyYW0gcyBCeXRlIHRvIHJlbW92ZSBmcm9tIGFycmF5Ci0gICAqCi0gICAqIEByZXR1cm4gVHJ1ZSBpZiB0aGUgYnl0ZSB3YXMgcmVtb3ZlZCwgZmFsc2UgaWYgaXQgd2FzIG5vdCBmb3VuZAotICAgKi8KLSAgcHJpdmF0ZSAgYm9vbGVhbiByZW1vdmVFbGVtZW50KGJ5dGUgcykKLSAgewotICAgIGludCBhdD1pbmRleE9mKHMsMCk7Ci0gICAgaWYoYXQ8MCkKLSAgICAgIHJldHVybiBmYWxzZTsKLSAgICByZW1vdmVFbGVtZW50QXQoYXQpOwotICAgIHJldHVybiB0cnVlOwotICB9Ci0KLSAgLyoqCi0gICAqIERlbGV0ZXMgdGhlIGNvbXBvbmVudCBhdCB0aGUgc3BlY2lmaWVkIGluZGV4LiBFYWNoIGNvbXBvbmVudCBpbgotICAgKiB0aGlzIHZlY3RvciB3aXRoIGFuIGluZGV4IGdyZWF0ZXIgb3IgZXF1YWwgdG8gdGhlIHNwZWNpZmllZAotICAgKiBpbmRleCBpcyBzaGlmdGVkIGRvd253YXJkIHRvIGhhdmUgYW4gaW5kZXggb25lIHNtYWxsZXIgdGhhbgotICAgKiB0aGUgdmFsdWUgaXQgaGFkIHByZXZpb3VzbHkuCi0gICAqCi0gICAqIEBwYXJhbSBhdCBpbmRleCBvZiB3aGVyZSB0byByZW1vdmUgYSBieXRlCi0gICAqLwotICBwcml2YXRlICB2b2lkIHJlbW92ZUVsZW1lbnRBdChpbnQgYXQpCi0gIHsKLSAgICAvLyBObyBwb2ludCBpbiByZW1vdmluZyBlbGVtZW50cyB0aGF0ICJkb24ndCBleGlzdCIuLi4KLSAgICBpZihhdDxtX2ZpcnN0RnJlZSkKLSAgICB7Ci0gICAgICBpbnQgaW5kZXg9YXQvbV9ibG9ja3NpemU7Ci0gICAgICBpbnQgbWF4aW5kZXg9bV9maXJzdEZyZWUvbV9ibG9ja3NpemU7Ci0gICAgICBpbnQgb2Zmc2V0PWF0JW1fYmxvY2tzaXplOwotCi0gICAgICB3aGlsZShpbmRleDw9bWF4aW5kZXgpCi0gICAgICB7Ci0gICAgICAgIGludCBjb3B5bGVuPW1fYmxvY2tzaXplLW9mZnNldC0xOwotICAgICAgICBieXRlW10gYmxvY2s9bV9tYXBbaW5kZXhdOwotICAgICAgICBpZihudWxsPT1ibG9jaykKLSAgICAgICAgICBibG9jaz1tX21hcFtpbmRleF09bmV3IGJ5dGVbbV9ibG9ja3NpemVdOwotICAgICAgICBlbHNlCi0gICAgICAgICAgU3lzdGVtLmFycmF5Y29weShibG9jaywgb2Zmc2V0KzEsIGJsb2NrLCBvZmZzZXQsIGNvcHlsZW4pOwotICAgICAgICBpZihpbmRleDxtYXhpbmRleCkKLSAgICAgICAgewotICAgICAgICAgIGJ5dGVbXSBuZXh0PW1fbWFwW2luZGV4KzFdOwotICAgICAgICAgIGlmKG5leHQhPW51bGwpCi0gICAgICAgICAgICBibG9ja1ttX2Jsb2Nrc2l6ZS0xXT0obmV4dCE9bnVsbCkgPyBuZXh0WzBdIDogMDsKLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgICAgYmxvY2tbbV9ibG9ja3NpemUtMV09MDsKLSAgICAgICAgb2Zmc2V0PTA7Ci0gICAgICAgICsraW5kZXg7Ci0gICAgICB9Ci0gICAgfQotICAgIC0tbV9maXJzdEZyZWU7Ci0gIH0KLQotICAvKioKLSAgICogU2V0cyB0aGUgY29tcG9uZW50IGF0IHRoZSBzcGVjaWZpZWQgaW5kZXggb2YgdGhpcyB2ZWN0b3IgdG8gYmUgdGhlCi0gICAqIHNwZWNpZmllZCBvYmplY3QuIFRoZSBwcmV2aW91cyBjb21wb25lbnQgYXQgdGhhdCBwb3NpdGlvbiBpcyBkaXNjYXJkZWQuCi0gICAqCi0gICAqIFRoZSBpbmRleCBtdXN0IGJlIGEgdmFsdWUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIDAgYW5kIGxlc3MKLSAgICogdGhhbiB0aGUgY3VycmVudCBzaXplIG9mIHRoZSB2ZWN0b3IuCi0gICAqCi0gICAqIEBwYXJhbSB2YWx1ZQotICAgKiBAcGFyYW0gYXQgICAgIEluZGV4IG9mIHdoZXJlIHRvIHNldCB0aGUgb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRFbGVtZW50QXQoYnl0ZSB2YWx1ZSwgaW50IGF0KQotICB7Ci0gICAgaWYoYXQ8bV9ibG9ja3NpemUpCi0gICAgewotICAgICAgbV9tYXAwW2F0XT12YWx1ZTsKLSAgICAgIHJldHVybjsKLSAgICB9Ci0KLSAgICBpbnQgaW5kZXg9YXQvbV9ibG9ja3NpemU7Ci0gICAgaW50IG9mZnNldD1hdCVtX2Jsb2Nrc2l6ZTsKLQotICAgIGlmKGluZGV4Pj1tX21hcC5sZW5ndGgpCi0gICAgewotICAgICAgaW50IG5ld3NpemU9aW5kZXgrbV9udW1ibG9ja3M7Ci0gICAgICBieXRlW11bXSBuZXdNYXA9bmV3IGJ5dGVbbmV3c2l6ZV1bXTsKLSAgICAgIFN5c3RlbS5hcnJheWNvcHkobV9tYXAsIDAsIG5ld01hcCwgMCwgbV9tYXAubGVuZ3RoKTsKLSAgICAgIG1fbWFwPW5ld01hcDsKLSAgICB9Ci0KLSAgICBieXRlW10gYmxvY2s9bV9tYXBbaW5kZXhdOwotICAgIGlmKG51bGw9PWJsb2NrKQotICAgICAgYmxvY2s9bV9tYXBbaW5kZXhdPW5ldyBieXRlW21fYmxvY2tzaXplXTsKLSAgICBibG9ja1tvZmZzZXRdPXZhbHVlOwotCi0gICAgaWYoYXQ+PW1fZmlyc3RGcmVlKQotICAgICAgbV9maXJzdEZyZWU9YXQrMTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIG50aCBlbGVtZW50LiBUaGlzIGlzIG9mdGVuIGF0IHRoZSBpbm5lcm1vc3QgbG9vcCBvZiBhbgotICAgKiBhcHBsaWNhdGlvbiwgc28gcGVyZm9ybWFuY2UgaXMgY3JpdGljYWwuCi0gICAqCi0gICAqIEBwYXJhbSBpIGluZGV4IG9mIHZhbHVlIHRvIGdldAotICAgKgotICAgKiBAcmV0dXJuIHZhbHVlIGF0IGdpdmVuIGluZGV4LiBJZiB0aGF0IHZhbHVlIHdhc24ndCBwcmV2aW91c2x5IHNldCwKLSAgICogdGhlIHJlc3VsdCBpcyB1bmRlZmluZWQgZm9yIHBlcmZvcm1hbmNlIHJlYXNvbnMuIEl0IG1heSB0aHJvdyBhbgotICAgKiBleGNlcHRpb24gKHNlZSBiZWxvdyksIG1heSByZXR1cm4gemVybywgb3IgKGlmIHNldFNpemUgaGFzIHByZXZpb3VzbHkKLSAgICogYmVlbiB1c2VkKSBtYXkgcmV0dXJuIHN0YWxlIGRhdGEuCi0gICAqCi0gICAqIEB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlmIHRoZSBpbmRleCB3YXMgX2NsZWFybHlfCi0gICAqIHVucmVhc29uYWJsZSAobmVnYXRpdmUsIG9yIHBhc3QgdGhlIGhpZ2hlc3QgYmxvY2spLgotICAgKgotICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBpbmRleCBwb2ludHMgdG8gYSBibG9jayB0aGF0IGNvdWxkCi0gICAqIGhhdmUgZXhpc3RlZCAoYmFzZWQgb24gdGhlIGhpZ2hlc3QgaW5kZXggdXNlZCkgYnV0IGhhcyBuZXZlciBoYWQgYW55dGhpbmcKLSAgICogc2V0IGludG8gaXQuCi0gICAqICVSRVZJRVclIENvdWxkIGFkZCBhIGNhdGNoIHRvIGNyZWF0ZSB0aGUgYmxvY2sgaW4gdGhhdCBjYXNlLCBvciByZXR1cm4gMC4KLSAgICogVHJ5L0NhdGNoIGlzIF9zdXBwb3NlZF8gdG8gYmUgbmVhcmx5IGZyZWUgd2hlbiBub3QgdGhyb3duIHRvLiBEbyB3ZQotICAgKiBiZWxpZXZlIHRoYXQ/IFNob3VsZCB3ZSBoYXZlIGEgc2VwYXJhdGUgc2FmZUVsZW1lbnRBdD8KLSAgICovCi0gIHB1YmxpYyBieXRlIGVsZW1lbnRBdChpbnQgaSkKLSAgewotICAgIC8vICVPUFQlIERvZXMgdGhpcyByZWFsbHkgYnV5IHVzIGFueXRoaW5nPyBUZXN0IHZlcnN1cyBkaXZpc2lvbiBmb3Igc21hbGwsCi0gICAgLy8gdGVzdCBfcGx1c18gZGl2aXNpb24gZm9yIGJpZyBkb2NzLgotICAgIGlmKGk8bV9ibG9ja3NpemUpCi0gICAgICByZXR1cm4gbV9tYXAwW2ldOwotCi0gICAgcmV0dXJuIG1fbWFwW2kvbV9ibG9ja3NpemVdW2klbV9ibG9ja3NpemVdOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgdGhlIHRhYmxlIGNvbnRhaW5zIHRoZSBnaXZlbiBub2RlLgotICAgKgotICAgKiBAcGFyYW0gcyBvYmplY3QgdG8gbG9vayBmb3IKLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHRoZSBvYmplY3QgaXMgaW4gdGhlIGxpc3QKLSAgICovCi0gIHByaXZhdGUgIGJvb2xlYW4gY29udGFpbnMoYnl0ZSBzKQotICB7Ci0gICAgcmV0dXJuIChpbmRleE9mKHMsMCkgPj0gMCk7Ci0gIH0KLQotICAvKioKLSAgICogU2VhcmNoZXMgZm9yIHRoZSBmaXJzdCBvY2N1cmVuY2Ugb2YgdGhlIGdpdmVuIGFyZ3VtZW50LAotICAgKiBiZWdpbm5pbmcgdGhlIHNlYXJjaCBhdCBpbmRleCwgYW5kIHRlc3RpbmcgZm9yIGVxdWFsaXR5Ci0gICAqIHVzaW5nIHRoZSBlcXVhbHMgbWV0aG9kLgotICAgKgotICAgKiBAcGFyYW0gZWxlbSBvYmplY3QgdG8gbG9vayBmb3IKLSAgICogQHBhcmFtIGluZGV4IEluZGV4IG9mIHdoZXJlIHRvIGJlZ2luIHNlYXJjaAotICAgKiBAcmV0dXJuIHRoZSBpbmRleCBvZiB0aGUgZmlyc3Qgb2NjdXJyZW5jZSBvZiB0aGUgb2JqZWN0Ci0gICAqIGFyZ3VtZW50IGluIHRoaXMgdmVjdG9yIGF0IHBvc2l0aW9uIGluZGV4IG9yIGxhdGVyIGluIHRoZQotICAgKiB2ZWN0b3I7IHJldHVybnMgLTEgaWYgdGhlIG9iamVjdCBpcyBub3QgZm91bmQuCi0gICAqLwotICBwdWJsaWMgaW50IGluZGV4T2YoYnl0ZSBlbGVtLCBpbnQgaW5kZXgpCi0gIHsKLSAgICBpZihpbmRleD49bV9maXJzdEZyZWUpCi0gICAgICByZXR1cm4gLTE7Ci0KLSAgICBpbnQgYmluZGV4PWluZGV4L21fYmxvY2tzaXplOwotICAgIGludCBib2Zmc2V0PWluZGV4JW1fYmxvY2tzaXplOwotICAgIGludCBtYXhpbmRleD1tX2ZpcnN0RnJlZS9tX2Jsb2Nrc2l6ZTsKLSAgICBieXRlW10gYmxvY2s7Ci0KLSAgICBmb3IoO2JpbmRleDxtYXhpbmRleDsrK2JpbmRleCkKLSAgICB7Ci0gICAgICBibG9jaz1tX21hcFtiaW5kZXhdOwotICAgICAgaWYoYmxvY2shPW51bGwpCi0gICAgICAgIGZvcihpbnQgb2Zmc2V0PWJvZmZzZXQ7b2Zmc2V0PG1fYmxvY2tzaXplOysrb2Zmc2V0KQotICAgICAgICAgIGlmKGJsb2NrW29mZnNldF09PWVsZW0pCi0gICAgICAgICAgICByZXR1cm4gb2Zmc2V0K2JpbmRleCptX2Jsb2Nrc2l6ZTsKLSAgICAgIGJvZmZzZXQ9MDsgLy8gYWZ0ZXIgZmlyc3QKLSAgICB9Ci0gICAgLy8gTGFzdCBibG9jayBtYXkgbmVlZCB0byBzdG9wIGJlZm9yZSBlbmQKLSAgICBpbnQgbWF4b2Zmc2V0PW1fZmlyc3RGcmVlJW1fYmxvY2tzaXplOwotICAgIGJsb2NrPW1fbWFwW21heGluZGV4XTsKLSAgICBmb3IoaW50IG9mZnNldD1ib2Zmc2V0O29mZnNldDxtYXhvZmZzZXQ7KytvZmZzZXQpCi0gICAgICBpZihibG9ja1tvZmZzZXRdPT1lbGVtKQotICAgICAgICByZXR1cm4gb2Zmc2V0K21heGluZGV4Km1fYmxvY2tzaXplOwotCi0gICAgcmV0dXJuIC0xOwotICB9Ci0KLSAgLyoqCi0gICAqIFNlYXJjaGVzIGZvciB0aGUgZmlyc3Qgb2NjdXJlbmNlIG9mIHRoZSBnaXZlbiBhcmd1bWVudCwKLSAgICogYmVnaW5uaW5nIHRoZSBzZWFyY2ggYXQgaW5kZXgsIGFuZCB0ZXN0aW5nIGZvciBlcXVhbGl0eQotICAgKiB1c2luZyB0aGUgZXF1YWxzIG1ldGhvZC4KLSAgICoKLSAgICogQHBhcmFtIGVsZW0gb2JqZWN0IHRvIGxvb2sgZm9yCi0gICAqIEByZXR1cm4gdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZSBvYmplY3QKLSAgICogYXJndW1lbnQgaW4gdGhpcyB2ZWN0b3IgYXQgcG9zaXRpb24gaW5kZXggb3IgbGF0ZXIgaW4gdGhlCi0gICAqIHZlY3RvcjsgcmV0dXJucyAtMSBpZiB0aGUgb2JqZWN0IGlzIG5vdCBmb3VuZC4KLSAgICovCi0gIHB1YmxpYyBpbnQgaW5kZXhPZihieXRlIGVsZW0pCi0gIHsKLSAgICByZXR1cm4gaW5kZXhPZihlbGVtLDApOwotICB9Ci0KLSAgLyoqCi0gICAqIFNlYXJjaGVzIGZvciB0aGUgZmlyc3Qgb2NjdXJlbmNlIG9mIHRoZSBnaXZlbiBhcmd1bWVudCwKLSAgICogYmVnaW5uaW5nIHRoZSBzZWFyY2ggYXQgaW5kZXgsIGFuZCB0ZXN0aW5nIGZvciBlcXVhbGl0eQotICAgKiB1c2luZyB0aGUgZXF1YWxzIG1ldGhvZC4KLSAgICoKLSAgICogQHBhcmFtIGVsZW0gT2JqZWN0IHRvIGxvb2sgZm9yCi0gICAqIEByZXR1cm4gdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZSBvYmplY3QKLSAgICogYXJndW1lbnQgaW4gdGhpcyB2ZWN0b3IgYXQgcG9zaXRpb24gaW5kZXggb3IgbGF0ZXIgaW4gdGhlCi0gICAqIHZlY3RvcjsgcmV0dXJucyAtMSBpZiB0aGUgb2JqZWN0IGlzIG5vdCBmb3VuZC4KLSAgICovCi0gIHByaXZhdGUgIGludCBsYXN0SW5kZXhPZihieXRlIGVsZW0pCi0gIHsKLSAgICBpbnQgYm9mZnNldD1tX2ZpcnN0RnJlZSVtX2Jsb2Nrc2l6ZTsKLSAgICBmb3IoaW50IGluZGV4PW1fZmlyc3RGcmVlL21fYmxvY2tzaXplOwotICAgICAgICBpbmRleD49MDsKLSAgICAgICAgLS1pbmRleCkKLSAgICB7Ci0gICAgICBieXRlW10gYmxvY2s9bV9tYXBbaW5kZXhdOwotICAgICAgaWYoYmxvY2shPW51bGwpCi0gICAgICAgIGZvcihpbnQgb2Zmc2V0PWJvZmZzZXQ7IG9mZnNldD49MDsgLS1vZmZzZXQpCi0gICAgICAgICAgaWYoYmxvY2tbb2Zmc2V0XT09ZWxlbSkKLSAgICAgICAgICAgIHJldHVybiBvZmZzZXQraW5kZXgqbV9ibG9ja3NpemU7Ci0gICAgICBib2Zmc2V0PTA7IC8vIGFmdGVyIGZpcnN0Ci0gICAgfQotICAgIHJldHVybiAtMTsKLSAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9TdWJhbGxvY2F0ZWRJbnRWZWN0b3IuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL1N1YmFsbG9jYXRlZEludFZlY3Rvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0MDMyMzAyLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL1N1YmFsbG9jYXRlZEludFZlY3Rvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTU5ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFN1YmFsbG9jYXRlZEludFZlY3Rvci5qYXZhLHYgMS4zIDIwMDUvMDkvMjggMTM6NDk6MjIgcHZlZHVsYSBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHM7Ci0KLS8qKgotICogQSB2ZXJ5IHNpbXBsZSB0YWJsZSB0aGF0IHN0b3JlcyBhIGxpc3Qgb2YgaW50LiBWZXJ5IHNpbWlsYXIgQVBJIHRvIG91cgotICogSW50VmVjdG9yIGNsYXNzIChzYW1lIEFQSSk7IGRpZmZlcmVudCBpbnRlcm5hbCBzdG9yYWdlLgotICoKLSAqIFRoaXMgdmVyc2lvbiB1c2VzIGFuIGFycmF5LW9mLWFycmF5cyBzb2x1dGlvbi4gUmVhZC93cml0ZSBhY2Nlc3MgaXMgdGh1cwotICogYSBiaXQgc2xvd2VyIHRoYW4gdGhlIHNpbXBsZSBJbnRWZWN0b3IsIGFuZCBiYXNpYyBzdG9yYWdlIGlzIGEgdHJpZmxlCi0gKiBoaWdoZXIgZHVlIHRvIHRoZSB0b3AtbGV2ZWwgYXJyYXkgLS0gYnV0IGFwcGVuZGluZyBpcyBPKDEpIGZhc3QgcmF0aGVyCi0gKiB0aGFuIE8oTioqMikgc2xvdywgd2hpY2ggd2lsbCBzd2FtcCB0aG9zZSBjb3N0cyBpbiBzaXR1YXRpb25zIHdoZXJlCi0gKiBsb25nIHZlY3RvcnMgYXJlIGJlaW5nIGJ1aWx0IHVwLgotICoKLSAqIEtub3duIGlzc3VlczoKLSAqCi0gKiBTb21lIG1ldGhvZHMgYXJlIHByaXZhdGUgYmVjYXVzZSB0aGV5IGhhdmVuJ3QgeWV0IGJlZW4gdGVzdGVkIHByb3Blcmx5LgotICoKLSAqIFJldHJpZXZhbCBwZXJmb3JtYW5jZSBpcyBjcml0aWNhbCwgc2luY2UgdGhpcyBpcyB1c2VkIGF0IHRoZSBjb3JlCi0gKiBvZiB0aGUgRFRNIG1vZGVsLiAoQXBwZW5kIHBlcmZvcm1hbmNlIGlzIGFsbW9zdCBhcyBpbXBvcnRhbnQuKQotICogVGhhdCdzIHB1c2hpbmcgbWUgdG93YXJkIGp1c3QgbGV0dGluZyByZWFkcyBmcm9tIHVuc2V0IGluZGljZXMKLSAqIHRocm93IGV4Y2VwdGlvbnMgb3IgcmV0dXJuIHN0YWxlIGRhdGE7IHNhZmVyIGJlaGF2aW9yIHdvdWxkIGhhdmUKLSAqIHBlcmZvcm1hbmNlIGNvc3RzLgotICogKi8KLXB1YmxpYyBjbGFzcyBTdWJhbGxvY2F0ZWRJbnRWZWN0b3IKLXsKLSAgLyoqIFNpemUgb2YgYmxvY2tzIHRvIGFsbG9jYXRlICAgICAgICAgICovCi0gIHByb3RlY3RlZCBpbnQgbV9ibG9ja3NpemU7Ci0KLSAgLyoqIEJpdHdpc2UgYWRkcmVzc2luZyAobXVjaCBmYXN0ZXIgdGhhbiBkaXYvcmVtYWluZGVyICovCi0gIHByb3RlY3RlZCBpbnQgbV9TSElGVCwgbV9NQVNLOwotCi0gIC8qKiBUaGUgZGVmYXVsdCBudW1iZXIgb2YgYmxvY2tzIHRvIChvdmVyKWFsbG9jYXRlIGJ5ICovCi0gIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgaW50IE5VTUJMT0NLU19ERUZBVUxUID0gMzI7Ci0KLSAgLyoqIFRoZSBudW1iZXIgb2YgYmxvY2tzIHRvIChvdmVyKWFsbG9jYXRlIGJ5ICovCi0gIHByb3RlY3RlZCBpbnQgbV9udW1ibG9ja3MgPSBOVU1CTE9DS1NfREVGQVVMVDsKLQotICAvKiogQXJyYXkgb2YgYXJyYXlzIG9mIGludHMgICAgICAgICAgKi8KLSAgcHJvdGVjdGVkIGludCBtX21hcFtdW107Ci0KLSAgLyoqIE51bWJlciBvZiBpbnRzIGluIGFycmF5ICAgICAgICAgICovCi0gIHByb3RlY3RlZCBpbnQgbV9maXJzdEZyZWUgPSAwOwotCi0gIC8qKiAiU2hvcnRjdXQiIGhhbmRsZSB0byBtX21hcFswXS4gU3VycHJpc2luZ2x5IGhlbHBmdWwgZm9yIHNob3J0IHZlY3RvcnMuICovCi0gIHByb3RlY3RlZCBpbnQgbV9tYXAwW107Ci0KLSAgLyoqICJTaG9ydGN1dCIgaGFuZGxlIHRvIG1vc3QgcmVjZW50bHkgYWRkZWQgcm93IG9mIG1fbWFwLgotICAgKiBWZXJ5IGhlbHBmdWwgZHVyaW5nIGNvbnN0cnVjdGlvbi4KLSAgICogQHhzbC51c2FnZSBpbnRlcm5hbAotICAgKi8KLSAgcHJvdGVjdGVkIGludCBtX2J1aWxkQ2FjaGVbXTsKLSAgcHJvdGVjdGVkIGludCBtX2J1aWxkQ2FjaGVTdGFydEluZGV4OwotCi0KLSAgLyoqCi0gICAqIERlZmF1bHQgY29uc3RydWN0b3IuICBOb3RlIHRoYXQgdGhlIGRlZmF1bHQKLSAgICogYmxvY2sgc2l6ZSBpcyBjdXJyZW50bHkgMkssIHdoaWNoIG1heSBiZSBvdmVya2lsbCBmb3IKLSAgICogc21hbGwgbGlzdHMgYW5kIHVuZGVyc2hvb3RuZyBmb3IgbGFyZ2Ugb25lcy4KLSAgICovCi0gIHB1YmxpYyBTdWJhbGxvY2F0ZWRJbnRWZWN0b3IoKQotICB7Ci0gICAgdGhpcygyMDQ4KTsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBJbnRWZWN0b3IsIHVzaW5nIHRoZSBnaXZlbiBibG9jayBzaXplIGFuZCBudW1iZXIKLSAgICogb2YgYmxvY2tzLiBGb3IgZWZmaWNpZW5jeSwgd2Ugd2lsbCByb3VuZCB0aGUgcmVxdWVzdGVkIHNpemUKLSAgICogb2ZmIHRvIGEgcG93ZXIgb2YgdHdvLgotICAgKgotICAgKiBAcGFyYW0gYmxvY2tzaXplIFNpemUgb2YgYmxvY2sgdG8gYWxsb2NhdGUKLSAgICogQHBhcmFtIG51bWJsb2NrcyBOdW1iZXIgb2YgYmxvY2tzIHRvIGFsbG9jYXRlCi0gICAqICovCi0gIHB1YmxpYyBTdWJhbGxvY2F0ZWRJbnRWZWN0b3IoaW50IGJsb2Nrc2l6ZSwgaW50IG51bWJsb2NrcykKLSAgewotICAgIC8vbV9ibG9ja3NpemUgPSBibG9ja3NpemU7Ci0gICAgZm9yKG1fU0hJRlQ9MDswIT0oYmxvY2tzaXplPj4+PTEpOysrbV9TSElGVCkKLSAgICAgIDsKLSAgICBtX2Jsb2Nrc2l6ZT0xPDxtX1NISUZUOwotICAgIG1fTUFTSz1tX2Jsb2Nrc2l6ZS0xOwotICAgIG1fbnVtYmxvY2tzID0gbnVtYmxvY2tzOwotCi0gICAgbV9tYXAwPW5ldyBpbnRbbV9ibG9ja3NpemVdOwotICAgIG1fbWFwID0gbmV3IGludFtudW1ibG9ja3NdW107Ci0gICAgbV9tYXBbMF09bV9tYXAwOwotICAgIG1fYnVpbGRDYWNoZSA9IG1fbWFwMDsKLSAgICBtX2J1aWxkQ2FjaGVTdGFydEluZGV4ID0gMDsKLSAgfQotCi0gIC8qKiBDb25zdHJ1Y3QgYSBJbnRWZWN0b3IsIHVzaW5nIHRoZSBnaXZlbiBibG9jayBzaXplIGFuZAotICAgKiB0aGUgZGVmYXVsdCBudW1iZXIgb2YgYmxvY2tzICgzMikuCi0gICAqCi0gICAqIEBwYXJhbSBibG9ja3NpemUgU2l6ZSBvZiBibG9jayB0byBhbGxvY2F0ZQotICAgKiAqLwotICBwdWJsaWMgU3ViYWxsb2NhdGVkSW50VmVjdG9yKGludCBibG9ja3NpemUpCi0gIHsKLSAgICB0aGlzKGJsb2Nrc2l6ZSwgTlVNQkxPQ0tTX0RFRkFVTFQpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbGVuZ3RoIG9mIHRoZSBsaXN0LgotICAgKgotICAgKiBAcmV0dXJuIGxlbmd0aCBvZiB0aGUgbGlzdAotICAgKi8KLSAgcHVibGljIGludCBzaXplKCkKLSAgewotICAgIHJldHVybiBtX2ZpcnN0RnJlZTsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIGxlbmd0aCBvZiB0aGUgbGlzdC4gVGhpcyB3aWxsIG9ubHkgd29yayB0byB0cnVuY2F0ZSB0aGUgbGlzdCwgYW5kCi0gICAqIGV2ZW4gdGhlbiBpdCBoYXMgbm90IGJlZW4gaGVhdmlseSB0ZXN0ZWQgYW5kIG1heSBub3QgYmUgdHJ1c3R3b3J0aHkuCi0gICAqCi0gICAqIEByZXR1cm4gbGVuZ3RoIG9mIHRoZSBsaXN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRTaXplKGludCBzeikKLSAgewotICAgIGlmKG1fZmlyc3RGcmVlPnN6KSAvLyBXaHVwczsgaGFkIHRoYXQgYmFja3dhcmQhCi0gICAgICBtX2ZpcnN0RnJlZSA9IHN6OwotICB9Ci0KLSAgLyoqCi0gICAqIEFwcGVuZCBhIGludCBvbnRvIHRoZSB2ZWN0b3IuCi0gICAqCi0gICAqIEBwYXJhbSB2YWx1ZSBJbnQgdG8gYWRkIHRvIHRoZSBsaXN0Ci0gICAqLwotICBwdWJsaWMgIHZvaWQgYWRkRWxlbWVudChpbnQgdmFsdWUpCi0gIHsKLSAgICBpbnQgaW5kZXhSZWxhdGl2ZVRvQ2FjaGUgPSBtX2ZpcnN0RnJlZSAtIG1fYnVpbGRDYWNoZVN0YXJ0SW5kZXg7Ci0KLSAgICAvLyBJcyB0aGUgbmV3IGluZGV4IGFuIGluZGV4IGludG8gdGhlIGNhY2hlIHJvdyBvZiBtX21hcD8KLSAgICBpZihpbmRleFJlbGF0aXZlVG9DYWNoZSA+PSAwICYmIGluZGV4UmVsYXRpdmVUb0NhY2hlIDwgbV9ibG9ja3NpemUpIHsKLSAgICAgIG1fYnVpbGRDYWNoZVtpbmRleFJlbGF0aXZlVG9DYWNoZV09dmFsdWU7Ci0gICAgICArK21fZmlyc3RGcmVlOwotICAgIH0gZWxzZSB7Ci0gICAgICAvLyBHcm93aW5nIHRoZSBvdXRlciBhcnJheSBzaG91bGQgYmUgcmFyZS4gV2UgaW5pdGlhbGl6ZSB0byBhCi0gICAgICAvLyB0b3RhbCBvZiBtX2Jsb2Nrc2l6ZSBzcXVhcmVkIGVsZW1lbnRzLCB3aGljaCBhdCB0aGUgZGVmYXVsdAotICAgICAgLy8gc2l6ZSBpcyA0TSBpbnRlZ2Vycy4uLiBhbmQgd2UgZ3JvdyBieSBhdCBsZWFzdCB0aGF0IG11Y2ggZWFjaAotICAgICAgLy8gdGltZS4gIEhvd2V2ZXIsIGF0dGVtcHRzIHRvIG1pY3Jvb3B0aW1pemUgZm9yIHRoaXMgKGFzc3VtZQotICAgICAgLy8gbG9uZyBlbm91Z2ggYW5kIGNhdGNoIGV4Y2VwdGlvbnMpIHlpZWxkIG5vIG5vdGljYWJsZQotICAgICAgLy8gaW1wcm92ZW1lbnQuCi0KLSAgICAgIGludCBpbmRleD1tX2ZpcnN0RnJlZT4+Pm1fU0hJRlQ7Ci0gICAgICBpbnQgb2Zmc2V0PW1fZmlyc3RGcmVlJm1fTUFTSzsKLQotICAgICAgaWYoaW5kZXg+PW1fbWFwLmxlbmd0aCkKLSAgICAgIHsKLSAgICAgICAgaW50IG5ld3NpemU9aW5kZXgrbV9udW1ibG9ja3M7Ci0gICAgICAgIGludFtdW10gbmV3TWFwPW5ldyBpbnRbbmV3c2l6ZV1bXTsKLSAgICAgICAgU3lzdGVtLmFycmF5Y29weShtX21hcCwgMCwgbmV3TWFwLCAwLCBtX21hcC5sZW5ndGgpOwotICAgICAgICBtX21hcD1uZXdNYXA7Ci0gICAgICB9Ci0gICAgICBpbnRbXSBibG9jaz1tX21hcFtpbmRleF07Ci0gICAgICBpZihudWxsPT1ibG9jaykKLSAgICAgICAgYmxvY2s9bV9tYXBbaW5kZXhdPW5ldyBpbnRbbV9ibG9ja3NpemVdOwotICAgICAgYmxvY2tbb2Zmc2V0XT12YWx1ZTsKLQotICAgICAgLy8gQ2FjaGUgdGhlIGN1cnJlbnQgcm93IG9mIG1fbWFwLiAgTmV4dCBtX2Jsb2Nrc2l6ZS0xCi0gICAgICAvLyB2YWx1ZXMgYWRkZWQgd2lsbCBnbyB0byB0aGlzIHJvdy4KLSAgICAgIG1fYnVpbGRDYWNoZSA9IGJsb2NrOwotICAgICAgbV9idWlsZENhY2hlU3RhcnRJbmRleCA9IG1fZmlyc3RGcmVlLW9mZnNldDsKLQotICAgICAgKyttX2ZpcnN0RnJlZTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogQXBwZW5kIHNldmVyYWwgaW50IHZhbHVlcyBvbnRvIHRoZSB2ZWN0b3IuCi0gICAqCi0gICAqIEBwYXJhbSB2YWx1ZSBJbnQgdG8gYWRkIHRvIHRoZSBsaXN0Ci0gICAqLwotICBwcml2YXRlICB2b2lkIGFkZEVsZW1lbnRzKGludCB2YWx1ZSwgaW50IG51bWJlck9mRWxlbWVudHMpCi0gIHsKLSAgICBpZihtX2ZpcnN0RnJlZStudW1iZXJPZkVsZW1lbnRzPG1fYmxvY2tzaXplKQotICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW1iZXJPZkVsZW1lbnRzOyBpKyspCi0gICAgICB7Ci0gICAgICAgIG1fbWFwMFttX2ZpcnN0RnJlZSsrXT12YWx1ZTsKLSAgICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgaW50IGluZGV4PW1fZmlyc3RGcmVlPj4+bV9TSElGVDsKLSAgICAgIGludCBvZmZzZXQ9bV9maXJzdEZyZWUmbV9NQVNLOwotICAgICAgbV9maXJzdEZyZWUrPW51bWJlck9mRWxlbWVudHM7Ci0gICAgICB3aGlsZSggbnVtYmVyT2ZFbGVtZW50cz4wKQotICAgICAgewotICAgICAgICBpZihpbmRleD49bV9tYXAubGVuZ3RoKQotICAgICAgICB7Ci0gICAgICAgICAgaW50IG5ld3NpemU9aW5kZXgrbV9udW1ibG9ja3M7Ci0gICAgICAgICAgaW50W11bXSBuZXdNYXA9bmV3IGludFtuZXdzaXplXVtdOwotICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkobV9tYXAsIDAsIG5ld01hcCwgMCwgbV9tYXAubGVuZ3RoKTsKLSAgICAgICAgICBtX21hcD1uZXdNYXA7Ci0gICAgICAgIH0KLSAgICAgICAgaW50W10gYmxvY2s9bV9tYXBbaW5kZXhdOwotICAgICAgICBpZihudWxsPT1ibG9jaykKLSAgICAgICAgICBibG9jaz1tX21hcFtpbmRleF09bmV3IGludFttX2Jsb2Nrc2l6ZV07Ci0gICAgICAgIGludCBjb3BpZWQ9KG1fYmxvY2tzaXplLW9mZnNldCA8IG51bWJlck9mRWxlbWVudHMpCi0gICAgICAgICAgPyBtX2Jsb2Nrc2l6ZS1vZmZzZXQgOiBudW1iZXJPZkVsZW1lbnRzOwotICAgICAgICBudW1iZXJPZkVsZW1lbnRzLT1jb3BpZWQ7Ci0gICAgICAgIHdoaWxlKGNvcGllZC0tID4gMCkKLSAgICAgICAgICBibG9ja1tvZmZzZXQrK109dmFsdWU7Ci0KLSAgICAgICAgKytpbmRleDtvZmZzZXQ9MDsKLSAgICAgIH0KLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogQXBwZW5kIHNldmVyYWwgc2xvdHMgb250byB0aGUgdmVjdG9yLCBidXQgZG8gbm90IHNldCB0aGUgdmFsdWVzLgotICAgKiBOb3RlOiAiTm90IFNldCIgbWVhbnMgdGhlIHZhbHVlIGlzIHVuc3BlY2lmaWVkLgotICAgKgotICAgKiBAcGFyYW0gbnVtYmVyT2ZFbGVtZW50cyBJbnQgdG8gYWRkIHRvIHRoZSBsaXN0Ci0gICAqLwotICBwcml2YXRlICB2b2lkIGFkZEVsZW1lbnRzKGludCBudW1iZXJPZkVsZW1lbnRzKQotICB7Ci0gICAgaW50IG5ld2xlbj1tX2ZpcnN0RnJlZStudW1iZXJPZkVsZW1lbnRzOwotICAgIGlmKG5ld2xlbj5tX2Jsb2Nrc2l6ZSkKLSAgICB7Ci0gICAgICBpbnQgaW5kZXg9bV9maXJzdEZyZWU+Pj5tX1NISUZUOwotICAgICAgaW50IG5ld2luZGV4PShtX2ZpcnN0RnJlZStudW1iZXJPZkVsZW1lbnRzKT4+Pm1fU0hJRlQ7Ci0gICAgICBmb3IoaW50IGk9aW5kZXgrMTtpPD1uZXdpbmRleDsrK2kpCi0gICAgICAgIG1fbWFwW2ldPW5ldyBpbnRbbV9ibG9ja3NpemVdOwotICAgIH0KLSAgICBtX2ZpcnN0RnJlZT1uZXdsZW47Ci0gIH0KLQotICAvKioKLSAgICogSW5zZXJ0cyB0aGUgc3BlY2lmaWVkIG5vZGUgaW4gdGhpcyB2ZWN0b3IgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4KLSAgICogRWFjaCBjb21wb25lbnQgaW4gdGhpcyB2ZWN0b3Igd2l0aCBhbiBpbmRleCBncmVhdGVyIG9yIGVxdWFsIHRvCi0gICAqIHRoZSBzcGVjaWZpZWQgaW5kZXggaXMgc2hpZnRlZCB1cHdhcmQgdG8gaGF2ZSBhbiBpbmRleCBvbmUgZ3JlYXRlcgotICAgKiB0aGFuIHRoZSB2YWx1ZSBpdCBoYWQgcHJldmlvdXNseS4KLSAgICoKLSAgICogSW5zZXJ0aW9uIG1heSBiZSBhbiBFWFBFTlNJVkUgb3BlcmF0aW9uIQotICAgKgotICAgKiBAcGFyYW0gdmFsdWUgSW50IHRvIGluc2VydAotICAgKiBAcGFyYW0gYXQgSW5kZXggb2Ygd2hlcmUgdG8gaW5zZXJ0Ci0gICAqLwotICBwcml2YXRlICB2b2lkIGluc2VydEVsZW1lbnRBdChpbnQgdmFsdWUsIGludCBhdCkKLSAgewotICAgIGlmKGF0PT1tX2ZpcnN0RnJlZSkKLSAgICAgIGFkZEVsZW1lbnQodmFsdWUpOwotICAgIGVsc2UgaWYgKGF0Pm1fZmlyc3RGcmVlKQotICAgIHsKLSAgICAgIGludCBpbmRleD1hdD4+Pm1fU0hJRlQ7Ci0gICAgICBpZihpbmRleD49bV9tYXAubGVuZ3RoKQotICAgICAgewotICAgICAgICBpbnQgbmV3c2l6ZT1pbmRleCttX251bWJsb2NrczsKLSAgICAgICAgaW50W11bXSBuZXdNYXA9bmV3IGludFtuZXdzaXplXVtdOwotICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KG1fbWFwLCAwLCBuZXdNYXAsIDAsIG1fbWFwLmxlbmd0aCk7Ci0gICAgICAgIG1fbWFwPW5ld01hcDsKLSAgICAgIH0KLSAgICAgIGludFtdIGJsb2NrPW1fbWFwW2luZGV4XTsKLSAgICAgIGlmKG51bGw9PWJsb2NrKQotICAgICAgICBibG9jaz1tX21hcFtpbmRleF09bmV3IGludFttX2Jsb2Nrc2l6ZV07Ci0gICAgICBpbnQgb2Zmc2V0PWF0Jm1fTUFTSzsKLSAgICAgICAgICBibG9ja1tvZmZzZXRdPXZhbHVlOwotICAgICAgICAgIG1fZmlyc3RGcmVlPW9mZnNldCsxOwotICAgICAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIGludCBpbmRleD1hdD4+Pm1fU0hJRlQ7Ci0gICAgICBpbnQgbWF4aW5kZXg9bV9maXJzdEZyZWU+Pj5tX1NISUZUOyAvLyAlUkVWSUVXJSAobV9maXJzdEZyZWUrMT8pCi0gICAgICArK21fZmlyc3RGcmVlOwotICAgICAgaW50IG9mZnNldD1hdCZtX01BU0s7Ci0gICAgICBpbnQgcHVzaDsKLQotICAgICAgLy8gKioqKiogRWFzaWVyIHRvIHdvcmsgZG93biBmcm9tIHRvcD8KLSAgICAgIHdoaWxlKGluZGV4PD1tYXhpbmRleCkKLSAgICAgIHsKLSAgICAgICAgaW50IGNvcHlsZW49bV9ibG9ja3NpemUtb2Zmc2V0LTE7Ci0gICAgICAgIGludFtdIGJsb2NrPW1fbWFwW2luZGV4XTsKLSAgICAgICAgaWYobnVsbD09YmxvY2spCi0gICAgICAgIHsKLSAgICAgICAgICBwdXNoPTA7Ci0gICAgICAgICAgYmxvY2s9bV9tYXBbaW5kZXhdPW5ldyBpbnRbbV9ibG9ja3NpemVdOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotICAgICAgICAgIHB1c2g9YmxvY2tbbV9ibG9ja3NpemUtMV07Ci0gICAgICAgICAgU3lzdGVtLmFycmF5Y29weShibG9jaywgb2Zmc2V0ICwgYmxvY2ssIG9mZnNldCsxLCBjb3B5bGVuKTsKLSAgICAgICAgfQotICAgICAgICBibG9ja1tvZmZzZXRdPXZhbHVlOwotICAgICAgICB2YWx1ZT1wdXNoOwotICAgICAgICBvZmZzZXQ9MDsKLSAgICAgICAgKytpbmRleDsKLSAgICAgIH0KLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogV2lwZSBpdCBvdXQuIEN1cnJlbnRseSBkZWZpbmVkIGFzIGVxdWl2YWxlbnQgdG8gc2V0U2l6ZSgwKS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHJlbW92ZUFsbEVsZW1lbnRzKCkKLSAgewotICAgIG1fZmlyc3RGcmVlID0gMDsKLSAgICBtX2J1aWxkQ2FjaGUgPSBtX21hcDA7Ci0gICAgbV9idWlsZENhY2hlU3RhcnRJbmRleCA9IDA7Ci0gIH0KLQotICAvKioKLSAgICogUmVtb3ZlcyB0aGUgZmlyc3Qgb2NjdXJyZW5jZSBvZiB0aGUgYXJndW1lbnQgZnJvbSB0aGlzIHZlY3Rvci4KLSAgICogSWYgdGhlIG9iamVjdCBpcyBmb3VuZCBpbiB0aGlzIHZlY3RvciwgZWFjaCBjb21wb25lbnQgaW4gdGhlIHZlY3RvcgotICAgKiB3aXRoIGFuIGluZGV4IGdyZWF0ZXIgb3IgZXF1YWwgdG8gdGhlIG9iamVjdCdzIGluZGV4IGlzIHNoaWZ0ZWQKLSAgICogZG93bndhcmQgdG8gaGF2ZSBhbiBpbmRleCBvbmUgc21hbGxlciB0aGFuIHRoZSB2YWx1ZSBpdCBoYWQKLSAgICogcHJldmlvdXNseS4KLSAgICoKLSAgICogQHBhcmFtIHMgSW50IHRvIHJlbW92ZSBmcm9tIGFycmF5Ci0gICAqCi0gICAqIEByZXR1cm4gVHJ1ZSBpZiB0aGUgaW50IHdhcyByZW1vdmVkLCBmYWxzZSBpZiBpdCB3YXMgbm90IGZvdW5kCi0gICAqLwotICBwcml2YXRlICBib29sZWFuIHJlbW92ZUVsZW1lbnQoaW50IHMpCi0gIHsKLSAgICBpbnQgYXQ9aW5kZXhPZihzLDApOwotICAgIGlmKGF0PDApCi0gICAgICByZXR1cm4gZmFsc2U7Ci0gICAgcmVtb3ZlRWxlbWVudEF0KGF0KTsKLSAgICByZXR1cm4gdHJ1ZTsKLSAgfQotCi0gIC8qKgotICAgKiBEZWxldGVzIHRoZSBjb21wb25lbnQgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4gRWFjaCBjb21wb25lbnQgaW4KLSAgICogdGhpcyB2ZWN0b3Igd2l0aCBhbiBpbmRleCBncmVhdGVyIG9yIGVxdWFsIHRvIHRoZSBzcGVjaWZpZWQKLSAgICogaW5kZXggaXMgc2hpZnRlZCBkb3dud2FyZCB0byBoYXZlIGFuIGluZGV4IG9uZSBzbWFsbGVyIHRoYW4KLSAgICogdGhlIHZhbHVlIGl0IGhhZCBwcmV2aW91c2x5LgotICAgKgotICAgKiBAcGFyYW0gYXQgaW5kZXggb2Ygd2hlcmUgdG8gcmVtb3ZlIGFuZCBpbnQKLSAgICovCi0gIHByaXZhdGUgIHZvaWQgcmVtb3ZlRWxlbWVudEF0KGludCBhdCkKLSAgewotICAgICAgICAvLyBObyBwb2ludCBpbiByZW1vdmluZyBlbGVtZW50cyB0aGF0ICJkb24ndCBleGlzdCIuLi4KLSAgICBpZihhdDxtX2ZpcnN0RnJlZSkKLSAgICB7Ci0gICAgICBpbnQgaW5kZXg9YXQ+Pj5tX1NISUZUOwotICAgICAgaW50IG1heGluZGV4PW1fZmlyc3RGcmVlPj4+bV9TSElGVDsKLSAgICAgIGludCBvZmZzZXQ9YXQmbV9NQVNLOwotCi0gICAgICB3aGlsZShpbmRleDw9bWF4aW5kZXgpCi0gICAgICB7Ci0gICAgICAgIGludCBjb3B5bGVuPW1fYmxvY2tzaXplLW9mZnNldC0xOwotICAgICAgICBpbnRbXSBibG9jaz1tX21hcFtpbmRleF07Ci0gICAgICAgIGlmKG51bGw9PWJsb2NrKQotICAgICAgICAgIGJsb2NrPW1fbWFwW2luZGV4XT1uZXcgaW50W21fYmxvY2tzaXplXTsKLSAgICAgICAgZWxzZQotICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYmxvY2ssIG9mZnNldCsxLCBibG9jaywgb2Zmc2V0LCBjb3B5bGVuKTsKLSAgICAgICAgaWYoaW5kZXg8bWF4aW5kZXgpCi0gICAgICAgIHsKLSAgICAgICAgICBpbnRbXSBuZXh0PW1fbWFwW2luZGV4KzFdOwotICAgICAgICAgIGlmKG5leHQhPW51bGwpCi0gICAgICAgICAgICBibG9ja1ttX2Jsb2Nrc2l6ZS0xXT0obmV4dCE9bnVsbCkgPyBuZXh0WzBdIDogMDsKLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgICAgYmxvY2tbbV9ibG9ja3NpemUtMV09MDsKLSAgICAgICAgb2Zmc2V0PTA7Ci0gICAgICAgICsraW5kZXg7Ci0gICAgICB9Ci0gICAgfQotICAgIC0tbV9maXJzdEZyZWU7Ci0gIH0KLQotICAvKioKLSAgICogU2V0cyB0aGUgY29tcG9uZW50IGF0IHRoZSBzcGVjaWZpZWQgaW5kZXggb2YgdGhpcyB2ZWN0b3IgdG8gYmUgdGhlCi0gICAqIHNwZWNpZmllZCBvYmplY3QuIFRoZSBwcmV2aW91cyBjb21wb25lbnQgYXQgdGhhdCBwb3NpdGlvbiBpcyBkaXNjYXJkZWQuCi0gICAqCi0gICAqIFRoZSBpbmRleCBtdXN0IGJlIGEgdmFsdWUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIDAgYW5kIGxlc3MKLSAgICogdGhhbiB0aGUgY3VycmVudCBzaXplIG9mIHRoZSB2ZWN0b3IuCi0gICAqCi0gICAqIEBwYXJhbSB2YWx1ZSBvYmplY3QgdG8gc2V0Ci0gICAqIEBwYXJhbSBhdCAgICBJbmRleCBvZiB3aGVyZSB0byBzZXQgdGhlIG9iamVjdAotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0RWxlbWVudEF0KGludCB2YWx1ZSwgaW50IGF0KQotICB7Ci0gICAgaWYoYXQ8bV9ibG9ja3NpemUpCi0gICAgICBtX21hcDBbYXRdPXZhbHVlOwotICAgIGVsc2UKLSAgICB7Ci0gICAgICBpbnQgaW5kZXg9YXQ+Pj5tX1NISUZUOwotICAgICAgaW50IG9mZnNldD1hdCZtX01BU0s7Ci0KLSAgICAgIGlmKGluZGV4Pj1tX21hcC5sZW5ndGgpCi0gICAgICB7Ci0gICAgICAgIGludCBuZXdzaXplPWluZGV4K21fbnVtYmxvY2tzOwotICAgICAgICBpbnRbXVtdIG5ld01hcD1uZXcgaW50W25ld3NpemVdW107Ci0gICAgICAgIFN5c3RlbS5hcnJheWNvcHkobV9tYXAsIDAsIG5ld01hcCwgMCwgbV9tYXAubGVuZ3RoKTsKLSAgICAgICAgbV9tYXA9bmV3TWFwOwotICAgICAgfQotCi0gICAgICBpbnRbXSBibG9jaz1tX21hcFtpbmRleF07Ci0gICAgICBpZihudWxsPT1ibG9jaykKLSAgICAgICAgYmxvY2s9bV9tYXBbaW5kZXhdPW5ldyBpbnRbbV9ibG9ja3NpemVdOwotICAgICAgYmxvY2tbb2Zmc2V0XT12YWx1ZTsKLSAgICB9Ci0KLSAgICBpZihhdD49bV9maXJzdEZyZWUpCi0gICAgICBtX2ZpcnN0RnJlZT1hdCsxOwotICB9Ci0KLQotICAvKioKLSAgICogR2V0IHRoZSBudGggZWxlbWVudC4gVGhpcyBpcyBvZnRlbiBhdCB0aGUgaW5uZXJtb3N0IGxvb3Agb2YgYW4KLSAgICogYXBwbGljYXRpb24sIHNvIHBlcmZvcm1hbmNlIGlzIGNyaXRpY2FsLgotICAgKgotICAgKiBAcGFyYW0gaSBpbmRleCBvZiB2YWx1ZSB0byBnZXQKLSAgICoKLSAgICogQHJldHVybiB2YWx1ZSBhdCBnaXZlbiBpbmRleC4gSWYgdGhhdCB2YWx1ZSB3YXNuJ3QgcHJldmlvdXNseSBzZXQsCi0gICAqIHRoZSByZXN1bHQgaXMgdW5kZWZpbmVkIGZvciBwZXJmb3JtYW5jZSByZWFzb25zLiBJdCBtYXkgdGhyb3cgYW4KLSAgICogZXhjZXB0aW9uIChzZWUgYmVsb3cpLCBtYXkgcmV0dXJuIHplcm8sIG9yIChpZiBzZXRTaXplIGhhcyBwcmV2aW91c2x5Ci0gICAqIGJlZW4gdXNlZCkgbWF5IHJldHVybiBzdGFsZSBkYXRhLgotICAgKgotICAgKiBAdGhyb3dzIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpZiB0aGUgaW5kZXggd2FzIF9jbGVhcmx5XwotICAgKiB1bnJlYXNvbmFibGUgKG5lZ2F0aXZlLCBvciBwYXN0IHRoZSBoaWdoZXN0IGJsb2NrKS4KLSAgICoKLSAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgaW5kZXggcG9pbnRzIHRvIGEgYmxvY2sgdGhhdCBjb3VsZAotICAgKiBoYXZlIGV4aXN0ZWQgKGJhc2VkIG9uIHRoZSBoaWdoZXN0IGluZGV4IHVzZWQpIGJ1dCBoYXMgbmV2ZXIgaGFkIGFueXRoaW5nCi0gICAqIHNldCBpbnRvIGl0LgotICAgKiAlUkVWSUVXJSBDb3VsZCBhZGQgYSBjYXRjaCB0byBjcmVhdGUgdGhlIGJsb2NrIGluIHRoYXQgY2FzZSwgb3IgcmV0dXJuIDAuCi0gICAqIFRyeS9DYXRjaCBpcyBfc3VwcG9zZWRfIHRvIGJlIG5lYXJseSBmcmVlIHdoZW4gbm90IHRocm93biB0by4gRG8gd2UKLSAgICogYmVsaWV2ZSB0aGF0PyBTaG91bGQgd2UgaGF2ZSBhIHNlcGFyYXRlIHNhZmVFbGVtZW50QXQ/Ci0gICAqLwotICBwdWJsaWMgaW50IGVsZW1lbnRBdChpbnQgaSkKLSAgewotICAgIC8vIFRoaXMgaXMgYWN0dWFsbHkgYSBzaWduaWZpY2FudCBvcHRpbWl6YXRpb24hCi0gICAgaWYoaTxtX2Jsb2Nrc2l6ZSkKLSAgICAgIHJldHVybiBtX21hcDBbaV07Ci0KLSAgICByZXR1cm4gbV9tYXBbaT4+Pm1fU0hJRlRdW2kmbV9NQVNLXTsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIGlmIHRoZSB0YWJsZSBjb250YWlucyB0aGUgZ2l2ZW4gbm9kZS4KLSAgICoKLSAgICogQHBhcmFtIHMgb2JqZWN0IHRvIGxvb2sgZm9yCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgb2JqZWN0IGlzIGluIHRoZSBsaXN0Ci0gICAqLwotICBwcml2YXRlICBib29sZWFuIGNvbnRhaW5zKGludCBzKQotICB7Ci0gICAgcmV0dXJuIChpbmRleE9mKHMsMCkgPj0gMCk7Ci0gIH0KLQotICAvKioKLSAgICogU2VhcmNoZXMgZm9yIHRoZSBmaXJzdCBvY2N1cmVuY2Ugb2YgdGhlIGdpdmVuIGFyZ3VtZW50LAotICAgKiBiZWdpbm5pbmcgdGhlIHNlYXJjaCBhdCBpbmRleCwgYW5kIHRlc3RpbmcgZm9yIGVxdWFsaXR5Ci0gICAqIHVzaW5nIHRoZSBlcXVhbHMgbWV0aG9kLgotICAgKgotICAgKiBAcGFyYW0gZWxlbSBvYmplY3QgdG8gbG9vayBmb3IKLSAgICogQHBhcmFtIGluZGV4IEluZGV4IG9mIHdoZXJlIHRvIGJlZ2luIHNlYXJjaAotICAgKiBAcmV0dXJuIHRoZSBpbmRleCBvZiB0aGUgZmlyc3Qgb2NjdXJyZW5jZSBvZiB0aGUgb2JqZWN0Ci0gICAqIGFyZ3VtZW50IGluIHRoaXMgdmVjdG9yIGF0IHBvc2l0aW9uIGluZGV4IG9yIGxhdGVyIGluIHRoZQotICAgKiB2ZWN0b3I7IHJldHVybnMgLTEgaWYgdGhlIG9iamVjdCBpcyBub3QgZm91bmQuCi0gICAqLwotICBwdWJsaWMgaW50IGluZGV4T2YoaW50IGVsZW0sIGludCBpbmRleCkKLSAgewotICAgICAgICBpZihpbmRleD49bV9maXJzdEZyZWUpCi0gICAgICAgICAgICAgICAgcmV0dXJuIC0xOwotCi0gICAgaW50IGJpbmRleD1pbmRleD4+Pm1fU0hJRlQ7Ci0gICAgaW50IGJvZmZzZXQ9aW5kZXgmbV9NQVNLOwotICAgIGludCBtYXhpbmRleD1tX2ZpcnN0RnJlZT4+Pm1fU0hJRlQ7Ci0gICAgaW50W10gYmxvY2s7Ci0KLSAgICBmb3IoO2JpbmRleDxtYXhpbmRleDsrK2JpbmRleCkKLSAgICB7Ci0gICAgICBibG9jaz1tX21hcFtiaW5kZXhdOwotICAgICAgaWYoYmxvY2shPW51bGwpCi0gICAgICAgIGZvcihpbnQgb2Zmc2V0PWJvZmZzZXQ7b2Zmc2V0PG1fYmxvY2tzaXplOysrb2Zmc2V0KQotICAgICAgICAgIGlmKGJsb2NrW29mZnNldF09PWVsZW0pCi0gICAgICAgICAgICByZXR1cm4gb2Zmc2V0K2JpbmRleCptX2Jsb2Nrc2l6ZTsKLSAgICAgIGJvZmZzZXQ9MDsgLy8gYWZ0ZXIgZmlyc3QKLSAgICB9Ci0gICAgLy8gTGFzdCBibG9jayBtYXkgbmVlZCB0byBzdG9wIGJlZm9yZSBlbmQKLSAgICBpbnQgbWF4b2Zmc2V0PW1fZmlyc3RGcmVlJm1fTUFTSzsKLSAgICBibG9jaz1tX21hcFttYXhpbmRleF07Ci0gICAgZm9yKGludCBvZmZzZXQ9Ym9mZnNldDtvZmZzZXQ8bWF4b2Zmc2V0Oysrb2Zmc2V0KQotICAgICAgaWYoYmxvY2tbb2Zmc2V0XT09ZWxlbSkKLSAgICAgICAgcmV0dXJuIG9mZnNldCttYXhpbmRleCptX2Jsb2Nrc2l6ZTsKLQotICAgIHJldHVybiAtMTsKLSAgfQotCi0gIC8qKgotICAgKiBTZWFyY2hlcyBmb3IgdGhlIGZpcnN0IG9jY3VyZW5jZSBvZiB0aGUgZ2l2ZW4gYXJndW1lbnQsCi0gICAqIGJlZ2lubmluZyB0aGUgc2VhcmNoIGF0IGluZGV4LCBhbmQgdGVzdGluZyBmb3IgZXF1YWxpdHkKLSAgICogdXNpbmcgdGhlIGVxdWFscyBtZXRob2QuCi0gICAqCi0gICAqIEBwYXJhbSBlbGVtIG9iamVjdCB0byBsb29rIGZvcgotICAgKiBAcmV0dXJuIHRoZSBpbmRleCBvZiB0aGUgZmlyc3Qgb2NjdXJyZW5jZSBvZiB0aGUgb2JqZWN0Ci0gICAqIGFyZ3VtZW50IGluIHRoaXMgdmVjdG9yIGF0IHBvc2l0aW9uIGluZGV4IG9yIGxhdGVyIGluIHRoZQotICAgKiB2ZWN0b3I7IHJldHVybnMgLTEgaWYgdGhlIG9iamVjdCBpcyBub3QgZm91bmQuCi0gICAqLwotICBwdWJsaWMgaW50IGluZGV4T2YoaW50IGVsZW0pCi0gIHsKLSAgICByZXR1cm4gaW5kZXhPZihlbGVtLDApOwotICB9Ci0KLSAgLyoqCi0gICAqIFNlYXJjaGVzIGZvciB0aGUgZmlyc3Qgb2NjdXJlbmNlIG9mIHRoZSBnaXZlbiBhcmd1bWVudCwKLSAgICogYmVnaW5uaW5nIHRoZSBzZWFyY2ggYXQgaW5kZXgsIGFuZCB0ZXN0aW5nIGZvciBlcXVhbGl0eQotICAgKiB1c2luZyB0aGUgZXF1YWxzIG1ldGhvZC4KLSAgICoKLSAgICogQHBhcmFtIGVsZW0gT2JqZWN0IHRvIGxvb2sgZm9yCi0gICAqIEByZXR1cm4gdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZSBvYmplY3QKLSAgICogYXJndW1lbnQgaW4gdGhpcyB2ZWN0b3IgYXQgcG9zaXRpb24gaW5kZXggb3IgbGF0ZXIgaW4gdGhlCi0gICAqIHZlY3RvcjsgcmV0dXJucyAtMSBpZiB0aGUgb2JqZWN0IGlzIG5vdCBmb3VuZC4KLSAgICovCi0gIHByaXZhdGUgIGludCBsYXN0SW5kZXhPZihpbnQgZWxlbSkKLSAgewotICAgIGludCBib2Zmc2V0PW1fZmlyc3RGcmVlJm1fTUFTSzsKLSAgICBmb3IoaW50IGluZGV4PW1fZmlyc3RGcmVlPj4+bV9TSElGVDsKLSAgICAgICAgaW5kZXg+PTA7Ci0gICAgICAgIC0taW5kZXgpCi0gICAgewotICAgICAgaW50W10gYmxvY2s9bV9tYXBbaW5kZXhdOwotICAgICAgaWYoYmxvY2shPW51bGwpCi0gICAgICAgIGZvcihpbnQgb2Zmc2V0PWJvZmZzZXQ7IG9mZnNldD49MDsgLS1vZmZzZXQpCi0gICAgICAgICAgaWYoYmxvY2tbb2Zmc2V0XT09ZWxlbSkKLSAgICAgICAgICAgIHJldHVybiBvZmZzZXQraW5kZXgqbV9ibG9ja3NpemU7Ci0gICAgICBib2Zmc2V0PTA7IC8vIGFmdGVyIGZpcnN0Ci0gICAgfQotICAgIHJldHVybiAtMTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIGludGVybmFsIG1fbWFwMCBhcnJheQotICAgKiBAcmV0dXJuIHRoZSBtX21hcDAgYXJyYXkKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBpbnRbXSBnZXRNYXAwKCkKLSAgewotICAgIHJldHVybiBtX21hcDA7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBtX21hcCBkb3VibGUgYXJyYXkKLSAgICogQHJldHVybiB0aGUgaW50ZXJuYWwgbWFwIG9mIGFycmF5IG9mIGFycmF5cwotICAgKi8KLSAgcHVibGljIGZpbmFsIGludFtdW10gZ2V0TWFwKCkKLSAgewotICAgIHJldHVybiBtX21hcDsKLSAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9TeXN0ZW1JRFJlc29sdmVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9TeXN0ZW1JRFJlc29sdmVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDdiNmY1M2IuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvU3lzdGVtSURSZXNvbHZlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjk3ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFN5c3RlbUlEUmVzb2x2ZXIuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNSAwODoxNTo1OCBzdXJlc2hfZW1haWxpZCBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHM7Ci0KLWltcG9ydCBqYXZhLmlvLkZpbGU7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5VUkkuTWFsZm9ybWVkVVJJRXhjZXB0aW9uOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgaXMgdXNlZCB0byByZXNvbHZlIHJlbGF0aXZlIFVSSXMgYW5kIFN5c3RlbUlECi0gKiBzdHJpbmdzIGludG8gYWJzb2x1dGUgVVJJcy4KLSAqCi0gKiA8cD5UaGlzIGlzIGEgZ2VuZXJpYyB1dGlsaXR5IGZvciByZXNvbHZpbmcgVVJJcywgb3RoZXIgdGhhbiB0aGUKLSAqIGZhY3QgdGhhdCBpdCdzIGRlY2xhcmVkIHRvIHRocm93IFRyYW5zZm9ybWVyRXhjZXB0aW9uLiAgUGxlYXNlCi0gKiBzZWUgY29kZSBjb21tZW50cyBmb3IgZGV0YWlscyBvbiBob3cgcmVzb2x1dGlvbiBpcyBwZXJmb3JtZWQuPC9wPgotICogQHhzbC51c2FnZSBpbnRlcm5hbAotICovCi1wdWJsaWMgY2xhc3MgU3lzdGVtSURSZXNvbHZlcgotewotCi0gIC8qKgotICAgKiBHZXQgYW4gYWJzb2x1dGUgVVJJIGZyb20gYSBnaXZlbiByZWxhdGl2ZSBVUkkgKGxvY2FsIHBhdGgpLgotICAgKgotICAgKiA8cD5UaGUgcmVsYXRpdmUgVVJJIGlzIGEgbG9jYWwgZmlsZXN5c3RlbSBwYXRoLiBUaGUgcGF0aCBjYW4gYmUKLSAgICogYWJzb2x1dGUgb3IgcmVsYXRpdmUuIElmIGl0IGlzIGEgcmVsYXRpdmUgcGF0aCwgaXQgaXMgcmVzb2x2ZWQgcmVsYXRpdmUKLSAgICogdG8gdGhlIHN5c3RlbSBwcm9wZXJ0eSAidXNlci5kaXIiIGlmIGl0IGlzIGF2YWlsYWJsZTsgaWYgbm90IChpLmUuIGluIGFuCi0gICAqIEFwcGxldCBwZXJoYXBzIHdoaWNoIHRocm93cyBTZWN1cml0eUV4Y2VwdGlvbikgdGhlbiB3ZSBqdXN0IHJldHVybiB0aGUKLSAgICogcmVsYXRpdmUgcGF0aC4gVGhlIHNwYWNlIGFuZCBiYWNrc2xhc2ggY2hhcmFjdGVycyBhcmUgYWxzbyByZXBsYWNlZCB0bwotICAgKiBnZW5lcmF0ZSBhIGdvb2QgYWJzb2x1dGUgVVJJLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIGxvY2FsUGF0aCBUaGUgcmVsYXRpdmUgVVJJIHRvIHJlc29sdmUKLSAgICoKLSAgICogQHJldHVybiBSZXNvbHZlZCBhYnNvbHV0ZSBVUkkKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldEFic29sdXRlVVJJRnJvbVJlbGF0aXZlKFN0cmluZyBsb2NhbFBhdGgpCi0gIHsKLSAgICBpZiAobG9jYWxQYXRoID09IG51bGwgfHwgbG9jYWxQYXRoLmxlbmd0aCgpID09IDApCi0gICAgICByZXR1cm4gIiI7Ci0KLSAgICAvLyBJZiB0aGUgbG9jYWwgcGF0aCBpcyBhIHJlbGF0aXZlIHBhdGgsIHRoZW4gaXQgaXMgcmVzb2x2ZWQgYWdhaW5zdAotICAgIC8vIHRoZSAidXNlci5kaXIiIHN5c3RlbSBwcm9wZXJ0eS4KLSAgICBTdHJpbmcgYWJzb2x1dGVQYXRoID0gbG9jYWxQYXRoOwotICAgIGlmICghaXNBYnNvbHV0ZVBhdGgobG9jYWxQYXRoKSkKLSAgICB7Ci0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgYWJzb2x1dGVQYXRoID0gZ2V0QWJzb2x1dGVQYXRoRnJvbVJlbGF0aXZlUGF0aChsb2NhbFBhdGgpOwotICAgICAgfQotICAgICAgLy8gdXNlci5kaXIgbm90IGFjY2Vzc2libGUgZnJvbSBhcHBsZXQKLSAgICAgIGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBzZSkKLSAgICAgIHsKLSAgICAgICAgcmV0dXJuICJmaWxlOiIgKyBsb2NhbFBhdGg7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgU3RyaW5nIHVybFN0cmluZzsKLSAgICBpZiAobnVsbCAhPSBhYnNvbHV0ZVBhdGgpCi0gICAgewotICAgICAgaWYgKGFic29sdXRlUGF0aC5zdGFydHNXaXRoKEZpbGUuc2VwYXJhdG9yKSkKLSAgICAgICAgdXJsU3RyaW5nID0gImZpbGU6Ly8iICsgYWJzb2x1dGVQYXRoOwotICAgICAgZWxzZQotICAgICAgICB1cmxTdHJpbmcgPSAiZmlsZTovLy8iICsgYWJzb2x1dGVQYXRoOwotICAgIH0KLSAgICBlbHNlCi0gICAgICB1cmxTdHJpbmcgPSAiZmlsZToiICsgbG9jYWxQYXRoOwotCi0gICAgcmV0dXJuIHJlcGxhY2VDaGFycyh1cmxTdHJpbmcpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiBhbiBhYnNvbHV0ZSBwYXRoIGZyb20gYSByZWxhdGl2ZSBwYXRoLgotICAgKgotICAgKiBAcGFyYW0gcmVsYXRpdmVQYXRoIEEgcmVsYXRpdmUgcGF0aAotICAgKiBAcmV0dXJuIFRoZSBhYnNvbHV0ZSBwYXRoCi0gICAqLwotICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgZ2V0QWJzb2x1dGVQYXRoRnJvbVJlbGF0aXZlUGF0aChTdHJpbmcgcmVsYXRpdmVQYXRoKQotICB7Ci0gICAgcmV0dXJuIG5ldyBGaWxlKHJlbGF0aXZlUGF0aCkuZ2V0QWJzb2x1dGVQYXRoKCk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRydWUgaWYgdGhlIHN5c3RlbUlkIGRlbm90ZXMgYW4gYWJzb2x1dGUgVVJJIC4KLSAgICoKLSAgICogQHBhcmFtIHN5c3RlbUlkIFRoZSBzeXN0ZW1JZCBzdHJpbmcKLSAgICogQHJldHVybiB0cnVlIGlmIHRoZSBzeXN0ZW1JZCBpcyBhbiBhbiBhYnNvbHV0ZSBVUkkKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0Fic29sdXRlVVJJKFN0cmluZyBzeXN0ZW1JZCkKLSAgewotICAgICAvKiogaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjM5Ni50eHQKLSAgICAgICogICBBdXRob3JzIHNob3VsZCBiZSBhd2FyZSB0aGF0IGEgcGF0aCBzZWdtZW50IHdoaWNoIGNvbnRhaW5zIGEgY29sb24KLSAgICAgICogY2hhcmFjdGVyIGNhbm5vdCBiZSB1c2VkIGFzIHRoZSBmaXJzdCBzZWdtZW50IG9mIGEgcmVsYXRpdmUgVVJJIHBhdGgKLSAgICAgICogKGUuZy4sICJ0aGlzOnRoYXQiKSwgYmVjYXVzZSBpdCB3b3VsZCBiZSBtaXN0YWtlbiBmb3IgYSBzY2hlbWUgbmFtZS4KLSAgICAgKiovCi0gICAgIC8qKgotICAgICAgKiAlUkVWSUVXJSBDYW4gd2UgYXNzdW1lIGhlcmUgdGhhdCBzeXN0ZW1JZCBpcyBhIHZhbGlkIFVSST8KLSAgICAgICogSXQgbG9va3MgbGlrZSB3ZSBjYW5ub3QgKCBTZWUgZGlzY3Vzc2lvbiBvZiB0aGlzIGNvbW1vbiBwcm9ibGVtIGluCi0gICAgICAqIEJ1Z3ppbGxhIEJ1ZyAyMjc3NyApLgotICAgICAqKi8KLSAgICAgLy8iZml4IiBmb3IgQnVnemlsbGEgQnVnIDIyNzc3Ci0gICAgaWYoaXNXaW5kb3dzQWJzb2x1dGVQYXRoKHN5c3RlbUlkKSl7Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgfQotCi0gICAgZmluYWwgaW50IGZyYWdtZW50SW5kZXggPSBzeXN0ZW1JZC5pbmRleE9mKCcjJyk7Ci0gICAgZmluYWwgaW50IHF1ZXJ5SW5kZXggPSBzeXN0ZW1JZC5pbmRleE9mKCc/Jyk7Ci0gICAgZmluYWwgaW50IHNsYXNoSW5kZXggPSBzeXN0ZW1JZC5pbmRleE9mKCcvJyk7Ci0gICAgZmluYWwgaW50IGNvbG9uSW5kZXggPSBzeXN0ZW1JZC5pbmRleE9mKCc6Jyk7Ci0KLSAgICAvL2ZpbmRpbmcgc3Vic3RyaW5nICBiZWZvcmUgJyMnLCAnPycsIGFuZCAnLycKLSAgICBpbnQgaW5kZXggPSBzeXN0ZW1JZC5sZW5ndGgoKSAtMTsKLSAgICBpZihmcmFnbWVudEluZGV4ID4gMCkKLSAgICAgICAgaW5kZXggPSBmcmFnbWVudEluZGV4OwotICAgIGlmKChxdWVyeUluZGV4ID4gMCkgJiYgKHF1ZXJ5SW5kZXggPGluZGV4KSkKLSAgICAgICAgaW5kZXggPSBxdWVyeUluZGV4OwotICAgIGlmKChzbGFzaEluZGV4ID4gMCkgJiYgKHNsYXNoSW5kZXggPGluZGV4KSkKLSAgICAgICAgaW5kZXggPSBzbGFzaEluZGV4OwotICAgIC8vIHJldHVybiB0cnVlIGlmIHRoZXJlIGlzICc6JyBiZWZvcmUgJyMnLCAnPycsIGFuZCAnLycKLSAgICByZXR1cm4gKChjb2xvbkluZGV4ID4wKSAmJiAoY29sb25JbmRleDxpbmRleCkpOwotCi0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRydWUgaWYgdGhlIGxvY2FsIHBhdGggaXMgYW4gYWJzb2x1dGUgcGF0aC4KLSAgICoKLSAgICogQHBhcmFtIHN5c3RlbUlkIFRoZSBwYXRoIHN0cmluZwotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHBhdGggaXMgYWJzb2x1dGUKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0Fic29sdXRlUGF0aChTdHJpbmcgc3lzdGVtSWQpCi0gIHsKLSAgICBpZihzeXN0ZW1JZCA9PSBudWxsKQotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgZmluYWwgRmlsZSBmaWxlID0gbmV3IEZpbGUoc3lzdGVtSWQpOwotICAgIHJldHVybiBmaWxlLmlzQWJzb2x1dGUoKTsKLQotICB9Ci0KLSAgIC8qKgotICAgKiBSZXR1cm4gdHJ1ZSBpZiB0aGUgbG9jYWwgcGF0aCBpcyBhIFdpbmRvd3MgYWJzb2x1dGUgcGF0aC4KLSAgICoKLSAgICogQHBhcmFtIHN5c3RlbUlkIFRoZSBwYXRoIHN0cmluZwotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHBhdGggaXMgYSBXaW5kb3dzIGFic29sdXRlIHBhdGgKLSAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBpc1dpbmRvd3NBYnNvbHV0ZVBhdGgoU3RyaW5nIHN5c3RlbUlkKQotICB7Ci0gICAgaWYoIWlzQWJzb2x1dGVQYXRoKHN5c3RlbUlkKSkKLSAgICAgIHJldHVybiBmYWxzZTsKLSAgICAvLyBPbiBXaW5kb3dzLCBhbiBhYnNvbHV0ZSBwYXRoIHN0YXJ0cyB3aXRoICJbZHJpdmVfbGV0dGVyXTpcIi4KLSAgICBpZiAoc3lzdGVtSWQubGVuZ3RoKCkgPiAyCi0gICAgICAgICYmIHN5c3RlbUlkLmNoYXJBdCgxKSA9PSAnOicKLSAgICAgICAgJiYgQ2hhcmFjdGVyLmlzTGV0dGVyKHN5c3RlbUlkLmNoYXJBdCgwKSkKLSAgICAgICAgJiYgKHN5c3RlbUlkLmNoYXJBdCgyKSA9PSAnXFwnIHx8IHN5c3RlbUlkLmNoYXJBdCgyKSA9PSAnLycpKQotICAgICAgcmV0dXJuIHRydWU7Ci0gICAgZWxzZQotICAgICAgcmV0dXJuIGZhbHNlOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlcGxhY2Ugc3BhY2VzIHdpdGggIiUyMCIgYW5kIGJhY2tzbGFzaGVzIHdpdGggZm9yd2FyZCBzbGFzaGVzIGluCi0gICAqIHRoZSBpbnB1dCBzdHJpbmcgdG8gZ2VuZXJhdGUgYSB3ZWxsLWZvcm1lZCBVUkkgc3RyaW5nLgotICAgKgotICAgKiBAcGFyYW0gc3RyIFRoZSBpbnB1dCBzdHJpbmcKLSAgICogQHJldHVybiBUaGUgc3RyaW5nIGFmdGVyIGNvbnZlcnNpb24KLSAgICovCi0gIHByaXZhdGUgc3RhdGljIFN0cmluZyByZXBsYWNlQ2hhcnMoU3RyaW5nIHN0cikKLSAgewotICAgIFN0cmluZ0J1ZmZlciBidWYgPSBuZXcgU3RyaW5nQnVmZmVyKHN0cik7Ci0gICAgaW50IGxlbmd0aCA9IGJ1Zi5sZW5ndGgoKTsKLSAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKQotICAgIHsKLSAgICAgIGNoYXIgY3VycmVudENoYXIgPSBidWYuY2hhckF0KGkpOwotICAgICAgLy8gUmVwbGFjZSBzcGFjZSB3aXRoICIlMjAiCi0gICAgICBpZiAoY3VycmVudENoYXIgPT0gJyAnKQotICAgICAgewotICAgICAgICBidWYuc2V0Q2hhckF0KGksICclJyk7Ci0gICAgICAgIGJ1Zi5pbnNlcnQoaSsxLCAiMjAiKTsKLSAgICAgICAgbGVuZ3RoID0gbGVuZ3RoICsgMjsKLSAgICAgICAgaSA9IGkgKyAyOwotICAgICAgfQotICAgICAgLy8gUmVwbGFjZSBiYWNrc2xhc2ggd2l0aCBmb3J3YXJkIHNsYXNoCi0gICAgICBlbHNlIGlmIChjdXJyZW50Q2hhciA9PSAnXFwnKQotICAgICAgewotICAgICAgICBidWYuc2V0Q2hhckF0KGksICcvJyk7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgcmV0dXJuIGJ1Zi50b1N0cmluZygpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRha2UgYSBTeXN0ZW1JRCBzdHJpbmcgYW5kIHRyeSB0byB0dXJuIGl0IGludG8gYSBnb29kIGFic29sdXRlIFVSSS4KLSAgICoKLSAgICogQHBhcmFtIHN5c3RlbUlkIEEgVVJJIHN0cmluZywgd2hpY2ggbWF5IGJlIGFic29sdXRlIG9yIHJlbGF0aXZlLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSByZXNvbHZlZCBhYnNvbHV0ZSBVUkkKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldEFic29sdXRlVVJJKFN0cmluZyBzeXN0ZW1JZCkKLSAgewotICAgIFN0cmluZyBhYnNvbHV0ZVVSSSA9IHN5c3RlbUlkOwotICAgIGlmIChpc0Fic29sdXRlVVJJKHN5c3RlbUlkKSkKLSAgICB7Ci0gICAgICAvLyBPbmx5IHByb2Nlc3MgdGhlIHN5c3RlbUlkIGlmIGl0IHN0YXJ0cyB3aXRoICJmaWxlOiIuCi0gICAgICBpZiAoc3lzdGVtSWQuc3RhcnRzV2l0aCgiZmlsZToiKSkKLSAgICAgIHsKLSAgICAgICAgU3RyaW5nIHN0ciA9IHN5c3RlbUlkLnN1YnN0cmluZyg1KTsKLQotICAgICAgICAvLyBSZXNvbHZlIHRoZSBhYnNvbHV0ZSBwYXRoIGlmIHRoZSBzeXN0ZW1JZCBzdGFydHMgd2l0aCAiZmlsZTovLy8iCi0gICAgICAgIC8vIG9yICJmaWxlOi8iLiBEb24ndCBkbyBhbnl0aGluZyBpZiBpdCBvbmx5IHN0YXJ0cyB3aXRoICJmaWxlOi8vIi4KLSAgICAgICAgaWYgKHN0ciAhPSBudWxsICYmIHN0ci5zdGFydHNXaXRoKCIvIikpCi0gICAgICAgIHsKLSAgICAgICAgICBpZiAoc3RyLnN0YXJ0c1dpdGgoIi8vLyIpIHx8ICFzdHIuc3RhcnRzV2l0aCgiLy8iKSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICAvLyBBIFdpbmRvd3MgcGF0aCBjb250YWluaW5nIGEgZHJpdmUgbGV0dGVyIGNhbiBiZSByZWxhdGl2ZS4KLSAgICAgICAgICAgIC8vIEEgVW5peCBwYXRoIHN0YXJ0aW5nIHdpdGggImZpbGU6LyIgaXMgYWx3YXlzIGFic29sdXRlLgotICAgICAgICAgICAgaW50IHNlY29uZENvbG9uSW5kZXggPSBzeXN0ZW1JZC5pbmRleE9mKCc6JywgNSk7Ci0gICAgICAgICAgICBpZiAoc2Vjb25kQ29sb25JbmRleCA+IDApCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIFN0cmluZyBsb2NhbFBhdGggPSBzeXN0ZW1JZC5zdWJzdHJpbmcoc2Vjb25kQ29sb25JbmRleC0xKTsKLSAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICBpZiAoIWlzQWJzb2x1dGVQYXRoKGxvY2FsUGF0aCkpCi0gICAgICAgICAgICAgICAgICBhYnNvbHV0ZVVSSSA9IHN5c3RlbUlkLnN1YnN0cmluZygwLCBzZWNvbmRDb2xvbkluZGV4LTEpICsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0QWJzb2x1dGVQYXRoRnJvbVJlbGF0aXZlUGF0aChsb2NhbFBhdGgpOwotICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgIGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBzZSkgewotICAgICAgICAgICAgICAgIHJldHVybiBzeXN0ZW1JZDsKLSAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgIHsKLSAgICAgICAgICByZXR1cm4gZ2V0QWJzb2x1dGVVUklGcm9tUmVsYXRpdmUoc3lzdGVtSWQuc3Vic3RyaW5nKDUpKTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiByZXBsYWNlQ2hhcnMoYWJzb2x1dGVVUkkpOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgICByZXR1cm4gc3lzdGVtSWQ7Ci0gICAgfQotICAgIGVsc2UKLSAgICAgIHJldHVybiBnZXRBYnNvbHV0ZVVSSUZyb21SZWxhdGl2ZShzeXN0ZW1JZCk7Ci0KLSAgfQotCi0KLSAgLyoqCi0gICAqIFRha2UgYSBTeXN0ZW1JRCBzdHJpbmcgYW5kIHRyeSB0byB0dXJuIGl0IGludG8gYSBnb29kIGFic29sdXRlIFVSSS4KLSAgICoKLSAgICogQHBhcmFtIHVybFN0cmluZyBTeXN0ZW1JRCBzdHJpbmcKLSAgICogQHBhcmFtIGJhc2UgVGhlIFVSSSBzdHJpbmcgdXNlZCBhcyB0aGUgYmFzZSBmb3IgcmVzb2x2aW5nIHRoZSBzeXN0ZW1JRAotICAgKgotICAgKiBAcmV0dXJuIFRoZSByZXNvbHZlZCBhYnNvbHV0ZSBVUkkKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiB0aHJvd24gaWYgdGhlIHN0cmluZyBjYW4ndCBiZSB0dXJuZWQgaW50byBhIFVSSS4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldEFic29sdXRlVVJJKFN0cmluZyB1cmxTdHJpbmcsIFN0cmluZyBiYXNlKQotICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgaWYgKGJhc2UgPT0gbnVsbCkKLSAgICAgIHJldHVybiBnZXRBYnNvbHV0ZVVSSSh1cmxTdHJpbmcpOwotCi0gICAgU3RyaW5nIGFic29sdXRlQmFzZSA9IGdldEFic29sdXRlVVJJKGJhc2UpOwotICAgIFVSSSB1cmkgPSBudWxsOwotICAgIHRyeQotICAgIHsKLSAgICAgIFVSSSBiYXNlVVJJID0gbmV3IFVSSShhYnNvbHV0ZUJhc2UpOwotICAgICAgdXJpID0gbmV3IFVSSShiYXNlVVJJLCB1cmxTdHJpbmcpOwotICAgIH0KLSAgICBjYXRjaCAoTWFsZm9ybWVkVVJJRXhjZXB0aW9uIG11ZSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24obXVlKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gcmVwbGFjZUNoYXJzKHVyaS50b1N0cmluZygpKTsKLSAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9UaHJlYWRDb250cm9sbGVyV3JhcHBlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvVGhyZWFkQ29udHJvbGxlcldyYXBwZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMmRjODc4Mi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9UaHJlYWRDb250cm9sbGVyV3JhcHBlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTI2ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFRocmVhZENvbnRyb2xsZXJXcmFwcGVyLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTUgMDg6MTU6NTkgc3VyZXNoX2VtYWlsaWQgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzOwotCi0vKioKLSAqIEEgdXRpbGl0eSBjbGFzcyB0aGF0IHdyYXBzIHRoZSBUaHJlYWRDb250cm9sbGVyLCB3aGljaCBpcyB1c2VkCi0gKiBieSBJbmNyZW1lbnRhbFNBWFNvdXJjZSBmb3IgdGhlIGluY3JlbWVudGFsIGJ1aWxkaW5nIG9mIERUTS4KLSAqLwotcHVibGljIGNsYXNzIFRocmVhZENvbnRyb2xsZXJXcmFwcGVyCi17Ci0KLSAgLyoqIFRoZSBUaHJlYWRDb250cm9sbGVyIHBvb2wgICAqLwotICBwcml2YXRlIHN0YXRpYyBUaHJlYWRDb250cm9sbGVyIG1fdHBvb2wgPSBuZXcgVGhyZWFkQ29udHJvbGxlcigpOwotCi0gIHB1YmxpYyBzdGF0aWMgVGhyZWFkIHJ1blRocmVhZChSdW5uYWJsZSBydW5uYWJsZSwgaW50IHByaW9yaXR5KQotICB7Ci0gICAgcmV0dXJuIG1fdHBvb2wucnVuKHJ1bm5hYmxlLCBwcmlvcml0eSk7Ci0gIH0KLQotICBwdWJsaWMgc3RhdGljIHZvaWQgd2FpdFRocmVhZChUaHJlYWQgd29ya2VyLCBSdW5uYWJsZSB0YXNrKQotICAgIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbgotICB7Ci0gICAgbV90cG9vbC53YWl0VGhyZWFkKHdvcmtlciwgdGFzayk7Ci0gIH0KLQotICAvKioKLSAgICogVGhyZWFkIGNvbnRyb2xsZXIgdXRpbGl0eSBjbGFzcyBmb3IgaW5jcmVtZW50YWwgU0FYIHNvdXJjZS4gTXVzdAotICAgKiBiZSBvdmVycmlkZW4gd2l0aCBhIGRlcml2ZWQgY2xhc3MgdG8gc3VwcG9ydCB0aHJlYWQgcG9vbGluZy4KLSAgICoKLSAgICogQWxsIHRocmVhZC1yZWxhdGVkIHN0dWZmIGlzIGluIHRoaXMgY2xhc3MuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGNsYXNzIFRocmVhZENvbnRyb2xsZXIKLSAgewotCi0gICAgLyoqCi0gICAgICogVGhpcyBjbGFzcyB3YXMgaW50cm9kdWNlZCBhcyBhIGZpeCBmb3IgQ1IgNjYwNzMzOS4KLSAgICAgKi8KLSAgICBmaW5hbCBjbGFzcyBTYWZlVGhyZWFkIGV4dGVuZHMgVGhyZWFkIHsKLSAgICAgICAgIHByaXZhdGUgdm9sYXRpbGUgYm9vbGVhbiByYW4gPSBmYWxzZTsKLQotICAgICAgICAgcHVibGljIFNhZmVUaHJlYWQoUnVubmFibGUgdGFyZ2V0KSB7Ci0gICAgICAgICAgICAgc3VwZXIodGFyZ2V0KTsKLSAgICAgICAgIH0KLQotICAgICAgICAgcHVibGljIGZpbmFsIHZvaWQgcnVuKCkgewotICAgICAgICAgICAgIGlmIChUaHJlYWQuY3VycmVudFRocmVhZCgpICE9IHRoaXMpIHsKLSAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiVGhlIHJ1bigpIG1ldGhvZCBpbiBhIgotICAgICAgICAgICAgICAgICAgICAgKyAiIFNhZmVUaHJlYWQgY2Fubm90IGJlIGNhbGxlZCBmcm9tIGFub3RoZXIgdGhyZWFkLiIpOwotICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKHRoaXMpIHsKLSAgICAgICAgICAgICAgICBpZiAoIXJhbikgewotICAgICAgICAgICAgICAgICAgICByYW4gPSB0cnVlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiVGhlIHJ1bigpIG1ldGhvZCBpbiBhIgotICAgICAgICAgICAgICAgICAgICAgKyAiIFNhZmVUaHJlYWQgY2Fubm90IGJlIGNhbGxlZCBtb3JlIHRoYW4gb25jZS4iKTsKLSAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICBzdXBlci5ydW4oKTsKLSAgICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBXaWxsIGdldCBhIHRocmVhZCBmcm9tIHRoZSBwb29sLCBleGVjdXRlIHRoZSB0YXNrCi0gICAgICogIGFuZCByZXR1cm4gdGhlIHRocmVhZCB0byB0aGUgcG9vbC4KLSAgICAgKgotICAgICAqICBUaGUgcmV0dXJuIHZhbHVlIGlzIHVzZWQgb25seSB0byB3YWl0IGZvciBjb21wbGV0aW9uCi0gICAgICoKLSAgICAgKgotICAgICAqIE5FRURTRE9DIEBwYXJhbSB0YXNrCi0gICAgICogQHBhcmFtIHByaW9yaXR5IGlmID4wIHRoZSB0YXNrIHdpbGwgcnVuIHdpdGggdGhlIGdpdmVuIHByaW9yaXR5Ci0gICAgICogICggZG9lc24ndCBzZWVtIHRvIGJlIHVzZWQgaW4geGFsYW4sIHNpbmNlIGl0J3MgYWxsd2F5cyB0aGUgZGVmYXVsdCApCi0gICAgICogQHJldHVybiAgVGhlIHRocmVhZCB0aGF0IGlzIHJ1bm5pbmcgdGhlIHRhc2ssIGNhbiBiZSB1c2VkCi0gICAgICogICAgICAgICAgdG8gd2FpdCBmb3IgY29tcGxldGlvbgotICAgICAqLwotICAgIHB1YmxpYyBUaHJlYWQgcnVuKFJ1bm5hYmxlIHRhc2ssIGludCBwcmlvcml0eSkKLSAgICB7Ci0KLSAgICAgIFRocmVhZCB0ID0gbmV3IFNhZmVUaHJlYWQodGFzayk7Ci0KLSAgICAgIHQuc3RhcnQoKTsKLQotICAgICAgLy8gICAgICAgaWYoIHByaW9yaXR5ID4gMCApCi0gICAgICAvLyAgICAgIHQuc2V0UHJpb3JpdHkoIHByaW9yaXR5ICk7Ci0gICAgICByZXR1cm4gdDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiAgV2FpdCB1bnRpbCB0aGUgdGFzayBpcyBjb21wbGV0ZWQgb24gdGhlIHdvcmtlcgotICAgICAqICB0aHJlYWQuCi0gICAgICoKLSAgICAgKiBORUVEU0RPQyBAcGFyYW0gd29ya2VyCi0gICAgICogTkVFRFNET0MgQHBhcmFtIHRhc2sKLSAgICAgKgotICAgICAqIEB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB3YWl0VGhyZWFkKFRocmVhZCB3b3JrZXIsIFJ1bm5hYmxlIHRhc2spCi0gICAgICAgICAgICB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24KLSAgICB7Ci0KLSAgICAgIC8vIFRoaXMgc2hvdWxkIHdhaXQgdW50aWwgdGhlIHRyYW5zZm9ybVRocmVhZCBpcyBjb25zaWRlcmVkIG5vdCBhbGl2ZS4KLSAgICAgIHdvcmtlci5qb2luKCk7Ci0gICAgfQotICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL1RyZWVXYWxrZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL1RyZWVXYWxrZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDk5NDZmMy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9UcmVlV2Fsa2VyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0ODkgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAxNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqLwotLyoKLSAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQotICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCi0gKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCi0gKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAotICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKLSAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwudXRpbHMuU2VjdXJpdHlTdXBwb3J0OwotaW1wb3J0IGphdmEuaW8uRmlsZTsKLQotaW1wb3J0IG9yZy53M2MuZG9tLkNvbW1lbnQ7Ci1pbXBvcnQgb3JnLnczYy5kb20uRWxlbWVudDsKLWltcG9ydCBvcmcudzNjLmRvbS5FbnRpdHlSZWZlcmVuY2U7Ci1pbXBvcnQgb3JnLnczYy5kb20uTmFtZWROb2RlTWFwOwotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci1pbXBvcnQgb3JnLnczYy5kb20uUHJvY2Vzc2luZ0luc3RydWN0aW9uOwotaW1wb3J0IG9yZy53M2MuZG9tLlRleHQ7Ci0KLWltcG9ydCBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5Mb2NhdG9yOwotaW1wb3J0IG9yZy54bWwuc2F4LmV4dC5MZXhpY2FsSGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5oZWxwZXJzLkxvY2F0b3JJbXBsOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgZG9lcyBhIHByZS1vcmRlciB3YWxrIG9mIHRoZSBET00gdHJlZSwgY2FsbGluZyBhIENvbnRlbnRIYW5kbGVyCi0gKiBpbnRlcmZhY2UgYXMgaXQgZ29lcy4KLSAqIEB4c2wudXNhZ2UgYWR2YW5jZWQKLSAqLwotCi1wdWJsaWMgY2xhc3MgVHJlZVdhbGtlcgotewotCi0gIC8qKiBMb2NhbCByZWZlcmVuY2UgdG8gYSBDb250ZW50SGFuZGxlciAgICAgICAgICAqLwotICBwcml2YXRlIENvbnRlbnRIYW5kbGVyIG1fY29udGVudEhhbmRsZXIgPSBudWxsOwotCi0gIC8vIEFSR0hIISEgIEpBWFAgVXNlcyBYZXJjZXMgd2l0aG91dCBzZXR0aW5nIHRoZSBuYW1lc3BhY2UgcHJvY2Vzc2luZyB0byBPTiEKLSAgLy8gRE9NMkhlbHBlciBtX2RoID0gbmV3IERPTTJIZWxwZXIoKTsKLQotICAvKiogRG9tSGVscGVyIGZvciB0aGlzIFRyZWVXYWxrZXIgICAgICAgICAgKi8KLSAgcHJvdGVjdGVkIERPTUhlbHBlciBtX2RoOwotCi0gICAgICAgIC8qKiBMb2NhdG9yIG9iamVjdCBmb3IgdGhpcyBUcmVlV2Fsa2VyICAgICAgICAgICovCi0gICAgICAgIHByaXZhdGUgTG9jYXRvckltcGwgbV9sb2NhdG9yID0gbmV3IExvY2F0b3JJbXBsKCk7Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgQ29udGVudEhhbmRsZXIgdXNlZCBmb3IgdGhlIHRyZWUgd2Fsay4KLSAgICoKLSAgICogQHJldHVybiB0aGUgQ29udGVudEhhbmRsZXIgdXNlZCBmb3IgdGhlIHRyZWUgd2FsawotICAgKi8KLSAgcHVibGljIENvbnRlbnRIYW5kbGVyIGdldENvbnRlbnRIYW5kbGVyKCkKLSAgewotICAgIHJldHVybiBtX2NvbnRlbnRIYW5kbGVyOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgQ29udGVudEhhbmRsZXIgdXNlZCBmb3IgdGhlIHRyZWUgd2Fsay4KLSAgICoKLSAgICogQHJldHVybiB0aGUgQ29udGVudEhhbmRsZXIgdXNlZCBmb3IgdGhlIHRyZWUgd2FsawotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0Q29udGVudEhhbmRsZXIoQ29udGVudEhhbmRsZXIgY2gpCi0gIHsKLSAgICBtX2NvbnRlbnRIYW5kbGVyID0gY2g7Ci0gIH0KLQotICAgICAgICAvKioKLSAgICogQ29uc3RydWN0b3IuCi0gICAqIEBwYXJhbSAgIGNvbnRlbnRIYW5kbGVyIFRoZSBpbXBsZW1lbnRhdGlvbiBvZiB0aGUKLSAgICogQHBhcmFtICAgc3lzdGVtSWQgU3lzdGVtIGlkZW50aWZpZXIgZm9yIHRoZSBkb2N1bWVudC4KLSAgICogY29udGVudEhhbmRsZXIgb3BlcmF0aW9uICh0b1hNTFN0cmluZywgZGlnZXN0LCAuLi4pCi0gICAqLwotICBwdWJsaWMgVHJlZVdhbGtlcihDb250ZW50SGFuZGxlciBjb250ZW50SGFuZGxlciwgRE9NSGVscGVyIGRoLCBTdHJpbmcgc3lzdGVtSWQpCi0gIHsKLSAgICB0aGlzLm1fY29udGVudEhhbmRsZXIgPSBjb250ZW50SGFuZGxlcjsKLSAgICBtX2NvbnRlbnRIYW5kbGVyLnNldERvY3VtZW50TG9jYXRvcihtX2xvY2F0b3IpOwotICAgIGlmIChzeXN0ZW1JZCAhPSBudWxsKSB7Ci0gICAgICAgIG1fbG9jYXRvci5zZXRTeXN0ZW1JZChzeXN0ZW1JZCk7Ci0gICAgfQotICAgIG1fZGggPSBkaDsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3Rvci4KLSAgICogQHBhcmFtICAgY29udGVudEhhbmRsZXIgVGhlIGltcGxlbWVudGlvbiBvZiB0aGUKLSAgICogY29udGVudEhhbmRsZXIgb3BlcmF0aW9uICh0b1hNTFN0cmluZywgZGlnZXN0LCAuLi4pCi0gICAqLwotICBwdWJsaWMgVHJlZVdhbGtlcihDb250ZW50SGFuZGxlciBjb250ZW50SGFuZGxlciwgRE9NSGVscGVyIGRoKQotICB7Ci0gICAgdGhpcy5tX2NvbnRlbnRIYW5kbGVyID0gY29udGVudEhhbmRsZXI7Ci0gICAgbV9jb250ZW50SGFuZGxlci5zZXREb2N1bWVudExvY2F0b3IobV9sb2NhdG9yKTsKLSAgICBtX2RoID0gZGg7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0b3IuCi0gICAqIEBwYXJhbSAgIGNvbnRlbnRIYW5kbGVyIFRoZSBpbXBsZW1lbnRhdGlvbiBvZiB0aGUKLSAgICogY29udGVudEhhbmRsZXIgb3BlcmF0aW9uICh0b1hNTFN0cmluZywgZGlnZXN0LCAuLi4pCi0gICAqLwotICBwdWJsaWMgVHJlZVdhbGtlcihDb250ZW50SGFuZGxlciBjb250ZW50SGFuZGxlcikKLSAgewotICAgIHRoaXMubV9jb250ZW50SGFuZGxlciA9IGNvbnRlbnRIYW5kbGVyOwotICAgIGlmIChtX2NvbnRlbnRIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgbV9jb250ZW50SGFuZGxlci5zZXREb2N1bWVudExvY2F0b3IobV9sb2NhdG9yKTsKLSAgICB9Ci0gICAgbV9kaCA9IG5ldyBET00ySGVscGVyKCk7Ci0gIH0KLQotICAvKioKLSAgICogUGVyZm9ybSBhIHByZS1vcmRlciB0cmF2ZXJzYWwgbm9uLXJlY3Vyc2l2ZSBzdHlsZS4KLSAgICoKLSAgICogTm90ZSB0aGF0IFRyZWVXYWxrZXIgYXNzdW1lcyB0aGF0IHRoZSBzdWJ0cmVlIGlzIGludGVuZGVkIHRvIHJlcHJlc2VudAotICAgKiBhIGNvbXBsZXRlICh0aG91Z2ggbm90IG5lY2Vzc2FyaWx5IHdlbGwtZm9ybWVkKSBkb2N1bWVudCBhbmQsIGR1cmluZyBhCi0gICAqIHRyYXZlcnNhbCwgc3RhcnREb2N1bWVudCBhbmQgZW5kRG9jdW1lbnQgd2lsbCBhbHdheXMgYmUgaXNzdWVkIHRvIHRoZQotICAgKiBTQVggbGlzdGVuZXIuCi0gICAqCi0gICAqIEBwYXJhbSBwb3MgTm9kZSBpbiB0aGUgdHJlZSB3aGVyZSB0byBzdGFydCB0cmF2ZXJzYWwKLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgdHJhdmVyc2UoTm9kZSBwb3MpIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgICAgICB0aGlzLm1fY29udGVudEhhbmRsZXIuc3RhcnREb2N1bWVudCgpOwotCi0gICAgICAgIHRyYXZlcnNlRnJhZ21lbnQocG9zKTsKLQotICAgICAgICB0aGlzLm1fY29udGVudEhhbmRsZXIuZW5kRG9jdW1lbnQoKTsKLSAgfQotCi0gIC8qKgotICAgKiBQZXJmb3JtIGEgcHJlLW9yZGVyIHRyYXZlcnNhbCBub24tcmVjdXJzaXZlIHN0eWxlLgotICAgKgotICAgKiBJbiBjb250cmFzdCB0byB0aGUgdHJhdmVyc2UoKSBtZXRob2QgdGhpcyBtZXRob2Qgd2lsbCBub3QgaXNzdWUKLSAgICogc3RhcnREb2N1bWVudCgpIGFuZCBlbmREb2N1bWVudCgpIGV2ZW50cyB0byB0aGUgU0FYIGxpc3RlbmVyLgotICAgKgotICAgKiBAcGFyYW0gcG9zIE5vZGUgaW4gdGhlIHRyZWUgd2hlcmUgdG8gc3RhcnQgdHJhdmVyc2FsCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHRyYXZlcnNlRnJhZ21lbnQoTm9kZSBwb3MpIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIE5vZGUgdG9wID0gcG9zOwotCi0gICAgd2hpbGUgKG51bGwgIT0gcG9zKQotICAgIHsKLSAgICAgIHN0YXJ0Tm9kZShwb3MpOwotCi0gICAgICBOb2RlIG5leHROb2RlID0gcG9zLmdldEZpcnN0Q2hpbGQoKTsKLQotICAgICAgd2hpbGUgKG51bGwgPT0gbmV4dE5vZGUpCi0gICAgICB7Ci0gICAgICAgIGVuZE5vZGUocG9zKTsKLQotICAgICAgICBpZiAodG9wLmVxdWFscyhwb3MpKQotICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgIG5leHROb2RlID0gcG9zLmdldE5leHRTaWJsaW5nKCk7Ci0KLSAgICAgICAgaWYgKG51bGwgPT0gbmV4dE5vZGUpCi0gICAgICAgIHsKLSAgICAgICAgICBwb3MgPSBwb3MuZ2V0UGFyZW50Tm9kZSgpOwotCi0gICAgICAgICAgaWYgKChudWxsID09IHBvcykgfHwgKHRvcC5lcXVhbHMocG9zKSkpCi0gICAgICAgICAgewotICAgICAgICAgICAgaWYgKG51bGwgIT0gcG9zKQotICAgICAgICAgICAgICBlbmROb2RlKHBvcyk7Ci0KLSAgICAgICAgICAgIG5leHROb2RlID0gbnVsbDsKLQotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICB9Ci0KLSAgICAgIHBvcyA9IG5leHROb2RlOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBQZXJmb3JtIGEgcHJlLW9yZGVyIHRyYXZlcnNhbCBub24tcmVjdXJzaXZlIHN0eWxlLgotCi0gICAqIE5vdGUgdGhhdCBUcmVlV2Fsa2VyIGFzc3VtZXMgdGhhdCB0aGUgc3VidHJlZSBpcyBpbnRlbmRlZCB0byByZXByZXNlbnQKLSAgICogYSBjb21wbGV0ZSAodGhvdWdoIG5vdCBuZWNlc3NhcmlseSB3ZWxsLWZvcm1lZCkgZG9jdW1lbnQgYW5kLCBkdXJpbmcgYQotICAgKiB0cmF2ZXJzYWwsIHN0YXJ0RG9jdW1lbnQgYW5kIGVuZERvY3VtZW50IHdpbGwgYWx3YXlzIGJlIGlzc3VlZCB0byB0aGUKLSAgICogU0FYIGxpc3RlbmVyLgotICAgKgotICAgKiBAcGFyYW0gcG9zIE5vZGUgaW4gdGhlIHRyZWUgd2hlcmUgdG8gc3RhcnQgdHJhdmVyc2FsCi0gICAqIEBwYXJhbSB0b3AgTm9kZSBpbiB0aGUgdHJlZSB3aGVyZSB0byBlbmQgdHJhdmVyc2FsCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHRyYXZlcnNlKE5vZGUgcG9zLCBOb2RlIHRvcCkgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICAgICAgdGhpcy5tX2NvbnRlbnRIYW5kbGVyLnN0YXJ0RG9jdW1lbnQoKTsKLQotICAgIHdoaWxlIChudWxsICE9IHBvcykKLSAgICB7Ci0gICAgICBzdGFydE5vZGUocG9zKTsKLQotICAgICAgTm9kZSBuZXh0Tm9kZSA9IHBvcy5nZXRGaXJzdENoaWxkKCk7Ci0KLSAgICAgIHdoaWxlIChudWxsID09IG5leHROb2RlKQotICAgICAgewotICAgICAgICBlbmROb2RlKHBvcyk7Ci0KLSAgICAgICAgaWYgKChudWxsICE9IHRvcCkgJiYgdG9wLmVxdWFscyhwb3MpKQotICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgIG5leHROb2RlID0gcG9zLmdldE5leHRTaWJsaW5nKCk7Ci0KLSAgICAgICAgaWYgKG51bGwgPT0gbmV4dE5vZGUpCi0gICAgICAgIHsKLSAgICAgICAgICBwb3MgPSBwb3MuZ2V0UGFyZW50Tm9kZSgpOwotCi0gICAgICAgICAgaWYgKChudWxsID09IHBvcykgfHwgKChudWxsICE9IHRvcCkgJiYgdG9wLmVxdWFscyhwb3MpKSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBuZXh0Tm9kZSA9IG51bGw7Ci0KLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgfQotCi0gICAgICBwb3MgPSBuZXh0Tm9kZTsKLSAgICB9Ci0gICAgdGhpcy5tX2NvbnRlbnRIYW5kbGVyLmVuZERvY3VtZW50KCk7Ci0gIH0KLQotICAvKiogRmxhZyBpbmRpY2F0aW5nIHdoZXRoZXIgZm9sbG93aW5nIHRleHQgdG8gYmUgcHJvY2Vzc2VkIGlzIHJhdyB0ZXh0ICAgICAgICAgICovCi0gIGJvb2xlYW4gbmV4dElzUmF3ID0gZmFsc2U7Ci0KLSAgLyoqCi0gICAqIE9wdGltaXplZCBkaXNwYXRjaCBvZiBjaGFyYWN0ZXJzLgotICAgKi8KLSAgcHJpdmF0ZSBmaW5hbCB2b2lkIGRpc3BhdGFjaENoYXJzKE5vZGUgbm9kZSkKLSAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgaWYobV9jb250ZW50SGFuZGxlciBpbnN0YW5jZW9mIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLnJlZi5kb20yZHRtLkRPTTJEVE0uQ2hhcmFjdGVyTm9kZUhhbmRsZXIpCi0gICAgewotICAgICAgKChjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5yZWYuZG9tMmR0bS5ET00yRFRNLkNoYXJhY3Rlck5vZGVIYW5kbGVyKW1fY29udGVudEhhbmRsZXIpLmNoYXJhY3RlcnMobm9kZSk7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBTdHJpbmcgZGF0YSA9ICgoVGV4dCkgbm9kZSkuZ2V0RGF0YSgpOwotICAgICAgdGhpcy5tX2NvbnRlbnRIYW5kbGVyLmNoYXJhY3RlcnMoZGF0YS50b0NoYXJBcnJheSgpLCAwLCBkYXRhLmxlbmd0aCgpKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogU3RhcnQgcHJvY2Vzc2luZyBnaXZlbiBub2RlCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBub2RlIE5vZGUgdG8gcHJvY2VzcwotICAgKgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgc3RhcnROb2RlKE5vZGUgbm9kZSkgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAobV9jb250ZW50SGFuZGxlciBpbnN0YW5jZW9mIE5vZGVDb25zdW1lcikKLSAgICB7Ci0gICAgICAoKE5vZGVDb25zdW1lcikgbV9jb250ZW50SGFuZGxlcikuc2V0T3JpZ2luYXRpbmdOb2RlKG5vZGUpOwotICAgIH0KLQotICAgICAgICAgICAgICAgIGlmIChub2RlIGluc3RhbmNlb2YgTG9jYXRvcikKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBMb2NhdG9yIGxvYyA9IChMb2NhdG9yKW5vZGU7Ci0gICAgICAgICAgICAgICAgICAgICAgICBtX2xvY2F0b3Iuc2V0Q29sdW1uTnVtYmVyKGxvYy5nZXRDb2x1bW5OdW1iZXIoKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBtX2xvY2F0b3Iuc2V0TGluZU51bWJlcihsb2MuZ2V0TGluZU51bWJlcigpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIG1fbG9jYXRvci5zZXRQdWJsaWNJZChsb2MuZ2V0UHVibGljSWQoKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBtX2xvY2F0b3Iuc2V0U3lzdGVtSWQobG9jLmdldFN5c3RlbUlkKCkpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgbV9sb2NhdG9yLnNldENvbHVtbk51bWJlcigwKTsKLSAgICAgIG1fbG9jYXRvci5zZXRMaW5lTnVtYmVyKDApOwotICAgICAgICAgICAgICAgIH0KLQotICAgIHN3aXRjaCAobm9kZS5nZXROb2RlVHlwZSgpKQotICAgIHsKLSAgICBjYXNlIE5vZGUuQ09NTUVOVF9OT0RFIDoKLSAgICB7Ci0gICAgICBTdHJpbmcgZGF0YSA9ICgoQ29tbWVudCkgbm9kZSkuZ2V0RGF0YSgpOwotCi0gICAgICBpZiAobV9jb250ZW50SGFuZGxlciBpbnN0YW5jZW9mIExleGljYWxIYW5kbGVyKQotICAgICAgewotICAgICAgICBMZXhpY2FsSGFuZGxlciBsaCA9ICgoTGV4aWNhbEhhbmRsZXIpIHRoaXMubV9jb250ZW50SGFuZGxlcik7Ci0KLSAgICAgICAgbGguY29tbWVudChkYXRhLnRvQ2hhckFycmF5KCksIDAsIGRhdGEubGVuZ3RoKCkpOwotICAgICAgfQotICAgIH0KLSAgICBicmVhazsKLSAgICBjYXNlIE5vZGUuRE9DVU1FTlRfRlJBR01FTlRfTk9ERSA6Ci0KLSAgICAgIC8vID8/OwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBOb2RlLkRPQ1VNRU5UX05PREUgOgotCi0gICAgICBicmVhazsKLSAgICBjYXNlIE5vZGUuRUxFTUVOVF9OT0RFIDoKLSAgICAgIE5hbWVkTm9kZU1hcCBhdHRzID0gKChFbGVtZW50KSBub2RlKS5nZXRBdHRyaWJ1dGVzKCk7Ci0gICAgICBpbnQgbkF0dHJzID0gYXR0cy5nZXRMZW5ndGgoKTsKLSAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiVHJlZVdhbGtlciNzdGFydE5vZGU6ICIrbm9kZS5nZXROb2RlTmFtZSgpKTsKLQotICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuQXR0cnM7IGkrKykKLSAgICAgIHsKLSAgICAgICAgTm9kZSBhdHRyID0gYXR0cy5pdGVtKGkpOwotICAgICAgICBTdHJpbmcgYXR0ck5hbWUgPSBhdHRyLmdldE5vZGVOYW1lKCk7Ci0KLSAgICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJUcmVlV2Fsa2VyI3N0YXJ0Tm9kZTogYXR0clsiK2krIl0gPSAiK2F0dHJOYW1lKyIsICIrYXR0ci5nZXROb2RlVmFsdWUoKSk7Ci0gICAgICAgIGlmIChhdHRyTmFtZS5lcXVhbHMoInhtbG5zIikgfHwgYXR0ck5hbWUuc3RhcnRzV2l0aCgieG1sbnM6IikpCi0gICAgICAgIHsKLSAgICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIlRyZWVXYWxrZXIjc3RhcnROb2RlOiBhdHRyWyIraSsiXSA9ICIrYXR0ck5hbWUrIiwgIithdHRyLmdldE5vZGVWYWx1ZSgpKTsKLSAgICAgICAgICBpbnQgaW5kZXg7Ci0gICAgICAgICAgLy8gVXNlICIiIGluc3RlYWQgb2YgbnVsbCwgYXMgWGVyY2VzIGxpa2VzICIiIGZvciB0aGUKLSAgICAgICAgICAvLyBuYW1lIG9mIHRoZSBkZWZhdWx0IG5hbWVzcGFjZS4gIEZpeCBhdHRyaWJ1dGVkCi0gICAgICAgICAgLy8gdG8gIlN0ZXZlbiBNdXJyYXkiIDxzbXVycmF5QGVidC5jb20+LgotICAgICAgICAgIFN0cmluZyBwcmVmaXggPSAoaW5kZXggPSBhdHRyTmFtZS5pbmRleE9mKCI6IikpIDwgMAotICAgICAgICAgICAgICAgICAgICAgICAgICA/ICIiIDogYXR0ck5hbWUuc3Vic3RyaW5nKGluZGV4ICsgMSk7Ci0KLSAgICAgICAgICB0aGlzLm1fY29udGVudEhhbmRsZXIuc3RhcnRQcmVmaXhNYXBwaW5nKHByZWZpeCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHIuZ2V0Tm9kZVZhbHVlKCkpOwotICAgICAgICB9Ci0KLSAgICAgIH0KLQotICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJtX2RoLmdldE5hbWVzcGFjZU9mTm9kZShub2RlKTogIittX2RoLmdldE5hbWVzcGFjZU9mTm9kZShub2RlKSk7Ci0gICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIm1fZGguZ2V0TG9jYWxOYW1lT2ZOb2RlKG5vZGUpOiAiK21fZGguZ2V0TG9jYWxOYW1lT2ZOb2RlKG5vZGUpKTsKLSAgICAgIFN0cmluZyBucyA9IG1fZGguZ2V0TmFtZXNwYWNlT2ZOb2RlKG5vZGUpOwotICAgICAgaWYobnVsbCA9PSBucykKLSAgICAgICAgbnMgPSAiIjsKLSAgICAgIHRoaXMubV9jb250ZW50SGFuZGxlci5zdGFydEVsZW1lbnQobnMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fZGguZ2V0TG9jYWxOYW1lT2ZOb2RlKG5vZGUpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlLmdldE5vZGVOYW1lKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBBdHRMaXN0KGF0dHMsIG1fZGgpKTsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgTm9kZS5QUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREUgOgotICAgIHsKLSAgICAgIFByb2Nlc3NpbmdJbnN0cnVjdGlvbiBwaSA9IChQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24pIG5vZGU7Ci0gICAgICBTdHJpbmcgbmFtZSA9IHBpLmdldE5vZGVOYW1lKCk7Ci0KLSAgICAgIC8vIFN0cmluZyBkYXRhID0gcGkuZ2V0RGF0YSgpOwotICAgICAgaWYgKG5hbWUuZXF1YWxzKCJ4c2x0LW5leHQtaXMtcmF3IikpCi0gICAgICB7Ci0gICAgICAgIG5leHRJc1JhdyA9IHRydWU7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIHRoaXMubV9jb250ZW50SGFuZGxlci5wcm9jZXNzaW5nSW5zdHJ1Y3Rpb24ocGkuZ2V0Tm9kZU5hbWUoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaS5nZXREYXRhKCkpOwotICAgICAgfQotICAgIH0KLSAgICBicmVhazsKLSAgICBjYXNlIE5vZGUuQ0RBVEFfU0VDVElPTl9OT0RFIDoKLSAgICB7Ci0gICAgICBib29sZWFuIGlzTGV4SCA9IChtX2NvbnRlbnRIYW5kbGVyIGluc3RhbmNlb2YgTGV4aWNhbEhhbmRsZXIpOwotICAgICAgTGV4aWNhbEhhbmRsZXIgbGggPSBpc0xleEgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgPyAoKExleGljYWxIYW5kbGVyKSB0aGlzLm1fY29udGVudEhhbmRsZXIpIDogbnVsbDsKLQotICAgICAgaWYgKGlzTGV4SCkKLSAgICAgIHsKLSAgICAgICAgbGguc3RhcnRDREFUQSgpOwotICAgICAgfQotCi0gICAgICBkaXNwYXRhY2hDaGFycyhub2RlKTsKLQotICAgICAgewotICAgICAgICBpZiAoaXNMZXhIKQotICAgICAgICB7Ci0gICAgICAgICAgbGguZW5kQ0RBVEEoKTsKLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLSAgICBicmVhazsKLSAgICBjYXNlIE5vZGUuVEVYVF9OT0RFIDoKLSAgICB7Ci0gICAgICAvL1N0cmluZyBkYXRhID0gKChUZXh0KSBub2RlKS5nZXREYXRhKCk7Ci0KLSAgICAgIGlmIChuZXh0SXNSYXcpCi0gICAgICB7Ci0gICAgICAgIG5leHRJc1JhdyA9IGZhbHNlOwotCi0gICAgICAgIG1fY29udGVudEhhbmRsZXIucHJvY2Vzc2luZ0luc3RydWN0aW9uKGphdmF4LnhtbC50cmFuc2Zvcm0uUmVzdWx0LlBJX0RJU0FCTEVfT1VUUFVUX0VTQ0FQSU5HLCAiIik7Ci0gICAgICAgIGRpc3BhdGFjaENoYXJzKG5vZGUpOwotICAgICAgICBtX2NvbnRlbnRIYW5kbGVyLnByb2Nlc3NpbmdJbnN0cnVjdGlvbihqYXZheC54bWwudHJhbnNmb3JtLlJlc3VsdC5QSV9FTkFCTEVfT1VUUFVUX0VTQ0FQSU5HLCAiIik7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIGRpc3BhdGFjaENoYXJzKG5vZGUpOwotICAgICAgfQotICAgIH0KLSAgICBicmVhazsKLSAgICBjYXNlIE5vZGUuRU5USVRZX1JFRkVSRU5DRV9OT0RFIDoKLSAgICB7Ci0gICAgICBFbnRpdHlSZWZlcmVuY2UgZXJlZiA9IChFbnRpdHlSZWZlcmVuY2UpIG5vZGU7Ci0KLSAgICAgIGlmIChtX2NvbnRlbnRIYW5kbGVyIGluc3RhbmNlb2YgTGV4aWNhbEhhbmRsZXIpCi0gICAgICB7Ci0gICAgICAgICgoTGV4aWNhbEhhbmRsZXIpIHRoaXMubV9jb250ZW50SGFuZGxlcikuc3RhcnRFbnRpdHkoCi0gICAgICAgICAgZXJlZi5nZXROb2RlTmFtZSgpKTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLQotICAgICAgICAvLyB3YXJuaW5nKCJDYW4gbm90IG91dHB1dCBlbnRpdHkgdG8gYSBwdXJlIFNBWCBDb250ZW50SGFuZGxlciIpOwotICAgICAgfQotICAgIH0KLSAgICBicmVhazsKLSAgICBkZWZhdWx0IDoKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogRW5kIHByb2Nlc3Npbmcgb2YgZ2l2ZW4gbm9kZQotICAgKgotICAgKgotICAgKiBAcGFyYW0gbm9kZSBOb2RlIHdlIGp1c3QgZmluaXNoZWQgcHJvY2Vzc2luZwotICAgKgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgZW5kTm9kZShOb2RlIG5vZGUpIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgc3dpdGNoIChub2RlLmdldE5vZGVUeXBlKCkpCi0gICAgewotICAgIGNhc2UgTm9kZS5ET0NVTUVOVF9OT0RFIDoKLSAgICAgIGJyZWFrOwotCi0gICAgY2FzZSBOb2RlLkVMRU1FTlRfTk9ERSA6Ci0gICAgICBTdHJpbmcgbnMgPSBtX2RoLmdldE5hbWVzcGFjZU9mTm9kZShub2RlKTsKLSAgICAgIGlmKG51bGwgPT0gbnMpCi0gICAgICAgIG5zID0gIiI7Ci0gICAgICB0aGlzLm1fY29udGVudEhhbmRsZXIuZW5kRWxlbWVudChucywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbV9kaC5nZXRMb2NhbE5hbWVPZk5vZGUobm9kZSksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUuZ2V0Tm9kZU5hbWUoKSk7Ci0KLSAgICAgIE5hbWVkTm9kZU1hcCBhdHRzID0gKChFbGVtZW50KSBub2RlKS5nZXRBdHRyaWJ1dGVzKCk7Ci0gICAgICBpbnQgbkF0dHJzID0gYXR0cy5nZXRMZW5ndGgoKTsKLQotICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuQXR0cnM7IGkrKykKLSAgICAgIHsKLSAgICAgICAgTm9kZSBhdHRyID0gYXR0cy5pdGVtKGkpOwotICAgICAgICBTdHJpbmcgYXR0ck5hbWUgPSBhdHRyLmdldE5vZGVOYW1lKCk7Ci0KLSAgICAgICAgaWYgKGF0dHJOYW1lLmVxdWFscygieG1sbnMiKSB8fCBhdHRyTmFtZS5zdGFydHNXaXRoKCJ4bWxuczoiKSkKLSAgICAgICAgewotICAgICAgICAgIGludCBpbmRleDsKLSAgICAgICAgICAvLyBVc2UgIiIgaW5zdGVhZCBvZiBudWxsLCBhcyBYZXJjZXMgbGlrZXMgIiIgZm9yIHRoZQotICAgICAgICAgIC8vIG5hbWUgb2YgdGhlIGRlZmF1bHQgbmFtZXNwYWNlLiAgRml4IGF0dHJpYnV0ZWQKLSAgICAgICAgICAvLyB0byAiU3RldmVuIE11cnJheSIgPHNtdXJyYXlAZWJ0LmNvbT4uCi0gICAgICAgICAgU3RyaW5nIHByZWZpeCA9IChpbmRleCA9IGF0dHJOYW1lLmluZGV4T2YoIjoiKSkgPCAwCi0gICAgICAgICAgICAgICAgICAgICAgICAgID8gIiIgOiBhdHRyTmFtZS5zdWJzdHJpbmcoaW5kZXggKyAxKTsKLQotICAgICAgICAgIHRoaXMubV9jb250ZW50SGFuZGxlci5lbmRQcmVmaXhNYXBwaW5nKHByZWZpeCk7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICAgIGJyZWFrOwotICAgIGNhc2UgTm9kZS5DREFUQV9TRUNUSU9OX05PREUgOgotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBOb2RlLkVOVElUWV9SRUZFUkVOQ0VfTk9ERSA6Ci0gICAgewotICAgICAgRW50aXR5UmVmZXJlbmNlIGVyZWYgPSAoRW50aXR5UmVmZXJlbmNlKSBub2RlOwotCi0gICAgICBpZiAobV9jb250ZW50SGFuZGxlciBpbnN0YW5jZW9mIExleGljYWxIYW5kbGVyKQotICAgICAgewotICAgICAgICBMZXhpY2FsSGFuZGxlciBsaCA9ICgoTGV4aWNhbEhhbmRsZXIpIHRoaXMubV9jb250ZW50SGFuZGxlcik7Ci0KLSAgICAgICAgbGguZW5kRW50aXR5KGVyZWYuZ2V0Tm9kZU5hbWUoKSk7Ci0gICAgICB9Ci0gICAgfQotICAgIGJyZWFrOwotICAgIGRlZmF1bHQgOgotICAgIH0KLSAgfQotfSAgLy9UcmVlV2Fsa2VyCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9UcmllLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9UcmllLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDk2YjIxMzguLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvVHJpZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjA3ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFRyaWUuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNSAwODoxNTo1OSBzdXJlc2hfZW1haWxpZCBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHM7Ci0KLS8qKgotICogQSBkaWdpdGFsIHNlYXJjaCB0cmllIGZvciA3LWJpdCBBU0NJSSB0ZXh0Ci0gKiBUaGUgQVBJIGlzIGEgc3Vic2V0IG9mIGphdmEudXRpbC5IYXNodGFibGUKLSAqIFRoZSBrZXkgbXVzdCBiZSBhIDctYml0IEFTQ0lJIHN0cmluZwotICogVGhlIHZhbHVlIG1heSBiZSBhbnkgSmF2YSBPYmplY3QKLSAqIEB4c2wudXNhZ2UgaW50ZXJuYWwKLSAqLwotcHVibGljIGNsYXNzIFRyaWUKLXsKLQotICAvKiogU2l6ZSBvZiB0aGUgbV9uZXh0Q2hhciBhcnJheS4gICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFMUEhBX1NJWkUgPSAxMjg7Ci0KLSAgLyoqIFRoZSByb290IG5vZGUgb2YgdGhlIHRyZWUuICAgICovCi0gIE5vZGUgbV9Sb290OwotCi0gIC8qKiBoZWxwZXIgYnVmZmVyIHRvIGNvbnZlcnQgU3RyaW5ncyB0byBjaGFyIGFycmF5cyAqLwotICBwcml2YXRlIGNoYXJbXSBtX2NoYXJCdWZmZXIgPSBuZXcgY2hhclswXTsKLQotICAvKioKLSAgICogQ29uc3RydWN0IHRoZSB0cmllLgotICAgKi8KLSAgcHVibGljIFRyaWUoKQotICB7Ci0gICAgbV9Sb290ID0gbmV3IE5vZGUoKTsKLSAgfQotCi0gIC8qKgotICAgKiBQdXQgYW4gb2JqZWN0IGludG8gdGhlIHRyaWUgZm9yIGxvb2t1cC4KLSAgICoKLSAgICogQHBhcmFtIGtleSBtdXN0IGJlIGEgNy1iaXQgQVNDSUkgc3RyaW5nCi0gICAqIEBwYXJhbSB2YWx1ZSBhbnkgamF2YSBvYmplY3QuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIG9sZCBvYmplY3QgdGhhdCBtYXRjaGVkIGtleSwgb3IgbnVsbC4KLSAgICovCi0gIHB1YmxpYyBPYmplY3QgcHV0KFN0cmluZyBrZXksIE9iamVjdCB2YWx1ZSkKLSAgewotCi0gICAgZmluYWwgaW50IGxlbiA9IGtleS5sZW5ndGgoKTsKLSAgICBpZiAobGVuID4gbV9jaGFyQnVmZmVyLmxlbmd0aCkKLSAgICB7Ci0gICAgICAgIC8vIG1ha2UgdGhlIGJpZ2dlc3QgYnVmZmVyIGV2ZXIgbmVlZGVkIGluIGdldChTdHJpbmcpCi0gICAgICAgIG1fY2hhckJ1ZmZlciA9IG5ldyBjaGFyW2xlbl07Ci0gICAgfQotCi0gICAgTm9kZSBub2RlID0gbV9Sb290OwotCi0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW47IGkrKykKLSAgICB7Ci0gICAgICBOb2RlIG5leHROb2RlID0gbm9kZS5tX25leHRDaGFyW0NoYXJhY3Rlci50b1VwcGVyQ2FzZShrZXkuY2hhckF0KGkpKV07Ci0KLSAgICAgIGlmIChuZXh0Tm9kZSAhPSBudWxsKQotICAgICAgewotICAgICAgICBub2RlID0gbmV4dE5vZGU7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIGZvciAoOyBpIDwgbGVuOyBpKyspCi0gICAgICAgIHsKLSAgICAgICAgICBOb2RlIG5ld05vZGUgPSBuZXcgTm9kZSgpOwotICAgICAgICAgIC8vIHB1dCB0aGlzIHZhbHVlIGludG8gdGhlIHRyZWUgd2l0aCBhIGNhc2UgaW5zZW5zaXRpdmUga2V5Ci0gICAgICAgICAgbm9kZS5tX25leHRDaGFyW0NoYXJhY3Rlci50b1VwcGVyQ2FzZShrZXkuY2hhckF0KGkpKV0gPSBuZXdOb2RlOwotICAgICAgICAgIG5vZGUubV9uZXh0Q2hhcltDaGFyYWN0ZXIudG9Mb3dlckNhc2Uoa2V5LmNoYXJBdChpKSldID0gbmV3Tm9kZTsKLSAgICAgICAgICBub2RlID0gbmV3Tm9kZTsKLSAgICAgICAgfQotICAgICAgICBicmVhazsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICBPYmplY3QgcmV0ID0gbm9kZS5tX1ZhbHVlOwotCi0gICAgbm9kZS5tX1ZhbHVlID0gdmFsdWU7Ci0KLSAgICByZXR1cm4gcmV0OwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBhbiBvYmplY3QgdGhhdCBtYXRjaGVzIHRoZSBrZXkuCi0gICAqCi0gICAqIEBwYXJhbSBrZXkgbXVzdCBiZSBhIDctYml0IEFTQ0lJIHN0cmluZwotICAgKgotICAgKiBAcmV0dXJuIFRoZSBvYmplY3QgdGhhdCBtYXRjaGVzIHRoZSBrZXksIG9yIG51bGwuCi0gICAqLwotcHVibGljIE9iamVjdCBnZXQoZmluYWwgU3RyaW5nIGtleSkKLXsKLQotICAgIGZpbmFsIGludCBsZW4gPSBrZXkubGVuZ3RoKCk7Ci0KLSAgICAvKiBJZiB0aGUgbmFtZSBpcyB0b28gbG9uZywgd2Ugd29uJ3QgZmluZCBpdCwgdGhpcyBhbHNvIGtlZXBzIHVzCi0gICAgICogZnJvbSBvdmVyZmxvd2luZyBtX2NoYXJCdWZmZXIKLSAgICAgKi8KLSAgICBpZiAobV9jaGFyQnVmZmVyLmxlbmd0aCA8IGxlbikKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0KLSAgICBOb2RlIG5vZGUgPSBtX1Jvb3Q7Ci0gICAgc3dpdGNoIChsZW4pIC8vIG9wdGltaXplIHRoZSBsb29rIHVwIGJhc2VkIG9uIHRoZSBudW1iZXIgb2YgY2hhcnMKLSAgICB7Ci0gICAgICAgIC8vIGNhc2UgMCBsb29rcyBzaWxseSwgYnV0IHRoZSBnZW5lcmF0ZWQgYnl0ZWNvZGUgcnVucwotICAgICAgICAvLyBmYXN0ZXIgZm9yIGxvb2t1cCBvZiBlbGVtZW50cyBvZiBsZW5ndGggMiB3aXRoIHRoaXMgaW4KLSAgICAgICAgLy8gYW5kIGEgZmFpciBiaXQgZmFzdGVyLiAgRG9uJ3Qga25vdyB3aHkuCi0gICAgICAgIGNhc2UgMCA6Ci0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgY2FzZSAxIDoKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBmaW5hbCBjaGFyIGNoID0ga2V5LmNoYXJBdCgwKTsKLSAgICAgICAgICAgICAgICBpZiAoY2ggPCBBTFBIQV9TSVpFKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgbm9kZSA9IG5vZGUubV9uZXh0Q2hhcltjaF07Ci0gICAgICAgICAgICAgICAgICAgIGlmIChub2RlICE9IG51bGwpCi0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbm9kZS5tX1ZhbHVlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgICAgIH0KLS8vICAgICAgICBjb21tZW50IG91dCBjYXNlIDIgYmVjYXVzZSB0aGUgZGVmYXVsdCBpcyBmYXN0ZXIKLS8vICAgICAgICBjYXNlIDIgOgotLy8gICAgICAgICAgICB7Ci0vLyAgICAgICAgICAgICAgICBmaW5hbCBjaGFyIGNoMCA9IGtleS5jaGFyQXQoMCk7Ci0vLyAgICAgICAgICAgICAgICBmaW5hbCBjaGFyIGNoMSA9IGtleS5jaGFyQXQoMSk7Ci0vLyAgICAgICAgICAgICAgICBpZiAoY2gwIDwgQUxQSEFfU0laRSAmJiBjaDEgPCBBTFBIQV9TSVpFKQotLy8gICAgICAgICAgICAgICAgewotLy8gICAgICAgICAgICAgICAgICAgIG5vZGUgPSBub2RlLm1fbmV4dENoYXJbY2gwXTsKLS8vICAgICAgICAgICAgICAgICAgICBpZiAobm9kZSAhPSBudWxsKQotLy8gICAgICAgICAgICAgICAgICAgIHsKLS8vCi0vLyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjaDEgPCBBTFBIQV9TSVpFKQotLy8gICAgICAgICAgICAgICAgICAgICAgICB7Ci0vLyAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlID0gbm9kZS5tX25leHRDaGFyW2NoMV07Ci0vLyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobm9kZSAhPSBudWxsKQotLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBub2RlLm1fVmFsdWU7Ci0vLyAgICAgICAgICAgICAgICAgICAgICAgIH0KLS8vICAgICAgICAgICAgICAgICAgICB9Ci0vLyAgICAgICAgICAgICAgICB9Ci0vLyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLS8vICAgICAgICAgICB9Ci0gICAgICAgIGRlZmF1bHQgOgotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIGtleS5nZXRDaGFycygwLCBsZW4sIG1fY2hhckJ1ZmZlciwgMCk7Ci0gICAgICAgICAgICAgICAgLy8gY29weSBzdHJpbmcgaW50byBhcnJheQotICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuOyBpKyspCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICBmaW5hbCBjaGFyIGNoID0gbV9jaGFyQnVmZmVyW2ldOwotICAgICAgICAgICAgICAgICAgICBpZiAoQUxQSEFfU0laRSA8PSBjaCkKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhlIGtleSBpcyBub3QgNy1iaXQgQVNDSUkgc28gd2Ugd29uJ3QgZmluZCBpdCBoZXJlCi0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgIG5vZGUgPSBub2RlLm1fbmV4dENoYXJbY2hdOwotICAgICAgICAgICAgICAgICAgICBpZiAobm9kZSA9PSBudWxsKQotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgcmV0dXJuIG5vZGUubV9WYWx1ZTsKLSAgICAgICAgICAgIH0KLSAgICB9Ci19Ci0KLSAgLyoqCi0gICAqIFRoZSBub2RlIHJlcHJlc2VudGF0aW9uIGZvciB0aGUgdHJpZS4KLSAgICogQHhzbC51c2FnZSBpbnRlcm5hbAotICAgKi8KLSAgY2xhc3MgTm9kZQotICB7Ci0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RvciwgY3JlYXRlcyBhIE5vZGVbQUxQSEFfU0laRV0uCi0gICAgICovCi0gICAgTm9kZSgpCi0gICAgewotICAgICAgbV9uZXh0Q2hhciA9IG5ldyBOb2RlW0FMUEhBX1NJWkVdOwotICAgICAgbV9WYWx1ZSA9IG51bGw7Ci0gICAgfQotCi0gICAgLyoqIFRoZSBuZXh0IG5vZGVzLiAgICovCi0gICAgTm9kZSBtX25leHRDaGFyW107Ci0KLSAgICAvKiogVGhlIHZhbHVlLiAgICovCi0gICAgT2JqZWN0IG1fVmFsdWU7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL1VSSS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvVVJJLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGY5ZTY3YWIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvVVJJLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNjkyICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFVSSS5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE1IDA4OjE2OjAwIHN1cmVzaF9lbWFpbGlkIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlsczsKLQotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci1pbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnJlcy5YTUxFcnJvclJlc291cmNlczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnJlcy5YTUxNZXNzYWdlczsKLWltcG9ydCBqYXZhLnV0aWwuT2JqZWN0czsKLQotLyoqCi0gKiBBIGNsYXNzIHRvIHJlcHJlc2VudCBhIFVuaWZvcm0gUmVzb3VyY2UgSWRlbnRpZmllciAoVVJJKS4gVGhpcyBjbGFzcwotICogaXMgZGVzaWduZWQgdG8gaGFuZGxlIHRoZSBwYXJzaW5nIG9mIFVSSXMgYW5kIHByb3ZpZGUgYWNjZXNzIHRvCi0gKiB0aGUgdmFyaW91cyBjb21wb25lbnRzIChzY2hlbWUsIGhvc3QsIHBvcnQsIHVzZXJpbmZvLCBwYXRoLCBxdWVyeQotICogc3RyaW5nIGFuZCBmcmFnbWVudCkgdGhhdCBtYXkgY29uc3RpdHV0ZSBhIFVSSS4KLSAqIDxwPgotICogUGFyc2luZyBvZiBhIFVSSSBzcGVjaWZpY2F0aW9uIGlzIGRvbmUgYWNjb3JkaW5nIHRvIHRoZSBVUkkKLSAqIHN5bnRheCBkZXNjcmliZWQgaW4gUkZDIDIzOTYKLSAqIDxodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyMzk2LnR4dD9udW1iZXI9MjM5Nj4uIEV2ZXJ5IFVSSSBjb25zaXN0cwotICogb2YgYSBzY2hlbWUsIGZvbGxvd2VkIGJ5IGEgY29sb24gKCc6JyksIGZvbGxvd2VkIGJ5IGEgc2NoZW1lLXNwZWNpZmljCi0gKiBwYXJ0LiBGb3IgVVJJcyB0aGF0IGZvbGxvdyB0aGUgImdlbmVyaWMgVVJJIiBzeW50YXgsIHRoZSBzY2hlbWUtCi0gKiBzcGVjaWZpYyBwYXJ0IGJlZ2lucyB3aXRoIHR3byBzbGFzaGVzICgiLy8iKSBhbmQgbWF5IGJlIGZvbGxvd2VkCi0gKiBieSBhbiBhdXRob3JpdHkgc2VnbWVudCAoY29tcHJpc2VkIG9mIHVzZXIgaW5mb3JtYXRpb24sIGhvc3QsIGFuZAotICogcG9ydCksIHBhdGggc2VnbWVudCwgcXVlcnkgc2VnbWVudCBhbmQgZnJhZ21lbnQuIE5vdGUgdGhhdCBSRkMgMjM5NgotICogbm8gbG9uZ2VyIHNwZWNpZmllcyB0aGUgdXNlIG9mIHRoZSBwYXJhbWV0ZXJzIHNlZ21lbnQgYW5kIGV4Y2x1ZGVzCi0gKiB0aGUgInVzZXI6cGFzc3dvcmQiIHN5bnRheCBhcyBwYXJ0IG9mIHRoZSBhdXRob3JpdHkgc2VnbWVudC4gSWYKLSAqICJ1c2VyOnBhc3N3b3JkIiBhcHBlYXJzIGluIGEgVVJJLCB0aGUgZW50aXJlIHVzZXIvcGFzc3dvcmQgc3RyaW5nCi0gKiBpcyBzdG9yZWQgYXMgdXNlcmluZm8uCi0gKiA8cD4KLSAqIEZvciBVUklzIHRoYXQgZG8gbm90IGZvbGxvdyB0aGUgImdlbmVyaWMgVVJJIiBzeW50YXggKGUuZy4gbWFpbHRvKSwKLSAqIHRoZSBlbnRpcmUgc2NoZW1lLXNwZWNpZmljIHBhcnQgaXMgdHJlYXRlZCBhcyB0aGUgInBhdGgiIHBvcnRpb24KLSAqIG9mIHRoZSBVUkkuCi0gKiA8cD4KLSAqIE5vdGUgdGhhdCwgdW5saWtlIHRoZSBqYXZhLm5ldC5VUkwgY2xhc3MsIHRoaXMgY2xhc3MgZG9lcyBub3QgcHJvdmlkZQotICogYW55IGJ1aWx0LWluIG5ldHdvcmsgYWNjZXNzIGZ1bmN0aW9uYWxpdHkgbm9yIGRvZXMgaXQgcHJvdmlkZSBhbnkKLSAqIHNjaGVtZS1zcGVjaWZpYyBmdW5jdGlvbmFsaXR5IChmb3IgZXhhbXBsZSwgaXQgZG9lcyBub3Qga25vdyBhCi0gKiBkZWZhdWx0IHBvcnQgZm9yIGEgc3BlY2lmaWMgc2NoZW1lKS4gUmF0aGVyLCBpdCBvbmx5IGtub3dzIHRoZQotICogZ3JhbW1hciBhbmQgYmFzaWMgc2V0IG9mIG9wZXJhdGlvbnMgdGhhdCBjYW4gYmUgYXBwbGllZCB0byBhIFVSSS4KLSAqCi0gKgotICovCi1wdWJsaWMgY2xhc3MgVVJJIGltcGxlbWVudHMgU2VyaWFsaXphYmxlCi17Ci0gICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDcwOTYyNjYzNzc5MDcwODE4OTdMOwotCi0gIC8qKgotICAgKiBNYWxmb3JtZWRVUklFeGNlcHRpb25zIGFyZSB0aHJvd24gaW4gdGhlIHByb2Nlc3Mgb2YgYnVpbGRpbmcgYSBVUkkKLSAgICogb3Igc2V0dGluZyBmaWVsZHMgb24gYSBVUkkgd2hlbiBhbiBvcGVyYXRpb24gd291bGQgcmVzdWx0IGluIGFuCi0gICAqIGludmFsaWQgVVJJIHNwZWNpZmljYXRpb24uCi0gICAqCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGNsYXNzIE1hbGZvcm1lZFVSSUV4Y2VwdGlvbiBleHRlbmRzIElPRXhjZXB0aW9uCi0gIHsKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHMgYSA8Y29kZT5NYWxmb3JtZWRVUklFeGNlcHRpb248L2NvZGU+IHdpdGggbm8gc3BlY2lmaWVkCi0gICAgICogZGV0YWlsIG1lc3NhZ2UuCi0gICAgICovCi0gICAgcHVibGljIE1hbGZvcm1lZFVSSUV4Y2VwdGlvbigpCi0gICAgewotICAgICAgc3VwZXIoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RzIGEgPGNvZGU+TWFsZm9ybWVkVVJJRXhjZXB0aW9uPC9jb2RlPiB3aXRoIHRoZQotICAgICAqIHNwZWNpZmllZCBkZXRhaWwgbWVzc2FnZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBwX21zZyB0aGUgZGV0YWlsIG1lc3NhZ2UuCi0gICAgICovCi0gICAgcHVibGljIE1hbGZvcm1lZFVSSUV4Y2VwdGlvbihTdHJpbmcgcF9tc2cpCi0gICAgewotICAgICAgc3VwZXIocF9tc2cpOwotICAgIH0KLSAgfQotCi0gIC8qKiByZXNlcnZlZCBjaGFyYWN0ZXJzICovCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBSRVNFUlZFRF9DSEFSQUNURVJTID0gIjsvPzpAJj0rJCwiOwotCi0gIC8qKgotICAgKiBVUkkgcHVuY3R1YXRpb24gbWFyayBjaGFyYWN0ZXJzIC0gdGhlc2UsIGNvbWJpbmVkIHdpdGgKLSAgICogICBhbHBoYW51bWVyaWNzLCBjb25zdGl0dXRlIHRoZSAidW5yZXNlcnZlZCIgY2hhcmFjdGVycwotICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIE1BUktfQ0hBUkFDVEVSUyA9ICItXy4hfionKCkgIjsKLQotICAvKiogc2NoZW1lIGNhbiBiZSBjb21wb3NlZCBvZiBhbHBoYW51bWVyaWNzIGFuZCB0aGVzZSBjaGFyYWN0ZXJzICovCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBTQ0hFTUVfQ0hBUkFDVEVSUyA9ICIrLS4iOwotCi0gIC8qKgotICAgKiB1c2VyaW5mbyBjYW4gYmUgY29tcG9zZWQgb2YgdW5yZXNlcnZlZCwgZXNjYXBlZCBhbmQgdGhlc2UKLSAgICogICBjaGFyYWN0ZXJzCi0gICAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgVVNFUklORk9fQ0hBUkFDVEVSUyA9ICI7OiY9KyQsIjsKLQotICAvKiogU3RvcmVzIHRoZSBzY2hlbWUgKHVzdWFsbHkgdGhlIHByb3RvY29sKSBmb3IgdGhpcyBVUkkuCi0gICAqICBAc2VyaWFsICovCi0gIHByaXZhdGUgU3RyaW5nIG1fc2NoZW1lID0gbnVsbDsKLQotICAvKiogSWYgc3BlY2lmaWVkLCBzdG9yZXMgdGhlIHVzZXJpbmZvIGZvciB0aGlzIFVSSTsgb3RoZXJ3aXNlIG51bGwuCi0gICAqICBAc2VyaWFsICovCi0gIHByaXZhdGUgU3RyaW5nIG1fdXNlcmluZm8gPSBudWxsOwotCi0gIC8qKiBJZiBzcGVjaWZpZWQsIHN0b3JlcyB0aGUgaG9zdCBmb3IgdGhpcyBVUkk7IG90aGVyd2lzZSBudWxsLgotICAgKiAgQHNlcmlhbCAqLwotICBwcml2YXRlIFN0cmluZyBtX2hvc3QgPSBudWxsOwotCi0gIC8qKiBJZiBzcGVjaWZpZWQsIHN0b3JlcyB0aGUgcG9ydCBmb3IgdGhpcyBVUkk7IG90aGVyd2lzZSAtMS4KLSAgICogIEBzZXJpYWwgKi8KLSAgcHJpdmF0ZSBpbnQgbV9wb3J0ID0gLTE7Ci0KLSAgLyoqIElmIHNwZWNpZmllZCwgc3RvcmVzIHRoZSBwYXRoIGZvciB0aGlzIFVSSTsgb3RoZXJ3aXNlIG51bGwuCi0gICAqICBAc2VyaWFsICovCi0gIHByaXZhdGUgU3RyaW5nIG1fcGF0aCA9IG51bGw7Ci0KLSAgLyoqCi0gICAqIElmIHNwZWNpZmllZCwgc3RvcmVzIHRoZSBxdWVyeSBzdHJpbmcgZm9yIHRoaXMgVVJJOyBvdGhlcndpc2UKLSAgICogICBudWxsLgotICAgKiBAc2VyaWFsCi0gICAqLwotICBwcml2YXRlIFN0cmluZyBtX3F1ZXJ5U3RyaW5nID0gbnVsbDsKLQotICAvKiogSWYgc3BlY2lmaWVkLCBzdG9yZXMgdGhlIGZyYWdtZW50IGZvciB0aGlzIFVSSTsgb3RoZXJ3aXNlIG51bGwuCi0gICAqICBAc2VyaWFsICovCi0gIHByaXZhdGUgU3RyaW5nIG1fZnJhZ21lbnQgPSBudWxsOwotCi0gIC8qKiBJbmRpY2F0ZSB3aGV0aGVyIGluIERFQlVHIG1vZGUgICAgICAgICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBERUJVRyA9IGZhbHNlOwotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBuZXcgYW5kIHVuaW5pdGlhbGl6ZWQgVVJJLgotICAgKi8KLSAgcHVibGljIFVSSSgpe30KLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgbmV3IFVSSSBmcm9tIGFub3RoZXIgVVJJLiBBbGwgZmllbGRzIGZvciB0aGlzIFVSSSBhcmUKLSAgICogc2V0IGVxdWFsIHRvIHRoZSBmaWVsZHMgb2YgdGhlIFVSSSBwYXNzZWQgaW4uCi0gICAqCi0gICAqIEBwYXJhbSBwX290aGVyIHRoZSBVUkkgdG8gY29weSAoY2Fubm90IGJlIG51bGwpCi0gICAqLwotICBwdWJsaWMgVVJJKFVSSSBwX290aGVyKQotICB7Ci0gICAgaW5pdGlhbGl6ZShwX290aGVyKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBuZXcgVVJJIGZyb20gYSBVUkkgc3BlY2lmaWNhdGlvbiBzdHJpbmcuIElmIHRoZQotICAgKiBzcGVjaWZpY2F0aW9uIGZvbGxvd3MgdGhlICJnZW5lcmljIFVSSSIgc3ludGF4LCAodHdvIHNsYXNoZXMKLSAgICogZm9sbG93aW5nIHRoZSBmaXJzdCBjb2xvbiksIHRoZSBzcGVjaWZpY2F0aW9uIHdpbGwgYmUgcGFyc2VkCi0gICAqIGFjY29yZGluZ2x5IC0gc2V0dGluZyB0aGUgc2NoZW1lLCB1c2VyaW5mbywgaG9zdCxwb3J0LCBwYXRoLCBxdWVyeQotICAgKiBzdHJpbmcgYW5kIGZyYWdtZW50IGZpZWxkcyBhcyBuZWNlc3NhcnkuIElmIHRoZSBzcGVjaWZpY2F0aW9uIGRvZXMKLSAgICogbm90IGZvbGxvdyB0aGUgImdlbmVyaWMgVVJJIiBzeW50YXgsIHRoZSBzcGVjaWZpY2F0aW9uIGlzIHBhcnNlZAotICAgKiBpbnRvIGEgc2NoZW1lIGFuZCBzY2hlbWUtc3BlY2lmaWMgcGFydCAoc3RvcmVkIGFzIHRoZSBwYXRoKSBvbmx5LgotICAgKgotICAgKiBAcGFyYW0gcF91cmlTcGVjIHRoZSBVUkkgc3BlY2lmaWNhdGlvbiBzdHJpbmcgKGNhbm5vdCBiZSBudWxsIG9yCi0gICAqICAgICAgICAgICAgICAgICAgZW1wdHkpCi0gICAqCi0gICAqIEB0aHJvd3MgTWFsZm9ybWVkVVJJRXhjZXB0aW9uIGlmIHBfdXJpU3BlYyB2aW9sYXRlcyBhbnkgc3ludGF4Ci0gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBydWxlcwotICAgKi8KLSAgcHVibGljIFVSSShTdHJpbmcgcF91cmlTcGVjKSB0aHJvd3MgTWFsZm9ybWVkVVJJRXhjZXB0aW9uCi0gIHsKLSAgICB0aGlzKChVUkkpIG51bGwsIHBfdXJpU3BlYyk7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgbmV3IFVSSSBmcm9tIGEgYmFzZSBVUkkgYW5kIGEgVVJJIHNwZWNpZmljYXRpb24gc3RyaW5nLgotICAgKiBUaGUgVVJJIHNwZWNpZmljYXRpb24gc3RyaW5nIG1heSBiZSBhIHJlbGF0aXZlIFVSSS4KLSAgICoKLSAgICogQHBhcmFtIHBfYmFzZSB0aGUgYmFzZSBVUkkgKGNhbm5vdCBiZSBudWxsIGlmIHBfdXJpU3BlYyBpcyBudWxsIG9yCi0gICAqICAgICAgICAgICAgICAgZW1wdHkpCi0gICAqIEBwYXJhbSBwX3VyaVNwZWMgdGhlIFVSSSBzcGVjaWZpY2F0aW9uIHN0cmluZyAoY2Fubm90IGJlIG51bGwgb3IKLSAgICogICAgICAgICAgICAgICAgICBlbXB0eSBpZiBwX2Jhc2UgaXMgbnVsbCkKLSAgICoKLSAgICogQHRocm93cyBNYWxmb3JtZWRVUklFeGNlcHRpb24gaWYgcF91cmlTcGVjIHZpb2xhdGVzIGFueSBzeW50YXgKLSAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcnVsZXMKLSAgICovCi0gIHB1YmxpYyBVUkkoVVJJIHBfYmFzZSwgU3RyaW5nIHBfdXJpU3BlYykgdGhyb3dzIE1hbGZvcm1lZFVSSUV4Y2VwdGlvbgotICB7Ci0gICAgaW5pdGlhbGl6ZShwX2Jhc2UsIHBfdXJpU3BlYyk7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgbmV3IFVSSSB0aGF0IGRvZXMgbm90IGZvbGxvdyB0aGUgZ2VuZXJpYyBVUkkgc3ludGF4LgotICAgKiBPbmx5IHRoZSBzY2hlbWUgYW5kIHNjaGVtZS1zcGVjaWZpYyBwYXJ0IChzdG9yZWQgYXMgdGhlIHBhdGgpIGFyZQotICAgKiBpbml0aWFsaXplZC4KLSAgICoKLSAgICogQHBhcmFtIHBfc2NoZW1lIHRoZSBVUkkgc2NoZW1lIChjYW5ub3QgYmUgbnVsbCBvciBlbXB0eSkKLSAgICogQHBhcmFtIHBfc2NoZW1lU3BlY2lmaWNQYXJ0IHRoZSBzY2hlbWUtc3BlY2lmaWMgcGFydCAoY2Fubm90IGJlCi0gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsIG9yIGVtcHR5KQotICAgKgotICAgKiBAdGhyb3dzIE1hbGZvcm1lZFVSSUV4Y2VwdGlvbiBpZiBwX3NjaGVtZSB2aW9sYXRlcyBhbnkKLSAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ludGF4IHJ1bGVzCi0gICAqLwotICBwdWJsaWMgVVJJKFN0cmluZyBwX3NjaGVtZSwgU3RyaW5nIHBfc2NoZW1lU3BlY2lmaWNQYXJ0KQotICAgICAgICAgIHRocm93cyBNYWxmb3JtZWRVUklFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKHBfc2NoZW1lID09IG51bGwgfHwgcF9zY2hlbWUudHJpbSgpLmxlbmd0aCgpID09IDApCi0gICAgewotICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVSSUV4Y2VwdGlvbigKLSAgICAgICAgIkNhbm5vdCBjb25zdHJ1Y3QgVVJJIHdpdGggbnVsbC9lbXB0eSBzY2hlbWUhIik7Ci0gICAgfQotCi0gICAgaWYgKHBfc2NoZW1lU3BlY2lmaWNQYXJ0ID09IG51bGwKLSAgICAgICAgICAgIHx8IHBfc2NoZW1lU3BlY2lmaWNQYXJ0LnRyaW0oKS5sZW5ndGgoKSA9PSAwKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVUklFeGNlcHRpb24oCi0gICAgICAgICJDYW5ub3QgY29uc3RydWN0IFVSSSB3aXRoIG51bGwvZW1wdHkgc2NoZW1lLXNwZWNpZmljIHBhcnQhIik7Ci0gICAgfQotCi0gICAgc2V0U2NoZW1lKHBfc2NoZW1lKTsKLSAgICBzZXRQYXRoKHBfc2NoZW1lU3BlY2lmaWNQYXJ0KTsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBuZXcgVVJJIHRoYXQgZm9sbG93cyB0aGUgZ2VuZXJpYyBVUkkgc3ludGF4IGZyb20gaXRzCi0gICAqIGNvbXBvbmVudCBwYXJ0cy4gRWFjaCBjb21wb25lbnQgaXMgdmFsaWRhdGVkIGZvciBzeW50YXggYW5kIHNvbWUKLSAgICogYmFzaWMgc2VtYW50aWMgY2hlY2tzIGFyZSBwZXJmb3JtZWQgYXMgd2VsbC4gIFNlZSB0aGUgaW5kaXZpZHVhbAotICAgKiBzZXR0ZXIgbWV0aG9kcyBmb3Igc3BlY2lmaWNzLgotICAgKgotICAgKiBAcGFyYW0gcF9zY2hlbWUgdGhlIFVSSSBzY2hlbWUgKGNhbm5vdCBiZSBudWxsIG9yIGVtcHR5KQotICAgKiBAcGFyYW0gcF9ob3N0IHRoZSBob3N0bmFtZSBvciBJUHY0IGFkZHJlc3MgZm9yIHRoZSBVUkkKLSAgICogQHBhcmFtIHBfcGF0aCB0aGUgVVJJIHBhdGggLSBpZiB0aGUgcGF0aCBjb250YWlucyAnPycgb3IgJyMnLAotICAgKiAgICAgICAgICAgICAgIHRoZW4gdGhlIHF1ZXJ5IHN0cmluZyBhbmQvb3IgZnJhZ21lbnQgd2lsbCBiZQotICAgKiAgICAgICAgICAgICAgIHNldCBmcm9tIHRoZSBwYXRoOyBob3dldmVyLCBpZiB0aGUgcXVlcnkgYW5kCi0gICAqICAgICAgICAgICAgICAgZnJhZ21lbnQgYXJlIHNwZWNpZmllZCBib3RoIGluIHRoZSBwYXRoIGFuZCBhcwotICAgKiAgICAgICAgICAgICAgIHNlcGFyYXRlIHBhcmFtZXRlcnMsIGFuIGV4Y2VwdGlvbiBpcyB0aHJvd24KLSAgICogQHBhcmFtIHBfcXVlcnlTdHJpbmcgdGhlIFVSSSBxdWVyeSBzdHJpbmcgKGNhbm5vdCBiZSBzcGVjaWZpZWQKLSAgICogICAgICAgICAgICAgICAgICAgICAgaWYgcGF0aCBpcyBudWxsKQotICAgKiBAcGFyYW0gcF9mcmFnbWVudCB0aGUgVVJJIGZyYWdtZW50IChjYW5ub3QgYmUgc3BlY2lmaWVkIGlmIHBhdGgKLSAgICogICAgICAgICAgICAgICAgICAgaXMgbnVsbCkKLSAgICoKLSAgICogQHRocm93cyBNYWxmb3JtZWRVUklFeGNlcHRpb24gaWYgYW55IG9mIHRoZSBwYXJhbWV0ZXJzIHZpb2xhdGVzCi0gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bnRheCBydWxlcyBvciBzZW1hbnRpYyBydWxlcwotICAgKi8KLSAgcHVibGljIFVSSShTdHJpbmcgcF9zY2hlbWUsIFN0cmluZyBwX2hvc3QsIFN0cmluZyBwX3BhdGgsIFN0cmluZyBwX3F1ZXJ5U3RyaW5nLCBTdHJpbmcgcF9mcmFnbWVudCkKLSAgICAgICAgICB0aHJvd3MgTWFsZm9ybWVkVVJJRXhjZXB0aW9uCi0gIHsKLSAgICB0aGlzKHBfc2NoZW1lLCBudWxsLCBwX2hvc3QsIC0xLCBwX3BhdGgsIHBfcXVlcnlTdHJpbmcsIHBfZnJhZ21lbnQpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhIG5ldyBVUkkgdGhhdCBmb2xsb3dzIHRoZSBnZW5lcmljIFVSSSBzeW50YXggZnJvbSBpdHMKLSAgICogY29tcG9uZW50IHBhcnRzLiBFYWNoIGNvbXBvbmVudCBpcyB2YWxpZGF0ZWQgZm9yIHN5bnRheCBhbmQgc29tZQotICAgKiBiYXNpYyBzZW1hbnRpYyBjaGVja3MgYXJlIHBlcmZvcm1lZCBhcyB3ZWxsLiAgU2VlIHRoZSBpbmRpdmlkdWFsCi0gICAqIHNldHRlciBtZXRob2RzIGZvciBzcGVjaWZpY3MuCi0gICAqCi0gICAqIEBwYXJhbSBwX3NjaGVtZSB0aGUgVVJJIHNjaGVtZSAoY2Fubm90IGJlIG51bGwgb3IgZW1wdHkpCi0gICAqIEBwYXJhbSBwX3VzZXJpbmZvIHRoZSBVUkkgdXNlcmluZm8gKGNhbm5vdCBiZSBzcGVjaWZpZWQgaWYgaG9zdAotICAgKiAgICAgICAgICAgICAgICAgICBpcyBudWxsKQotICAgKiBAcGFyYW0gcF9ob3N0IHRoZSBob3N0bmFtZSBvciBJUHY0IGFkZHJlc3MgZm9yIHRoZSBVUkkKLSAgICogQHBhcmFtIHBfcG9ydCB0aGUgVVJJIHBvcnQgKG1heSBiZSAtMSBmb3IgInVuc3BlY2lmaWVkIjsgY2Fubm90Ci0gICAqICAgICAgICAgICAgICAgYmUgc3BlY2lmaWVkIGlmIGhvc3QgaXMgbnVsbCkKLSAgICogQHBhcmFtIHBfcGF0aCB0aGUgVVJJIHBhdGggLSBpZiB0aGUgcGF0aCBjb250YWlucyAnPycgb3IgJyMnLAotICAgKiAgICAgICAgICAgICAgIHRoZW4gdGhlIHF1ZXJ5IHN0cmluZyBhbmQvb3IgZnJhZ21lbnQgd2lsbCBiZQotICAgKiAgICAgICAgICAgICAgIHNldCBmcm9tIHRoZSBwYXRoOyBob3dldmVyLCBpZiB0aGUgcXVlcnkgYW5kCi0gICAqICAgICAgICAgICAgICAgZnJhZ21lbnQgYXJlIHNwZWNpZmllZCBib3RoIGluIHRoZSBwYXRoIGFuZCBhcwotICAgKiAgICAgICAgICAgICAgIHNlcGFyYXRlIHBhcmFtZXRlcnMsIGFuIGV4Y2VwdGlvbiBpcyB0aHJvd24KLSAgICogQHBhcmFtIHBfcXVlcnlTdHJpbmcgdGhlIFVSSSBxdWVyeSBzdHJpbmcgKGNhbm5vdCBiZSBzcGVjaWZpZWQKLSAgICogICAgICAgICAgICAgICAgICAgICAgaWYgcGF0aCBpcyBudWxsKQotICAgKiBAcGFyYW0gcF9mcmFnbWVudCB0aGUgVVJJIGZyYWdtZW50IChjYW5ub3QgYmUgc3BlY2lmaWVkIGlmIHBhdGgKLSAgICogICAgICAgICAgICAgICAgICAgaXMgbnVsbCkKLSAgICoKLSAgICogQHRocm93cyBNYWxmb3JtZWRVUklFeGNlcHRpb24gaWYgYW55IG9mIHRoZSBwYXJhbWV0ZXJzIHZpb2xhdGVzCi0gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bnRheCBydWxlcyBvciBzZW1hbnRpYyBydWxlcwotICAgKi8KLSAgcHVibGljIFVSSShTdHJpbmcgcF9zY2hlbWUsIFN0cmluZyBwX3VzZXJpbmZvLCBTdHJpbmcgcF9ob3N0LCBpbnQgcF9wb3J0LCBTdHJpbmcgcF9wYXRoLCBTdHJpbmcgcF9xdWVyeVN0cmluZywgU3RyaW5nIHBfZnJhZ21lbnQpCi0gICAgICAgICAgdGhyb3dzIE1hbGZvcm1lZFVSSUV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAocF9zY2hlbWUgPT0gbnVsbCB8fCBwX3NjaGVtZS50cmltKCkubGVuZ3RoKCkgPT0gMCkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVVJJRXhjZXB0aW9uKFhNTE1lc3NhZ2VzLmNyZWF0ZVhNTE1lc3NhZ2UoWE1MRXJyb3JSZXNvdXJjZXMuRVJfU0NIRU1FX1JFUVVJUkVELCBudWxsKSk7IC8vIlNjaGVtZSBpcyByZXF1aXJlZCEiKTsKLSAgICB9Ci0KLSAgICBpZiAocF9ob3N0ID09IG51bGwpCi0gICAgewotICAgICAgaWYgKHBfdXNlcmluZm8gIT0gbnVsbCkKLSAgICAgIHsKLSAgICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVSSUV4Y2VwdGlvbigKLSAgICAgICAgICBYTUxNZXNzYWdlcy5jcmVhdGVYTUxNZXNzYWdlKFhNTEVycm9yUmVzb3VyY2VzLkVSX05PX1VTRVJJTkZPX0lGX05PX0hPU1QsIG51bGwpKTsgLy8iVXNlcmluZm8gbWF5IG5vdCBiZSBzcGVjaWZpZWQgaWYgaG9zdCBpcyBub3Qgc3BlY2lmaWVkISIpOwotICAgICAgfQotCi0gICAgICBpZiAocF9wb3J0ICE9IC0xKQotICAgICAgewotICAgICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVVJJRXhjZXB0aW9uKAotICAgICAgICAgIFhNTE1lc3NhZ2VzLmNyZWF0ZVhNTE1lc3NhZ2UoWE1MRXJyb3JSZXNvdXJjZXMuRVJfTk9fUE9SVF9JRl9OT19IT1NULCBudWxsKSk7IC8vIlBvcnQgbWF5IG5vdCBiZSBzcGVjaWZpZWQgaWYgaG9zdCBpcyBub3Qgc3BlY2lmaWVkISIpOwotICAgICAgfQotICAgIH0KLQotICAgIGlmIChwX3BhdGggIT0gbnVsbCkKLSAgICB7Ci0gICAgICBpZiAocF9wYXRoLmluZGV4T2YoJz8nKSAhPSAtMSAmJiBwX3F1ZXJ5U3RyaW5nICE9IG51bGwpCi0gICAgICB7Ci0gICAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVUklFeGNlcHRpb24oCi0gICAgICAgICAgWE1MTWVzc2FnZXMuY3JlYXRlWE1MTWVzc2FnZShYTUxFcnJvclJlc291cmNlcy5FUl9OT19RVUVSWV9TVFJJTkdfSU5fUEFUSCwgbnVsbCkpOyAvLyJRdWVyeSBzdHJpbmcgY2Fubm90IGJlIHNwZWNpZmllZCBpbiBwYXRoIGFuZCBxdWVyeSBzdHJpbmchIik7Ci0gICAgICB9Ci0KLSAgICAgIGlmIChwX3BhdGguaW5kZXhPZignIycpICE9IC0xICYmIHBfZnJhZ21lbnQgIT0gbnVsbCkKLSAgICAgIHsKLSAgICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVSSUV4Y2VwdGlvbigKLSAgICAgICAgICBYTUxNZXNzYWdlcy5jcmVhdGVYTUxNZXNzYWdlKFhNTEVycm9yUmVzb3VyY2VzLkVSX05PX0ZSQUdNRU5UX1NUUklOR19JTl9QQVRILCBudWxsKSk7IC8vIkZyYWdtZW50IGNhbm5vdCBiZSBzcGVjaWZpZWQgaW4gYm90aCB0aGUgcGF0aCBhbmQgZnJhZ21lbnQhIik7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgc2V0U2NoZW1lKHBfc2NoZW1lKTsKLSAgICBzZXRIb3N0KHBfaG9zdCk7Ci0gICAgc2V0UG9ydChwX3BvcnQpOwotICAgIHNldFVzZXJpbmZvKHBfdXNlcmluZm8pOwotICAgIHNldFBhdGgocF9wYXRoKTsKLSAgICBzZXRRdWVyeVN0cmluZyhwX3F1ZXJ5U3RyaW5nKTsKLSAgICBzZXRGcmFnbWVudChwX2ZyYWdtZW50KTsKLSAgfQotCi0gIC8qKgotICAgKiBJbml0aWFsaXplIGFsbCBmaWVsZHMgb2YgdGhpcyBVUkkgZnJvbSBhbm90aGVyIFVSSS4KLSAgICoKLSAgICogQHBhcmFtIHBfb3RoZXIgdGhlIFVSSSB0byBjb3B5IChjYW5ub3QgYmUgbnVsbCkKLSAgICovCi0gIHByaXZhdGUgdm9pZCBpbml0aWFsaXplKFVSSSBwX290aGVyKQotICB7Ci0KLSAgICBtX3NjaGVtZSA9IHBfb3RoZXIuZ2V0U2NoZW1lKCk7Ci0gICAgbV91c2VyaW5mbyA9IHBfb3RoZXIuZ2V0VXNlcmluZm8oKTsKLSAgICBtX2hvc3QgPSBwX290aGVyLmdldEhvc3QoKTsKLSAgICBtX3BvcnQgPSBwX290aGVyLmdldFBvcnQoKTsKLSAgICBtX3BhdGggPSBwX290aGVyLmdldFBhdGgoKTsKLSAgICBtX3F1ZXJ5U3RyaW5nID0gcF9vdGhlci5nZXRRdWVyeVN0cmluZygpOwotICAgIG1fZnJhZ21lbnQgPSBwX290aGVyLmdldEZyYWdtZW50KCk7Ci0gIH0KLQotICAvKioKLSAgICogSW5pdGlhbGl6ZXMgdGhpcyBVUkkgZnJvbSBhIGJhc2UgVVJJIGFuZCBhIFVSSSBzcGVjaWZpY2F0aW9uIHN0cmluZy4KLSAgICogU2VlIFJGQyAyMzk2IFNlY3Rpb24gNCBhbmQgQXBwZW5kaXggQiBmb3Igc3BlY2lmaWNhdGlvbnMgb24gcGFyc2luZwotICAgKiB0aGUgVVJJIGFuZCBTZWN0aW9uIDUgZm9yIHNwZWNpZmljYXRpb25zIG9uIHJlc29sdmluZyByZWxhdGl2ZSBVUklzCi0gICAqIGFuZCByZWxhdGl2ZSBwYXRocy4KLSAgICoKLSAgICogQHBhcmFtIHBfYmFzZSB0aGUgYmFzZSBVUkkgKG1heSBiZSBudWxsIGlmIHBfdXJpU3BlYyBpcyBhbiBhYnNvbHV0ZQotICAgKiAgICAgICAgICAgICAgIFVSSSkKLSAgICogQHBhcmFtIHBfdXJpU3BlYyB0aGUgVVJJIHNwZWMgc3RyaW5nIHdoaWNoIG1heSBiZSBhbiBhYnNvbHV0ZSBvcgotICAgKiAgICAgICAgICAgICAgICAgIHJlbGF0aXZlIFVSSSAoY2FuIG9ubHkgYmUgbnVsbC9lbXB0eSBpZiBwX2Jhc2UKLSAgICogICAgICAgICAgICAgICAgICBpcyBub3QgbnVsbCkKLSAgICoKLSAgICogQHRocm93cyBNYWxmb3JtZWRVUklFeGNlcHRpb24gaWYgcF9iYXNlIGlzIG51bGwgYW5kIHBfdXJpU3BlYwotICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpcyBub3QgYW4gYWJzb2x1dGUgVVJJIG9yIGlmCi0gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBfdXJpU3BlYyB2aW9sYXRlcyBzeW50YXggcnVsZXMKLSAgICovCi0gIHByaXZhdGUgdm9pZCBpbml0aWFsaXplKFVSSSBwX2Jhc2UsIFN0cmluZyBwX3VyaVNwZWMpCi0gICAgICAgICAgdGhyb3dzIE1hbGZvcm1lZFVSSUV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAocF9iYXNlID09IG51bGwKLSAgICAgICAgICAgICYmIChwX3VyaVNwZWMgPT0gbnVsbCB8fCBwX3VyaVNwZWMudHJpbSgpLmxlbmd0aCgpID09IDApKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVUklFeGNlcHRpb24oCi0gICAgICAgIFhNTE1lc3NhZ2VzLmNyZWF0ZVhNTE1lc3NhZ2UoWE1MRXJyb3JSZXNvdXJjZXMuRVJfQ0FOTk9UX0lOSVRfVVJJX0VNUFRZX1BBUk1TLCBudWxsKSk7IC8vIkNhbm5vdCBpbml0aWFsaXplIFVSSSB3aXRoIGVtcHR5IHBhcmFtZXRlcnMuIik7Ci0gICAgfQotCi0gICAgLy8ganVzdCBtYWtlIGEgY29weSBvZiB0aGUgYmFzZSBpZiBzcGVjIGlzIGVtcHR5Ci0gICAgaWYgKHBfdXJpU3BlYyA9PSBudWxsIHx8IHBfdXJpU3BlYy50cmltKCkubGVuZ3RoKCkgPT0gMCkKLSAgICB7Ci0gICAgICBpbml0aWFsaXplKHBfYmFzZSk7Ci0KLSAgICAgIHJldHVybjsKLSAgICB9Ci0KLSAgICBTdHJpbmcgdXJpU3BlYyA9IHBfdXJpU3BlYy50cmltKCk7Ci0gICAgaW50IHVyaVNwZWNMZW4gPSB1cmlTcGVjLmxlbmd0aCgpOwotICAgIGludCBpbmRleCA9IDA7Ci0KLSAgICAvLyBjaGVjayBmb3Igc2NoZW1lCi0gICAgaW50IGNvbG9uSW5kZXggPSB1cmlTcGVjLmluZGV4T2YoJzonKTsKLSAgICBpZiAoY29sb25JbmRleCA8IDApCi0gICAgewotICAgICAgaWYgKHBfYmFzZSA9PSBudWxsKQotICAgICAgewotICAgICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVVJJRXhjZXB0aW9uKFhNTE1lc3NhZ2VzLmNyZWF0ZVhNTE1lc3NhZ2UoWE1MRXJyb3JSZXNvdXJjZXMuRVJfTk9fU0NIRU1FX0lOX1VSSSwgbmV3IE9iamVjdFtde3VyaVNwZWN9KSk7IC8vIk5vIHNjaGVtZSBmb3VuZCBpbiBVUkk6ICIrdXJpU3BlYyk7Ci0gICAgICB9Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBpbml0aWFsaXplU2NoZW1lKHVyaVNwZWMpOwotICAgICAgdXJpU3BlYyA9IHVyaVNwZWMuc3Vic3RyaW5nKGNvbG9uSW5kZXgrMSk7Ci0gICAgICAvLyBUaGlzIGlzIGEgZml4IGZvciBYQUxBTkotMjA1OS4KLSAgICAgIGlmKG1fc2NoZW1lICE9IG51bGwgJiYgcF9iYXNlICE9IG51bGwpCi0gICAgICB7Ci0gICAgICAgIC8vIGEpIElmIDx1cmlTcGVjPiBzdGFydHMgd2l0aCBhIHNsYXNoICgvKSwgaXQgbWVhbnMgPHVyaVNwZWM+IGlzIGFic29sdXRlCi0gICAgICAgIC8vICAgIGFuZCBwX2Jhc2UgY2FuIGJlIGlnbm9yZWQuCi0gICAgICAgIC8vICAgIEZvciBleGFtcGxlLAotICAgICAgICAvLyAgICB1cmlTcGVjID0gZmlsZTovbXlESVIvbXlYU0xGaWxlLnhzbAotICAgICAgICAvLyAgICBwX2Jhc2UgPSBmaWxlOi9teVdvcmsvCi0gICAgICAgIC8vCi0gICAgICAgIC8vICAgIEhlcmUsIHVyaVNwZWMgaGFzIGFic29sdXRlIHBhdGggYWZ0ZXIgc2NoZW1lIGZpbGUgYW5kIDoKLSAgICAgICAgLy8gICAgSGVuY2UgcF9iYXNlIGNhbiBiZSBpZ25vcmVkLgotICAgICAgICAvLwotICAgICAgICAvLyBiKSBTaW1pbGFyaWx5LCBhY2NvcmRpbmcgdG8gUkZDIDIzOTYsIHVyaSBpcyByZXNvbHZlZCBmb3IgPHVyaVNwZWM+IHJlbGF0aXZlIHRvIDxwX2Jhc2U+Ci0gICAgICAgIC8vICAgIGlmIHNjaGVtZSBpbiA8dXJpU3BlYz4gaXMgc2FtZSBhcyBzY2hlbWUgaW4gPHBfYmFzZT4sIGVsc2UgcF9iYXNlIGNhbiBiZSBpZ25vcmVkLgotICAgICAgICAvLwotICAgICAgICAvLyBjKSBpZiA8cF9iYXNlPiBpcyBub3QgaGllcmFyY2hpY2FsLCBpdCBjYW4gYmUgaWdub3JlZC4KLSAgICAgICAgLy8KLSAgICAgICAgaWYodXJpU3BlYy5zdGFydHNXaXRoKCIvIikgfHwgIW1fc2NoZW1lLmVxdWFscyhwX2Jhc2UubV9zY2hlbWUpIHx8ICFwX2Jhc2UuZ2V0U2NoZW1lU3BlY2lmaWNQYXJ0KCkuc3RhcnRzV2l0aCgiLyIpKQotICAgICAgICB7Ci0gICAgICAgICAgcF9iYXNlID0gbnVsbDsKLSAgICAgICAgfQotICAgICAgfQotICAgICAgLy8gRml4IGZvciBYQUxBTkotMjA1OQotICAgICAgdXJpU3BlY0xlbiA9IHVyaVNwZWMubGVuZ3RoKCk7Ci0gICAgfQotCi0gICAgLy8gdHdvIHNsYXNoZXMgbWVhbnMgZ2VuZXJpYyBVUkkgc3ludGF4LCBzbyB3ZSBnZXQgdGhlIGF1dGhvcml0eQotICAgIGlmICgoKGluZGV4ICsgMSkgPCB1cmlTcGVjTGVuKQotICAgICAgICAgICAgJiYgKHVyaVNwZWMuc3Vic3RyaW5nKGluZGV4KS5zdGFydHNXaXRoKCIvLyIpKSkKLSAgICB7Ci0gICAgICBpbmRleCArPSAyOwotCi0gICAgICBpbnQgc3RhcnRQb3MgPSBpbmRleDsKLQotICAgICAgLy8gZ2V0IGF1dGhvcml0eSAtIGV2ZXJ5dGhpbmcgdXAgdG8gcGF0aCwgcXVlcnkgb3IgZnJhZ21lbnQKLSAgICAgIGNoYXIgdGVzdENoYXIgPSAnXDAnOwotCi0gICAgICB3aGlsZSAoaW5kZXggPCB1cmlTcGVjTGVuKQotICAgICAgewotICAgICAgICB0ZXN0Q2hhciA9IHVyaVNwZWMuY2hhckF0KGluZGV4KTsKLQotICAgICAgICBpZiAodGVzdENoYXIgPT0gJy8nIHx8IHRlc3RDaGFyID09ICc/JyB8fCB0ZXN0Q2hhciA9PSAnIycpCi0gICAgICAgIHsKLSAgICAgICAgICBicmVhazsKLSAgICAgICAgfQotCi0gICAgICAgIGluZGV4Kys7Ci0gICAgICB9Ci0KLSAgICAgIC8vIGlmIHdlIGZvdW5kIGF1dGhvcml0eSwgcGFyc2UgaXQgb3V0LCBvdGhlcndpc2Ugd2Ugc2V0IHRoZQotICAgICAgLy8gaG9zdCB0byBlbXB0eSBzdHJpbmcKLSAgICAgIGlmIChpbmRleCA+IHN0YXJ0UG9zKQotICAgICAgewotICAgICAgICBpbml0aWFsaXplQXV0aG9yaXR5KHVyaVNwZWMuc3Vic3RyaW5nKHN0YXJ0UG9zLCBpbmRleCkpOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBtX2hvc3QgPSAiIjsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICBpbml0aWFsaXplUGF0aCh1cmlTcGVjLnN1YnN0cmluZyhpbmRleCkpOwotCi0gICAgLy8gUmVzb2x2ZSByZWxhdGl2ZSBVUkkgdG8gYmFzZSBVUkkgLSBzZWUgUkZDIDIzOTYgU2VjdGlvbiA1LjIKLSAgICAvLyBJbiBzb21lIGNhc2VzLCBpdCBtaWdodCBtYWtlIG1vcmUgc2Vuc2UgdG8gdGhyb3cgYW4gZXhjZXB0aW9uCi0gICAgLy8gKHdoZW4gc2NoZW1lIGlzIHNwZWNpZmllZCBpcyB0aGUgc3RyaW5nIHNwZWMgYW5kIHRoZSBiYXNlIFVSSQotICAgIC8vIGlzIGFsc28gc3BlY2lmaWVkLCBmb3IgZXhhbXBsZSksIGJ1dCB3ZSdyZSBqdXN0IGZvbGxvd2luZyB0aGUKLSAgICAvLyBSRkMgc3BlY2lmaWNhdGlvbnMKLSAgICBpZiAocF9iYXNlICE9IG51bGwpCi0gICAgewotCi0gICAgICAvLyBjaGVjayB0byBzZWUgaWYgdGhpcyBpcyB0aGUgY3VycmVudCBkb2MgLSBSRkMgMjM5NiA1LjIgIzIKLSAgICAgIC8vIG5vdGUgdGhhdCB0aGlzIGlzIHNsaWdodGx5IGRpZmZlcmVudCBmcm9tIHRoZSBSRkMgc3BlYyBpbiB0aGF0Ci0gICAgICAvLyB3ZSBkb24ndCBpbmNsdWRlIHRoZSBjaGVjayBmb3IgcXVlcnkgc3RyaW5nIGJlaW5nIG51bGwKLSAgICAgIC8vIC0gdGhpcyBoYW5kbGVzIGNhc2VzIHdoZXJlIHRoZSB1cmlzcGVjIGlzIGp1c3QgYSBxdWVyeQotICAgICAgLy8gc3RyaW5nIG9yIGEgZnJhZ21lbnQgKGUuZy4gIj95IiBvciAiI3MiKSAtCi0gICAgICAvLyBzZWUgPGh0dHA6Ly93d3cuaWNzLnVjaS5lZHUvfmZpZWxkaW5nL3VybC90ZXN0MS5odG1sPiB3aGljaAotICAgICAgLy8gaWRlbnRpZmllZCB0aGlzIGFzIGEgYnVnIGluIHRoZSBSRkMKLSAgICAgIGlmIChtX3BhdGgubGVuZ3RoKCkgPT0gMCAmJiBtX3NjaGVtZSA9PSBudWxsICYmIG1faG9zdCA9PSBudWxsKQotICAgICAgewotICAgICAgICBtX3NjaGVtZSA9IHBfYmFzZS5nZXRTY2hlbWUoKTsKLSAgICAgICAgbV91c2VyaW5mbyA9IHBfYmFzZS5nZXRVc2VyaW5mbygpOwotICAgICAgICBtX2hvc3QgPSBwX2Jhc2UuZ2V0SG9zdCgpOwotICAgICAgICBtX3BvcnQgPSBwX2Jhc2UuZ2V0UG9ydCgpOwotICAgICAgICBtX3BhdGggPSBwX2Jhc2UuZ2V0UGF0aCgpOwotCi0gICAgICAgIGlmIChtX3F1ZXJ5U3RyaW5nID09IG51bGwpCi0gICAgICAgIHsKLSAgICAgICAgICBtX3F1ZXJ5U3RyaW5nID0gcF9iYXNlLmdldFF1ZXJ5U3RyaW5nKCk7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm47Ci0gICAgICB9Ci0KLSAgICAgIC8vIGNoZWNrIGZvciBzY2hlbWUgLSBSRkMgMjM5NiA1LjIgIzMKLSAgICAgIC8vIGlmIHdlIGZvdW5kIGEgc2NoZW1lLCBpdCBtZWFucyBhYnNvbHV0ZSBVUkksIHNvIHdlJ3JlIGRvbmUKLSAgICAgIGlmIChtX3NjaGVtZSA9PSBudWxsKQotICAgICAgewotICAgICAgICBtX3NjaGVtZSA9IHBfYmFzZS5nZXRTY2hlbWUoKTsKLSAgICAgIH0KLQotICAgICAgLy8gY2hlY2sgZm9yIGF1dGhvcml0eSAtIFJGQyAyMzk2IDUuMiAjNAotICAgICAgLy8gaWYgd2UgZm91bmQgYSBob3N0LCB0aGVuIHdlJ3ZlIGdvdCBhIG5ldHdvcmsgcGF0aCwgc28gd2UncmUgZG9uZQotICAgICAgaWYgKG1faG9zdCA9PSBudWxsKQotICAgICAgewotICAgICAgICBtX3VzZXJpbmZvID0gcF9iYXNlLmdldFVzZXJpbmZvKCk7Ci0gICAgICAgIG1faG9zdCA9IHBfYmFzZS5nZXRIb3N0KCk7Ci0gICAgICAgIG1fcG9ydCA9IHBfYmFzZS5nZXRQb3J0KCk7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIHJldHVybjsKLSAgICAgIH0KLQotICAgICAgLy8gY2hlY2sgZm9yIGFic29sdXRlIHBhdGggLSBSRkMgMjM5NiA1LjIgIzUKLSAgICAgIGlmIChtX3BhdGgubGVuZ3RoKCkgPiAwICYmIG1fcGF0aC5zdGFydHNXaXRoKCIvIikpCi0gICAgICB7Ci0gICAgICAgIHJldHVybjsKLSAgICAgIH0KLQotICAgICAgLy8gaWYgd2UgZ2V0IHRvIHRoaXMgcG9pbnQsIHdlIG5lZWQgdG8gcmVzb2x2ZSByZWxhdGl2ZSBwYXRoCi0gICAgICAvLyBSRkMgMjM5NiA1LjIgIzYKLSAgICAgIFN0cmluZyBwYXRoID0gIiI7Ci0gICAgICBTdHJpbmcgYmFzZVBhdGggPSBwX2Jhc2UuZ2V0UGF0aCgpOwotCi0gICAgICAvLyA2YSAtIGdldCBhbGwgYnV0IHRoZSBsYXN0IHNlZ21lbnQgb2YgdGhlIGJhc2UgVVJJIHBhdGgKLSAgICAgIGlmIChiYXNlUGF0aCAhPSBudWxsKQotICAgICAgewotICAgICAgICBpbnQgbGFzdFNsYXNoID0gYmFzZVBhdGgubGFzdEluZGV4T2YoJy8nKTsKLQotICAgICAgICBpZiAobGFzdFNsYXNoICE9IC0xKQotICAgICAgICB7Ci0gICAgICAgICAgcGF0aCA9IGJhc2VQYXRoLnN1YnN0cmluZygwLCBsYXN0U2xhc2ggKyAxKTsKLSAgICAgICAgfQotICAgICAgfQotCi0gICAgICAvLyA2YiAtIGFwcGVuZCB0aGUgcmVsYXRpdmUgVVJJIHBhdGgKLSAgICAgIHBhdGggPSBwYXRoLmNvbmNhdChtX3BhdGgpOwotCi0gICAgICAvLyA2YyAtIHJlbW92ZSBhbGwgIi4vIiB3aGVyZSAiLiIgaXMgYSBjb21wbGV0ZSBwYXRoIHNlZ21lbnQKLSAgICAgIGluZGV4ID0gLTE7Ci0KLSAgICAgIHdoaWxlICgoaW5kZXggPSBwYXRoLmluZGV4T2YoIi8uLyIpKSAhPSAtMSkKLSAgICAgIHsKLSAgICAgICAgcGF0aCA9IHBhdGguc3Vic3RyaW5nKDAsIGluZGV4ICsgMSkuY29uY2F0KHBhdGguc3Vic3RyaW5nKGluZGV4ICsgMykpOwotICAgICAgfQotCi0gICAgICAvLyA2ZCAtIHJlbW92ZSAiLiIgaWYgcGF0aCBlbmRzIHdpdGggIi4iIGFzIGEgY29tcGxldGUgcGF0aCBzZWdtZW50Ci0gICAgICBpZiAocGF0aC5lbmRzV2l0aCgiLy4iKSkKLSAgICAgIHsKLSAgICAgICAgcGF0aCA9IHBhdGguc3Vic3RyaW5nKDAsIHBhdGgubGVuZ3RoKCkgLSAxKTsKLSAgICAgIH0KLQotICAgICAgLy8gNmUgLSByZW1vdmUgYWxsICI8c2VnbWVudD4vLi4vIiB3aGVyZSAiPHNlZ21lbnQ+IiBpcyBhIGNvbXBsZXRlCi0gICAgICAvLyBwYXRoIHNlZ21lbnQgbm90IGVxdWFsIHRvICIuLiIKLSAgICAgIGluZGV4ID0gLTE7Ci0KLSAgICAgIGludCBzZWdJbmRleCA9IC0xOwotICAgICAgU3RyaW5nIHRlbXBTdHJpbmcgPSBudWxsOwotCi0gICAgICB3aGlsZSAoKGluZGV4ID0gcGF0aC5pbmRleE9mKCIvLi4vIikpID4gMCkKLSAgICAgIHsKLSAgICAgICAgdGVtcFN0cmluZyA9IHBhdGguc3Vic3RyaW5nKDAsIHBhdGguaW5kZXhPZigiLy4uLyIpKTsKLSAgICAgICAgc2VnSW5kZXggPSB0ZW1wU3RyaW5nLmxhc3RJbmRleE9mKCcvJyk7Ci0KLSAgICAgICAgaWYgKHNlZ0luZGV4ICE9IC0xKQotICAgICAgICB7Ci0gICAgICAgICAgaWYgKCF0ZW1wU3RyaW5nLnN1YnN0cmluZyhzZWdJbmRleCsrKS5lcXVhbHMoIi4uIikpCi0gICAgICAgICAgewotICAgICAgICAgICAgcGF0aCA9IHBhdGguc3Vic3RyaW5nKDAsIHNlZ0luZGV4KS5jb25jYXQocGF0aC5zdWJzdHJpbmcoaW5kZXgKLSAgICAgICAgICAgICAgICAgICAgKyA0KSk7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICB9Ci0KLSAgICAgIC8vIDZmIC0gcmVtb3ZlIGVuZGluZyAiPHNlZ21lbnQ+Ly4uIiB3aGVyZSAiPHNlZ21lbnQ+IiBpcyBhCi0gICAgICAvLyBjb21wbGV0ZSBwYXRoIHNlZ21lbnQKLSAgICAgIGlmIChwYXRoLmVuZHNXaXRoKCIvLi4iKSkKLSAgICAgIHsKLSAgICAgICAgdGVtcFN0cmluZyA9IHBhdGguc3Vic3RyaW5nKDAsIHBhdGgubGVuZ3RoKCkgLSAzKTsKLSAgICAgICAgc2VnSW5kZXggPSB0ZW1wU3RyaW5nLmxhc3RJbmRleE9mKCcvJyk7Ci0KLSAgICAgICAgaWYgKHNlZ0luZGV4ICE9IC0xKQotICAgICAgICB7Ci0gICAgICAgICAgcGF0aCA9IHBhdGguc3Vic3RyaW5nKDAsIHNlZ0luZGV4ICsgMSk7Ci0gICAgICAgIH0KLSAgICAgIH0KLQotICAgICAgbV9wYXRoID0gcGF0aDsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogSW5pdGlhbGl6ZSB0aGUgc2NoZW1lIGZvciB0aGlzIFVSSSBmcm9tIGEgVVJJIHN0cmluZyBzcGVjLgotICAgKgotICAgKiBAcGFyYW0gcF91cmlTcGVjIHRoZSBVUkkgc3BlY2lmaWNhdGlvbiAoY2Fubm90IGJlIG51bGwpCi0gICAqCi0gICAqIEB0aHJvd3MgTWFsZm9ybWVkVVJJRXhjZXB0aW9uIGlmIFVSSSBkb2VzIG5vdCBoYXZlIGEgY29uZm9ybWFudAotICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2hlbWUKLSAgICovCi0gIHByaXZhdGUgdm9pZCBpbml0aWFsaXplU2NoZW1lKFN0cmluZyBwX3VyaVNwZWMpIHRocm93cyBNYWxmb3JtZWRVUklFeGNlcHRpb24KLSAgewotCi0gICAgaW50IHVyaVNwZWNMZW4gPSBwX3VyaVNwZWMubGVuZ3RoKCk7Ci0gICAgaW50IGluZGV4ID0gMDsKLSAgICBTdHJpbmcgc2NoZW1lID0gbnVsbDsKLSAgICBjaGFyIHRlc3RDaGFyID0gJ1wwJzsKLQotICAgIHdoaWxlIChpbmRleCA8IHVyaVNwZWNMZW4pCi0gICAgewotICAgICAgdGVzdENoYXIgPSBwX3VyaVNwZWMuY2hhckF0KGluZGV4KTsKLQotICAgICAgaWYgKHRlc3RDaGFyID09ICc6JyB8fCB0ZXN0Q2hhciA9PSAnLycgfHwgdGVzdENoYXIgPT0gJz8nCi0gICAgICAgICAgICAgIHx8IHRlc3RDaGFyID09ICcjJykKLSAgICAgIHsKLSAgICAgICAgYnJlYWs7Ci0gICAgICB9Ci0KLSAgICAgIGluZGV4Kys7Ci0gICAgfQotCi0gICAgc2NoZW1lID0gcF91cmlTcGVjLnN1YnN0cmluZygwLCBpbmRleCk7Ci0KLSAgICBpZiAoc2NoZW1lLmxlbmd0aCgpID09IDApCi0gICAgewotICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVSSUV4Y2VwdGlvbihYTUxNZXNzYWdlcy5jcmVhdGVYTUxNZXNzYWdlKFhNTEVycm9yUmVzb3VyY2VzLkVSX05PX1NDSEVNRV9JTlVSSSwgbnVsbCkpOyAvLyJObyBzY2hlbWUgZm91bmQgaW4gVVJJLiIpOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgc2V0U2NoZW1lKHNjaGVtZSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEluaXRpYWxpemUgdGhlIGF1dGhvcml0eSAodXNlcmluZm8sIGhvc3QgYW5kIHBvcnQpIGZvciB0aGlzCi0gICAqIFVSSSBmcm9tIGEgVVJJIHN0cmluZyBzcGVjLgotICAgKgotICAgKiBAcGFyYW0gcF91cmlTcGVjIHRoZSBVUkkgc3BlY2lmaWNhdGlvbiAoY2Fubm90IGJlIG51bGwpCi0gICAqCi0gICAqIEB0aHJvd3MgTWFsZm9ybWVkVVJJRXhjZXB0aW9uIGlmIHBfdXJpU3BlYyB2aW9sYXRlcyBzeW50YXggcnVsZXMKLSAgICovCi0gIHByaXZhdGUgdm9pZCBpbml0aWFsaXplQXV0aG9yaXR5KFN0cmluZyBwX3VyaVNwZWMpCi0gICAgICAgICAgdGhyb3dzIE1hbGZvcm1lZFVSSUV4Y2VwdGlvbgotICB7Ci0KLSAgICBpbnQgaW5kZXggPSAwOwotICAgIGludCBzdGFydCA9IDA7Ci0gICAgaW50IGVuZCA9IHBfdXJpU3BlYy5sZW5ndGgoKTsKLSAgICBjaGFyIHRlc3RDaGFyID0gJ1wwJzsKLSAgICBTdHJpbmcgdXNlcmluZm8gPSBudWxsOwotCi0gICAgLy8gdXNlcmluZm8gaXMgZXZlcnl0aGluZyB1cCBACi0gICAgaWYgKHBfdXJpU3BlYy5pbmRleE9mKCdAJywgc3RhcnQpICE9IC0xKQotICAgIHsKLSAgICAgIHdoaWxlIChpbmRleCA8IGVuZCkKLSAgICAgIHsKLSAgICAgICAgdGVzdENoYXIgPSBwX3VyaVNwZWMuY2hhckF0KGluZGV4KTsKLQotICAgICAgICBpZiAodGVzdENoYXIgPT0gJ0AnKQotICAgICAgICB7Ci0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIH0KLQotICAgICAgICBpbmRleCsrOwotICAgICAgfQotCi0gICAgICB1c2VyaW5mbyA9IHBfdXJpU3BlYy5zdWJzdHJpbmcoc3RhcnQsIGluZGV4KTsKLQotICAgICAgaW5kZXgrKzsKLSAgICB9Ci0KLSAgICAvLyBob3N0IGlzIGV2ZXJ5dGhpbmcgdXAgdG8gJzonCi0gICAgU3RyaW5nIGhvc3QgPSBudWxsOwotCi0gICAgc3RhcnQgPSBpbmRleDsKLQotICAgIHdoaWxlIChpbmRleCA8IGVuZCkKLSAgICB7Ci0gICAgICB0ZXN0Q2hhciA9IHBfdXJpU3BlYy5jaGFyQXQoaW5kZXgpOwotCi0gICAgICBpZiAodGVzdENoYXIgPT0gJzonKQotICAgICAgewotICAgICAgICBicmVhazsKLSAgICAgIH0KLQotICAgICAgaW5kZXgrKzsKLSAgICB9Ci0KLSAgICBob3N0ID0gcF91cmlTcGVjLnN1YnN0cmluZyhzdGFydCwgaW5kZXgpOwotCi0gICAgaW50IHBvcnQgPSAtMTsKLQotICAgIGlmIChob3N0Lmxlbmd0aCgpID4gMCkKLSAgICB7Ci0KLSAgICAgIC8vIHBvcnQKLSAgICAgIGlmICh0ZXN0Q2hhciA9PSAnOicpCi0gICAgICB7Ci0gICAgICAgIGluZGV4Kys7Ci0KLSAgICAgICAgc3RhcnQgPSBpbmRleDsKLQotICAgICAgICB3aGlsZSAoaW5kZXggPCBlbmQpCi0gICAgICAgIHsKLSAgICAgICAgICBpbmRleCsrOwotICAgICAgICB9Ci0KLSAgICAgICAgU3RyaW5nIHBvcnRTdHIgPSBwX3VyaVNwZWMuc3Vic3RyaW5nKHN0YXJ0LCBpbmRleCk7Ci0KLSAgICAgICAgaWYgKHBvcnRTdHIubGVuZ3RoKCkgPiAwKQotICAgICAgICB7Ci0gICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwb3J0U3RyLmxlbmd0aCgpOyBpKyspCi0gICAgICAgICAgewotICAgICAgICAgICAgaWYgKCFpc0RpZ2l0KHBvcnRTdHIuY2hhckF0KGkpKSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVSSUV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICBwb3J0U3RyICsgIiBpcyBpbnZhbGlkLiBQb3J0IHNob3VsZCBvbmx5IGNvbnRhaW4gZGlnaXRzISIpOwotICAgICAgICAgICAgfQotICAgICAgICAgIH0KLQotICAgICAgICAgIHRyeQotICAgICAgICAgIHsKLSAgICAgICAgICAgIHBvcnQgPSBJbnRlZ2VyLnBhcnNlSW50KHBvcnRTdHIpOwotICAgICAgICAgIH0KLSAgICAgICAgICBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIG5mZSkKLSAgICAgICAgICB7Ci0KLSAgICAgICAgICAgIC8vIGNhbid0IGhhcHBlbgotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLQotICAgIHNldEhvc3QoaG9zdCk7Ci0gICAgc2V0UG9ydChwb3J0KTsKLSAgICBzZXRVc2VyaW5mbyh1c2VyaW5mbyk7Ci0gIH0KLQotICAvKioKLSAgICogSW5pdGlhbGl6ZSB0aGUgcGF0aCBmb3IgdGhpcyBVUkkgZnJvbSBhIFVSSSBzdHJpbmcgc3BlYy4KLSAgICoKLSAgICogQHBhcmFtIHBfdXJpU3BlYyB0aGUgVVJJIHNwZWNpZmljYXRpb24gKGNhbm5vdCBiZSBudWxsKQotICAgKgotICAgKiBAdGhyb3dzIE1hbGZvcm1lZFVSSUV4Y2VwdGlvbiBpZiBwX3VyaVNwZWMgdmlvbGF0ZXMgc3ludGF4IHJ1bGVzCi0gICAqLwotICBwcml2YXRlIHZvaWQgaW5pdGlhbGl6ZVBhdGgoU3RyaW5nIHBfdXJpU3BlYykgdGhyb3dzIE1hbGZvcm1lZFVSSUV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAocF91cmlTcGVjID09IG51bGwpCi0gICAgewotICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVSSUV4Y2VwdGlvbigKLSAgICAgICAgIkNhbm5vdCBpbml0aWFsaXplIHBhdGggZnJvbSBudWxsIHN0cmluZyEiKTsKLSAgICB9Ci0KLSAgICBpbnQgaW5kZXggPSAwOwotICAgIGludCBzdGFydCA9IDA7Ci0gICAgaW50IGVuZCA9IHBfdXJpU3BlYy5sZW5ndGgoKTsKLSAgICBjaGFyIHRlc3RDaGFyID0gJ1wwJzsKLQotICAgIC8vIHBhdGggLSBldmVyeXRoaW5nIHVwIHRvIHF1ZXJ5IHN0cmluZyBvciBmcmFnbWVudAotICAgIHdoaWxlIChpbmRleCA8IGVuZCkKLSAgICB7Ci0gICAgICB0ZXN0Q2hhciA9IHBfdXJpU3BlYy5jaGFyQXQoaW5kZXgpOwotCi0gICAgICBpZiAodGVzdENoYXIgPT0gJz8nIHx8IHRlc3RDaGFyID09ICcjJykKLSAgICAgIHsKLSAgICAgICAgYnJlYWs7Ci0gICAgICB9Ci0KLSAgICAgIC8vIGNoZWNrIGZvciB2YWxpZCBlc2NhcGUgc2VxdWVuY2UKLSAgICAgIGlmICh0ZXN0Q2hhciA9PSAnJScpCi0gICAgICB7Ci0gICAgICAgIGlmIChpbmRleCArIDIgPj0gZW5kIHx8IWlzSGV4KHBfdXJpU3BlYy5jaGFyQXQoaW5kZXggKyAxKSkKLSAgICAgICAgICAgICAgICB8fCFpc0hleChwX3VyaVNwZWMuY2hhckF0KGluZGV4ICsgMikpKQotICAgICAgICB7Ci0gICAgICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVSSUV4Y2VwdGlvbigKLSAgICAgICAgICAgIFhNTE1lc3NhZ2VzLmNyZWF0ZVhNTE1lc3NhZ2UoWE1MRXJyb3JSZXNvdXJjZXMuRVJfUEFUSF9DT05UQUlOU19JTlZBTElEX0VTQ0FQRV9TRVFVRU5DRSwgbnVsbCkpOyAvLyJQYXRoIGNvbnRhaW5zIGludmFsaWQgZXNjYXBlIHNlcXVlbmNlISIpOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmICghaXNSZXNlcnZlZENoYXJhY3Rlcih0ZXN0Q2hhcikKLSAgICAgICAgICAgICAgICYmIWlzVW5yZXNlcnZlZENoYXJhY3Rlcih0ZXN0Q2hhcikpCi0gICAgICB7Ci0gICAgICAgIGlmICgnXFwnICE9IHRlc3RDaGFyKQotICAgICAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVUklFeGNlcHRpb24oWE1MTWVzc2FnZXMuY3JlYXRlWE1MTWVzc2FnZShYTUxFcnJvclJlc291cmNlcy5FUl9QQVRIX0lOVkFMSURfQ0hBUiwgbmV3IE9iamVjdFtde1N0cmluZy52YWx1ZU9mKHRlc3RDaGFyKX0pKTsgLy8iUGF0aCBjb250YWlucyBpbnZhbGlkIGNoYXJhY3RlcjogIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8rIHRlc3RDaGFyKTsKLSAgICAgIH0KLQotICAgICAgaW5kZXgrKzsKLSAgICB9Ci0KLSAgICBtX3BhdGggPSBwX3VyaVNwZWMuc3Vic3RyaW5nKHN0YXJ0LCBpbmRleCk7Ci0KLSAgICAvLyBxdWVyeSAtIHN0YXJ0cyB3aXRoID8gYW5kIHVwIHRvIGZyYWdtZW50IG9yIGVuZAotICAgIGlmICh0ZXN0Q2hhciA9PSAnPycpCi0gICAgewotICAgICAgaW5kZXgrKzsKLQotICAgICAgc3RhcnQgPSBpbmRleDsKLQotICAgICAgd2hpbGUgKGluZGV4IDwgZW5kKQotICAgICAgewotICAgICAgICB0ZXN0Q2hhciA9IHBfdXJpU3BlYy5jaGFyQXQoaW5kZXgpOwotCi0gICAgICAgIGlmICh0ZXN0Q2hhciA9PSAnIycpCi0gICAgICAgIHsKLSAgICAgICAgICBicmVhazsKLSAgICAgICAgfQotCi0gICAgICAgIGlmICh0ZXN0Q2hhciA9PSAnJScpCi0gICAgICAgIHsKLSAgICAgICAgICBpZiAoaW5kZXggKyAyID49IGVuZCB8fCFpc0hleChwX3VyaVNwZWMuY2hhckF0KGluZGV4ICsgMSkpCi0gICAgICAgICAgICAgICAgICB8fCFpc0hleChwX3VyaVNwZWMuY2hhckF0KGluZGV4ICsgMikpKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVUklFeGNlcHRpb24oCi0gICAgICAgICAgICAgICJRdWVyeSBzdHJpbmcgY29udGFpbnMgaW52YWxpZCBlc2NhcGUgc2VxdWVuY2UhIik7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKCFpc1Jlc2VydmVkQ2hhcmFjdGVyKHRlc3RDaGFyKQotICAgICAgICAgICAgICAgICAmJiFpc1VucmVzZXJ2ZWRDaGFyYWN0ZXIodGVzdENoYXIpKQotICAgICAgICB7Ci0gICAgICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVSSUV4Y2VwdGlvbigKLSAgICAgICAgICAgICJRdWVyeSBzdHJpbmcgY29udGFpbnMgaW52YWxpZCBjaGFyYWN0ZXI6IiArIHRlc3RDaGFyKTsKLSAgICAgICAgfQotCi0gICAgICAgIGluZGV4Kys7Ci0gICAgICB9Ci0KLSAgICAgIG1fcXVlcnlTdHJpbmcgPSBwX3VyaVNwZWMuc3Vic3RyaW5nKHN0YXJ0LCBpbmRleCk7Ci0gICAgfQotCi0gICAgLy8gZnJhZ21lbnQgLSBzdGFydHMgd2l0aCAjCi0gICAgaWYgKHRlc3RDaGFyID09ICcjJykKLSAgICB7Ci0gICAgICBpbmRleCsrOwotCi0gICAgICBzdGFydCA9IGluZGV4OwotCi0gICAgICB3aGlsZSAoaW5kZXggPCBlbmQpCi0gICAgICB7Ci0gICAgICAgIHRlc3RDaGFyID0gcF91cmlTcGVjLmNoYXJBdChpbmRleCk7Ci0KLSAgICAgICAgaWYgKHRlc3RDaGFyID09ICclJykKLSAgICAgICAgewotICAgICAgICAgIGlmIChpbmRleCArIDIgPj0gZW5kIHx8IWlzSGV4KHBfdXJpU3BlYy5jaGFyQXQoaW5kZXggKyAxKSkKLSAgICAgICAgICAgICAgICAgIHx8IWlzSGV4KHBfdXJpU3BlYy5jaGFyQXQoaW5kZXggKyAyKSkpCi0gICAgICAgICAgewotICAgICAgICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVSSUV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgIkZyYWdtZW50IGNvbnRhaW5zIGludmFsaWQgZXNjYXBlIHNlcXVlbmNlISIpOwotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICghaXNSZXNlcnZlZENoYXJhY3Rlcih0ZXN0Q2hhcikKLSAgICAgICAgICAgICAgICAgJiYhaXNVbnJlc2VydmVkQ2hhcmFjdGVyKHRlc3RDaGFyKSkKLSAgICAgICAgewotICAgICAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVUklFeGNlcHRpb24oCi0gICAgICAgICAgICAiRnJhZ21lbnQgY29udGFpbnMgaW52YWxpZCBjaGFyYWN0ZXI6IiArIHRlc3RDaGFyKTsKLSAgICAgICAgfQotCi0gICAgICAgIGluZGV4Kys7Ci0gICAgICB9Ci0KLSAgICAgIG1fZnJhZ21lbnQgPSBwX3VyaVNwZWMuc3Vic3RyaW5nKHN0YXJ0LCBpbmRleCk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgc2NoZW1lIGZvciB0aGlzIFVSSS4KLSAgICoKLSAgICogQHJldHVybiB0aGUgc2NoZW1lIGZvciB0aGlzIFVSSQotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRTY2hlbWUoKQotICB7Ci0gICAgcmV0dXJuIG1fc2NoZW1lOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgc2NoZW1lLXNwZWNpZmljIHBhcnQgZm9yIHRoaXMgVVJJIChldmVyeXRoaW5nIGZvbGxvd2luZyB0aGUKLSAgICogc2NoZW1lIGFuZCB0aGUgZmlyc3QgY29sb24pLiBTZWUgUkZDIDIzOTYgU2VjdGlvbiA1LjIgZm9yIHNwZWMuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIHNjaGVtZS1zcGVjaWZpYyBwYXJ0IGZvciB0aGlzIFVSSQotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRTY2hlbWVTcGVjaWZpY1BhcnQoKQotICB7Ci0KLSAgICBmaW5hbCBTdHJpbmdCdWlsZGVyIHNjaGVtZXNwZWMgPSBuZXcgU3RyaW5nQnVpbGRlcigpOwotCi0gICAgaWYgKG1fdXNlcmluZm8gIT0gbnVsbCB8fCBtX2hvc3QgIT0gbnVsbCB8fCBtX3BvcnQgIT0gLTEpCi0gICAgewotICAgICAgc2NoZW1lc3BlYy5hcHBlbmQoIi8vIik7Ci0gICAgfQotCi0gICAgaWYgKG1fdXNlcmluZm8gIT0gbnVsbCkKLSAgICB7Ci0gICAgICBzY2hlbWVzcGVjLmFwcGVuZChtX3VzZXJpbmZvKTsKLSAgICAgIHNjaGVtZXNwZWMuYXBwZW5kKCdAJyk7Ci0gICAgfQotCi0gICAgaWYgKG1faG9zdCAhPSBudWxsKQotICAgIHsKLSAgICAgIHNjaGVtZXNwZWMuYXBwZW5kKG1faG9zdCk7Ci0gICAgfQotCi0gICAgaWYgKG1fcG9ydCAhPSAtMSkKLSAgICB7Ci0gICAgICBzY2hlbWVzcGVjLmFwcGVuZCgnOicpOwotICAgICAgc2NoZW1lc3BlYy5hcHBlbmQobV9wb3J0KTsKLSAgICB9Ci0KLSAgICBpZiAobV9wYXRoICE9IG51bGwpCi0gICAgewotICAgICAgc2NoZW1lc3BlYy5hcHBlbmQoKG1fcGF0aCkpOwotICAgIH0KLQotICAgIGlmIChtX3F1ZXJ5U3RyaW5nICE9IG51bGwpCi0gICAgewotICAgICAgc2NoZW1lc3BlYy5hcHBlbmQoJz8nKTsKLSAgICAgIHNjaGVtZXNwZWMuYXBwZW5kKG1fcXVlcnlTdHJpbmcpOwotICAgIH0KLQotICAgIGlmIChtX2ZyYWdtZW50ICE9IG51bGwpCi0gICAgewotICAgICAgc2NoZW1lc3BlYy5hcHBlbmQoJyMnKTsKLSAgICAgIHNjaGVtZXNwZWMuYXBwZW5kKG1fZnJhZ21lbnQpOwotICAgIH0KLQotICAgIHJldHVybiBzY2hlbWVzcGVjLnRvU3RyaW5nKCk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSB1c2VyaW5mbyBmb3IgdGhpcyBVUkkuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIHVzZXJpbmZvIGZvciB0aGlzIFVSSSAobnVsbCBpZiBub3Qgc3BlY2lmaWVkKS4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0VXNlcmluZm8oKQotICB7Ci0gICAgcmV0dXJuIG1fdXNlcmluZm87Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBob3N0IGZvciB0aGlzIFVSSS4KLSAgICoKLSAgICogQHJldHVybiB0aGUgaG9zdCBmb3IgdGhpcyBVUkkgKG51bGwgaWYgbm90IHNwZWNpZmllZCkuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldEhvc3QoKQotICB7Ci0gICAgcmV0dXJuIG1faG9zdDsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIHBvcnQgZm9yIHRoaXMgVVJJLgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBwb3J0IGZvciB0aGlzIFVSSSAoLTEgaWYgbm90IHNwZWNpZmllZCkuCi0gICAqLwotICBwdWJsaWMgaW50IGdldFBvcnQoKQotICB7Ci0gICAgcmV0dXJuIG1fcG9ydDsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIHBhdGggZm9yIHRoaXMgVVJJIChvcHRpb25hbGx5IHdpdGggdGhlIHF1ZXJ5IHN0cmluZyBhbmQKLSAgICogZnJhZ21lbnQpLgotICAgKgotICAgKiBAcGFyYW0gcF9pbmNsdWRlUXVlcnlTdHJpbmcgaWYgdHJ1ZSAoYW5kIHF1ZXJ5IHN0cmluZyBpcyBub3QgbnVsbCksCi0gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGEgIj8iIGZvbGxvd2VkIGJ5IHRoZSBxdWVyeSBzdHJpbmcKLSAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpbGwgYmUgYXBwZW5kZWQKLSAgICogQHBhcmFtIHBfaW5jbHVkZUZyYWdtZW50IGlmIHRydWUgKGFuZCBmcmFnbWVudCBpcyBub3QgbnVsbCksCi0gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVuIGEgIiMiIGZvbGxvd2VkIGJ5IHRoZSBmcmFnbWVudAotICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lsbCBiZSBhcHBlbmRlZAotICAgKgotICAgKiBAcmV0dXJuIHRoZSBwYXRoIGZvciB0aGlzIFVSSSBwb3NzaWJseSBpbmNsdWRpbmcgdGhlIHF1ZXJ5IHN0cmluZwotICAgKiAgICAgICAgIGFuZCBmcmFnbWVudAotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRQYXRoKGJvb2xlYW4gcF9pbmNsdWRlUXVlcnlTdHJpbmcsCi0gICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIHBfaW5jbHVkZUZyYWdtZW50KQotICB7Ci0KLSAgICBmaW5hbCBTdHJpbmdCdWlsZGVyIHBhdGhTdHJpbmcgPSBuZXcgU3RyaW5nQnVpbGRlcihtX3BhdGgpOwotCi0gICAgaWYgKHBfaW5jbHVkZVF1ZXJ5U3RyaW5nICYmIG1fcXVlcnlTdHJpbmcgIT0gbnVsbCkKLSAgICB7Ci0gICAgICBwYXRoU3RyaW5nLmFwcGVuZCgnPycpOwotICAgICAgcGF0aFN0cmluZy5hcHBlbmQobV9xdWVyeVN0cmluZyk7Ci0gICAgfQotCi0gICAgaWYgKHBfaW5jbHVkZUZyYWdtZW50ICYmIG1fZnJhZ21lbnQgIT0gbnVsbCkKLSAgICB7Ci0gICAgICBwYXRoU3RyaW5nLmFwcGVuZCgnIycpOwotICAgICAgcGF0aFN0cmluZy5hcHBlbmQobV9mcmFnbWVudCk7Ci0gICAgfQotCi0gICAgcmV0dXJuIHBhdGhTdHJpbmcudG9TdHJpbmcoKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIHBhdGggZm9yIHRoaXMgVVJJLiBOb3RlIHRoYXQgdGhlIHZhbHVlIHJldHVybmVkIGlzIHRoZSBwYXRoCi0gICAqIG9ubHkgYW5kIGRvZXMgbm90IGluY2x1ZGUgdGhlIHF1ZXJ5IHN0cmluZyBvciBmcmFnbWVudC4KLSAgICoKLSAgICogQHJldHVybiB0aGUgcGF0aCBmb3IgdGhpcyBVUkkuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFBhdGgoKQotICB7Ci0gICAgcmV0dXJuIG1fcGF0aDsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIHF1ZXJ5IHN0cmluZyBmb3IgdGhpcyBVUkkuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIHF1ZXJ5IHN0cmluZyBmb3IgdGhpcyBVUkkuIE51bGwgaXMgcmV0dXJuZWQgaWYgdGhlcmUKLSAgICogICAgICAgICB3YXMgbm8gIj8iIGluIHRoZSBVUkkgc3BlYywgZW1wdHkgc3RyaW5nIGlmIHRoZXJlIHdhcyBhCi0gICAqICAgICAgICAgIj8iIGJ1dCBubyBxdWVyeSBzdHJpbmcgZm9sbG93aW5nIGl0LgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRRdWVyeVN0cmluZygpCi0gIHsKLSAgICByZXR1cm4gbV9xdWVyeVN0cmluZzsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGZyYWdtZW50IGZvciB0aGlzIFVSSS4KLSAgICoKLSAgICogQHJldHVybiB0aGUgZnJhZ21lbnQgZm9yIHRoaXMgVVJJLiBOdWxsIGlzIHJldHVybmVkIGlmIHRoZXJlCi0gICAqICAgICAgICAgd2FzIG5vICIjIiBpbiB0aGUgVVJJIHNwZWMsIGVtcHR5IHN0cmluZyBpZiB0aGVyZSB3YXMgYQotICAgKiAgICAgICAgICIjIiBidXQgbm8gZnJhZ21lbnQgZm9sbG93aW5nIGl0LgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRGcmFnbWVudCgpCi0gIHsKLSAgICByZXR1cm4gbV9mcmFnbWVudDsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIHNjaGVtZSBmb3IgdGhpcyBVUkkuIFRoZSBzY2hlbWUgaXMgY29udmVydGVkIHRvIGxvd2VyY2FzZQotICAgKiBiZWZvcmUgaXQgaXMgc2V0LgotICAgKgotICAgKiBAcGFyYW0gcF9zY2hlbWUgdGhlIHNjaGVtZSBmb3IgdGhpcyBVUkkgKGNhbm5vdCBiZSBudWxsKQotICAgKgotICAgKiBAdGhyb3dzIE1hbGZvcm1lZFVSSUV4Y2VwdGlvbiBpZiBwX3NjaGVtZSBpcyBub3QgYSBjb25mb3JtYW50Ci0gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjaGVtZSBuYW1lCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRTY2hlbWUoU3RyaW5nIHBfc2NoZW1lKSB0aHJvd3MgTWFsZm9ybWVkVVJJRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChwX3NjaGVtZSA9PSBudWxsKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVUklFeGNlcHRpb24oWE1MTWVzc2FnZXMuY3JlYXRlWE1MTWVzc2FnZShYTUxFcnJvclJlc291cmNlcy5FUl9TQ0hFTUVfRlJPTV9OVUxMX1NUUklORywgbnVsbCkpOyAvLyJDYW5ub3Qgc2V0IHNjaGVtZSBmcm9tIG51bGwgc3RyaW5nISIpOwotICAgIH0KLQotICAgIGlmICghaXNDb25mb3JtYW50U2NoZW1lTmFtZShwX3NjaGVtZSkpCi0gICAgewotICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVSSUV4Y2VwdGlvbihYTUxNZXNzYWdlcy5jcmVhdGVYTUxNZXNzYWdlKFhNTEVycm9yUmVzb3VyY2VzLkVSX1NDSEVNRV9OT1RfQ09ORk9STUFOVCwgbnVsbCkpOyAvLyJUaGUgc2NoZW1lIGlzIG5vdCBjb25mb3JtYW50LiIpOwotICAgIH0KLQotICAgIG1fc2NoZW1lID0gcF9zY2hlbWUudG9Mb3dlckNhc2UoKTsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIHVzZXJpbmZvIGZvciB0aGlzIFVSSS4gSWYgYSBub24tbnVsbCB2YWx1ZSBpcyBwYXNzZWQgaW4gYW5kCi0gICAqIHRoZSBob3N0IHZhbHVlIGlzIG51bGwsIHRoZW4gYW4gZXhjZXB0aW9uIGlzIHRocm93bi4KLSAgICoKLSAgICogQHBhcmFtIHBfdXNlcmluZm8gdGhlIHVzZXJpbmZvIGZvciB0aGlzIFVSSQotICAgKgotICAgKiBAdGhyb3dzIE1hbGZvcm1lZFVSSUV4Y2VwdGlvbiBpZiBwX3VzZXJpbmZvIGNvbnRhaW5zIGludmFsaWQKLSAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhcmFjdGVycwotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0VXNlcmluZm8oU3RyaW5nIHBfdXNlcmluZm8pIHRocm93cyBNYWxmb3JtZWRVUklFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKHBfdXNlcmluZm8gPT0gbnVsbCkKLSAgICB7Ci0gICAgICBtX3VzZXJpbmZvID0gbnVsbDsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIGlmIChtX2hvc3QgPT0gbnVsbCkKLSAgICAgIHsKLSAgICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVSSUV4Y2VwdGlvbigKLSAgICAgICAgICAiVXNlcmluZm8gY2Fubm90IGJlIHNldCB3aGVuIGhvc3QgaXMgbnVsbCEiKTsKLSAgICAgIH0KLQotICAgICAgLy8gdXNlcmluZm8gY2FuIGNvbnRhaW4gYWxwaGFudW1lcmljcywgbWFyayBjaGFyYWN0ZXJzLCBlc2NhcGVkCi0gICAgICAvLyBhbmQgJzsnLCc6JywnJicsJz0nLCcrJywnJCcsJywnCi0gICAgICBpbnQgaW5kZXggPSAwOwotICAgICAgaW50IGVuZCA9IHBfdXNlcmluZm8ubGVuZ3RoKCk7Ci0gICAgICBjaGFyIHRlc3RDaGFyID0gJ1wwJzsKLQotICAgICAgd2hpbGUgKGluZGV4IDwgZW5kKQotICAgICAgewotICAgICAgICB0ZXN0Q2hhciA9IHBfdXNlcmluZm8uY2hhckF0KGluZGV4KTsKLQotICAgICAgICBpZiAodGVzdENoYXIgPT0gJyUnKQotICAgICAgICB7Ci0gICAgICAgICAgaWYgKGluZGV4ICsgMiA+PSBlbmQgfHwhaXNIZXgocF91c2VyaW5mby5jaGFyQXQoaW5kZXggKyAxKSkKLSAgICAgICAgICAgICAgICAgIHx8IWlzSGV4KHBfdXNlcmluZm8uY2hhckF0KGluZGV4ICsgMikpKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVUklFeGNlcHRpb24oCi0gICAgICAgICAgICAgICJVc2VyaW5mbyBjb250YWlucyBpbnZhbGlkIGVzY2FwZSBzZXF1ZW5jZSEiKTsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoIWlzVW5yZXNlcnZlZENoYXJhY3Rlcih0ZXN0Q2hhcikKLSAgICAgICAgICAgICAgICAgJiYgVVNFUklORk9fQ0hBUkFDVEVSUy5pbmRleE9mKHRlc3RDaGFyKSA9PSAtMSkKLSAgICAgICAgewotICAgICAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVUklFeGNlcHRpb24oCi0gICAgICAgICAgICAiVXNlcmluZm8gY29udGFpbnMgaW52YWxpZCBjaGFyYWN0ZXI6IiArIHRlc3RDaGFyKTsKLSAgICAgICAgfQotCi0gICAgICAgIGluZGV4Kys7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgbV91c2VyaW5mbyA9IHBfdXNlcmluZm87Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBob3N0IGZvciB0aGlzIFVSSS4gSWYgbnVsbCBpcyBwYXNzZWQgaW4sIHRoZSB1c2VyaW5mbwotICAgKiBmaWVsZCBpcyBhbHNvIHNldCB0byBudWxsIGFuZCB0aGUgcG9ydCBpcyBzZXQgdG8gLTEuCi0gICAqCi0gICAqIEBwYXJhbSBwX2hvc3QgdGhlIGhvc3QgZm9yIHRoaXMgVVJJCi0gICAqCi0gICAqIEB0aHJvd3MgTWFsZm9ybWVkVVJJRXhjZXB0aW9uIGlmIHBfaG9zdCBpcyBub3QgYSB2YWxpZCBJUAotICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRyZXNzIG9yIEROUyBob3N0bmFtZS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldEhvc3QoU3RyaW5nIHBfaG9zdCkgdGhyb3dzIE1hbGZvcm1lZFVSSUV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAocF9ob3N0ID09IG51bGwgfHwgcF9ob3N0LnRyaW0oKS5sZW5ndGgoKSA9PSAwKQotICAgIHsKLSAgICAgIG1faG9zdCA9IHBfaG9zdDsKLSAgICAgIG1fdXNlcmluZm8gPSBudWxsOwotICAgICAgbV9wb3J0ID0gLTE7Ci0gICAgfQotICAgIGVsc2UgaWYgKCFpc1dlbGxGb3JtZWRBZGRyZXNzKHBfaG9zdCkpCi0gICAgewotICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVSSUV4Y2VwdGlvbihYTUxNZXNzYWdlcy5jcmVhdGVYTUxNZXNzYWdlKFhNTEVycm9yUmVzb3VyY2VzLkVSX0hPU1RfQUREUkVTU19OT1RfV0VMTEZPUk1FRCwgbnVsbCkpOyAvLyJIb3N0IGlzIG5vdCBhIHdlbGwgZm9ybWVkIGFkZHJlc3MhIik7Ci0gICAgfQotCi0gICAgbV9ob3N0ID0gcF9ob3N0OwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgcG9ydCBmb3IgdGhpcyBVUkkuIC0xIGlzIHVzZWQgdG8gaW5kaWNhdGUgdGhhdCB0aGUgcG9ydCBpcwotICAgKiBub3Qgc3BlY2lmaWVkLCBvdGhlcndpc2UgdmFsaWQgcG9ydCBudW1iZXJzIGFyZSAgYmV0d2VlbiAwIGFuZCA2NTUzNS4KLSAgICogSWYgYSB2YWxpZCBwb3J0IG51bWJlciBpcyBwYXNzZWQgaW4gYW5kIHRoZSBob3N0IGZpZWxkIGlzIG51bGwsCi0gICAqIGFuIGV4Y2VwdGlvbiBpcyB0aHJvd24uCi0gICAqCi0gICAqIEBwYXJhbSBwX3BvcnQgdGhlIHBvcnQgbnVtYmVyIGZvciB0aGlzIFVSSQotICAgKgotICAgKiBAdGhyb3dzIE1hbGZvcm1lZFVSSUV4Y2VwdGlvbiBpZiBwX3BvcnQgaXMgbm90IC0xIGFuZCBub3QgYQotICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWxpZCBwb3J0IG51bWJlcgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0UG9ydChpbnQgcF9wb3J0KSB0aHJvd3MgTWFsZm9ybWVkVVJJRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChwX3BvcnQgPj0gMCAmJiBwX3BvcnQgPD0gNjU1MzUpCi0gICAgewotICAgICAgaWYgKG1faG9zdCA9PSBudWxsKQotICAgICAgewotICAgICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVVJJRXhjZXB0aW9uKAotICAgICAgICAgIFhNTE1lc3NhZ2VzLmNyZWF0ZVhNTE1lc3NhZ2UoWE1MRXJyb3JSZXNvdXJjZXMuRVJfUE9SVF9XSEVOX0hPU1RfTlVMTCwgbnVsbCkpOyAvLyJQb3J0IGNhbm5vdCBiZSBzZXQgd2hlbiBob3N0IGlzIG51bGwhIik7Ci0gICAgICB9Ci0gICAgfQotICAgIGVsc2UgaWYgKHBfcG9ydCAhPSAtMSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVVJJRXhjZXB0aW9uKFhNTE1lc3NhZ2VzLmNyZWF0ZVhNTE1lc3NhZ2UoWE1MRXJyb3JSZXNvdXJjZXMuRVJfSU5WQUxJRF9QT1JULCBudWxsKSk7IC8vIkludmFsaWQgcG9ydCBudW1iZXIhIik7Ci0gICAgfQotCi0gICAgbV9wb3J0ID0gcF9wb3J0OwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgcGF0aCBmb3IgdGhpcyBVUkkuIElmIHRoZSBzdXBwbGllZCBwYXRoIGlzIG51bGwsIHRoZW4gdGhlCi0gICAqIHF1ZXJ5IHN0cmluZyBhbmQgZnJhZ21lbnQgYXJlIHNldCB0byBudWxsIGFzIHdlbGwuIElmIHRoZSBzdXBwbGllZAotICAgKiBwYXRoIGluY2x1ZGVzIGEgcXVlcnkgc3RyaW5nIGFuZC9vciBmcmFnbWVudCwgdGhlc2UgZmllbGRzIHdpbGwgYmUKLSAgICogcGFyc2VkIGFuZCBzZXQgYXMgd2VsbC4gTm90ZSB0aGF0LCBmb3IgVVJJcyBmb2xsb3dpbmcgdGhlICJnZW5lcmljCi0gICAqIFVSSSIgc3ludGF4LCB0aGUgcGF0aCBzcGVjaWZpZWQgc2hvdWxkIHN0YXJ0IHdpdGggYSBzbGFzaC4KLSAgICogRm9yIFVSSXMgdGhhdCBkbyBub3QgZm9sbG93IHRoZSBnZW5lcmljIFVSSSBzeW50YXgsIHRoaXMgbWV0aG9kCi0gICAqIHNldHMgdGhlIHNjaGVtZS1zcGVjaWZpYyBwYXJ0LgotICAgKgotICAgKiBAcGFyYW0gcF9wYXRoIHRoZSBwYXRoIGZvciB0aGlzIFVSSSAobWF5IGJlIG51bGwpCi0gICAqCi0gICAqIEB0aHJvd3MgTWFsZm9ybWVkVVJJRXhjZXB0aW9uIGlmIHBfcGF0aCBjb250YWlucyBpbnZhbGlkCi0gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYXJhY3RlcnMKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFBhdGgoU3RyaW5nIHBfcGF0aCkgdGhyb3dzIE1hbGZvcm1lZFVSSUV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAocF9wYXRoID09IG51bGwpCi0gICAgewotICAgICAgbV9wYXRoID0gbnVsbDsKLSAgICAgIG1fcXVlcnlTdHJpbmcgPSBudWxsOwotICAgICAgbV9mcmFnbWVudCA9IG51bGw7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBpbml0aWFsaXplUGF0aChwX3BhdGgpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBBcHBlbmQgdG8gdGhlIGVuZCBvZiB0aGUgcGF0aCBvZiB0aGlzIFVSSS4gSWYgdGhlIGN1cnJlbnQgcGF0aCBkb2VzCi0gICAqIG5vdCBlbmQgaW4gYSBzbGFzaCBhbmQgdGhlIHBhdGggdG8gYmUgYXBwZW5kZWQgZG9lcyBub3QgYmVnaW4gd2l0aAotICAgKiBhIHNsYXNoLCBhIHNsYXNoIHdpbGwgYmUgYXBwZW5kZWQgdG8gdGhlIGN1cnJlbnQgcGF0aCBiZWZvcmUgdGhlCi0gICAqIG5ldyBzZWdtZW50IGlzIGFkZGVkLiBBbHNvLCBpZiB0aGUgY3VycmVudCBwYXRoIGVuZHMgaW4gYSBzbGFzaAotICAgKiBhbmQgdGhlIG5ldyBzZWdtZW50IGJlZ2lucyB3aXRoIGEgc2xhc2gsIHRoZSBleHRyYSBzbGFzaCB3aWxsIGJlCi0gICAqIHJlbW92ZWQgYmVmb3JlIHRoZSBuZXcgc2VnbWVudCBpcyBhcHBlbmRlZC4KLSAgICoKLSAgICogQHBhcmFtIHBfYWRkVG9QYXRoIHRoZSBuZXcgc2VnbWVudCB0byBiZSBhZGRlZCB0byB0aGUgY3VycmVudCBwYXRoCi0gICAqCi0gICAqIEB0aHJvd3MgTWFsZm9ybWVkVVJJRXhjZXB0aW9uIGlmIHBfYWRkVG9QYXRoIGNvbnRhaW5zIHN5bnRheAotICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvcnMKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFwcGVuZFBhdGgoU3RyaW5nIHBfYWRkVG9QYXRoKSB0aHJvd3MgTWFsZm9ybWVkVVJJRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChwX2FkZFRvUGF0aCA9PSBudWxsIHx8IHBfYWRkVG9QYXRoLnRyaW0oKS5sZW5ndGgoKSA9PSAwKQotICAgIHsKLSAgICAgIHJldHVybjsKLSAgICB9Ci0KLSAgICBpZiAoIWlzVVJJU3RyaW5nKHBfYWRkVG9QYXRoKSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVVJJRXhjZXB0aW9uKFhNTE1lc3NhZ2VzLmNyZWF0ZVhNTE1lc3NhZ2UoWE1MRXJyb3JSZXNvdXJjZXMuRVJfUEFUSF9JTlZBTElEX0NIQVIsIG5ldyBPYmplY3RbXXtwX2FkZFRvUGF0aH0pKTsgLy8iUGF0aCBjb250YWlucyBpbnZhbGlkIGNoYXJhY3RlciEiKTsKLSAgICB9Ci0KLSAgICBpZiAobV9wYXRoID09IG51bGwgfHwgbV9wYXRoLnRyaW0oKS5sZW5ndGgoKSA9PSAwKQotICAgIHsKLSAgICAgIGlmIChwX2FkZFRvUGF0aC5zdGFydHNXaXRoKCIvIikpCi0gICAgICB7Ci0gICAgICAgIG1fcGF0aCA9IHBfYWRkVG9QYXRoOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBtX3BhdGggPSAiLyIgKyBwX2FkZFRvUGF0aDsKLSAgICAgIH0KLSAgICB9Ci0gICAgZWxzZSBpZiAobV9wYXRoLmVuZHNXaXRoKCIvIikpCi0gICAgewotICAgICAgaWYgKHBfYWRkVG9QYXRoLnN0YXJ0c1dpdGgoIi8iKSkKLSAgICAgIHsKLSAgICAgICAgbV9wYXRoID0gbV9wYXRoLmNvbmNhdChwX2FkZFRvUGF0aC5zdWJzdHJpbmcoMSkpOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBtX3BhdGggPSBtX3BhdGguY29uY2F0KHBfYWRkVG9QYXRoKTsKLSAgICAgIH0KLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIGlmIChwX2FkZFRvUGF0aC5zdGFydHNXaXRoKCIvIikpCi0gICAgICB7Ci0gICAgICAgIG1fcGF0aCA9IG1fcGF0aC5jb25jYXQocF9hZGRUb1BhdGgpOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBtX3BhdGggPSBtX3BhdGguY29uY2F0KCIvIiArIHBfYWRkVG9QYXRoKTsKLSAgICAgIH0KLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBxdWVyeSBzdHJpbmcgZm9yIHRoaXMgVVJJLiBBIG5vbi1udWxsIHZhbHVlIGlzIHZhbGlkIG9ubHkKLSAgICogaWYgdGhpcyBpcyBhbiBVUkkgY29uZm9ybWluZyB0byB0aGUgZ2VuZXJpYyBVUkkgc3ludGF4IGFuZAotICAgKiB0aGUgcGF0aCB2YWx1ZSBpcyBub3QgbnVsbC4KLSAgICoKLSAgICogQHBhcmFtIHBfcXVlcnlTdHJpbmcgdGhlIHF1ZXJ5IHN0cmluZyBmb3IgdGhpcyBVUkkKLSAgICoKLSAgICogQHRocm93cyBNYWxmb3JtZWRVUklFeGNlcHRpb24gaWYgcF9xdWVyeVN0cmluZyBpcyBub3QgbnVsbCBhbmQgdGhpcwotICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVUkkgZG9lcyBub3QgY29uZm9ybSB0byB0aGUgZ2VuZXJpYwotICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVUkkgc3ludGF4IG9yIGlmIHRoZSBwYXRoIGlzIG51bGwKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFF1ZXJ5U3RyaW5nKFN0cmluZyBwX3F1ZXJ5U3RyaW5nKQotICAgICAgICAgIHRocm93cyBNYWxmb3JtZWRVUklFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKHBfcXVlcnlTdHJpbmcgPT0gbnVsbCkKLSAgICB7Ci0gICAgICBtX3F1ZXJ5U3RyaW5nID0gbnVsbDsKLSAgICB9Ci0gICAgZWxzZSBpZiAoIWlzR2VuZXJpY1VSSSgpKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVUklFeGNlcHRpb24oCi0gICAgICAgICJRdWVyeSBzdHJpbmcgY2FuIG9ubHkgYmUgc2V0IGZvciBhIGdlbmVyaWMgVVJJISIpOwotICAgIH0KLSAgICBlbHNlIGlmIChnZXRQYXRoKCkgPT0gbnVsbCkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVVJJRXhjZXB0aW9uKAotICAgICAgICAiUXVlcnkgc3RyaW5nIGNhbm5vdCBiZSBzZXQgd2hlbiBwYXRoIGlzIG51bGwhIik7Ci0gICAgfQotICAgIGVsc2UgaWYgKCFpc1VSSVN0cmluZyhwX3F1ZXJ5U3RyaW5nKSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVVJJRXhjZXB0aW9uKAotICAgICAgICAiUXVlcnkgc3RyaW5nIGNvbnRhaW5zIGludmFsaWQgY2hhcmFjdGVyISIpOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgbV9xdWVyeVN0cmluZyA9IHBfcXVlcnlTdHJpbmc7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgZnJhZ21lbnQgZm9yIHRoaXMgVVJJLiBBIG5vbi1udWxsIHZhbHVlIGlzIHZhbGlkIG9ubHkKLSAgICogaWYgdGhpcyBpcyBhIFVSSSBjb25mb3JtaW5nIHRvIHRoZSBnZW5lcmljIFVSSSBzeW50YXggYW5kCi0gICAqIHRoZSBwYXRoIHZhbHVlIGlzIG5vdCBudWxsLgotICAgKgotICAgKiBAcGFyYW0gcF9mcmFnbWVudCB0aGUgZnJhZ21lbnQgZm9yIHRoaXMgVVJJCi0gICAqCi0gICAqIEB0aHJvd3MgTWFsZm9ybWVkVVJJRXhjZXB0aW9uIGlmIHBfZnJhZ21lbnQgaXMgbm90IG51bGwgYW5kIHRoaXMKLSAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVVJJIGRvZXMgbm90IGNvbmZvcm0gdG8gdGhlIGdlbmVyaWMKLSAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVVJJIHN5bnRheCBvciBpZiB0aGUgcGF0aCBpcyBudWxsCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRGcmFnbWVudChTdHJpbmcgcF9mcmFnbWVudCkgdGhyb3dzIE1hbGZvcm1lZFVSSUV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAocF9mcmFnbWVudCA9PSBudWxsKQotICAgIHsKLSAgICAgIG1fZnJhZ21lbnQgPSBudWxsOwotICAgIH0KLSAgICBlbHNlIGlmICghaXNHZW5lcmljVVJJKCkpCi0gICAgewotICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVSSUV4Y2VwdGlvbigKLSAgICAgICAgWE1MTWVzc2FnZXMuY3JlYXRlWE1MTWVzc2FnZShYTUxFcnJvclJlc291cmNlcy5FUl9GUkFHX0ZPUl9HRU5FUklDX1VSSSwgbnVsbCkpOyAvLyJGcmFnbWVudCBjYW4gb25seSBiZSBzZXQgZm9yIGEgZ2VuZXJpYyBVUkkhIik7Ci0gICAgfQotICAgIGVsc2UgaWYgKGdldFBhdGgoKSA9PSBudWxsKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVUklFeGNlcHRpb24oCi0gICAgICAgIFhNTE1lc3NhZ2VzLmNyZWF0ZVhNTE1lc3NhZ2UoWE1MRXJyb3JSZXNvdXJjZXMuRVJfRlJBR19XSEVOX1BBVEhfTlVMTCwgbnVsbCkpOyAvLyJGcmFnbWVudCBjYW5ub3QgYmUgc2V0IHdoZW4gcGF0aCBpcyBudWxsISIpOwotICAgIH0KLSAgICBlbHNlIGlmICghaXNVUklTdHJpbmcocF9mcmFnbWVudCkpCi0gICAgewotICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVSSUV4Y2VwdGlvbihYTUxNZXNzYWdlcy5jcmVhdGVYTUxNZXNzYWdlKFhNTEVycm9yUmVzb3VyY2VzLkVSX0ZSQUdfSU5WQUxJRF9DSEFSLCBudWxsKSk7IC8vIkZyYWdtZW50IGNvbnRhaW5zIGludmFsaWQgY2hhcmFjdGVyISIpOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgbV9mcmFnbWVudCA9IHBfZnJhZ21lbnQ7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIERldGVybWluZXMgaWYgdGhlIHBhc3NlZC1pbiBPYmplY3QgaXMgZXF1aXZhbGVudCB0byB0aGlzIFVSSS4KLSAgICoKLSAgICogQHBhcmFtIHBfdGVzdCB0aGUgT2JqZWN0IHRvIHRlc3QgZm9yIGVxdWFsaXR5LgotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYgcF90ZXN0IGlzIGEgVVJJIHdpdGggYWxsIHZhbHVlcyBlcXVhbCB0byB0aGlzCi0gICAqICAgICAgICAgVVJJLCBmYWxzZSBvdGhlcndpc2UKLSAgICovCi0gIEBPdmVycmlkZQotICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IHBfdGVzdCkKLSAgewotCi0gICAgaWYgKHBfdGVzdCBpbnN0YW5jZW9mIFVSSSkKLSAgICB7Ci0gICAgICBVUkkgdGVzdFVSSSA9IChVUkkpIHBfdGVzdDsKLQotICAgICAgaWYgKCgobV9zY2hlbWUgPT0gbnVsbCAmJiB0ZXN0VVJJLm1fc2NoZW1lID09IG51bGwpIHx8IChtX3NjaGVtZSAhPSBudWxsICYmIHRlc3RVUkkubV9zY2hlbWUgIT0gbnVsbCAmJiBtX3NjaGVtZS5lcXVhbHMoCi0gICAgICAgICAgICAgIHRlc3RVUkkubV9zY2hlbWUpKSkgJiYgKChtX3VzZXJpbmZvID09IG51bGwgJiYgdGVzdFVSSS5tX3VzZXJpbmZvID09IG51bGwpIHx8IChtX3VzZXJpbmZvICE9IG51bGwgJiYgdGVzdFVSSS5tX3VzZXJpbmZvICE9IG51bGwgJiYgbV91c2VyaW5mby5lcXVhbHMoCi0gICAgICAgICAgICAgIHRlc3RVUkkubV91c2VyaW5mbykpKSAmJiAoKG1faG9zdCA9PSBudWxsICYmIHRlc3RVUkkubV9ob3N0ID09IG51bGwpIHx8IChtX2hvc3QgIT0gbnVsbCAmJiB0ZXN0VVJJLm1faG9zdCAhPSBudWxsICYmIG1faG9zdC5lcXVhbHMoCi0gICAgICAgICAgICAgIHRlc3RVUkkubV9ob3N0KSkpICYmIG1fcG9ydCA9PSB0ZXN0VVJJLm1fcG9ydCAmJiAoKG1fcGF0aCA9PSBudWxsICYmIHRlc3RVUkkubV9wYXRoID09IG51bGwpIHx8IChtX3BhdGggIT0gbnVsbCAmJiB0ZXN0VVJJLm1fcGF0aCAhPSBudWxsICYmIG1fcGF0aC5lcXVhbHMoCi0gICAgICAgICAgICAgIHRlc3RVUkkubV9wYXRoKSkpICYmICgobV9xdWVyeVN0cmluZyA9PSBudWxsICYmIHRlc3RVUkkubV9xdWVyeVN0cmluZyA9PSBudWxsKSB8fCAobV9xdWVyeVN0cmluZyAhPSBudWxsICYmIHRlc3RVUkkubV9xdWVyeVN0cmluZyAhPSBudWxsICYmIG1fcXVlcnlTdHJpbmcuZXF1YWxzKAotICAgICAgICAgICAgICB0ZXN0VVJJLm1fcXVlcnlTdHJpbmcpKSkgJiYgKChtX2ZyYWdtZW50ID09IG51bGwgJiYgdGVzdFVSSS5tX2ZyYWdtZW50ID09IG51bGwpIHx8IChtX2ZyYWdtZW50ICE9IG51bGwgJiYgdGVzdFVSSS5tX2ZyYWdtZW50ICE9IG51bGwgJiYgbV9mcmFnbWVudC5lcXVhbHMoCi0gICAgICAgICAgICAgIHRlc3RVUkkubV9mcmFnbWVudCkpKSkKLSAgICAgIHsKLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgcmV0dXJuIGZhbHNlOwotICB9Ci0KLSAgQE92ZXJyaWRlCi0gIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7Ci0gICAgaW50IGhhc2ggPSA3OwotICAgIGhhc2ggPSA1OSAqIGhhc2ggKyBPYmplY3RzLmhhc2hDb2RlKHRoaXMubV9zY2hlbWUpOwotICAgIGhhc2ggPSA1OSAqIGhhc2ggKyBPYmplY3RzLmhhc2hDb2RlKHRoaXMubV91c2VyaW5mbyk7Ci0gICAgaGFzaCA9IDU5ICogaGFzaCArIE9iamVjdHMuaGFzaENvZGUodGhpcy5tX2hvc3QpOwotICAgIGhhc2ggPSA1OSAqIGhhc2ggKyB0aGlzLm1fcG9ydDsKLSAgICBoYXNoID0gNTkgKiBoYXNoICsgT2JqZWN0cy5oYXNoQ29kZSh0aGlzLm1fcGF0aCk7Ci0gICAgaGFzaCA9IDU5ICogaGFzaCArIE9iamVjdHMuaGFzaENvZGUodGhpcy5tX3F1ZXJ5U3RyaW5nKTsKLSAgICBoYXNoID0gNTkgKiBoYXNoICsgT2JqZWN0cy5oYXNoQ29kZSh0aGlzLm1fZnJhZ21lbnQpOwotICAgIHJldHVybiBoYXNoOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgVVJJIGFzIGEgc3RyaW5nIHNwZWNpZmljYXRpb24uIFNlZSBSRkMgMjM5NiBTZWN0aW9uIDUuMi4KLSAgICoKLSAgICogQHJldHVybiB0aGUgVVJJIHN0cmluZyBzcGVjaWZpY2F0aW9uCi0gICAqLwotICBAT3ZlcnJpZGUKLSAgcHVibGljIFN0cmluZyB0b1N0cmluZygpCi0gIHsKLQotICAgIGZpbmFsIFN0cmluZ0J1aWxkZXIgdXJpU3BlY1N0cmluZyA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7Ci0KLSAgICBpZiAobV9zY2hlbWUgIT0gbnVsbCkKLSAgICB7Ci0gICAgICB1cmlTcGVjU3RyaW5nLmFwcGVuZChtX3NjaGVtZSk7Ci0gICAgICB1cmlTcGVjU3RyaW5nLmFwcGVuZCgnOicpOwotICAgIH0KLQotICAgIHVyaVNwZWNTdHJpbmcuYXBwZW5kKGdldFNjaGVtZVNwZWNpZmljUGFydCgpKTsKLQotICAgIHJldHVybiB1cmlTcGVjU3RyaW5nLnRvU3RyaW5nKCk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBpbmRpY2F0b3IgYXMgdG8gd2hldGhlciB0aGlzIFVSSSB1c2VzIHRoZSAiZ2VuZXJpYyBVUkkiCi0gICAqIHN5bnRheC4KLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHRoaXMgVVJJIHVzZXMgdGhlICJnZW5lcmljIFVSSSIgc3ludGF4LCBmYWxzZQotICAgKiAgICAgICAgIG90aGVyd2lzZQotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNHZW5lcmljVVJJKCkKLSAgewotCi0gICAgLy8gcHJlc2VuY2Ugb2YgdGhlIGhvc3QgKHdoZXRoZXIgdmFsaWQgb3IgZW1wdHkpIG1lYW5zCi0gICAgLy8gZG91YmxlLXNsYXNoZXMgd2hpY2ggbWVhbnMgZ2VuZXJpYyB1cmkKLSAgICByZXR1cm4gKG1faG9zdCAhPSBudWxsKTsKLSAgfQotCi0gIC8qKgotICAgKiBEZXRlcm1pbmUgd2hldGhlciBhIHNjaGVtZSBjb25mb3JtcyB0byB0aGUgcnVsZXMgZm9yIGEgc2NoZW1lIG5hbWUuCi0gICAqIEEgc2NoZW1lIGlzIGNvbmZvcm1hbnQgaWYgaXQgc3RhcnRzIHdpdGggYW4gYWxwaGFudW1lcmljLCBhbmQKLSAgICogY29udGFpbnMgb25seSBhbHBoYW51bWVyaWNzLCAnKycsJy0nIGFuZCAnLicuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBwX3NjaGVtZSBUaGUgc2hlbWUgbmFtZSB0byBjaGVjawotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHNjaGVtZSBpcyBjb25mb3JtYW50LCBmYWxzZSBvdGhlcndpc2UKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0NvbmZvcm1hbnRTY2hlbWVOYW1lKFN0cmluZyBwX3NjaGVtZSkKLSAgewotCi0gICAgaWYgKHBfc2NoZW1lID09IG51bGwgfHwgcF9zY2hlbWUudHJpbSgpLmxlbmd0aCgpID09IDApCi0gICAgewotICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIGlmICghaXNBbHBoYShwX3NjaGVtZS5jaGFyQXQoMCkpKQotICAgIHsKLSAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICBjaGFyIHRlc3RDaGFyOwotCi0gICAgZm9yIChpbnQgaSA9IDE7IGkgPCBwX3NjaGVtZS5sZW5ndGgoKTsgaSsrKQotICAgIHsKLSAgICAgIHRlc3RDaGFyID0gcF9zY2hlbWUuY2hhckF0KGkpOwotCi0gICAgICBpZiAoIWlzQWxwaGFudW0odGVzdENoYXIpICYmIFNDSEVNRV9DSEFSQUNURVJTLmluZGV4T2YodGVzdENoYXIpID09IC0xKQotICAgICAgewotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgcmV0dXJuIHRydWU7Ci0gIH0KLQotICAvKioKLSAgICogRGV0ZXJtaW5lIHdoZXRoZXIgYSBzdHJpbmcgaXMgc3ludGFjdGljYWxseSBjYXBhYmxlIG9mIHJlcHJlc2VudGluZwotICAgKiBhIHZhbGlkIElQdjQgYWRkcmVzcyBvciB0aGUgZG9tYWluIG5hbWUgb2YgYSBuZXR3b3JrIGhvc3QuIEEgdmFsaWQKLSAgICogSVB2NCBhZGRyZXNzIGNvbnNpc3RzIG9mIGZvdXIgZGVjaW1hbCBkaWdpdCBncm91cHMgc2VwYXJhdGVkIGJ5IGEKLSAgICogJy4nLiBBIGhvc3RuYW1lIGNvbnNpc3RzIG9mIGRvbWFpbiBsYWJlbHMgKGVhY2ggb2Ygd2hpY2ggbXVzdAotICAgKiBiZWdpbiBhbmQgZW5kIHdpdGggYW4gYWxwaGFudW1lcmljIGJ1dCBtYXkgY29udGFpbiAnLScpIHNlcGFyYXRlZAotICAgKiAmIGJ5IGEgJy4nLiBTZWUgUkZDIDIzOTYgU2VjdGlvbiAzLjIuMi4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHBfYWRkcmVzcyBUaGUgYWRkcmVzcyBzdHJpbmcgdG8gY2hlY2sKLSAgICogQHJldHVybiB0cnVlIGlmIHRoZSBzdHJpbmcgaXMgYSBzeW50YWN0aWNhbGx5IHZhbGlkIElQdjQgYWRkcmVzcwotICAgKiAgICAgICAgICAgICAgb3IgaG9zdG5hbWUKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc1dlbGxGb3JtZWRBZGRyZXNzKFN0cmluZyBwX2FkZHJlc3MpCi0gIHsKLQotICAgIGlmIChwX2FkZHJlc3MgPT0gbnVsbCkKLSAgICB7Ci0gICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgU3RyaW5nIGFkZHJlc3MgPSBwX2FkZHJlc3MudHJpbSgpOwotICAgIGludCBhZGRyTGVuZ3RoID0gYWRkcmVzcy5sZW5ndGgoKTsKLQotICAgIGlmIChhZGRyTGVuZ3RoID09IDAgfHwgYWRkckxlbmd0aCA+IDI1NSkKLSAgICB7Ci0gICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgaWYgKGFkZHJlc3Muc3RhcnRzV2l0aCgiLiIpIHx8IGFkZHJlc3Muc3RhcnRzV2l0aCgiLSIpKQotICAgIHsKLSAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICAvLyByaWdodG1vc3QgZG9tYWluIGxhYmVsIHN0YXJ0aW5nIHdpdGggZGlnaXQgaW5kaWNhdGVzIElQIGFkZHJlc3MKLSAgICAvLyBzaW5jZSB0b3AgbGV2ZWwgZG9tYWluIGxhYmVsIGNhbiBvbmx5IHN0YXJ0IHdpdGggYW4gYWxwaGEKLSAgICAvLyBzZWUgUkZDIDIzOTYgU2VjdGlvbiAzLjIuMgotICAgIGludCBpbmRleCA9IGFkZHJlc3MubGFzdEluZGV4T2YoJy4nKTsKLQotICAgIGlmIChhZGRyZXNzLmVuZHNXaXRoKCIuIikpCi0gICAgewotICAgICAgaW5kZXggPSBhZGRyZXNzLnN1YnN0cmluZygwLCBpbmRleCkubGFzdEluZGV4T2YoJy4nKTsKLSAgICB9Ci0KLSAgICBpZiAoaW5kZXggKyAxIDwgYWRkckxlbmd0aCAmJiBpc0RpZ2l0KHBfYWRkcmVzcy5jaGFyQXQoaW5kZXggKyAxKSkpCi0gICAgewotICAgICAgY2hhciB0ZXN0Q2hhcjsKLSAgICAgIGludCBudW1Eb3RzID0gMDsKLQotICAgICAgLy8gbWFrZSBzdXJlIHRoYXQgMSkgd2Ugc2VlIG9ubHkgZGlnaXRzIGFuZCBkb3Qgc2VwYXJhdG9ycywgMikgdGhhdAotICAgICAgLy8gYW55IGRvdCBzZXBhcmF0b3IgaXMgcHJlY2VkZWQgYW5kIGZvbGxvd2VkIGJ5IGEgZGlnaXQgYW5kCi0gICAgICAvLyAzKSB0aGF0IHdlIGZpbmQgMyBkb3RzCi0gICAgICBmb3IgKGludCBpID0gMDsgaSA8IGFkZHJMZW5ndGg7IGkrKykKLSAgICAgIHsKLSAgICAgICAgdGVzdENoYXIgPSBhZGRyZXNzLmNoYXJBdChpKTsKLQotICAgICAgICBpZiAodGVzdENoYXIgPT0gJy4nKQotICAgICAgICB7Ci0gICAgICAgICAgaWYgKCFpc0RpZ2l0KGFkZHJlc3MuY2hhckF0KGkgLSAxKSkKLSAgICAgICAgICAgICAgICAgIHx8IChpICsgMSA8IGFkZHJMZW5ndGggJiYhaXNEaWdpdChhZGRyZXNzLmNoYXJBdChpICsgMSkpKSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgfQotCi0gICAgICAgICAgbnVtRG90cysrOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKCFpc0RpZ2l0KHRlc3RDaGFyKSkKLSAgICAgICAgewotICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotICAgICAgfQotCi0gICAgICBpZiAobnVtRG90cyAhPSAzKQotICAgICAgewotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICB9Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0KLSAgICAgIC8vIGRvbWFpbiBsYWJlbHMgY2FuIGNvbnRhaW4gYWxwaGFudW1lcmljcyBhbmQgJy0iCi0gICAgICAvLyBidXQgbXVzdCBzdGFydCBhbmQgZW5kIHdpdGggYW4gYWxwaGFudW1lcmljCi0gICAgICBjaGFyIHRlc3RDaGFyOwotCi0gICAgICBmb3IgKGludCBpID0gMDsgaSA8IGFkZHJMZW5ndGg7IGkrKykKLSAgICAgIHsKLSAgICAgICAgdGVzdENoYXIgPSBhZGRyZXNzLmNoYXJBdChpKTsKLQotICAgICAgICBpZiAodGVzdENoYXIgPT0gJy4nKQotICAgICAgICB7Ci0gICAgICAgICAgaWYgKCFpc0FscGhhbnVtKGFkZHJlc3MuY2hhckF0KGkgLSAxKSkpCi0gICAgICAgICAgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgIH0KLQotICAgICAgICAgIGlmIChpICsgMSA8IGFkZHJMZW5ndGggJiYhaXNBbHBoYW51bShhZGRyZXNzLmNoYXJBdChpICsgMSkpKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoIWlzQWxwaGFudW0odGVzdENoYXIpICYmIHRlc3RDaGFyICE9ICctJykKLSAgICAgICAgewotICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiB0cnVlOwotICB9Ci0KLSAgLyoqCi0gICAqIERldGVybWluZSB3aGV0aGVyIGEgY2hhciBpcyBhIGRpZ2l0LgotICAgKgotICAgKgotICAgKiBAcGFyYW0gcF9jaGFyIHRoZSBjaGFyYWN0ZXIgdG8gY2hlY2sKLSAgICogQHJldHVybiB0cnVlIGlmIHRoZSBjaGFyIGlzIGJldHdlZWVuICcwJyBhbmQgJzknLCBmYWxzZSBvdGhlcndpc2UKLSAgICovCi0gIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNEaWdpdChjaGFyIHBfY2hhcikKLSAgewotICAgIHJldHVybiBwX2NoYXIgPj0gJzAnICYmIHBfY2hhciA8PSAnOSc7Ci0gIH0KLQotICAvKioKLSAgICogRGV0ZXJtaW5lIHdoZXRoZXIgYSBjaGFyYWN0ZXIgaXMgYSBoZXhhZGVjaW1hbCBjaGFyYWN0ZXIuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBwX2NoYXIgdGhlIGNoYXJhY3RlciB0byBjaGVjawotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGNoYXIgaXMgYmV0d2VlZW4gJzAnIGFuZCAnOScsICdhJyBhbmQgJ2YnCi0gICAqICAgICAgICAgb3IgJ0EnIGFuZCAnRicsIGZhbHNlIG90aGVyd2lzZQotICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBpc0hleChjaGFyIHBfY2hhcikKLSAgewotICAgIHJldHVybiAoaXNEaWdpdChwX2NoYXIpIHx8IChwX2NoYXIgPj0gJ2EnICYmIHBfY2hhciA8PSAnZicpCi0gICAgICAgICAgICB8fCAocF9jaGFyID49ICdBJyAmJiBwX2NoYXIgPD0gJ0YnKSk7Ci0gIH0KLQotICAvKioKLSAgICogRGV0ZXJtaW5lIHdoZXRoZXIgYSBjaGFyIGlzIGFuIGFscGhhYmV0aWMgY2hhcmFjdGVyOiBhLXogb3IgQS1aCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBwX2NoYXIgdGhlIGNoYXJhY3RlciB0byBjaGVjawotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGNoYXIgaXMgYWxwaGFiZXRpYywgZmFsc2Ugb3RoZXJ3aXNlCi0gICAqLwotICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGlzQWxwaGEoY2hhciBwX2NoYXIpCi0gIHsKLSAgICByZXR1cm4gKChwX2NoYXIgPj0gJ2EnICYmIHBfY2hhciA8PSAneicpCi0gICAgICAgICAgICB8fCAocF9jaGFyID49ICdBJyAmJiBwX2NoYXIgPD0gJ1onKSk7Ci0gIH0KLQotICAvKioKLSAgICogRGV0ZXJtaW5lIHdoZXRoZXIgYSBjaGFyIGlzIGFuIGFscGhhbnVtZXJpYzogMC05LCBhLXogb3IgQS1aCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBwX2NoYXIgdGhlIGNoYXJhY3RlciB0byBjaGVjawotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGNoYXIgaXMgYWxwaGFudW1lcmljLCBmYWxzZSBvdGhlcndpc2UKLSAgICovCi0gIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNBbHBoYW51bShjaGFyIHBfY2hhcikKLSAgewotICAgIHJldHVybiAoaXNBbHBoYShwX2NoYXIpIHx8IGlzRGlnaXQocF9jaGFyKSk7Ci0gIH0KLQotICAvKioKLSAgICogRGV0ZXJtaW5lIHdoZXRoZXIgYSBjaGFyYWN0ZXIgaXMgYSByZXNlcnZlZCBjaGFyYWN0ZXI6Ci0gICAqICc7JywgJy8nLCAnPycsICc6JywgJ0AnLCAnJicsICc9JywgJysnLCAnJCcgb3IgJywnCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBwX2NoYXIgdGhlIGNoYXJhY3RlciB0byBjaGVjawotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHN0cmluZyBjb250YWlucyBhbnkgcmVzZXJ2ZWQgY2hhcmFjdGVycwotICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBpc1Jlc2VydmVkQ2hhcmFjdGVyKGNoYXIgcF9jaGFyKQotICB7Ci0gICAgcmV0dXJuIFJFU0VSVkVEX0NIQVJBQ1RFUlMuaW5kZXhPZihwX2NoYXIpICE9IC0xOwotICB9Ci0KLSAgLyoqCi0gICAqIERldGVybWluZSB3aGV0aGVyIGEgY2hhciBpcyBhbiB1bnJlc2VydmVkIGNoYXJhY3Rlci4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHBfY2hhciB0aGUgY2hhcmFjdGVyIHRvIGNoZWNrCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgY2hhciBpcyB1bnJlc2VydmVkLCBmYWxzZSBvdGhlcndpc2UKLSAgICovCi0gIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNVbnJlc2VydmVkQ2hhcmFjdGVyKGNoYXIgcF9jaGFyKQotICB7Ci0gICAgcmV0dXJuIChpc0FscGhhbnVtKHBfY2hhcikgfHwgTUFSS19DSEFSQUNURVJTLmluZGV4T2YocF9jaGFyKSAhPSAtMSk7Ci0gIH0KLQotICAvKioKLSAgICogRGV0ZXJtaW5lIHdoZXRoZXIgYSBnaXZlbiBzdHJpbmcgY29udGFpbnMgb25seSBVUkkgY2hhcmFjdGVycyAoYWxzbwotICAgKiBjYWxsZWQgInVyaWMiIGluIFJGQyAyMzk2KS4gdXJpYyBjb25zaXN0IG9mIGFsbCByZXNlcnZlZAotICAgKiBjaGFyYWN0ZXJzLCB1bnJlc2VydmVkIGNoYXJhY3RlcnMgYW5kIGVzY2FwZWQgY2hhcmFjdGVycy4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHBfdXJpYyBVUkkgc3RyaW5nCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgc3RyaW5nIGlzIGNvbXByaXNlZCBvZiB1cmljLCBmYWxzZSBvdGhlcndpc2UKLSAgICovCi0gIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNVUklTdHJpbmcoU3RyaW5nIHBfdXJpYykKLSAgewotCi0gICAgaWYgKHBfdXJpYyA9PSBudWxsKQotICAgIHsKLSAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICBpbnQgZW5kID0gcF91cmljLmxlbmd0aCgpOwotICAgIGNoYXIgdGVzdENoYXIgPSAnXDAnOwotCi0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBlbmQ7IGkrKykKLSAgICB7Ci0gICAgICB0ZXN0Q2hhciA9IHBfdXJpYy5jaGFyQXQoaSk7Ci0KLSAgICAgIGlmICh0ZXN0Q2hhciA9PSAnJScpCi0gICAgICB7Ci0gICAgICAgIGlmIChpICsgMiA+PSBlbmQgfHwhaXNIZXgocF91cmljLmNoYXJBdChpICsgMSkpCi0gICAgICAgICAgICAgICAgfHwhaXNIZXgocF91cmljLmNoYXJBdChpICsgMikpKQotICAgICAgICB7Ci0gICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotICAgICAgICAgIGkgKz0gMjsKLQotICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICB9Ci0gICAgICB9Ci0KLSAgICAgIGlmIChpc1Jlc2VydmVkQ2hhcmFjdGVyKHRlc3RDaGFyKSB8fCBpc1VucmVzZXJ2ZWRDaGFyYWN0ZXIodGVzdENoYXIpKQotICAgICAgewotICAgICAgICBjb250aW51ZTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiB0cnVlOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9VbkltcGxOb2RlLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9VbkltcGxOb2RlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGRmZTI3NjYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvVW5JbXBsTm9kZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjA1NCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBVbkltcGxOb2RlLmphdmEsdgotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnJlcy5YTUxFcnJvclJlc291cmNlczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnJlcy5YTUxNZXNzYWdlczsKLQotaW1wb3J0IG9yZy53M2MuZG9tLkF0dHI7Ci1pbXBvcnQgb3JnLnczYy5kb20uQ0RBVEFTZWN0aW9uOwotaW1wb3J0IG9yZy53M2MuZG9tLkNvbW1lbnQ7Ci1pbXBvcnQgb3JnLnczYy5kb20uRE9NRXhjZXB0aW9uOwotaW1wb3J0IG9yZy53M2MuZG9tLkRPTUltcGxlbWVudGF0aW9uOwotaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50RnJhZ21lbnQ7Ci1pbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnRUeXBlOwotaW1wb3J0IG9yZy53M2MuZG9tLkVsZW1lbnQ7Ci1pbXBvcnQgb3JnLnczYy5kb20uRW50aXR5UmVmZXJlbmNlOwotaW1wb3J0IG9yZy53M2MuZG9tLk5hbWVkTm9kZU1hcDsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGVMaXN0OwotaW1wb3J0IG9yZy53M2MuZG9tLlByb2Nlc3NpbmdJbnN0cnVjdGlvbjsKLWltcG9ydCBvcmcudzNjLmRvbS5UZXh0OwotCi1pbXBvcnQgb3JnLnczYy5kb20uVXNlckRhdGFIYW5kbGVyOwotaW1wb3J0IG9yZy53M2MuZG9tLkRPTUNvbmZpZ3VyYXRpb247Ci1pbXBvcnQgb3JnLnczYy5kb20uVHlwZUluZm87Ci0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJpbnRlcm5hbCIvPgotICogVG8gYmUgc3ViY2xhc3NlZCBieSBjbGFzc2VzIHRoYXQgd2lzaCB0byBmYWtlIGJlaW5nIG5vZGVzLgotICovCi1wdWJsaWMgY2xhc3MgVW5JbXBsTm9kZSBpbXBsZW1lbnRzIE5vZGUsIEVsZW1lbnQsIE5vZGVMaXN0LCBEb2N1bWVudAotewotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3RvciBVbkltcGxOb2RlCi0gICAqCi0gICAqLwotICBwdWJsaWMgVW5JbXBsTm9kZSgpe30KLQotICAvKioKLSAgICogVGhyb3cgYW4gZXJyb3IuCi0gICAqCi0gICAqIEBwYXJhbSBtc2cgTWVzc2FnZSBLZXkgZm9yIHRoZSBlcnJvcgotICAgKi8KLSAgcHVibGljIHZvaWQgZXJyb3IoU3RyaW5nIG1zZykKLSAgewotCi0gICAgU3lzdGVtLm91dC5wcmludGxuKCJET00gRVJST1IhIGNsYXNzOiAiICsgdGhpcy5nZXRDbGFzcygpLmdldE5hbWUoKSk7Ci0KLSAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihYTUxNZXNzYWdlcy5jcmVhdGVYTUxNZXNzYWdlKG1zZywgbnVsbCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRocm93IGFuIGVycm9yLgotICAgKgotICAgKiBAcGFyYW0gbXNnIE1lc3NhZ2UgS2V5IGZvciB0aGUgZXJyb3IKLSAgICogQHBhcmFtIGFyZ3MgQXJyYXkgb2YgYXJndW1lbnRzIHRvIGJlIHVzZWQgaW4gdGhlIGVycm9yIG1lc3NhZ2UKLSAgICovCi0gIHB1YmxpYyB2b2lkIGVycm9yKFN0cmluZyBtc2csIE9iamVjdFtdIGFyZ3MpCi0gIHsKLQotICAgIFN5c3RlbS5vdXQucHJpbnRsbigiRE9NIEVSUk9SISBjbGFzczogIiArIHRoaXMuZ2V0Q2xhc3MoKS5nZXROYW1lKCkpOwotCi0gICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oWE1MTWVzc2FnZXMuY3JlYXRlWE1MTWVzc2FnZShtc2csIGFyZ3MpKTsgIC8vIlVuSW1wbE5vZGUgZXJyb3I6ICIrbXNnKTsKLSAgfQotCi0gIC8qKgotICAgKiBVbmltcGxlbWVudGVkLiBTZWUgb3JnLnczYy5kb20uTm9kZQotICAgKgotICAgKiBAcGFyYW0gbmV3Q2hpbGQgTmV3IG5vZGUgdG8gYXBwZW5kIHRvIHRoZSBsaXN0IG9mIHRoaXMgbm9kZSdzIGNoaWxkcmVuCi0gICAqCi0gICAqIEByZXR1cm4gbnVsbAotICAgKgotICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIE5vZGUgYXBwZW5kQ2hpbGQoTm9kZSBuZXdDaGlsZCkgdGhyb3dzIERPTUV4Y2VwdGlvbgotICB7Ci0KLSAgICBlcnJvcihYTUxFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsgIC8vImFwcGVuZENoaWxkIG5vdCBzdXBwb3J0ZWQhIik7Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBVbmltcGxlbWVudGVkLiBTZWUgb3JnLnczYy5kb20uTm9kZQotICAgKgotICAgKiBAcmV0dXJuIGZhbHNlCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBoYXNDaGlsZE5vZGVzKCkKLSAgewotCi0gICAgZXJyb3IoWE1MRXJyb3JSZXNvdXJjZXMuRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCk7ICAvLyJoYXNDaGlsZE5vZGVzIG5vdCBzdXBwb3J0ZWQhIik7Ci0KLSAgICByZXR1cm4gZmFsc2U7Ci0gIH0KLQotICAvKioKLSAgICogVW5pbXBsZW1lbnRlZC4gU2VlIG9yZy53M2MuZG9tLk5vZGUKLSAgICoKLSAgICogQHJldHVybiAwCi0gICAqLwotICBwdWJsaWMgc2hvcnQgZ2V0Tm9kZVR5cGUoKQotICB7Ci0KLSAgICBlcnJvcihYTUxFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsgIC8vImdldE5vZGVUeXBlIG5vdCBzdXBwb3J0ZWQhIik7Ci0KLSAgICByZXR1cm4gMDsKLSAgfQotCi0gIC8qKgotICAgKiBVbmltcGxlbWVudGVkLiBTZWUgb3JnLnczYy5kb20uTm9kZQotICAgKgotICAgKiBAcmV0dXJuIG51bGwKLSAgICovCi0gIHB1YmxpYyBOb2RlIGdldFBhcmVudE5vZGUoKQotICB7Ci0KLSAgICBlcnJvcihYTUxFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsgIC8vImdldFBhcmVudE5vZGUgbm90IHN1cHBvcnRlZCEiKTsKLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFVuaW1wbGVtZW50ZWQuIFNlZSBvcmcudzNjLmRvbS5Ob2RlCi0gICAqCi0gICAqIEByZXR1cm4gbnVsbAotICAgKi8KLSAgcHVibGljIE5vZGVMaXN0IGdldENoaWxkTm9kZXMoKQotICB7Ci0KLSAgICBlcnJvcihYTUxFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsgIC8vImdldENoaWxkTm9kZXMgbm90IHN1cHBvcnRlZCEiKTsKLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFVuaW1wbGVtZW50ZWQuIFNlZSBvcmcudzNjLmRvbS5Ob2RlCi0gICAqCi0gICAqIEByZXR1cm4gbnVsbAotICAgKi8KLSAgcHVibGljIE5vZGUgZ2V0Rmlyc3RDaGlsZCgpCi0gIHsKLQotICAgIGVycm9yKFhNTEVycm9yUmVzb3VyY2VzLkVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQpOyAgLy8iZ2V0Rmlyc3RDaGlsZCBub3Qgc3VwcG9ydGVkISIpOwotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogVW5pbXBsZW1lbnRlZC4gU2VlIG9yZy53M2MuZG9tLk5vZGUKLSAgICoKLSAgICogQHJldHVybiBudWxsCi0gICAqLwotICBwdWJsaWMgTm9kZSBnZXRMYXN0Q2hpbGQoKQotICB7Ci0KLSAgICBlcnJvcihYTUxFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsgIC8vImdldExhc3RDaGlsZCBub3Qgc3VwcG9ydGVkISIpOwotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogVW5pbXBsZW1lbnRlZC4gU2VlIG9yZy53M2MuZG9tLk5vZGUKLSAgICoKLSAgICogQHJldHVybiBudWxsCi0gICAqLwotICBwdWJsaWMgTm9kZSBnZXROZXh0U2libGluZygpCi0gIHsKLQotICAgIGVycm9yKFhNTEVycm9yUmVzb3VyY2VzLkVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQpOyAgLy8iZ2V0TmV4dFNpYmxpbmcgbm90IHN1cHBvcnRlZCEiKTsKLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFVuaW1wbGVtZW50ZWQuIFNlZSBvcmcudzNjLmRvbS5Ob2RlTGlzdAotICAgKgotICAgKiBAcmV0dXJuIDAKLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0TGVuZ3RoKCkKLSAgewotCi0gICAgZXJyb3IoWE1MRXJyb3JSZXNvdXJjZXMuRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCk7ICAvLyJnZXRMZW5ndGggbm90IHN1cHBvcnRlZCEiKTsKLQotICAgIHJldHVybiAwOwotICB9ICAvLyBnZXRMZW5ndGgoKTppbnQKLQotICAvKioKLSAgICogVW5pbXBsZW1lbnRlZC4gU2VlIG9yZy53M2MuZG9tLk5vZGVMaXN0Ci0gICAqCi0gICAqIEBwYXJhbSBpbmRleCBpbmRleCBvZiBhIGNoaWxkIG9mIHRoaXMgbm9kZSBpbiBpdHMgbGlzdCBvZiBjaGlsZHJlbgotICAgKgotICAgKiBAcmV0dXJuIG51bGwKLSAgICovCi0gIHB1YmxpYyBOb2RlIGl0ZW0oaW50IGluZGV4KQotICB7Ci0KLSAgICBlcnJvcihYTUxFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsgIC8vIml0ZW0gbm90IHN1cHBvcnRlZCEiKTsKLQotICAgIHJldHVybiBudWxsOwotICB9ICAvLyBpdGVtKGludCk6Tm9kZQotCi0gIC8qKgotICAgKiBVbmltcGxlbWVudGVkLiBTZWUgb3JnLnczYy5kb20uTm9kZQotICAgKgotICAgKiBAcmV0dXJuIG51bGwKLSAgICovCi0gIHB1YmxpYyBEb2N1bWVudCBnZXRPd25lckRvY3VtZW50KCkKLSAgewotCi0gICAgZXJyb3IoWE1MRXJyb3JSZXNvdXJjZXMuRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCk7ICAvLyJnZXRPd25lckRvY3VtZW50IG5vdCBzdXBwb3J0ZWQhIik7Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBVbmltcGxlbWVudGVkLiBTZWUgb3JnLnczYy5kb20uTm9kZQotICAgKgotICAgKiBAcmV0dXJuIG51bGwKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0VGFnTmFtZSgpCi0gIHsKLQotICAgIGVycm9yKFhNTEVycm9yUmVzb3VyY2VzLkVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQpOyAgLy8iZ2V0VGFnTmFtZSBub3Qgc3VwcG9ydGVkISIpOwotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogVW5pbXBsZW1lbnRlZC4gU2VlIG9yZy53M2MuZG9tLk5vZGUKLSAgICoKLSAgICogQHJldHVybiBudWxsCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldE5vZGVOYW1lKCkKLSAgewotCi0gICAgZXJyb3IoWE1MRXJyb3JSZXNvdXJjZXMuRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCk7ICAvLyJnZXROb2RlTmFtZSBub3Qgc3VwcG9ydGVkISIpOwotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKiogVW5pbXBsZW1lbnRlZC4gU2VlIG9yZy53M2MuZG9tLk5vZGUgKi8KLSAgcHVibGljIHZvaWQgbm9ybWFsaXplKCkKLSAgewotICAgIGVycm9yKFhNTEVycm9yUmVzb3VyY2VzLkVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQpOyAgLy8ibm9ybWFsaXplIG5vdCBzdXBwb3J0ZWQhIik7Ci0gIH0KLQotICAvKioKLSAgICogVW5pbXBsZW1lbnRlZC4gU2VlIG9yZy53M2MuZG9tLkVsZW1lbnQKLSAgICoKLSAgICogQHBhcmFtIG5hbWUgTmFtZSBvZiB0aGUgZWxlbWVudAotICAgKgotICAgKiBAcmV0dXJuIG51bGwKLSAgICovCi0gIHB1YmxpYyBOb2RlTGlzdCBnZXRFbGVtZW50c0J5VGFnTmFtZShTdHJpbmcgbmFtZSkKLSAgewotCi0gICAgZXJyb3IoWE1MRXJyb3JSZXNvdXJjZXMuRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCk7ICAvLyJnZXRFbGVtZW50c0J5VGFnTmFtZSBub3Qgc3VwcG9ydGVkISIpOwotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogVW5pbXBsZW1lbnRlZC4gU2VlIG9yZy53M2MuZG9tLkVsZW1lbnQKLSAgICoKLSAgICogQHBhcmFtIG9sZEF0dHIgQXR0cmlidXRlIHRvIGJlIHJlbW92ZWQgZnJvbSB0aGlzIG5vZGUncyBsaXN0IG9mIGF0dHJpYnV0ZXMKLSAgICoKLSAgICogQHJldHVybiBudWxsCi0gICAqCi0gICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgQXR0ciByZW1vdmVBdHRyaWJ1dGVOb2RlKEF0dHIgb2xkQXR0cikgdGhyb3dzIERPTUV4Y2VwdGlvbgotICB7Ci0KLSAgICBlcnJvcihYTUxFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsgIC8vInJlbW92ZUF0dHJpYnV0ZU5vZGUgbm90IHN1cHBvcnRlZCEiKTsKLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFVuaW1wbGVtZW50ZWQuIFNlZSBvcmcudzNjLmRvbS5FbGVtZW50Ci0gICAqCi0gICAqIEBwYXJhbSBuZXdBdHRyIEF0dHJpYnV0ZSBub2RlIHRvIGJlIGFkZGVkIHRvIHRoaXMgbm9kZSdzIGxpc3Qgb2YgYXR0cmlidXRlcwotICAgKgotICAgKiBAcmV0dXJuIG51bGwKLSAgICoKLSAgICogQHRocm93cyBET01FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBBdHRyIHNldEF0dHJpYnV0ZU5vZGUoQXR0ciBuZXdBdHRyKSB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gIHsKLQotICAgIGVycm9yKFhNTEVycm9yUmVzb3VyY2VzLkVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQpOyAgLy8ic2V0QXR0cmlidXRlTm9kZSBub3Qgc3VwcG9ydGVkISIpOwotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogVW5pbXBsZW1lbnRlZC4gU2VlIG9yZy53M2MuZG9tLkVsZW1lbnQKLSAgICoKLSAgICoKLSAgICogQHBhcmFtIG5hbWUgTmFtZSBvZiBhbiBhdHRyaWJ1dGUKLSAgICoKLSAgICogQHJldHVybiBmYWxzZQotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaGFzQXR0cmlidXRlKFN0cmluZyBuYW1lKQotICB7Ci0KLSAgICBlcnJvcihYTUxFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsgIC8vImhhc0F0dHJpYnV0ZSBub3Qgc3VwcG9ydGVkISIpOwotCi0gICAgcmV0dXJuIGZhbHNlOwotICB9Ci0KLSAgLyoqCi0gICAqIFVuaW1wbGVtZW50ZWQuIFNlZSBvcmcudzNjLmRvbS5FbGVtZW50Ci0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lCi0gICAqIEBwYXJhbSB4Ci0gICAqCi0gICAqIEByZXR1cm4gZmFsc2UKLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGhhc0F0dHJpYnV0ZU5TKFN0cmluZyBuYW1lLCBTdHJpbmcgeCkKLSAgewotCi0gICAgZXJyb3IoWE1MRXJyb3JSZXNvdXJjZXMuRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCk7ICAvLyJoYXNBdHRyaWJ1dGVOUyBub3Qgc3VwcG9ydGVkISIpOwotCi0gICAgcmV0dXJuIGZhbHNlOwotICB9Ci0KLSAgLyoqCi0gICAqIFVuaW1wbGVtZW50ZWQuIFNlZSBvcmcudzNjLmRvbS5FbGVtZW50Ci0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lIEF0dHJpYnV0ZSBub2RlIG5hbWUKLSAgICoKLSAgICogQHJldHVybiBudWxsCi0gICAqLwotICBwdWJsaWMgQXR0ciBnZXRBdHRyaWJ1dGVOb2RlKFN0cmluZyBuYW1lKQotICB7Ci0KLSAgICBlcnJvcihYTUxFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsgIC8vImdldEF0dHJpYnV0ZU5vZGUgbm90IHN1cHBvcnRlZCEiKTsKLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFVuaW1wbGVtZW50ZWQuIFNlZSBvcmcudzNjLmRvbS5FbGVtZW50Ci0gICAqCi0gICAqIEBwYXJhbSBuYW1lIEF0dHJpYnV0ZSBub2RlIG5hbWUgdG8gcmVtb3ZlIGZyb20gbGlzdCBvZiBhdHRyaWJ1dGVzCi0gICAqCi0gICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCByZW1vdmVBdHRyaWJ1dGUoU3RyaW5nIG5hbWUpIHRocm93cyBET01FeGNlcHRpb24KLSAgewotICAgIGVycm9yKFhNTEVycm9yUmVzb3VyY2VzLkVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQpOyAgLy8icmVtb3ZlQXR0cmlidXRlIG5vdCBzdXBwb3J0ZWQhIik7Ci0gIH0KLQotICAvKioKLSAgICogVW5pbXBsZW1lbnRlZC4gU2VlIG9yZy53M2MuZG9tLkVsZW1lbnQKLSAgICoKLSAgICogQHBhcmFtIG5hbWUgTmFtZSBvZiBhdHRyaWJ1dGUgdG8gc2V0Ci0gICAqIEBwYXJhbSB2YWx1ZSBWYWx1ZSBvZiBhdHRyaWJ1dGUKLSAgICoKLSAgICogQHRocm93cyBET01FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldEF0dHJpYnV0ZShTdHJpbmcgbmFtZSwgU3RyaW5nIHZhbHVlKSB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gIHsKLSAgICBlcnJvcihYTUxFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsgIC8vInNldEF0dHJpYnV0ZSBub3Qgc3VwcG9ydGVkISIpOwotICB9Ci0KLSAgLyoqCi0gICAqIFVuaW1wbGVtZW50ZWQuIFNlZSBvcmcudzNjLmRvbS5FbGVtZW50Ci0gICAqCi0gICAqIEBwYXJhbSBuYW1lIE5hbWUgb2YgYXR0cmlidXRlIHRvIGdldAotICAgKgotICAgKiBAcmV0dXJuIG51bGwKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0QXR0cmlidXRlKFN0cmluZyBuYW1lKQotICB7Ci0KLSAgICBlcnJvcihYTUxFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsgIC8vImdldEF0dHJpYnV0ZSBub3Qgc3VwcG9ydGVkISIpOwotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogVW5pbXBsZW1lbnRlZC4gSW50cm9kdWNlZCBpbiBET00gTGV2ZWwgMi4KLSAgICoKLSAgICogQHJldHVybiBmYWxzZQotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaGFzQXR0cmlidXRlcygpCi0gIHsKLQotICAgIGVycm9yKFhNTEVycm9yUmVzb3VyY2VzLkVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQpOyAgLy8iaGFzQXR0cmlidXRlcyBub3Qgc3VwcG9ydGVkISIpOwotCi0gICAgcmV0dXJuIGZhbHNlOwotICB9Ci0KLSAgLyoqCi0gICAqIFVuaW1wbGVtZW50ZWQuIFNlZSBvcmcudzNjLmRvbS5FbGVtZW50Ci0gICAqCi0gICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkgTmFtZXNwYWNlIFVSSSBvZiB0aGUgZWxlbWVudAotICAgKiBAcGFyYW0gbG9jYWxOYW1lIExvY2FsIHBhcnQgb2YgcXVhbGlmaWVkIG5hbWUgb2YgdGhlIGVsZW1lbnQKLSAgICoKLSAgICogQHJldHVybiBudWxsCi0gICAqLwotICBwdWJsaWMgTm9kZUxpc3QgZ2V0RWxlbWVudHNCeVRhZ05hbWVOUyhTdHJpbmcgbmFtZXNwYWNlVVJJLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbG9jYWxOYW1lKQotICB7Ci0KLSAgICBlcnJvcihYTUxFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsgIC8vImdldEVsZW1lbnRzQnlUYWdOYW1lTlMgbm90IHN1cHBvcnRlZCEiKTsKLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFVuaW1wbGVtZW50ZWQuIFNlZSBvcmcudzNjLmRvbS5FbGVtZW50Ci0gICAqCi0gICAqIEBwYXJhbSBuZXdBdHRyIEF0dHJpYnV0ZSB0byBzZXQKLSAgICoKLSAgICogQHJldHVybiBudWxsCi0gICAqCi0gICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgQXR0ciBzZXRBdHRyaWJ1dGVOb2RlTlMoQXR0ciBuZXdBdHRyKSB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gIHsKLQotICAgIGVycm9yKFhNTEVycm9yUmVzb3VyY2VzLkVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQpOyAgLy8ic2V0QXR0cmlidXRlTm9kZU5TIG5vdCBzdXBwb3J0ZWQhIik7Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBVbmltcGxlbWVudGVkLiBTZWUgb3JnLnczYy5kb20uRWxlbWVudAotICAgKgotICAgKiBAcGFyYW0gbmFtZXNwYWNlVVJJIE5hbWVzcGFjZSBVUkkgb2YgYXR0cmlidXRlIG5vZGUgdG8gZ2V0Ci0gICAqIEBwYXJhbSBsb2NhbE5hbWUgTG9jYWwgcGFydCBvZiBxdWFsaWZpZWQgbmFtZSBvZiBhdHRyaWJ1dGUgbm9kZSB0byBnZXQKLSAgICoKLSAgICogQHJldHVybiBudWxsCi0gICAqLwotICBwdWJsaWMgQXR0ciBnZXRBdHRyaWJ1dGVOb2RlTlMoU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIGxvY2FsTmFtZSkKLSAgewotCi0gICAgZXJyb3IoWE1MRXJyb3JSZXNvdXJjZXMuRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCk7ICAvLyJnZXRBdHRyaWJ1dGVOb2RlTlMgbm90IHN1cHBvcnRlZCEiKTsKLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFVuaW1wbGVtZW50ZWQuIFNlZSBvcmcudzNjLmRvbS5FbGVtZW50Ci0gICAqCi0gICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkgTmFtZXNwYWNlIFVSSSBvZiBhdHRyaWJ1dGUgbm9kZSB0byByZW1vdmUKLSAgICogQHBhcmFtIGxvY2FsTmFtZSBMb2NhbCBwYXJ0IG9mIHF1YWxpZmllZCBuYW1lIG9mIGF0dHJpYnV0ZSBub2RlIHRvIHJlbW92ZQotICAgKgotICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgcmVtb3ZlQXR0cmlidXRlTlMoU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIGxvY2FsTmFtZSkKLSAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gIHsKLSAgICBlcnJvcihYTUxFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsgIC8vInJlbW92ZUF0dHJpYnV0ZU5TIG5vdCBzdXBwb3J0ZWQhIik7Ci0gIH0KLQotICAvKioKLSAgICogVW5pbXBsZW1lbnRlZC4gU2VlIG9yZy53M2MuZG9tLkVsZW1lbnQKLSAgICoKLSAgICogQHBhcmFtIG5hbWVzcGFjZVVSSSBOYW1lc3BhY2UgVVJJIG9mIGF0dHJpYnV0ZSBub2RlIHRvIHNldAotICAgKiBAcGFyYW0gcXVhbGlmaWVkTmFtZSBxdWFsaWZpZWQgbmFtZSBvZiBhdHRyaWJ1dGUKLSAgICogQHBhcmFtIHZhbHVlIHZhbHVlIG9mIGF0dHJpYnV0ZQotICAgKgotICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0QXR0cmlidXRlTlMoCi0gICAgICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIHF1YWxpZmllZE5hbWUsIFN0cmluZyB2YWx1ZSkKLSAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb24KLSAgewotICAgIGVycm9yKFhNTEVycm9yUmVzb3VyY2VzLkVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQpOyAgLy8ic2V0QXR0cmlidXRlTlMgbm90IHN1cHBvcnRlZCEiKTsKLSAgfQotCi0gIC8qKgotICAgKiBVbmltcGxlbWVudGVkLiBTZWUgb3JnLnczYy5kb20uRWxlbWVudAotICAgKgotICAgKiBAcGFyYW0gbmFtZXNwYWNlVVJJIE5hbWVzcGFjZSBVUkkgb2YgYXR0cmlidXRlIG5vZGUgdG8gZ2V0Ci0gICAqIEBwYXJhbSBsb2NhbE5hbWUgTG9jYWwgcGFydCBvZiBxdWFsaWZpZWQgbmFtZSBvZiBhdHRyaWJ1dGUgbm9kZSB0byBnZXQKLSAgICoKLSAgICogQHJldHVybiBudWxsCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldEF0dHJpYnV0ZU5TKFN0cmluZyBuYW1lc3BhY2VVUkksIFN0cmluZyBsb2NhbE5hbWUpCi0gIHsKLQotICAgIGVycm9yKFhNTEVycm9yUmVzb3VyY2VzLkVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQpOyAgLy8iZ2V0QXR0cmlidXRlTlMgbm90IHN1cHBvcnRlZCEiKTsKLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFVuaW1wbGVtZW50ZWQuIFNlZSBvcmcudzNjLmRvbS5Ob2RlCi0gICAqCi0gICAqIEByZXR1cm4gbnVsbAotICAgKi8KLSAgcHVibGljIE5vZGUgZ2V0UHJldmlvdXNTaWJsaW5nKCkKLSAgewotCi0gICAgZXJyb3IoWE1MRXJyb3JSZXNvdXJjZXMuRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCk7ICAvLyJnZXRQcmV2aW91c1NpYmxpbmcgbm90IHN1cHBvcnRlZCEiKTsKLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFVuaW1wbGVtZW50ZWQuIFNlZSBvcmcudzNjLmRvbS5Ob2RlCi0gICAqCi0gICAqIEBwYXJhbSBkZWVwIEZsYWcgaW5kaWNhdGluZyB3aGV0aGVyIHRvIGNsb25lIGRlZXAgKGNsb25lIG1lbWJlciB2YXJpYWJsZXMpCi0gICAqCi0gICAqIEByZXR1cm4gbnVsbAotICAgKi8KLSAgcHVibGljIE5vZGUgY2xvbmVOb2RlKGJvb2xlYW4gZGVlcCkKLSAgewotCi0gICAgZXJyb3IoWE1MRXJyb3JSZXNvdXJjZXMuRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCk7ICAvLyJjbG9uZU5vZGUgbm90IHN1cHBvcnRlZCEiKTsKLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFVuaW1wbGVtZW50ZWQuIFNlZSBvcmcudzNjLmRvbS5Ob2RlCi0gICAqCi0gICAqIEByZXR1cm4gbnVsbAotICAgKgotICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXROb2RlVmFsdWUoKSB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gIHsKLQotICAgIGVycm9yKFhNTEVycm9yUmVzb3VyY2VzLkVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQpOyAgLy8iZ2V0Tm9kZVZhbHVlIG5vdCBzdXBwb3J0ZWQhIik7Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBVbmltcGxlbWVudGVkLiBTZWUgb3JnLnczYy5kb20uTm9kZQotICAgKgotICAgKiBAcGFyYW0gbm9kZVZhbHVlIFZhbHVlIHRvIHNldCB0aGlzIG5vZGUgdG8KLSAgICoKLSAgICogQHRocm93cyBET01FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldE5vZGVWYWx1ZShTdHJpbmcgbm9kZVZhbHVlKSB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gIHsKLSAgICBlcnJvcihYTUxFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsgIC8vInNldE5vZGVWYWx1ZSBub3Qgc3VwcG9ydGVkISIpOwotICB9Ci0KLSAgLyoqCi0gICAqIFVuaW1wbGVtZW50ZWQuIFNlZSBvcmcudzNjLmRvbS5Ob2RlCi0gICAqCi0gICAqCi0gICAqIE5FRURTRE9DIEBwYXJhbSB2YWx1ZQotICAgKiBAcmV0dXJuIHZhbHVlIE5vZGUgdmFsdWUKLSAgICoKLSAgICogQHRocm93cyBET01FeGNlcHRpb24KLSAgICovCi0KLSAgLy8gcHVibGljIFN0cmluZyBnZXRWYWx1ZSAoKQotICAvLyB7Ci0gIC8vICBlcnJvcihYTUxFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsgLy8iZ2V0VmFsdWUgbm90IHN1cHBvcnRlZCEiKTsKLSAgLy8gIHJldHVybiBudWxsOwotICAvLyB9Ci0KLSAgLyoqCi0gICAqIFVuaW1wbGVtZW50ZWQuIFNlZSBvcmcudzNjLmRvbS5Ob2RlCi0gICAqCi0gICAqIEBwYXJhbSB2YWx1ZSBWYWx1ZSB0byBzZXQgdGhpcyBub2RlIHRvCi0gICAqCi0gICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRWYWx1ZShTdHJpbmcgdmFsdWUpIHRocm93cyBET01FeGNlcHRpb24KLSAgewotICAgIGVycm9yKFhNTEVycm9yUmVzb3VyY2VzLkVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQpOyAgLy8ic2V0VmFsdWUgbm90IHN1cHBvcnRlZCEiKTsKLSAgfQotCi0gIC8qKgotICAgKiAgUmV0dXJucyB0aGUgbmFtZSBvZiB0aGlzIGF0dHJpYnV0ZS4KLSAgICoKLSAgICogQHJldHVybiB0aGUgbmFtZSBvZiB0aGlzIGF0dHJpYnV0ZS4KLSAgICovCi0KLSAgLy8gcHVibGljIFN0cmluZyBnZXROYW1lKCkKLSAgLy8gewotICAvLyAgcmV0dXJuIHRoaXMuZ2V0Tm9kZU5hbWUoKTsKLSAgLy8gfQotCi0gIC8qKgotICAgKiBVbmltcGxlbWVudGVkLiBTZWUgb3JnLnczYy5kb20uTm9kZQotICAgKgotICAgKiBAcmV0dXJuIG51bGwKLSAgICovCi0gIHB1YmxpYyBFbGVtZW50IGdldE93bmVyRWxlbWVudCgpCi0gIHsKLQotICAgIGVycm9yKFhNTEVycm9yUmVzb3VyY2VzLkVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQpOyAgLy8iZ2V0T3duZXJFbGVtZW50IG5vdCBzdXBwb3J0ZWQhIik7Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBVbmltcGxlbWVudGVkLiBTZWUgb3JnLnczYy5kb20uTm9kZQotICAgKgotICAgKiBAcmV0dXJuIEZhbHNlCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBnZXRTcGVjaWZpZWQoKQotICB7Ci0KLSAgICBlcnJvcihYTUxFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsgIC8vInNldFZhbHVlIG5vdCBzdXBwb3J0ZWQhIik7Ci0KLSAgICByZXR1cm4gZmFsc2U7Ci0gIH0KLQotICAvKioKLSAgICogVW5pbXBsZW1lbnRlZC4gU2VlIG9yZy53M2MuZG9tLk5vZGUKLSAgICoKLSAgICogQHJldHVybiBudWxsCi0gICAqLwotICBwdWJsaWMgTmFtZWROb2RlTWFwIGdldEF0dHJpYnV0ZXMoKQotICB7Ci0KLSAgICBlcnJvcihYTUxFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsgIC8vImdldEF0dHJpYnV0ZXMgbm90IHN1cHBvcnRlZCEiKTsKLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFVuaW1wbGVtZW50ZWQuIFNlZSBvcmcudzNjLmRvbS5Ob2RlCi0gICAqCi0gICAqIEBwYXJhbSBuZXdDaGlsZCBOZXcgY2hpbGQgbm9kZSB0byBpbnNlcnQKLSAgICogQHBhcmFtIHJlZkNoaWxkIEluc2VydCBpbiBmcm9udCBvZiB0aGlzIGNoaWxkCi0gICAqCi0gICAqIEByZXR1cm4gbnVsbAotICAgKgotICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIE5vZGUgaW5zZXJ0QmVmb3JlKE5vZGUgbmV3Q2hpbGQsIE5vZGUgcmVmQ2hpbGQpIHRocm93cyBET01FeGNlcHRpb24KLSAgewotCi0gICAgZXJyb3IoWE1MRXJyb3JSZXNvdXJjZXMuRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCk7ICAvLyJpbnNlcnRCZWZvcmUgbm90IHN1cHBvcnRlZCEiKTsKLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFVuaW1wbGVtZW50ZWQuIFNlZSBvcmcudzNjLmRvbS5Ob2RlCi0gICAqCi0gICAqIEBwYXJhbSBuZXdDaGlsZCBSZXBsYWNlIGV4aXN0aW5nIGNoaWxkIHdpdGggdGhpcyBvbmUKLSAgICogQHBhcmFtIG9sZENoaWxkIEV4aXN0aW5nIGNoaWxkIHRvIGJlIHJlcGxhY2VkCi0gICAqCi0gICAqIEByZXR1cm4gbnVsbAotICAgKgotICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIE5vZGUgcmVwbGFjZUNoaWxkKE5vZGUgbmV3Q2hpbGQsIE5vZGUgb2xkQ2hpbGQpIHRocm93cyBET01FeGNlcHRpb24KLSAgewotCi0gICAgZXJyb3IoWE1MRXJyb3JSZXNvdXJjZXMuRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCk7ICAvLyJyZXBsYWNlQ2hpbGQgbm90IHN1cHBvcnRlZCEiKTsKLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFVuaW1wbGVtZW50ZWQuIFNlZSBvcmcudzNjLmRvbS5Ob2RlCi0gICAqCi0gICAqIEBwYXJhbSBvbGRDaGlsZCBDaGlsZCB0byBiZSByZW1vdmVkCi0gICAqCi0gICAqIEByZXR1cm4gbnVsbAotICAgKgotICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIE5vZGUgcmVtb3ZlQ2hpbGQoTm9kZSBvbGRDaGlsZCkgdGhyb3dzIERPTUV4Y2VwdGlvbgotICB7Ci0KLSAgICBlcnJvcihYTUxFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsgIC8vInJlcGxhY2VDaGlsZCBub3Qgc3VwcG9ydGVkISIpOwotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogVGVzdHMgd2hldGhlciB0aGUgRE9NIGltcGxlbWVudGF0aW9uIGltcGxlbWVudHMgYSBzcGVjaWZpYyBmZWF0dXJlIGFuZAotICAgKiB0aGF0IGZlYXR1cmUgaXMgc3VwcG9ydGVkIGJ5IHRoaXMgbm9kZS4KLSAgICogQHBhcmFtIGZlYXR1cmUgVGhlIG5hbWUgb2YgdGhlIGZlYXR1cmUgdG8gdGVzdC4gVGhpcyBpcyB0aGUgc2FtZSBuYW1lCi0gICAqICAgd2hpY2ggY2FuIGJlIHBhc3NlZCB0byB0aGUgbWV0aG9kIDxjb2RlPmhhc0ZlYXR1cmU8L2NvZGU+IG9uCi0gICAqICAgPGNvZGU+RE9NSW1wbGVtZW50YXRpb248L2NvZGU+LgotICAgKiBAcGFyYW0gdmVyc2lvbiBUaGlzIGlzIHRoZSB2ZXJzaW9uIG51bWJlciBvZiB0aGUgZmVhdHVyZSB0byB0ZXN0LiBJbgotICAgKiAgIExldmVsIDIsIHZlcnNpb24gMSwgdGhpcyBpcyB0aGUgc3RyaW5nICIyLjAiLiBJZiB0aGUgdmVyc2lvbiBpcyBub3QKLSAgICogICBzcGVjaWZpZWQsIHN1cHBvcnRpbmcgYW55IHZlcnNpb24gb2YgdGhlIGZlYXR1cmUgd2lsbCBjYXVzZSB0aGUKLSAgICogICBtZXRob2QgdG8gcmV0dXJuIDxjb2RlPnRydWU8L2NvZGU+LgotICAgKgotICAgKiBAcmV0dXJuIFJldHVybnMgPGNvZGU+ZmFsc2U8L2NvZGU+Ci0gICAqIEBzaW5jZSBET00gTGV2ZWwgMgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNTdXBwb3J0ZWQoU3RyaW5nIGZlYXR1cmUsIFN0cmluZyB2ZXJzaW9uKQotICB7Ci0gICAgcmV0dXJuIGZhbHNlOwotICB9Ci0KLSAgLyoqCi0gICAqIFVuaW1wbGVtZW50ZWQuIFNlZSBvcmcudzNjLmRvbS5Ob2RlCi0gICAqCi0gICAqIEByZXR1cm4gbnVsbAotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXROYW1lc3BhY2VVUkkoKQotICB7Ci0KLSAgICBlcnJvcihYTUxFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsgIC8vImdldE5hbWVzcGFjZVVSSSBub3Qgc3VwcG9ydGVkISIpOwotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogVW5pbXBsZW1lbnRlZC4gU2VlIG9yZy53M2MuZG9tLk5vZGUKLSAgICoKLSAgICogQHJldHVybiBudWxsCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFByZWZpeCgpCi0gIHsKLQotICAgIGVycm9yKFhNTEVycm9yUmVzb3VyY2VzLkVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQpOyAgLy8iZ2V0UHJlZml4IG5vdCBzdXBwb3J0ZWQhIik7Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBVbmltcGxlbWVudGVkLiBTZWUgb3JnLnczYy5kb20uTm9kZQotICAgKgotICAgKiBAcGFyYW0gcHJlZml4IFByZWZpeCB0byBzZXQgZm9yIHRoaXMgbm9kZQotICAgKgotICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0UHJlZml4KFN0cmluZyBwcmVmaXgpIHRocm93cyBET01FeGNlcHRpb24KLSAgewotICAgIGVycm9yKFhNTEVycm9yUmVzb3VyY2VzLkVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQpOyAgLy8ic2V0UHJlZml4IG5vdCBzdXBwb3J0ZWQhIik7Ci0gIH0KLQotICAvKioKLSAgICogVW5pbXBsZW1lbnRlZC4gU2VlIG9yZy53M2MuZG9tLk5vZGUKLSAgICoKLSAgICogQHJldHVybiBudWxsCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldExvY2FsTmFtZSgpCi0gIHsKLQotICAgIGVycm9yKFhNTEVycm9yUmVzb3VyY2VzLkVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQpOyAgLy8iZ2V0TG9jYWxOYW1lIG5vdCBzdXBwb3J0ZWQhIik7Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBVbmltcGxlbWVudGVkLiBTZWUgb3JnLnczYy5kb20uRG9jdW1lbnQKLSAgICoKLSAgICogQHJldHVybiBudWxsCi0gICAqLwotICBwdWJsaWMgRG9jdW1lbnRUeXBlIGdldERvY3R5cGUoKQotICB7Ci0KLSAgICBlcnJvcihYTUxFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsKLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFVuaW1wbGVtZW50ZWQuIFNlZSBvcmcudzNjLmRvbS5Eb2N1bWVudAotICAgKgotICAgKiBAcmV0dXJuIG51bGwKLSAgICovCi0gIHB1YmxpYyBET01JbXBsZW1lbnRhdGlvbiBnZXRJbXBsZW1lbnRhdGlvbigpCi0gIHsKLQotICAgIGVycm9yKFhNTEVycm9yUmVzb3VyY2VzLkVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQpOwotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogVW5pbXBsZW1lbnRlZC4gU2VlIG9yZy53M2MuZG9tLkRvY3VtZW50Ci0gICAqCi0gICAqIEByZXR1cm4gbnVsbAotICAgKi8KLSAgcHVibGljIEVsZW1lbnQgZ2V0RG9jdW1lbnRFbGVtZW50KCkKLSAgewotCi0gICAgZXJyb3IoWE1MRXJyb3JSZXNvdXJjZXMuRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCk7Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBVbmltcGxlbWVudGVkLiBTZWUgb3JnLnczYy5kb20uRG9jdW1lbnQKLSAgICoKLSAgICogQHBhcmFtIHRhZ05hbWUgRWxlbWVudCB0YWcgbmFtZQotICAgKgotICAgKiBAcmV0dXJuIG51bGwKLSAgICoKLSAgICogQHRocm93cyBET01FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBFbGVtZW50IGNyZWF0ZUVsZW1lbnQoU3RyaW5nIHRhZ05hbWUpIHRocm93cyBET01FeGNlcHRpb24KLSAgewotCi0gICAgZXJyb3IoWE1MRXJyb3JSZXNvdXJjZXMuRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCk7Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBVbmltcGxlbWVudGVkLiBTZWUgb3JnLnczYy5kb20uRG9jdW1lbnQKLSAgICoKLSAgICogQHJldHVybiBudWxsCi0gICAqLwotICBwdWJsaWMgRG9jdW1lbnRGcmFnbWVudCBjcmVhdGVEb2N1bWVudEZyYWdtZW50KCkKLSAgewotCi0gICAgZXJyb3IoWE1MRXJyb3JSZXNvdXJjZXMuRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCk7Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBVbmltcGxlbWVudGVkLiBTZWUgb3JnLnczYy5kb20uRG9jdW1lbnQKLSAgICoKLSAgICogQHBhcmFtIGRhdGEgRGF0YSBmb3IgdGV4dCBub2RlCi0gICAqCi0gICAqIEByZXR1cm4gbnVsbAotICAgKi8KLSAgcHVibGljIFRleHQgY3JlYXRlVGV4dE5vZGUoU3RyaW5nIGRhdGEpCi0gIHsKLQotICAgIGVycm9yKFhNTEVycm9yUmVzb3VyY2VzLkVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQpOwotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogVW5pbXBsZW1lbnRlZC4gU2VlIG9yZy53M2MuZG9tLkRvY3VtZW50Ci0gICAqCi0gICAqIEBwYXJhbSBkYXRhIERhdGEgZm9yIGNvbW1lbnQKLSAgICoKLSAgICogQHJldHVybiBudWxsCi0gICAqLwotICBwdWJsaWMgQ29tbWVudCBjcmVhdGVDb21tZW50KFN0cmluZyBkYXRhKQotICB7Ci0KLSAgICBlcnJvcihYTUxFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsKLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFVuaW1wbGVtZW50ZWQuIFNlZSBvcmcudzNjLmRvbS5Eb2N1bWVudAotICAgKgotICAgKiBAcGFyYW0gZGF0YSBEYXRhIGZvciBDREFUQSBzZWN0aW9uCi0gICAqCi0gICAqIEByZXR1cm4gbnVsbAotICAgKgotICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIENEQVRBU2VjdGlvbiBjcmVhdGVDREFUQVNlY3Rpb24oU3RyaW5nIGRhdGEpIHRocm93cyBET01FeGNlcHRpb24KLSAgewotCi0gICAgZXJyb3IoWE1MRXJyb3JSZXNvdXJjZXMuRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCk7Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBVbmltcGxlbWVudGVkLiBTZWUgb3JnLnczYy5kb20uRG9jdW1lbnQKLSAgICoKLSAgICogQHBhcmFtIHRhcmdldCBUYXJnZXQgZm9yIFByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24KLSAgICogQHBhcmFtIGRhdGEgRGF0YSBmb3IgUHJvY2Vzc2luZyBpbnN0cnVjdGlvbgotICAgKgotICAgKiBAcmV0dXJuIG51bGwKLSAgICoKLSAgICogQHRocm93cyBET01FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24gY3JlYXRlUHJvY2Vzc2luZ0luc3RydWN0aW9uKAotICAgICAgICAgIFN0cmluZyB0YXJnZXQsIFN0cmluZyBkYXRhKSB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gIHsKLQotICAgIGVycm9yKFhNTEVycm9yUmVzb3VyY2VzLkVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQpOwotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogVW5pbXBsZW1lbnRlZC4gU2VlIG9yZy53M2MuZG9tLkRvY3VtZW50Ci0gICAqCi0gICAqIEBwYXJhbSBuYW1lIEF0dHJpYnV0ZSBuYW1lCi0gICAqCi0gICAqIEByZXR1cm4gbnVsbAotICAgKgotICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIEF0dHIgY3JlYXRlQXR0cmlidXRlKFN0cmluZyBuYW1lKSB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gIHsKLQotICAgIGVycm9yKFhNTEVycm9yUmVzb3VyY2VzLkVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQpOwotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogVW5pbXBsZW1lbnRlZC4gU2VlIG9yZy53M2MuZG9tLkRvY3VtZW50Ci0gICAqCi0gICAqIEBwYXJhbSBuYW1lIEVudGl0eSBSZWZlcmVuY2UgbmFtZQotICAgKgotICAgKiBAcmV0dXJuIG51bGwKLSAgICoKLSAgICogQHRocm93cyBET01FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBFbnRpdHlSZWZlcmVuY2UgY3JlYXRlRW50aXR5UmVmZXJlbmNlKFN0cmluZyBuYW1lKQotICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb24KLSAgewotCi0gICAgZXJyb3IoWE1MRXJyb3JSZXNvdXJjZXMuRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCk7Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBVbmltcGxlbWVudGVkLiBTZWUgb3JnLnczYy5kb20uRG9jdW1lbnQKLSAgICoKLSAgICogQHBhcmFtIGltcG9ydGVkTm9kZSBUaGUgbm9kZSB0byBpbXBvcnQuCi0gICAqIEBwYXJhbSBkZWVwIElmIDxjb2RlPnRydWU8L2NvZGU+LCByZWN1cnNpdmVseSBpbXBvcnQgdGhlIHN1YnRyZWUgdW5kZXIKLSAgICogICB0aGUgc3BlY2lmaWVkIG5vZGU7IGlmIDxjb2RlPmZhbHNlPC9jb2RlPiwgaW1wb3J0IG9ubHkgdGhlIG5vZGUKLSAgICogICBpdHNlbGYsIGFzIGV4cGxhaW5lZCBhYm92ZS4gVGhpcyBoYXMgbm8gZWZmZWN0IG9uIDxjb2RlPkF0dHI8L2NvZGU+Ci0gICAqICAgLCA8Y29kZT5FbnRpdHlSZWZlcmVuY2U8L2NvZGU+LCBhbmQgPGNvZGU+Tm90YXRpb248L2NvZGU+IG5vZGVzLgotICAgKgotICAgKiBAcmV0dXJuIG51bGwKLSAgICoKLSAgICogQHRocm93cyBET01FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBOb2RlIGltcG9ydE5vZGUoTm9kZSBpbXBvcnRlZE5vZGUsIGJvb2xlYW4gZGVlcCkgdGhyb3dzIERPTUV4Y2VwdGlvbgotICB7Ci0KLSAgICBlcnJvcihYTUxFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsKLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFVuaW1wbGVtZW50ZWQuIFNlZSBvcmcudzNjLmRvbS5Eb2N1bWVudAotICAgKgotICAgKiBAcGFyYW0gbmFtZXNwYWNlVVJJIE5hbWVzcGFjZSBVUkkgZm9yIHRoZSBlbGVtZW50Ci0gICAqIEBwYXJhbSBxdWFsaWZpZWROYW1lIFF1YWxpZmllZCBuYW1lIG9mIHRoZSBlbGVtZW50Ci0gICAqCi0gICAqIEByZXR1cm4gbnVsbAotICAgKgotICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIEVsZW1lbnQgY3JlYXRlRWxlbWVudE5TKFN0cmluZyBuYW1lc3BhY2VVUkksIFN0cmluZyBxdWFsaWZpZWROYW1lKQotICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb24KLSAgewotCi0gICAgZXJyb3IoWE1MRXJyb3JSZXNvdXJjZXMuRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCk7Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBVbmltcGxlbWVudGVkLiBTZWUgb3JnLnczYy5kb20uRG9jdW1lbnQKLSAgICoKLSAgICogQHBhcmFtIG5hbWVzcGFjZVVSSSBOYW1lc3BhY2UgVVJJIG9mIHRoZSBhdHRyaWJ1dGUKLSAgICogQHBhcmFtIHF1YWxpZmllZE5hbWUgUXVhbGlmaWVkIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZQotICAgKgotICAgKiBAcmV0dXJuIG51bGwKLSAgICoKLSAgICogQHRocm93cyBET01FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBBdHRyIGNyZWF0ZUF0dHJpYnV0ZU5TKFN0cmluZyBuYW1lc3BhY2VVUkksIFN0cmluZyBxdWFsaWZpZWROYW1lKQotICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb24KLSAgewotCi0gICAgZXJyb3IoWE1MRXJyb3JSZXNvdXJjZXMuRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCk7Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBVbmltcGxlbWVudGVkLiBTZWUgb3JnLnczYy5kb20uRG9jdW1lbnQKLSAgICoKLSAgICogQHBhcmFtIGVsZW1lbnRJZCBJRCBvZiB0aGUgZWxlbWVudCB0byBnZXQKLSAgICoKLSAgICogQHJldHVybiBudWxsCi0gICAqLwotICBwdWJsaWMgRWxlbWVudCBnZXRFbGVtZW50QnlJZChTdHJpbmcgZWxlbWVudElkKQotICB7Ci0KLSAgICBlcnJvcihYTUxFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsKLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCBOb2RlIGRhdGEKLSAgICoKLSAgICoKLSAgICogQHBhcmFtIGRhdGEgZGF0YSB0byBzZXQgZm9yIHRoaXMgbm9kZQotICAgKgotICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0RGF0YShTdHJpbmcgZGF0YSkgdGhyb3dzIERPTUV4Y2VwdGlvbgotICB7Ci0gICAgZXJyb3IoWE1MRXJyb3JSZXNvdXJjZXMuRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCk7Ci0gIH0KLQotICAvKioKLSAgICogVW5pbXBsZW1lbnRlZC4KLSAgICoKLSAgICogQHBhcmFtIG9mZnNldCBTdGFydCBvZmZzZXQgb2Ygc3Vic3RyaW5nIHRvIGV4dHJhY3QuCi0gICAqIEBwYXJhbSBjb3VudCBUaGUgbGVuZ3RoIG9mIHRoZSBzdWJzdHJpbmcgdG8gZXh0cmFjdC4KLSAgICoKLSAgICogQHJldHVybiBudWxsCi0gICAqCi0gICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIHN1YnN0cmluZ0RhdGEoaW50IG9mZnNldCwgaW50IGNvdW50KSB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gIHsKLQotICAgIGVycm9yKFhNTEVycm9yUmVzb3VyY2VzLkVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQpOwotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogVW5pbXBsZW1lbnRlZC4KLSAgICoKLSAgICogQHBhcmFtIGFyZyBTdHJpbmcgZGF0YSB0byBhcHBlbmQKLSAgICoKLSAgICogQHRocm93cyBET01FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGFwcGVuZERhdGEoU3RyaW5nIGFyZykgdGhyb3dzIERPTUV4Y2VwdGlvbgotICB7Ci0gICAgZXJyb3IoWE1MRXJyb3JSZXNvdXJjZXMuRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCk7Ci0gIH0KLQotICAvKioKLSAgICogVW5pbXBsZW1lbnRlZC4KLSAgICoKLSAgICogQHBhcmFtIG9mZnNldCBTdGFydCBvZmZzZXQgb2Ygc3Vic3RyaW5nIHRvIGluc2VydC4KLSAgICogQHBhcmFtIGFyZyBUaGUgKHN1YilzdHJpbmcgdG8gaW5zZXJ0LgotICAgKgotICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgaW5zZXJ0RGF0YShpbnQgb2Zmc2V0LCBTdHJpbmcgYXJnKSB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gIHsKLSAgICBlcnJvcihYTUxFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsKLSAgfQotCi0gIC8qKgotICAgKiBVbmltcGxlbWVudGVkLgotICAgKgotICAgKiBAcGFyYW0gb2Zmc2V0IFN0YXJ0IG9mZnNldCBvZiBzdWJzdHJpbmcgdG8gZGVsZXRlLgotICAgKiBAcGFyYW0gY291bnQgVGhlIGxlbmd0aCBvZiB0aGUgc3Vic3RyaW5nIHRvIGRlbGV0ZS4KLSAgICoKLSAgICogQHRocm93cyBET01FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGRlbGV0ZURhdGEoaW50IG9mZnNldCwgaW50IGNvdW50KSB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gIHsKLSAgICBlcnJvcihYTUxFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsKLSAgfQotCi0gIC8qKgotICAgKiBVbmltcGxlbWVudGVkLgotICAgKgotICAgKiBAcGFyYW0gb2Zmc2V0IFN0YXJ0IG9mZnNldCBvZiBzdWJzdHJpbmcgdG8gcmVwbGFjZS4KLSAgICogQHBhcmFtIGNvdW50IFRoZSBsZW5ndGggb2YgdGhlIHN1YnN0cmluZyB0byByZXBsYWNlLgotICAgKiBAcGFyYW0gYXJnIHN1YnN0cmluZyB0byByZXBsYWNlIHdpdGgKLSAgICoKLSAgICogQHRocm93cyBET01FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHJlcGxhY2VEYXRhKGludCBvZmZzZXQsIGludCBjb3VudCwgU3RyaW5nIGFyZykKLSAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gIHsKLSAgICBlcnJvcihYTUxFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsKLSAgfQotCi0gIC8qKgotICAgKiBVbmltcGxlbWVudGVkLgotICAgKgotICAgKiBAcGFyYW0gb2Zmc2V0IE9mZnNldCBpbnRvIHRleHQgdG8gc3BsaXQKLSAgICoKLSAgICogQHJldHVybiBudWxsLCB1bmltcGxlbWVudGVkCi0gICAqCi0gICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgVGV4dCBzcGxpdFRleHQoaW50IG9mZnNldCkgdGhyb3dzIERPTUV4Y2VwdGlvbgotICB7Ci0KLSAgICBlcnJvcihYTUxFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsKLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIE5FRURTRE9DIE1ldGhvZCBhZG9wdE5vZGUKLSAgICoKLSAgICoKLSAgICogTkVFRFNET0MgQHBhcmFtIHNvdXJjZQotICAgKgotICAgKiBORUVEU0RPQyAoYWRvcHROb2RlKSBAcmV0dXJuCi0gICAqCi0gICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgTm9kZSBhZG9wdE5vZGUoTm9kZSBzb3VyY2UpIHRocm93cyBET01FeGNlcHRpb24KLSAgewotCi0gICAgZXJyb3IoWE1MRXJyb3JSZXNvdXJjZXMuRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCk7Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiA8cD5FWFBFUklNRU5UQUwhIEJhc2VkIG9uIHRoZSA8YQotICAgKiBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAxL1dELURPTS1MZXZlbC0zLUNvcmUtMjAwMTA2MDUnPkRvY3VtZW50Ci0gICAqIE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAzIENvcmUgV29ya2luZyBEcmFmdCBvZiA1IEp1bmUgMjAwMS48L2E+LgotICAgKiA8cD4KLSAgICogQW4gYXR0cmlidXRlIHNwZWNpZnlpbmcsIGFzIHBhcnQgb2YgdGhlIFhNTCBkZWNsYXJhdGlvbiwgdGhlIGVuY29kaW5nCi0gICAqIG9mIHRoaXMgZG9jdW1lbnQuIFRoaXMgaXMgPGNvZGU+bnVsbDwvY29kZT4gd2hlbiB1bnNwZWNpZmllZC4KLSAgICogQHNpbmNlIERPTSBMZXZlbCAzCi0gICAqCi0gICAqIE5FRURTRE9DICgkb2JqZWN0TmFtZSQpIEByZXR1cm4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0SW5wdXRFbmNvZGluZygpCi0gIHsKLQotICAgIGVycm9yKFhNTEVycm9yUmVzb3VyY2VzLkVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQpOwotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogPHA+RVhQRVJJTUVOVEFMISBCYXNlZCBvbiB0aGUgPGEKLSAgICogaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMS9XRC1ET00tTGV2ZWwtMy1Db3JlLTIwMDEwNjA1Jz5Eb2N1bWVudAotICAgKiBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMyBDb3JlIFdvcmtpbmcgRHJhZnQgb2YgNSBKdW5lIDIwMDEuPC9hPi4KLSAgICogPHA+Ci0gICAqIEFuIGF0dHJpYnV0ZSBzcGVjaWZ5aW5nLCBhcyBwYXJ0IG9mIHRoZSBYTUwgZGVjbGFyYXRpb24sIHRoZSBlbmNvZGluZwotICAgKiBvZiB0aGlzIGRvY3VtZW50LiBUaGlzIGlzIDxjb2RlPm51bGw8L2NvZGU+IHdoZW4gdW5zcGVjaWZpZWQuCi0gICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgKgotICAgKiBORUVEU0RPQyBAcGFyYW0gZW5jb2RpbmcKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldElucHV0RW5jb2RpbmcoU3RyaW5nIGVuY29kaW5nKQotICB7Ci0gICAgZXJyb3IoWE1MRXJyb3JSZXNvdXJjZXMuRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCk7Ci0gIH0KLQotICAvKioKLSAgICogPHA+RVhQRVJJTUVOVEFMISBCYXNlZCBvbiB0aGUgPGEKLSAgICogaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMS9XRC1ET00tTGV2ZWwtMy1Db3JlLTIwMDEwNjA1Jz5Eb2N1bWVudAotICAgKiBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMyBDb3JlIFdvcmtpbmcgRHJhZnQgb2YgNSBKdW5lIDIwMDEuPC9hPi4KLSAgICogPHA+Ci0gICAqIEFuIGF0dHJpYnV0ZSBzcGVjaWZ5aW5nLCBhcyBwYXJ0IG9mIHRoZSBYTUwgZGVjbGFyYXRpb24sIHdoZXRoZXIgdGhpcwotICAgKiBkb2N1bWVudCBpcyBzdGFuZGFsb25lLgotICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICoKLSAgICogTkVFRFNET0MgKCRvYmplY3ROYW1lJCkgQHJldHVybgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZ2V0U3RhbmRhbG9uZSgpCi0gIHsKLQotICAgIGVycm9yKFhNTEVycm9yUmVzb3VyY2VzLkVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQpOwotCi0gICAgcmV0dXJuIGZhbHNlOwotICB9Ci0KLSAgLyoqCi0gICAqIDxwPkVYUEVSSU1FTlRBTCEgQmFzZWQgb24gdGhlIDxhCi0gICAqIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDEvV0QtRE9NLUxldmVsLTMtQ29yZS0yMDAxMDYwNSc+RG9jdW1lbnQKLSAgICogT2JqZWN0IE1vZGVsIChET00pIExldmVsIDMgQ29yZSBXb3JraW5nIERyYWZ0IG9mIDUgSnVuZSAyMDAxLjwvYT4uCi0gICAqIDxwPgotICAgKiBBbiBhdHRyaWJ1dGUgc3BlY2lmeWluZywgYXMgcGFydCBvZiB0aGUgWE1MIGRlY2xhcmF0aW9uLCB3aGV0aGVyIHRoaXMKLSAgICogZG9jdW1lbnQgaXMgc3RhbmRhbG9uZS4KLSAgICogQHNpbmNlIERPTSBMZXZlbCAzCi0gICAqCi0gICAqIE5FRURTRE9DIEBwYXJhbSBzdGFuZGFsb25lCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRTdGFuZGFsb25lKGJvb2xlYW4gc3RhbmRhbG9uZSkKLSAgewotICAgIGVycm9yKFhNTEVycm9yUmVzb3VyY2VzLkVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQpOwotICB9Ci0KLSAgLyoqCi0gICAqIDxwPkVYUEVSSU1FTlRBTCEgQmFzZWQgb24gdGhlIDxhCi0gICAqIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDEvV0QtRE9NLUxldmVsLTMtQ29yZS0yMDAxMDYwNSc+RG9jdW1lbnQKLSAgICogT2JqZWN0IE1vZGVsIChET00pIExldmVsIDMgQ29yZSBXb3JraW5nIERyYWZ0IG9mIDUgSnVuZSAyMDAxLjwvYT4uCi0gICAqIDxwPgotICAgKiBBbiBhdHRyaWJ1dGUgc3BlY2lmeWluZyB3aGV0aGVyIGVycm9ycyBjaGVja2luZyBpcyBlbmZvcmNlZCBvciBub3QuCi0gICAqIFdoZW4gc2V0IHRvIDxjb2RlPmZhbHNlPC9jb2RlPiwgdGhlIGltcGxlbWVudGF0aW9uIGlzIGZyZWUgdG8gbm90Ci0gICAqIHRlc3QgZXZlcnkgcG9zc2libGUgZXJyb3IgY2FzZSBub3JtYWxseSBkZWZpbmVkIG9uIERPTSBvcGVyYXRpb25zLAotICAgKiBhbmQgbm90IHJhaXNlIGFueSA8Y29kZT5ET01FeGNlcHRpb248L2NvZGU+LiBJbiBjYXNlIG9mIGVycm9yLCB0aGUKLSAgICogYmVoYXZpb3IgaXMgdW5kZWZpbmVkLiBUaGlzIGF0dHJpYnV0ZSBpcyA8Y29kZT50cnVlPC9jb2RlPiBieQotICAgKiBkZWZhdWx0cy4KLSAgICogQHNpbmNlIERPTSBMZXZlbCAzCi0gICAqCi0gICAqIE5FRURTRE9DICgkb2JqZWN0TmFtZSQpIEByZXR1cm4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGdldFN0cmljdEVycm9yQ2hlY2tpbmcoKQotICB7Ci0KLSAgICBlcnJvcihYTUxFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsKLQotICAgIHJldHVybiBmYWxzZTsKLSAgfQotCi0gIC8qKgotICAgKiA8cD5FWFBFUklNRU5UQUwhIEJhc2VkIG9uIHRoZSA8YQotICAgKiBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAxL1dELURPTS1MZXZlbC0zLUNvcmUtMjAwMTA2MDUnPkRvY3VtZW50Ci0gICAqIE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAzIENvcmUgV29ya2luZyBEcmFmdCBvZiA1IEp1bmUgMjAwMS48L2E+LgotICAgKiA8cD4KLSAgICogQW4gYXR0cmlidXRlIHNwZWNpZnlpbmcgd2hldGhlciBlcnJvcnMgY2hlY2tpbmcgaXMgZW5mb3JjZWQgb3Igbm90LgotICAgKiBXaGVuIHNldCB0byA8Y29kZT5mYWxzZTwvY29kZT4sIHRoZSBpbXBsZW1lbnRhdGlvbiBpcyBmcmVlIHRvIG5vdAotICAgKiB0ZXN0IGV2ZXJ5IHBvc3NpYmxlIGVycm9yIGNhc2Ugbm9ybWFsbHkgZGVmaW5lZCBvbiBET00gb3BlcmF0aW9ucywKLSAgICogYW5kIG5vdCByYWlzZSBhbnkgPGNvZGU+RE9NRXhjZXB0aW9uPC9jb2RlPi4gSW4gY2FzZSBvZiBlcnJvciwgdGhlCi0gICAqIGJlaGF2aW9yIGlzIHVuZGVmaW5lZC4gVGhpcyBhdHRyaWJ1dGUgaXMgPGNvZGU+dHJ1ZTwvY29kZT4gYnkKLSAgICogZGVmYXVsdHMuCi0gICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgKgotICAgKiBORUVEU0RPQyBAcGFyYW0gc3RyaWN0RXJyb3JDaGVja2luZwotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0U3RyaWN0RXJyb3JDaGVja2luZyhib29sZWFuIHN0cmljdEVycm9yQ2hlY2tpbmcpCi0gIHsKLSAgICBlcnJvcihYTUxFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsKLSAgfQotCi0gIC8qKgotICAgKiA8cD5FWFBFUklNRU5UQUwhIEJhc2VkIG9uIHRoZSA8YQotICAgKiBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAxL1dELURPTS1MZXZlbC0zLUNvcmUtMjAwMTA2MDUnPkRvY3VtZW50Ci0gICAqIE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAzIENvcmUgV29ya2luZyBEcmFmdCBvZiA1IEp1bmUgMjAwMS48L2E+LgotICAgKiA8cD4KLSAgICogQW4gYXR0cmlidXRlIHNwZWNpZnlpbmcsIGFzIHBhcnQgb2YgdGhlIFhNTCBkZWNsYXJhdGlvbiwgdGhlIHZlcnNpb24KLSAgICogbnVtYmVyIG9mIHRoaXMgZG9jdW1lbnQuIFRoaXMgaXMgPGNvZGU+bnVsbDwvY29kZT4gd2hlbiB1bnNwZWNpZmllZC4KLSAgICogQHNpbmNlIERPTSBMZXZlbCAzCi0gICAqCi0gICAqIE5FRURTRE9DICgkb2JqZWN0TmFtZSQpIEByZXR1cm4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0VmVyc2lvbigpCi0gIHsKLQotICAgIGVycm9yKFhNTEVycm9yUmVzb3VyY2VzLkVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQpOwotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogPHA+RVhQRVJJTUVOVEFMISBCYXNlZCBvbiB0aGUgPGEKLSAgICogaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMS9XRC1ET00tTGV2ZWwtMy1Db3JlLTIwMDEwNjA1Jz5Eb2N1bWVudAotICAgKiBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMyBDb3JlIFdvcmtpbmcgRHJhZnQgb2YgNSBKdW5lIDIwMDEuPC9hPi4KLSAgICogPHA+Ci0gICAqIEFuIGF0dHJpYnV0ZSBzcGVjaWZ5aW5nLCBhcyBwYXJ0IG9mIHRoZSBYTUwgZGVjbGFyYXRpb24sIHRoZSB2ZXJzaW9uCi0gICAqIG51bWJlciBvZiB0aGlzIGRvY3VtZW50LiBUaGlzIGlzIDxjb2RlPm51bGw8L2NvZGU+IHdoZW4gdW5zcGVjaWZpZWQuCi0gICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgKgotICAgKiBORUVEU0RPQyBAcGFyYW0gdmVyc2lvbgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0VmVyc2lvbihTdHJpbmcgdmVyc2lvbikKLSAgewotICAgIGVycm9yKFhNTEVycm9yUmVzb3VyY2VzLkVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQpOwotICB9Ci0KLQotCi0vL1JBTUVTSCA6IFBlbmRpbmcgcHJvcGVyIGltcGxlbWVudGF0aW9uIG9mIERPTSBMZXZlbCAzCi0KLSAgICBwdWJsaWMgT2JqZWN0IHNldFVzZXJEYXRhKFN0cmluZyBrZXksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPYmplY3QgZGF0YSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVzZXJEYXRhSGFuZGxlciBoYW5kbGVyKSB7Ci0gICAgICAgIHJldHVybiBnZXRPd25lckRvY3VtZW50KCkuc2V0VXNlckRhdGEoIGtleSwgZGF0YSwgaGFuZGxlcik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0cmlldmVzIHRoZSBvYmplY3QgYXNzb2NpYXRlZCB0byBhIGtleSBvbiBhIHRoaXMgbm9kZS4gVGhlIG9iamVjdAotICAgICAqIG11c3QgZmlyc3QgaGF2ZSBiZWVuIHNldCB0byB0aGlzIG5vZGUgYnkgY2FsbGluZwotICAgICAqIDxjb2RlPnNldFVzZXJEYXRhPC9jb2RlPiB3aXRoIHRoZSBzYW1lIGtleS4KLSAgICAgKiBAcGFyYW0ga2V5IFRoZSBrZXkgdGhlIG9iamVjdCBpcyBhc3NvY2lhdGVkIHRvLgotICAgICAqIEByZXR1cm4gUmV0dXJucyB0aGUgPGNvZGU+RE9NT2JqZWN0PC9jb2RlPiBhc3NvY2lhdGVkIHRvIHRoZSBnaXZlbiBrZXkKLSAgICAgKiAgIG9uIHRoaXMgbm9kZSwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlcmUgd2FzIG5vbmUuCi0gICAgICogQHNpbmNlIERPTSBMZXZlbCAzCi0gICAgICovCi0gICAgcHVibGljIE9iamVjdCBnZXRVc2VyRGF0YShTdHJpbmcga2V5KSB7Ci0gICAgICAgIHJldHVybiBnZXRPd25lckRvY3VtZW50KCkuZ2V0VXNlckRhdGEoIGtleSk7Ci0gICAgfQotCi0gICAgICAvKioKLSAgICAgKiAgVGhpcyBtZXRob2QgcmV0dXJucyBhIHNwZWNpYWxpemVkIG9iamVjdCB3aGljaCBpbXBsZW1lbnRzIHRoZQotICAgICAqIHNwZWNpYWxpemVkIEFQSXMgb2YgdGhlIHNwZWNpZmllZCBmZWF0dXJlIGFuZCB2ZXJzaW9uLiBUaGUKLSAgICAgKiBzcGVjaWFsaXplZCBvYmplY3QgbWF5IGFsc28gYmUgb2J0YWluZWQgYnkgdXNpbmcgYmluZGluZy1zcGVjaWZpYwotICAgICAqIGNhc3RpbmcgbWV0aG9kcyBidXQgaXMgbm90IG5lY2Vzc2FyaWx5IGV4cGVjdGVkIHRvLCBhcyBkaXNjdXNzZWQgaW4gTWl4ZWQgRE9NIGltcGxlbWVudGF0aW9ucy4KLSAgICAgKiBAcGFyYW0gZmVhdHVyZSBUaGUgbmFtZSBvZiB0aGUgZmVhdHVyZSByZXF1ZXN0ZWQgKGNhc2UtaW5zZW5zaXRpdmUpLgotICAgICAqIEBwYXJhbSB2ZXJzaW9uICBUaGlzIGlzIHRoZSB2ZXJzaW9uIG51bWJlciBvZiB0aGUgZmVhdHVyZSB0byB0ZXN0LiBJZgotICAgICAqICAgdGhlIHZlcnNpb24gaXMgPGNvZGU+bnVsbDwvY29kZT4gb3IgdGhlIGVtcHR5IHN0cmluZywgc3VwcG9ydGluZwotICAgICAqICAgYW55IHZlcnNpb24gb2YgdGhlIGZlYXR1cmUgd2lsbCBjYXVzZSB0aGUgbWV0aG9kIHRvIHJldHVybiBhbgotICAgICAqICAgb2JqZWN0IHRoYXQgc3VwcG9ydHMgYXQgbGVhc3Qgb25lIHZlcnNpb24gb2YgdGhlIGZlYXR1cmUuCi0gICAgICogQHJldHVybiAgUmV0dXJucyBhbiBvYmplY3Qgd2hpY2ggaW1wbGVtZW50cyB0aGUgc3BlY2lhbGl6ZWQgQVBJcyBvZgotICAgICAqICAgdGhlIHNwZWNpZmllZCBmZWF0dXJlIGFuZCB2ZXJzaW9uLCBpZiBhbnksIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmCi0gICAgICogICB0aGVyZSBpcyBubyBvYmplY3Qgd2hpY2ggaW1wbGVtZW50cyBpbnRlcmZhY2VzIGFzc29jaWF0ZWQgd2l0aCB0aGF0Ci0gICAgICogICBmZWF0dXJlLiBJZiB0aGUgPGNvZGU+RE9NT2JqZWN0PC9jb2RlPiByZXR1cm5lZCBieSB0aGlzIG1ldGhvZAotICAgICAqICAgaW1wbGVtZW50cyB0aGUgPGNvZGU+Tm9kZTwvY29kZT4gaW50ZXJmYWNlLCBpdCBtdXN0IGRlbGVnYXRlIHRvIHRoZQotICAgICAqICAgcHJpbWFyeSBjb3JlIDxjb2RlPk5vZGU8L2NvZGU+IGFuZCBub3QgcmV0dXJuIHJlc3VsdHMgaW5jb25zaXN0ZW50Ci0gICAgICogICB3aXRoIHRoZSBwcmltYXJ5IGNvcmUgPGNvZGU+Tm9kZTwvY29kZT4gc3VjaCBhcyBhdHRyaWJ1dGVzLAotICAgICAqICAgY2hpbGROb2RlcywgZXRjLgotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgICAqLwotICAgIHB1YmxpYyBPYmplY3QgZ2V0RmVhdHVyZShTdHJpbmcgZmVhdHVyZSwgU3RyaW5nIHZlcnNpb24pIHsKLSAgICAgICAgLy8gd2UgZG9uJ3QgaGF2ZSBhbnkgYWx0ZXJuYXRlIG5vZGUsIGVpdGhlciB0aGlzIG5vZGUgZG9lcyB0aGUgam9iCi0gICAgICAgIC8vIG9yIHdlIGRvbid0IGhhdmUgYW55dGhpbmcgdGhhdCBkb2VzCi0gICAgICAgIHJldHVybiBpc1N1cHBvcnRlZChmZWF0dXJlLCB2ZXJzaW9uKSA/IHRoaXMgOiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRlc3RzIHdoZXRoZXIgdHdvIG5vZGVzIGFyZSBlcXVhbC4KLSAgICAgKiA8YnI+VGhpcyBtZXRob2QgdGVzdHMgZm9yIGVxdWFsaXR5IG9mIG5vZGVzLCBub3Qgc2FtZW5lc3MgKGkuZS4sCi0gICAgICogd2hldGhlciB0aGUgdHdvIG5vZGVzIGFyZSByZWZlcmVuY2VzIHRvIHRoZSBzYW1lIG9iamVjdCkgd2hpY2ggY2FuIGJlCi0gICAgICogdGVzdGVkIHdpdGggPGNvZGU+Tm9kZS5pc1NhbWVOb2RlPC9jb2RlPi4gQWxsIG5vZGVzIHRoYXQgYXJlIHRoZSBzYW1lCi0gICAgICogd2lsbCBhbHNvIGJlIGVxdWFsLCB0aG91Z2ggdGhlIHJldmVyc2UgbWF5IG5vdCBiZSB0cnVlLgotICAgICAqIDxicj5Ud28gbm9kZXMgYXJlIGVxdWFsIGlmIGFuZCBvbmx5IGlmIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKLSAgICAgKiBzYXRpc2ZpZWQ6IFRoZSB0d28gbm9kZXMgYXJlIG9mIHRoZSBzYW1lIHR5cGUuVGhlIGZvbGxvd2luZyBzdHJpbmcKLSAgICAgKiBhdHRyaWJ1dGVzIGFyZSBlcXVhbDogPGNvZGU+bm9kZU5hbWU8L2NvZGU+LCA8Y29kZT5sb2NhbE5hbWU8L2NvZGU+LAotICAgICAqIDxjb2RlPm5hbWVzcGFjZVVSSTwvY29kZT4sIDxjb2RlPnByZWZpeDwvY29kZT4sIDxjb2RlPm5vZGVWYWx1ZTwvY29kZT4KLSAgICAgKiAsIDxjb2RlPmJhc2VVUkk8L2NvZGU+LiBUaGlzIGlzOiB0aGV5IGFyZSBib3RoIDxjb2RlPm51bGw8L2NvZGU+LCBvcgotICAgICAqIHRoZXkgaGF2ZSB0aGUgc2FtZSBsZW5ndGggYW5kIGFyZSBjaGFyYWN0ZXIgZm9yIGNoYXJhY3RlciBpZGVudGljYWwuCi0gICAgICogVGhlIDxjb2RlPmF0dHJpYnV0ZXM8L2NvZGU+IDxjb2RlPk5hbWVkTm9kZU1hcHM8L2NvZGU+IGFyZSBlcXVhbC4KLSAgICAgKiBUaGlzIGlzOiB0aGV5IGFyZSBib3RoIDxjb2RlPm51bGw8L2NvZGU+LCBvciB0aGV5IGhhdmUgdGhlIHNhbWUKLSAgICAgKiBsZW5ndGggYW5kIGZvciBlYWNoIG5vZGUgdGhhdCBleGlzdHMgaW4gb25lIG1hcCB0aGVyZSBpcyBhIG5vZGUgdGhhdAotICAgICAqIGV4aXN0cyBpbiB0aGUgb3RoZXIgbWFwIGFuZCBpcyBlcXVhbCwgYWx0aG91Z2ggbm90IG5lY2Vzc2FyaWx5IGF0IHRoZQotICAgICAqIHNhbWUgaW5kZXguVGhlIDxjb2RlPmNoaWxkTm9kZXM8L2NvZGU+IDxjb2RlPk5vZGVMaXN0czwvY29kZT4gYXJlCi0gICAgICogZXF1YWwuIFRoaXMgaXM6IHRoZXkgYXJlIGJvdGggPGNvZGU+bnVsbDwvY29kZT4sIG9yIHRoZXkgaGF2ZSB0aGUKLSAgICAgKiBzYW1lIGxlbmd0aCBhbmQgY29udGFpbiBlcXVhbCBub2RlcyBhdCB0aGUgc2FtZSBpbmRleC4gVGhpcyBpcyB0cnVlCi0gICAgICogZm9yIDxjb2RlPkF0dHI8L2NvZGU+IG5vZGVzIGFzIGZvciBhbnkgb3RoZXIgdHlwZSBvZiBub2RlLiBOb3RlIHRoYXQKLSAgICAgKiBub3JtYWxpemF0aW9uIGNhbiBhZmZlY3QgZXF1YWxpdHk7IHRvIGF2b2lkIHRoaXMsIG5vZGVzIHNob3VsZCBiZQotICAgICAqIG5vcm1hbGl6ZWQgYmVmb3JlIGJlaW5nIGNvbXBhcmVkLgotICAgICAqIDxicj5Gb3IgdHdvIDxjb2RlPkRvY3VtZW50VHlwZTwvY29kZT4gbm9kZXMgdG8gYmUgZXF1YWwsIHRoZSBmb2xsb3dpbmcKLSAgICAgKiBjb25kaXRpb25zIG11c3QgYWxzbyBiZSBzYXRpc2ZpZWQ6IFRoZSBmb2xsb3dpbmcgc3RyaW5nIGF0dHJpYnV0ZXMKLSAgICAgKiBhcmUgZXF1YWw6IDxjb2RlPnB1YmxpY0lkPC9jb2RlPiwgPGNvZGU+c3lzdGVtSWQ8L2NvZGU+LAotICAgICAqIDxjb2RlPmludGVybmFsU3Vic2V0PC9jb2RlPi5UaGUgPGNvZGU+ZW50aXRpZXM8L2NvZGU+Ci0gICAgICogPGNvZGU+TmFtZWROb2RlTWFwczwvY29kZT4gYXJlIGVxdWFsLlRoZSA8Y29kZT5ub3RhdGlvbnM8L2NvZGU+Ci0gICAgICogPGNvZGU+TmFtZWROb2RlTWFwczwvY29kZT4gYXJlIGVxdWFsLgotICAgICAqIDxicj5PbiB0aGUgb3RoZXIgaGFuZCwgdGhlIGZvbGxvd2luZyBkbyBub3QgYWZmZWN0IGVxdWFsaXR5OiB0aGUKLSAgICAgKiA8Y29kZT5vd25lckRvY3VtZW50PC9jb2RlPiBhdHRyaWJ1dGUsIHRoZSA8Y29kZT5zcGVjaWZpZWQ8L2NvZGU+Ci0gICAgICogYXR0cmlidXRlIGZvciA8Y29kZT5BdHRyPC9jb2RlPiBub2RlcywgdGhlCi0gICAgICogPGNvZGU+aXNXaGl0ZXNwYWNlSW5FbGVtZW50Q29udGVudDwvY29kZT4gYXR0cmlidXRlIGZvcgotICAgICAqIDxjb2RlPlRleHQ8L2NvZGU+IG5vZGVzLCBhcyB3ZWxsIGFzIGFueSB1c2VyIGRhdGEgb3IgZXZlbnQgbGlzdGVuZXJzCi0gICAgICogcmVnaXN0ZXJlZCBvbiB0aGUgbm9kZXMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYXJnIFRoZSBub2RlIHRvIGNvbXBhcmUgZXF1YWxpdHkgd2l0aC4KLSAgICAgKiBAcmV0dXJuIElmIHRoZSBub2RlcywgYW5kIHBvc3NpYmx5IHN1YnRyZWVzIGFyZSBlcXVhbCwKLSAgICAgKiAgIDxjb2RlPnRydWU8L2NvZGU+IG90aGVyd2lzZSA8Y29kZT5mYWxzZTwvY29kZT4uCi0gICAgICogQHNpbmNlIERPTSBMZXZlbCAzCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNFcXVhbE5vZGUoTm9kZSBhcmcpIHsKLSAgICAgICAgaWYgKGFyZyA9PSB0aGlzKSB7Ci0gICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgfQotICAgICAgICBpZiAoYXJnLmdldE5vZGVUeXBlKCkgIT0gZ2V0Tm9kZVR5cGUoKSkgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0gICAgICAgIC8vIGluIHRoZW9yeSBub2RlTmFtZSBjYW4ndCBiZSBudWxsIGJ1dCBiZXR0ZXIgYmUgY2FyZWZ1bAotICAgICAgICAvLyB3aG8ga25vd3Mgd2hhdCBvdGhlciBpbXBsZW1lbnRhdGlvbnMgbWF5IGJlIGRvaW5nPy4uLgotICAgICAgICBpZiAoZ2V0Tm9kZU5hbWUoKSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAoYXJnLmdldE5vZGVOYW1lKCkgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICghZ2V0Tm9kZU5hbWUoKS5lcXVhbHMoYXJnLmdldE5vZGVOYW1lKCkpKSB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoZ2V0TG9jYWxOYW1lKCkgPT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKGFyZy5nZXRMb2NhbE5hbWUoKSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKCFnZXRMb2NhbE5hbWUoKS5lcXVhbHMoYXJnLmdldExvY2FsTmFtZSgpKSkgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKGdldE5hbWVzcGFjZVVSSSgpID09IG51bGwpIHsKLSAgICAgICAgICAgIGlmIChhcmcuZ2V0TmFtZXNwYWNlVVJJKCkgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICghZ2V0TmFtZXNwYWNlVVJJKCkuZXF1YWxzKGFyZy5nZXROYW1lc3BhY2VVUkkoKSkpIHsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChnZXRQcmVmaXgoKSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAoYXJnLmdldFByZWZpeCgpICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoIWdldFByZWZpeCgpLmVxdWFscyhhcmcuZ2V0UHJlZml4KCkpKSB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoZ2V0Tm9kZVZhbHVlKCkgPT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKGFyZy5nZXROb2RlVmFsdWUoKSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKCFnZXROb2RlVmFsdWUoKS5lcXVhbHMoYXJnLmdldE5vZGVWYWx1ZSgpKSkgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0gICAgLyoKLSAgICAgICAgaWYgKGdldEJhc2VVUkkoKSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAoKChOb2RlSW1wbCkgYXJnKS5nZXRCYXNlVVJJKCkgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICghZ2V0QmFzZVVSSSgpLmVxdWFscygoKE5vZGVJbXBsKSBhcmcpLmdldEJhc2VVUkkoKSkpIHsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotKi8KLQotICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotICAgICAgLyoqCi0gICAgICogRE9NIExldmVsIDMgLSBFeHBlcmltZW50YWw6Ci0gICAgICogTG9vayB1cCB0aGUgbmFtZXNwYWNlIFVSSSBhc3NvY2lhdGVkIHRvIHRoZSBnaXZlbiBwcmVmaXgsIHN0YXJ0aW5nIGZyb20gdGhpcyBub2RlLgotICAgICAqIFVzZSBsb29rdXBOYW1lc3BhY2VVUkkobnVsbCkgdG8gbG9va3VwIHRoZSBkZWZhdWx0IG5hbWVzcGFjZQotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWVzcGFjZVVSSQotICAgICAqIEByZXR1cm4gdGggVVJJIGZvciB0aGUgbmFtZXNwYWNlCi0gICAgICogQHNpbmNlIERPTSBMZXZlbCAzCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBsb29rdXBOYW1lc3BhY2VVUkkoU3RyaW5nIHNwZWNpZmllZFByZWZpeCkgewotICAgICAgICBzaG9ydCB0eXBlID0gdGhpcy5nZXROb2RlVHlwZSgpOwotICAgICAgICBzd2l0Y2ggKHR5cGUpIHsKLSAgICAgICAgY2FzZSBOb2RlLkVMRU1FTlRfTk9ERSA6IHsKLQotICAgICAgICAgICAgICAgIFN0cmluZyBuYW1lc3BhY2UgPSB0aGlzLmdldE5hbWVzcGFjZVVSSSgpOwotICAgICAgICAgICAgICAgIFN0cmluZyBwcmVmaXggPSB0aGlzLmdldFByZWZpeCgpOwotICAgICAgICAgICAgICAgIGlmIChuYW1lc3BhY2UgIT1udWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIFJFVklTSVQ6IGlzIGl0IHBvc3NpYmxlIHRoYXQgcHJlZml4IGlzIGVtcHR5IHN0cmluZz8KLSAgICAgICAgICAgICAgICAgICAgaWYgKHNwZWNpZmllZFByZWZpeD09IG51bGwgJiYgcHJlZml4PT1zcGVjaWZpZWRQcmVmaXgpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGxvb2tpbmcgZm9yIGRlZmF1bHQgbmFtZXNwYWNlCi0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmFtZXNwYWNlOwotICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHByZWZpeCAhPSBudWxsICYmIHByZWZpeC5lcXVhbHMoc3BlY2lmaWVkUHJlZml4KSkgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gbm9uIGRlZmF1bHQgbmFtZXNwYWNlCi0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmFtZXNwYWNlOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGlmICh0aGlzLmhhc0F0dHJpYnV0ZXMoKSkgewotICAgICAgICAgICAgICAgICAgICBOYW1lZE5vZGVNYXAgbWFwID0gdGhpcy5nZXRBdHRyaWJ1dGVzKCk7Ci0gICAgICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBtYXAuZ2V0TGVuZ3RoKCk7Ci0gICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGk9MDtpPGxlbmd0aDtpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIE5vZGUgYXR0ciA9IG1hcC5pdGVtKGkpOwotICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGF0dHJQcmVmaXggPSBhdHRyLmdldFByZWZpeCgpOwotICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHZhbHVlID0gYXR0ci5nZXROb2RlVmFsdWUoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZSA9IGF0dHIuZ2V0TmFtZXNwYWNlVVJJKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAobmFtZXNwYWNlICE9bnVsbCAmJiBuYW1lc3BhY2UuZXF1YWxzKCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3htbG5zLyIpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYXQgdGhpcyBwb2ludCB3ZSBhcmUgZGVhbGluZyB3aXRoIERPTSBMZXZlbCAyIG5vZGVzIG9ubHkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3BlY2lmaWVkUHJlZml4ID09IG51bGwgJiYKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0ci5nZXROb2RlTmFtZSgpLmVxdWFscygieG1sbnMiKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBkZWZhdWx0IG5hbWVzcGFjZQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChhdHRyUHJlZml4ICE9bnVsbCAmJgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0clByZWZpeC5lcXVhbHMoInhtbG5zIikgJiYKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHIuZ2V0TG9jYWxOYW1lKCkuZXF1YWxzKHNwZWNpZmllZFByZWZpeCkpIHsKLSAgICAgICAgICAgICAgICAgLy8gbm9uIGRlZmF1bHQgbmFtZXNwYWNlCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLyoKLSAgICAgICAgICAgICAgICBOb2RlSW1wbCBhbmNlc3RvciA9IChOb2RlSW1wbClnZXRFbGVtZW50QW5jZXN0b3IodGhpcyk7Ci0gICAgICAgICAgICAgICAgaWYgKGFuY2VzdG9yICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFuY2VzdG9yLmxvb2t1cE5hbWVzcGFjZVVSSShzcGVjaWZpZWRQcmVmaXgpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAqLwotCi0gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0KLQotICAgICAgICAgICAgfQotLyoKLSAgICAgICAgY2FzZSBOb2RlLkRPQ1VNRU5UX05PREUgOiB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuKChOb2RlSW1wbCkoKERvY3VtZW50KXRoaXMpLmdldERvY3VtZW50RWxlbWVudCgpKS5sb29rdXBOYW1lc3BhY2VVUkkoc3BlY2lmaWVkUHJlZml4KSA7Ci0gICAgICAgICAgICB9Ci0qLwotICAgICAgICBjYXNlIE5vZGUuRU5USVRZX05PREUgOgotICAgICAgICBjYXNlIE5vZGUuTk9UQVRJT05fTk9ERToKLSAgICAgICAgY2FzZSBOb2RlLkRPQ1VNRU5UX0ZSQUdNRU5UX05PREU6Ci0gICAgICAgIGNhc2UgTm9kZS5ET0NVTUVOVF9UWVBFX05PREU6Ci0gICAgICAgICAgICAvLyB0eXBlIGlzIHVua25vd24KLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICBjYXNlIE5vZGUuQVRUUklCVVRFX05PREU6ewotICAgICAgICAgICAgICAgIGlmICh0aGlzLmdldE93bmVyRWxlbWVudCgpLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5FTEVNRU5UX05PREUpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGdldE93bmVyRWxlbWVudCgpLmxvb2t1cE5hbWVzcGFjZVVSSShzcGVjaWZpZWRQcmVmaXgpOwotCi0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICAgICAgfQotICAgICAgICBkZWZhdWx0OnsKLSAgICAgICAgICAgLyoKLSAgICAgICAgICAgICAgICBOb2RlSW1wbCBhbmNlc3RvciA9IChOb2RlSW1wbClnZXRFbGVtZW50QW5jZXN0b3IodGhpcyk7Ci0gICAgICAgICAgICAgICAgaWYgKGFuY2VzdG9yICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFuY2VzdG9yLmxvb2t1cE5hbWVzcGFjZVVSSShzcGVjaWZpZWRQcmVmaXgpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAqLwotICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICAgICAgfQotCi0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqICBET00gTGV2ZWwgMzogRXhwZXJpbWVudGFsCi0gICAgICogIFRoaXMgbWV0aG9kIGNoZWNrcyBpZiB0aGUgc3BlY2lmaWVkIDxjb2RlPm5hbWVzcGFjZVVSSTwvY29kZT4gaXMgdGhlCi0gICAgICogIGRlZmF1bHQgbmFtZXNwYWNlIG9yIG5vdC4KLSAgICAgKiAgQHBhcmFtIG5hbWVzcGFjZVVSSSBUaGUgbmFtZXNwYWNlIFVSSSB0byBsb29rIGZvci4KLSAgICAgKiAgQHJldHVybiAgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIHNwZWNpZmllZCA8Y29kZT5uYW1lc3BhY2VVUkk8L2NvZGU+Ci0gICAgICogICBpcyB0aGUgZGVmYXVsdCBuYW1lc3BhY2UsIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuCi0gICAgICogQHNpbmNlIERPTSBMZXZlbCAzCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNEZWZhdWx0TmFtZXNwYWNlKFN0cmluZyBuYW1lc3BhY2VVUkkpewotICAgICAgIC8qCi0gICAgICAgIC8vIFJFVklTSVQ6IHJlbW92ZSBjYXN0cyB3aGVuIERPTSBMMyBiZWNvbWVzIFJFQy4KLSAgICAgICAgc2hvcnQgdHlwZSA9IHRoaXMuZ2V0Tm9kZVR5cGUoKTsKLSAgICAgICAgc3dpdGNoICh0eXBlKSB7Ci0gICAgICAgIGNhc2UgTm9kZS5FTEVNRU5UX05PREU6IHsKLSAgICAgICAgICAgIFN0cmluZyBuYW1lc3BhY2UgPSB0aGlzLmdldE5hbWVzcGFjZVVSSSgpOwotICAgICAgICAgICAgU3RyaW5nIHByZWZpeCA9IHRoaXMuZ2V0UHJlZml4KCk7Ci0KLSAgICAgICAgICAgIC8vIFJFVklTSVQ6IGlzIGl0IHBvc3NpYmxlIHRoYXQgcHJlZml4IGlzIGVtcHR5IHN0cmluZz8KLSAgICAgICAgICAgIGlmIChwcmVmaXggPT0gbnVsbCB8fCBwcmVmaXgubGVuZ3RoKCkgPT0gMCkgewotICAgICAgICAgICAgICAgIGlmIChuYW1lc3BhY2VVUkkgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gKG5hbWVzcGFjZSA9PSBuYW1lc3BhY2VVUkkpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICByZXR1cm4gbmFtZXNwYWNlVVJJLmVxdWFscyhuYW1lc3BhY2UpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKHRoaXMuaGFzQXR0cmlidXRlcygpKSB7Ci0gICAgICAgICAgICAgICAgRWxlbWVudEltcGwgZWxlbSA9IChFbGVtZW50SW1wbCl0aGlzOwotICAgICAgICAgICAgICAgIE5vZGVJbXBsIGF0dHIgPSAoTm9kZUltcGwpZWxlbS5nZXRBdHRyaWJ1dGVOb2RlTlMoImh0dHA6Ly93d3cudzMub3JnLzIwMDAveG1sbnMvIiwgInhtbG5zIik7Ci0gICAgICAgICAgICAgICAgaWYgKGF0dHIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdmFsdWUgPSBhdHRyLmdldE5vZGVWYWx1ZSgpOwotICAgICAgICAgICAgICAgICAgICBpZiAobmFtZXNwYWNlVVJJID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAobmFtZXNwYWNlID09IHZhbHVlKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmFtZXNwYWNlVVJJLmVxdWFscyh2YWx1ZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBOb2RlSW1wbCBhbmNlc3RvciA9IChOb2RlSW1wbClnZXRFbGVtZW50QW5jZXN0b3IodGhpcyk7Ci0gICAgICAgICAgICBpZiAoYW5jZXN0b3IgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJldHVybiBhbmNlc3Rvci5pc0RlZmF1bHROYW1lc3BhY2UobmFtZXNwYWNlVVJJKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotICAgICAgICBjYXNlIE5vZGUuRE9DVU1FTlRfTk9ERTp7Ci0gICAgICAgICAgICAgICAgcmV0dXJuKChOb2RlSW1wbCkoKERvY3VtZW50KXRoaXMpLmdldERvY3VtZW50RWxlbWVudCgpKS5pc0RlZmF1bHROYW1lc3BhY2UobmFtZXNwYWNlVVJJKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICBjYXNlIE5vZGUuRU5USVRZX05PREUgOgotICAgICAgICAgIGNhc2UgTm9kZS5OT1RBVElPTl9OT0RFOgotICAgICAgICBjYXNlIE5vZGUuRE9DVU1FTlRfRlJBR01FTlRfTk9ERToKLSAgICAgICAgY2FzZSBOb2RlLkRPQ1VNRU5UX1RZUEVfTk9ERToKLSAgICAgICAgICAgIC8vIHR5cGUgaXMgdW5rbm93bgotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICBjYXNlIE5vZGUuQVRUUklCVVRFX05PREU6ewotICAgICAgICAgICAgICAgIGlmICh0aGlzLm93bmVyTm9kZS5nZXROb2RlVHlwZSgpID09IE5vZGUuRUxFTUVOVF9OT0RFKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBvd25lck5vZGUuaXNEZWZhdWx0TmFtZXNwYWNlKG5hbWVzcGFjZVVSSSk7Ci0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICBkZWZhdWx0OnsKLSAgICAgICAgICAgICAgICBOb2RlSW1wbCBhbmNlc3RvciA9IChOb2RlSW1wbClnZXRFbGVtZW50QW5jZXN0b3IodGhpcyk7Ci0gICAgICAgICAgICAgICAgaWYgKGFuY2VzdG9yICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFuY2VzdG9yLmlzRGVmYXVsdE5hbWVzcGFjZShuYW1lc3BhY2VVUkkpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgfQotKi8KLSAgICAgICAgcmV0dXJuIGZhbHNlOwotCi0KLSAgICB9Ci0KLSAgICAgIC8qKgotICAgICAqCi0gICAgICogRE9NIExldmVsIDMgLSBFeHBlcmltZW50YWw6Ci0gICAgICogTG9vayB1cCB0aGUgcHJlZml4IGFzc29jaWF0ZWQgdG8gdGhlIGdpdmVuIG5hbWVzcGFjZSBVUkksIHN0YXJ0aW5nIGZyb20gdGhpcyBub2RlLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWVzcGFjZVVSSQotICAgICAqIEByZXR1cm4gdGhlIHByZWZpeCBmb3IgdGhlIG5hbWVzcGFjZQotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgbG9va3VwUHJlZml4KFN0cmluZyBuYW1lc3BhY2VVUkkpewotCi0gICAgICAgIC8vIFJFVklTSVQ6IFdoZW4gTmFtZXNwYWNlcyAxLjEgY29tZXMgb3V0IHRoaXMgbWF5IG5vdCBiZSB0cnVlCi0gICAgICAgIC8vIFByZWZpeCBjYW4ndCBiZSBib3VuZCB0byBudWxsIG5hbWVzcGFjZQotICAgICAgICBpZiAobmFtZXNwYWNlVVJJID09IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0KLSAgICAgICAgc2hvcnQgdHlwZSA9IHRoaXMuZ2V0Tm9kZVR5cGUoKTsKLQotICAgICAgICBzd2l0Y2ggKHR5cGUpIHsKLS8qCi0gICAgICAgIGNhc2UgTm9kZS5FTEVNRU5UX05PREU6IHsKLQotICAgICAgICAgICAgICAgIFN0cmluZyBuYW1lc3BhY2UgPSB0aGlzLmdldE5hbWVzcGFjZVVSSSgpOyAvLyB0byBmbGlwIG91dCBjaGlsZHJlbgotICAgICAgICAgICAgICAgIHJldHVybiBsb29rdXBOYW1lc3BhY2VQcmVmaXgobmFtZXNwYWNlVVJJLCAoRWxlbWVudEltcGwpdGhpcyk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgY2FzZSBOb2RlLkRPQ1VNRU5UX05PREU6ewotICAgICAgICAgICAgICAgIHJldHVybigoTm9kZUltcGwpKChEb2N1bWVudCl0aGlzKS5nZXREb2N1bWVudEVsZW1lbnQoKSkubG9va3VwUHJlZml4KG5hbWVzcGFjZVVSSSk7Ci0gICAgICAgICAgICB9Ci0qLwotICAgICAgICBjYXNlIE5vZGUuRU5USVRZX05PREUgOgotICAgICAgICBjYXNlIE5vZGUuTk9UQVRJT05fTk9ERToKLSAgICAgICAgY2FzZSBOb2RlLkRPQ1VNRU5UX0ZSQUdNRU5UX05PREU6Ci0gICAgICAgIGNhc2UgTm9kZS5ET0NVTUVOVF9UWVBFX05PREU6Ci0gICAgICAgICAgICAvLyB0eXBlIGlzIHVua25vd24KLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICBjYXNlIE5vZGUuQVRUUklCVVRFX05PREU6ewotICAgICAgICAgICAgICAgIGlmICh0aGlzLmdldE93bmVyRWxlbWVudCgpLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5FTEVNRU5UX05PREUpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGdldE93bmVyRWxlbWVudCgpLmxvb2t1cFByZWZpeChuYW1lc3BhY2VVUkkpOwotCi0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICAgICAgfQotICAgICAgICBkZWZhdWx0OnsKLS8qCi0gICAgICAgICAgICAgICAgTm9kZUltcGwgYW5jZXN0b3IgPSAoTm9kZUltcGwpZ2V0RWxlbWVudEFuY2VzdG9yKHRoaXMpOwotICAgICAgICAgICAgICAgIGlmIChhbmNlc3RvciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBhbmNlc3Rvci5sb29rdXBQcmVmaXgobmFtZXNwYWNlVVJJKTsKLSAgICAgICAgICAgICAgICB9Ci0qLwotICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICAgICAgfQotICAgICAgICAgfQotICAgIH0KLQotICAgICAvKioKLSAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhpcyBub2RlIGlzIHRoZSBzYW1lIG5vZGUgYXMgdGhlIGdpdmVuIG9uZS4KLSAgICAgKiA8YnI+VGhpcyBtZXRob2QgcHJvdmlkZXMgYSB3YXkgdG8gZGV0ZXJtaW5lIHdoZXRoZXIgdHdvCi0gICAgICogPGNvZGU+Tm9kZTwvY29kZT4gcmVmZXJlbmNlcyByZXR1cm5lZCBieSB0aGUgaW1wbGVtZW50YXRpb24gcmVmZXJlbmNlCi0gICAgICogdGhlIHNhbWUgb2JqZWN0LiBXaGVuIHR3byA8Y29kZT5Ob2RlPC9jb2RlPiByZWZlcmVuY2VzIGFyZSByZWZlcmVuY2VzCi0gICAgICogdG8gdGhlIHNhbWUgb2JqZWN0LCBldmVuIGlmIHRocm91Z2ggYSBwcm94eSwgdGhlIHJlZmVyZW5jZXMgbWF5IGJlCi0gICAgICogdXNlZCBjb21wbGV0ZWx5IGludGVyY2hhbmdhYmx5LCBzdWNoIHRoYXQgYWxsIGF0dHJpYnV0ZXMgaGF2ZSB0aGUKLSAgICAgKiBzYW1lIHZhbHVlcyBhbmQgY2FsbGluZyB0aGUgc2FtZSBET00gbWV0aG9kIG9uIGVpdGhlciByZWZlcmVuY2UKLSAgICAgKiBhbHdheXMgaGFzIGV4YWN0bHkgdGhlIHNhbWUgZWZmZWN0LgotICAgICAqIEBwYXJhbSBvdGhlciBUaGUgbm9kZSB0byB0ZXN0IGFnYWluc3QuCi0gICAgICogQHJldHVybiBSZXR1cm5zIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBub2RlcyBhcmUgdGhlIHNhbWUsCi0gICAgICogICA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLgotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzU2FtZU5vZGUoTm9kZSBvdGhlcikgewotICAgICAgICAvLyB3ZSBkbyBub3QgdXNlIGFueSB3cmFwcGVyIHNvIHRoZSBhbnN3ZXIgaXMgb2J2aW91cwotICAgICAgICByZXR1cm4gdGhpcyA9PSBvdGhlcjsKLSAgICB9Ci0KLSAgICAgIC8qKgotICAgICAqIFRoaXMgYXR0cmlidXRlIHJldHVybnMgdGhlIHRleHQgY29udGVudCBvZiB0aGlzIG5vZGUgYW5kIGl0cwotICAgICAqIGRlc2NlbmRhbnRzLiBXaGVuIGl0IGlzIGRlZmluZWQgdG8gYmUgbnVsbCwgc2V0dGluZyBpdCBoYXMgbm8gZWZmZWN0LgotICAgICAqIFdoZW4gc2V0LCBhbnkgcG9zc2libGUgY2hpbGRyZW4gdGhpcyBub2RlIG1heSBoYXZlIGFyZSByZW1vdmVkIGFuZAotICAgICAqIHJlcGxhY2VkIGJ5IGEgc2luZ2xlIDxjb2RlPlRleHQ8L2NvZGU+IG5vZGUgY29udGFpbmluZyB0aGUgc3RyaW5nCi0gICAgICogdGhpcyBhdHRyaWJ1dGUgaXMgc2V0IHRvLiBPbiBnZXR0aW5nLCBubyBzZXJpYWxpemF0aW9uIGlzIHBlcmZvcm1lZCwKLSAgICAgKiB0aGUgcmV0dXJuZWQgc3RyaW5nIGRvZXMgbm90IGNvbnRhaW4gYW55IG1hcmt1cC4gTm8gd2hpdGVzcGFjZQotICAgICAqIG5vcm1hbGl6YXRpb24gaXMgcGVyZm9ybWVkLCB0aGUgcmV0dXJuZWQgc3RyaW5nIGRvZXMgbm90IGNvbnRhaW4gdGhlCi0gICAgICogZWxlbWVudCBjb250ZW50IHdoaXRlc3BhY2VzIC4gU2ltaWxhcmx5LCBvbiBzZXR0aW5nLCBubyBwYXJzaW5nIGlzCi0gICAgICogcGVyZm9ybWVkIGVpdGhlciwgdGhlIGlucHV0IHN0cmluZyBpcyB0YWtlbiBhcyBwdXJlIHRleHR1YWwgY29udGVudC4KLSAgICAgKiA8YnI+VGhlIHN0cmluZyByZXR1cm5lZCBpcyBtYWRlIG9mIHRoZSB0ZXh0IGNvbnRlbnQgb2YgdGhpcyBub2RlCi0gICAgICogZGVwZW5kaW5nIG9uIGl0cyB0eXBlLCBhcyBkZWZpbmVkIGJlbG93OgotICAgICAqIDx0YWJsZSBib3JkZXI9JzEnPgotICAgICAqIDx0cj4KLSAgICAgKiA8dGg+Tm9kZSB0eXBlPC90aD4KLSAgICAgKiA8dGg+Q29udGVudDwvdGg+Ci0gICAgICogPC90cj4KLSAgICAgKiA8dHI+Ci0gICAgICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz4KLSAgICAgKiBFTEVNRU5UX05PREUsIEVOVElUWV9OT0RFLCBFTlRJVFlfUkVGRVJFTkNFX05PREUsCi0gICAgICogRE9DVU1FTlRfRlJBR01FTlRfTk9ERTwvdGQ+Ci0gICAgICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz5jb25jYXRlbmF0aW9uIG9mIHRoZSA8Y29kZT50ZXh0Q29udGVudDwvY29kZT4KLSAgICAgKiBhdHRyaWJ1dGUgdmFsdWUgb2YgZXZlcnkgY2hpbGQgbm9kZSwgZXhjbHVkaW5nIENPTU1FTlRfTk9ERSBhbmQKLSAgICAgKiBQUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREUgbm9kZXM8L3RkPgotICAgICAqIDwvdHI+Ci0gICAgICogPHRyPgotICAgICAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+QVRUUklCVVRFX05PREUsIFRFWFRfTk9ERSwKLSAgICAgKiBDREFUQV9TRUNUSU9OX05PREUsIENPTU1FTlRfTk9ERSwgUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFPC90ZD4KLSAgICAgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPgotICAgICAqIDxjb2RlPm5vZGVWYWx1ZTwvY29kZT48L3RkPgotICAgICAqIDwvdHI+Ci0gICAgICogPHRyPgotICAgICAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+RE9DVU1FTlRfTk9ERSwgRE9DVU1FTlRfVFlQRV9OT0RFLCBOT1RBVElPTl9OT0RFPC90ZD4KLSAgICAgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPgotICAgICAqIG51bGw8L3RkPgotICAgICAqIDwvdHI+Ci0gICAgICogPC90YWJsZT4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgd2hlbiB0aGUgbm9kZSBpcyByZWFkb25seS4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgRE9NU1RSSU5HX1NJWkVfRVJSOiBSYWlzZWQgd2hlbiBpdCB3b3VsZCByZXR1cm4gbW9yZSBjaGFyYWN0ZXJzIHRoYW4KLSAgICAgKiAgIGZpdCBpbiBhIDxjb2RlPkRPTVN0cmluZzwvY29kZT4gdmFyaWFibGUgb24gdGhlIGltcGxlbWVudGF0aW9uCi0gICAgICogICBwbGF0Zm9ybS4KLSAgICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFRleHRDb250ZW50KFN0cmluZyB0ZXh0Q29udGVudCkKLSAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0gICAgICAgIHNldE5vZGVWYWx1ZSh0ZXh0Q29udGVudCk7Ci0gICAgfQotICAgIC8qKgotICAgICAqIFRoaXMgYXR0cmlidXRlIHJldHVybnMgdGhlIHRleHQgY29udGVudCBvZiB0aGlzIG5vZGUgYW5kIGl0cwotICAgICAqIGRlc2NlbmRhbnRzLiBXaGVuIGl0IGlzIGRlZmluZWQgdG8gYmUgbnVsbCwgc2V0dGluZyBpdCBoYXMgbm8gZWZmZWN0LgotICAgICAqIFdoZW4gc2V0LCBhbnkgcG9zc2libGUgY2hpbGRyZW4gdGhpcyBub2RlIG1heSBoYXZlIGFyZSByZW1vdmVkIGFuZAotICAgICAqIHJlcGxhY2VkIGJ5IGEgc2luZ2xlIDxjb2RlPlRleHQ8L2NvZGU+IG5vZGUgY29udGFpbmluZyB0aGUgc3RyaW5nCi0gICAgICogdGhpcyBhdHRyaWJ1dGUgaXMgc2V0IHRvLiBPbiBnZXR0aW5nLCBubyBzZXJpYWxpemF0aW9uIGlzIHBlcmZvcm1lZCwKLSAgICAgKiB0aGUgcmV0dXJuZWQgc3RyaW5nIGRvZXMgbm90IGNvbnRhaW4gYW55IG1hcmt1cC4gTm8gd2hpdGVzcGFjZQotICAgICAqIG5vcm1hbGl6YXRpb24gaXMgcGVyZm9ybWVkLCB0aGUgcmV0dXJuZWQgc3RyaW5nIGRvZXMgbm90IGNvbnRhaW4gdGhlCi0gICAgICogZWxlbWVudCBjb250ZW50IHdoaXRlc3BhY2VzIC4gU2ltaWxhcmx5LCBvbiBzZXR0aW5nLCBubyBwYXJzaW5nIGlzCi0gICAgICogcGVyZm9ybWVkIGVpdGhlciwgdGhlIGlucHV0IHN0cmluZyBpcyB0YWtlbiBhcyBwdXJlIHRleHR1YWwgY29udGVudC4KLSAgICAgKiA8YnI+VGhlIHN0cmluZyByZXR1cm5lZCBpcyBtYWRlIG9mIHRoZSB0ZXh0IGNvbnRlbnQgb2YgdGhpcyBub2RlCi0gICAgICogZGVwZW5kaW5nIG9uIGl0cyB0eXBlLCBhcyBkZWZpbmVkIGJlbG93OgotICAgICAqIDx0YWJsZSBib3JkZXI9JzEnPgotICAgICAqIDx0cj4KLSAgICAgKiA8dGg+Tm9kZSB0eXBlPC90aD4KLSAgICAgKiA8dGg+Q29udGVudDwvdGg+Ci0gICAgICogPC90cj4KLSAgICAgKiA8dHI+Ci0gICAgICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz4KLSAgICAgKiBFTEVNRU5UX05PREUsIEVOVElUWV9OT0RFLCBFTlRJVFlfUkVGRVJFTkNFX05PREUsCi0gICAgICogRE9DVU1FTlRfRlJBR01FTlRfTk9ERTwvdGQ+Ci0gICAgICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz5jb25jYXRlbmF0aW9uIG9mIHRoZSA8Y29kZT50ZXh0Q29udGVudDwvY29kZT4KLSAgICAgKiBhdHRyaWJ1dGUgdmFsdWUgb2YgZXZlcnkgY2hpbGQgbm9kZSwgZXhjbHVkaW5nIENPTU1FTlRfTk9ERSBhbmQKLSAgICAgKiBQUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREUgbm9kZXM8L3RkPgotICAgICAqIDwvdHI+Ci0gICAgICogPHRyPgotICAgICAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+QVRUUklCVVRFX05PREUsIFRFWFRfTk9ERSwKLSAgICAgKiBDREFUQV9TRUNUSU9OX05PREUsIENPTU1FTlRfTk9ERSwgUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFPC90ZD4KLSAgICAgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPgotICAgICAqIDxjb2RlPm5vZGVWYWx1ZTwvY29kZT48L3RkPgotICAgICAqIDwvdHI+Ci0gICAgICogPHRyPgotICAgICAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+RE9DVU1FTlRfTk9ERSwgRE9DVU1FTlRfVFlQRV9OT0RFLCBOT1RBVElPTl9OT0RFPC90ZD4KLSAgICAgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPgotICAgICAqIG51bGw8L3RkPgotICAgICAqIDwvdHI+Ci0gICAgICogPC90YWJsZT4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgd2hlbiB0aGUgbm9kZSBpcyByZWFkb25seS4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgRE9NU1RSSU5HX1NJWkVfRVJSOiBSYWlzZWQgd2hlbiBpdCB3b3VsZCByZXR1cm4gbW9yZSBjaGFyYWN0ZXJzIHRoYW4KLSAgICAgKiAgIGZpdCBpbiBhIDxjb2RlPkRPTVN0cmluZzwvY29kZT4gdmFyaWFibGUgb24gdGhlIGltcGxlbWVudGF0aW9uCi0gICAgICogICBwbGF0Zm9ybS4KLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFRleHRDb250ZW50KCkgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0gICAgICAgIHJldHVybiBnZXROb2RlVmFsdWUoKTsgIC8vIG92ZXJyaWRlbiBpbiBzb21lIHN1YmNsYXNzZXMKLSAgICB9Ci0KLSAgICAgLyoqCi0gICAgICogQ29tcGFyZXMgYSBub2RlIHdpdGggdGhpcyBub2RlIHdpdGggcmVnYXJkIHRvIHRoZWlyIHBvc2l0aW9uIGluIHRoZQotICAgICAqIGRvY3VtZW50LgotICAgICAqIEBwYXJhbSBvdGhlciBUaGUgbm9kZSB0byBjb21wYXJlIGFnYWluc3QgdGhpcyBub2RlLgotICAgICAqIEByZXR1cm4gUmV0dXJucyBob3cgdGhlIGdpdmVuIG5vZGUgaXMgcG9zaXRpb25lZCByZWxhdGl2ZWx5IHRvIHRoaXMKLSAgICAgKiAgIG5vZGUuCi0gICAgICogQHNpbmNlIERPTSBMZXZlbCAzCi0gICAgICovCi0gICAgcHVibGljIHNob3J0IGNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKE5vZGUgb3RoZXIpIHRocm93cyBET01FeGNlcHRpb24gewotICAgICAgICByZXR1cm4gMDsKLSAgICB9Ci0KLSAgICAgLyoqCi0gICAgICogVGhlIGFic29sdXRlIGJhc2UgVVJJIG9mIHRoaXMgbm9kZSBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiB1bmRlZmluZWQuCi0gICAgICogVGhpcyB2YWx1ZSBpcyBjb21wdXRlZCBhY2NvcmRpbmcgdG8gLiBIb3dldmVyLCB3aGVuIHRoZQotICAgICAqIDxjb2RlPkRvY3VtZW50PC9jb2RlPiBzdXBwb3J0cyB0aGUgZmVhdHVyZSAiSFRNTCIgLCB0aGUgYmFzZSBVUkkgaXMKLSAgICAgKiBjb21wdXRlZCB1c2luZyBmaXJzdCB0aGUgdmFsdWUgb2YgdGhlIGhyZWYgYXR0cmlidXRlIG9mIHRoZSBIVE1MIEJBU0UKLSAgICAgKiBlbGVtZW50IGlmIGFueSwgYW5kIHRoZSB2YWx1ZSBvZiB0aGUgPGNvZGU+ZG9jdW1lbnRVUkk8L2NvZGU+Ci0gICAgICogYXR0cmlidXRlIGZyb20gdGhlIDxjb2RlPkRvY3VtZW50PC9jb2RlPiBpbnRlcmZhY2Ugb3RoZXJ3aXNlLgotICAgICAqIDxicj4gV2hlbiB0aGUgbm9kZSBpcyBhbiA8Y29kZT5FbGVtZW50PC9jb2RlPiwgYSA8Y29kZT5Eb2N1bWVudDwvY29kZT4KLSAgICAgKiBvciBhIGEgPGNvZGU+UHJvY2Vzc2luZ0luc3RydWN0aW9uPC9jb2RlPiwgdGhpcyBhdHRyaWJ1dGUgcmVwcmVzZW50cwotICAgICAqIHRoZSBwcm9wZXJ0aWVzIFtiYXNlIFVSSV0gZGVmaW5lZCBpbiAuIFdoZW4gdGhlIG5vZGUgaXMgYQotICAgICAqIDxjb2RlPk5vdGF0aW9uPC9jb2RlPiwgYW4gPGNvZGU+RW50aXR5PC9jb2RlPiwgb3IgYW4KLSAgICAgKiA8Y29kZT5FbnRpdHlSZWZlcmVuY2U8L2NvZGU+LCB0aGlzIGF0dHJpYnV0ZSByZXByZXNlbnRzIHRoZQotICAgICAqIHByb3BlcnRpZXMgW2RlY2xhcmF0aW9uIGJhc2UgVVJJXSBpbiB0aGUgLiBIb3cgd2lsbCB0aGlzIGJlIGFmZmVjdGVkCi0gICAgICogYnkgcmVzb2x1dGlvbiBvZiByZWxhdGl2ZSBuYW1lc3BhY2UgVVJJcyBpc3N1ZT9JdCdzIG5vdC5TaG91bGQgdGhpcwotICAgICAqIG9ubHkgYmUgb24gRG9jdW1lbnQsIEVsZW1lbnQsIFByb2Nlc3NpbmdJbnN0cnVjdGlvbiwgRW50aXR5LCBhbmQKLSAgICAgKiBOb3RhdGlvbiBub2RlcywgYWNjb3JkaW5nIHRvIHRoZSBpbmZvc2V0PyBJZiBub3QsIHdoYXQgaXMgaXQgZXF1YWwgdG8KLSAgICAgKiBvbiBvdGhlciBub2Rlcz8gTnVsbD8gQW4gZW1wdHkgc3RyaW5nPyBJIHRoaW5rIGl0IHNob3VsZCBiZSB0aGUKLSAgICAgKiBwYXJlbnQncy5Oby5TaG91bGQgdGhpcyBiZSByZWFkLW9ubHkgYW5kIGNvbXB1dGVkIG9yIGFuZCBhY3R1YWwKLSAgICAgKiByZWFkLXdyaXRlIGF0dHJpYnV0ZT9SZWFkLW9ubHkgYW5kIGNvbXB1dGVkIChGMkYgMTkgSnVuIDIwMDAgYW5kCi0gICAgICogdGVsZWNvbmZlcmVuY2UgMzAgTWF5IDIwMDEpLklmIHRoZSBiYXNlIEhUTUwgZWxlbWVudCBpcyBub3QgeWV0Ci0gICAgICogYXR0YWNoZWQgdG8gYSBkb2N1bWVudCwgZG9lcyB0aGUgaW5zZXJ0IGNoYW5nZSB0aGUgRG9jdW1lbnQuYmFzZVVSST8KLSAgICAgKiBZZXMuIChGMkYgMjYgU2VwIDIwMDEpCi0gICAgICogQHNpbmNlIERPTSBMZXZlbCAzCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRCYXNlVVJJKCkgewotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICogRE9NIExldmVsIDMgV0QgLSBFeHBlcmltZW50YWwuCi0gICAgICogUmVuYW1pbmcgbm9kZQotICAgICAqLwotICAgIHB1YmxpYyBOb2RlIHJlbmFtZU5vZGUoTm9kZSBuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBuYW1lKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbnsKLSAgICAgICAgcmV0dXJuIG47Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiAgRE9NIExldmVsIDMgV0QgLSBFeHBlcmltZW50YWwKLSAgICAgKiAgTm9ybWFsaXplIGRvY3VtZW50LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIG5vcm1hbGl6ZURvY3VtZW50KCl7Ci0KLSAgICB9Ci0gICAgLyoqCi0gICAgICogIFRoZSBjb25maWd1cmF0aW9uIHVzZWQgd2hlbiA8Y29kZT5Eb2N1bWVudC5ub3JtYWxpemVEb2N1bWVudDwvY29kZT4gaXMKLSAgICAgKiBpbnZva2VkLgotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgICAqLwotICAgIHB1YmxpYyBET01Db25maWd1cmF0aW9uIGdldERvbUNvbmZpZygpewotICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotCi0gICAgLyoqRXhwZXJpbWVudGFsIERPTSBMZXZlbCAzIGZlYXR1cmU6IGRvY3VtZW50VVJJICovCi0gICAgcHJvdGVjdGVkIFN0cmluZyBmRG9jdW1lbnRVUkk7Ci0KLSAgICAvKioKLSAgICAgKiBET00gTGV2ZWwgMyBXRCAtIEV4cGVyaW1lbnRhbC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXREb2N1bWVudFVSSShTdHJpbmcgZG9jdW1lbnRVUkkpewotCi0gICAgICAgIGZEb2N1bWVudFVSST0gZG9jdW1lbnRVUkk7Ci0gICAgfQotCi0gICAgICAgIC8qKgotICAgICAqIERPTSBMZXZlbCAzIFdEIC0gRXhwZXJpbWVudGFsLgotICAgICAqIFRoZSBsb2NhdGlvbiBvZiB0aGUgZG9jdW1lbnQgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdW5kZWZpbmVkLgotICAgICAqIDxicj5CZXdhcmUgdGhhdCB3aGVuIHRoZSA8Y29kZT5Eb2N1bWVudDwvY29kZT4gc3VwcG9ydHMgdGhlIGZlYXR1cmUKLSAgICAgKiAiSFRNTCIgLCB0aGUgaHJlZiBhdHRyaWJ1dGUgb2YgdGhlIEhUTUwgQkFTRSBlbGVtZW50IHRha2VzIHByZWNlZGVuY2UKLSAgICAgKiBvdmVyIHRoaXMgYXR0cmlidXRlLgotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0RG9jdW1lbnRVUkkoKXsKLSAgICAgICAgcmV0dXJuIGZEb2N1bWVudFVSSTsKLSAgICB9Ci0KLSAgICAgICAgLyoqRXhwZXJpbWVudGFsIERPTSBMZXZlbCAzIGZlYXR1cmU6IERvY3VtZW50IGFjdHVhbEVuY29kaW5nICovCi0gICAgcHJvdGVjdGVkIFN0cmluZyBhY3R1YWxFbmNvZGluZzsKLQotICAgICAvKioKLSAgICAgKiBET00gTGV2ZWwgMyBXRCAtIEV4cGVyaW1lbnRhbC4KLSAgICAgKiBBbiBhdHRyaWJ1dGUgc3BlY2lmeWluZyB0aGUgYWN0dWFsIGVuY29kaW5nIG9mIHRoaXMgZG9jdW1lbnQuIFRoaXMgaXMKLSAgICAgKiA8Y29kZT5udWxsPC9jb2RlPiBvdGhlcndpc2UuCi0gICAgICogPGJyPiBUaGlzIGF0dHJpYnV0ZSByZXByZXNlbnRzIHRoZSBwcm9wZXJ0eSBbY2hhcmFjdGVyIGVuY29kaW5nIHNjaGVtZV0KLSAgICAgKiBkZWZpbmVkIGluIC4KLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEFjdHVhbEVuY29kaW5nKCkgewotICAgICAgICByZXR1cm4gYWN0dWFsRW5jb2Rpbmc7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRE9NIExldmVsIDMgV0QgLSBFeHBlcmltZW50YWwuCi0gICAgICogQW4gYXR0cmlidXRlIHNwZWNpZnlpbmcgdGhlIGFjdHVhbCBlbmNvZGluZyBvZiB0aGlzIGRvY3VtZW50LiBUaGlzIGlzCi0gICAgICogPGNvZGU+bnVsbDwvY29kZT4gb3RoZXJ3aXNlLgotICAgICAqIDxicj4gVGhpcyBhdHRyaWJ1dGUgcmVwcmVzZW50cyB0aGUgcHJvcGVydHkgW2NoYXJhY3RlciBlbmNvZGluZyBzY2hlbWVdCi0gICAgICogZGVmaW5lZCBpbiAuCi0gICAgICogQHNpbmNlIERPTSBMZXZlbCAzCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0QWN0dWFsRW5jb2RpbmcoU3RyaW5nIHZhbHVlKSB7Ci0gICAgICAgIGFjdHVhbEVuY29kaW5nID0gdmFsdWU7Ci0gICAgfQotCi0gICAgIC8qKgotICAgICogRE9NIExldmVsIDMgV0QgLSBFeHBlcmltZW50YWwuCi0gICAgKi8KLSAgICBwdWJsaWMgVGV4dCByZXBsYWNlV2hvbGVUZXh0KFN0cmluZyBjb250ZW50KQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbnsKLS8qCi0KLSAgICAgICAgaWYgKG5lZWRzU3luY0RhdGEoKSkgewotICAgICAgICAgICAgc3luY2hyb25pemVEYXRhKCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBtYWtlIHN1cmUgd2UgY2FuIG1ha2UgdGhlIHJlcGxhY2VtZW50Ci0gICAgICAgIGlmICghY2FuTW9kaWZ5KG5leHRTaWJsaW5nKSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSLAotICAgICAgICAgICAgICAgIERPTU1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShET01NZXNzYWdlRm9ybWF0dGVyLkRPTV9ET01BSU4sICJOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIiLCBudWxsKSk7Ci0gICAgICAgIH0KLQotICAgICAgICBOb2RlIHBhcmVudCA9IHRoaXMuZ2V0UGFyZW50Tm9kZSgpOwotICAgICAgICBpZiAoY29udGVudCA9PSBudWxsIHx8IGNvbnRlbnQubGVuZ3RoKCkgPT0gMCkgewotICAgICAgICAgICAgLy8gcmVtb3ZlIGN1cnJlbnQgbm9kZQotICAgICAgICAgICAgaWYgKHBhcmVudCAhPW51bGwpIHsgLy8gY2hlY2sgaWYgbm9kZSBpbiB0aGUgdHJlZQotICAgICAgICAgICAgICAgIHBhcmVudC5yZW1vdmVDaGlsZCh0aGlzKTsKLSAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBUZXh0IGN1cnJlbnROb2RlID0gbnVsbDsKLSAgICAgICAgaWYgKGlzUmVhZE9ubHkoKSl7Ci0gICAgICAgICAgICBUZXh0IG5ld05vZGUgPSB0aGlzLm93bmVyRG9jdW1lbnQoKS5jcmVhdGVUZXh0Tm9kZShjb250ZW50KTsKLSAgICAgICAgICAgIGlmIChwYXJlbnQgIT1udWxsKSB7IC8vIGNoZWNrIGlmIG5vZGUgaW4gdGhlIHRyZWUKLSAgICAgICAgICAgICAgICBwYXJlbnQuaW5zZXJ0QmVmb3JlKG5ld05vZGUsIHRoaXMpOwotICAgICAgICAgICAgICAgIHBhcmVudC5yZW1vdmVDaGlsZCh0aGlzKTsKLSAgICAgICAgICAgICAgICBjdXJyZW50Tm9kZSA9IG5ld05vZGU7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIHJldHVybiBuZXdOb2RlOwotICAgICAgICAgICAgfQotICAgICAgICB9ICBlbHNlIHsKLSAgICAgICAgICAgIHRoaXMuc2V0RGF0YShjb250ZW50KTsKLSAgICAgICAgICAgIGN1cnJlbnROb2RlID0gdGhpczsKLSAgICAgICAgfQotICAgICAgICBOb2RlIHNpYmxpbmcgPSAgY3VycmVudE5vZGUuZ2V0TmV4dFNpYmxpbmcoKTsKLSAgICAgICAgd2hpbGUgKCBzaWJsaW5nICE9bnVsbCkgewotICAgICAgICAgICAgcGFyZW50LnJlbW92ZUNoaWxkKHNpYmxpbmcpOwotICAgICAgICAgICAgc2libGluZyA9IGN1cnJlbnROb2RlLmdldE5leHRTaWJsaW5nKCk7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gY3VycmVudE5vZGU7Ci0qLwotICAgICAgICByZXR1cm4gbnVsbDsgLy9QZW5kaW5nCi0gICAgfQotCi0gICAgIC8qKgotICAgICAqIERPTSBMZXZlbCAzIFdEIC0gRXhwZXJpbWVudGFsLgotICAgICAqIFJldHVybnMgYWxsIHRleHQgb2YgPGNvZGU+VGV4dDwvY29kZT4gbm9kZXMgbG9naWNhbGx5LWFkamFjZW50IHRleHQKLSAgICAgKiBub2RlcyB0byB0aGlzIG5vZGUsIGNvbmNhdGVuYXRlZCBpbiBkb2N1bWVudCBvcmRlci4KLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFdob2xlVGV4dCgpewotCi0vKgotICAgICAgICBpZiAobmVlZHNTeW5jRGF0YSgpKSB7Ci0gICAgICAgICAgICBzeW5jaHJvbml6ZURhdGEoKTsKLSAgICAgICAgfQotICAgICAgICBpZiAobmV4dFNpYmxpbmcgPT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIGRhdGE7Ci0gICAgICAgIH0KLSAgICAgICAgU3RyaW5nQnVmZmVyIGJ1ZmZlciA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLSAgICAgICAgaWYgKGRhdGEgIT0gbnVsbCAmJiBkYXRhLmxlbmd0aCgpICE9IDApIHsKLSAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoZGF0YSk7Ci0gICAgICAgIH0KLSAgICAgICAgZ2V0V2hvbGVUZXh0KG5leHRTaWJsaW5nLCBidWZmZXIpOwotICAgICAgICByZXR1cm4gYnVmZmVyLnRvU3RyaW5nKCk7Ci0qLwotICAgICAgICByZXR1cm4gbnVsbDsgLy8gUEVORElORwotCi0gICAgfQotCi0gICAgICAvKioKLSAgICAqIERPTSBMZXZlbCAzIFdEIC0gRXhwZXJpbWVudGFsLgotICAgICAqIFJldHVybnMgd2hldGhlciB0aGlzIHRleHQgbm9kZSBjb250YWlucyB3aGl0ZXNwYWNlIGluIGVsZW1lbnQgY29udGVudCwKLSAgICAgKiBvZnRlbiBhYnVzaXZlbHkgY2FsbGVkICJpZ25vcmFibGUgd2hpdGVzcGFjZSIuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNXaGl0ZXNwYWNlSW5FbGVtZW50Q29udGVudCgpewotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0KLQotCi0gICAgIC8qKgotICAgICAqIE5PTi1ET006IHNldCB0aGUgdHlwZSBvZiB0aGlzIGF0dHJpYnV0ZSB0byBiZSBJRCB0eXBlLgotICAgICAqCi0gICAgICogQHBhcmFtIGlkCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0SWRBdHRyaWJ1dGUoYm9vbGVhbiBpZCl7Ci0gICAgICAgIC8vUEVORElORwotICAgIH0KLQotICAgICAvKioKLSAgICAgKiBET00gTGV2ZWwgMzogcmVnaXN0ZXIgdGhlIGdpdmVuIGF0dHJpYnV0ZSBub2RlIGFzIGFuIElEIGF0dHJpYnV0ZQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldElkQXR0cmlidXRlKFN0cmluZyBuYW1lLCBib29sZWFuIG1ha2VJZCkgewotICAgICAgICAvL1BFTkRJTkcKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIERPTSBMZXZlbCAzOiByZWdpc3RlciB0aGUgZ2l2ZW4gYXR0cmlidXRlIG5vZGUgYXMgYW4gSUQgYXR0cmlidXRlCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0SWRBdHRyaWJ1dGVOb2RlKEF0dHIgYXQsIGJvb2xlYW4gbWFrZUlkKSB7Ci0gICAgICAgIC8vUEVORElORwotICAgIH0KLQotICAgIC8qKgotICAgICAqIERPTSBMZXZlbCAzOiByZWdpc3RlciB0aGUgZ2l2ZW4gYXR0cmlidXRlIG5vZGUgYXMgYW4gSUQgYXR0cmlidXRlCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0SWRBdHRyaWJ1dGVOUyhTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgbG9jYWxOYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBtYWtlSWQpIHsKLSAgICAgICAgLy9QRU5ESU5HCi0gICAgfQotICAgICAgICAgLyoqCi0gICAgICAgICAqIE1ldGhvZCBnZXRTY2hlbWFUeXBlSW5mby4KLSAgICAgICAgICogQHJldHVybiBUeXBlSW5mbwotICAgICAgICAgKi8KLSAgICBwdWJsaWMgVHlwZUluZm8gZ2V0U2NoZW1hVHlwZUluZm8oKXsKLSAgICAgIHJldHVybiBudWxsOyAvL1BFTkRJTkcKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0lkKCkgewotICAgICAgICByZXR1cm4gZmFsc2U7IC8vUEVORElORwotICAgIH0KLQotICAgIHByaXZhdGUgU3RyaW5nIHhtbEVuY29kaW5nOwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0WG1sRW5jb2RpbmcgKCApIHsKLSAgICAgICAgcmV0dXJuIHhtbEVuY29kaW5nOwotICAgIH0KLSAgICBwdWJsaWMgdm9pZCBzZXRYbWxFbmNvZGluZyAoIFN0cmluZyB4bWxFbmNvZGluZyApIHsKLSAgICAgICAgdGhpcy54bWxFbmNvZGluZyA9IHhtbEVuY29kaW5nOwotICAgIH0KLQotICAgIHByaXZhdGUgYm9vbGVhbiB4bWxTdGFuZGFsb25lOwotICAgIHB1YmxpYyBib29sZWFuIGdldFhtbFN0YW5kYWxvbmUoKSB7Ci0gICAgICAgIHJldHVybiB4bWxTdGFuZGFsb25lOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldFhtbFN0YW5kYWxvbmUoYm9vbGVhbiB4bWxTdGFuZGFsb25lKSB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKLSAgICAgICAgdGhpcy54bWxTdGFuZGFsb25lID0geG1sU3RhbmRhbG9uZTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIFN0cmluZyB4bWxWZXJzaW9uOwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0WG1sVmVyc2lvbigpIHsKLSAgICAgICAgcmV0dXJuIHhtbFZlcnNpb247Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0WG1sVmVyc2lvbihTdHJpbmcgeG1sVmVyc2lvbikgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0gICAgICAgIHRoaXMueG1sVmVyc2lvbiA9IHhtbFZlcnNpb247Ci0gICAgfQotCi0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL1dyYXBwZWRSdW50aW1lRXhjZXB0aW9uLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9XcmFwcGVkUnVudGltZUV4Y2VwdGlvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA5ZGU2MzJiLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL1dyYXBwZWRSdW50aW1lRXhjZXB0aW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3NiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBXcmFwcGVkUnVudGltZUV4Y2VwdGlvbi5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE1IDA4OjE2OjAwIHN1cmVzaF9lbWFpbGlkIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlsczsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGlzIGZvciB0aHJvd2luZyBpbXBvcnRhbnQgY2hlY2tlZCBleGNlcHRpb25zCi0gKiBvdmVyIG5vbi1jaGVja2VkIG1ldGhvZHMuICBJdCBzaG91bGQgYmUgdXNlZCB3aXRoIGNhcmUsCi0gKiBhbmQgaW4gbGltaXRlZCBjaXJjdW1zdGFuY2VzLgotICovCi1wdWJsaWMgY2xhc3MgV3JhcHBlZFJ1bnRpbWVFeGNlcHRpb24gZXh0ZW5kcyBSdW50aW1lRXhjZXB0aW9uCi17Ci0gICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDcxNDA0MTQ0NTY3MTQ2NTgwNzNMOwotCi0gIC8qKiBQcmltYXJ5IGNoZWNrZWQgZXhjZXB0aW9uLgotICAgKiAgQHNlcmlhbCAgICAgICAgICAqLwotICBwcml2YXRlIEV4Y2VwdGlvbiBtX2V4Y2VwdGlvbjsKLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgV3JhcHBlZFJ1bnRpbWVFeGNlcHRpb24gZnJvbSBhCi0gICAqIGNoZWNrZWQgZXhjZXB0aW9uLgotICAgKgotICAgKiBAcGFyYW0gZSBQcmltYXJ5IGNoZWNrZWQgZXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgV3JhcHBlZFJ1bnRpbWVFeGNlcHRpb24oRXhjZXB0aW9uIGUpCi0gIHsKLQotICAgIHN1cGVyKGUuZ2V0TWVzc2FnZSgpKTsKLQotICAgIG1fZXhjZXB0aW9uID0gZTsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3RvciBXcmFwcGVkUnVudGltZUV4Y2VwdGlvbgotICAgKgotICAgKgotICAgKiBAcGFyYW0gbXNnIEV4Y2VwdGlvbiBpbmZvcm1hdGlvbi4KLSAgICogQHBhcmFtIGUgUHJpbWFyeSBjaGVja2VkIGV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFdyYXBwZWRSdW50aW1lRXhjZXB0aW9uKFN0cmluZyBtc2csIEV4Y2VwdGlvbiBlKQotICB7Ci0KLSAgICBzdXBlcihtc2cpOwotCi0gICAgbV9leGNlcHRpb24gPSBlOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgY2hlY2tlZCBleGNlcHRpb24gdGhhdCB0aGlzIHJ1bnRpbWUgZXhjZXB0aW9uIHdyYXBzLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBwcmltYXJ5IGNoZWNrZWQgZXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgRXhjZXB0aW9uIGdldEV4Y2VwdGlvbigpCi0gIHsKLSAgICByZXR1cm4gbV9leGNlcHRpb247Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL1dyb25nUGFyc2VyRXhjZXB0aW9uLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9Xcm9uZ1BhcnNlckV4Y2VwdGlvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwZmU5MzEwLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL1dyb25nUGFyc2VyRXhjZXB0aW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0MiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBXcm9uZ1BhcnNlckV4Y2VwdGlvbi5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE1IDA4OjE2OjAwIHN1cmVzaF9lbWFpbGlkIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlsczsKLQotLyoqCi0gKiBDZXJ0YWluIGZ1bmN0aW9ucyBtYXkgdGhyb3cgdGhpcyBlcnJvciBpZiB0aGV5IGFyZSBwYWlyZWQgd2l0aAotICogdGhlIGluY29ycmVjdCBwYXJzZXIuCi0gKiBAeHNsLnVzYWdlIGdlbmVyYWwKLSAqLwotcHVibGljIGNsYXNzIFdyb25nUGFyc2VyRXhjZXB0aW9uIGV4dGVuZHMgUnVudGltZUV4Y2VwdGlvbgotewotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA2NDgxNjQzMDE4NTMzMDQzODQ2TDsKLQotICAvKioKLSAgICogQ3JlYXRlIGEgV3JvbmdQYXJzZXJFeGNlcHRpb24gb2JqZWN0LgotICAgKiBAcGFyYW0gbWVzc2FnZSBUaGUgZXJyb3IgbWVzc2FnZSB0aGF0IHNob3VsZCBiZSByZXBvcnRlZCB0byB0aGUgdXNlci4KLSAgICovCi0gIHB1YmxpYyBXcm9uZ1BhcnNlckV4Y2VwdGlvbihTdHJpbmcgbWVzc2FnZSkKLSAgewotICAgIHN1cGVyKG1lc3NhZ2UpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9YTUwxMUNoYXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL1hNTDExQ2hhci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwNWJiMzE1Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL1hNTDExQ2hhci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDMyICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlsczsKLQotaW1wb3J0IGphdmEudXRpbC5BcnJheXM7Ci0KLQotLyoqCi0gKiBUSElTIElTIEEgQ09QWSBPRiBUSEUgWEVSQ0VTLTJKIENMQVNTIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRscy5YTUxDaGFyCi0gKgotICogVGhpcyBjbGFzcyBkZWZpbmVzIHRoZSBiYXNpYyBwcm9wZXJ0aWVzIG9mIGNoYXJhY3RlcnMgaW4gWE1MIDEuMS4gVGhlIGRhdGEKLSAqIGluIHRoaXMgY2xhc3MgY2FuIGJlIHVzZWQgdG8gdmVyaWZ5IHRoYXQgYSBjaGFyYWN0ZXIgaXMgYSB2YWxpZAotICogWE1MIDEuMSBjaGFyYWN0ZXIgb3IgaWYgdGhlIGNoYXJhY3RlciBpcyBhIHNwYWNlLCBuYW1lIHN0YXJ0LCBvciBuYW1lCi0gKiBjaGFyYWN0ZXIuCi0gKiA8cD4KLSAqIEEgc2VyaWVzIG9mIGNvbnZlbmllbmNlIG1ldGhvZHMgYXJlIHN1cHBsaWVkIHRvIGVhc2UgdGhlIGJ1cmRlbgotICogb2YgdGhlIGRldmVsb3Blci4gIFVzaW5nIHRoZSBjaGFyYWN0ZXIgYXMgYW4gaW5kZXggaW50byB0aGUgPGNvZGU+WE1MMTFDSEFSUzwvY29kZT4KLSAqIGFycmF5IGFuZCBhcHBseWluZyB0aGUgYXBwcm9wcmlhdGUgbWFzayBmbGFnIChlLmcuCi0gKiA8Y29kZT5NQVNLX1ZBTElEPC9jb2RlPiksIHlpZWxkcyB0aGUgc2FtZSByZXN1bHRzIGFzIGNhbGxpbmcgdGhlCi0gKiBjb252ZW5pZW5jZSBtZXRob2RzLiBUaGVyZSBpcyBvbmUgZXhjZXB0aW9uOiBjaGVjayB0aGUgY29tbWVudHMKLSAqIGZvciB0aGUgPGNvZGU+aXNWYWxpZDwvY29kZT4gbWV0aG9kIGZvciBkZXRhaWxzLgotICoKLSAqLwotcHVibGljIGNsYXNzIFhNTDExQ2hhciB7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0YW50cwotICAgIC8vCi0KLSAgICAvKiogQ2hhcmFjdGVyIGZsYWdzIGZvciBYTUwgMS4xLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGUgWE1MMTFDSEFSUyBbXSA9IG5ldyBieXRlIFsxIDw8IDE2XTsKLQotICAgIC8qKiBYTUwgMS4xIFZhbGlkIGNoYXJhY3RlciBtYXNrLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BU0tfWE1MMTFfVkFMSUQgPSAweDAxOwotCi0gICAgLyoqIFhNTCAxLjEgU3BhY2UgY2hhcmFjdGVyIG1hc2suICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFTS19YTUwxMV9TUEFDRSA9IDB4MDI7Ci0KLSAgICAvKiogWE1MIDEuMSBOYW1lIHN0YXJ0IGNoYXJhY3RlciBtYXNrLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BU0tfWE1MMTFfTkFNRV9TVEFSVCA9IDB4MDQ7Ci0KLSAgICAvKiogWE1MIDEuMSBOYW1lIGNoYXJhY3RlciBtYXNrLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BU0tfWE1MMTFfTkFNRSA9IDB4MDg7Ci0KLSAgICAvKiogWE1MIDEuMSBjb250cm9sIGNoYXJhY3RlciBtYXNrICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFTS19YTUwxMV9DT05UUk9MID0gMHgxMDsKLQotICAgIC8qKiBYTUwgMS4xIGNvbnRlbnQgZm9yIGV4dGVybmFsIGVudGl0aWVzICh2YWxpZCAtICJzcGVjaWFsIiBjaGFycyAtIGNvbnRyb2wgY2hhcnMpICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFTS19YTUwxMV9DT05URU5UID0gMHgyMDsKLQotICAgIC8qKiBYTUwgbmFtZXNwYWNlcyAxLjEgTkNOYW1lU3RhcnQgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVNLX1hNTDExX05DTkFNRV9TVEFSVCA9IDB4NDA7Ci0KLSAgICAvKiogWE1MIG5hbWVzcGFjZXMgMS4xIE5DTmFtZSAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BU0tfWE1MMTFfTkNOQU1FID0gMHg4MDsKLQotICAgIC8qKiBYTUwgMS4xIGNvbnRlbnQgZm9yIGludGVybmFsIGVudGl0aWVzICh2YWxpZCAtICJzcGVjaWFsIiBjaGFycykgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVNLX1hNTDExX0NPTlRFTlRfSU5URVJOQUwgPSBNQVNLX1hNTDExX0NPTlRST0wgfCBNQVNLX1hNTDExX0NPTlRFTlQ7Ci0KLSAgICAvLwotICAgIC8vIFN0YXRpYyBpbml0aWFsaXphdGlvbgotICAgIC8vCi0KLSAgICBzdGF0aWMgewotCi0gICAgICAgIC8vIEluaXRpYWxpemluZyB0aGUgQ2hhcmFjdGVyIEZsYWcgQXJyYXkKLSAgICAgICAgLy8gQ29kZSBnZW5lcmF0ZWQgYnk6IFhNTDExQ2hhckdlbmVyYXRvci4KLQotICAgICAgICBBcnJheXMuZmlsbChYTUwxMUNIQVJTLCAxLCA5LCAoYnl0ZSkgMTcgKTsgLy8gRmlsbCA4IG9mIHZhbHVlIChieXRlKSAxNwotICAgICAgICBYTUwxMUNIQVJTWzldID0gMzU7Ci0gICAgICAgIFhNTDExQ0hBUlNbMTBdID0gMzsKLSAgICAgICAgQXJyYXlzLmZpbGwoWE1MMTFDSEFSUywgMTEsIDEzLCAoYnl0ZSkgMTcgKTsgLy8gRmlsbCAyIG9mIHZhbHVlIChieXRlKSAxNwotICAgICAgICBYTUwxMUNIQVJTWzEzXSA9IDM7Ci0gICAgICAgIEFycmF5cy5maWxsKFhNTDExQ0hBUlMsIDE0LCAzMiwgKGJ5dGUpIDE3ICk7IC8vIEZpbGwgMTggb2YgdmFsdWUgKGJ5dGUpIDE3Ci0gICAgICAgIFhNTDExQ0hBUlNbMzJdID0gMzU7Ci0gICAgICAgIEFycmF5cy5maWxsKFhNTDExQ0hBUlMsIDMzLCAzOCwgKGJ5dGUpIDMzICk7IC8vIEZpbGwgNSBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgWE1MMTFDSEFSU1szOF0gPSAxOwotICAgICAgICBBcnJheXMuZmlsbChYTUwxMUNIQVJTLCAzOSwgNDUsIChieXRlKSAzMyApOyAvLyBGaWxsIDYgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIEFycmF5cy5maWxsKFhNTDExQ0hBUlMsIDQ1LCA0NywgKGJ5dGUpIC04NyApOyAvLyBGaWxsIDIgb2YgdmFsdWUgKGJ5dGUpIC04NwotICAgICAgICBYTUwxMUNIQVJTWzQ3XSA9IDMzOwotICAgICAgICBBcnJheXMuZmlsbChYTUwxMUNIQVJTLCA0OCwgNTgsIChieXRlKSAtODcgKTsgLy8gRmlsbCAxMCBvZiB2YWx1ZSAoYnl0ZSkgLTg3Ci0gICAgICAgIFhNTDExQ0hBUlNbNThdID0gNDU7Ci0gICAgICAgIFhNTDExQ0hBUlNbNTldID0gMzM7Ci0gICAgICAgIFhNTDExQ0hBUlNbNjBdID0gMTsKLSAgICAgICAgQXJyYXlzLmZpbGwoWE1MMTFDSEFSUywgNjEsIDY1LCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCA0IG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBBcnJheXMuZmlsbChYTUwxMUNIQVJTLCA2NSwgOTEsIChieXRlKSAtMTkgKTsgLy8gRmlsbCAyNiBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIEFycmF5cy5maWxsKFhNTDExQ0hBUlMsIDkxLCA5MywgKGJ5dGUpIDMzICk7IC8vIEZpbGwgMiBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgWE1MMTFDSEFSU1s5M10gPSAxOwotICAgICAgICBYTUwxMUNIQVJTWzk0XSA9IDMzOwotICAgICAgICBYTUwxMUNIQVJTWzk1XSA9IC0xOTsKLSAgICAgICAgWE1MMTFDSEFSU1s5Nl0gPSAzMzsKLSAgICAgICAgQXJyYXlzLmZpbGwoWE1MMTFDSEFSUywgOTcsIDEyMywgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDI2IG9mIHZhbHVlIChieXRlKSAtMTkKLSAgICAgICAgQXJyYXlzLmZpbGwoWE1MMTFDSEFSUywgMTIzLCAxMjcsIChieXRlKSAzMyApOyAvLyBGaWxsIDQgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIEFycmF5cy5maWxsKFhNTDExQ0hBUlMsIDEyNywgMTMzLCAoYnl0ZSkgMTcgKTsgLy8gRmlsbCA2IG9mIHZhbHVlIChieXRlKSAxNwotICAgICAgICBYTUwxMUNIQVJTWzEzM10gPSAzNTsKLSAgICAgICAgQXJyYXlzLmZpbGwoWE1MMTFDSEFSUywgMTM0LCAxNjAsIChieXRlKSAxNyApOyAvLyBGaWxsIDI2IG9mIHZhbHVlIChieXRlKSAxNwotICAgICAgICBBcnJheXMuZmlsbChYTUwxMUNIQVJTLCAxNjAsIDE4MywgKGJ5dGUpIDMzICk7IC8vIEZpbGwgMjMgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIFhNTDExQ0hBUlNbMTgzXSA9IC04NzsKLSAgICAgICAgQXJyYXlzLmZpbGwoWE1MMTFDSEFSUywgMTg0LCAxOTIsIChieXRlKSAzMyApOyAvLyBGaWxsIDggb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIEFycmF5cy5maWxsKFhNTDExQ0hBUlMsIDE5MiwgMjE1LCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgMjMgb2YgdmFsdWUgKGJ5dGUpIC0xOQotICAgICAgICBYTUwxMUNIQVJTWzIxNV0gPSAzMzsKLSAgICAgICAgQXJyYXlzLmZpbGwoWE1MMTFDSEFSUywgMjE2LCAyNDcsIChieXRlKSAtMTkgKTsgLy8gRmlsbCAzMSBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIFhNTDExQ0hBUlNbMjQ3XSA9IDMzOwotICAgICAgICBBcnJheXMuZmlsbChYTUwxMUNIQVJTLCAyNDgsIDc2OCwgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDUyMCBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIEFycmF5cy5maWxsKFhNTDExQ0hBUlMsIDc2OCwgODgwLCAoYnl0ZSkgLTg3ICk7IC8vIEZpbGwgMTEyIG9mIHZhbHVlIChieXRlKSAtODcKLSAgICAgICAgQXJyYXlzLmZpbGwoWE1MMTFDSEFSUywgODgwLCA4OTQsIChieXRlKSAtMTkgKTsgLy8gRmlsbCAxNCBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIFhNTDExQ0hBUlNbODk0XSA9IDMzOwotICAgICAgICBBcnJheXMuZmlsbChYTUwxMUNIQVJTLCA4OTUsIDgxOTIsIChieXRlKSAtMTkgKTsgLy8gRmlsbCA3Mjk3IG9mIHZhbHVlIChieXRlKSAtMTkKLSAgICAgICAgQXJyYXlzLmZpbGwoWE1MMTFDSEFSUywgODE5MiwgODIwNCwgKGJ5dGUpIDMzICk7IC8vIEZpbGwgMTIgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIEFycmF5cy5maWxsKFhNTDExQ0hBUlMsIDgyMDQsIDgyMDYsIChieXRlKSAtMTkgKTsgLy8gRmlsbCAyIG9mIHZhbHVlIChieXRlKSAtMTkKLSAgICAgICAgQXJyYXlzLmZpbGwoWE1MMTFDSEFSUywgODIwNiwgODIzMiwgKGJ5dGUpIDMzICk7IC8vIEZpbGwgMjYgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIFhNTDExQ0hBUlNbODIzMl0gPSAzNTsKLSAgICAgICAgQXJyYXlzLmZpbGwoWE1MMTFDSEFSUywgODIzMywgODI1NSwgKGJ5dGUpIDMzICk7IC8vIEZpbGwgMjIgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIEFycmF5cy5maWxsKFhNTDExQ0hBUlMsIDgyNTUsIDgyNTcsIChieXRlKSAtODcgKTsgLy8gRmlsbCAyIG9mIHZhbHVlIChieXRlKSAtODcKLSAgICAgICAgQXJyYXlzLmZpbGwoWE1MMTFDSEFSUywgODI1NywgODMwNCwgKGJ5dGUpIDMzICk7IC8vIEZpbGwgNDcgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIEFycmF5cy5maWxsKFhNTDExQ0hBUlMsIDgzMDQsIDg1OTIsIChieXRlKSAtMTkgKTsgLy8gRmlsbCAyODggb2YgdmFsdWUgKGJ5dGUpIC0xOQotICAgICAgICBBcnJheXMuZmlsbChYTUwxMUNIQVJTLCA4NTkyLCAxMTI2NCwgKGJ5dGUpIDMzICk7IC8vIEZpbGwgMjY3MiBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgQXJyYXlzLmZpbGwoWE1MMTFDSEFSUywgMTEyNjQsIDEyMjcyLCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgMTAwOCBvZiB2YWx1ZSAoYnl0ZSkgLTE5Ci0gICAgICAgIEFycmF5cy5maWxsKFhNTDExQ0hBUlMsIDEyMjcyLCAxMjI4OSwgKGJ5dGUpIDMzICk7IC8vIEZpbGwgMTcgb2YgdmFsdWUgKGJ5dGUpIDMzCi0gICAgICAgIEFycmF5cy5maWxsKFhNTDExQ0hBUlMsIDEyMjg5LCA1NTI5NiwgKGJ5dGUpIC0xOSApOyAvLyBGaWxsIDQzMDA3IG9mIHZhbHVlIChieXRlKSAtMTkKLSAgICAgICAgQXJyYXlzLmZpbGwoWE1MMTFDSEFSUywgNTczNDQsIDYzNzQ0LCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCA2NDAwIG9mIHZhbHVlIChieXRlKSAzMwotICAgICAgICBBcnJheXMuZmlsbChYTUwxMUNIQVJTLCA2Mzc0NCwgNjQ5NzYsIChieXRlKSAtMTkgKTsgLy8gRmlsbCAxMjMyIG9mIHZhbHVlIChieXRlKSAtMTkKLSAgICAgICAgQXJyYXlzLmZpbGwoWE1MMTFDSEFSUywgNjQ5NzYsIDY1MDA4LCAoYnl0ZSkgMzMgKTsgLy8gRmlsbCAzMiBvZiB2YWx1ZSAoYnl0ZSkgMzMKLSAgICAgICAgQXJyYXlzLmZpbGwoWE1MMTFDSEFSUywgNjUwMDgsIDY1NTM0LCAoYnl0ZSkgLTE5ICk7IC8vIEZpbGwgNTI2IG9mIHZhbHVlIChieXRlKSAtMTkKLQotICAgIH0gLy8gPGNsaW5pdD4oKQotCi0gICAgLy8KLSAgICAvLyBQdWJsaWMgc3RhdGljIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyIGlzIGEgc3BhY2UgY2hhcmFjdGVyCi0gICAgICogYXMgYW1kZW5kZWQgaW4gdGhlIFhNTCAxLjEgc3BlY2lmaWNhdGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjIFRoZSBjaGFyYWN0ZXIgdG8gY2hlY2suCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzWE1MMTFTcGFjZShpbnQgYykgewotICAgICAgICByZXR1cm4gKGMgPCAweDEwMDAwICYmIChYTUwxMUNIQVJTW2NdICYgTUFTS19YTUwxMV9TUEFDRSkgIT0gMCk7Ci0gICAgfSAvLyBpc1hNTDExU3BhY2UoaW50KTpib29sZWFuCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXIgaXMgdmFsaWQuIFRoaXMgbWV0aG9kCi0gICAgICogYWxzbyBjaGVja3MgdGhlIHN1cnJvZ2F0ZSBjaGFyYWN0ZXIgcmFuZ2UgZnJvbSAweDEwMDAwIHRvIDB4MTBGRkZGLgotICAgICAqIDxwPgotICAgICAqIElmIHRoZSBwcm9ncmFtIGNob29zZXMgdG8gYXBwbHkgdGhlIG1hc2sgZGlyZWN0bHkgdG8gdGhlCi0gICAgICogPGNvZGU+WE1MMTFDSEFSUzwvY29kZT4gYXJyYXksIHRoZW4gdGhleSBhcmUgcmVzcG9uc2libGUgZm9yIGNoZWNraW5nCi0gICAgICogdGhlIHN1cnJvZ2F0ZSBjaGFyYWN0ZXIgcmFuZ2UuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYyBUaGUgY2hhcmFjdGVyIHRvIGNoZWNrLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc1hNTDExVmFsaWQoaW50IGMpIHsKLSAgICAgICAgcmV0dXJuIChjIDwgMHgxMDAwMCAmJiAoWE1MMTFDSEFSU1tjXSAmIE1BU0tfWE1MMTFfVkFMSUQpICE9IDApCi0gICAgICAgICAgICAgICAgfHwgKDB4MTAwMDAgPD0gYyAmJiBjIDw9IDB4MTBGRkZGKTsKLSAgICB9IC8vIGlzWE1MMTFWYWxpZChpbnQpOmJvb2xlYW4KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgc3BlY2lmaWVkIGNoYXJhY3RlciBpcyBpbnZhbGlkLgotICAgICAqCi0gICAgICogQHBhcmFtIGMgVGhlIGNoYXJhY3RlciB0byBjaGVjay4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNYTUwxMUludmFsaWQoaW50IGMpIHsKLSAgICAgICAgcmV0dXJuICFpc1hNTDExVmFsaWQoYyk7Ci0gICAgfSAvLyBpc1hNTDExSW52YWxpZChpbnQpOmJvb2xlYW4KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgc3BlY2lmaWVkIGNoYXJhY3RlciBpcyB2YWxpZCBhbmQgcGVybWl0dGVkIG91dHNpZGUKLSAgICAgKiBvZiBhIGNoYXJhY3RlciByZWZlcmVuY2UuCi0gICAgICogVGhhdCBpcywgdGhpcyBtZXRob2Qgd2lsbCByZXR1cm4gZmFsc2UgZm9yIHRoZSBzYW1lIHNldCBhcwotICAgICAqIGlzWE1MMTFWYWxpZCwgZXhjZXB0IGl0IGFsc28gcmVwb3J0cyBmYWxzZSBmb3IgImNvbnRyb2wgY2hhcmFjdGVycyIuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYyBUaGUgY2hhcmFjdGVyIHRvIGNoZWNrLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc1hNTDExVmFsaWRMaXRlcmFsKGludCBjKSB7Ci0gICAgICAgIHJldHVybiAoKGMgPCAweDEwMDAwICYmICgoWE1MMTFDSEFSU1tjXSAmIE1BU0tfWE1MMTFfVkFMSUQpICE9IDAgJiYgKFhNTDExQ0hBUlNbY10gJiBNQVNLX1hNTDExX0NPTlRST0wpID09IDApKQotICAgICAgICAgICAgfHwgKDB4MTAwMDAgPD0gYyAmJiBjIDw9IDB4MTBGRkZGKSk7Ci0gICAgfSAvLyBpc1hNTDExVmFsaWRMaXRlcmFsKGludCk6Ym9vbGVhbgotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyIGNhbiBiZSBjb25zaWRlcmVkCi0gICAgICogY29udGVudCBpbiBhbiBleHRlcm5hbCBwYXJzZWQgZW50aXR5LgotICAgICAqCi0gICAgICogQHBhcmFtIGMgVGhlIGNoYXJhY3RlciB0byBjaGVjay4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNYTUwxMUNvbnRlbnQoaW50IGMpIHsKLSAgICAgICAgcmV0dXJuIChjIDwgMHgxMDAwMCAmJiAoWE1MMTFDSEFSU1tjXSAmIE1BU0tfWE1MMTFfQ09OVEVOVCkgIT0gMCkgfHwKLSAgICAgICAgICAgICAgICgweDEwMDAwIDw9IGMgJiYgYyA8PSAweDEwRkZGRik7Ci0gICAgfSAvLyBpc1hNTDExQ29udGVudChpbnQpOmJvb2xlYW4KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgc3BlY2lmaWVkIGNoYXJhY3RlciBjYW4gYmUgY29uc2lkZXJlZAotICAgICAqIGNvbnRlbnQgaW4gYW4gaW50ZXJuYWwgcGFyc2VkIGVudGl0eS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjIFRoZSBjaGFyYWN0ZXIgdG8gY2hlY2suCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzWE1MMTFJbnRlcm5hbEVudGl0eUNvbnRlbnQoaW50IGMpIHsKLSAgICAgICAgcmV0dXJuIChjIDwgMHgxMDAwMCAmJiAoWE1MMTFDSEFSU1tjXSAmIE1BU0tfWE1MMTFfQ09OVEVOVF9JTlRFUk5BTCkgIT0gMCkgfHwKLSAgICAgICAgICAgICAgICgweDEwMDAwIDw9IGMgJiYgYyA8PSAweDEwRkZGRik7Ci0gICAgfSAvLyBpc1hNTDExSW50ZXJuYWxFbnRpdHlDb250ZW50KGludCk6Ym9vbGVhbgotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyIGlzIGEgdmFsaWQgbmFtZSBzdGFydAotICAgICAqIGNoYXJhY3RlciBhcyBkZWZpbmVkIGJ5IHByb2R1Y3Rpb24gWzRdIGluIHRoZSBYTUwgMS4xCi0gICAgICogc3BlY2lmaWNhdGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjIFRoZSBjaGFyYWN0ZXIgdG8gY2hlY2suCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzWE1MMTFOYW1lU3RhcnQoaW50IGMpIHsKLSAgICAgICAgcmV0dXJuIChjIDwgMHgxMDAwMCAmJiAoWE1MMTFDSEFSU1tjXSAmIE1BU0tfWE1MMTFfTkFNRV9TVEFSVCkgIT0gMCkKLSAgICAgICAgICAgIHx8ICgweDEwMDAwIDw9IGMgJiYgYyA8IDB4RjAwMDApOwotICAgIH0gLy8gaXNYTUwxMU5hbWVTdGFydChpbnQpOmJvb2xlYW4KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgc3BlY2lmaWVkIGNoYXJhY3RlciBpcyBhIHZhbGlkIG5hbWUKLSAgICAgKiBjaGFyYWN0ZXIgYXMgZGVmaW5lZCBieSBwcm9kdWN0aW9uIFs0YV0gaW4gdGhlIFhNTCAxLjEKLSAgICAgKiBzcGVjaWZpY2F0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIGMgVGhlIGNoYXJhY3RlciB0byBjaGVjay4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNYTUwxMU5hbWUoaW50IGMpIHsKLSAgICAgICAgcmV0dXJuIChjIDwgMHgxMDAwMCAmJiAoWE1MMTFDSEFSU1tjXSAmIE1BU0tfWE1MMTFfTkFNRSkgIT0gMCkKLSAgICAgICAgICAgIHx8IChjID49IDB4MTAwMDAgJiYgYyA8IDB4RjAwMDApOwotICAgIH0gLy8gaXNYTUwxMU5hbWUoaW50KTpib29sZWFuCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXIgaXMgYSB2YWxpZCBOQ05hbWUgc3RhcnQKLSAgICAgKiBjaGFyYWN0ZXIgYXMgZGVmaW5lZCBieSBwcm9kdWN0aW9uIFs0XSBpbiBOYW1lc3BhY2VzIGluIFhNTAotICAgICAqIDEuMSByZWNvbW1lbmRhdGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjIFRoZSBjaGFyYWN0ZXIgdG8gY2hlY2suCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzWE1MMTFOQ05hbWVTdGFydChpbnQgYykgewotICAgICAgICByZXR1cm4gKGMgPCAweDEwMDAwICYmIChYTUwxMUNIQVJTW2NdICYgTUFTS19YTUwxMV9OQ05BTUVfU1RBUlQpICE9IDApCi0gICAgICAgICAgICB8fCAoMHgxMDAwMCA8PSBjICYmIGMgPCAweEYwMDAwKTsKLSAgICB9IC8vIGlzWE1MMTFOQ05hbWVTdGFydChpbnQpOmJvb2xlYW4KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgc3BlY2lmaWVkIGNoYXJhY3RlciBpcyBhIHZhbGlkIE5DTmFtZQotICAgICAqIGNoYXJhY3RlciBhcyBkZWZpbmVkIGJ5IHByb2R1Y3Rpb24gWzVdIGluIE5hbWVzcGFjZXMgaW4gWE1MCi0gICAgICogMS4xIHJlY29tbWVuZGF0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIGMgVGhlIGNoYXJhY3RlciB0byBjaGVjay4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNYTUwxMU5DTmFtZShpbnQgYykgewotICAgICAgICByZXR1cm4gKGMgPCAweDEwMDAwICYmIChYTUwxMUNIQVJTW2NdICYgTUFTS19YTUwxMV9OQ05BTUUpICE9IDApCi0gICAgICAgICAgICB8fCAoMHgxMDAwMCA8PSBjICYmIGMgPCAweEYwMDAwKTsKLSAgICB9IC8vIGlzWE1MMTFOQ05hbWUoaW50KTpib29sZWFuCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhlIGdpdmVuIGNoYXJhY3RlciBpcyBhIHZhbGlkCi0gICAgICogaGlnaCBzdXJyb2dhdGUgZm9yIGEgbmFtZSBjaGFyYWN0ZXIuIFRoaXMgaW5jbHVkZXMKLSAgICAgKiBhbGwgaGlnaCBzdXJyb2dhdGVzIGZvciBjaGFyYWN0ZXJzIFsweDEwMDAwLTB4RUZGRkZdLgotICAgICAqIEluIG90aGVyIHdvcmRzIGV2ZXJ5dGhpbmcgZXhjbHVkaW5nIHBsYW5lcyAxNSBhbmQgMTYuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYyBUaGUgY2hhcmFjdGVyIHRvIGNoZWNrLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc1hNTDExTmFtZUhpZ2hTdXJyb2dhdGUoaW50IGMpIHsKLSAgICAgICAgcmV0dXJuICgweEQ4MDAgPD0gYyAmJiBjIDw9IDB4REI3Rik7Ci0gICAgfQotCi0gICAgLyoKLSAgICAgKiBbNV0gTmFtZSA6Oj0gTmFtZVN0YXJ0Q2hhciBOYW1lQ2hhcioKLSAgICAgKi8KLSAgICAvKioKLSAgICAgKiBDaGVjayB0byBzZWUgaWYgYSBzdHJpbmcgaXMgYSB2YWxpZCBOYW1lIGFjY29yZGluZyB0byBbNV0KLSAgICAgKiBpbiB0aGUgWE1MIDEuMSBSZWNvbW1lbmRhdGlvbgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgc3RyaW5nIHRvIGNoZWNrCi0gICAgICogQHJldHVybiB0cnVlIGlmIG5hbWUgaXMgYSB2YWxpZCBOYW1lCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzWE1MMTFWYWxpZE5hbWUoU3RyaW5nIG5hbWUpIHsKLSAgICAgICAgaW50IGxlbmd0aCA9IG5hbWUubGVuZ3RoKCk7Ci0gICAgICAgIGlmIChsZW5ndGggPT0gMCkKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgaW50IGkgPSAxOwotICAgICAgICBjaGFyIGNoID0gbmFtZS5jaGFyQXQoMCk7Ci0gICAgICAgIGlmKCAhaXNYTUwxMU5hbWVTdGFydChjaCkgKSB7Ci0gICAgICAgICAgICBpZiAoIGxlbmd0aCA+IDEgJiYgaXNYTUwxMU5hbWVIaWdoU3Vycm9nYXRlKGNoKSApIHsKLSAgICAgICAgICAgICAgICBjaGFyIGNoMiA9IG5hbWUuY2hhckF0KDEpOwotICAgICAgICAgICAgICAgIGlmICggIVhNTENoYXIuaXNMb3dTdXJyb2dhdGUoY2gyKSB8fAotICAgICAgICAgICAgICAgICAgICAgIWlzWE1MMTFOYW1lU3RhcnQoWE1MQ2hhci5zdXBwbGVtZW50YWwoY2gsIGNoMikpICkgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGkgPSAyOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHdoaWxlIChpIDwgbGVuZ3RoKSB7Ci0gICAgICAgICAgICBjaCA9IG5hbWUuY2hhckF0KGkpOwotICAgICAgICAgICAgaWYgKCAhaXNYTUwxMU5hbWUoY2gpICkgewotICAgICAgICAgICAgICAgIGlmICggKytpIDwgbGVuZ3RoICYmIGlzWE1MMTFOYW1lSGlnaFN1cnJvZ2F0ZShjaCkgKSB7Ci0gICAgICAgICAgICAgICAgICAgIGNoYXIgY2gyID0gbmFtZS5jaGFyQXQoaSk7Ci0gICAgICAgICAgICAgICAgICAgIGlmICggIVhNTENoYXIuaXNMb3dTdXJyb2dhdGUoY2gyKSB8fAotICAgICAgICAgICAgICAgICAgICAgICAgICFpc1hNTDExTmFtZShYTUxDaGFyLnN1cHBsZW1lbnRhbChjaCwgY2gyKSkgKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICArK2k7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfSAvLyBpc1hNTDExVmFsaWROYW1lKFN0cmluZyk6Ym9vbGVhbgotCi0KLSAgICAvKgotICAgICAqIGZyb20gdGhlIG5hbWVzcGFjZSAxLjEgcmVjCi0gICAgICogWzRdIE5DTmFtZSA6Oj0gTkNOYW1lU3RhcnRDaGFyIE5DTmFtZUNoYXIqCi0gICAgICovCi0gICAgLyoqCi0gICAgICogQ2hlY2sgdG8gc2VlIGlmIGEgc3RyaW5nIGlzIGEgdmFsaWQgTkNOYW1lIGFjY29yZGluZyB0byBbNF0KLSAgICAgKiBmcm9tIHRoZSBYTUwgTmFtZXNwYWNlcyAxLjEgUmVjb21tZW5kYXRpb24KLSAgICAgKgotICAgICAqIEBwYXJhbSBuY05hbWUgc3RyaW5nIHRvIGNoZWNrCi0gICAgICogQHJldHVybiB0cnVlIGlmIG5hbWUgaXMgYSB2YWxpZCBOQ05hbWUKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNYTUwxMVZhbGlkTkNOYW1lKFN0cmluZyBuY05hbWUpIHsKLSAgICAgICAgaW50IGxlbmd0aCA9IG5jTmFtZS5sZW5ndGgoKTsKLSAgICAgICAgaWYgKGxlbmd0aCA9PSAwKQotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICBpbnQgaSA9IDE7Ci0gICAgICAgIGNoYXIgY2ggPSBuY05hbWUuY2hhckF0KDApOwotICAgICAgICBpZiggIWlzWE1MMTFOQ05hbWVTdGFydChjaCkgKSB7Ci0gICAgICAgICAgICBpZiAoIGxlbmd0aCA+IDEgJiYgaXNYTUwxMU5hbWVIaWdoU3Vycm9nYXRlKGNoKSApIHsKLSAgICAgICAgICAgICAgICBjaGFyIGNoMiA9IG5jTmFtZS5jaGFyQXQoMSk7Ci0gICAgICAgICAgICAgICAgaWYgKCAhWE1MQ2hhci5pc0xvd1N1cnJvZ2F0ZShjaDIpIHx8Ci0gICAgICAgICAgICAgICAgICAgICAhaXNYTUwxMU5DTmFtZVN0YXJ0KFhNTENoYXIuc3VwcGxlbWVudGFsKGNoLCBjaDIpKSApIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpID0gMjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICB3aGlsZSAoaSA8IGxlbmd0aCkgewotICAgICAgICAgICAgY2ggPSBuY05hbWUuY2hhckF0KGkpOwotICAgICAgICAgICAgaWYgKCAhaXNYTUwxMU5DTmFtZShjaCkgKSB7Ci0gICAgICAgICAgICAgICAgaWYgKCArK2kgPCBsZW5ndGggJiYgaXNYTUwxMU5hbWVIaWdoU3Vycm9nYXRlKGNoKSApIHsKLSAgICAgICAgICAgICAgICAgICAgY2hhciBjaDIgPSBuY05hbWUuY2hhckF0KGkpOwotICAgICAgICAgICAgICAgICAgICBpZiAoICFYTUxDaGFyLmlzTG93U3Vycm9nYXRlKGNoMikgfHwKLSAgICAgICAgICAgICAgICAgICAgICAgICAhaXNYTUwxMU5DTmFtZShYTUxDaGFyLnN1cHBsZW1lbnRhbChjaCwgY2gyKSkgKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICArK2k7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfSAvLyBpc1hNTDExVmFsaWROQ05hbWUoU3RyaW5nKTpib29sZWFuCi0KLSAgICAvKgotICAgICAqIFs3XSBObXRva2VuIDo6PSAoTmFtZUNoYXIpKwotICAgICAqLwotICAgIC8qKgotICAgICAqIENoZWNrIHRvIHNlZSBpZiBhIHN0cmluZyBpcyBhIHZhbGlkIE5tdG9rZW4gYWNjb3JkaW5nIHRvIFs3XQotICAgICAqIGluIHRoZSBYTUwgMS4xIFJlY29tbWVuZGF0aW9uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbm10b2tlbiBzdHJpbmcgdG8gY2hlY2sKLSAgICAgKiBAcmV0dXJuIHRydWUgaWYgbm10b2tlbiBpcyBhIHZhbGlkIE5tdG9rZW4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNYTUwxMVZhbGlkTm10b2tlbihTdHJpbmcgbm10b2tlbikgewotICAgICAgICBpbnQgbGVuZ3RoID0gbm10b2tlbi5sZW5ndGgoKTsKLSAgICAgICAgaWYgKGxlbmd0aCA9PSAwKQotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgKytpICkgewotICAgICAgICAgICAgY2hhciBjaCA9IG5tdG9rZW4uY2hhckF0KGkpOwotICAgICAgICAgICAgaWYoICFpc1hNTDExTmFtZShjaCkgKSB7Ci0gICAgICAgICAgICAgICAgaWYgKCArK2kgPCBsZW5ndGggJiYgaXNYTUwxMU5hbWVIaWdoU3Vycm9nYXRlKGNoKSApIHsKLSAgICAgICAgICAgICAgICAgICAgY2hhciBjaDIgPSBubXRva2VuLmNoYXJBdChpKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKCAhWE1MQ2hhci5pc0xvd1N1cnJvZ2F0ZShjaDIpIHx8Ci0gICAgICAgICAgICAgICAgICAgICAgICAgIWlzWE1MMTFOYW1lKFhNTENoYXIuc3VwcGxlbWVudGFsKGNoLCBjaDIpKSApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICB9IC8vIGlzWE1MMTFWYWxpZE5hbWUoU3RyaW5nKTpib29sZWFuCi0KLSAgICAvKioKLSAgICAgICogU2ltcGxlIGNoZWNrIHRvIGRldGVybWluZSBpZiBxbmFtZSBpcyBsZWdhbC4gSWYgaXQgcmV0dXJucyBmYWxzZQotICAgICAgKiB0aGVuIDxwYXJhbT5zdHI8L3BhcmFtPiBpcyBpbGxlZ2FsOyBpZiBpdCByZXR1cm5zIHRydWUgdGhlbgotICAgICAgKiA8cGFyYW0+c3RyPC9wYXJhbT4gaXMgbGVnYWwuCi0gICAgICAqLwotICAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNYTUwxMVZhbGlkUU5hbWUoU3RyaW5nIHN0cikgewotCi0gICAgICAgIGZpbmFsIGludCBjb2xvbiA9IHN0ci5pbmRleE9mKCc6Jyk7Ci0KLSAgICAgICAgaWYgKGNvbG9uID09IDAgfHwgY29sb24gPT0gc3RyLmxlbmd0aCgpIC0gMSkgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKGNvbG9uID4gMCkgewotICAgICAgICAgICAgZmluYWwgU3RyaW5nIHByZWZpeCA9IHN0ci5zdWJzdHJpbmcoMCxjb2xvbik7Ci0gICAgICAgICAgICBmaW5hbCBTdHJpbmcgbG9jYWxQYXJ0ID0gc3RyLnN1YnN0cmluZyhjb2xvbisxKTsKLSAgICAgICAgICAgIHJldHVybiBpc1hNTDExVmFsaWROQ05hbWUocHJlZml4KSAmJiBpc1hNTDExVmFsaWROQ05hbWUobG9jYWxQYXJ0KTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiBpc1hNTDExVmFsaWROQ05hbWUoc3RyKTsKLSAgICAgICAgfQotICAgICB9Ci0KLX0gLy8gY2xhc3MgWE1MMTFDaGFyCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9YTUxDaGFyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9YTUxDaGFyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDQ1ZDc1NGMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvWE1MQ2hhci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNjY5ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFhNTENoYXIuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNSAwODoxNjowMSBzdXJlc2hfZW1haWxpZCBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlsczsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGRlZmluZXMgdGhlIGJhc2ljIFhNTCBjaGFyYWN0ZXIgcHJvcGVydGllcy4gVGhlIGRhdGEKLSAqIGluIHRoaXMgY2xhc3MgY2FuIGJlIHVzZWQgdG8gdmVyaWZ5IHRoYXQgYSBjaGFyYWN0ZXIgaXMgYSB2YWxpZAotICogWE1MIGNoYXJhY3RlciBvciBpZiB0aGUgY2hhcmFjdGVyIGlzIGEgc3BhY2UsIG5hbWUgc3RhcnQsIG9yIG5hbWUKLSAqIGNoYXJhY3Rlci4KLSAqIDxwPgotICogQSBzZXJpZXMgb2YgY29udmVuaWVuY2UgbWV0aG9kcyBhcmUgc3VwcGxpZWQgdG8gZWFzZSB0aGUgYnVyZGVuCi0gKiBvZiB0aGUgZGV2ZWxvcGVyLiBCZWNhdXNlIGlubGluaW5nIHRoZSBjaGVja3MgY2FuIGltcHJvdmUgcGVyCi0gKiBjaGFyYWN0ZXIgcGVyZm9ybWFuY2UsIHRoZSB0YWJsZXMgb2YgY2hhcmFjdGVyIHByb3BlcnRpZXMgYXJlCi0gKiBwdWJsaWMuIFVzaW5nIHRoZSBjaGFyYWN0ZXIgYXMgYW4gaW5kZXggaW50byB0aGUgPGNvZGU+Q0hBUlM8L2NvZGU+Ci0gKiBhcnJheSBhbmQgYXBwbHlpbmcgdGhlIGFwcHJvcHJpYXRlIG1hc2sgZmxhZyAoZS5nLgotICogPGNvZGU+TUFTS19WQUxJRDwvY29kZT4pLCB5aWVsZHMgdGhlIHNhbWUgcmVzdWx0cyBhcyBjYWxsaW5nIHRoZQotICogY29udmVuaWVuY2UgbWV0aG9kcy4gVGhlcmUgaXMgb25lIGV4Y2VwdGlvbjogY2hlY2sgdGhlIGNvbW1lbnRzCi0gKiBmb3IgdGhlIDxjb2RlPmlzVmFsaWQ8L2NvZGU+IG1ldGhvZCBmb3IgZGV0YWlscy4KLSAqCi0gKiBAYXV0aG9yIEdsZW5uIE1hcmN5LCBJQk0KLSAqIEBhdXRob3IgQW5keSBDbGFyaywgSUJNCi0gKiBAYXV0aG9yIEVyaWMgWWUsIElCTQotICogQGF1dGhvciBBcm5hdWQgIExlIEhvcnMsIElCTQotICogQGF1dGhvciBSYWh1bCBTcml2YXN0YXZhLCBTdW4gTWljcm9zeXN0ZW1zIEluYy4KLSAqCi0gKi8KLXB1YmxpYyBjbGFzcyBYTUxDaGFyIHsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RhbnRzCi0gICAgLy8KLQotICAgIC8qKiBDaGFyYWN0ZXIgZmxhZ3MuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZVtdIENIQVJTID0gbmV3IGJ5dGVbMSA8PCAxNl07Ci0KLSAgICAvKiogVmFsaWQgY2hhcmFjdGVyIG1hc2suICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFTS19WQUxJRCA9IDB4MDE7Ci0KLSAgICAvKiogU3BhY2UgY2hhcmFjdGVyIG1hc2suICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFTS19TUEFDRSA9IDB4MDI7Ci0KLSAgICAvKiogTmFtZSBzdGFydCBjaGFyYWN0ZXIgbWFzay4gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVNLX05BTUVfU1RBUlQgPSAweDA0OwotCi0gICAgLyoqIE5hbWUgY2hhcmFjdGVyIG1hc2suICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFTS19OQU1FID0gMHgwODsKLQotICAgIC8qKiBQdWJpZCBjaGFyYWN0ZXIgbWFzay4gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVNLX1BVQklEID0gMHgxMDsKLQotICAgIC8qKgotICAgICAqIENvbnRlbnQgY2hhcmFjdGVyIG1hc2suIFNwZWNpYWwgY2hhcmFjdGVycyBhcmUgdGhvc2UgdGhhdCBjYW4KLSAgICAgKiBiZSBjb25zaWRlcmVkIHRoZSBzdGFydCBvZiBtYXJrdXAsIHN1Y2ggYXMgJyZsdDsnIGFuZCAnJmFtcDsnLgotICAgICAqIFRoZSB2YXJpb3VzIG5ld2xpbmUgY2hhcmFjdGVycyBhcmUgY29uc2lkZXJlZCBzcGVjaWFsIGFzIHdlbGwuCi0gICAgICogQWxsIG90aGVyIHZhbGlkIFhNTCBjaGFyYWN0ZXJzIGNhbiBiZSBjb25zaWRlcmVkIGNvbnRlbnQuCi0gICAgICogPHA+Ci0gICAgICogVGhpcyBpcyBhbiBvcHRpbWl6YXRpb24gZm9yIHRoZSBpbm5lciBsb29wIG9mIGNoYXJhY3RlciBzY2FubmluZy4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVNLX0NPTlRFTlQgPSAweDIwOwotCi0gICAgLyoqIE5DTmFtZSBzdGFydCBjaGFyYWN0ZXIgbWFzay4gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVNLX05DTkFNRV9TVEFSVCA9IDB4NDA7Ci0KLSAgICAvKiogTkNOYW1lIGNoYXJhY3RlciBtYXNrLiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BU0tfTkNOQU1FID0gMHg4MDsKLQotICAgIC8vCi0gICAgLy8gU3RhdGljIGluaXRpYWxpemF0aW9uCi0gICAgLy8KLQotICAgIHN0YXRpYyB7Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gWzJdIENoYXIgOjo9ICN4OSB8ICN4QSB8ICN4RCB8IFsjeDIwLSN4RDdGRl0gfAotICAgICAgICAvLyAgICAgICAgICAgICAgWyN4RTAwMC0jeEZGRkRdIHwgWyN4MTAwMDAtI3gxMEZGRkZdCi0gICAgICAgIC8vCi0KLSAgICAgICAgaW50IGNoYXJSYW5nZVtdID0gewotICAgICAgICAgICAgMHgwMDA5LCAweDAwMEEsIDB4MDAwRCwgMHgwMDBELCAweDAwMjAsIDB4RDdGRiwgMHhFMDAwLCAweEZGRkQsCi0gICAgICAgIH07Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gWzNdIFMgOjo9ICgjeDIwIHwgI3g5IHwgI3hEIHwgI3hBKSsKLSAgICAgICAgLy8KLQotICAgICAgICBpbnQgc3BhY2VDaGFyW10gPSB7Ci0gICAgICAgICAgICAweDAwMjAsIDB4MDAwOSwgMHgwMDBELCAweDAwMEEsCi0gICAgICAgIH07Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gWzRdIE5hbWVDaGFyIDo6PSBMZXR0ZXIgfCBEaWdpdCB8ICcuJyB8ICctJyB8ICdfJyB8ICc6JyB8Ci0gICAgICAgIC8vICAgICAgICAgICAgICAgICAgQ29tYmluaW5nQ2hhciB8IEV4dGVuZGVyCi0gICAgICAgIC8vCi0KLSAgICAgICAgaW50IG5hbWVDaGFyW10gPSB7Ci0gICAgICAgICAgICAweDAwMkQsIDB4MDAyRSwgLy8gJy0nIGFuZCAnLicKLSAgICAgICAgfTsKLQotICAgICAgICAvLwotICAgICAgICAvLyBbNV0gTmFtZSA6Oj0gKExldHRlciB8ICdfJyB8ICc6JykgKE5hbWVDaGFyKSoKLSAgICAgICAgLy8KLQotICAgICAgICBpbnQgbmFtZVN0YXJ0Q2hhcltdID0gewotICAgICAgICAgICAgMHgwMDNBLCAweDAwNUYsIC8vICc6JyBhbmQgJ18nCi0gICAgICAgIH07Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gWzEzXSBQdWJpZENoYXIgOjo9ICN4MjAgfCAweEQgfCAweEEgfCBbYS16QS1aMC05XSB8IFstJygpKywuLzo9PzshKiNAJF8lXQotICAgICAgICAvLwotCi0gICAgICAgIGludCBwdWJpZENoYXJbXSA9IHsKLSAgICAgICAgICAgIDB4MDAwQSwgMHgwMDBELCAweDAwMjAsIDB4MDAyMSwgMHgwMDIzLCAweDAwMjQsIDB4MDAyNSwgMHgwMDNELAotICAgICAgICAgICAgMHgwMDVGCi0gICAgICAgIH07Ci0KLSAgICAgICAgaW50IHB1YmlkUmFuZ2VbXSA9IHsKLSAgICAgICAgICAgIDB4MDAyNywgMHgwMDNCLCAweDAwM0YsIDB4MDA1QSwgMHgwMDYxLCAweDAwN0EKLSAgICAgICAgfTsKLQotICAgICAgICAvLwotICAgICAgICAvLyBbODRdIExldHRlciA6Oj0gQmFzZUNoYXIgfCBJZGVvZ3JhcGhpYwotICAgICAgICAvLwotCi0gICAgICAgIGludCBsZXR0ZXJSYW5nZVtdID0gewotICAgICAgICAgICAgLy8gQmFzZUNoYXIKLSAgICAgICAgICAgIDB4MDA0MSwgMHgwMDVBLCAweDAwNjEsIDB4MDA3QSwgMHgwMEMwLCAweDAwRDYsIDB4MDBEOCwgMHgwMEY2LAotICAgICAgICAgICAgMHgwMEY4LCAweDAxMzEsIDB4MDEzNCwgMHgwMTNFLCAweDAxNDEsIDB4MDE0OCwgMHgwMTRBLCAweDAxN0UsCi0gICAgICAgICAgICAweDAxODAsIDB4MDFDMywgMHgwMUNELCAweDAxRjAsIDB4MDFGNCwgMHgwMUY1LCAweDAxRkEsIDB4MDIxNywKLSAgICAgICAgICAgIDB4MDI1MCwgMHgwMkE4LCAweDAyQkIsIDB4MDJDMSwgMHgwMzg4LCAweDAzOEEsIDB4MDM4RSwgMHgwM0ExLAotICAgICAgICAgICAgMHgwM0EzLCAweDAzQ0UsIDB4MDNEMCwgMHgwM0Q2LCAweDAzRTIsIDB4MDNGMywgMHgwNDAxLCAweDA0MEMsCi0gICAgICAgICAgICAweDA0MEUsIDB4MDQ0RiwgMHgwNDUxLCAweDA0NUMsIDB4MDQ1RSwgMHgwNDgxLCAweDA0OTAsIDB4MDRDNCwKLSAgICAgICAgICAgIDB4MDRDNywgMHgwNEM4LCAweDA0Q0IsIDB4MDRDQywgMHgwNEQwLCAweDA0RUIsIDB4MDRFRSwgMHgwNEY1LAotICAgICAgICAgICAgMHgwNEY4LCAweDA0RjksIDB4MDUzMSwgMHgwNTU2LCAweDA1NjEsIDB4MDU4NiwgMHgwNUQwLCAweDA1RUEsCi0gICAgICAgICAgICAweDA1RjAsIDB4MDVGMiwgMHgwNjIxLCAweDA2M0EsIDB4MDY0MSwgMHgwNjRBLCAweDA2NzEsIDB4MDZCNywKLSAgICAgICAgICAgIDB4MDZCQSwgMHgwNkJFLCAweDA2QzAsIDB4MDZDRSwgMHgwNkQwLCAweDA2RDMsIDB4MDZFNSwgMHgwNkU2LAotICAgICAgICAgICAgMHgwOTA1LCAweDA5MzksIDB4MDk1OCwgMHgwOTYxLCAweDA5ODUsIDB4MDk4QywgMHgwOThGLCAweDA5OTAsCi0gICAgICAgICAgICAweDA5OTMsIDB4MDlBOCwgMHgwOUFBLCAweDA5QjAsIDB4MDlCNiwgMHgwOUI5LCAweDA5REMsIDB4MDlERCwKLSAgICAgICAgICAgIDB4MDlERiwgMHgwOUUxLCAweDA5RjAsIDB4MDlGMSwgMHgwQTA1LCAweDBBMEEsIDB4MEEwRiwgMHgwQTEwLAotICAgICAgICAgICAgMHgwQTEzLCAweDBBMjgsIDB4MEEyQSwgMHgwQTMwLCAweDBBMzIsIDB4MEEzMywgMHgwQTM1LCAweDBBMzYsCi0gICAgICAgICAgICAweDBBMzgsIDB4MEEzOSwgMHgwQTU5LCAweDBBNUMsIDB4MEE3MiwgMHgwQTc0LCAweDBBODUsIDB4MEE4QiwKLSAgICAgICAgICAgIDB4MEE4RiwgMHgwQTkxLCAweDBBOTMsIDB4MEFBOCwgMHgwQUFBLCAweDBBQjAsIDB4MEFCMiwgMHgwQUIzLAotICAgICAgICAgICAgMHgwQUI1LCAweDBBQjksIDB4MEIwNSwgMHgwQjBDLCAweDBCMEYsIDB4MEIxMCwgMHgwQjEzLCAweDBCMjgsCi0gICAgICAgICAgICAweDBCMkEsIDB4MEIzMCwgMHgwQjMyLCAweDBCMzMsIDB4MEIzNiwgMHgwQjM5LCAweDBCNUMsIDB4MEI1RCwKLSAgICAgICAgICAgIDB4MEI1RiwgMHgwQjYxLCAweDBCODUsIDB4MEI4QSwgMHgwQjhFLCAweDBCOTAsIDB4MEI5MiwgMHgwQjk1LAotICAgICAgICAgICAgMHgwQjk5LCAweDBCOUEsIDB4MEI5RSwgMHgwQjlGLCAweDBCQTMsIDB4MEJBNCwgMHgwQkE4LCAweDBCQUEsCi0gICAgICAgICAgICAweDBCQUUsIDB4MEJCNSwgMHgwQkI3LCAweDBCQjksIDB4MEMwNSwgMHgwQzBDLCAweDBDMEUsIDB4MEMxMCwKLSAgICAgICAgICAgIDB4MEMxMiwgMHgwQzI4LCAweDBDMkEsIDB4MEMzMywgMHgwQzM1LCAweDBDMzksIDB4MEM2MCwgMHgwQzYxLAotICAgICAgICAgICAgMHgwQzg1LCAweDBDOEMsIDB4MEM4RSwgMHgwQzkwLCAweDBDOTIsIDB4MENBOCwgMHgwQ0FBLCAweDBDQjMsCi0gICAgICAgICAgICAweDBDQjUsIDB4MENCOSwgMHgwQ0UwLCAweDBDRTEsIDB4MEQwNSwgMHgwRDBDLCAweDBEMEUsIDB4MEQxMCwKLSAgICAgICAgICAgIDB4MEQxMiwgMHgwRDI4LCAweDBEMkEsIDB4MEQzOSwgMHgwRDYwLCAweDBENjEsIDB4MEUwMSwgMHgwRTJFLAotICAgICAgICAgICAgMHgwRTMyLCAweDBFMzMsIDB4MEU0MCwgMHgwRTQ1LCAweDBFODEsIDB4MEU4MiwgMHgwRTg3LCAweDBFODgsCi0gICAgICAgICAgICAweDBFOTQsIDB4MEU5NywgMHgwRTk5LCAweDBFOUYsIDB4MEVBMSwgMHgwRUEzLCAweDBFQUEsIDB4MEVBQiwKLSAgICAgICAgICAgIDB4MEVBRCwgMHgwRUFFLCAweDBFQjIsIDB4MEVCMywgMHgwRUMwLCAweDBFQzQsIDB4MEY0MCwgMHgwRjQ3LAotICAgICAgICAgICAgMHgwRjQ5LCAweDBGNjksIDB4MTBBMCwgMHgxMEM1LCAweDEwRDAsIDB4MTBGNiwgMHgxMTAyLCAweDExMDMsCi0gICAgICAgICAgICAweDExMDUsIDB4MTEwNywgMHgxMTBCLCAweDExMEMsIDB4MTEwRSwgMHgxMTEyLCAweDExNTQsIDB4MTE1NSwKLSAgICAgICAgICAgIDB4MTE1RiwgMHgxMTYxLCAweDExNkQsIDB4MTE2RSwgMHgxMTcyLCAweDExNzMsIDB4MTFBRSwgMHgxMUFGLAotICAgICAgICAgICAgMHgxMUI3LCAweDExQjgsIDB4MTFCQywgMHgxMUMyLCAweDFFMDAsIDB4MUU5QiwgMHgxRUEwLCAweDFFRjksCi0gICAgICAgICAgICAweDFGMDAsIDB4MUYxNSwgMHgxRjE4LCAweDFGMUQsIDB4MUYyMCwgMHgxRjQ1LCAweDFGNDgsIDB4MUY0RCwKLSAgICAgICAgICAgIDB4MUY1MCwgMHgxRjU3LCAweDFGNUYsIDB4MUY3RCwgMHgxRjgwLCAweDFGQjQsIDB4MUZCNiwgMHgxRkJDLAotICAgICAgICAgICAgMHgxRkMyLCAweDFGQzQsIDB4MUZDNiwgMHgxRkNDLCAweDFGRDAsIDB4MUZEMywgMHgxRkQ2LCAweDFGREIsCi0gICAgICAgICAgICAweDFGRTAsIDB4MUZFQywgMHgxRkYyLCAweDFGRjQsIDB4MUZGNiwgMHgxRkZDLCAweDIxMkEsIDB4MjEyQiwKLSAgICAgICAgICAgIDB4MjE4MCwgMHgyMTgyLCAweDMwNDEsIDB4MzA5NCwgMHgzMEExLCAweDMwRkEsIDB4MzEwNSwgMHgzMTJDLAotICAgICAgICAgICAgMHhBQzAwLCAweEQ3QTMsCi0gICAgICAgICAgICAvLyBJZGVvZ3JhcGhpYwotICAgICAgICAgICAgMHgzMDIxLCAweDMwMjksIDB4NEUwMCwgMHg5RkE1LAotICAgICAgICB9OwotICAgICAgICBpbnQgbGV0dGVyQ2hhcltdID0gewotICAgICAgICAgICAgLy8gQmFzZUNoYXIKLSAgICAgICAgICAgIDB4MDM4NiwgMHgwMzhDLCAweDAzREEsIDB4MDNEQywgMHgwM0RFLCAweDAzRTAsIDB4MDU1OSwgMHgwNkQ1LAotICAgICAgICAgICAgMHgwOTNELCAweDA5QjIsIDB4MEE1RSwgMHgwQThELCAweDBBQkQsIDB4MEFFMCwgMHgwQjNELCAweDBCOUMsCi0gICAgICAgICAgICAweDBDREUsIDB4MEUzMCwgMHgwRTg0LCAweDBFOEEsIDB4MEU4RCwgMHgwRUE1LCAweDBFQTcsIDB4MEVCMCwKLSAgICAgICAgICAgIDB4MEVCRCwgMHgxMTAwLCAweDExMDksIDB4MTEzQywgMHgxMTNFLCAweDExNDAsIDB4MTE0QywgMHgxMTRFLAotICAgICAgICAgICAgMHgxMTUwLCAweDExNTksIDB4MTE2MywgMHgxMTY1LCAweDExNjcsIDB4MTE2OSwgMHgxMTc1LCAweDExOUUsCi0gICAgICAgICAgICAweDExQTgsIDB4MTFBQiwgMHgxMUJBLCAweDExRUIsIDB4MTFGMCwgMHgxMUY5LCAweDFGNTksIDB4MUY1QiwKLSAgICAgICAgICAgIDB4MUY1RCwgMHgxRkJFLCAweDIxMjYsIDB4MjEyRSwKLSAgICAgICAgICAgIC8vIElkZW9ncmFwaGljCi0gICAgICAgICAgICAweDMwMDcsCi0gICAgICAgIH07Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gWzg3XSBDb21iaW5pbmdDaGFyIDo6PSAuLi4KLSAgICAgICAgLy8KLQotICAgICAgICBpbnQgY29tYmluaW5nQ2hhclJhbmdlW10gPSB7Ci0gICAgICAgICAgICAweDAzMDAsIDB4MDM0NSwgMHgwMzYwLCAweDAzNjEsIDB4MDQ4MywgMHgwNDg2LCAweDA1OTEsIDB4MDVBMSwKLSAgICAgICAgICAgIDB4MDVBMywgMHgwNUI5LCAweDA1QkIsIDB4MDVCRCwgMHgwNUMxLCAweDA1QzIsIDB4MDY0QiwgMHgwNjUyLAotICAgICAgICAgICAgMHgwNkQ2LCAweDA2REMsIDB4MDZERCwgMHgwNkRGLCAweDA2RTAsIDB4MDZFNCwgMHgwNkU3LCAweDA2RTgsCi0gICAgICAgICAgICAweDA2RUEsIDB4MDZFRCwgMHgwOTAxLCAweDA5MDMsIDB4MDkzRSwgMHgwOTRDLCAweDA5NTEsIDB4MDk1NCwKLSAgICAgICAgICAgIDB4MDk2MiwgMHgwOTYzLCAweDA5ODEsIDB4MDk4MywgMHgwOUMwLCAweDA5QzQsIDB4MDlDNywgMHgwOUM4LAotICAgICAgICAgICAgMHgwOUNCLCAweDA5Q0QsIDB4MDlFMiwgMHgwOUUzLCAweDBBNDAsIDB4MEE0MiwgMHgwQTQ3LCAweDBBNDgsCi0gICAgICAgICAgICAweDBBNEIsIDB4MEE0RCwgMHgwQTcwLCAweDBBNzEsIDB4MEE4MSwgMHgwQTgzLCAweDBBQkUsIDB4MEFDNSwKLSAgICAgICAgICAgIDB4MEFDNywgMHgwQUM5LCAweDBBQ0IsIDB4MEFDRCwgMHgwQjAxLCAweDBCMDMsIDB4MEIzRSwgMHgwQjQzLAotICAgICAgICAgICAgMHgwQjQ3LCAweDBCNDgsIDB4MEI0QiwgMHgwQjRELCAweDBCNTYsIDB4MEI1NywgMHgwQjgyLCAweDBCODMsCi0gICAgICAgICAgICAweDBCQkUsIDB4MEJDMiwgMHgwQkM2LCAweDBCQzgsIDB4MEJDQSwgMHgwQkNELCAweDBDMDEsIDB4MEMwMywKLSAgICAgICAgICAgIDB4MEMzRSwgMHgwQzQ0LCAweDBDNDYsIDB4MEM0OCwgMHgwQzRBLCAweDBDNEQsIDB4MEM1NSwgMHgwQzU2LAotICAgICAgICAgICAgMHgwQzgyLCAweDBDODMsIDB4MENCRSwgMHgwQ0M0LCAweDBDQzYsIDB4MENDOCwgMHgwQ0NBLCAweDBDQ0QsCi0gICAgICAgICAgICAweDBDRDUsIDB4MENENiwgMHgwRDAyLCAweDBEMDMsIDB4MEQzRSwgMHgwRDQzLCAweDBENDYsIDB4MEQ0OCwKLSAgICAgICAgICAgIDB4MEQ0QSwgMHgwRDRELCAweDBFMzQsIDB4MEUzQSwgMHgwRTQ3LCAweDBFNEUsIDB4MEVCNCwgMHgwRUI5LAotICAgICAgICAgICAgMHgwRUJCLCAweDBFQkMsIDB4MEVDOCwgMHgwRUNELCAweDBGMTgsIDB4MEYxOSwgMHgwRjcxLCAweDBGODQsCi0gICAgICAgICAgICAweDBGODYsIDB4MEY4QiwgMHgwRjkwLCAweDBGOTUsIDB4MEY5OSwgMHgwRkFELCAweDBGQjEsIDB4MEZCNywKLSAgICAgICAgICAgIDB4MjBEMCwgMHgyMERDLCAweDMwMkEsIDB4MzAyRiwKLSAgICAgICAgfTsKLQotICAgICAgICBpbnQgY29tYmluaW5nQ2hhckNoYXJbXSA9IHsKLSAgICAgICAgICAgIDB4MDVCRiwgMHgwNUM0LCAweDA2NzAsIDB4MDkzQywgMHgwOTRELCAweDA5QkMsIDB4MDlCRSwgMHgwOUJGLAotICAgICAgICAgICAgMHgwOUQ3LCAweDBBMDIsIDB4MEEzQywgMHgwQTNFLCAweDBBM0YsIDB4MEFCQywgMHgwQjNDLCAweDBCRDcsCi0gICAgICAgICAgICAweDBENTcsIDB4MEUzMSwgMHgwRUIxLCAweDBGMzUsIDB4MEYzNywgMHgwRjM5LCAweDBGM0UsIDB4MEYzRiwKLSAgICAgICAgICAgIDB4MEY5NywgMHgwRkI5LCAweDIwRTEsIDB4MzA5OSwgMHgzMDlBLAotICAgICAgICB9OwotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIFs4OF0gRGlnaXQgOjo9IC4uLgotICAgICAgICAvLwotCi0gICAgICAgIGludCBkaWdpdFJhbmdlW10gPSB7Ci0gICAgICAgICAgICAweDAwMzAsIDB4MDAzOSwgMHgwNjYwLCAweDA2NjksIDB4MDZGMCwgMHgwNkY5LCAweDA5NjYsIDB4MDk2RiwKLSAgICAgICAgICAgIDB4MDlFNiwgMHgwOUVGLCAweDBBNjYsIDB4MEE2RiwgMHgwQUU2LCAweDBBRUYsIDB4MEI2NiwgMHgwQjZGLAotICAgICAgICAgICAgMHgwQkU3LCAweDBCRUYsIDB4MEM2NiwgMHgwQzZGLCAweDBDRTYsIDB4MENFRiwgMHgwRDY2LCAweDBENkYsCi0gICAgICAgICAgICAweDBFNTAsIDB4MEU1OSwgMHgwRUQwLCAweDBFRDksIDB4MEYyMCwgMHgwRjI5LAotICAgICAgICB9OwotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIFs4OV0gRXh0ZW5kZXIgOjo9IC4uLgotICAgICAgICAvLwotCi0gICAgICAgIGludCBleHRlbmRlclJhbmdlW10gPSB7Ci0gICAgICAgICAgICAweDMwMzEsIDB4MzAzNSwgMHgzMDlELCAweDMwOUUsIDB4MzBGQywgMHgzMEZFLAotICAgICAgICB9OwotCi0gICAgICAgIGludCBleHRlbmRlckNoYXJbXSA9IHsKLSAgICAgICAgICAgIDB4MDBCNywgMHgwMkQwLCAweDAyRDEsIDB4MDM4NywgMHgwNjQwLCAweDBFNDYsIDB4MEVDNiwgMHgzMDA1LAotICAgICAgICB9OwotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIFNwZWNpYWxDaGFyIDo6PSAnPCcsICcmJywgJ1xuJywgJ1xyJywgJ10nCi0gICAgICAgIC8vCi0KLSAgICAgICAgaW50IHNwZWNpYWxDaGFyW10gPSB7Ci0gICAgICAgICAgICAnPCcsICcmJywgJ1xuJywgJ1xyJywgJ10nLAotICAgICAgICB9OwotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIEluaXRpYWxpemUKLSAgICAgICAgLy8KLQotICAgICAgICAvLyBzZXQgdmFsaWQgY2hhcmFjdGVycwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNoYXJSYW5nZS5sZW5ndGg7IGkgKz0gMikgewotICAgICAgICAgICAgZm9yIChpbnQgaiA9IGNoYXJSYW5nZVtpXTsgaiA8PSBjaGFyUmFuZ2VbaSArIDFdOyBqKyspIHsKLSAgICAgICAgICAgICAgICBDSEFSU1tqXSB8PSBNQVNLX1ZBTElEIHwgTUFTS19DT05URU5UOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gcmVtb3ZlIHNwZWNpYWwgY2hhcmFjdGVycwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNwZWNpYWxDaGFyLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICBDSEFSU1tzcGVjaWFsQ2hhcltpXV0gPSAoYnl0ZSkoQ0hBUlNbc3BlY2lhbENoYXJbaV1dICYgfk1BU0tfQ09OVEVOVCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBzZXQgc3BhY2UgY2hhcmFjdGVycwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNwYWNlQ2hhci5sZW5ndGg7IGkrKykgewotICAgICAgICAgICAgQ0hBUlNbc3BhY2VDaGFyW2ldXSB8PSBNQVNLX1NQQUNFOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gc2V0IG5hbWUgc3RhcnQgY2hhcmFjdGVycwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG5hbWVTdGFydENoYXIubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgIENIQVJTW25hbWVTdGFydENoYXJbaV1dIHw9IE1BU0tfTkFNRV9TVEFSVCB8IE1BU0tfTkFNRSB8Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNQVNLX05DTkFNRV9TVEFSVCB8IE1BU0tfTkNOQU1FOwotICAgICAgICB9Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGV0dGVyUmFuZ2UubGVuZ3RoOyBpICs9IDIpIHsKLSAgICAgICAgICAgIGZvciAoaW50IGogPSBsZXR0ZXJSYW5nZVtpXTsgaiA8PSBsZXR0ZXJSYW5nZVtpICsgMV07IGorKykgewotICAgICAgICAgICAgICAgIENIQVJTW2pdIHw9IE1BU0tfTkFNRV9TVEFSVCB8IE1BU0tfTkFNRSB8Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgTUFTS19OQ05BTUVfU1RBUlQgfCBNQVNLX05DTkFNRTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxldHRlckNoYXIubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgIENIQVJTW2xldHRlckNoYXJbaV1dIHw9IE1BU0tfTkFNRV9TVEFSVCB8IE1BU0tfTkFNRSB8Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNQVNLX05DTkFNRV9TVEFSVCB8IE1BU0tfTkNOQU1FOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gc2V0IG5hbWUgY2hhcmFjdGVycwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG5hbWVDaGFyLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICBDSEFSU1tuYW1lQ2hhcltpXV0gfD0gTUFTS19OQU1FIHwgTUFTS19OQ05BTUU7Ci0gICAgICAgIH0KLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBkaWdpdFJhbmdlLmxlbmd0aDsgaSArPSAyKSB7Ci0gICAgICAgICAgICBmb3IgKGludCBqID0gZGlnaXRSYW5nZVtpXTsgaiA8PSBkaWdpdFJhbmdlW2kgKyAxXTsgaisrKSB7Ci0gICAgICAgICAgICAgICAgQ0hBUlNbal0gfD0gTUFTS19OQU1FIHwgTUFTS19OQ05BTUU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb21iaW5pbmdDaGFyUmFuZ2UubGVuZ3RoOyBpICs9IDIpIHsKLSAgICAgICAgICAgIGZvciAoaW50IGogPSBjb21iaW5pbmdDaGFyUmFuZ2VbaV07IGogPD0gY29tYmluaW5nQ2hhclJhbmdlW2kgKyAxXTsgaisrKSB7Ci0gICAgICAgICAgICAgICAgQ0hBUlNbal0gfD0gTUFTS19OQU1FIHwgTUFTS19OQ05BTUU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb21iaW5pbmdDaGFyQ2hhci5sZW5ndGg7IGkrKykgewotICAgICAgICAgICAgQ0hBUlNbY29tYmluaW5nQ2hhckNoYXJbaV1dIHw9IE1BU0tfTkFNRSB8IE1BU0tfTkNOQU1FOwotICAgICAgICB9Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZXh0ZW5kZXJSYW5nZS5sZW5ndGg7IGkgKz0gMikgewotICAgICAgICAgICAgZm9yIChpbnQgaiA9IGV4dGVuZGVyUmFuZ2VbaV07IGogPD0gZXh0ZW5kZXJSYW5nZVtpICsgMV07IGorKykgewotICAgICAgICAgICAgICAgIENIQVJTW2pdIHw9IE1BU0tfTkFNRSB8IE1BU0tfTkNOQU1FOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZXh0ZW5kZXJDaGFyLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICBDSEFSU1tleHRlbmRlckNoYXJbaV1dIHw9IE1BU0tfTkFNRSB8IE1BU0tfTkNOQU1FOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gcmVtb3ZlICc6JyBmcm9tIGFsbG93YWJsZSBNQVNLX05DTkFNRV9TVEFSVCBhbmQgTUFTS19OQ05BTUUgY2hhcnMKLSAgICAgICAgQ0hBUlNbJzonXSAmPSB+KE1BU0tfTkNOQU1FX1NUQVJUIHwgTUFTS19OQ05BTUUpOwotCi0gICAgICAgIC8vIHNldCBQdWJpZCBjaGFyYWN0ZXJzCi0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcHViaWRDaGFyLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICBDSEFSU1twdWJpZENoYXJbaV1dIHw9IE1BU0tfUFVCSUQ7Ci0gICAgICAgIH0KLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwdWJpZFJhbmdlLmxlbmd0aDsgaSArPSAyKSB7Ci0gICAgICAgICAgICBmb3IgKGludCBqID0gcHViaWRSYW5nZVtpXTsgaiA8PSBwdWJpZFJhbmdlW2kgKyAxXTsgaisrKSB7Ci0gICAgICAgICAgICAgICAgQ0hBUlNbal0gfD0gTUFTS19QVUJJRDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgfSAvLyA8Y2xpbml0PigpCi0KLSAgICAvLwotICAgIC8vIFB1YmxpYyBzdGF0aWMgbWV0aG9kcwotICAgIC8vCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXIgaXMgYSBzdXBwbGVtZW50YWwgY2hhcmFjdGVyLgotICAgICAqCi0gICAgICogQHBhcmFtIGMgVGhlIGNoYXJhY3RlciB0byBjaGVjay4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNTdXBwbGVtZW50YWwoaW50IGMpIHsKLSAgICAgICAgcmV0dXJuIChjID49IDB4MTAwMDAgJiYgYyA8PSAweDEwRkZGRik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIHRoZSBzdXBwbGVtZW50YWwgY2hhcmFjdGVyIGNvcnJlc3BvbmRpbmcgdG8gdGhlIGdpdmVuCi0gICAgICogc3Vycm9nYXRlcy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBoIFRoZSBoaWdoIHN1cnJvZ2F0ZS4KLSAgICAgKiBAcGFyYW0gbCBUaGUgbG93IHN1cnJvZ2F0ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGludCBzdXBwbGVtZW50YWwoY2hhciBoLCBjaGFyIGwpIHsKLSAgICAgICAgcmV0dXJuIChoIC0gMHhEODAwKSAqIDB4NDAwICsgKGwgLSAweERDMDApICsgMHgxMDAwMDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBoaWdoIHN1cnJvZ2F0ZSBvZiBhIHN1cHBsZW1lbnRhbCBjaGFyYWN0ZXIKLSAgICAgKgotICAgICAqIEBwYXJhbSBjIFRoZSBzdXBwbGVtZW50YWwgY2hhcmFjdGVyIHRvICJzcGxpdCIuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBjaGFyIGhpZ2hTdXJyb2dhdGUoaW50IGMpIHsKLSAgICAgICAgcmV0dXJuIChjaGFyKSAoKChjIC0gMHgwMDAxMDAwMCkgPj4gMTApICsgMHhEODAwKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBsb3cgc3Vycm9nYXRlIG9mIGEgc3VwcGxlbWVudGFsIGNoYXJhY3RlcgotICAgICAqCi0gICAgICogQHBhcmFtIGMgVGhlIHN1cHBsZW1lbnRhbCBjaGFyYWN0ZXIgdG8gInNwbGl0Ii4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGNoYXIgbG93U3Vycm9nYXRlKGludCBjKSB7Ci0gICAgICAgIHJldHVybiAoY2hhcikgKCgoYyAtIDB4MDAwMTAwMDApICYgMHgzRkYpICsgMHhEQzAwKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhlIGdpdmVuIGNoYXJhY3RlciBpcyBhIGhpZ2ggc3Vycm9nYXRlCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYyBUaGUgY2hhcmFjdGVyIHRvIGNoZWNrLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0hpZ2hTdXJyb2dhdGUoaW50IGMpIHsKLSAgICAgICAgcmV0dXJuICgweEQ4MDAgPD0gYyAmJiBjIDw9IDB4REJGRik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB3aGV0aGVyIHRoZSBnaXZlbiBjaGFyYWN0ZXIgaXMgYSBsb3cgc3Vycm9nYXRlCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYyBUaGUgY2hhcmFjdGVyIHRvIGNoZWNrLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0xvd1N1cnJvZ2F0ZShpbnQgYykgewotICAgICAgICByZXR1cm4gKDB4REMwMCA8PSBjICYmIGMgPD0gMHhERkZGKTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgc3BlY2lmaWVkIGNoYXJhY3RlciBpcyB2YWxpZC4gVGhpcyBtZXRob2QKLSAgICAgKiBhbHNvIGNoZWNrcyB0aGUgc3Vycm9nYXRlIGNoYXJhY3RlciByYW5nZSBmcm9tIDB4MTAwMDAgdG8gMHgxMEZGRkYuCi0gICAgICogPHA+Ci0gICAgICogSWYgdGhlIHByb2dyYW0gY2hvb3NlcyB0byBhcHBseSB0aGUgbWFzayBkaXJlY3RseSB0byB0aGUKLSAgICAgKiA8Y29kZT5DSEFSUzwvY29kZT4gYXJyYXksIHRoZW4gdGhleSBhcmUgcmVzcG9uc2libGUgZm9yIGNoZWNraW5nCi0gICAgICogdGhlIHN1cnJvZ2F0ZSBjaGFyYWN0ZXIgcmFuZ2UuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYyBUaGUgY2hhcmFjdGVyIHRvIGNoZWNrLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc1ZhbGlkKGludCBjKSB7Ci0gICAgICAgIHJldHVybiAoYyA8IDB4MTAwMDAgJiYgKENIQVJTW2NdICYgTUFTS19WQUxJRCkgIT0gMCkgfHwKLSAgICAgICAgICAgICAgICgweDEwMDAwIDw9IGMgJiYgYyA8PSAweDEwRkZGRik7Ci0gICAgfSAvLyBpc1ZhbGlkKGludCk6Ym9vbGVhbgotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyIGlzIGludmFsaWQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYyBUaGUgY2hhcmFjdGVyIHRvIGNoZWNrLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0ludmFsaWQoaW50IGMpIHsKLSAgICAgICAgcmV0dXJuICFpc1ZhbGlkKGMpOwotICAgIH0gLy8gaXNJbnZhbGlkKGludCk6Ym9vbGVhbgotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyIGNhbiBiZSBjb25zaWRlcmVkIGNvbnRlbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYyBUaGUgY2hhcmFjdGVyIHRvIGNoZWNrLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0NvbnRlbnQoaW50IGMpIHsKLSAgICAgICAgcmV0dXJuIChjIDwgMHgxMDAwMCAmJiAoQ0hBUlNbY10gJiBNQVNLX0NPTlRFTlQpICE9IDApIHx8Ci0gICAgICAgICAgICAgICAoMHgxMDAwMCA8PSBjICYmIGMgPD0gMHgxMEZGRkYpOwotICAgIH0gLy8gaXNDb250ZW50KGludCk6Ym9vbGVhbgotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyIGNhbiBiZSBjb25zaWRlcmVkIG1hcmt1cC4KLSAgICAgKiBNYXJrdXAgY2hhcmFjdGVycyBpbmNsdWRlICcmbHQ7JywgJyZhbXA7JywgYW5kICclJy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjIFRoZSBjaGFyYWN0ZXIgdG8gY2hlY2suCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzTWFya3VwKGludCBjKSB7Ci0gICAgICAgIHJldHVybiBjID09ICc8JyB8fCBjID09ICcmJyB8fCBjID09ICclJzsKLSAgICB9IC8vIGlzTWFya3VwKGludCk6Ym9vbGVhbgotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyIGlzIGEgc3BhY2UgY2hhcmFjdGVyCi0gICAgICogYXMgZGVmaW5lZCBieSBwcm9kdWN0aW9uIFszXSBpbiB0aGUgWE1MIDEuMCBzcGVjaWZpY2F0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIGMgVGhlIGNoYXJhY3RlciB0byBjaGVjay4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNTcGFjZShpbnQgYykgewotICAgICAgICByZXR1cm4gYyA8IDB4MTAwMDAgJiYgKENIQVJTW2NdICYgTUFTS19TUEFDRSkgIT0gMDsKLSAgICB9IC8vIGlzU3BhY2UoaW50KTpib29sZWFuCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXIgaXMgYSB2YWxpZCBuYW1lIHN0YXJ0Ci0gICAgICogY2hhcmFjdGVyIGFzIGRlZmluZWQgYnkgcHJvZHVjdGlvbiBbNV0gaW4gdGhlIFhNTCAxLjAKLSAgICAgKiBzcGVjaWZpY2F0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIGMgVGhlIGNoYXJhY3RlciB0byBjaGVjay4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNOYW1lU3RhcnQoaW50IGMpIHsKLSAgICAgICAgcmV0dXJuIGMgPCAweDEwMDAwICYmIChDSEFSU1tjXSAmIE1BU0tfTkFNRV9TVEFSVCkgIT0gMDsKLSAgICB9IC8vIGlzTmFtZVN0YXJ0KGludCk6Ym9vbGVhbgotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyIGlzIGEgdmFsaWQgbmFtZQotICAgICAqIGNoYXJhY3RlciBhcyBkZWZpbmVkIGJ5IHByb2R1Y3Rpb24gWzRdIGluIHRoZSBYTUwgMS4wCi0gICAgICogc3BlY2lmaWNhdGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjIFRoZSBjaGFyYWN0ZXIgdG8gY2hlY2suCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzTmFtZShpbnQgYykgewotICAgICAgICByZXR1cm4gYyA8IDB4MTAwMDAgJiYgKENIQVJTW2NdICYgTUFTS19OQU1FKSAhPSAwOwotICAgIH0gLy8gaXNOYW1lKGludCk6Ym9vbGVhbgotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyIGlzIGEgdmFsaWQgTkNOYW1lIHN0YXJ0Ci0gICAgICogY2hhcmFjdGVyIGFzIGRlZmluZWQgYnkgcHJvZHVjdGlvbiBbNF0gaW4gTmFtZXNwYWNlcyBpbiBYTUwKLSAgICAgKiByZWNvbW1lbmRhdGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjIFRoZSBjaGFyYWN0ZXIgdG8gY2hlY2suCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzTkNOYW1lU3RhcnQoaW50IGMpIHsKLSAgICAgICAgcmV0dXJuIGMgPCAweDEwMDAwICYmIChDSEFSU1tjXSAmIE1BU0tfTkNOQU1FX1NUQVJUKSAhPSAwOwotICAgIH0gLy8gaXNOQ05hbWVTdGFydChpbnQpOmJvb2xlYW4KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgc3BlY2lmaWVkIGNoYXJhY3RlciBpcyBhIHZhbGlkIE5DTmFtZQotICAgICAqIGNoYXJhY3RlciBhcyBkZWZpbmVkIGJ5IHByb2R1Y3Rpb24gWzVdIGluIE5hbWVzcGFjZXMgaW4gWE1MCi0gICAgICogcmVjb21tZW5kYXRpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYyBUaGUgY2hhcmFjdGVyIHRvIGNoZWNrLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc05DTmFtZShpbnQgYykgewotICAgICAgICByZXR1cm4gYyA8IDB4MTAwMDAgJiYgKENIQVJTW2NdICYgTUFTS19OQ05BTUUpICE9IDA7Ci0gICAgfSAvLyBpc05DTmFtZShpbnQpOmJvb2xlYW4KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgc3BlY2lmaWVkIGNoYXJhY3RlciBpcyBhIHZhbGlkIFB1YmlkCi0gICAgICogY2hhcmFjdGVyIGFzIGRlZmluZWQgYnkgcHJvZHVjdGlvbiBbMTNdIGluIHRoZSBYTUwgMS4wCi0gICAgICogc3BlY2lmaWNhdGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjIFRoZSBjaGFyYWN0ZXIgdG8gY2hlY2suCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzUHViaWQoaW50IGMpIHsKLSAgICAgICAgcmV0dXJuIGMgPCAweDEwMDAwICYmIChDSEFSU1tjXSAmIE1BU0tfUFVCSUQpICE9IDA7Ci0gICAgfSAvLyBpc1B1YmlkKGludCk6Ym9vbGVhbgotCi0gICAgLyoKLSAgICAgKiBbNV0gTmFtZSA6Oj0gKExldHRlciB8ICdfJyB8ICc6JykgKE5hbWVDaGFyKSoKLSAgICAgKi8KLSAgICAvKioKLSAgICAgKiBDaGVjayB0byBzZWUgaWYgYSBzdHJpbmcgaXMgYSB2YWxpZCBOYW1lIGFjY29yZGluZyB0byBbNV0KLSAgICAgKiBpbiB0aGUgWE1MIDEuMCBSZWNvbW1lbmRhdGlvbgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgc3RyaW5nIHRvIGNoZWNrCi0gICAgICogQHJldHVybiB0cnVlIGlmIG5hbWUgaXMgYSB2YWxpZCBOYW1lCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzVmFsaWROYW1lKFN0cmluZyBuYW1lKSB7Ci0gICAgICAgIGlmIChuYW1lLmxlbmd0aCgpID09IDApCi0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIGNoYXIgY2ggPSBuYW1lLmNoYXJBdCgwKTsKLSAgICAgICAgaWYoIGlzTmFtZVN0YXJ0KGNoKSA9PSBmYWxzZSkKLSAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICBmb3IgKGludCBpID0gMTsgaSA8IG5hbWUubGVuZ3RoKCk7IGkrKyApIHsKLSAgICAgICAgICAgY2ggPSBuYW1lLmNoYXJBdChpKTsKLSAgICAgICAgICAgaWYoIGlzTmFtZSggY2ggKSA9PSBmYWxzZSApewotICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICB9IC8vIGlzVmFsaWROYW1lKFN0cmluZyk6Ym9vbGVhbgotCi0KLSAgICAvKgotICAgICAqIGZyb20gdGhlIG5hbWVzcGFjZSByZWMKLSAgICAgKiBbNF0gTkNOYW1lIDo6PSAoTGV0dGVyIHwgJ18nKSAoTkNOYW1lQ2hhcikqCi0gICAgICovCi0gICAgLyoqCi0gICAgICogQ2hlY2sgdG8gc2VlIGlmIGEgc3RyaW5nIGlzIGEgdmFsaWQgTkNOYW1lIGFjY29yZGluZyB0byBbNF0KLSAgICAgKiBmcm9tIHRoZSBYTUwgTmFtZXNwYWNlcyAxLjAgUmVjb21tZW5kYXRpb24KLSAgICAgKgotICAgICAqIEBwYXJhbSBuY05hbWUgc3RyaW5nIHRvIGNoZWNrCi0gICAgICogQHJldHVybiB0cnVlIGlmIG5hbWUgaXMgYSB2YWxpZCBOQ05hbWUKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNWYWxpZE5DTmFtZShTdHJpbmcgbmNOYW1lKSB7Ci0gICAgICAgIGlmIChuY05hbWUubGVuZ3RoKCkgPT0gMCkKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgY2hhciBjaCA9IG5jTmFtZS5jaGFyQXQoMCk7Ci0gICAgICAgIGlmKCBpc05DTmFtZVN0YXJ0KGNoKSA9PSBmYWxzZSkKLSAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICBmb3IgKGludCBpID0gMTsgaSA8IG5jTmFtZS5sZW5ndGgoKTsgaSsrICkgewotICAgICAgICAgICBjaCA9IG5jTmFtZS5jaGFyQXQoaSk7Ci0gICAgICAgICAgIGlmKCBpc05DTmFtZSggY2ggKSA9PSBmYWxzZSApewotICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICB9IC8vIGlzVmFsaWROQ05hbWUoU3RyaW5nKTpib29sZWFuCi0KLSAgICAvKgotICAgICAqIFs3XSBObXRva2VuIDo6PSAoTmFtZUNoYXIpKwotICAgICAqLwotICAgIC8qKgotICAgICAqIENoZWNrIHRvIHNlZSBpZiBhIHN0cmluZyBpcyBhIHZhbGlkIE5tdG9rZW4gYWNjb3JkaW5nIHRvIFs3XQotICAgICAqIGluIHRoZSBYTUwgMS4wIFJlY29tbWVuZGF0aW9uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbm10b2tlbiBzdHJpbmcgdG8gY2hlY2sKLSAgICAgKiBAcmV0dXJuIHRydWUgaWYgbm10b2tlbiBpcyBhIHZhbGlkIE5tdG9rZW4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNWYWxpZE5tdG9rZW4oU3RyaW5nIG5tdG9rZW4pIHsKLSAgICAgICAgaWYgKG5tdG9rZW4ubGVuZ3RoKCkgPT0gMCkKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBubXRva2VuLmxlbmd0aCgpOyBpKysgKSB7Ci0gICAgICAgICAgIGNoYXIgY2ggPSBubXRva2VuLmNoYXJBdChpKTsKLSAgICAgICAgICAgaWYoICAhIGlzTmFtZSggY2ggKSApewotICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICB9IC8vIGlzVmFsaWROYW1lKFN0cmluZyk6Ym9vbGVhbgotCi0KLQotCi0KLSAgICAvLyBlbmNvZGluZ3MKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgZW5jb2RpbmcgbmFtZSBpcyBhIHZhbGlkIElBTkEgZW5jb2RpbmcuCi0gICAgICogVGhpcyBtZXRob2QgZG9lcyBub3QgdmVyaWZ5IHRoYXQgdGhlcmUgaXMgYSBkZWNvZGVyIGF2YWlsYWJsZQotICAgICAqIGZvciB0aGlzIGVuY29kaW5nLCBvbmx5IHRoYXQgdGhlIGNoYXJhY3RlcnMgYXJlIHZhbGlkIGZvciBhbgotICAgICAqIElBTkEgZW5jb2RpbmcgbmFtZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBpYW5hRW5jb2RpbmcgVGhlIElBTkEgZW5jb2RpbmcgbmFtZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNWYWxpZElBTkFFbmNvZGluZyhTdHJpbmcgaWFuYUVuY29kaW5nKSB7Ci0gICAgICAgIGlmIChpYW5hRW5jb2RpbmcgIT0gbnVsbCkgewotICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlhbmFFbmNvZGluZy5sZW5ndGgoKTsKLSAgICAgICAgICAgIGlmIChsZW5ndGggPiAwKSB7Ci0gICAgICAgICAgICAgICAgY2hhciBjID0gaWFuYUVuY29kaW5nLmNoYXJBdCgwKTsKLSAgICAgICAgICAgICAgICBpZiAoKGMgPj0gJ0EnICYmIGMgPD0gJ1onKSB8fCAoYyA+PSAnYScgJiYgYyA8PSAneicpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAxOyBpIDwgbGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGMgPSBpYW5hRW5jb2RpbmcuY2hhckF0KGkpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChjIDwgJ0EnIHx8IGMgPiAnWicpICYmIChjIDwgJ2EnIHx8IGMgPiAneicpICYmCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGMgPCAnMCcgfHwgYyA+ICc5JykgJiYgYyAhPSAnLicgJiYgYyAhPSAnXycgJiYKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjICE9ICctJykgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0gLy8gaXNWYWxpZElBTkFFbmNvZGluZyhTdHJpbmcpOmJvb2xlYW4KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgZW5jb2RpbmcgbmFtZSBpcyBhIHZhbGlkIEphdmEgZW5jb2RpbmcuCi0gICAgICogVGhpcyBtZXRob2QgZG9lcyBub3QgdmVyaWZ5IHRoYXQgdGhlcmUgaXMgYSBkZWNvZGVyIGF2YWlsYWJsZQotICAgICAqIGZvciB0aGlzIGVuY29kaW5nLCBvbmx5IHRoYXQgdGhlIGNoYXJhY3RlcnMgYXJlIHZhbGlkIGZvciBhbgotICAgICAqIEphdmEgZW5jb2RpbmcgbmFtZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBqYXZhRW5jb2RpbmcgVGhlIEphdmEgZW5jb2RpbmcgbmFtZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNWYWxpZEphdmFFbmNvZGluZyhTdHJpbmcgamF2YUVuY29kaW5nKSB7Ci0gICAgICAgIGlmIChqYXZhRW5jb2RpbmcgIT0gbnVsbCkgewotICAgICAgICAgICAgaW50IGxlbmd0aCA9IGphdmFFbmNvZGluZy5sZW5ndGgoKTsKLSAgICAgICAgICAgIGlmIChsZW5ndGggPiAwKSB7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDE7IGkgPCBsZW5ndGg7IGkrKykgewotICAgICAgICAgICAgICAgICAgICBjaGFyIGMgPSBqYXZhRW5jb2RpbmcuY2hhckF0KGkpOwotICAgICAgICAgICAgICAgICAgICBpZiAoKGMgPCAnQScgfHwgYyA+ICdaJykgJiYgKGMgPCAnYScgfHwgYyA+ICd6JykgJiYKLSAgICAgICAgICAgICAgICAgICAgICAgIChjIDwgJzAnIHx8IGMgPiAnOScpICYmIGMgIT0gJy4nICYmIGMgIT0gJ18nICYmCi0gICAgICAgICAgICAgICAgICAgICAgICBjICE9ICctJykgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9IC8vIGlzVmFsaWRJQU5BRW5jb2RpbmcoU3RyaW5nKTpib29sZWFuCi0KLSAgIC8qKgotICAgICAqIFNpbXBsZSBjaGVjayB0byBkZXRlcm1pbmUgaWYgcW5hbWUgaXMgbGVnYWwuIElmIGl0IHJldHVybnMgZmFsc2UKLSAgICAgKiB0aGVuIDxwYXJhbT5zdHI8L3BhcmFtPiBpcyBpbGxlZ2FsOyBpZiBpdCByZXR1cm5zIHRydWUgdGhlbgotICAgICAqIDxwYXJhbT5zdHI8L3BhcmFtPiBpcyBsZWdhbC4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNWYWxpZFFOYW1lKFN0cmluZyBzdHIpIHsKLQotICAgICAgIGZpbmFsIGludCBjb2xvbiA9IHN0ci5pbmRleE9mKCc6Jyk7Ci0KLSAgICAgICBpZiAoY29sb24gPT0gMCB8fCBjb2xvbiA9PSBzdHIubGVuZ3RoKCkgLSAxKSB7Ci0gICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICB9Ci0KLSAgICAgICBpZiAoY29sb24gPiAwKSB7Ci0gICAgICAgICAgIGZpbmFsIFN0cmluZyBwcmVmaXggPSBzdHIuc3Vic3RyaW5nKDAsY29sb24pOwotICAgICAgICAgICBmaW5hbCBTdHJpbmcgbG9jYWxQYXJ0ID0gc3RyLnN1YnN0cmluZyhjb2xvbisxKTsKLSAgICAgICAgICAgcmV0dXJuIGlzVmFsaWROQ05hbWUocHJlZml4KSAmJiBpc1ZhbGlkTkNOYW1lKGxvY2FsUGFydCk7Ci0gICAgICAgfQotICAgICAgIGVsc2UgewotICAgICAgICAgICByZXR1cm4gaXNWYWxpZE5DTmFtZShzdHIpOwotICAgICAgIH0KLSAgICB9Ci0KLX0gLy8gY2xhc3MgWE1MQ2hhcgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvWE1MQ2hhcmFjdGVyUmVjb2duaXplci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvWE1MQ2hhcmFjdGVyUmVjb2duaXplci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmYTEzN2RjLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL1hNTENoYXJhY3RlclJlY29nbml6ZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExMSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBYTUxDaGFyYWN0ZXJSZWNvZ25pemVyLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTUgMDg6MTY6MDEgc3VyZXNoX2VtYWlsaWQgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzOwotCi0vKioKLSAqIENsYXNzIHVzZWQgdG8gdmVyaWZ5IHdoZXRoZXIgdGhlIHNwZWNpZmllZCA8dmFyPmNoPC92YXI+Ci0gKiBjb25mb3JtcyB0byB0aGUgWE1MIDEuMCBkZWZpbml0aW9uIG9mIHdoaXRlc3BhY2UuCi0gKiBAeHNsLnVzYWdlIGludGVybmFsCi0gKi8KLXB1YmxpYyBjbGFzcyBYTUxDaGFyYWN0ZXJSZWNvZ25pemVyCi17Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgd2hldGhlciB0aGUgc3BlY2lmaWVkIDx2YXI+Y2g8L3Zhcj4gY29uZm9ybXMgdG8gdGhlIFhNTCAxLjAgZGVmaW5pdGlvbgotICAgKiBvZiB3aGl0ZXNwYWNlLiAgUmVmZXIgdG8gPEEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMteG1sLTE5OTgwMjEwI05ULVMiPgotICAgKiB0aGUgZGVmaW5pdGlvbiBvZiA8Q09ERT5TPC9DT0RFPjwvQT4gZm9yIGRldGFpbHMuCi0gICAqIEBwYXJhbSBjaCBDaGFyYWN0ZXIgdG8gY2hlY2sgYXMgWE1MIHdoaXRlc3BhY2UuCi0gICAqIEByZXR1cm4gPXRydWUgaWYgPHZhcj5jaDwvdmFyPiBpcyBYTUwgd2hpdGVzcGFjZTsgb3RoZXJ3aXNlID1mYWxzZS4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc1doaXRlU3BhY2UoY2hhciBjaCkKLSAgewotICAgIHJldHVybiAoY2ggPT0gMHgyMCkgfHwgKGNoID09IDB4MDkpIHx8IChjaCA9PSAweEQpIHx8IChjaCA9PSAweEEpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgdGhlIHN0cmluZyBpcyB3aGl0ZXNwYWNlLgotICAgKgotICAgKiBAcGFyYW0gY2ggQ2hhcmFjdGVyIGFycmF5IHRvIGNoZWNrIGFzIFhNTCB3aGl0ZXNwYWNlLgotICAgKiBAcGFyYW0gc3RhcnQgU3RhcnQgaW5kZXggb2YgY2hhcmFjdGVycyBpbiB0aGUgYXJyYXkKLSAgICogQHBhcmFtIGxlbmd0aCBOdW1iZXIgb2YgY2hhcmFjdGVycyBpbiB0aGUgYXJyYXkKLSAgICogQHJldHVybiBUcnVlIGlmIHRoZSBjaGFyYWN0ZXJzIGluIHRoZSBhcnJheSBhcmUKLSAgICogWE1MIHdoaXRlc3BhY2U7IG90aGVyd2lzZSwgZmFsc2UuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNXaGl0ZVNwYWNlKGNoYXIgY2hbXSwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKQotICB7Ci0KLSAgICBpbnQgZW5kID0gc3RhcnQgKyBsZW5ndGg7Ci0KLSAgICBmb3IgKGludCBzID0gc3RhcnQ7IHMgPCBlbmQ7IHMrKykKLSAgICB7Ci0gICAgICBpZiAoIWlzV2hpdGVTcGFjZShjaFtzXSkpCi0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICByZXR1cm4gdHJ1ZTsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIGlmIHRoZSBzdHJpbmcgaXMgd2hpdGVzcGFjZS4KLSAgICoKLSAgICogQHBhcmFtIGJ1ZiBTdHJpbmdCdWZmZXIgdG8gY2hlY2sgYXMgWE1MIHdoaXRlc3BhY2UuCi0gICAqIEByZXR1cm4gVHJ1ZSBpZiBjaGFyYWN0ZXJzIGluIGJ1ZmZlciBhcmUgWE1MIHdoaXRlc3BhY2UsIGZhbHNlIG90aGVyd2lzZQotICAgKi8KLSAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzV2hpdGVTcGFjZShTdHJpbmdCdWZmZXIgYnVmKQotICB7Ci0KLSAgICBpbnQgbiA9IGJ1Zi5sZW5ndGgoKTsKLQotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKQotICAgIHsKLSAgICAgIGlmICghaXNXaGl0ZVNwYWNlKGJ1Zi5jaGFyQXQoaSkpKQotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgcmV0dXJuIHRydWU7Ci0gIH0KLQotICAvKioKLSAgICogVGVsbCBpZiB0aGUgc3RyaW5nIGlzIHdoaXRlc3BhY2UuCi0gICAqCi0gICAqIEBwYXJhbSBzIFN0cmluZyB0byBjaGVjayBhcyBYTUwgd2hpdGVzcGFjZS4KLSAgICogQHJldHVybiBUcnVlIGlmIGNoYXJhY3RlcnMgaW4gYnVmZmVyIGFyZSBYTUwgd2hpdGVzcGFjZSwgZmFsc2Ugb3RoZXJ3aXNlCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNXaGl0ZVNwYWNlKFN0cmluZyBzKQotICB7Ci0KLSAgICBpZihudWxsICE9IHMpCi0gICAgewotICAgICAgaW50IG4gPSBzLmxlbmd0aCgpOwotCi0gICAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykKLSAgICAgIHsKLSAgICAgICAgaWYgKCFpc1doaXRlU3BhY2Uocy5jaGFyQXQoaSkpKQotICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gdHJ1ZTsKLSAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9YTUxSZWFkZXJNYW5hZ2VyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9YTUxSZWFkZXJNYW5hZ2VyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDA5Y2QwNGMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvWE1MUmVhZGVyTWFuYWdlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjU3ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFhNTFJlYWRlck1hbmFnZXIuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNSAwODoxNjowMiBzdXJlc2hfZW1haWxpZCBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwuWGFsYW5Db25zdGFudHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnV0aWxzLkZhY3RvcnlJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC51dGlscy5TZWN1cml0eVN1cHBvcnQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnV0aWxzLlhNTFNlY3VyaXR5TWFuYWdlcjsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKLQotaW1wb3J0IGphdmF4LnhtbC5YTUxDb25zdGFudHM7Ci1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvcjsKLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy5QYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uOwotaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLlNBWFBhcnNlckZhY3Rvcnk7Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguWE1MUmVhZGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LmhlbHBlcnMuWE1MUmVhZGVyRmFjdG9yeTsKLQotLyoqCi0gKiBDcmVhdGVzIFhNTFJlYWRlciBvYmplY3RzIGFuZCBjYWNoZXMgdGhlbSBmb3IgcmUtdXNlLgotICogVGhpcyBjbGFzcyBmb2xsb3dzIHRoZSBzaW5nbGV0b24gcGF0dGVybi4KLSAqLwotcHVibGljIGNsYXNzIFhNTFJlYWRlck1hbmFnZXIgewotCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIE5BTUVTUEFDRVNfRkVBVFVSRSA9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICJodHRwOi8veG1sLm9yZy9zYXgvZmVhdHVyZXMvbmFtZXNwYWNlcyI7Ci0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIE5BTUVTUEFDRV9QUkVGSVhFU19GRUFUVVJFID0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy9uYW1lc3BhY2UtcHJlZml4ZXMiOwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFhNTFJlYWRlck1hbmFnZXIgbV9zaW5nbGV0b25NYW5hZ2VyID0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFhNTFJlYWRlck1hbmFnZXIoKTsKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgcHJvcGVydHkgPSAib3JnLnhtbC5zYXguZHJpdmVyIjsKLSAgICAvKioKLSAgICAgKiBQYXJzZXIgZmFjdG9yeSB0byBiZSB1c2VkIHRvIGNvbnN0cnVjdCBYTUxSZWFkZXIgb2JqZWN0cwotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIFNBWFBhcnNlckZhY3RvcnkgbV9wYXJzZXJGYWN0b3J5OwotCi0gICAgLyoqCi0gICAgICogQ2FjaGUgb2YgWE1MUmVhZGVyIG9iamVjdHMKLSAgICAgKi8KLSAgICBwcml2YXRlIFRocmVhZExvY2FsIG1fcmVhZGVyczsKLQotICAgIC8qKgotICAgICAqIEtlZXBzIHRyYWNrIG9mIHdoZXRoZXIgYW4gWE1MUmVhZGVyIG9iamVjdCBpcyBpbiB1c2UuCi0gICAgICovCi0gICAgcHJpdmF0ZSBIYXNoTWFwIG1faW5Vc2U7Ci0KLSAgICBwcml2YXRlIGJvb2xlYW4gbV91c2VTZXJ2aWNlc01lY2hhbmlzbSA9IHRydWU7Ci0KLSAgICBwcml2YXRlIGJvb2xlYW4gX3NlY3VyZVByb2Nlc3Npbmc7Ci0gICAgIC8qKgotICAgICAqIHByb3RvY29scyBhbGxvd2VkIGZvciBleHRlcm5hbCBEVEQgcmVmZXJlbmNlcyBpbiBzb3VyY2UgZmlsZSBhbmQvb3Igc3R5bGVzaGVldC4KLSAgICAgKi8KLSAgICBwcml2YXRlIFN0cmluZyBfYWNjZXNzRXh0ZXJuYWxEVEQgPSBYYWxhbkNvbnN0YW50cy5FWFRFUk5BTF9BQ0NFU1NfREVGQVVMVDsKLQotICAgIHByaXZhdGUgWE1MU2VjdXJpdHlNYW5hZ2VyIF94bWxTZWN1cml0eU1hbmFnZXI7Ci0KLSAgICAvKioKLSAgICAgKiBIaWRkZW4gY29uc3RydWN0b3IKLSAgICAgKi8KLSAgICBwcml2YXRlIFhNTFJlYWRlck1hbmFnZXIoKSB7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0cmlldmVzIHRoZSBzaW5nbGV0b24gcmVhZGVyIG1hbmFnZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFhNTFJlYWRlck1hbmFnZXIgZ2V0SW5zdGFuY2UoYm9vbGVhbiB1c2VTZXJ2aWNlc01lY2hhbmlzbSkgewotICAgICAgICBtX3NpbmdsZXRvbk1hbmFnZXIuc2V0U2VydmljZXNNZWNobmlzbSh1c2VTZXJ2aWNlc01lY2hhbmlzbSk7Ci0gICAgICAgIHJldHVybiBtX3NpbmdsZXRvbk1hbmFnZXI7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0cmlldmVzIGEgY2FjaGVkIFhNTFJlYWRlciBmb3IgdGhpcyB0aHJlYWQsIG9yIGNyZWF0ZXMgYSBuZXcKLSAgICAgKiBYTUxSZWFkZXIsIGlmIHRoZSBleGlzdGluZyByZWFkZXIgaXMgaW4gdXNlLiAgV2hlbiB0aGUgY2FsbGVyIG5vCi0gICAgICogbG9uZ2VyIG5lZWRzIHRoZSByZWFkZXIsIGl0IG11c3QgcmVsZWFzZSBpdCB3aXRoIGEgY2FsbCB0bwotICAgICAqIHtAbGluayAjcmVsZWFzZVhNTFJlYWRlcn0uCi0gICAgICovCi0gICAgcHVibGljIHN5bmNocm9uaXplZCBYTUxSZWFkZXIgZ2V0WE1MUmVhZGVyKCkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0gICAgICAgIFhNTFJlYWRlciByZWFkZXI7Ci0KLSAgICAgICAgaWYgKG1fcmVhZGVycyA9PSBudWxsKSB7Ci0gICAgICAgICAgICAvLyBXaGVuIHRoZSBtX3JlYWRlcnMuZ2V0KCkgbWV0aG9kIGlzIGNhbGxlZCBmb3IgdGhlIGZpcnN0IHRpbWUKLSAgICAgICAgICAgIC8vIG9uIGEgdGhyZWFkLCBhIG5ldyBYTUxSZWFkZXIgd2lsbCBhdXRvbWF0aWNhbGx5IGJlIGNyZWF0ZWQuCi0gICAgICAgICAgICBtX3JlYWRlcnMgPSBuZXcgVGhyZWFkTG9jYWwoKTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChtX2luVXNlID09IG51bGwpIHsKLSAgICAgICAgICAgIG1faW5Vc2UgPSBuZXcgSGFzaE1hcCgpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gSWYgdGhlIGNhY2hlZCByZWFkZXIgZm9yIHRoaXMgdGhyZWFkIGlzIGluIHVzZSwgY29uc3RydWN0IGEgbmV3Ci0gICAgICAgIC8vIG9uZTsgb3RoZXJ3aXNlLCByZXR1cm4gdGhlIGNhY2hlZCByZWFkZXIgdW5sZXNzIGl0IGlzbid0IGFuCi0gICAgICAgIC8vIGluc3RhbmNlIG9mIHRoZSBjbGFzcyBzZXQgaW4gdGhlICdvcmcueG1sLnNheC5kcml2ZXInIHByb3BlcnR5Ci0gICAgICAgIHJlYWRlciA9IChYTUxSZWFkZXIpIG1fcmVhZGVycy5nZXQoKTsKLSAgICAgICAgYm9vbGVhbiB0aHJlYWRIYXNSZWFkZXIgPSAocmVhZGVyICE9IG51bGwpOwotICAgICAgICBTdHJpbmcgZmFjdG9yeSA9IFNlY3VyaXR5U3VwcG9ydC5nZXRTeXN0ZW1Qcm9wZXJ0eShwcm9wZXJ0eSk7Ci0gICAgICAgIGlmICh0aHJlYWRIYXNSZWFkZXIgJiYgbV9pblVzZS5nZXQocmVhZGVyKSAhPSBCb29sZWFuLlRSVUUgJiYKLSAgICAgICAgICAgICAgICAoIGZhY3RvcnkgPT0gbnVsbCB8fCByZWFkZXIuZ2V0Q2xhc3MoKS5nZXROYW1lKCkuZXF1YWxzKGZhY3RvcnkpKSkgewotICAgICAgICAgICAgbV9pblVzZS5wdXQocmVhZGVyLCBCb29sZWFuLlRSVUUpOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICAvLyBBY2NvcmRpbmcgdG8gSkFYUCAxLjIgc3BlY2lmaWNhdGlvbiwgaWYgYSBTQVhTb3VyY2UKLSAgICAgICAgICAgICAgICAgICAgLy8gaXMgY3JlYXRlZCB1c2luZyBhIFNBWCBJbnB1dFNvdXJjZSB0aGUgVHJhbnNmb3JtZXIgb3IKLSAgICAgICAgICAgICAgICAgICAgLy8gVHJhbnNmb3JtZXJGYWN0b3J5IGNyZWF0ZXMgYSByZWFkZXIgdmlhIHRoZQotICAgICAgICAgICAgICAgICAgICAvLyBYTUxSZWFkZXJGYWN0b3J5IGlmIHNldFhNTFJlYWRlciBpcyBub3QgdXNlZAotICAgICAgICAgICAgICAgICAgICByZWFkZXIgPSBYTUxSZWFkZXJGYWN0b3J5LmNyZWF0ZVhNTFJlYWRlcigpOwotICAgICAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICAgICAgcmVhZGVyLnNldEZlYXR1cmUoWE1MQ29uc3RhbnRzLkZFQVRVUkVfU0VDVVJFX1BST0NFU1NJTkcsIF9zZWN1cmVQcm9jZXNzaW5nKTsKLSAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBYTUxTZWN1cml0eU1hbmFnZXIucHJpbnRXYXJuaW5nKHJlYWRlci5nZXRDbGFzcygpLmdldE5hbWUoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MQ29uc3RhbnRzLkZFQVRVUkVfU0VDVVJFX1BST0NFU1NJTkcsIGUpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gSWYgdW5hYmxlIHRvIGNyZWF0ZSBhbiBpbnN0YW5jZSwgbGV0J3MgdHJ5IHRvIHVzZQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhlIFhNTFJlYWRlciBmcm9tIEpBWFAKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtX3BhcnNlckZhY3RvcnkgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fcGFyc2VyRmFjdG9yeSA9IEZhY3RvcnlJbXBsLmdldFNBWEZhY3RvcnkobV91c2VTZXJ2aWNlc01lY2hhbmlzbSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbV9wYXJzZXJGYWN0b3J5LnNldE5hbWVzcGFjZUF3YXJlKHRydWUpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgICAgICByZWFkZXIgPSBtX3BhcnNlckZhY3RvcnkubmV3U0FYUGFyc2VyKCkuZ2V0WE1MUmVhZGVyKCk7Ci0gICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBwY2UpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgcGNlOyAgIC8vIHBhc3MgYWxvbmcgcGNlCi0gICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICByZWFkZXIuc2V0RmVhdHVyZShOQU1FU1BBQ0VTX0ZFQVRVUkUsIHRydWUpOwotICAgICAgICAgICAgICAgICAgICByZWFkZXIuc2V0RmVhdHVyZShOQU1FU1BBQ0VfUFJFRklYRVNfRkVBVFVSRSwgZmFsc2UpOwotICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBzZSkgewotICAgICAgICAgICAgICAgICAgICAvLyBUcnkgdG8gY2Fycnkgb24gaWYgd2UndmUgZ290IGEgcGFyc2VyIHRoYXQKLSAgICAgICAgICAgICAgICAgICAgLy8gZG9lc24ndCBrbm93IGFib3V0IG5hbWVzcGFjZSBwcmVmaXhlcy4KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9IGNhdGNoIChQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIGV4KSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbihleCk7Ci0gICAgICAgICAgICB9IGNhdGNoIChGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yIGV4MSkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oZXgxLnRvU3RyaW5nKCkpOwotICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoTWV0aG9kRXJyb3IgZXgyKSB7Ci0gICAgICAgICAgICB9IGNhdGNoIChBYnN0cmFjdE1ldGhvZEVycm9yIGFtZSkgewotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBDYWNoZSB0aGUgWE1MUmVhZGVyIGlmIHRoaXMgaXMgdGhlIGZpcnN0IHRpbWUgd2UndmUgY3JlYXRlZAotICAgICAgICAgICAgLy8gYSByZWFkZXIgZm9yIHRoaXMgdGhyZWFkLgotICAgICAgICAgICAgaWYgKCF0aHJlYWRIYXNSZWFkZXIpIHsKLSAgICAgICAgICAgICAgICBtX3JlYWRlcnMuc2V0KHJlYWRlcik7Ci0gICAgICAgICAgICAgICAgbV9pblVzZS5wdXQocmVhZGVyLCBCb29sZWFuLlRSVUUpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIC8vcmVhZGVyIGlzIGNhY2hlZCwgYnV0IHRoaXMgcHJvcGVydHkgbWlnaHQgaGF2ZSBiZWVuIHJlc2V0Ci0gICAgICAgICAgICByZWFkZXIuc2V0UHJvcGVydHkoWE1MQ29uc3RhbnRzLkFDQ0VTU19FWFRFUk5BTF9EVEQsIF9hY2Nlc3NFeHRlcm5hbERURCk7Ci0gICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBzZSkgewotICAgICAgICAgICAgWE1MU2VjdXJpdHlNYW5hZ2VyLnByaW50V2FybmluZyhyZWFkZXIuZ2V0Q2xhc3MoKS5nZXROYW1lKCksCi0gICAgICAgICAgICAgICAgICAgIFhNTENvbnN0YW50cy5BQ0NFU1NfRVhURVJOQUxfRFRELCBzZSk7Ci0gICAgICAgIH0KLQotICAgICAgICBTdHJpbmcgbGFzdFByb3BlcnR5ID0gIiI7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBpZiAoX3htbFNlY3VyaXR5TWFuYWdlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZm9yIChYTUxTZWN1cml0eU1hbmFnZXIuTGltaXQgbGltaXQgOiBYTUxTZWN1cml0eU1hbmFnZXIuTGltaXQudmFsdWVzKCkpIHsKLSAgICAgICAgICAgICAgICAgICAgbGFzdFByb3BlcnR5ID0gbGltaXQuYXBpUHJvcGVydHkoKTsKLSAgICAgICAgICAgICAgICAgICAgcmVhZGVyLnNldFByb3BlcnR5KGxhc3RQcm9wZXJ0eSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBfeG1sU2VjdXJpdHlNYW5hZ2VyLmdldExpbWl0VmFsdWVBc1N0cmluZyhsaW1pdCkpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpZiAoX3htbFNlY3VyaXR5TWFuYWdlci5wcmludEVudGl0eUNvdW50SW5mbygpKSB7Ci0gICAgICAgICAgICAgICAgICAgIGxhc3RQcm9wZXJ0eSA9IFhhbGFuQ29uc3RhbnRzLkpES19FTlRJVFlfQ09VTlRfSU5GTzsKLSAgICAgICAgICAgICAgICAgICAgcmVhZGVyLnNldFByb3BlcnR5KFhhbGFuQ29uc3RhbnRzLkpES19FTlRJVFlfQ09VTlRfSU5GTywgWGFsYW5Db25zdGFudHMuSkRLX1lFUyk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gc2UpIHsKLSAgICAgICAgICAgIFhNTFNlY3VyaXR5TWFuYWdlci5wcmludFdhcm5pbmcocmVhZGVyLmdldENsYXNzKCkuZ2V0TmFtZSgpLCBsYXN0UHJvcGVydHksIHNlKTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiByZWFkZXI7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogTWFyayB0aGUgY2FjaGVkIFhNTFJlYWRlciBhcyBhdmFpbGFibGUuICBJZiB0aGUgcmVhZGVyIHdhcyBub3QKLSAgICAgKiBhY3R1YWxseSBpbiB0aGUgY2FjaGUsIGRvIG5vdGhpbmcuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcmVhZGVyIFRoZSBYTUxSZWFkZXIgdGhhdCdzIGJlaW5nIHJlbGVhc2VkLgotICAgICAqLwotICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCByZWxlYXNlWE1MUmVhZGVyKFhNTFJlYWRlciByZWFkZXIpIHsKLSAgICAgICAgLy8gSWYgdGhlIHJlYWRlciB0aGF0J3MgYmVpbmcgcmVsZWFzZWQgaXMgdGhlIGNhY2hlZCByZWFkZXIKLSAgICAgICAgLy8gZm9yIHRoaXMgdGhyZWFkLCByZW1vdmUgaXQgZnJvbSB0aGUgbV9pc1VzZSBsaXN0LgotICAgICAgICBpZiAobV9yZWFkZXJzLmdldCgpID09IHJlYWRlciAmJiByZWFkZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgbV9pblVzZS5yZW1vdmUocmVhZGVyKTsKLSAgICAgICAgfQotICAgIH0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIHN0YXRlIG9mIHRoZSBzZXJ2aWNlcyBtZWNoYW5pc20gZmVhdHVyZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiB1c2VTZXJ2aWNlc01lY2huaXNtKCkgewotICAgICAgICByZXR1cm4gbV91c2VTZXJ2aWNlc01lY2hhbmlzbTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIHN0YXRlIG9mIHRoZSBzZXJ2aWNlcyBtZWNoYW5pc20gZmVhdHVyZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRTZXJ2aWNlc01lY2huaXNtKGJvb2xlYW4gZmxhZykgewotICAgICAgICBtX3VzZVNlcnZpY2VzTWVjaGFuaXNtID0gZmxhZzsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgZmVhdHVyZQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEZlYXR1cmUoU3RyaW5nIG5hbWUsIGJvb2xlYW4gdmFsdWUpIHsKLSAgICAgICAgaWYgKG5hbWUuZXF1YWxzKFhNTENvbnN0YW50cy5GRUFUVVJFX1NFQ1VSRV9QUk9DRVNTSU5HKSkgewotICAgICAgICAgICAgX3NlY3VyZVByb2Nlc3NpbmcgPSB2YWx1ZTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCBwcm9wZXJ0eSB2YWx1ZQotICAgICAqLwotICAgIHB1YmxpYyBPYmplY3QgZ2V0UHJvcGVydHkoU3RyaW5nIG5hbWUpIHsKLSAgICAgICAgaWYgKG5hbWUuZXF1YWxzKFhNTENvbnN0YW50cy5BQ0NFU1NfRVhURVJOQUxfRFREKSkgewotICAgICAgICAgICAgcmV0dXJuIF9hY2Nlc3NFeHRlcm5hbERURDsKLSAgICAgICAgfSBlbHNlIGlmIChuYW1lLmVxdWFscyhYYWxhbkNvbnN0YW50cy5TRUNVUklUWV9NQU5BR0VSKSkgewotICAgICAgICAgICAgcmV0dXJuIF94bWxTZWN1cml0eU1hbmFnZXI7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0IHByb3BlcnR5LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFByb3BlcnR5KFN0cmluZyBuYW1lLCBPYmplY3QgdmFsdWUpIHsKLSAgICAgICAgaWYgKG5hbWUuZXF1YWxzKFhNTENvbnN0YW50cy5BQ0NFU1NfRVhURVJOQUxfRFREKSkgewotICAgICAgICAgICAgX2FjY2Vzc0V4dGVybmFsRFREID0gKFN0cmluZyl2YWx1ZTsKLSAgICAgICAgfSBlbHNlIGlmIChuYW1lLmVxdWFscyhYYWxhbkNvbnN0YW50cy5TRUNVUklUWV9NQU5BR0VSKSkgewotICAgICAgICAgICAgX3htbFNlY3VyaXR5TWFuYWdlciA9IChYTUxTZWN1cml0eU1hbmFnZXIpdmFsdWU7Ci0gICAgICAgIH0KLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9YTUxTdHJpbmcuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL1hNTFN0cmluZy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlOGRlNmYzLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL1hNTFN0cmluZy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNjkxICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFhNTFN0cmluZy5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE1IDA4OjE2OjAyIHN1cmVzaF9lbWFpbGlkIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlsczsKLQotaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7Ci0KLS8qKgotICogVGhpcyBjbGFzcyBpcyBtZWFudCB0byBiZSBhbiBpbnRlcmZhY2UgdG8gY2hhcmFjdGVyIHN0cmluZ3MsIHdoZXRoZXIgdGhleQotICogYmUgamF2YSBTdHJpbmdzIG9yIDxjb2RlPmNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuRmFzdFN0cmluZ0J1ZmZlcjwvY29kZT5zLCBvcgotICogb3RoZXIgY2hhcmFjdGVyIGRhdGEuICBCeSB1c2luZyBYTUxTdHJpbmcsIGNoYXJhY3RlciBjb3BpZXMgY2FuIGJlIHJlZHVjZWQKLSAqIGluIHRoZSBYTUwgcGlwZWxpbmUuCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgWE1MU3RyaW5nCi17Ci0KLSAgLyoqCi0gICAqIERpcmVjdGx5IGNhbGwgdGhlCi0gICAqIGNoYXJhY3RlcnMgbWV0aG9kIG9uIHRoZSBwYXNzZWQgQ29udGVudEhhbmRsZXIgZm9yIHRoZQotICAgKiBzdHJpbmctdmFsdWUuIE11bHRpcGxlIGNhbGxzIHRvIHRoZQotICAgKiBDb250ZW50SGFuZGxlcidzIGNoYXJhY3RlcnMgbWV0aG9kcyBtYXkgd2VsbCBvY2N1ciBmb3IgYSBzaW5nbGUgY2FsbCB0bwotICAgKiB0aGlzIG1ldGhvZC4KLSAgICoKLSAgICogQHBhcmFtIGNoIEEgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGEgQ29udGVudEhhbmRsZXIuCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBkaXNwYXRjaENoYXJhY3RlcnNFdmVudHMob3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIgY2gpCi0gICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKLQotICAvKioKLSAgICogRGlyZWN0bHkgY2FsbCB0aGUKLSAgICogY29tbWVudCBtZXRob2Qgb24gdGhlIHBhc3NlZCBMZXhpY2FsSGFuZGxlciBmb3IgdGhlCi0gICAqIHN0cmluZy12YWx1ZS4KLSAgICoKLSAgICogQHBhcmFtIGxoIEEgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGEgTGV4aWNhbEhhbmRsZXIuCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBkaXNwYXRjaEFzQ29tbWVudChvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXIgbGgpCi0gICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKLQotICAvKioKLSAgICogQ29uZGl0aW9uYWxseSB0cmltIGFsbCBsZWFkaW5nIGFuZCB0cmFpbGluZyB3aGl0ZXNwYWNlIGluIHRoZSBzcGVjaWZpZWQgU3RyaW5nLgotICAgKiBBbGwgc3RyaW5ncyBvZiB3aGl0ZSBzcGFjZSBhcmUKLSAgICogcmVwbGFjZWQgYnkgYSBzaW5nbGUgc3BhY2UgY2hhcmFjdGVyICgjeDIwKSwgZXhjZXB0IHNwYWNlcyBhZnRlciBwdW5jdHVhdGlvbiB3aGljaAotICAgKiByZWNlaXZlIGRvdWJsZSBzcGFjZXMgaWYgZG91YmxlUHVuY3R1YXRpb25TcGFjZXMgaXMgdHJ1ZS4KLSAgICogVGhpcyBmdW5jdGlvbiBtYXkgYmUgdXNlZnVsIHRvIGEgZm9ybWF0dGVyLCBidXQgdG8gZ2V0IGZpcnN0IGNsYXNzCi0gICAqIHJlc3VsdHMsIHRoZSBmb3JtYXR0ZXIgc2hvdWxkIHByb2JhYmx5IGRvIGl0J3Mgb3duIHdoaXRlIHNwYWNlIGhhbmRsaW5nCi0gICAqIGJhc2VkIG9uIHRoZSBzZW1hbnRpY3Mgb2YgdGhlIGZvcm1hdHRpbmcgb2JqZWN0LgotICAgKgotICAgKiBAcGFyYW0gICB0cmltSGVhZCAgICBUcmltIGxlYWRpbmcgd2hpdGVzcGFjZT8KLSAgICogQHBhcmFtICAgdHJpbVRhaWwgICAgVHJpbSB0cmFpbGluZyB3aGl0ZXNwYWNlPwotICAgKiBAcGFyYW0gICBkb3VibGVQdW5jdHVhdGlvblNwYWNlcyAgICBVc2UgZG91YmxlIHNwYWNlcyBmb3IgcHVuY3R1YXRpb24/Ci0gICAqIEByZXR1cm4gICAgICAgICAgICAgIFRoZSB0cmltbWVkIHN0cmluZy4KLSAgICovCi0gIHB1YmxpYyBYTUxTdHJpbmcgZml4V2hpdGVTcGFjZShib29sZWFuIHRyaW1IZWFkLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiB0cmltVGFpbCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gZG91YmxlUHVuY3R1YXRpb25TcGFjZXMpOwotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBsZW5ndGggb2YgdGhpcyBzdHJpbmcuCi0gICAqCi0gICAqIEByZXR1cm4gIHRoZSBsZW5ndGggb2YgdGhlIHNlcXVlbmNlIG9mIGNoYXJhY3RlcnMgcmVwcmVzZW50ZWQgYnkgdGhpcwotICAgKiAgICAgICAgICBvYmplY3QuCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgaW50IGxlbmd0aCgpOwotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBjaGFyYWN0ZXIgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4gQW4gaW5kZXggcmFuZ2VzCi0gICAqIGZyb20gPGNvZGU+MDwvY29kZT4gdG8gPGNvZGU+bGVuZ3RoKCkgLSAxPC9jb2RlPi4gVGhlIGZpcnN0IGNoYXJhY3RlcgotICAgKiBvZiB0aGUgc2VxdWVuY2UgaXMgYXQgaW5kZXggPGNvZGU+MDwvY29kZT4sIHRoZSBuZXh0IGF0IGluZGV4Ci0gICAqIDxjb2RlPjE8L2NvZGU+LCBhbmQgc28gb24sIGFzIGZvciBhcnJheSBpbmRleGluZy4KLSAgICoKLSAgICogQHBhcmFtICAgICAgaW5kZXggICB0aGUgaW5kZXggb2YgdGhlIGNoYXJhY3Rlci4KLSAgICogQHJldHVybiAgICAgdGhlIGNoYXJhY3RlciBhdCB0aGUgc3BlY2lmaWVkIGluZGV4IG9mIHRoaXMgc3RyaW5nLgotICAgKiAgICAgICAgICAgICBUaGUgZmlyc3QgY2hhcmFjdGVyIGlzIGF0IGluZGV4IDxjb2RlPjA8L2NvZGU+LgotICAgKiBAZXhjZXB0aW9uICBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uICBpZiB0aGUgPGNvZGU+aW5kZXg8L2NvZGU+Ci0gICAqICAgICAgICAgICAgIGFyZ3VtZW50IGlzIG5lZ2F0aXZlIG9yIG5vdCBsZXNzIHRoYW4gdGhlIGxlbmd0aCBvZiB0aGlzCi0gICAqICAgICAgICAgICAgIHN0cmluZy4KLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBjaGFyIGNoYXJBdChpbnQgaW5kZXgpOwotCi0gIC8qKgotICAgKiBDb3BpZXMgY2hhcmFjdGVycyBmcm9tIHRoaXMgc3RyaW5nIGludG8gdGhlIGRlc3RpbmF0aW9uIGNoYXJhY3RlcgotICAgKiBhcnJheS4KLSAgICoKLSAgICogQHBhcmFtICAgICAgc3JjQmVnaW4gICBpbmRleCBvZiB0aGUgZmlyc3QgY2hhcmFjdGVyIGluIHRoZSBzdHJpbmcKLSAgICogICAgICAgICAgICAgICAgICAgICAgICB0byBjb3B5LgotICAgKiBAcGFyYW0gICAgICBzcmNFbmQgICAgIGluZGV4IGFmdGVyIHRoZSBsYXN0IGNoYXJhY3RlciBpbiB0aGUgc3RyaW5nCi0gICAqICAgICAgICAgICAgICAgICAgICAgICAgdG8gY29weS4KLSAgICogQHBhcmFtICAgICAgZHN0ICAgICAgICB0aGUgZGVzdGluYXRpb24gYXJyYXkuCi0gICAqIEBwYXJhbSAgICAgIGRzdEJlZ2luICAgdGhlIHN0YXJ0IG9mZnNldCBpbiB0aGUgZGVzdGluYXRpb24gYXJyYXkuCi0gICAqIEBleGNlcHRpb24gSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBJZiBhbnkgb2YgdGhlIGZvbGxvd2luZwotICAgKiAgICAgICAgICAgIGlzIHRydWU6Ci0gICAqICAgICAgICAgICAgPHVsPjxsaT48Y29kZT5zcmNCZWdpbjwvY29kZT4gaXMgbmVnYXRpdmUuCi0gICAqICAgICAgICAgICAgPGxpPjxjb2RlPnNyY0JlZ2luPC9jb2RlPiBpcyBncmVhdGVyIHRoYW4gPGNvZGU+c3JjRW5kPC9jb2RlPgotICAgKiAgICAgICAgICAgIDxsaT48Y29kZT5zcmNFbmQ8L2NvZGU+IGlzIGdyZWF0ZXIgdGhhbiB0aGUgbGVuZ3RoIG9mIHRoaXMKLSAgICogICAgICAgICAgICAgICAgc3RyaW5nCi0gICAqICAgICAgICAgICAgPGxpPjxjb2RlPmRzdEJlZ2luPC9jb2RlPiBpcyBuZWdhdGl2ZQotICAgKiAgICAgICAgICAgIDxsaT48Y29kZT5kc3RCZWdpbisoc3JjRW5kLXNyY0JlZ2luKTwvY29kZT4gaXMgbGFyZ2VyIHRoYW4KLSAgICogICAgICAgICAgICAgICAgPGNvZGU+ZHN0Lmxlbmd0aDwvY29kZT48L3VsPgotICAgKiBAZXhjZXB0aW9uIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIDxjb2RlPmRzdDwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4KLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCB2b2lkIGdldENoYXJzKGludCBzcmNCZWdpbiwgaW50IHNyY0VuZCwgY2hhciBkc3RbXSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGRzdEJlZ2luKTsKLQotICAvKioKLSAgICogQ29tcGFyZXMgdGhpcyBzdHJpbmcgdG8gdGhlIHNwZWNpZmllZCBvYmplY3QuCi0gICAqIFRoZSByZXN1bHQgaXMgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgYW5kIG9ubHkgaWYgdGhlIGFyZ3VtZW50IGlzIG5vdAotICAgKiA8Y29kZT5udWxsPC9jb2RlPiBhbmQgaXMgYW4gPGNvZGU+WE1MU3RyaW5nPC9jb2RlPiBvYmplY3QgdGhhdCByZXByZXNlbnRzCi0gICAqIHRoZSBzYW1lIHNlcXVlbmNlIG9mIGNoYXJhY3RlcnMgYXMgdGhpcyBvYmplY3QuCi0gICAqCi0gICAqIEBwYXJhbSAgIGFuT2JqZWN0ICAgdGhlIG9iamVjdCB0byBjb21wYXJlIHRoaXMgPGNvZGU+U3RyaW5nPC9jb2RlPgotICAgKiAgICAgICAgICAgICAgICAgICAgIGFnYWluc3QuCi0gICAqIEByZXR1cm4gIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSA8Y29kZT5TdHJpbmcgPC9jb2RlPmFyZSBlcXVhbDsKLSAgICogICAgICAgICAgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4KLSAgICogQHNlZSAgICAgamF2YS5sYW5nLlN0cmluZyNjb21wYXJlVG8oamF2YS5sYW5nLlN0cmluZykKLSAgICogQHNlZSAgICAgamF2YS5sYW5nLlN0cmluZyNlcXVhbHNJZ25vcmVDYXNlKGphdmEubGFuZy5TdHJpbmcpCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBlcXVhbHMoWE1MU3RyaW5nIGFuT2JqZWN0KTsKLQotICAvKioKLSAgICogQ29tcGFyZXMgdGhpcyBzdHJpbmcgdG8gdGhlIHNwZWNpZmllZCA8Y29kZT5TdHJpbmc8L2NvZGU+LgotICAgKiBUaGUgcmVzdWx0IGlzIDxjb2RlPnRydWU8L2NvZGU+IGlmIGFuZCBvbmx5IGlmIHRoZSBhcmd1bWVudCBpcyBub3QKLSAgICogPGNvZGU+bnVsbDwvY29kZT4gYW5kIGlzIGEgPGNvZGU+U3RyaW5nPC9jb2RlPiBvYmplY3QgdGhhdCByZXByZXNlbnRzCi0gICAqIHRoZSBzYW1lIHNlcXVlbmNlIG9mIGNoYXJhY3RlcnMgYXMgdGhpcyBvYmplY3QuCi0gICAqCi0gICAqIEBwYXJhbSAgIGFub3RoZXJTdHJpbmcgICB0aGUgb2JqZWN0IHRvIGNvbXBhcmUgdGhpcyA8Y29kZT5TdHJpbmc8L2NvZGU+Ci0gICAqICAgICAgICAgICAgICAgICAgICAgICAgICBhZ2FpbnN0LgotICAgKiBAcmV0dXJuICA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgPGNvZGU+U3RyaW5nPC9jb2RlPnMgYXJlIGVxdWFsOwotICAgKiAgICAgICAgICA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLgotICAgKiBAc2VlICAgICBqYXZhLmxhbmcuU3RyaW5nI2NvbXBhcmVUbyhqYXZhLmxhbmcuU3RyaW5nKQotICAgKiBAc2VlICAgICBqYXZhLmxhbmcuU3RyaW5nI2VxdWFsc0lnbm9yZUNhc2UoamF2YS5sYW5nLlN0cmluZykKLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGVxdWFscyhTdHJpbmcgYW5vdGhlclN0cmluZyk7Ci0KLSAgLyoqCi0gICAqIENvbXBhcmVzIHRoaXMgc3RyaW5nIHRvIHRoZSBzcGVjaWZpZWQgb2JqZWN0LgotICAgKiBUaGUgcmVzdWx0IGlzIDxjb2RlPnRydWU8L2NvZGU+IGlmIGFuZCBvbmx5IGlmIHRoZSBhcmd1bWVudCBpcyBub3QKLSAgICogPGNvZGU+bnVsbDwvY29kZT4gYW5kIGlzIGEgPGNvZGU+U3RyaW5nPC9jb2RlPiBvYmplY3QgdGhhdCByZXByZXNlbnRzCi0gICAqIHRoZSBzYW1lIHNlcXVlbmNlIG9mIGNoYXJhY3RlcnMgYXMgdGhpcyBvYmplY3QuCi0gICAqCi0gICAqIEBwYXJhbSAgIGFuT2JqZWN0ICAgdGhlIG9iamVjdCB0byBjb21wYXJlIHRoaXMgPGNvZGU+U3RyaW5nPC9jb2RlPgotICAgKiAgICAgICAgICAgICAgICAgICAgIGFnYWluc3QuCi0gICAqIEByZXR1cm4gIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSA8Y29kZT5TdHJpbmcgPC9jb2RlPmFyZSBlcXVhbDsKLSAgICogICAgICAgICAgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4KLSAgICogQHNlZSAgICAgamF2YS5sYW5nLlN0cmluZyNjb21wYXJlVG8oamF2YS5sYW5nLlN0cmluZykKLSAgICogQHNlZSAgICAgamF2YS5sYW5nLlN0cmluZyNlcXVhbHNJZ25vcmVDYXNlKGphdmEubGFuZy5TdHJpbmcpCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IGFuT2JqZWN0KTsKLQotICAvKioKLSAgICogQ29tcGFyZXMgdGhpcyA8Y29kZT5TdHJpbmc8L2NvZGU+IHRvIGFub3RoZXIgPGNvZGU+U3RyaW5nPC9jb2RlPiwKLSAgICogaWdub3JpbmcgY2FzZSBjb25zaWRlcmF0aW9ucy4gIFR3byBzdHJpbmdzIGFyZSBjb25zaWRlcmVkIGVxdWFsCi0gICAqIGlnbm9yaW5nIGNhc2UgaWYgdGhleSBhcmUgb2YgdGhlIHNhbWUgbGVuZ3RoLCBhbmQgY29ycmVzcG9uZGluZwotICAgKiBjaGFyYWN0ZXJzIGluIHRoZSB0d28gc3RyaW5ncyBhcmUgZXF1YWwgaWdub3JpbmcgY2FzZS4KLSAgICoKLSAgICogQHBhcmFtICAgYW5vdGhlclN0cmluZyAgIHRoZSA8Y29kZT5TdHJpbmc8L2NvZGU+IHRvIGNvbXBhcmUgdGhpcwotICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgPGNvZGU+U3RyaW5nPC9jb2RlPiBhZ2FpbnN0LgotICAgKiBAcmV0dXJuICA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgYXJndW1lbnQgaXMgbm90IDxjb2RlPm51bGw8L2NvZGU+Ci0gICAqICAgICAgICAgIGFuZCB0aGUgPGNvZGU+U3RyaW5nPC9jb2RlPnMgYXJlIGVxdWFsLAotICAgKiAgICAgICAgICBpZ25vcmluZyBjYXNlOyA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLgotICAgKiBAc2VlICAgICAjZXF1YWxzKE9iamVjdCkKLSAgICogQHNlZSAgICAgamF2YS5sYW5nLkNoYXJhY3RlciN0b0xvd2VyQ2FzZShjaGFyKQotICAgKiBAc2VlIGphdmEubGFuZy5DaGFyYWN0ZXIjdG9VcHBlckNhc2UoY2hhcikKLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGVxdWFsc0lnbm9yZUNhc2UoU3RyaW5nIGFub3RoZXJTdHJpbmcpOwotCi0gIC8qKgotICAgKiBDb21wYXJlcyB0d28gc3RyaW5ncyBsZXhpY29ncmFwaGljYWxseS4KLSAgICoKLSAgICogQHBhcmFtICAgYW5vdGhlclN0cmluZyAgIHRoZSA8Y29kZT5TdHJpbmc8L2NvZGU+IHRvIGJlIGNvbXBhcmVkLgotICAgKiBAcmV0dXJuICB0aGUgdmFsdWUgPGNvZGU+MDwvY29kZT4gaWYgdGhlIGFyZ3VtZW50IHN0cmluZyBpcyBlcXVhbCB0bwotICAgKiAgICAgICAgICB0aGlzIHN0cmluZzsgYSB2YWx1ZSBsZXNzIHRoYW4gPGNvZGU+MDwvY29kZT4gaWYgdGhpcyBzdHJpbmcKLSAgICogICAgICAgICAgaXMgbGV4aWNvZ3JhcGhpY2FsbHkgbGVzcyB0aGFuIHRoZSBzdHJpbmcgYXJndW1lbnQ7IGFuZCBhCi0gICAqICAgICAgICAgIHZhbHVlIGdyZWF0ZXIgdGhhbiA8Y29kZT4wPC9jb2RlPiBpZiB0aGlzIHN0cmluZyBpcwotICAgKiAgICAgICAgICBsZXhpY29ncmFwaGljYWxseSBncmVhdGVyIHRoYW4gdGhlIHN0cmluZyBhcmd1bWVudC4KLSAgICogQGV4Y2VwdGlvbiBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgPGNvZGU+YW5vdGhlclN0cmluZzwvY29kZT4KLSAgICogICAgICAgICAgaXMgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgaW50IGNvbXBhcmVUbyhYTUxTdHJpbmcgYW5vdGhlclN0cmluZyk7Ci0KLSAgLyoqCi0gICAqIENvbXBhcmVzIHR3byBzdHJpbmdzIGxleGljb2dyYXBoaWNhbGx5LCBpZ25vcmluZyBjYXNlIGNvbnNpZGVyYXRpb25zLgotICAgKiBUaGlzIG1ldGhvZCByZXR1cm5zIGFuIGludGVnZXIgd2hvc2Ugc2lnbiBpcyB0aGF0IG9mCi0gICAqIDxjb2RlPnRoaXMudG9VcHBlckNhc2UoKS50b0xvd2VyQ2FzZSgpLmNvbXBhcmVUbygKLSAgICogc3RyLnRvVXBwZXJDYXNlKCkudG9Mb3dlckNhc2UoKSk8L2NvZGU+LgotICAgKiA8cD4KLSAgICogTm90ZSB0aGF0IHRoaXMgbWV0aG9kIGRvZXMgPGVtPm5vdDwvZW0+IHRha2UgbG9jYWxlIGludG8gYWNjb3VudCwKLSAgICogYW5kIHdpbGwgcmVzdWx0IGluIGFuIHVuc2F0aXNmYWN0b3J5IG9yZGVyaW5nIGZvciBjZXJ0YWluIGxvY2FsZXMuCi0gICAqIFRoZSBqYXZhLnRleHQgcGFja2FnZSBwcm92aWRlcyA8ZW0+Y29sbGF0b3JzPC9lbT4gdG8gYWxsb3cKLSAgICogbG9jYWxlLXNlbnNpdGl2ZSBvcmRlcmluZy4KLSAgICoKLSAgICogQHBhcmFtICAgc3RyICAgdGhlIDxjb2RlPlN0cmluZzwvY29kZT4gdG8gYmUgY29tcGFyZWQuCi0gICAqIEByZXR1cm4gIGEgbmVnYXRpdmUgaW50ZWdlciwgemVybywgb3IgYSBwb3NpdGl2ZSBpbnRlZ2VyIGFzIHRoZQotICAgKiAgICAgICAgICB0aGUgc3BlY2lmaWVkIFN0cmluZyBpcyBncmVhdGVyIHRoYW4sIGVxdWFsIHRvLCBvciBsZXNzCi0gICAqICAgICAgICAgIHRoYW4gdGhpcyBTdHJpbmcsIGlnbm9yaW5nIGNhc2UgY29uc2lkZXJhdGlvbnMuCi0gICAqIEBzZWUgICAgIGphdmEudGV4dC5Db2xsYXRvciNjb21wYXJlKFN0cmluZywgU3RyaW5nKQotICAgKiBAc2luY2UgICAxLjIKLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBpbnQgY29tcGFyZVRvSWdub3JlQ2FzZShYTUxTdHJpbmcgc3RyKTsKLQotICAvKioKLSAgICogVGVzdHMgaWYgdGhpcyBzdHJpbmcgc3RhcnRzIHdpdGggdGhlIHNwZWNpZmllZCBwcmVmaXggYmVnaW5uaW5nCi0gICAqIGEgc3BlY2lmaWVkIGluZGV4LgotICAgKgotICAgKiBAcGFyYW0gICBwcmVmaXggICAgdGhlIHByZWZpeC4KLSAgICogQHBhcmFtICAgdG9mZnNldCAgIHdoZXJlIHRvIGJlZ2luIGxvb2tpbmcgaW4gdGhlIHN0cmluZy4KLSAgICogQHJldHVybiAgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIGNoYXJhY3RlciBzZXF1ZW5jZSByZXByZXNlbnRlZCBieSB0aGUKLSAgICogICAgICAgICAgYXJndW1lbnQgaXMgYSBwcmVmaXggb2YgdGhlIHN1YnN0cmluZyBvZiB0aGlzIG9iamVjdCBzdGFydGluZwotICAgKiAgICAgICAgICBhdCBpbmRleCA8Y29kZT50b2Zmc2V0PC9jb2RlPjsgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4KLSAgICogICAgICAgICAgVGhlIHJlc3VsdCBpcyA8Y29kZT5mYWxzZTwvY29kZT4gaWYgPGNvZGU+dG9mZnNldDwvY29kZT4gaXMKLSAgICogICAgICAgICAgbmVnYXRpdmUgb3IgZ3JlYXRlciB0aGFuIHRoZSBsZW5ndGggb2YgdGhpcwotICAgKiAgICAgICAgICA8Y29kZT5TdHJpbmc8L2NvZGU+IG9iamVjdDsgb3RoZXJ3aXNlIHRoZSByZXN1bHQgaXMgdGhlIHNhbWUKLSAgICogICAgICAgICAgYXMgdGhlIHJlc3VsdCBvZiB0aGUgZXhwcmVzc2lvbgotICAgKiAgICAgICAgICA8cHJlPgotICAgKiAgICAgICAgICB0aGlzLnN1YlN0cmluZyh0b2Zmc2V0KS5zdGFydHNXaXRoKHByZWZpeCkKLSAgICogICAgICAgICAgPC9wcmU+Ci0gICAqIEBleGNlcHRpb24gamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uIGlmIDxjb2RlPnByZWZpeDwvY29kZT4gaXMKLSAgICogICAgICAgICAgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBzdGFydHNXaXRoKFN0cmluZyBwcmVmaXgsIGludCB0b2Zmc2V0KTsKLQotICAvKioKLSAgICogVGVzdHMgaWYgdGhpcyBzdHJpbmcgc3RhcnRzIHdpdGggdGhlIHNwZWNpZmllZCBwcmVmaXggYmVnaW5uaW5nCi0gICAqIGEgc3BlY2lmaWVkIGluZGV4LgotICAgKgotICAgKiBAcGFyYW0gICBwcmVmaXggICAgdGhlIHByZWZpeC4KLSAgICogQHBhcmFtICAgdG9mZnNldCAgIHdoZXJlIHRvIGJlZ2luIGxvb2tpbmcgaW4gdGhlIHN0cmluZy4KLSAgICogQHJldHVybiAgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIGNoYXJhY3RlciBzZXF1ZW5jZSByZXByZXNlbnRlZCBieSB0aGUKLSAgICogICAgICAgICAgYXJndW1lbnQgaXMgYSBwcmVmaXggb2YgdGhlIHN1YnN0cmluZyBvZiB0aGlzIG9iamVjdCBzdGFydGluZwotICAgKiAgICAgICAgICBhdCBpbmRleCA8Y29kZT50b2Zmc2V0PC9jb2RlPjsgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4KLSAgICogICAgICAgICAgVGhlIHJlc3VsdCBpcyA8Y29kZT5mYWxzZTwvY29kZT4gaWYgPGNvZGU+dG9mZnNldDwvY29kZT4gaXMKLSAgICogICAgICAgICAgbmVnYXRpdmUgb3IgZ3JlYXRlciB0aGFuIHRoZSBsZW5ndGggb2YgdGhpcwotICAgKiAgICAgICAgICA8Y29kZT5TdHJpbmc8L2NvZGU+IG9iamVjdDsgb3RoZXJ3aXNlIHRoZSByZXN1bHQgaXMgdGhlIHNhbWUKLSAgICogICAgICAgICAgYXMgdGhlIHJlc3VsdCBvZiB0aGUgZXhwcmVzc2lvbgotICAgKiAgICAgICAgICA8cHJlPgotICAgKiAgICAgICAgICB0aGlzLnN1YlN0cmluZyh0b2Zmc2V0KS5zdGFydHNXaXRoKHByZWZpeCkKLSAgICogICAgICAgICAgPC9wcmU+Ci0gICAqIEBleGNlcHRpb24gamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uIGlmIDxjb2RlPnByZWZpeDwvY29kZT4gaXMKLSAgICogICAgICAgICAgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBzdGFydHNXaXRoKFhNTFN0cmluZyBwcmVmaXgsIGludCB0b2Zmc2V0KTsKLQotICAvKioKLSAgICogVGVzdHMgaWYgdGhpcyBzdHJpbmcgc3RhcnRzIHdpdGggdGhlIHNwZWNpZmllZCBwcmVmaXguCi0gICAqCi0gICAqIEBwYXJhbSAgIHByZWZpeCAgIHRoZSBwcmVmaXguCi0gICAqIEByZXR1cm4gIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBjaGFyYWN0ZXIgc2VxdWVuY2UgcmVwcmVzZW50ZWQgYnkgdGhlCi0gICAqICAgICAgICAgIGFyZ3VtZW50IGlzIGEgcHJlZml4IG9mIHRoZSBjaGFyYWN0ZXIgc2VxdWVuY2UgcmVwcmVzZW50ZWQgYnkKLSAgICogICAgICAgICAgdGhpcyBzdHJpbmc7IDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuCi0gICAqICAgICAgICAgIE5vdGUgYWxzbyB0aGF0IDxjb2RlPnRydWU8L2NvZGU+IHdpbGwgYmUgcmV0dXJuZWQgaWYgdGhlCi0gICAqICAgICAgICAgIGFyZ3VtZW50IGlzIGFuIGVtcHR5IHN0cmluZyBvciBpcyBlcXVhbCB0byB0aGlzCi0gICAqICAgICAgICAgIDxjb2RlPlN0cmluZzwvY29kZT4gb2JqZWN0IGFzIGRldGVybWluZWQgYnkgdGhlCi0gICAqICAgICAgICAgIHtAbGluayAjZXF1YWxzKE9iamVjdCl9IG1ldGhvZC4KLSAgICogQGV4Y2VwdGlvbiBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgPGNvZGU+cHJlZml4PC9jb2RlPiBpcwotICAgKiAgICAgICAgICA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICogQHNpbmNlICAgSkRLMS4gMAotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gc3RhcnRzV2l0aChTdHJpbmcgcHJlZml4KTsKLQotICAvKioKLSAgICogVGVzdHMgaWYgdGhpcyBzdHJpbmcgc3RhcnRzIHdpdGggdGhlIHNwZWNpZmllZCBwcmVmaXguCi0gICAqCi0gICAqIEBwYXJhbSAgIHByZWZpeCAgIHRoZSBwcmVmaXguCi0gICAqIEByZXR1cm4gIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBjaGFyYWN0ZXIgc2VxdWVuY2UgcmVwcmVzZW50ZWQgYnkgdGhlCi0gICAqICAgICAgICAgIGFyZ3VtZW50IGlzIGEgcHJlZml4IG9mIHRoZSBjaGFyYWN0ZXIgc2VxdWVuY2UgcmVwcmVzZW50ZWQgYnkKLSAgICogICAgICAgICAgdGhpcyBzdHJpbmc7IDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuCi0gICAqICAgICAgICAgIE5vdGUgYWxzbyB0aGF0IDxjb2RlPnRydWU8L2NvZGU+IHdpbGwgYmUgcmV0dXJuZWQgaWYgdGhlCi0gICAqICAgICAgICAgIGFyZ3VtZW50IGlzIGFuIGVtcHR5IHN0cmluZyBvciBpcyBlcXVhbCB0byB0aGlzCi0gICAqICAgICAgICAgIDxjb2RlPlN0cmluZzwvY29kZT4gb2JqZWN0IGFzIGRldGVybWluZWQgYnkgdGhlCi0gICAqICAgICAgICAgIHtAbGluayAjZXF1YWxzKE9iamVjdCl9IG1ldGhvZC4KLSAgICogQGV4Y2VwdGlvbiBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgPGNvZGU+cHJlZml4PC9jb2RlPiBpcwotICAgKiAgICAgICAgICA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICogQHNpbmNlICAgSkRLMS4gMAotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gc3RhcnRzV2l0aChYTUxTdHJpbmcgcHJlZml4KTsKLQotICAvKioKLSAgICogVGVzdHMgaWYgdGhpcyBzdHJpbmcgZW5kcyB3aXRoIHRoZSBzcGVjaWZpZWQgc3VmZml4LgotICAgKgotICAgKiBAcGFyYW0gICBzdWZmaXggICB0aGUgc3VmZml4LgotICAgKiBAcmV0dXJuICA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgY2hhcmFjdGVyIHNlcXVlbmNlIHJlcHJlc2VudGVkIGJ5IHRoZQotICAgKiAgICAgICAgICBhcmd1bWVudCBpcyBhIHN1ZmZpeCBvZiB0aGUgY2hhcmFjdGVyIHNlcXVlbmNlIHJlcHJlc2VudGVkIGJ5Ci0gICAqICAgICAgICAgIHRoaXMgb2JqZWN0OyA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLiBOb3RlIHRoYXQgdGhlCi0gICAqICAgICAgICAgIHJlc3VsdCB3aWxsIGJlIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBhcmd1bWVudCBpcyB0aGUKLSAgICogICAgICAgICAgZW1wdHkgc3RyaW5nIG9yIGlzIGVxdWFsIHRvIHRoaXMgPGNvZGU+U3RyaW5nPC9jb2RlPiBvYmplY3QKLSAgICogICAgICAgICAgYXMgZGV0ZXJtaW5lZCBieSB0aGUge0BsaW5rICNlcXVhbHMoT2JqZWN0KX0gbWV0aG9kLgotICAgKiBAZXhjZXB0aW9uIGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiA8Y29kZT5zdWZmaXg8L2NvZGU+IGlzCi0gICAqICAgICAgICAgIDxjb2RlPm51bGw8L2NvZGU+LgotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gZW5kc1dpdGgoU3RyaW5nIHN1ZmZpeCk7Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgYSBoYXNoY29kZSBmb3IgdGhpcyBzdHJpbmcuIFRoZSBoYXNoY29kZSBmb3IgYQotICAgKiA8Y29kZT5TdHJpbmc8L2NvZGU+IG9iamVjdCBpcyBjb21wdXRlZCBhcwotICAgKiA8YmxvY2txdW90ZT48cHJlPgotICAgKiBzWzBdKjMxXihuLTEpICsgc1sxXSozMV4obi0yKSArIC4uLiArIHNbbi0xXQotICAgKiA8L3ByZT48L2Jsb2NrcXVvdGU+Ci0gICAqIHVzaW5nIDxjb2RlPmludDwvY29kZT4gYXJpdGhtZXRpYywgd2hlcmUgPGNvZGU+c1tpXTwvY29kZT4gaXMgdGhlCi0gICAqIDxpPmk8L2k+dGggY2hhcmFjdGVyIG9mIHRoZSBzdHJpbmcsIDxjb2RlPm48L2NvZGU+IGlzIHRoZSBsZW5ndGggb2YKLSAgICogdGhlIHN0cmluZywgYW5kIDxjb2RlPl48L2NvZGU+IGluZGljYXRlcyBleHBvbmVudGlhdGlvbi4KLSAgICogKFRoZSBoYXNoIHZhbHVlIG9mIHRoZSBlbXB0eSBzdHJpbmcgaXMgemVyby4pCi0gICAqCi0gICAqIEByZXR1cm4gIGEgaGFzaCBjb2RlIHZhbHVlIGZvciB0aGlzIG9iamVjdC4KLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBpbnQgaGFzaENvZGUoKTsKLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgaW5kZXggd2l0aGluIHRoaXMgc3RyaW5nIG9mIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZQotICAgKiBzcGVjaWZpZWQgY2hhcmFjdGVyLiBJZiBhIGNoYXJhY3RlciB3aXRoIHZhbHVlIDxjb2RlPmNoPC9jb2RlPiBvY2N1cnMKLSAgICogaW4gdGhlIGNoYXJhY3RlciBzZXF1ZW5jZSByZXByZXNlbnRlZCBieSB0aGlzIDxjb2RlPlN0cmluZzwvY29kZT4KLSAgICogb2JqZWN0LCB0aGVuIHRoZSBpbmRleCBvZiB0aGUgZmlyc3Qgc3VjaCBvY2N1cnJlbmNlIGlzIHJldHVybmVkIC0tCi0gICAqIHRoYXQgaXMsIHRoZSBzbWFsbGVzdCB2YWx1ZSA8aT5rPC9pPiBzdWNoIHRoYXQ6Ci0gICAqIDxibG9ja3F1b3RlPjxwcmU+Ci0gICAqIHRoaXMuY2hhckF0KDxpPms8L2k+KSA9PSBjaAotICAgKiA8L3ByZT48L2Jsb2NrcXVvdGU+Ci0gICAqIGlzIDxjb2RlPnRydWU8L2NvZGU+LiBJZiBubyBzdWNoIGNoYXJhY3RlciBvY2N1cnMgaW4gdGhpcyBzdHJpbmcsCi0gICAqIHRoZW4gPGNvZGU+LTE8L2NvZGU+IGlzIHJldHVybmVkLgotICAgKgotICAgKiBAcGFyYW0gICBjaCAgIGEgY2hhcmFjdGVyLgotICAgKiBAcmV0dXJuICB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgdGhlIGNoYXJhY3RlciBpbiB0aGUKLSAgICogICAgICAgICAgY2hhcmFjdGVyIHNlcXVlbmNlIHJlcHJlc2VudGVkIGJ5IHRoaXMgb2JqZWN0LCBvcgotICAgKiAgICAgICAgICA8Y29kZT4tMTwvY29kZT4gaWYgdGhlIGNoYXJhY3RlciBkb2VzIG5vdCBvY2N1ci4KLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBpbnQgaW5kZXhPZihpbnQgY2gpOwotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBpbmRleCB3aXRoaW4gdGhpcyBzdHJpbmcgb2YgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgdGhlCi0gICAqIHNwZWNpZmllZCBjaGFyYWN0ZXIsIHN0YXJ0aW5nIHRoZSBzZWFyY2ggYXQgdGhlIHNwZWNpZmllZCBpbmRleC4KLSAgICogPHA+Ci0gICAqIElmIGEgY2hhcmFjdGVyIHdpdGggdmFsdWUgPGNvZGU+Y2g8L2NvZGU+IG9jY3VycyBpbiB0aGUgY2hhcmFjdGVyCi0gICAqIHNlcXVlbmNlIHJlcHJlc2VudGVkIGJ5IHRoaXMgPGNvZGU+U3RyaW5nPC9jb2RlPiBvYmplY3QgYXQgYW4gaW5kZXgKLSAgICogbm8gc21hbGxlciB0aGFuIDxjb2RlPmZyb21JbmRleDwvY29kZT4sIHRoZW4gdGhlIGluZGV4IG9mIHRoZSBmaXJzdAotICAgKiBzdWNoIG9jY3VycmVuY2UgaXMgcmV0dXJuZWQtLXRoYXQgaXMsIHRoZSBzbWFsbGVzdCB2YWx1ZSA8aT5rPC9pPgotICAgKiBzdWNoIHRoYXQ6Ci0gICAqIDxibG9ja3F1b3RlPjxwcmU+Ci0gICAqICh0aGlzLmNoYXJBdCg8aT5rPC9pPikgPT0gY2gpICYmICg8aT5rPC9pPiA+PSBmcm9tSW5kZXgpCi0gICAqIDwvcHJlPjwvYmxvY2txdW90ZT4KLSAgICogaXMgdHJ1ZS4gSWYgbm8gc3VjaCBjaGFyYWN0ZXIgb2NjdXJzIGluIHRoaXMgc3RyaW5nIGF0IG9yIGFmdGVyCi0gICAqIHBvc2l0aW9uIDxjb2RlPmZyb21JbmRleDwvY29kZT4sIHRoZW4gPGNvZGU+LTE8L2NvZGU+IGlzIHJldHVybmVkLgotICAgKiA8cD4KLSAgICogVGhlcmUgaXMgbm8gcmVzdHJpY3Rpb24gb24gdGhlIHZhbHVlIG9mIDxjb2RlPmZyb21JbmRleDwvY29kZT4uIElmIGl0Ci0gICAqIGlzIG5lZ2F0aXZlLCBpdCBoYXMgdGhlIHNhbWUgZWZmZWN0IGFzIGlmIGl0IHdlcmUgemVybzogdGhpcyBlbnRpcmUKLSAgICogc3RyaW5nIG1heSBiZSBzZWFyY2hlZC4gSWYgaXQgaXMgZ3JlYXRlciB0aGFuIHRoZSBsZW5ndGggb2YgdGhpcwotICAgKiBzdHJpbmcsIGl0IGhhcyB0aGUgc2FtZSBlZmZlY3QgYXMgaWYgaXQgd2VyZSBlcXVhbCB0byB0aGUgbGVuZ3RoIG9mCi0gICAqIHRoaXMgc3RyaW5nOiA8Y29kZT4tMTwvY29kZT4gaXMgcmV0dXJuZWQuCi0gICAqCi0gICAqIEBwYXJhbSAgIGNoICAgICAgICAgIGEgY2hhcmFjdGVyLgotICAgKiBAcGFyYW0gICBmcm9tSW5kZXggICB0aGUgaW5kZXggdG8gc3RhcnQgdGhlIHNlYXJjaCBmcm9tLgotICAgKiBAcmV0dXJuICB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgdGhlIGNoYXJhY3RlciBpbiB0aGUKLSAgICogICAgICAgICAgY2hhcmFjdGVyIHNlcXVlbmNlIHJlcHJlc2VudGVkIGJ5IHRoaXMgb2JqZWN0IHRoYXQgaXMgZ3JlYXRlcgotICAgKiAgICAgICAgICB0aGFuIG9yIGVxdWFsIHRvIDxjb2RlPmZyb21JbmRleDwvY29kZT4sIG9yIDxjb2RlPi0xPC9jb2RlPgotICAgKiAgICAgICAgICBpZiB0aGUgY2hhcmFjdGVyIGRvZXMgbm90IG9jY3VyLgotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IGludCBpbmRleE9mKGludCBjaCwgaW50IGZyb21JbmRleCk7Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIGluZGV4IHdpdGhpbiB0aGlzIHN0cmluZyBvZiB0aGUgbGFzdCBvY2N1cnJlbmNlIG9mIHRoZQotICAgKiBzcGVjaWZpZWQgY2hhcmFjdGVyLiBUaGF0IGlzLCB0aGUgaW5kZXggcmV0dXJuZWQgaXMgdGhlIGxhcmdlc3QKLSAgICogdmFsdWUgPGk+azwvaT4gc3VjaCB0aGF0OgotICAgKiA8YmxvY2txdW90ZT48cHJlPgotICAgKiB0aGlzLmNoYXJBdCg8aT5rPC9pPikgPT0gY2gKLSAgICogPC9wcmU+PC9ibG9ja3F1b3RlPgotICAgKiBpcyB0cnVlLgotICAgKiBUaGUgU3RyaW5nIGlzIHNlYXJjaGVkIGJhY2t3YXJkcyBzdGFydGluZyBhdCB0aGUgbGFzdCBjaGFyYWN0ZXIuCi0gICAqCi0gICAqIEBwYXJhbSAgIGNoICAgYSBjaGFyYWN0ZXIuCi0gICAqIEByZXR1cm4gIHRoZSBpbmRleCBvZiB0aGUgbGFzdCBvY2N1cnJlbmNlIG9mIHRoZSBjaGFyYWN0ZXIgaW4gdGhlCi0gICAqICAgICAgICAgIGNoYXJhY3RlciBzZXF1ZW5jZSByZXByZXNlbnRlZCBieSB0aGlzIG9iamVjdCwgb3IKLSAgICogICAgICAgICAgPGNvZGU+LTE8L2NvZGU+IGlmIHRoZSBjaGFyYWN0ZXIgZG9lcyBub3Qgb2NjdXIuCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgaW50IGxhc3RJbmRleE9mKGludCBjaCk7Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIGluZGV4IHdpdGhpbiB0aGlzIHN0cmluZyBvZiB0aGUgbGFzdCBvY2N1cnJlbmNlIG9mIHRoZQotICAgKiBzcGVjaWZpZWQgY2hhcmFjdGVyLCBzZWFyY2hpbmcgYmFja3dhcmQgc3RhcnRpbmcgYXQgdGhlIHNwZWNpZmllZAotICAgKiBpbmRleC4gVGhhdCBpcywgdGhlIGluZGV4IHJldHVybmVkIGlzIHRoZSBsYXJnZXN0IHZhbHVlIDxpPms8L2k+Ci0gICAqIHN1Y2ggdGhhdDoKLSAgICogPGJsb2NrcXVvdGU+PHByZT4KLSAgICogdGhpcy5jaGFyQXQoaykgPT0gY2gpICYmIChrIDw9IGZyb21JbmRleCkKLSAgICogPC9wcmU+PC9ibG9ja3F1b3RlPgotICAgKiBpcyB0cnVlLgotICAgKgotICAgKiBAcGFyYW0gICBjaCAgICAgICAgICBhIGNoYXJhY3Rlci4KLSAgICogQHBhcmFtICAgZnJvbUluZGV4ICAgdGhlIGluZGV4IHRvIHN0YXJ0IHRoZSBzZWFyY2ggZnJvbS4gVGhlcmUgaXMgbm8KLSAgICogICAgICAgICAgcmVzdHJpY3Rpb24gb24gdGhlIHZhbHVlIG9mIDxjb2RlPmZyb21JbmRleDwvY29kZT4uIElmIGl0IGlzCi0gICAqICAgICAgICAgIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byB0aGUgbGVuZ3RoIG9mIHRoaXMgc3RyaW5nLCBpdCBoYXMKLSAgICogICAgICAgICAgdGhlIHNhbWUgZWZmZWN0IGFzIGlmIGl0IHdlcmUgZXF1YWwgdG8gb25lIGxlc3MgdGhhbiB0aGUKLSAgICogICAgICAgICAgbGVuZ3RoIG9mIHRoaXMgc3RyaW5nOiB0aGlzIGVudGlyZSBzdHJpbmcgbWF5IGJlIHNlYXJjaGVkLgotICAgKiAgICAgICAgICBJZiBpdCBpcyBuZWdhdGl2ZSwgaXQgaGFzIHRoZSBzYW1lIGVmZmVjdCBhcyBpZiBpdCB3ZXJlIC0xOgotICAgKiAgICAgICAgICAtMSBpcyByZXR1cm5lZC4KLSAgICogQHJldHVybiAgdGhlIGluZGV4IG9mIHRoZSBsYXN0IG9jY3VycmVuY2Ugb2YgdGhlIGNoYXJhY3RlciBpbiB0aGUKLSAgICogICAgICAgICAgY2hhcmFjdGVyIHNlcXVlbmNlIHJlcHJlc2VudGVkIGJ5IHRoaXMgb2JqZWN0IHRoYXQgaXMgbGVzcwotICAgKiAgICAgICAgICB0aGFuIG9yIGVxdWFsIHRvIDxjb2RlPmZyb21JbmRleDwvY29kZT4sIG9yIDxjb2RlPi0xPC9jb2RlPgotICAgKiAgICAgICAgICBpZiB0aGUgY2hhcmFjdGVyIGRvZXMgbm90IG9jY3VyIGJlZm9yZSB0aGF0IHBvaW50LgotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IGludCBsYXN0SW5kZXhPZihpbnQgY2gsIGludCBmcm9tSW5kZXgpOwotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBpbmRleCB3aXRoaW4gdGhpcyBzdHJpbmcgb2YgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgdGhlCi0gICAqIHNwZWNpZmllZCBzdWJzdHJpbmcuIFRoZSBpbnRlZ2VyIHJldHVybmVkIGlzIHRoZSBzbWFsbGVzdCB2YWx1ZQotICAgKiA8aT5rPC9pPiBzdWNoIHRoYXQ6Ci0gICAqIDxibG9ja3F1b3RlPjxwcmU+Ci0gICAqIHRoaXMuc3RhcnRzV2l0aChzdHIsIDxpPms8L2k+KQotICAgKiA8L3ByZT48L2Jsb2NrcXVvdGU+Ci0gICAqIGlzIDxjb2RlPnRydWU8L2NvZGU+LgotICAgKgotICAgKiBAcGFyYW0gICBzdHIgICBhbnkgc3RyaW5nLgotICAgKiBAcmV0dXJuICBpZiB0aGUgc3RyaW5nIGFyZ3VtZW50IG9jY3VycyBhcyBhIHN1YnN0cmluZyB3aXRoaW4gdGhpcwotICAgKiAgICAgICAgICBvYmplY3QsIHRoZW4gdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBjaGFyYWN0ZXIgb2YgdGhlIGZpcnN0Ci0gICAqICAgICAgICAgIHN1Y2ggc3Vic3RyaW5nIGlzIHJldHVybmVkOyBpZiBpdCBkb2VzIG5vdCBvY2N1ciBhcyBhCi0gICAqICAgICAgICAgIHN1YnN0cmluZywgPGNvZGU+LTE8L2NvZGU+IGlzIHJldHVybmVkLgotICAgKiBAZXhjZXB0aW9uIGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiA8Y29kZT5zdHI8L2NvZGU+IGlzCi0gICAqICAgICAgICAgIDxjb2RlPm51bGw8L2NvZGU+LgotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IGludCBpbmRleE9mKFN0cmluZyBzdHIpOwotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBpbmRleCB3aXRoaW4gdGhpcyBzdHJpbmcgb2YgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgdGhlCi0gICAqIHNwZWNpZmllZCBzdWJzdHJpbmcuIFRoZSBpbnRlZ2VyIHJldHVybmVkIGlzIHRoZSBzbWFsbGVzdCB2YWx1ZQotICAgKiA8aT5rPC9pPiBzdWNoIHRoYXQ6Ci0gICAqIDxibG9ja3F1b3RlPjxwcmU+Ci0gICAqIHRoaXMuc3RhcnRzV2l0aChzdHIsIDxpPms8L2k+KQotICAgKiA8L3ByZT48L2Jsb2NrcXVvdGU+Ci0gICAqIGlzIDxjb2RlPnRydWU8L2NvZGU+LgotICAgKgotICAgKiBAcGFyYW0gICBzdHIgICBhbnkgc3RyaW5nLgotICAgKiBAcmV0dXJuICBpZiB0aGUgc3RyaW5nIGFyZ3VtZW50IG9jY3VycyBhcyBhIHN1YnN0cmluZyB3aXRoaW4gdGhpcwotICAgKiAgICAgICAgICBvYmplY3QsIHRoZW4gdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBjaGFyYWN0ZXIgb2YgdGhlIGZpcnN0Ci0gICAqICAgICAgICAgIHN1Y2ggc3Vic3RyaW5nIGlzIHJldHVybmVkOyBpZiBpdCBkb2VzIG5vdCBvY2N1ciBhcyBhCi0gICAqICAgICAgICAgIHN1YnN0cmluZywgPGNvZGU+LTE8L2NvZGU+IGlzIHJldHVybmVkLgotICAgKiBAZXhjZXB0aW9uIGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiA8Y29kZT5zdHI8L2NvZGU+IGlzCi0gICAqICAgICAgICAgIDxjb2RlPm51bGw8L2NvZGU+LgotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IGludCBpbmRleE9mKFhNTFN0cmluZyBzdHIpOwotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBpbmRleCB3aXRoaW4gdGhpcyBzdHJpbmcgb2YgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgdGhlCi0gICAqIHNwZWNpZmllZCBzdWJzdHJpbmcsIHN0YXJ0aW5nIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXguIFRoZSBpbnRlZ2VyCi0gICAqIHJldHVybmVkIGlzIHRoZSBzbWFsbGVzdCB2YWx1ZSA8aT5rPC9pPiBzdWNoIHRoYXQ6Ci0gICAqIDxibG9ja3F1b3RlPjxwcmU+Ci0gICAqIHRoaXMuc3RhcnRzV2l0aChzdHIsIDxpPms8L2k+KSAmJiAoPGk+azwvaT4gPj0gZnJvbUluZGV4KQotICAgKiA8L3ByZT48L2Jsb2NrcXVvdGU+Ci0gICAqIGlzIDxjb2RlPnRydWU8L2NvZGU+LgotICAgKiA8cD4KLSAgICogVGhlcmUgaXMgbm8gcmVzdHJpY3Rpb24gb24gdGhlIHZhbHVlIG9mIDxjb2RlPmZyb21JbmRleDwvY29kZT4uIElmCi0gICAqIGl0IGlzIG5lZ2F0aXZlLCBpdCBoYXMgdGhlIHNhbWUgZWZmZWN0IGFzIGlmIGl0IHdlcmUgemVybzogdGhpcyBlbnRpcmUKLSAgICogc3RyaW5nIG1heSBiZSBzZWFyY2hlZC4gSWYgaXQgaXMgZ3JlYXRlciB0aGFuIHRoZSBsZW5ndGggb2YgdGhpcwotICAgKiBzdHJpbmcsIGl0IGhhcyB0aGUgc2FtZSBlZmZlY3QgYXMgaWYgaXQgd2VyZSBlcXVhbCB0byB0aGUgbGVuZ3RoIG9mCi0gICAqIHRoaXMgc3RyaW5nOiA8Y29kZT4tMTwvY29kZT4gaXMgcmV0dXJuZWQuCi0gICAqCi0gICAqIEBwYXJhbSAgIHN0ciAgICAgICAgIHRoZSBzdWJzdHJpbmcgdG8gc2VhcmNoIGZvci4KLSAgICogQHBhcmFtICAgZnJvbUluZGV4ICAgdGhlIGluZGV4IHRvIHN0YXJ0IHRoZSBzZWFyY2ggZnJvbS4KLSAgICogQHJldHVybiAgSWYgdGhlIHN0cmluZyBhcmd1bWVudCBvY2N1cnMgYXMgYSBzdWJzdHJpbmcgd2l0aGluIHRoaXMKLSAgICogICAgICAgICAgb2JqZWN0IGF0IGEgc3RhcnRpbmcgaW5kZXggbm8gc21hbGxlciB0aGFuCi0gICAqICAgICAgICAgIDxjb2RlPmZyb21JbmRleDwvY29kZT4sIHRoZW4gdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBjaGFyYWN0ZXIKLSAgICogICAgICAgICAgb2YgdGhlIGZpcnN0IHN1Y2ggc3Vic3RyaW5nIGlzIHJldHVybmVkLiBJZiBpdCBkb2VzIG5vdCBvY2N1cgotICAgKiAgICAgICAgICBhcyBhIHN1YnN0cmluZyBzdGFydGluZyBhdCA8Y29kZT5mcm9tSW5kZXg8L2NvZGU+IG9yIGJleW9uZCwKLSAgICogICAgICAgICAgPGNvZGU+LTE8L2NvZGU+IGlzIHJldHVybmVkLgotICAgKiBAZXhjZXB0aW9uIGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiA8Y29kZT5zdHI8L2NvZGU+IGlzCi0gICAqICAgICAgICAgIDxjb2RlPm51bGw8L2NvZGU+Ci0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgaW50IGluZGV4T2YoU3RyaW5nIHN0ciwgaW50IGZyb21JbmRleCk7Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIGluZGV4IHdpdGhpbiB0aGlzIHN0cmluZyBvZiB0aGUgcmlnaHRtb3N0IG9jY3VycmVuY2UKLSAgICogb2YgdGhlIHNwZWNpZmllZCBzdWJzdHJpbmcuICBUaGUgcmlnaHRtb3N0IGVtcHR5IHN0cmluZyAiIiBpcwotICAgKiBjb25zaWRlcmVkIHRvIG9jY3VyIGF0IHRoZSBpbmRleCB2YWx1ZSA8Y29kZT50aGlzLmxlbmd0aCgpPC9jb2RlPi4KLSAgICogVGhlIHJldHVybmVkIGluZGV4IGlzIHRoZSBsYXJnZXN0IHZhbHVlIDxpPms8L2k+IHN1Y2ggdGhhdAotICAgKiA8YmxvY2txdW90ZT48cHJlPgotICAgKiB0aGlzLnN0YXJ0c1dpdGgoc3RyLCBrKQotICAgKiA8L3ByZT48L2Jsb2NrcXVvdGU+Ci0gICAqIGlzIHRydWUuCi0gICAqCi0gICAqIEBwYXJhbSAgIHN0ciAgIHRoZSBzdWJzdHJpbmcgdG8gc2VhcmNoIGZvci4KLSAgICogQHJldHVybiAgaWYgdGhlIHN0cmluZyBhcmd1bWVudCBvY2N1cnMgb25lIG9yIG1vcmUgdGltZXMgYXMgYSBzdWJzdHJpbmcKLSAgICogICAgICAgICAgd2l0aGluIHRoaXMgb2JqZWN0LCB0aGVuIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgY2hhcmFjdGVyIG9mCi0gICAqICAgICAgICAgIHRoZSBsYXN0IHN1Y2ggc3Vic3RyaW5nIGlzIHJldHVybmVkLiBJZiBpdCBkb2VzIG5vdCBvY2N1ciBhcwotICAgKiAgICAgICAgICBhIHN1YnN0cmluZywgPGNvZGU+LTE8L2NvZGU+IGlzIHJldHVybmVkLgotICAgKiBAZXhjZXB0aW9uIGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbiAgaWYgPGNvZGU+c3RyPC9jb2RlPiBpcwotICAgKiAgICAgICAgICA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBpbnQgbGFzdEluZGV4T2YoU3RyaW5nIHN0cik7Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIGluZGV4IHdpdGhpbiB0aGlzIHN0cmluZyBvZiB0aGUgbGFzdCBvY2N1cnJlbmNlIG9mCi0gICAqIHRoZSBzcGVjaWZpZWQgc3Vic3RyaW5nLgotICAgKgotICAgKiBAcGFyYW0gICBzdHIgICAgICAgICB0aGUgc3Vic3RyaW5nIHRvIHNlYXJjaCBmb3IuCi0gICAqIEBwYXJhbSAgIGZyb21JbmRleCAgIHRoZSBpbmRleCB0byBzdGFydCB0aGUgc2VhcmNoIGZyb20uIFRoZXJlIGlzIG5vCi0gICAqICAgICAgICAgIHJlc3RyaWN0aW9uIG9uIHRoZSB2YWx1ZSBvZiBmcm9tSW5kZXguIElmIGl0IGlzIGdyZWF0ZXIgdGhhbgotICAgKiAgICAgICAgICB0aGUgbGVuZ3RoIG9mIHRoaXMgc3RyaW5nLCBpdCBoYXMgdGhlIHNhbWUgZWZmZWN0IGFzIGlmIGl0Ci0gICAqICAgICAgICAgIHdlcmUgZXF1YWwgdG8gdGhlIGxlbmd0aCBvZiB0aGlzIHN0cmluZzogdGhpcyBlbnRpcmUgc3RyaW5nCi0gICAqICAgICAgICAgIG1heSBiZSBzZWFyY2hlZC4gSWYgaXQgaXMgbmVnYXRpdmUsIGl0IGhhcyB0aGUgc2FtZSBlZmZlY3QKLSAgICogICAgICAgICAgYXMgaWYgaXQgd2VyZSAtMTogLTEgaXMgcmV0dXJuZWQuCi0gICAqIEByZXR1cm4gIElmIHRoZSBzdHJpbmcgYXJndW1lbnQgb2NjdXJzIG9uZSBvciBtb3JlIHRpbWVzIGFzIGEgc3Vic3RyaW5nCi0gICAqICAgICAgICAgIHdpdGhpbiB0aGlzIG9iamVjdCBhdCBhIHN0YXJ0aW5nIGluZGV4IG5vIGdyZWF0ZXIgdGhhbgotICAgKiAgICAgICAgICA8Y29kZT5mcm9tSW5kZXg8L2NvZGU+LCB0aGVuIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgY2hhcmFjdGVyIG9mCi0gICAqICAgICAgICAgIHRoZSBsYXN0IHN1Y2ggc3Vic3RyaW5nIGlzIHJldHVybmVkLiBJZiBpdCBkb2VzIG5vdCBvY2N1ciBhcyBhCi0gICAqICAgICAgICAgIHN1YnN0cmluZyBzdGFydGluZyBhdCA8Y29kZT5mcm9tSW5kZXg8L2NvZGU+IG9yIGVhcmxpZXIsCi0gICAqICAgICAgICAgIDxjb2RlPi0xPC9jb2RlPiBpcyByZXR1cm5lZC4KLSAgICogQGV4Y2VwdGlvbiBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgPGNvZGU+c3RyPC9jb2RlPiBpcwotICAgKiAgICAgICAgICA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBpbnQgbGFzdEluZGV4T2YoU3RyaW5nIHN0ciwgaW50IGZyb21JbmRleCk7Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgYSBuZXcgc3RyaW5nIHRoYXQgaXMgYSBzdWJzdHJpbmcgb2YgdGhpcyBzdHJpbmcuIFRoZQotICAgKiBzdWJzdHJpbmcgYmVnaW5zIHdpdGggdGhlIGNoYXJhY3RlciBhdCB0aGUgc3BlY2lmaWVkIGluZGV4IGFuZAotICAgKiBleHRlbmRzIHRvIHRoZSBlbmQgb2YgdGhpcyBzdHJpbmcuIDxwPgotICAgKiBFeGFtcGxlczoKLSAgICogPGJsb2NrcXVvdGU+PHByZT4KLSAgICogInVuaGFwcHkiLnN1YnN0cmluZygyKSByZXR1cm5zICJoYXBweSIKLSAgICogIkhhcmJpc29uIi5zdWJzdHJpbmcoMykgcmV0dXJucyAiYmlzb24iCi0gICAqICJlbXB0aW5lc3MiLnN1YnN0cmluZyg5KSByZXR1cm5zICIiIChhbiBlbXB0eSBzdHJpbmcpCi0gICAqIDwvcHJlPjwvYmxvY2txdW90ZT4KLSAgICoKLSAgICogQHBhcmFtICAgICAgYmVnaW5JbmRleCAgIHRoZSBiZWdpbm5pbmcgaW5kZXgsIGluY2x1c2l2ZS4KLSAgICogQHJldHVybiAgICAgdGhlIHNwZWNpZmllZCBzdWJzdHJpbmcuCi0gICAqIEBleGNlcHRpb24gIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gIGlmCi0gICAqICAgICAgICAgICAgIDxjb2RlPmJlZ2luSW5kZXg8L2NvZGU+IGlzIG5lZ2F0aXZlIG9yIGxhcmdlciB0aGFuIHRoZQotICAgKiAgICAgICAgICAgICBsZW5ndGggb2YgdGhpcyA8Y29kZT5TdHJpbmc8L2NvZGU+IG9iamVjdC4KLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBYTUxTdHJpbmcgc3Vic3RyaW5nKGludCBiZWdpbkluZGV4KTsKLQotICAvKioKLSAgICogUmV0dXJucyBhIG5ldyBzdHJpbmcgdGhhdCBpcyBhIHN1YnN0cmluZyBvZiB0aGlzIHN0cmluZy4gVGhlCi0gICAqIHN1YnN0cmluZyBiZWdpbnMgYXQgdGhlIHNwZWNpZmllZCA8Y29kZT5iZWdpbkluZGV4PC9jb2RlPiBhbmQKLSAgICogZXh0ZW5kcyB0byB0aGUgY2hhcmFjdGVyIGF0IGluZGV4IDxjb2RlPmVuZEluZGV4IC0gMTwvY29kZT4uCi0gICAqIFRodXMgdGhlIGxlbmd0aCBvZiB0aGUgc3Vic3RyaW5nIGlzIDxjb2RlPmVuZEluZGV4LWJlZ2luSW5kZXg8L2NvZGU+LgotICAgKgotICAgKiBAcGFyYW0gICAgICBiZWdpbkluZGV4ICAgdGhlIGJlZ2lubmluZyBpbmRleCwgaW5jbHVzaXZlLgotICAgKiBAcGFyYW0gICAgICBlbmRJbmRleCAgICAgdGhlIGVuZGluZyBpbmRleCwgZXhjbHVzaXZlLgotICAgKiBAcmV0dXJuICAgICB0aGUgc3BlY2lmaWVkIHN1YnN0cmluZy4KLSAgICogQGV4Y2VwdGlvbiAgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiAgaWYgdGhlCi0gICAqICAgICAgICAgICAgIDxjb2RlPmJlZ2luSW5kZXg8L2NvZGU+IGlzIG5lZ2F0aXZlLCBvcgotICAgKiAgICAgICAgICAgICA8Y29kZT5lbmRJbmRleDwvY29kZT4gaXMgbGFyZ2VyIHRoYW4gdGhlIGxlbmd0aCBvZgotICAgKiAgICAgICAgICAgICB0aGlzIDxjb2RlPlN0cmluZzwvY29kZT4gb2JqZWN0LCBvcgotICAgKiAgICAgICAgICAgICA8Y29kZT5iZWdpbkluZGV4PC9jb2RlPiBpcyBsYXJnZXIgdGhhbgotICAgKiAgICAgICAgICAgICA8Y29kZT5lbmRJbmRleDwvY29kZT4uCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgWE1MU3RyaW5nIHN1YnN0cmluZyhpbnQgYmVnaW5JbmRleCwgaW50IGVuZEluZGV4KTsKLQotICAvKioKLSAgICogQ29uY2F0ZW5hdGVzIHRoZSBzcGVjaWZpZWQgc3RyaW5nIHRvIHRoZSBlbmQgb2YgdGhpcyBzdHJpbmcuCi0gICAqCi0gICAqIEBwYXJhbSAgIHN0ciAgIHRoZSA8Y29kZT5TdHJpbmc8L2NvZGU+IHRoYXQgaXMgY29uY2F0ZW5hdGVkIHRvIHRoZSBlbmQKLSAgICogICAgICAgICAgICAgICAgb2YgdGhpcyA8Y29kZT5TdHJpbmc8L2NvZGU+LgotICAgKiBAcmV0dXJuICBhIHN0cmluZyB0aGF0IHJlcHJlc2VudHMgdGhlIGNvbmNhdGVuYXRpb24gb2YgdGhpcyBvYmplY3QncwotICAgKiAgICAgICAgICBjaGFyYWN0ZXJzIGZvbGxvd2VkIGJ5IHRoZSBzdHJpbmcgYXJndW1lbnQncyBjaGFyYWN0ZXJzLgotICAgKiBAZXhjZXB0aW9uIGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiA8Y29kZT5zdHI8L2NvZGU+IGlzCi0gICAqICAgICAgICAgIDxjb2RlPm51bGw8L2NvZGU+LgotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IFhNTFN0cmluZyBjb25jYXQoU3RyaW5nIHN0cik7Ci0KLSAgLyoqCi0gICAqIENvbnZlcnRzIGFsbCBvZiB0aGUgY2hhcmFjdGVycyBpbiB0aGlzIDxjb2RlPlN0cmluZzwvY29kZT4gdG8gbG93ZXIKLSAgICogY2FzZSB1c2luZyB0aGUgcnVsZXMgb2YgdGhlIGdpdmVuIDxjb2RlPkxvY2FsZTwvY29kZT4uCi0gICAqCi0gICAqIEBwYXJhbSBsb2NhbGUgdXNlIHRoZSBjYXNlIHRyYW5zZm9ybWF0aW9uIHJ1bGVzIGZvciB0aGlzIGxvY2FsZQotICAgKiBAcmV0dXJuIHRoZSBTdHJpbmcsIGNvbnZlcnRlZCB0byBsb3dlcmNhc2UuCi0gICAqIEBzZWUgICAgIGphdmEubGFuZy5DaGFyYWN0ZXIjdG9Mb3dlckNhc2UoY2hhcikKLSAgICogQHNlZSAgICAgamF2YS5sYW5nLlN0cmluZyN0b1VwcGVyQ2FzZShMb2NhbGUpCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgWE1MU3RyaW5nIHRvTG93ZXJDYXNlKExvY2FsZSBsb2NhbGUpOwotCi0gIC8qKgotICAgKiBDb252ZXJ0cyBhbGwgb2YgdGhlIGNoYXJhY3RlcnMgaW4gdGhpcyA8Y29kZT5TdHJpbmc8L2NvZGU+IHRvIGxvd2VyCi0gICAqIGNhc2UgdXNpbmcgdGhlIHJ1bGVzIG9mIHRoZSBkZWZhdWx0IGxvY2FsZSwgd2hpY2ggaXMgcmV0dXJuZWQKLSAgICogYnkgPGNvZGU+TG9jYWxlLmdldERlZmF1bHQ8L2NvZGU+LgotICAgKiA8cD4KLSAgICoKLSAgICogQHJldHVybiAgdGhlIHN0cmluZywgY29udmVydGVkIHRvIGxvd2VyY2FzZS4KLSAgICogQHNlZSAgICAgamF2YS5sYW5nLkNoYXJhY3RlciN0b0xvd2VyQ2FzZShjaGFyKQotICAgKiBAc2VlICAgICBqYXZhLmxhbmcuU3RyaW5nI3RvTG93ZXJDYXNlKExvY2FsZSkKLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBYTUxTdHJpbmcgdG9Mb3dlckNhc2UoKTsKLQotICAvKioKLSAgICogQ29udmVydHMgYWxsIG9mIHRoZSBjaGFyYWN0ZXJzIGluIHRoaXMgPGNvZGU+U3RyaW5nPC9jb2RlPiB0byB1cHBlcgotICAgKiBjYXNlIHVzaW5nIHRoZSBydWxlcyBvZiB0aGUgZ2l2ZW4gbG9jYWxlLgotICAgKiBAcGFyYW0gbG9jYWxlIHVzZSB0aGUgY2FzZSB0cmFuc2Zvcm1hdGlvbiBydWxlcyBmb3IgdGhpcyBsb2NhbGUKLSAgICogQHJldHVybiB0aGUgU3RyaW5nLCBjb252ZXJ0ZWQgdG8gdXBwZXJjYXNlLgotICAgKiBAc2VlICAgICBqYXZhLmxhbmcuQ2hhcmFjdGVyI3RvVXBwZXJDYXNlKGNoYXIpCi0gICAqIEBzZWUgICAgIGphdmEubGFuZy5TdHJpbmcjdG9Mb3dlckNhc2UoTG9jYWxlKQotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IFhNTFN0cmluZyB0b1VwcGVyQ2FzZShMb2NhbGUgbG9jYWxlKTsKLQotICAvKioKLSAgICogQ29udmVydHMgYWxsIG9mIHRoZSBjaGFyYWN0ZXJzIGluIHRoaXMgPGNvZGU+U3RyaW5nPC9jb2RlPiB0byB1cHBlcgotICAgKiBjYXNlIHVzaW5nIHRoZSBydWxlcyBvZiB0aGUgZGVmYXVsdCBsb2NhbGUsIHdoaWNoIGlzIHJldHVybmVkCi0gICAqIGJ5IDxjb2RlPkxvY2FsZS5nZXREZWZhdWx0PC9jb2RlPi4KLSAgICoKLSAgICogPHA+Ci0gICAqIElmIG5vIGNoYXJhY3RlciBpbiB0aGlzIHN0cmluZyBoYXMgYSBkaWZmZXJlbnQgdXBwZXJjYXNlIHZlcnNpb24sCi0gICAqIGJhc2VkIG9uIGNhbGxpbmcgdGhlIDxjb2RlPnRvVXBwZXJDYXNlPC9jb2RlPiBtZXRob2QgZGVmaW5lZCBieQotICAgKiA8Y29kZT5DaGFyYWN0ZXI8L2NvZGU+LCB0aGVuIHRoZSBvcmlnaW5hbCBzdHJpbmcgaXMgcmV0dXJuZWQuCi0gICAqIDxwPgotICAgKiBPdGhlcndpc2UsIHRoaXMgbWV0aG9kIGNyZWF0ZXMgYSBuZXcgPGNvZGU+U3RyaW5nPC9jb2RlPiBvYmplY3QKLSAgICogcmVwcmVzZW50aW5nIGEgY2hhcmFjdGVyIHNlcXVlbmNlIGlkZW50aWNhbCBpbiBsZW5ndGggdG8gdGhlCi0gICAqIGNoYXJhY3RlciBzZXF1ZW5jZSByZXByZXNlbnRlZCBieSB0aGlzIDxjb2RlPlN0cmluZzwvY29kZT4gb2JqZWN0IGFuZAotICAgKiB3aXRoIGV2ZXJ5IGNoYXJhY3RlciBlcXVhbCB0byB0aGUgcmVzdWx0IG9mIGFwcGx5aW5nIHRoZSBtZXRob2QKLSAgICogPGNvZGU+Q2hhcmFjdGVyLnRvVXBwZXJDYXNlPC9jb2RlPiB0byB0aGUgY29ycmVzcG9uZGluZyBjaGFyYWN0ZXIgb2YKLSAgICogdGhpcyA8Y29kZT5TdHJpbmc8L2NvZGU+IG9iamVjdC4gPHA+Ci0gICAqIEV4YW1wbGVzOgotICAgKiA8YmxvY2txdW90ZT48cHJlPgotICAgKiAiRmFocnZlcmduJnV1bWw7Z2VuIi50b1VwcGVyQ2FzZSgpIHJldHVybnMgIkZBSFJWRVJHTiZVdW1sO0dFTiIKLSAgICogIlZpc2l0IExqdWJpbmplISIudG9VcHBlckNhc2UoKSByZXR1cm5zICJWSVNJVCBMSlVCSU5KRSEiCi0gICAqIDwvcHJlPjwvYmxvY2txdW90ZT4KLSAgICoKLSAgICogQHJldHVybiAgdGhlIHN0cmluZywgY29udmVydGVkIHRvIHVwcGVyY2FzZS4KLSAgICogQHNlZSAgICAgamF2YS5sYW5nLkNoYXJhY3RlciN0b1VwcGVyQ2FzZShjaGFyKQotICAgKiBAc2VlICAgICBqYXZhLmxhbmcuU3RyaW5nI3RvVXBwZXJDYXNlKExvY2FsZSkKLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBYTUxTdHJpbmcgdG9VcHBlckNhc2UoKTsKLQotICAvKioKLSAgICogUmVtb3ZlcyB3aGl0ZSBzcGFjZSBmcm9tIGJvdGggZW5kcyBvZiB0aGlzIHN0cmluZy4KLSAgICogPHA+Ci0gICAqIElmIHRoaXMgPGNvZGU+U3RyaW5nPC9jb2RlPiBvYmplY3QgcmVwcmVzZW50cyBhbiBlbXB0eSBjaGFyYWN0ZXIKLSAgICogc2VxdWVuY2UsIG9yIHRoZSBmaXJzdCBhbmQgbGFzdCBjaGFyYWN0ZXJzIG9mIGNoYXJhY3RlciBzZXF1ZW5jZQotICAgKiByZXByZXNlbnRlZCBieSB0aGlzIDxjb2RlPlN0cmluZzwvY29kZT4gb2JqZWN0IGJvdGggaGF2ZSBjb2RlcwotICAgKiBncmVhdGVyIHRoYW4gPGNvZGU+JyYjOTI7dTAwMjAnPC9jb2RlPiAodGhlIHNwYWNlIGNoYXJhY3RlciksIHRoZW4gYQotICAgKiByZWZlcmVuY2UgdG8gdGhpcyA8Y29kZT5TdHJpbmc8L2NvZGU+IG9iamVjdCBpcyByZXR1cm5lZC4KLSAgICogPHA+Ci0gICAqIE90aGVyd2lzZSwgaWYgdGhlcmUgaXMgbm8gY2hhcmFjdGVyIHdpdGggYSBjb2RlIGdyZWF0ZXIgdGhhbgotICAgKiA8Y29kZT4nJiM5Mjt1MDAyMCc8L2NvZGU+IGluIHRoZSBzdHJpbmcsIHRoZW4gYSBuZXcKLSAgICogPGNvZGU+U3RyaW5nPC9jb2RlPiBvYmplY3QgcmVwcmVzZW50aW5nIGFuIGVtcHR5IHN0cmluZyBpcyBjcmVhdGVkCi0gICAqIGFuZCByZXR1cm5lZC4KLSAgICogPHA+Ci0gICAqIE90aGVyd2lzZSwgbGV0IDxpPms8L2k+IGJlIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgY2hhcmFjdGVyIGluIHRoZQotICAgKiBzdHJpbmcgd2hvc2UgY29kZSBpcyBncmVhdGVyIHRoYW4gPGNvZGU+JyYjOTI7dTAwMjAnPC9jb2RlPiwgYW5kIGxldAotICAgKiA8aT5tPC9pPiBiZSB0aGUgaW5kZXggb2YgdGhlIGxhc3QgY2hhcmFjdGVyIGluIHRoZSBzdHJpbmcgd2hvc2UgY29kZQotICAgKiBpcyBncmVhdGVyIHRoYW4gPGNvZGU+JyYjOTI7dTAwMjAnPC9jb2RlPi4gQSBuZXcgPGNvZGU+U3RyaW5nPC9jb2RlPgotICAgKiBvYmplY3QgaXMgY3JlYXRlZCwgcmVwcmVzZW50aW5nIHRoZSBzdWJzdHJpbmcgb2YgdGhpcyBzdHJpbmcgdGhhdAotICAgKiBiZWdpbnMgd2l0aCB0aGUgY2hhcmFjdGVyIGF0IGluZGV4IDxpPms8L2k+IGFuZCBlbmRzIHdpdGggdGhlCi0gICAqIGNoYXJhY3RlciBhdCBpbmRleCA8aT5tPC9pPi10aGF0IGlzLCB0aGUgcmVzdWx0IG9mCi0gICAqIDxjb2RlPnRoaXMuc3Vic3RyaW5nKDxpPms8L2k+LCZuYnNwOzxpPm08L2k+KzEpPC9jb2RlPi4KLSAgICogPHA+Ci0gICAqIFRoaXMgbWV0aG9kIG1heSBiZSB1c2VkIHRvIHRyaW0KLSAgICoge0BsaW5rIENoYXJhY3RlciNpc1NwYWNlKGNoYXIpIHdoaXRlc3BhY2V9IGZyb20gdGhlIGJlZ2lubmluZyBhbmQgZW5kCi0gICAqIG9mIGEgc3RyaW5nOyBpbiBmYWN0LCBpdCB0cmltcyBhbGwgQVNDSUkgY29udHJvbCBjaGFyYWN0ZXJzIGFzIHdlbGwuCi0gICAqCi0gICAqIEByZXR1cm4gIHRoaXMgc3RyaW5nLCB3aXRoIHdoaXRlIHNwYWNlIHJlbW92ZWQgZnJvbSB0aGUgZnJvbnQgYW5kIGVuZC4KLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBYTUxTdHJpbmcgdHJpbSgpOwotCi0gIC8qKgotICAgKiBUaGlzIG9iamVjdCAod2hpY2ggaXMgYWxyZWFkeSBhIHN0cmluZyEpIGlzIGl0c2VsZiByZXR1cm5lZC4KLSAgICoKLSAgICogQHJldHVybiAgdGhlIHN0cmluZyBpdHNlbGYuCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nIHRvU3RyaW5nKCk7Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgdGhpcyBvYmplY3QgY29udGFpbnMgYSBqYXZhIFN0cmluZyBvYmplY3QuCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGlzIFhNTFN0cmluZyBjYW4gcmV0dXJuIGEgc3RyaW5nIHdpdGhvdXQgY3JlYXRpbmcgb25lLgotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gaGFzU3RyaW5nKCk7Ci0KLSAgLyoqCi0gICAqIENvbnZlcnQgYSBzdHJpbmcgdG8gYSBkb3VibGUgLS0gQWxsb3dlZCBpbnB1dCBpcyBpbiBmaXhlZAotICAgKiBub3RhdGlvbiBkZGQuZmZmLgotICAgKgotICAgKiBAcmV0dXJuIEEgZG91YmxlIHZhbHVlIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBzdHJpbmcsIG9yIHJldHVybiBEb3VibGUuTmFOCi0gICAqIGlmIHRoZSBzdHJpbmcgY2FuIG5vdCBiZSBjb252ZXJ0ZWQuCi0gICAqLwotICBwdWJsaWMgZG91YmxlIHRvRG91YmxlKCk7Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9YTUxTdHJpbmdEZWZhdWx0LmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9YTUxTdHJpbmdEZWZhdWx0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDM5NTNjODYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvWE1MU3RyaW5nRGVmYXVsdC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsODIwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFhNTFN0cmluZ0RlZmF1bHQuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNSAwODoxNjowMiBzdXJlc2hfZW1haWxpZCBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHM7Ci0KLWltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwotCi0vKioKLSAqIFRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBYTUxTdHJpbmcgaW50ZXJmYWNlLAotICogd2hpY2ggaXMganVzdCBhIHNpbXBsZSB3cmFwcGVyIG9mIGEgU3RyaW5nIG9iamVjdC4KLSAqLwotcHVibGljIGNsYXNzIFhNTFN0cmluZ0RlZmF1bHQgaW1wbGVtZW50cyBYTUxTdHJpbmcKLXsKLQotICBwcml2YXRlIFN0cmluZyBtX3N0cjsKLQotICAvKioKLSAgICogQ3JlYXRlIGEgWE1MU3RyaW5nRGVmYXVsdCBvYmplY3QgZnJvbSBhIFN0cmluZwotICAgKi8KLSAgcHVibGljIFhNTFN0cmluZ0RlZmF1bHQoU3RyaW5nIHN0cikKLSAgewotICAgIG1fc3RyID0gc3RyOwotICB9Ci0KLSAgLyoqCi0gICAqIERpcmVjdGx5IGNhbGwgdGhlCi0gICAqIGNoYXJhY3RlcnMgbWV0aG9kIG9uIHRoZSBwYXNzZWQgQ29udGVudEhhbmRsZXIgZm9yIHRoZQotICAgKiBzdHJpbmctdmFsdWUuIE11bHRpcGxlIGNhbGxzIHRvIHRoZQotICAgKiBDb250ZW50SGFuZGxlcidzIGNoYXJhY3RlcnMgbWV0aG9kcyBtYXkgd2VsbCBvY2N1ciBmb3IgYSBzaW5nbGUgY2FsbCB0bwotICAgKiB0aGlzIG1ldGhvZC4KLSAgICoKLSAgICogQHBhcmFtIGNoIEEgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGEgQ29udGVudEhhbmRsZXIuCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBkaXNwYXRjaENoYXJhY3RlcnNFdmVudHMob3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIgY2gpCi0gICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gIH0KLQotICAvKioKLSAgICogRGlyZWN0bHkgY2FsbCB0aGUKLSAgICogY29tbWVudCBtZXRob2Qgb24gdGhlIHBhc3NlZCBMZXhpY2FsSGFuZGxlciBmb3IgdGhlCi0gICAqIHN0cmluZy12YWx1ZS4KLSAgICoKLSAgICogQHBhcmFtIGxoIEEgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGEgTGV4aWNhbEhhbmRsZXIuCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBkaXNwYXRjaEFzQ29tbWVudChvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXIgbGgpCi0gICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gIH0KLQotICAvKioKLSAgICogQ29uZGl0aW9uYWxseSB0cmltIGFsbCBsZWFkaW5nIGFuZCB0cmFpbGluZyB3aGl0ZXNwYWNlIGluIHRoZSBzcGVjaWZpZWQgU3RyaW5nLgotICAgKiBBbGwgc3RyaW5ncyBvZiB3aGl0ZSBzcGFjZSBhcmUKLSAgICogcmVwbGFjZWQgYnkgYSBzaW5nbGUgc3BhY2UgY2hhcmFjdGVyICgjeDIwKSwgZXhjZXB0IHNwYWNlcyBhZnRlciBwdW5jdHVhdGlvbiB3aGljaAotICAgKiByZWNlaXZlIGRvdWJsZSBzcGFjZXMgaWYgZG91YmxlUHVuY3R1YXRpb25TcGFjZXMgaXMgdHJ1ZS4KLSAgICogVGhpcyBmdW5jdGlvbiBtYXkgYmUgdXNlZnVsIHRvIGEgZm9ybWF0dGVyLCBidXQgdG8gZ2V0IGZpcnN0IGNsYXNzCi0gICAqIHJlc3VsdHMsIHRoZSBmb3JtYXR0ZXIgc2hvdWxkIHByb2JhYmx5IGRvIGl0J3Mgb3duIHdoaXRlIHNwYWNlIGhhbmRsaW5nCi0gICAqIGJhc2VkIG9uIHRoZSBzZW1hbnRpY3Mgb2YgdGhlIGZvcm1hdHRpbmcgb2JqZWN0LgotICAgKgotICAgKiBAcGFyYW0gICB0cmltSGVhZCAgICBUcmltIGxlYWRpbmcgd2hpdGVzcGFjZT8KLSAgICogQHBhcmFtICAgdHJpbVRhaWwgICAgVHJpbSB0cmFpbGluZyB3aGl0ZXNwYWNlPwotICAgKiBAcGFyYW0gICBkb3VibGVQdW5jdHVhdGlvblNwYWNlcyAgICBVc2UgZG91YmxlIHNwYWNlcyBmb3IgcHVuY3R1YXRpb24/Ci0gICAqIEByZXR1cm4gICAgICAgICAgICAgIFRoZSB0cmltbWVkIHN0cmluZy4KLSAgICovCi0gIHB1YmxpYyBYTUxTdHJpbmcgZml4V2hpdGVTcGFjZShib29sZWFuIHRyaW1IZWFkLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiB0cmltVGFpbCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gZG91YmxlUHVuY3R1YXRpb25TcGFjZXMpCi0gIHsKLSAgICByZXR1cm4gbmV3IFhNTFN0cmluZ0RlZmF1bHQobV9zdHIudHJpbSgpKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBsZW5ndGggb2YgdGhpcyBzdHJpbmcuCi0gICAqCi0gICAqIEByZXR1cm4gIHRoZSBsZW5ndGggb2YgdGhlIHNlcXVlbmNlIG9mIGNoYXJhY3RlcnMgcmVwcmVzZW50ZWQgYnkgdGhpcwotICAgKiAgICAgICAgICBvYmplY3QuCi0gICAqLwotICBwdWJsaWMgaW50IGxlbmd0aCgpCi0gIHsKLSAgICByZXR1cm4gbV9zdHIubGVuZ3RoKCk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgY2hhcmFjdGVyIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXguIEFuIGluZGV4IHJhbmdlcwotICAgKiBmcm9tIDxjb2RlPjA8L2NvZGU+IHRvIDxjb2RlPmxlbmd0aCgpIC0gMTwvY29kZT4uIFRoZSBmaXJzdCBjaGFyYWN0ZXIKLSAgICogb2YgdGhlIHNlcXVlbmNlIGlzIGF0IGluZGV4IDxjb2RlPjA8L2NvZGU+LCB0aGUgbmV4dCBhdCBpbmRleAotICAgKiA8Y29kZT4xPC9jb2RlPiwgYW5kIHNvIG9uLCBhcyBmb3IgYXJyYXkgaW5kZXhpbmcuCi0gICAqCi0gICAqIEBwYXJhbSAgICAgIGluZGV4ICAgdGhlIGluZGV4IG9mIHRoZSBjaGFyYWN0ZXIuCi0gICAqIEByZXR1cm4gICAgIHRoZSBjaGFyYWN0ZXIgYXQgdGhlIHNwZWNpZmllZCBpbmRleCBvZiB0aGlzIHN0cmluZy4KLSAgICogICAgICAgICAgICAgVGhlIGZpcnN0IGNoYXJhY3RlciBpcyBhdCBpbmRleCA8Y29kZT4wPC9jb2RlPi4KLSAgICogQGV4Y2VwdGlvbiAgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiAgaWYgdGhlIDxjb2RlPmluZGV4PC9jb2RlPgotICAgKiAgICAgICAgICAgICBhcmd1bWVudCBpcyBuZWdhdGl2ZSBvciBub3QgbGVzcyB0aGFuIHRoZSBsZW5ndGggb2YgdGhpcwotICAgKiAgICAgICAgICAgICBzdHJpbmcuCi0gICAqLwotICBwdWJsaWMgY2hhciBjaGFyQXQoaW50IGluZGV4KQotICB7Ci0gICAgcmV0dXJuIG1fc3RyLmNoYXJBdChpbmRleCk7Ci0gIH0KLQotICAvKioKLSAgICogQ29waWVzIGNoYXJhY3RlcnMgZnJvbSB0aGlzIHN0cmluZyBpbnRvIHRoZSBkZXN0aW5hdGlvbiBjaGFyYWN0ZXIKLSAgICogYXJyYXkuCi0gICAqCi0gICAqIEBwYXJhbSAgICAgIHNyY0JlZ2luICAgaW5kZXggb2YgdGhlIGZpcnN0IGNoYXJhY3RlciBpbiB0aGUgc3RyaW5nCi0gICAqICAgICAgICAgICAgICAgICAgICAgICAgdG8gY29weS4KLSAgICogQHBhcmFtICAgICAgc3JjRW5kICAgICBpbmRleCBhZnRlciB0aGUgbGFzdCBjaGFyYWN0ZXIgaW4gdGhlIHN0cmluZwotICAgKiAgICAgICAgICAgICAgICAgICAgICAgIHRvIGNvcHkuCi0gICAqIEBwYXJhbSAgICAgIGRzdCAgICAgICAgdGhlIGRlc3RpbmF0aW9uIGFycmF5LgotICAgKiBAcGFyYW0gICAgICBkc3RCZWdpbiAgIHRoZSBzdGFydCBvZmZzZXQgaW4gdGhlIGRlc3RpbmF0aW9uIGFycmF5LgotICAgKiBAZXhjZXB0aW9uIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gSWYgYW55IG9mIHRoZSBmb2xsb3dpbmcKLSAgICogICAgICAgICAgICBpcyB0cnVlOgotICAgKiAgICAgICAgICAgIDx1bD48bGk+PGNvZGU+c3JjQmVnaW48L2NvZGU+IGlzIG5lZ2F0aXZlLgotICAgKiAgICAgICAgICAgIDxsaT48Y29kZT5zcmNCZWdpbjwvY29kZT4gaXMgZ3JlYXRlciB0aGFuIDxjb2RlPnNyY0VuZDwvY29kZT4KLSAgICogICAgICAgICAgICA8bGk+PGNvZGU+c3JjRW5kPC9jb2RlPiBpcyBncmVhdGVyIHRoYW4gdGhlIGxlbmd0aCBvZiB0aGlzCi0gICAqICAgICAgICAgICAgICAgIHN0cmluZwotICAgKiAgICAgICAgICAgIDxsaT48Y29kZT5kc3RCZWdpbjwvY29kZT4gaXMgbmVnYXRpdmUKLSAgICogICAgICAgICAgICA8bGk+PGNvZGU+ZHN0QmVnaW4rKHNyY0VuZC1zcmNCZWdpbik8L2NvZGU+IGlzIGxhcmdlciB0aGFuCi0gICAqICAgICAgICAgICAgICAgIDxjb2RlPmRzdC5sZW5ndGg8L2NvZGU+PC91bD4KLSAgICogQGV4Y2VwdGlvbiBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiA8Y29kZT5kc3Q8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+Ci0gICAqLwotICBwdWJsaWMgdm9pZCBnZXRDaGFycyhpbnQgc3JjQmVnaW4sIGludCBzcmNFbmQsIGNoYXIgZHN0W10sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBkc3RCZWdpbikKLSAgewotICAgIGludCBkZXN0SW5kZXggPSBkc3RCZWdpbjsKLSAgICBmb3IgKGludCBpID0gc3JjQmVnaW47IGkgPCBzcmNFbmQ7IGkrKykKLSAgICB7Ci0gICAgICBkc3RbZGVzdEluZGV4KytdID0gbV9zdHIuY2hhckF0KGkpOwotICAgIH0KLSAgfQotCi0gICAvKioKLSAgICogQ29tcGFyZXMgdGhpcyBzdHJpbmcgdG8gdGhlIHNwZWNpZmllZCA8Y29kZT5TdHJpbmc8L2NvZGU+LgotICAgKiBUaGUgcmVzdWx0IGlzIDxjb2RlPnRydWU8L2NvZGU+IGlmIGFuZCBvbmx5IGlmIHRoZSBhcmd1bWVudCBpcyBub3QKLSAgICogPGNvZGU+bnVsbDwvY29kZT4gYW5kIGlzIGEgPGNvZGU+U3RyaW5nPC9jb2RlPiBvYmplY3QgdGhhdCByZXByZXNlbnRzCi0gICAqIHRoZSBzYW1lIHNlcXVlbmNlIG9mIGNoYXJhY3RlcnMgYXMgdGhpcyBvYmplY3QuCi0gICAqCi0gICAqIEBwYXJhbSAgIG9iajIgICB0aGUgb2JqZWN0IHRvIGNvbXBhcmUgdGhpcyA8Y29kZT5TdHJpbmc8L2NvZGU+IGFnYWluc3QuCi0gICAqIEByZXR1cm4gIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSA8Y29kZT5TdHJpbmc8L2NvZGU+cyBhcmUgZXF1YWw7Ci0gICAqICAgICAgICAgIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuCi0gICAqIEBzZWUgICAgIGphdmEubGFuZy5TdHJpbmcjY29tcGFyZVRvKGphdmEubGFuZy5TdHJpbmcpCi0gICAqIEBzZWUgICAgIGphdmEubGFuZy5TdHJpbmcjZXF1YWxzSWdub3JlQ2FzZShqYXZhLmxhbmcuU3RyaW5nKQotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZXF1YWxzKFN0cmluZyBvYmoyKSB7Ci0gICAgICByZXR1cm4gbV9zdHIuZXF1YWxzKG9iajIpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbXBhcmVzIHRoaXMgc3RyaW5nIHRvIHRoZSBzcGVjaWZpZWQgb2JqZWN0LgotICAgKiBUaGUgcmVzdWx0IGlzIDxjb2RlPnRydWU8L2NvZGU+IGlmIGFuZCBvbmx5IGlmIHRoZSBhcmd1bWVudCBpcyBub3QKLSAgICogPGNvZGU+bnVsbDwvY29kZT4gYW5kIGlzIGEgPGNvZGU+U3RyaW5nPC9jb2RlPiBvYmplY3QgdGhhdCByZXByZXNlbnRzCi0gICAqIHRoZSBzYW1lIHNlcXVlbmNlIG9mIGNoYXJhY3RlcnMgYXMgdGhpcyBvYmplY3QuCi0gICAqCi0gICAqIEBwYXJhbSAgIGFuT2JqZWN0ICAgdGhlIG9iamVjdCB0byBjb21wYXJlIHRoaXMgPGNvZGU+U3RyaW5nPC9jb2RlPgotICAgKiAgICAgICAgICAgICAgICAgICAgIGFnYWluc3QuCi0gICAqIEByZXR1cm4gIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSA8Y29kZT5TdHJpbmcgPC9jb2RlPmFyZSBlcXVhbDsKLSAgICogICAgICAgICAgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4KLSAgICogQHNlZSAgICAgamF2YS5sYW5nLlN0cmluZyNjb21wYXJlVG8oamF2YS5sYW5nLlN0cmluZykKLSAgICogQHNlZSAgICAgamF2YS5sYW5nLlN0cmluZyNlcXVhbHNJZ25vcmVDYXNlKGphdmEubGFuZy5TdHJpbmcpCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoWE1MU3RyaW5nIGFuT2JqZWN0KQotICB7Ci0gICAgcmV0dXJuIG1fc3RyLmVxdWFscyhhbk9iamVjdC50b1N0cmluZygpKTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIENvbXBhcmVzIHRoaXMgc3RyaW5nIHRvIHRoZSBzcGVjaWZpZWQgb2JqZWN0LgotICAgKiBUaGUgcmVzdWx0IGlzIDxjb2RlPnRydWU8L2NvZGU+IGlmIGFuZCBvbmx5IGlmIHRoZSBhcmd1bWVudCBpcyBub3QKLSAgICogPGNvZGU+bnVsbDwvY29kZT4gYW5kIGlzIGEgPGNvZGU+U3RyaW5nPC9jb2RlPiBvYmplY3QgdGhhdCByZXByZXNlbnRzCi0gICAqIHRoZSBzYW1lIHNlcXVlbmNlIG9mIGNoYXJhY3RlcnMgYXMgdGhpcyBvYmplY3QuCi0gICAqCi0gICAqIEBwYXJhbSAgIGFuT2JqZWN0ICAgdGhlIG9iamVjdCB0byBjb21wYXJlIHRoaXMgPGNvZGU+U3RyaW5nPC9jb2RlPgotICAgKiAgICAgICAgICAgICAgICAgICAgIGFnYWluc3QuCi0gICAqIEByZXR1cm4gIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSA8Y29kZT5TdHJpbmcgPC9jb2RlPmFyZSBlcXVhbDsKLSAgICogICAgICAgICAgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4KLSAgICogQHNlZSAgICAgamF2YS5sYW5nLlN0cmluZyNjb21wYXJlVG8oamF2YS5sYW5nLlN0cmluZykKLSAgICogQHNlZSAgICAgamF2YS5sYW5nLlN0cmluZyNlcXVhbHNJZ25vcmVDYXNlKGphdmEubGFuZy5TdHJpbmcpCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IGFuT2JqZWN0KQotICB7Ci0gICAgcmV0dXJuIG1fc3RyLmVxdWFscyhhbk9iamVjdCk7Ci0gIH0KLQotICAvKioKLSAgICogQ29tcGFyZXMgdGhpcyA8Y29kZT5TdHJpbmc8L2NvZGU+IHRvIGFub3RoZXIgPGNvZGU+U3RyaW5nPC9jb2RlPiwKLSAgICogaWdub3JpbmcgY2FzZSBjb25zaWRlcmF0aW9ucy4gIFR3byBzdHJpbmdzIGFyZSBjb25zaWRlcmVkIGVxdWFsCi0gICAqIGlnbm9yaW5nIGNhc2UgaWYgdGhleSBhcmUgb2YgdGhlIHNhbWUgbGVuZ3RoLCBhbmQgY29ycmVzcG9uZGluZwotICAgKiBjaGFyYWN0ZXJzIGluIHRoZSB0d28gc3RyaW5ncyBhcmUgZXF1YWwgaWdub3JpbmcgY2FzZS4KLSAgICoKLSAgICogQHBhcmFtICAgYW5vdGhlclN0cmluZyAgIHRoZSA8Y29kZT5TdHJpbmc8L2NvZGU+IHRvIGNvbXBhcmUgdGhpcwotICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgPGNvZGU+U3RyaW5nPC9jb2RlPiBhZ2FpbnN0LgotICAgKiBAcmV0dXJuICA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgYXJndW1lbnQgaXMgbm90IDxjb2RlPm51bGw8L2NvZGU+Ci0gICAqICAgICAgICAgIGFuZCB0aGUgPGNvZGU+U3RyaW5nPC9jb2RlPnMgYXJlIGVxdWFsLAotICAgKiAgICAgICAgICBpZ25vcmluZyBjYXNlOyA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLgotICAgKiBAc2VlICAgICAjZXF1YWxzKE9iamVjdCkKLSAgICogQHNlZSAgICAgamF2YS5sYW5nLkNoYXJhY3RlciN0b0xvd2VyQ2FzZShjaGFyKQotICAgKiBAc2VlIGphdmEubGFuZy5DaGFyYWN0ZXIjdG9VcHBlckNhc2UoY2hhcikKLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGVxdWFsc0lnbm9yZUNhc2UoU3RyaW5nIGFub3RoZXJTdHJpbmcpCi0gIHsKLSAgICByZXR1cm4gbV9zdHIuZXF1YWxzSWdub3JlQ2FzZShhbm90aGVyU3RyaW5nKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb21wYXJlcyB0d28gc3RyaW5ncyBsZXhpY29ncmFwaGljYWxseS4KLSAgICoKLSAgICogQHBhcmFtICAgYW5vdGhlclN0cmluZyAgIHRoZSA8Y29kZT5TdHJpbmc8L2NvZGU+IHRvIGJlIGNvbXBhcmVkLgotICAgKiBAcmV0dXJuICB0aGUgdmFsdWUgPGNvZGU+MDwvY29kZT4gaWYgdGhlIGFyZ3VtZW50IHN0cmluZyBpcyBlcXVhbCB0bwotICAgKiAgICAgICAgICB0aGlzIHN0cmluZzsgYSB2YWx1ZSBsZXNzIHRoYW4gPGNvZGU+MDwvY29kZT4gaWYgdGhpcyBzdHJpbmcKLSAgICogICAgICAgICAgaXMgbGV4aWNvZ3JhcGhpY2FsbHkgbGVzcyB0aGFuIHRoZSBzdHJpbmcgYXJndW1lbnQ7IGFuZCBhCi0gICAqICAgICAgICAgIHZhbHVlIGdyZWF0ZXIgdGhhbiA8Y29kZT4wPC9jb2RlPiBpZiB0aGlzIHN0cmluZyBpcwotICAgKiAgICAgICAgICBsZXhpY29ncmFwaGljYWxseSBncmVhdGVyIHRoYW4gdGhlIHN0cmluZyBhcmd1bWVudC4KLSAgICogQGV4Y2VwdGlvbiBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgPGNvZGU+YW5vdGhlclN0cmluZzwvY29kZT4KLSAgICogICAgICAgICAgaXMgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAqLwotICBwdWJsaWMgaW50IGNvbXBhcmVUbyhYTUxTdHJpbmcgYW5vdGhlclN0cmluZykKLSAgewotICAgIHJldHVybiBtX3N0ci5jb21wYXJlVG8oYW5vdGhlclN0cmluZy50b1N0cmluZygpKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb21wYXJlcyB0d28gc3RyaW5ncyBsZXhpY29ncmFwaGljYWxseSwgaWdub3JpbmcgY2FzZSBjb25zaWRlcmF0aW9ucy4KLSAgICogVGhpcyBtZXRob2QgcmV0dXJucyBhbiBpbnRlZ2VyIHdob3NlIHNpZ24gaXMgdGhhdCBvZgotICAgKiA8Y29kZT50aGlzLnRvVXBwZXJDYXNlKCkudG9Mb3dlckNhc2UoKS5jb21wYXJlVG8oCi0gICAqIHN0ci50b1VwcGVyQ2FzZSgpLnRvTG93ZXJDYXNlKCkpPC9jb2RlPi4KLSAgICogPHA+Ci0gICAqIE5vdGUgdGhhdCB0aGlzIG1ldGhvZCBkb2VzIDxlbT5ub3Q8L2VtPiB0YWtlIGxvY2FsZSBpbnRvIGFjY291bnQsCi0gICAqIGFuZCB3aWxsIHJlc3VsdCBpbiBhbiB1bnNhdGlzZmFjdG9yeSBvcmRlcmluZyBmb3IgY2VydGFpbiBsb2NhbGVzLgotICAgKiBUaGUgamF2YS50ZXh0IHBhY2thZ2UgcHJvdmlkZXMgPGVtPmNvbGxhdG9yczwvZW0+IHRvIGFsbG93Ci0gICAqIGxvY2FsZS1zZW5zaXRpdmUgb3JkZXJpbmcuCi0gICAqCi0gICAqIEBwYXJhbSAgIHN0ciAgIHRoZSA8Y29kZT5TdHJpbmc8L2NvZGU+IHRvIGJlIGNvbXBhcmVkLgotICAgKiBAcmV0dXJuICBhIG5lZ2F0aXZlIGludGVnZXIsIHplcm8sIG9yIGEgcG9zaXRpdmUgaW50ZWdlciBhcyB0aGUKLSAgICogICAgICAgICAgdGhlIHNwZWNpZmllZCBTdHJpbmcgaXMgZ3JlYXRlciB0aGFuLCBlcXVhbCB0bywgb3IgbGVzcwotICAgKiAgICAgICAgICB0aGFuIHRoaXMgU3RyaW5nLCBpZ25vcmluZyBjYXNlIGNvbnNpZGVyYXRpb25zLgotICAgKiBAc2VlICAgICBqYXZhLnRleHQuQ29sbGF0b3IjY29tcGFyZShTdHJpbmcsIFN0cmluZykKLSAgICogQHNpbmNlICAgMS4yCi0gICAqLwotICBwdWJsaWMgaW50IGNvbXBhcmVUb0lnbm9yZUNhc2UoWE1MU3RyaW5nIHN0cikKLSAgewotICAgIHJldHVybiBtX3N0ci5jb21wYXJlVG9JZ25vcmVDYXNlKHN0ci50b1N0cmluZygpKTsKLSAgfQotCi0gIC8qKgotICAgKiBUZXN0cyBpZiB0aGlzIHN0cmluZyBzdGFydHMgd2l0aCB0aGUgc3BlY2lmaWVkIHByZWZpeCBiZWdpbm5pbmcKLSAgICogYSBzcGVjaWZpZWQgaW5kZXguCi0gICAqCi0gICAqIEBwYXJhbSAgIHByZWZpeCAgICB0aGUgcHJlZml4LgotICAgKiBAcGFyYW0gICB0b2Zmc2V0ICAgd2hlcmUgdG8gYmVnaW4gbG9va2luZyBpbiB0aGUgc3RyaW5nLgotICAgKiBAcmV0dXJuICA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgY2hhcmFjdGVyIHNlcXVlbmNlIHJlcHJlc2VudGVkIGJ5IHRoZQotICAgKiAgICAgICAgICBhcmd1bWVudCBpcyBhIHByZWZpeCBvZiB0aGUgc3Vic3RyaW5nIG9mIHRoaXMgb2JqZWN0IHN0YXJ0aW5nCi0gICAqICAgICAgICAgIGF0IGluZGV4IDxjb2RlPnRvZmZzZXQ8L2NvZGU+OyA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLgotICAgKiAgICAgICAgICBUaGUgcmVzdWx0IGlzIDxjb2RlPmZhbHNlPC9jb2RlPiBpZiA8Y29kZT50b2Zmc2V0PC9jb2RlPiBpcwotICAgKiAgICAgICAgICBuZWdhdGl2ZSBvciBncmVhdGVyIHRoYW4gdGhlIGxlbmd0aCBvZiB0aGlzCi0gICAqICAgICAgICAgIDxjb2RlPlN0cmluZzwvY29kZT4gb2JqZWN0OyBvdGhlcndpc2UgdGhlIHJlc3VsdCBpcyB0aGUgc2FtZQotICAgKiAgICAgICAgICBhcyB0aGUgcmVzdWx0IG9mIHRoZSBleHByZXNzaW9uCi0gICAqICAgICAgICAgIDxwcmU+Ci0gICAqICAgICAgICAgIHRoaXMuc3ViU3RyaW5nKHRvZmZzZXQpLnN0YXJ0c1dpdGgocHJlZml4KQotICAgKiAgICAgICAgICA8L3ByZT4KLSAgICogQGV4Y2VwdGlvbiBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgPGNvZGU+cHJlZml4PC9jb2RlPiBpcwotICAgKiAgICAgICAgICA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIHN0YXJ0c1dpdGgoU3RyaW5nIHByZWZpeCwgaW50IHRvZmZzZXQpCi0gIHsKLSAgICByZXR1cm4gbV9zdHIuc3RhcnRzV2l0aChwcmVmaXgsIHRvZmZzZXQpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlc3RzIGlmIHRoaXMgc3RyaW5nIHN0YXJ0cyB3aXRoIHRoZSBzcGVjaWZpZWQgcHJlZml4IGJlZ2lubmluZwotICAgKiBhIHNwZWNpZmllZCBpbmRleC4KLSAgICoKLSAgICogQHBhcmFtICAgcHJlZml4ICAgIHRoZSBwcmVmaXguCi0gICAqIEBwYXJhbSAgIHRvZmZzZXQgICB3aGVyZSB0byBiZWdpbiBsb29raW5nIGluIHRoZSBzdHJpbmcuCi0gICAqIEByZXR1cm4gIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBjaGFyYWN0ZXIgc2VxdWVuY2UgcmVwcmVzZW50ZWQgYnkgdGhlCi0gICAqICAgICAgICAgIGFyZ3VtZW50IGlzIGEgcHJlZml4IG9mIHRoZSBzdWJzdHJpbmcgb2YgdGhpcyBvYmplY3Qgc3RhcnRpbmcKLSAgICogICAgICAgICAgYXQgaW5kZXggPGNvZGU+dG9mZnNldDwvY29kZT47IDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuCi0gICAqICAgICAgICAgIFRoZSByZXN1bHQgaXMgPGNvZGU+ZmFsc2U8L2NvZGU+IGlmIDxjb2RlPnRvZmZzZXQ8L2NvZGU+IGlzCi0gICAqICAgICAgICAgIG5lZ2F0aXZlIG9yIGdyZWF0ZXIgdGhhbiB0aGUgbGVuZ3RoIG9mIHRoaXMKLSAgICogICAgICAgICAgPGNvZGU+U3RyaW5nPC9jb2RlPiBvYmplY3Q7IG90aGVyd2lzZSB0aGUgcmVzdWx0IGlzIHRoZSBzYW1lCi0gICAqICAgICAgICAgIGFzIHRoZSByZXN1bHQgb2YgdGhlIGV4cHJlc3Npb24KLSAgICogICAgICAgICAgPHByZT4KLSAgICogICAgICAgICAgdGhpcy5zdWJTdHJpbmcodG9mZnNldCkuc3RhcnRzV2l0aChwcmVmaXgpCi0gICAqICAgICAgICAgIDwvcHJlPgotICAgKiBAZXhjZXB0aW9uIGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiA8Y29kZT5wcmVmaXg8L2NvZGU+IGlzCi0gICAqICAgICAgICAgIDxjb2RlPm51bGw8L2NvZGU+LgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gc3RhcnRzV2l0aChYTUxTdHJpbmcgcHJlZml4LCBpbnQgdG9mZnNldCkKLSAgewotICAgIHJldHVybiBtX3N0ci5zdGFydHNXaXRoKHByZWZpeC50b1N0cmluZygpLCB0b2Zmc2V0KTsKLSAgfQotCi0gIC8qKgotICAgKiBUZXN0cyBpZiB0aGlzIHN0cmluZyBzdGFydHMgd2l0aCB0aGUgc3BlY2lmaWVkIHByZWZpeC4KLSAgICoKLSAgICogQHBhcmFtICAgcHJlZml4ICAgdGhlIHByZWZpeC4KLSAgICogQHJldHVybiAgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIGNoYXJhY3RlciBzZXF1ZW5jZSByZXByZXNlbnRlZCBieSB0aGUKLSAgICogICAgICAgICAgYXJndW1lbnQgaXMgYSBwcmVmaXggb2YgdGhlIGNoYXJhY3RlciBzZXF1ZW5jZSByZXByZXNlbnRlZCBieQotICAgKiAgICAgICAgICB0aGlzIHN0cmluZzsgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4KLSAgICogICAgICAgICAgTm90ZSBhbHNvIHRoYXQgPGNvZGU+dHJ1ZTwvY29kZT4gd2lsbCBiZSByZXR1cm5lZCBpZiB0aGUKLSAgICogICAgICAgICAgYXJndW1lbnQgaXMgYW4gZW1wdHkgc3RyaW5nIG9yIGlzIGVxdWFsIHRvIHRoaXMKLSAgICogICAgICAgICAgPGNvZGU+U3RyaW5nPC9jb2RlPiBvYmplY3QgYXMgZGV0ZXJtaW5lZCBieSB0aGUKLSAgICogICAgICAgICAge0BsaW5rICNlcXVhbHMoT2JqZWN0KX0gbWV0aG9kLgotICAgKiBAZXhjZXB0aW9uIGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiA8Y29kZT5wcmVmaXg8L2NvZGU+IGlzCi0gICAqICAgICAgICAgIDxjb2RlPm51bGw8L2NvZGU+LgotICAgKiBAc2luY2UgICBKREsxLiAwCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBzdGFydHNXaXRoKFN0cmluZyBwcmVmaXgpCi0gIHsKLSAgICByZXR1cm4gbV9zdHIuc3RhcnRzV2l0aChwcmVmaXgpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlc3RzIGlmIHRoaXMgc3RyaW5nIHN0YXJ0cyB3aXRoIHRoZSBzcGVjaWZpZWQgcHJlZml4LgotICAgKgotICAgKiBAcGFyYW0gICBwcmVmaXggICB0aGUgcHJlZml4LgotICAgKiBAcmV0dXJuICA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgY2hhcmFjdGVyIHNlcXVlbmNlIHJlcHJlc2VudGVkIGJ5IHRoZQotICAgKiAgICAgICAgICBhcmd1bWVudCBpcyBhIHByZWZpeCBvZiB0aGUgY2hhcmFjdGVyIHNlcXVlbmNlIHJlcHJlc2VudGVkIGJ5Ci0gICAqICAgICAgICAgIHRoaXMgc3RyaW5nOyA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLgotICAgKiAgICAgICAgICBOb3RlIGFsc28gdGhhdCA8Y29kZT50cnVlPC9jb2RlPiB3aWxsIGJlIHJldHVybmVkIGlmIHRoZQotICAgKiAgICAgICAgICBhcmd1bWVudCBpcyBhbiBlbXB0eSBzdHJpbmcgb3IgaXMgZXF1YWwgdG8gdGhpcwotICAgKiAgICAgICAgICA8Y29kZT5TdHJpbmc8L2NvZGU+IG9iamVjdCBhcyBkZXRlcm1pbmVkIGJ5IHRoZQotICAgKiAgICAgICAgICB7QGxpbmsgI2VxdWFscyhPYmplY3QpfSBtZXRob2QuCi0gICAqIEBleGNlcHRpb24gamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uIGlmIDxjb2RlPnByZWZpeDwvY29kZT4gaXMKLSAgICogICAgICAgICAgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAqIEBzaW5jZSAgIEpESzEuIDAKLSAgICovCi0gIHB1YmxpYyBib29sZWFuIHN0YXJ0c1dpdGgoWE1MU3RyaW5nIHByZWZpeCkKLSAgewotICAgIHJldHVybiBtX3N0ci5zdGFydHNXaXRoKHByZWZpeC50b1N0cmluZygpKTsKLSAgfQotCi0gIC8qKgotICAgKiBUZXN0cyBpZiB0aGlzIHN0cmluZyBlbmRzIHdpdGggdGhlIHNwZWNpZmllZCBzdWZmaXguCi0gICAqCi0gICAqIEBwYXJhbSAgIHN1ZmZpeCAgIHRoZSBzdWZmaXguCi0gICAqIEByZXR1cm4gIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBjaGFyYWN0ZXIgc2VxdWVuY2UgcmVwcmVzZW50ZWQgYnkgdGhlCi0gICAqICAgICAgICAgIGFyZ3VtZW50IGlzIGEgc3VmZml4IG9mIHRoZSBjaGFyYWN0ZXIgc2VxdWVuY2UgcmVwcmVzZW50ZWQgYnkKLSAgICogICAgICAgICAgdGhpcyBvYmplY3Q7IDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuIE5vdGUgdGhhdCB0aGUKLSAgICogICAgICAgICAgcmVzdWx0IHdpbGwgYmUgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIGFyZ3VtZW50IGlzIHRoZQotICAgKiAgICAgICAgICBlbXB0eSBzdHJpbmcgb3IgaXMgZXF1YWwgdG8gdGhpcyA8Y29kZT5TdHJpbmc8L2NvZGU+IG9iamVjdAotICAgKiAgICAgICAgICBhcyBkZXRlcm1pbmVkIGJ5IHRoZSB7QGxpbmsgI2VxdWFscyhPYmplY3QpfSBtZXRob2QuCi0gICAqIEBleGNlcHRpb24gamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uIGlmIDxjb2RlPnN1ZmZpeDwvY29kZT4gaXMKLSAgICogICAgICAgICAgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBlbmRzV2l0aChTdHJpbmcgc3VmZml4KQotICB7Ci0gICAgcmV0dXJuIG1fc3RyLmVuZHNXaXRoKHN1ZmZpeCk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyBhIGhhc2hjb2RlIGZvciB0aGlzIHN0cmluZy4gVGhlIGhhc2hjb2RlIGZvciBhCi0gICAqIDxjb2RlPlN0cmluZzwvY29kZT4gb2JqZWN0IGlzIGNvbXB1dGVkIGFzCi0gICAqIDxibG9ja3F1b3RlPjxwcmU+Ci0gICAqIHNbMF0qMzFeKG4tMSkgKyBzWzFdKjMxXihuLTIpICsgLi4uICsgc1tuLTFdCi0gICAqIDwvcHJlPjwvYmxvY2txdW90ZT4KLSAgICogdXNpbmcgPGNvZGU+aW50PC9jb2RlPiBhcml0aG1ldGljLCB3aGVyZSA8Y29kZT5zW2ldPC9jb2RlPiBpcyB0aGUKLSAgICogPGk+aTwvaT50aCBjaGFyYWN0ZXIgb2YgdGhlIHN0cmluZywgPGNvZGU+bjwvY29kZT4gaXMgdGhlIGxlbmd0aCBvZgotICAgKiB0aGUgc3RyaW5nLCBhbmQgPGNvZGU+XjwvY29kZT4gaW5kaWNhdGVzIGV4cG9uZW50aWF0aW9uLgotICAgKiAoVGhlIGhhc2ggdmFsdWUgb2YgdGhlIGVtcHR5IHN0cmluZyBpcyB6ZXJvLikKLSAgICoKLSAgICogQHJldHVybiAgYSBoYXNoIGNvZGUgdmFsdWUgZm9yIHRoaXMgb2JqZWN0LgotICAgKi8KLSAgcHVibGljIGludCBoYXNoQ29kZSgpCi0gIHsKLSAgICByZXR1cm4gbV9zdHIuaGFzaENvZGUoKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBpbmRleCB3aXRoaW4gdGhpcyBzdHJpbmcgb2YgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgdGhlCi0gICAqIHNwZWNpZmllZCBjaGFyYWN0ZXIuIElmIGEgY2hhcmFjdGVyIHdpdGggdmFsdWUgPGNvZGU+Y2g8L2NvZGU+IG9jY3VycwotICAgKiBpbiB0aGUgY2hhcmFjdGVyIHNlcXVlbmNlIHJlcHJlc2VudGVkIGJ5IHRoaXMgPGNvZGU+U3RyaW5nPC9jb2RlPgotICAgKiBvYmplY3QsIHRoZW4gdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBzdWNoIG9jY3VycmVuY2UgaXMgcmV0dXJuZWQgLS0KLSAgICogdGhhdCBpcywgdGhlIHNtYWxsZXN0IHZhbHVlIDxpPms8L2k+IHN1Y2ggdGhhdDoKLSAgICogPGJsb2NrcXVvdGU+PHByZT4KLSAgICogdGhpcy5jaGFyQXQoPGk+azwvaT4pID09IGNoCi0gICAqIDwvcHJlPjwvYmxvY2txdW90ZT4KLSAgICogaXMgPGNvZGU+dHJ1ZTwvY29kZT4uIElmIG5vIHN1Y2ggY2hhcmFjdGVyIG9jY3VycyBpbiB0aGlzIHN0cmluZywKLSAgICogdGhlbiA8Y29kZT4tMTwvY29kZT4gaXMgcmV0dXJuZWQuCi0gICAqCi0gICAqIEBwYXJhbSAgIGNoICAgYSBjaGFyYWN0ZXIuCi0gICAqIEByZXR1cm4gIHRoZSBpbmRleCBvZiB0aGUgZmlyc3Qgb2NjdXJyZW5jZSBvZiB0aGUgY2hhcmFjdGVyIGluIHRoZQotICAgKiAgICAgICAgICBjaGFyYWN0ZXIgc2VxdWVuY2UgcmVwcmVzZW50ZWQgYnkgdGhpcyBvYmplY3QsIG9yCi0gICAqICAgICAgICAgIDxjb2RlPi0xPC9jb2RlPiBpZiB0aGUgY2hhcmFjdGVyIGRvZXMgbm90IG9jY3VyLgotICAgKi8KLSAgcHVibGljIGludCBpbmRleE9mKGludCBjaCkKLSAgewotICAgIHJldHVybiBtX3N0ci5pbmRleE9mKGNoKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBpbmRleCB3aXRoaW4gdGhpcyBzdHJpbmcgb2YgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgdGhlCi0gICAqIHNwZWNpZmllZCBjaGFyYWN0ZXIsIHN0YXJ0aW5nIHRoZSBzZWFyY2ggYXQgdGhlIHNwZWNpZmllZCBpbmRleC4KLSAgICogPHA+Ci0gICAqIElmIGEgY2hhcmFjdGVyIHdpdGggdmFsdWUgPGNvZGU+Y2g8L2NvZGU+IG9jY3VycyBpbiB0aGUgY2hhcmFjdGVyCi0gICAqIHNlcXVlbmNlIHJlcHJlc2VudGVkIGJ5IHRoaXMgPGNvZGU+U3RyaW5nPC9jb2RlPiBvYmplY3QgYXQgYW4gaW5kZXgKLSAgICogbm8gc21hbGxlciB0aGFuIDxjb2RlPmZyb21JbmRleDwvY29kZT4sIHRoZW4gdGhlIGluZGV4IG9mIHRoZSBmaXJzdAotICAgKiBzdWNoIG9jY3VycmVuY2UgaXMgcmV0dXJuZWQtLXRoYXQgaXMsIHRoZSBzbWFsbGVzdCB2YWx1ZSA8aT5rPC9pPgotICAgKiBzdWNoIHRoYXQ6Ci0gICAqIDxibG9ja3F1b3RlPjxwcmU+Ci0gICAqICh0aGlzLmNoYXJBdCg8aT5rPC9pPikgPT0gY2gpICYmICg8aT5rPC9pPiA+PSBmcm9tSW5kZXgpCi0gICAqIDwvcHJlPjwvYmxvY2txdW90ZT4KLSAgICogaXMgdHJ1ZS4gSWYgbm8gc3VjaCBjaGFyYWN0ZXIgb2NjdXJzIGluIHRoaXMgc3RyaW5nIGF0IG9yIGFmdGVyCi0gICAqIHBvc2l0aW9uIDxjb2RlPmZyb21JbmRleDwvY29kZT4sIHRoZW4gPGNvZGU+LTE8L2NvZGU+IGlzIHJldHVybmVkLgotICAgKiA8cD4KLSAgICogVGhlcmUgaXMgbm8gcmVzdHJpY3Rpb24gb24gdGhlIHZhbHVlIG9mIDxjb2RlPmZyb21JbmRleDwvY29kZT4uIElmIGl0Ci0gICAqIGlzIG5lZ2F0aXZlLCBpdCBoYXMgdGhlIHNhbWUgZWZmZWN0IGFzIGlmIGl0IHdlcmUgemVybzogdGhpcyBlbnRpcmUKLSAgICogc3RyaW5nIG1heSBiZSBzZWFyY2hlZC4gSWYgaXQgaXMgZ3JlYXRlciB0aGFuIHRoZSBsZW5ndGggb2YgdGhpcwotICAgKiBzdHJpbmcsIGl0IGhhcyB0aGUgc2FtZSBlZmZlY3QgYXMgaWYgaXQgd2VyZSBlcXVhbCB0byB0aGUgbGVuZ3RoIG9mCi0gICAqIHRoaXMgc3RyaW5nOiA8Y29kZT4tMTwvY29kZT4gaXMgcmV0dXJuZWQuCi0gICAqCi0gICAqIEBwYXJhbSAgIGNoICAgICAgICAgIGEgY2hhcmFjdGVyLgotICAgKiBAcGFyYW0gICBmcm9tSW5kZXggICB0aGUgaW5kZXggdG8gc3RhcnQgdGhlIHNlYXJjaCBmcm9tLgotICAgKiBAcmV0dXJuICB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgdGhlIGNoYXJhY3RlciBpbiB0aGUKLSAgICogICAgICAgICAgY2hhcmFjdGVyIHNlcXVlbmNlIHJlcHJlc2VudGVkIGJ5IHRoaXMgb2JqZWN0IHRoYXQgaXMgZ3JlYXRlcgotICAgKiAgICAgICAgICB0aGFuIG9yIGVxdWFsIHRvIDxjb2RlPmZyb21JbmRleDwvY29kZT4sIG9yIDxjb2RlPi0xPC9jb2RlPgotICAgKiAgICAgICAgICBpZiB0aGUgY2hhcmFjdGVyIGRvZXMgbm90IG9jY3VyLgotICAgKi8KLSAgcHVibGljIGludCBpbmRleE9mKGludCBjaCwgaW50IGZyb21JbmRleCkKLSAgewotICAgIHJldHVybiBtX3N0ci5pbmRleE9mKGNoLCBmcm9tSW5kZXgpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIGluZGV4IHdpdGhpbiB0aGlzIHN0cmluZyBvZiB0aGUgbGFzdCBvY2N1cnJlbmNlIG9mIHRoZQotICAgKiBzcGVjaWZpZWQgY2hhcmFjdGVyLiBUaGF0IGlzLCB0aGUgaW5kZXggcmV0dXJuZWQgaXMgdGhlIGxhcmdlc3QKLSAgICogdmFsdWUgPGk+azwvaT4gc3VjaCB0aGF0OgotICAgKiA8YmxvY2txdW90ZT48cHJlPgotICAgKiB0aGlzLmNoYXJBdCg8aT5rPC9pPikgPT0gY2gKLSAgICogPC9wcmU+PC9ibG9ja3F1b3RlPgotICAgKiBpcyB0cnVlLgotICAgKiBUaGUgU3RyaW5nIGlzIHNlYXJjaGVkIGJhY2t3YXJkcyBzdGFydGluZyBhdCB0aGUgbGFzdCBjaGFyYWN0ZXIuCi0gICAqCi0gICAqIEBwYXJhbSAgIGNoICAgYSBjaGFyYWN0ZXIuCi0gICAqIEByZXR1cm4gIHRoZSBpbmRleCBvZiB0aGUgbGFzdCBvY2N1cnJlbmNlIG9mIHRoZSBjaGFyYWN0ZXIgaW4gdGhlCi0gICAqICAgICAgICAgIGNoYXJhY3RlciBzZXF1ZW5jZSByZXByZXNlbnRlZCBieSB0aGlzIG9iamVjdCwgb3IKLSAgICogICAgICAgICAgPGNvZGU+LTE8L2NvZGU+IGlmIHRoZSBjaGFyYWN0ZXIgZG9lcyBub3Qgb2NjdXIuCi0gICAqLwotICBwdWJsaWMgaW50IGxhc3RJbmRleE9mKGludCBjaCkKLSAgewotICAgIHJldHVybiBtX3N0ci5sYXN0SW5kZXhPZihjaCk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgaW5kZXggd2l0aGluIHRoaXMgc3RyaW5nIG9mIHRoZSBsYXN0IG9jY3VycmVuY2Ugb2YgdGhlCi0gICAqIHNwZWNpZmllZCBjaGFyYWN0ZXIsIHNlYXJjaGluZyBiYWNrd2FyZCBzdGFydGluZyBhdCB0aGUgc3BlY2lmaWVkCi0gICAqIGluZGV4LiBUaGF0IGlzLCB0aGUgaW5kZXggcmV0dXJuZWQgaXMgdGhlIGxhcmdlc3QgdmFsdWUgPGk+azwvaT4KLSAgICogc3VjaCB0aGF0OgotICAgKiA8YmxvY2txdW90ZT48cHJlPgotICAgKiB0aGlzLmNoYXJBdChrKSA9PSBjaCkgJiYgKGsgPD0gZnJvbUluZGV4KQotICAgKiA8L3ByZT48L2Jsb2NrcXVvdGU+Ci0gICAqIGlzIHRydWUuCi0gICAqCi0gICAqIEBwYXJhbSAgIGNoICAgICAgICAgIGEgY2hhcmFjdGVyLgotICAgKiBAcGFyYW0gICBmcm9tSW5kZXggICB0aGUgaW5kZXggdG8gc3RhcnQgdGhlIHNlYXJjaCBmcm9tLiBUaGVyZSBpcyBubwotICAgKiAgICAgICAgICByZXN0cmljdGlvbiBvbiB0aGUgdmFsdWUgb2YgPGNvZGU+ZnJvbUluZGV4PC9jb2RlPi4gSWYgaXQgaXMKLSAgICogICAgICAgICAgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHRoZSBsZW5ndGggb2YgdGhpcyBzdHJpbmcsIGl0IGhhcwotICAgKiAgICAgICAgICB0aGUgc2FtZSBlZmZlY3QgYXMgaWYgaXQgd2VyZSBlcXVhbCB0byBvbmUgbGVzcyB0aGFuIHRoZQotICAgKiAgICAgICAgICBsZW5ndGggb2YgdGhpcyBzdHJpbmc6IHRoaXMgZW50aXJlIHN0cmluZyBtYXkgYmUgc2VhcmNoZWQuCi0gICAqICAgICAgICAgIElmIGl0IGlzIG5lZ2F0aXZlLCBpdCBoYXMgdGhlIHNhbWUgZWZmZWN0IGFzIGlmIGl0IHdlcmUgLTE6Ci0gICAqICAgICAgICAgIC0xIGlzIHJldHVybmVkLgotICAgKiBAcmV0dXJuICB0aGUgaW5kZXggb2YgdGhlIGxhc3Qgb2NjdXJyZW5jZSBvZiB0aGUgY2hhcmFjdGVyIGluIHRoZQotICAgKiAgICAgICAgICBjaGFyYWN0ZXIgc2VxdWVuY2UgcmVwcmVzZW50ZWQgYnkgdGhpcyBvYmplY3QgdGhhdCBpcyBsZXNzCi0gICAqICAgICAgICAgIHRoYW4gb3IgZXF1YWwgdG8gPGNvZGU+ZnJvbUluZGV4PC9jb2RlPiwgb3IgPGNvZGU+LTE8L2NvZGU+Ci0gICAqICAgICAgICAgIGlmIHRoZSBjaGFyYWN0ZXIgZG9lcyBub3Qgb2NjdXIgYmVmb3JlIHRoYXQgcG9pbnQuCi0gICAqLwotICBwdWJsaWMgaW50IGxhc3RJbmRleE9mKGludCBjaCwgaW50IGZyb21JbmRleCkKLSAgewotICAgIHJldHVybiBtX3N0ci5sYXN0SW5kZXhPZihjaCwgZnJvbUluZGV4KTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBpbmRleCB3aXRoaW4gdGhpcyBzdHJpbmcgb2YgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgdGhlCi0gICAqIHNwZWNpZmllZCBzdWJzdHJpbmcuIFRoZSBpbnRlZ2VyIHJldHVybmVkIGlzIHRoZSBzbWFsbGVzdCB2YWx1ZQotICAgKiA8aT5rPC9pPiBzdWNoIHRoYXQ6Ci0gICAqIDxibG9ja3F1b3RlPjxwcmU+Ci0gICAqIHRoaXMuc3RhcnRzV2l0aChzdHIsIDxpPms8L2k+KQotICAgKiA8L3ByZT48L2Jsb2NrcXVvdGU+Ci0gICAqIGlzIDxjb2RlPnRydWU8L2NvZGU+LgotICAgKgotICAgKiBAcGFyYW0gICBzdHIgICBhbnkgc3RyaW5nLgotICAgKiBAcmV0dXJuICBpZiB0aGUgc3RyaW5nIGFyZ3VtZW50IG9jY3VycyBhcyBhIHN1YnN0cmluZyB3aXRoaW4gdGhpcwotICAgKiAgICAgICAgICBvYmplY3QsIHRoZW4gdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBjaGFyYWN0ZXIgb2YgdGhlIGZpcnN0Ci0gICAqICAgICAgICAgIHN1Y2ggc3Vic3RyaW5nIGlzIHJldHVybmVkOyBpZiBpdCBkb2VzIG5vdCBvY2N1ciBhcyBhCi0gICAqICAgICAgICAgIHN1YnN0cmluZywgPGNvZGU+LTE8L2NvZGU+IGlzIHJldHVybmVkLgotICAgKiBAZXhjZXB0aW9uIGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiA8Y29kZT5zdHI8L2NvZGU+IGlzCi0gICAqICAgICAgICAgIDxjb2RlPm51bGw8L2NvZGU+LgotICAgKi8KLSAgcHVibGljIGludCBpbmRleE9mKFN0cmluZyBzdHIpCi0gIHsKLSAgICByZXR1cm4gbV9zdHIuaW5kZXhPZihzdHIpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIGluZGV4IHdpdGhpbiB0aGlzIHN0cmluZyBvZiB0aGUgZmlyc3Qgb2NjdXJyZW5jZSBvZiB0aGUKLSAgICogc3BlY2lmaWVkIHN1YnN0cmluZy4gVGhlIGludGVnZXIgcmV0dXJuZWQgaXMgdGhlIHNtYWxsZXN0IHZhbHVlCi0gICAqIDxpPms8L2k+IHN1Y2ggdGhhdDoKLSAgICogPGJsb2NrcXVvdGU+PHByZT4KLSAgICogdGhpcy5zdGFydHNXaXRoKHN0ciwgPGk+azwvaT4pCi0gICAqIDwvcHJlPjwvYmxvY2txdW90ZT4KLSAgICogaXMgPGNvZGU+dHJ1ZTwvY29kZT4uCi0gICAqCi0gICAqIEBwYXJhbSAgIHN0ciAgIGFueSBzdHJpbmcuCi0gICAqIEByZXR1cm4gIGlmIHRoZSBzdHJpbmcgYXJndW1lbnQgb2NjdXJzIGFzIGEgc3Vic3RyaW5nIHdpdGhpbiB0aGlzCi0gICAqICAgICAgICAgIG9iamVjdCwgdGhlbiB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IGNoYXJhY3RlciBvZiB0aGUgZmlyc3QKLSAgICogICAgICAgICAgc3VjaCBzdWJzdHJpbmcgaXMgcmV0dXJuZWQ7IGlmIGl0IGRvZXMgbm90IG9jY3VyIGFzIGEKLSAgICogICAgICAgICAgc3Vic3RyaW5nLCA8Y29kZT4tMTwvY29kZT4gaXMgcmV0dXJuZWQuCi0gICAqIEBleGNlcHRpb24gamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uIGlmIDxjb2RlPnN0cjwvY29kZT4gaXMKLSAgICogICAgICAgICAgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAqLwotICBwdWJsaWMgaW50IGluZGV4T2YoWE1MU3RyaW5nIHN0cikKLSAgewotICAgIHJldHVybiBtX3N0ci5pbmRleE9mKHN0ci50b1N0cmluZygpKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBpbmRleCB3aXRoaW4gdGhpcyBzdHJpbmcgb2YgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgdGhlCi0gICAqIHNwZWNpZmllZCBzdWJzdHJpbmcsIHN0YXJ0aW5nIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXguIFRoZSBpbnRlZ2VyCi0gICAqIHJldHVybmVkIGlzIHRoZSBzbWFsbGVzdCB2YWx1ZSA8aT5rPC9pPiBzdWNoIHRoYXQ6Ci0gICAqIDxibG9ja3F1b3RlPjxwcmU+Ci0gICAqIHRoaXMuc3RhcnRzV2l0aChzdHIsIDxpPms8L2k+KSAmJiAoPGk+azwvaT4gPj0gZnJvbUluZGV4KQotICAgKiA8L3ByZT48L2Jsb2NrcXVvdGU+Ci0gICAqIGlzIDxjb2RlPnRydWU8L2NvZGU+LgotICAgKiA8cD4KLSAgICogVGhlcmUgaXMgbm8gcmVzdHJpY3Rpb24gb24gdGhlIHZhbHVlIG9mIDxjb2RlPmZyb21JbmRleDwvY29kZT4uIElmCi0gICAqIGl0IGlzIG5lZ2F0aXZlLCBpdCBoYXMgdGhlIHNhbWUgZWZmZWN0IGFzIGlmIGl0IHdlcmUgemVybzogdGhpcyBlbnRpcmUKLSAgICogc3RyaW5nIG1heSBiZSBzZWFyY2hlZC4gSWYgaXQgaXMgZ3JlYXRlciB0aGFuIHRoZSBsZW5ndGggb2YgdGhpcwotICAgKiBzdHJpbmcsIGl0IGhhcyB0aGUgc2FtZSBlZmZlY3QgYXMgaWYgaXQgd2VyZSBlcXVhbCB0byB0aGUgbGVuZ3RoIG9mCi0gICAqIHRoaXMgc3RyaW5nOiA8Y29kZT4tMTwvY29kZT4gaXMgcmV0dXJuZWQuCi0gICAqCi0gICAqIEBwYXJhbSAgIHN0ciAgICAgICAgIHRoZSBzdWJzdHJpbmcgdG8gc2VhcmNoIGZvci4KLSAgICogQHBhcmFtICAgZnJvbUluZGV4ICAgdGhlIGluZGV4IHRvIHN0YXJ0IHRoZSBzZWFyY2ggZnJvbS4KLSAgICogQHJldHVybiAgSWYgdGhlIHN0cmluZyBhcmd1bWVudCBvY2N1cnMgYXMgYSBzdWJzdHJpbmcgd2l0aGluIHRoaXMKLSAgICogICAgICAgICAgb2JqZWN0IGF0IGEgc3RhcnRpbmcgaW5kZXggbm8gc21hbGxlciB0aGFuCi0gICAqICAgICAgICAgIDxjb2RlPmZyb21JbmRleDwvY29kZT4sIHRoZW4gdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBjaGFyYWN0ZXIKLSAgICogICAgICAgICAgb2YgdGhlIGZpcnN0IHN1Y2ggc3Vic3RyaW5nIGlzIHJldHVybmVkLiBJZiBpdCBkb2VzIG5vdCBvY2N1cgotICAgKiAgICAgICAgICBhcyBhIHN1YnN0cmluZyBzdGFydGluZyBhdCA8Y29kZT5mcm9tSW5kZXg8L2NvZGU+IG9yIGJleW9uZCwKLSAgICogICAgICAgICAgPGNvZGU+LTE8L2NvZGU+IGlzIHJldHVybmVkLgotICAgKiBAZXhjZXB0aW9uIGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiA8Y29kZT5zdHI8L2NvZGU+IGlzCi0gICAqICAgICAgICAgIDxjb2RlPm51bGw8L2NvZGU+Ci0gICAqLwotICBwdWJsaWMgaW50IGluZGV4T2YoU3RyaW5nIHN0ciwgaW50IGZyb21JbmRleCkKLSAgewotICAgIHJldHVybiBtX3N0ci5pbmRleE9mKHN0ciwgZnJvbUluZGV4KTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBpbmRleCB3aXRoaW4gdGhpcyBzdHJpbmcgb2YgdGhlIHJpZ2h0bW9zdCBvY2N1cnJlbmNlCi0gICAqIG9mIHRoZSBzcGVjaWZpZWQgc3Vic3RyaW5nLiAgVGhlIHJpZ2h0bW9zdCBlbXB0eSBzdHJpbmcgIiIgaXMKLSAgICogY29uc2lkZXJlZCB0byBvY2N1ciBhdCB0aGUgaW5kZXggdmFsdWUgPGNvZGU+dGhpcy5sZW5ndGgoKTwvY29kZT4uCi0gICAqIFRoZSByZXR1cm5lZCBpbmRleCBpcyB0aGUgbGFyZ2VzdCB2YWx1ZSA8aT5rPC9pPiBzdWNoIHRoYXQKLSAgICogPGJsb2NrcXVvdGU+PHByZT4KLSAgICogdGhpcy5zdGFydHNXaXRoKHN0ciwgaykKLSAgICogPC9wcmU+PC9ibG9ja3F1b3RlPgotICAgKiBpcyB0cnVlLgotICAgKgotICAgKiBAcGFyYW0gICBzdHIgICB0aGUgc3Vic3RyaW5nIHRvIHNlYXJjaCBmb3IuCi0gICAqIEByZXR1cm4gIGlmIHRoZSBzdHJpbmcgYXJndW1lbnQgb2NjdXJzIG9uZSBvciBtb3JlIHRpbWVzIGFzIGEgc3Vic3RyaW5nCi0gICAqICAgICAgICAgIHdpdGhpbiB0aGlzIG9iamVjdCwgdGhlbiB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IGNoYXJhY3RlciBvZgotICAgKiAgICAgICAgICB0aGUgbGFzdCBzdWNoIHN1YnN0cmluZyBpcyByZXR1cm5lZC4gSWYgaXQgZG9lcyBub3Qgb2NjdXIgYXMKLSAgICogICAgICAgICAgYSBzdWJzdHJpbmcsIDxjb2RlPi0xPC9jb2RlPiBpcyByZXR1cm5lZC4KLSAgICogQGV4Y2VwdGlvbiBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24gIGlmIDxjb2RlPnN0cjwvY29kZT4gaXMKLSAgICogICAgICAgICAgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAqLwotICBwdWJsaWMgaW50IGxhc3RJbmRleE9mKFN0cmluZyBzdHIpCi0gIHsKLSAgICByZXR1cm4gbV9zdHIubGFzdEluZGV4T2Yoc3RyKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBpbmRleCB3aXRoaW4gdGhpcyBzdHJpbmcgb2YgdGhlIGxhc3Qgb2NjdXJyZW5jZSBvZgotICAgKiB0aGUgc3BlY2lmaWVkIHN1YnN0cmluZy4KLSAgICoKLSAgICogQHBhcmFtICAgc3RyICAgICAgICAgdGhlIHN1YnN0cmluZyB0byBzZWFyY2ggZm9yLgotICAgKiBAcGFyYW0gICBmcm9tSW5kZXggICB0aGUgaW5kZXggdG8gc3RhcnQgdGhlIHNlYXJjaCBmcm9tLiBUaGVyZSBpcyBubwotICAgKiAgICAgICAgICByZXN0cmljdGlvbiBvbiB0aGUgdmFsdWUgb2YgZnJvbUluZGV4LiBJZiBpdCBpcyBncmVhdGVyIHRoYW4KLSAgICogICAgICAgICAgdGhlIGxlbmd0aCBvZiB0aGlzIHN0cmluZywgaXQgaGFzIHRoZSBzYW1lIGVmZmVjdCBhcyBpZiBpdAotICAgKiAgICAgICAgICB3ZXJlIGVxdWFsIHRvIHRoZSBsZW5ndGggb2YgdGhpcyBzdHJpbmc6IHRoaXMgZW50aXJlIHN0cmluZwotICAgKiAgICAgICAgICBtYXkgYmUgc2VhcmNoZWQuIElmIGl0IGlzIG5lZ2F0aXZlLCBpdCBoYXMgdGhlIHNhbWUgZWZmZWN0Ci0gICAqICAgICAgICAgIGFzIGlmIGl0IHdlcmUgLTE6IC0xIGlzIHJldHVybmVkLgotICAgKiBAcmV0dXJuICBJZiB0aGUgc3RyaW5nIGFyZ3VtZW50IG9jY3VycyBvbmUgb3IgbW9yZSB0aW1lcyBhcyBhIHN1YnN0cmluZwotICAgKiAgICAgICAgICB3aXRoaW4gdGhpcyBvYmplY3QgYXQgYSBzdGFydGluZyBpbmRleCBubyBncmVhdGVyIHRoYW4KLSAgICogICAgICAgICAgPGNvZGU+ZnJvbUluZGV4PC9jb2RlPiwgdGhlbiB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IGNoYXJhY3RlciBvZgotICAgKiAgICAgICAgICB0aGUgbGFzdCBzdWNoIHN1YnN0cmluZyBpcyByZXR1cm5lZC4gSWYgaXQgZG9lcyBub3Qgb2NjdXIgYXMgYQotICAgKiAgICAgICAgICBzdWJzdHJpbmcgc3RhcnRpbmcgYXQgPGNvZGU+ZnJvbUluZGV4PC9jb2RlPiBvciBlYXJsaWVyLAotICAgKiAgICAgICAgICA8Y29kZT4tMTwvY29kZT4gaXMgcmV0dXJuZWQuCi0gICAqIEBleGNlcHRpb24gamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uIGlmIDxjb2RlPnN0cjwvY29kZT4gaXMKLSAgICogICAgICAgICAgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAqLwotICBwdWJsaWMgaW50IGxhc3RJbmRleE9mKFN0cmluZyBzdHIsIGludCBmcm9tSW5kZXgpCi0gIHsKLSAgICByZXR1cm4gbV9zdHIubGFzdEluZGV4T2Yoc3RyLCBmcm9tSW5kZXgpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgYSBuZXcgc3RyaW5nIHRoYXQgaXMgYSBzdWJzdHJpbmcgb2YgdGhpcyBzdHJpbmcuIFRoZQotICAgKiBzdWJzdHJpbmcgYmVnaW5zIHdpdGggdGhlIGNoYXJhY3RlciBhdCB0aGUgc3BlY2lmaWVkIGluZGV4IGFuZAotICAgKiBleHRlbmRzIHRvIHRoZSBlbmQgb2YgdGhpcyBzdHJpbmcuIDxwPgotICAgKiBFeGFtcGxlczoKLSAgICogPGJsb2NrcXVvdGU+PHByZT4KLSAgICogInVuaGFwcHkiLnN1YnN0cmluZygyKSByZXR1cm5zICJoYXBweSIKLSAgICogIkhhcmJpc29uIi5zdWJzdHJpbmcoMykgcmV0dXJucyAiYmlzb24iCi0gICAqICJlbXB0aW5lc3MiLnN1YnN0cmluZyg5KSByZXR1cm5zICIiIChhbiBlbXB0eSBzdHJpbmcpCi0gICAqIDwvcHJlPjwvYmxvY2txdW90ZT4KLSAgICoKLSAgICogQHBhcmFtICAgICAgYmVnaW5JbmRleCAgIHRoZSBiZWdpbm5pbmcgaW5kZXgsIGluY2x1c2l2ZS4KLSAgICogQHJldHVybiAgICAgdGhlIHNwZWNpZmllZCBzdWJzdHJpbmcuCi0gICAqIEBleGNlcHRpb24gIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gIGlmCi0gICAqICAgICAgICAgICAgIDxjb2RlPmJlZ2luSW5kZXg8L2NvZGU+IGlzIG5lZ2F0aXZlIG9yIGxhcmdlciB0aGFuIHRoZQotICAgKiAgICAgICAgICAgICBsZW5ndGggb2YgdGhpcyA8Y29kZT5TdHJpbmc8L2NvZGU+IG9iamVjdC4KLSAgICovCi0gIHB1YmxpYyBYTUxTdHJpbmcgc3Vic3RyaW5nKGludCBiZWdpbkluZGV4KQotICB7Ci0gICAgcmV0dXJuIG5ldyBYTUxTdHJpbmdEZWZhdWx0KG1fc3RyLnN1YnN0cmluZyhiZWdpbkluZGV4KSk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyBhIG5ldyBzdHJpbmcgdGhhdCBpcyBhIHN1YnN0cmluZyBvZiB0aGlzIHN0cmluZy4gVGhlCi0gICAqIHN1YnN0cmluZyBiZWdpbnMgYXQgdGhlIHNwZWNpZmllZCA8Y29kZT5iZWdpbkluZGV4PC9jb2RlPiBhbmQKLSAgICogZXh0ZW5kcyB0byB0aGUgY2hhcmFjdGVyIGF0IGluZGV4IDxjb2RlPmVuZEluZGV4IC0gMTwvY29kZT4uCi0gICAqIFRodXMgdGhlIGxlbmd0aCBvZiB0aGUgc3Vic3RyaW5nIGlzIDxjb2RlPmVuZEluZGV4LWJlZ2luSW5kZXg8L2NvZGU+LgotICAgKgotICAgKiBAcGFyYW0gICAgICBiZWdpbkluZGV4ICAgdGhlIGJlZ2lubmluZyBpbmRleCwgaW5jbHVzaXZlLgotICAgKiBAcGFyYW0gICAgICBlbmRJbmRleCAgICAgdGhlIGVuZGluZyBpbmRleCwgZXhjbHVzaXZlLgotICAgKiBAcmV0dXJuICAgICB0aGUgc3BlY2lmaWVkIHN1YnN0cmluZy4KLSAgICogQGV4Y2VwdGlvbiAgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiAgaWYgdGhlCi0gICAqICAgICAgICAgICAgIDxjb2RlPmJlZ2luSW5kZXg8L2NvZGU+IGlzIG5lZ2F0aXZlLCBvcgotICAgKiAgICAgICAgICAgICA8Y29kZT5lbmRJbmRleDwvY29kZT4gaXMgbGFyZ2VyIHRoYW4gdGhlIGxlbmd0aCBvZgotICAgKiAgICAgICAgICAgICB0aGlzIDxjb2RlPlN0cmluZzwvY29kZT4gb2JqZWN0LCBvcgotICAgKiAgICAgICAgICAgICA8Y29kZT5iZWdpbkluZGV4PC9jb2RlPiBpcyBsYXJnZXIgdGhhbgotICAgKiAgICAgICAgICAgICA8Y29kZT5lbmRJbmRleDwvY29kZT4uCi0gICAqLwotICBwdWJsaWMgWE1MU3RyaW5nIHN1YnN0cmluZyhpbnQgYmVnaW5JbmRleCwgaW50IGVuZEluZGV4KQotICB7Ci0gICAgcmV0dXJuIG5ldyBYTUxTdHJpbmdEZWZhdWx0KG1fc3RyLnN1YnN0cmluZyhiZWdpbkluZGV4LCBlbmRJbmRleCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbmNhdGVuYXRlcyB0aGUgc3BlY2lmaWVkIHN0cmluZyB0byB0aGUgZW5kIG9mIHRoaXMgc3RyaW5nLgotICAgKgotICAgKiBAcGFyYW0gICBzdHIgICB0aGUgPGNvZGU+U3RyaW5nPC9jb2RlPiB0aGF0IGlzIGNvbmNhdGVuYXRlZCB0byB0aGUgZW5kCi0gICAqICAgICAgICAgICAgICAgIG9mIHRoaXMgPGNvZGU+U3RyaW5nPC9jb2RlPi4KLSAgICogQHJldHVybiAgYSBzdHJpbmcgdGhhdCByZXByZXNlbnRzIHRoZSBjb25jYXRlbmF0aW9uIG9mIHRoaXMgb2JqZWN0J3MKLSAgICogICAgICAgICAgY2hhcmFjdGVycyBmb2xsb3dlZCBieSB0aGUgc3RyaW5nIGFyZ3VtZW50J3MgY2hhcmFjdGVycy4KLSAgICogQGV4Y2VwdGlvbiBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgPGNvZGU+c3RyPC9jb2RlPiBpcwotICAgKiAgICAgICAgICA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICovCi0gIHB1YmxpYyBYTUxTdHJpbmcgY29uY2F0KFN0cmluZyBzdHIpCi0gIHsKLSAgICByZXR1cm4gbmV3IFhNTFN0cmluZ0RlZmF1bHQobV9zdHIuY29uY2F0KHN0cikpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbnZlcnRzIGFsbCBvZiB0aGUgY2hhcmFjdGVycyBpbiB0aGlzIDxjb2RlPlN0cmluZzwvY29kZT4gdG8gbG93ZXIKLSAgICogY2FzZSB1c2luZyB0aGUgcnVsZXMgb2YgdGhlIGdpdmVuIDxjb2RlPkxvY2FsZTwvY29kZT4uCi0gICAqCi0gICAqIEBwYXJhbSBsb2NhbGUgdXNlIHRoZSBjYXNlIHRyYW5zZm9ybWF0aW9uIHJ1bGVzIGZvciB0aGlzIGxvY2FsZQotICAgKiBAcmV0dXJuIHRoZSBTdHJpbmcsIGNvbnZlcnRlZCB0byBsb3dlcmNhc2UuCi0gICAqIEBzZWUgICAgIGphdmEubGFuZy5DaGFyYWN0ZXIjdG9Mb3dlckNhc2UoY2hhcikKLSAgICogQHNlZSAgICAgamF2YS5sYW5nLlN0cmluZyN0b1VwcGVyQ2FzZShMb2NhbGUpCi0gICAqLwotICBwdWJsaWMgWE1MU3RyaW5nIHRvTG93ZXJDYXNlKExvY2FsZSBsb2NhbGUpCi0gIHsKLSAgICByZXR1cm4gbmV3IFhNTFN0cmluZ0RlZmF1bHQobV9zdHIudG9Mb3dlckNhc2UobG9jYWxlKSk7Ci0gIH0KLQotICAvKioKLSAgICogQ29udmVydHMgYWxsIG9mIHRoZSBjaGFyYWN0ZXJzIGluIHRoaXMgPGNvZGU+U3RyaW5nPC9jb2RlPiB0byBsb3dlcgotICAgKiBjYXNlIHVzaW5nIHRoZSBydWxlcyBvZiB0aGUgZGVmYXVsdCBsb2NhbGUsIHdoaWNoIGlzIHJldHVybmVkCi0gICAqIGJ5IDxjb2RlPkxvY2FsZS5nZXREZWZhdWx0PC9jb2RlPi4KLSAgICogPHA+Ci0gICAqCi0gICAqIEByZXR1cm4gIHRoZSBzdHJpbmcsIGNvbnZlcnRlZCB0byBsb3dlcmNhc2UuCi0gICAqIEBzZWUgICAgIGphdmEubGFuZy5DaGFyYWN0ZXIjdG9Mb3dlckNhc2UoY2hhcikKLSAgICogQHNlZSAgICAgamF2YS5sYW5nLlN0cmluZyN0b0xvd2VyQ2FzZShMb2NhbGUpCi0gICAqLwotICBwdWJsaWMgWE1MU3RyaW5nIHRvTG93ZXJDYXNlKCkKLSAgewotICAgIHJldHVybiBuZXcgWE1MU3RyaW5nRGVmYXVsdChtX3N0ci50b0xvd2VyQ2FzZSgpKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb252ZXJ0cyBhbGwgb2YgdGhlIGNoYXJhY3RlcnMgaW4gdGhpcyA8Y29kZT5TdHJpbmc8L2NvZGU+IHRvIHVwcGVyCi0gICAqIGNhc2UgdXNpbmcgdGhlIHJ1bGVzIG9mIHRoZSBnaXZlbiBsb2NhbGUuCi0gICAqIEBwYXJhbSBsb2NhbGUgdXNlIHRoZSBjYXNlIHRyYW5zZm9ybWF0aW9uIHJ1bGVzIGZvciB0aGlzIGxvY2FsZQotICAgKiBAcmV0dXJuIHRoZSBTdHJpbmcsIGNvbnZlcnRlZCB0byB1cHBlcmNhc2UuCi0gICAqIEBzZWUgICAgIGphdmEubGFuZy5DaGFyYWN0ZXIjdG9VcHBlckNhc2UoY2hhcikKLSAgICogQHNlZSAgICAgamF2YS5sYW5nLlN0cmluZyN0b0xvd2VyQ2FzZShMb2NhbGUpCi0gICAqLwotICBwdWJsaWMgWE1MU3RyaW5nIHRvVXBwZXJDYXNlKExvY2FsZSBsb2NhbGUpCi0gIHsKLSAgICByZXR1cm4gbmV3IFhNTFN0cmluZ0RlZmF1bHQobV9zdHIudG9VcHBlckNhc2UobG9jYWxlKSk7Ci0gIH0KLQotICAvKioKLSAgICogQ29udmVydHMgYWxsIG9mIHRoZSBjaGFyYWN0ZXJzIGluIHRoaXMgPGNvZGU+U3RyaW5nPC9jb2RlPiB0byB1cHBlcgotICAgKiBjYXNlIHVzaW5nIHRoZSBydWxlcyBvZiB0aGUgZGVmYXVsdCBsb2NhbGUsIHdoaWNoIGlzIHJldHVybmVkCi0gICAqIGJ5IDxjb2RlPkxvY2FsZS5nZXREZWZhdWx0PC9jb2RlPi4KLSAgICoKLSAgICogPHA+Ci0gICAqIElmIG5vIGNoYXJhY3RlciBpbiB0aGlzIHN0cmluZyBoYXMgYSBkaWZmZXJlbnQgdXBwZXJjYXNlIHZlcnNpb24sCi0gICAqIGJhc2VkIG9uIGNhbGxpbmcgdGhlIDxjb2RlPnRvVXBwZXJDYXNlPC9jb2RlPiBtZXRob2QgZGVmaW5lZCBieQotICAgKiA8Y29kZT5DaGFyYWN0ZXI8L2NvZGU+LCB0aGVuIHRoZSBvcmlnaW5hbCBzdHJpbmcgaXMgcmV0dXJuZWQuCi0gICAqIDxwPgotICAgKiBPdGhlcndpc2UsIHRoaXMgbWV0aG9kIGNyZWF0ZXMgYSBuZXcgPGNvZGU+U3RyaW5nPC9jb2RlPiBvYmplY3QKLSAgICogcmVwcmVzZW50aW5nIGEgY2hhcmFjdGVyIHNlcXVlbmNlIGlkZW50aWNhbCBpbiBsZW5ndGggdG8gdGhlCi0gICAqIGNoYXJhY3RlciBzZXF1ZW5jZSByZXByZXNlbnRlZCBieSB0aGlzIDxjb2RlPlN0cmluZzwvY29kZT4gb2JqZWN0IGFuZAotICAgKiB3aXRoIGV2ZXJ5IGNoYXJhY3RlciBlcXVhbCB0byB0aGUgcmVzdWx0IG9mIGFwcGx5aW5nIHRoZSBtZXRob2QKLSAgICogPGNvZGU+Q2hhcmFjdGVyLnRvVXBwZXJDYXNlPC9jb2RlPiB0byB0aGUgY29ycmVzcG9uZGluZyBjaGFyYWN0ZXIgb2YKLSAgICogdGhpcyA8Y29kZT5TdHJpbmc8L2NvZGU+IG9iamVjdC4gPHA+Ci0gICAqIEV4YW1wbGVzOgotICAgKiA8YmxvY2txdW90ZT48cHJlPgotICAgKiAiRmFocnZlcmduJnV1bWw7Z2VuIi50b1VwcGVyQ2FzZSgpIHJldHVybnMgIkZBSFJWRVJHTiZVdW1sO0dFTiIKLSAgICogIlZpc2l0IExqdWJpbmplISIudG9VcHBlckNhc2UoKSByZXR1cm5zICJWSVNJVCBMSlVCSU5KRSEiCi0gICAqIDwvcHJlPjwvYmxvY2txdW90ZT4KLSAgICoKLSAgICogQHJldHVybiAgdGhlIHN0cmluZywgY29udmVydGVkIHRvIHVwcGVyY2FzZS4KLSAgICogQHNlZSAgICAgamF2YS5sYW5nLkNoYXJhY3RlciN0b1VwcGVyQ2FzZShjaGFyKQotICAgKiBAc2VlICAgICBqYXZhLmxhbmcuU3RyaW5nI3RvVXBwZXJDYXNlKExvY2FsZSkKLSAgICovCi0gIHB1YmxpYyBYTUxTdHJpbmcgdG9VcHBlckNhc2UoKQotICB7Ci0gICAgcmV0dXJuIG5ldyBYTUxTdHJpbmdEZWZhdWx0KG1fc3RyLnRvVXBwZXJDYXNlKCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlbW92ZXMgd2hpdGUgc3BhY2UgZnJvbSBib3RoIGVuZHMgb2YgdGhpcyBzdHJpbmcuCi0gICAqIDxwPgotICAgKiBJZiB0aGlzIDxjb2RlPlN0cmluZzwvY29kZT4gb2JqZWN0IHJlcHJlc2VudHMgYW4gZW1wdHkgY2hhcmFjdGVyCi0gICAqIHNlcXVlbmNlLCBvciB0aGUgZmlyc3QgYW5kIGxhc3QgY2hhcmFjdGVycyBvZiBjaGFyYWN0ZXIgc2VxdWVuY2UKLSAgICogcmVwcmVzZW50ZWQgYnkgdGhpcyA8Y29kZT5TdHJpbmc8L2NvZGU+IG9iamVjdCBib3RoIGhhdmUgY29kZXMKLSAgICogZ3JlYXRlciB0aGFuIDxjb2RlPicmIzkyO3UwMDIwJzwvY29kZT4gKHRoZSBzcGFjZSBjaGFyYWN0ZXIpLCB0aGVuIGEKLSAgICogcmVmZXJlbmNlIHRvIHRoaXMgPGNvZGU+U3RyaW5nPC9jb2RlPiBvYmplY3QgaXMgcmV0dXJuZWQuCi0gICAqIDxwPgotICAgKiBPdGhlcndpc2UsIGlmIHRoZXJlIGlzIG5vIGNoYXJhY3RlciB3aXRoIGEgY29kZSBncmVhdGVyIHRoYW4KLSAgICogPGNvZGU+JyYjOTI7dTAwMjAnPC9jb2RlPiBpbiB0aGUgc3RyaW5nLCB0aGVuIGEgbmV3Ci0gICAqIDxjb2RlPlN0cmluZzwvY29kZT4gb2JqZWN0IHJlcHJlc2VudGluZyBhbiBlbXB0eSBzdHJpbmcgaXMgY3JlYXRlZAotICAgKiBhbmQgcmV0dXJuZWQuCi0gICAqIDxwPgotICAgKiBPdGhlcndpc2UsIGxldCA8aT5rPC9pPiBiZSB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IGNoYXJhY3RlciBpbiB0aGUKLSAgICogc3RyaW5nIHdob3NlIGNvZGUgaXMgZ3JlYXRlciB0aGFuIDxjb2RlPicmIzkyO3UwMDIwJzwvY29kZT4sIGFuZCBsZXQKLSAgICogPGk+bTwvaT4gYmUgdGhlIGluZGV4IG9mIHRoZSBsYXN0IGNoYXJhY3RlciBpbiB0aGUgc3RyaW5nIHdob3NlIGNvZGUKLSAgICogaXMgZ3JlYXRlciB0aGFuIDxjb2RlPicmIzkyO3UwMDIwJzwvY29kZT4uIEEgbmV3IDxjb2RlPlN0cmluZzwvY29kZT4KLSAgICogb2JqZWN0IGlzIGNyZWF0ZWQsIHJlcHJlc2VudGluZyB0aGUgc3Vic3RyaW5nIG9mIHRoaXMgc3RyaW5nIHRoYXQKLSAgICogYmVnaW5zIHdpdGggdGhlIGNoYXJhY3RlciBhdCBpbmRleCA8aT5rPC9pPiBhbmQgZW5kcyB3aXRoIHRoZQotICAgKiBjaGFyYWN0ZXIgYXQgaW5kZXggPGk+bTwvaT4tdGhhdCBpcywgdGhlIHJlc3VsdCBvZgotICAgKiA8Y29kZT50aGlzLnN1YnN0cmluZyg8aT5rPC9pPiwmbmJzcDs8aT5tPC9pPisxKTwvY29kZT4uCi0gICAqIDxwPgotICAgKiBUaGlzIG1ldGhvZCBtYXkgYmUgdXNlZCB0byB0cmltCi0gICAqIHtAbGluayBDaGFyYWN0ZXIjaXNTcGFjZShjaGFyKSB3aGl0ZXNwYWNlfSBmcm9tIHRoZSBiZWdpbm5pbmcgYW5kIGVuZAotICAgKiBvZiBhIHN0cmluZzsgaW4gZmFjdCwgaXQgdHJpbXMgYWxsIEFTQ0lJIGNvbnRyb2wgY2hhcmFjdGVycyBhcyB3ZWxsLgotICAgKgotICAgKiBAcmV0dXJuICB0aGlzIHN0cmluZywgd2l0aCB3aGl0ZSBzcGFjZSByZW1vdmVkIGZyb20gdGhlIGZyb250IGFuZCBlbmQuCi0gICAqLwotICBwdWJsaWMgWE1MU3RyaW5nIHRyaW0oKQotICB7Ci0gICAgcmV0dXJuIG5ldyBYTUxTdHJpbmdEZWZhdWx0KG1fc3RyLnRyaW0oKSk7Ci0gIH0KLQotICAvKioKLSAgICogVGhpcyBvYmplY3QgKHdoaWNoIGlzIGFscmVhZHkgYSBzdHJpbmchKSBpcyBpdHNlbGYgcmV0dXJuZWQuCi0gICAqCi0gICAqIEByZXR1cm4gIHRoZSBzdHJpbmcgaXRzZWxmLgotICAgKi8KLSAgcHVibGljIFN0cmluZyB0b1N0cmluZygpCi0gIHsKLSAgICByZXR1cm4gbV9zdHI7Ci0gIH0KLQotICAvKioKLSAgICogVGVsbCBpZiB0aGlzIG9iamVjdCBjb250YWlucyBhIGphdmEgU3RyaW5nIG9iamVjdC4KLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHRoaXMgWE1MU3RyaW5nIGNhbiByZXR1cm4gYSBzdHJpbmcgd2l0aG91dCBjcmVhdGluZyBvbmUuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBoYXNTdHJpbmcoKQotICB7Ci0gICAgcmV0dXJuIHRydWU7Ci0gIH0KLQotICAvKioKLSAgICogQ29udmVydCBhIHN0cmluZyB0byBhIGRvdWJsZSAtLSBBbGxvd2VkIGlucHV0IGlzIGluIGZpeGVkCi0gICAqIG5vdGF0aW9uIGRkZC5mZmYuCi0gICAqCi0gICAqIEByZXR1cm4gQSBkb3VibGUgdmFsdWUgcmVwcmVzZW50YXRpb24gb2YgdGhlIHN0cmluZywgb3IgcmV0dXJuIERvdWJsZS5OYU4KLSAgICogaWYgdGhlIHN0cmluZyBjYW4gbm90IGJlIGNvbnZlcnRlZC4KLSAgICovCi0gIHB1YmxpYyBkb3VibGUgdG9Eb3VibGUoKQotICB7Ci0gICAgdHJ5IHsKLSAgICAgIHJldHVybiBEb3VibGUudmFsdWVPZihtX3N0cikuZG91YmxlVmFsdWUoKTsKLSAgICB9Ci0gICAgY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBuZmUpCi0gICAgewotICAgICAgcmV0dXJuIERvdWJsZS5OYU47Ci0gICAgfQotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9YTUxTdHJpbmdGYWN0b3J5LmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9YTUxTdHJpbmdGYWN0b3J5LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDIxY2FiMzIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvWE1MU3RyaW5nRmFjdG9yeS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNzMgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogWE1MU3RyaW5nRmFjdG9yeS5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE1IDA4OjE2OjAzIHN1cmVzaF9lbWFpbGlkIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlsczsKLQotLyoqCi0gKiBBIGNvbmNyZXRlIGNsYXNzIHRoYXQgaW1wbGVtZW50cyB0aGlzIGludGVyZmFjZSBjcmVhdGVzIFhNTFN0cmluZyBvYmplY3RzLgotICovCi1wdWJsaWMgYWJzdHJhY3QgY2xhc3MgWE1MU3RyaW5nRmFjdG9yeQotewotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBuZXcgWE1MU3RyaW5nIGZyb20gYSBKYXZhIHN0cmluZy4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHN0cmluZyBKYXZhIFN0cmluZyByZWZlcmVuY2UsIHdoaWNoIG11c3QgYmUgbm9uLW51bGwuCi0gICAqCi0gICAqIEByZXR1cm4gQW4gWE1MU3RyaW5nIG9iamVjdCB0aGF0IHdyYXBzIHRoZSBTdHJpbmcgcmVmZXJlbmNlLgotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IFhNTFN0cmluZyBuZXdzdHIoU3RyaW5nIHN0cmluZyk7Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIFhNTFN0cmluZyBmcm9tIGEgRmFzdFN0cmluZ0J1ZmZlci4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHN0cmluZyBGYXN0U3RyaW5nQnVmZmVyIHJlZmVyZW5jZSwgd2hpY2ggbXVzdCBiZSBub24tbnVsbC4KLSAgICogQHBhcmFtIHN0YXJ0IFRoZSBzdGFydCBwb3NpdGlvbiBpbiB0aGUgYXJyYXkuCi0gICAqIEBwYXJhbSBsZW5ndGggVGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHJlYWQgZnJvbSB0aGUgYXJyYXkuCi0gICAqCi0gICAqIEByZXR1cm4gQW4gWE1MU3RyaW5nIG9iamVjdCB0aGF0IHdyYXBzIHRoZSBGYXN0U3RyaW5nQnVmZmVyIHJlZmVyZW5jZS4KLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBYTUxTdHJpbmcgbmV3c3RyKEZhc3RTdHJpbmdCdWZmZXIgc3RyaW5nLCBpbnQgc3RhcnQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBsZW5ndGgpOwotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBYTUxTdHJpbmcgZnJvbSBhIEZhc3RTdHJpbmdCdWZmZXIuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBzdHJpbmcgRmFzdFN0cmluZ0J1ZmZlciByZWZlcmVuY2UsIHdoaWNoIG11c3QgYmUgbm9uLW51bGwuCi0gICAqIEBwYXJhbSBzdGFydCBUaGUgc3RhcnQgcG9zaXRpb24gaW4gdGhlIGFycmF5LgotICAgKiBAcGFyYW0gbGVuZ3RoIFRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyB0byByZWFkIGZyb20gdGhlIGFycmF5LgotICAgKgotICAgKiBAcmV0dXJuIEFuIFhNTFN0cmluZyBvYmplY3QgdGhhdCB3cmFwcyB0aGUgRmFzdFN0cmluZ0J1ZmZlciByZWZlcmVuY2UuCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgWE1MU3RyaW5nIG5ld3N0cihjaGFyW10gc3RyaW5nLCBpbnQgc3RhcnQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBsZW5ndGgpOwotCi0gIC8qKgotICAgKiBHZXQgYSBjaGVhcCByZXByZXNlbnRhdGlvbiBvZiBhbiBlbXB0eSBzdHJpbmcuCi0gICAqCi0gICAqIEByZXR1cm4gQW4gbm9uLW51bGwgcmVmZXJlbmNlIHRvIGFuIFhNTFN0cmluZyB0aGF0IHJlcHJlc2VudHMgIiIuCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgWE1MU3RyaW5nIGVtcHR5c3RyKCk7Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9YTUxTdHJpbmdGYWN0b3J5RGVmYXVsdC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvWE1MU3RyaW5nRmFjdG9yeURlZmF1bHQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNjM5YWVhNy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9YTUxTdHJpbmdGYWN0b3J5RGVmYXVsdC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsODYgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogWE1MU3RyaW5nRmFjdG9yeURlZmF1bHQuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNSAwODoxNjowMyBzdXJlc2hfZW1haWxpZCBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHM7Ci0KLS8qKgotICogVGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gb2YgWE1MU3RyaW5nRmFjdG9yeS4KLSAqIFRoaXMgaW1wbGVtZW50YXRpb24gY3JlYXRlcyBYTUxTdHJpbmdEZWZhdWx0IG9iamVjdHMuCi0gKi8KLXB1YmxpYyBjbGFzcyBYTUxTdHJpbmdGYWN0b3J5RGVmYXVsdCBleHRlbmRzIFhNTFN0cmluZ0ZhY3RvcnkKLXsKLSAgLy8gQSBjb25zdGFudCByZXByZXNlbnRpbmcgdGhlIGVtcHR5IFN0cmluZwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBYTUxTdHJpbmdEZWZhdWx0IEVNUFRZX1NUUiA9IG5ldyBYTUxTdHJpbmdEZWZhdWx0KCIiKTsKLQotICAvKioKLSAgICogQ3JlYXRlIGEgbmV3IFhNTFN0cmluZyBmcm9tIGEgSmF2YSBzdHJpbmcuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBzdHJpbmcgSmF2YSBTdHJpbmcgcmVmZXJlbmNlLCB3aGljaCBtdXN0IGJlIG5vbi1udWxsLgotICAgKgotICAgKiBAcmV0dXJuIEFuIFhNTFN0cmluZyBvYmplY3QgdGhhdCB3cmFwcyB0aGUgU3RyaW5nIHJlZmVyZW5jZS4KLSAgICovCi0gIHB1YmxpYyBYTUxTdHJpbmcgbmV3c3RyKFN0cmluZyBzdHJpbmcpCi0gIHsKLSAgICByZXR1cm4gbmV3IFhNTFN0cmluZ0RlZmF1bHQoc3RyaW5nKTsKLSAgfQotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBYTUxTdHJpbmcgZnJvbSBhIEZhc3RTdHJpbmdCdWZmZXIuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBmc2IgRmFzdFN0cmluZ0J1ZmZlciByZWZlcmVuY2UsIHdoaWNoIG11c3QgYmUgbm9uLW51bGwuCi0gICAqIEBwYXJhbSBzdGFydCBUaGUgc3RhcnQgcG9zaXRpb24gaW4gdGhlIGFycmF5LgotICAgKiBAcGFyYW0gbGVuZ3RoIFRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyB0byByZWFkIGZyb20gdGhlIGFycmF5LgotICAgKgotICAgKiBAcmV0dXJuIEFuIFhNTFN0cmluZyBvYmplY3QgdGhhdCB3cmFwcyB0aGUgRmFzdFN0cmluZ0J1ZmZlciByZWZlcmVuY2UuCi0gICAqLwotICBwdWJsaWMgWE1MU3RyaW5nIG5ld3N0cihGYXN0U3RyaW5nQnVmZmVyIGZzYiwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKQotICB7Ci0gICAgcmV0dXJuIG5ldyBYTUxTdHJpbmdEZWZhdWx0KGZzYi5nZXRTdHJpbmcoc3RhcnQsIGxlbmd0aCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIFhNTFN0cmluZyBmcm9tIGEgRmFzdFN0cmluZ0J1ZmZlci4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHN0cmluZyBGYXN0U3RyaW5nQnVmZmVyIHJlZmVyZW5jZSwgd2hpY2ggbXVzdCBiZSBub24tbnVsbC4KLSAgICogQHBhcmFtIHN0YXJ0IFRoZSBzdGFydCBwb3NpdGlvbiBpbiB0aGUgYXJyYXkuCi0gICAqIEBwYXJhbSBsZW5ndGggVGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHJlYWQgZnJvbSB0aGUgYXJyYXkuCi0gICAqCi0gICAqIEByZXR1cm4gQW4gWE1MU3RyaW5nIG9iamVjdCB0aGF0IHdyYXBzIHRoZSBGYXN0U3RyaW5nQnVmZmVyIHJlZmVyZW5jZS4KLSAgICovCi0gIHB1YmxpYyBYTUxTdHJpbmcgbmV3c3RyKGNoYXJbXSBzdHJpbmcsIGludCBzdGFydCwgaW50IGxlbmd0aCkKLSAgewotICAgIHJldHVybiBuZXcgWE1MU3RyaW5nRGVmYXVsdChuZXcgU3RyaW5nKHN0cmluZywgc3RhcnQsIGxlbmd0aCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBhIGNoZWFwIHJlcHJlc2VudGF0aW9uIG9mIGFuIGVtcHR5IHN0cmluZy4KLSAgICoKLSAgICogQHJldHVybiBBbiBub24tbnVsbCByZWZlcmVuY2UgdG8gYW4gWE1MU3RyaW5nIHRoYXQgcmVwcmVzZW50cyAiIi4KLSAgICovCi0gIHB1YmxpYyBYTUxTdHJpbmcgZW1wdHlzdHIoKQotICB7Ci0gICAgcmV0dXJuIEVNUFRZX1NUUjsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvcGFja2FnZS5odG1sIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvcGFja2FnZS5odG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyYWQ2OTZhLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL3BhY2thZ2UuaHRtbAorKysgL2Rldi9udWxsCkBAIC0xLDI5ICswLDAgQEAKLTwhLS0KLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0tLT4KLTwhLS0KLSAqIENvcHlyaWdodCAyMDAwLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotLS0+Ci08IS0tICRJZDogcGFja2FnZS5odG1sLHYgMS4yLjQuMSAyMDA1LzA5LzE1IDA4OjE2OjA0IHN1cmVzaF9lbWFpbGlkIEV4cCAkIC0tPgotPGh0bWw+Ci0gIDx0aXRsZT5YYWxhbiB1dGlsaXRpZXMuPC90aXRsZT4KLSAgPGJvZHk+Ci0gICAgPHA+SW1wbGVtZW50YXRpb24gb2YgWGFsYW4gdXRpbGl0eSBjbGFzc2VzLiAgVGhpcyBwYWNrYWdlIGlzIGFsc28gc2hhcmVkIGJ5IFhQYXRoLgotICAgICAgIFRoZXJlICpzaG91bGQqIGJlIG5vIG91dHdhcmQgZGVwZW5kZW5jaWVzIHRvIFhQYXRoIG9yIFhhbGFuIGJ5IGNsYXNzZXMgaW4gdGhpcyBwYWNrYWdlLjxwPgotIDwvYm9keT4KLTwvaHRtbD4KLQotCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9yZXMvQ2hhckFycmF5V3JhcHBlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvcmVzL0NoYXJBcnJheVdyYXBwZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYzViNmFiYS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9yZXMvQ2hhckFycmF5V3JhcHBlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDQgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogQ2hhckFycmF5V3JhcHBlci5qYXZhLHYgMS4xLjQuMSAyMDA1LzA5LzA4IDExOjM5OjMyIHN1cmVzaF9lbWFpbGlkIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5yZXM7Ci0KLS8qKgotICoKLSAqIEl0IGlzIGEgbXV0YWJsZSBvYmplY3QgdG8gd3JhcCB0aGUgY2hhcltdIHVzZWQgaW4KLSAqIHRoZSBjb250ZW50cyBvZiB0aGUgWFJlc291cmNlQnVuZGxlIGNsYXNzCi0gKi8KLXB1YmxpYyBjbGFzcyBDaGFyQXJyYXlXcmFwcGVyIHsKLSAgICBwcml2YXRlIGNoYXJbXSBtX2NoYXI7Ci0KLSAgICBwdWJsaWMgQ2hhckFycmF5V3JhcHBlcihjaGFyW10gYXJnKXsKLSAgICAgICAgbV9jaGFyID0gYXJnOwotICAgIH0KLQotICAgIHB1YmxpYyBjaGFyIGdldENoYXIoaW50IGluZGV4KXsKLSAgICAgICAgcmV0dXJuIG1fY2hhcltpbmRleF07Ci0gICAgfQotCi0gICAgcHVibGljIGludCBnZXRMZW5ndGgoKXsKLSAgICAgICAgcmV0dXJuIG1fY2hhci5sZW5ndGg7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvcmVzL0ludEFycmF5V3JhcHBlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvcmVzL0ludEFycmF5V3JhcHBlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3ZmMyMmY1Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL3Jlcy9JbnRBcnJheVdyYXBwZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQ0ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IEludEFycmF5V3JhcHBlci5qYXZhLHYgMS4xLjQuMSAyMDA1LzA5LzA4IDExOjM5OjMyIHN1cmVzaF9lbWFpbGlkIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5yZXM7Ci0KLS8qKgotICoKLSAqIEl0IGlzIGEgbXV0YWJsZSBvYmplY3QgdG8gd3JhcCB0aGUgaW50W10gdXNlZCBpbgotICogdGhlIGNvbnRlbnRzIG9mIHRoZSBYUmVzb3VyY2VCdW5kbGUgY2xhc3MKLSAqLwotcHVibGljIGNsYXNzIEludEFycmF5V3JhcHBlciB7Ci0gICAgcHJpdmF0ZSBpbnRbXSBtX2ludDsKLQotICAgIHB1YmxpYyBJbnRBcnJheVdyYXBwZXIoaW50W10gYXJnKXsKLSAgICAgICAgbV9pbnQgPSBhcmc7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBnZXRJbnQoaW50IGluZGV4KXsKLSAgICAgICAgcmV0dXJuIG1faW50W2luZGV4XTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldExlbmd0aCgpewotICAgICAgICByZXR1cm4gbV9pbnQubGVuZ3RoOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL3Jlcy9Mb25nQXJyYXlXcmFwcGVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9yZXMvTG9uZ0FycmF5V3JhcHBlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1MzI0MDMzLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL3Jlcy9Mb25nQXJyYXlXcmFwcGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0NCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBMb25nQXJyYXlXcmFwcGVyLmphdmEsdiAxLjEuNC4xIDIwMDUvMDkvMDggMTE6Mzk6MzIgc3VyZXNoX2VtYWlsaWQgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLnJlczsKLQotLyoqCi0gKgotICogSXQgaXMgYSBtdXRhYmxlIG9iamVjdCB0byB3cmFwIHRoZSBsb25nW10gdXNlZCBpbgotICogdGhlIGNvbnRlbnRzIG9mIHRoZSBYUmVzb3VyY2VCdW5kbGUgY2xhc3MKLSAqLwotcHVibGljIGNsYXNzIExvbmdBcnJheVdyYXBwZXIgewotICAgIHByaXZhdGUgbG9uZ1tdIG1fbG9uZzsKLQotICAgIHB1YmxpYyBMb25nQXJyYXlXcmFwcGVyKGxvbmdbXSBhcmcpewotICAgICAgICBtX2xvbmcgPSBhcmc7Ci0gICAgfQotCi0gICAgcHVibGljIGxvbmcgZ2V0TG9uZyhpbnQgaW5kZXgpewotICAgICAgICByZXR1cm4gbV9sb25nW2luZGV4XTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldExlbmd0aCgpewotICAgICAgICByZXR1cm4gbV9sb25nLmxlbmd0aDsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9yZXMvU3RyaW5nQXJyYXlXcmFwcGVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9yZXMvU3RyaW5nQXJyYXlXcmFwcGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwYjFjNDEuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvcmVzL1N0cmluZ0FycmF5V3JhcHBlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDQgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogU3RyaW5nQXJyYXlXcmFwcGVyLmphdmEsdiAxLjEuNC4xIDIwMDUvMDkvMDggMTE6Mzk6MzMgc3VyZXNoX2VtYWlsaWQgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLnJlczsKLQotLyoqCi0gKgotICogSXQgaXMgYSBtdXRhYmxlIG9iamVjdCB0byB3cmFwIHRoZSBTdHJpbmdbXSB1c2VkIGluCi0gKiB0aGUgY29udGVudHMgb2YgdGhlIFhSZXNvdXJjZUJ1bmRsZSBjbGFzcwotICovCi1wdWJsaWMgY2xhc3MgU3RyaW5nQXJyYXlXcmFwcGVyIHsKLSAgICBwcml2YXRlIFN0cmluZ1tdIG1fc3RyaW5nOwotCi0gICAgcHVibGljIFN0cmluZ0FycmF5V3JhcHBlcihTdHJpbmdbXSBhcmcpewotICAgICAgICBtX3N0cmluZyA9IGFyZzsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldFN0cmluZyhpbnQgaW5kZXgpewotICAgICAgICByZXR1cm4gbV9zdHJpbmdbaW5kZXhdOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgZ2V0TGVuZ3RoKCl7Ci0gICAgICAgIHJldHVybiBtX3N0cmluZy5sZW5ndGg7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvcmVzL1hSZXNvdXJjZUJ1bmRsZS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvcmVzL1hSZXNvdXJjZUJ1bmRsZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3MDhmYmI0Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL3Jlcy9YUmVzb3VyY2VCdW5kbGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDc1ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFhSZXNvdXJjZUJ1bmRsZS5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE1IDA4OjE2OjA0IHN1cmVzaF9lbWFpbGlkIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5yZXM7Ci0KLWltcG9ydCBqYXZhLnNlY3VyaXR5LkFjY2Vzc0NvbnRyb2xsZXI7Ci1pbXBvcnQgamF2YS5zZWN1cml0eS5Qcml2aWxlZ2VkQWN0aW9uOwotaW1wb3J0IGphdmEudXRpbC5MaXN0UmVzb3VyY2VCdW5kbGU7Ci1pbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKLWltcG9ydCBqYXZhLnV0aWwuTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uOwotaW1wb3J0IGphdmEudXRpbC5SZXNvdXJjZUJ1bmRsZTsKLQotLyoqCi0gKiBUaGUgZGVmYXVsdCAoZW5nbGlzaCkgcmVzb3VyY2UgYnVuZGxlLgotICoKLSAqIEB4c2wudXNhZ2UgaW50ZXJuYWwKLSAqLwotcHVibGljIGNsYXNzIFhSZXNvdXJjZUJ1bmRsZSBleHRlbmRzIExpc3RSZXNvdXJjZUJ1bmRsZSB7Ci0KLSAgICAvKioKLSAgICAgKiBFcnJvciByZXNvdXJjZSBjb25zdGFudHMKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJPUl9SRVNPVVJDRVMgPQotICAgICAgICAgICAgImNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC5yZXMuWFNMVEVycm9yUmVzb3VyY2VzIiwgWFNMVF9SRVNPVVJDRSA9Ci0gICAgICAgICAgICAiY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5yZXMuWFJlc291cmNlQnVuZGxlIiwgTEFOR19CVU5ETEVfTkFNRSA9Ci0gICAgICAgICAgICAiY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5yZXMuWFJlc291cmNlcyIsIE1VTFRfT1JERVIgPQotICAgICAgICAgICAgIm11bHRpcGxpZXJPcmRlciIsIE1VTFRfUFJFQ0VERVMgPSAicHJlY2VkZXMiLCBNVUxUX0ZPTExPV1MgPQotICAgICAgICAgICAgImZvbGxvd3MiLCBMQU5HX09SSUVOVEFUSU9OID0gIm9yaWVudGF0aW9uIiwgTEFOR19SSUdIVFRPTEVGVCA9Ci0gICAgICAgICAgICAicmlnaHRUb0xlZnQiLCBMQU5HX0xFRlRUT1JJR0hUID0gImxlZnRUb1JpZ2h0IiwgTEFOR19OVU1CRVJJTkcgPQotICAgICAgICAgICAgIm51bWJlcmluZyIsIExBTkdfQURESVRJVkUgPSAiYWRkaXRpdmUiLCBMQU5HX01VTFRfQUREID0KLSAgICAgICAgICAgICJtdWx0aXBsaWNhdGl2ZS1hZGRpdGl2ZSIsIExBTkdfTVVMVElQTElFUiA9Ci0gICAgICAgICAgICAibXVsdGlwbGllciIsIExBTkdfTVVMVElQTElFUl9DSEFSID0KLSAgICAgICAgICAgICJtdWx0aXBsaWVyQ2hhciIsIExBTkdfTlVNQkVSR1JPVVBTID0gIm51bWJlckdyb3VwcyIsIExBTkdfTlVNX1RBQkxFUyA9Ci0gICAgICAgICAgICAidGFibGVzIiwgTEFOR19BTFBIQUJFVCA9ICJhbHBoYWJldCIsIExBTkdfVFJBRF9BTFBIQUJFVCA9ICJ0cmFkQWxwaGFiZXQiOwotCi0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIGFzc29jaWF0aW9uIGxpc3QuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBhc3NvY2lhdGlvbiBsaXN0LgotICAgICAqLwotICAgIHB1YmxpYyBPYmplY3RbXVtdIGdldENvbnRlbnRzKCkgewotICAgICAgICByZXR1cm4gbmV3IE9iamVjdFtdW117Ci0gICAgICAgICAgICAgICAgICAgIHsidWlfbGFuZ3VhZ2UiLCAiZW4ifSwgeyJoZWxwX2xhbmd1YWdlIiwgImVuIn0sIHsibGFuZ3VhZ2UiLCAiZW4ifSwKLSAgICAgICAgICAgICAgICAgICAgeyJhbHBoYWJldCIsIG5ldyBDaGFyQXJyYXlXcmFwcGVyKG5ldyBjaGFyW117J0EnLCAnQicsICdDJywgJ0QnLCAnRScsICdGJywgJ0cnLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICdIJywgJ0knLCAnSicsICdLJywgJ0wnLCAnTScsICdOJywgJ08nLCAnUCcsICdRJywgJ1InLCAnUycsICdUJywgJ1UnLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICdWJywgJ1cnLCAnWCcsICdZJywgJ1onfSl9LAotICAgICAgICAgICAgICAgICAgICB7InRyYWRBbHBoYWJldCIsIG5ldyBDaGFyQXJyYXlXcmFwcGVyKG5ldyBjaGFyW117J0EnLCAnQicsICdDJywgJ0QnLCAnRScsICdGJywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAnRycsICdIJywgJ0knLCAnSicsICdLJywgJ0wnLCAnTScsICdOJywgJ08nLCAnUCcsICdRJywgJ1InLCAnUycsICdUJywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAnVScsICdWJywgJ1cnLCAnWCcsICdZJywgJ1onfSl9LAotICAgICAgICAgICAgICAgICAgICAvL2xhbmd1YWdlIG9yaWVudGF0aW9uCi0gICAgICAgICAgICAgICAgICAgIHsib3JpZW50YXRpb24iLCAiTGVmdFRvUmlnaHQifSwKLSAgICAgICAgICAgICAgICAgICAgLy9sYW5ndWFnZSBudW1iZXJpbmcKLSAgICAgICAgICAgICAgICAgICAgeyJudW1iZXJpbmciLCAiYWRkaXRpdmUifSx9OwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL3Jlcy9YUmVzb3VyY2VCdW5kbGVCYXNlLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9yZXMvWFJlc291cmNlQnVuZGxlQmFzZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjNTU5ZGQ0Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL3Jlcy9YUmVzb3VyY2VCdW5kbGVCYXNlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw1MiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBYUmVzb3VyY2VCdW5kbGVCYXNlLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTUgMDg6MTY6MDUgc3VyZXNoX2VtYWlsaWQgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLnJlczsKLQotaW1wb3J0IGphdmEudXRpbC5MaXN0UmVzb3VyY2VCdW5kbGU7Ci0KLS8qKgotICogVGhpcyBpcyBhbiBpbnRlcmZhY2UgZm9yIGVycm9yIG1lc3NhZ2VzLiAgVGhpcyBjbGFzcyBpcyBtaXNuYW1lZCwKLSAqIGFuZCBzaG91bGQgYmUgY2FsbGVkIFhhbGFuUmVzb3VyY2VCdW5kbGUsIG9yIHNvbWUgc3VjaC4KLSAqIEB4c2wudXNhZ2UgaW50ZXJuYWwKLSAqLwotYWJzdHJhY3QgcHVibGljIGNsYXNzIFhSZXNvdXJjZUJ1bmRsZUJhc2UgZXh0ZW5kcyBMaXN0UmVzb3VyY2VCdW5kbGUKLXsKLQotICAvKioKLSAgICogR2V0IHRoZSBlcnJvciBzdHJpbmcgYXNzb2NpYXRlZCB3aXRoIHRoZSBlcnJvciBjb2RlCi0gICAqCi0gICAqIEBwYXJhbSBlcnJvckNvZGUgRXJyb3IgY29kZQotICAgKgotICAgKiBAcmV0dXJuIGVycm9yIHN0cmluZyBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIGVycm9yIGNvZGUKLSAgICovCi0gIGFic3RyYWN0IHB1YmxpYyBTdHJpbmcgZ2V0TWVzc2FnZUtleShpbnQgZXJyb3JDb2RlKTsKLQotICAvKioKLSAgICogR2V0IHRoZSB3YXJuaW5nIHN0cmluZyBhc3NvY2lhdGVkIHdpdGggdGhlIGVycm9yIGNvZGUKLSAgICoKLSAgICogQHBhcmFtIGVycm9yQ29kZSBFcnJvciBjb2RlCi0gICAqCi0gICAqIEByZXR1cm4gd2FybmluZyBzdHJpbmcgYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBlcnJvciBjb2RlCi0gICAqLwotICBhYnN0cmFjdCBwdWJsaWMgU3RyaW5nIGdldFdhcm5pbmdLZXkoaW50IGVycm9yQ29kZSk7Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9yZXMvWFJlc291cmNlc19kZS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvcmVzL1hSZXNvdXJjZXNfZGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMmIyY2RhZS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9yZXMvWFJlc291cmNlc19kZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNzYgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogWFJlc291cmNlc19kZS5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE1IDA4OjE2OjA1IHN1cmVzaF9lbWFpbGlkIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5yZXM7Ci0KLS8vCi0vLyAgTGFuZ1Jlc291cmNlc19kZS5wcm9wZXJ0aWVzCi0vLwotCi0vKioKLSAqIFRoZSBHZXJtYW4gcmVzb3VyY2UgYnVuZGxlLgotICogQHhzbC51c2FnZSBpbnRlcm5hbAotICovCi1wdWJsaWMgY2xhc3MgWFJlc291cmNlc19kZSBleHRlbmRzIFhSZXNvdXJjZUJ1bmRsZQotewotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBPYmplY3RbXVtdIF9jb250ZW50cyA9IG5ldyBPYmplY3RbXVtdCi0gIHsKLSAgICB7ICJ1aV9sYW5ndWFnZSIsICJkZSIgfSwgeyAiaGVscF9sYW5ndWFnZSIsICJkZSIgfSwgeyAibGFuZ3VhZ2UiLCAiZGUiIH0sCi0gICAgeyAiYWxwaGFiZXQiLCBuZXcgQ2hhckFycmF5V3JhcHBlcigKLSAgICAgIG5ldyBjaGFyW117ICdBJywgJ0InLCAnQycsICdEJywgJ0UnLCAnRicsICdHJywgJ0gnLCAnSScsICdKJywgJ0snLCAnTCcsCi0gICAgICAgICAgICAgICAgICAnTScsICdOJywgJ08nLCAnUCcsICdRJywgJ1InLCAnUycsICdUJywgJ1UnLCAnVicsICdXJywgJ1gnLAotICAgICAgICAgICAgICAgICAgJ1knLCAnWicgfSkgfSwKLSAgICB7ICJ0cmFkQWxwaGFiZXQiLCBuZXcgQ2hhckFycmF5V3JhcHBlcigKLSAgICAgIG5ldyBjaGFyW117ICdBJywgJ0InLCAnQycsICdEJywgJ0UnLCAnRicsICdHJywgJ0gnLCAnSScsICdKJywgJ0snLCAnTCcsCi0gICAgICAgICAgICAgICAgICAnTScsICdOJywgJ08nLCAnUCcsICdRJywgJ1InLCAnUycsICdUJywgJ1UnLCAnVicsICdXJywgJ1gnLAotICAgICAgICAgICAgICAgICAgJ1knLCAnWicgfSkgfSwKLQotICAgIC8vbGFuZ3VhZ2Ugb3JpZW50YXRpb24KLSAgICB7ICJvcmllbnRhdGlvbiIsICJMZWZ0VG9SaWdodCIgfSwKLQotICAgIC8vbGFuZ3VhZ2UgbnVtYmVyaW5nCi0gICAgeyAibnVtYmVyaW5nIiwgImFkZGl0aXZlIiB9LAotCi0gICAgLy8gbGFyZ2VzdCBudW1lcmljYWwgdmFsdWUKLSAgICAvL3siTWF4TnVtZXJpY2FsVmFsdWUiLCBuZXcgSW50ZWdlcigpfSwKLSAgICAvL1RoZXNlIHdvdWxkIG5vdCBiZSB1c2VkIGZvciBFTi4gT25seSB1c2VkIGZvciB0cmFkaXRpb25hbCBudW1iZXJpbmcKLSAgICAvL3sibnVtYmVyR3JvdXBzIiwgbmV3IGludFtdezEwLDF9fSwKLSAgICAvL1RoZXNlIG9ubHkgdXNlZCBmb3IgbXV0aXBsaWNhdGl2ZS1hZGRpdGl2ZSBudW1iZXJpbmcKLSAgICAvL3sibXVsdGlwbGllciIsICIxMCJ9LAotICAgIC8veyJtdWx0aXBsaWVyQ2hhciIsICJNIn0sCi0gICAgLy97ImRpZ2l0cyIsIG5ldyBjaGFyW117J2EnLCdiJywnYycsJ2QnLCdlJywnZicsJ2cnLCdoJywnaSd9fSwKLSAgICAvL3siZGlnaXRzIiwgbmV3IGNoYXJbXXsweDEwRDAsMHgxMEQxLDB4MTBEMiwweDEwRDMsMHgxMEQ0LDB4MTBENSwweDEwRDYsMHgxMEQ3LDB4MTBEOH19LAotICAgIC8veyJ0ZW5zIiwgbmV3IGNoYXJbXXsweDEwRDksMHgxMERBLDB4MTBEQiwweDEwREMsMHgxMERELDB4MTBERSwweDEwREYsMHgxMEUwLDB4MTBFMX19LAotICAgIC8vaHVuZHJlZHMsIGV0Yy4uLgotICAgIC8veyJ0YWJsZXMiLCBuZXcgU3RyaW5nW117InRlbnMiLCAiZGlnaXRzIn19Ci0gIH07Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgYXNzb2NpYXRpb24gbGlzdC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgYXNzb2NpYXRpb24gbGlzdC4KLSAgICovCi0gIHB1YmxpYyBPYmplY3RbXVtdIGdldENvbnRlbnRzKCkKLSAgewotICAgIHJldHVybiBfY29udGVudHM7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL3Jlcy9YUmVzb3VyY2VzX2VuLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9yZXMvWFJlc291cmNlc19lbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjMWRlMGI0Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL3Jlcy9YUmVzb3VyY2VzX2VuLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3NiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBYUmVzb3VyY2VzX2VuLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTUgMDg6MTY6MDYgc3VyZXNoX2VtYWlsaWQgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLnJlczsKLQotLy8KLS8vICBMYW5nUmVzb3VyY2VzX2VuLnByb3BlcnRpZXMKLS8vCi0KLS8qKgotICogVGhlIEVuZ2xpc2ggcmVzb3VyY2UgYnVuZGxlLgotICogQHhzbC51c2FnZSBpbnRlcm5hbAotICovCi1wdWJsaWMgY2xhc3MgWFJlc291cmNlc19lbiBleHRlbmRzIFhSZXNvdXJjZUJ1bmRsZQotewotCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIE9iamVjdFtdW10gX2NvbnRlbnRzID0gbmV3IE9iamVjdFtdW10KLSAgewotICAgIHsgInVpX2xhbmd1YWdlIiwgImVuIiB9LCB7ICJoZWxwX2xhbmd1YWdlIiwgImVuIiB9LCB7ICJsYW5ndWFnZSIsICJlbiIgfSwKLSAgICB7ICJhbHBoYWJldCIsIG5ldyBDaGFyQXJyYXlXcmFwcGVyKAotICAgICAgbmV3IGNoYXJbXXsgJ0EnLCAnQicsICdDJywgJ0QnLCAnRScsICdGJywgJ0cnLCAnSCcsICdJJywgJ0onLCAnSycsICdMJywKLSAgICAgICAgICAgICAgICAgICdNJywgJ04nLCAnTycsICdQJywgJ1EnLCAnUicsICdTJywgJ1QnLCAnVScsICdWJywgJ1cnLCAnWCcsCi0gICAgICAgICAgICAgICAgICAnWScsICdaJyB9KX0sCi0gICAgeyAidHJhZEFscGhhYmV0IiwgbmV3IENoYXJBcnJheVdyYXBwZXIoCi0gICAgICBuZXcgY2hhcltdeyAnQScsICdCJywgJ0MnLCAnRCcsICdFJywgJ0YnLCAnRycsICdIJywgJ0knLCAnSicsICdLJywgJ0wnLAotICAgICAgICAgICAgICAgICAgJ00nLCAnTicsICdPJywgJ1AnLCAnUScsICdSJywgJ1MnLCAnVCcsICdVJywgJ1YnLCAnVycsICdYJywKLSAgICAgICAgICAgICAgICAgICdZJywgJ1onIH0pIH0sCi0KLSAgICAvL2xhbmd1YWdlIG9yaWVudGF0aW9uCi0gICAgeyAib3JpZW50YXRpb24iLCAiTGVmdFRvUmlnaHQiIH0sCi0KLSAgICAvL2xhbmd1YWdlIG51bWJlcmluZwotICAgIHsgIm51bWJlcmluZyIsICJhZGRpdGl2ZSIgfSwKLQotICAgIC8vIGxhcmdlc3QgbnVtZXJpY2FsIHZhbHVlCi0gICAgLy97Ik1heE51bWVyaWNhbFZhbHVlIiwgbmV3IEludGVnZXIoKX0sCi0gICAgLy9UaGVzZSB3b3VsZCBub3QgYmUgdXNlZCBmb3IgRU4uIE9ubHkgdXNlZCBmb3IgdHJhZGl0aW9uYWwgbnVtYmVyaW5nCi0gICAgLy97Im51bWJlckdyb3VwcyIsIG5ldyBpbnRbXXsxMCwxfX0sCi0gICAgLy9UaGVzZSBvbmx5IHVzZWQgZm9yIG11dGlwbGljYXRpdmUtYWRkaXRpdmUgbnVtYmVyaW5nCi0gICAgLy97Im11bHRpcGxpZXIiLCAiMTAifSwKLSAgICAvL3sibXVsdGlwbGllckNoYXIiLCAiTSJ9LAotICAgIC8veyJkaWdpdHMiLCBuZXcgY2hhcltdeydhJywnYicsJ2MnLCdkJywnZScsJ2YnLCdnJywnaCcsJ2knfX0sCi0gICAgLy97ImRpZ2l0cyIsIG5ldyBjaGFyW117MHgxMEQwLDB4MTBEMSwweDEwRDIsMHgxMEQzLDB4MTBENCwweDEwRDUsMHgxMEQ2LDB4MTBENywweDEwRDh9fSwKLSAgICAvL3sidGVucyIsIG5ldyBjaGFyW117MHgxMEQ5LDB4MTBEQSwweDEwREIsMHgxMERDLDB4MTBERCwweDEwREUsMHgxMERGLDB4MTBFMCwweDEwRTF9fSwKLSAgICAvL2h1bmRyZWRzLCBldGMuLi4KLSAgICAvL3sidGFibGVzIiwgbmV3IFN0cmluZ1tdeyJ0ZW5zIiwgImRpZ2l0cyJ9fQotICB9OwotICAvKioKLSAgICogR2V0IHRoZSBhc3NvY2lhdGlvbiBsaXN0LgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBhc3NvY2lhdGlvbiBsaXN0LgotICAgKi8KLSAgcHVibGljIE9iamVjdFtdW10gZ2V0Q29udGVudHMoKQotICB7Ci0gICAgICByZXR1cm4gX2NvbnRlbnRzOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9yZXMvWFJlc291cmNlc19lcy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvcmVzL1hSZXNvdXJjZXNfZXMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggY2QyYmI4MC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9yZXMvWFJlc291cmNlc19lcy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNzYgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogWFJlc291cmNlc19lcy5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE1IDA4OjE2OjA2IHN1cmVzaF9lbWFpbGlkIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5yZXM7Ci0KLS8vCi0vLyAgTGFuZ1Jlc291cmNlc19lcy5wcm9wZXJ0aWVzCi0vLwotCi0vKioKLSAqIFRoZSBTcGFuaXNoIHJlc291cmNlIGJ1bmRsZS4KLSAqIEB4c2wudXNhZ2UgaW50ZXJuYWwKLSAqLwotcHVibGljIGNsYXNzIFhSZXNvdXJjZXNfZXMgZXh0ZW5kcyBYUmVzb3VyY2VCdW5kbGUKLXsKLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgT2JqZWN0W11bXSBfY29udGVudHMgPSBuZXcgT2JqZWN0W11bXQotICB7Ci0gICAgeyAidWlfbGFuZ3VhZ2UiLCAiZXMiIH0sIHsgImhlbHBfbGFuZ3VhZ2UiLCAiZXMiIH0sIHsgImxhbmd1YWdlIiwgImVzIiB9LAotICAgIHsgImFscGhhYmV0IiwgbmV3IENoYXJBcnJheVdyYXBwZXIoCi0gICAgICBuZXcgY2hhcltdeyAnQScsICdCJywgJ0MnLCAnRCcsICdFJywgJ0YnLCAnRycsICdIJywgJ0knLCAnSicsICdLJywgJ0wnLAotICAgICAgICAgICAgICAgICAgJ00nLCAnTicsICdPJywgJ1AnLCAnUScsICdSJywgJ1MnLCAnVCcsICdVJywgJ1YnLCAnVycsICdYJywKLSAgICAgICAgICAgICAgICAgICdZJywgJ1onIH0pIH0sCi0gICAgeyAidHJhZEFscGhhYmV0IiwgbmV3IENoYXJBcnJheVdyYXBwZXIoCi0gICAgICBuZXcgY2hhcltdeyAnQScsICdCJywgJ0MnLCAnRCcsICdFJywgJ0YnLCAnRycsICdIJywgJ0knLCAnSicsICdLJywgJ0wnLAotICAgICAgICAgICAgICAgICAgJ00nLCAnTicsICdPJywgJ1AnLCAnUScsICdSJywgJ1MnLCAnVCcsICdVJywgJ1YnLCAnVycsICdYJywKLSAgICAgICAgICAgICAgICAgICdZJywgJ1onIH0pIH0sCi0KLSAgICAvL2xhbmd1YWdlIG9yaWVudGF0aW9uCi0gICAgeyAib3JpZW50YXRpb24iLCAiTGVmdFRvUmlnaHQiIH0sCi0KLSAgICAvL2xhbmd1YWdlIG51bWJlcmluZwotICAgIHsgIm51bWJlcmluZyIsICJhZGRpdGl2ZSIgfSwKLQotICAgIC8vIGxhcmdlc3QgbnVtZXJpY2FsIHZhbHVlCi0gICAgLy97Ik1heE51bWVyaWNhbFZhbHVlIiwgbmV3IEludGVnZXIoKX0sCi0gICAgLy9UaGVzZSB3b3VsZCBub3QgYmUgdXNlZCBmb3IgRU4uIE9ubHkgdXNlZCBmb3IgdHJhZGl0aW9uYWwgbnVtYmVyaW5nCi0gICAgLy97Im51bWJlckdyb3VwcyIsIG5ldyBpbnRbXXsxMCwxfX0sCi0gICAgLy9UaGVzZSBvbmx5IHVzZWQgZm9yIG11dGlwbGljYXRpdmUtYWRkaXRpdmUgbnVtYmVyaW5nCi0gICAgLy97Im11bHRpcGxpZXIiLCAiMTAifSwKLSAgICAvL3sibXVsdGlwbGllckNoYXIiLCAiTSJ9LAotICAgIC8veyJkaWdpdHMiLCBuZXcgY2hhcltdeydhJywnYicsJ2MnLCdkJywnZScsJ2YnLCdnJywnaCcsJ2knfX0sCi0gICAgLy97ImRpZ2l0cyIsIG5ldyBjaGFyW117MHgxMEQwLDB4MTBEMSwweDEwRDIsMHgxMEQzLDB4MTBENCwweDEwRDUsMHgxMEQ2LDB4MTBENywweDEwRDh9fSwKLSAgICAvL3sidGVucyIsIG5ldyBjaGFyW117MHgxMEQ5LDB4MTBEQSwweDEwREIsMHgxMERDLDB4MTBERCwweDEwREUsMHgxMERGLDB4MTBFMCwweDEwRTF9fSwKLSAgICAvL2h1bmRyZWRzLCBldGMuLi4KLSAgICAvL3sidGFibGVzIiwgbmV3IFN0cmluZ1tdeyJ0ZW5zIiwgImRpZ2l0cyJ9fQotICB9OwotCi0gIC8qKgotICAgKiBHZXQgdGhlIGFzc29jaWF0aW9uIGxpc3QuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGFzc29jaWF0aW9uIGxpc3QuCi0gICAqLwotICBwdWJsaWMgT2JqZWN0W11bXSBnZXRDb250ZW50cygpCi0gIHsKLSAgICByZXR1cm4gX2NvbnRlbnRzOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9yZXMvWFJlc291cmNlc19mci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvcmVzL1hSZXNvdXJjZXNfZnIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNzZkMDk5My4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9yZXMvWFJlc291cmNlc19mci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNzYgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogWFJlc291cmNlc19mci5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE1IDA4OjE2OjA2IHN1cmVzaF9lbWFpbGlkIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5yZXM7Ci0KLS8vCi0vLyAgTGFuZ1Jlc291cmNlc19mci5wcm9wZXJ0aWVzCi0vLwotCi0vKioKLSAqIFRoZSBGcmVuY2ggcmVzb3VyY2UgYnVuZGxlLgotICogQHhzbC51c2FnZSBpbnRlcm5hbAotICovCi1wdWJsaWMgY2xhc3MgWFJlc291cmNlc19mciBleHRlbmRzIFhSZXNvdXJjZUJ1bmRsZQotewotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBPYmplY3RbXVtdIF9jb250ZW50cyA9IG5ldyBPYmplY3RbXVtdCi0gIHsKLSAgICB7ICJ1aV9sYW5ndWFnZSIsICJmciIgfSwgeyAiaGVscF9sYW5ndWFnZSIsICJmciIgfSwgeyAibGFuZ3VhZ2UiLCAiZnIiIH0sCi0gICAgeyAiYWxwaGFiZXQiLCBuZXcgQ2hhckFycmF5V3JhcHBlcigKLSAgICAgIG5ldyBjaGFyW117ICdBJywgJ0InLCAnQycsICdEJywgJ0UnLCAnRicsICdHJywgJ0gnLCAnSScsICdKJywgJ0snLCAnTCcsCi0gICAgICAgICAgICAgICAgICAnTScsICdOJywgJ08nLCAnUCcsICdRJywgJ1InLCAnUycsICdUJywgJ1UnLCAnVicsICdXJywgJ1gnLAotICAgICAgICAgICAgICAgICAgJ1knLCAnWicgfSkgfSwKLSAgICB7ICJ0cmFkQWxwaGFiZXQiLCBuZXcgQ2hhckFycmF5V3JhcHBlcigKLSAgICAgIG5ldyBjaGFyW117ICdBJywgJ0InLCAnQycsICdEJywgJ0UnLCAnRicsICdHJywgJ0gnLCAnSScsICdKJywgJ0snLCAnTCcsCi0gICAgICAgICAgICAgICAgICAnTScsICdOJywgJ08nLCAnUCcsICdRJywgJ1InLCAnUycsICdUJywgJ1UnLCAnVicsICdXJywgJ1gnLAotICAgICAgICAgICAgICAgICAgJ1knLCAnWicgfSkgfSwKLQotICAgIC8vbGFuZ3VhZ2Ugb3JpZW50YXRpb24KLSAgICB7ICJvcmllbnRhdGlvbiIsICJMZWZ0VG9SaWdodCIgfSwKLQotICAgIC8vbGFuZ3VhZ2UgbnVtYmVyaW5nCi0gICAgeyAibnVtYmVyaW5nIiwgImFkZGl0aXZlIiB9LAotCi0gICAgLy8gbGFyZ2VzdCBudW1lcmljYWwgdmFsdWUKLSAgICAvL3siTWF4TnVtZXJpY2FsVmFsdWUiLCBuZXcgSW50ZWdlcigpfSwKLSAgICAvL1RoZXNlIHdvdWxkIG5vdCBiZSB1c2VkIGZvciBFTi4gT25seSB1c2VkIGZvciB0cmFkaXRpb25hbCBudW1iZXJpbmcKLSAgICAvL3sibnVtYmVyR3JvdXBzIiwgbmV3IGludFtdezEwLDF9fSwKLSAgICAvL1RoZXNlIG9ubHkgdXNlZCBmb3IgbXV0aXBsaWNhdGl2ZS1hZGRpdGl2ZSBudW1iZXJpbmcKLSAgICAvL3sibXVsdGlwbGllciIsICIxMCJ9LAotICAgIC8veyJtdWx0aXBsaWVyQ2hhciIsICJNIn0sCi0gICAgLy97ImRpZ2l0cyIsIG5ldyBjaGFyW117J2EnLCdiJywnYycsJ2QnLCdlJywnZicsJ2cnLCdoJywnaSd9fSwKLSAgICAvL3siZGlnaXRzIiwgbmV3IGNoYXJbXXsweDEwRDAsMHgxMEQxLDB4MTBEMiwweDEwRDMsMHgxMEQ0LDB4MTBENSwweDEwRDYsMHgxMEQ3LDB4MTBEOH19LAotICAgIC8veyJ0ZW5zIiwgbmV3IGNoYXJbXXsweDEwRDksMHgxMERBLDB4MTBEQiwweDEwREMsMHgxMERELDB4MTBERSwweDEwREYsMHgxMEUwLDB4MTBFMX19LAotICAgIC8vaHVuZHJlZHMsIGV0Yy4uLgotICAgIC8veyJ0YWJsZXMiLCBuZXcgU3RyaW5nW117InRlbnMiLCAiZGlnaXRzIn19Ci0gIH07Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgYXNzb2NpYXRpb24gbGlzdC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgYXNzb2NpYXRpb24gbGlzdC4KLSAgICovCi0gIHB1YmxpYyBPYmplY3RbXVtdIGdldENvbnRlbnRzKCkKLSAgewotICAgIHJldHVybiBfY29udGVudHM7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL3Jlcy9YUmVzb3VyY2VzX2l0LmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9yZXMvWFJlc291cmNlc19pdC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyZDk1ZGUzLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL3Jlcy9YUmVzb3VyY2VzX2l0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3NiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBYUmVzb3VyY2VzX2l0LmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTUgMDg6MTY6MDcgc3VyZXNoX2VtYWlsaWQgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLnJlczsKLQotLy8KLS8vICBMYW5nUmVzb3VyY2VzX2l0LnByb3BlcnRpZXMKLS8vCi0KLS8qKgotICogVGhlIEl0YWxpYW4gcmVzb3VyY2UgYnVuZGxlLgotICogQHhzbC51c2FnZSBpbnRlcm5hbAotICovCi1wdWJsaWMgY2xhc3MgWFJlc291cmNlc19pdCBleHRlbmRzIFhSZXNvdXJjZUJ1bmRsZQotewotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBPYmplY3RbXVtdIF9jb250ZW50cyA9IG5ldyBPYmplY3RbXVtdCi0gIHsKLSAgICB7ICJ1aV9sYW5ndWFnZSIsICJpdCIgfSwgeyAiaGVscF9sYW5ndWFnZSIsICJpdCIgfSwgeyAibGFuZ3VhZ2UiLCAiaXQiIH0sCi0gICAgeyAiYWxwaGFiZXQiLCBuZXcgQ2hhckFycmF5V3JhcHBlcigKLSAgICAgIG5ldyBjaGFyW117ICdBJywgJ0InLCAnQycsICdEJywgJ0UnLCAnRicsICdHJywgJ0gnLCAnSScsICdKJywgJ0snLCAnTCcsCi0gICAgICAgICAgICAgICAgICAnTScsICdOJywgJ08nLCAnUCcsICdRJywgJ1InLCAnUycsICdUJywgJ1UnLCAnVicsICdXJywgJ1gnLAotICAgICAgICAgICAgICAgICAgJ1knLCAnWicgfSkgfSwKLSAgICB7ICJ0cmFkQWxwaGFiZXQiLCBuZXcgQ2hhckFycmF5V3JhcHBlcigKLSAgICAgIG5ldyBjaGFyW117ICdBJywgJ0InLCAnQycsICdEJywgJ0UnLCAnRicsICdHJywgJ0gnLCAnSScsICdKJywgJ0snLCAnTCcsCi0gICAgICAgICAgICAgICAgICAnTScsICdOJywgJ08nLCAnUCcsICdRJywgJ1InLCAnUycsICdUJywgJ1UnLCAnVicsICdXJywgJ1gnLAotICAgICAgICAgICAgICAgICAgJ1knLCAnWicgfSkgfSwKLQotICAgIC8vbGFuZ3VhZ2Ugb3JpZW50YXRpb24KLSAgICB7ICJvcmllbnRhdGlvbiIsICJMZWZ0VG9SaWdodCIgfSwKLQotICAgIC8vbGFuZ3VhZ2UgbnVtYmVyaW5nCi0gICAgeyAibnVtYmVyaW5nIiwgImFkZGl0aXZlIiB9LAotCi0gICAgLy8gbGFyZ2VzdCBudW1lcmljYWwgdmFsdWUKLSAgICAvL3siTWF4TnVtZXJpY2FsVmFsdWUiLCBuZXcgSW50ZWdlcigpfSwKLSAgICAvL1RoZXNlIHdvdWxkIG5vdCBiZSB1c2VkIGZvciBFTi4gT25seSB1c2VkIGZvciB0cmFkaXRpb25hbCBudW1iZXJpbmcKLSAgICAvL3sibnVtYmVyR3JvdXBzIiwgbmV3IGludFtdezEwLDF9fSwKLSAgICAvL1RoZXNlIG9ubHkgdXNlZCBmb3IgbXV0aXBsaWNhdGl2ZS1hZGRpdGl2ZSBudW1iZXJpbmcKLSAgICAvL3sibXVsdGlwbGllciIsICIxMCJ9LAotICAgIC8veyJtdWx0aXBsaWVyQ2hhciIsICJNIn0sCi0gICAgLy97ImRpZ2l0cyIsIG5ldyBjaGFyW117J2EnLCdiJywnYycsJ2QnLCdlJywnZicsJ2cnLCdoJywnaSd9fSwKLSAgICAvL3siZGlnaXRzIiwgbmV3IGNoYXJbXXsweDEwRDAsMHgxMEQxLDB4MTBEMiwweDEwRDMsMHgxMEQ0LDB4MTBENSwweDEwRDYsMHgxMEQ3LDB4MTBEOH19LAotICAgIC8veyJ0ZW5zIiwgbmV3IGNoYXJbXXsweDEwRDksMHgxMERBLDB4MTBEQiwweDEwREMsMHgxMERELDB4MTBERSwweDEwREYsMHgxMEUwLDB4MTBFMX19LAotICAgIC8vaHVuZHJlZHMsIGV0Yy4uLgotICAgIC8veyJ0YWJsZXMiLCBuZXcgU3RyaW5nW117InRlbnMiLCAiZGlnaXRzIn19Ci0gIH07Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgYXNzb2NpYXRpb24gbGlzdC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgYXNzb2NpYXRpb24gbGlzdC4KLSAgICovCi0gIHB1YmxpYyBPYmplY3RbXVtdIGdldENvbnRlbnRzKCkKLSAgewotICAgIHJldHVybiBfY29udGVudHM7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL3Jlcy9YUmVzb3VyY2VzX2phX0pQX0EuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL3Jlcy9YUmVzb3VyY2VzX2phX0pQX0EuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYjI3Nzg1ZC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9yZXMvWFJlc291cmNlc19qYV9KUF9BLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4OSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBYUmVzb3VyY2VzX2phX0pQX0EuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNSAwODoxNjowNyBzdXJlc2hfZW1haWxpZCBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMucmVzOwotCi0vLwotLy8gIExhbmdSZXNvdXJjZXNfZW4ucHJvcGVydGllcwotLy8KLQotLyoqCi0gKiBUaGUgSmFwYW5lc2UgKEthdGFrYW5hKSByZXNvdXJjZSBidW5kbGUuCi0gKiBAeHNsLnVzYWdlIGludGVybmFsCi0gKi8KLXB1YmxpYyBjbGFzcyBYUmVzb3VyY2VzX2phX0pQX0EgZXh0ZW5kcyBYUmVzb3VyY2VCdW5kbGUKLXsKLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgT2JqZWN0W11bXSBfY29udGVudHMgPSBuZXcgT2JqZWN0W11bXQotICB7Ci0gICAgeyAidWlfbGFuZ3VhZ2UiLCAiamEiIH0sIHsgImhlbHBfbGFuZ3VhZ2UiLCAiamEiIH0sIHsgImxhbmd1YWdlIiwgImphIiB9LAotICAgIHsgImFscGhhYmV0IiwgbmV3IENoYXJBcnJheVdyYXBwZXIoCi0gICAgICBuZXcgY2hhcltdeyAweDMwYTIsIDB4MzBhNCwgMHgzMGE2LCAweDMwYTgsIDB4MzBhYSwgMHgzMGFiLCAweDMwYWQsCi0gICAgICAgICAgICAgICAgICAweDMwYWYsIDB4MzBiMSwgMHgzMGIzLCAweDMwYjUsIDB4MzBiNywgMHgzMGI5LCAweDMwYmIsCi0gICAgICAgICAgICAgICAgICAweDMwYmQsIDB4MzBiZiwgMHgzMGMxLCAweDMwYzQsIDB4MzBjNiwgMHgzMGM4LCAweDMwY2EsCi0gICAgICAgICAgICAgICAgICAweDMwY2IsIDB4MzBjYywgMHgzMGNkLCAweDMwY2UsIDB4MzBjZiwgMHgzMGQyLCAweDMwZDUsCi0gICAgICAgICAgICAgICAgICAweDMwZDgsIDB4MzBkYiwgMHgzMGRlLCAweDMwZGYsIDB4MzBlMCwgMHgzMGUxLCAweDMwZTIsCi0gICAgICAgICAgICAgICAgICAweDMwZTQsIDB4MzBlNiwgMHgzMGU4LCAweDMwZTksIDB4MzBlYSwgMHgzMGViLCAweDMwZWMsCi0gICAgICAgICAgICAgICAgICAweDMwZWQsIDB4MzBlZiwgMHgzMGYwLCAweDMwZjEsIDB4MzBmMiwgMHgzMGYzIH0pIH0sCi0gICAgeyAidHJhZEFscGhhYmV0IiwgbmV3IENoYXJBcnJheVdyYXBwZXIoCi0gICAgICBuZXcgY2hhcltdeyAnQScsICdCJywgJ0MnLCAnRCcsICdFJywgJ0YnLCAnRycsICdIJywgJ0knLCAnSicsICdLJywgJ0wnLAotICAgICAgICAgICAgICAgICAgJ00nLCAnTicsICdPJywgJ1AnLCAnUScsICdSJywgJ1MnLCAnVCcsICdVJywgJ1YnLCAnVycsICdYJywKLSAgICAgICAgICAgICAgICAgICdZJywgJ1onIH0pIH0sCi0KLSAgICAvL2xhbmd1YWdlIG9yaWVudGF0aW9uCi0gICAgeyAib3JpZW50YXRpb24iLCAiTGVmdFRvUmlnaHQiIH0sCi0KLSAgICAvL2xhbmd1YWdlIG51bWJlcmluZwotICAgIHsgIm51bWJlcmluZyIsICJtdWx0aXBsaWNhdGl2ZS1hZGRpdGl2ZSIgfSwKLSAgICB7ICJtdWx0aXBsaWVyT3JkZXIiLCAiZm9sbG93cyIgfSwKLQotICAgIC8vIGxhcmdlc3QgbnVtZXJpY2FsIHZhbHVlCi0gICAgLy97Ik1heE51bWVyaWNhbFZhbHVlIiwgbmV3IEludGVnZXIoMTAwMDAwMDAwMDApfSwKLSAgICAvL1RoZXNlIHdvdWxkIG5vdCBiZSB1c2VkIGZvciBFTi4gT25seSB1c2VkIGZvciB0cmFkaXRpb25hbCBudW1iZXJpbmcKLSAgICB7ICJudW1iZXJHcm91cHMiLCBuZXcgSW50QXJyYXlXcmFwcGVyKG5ldyBpbnRbXXsgMSB9KSB9LAotCi0gICAgLy9UaGVzZSBvbmx5IHVzZWQgZm9yIG11dGlwbGljYXRpdmUtYWRkaXRpdmUgbnVtYmVyaW5nCi0gICAgLy8gTm90ZSB0aGF0IHdlIGFyZSB1c2luZyBsb25ncyBhbmQgdGhhdCB0aGUgbGFzdCB0d28KLSAgICAvLyBtdWx0aXBsaWVycyBhcmUgbm90IHN1cHBvcnRlZC4gVGhpcyBpcyBhIGtub3duIGxpbWl0YXRpb24uCi0gICAgeyAibXVsdGlwbGllciIsIG5ldyBMb25nQXJyYXlXcmFwcGVyKAotICAgICAgbmV3IGxvbmdbXXsgTG9uZy5NQVhfVkFMVUUsIExvbmcuTUFYX1ZBTFVFLCAxMDAwMDAwMDAsIDEwMDAwLCAxMDAwLAotICAgICAgICAgIDEwMCwgMTAgfSkgfSwKLSAgICB7ICJtdWx0aXBsaWVyQ2hhciIsIG5ldyBDaGFyQXJyYXlXcmFwcGVyKAotICAgICAgbmV3IGNoYXJbXXsgMHg0RUFDLCAweDUxNDYsIDB4NTEwNCwgMHg0RTA3LCAweDUzNDMsIDB4NzY3ZSwgMHg1MzQxIH0pIH0sCi0KLSAgICAvLyBjaGluZXNlIG9ubHk/Ci0gICAgeyAiemVybyIsIG5ldyBDaGFyQXJyYXlXcmFwcGVyKG5ldyBjaGFyWzBdKSB9LAotICAgIHsgImRpZ2l0cyIsIG5ldyBDaGFyQXJyYXlXcmFwcGVyKAotICAgICAgbmV3IGNoYXJbXXsgMHg0RTAwLCAweDRFOEMsIDB4NEUwOSwgMHg1NkRCLCAweDRFOTQsIDB4NTE2RCwgMHg0RTAzLAotICAgICAgICAgICAgICAgICAgMHg1MTZCLCAweDRFNUQgfSkgfSwgeyAidGFibGVzIiwgbmV3IFN0cmluZ0FycmF5V3JhcHBlcigKLSAgICAgICAgICAgICAgICAgICAgICBuZXcgU3RyaW5nW117ICJkaWdpdHMiIH0pIH0KLSAgfTsKLQotICAvKioKLSAgICogR2V0IHRoZSBhc3NvY2lhdGlvbiBsaXN0LgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBhc3NvY2lhdGlvbiBsaXN0LgotICAgKi8KLSAgcHVibGljIE9iamVjdFtdW10gZ2V0Q29udGVudHMoKQotICB7Ci0gICAgcmV0dXJuIF9jb250ZW50czsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvcmVzL1hSZXNvdXJjZXNfamFfSlBfSEEuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL3Jlcy9YUmVzb3VyY2VzX2phX0pQX0hBLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDJmYzg3N2IuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvcmVzL1hSZXNvdXJjZXNfamFfSlBfSEEuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDg5ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFhSZXNvdXJjZXNfamFfSlBfSEEuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNSAwODoxNjowNyBzdXJlc2hfZW1haWxpZCBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMucmVzOwotCi0vLwotLy8gIExhbmdSZXNvdXJjZXNfZW4ucHJvcGVydGllcwotLy8KLQotLyoqCi0gKiBUaGUgSmFwYW5lc2UgKEhpcmFnYW5hKSByZXNvdXJjZSBidW5kbGUuCi0gKiBAeHNsLnVzYWdlIGludGVybmFsCi0gKi8KLXB1YmxpYyBjbGFzcyBYUmVzb3VyY2VzX2phX0pQX0hBIGV4dGVuZHMgWFJlc291cmNlQnVuZGxlCi17Ci0gIHByaXZhdGUgc3RhdGljIGZpbmFsIE9iamVjdFtdW10gX2NvbnRlbnRzID0gbmV3IE9iamVjdFtdW10KLSAgewotICAgIHsgInVpX2xhbmd1YWdlIiwgImphIiB9LCB7ICJoZWxwX2xhbmd1YWdlIiwgImphIiB9LCB7ICJsYW5ndWFnZSIsICJqYSIgfSwKLSAgICB7ICJhbHBoYWJldCIsIG5ldyBDaGFyQXJyYXlXcmFwcGVyKAotICAgICAgbmV3IGNoYXJbXXsgMHgzMDQyLCAweDMwNDQsIDB4MzA0NiwgMHgzMDQ4LCAweDMwNGEsIDB4MzA0YiwgMHgzMDRkLAotICAgICAgICAgICAgICAgICAgMHgzMDRmLCAweDMwNTEsIDB4MzA1MywgMHgzMDU1LCAweDMwNTcsIDB4MzA1OSwgMHgzMDViLAotICAgICAgICAgICAgICAgICAgMHgzMDVkLCAweDMwNWYsIDB4MzA2MSwgMHgzMDY0LCAweDMwNjYsIDB4MzA2OCwgMHgzMDZhLAotICAgICAgICAgICAgICAgICAgMHgzMDZiLCAweDMwNmMsIDB4MzA2ZCwgMHgzMDZlLCAweDMwNmYsIDB4MzA3MiwgMHgzMDc1LAotICAgICAgICAgICAgICAgICAgMHgzMDc4LCAweDMwN2IsIDB4MzA3ZSwgMHgzMDdmLCAweDMwODAsIDB4MzA4MSwgMHgzMDgyLAotICAgICAgICAgICAgICAgICAgMHgzMDg0LCAweDMwODYsIDB4MzA4OCwgMHgzMDg5LCAweDMwOGEsIDB4MzA4YiwgMHgzMDhjLAotICAgICAgICAgICAgICAgICAgMHgzMDhkLCAweDMwOGYsIDB4MzA5MCwgMHgzMDkxLCAweDMwOTIsIDB4MzA5MyB9KSB9LAotICAgIHsgInRyYWRBbHBoYWJldCIsIG5ldyBDaGFyQXJyYXlXcmFwcGVyKAotICAgICAgbmV3IGNoYXJbXXsgJ0EnLCAnQicsICdDJywgJ0QnLCAnRScsICdGJywgJ0cnLCAnSCcsICdJJywgJ0onLCAnSycsICdMJywKLSAgICAgICAgICAgICAgICAgICdNJywgJ04nLCAnTycsICdQJywgJ1EnLCAnUicsICdTJywgJ1QnLCAnVScsICdWJywgJ1cnLCAnWCcsCi0gICAgICAgICAgICAgICAgICAnWScsICdaJyB9KSB9LAotCi0gICAgLy9sYW5ndWFnZSBvcmllbnRhdGlvbgotICAgIHsgIm9yaWVudGF0aW9uIiwgIkxlZnRUb1JpZ2h0IiB9LAotCi0gICAgLy9sYW5ndWFnZSBudW1iZXJpbmcKLSAgICB7ICJudW1iZXJpbmciLCAibXVsdGlwbGljYXRpdmUtYWRkaXRpdmUiIH0sCi0gICAgeyAibXVsdGlwbGllck9yZGVyIiwgImZvbGxvd3MiIH0sCi0KLSAgICAvLyBsYXJnZXN0IG51bWVyaWNhbCB2YWx1ZQotICAgIC8veyJNYXhOdW1lcmljYWxWYWx1ZSIsIG5ldyBJbnRlZ2VyKDEwMDAwMDAwMDAwKX0sCi0gICAgLy9UaGVzZSB3b3VsZCBub3QgYmUgdXNlZCBmb3IgRU4uIE9ubHkgdXNlZCBmb3IgdHJhZGl0aW9uYWwgbnVtYmVyaW5nCi0gICAgeyAibnVtYmVyR3JvdXBzIiwgbmV3IEludEFycmF5V3JhcHBlcihuZXcgaW50W117IDEgfSkgfSwKLQotICAgIC8vVGhlc2Ugb25seSB1c2VkIGZvciBtdXRpcGxpY2F0aXZlLWFkZGl0aXZlIG51bWJlcmluZwotICAgIC8vIE5vdGUgdGhhdCB3ZSBhcmUgdXNpbmcgbG9uZ3MgYW5kIHRoYXQgdGhlIGxhc3QgdHdvCi0gICAgLy8gbXVsdGlwbGllcnMgYXJlIG5vdCBzdXBwb3J0ZWQuIFRoaXMgaXMgYSBrbm93biBsaW1pdGF0aW9uLgotICAgIHsgIm11bHRpcGxpZXIiLCBuZXcgTG9uZ0FycmF5V3JhcHBlcigKLSAgICAgIG5ldyBsb25nW117IExvbmcuTUFYX1ZBTFVFLCBMb25nLk1BWF9WQUxVRSwgMTAwMDAwMDAwLCAxMDAwMCwgMTAwMCwKLSAgICAgICAgICAxMDAsIDEwIH0pIH0sCi0gICAgeyAibXVsdGlwbGllckNoYXIiLCBuZXcgQ2hhckFycmF5V3JhcHBlcigKLSAgICAgIG5ldyBjaGFyW117IDB4NEVBQywgMHg1MTQ2LCAweDUxMDQsIDB4NEUwNywgMHg1MzQzLCAweDc2N2UsIDB4NTM0MSB9KSB9LAotCi0gICAgLy8gY2hpbmVzZSBvbmx5PwotICAgIHsgInplcm8iLCBuZXcgQ2hhckFycmF5V3JhcHBlcihuZXcgY2hhclswXSkgfSwKLSAgICB7ICJkaWdpdHMiLCBuZXcgQ2hhckFycmF5V3JhcHBlcigKLSAgICAgIG5ldyBjaGFyW117IDB4NEUwMCwgMHg0RThDLCAweDRFMDksIDB4NTZEQiwgMHg0RTk0LCAweDUxNkQsIDB4NEUwMywKLSAgICAgICAgICAgICAgICAgIDB4NTE2QiwgMHg0RTVEIH0pIH0sIHsgInRhYmxlcyIsIG5ldyBTdHJpbmdBcnJheVdyYXBwZXIoCi0gICAgICAgICAgICAgICAgICAgICAgbmV3IFN0cmluZ1tdeyAiZGlnaXRzIiB9KSB9Ci0gIH07Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgYXNzb2NpYXRpb24gbGlzdC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgYXNzb2NpYXRpb24gbGlzdC4KLSAgICovCi0gIHB1YmxpYyBPYmplY3RbXVtdIGdldENvbnRlbnRzKCkKLSAgewotICAgIHJldHVybiBfY29udGVudHM7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL3Jlcy9YUmVzb3VyY2VzX2phX0pQX0hJLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9yZXMvWFJlc291cmNlc19qYV9KUF9ISS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhMWE1ZjUzLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL3Jlcy9YUmVzb3VyY2VzX2phX0pQX0hJLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5MCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBYUmVzb3VyY2VzX2phX0pQX0hJLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTUgMDg6MTY6MDcgc3VyZXNoX2VtYWlsaWQgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLnJlczsKLQotLy8KLS8vICBMYW5nUmVzb3VyY2VzX2VuLnByb3BlcnRpZXMKLS8vCi0KLS8qKgotICogVGhlIEphcGFuZXNlIChIaXJhZ2FuYSkgcmVzb3VyY2UgYnVuZGxlLgotICogQHhzbC51c2FnZSBpbnRlcm5hbAotICovCi1wdWJsaWMgY2xhc3MgWFJlc291cmNlc19qYV9KUF9ISSBleHRlbmRzIFhSZXNvdXJjZUJ1bmRsZQotewotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBPYmplY3RbXVtdIF9jb250ZW50cyA9IG5ldyBPYmplY3RbXVtdCi0gIHsKLSAgICB7ICJ1aV9sYW5ndWFnZSIsICJqYSIgfSwgeyAiaGVscF9sYW5ndWFnZSIsICJqYSIgfSwgeyAibGFuZ3VhZ2UiLCAiamEiIH0sCi0gICAgeyAiYWxwaGFiZXQiLCBuZXcgQ2hhckFycmF5V3JhcHBlcigKLSAgICAgIG5ldyBjaGFyW117IDB4MzA0NCwgMHgzMDhkLCAweDMwNmYsIDB4MzA2YiwgMHgzMDdiLCAweDMwNzgsIDB4MzA2OCwKLSAgICAgICAgICAgICAgICAgIDB4MzA2MSwgMHgzMDhhLCAweDMwNmMsIDB4MzA4YiwgMHgzMDkyLCAweDMwOGYsIDB4MzA0YiwKLSAgICAgICAgICAgICAgICAgIDB4MzA4OCwgMHgzMDVmLCAweDMwOGMsIDB4MzA1ZCwgMHgzMDY0LCAweDMwNmQsIDB4MzA2YSwKLSAgICAgICAgICAgICAgICAgIDB4MzA4OSwgMHgzMDgwLCAweDMwNDYsIDB4MzA5MCwgMHgzMDZlLCAweDMwNGEsIDB4MzA0ZiwKLSAgICAgICAgICAgICAgICAgIDB4MzA4NCwgMHgzMDdlLCAweDMwNTEsIDB4MzA3NSwgMHgzMDUzLCAweDMwNDgsIDB4MzA2NiwKLSAgICAgICAgICAgICAgICAgIDB4MzA0MiwgMHgzMDU1LCAweDMwNGQsIDB4MzA4NiwgMHgzMDgxLCAweDMwN2YsIDB4MzA1NywKLSAgICAgICAgICAgICAgICAgIDB4MzA5MSwgMHgzMDcyLCAweDMwODIsIDB4MzA1YiwgMHgzMDU5IH0pIH0sCi0gICAgeyAidHJhZEFscGhhYmV0IiwgbmV3IENoYXJBcnJheVdyYXBwZXIoCi0gICAgICBuZXcgY2hhcltdeyAnQScsICdCJywgJ0MnLCAnRCcsICdFJywgJ0YnLCAnRycsICdIJywgJ0knLCAnSicsICdLJywgJ0wnLAotICAgICAgICAgICAgICAgICAgJ00nLCAnTicsICdPJywgJ1AnLCAnUScsICdSJywgJ1MnLCAnVCcsICdVJywgJ1YnLCAnVycsICdYJywKLSAgICAgICAgICAgICAgICAgICdZJywgJ1onIH0pIH0sCi0KLSAgICAvL2xhbmd1YWdlIG9yaWVudGF0aW9uCi0gICAgeyAib3JpZW50YXRpb24iLCAiTGVmdFRvUmlnaHQiIH0sCi0KLSAgICAvL2xhbmd1YWdlIG51bWJlcmluZwotICAgIHsgIm51bWJlcmluZyIsICJtdWx0aXBsaWNhdGl2ZS1hZGRpdGl2ZSIgfSwKLSAgICB7ICJtdWx0aXBsaWVyT3JkZXIiLCAiZm9sbG93cyIgfSwKLQotICAgIC8vIGxhcmdlc3QgbnVtZXJpY2FsIHZhbHVlCi0gICAgLy97Ik1heE51bWVyaWNhbFZhbHVlIiwgbmV3IEludGVnZXIoMTAwMDAwMDAwMDApfSwKLSAgICAvL1RoZXNlIHdvdWxkIG5vdCBiZSB1c2VkIGZvciBFTi4gT25seSB1c2VkIGZvciB0cmFkaXRpb25hbCBudW1iZXJpbmcKLSAgICB7ICJudW1iZXJHcm91cHMiLCBuZXcgSW50QXJyYXlXcmFwcGVyKG5ldyBpbnRbXXsgMSB9KSB9LAotCi0gICAgLy9UaGVzZSBvbmx5IHVzZWQgZm9yIG11dGlwbGljYXRpdmUtYWRkaXRpdmUgbnVtYmVyaW5nCi0gICAgLy8gTm90ZSB0aGF0IHdlIGFyZSB1c2luZyBsb25ncyBhbmQgdGhhdCB0aGUgbGFzdCB0d28KLSAgICAvLyBtdWx0aXBsaWVycyBhcmUgbm90IHN1cHBvcnRlZC4gVGhpcyBpcyBhIGtub3duIGxpbWl0YXRpb24uCi0gICAgeyAibXVsdGlwbGllciIsIG5ldyBMb25nQXJyYXlXcmFwcGVyKAotICAgICAgbmV3IGxvbmdbXXsgTG9uZy5NQVhfVkFMVUUsIExvbmcuTUFYX1ZBTFVFLCAxMDAwMDAwMDAsIDEwMDAwLCAxMDAwLAotICAgICAgICAgIDEwMCwgMTAgfSkgfSwKLSAgICB7ICJtdWx0aXBsaWVyQ2hhciIsIG5ldyBDaGFyQXJyYXlXcmFwcGVyKAotICAgICAgbmV3IGNoYXJbXXsgMHg0RUFDLCAweDUxNDYsIDB4NTEwNCwgMHg0RTA3LCAweDUzNDMsIDB4NzY3ZSwgMHg1MzQxIH0pIH0sCi0KLSAgICAvLyBjaGluZXNlIG9ubHk/PwotICAgIHsgInplcm8iLCBuZXcgQ2hhckFycmF5V3JhcHBlcihuZXcgY2hhclswXSkgfSwKLSAgICB7ICJkaWdpdHMiLCBuZXcgQ2hhckFycmF5V3JhcHBlcigKLSAgICAgIG5ldyBjaGFyW117IDB4NEUwMCwgMHg0RThDLCAweDRFMDksIDB4NTZEQiwgMHg0RTk0LCAweDUxNkQsIDB4NEUwMywKLSAgICAgICAgICAgICAgICAgIDB4NTE2QiwgMHg0RTVEIH0pIH0sIHsgInRhYmxlcyIsIG5ldyBTdHJpbmdBcnJheVdyYXBwZXIoCi0gICAgICAgICAgICAgICAgICAgICAgbmV3IFN0cmluZ1tdeyAiZGlnaXRzIiB9KSB9Ci0gIH07Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgYXNzb2NpYXRpb24gdGFibGUgZm9yIHRoaXMgcmVzb3VyY2UuCi0gICAqCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIGFzc29jaWF0aW9uIHRhYmxlIGZvciB0aGlzIHJlc291cmNlLgotICAgKi8KLSAgcHVibGljIE9iamVjdFtdW10gZ2V0Q29udGVudHMoKQotICB7Ci0gICAgcmV0dXJuIF9jb250ZW50czsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvcmVzL1hSZXNvdXJjZXNfamFfSlBfSS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvcmVzL1hSZXNvdXJjZXNfamFfSlBfSS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxZjUzZTkzLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL3Jlcy9YUmVzb3VyY2VzX2phX0pQX0kuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDg5ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFhSZXNvdXJjZXNfamFfSlBfSS5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE1IDA4OjE2OjA3IHN1cmVzaF9lbWFpbGlkIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5yZXM7Ci0KLS8vCi0vLyAgTGFuZ1Jlc291cmNlc19lbi5wcm9wZXJ0aWVzCi0vLwotCi0vKioKLSAqIFRoZSBKYXBhbmVzZSAoS2F0YWthbmEpIHJlc291cmNlIGJ1bmRsZS4KLSAqIEB4c2wudXNhZ2UgaW50ZXJuYWwKLSAqLwotcHVibGljIGNsYXNzIFhSZXNvdXJjZXNfamFfSlBfSSBleHRlbmRzIFhSZXNvdXJjZUJ1bmRsZQotewotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBPYmplY3RbXVtdIF9jb250ZW50cyA9IG5ldyBPYmplY3RbXVtdCi0gIHsKLSAgICB7ICJ1aV9sYW5ndWFnZSIsICJqYSIgfSwgeyAiaGVscF9sYW5ndWFnZSIsICJqYSIgfSwgeyAibGFuZ3VhZ2UiLCAiamEiIH0sCi0gICAgeyAiYWxwaGFiZXQiLCBuZXcgQ2hhckFycmF5V3JhcHBlcigKLSAgICAgIG5ldyBjaGFyW117IDB4MzBhNCwgMHgzMGVkLCAweDMwY2YsIDB4MzBjYiwgMHgzMGRiLCAweDMwZDgsIDB4MzBjOCwKLSAgICAgICAgICAgICAgICAgIDB4MzBjMSwgMHgzMGVhLCAweDMwY2MsIDB4MzBlYiwgMHgzMGYyLCAweDMwZWYsIDB4MzBhYiwKLSAgICAgICAgICAgICAgICAgIDB4MzBlOCwgMHgzMGJmLCAweDMwZWMsIDB4MzBiZCwgMHgzMGM0LCAweDMwY2QsIDB4MzBjYSwKLSAgICAgICAgICAgICAgICAgIDB4MzBlOSwgMHgzMGUwLCAweDMwYTYsIDB4MzBmMCwgMHgzMGNlLCAweDMwYWEsIDB4MzBhZiwKLSAgICAgICAgICAgICAgICAgIDB4MzBlNCwgMHgzMGRlLCAweDMwYjEsIDB4MzBkNSwgMHgzMGIzLCAweDMwYTgsIDB4MzBjNiwKLSAgICAgICAgICAgICAgICAgIDB4MzBhMiwgMHgzMGI1LCAweDMwYWQsIDB4MzBlNiwgMHgzMGUxLCAweDMwZGYsIDB4MzBiNywKLSAgICAgICAgICAgICAgICAgIDB4MzBmMSwgMHgzMGQyLCAweDMwZTIsIDB4MzBiYiwgMHgzMGI5IH0pIH0sCi0gICAgeyAidHJhZEFscGhhYmV0IiwgbmV3IENoYXJBcnJheVdyYXBwZXIoCi0gICAgICBuZXcgY2hhcltdeyAnQScsICdCJywgJ0MnLCAnRCcsICdFJywgJ0YnLCAnRycsICdIJywgJ0knLCAnSicsICdLJywgJ0wnLAotICAgICAgICAgICAgICAgICAgJ00nLCAnTicsICdPJywgJ1AnLCAnUScsICdSJywgJ1MnLCAnVCcsICdVJywgJ1YnLCAnVycsICdYJywKLSAgICAgICAgICAgICAgICAgICdZJywgJ1onIH0pIH0sCi0KLSAgICAvL2xhbmd1YWdlIG9yaWVudGF0aW9uCi0gICAgeyAib3JpZW50YXRpb24iLCAiTGVmdFRvUmlnaHQiIH0sCi0KLSAgICAvL2xhbmd1YWdlIG51bWJlcmluZwotICAgIHsgIm51bWJlcmluZyIsICJtdWx0aXBsaWNhdGl2ZS1hZGRpdGl2ZSIgfSwKLSAgICB7ICJtdWx0aXBsaWVyT3JkZXIiLCAiZm9sbG93cyIgfSwKLQotICAgIC8vIGxhcmdlc3QgbnVtZXJpY2FsIHZhbHVlCi0gICAgLy97Ik1heE51bWVyaWNhbFZhbHVlIiwgbmV3IEludGVnZXIoMTAwMDAwMDAwMDApfSwKLSAgICAvL1RoZXNlIHdvdWxkIG5vdCBiZSB1c2VkIGZvciBFTi4gT25seSB1c2VkIGZvciB0cmFkaXRpb25hbCBudW1iZXJpbmcKLSAgICB7ICJudW1iZXJHcm91cHMiLCBuZXcgSW50QXJyYXlXcmFwcGVyKG5ldyBpbnRbXXsgMSB9KSB9LAotCi0gICAgLy9UaGVzZSBvbmx5IHVzZWQgZm9yIG11dGlwbGljYXRpdmUtYWRkaXRpdmUgbnVtYmVyaW5nCi0gICAgLy8gTm90ZSB0aGF0IHdlIGFyZSB1c2luZyBsb25ncyBhbmQgdGhhdCB0aGUgbGFzdCB0d28KLSAgICAvLyBtdWx0aXBsaWVycyBhcmUgbm90IHN1cHBvcnRlZC4gVGhpcyBpcyBhIGtub3duIGxpbWl0YXRpb24uCi0gICAgeyAibXVsdGlwbGllciIsIG5ldyBMb25nQXJyYXlXcmFwcGVyKAotICAgICAgbmV3IGxvbmdbXXsgTG9uZy5NQVhfVkFMVUUsIExvbmcuTUFYX1ZBTFVFLCAxMDAwMDAwMDAsIDEwMDAwLCAxMDAwLCAxMDAsIDEwIH0pIH0sCi0gICAgeyAibXVsdGlwbGllckNoYXIiLCBuZXcgQ2hhckFycmF5V3JhcHBlcigKLSAgICAgIG5ldyBjaGFyW117IDB4NEVBQywgMHg1MTQ2LCAweDUxMDQsIDB4NEUwNywgMHg1MzQzLCAweDc2N2UsIDB4NTM0MSB9KSB9LAotCi0gICAgLy8gY2hpbmVzZSBvbmx5Pz8KLSAgICB7ICJ6ZXJvIiwgbmV3IENoYXJBcnJheVdyYXBwZXIobmV3IGNoYXJbMF0pIH0sCi0gICAgeyAiZGlnaXRzIiwgbmV3IENoYXJBcnJheVdyYXBwZXIoCi0gICAgICBuZXcgY2hhcltdeyAweDRFMDAsIDB4NEU4QywgMHg0RTA5LCAweDU2REIsIDB4NEU5NCwgMHg1MTZELCAweDRFMDMsCi0gICAgICAgICAgICAgICAgICAweDUxNkIsIDB4NEU1RCB9KSB9LCB7ICJ0YWJsZXMiLCBuZXcgU3RyaW5nQXJyYXlXcmFwcGVyKAotICAgICAgICAgICAgICAgICAgICAgIG5ldyBTdHJpbmdbXXsgImRpZ2l0cyIgfSkgfQotICB9OwotCi0gIC8qKgotICAgKiBHZXQgdGhlIGFzc29jaWF0aW9uIHRhYmxlIGZvciB0aGlzIHJlc291cmNlLgotICAgKgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBhc3NvY2lhdGlvbiB0YWJsZSBmb3IgdGhpcyByZXNvdXJjZS4KLSAgICovCi0gIHB1YmxpYyBPYmplY3RbXVtdIGdldENvbnRlbnRzKCkKLSAgewotICAgIHJldHVybiBfY29udGVudHM7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL3Jlcy9YUmVzb3VyY2VzX2tvLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9yZXMvWFJlc291cmNlc19rby5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA5ODFkOWE5Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL3Jlcy9YUmVzb3VyY2VzX2tvLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4MyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBYUmVzb3VyY2VzX2tvLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTUgMDg6MTY6MDggc3VyZXNoX2VtYWlsaWQgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLnJlczsKLQotLy8KLS8vICBMYW5nUmVzb3VyY2VzX2tvLnByb3BlcnRpZXMKLS8vCi0KLS8qKgotICogVGhlIEtvcmVhbiByZXNvdXJjZSBidW5kbGUuCi0gKiBAeHNsLnVzYWdlIGludGVybmFsCi0gKi8KLXB1YmxpYyBjbGFzcyBYUmVzb3VyY2VzX2tvIGV4dGVuZHMgWFJlc291cmNlQnVuZGxlCi17Ci0gIHByaXZhdGUgc3RhdGljIGZpbmFsIE9iamVjdFtdW10gX2NvbnRlbnRzID0gbmV3IE9iamVjdFtdW10KLSAgewotICAgIHsgInVpX2xhbmd1YWdlIiwgImtvIiB9LCB7ICJoZWxwX2xhbmd1YWdlIiwgImtvIiB9LCB7ICJsYW5ndWFnZSIsICJrbyIgfSwKLSAgICB7ICJhbHBoYWJldCIsIG5ldyBDaGFyQXJyYXlXcmFwcGVyKAotICAgICAgbmV3IGNoYXJbXXsgMHgzMTMxLCAweDMxMzQsIDB4MzEzNywgMHgzMTM5LCAweDMxNDEsIDB4MzE0MiwgMHgzMTQ1LAotICAgICAgICAgICAgICAgICAgMHgzMTQ3LCAweDMxNDgsIDB4MzE0YSwgMHgzMTRiLCAweDMxNGMsIDB4MzE0ZCwgMHgzMTRlLAotICAgICAgICAgICAgICAgICAgMHgzMTRmLCAweDMxNTEsIDB4MzE1MywgMHgzMTU1LCAweDMxNTcsIDB4MzE1YiwgMHgzMTVjLAotICAgICAgICAgICAgICAgICAgMHgzMTYwLCAweDMxNjEsIDB4MzE2M30pfSwKLSAgICB7ICJ0cmFkQWxwaGFiZXQiLCBuZXcgQ2hhckFycmF5V3JhcHBlcigKLSAgICAgIG5ldyBjaGFyW117ICdBJywgJ0InLCAnQycsICdEJywgJ0UnLCAnRicsICdHJywgJ0gnLCAnSScsICdKJywgJ0snLCAnTCcsCi0gICAgICAgICAgICAgICAgICAnTScsICdOJywgJ08nLCAnUCcsICdRJywgJ1InLCAnUycsICdUJywgJ1UnLCAnVicsICdXJywgJ1gnLAotICAgICAgICAgICAgICAgICAgJ1knLCAnWicgfSkgfSwKLQotICAgIC8vbGFuZ3VhZ2Ugb3JpZW50YXRpb24KLSAgICB7ICJvcmllbnRhdGlvbiIsICJMZWZ0VG9SaWdodCIgfSwKLQotICAgIC8vbGFuZ3VhZ2UgbnVtYmVyaW5nCi0gICAgeyAibnVtYmVyaW5nIiwgIm11bHRpcGxpY2F0aXZlLWFkZGl0aXZlIiB9LAotICAgIHsgIm11bHRpcGxpZXJPcmRlciIsICJmb2xsb3dzIiB9LAotCi0gICAgLy8gbGFyZ2VzdCBudW1lcmljYWwgdmFsdWUKLSAgICAvL3siTWF4TnVtZXJpY2FsVmFsdWUiLCBuZXcgSW50ZWdlcigxMDAwMDAwMDApfSwKLSAgICAvL1RoZXNlIHdvdWxkIG5vdCBiZSB1c2VkIGZvciBFTi4gT25seSB1c2VkIGZvciB0cmFkaXRpb25hbCBudW1iZXJpbmcKLSAgICB7ICJudW1iZXJHcm91cHMiLCBuZXcgSW50QXJyYXlXcmFwcGVyKG5ldyBpbnRbXXsgMSB9KSB9LAotCi0gICAgLy8gY2hpbmVzZSBvbmx5ID8/Ci0gICAgeyAiemVybyIsIG5ldyBDaGFyQXJyYXlXcmFwcGVyKG5ldyBjaGFyWzBdKSB9LAotCi0gICAgLy9UaGVzZSBvbmx5IHVzZWQgZm9yIG11dGlwbGljYXRpdmUtYWRkaXRpdmUgbnVtYmVyaW5nCi0gICAgeyAibXVsdGlwbGllciIsIG5ldyBMb25nQXJyYXlXcmFwcGVyKG5ldyBsb25nW117IDEwMDAwMDAwMCwgMTAwMDAsIDEwMDAsCi0gICAgICAgIDEwMCwgMTAgfSkgfSwKLSAgICB7ICJtdWx0aXBsaWVyQ2hhciIsIG5ldyBDaGFyQXJyYXlXcmFwcGVyKAotICAgICAgbmV3IGNoYXJbXXsgIDB4YzViNSwgMHhiOWNjLCAweGNjOWMsIDB4YmMzMSwgMHhjMmVkIH0pIH0sCi0gICAgeyAiZGlnaXRzIiwgbmV3IENoYXJBcnJheVdyYXBwZXIoCi0gICAgICBuZXcgY2hhcltdeyAweGM3N2MsIDB4Yzc3NCwgMHhjMGJjLCAweGMwYWMsIDB4YzYyNCwgMHhjNzIxLCAweGNlNjAsCi0gICAgICAgICAgMHhkMzE0LCAweGFkNmN9KSB9LCB7ICJ0YWJsZXMiLCBuZXcgU3RyaW5nQXJyYXlXcmFwcGVyKAotICAgICAgICAgICAgICBuZXcgU3RyaW5nW117ICJkaWdpdHMiIH0pIH0KLSAgfTsKLQotICAvKioKLSAgICogR2V0IHRoZSBhc3NvY2lhdGlvbiBsaXN0LgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBhc3NvY2lhdGlvbiBsaXN0LgotICAgKi8KLSAgcHVibGljIE9iamVjdFtdW10gZ2V0Q29udGVudHMoKQotICB7Ci0gICAgcmV0dXJuIF9jb250ZW50czsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvcmVzL1hSZXNvdXJjZXNfc3YuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL3Jlcy9YUmVzb3VyY2VzX3N2LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDJkMDRhNjQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvcmVzL1hSZXNvdXJjZXNfc3YuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDc2ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFhSZXNvdXJjZXNfc3YuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNSAwODoxNjowOSBzdXJlc2hfZW1haWxpZCBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMucmVzOwotCi0vLwotLy8gIExhbmdSZXNvdXJjZXNfc3YucHJvcGVydGllcwotLy8KLQotLyoqCi0gKiBUaGUgU3dlZGlzaCByZXNvdXJjZSBidW5kbGUuCi0gKiBAeHNsLnVzYWdlIGludGVybmFsCi0gKi8KLXB1YmxpYyBjbGFzcyBYUmVzb3VyY2VzX3N2IGV4dGVuZHMgWFJlc291cmNlQnVuZGxlCi17Ci0gIHByaXZhdGUgc3RhdGljIGZpbmFsIE9iamVjdFtdW10gX2NvbnRlbnRzID0gbmV3IE9iamVjdFtdW10KLSAgewotICAgIHsgInVpX2xhbmd1YWdlIiwgInN2IiB9LCB7ICJoZWxwX2xhbmd1YWdlIiwgInN2IiB9LCB7ICJsYW5ndWFnZSIsICJzdiIgfSwKLSAgICB7ICJhbHBoYWJldCIsIG5ldyBDaGFyQXJyYXlXcmFwcGVyKAotICAgICAgbmV3IGNoYXJbXXsgJ0EnLCAnQicsICdDJywgJ0QnLCAnRScsICdGJywgJ0cnLCAnSCcsICdJJywgJ0onLCAnSycsICdMJywKLSAgICAgICAgICAgICAgICAgICdNJywgJ04nLCAnTycsICdQJywgJ1EnLCAnUicsICdTJywgJ1QnLCAnVScsICdWJywgJ1cnLCAnWCcsCi0gICAgICAgICAgICAgICAgICAnWScsICdaJyB9KSB9LAotICAgIHsgInRyYWRBbHBoYWJldCIsIG5ldyBDaGFyQXJyYXlXcmFwcGVyKAotICAgICAgbmV3IGNoYXJbXXsgJ0EnLCAnQicsICdDJywgJ0QnLCAnRScsICdGJywgJ0cnLCAnSCcsICdJJywgJ0onLCAnSycsICdMJywKLSAgICAgICAgICAgICAgICAgICdNJywgJ04nLCAnTycsICdQJywgJ1EnLCAnUicsICdTJywgJ1QnLCAnVScsICdWJywgJ1cnLCAnWCcsCi0gICAgICAgICAgICAgICAgICAnWScsICdaJyB9KSB9LAotCi0gICAgLy9sYW5ndWFnZSBvcmllbnRhdGlvbgotICAgIHsgIm9yaWVudGF0aW9uIiwgIkxlZnRUb1JpZ2h0IiB9LAotCi0gICAgLy9sYW5ndWFnZSBudW1iZXJpbmcKLSAgICB7ICJudW1iZXJpbmciLCAiYWRkaXRpdmUiIH0sCi0KLSAgICAvLyBsYXJnZXN0IG51bWVyaWNhbCB2YWx1ZQotICAgIC8veyJNYXhOdW1lcmljYWxWYWx1ZSIsIG5ldyBJbnRlZ2VyKCl9LAotICAgIC8vVGhlc2Ugd291bGQgbm90IGJlIHVzZWQgZm9yIEVOLiBPbmx5IHVzZWQgZm9yIHRyYWRpdGlvbmFsIG51bWJlcmluZwotICAgIC8veyJudW1iZXJHcm91cHMiLCBuZXcgaW50W117MTAsMX19LAotICAgIC8vVGhlc2Ugb25seSB1c2VkIGZvciBtdXRpcGxpY2F0aXZlLWFkZGl0aXZlIG51bWJlcmluZwotICAgIC8veyJtdWx0aXBsaWVyIiwgIjEwIn0sCi0gICAgLy97Im11bHRpcGxpZXJDaGFyIiwgIk0ifSwKLSAgICAvL3siZGlnaXRzIiwgbmV3IGNoYXJbXXsnYScsJ2InLCdjJywnZCcsJ2UnLCdmJywnZycsJ2gnLCdpJ319LAotICAgIC8veyJkaWdpdHMiLCBuZXcgY2hhcltdezB4MTBEMCwweDEwRDEsMHgxMEQyLDB4MTBEMywweDEwRDQsMHgxMEQ1LDB4MTBENiwweDEwRDcsMHgxMEQ4fX0sCi0gICAgLy97InRlbnMiLCBuZXcgY2hhcltdezB4MTBEOSwweDEwREEsMHgxMERCLDB4MTBEQywweDEwREQsMHgxMERFLDB4MTBERiwweDEwRTAsMHgxMEUxfX0sCi0gICAgLy9odW5kcmVkcywgZXRjLi4uCi0gICAgLy97InRhYmxlcyIsIG5ldyBTdHJpbmdbXXsidGVucyIsICJkaWdpdHMifX0KLSAgfTsKLQotICAvKioKLSAgICogR2V0IHRoZSBhc3NvY2lhdGlvbiBsaXN0LgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBhc3NvY2lhdGlvbiBsaXN0LgotICAgKi8KLSAgcHVibGljIE9iamVjdFtdW10gZ2V0Q29udGVudHMoKQotICB7Ci0gICAgcmV0dXJuIF9jb250ZW50czsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvcmVzL1hSZXNvdXJjZXNfemhfQ04uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL3Jlcy9YUmVzb3VyY2VzX3poX0NOLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDhmZDg0MGYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvdXRpbHMvcmVzL1hSZXNvdXJjZXNfemhfQ04uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDgzICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFhSZXNvdXJjZXNfemhfQ04uamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNSAwODoxNjoxMCBzdXJlc2hfZW1haWxpZCBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMucmVzOwotCi0vLwotLy8gIExhbmdSZXNvdXJjZXNfZW4ucHJvcGVydGllcwotLy8KLQotLyoqCi0gKiBUaGUgQ2hpbmVzZSByZXNvdXJjZSBidW5kbGUuCi0gKiBAeHNsLnVzYWdlIGludGVybmFsCi0gKi8KLXB1YmxpYyBjbGFzcyBYUmVzb3VyY2VzX3poX0NOIGV4dGVuZHMgWFJlc291cmNlQnVuZGxlCi17Ci0gIHByaXZhdGUgc3RhdGljIGZpbmFsIE9iamVjdFtdW10gX2NvbnRlbnRzID0gbmV3IE9iamVjdFtdW10KLSAgewotICAgIHsgInVpX2xhbmd1YWdlIiwgInpoIiB9LCB7ICJoZWxwX2xhbmd1YWdlIiwgInpoIiB9LCB7ICJsYW5ndWFnZSIsICJ6aCIgfSwKLSAgICB7ICJhbHBoYWJldCIsIG5ldyBDaGFyQXJyYXlXcmFwcGVyKAotICAgICAgbmV3IGNoYXJbXXsgMHhmZjIxLCAweGZmMjIsIDB4ZmYyMywgMHhmZjI0LCAweGZmMjUsIDB4ZmYyNiwgMHhmZjI3LAotICAgICAgICAgICAgICAgICAgMHhmZjI4LCAweGZmMjksIDB4ZmYyYSwgMHhmZjJiLCAweGZmMmMsIDB4ZmYyZCwgMHhmZjJlLAotICAgICAgICAgICAgICAgICAgMHhmZjJmLCAweGZmMzAsIDB4ZmYzMSwgMHhmZjMyLCAweGZmMzMsIDB4ZmYzNCwgMHhmZjM1LAotICAgICAgICAgICAgICAgICAgMHhmZjM2LCAweGZmMzcsIDB4ZmYzOCwgMHhmZjM5LCAweGZmM2EgfSkgfSwKLSAgICB7ICJ0cmFkQWxwaGFiZXQiLCBuZXcgQ2hhckFycmF5V3JhcHBlcigKLSAgICAgIG5ldyBjaGFyW117ICdBJywgJ0InLCAnQycsICdEJywgJ0UnLCAnRicsICdHJywgJ0gnLCAnSScsICdKJywgJ0snLCAnTCcsCi0gICAgICAgICAgICAgICAgICAnTScsICdOJywgJ08nLCAnUCcsICdRJywgJ1InLCAnUycsICdUJywgJ1UnLCAnVicsICdXJywgJ1gnLAotICAgICAgICAgICAgICAgICAgJ1knLCAnWicgfSkgfSwKLQotICAgIC8vbGFuZ3VhZ2Ugb3JpZW50YXRpb24KLSAgICB7ICJvcmllbnRhdGlvbiIsICJMZWZ0VG9SaWdodCIgfSwKLQotICAgIC8vbGFuZ3VhZ2UgbnVtYmVyaW5nCi0gICAgeyAibnVtYmVyaW5nIiwgIm11bHRpcGxpY2F0aXZlLWFkZGl0aXZlIiB9LAotICAgIHsgIm11bHRpcGxpZXJPcmRlciIsICJmb2xsb3dzIiB9LAotCi0gICAgLy8gbGFyZ2VzdCBudW1lcmljYWwgdmFsdWUKLSAgICAvL3siTWF4TnVtZXJpY2FsVmFsdWUiLCBuZXcgSW50ZWdlcigxMDAwMDAwMDApfSwKLSAgICAvL1RoZXNlIHdvdWxkIG5vdCBiZSB1c2VkIGZvciBFTi4gT25seSB1c2VkIGZvciB0cmFkaXRpb25hbCBudW1iZXJpbmcKLSAgICB7ICJudW1iZXJHcm91cHMiLCBuZXcgSW50QXJyYXlXcmFwcGVyKG5ldyBpbnRbXXsgMSB9KSB9LAotCi0gICAgLy8gc2ltcGxpZmllZCBjaGluZXNlCi0gICAgeyAiemVybyIsIG5ldyBDaGFyQXJyYXlXcmFwcGVyKG5ldyBjaGFyW117IDB4OTZmNiB9KSB9LAotCi0gICAgLy9UaGVzZSBvbmx5IHVzZWQgZm9yIG11dGlwbGljYXRpdmUtYWRkaXRpdmUgbnVtYmVyaW5nCi0gICAgeyAibXVsdGlwbGllciIsIG5ldyBMb25nQXJyYXlXcmFwcGVyKG5ldyBsb25nW117IDEwMDAwMDAwMCwgMTAwMDAsIDEwMDAsCi0gICAgICAgIDEwMCwgMTAgfSkgfSwKLSAgICB7ICJtdWx0aXBsaWVyQ2hhciIsIG5ldyBDaGFyQXJyYXlXcmFwcGVyKAotICAgICAgbmV3IGNoYXJbXXsgMHg0ZWJmLCAweDRlMDcsIDB4NTM0MywgMHg3NjdlLCAweDUzNDEgfSkgfSwKLSAgICB7ICJkaWdpdHMiLCBuZXcgQ2hhckFycmF5V3JhcHBlcigKLSAgICAgIG5ldyBjaGFyW117IDB4NGUwMCwgMHg0ZThjLCAweDRlMDksIDB4NTZkYiwgMHg0ZTk0LCAweDUxNmQsIDB4NGUwMywKLSAgICAgICAgICAgICAgICAgIDB4NTE2YiwgMHg0ZTVkIH0pIH0sIHsgInRhYmxlcyIsIG5ldyBTdHJpbmdBcnJheVdyYXBwZXIoCi0gICAgICAgICAgICAgICAgICAgICAgbmV3IFN0cmluZ1tdeyAiZGlnaXRzIiB9KSB9Ci0gIH07Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgYXNzb2NpYXRpb24gbGlzdC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgYXNzb2NpYXRpb24gbGlzdC4KLSAgICovCi0gIHB1YmxpYyBPYmplY3RbXVtdIGdldENvbnRlbnRzKCkKLSAgewotICAgIHJldHVybiBfY29udGVudHM7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL3Jlcy9YUmVzb3VyY2VzX3poX1RXLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC91dGlscy9yZXMvWFJlc291cmNlc196aF9UVy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzMzk3MzI5Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3V0aWxzL3Jlcy9YUmVzb3VyY2VzX3poX1RXLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4MyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBYUmVzb3VyY2VzX3poX1RXLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTUgMDg6MTY6MTAgc3VyZXNoX2VtYWlsaWQgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLnJlczsKLQotLy8KLS8vICBMYW5nUmVzb3VyY2VzX2VuLnByb3BlcnRpZXMKLS8vCi0KLS8qKgotICogVGhlIENoaW5lc2UoVGFpd2FuKSByZXNvdXJjZSBidW5kbGUuCi0gKiBAeHNsLnVzYWdlIGludGVybmFsCi0gKi8KLXB1YmxpYyBjbGFzcyBYUmVzb3VyY2VzX3poX1RXIGV4dGVuZHMgWFJlc291cmNlQnVuZGxlCi17Ci0gIHByaXZhdGUgc3RhdGljIGZpbmFsIE9iamVjdFtdW10gX2NvbnRlbnRzID0gbmV3IE9iamVjdFtdW10KLSAgewotICAgIHsgInVpX2xhbmd1YWdlIiwgInpoIiB9LCB7ICJoZWxwX2xhbmd1YWdlIiwgInpoIiB9LCB7ICJsYW5ndWFnZSIsICJ6aCIgfSwKLSAgICB7ICJhbHBoYWJldCIsIG5ldyBDaGFyQXJyYXlXcmFwcGVyKAotICAgICAgbmV3IGNoYXJbXXsgMHhmZjIxLCAweGZmMjIsIDB4ZmYyMywgMHhmZjI0LCAweGZmMjUsIDB4ZmYyNiwgMHhmZjI3LAotICAgICAgICAgICAgICAgICAgMHhmZjI4LCAweGZmMjksIDB4ZmYyYSwgMHhmZjJiLCAweGZmMmMsIDB4ZmYyZCwgMHhmZjJlLAotICAgICAgICAgICAgICAgICAgMHhmZjJmLCAweGZmMzAsIDB4ZmYzMSwgMHhmZjMyLCAweGZmMzMsIDB4ZmYzNCwgMHhmZjM1LAotICAgICAgICAgICAgICAgICAgMHhmZjM2LCAweGZmMzcsIDB4ZmYzOCwgMHhmZjM5LCAweGZmM2EgfSkgfSwKLSAgICB7ICJ0cmFkQWxwaGFiZXQiLCBuZXcgQ2hhckFycmF5V3JhcHBlcigKLSAgICAgIG5ldyBjaGFyW117ICdBJywgJ0InLCAnQycsICdEJywgJ0UnLCAnRicsICdHJywgJ0gnLCAnSScsICdKJywgJ0snLCAnTCcsCi0gICAgICAgICAgICAgICAgICAnTScsICdOJywgJ08nLCAnUCcsICdRJywgJ1InLCAnUycsICdUJywgJ1UnLCAnVicsICdXJywgJ1gnLAotICAgICAgICAgICAgICAgICAgJ1knLCAnWicgfSkgfSwKLQotICAgIC8vbGFuZ3VhZ2Ugb3JpZW50YXRpb24KLSAgICB7ICJvcmllbnRhdGlvbiIsICJMZWZ0VG9SaWdodCIgfSwKLQotICAgIC8vbGFuZ3VhZ2UgbnVtYmVyaW5nCi0gICAgeyAibnVtYmVyaW5nIiwgIm11bHRpcGxpY2F0aXZlLWFkZGl0aXZlIiB9LAotICAgIHsgIm11bHRpcGxpZXJPcmRlciIsICJmb2xsb3dzIiB9LAotCi0gICAgLy8gbGFyZ2VzdCBudW1lcmljYWwgdmFsdWUKLSAgICAvL3siTWF4TnVtZXJpY2FsVmFsdWUiLCBuZXcgSW50ZWdlcigxMDAwMDAwMDApfSwKLSAgICAvL1RoZXNlIHdvdWxkIG5vdCBiZSB1c2VkIGZvciBFTi4gT25seSB1c2VkIGZvciB0cmFkaXRpb25hbCBudW1iZXJpbmcKLSAgICB7ICJudW1iZXJHcm91cHMiLCBuZXcgSW50QXJyYXlXcmFwcGVyKG5ldyBpbnRbXXsgMSB9KSB9LAotCi0gICAgLy8gc2ltcGxpZmllZCBjaGluZXNlCi0gICAgeyAiemVybyIsIG5ldyBDaGFyQXJyYXlXcmFwcGVyKG5ldyBjaGFyW117IDB4OTZmNiB9KSB9LAotCi0gICAgLy9UaGVzZSBvbmx5IHVzZWQgZm9yIG11dGlwbGljYXRpdmUtYWRkaXRpdmUgbnVtYmVyaW5nCi0gICAgeyAibXVsdGlwbGllciIsIG5ldyBMb25nQXJyYXlXcmFwcGVyKG5ldyBsb25nW117IDEwMDAwMDAwMCwgMTAwMDAsIDEwMDAsCi0gICAgICAgIDEwMCwgMTAgfSkgfSwKLSAgICB7ICJtdWx0aXBsaWVyQ2hhciIsIG5ldyBDaGFyQXJyYXlXcmFwcGVyKAotICAgICAgbmV3IGNoYXJbXXsgMHg1MTA0LCAweDg0MmMsIDB4NGVkZiwgMHg0ZjcwLCAweDYyZmUgfSkgfSwKLSAgICB7ICJkaWdpdHMiLCBuZXcgQ2hhckFycmF5V3JhcHBlcigKLSAgICAgIG5ldyBjaGFyW117IDB4NThmOSwgMHg4Y2IzLCAweDUzYzMsIDB4ODA4NiwgMHg0ZjBkLCAweDk2NzgsIDB4NjdkMiwKLSAgICAgICAgICAgICAgICAgIDB4NjM0YywgMHg3Mzk2IH0pIH0sIHsgInRhYmxlcyIsIG5ldyBTdHJpbmdBcnJheVdyYXBwZXIoCi0gICAgICAgICAgICAgICAgICAgICAgbmV3IFN0cmluZ1tdeyAiZGlnaXRzIiB9KSB9Ci0gIH07Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgYXNzb2NpYXRpb24gbGlzdC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgYXNzb2NpYXRpb24gbGlzdC4KLSAgICovCi0gIHB1YmxpYyBPYmplY3RbXVtdIGdldENvbnRlbnRzKCkKLSAgewotICAgIHJldHVybiBfY29udGVudHM7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvQXJnLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL0FyZy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzMTFkMDdlLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvQXJnLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyNjcgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogQXJnLmphdmEsdiAxLjEuMi4xIDIwMDUvMDgvMDEgMDE6MzA6MTEgamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbDsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuUU5hbWU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWE9iamVjdDsKLWltcG9ydCBqYXZhLnV0aWwuT2JqZWN0czsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGhvbGRzIGFuIGluc3RhbmNlIG9mIGFuIGFyZ3VtZW50IG9uCi0gKiB0aGUgc3RhY2suIFRoZSB2YWx1ZSBvZiB0aGUgYXJndW1lbnQgY2FuIGJlIGVpdGhlciBhbgotICogWE9iamVjdCBvciBhIFN0cmluZyBjb250YWluaW5nIGFuIGV4cHJlc3Npb24uCi0gKiBAeHNsLnVzYWdlIGludGVybmFsCi0gKi8KLXB1YmxpYyBjbGFzcyBBcmcKLXsKLQotICAvKiogRmllbGQgbV9xbmFtZTogVGhlIG5hbWUgb2YgdGhpcyBhcmd1bWVudCwgZXhwcmVzc2VkIGFzIGEgUU5hbWUKLSAgICogKFF1YWxpZmllZCBOYW1lKSBvYmplY3QuCi0gICAqIEBzZWUgZ2V0UU5hbWUKLSAgICogQHNlZSBzZXRRTmFtZQotICAgKiAgKi8KLSAgcHJpdmF0ZSBRTmFtZSBtX3FuYW1lOwotCi0gIC8qKgotICAgKiBHZXQgdGhlIHF1YWxpZmllZCBuYW1lIGZvciB0aGlzIGFyZ3VtZW50LgotICAgKgotICAgKiBAcmV0dXJuIFFOYW1lIG9iamVjdCBjb250YWluaW5nIHRoZSBxdWFsaWZpZWQgbmFtZQotICAgKi8KLSAgcHVibGljIGZpbmFsIFFOYW1lIGdldFFOYW1lKCkKLSAgewotICAgIHJldHVybiBtX3FuYW1lOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgcXVhbGlmaWVkIG5hbWUgZm9yIHRoaXMgYXJndW1lbnQuCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lIFFOYW1lIG9iamVjdCByZXByZXNlbnRpbmcgdGhlIG5ldyBRdWFsaWZpZWQgTmFtZS4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHNldFFOYW1lKFFOYW1lIG5hbWUpCi0gIHsKLSAgICBtX3FuYW1lID0gbmFtZTsKLSAgfQotCi0gIC8qKiBGaWVsZCBtX3ZhbDogU3RvcmVkIFhPYmplY3QgdmFsdWUgb2YgdGhpcyBhcmd1bWVudAotICAgKiBAc2VlICNnZXRWYWwoKQotICAgKiBAc2VlICNzZXRWYWwoKQotICAgKi8KLSAgcHJpdmF0ZSBYT2JqZWN0IG1fdmFsOwotCi0gIC8qKgotICAgKiBHZXQgdGhlIHZhbHVlIGZvciB0aGlzIGFyZ3VtZW50LgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBhcmd1bWVudCdzIHN0b3JlZCBYT2JqZWN0IHZhbHVlLgotICAgKiBAc2VlICNzZXRWYWwoWE9iamVjdCkKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBYT2JqZWN0IGdldFZhbCgpCi0gIHsKLSAgICByZXR1cm4gbV92YWw7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSB2YWx1ZSBvZiB0aGlzIGFyZ3VtZW50LgotICAgKgotICAgKiBAcGFyYW0gdmFsIGFuIFhPYmplY3QgcmVwcmVzZW50aW5nIHRoZSBhcmd1bWVudHMncyB2YWx1ZS4KLSAgICogQHNlZSAjZ2V0VmFsKCkKLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHNldFZhbChYT2JqZWN0IHZhbCkKLSAgewotICAgIG1fdmFsID0gdmFsOwotICB9Ci0KLSAgLyoqCi0gICAqIEhhdmUgdGhlIG9iamVjdCByZWxlYXNlIGl0J3MgcmVzb3VyY2VzLgotICAgKiBDYWxsIG9ubHkgd2hlbiB0aGUgdmFyaWFibGUgb3IgYXJndW1lbnQgaXMgZ29pbmcgb3V0IG9mIHNjb3BlLgotICAgKi8KLSAgcHVibGljIHZvaWQgZGV0YWNoKCkKLSAgewotICAgIGlmKG51bGwgIT0gbV92YWwpCi0gICAgewotICAgICAgbV92YWwuYWxsb3dEZXRhY2hUb1JlbGVhc2UodHJ1ZSk7Ci0gICAgICBtX3ZhbC5kZXRhY2goKTsKLSAgICB9Ci0gIH0KLQotCi0gIC8qKiBGaWVsZCBtX2V4cHJlc3Npb246IFN0b3JlZCBleHByZXNzaW9uIHZhbHVlIG9mIHRoaXMgYXJndW1lbnQuCi0gICAqIEBzZWUgI3NldEV4cHJlc3Npb24KLSAgICogQHNlZSAjZ2V0RXhwcmVzc2lvbgotICAgKiAqLwotICBwcml2YXRlIFN0cmluZyBtX2V4cHJlc3Npb247Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgdmFsdWUgZXhwcmVzc2lvbiBmb3IgdGhpcyBhcmd1bWVudC4KLSAgICoKLSAgICogQHJldHVybiBTdHJpbmcgY29udGFpbmluZyB0aGUgZXhwcmVzc2lvbiBwcmV2aW91c2x5IHN0b3JlZCBpbnRvIHRoaXMKLSAgICogYXJndW1lbnQKLSAgICogQHNlZSAjc2V0RXhwcmVzc2lvbgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRFeHByZXNzaW9uKCkKLSAgewotICAgIHJldHVybiBtX2V4cHJlc3Npb247Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSB2YWx1ZSBleHByZXNzaW9uIGZvciB0aGlzIGFyZ3VtZW50LgotICAgKgotICAgKiBAcGFyYW0gZXhwciBTdHJpbmcgY29udGFpbmluZyB0aGUgZXhwcmVzc2lvbiB0byBiZSBzdG9yZWQgYXMgdGhpcwotICAgKiBhcmd1bWVudCdzIHZhbHVlLgotICAgKiBAc2VlICNnZXRFeHByZXNzaW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRFeHByZXNzaW9uKFN0cmluZyBleHByKQotICB7Ci0gICAgbV9leHByZXNzaW9uID0gZXhwcjsKLSAgfQotCi0gIC8qKgotICAgKiBUcnVlIGlmIHRoaXMgdmFyaWFibGUgd2FzIGFkZGVkIHdpdGggYW4geHNsOndpdGgtcGFyYW0gb3IKLSAgICogaXMgYWRkZWQgdmlhIHNldFBhcmFtZXRlci4KLSAgICovCi0gIHByaXZhdGUgYm9vbGVhbiBtX2lzRnJvbVdpdGhQYXJhbTsKLQotICAvKioKLSAgICogVGVsbCBpZiB0aGlzIHZhcmlhYmxlIGlzIGEgcGFyYW1ldGVyIHBhc3NlZCB3aXRoIGEgd2l0aC1wYXJhbSBvciBhcwotICAgKiBhIHRvcC1sZXZlbCBwYXJhbWV0ZXIuCi0gICAqLwotICAgcHVibGljIGJvb2xlYW4gaXNGcm9tV2l0aFBhcmFtKCkKLSAgIHsKLSAgICByZXR1cm4gbV9pc0Zyb21XaXRoUGFyYW07Ci0gICB9Ci0KLSAgLyoqCi0gICAqIFRydWUgaWYgdGhpcyB2YXJpYWJsZSBpcyBjdXJyZW50bHkgdmlzaWJsZS4gIFRvIGJlIHZpc2libGUsCi0gICAqIGEgdmFyaWFibGUgbmVlZHMgdG8gY29tZSBlaXRoZXIgZnJvbSB4c2w6dmFyaWFibGUgb3IgYmUKLSAgICogYSAicmVjZWl2ZWQiIHBhcmFtZXRlciwgaWUgb25lIGZvciB3aGljaCBhbiB4c2w6cGFyYW0gaGFzCi0gICAqIGJlZW4gZW5jb3VudGVyZWQuCi0gICAqIFNldCBhdCB0aGUgdGltZSB0aGUgb2JqZWN0IGlzIGNvbnN0cnVjdGVkIGFuZCB1cGRhdGVkIGFzIG5lZWRlZC4KLSAgICovCi0gIHByaXZhdGUgYm9vbGVhbiBtX2lzVmlzaWJsZTsKLQotICAvKioKLSAgICogVGVsbCBpZiB0aGlzIHZhcmlhYmxlIGlzIGN1cnJlbnRseSB2aXNpYmxlLgotICAgKi8KLSAgIHB1YmxpYyBib29sZWFuIGlzVmlzaWJsZSgpCi0gICB7Ci0gICAgcmV0dXJuIG1faXNWaXNpYmxlOwotICAgfQotCi0gIC8qKgotICAgKiBVcGRhdGUgdmlzaWJpbGl0eSBzdGF0dXMgb2YgdGhpcyB2YXJpYWJsZS4KLSAgICovCi0gICBwdWJsaWMgdm9pZCBzZXRJc1Zpc2libGUoYm9vbGVhbiBiKQotICAgewotICAgIG1faXNWaXNpYmxlID0gYjsKLSAgIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgZHVtbXkgcGFyYW1ldGVyIGFyZ3VtZW50LCB3aXRoIG5vIFFOYW1lIGFuZCBubwotICAgKiB2YWx1ZSAoZWl0aGVyIGV4cHJlc3Npb24gc3RyaW5nIG9yIHZhbHVlIFhPYmplY3QpLiBpc1Zpc2libGUKLSAgICogZGVmYXVsdHMgdG8gdHJ1ZS4KLSAgICovCi0gIHB1YmxpYyBBcmcoKQotICB7Ci0KLSAgICBtX3FuYW1lID0gbmV3IFFOYW1lKCIiKTsKLSAgICAgICAvLyBzbyB0aGF0IHN0cmluZyBjb21wYXJlcyBjYW4gYmUgZG9uZS4KLSAgICBtX3ZhbCA9IG51bGw7Ci0gICAgbV9leHByZXNzaW9uID0gbnVsbDsKLSAgICBtX2lzVmlzaWJsZSA9IHRydWU7Ci0gICAgbV9pc0Zyb21XaXRoUGFyYW0gPSBmYWxzZTsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBwYXJhbWV0ZXIgYXJndW1lbnQgdGhhdCBjb250YWlucyBhbiBleHByZXNzaW9uLgotICAgKgotICAgKiBAcGFyYW0gcW5hbWUgTmFtZSBvZiB0aGUgYXJndW1lbnQsIGV4cHJlc3NlZCBhcyBhIFFOYW1lIG9iamVjdC4KLSAgICogQHBhcmFtIGV4cHJlc3Npb24gU3RyaW5nIHRvIGJlIHN0b3JlZCBhcyB0aGlzIGFyZ3VtZW50J3MgdmFsdWUgZXhwcmVzc2lvbi4KLSAgICogQHBhcmFtIGlzRnJvbVdpdGhQYXJhbSBUcnVlIGlmIHRoaXMgaXMgYSBwYXJhbWV0ZXIgdmFyaWFibGUuCi0gICAqLwotICBwdWJsaWMgQXJnKFFOYW1lIHFuYW1lLCBTdHJpbmcgZXhwcmVzc2lvbiwgYm9vbGVhbiBpc0Zyb21XaXRoUGFyYW0pCi0gIHsKLQotICAgIG1fcW5hbWUgPSBxbmFtZTsKLSAgICBtX3ZhbCA9IG51bGw7Ci0gICAgbV9leHByZXNzaW9uID0gZXhwcmVzc2lvbjsKLSAgICBtX2lzRnJvbVdpdGhQYXJhbSA9IGlzRnJvbVdpdGhQYXJhbTsKLSAgICBtX2lzVmlzaWJsZSA9ICFpc0Zyb21XaXRoUGFyYW07Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgcGFyYW1ldGVyIGFyZ3VtZW50IHdoaWNoIGhhcyBhbiBYT2JqZWN0IHZhbHVlLgotICAgKiBpc1Zpc2libGUgZGVmYXVsdHMgdG8gdHJ1ZS4KLSAgICoKLSAgICogQHBhcmFtIHFuYW1lIE5hbWUgb2YgdGhlIGFyZ3VtZW50LCBleHByZXNzZWQgYXMgYSBRTmFtZSBvYmplY3QuCi0gICAqIEBwYXJhbSB2YWwgVmFsdWUgb2YgdGhlIGFyZ3VtZW50LCBleHByZXNzZWQgYXMgYW4gWE9iamVjdAotICAgKi8KLSAgcHVibGljIEFyZyhRTmFtZSBxbmFtZSwgWE9iamVjdCB2YWwpCi0gIHsKLQotICAgIG1fcW5hbWUgPSBxbmFtZTsKLSAgICBtX3ZhbCA9IHZhbDsKLSAgICBtX2lzVmlzaWJsZSA9IHRydWU7Ci0gICAgbV9pc0Zyb21XaXRoUGFyYW0gPSBmYWxzZTsKLSAgICBtX2V4cHJlc3Npb24gPSBudWxsOwotICB9Ci0KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewotICAgICAgICByZXR1cm4gT2JqZWN0cy5oYXNoQ29kZSh0aGlzLm1fcW5hbWUpOwotICAgIH0KLQotICAvKioKLSAgICogRXF1YWxpdHkgZnVuY3Rpb24gc3BlY2lhbGl6ZWQgZm9yIHRoZSB2YXJpYWJsZSBuYW1lLiAgSWYgdGhlIGFyZ3VtZW50Ci0gICAqIGlzIG5vdCBhIHFuYW1lLCBpdCB3aWxsIGRlbGlnYXRlIHRvIHRoZSBzdXBlciBjbGFzcy4KLSAgICoKLSAgICogQHBhcmFtICAgb2JqICAgdGhlIHJlZmVyZW5jZSBvYmplY3Qgd2l0aCB3aGljaCB0byBjb21wYXJlLgotICAgKiBAcmV0dXJuICA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGlzIG9iamVjdCBpcyB0aGUgc2FtZSBhcyB0aGUgb2JqCi0gICAqICAgICAgICAgIGFyZ3VtZW50OyA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLgotICAgKi8KLSAgQE92ZXJyaWRlCi0gIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqKQotICB7Ci0gICAgaWYob2JqIGluc3RhbmNlb2YgUU5hbWUpCi0gICAgewotICAgICAgcmV0dXJuIG1fcW5hbWUuZXF1YWxzKG9iaik7Ci0gICAgfQotICAgIGVsc2UKLSAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBwYXJhbWV0ZXIgYXJndW1lbnQuCi0gICAqCi0gICAqIEBwYXJhbSBxbmFtZSBOYW1lIG9mIHRoZSBhcmd1bWVudCwgZXhwcmVzc2VkIGFzIGEgUU5hbWUgb2JqZWN0LgotICAgKiBAcGFyYW0gdmFsIFZhbHVlIG9mIHRoZSBhcmd1bWVudCwgZXhwcmVzc2VkIGFzIGFuIFhPYmplY3QKLSAgICogQHBhcmFtIGlzRnJvbVdpdGhQYXJhbSBUcnVlIGlmIHRoaXMgaXMgYSBwYXJhbWV0ZXIgdmFyaWFibGUuCi0gICAqLwotICBwdWJsaWMgQXJnKFFOYW1lIHFuYW1lLCBYT2JqZWN0IHZhbCwgYm9vbGVhbiBpc0Zyb21XaXRoUGFyYW0pCi0gIHsKLQotICAgIG1fcW5hbWUgPSBxbmFtZTsKLSAgICBtX3ZhbCA9IHZhbDsKLSAgICBtX2lzRnJvbVdpdGhQYXJhbSA9IGlzRnJvbVdpdGhQYXJhbTsKLSAgICBtX2lzVmlzaWJsZSA9ICFpc0Zyb21XaXRoUGFyYW07Ci0gICAgbV9leHByZXNzaW9uID0gbnVsbDsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9DYWNoZWRYUGF0aEFQSS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9DYWNoZWRYUGF0aEFQSS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyMTk1OTFjLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvQ2FjaGVkWFBhdGhBUEkuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDMzNyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBDYWNoZWRYUGF0aEFQSS5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzEwIDAzOjQ3OjQyIGplZmZzdXR0b3IgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWw7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5QcmVmaXhSZXNvbHZlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLlByZWZpeFJlc29sdmVyRGVmYXVsdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YT2JqZWN0OwotCi1pbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlTGlzdDsKLWltcG9ydCBvcmcudzNjLmRvbS50cmF2ZXJzYWwuTm9kZUl0ZXJhdG9yOwotCi0vKioKLSAqIFRoZSBtZXRob2RzIGluIHRoaXMgY2xhc3MgYXJlIGNvbnZlbmllbmNlIG1ldGhvZHMgaW50byB0aGUKLSAqIGxvdy1sZXZlbCBYUGF0aCBBUEkuCi0gKgotICogVGhlc2UgZnVuY3Rpb25zIHRlbmQgdG8gYmUgYSBsaXR0bGUgc2xvdywgc2luY2UgYSBudW1iZXIgb2Ygb2JqZWN0cyBtdXN0IGJlCi0gKiBjcmVhdGVkIGZvciBlYWNoIGV2YWx1YXRpb24uICBBIGZhc3RlciB3YXkgaXMgdG8gcHJlY29tcGlsZSB0aGUKLSAqIFhQYXRocyB1c2luZyB0aGUgbG93LWxldmVsIEFQSSwgYW5kIHRoZW4ganVzdCB1c2UgdGhlIFhQYXRocwotICogb3ZlciBhbmQgb3Zlci4KLSAqCi0gKiBUaGlzIGlzIGFuIGFsdGVybmF0aXZlIGZvciB0aGUgb2xkIFhQYXRoQVBJIGNsYXNzLCB3aGljaCBwcm92aWRlZAotICogc3RhdGljIG1ldGhvZHMgZm9yIHRoZSBwdXJwb3NlIGJ1dCBoYWQgdGhlIGRyYXdiYWNrIG9mCi0gKiBpbnN0YW50aWF0aW5nIGEgbmV3IFhQYXRoQ29udGV4dCAoYW5kIHRodXMgYnVpbGRpbmcgYSBuZXcgRFRNTWFuYWdlciwKLSAqIGFuZCBuZXcgRFRNcykgZWFjaCB0aW1lIGl0IHdhcyBjYWxsZWQuIFhQYXRoQVBJT2JqZWN0IGluc3RlYWQgcmV0YWlucwotICogaXRzIGNvbnRleHQgYXMgbG9uZyBhcyB0aGUgb2JqZWN0IHBlcnNpc3RzLCByZXVzaW5nIHRoZSBEVE1zLiBUaGlzCi0gKiBkb2VzIGhhdmUgYSBkb3duc2lkZTogaWYgeW91J3ZlIGNoYW5nZWQgeW91ciBzb3VyY2UgZG9jdW1lbnQsIHlvdSBzaG91bGQKLSAqIG9idGFpbiBhIG5ldyBYUGF0aEFQSU9iamVjdCB0byBjb250aW51ZSBzZWFyY2hpbmcgaXQsIHNpbmNlIHRyeWluZyB0byB1c2UKLSAqIHRoZSBvbGQgRFRNcyB3aWxsIHByb2JhYmx5IHlpZWxkIGJhZCByZXN1bHRzIG9yIG1hbGZ1bmN0aW9uIG91dHJpZ2h0Li4uIGFuZAotICogdGhlIGNhY2hlZCBEVE1zIG1heSBjb25zdW1lIG1lbW9yeSB1bnRpbCB0aGlzIG9iamVjdCBhbmQgaXRzIGNvbnRleHQgYXJlCi0gKiByZXR1cm5lZCB0byB0aGUgaGVhcC4gRXNzZW50aWFsbHksIGl0J3MgdGhlIGNhbGxlcidzIHJlc3BvbnNpYmlsaXR5IHRvCi0gKiBkZWNpZGUgd2hlbiB0byBkaXNjYXJkIHRoZSBjYWNoZS4KLSAqCi0gKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hwYXRoIj5YUGF0aCBTcGVjaWZpY2F0aW9uPC9hPgotICogKi8KLXB1YmxpYyBjbGFzcyBDYWNoZWRYUGF0aEFQSQotewotICAvKiogWFBhdGhDb250ZXh0LCBhbmQgdGh1cyB0aGUgZG9jdW1lbnQgbW9kZWwgc3lzdGVtIChEVE1zKSwgcGVyc2lzdHMgdGhyb3VnaCBtdWx0aXBsZQotICAgICAgY2FsbHMgdG8gdGhpcyBvYmplY3QuIFRoaXMgaXMgc2V0IGluIHRoZSBjb25zdHJ1Y3Rvci4KLSAgKi8KLSAgcHJvdGVjdGVkIFhQYXRoQ29udGV4dCB4cGF0aFN1cHBvcnQ7Ci0KLSAgLyoqCi0gICAqIDxwPkRlZmF1bHQgY29uc3RydWN0b3IuIEVzdGFibGlzaGVzIGl0cyBvd24ge0BsaW5rIFhQYXRoQ29udGV4dH0sIGFuZCBoZW5jZQotICAgKiBpdHMgb3duIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1NYW5hZ2VyfS4KLSAgICogR29vZCBjaG9pY2UgZm9yIHNpbXBsZSB1c2VzLjwvcD4KLSAgICogPHA+Tm90ZSB0aGF0IGFueSBwYXJ0aWN1bGFyIGluc3RhbmNlIG9mIHtAbGluayBDYWNoZWRYUGF0aEFQSX0gbXVzdCBub3QgYmUKLSAgICogb3BlcmF0ZWQgdXBvbiBieSBtdWx0aXBsZSB0aHJlYWRzIHdpdGhvdXQgc3luY2hyb25pemF0aW9uOyB3ZSBkbwotICAgKiBub3QgY3VycmVudGx5IHN1cHBvcnQgbXVsdGl0aHJlYWRlZCBhY2Nlc3MgdG8gYSBzaW5nbGUKLSAgICoge0BsaW5rIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTX0uPC9wPgotICAgKi8KLSAgcHVibGljIENhY2hlZFhQYXRoQVBJKCkKLSAgewotICAgIHhwYXRoU3VwcG9ydCA9IG5ldyBYUGF0aENvbnRleHQoKTsKLSAgfQotCi0gIC8qKgotICAgKiA8cD5UaGlzIGNvbnN0cnVjdG9yIHNoYXJlcyBpdHMge0BsaW5rIFhQYXRoQ29udGV4dH0gd2l0aCBhIHByZS1leGlzdGluZwotICAgKiB7QGxpbmsgQ2FjaGVkWFBhdGhBUEl9LiAgVGhhdCBhbGxvd3Mgc2hhcmluZyBkb2N1bWVudCBtb2RlbHMKLSAgICogKHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE19KSBhbmQgcHJldmlvdXNseSBlc3RhYmxpc2hlZCBsb2NhdGlvbgotICAgKiBzdGF0ZS48L3A+Ci0gICAqIDxwPk5vdGUgdGhhdCB0aGUgb3JpZ2luYWwge0BsaW5rIENhY2hlZFhQYXRoQVBJfSBhbmQgdGhlIG5ldyBvbmUgc2hvdWxkCi0gICAqIG5vdCBiZSBvcGVyYXRlZCB1cG9uIGNvbmN1cnJlbnRseTsgd2UgZG8gbm90IHN1cHBvcnQgbXVsdGl0aHJlYWRlZCBhY2Nlc3MKLSAgICogdG8gYSBzaW5nbGUge0BsaW5rIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTX0gYXQgdGhpcyB0aW1lLiAgU2ltaWxhcmx5LAotICAgKiBhbnkgcGFydGljdWxhciBpbnN0YW5jZSBvZiB7QGxpbmsgQ2FjaGVkWFBhdGhBUEl9IG11c3Qgbm90IGJlIG9wZXJhdGVkCi0gICAqIHVwb24gYnkgbXVsdGlwbGUgdGhyZWFkcyB3aXRob3V0IHN5bmNocm9uaXphdGlvbi48L3A+Ci0gICAqIDxwPiVSRVZJRVclIFNob3VsZCB0aGlzIGluc3RlYWQgZG8gYSBjbG9uZS1hbmQtcmVzZXQgb24gdGhlIFhQYXRoU3VwcG9ydCBvYmplY3Q/PC9wPgotICAgKgotICAgKi8KLSAgcHVibGljIENhY2hlZFhQYXRoQVBJKENhY2hlZFhQYXRoQVBJIHByaW9yWFBhdGhBUEkpCi0gIHsKLSAgICB4cGF0aFN1cHBvcnQgPSBwcmlvclhQYXRoQVBJLnhwYXRoU3VwcG9ydDsKLSAgfQotCi0KLSAgLyoqIFJldHVybnMgdGhlIFhQYXRoU3VwcG9ydCBvYmplY3QgdXNlZCBpbiB0aGlzIENhY2hlZFhQYXRoQVBJCi0gICAqCi0gICAqICVSRVZJRVclIEknbSBzb21ld2hhdCBjb25jZXJuZWQgYWJvdXQgdGhlIGxvc3Mgb2YgZW5jYXBzdWxhdGlvbgotICAgKiB0aGlzIGNhdXNlcywgYnV0IHRoZSB4bWwtc2VjdXJpdHkgZm9sa3Mgc2F5IHRoZXkgbmVlZCBpdC4KLSAgICogKi8KLSAgcHVibGljIFhQYXRoQ29udGV4dCBnZXRYUGF0aENvbnRleHQoKQotICB7Ci0gICAgcmV0dXJuIHRoaXMueHBhdGhTdXBwb3J0OwotICB9Ci0KLQotICAvKioKLSAgICogVXNlIGFuIFhQYXRoIHN0cmluZyB0byBzZWxlY3QgYSBzaW5nbGUgbm9kZS4gWFBhdGggbmFtZXNwYWNlCi0gICAqIHByZWZpeGVzIGFyZSByZXNvbHZlZCBmcm9tIHRoZSBjb250ZXh0IG5vZGUsIHdoaWNoIG1heSBub3QKLSAgICogYmUgd2hhdCB5b3Ugd2FudCAoc2VlIHRoZSBuZXh0IG1ldGhvZCkuCi0gICAqCi0gICAqIEBwYXJhbSBjb250ZXh0Tm9kZSBUaGUgbm9kZSB0byBzdGFydCBzZWFyY2hpbmcgZnJvbS4KLSAgICogQHBhcmFtIHN0ciBBIHZhbGlkIFhQYXRoIHN0cmluZy4KLSAgICogQHJldHVybiBUaGUgZmlyc3Qgbm9kZSBmb3VuZCB0aGF0IG1hdGNoZXMgdGhlIFhQYXRoLCBvciBudWxsLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgIE5vZGUgc2VsZWN0U2luZ2xlTm9kZShOb2RlIGNvbnRleHROb2RlLCBTdHJpbmcgc3RyKQotICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIHNlbGVjdFNpbmdsZU5vZGUoY29udGV4dE5vZGUsIHN0ciwgY29udGV4dE5vZGUpOwotICB9Ci0KLSAgLyoqCi0gICAqIFVzZSBhbiBYUGF0aCBzdHJpbmcgdG8gc2VsZWN0IGEgc2luZ2xlIG5vZGUuCi0gICAqIFhQYXRoIG5hbWVzcGFjZSBwcmVmaXhlcyBhcmUgcmVzb2x2ZWQgZnJvbSB0aGUgbmFtZXNwYWNlTm9kZS4KLSAgICoKLSAgICogQHBhcmFtIGNvbnRleHROb2RlIFRoZSBub2RlIHRvIHN0YXJ0IHNlYXJjaGluZyBmcm9tLgotICAgKiBAcGFyYW0gc3RyIEEgdmFsaWQgWFBhdGggc3RyaW5nLgotICAgKiBAcGFyYW0gbmFtZXNwYWNlTm9kZSBUaGUgbm9kZSBmcm9tIHdoaWNoIHByZWZpeGVzIGluIHRoZSBYUGF0aCB3aWxsIGJlIHJlc29sdmVkIHRvIG5hbWVzcGFjZXMuCi0gICAqIEByZXR1cm4gVGhlIGZpcnN0IG5vZGUgZm91bmQgdGhhdCBtYXRjaGVzIHRoZSBYUGF0aCwgb3IgbnVsbC4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljICBOb2RlIHNlbGVjdFNpbmdsZU5vZGUoCi0gICAgICAgICAgTm9kZSBjb250ZXh0Tm9kZSwgU3RyaW5nIHN0ciwgTm9kZSBuYW1lc3BhY2VOb2RlKQotICAgICAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIC8vIEhhdmUgdGhlIFhPYmplY3QgcmV0dXJuIGl0cyByZXN1bHQgYXMgYSBOb2RlU2V0RFRNLgotICAgIE5vZGVJdGVyYXRvciBubCA9IHNlbGVjdE5vZGVJdGVyYXRvcihjb250ZXh0Tm9kZSwgc3RyLCBuYW1lc3BhY2VOb2RlKTsKLQotICAgIC8vIFJldHVybiB0aGUgZmlyc3Qgbm9kZSwgb3IgbnVsbAotICAgIHJldHVybiBubC5uZXh0Tm9kZSgpOwotICB9Ci0KLSAgLyoqCi0gICAqICBVc2UgYW4gWFBhdGggc3RyaW5nIHRvIHNlbGVjdCBhIG5vZGVsaXN0LgotICAgKiAgWFBhdGggbmFtZXNwYWNlIHByZWZpeGVzIGFyZSByZXNvbHZlZCBmcm9tIHRoZSBjb250ZXh0Tm9kZS4KLSAgICoKLSAgICogIEBwYXJhbSBjb250ZXh0Tm9kZSBUaGUgbm9kZSB0byBzdGFydCBzZWFyY2hpbmcgZnJvbS4KLSAgICogIEBwYXJhbSBzdHIgQSB2YWxpZCBYUGF0aCBzdHJpbmcuCi0gICAqICBAcmV0dXJuIEEgTm9kZUl0ZXJhdG9yLCBzaG91bGQgbmV2ZXIgYmUgbnVsbC4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljICBOb2RlSXRlcmF0b3Igc2VsZWN0Tm9kZUl0ZXJhdG9yKE5vZGUgY29udGV4dE5vZGUsIFN0cmluZyBzdHIpCi0gICAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gc2VsZWN0Tm9kZUl0ZXJhdG9yKGNvbnRleHROb2RlLCBzdHIsIGNvbnRleHROb2RlKTsKLSAgfQotCi0gIC8qKgotICAgKiAgVXNlIGFuIFhQYXRoIHN0cmluZyB0byBzZWxlY3QgYSBub2RlbGlzdC4KLSAgICogIFhQYXRoIG5hbWVzcGFjZSBwcmVmaXhlcyBhcmUgcmVzb2x2ZWQgZnJvbSB0aGUgbmFtZXNwYWNlTm9kZS4KLSAgICoKLSAgICogIEBwYXJhbSBjb250ZXh0Tm9kZSBUaGUgbm9kZSB0byBzdGFydCBzZWFyY2hpbmcgZnJvbS4KLSAgICogIEBwYXJhbSBzdHIgQSB2YWxpZCBYUGF0aCBzdHJpbmcuCi0gICAqICBAcGFyYW0gbmFtZXNwYWNlTm9kZSBUaGUgbm9kZSBmcm9tIHdoaWNoIHByZWZpeGVzIGluIHRoZSBYUGF0aCB3aWxsIGJlIHJlc29sdmVkIHRvIG5hbWVzcGFjZXMuCi0gICAqICBAcmV0dXJuIEEgTm9kZUl0ZXJhdG9yLCBzaG91bGQgbmV2ZXIgYmUgbnVsbC4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljICBOb2RlSXRlcmF0b3Igc2VsZWN0Tm9kZUl0ZXJhdG9yKAotICAgICAgICAgIE5vZGUgY29udGV4dE5vZGUsIFN0cmluZyBzdHIsIE5vZGUgbmFtZXNwYWNlTm9kZSkKLSAgICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICAvLyBFeGVjdXRlIHRoZSBYUGF0aCwgYW5kIGhhdmUgaXQgcmV0dXJuIHRoZSByZXN1bHQKLSAgICBYT2JqZWN0IGxpc3QgPSBldmFsKGNvbnRleHROb2RlLCBzdHIsIG5hbWVzcGFjZU5vZGUpOwotCi0gICAgLy8gSGF2ZSB0aGUgWE9iamVjdCByZXR1cm4gaXRzIHJlc3VsdCBhcyBhIE5vZGVTZXREVE0uCi0gICAgcmV0dXJuIGxpc3Qubm9kZXNldCgpOwotICB9Ci0KLSAgLyoqCi0gICAqICBVc2UgYW4gWFBhdGggc3RyaW5nIHRvIHNlbGVjdCBhIG5vZGVsaXN0LgotICAgKiAgWFBhdGggbmFtZXNwYWNlIHByZWZpeGVzIGFyZSByZXNvbHZlZCBmcm9tIHRoZSBjb250ZXh0Tm9kZS4KLSAgICoKLSAgICogIEBwYXJhbSBjb250ZXh0Tm9kZSBUaGUgbm9kZSB0byBzdGFydCBzZWFyY2hpbmcgZnJvbS4KLSAgICogIEBwYXJhbSBzdHIgQSB2YWxpZCBYUGF0aCBzdHJpbmcuCi0gICAqICBAcmV0dXJuIEEgTm9kZUl0ZXJhdG9yLCBzaG91bGQgbmV2ZXIgYmUgbnVsbC4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljICBOb2RlTGlzdCBzZWxlY3ROb2RlTGlzdChOb2RlIGNvbnRleHROb2RlLCBTdHJpbmcgc3RyKQotICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIHNlbGVjdE5vZGVMaXN0KGNvbnRleHROb2RlLCBzdHIsIGNvbnRleHROb2RlKTsKLSAgfQotCi0gIC8qKgotICAgKiAgVXNlIGFuIFhQYXRoIHN0cmluZyB0byBzZWxlY3QgYSBub2RlbGlzdC4KLSAgICogIFhQYXRoIG5hbWVzcGFjZSBwcmVmaXhlcyBhcmUgcmVzb2x2ZWQgZnJvbSB0aGUgbmFtZXNwYWNlTm9kZS4KLSAgICoKLSAgICogIEBwYXJhbSBjb250ZXh0Tm9kZSBUaGUgbm9kZSB0byBzdGFydCBzZWFyY2hpbmcgZnJvbS4KLSAgICogIEBwYXJhbSBzdHIgQSB2YWxpZCBYUGF0aCBzdHJpbmcuCi0gICAqICBAcGFyYW0gbmFtZXNwYWNlTm9kZSBUaGUgbm9kZSBmcm9tIHdoaWNoIHByZWZpeGVzIGluIHRoZSBYUGF0aCB3aWxsIGJlIHJlc29sdmVkIHRvIG5hbWVzcGFjZXMuCi0gICAqICBAcmV0dXJuIEEgTm9kZUl0ZXJhdG9yLCBzaG91bGQgbmV2ZXIgYmUgbnVsbC4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljICBOb2RlTGlzdCBzZWxlY3ROb2RlTGlzdCgKLSAgICAgICAgICBOb2RlIGNvbnRleHROb2RlLCBTdHJpbmcgc3RyLCBOb2RlIG5hbWVzcGFjZU5vZGUpCi0gICAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgLy8gRXhlY3V0ZSB0aGUgWFBhdGgsIGFuZCBoYXZlIGl0IHJldHVybiB0aGUgcmVzdWx0Ci0gICAgWE9iamVjdCBsaXN0ID0gZXZhbChjb250ZXh0Tm9kZSwgc3RyLCBuYW1lc3BhY2VOb2RlKTsKLQotICAgIC8vIFJldHVybiBhIE5vZGVMaXN0LgotICAgIHJldHVybiBsaXN0Lm5vZGVsaXN0KCk7Ci0gIH0KLQotICAvKioKLSAgICogIEV2YWx1YXRlIFhQYXRoIHN0cmluZyB0byBhbiBYT2JqZWN0LiAgVXNpbmcgdGhpcyBtZXRob2QsCi0gICAqICBYUGF0aCBuYW1lc3BhY2UgcHJlZml4ZXMgd2lsbCBiZSByZXNvbHZlZCBmcm9tIHRoZSBuYW1lc3BhY2VOb2RlLgotICAgKiAgQHBhcmFtIGNvbnRleHROb2RlIFRoZSBub2RlIHRvIHN0YXJ0IHNlYXJjaGluZyBmcm9tLgotICAgKiAgQHBhcmFtIHN0ciBBIHZhbGlkIFhQYXRoIHN0cmluZy4KLSAgICogIEByZXR1cm4gQW4gWE9iamVjdCwgd2hpY2ggY2FuIGJlIHVzZWQgdG8gb2J0YWluIGEgc3RyaW5nLCBudW1iZXIsIG5vZGVsaXN0LCBldGMsIHNob3VsZCBuZXZlciBiZSBudWxsLgotICAgKiAgQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YT2JqZWN0Ci0gICAqICBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhOdWxsCi0gICAqICBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhCb29sZWFuCi0gICAqICBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhOdW1iZXIKLSAgICogIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWFN0cmluZwotICAgKiAgQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YUlRyZWVGcmFnCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyAgWE9iamVjdCBldmFsKE5vZGUgY29udGV4dE5vZGUsIFN0cmluZyBzdHIpCi0gICAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gZXZhbChjb250ZXh0Tm9kZSwgc3RyLCBjb250ZXh0Tm9kZSk7Ci0gIH0KLQotICAvKioKLSAgICogIEV2YWx1YXRlIFhQYXRoIHN0cmluZyB0byBhbiBYT2JqZWN0LgotICAgKiAgWFBhdGggbmFtZXNwYWNlIHByZWZpeGVzIGFyZSByZXNvbHZlZCBmcm9tIHRoZSBuYW1lc3BhY2VOb2RlLgotICAgKiAgVGhlIGltcGxlbWVudGF0aW9uIG9mIHRoaXMgaXMgYSBsaXR0bGUgc2xvdywgc2luY2UgaXQgY3JlYXRlcwotICAgKiAgYSBudW1iZXIgb2Ygb2JqZWN0cyBlYWNoIHRpbWUgaXQgaXMgY2FsbGVkLiAgVGhpcyBjb3VsZCBiZSBvcHRpbWl6ZWQKLSAgICogIHRvIGtlZXAgdGhlIHNhbWUgb2JqZWN0cyBhcm91bmQsIGJ1dCB0aGVuIHRocmVhZC1zYWZldHkgaXNzdWVzIHdvdWxkIGFyaXNlLgotICAgKgotICAgKiAgQHBhcmFtIGNvbnRleHROb2RlIFRoZSBub2RlIHRvIHN0YXJ0IHNlYXJjaGluZyBmcm9tLgotICAgKiAgQHBhcmFtIHN0ciBBIHZhbGlkIFhQYXRoIHN0cmluZy4KLSAgICogIEBwYXJhbSBuYW1lc3BhY2VOb2RlIFRoZSBub2RlIGZyb20gd2hpY2ggcHJlZml4ZXMgaW4gdGhlIFhQYXRoIHdpbGwgYmUgcmVzb2x2ZWQgdG8gbmFtZXNwYWNlcy4KLSAgICogIEByZXR1cm4gQW4gWE9iamVjdCwgd2hpY2ggY2FuIGJlIHVzZWQgdG8gb2J0YWluIGEgc3RyaW5nLCBudW1iZXIsIG5vZGVsaXN0LCBldGMsIHNob3VsZCBuZXZlciBiZSBudWxsLgotICAgKiAgQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YT2JqZWN0Ci0gICAqICBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhOdWxsCi0gICAqICBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhCb29sZWFuCi0gICAqICBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhOdW1iZXIKLSAgICogIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWFN0cmluZwotICAgKiAgQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YUlRyZWVGcmFnCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyAgWE9iamVjdCBldmFsKE5vZGUgY29udGV4dE5vZGUsIFN0cmluZyBzdHIsIE5vZGUgbmFtZXNwYWNlTm9kZSkKLSAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgLy8gU2luY2Ugd2UgZG9uJ3QgaGF2ZSBhIFhNTCBQYXJzZXIgaW52b2x2ZWQgaGVyZSwgaW5zdGFsbCBzb21lIGRlZmF1bHQgc3VwcG9ydAotICAgIC8vIGZvciB0aGluZ3MgbGlrZSBuYW1lc3BhY2VzLCBldGMuCi0gICAgLy8gKENoYW5nZWQgZnJvbTogWFBhdGhDb250ZXh0IHhwYXRoU3VwcG9ydCA9IG5ldyBYUGF0aENvbnRleHQoKTsKLSAgICAvLyAgICBiZWNhdXNlIFhQYXRoQ29udGV4dCBpcyB3ZWFrIGluIGEgbnVtYmVyIG9mIGFyZWFzLi4uIHBlcmhhcHMKLSAgICAvLyAgICBYUGF0aENvbnRleHQgc2hvdWxkIGJlIGRvbmUgYXdheSB3aXRoLikKLQotICAgIC8vIENyZWF0ZSBhbiBvYmplY3QgdG8gcmVzb2x2ZSBuYW1lc3BhY2UgcHJlZml4ZXMuCi0gICAgLy8gWFBhdGggbmFtZXNwYWNlcyBhcmUgcmVzb2x2ZWQgZnJvbSB0aGUgaW5wdXQgY29udGV4dCBub2RlJ3MgZG9jdW1lbnQgZWxlbWVudAotICAgIC8vIGlmIGl0IGlzIGEgcm9vdCBub2RlLCBvciBlbHNlIHRoZSBjdXJyZW50IGNvbnRleHQgbm9kZSAoZm9yIGxhY2sgb2YgYSBiZXR0ZXIKLSAgICAvLyByZXNvbHV0aW9uIHNwYWNlLCBnaXZlbiB0aGUgc2ltcGxpY2l0eSBvZiB0aGlzIHNhbXBsZSBjb2RlKS4KLSAgICBQcmVmaXhSZXNvbHZlckRlZmF1bHQgcHJlZml4UmVzb2x2ZXIgPSBuZXcgUHJlZml4UmVzb2x2ZXJEZWZhdWx0KAotICAgICAgKG5hbWVzcGFjZU5vZGUuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLkRPQ1VNRU5UX05PREUpCi0gICAgICA/ICgoRG9jdW1lbnQpIG5hbWVzcGFjZU5vZGUpLmdldERvY3VtZW50RWxlbWVudCgpIDogbmFtZXNwYWNlTm9kZSk7Ci0KLSAgICAvLyBDcmVhdGUgdGhlIFhQYXRoIG9iamVjdC4KLSAgICBYUGF0aCB4cGF0aCA9IG5ldyBYUGF0aChzdHIsIG51bGwsIHByZWZpeFJlc29sdmVyLCBYUGF0aC5TRUxFQ1QsIG51bGwpOwotCi0gICAgLy8gRXhlY3V0ZSB0aGUgWFBhdGgsIGFuZCBoYXZlIGl0IHJldHVybiB0aGUgcmVzdWx0Ci0gICAgLy8gcmV0dXJuIHhwYXRoLmV4ZWN1dGUoeHBhdGhTdXBwb3J0LCBjb250ZXh0Tm9kZSwgcHJlZml4UmVzb2x2ZXIpOwotICAgIGludCBjdHh0Tm9kZSA9IHhwYXRoU3VwcG9ydC5nZXREVE1IYW5kbGVGcm9tTm9kZShjb250ZXh0Tm9kZSk7Ci0KLSAgICByZXR1cm4geHBhdGguZXhlY3V0ZSh4cGF0aFN1cHBvcnQsIGN0eHROb2RlLCBwcmVmaXhSZXNvbHZlcik7Ci0gIH0KLQotICAvKioKLSAgICogICBFdmFsdWF0ZSBYUGF0aCBzdHJpbmcgdG8gYW4gWE9iamVjdC4KLSAgICogICBYUGF0aCBuYW1lc3BhY2UgcHJlZml4ZXMgYXJlIHJlc29sdmVkIGZyb20gdGhlIG5hbWVzcGFjZU5vZGUuCi0gICAqICAgVGhlIGltcGxlbWVudGF0aW9uIG9mIHRoaXMgaXMgYSBsaXR0bGUgc2xvdywgc2luY2UgaXQgY3JlYXRlcwotICAgKiAgIGEgbnVtYmVyIG9mIG9iamVjdHMgZWFjaCB0aW1lIGl0IGlzIGNhbGxlZC4gIFRoaXMgY291bGQgYmUgb3B0aW1pemVkCi0gICAqICAgdG8ga2VlcCB0aGUgc2FtZSBvYmplY3RzIGFyb3VuZCwgYnV0IHRoZW4gdGhyZWFkLXNhZmV0eSBpc3N1ZXMgd291bGQgYXJpc2UuCi0gICAqCi0gICAqICAgQHBhcmFtIGNvbnRleHROb2RlIFRoZSBub2RlIHRvIHN0YXJ0IHNlYXJjaGluZyBmcm9tLgotICAgKiAgIEBwYXJhbSBzdHIgQSB2YWxpZCBYUGF0aCBzdHJpbmcuCi0gICAqICAgQHBhcmFtIHByZWZpeFJlc29sdmVyIFdpbGwgYmUgY2FsbGVkIGlmIHRoZSBwYXJzZXIgZW5jb3VudGVycyBuYW1lc3BhY2UKLSAgICogICAgICAgICAgICAgICAgICAgICAgICAgcHJlZml4ZXMsIHRvIHJlc29sdmUgdGhlIHByZWZpeGVzIHRvIFVSTHMuCi0gICAqICAgQHJldHVybiBBbiBYT2JqZWN0LCB3aGljaCBjYW4gYmUgdXNlZCB0byBvYnRhaW4gYSBzdHJpbmcsIG51bWJlciwgbm9kZWxpc3QsIGV0Yywgc2hvdWxkIG5ldmVyIGJlIG51bGwuCi0gICAqICAgQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YT2JqZWN0Ci0gICAqICAgQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YTnVsbAotICAgKiAgIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWEJvb2xlYW4KLSAgICogICBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhOdW1iZXIKLSAgICogICBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhTdHJpbmcKLSAgICogICBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhSVHJlZUZyYWcKLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljICBYT2JqZWN0IGV2YWwoCi0gICAgICAgICAgTm9kZSBjb250ZXh0Tm9kZSwgU3RyaW5nIHN0ciwgUHJlZml4UmVzb2x2ZXIgcHJlZml4UmVzb2x2ZXIpCi0gICAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgLy8gU2luY2Ugd2UgZG9uJ3QgaGF2ZSBhIFhNTCBQYXJzZXIgaW52b2x2ZWQgaGVyZSwgaW5zdGFsbCBzb21lIGRlZmF1bHQgc3VwcG9ydAotICAgIC8vIGZvciB0aGluZ3MgbGlrZSBuYW1lc3BhY2VzLCBldGMuCi0gICAgLy8gKENoYW5nZWQgZnJvbTogWFBhdGhDb250ZXh0IHhwYXRoU3VwcG9ydCA9IG5ldyBYUGF0aENvbnRleHQoKTsKLSAgICAvLyAgICBiZWNhdXNlIFhQYXRoQ29udGV4dCBpcyB3ZWFrIGluIGEgbnVtYmVyIG9mIGFyZWFzLi4uIHBlcmhhcHMKLSAgICAvLyAgICBYUGF0aENvbnRleHQgc2hvdWxkIGJlIGRvbmUgYXdheSB3aXRoLikKLSAgICAvLyBDcmVhdGUgdGhlIFhQYXRoIG9iamVjdC4KLSAgICBYUGF0aCB4cGF0aCA9IG5ldyBYUGF0aChzdHIsIG51bGwsIHByZWZpeFJlc29sdmVyLCBYUGF0aC5TRUxFQ1QsIG51bGwpOwotCi0gICAgLy8gRXhlY3V0ZSB0aGUgWFBhdGgsIGFuZCBoYXZlIGl0IHJldHVybiB0aGUgcmVzdWx0Ci0gICAgWFBhdGhDb250ZXh0IHhwYXRoU3VwcG9ydCA9IG5ldyBYUGF0aENvbnRleHQoKTsKLSAgICBpbnQgY3R4dE5vZGUgPSB4cGF0aFN1cHBvcnQuZ2V0RFRNSGFuZGxlRnJvbU5vZGUoY29udGV4dE5vZGUpOwotCi0gICAgcmV0dXJuIHhwYXRoLmV4ZWN1dGUoeHBhdGhTdXBwb3J0LCBjdHh0Tm9kZSwgcHJlZml4UmVzb2x2ZXIpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL0V4cHJlc3Npb24uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvRXhwcmVzc2lvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhMTZkMTM3Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvRXhwcmVzc2lvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTkxICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IEV4cHJlc3Npb24uamF2YSx2IDEuMi40LjIgMjAwNS8wOS8xNCAxOTo1MDoyMCBqZWZmc3V0dG9yIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5FcnJvckxpc3RlbmVyOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwucmVzLlhTTE1lc3NhZ2VzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1JdGVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLlhNTFN0cmluZzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YTm9kZVNldDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YT2JqZWN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5yZXMuWFBBVEhFcnJvclJlc291cmNlczsKLQotaW1wb3J0IG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyOwotCi0vKioKLSAqIFRoaXMgYWJzdHJhY3QgY2xhc3Mgc2VydmVzIGFzIHRoZSBiYXNlIGZvciBhbGwgZXhwcmVzc2lvbiBvYmplY3RzLiAgQW4KLSAqIEV4cHJlc3Npb24gY2FuIGJlIGV4ZWN1dGVkIHRvIHJldHVybiBhIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YT2JqZWN0fSwKLSAqIG5vcm1hbGx5IGhhcyBhIGxvY2F0aW9uIHdpdGhpbiBhIGRvY3VtZW50IG9yIERPTSwgY2FuIHNlbmQgZXJyb3IgYW5kIHdhcm5pbmcKLSAqIGV2ZW50cywgYW5kIG5vcm1hbGx5IGRvIG5vdCBob2xkIHN0YXRlIGFuZCBhcmUgbWVhbnQgdG8gYmUgaW1tdXRhYmxlIG9uY2UKLSAqIGNvbnN0cnVjdGlvbiBoYXMgY29tcGxldGVkLiAgQW4gZXhjZXB0aW9uIHRvIHRoZSBpbW11dGliaWxpdHkgcnVsZSBpcyBpdGVyYXRvcnMKLSAqIGFuZCB3YWxrZXJzLCB3aGljaCBtdXN0IGJlIGNsb25lZCBpbiBvcmRlciB0byBiZSB1c2VkIC0tIHRoZSBvcmlnaW5hbCBtdXN0Ci0gKiBzdGlsbCBiZSBpbW11dGFibGUuCi0gKi8KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBFeHByZXNzaW9uIGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUsIEV4cHJlc3Npb25Ob2RlLCBYUGF0aFZpc2l0YWJsZQotewotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA1NjU2NjU4Njk3Nzc5MDY5MDJMOwotICAvKioKLSAgICogVGhlIGxvY2F0aW9uIHdoZXJlIHRoaXMgZXhwcmVzc2lvbiB3YXMgYnVpbHQgZnJvbS4gIE5lZWQgZm9yIGRpYWdub3N0aWMKLSAgICogIG1lc3NhZ2VzLiBNYXkgYmUgbnVsbC4KLSAgICogIEBzZXJpYWwKLSAgICovCi0gIHByaXZhdGUgRXhwcmVzc2lvbk5vZGUgbV9wYXJlbnQ7Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgdGhpcyBleHByZXNzaW9uIG9yIGl0J3Mgc3ViZXhwcmVzc2lvbnMgY2FuIHRyYXZlcnNlIG91dHNpZGUKLSAgICogdGhlIGN1cnJlbnQgc3VidHJlZS4KLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHRyYXZlcnNhbCBvdXRzaWRlIHRoZSBjb250ZXh0IG5vZGUncyBzdWJ0cmVlIGNhbiBvY2N1ci4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGNhblRyYXZlcnNlT3V0c2lkZVN1YnRyZWUoKQotICB7Ci0gICAgcmV0dXJuIGZhbHNlOwotICB9Ci0KLS8vICAvKioKLS8vICAgKiBTZXQgdGhlIGxvY2F0aW9uIHdoZXJlIHRoaXMgZXhwcmVzc2lvbiB3YXMgYnVpbHQgZnJvbS4KLS8vICAgKgotLy8gICAqCi0vLyAgICogQHBhcmFtIGxvY2F0b3IgdGhlIGxvY2F0aW9uIHdoZXJlIHRoaXMgZXhwcmVzc2lvbiB3YXMgYnVpbHQgZnJvbSwgbWF5IGJlCi0vLyAgICogICAgICAgICAgICAgICAgbnVsbC4KLS8vICAgKi8KLS8vICBwdWJsaWMgdm9pZCBzZXRTb3VyY2VMb2NhdG9yKFNvdXJjZUxvY2F0b3IgbG9jYXRvcikKLS8vICB7Ci0vLyAgICBtX3Nsb2NhdG9yID0gbG9jYXRvcjsKLS8vICB9Ci0KLSAgLyoqCi0gICAqIEV4ZWN1dGUgYW4gZXhwcmVzc2lvbiBpbiB0aGUgWFBhdGggcnVudGltZSBjb250ZXh0LCBhbmQgcmV0dXJuIHRoZQotICAgKiByZXN1bHQgb2YgdGhlIGV4cHJlc3Npb24uCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgWFBhdGggcnVudGltZSBjb250ZXh0LgotICAgKiBAcGFyYW0gY3VycmVudE5vZGUgVGhlIGN1cnJlbnROb2RlLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSByZXN1bHQgb2YgdGhlIGV4cHJlc3Npb24gaW4gdGhlIGZvcm0gb2YgYSA8Y29kZT5YT2JqZWN0PC9jb2RlPi4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uIGlmIGEgcnVudGltZSBleGNlcHRpb24KLSAgICogICAgICAgICBvY2N1cnMuCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBleGVjdXRlKFhQYXRoQ29udGV4dCB4Y3R4dCwgaW50IGN1cnJlbnROb2RlKQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIC8vIEZvciBub3csIHRoZSBjdXJyZW50IG5vZGUgaXMgYWxyZWFkeSBwdXNoZWQuCi0gICAgcmV0dXJuIGV4ZWN1dGUoeGN0eHQpOwotICB9Ci0KLSAgLyoqCi0gICAqIEV4ZWN1dGUgYW4gZXhwcmVzc2lvbiBpbiB0aGUgWFBhdGggcnVudGltZSBjb250ZXh0LCBhbmQgcmV0dXJuIHRoZQotICAgKiByZXN1bHQgb2YgdGhlIGV4cHJlc3Npb24uCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgWFBhdGggcnVudGltZSBjb250ZXh0LgotICAgKiBAcGFyYW0gY3VycmVudE5vZGUgVGhlIGN1cnJlbnROb2RlLgotICAgKiBAcGFyYW0gZHRtIFRoZSBEVE0gb2YgdGhlIGN1cnJlbnQgbm9kZS4KLSAgICogQHBhcmFtIGV4cFR5cGUgVGhlIGV4cGFuZGVkIHR5cGUgSUQgb2YgdGhlIGN1cnJlbnQgbm9kZS4KLSAgICoKLSAgICogQHJldHVybiBUaGUgcmVzdWx0IG9mIHRoZSBleHByZXNzaW9uIGluIHRoZSBmb3JtIG9mIGEgPGNvZGU+WE9iamVjdDwvY29kZT4uCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbiBpZiBhIHJ1bnRpbWUgZXhjZXB0aW9uCi0gICAqICAgICAgICAgb2NjdXJzLgotICAgKi8KLSAgcHVibGljIFhPYmplY3QgZXhlY3V0ZSgKLSAgICAgICAgICBYUGF0aENvbnRleHQgeGN0eHQsIGludCBjdXJyZW50Tm9kZSwgRFRNIGR0bSwgaW50IGV4cFR5cGUpCi0gICAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICAvLyBGb3Igbm93LCB0aGUgY3VycmVudCBub2RlIGlzIGFscmVhZHkgcHVzaGVkLgotICAgIHJldHVybiBleGVjdXRlKHhjdHh0KTsKLSAgfQotCi0gIC8qKgotICAgKiBFeGVjdXRlIGFuIGV4cHJlc3Npb24gaW4gdGhlIFhQYXRoIHJ1bnRpbWUgY29udGV4dCwgYW5kIHJldHVybiB0aGUKLSAgICogcmVzdWx0IG9mIHRoZSBleHByZXNzaW9uLgotICAgKgotICAgKgotICAgKiBAcGFyYW0geGN0eHQgVGhlIFhQYXRoIHJ1bnRpbWUgY29udGV4dC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgcmVzdWx0IG9mIHRoZSBleHByZXNzaW9uIGluIHRoZSBmb3JtIG9mIGEgPGNvZGU+WE9iamVjdDwvY29kZT4uCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbiBpZiBhIHJ1bnRpbWUgZXhjZXB0aW9uCi0gICAqICAgICAgICAgb2NjdXJzLgotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IFhPYmplY3QgZXhlY3V0ZShYUGF0aENvbnRleHQgeGN0eHQpCi0gICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci0KLSAgLyoqCi0gICAqIEV4ZWN1dGUgYW4gZXhwcmVzc2lvbiBpbiB0aGUgWFBhdGggcnVudGltZSBjb250ZXh0LCBhbmQgcmV0dXJuIHRoZQotICAgKiByZXN1bHQgb2YgdGhlIGV4cHJlc3Npb24sIGJ1dCB0ZWxsIHRoYXQgYSAic2FmZSIgb2JqZWN0IGRvZXNuJ3QgaGF2ZQotICAgKiB0byBiZSByZXR1cm5lZC4gIFRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIGp1c3QgY2FsbHMgZXhlY3V0ZSh4Y3R4dCkuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgWFBhdGggcnVudGltZSBjb250ZXh0LgotICAgKiBAcGFyYW0gZGVzdHJ1Y3RpdmVPSyB0cnVlIGlmIGEgInNhZmUiIG9iamVjdCBkb2Vzbid0IG5lZWQgdG8gYmUgcmV0dXJuZWQuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHJlc3VsdCBvZiB0aGUgZXhwcmVzc2lvbiBpbiB0aGUgZm9ybSBvZiBhIDxjb2RlPlhPYmplY3Q8L2NvZGU+LgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24gaWYgYSBydW50aW1lIGV4Y2VwdGlvbgotICAgKiAgICAgICAgIG9jY3Vycy4KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IGV4ZWN1dGUoWFBhdGhDb250ZXh0IHhjdHh0LCBib29sZWFuIGRlc3RydWN0aXZlT0spCi0gICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgICAgICByZXR1cm4gZXhlY3V0ZSh4Y3R4dCk7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBFdmFsdWF0ZSBleHByZXNzaW9uIHRvIGEgbnVtYmVyLgotICAgKgotICAgKgotICAgKiBAcGFyYW0geGN0eHQgVGhlIFhQYXRoIHJ1bnRpbWUgY29udGV4dC4KLSAgICogQHJldHVybiBUaGUgZXhwcmVzc2lvbiBldmFsdWF0ZWQgYXMgYSBkb3VibGUuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGRvdWJsZSBudW0oWFBhdGhDb250ZXh0IHhjdHh0KQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gZXhlY3V0ZSh4Y3R4dCkubnVtKCk7Ci0gIH0KLQotICAvKioKLSAgICogRXZhbHVhdGUgZXhwcmVzc2lvbiB0byBhIGJvb2xlYW4uCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgWFBhdGggcnVudGltZSBjb250ZXh0LgotICAgKiBAcmV0dXJuIGZhbHNlCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gYm9vbChYUGF0aENvbnRleHQgeGN0eHQpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHJldHVybiBleGVjdXRlKHhjdHh0KS5ib29sKCk7Ci0gIH0KLQotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGEgc3RyaW5nLgotICAgKgotICAgKgotICAgKiBAcGFyYW0geGN0eHQgVGhlIFhQYXRoIHJ1bnRpbWUgY29udGV4dC4KLSAgICogQHJldHVybiBUaGUgc3RyaW5nIHRoaXMgd3JhcHMgb3IgdGhlIGVtcHR5IHN0cmluZyBpZiBudWxsCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFhNTFN0cmluZyB4c3RyKFhQYXRoQ29udGV4dCB4Y3R4dCkKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIGV4ZWN1dGUoeGN0eHQpLnhzdHIoKTsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIGlmIHRoZSBleHByZXNzaW9uIGlzIGEgbm9kZXNldCBleHByZXNzaW9uLiAgSW4gb3RoZXIgd29yZHMsIHRlbGwKLSAgICogaWYgeW91IGNhbiBleGVjdXRlIHtAbGluayAjYXNOb2RlKFhQYXRoQ29udGV4dCkgYXNOb2RlfSB3aXRob3V0IGFuIGV4Y2VwdGlvbi4KLSAgICogQHJldHVybiB0cnVlIGlmIHRoZSBleHByZXNzaW9uIGNhbiBiZSByZXByZXNlbnRlZCBhcyBhIG5vZGVzZXQuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBpc05vZGVzZXRFeHByKCkKLSAgewotICAgIHJldHVybiBmYWxzZTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIGZpcnN0IG5vZGUgb3V0IG9mIHRoZSBub2Rlc2V0LCBpZiB0aGlzIGV4cHJlc3Npb24gaXMKLSAgICogYSBub2Rlc2V0IGV4cHJlc3Npb24uCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgWFBhdGggcnVudGltZSBjb250ZXh0LgotICAgKiBAcmV0dXJuIHRoZSBmaXJzdCBub2RlIG91dCBvZiB0aGUgbm9kZXNldCwgb3IgRFRNLk5VTEwuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGludCBhc05vZGUoWFBhdGhDb250ZXh0IHhjdHh0KQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICAgICAgRFRNSXRlcmF0b3IgaXRlciA9IGV4ZWN1dGUoeGN0eHQpLml0ZXIoKTsKLSAgICByZXR1cm4gaXRlci5uZXh0Tm9kZSgpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGFuIHNlbGVjdCBleHByZXNzaW9uIGFuZCBhIGNvbnRleHQsIGV2YWx1YXRlIHRoZSBYUGF0aAotICAgKiBhbmQgcmV0dXJuIHRoZSByZXN1bHRpbmcgaXRlcmF0b3IuCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgZXhlY3V0aW9uIGNvbnRleHQuCi0gICAqIEBwYXJhbSBjb250ZXh0Tm9kZSBUaGUgbm9kZSB0aGF0ICIuIiBleHByZXNzZXMuCi0gICAqCi0gICAqCi0gICAqIEByZXR1cm4gQSB2YWxpZCBEVE1JdGVyYXRvci4KLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiB0aHJvd24gaWYgdGhlIGFjdGl2ZSBQcm9ibGVtTGlzdGVuZXIgZGVjaWRlcwotICAgKiB0aGUgZXJyb3IgY29uZGl0aW9uIGlzIHNldmVyZSBlbm91Z2ggdG8gaGFsdCBwcm9jZXNzaW5nLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICogQHhzbC51c2FnZSBleHBlcmltZW50YWwKLSAgICovCi0gIHB1YmxpYyBEVE1JdGVyYXRvciBhc0l0ZXJhdG9yKFhQYXRoQ29udGV4dCB4Y3R4dCwgaW50IGNvbnRleHROb2RlKQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIHhjdHh0LnB1c2hDdXJyZW50Tm9kZUFuZEV4cHJlc3Npb24oY29udGV4dE5vZGUsIGNvbnRleHROb2RlKTsKLQotICAgICAgcmV0dXJuIGV4ZWN1dGUoeGN0eHQpLml0ZXIoKTsKLSAgICB9Ci0gICAgZmluYWxseQotICAgIHsKLSAgICAgIHhjdHh0LnBvcEN1cnJlbnROb2RlQW5kRXhwcmVzc2lvbigpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBHaXZlbiBhbiBzZWxlY3QgZXhwcmVzc2lvbiBhbmQgYSBjb250ZXh0LCBldmFsdWF0ZSB0aGUgWFBhdGgKLSAgICogYW5kIHJldHVybiB0aGUgcmVzdWx0aW5nIGl0ZXJhdG9yLCBidXQgZG8gbm90IGNsb25lLgotICAgKgotICAgKiBAcGFyYW0geGN0eHQgVGhlIGV4ZWN1dGlvbiBjb250ZXh0LgotICAgKiBAcGFyYW0gY29udGV4dE5vZGUgVGhlIG5vZGUgdGhhdCAiLiIgZXhwcmVzc2VzLgotICAgKgotICAgKgotICAgKiBAcmV0dXJuIEEgdmFsaWQgRFRNSXRlcmF0b3IuCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24gdGhyb3duIGlmIHRoZSBhY3RpdmUgUHJvYmxlbUxpc3RlbmVyIGRlY2lkZXMKLSAgICogdGhlIGVycm9yIGNvbmRpdGlvbiBpcyBzZXZlcmUgZW5vdWdoIHRvIGhhbHQgcHJvY2Vzc2luZy4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqIEB4c2wudXNhZ2UgZXhwZXJpbWVudGFsCi0gICAqLwotICBwdWJsaWMgRFRNSXRlcmF0b3IgYXNJdGVyYXRvclJhdyhYUGF0aENvbnRleHQgeGN0eHQsIGludCBjb250ZXh0Tm9kZSkKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICB0cnkKLSAgICB7Ci0gICAgICB4Y3R4dC5wdXNoQ3VycmVudE5vZGVBbmRFeHByZXNzaW9uKGNvbnRleHROb2RlLCBjb250ZXh0Tm9kZSk7Ci0KLSAgICAgIFhOb2RlU2V0IG5vZGVzZXQgPSAoWE5vZGVTZXQpZXhlY3V0ZSh4Y3R4dCk7Ci0gICAgICByZXR1cm4gbm9kZXNldC5pdGVyUmF3KCk7Ci0gICAgfQotICAgIGZpbmFsbHkKLSAgICB7Ci0gICAgICB4Y3R4dC5wb3BDdXJyZW50Tm9kZUFuZEV4cHJlc3Npb24oKTsKLSAgICB9Ci0gIH0KLQotCi0gIC8qKgotICAgKiBFeGVjdXRlIGFuIGV4cHJlc3Npb24gaW4gdGhlIFhQYXRoIHJ1bnRpbWUgY29udGV4dCwgYW5kIHJldHVybiB0aGUKLSAgICogcmVzdWx0IG9mIHRoZSBleHByZXNzaW9uLgotICAgKgotICAgKgotICAgKiBAcGFyYW0geGN0eHQgVGhlIFhQYXRoIHJ1bnRpbWUgY29udGV4dC4KLSAgICogTkVFRFNET0MgQHBhcmFtIGhhbmRsZXIKLSAgICoKLSAgICogQHJldHVybiBUaGUgcmVzdWx0IG9mIHRoZSBleHByZXNzaW9uIGluIHRoZSBmb3JtIG9mIGEgPGNvZGU+WE9iamVjdDwvY29kZT4uCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbiBpZiBhIHJ1bnRpbWUgZXhjZXB0aW9uCi0gICAqICAgICAgICAgb2NjdXJzLgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgZXhlY3V0ZUNoYXJzVG9Db250ZW50SGFuZGxlcigKLSAgICAgICAgICBYUGF0aENvbnRleHQgeGN0eHQsIENvbnRlbnRIYW5kbGVyIGhhbmRsZXIpCi0gICAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbiwKLSAgICAgICAgICAgICAgICAgICBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgWE9iamVjdCBvYmogPSBleGVjdXRlKHhjdHh0KTsKLQotICAgIG9iai5kaXNwYXRjaENoYXJhY3RlcnNFdmVudHMoaGFuZGxlcik7Ci0gICAgb2JqLmRldGFjaCgpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgdGhpcyBleHByZXNzaW9uIHJldHVybnMgYSBzdGFibGUgbnVtYmVyIHRoYXQgd2lsbCBub3QgY2hhbmdlIGR1cmluZwotICAgKiBpdGVyYXRpb25zIHdpdGhpbiB0aGUgZXhwcmVzc2lvbi4gIFRoaXMgaXMgdXNlZCB0byBkZXRlcm1pbmUgaWYgYSBwcm94aW1pdHkKLSAgICogcG9zaXRpb24gcHJlZGljYXRlIGNhbiBpbmRpY2F0ZSB0aGF0IG5vIG1vcmUgc2VhcmNoaW5nIGhhcyB0byBvY2N1ci4KLSAgICoKLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHRoZSBleHByZXNzaW9uIHJlcHJlc2VudHMgYSBzdGFibGUgbnVtYmVyLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNTdGFibGVOdW1iZXIoKQotICB7Ci0gICAgcmV0dXJuIGZhbHNlOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoaXMgZnVuY3Rpb24gaXMgdXNlZCB0byBmaXh1cCB2YXJpYWJsZXMgZnJvbSBRTmFtZXMgdG8gc3RhY2sgZnJhbWUKLSAgICogaW5kZXhlcyBhdCBzdHlsZXNoZWV0IGJ1aWxkIHRpbWUuCi0gICAqIEBwYXJhbSB2YXJzIExpc3Qgb2YgUU5hbWVzIHRoYXQgY29ycmVzcG9uZCB0byB2YXJpYWJsZXMuICBUaGlzIGxpc3QKLSAgICogc2hvdWxkIGJlIHNlYXJjaGVkIGJhY2t3YXJkcyBmb3IgdGhlIGZpcnN0IHF1YWxpZmllZCBuYW1lIHRoYXQKLSAgICogY29ycmVzcG9uZHMgdG8gdGhlIHZhcmlhYmxlIHJlZmVyZW5jZSBxbmFtZS4gIFRoZSBwb3NpdGlvbiBvZiB0aGUKLSAgICogUU5hbWUgaW4gdGhlIHZlY3RvciBmcm9tIHRoZSBzdGFydCBvZiB0aGUgdmVjdG9yIHdpbGwgYmUgaXRzIHBvc2l0aW9uCi0gICAqIGluIHRoZSBzdGFjayBmcmFtZSAoYnV0IHZhcmlhYmxlcyBhYm92ZSB0aGUgZ2xvYmFsc1RvcCB2YWx1ZSB3aWxsIG5lZWQKLSAgICogdG8gYmUgb2Zmc2V0IHRvIHRoZSBjdXJyZW50IHN0YWNrIGZyYW1lKS4KLSAgICogTkVFRFNET0MgQHBhcmFtIGdsb2JhbHNTaXplCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBmaXh1cFZhcmlhYmxlcyhqYXZhLnV0aWwuVmVjdG9yIHZhcnMsIGludCBnbG9iYWxzU2l6ZSk7Ci0KLSAgLyoqCi0gICAqIENvbXBhcmUgdGhpcyBvYmplY3Qgd2l0aCBhbm90aGVyIG9iamVjdCBhbmQgc2VlCi0gICAqIGlmIHRoZXkgYXJlIGVxdWFsLCBpbmNsdWRlIHRoZSBzdWIgaGVhcmFyY2h5LgotICAgKgotICAgKiBAcGFyYW0gZXhwciBBbm90aGVyIGV4cHJlc3Npb24gb2JqZWN0LgotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhpcyBvYmplY3RzIGNsYXNzIGFuZCB0aGUgZXhwcgotICAgKiBvYmplY3QncyBjbGFzcyBhcmUgdGhlIHNhbWUsIGFuZCB0aGUgZGF0YSBjb250YWluZWQKLSAgICogd2l0aGluIGJvdGggb2JqZWN0cyBhcmUgY29uc2lkZXJlZCBlcXVhbC4KLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGRlZXBFcXVhbHMoRXhwcmVzc2lvbiBleHByKTsKLQotICAvKioKLSAgICogVGhpcyBpcyBhIHV0aWxpdHkgbWV0aG9kIHRvIHRlbGwgaWYgdGhlIHBhc3NlZCBpbgotICAgKiBjbGFzcyBpcyB0aGUgc2FtZSBjbGFzcyBhcyB0aGlzLiAgSXQgaXMgdG8gYmUgdXNlZCBieQotICAgKiB0aGUgZGVlcEVxdWFscyBtZXRob2QuICBJJ20gYm90dGxlbmVja2luZyBpdCBoZXJlCi0gICAqIGJlY2F1c2UgSSdtIG5vdCB0b3RhbGx5IGNvbmZpZGVudCB0aGF0IGNvbXBhcmluZyB0aGUKLSAgICogY2xhc3Mgb2JqZWN0cyBpcyB0aGUgYmVzdCB3YXkgdG8gZG8gdGhpcy4KLSAgICogQHJldHVybiB0cnVlIG9mIHRoZSBwYXNzZWQgaW4gY2xhc3MgaXMgdGhlIGV4YWN0IHNhbWUKLSAgICogY2xhc3MgYXMgdGhpcyBjbGFzcy4KLSAgICovCi0gIHByb3RlY3RlZCBmaW5hbCBib29sZWFuIGlzU2FtZUNsYXNzKEV4cHJlc3Npb24gZXhwcikKLSAgewotICAgICAgICBpZihudWxsID09IGV4cHIpCi0gICAgICAgICAgcmV0dXJuIGZhbHNlOwotCi0gICAgICAgIHJldHVybiAoZ2V0Q2xhc3MoKSA9PSBleHByLmdldENsYXNzKCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIFdhcm4gdGhlIHVzZXIgb2YgYW4gcHJvYmxlbS4KLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IFRoZSBYUGF0aCBydW50aW1lIGNvbnRleHQuCi0gICAqIEBwYXJhbSBtc2cgQW4gZXJyb3IgbXNna2V5IHRoYXQgY29ycmVzcG9uZHMgdG8gb25lIG9mIHRoZSBjb25zdHN0YW50cyBmb3VuZAotICAgKiAgICAgICAgICAgIGluIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucmVzLlhQQVRIRXJyb3JSZXNvdXJjZXN9LCB3aGljaCBpcwotICAgKiAgICAgICAgICAgIGEga2V5IGZvciBhIGZvcm1hdCBzdHJpbmcuCi0gICAqIEBwYXJhbSBhcmdzIEFuIGFycmF5IG9mIGFyZ3VtZW50cyByZXByZXNlbnRlZCBpbiB0aGUgZm9ybWF0IHN0cmluZywgd2hpY2gKLSAgICogICAgICAgICAgICAgbWF5IGJlIG51bGwuCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24gaWYgdGhlIGN1cnJlbnQgRXJyb3JMaXN0b25lciBkZXRlcm1pbmVzIHRvCi0gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgYW4gZXhjZXB0aW9uLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHdhcm4oWFBhdGhDb250ZXh0IHhjdHh0LCBTdHJpbmcgbXNnLCBPYmplY3RbXSBhcmdzKQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGphdmEubGFuZy5TdHJpbmcgZm1zZyA9IFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRIV2FybmluZyhtc2csIGFyZ3MpOwotCi0gICAgaWYgKG51bGwgIT0geGN0eHQpCi0gICAgewotICAgICAgRXJyb3JMaXN0ZW5lciBlaCA9IHhjdHh0LmdldEVycm9yTGlzdGVuZXIoKTsKLQotICAgICAgLy8gVE8gRE86IE5lZWQgdG8gZ2V0IHN0eWxlc2hlZXQgTG9jYXRvciBmcm9tIGhlcmUuCi0gICAgICBlaC53YXJuaW5nKG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihmbXNnLCB4Y3R4dC5nZXRTQVhMb2NhdG9yKCkpKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogVGVsbCB0aGUgdXNlciBvZiBhbiBhc3NlcnRpb24gZXJyb3IsIGFuZCBwcm9iYWJseSB0aHJvdyBhbgotICAgKiBleGNlcHRpb24uCi0gICAqCi0gICAqIEBwYXJhbSBiICBJZiBmYWxzZSwgYSBydW50aW1lIGV4Y2VwdGlvbiB3aWxsIGJlIHRocm93bi4KLSAgICogQHBhcmFtIG1zZyBUaGUgYXNzZXJ0aW9uIG1lc3NhZ2UsIHdoaWNoIHNob3VsZCBiZSBpbmZvcm1hdGl2ZS4KLSAgICoKLSAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIGlmIHRoZSBiIGFyZ3VtZW50IGlzIGZhbHNlLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGFzc2VydGlvbihib29sZWFuIGIsIGphdmEubGFuZy5TdHJpbmcgbXNnKQotICB7Ci0KLSAgICBpZiAoIWIpCi0gICAgewotICAgICAgamF2YS5sYW5nLlN0cmluZyBmTXNnID0gWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKAotICAgICAgICBYUEFUSEVycm9yUmVzb3VyY2VzLkVSX0lOQ09SUkVDVF9QUk9HUkFNTUVSX0FTU0VSVElPTiwKLSAgICAgICAgbmV3IE9iamVjdFtdeyBtc2cgfSk7Ci0KLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGZNc2cpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIHRoZSB1c2VyIG9mIGFuIGVycm9yLCBhbmQgcHJvYmFibHkgdGhyb3cgYW4KLSAgICogZXhjZXB0aW9uLgotICAgKgotICAgKiBAcGFyYW0geGN0eHQgVGhlIFhQYXRoIHJ1bnRpbWUgY29udGV4dC4KLSAgICogQHBhcmFtIG1zZyBBbiBlcnJvciBtc2drZXkgdGhhdCBjb3JyZXNwb25kcyB0byBvbmUgb2YgdGhlIGNvbnN0YW50cyBmb3VuZAotICAgKiAgICAgICAgICAgIGluIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucmVzLlhQQVRIRXJyb3JSZXNvdXJjZXN9LCB3aGljaCBpcwotICAgKiAgICAgICAgICAgIGEga2V5IGZvciBhIGZvcm1hdCBzdHJpbmcuCi0gICAqIEBwYXJhbSBhcmdzIEFuIGFycmF5IG9mIGFyZ3VtZW50cyByZXByZXNlbnRlZCBpbiB0aGUgZm9ybWF0IHN0cmluZywgd2hpY2gKLSAgICogICAgICAgICAgICAgbWF5IGJlIG51bGwuCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24gaWYgdGhlIGN1cnJlbnQgRXJyb3JMaXN0b25lciBkZXRlcm1pbmVzIHRvCi0gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgYW4gZXhjZXB0aW9uLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGVycm9yKFhQYXRoQ29udGV4dCB4Y3R4dCwgU3RyaW5nIG1zZywgT2JqZWN0W10gYXJncykKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBqYXZhLmxhbmcuU3RyaW5nIGZtc2cgPSBYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UobXNnLCBhcmdzKTsKLQotICAgIGlmIChudWxsICE9IHhjdHh0KQotICAgIHsKLSAgICAgIEVycm9yTGlzdGVuZXIgZWggPSB4Y3R4dC5nZXRFcnJvckxpc3RlbmVyKCk7Ci0gICAgICBUcmFuc2Zvcm1lckV4Y2VwdGlvbiB0ZSA9IG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihmbXNnLCB0aGlzKTsKLQotICAgICAgZWguZmF0YWxFcnJvcih0ZSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgZmlyc3Qgbm9uLUV4cHJlc3Npb24gcGFyZW50IG9mIHRoaXMgbm9kZS4KLSAgICogQHJldHVybiBudWxsIG9yIGZpcnN0IGFuY2VzdG9yIHRoYXQgaXMgbm90IGFuIEV4cHJlc3Npb24uCi0gICAqLwotICBwdWJsaWMgRXhwcmVzc2lvbk5vZGUgZ2V0RXhwcmVzc2lvbk93bmVyKCkKLSAgewotICAgICAgICBFeHByZXNzaW9uTm9kZSBwYXJlbnQgPSBleHByR2V0UGFyZW50KCk7Ci0gICAgICAgIHdoaWxlKChudWxsICE9IHBhcmVudCkgJiYgKHBhcmVudCBpbnN0YW5jZW9mIEV4cHJlc3Npb24pKQotICAgICAgICAgICAgICAgIHBhcmVudCA9IHBhcmVudC5leHByR2V0UGFyZW50KCk7Ci0gICAgICAgIHJldHVybiBwYXJlbnQ7Ci0gIH0KLQotICAvLz09PT09PT09PT09PT09PSBFeHByZXNzaW9uTm9kZSBtZXRob2RzID09PT09PT09PT09PT09PT0KLQotICAvKiogVGhpcyBwYWlyIG9mIG1ldGhvZHMgYXJlIHVzZWQgdG8gaW5mb3JtIHRoZSBub2RlIG9mIGl0cwotICAgIHBhcmVudC4gKi8KLSAgcHVibGljIHZvaWQgZXhwclNldFBhcmVudChFeHByZXNzaW9uTm9kZSBuKQotICB7Ci0gICAgICAgIGFzc2VydGlvbihuICE9IHRoaXMsICJDYW4gbm90IHBhcmVudCBhbiBleHByZXNzaW9uIHRvIGl0c2VsZiEiKTsKLSAgICAgICAgbV9wYXJlbnQgPSBuOwotICB9Ci0KLSAgcHVibGljIEV4cHJlc3Npb25Ob2RlIGV4cHJHZXRQYXJlbnQoKQotICB7Ci0gICAgICAgIHJldHVybiBtX3BhcmVudDsKLSAgfQotCi0gIC8qKiBUaGlzIG1ldGhvZCB0ZWxscyB0aGUgbm9kZSB0byBhZGQgaXRzIGFyZ3VtZW50IHRvIHRoZSBub2RlJ3MKLSAgICBsaXN0IG9mIGNoaWxkcmVuLiAgKi8KLSAgcHVibGljIHZvaWQgZXhwckFkZENoaWxkKEV4cHJlc3Npb25Ob2RlIG4sIGludCBpKQotICB7Ci0gICAgICAgIGFzc2VydGlvbihmYWxzZSwgImV4cHJBZGRDaGlsZCBtZXRob2Qgbm90IGltcGxlbWVudGVkISIpOwotICB9Ci0KLSAgLyoqIFRoaXMgbWV0aG9kIHJldHVybnMgYSBjaGlsZCBub2RlLiAgVGhlIGNoaWxkcmVuIGFyZSBudW1iZXJlZAotICAgICBmcm9tIHplcm8sIGxlZnQgdG8gcmlnaHQuICovCi0gIHB1YmxpYyBFeHByZXNzaW9uTm9kZSBleHByR2V0Q2hpbGQoaW50IGkpCi0gIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKiogUmV0dXJuIHRoZSBudW1iZXIgb2YgY2hpbGRyZW4gdGhlIG5vZGUgaGFzLiAqLwotICBwdWJsaWMgaW50IGV4cHJHZXROdW1DaGlsZHJlbigpCi0gIHsKLSAgICAgICAgcmV0dXJuIDA7Ci0gIH0KLQotICAvLz09PT09PT09PT09PT09PSBTb3VyY2VMb2NhdG9yIG1ldGhvZHMgPT09PT09PT09PT09PT09PQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIHB1YmxpYyBpZGVudGlmaWVyIGZvciB0aGUgY3VycmVudCBkb2N1bWVudCBldmVudC4KLSAgICoKLSAgICogPHA+VGhlIHJldHVybiB2YWx1ZSBpcyB0aGUgcHVibGljIGlkZW50aWZpZXIgb2YgdGhlIGRvY3VtZW50Ci0gICAqIGVudGl0eSBvciBvZiB0aGUgZXh0ZXJuYWwgcGFyc2VkIGVudGl0eSBpbiB3aGljaCB0aGUgbWFya3VwIHRoYXQKLSAgICogdHJpZ2dlcmVkIHRoZSBldmVudCBhcHBlYXJzLjwvcD4KLSAgICoKLSAgICogQHJldHVybiBBIHN0cmluZyBjb250YWluaW5nIHRoZSBwdWJsaWMgaWRlbnRpZmllciwgb3IKLSAgICogICAgICAgICBudWxsIGlmIG5vbmUgaXMgYXZhaWxhYmxlLgotICAgKiBAc2VlICNnZXRTeXN0ZW1JZAotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRQdWJsaWNJZCgpCi0gIHsKLSAgICAgICAgaWYobnVsbCA9PSBtX3BhcmVudCkKLSAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgcmV0dXJuIG1fcGFyZW50LmdldFB1YmxpY0lkKCk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBzeXN0ZW0gaWRlbnRpZmllciBmb3IgdGhlIGN1cnJlbnQgZG9jdW1lbnQgZXZlbnQuCi0gICAqCi0gICAqIDxwPlRoZSByZXR1cm4gdmFsdWUgaXMgdGhlIHN5c3RlbSBpZGVudGlmaWVyIG9mIHRoZSBkb2N1bWVudAotICAgKiBlbnRpdHkgb3Igb2YgdGhlIGV4dGVybmFsIHBhcnNlZCBlbnRpdHkgaW4gd2hpY2ggdGhlIG1hcmt1cCB0aGF0Ci0gICAqIHRyaWdnZXJlZCB0aGUgZXZlbnQgYXBwZWFycy48L3A+Ci0gICAqCi0gICAqIDxwPklmIHRoZSBzeXN0ZW0gaWRlbnRpZmllciBpcyBhIFVSTCwgdGhlIHBhcnNlciBtdXN0IHJlc29sdmUgaXQKLSAgICogZnVsbHkgYmVmb3JlIHBhc3NpbmcgaXQgdG8gdGhlIGFwcGxpY2F0aW9uLjwvcD4KLSAgICoKLSAgICogQHJldHVybiBBIHN0cmluZyBjb250YWluaW5nIHRoZSBzeXN0ZW0gaWRlbnRpZmllciwgb3IgbnVsbAotICAgKiAgICAgICAgIGlmIG5vbmUgaXMgYXZhaWxhYmxlLgotICAgKiBAc2VlICNnZXRQdWJsaWNJZAotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRTeXN0ZW1JZCgpCi0gIHsKLSAgICAgICAgaWYobnVsbCA9PSBtX3BhcmVudCkKLSAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgcmV0dXJuIG1fcGFyZW50LmdldFN5c3RlbUlkKCk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBsaW5lIG51bWJlciB3aGVyZSB0aGUgY3VycmVudCBkb2N1bWVudCBldmVudCBlbmRzLgotICAgKgotICAgKiA8cD48c3Ryb25nPldhcm5pbmc6PC9zdHJvbmc+IFRoZSByZXR1cm4gdmFsdWUgZnJvbSB0aGUgbWV0aG9kCi0gICAqIGlzIGludGVuZGVkIG9ubHkgYXMgYW4gYXBwcm94aW1hdGlvbiBmb3IgdGhlIHNha2Ugb2YgZXJyb3IKLSAgICogcmVwb3J0aW5nOyBpdCBpcyBub3QgaW50ZW5kZWQgdG8gcHJvdmlkZSBzdWZmaWNpZW50IGluZm9ybWF0aW9uCi0gICAqIHRvIGVkaXQgdGhlIGNoYXJhY3RlciBjb250ZW50IG9mIHRoZSBvcmlnaW5hbCBYTUwgZG9jdW1lbnQuPC9wPgotICAgKgotICAgKiA8cD5UaGUgcmV0dXJuIHZhbHVlIGlzIGFuIGFwcHJveGltYXRpb24gb2YgdGhlIGxpbmUgbnVtYmVyCi0gICAqIGluIHRoZSBkb2N1bWVudCBlbnRpdHkgb3IgZXh0ZXJuYWwgcGFyc2VkIGVudGl0eSB3aGVyZSB0aGUKLSAgICogbWFya3VwIHRoYXQgdHJpZ2dlcmVkIHRoZSBldmVudCBhcHBlYXJzLjwvcD4KLSAgICoKLSAgICogQHJldHVybiBUaGUgbGluZSBudW1iZXIsIG9yIC0xIGlmIG5vbmUgaXMgYXZhaWxhYmxlLgotICAgKiBAc2VlICNnZXRDb2x1bW5OdW1iZXIKLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0TGluZU51bWJlcigpCi0gIHsKLSAgICAgICAgaWYobnVsbCA9PSBtX3BhcmVudCkKLSAgICAgICAgICByZXR1cm4gMDsKLSAgICAgICAgcmV0dXJuIG1fcGFyZW50LmdldExpbmVOdW1iZXIoKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIGNoYXJhY3RlciBwb3NpdGlvbiB3aGVyZSB0aGUgY3VycmVudCBkb2N1bWVudCBldmVudCBlbmRzLgotICAgKgotICAgKiA8cD48c3Ryb25nPldhcm5pbmc6PC9zdHJvbmc+IFRoZSByZXR1cm4gdmFsdWUgZnJvbSB0aGUgbWV0aG9kCi0gICAqIGlzIGludGVuZGVkIG9ubHkgYXMgYW4gYXBwcm94aW1hdGlvbiBmb3IgdGhlIHNha2Ugb2YgZXJyb3IKLSAgICogcmVwb3J0aW5nOyBpdCBpcyBub3QgaW50ZW5kZWQgdG8gcHJvdmlkZSBzdWZmaWNpZW50IGluZm9ybWF0aW9uCi0gICAqIHRvIGVkaXQgdGhlIGNoYXJhY3RlciBjb250ZW50IG9mIHRoZSBvcmlnaW5hbCBYTUwgZG9jdW1lbnQuPC9wPgotICAgKgotICAgKiA8cD5UaGUgcmV0dXJuIHZhbHVlIGlzIGFuIGFwcHJveGltYXRpb24gb2YgdGhlIGNvbHVtbiBudW1iZXIKLSAgICogaW4gdGhlIGRvY3VtZW50IGVudGl0eSBvciBleHRlcm5hbCBwYXJzZWQgZW50aXR5IHdoZXJlIHRoZQotICAgKiBtYXJrdXAgdGhhdCB0cmlnZ2VyZWQgdGhlIGV2ZW50IGFwcGVhcnMuPC9wPgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBjb2x1bW4gbnVtYmVyLCBvciAtMSBpZiBub25lIGlzIGF2YWlsYWJsZS4KLSAgICogQHNlZSAjZ2V0TGluZU51bWJlcgotICAgKi8KLSAgcHVibGljIGludCBnZXRDb2x1bW5OdW1iZXIoKQotICB7Ci0gICAgICAgIGlmKG51bGwgPT0gbV9wYXJlbnQpCi0gICAgICAgICAgcmV0dXJuIDA7Ci0gICAgICAgIHJldHVybiBtX3BhcmVudC5nZXRDb2x1bW5OdW1iZXIoKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9FeHByZXNzaW9uTm9kZS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9FeHByZXNzaW9uTm9kZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1OTFjYzVlLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvRXhwcmVzc2lvbk5vZGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDUzICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IEV4cHJlc3Npb25Ob2RlLmphdmEsdiAxLjEuMi4xIDIwMDUvMDgvMDEgMDE6MzA6MTUgamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbDsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uU291cmNlTG9jYXRvcjsKLQotLyoqCi0gKiBBIGNsYXNzIHRoYXQgaW1wbGVtZW50cyB0aGlzIGludGVyZmFjZSBjYW4gY29uc3RydWN0IGV4cHJlc3Npb25zLAotICogZ2l2ZSBpbmZvcm1hdGlvbiBhYm91dCBjaGlsZCBhbmQgcGFyZW50IGV4cHJlc3Npb25zLAotICogYW5kIGdpdmUgdGhlIG9yaWdpbmF0aW5nIHNvdXJjZSBpbmZvcm1hdGlvbi4gIEEgY2xhc3MgdGhhdCBpbXBsZW1lbnRzCi0gKiB0aGlzIGludGVyZmFjZSBkb2VzIG5vdCBsYXkgYW55IGNsYWltIHRvIGJlaW5nIGRpcmVjdGx5IGV4ZWN1dGFibGUuCi0gKgotICogPHA+Tm90ZTogVGhpcyBpbnRlcmZhY2Ugc2hvdWxkIG5vdCBiZSBjb25zaWRlcmVkIHN0YWJsZS4gIE9ubHkgZXhwclNldFBhcmVudAotICogYW5kIGV4cHJHZXRQYXJlbnQgY2FuIGJlIGNvdW50ZWQgb24gdG8gd29yayByZWxpYWJseS4gIFdvcmsgaW4gcHJvZ3Jlc3MuPC9wPgotICovCi1wdWJsaWMgaW50ZXJmYWNlIEV4cHJlc3Npb25Ob2RlIGV4dGVuZHMgU291cmNlTG9jYXRvcgotewotICAvKiogVGhpcyBwYWlyIG9mIG1ldGhvZHMgYXJlIHVzZWQgdG8gaW5mb3JtIHRoZSBub2RlIG9mIGl0cwotICAgIHBhcmVudC4gKi8KLSAgcHVibGljIHZvaWQgZXhwclNldFBhcmVudChFeHByZXNzaW9uTm9kZSBuKTsKLSAgcHVibGljIEV4cHJlc3Npb25Ob2RlIGV4cHJHZXRQYXJlbnQoKTsKLQotICAvKiogVGhpcyBtZXRob2QgdGVsbHMgdGhlIG5vZGUgdG8gYWRkIGl0cyBhcmd1bWVudCB0byB0aGUgbm9kZSdzCi0gICAgbGlzdCBvZiBjaGlsZHJlbi4gICovCi0gIHB1YmxpYyB2b2lkIGV4cHJBZGRDaGlsZChFeHByZXNzaW9uTm9kZSBuLCBpbnQgaSk7Ci0KLSAgLyoqIFRoaXMgbWV0aG9kIHJldHVybnMgYSBjaGlsZCBub2RlLiAgVGhlIGNoaWxkcmVuIGFyZSBudW1iZXJlZAotICAgICBmcm9tIHplcm8sIGxlZnQgdG8gcmlnaHQuICovCi0gIHB1YmxpYyBFeHByZXNzaW9uTm9kZSBleHByR2V0Q2hpbGQoaW50IGkpOwotCi0gIC8qKiBSZXR1cm4gdGhlIG51bWJlciBvZiBjaGlsZHJlbiB0aGUgbm9kZSBoYXMuICovCi0gIHB1YmxpYyBpbnQgZXhwckdldE51bUNoaWxkcmVuKCk7Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL0V4cHJlc3Npb25Pd25lci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9FeHByZXNzaW9uT3duZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZGZjYTQ3Yy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL0V4cHJlc3Npb25Pd25lci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDYgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRXhwcmVzc2lvbk93bmVyLmphdmEsdiAxLjEuMi4xIDIwMDUvMDgvMDEgMDE6MzA6MTIgamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbDsKLQotLyoqCi0gKiBDbGFzc2VzIHRoYXQgaW1wbGVtZW50IHRoaXMgaW50ZXJmYWNlIG93biBhbiBleHByZXNzaW9uLCB3aGljaAotICogY2FuIGJlIHJld3JpdHRlbi4KLSAqLwotcHVibGljIGludGVyZmFjZSBFeHByZXNzaW9uT3duZXIKLXsKLSAgLyoqCi0gICAqIEdldCB0aGUgcmF3IEV4cHJlc3Npb24gb2JqZWN0IHRoYXQgdGhpcyBjbGFzcyB3cmFwcy4KLSAgICoKLSAgICogQHJldHVybiB0aGUgcmF3IEV4cHJlc3Npb24gb2JqZWN0LCB3aGljaCBzaG91bGQgbm90IG5vcm1hbGx5IGJlIG51bGwuCi0gICAqLwotICBwdWJsaWMgRXhwcmVzc2lvbiBnZXRFeHByZXNzaW9uKCk7Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgcmF3IGV4cHJlc3Npb24gb2JqZWN0IGZvciB0aGlzIG9iamVjdC4KLSAgICoKLSAgICogQHBhcmFtIGV4cCB0aGUgcmF3IEV4cHJlc3Npb24gb2JqZWN0LCB3aGljaCBzaG91bGQgbm90IG5vcm1hbGx5IGJlIG51bGwuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRFeHByZXNzaW9uKEV4cHJlc3Npb24gZXhwKTsKLQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL0V4dGVuc2lvbnNQcm92aWRlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9FeHRlbnNpb25zUHJvdmlkZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYjk0OTM4NS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL0V4dGVuc2lvbnNQcm92aWRlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNjIgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRXh0ZW5zaW9uc1Byb3ZpZGVyLmphdmEsdiAxLjEuMi4xIDIwMDUvMDgvMDEgMDE6MzA6MDggamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbDsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuZnVuY3Rpb25zLkZ1bmNFeHRGdW5jdGlvbjsKLQotLyoqCi0gKiBJbnRlcmZhY2UgdGhhdCBYUGF0aCBvYmplY3RzIGNhbiBjYWxsIHRvIG9idGFpbiBhY2Nlc3MgdG8gYW4KLSAqIEV4dGVuc2lvbnNUYWJsZS4KLSAqCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgRXh0ZW5zaW9uc1Byb3ZpZGVyCi17Ci0gIC8qKgotICAgKiBJcyB0aGUgZXh0ZW5zaW9uIGZ1bmN0aW9uIGF2YWlsYWJsZT8KLSAgICovCi0KLSAgcHVibGljIGJvb2xlYW4gZnVuY3Rpb25BdmFpbGFibGUoU3RyaW5nIG5zLCBTdHJpbmcgZnVuY05hbWUpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci0KLSAgLyoqCi0gICAqIElzIHRoZSBleHRlbnNpb24gZWxlbWVudCBhdmFpbGFibGU/Ci0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBlbGVtZW50QXZhaWxhYmxlKFN0cmluZyBucywgU3RyaW5nIGVsZW1OYW1lKQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotCi0gIC8qKgotICAgKiBFeGVjdXRlIHRoZSBleHRlbnNpb24gZnVuY3Rpb24uCi0gICAqLwotICBwdWJsaWMgT2JqZWN0IGV4dEZ1bmN0aW9uKFN0cmluZyBucywgU3RyaW5nIGZ1bmNOYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlY3RvciBhcmdWZWMsIE9iamVjdCBtZXRob2RLZXkpCi0gICAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLQotICAvKioKLSAgICogRXhlY3V0ZSB0aGUgZXh0ZW5zaW9uIGZ1bmN0aW9uLgotICAgKi8KLSAgcHVibGljIE9iamVjdCBleHRGdW5jdGlvbihGdW5jRXh0RnVuY3Rpb24gZXh0RnVuY3Rpb24sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgVmVjdG9yIGFyZ1ZlYykKLSAgICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9Gb3VuZEluZGV4LmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL0ZvdW5kSW5kZXguamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYTZmMmE0Ny4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL0ZvdW5kSW5kZXguamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDM5ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IEZvdW5kSW5kZXguamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNCAxOTo1MDoyMCBqZWZmc3V0dG9yIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsOwotCi0vKioKLSAqIENsYXNzIHRvIGxldCB1cyBrbm93IHdoZW4gaXQncyB0aW1lIHRvIGRvCi0gKiBhIHNlYXJjaCBmcm9tIHRoZSBwYXJlbnQgYmVjYXVzZSBvZiBpbmRleGluZy4KLSAqIEB4c2wudXNhZ2UgaW50ZXJuYWwKLSAqLwotcHVibGljIGNsYXNzIEZvdW5kSW5kZXggZXh0ZW5kcyBSdW50aW1lRXhjZXB0aW9uCi17Ci0gICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC00NjQzOTc1MzM1MjQzMDc4MjcwTDsKLQotICAvKioKLSAgICogQ29uc3RydWN0b3IgRm91bmRJbmRleAotICAgKgotICAgKi8KLSAgcHVibGljIEZvdW5kSW5kZXgoKXt9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL05vZGVTZXQuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvTm9kZVNldC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzNDA5ZTdmLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvTm9kZVNldC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTM3MiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBOb2RlU2V0LmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTAgMTc6Mzk6NDkgamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbDsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC5yZXMuWFNMTWVzc2FnZXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5ET00ySGVscGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5heGVzLkNvbnRleHROb2RlTGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucmVzLlhQQVRIRXJyb3JSZXNvdXJjZXM7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5ET01FeGNlcHRpb247Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlTGlzdDsKLWltcG9ydCBvcmcudzNjLmRvbS50cmF2ZXJzYWwuTm9kZUZpbHRlcjsKLWltcG9ydCBvcmcudzNjLmRvbS50cmF2ZXJzYWwuTm9kZUl0ZXJhdG9yOwotCi0KLS8qKgotICogPHA+VGhlIE5vZGVTZXQgY2xhc3MgY2FuIGFjdCBhcyBlaXRoZXIgYSBOb2RlVmVjdG9yLAotICogTm9kZUxpc3QsIG9yIE5vZGVJdGVyYXRvci4gIEhvd2V2ZXIsIGluIG9yZGVyIGZvciBpdCB0bwotICogYWN0IGFzIGEgTm9kZVZlY3RvciBvciBOb2RlTGlzdCwgaXQncyByZXF1aXJlZCB0aGF0Ci0gKiBzZXRTaG91bGRDYWNoZU5vZGVzKHRydWUpIGJlIGNhbGxlZCBiZWZvcmUgdGhlIGZpcnN0Ci0gKiBuZXh0Tm9kZSgpIGlzIGNhbGxlZCwgaW4gb3JkZXIgdGhhdCBub2RlcyBjYW4gYmUgYWRkZWQKLSAqIGFzIHRoZXkgYXJlIGZldGNoZWQuICBEZXJpdmVkIGNsYXNzZXMgdGhhdCBpbXBsZW1lbnQgaXRlcmF0b3JzCi0gKiBtdXN0IG92ZXJyaWRlIHJ1blRvKGludCBpbmRleCksIGluIG9yZGVyIHRoYXQgdGhleSBtYXkKLSAqIHJ1biB0aGUgaXRlcmF0aW9uIHRvIHRoZSBnaXZlbiBpbmRleC4gPC9wPgotICoKLSAqIDxwPk5vdGUgdGhhdCB3ZSBkaXJlY3RseSBpbXBsZW1lbnQgdGhlIERPTSdzIE5vZGVJdGVyYXRvcgotICogaW50ZXJmYWNlLiBXZSBkbyBub3QgZW11bGF0ZSBhbGwgdGhlIGJlaGF2aW9yIG9mIHRoZQotICogc3RhbmRhcmQgTm9kZUl0ZXJhdG9yLiBJbiBwYXJ0aWN1bGFyLCB3ZSBkbyBub3QgZ3VhcmFudGVlCi0gKiB0byBwcmVzZW50IGEgImxpdmUgdmlldyIgb2YgdGhlIGRvY3VtZW50IC4uLiBidXQgaW4gWFNMVCwKLSAqIHRoZSBzb3VyY2UgZG9jdW1lbnQgc2hvdWxkIG5ldmVyIGJlIG11dGF0ZWQsIHNvIHRoaXMgc2hvdWxkCi0gKiBuZXZlciBiZSBhbiBpc3N1ZS48L3A+Ci0gKgotICogPHA+VGhvdWdodDogU2hvdWxkIE5vZGVTZXQgcmVhbGx5IGltcGxlbWVudCBOb2RlTGlzdCBhbmQgTm9kZUl0ZXJhdG9yLAotICogb3Igc2hvdWxkIHRoZXJlIGJlIHNwZWNpZmljIHN1YmNsYXNzZXMgb2YgaXQgd2hpY2ggZG8gc28/IFRoZQotICogYWR2YW50YWdlIG9mIGRvaW5nIGl0IGFsbCBoZXJlIGlzIHRoYXQgYWxsIE5vZGVTZXRzIHdpbGwgcmVzcG9uZAotICogdG8gdGhlIHNhbWUgY2FsbHM7IHRoZSBkaXNhZHZhbnRhZ2UgaXMgdGhhdCBzb21lIG9mIHRoZW0gbWF5IHJldHVybgotICogbGVzcy10aGFuLWVubGlnaHRlbmluZyByZXN1bHRzIHdoZW4geW91IGRvIHNvLjwvcD4KLSAqIEB4c2wudXNhZ2UgYWR2YW5jZWQKLSAqLwotcHVibGljIGNsYXNzIE5vZGVTZXQKLSAgICAgICAgaW1wbGVtZW50cyBOb2RlTGlzdCwgTm9kZUl0ZXJhdG9yLCBDbG9uZWFibGUsIENvbnRleHROb2RlTGlzdAotewotCi0gIC8qKgotICAgKiBDcmVhdGUgYW4gZW1wdHkgbm9kZWxpc3QuCi0gICAqLwotICBwdWJsaWMgTm9kZVNldCgpCi0gIHsKLSAgICBtX2Jsb2Nrc2l6ZSA9IDMyOwotICAgIG1fbWFwU2l6ZSA9IDA7Ci0gIH0KLQotICAvKioKLSAgICogQ3JlYXRlIGFuIGVtcHR5LCB1c2luZyB0aGUgZ2l2ZW4gYmxvY2sgc2l6ZS4KLSAgICoKLSAgICogQHBhcmFtIGJsb2Nrc2l6ZSBTaXplIG9mIGJsb2NrcyB0byBhbGxvY2F0ZQotICAgKi8KLSAgcHVibGljIE5vZGVTZXQoaW50IGJsb2Nrc2l6ZSkKLSAgewotICAgIG1fYmxvY2tzaXplID0gYmxvY2tzaXplOwotICAgIG1fbWFwU2l6ZSA9IDA7Ci0gIH0KLQotICAvKioKLSAgICogQ3JlYXRlIGEgTm9kZVNldCwgYW5kIGNvcHkgdGhlIG1lbWJlcnMgb2YgdGhlCi0gICAqIGdpdmVuIG5vZGVsaXN0IGludG8gaXQuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlbGlzdCBMaXN0IG9mIE5vZGVzIHRvIGJlIG1hZGUgbWVtYmVycyBvZiB0aGUgbmV3IHNldC4KLSAgICovCi0gIHB1YmxpYyBOb2RlU2V0KE5vZGVMaXN0IG5vZGVsaXN0KQotICB7Ci0KLSAgICB0aGlzKDMyKTsKLQotICAgIGFkZE5vZGVzKG5vZGVsaXN0KTsKLSAgfQotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBOb2RlU2V0LCBhbmQgY29weSB0aGUgbWVtYmVycyBvZiB0aGUKLSAgICogZ2l2ZW4gTm9kZVNldCBpbnRvIGl0LgotICAgKgotICAgKiBAcGFyYW0gbm9kZWxpc3QgU2V0IG9mIE5vZGVzIHRvIGJlIG1hZGUgbWVtYmVycyBvZiB0aGUgbmV3IHNldC4KLSAgICovCi0gIHB1YmxpYyBOb2RlU2V0KE5vZGVTZXQgbm9kZWxpc3QpCi0gIHsKLQotICAgIHRoaXMoMzIpOwotCi0gICAgYWRkTm9kZXMoKE5vZGVJdGVyYXRvcikgbm9kZWxpc3QpOwotICB9Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIE5vZGVTZXQsIGFuZCBjb3B5IHRoZSBtZW1iZXJzIG9mIHRoZQotICAgKiBnaXZlbiBOb2RlSXRlcmF0b3IgaW50byBpdC4KLSAgICoKLSAgICogQHBhcmFtIG5pIEl0ZXJhdG9yIHdoaWNoIHlpZWxkcyBOb2RlcyB0byBiZSBtYWRlIG1lbWJlcnMgb2YgdGhlIG5ldyBzZXQuCi0gICAqLwotICBwdWJsaWMgTm9kZVNldChOb2RlSXRlcmF0b3IgbmkpCi0gIHsKLQotICAgIHRoaXMoMzIpOwotCi0gICAgYWRkTm9kZXMobmkpOwotICB9Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIE5vZGVTZXQgd2hpY2ggY29udGFpbnMgdGhlIGdpdmVuIE5vZGUuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlIFNpbmdsZSBub2RlIHRvIGJlIGFkZGVkIHRvIHRoZSBuZXcgc2V0LgotICAgKi8KLSAgcHVibGljIE5vZGVTZXQoTm9kZSBub2RlKQotICB7Ci0KLSAgICB0aGlzKDMyKTsKLQotICAgIGFkZE5vZGUobm9kZSk7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBUaGUgcm9vdCBub2RlIG9mIHRoZSBJdGVyYXRvciwgYXMgc3BlY2lmaWVkIHdoZW4gaXQgd2FzIGNyZWF0ZWQuCi0gICAqIEZvciBub24tSXRlcmF0b3IgTm9kZVNldHMsIHRoaXMgd2lsbCBiZSBudWxsLgotICAgKi8KLSAgcHVibGljIE5vZGUgZ2V0Um9vdCgpCi0gIHsKLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgYSBjbG9uZWQgSXRlcmF0b3IsIGFuZCByZXNldCBpdHMgc3RhdGUgdG8gdGhlIGJlZ2lubmluZyBvZiB0aGUKLSAgICogaXRlcmF0aW9uLgotICAgKgotICAgKiBAcmV0dXJuIGEgbmV3IE5vZGVTZXQgb2YgdGhlIHNhbWUgdHlwZSwgaGF2aW5nIHRoZSBzYW1lIHN0YXRlLi4uCi0gICAqIGV4Y2VwdCB0aGF0IHRoZSByZXNldCgpIG9wZXJhdGlvbiBoYXMgYmVlbiBjYWxsZWQuCi0gICAqCi0gICAqIEB0aHJvd3MgQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gaWYgdGhpcyBzdWJjbGFzcyBvZiBOb2RlU2V0Ci0gICAqIGRvZXMgbm90IHN1cHBvcnQgdGhlIGNsb25lKCkgb3BlcmF0aW9uLgotICAgKi8KLSAgcHVibGljIE5vZGVJdGVyYXRvciBjbG9uZVdpdGhSZXNldCgpIHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbgotICB7Ci0KLSAgICBOb2RlU2V0IGNsb25lID0gKE5vZGVTZXQpIGNsb25lKCk7Ci0KLSAgICBjbG9uZS5yZXNldCgpOwotCi0gICAgcmV0dXJuIGNsb25lOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlc2V0IHRoZSBpdGVyYXRvci4gTWF5IGhhdmUgbm8gZWZmZWN0IG9uIG5vbi1pdGVyYXRvciBOb2Rlc2V0cy4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHJlc2V0KCkKLSAgewotICAgIG1fbmV4dCA9IDA7Ci0gIH0KLQotICAvKioKLSAgICogIFRoaXMgYXR0cmlidXRlIGRldGVybWluZXMgd2hpY2ggbm9kZSB0eXBlcyBhcmUgcHJlc2VudGVkIHZpYSB0aGUKLSAgICogaXRlcmF0b3IuIFRoZSBhdmFpbGFibGUgc2V0IG9mIGNvbnN0YW50cyBpcyBkZWZpbmVkIGluIHRoZQotICAgKiA8Y29kZT5Ob2RlRmlsdGVyPC9jb2RlPiBpbnRlcmZhY2UuIEZvciBOb2RlU2V0cywgdGhlIG1hc2sgaGFzIGJlZW4KLSAgICogaGFyZGNvZGVkIHRvIHNob3cgYWxsIG5vZGVzIGV4Y2VwdCBFbnRpdHlSZWZlcmVuY2Ugbm9kZXMsIHdoaWNoIGhhdmUKLSAgICogbm8gZXF1aXZhbGVudCBpbiB0aGUgWFBhdGggZGF0YSBtb2RlbC4KLSAgICoKLSAgICogQHJldHVybiBpbnRlZ2VyIHVzZWQgYXMgYSBiaXQtYXJyYXksIGNvbnRhaW5pbmcgZmxhZ3MgZGVmaW5lZCBpbgotICAgKiB0aGUgRE9NJ3MgTm9kZUZpbHRlciBjbGFzcy4gVGhlIHZhbHVlIHdpbGwgYmUKLSAgICogPGNvZGU+U0hPV19BTEwgJiB+U0hPV19FTlRJVFlfUkVGRVJFTkNFPC9jb2RlPiwgbWVhbmluZyB0aGF0Ci0gICAqIG9ubHkgZW50aXR5IHJlZmVyZW5jZXMgYXJlIHN1cHByZXNzZWQuCi0gICAqLwotICBwdWJsaWMgaW50IGdldFdoYXRUb1Nob3coKQotICB7Ci0gICAgcmV0dXJuIE5vZGVGaWx0ZXIuU0hPV19BTEwgJiB+Tm9kZUZpbHRlci5TSE9XX0VOVElUWV9SRUZFUkVOQ0U7Ci0gIH0KLQotICAvKioKLSAgICogVGhlIGZpbHRlciBvYmplY3QgdXNlZCB0byBzY3JlZW4gbm9kZXMuIEZpbHRlcnMgYXJlIGFwcGxpZWQgdG8KLSAgICogZnVydGhlciByZWR1Y2UgKGFuZCByZXN0cnVjdHVyZSkgdGhlIE5vZGVJdGVyYXRvcidzIHZpZXcgb2YgdGhlCi0gICAqIGRvY3VtZW50LiBJbiBvdXIgY2FzZSwgd2Ugd2lsbCBiZSB1c2luZyBoYXJkY29kZWQgZmlsdGVycyBidWlsdAotICAgKiBpbnRvIG91ciBpdGVyYXRvcnMuLi4gYnV0IGdldEZpbHRlcigpIGlzIHBhcnQgb2YgdGhlIERPTSdzCi0gICAqIE5vZGVJdGVyYXRvciBpbnRlcmZhY2UsIHNvIHdlIGhhdmUgdG8gc3VwcG9ydCBpdC4KLSAgICoKLSAgICogQHJldHVybiBudWxsLCB3aGljaCBpcyBzbGlnaHRseSBtaXNsZWFkaW5nLiBUcnVlLCB0aGVyZSBpcyBubwotICAgKiB1c2VyLXdyaXR0ZW4gZmlsdGVyIG9iamVjdCwgYnV0IGluIGZhY3Qgd2UgYXJlIGRvaW5nIHNvbWUgdmVyeQotICAgKiBzb3BoaXN0aWNhdGVkIGN1c3RvbSBmaWx0ZXJpbmcuIEEgRE9NIHB1cmlzdCBtaWdodCBzdWdnZXN0Ci0gICAqIHJldHVybmluZyBhIHBsYWNlaG9sZGVyIG9iamVjdCBqdXN0IHRvIGluZGljYXRlIHRoYXQgdGhpcyBpcwotICAgKiBub3QgZ29pbmcgdG8gcmV0dXJuIGFsbCBub2RlcyBzZWxlY3RlZCBieSB3aGF0VG9TaG93LgotICAgKi8KLSAgcHVibGljIE5vZGVGaWx0ZXIgZ2V0RmlsdGVyKCkKLSAgewotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqICBUaGUgdmFsdWUgb2YgdGhpcyBmbGFnIGRldGVybWluZXMgd2hldGhlciB0aGUgY2hpbGRyZW4gb2YgZW50aXR5Ci0gICAqIHJlZmVyZW5jZSBub2RlcyBhcmUgdmlzaWJsZSB0byB0aGUgaXRlcmF0b3IuIElmIGZhbHNlLCB0aGV5IHdpbGwgYmUKLSAgICogc2tpcHBlZCBvdmVyLgotICAgKiA8YnI+IFRvIHByb2R1Y2UgYSB2aWV3IG9mIHRoZSBkb2N1bWVudCB0aGF0IGhhcyBlbnRpdHkgcmVmZXJlbmNlcwotICAgKiBleHBhbmRlZCBhbmQgZG9lcyBub3QgZXhwb3NlIHRoZSBlbnRpdHkgcmVmZXJlbmNlIG5vZGUgaXRzZWxmLCB1c2UgdGhlCi0gICAqIHdoYXRUb1Nob3cgZmxhZ3MgdG8gaGlkZSB0aGUgZW50aXR5IHJlZmVyZW5jZSBub2RlIGFuZCBzZXQKLSAgICogZXhwYW5kRW50aXR5UmVmZXJlbmNlcyB0byB0cnVlIHdoZW4gY3JlYXRpbmcgdGhlIGl0ZXJhdG9yLiBUbyBwcm9kdWNlCi0gICAqIGEgdmlldyBvZiB0aGUgZG9jdW1lbnQgdGhhdCBoYXMgZW50aXR5IHJlZmVyZW5jZSBub2RlcyBidXQgbm8gZW50aXR5Ci0gICAqIGV4cGFuc2lvbiwgdXNlIHRoZSB3aGF0VG9TaG93IGZsYWdzIHRvIHNob3cgdGhlIGVudGl0eSByZWZlcmVuY2Ugbm9kZQotICAgKiBhbmQgc2V0IGV4cGFuZEVudGl0eVJlZmVyZW5jZXMgdG8gZmFsc2UuCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBmb3IgYWxsIGl0ZXJhdG9ycyBiYXNlZCBvbiBOb2RlU2V0LCBtZWFuaW5nIHRoYXQgdGhlCi0gICAqIGNvbnRlbnRzIG9mIEVudGl0eVJlZnJlbmNlIG5vZGVzIG1heSBiZSByZXR1cm5lZCAodGhvdWdoIHdoYXRUb1Nob3cKLSAgICogc2F5cyB0aGF0IHRoZSBFbnRpdHlSZWZlcmVuY2VzIHRoZW1zZWx2ZXMgYXJlIG5vdCBzaG93bi4pCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBnZXRFeHBhbmRFbnRpdHlSZWZlcmVuY2VzKCkKLSAgewotICAgIHJldHVybiB0cnVlOwotICB9Ci0KLSAgLyoqCi0gICAqICBSZXR1cm5zIHRoZSBuZXh0IG5vZGUgaW4gdGhlIHNldCBhbmQgYWR2YW5jZXMgdGhlIHBvc2l0aW9uIG9mIHRoZQotICAgKiBpdGVyYXRvciBpbiB0aGUgc2V0LiBBZnRlciBhIE5vZGVJdGVyYXRvciBpcyBjcmVhdGVkLCB0aGUgZmlyc3QgY2FsbAotICAgKiB0byBuZXh0Tm9kZSgpIHJldHVybnMgdGhlIGZpcnN0IG5vZGUgaW4gdGhlIHNldC4KLSAgICogQHJldHVybiAgVGhlIG5leHQgPGNvZGU+Tm9kZTwvY29kZT4gaW4gdGhlIHNldCBiZWluZyBpdGVyYXRlZCBvdmVyLCBvcgotICAgKiAgIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoZXJlIGFyZSBubyBtb3JlIG1lbWJlcnMgaW4gdGhhdCBzZXQuCi0gICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gICAqICAgIElOVkFMSURfU1RBVEVfRVJSOiBSYWlzZWQgaWYgdGhpcyBtZXRob2QgaXMgY2FsbGVkIGFmdGVyIHRoZQotICAgKiAgIDxjb2RlPmRldGFjaDwvY29kZT4gbWV0aG9kIHdhcyBpbnZva2VkLgotICAgKi8KLSAgcHVibGljIE5vZGUgbmV4dE5vZGUoKSB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmICgobV9uZXh0KSA8IHRoaXMuc2l6ZSgpKQotICAgIHsKLSAgICAgIE5vZGUgbmV4dCA9IHRoaXMuZWxlbWVudEF0KG1fbmV4dCk7Ci0KLSAgICAgIG1fbmV4dCsrOwotCi0gICAgICByZXR1cm4gbmV4dDsKLSAgICB9Ci0gICAgZWxzZQotICAgICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogIFJldHVybnMgdGhlIHByZXZpb3VzIG5vZGUgaW4gdGhlIHNldCBhbmQgbW92ZXMgdGhlIHBvc2l0aW9uIG9mIHRoZQotICAgKiBpdGVyYXRvciBiYWNrd2FyZHMgaW4gdGhlIHNldC4KLSAgICogQHJldHVybiAgVGhlIHByZXZpb3VzIDxjb2RlPk5vZGU8L2NvZGU+IGluIHRoZSBzZXQgYmVpbmcgaXRlcmF0ZWQgb3ZlciwKLSAgICogICBvcjxjb2RlPm51bGw8L2NvZGU+IGlmIHRoZXJlIGFyZSBubyBtb3JlIG1lbWJlcnMgaW4gdGhhdCBzZXQuCi0gICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gICAqICAgIElOVkFMSURfU1RBVEVfRVJSOiBSYWlzZWQgaWYgdGhpcyBtZXRob2QgaXMgY2FsbGVkIGFmdGVyIHRoZQotICAgKiAgIDxjb2RlPmRldGFjaDwvY29kZT4gbWV0aG9kIHdhcyBpbnZva2VkLgotICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gdGhyb3duIGlmIHRoaXMgTm9kZVNldCBpcyBub3Qgb2YKLSAgICogYSBjYWNoZWQgdHlwZSwgYW5kIGhlbmNlIGRvZXNuJ3Qga25vdyB3aGF0IHRoZSBwcmV2aW91cyBub2RlIHdhcy4KLSAgICovCi0gIHB1YmxpYyBOb2RlIHByZXZpb3VzTm9kZSgpIHRocm93cyBET01FeGNlcHRpb24KLSAgewotCi0gICAgaWYgKCFtX2NhY2hlTm9kZXMpCi0gICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKLSAgICAgICAgWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfTk9ERVNFVF9DQU5OT1RfSVRFUkFURSwgbnVsbCkpOyAvLyJUaGlzIE5vZGVTZXQgY2FuIG5vdCBpdGVyYXRlIHRvIGEgcHJldmlvdXMgbm9kZSEiKTsKLQotICAgIGlmICgobV9uZXh0IC0gMSkgPiAwKQotICAgIHsKLSAgICAgIG1fbmV4dC0tOwotCi0gICAgICByZXR1cm4gdGhpcy5lbGVtZW50QXQobV9uZXh0KTsKLSAgICB9Ci0gICAgZWxzZQotICAgICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogRGV0YWNoZXMgdGhlIGl0ZXJhdG9yIGZyb20gdGhlIHNldCB3aGljaCBpdCBpdGVyYXRlZCBvdmVyLCByZWxlYXNpbmcKLSAgICogYW55IGNvbXB1dGF0aW9uYWwgcmVzb3VyY2VzIGFuZCBwbGFjaW5nIHRoZSBpdGVyYXRvciBpbiB0aGUgSU5WQUxJRAotICAgKiBzdGF0ZS4gQWZ0ZXI8Y29kZT5kZXRhY2g8L2NvZGU+IGhhcyBiZWVuIGludm9rZWQsIGNhbGxzIHRvCi0gICAqIDxjb2RlPm5leHROb2RlPC9jb2RlPiBvcjxjb2RlPnByZXZpb3VzTm9kZTwvY29kZT4gd2lsbCByYWlzZSB0aGUKLSAgICogZXhjZXB0aW9uIElOVkFMSURfU1RBVEVfRVJSLgotICAgKiA8cD4KLSAgICogVGhpcyBvcGVyYXRpb24gaXMgYSBuby1vcCBpbiBOb2RlU2V0LCBhbmQgd2lsbCBub3QgY2F1c2UKLSAgICogSU5WQUxJRF9TVEFURV9FUlIgdG8gYmUgcmFpc2VkIGJ5IGxhdGVyIG9wZXJhdGlvbnMuCi0gICAqIDwvcD4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGRldGFjaCgpe30KLQotICAvKioKLSAgICogVGVsbHMgaWYgdGhpcyBOb2RlU2V0IGlzICJmcmVzaCIsIGluIG90aGVyIHdvcmRzLCBpZgotICAgKiB0aGUgZmlyc3QgbmV4dE5vZGUoKSB0aGF0IGlzIGNhbGxlZCB3aWxsIHJldHVybiB0aGUKLSAgICogZmlyc3Qgbm9kZSBpbiB0aGUgc2V0LgotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYgbmV4dE5vZGUoKSB3b3VsZCByZXR1cm4gdGhlIGZpcnN0IG5vZGUgaW4gdGhlIHNldCwKLSAgICogZmFsc2UgaWYgaXQgd291bGQgcmV0dXJuIGEgbGF0ZXIgb25lLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNGcmVzaCgpCi0gIHsKLSAgICByZXR1cm4gKG1fbmV4dCA9PSAwKTsKLSAgfQotCi0gIC8qKgotICAgKiBJZiBhbiBpbmRleCBpcyByZXF1ZXN0ZWQsIE5vZGVTZXQgd2lsbCBjYWxsIHRoaXMgbWV0aG9kCi0gICAqIHRvIHJ1biB0aGUgaXRlcmF0b3IgdG8gdGhlIGluZGV4LiAgQnkgZGVmYXVsdCB0aGlzIHNldHMKLSAgICogbV9uZXh0IHRvIHRoZSBpbmRleC4gIElmIHRoZSBpbmRleCBhcmd1bWVudCBpcyAtMSwgdGhpcwotICAgKiBzaWduYWxzIHRoYXQgdGhlIGl0ZXJhdG9yIHNob3VsZCBiZSBydW4gdG8gdGhlIGVuZC4KLSAgICoKLSAgICogQHBhcmFtIGluZGV4IFBvc2l0aW9uIHRvIGFkdmFuY2UgKG9yIHJldHJlYXQpIHRvLCB3aXRoCi0gICAqIDAgcmVxdWVzdGluZyB0aGUgcmVzZXQgKCJmcmVzaCIpIHBvc2l0aW9uIGFuZCAtMSAob3IgaW5kZWVkCi0gICAqIGFueSBvdXQtb2YtYm91bmRzIHZhbHVlKSByZXF1ZXN0aW5nIHRoZSBmaW5hbCBwb3NpdGlvbi4KLSAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIHRocm93biBpZiB0aGlzIE5vZGVTZXQgaXMgbm90Ci0gICAqIG9uZSBvZiB0aGUgdHlwZXMgd2hpY2ggc3VwcG9ydHMgaW5kZXhpbmcvY291bnRpbmcuCi0gICAqLwotICBwdWJsaWMgdm9pZCBydW5UbyhpbnQgaW5kZXgpCi0gIHsKLQotICAgIGlmICghbV9jYWNoZU5vZGVzKQotICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCi0gICAgICAgIFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShYUEFUSEVycm9yUmVzb3VyY2VzLkVSX05PREVTRVRfQ0FOTk9UX0lOREVYLCBudWxsKSk7IC8vIlRoaXMgTm9kZVNldCBjYW4gbm90IGRvIGluZGV4aW5nIG9yIGNvdW50aW5nIGZ1bmN0aW9ucyEiKTsKLQotICAgIGlmICgoaW5kZXggPj0gMCkgJiYgKG1fbmV4dCA8IG1fZmlyc3RGcmVlKSkKLSAgICAgIG1fbmV4dCA9IGluZGV4OwotICAgIGVsc2UKLSAgICAgIG1fbmV4dCA9IG1fZmlyc3RGcmVlIC0gMTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSA8Y29kZT5pbmRleDwvY29kZT50aCBpdGVtIGluIHRoZSBjb2xsZWN0aW9uLiBJZgotICAgKiA8Y29kZT5pbmRleDwvY29kZT4gaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHRoZSBudW1iZXIgb2Ygbm9kZXMgaW4KLSAgICogdGhlIGxpc3QsIHRoaXMgcmV0dXJucyA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICoKLSAgICogVE9ETzogV2hhdCBoYXBwZW5zIGlmIGluZGV4IGlzIG91dCBvZiByYW5nZT8KLSAgICoKLSAgICogQHBhcmFtIGluZGV4IEluZGV4IGludG8gdGhlIGNvbGxlY3Rpb24uCi0gICAqIEByZXR1cm4gVGhlIG5vZGUgYXQgdGhlIDxjb2RlPmluZGV4PC9jb2RlPnRoIHBvc2l0aW9uIGluIHRoZQotICAgKiAgIDxjb2RlPk5vZGVMaXN0PC9jb2RlPiwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhhdCBpcyBub3QgYSB2YWxpZAotICAgKiAgIGluZGV4LgotICAgKi8KLSAgcHVibGljIE5vZGUgaXRlbShpbnQgaW5kZXgpCi0gIHsKLQotICAgIHJ1blRvKGluZGV4KTsKLQotICAgIHJldHVybiAoTm9kZSkgdGhpcy5lbGVtZW50QXQoaW5kZXgpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoZSBudW1iZXIgb2Ygbm9kZXMgaW4gdGhlIGxpc3QuIFRoZSByYW5nZSBvZiB2YWxpZCBjaGlsZCBub2RlIGluZGljZXMgaXMKLSAgICogMCB0byA8Y29kZT5sZW5ndGgtMTwvY29kZT4gaW5jbHVzaXZlLiBOb3RlIHRoYXQgdGhpcyBvcGVyYXRpb24gcmVxdWlyZXMKLSAgICogZmluZGluZyBhbGwgdGhlIG1hdGNoaW5nIG5vZGVzLCB3aGljaCBtYXkgZGVmZWF0IGF0dGVtcHRzIHRvIGRlZmVyCi0gICAqIHRoYXQgd29yay4KLSAgICoKLSAgICogQHJldHVybiBpbnRlZ2VyIGluZGljYXRpbmcgaG93IG1hbnkgbm9kZXMgYXJlIHJlcHJlc2VudGVkIGJ5IHRoaXMgbGlzdC4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0TGVuZ3RoKCkKLSAgewotCi0gICAgcnVuVG8oLTEpOwotCi0gICAgcmV0dXJuIHRoaXMuc2l6ZSgpOwotICB9Ci0KLSAgLyoqCi0gICAqIEFkZCBhIG5vZGUgdG8gdGhlIE5vZGVTZXQuIE5vdCBhbGwgdHlwZXMgb2YgTm9kZVNldHMgc3VwcG9ydCB0aGlzCi0gICAqIG9wZXJhdGlvbgotICAgKgotICAgKiBAcGFyYW0gbiBOb2RlIHRvIGJlIGFkZGVkCi0gICAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiB0aHJvd24gaWYgdGhpcyBOb2RlU2V0IGlzIG5vdCBvZgotICAgKiBhIG11dGFibGUgdHlwZS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGFkZE5vZGUoTm9kZSBuKQotICB7Ci0KLSAgICBpZiAoIW1fbXV0YWJsZSkKLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShYUEFUSEVycm9yUmVzb3VyY2VzLkVSX05PREVTRVRfTk9UX01VVEFCTEUsIG51bGwpKTsgLy8iVGhpcyBOb2RlU2V0IGlzIG5vdCBtdXRhYmxlISIpOwotCi0gICAgdGhpcy5hZGRFbGVtZW50KG4pOwotICB9Ci0KLSAgLyoqCi0gICAqIEluc2VydCBhIG5vZGUgYXQgYSBnaXZlbiBwb3NpdGlvbi4KLSAgICoKLSAgICogQHBhcmFtIG4gTm9kZSB0byBiZSBhZGRlZAotICAgKiBAcGFyYW0gcG9zIE9mZnNldCBhdCB3aGljaCB0aGUgbm9kZSBpcyB0byBiZSBpbnNlcnRlZCwKLSAgICogd2l0aCAwIGJlaW5nIHRoZSBmaXJzdCBwb3NpdGlvbi4KLSAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIHRocm93biBpZiB0aGlzIE5vZGVTZXQgaXMgbm90IG9mCi0gICAqIGEgbXV0YWJsZSB0eXBlLgotICAgKi8KLSAgcHVibGljIHZvaWQgaW5zZXJ0Tm9kZShOb2RlIG4sIGludCBwb3MpCi0gIHsKLQotICAgIGlmICghbV9tdXRhYmxlKQotICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfTk9ERVNFVF9OT1RfTVVUQUJMRSwgbnVsbCkpOyAvLyJUaGlzIE5vZGVTZXQgaXMgbm90IG11dGFibGUhIik7Ci0KLSAgICBpbnNlcnRFbGVtZW50QXQobiwgcG9zKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZW1vdmUgYSBub2RlLgotICAgKgotICAgKiBAcGFyYW0gbiBOb2RlIHRvIGJlIGFkZGVkCi0gICAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiB0aHJvd24gaWYgdGhpcyBOb2RlU2V0IGlzIG5vdCBvZgotICAgKiBhIG11dGFibGUgdHlwZS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHJlbW92ZU5vZGUoTm9kZSBuKQotICB7Ci0KLSAgICBpZiAoIW1fbXV0YWJsZSkKLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShYUEFUSEVycm9yUmVzb3VyY2VzLkVSX05PREVTRVRfTk9UX01VVEFCTEUsIG51bGwpKTsgLy8iVGhpcyBOb2RlU2V0IGlzIG5vdCBtdXRhYmxlISIpOwotCi0gICAgdGhpcy5yZW1vdmVFbGVtZW50KG4pOwotICB9Ci0KLSAgLyoqCi0gICAqIENvcHkgTm9kZUxpc3QgbWVtYmVycyBpbnRvIHRoaXMgbm9kZWxpc3QsIGFkZGluZyBpbgotICAgKiBkb2N1bWVudCBvcmRlci4gIElmIGEgbm9kZSBpcyBudWxsLCBkb24ndCBhZGQgaXQuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlbGlzdCBMaXN0IG9mIG5vZGVzIHdoaWNoIHNob3VsZCBub3cgYmUgcmVmZXJlbmNlZCBieQotICAgKiB0aGlzIE5vZGVTZXQuCi0gICAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiB0aHJvd24gaWYgdGhpcyBOb2RlU2V0IGlzIG5vdCBvZgotICAgKiBhIG11dGFibGUgdHlwZS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGFkZE5vZGVzKE5vZGVMaXN0IG5vZGVsaXN0KQotICB7Ci0KLSAgICBpZiAoIW1fbXV0YWJsZSkKLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShYUEFUSEVycm9yUmVzb3VyY2VzLkVSX05PREVTRVRfTk9UX01VVEFCTEUsIG51bGwpKTsgLy8iVGhpcyBOb2RlU2V0IGlzIG5vdCBtdXRhYmxlISIpOwotCi0gICAgaWYgKG51bGwgIT0gbm9kZWxpc3QpICAvLyBkZWZlbnNpdmUgdG8gZml4IGEgYnVnIHRoYXQgU2Fuaml2YSByZXBvcnRlZC4KLSAgICB7Ci0gICAgICBpbnQgbkNoaWxkcmVuID0gbm9kZWxpc3QuZ2V0TGVuZ3RoKCk7Ci0KLSAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbkNoaWxkcmVuOyBpKyspCi0gICAgICB7Ci0gICAgICAgIE5vZGUgb2JqID0gbm9kZWxpc3QuaXRlbShpKTsKLQotICAgICAgICBpZiAobnVsbCAhPSBvYmopCi0gICAgICAgIHsKLSAgICAgICAgICBhZGRFbGVtZW50KG9iaik7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICB9Ci0KLSAgICAvLyBjaGVja0R1cHMoKTsKLSAgfQotCi0gIC8qKgotICAgKiA8cD5Db3B5IE5vZGVMaXN0IG1lbWJlcnMgaW50byB0aGlzIG5vZGVsaXN0LCBhZGRpbmcgaW4KLSAgICogZG9jdW1lbnQgb3JkZXIuICBPbmx5IGdlbnVpbmUgbm9kZSByZWZlcmVuY2VzIHdpbGwgYmUgY29waWVkOwotICAgKiBudWxscyBhcHBlYXJpbmcgaW4gdGhlIHNvdXJjZSBOb2RlU2V0IHdpbGwKLSAgICogbm90IGJlIGFkZGVkIHRvIHRoaXMgb25lLiA8L3A+Ci0gICAqCi0gICAqIDxwPiBJbiBjYXNlIHlvdSdyZSB3b25kZXJpbmcgd2h5IHRoaXMgZnVuY3Rpb24gaXMgbmVlZGVkOiBOb2RlU2V0Ci0gICAqIGltcGxlbWVudHMgYm90aCBOb2RlSXRlcmF0b3IgYW5kIE5vZGVMaXN0LiBJZiB0aGlzIG1ldGhvZCBpc24ndAotICAgKiBwcm92aWRlZCwgSmF2YSBjYW4ndCBkZWNpZGUgd2hpY2ggb2YgdGhvc2UgdG8gdXNlIHdoZW4gYWRkTm9kZXMoKQotICAgKiBpcyBpbnZva2VkLiBQcm92aWRpbmcgdGhlIG1vcmUtZXhwbGljaXQgbWF0Y2ggYXZvaWRzIHRoYXQKLSAgICogYW1iaWd1aXR5Lik8L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBucyBOb2RlU2V0IHdob3NlIG1lbWJlcnMgc2hvdWxkIGJlIG1lcmdlZCBpbnRvIHRoaXMgTm9kZVNldC4KLSAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIHRocm93biBpZiB0aGlzIE5vZGVTZXQgaXMgbm90IG9mCi0gICAqIGEgbXV0YWJsZSB0eXBlLgotICAgKi8KLSAgcHVibGljIHZvaWQgYWRkTm9kZXMoTm9kZVNldCBucykKLSAgewotCi0gICAgaWYgKCFtX211dGFibGUpCi0gICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoWFBBVEhFcnJvclJlc291cmNlcy5FUl9OT0RFU0VUX05PVF9NVVRBQkxFLCBudWxsKSk7IC8vIlRoaXMgTm9kZVNldCBpcyBub3QgbXV0YWJsZSEiKTsKLQotICAgIGFkZE5vZGVzKChOb2RlSXRlcmF0b3IpIG5zKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb3B5IE5vZGVMaXN0IG1lbWJlcnMgaW50byB0aGlzIG5vZGVsaXN0LCBhZGRpbmcgaW4KLSAgICogZG9jdW1lbnQgb3JkZXIuICBOdWxsIHJlZmVyZW5jZXMgYXJlIG5vdCBhZGRlZC4KLSAgICoKLSAgICogQHBhcmFtIGl0ZXJhdG9yIE5vZGVJdGVyYXRvciB3aGljaCB5aWVsZHMgdGhlIG5vZGVzIHRvIGJlIGFkZGVkLgotICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gdGhyb3duIGlmIHRoaXMgTm9kZVNldCBpcyBub3Qgb2YKLSAgICogYSBtdXRhYmxlIHR5cGUuCi0gICAqLwotICBwdWJsaWMgdm9pZCBhZGROb2RlcyhOb2RlSXRlcmF0b3IgaXRlcmF0b3IpCi0gIHsKLQotICAgIGlmICghbV9tdXRhYmxlKQotICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfTk9ERVNFVF9OT1RfTVVUQUJMRSwgbnVsbCkpOyAvLyJUaGlzIE5vZGVTZXQgaXMgbm90IG11dGFibGUhIik7Ci0KLSAgICBpZiAobnVsbCAhPSBpdGVyYXRvcikgIC8vIGRlZmVuc2l2ZSB0byBmaXggYSBidWcgdGhhdCBTYW5qaXZhIHJlcG9ydGVkLgotICAgIHsKLSAgICAgIE5vZGUgb2JqOwotCi0gICAgICB3aGlsZSAobnVsbCAhPSAob2JqID0gaXRlcmF0b3IubmV4dE5vZGUoKSkpCi0gICAgICB7Ci0gICAgICAgIGFkZEVsZW1lbnQob2JqKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICAvLyBjaGVja0R1cHMoKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb3B5IE5vZGVMaXN0IG1lbWJlcnMgaW50byB0aGlzIG5vZGVsaXN0LCBhZGRpbmcgaW4KLSAgICogZG9jdW1lbnQgb3JkZXIuICBJZiBhIG5vZGUgaXMgbnVsbCwgZG9uJ3QgYWRkIGl0LgotICAgKgotICAgKiBAcGFyYW0gbm9kZWxpc3QgTGlzdCBvZiBub2RlcyB0byBiZSBhZGRlZAotICAgKiBAcGFyYW0gc3VwcG9ydCBUaGUgWFBhdGggcnVudGltZSBjb250ZXh0LgotICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gdGhyb3duIGlmIHRoaXMgTm9kZVNldCBpcyBub3Qgb2YKLSAgICogYSBtdXRhYmxlIHR5cGUuCi0gICAqLwotICBwdWJsaWMgdm9pZCBhZGROb2Rlc0luRG9jT3JkZXIoTm9kZUxpc3Qgbm9kZWxpc3QsIFhQYXRoQ29udGV4dCBzdXBwb3J0KQotICB7Ci0KLSAgICBpZiAoIW1fbXV0YWJsZSkKLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShYUEFUSEVycm9yUmVzb3VyY2VzLkVSX05PREVTRVRfTk9UX01VVEFCTEUsIG51bGwpKTsgLy8iVGhpcyBOb2RlU2V0IGlzIG5vdCBtdXRhYmxlISIpOwotCi0gICAgaW50IG5DaGlsZHJlbiA9IG5vZGVsaXN0LmdldExlbmd0aCgpOwotCi0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuQ2hpbGRyZW47IGkrKykKLSAgICB7Ci0gICAgICBOb2RlIG5vZGUgPSBub2RlbGlzdC5pdGVtKGkpOwotCi0gICAgICBpZiAobnVsbCAhPSBub2RlKQotICAgICAgewotICAgICAgICBhZGROb2RlSW5Eb2NPcmRlcihub2RlLCBzdXBwb3J0KTsKLSAgICAgIH0KLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogQ29weSBOb2RlTGlzdCBtZW1iZXJzIGludG8gdGhpcyBub2RlbGlzdCwgYWRkaW5nIGluCi0gICAqIGRvY3VtZW50IG9yZGVyLiAgSWYgYSBub2RlIGlzIG51bGwsIGRvbid0IGFkZCBpdC4KLSAgICoKLSAgICogQHBhcmFtIGl0ZXJhdG9yIE5vZGVJdGVyYXRvciB3aGljaCB5aWVsZHMgdGhlIG5vZGVzIHRvIGJlIGFkZGVkLgotICAgKiBAcGFyYW0gc3VwcG9ydCBUaGUgWFBhdGggcnVudGltZSBjb250ZXh0LgotICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gdGhyb3duIGlmIHRoaXMgTm9kZVNldCBpcyBub3Qgb2YKLSAgICogYSBtdXRhYmxlIHR5cGUuCi0gICAqLwotICBwdWJsaWMgdm9pZCBhZGROb2Rlc0luRG9jT3JkZXIoTm9kZUl0ZXJhdG9yIGl0ZXJhdG9yLCBYUGF0aENvbnRleHQgc3VwcG9ydCkKLSAgewotCi0gICAgaWYgKCFtX211dGFibGUpCi0gICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoWFBBVEhFcnJvclJlc291cmNlcy5FUl9OT0RFU0VUX05PVF9NVVRBQkxFLCBudWxsKSk7IC8vIlRoaXMgTm9kZVNldCBpcyBub3QgbXV0YWJsZSEiKTsKLQotICAgIE5vZGUgbm9kZTsKLQotICAgIHdoaWxlIChudWxsICE9IChub2RlID0gaXRlcmF0b3IubmV4dE5vZGUoKSkpCi0gICAgewotICAgICAgYWRkTm9kZUluRG9jT3JkZXIobm9kZSwgc3VwcG9ydCk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEFkZCB0aGUgbm9kZSBsaXN0IHRvIHRoaXMgbm9kZSBzZXQgaW4gZG9jdW1lbnQgb3JkZXIuCi0gICAqCi0gICAqIEBwYXJhbSBzdGFydCBpbmRleC4KLSAgICogQHBhcmFtIGVuZCBpbmRleC4KLSAgICogQHBhcmFtIHRlc3RJbmRleCBpbmRleC4KLSAgICogQHBhcmFtIG5vZGVsaXN0IFRoZSBub2RlbGlzdCB0byBhZGQuCi0gICAqIEBwYXJhbSBzdXBwb3J0IFRoZSBYUGF0aCBydW50aW1lIGNvbnRleHQuCi0gICAqCi0gICAqIEByZXR1cm4gZmFsc2UgYWx3YXlzLgotICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gdGhyb3duIGlmIHRoaXMgTm9kZVNldCBpcyBub3Qgb2YKLSAgICogYSBtdXRhYmxlIHR5cGUuCi0gICAqLwotICBwcml2YXRlIGJvb2xlYW4gYWRkTm9kZXNJbkRvY09yZGVyKGludCBzdGFydCwgaW50IGVuZCwgaW50IHRlc3RJbmRleCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOb2RlTGlzdCBub2RlbGlzdCwgWFBhdGhDb250ZXh0IHN1cHBvcnQpCi0gIHsKLQotICAgIGlmICghbV9tdXRhYmxlKQotICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfTk9ERVNFVF9OT1RfTVVUQUJMRSwgbnVsbCkpOyAvLyJUaGlzIE5vZGVTZXQgaXMgbm90IG11dGFibGUhIik7Ci0KLSAgICBib29sZWFuIGZvdW5kaXQgPSBmYWxzZTsKLSAgICBpbnQgaTsKLSAgICBOb2RlIG5vZGUgPSBub2RlbGlzdC5pdGVtKHRlc3RJbmRleCk7Ci0KLSAgICBmb3IgKGkgPSBlbmQ7IGkgPj0gc3RhcnQ7IGktLSkKLSAgICB7Ci0gICAgICBOb2RlIGNoaWxkID0gKE5vZGUpIGVsZW1lbnRBdChpKTsKLQotICAgICAgaWYgKGNoaWxkID09IG5vZGUpCi0gICAgICB7Ci0gICAgICAgIGkgPSAtMjsgIC8vIER1cGxpY2F0ZSwgc3VwcHJlc3MgaW5zZXJ0Ci0KLSAgICAgICAgYnJlYWs7Ci0gICAgICB9Ci0KLSAgICAgIGlmICghRE9NMkhlbHBlci5pc05vZGVBZnRlcihub2RlLCBjaGlsZCkpCi0gICAgICB7Ci0gICAgICAgIGluc2VydEVsZW1lbnRBdChub2RlLCBpICsgMSk7Ci0KLSAgICAgICAgdGVzdEluZGV4LS07Ci0KLSAgICAgICAgaWYgKHRlc3RJbmRleCA+IDApCi0gICAgICAgIHsKLSAgICAgICAgICBib29sZWFuIGZvdW5kUHJldiA9IGFkZE5vZGVzSW5Eb2NPcmRlcigwLCBpLCB0ZXN0SW5kZXgsIG5vZGVsaXN0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1cHBvcnQpOwotCi0gICAgICAgICAgaWYgKCFmb3VuZFByZXYpCi0gICAgICAgICAgewotICAgICAgICAgICAgYWRkTm9kZXNJbkRvY09yZGVyKGksIHNpemUoKSAtIDEsIHRlc3RJbmRleCwgbm9kZWxpc3QsIHN1cHBvcnQpOwotICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGJyZWFrOwotICAgICAgfQotICAgIH0KLQotICAgIGlmIChpID09IC0xKQotICAgIHsKLSAgICAgIGluc2VydEVsZW1lbnRBdChub2RlLCAwKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gZm91bmRpdDsKLSAgfQotCi0gIC8qKgotICAgKiBBZGQgdGhlIG5vZGUgaW50byBhIHZlY3RvciBvZiBub2RlcyB3aGVyZSBpdCBzaG91bGQgb2NjdXIgaW4KLSAgICogZG9jdW1lbnQgb3JkZXIuCi0gICAqIEBwYXJhbSBub2RlIFRoZSBub2RlIHRvIGJlIGFkZGVkLgotICAgKiBAcGFyYW0gdGVzdCB0cnVlIGlmIHdlIHNob3VsZCB0ZXN0IGZvciBkb2Mgb3JkZXIKLSAgICogQHBhcmFtIHN1cHBvcnQgVGhlIFhQYXRoIHJ1bnRpbWUgY29udGV4dC4KLSAgICogQHJldHVybiBpbnNlcnRJbmRleC4KLSAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIHRocm93biBpZiB0aGlzIE5vZGVTZXQgaXMgbm90IG9mCi0gICAqIGEgbXV0YWJsZSB0eXBlLgotICAgKi8KLSAgcHVibGljIGludCBhZGROb2RlSW5Eb2NPcmRlcihOb2RlIG5vZGUsIGJvb2xlYW4gdGVzdCwgWFBhdGhDb250ZXh0IHN1cHBvcnQpCi0gIHsKLQotICAgIGlmICghbV9tdXRhYmxlKQotICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfTk9ERVNFVF9OT1RfTVVUQUJMRSwgbnVsbCkpOyAvL1hTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShYUEFUSEVycm9yUmVzb3VyY2VzLkVSX05PREVTRVRfTk9UX01VVEFCTEUsIG51bGwpKTsgLy8iVGhpcyBOb2RlU2V0IGlzIG5vdCBtdXRhYmxlISIpOwotCi0gICAgaW50IGluc2VydEluZGV4ID0gLTE7Ci0KLSAgICBpZiAodGVzdCkKLSAgICB7Ci0KLSAgICAgIC8vIFRoaXMgbmVlZHMgdG8gZG8gYSBiaW5hcnkgc2VhcmNoLCBidXQgYSBiaW5hcnkgc2VhcmNoCi0gICAgICAvLyBpcyBzb21ld2hhdCB0b3VnaCBiZWNhdXNlIHRoZSBzZXF1ZW5jZSB0ZXN0IGludm9sdmVzCi0gICAgICAvLyB0d28gbm9kZXMuCi0gICAgICBpbnQgc2l6ZSA9IHNpemUoKSwgaTsKLQotICAgICAgZm9yIChpID0gc2l6ZSAtIDE7IGkgPj0gMDsgaS0tKQotICAgICAgewotICAgICAgICBOb2RlIGNoaWxkID0gKE5vZGUpIGVsZW1lbnRBdChpKTsKLQotICAgICAgICBpZiAoY2hpbGQgPT0gbm9kZSkKLSAgICAgICAgewotICAgICAgICAgIGkgPSAtMjsgIC8vIER1cGxpY2F0ZSwgc3VwcHJlc3MgaW5zZXJ0Ci0KLSAgICAgICAgICBicmVhazsKLSAgICAgICAgfQotCi0gICAgICAgIGlmICghRE9NMkhlbHBlci5pc05vZGVBZnRlcihub2RlLCBjaGlsZCkpCi0gICAgICAgIHsKLSAgICAgICAgICBicmVhazsKLSAgICAgICAgfQotICAgICAgfQotCi0gICAgICBpZiAoaSAhPSAtMikKLSAgICAgIHsKLSAgICAgICAgaW5zZXJ0SW5kZXggPSBpICsgMTsKLQotICAgICAgICBpbnNlcnRFbGVtZW50QXQobm9kZSwgaW5zZXJ0SW5kZXgpOwotICAgICAgfQotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgaW5zZXJ0SW5kZXggPSB0aGlzLnNpemUoKTsKLQotICAgICAgYm9vbGVhbiBmb3VuZGl0ID0gZmFsc2U7Ci0KLSAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaW5zZXJ0SW5kZXg7IGkrKykKLSAgICAgIHsKLSAgICAgICAgaWYgKHRoaXMuaXRlbShpKS5lcXVhbHMobm9kZSkpCi0gICAgICAgIHsKLSAgICAgICAgICBmb3VuZGl0ID0gdHJ1ZTsKLQotICAgICAgICAgIGJyZWFrOwotICAgICAgICB9Ci0gICAgICB9Ci0KLSAgICAgIGlmICghZm91bmRpdCkKLSAgICAgICAgYWRkRWxlbWVudChub2RlKTsKLSAgICB9Ci0KLSAgICAvLyBjaGVja0R1cHMoKTsKLSAgICByZXR1cm4gaW5zZXJ0SW5kZXg7Ci0gIH0gIC8vIGVuZCBhZGROb2RlSW5Eb2NPcmRlcihWZWN0b3IgdiwgT2JqZWN0IG9iaikKLQotICAvKioKLSAgICogQWRkIHRoZSBub2RlIGludG8gYSB2ZWN0b3Igb2Ygbm9kZXMgd2hlcmUgaXQgc2hvdWxkIG9jY3VyIGluCi0gICAqIGRvY3VtZW50IG9yZGVyLgotICAgKiBAcGFyYW0gbm9kZSBUaGUgbm9kZSB0byBiZSBhZGRlZC4KLSAgICogQHBhcmFtIHN1cHBvcnQgVGhlIFhQYXRoIHJ1bnRpbWUgY29udGV4dC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgaW5kZXggd2hlcmUgaXQgd2FzIGluc2VydGVkLgotICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gdGhyb3duIGlmIHRoaXMgTm9kZVNldCBpcyBub3Qgb2YKLSAgICogYSBtdXRhYmxlIHR5cGUuCi0gICAqLwotICBwdWJsaWMgaW50IGFkZE5vZGVJbkRvY09yZGVyKE5vZGUgbm9kZSwgWFBhdGhDb250ZXh0IHN1cHBvcnQpCi0gIHsKLQotICAgIGlmICghbV9tdXRhYmxlKQotICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfTk9ERVNFVF9OT1RfTVVUQUJMRSwgbnVsbCkpOyAvLyJUaGlzIE5vZGVTZXQgaXMgbm90IG11dGFibGUhIik7Ci0KLSAgICByZXR1cm4gYWRkTm9kZUluRG9jT3JkZXIobm9kZSwgdHJ1ZSwgc3VwcG9ydCk7Ci0gIH0gIC8vIGVuZCBhZGROb2RlSW5Eb2NPcmRlcihWZWN0b3IgdiwgT2JqZWN0IG9iaikKLQotCi0gIC8qKiBJZiB0aGlzIG5vZGUgaXMgYmVpbmcgdXNlZCBhcyBhbiBpdGVyYXRvciwgdGhlIG5leHQgaW5kZXggdGhhdCBuZXh0Tm9kZSgpCi0gICAqICB3aWxsIHJldHVybi4gICovCi0gIHRyYW5zaWVudCBwcm90ZWN0ZWQgaW50IG1fbmV4dCA9IDA7Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgY3VycmVudCBwb3NpdGlvbiwgd2hpY2ggaXMgb25lIGxlc3MgdGhhbgotICAgKiB0aGUgbmV4dCBuZXh0Tm9kZSgpIGNhbGwgd2lsbCByZXRyaWV2ZS4gIGkuZS4gaWYKLSAgICogeW91IGNhbGwgZ2V0Q3VycmVudFBvcygpIGFuZCB0aGUgcmV0dXJuIGlzIDAsIHRoZSBuZXh0Ci0gICAqIGZldGNoIHdpbGwgdGFrZSBwbGFjZSBhdCBpbmRleCAxLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSB0aGUgY3VycmVudCBwb3NpdGlvbiBpbmRleC4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0Q3VycmVudFBvcygpCi0gIHsKLSAgICByZXR1cm4gbV9uZXh0OwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgY3VycmVudCBwb3NpdGlvbiBpbiB0aGUgbm9kZSBzZXQuCi0gICAqIEBwYXJhbSBpIE11c3QgYmUgYSB2YWxpZCBpbmRleC4KLSAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIHRocm93biBpZiB0aGlzIE5vZGVTZXQgaXMgbm90IG9mCi0gICAqIGEgY2FjaGVkIHR5cGUsIGFuZCB0aHVzIGRvZXNuJ3QgcGVybWl0IGluZGV4ZWQgYWNjZXNzLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0Q3VycmVudFBvcyhpbnQgaSkKLSAgewotCi0gICAgaWYgKCFtX2NhY2hlTm9kZXMpCi0gICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKLSAgICAgICAgWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfTk9ERVNFVF9DQU5OT1RfSU5ERVgsIG51bGwpKTsgLy8iVGhpcyBOb2RlU2V0IGNhbiBub3QgZG8gaW5kZXhpbmcgb3IgY291bnRpbmcgZnVuY3Rpb25zISIpOwotCi0gICAgbV9uZXh0ID0gaTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIGxhc3QgZmV0Y2hlZCBub2RlLiAgTmVlZGVkIHRvIHN1cHBvcnQgdGhlIFVuaW9uUGF0aEl0ZXJhdG9yLgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBsYXN0IGZldGNoZWQgbm9kZS4KLSAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIHRocm93biBpZiB0aGlzIE5vZGVTZXQgaXMgbm90IG9mCi0gICAqIGEgY2FjaGVkIHR5cGUsIGFuZCB0aHVzIGRvZXNuJ3QgcGVybWl0IGluZGV4ZWQgYWNjZXNzLgotICAgKi8KLSAgcHVibGljIE5vZGUgZ2V0Q3VycmVudE5vZGUoKQotICB7Ci0KLSAgICBpZiAoIW1fY2FjaGVOb2RlcykKLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAotICAgICAgICBYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoWFBBVEhFcnJvclJlc291cmNlcy5FUl9OT0RFU0VUX0NBTk5PVF9JTkRFWCwgbnVsbCkpOyAvLyJUaGlzIE5vZGVTZXQgY2FuIG5vdCBkbyBpbmRleGluZyBvciBjb3VudGluZyBmdW5jdGlvbnMhIik7Ci0KLSAgICBpbnQgc2F2ZWQgPSBtX25leHQ7Ci0gICAgTm9kZSBuID0gKG1fbmV4dCA8IG1fZmlyc3RGcmVlKSA/IGVsZW1lbnRBdChtX25leHQpIDogbnVsbDsKLSAgICBtX25leHQgPSBzYXZlZDsgLy8gSEFDSzogSSB0aGluayB0aGlzIGlzIGEgYml0IG9mIGEgaGFjay4gIC1zYgotICAgIHJldHVybiBuOwotICB9Ci0KLSAgLyoqIFRydWUgaWYgdGhpcyBsaXN0IGNhbiBiZSBtdXRhdGVkLiAgKi8KLSAgdHJhbnNpZW50IHByb3RlY3RlZCBib29sZWFuIG1fbXV0YWJsZSA9IHRydWU7Ci0KLSAgLyoqIFRydWUgaWYgdGhpcyBsaXN0IGlzIGNhY2hlZC4KLSAgICogIEBzZXJpYWwgICovCi0gIHRyYW5zaWVudCBwcm90ZWN0ZWQgYm9vbGVhbiBtX2NhY2hlTm9kZXMgPSB0cnVlOwotCi0gIC8qKgotICAgKiBHZXQgd2hldGhlciBvciBub3QgdGhpcyBpcyBhIGNhY2hlZCBub2RlIHNldC4KLSAgICoKLSAgICoKLSAgICogQHJldHVybiBUcnVlIGlmIHRoaXMgbGlzdCBpcyBjYWNoZWQuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBnZXRTaG91bGRDYWNoZU5vZGVzKCkKLSAgewotICAgIHJldHVybiBtX2NhY2hlTm9kZXM7Ci0gIH0KLQotICAvKioKLSAgICogSWYgc2V0U2hvdWxkQ2FjaGVOb2Rlcyh0cnVlKSBpcyBjYWxsZWQsIHRoZW4gbm9kZXMgd2lsbAotICAgKiBiZSBjYWNoZWQuICBUaGV5IGFyZSBub3QgY2FjaGVkIGJ5IGRlZmF1bHQuIFRoaXMgc3dpdGNoIG11c3QKLSAgICogYmUgc2V0IGJlZm9yZSB0aGUgZmlyc3QgY2FsbCB0byBuZXh0Tm9kZSBpcyBtYWRlLCB0byBlbnN1cmUKLSAgICogdGhhdCBhbGwgbm9kZXMgYXJlIGNhY2hlZC4KLSAgICoKLSAgICogQHBhcmFtIGIgdHJ1ZSBpZiB0aGlzIG5vZGUgc2V0IHNob3VsZCBiZSBjYWNoZWQuCi0gICAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiB0aHJvd24gaWYgYW4gYXR0ZW1wdCBpcyBtYWRlIHRvCi0gICAqIHJlcXVlc3QgY2FjaGluZyBhZnRlciB3ZSd2ZSBhbHJlYWR5IGJlZ3VuIHN0ZXBwaW5nIHRocm91Z2ggdGhlCi0gICAqIG5vZGVzIGluIHRoaXMgc2V0LgotICAqLwotICBwdWJsaWMgdm9pZCBzZXRTaG91bGRDYWNoZU5vZGVzKGJvb2xlYW4gYikKLSAgewotCi0gICAgaWYgKCFpc0ZyZXNoKCkpCi0gICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKLSAgICAgICAgWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfQ0FOTk9UX0NBTExfU0VUU0hPVUxEQ0FDSEVOT0RFLCBudWxsKSk7IC8vIkNhbiBub3QgY2FsbCBzZXRTaG91bGRDYWNoZU5vZGVzIGFmdGVyIG5leHROb2RlIGhhcyBiZWVuIGNhbGxlZCEiKTsKLQotICAgIG1fY2FjaGVOb2RlcyA9IGI7Ci0gICAgbV9tdXRhYmxlID0gdHJ1ZTsKLSAgfQotCi0KLSAgdHJhbnNpZW50IHByaXZhdGUgaW50IG1fbGFzdCA9IDA7Ci0KLSAgcHVibGljIGludCBnZXRMYXN0KCkKLSAgewotICAgIHJldHVybiBtX2xhc3Q7Ci0gIH0KLQotICBwdWJsaWMgdm9pZCBzZXRMYXN0KGludCBsYXN0KQotICB7Ci0gICAgbV9sYXN0ID0gbGFzdDsKLSAgfQotCi0gIC8qKiBTaXplIG9mIGJsb2NrcyB0byBhbGxvY2F0ZS4KLSAgICogIEBzZXJpYWwgICAgICAgICAgKi8KLSAgcHJpdmF0ZSBpbnQgbV9ibG9ja3NpemU7Ci0KLSAgLyoqIEFycmF5IG9mIG5vZGVzIHRoaXMgcG9pbnRzIHRvLgotICAgKiAgQHNlcmlhbCAgICAgICAgICAqLwotICBOb2RlIG1fbWFwW107Ci0KLSAgLyoqIE51bWJlciBvZiBub2RlcyBpbiB0aGlzIE5vZGVWZWN0b3IuCi0gICAqICBAc2VyaWFsICAgICAgICAgICovCi0gIHByb3RlY3RlZCBpbnQgbV9maXJzdEZyZWUgPSAwOwotCi0gIC8qKiBTaXplIG9mIHRoZSBhcnJheSB0aGlzIHBvaW50cyB0by4KLSAgICogIEBzZXJpYWwgICAgICAgICAgICovCi0gIHByaXZhdGUgaW50IG1fbWFwU2l6ZTsgIC8vIGxhenkgaW5pdGlhbGl6YXRpb24KLQotICAvKioKLSAgICogR2V0IGEgY2xvbmVkIExvY1BhdGhJdGVyYXRvci4KLSAgICoKLSAgICogQHJldHVybiBBIGNsb25lIG9mIHRoaXMKLSAgICoKLSAgICogQHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIE9iamVjdCBjbG9uZSgpIHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbgotICB7Ci0KLSAgICBOb2RlU2V0IGNsb25lID0gKE5vZGVTZXQpIHN1cGVyLmNsb25lKCk7Ci0KLSAgICBpZiAoKG51bGwgIT0gdGhpcy5tX21hcCkgJiYgKHRoaXMubV9tYXAgPT0gY2xvbmUubV9tYXApKQotICAgIHsKLSAgICAgIGNsb25lLm1fbWFwID0gbmV3IE5vZGVbdGhpcy5tX21hcC5sZW5ndGhdOwotCi0gICAgICBTeXN0ZW0uYXJyYXljb3B5KHRoaXMubV9tYXAsIDAsIGNsb25lLm1fbWFwLCAwLCB0aGlzLm1fbWFwLmxlbmd0aCk7Ci0gICAgfQotCi0gICAgcmV0dXJuIGNsb25lOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbGVuZ3RoIG9mIHRoZSBsaXN0LgotICAgKgotICAgKiBAcmV0dXJuIE51bWJlciBvZiBub2RlcyBpbiB0aGlzIE5vZGVWZWN0b3IKLSAgICovCi0gIHB1YmxpYyBpbnQgc2l6ZSgpCi0gIHsKLSAgICByZXR1cm4gbV9maXJzdEZyZWU7Ci0gIH0KLQotICAvKioKLSAgICogQXBwZW5kIGEgTm9kZSBvbnRvIHRoZSB2ZWN0b3IuCi0gICAqCi0gICAqIEBwYXJhbSB2YWx1ZSBOb2RlIHRvIGFkZCB0byB0aGUgdmVjdG9yCi0gICAqLwotICBwdWJsaWMgdm9pZCBhZGRFbGVtZW50KE5vZGUgdmFsdWUpCi0gIHsKLSAgICBpZiAoIW1fbXV0YWJsZSkKLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShYUEFUSEVycm9yUmVzb3VyY2VzLkVSX05PREVTRVRfTk9UX01VVEFCTEUsIG51bGwpKTsgLy8iVGhpcyBOb2RlU2V0IGlzIG5vdCBtdXRhYmxlISIpOwotCi0gICAgaWYgKChtX2ZpcnN0RnJlZSArIDEpID49IG1fbWFwU2l6ZSkKLSAgICB7Ci0gICAgICBpZiAobnVsbCA9PSBtX21hcCkKLSAgICAgIHsKLSAgICAgICAgbV9tYXAgPSBuZXcgTm9kZVttX2Jsb2Nrc2l6ZV07Ci0gICAgICAgIG1fbWFwU2l6ZSA9IG1fYmxvY2tzaXplOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBtX21hcFNpemUgKz0gbV9ibG9ja3NpemU7Ci0KLSAgICAgICAgTm9kZSBuZXdNYXBbXSA9IG5ldyBOb2RlW21fbWFwU2l6ZV07Ci0KLSAgICAgICAgU3lzdGVtLmFycmF5Y29weShtX21hcCwgMCwgbmV3TWFwLCAwLCBtX2ZpcnN0RnJlZSArIDEpOwotCi0gICAgICAgIG1fbWFwID0gbmV3TWFwOwotICAgICAgfQotICAgIH0KLQotICAgIG1fbWFwW21fZmlyc3RGcmVlXSA9IHZhbHVlOwotCi0gICAgbV9maXJzdEZyZWUrKzsKLSAgfQotCi0gIC8qKgotICAgKiBBcHBlbmQgYSBOb2RlIG9udG8gdGhlIHZlY3Rvci4KLSAgICoKLSAgICogQHBhcmFtIHZhbHVlIE5vZGUgdG8gYWRkIHRvIHRoZSB2ZWN0b3IKLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHB1c2goTm9kZSB2YWx1ZSkKLSAgewotCi0gICAgaW50IGZmID0gbV9maXJzdEZyZWU7Ci0KLSAgICBpZiAoKGZmICsgMSkgPj0gbV9tYXBTaXplKQotICAgIHsKLSAgICAgIGlmIChudWxsID09IG1fbWFwKQotICAgICAgewotICAgICAgICBtX21hcCA9IG5ldyBOb2RlW21fYmxvY2tzaXplXTsKLSAgICAgICAgbV9tYXBTaXplID0gbV9ibG9ja3NpemU7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIG1fbWFwU2l6ZSArPSBtX2Jsb2Nrc2l6ZTsKLQotICAgICAgICBOb2RlIG5ld01hcFtdID0gbmV3IE5vZGVbbV9tYXBTaXplXTsKLQotICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KG1fbWFwLCAwLCBuZXdNYXAsIDAsIGZmICsgMSk7Ci0KLSAgICAgICAgbV9tYXAgPSBuZXdNYXA7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgbV9tYXBbZmZdID0gdmFsdWU7Ci0KLSAgICBmZisrOwotCi0gICAgbV9maXJzdEZyZWUgPSBmZjsKLSAgfQotCi0gIC8qKgotICAgKiBQb3AgYSBub2RlIGZyb20gdGhlIHRhaWwgb2YgdGhlIHZlY3RvciBhbmQgcmV0dXJuIHRoZSByZXN1bHQuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIG5vZGUgYXQgdGhlIHRhaWwgb2YgdGhlIHZlY3RvcgotICAgKi8KLSAgcHVibGljIGZpbmFsIE5vZGUgcG9wKCkKLSAgewotCi0gICAgbV9maXJzdEZyZWUtLTsKLQotICAgIE5vZGUgbiA9IG1fbWFwW21fZmlyc3RGcmVlXTsKLQotICAgIG1fbWFwW21fZmlyc3RGcmVlXSA9IG51bGw7Ci0KLSAgICByZXR1cm4gbjsKLSAgfQotCi0gIC8qKgotICAgKiBQb3AgYSBub2RlIGZyb20gdGhlIHRhaWwgb2YgdGhlIHZlY3RvciBhbmQgcmV0dXJuIHRoZQotICAgKiB0b3Agb2YgdGhlIHN0YWNrIGFmdGVyIHRoZSBwb3AuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHRvcCBvZiB0aGUgc3RhY2sgYWZ0ZXIgaXQncyBiZWVuIHBvcHBlZAotICAgKi8KLSAgcHVibGljIGZpbmFsIE5vZGUgcG9wQW5kVG9wKCkKLSAgewotCi0gICAgbV9maXJzdEZyZWUtLTsKLQotICAgIG1fbWFwW21fZmlyc3RGcmVlXSA9IG51bGw7Ci0KLSAgICByZXR1cm4gKG1fZmlyc3RGcmVlID09IDApID8gbnVsbCA6IG1fbWFwW21fZmlyc3RGcmVlIC0gMV07Ci0gIH0KLQotICAvKioKLSAgICogUG9wIGEgbm9kZSBmcm9tIHRoZSB0YWlsIG9mIHRoZSB2ZWN0b3IuCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBwb3BRdWljaygpCi0gIHsKLQotICAgIG1fZmlyc3RGcmVlLS07Ci0KLSAgICBtX21hcFttX2ZpcnN0RnJlZV0gPSBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgbm9kZSBhdCB0aGUgdG9wIG9mIHRoZSBzdGFjayB3aXRob3V0IHBvcHBpbmcgdGhlIHN0YWNrLgotICAgKiBTcGVjaWFsIHB1cnBvc2UgbWV0aG9kIGZvciBUcmFuc2Zvcm1lckltcGwsIHB1c2hFbGVtVGVtcGxhdGVFbGVtZW50LgotICAgKiBQZXJmb3JtYW5jZSBjcml0aWNhbC4KLSAgICoKLSAgICogQHJldHVybiBOb2RlIGF0IHRoZSB0b3Agb2YgdGhlIHN0YWNrIG9yIG51bGwgaWYgc3RhY2sgaXMgZW1wdHkuCi0gICAqLwotICBwdWJsaWMgZmluYWwgTm9kZSBwZWVwT3JOdWxsKCkKLSAgewotICAgIHJldHVybiAoKG51bGwgIT0gbV9tYXApICYmIChtX2ZpcnN0RnJlZSA+IDApKQotICAgICAgICAgICA/IG1fbWFwW21fZmlyc3RGcmVlIC0gMV0gOiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFB1c2ggYSBwYWlyIG9mIG5vZGVzIGludG8gdGhlIHN0YWNrLgotICAgKiBTcGVjaWFsIHB1cnBvc2UgbWV0aG9kIGZvciBUcmFuc2Zvcm1lckltcGwsIHB1c2hFbGVtVGVtcGxhdGVFbGVtZW50LgotICAgKiBQZXJmb3JtYW5jZSBjcml0aWNhbC4KLSAgICoKLSAgICogQHBhcmFtIHYxIEZpcnN0IG5vZGUgdG8gYWRkIHRvIHZlY3RvcgotICAgKiBAcGFyYW0gdjIgU2Vjb25kIG5vZGUgdG8gYWRkIHRvIHZlY3RvcgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgcHVzaFBhaXIoTm9kZSB2MSwgTm9kZSB2MikKLSAgewotCi0gICAgaWYgKG51bGwgPT0gbV9tYXApCi0gICAgewotICAgICAgbV9tYXAgPSBuZXcgTm9kZVttX2Jsb2Nrc2l6ZV07Ci0gICAgICBtX21hcFNpemUgPSBtX2Jsb2Nrc2l6ZTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIGlmICgobV9maXJzdEZyZWUgKyAyKSA+PSBtX21hcFNpemUpCi0gICAgICB7Ci0gICAgICAgIG1fbWFwU2l6ZSArPSBtX2Jsb2Nrc2l6ZTsKLQotICAgICAgICBOb2RlIG5ld01hcFtdID0gbmV3IE5vZGVbbV9tYXBTaXplXTsKLQotICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KG1fbWFwLCAwLCBuZXdNYXAsIDAsIG1fZmlyc3RGcmVlKTsKLQotICAgICAgICBtX21hcCA9IG5ld01hcDsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICBtX21hcFttX2ZpcnN0RnJlZV0gPSB2MTsKLSAgICBtX21hcFttX2ZpcnN0RnJlZSArIDFdID0gdjI7Ci0gICAgbV9maXJzdEZyZWUgKz0gMjsKLSAgfQotCi0gIC8qKgotICAgKiBQb3AgYSBwYWlyIG9mIG5vZGVzIGZyb20gdGhlIHRhaWwgb2YgdGhlIHN0YWNrLgotICAgKiBTcGVjaWFsIHB1cnBvc2UgbWV0aG9kIGZvciBUcmFuc2Zvcm1lckltcGwsIHB1c2hFbGVtVGVtcGxhdGVFbGVtZW50LgotICAgKiBQZXJmb3JtYW5jZSBjcml0aWNhbC4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHBvcFBhaXIoKQotICB7Ci0KLSAgICBtX2ZpcnN0RnJlZSAtPSAyOwotICAgIG1fbWFwW21fZmlyc3RGcmVlXSA9IG51bGw7Ci0gICAgbV9tYXBbbV9maXJzdEZyZWUgKyAxXSA9IG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSB0YWlsIG9mIHRoZSBzdGFjayB0byB0aGUgZ2l2ZW4gbm9kZS4KLSAgICogU3BlY2lhbCBwdXJwb3NlIG1ldGhvZCBmb3IgVHJhbnNmb3JtZXJJbXBsLCBwdXNoRWxlbVRlbXBsYXRlRWxlbWVudC4KLSAgICogUGVyZm9ybWFuY2UgY3JpdGljYWwuCi0gICAqCi0gICAqIEBwYXJhbSBuIE5vZGUgdG8gc2V0IGF0IHRoZSB0YWlsIG9mIHZlY3RvcgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgc2V0VGFpbChOb2RlIG4pCi0gIHsKLSAgICBtX21hcFttX2ZpcnN0RnJlZSAtIDFdID0gbjsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIGdpdmVuIG5vZGUgb25lIHBvc2l0aW9uIGZyb20gdGhlIHRhaWwuCi0gICAqIFNwZWNpYWwgcHVycG9zZSBtZXRob2QgZm9yIFRyYW5zZm9ybWVySW1wbCwgcHVzaEVsZW1UZW1wbGF0ZUVsZW1lbnQuCi0gICAqIFBlcmZvcm1hbmNlIGNyaXRpY2FsLgotICAgKgotICAgKiBAcGFyYW0gbiBOb2RlIHRvIHNldAotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgc2V0VGFpbFN1YjEoTm9kZSBuKQotICB7Ci0gICAgbV9tYXBbbV9maXJzdEZyZWUgLSAyXSA9IG47Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBub2RlIGF0IHRoZSB0YWlsIG9mIHRoZSB2ZWN0b3Igd2l0aG91dCBwb3BwaW5nCi0gICAqIFNwZWNpYWwgcHVycG9zZSBtZXRob2QgZm9yIFRyYW5zZm9ybWVySW1wbCwgcHVzaEVsZW1UZW1wbGF0ZUVsZW1lbnQuCi0gICAqIFBlcmZvcm1hbmNlIGNyaXRpY2FsLgotICAgKgotICAgKiBAcmV0dXJuIE5vZGUgYXQgdGhlIHRhaWwgb2YgdGhlIHZlY3RvcgotICAgKi8KLSAgcHVibGljIGZpbmFsIE5vZGUgcGVlcFRhaWwoKQotICB7Ci0gICAgcmV0dXJuIG1fbWFwW21fZmlyc3RGcmVlIC0gMV07Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBub2RlIG9uZSBwb3NpdGlvbiBmcm9tIHRoZSB0YWlsIHdpdGhvdXQgcG9wcGluZy4KLSAgICogU3BlY2lhbCBwdXJwb3NlIG1ldGhvZCBmb3IgVHJhbnNmb3JtZXJJbXBsLCBwdXNoRWxlbVRlbXBsYXRlRWxlbWVudC4KLSAgICogUGVyZm9ybWFuY2UgY3JpdGljYWwuCi0gICAqCi0gICAqIEByZXR1cm4gTm9kZSBvbmUgYXdheSBmcm9tIHRoZSB0YWlsCi0gICAqLwotICBwdWJsaWMgZmluYWwgTm9kZSBwZWVwVGFpbFN1YjEoKQotICB7Ci0gICAgcmV0dXJuIG1fbWFwW21fZmlyc3RGcmVlIC0gMl07Ci0gIH0KLQotICAvKioKLSAgICogSW5zZXJ0cyB0aGUgc3BlY2lmaWVkIG5vZGUgaW4gdGhpcyB2ZWN0b3IgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4KLSAgICogRWFjaCBjb21wb25lbnQgaW4gdGhpcyB2ZWN0b3Igd2l0aCBhbiBpbmRleCBncmVhdGVyIG9yIGVxdWFsIHRvCi0gICAqIHRoZSBzcGVjaWZpZWQgaW5kZXggaXMgc2hpZnRlZCB1cHdhcmQgdG8gaGF2ZSBhbiBpbmRleCBvbmUgZ3JlYXRlcgotICAgKiB0aGFuIHRoZSB2YWx1ZSBpdCBoYWQgcHJldmlvdXNseS4KLSAgICoKLSAgICogQHBhcmFtIHZhbHVlIE5vZGUgdG8gaW5zZXJ0Ci0gICAqIEBwYXJhbSBhdCBQb3NpdGlvbiB3aGVyZSB0byBpbnNlcnQKLSAgICovCi0gIHB1YmxpYyB2b2lkIGluc2VydEVsZW1lbnRBdChOb2RlIHZhbHVlLCBpbnQgYXQpCi0gIHsKLSAgICBpZiAoIW1fbXV0YWJsZSkKLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShYUEFUSEVycm9yUmVzb3VyY2VzLkVSX05PREVTRVRfTk9UX01VVEFCTEUsIG51bGwpKTsgLy8iVGhpcyBOb2RlU2V0IGlzIG5vdCBtdXRhYmxlISIpOwotCi0gICAgaWYgKG51bGwgPT0gbV9tYXApCi0gICAgewotICAgICAgbV9tYXAgPSBuZXcgTm9kZVttX2Jsb2Nrc2l6ZV07Ci0gICAgICBtX21hcFNpemUgPSBtX2Jsb2Nrc2l6ZTsKLSAgICB9Ci0gICAgZWxzZSBpZiAoKG1fZmlyc3RGcmVlICsgMSkgPj0gbV9tYXBTaXplKQotICAgIHsKLSAgICAgIG1fbWFwU2l6ZSArPSBtX2Jsb2Nrc2l6ZTsKLQotICAgICAgTm9kZSBuZXdNYXBbXSA9IG5ldyBOb2RlW21fbWFwU2l6ZV07Ci0KLSAgICAgIFN5c3RlbS5hcnJheWNvcHkobV9tYXAsIDAsIG5ld01hcCwgMCwgbV9maXJzdEZyZWUgKyAxKTsKLQotICAgICAgbV9tYXAgPSBuZXdNYXA7Ci0gICAgfQotCi0gICAgaWYgKGF0IDw9IChtX2ZpcnN0RnJlZSAtIDEpKQotICAgIHsKLSAgICAgIFN5c3RlbS5hcnJheWNvcHkobV9tYXAsIGF0LCBtX21hcCwgYXQgKyAxLCBtX2ZpcnN0RnJlZSAtIGF0KTsKLSAgICB9Ci0KLSAgICBtX21hcFthdF0gPSB2YWx1ZTsKLQotICAgIG1fZmlyc3RGcmVlKys7Ci0gIH0KLQotICAvKioKLSAgICogQXBwZW5kIHRoZSBub2RlcyB0byB0aGUgbGlzdC4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVzIE5vZGVWZWN0b3IgdG8gYXBwZW5kIHRvIHRoaXMgbGlzdAotICAgKi8KLSAgcHVibGljIHZvaWQgYXBwZW5kTm9kZXMoTm9kZVNldCBub2RlcykKLSAgewotCi0gICAgaW50IG5Ob2RlcyA9IG5vZGVzLnNpemUoKTsKLQotICAgIGlmIChudWxsID09IG1fbWFwKQotICAgIHsKLSAgICAgIG1fbWFwU2l6ZSA9IG5Ob2RlcyArIG1fYmxvY2tzaXplOwotICAgICAgbV9tYXAgPSBuZXcgTm9kZVttX21hcFNpemVdOwotICAgIH0KLSAgICBlbHNlIGlmICgobV9maXJzdEZyZWUgKyBuTm9kZXMpID49IG1fbWFwU2l6ZSkKLSAgICB7Ci0gICAgICBtX21hcFNpemUgKz0gKG5Ob2RlcyArIG1fYmxvY2tzaXplKTsKLQotICAgICAgTm9kZSBuZXdNYXBbXSA9IG5ldyBOb2RlW21fbWFwU2l6ZV07Ci0KLSAgICAgIFN5c3RlbS5hcnJheWNvcHkobV9tYXAsIDAsIG5ld01hcCwgMCwgbV9maXJzdEZyZWUgKyBuTm9kZXMpOwotCi0gICAgICBtX21hcCA9IG5ld01hcDsKLSAgICB9Ci0KLSAgICBTeXN0ZW0uYXJyYXljb3B5KG5vZGVzLm1fbWFwLCAwLCBtX21hcCwgbV9maXJzdEZyZWUsIG5Ob2Rlcyk7Ci0KLSAgICBtX2ZpcnN0RnJlZSArPSBuTm9kZXM7Ci0gIH0KLQotICAvKioKLSAgICogSW5zZXJ0cyB0aGUgc3BlY2lmaWVkIG5vZGUgaW4gdGhpcyB2ZWN0b3IgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4KLSAgICogRWFjaCBjb21wb25lbnQgaW4gdGhpcyB2ZWN0b3Igd2l0aCBhbiBpbmRleCBncmVhdGVyIG9yIGVxdWFsIHRvCi0gICAqIHRoZSBzcGVjaWZpZWQgaW5kZXggaXMgc2hpZnRlZCB1cHdhcmQgdG8gaGF2ZSBhbiBpbmRleCBvbmUgZ3JlYXRlcgotICAgKiB0aGFuIHRoZSB2YWx1ZSBpdCBoYWQgcHJldmlvdXNseS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHJlbW92ZUFsbEVsZW1lbnRzKCkKLSAgewotCi0gICAgaWYgKG51bGwgPT0gbV9tYXApCi0gICAgICByZXR1cm47Ci0KLSAgICBmb3IgKGludCBpID0gMDsgaSA8IG1fZmlyc3RGcmVlOyBpKyspCi0gICAgewotICAgICAgbV9tYXBbaV0gPSBudWxsOwotICAgIH0KLQotICAgIG1fZmlyc3RGcmVlID0gMDsKLSAgfQotCi0gIC8qKgotICAgKiBSZW1vdmVzIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZSBhcmd1bWVudCBmcm9tIHRoaXMgdmVjdG9yLgotICAgKiBJZiB0aGUgb2JqZWN0IGlzIGZvdW5kIGluIHRoaXMgdmVjdG9yLCBlYWNoIGNvbXBvbmVudCBpbiB0aGUgdmVjdG9yCi0gICAqIHdpdGggYW4gaW5kZXggZ3JlYXRlciBvciBlcXVhbCB0byB0aGUgb2JqZWN0J3MgaW5kZXggaXMgc2hpZnRlZAotICAgKiBkb3dud2FyZCB0byBoYXZlIGFuIGluZGV4IG9uZSBzbWFsbGVyIHRoYW4gdGhlIHZhbHVlIGl0IGhhZAotICAgKiBwcmV2aW91c2x5LgotICAgKgotICAgKiBAcGFyYW0gcyBOb2RlIHRvIHJlbW92ZSBmcm9tIHRoZSBsaXN0Ci0gICAqCi0gICAqIEByZXR1cm4gVHJ1ZSBpZiB0aGUgbm9kZSB3YXMgc3VjY2Vzc2Z1bGx5IHJlbW92ZWQKLSAgICovCi0gIHB1YmxpYyBib29sZWFuIHJlbW92ZUVsZW1lbnQoTm9kZSBzKQotICB7Ci0gICAgaWYgKCFtX211dGFibGUpCi0gICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoWFBBVEhFcnJvclJlc291cmNlcy5FUl9OT0RFU0VUX05PVF9NVVRBQkxFLCBudWxsKSk7IC8vIlRoaXMgTm9kZVNldCBpcyBub3QgbXV0YWJsZSEiKTsKLQotICAgIGlmIChudWxsID09IG1fbWFwKQotICAgICAgcmV0dXJuIGZhbHNlOwotCi0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtX2ZpcnN0RnJlZTsgaSsrKQotICAgIHsKLSAgICAgIE5vZGUgbm9kZSA9IG1fbWFwW2ldOwotCi0gICAgICBpZiAoKG51bGwgIT0gbm9kZSkgJiYgbm9kZS5lcXVhbHMocykpCi0gICAgICB7Ci0gICAgICAgIGlmIChpIDwgbV9maXJzdEZyZWUgLSAxKQotICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkobV9tYXAsIGkgKyAxLCBtX21hcCwgaSwgbV9maXJzdEZyZWUgLSBpIC0gMSk7Ci0KLSAgICAgICAgbV9maXJzdEZyZWUtLTsKLSAgICAgICAgbV9tYXBbbV9maXJzdEZyZWVdID0gbnVsbDsKLQotICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gZmFsc2U7Ci0gIH0KLQotICAvKioKLSAgICogRGVsZXRlcyB0aGUgY29tcG9uZW50IGF0IHRoZSBzcGVjaWZpZWQgaW5kZXguIEVhY2ggY29tcG9uZW50IGluCi0gICAqIHRoaXMgdmVjdG9yIHdpdGggYW4gaW5kZXggZ3JlYXRlciBvciBlcXVhbCB0byB0aGUgc3BlY2lmaWVkCi0gICAqIGluZGV4IGlzIHNoaWZ0ZWQgZG93bndhcmQgdG8gaGF2ZSBhbiBpbmRleCBvbmUgc21hbGxlciB0aGFuCi0gICAqIHRoZSB2YWx1ZSBpdCBoYWQgcHJldmlvdXNseS4KLSAgICoKLSAgICogQHBhcmFtIGkgSW5kZXggb2Ygbm9kZSB0byByZW1vdmUKLSAgICovCi0gIHB1YmxpYyB2b2lkIHJlbW92ZUVsZW1lbnRBdChpbnQgaSkKLSAgewotCi0gICAgaWYgKG51bGwgPT0gbV9tYXApCi0gICAgICByZXR1cm47Ci0KLSAgICBpZiAoaSA+PSBtX2ZpcnN0RnJlZSkKLSAgICAgIHRocm93IG5ldyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oaSArICIgPj0gIiArIG1fZmlyc3RGcmVlKTsKLSAgICBlbHNlIGlmIChpIDwgMCkKLSAgICAgIHRocm93IG5ldyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oaSk7Ci0KLSAgICBpZiAoaSA8IG1fZmlyc3RGcmVlIC0gMSkKLSAgICAgIFN5c3RlbS5hcnJheWNvcHkobV9tYXAsIGkgKyAxLCBtX21hcCwgaSwgbV9maXJzdEZyZWUgLSBpIC0gMSk7Ci0KLSAgICBtX2ZpcnN0RnJlZS0tOwotICAgIG1fbWFwW21fZmlyc3RGcmVlXSA9IG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogU2V0cyB0aGUgY29tcG9uZW50IGF0IHRoZSBzcGVjaWZpZWQgaW5kZXggb2YgdGhpcyB2ZWN0b3IgdG8gYmUgdGhlCi0gICAqIHNwZWNpZmllZCBvYmplY3QuIFRoZSBwcmV2aW91cyBjb21wb25lbnQgYXQgdGhhdCBwb3NpdGlvbiBpcyBkaXNjYXJkZWQuCi0gICAqCi0gICAqIFRoZSBpbmRleCBtdXN0IGJlIGEgdmFsdWUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIDAgYW5kIGxlc3MKLSAgICogdGhhbiB0aGUgY3VycmVudCBzaXplIG9mIHRoZSB2ZWN0b3IuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlIE5vZGUgdG8gc2V0Ci0gICAqIEBwYXJhbSBpbmRleCBJbmRleCBvZiB3aGVyZSB0byBzZXQgdGhlIG5vZGUKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldEVsZW1lbnRBdChOb2RlIG5vZGUsIGludCBpbmRleCkKLSAgewotICAgIGlmICghbV9tdXRhYmxlKQotICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfTk9ERVNFVF9OT1RfTVVUQUJMRSwgbnVsbCkpOyAvLyJUaGlzIE5vZGVTZXQgaXMgbm90IG11dGFibGUhIik7Ci0KLSAgICBpZiAobnVsbCA9PSBtX21hcCkKLSAgICB7Ci0gICAgICBtX21hcCA9IG5ldyBOb2RlW21fYmxvY2tzaXplXTsKLSAgICAgIG1fbWFwU2l6ZSA9IG1fYmxvY2tzaXplOwotICAgIH0KLQotICAgIG1fbWFwW2luZGV4XSA9IG5vZGU7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBudGggZWxlbWVudC4KLSAgICoKLSAgICogQHBhcmFtIGkgSW5kZXggb2Ygbm9kZSB0byBnZXQKLSAgICoKLSAgICogQHJldHVybiBOb2RlIGF0IHNwZWNpZmllZCBpbmRleAotICAgKi8KLSAgcHVibGljIE5vZGUgZWxlbWVudEF0KGludCBpKQotICB7Ci0KLSAgICBpZiAobnVsbCA9PSBtX21hcCkKLSAgICAgIHJldHVybiBudWxsOwotCi0gICAgcmV0dXJuIG1fbWFwW2ldOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgdGhlIHRhYmxlIGNvbnRhaW5zIHRoZSBnaXZlbiBub2RlLgotICAgKgotICAgKiBAcGFyYW0gcyBOb2RlIHRvIGxvb2sgZm9yCi0gICAqCi0gICAqIEByZXR1cm4gVHJ1ZSBpZiB0aGUgZ2l2ZW4gbm9kZSB3YXMgZm91bmQuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBjb250YWlucyhOb2RlIHMpCi0gIHsKLSAgICBydW5UbygtMSk7Ci0KLSAgICBpZiAobnVsbCA9PSBtX21hcCkKLSAgICAgIHJldHVybiBmYWxzZTsKLQotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbV9maXJzdEZyZWU7IGkrKykKLSAgICB7Ci0gICAgICBOb2RlIG5vZGUgPSBtX21hcFtpXTsKLQotICAgICAgaWYgKChudWxsICE9IG5vZGUpICYmIG5vZGUuZXF1YWxzKHMpKQotICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICB9Ci0KLSAgICByZXR1cm4gZmFsc2U7Ci0gIH0KLQotICAvKioKLSAgICogU2VhcmNoZXMgZm9yIHRoZSBmaXJzdCBvY2N1cmVuY2Ugb2YgdGhlIGdpdmVuIGFyZ3VtZW50LAotICAgKiBiZWdpbm5pbmcgdGhlIHNlYXJjaCBhdCBpbmRleCwgYW5kIHRlc3RpbmcgZm9yIGVxdWFsaXR5Ci0gICAqIHVzaW5nIHRoZSBlcXVhbHMgbWV0aG9kLgotICAgKgotICAgKiBAcGFyYW0gZWxlbSBOb2RlIHRvIGxvb2sgZm9yCi0gICAqIEBwYXJhbSBpbmRleCBJbmRleCBvZiB3aGVyZSB0byBzdGFydCB0aGUgc2VhcmNoCi0gICAqIEByZXR1cm4gdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZSBvYmplY3QKLSAgICogYXJndW1lbnQgaW4gdGhpcyB2ZWN0b3IgYXQgcG9zaXRpb24gaW5kZXggb3IgbGF0ZXIgaW4gdGhlCi0gICAqIHZlY3RvcjsgcmV0dXJucyAtMSBpZiB0aGUgb2JqZWN0IGlzIG5vdCBmb3VuZC4KLSAgICovCi0gIHB1YmxpYyBpbnQgaW5kZXhPZihOb2RlIGVsZW0sIGludCBpbmRleCkKLSAgewotICAgIHJ1blRvKC0xKTsKLQotICAgIGlmIChudWxsID09IG1fbWFwKQotICAgICAgcmV0dXJuIC0xOwotCi0gICAgZm9yIChpbnQgaSA9IGluZGV4OyBpIDwgbV9maXJzdEZyZWU7IGkrKykKLSAgICB7Ci0gICAgICBOb2RlIG5vZGUgPSBtX21hcFtpXTsKLQotICAgICAgaWYgKChudWxsICE9IG5vZGUpICYmIG5vZGUuZXF1YWxzKGVsZW0pKQotICAgICAgICByZXR1cm4gaTsKLSAgICB9Ci0KLSAgICByZXR1cm4gLTE7Ci0gIH0KLQotICAvKioKLSAgICogU2VhcmNoZXMgZm9yIHRoZSBmaXJzdCBvY2N1cmVuY2Ugb2YgdGhlIGdpdmVuIGFyZ3VtZW50LAotICAgKiBiZWdpbm5pbmcgdGhlIHNlYXJjaCBhdCBpbmRleCwgYW5kIHRlc3RpbmcgZm9yIGVxdWFsaXR5Ci0gICAqIHVzaW5nIHRoZSBlcXVhbHMgbWV0aG9kLgotICAgKgotICAgKiBAcGFyYW0gZWxlbSBOb2RlIHRvIGxvb2sgZm9yCi0gICAqIEByZXR1cm4gdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZSBvYmplY3QKLSAgICogYXJndW1lbnQgaW4gdGhpcyB2ZWN0b3IgYXQgcG9zaXRpb24gaW5kZXggb3IgbGF0ZXIgaW4gdGhlCi0gICAqIHZlY3RvcjsgcmV0dXJucyAtMSBpZiB0aGUgb2JqZWN0IGlzIG5vdCBmb3VuZC4KLSAgICovCi0gIHB1YmxpYyBpbnQgaW5kZXhPZihOb2RlIGVsZW0pCi0gIHsKLSAgICBydW5UbygtMSk7Ci0KLSAgICBpZiAobnVsbCA9PSBtX21hcCkKLSAgICAgIHJldHVybiAtMTsKLQotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbV9maXJzdEZyZWU7IGkrKykKLSAgICB7Ci0gICAgICBOb2RlIG5vZGUgPSBtX21hcFtpXTsKLQotICAgICAgaWYgKChudWxsICE9IG5vZGUpICYmIG5vZGUuZXF1YWxzKGVsZW0pKQotICAgICAgICByZXR1cm4gaTsKLSAgICB9Ci0KLSAgICByZXR1cm4gLTE7Ci0gIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9Ob2RlU2V0RFRNLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL05vZGVTZXREVE0uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggY2M5ODdkOC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL05vZGVTZXREVE0uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEyNDkgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogTm9kZVNldERUTS5qYXZhLHYgMS4yLjQuMiAyMDA1LzA5LzE0IDIwOjMwOjA2IGplZmZzdXR0b3IgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWw7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwucmVzLlhTTE1lc3NhZ2VzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1GaWx0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNSXRlcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNTWFuYWdlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLk5vZGVWZWN0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLnJlcy5YUEFUSEVycm9yUmVzb3VyY2VzOwotCi1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlTGlzdDsKLWltcG9ydCBvcmcudzNjLmRvbS50cmF2ZXJzYWwuTm9kZUl0ZXJhdG9yOwotCi0KLS8qKgotICogPHA+VGhlIE5vZGVTZXREVE0gY2xhc3MgY2FuIGFjdCBhcyBlaXRoZXIgYSBOb2RlVmVjdG9yLAotICogTm9kZUxpc3QsIG9yIE5vZGVJdGVyYXRvci4gIEhvd2V2ZXIsIGluIG9yZGVyIGZvciBpdCB0bwotICogYWN0IGFzIGEgTm9kZVZlY3RvciBvciBOb2RlTGlzdCwgaXQncyByZXF1aXJlZCB0aGF0Ci0gKiBzZXRTaG91bGRDYWNoZU5vZGVzKHRydWUpIGJlIGNhbGxlZCBiZWZvcmUgdGhlIGZpcnN0Ci0gKiBuZXh0Tm9kZSgpIGlzIGNhbGxlZCwgaW4gb3JkZXIgdGhhdCBub2RlcyBjYW4gYmUgYWRkZWQKLSAqIGFzIHRoZXkgYXJlIGZldGNoZWQuICBEZXJpdmVkIGNsYXNzZXMgdGhhdCBpbXBsZW1lbnQgaXRlcmF0b3JzCi0gKiBtdXN0IG92ZXJyaWRlIHJ1blRvKGludCBpbmRleCksIGluIG9yZGVyIHRoYXQgdGhleSBtYXkKLSAqIHJ1biB0aGUgaXRlcmF0aW9uIHRvIHRoZSBnaXZlbiBpbmRleC4gPC9wPgotICoKLSAqIDxwPk5vdGUgdGhhdCB3ZSBkaXJlY3RseSBpbXBsZW1lbnQgdGhlIERPTSdzIE5vZGVJdGVyYXRvcgotICogaW50ZXJmYWNlLiBXZSBkbyBub3QgZW11bGF0ZSBhbGwgdGhlIGJlaGF2aW9yIG9mIHRoZQotICogc3RhbmRhcmQgTm9kZUl0ZXJhdG9yLiBJbiBwYXJ0aWN1bGFyLCB3ZSBkbyBub3QgZ3VhcmFudGVlCi0gKiB0byBwcmVzZW50IGEgImxpdmUgdmlldyIgb2YgdGhlIGRvY3VtZW50IC4uLiBidXQgaW4gWFNMVCwKLSAqIHRoZSBzb3VyY2UgZG9jdW1lbnQgc2hvdWxkIG5ldmVyIGJlIG11dGF0ZWQsIHNvIHRoaXMgc2hvdWxkCi0gKiBuZXZlciBiZSBhbiBpc3N1ZS48L3A+Ci0gKgotICogPHA+VGhvdWdodDogU2hvdWxkIE5vZGVTZXREVE0gcmVhbGx5IGltcGxlbWVudCBOb2RlTGlzdCBhbmQgTm9kZUl0ZXJhdG9yLAotICogb3Igc2hvdWxkIHRoZXJlIGJlIHNwZWNpZmljIHN1YmNsYXNzZXMgb2YgaXQgd2hpY2ggZG8gc28/IFRoZQotICogYWR2YW50YWdlIG9mIGRvaW5nIGl0IGFsbCBoZXJlIGlzIHRoYXQgYWxsIE5vZGVTZXREVE1zIHdpbGwgcmVzcG9uZAotICogdG8gdGhlIHNhbWUgY2FsbHM7IHRoZSBkaXNhZHZhbnRhZ2UgaXMgdGhhdCBzb21lIG9mIHRoZW0gbWF5IHJldHVybgotICogbGVzcy10aGFuLWVubGlnaHRlbmluZyByZXN1bHRzIHdoZW4geW91IGRvIHNvLjwvcD4KLSAqIEB4c2wudXNhZ2UgYWR2YW5jZWQKLSAqLwotcHVibGljIGNsYXNzIE5vZGVTZXREVE0gZXh0ZW5kcyBOb2RlVmVjdG9yCi0gICAgICAgIGltcGxlbWVudHMgLyogTm9kZUxpc3QsIE5vZGVJdGVyYXRvciwgKi8gRFRNSXRlcmF0b3IsCi0gICAgICAgIENsb25lYWJsZQotewotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA3Njg2NDgwMTMzMzMxMzE3MDcwTDsKLQotICAvKioKLSAgICogQ3JlYXRlIGFuIGVtcHR5IG5vZGVsaXN0LgotICAgKi8KLSAgcHVibGljIE5vZGVTZXREVE0oRFRNTWFuYWdlciBkdG1NYW5hZ2VyKQotICB7Ci0gICAgc3VwZXIoKTsKLSAgICBtX21hbmFnZXIgPSBkdG1NYW5hZ2VyOwotICB9Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhbiBlbXB0eSwgdXNpbmcgdGhlIGdpdmVuIGJsb2NrIHNpemUuCi0gICAqCi0gICAqIEBwYXJhbSBibG9ja3NpemUgU2l6ZSBvZiBibG9ja3MgdG8gYWxsb2NhdGUKLSAgICogQHBhcmFtIGR1bW15IHBhc3MgemVybyBmb3IgcmlnaHQgbm93Li4uCi0gICAqLwotICBwdWJsaWMgTm9kZVNldERUTShpbnQgYmxvY2tzaXplLCBpbnQgZHVtbXksIERUTU1hbmFnZXIgZHRtTWFuYWdlcikKLSAgewotICAgIHN1cGVyKGJsb2Nrc2l6ZSk7Ci0gICAgbV9tYW5hZ2VyID0gZHRtTWFuYWdlcjsKLSAgfQotCi0gIC8vICVUQkQlCi0vLyAgLyoqCi0vLyAgICogQ3JlYXRlIGEgTm9kZVNldERUTSwgYW5kIGNvcHkgdGhlIG1lbWJlcnMgb2YgdGhlCi0vLyAgICogZ2l2ZW4gbm9kZWxpc3QgaW50byBpdC4KLS8vICAgKgotLy8gICAqIEBwYXJhbSBub2RlbGlzdCBMaXN0IG9mIE5vZGVzIHRvIGJlIG1hZGUgbWVtYmVycyBvZiB0aGUgbmV3IHNldC4KLS8vICAgKi8KLS8vICBwdWJsaWMgTm9kZVNldERUTShOb2RlTGlzdCBub2RlbGlzdCkKLS8vICB7Ci0vLwotLy8gICAgc3VwZXIoKTsKLS8vCi0vLyAgICBhZGROb2Rlcyhub2RlbGlzdCk7Ci0vLyAgfQotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBOb2RlU2V0RFRNLCBhbmQgY29weSB0aGUgbWVtYmVycyBvZiB0aGUKLSAgICogZ2l2ZW4gTm9kZVNldERUTSBpbnRvIGl0LgotICAgKgotICAgKiBAcGFyYW0gbm9kZWxpc3QgU2V0IG9mIE5vZGVzIHRvIGJlIG1hZGUgbWVtYmVycyBvZiB0aGUgbmV3IHNldC4KLSAgICovCi0gIHB1YmxpYyBOb2RlU2V0RFRNKE5vZGVTZXREVE0gbm9kZWxpc3QpCi0gIHsKLQotICAgIHN1cGVyKCk7Ci0gICAgbV9tYW5hZ2VyID0gbm9kZWxpc3QuZ2V0RFRNTWFuYWdlcigpOwotICAgIG1fcm9vdCA9IG5vZGVsaXN0LmdldFJvb3QoKTsKLQotICAgIGFkZE5vZGVzKChEVE1JdGVyYXRvcikgbm9kZWxpc3QpOwotICB9Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIE5vZGVTZXREVE0sIGFuZCBjb3B5IHRoZSBtZW1iZXJzIG9mIHRoZQotICAgKiBnaXZlbiBEVE1JdGVyYXRvciBpbnRvIGl0LgotICAgKgotICAgKiBAcGFyYW0gbmkgSXRlcmF0b3Igd2hpY2ggeWllbGRzIE5vZGVzIHRvIGJlIG1hZGUgbWVtYmVycyBvZiB0aGUgbmV3IHNldC4KLSAgICovCi0gIHB1YmxpYyBOb2RlU2V0RFRNKERUTUl0ZXJhdG9yIG5pKQotICB7Ci0KLSAgICBzdXBlcigpOwotCi0gICAgbV9tYW5hZ2VyID0gbmkuZ2V0RFRNTWFuYWdlcigpOwotICAgIG1fcm9vdCA9IG5pLmdldFJvb3QoKTsKLSAgICBhZGROb2RlcyhuaSk7Ci0gIH0KLQotICAvKioKLSAgICogQ3JlYXRlIGEgTm9kZVNldERUTSwgYW5kIGNvcHkgdGhlIG1lbWJlcnMgb2YgdGhlCi0gICAqIGdpdmVuIERUTUl0ZXJhdG9yIGludG8gaXQuCi0gICAqCi0gICAqIEBwYXJhbSBpdGVyYXRvciBJdGVyYXRvciB3aGljaCB5aWVsZHMgTm9kZXMgdG8gYmUgbWFkZSBtZW1iZXJzIG9mIHRoZSBuZXcgc2V0LgotICAgKi8KLSAgcHVibGljIE5vZGVTZXREVE0oTm9kZUl0ZXJhdG9yIGl0ZXJhdG9yLCBYUGF0aENvbnRleHQgeGN0eHQpCi0gIHsKLQotICAgIHN1cGVyKCk7Ci0KLSAgICBOb2RlIG5vZGU7Ci0gICAgbV9tYW5hZ2VyID0geGN0eHQuZ2V0RFRNTWFuYWdlcigpOwotCi0gICAgd2hpbGUgKG51bGwgIT0gKG5vZGUgPSBpdGVyYXRvci5uZXh0Tm9kZSgpKSkKLSAgICB7Ci0gICAgICBpbnQgaGFuZGxlID0geGN0eHQuZ2V0RFRNSGFuZGxlRnJvbU5vZGUobm9kZSk7Ci0gICAgICBhZGROb2RlSW5Eb2NPcmRlcihoYW5kbGUsIHhjdHh0KTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogQ3JlYXRlIGEgTm9kZVNldERUTSwgYW5kIGNvcHkgdGhlIG1lbWJlcnMgb2YgdGhlCi0gICAqIGdpdmVuIERUTUl0ZXJhdG9yIGludG8gaXQuCi0gICAqCi0gICAqLwotICBwdWJsaWMgTm9kZVNldERUTShOb2RlTGlzdCBub2RlTGlzdCwgWFBhdGhDb250ZXh0IHhjdHh0KQotICB7Ci0KLSAgICBzdXBlcigpOwotCi0gICAgbV9tYW5hZ2VyID0geGN0eHQuZ2V0RFRNTWFuYWdlcigpOwotCi0gICAgaW50IG4gPSBub2RlTGlzdC5nZXRMZW5ndGgoKTsKLSAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykKLSAgICB7Ci0gICAgICBOb2RlIG5vZGUgPSBub2RlTGlzdC5pdGVtKGkpOwotICAgICAgaW50IGhhbmRsZSA9IHhjdHh0LmdldERUTUhhbmRsZUZyb21Ob2RlKG5vZGUpOwotICAgICAgLy8gRG8gbm90IHJlb3JkZXIgb3Igc3RyaXAgZHVwbGljYXRlIG5vZGVzIGZyb20gdGhlIGdpdmVuIERPTSBub2RlbGlzdAotICAgICAgYWRkTm9kZShoYW5kbGUpOyAvLyBhZGROb2RlSW5Eb2NPcmRlcihoYW5kbGUsIHhjdHh0KTsKLSAgICB9Ci0gIH0KLQotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBOb2RlU2V0RFRNIHdoaWNoIGNvbnRhaW5zIHRoZSBnaXZlbiBOb2RlLgotICAgKgotICAgKiBAcGFyYW0gbm9kZSBTaW5nbGUgbm9kZSB0byBiZSBhZGRlZCB0byB0aGUgbmV3IHNldC4KLSAgICovCi0gIHB1YmxpYyBOb2RlU2V0RFRNKGludCBub2RlLCBEVE1NYW5hZ2VyIGR0bU1hbmFnZXIpCi0gIHsKLQotICAgIHN1cGVyKCk7Ci0gICAgbV9tYW5hZ2VyID0gZHRtTWFuYWdlcjsKLQotICAgIGFkZE5vZGUobm9kZSk7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBlbnZpcm9ubWVudCBpbiB3aGljaCB0aGlzIGl0ZXJhdG9yIG9wZXJhdGVzLCB3aGljaCBzaG91bGQgcHJvdmlkZToKLSAgICogYSBub2RlICh0aGUgY29udGV4dCBub2RlLi4uIHNhbWUgdmFsdWUgYXMgInJvb3QiIGRlZmluZWQgYmVsb3cpCi0gICAqIGEgcGFpciBvZiBub24temVybyBwb3NpdGl2ZSBpbnRlZ2VycyAodGhlIGNvbnRleHQgcG9zaXRpb24gYW5kIHRoZSBjb250ZXh0IHNpemUpCi0gICAqIGEgc2V0IG9mIHZhcmlhYmxlIGJpbmRpbmdzCi0gICAqIGEgZnVuY3Rpb24gbGlicmFyeQotICAgKiB0aGUgc2V0IG9mIG5hbWVzcGFjZSBkZWNsYXJhdGlvbnMgaW4gc2NvcGUgZm9yIHRoZSBleHByZXNzaW9uLgotICAgKgotICAgKiA8cD5BdCB0aGlzIHRpbWUgdGhlIGV4YWN0IGltcGxlbWVudGF0aW9uIG9mIHRoaXMgZW52aXJvbm1lbnQgaXMgYXBwbGljYXRpb24KLSAgICogZGVwZW5kZW50LiAgUHJvYmFibHkgYSBwcm9wZXIgaW50ZXJmYWNlIHdpbGwgYmUgY3JlYXRlZCBmYWlybHkgc29vbi48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBlbnZpcm9ubWVudCBUaGUgZW52aXJvbm1lbnQgb2JqZWN0LgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0RW52aXJvbm1lbnQoT2JqZWN0IGVudmlyb25tZW50KQotICB7Ci0gICAgLy8gbm8tb3AKLSAgfQotCi0KLSAgLyoqCi0gICAqIEByZXR1cm4gVGhlIHJvb3Qgbm9kZSBvZiB0aGUgSXRlcmF0b3IsIGFzIHNwZWNpZmllZCB3aGVuIGl0IHdhcyBjcmVhdGVkLgotICAgKiBGb3Igbm9uLUl0ZXJhdG9yIE5vZGVTZXREVE1zLCB0aGlzIHdpbGwgYmUgbnVsbC4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0Um9vdCgpCi0gIHsKLSAgICBpZihEVE0uTlVMTCA9PSBtX3Jvb3QpCi0gICAgewotICAgICAgaWYoc2l6ZSgpID4gMCkKLSAgICAgICAgcmV0dXJuIGl0ZW0oMCk7Ci0gICAgICBlbHNlCi0gICAgICAgIHJldHVybiBEVE0uTlVMTDsKLSAgICB9Ci0gICAgZWxzZQotICAgICAgcmV0dXJuIG1fcm9vdDsKLSAgfQotCi0gIC8qKgotICAgKiBJbml0aWFsaXplIHRoZSBjb250ZXh0IHZhbHVlcyBmb3IgdGhpcyBleHByZXNzaW9uCi0gICAqIGFmdGVyIGl0IGlzIGNsb25lZC4KLSAgICoKLSAgICogQHBhcmFtIGNvbnRleHQgVGhlIFhQYXRoIHJ1bnRpbWUgY29udGV4dCBmb3IgdGhpcwotICAgKiB0cmFuc2Zvcm1hdGlvbi4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFJvb3QoaW50IGNvbnRleHQsIE9iamVjdCBlbnZpcm9ubWVudCkKLSAgewotICAgIC8vIG5vLW9wLCBJIGd1ZXNzLi4uICAoLXNiKQotICB9Ci0KLSAgLyoqCi0gICAqIENsb25lIHRoaXMgTm9kZVNldERUTS4KLSAgICogQXQgdGhpcyB0aW1lLCB3ZSBvbmx5IGV4cGVjdCB0aGlzIHRvIGJlIHVzZWQgd2l0aCBMb2NQYXRoSXRlcmF0b3JzOwotICAgKiBpdCBtYXkgbm90IHdvcmsgd2l0aCBvdGhlciBraW5kcyBvZiBOb2RlU2V0RFRNcy4KLSAgICoKLSAgICogQHJldHVybiBhIG5ldyBOb2RlU2V0RFRNIG9mIHRoZSBzYW1lIHR5cGUsIGhhdmluZyB0aGUgc2FtZSBzdGF0ZS4uLgotICAgKiB0aG91Z2ggdW5sZXNzIG92ZXJyaWRkZW4gaW4gdGhlIHN1YmNsYXNzZXMsIGl0IG1heSBub3QgY29weSBhbGwKLSAgICogdGhlIHN0YXRlIGluZm9ybWF0aW9uLgotICAgKgotICAgKiBAdGhyb3dzIENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGlmIHRoaXMgc3ViY2xhc3Mgb2YgTm9kZVNldERUTQotICAgKiBkb2VzIG5vdCBzdXBwb3J0IHRoZSBjbG9uZSgpIG9wZXJhdGlvbi4KLSAgICovCi0gIHB1YmxpYyBPYmplY3QgY2xvbmUoKSB0aHJvd3MgQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24KLSAgewotCi0gICAgTm9kZVNldERUTSBjbG9uZSA9IChOb2RlU2V0RFRNKSBzdXBlci5jbG9uZSgpOwotCi0gICAgcmV0dXJuIGNsb25lOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBhIGNsb25lZCBJdGVyYXRvciwgYW5kIHJlc2V0IGl0cyBzdGF0ZSB0byB0aGUgYmVnaW5uaW5nIG9mIHRoZQotICAgKiBpdGVyYXRpb24uCi0gICAqCi0gICAqIEByZXR1cm4gYSBuZXcgTm9kZVNldERUTSBvZiB0aGUgc2FtZSB0eXBlLCBoYXZpbmcgdGhlIHNhbWUgc3RhdGUuLi4KLSAgICogZXhjZXB0IHRoYXQgdGhlIHJlc2V0KCkgb3BlcmF0aW9uIGhhcyBiZWVuIGNhbGxlZC4KLSAgICoKLSAgICogQHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBpZiB0aGlzIHN1YmNsYXNzIG9mIE5vZGVTZXREVE0KLSAgICogZG9lcyBub3Qgc3VwcG9ydCB0aGUgY2xvbmUoKSBvcGVyYXRpb24uCi0gICAqLwotICBwdWJsaWMgRFRNSXRlcmF0b3IgY2xvbmVXaXRoUmVzZXQoKSB0aHJvd3MgQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24KLSAgewotCi0gICAgTm9kZVNldERUTSBjbG9uZSA9IChOb2RlU2V0RFRNKSBjbG9uZSgpOwotCi0gICAgY2xvbmUucmVzZXQoKTsKLQotICAgIHJldHVybiBjbG9uZTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXNldCB0aGUgaXRlcmF0b3IuIE1heSBoYXZlIG5vIGVmZmVjdCBvbiBub24taXRlcmF0b3IgTm9kZXNldHMuCi0gICAqLwotICBwdWJsaWMgdm9pZCByZXNldCgpCi0gIHsKLSAgICBtX25leHQgPSAwOwotICB9Ci0KLSAgLyoqCi0gICAqICBUaGlzIGF0dHJpYnV0ZSBkZXRlcm1pbmVzIHdoaWNoIG5vZGUgdHlwZXMgYXJlIHByZXNlbnRlZCB2aWEgdGhlCi0gICAqIGl0ZXJhdG9yLiBUaGUgYXZhaWxhYmxlIHNldCBvZiBjb25zdGFudHMgaXMgZGVmaW5lZCBpbiB0aGUKLSAgICogPGNvZGU+RFRNRmlsdGVyPC9jb2RlPiBpbnRlcmZhY2UuIEZvciBOb2RlU2V0RFRNcywgdGhlIG1hc2sgaGFzIGJlZW4KLSAgICogaGFyZGNvZGVkIHRvIHNob3cgYWxsIG5vZGVzIGV4Y2VwdCBFbnRpdHlSZWZlcmVuY2Ugbm9kZXMsIHdoaWNoIGhhdmUKLSAgICogbm8gZXF1aXZhbGVudCBpbiB0aGUgWFBhdGggZGF0YSBtb2RlbC4KLSAgICoKLSAgICogQHJldHVybiBpbnRlZ2VyIHVzZWQgYXMgYSBiaXQtYXJyYXksIGNvbnRhaW5pbmcgZmxhZ3MgZGVmaW5lZCBpbgotICAgKiB0aGUgRE9NJ3MgRFRNRmlsdGVyIGNsYXNzLiBUaGUgdmFsdWUgd2lsbCBiZQotICAgKiA8Y29kZT5TSE9XX0FMTCAmIH5TSE9XX0VOVElUWV9SRUZFUkVOQ0U8L2NvZGU+LCBtZWFuaW5nIHRoYXQKLSAgICogb25seSBlbnRpdHkgcmVmZXJlbmNlcyBhcmUgc3VwcHJlc3NlZC4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0V2hhdFRvU2hvdygpCi0gIHsKLSAgICByZXR1cm4gRFRNRmlsdGVyLlNIT1dfQUxMICYgfkRUTUZpbHRlci5TSE9XX0VOVElUWV9SRUZFUkVOQ0U7Ci0gIH0KLQotICAvKioKLSAgICogVGhlIGZpbHRlciBvYmplY3QgdXNlZCB0byBzY3JlZW4gbm9kZXMuIEZpbHRlcnMgYXJlIGFwcGxpZWQgdG8KLSAgICogZnVydGhlciByZWR1Y2UgKGFuZCByZXN0cnVjdHVyZSkgdGhlIERUTUl0ZXJhdG9yJ3MgdmlldyBvZiB0aGUKLSAgICogZG9jdW1lbnQuIEluIG91ciBjYXNlLCB3ZSB3aWxsIGJlIHVzaW5nIGhhcmRjb2RlZCBmaWx0ZXJzIGJ1aWx0Ci0gICAqIGludG8gb3VyIGl0ZXJhdG9ycy4uLiBidXQgZ2V0RmlsdGVyKCkgaXMgcGFydCBvZiB0aGUgRE9NJ3MKLSAgICogRFRNSXRlcmF0b3IgaW50ZXJmYWNlLCBzbyB3ZSBoYXZlIHRvIHN1cHBvcnQgaXQuCi0gICAqCi0gICAqIEByZXR1cm4gbnVsbCwgd2hpY2ggaXMgc2xpZ2h0bHkgbWlzbGVhZGluZy4gVHJ1ZSwgdGhlcmUgaXMgbm8KLSAgICogdXNlci13cml0dGVuIGZpbHRlciBvYmplY3QsIGJ1dCBpbiBmYWN0IHdlIGFyZSBkb2luZyBzb21lIHZlcnkKLSAgICogc29waGlzdGljYXRlZCBjdXN0b20gZmlsdGVyaW5nLiBBIERPTSBwdXJpc3QgbWlnaHQgc3VnZ2VzdAotICAgKiByZXR1cm5pbmcgYSBwbGFjZWhvbGRlciBvYmplY3QganVzdCB0byBpbmRpY2F0ZSB0aGF0IHRoaXMgaXMKLSAgICogbm90IGdvaW5nIHRvIHJldHVybiBhbGwgbm9kZXMgc2VsZWN0ZWQgYnkgd2hhdFRvU2hvdy4KLSAgICovCi0gIHB1YmxpYyBEVE1GaWx0ZXIgZ2V0RmlsdGVyKCkKLSAgewotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqICBUaGUgdmFsdWUgb2YgdGhpcyBmbGFnIGRldGVybWluZXMgd2hldGhlciB0aGUgY2hpbGRyZW4gb2YgZW50aXR5Ci0gICAqIHJlZmVyZW5jZSBub2RlcyBhcmUgdmlzaWJsZSB0byB0aGUgaXRlcmF0b3IuIElmIGZhbHNlLCB0aGV5IHdpbGwgYmUKLSAgICogc2tpcHBlZCBvdmVyLgotICAgKiA8YnI+IFRvIHByb2R1Y2UgYSB2aWV3IG9mIHRoZSBkb2N1bWVudCB0aGF0IGhhcyBlbnRpdHkgcmVmZXJlbmNlcwotICAgKiBleHBhbmRlZCBhbmQgZG9lcyBub3QgZXhwb3NlIHRoZSBlbnRpdHkgcmVmZXJlbmNlIG5vZGUgaXRzZWxmLCB1c2UgdGhlCi0gICAqIHdoYXRUb1Nob3cgZmxhZ3MgdG8gaGlkZSB0aGUgZW50aXR5IHJlZmVyZW5jZSBub2RlIGFuZCBzZXQKLSAgICogZXhwYW5kRW50aXR5UmVmZXJlbmNlcyB0byB0cnVlIHdoZW4gY3JlYXRpbmcgdGhlIGl0ZXJhdG9yLiBUbyBwcm9kdWNlCi0gICAqIGEgdmlldyBvZiB0aGUgZG9jdW1lbnQgdGhhdCBoYXMgZW50aXR5IHJlZmVyZW5jZSBub2RlcyBidXQgbm8gZW50aXR5Ci0gICAqIGV4cGFuc2lvbiwgdXNlIHRoZSB3aGF0VG9TaG93IGZsYWdzIHRvIHNob3cgdGhlIGVudGl0eSByZWZlcmVuY2Ugbm9kZQotICAgKiBhbmQgc2V0IGV4cGFuZEVudGl0eVJlZmVyZW5jZXMgdG8gZmFsc2UuCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBmb3IgYWxsIGl0ZXJhdG9ycyBiYXNlZCBvbiBOb2RlU2V0RFRNLCBtZWFuaW5nIHRoYXQgdGhlCi0gICAqIGNvbnRlbnRzIG9mIEVudGl0eVJlZnJlbmNlIG5vZGVzIG1heSBiZSByZXR1cm5lZCAodGhvdWdoIHdoYXRUb1Nob3cKLSAgICogc2F5cyB0aGF0IHRoZSBFbnRpdHlSZWZlcmVuY2VzIHRoZW1zZWx2ZXMgYXJlIG5vdCBzaG93bi4pCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBnZXRFeHBhbmRFbnRpdHlSZWZlcmVuY2VzKCkKLSAgewotICAgIHJldHVybiB0cnVlOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBhbiBpbnN0YW5jZSBvZiBhIERUTSB0aGF0ICJvd25zIiBhIG5vZGUgaGFuZGxlLiAgU2luY2UgYSBub2RlCi0gICAqIGl0ZXJhdG9yIG1heSBiZSBwYXNzZWQgd2l0aG91dCBhIERUTU1hbmFnZXIsIHRoaXMgYWxsb3dzIHRoZQotICAgKiBjYWxsZXIgdG8gZWFzaWx5IGdldCB0aGUgRFRNIHVzaW5nIGp1c3QgdGhlIGl0ZXJhdG9yLgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSB0aGUgbm9kZUhhbmRsZS4KLSAgICoKLSAgICogQHJldHVybiBhIG5vbi1udWxsIERUTSByZWZlcmVuY2UuCi0gICAqLwotICBwdWJsaWMgRFRNIGdldERUTShpbnQgbm9kZUhhbmRsZSkKLSAgewotCi0gICAgcmV0dXJuIG1fbWFuYWdlci5nZXREVE0obm9kZUhhbmRsZSk7Ci0gIH0KLQotICAvKiBBbiBpbnN0YW5jZSBvZiB0aGUgRFRNTWFuYWdlci4gKi8KLSAgRFRNTWFuYWdlciBtX21hbmFnZXI7Ci0KLSAgLyoqCi0gICAqIEdldCBhbiBpbnN0YW5jZSBvZiB0aGUgRFRNTWFuYWdlci4gIFNpbmNlIGEgbm9kZQotICAgKiBpdGVyYXRvciBtYXkgYmUgcGFzc2VkIHdpdGhvdXQgYSBEVE1NYW5hZ2VyLCB0aGlzIGFsbG93cyB0aGUKLSAgICogY2FsbGVyIHRvIGVhc2lseSBnZXQgdGhlIERUTU1hbmFnZXIgdXNpbmcganVzdCB0aGUgaXRlcmF0b3IuCi0gICAqCi0gICAqIEByZXR1cm4gYSBub24tbnVsbCBEVE1NYW5hZ2VyIHJlZmVyZW5jZS4KLSAgICovCi0gIHB1YmxpYyBEVE1NYW5hZ2VyIGdldERUTU1hbmFnZXIoKQotICB7Ci0KLSAgICByZXR1cm4gbV9tYW5hZ2VyOwotICB9Ci0KLSAgLyoqCi0gICAqICBSZXR1cm5zIHRoZSBuZXh0IG5vZGUgaW4gdGhlIHNldCBhbmQgYWR2YW5jZXMgdGhlIHBvc2l0aW9uIG9mIHRoZQotICAgKiBpdGVyYXRvciBpbiB0aGUgc2V0LiBBZnRlciBhIERUTUl0ZXJhdG9yIGlzIGNyZWF0ZWQsIHRoZSBmaXJzdCBjYWxsCi0gICAqIHRvIG5leHROb2RlKCkgcmV0dXJucyB0aGUgZmlyc3Qgbm9kZSBpbiB0aGUgc2V0LgotICAgKiBAcmV0dXJuICBUaGUgbmV4dCA8Y29kZT5Ob2RlPC9jb2RlPiBpbiB0aGUgc2V0IGJlaW5nIGl0ZXJhdGVkIG92ZXIsIG9yCi0gICAqICAgPGNvZGU+RFRNLk5VTEw8L2NvZGU+IGlmIHRoZXJlIGFyZSBubyBtb3JlIG1lbWJlcnMgaW4gdGhhdCBzZXQuCi0gICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gICAqICAgIElOVkFMSURfU1RBVEVfRVJSOiBSYWlzZWQgaWYgdGhpcyBtZXRob2QgaXMgY2FsbGVkIGFmdGVyIHRoZQotICAgKiAgIDxjb2RlPmRldGFjaDwvY29kZT4gbWV0aG9kIHdhcyBpbnZva2VkLgotICAgKi8KLSAgcHVibGljIGludCBuZXh0Tm9kZSgpCi0gIHsKLQotICAgIGlmICgobV9uZXh0KSA8IHRoaXMuc2l6ZSgpKQotICAgIHsKLSAgICAgIGludCBuZXh0ID0gdGhpcy5lbGVtZW50QXQobV9uZXh0KTsKLQotICAgICAgbV9uZXh0Kys7Ci0KLSAgICAgIHJldHVybiBuZXh0OwotICAgIH0KLSAgICBlbHNlCi0gICAgICByZXR1cm4gRFRNLk5VTEw7Ci0gIH0KLQotICAvKioKLSAgICogIFJldHVybnMgdGhlIHByZXZpb3VzIG5vZGUgaW4gdGhlIHNldCBhbmQgbW92ZXMgdGhlIHBvc2l0aW9uIG9mIHRoZQotICAgKiBpdGVyYXRvciBiYWNrd2FyZHMgaW4gdGhlIHNldC4KLSAgICogQHJldHVybiAgVGhlIHByZXZpb3VzIDxjb2RlPk5vZGU8L2NvZGU+IGluIHRoZSBzZXQgYmVpbmcgaXRlcmF0ZWQgb3ZlciwKLSAgICogICBvcjxjb2RlPkRUTS5OVUxMPC9jb2RlPiBpZiB0aGVyZSBhcmUgbm8gbW9yZSBtZW1iZXJzIGluIHRoYXQgc2V0LgotICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgKiAgICBJTlZBTElEX1NUQVRFX0VSUjogUmFpc2VkIGlmIHRoaXMgbWV0aG9kIGlzIGNhbGxlZCBhZnRlciB0aGUKLSAgICogICA8Y29kZT5kZXRhY2g8L2NvZGU+IG1ldGhvZCB3YXMgaW52b2tlZC4KLSAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIHRocm93biBpZiB0aGlzIE5vZGVTZXREVE0gaXMgbm90IG9mCi0gICAqIGEgY2FjaGVkIHR5cGUsIGFuZCBoZW5jZSBkb2Vzbid0IGtub3cgd2hhdCB0aGUgcHJldmlvdXMgbm9kZSB3YXMuCi0gICAqLwotICBwdWJsaWMgaW50IHByZXZpb3VzTm9kZSgpCi0gIHsKLQotICAgIGlmICghbV9jYWNoZU5vZGVzKQotICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCi0gICAgICAgIFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShYUEFUSEVycm9yUmVzb3VyY2VzLkVSX05PREVTRVREVE1fQ0FOTk9UX0lURVJBVEUsIG51bGwpKTsgLy8iVGhpcyBOb2RlU2V0RFRNIGNhbiBub3QgaXRlcmF0ZSB0byBhIHByZXZpb3VzIG5vZGUhIik7Ci0KLSAgICBpZiAoKG1fbmV4dCAtIDEpID4gMCkKLSAgICB7Ci0gICAgICBtX25leHQtLTsKLQotICAgICAgcmV0dXJuIHRoaXMuZWxlbWVudEF0KG1fbmV4dCk7Ci0gICAgfQotICAgIGVsc2UKLSAgICAgIHJldHVybiBEVE0uTlVMTDsKLSAgfQotCi0gIC8qKgotICAgKiBEZXRhY2hlcyB0aGUgaXRlcmF0b3IgZnJvbSB0aGUgc2V0IHdoaWNoIGl0IGl0ZXJhdGVkIG92ZXIsIHJlbGVhc2luZwotICAgKiBhbnkgY29tcHV0YXRpb25hbCByZXNvdXJjZXMgYW5kIHBsYWNpbmcgdGhlIGl0ZXJhdG9yIGluIHRoZSBJTlZBTElECi0gICAqIHN0YXRlLiBBZnRlcjxjb2RlPmRldGFjaDwvY29kZT4gaGFzIGJlZW4gaW52b2tlZCwgY2FsbHMgdG8KLSAgICogPGNvZGU+bmV4dE5vZGU8L2NvZGU+IG9yPGNvZGU+cHJldmlvdXNOb2RlPC9jb2RlPiB3aWxsIHJhaXNlIHRoZQotICAgKiBleGNlcHRpb24gSU5WQUxJRF9TVEFURV9FUlIuCi0gICAqIDxwPgotICAgKiBUaGlzIG9wZXJhdGlvbiBpcyBhIG5vLW9wIGluIE5vZGVTZXREVE0sIGFuZCB3aWxsIG5vdCBjYXVzZQotICAgKiBJTlZBTElEX1NUQVRFX0VSUiB0byBiZSByYWlzZWQgYnkgbGF0ZXIgb3BlcmF0aW9ucy4KLSAgICogPC9wPgotICAgKi8KLSAgcHVibGljIHZvaWQgZGV0YWNoKCl7fQotCi0gIC8qKgotICAgKiBTcGVjaWZ5IGlmIGl0J3MgT0sgZm9yIGRldGFjaCB0byByZWxlYXNlIHRoZSBpdGVyYXRvciBmb3IgcmV1c2UuCi0gICAqCi0gICAqIEBwYXJhbSBhbGxvd1JlbGVhc2UgdHJ1ZSBpZiBpdCBpcyBPSyBmb3IgZGV0YWNoIHRvIHJlbGVhc2UgdGhpcyBpdGVyYXRvcgotICAgKiBmb3IgcG9vbGluZy4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGFsbG93RGV0YWNoVG9SZWxlYXNlKGJvb2xlYW4gYWxsb3dSZWxlYXNlKQotICB7Ci0gICAgLy8gbm8gYWN0aW9uIGZvciByaWdodCBub3cuCi0gIH0KLQotCi0gIC8qKgotICAgKiBUZWxscyBpZiB0aGlzIE5vZGVTZXREVE0gaXMgImZyZXNoIiwgaW4gb3RoZXIgd29yZHMsIGlmCi0gICAqIHRoZSBmaXJzdCBuZXh0Tm9kZSgpIHRoYXQgaXMgY2FsbGVkIHdpbGwgcmV0dXJuIHRoZQotICAgKiBmaXJzdCBub2RlIGluIHRoZSBzZXQuCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiBuZXh0Tm9kZSgpIHdvdWxkIHJldHVybiB0aGUgZmlyc3Qgbm9kZSBpbiB0aGUgc2V0LAotICAgKiBmYWxzZSBpZiBpdCB3b3VsZCByZXR1cm4gYSBsYXRlciBvbmUuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBpc0ZyZXNoKCkKLSAgewotICAgIHJldHVybiAobV9uZXh0ID09IDApOwotICB9Ci0KLSAgLyoqCi0gICAqIElmIGFuIGluZGV4IGlzIHJlcXVlc3RlZCwgTm9kZVNldERUTSB3aWxsIGNhbGwgdGhpcyBtZXRob2QKLSAgICogdG8gcnVuIHRoZSBpdGVyYXRvciB0byB0aGUgaW5kZXguICBCeSBkZWZhdWx0IHRoaXMgc2V0cwotICAgKiBtX25leHQgdG8gdGhlIGluZGV4LiAgSWYgdGhlIGluZGV4IGFyZ3VtZW50IGlzIC0xLCB0aGlzCi0gICAqIHNpZ25hbHMgdGhhdCB0aGUgaXRlcmF0b3Igc2hvdWxkIGJlIHJ1biB0byB0aGUgZW5kLgotICAgKgotICAgKiBAcGFyYW0gaW5kZXggUG9zaXRpb24gdG8gYWR2YW5jZSAob3IgcmV0cmVhdCkgdG8sIHdpdGgKLSAgICogMCByZXF1ZXN0aW5nIHRoZSByZXNldCAoImZyZXNoIikgcG9zaXRpb24gYW5kIC0xIChvciBpbmRlZWQKLSAgICogYW55IG91dC1vZi1ib3VuZHMgdmFsdWUpIHJlcXVlc3RpbmcgdGhlIGZpbmFsIHBvc2l0aW9uLgotICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gdGhyb3duIGlmIHRoaXMgTm9kZVNldERUTSBpcyBub3QKLSAgICogb25lIG9mIHRoZSB0eXBlcyB3aGljaCBzdXBwb3J0cyBpbmRleGluZy9jb3VudGluZy4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHJ1blRvKGludCBpbmRleCkKLSAgewotCi0gICAgaWYgKCFtX2NhY2hlTm9kZXMpCi0gICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKLSAgICAgICAgWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfTk9ERVNFVERUTV9DQU5OT1RfSU5ERVgsIG51bGwpKTsgLy8iVGhpcyBOb2RlU2V0RFRNIGNhbiBub3QgZG8gaW5kZXhpbmcgb3IgY291bnRpbmcgZnVuY3Rpb25zISIpOwotCi0gICAgaWYgKChpbmRleCA+PSAwKSAmJiAobV9uZXh0IDwgbV9maXJzdEZyZWUpKQotICAgICAgbV9uZXh0ID0gaW5kZXg7Ci0gICAgZWxzZQotICAgICAgbV9uZXh0ID0gbV9maXJzdEZyZWUgLSAxOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIDxjb2RlPmluZGV4PC9jb2RlPnRoIGl0ZW0gaW4gdGhlIGNvbGxlY3Rpb24uIElmCi0gICAqIDxjb2RlPmluZGV4PC9jb2RlPiBpcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gdGhlIG51bWJlciBvZiBub2RlcyBpbgotICAgKiB0aGUgbGlzdCwgdGhpcyByZXR1cm5zIDxjb2RlPm51bGw8L2NvZGU+LgotICAgKgotICAgKiBUT0RPOiBXaGF0IGhhcHBlbnMgaWYgaW5kZXggaXMgb3V0IG9mIHJhbmdlPwotICAgKgotICAgKiBAcGFyYW0gaW5kZXggSW5kZXggaW50byB0aGUgY29sbGVjdGlvbi4KLSAgICogQHJldHVybiBUaGUgbm9kZSBhdCB0aGUgPGNvZGU+aW5kZXg8L2NvZGU+dGggcG9zaXRpb24gaW4gdGhlCi0gICAqICAgPGNvZGU+Tm9kZUxpc3Q8L2NvZGU+LCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGF0IGlzIG5vdCBhIHZhbGlkCi0gICAqICAgaW5kZXguCi0gICAqLwotICBwdWJsaWMgaW50IGl0ZW0oaW50IGluZGV4KQotICB7Ci0KLSAgICBydW5UbyhpbmRleCk7Ci0KLSAgICByZXR1cm4gdGhpcy5lbGVtZW50QXQoaW5kZXgpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoZSBudW1iZXIgb2Ygbm9kZXMgaW4gdGhlIGxpc3QuIFRoZSByYW5nZSBvZiB2YWxpZCBjaGlsZCBub2RlIGluZGljZXMgaXMKLSAgICogMCB0byA8Y29kZT5sZW5ndGgtMTwvY29kZT4gaW5jbHVzaXZlLiBOb3RlIHRoYXQgdGhpcyBvcGVyYXRpb24gcmVxdWlyZXMKLSAgICogZmluZGluZyBhbGwgdGhlIG1hdGNoaW5nIG5vZGVzLCB3aGljaCBtYXkgZGVmZWF0IGF0dGVtcHRzIHRvIGRlZmVyCi0gICAqIHRoYXQgd29yay4KLSAgICoKLSAgICogQHJldHVybiBpbnRlZ2VyIGluZGljYXRpbmcgaG93IG1hbnkgbm9kZXMgYXJlIHJlcHJlc2VudGVkIGJ5IHRoaXMgbGlzdC4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0TGVuZ3RoKCkKLSAgewotCi0gICAgcnVuVG8oLTEpOwotCi0gICAgcmV0dXJuIHRoaXMuc2l6ZSgpOwotICB9Ci0KLSAgLyoqCi0gICAqIEFkZCBhIG5vZGUgdG8gdGhlIE5vZGVTZXREVE0uIE5vdCBhbGwgdHlwZXMgb2YgTm9kZVNldERUTXMgc3VwcG9ydCB0aGlzCi0gICAqIG9wZXJhdGlvbgotICAgKgotICAgKiBAcGFyYW0gbiBOb2RlIHRvIGJlIGFkZGVkCi0gICAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiB0aHJvd24gaWYgdGhpcyBOb2RlU2V0RFRNIGlzIG5vdCBvZgotICAgKiBhIG11dGFibGUgdHlwZS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGFkZE5vZGUoaW50IG4pCi0gIHsKLQotICAgIGlmICghbV9tdXRhYmxlKQotICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfTk9ERVNFVERUTV9OT1RfTVVUQUJMRSwgbnVsbCkpOyAvLyJUaGlzIE5vZGVTZXREVE0gaXMgbm90IG11dGFibGUhIik7Ci0KLSAgICB0aGlzLmFkZEVsZW1lbnQobik7Ci0gIH0KLQotICAvKioKLSAgICogSW5zZXJ0IGEgbm9kZSBhdCBhIGdpdmVuIHBvc2l0aW9uLgotICAgKgotICAgKiBAcGFyYW0gbiBOb2RlIHRvIGJlIGFkZGVkCi0gICAqIEBwYXJhbSBwb3MgT2Zmc2V0IGF0IHdoaWNoIHRoZSBub2RlIGlzIHRvIGJlIGluc2VydGVkLAotICAgKiB3aXRoIDAgYmVpbmcgdGhlIGZpcnN0IHBvc2l0aW9uLgotICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gdGhyb3duIGlmIHRoaXMgTm9kZVNldERUTSBpcyBub3Qgb2YKLSAgICogYSBtdXRhYmxlIHR5cGUuCi0gICAqLwotICBwdWJsaWMgdm9pZCBpbnNlcnROb2RlKGludCBuLCBpbnQgcG9zKQotICB7Ci0KLSAgICBpZiAoIW1fbXV0YWJsZSkKLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShYUEFUSEVycm9yUmVzb3VyY2VzLkVSX05PREVTRVREVE1fTk9UX01VVEFCTEUsIG51bGwpKTsgLy8iVGhpcyBOb2RlU2V0RFRNIGlzIG5vdCBtdXRhYmxlISIpOwotCi0gICAgaW5zZXJ0RWxlbWVudEF0KG4sIHBvcyk7Ci0gIH0KLQotICAvKioKLSAgICogUmVtb3ZlIGEgbm9kZS4KLSAgICoKLSAgICogQHBhcmFtIG4gTm9kZSB0byBiZSBhZGRlZAotICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gdGhyb3duIGlmIHRoaXMgTm9kZVNldERUTSBpcyBub3Qgb2YKLSAgICogYSBtdXRhYmxlIHR5cGUuCi0gICAqLwotICBwdWJsaWMgdm9pZCByZW1vdmVOb2RlKGludCBuKQotICB7Ci0KLSAgICBpZiAoIW1fbXV0YWJsZSkKLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShYUEFUSEVycm9yUmVzb3VyY2VzLkVSX05PREVTRVREVE1fTk9UX01VVEFCTEUsIG51bGwpKTsgLy8iVGhpcyBOb2RlU2V0RFRNIGlzIG5vdCBtdXRhYmxlISIpOwotCi0gICAgdGhpcy5yZW1vdmVFbGVtZW50KG4pOwotICB9Ci0KLSAgLy8gJVRCRCUKLS8vICAvKioKLS8vICAgKiBDb3B5IE5vZGVMaXN0IG1lbWJlcnMgaW50byB0aGlzIG5vZGVsaXN0LCBhZGRpbmcgaW4KLS8vICAgKiBkb2N1bWVudCBvcmRlci4gIElmIGEgbm9kZSBpcyBudWxsLCBkb24ndCBhZGQgaXQuCi0vLyAgICoKLS8vICAgKiBAcGFyYW0gbm9kZWxpc3QgTGlzdCBvZiBub2RlcyB3aGljaCBzaG91bGQgbm93IGJlIHJlZmVyZW5jZWQgYnkKLS8vICAgKiB0aGlzIE5vZGVTZXREVE0uCi0vLyAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIHRocm93biBpZiB0aGlzIE5vZGVTZXREVE0gaXMgbm90IG9mCi0vLyAgICogYSBtdXRhYmxlIHR5cGUuCi0vLyAgICovCi0vLyAgcHVibGljIHZvaWQgYWRkTm9kZXMoTm9kZUxpc3Qgbm9kZWxpc3QpCi0vLyAgewotLy8KLS8vICAgIGlmICghbV9tdXRhYmxlKQotLy8gICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVGhpcyBOb2RlU2V0RFRNIGlzIG5vdCBtdXRhYmxlISIpOwotLy8KLS8vICAgIGlmIChudWxsICE9IG5vZGVsaXN0KSAgLy8gZGVmZW5zaXZlIHRvIGZpeCBhIGJ1ZyB0aGF0IFNhbmppdmEgcmVwb3J0ZWQuCi0vLyAgICB7Ci0vLyAgICAgIGludCBuQ2hpbGRyZW4gPSBub2RlbGlzdC5nZXRMZW5ndGgoKTsKLS8vCi0vLyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbkNoaWxkcmVuOyBpKyspCi0vLyAgICAgIHsKLS8vICAgICAgICBpbnQgb2JqID0gbm9kZWxpc3QuaXRlbShpKTsKLS8vCi0vLyAgICAgICAgaWYgKG51bGwgIT0gb2JqKQotLy8gICAgICAgIHsKLS8vICAgICAgICAgIGFkZEVsZW1lbnQob2JqKTsKLS8vICAgICAgICB9Ci0vLyAgICAgIH0KLS8vICAgIH0KLS8vCi0vLyAgICAvLyBjaGVja0R1cHMoKTsKLS8vICB9Ci0KLSAgLy8gJVRCRCUKLS8vICAvKioKLS8vICAgKiA8cD5Db3B5IE5vZGVMaXN0IG1lbWJlcnMgaW50byB0aGlzIG5vZGVsaXN0LCBhZGRpbmcgaW4KLS8vICAgKiBkb2N1bWVudCBvcmRlci4gIE9ubHkgZ2VudWluZSBub2RlIHJlZmVyZW5jZXMgd2lsbCBiZSBjb3BpZWQ7Ci0vLyAgICogbnVsbHMgYXBwZWFyaW5nIGluIHRoZSBzb3VyY2UgTm9kZVNldERUTSB3aWxsCi0vLyAgICogbm90IGJlIGFkZGVkIHRvIHRoaXMgb25lLiA8L3A+Ci0vLyAgICoKLS8vICAgKiA8cD4gSW4gY2FzZSB5b3UncmUgd29uZGVyaW5nIHdoeSB0aGlzIGZ1bmN0aW9uIGlzIG5lZWRlZDogTm9kZVNldERUTQotLy8gICAqIGltcGxlbWVudHMgYm90aCBEVE1JdGVyYXRvciBhbmQgTm9kZUxpc3QuIElmIHRoaXMgbWV0aG9kIGlzbid0Ci0vLyAgICogcHJvdmlkZWQsIEphdmEgY2FuJ3QgZGVjaWRlIHdoaWNoIG9mIHRob3NlIHRvIHVzZSB3aGVuIGFkZE5vZGVzKCkKLS8vICAgKiBpcyBpbnZva2VkLiBQcm92aWRpbmcgdGhlIG1vcmUtZXhwbGljaXQgbWF0Y2ggYXZvaWRzIHRoYXQKLS8vICAgKiBhbWJpZ3VpdHkuKTwvcD4KLS8vICAgKgotLy8gICAqIEBwYXJhbSBucyBOb2RlU2V0RFRNIHdob3NlIG1lbWJlcnMgc2hvdWxkIGJlIG1lcmdlZCBpbnRvIHRoaXMgTm9kZVNldERUTS4KLS8vICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gdGhyb3duIGlmIHRoaXMgTm9kZVNldERUTSBpcyBub3Qgb2YKLS8vICAgKiBhIG11dGFibGUgdHlwZS4KLS8vICAgKi8KLS8vICBwdWJsaWMgdm9pZCBhZGROb2RlcyhOb2RlU2V0RFRNIG5zKQotLy8gIHsKLS8vCi0vLyAgICBpZiAoIW1fbXV0YWJsZSkKLS8vICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlRoaXMgTm9kZVNldERUTSBpcyBub3QgbXV0YWJsZSEiKTsKLS8vCi0vLyAgICBhZGROb2RlcygoRFRNSXRlcmF0b3IpIG5zKTsKLS8vICB9Ci0KLSAgLyoqCi0gICAqIENvcHkgTm9kZUxpc3QgbWVtYmVycyBpbnRvIHRoaXMgbm9kZWxpc3QsIGFkZGluZyBpbgotICAgKiBkb2N1bWVudCBvcmRlci4gIE51bGwgcmVmZXJlbmNlcyBhcmUgbm90IGFkZGVkLgotICAgKgotICAgKiBAcGFyYW0gaXRlcmF0b3IgRFRNSXRlcmF0b3Igd2hpY2ggeWllbGRzIHRoZSBub2RlcyB0byBiZSBhZGRlZC4KLSAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIHRocm93biBpZiB0aGlzIE5vZGVTZXREVE0gaXMgbm90IG9mCi0gICAqIGEgbXV0YWJsZSB0eXBlLgotICAgKi8KLSAgcHVibGljIHZvaWQgYWRkTm9kZXMoRFRNSXRlcmF0b3IgaXRlcmF0b3IpCi0gIHsKLQotICAgIGlmICghbV9tdXRhYmxlKQotICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfTk9ERVNFVERUTV9OT1RfTVVUQUJMRSwgbnVsbCkpOyAvLyJUaGlzIE5vZGVTZXREVE0gaXMgbm90IG11dGFibGUhIik7Ci0KLSAgICBpZiAobnVsbCAhPSBpdGVyYXRvcikgIC8vIGRlZmVuc2l2ZSB0byBmaXggYSBidWcgdGhhdCBTYW5qaXZhIHJlcG9ydGVkLgotICAgIHsKLSAgICAgIGludCBvYmo7Ci0KLSAgICAgIHdoaWxlIChEVE0uTlVMTCAhPSAob2JqID0gaXRlcmF0b3IubmV4dE5vZGUoKSkpCi0gICAgICB7Ci0gICAgICAgIGFkZEVsZW1lbnQob2JqKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICAvLyBjaGVja0R1cHMoKTsKLSAgfQotCi0gIC8vICVUQkQlCi0vLyAgLyoqCi0vLyAgICogQ29weSBOb2RlTGlzdCBtZW1iZXJzIGludG8gdGhpcyBub2RlbGlzdCwgYWRkaW5nIGluCi0vLyAgICogZG9jdW1lbnQgb3JkZXIuICBJZiBhIG5vZGUgaXMgbnVsbCwgZG9uJ3QgYWRkIGl0LgotLy8gICAqCi0vLyAgICogQHBhcmFtIG5vZGVsaXN0IExpc3Qgb2Ygbm9kZXMgdG8gYmUgYWRkZWQKLS8vICAgKiBAcGFyYW0gc3VwcG9ydCBUaGUgWFBhdGggcnVudGltZSBjb250ZXh0LgotLy8gICAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiB0aHJvd24gaWYgdGhpcyBOb2RlU2V0RFRNIGlzIG5vdCBvZgotLy8gICAqIGEgbXV0YWJsZSB0eXBlLgotLy8gICAqLwotLy8gIHB1YmxpYyB2b2lkIGFkZE5vZGVzSW5Eb2NPcmRlcihOb2RlTGlzdCBub2RlbGlzdCwgWFBhdGhDb250ZXh0IHN1cHBvcnQpCi0vLyAgewotLy8KLS8vICAgIGlmICghbV9tdXRhYmxlKQotLy8gICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVGhpcyBOb2RlU2V0RFRNIGlzIG5vdCBtdXRhYmxlISIpOwotLy8KLS8vICAgIGludCBuQ2hpbGRyZW4gPSBub2RlbGlzdC5nZXRMZW5ndGgoKTsKLS8vCi0vLyAgICBmb3IgKGludCBpID0gMDsgaSA8IG5DaGlsZHJlbjsgaSsrKQotLy8gICAgewotLy8gICAgICBpbnQgbm9kZSA9IG5vZGVsaXN0Lml0ZW0oaSk7Ci0vLwotLy8gICAgICBpZiAobnVsbCAhPSBub2RlKQotLy8gICAgICB7Ci0vLyAgICAgICAgYWRkTm9kZUluRG9jT3JkZXIobm9kZSwgc3VwcG9ydCk7Ci0vLyAgICAgIH0KLS8vICAgIH0KLS8vICB9Ci0KLSAgLyoqCi0gICAqIENvcHkgTm9kZUxpc3QgbWVtYmVycyBpbnRvIHRoaXMgbm9kZWxpc3QsIGFkZGluZyBpbgotICAgKiBkb2N1bWVudCBvcmRlci4gIElmIGEgbm9kZSBpcyBudWxsLCBkb24ndCBhZGQgaXQuCi0gICAqCi0gICAqIEBwYXJhbSBpdGVyYXRvciBEVE1JdGVyYXRvciB3aGljaCB5aWVsZHMgdGhlIG5vZGVzIHRvIGJlIGFkZGVkLgotICAgKiBAcGFyYW0gc3VwcG9ydCBUaGUgWFBhdGggcnVudGltZSBjb250ZXh0LgotICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gdGhyb3duIGlmIHRoaXMgTm9kZVNldERUTSBpcyBub3Qgb2YKLSAgICogYSBtdXRhYmxlIHR5cGUuCi0gICAqLwotICBwdWJsaWMgdm9pZCBhZGROb2Rlc0luRG9jT3JkZXIoRFRNSXRlcmF0b3IgaXRlcmF0b3IsIFhQYXRoQ29udGV4dCBzdXBwb3J0KQotICB7Ci0KLSAgICBpZiAoIW1fbXV0YWJsZSkKLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShYUEFUSEVycm9yUmVzb3VyY2VzLkVSX05PREVTRVREVE1fTk9UX01VVEFCTEUsIG51bGwpKTsgLy8iVGhpcyBOb2RlU2V0RFRNIGlzIG5vdCBtdXRhYmxlISIpOwotCi0gICAgaW50IG5vZGU7Ci0KLSAgICB3aGlsZSAoRFRNLk5VTEwgIT0gKG5vZGUgPSBpdGVyYXRvci5uZXh0Tm9kZSgpKSkKLSAgICB7Ci0gICAgICBhZGROb2RlSW5Eb2NPcmRlcihub2RlLCBzdXBwb3J0KTsKLSAgICB9Ci0gIH0KLQotICAvLyAlVEJEJQotLy8gIC8qKgotLy8gICAqIEFkZCB0aGUgbm9kZSBsaXN0IHRvIHRoaXMgbm9kZSBzZXQgaW4gZG9jdW1lbnQgb3JkZXIuCi0vLyAgICoKLS8vICAgKiBAcGFyYW0gc3RhcnQgaW5kZXguCi0vLyAgICogQHBhcmFtIGVuZCBpbmRleC4KLS8vICAgKiBAcGFyYW0gdGVzdEluZGV4IGluZGV4LgotLy8gICAqIEBwYXJhbSBub2RlbGlzdCBUaGUgbm9kZWxpc3QgdG8gYWRkLgotLy8gICAqIEBwYXJhbSBzdXBwb3J0IFRoZSBYUGF0aCBydW50aW1lIGNvbnRleHQuCi0vLyAgICoKLS8vICAgKiBAcmV0dXJuIGZhbHNlIGFsd2F5cy4KLS8vICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gdGhyb3duIGlmIHRoaXMgTm9kZVNldERUTSBpcyBub3Qgb2YKLS8vICAgKiBhIG11dGFibGUgdHlwZS4KLS8vICAgKi8KLS8vICBwcml2YXRlIGJvb2xlYW4gYWRkTm9kZXNJbkRvY09yZGVyKGludCBzdGFydCwgaW50IGVuZCwgaW50IHRlc3RJbmRleCwKLS8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5vZGVMaXN0IG5vZGVsaXN0LCBYUGF0aENvbnRleHQgc3VwcG9ydCkKLS8vICB7Ci0vLwotLy8gICAgaWYgKCFtX211dGFibGUpCi0vLyAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJUaGlzIE5vZGVTZXREVE0gaXMgbm90IG11dGFibGUhIik7Ci0vLwotLy8gICAgYm9vbGVhbiBmb3VuZGl0ID0gZmFsc2U7Ci0vLyAgICBpbnQgaTsKLS8vICAgIGludCBub2RlID0gbm9kZWxpc3QuaXRlbSh0ZXN0SW5kZXgpOwotLy8KLS8vICAgIGZvciAoaSA9IGVuZDsgaSA+PSBzdGFydDsgaS0tKQotLy8gICAgewotLy8gICAgICBpbnQgY2hpbGQgPSBlbGVtZW50QXQoaSk7Ci0vLwotLy8gICAgICBpZiAoY2hpbGQgPT0gbm9kZSkKLS8vICAgICAgewotLy8gICAgICAgIGkgPSAtMjsgIC8vIER1cGxpY2F0ZSwgc3VwcHJlc3MgaW5zZXJ0Ci0vLwotLy8gICAgICAgIGJyZWFrOwotLy8gICAgICB9Ci0vLwotLy8gICAgICBpZiAoIXN1cHBvcnQuZ2V0RE9NSGVscGVyKCkuaXNOb2RlQWZ0ZXIobm9kZSwgY2hpbGQpKQotLy8gICAgICB7Ci0vLyAgICAgICAgaW5zZXJ0RWxlbWVudEF0KG5vZGUsIGkgKyAxKTsKLS8vCi0vLyAgICAgICAgdGVzdEluZGV4LS07Ci0vLwotLy8gICAgICAgIGlmICh0ZXN0SW5kZXggPiAwKQotLy8gICAgICAgIHsKLS8vICAgICAgICAgIGJvb2xlYW4gZm91bmRQcmV2ID0gYWRkTm9kZXNJbkRvY09yZGVyKDAsIGksIHRlc3RJbmRleCwgbm9kZWxpc3QsCi0vLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdXBwb3J0KTsKLS8vCi0vLyAgICAgICAgICBpZiAoIWZvdW5kUHJldikKLS8vICAgICAgICAgIHsKLS8vICAgICAgICAgICAgYWRkTm9kZXNJbkRvY09yZGVyKGksIHNpemUoKSAtIDEsIHRlc3RJbmRleCwgbm9kZWxpc3QsIHN1cHBvcnQpOwotLy8gICAgICAgICAgfQotLy8gICAgICAgIH0KLS8vCi0vLyAgICAgICAgYnJlYWs7Ci0vLyAgICAgIH0KLS8vICAgIH0KLS8vCi0vLyAgICBpZiAoaSA9PSAtMSkKLS8vICAgIHsKLS8vICAgICAgaW5zZXJ0RWxlbWVudEF0KG5vZGUsIDApOwotLy8gICAgfQotLy8KLS8vICAgIHJldHVybiBmb3VuZGl0OwotLy8gIH0KLQotICAvKioKLSAgICogQWRkIHRoZSBub2RlIGludG8gYSB2ZWN0b3Igb2Ygbm9kZXMgd2hlcmUgaXQgc2hvdWxkIG9jY3VyIGluCi0gICAqIGRvY3VtZW50IG9yZGVyLgotICAgKiBAcGFyYW0gbm9kZSBUaGUgbm9kZSB0byBiZSBhZGRlZC4KLSAgICogQHBhcmFtIHRlc3QgdHJ1ZSBpZiB3ZSBzaG91bGQgdGVzdCBmb3IgZG9jIG9yZGVyCi0gICAqIEBwYXJhbSBzdXBwb3J0IFRoZSBYUGF0aCBydW50aW1lIGNvbnRleHQuCi0gICAqIEByZXR1cm4gaW5zZXJ0SW5kZXguCi0gICAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiB0aHJvd24gaWYgdGhpcyBOb2RlU2V0RFRNIGlzIG5vdCBvZgotICAgKiBhIG11dGFibGUgdHlwZS4KLSAgICovCi0gIHB1YmxpYyBpbnQgYWRkTm9kZUluRG9jT3JkZXIoaW50IG5vZGUsIGJvb2xlYW4gdGVzdCwgWFBhdGhDb250ZXh0IHN1cHBvcnQpCi0gIHsKLQotICAgIGlmICghbV9tdXRhYmxlKQotICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfTk9ERVNFVERUTV9OT1RfTVVUQUJMRSwgbnVsbCkpOyAvLyJUaGlzIE5vZGVTZXREVE0gaXMgbm90IG11dGFibGUhIik7Ci0KLSAgICBpbnQgaW5zZXJ0SW5kZXggPSAtMTsKLQotICAgIGlmICh0ZXN0KQotICAgIHsKLQotICAgICAgLy8gVGhpcyBuZWVkcyB0byBkbyBhIGJpbmFyeSBzZWFyY2gsIGJ1dCBhIGJpbmFyeSBzZWFyY2gKLSAgICAgIC8vIGlzIHNvbWV3aGF0IHRvdWdoIGJlY2F1c2UgdGhlIHNlcXVlbmNlIHRlc3QgaW52b2x2ZXMKLSAgICAgIC8vIHR3byBub2Rlcy4KLSAgICAgIGludCBzaXplID0gc2l6ZSgpLCBpOwotCi0gICAgICBmb3IgKGkgPSBzaXplIC0gMTsgaSA+PSAwOyBpLS0pCi0gICAgICB7Ci0gICAgICAgIGludCBjaGlsZCA9IGVsZW1lbnRBdChpKTsKLQotICAgICAgICBpZiAoY2hpbGQgPT0gbm9kZSkKLSAgICAgICAgewotICAgICAgICAgIGkgPSAtMjsgIC8vIER1cGxpY2F0ZSwgc3VwcHJlc3MgaW5zZXJ0Ci0KLSAgICAgICAgICBicmVhazsKLSAgICAgICAgfQotCi0gICAgICAgIERUTSBkdG0gPSBzdXBwb3J0LmdldERUTShub2RlKTsKLSAgICAgICAgaWYgKCFkdG0uaXNOb2RlQWZ0ZXIobm9kZSwgY2hpbGQpKQotICAgICAgICB7Ci0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIH0KLSAgICAgIH0KLQotICAgICAgaWYgKGkgIT0gLTIpCi0gICAgICB7Ci0gICAgICAgIGluc2VydEluZGV4ID0gaSArIDE7Ci0KLSAgICAgICAgaW5zZXJ0RWxlbWVudEF0KG5vZGUsIGluc2VydEluZGV4KTsKLSAgICAgIH0KLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIGluc2VydEluZGV4ID0gdGhpcy5zaXplKCk7Ci0KLSAgICAgIGJvb2xlYW4gZm91bmRpdCA9IGZhbHNlOwotCi0gICAgICBmb3IgKGludCBpID0gMDsgaSA8IGluc2VydEluZGV4OyBpKyspCi0gICAgICB7Ci0gICAgICAgIGlmIChpID09IG5vZGUpCi0gICAgICAgIHsKLSAgICAgICAgICBmb3VuZGl0ID0gdHJ1ZTsKLQotICAgICAgICAgIGJyZWFrOwotICAgICAgICB9Ci0gICAgICB9Ci0KLSAgICAgIGlmICghZm91bmRpdCkKLSAgICAgICAgYWRkRWxlbWVudChub2RlKTsKLSAgICB9Ci0KLSAgICAvLyBjaGVja0R1cHMoKTsKLSAgICByZXR1cm4gaW5zZXJ0SW5kZXg7Ci0gIH0gIC8vIGVuZCBhZGROb2RlSW5Eb2NPcmRlcihWZWN0b3IgdiwgT2JqZWN0IG9iaikKLQotICAvKioKLSAgICogQWRkIHRoZSBub2RlIGludG8gYSB2ZWN0b3Igb2Ygbm9kZXMgd2hlcmUgaXQgc2hvdWxkIG9jY3VyIGluCi0gICAqIGRvY3VtZW50IG9yZGVyLgotICAgKiBAcGFyYW0gbm9kZSBUaGUgbm9kZSB0byBiZSBhZGRlZC4KLSAgICogQHBhcmFtIHN1cHBvcnQgVGhlIFhQYXRoIHJ1bnRpbWUgY29udGV4dC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgaW5kZXggd2hlcmUgaXQgd2FzIGluc2VydGVkLgotICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gdGhyb3duIGlmIHRoaXMgTm9kZVNldERUTSBpcyBub3Qgb2YKLSAgICogYSBtdXRhYmxlIHR5cGUuCi0gICAqLwotICBwdWJsaWMgaW50IGFkZE5vZGVJbkRvY09yZGVyKGludCBub2RlLCBYUGF0aENvbnRleHQgc3VwcG9ydCkKLSAgewotCi0gICAgaWYgKCFtX211dGFibGUpCi0gICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoWFBBVEhFcnJvclJlc291cmNlcy5FUl9OT0RFU0VURFRNX05PVF9NVVRBQkxFLCBudWxsKSk7IC8vIlRoaXMgTm9kZVNldERUTSBpcyBub3QgbXV0YWJsZSEiKTsKLQotICAgIHJldHVybiBhZGROb2RlSW5Eb2NPcmRlcihub2RlLCB0cnVlLCBzdXBwb3J0KTsKLSAgfSAgLy8gZW5kIGFkZE5vZGVJbkRvY09yZGVyKFZlY3RvciB2LCBPYmplY3Qgb2JqKQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGxlbmd0aCBvZiB0aGUgbGlzdC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgc2l6ZSBvZiB0aGlzIG5vZGUgc2V0LgotICAgKi8KLSAgcHVibGljIGludCBzaXplKCkKLSAgewotICAgIHJldHVybiBzdXBlci5zaXplKCk7Ci0gIH0KLQotICAvKioKLSAgICogQXBwZW5kIGEgTm9kZSBvbnRvIHRoZSB2ZWN0b3IuCi0gICAqCi0gICAqIEBwYXJhbSB2YWx1ZSBUaGUgbm9kZSB0byBiZSBhZGRlZC4KLSAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIHRocm93biBpZiB0aGlzIE5vZGVTZXREVE0gaXMgbm90IG9mCi0gICAqIGEgbXV0YWJsZSB0eXBlLgotICAgKi8KLSAgcHVibGljIHZvaWQgYWRkRWxlbWVudChpbnQgdmFsdWUpCi0gIHsKLQotICAgIGlmICghbV9tdXRhYmxlKQotICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfTk9ERVNFVERUTV9OT1RfTVVUQUJMRSwgbnVsbCkpOyAvLyJUaGlzIE5vZGVTZXREVE0gaXMgbm90IG11dGFibGUhIik7Ci0KLSAgICBzdXBlci5hZGRFbGVtZW50KHZhbHVlKTsKLSAgfQotCi0gIC8qKgotICAgKiBJbnNlcnRzIHRoZSBzcGVjaWZpZWQgbm9kZSBpbiB0aGlzIHZlY3RvciBhdCB0aGUgc3BlY2lmaWVkIGluZGV4LgotICAgKiBFYWNoIGNvbXBvbmVudCBpbiB0aGlzIHZlY3RvciB3aXRoIGFuIGluZGV4IGdyZWF0ZXIgb3IgZXF1YWwgdG8KLSAgICogdGhlIHNwZWNpZmllZCBpbmRleCBpcyBzaGlmdGVkIHVwd2FyZCB0byBoYXZlIGFuIGluZGV4IG9uZSBncmVhdGVyCi0gICAqIHRoYW4gdGhlIHZhbHVlIGl0IGhhZCBwcmV2aW91c2x5LgotICAgKgotICAgKiBAcGFyYW0gdmFsdWUgVGhlIG5vZGUgdG8gYmUgaW5zZXJ0ZWQuCi0gICAqIEBwYXJhbSBhdCBUaGUgaW5kZXggd2hlcmUgdGhlIGluc2VydCBzaG91bGQgb2NjdXIuCi0gICAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiB0aHJvd24gaWYgdGhpcyBOb2RlU2V0RFRNIGlzIG5vdCBvZgotICAgKiBhIG11dGFibGUgdHlwZS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGluc2VydEVsZW1lbnRBdChpbnQgdmFsdWUsIGludCBhdCkKLSAgewotCi0gICAgaWYgKCFtX211dGFibGUpCi0gICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoWFBBVEhFcnJvclJlc291cmNlcy5FUl9OT0RFU0VURFRNX05PVF9NVVRBQkxFLCBudWxsKSk7IC8vIlRoaXMgTm9kZVNldERUTSBpcyBub3QgbXV0YWJsZSEiKTsKLQotICAgIHN1cGVyLmluc2VydEVsZW1lbnRBdCh2YWx1ZSwgYXQpOwotICB9Ci0KLSAgLyoqCi0gICAqIEFwcGVuZCB0aGUgbm9kZXMgdG8gdGhlIGxpc3QuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlcyBUaGUgbm9kZXMgdG8gYmUgYXBwZW5kZWQgdG8gdGhpcyBub2RlIHNldC4KLSAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIHRocm93biBpZiB0aGlzIE5vZGVTZXREVE0gaXMgbm90IG9mCi0gICAqIGEgbXV0YWJsZSB0eXBlLgotICAgKi8KLSAgcHVibGljIHZvaWQgYXBwZW5kTm9kZXMoTm9kZVZlY3RvciBub2RlcykKLSAgewotCi0gICAgaWYgKCFtX211dGFibGUpCi0gICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoWFBBVEhFcnJvclJlc291cmNlcy5FUl9OT0RFU0VURFRNX05PVF9NVVRBQkxFLCBudWxsKSk7IC8vIlRoaXMgTm9kZVNldERUTSBpcyBub3QgbXV0YWJsZSEiKTsKLQotICAgIHN1cGVyLmFwcGVuZE5vZGVzKG5vZGVzKTsKLSAgfQotCi0gIC8qKgotICAgKiBJbnNlcnRzIHRoZSBzcGVjaWZpZWQgbm9kZSBpbiB0aGlzIHZlY3RvciBhdCB0aGUgc3BlY2lmaWVkIGluZGV4LgotICAgKiBFYWNoIGNvbXBvbmVudCBpbiB0aGlzIHZlY3RvciB3aXRoIGFuIGluZGV4IGdyZWF0ZXIgb3IgZXF1YWwgdG8KLSAgICogdGhlIHNwZWNpZmllZCBpbmRleCBpcyBzaGlmdGVkIHVwd2FyZCB0byBoYXZlIGFuIGluZGV4IG9uZSBncmVhdGVyCi0gICAqIHRoYW4gdGhlIHZhbHVlIGl0IGhhZCBwcmV2aW91c2x5LgotICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gdGhyb3duIGlmIHRoaXMgTm9kZVNldERUTSBpcyBub3Qgb2YKLSAgICogYSBtdXRhYmxlIHR5cGUuCi0gICAqLwotICBwdWJsaWMgdm9pZCByZW1vdmVBbGxFbGVtZW50cygpCi0gIHsKLQotICAgIGlmICghbV9tdXRhYmxlKQotICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfTk9ERVNFVERUTV9OT1RfTVVUQUJMRSwgbnVsbCkpOyAvLyJUaGlzIE5vZGVTZXREVE0gaXMgbm90IG11dGFibGUhIik7Ci0KLSAgICBzdXBlci5yZW1vdmVBbGxFbGVtZW50cygpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlbW92ZXMgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgdGhlIGFyZ3VtZW50IGZyb20gdGhpcyB2ZWN0b3IuCi0gICAqIElmIHRoZSBvYmplY3QgaXMgZm91bmQgaW4gdGhpcyB2ZWN0b3IsIGVhY2ggY29tcG9uZW50IGluIHRoZSB2ZWN0b3IKLSAgICogd2l0aCBhbiBpbmRleCBncmVhdGVyIG9yIGVxdWFsIHRvIHRoZSBvYmplY3QncyBpbmRleCBpcyBzaGlmdGVkCi0gICAqIGRvd253YXJkIHRvIGhhdmUgYW4gaW5kZXggb25lIHNtYWxsZXIgdGhhbiB0aGUgdmFsdWUgaXQgaGFkCi0gICAqIHByZXZpb3VzbHkuCi0gICAqCi0gICAqIEBwYXJhbSBzIFRoZSBub2RlIHRvIGJlIHJlbW92ZWQuCi0gICAqCi0gICAqIEByZXR1cm4gVHJ1ZSBpZiB0aGUgbm9kZSB3YXMgc3VjY2Vzc2Z1bGx5IHJlbW92ZWQKLSAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIHRocm93biBpZiB0aGlzIE5vZGVTZXREVE0gaXMgbm90IG9mCi0gICAqIGEgbXV0YWJsZSB0eXBlLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gcmVtb3ZlRWxlbWVudChpbnQgcykKLSAgewotCi0gICAgaWYgKCFtX211dGFibGUpCi0gICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoWFBBVEhFcnJvclJlc291cmNlcy5FUl9OT0RFU0VURFRNX05PVF9NVVRBQkxFLCBudWxsKSk7IC8vIlRoaXMgTm9kZVNldERUTSBpcyBub3QgbXV0YWJsZSEiKTsKLQotICAgIHJldHVybiBzdXBlci5yZW1vdmVFbGVtZW50KHMpOwotICB9Ci0KLSAgLyoqCi0gICAqIERlbGV0ZXMgdGhlIGNvbXBvbmVudCBhdCB0aGUgc3BlY2lmaWVkIGluZGV4LiBFYWNoIGNvbXBvbmVudCBpbgotICAgKiB0aGlzIHZlY3RvciB3aXRoIGFuIGluZGV4IGdyZWF0ZXIgb3IgZXF1YWwgdG8gdGhlIHNwZWNpZmllZAotICAgKiBpbmRleCBpcyBzaGlmdGVkIGRvd253YXJkIHRvIGhhdmUgYW4gaW5kZXggb25lIHNtYWxsZXIgdGhhbgotICAgKiB0aGUgdmFsdWUgaXQgaGFkIHByZXZpb3VzbHkuCi0gICAqCi0gICAqIEBwYXJhbSBpIFRoZSBpbmRleCBvZiB0aGUgbm9kZSB0byBiZSByZW1vdmVkLgotICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gdGhyb3duIGlmIHRoaXMgTm9kZVNldERUTSBpcyBub3Qgb2YKLSAgICogYSBtdXRhYmxlIHR5cGUuCi0gICAqLwotICBwdWJsaWMgdm9pZCByZW1vdmVFbGVtZW50QXQoaW50IGkpCi0gIHsKLQotICAgIGlmICghbV9tdXRhYmxlKQotICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfTk9ERVNFVERUTV9OT1RfTVVUQUJMRSwgbnVsbCkpOyAvLyJUaGlzIE5vZGVTZXREVE0gaXMgbm90IG11dGFibGUhIik7Ci0KLSAgICBzdXBlci5yZW1vdmVFbGVtZW50QXQoaSk7Ci0gIH0KLQotICAvKioKLSAgICogU2V0cyB0aGUgY29tcG9uZW50IGF0IHRoZSBzcGVjaWZpZWQgaW5kZXggb2YgdGhpcyB2ZWN0b3IgdG8gYmUgdGhlCi0gICAqIHNwZWNpZmllZCBvYmplY3QuIFRoZSBwcmV2aW91cyBjb21wb25lbnQgYXQgdGhhdCBwb3NpdGlvbiBpcyBkaXNjYXJkZWQuCi0gICAqCi0gICAqIFRoZSBpbmRleCBtdXN0IGJlIGEgdmFsdWUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIDAgYW5kIGxlc3MKLSAgICogdGhhbiB0aGUgY3VycmVudCBzaXplIG9mIHRoZSB2ZWN0b3IuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlICBUaGUgbm9kZSB0byBiZSBzZXQuCi0gICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIG5vZGUgdG8gYmUgcmVwbGFjZWQuCi0gICAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiB0aHJvd24gaWYgdGhpcyBOb2RlU2V0RFRNIGlzIG5vdCBvZgotICAgKiBhIG11dGFibGUgdHlwZS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldEVsZW1lbnRBdChpbnQgbm9kZSwgaW50IGluZGV4KQotICB7Ci0KLSAgICBpZiAoIW1fbXV0YWJsZSkKLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShYUEFUSEVycm9yUmVzb3VyY2VzLkVSX05PREVTRVREVE1fTk9UX01VVEFCTEUsIG51bGwpKTsgLy8iVGhpcyBOb2RlU2V0RFRNIGlzIG5vdCBtdXRhYmxlISIpOwotCi0gICAgc3VwZXIuc2V0RWxlbWVudEF0KG5vZGUsIGluZGV4KTsKLSAgfQotCi0gIC8qKgotICAgKiBTYW1lIGFzIHNldEVsZW1lbnRBdC4KLSAgICoKLSAgICogQHBhcmFtIG5vZGUgIFRoZSBub2RlIHRvIGJlIHNldC4KLSAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgbm9kZSB0byBiZSByZXBsYWNlZC4KLSAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIHRocm93biBpZiB0aGlzIE5vZGVTZXREVE0gaXMgbm90IG9mCi0gICAqIGEgbXV0YWJsZSB0eXBlLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0SXRlbShpbnQgbm9kZSwgaW50IGluZGV4KQotICB7Ci0KLSAgICBpZiAoIW1fbXV0YWJsZSkKLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShYUEFUSEVycm9yUmVzb3VyY2VzLkVSX05PREVTRVREVE1fTk9UX01VVEFCTEUsIG51bGwpKTsgLy8iVGhpcyBOb2RlU2V0RFRNIGlzIG5vdCBtdXRhYmxlISIpOwotCi0gICAgc3VwZXIuc2V0RWxlbWVudEF0KG5vZGUsIGluZGV4KTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIG50aCBlbGVtZW50LgotICAgKgotICAgKiBAcGFyYW0gaSBUaGUgaW5kZXggb2YgdGhlIHJlcXVlc3RlZCBub2RlLgotICAgKgotICAgKiBAcmV0dXJuIE5vZGUgYXQgc3BlY2lmaWVkIGluZGV4LgotICAgKi8KLSAgcHVibGljIGludCBlbGVtZW50QXQoaW50IGkpCi0gIHsKLQotICAgIHJ1blRvKGkpOwotCi0gICAgcmV0dXJuIHN1cGVyLmVsZW1lbnRBdChpKTsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIGlmIHRoZSB0YWJsZSBjb250YWlucyB0aGUgZ2l2ZW4gbm9kZS4KLSAgICoKLSAgICogQHBhcmFtIHMgTm9kZSB0byBsb29rIGZvcgotICAgKgotICAgKiBAcmV0dXJuIFRydWUgaWYgdGhlIGdpdmVuIG5vZGUgd2FzIGZvdW5kLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gY29udGFpbnMoaW50IHMpCi0gIHsKLQotICAgIHJ1blRvKC0xKTsKLQotICAgIHJldHVybiBzdXBlci5jb250YWlucyhzKTsKLSAgfQotCi0gIC8qKgotICAgKiBTZWFyY2hlcyBmb3IgdGhlIGZpcnN0IG9jY3VyZW5jZSBvZiB0aGUgZ2l2ZW4gYXJndW1lbnQsCi0gICAqIGJlZ2lubmluZyB0aGUgc2VhcmNoIGF0IGluZGV4LCBhbmQgdGVzdGluZyBmb3IgZXF1YWxpdHkKLSAgICogdXNpbmcgdGhlIGVxdWFscyBtZXRob2QuCi0gICAqCi0gICAqIEBwYXJhbSBlbGVtIE5vZGUgdG8gbG9vayBmb3IKLSAgICogQHBhcmFtIGluZGV4IEluZGV4IG9mIHdoZXJlIHRvIHN0YXJ0IHRoZSBzZWFyY2gKLSAgICogQHJldHVybiB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgdGhlIG9iamVjdAotICAgKiBhcmd1bWVudCBpbiB0aGlzIHZlY3RvciBhdCBwb3NpdGlvbiBpbmRleCBvciBsYXRlciBpbiB0aGUKLSAgICogdmVjdG9yOyByZXR1cm5zIC0xIGlmIHRoZSBvYmplY3QgaXMgbm90IGZvdW5kLgotICAgKi8KLSAgcHVibGljIGludCBpbmRleE9mKGludCBlbGVtLCBpbnQgaW5kZXgpCi0gIHsKLQotICAgIHJ1blRvKC0xKTsKLQotICAgIHJldHVybiBzdXBlci5pbmRleE9mKGVsZW0sIGluZGV4KTsKLSAgfQotCi0gIC8qKgotICAgKiBTZWFyY2hlcyBmb3IgdGhlIGZpcnN0IG9jY3VyZW5jZSBvZiB0aGUgZ2l2ZW4gYXJndW1lbnQsCi0gICAqIGJlZ2lubmluZyB0aGUgc2VhcmNoIGF0IGluZGV4LCBhbmQgdGVzdGluZyBmb3IgZXF1YWxpdHkKLSAgICogdXNpbmcgdGhlIGVxdWFscyBtZXRob2QuCi0gICAqCi0gICAqIEBwYXJhbSBlbGVtIE5vZGUgdG8gbG9vayBmb3IKLSAgICogQHJldHVybiB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgdGhlIG9iamVjdAotICAgKiBhcmd1bWVudCBpbiB0aGlzIHZlY3RvciBhdCBwb3NpdGlvbiBpbmRleCBvciBsYXRlciBpbiB0aGUKLSAgICogdmVjdG9yOyByZXR1cm5zIC0xIGlmIHRoZSBvYmplY3QgaXMgbm90IGZvdW5kLgotICAgKi8KLSAgcHVibGljIGludCBpbmRleE9mKGludCBlbGVtKQotICB7Ci0KLSAgICBydW5UbygtMSk7Ci0KLSAgICByZXR1cm4gc3VwZXIuaW5kZXhPZihlbGVtKTsKLSAgfQotCi0gIC8qKiBJZiB0aGlzIG5vZGUgaXMgYmVpbmcgdXNlZCBhcyBhbiBpdGVyYXRvciwgdGhlIG5leHQgaW5kZXggdGhhdCBuZXh0Tm9kZSgpCi0gICAqICB3aWxsIHJldHVybi4gICovCi0gIHRyYW5zaWVudCBwcm90ZWN0ZWQgaW50IG1fbmV4dCA9IDA7Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgY3VycmVudCBwb3NpdGlvbiwgd2hpY2ggaXMgb25lIGxlc3MgdGhhbgotICAgKiB0aGUgbmV4dCBuZXh0Tm9kZSgpIGNhbGwgd2lsbCByZXRyaWV2ZS4gIGkuZS4gaWYKLSAgICogeW91IGNhbGwgZ2V0Q3VycmVudFBvcygpIGFuZCB0aGUgcmV0dXJuIGlzIDAsIHRoZSBuZXh0Ci0gICAqIGZldGNoIHdpbGwgdGFrZSBwbGFjZSBhdCBpbmRleCAxLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSB0aGUgY3VycmVudCBwb3NpdGlvbiBpbmRleC4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0Q3VycmVudFBvcygpCi0gIHsKLSAgICByZXR1cm4gbV9uZXh0OwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgY3VycmVudCBwb3NpdGlvbiBpbiB0aGUgbm9kZSBzZXQuCi0gICAqIEBwYXJhbSBpIE11c3QgYmUgYSB2YWxpZCBpbmRleC4KLSAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIHRocm93biBpZiB0aGlzIE5vZGVTZXREVE0gaXMgbm90IG9mCi0gICAqIGEgY2FjaGVkIHR5cGUsIGFuZCB0aHVzIGRvZXNuJ3QgcGVybWl0IGluZGV4ZWQgYWNjZXNzLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0Q3VycmVudFBvcyhpbnQgaSkKLSAgewotCi0gICAgaWYgKCFtX2NhY2hlTm9kZXMpCi0gICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKLSAgICAgICAgWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfTk9ERVNFVERUTV9DQU5OT1RfSU5ERVgsIG51bGwpKTsgLy8iVGhpcyBOb2RlU2V0RFRNIGNhbiBub3QgZG8gaW5kZXhpbmcgb3IgY291bnRpbmcgZnVuY3Rpb25zISIpOwotCi0gICAgbV9uZXh0ID0gaTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIGxhc3QgZmV0Y2hlZCBub2RlLiAgTmVlZGVkIHRvIHN1cHBvcnQgdGhlIFVuaW9uUGF0aEl0ZXJhdG9yLgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBsYXN0IGZldGNoZWQgbm9kZS4KLSAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIHRocm93biBpZiB0aGlzIE5vZGVTZXREVE0gaXMgbm90IG9mCi0gICAqIGEgY2FjaGVkIHR5cGUsIGFuZCB0aHVzIGRvZXNuJ3QgcGVybWl0IGluZGV4ZWQgYWNjZXNzLgotICAgKi8KLSAgcHVibGljIGludCBnZXRDdXJyZW50Tm9kZSgpCi0gIHsKLQotICAgIGlmICghbV9jYWNoZU5vZGVzKQotICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCi0gICAgICAgICJUaGlzIE5vZGVTZXREVE0gY2FuIG5vdCBkbyBpbmRleGluZyBvciBjb3VudGluZyBmdW5jdGlvbnMhIik7Ci0KLSAgICBpbnQgc2F2ZWQgPSBtX25leHQ7Ci0gICAgLy8gYmVjYXVzZSBuZXh0Tm9kZSBhbHdheXMgaW5jcmVtZW50cwotICAgIC8vIEJ1dCB3YXRjaCBvdXQgZm9yIGNvcHkyOSwgd2hlcmUgdGhlIHJvb3QgaXRlcmF0b3IgZGlkbid0Ci0gICAgLy8gaGF2ZSBuZXh0Tm9kZSBjYWxsZWQgb24gaXQuCi0gICAgaW50IGN1cnJlbnQgPSAobV9uZXh0ID4gMCkgPyBtX25leHQtMSA6IG1fbmV4dDsKLSAgICBpbnQgbiA9IChjdXJyZW50IDwgbV9maXJzdEZyZWUpID8gZWxlbWVudEF0KGN1cnJlbnQpIDogRFRNLk5VTEw7Ci0gICAgbV9uZXh0ID0gc2F2ZWQ7IC8vIEhBQ0s6IEkgdGhpbmsgdGhpcyBpcyBhIGJpdCBvZiBhIGhhY2suICAtc2IKLSAgICByZXR1cm4gbjsKLSAgfQotCi0gIC8qKiBUcnVlIGlmIHRoaXMgbGlzdCBjYW4gYmUgbXV0YXRlZC4gICovCi0gIHRyYW5zaWVudCBwcm90ZWN0ZWQgYm9vbGVhbiBtX211dGFibGUgPSB0cnVlOwotCi0gIC8qKiBUcnVlIGlmIHRoaXMgbGlzdCBpcyBjYWNoZWQuCi0gICAqICBAc2VyaWFsICAqLwotICB0cmFuc2llbnQgcHJvdGVjdGVkIGJvb2xlYW4gbV9jYWNoZU5vZGVzID0gdHJ1ZTsKLQotICAvKiogVGhlIHJvb3Qgb2YgdGhlIGl0ZXJhdGlvbiwgaWYgYXZhaWxhYmxlLiAqLwotICBwcm90ZWN0ZWQgaW50IG1fcm9vdCA9IERUTS5OVUxMOwotCi0gIC8qKgotICAgKiBHZXQgd2hldGhlciBvciBub3QgdGhpcyBpcyBhIGNhY2hlZCBub2RlIHNldC4KLSAgICoKLSAgICoKLSAgICogQHJldHVybiBUcnVlIGlmIHRoaXMgbGlzdCBpcyBjYWNoZWQuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBnZXRTaG91bGRDYWNoZU5vZGVzKCkKLSAgewotICAgIHJldHVybiBtX2NhY2hlTm9kZXM7Ci0gIH0KLQotICAvKioKLSAgICogSWYgc2V0U2hvdWxkQ2FjaGVOb2Rlcyh0cnVlKSBpcyBjYWxsZWQsIHRoZW4gbm9kZXMgd2lsbAotICAgKiBiZSBjYWNoZWQuICBUaGV5IGFyZSBub3QgY2FjaGVkIGJ5IGRlZmF1bHQuIFRoaXMgc3dpdGNoIG11c3QKLSAgICogYmUgc2V0IGJlZm9yZSB0aGUgZmlyc3QgY2FsbCB0byBuZXh0Tm9kZSBpcyBtYWRlLCB0byBlbnN1cmUKLSAgICogdGhhdCBhbGwgbm9kZXMgYXJlIGNhY2hlZC4KLSAgICoKLSAgICogQHBhcmFtIGIgdHJ1ZSBpZiB0aGlzIG5vZGUgc2V0IHNob3VsZCBiZSBjYWNoZWQuCi0gICAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiB0aHJvd24gaWYgYW4gYXR0ZW1wdCBpcyBtYWRlIHRvCi0gICAqIHJlcXVlc3QgY2FjaGluZyBhZnRlciB3ZSd2ZSBhbHJlYWR5IGJlZ3VuIHN0ZXBwaW5nIHRocm91Z2ggdGhlCi0gICAqIG5vZGVzIGluIHRoaXMgc2V0LgotICAqLwotICBwdWJsaWMgdm9pZCBzZXRTaG91bGRDYWNoZU5vZGVzKGJvb2xlYW4gYikKLSAgewotCi0gICAgaWYgKCFpc0ZyZXNoKCkpCi0gICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKLSAgICAgICAgWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfQ0FOTk9UX0NBTExfU0VUU0hPVUxEQ0FDSEVOT0RFLCBudWxsKSk7IC8vIkNhbiBub3QgY2FsbCBzZXRTaG91bGRDYWNoZU5vZGVzIGFmdGVyIG5leHROb2RlIGhhcyBiZWVuIGNhbGxlZCEiKTsKLQotICAgIG1fY2FjaGVOb2RlcyA9IGI7Ci0gICAgbV9tdXRhYmxlID0gdHJ1ZTsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxscyBpZiB0aGlzIGl0ZXJhdG9yIGNhbiBoYXZlIG5vZGVzIGFkZGVkIHRvIGl0IG9yIHNldCB2aWEKLSAgICogdGhlIDxjb2RlPnNldEl0ZW0oaW50IG5vZGUsIGludCBpbmRleCk8L2NvZGU+IG1ldGhvZC4KLSAgICoKLSAgICogQHJldHVybiBUcnVlIGlmIHRoZSBub2RlbGlzdCBjYW4gYmUgbXV0YXRlZC4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzTXV0YWJsZSgpCi0gIHsKLSAgICByZXR1cm4gbV9tdXRhYmxlOwotICB9Ci0KLSAgdHJhbnNpZW50IHByaXZhdGUgaW50IG1fbGFzdCA9IDA7Ci0KLSAgcHVibGljIGludCBnZXRMYXN0KCkKLSAgewotICAgIHJldHVybiBtX2xhc3Q7Ci0gIH0KLQotICBwdWJsaWMgdm9pZCBzZXRMYXN0KGludCBsYXN0KQotICB7Ci0gICAgbV9sYXN0ID0gbGFzdDsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRydWUgaWYgYWxsIHRoZSBub2RlcyBpbiB0aGUgaXRlcmF0aW9uIHdlbGwgYmUgcmV0dXJuZWQgaW4gZG9jdW1lbnQKLSAgICogb3JkZXIuCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBhcyBhIGRlZmF1bHQuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBpc0RvY09yZGVyZWQoKQotICB7Ci0gICAgcmV0dXJuIHRydWU7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgYXhpcyBiZWluZyBpdGVyYXRlZCwgaWYgaXQgaXMga25vd24uCi0gICAqCi0gICAqIEByZXR1cm4gQXhpcy5DSElMRCwgZXRjLiwgb3IgLTEgaWYgdGhlIGF4aXMgaXMgbm90IGtub3duIG9yIGlzIG9mIG11bHRpcGxlCi0gICAqIHR5cGVzLgotICAgKi8KLSAgcHVibGljIGludCBnZXRBeGlzKCkKLSAgewotICAgIHJldHVybiAtMTsKLSAgfQotCi0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvU291cmNlVHJlZS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9Tb3VyY2VUcmVlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDdhMWNjMGEuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9Tb3VyY2VUcmVlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw1NCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBTb3VyY2VUcmVlLmphdmEsdiAxLjEuMi4xIDIwMDUvMDgvMDEgMDE6MzA6MTUgamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbDsKLQotCi0vKioKLSAqIFRoaXMgb2JqZWN0IHJlcHJlc2VudHMgYSBTb3VyY2UgVHJlZSwgYW5kIGFueSBhc3NvY2lhdGVkCi0gKiBpbmZvcm1hdGlvbi4KLSAqIEB4c2wudXNhZ2UgaW50ZXJuYWwKLSAqLwotcHVibGljIGNsYXNzIFNvdXJjZVRyZWUKLXsKLQotICAvKioKLSAgICogQ29uc3RydWN0b3IgU291cmNlVHJlZQotICAgKgotICAgKgotICAgKiBAcGFyYW0gcm9vdCBUaGUgcm9vdCBvZiB0aGUgc291cmNlIHRyZWUsIHdoaWNoIG1heSBvciBtYXkgbm90IGJlIGEKLSAgICoge0BsaW5rIG9yZy53M2MuZG9tLkRvY3VtZW50fSBub2RlLgotICAgKiBAcGFyYW0gdXJsIFRoZSBVUkkgb2YgdGhlIHNvdXJjZSB0cmVlLgotICAgKi8KLSAgcHVibGljIFNvdXJjZVRyZWUoaW50IHJvb3QsIFN0cmluZyB1cmwpCi0gIHsKLSAgICBtX3Jvb3QgPSByb290OwotICAgIG1fdXJsID0gdXJsOwotICB9Ci0KLSAgLyoqIFRoZSBVUkkgb2YgdGhlIHNvdXJjZSB0cmVlLiAgICovCi0gIHB1YmxpYyBTdHJpbmcgbV91cmw7Ci0KLSAgLyoqIFRoZSByb290IG9mIHRoZSBzb3VyY2UgdHJlZSwgd2hpY2ggbWF5IG9yIG1heSBub3QgYmUgYQotICAgKiB7QGxpbmsgb3JnLnczYy5kb20uRG9jdW1lbnR9IG5vZGUuICAqLwotICBwdWJsaWMgaW50IG1fcm9vdDsKLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvU291cmNlVHJlZU1hbmFnZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvU291cmNlVHJlZU1hbmFnZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYjljNDc3MC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL1NvdXJjZVRyZWVNYW5hZ2VyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzOTIgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogU291cmNlVHJlZU1hbmFnZXIuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xMCAxODoxNDowOSBqZWZmc3V0dG9yIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsOwotCi1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2U7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2VMb2NhdG9yOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5VUklSZXNvbHZlcjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnNheC5TQVhTb3VyY2U7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zdHJlYW0uU3RyZWFtU291cmNlOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuU3lzdGVtSURSZXNvbHZlcjsKLQotaW1wb3J0IG9yZy54bWwuc2F4LlhNTFJlYWRlcjsKLWltcG9ydCBvcmcueG1sLnNheC5oZWxwZXJzLlhNTFJlYWRlckZhY3Rvcnk7Ci0KLS8qKgotICogVGhpcyBjbGFzcyBib3R0bGVuZWNrcyBhbGwgbWFuYWdlbWVudCBvZiBzb3VyY2UgdHJlZXMuICBUaGUgbWV0aG9kcwotICogaW4gdGhpcyBjbGFzcyBzaG91bGQgYWxsb3cgZWFzeSBnYXJiYWdlIGNvbGxlY3Rpb24gb2Ygc291cmNlCi0gKiB0cmVlcyAobm90IHlldCEpLCBhbmQgc2hvdWxkIGNlbnRyYWxpemUgcGFyc2luZyBmb3IgdGhvc2Ugc291cmNlIHRyZWVzLgotICovCi1wdWJsaWMgY2xhc3MgU291cmNlVHJlZU1hbmFnZXIKLXsKLQotICAvKiogVmVjdG9yIG9mIFNvdXJjZVRyZWUgb2JqZWN0cyB0aGF0IHRoaXMgbWFuYWdlciBtYW5hZ2VzLiAqLwotICBwcml2YXRlIFZlY3RvciBtX3NvdXJjZVRyZWUgPSBuZXcgVmVjdG9yKCk7Ci0KLSAgLyoqCi0gICAqIFJlc2V0IHRoZSBsaXN0IG9mIFNvdXJjZVRyZWUgb2JqZWN0cyB0aGF0IHRoaXMgbWFuYWdlciBtYW5hZ2VzLgotICAgKgotICAgKi8KLSAgcHVibGljIHZvaWQgcmVzZXQoKQotICB7Ci0gICAgbV9zb3VyY2VUcmVlID0gbmV3IFZlY3RvcigpOwotICB9Ci0KLSAgLyoqIFRoZSBUckFYIFVSSSByZXNvbHZlciB1c2VkIHRvIG9idGFpbiBzb3VyY2UgdHJlZXMuICovCi0gIFVSSVJlc29sdmVyIG1fdXJpUmVzb2x2ZXI7Ci0KLSAgLyoqCi0gICAqIFNldCBhbiBvYmplY3QgdGhhdCB3aWxsIGJlIHVzZWQgdG8gcmVzb2x2ZSBVUklzIHVzZWQgaW4KLSAgICogZG9jdW1lbnQoKSwgZXRjLgotICAgKiBAcGFyYW0gcmVzb2x2ZXIgQW4gb2JqZWN0IHRoYXQgaW1wbGVtZW50cyB0aGUgVVJJUmVzb2x2ZXIgaW50ZXJmYWNlLAotICAgKiBvciBudWxsLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0VVJJUmVzb2x2ZXIoVVJJUmVzb2x2ZXIgcmVzb2x2ZXIpCi0gIHsKLSAgICBtX3VyaVJlc29sdmVyID0gcmVzb2x2ZXI7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBvYmplY3QgdGhhdCB3aWxsIGJlIHVzZWQgdG8gcmVzb2x2ZSBVUklzIHVzZWQgaW4KLSAgICogZG9jdW1lbnQoKSwgZXRjLgotICAgKiBAcmV0dXJuIEFuIG9iamVjdCB0aGF0IGltcGxlbWVudHMgdGhlIFVSSVJlc29sdmVyIGludGVyZmFjZSwKLSAgICogb3IgbnVsbC4KLSAgICovCi0gIHB1YmxpYyBVUklSZXNvbHZlciBnZXRVUklSZXNvbHZlcigpCi0gIHsKLSAgICByZXR1cm4gbV91cmlSZXNvbHZlcjsKLSAgfQotCi0gIC8qKgotICAgKiBHaXZlbiBhIGRvY3VtZW50LCBmaW5kIHRoZSBVUkwgYXNzb2NpYXRlZCB3aXRoIHRoYXQgZG9jdW1lbnQuCi0gICAqIEBwYXJhbSBvd25lciBEb2N1bWVudCB0aGF0IHdhcyBwcmV2aW91c2x5IHByb2Nlc3NlZCBieSB0aGlzIGxpYWlzb24uCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGJhc2UgVVJJIG9mIHRoZSBvd25lciBhcmd1bWVudC4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZmluZFVSSUZyb21Eb2MoaW50IG93bmVyKQotICB7Ci0gICAgaW50IG4gPSBtX3NvdXJjZVRyZWUuc2l6ZSgpOwotCi0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspCi0gICAgewotICAgICAgU291cmNlVHJlZSBzVHJlZSA9IChTb3VyY2VUcmVlKSBtX3NvdXJjZVRyZWUuZWxlbWVudEF0KGkpOwotCi0gICAgICBpZiAob3duZXIgPT0gc1RyZWUubV9yb290KQotICAgICAgICByZXR1cm4gc1RyZWUubV91cmw7Ci0gICAgfQotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogVGhpcyB3aWxsIGJlIGNhbGxlZCBieSB0aGUgcHJvY2Vzc29yIHdoZW4gaXQgZW5jb3VudGVycwotICAgKiBhbiB4c2w6aW5jbHVkZSwgeHNsOmltcG9ydCwgb3IgZG9jdW1lbnQoKSBmdW5jdGlvbi4KLSAgICoKLSAgICogQHBhcmFtIGJhc2UgVGhlIGJhc2UgVVJJIHRoYXQgc2hvdWxkIGJlIHVzZWQuCi0gICAqIEBwYXJhbSB1cmxTdHJpbmcgVmFsdWUgZnJvbSBhbiB4c2w6aW1wb3J0IG9yIHhzbDppbmNsdWRlJ3MgaHJlZiBhdHRyaWJ1dGUsCi0gICAqIG9yIGEgVVJJIHNwZWNpZmllZCBpbiB0aGUgZG9jdW1lbnQoKSBmdW5jdGlvbi4KLSAgICoKLSAgICogQHJldHVybiBhIFNvdXJjZSB0aGF0IGNhbiBiZSB1c2VkIHRvIHByb2Nlc3MgdGhlIHJlc291cmNlLgotICAgKgotICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBTb3VyY2UgcmVzb2x2ZVVSSSgKLSAgICAgICAgICBTdHJpbmcgYmFzZSwgU3RyaW5nIHVybFN0cmluZywgU291cmNlTG9jYXRvciBsb2NhdG9yKQotICAgICAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbgotICB7Ci0KLSAgICBTb3VyY2Ugc291cmNlID0gbnVsbDsKLQotICAgIGlmIChudWxsICE9IG1fdXJpUmVzb2x2ZXIpCi0gICAgewotICAgICAgc291cmNlID0gbV91cmlSZXNvbHZlci5yZXNvbHZlKHVybFN0cmluZywgYmFzZSk7Ci0gICAgfQotCi0gICAgaWYgKG51bGwgPT0gc291cmNlKQotICAgIHsKLSAgICAgIFN0cmluZyB1cmkgPSBTeXN0ZW1JRFJlc29sdmVyLmdldEFic29sdXRlVVJJKHVybFN0cmluZywgYmFzZSk7Ci0KLSAgICAgIHNvdXJjZSA9IG5ldyBTdHJlYW1Tb3VyY2UodXJpKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gc291cmNlOwotICB9Ci0KLSAgLyoqIEpKSzogU3VwcG9ydCAgPD94YWxhbjpkb2NfY2FjaGVfb2ZmPz4ga2x1Z2UgaW4gRWxlbUZvckVhY2guCi0gICAqIFRPRE86IFRoaXMgZnVuY3Rpb24gaXMgaGlnaGx5IGRhbmdlcm91cy4gQ2FjaGUgbWFuYWdlbWVudCBtdXN0IGJlIGltcHJvdmVkLgotICAgKgotICAgKiBAcGFyYW0gbiBUaGUgbm9kZSB0byByZW1vdmUuCi0gICAqLwotICBwdWJsaWMgdm9pZCByZW1vdmVEb2N1bWVudEZyb21DYWNoZShpbnQgbikKLSAgewotICAgIGlmKERUTS5OVUxMID09bikKLSAgICAgIHJldHVybjsKLSAgICBmb3IoaW50IGk9bV9zb3VyY2VUcmVlLnNpemUoKS0xO2k+PTA7LS1pKQotICAgIHsKLSAgICAgIFNvdXJjZVRyZWUgc3Q9KFNvdXJjZVRyZWUpbV9zb3VyY2VUcmVlLmVsZW1lbnRBdChpKTsKLSAgICAgIGlmKHN0IT1udWxsICYmIHN0Lm1fcm9vdD09bikKLSAgICAgIHsKLSAgICAgICAgbV9zb3VyY2VUcmVlLnJlbW92ZUVsZW1lbnRBdChpKTsKLSAgICAgICAgcmV0dXJuOwotICAgICAgfQotICAgIH0KLSAgfQotCi0KLQotICAvKioKLSAgICogUHV0IHRoZSBzb3VyY2UgdHJlZSByb290IG5vZGUgaW4gdGhlIGRvY3VtZW50IGNhY2hlLgotICAgKiBUT0RPOiBUaGlzIGZ1bmN0aW9uIG5lZWRzIHRvIGJlIGEgTE9UIG1vcmUgc29waGlzdGljYXRlZC4KLSAgICoKLSAgICogQHBhcmFtIG4gVGhlIG5vZGUgdG8gY2FjaGUuCi0gICAqIEBwYXJhbSBzb3VyY2UgVGhlIFNvdXJjZSBvYmplY3QgdG8gY2FjaGUuCi0gICAqLwotICBwdWJsaWMgdm9pZCBwdXREb2N1bWVudEluQ2FjaGUoaW50IG4sIFNvdXJjZSBzb3VyY2UpCi0gIHsKLQotICAgIGludCBjYWNoZWROb2RlID0gZ2V0Tm9kZShzb3VyY2UpOwotCi0gICAgaWYgKERUTS5OVUxMICE9IGNhY2hlZE5vZGUpCi0gICAgewotICAgICAgaWYgKCEoY2FjaGVkTm9kZSA9PSBuKSkKLSAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCi0gICAgICAgICAgIlByb2dyYW1tZXIncyBFcnJvciEgICIKLSAgICAgICAgICArICJwdXREb2N1bWVudEluQ2FjaGUgZm91bmQgcmVwYXJzZSBvZiBkb2M6ICIKLSAgICAgICAgICArIHNvdXJjZS5nZXRTeXN0ZW1JZCgpKTsKLSAgICAgIHJldHVybjsKLSAgICB9Ci0gICAgaWYgKG51bGwgIT0gc291cmNlLmdldFN5c3RlbUlkKCkpCi0gICAgewotICAgICAgbV9zb3VyY2VUcmVlLmFkZEVsZW1lbnQobmV3IFNvdXJjZVRyZWUobiwgc291cmNlLmdldFN5c3RlbUlkKCkpKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYSBTb3VyY2Ugb2JqZWN0LCBmaW5kIHRoZSBub2RlIGFzc29jaWF0ZWQgd2l0aCBpdC4KLSAgICoKLSAgICogQHBhcmFtIHNvdXJjZSBUaGUgU291cmNlIG9iamVjdCB0byBhY3QgYXMgdGhlIGtleS4KLSAgICoKLSAgICogQHJldHVybiBUaGUgbm9kZSB0aGF0IGlzIGFzc29jaWF0ZWQgd2l0aCB0aGUgU291cmNlLCBvciBudWxsIGlmIG5vdCBmb3VuZC4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0Tm9kZShTb3VyY2Ugc291cmNlKQotICB7Ci0KLS8vICAgIGlmIChzb3VyY2UgaW5zdGFuY2VvZiBET01Tb3VyY2UpCi0vLyAgICAgIHJldHVybiAoKERPTVNvdXJjZSkgc291cmNlKS5nZXROb2RlKCk7Ci0KLSAgICAvLyBUT0RPOiBOb3Qgc3VyZSBpZiB0aGUgQmFzZUlEIGlzIHJlYWxseSB0aGUgc2FtZSB0aGluZyBhcyB0aGUgSUQuCi0gICAgU3RyaW5nIHVybCA9IHNvdXJjZS5nZXRTeXN0ZW1JZCgpOwotCi0gICAgaWYgKG51bGwgPT0gdXJsKQotICAgICAgcmV0dXJuIERUTS5OVUxMOwotCi0gICAgaW50IG4gPSBtX3NvdXJjZVRyZWUuc2l6ZSgpOwotCi0gICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJnZXROb2RlOiAiK24pOwotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKQotICAgIHsKLSAgICAgIFNvdXJjZVRyZWUgc1RyZWUgPSAoU291cmNlVHJlZSkgbV9zb3VyY2VUcmVlLmVsZW1lbnRBdChpKTsKLQotICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJnZXROb2RlIC0gICAgICAgICB1cmw6ICIrdXJsKTsKLSAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiZ2V0Tm9kZSAtIHNUcmVlLm1fdXJsOiAiK3NUcmVlLm1fdXJsKTsKLSAgICAgIGlmICh1cmwuZXF1YWxzKHNUcmVlLm1fdXJsKSkKLSAgICAgICAgcmV0dXJuIHNUcmVlLm1fcm9vdDsKLSAgICB9Ci0KLSAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oImdldE5vZGUgLSByZXR1cm5pbmc6ICIrbm9kZSk7Ci0gICAgcmV0dXJuIERUTS5OVUxMOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgc291cmNlIHRyZWUgZnJvbSB0aGUgYSBiYXNlIFVSTCBhbmQgYSBVUkwgc3RyaW5nLgotICAgKgotICAgKiBAcGFyYW0gYmFzZSBUaGUgYmFzZSBVUkkgdG8gdXNlIGlmIHRoZSB1cmxTdHJpbmcgaXMgcmVsYXRpdmUuCi0gICAqIEBwYXJhbSB1cmxTdHJpbmcgQW4gYWJzb2x1dGUgb3IgcmVsYXRpdmUgVVJMIHN0cmluZy4KLSAgICogQHBhcmFtIGxvY2F0b3IgVGhlIGxvY2F0aW9uIG9mIHRoZSBjYWxsZXIsIGZvciBkaWFnbm9zdGljIHB1cnBvc2VzLgotICAgKgotICAgKiBAcmV0dXJuIHNob3VsZCBiZSBhIG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgbm9kZSBpZGVudGlmaWVkIGJ5IHRoZQotICAgKiBiYXNlIGFuZCB1cmxTdHJpbmcuCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24gSWYgdGhlIFVSTCBjYW4gbm90IHJlc29sdmUgdG8gYSBub2RlLgotICAgKi8KLSAgcHVibGljIGludCBnZXRTb3VyY2VUcmVlKAotICAgICAgICAgIFN0cmluZyBiYXNlLCBTdHJpbmcgdXJsU3RyaW5nLCBTb3VyY2VMb2NhdG9yIGxvY2F0b3IsIFhQYXRoQ29udGV4dCB4Y3R4dCkKLSAgICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oImdldFNvdXJjZVRyZWUiKTsKLSAgICB0cnkKLSAgICB7Ci0gICAgICBTb3VyY2Ugc291cmNlID0gdGhpcy5yZXNvbHZlVVJJKGJhc2UsIHVybFN0cmluZywgbG9jYXRvcik7Ci0KLSAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiZ2V0U291cmNlVHJlZSAtIGJhc2U6ICIrYmFzZSsiLCB1cmxTdHJpbmc6ICIrdXJsU3RyaW5nKyIsIHNvdXJjZTogIitzb3VyY2UuZ2V0U3lzdGVtSWQoKSk7Ci0gICAgICByZXR1cm4gZ2V0U291cmNlVHJlZShzb3VyY2UsIGxvY2F0b3IsIHhjdHh0KTsKLSAgICB9Ci0gICAgY2F0Y2ggKElPRXhjZXB0aW9uIGlvZSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oaW9lLmdldE1lc3NhZ2UoKSwgbG9jYXRvciwgaW9lKTsKLSAgICB9Ci0KLSAgICAvKiBjYXRjaCAoVHJhbnNmb3JtZXJFeGNlcHRpb24gdGUpCi0gICAgIHsKLSAgICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24odGUuZ2V0TWVzc2FnZSgpLCBsb2NhdG9yLCB0ZSk7Ci0gICAgIH0qLwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgc291cmNlIHRyZWUgZnJvbSB0aGUgaW5wdXQgc291cmNlLgotICAgKgotICAgKiBAcGFyYW0gc291cmNlIFRoZSBTb3VyY2Ugb2JqZWN0IHRoYXQgc2hvdWxkIGlkZW50aWZ5IHRoZSBkZXNpcmVkIG5vZGUuCi0gICAqIEBwYXJhbSBsb2NhdG9yIFRoZSBsb2NhdGlvbiBvZiB0aGUgY2FsbGVyLCBmb3IgZGlhZ25vc3RpYyBwdXJwb3Nlcy4KLSAgICoKLSAgICogQHJldHVybiBub24tbnVsbCByZWZlcmVuY2UgdG8gYSBub2RlLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uIGlmIHRoZSBTb3VyY2UgYXJndW1lbnQgY2FuJ3QgYmUgcmVzb2x2ZWQgdG8KLSAgICogICAgICAgICBhIG5vZGUuCi0gICAqLwotICBwdWJsaWMgaW50IGdldFNvdXJjZVRyZWUoU291cmNlIHNvdXJjZSwgU291cmNlTG9jYXRvciBsb2NhdG9yLCBYUGF0aENvbnRleHQgeGN0eHQpCi0gICAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGludCBuID0gZ2V0Tm9kZShzb3VyY2UpOwotCi0gICAgaWYgKERUTS5OVUxMICE9IG4pCi0gICAgICByZXR1cm4gbjsKLQotICAgIG4gPSBwYXJzZVRvTm9kZShzb3VyY2UsIGxvY2F0b3IsIHhjdHh0KTsKLQotICAgIGlmIChEVE0uTlVMTCAhPSBuKQotICAgICAgcHV0RG9jdW1lbnRJbkNhY2hlKG4sIHNvdXJjZSk7Ci0KLSAgICByZXR1cm4gbjsKLSAgfQotCi0gIC8qKgotICAgKiBUcnkgdG8gY3JlYXRlIGEgRE9NIHNvdXJjZSB0cmVlIGZyb20gdGhlIGlucHV0IHNvdXJjZS4KLSAgICoKLSAgICogQHBhcmFtIHNvdXJjZSBUaGUgU291cmNlIG9iamVjdCB0aGF0IGlkZW50aWZpZXMgdGhlIHNvdXJjZSBub2RlLgotICAgKiBAcGFyYW0gbG9jYXRvciBUaGUgbG9jYXRpb24gb2YgdGhlIGNhbGxlciwgZm9yIGRpYWdub3N0aWMgcHVycG9zZXMuCi0gICAqCi0gICAqIEByZXR1cm4gbm9uLW51bGwgcmVmZXJlbmNlIHRvIG5vZGUgaWRlbnRpZmllZCBieSB0aGUgc291cmNlIGFyZ3VtZW50LgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uIGlmIHRoZSBzb3VyY2UgYXJndW1lbnQgY2FuIG5vdCBiZSByZXNvbHZlZAotICAgKiAgICAgICAgIHRvIGEgc291cmNlIG5vZGUuCi0gICAqLwotICBwdWJsaWMgaW50IHBhcnNlVG9Ob2RlKFNvdXJjZSBzb3VyY2UsIFNvdXJjZUxvY2F0b3IgbG9jYXRvciwgWFBhdGhDb250ZXh0IHhjdHh0KQotICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICB0cnkKLSAgICB7Ci0gICAgICBPYmplY3QgeG93bmVyID0geGN0eHQuZ2V0T3duZXJPYmplY3QoKTsKLSAgICAgIERUTSBkdG07Ci0gICAgICBpZihudWxsICE9IHhvd25lciAmJiB4b3duZXIgaW5zdGFuY2VvZiBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1XU0ZpbHRlcikKLSAgICAgIHsKLSAgICAgICAgZHRtID0geGN0eHQuZ2V0RFRNKHNvdXJjZSwgZmFsc2UsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIChjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1XU0ZpbHRlcil4b3duZXIsIGZhbHNlLCB0cnVlKTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgZHRtID0geGN0eHQuZ2V0RFRNKHNvdXJjZSwgZmFsc2UsIG51bGwsIGZhbHNlLCB0cnVlKTsKLSAgICAgIH0KLSAgICAgIHJldHVybiBkdG0uZ2V0RG9jdW1lbnQoKTsKLSAgICB9Ci0gICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKQotICAgIHsKLSAgICAgIC8vZS5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihlLmdldE1lc3NhZ2UoKSwgbG9jYXRvciwgZSk7Ci0gICAgfQotCi0gIH0KLQotICAvKioKLSAgICogVGhpcyBtZXRob2QgcmV0dXJucyB0aGUgU0FYMiBwYXJzZXIgdG8gdXNlIHdpdGggdGhlIElucHV0U291cmNlCi0gICAqIG9idGFpbmVkIGZyb20gdGhpcyBVUkkuCi0gICAqIEl0IG1heSByZXR1cm4gbnVsbCBpZiBhbnkgU0FYMi1jb25mb3JtYW50IFhNTCBwYXJzZXIgY2FuIGJlIHVzZWQsCi0gICAqIG9yIGlmIGdldElucHV0U291cmNlKCkgd2lsbCBhbHNvIHJldHVybiBudWxsLiBUaGUgcGFyc2VyIG11c3QKLSAgICogYmUgZnJlZSBmb3IgdXNlIChpLmUuCi0gICAqIG5vdCBjdXJyZW50bHkgaW4gdXNlIGZvciBhbm90aGVyIHBhcnNlKCkuCi0gICAqCi0gICAqIEBwYXJhbSBpbnB1dFNvdXJjZSBUaGUgdmFsdWUgcmV0dXJuZWQgZnJvbSB0aGUgVVJJUmVzb2x2ZXIuCi0gICAqIEByZXR1cm4gYSBTQVgyIFhNTFJlYWRlciB0byB1c2UgdG8gcmVzb2x2ZSB0aGUgaW5wdXRTb3VyY2UgYXJndW1lbnQuCi0gICAqIEBwYXJhbSBsb2NhdG9yIFRoZSBsb2NhdGlvbiBvZiB0aGUgb3JpZ2luYWwgY2FsbGVyLCBmb3IgZGlhZ25vc3RpYyBwdXJwb3Nlcy4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBpZiB0aGUgcmVhZGVyIGNhbiBub3QgYmUgY3JlYXRlZC4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgWE1MUmVhZGVyIGdldFhNTFJlYWRlcihTb3VyY2UgaW5wdXRTb3VyY2UsIFNvdXJjZUxvY2F0b3IgbG9jYXRvcikKLSAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgdHJ5Ci0gICAgewotICAgICAgWE1MUmVhZGVyIHJlYWRlciA9IChpbnB1dFNvdXJjZSBpbnN0YW5jZW9mIFNBWFNvdXJjZSkKLSAgICAgICAgICAgICAgICAgICAgICAgICA/ICgoU0FYU291cmNlKSBpbnB1dFNvdXJjZSkuZ2V0WE1MUmVhZGVyKCkgOiBudWxsOwotCi0gICAgICBpZiAobnVsbCA9PSByZWFkZXIpCi0gICAgICB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgamF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyRmFjdG9yeSBmYWN0b3J5PQotICAgICAgICAgICAgICBqYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCk7Ci0gICAgICAgICAgZmFjdG9yeS5zZXROYW1lc3BhY2VBd2FyZSggdHJ1ZSApOwotICAgICAgICAgIGphdmF4LnhtbC5wYXJzZXJzLlNBWFBhcnNlciBqYXhwUGFyc2VyPQotICAgICAgICAgICAgICBmYWN0b3J5Lm5ld1NBWFBhcnNlcigpOwotICAgICAgICAgIHJlYWRlcj1qYXhwUGFyc2VyLmdldFhNTFJlYWRlcigpOwotCi0gICAgICAgIH0gY2F0Y2goIGphdmF4LnhtbC5wYXJzZXJzLlBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gZXggKSB7Ci0gICAgICAgICAgdGhyb3cgbmV3IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiggZXggKTsKLSAgICAgICAgfSBjYXRjaCggamF2YXgueG1sLnBhcnNlcnMuRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvciBleDEgKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uKCBleDEudG9TdHJpbmcoKSApOwotICAgICAgICB9IGNhdGNoKCBOb1N1Y2hNZXRob2RFcnJvciBleDIgKSB7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKEFic3RyYWN0TWV0aG9kRXJyb3IgYW1lKXt9Ci0gICAgICAgIGlmKG51bGwgPT0gcmVhZGVyKQotICAgICAgICAgIHJlYWRlciA9IFhNTFJlYWRlckZhY3RvcnkuY3JlYXRlWE1MUmVhZGVyKCk7Ci0gICAgICB9Ci0KLSAgICAgIHRyeQotICAgICAgewotICAgICAgICByZWFkZXIuc2V0RmVhdHVyZSgiaHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL25hbWVzcGFjZS1wcmVmaXhlcyIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUpOwotICAgICAgfQotICAgICAgY2F0Y2ggKG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBzZSkKLSAgICAgIHsKLQotICAgICAgICAvLyBXaGF0IGNhbiB3ZSBkbz8KLSAgICAgICAgLy8gVE9ETzogVXNlciBkaWFnbm9zdGljcy4KLSAgICAgIH0KLQotICAgICAgcmV0dXJuIHJlYWRlcjsKLSAgICB9Ci0gICAgY2F0Y2ggKG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBzZSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oc2UuZ2V0TWVzc2FnZSgpLCBsb2NhdG9yLCBzZSk7Ci0gICAgfQotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL1ZhcmlhYmxlU3RhY2suamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvVmFyaWFibGVTdGFjay5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkMjE5YTE4Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvVmFyaWFibGVTdGFjay5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTIwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFZhcmlhYmxlU3RhY2suamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xMCAxODoxNjoyMiBqZWZmc3V0dG9yIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC5yZXMuWFNMTWVzc2FnZXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWE9iamVjdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucmVzLlhQQVRIRXJyb3JSZXNvdXJjZXM7Ci0KLS8qKgotICogRGVmaW5lcyBhIGNsYXNzIHRvIGtlZXAgdHJhY2sgb2YgYSBzdGFjayBmb3IKLSAqIHRlbXBsYXRlIGFyZ3VtZW50cyBhbmQgdmFyaWFibGVzLgotICoKLSAqIDxwPlRoaXMgaGFzIGJlZW4gY2hhbmdlZCBmcm9tIHRoZSBwcmV2aW91cyBpbmNhcm5hdGlvbnMgb2YgdGhpcwotICogY2xhc3MgdG8gYmUgZmFpcmx5IGxvdyBsZXZlbC48L3A+Ci0gKiBAeHNsLnVzYWdlIGludGVybmFsCi0gKi8KLXB1YmxpYyBjbGFzcyBWYXJpYWJsZVN0YWNrIGltcGxlbWVudHMgQ2xvbmVhYmxlCi17Ci0gIC8qKgotICAgKiBsaW1pdGF0aW9uIGZvciAxSwotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ0xFQVJMSU1JVEFUSU9OPSAxMDI0OwotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3RvciBmb3IgYSB2YXJpYWJsZSBzdGFjay4KLSAgICovCi0gIHB1YmxpYyBWYXJpYWJsZVN0YWNrKCkKLSAgewotICAgIHJlc2V0KCk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyBhIGNsb25lIG9mIHRoaXMgdmFyaWFibGUgc3RhY2suCi0gICAqCi0gICAqIEByZXR1cm4gIGEgY2xvbmUgb2YgdGhpcyB2YXJpYWJsZSBzdGFjay4KLSAgICoKLSAgICogQHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHN5bmNocm9uaXplZCBPYmplY3QgY2xvbmUoKSB0aHJvd3MgQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24KLSAgewotCi0gICAgVmFyaWFibGVTdGFjayB2cyA9IChWYXJpYWJsZVN0YWNrKSBzdXBlci5jbG9uZSgpOwotCi0gICAgLy8gSSAqdGhpbmsqIEkgY2FuIGdldCBhd2F5IHdpdGggYSBzaGFsbG93IGNsb25lIGhlcmU/Ci0gICAgdnMuX3N0YWNrRnJhbWVzID0gKFhPYmplY3RbXSkgX3N0YWNrRnJhbWVzLmNsb25lKCk7Ci0gICAgdnMuX2xpbmtzID0gKGludFtdKSBfbGlua3MuY2xvbmUoKTsKLQotICAgIHJldHVybiB2czsKLSAgfQotCi0gIC8qKgotICAgKiBUaGUgc3RhY2sgZnJhbWUgd2hlcmUgYWxsIHZhcmlhYmxlcyBhbmQgcGFyYW1zIHdpbGwgYmUga2VwdC4KLSAgICogQHNlcmlhbAotICAgKi8KLSAgWE9iamVjdFtdIF9zdGFja0ZyYW1lcyA9IG5ldyBYT2JqZWN0W1hQYXRoQ29udGV4dC5SRUNVUlNJT05MSU1JVCAqIDJdOwotCi0gIC8qKgotICAgKiBUaGUgdG9wIG9mIHRoZSBzdGFjayBmcmFtZSAoPGNvZGU+X3N0YWNrRnJhbWVzPC9jb2RlPikuCi0gICAqIEBzZXJpYWwKLSAgICovCi0gIGludCBfZnJhbWVUb3A7Ci0KLSAgLyoqCi0gICAqIFRoZSBib3R0b20gaW5kZXggb2YgdGhlIGN1cnJlbnQgZnJhbWUgKHJlbGF0aXZlIHRvIDxjb2RlPl9zdGFja0ZyYW1lczwvY29kZT4pLgotICAgKiBAc2VyaWFsCi0gICAqLwotICBwcml2YXRlIGludCBfY3VycmVudEZyYW1lQm90dG9tOwotCi0gIC8qKgotICAgKiBUaGUgc3RhY2sgb2YgZnJhbWUgcG9zaXRpb25zLiAgSSBjYWxsICdlbSBsaW5rcyBiZWNhdXNlIG9mIGRpc3RhbnQKLSAgICogPGEgaHJlZj0iaHR0cDovL21hdGgubWlsbGlraW4uZWR1L21wcm9nZXJzL0NvdXJzZXMvY3VycmVudENvdXJzZXMvQ1M0ODEtQ29tcHV0ZXJBcmNoaXRlY3R1cmUvY3M0ODEuTW90b3JvbGE2ODAwMC5odG1sIj4KLSAgICogTW90b3JvbGEgNjgwMDAgYXNzZW1ibGVyPC9hPiBtZW1vcmllcy4gIDotKQotICAgKiBAc2VyaWFsCi0gICAqLwotICBpbnRbXSBfbGlua3MgPSBuZXcgaW50W1hQYXRoQ29udGV4dC5SRUNVUlNJT05MSU1JVF07Ci0KLSAgLyoqCi0gICAqIFRoZSB0b3Agb2YgdGhlIGxpbmtzIHN0YWNrLgotICAgKi8KLSAgaW50IF9saW5rc1RvcDsKLQotICAvKioKLSAgICogR2V0IHRoZSBlbGVtZW50IGF0IHRoZSBnaXZlbiBpbmRleCwgcmVnYXJkbGVzcyBvZiBzdGFja2ZyYW1lLgotICAgKgotICAgKiBAcGFyYW0gaSBpbmRleCBmcm9tIHplcm8uCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGl0ZW0gYXQgdGhlIGdpdmVuIGluZGV4LgotICAgKi8KLSAgcHVibGljIFhPYmplY3QgZWxlbWVudEF0KGZpbmFsIGludCBpKQotICB7Ci0gICAgcmV0dXJuIF9zdGFja0ZyYW1lc1tpXTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgc2l6ZSBvZiB0aGUgc3RhY2suCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIHRvdGFsIHNpemUgb2YgdGhlIGV4ZWN1dGlvbiBzdGFjay4KLSAgICovCi0gIHB1YmxpYyBpbnQgc2l6ZSgpCi0gIHsKLSAgICByZXR1cm4gX2ZyYW1lVG9wOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlc2V0IHRoZSBzdGFjayB0byBhIHN0YXJ0IHBvc2l0aW9uLgotICAgKgotICAgKiBAcmV0dXJuIHRoZSB0b3RhbCBzaXplIG9mIHRoZSBleGVjdXRpb24gc3RhY2suCi0gICAqLwotICBwdWJsaWMgdm9pZCByZXNldCgpCi0gIHsKLQotICAgIF9mcmFtZVRvcCA9IDA7Ci0gICAgX2xpbmtzVG9wID0gMDsKLQotICAgIC8vIEFkZGluZyBvbmUgaGVyZSB0byB0aGUgc3RhY2sgb2YgZnJhbWUgcG9zaXRpb25zIHdpbGwgYWxsb3cgdXMgYWx3YXlzCi0gICAgLy8gdG8gbG9vayBvbmUgdW5kZXIgd2l0aG91dCBoYXZpbmcgdG8gY2hlY2sgaWYgd2UncmUgYXQgemVyby4KLSAgICAvLyAoQXMgbG9uZyBhcyB0aGUgY2FsbGVyIGRvZXNuJ3Qgc2NyZXcgdXAgbGluay91bmxpbmsuKQotICAgIF9saW5rc1tfbGlua3NUb3ArK10gPSAwOwotICAgIF9zdGFja0ZyYW1lcyA9IG5ldyBYT2JqZWN0W19zdGFja0ZyYW1lcy5sZW5ndGhdOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgY3VycmVudCBzdGFjayBmcmFtZS4KLSAgICoKLSAgICogQHBhcmFtIHNmIFRoZSBuZXcgc3RhY2sgZnJhbWUgcG9zaXRpb24uCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRTdGFja0ZyYW1lKGludCBzZikKLSAgewotICAgIF9jdXJyZW50RnJhbWVCb3R0b20gPSBzZjsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIHBvc2l0aW9uIGZyb20gd2hlcmUgdGhlIHNlYXJjaCBzaG91bGQgc3RhcnQsCi0gICAqIHdoaWNoIGlzIGVpdGhlciB0aGUgc2VhcmNoU3RhcnQgcHJvcGVydHksIG9yIHRoZSB0b3AKLSAgICogb2YgdGhlIHN0YWNrIGlmIHRoYXQgdmFsdWUgaXMgLTEuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGN1cnJlbnQgc3RhY2sgZnJhbWUgcG9zaXRpb24uCi0gICAqLwotICBwdWJsaWMgaW50IGdldFN0YWNrRnJhbWUoKQotICB7Ci0gICAgcmV0dXJuIF9jdXJyZW50RnJhbWVCb3R0b207Ci0gIH0KLQotICAvKioKLSAgICogQWxsb2NhdGVzIG1lbW9yeSAoY2FsbGVkIGEgc3RhY2tmcmFtZSkgb24gdGhlIHN0YWNrOyB1c2VkIHRvIHN0b3JlCi0gICAqIGxvY2FsIHZhcmlhYmxlcyBhbmQgcGFyYW1ldGVyIGFyZ3VtZW50cy4KLSAgICoKLSAgICogPHA+SSB1c2UgdGhlIGxpbmsvdW5saW5rIGNvbmNlcHQgYmVjYXVzZSBvZiBkaXN0YW50Ci0gICAqIDxhIGhyZWY9Imh0dHA6Ly9tYXRoLm1pbGxpa2luLmVkdS9tcHJvZ2Vycy9Db3Vyc2VzL2N1cnJlbnRDb3Vyc2VzL0NTNDgxLUNvbXB1dGVyQXJjaGl0ZWN0dXJlL2NzNDgxLk1vdG9yb2xhNjgwMDAuaHRtbCI+Ci0gICAqIE1vdG9yb2xhIDY4MDAwIGFzc2VtYmxlcjwvYT4gbWVtb3JpZXMuPC9wPgotICAgKgotICAgKiBAcGFyYW0gc2l6ZSBUaGUgc2l6ZSBvZiB0aGUgc3RhY2sgZnJhbWUgYWxsb2NhdGlvbi4gIFRoaXMgYW1tb3VudCBzaG91bGQKLSAgICogbm9ybWFsbHkgYmUgdGhlIG1heGltdW0gbnVtYmVyIG9mIHZhcmlhYmxlcyB0aGF0IHlvdSBjYW4gaGF2ZSBhbGxvY2F0ZWQKLSAgICogYXQgb25lIHRpbWUgaW4gdGhlIG5ldyBzdGFjayBmcmFtZS4KLSAgICoKLSAgICogQHJldHVybiBUaGUgYm90dG9tIG9mIHRoZSBzdGFjayBmcmFtZSwgZnJvbSB3aGVyZSBsb2NhbCB2YXJpYWJsZSBhZGRyZXNzaW5nCi0gICAqIHNob3VsZCBzdGFydCBmcm9tLgotICAgKi8KLSAgcHVibGljIGludCBsaW5rKGZpbmFsIGludCBzaXplKQotICB7Ci0KLSAgICBfY3VycmVudEZyYW1lQm90dG9tID0gX2ZyYW1lVG9wOwotICAgIF9mcmFtZVRvcCArPSBzaXplOwotCi0gICAgaWYgKF9mcmFtZVRvcCA+PSBfc3RhY2tGcmFtZXMubGVuZ3RoKQotICAgIHsKLSAgICAgIFhPYmplY3QgbmV3c2ZbXSA9IG5ldyBYT2JqZWN0W19zdGFja0ZyYW1lcy5sZW5ndGggKyBYUGF0aENvbnRleHQuUkVDVVJTSU9OTElNSVQgKyBzaXplXTsKLQotICAgICAgU3lzdGVtLmFycmF5Y29weShfc3RhY2tGcmFtZXMsIDAsIG5ld3NmLCAwLCBfc3RhY2tGcmFtZXMubGVuZ3RoKTsKLQotICAgICAgX3N0YWNrRnJhbWVzID0gbmV3c2Y7Ci0gICAgfQotCi0gICAgaWYgKF9saW5rc1RvcCArIDEgPj0gX2xpbmtzLmxlbmd0aCkKLSAgICB7Ci0gICAgICBpbnQgbmV3bGlua3NbXSA9IG5ldyBpbnRbX2xpbmtzLmxlbmd0aCArIChDTEVBUkxJTUlUQVRJT04gKiAyKV07Ci0KLSAgICAgIFN5c3RlbS5hcnJheWNvcHkoX2xpbmtzLCAwLCBuZXdsaW5rcywgMCwgX2xpbmtzLmxlbmd0aCk7Ci0KLSAgICAgIF9saW5rcyA9IG5ld2xpbmtzOwotICAgIH0KLQotICAgIF9saW5rc1tfbGlua3NUb3ArK10gPSBfY3VycmVudEZyYW1lQm90dG9tOwotCi0gICAgcmV0dXJuIF9jdXJyZW50RnJhbWVCb3R0b207Ci0gIH0KLQotICAvKioKLSAgICogRnJlZSB1cCB0aGUgc3RhY2sgZnJhbWUgdGhhdCB3YXMgbGFzdCBhbGxvY2F0ZWQgd2l0aAotICAgKiB7QGxpbmsgI2xpbmsoaW50IHNpemUpfS4KLSAgICovCi0gIHB1YmxpYyAgdm9pZCB1bmxpbmsoKQotICB7Ci0gICAgX2ZyYW1lVG9wID0gX2xpbmtzWy0tX2xpbmtzVG9wXTsKLSAgICBfY3VycmVudEZyYW1lQm90dG9tID0gX2xpbmtzW19saW5rc1RvcCAtIDFdOwotICB9Ci0KLSAgLyoqCi0gICAqIEZyZWUgdXAgdGhlIHN0YWNrIGZyYW1lIHRoYXQgd2FzIGxhc3QgYWxsb2NhdGVkIHdpdGgKLSAgICoge0BsaW5rICNsaW5rKGludCBzaXplKX0uCi0gICAqIEBwYXJhbSBjdXJyZW50RnJhbWUgVGhlIGN1cnJlbnQgZnJhbWUgdG8gc2V0IHRvCi0gICAqIGFmdGVyIHRoZSB1bmxpbmsuCi0gICAqLwotICBwdWJsaWMgIHZvaWQgdW5saW5rKGludCBjdXJyZW50RnJhbWUpCi0gIHsKLSAgICBfZnJhbWVUb3AgPSBfbGlua3NbLS1fbGlua3NUb3BdOwotICAgIF9jdXJyZW50RnJhbWVCb3R0b20gPSBjdXJyZW50RnJhbWU7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IGEgbG9jYWwgdmFyaWFibGUgb3IgcGFyYW1ldGVyIGluIHRoZSBjdXJyZW50IHN0YWNrIGZyYW1lLgotICAgKgotICAgKgotICAgKiBAcGFyYW0gaW5kZXggTG9jYWwgdmFyaWFibGUgaW5kZXggcmVsYXRpdmUgdG8gdGhlIGN1cnJlbnQgc3RhY2sKLSAgICogZnJhbWUgYm90dG9tLgotICAgKgotICAgKiBAcGFyYW0gdmFsIFRoZSB2YWx1ZSBvZiB0aGUgdmFyaWFibGUgdGhhdCBpcyBiZWluZyBzZXQuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRMb2NhbFZhcmlhYmxlKGludCBpbmRleCwgWE9iamVjdCB2YWwpCi0gIHsKLSAgICBfc3RhY2tGcmFtZXNbaW5kZXggKyBfY3VycmVudEZyYW1lQm90dG9tXSA9IHZhbDsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgYSBsb2NhbCB2YXJpYWJsZSBvciBwYXJhbWV0ZXIgaW4gdGhlIHNwZWNpZmllZCBzdGFjayBmcmFtZS4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIGluZGV4IExvY2FsIHZhcmlhYmxlIGluZGV4IHJlbGF0aXZlIHRvIHRoZSBjdXJyZW50IHN0YWNrCi0gICAqIGZyYW1lIGJvdHRvbS4KLSAgICogTkVFRFNET0MgQHBhcmFtIHN0YWNrRnJhbWUKLSAgICoKLSAgICogQHBhcmFtIHZhbCBUaGUgdmFsdWUgb2YgdGhlIHZhcmlhYmxlIHRoYXQgaXMgYmVpbmcgc2V0LgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0TG9jYWxWYXJpYWJsZShpbnQgaW5kZXgsIFhPYmplY3QgdmFsLCBpbnQgc3RhY2tGcmFtZSkKLSAgewotICAgIF9zdGFja0ZyYW1lc1tpbmRleCArIHN0YWNrRnJhbWVdID0gdmFsOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBhIGxvY2FsIHZhcmlhYmxlIG9yIHBhcmFtZXRlciBpbiB0aGUgY3VycmVudCBzdGFjayBmcmFtZS4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IFRoZSBYUGF0aCBjb250ZXh0LCB3aGljaCBtdXN0IGJlIHBhc3NlZCBpbiBvcmRlciB0bwotICAgKiBsYXp5IGV2YWx1YXRlIHZhcmlhYmxlcy4KLSAgICoKLSAgICogQHBhcmFtIGluZGV4IExvY2FsIHZhcmlhYmxlIGluZGV4IHJlbGF0aXZlIHRvIHRoZSBjdXJyZW50IHN0YWNrCi0gICAqIGZyYW1lIGJvdHRvbS4KLSAgICoKLSAgICogQHJldHVybiBUaGUgdmFsdWUgb2YgdGhlIHZhcmlhYmxlLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBnZXRMb2NhbFZhcmlhYmxlKFhQYXRoQ29udGV4dCB4Y3R4dCwgaW50IGluZGV4KQotICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpbmRleCArPSBfY3VycmVudEZyYW1lQm90dG9tOwotCi0gICAgWE9iamVjdCB2YWwgPSBfc3RhY2tGcmFtZXNbaW5kZXhdOwotCi0gICAgaWYobnVsbCA9PSB2YWwpCi0gICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfVkFSSUFCTEVfQUNDRVNTRURfQkVGT1JFX0JJTkQsIG51bGwpLAotICAgICAgICAgICAgICAgICAgICAgeGN0eHQuZ2V0U0FYTG9jYXRvcigpKTsKLSAgICAgIC8vICJWYXJpYWJsZSBhY2Nlc3NlZCBiZWZvcmUgaXQgaXMgYm91bmQhIiwgeGN0eHQuZ2V0U0FYTG9jYXRvcigpKTsKLQotICAgIC8vIExhenkgZXhlY3V0aW9uIG9mIHZhcmlhYmxlcy4KLSAgICBpZiAodmFsLmdldFR5cGUoKSA9PSBYT2JqZWN0LkNMQVNTX1VOUkVTT0xWRURWQVJJQUJMRSkKLSAgICAgIHJldHVybiAoX3N0YWNrRnJhbWVzW2luZGV4XSA9IHZhbC5leGVjdXRlKHhjdHh0KSk7Ci0KLSAgICByZXR1cm4gdmFsOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBhIGxvY2FsIHZhcmlhYmxlIG9yIHBhcmFtZXRlciBpbiB0aGUgY3VycmVudCBzdGFjayBmcmFtZS4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIGluZGV4IExvY2FsIHZhcmlhYmxlIGluZGV4IHJlbGF0aXZlIHRvIHRoZSBnaXZlbgotICAgKiBmcmFtZSBib3R0b20uCi0gICAqIE5FRURTRE9DIEBwYXJhbSBmcmFtZQotICAgKgotICAgKiBAcmV0dXJuIFRoZSB2YWx1ZSBvZiB0aGUgdmFyaWFibGUuCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IGdldExvY2FsVmFyaWFibGUoaW50IGluZGV4LCBpbnQgZnJhbWUpCi0gICAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGluZGV4ICs9IGZyYW1lOwotCi0gICAgWE9iamVjdCB2YWwgPSBfc3RhY2tGcmFtZXNbaW5kZXhdOwotCi0gICAgcmV0dXJuIHZhbDsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgYSBsb2NhbCB2YXJpYWJsZSBvciBwYXJhbWV0ZXIgaW4gdGhlIGN1cnJlbnQgc3RhY2sgZnJhbWUuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgWFBhdGggY29udGV4dCwgd2hpY2ggbXVzdCBiZSBwYXNzZWQgaW4gb3JkZXIgdG8KLSAgICogbGF6eSBldmFsdWF0ZSB2YXJpYWJsZXMuCi0gICAqCi0gICAqIEBwYXJhbSBpbmRleCBMb2NhbCB2YXJpYWJsZSBpbmRleCByZWxhdGl2ZSB0byB0aGUgY3VycmVudCBzdGFjawotICAgKiBmcmFtZSBib3R0b20uCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHZhbHVlIG9mIHRoZSB2YXJpYWJsZS4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFhPYmplY3QgZ2V0TG9jYWxWYXJpYWJsZShYUGF0aENvbnRleHQgeGN0eHQsIGludCBpbmRleCwgYm9vbGVhbiBkZXN0cnVjdGl2ZU9LKQotICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpbmRleCArPSBfY3VycmVudEZyYW1lQm90dG9tOwotCi0gICAgWE9iamVjdCB2YWwgPSBfc3RhY2tGcmFtZXNbaW5kZXhdOwotCi0gICAgaWYobnVsbCA9PSB2YWwpCi0gICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfVkFSSUFCTEVfQUNDRVNTRURfQkVGT1JFX0JJTkQsIG51bGwpLAotICAgICAgICAgICAgICAgICAgICAgeGN0eHQuZ2V0U0FYTG9jYXRvcigpKTsKLSAgICAgIC8vICJWYXJpYWJsZSBhY2Nlc3NlZCBiZWZvcmUgaXQgaXMgYm91bmQhIiwgeGN0eHQuZ2V0U0FYTG9jYXRvcigpKTsKLQotICAgIC8vIExhenkgZXhlY3V0aW9uIG9mIHZhcmlhYmxlcy4KLSAgICBpZiAodmFsLmdldFR5cGUoKSA9PSBYT2JqZWN0LkNMQVNTX1VOUkVTT0xWRURWQVJJQUJMRSkKLSAgICAgIHJldHVybiAoX3N0YWNrRnJhbWVzW2luZGV4XSA9IHZhbC5leGVjdXRlKHhjdHh0KSk7Ci0KLSAgICByZXR1cm4gZGVzdHJ1Y3RpdmVPSyA/IHZhbCA6IHZhbC5nZXRGcmVzaCgpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgYSBsb2NhbCB2YXJpYWJsZSBoYXMgYmVlbiBzZXQgb3Igbm90LgotICAgKgotICAgKiBAcGFyYW0gaW5kZXggTG9jYWwgdmFyaWFibGUgaW5kZXggcmVsYXRpdmUgdG8gdGhlIGN1cnJlbnQgc3RhY2sKLSAgICogZnJhbWUgYm90dG9tLgotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHZhbHVlIGF0IHRoZSBpbmRleCBpcyBub3QgbnVsbC4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNMb2NhbFNldChpbnQgaW5kZXgpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIChfc3RhY2tGcmFtZXNbaW5kZXggKyBfY3VycmVudEZyYW1lQm90dG9tXSAhPSBudWxsKTsKLSAgfQotCi0gIC8qKiBORUVEU0RPQyBGaWVsZCBtX251bGxzICAgICAgICAgICovCi0gIHByaXZhdGUgc3RhdGljIFhPYmplY3RbXSBtX251bGxzID0gbmV3IFhPYmplY3RbQ0xFQVJMSU1JVEFUSU9OXTsKLQotICAvKioKLSAgICogVXNlIHRoaXMgdG8gY2xlYXIgdGhlIHZhcmlhYmxlcyBpbiBhIHNlY3Rpb24gb2YgdGhlIHN0YWNrLiAgVGhpcyBpcwotICAgKiB1c2VkIHRvIGNsZWFyIHRoZSBwYXJhbWV0ZXIgc2VjdGlvbiBvZiB0aGUgc3RhY2ssIHNvIHRoYXQgZGVmYXVsdCBwYXJhbQotICAgKiB2YWx1ZXMgY2FuIHRlbGwgaWYgdGhleSd2ZSBhbHJlYWR5IGJlZW4gc2V0LiAgSXQgaXMgaW1wb3J0YW50IHRvIG5vdGUgdGhhdAotICAgKiB0aGlzIGZ1bmN0aW9uIGhhcyBhIDFLIGxpbWl0YXRpb24uCi0gICAqCi0gICAqIEBwYXJhbSBzdGFydCBUaGUgc3RhcnQgcG9zaXRpb24sIHJlbGF0aXZlIHRvIHRoZSBjdXJyZW50IGxvY2FsIHN0YWNrIGZyYW1lLgotICAgKiBAcGFyYW0gbGVuIFRoZSBudW1iZXIgb2Ygc2xvdHMgdG8gYmUgY2xlYXJlZC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGNsZWFyTG9jYWxTbG90cyhpbnQgc3RhcnQsIGludCBsZW4pCi0gIHsKLQotICAgIHN0YXJ0ICs9IF9jdXJyZW50RnJhbWVCb3R0b207Ci0KLSAgICBTeXN0ZW0uYXJyYXljb3B5KG1fbnVsbHMsIDAsIF9zdGFja0ZyYW1lcywgc3RhcnQsIGxlbik7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IGEgZ2xvYmFsIHZhcmlhYmxlIG9yIHBhcmFtZXRlciBpbiB0aGUgZ2xvYmFsIHN0YWNrIGZyYW1lLgotICAgKgotICAgKgotICAgKiBAcGFyYW0gaW5kZXggTG9jYWwgdmFyaWFibGUgaW5kZXggcmVsYXRpdmUgdG8gdGhlIGdsb2JhbCBzdGFjayBmcmFtZQotICAgKiBib3R0b20uCi0gICAqCi0gICAqIEBwYXJhbSB2YWwgVGhlIHZhbHVlIG9mIHRoZSB2YXJpYWJsZSB0aGF0IGlzIGJlaW5nIHNldC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldEdsb2JhbFZhcmlhYmxlKGZpbmFsIGludCBpbmRleCwgZmluYWwgWE9iamVjdCB2YWwpCi0gIHsKLSAgICBfc3RhY2tGcmFtZXNbaW5kZXhdID0gdmFsOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBhIGdsb2JhbCB2YXJpYWJsZSBvciBwYXJhbWV0ZXIgZnJvbSB0aGUgZ2xvYmFsIHN0YWNrIGZyYW1lLgotICAgKgotICAgKgotICAgKiBAcGFyYW0geGN0eHQgVGhlIFhQYXRoIGNvbnRleHQsIHdoaWNoIG11c3QgYmUgcGFzc2VkIGluIG9yZGVyIHRvCi0gICAqIGxhenkgZXZhbHVhdGUgdmFyaWFibGVzLgotICAgKgotICAgKiBAcGFyYW0gaW5kZXggR2xvYmFsIHZhcmlhYmxlIGluZGV4IHJlbGF0aXZlIHRvIHRoZSBnbG9iYWwgc3RhY2sKLSAgICogZnJhbWUgYm90dG9tLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSB2YWx1ZSBvZiB0aGUgdmFyaWFibGUuCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IGdldEdsb2JhbFZhcmlhYmxlKFhQYXRoQ29udGV4dCB4Y3R4dCwgZmluYWwgaW50IGluZGV4KQotICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBYT2JqZWN0IHZhbCA9IF9zdGFja0ZyYW1lc1tpbmRleF07Ci0KLSAgICAvLyBMYXp5IGV4ZWN1dGlvbiBvZiB2YXJpYWJsZXMuCi0gICAgaWYgKHZhbC5nZXRUeXBlKCkgPT0gWE9iamVjdC5DTEFTU19VTlJFU09MVkVEVkFSSUFCTEUpCi0gICAgICByZXR1cm4gKF9zdGFja0ZyYW1lc1tpbmRleF0gPSB2YWwuZXhlY3V0ZSh4Y3R4dCkpOwotCi0gICAgcmV0dXJuIHZhbDsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgYSBnbG9iYWwgdmFyaWFibGUgb3IgcGFyYW1ldGVyIGZyb20gdGhlIGdsb2JhbCBzdGFjayBmcmFtZS4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IFRoZSBYUGF0aCBjb250ZXh0LCB3aGljaCBtdXN0IGJlIHBhc3NlZCBpbiBvcmRlciB0bwotICAgKiBsYXp5IGV2YWx1YXRlIHZhcmlhYmxlcy4KLSAgICoKLSAgICogQHBhcmFtIGluZGV4IEdsb2JhbCB2YXJpYWJsZSBpbmRleCByZWxhdGl2ZSB0byB0aGUgZ2xvYmFsIHN0YWNrCi0gICAqIGZyYW1lIGJvdHRvbS4KLSAgICoKLSAgICogQHJldHVybiBUaGUgdmFsdWUgb2YgdGhlIHZhcmlhYmxlLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBnZXRHbG9iYWxWYXJpYWJsZShYUGF0aENvbnRleHQgeGN0eHQsIGZpbmFsIGludCBpbmRleCwgYm9vbGVhbiBkZXN0cnVjdGl2ZU9LKQotICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBYT2JqZWN0IHZhbCA9IF9zdGFja0ZyYW1lc1tpbmRleF07Ci0KLSAgICAvLyBMYXp5IGV4ZWN1dGlvbiBvZiB2YXJpYWJsZXMuCi0gICAgaWYgKHZhbC5nZXRUeXBlKCkgPT0gWE9iamVjdC5DTEFTU19VTlJFU09MVkVEVkFSSUFCTEUpCi0gICAgICByZXR1cm4gKF9zdGFja0ZyYW1lc1tpbmRleF0gPSB2YWwuZXhlY3V0ZSh4Y3R4dCkpOwotCi0gICAgcmV0dXJuIGRlc3RydWN0aXZlT0sgPyB2YWwgOiB2YWwuZ2V0RnJlc2goKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgYSB2YXJpYWJsZSBiYXNlZCBvbiBpdCdzIHF1YWxpZmllZCBuYW1lLgotICAgKiBUaGlzIGlzIGZvciBleHRlcm5hbCB1c2Ugb25seS4KLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IFRoZSBYUGF0aCBjb250ZXh0LCB3aGljaCBtdXN0IGJlIHBhc3NlZCBpbiBvcmRlciB0bwotICAgKiBsYXp5IGV2YWx1YXRlIHZhcmlhYmxlcy4KLSAgICoKLSAgICogQHBhcmFtIHFuYW1lIFRoZSBxdWFsaWZpZWQgbmFtZSBvZiB0aGUgdmFyaWFibGUuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGV2YWx1YXRlZCB2YWx1ZSBvZiB0aGUgdmFyaWFibGUuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFhPYmplY3QgZ2V0VmFyaWFibGVPclBhcmFtKAotICAgICAgICAgIFhQYXRoQ29udGV4dCB4Y3R4dCwgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5RTmFtZSBxbmFtZSkKLSAgICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIC8vIEoyU0UgZG9lcyBub3Qgc3VwcG9ydCBYYWxhbiBpbnRlcnByZXRpdmUKLSAgICAgICAgLyoKLSAgICBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLlByZWZpeFJlc29sdmVyIHByZWZpeFJlc29sdmVyID0KLSAgICAgIHhjdHh0LmdldE5hbWVzcGFjZUNvbnRleHQoKTsKLQotICAgIC8vIEdldCB0aGUgY3VycmVudCBFbGVtVGVtcGxhdGVFbGVtZW50LCB3aGljaCBtdXN0IGJlIHB1c2hlZCBpbiBhcyB0aGUKLSAgICAvLyBwcmVmaXggcmVzb2x2ZXIsIGFuZCB0aGVuIHdhbGsgYmFja3dhcmRzIGluIGRvY3VtZW50IG9yZGVyLCBzZWFyY2hpbmcKLSAgICAvLyBmb3IgYW4geHNsOnBhcmFtIGVsZW1lbnQgb3IgeHNsOnZhcmlhYmxlIGVsZW1lbnQgdGhhdCBtYXRjaGVzIG91cgotICAgIC8vIHFuYW1lLiAgSWYgd2UgcmVhY2ggdGhlIHRvcCBsZXZlbCwgdXNlIHRoZSBTdHlsZXNoZWV0Um9vdCdzIGNvbXBvc2VkCi0gICAgLy8gbGlzdCBvZiB0b3AgbGV2ZWwgdmFyaWFibGVzIGFuZCBwYXJhbWV0ZXJzLgotCi0gICAgaWYgKHByZWZpeFJlc29sdmVyIGluc3RhbmNlb2YgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnRlbXBsYXRlcy5FbGVtVGVtcGxhdGVFbGVtZW50KQotICAgIHsKLQotICAgICAgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnRlbXBsYXRlcy5FbGVtVmFyaWFibGUgdnZhcjsKLQotICAgICAgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnRlbXBsYXRlcy5FbGVtVGVtcGxhdGVFbGVtZW50IHByZXYgPQotICAgICAgICAoY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnRlbXBsYXRlcy5FbGVtVGVtcGxhdGVFbGVtZW50KSBwcmVmaXhSZXNvbHZlcjsKLQotICAgICAgaWYgKCEocHJldiBpbnN0YW5jZW9mIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC50ZW1wbGF0ZXMuU3R5bGVzaGVldCkpCi0gICAgICB7Ci0gICAgICAgIHdoaWxlICggIShwcmV2LmdldFBhcmVudE5vZGUoKSBpbnN0YW5jZW9mIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC50ZW1wbGF0ZXMuU3R5bGVzaGVldCkgKQotICAgICAgICB7Ci0gICAgICAgICAgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnRlbXBsYXRlcy5FbGVtVGVtcGxhdGVFbGVtZW50IHNhdmVkcHJldiA9IHByZXY7Ci0KLSAgICAgICAgICB3aGlsZSAobnVsbCAhPSAocHJldiA9IHByZXYuZ2V0UHJldmlvdXNTaWJsaW5nRWxlbSgpKSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBpZiAocHJldiBpbnN0YW5jZW9mIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC50ZW1wbGF0ZXMuRWxlbVZhcmlhYmxlKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICB2dmFyID0gKGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC50ZW1wbGF0ZXMuRWxlbVZhcmlhYmxlKSBwcmV2OwotCi0gICAgICAgICAgICAgIGlmICh2dmFyLmdldE5hbWUoKS5lcXVhbHMocW5hbWUpKQotICAgICAgICAgICAgICAgIHJldHVybiBnZXRMb2NhbFZhcmlhYmxlKHhjdHh0LCB2dmFyLmdldEluZGV4KCkpOwotICAgICAgICAgICAgfQotICAgICAgICAgIH0KLSAgICAgICAgICBwcmV2ID0gc2F2ZWRwcmV2LmdldFBhcmVudEVsZW0oKTsKLSAgICAgICAgfQotICAgICAgfQotCi0gICAgICB2dmFyID0gcHJldi5nZXRTdHlsZXNoZWV0Um9vdCgpLmdldFZhcmlhYmxlT3JQYXJhbUNvbXBvc2VkKHFuYW1lKTsKLSAgICAgIGlmIChudWxsICE9IHZ2YXIpCi0gICAgICAgIHJldHVybiBnZXRHbG9iYWxWYXJpYWJsZSh4Y3R4dCwgdnZhci5nZXRJbmRleCgpKTsKLSAgICB9Ci0gICAgKi8KLQotICAgIHRocm93IG5ldyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShYUEFUSEVycm9yUmVzb3VyY2VzLkVSX1ZBUl9OT1RfUkVTT0xWQUJMRSwgbmV3IE9iamVjdFtde3FuYW1lLnRvU3RyaW5nKCl9KSk7IC8vIlZhcmlhYmxlIG5vdCByZXNvbHZhYmxlOiAiICsgcW5hbWUpOwotICB9Ci19ICAvLyBlbmQgVmFyaWFibGVTdGFjawpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9XaGl0ZXNwYWNlU3RyaXBwaW5nRWxlbWVudE1hdGNoZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvV2hpdGVzcGFjZVN0cmlwcGluZ0VsZW1lbnRNYXRjaGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGRjNWQ5NzUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9XaGl0ZXNwYWNlU3RyaXBwaW5nRWxlbWVudE1hdGNoZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDU2ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFdoaXRlc3BhY2VTdHJpcHBpbmdFbGVtZW50TWF0Y2hlci5qYXZhLHYgMS4xLjIuMSAyMDA1LzA4LzAxIDAxOjMwOjE1IGplZmZzdXR0b3IgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWw7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotCi1pbXBvcnQgb3JnLnczYy5kb20uRWxlbWVudDsKLQotLyoqCi0gKiBBIGNsYXNzIHRoYXQgaW1wbGVtZW50cyB0aGlzIGludGVyZmFjZSBjYW4gdGVsbCBpZiBhIGdpdmVuIGVsZW1lbnQgc2hvdWxkCi0gKiBzdHJpcCB3aGl0ZXNwYWNlIG5vZGVzIGZyb20gaXQncyBjaGlsZHJlbi4KLSAqLwotcHVibGljIGludGVyZmFjZSBXaGl0ZXNwYWNlU3RyaXBwaW5nRWxlbWVudE1hdGNoZXIKLXsKLSAgLyoqCi0gICAqIEdldCBpbmZvcm1hdGlvbiBhYm91dCB3aGV0aGVyIG9yIG5vdCBhbiBlbGVtZW50IHNob3VsZCBzdHJpcCB3aGl0ZXNwYWNlLgotICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjc3RyaXAiPnN0cmlwIGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAgICoKLSAgICogQHBhcmFtIHN1cHBvcnQgVGhlIFhQYXRoIHJ1bnRpbWUgc3RhdGUuCi0gICAqIEBwYXJhbSB0YXJnZXRFbGVtZW50IEVsZW1lbnQgdG8gY2hlY2sKLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHRoZSB3aGl0ZXNwYWNlIHNob3VsZCBiZSBzdHJpcHBlZC4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gc2hvdWxkU3RyaXBXaGl0ZVNwYWNlKAotICAgICAgICAgIFhQYXRoQ29udGV4dCBzdXBwb3J0LCBFbGVtZW50IHRhcmdldEVsZW1lbnQpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLQotICAvKioKLSAgICogR2V0IGluZm9ybWF0aW9uIGFib3V0IHdoZXRoZXIgb3Igbm90IHdoaXRlc3BhY2UgY2FuIGJlIHN0cmlwcGVkLgotICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjc3RyaXAiPnN0cmlwIGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHRoZSB3aGl0ZXNwYWNlIGNhbiBiZSBzdHJpcHBlZC4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGNhblN0cmlwV2hpdGVTcGFjZSgpOwotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9YUGF0aC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9YUGF0aC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxNjAxYWUxLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvWFBhdGguamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDY0NSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBYUGF0aC5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE1IDAxOjQxOjU3IGplZmZzdXR0b3IgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWw7Ci0KLWltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uRXJyb3JMaXN0ZW5lcjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlNvdXJjZUxvY2F0b3I7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC5yZXMuWFNMTWVzc2FnZXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuUHJlZml4UmVzb2x2ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5TQVhTb3VyY2VMb2NhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5jb21waWxlci5Db21waWxlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuY29tcGlsZXIuRnVuY3Rpb25UYWJsZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuY29tcGlsZXIuWFBhdGhQYXJzZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmZ1bmN0aW9ucy5GdW5jdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YT2JqZWN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5yZXMuWFBBVEhFcnJvclJlc291cmNlczsKLQotLyoqCi0gKiBUaGUgWFBhdGggY2xhc3Mgd3JhcHMgYW4gZXhwcmVzc2lvbiBvYmplY3QgYW5kIHByb3ZpZGVzIGdlbmVyYWwgc2VydmljZXMKLSAqIGZvciBleGVjdXRpb24gb2YgdGhhdCBleHByZXNzaW9uLgotICogQHhzbC51c2FnZSBhZHZhbmNlZAotICovCi1wdWJsaWMgY2xhc3MgWFBhdGggaW1wbGVtZW50cyBTZXJpYWxpemFibGUsIEV4cHJlc3Npb25Pd25lcgotewotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAzOTc2NDkzNDc3OTM5MTEwNTUzTDsKLQotICAvKiogVGhlIHRvcCBvZiB0aGUgZXhwcmVzc2lvbiB0cmVlLgotICAgKiAgQHNlcmlhbCAqLwotICBwcml2YXRlIEV4cHJlc3Npb24gbV9tYWluRXhwOwotCi0gIC8qKgotICAgKiBUaGUgZnVuY3Rpb24gdGFibGUgZm9yIHhwYXRoIGJ1aWxkLWluIGZ1bmN0aW9ucwotICAgKi8KLSAgcHJpdmF0ZSB0cmFuc2llbnQgRnVuY3Rpb25UYWJsZSBtX2Z1bmNUYWJsZSA9IG51bGw7Ci0KLSAgLyoqCi0gICAqIGluaXRpYWwgdGhlIGZ1bmN0aW9uIHRhYmxlCi0gICAqLwotICBwcml2YXRlIHZvaWQgaW5pdEZ1bmN0aW9uVGFibGUoKXsKLSAgICAgICAgICAgICAgbV9mdW5jVGFibGUgPSBuZXcgRnVuY3Rpb25UYWJsZSgpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgcmF3IEV4cHJlc3Npb24gb2JqZWN0IHRoYXQgdGhpcyBjbGFzcyB3cmFwcy4KLSAgICoKLSAgICoKLSAgICogQHJldHVybiB0aGUgcmF3IEV4cHJlc3Npb24gb2JqZWN0LCB3aGljaCBzaG91bGQgbm90IG5vcm1hbGx5IGJlIG51bGwuCi0gICAqLwotICBwdWJsaWMgRXhwcmVzc2lvbiBnZXRFeHByZXNzaW9uKCkKLSAgewotICAgIHJldHVybiBtX21haW5FeHA7Ci0gIH0KLQotICAvKioKLSAgICogVGhpcyBmdW5jdGlvbiBpcyB1c2VkIHRvIGZpeHVwIHZhcmlhYmxlcyBmcm9tIFFOYW1lcyB0byBzdGFjayBmcmFtZQotICAgKiBpbmRleGVzIGF0IHN0eWxlc2hlZXQgYnVpbGQgdGltZS4KLSAgICogQHBhcmFtIHZhcnMgTGlzdCBvZiBRTmFtZXMgdGhhdCBjb3JyZXNwb25kIHRvIHZhcmlhYmxlcy4gIFRoaXMgbGlzdAotICAgKiBzaG91bGQgYmUgc2VhcmNoZWQgYmFja3dhcmRzIGZvciB0aGUgZmlyc3QgcXVhbGlmaWVkIG5hbWUgdGhhdAotICAgKiBjb3JyZXNwb25kcyB0byB0aGUgdmFyaWFibGUgcmVmZXJlbmNlIHFuYW1lLiAgVGhlIHBvc2l0aW9uIG9mIHRoZQotICAgKiBRTmFtZSBpbiB0aGUgdmVjdG9yIGZyb20gdGhlIHN0YXJ0IG9mIHRoZSB2ZWN0b3Igd2lsbCBiZSBpdHMgcG9zaXRpb24KLSAgICogaW4gdGhlIHN0YWNrIGZyYW1lIChidXQgdmFyaWFibGVzIGFib3ZlIHRoZSBnbG9iYWxzVG9wIHZhbHVlIHdpbGwgbmVlZAotICAgKiB0byBiZSBvZmZzZXQgdG8gdGhlIGN1cnJlbnQgc3RhY2sgZnJhbWUpLgotICAgKi8KLSAgcHVibGljIHZvaWQgZml4dXBWYXJpYWJsZXMoamF2YS51dGlsLlZlY3RvciB2YXJzLCBpbnQgZ2xvYmFsc1NpemUpCi0gIHsKLSAgICBtX21haW5FeHAuZml4dXBWYXJpYWJsZXModmFycywgZ2xvYmFsc1NpemUpOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgcmF3IGV4cHJlc3Npb24gb2JqZWN0IGZvciB0aGlzIG9iamVjdC4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIGV4cCB0aGUgcmF3IEV4cHJlc3Npb24gb2JqZWN0LCB3aGljaCBzaG91bGQgbm90IG5vcm1hbGx5IGJlIG51bGwuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRFeHByZXNzaW9uKEV4cHJlc3Npb24gZXhwKQotICB7Ci0gICAgICAgIGlmKG51bGwgIT0gbV9tYWluRXhwKQotICAgICAgICBleHAuZXhwclNldFBhcmVudChtX21haW5FeHAuZXhwckdldFBhcmVudCgpKTsgLy8gYSBiaXQgYm9ndXMKLSAgICBtX21haW5FeHAgPSBleHA7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBTb3VyY2VMb2NhdG9yIG9uIHRoZSBleHByZXNzaW9uIG9iamVjdC4KLSAgICoKLSAgICoKLSAgICogQHJldHVybiB0aGUgU291cmNlTG9jYXRvciBvbiB0aGUgZXhwcmVzc2lvbiBvYmplY3QsIHdoaWNoIG1heSBiZSBudWxsLgotICAgKi8KLSAgcHVibGljIFNvdXJjZUxvY2F0b3IgZ2V0TG9jYXRvcigpCi0gIHsKLSAgICByZXR1cm4gbV9tYWluRXhwOwotICB9Ci0KLS8vICAvKioKLS8vICAgKiBTZXQgdGhlIFNvdXJjZUxvY2F0b3Igb24gdGhlIGV4cHJlc3Npb24gb2JqZWN0LgotLy8gICAqCi0vLyAgICoKLS8vICAgKiBAcGFyYW0gbCB0aGUgU291cmNlTG9jYXRvciBvbiB0aGUgZXhwcmVzc2lvbiBvYmplY3QsIHdoaWNoIG1heSBiZSBudWxsLgotLy8gICAqLwotLy8gIHB1YmxpYyB2b2lkIHNldExvY2F0b3IoU291cmNlTG9jYXRvciBsKQotLy8gIHsKLS8vICAgIC8vIE5vdGUgcG90ZW50aWFsIGhhemFyZHMgLS0gbCBtYXkgbm90IGJlIHNlcmlhbGl6YWJsZSwgb3IgbWF5IGJlIGNoYW5nZWQKLS8vICAgICAgLy8gYWZ0ZXIgYmVpbmcgYXNzaWduZWQgaGVyZS4KLS8vICAgIG1fbWFpbkV4cC5zZXRTb3VyY2VMb2NhdG9yKGwpOwotLy8gIH0KLQotICAvKiogVGhlIHBhdHRlcm4gc3RyaW5nLCBtYWlubHkga2VwdCBhcm91bmQgZm9yIGRpYWdub3N0aWMgcHVycG9zZXMuCi0gICAqICBAc2VyaWFsICAqLwotICBTdHJpbmcgbV9wYXR0ZXJuU3RyaW5nOwotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIFhQYXRoIHN0cmluZyBhc3NvY2lhdGVkIHdpdGggdGhpcyBvYmplY3QuCi0gICAqCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIFhQYXRoIHN0cmluZyBhc3NvY2lhdGVkIHdpdGggdGhpcyBvYmplY3QuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFBhdHRlcm5TdHJpbmcoKQotICB7Ci0gICAgcmV0dXJuIG1fcGF0dGVyblN0cmluZzsKLSAgfQotCi0gIC8qKiBSZXByZXNlbnRzIGEgc2VsZWN0IHR5cGUgZXhwcmVzc2lvbi4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0VMRUNUID0gMDsKLQotICAvKiogUmVwcmVzZW50cyBhIG1hdGNoIHR5cGUgZXhwcmVzc2lvbi4gICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BVENIID0gMTsKLQotICAvKioKLSAgICogQ29uc3RydWN0IGFuIFhQYXRoIG9iamVjdC4KLSAgICoKLSAgICogKE5lZWRzIHJldmlldyAtc2MpIFRoaXMgbWV0aG9kIGluaXRpYWxpemVzIGFuIFhQYXRoUGFyc2VyLwotICAgKiBDb21waWxlciBhbmQgY29tcGlsZXMgdGhlIGV4cHJlc3Npb24uCi0gICAqIEBwYXJhbSBleHByU3RyaW5nIFRoZSBYUGF0aCBleHByZXNzaW9uLgotICAgKiBAcGFyYW0gbG9jYXRvciBUaGUgbG9jYXRpb24gb2YgdGhlIGV4cHJlc3Npb24sIG1heSBiZSBudWxsLgotICAgKiBAcGFyYW0gcHJlZml4UmVzb2x2ZXIgQSBwcmVmaXggcmVzb2x2ZXIgdG8gdXNlIHRvIHJlc29sdmUgcHJlZml4ZXMgdG8KLSAgICogICAgICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZSBVUklzLgotICAgKiBAcGFyYW0gdHlwZSBvbmUgb2Yge0BsaW5rICNTRUxFQ1R9IG9yIHtAbGluayAjTUFUQ0h9LgotICAgKiBAcGFyYW0gZXJyb3JMaXN0ZW5lciBUaGUgZXJyb3IgbGlzdGVuZXIsIG9yIG51bGwgaWYgZGVmYXVsdCBzaG91bGQgYmUgdXNlZC4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uIGlmIHN5bnRheCBvciBvdGhlciBlcnJvci4KLSAgICovCi0gIHB1YmxpYyBYUGF0aCgKLSAgICAgICAgICBTdHJpbmcgZXhwclN0cmluZywgU291cmNlTG9jYXRvciBsb2NhdG9yLCBQcmVmaXhSZXNvbHZlciBwcmVmaXhSZXNvbHZlciwgaW50IHR5cGUsCi0gICAgICAgICAgRXJyb3JMaXN0ZW5lciBlcnJvckxpc3RlbmVyKQotICAgICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIGluaXRGdW5jdGlvblRhYmxlKCk7Ci0gICAgaWYobnVsbCA9PSBlcnJvckxpc3RlbmVyKQotICAgICAgZXJyb3JMaXN0ZW5lciA9IG5ldyBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLkRlZmF1bHRFcnJvckhhbmRsZXIoKTsKLQotICAgIG1fcGF0dGVyblN0cmluZyA9IGV4cHJTdHJpbmc7Ci0KLSAgICBYUGF0aFBhcnNlciBwYXJzZXIgPSBuZXcgWFBhdGhQYXJzZXIoZXJyb3JMaXN0ZW5lciwgbG9jYXRvcik7Ci0gICAgQ29tcGlsZXIgY29tcGlsZXIgPSBuZXcgQ29tcGlsZXIoZXJyb3JMaXN0ZW5lciwgbG9jYXRvciwgbV9mdW5jVGFibGUpOwotCi0gICAgaWYgKFNFTEVDVCA9PSB0eXBlKQotICAgICAgcGFyc2VyLmluaXRYUGF0aChjb21waWxlciwgZXhwclN0cmluZywgcHJlZml4UmVzb2x2ZXIpOwotICAgIGVsc2UgaWYgKE1BVENIID09IHR5cGUpCi0gICAgICBwYXJzZXIuaW5pdE1hdGNoUGF0dGVybihjb21waWxlciwgZXhwclN0cmluZywgcHJlZml4UmVzb2x2ZXIpOwotICAgIGVsc2UKLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShYUEFUSEVycm9yUmVzb3VyY2VzLkVSX0NBTk5PVF9ERUFMX1hQQVRIX1RZUEUsIG5ldyBPYmplY3RbXXtJbnRlZ2VyLnRvU3RyaW5nKHR5cGUpfSkpOyAvLyJDYW4gbm90IGRlYWwgd2l0aCBYUGF0aCB0eXBlOiAiICsgdHlwZSk7Ci0KLSAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIi0tLS0tLS0tLS0tLS0tLS0iKTsKLSAgICBFeHByZXNzaW9uIGV4cHIgPSBjb21waWxlci5jb21waWxlKDApOwotCi0gICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJleHByOiAiK2V4cHIpOwotICAgIHRoaXMuc2V0RXhwcmVzc2lvbihleHByKTsKLQotICAgIGlmKChudWxsICE9IGxvY2F0b3IpICYmIGxvY2F0b3IgaW5zdGFuY2VvZiBFeHByZXNzaW9uTm9kZSkKLSAgICB7Ci0gICAgICAgIGV4cHIuZXhwclNldFBhcmVudCgoRXhwcmVzc2lvbk5vZGUpbG9jYXRvcik7Ci0gICAgfQotCi0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IGFuIFhQYXRoIG9iamVjdC4KLSAgICoKLSAgICogKE5lZWRzIHJldmlldyAtc2MpIFRoaXMgbWV0aG9kIGluaXRpYWxpemVzIGFuIFhQYXRoUGFyc2VyLwotICAgKiBDb21waWxlciBhbmQgY29tcGlsZXMgdGhlIGV4cHJlc3Npb24uCi0gICAqIEBwYXJhbSBleHByU3RyaW5nIFRoZSBYUGF0aCBleHByZXNzaW9uLgotICAgKiBAcGFyYW0gbG9jYXRvciBUaGUgbG9jYXRpb24gb2YgdGhlIGV4cHJlc3Npb24sIG1heSBiZSBudWxsLgotICAgKiBAcGFyYW0gcHJlZml4UmVzb2x2ZXIgQSBwcmVmaXggcmVzb2x2ZXIgdG8gdXNlIHRvIHJlc29sdmUgcHJlZml4ZXMgdG8KLSAgICogICAgICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZSBVUklzLgotICAgKiBAcGFyYW0gdHlwZSBvbmUgb2Yge0BsaW5rICNTRUxFQ1R9IG9yIHtAbGluayAjTUFUQ0h9LgotICAgKiBAcGFyYW0gZXJyb3JMaXN0ZW5lciBUaGUgZXJyb3IgbGlzdGVuZXIsIG9yIG51bGwgaWYgZGVmYXVsdCBzaG91bGQgYmUgdXNlZC4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uIGlmIHN5bnRheCBvciBvdGhlciBlcnJvci4KLSAgICovCi0gIHB1YmxpYyBYUGF0aCgKLSAgICAgICAgICBTdHJpbmcgZXhwclN0cmluZywgU291cmNlTG9jYXRvciBsb2NhdG9yLAotICAgICAgICAgIFByZWZpeFJlc29sdmVyIHByZWZpeFJlc29sdmVyLCBpbnQgdHlwZSwKLSAgICAgICAgICBFcnJvckxpc3RlbmVyIGVycm9yTGlzdGVuZXIsIEZ1bmN0aW9uVGFibGUgYVRhYmxlKQotICAgICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIG1fZnVuY1RhYmxlID0gYVRhYmxlOwotICAgIGlmKG51bGwgPT0gZXJyb3JMaXN0ZW5lcikKLSAgICAgIGVycm9yTGlzdGVuZXIgPSBuZXcgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5EZWZhdWx0RXJyb3JIYW5kbGVyKCk7Ci0KLSAgICBtX3BhdHRlcm5TdHJpbmcgPSBleHByU3RyaW5nOwotCi0gICAgWFBhdGhQYXJzZXIgcGFyc2VyID0gbmV3IFhQYXRoUGFyc2VyKGVycm9yTGlzdGVuZXIsIGxvY2F0b3IpOwotICAgIENvbXBpbGVyIGNvbXBpbGVyID0gbmV3IENvbXBpbGVyKGVycm9yTGlzdGVuZXIsIGxvY2F0b3IsIG1fZnVuY1RhYmxlKTsKLQotICAgIGlmIChTRUxFQ1QgPT0gdHlwZSkKLSAgICAgIHBhcnNlci5pbml0WFBhdGgoY29tcGlsZXIsIGV4cHJTdHJpbmcsIHByZWZpeFJlc29sdmVyKTsKLSAgICBlbHNlIGlmIChNQVRDSCA9PSB0eXBlKQotICAgICAgcGFyc2VyLmluaXRNYXRjaFBhdHRlcm4oY29tcGlsZXIsIGV4cHJTdHJpbmcsIHByZWZpeFJlc29sdmVyKTsKLSAgICBlbHNlCi0gICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoCi0gICAgICAgICAgICBYUEFUSEVycm9yUmVzb3VyY2VzLkVSX0NBTk5PVF9ERUFMX1hQQVRIX1RZUEUsCi0gICAgICAgICAgICBuZXcgT2JqZWN0W117SW50ZWdlci50b1N0cmluZyh0eXBlKX0pKTsKLSAgICAgICAgICAgIC8vIkNhbiBub3QgZGVhbCB3aXRoIFhQYXRoIHR5cGU6ICIgKyB0eXBlKTsKLQotICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiLS0tLS0tLS0tLS0tLS0tLSIpOwotICAgIEV4cHJlc3Npb24gZXhwciA9IGNvbXBpbGVyLmNvbXBpbGUoMCk7Ci0KLSAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oImV4cHI6ICIrZXhwcik7Ci0gICAgdGhpcy5zZXRFeHByZXNzaW9uKGV4cHIpOwotCi0gICAgaWYoKG51bGwgIT0gbG9jYXRvcikgJiYgbG9jYXRvciBpbnN0YW5jZW9mIEV4cHJlc3Npb25Ob2RlKQotICAgIHsKLSAgICAgICAgZXhwci5leHByU2V0UGFyZW50KChFeHByZXNzaW9uTm9kZSlsb2NhdG9yKTsKLSAgICB9Ci0KLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYW4gWFBhdGggb2JqZWN0LgotICAgKgotICAgKiAoTmVlZHMgcmV2aWV3IC1zYykgVGhpcyBtZXRob2QgaW5pdGlhbGl6ZXMgYW4gWFBhdGhQYXJzZXIvCi0gICAqIENvbXBpbGVyIGFuZCBjb21waWxlcyB0aGUgZXhwcmVzc2lvbi4KLSAgICogQHBhcmFtIGV4cHJTdHJpbmcgVGhlIFhQYXRoIGV4cHJlc3Npb24uCi0gICAqIEBwYXJhbSBsb2NhdG9yIFRoZSBsb2NhdGlvbiBvZiB0aGUgZXhwcmVzc2lvbiwgbWF5IGJlIG51bGwuCi0gICAqIEBwYXJhbSBwcmVmaXhSZXNvbHZlciBBIHByZWZpeCByZXNvbHZlciB0byB1c2UgdG8gcmVzb2x2ZSBwcmVmaXhlcyB0bwotICAgKiAgICAgICAgICAgICAgICAgICAgICAgbmFtZXNwYWNlIFVSSXMuCi0gICAqIEBwYXJhbSB0eXBlIG9uZSBvZiB7QGxpbmsgI1NFTEVDVH0gb3Ige0BsaW5rICNNQVRDSH0uCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbiBpZiBzeW50YXggb3Igb3RoZXIgZXJyb3IuCi0gICAqLwotICBwdWJsaWMgWFBhdGgoCi0gICAgICAgICAgU3RyaW5nIGV4cHJTdHJpbmcsIFNvdXJjZUxvY2F0b3IgbG9jYXRvciwgUHJlZml4UmVzb2x2ZXIgcHJlZml4UmVzb2x2ZXIsIGludCB0eXBlKQotICAgICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHRoaXMoZXhwclN0cmluZywgbG9jYXRvciwgcHJlZml4UmVzb2x2ZXIsIHR5cGUsIG51bGwpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhbiBYUGF0aCBvYmplY3QuCi0gICAqCi0gICAqIEBwYXJhbSBleHByIFRoZSBFeHByZXNzaW9uIG9iamVjdC4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uIGlmIHN5bnRheCBvciBvdGhlciBlcnJvci4KLSAgICovCi0gIHB1YmxpYyBYUGF0aChFeHByZXNzaW9uIGV4cHIpCi0gIHsKLSAgICB0aGlzLnNldEV4cHJlc3Npb24oZXhwcik7Ci0gICAgaW5pdEZ1bmN0aW9uVGFibGUoKTsKLSAgfQotCi0gIC8qKgotICAgKiBHaXZlbiBhbiBleHByZXNzaW9uIGFuZCBhIGNvbnRleHQsIGV2YWx1YXRlIHRoZSBYUGF0aAotICAgKiBhbmQgcmV0dXJuIHRoZSByZXN1bHQuCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgZXhlY3V0aW9uIGNvbnRleHQuCi0gICAqIEBwYXJhbSBjb250ZXh0Tm9kZSBUaGUgbm9kZSB0aGF0ICIuIiBleHByZXNzZXMuCi0gICAqIEBwYXJhbSBuYW1lc3BhY2VDb250ZXh0IFRoZSBjb250ZXh0IGluIHdoaWNoIG5hbWVzcGFjZXMgaW4gdGhlCi0gICAqIFhQYXRoIGFyZSBzdXBwb3NlZCB0byBiZSBleHBhbmRlZC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgcmVzdWx0IG9mIHRoZSBYUGF0aCBvciBudWxsIGlmIGNhbGxiYWNrcyBhcmUgdXNlZC4KLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiB0aHJvd24gaWYKLSAgICogdGhlIGVycm9yIGNvbmRpdGlvbiBpcyBzZXZlcmUgZW5vdWdoIHRvIGhhbHQgcHJvY2Vzc2luZy4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqIEB4c2wudXNhZ2UgZXhwZXJpbWVudGFsCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBleGVjdXRlKAotICAgICAgICAgIFhQYXRoQ29udGV4dCB4Y3R4dCwgb3JnLnczYy5kb20uTm9kZSBjb250ZXh0Tm9kZSwKLSAgICAgICAgICBQcmVmaXhSZXNvbHZlciBuYW1lc3BhY2VDb250ZXh0KQotICAgICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHJldHVybiBleGVjdXRlKAotICAgICAgICAgIHhjdHh0LCB4Y3R4dC5nZXREVE1IYW5kbGVGcm9tTm9kZShjb250ZXh0Tm9kZSksCi0gICAgICAgICAgbmFtZXNwYWNlQ29udGV4dCk7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBHaXZlbiBhbiBleHByZXNzaW9uIGFuZCBhIGNvbnRleHQsIGV2YWx1YXRlIHRoZSBYUGF0aAotICAgKiBhbmQgcmV0dXJuIHRoZSByZXN1bHQuCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgZXhlY3V0aW9uIGNvbnRleHQuCi0gICAqIEBwYXJhbSBjb250ZXh0Tm9kZSBUaGUgbm9kZSB0aGF0ICIuIiBleHByZXNzZXMuCi0gICAqIEBwYXJhbSBuYW1lc3BhY2VDb250ZXh0IFRoZSBjb250ZXh0IGluIHdoaWNoIG5hbWVzcGFjZXMgaW4gdGhlCi0gICAqIFhQYXRoIGFyZSBzdXBwb3NlZCB0byBiZSBleHBhbmRlZC4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiB0aHJvd24gaWYgdGhlIGFjdGl2ZSBQcm9ibGVtTGlzdGVuZXIgZGVjaWRlcwotICAgKiB0aGUgZXJyb3IgY29uZGl0aW9uIGlzIHNldmVyZSBlbm91Z2ggdG8gaGFsdCBwcm9jZXNzaW5nLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICogQHhzbC51c2FnZSBleHBlcmltZW50YWwKLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IGV4ZWN1dGUoCi0gICAgICAgICAgWFBhdGhDb250ZXh0IHhjdHh0LCBpbnQgY29udGV4dE5vZGUsIFByZWZpeFJlc29sdmVyIG5hbWVzcGFjZUNvbnRleHQpCi0gICAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICB4Y3R4dC5wdXNoTmFtZXNwYWNlQ29udGV4dChuYW1lc3BhY2VDb250ZXh0KTsKLQotICAgIHhjdHh0LnB1c2hDdXJyZW50Tm9kZUFuZEV4cHJlc3Npb24oY29udGV4dE5vZGUsIGNvbnRleHROb2RlKTsKLQotICAgIFhPYmplY3QgeG9iaiA9IG51bGw7Ci0KLSAgICB0cnkKLSAgICB7Ci0gICAgICB4b2JqID0gbV9tYWluRXhwLmV4ZWN1dGUoeGN0eHQpOwotICAgIH0KLSAgICBjYXRjaCAoVHJhbnNmb3JtZXJFeGNlcHRpb24gdGUpCi0gICAgewotICAgICAgdGUuc2V0TG9jYXRvcih0aGlzLmdldExvY2F0b3IoKSk7Ci0gICAgICBFcnJvckxpc3RlbmVyIGVsID0geGN0eHQuZ2V0RXJyb3JMaXN0ZW5lcigpOwotICAgICAgaWYobnVsbCAhPSBlbCkgLy8gZGVmZW5zaXZlLCBzaG91bGQgbmV2ZXIgaGFwcGVuLgotICAgICAgewotICAgICAgICBlbC5lcnJvcih0ZSk7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICAgIHRocm93IHRlOwotICAgIH0KLSAgICBjYXRjaCAoRXhjZXB0aW9uIGUpCi0gICAgewotICAgICAgd2hpbGUgKGUgaW5zdGFuY2VvZiBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLldyYXBwZWRSdW50aW1lRXhjZXB0aW9uKQotICAgICAgewotICAgICAgICBlID0gKChjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLldyYXBwZWRSdW50aW1lRXhjZXB0aW9uKSBlKS5nZXRFeGNlcHRpb24oKTsKLSAgICAgIH0KLSAgICAgIC8vIGUucHJpbnRTdGFja1RyYWNlKCk7Ci0KLSAgICAgIFN0cmluZyBtc2cgPSBlLmdldE1lc3NhZ2UoKTsKLQotICAgICAgaWYgKG1zZyA9PSBudWxsIHx8IG1zZy5sZW5ndGgoKSA9PSAwKSB7Ci0gICAgICAgICAgIG1zZyA9IFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZSgKLSAgICAgICAgICAgICAgIFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfWFBBVEhfRVJST1IsIG51bGwpOwotCi0gICAgICB9Ci0gICAgICBUcmFuc2Zvcm1lckV4Y2VwdGlvbiB0ZSA9IG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihtc2csCi0gICAgICAgICAgICAgIGdldExvY2F0b3IoKSwgZSk7Ci0gICAgICBFcnJvckxpc3RlbmVyIGVsID0geGN0eHQuZ2V0RXJyb3JMaXN0ZW5lcigpOwotICAgICAgLy8gdGUucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICBpZihudWxsICE9IGVsKSAvLyBkZWZlbnNpdmUsIHNob3VsZCBuZXZlciBoYXBwZW4uCi0gICAgICB7Ci0gICAgICAgIGVsLmZhdGFsRXJyb3IodGUpOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgICB0aHJvdyB0ZTsKLSAgICB9Ci0gICAgZmluYWxseQotICAgIHsKLSAgICAgIHhjdHh0LnBvcE5hbWVzcGFjZUNvbnRleHQoKTsKLQotICAgICAgeGN0eHQucG9wQ3VycmVudE5vZGVBbmRFeHByZXNzaW9uKCk7Ci0gICAgfQotCi0gICAgcmV0dXJuIHhvYmo7Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYW4gZXhwcmVzc2lvbiBhbmQgYSBjb250ZXh0LCBldmFsdWF0ZSB0aGUgWFBhdGgKLSAgICogYW5kIHJldHVybiB0aGUgcmVzdWx0LgotICAgKgotICAgKiBAcGFyYW0geGN0eHQgVGhlIGV4ZWN1dGlvbiBjb250ZXh0LgotICAgKiBAcGFyYW0gY29udGV4dE5vZGUgVGhlIG5vZGUgdGhhdCAiLiIgZXhwcmVzc2VzLgotICAgKiBAcGFyYW0gbmFtZXNwYWNlQ29udGV4dCBUaGUgY29udGV4dCBpbiB3aGljaCBuYW1lc3BhY2VzIGluIHRoZQotICAgKiBYUGF0aCBhcmUgc3VwcG9zZWQgdG8gYmUgZXhwYW5kZWQuCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24gdGhyb3duIGlmIHRoZSBhY3RpdmUgUHJvYmxlbUxpc3RlbmVyIGRlY2lkZXMKLSAgICogdGhlIGVycm9yIGNvbmRpdGlvbiBpcyBzZXZlcmUgZW5vdWdoIHRvIGhhbHQgcHJvY2Vzc2luZy4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqIEB4c2wudXNhZ2UgZXhwZXJpbWVudGFsCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBib29sKAotICAgICAgICAgIFhQYXRoQ29udGV4dCB4Y3R4dCwgaW50IGNvbnRleHROb2RlLCBQcmVmaXhSZXNvbHZlciBuYW1lc3BhY2VDb250ZXh0KQotICAgICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgeGN0eHQucHVzaE5hbWVzcGFjZUNvbnRleHQobmFtZXNwYWNlQ29udGV4dCk7Ci0KLSAgICB4Y3R4dC5wdXNoQ3VycmVudE5vZGVBbmRFeHByZXNzaW9uKGNvbnRleHROb2RlLCBjb250ZXh0Tm9kZSk7Ci0KLSAgICB0cnkKLSAgICB7Ci0gICAgICByZXR1cm4gbV9tYWluRXhwLmJvb2woeGN0eHQpOwotICAgIH0KLSAgICBjYXRjaCAoVHJhbnNmb3JtZXJFeGNlcHRpb24gdGUpCi0gICAgewotICAgICAgdGUuc2V0TG9jYXRvcih0aGlzLmdldExvY2F0b3IoKSk7Ci0gICAgICBFcnJvckxpc3RlbmVyIGVsID0geGN0eHQuZ2V0RXJyb3JMaXN0ZW5lcigpOwotICAgICAgaWYobnVsbCAhPSBlbCkgLy8gZGVmZW5zaXZlLCBzaG91bGQgbmV2ZXIgaGFwcGVuLgotICAgICAgewotICAgICAgICBlbC5lcnJvcih0ZSk7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICAgIHRocm93IHRlOwotICAgIH0KLSAgICBjYXRjaCAoRXhjZXB0aW9uIGUpCi0gICAgewotICAgICAgd2hpbGUgKGUgaW5zdGFuY2VvZiBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLldyYXBwZWRSdW50aW1lRXhjZXB0aW9uKQotICAgICAgewotICAgICAgICBlID0gKChjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLldyYXBwZWRSdW50aW1lRXhjZXB0aW9uKSBlKS5nZXRFeGNlcHRpb24oKTsKLSAgICAgIH0KLSAgICAgIC8vIGUucHJpbnRTdGFja1RyYWNlKCk7Ci0KLSAgICAgIFN0cmluZyBtc2cgPSBlLmdldE1lc3NhZ2UoKTsKLQotICAgICAgaWYgKG1zZyA9PSBudWxsIHx8IG1zZy5sZW5ndGgoKSA9PSAwKSB7Ci0gICAgICAgICAgIG1zZyA9IFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZSgKLSAgICAgICAgICAgICAgIFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfWFBBVEhfRVJST1IsIG51bGwpOwotCi0gICAgICB9Ci0KLSAgICAgIFRyYW5zZm9ybWVyRXhjZXB0aW9uIHRlID0gbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKG1zZywKLSAgICAgICAgICAgICAgZ2V0TG9jYXRvcigpLCBlKTsKLSAgICAgIEVycm9yTGlzdGVuZXIgZWwgPSB4Y3R4dC5nZXRFcnJvckxpc3RlbmVyKCk7Ci0gICAgICAvLyB0ZS5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgIGlmKG51bGwgIT0gZWwpIC8vIGRlZmVuc2l2ZSwgc2hvdWxkIG5ldmVyIGhhcHBlbi4KLSAgICAgIHsKLSAgICAgICAgZWwuZmF0YWxFcnJvcih0ZSk7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICAgIHRocm93IHRlOwotICAgIH0KLSAgICBmaW5hbGx5Ci0gICAgewotICAgICAgeGN0eHQucG9wTmFtZXNwYWNlQ29udGV4dCgpOwotCi0gICAgICB4Y3R4dC5wb3BDdXJyZW50Tm9kZUFuZEV4cHJlc3Npb24oKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gZmFsc2U7Ci0gIH0KLQotICAvKiogU2V0IHRvIHRydWUgdG8gZ2V0IGRpYWdub3N0aWMgbWVzc2FnZXMgYWJvdXQgdGhlIHJlc3VsdCBvZgotICAgKiAgbWF0Y2ggcGF0dGVybiB0ZXN0aW5nLiAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbiBERUJVR19NQVRDSEVTID0gZmFsc2U7Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbWF0Y2ggc2NvcmUgb2YgdGhlIGdpdmVuIG5vZGUuCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBYUGF0aCBydW50aW1lIGNvbnRleHQuCi0gICAqIEBwYXJhbSBjb250ZXh0IFRoZSBjdXJyZW50IHNvdXJjZSB0cmVlIGNvbnRleHQgbm9kZS4KLSAgICoKLSAgICogQHJldHVybiBzY29yZSwgb25lIG9mIHtAbGluayAjTUFUQ0hfU0NPUkVfTk9ERVRFU1R9LAotICAgKiB7QGxpbmsgI01BVENIX1NDT1JFX05PTkV9LCB7QGxpbmsgI01BVENIX1NDT1JFX09USEVSfSwKLSAgICogb3Ige0BsaW5rICNNQVRDSF9TQ09SRV9RTkFNRX0uCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGRvdWJsZSBnZXRNYXRjaFNjb3JlKFhQYXRoQ29udGV4dCB4Y3R4dCwgaW50IGNvbnRleHQpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgeGN0eHQucHVzaEN1cnJlbnROb2RlKGNvbnRleHQpOwotICAgIHhjdHh0LnB1c2hDdXJyZW50RXhwcmVzc2lvbk5vZGUoY29udGV4dCk7Ci0KLSAgICB0cnkKLSAgICB7Ci0gICAgICBYT2JqZWN0IHNjb3JlID0gbV9tYWluRXhwLmV4ZWN1dGUoeGN0eHQpOwotCi0gICAgICBpZiAoREVCVUdfTUFUQ0hFUykKLSAgICAgIHsKLSAgICAgICAgRFRNIGR0bSA9IHhjdHh0LmdldERUTShjb250ZXh0KTsKLSAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJzY29yZTogIiArIHNjb3JlLm51bSgpICsgIiBmb3IgIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBkdG0uZ2V0Tm9kZU5hbWUoY29udGV4dCkgKyAiIGZvciB4cGF0aCAiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICArIHRoaXMuZ2V0UGF0dGVyblN0cmluZygpKTsKLSAgICAgIH0KLQotICAgICAgcmV0dXJuIHNjb3JlLm51bSgpOwotICAgIH0KLSAgICBmaW5hbGx5Ci0gICAgewotICAgICAgeGN0eHQucG9wQ3VycmVudE5vZGUoKTsKLSAgICAgIHhjdHh0LnBvcEN1cnJlbnRFeHByZXNzaW9uTm9kZSgpOwotICAgIH0KLQotICAgIC8vIHJldHVybiBYUGF0aC5NQVRDSF9TQ09SRV9OT05FOwotICB9Ci0KLQotICAvKioKLSAgICogV2FybiB0aGUgdXNlciBvZiBhbiBwcm9ibGVtLgotICAgKgotICAgKiBAcGFyYW0geGN0eHQgVGhlIFhQYXRoIHJ1bnRpbWUgY29udGV4dC4KLSAgICogQHBhcmFtIHNvdXJjZU5vZGUgTm90IHVzZWQuCi0gICAqIEBwYXJhbSBtc2cgQW4gZXJyb3IgbXNna2V5IHRoYXQgY29ycmVzcG9uZHMgdG8gb25lIG9mIHRoZSBjb25zdGFudHMgZm91bmQKLSAgICogICAgICAgICAgICBpbiB7QGxpbmsgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLnJlcy5YUEFUSEVycm9yUmVzb3VyY2VzfSwgd2hpY2ggaXMKLSAgICogICAgICAgICAgICBhIGtleSBmb3IgYSBmb3JtYXQgc3RyaW5nLgotICAgKiBAcGFyYW0gYXJncyBBbiBhcnJheSBvZiBhcmd1bWVudHMgcmVwcmVzZW50ZWQgaW4gdGhlIGZvcm1hdCBzdHJpbmcsIHdoaWNoCi0gICAqICAgICAgICAgICAgIG1heSBiZSBudWxsLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uIGlmIHRoZSBjdXJyZW50IEVycm9yTGlzdG9uZXIgZGV0ZXJtaW5lcyB0bwotICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGFuIGV4Y2VwdGlvbi4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHdhcm4oCi0gICAgICAgICAgWFBhdGhDb250ZXh0IHhjdHh0LCBpbnQgc291cmNlTm9kZSwgU3RyaW5nIG1zZywgT2JqZWN0W10gYXJncykKLSAgICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIFN0cmluZyBmbXNnID0gWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhXYXJuaW5nKG1zZywgYXJncyk7Ci0gICAgRXJyb3JMaXN0ZW5lciBlaGFuZGxlciA9IHhjdHh0LmdldEVycm9yTGlzdGVuZXIoKTsKLQotICAgIGlmIChudWxsICE9IGVoYW5kbGVyKQotICAgIHsKLQotICAgICAgLy8gVE8gRE86IE5lZWQgdG8gZ2V0IHN0eWxlc2hlZXQgTG9jYXRvciBmcm9tIGhlcmUuCi0gICAgICBlaGFuZGxlci53YXJuaW5nKG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihmbXNnLCAoU0FYU291cmNlTG9jYXRvcil4Y3R4dC5nZXRTQVhMb2NhdG9yKCkpKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogVGVsbCB0aGUgdXNlciBvZiBhbiBhc3NlcnRpb24gZXJyb3IsIGFuZCBwcm9iYWJseSB0aHJvdyBhbgotICAgKiBleGNlcHRpb24uCi0gICAqCi0gICAqIEBwYXJhbSBiICBJZiBmYWxzZSwgYSBydW50aW1lIGV4Y2VwdGlvbiB3aWxsIGJlIHRocm93bi4KLSAgICogQHBhcmFtIG1zZyBUaGUgYXNzZXJ0aW9uIG1lc3NhZ2UsIHdoaWNoIHNob3VsZCBiZSBpbmZvcm1hdGl2ZS4KLSAgICoKLSAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIGlmIHRoZSBiIGFyZ3VtZW50IGlzIGZhbHNlLgotICAgKi8KLSAgcHVibGljIHZvaWQgYXNzZXJ0aW9uKGJvb2xlYW4gYiwgU3RyaW5nIG1zZykKLSAgewotCi0gICAgaWYgKCFiKQotICAgIHsKLSAgICAgIFN0cmluZyBmTXNnID0gWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKAotICAgICAgICBYUEFUSEVycm9yUmVzb3VyY2VzLkVSX0lOQ09SUkVDVF9QUk9HUkFNTUVSX0FTU0VSVElPTiwKLSAgICAgICAgbmV3IE9iamVjdFtdeyBtc2cgfSk7Ci0KLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGZNc2cpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIHRoZSB1c2VyIG9mIGFuIGVycm9yLCBhbmQgcHJvYmFibHkgdGhyb3cgYW4KLSAgICogZXhjZXB0aW9uLgotICAgKgotICAgKiBAcGFyYW0geGN0eHQgVGhlIFhQYXRoIHJ1bnRpbWUgY29udGV4dC4KLSAgICogQHBhcmFtIHNvdXJjZU5vZGUgTm90IHVzZWQuCi0gICAqIEBwYXJhbSBtc2cgQW4gZXJyb3IgbXNna2V5IHRoYXQgY29ycmVzcG9uZHMgdG8gb25lIG9mIHRoZSBjb25zdGFudHMgZm91bmQKLSAgICogICAgICAgICAgICBpbiB7QGxpbmsgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLnJlcy5YUEFUSEVycm9yUmVzb3VyY2VzfSwgd2hpY2ggaXMKLSAgICogICAgICAgICAgICBhIGtleSBmb3IgYSBmb3JtYXQgc3RyaW5nLgotICAgKiBAcGFyYW0gYXJncyBBbiBhcnJheSBvZiBhcmd1bWVudHMgcmVwcmVzZW50ZWQgaW4gdGhlIGZvcm1hdCBzdHJpbmcsIHdoaWNoCi0gICAqICAgICAgICAgICAgIG1heSBiZSBudWxsLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uIGlmIHRoZSBjdXJyZW50IEVycm9yTGlzdG9uZXIgZGV0ZXJtaW5lcyB0bwotICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGFuIGV4Y2VwdGlvbi4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGVycm9yKAotICAgICAgICAgIFhQYXRoQ29udGV4dCB4Y3R4dCwgaW50IHNvdXJjZU5vZGUsIFN0cmluZyBtc2csIE9iamVjdFtdIGFyZ3MpCi0gICAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBTdHJpbmcgZm1zZyA9IFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShtc2csIGFyZ3MpOwotICAgIEVycm9yTGlzdGVuZXIgZWhhbmRsZXIgPSB4Y3R4dC5nZXRFcnJvckxpc3RlbmVyKCk7Ci0KLSAgICBpZiAobnVsbCAhPSBlaGFuZGxlcikKLSAgICB7Ci0gICAgICBlaGFuZGxlci5mYXRhbEVycm9yKG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihmbXNnLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFNBWFNvdXJjZUxvY2F0b3IpeGN0eHQuZ2V0U0FYTG9jYXRvcigpKSk7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBTb3VyY2VMb2NhdG9yIHNsb2NhdG9yID0geGN0eHQuZ2V0U0FYTG9jYXRvcigpOwotICAgICAgU3lzdGVtLm91dC5wcmludGxuKGZtc2cgKyAiOyBmaWxlICIgKyBzbG9jYXRvci5nZXRTeXN0ZW1JZCgpCi0gICAgICAgICAgICAgICAgICAgICAgICAgKyAiOyBsaW5lICIgKyBzbG9jYXRvci5nZXRMaW5lTnVtYmVyKCkgKyAiOyBjb2x1bW4gIgotICAgICAgICAgICAgICAgICAgICAgICAgICsgc2xvY2F0b3IuZ2V0Q29sdW1uTnVtYmVyKCkpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBUaGlzIHdpbGwgdHJhdmVyc2UgdGhlIGhlYXJhcmNoeSwgY2FsbGluZyB0aGUgdmlzaXRvciBmb3IKLSAgICogZWFjaCBtZW1iZXIuICBJZiB0aGUgY2FsbGVkIHZpc2l0b3IgbWV0aG9kIHJldHVybnMKLSAgICogZmFsc2UsIHRoZSBzdWJ0cmVlIHNob3VsZCBub3QgYmUgY2FsbGVkLgotICAgKgotICAgKiBAcGFyYW0gb3duZXIgVGhlIG93bmVyIG9mIHRoZSB2aXNpdG9yLCB3aGVyZSB0aGF0IHBhdGggbWF5IGJlCi0gICAqICAgICAgICAgICAgICByZXdyaXR0ZW4gaWYgbmVlZGVkLgotICAgKiBAcGFyYW0gdmlzaXRvciBUaGUgdmlzaXRvciB3aG9zZSBhcHByb3ByaWF0ZSBtZXRob2Qgd2lsbCBiZSBjYWxsZWQuCi0gICAqLwotICBwdWJsaWMgdm9pZCBjYWxsVmlzaXRvcnMoRXhwcmVzc2lvbk93bmVyIG93bmVyLCBYUGF0aFZpc2l0b3IgdmlzaXRvcikKLSAgewotICAgICAgICBtX21haW5FeHAuY2FsbFZpc2l0b3JzKHRoaXMsIHZpc2l0b3IpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoZSBtYXRjaCBzY29yZSBpZiBubyBtYXRjaCBpcyBtYWRlLgotICAgKiBAeHNsLnVzYWdlIGFkdmFuY2VkCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGRvdWJsZSBNQVRDSF9TQ09SRV9OT05FID0gRG91YmxlLk5FR0FUSVZFX0lORklOSVRZOwotCi0gIC8qKgotICAgKiBUaGUgbWF0Y2ggc2NvcmUgaWYgdGhlIHBhdHRlcm4gaGFzIHRoZSBmb3JtCi0gICAqIG9mIGEgUU5hbWUgb3B0aW9uYWxseSBwcmVjZWRlZCBieSBhbiBAIGNoYXJhY3Rlci4KLSAgICogQHhzbC51c2FnZSBhZHZhbmNlZAotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBkb3VibGUgTUFUQ0hfU0NPUkVfUU5BTUUgPSAwLjA7Ci0KLSAgLyoqCi0gICAqIFRoZSBtYXRjaCBzY29yZSBpZiB0aGUgcGF0dGVybiBwYXR0ZXJuIGhhcyB0aGUgZm9ybSBOQ05hbWU6Ki4KLSAgICogQHhzbC51c2FnZSBhZHZhbmNlZAotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBkb3VibGUgTUFUQ0hfU0NPUkVfTlNXSUxEID0gLTAuMjU7Ci0KLSAgLyoqCi0gICAqIFRoZSBtYXRjaCBzY29yZSBpZiB0aGUgcGF0dGVybiBjb25zaXN0cyBvZiBqdXN0IGEgTm9kZVRlc3QuCi0gICAqIEB4c2wudXNhZ2UgYWR2YW5jZWQKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgZG91YmxlIE1BVENIX1NDT1JFX05PREVURVNUID0gLTAuNTsKLQotICAvKioKLSAgICogVGhlIG1hdGNoIHNjb3JlIGlmIHRoZSBwYXR0ZXJuIGNvbnNpc3RzIG9mIHNvbWV0aGluZwotICAgKiBvdGhlciB0aGFuIGp1c3QgYSBOb2RlVGVzdCBvciBqdXN0IGEgcW5hbWUuCi0gICAqIEB4c2wudXNhZ2UgYWR2YW5jZWQKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgZG91YmxlIE1BVENIX1NDT1JFX09USEVSID0gMC41OwotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9YUGF0aEFQSS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9YUGF0aEFQSS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmYjkxZDkwLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvWFBhdGhBUEkuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI4NSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBYUGF0aEFQSS5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzEwIDE4OjE4OjIzIGplZmZzdXR0b3IgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWw7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5QcmVmaXhSZXNvbHZlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLlByZWZpeFJlc29sdmVyRGVmYXVsdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YT2JqZWN0OwotCi1pbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlTGlzdDsKLWltcG9ydCBvcmcudzNjLmRvbS50cmF2ZXJzYWwuTm9kZUl0ZXJhdG9yOwotCi0vKioKLSAqIFRoZSBtZXRob2RzIGluIHRoaXMgY2xhc3MgYXJlIGNvbnZlbmllbmNlIG1ldGhvZHMgaW50byB0aGUKLSAqIGxvdy1sZXZlbCBYUGF0aCBBUEkuCi0gKiBUaGVzZSBmdW5jdGlvbnMgdGVuZCB0byBiZSBhIGxpdHRsZSBzbG93LCBzaW5jZSBhIG51bWJlciBvZiBvYmplY3RzIG11c3QgYmUKLSAqIGNyZWF0ZWQgZm9yIGVhY2ggZXZhbHVhdGlvbi4gIEEgZmFzdGVyIHdheSBpcyB0byBwcmVjb21waWxlIHRoZQotICogWFBhdGhzIHVzaW5nIHRoZSBsb3ctbGV2ZWwgQVBJLCBhbmQgdGhlbiBqdXN0IHVzZSB0aGUgWFBhdGhzCi0gKiBvdmVyIGFuZCBvdmVyLgotICoKLSAqIE5PVEU6IEluIHBhcnRpY3VsYXIsIGVhY2ggY2FsbCB0byB0aGlzIG1ldGhvZCB3aWxsIGNyZWF0ZSBhIG5ldwotICogWFBhdGhDb250ZXh0LCBhIG5ldyBEVE1NYW5hZ2VyLi4uIGFuZCB0aHVzIGEgbmV3IERUTS4gVGhhdCdzIHZlcnkKLSAqIHNhZmUsIHNpbmNlIGl0IGd1YXJhbnRlZXMgdGhhdCB5b3UncmUgYWx3YXlzIHByb2Nlc3NpbmcgYWdhaW5zdCBhCi0gKiBmdWxseSB1cC10by1kYXRlIHZpZXcgb2YgeW91ciBkb2N1bWVudC4gQnV0IGl0J3MgYWxzbyBwb3J0ZW50aWFsbHkKLSAqIHZlcnkgZXhwZW5zaXZlLCBzaW5jZSB5b3UncmUgcmVidWlsZGluZyB0aGUgRFRNIGV2ZXJ5IHRpbWUuIFlvdSBzaG91bGQKLSAqIGNvbnNpZGVyIHVzaW5nIGFuIGluc3RhbmNlIG9mIENhY2hlZFhQYXRoQVBJIHJhdGhlciB0aGFuIHRoZXNlIHN0YXRpYwotICogbWV0aG9kcy4KLSAqCi0gKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hwYXRoIj5YUGF0aCBTcGVjaWZpY2F0aW9uPC9hPgotICogKi8KLXB1YmxpYyBjbGFzcyBYUGF0aEFQSQotewotCi0gIC8qKgotICAgKiBVc2UgYW4gWFBhdGggc3RyaW5nIHRvIHNlbGVjdCBhIHNpbmdsZSBub2RlLiBYUGF0aCBuYW1lc3BhY2UKLSAgICogcHJlZml4ZXMgYXJlIHJlc29sdmVkIGZyb20gdGhlIGNvbnRleHQgbm9kZSwgd2hpY2ggbWF5IG5vdAotICAgKiBiZSB3aGF0IHlvdSB3YW50IChzZWUgdGhlIG5leHQgbWV0aG9kKS4KLSAgICoKLSAgICogQHBhcmFtIGNvbnRleHROb2RlIFRoZSBub2RlIHRvIHN0YXJ0IHNlYXJjaGluZyBmcm9tLgotICAgKiBAcGFyYW0gc3RyIEEgdmFsaWQgWFBhdGggc3RyaW5nLgotICAgKiBAcmV0dXJuIFRoZSBmaXJzdCBub2RlIGZvdW5kIHRoYXQgbWF0Y2hlcyB0aGUgWFBhdGgsIG9yIG51bGwuCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgTm9kZSBzZWxlY3RTaW5nbGVOb2RlKE5vZGUgY29udGV4dE5vZGUsIFN0cmluZyBzdHIpCi0gICAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gc2VsZWN0U2luZ2xlTm9kZShjb250ZXh0Tm9kZSwgc3RyLCBjb250ZXh0Tm9kZSk7Ci0gIH0KLQotICAvKioKLSAgICogVXNlIGFuIFhQYXRoIHN0cmluZyB0byBzZWxlY3QgYSBzaW5nbGUgbm9kZS4KLSAgICogWFBhdGggbmFtZXNwYWNlIHByZWZpeGVzIGFyZSByZXNvbHZlZCBmcm9tIHRoZSBuYW1lc3BhY2VOb2RlLgotICAgKgotICAgKiBAcGFyYW0gY29udGV4dE5vZGUgVGhlIG5vZGUgdG8gc3RhcnQgc2VhcmNoaW5nIGZyb20uCi0gICAqIEBwYXJhbSBzdHIgQSB2YWxpZCBYUGF0aCBzdHJpbmcuCi0gICAqIEBwYXJhbSBuYW1lc3BhY2VOb2RlIFRoZSBub2RlIGZyb20gd2hpY2ggcHJlZml4ZXMgaW4gdGhlIFhQYXRoIHdpbGwgYmUgcmVzb2x2ZWQgdG8gbmFtZXNwYWNlcy4KLSAgICogQHJldHVybiBUaGUgZmlyc3Qgbm9kZSBmb3VuZCB0aGF0IG1hdGNoZXMgdGhlIFhQYXRoLCBvciBudWxsLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgc3RhdGljIE5vZGUgc2VsZWN0U2luZ2xlTm9kZSgKLSAgICAgICAgICBOb2RlIGNvbnRleHROb2RlLCBTdHJpbmcgc3RyLCBOb2RlIG5hbWVzcGFjZU5vZGUpCi0gICAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgLy8gSGF2ZSB0aGUgWE9iamVjdCByZXR1cm4gaXRzIHJlc3VsdCBhcyBhIE5vZGVTZXREVE0uCi0gICAgTm9kZUl0ZXJhdG9yIG5sID0gc2VsZWN0Tm9kZUl0ZXJhdG9yKGNvbnRleHROb2RlLCBzdHIsIG5hbWVzcGFjZU5vZGUpOwotCi0gICAgLy8gUmV0dXJuIHRoZSBmaXJzdCBub2RlLCBvciBudWxsCi0gICAgcmV0dXJuIG5sLm5leHROb2RlKCk7Ci0gIH0KLQotICAvKioKLSAgICogIFVzZSBhbiBYUGF0aCBzdHJpbmcgdG8gc2VsZWN0IGEgbm9kZWxpc3QuCi0gICAqICBYUGF0aCBuYW1lc3BhY2UgcHJlZml4ZXMgYXJlIHJlc29sdmVkIGZyb20gdGhlIGNvbnRleHROb2RlLgotICAgKgotICAgKiAgQHBhcmFtIGNvbnRleHROb2RlIFRoZSBub2RlIHRvIHN0YXJ0IHNlYXJjaGluZyBmcm9tLgotICAgKiAgQHBhcmFtIHN0ciBBIHZhbGlkIFhQYXRoIHN0cmluZy4KLSAgICogIEByZXR1cm4gQSBOb2RlSXRlcmF0b3IsIHNob3VsZCBuZXZlciBiZSBudWxsLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgc3RhdGljIE5vZGVJdGVyYXRvciBzZWxlY3ROb2RlSXRlcmF0b3IoTm9kZSBjb250ZXh0Tm9kZSwgU3RyaW5nIHN0cikKLSAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHJldHVybiBzZWxlY3ROb2RlSXRlcmF0b3IoY29udGV4dE5vZGUsIHN0ciwgY29udGV4dE5vZGUpOwotICB9Ci0KLSAgLyoqCi0gICAqICBVc2UgYW4gWFBhdGggc3RyaW5nIHRvIHNlbGVjdCBhIG5vZGVsaXN0LgotICAgKiAgWFBhdGggbmFtZXNwYWNlIHByZWZpeGVzIGFyZSByZXNvbHZlZCBmcm9tIHRoZSBuYW1lc3BhY2VOb2RlLgotICAgKgotICAgKiAgQHBhcmFtIGNvbnRleHROb2RlIFRoZSBub2RlIHRvIHN0YXJ0IHNlYXJjaGluZyBmcm9tLgotICAgKiAgQHBhcmFtIHN0ciBBIHZhbGlkIFhQYXRoIHN0cmluZy4KLSAgICogIEBwYXJhbSBuYW1lc3BhY2VOb2RlIFRoZSBub2RlIGZyb20gd2hpY2ggcHJlZml4ZXMgaW4gdGhlIFhQYXRoIHdpbGwgYmUgcmVzb2x2ZWQgdG8gbmFtZXNwYWNlcy4KLSAgICogIEByZXR1cm4gQSBOb2RlSXRlcmF0b3IsIHNob3VsZCBuZXZlciBiZSBudWxsLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgc3RhdGljIE5vZGVJdGVyYXRvciBzZWxlY3ROb2RlSXRlcmF0b3IoCi0gICAgICAgICAgTm9kZSBjb250ZXh0Tm9kZSwgU3RyaW5nIHN0ciwgTm9kZSBuYW1lc3BhY2VOb2RlKQotICAgICAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIC8vIEV4ZWN1dGUgdGhlIFhQYXRoLCBhbmQgaGF2ZSBpdCByZXR1cm4gdGhlIHJlc3VsdAotICAgIFhPYmplY3QgbGlzdCA9IGV2YWwoY29udGV4dE5vZGUsIHN0ciwgbmFtZXNwYWNlTm9kZSk7Ci0KLSAgICAvLyBIYXZlIHRoZSBYT2JqZWN0IHJldHVybiBpdHMgcmVzdWx0IGFzIGEgTm9kZVNldERUTS4KLSAgICByZXR1cm4gbGlzdC5ub2Rlc2V0KCk7Ci0gIH0KLQotICAvKioKLSAgICogIFVzZSBhbiBYUGF0aCBzdHJpbmcgdG8gc2VsZWN0IGEgbm9kZWxpc3QuCi0gICAqICBYUGF0aCBuYW1lc3BhY2UgcHJlZml4ZXMgYXJlIHJlc29sdmVkIGZyb20gdGhlIGNvbnRleHROb2RlLgotICAgKgotICAgKiAgQHBhcmFtIGNvbnRleHROb2RlIFRoZSBub2RlIHRvIHN0YXJ0IHNlYXJjaGluZyBmcm9tLgotICAgKiAgQHBhcmFtIHN0ciBBIHZhbGlkIFhQYXRoIHN0cmluZy4KLSAgICogIEByZXR1cm4gQSBOb2RlSXRlcmF0b3IsIHNob3VsZCBuZXZlciBiZSBudWxsLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgc3RhdGljIE5vZGVMaXN0IHNlbGVjdE5vZGVMaXN0KE5vZGUgY29udGV4dE5vZGUsIFN0cmluZyBzdHIpCi0gICAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gc2VsZWN0Tm9kZUxpc3QoY29udGV4dE5vZGUsIHN0ciwgY29udGV4dE5vZGUpOwotICB9Ci0KLSAgLyoqCi0gICAqICBVc2UgYW4gWFBhdGggc3RyaW5nIHRvIHNlbGVjdCBhIG5vZGVsaXN0LgotICAgKiAgWFBhdGggbmFtZXNwYWNlIHByZWZpeGVzIGFyZSByZXNvbHZlZCBmcm9tIHRoZSBuYW1lc3BhY2VOb2RlLgotICAgKgotICAgKiAgQHBhcmFtIGNvbnRleHROb2RlIFRoZSBub2RlIHRvIHN0YXJ0IHNlYXJjaGluZyBmcm9tLgotICAgKiAgQHBhcmFtIHN0ciBBIHZhbGlkIFhQYXRoIHN0cmluZy4KLSAgICogIEBwYXJhbSBuYW1lc3BhY2VOb2RlIFRoZSBub2RlIGZyb20gd2hpY2ggcHJlZml4ZXMgaW4gdGhlIFhQYXRoIHdpbGwgYmUgcmVzb2x2ZWQgdG8gbmFtZXNwYWNlcy4KLSAgICogIEByZXR1cm4gQSBOb2RlSXRlcmF0b3IsIHNob3VsZCBuZXZlciBiZSBudWxsLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgc3RhdGljIE5vZGVMaXN0IHNlbGVjdE5vZGVMaXN0KAotICAgICAgICAgIE5vZGUgY29udGV4dE5vZGUsIFN0cmluZyBzdHIsIE5vZGUgbmFtZXNwYWNlTm9kZSkKLSAgICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICAvLyBFeGVjdXRlIHRoZSBYUGF0aCwgYW5kIGhhdmUgaXQgcmV0dXJuIHRoZSByZXN1bHQKLSAgICBYT2JqZWN0IGxpc3QgPSBldmFsKGNvbnRleHROb2RlLCBzdHIsIG5hbWVzcGFjZU5vZGUpOwotCi0gICAgLy8gUmV0dXJuIGEgTm9kZUxpc3QuCi0gICAgcmV0dXJuIGxpc3Qubm9kZWxpc3QoKTsKLSAgfQotCi0gIC8qKgotICAgKiAgRXZhbHVhdGUgWFBhdGggc3RyaW5nIHRvIGFuIFhPYmplY3QuICBVc2luZyB0aGlzIG1ldGhvZCwKLSAgICogIFhQYXRoIG5hbWVzcGFjZSBwcmVmaXhlcyB3aWxsIGJlIHJlc29sdmVkIGZyb20gdGhlIG5hbWVzcGFjZU5vZGUuCi0gICAqICBAcGFyYW0gY29udGV4dE5vZGUgVGhlIG5vZGUgdG8gc3RhcnQgc2VhcmNoaW5nIGZyb20uCi0gICAqICBAcGFyYW0gc3RyIEEgdmFsaWQgWFBhdGggc3RyaW5nLgotICAgKiAgQHJldHVybiBBbiBYT2JqZWN0LCB3aGljaCBjYW4gYmUgdXNlZCB0byBvYnRhaW4gYSBzdHJpbmcsIG51bWJlciwgbm9kZWxpc3QsIGV0Yywgc2hvdWxkIG5ldmVyIGJlIG51bGwuCi0gICAqICBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhPYmplY3QKLSAgICogIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWE51bGwKLSAgICogIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWEJvb2xlYW4KLSAgICogIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWE51bWJlcgotICAgKiAgQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YU3RyaW5nCi0gICAqICBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhSVHJlZUZyYWcKLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBYT2JqZWN0IGV2YWwoTm9kZSBjb250ZXh0Tm9kZSwgU3RyaW5nIHN0cikKLSAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHJldHVybiBldmFsKGNvbnRleHROb2RlLCBzdHIsIGNvbnRleHROb2RlKTsKLSAgfQotCi0gIC8qKgotICAgKiAgRXZhbHVhdGUgWFBhdGggc3RyaW5nIHRvIGFuIFhPYmplY3QuCi0gICAqICBYUGF0aCBuYW1lc3BhY2UgcHJlZml4ZXMgYXJlIHJlc29sdmVkIGZyb20gdGhlIG5hbWVzcGFjZU5vZGUuCi0gICAqICBUaGUgaW1wbGVtZW50YXRpb24gb2YgdGhpcyBpcyBhIGxpdHRsZSBzbG93LCBzaW5jZSBpdCBjcmVhdGVzCi0gICAqICBhIG51bWJlciBvZiBvYmplY3RzIGVhY2ggdGltZSBpdCBpcyBjYWxsZWQuICBUaGlzIGNvdWxkIGJlIG9wdGltaXplZAotICAgKiAgdG8ga2VlcCB0aGUgc2FtZSBvYmplY3RzIGFyb3VuZCwgYnV0IHRoZW4gdGhyZWFkLXNhZmV0eSBpc3N1ZXMgd291bGQgYXJpc2UuCi0gICAqCi0gICAqICBAcGFyYW0gY29udGV4dE5vZGUgVGhlIG5vZGUgdG8gc3RhcnQgc2VhcmNoaW5nIGZyb20uCi0gICAqICBAcGFyYW0gc3RyIEEgdmFsaWQgWFBhdGggc3RyaW5nLgotICAgKiAgQHBhcmFtIG5hbWVzcGFjZU5vZGUgVGhlIG5vZGUgZnJvbSB3aGljaCBwcmVmaXhlcyBpbiB0aGUgWFBhdGggd2lsbCBiZSByZXNvbHZlZCB0byBuYW1lc3BhY2VzLgotICAgKiAgQHJldHVybiBBbiBYT2JqZWN0LCB3aGljaCBjYW4gYmUgdXNlZCB0byBvYnRhaW4gYSBzdHJpbmcsIG51bWJlciwgbm9kZWxpc3QsIGV0Yywgc2hvdWxkIG5ldmVyIGJlIG51bGwuCi0gICAqICBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhPYmplY3QKLSAgICogIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWE51bGwKLSAgICogIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWEJvb2xlYW4KLSAgICogIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWE51bWJlcgotICAgKiAgQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YU3RyaW5nCi0gICAqICBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhSVHJlZUZyYWcKLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBYT2JqZWN0IGV2YWwoTm9kZSBjb250ZXh0Tm9kZSwgU3RyaW5nIHN0ciwgTm9kZSBuYW1lc3BhY2VOb2RlKQotICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICAvLyBTaW5jZSB3ZSBkb24ndCBoYXZlIGEgWE1MIFBhcnNlciBpbnZvbHZlZCBoZXJlLCBpbnN0YWxsIHNvbWUgZGVmYXVsdCBzdXBwb3J0Ci0gICAgLy8gZm9yIHRoaW5ncyBsaWtlIG5hbWVzcGFjZXMsIGV0Yy4KLSAgICAvLyAoQ2hhbmdlZCBmcm9tOiBYUGF0aENvbnRleHQgeHBhdGhTdXBwb3J0ID0gbmV3IFhQYXRoQ29udGV4dCgpOwotICAgIC8vICAgIGJlY2F1c2UgWFBhdGhDb250ZXh0IGlzIHdlYWsgaW4gYSBudW1iZXIgb2YgYXJlYXMuLi4gcGVyaGFwcwotICAgIC8vICAgIFhQYXRoQ29udGV4dCBzaG91bGQgYmUgZG9uZSBhd2F5IHdpdGguKQotICAgIFhQYXRoQ29udGV4dCB4cGF0aFN1cHBvcnQgPSBuZXcgWFBhdGhDb250ZXh0KCk7Ci0KLSAgICAvLyBDcmVhdGUgYW4gb2JqZWN0IHRvIHJlc29sdmUgbmFtZXNwYWNlIHByZWZpeGVzLgotICAgIC8vIFhQYXRoIG5hbWVzcGFjZXMgYXJlIHJlc29sdmVkIGZyb20gdGhlIGlucHV0IGNvbnRleHQgbm9kZSdzIGRvY3VtZW50IGVsZW1lbnQKLSAgICAvLyBpZiBpdCBpcyBhIHJvb3Qgbm9kZSwgb3IgZWxzZSB0aGUgY3VycmVudCBjb250ZXh0IG5vZGUgKGZvciBsYWNrIG9mIGEgYmV0dGVyCi0gICAgLy8gcmVzb2x1dGlvbiBzcGFjZSwgZ2l2ZW4gdGhlIHNpbXBsaWNpdHkgb2YgdGhpcyBzYW1wbGUgY29kZSkuCi0gICAgUHJlZml4UmVzb2x2ZXJEZWZhdWx0IHByZWZpeFJlc29sdmVyID0gbmV3IFByZWZpeFJlc29sdmVyRGVmYXVsdCgKLSAgICAgIChuYW1lc3BhY2VOb2RlLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5ET0NVTUVOVF9OT0RFKQotICAgICAgPyAoKERvY3VtZW50KSBuYW1lc3BhY2VOb2RlKS5nZXREb2N1bWVudEVsZW1lbnQoKSA6IG5hbWVzcGFjZU5vZGUpOwotCi0gICAgLy8gQ3JlYXRlIHRoZSBYUGF0aCBvYmplY3QuCi0gICAgWFBhdGggeHBhdGggPSBuZXcgWFBhdGgoc3RyLCBudWxsLCBwcmVmaXhSZXNvbHZlciwgWFBhdGguU0VMRUNULCBudWxsKTsKLQotICAgIC8vIEV4ZWN1dGUgdGhlIFhQYXRoLCBhbmQgaGF2ZSBpdCByZXR1cm4gdGhlIHJlc3VsdAotICAgIC8vIHJldHVybiB4cGF0aC5leGVjdXRlKHhwYXRoU3VwcG9ydCwgY29udGV4dE5vZGUsIHByZWZpeFJlc29sdmVyKTsKLSAgICBpbnQgY3R4dE5vZGUgPSB4cGF0aFN1cHBvcnQuZ2V0RFRNSGFuZGxlRnJvbU5vZGUoY29udGV4dE5vZGUpOwotCi0gICAgcmV0dXJuIHhwYXRoLmV4ZWN1dGUoeHBhdGhTdXBwb3J0LCBjdHh0Tm9kZSwgcHJlZml4UmVzb2x2ZXIpOwotICB9Ci0KLSAgLyoqCi0gICAqICAgRXZhbHVhdGUgWFBhdGggc3RyaW5nIHRvIGFuIFhPYmplY3QuCi0gICAqICAgWFBhdGggbmFtZXNwYWNlIHByZWZpeGVzIGFyZSByZXNvbHZlZCBmcm9tIHRoZSBuYW1lc3BhY2VOb2RlLgotICAgKiAgIFRoZSBpbXBsZW1lbnRhdGlvbiBvZiB0aGlzIGlzIGEgbGl0dGxlIHNsb3csIHNpbmNlIGl0IGNyZWF0ZXMKLSAgICogICBhIG51bWJlciBvZiBvYmplY3RzIGVhY2ggdGltZSBpdCBpcyBjYWxsZWQuICBUaGlzIGNvdWxkIGJlIG9wdGltaXplZAotICAgKiAgIHRvIGtlZXAgdGhlIHNhbWUgb2JqZWN0cyBhcm91bmQsIGJ1dCB0aGVuIHRocmVhZC1zYWZldHkgaXNzdWVzIHdvdWxkIGFyaXNlLgotICAgKgotICAgKiAgIEBwYXJhbSBjb250ZXh0Tm9kZSBUaGUgbm9kZSB0byBzdGFydCBzZWFyY2hpbmcgZnJvbS4KLSAgICogICBAcGFyYW0gc3RyIEEgdmFsaWQgWFBhdGggc3RyaW5nLgotICAgKiAgIEBwYXJhbSBwcmVmaXhSZXNvbHZlciBXaWxsIGJlIGNhbGxlZCBpZiB0aGUgcGFyc2VyIGVuY291bnRlcnMgbmFtZXNwYWNlCi0gICAqICAgICAgICAgICAgICAgICAgICAgICAgIHByZWZpeGVzLCB0byByZXNvbHZlIHRoZSBwcmVmaXhlcyB0byBVUkxzLgotICAgKiAgIEByZXR1cm4gQW4gWE9iamVjdCwgd2hpY2ggY2FuIGJlIHVzZWQgdG8gb2J0YWluIGEgc3RyaW5nLCBudW1iZXIsIG5vZGVsaXN0LCBldGMsIHNob3VsZCBuZXZlciBiZSBudWxsLgotICAgKiAgIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWE9iamVjdAotICAgKiAgIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWE51bGwKLSAgICogICBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhCb29sZWFuCi0gICAqICAgQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YTnVtYmVyCi0gICAqICAgQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YU3RyaW5nCi0gICAqICAgQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YUlRyZWVGcmFnCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgWE9iamVjdCBldmFsKAotICAgICAgICAgIE5vZGUgY29udGV4dE5vZGUsIFN0cmluZyBzdHIsIFByZWZpeFJlc29sdmVyIHByZWZpeFJlc29sdmVyKQotICAgICAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIC8vIFNpbmNlIHdlIGRvbid0IGhhdmUgYSBYTUwgUGFyc2VyIGludm9sdmVkIGhlcmUsIGluc3RhbGwgc29tZSBkZWZhdWx0IHN1cHBvcnQKLSAgICAvLyBmb3IgdGhpbmdzIGxpa2UgbmFtZXNwYWNlcywgZXRjLgotICAgIC8vIChDaGFuZ2VkIGZyb206IFhQYXRoQ29udGV4dCB4cGF0aFN1cHBvcnQgPSBuZXcgWFBhdGhDb250ZXh0KCk7Ci0gICAgLy8gICAgYmVjYXVzZSBYUGF0aENvbnRleHQgaXMgd2VhayBpbiBhIG51bWJlciBvZiBhcmVhcy4uLiBwZXJoYXBzCi0gICAgLy8gICAgWFBhdGhDb250ZXh0IHNob3VsZCBiZSBkb25lIGF3YXkgd2l0aC4pCi0gICAgLy8gQ3JlYXRlIHRoZSBYUGF0aCBvYmplY3QuCi0gICAgWFBhdGggeHBhdGggPSBuZXcgWFBhdGgoc3RyLCBudWxsLCBwcmVmaXhSZXNvbHZlciwgWFBhdGguU0VMRUNULCBudWxsKTsKLQotICAgIC8vIEV4ZWN1dGUgdGhlIFhQYXRoLCBhbmQgaGF2ZSBpdCByZXR1cm4gdGhlIHJlc3VsdAotICAgIFhQYXRoQ29udGV4dCB4cGF0aFN1cHBvcnQgPSBuZXcgWFBhdGhDb250ZXh0KCk7Ci0gICAgaW50IGN0eHROb2RlID0geHBhdGhTdXBwb3J0LmdldERUTUhhbmRsZUZyb21Ob2RlKGNvbnRleHROb2RlKTsKLQotICAgIHJldHVybiB4cGF0aC5leGVjdXRlKHhwYXRoU3VwcG9ydCwgY3R4dE5vZGUsIHByZWZpeFJlc29sdmVyKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9YUGF0aENvbnRleHQuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvWFBhdGhDb250ZXh0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGZkNWRiNmYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9YUGF0aENvbnRleHQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEzMjQgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogWFBhdGhDb250ZXh0LmphdmEsdiAxLjIuNC4yIDIwMDUvMDkvMTUgMDE6Mzc6NTUgamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbDsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC5leHRlbnNpb25zLkV4cHJlc3Npb25Db250ZXh0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC5yZXMuWFNMTWVzc2FnZXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uQXhpczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE07Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNRmlsdGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTUl0ZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTU1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNV1NGaWx0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0ucmVmLnNheDJkdG0uU0FYMlJURkRUTTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLkludFN0YWNrOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuTm9kZVZlY3RvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLk9iamVjdFN0YWNrOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuUHJlZml4UmVzb2x2ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5YTUxTdHJpbmc7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmF4ZXMuU3ViQ29udGV4dExpc3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuRFRNWFJUcmVlRnJhZzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YT2JqZWN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhTdHJpbmc7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLnJlcy5YUEFUSEVycm9yUmVzb3VyY2VzOwotaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lk1ldGhvZDsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKLWltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7Ci1pbXBvcnQgamF2YS51dGlsLlN0YWNrOwotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5FcnJvckxpc3RlbmVyOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uU291cmNlTG9jYXRvcjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVVJJUmVzb2x2ZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguWE1MUmVhZGVyOwotCi0vKioKLSAqIERlZmF1bHQgY2xhc3MgZm9yIHRoZSBydW50aW1lIGV4ZWN1dGlvbiBjb250ZXh0IGZvciBYUGF0aC4KLSAqCi0gKiA8cD5UaGlzIGNsYXNzIGV4dGVuZHMgRFRNTWFuYWdlciBidXQgZG9lcyBub3QgZGlyZWN0bHkgaW1wbGVtZW50IGl0LjwvcD4KLSAqIEB4c2wudXNhZ2UgYWR2YW5jZWQKLSAqLwotcHVibGljIGNsYXNzIFhQYXRoQ29udGV4dCBleHRlbmRzIERUTU1hbmFnZXIgLy8gaW1wbGVtZW50cyBFeHByZXNzaW9uQ29udGV4dAotewotICAgICAgICBJbnRTdGFjayBtX2xhc3RfcHVzaGVkX3J0ZmR0bT1uZXcgSW50U3RhY2soKTsKLSAgLyoqCi0gICAqIFN0YWNrIG9mIGNhY2hlZCAicmV1c2FibGUiIERUTXMgZm9yIFJlc3VsdCBUcmVlIEZyYWdtZW50cy4KLSAgICogVGhpcyBpcyBhIGtsdWdlIHRvIGhhbmRsZSB0aGUgcHJvYmxlbSBvZiBzdGFydGluZyBhbiBSVEYgYmVmb3JlCi0gICAqIHRoZSBvbGQgb25lIGlzIGNvbXBsZXRlLgotICAgKgotICAgKiAlUkVWSUVXJSBJJ20gdXNpbmcgYSBWZWN0b3IgcmF0aGVyIHRoYW4gU3RhY2sgc28gd2UgY2FuIHJldXNlCi0gICAqIHRoZSBEVE1zIGlmIHRoZSBwcm9ibGVtIG9jY3VycyBtdWx0aXBsZSB0aW1lcy4gSSdtIG5vdCBzdXJlIHRoYXQncwotICAgKiByZWFsbHkgYSBuZXQgd2luIHZlcnN1cyBkaXNjYXJkaW5nIHRoZSBEVE0gYW5kIHN0YXJ0aW5nIGEgbmV3IG9uZS4uLgotICAgKiBidXQgdGhlIHJldGFpbmVkIFJURiBEVE0gd2lsbCBoYXZlIGJlZW4gdGFpbC1wcnVuZWQgc28gc2hvdWxkIGJlIHNtYWxsLgotICAgKi8KLSAgcHJpdmF0ZSBWZWN0b3IgbV9ydGZkdG1fc3RhY2s9bnVsbDsKLSAgLyoqIEluZGV4IG9mIGN1cnJlbnRseSBhY3RpdmUgUlRGIERUTSBpbiBtX3J0ZmR0bV9zdGFjayAqLwotICBwcml2YXRlIGludCBtX3doaWNoX3J0ZmR0bT0tMTsKLQotIC8qKgotICAgKiBNb3N0IHJlY2VudCAicmV1c2FibGUiIERUTSBmb3IgR2xvYmFsIFJlc3VsdCBUcmVlIEZyYWdtZW50cy4gTm8gc3RhY2sgaXMKLSAgICogcmVxdWlyZWQgc2luY2Ugd2UncmUgbmV2ZXIgZ29pbmcgdG8gcG9wIHRoZXNlLgotICAgKi8KLSAgcHJpdmF0ZSBTQVgyUlRGRFRNIG1fZ2xvYmFsX3J0ZmR0bT1udWxsOwotCi0gIC8qKgotICAgKiBIYXNoTWFwIG9mIGNhY2hlZCB0aGUgRFRNWFJUcmVlRnJhZyBvYmplY3RzLCB3aGljaCBhcmUgaWRlbnRpZmllZCBieSBEVE0gSURzLgotICAgKiBUaGUgb2JqZWN0IGFyZSBqdXN0IHdyYXBwZXJzIGZvciBEVE1zIHdoaWNoIGFyZSB1c2VkIGluICBYUlRyZWVGcmFnLgotICAgKi8KLSAgcHJpdmF0ZSBIYXNoTWFwIG1fRFRNWFJUcmVlRnJhZ3MgPSBudWxsOwotCi0gIC8qKgotICAgKiBzdGF0ZSBvZiB0aGUgc2VjdXJlIHByb2Nlc3NpbmcgZmVhdHVyZS4KLSAgICovCi0gIHByaXZhdGUgYm9vbGVhbiBtX2lzU2VjdXJlUHJvY2Vzc2luZyA9IGZhbHNlOwotCi0gIHByaXZhdGUgYm9vbGVhbiBtX3VzZVNlcnZpY2VzTWVjaGFuaXNtID0gdHJ1ZTsKLQotICAvKioKLSAgICogVGhvdWdoIFhQYXRoQ29udGV4dCBjb250ZXh0IGV4dGVuZHMKLSAgICogdGhlIERUTU1hbmFnZXIsIGl0IHJlYWxseSBpcyBhIHByb3h5IGZvciB0aGlzIG9iamVjdCwgd2hpY2gKLSAgICogaXMgdGhlIHJlYWwgRFRNTWFuYWdlci4KLSAgICovCi0gIHByb3RlY3RlZCBEVE1NYW5hZ2VyIG1fZHRtTWFuYWdlciA9IG51bGw7Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgRFRNTWFuYWdlciBvYmplY3QuICBUaG91Z2ggWFBhdGhDb250ZXh0IGNvbnRleHQgZXh0ZW5kcwotICAgKiB0aGUgRFRNTWFuYWdlciwgaXQgcmVhbGx5IGlzIGEgcHJveHkgZm9yIHRoZSByZWFsIERUTU1hbmFnZXIuICBJZiBhCi0gICAqIGNhbGxlciBuZWVkcyB0byBtYWtlIGEgbG90IG9mIGNhbGxzIHRvIHRoZSBEVE1NYW5hZ2VyLCBpdCBpcyBmYXN0ZXIKLSAgICogaWYgaXQgZ2V0cyB0aGUgcmVhbCBvbmUgZnJvbSB0aGlzIGZ1bmN0aW9uLgotICAgKi8KLSAgIHB1YmxpYyBEVE1NYW5hZ2VyIGdldERUTU1hbmFnZXIoKQotICAgewotICAgICByZXR1cm4gbV9kdG1NYW5hZ2VyOwotICAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIHN0YXRlIG9mIHRoZSBzZWN1cmUgcHJvY2Vzc2luZyBmZWF0dXJlCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRTZWN1cmVQcm9jZXNzaW5nKGJvb2xlYW4gZmxhZykKLSAgewotICAgIG1faXNTZWN1cmVQcm9jZXNzaW5nID0gZmxhZzsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIHN0YXRlIG9mIHRoZSBzZWN1cmUgcHJvY2Vzc2luZyBmZWF0dXJlCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBpc1NlY3VyZVByb2Nlc3NpbmcoKQotICB7Ci0gICAgcmV0dXJuIG1faXNTZWN1cmVQcm9jZXNzaW5nOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBhbiBpbnN0YW5jZSBvZiBhIERUTSwgbG9hZGVkIHdpdGggdGhlIGNvbnRlbnQgZnJvbSB0aGUKLSAgICogc3BlY2lmaWVkIHNvdXJjZS4gIElmIHRoZSB1bmlxdWUgZmxhZyBpcyB0cnVlLCBhIG5ldyBpbnN0YW5jZSB3aWxsCi0gICAqIGFsd2F5cyBiZSByZXR1cm5lZC4gIE90aGVyd2lzZSBpdCBpcyB1cCB0byB0aGUgRFRNTWFuYWdlciB0byByZXR1cm4gYQotICAgKiBuZXcgaW5zdGFuY2Ugb3IgYW4gaW5zdGFuY2UgdGhhdCBpdCBhbHJlYWR5IGNyZWF0ZWQgYW5kIG1heSBiZSBiZWluZyB1c2VkCi0gICAqIGJ5IHNvbWVvbmUgZWxzZS4KLSAgICogKEkgdGhpbmsgbW9yZSBwYXJhbWV0ZXJzIHdpbGwgbmVlZCB0byBiZSBhZGRlZCBmb3IgZXJyb3IgaGFuZGxpbmcsIGFuZCBlbnRpdHkKLSAgICogcmVzb2x1dGlvbikuCi0gICAqCi0gICAqIEBwYXJhbSBzb3VyY2UgdGhlIHNwZWNpZmljYXRpb24gb2YgdGhlIHNvdXJjZSBvYmplY3QsIHdoaWNoIG1heSBiZSBudWxsLAotICAgKiAgICAgICAgICAgICAgIGluIHdoaWNoIGNhc2UgaXQgaXMgYXNzdW1lZCB0aGF0IG5vZGUgY29uc3RydWN0aW9uIHdpbGwgdGFrZQotICAgKiAgICAgICAgICAgICAgIGJ5IHNvbWUgb3RoZXIgbWVhbnMuCi0gICAqIEBwYXJhbSB1bmlxdWUgdHJ1ZSBpZiB0aGUgcmV0dXJuZWQgRFRNIG11c3QgYmUgdW5pcXVlLCBwcm9iYWJseSBiZWNhdXNlIGl0Ci0gICAqIGlzIGdvaW5nIHRvIGJlIG11dGF0ZWQuCi0gICAqIEBwYXJhbSB3c2ZpbHRlciBFbmFibGVzIGZpbHRlcmluZyBvZiB3aGl0ZXNwYWNlIG5vZGVzLCBhbmQgbWF5IGJlIG51bGwuCi0gICAqIEBwYXJhbSBpbmNyZW1lbnRhbCB0cnVlIGlmIHRoZSBjb25zdHJ1Y3Rpb24gc2hvdWxkIHRyeSBhbmQgYmUgaW5jcmVtZW50YWwuCi0gICAqIEBwYXJhbSBkb0luZGV4aW5nIHRydWUgaWYgdGhlIGNhbGxlciBjb25zaWRlcnMgaXQgd29ydGggaXQgdG8gdXNlCi0gICAqICAgICAgICAgICAgICAgICAgIGluZGV4aW5nIHNjaGVtZXMuCi0gICAqCi0gICAqIEByZXR1cm4gYSBub24tbnVsbCBEVE0gcmVmZXJlbmNlLgotICAgKi8KLSAgcHVibGljIERUTSBnZXREVE0oamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2Ugc291cmNlLCBib29sZWFuIHVuaXF1ZSwKLSAgICAgICAgICAgICAgICAgICAgRFRNV1NGaWx0ZXIgd3NmaWx0ZXIsCi0gICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gaW5jcmVtZW50YWwsCi0gICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gZG9JbmRleGluZykKLSAgewotICAgIHJldHVybiBtX2R0bU1hbmFnZXIuZ2V0RFRNKHNvdXJjZSwgdW5pcXVlLCB3c2ZpbHRlciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmNyZW1lbnRhbCwgZG9JbmRleGluZyk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IGFuIGluc3RhbmNlIG9mIGEgRFRNIHRoYXQgIm93bnMiIGEgbm9kZSBoYW5kbGUuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIHRoZSBub2RlSGFuZGxlLgotICAgKgotICAgKiBAcmV0dXJuIGEgbm9uLW51bGwgRFRNIHJlZmVyZW5jZS4KLSAgICovCi0gIHB1YmxpYyBEVE0gZ2V0RFRNKGludCBub2RlSGFuZGxlKQotICB7Ci0gICAgcmV0dXJuIG1fZHRtTWFuYWdlci5nZXREVE0obm9kZUhhbmRsZSk7Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYSBXM0MgRE9NIG5vZGUsIHRyeSBhbmQgcmV0dXJuIGEgRFRNIGhhbmRsZS4KLSAgICogTm90ZTogY2FsbGluZyB0aGlzIG1heSBiZSBub24tb3B0aW1hbC4KLSAgICoKLSAgICogQHBhcmFtIG5vZGUgTm9uLW51bGwgcmVmZXJlbmNlIHRvIGEgRE9NIG5vZGUuCi0gICAqCi0gICAqIEByZXR1cm4gYSB2YWxpZCBEVE0gaGFuZGxlLgotICAgKi8KLSAgcHVibGljIGludCBnZXREVE1IYW5kbGVGcm9tTm9kZShvcmcudzNjLmRvbS5Ob2RlIG5vZGUpCi0gIHsKLSAgICByZXR1cm4gbV9kdG1NYW5hZ2VyLmdldERUTUhhbmRsZUZyb21Ob2RlKG5vZGUpOwotICB9Ci0vLwotLy8KLSAgLyoqCi0gICAqICVUQkQlIERvYwotICAgKi8KLSAgcHVibGljIGludCBnZXREVE1JZGVudGl0eShEVE0gZHRtKQotICB7Ci0gICAgcmV0dXJuIG1fZHRtTWFuYWdlci5nZXREVE1JZGVudGl0eShkdG0pOwotICB9Ci0vLwotICAvKioKLSAgICogQ3JlYXRlcyBhbiBlbXB0eSA8Y29kZT5Eb2N1bWVudEZyYWdtZW50PC9jb2RlPiBvYmplY3QuCi0gICAqIEByZXR1cm4gQSBuZXcgPGNvZGU+RG9jdW1lbnRGcmFnbWVudCBoYW5kbGU8L2NvZGU+LgotICAgKi8KLSAgcHVibGljIERUTSBjcmVhdGVEb2N1bWVudEZyYWdtZW50KCkKLSAgewotICAgIHJldHVybiBtX2R0bU1hbmFnZXIuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpOwotICB9Ci0vLwotICAvKioKLSAgICogUmVsZWFzZSBhIERUTSBlaXRoZXIgdG8gYSBscnUgcG9vbCwgb3IgY29tcGxldGVseSByZW1vdmUgcmVmZXJlbmNlLgotICAgKiBEVE1zIHdpdGhvdXQgc3lzdGVtIElEcyBhcmUgYWx3YXlzIGhhcmQgZGVsZXRlZC4KLSAgICogU3RhdGU6IGV4cGVyaW1lbnRhbC4KLSAgICoKLSAgICogQHBhcmFtIGR0bSBUaGUgRFRNIHRvIGJlIHJlbGVhc2VkLgotICAgKiBAcGFyYW0gc2hvdWxkSGFyZERlbGV0ZSBUcnVlIGlmIHRoZSBEVE0gc2hvdWxkIGJlIHJlbW92ZWQgbm8gbWF0dGVyIHdoYXQuCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgRFRNIHdhcyByZW1vdmVkLCBmYWxzZSBpZiBpdCB3YXMgcHV0IGJhY2sgaW4gYSBscnUgcG9vbC4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIHJlbGVhc2UoRFRNIGR0bSwgYm9vbGVhbiBzaG91bGRIYXJkRGVsZXRlKQotICB7Ci0gICAgLy8gJVJFVklFVyUgSWYgaXQncyBhIERUTSB3aGljaCBtYXkgY29udGFpbiBtdWx0aXBsZSBSZXN1bHQgVHJlZQotICAgIC8vIEZyYWdtZW50cywgd2UgY2FuJ3QgZGlzY2FyZCBpdCB1bmxlc3Mgd2Uga25vdyBub3Qgb25seSB0aGF0IGl0Ci0gICAgLy8gaXMgZW1wdHksIGJ1dCB0aGF0IHRoZSBYUGF0aENvbnRleHQgaXRzZWxmIGlzIGdvaW5nIGF3YXkuIFNvIGRvCi0gICAgLy8gX25vdF8gYWNjZXB0IHRoZSByZXF1ZXN0LiAoTWF5IHdhbnQgdG8gZG8gaXQgYXMgcGFydCBvZgotICAgIC8vIHJlc2V0KCksIHRob3VnaC4pCi0gICAgaWYobV9ydGZkdG1fc3RhY2shPW51bGwgJiYgbV9ydGZkdG1fc3RhY2suY29udGFpbnMoZHRtKSkKLSAgICB7Ci0gICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgcmV0dXJuIG1fZHRtTWFuYWdlci5yZWxlYXNlKGR0bSwgc2hvdWxkSGFyZERlbGV0ZSk7Ci0gIH0KLQotICAvKioKLSAgICogQ3JlYXRlIGEgbmV3IDxjb2RlPkRUTUl0ZXJhdG9yPC9jb2RlPiBiYXNlZCBvbiBhbiBYUGF0aAotICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aCNOVC1Mb2NhdGlvblBhdGg+TG9jYXRpb25QYXRoPC9hPiBvcgotICAgKiBhIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hwYXRoI05ULVVuaW9uRXhwciI+VW5pb25FeHByPC9hPi4KLSAgICoKLSAgICogQHBhcmFtIHhwYXRoQ29tcGlsZXIgPz8/IFNvbWVob3cgd2UgbmVlZCB0byBwYXNzIGluIGEgc3VicGFydCBvZiB0aGUKLSAgICogZXhwcmVzc2lvbi4gIEkgaGF0ZSB0byBkbyB0aGlzIHdpdGggc3RyaW5ncywgc2luY2UgdGhlIGxhcmdlciBleHByZXNzaW9uCi0gICAqIGhhcyBhbHJlYWR5IGJlZW4gcGFyc2VkLgotICAgKgotICAgKiBAcGFyYW0gcG9zIFRoZSBwb3NpdGlvbiBpbiB0aGUgZXhwcmVzc2lvbi4KLSAgICogQHJldHVybiBUaGUgbmV3bHkgY3JlYXRlZCA8Y29kZT5EVE1JdGVyYXRvcjwvY29kZT4uCi0gICAqLwotICBwdWJsaWMgRFRNSXRlcmF0b3IgY3JlYXRlRFRNSXRlcmF0b3IoT2JqZWN0IHhwYXRoQ29tcGlsZXIsIGludCBwb3MpCi0gIHsKLSAgICByZXR1cm4gbV9kdG1NYW5hZ2VyLmNyZWF0ZURUTUl0ZXJhdG9yKHhwYXRoQ29tcGlsZXIsIHBvcyk7Ci0gIH0KLS8vCi0gIC8qKgotICAgKiBDcmVhdGUgYSBuZXcgPGNvZGU+RFRNSXRlcmF0b3I8L2NvZGU+IGJhc2VkIG9uIGFuIFhQYXRoCi0gICAqIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hwYXRoI05ULUxvY2F0aW9uUGF0aD5Mb2NhdGlvblBhdGg8L2E+IG9yCi0gICAqIGEgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGgjTlQtVW5pb25FeHByIj5VbmlvbkV4cHI8L2E+LgotICAgKgotICAgKiBAcGFyYW0geHBhdGhTdHJpbmcgTXVzdCBiZSBhIHZhbGlkIHN0cmluZyBleHByZXNzaW5nIGEKLSAgICogPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGgjTlQtTG9jYXRpb25QYXRoPkxvY2F0aW9uUGF0aDwvYT4gb3IKLSAgICogYSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aCNOVC1VbmlvbkV4cHIiPlVuaW9uRXhwcjwvYT4uCi0gICAqCi0gICAqIEBwYXJhbSBwcmVzb2x2ZXIgQW4gb2JqZWN0IHRoYXQgY2FuIHJlc29sdmUgcHJlZml4ZXMgdG8gbmFtZXNwYWNlIFVSTHMuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIG5ld2x5IGNyZWF0ZWQgPGNvZGU+RFRNSXRlcmF0b3I8L2NvZGU+LgotICAgKi8KLSAgcHVibGljIERUTUl0ZXJhdG9yIGNyZWF0ZURUTUl0ZXJhdG9yKFN0cmluZyB4cGF0aFN0cmluZywKLSAgICAgICAgICBQcmVmaXhSZXNvbHZlciBwcmVzb2x2ZXIpCi0gIHsKLSAgICByZXR1cm4gbV9kdG1NYW5hZ2VyLmNyZWF0ZURUTUl0ZXJhdG9yKHhwYXRoU3RyaW5nLCBwcmVzb2x2ZXIpOwotICB9Ci0vLwotICAvKioKLSAgICogQ3JlYXRlIGEgbmV3IDxjb2RlPkRUTUl0ZXJhdG9yPC9jb2RlPiBiYXNlZCBvbmx5IG9uIGEgd2hhdFRvU2hvdyBhbmQKLSAgICogYSBEVE1GaWx0ZXIuICBUaGUgdHJhdmVyc2FsIHNlbWFudGljcyBhcmUgZGVmaW5lZCBhcyB0aGUgZGVzY2VuZGFudAotICAgKiBhY2Nlc3MuCi0gICAqCi0gICAqIEBwYXJhbSB3aGF0VG9TaG93IFRoaXMgZmxhZyBzcGVjaWZpZXMgd2hpY2ggbm9kZSB0eXBlcyBtYXkgYXBwZWFyIGluCi0gICAqICAgdGhlIGxvZ2ljYWwgdmlldyBvZiB0aGUgdHJlZSBwcmVzZW50ZWQgYnkgdGhlIGl0ZXJhdG9yLiBTZWUgdGhlCi0gICAqICAgZGVzY3JpcHRpb24gb2YgPGNvZGU+Tm9kZUZpbHRlcjwvY29kZT4gZm9yIHRoZSBzZXQgb2YgcG9zc2libGUKLSAgICogICA8Y29kZT5TSE9XXzwvY29kZT4gdmFsdWVzLlRoZXNlIGZsYWdzIGNhbiBiZSBjb21iaW5lZCB1c2luZwotICAgKiAgIDxjb2RlPk9SPC9jb2RlPi4KLSAgICogQHBhcmFtIGZpbHRlciBUaGUgPGNvZGU+Tm9kZUZpbHRlcjwvY29kZT4gdG8gYmUgdXNlZCB3aXRoIHRoaXMKLSAgICogICA8Y29kZT5UcmVlV2Fsa2VyPC9jb2RlPiwgb3IgPGNvZGU+bnVsbDwvY29kZT4gdG8gaW5kaWNhdGUgbm8gZmlsdGVyLgotICAgKiBAcGFyYW0gZW50aXR5UmVmZXJlbmNlRXhwYW5zaW9uIFRoZSB2YWx1ZSBvZiB0aGlzIGZsYWcgZGV0ZXJtaW5lcwotICAgKiAgIHdoZXRoZXIgZW50aXR5IHJlZmVyZW5jZSBub2RlcyBhcmUgZXhwYW5kZWQuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIG5ld2x5IGNyZWF0ZWQgPGNvZGU+Tm9kZUl0ZXJhdG9yPC9jb2RlPi4KLSAgICovCi0gIHB1YmxpYyBEVE1JdGVyYXRvciBjcmVhdGVEVE1JdGVyYXRvcihpbnQgd2hhdFRvU2hvdywKLSAgICAgICAgICBEVE1GaWx0ZXIgZmlsdGVyLCBib29sZWFuIGVudGl0eVJlZmVyZW5jZUV4cGFuc2lvbikKLSAgewotICAgIHJldHVybiBtX2R0bU1hbmFnZXIuY3JlYXRlRFRNSXRlcmF0b3Iod2hhdFRvU2hvdywgZmlsdGVyLCBlbnRpdHlSZWZlcmVuY2VFeHBhbnNpb24pOwotICB9Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIG5ldyA8Y29kZT5EVE1JdGVyYXRvcjwvY29kZT4gdGhhdCBob2xkcyBleGFjdGx5IG9uZSBub2RlLgotICAgKgotICAgKiBAcGFyYW0gbm9kZSBUaGUgbm9kZSBoYW5kbGUgdGhhdCB0aGUgRFRNSXRlcmF0b3Igd2lsbCBpdGVyYXRlIHRvLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBuZXdseSBjcmVhdGVkIDxjb2RlPkRUTUl0ZXJhdG9yPC9jb2RlPi4KLSAgICovCi0gIHB1YmxpYyBEVE1JdGVyYXRvciBjcmVhdGVEVE1JdGVyYXRvcihpbnQgbm9kZSkKLSAgewotICAgIC8vIERlc2NlbmRhbnRJdGVyYXRvciBpdGVyID0gbmV3IERlc2NlbmRhbnRJdGVyYXRvcigpOwotICAgIERUTUl0ZXJhdG9yIGl0ZXIgPSBuZXcgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmF4ZXMuT25lU3RlcEl0ZXJhdG9yRm9yd2FyZChBeGlzLlNFTEYpOwotICAgIGl0ZXIuc2V0Um9vdChub2RlLCB0aGlzKTsKLSAgICByZXR1cm4gaXRlcjsKLSAgICAvLyByZXR1cm4gbV9kdG1NYW5hZ2VyLmNyZWF0ZURUTUl0ZXJhdG9yKG5vZGUpOwotICB9Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhbiBYUGF0aENvbnRleHQgaW5zdGFuY2UuCi0gICAqLwotICBwdWJsaWMgWFBhdGhDb250ZXh0KCkKLSAgewotICAgIHRoaXModHJ1ZSk7Ci0gIH0KLQotICBwdWJsaWMgWFBhdGhDb250ZXh0KGJvb2xlYW4gdXNlU2VydmljZXNNZWNoYW5pc20pIHsKLSAgICAgIGluaXQodXNlU2VydmljZXNNZWNoYW5pc20pOwotICB9Ci0gIC8qKgotICAgKipUaGlzIGNvbnN0cnVjdG9yIGRvZXNuJ3Qgc2VlbSB0byBiZSB1c2VkIGFueXdoZXJlIC0tIGh1aXpoZSB3YW5nKioKLSAgICogQ3JlYXRlIGFuIFhQYXRoQ29udGV4dCBpbnN0YW5jZS4KLSAgICogQHBhcmFtIG93bmVyIFZhbHVlIHRoYXQgY2FuIGJlIHJldHJpZXZlZCB2aWEgdGhlIGdldE93bmVyT2JqZWN0KCkgbWV0aG9kLgotICAgKiBAc2VlICNnZXRPd25lck9iamVjdAotICAgKi8KLSAgcHVibGljIFhQYXRoQ29udGV4dChPYmplY3Qgb3duZXIpCi0gIHsKLSAgICBtX293bmVyID0gb3duZXI7Ci0gICAgdHJ5IHsKLSAgICAgIG1fb3duZXJHZXRFcnJvckxpc3RlbmVyID0gbV9vd25lci5nZXRDbGFzcygpLmdldE1ldGhvZCgiZ2V0RXJyb3JMaXN0ZW5lciIsIG5ldyBDbGFzc1tdIHt9KTsKLSAgICB9Ci0gICAgY2F0Y2ggKE5vU3VjaE1ldGhvZEV4Y2VwdGlvbiBuc21lKSB7fQotICAgIGluaXQodHJ1ZSk7Ci0gIH0KLQotICBwcml2YXRlIHZvaWQgaW5pdChib29sZWFuIHVzZVNlcnZpY2VzTWVjaGFuaXNtKSB7Ci0gICAgbV9wcmVmaXhSZXNvbHZlcnMucHVzaChudWxsKTsKLSAgICBtX2N1cnJlbnROb2Rlcy5wdXNoKERUTS5OVUxMKTsKLSAgICBtX2N1cnJlbnRFeHByZXNzaW9uTm9kZXMucHVzaChEVE0uTlVMTCk7Ci0gICAgbV9zYXhMb2NhdGlvbnMucHVzaChudWxsKTsKLSAgICBtX3VzZVNlcnZpY2VzTWVjaGFuaXNtID0gdXNlU2VydmljZXNNZWNoYW5pc207Ci0gICAgbV9kdG1NYW5hZ2VyID0gRFRNTWFuYWdlci5uZXdJbnN0YW5jZSgKLSAgICAgICAgICAgICAgICAgICBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YTUxTdHJpbmdGYWN0b3J5SW1wbC5nZXRGYWN0b3J5KCkKLSAgICAgICAgICAgICAgICAgICApOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlc2V0IGZvciBuZXcgcnVuLgotICAgKi8KLSAgcHVibGljIHZvaWQgcmVzZXQoKQotICB7Ci0gICAgcmVsZWFzZURUTVhSVHJlZUZyYWdzKCk7Ci0gICAgICAgIC8vIFRoZXNlIGNvdWxkbid0IGJlIGRpc3Bvc2VkIG9mIGVhcmxpZXIgKHNlZSBjb21tZW50cyBpbiByZWxlYXNlKCkpOyB6YXAgdGhlbSBub3cuCi0gICAgICAgIGlmKG1fcnRmZHRtX3N0YWNrIT1udWxsKQotICAgICAgICAgICAgICAgICBmb3IgKGphdmEudXRpbC5FbnVtZXJhdGlvbiBlID0gbV9ydGZkdG1fc3RhY2suZWxlbWVudHMoKSA7IGUuaGFzTW9yZUVsZW1lbnRzKCkgOykKLSAgICAgICAgICAgICAgICAgICAgICAgIG1fZHRtTWFuYWdlci5yZWxlYXNlKChEVE0pZS5uZXh0RWxlbWVudCgpLCB0cnVlKTsKLQotICAgIG1fcnRmZHRtX3N0YWNrPW51bGw7IC8vIGRyb3Agb3VyIHJlZmVyZW5jZXMgdG9vCi0gICAgbV93aGljaF9ydGZkdG09LTE7Ci0KLSAgICBpZihtX2dsb2JhbF9ydGZkdG0hPW51bGwpCi0gICAgICAgICAgICAgICAgICAgICAgICBtX2R0bU1hbmFnZXIucmVsZWFzZShtX2dsb2JhbF9ydGZkdG0sdHJ1ZSk7Ci0gICAgbV9nbG9iYWxfcnRmZHRtPW51bGw7Ci0KLQotICAgIG1fZHRtTWFuYWdlciA9IERUTU1hbmFnZXIubmV3SW5zdGFuY2UoCi0gICAgICAgICAgICAgICAgICAgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWE1MU3RyaW5nRmFjdG9yeUltcGwuZ2V0RmFjdG9yeSgpCi0gICAgICAgICAgICAgICAgICAgKTsKLQotICAgIG1fc2F4TG9jYXRpb25zLnJlbW92ZUFsbEVsZW1lbnRzKCk7Ci0gICAgICAgIG1fYXhlc0l0ZXJhdG9yU3RhY2sucmVtb3ZlQWxsRWxlbWVudHMoKTsKLSAgICAgICAgbV9jb250ZXh0Tm9kZUxpc3RzLnJlbW92ZUFsbEVsZW1lbnRzKCk7Ci0gICAgICAgIG1fY3VycmVudEV4cHJlc3Npb25Ob2Rlcy5yZW1vdmVBbGxFbGVtZW50cygpOwotICAgICAgICBtX2N1cnJlbnROb2Rlcy5yZW1vdmVBbGxFbGVtZW50cygpOwotICAgICAgICBtX2l0ZXJhdG9yUm9vdHMuUmVtb3ZlQWxsTm9DbGVhcigpOwotICAgICAgICBtX3ByZWRpY2F0ZVBvcy5yZW1vdmVBbGxFbGVtZW50cygpOwotICAgICAgICBtX3ByZWRpY2F0ZVJvb3RzLlJlbW92ZUFsbE5vQ2xlYXIoKTsKLSAgICAgICAgbV9wcmVmaXhSZXNvbHZlcnMucmVtb3ZlQWxsRWxlbWVudHMoKTsKLQotICAgICAgICBtX3ByZWZpeFJlc29sdmVycy5wdXNoKG51bGwpOwotICAgIG1fY3VycmVudE5vZGVzLnB1c2goRFRNLk5VTEwpOwotICAgIG1fY3VycmVudEV4cHJlc3Npb25Ob2Rlcy5wdXNoKERUTS5OVUxMKTsKLSAgICBtX3NheExvY2F0aW9ucy5wdXNoKG51bGwpOwotICB9Ci0KLSAgLyoqIFRoZSBjdXJyZW50IHN0eWxlc2hlZXQgbG9jYXRvci4gKi8KLSAgT2JqZWN0U3RhY2sgbV9zYXhMb2NhdGlvbnMgPSBuZXcgT2JqZWN0U3RhY2soUkVDVVJTSU9OTElNSVQpOwotCi0gIC8qKgotICAgKiBTZXQgdGhlIGN1cnJlbnQgbG9jYXRlciBpbiB0aGUgc3R5bGVzaGVldC4KLSAgICoKLSAgICogQHBhcmFtIGxvY2F0aW9uIFRoZSBsb2NhdGlvbiB3aXRoaW4gdGhlIHN0eWxlc2hlZXQuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRTQVhMb2NhdG9yKFNvdXJjZUxvY2F0b3IgbG9jYXRpb24pCi0gIHsKLSAgICBtX3NheExvY2F0aW9ucy5zZXRUb3AobG9jYXRpb24pOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgY3VycmVudCBsb2NhdGVyIGluIHRoZSBzdHlsZXNoZWV0LgotICAgKgotICAgKiBAcGFyYW0gbG9jYXRpb24gVGhlIGxvY2F0aW9uIHdpdGhpbiB0aGUgc3R5bGVzaGVldC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHB1c2hTQVhMb2NhdG9yKFNvdXJjZUxvY2F0b3IgbG9jYXRpb24pCi0gIHsKLSAgICBtX3NheExvY2F0aW9ucy5wdXNoKGxvY2F0aW9uKTsKLSAgfQotCi0gIC8qKgotICAgKiBQdXNoIGEgc2xvdCBvbiB0aGUgbG9jYXRpb25zIHN0YWNrIHNvIHRoYXQgc2V0U0FYTG9jYXRvciBjYW4gYmUKLSAgICogcmVwZWF0ZWRseSBjYWxsZWQuCi0gICAqCi0gICAqLwotICBwdWJsaWMgdm9pZCBwdXNoU0FYTG9jYXRvck51bGwoKQotICB7Ci0gICAgbV9zYXhMb2NhdGlvbnMucHVzaChudWxsKTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIFBvcCB0aGUgY3VycmVudCBsb2NhdGVyLgotICAgKi8KLSAgcHVibGljIHZvaWQgcG9wU0FYTG9jYXRvcigpCi0gIHsKLSAgICBtX3NheExvY2F0aW9ucy5wb3AoKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGN1cnJlbnQgbG9jYXRlciBpbiB0aGUgc3R5bGVzaGVldC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgbG9jYXRpb24gd2l0aGluIHRoZSBzdHlsZXNoZWV0LCBvciBudWxsIGlmIG5vdCBrbm93bi4KLSAgICovCi0gIHB1YmxpYyBTb3VyY2VMb2NhdG9yIGdldFNBWExvY2F0b3IoKQotICB7Ci0gICAgcmV0dXJuIChTb3VyY2VMb2NhdG9yKSBtX3NheExvY2F0aW9ucy5wZWVrKCk7Ci0gIH0KLQotICAvKiogVGhlIG93bmVyIGNvbnRleHQgb2YgdGhpcyBYUGF0aENvbnRleHQuICBJbiB0aGUgY2FzZSBvZiBYU0xULCB0aGlzIHdpbGwgYmUgYQotICAgKiAgVHJhbnNmb3JtZXIgb2JqZWN0LgotICAgKi8KLSAgcHJpdmF0ZSBPYmplY3QgbV9vd25lcjsKLQotICAvKiogVGhlIG93bmVyIGNvbnRleHQgb2YgdGhpcyBYUGF0aENvbnRleHQuICBJbiB0aGUgY2FzZSBvZiBYU0xULCB0aGlzIHdpbGwgYmUgYQotICAgKiAgVHJhbnNmb3JtZXIgb2JqZWN0LgotICAgKi8KLSAgcHJpdmF0ZSBNZXRob2QgbV9vd25lckdldEVycm9yTGlzdGVuZXI7Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgIm93bmVyIiBjb250ZXh0IG9mIHRoaXMgY29udGV4dCwgd2hpY2ggc2hvdWxkIGJlLAotICAgKiBpbiB0aGUgY2FzZSBvZiBYU0xULCB0aGUgVHJhbnNmb3JtZXIgb2JqZWN0LiAgVGhpcyBpcyBuZWVkZWQKLSAgICogc28gdGhhdCBYU0xUIGZ1bmN0aW9ucyBjYW4gZ2V0IHRoZSBUcmFuc2Zvcm1lci4KLSAgICogQHJldHVybiBUaGUgb3duZXIgb2JqZWN0IHBhc3NlZCBpbnRvIHRoZSBjb25zdHJ1Y3Rvciwgb3IgbnVsbC4KLSAgICovCi0gIHB1YmxpYyBPYmplY3QgZ2V0T3duZXJPYmplY3QoKQotICB7Ci0gICAgcmV0dXJuIG1fb3duZXI7Ci0gIH0KLQotICAvLyA9PT09PT09PT09PT09PT09IFZhclN0YWNrID09PT09PT09PT09PT09PT09PT0KLQotICAvKioKLSAgICogVGhlIHN0YWNrIG9mIFZhcmlhYmxlIHN0YWNrcy4gIEEgVmFyaWFibGVTdGFjayB3aWxsIGJlCi0gICAqIHB1c2hlZCBvbnRvIHRoaXMgc3RhY2sgZm9yIGVhY2ggdGVtcGxhdGUgaW52b2NhdGlvbi4KLSAgICovCi0gIHByaXZhdGUgVmFyaWFibGVTdGFjayBtX3ZhcmlhYmxlU3RhY2tzID0gbmV3IFZhcmlhYmxlU3RhY2soKTsKLQotICAvKioKLSAgICogR2V0IHRoZSB2YXJpYWJsZSBzdGFjaywgd2hpY2ggaXMgaW4gY2hhcmdlIG9mIHZhcmlhYmxlcyBhbmQKLSAgICogcGFyYW1ldGVycy4KLSAgICoKLSAgICogQHJldHVybiB0aGUgdmFyaWFibGUgc3RhY2ssIHdoaWNoIHNob3VsZCBub3QgYmUgbnVsbC4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBWYXJpYWJsZVN0YWNrIGdldFZhclN0YWNrKCkKLSAgewotICAgIHJldHVybiBtX3ZhcmlhYmxlU3RhY2tzOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgdmFyaWFibGUgc3RhY2ssIHdoaWNoIGlzIGluIGNoYXJnZSBvZiB2YXJpYWJsZXMgYW5kCi0gICAqIHBhcmFtZXRlcnMuCi0gICAqCi0gICAqIEBwYXJhbSB2YXJTdGFjayBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIHZhcmlhYmxlIHN0YWNrLgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgc2V0VmFyU3RhY2soVmFyaWFibGVTdGFjayB2YXJTdGFjaykKLSAgewotICAgIG1fdmFyaWFibGVTdGFja3MgPSB2YXJTdGFjazsKLSAgfQotCi0gIC8vID09PT09PT09PT09PT09PT0gU291cmNlVHJlZU1hbmFnZXIgPT09PT09PT09PT09PT09PT09PQotCi0gIC8qKiBUaGUgc291cmNlIHRyZWUgbWFuYWdlciwgd2hpY2ggYXNzb2NpYXRlcyBTb3VyY2Ugb2JqZWN0cyB0byBzb3VyY2UKLSAgICogIHRyZWUgbm9kZXMuICovCi0gIHByaXZhdGUgU291cmNlVHJlZU1hbmFnZXIgbV9zb3VyY2VUcmVlTWFuYWdlciA9IG5ldyBTb3VyY2VUcmVlTWFuYWdlcigpOwotCi0gIC8qKgotICAgKiBHZXQgdGhlIFNvdXJjZVRyZWVNYW5hZ2VyIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGV4ZWN1dGlvbiBjb250ZXh0LgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBTb3VyY2VUcmVlTWFuYWdlciBhc3NvY2lhdGVkIHdpdGggdGhpcyBleGVjdXRpb24gY29udGV4dC4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBTb3VyY2VUcmVlTWFuYWdlciBnZXRTb3VyY2VUcmVlTWFuYWdlcigpCi0gIHsKLSAgICByZXR1cm4gbV9zb3VyY2VUcmVlTWFuYWdlcjsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIFNvdXJjZVRyZWVNYW5hZ2VyIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGV4ZWN1dGlvbiBjb250ZXh0LgotICAgKgotICAgKiBAcGFyYW0gbWdyIHRoZSBTb3VyY2VUcmVlTWFuYWdlciB0byBiZSBhc3NvY2lhdGVkIHdpdGggdGhpcwotICAgKiAgICAgICAgZXhlY3V0aW9uIGNvbnRleHQuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRTb3VyY2VUcmVlTWFuYWdlcihTb3VyY2VUcmVlTWFuYWdlciBtZ3IpCi0gIHsKLSAgICBtX3NvdXJjZVRyZWVNYW5hZ2VyID0gbWdyOwotICB9Ci0KLSAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotCi0gIC8qKiBUaGUgRXJyb3JMaXN0ZW5lciB3aGVyZSBlcnJvcnMgYW5kIHdhcm5pbmdzIGFyZSB0byBiZSByZXBvcnRlZC4gICAqLwotICBwcml2YXRlIEVycm9yTGlzdGVuZXIgbV9lcnJvckxpc3RlbmVyOwotCi0gIC8qKiBBIGRlZmF1bHQgRXJyb3JMaXN0ZW5lciBpbiBjYXNlIG91ciBtX2Vycm9yTGlzdGVuZXIgd2FzIG5vdCBzcGVjaWZpZWQgYW5kIG91cgotICAgKiAgb3duZXIgZWl0aGVyIGRvZXMgbm90IGhhdmUgYW4gRXJyb3JMaXN0ZW5lciBvciBoYXMgYSBudWxsIG9uZS4KLSAgICovCi0gIHByaXZhdGUgRXJyb3JMaXN0ZW5lciBtX2RlZmF1bHRFcnJvckxpc3RlbmVyOwotCi0gIC8qKgotICAgKiBHZXQgdGhlIEVycm9yTGlzdGVuZXIgd2hlcmUgZXJyb3JzIGFuZCB3YXJuaW5ncyBhcmUgdG8gYmUgcmVwb3J0ZWQuCi0gICAqCi0gICAqIEByZXR1cm4gQSBub24tbnVsbCBFcnJvckxpc3RlbmVyIHJlZmVyZW5jZS4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBFcnJvckxpc3RlbmVyIGdldEVycm9yTGlzdGVuZXIoKQotICB7Ci0KLSAgICBpZiAobnVsbCAhPSBtX2Vycm9yTGlzdGVuZXIpCi0gICAgICAgIHJldHVybiBtX2Vycm9yTGlzdGVuZXI7Ci0KLSAgICBFcnJvckxpc3RlbmVyIHJldHZhbCA9IG51bGw7Ci0KLSAgICB0cnkgewotICAgICAgaWYgKG51bGwgIT0gbV9vd25lckdldEVycm9yTGlzdGVuZXIpCi0gICAgICAgIHJldHZhbCA9IChFcnJvckxpc3RlbmVyKSBtX293bmVyR2V0RXJyb3JMaXN0ZW5lci5pbnZva2UobV9vd25lciwgbmV3IE9iamVjdFtdIHt9KTsKLSAgICB9Ci0gICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7fQotCi0gICAgaWYgKG51bGwgPT0gcmV0dmFsKQotICAgIHsKLSAgICAgIGlmIChudWxsID09IG1fZGVmYXVsdEVycm9yTGlzdGVuZXIpCi0gICAgICAgIG1fZGVmYXVsdEVycm9yTGlzdGVuZXIgPSBuZXcgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5EZWZhdWx0RXJyb3JIYW5kbGVyKCk7Ci0gICAgICByZXR2YWwgPSBtX2RlZmF1bHRFcnJvckxpc3RlbmVyOwotICAgIH0KLQotICAgIHJldHVybiByZXR2YWw7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBFcnJvckxpc3RlbmVyIHdoZXJlIGVycm9ycyBhbmQgd2FybmluZ3MgYXJlIHRvIGJlIHJlcG9ydGVkLgotICAgKgotICAgKiBAcGFyYW0gbGlzdGVuZXIgQSBub24tbnVsbCBFcnJvckxpc3RlbmVyIHJlZmVyZW5jZS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldEVycm9yTGlzdGVuZXIoRXJyb3JMaXN0ZW5lciBsaXN0ZW5lcikgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgotICB7Ci0gICAgaWYgKGxpc3RlbmVyID09IG51bGwpCi0gICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShYUEFUSEVycm9yUmVzb3VyY2VzLkVSX05VTExfRVJST1JfSEFORExFUiwgbnVsbCkpOyAvLyJOdWxsIGVycm9yIGhhbmRsZXIiKTsKLSAgICBtX2Vycm9yTGlzdGVuZXIgPSBsaXN0ZW5lcjsKLSAgfQotCi0KLSAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotCi0gIC8qKiBUaGUgVHJBWCBVUkkgUmVzb2x2ZXIgZm9yIHJlc29sdmluZyBVUklzIGZyb20gdGhlIGRvY3VtZW50KC4uLikKLSAgICogIGZ1bmN0aW9uIHRvIHNvdXJjZSB0cmVlIG5vZGVzLiAgKi8KLSAgcHJpdmF0ZSBVUklSZXNvbHZlciBtX3VyaVJlc29sdmVyOwotCi0gIC8qKgotICAgKiBHZXQgdGhlIFVSSVJlc29sdmVyIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGV4ZWN1dGlvbiBjb250ZXh0LgotICAgKgotICAgKiBAcmV0dXJuIGEgVVJJIHJlc29sdmVyLCB3aGljaCBtYXkgYmUgbnVsbC4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBVUklSZXNvbHZlciBnZXRVUklSZXNvbHZlcigpCi0gIHsKLSAgICByZXR1cm4gbV91cmlSZXNvbHZlcjsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIFVSSVJlc29sdmVyIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGV4ZWN1dGlvbiBjb250ZXh0LgotICAgKgotICAgKiBAcGFyYW0gcmVzb2x2ZXIgdGhlIFVSSVJlc29sdmVyIHRvIGJlIGFzc29jaWF0ZWQgd2l0aCB0aGlzCi0gICAqICAgICAgICBleGVjdXRpb24gY29udGV4dCwgbWF5IGJlIG51bGwgdG8gY2xlYXIgYW4gYWxyZWFkeSBzZXQgcmVzb2x2ZXIuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRVUklSZXNvbHZlcihVUklSZXNvbHZlciByZXNvbHZlcikKLSAgewotICAgIG1fdXJpUmVzb2x2ZXIgPSByZXNvbHZlcjsKLSAgfQotCi0gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLQotICAvKiogVGhlIHJlYWRlciBvZiB0aGUgcHJpbWFyeSBzb3VyY2UgdHJlZS4gICAgKi8KLSAgcHVibGljIFhNTFJlYWRlciBtX3ByaW1hcnlSZWFkZXI7Ci0KLSAgLyoqCi0gICAqIEdldCBwcmltYXJ5IFhNTFJlYWRlciBhc3NvY2lhdGVkIHdpdGggdGhpcyBleGVjdXRpb24gY29udGV4dC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgcmVhZGVyIG9mIHRoZSBwcmltYXJ5IHNvdXJjZSB0cmVlLgotICAgKi8KLSAgcHVibGljIGZpbmFsIFhNTFJlYWRlciBnZXRQcmltYXJ5UmVhZGVyKCkKLSAgewotICAgIHJldHVybiBtX3ByaW1hcnlSZWFkZXI7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHByaW1hcnkgWE1MUmVhZGVyIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGV4ZWN1dGlvbiBjb250ZXh0LgotICAgKgotICAgKiBAcGFyYW0gcmVhZGVyIFRoZSByZWFkZXIgb2YgdGhlIHByaW1hcnkgc291cmNlIHRyZWUuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRQcmltYXJ5UmVhZGVyKFhNTFJlYWRlciByZWFkZXIpCi0gIHsKLSAgICBtX3ByaW1hcnlSZWFkZXIgPSByZWFkZXI7Ci0gIH0KLQotICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0KLQotICAvKiogTWlzbmFtZWQgc3RyaW5nIG1hbmFnZXIgZm9yIFhQYXRoIG1lc3NhZ2VzLiAgKi8KLSAgLy8gcHJpdmF0ZSBzdGF0aWMgWFNMTWVzc2FnZXMgbV9YU0xNZXNzYWdlcyA9IG5ldyBYU0xNZXNzYWdlcygpOwotCi0gIC8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICAvLyBTRUNUSU9OOiBFeGVjdXRpb24gY29udGV4dCBzdGF0ZSB0cmFja2luZwotICAvLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLQotICAvKioKLSAgICogVGhlIGN1cnJlbnQgY29udGV4dCBub2RlIGxpc3QuCi0gICAqLwotICBwcml2YXRlIFN0YWNrIG1fY29udGV4dE5vZGVMaXN0cyA9IG5ldyBTdGFjaygpOwotCi0gIHB1YmxpYyBTdGFjayBnZXRDb250ZXh0Tm9kZUxpc3RzU3RhY2soKSB7IHJldHVybiBtX2NvbnRleHROb2RlTGlzdHM7IH0KLSAgcHVibGljIHZvaWQgc2V0Q29udGV4dE5vZGVMaXN0c1N0YWNrKFN0YWNrIHMpIHsgbV9jb250ZXh0Tm9kZUxpc3RzID0gczsgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGN1cnJlbnQgY29udGV4dCBub2RlIGxpc3QuCi0gICAqCi0gICAqIEByZXR1cm4gIHRoZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2R0LWN1cnJlbnQtbm9kZS1saXN0Ij5jdXJyZW50IG5vZGUgbGlzdDwvYT4sCi0gICAqIGFsc28gcmVmZXJyZWQgdG8gaGVyZSBhcyBhIDx0ZXJtPmNvbnRleHQgbm9kZSBsaXN0PC90ZXJtPi4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBEVE1JdGVyYXRvciBnZXRDb250ZXh0Tm9kZUxpc3QoKQotICB7Ci0KLSAgICBpZiAobV9jb250ZXh0Tm9kZUxpc3RzLnNpemUoKSA+IDApCi0gICAgICByZXR1cm4gKERUTUl0ZXJhdG9yKSBtX2NvbnRleHROb2RlTGlzdHMucGVlaygpOwotICAgIGVsc2UKLSAgICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgY3VycmVudCBjb250ZXh0IG5vZGUgbGlzdC4KLSAgICoKLSAgICogQHBhcmFtIG5sIHRoZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2R0LWN1cnJlbnQtbm9kZS1saXN0Ij5jdXJyZW50IG5vZGUgbGlzdDwvYT4sCi0gICAqIGFsc28gcmVmZXJyZWQgdG8gaGVyZSBhcyBhIDx0ZXJtPmNvbnRleHQgbm9kZSBsaXN0PC90ZXJtPi4KLSAgICogQHhzbC51c2FnZSBpbnRlcm5hbAotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgcHVzaENvbnRleHROb2RlTGlzdChEVE1JdGVyYXRvciBubCkKLSAgewotICAgIG1fY29udGV4dE5vZGVMaXN0cy5wdXNoKG5sKTsKLSAgfQotCi0gIC8qKgotICAgKiBQb3AgdGhlIGN1cnJlbnQgY29udGV4dCBub2RlIGxpc3QuCi0gICAqIEB4c2wudXNhZ2UgaW50ZXJuYWwKLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHBvcENvbnRleHROb2RlTGlzdCgpCi0gIHsKLSAgICAgICAgaWYobV9jb250ZXh0Tm9kZUxpc3RzLmlzRW1wdHkoKSkKLSAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIldhcm5pbmc6IHBvcENvbnRleHROb2RlTGlzdCB3aGVuIHN0YWNrIGlzIGVtcHR5ISIpOwotICAgICAgICBlbHNlCi0gICAgICBtX2NvbnRleHROb2RlTGlzdHMucG9wKCk7Ci0gIH0KLQotICAvKioKLSAgICogVGhlIGFtb3VudCB0byB1c2UgZm9yIHN0YWNrcyB0aGF0IHJlY29yZCBpbmZvcm1hdGlvbiBkdXJpbmcgdGhlCi0gICAqIHJlY3Vyc2l2ZSBleGVjdXRpb24uCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRUNVUlNJT05MSU1JVCA9ICgxMDI0KjQpOwotCi0gIC8qKiBUaGUgc3RhY2sgb2YgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNkdC1jdXJyZW50LW5vZGUiPmN1cnJlbnQgbm9kZTwvYT4gb2JqZWN0cy4KLSAgICogIE5vdCB0byBiZSBjb25mdXNlZCB3aXRoIHRoZSBjdXJyZW50IG5vZGUgbGlzdC4gICVSRVZJRVclIE5vdGUgdGhhdCB0aGVyZQotICAgKiAgYXJlIG5vIGJvdW5kcyBjaGVjayBhbmQgcmVzaXplIGZvciB0aGlzIHN0YWNrLCBzbyBpZiBpdCBpcyBibG93biwgaXQncyBhbGwKLSAgICogIG92ZXIuICAqLwotICBwcml2YXRlIEludFN0YWNrIG1fY3VycmVudE5vZGVzID0gbmV3IEludFN0YWNrKFJFQ1VSU0lPTkxJTUlUKTsKLQotLy8gIHByaXZhdGUgTm9kZVZlY3RvciBtX2N1cnJlbnROb2RlcyA9IG5ldyBOb2RlVmVjdG9yKCk7Ci0KLSAgcHVibGljIEludFN0YWNrIGdldEN1cnJlbnROb2RlU3RhY2soKSB7cmV0dXJuIG1fY3VycmVudE5vZGVzOyB9Ci0gIHB1YmxpYyB2b2lkIHNldEN1cnJlbnROb2RlU3RhY2soSW50U3RhY2sgbnYpIHsgbV9jdXJyZW50Tm9kZXMgPSBudjsgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGN1cnJlbnQgY29udGV4dCBub2RlLgotICAgKgotICAgKiBAcmV0dXJuIHRoZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2R0LWN1cnJlbnQtbm9kZSI+Y3VycmVudCBub2RlPC9hPi4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBpbnQgZ2V0Q3VycmVudE5vZGUoKQotICB7Ci0gICAgcmV0dXJuIG1fY3VycmVudE5vZGVzLnBlZWsoKTsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIGN1cnJlbnQgY29udGV4dCBub2RlIGFuZCBleHByZXNzaW9uIG5vZGUuCi0gICAqCi0gICAqIEBwYXJhbSBjbiB0aGUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNkdC1jdXJyZW50LW5vZGUiPmN1cnJlbnQgbm9kZTwvYT4uCi0gICAqIEBwYXJhbSBlbiB0aGUgc3ViLWV4cHJlc3Npb24gY29udGV4dCBub2RlLgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgcHVzaEN1cnJlbnROb2RlQW5kRXhwcmVzc2lvbihpbnQgY24sIGludCBlbikKLSAgewotICAgIG1fY3VycmVudE5vZGVzLnB1c2goY24pOwotICAgIG1fY3VycmVudEV4cHJlc3Npb25Ob2Rlcy5wdXNoKGNuKTsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIGN1cnJlbnQgY29udGV4dCBub2RlLgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgcG9wQ3VycmVudE5vZGVBbmRFeHByZXNzaW9uKCkKLSAgewotICAgIG1fY3VycmVudE5vZGVzLnF1aWNrUG9wKDEpOwotICAgIG1fY3VycmVudEV4cHJlc3Npb25Ob2Rlcy5xdWlja1BvcCgxKTsKLSAgfQotCi0gIC8qKgotICAgKiBQdXNoIHRoZSBjdXJyZW50IGNvbnRleHQgbm9kZSwgZXhwcmVzc2lvbiBub2RlLCBhbmQgcHJlZml4IHJlc29sdmVyLgotICAgKgotICAgKiBAcGFyYW0gY24gdGhlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjZHQtY3VycmVudC1ub2RlIj5jdXJyZW50IG5vZGU8L2E+LgotICAgKiBAcGFyYW0gZW4gdGhlIHN1Yi1leHByZXNzaW9uIGNvbnRleHQgbm9kZS4KLSAgICogQHBhcmFtIG5jIHRoZSBuYW1lc3BhY2UgY29udGV4dCAocHJlZml4IHJlc29sdmVyLgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgcHVzaEV4cHJlc3Npb25TdGF0ZShpbnQgY24sIGludCBlbiwgUHJlZml4UmVzb2x2ZXIgbmMpCi0gIHsKLSAgICBtX2N1cnJlbnROb2Rlcy5wdXNoKGNuKTsKLSAgICBtX2N1cnJlbnRFeHByZXNzaW9uTm9kZXMucHVzaChjbik7Ci0gICAgbV9wcmVmaXhSZXNvbHZlcnMucHVzaChuYyk7Ci0gIH0KLQotICAvKioKLSAgICogUG9wIHRoZSBjdXJyZW50IGNvbnRleHQgbm9kZSwgZXhwcmVzc2lvbiBub2RlLCBhbmQgcHJlZml4IHJlc29sdmVyLgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgcG9wRXhwcmVzc2lvblN0YXRlKCkKLSAgewotICAgIG1fY3VycmVudE5vZGVzLnF1aWNrUG9wKDEpOwotICAgIG1fY3VycmVudEV4cHJlc3Npb25Ob2Rlcy5xdWlja1BvcCgxKTsKLSAgICBtX3ByZWZpeFJlc29sdmVycy5wb3AoKTsKLSAgfQotCi0KLQotICAvKioKLSAgICogU2V0IHRoZSBjdXJyZW50IGNvbnRleHQgbm9kZS4KLSAgICoKLSAgICogQHBhcmFtIG4gdGhlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjZHQtY3VycmVudC1ub2RlIj5jdXJyZW50IG5vZGU8L2E+LgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgcHVzaEN1cnJlbnROb2RlKGludCBuKQotICB7Ci0gICAgbV9jdXJyZW50Tm9kZXMucHVzaChuKTsKLSAgfQotCi0gIC8qKgotICAgKiBQb3AgdGhlIGN1cnJlbnQgY29udGV4dCBub2RlLgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgcG9wQ3VycmVudE5vZGUoKQotICB7Ci0gICAgbV9jdXJyZW50Tm9kZXMucXVpY2tQb3AoMSk7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBjdXJyZW50IHByZWRpY2F0ZSByb290LgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgcHVzaFByZWRpY2F0ZVJvb3QoaW50IG4pCi0gIHsKLSAgICBtX3ByZWRpY2F0ZVJvb3RzLnB1c2gobik7Ci0gIH0KLQotICAvKioKLSAgICogUG9wIHRoZSBjdXJyZW50IHByZWRpY2F0ZSByb290LgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgcG9wUHJlZGljYXRlUm9vdCgpCi0gIHsKLSAgICBtX3ByZWRpY2F0ZVJvb3RzLnBvcFF1aWNrKCk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBjdXJyZW50IHByZWRpY2F0ZSByb290LgotICAgKi8KLSAgcHVibGljIGZpbmFsIGludCBnZXRQcmVkaWNhdGVSb290KCkKLSAgewotICAgIHJldHVybiBtX3ByZWRpY2F0ZVJvb3RzLnBlZXBPck51bGwoKTsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIGN1cnJlbnQgbG9jYXRpb24gcGF0aCBpdGVyYXRvciByb290LgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgcHVzaEl0ZXJhdG9yUm9vdChpbnQgbikKLSAgewotICAgIG1faXRlcmF0b3JSb290cy5wdXNoKG4pOwotICB9Ci0KLSAgLyoqCi0gICAqIFBvcCB0aGUgY3VycmVudCBsb2NhdGlvbiBwYXRoIGl0ZXJhdG9yIHJvb3QuCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBwb3BJdGVyYXRvclJvb3QoKQotICB7Ci0gICAgbV9pdGVyYXRvclJvb3RzLnBvcFF1aWNrKCk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBjdXJyZW50IGxvY2F0aW9uIHBhdGggaXRlcmF0b3Igcm9vdC4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBpbnQgZ2V0SXRlcmF0b3JSb290KCkKLSAgewotICAgIHJldHVybiBtX2l0ZXJhdG9yUm9vdHMucGVlcE9yTnVsbCgpOwotICB9Ci0KLSAgLyoqIEEgc3RhY2sgb2YgdGhlIGN1cnJlbnQgc3ViLWV4cHJlc3Npb24gbm9kZXMuICAqLwotICBwcml2YXRlIE5vZGVWZWN0b3IgbV9pdGVyYXRvclJvb3RzID0gbmV3IE5vZGVWZWN0b3IoKTsKLQotICAvKiogQSBzdGFjayBvZiB0aGUgY3VycmVudCBzdWItZXhwcmVzc2lvbiBub2Rlcy4gICovCi0gIHByaXZhdGUgTm9kZVZlY3RvciBtX3ByZWRpY2F0ZVJvb3RzID0gbmV3IE5vZGVWZWN0b3IoKTsKLQotICAvKiogQSBzdGFjayBvZiB0aGUgY3VycmVudCBzdWItZXhwcmVzc2lvbiBub2Rlcy4gICovCi0gIHByaXZhdGUgSW50U3RhY2sgbV9jdXJyZW50RXhwcmVzc2lvbk5vZGVzID0gbmV3IEludFN0YWNrKFJFQ1VSU0lPTkxJTUlUKTsKLQotCi0gIHB1YmxpYyBJbnRTdGFjayBnZXRDdXJyZW50RXhwcmVzc2lvbk5vZGVTdGFjaygpIHsgcmV0dXJuIG1fY3VycmVudEV4cHJlc3Npb25Ob2RlczsgfQotICBwdWJsaWMgdm9pZCBzZXRDdXJyZW50RXhwcmVzc2lvbk5vZGVTdGFjayhJbnRTdGFjayBudikgeyBtX2N1cnJlbnRFeHByZXNzaW9uTm9kZXMgPSBudjsgfQotCi0gIHByaXZhdGUgSW50U3RhY2sgbV9wcmVkaWNhdGVQb3MgPSBuZXcgSW50U3RhY2soKTsKLQotICBwdWJsaWMgZmluYWwgaW50IGdldFByZWRpY2F0ZVBvcygpCi0gIHsKLSAgICByZXR1cm4gbV9wcmVkaWNhdGVQb3MucGVlaygpOwotICB9Ci0KLSAgcHVibGljIGZpbmFsIHZvaWQgcHVzaFByZWRpY2F0ZVBvcyhpbnQgbikKLSAgewotICAgIG1fcHJlZGljYXRlUG9zLnB1c2gobik7Ci0gIH0KLQotICBwdWJsaWMgZmluYWwgdm9pZCBwb3BQcmVkaWNhdGVQb3MoKQotICB7Ci0gICAgbV9wcmVkaWNhdGVQb3MucG9wKCk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBjdXJyZW50IG5vZGUgdGhhdCBpcyB0aGUgZXhwcmVzc2lvbidzIGNvbnRleHQgKGkuZS4gZm9yIGN1cnJlbnQoKSBzdXBwb3J0KS4KLSAgICoKLSAgICogQHJldHVybiBUaGUgY3VycmVudCBzdWItZXhwcmVzc2lvbiBub2RlLgotICAgKi8KLSAgcHVibGljIGZpbmFsIGludCBnZXRDdXJyZW50RXhwcmVzc2lvbk5vZGUoKQotICB7Ci0gICAgcmV0dXJuIG1fY3VycmVudEV4cHJlc3Npb25Ob2Rlcy5wZWVrKCk7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBjdXJyZW50IG5vZGUgdGhhdCBpcyB0aGUgZXhwcmVzc2lvbidzIGNvbnRleHQgKGkuZS4gZm9yIGN1cnJlbnQoKSBzdXBwb3J0KS4KLSAgICoKLSAgICogQHBhcmFtIG4gVGhlIHN1Yi1leHByZXNzaW9uIG5vZGUgdG8gYmUgY3VycmVudC4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHB1c2hDdXJyZW50RXhwcmVzc2lvbk5vZGUoaW50IG4pCi0gIHsKLSAgICBtX2N1cnJlbnRFeHByZXNzaW9uTm9kZXMucHVzaChuKTsKLSAgfQotCi0gIC8qKgotICAgKiBQb3AgdGhlIGN1cnJlbnQgbm9kZSB0aGF0IGlzIHRoZSBleHByZXNzaW9uJ3MgY29udGV4dAotICAgKiAoaS5lLiBmb3IgY3VycmVudCgpIHN1cHBvcnQpLgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgcG9wQ3VycmVudEV4cHJlc3Npb25Ob2RlKCkKLSAgewotICAgIG1fY3VycmVudEV4cHJlc3Npb25Ob2Rlcy5xdWlja1BvcCgxKTsKLSAgfQotCi0gIHByaXZhdGUgT2JqZWN0U3RhY2sgbV9wcmVmaXhSZXNvbHZlcnMKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSBuZXcgT2JqZWN0U3RhY2soUkVDVVJTSU9OTElNSVQpOwotCi0gIC8qKgotICAgKiBHZXQgdGhlIGN1cnJlbnQgbmFtZXNwYWNlIGNvbnRleHQgZm9yIHRoZSB4cGF0aC4KLSAgICoKLSAgICogQHJldHVybiB0aGUgY3VycmVudCBwcmVmaXggcmVzb2x2ZXIgZm9yIHJlc29sdmluZyBwcmVmaXhlcyB0bwotICAgKiAgICAgICAgIG5hbWVzcGFjZSBVUkxzLgotICAgKi8KLSAgcHVibGljIGZpbmFsIFByZWZpeFJlc29sdmVyIGdldE5hbWVzcGFjZUNvbnRleHQoKQotICB7Ci0gICAgcmV0dXJuIChQcmVmaXhSZXNvbHZlcikgbV9wcmVmaXhSZXNvbHZlcnMucGVlaygpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgY3VycmVudCBuYW1lc3BhY2UgY29udGV4dCBmb3IgdGhlIHhwYXRoLgotICAgKgotICAgKiBAcGFyYW0gcHIgdGhlIHByZWZpeCByZXNvbHZlciB0byBiZSB1c2VkIGZvciByZXNvbHZpbmcgcHJlZml4ZXMgdG8KLSAgICogICAgICAgICBuYW1lc3BhY2UgVVJMcy4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHNldE5hbWVzcGFjZUNvbnRleHQoUHJlZml4UmVzb2x2ZXIgcHIpCi0gIHsKLSAgICBtX3ByZWZpeFJlc29sdmVycy5zZXRUb3AocHIpOwotICB9Ci0KLSAgLyoqCi0gICAqIFB1c2ggYSBjdXJyZW50IG5hbWVzcGFjZSBjb250ZXh0IGZvciB0aGUgeHBhdGguCi0gICAqCi0gICAqIEBwYXJhbSBwciB0aGUgcHJlZml4IHJlc29sdmVyIHRvIGJlIHVzZWQgZm9yIHJlc29sdmluZyBwcmVmaXhlcyB0bwotICAgKiAgICAgICAgIG5hbWVzcGFjZSBVUkxzLgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgcHVzaE5hbWVzcGFjZUNvbnRleHQoUHJlZml4UmVzb2x2ZXIgcHIpCi0gIHsKLSAgICBtX3ByZWZpeFJlc29sdmVycy5wdXNoKHByKTsKLSAgfQotCi0gIC8qKgotICAgKiBKdXN0IGluY3JlbWVudCB0aGUgbmFtZXNwYWNlIGNvbnRlc3Qgc3RhY2ssIHNvIHRoYXQgc2V0TmFtZXNwYWNlQ29udGV4dAotICAgKiBjYW4gYmUgdXNlZCBvbiB0aGUgc2xvdC4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHB1c2hOYW1lc3BhY2VDb250ZXh0TnVsbCgpCi0gIHsKLSAgICBtX3ByZWZpeFJlc29sdmVycy5wdXNoKG51bGwpOwotICB9Ci0KLSAgLyoqCi0gICAqIFBvcCB0aGUgY3VycmVudCBuYW1lc3BhY2UgY29udGV4dCBmb3IgdGhlIHhwYXRoLgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgcG9wTmFtZXNwYWNlQ29udGV4dCgpCi0gIHsKLSAgICBtX3ByZWZpeFJlc29sdmVycy5wb3AoKTsKLSAgfQotCi0gIC8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICAvLyBTRUNUSU9OOiBDdXJyZW50IFRyZWVXYWxrZXIgY29udGV4dHMgKGZvciBpbnRlcm5hbCB1c2UpCi0gIC8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotCi0gIC8qKgotICAgKiBTdGFjayBvZiBBeGVzSXRlcmF0b3JzLgotICAgKi8KLSAgcHJpdmF0ZSBTdGFjayBtX2F4ZXNJdGVyYXRvclN0YWNrID0gbmV3IFN0YWNrKCk7Ci0KLSAgcHVibGljIFN0YWNrIGdldEF4ZXNJdGVyYXRvclN0YWNrU3RhY2tzKCkgeyByZXR1cm4gbV9heGVzSXRlcmF0b3JTdGFjazsgfQotICBwdWJsaWMgdm9pZCBzZXRBeGVzSXRlcmF0b3JTdGFja1N0YWNrcyhTdGFjayBzKSB7IG1fYXhlc0l0ZXJhdG9yU3RhY2sgPSBzOyB9Ci0KLSAgLyoqCi0gICAqIFB1c2ggYSBUcmVlV2Fsa2VyIG9uIHRoZSBzdGFjay4KLSAgICoKLSAgICogQHBhcmFtIGl0ZXIgQSBzdWItY29udGV4dCBBeGVzV2Fsa2VyLgotICAgKiBAeHNsLnVzYWdlIGludGVybmFsCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBwdXNoU3ViQ29udGV4dExpc3QoU3ViQ29udGV4dExpc3QgaXRlcikKLSAgewotICAgIG1fYXhlc0l0ZXJhdG9yU3RhY2sucHVzaChpdGVyKTsKLSAgfQotCi0gIC8qKgotICAgKiBQb3AgdGhlIGxhc3QgcHVzaGVkIGF4ZXMgaXRlcmF0b3IuCi0gICAqIEB4c2wudXNhZ2UgaW50ZXJuYWwKLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHBvcFN1YkNvbnRleHRMaXN0KCkKLSAgewotICAgIG1fYXhlc0l0ZXJhdG9yU3RhY2sucG9wKCk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBjdXJyZW50IGF4ZXMgaXRlcmF0b3IsIG9yIHJldHVybiBudWxsIGlmIG5vbmUuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIHN1Yi1jb250ZXh0IG5vZGUgbGlzdC4KLSAgICogQHhzbC51c2FnZSBpbnRlcm5hbAotICAgKi8KLSAgcHVibGljIFN1YkNvbnRleHRMaXN0IGdldFN1YkNvbnRleHRMaXN0KCkKLSAgewotICAgIHJldHVybiBtX2F4ZXNJdGVyYXRvclN0YWNrLmlzRW1wdHkoKQotICAgICAgICAgICA/IG51bGwgOiAoU3ViQ29udGV4dExpc3QpIG1fYXhlc0l0ZXJhdG9yU3RhY2sucGVlaygpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNkdC1jdXJyZW50LW5vZGUtbGlzdCI+Y3VycmVudCBub2RlIGxpc3Q8L2E+Ci0gICAqIGFzIGRlZmluZWQgYnkgdGhlIFhTTFQgc3BlYy4KLSAgICoKLSAgICogQHJldHVybiB0aGUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNkdC1jdXJyZW50LW5vZGUtbGlzdCI+Y3VycmVudCBub2RlIGxpc3Q8L2E+LgotICAgKiBAeHNsLnVzYWdlIGludGVybmFsCi0gICAqLwotCi0gIHB1YmxpYyBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuYXhlcy5TdWJDb250ZXh0TGlzdCBnZXRDdXJyZW50Tm9kZUxpc3QoKQotICB7Ci0gICAgcmV0dXJuIG1fYXhlc0l0ZXJhdG9yU3RhY2suaXNFbXB0eSgpCi0gICAgICAgICAgID8gbnVsbCA6IChTdWJDb250ZXh0TGlzdCkgbV9heGVzSXRlcmF0b3JTdGFjay5lbGVtZW50QXQoMCk7Ci0gIH0KLSAgLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gIC8vIFNFQ1RJT046IEltcGxlbWVudGF0aW9uIG9mIEV4cHJlc3Npb25Db250ZXh0IGludGVyZmFjZQotICAvLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLQotICAvKioKLSAgICogR2V0IHRoZSBjdXJyZW50IGNvbnRleHQgbm9kZS4KLSAgICogQHJldHVybiBUaGUgY3VycmVudCBjb250ZXh0IG5vZGUuCi0gICAqLwotICBwdWJsaWMgZmluYWwgaW50IGdldENvbnRleHROb2RlKCkKLSAgewotICAgIHJldHVybiB0aGlzLmdldEN1cnJlbnROb2RlKCk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBjdXJyZW50IGNvbnRleHQgbm9kZSBsaXN0LgotICAgKiBAcmV0dXJuIEFuIGl0ZXJhdG9yIGZvciB0aGUgY3VycmVudCBjb250ZXh0IGxpc3QsIGFzCi0gICAqIGRlZmluZWQgaW4gWFNMVC4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBEVE1JdGVyYXRvciBnZXRDb250ZXh0Tm9kZXMoKQotICB7Ci0KLSAgICB0cnkKLSAgICB7Ci0gICAgICBEVE1JdGVyYXRvciBjbmwgPSBnZXRDb250ZXh0Tm9kZUxpc3QoKTsKLQotICAgICAgaWYgKG51bGwgIT0gY25sKQotICAgICAgICByZXR1cm4gY25sLmNsb25lV2l0aFJlc2V0KCk7Ci0gICAgICBlbHNlCi0gICAgICAgIHJldHVybiBudWxsOyAgLy8gZm9yIG5vdy4uLiB0aGlzIG1pZ2h0IG91Z2h0IHRvIGJlIGFuIGVtcHR5IGl0ZXJhdG9yLgotICAgIH0KLSAgICBjYXRjaCAoQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gY25zZSkKLSAgICB7Ci0gICAgICByZXR1cm4gbnVsbDsgIC8vIGVycm9yIHJlcG9ydGluZz8KLSAgICB9Ci0gIH0KLQotICBYUGF0aEV4cHJlc3Npb25Db250ZXh0IGV4cHJlc3Npb25Db250ZXh0ID0gbmV3IFhQYXRoRXhwcmVzc2lvbkNvbnRleHQoKTsKLQotICAvKioKLSAgICogVGhlIHRoZSBleHByZXNzaW9uIGNvbnRleHQgZm9yIGV4dGVuc2lvbnMgZm9yIHRoaXMgY29udGV4dC4KLSAgICoKLSAgICogQHJldHVybiBBbiBvYmplY3QgdGhhdCBpbXBsZW1lbnRzIHRoZSBFeHByZXNzaW9uQ29udGV4dC4KLSAgICovCi0gIHB1YmxpYyBFeHByZXNzaW9uQ29udGV4dCBnZXRFeHByZXNzaW9uQ29udGV4dCgpCi0gIHsKLSAgICByZXR1cm4gZXhwcmVzc2lvbkNvbnRleHQ7Ci0gIH0KLQotICBwdWJsaWMgY2xhc3MgWFBhdGhFeHByZXNzaW9uQ29udGV4dCBpbXBsZW1lbnRzIEV4cHJlc3Npb25Db250ZXh0Ci0gIHsKLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIFhQYXRoQ29udGV4dCBhc3NvY2lhdGVkIHdpdGggdGhpcyBYUGF0aEV4cHJlc3Npb25Db250ZXh0LgotICAgICAqIEV4dGVuc2lvbnMgc2hvdWxkIHVzZSB0aGlzIGp1ZGljaW91c2x5IGFuZCBvbmx5IHdoZW4gc3BlY2lhbCBwcm9jZXNzaW5nCi0gICAgICogcmVxdWlyZW1lbnRzIGNhbm5vdCBiZSBtZXQgYW5vdGhlciB3YXkuICBDb25zaWRlciByZXF1ZXN0aW5nIGFuIGVuaGFuY2VtZW50Ci0gICAgICogdG8gdGhlIEV4cHJlc3Npb25Db250ZXh0IGludGVyZmFjZSB0byBhdm9pZCBoYXZpbmcgdG8gY2FsbCB0aGlzIG1ldGhvZC4KLSAgICAgKiBAcmV0dXJuIHRoZSBYUGF0aENvbnRleHQgYXNzb2NpYXRlZCB3aXRoIHRoaXMgWFBhdGhFeHByZXNzaW9uQ29udGV4dC4KLSAgICAgKi8KLSAgICAgcHVibGljIFhQYXRoQ29udGV4dCBnZXRYUGF0aENvbnRleHQoKQotICAgICB7Ci0gICAgICAgcmV0dXJuIFhQYXRoQ29udGV4dC50aGlzOwotICAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIERUTU1hbmFnZXIgb2JqZWN0LiAgVGhvdWdoIFhQYXRoQ29udGV4dCBjb250ZXh0IGV4dGVuZHMKLSAgICAgKiB0aGUgRFRNTWFuYWdlciwgaXQgcmVhbGx5IGlzIGEgcHJveHkgZm9yIHRoZSByZWFsIERUTU1hbmFnZXIuICBJZiBhCi0gICAgICogY2FsbGVyIG5lZWRzIHRvIG1ha2UgYSBsb3Qgb2YgY2FsbHMgdG8gdGhlIERUTU1hbmFnZXIsIGl0IGlzIGZhc3RlcgotICAgICAqIGlmIGl0IGdldHMgdGhlIHJlYWwgb25lIGZyb20gdGhpcyBmdW5jdGlvbi4KLSAgICAgKi8KLSAgICAgcHVibGljIERUTU1hbmFnZXIgZ2V0RFRNTWFuYWdlcigpCi0gICAgIHsKLSAgICAgICByZXR1cm4gbV9kdG1NYW5hZ2VyOwotICAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIGN1cnJlbnQgY29udGV4dCBub2RlLgotICAgICAqIEByZXR1cm4gVGhlIGN1cnJlbnQgY29udGV4dCBub2RlLgotICAgICAqLwotICAgIHB1YmxpYyBvcmcudzNjLmRvbS5Ob2RlIGdldENvbnRleHROb2RlKCkKLSAgICB7Ci0gICAgICBpbnQgY29udGV4dCA9IGdldEN1cnJlbnROb2RlKCk7Ci0KLSAgICAgIHJldHVybiBnZXREVE0oY29udGV4dCkuZ2V0Tm9kZShjb250ZXh0KTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIGN1cnJlbnQgY29udGV4dCBub2RlIGxpc3QuCi0gICAgICogQHJldHVybiBBbiBpdGVyYXRvciBmb3IgdGhlIGN1cnJlbnQgY29udGV4dCBsaXN0LCBhcwotICAgICAqIGRlZmluZWQgaW4gWFNMVC4KLSAgICAgKi8KLSAgICBwdWJsaWMgb3JnLnczYy5kb20udHJhdmVyc2FsLk5vZGVJdGVyYXRvciBnZXRDb250ZXh0Tm9kZXMoKQotICAgIHsKLSAgICAgIHJldHVybiBuZXcgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0ucmVmLkRUTU5vZGVJdGVyYXRvcihnZXRDb250ZXh0Tm9kZUxpc3QoKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBlcnJvciBsaXN0ZW5lci4KLSAgICAgKiBAcmV0dXJuIFRoZSByZWdpc3RlcmVkIGVycm9yIGxpc3RlbmVyLgotICAgICAqLwotICAgIHB1YmxpYyBFcnJvckxpc3RlbmVyIGdldEVycm9yTGlzdGVuZXIoKQotICAgIHsKLSAgICAgIHJldHVybiBYUGF0aENvbnRleHQudGhpcy5nZXRFcnJvckxpc3RlbmVyKCk7Ci0gICAgfQotICAgIC8qKgotICAgICAqIFJldHVybiB0aGUgc3RhdGUgb2YgdGhlIHNlcnZpY2VzIG1lY2hhbmlzbSBmZWF0dXJlLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIHVzZVNlcnZpY2VzTWVjaG5pc20oKSB7Ci0gICAgICAgIHJldHVybiBtX3VzZVNlcnZpY2VzTWVjaGFuaXNtOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldCB0aGUgc3RhdGUgb2YgdGhlIHNlcnZpY2VzIG1lY2hhbmlzbSBmZWF0dXJlLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFNlcnZpY2VzTWVjaG5pc20oYm9vbGVhbiBmbGFnKSB7Ci0gICAgICAgIG1fdXNlU2VydmljZXNNZWNoYW5pc20gPSBmbGFnOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgdmFsdWUgb2YgYSBub2RlIGFzIGEgbnVtYmVyLgotICAgICAqIEBwYXJhbSBuIE5vZGUgdG8gYmUgY29udmVydGVkIHRvIGEgbnVtYmVyLiAgTWF5IGJlIG51bGwuCi0gICAgICogQHJldHVybiB2YWx1ZSBvZiBuIGFzIGEgbnVtYmVyLgotICAgICAqLwotICAgIHB1YmxpYyBkb3VibGUgdG9OdW1iZXIob3JnLnczYy5kb20uTm9kZSBuKQotICAgIHsKLSAgICAgIC8vICVSRVZJRVclIFlvdSBjYW4ndCBnZXQgbXVjaCB1Z2xpZXIgdGhhbiB0aGlzLi4uCi0gICAgICBpbnQgbm9kZUhhbmRsZSA9IGdldERUTUhhbmRsZUZyb21Ob2RlKG4pOwotICAgICAgRFRNIGR0bSA9IGdldERUTShub2RlSGFuZGxlKTsKLSAgICAgIFhTdHJpbmcgeG9iaiA9IChYU3RyaW5nKWR0bS5nZXRTdHJpbmdWYWx1ZShub2RlSGFuZGxlKTsKLSAgICAgIHJldHVybiB4b2JqLm51bSgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgdmFsdWUgb2YgYSBub2RlIGFzIGEgc3RyaW5nLgotICAgICAqIEBwYXJhbSBuIE5vZGUgdG8gYmUgY29udmVydGVkIHRvIGEgc3RyaW5nLiAgTWF5IGJlIG51bGwuCi0gICAgICogQHJldHVybiB2YWx1ZSBvZiBuIGFzIGEgc3RyaW5nLCBvciBhbiBlbXB0eSBzdHJpbmcgaWYgbiBpcyBudWxsLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcob3JnLnczYy5kb20uTm9kZSBuKQotICAgIHsKLSAgICAgIC8vICVSRVZJRVclIFlvdSBjYW4ndCBnZXQgbXVjaCB1Z2xpZXIgdGhhbiB0aGlzLi4uCi0gICAgICBpbnQgbm9kZUhhbmRsZSA9IGdldERUTUhhbmRsZUZyb21Ob2RlKG4pOwotICAgICAgRFRNIGR0bSA9IGdldERUTShub2RlSGFuZGxlKTsKLSAgICAgIFhNTFN0cmluZyBzdHJWYWwgPSBkdG0uZ2V0U3RyaW5nVmFsdWUobm9kZUhhbmRsZSk7Ci0gICAgICByZXR1cm4gc3RyVmFsLnRvU3RyaW5nKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IGEgdmFyaWFibGUgYmFzZWQgb24gaXQncyBxdWFsaWZpZWQgbmFtZS4KLSAgICAgKiBAcGFyYW0gcW5hbWUgVGhlIHF1YWxpZmllZCBuYW1lIG9mIHRoZSB2YXJpYWJsZS4KLSAgICAgKiBAcmV0dXJuIFRoZSBldmFsdWF0ZWQgdmFsdWUgb2YgdGhlIHZhcmlhYmxlLgotICAgICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgICAqLwotCi0gICAgcHVibGljIGZpbmFsIFhPYmplY3QgZ2V0VmFyaWFibGVPclBhcmFtKGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuUU5hbWUgcW5hbWUpCi0gICAgICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAgewotICAgICAgcmV0dXJuIG1fdmFyaWFibGVTdGFja3MuZ2V0VmFyaWFibGVPclBhcmFtKFhQYXRoQ29udGV4dC50aGlzLCBxbmFtZSk7Ci0gICAgfQotCi0gIH0KLQotIC8qKgotICAgKiBHZXQgYSBEVE0gdG8gYmUgdXNlZCBhcyBhIGNvbnRhaW5lciBmb3IgYSBnbG9iYWwgUmVzdWx0IFRyZWUKLSAgICogRnJhZ21lbnQuIFRoaXMgd2lsbCBhbHdheXMgYmUgYW4gaW5zdGFuY2Ugb2YgKGRlcml2ZWQgZnJvbT8gZXF1aXZhbGVudCB0bz8pCi0gICAqIFNBWDJEVE0sIHNpbmNlIGVhY2ggUlRGIGlzIGNvbnN0cnVjdGVkIGJ5IHRlbXBvcmFyaWx5IHJlZGlyZWN0aW5nIG91ciBTQVgKLSAgICogb3V0cHV0IHRvIGl0LiBJdCBtYXkgYmUgYSBzaW5nbGUgRFRNIGNvbnRhaW5pbmcgZm9yIG11bHRpcGxlIGZyYWdtZW50cywKLSAgICogaWYgdGhlIGltcGxlbWVudGF0aW9uIHN1cHBvcnRzIHRoYXQuCi0gICAqCi0gICAqIE5vdGU6IFRoZSBkaXN0aW5jdGlvbiBiZXR3ZWVuIHRoaXMgbWV0aG9kIGFuZCBnZXRSVEZEVE0oKSBpcyB0aGF0IHRoZSBsYXR0ZXIKLSAgICogYWxsb2NhdGVzIHNwYWNlIGZyb20gdGhlIGR5bmFtaWMgdmFyaWFibGUgc3RhY2sgKG1fcnRmZHRtX3N0YWNrKSwgd2hpY2ggbWF5Ci0gICAqIGJlIHBydW5lZCBhd2F5IGFnYWluIGFzIHRoZSB0ZW1wbGF0ZXMgd2hpY2ggZGVmaW5lZCB0aG9zZSB2YXJpYWJsZXMgYXJlIGV4aXRlZC4KLSAgICogR2xvYmFsIHZhcmlhYmxlcyBtYXkgYmUgYm91bmQgbGF0ZSAoc2VlIFhVbnJlc29sdmVkVmFyaWFibGUpLCBhbmQgbmV2ZXIgd2FudCB0bwotICAgKiBiZSBkaXNjYXJkZWQsIGhlbmNlIHdlIG5lZWQgdG8gYWxsb2NhdGUgdGhlbSBzZXBhcmF0ZWx5IGFuZCBkb24ndCBhY3R1YWxseSBuZWVkCi0gICAqIGEgc3RhY2sgdG8gdHJhY2sgdGhlbS4KLSAgICoKLSAgICogQHJldHVybiBhIG5vbi1udWxsIERUTSByZWZlcmVuY2UuCi0gICAqLwotICBwdWJsaWMgRFRNIGdldEdsb2JhbFJURkRUTSgpCi0gIHsKLSAgICAgICAgLy8gV2UgcHJvYmFibHkgc2hvdWxkIF9OT1RfIGJlIGFwcGx5aW5nIHdoaXRlc3BhY2UgZmlsdGVyaW5nIGF0IHRoaXMgc3RhZ2UhCi0gICAgICAgIC8vCi0gICAgICAgIC8vIFNvbWUgbWFnaWMgaGFzIGJlZW4gYXBwbGllZCBpbiBEVE1NYW5hZ2VyRGVmYXVsdCB0byByZWNvZ25pemUgdGhpcyBzZXQgb2Ygb3B0aW9ucwotICAgICAgICAvLyBhbmQgZ2VuZXJhdGUgYW4gaW5zdGFuY2Ugb2YgRFRNIHdoaWNoIGNhbiBjb250YWluIG11bHRpcGxlIGRvY3VtZW50cwotICAgICAgICAvLyAoU0FYMlJURkRUTSkuIFBlcmhhcHMgbm90IHRoZSBvcHRpbWFsIHdheSBvZiBhY2hpZXZpbmcgdGhhdCByZXN1bHQsIGJ1dAotICAgICAgICAvLyBJIGRpZG4ndCB3YW50IHRvIGNoYW5nZSB0aGUgbWFuYWdlciBBUEkgYXQgdGhpcyB0aW1lLCBvciBleHBvc2UKLSAgICAgICAgLy8gdG9vIG1hbnkgZGVwZW5kZW5jaWVzIG9uIGl0cyBpbnRlcm5hbHMuIChJZGVhbGx5LCBJJ2QgbGlrZSB0byBtb3ZlCi0gICAgICAgIC8vIGlzVHJlZUluY29tcGxldGUgYWxsIHRoZSB3YXkgdXAgdG8gRFRNLCBzbyB3ZSB3b3VsZG4ndCBuZWVkIHRvIGV4cGxpY2l0bHkKLSAgICAgICAgLy8gc3BlY2lmeSB0aGUgc3ViY2xhc3MgaGVyZS4pCi0KLSAgICAgICAgLy8gSWYgaXQgZG9lc24ndCBleGlzdCwgb3IgaWYgdGhlIG9uZSBhbHJlYWR5IGV4aXN0aW5nIGlzIGluIHRoZSBtaWRkbGUgb2YKLSAgICAgICAgLy8gYmVpbmcgY29uc3RydWN0ZWQsIHdlIG5lZWQgdG8gb2J0YWluIGEgbmV3IERUTSB0byB3cml0ZSBpbnRvLiBJJ20gbm90IHN1cmUKLSAgICAgICAgLy8gdGhlIGxhdHRlciB3aWxsIGV2ZXIgYXJpc2UsIGJ1dCBJJ2QgcmF0aGVyIGJlIGp1c3QgYSBiaXQgcGFyYW5vaWQuLgotICAgICAgICBpZiggbV9nbG9iYWxfcnRmZHRtPT1udWxsIHx8IG1fZ2xvYmFsX3J0ZmR0bS5pc1RyZWVJbmNvbXBsZXRlKCkgKQotICAgICAgICB7Ci0gICAgICAgICAgICAgICAgbV9nbG9iYWxfcnRmZHRtPShTQVgyUlRGRFRNKW1fZHRtTWFuYWdlci5nZXREVE0obnVsbCx0cnVlLG51bGwsZmFsc2UsZmFsc2UpOwotICAgICAgICB9Ci0gICAgcmV0dXJuIG1fZ2xvYmFsX3J0ZmR0bTsKLSAgfQotCi0KLQotCi0gIC8qKgotICAgKiBHZXQgYSBEVE0gdG8gYmUgdXNlZCBhcyBhIGNvbnRhaW5lciBmb3IgYSBkeW5hbWljIFJlc3VsdCBUcmVlCi0gICAqIEZyYWdtZW50LiBUaGlzIHdpbGwgYWx3YXlzIGJlIGFuIGluc3RhbmNlIG9mIChkZXJpdmVkIGZyb20/IGVxdWl2YWxlbnQgdG8/KQotICAgKiBTQVgyRFRNLCBzaW5jZSBlYWNoIFJURiBpcyBjb25zdHJ1Y3RlZCBieSB0ZW1wb3JhcmlseSByZWRpcmVjdGluZyBvdXIgU0FYCi0gICAqIG91dHB1dCB0byBpdC4gSXQgbWF5IGJlIGEgc2luZ2xlIERUTSBjb250YWluaW5nIGZvciBtdWx0aXBsZSBmcmFnbWVudHMsCi0gICAqIGlmIHRoZSBpbXBsZW1lbnRhdGlvbiBzdXBwb3J0cyB0aGF0LgotICAgKgotICAgKiBAcmV0dXJuIGEgbm9uLW51bGwgRFRNIHJlZmVyZW5jZS4KLSAgICovCi0gIHB1YmxpYyBEVE0gZ2V0UlRGRFRNKCkKLSAgewotICAgICAgICBTQVgyUlRGRFRNIHJ0ZmR0bTsKLQotICAgICAgICAvLyBXZSBwcm9iYWJseSBzaG91bGQgX05PVF8gYmUgYXBwbHlpbmcgd2hpdGVzcGFjZSBmaWx0ZXJpbmcgYXQgdGhpcyBzdGFnZSEKLSAgICAgICAgLy8KLSAgICAgICAgLy8gU29tZSBtYWdpYyBoYXMgYmVlbiBhcHBsaWVkIGluIERUTU1hbmFnZXJEZWZhdWx0IHRvIHJlY29nbml6ZSB0aGlzIHNldCBvZiBvcHRpb25zCi0gICAgICAgIC8vIGFuZCBnZW5lcmF0ZSBhbiBpbnN0YW5jZSBvZiBEVE0gd2hpY2ggY2FuIGNvbnRhaW4gbXVsdGlwbGUgZG9jdW1lbnRzCi0gICAgICAgIC8vIChTQVgyUlRGRFRNKS4gUGVyaGFwcyBub3QgdGhlIG9wdGltYWwgd2F5IG9mIGFjaGlldmluZyB0aGF0IHJlc3VsdCwgYnV0Ci0gICAgICAgIC8vIEkgZGlkbid0IHdhbnQgdG8gY2hhbmdlIHRoZSBtYW5hZ2VyIEFQSSBhdCB0aGlzIHRpbWUsIG9yIGV4cG9zZQotICAgICAgICAvLyB0b28gbWFueSBkZXBlbmRlbmNpZXMgb24gaXRzIGludGVybmFscy4gKElkZWFsbHksIEknZCBsaWtlIHRvIG1vdmUKLSAgICAgICAgLy8gaXNUcmVlSW5jb21wbGV0ZSBhbGwgdGhlIHdheSB1cCB0byBEVE0sIHNvIHdlIHdvdWxkbid0IG5lZWQgdG8gZXhwbGljaXRseQotICAgICAgICAvLyBzcGVjaWZ5IHRoZSBzdWJjbGFzcyBoZXJlLikKLQotICAgICAgICBpZihtX3J0ZmR0bV9zdGFjaz09bnVsbCkKLSAgICAgICAgewotICAgICAgICAgICAgICAgIG1fcnRmZHRtX3N0YWNrPW5ldyBWZWN0b3IoKTsKLSAgICAgICAgICAgICAgICBydGZkdG09KFNBWDJSVEZEVE0pbV9kdG1NYW5hZ2VyLmdldERUTShudWxsLHRydWUsbnVsbCxmYWxzZSxmYWxzZSk7Ci0gICAgbV9ydGZkdG1fc3RhY2suYWRkRWxlbWVudChydGZkdG0pOwotICAgICAgICAgICAgICAgICsrbV93aGljaF9ydGZkdG07Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZihtX3doaWNoX3J0ZmR0bTwwKQotICAgICAgICB7Ci0gICAgICAgICAgICAgICAgcnRmZHRtPShTQVgyUlRGRFRNKW1fcnRmZHRtX3N0YWNrLmVsZW1lbnRBdCgrK21fd2hpY2hfcnRmZHRtKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgIHsKLSAgICAgICAgICAgICAgICBydGZkdG09KFNBWDJSVEZEVE0pbV9ydGZkdG1fc3RhY2suZWxlbWVudEF0KG1fd2hpY2hfcnRmZHRtKTsKLQotICAgICAgICAgICAgICAgIC8vIEl0IG1pZ2h0IGFscmVhZHkgYmUgdW5kZXIgY29uc3RydWN0aW9uIC0tIHRoZSBjbGFzc2ljIGV4YW1wbGUgd291bGQgYmUKLSAgICAgICAgICAgICAgICAvLyBhbiB4c2w6dmFyaWFibGUgd2hpY2ggdXNlcyB4c2w6Y2FsbC10ZW1wbGF0ZSBhcyBwYXJ0IG9mIGl0cyB2YWx1ZS4gVG8KLSAgICAgICAgICAgICAgICAvLyBoYW5kbGUgdGhpcyByZWN1cnNpb24sIHdlIGhhdmUgdG8gc3RhcnQgYSBuZXcgUlRGIERUTSwgcHVzaGluZyB0aGUgb2xkCi0gICAgICAgICAgICAgICAgLy8gb25lIG9udG8gYSBzdGFjayBzbyB3ZSBjYW4gcmV0dXJuIHRvIGl0LiBUaGlzIGlzIG5vdCBhcyB1bmNvbW1vbiBhIGNhc2UKLSAgICAgICAgICAgICAgICAvLyBhcyB3ZSBtaWdodCB3aXNoLCB1bmZvcnR1bmF0ZWx5LCBhcyBzb21lIGZvbGtzIGluc2lzdCBvbiBjb2RpbmcgWFNMVAotICAgICAgICAgICAgICAgIC8vIGFzIGlmIGl0IHdlcmUgYSBwcm9jZWR1cmFsIGxhbmd1YWdlLi4uCi0gICAgICAgICAgICAgICAgaWYocnRmZHRtLmlzVHJlZUluY29tcGxldGUoKSkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZigrK21fd2hpY2hfcnRmZHRtIDwgbV9ydGZkdG1fc3RhY2suc2l6ZSgpKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBydGZkdG09KFNBWDJSVEZEVE0pbV9ydGZkdG1fc3RhY2suZWxlbWVudEF0KG1fd2hpY2hfcnRmZHRtKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcnRmZHRtPShTQVgyUlRGRFRNKW1fZHRtTWFuYWdlci5nZXREVE0obnVsbCx0cnVlLG51bGwsZmFsc2UsZmFsc2UpOwotICAgICAgICAgIG1fcnRmZHRtX3N0YWNrLmFkZEVsZW1lbnQocnRmZHRtKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgIHJldHVybiBydGZkdG07Ci0gIH0KLQotICAvKiogUHVzaCB0aGUgUlRGRFRNJ3MgY29udGV4dCBtYXJrLCB0byBhbGxvd3MgZGlzY2FyZGluZyBSVEZzIGFkZGVkIGFmdGVyIHRoaXMKLSAgICogcG9pbnQuIChJZiBpdCBkb2Vzbid0IGV4aXN0IHdlIGRvbid0IHB1c2gsIHNpbmNlIHdlIG1pZ2h0IHN0aWxsIGJlIGFibGUgdG8KLSAgICogZ2V0IGF3YXkgd2l0aCBub3QgY3JlYXRpbmcgaXQuIFRoYXQgcmVxdWlyZXMgdGhhdCBleGNlc3NpdmUgcG9wcyBiZSBoYXJtbGVzcy4pCi0gICAqICovCi0gIHB1YmxpYyB2b2lkIHB1c2hSVEZDb250ZXh0KCkKLSAgewotICAgICAgICBtX2xhc3RfcHVzaGVkX3J0ZmR0bS5wdXNoKG1fd2hpY2hfcnRmZHRtKTsKLSAgICAgICAgaWYobnVsbCE9bV9ydGZkdG1fc3RhY2spCi0gICAgICAgICAgICAgICAgKChTQVgyUlRGRFRNKShnZXRSVEZEVE0oKSkpLnB1c2hSZXdpbmRNYXJrKCk7Ci0gIH0KLQotICAvKiogUG9wIHRoZSBSVEZEVE0ncyBjb250ZXh0IG1hcmsuIFRoaXMgZGlzY2FyZHMgYW55IFJURnMgYWRkZWQgYWZ0ZXIgdGhlIGxhc3QKLSAgICogbWFyayB3YXMgc2V0LgotICAgKgotICAgKiBJZiB0aGVyZSBpcyBubyBSVEYgRFRNLCB0aGVyZSdzIG5vdGhpbmcgdG8gcG9wIHNvIHRoaXMKLSAgICogYmVjb21lcyBhIG5vLW9wLiBJZiBwdXNoZXMgd2VyZSBpc3N1ZWQgYmVmb3JlIHRoaXMgd2FzIGNhbGxlZCwgd2UgY291bnQgb24KLSAgICogdGhlIGZhY3QgdGhhdCBwb3BSZXdpbmRNYXJrIGlzIGRlZmluZWQgc3VjaCB0aGF0IG92ZXJwb3BwaW5nIGp1c3QgcmVzZXRzCi0gICAqIHRvIGVtcHR5LgotICAgKgotICAgKiBDb21wbGljYXRpbmcgZmFjdG9yOiBXZSBuZWVkIHRvIGhhbmRsZSB0aGUgY2FzZSBvZiBwb3BwaW5nIGJhY2sgdG8gYSBwcmV2aW91cwotICAgKiBSVEYgRFRNLCBpZiBvbmUgb2YgdGhlIHdlaXJkIHByb2R1Y2UtYW4tUlRGLXRvLWJ1aWxkLWFuLVJURiBjYXNlcyBhcm9zZS4KLSAgICogQmFzaWNhbGx5OiBJZiBwb3Agc2F5cyB0aGlzIERUTSBpcyBub3cgZW1wdHksIHRoZW4gcmV0dXJuIHRvIHRoZSBwcmV2aW91cwotICAgKiBpZiBvbmUgZXhpc3RzLCBpbiB3aGF0ZXZlciBzdGF0ZSB3ZSBsZWZ0IGl0IGluLiBVR0xZLCBidXQgaG9wZWZ1bGx5IHRoZQotICAgKiBzaXR1YXRpb24gd2hpY2ggZm9yY2VzIHVzIHRvIGNvbnNpZGVyIHRoaXMgd2lsbCBhcmlzZSBleGNlZWRpbmdseSByYXJlbHkuCi0gICAqICovCi0gIHB1YmxpYyB2b2lkIHBvcFJURkNvbnRleHQoKQotICB7Ci0gICAgICAgIGludCBwcmV2aW91cz1tX2xhc3RfcHVzaGVkX3J0ZmR0bS5wb3AoKTsKLSAgICAgICAgaWYobnVsbD09bV9ydGZkdG1fc3RhY2spCi0gICAgICAgICAgICAgICAgcmV0dXJuOwotCi0gICAgICAgIGlmKG1fd2hpY2hfcnRmZHRtPT1wcmV2aW91cykKLSAgICAgICAgewotICAgICAgICAgICAgICAgIGlmKHByZXZpb3VzPj0wKSAvLyBndWFyZCBhZ2FpbnN0IG5vbmUtYWN0aXZlCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBpc0VtcHR5PSgoU0FYMlJURkRUTSkobV9ydGZkdG1fc3RhY2suZWxlbWVudEF0KHByZXZpb3VzKSkpLnBvcFJld2luZE1hcmsoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB3aGlsZShtX3doaWNoX3J0ZmR0bSE9cHJldmlvdXMpCi0gICAgICAgIHsKLSAgICAgICAgICAgICAgICAvLyBFbXB0eSBlYWNoIERUTSBiZWZvcmUgcG9wcGluZywgc28gaXQncyByZWFkeSBmb3IgcmV1c2UKLSAgICAgICAgICAgICAgICAvLyBfRE9OJ1RfIHBvcCB0aGUgcHJldmlvdXMsIHNpbmNlIGl0J3Mgc3RpbGwgb3BlbiAod2hpY2ggaXMgd2h5IHdlCi0gICAgICAgICAgICAgICAgLy8gc3RhY2tlZCB1cCBtb3JlIG9mIHRoZXNlKSBhbmQgZGlkIG5vdCByZWNlaXZlIGEgbWFyay4KLSAgICAgICAgICAgICAgICBib29sZWFuIGlzRW1wdHk9KChTQVgyUlRGRFRNKShtX3J0ZmR0bV9zdGFjay5lbGVtZW50QXQobV93aGljaF9ydGZkdG0pKSkucG9wUmV3aW5kTWFyaygpOwotICAgICAgICAgICAgICAgIC0tbV93aGljaF9ydGZkdG07Ci0gICAgICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBHZXRzIERUTVhSVHJlZUZyYWcgb2JqZWN0IGlmIG9uZSBoYXMgYWxyZWFkeSBiZWVuIGNyZWF0ZWQuCi0gICAqIENyZWF0ZXMgbmV3IERUTVhSVHJlZUZyYWcgb2JqZWN0IGFuZCBhZGRzIHRvIG1fRFRNWFJUcmVlRnJhZ3MgIEhhc2hNYXAsCi0gICAqIG90aGVyd2lzZS4KLSAgICogQHBhcmFtIGR0bUlkZW50aXR5Ci0gICAqIEByZXR1cm4gRFRNWFJUcmVlRnJhZwotICAgKi8KLSAgcHVibGljIERUTVhSVHJlZUZyYWcgZ2V0RFRNWFJUcmVlRnJhZyhpbnQgZHRtSWRlbnRpdHkpewotICAgIGlmKG1fRFRNWFJUcmVlRnJhZ3MgPT0gbnVsbCl7Ci0gICAgICBtX0RUTVhSVHJlZUZyYWdzID0gbmV3IEhhc2hNYXAoKTsKLSAgICB9Ci0KLSAgICBpZihtX0RUTVhSVHJlZUZyYWdzLmNvbnRhaW5zS2V5KG5ldyBJbnRlZ2VyKGR0bUlkZW50aXR5KSkpewotICAgICAgIHJldHVybiAoRFRNWFJUcmVlRnJhZyltX0RUTVhSVHJlZUZyYWdzLmdldChuZXcgSW50ZWdlcihkdG1JZGVudGl0eSkpOwotICAgIH1lbHNlewotICAgICAgZmluYWwgRFRNWFJUcmVlRnJhZyBmcmFnID0gbmV3IERUTVhSVHJlZUZyYWcoZHRtSWRlbnRpdHksdGhpcyk7Ci0gICAgICBtX0RUTVhSVHJlZUZyYWdzLnB1dChuZXcgSW50ZWdlcihkdG1JZGVudGl0eSksZnJhZyk7Ci0gICAgICByZXR1cm4gZnJhZyA7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIENsZWFucyBEVE1YUlRyZWVGcmFnIG9iamVjdHMgYnkgcmVtb3ZpbmcgcmVmZXJlbmNlcwotICAgKiB0byBEVE0gYW5kIFhQYXRoQ29udGV4dCBvYmplY3RzLgotICAgKi8KLSAgcHJpdmF0ZSBmaW5hbCB2b2lkIHJlbGVhc2VEVE1YUlRyZWVGcmFncygpewotICAgIGlmKG1fRFRNWFJUcmVlRnJhZ3MgPT0gbnVsbCl7Ci0gICAgICByZXR1cm47Ci0gICAgfQotICAgIGZpbmFsIEl0ZXJhdG9yIGl0ZXIgPSAobV9EVE1YUlRyZWVGcmFncy52YWx1ZXMoKSkuaXRlcmF0b3IoKTsKLSAgICB3aGlsZShpdGVyLmhhc05leHQoKSl7Ci0gICAgICBEVE1YUlRyZWVGcmFnIGZyYWcgPSAoRFRNWFJUcmVlRnJhZylpdGVyLm5leHQoKTsKLSAgICAgIGZyYWcuZGVzdHJ1Y3QoKTsKLSAgICAgIGl0ZXIucmVtb3ZlKCk7Ci0gICAgfQotICAgIG1fRFRNWFJUcmVlRnJhZ3MgPSBudWxsOwotIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvWFBhdGhFeGNlcHRpb24uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvWFBhdGhFeGNlcHRpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZWYxZjhiYi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL1hQYXRoRXhjZXB0aW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzMzAgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogWFBhdGhFeGNlcHRpb24uamF2YSx2IDEuMyAyMDA1LzA5LzI4IDEzOjQ5OjMwIHB2ZWR1bGEgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWw7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotCi1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGltcGxlbWVudHMgYW4gZXhjZXB0aW9uIG9iamVjdCB0aGF0IGFsbAotICogWFBhdGggY2xhc3NlcyB3aWxsIHRocm93IGluIGNhc2Ugb2YgYW4gZXJyb3IuICBUaGlzIGNsYXNzCi0gKiBleHRlbmRzIFRyYW5zZm9ybWVyRXhjZXB0aW9uLCBhbmQgbWF5IGhvbGQgb3RoZXIgZXhjZXB0aW9ucy4gSW4gdGhlCi0gKiBjYXNlIG9mIG5lc3RlZCBleGNlcHRpb25zLCBwcmludFN0YWNrVHJhY2Ugd2lsbCBkdW1wCi0gKiBhbGwgdGhlIHRyYWNlcyBvZiB0aGUgbmVzdGVkIGV4Y2VwdGlvbnMsIG5vdCBqdXN0IHRoZSB0cmFjZQotICogb2YgdGhpcyBvYmplY3QuCi0gKiBAeHNsLnVzYWdlIGdlbmVyYWwKLSAqLwotcHVibGljIGNsYXNzIFhQYXRoRXhjZXB0aW9uIGV4dGVuZHMgVHJhbnNmb3JtZXJFeGNlcHRpb24KLXsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNDI2MzU0OTcxNzYxOTA0NTk2M0w7Ci0KLSAgLyoqIFRoZSBob21lIG9mIHRoZSBleHByZXNzaW9uIHRoYXQgY2F1c2VkIHRoZSBlcnJvci4KLSAgICogIEBzZXJpYWwgICovCi0gIE9iamVjdCBtX3N0eWxlTm9kZSA9IG51bGw7Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgc3R5bGVzaGVldCBub2RlIGZyb20gd2hlcmUgdGhpcyBlcnJvciBvcmlnaW5hdGVkLgotICAgKiBAcmV0dXJuIFRoZSBzdHlsZXNoZWV0IG5vZGUgZnJvbSB3aGVyZSB0aGlzIGVycm9yIG9yaWdpbmF0ZWQsIG9yIG51bGwuCi0gICAqLwotICBwdWJsaWMgT2JqZWN0IGdldFN0eWxlc2hlZXROb2RlKCkKLSAgewotICAgIHJldHVybiBtX3N0eWxlTm9kZTsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIHN0eWxlc2hlZXQgbm9kZSBmcm9tIHdoZXJlIHRoaXMgZXJyb3Igb3JpZ2luYXRlZC4KLSAgICogQHBhcmFtIHN0eWxlTm9kZSBUaGUgc3R5bGVzaGVldCBub2RlIGZyb20gd2hlcmUgdGhpcyBlcnJvciBvcmlnaW5hdGVkLCBvciBudWxsLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0U3R5bGVzaGVldE5vZGUoT2JqZWN0IHN0eWxlTm9kZSkKLSAgewotICAgIG1fc3R5bGVOb2RlID0gc3R5bGVOb2RlOwotICB9Ci0KLQotICAvKiogQSBuZXN0ZWQgZXhjZXB0aW9uLgotICAgKiAgQHNlcmlhbCAgICovCi0gIHByb3RlY3RlZCBFeGNlcHRpb24gbV9leGNlcHRpb247Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhbiBYUGF0aEV4Y2VwdGlvbiBvYmplY3QgdGhhdCBob2xkcwotICAgKiBhbiBlcnJvciBtZXNzYWdlLgotICAgKiBAcGFyYW0gbWVzc2FnZSBUaGUgZXJyb3IgbWVzc2FnZS4KLSAgICovCi0gIHB1YmxpYyBYUGF0aEV4Y2VwdGlvbihTdHJpbmcgbWVzc2FnZSwgRXhwcmVzc2lvbk5vZGUgZXgpCi0gIHsKLSAgICBzdXBlcihtZXNzYWdlKTsKLSAgICB0aGlzLnNldExvY2F0b3IoZXgpOwotICAgIHNldFN0eWxlc2hlZXROb2RlKGdldFN0eWxlc2hlZXROb2RlKGV4KSk7Ci0gIH0KLQotICAvKioKLSAgICogQ3JlYXRlIGFuIFhQYXRoRXhjZXB0aW9uIG9iamVjdCB0aGF0IGhvbGRzCi0gICAqIGFuIGVycm9yIG1lc3NhZ2UuCi0gICAqIEBwYXJhbSBtZXNzYWdlIFRoZSBlcnJvciBtZXNzYWdlLgotICAgKi8KLSAgcHVibGljIFhQYXRoRXhjZXB0aW9uKFN0cmluZyBtZXNzYWdlKQotICB7Ci0gICAgc3VwZXIobWVzc2FnZSk7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBHZXQgdGhlIFhTTFQgRWxlbVZhcmlhYmxlIHRoYXQgdGhpcyBzdWItZXhwcmVzc2lvbiByZWZlcmVuY2VzLiAgSW4gb3JkZXIgZm9yCi0gICAqIHRoaXMgdG8gd29yaywgdGhlIFNvdXJjZUxvY2F0b3IgbXVzdCBiZSB0aGUgb3duaW5nIEVsZW1UZW1wbGF0ZUVsZW1lbnQuCi0gICAqIEByZXR1cm4gVGhlIGRlcmVmZXJlbmNlIHRvIHRoZSBFbGVtVmFyaWFibGUsIG9yIG51bGwgaWYgbm90IGZvdW5kLgotICAgKi8KLSAgcHVibGljIG9yZy53M2MuZG9tLk5vZGUgZ2V0U3R5bGVzaGVldE5vZGUoRXhwcmVzc2lvbk5vZGUgZXgpCi0gIHsKLQotICAgIEV4cHJlc3Npb25Ob2RlIG93bmVyID0gZ2V0RXhwcmVzc2lvbk93bmVyKGV4KTsKLQotICAgIGlmIChudWxsICE9IG93bmVyICYmIG93bmVyIGluc3RhbmNlb2Ygb3JnLnczYy5kb20uTm9kZSkKLSAgICB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuICgob3JnLnczYy5kb20uTm9kZSlvd25lcik7Ci0gICAgfQotICAgIHJldHVybiBudWxsOwotCi0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBmaXJzdCBub24tRXhwcmVzc2lvbiBwYXJlbnQgb2YgdGhpcyBub2RlLgotICAgKiBAcmV0dXJuIG51bGwgb3IgZmlyc3QgYW5jZXN0b3IgdGhhdCBpcyBub3QgYW4gRXhwcmVzc2lvbi4KLSAgICovCi0gIHByb3RlY3RlZCBFeHByZXNzaW9uTm9kZSBnZXRFeHByZXNzaW9uT3duZXIoRXhwcmVzc2lvbk5vZGUgZXgpCi0gIHsKLSAgICAgICAgRXhwcmVzc2lvbk5vZGUgcGFyZW50ID0gZXguZXhwckdldFBhcmVudCgpOwotICAgICAgICB3aGlsZSgobnVsbCAhPSBwYXJlbnQpICYmIChwYXJlbnQgaW5zdGFuY2VvZiBFeHByZXNzaW9uKSkKLSAgICAgICAgICAgICAgICBwYXJlbnQgPSBwYXJlbnQuZXhwckdldFBhcmVudCgpOwotICAgICAgICByZXR1cm4gcGFyZW50OwotICB9Ci0KLQotCi0gIC8qKgotICAgKiBDcmVhdGUgYW4gWFBhdGhFeGNlcHRpb24gb2JqZWN0IHRoYXQgaG9sZHMKLSAgICogYW4gZXJyb3IgbWVzc2FnZSBhbmQgdGhlIHN0eWxlc2hlZXQgbm9kZSB0aGF0Ci0gICAqIHRoZSBlcnJvciBvcmlnaW5hdGVkIGZyb20uCi0gICAqIEBwYXJhbSBtZXNzYWdlIFRoZSBlcnJvciBtZXNzYWdlLgotICAgKiBAcGFyYW0gc3R5bGVOb2RlIFRoZSBzdHlsZXNoZWV0IG5vZGUgdGhhdCB0aGUgZXJyb3Igb3JpZ2luYXRlZCBmcm9tLgotICAgKi8KLSAgcHVibGljIFhQYXRoRXhjZXB0aW9uKFN0cmluZyBtZXNzYWdlLCBPYmplY3Qgc3R5bGVOb2RlKQotICB7Ci0KLSAgICBzdXBlcihtZXNzYWdlKTsKLQotICAgIG1fc3R5bGVOb2RlID0gc3R5bGVOb2RlOwotICB9Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhbiBYUGF0aEV4Y2VwdGlvbiBvYmplY3QgdGhhdCBob2xkcwotICAgKiBhbiBlcnJvciBtZXNzYWdlLCB0aGUgc3R5bGVzaGVldCBub2RlIHRoYXQKLSAgICogdGhlIGVycm9yIG9yaWdpbmF0ZWQgZnJvbSwgYW5kIGFub3RoZXIgZXhjZXB0aW9uCi0gICAqIHRoYXQgY2F1c2VkIHRoaXMgZXhjZXB0aW9uLgotICAgKiBAcGFyYW0gbWVzc2FnZSBUaGUgZXJyb3IgbWVzc2FnZS4KLSAgICogQHBhcmFtIHN0eWxlTm9kZSBUaGUgc3R5bGVzaGVldCBub2RlIHRoYXQgdGhlIGVycm9yIG9yaWdpbmF0ZWQgZnJvbS4KLSAgICogQHBhcmFtIGUgVGhlIGV4Y2VwdGlvbiB0aGF0IGNhdXNlZCB0aGlzIGV4Y2VwdGlvbi4KLSAgICovCi0gIHB1YmxpYyBYUGF0aEV4Y2VwdGlvbihTdHJpbmcgbWVzc2FnZSwgTm9kZSBzdHlsZU5vZGUsIEV4Y2VwdGlvbiBlKQotICB7Ci0KLSAgICBzdXBlcihtZXNzYWdlKTsKLQotICAgIG1fc3R5bGVOb2RlID0gc3R5bGVOb2RlOwotICAgIHRoaXMubV9leGNlcHRpb24gPSBlOwotICB9Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhbiBYUGF0aEV4Y2VwdGlvbiBvYmplY3QgdGhhdCBob2xkcwotICAgKiBhbiBlcnJvciBtZXNzYWdlLCBhbmQgYW5vdGhlciBleGNlcHRpb24KLSAgICogdGhhdCBjYXVzZWQgdGhpcyBleGNlcHRpb24uCi0gICAqIEBwYXJhbSBtZXNzYWdlIFRoZSBlcnJvciBtZXNzYWdlLgotICAgKiBAcGFyYW0gZSBUaGUgZXhjZXB0aW9uIHRoYXQgY2F1c2VkIHRoaXMgZXhjZXB0aW9uLgotICAgKi8KLSAgcHVibGljIFhQYXRoRXhjZXB0aW9uKFN0cmluZyBtZXNzYWdlLCBFeGNlcHRpb24gZSkKLSAgewotCi0gICAgc3VwZXIobWVzc2FnZSk7Ci0KLSAgICB0aGlzLm1fZXhjZXB0aW9uID0gZTsKLSAgfQotCi0gIC8qKgotICAgKiBQcmludCB0aGUgdGhlIHRyYWNlIG9mIG1ldGhvZHMgZnJvbSB3aGVyZSB0aGUgZXJyb3IKLSAgICogb3JpZ2luYXRlZC4gIFRoaXMgd2lsbCB0cmFjZSBhbGwgbmVzdGVkIGV4Y2VwdGlvbgotICAgKiBvYmplY3RzLCBhcyB3ZWxsIGFzIHRoaXMgb2JqZWN0LgotICAgKiBAcGFyYW0gcyBUaGUgc3RyZWFtIHdoZXJlIHRoZSBkdW1wIHdpbGwgYmUgc2VudCB0by4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHByaW50U3RhY2tUcmFjZShqYXZhLmlvLlByaW50U3RyZWFtIHMpCi0gIHsKLQotICAgIGlmIChzID09IG51bGwpCi0gICAgICBzID0gU3lzdGVtLmVycjsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIHN1cGVyLnByaW50U3RhY2tUcmFjZShzKTsKLSAgICB9Ci0gICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKXt9Ci0KLSAgICBUaHJvd2FibGUgZXhjZXB0aW9uID0gbV9leGNlcHRpb247Ci0KLSAgICBmb3IgKGludCBpID0gMDsgKGkgPCAxMCkgJiYgKG51bGwgIT0gZXhjZXB0aW9uKTsgaSsrKQotICAgIHsKLSAgICAgIHMucHJpbnRsbigiLS0tLS0tLS0tIik7Ci0gICAgICBleGNlcHRpb24ucHJpbnRTdGFja1RyYWNlKHMpOwotCi0gICAgICBpZiAoZXhjZXB0aW9uIGluc3RhbmNlb2YgVHJhbnNmb3JtZXJFeGNlcHRpb24pCi0gICAgICB7Ci0gICAgICAgIFRyYW5zZm9ybWVyRXhjZXB0aW9uIHNlID0gKFRyYW5zZm9ybWVyRXhjZXB0aW9uKSBleGNlcHRpb247Ci0gICAgICAgIFRocm93YWJsZSBwcmV2ID0gZXhjZXB0aW9uOwotCi0gICAgICAgIGV4Y2VwdGlvbiA9IHNlLmdldEV4Y2VwdGlvbigpOwotCi0gICAgICAgIGlmIChwcmV2ID09IGV4Y2VwdGlvbikKLSAgICAgICAgICBicmVhazsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgZXhjZXB0aW9uID0gbnVsbDsKLSAgICAgIH0KLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogRmluZCB0aGUgbW9zdCBjb250YWluZWQgbWVzc2FnZS4KLSAgICoKLSAgICogQHJldHVybiBUaGUgZXJyb3IgbWVzc2FnZSBvZiB0aGUgb3JpZ2luYXRpbmcgZXhjZXB0aW9uLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRNZXNzYWdlKCkKLSAgewotCi0gICAgU3RyaW5nIGxhc3RNZXNzYWdlID0gc3VwZXIuZ2V0TWVzc2FnZSgpOwotICAgIFRocm93YWJsZSBleGNlcHRpb24gPSBtX2V4Y2VwdGlvbjsKLQotICAgIHdoaWxlIChudWxsICE9IGV4Y2VwdGlvbikKLSAgICB7Ci0gICAgICBTdHJpbmcgbmV4dE1lc3NhZ2UgPSBleGNlcHRpb24uZ2V0TWVzc2FnZSgpOwotCi0gICAgICBpZiAobnVsbCAhPSBuZXh0TWVzc2FnZSkKLSAgICAgICAgbGFzdE1lc3NhZ2UgPSBuZXh0TWVzc2FnZTsKLQotICAgICAgaWYgKGV4Y2VwdGlvbiBpbnN0YW5jZW9mIFRyYW5zZm9ybWVyRXhjZXB0aW9uKQotICAgICAgewotICAgICAgICBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBzZSA9IChUcmFuc2Zvcm1lckV4Y2VwdGlvbikgZXhjZXB0aW9uOwotICAgICAgICBUaHJvd2FibGUgcHJldiA9IGV4Y2VwdGlvbjsKLQotICAgICAgICBleGNlcHRpb24gPSBzZS5nZXRFeGNlcHRpb24oKTsKLQotICAgICAgICBpZiAocHJldiA9PSBleGNlcHRpb24pCi0gICAgICAgICAgYnJlYWs7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIGV4Y2VwdGlvbiA9IG51bGw7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgcmV0dXJuIChudWxsICE9IGxhc3RNZXNzYWdlKSA/IGxhc3RNZXNzYWdlIDogIiI7Ci0gIH0KLQotICAvKioKLSAgICogUHJpbnQgdGhlIHRoZSB0cmFjZSBvZiBtZXRob2RzIGZyb20gd2hlcmUgdGhlIGVycm9yCi0gICAqIG9yaWdpbmF0ZWQuICBUaGlzIHdpbGwgdHJhY2UgYWxsIG5lc3RlZCBleGNlcHRpb24KLSAgICogb2JqZWN0cywgYXMgd2VsbCBhcyB0aGlzIG9iamVjdC4KLSAgICogQHBhcmFtIHMgVGhlIHdyaXRlciB3aGVyZSB0aGUgZHVtcCB3aWxsIGJlIHNlbnQgdG8uCi0gICAqLwotICBwdWJsaWMgdm9pZCBwcmludFN0YWNrVHJhY2UoamF2YS5pby5QcmludFdyaXRlciBzKQotICB7Ci0KLSAgICBpZiAocyA9PSBudWxsKQotICAgICAgcyA9IG5ldyBqYXZhLmlvLlByaW50V3JpdGVyKFN5c3RlbS5lcnIpOwotCi0gICAgdHJ5Ci0gICAgewotICAgICAgc3VwZXIucHJpbnRTdGFja1RyYWNlKHMpOwotICAgIH0KLSAgICBjYXRjaCAoRXhjZXB0aW9uIGUpe30KLQotCi0gICAgYm9vbGVhbiBpc0pkazE0T3JIaWdoZXIgPSBmYWxzZTsKLSAgICB0cnkgewotICAgICAgICBUaHJvd2FibGUuY2xhc3MuZ2V0TWV0aG9kKCJnZXRDYXVzZSIsIChDbGFzc1tdKSBudWxsKTsKLSAgICAgICAgaXNKZGsxNE9ySGlnaGVyID0gdHJ1ZTsKLSAgICB9IGNhdGNoIChOb1N1Y2hNZXRob2RFeGNlcHRpb24gbnNtZSkgewotICAgICAgICAvLyBkbyBub3RoaW5nCi0gICAgfQotCi0gICAgLy8gVGhlIHByaW50U3RhY2tUcmFjZSBtZXRob2Qgb2YgdGhlIFRocm93YWJsZSBjbGFzcyBpbiBqZGsgMS40Ci0gICAgLy8gYW5kIGhpZ2hlciB3aWxsIGluY2x1ZGUgdGhlIGNhdXNlIHdoZW4gcHJpbnRpbmcgdGhlIGJhY2t0cmFjZS4KLSAgICAvLyBUaGUgZm9sbG93aW5nIGNvZGUgaXMgb25seSByZXF1aXJlZCB3aGVuIHVzaW5nIGpkayAxLjMgb3IgbG93ZXIKLSAgICBpZiAoIWlzSmRrMTRPckhpZ2hlcikgewotCi0gICAgICBUaHJvd2FibGUgZXhjZXB0aW9uID0gbV9leGNlcHRpb247Ci0KLSAgICAgIGZvciAoaW50IGkgPSAwOyAoaSA8IDEwKSAmJiAobnVsbCAhPSBleGNlcHRpb24pOyBpKyspCi0gICAgICB7Ci0gICAgICAgIHMucHJpbnRsbigiLS0tLS0tLS0tIik7Ci0KLSAgICAgICAgdHJ5Ci0gICAgICAgIHsKLSAgICAgICAgICBleGNlcHRpb24ucHJpbnRTdGFja1RyYWNlKHMpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChFeGNlcHRpb24gZSkKLSAgICAgICAgewotICAgICAgICAgIHMucHJpbnRsbigiQ291bGQgbm90IHByaW50IHN0YWNrIHRyYWNlLi4uIik7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoZXhjZXB0aW9uIGluc3RhbmNlb2YgVHJhbnNmb3JtZXJFeGNlcHRpb24pCi0gICAgICAgIHsKLSAgICAgICAgICBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBzZSA9IChUcmFuc2Zvcm1lckV4Y2VwdGlvbikgZXhjZXB0aW9uOwotICAgICAgICAgIFRocm93YWJsZSBwcmV2ID0gZXhjZXB0aW9uOwotCi0gICAgICAgICAgZXhjZXB0aW9uID0gc2UuZ2V0RXhjZXB0aW9uKCk7Ci0KLSAgICAgICAgICBpZiAocHJldiA9PSBleGNlcHRpb24pCi0gICAgICAgICAgewotICAgICAgICAgICAgZXhjZXB0aW9uID0gbnVsbDsKLQotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotICAgICAgICAgIGV4Y2VwdGlvbiA9IG51bGw7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogIFJldHVybiB0aGUgZW1iZWRkZWQgZXhjZXB0aW9uLCBpZiBhbnkuCi0gICAqICBPdmVycmlkZXMgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbi5nZXRFeGNlcHRpb24oKS4KLSAgICoKLSAgICogIEByZXR1cm4gVGhlIGVtYmVkZGVkIGV4Y2VwdGlvbiwgb3IgbnVsbCBpZiB0aGVyZSBpcyBub25lLgotICAgKi8KLSAgcHVibGljIFRocm93YWJsZSBnZXRFeGNlcHRpb24oKQotICB7Ci0gICAgcmV0dXJuIG1fZXhjZXB0aW9uOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL1hQYXRoRmFjdG9yeS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9YUGF0aEZhY3RvcnkuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYmI1MDYxYi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL1hQYXRoRmFjdG9yeS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTIgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogWFBhdGhGYWN0b3J5LmphdmEsdiAxLjEuMi4xIDIwMDUvMDgvMDEgMDE6MzA6MTQgamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbDsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uU291cmNlTG9jYXRvcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuUHJlZml4UmVzb2x2ZXI7Ci0KLS8qKgotICogRmFjdG9yeSBjbGFzcyBmb3IgY3JlYXRpbmcgYW4gWFBhdGguICBJbXBsZW1lbnRvcnMgb2YgWFBhdGggZGVyaXZhdGl2ZXMKLSAqIHdpbGwgbmVlZCB0byBtYWtlIGEgZGVyaXZlZCBjbGFzcyBvZiB0aGlzLgotICogQHhzbC51c2FnZSBhZHZhbmNlZAotICovCi1wdWJsaWMgaW50ZXJmYWNlIFhQYXRoRmFjdG9yeQotewotCi0gIC8qKgotICAgKiBDcmVhdGUgYW4gWFBhdGguCi0gICAqCi0gICAqIEBwYXJhbSBleHByU3RyaW5nIFRoZSBYUGF0aCBleHByZXNzaW9uIHN0cmluZy4KLSAgICogQHBhcmFtIGxvY2F0b3IgVGhlIGxvY2F0aW9uIG9mIHRoZSBleHByZXNzaW9uIHN0cmluZywgbWFpbmx5IGZvciBkaWFnbm9zdGljCi0gICAqICAgICAgICAgICAgICAgIHB1cnBvc2VzLgotICAgKiBAcGFyYW0gcHJlZml4UmVzb2x2ZXIgVGhpcyB3aWxsIGJlIGNhbGxlZCBpbiBvcmRlciB0byByZXNvbHZlIHByZWZpeGVzCi0gICAqICAgICAgICB0byBuYW1lc3BhY2UgVVJJcy4KLSAgICogQHBhcmFtIHR5cGUgT25lIG9mIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuWFBhdGgjU0VMRUNUfSBvcgotICAgKiAgICAgICAgICAgICB7QGxpbmsgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoI01BVENIfS4KLSAgICoKLSAgICogQHJldHVybiBhbiBYUGF0aCByZWFkeSBmb3IgZXhlY3V0aW9uLgotICAgKi8KLSAgWFBhdGggY3JlYXRlKFN0cmluZyBleHByU3RyaW5nLCBTb3VyY2VMb2NhdG9yIGxvY2F0b3IsCi0gICAgICAgICAgICAgICBQcmVmaXhSZXNvbHZlciBwcmVmaXhSZXNvbHZlciwgaW50IHR5cGUpOwotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9YUGF0aFByb2Nlc3NvckV4Y2VwdGlvbi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9YUGF0aFByb2Nlc3NvckV4Y2VwdGlvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmNzcyOGVlLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvWFBhdGhQcm9jZXNzb3JFeGNlcHRpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDU2ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFhQYXRoUHJvY2Vzc29yRXhjZXB0aW9uLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTUgMDE6NDI6NDUgamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbDsKLQotLyoqCi0gKiBEZXJpdmVkIGZyb20gWFBhdGhFeGNlcHRpb24gaW4gb3JkZXIgdGhhdCBYUGF0aCBwcm9jZXNzb3IKLSAqIGV4Y2VwdGlvbnMgbWF5IGJlIHNwZWNpZmljYWxseSBjYXVnaHQuCi0gKiBAeHNsLnVzYWdlIGdlbmVyYWwKLSAqLwotcHVibGljIGNsYXNzIFhQYXRoUHJvY2Vzc29yRXhjZXB0aW9uIGV4dGVuZHMgWFBhdGhFeGNlcHRpb24KLXsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMTIxNTUwOTQxODMyNjY0MjYwM0w7Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhbiBYUGF0aFByb2Nlc3NvckV4Y2VwdGlvbiBvYmplY3QgdGhhdCBob2xkcwotICAgKiBhbiBlcnJvciBtZXNzYWdlLgotICAgKiBAcGFyYW0gbWVzc2FnZSBUaGUgZXJyb3IgbWVzc2FnZS4KLSAgICovCi0gIHB1YmxpYyBYUGF0aFByb2Nlc3NvckV4Y2VwdGlvbihTdHJpbmcgbWVzc2FnZSkKLSAgewotICAgIHN1cGVyKG1lc3NhZ2UpOwotICB9Ci0KLQotICAvKioKLSAgICogQ3JlYXRlIGFuIFhQYXRoUHJvY2Vzc29yRXhjZXB0aW9uIG9iamVjdCB0aGF0IGhvbGRzCi0gICAqIGFuIGVycm9yIG1lc3NhZ2UsIGFuZCBhbm90aGVyIGV4Y2VwdGlvbgotICAgKiB0aGF0IGNhdXNlZCB0aGlzIGV4Y2VwdGlvbi4KLSAgICogQHBhcmFtIG1lc3NhZ2UgVGhlIGVycm9yIG1lc3NhZ2UuCi0gICAqIEBwYXJhbSBlIFRoZSBleGNlcHRpb24gdGhhdCBjYXVzZWQgdGhpcyBleGNlcHRpb24uCi0gICAqLwotICBwdWJsaWMgWFBhdGhQcm9jZXNzb3JFeGNlcHRpb24oU3RyaW5nIG1lc3NhZ2UsIEV4Y2VwdGlvbiBlKQotICB7Ci0gICAgc3VwZXIobWVzc2FnZSwgZSk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvWFBhdGhWaXNpdGFibGUuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvWFBhdGhWaXNpdGFibGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYmZhODQ3MC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL1hQYXRoVmlzaXRhYmxlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0MyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAyLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBYUGF0aFZpc2l0YWJsZS5qYXZhLHYgMS4xLjIuMSAyMDA1LzA4LzAxIDAxOjMwOjEzIGplZmZzdXR0b3IgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWw7Ci0KLS8qKgotICogQSBjbGFzcyB0aGF0IGltcGxlbWVudHMgdGhpcyBpbnRlcmZhY2Ugd2lsbCBjYWxsIGEgWFBhdGhWaXNpdG9yCi0gKiBmb3IgaXRzZWxmIGFuZCBtZW1iZXJzIHdpdGhpbiBpdCdzIGhlYXJhcmNoeS4gIElmIHRoZSBYUGF0aFZpc2l0b3IncwotICogbWV0aG9kIHJldHVybnMgZmFsc2UsIHRoZSBzdWItbWVtYmVyIGhlYXJhcmNoeSB3aWxsIG5vdCBiZQotICogdHJhdmVyc2VkLgotICovCi1wdWJsaWMgaW50ZXJmYWNlIFhQYXRoVmlzaXRhYmxlCi17Ci0gICAgICAgIC8qKgotICAgICAgICAgKiBUaGlzIHdpbGwgdHJhdmVyc2UgdGhlIGhlYXJhcmNoeSwgY2FsbGluZyB0aGUgdmlzaXRvciBmb3IKLSAgICAgICAgICogZWFjaCBtZW1iZXIuICBJZiB0aGUgY2FsbGVkIHZpc2l0b3IgbWV0aG9kIHJldHVybnMKLSAgICAgICAgICogZmFsc2UsIHRoZSBzdWJ0cmVlIHNob3VsZCBub3QgYmUgY2FsbGVkLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gb3duZXIgVGhlIG93bmVyIG9mIHRoZSB2aXNpdG9yLCB3aGVyZSB0aGF0IHBhdGggbWF5IGJlCi0gICAgICAgICAqICAgICAgICAgICAgICByZXdyaXR0ZW4gaWYgbmVlZGVkLgotICAgICAgICAgKiBAcGFyYW0gdmlzaXRvciBUaGUgdmlzaXRvciB3aG9zZSBhcHByb3ByaWF0ZSBtZXRob2Qgd2lsbCBiZSBjYWxsZWQuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgdm9pZCBjYWxsVmlzaXRvcnMoRXhwcmVzc2lvbk93bmVyIG93bmVyLCBYUGF0aFZpc2l0b3IgdmlzaXRvcik7Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL1hQYXRoVmlzaXRvci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9YUGF0aFZpc2l0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOGE5MDllYi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL1hQYXRoVmlzaXRvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjA0ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDIwMDItMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFhQYXRoVmlzaXRvci5qYXZhLHYgMS4xLjIuMSAyMDA1LzA4LzAxIDAxOjMwOjExIGplZmZzdXR0b3IgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWw7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuYXhlcy5Mb2NQYXRoSXRlcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmF4ZXMuVW5pb25QYXRoSXRlcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmZ1bmN0aW9ucy5GdW5jdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YTnVtYmVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhTdHJpbmc7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9wZXJhdGlvbnMuT3BlcmF0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vcGVyYXRpb25zLlVuYXJ5T3BlcmF0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vcGVyYXRpb25zLlZhcmlhYmxlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5wYXR0ZXJucy5Ob2RlVGVzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucGF0dGVybnMuU3RlcFBhdHRlcm47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLnBhdHRlcm5zLlVuaW9uUGF0dGVybjsKLQotLyoqCi0gKiBBIGRlcml2YXRpb24gZnJvbSB0aGlzIGNsYXNzIGNhbiBiZSBwYXNzZWQgdG8gYSBjbGFzcyB0aGF0IGltcGxlbWVudHMKLSAqIHRoZSBYUGF0aFZpc2l0YWJsZSBpbnRlcmZhY2UsIHRvIGhhdmUgdGhlIGFwcHJvcHJpYXRlIG1ldGhvZCBjYWxsZWQKLSAqIGZvciBlYWNoIGNvbXBvbmVudCBvZiB0aGUgWFBhdGguICBBc2lkZSBmcm9tIHBvc3NpYmxlIG90aGVyIHVzZXMsIHRoZQotICogbWFpbiBpbnRlbnRpb24gaXMgdG8gcHJvdmlkZSBhIHJlYXNvbmFibGUgbWVhbnMgdG8gcGVyZm9ybSBleHByZXNzaW9uCi0gKiByZXdyaXRpbmcuCi0gKgotICogPHA+RWFjaCBtZXRob2QgaGFzIHRoZSBmb3JtCi0gKiA8Y29kZT5ib29sZWFuIHZpc2l0Q29tcG9uZW50VHlwZShFeHByZXNzaW9uT3duZXIgb3duZXIsIENvbXBvbmVudFR5cGUgY29tcFR5cGUpPC9jb2RlPi4KLSAqIFRoZSBFeHByZXNzaW9uT3duZXIgYXJndW1lbnQgaXMgdGhlIG93bmVyIG9mIHRoZSBjb21wb25lbnQsIGFuZCBjYW4KLSAqIGJlIHVzZWQgdG8gcmVzZXQgdGhlIGV4cHJlc3Npb24gZm9yIHJld3JpdGluZy4gIElmIGEgbWV0aG9kIHJldHVybnMKLSAqIGZhbHNlLCB0aGUgc3ViIGhpZXJhcmNoeSB3aWxsIG5vdCBiZSB0cmF2ZXJzZWQuPC9wPgotICoKLSAqIDxwPlRoaXMgY2xhc3MgaXMgbWVhbnQgdG8gYmUgYSBiYXNlIGNsYXNzIHRoYXQgd2lsbCBiZSBkZXJpdmVkIGJ5IGNvbmNyZXRlIGNsYXNzZXMsCi0gKiBhbmQgZG9lc24ndCBtdWNoIGV4Y2VwdCByZXR1cm4gdHJ1ZSBmb3IgZWFjaCBtZXRob2QuPC9wPgotICovCi1wdWJsaWMgY2xhc3MgWFBhdGhWaXNpdG9yCi17Ci0gICAgICAgIC8qKgotICAgICAgICAgKiBWaXNpdCBhIExvY2F0aW9uUGF0aC4KLSAgICAgICAgICogQHBhcmFtIG93bmVyIFRoZSBvd25lciBvZiB0aGUgZXhwcmVzc2lvbiwgdG8gd2hpY2ggdGhlIGV4cHJlc3Npb24gY2FuCi0gICAgICAgICAqICAgICAgICAgICAgICBiZSByZXNldCBpZiByZXdyaXRpbmcgdGFrZXMgcGxhY2UuCi0gICAgICAgICAqIEBwYXJhbSBwYXRoIFRoZSBMb2NhdGlvblBhdGggb2JqZWN0LgotICAgICAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHN1YiBleHByZXNzaW9ucyBzaG91bGQgYmUgdHJhdmVyc2VkLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIGJvb2xlYW4gdmlzaXRMb2NhdGlvblBhdGgoRXhwcmVzc2lvbk93bmVyIG93bmVyLCBMb2NQYXRoSXRlcmF0b3IgcGF0aCkKLSAgICAgICAgewotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFZpc2l0IGEgVW5pb25QYXRoLgotICAgICAgICAgKiBAcGFyYW0gb3duZXIgVGhlIG93bmVyIG9mIHRoZSBleHByZXNzaW9uLCB0byB3aGljaCB0aGUgZXhwcmVzc2lvbiBjYW4KLSAgICAgICAgICogICAgICAgICAgICAgIGJlIHJlc2V0IGlmIHJld3JpdGluZyB0YWtlcyBwbGFjZS4KLSAgICAgICAgICogQHBhcmFtIHBhdGggVGhlIFVuaW9uUGF0aCBvYmplY3QuCi0gICAgICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgc3ViIGV4cHJlc3Npb25zIHNob3VsZCBiZSB0cmF2ZXJzZWQuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgYm9vbGVhbiB2aXNpdFVuaW9uUGF0aChFeHByZXNzaW9uT3duZXIgb3duZXIsIFVuaW9uUGF0aEl0ZXJhdG9yIHBhdGgpCi0gICAgICAgIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBWaXNpdCBhIHN0ZXAgd2l0aGluIGEgbG9jYXRpb24gcGF0aC4KLSAgICAgICAgICogQHBhcmFtIG93bmVyIFRoZSBvd25lciBvZiB0aGUgZXhwcmVzc2lvbiwgdG8gd2hpY2ggdGhlIGV4cHJlc3Npb24gY2FuCi0gICAgICAgICAqICAgICAgICAgICAgICBiZSByZXNldCBpZiByZXdyaXRpbmcgdGFrZXMgcGxhY2UuCi0gICAgICAgICAqIEBwYXJhbSBzdGVwIFRoZSBTdGVwIG9iamVjdC4KLSAgICAgICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBzdWIgZXhwcmVzc2lvbnMgc2hvdWxkIGJlIHRyYXZlcnNlZC4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBib29sZWFuIHZpc2l0U3RlcChFeHByZXNzaW9uT3duZXIgb3duZXIsIE5vZGVUZXN0IHN0ZXApCi0gICAgICAgIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBWaXNpdCBhIHByZWRpY2F0ZSB3aXRoaW4gYSBsb2NhdGlvbiBwYXRoLiAgTm90ZSB0aGF0IHRoZXJlIGlzbid0IGEKLSAgICAgICAgICogcHJvcGVyIHVuaXF1ZSBjb21wb25lbnQgZm9yIHByZWRpY2F0ZXMsIGFuZCB0aGF0IHRoZSBleHByZXNzaW9uIHdpbGwKLSAgICAgICAgICogYmUgY2FsbGVkIGFsc28gZm9yIHdoYXRldmVyIHR5cGUgRXhwcmVzc2lvbiBpcy4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIG93bmVyIFRoZSBvd25lciBvZiB0aGUgZXhwcmVzc2lvbiwgdG8gd2hpY2ggdGhlIGV4cHJlc3Npb24gY2FuCi0gICAgICAgICAqICAgICAgICAgICAgICBiZSByZXNldCBpZiByZXdyaXRpbmcgdGFrZXMgcGxhY2UuCi0gICAgICAgICAqIEBwYXJhbSBwcmVkIFRoZSBwcmVkaWNhdGUgb2JqZWN0LgotICAgICAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHN1YiBleHByZXNzaW9ucyBzaG91bGQgYmUgdHJhdmVyc2VkLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIGJvb2xlYW4gdmlzaXRQcmVkaWNhdGUoRXhwcmVzc2lvbk93bmVyIG93bmVyLCBFeHByZXNzaW9uIHByZWQpCi0gICAgICAgIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBWaXNpdCBhIGJpbmFyeSBvcGVyYXRpb24uCi0gICAgICAgICAqIEBwYXJhbSBvd25lciBUaGUgb3duZXIgb2YgdGhlIGV4cHJlc3Npb24sIHRvIHdoaWNoIHRoZSBleHByZXNzaW9uIGNhbgotICAgICAgICAgKiAgICAgICAgICAgICAgYmUgcmVzZXQgaWYgcmV3cml0aW5nIHRha2VzIHBsYWNlLgotICAgICAgICAgKiBAcGFyYW0gb3AgVGhlIG9wZXJhdGlvbiBvYmplY3QuCi0gICAgICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgc3ViIGV4cHJlc3Npb25zIHNob3VsZCBiZSB0cmF2ZXJzZWQuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgYm9vbGVhbiB2aXNpdEJpbmFyeU9wZXJhdGlvbihFeHByZXNzaW9uT3duZXIgb3duZXIsIE9wZXJhdGlvbiBvcCkKLSAgICAgICAgewotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFZpc2l0IGEgdW5hcnkgb3BlcmF0aW9uLgotICAgICAgICAgKiBAcGFyYW0gb3duZXIgVGhlIG93bmVyIG9mIHRoZSBleHByZXNzaW9uLCB0byB3aGljaCB0aGUgZXhwcmVzc2lvbiBjYW4KLSAgICAgICAgICogICAgICAgICAgICAgIGJlIHJlc2V0IGlmIHJld3JpdGluZyB0YWtlcyBwbGFjZS4KLSAgICAgICAgICogQHBhcmFtIG9wIFRoZSBvcGVyYXRpb24gb2JqZWN0LgotICAgICAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHN1YiBleHByZXNzaW9ucyBzaG91bGQgYmUgdHJhdmVyc2VkLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIGJvb2xlYW4gdmlzaXRVbmFyeU9wZXJhdGlvbihFeHByZXNzaW9uT3duZXIgb3duZXIsIFVuYXJ5T3BlcmF0aW9uIG9wKQotICAgICAgICB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogVmlzaXQgYSB2YXJpYWJsZSByZWZlcmVuY2UuCi0gICAgICAgICAqIEBwYXJhbSBvd25lciBUaGUgb3duZXIgb2YgdGhlIGV4cHJlc3Npb24sIHRvIHdoaWNoIHRoZSBleHByZXNzaW9uIGNhbgotICAgICAgICAgKiAgICAgICAgICAgICAgYmUgcmVzZXQgaWYgcmV3cml0aW5nIHRha2VzIHBsYWNlLgotICAgICAgICAgKiBAcGFyYW0gdmFyIFRoZSB2YXJpYWJsZSByZWZlcmVuY2Ugb2JqZWN0LgotICAgICAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHN1YiBleHByZXNzaW9ucyBzaG91bGQgYmUgdHJhdmVyc2VkLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIGJvb2xlYW4gdmlzaXRWYXJpYWJsZVJlZihFeHByZXNzaW9uT3duZXIgb3duZXIsIFZhcmlhYmxlIHZhcikKLSAgICAgICAgewotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFZpc2l0IGEgZnVuY3Rpb24uCi0gICAgICAgICAqIEBwYXJhbSBvd25lciBUaGUgb3duZXIgb2YgdGhlIGV4cHJlc3Npb24sIHRvIHdoaWNoIHRoZSBleHByZXNzaW9uIGNhbgotICAgICAgICAgKiAgICAgICAgICAgICAgYmUgcmVzZXQgaWYgcmV3cml0aW5nIHRha2VzIHBsYWNlLgotICAgICAgICAgKiBAcGFyYW0gZnVuYyBUaGUgZnVuY3Rpb24gcmVmZXJlbmNlIG9iamVjdC4KLSAgICAgICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBzdWIgZXhwcmVzc2lvbnMgc2hvdWxkIGJlIHRyYXZlcnNlZC4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBib29sZWFuIHZpc2l0RnVuY3Rpb24oRXhwcmVzc2lvbk93bmVyIG93bmVyLCBGdW5jdGlvbiBmdW5jKQotICAgICAgICB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogVmlzaXQgYSBtYXRjaCBwYXR0ZXJuLgotICAgICAgICAgKiBAcGFyYW0gb3duZXIgVGhlIG93bmVyIG9mIHRoZSBleHByZXNzaW9uLCB0byB3aGljaCB0aGUgZXhwcmVzc2lvbiBjYW4KLSAgICAgICAgICogICAgICAgICAgICAgIGJlIHJlc2V0IGlmIHJld3JpdGluZyB0YWtlcyBwbGFjZS4KLSAgICAgICAgICogQHBhcmFtIHBhdHRlcm4gVGhlIG1hdGNoIHBhdHRlcm4gb2JqZWN0LgotICAgICAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHN1YiBleHByZXNzaW9ucyBzaG91bGQgYmUgdHJhdmVyc2VkLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIGJvb2xlYW4gdmlzaXRNYXRjaFBhdHRlcm4oRXhwcmVzc2lvbk93bmVyIG93bmVyLCBTdGVwUGF0dGVybiBwYXR0ZXJuKQotICAgICAgICB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogVmlzaXQgYSB1bmlvbiBwYXR0ZXJuLgotICAgICAgICAgKiBAcGFyYW0gb3duZXIgVGhlIG93bmVyIG9mIHRoZSBleHByZXNzaW9uLCB0byB3aGljaCB0aGUgZXhwcmVzc2lvbiBjYW4KLSAgICAgICAgICogICAgICAgICAgICAgIGJlIHJlc2V0IGlmIHJld3JpdGluZyB0YWtlcyBwbGFjZS4KLSAgICAgICAgICogQHBhcmFtIHBhdHRlcm4gVGhlIHVuaW9uIHBhdHRlcm4gb2JqZWN0LgotICAgICAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHN1YiBleHByZXNzaW9ucyBzaG91bGQgYmUgdHJhdmVyc2VkLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIGJvb2xlYW4gdmlzaXRVbmlvblBhdHRlcm4oRXhwcmVzc2lvbk93bmVyIG93bmVyLCBVbmlvblBhdHRlcm4gcGF0dGVybikKLSAgICAgICAgewotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFZpc2l0IGEgc3RyaW5nIGxpdGVyYWwuCi0gICAgICAgICAqIEBwYXJhbSBvd25lciBUaGUgb3duZXIgb2YgdGhlIGV4cHJlc3Npb24sIHRvIHdoaWNoIHRoZSBleHByZXNzaW9uIGNhbgotICAgICAgICAgKiAgICAgICAgICAgICAgYmUgcmVzZXQgaWYgcmV3cml0aW5nIHRha2VzIHBsYWNlLgotICAgICAgICAgKiBAcGFyYW0gc3RyIFRoZSBzdHJpbmcgbGl0ZXJhbCBvYmplY3QuCi0gICAgICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgc3ViIGV4cHJlc3Npb25zIHNob3VsZCBiZSB0cmF2ZXJzZWQuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgYm9vbGVhbiB2aXNpdFN0cmluZ0xpdGVyYWwoRXhwcmVzc2lvbk93bmVyIG93bmVyLCBYU3RyaW5nIHN0cikKLSAgICAgICAgewotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0KLQotICAgICAgICAvKioKLSAgICAgICAgICogVmlzaXQgYSBudW1iZXIgbGl0ZXJhbC4KLSAgICAgICAgICogQHBhcmFtIG93bmVyIFRoZSBvd25lciBvZiB0aGUgZXhwcmVzc2lvbiwgdG8gd2hpY2ggdGhlIGV4cHJlc3Npb24gY2FuCi0gICAgICAgICAqICAgICAgICAgICAgICBiZSByZXNldCBpZiByZXdyaXRpbmcgdGFrZXMgcGxhY2UuCi0gICAgICAgICAqIEBwYXJhbSBudW0gVGhlIG51bWJlciBsaXRlcmFsIG9iamVjdC4KLSAgICAgICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBzdWIgZXhwcmVzc2lvbnMgc2hvdWxkIGJlIHRyYXZlcnNlZC4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBib29sZWFuIHZpc2l0TnVtYmVyTGl0ZXJhbChFeHByZXNzaW9uT3duZXIgb3duZXIsIFhOdW1iZXIgbnVtKQotICAgICAgICB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgIH0KLQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2F4ZXMvQXR0cmlidXRlSXRlcmF0b3IuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvYXhlcy9BdHRyaWJ1dGVJdGVyYXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4ZjA4YWZhLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvYXhlcy9BdHRyaWJ1dGVJdGVyYXRvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNzcgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogQXR0cmlidXRlSXRlcmF0b3IuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNCAxOTo0NToyMiBqZWZmc3V0dG9yIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmF4ZXM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE07Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmNvbXBpbGVyLkNvbXBpbGVyOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgaW1wbGVtZW50cyBhbiBvcHRpbWl6ZWQgaXRlcmF0b3IgZm9yCi0gKiBhdHRyaWJ1dGUgYXhlcyBwYXR0ZXJucy4KLSAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmF4ZXMjQ2hpbGRUZXN0SXRlcmF0b3IKLSAqIEB4c2wudXNhZ2UgYWR2YW5jZWQKLSAqLwotcHVibGljIGNsYXNzIEF0dHJpYnV0ZUl0ZXJhdG9yIGV4dGVuZHMgQ2hpbGRUZXN0SXRlcmF0b3IKLXsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTg0MTc5ODY3MDA3MTIyMjk2ODZMOwotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBBdHRyaWJ1dGVJdGVyYXRvciBvYmplY3QuCi0gICAqCi0gICAqIEBwYXJhbSBjb21waWxlciBBIHJlZmVyZW5jZSB0byB0aGUgQ29tcGlsZXIgdGhhdCBjb250YWlucyB0aGUgb3AgbWFwLgotICAgKiBAcGFyYW0gb3BQb3MgVGhlIHBvc2l0aW9uIHdpdGhpbiB0aGUgb3AgbWFwLCB3aGljaCBjb250YWlucyB0aGUKLSAgICogbG9jYXRpb24gcGF0aCBleHByZXNzaW9uIGZvciB0aGlzIGl0dGVyYXRvci4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBBdHRyaWJ1dGVJdGVyYXRvcihDb21waWxlciBjb21waWxlciwgaW50IG9wUG9zLCBpbnQgYW5hbHlzaXMpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHN1cGVyKGNvbXBpbGVyLCBvcFBvcywgYW5hbHlzaXMpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbmV4dCBub2RlIHZpYSBnZXRGaXJzdEF0dHJpYnV0ZSAmJiBnZXROZXh0QXR0cmlidXRlLgotICAgKi8KLSAgcHJvdGVjdGVkIGludCBnZXROZXh0Tm9kZSgpCi0gIHsKLSAgICBtX2xhc3RGZXRjaGVkID0gKERUTS5OVUxMID09IG1fbGFzdEZldGNoZWQpCi0gICAgICAgICAgICAgICAgICAgICA/IG1fY2R0bS5nZXRGaXJzdEF0dHJpYnV0ZShtX2NvbnRleHQpCi0gICAgICAgICAgICAgICAgICAgICA6IG1fY2R0bS5nZXROZXh0QXR0cmlidXRlKG1fbGFzdEZldGNoZWQpOwotICAgIHJldHVybiBtX2xhc3RGZXRjaGVkOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIGF4aXMgYmVpbmcgaXRlcmF0ZWQsIGlmIGl0IGlzIGtub3duLgotICAgKgotICAgKiBAcmV0dXJuIEF4aXMuQ0hJTEQsIGV0Yy4sIG9yIC0xIGlmIHRoZSBheGlzIGlzIG5vdCBrbm93biBvciBpcyBvZiBtdWx0aXBsZQotICAgKiB0eXBlcy4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0QXhpcygpCi0gIHsKLSAgICByZXR1cm4gY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uQXhpcy5BVFRSSUJVVEU7Ci0gIH0KLQotCi0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvYXhlcy9BeGVzV2Fsa2VyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2F4ZXMvQXhlc1dhbGtlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxODM0MjY0Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvYXhlcy9BeGVzV2Fsa2VyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw1OTIgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogQXhlc1dhbGtlci5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE0IDE5OjQ1OjIyIGplZmZzdXR0b3IgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuYXhlczsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwucmVzLlhTTE1lc3NhZ2VzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1BeGlzVHJhdmVyc2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTUl0ZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5FeHByZXNzaW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5FeHByZXNzaW9uT3duZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoQ29udGV4dDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuWFBhdGhWaXNpdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5jb21waWxlci5Db21waWxlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucmVzLlhQQVRIRXJyb3JSZXNvdXJjZXM7Ci0KLS8qKgotICogU2VydmVzIGFzIGNvbW1vbiBpbnRlcmZhY2UgZm9yIGF4ZXMgV2Fsa2VycywgYW5kIHN0b3JlcyBjb21tb24KLSAqIHN0YXRlIHZhcmlhYmxlcy4KLSAqLwotcHVibGljIGNsYXNzIEF4ZXNXYWxrZXIgZXh0ZW5kcyBQcmVkaWNhdGVkTm9kZVRlc3QKLSAgICAgICAgaW1wbGVtZW50cyBDbG9uZWFibGUsIFBhdGhDb21wb25lbnQsIEV4cHJlc3Npb25Pd25lcgotewotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMjk2NjAzMTk1MTMwNjYwMTI0N0w7Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhbiBBeGVzV2Fsa2VyIHVzaW5nIGEgTG9jUGF0aEl0ZXJhdG9yLgotICAgKgotICAgKiBAcGFyYW0gbG9jUGF0aEl0ZXJhdG9yIG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgcGFyZW50IGl0ZXJhdG9yLgotICAgKi8KLSAgcHVibGljIEF4ZXNXYWxrZXIoTG9jUGF0aEl0ZXJhdG9yIGxvY1BhdGhJdGVyYXRvciwgaW50IGF4aXMpCi0gIHsKLSAgICBzdXBlciggbG9jUGF0aEl0ZXJhdG9yICk7Ci0gICAgbV9heGlzID0gYXhpczsKLSAgfQotCi0gIHB1YmxpYyBmaW5hbCBXYWxraW5nSXRlcmF0b3Igd2koKQotICB7Ci0gICAgcmV0dXJuIChXYWxraW5nSXRlcmF0b3IpbV9scGk7Ci0gIH0KLQotICAvKioKLSAgICogSW5pdGlhbGl6ZSBhbiBBeGVzV2Fsa2VyIGR1cmluZyB0aGUgcGFyc2Ugb2YgdGhlIFhQYXRoIGV4cHJlc3Npb24uCi0gICAqCi0gICAqIEBwYXJhbSBjb21waWxlciBUaGUgQ29tcGlsZXIgb2JqZWN0IHRoYXQgaGFzIGluZm9ybWF0aW9uIGFib3V0IHRoaXMKLSAgICogICAgICAgICAgICAgICAgIHdhbGtlciBpbiB0aGUgb3AgbWFwLgotICAgKiBAcGFyYW0gb3BQb3MgVGhlIG9wIGNvZGUgcG9zaXRpb24gb2YgdGhpcyBsb2NhdGlvbiBzdGVwLgotICAgKiBAcGFyYW0gc3RlcFR5cGUgIFRoZSB0eXBlIG9mIGxvY2F0aW9uIHN0ZXAuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgaW5pdChDb21waWxlciBjb21waWxlciwgaW50IG9wUG9zLCBpbnQgc3RlcFR5cGUpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaW5pdFByZWRpY2F0ZUluZm8oY29tcGlsZXIsIG9wUG9zKTsKLQotICAgIC8vIGludCB0ZXN0VHlwZSA9IGNvbXBpbGVyLmdldE9wKG5vZGVUZXN0T3BQb3MpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBhIGNsb25lZCBBeGVzV2Fsa2VyLgotICAgKgotICAgKiBAcmV0dXJuIEEgbmV3IEF4ZXNXYWxrZXIgdGhhdCBjYW4gYmUgdXNlZCB3aXRob3V0IG11dGF0aW5nIHRoaXMgb25lLgotICAgKgotICAgKiBAdGhyb3dzIENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgT2JqZWN0IGNsb25lKCkgdGhyb3dzIENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uCi0gIHsKLSAgICAvLyBEbyBub3QgYWNjZXNzIHRoZSBsb2NhdGlvbiBwYXRoIGl0dGVyYXRvciBkdXJpbmcgdGhpcyBvcGVyYXRpb24hCi0KLSAgICBBeGVzV2Fsa2VyIGNsb25lID0gKEF4ZXNXYWxrZXIpIHN1cGVyLmNsb25lKCk7Ci0KLSAgICAvL2Nsb25lLnNldEN1cnJlbnROb2RlKGNsb25lLm1fcm9vdCk7Ci0KLSAgICAvLyBjbG9uZS5tX2lzRnJlc2ggPSB0cnVlOwotCi0gICAgcmV0dXJuIGNsb25lOwotICB9Ci0KLSAgLyoqCi0gICAqIERvIGEgZGVlcCBjbG9uZSBvZiB0aGlzIHdhbGtlciwgaW5jbHVkaW5nIG5leHQgYW5kIHByZXZpb3VzIHdhbGtlcnMuCi0gICAqIElmIHRoZSB0aGlzIEF4ZXNXYWxrZXIgaXMgb24gdGhlIGNsb25lIGxpc3QsIGRvbid0IGNsb25lIGJ1dAotICAgKiByZXR1cm4gdGhlIGFscmVhZHkgY2xvbmVkIHZlcnNpb24uCi0gICAqCi0gICAqIEBwYXJhbSBjbG9uZU93bmVyIG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgY2xvbmVkIGxvY2F0aW9uIHBhdGgKLSAgICogICAgICAgICAgICAgICAgICAgaXRlcmF0b3IgdG8gd2hpY2ggdGhpcyBjbG9uZSB3aWxsIGJlIGFkZGVkLgotICAgKiBAcGFyYW0gY2xvbmVMaXN0IG5vbi1udWxsIHZlY3RvciBvZiBzb3VyY2VzIGluIG9kZCBlbGVtZW50cywgYW5kIHRoZQotICAgKiAgICAgICAgICAgICAgICAgIGNvcnJlc3BvbmRpbmcgY2xvbmVzIGluIGV2ZW4gdmVjdG9ycy4KLSAgICoKLSAgICogQHJldHVybiBub24tbnVsbCBjbG9uZSwgd2hpY2ggbWF5IGJlIGEgbmV3IGNsb25lLCBvciBtYXkgYmUgYSBjbG9uZQotICAgKiAgICAgICAgIGNvbnRhaW5lZCBvbiB0aGUgY2xvbmVMaXN0LgotICAgKi8KLSAgQXhlc1dhbGtlciBjbG9uZURlZXAoV2Fsa2luZ0l0ZXJhdG9yIGNsb25lT3duZXIsIFZlY3RvciBjbG9uZUxpc3QpCi0gICAgIHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbgotICB7Ci0gICAgQXhlc1dhbGtlciBjbG9uZSA9IGZpbmRDbG9uZSh0aGlzLCBjbG9uZUxpc3QpOwotICAgIGlmKG51bGwgIT0gY2xvbmUpCi0gICAgICByZXR1cm4gY2xvbmU7Ci0gICAgY2xvbmUgPSAoQXhlc1dhbGtlcil0aGlzLmNsb25lKCk7Ci0gICAgY2xvbmUuc2V0TG9jUGF0aEl0ZXJhdG9yKGNsb25lT3duZXIpOwotICAgIGlmKG51bGwgIT0gY2xvbmVMaXN0KQotICAgIHsKLSAgICAgIGNsb25lTGlzdC5hZGRFbGVtZW50KHRoaXMpOwotICAgICAgY2xvbmVMaXN0LmFkZEVsZW1lbnQoY2xvbmUpOwotICAgIH0KLQotICAgIGlmKHdpKCkubV9sYXN0VXNlZFdhbGtlciA9PSB0aGlzKQotICAgICAgY2xvbmVPd25lci5tX2xhc3RVc2VkV2Fsa2VyID0gY2xvbmU7Ci0KLSAgICBpZihudWxsICE9IG1fbmV4dFdhbGtlcikKLSAgICAgIGNsb25lLm1fbmV4dFdhbGtlciA9IG1fbmV4dFdhbGtlci5jbG9uZURlZXAoY2xvbmVPd25lciwgY2xvbmVMaXN0KTsKLQotICAgIC8vIElmIHlvdSBkb24ndCBjaGVjayBmb3IgdGhlIGNsb25lTGlzdCBoZXJlLCB5b3UnbGwgZ28gaW50byBhbgotICAgIC8vIHJlY3Vyc2l2ZSBpbmZpbmF0ZSBsb29wLgotICAgIGlmKG51bGwgIT0gY2xvbmVMaXN0KQotICAgIHsKLSAgICAgIGlmKG51bGwgIT0gbV9wcmV2V2Fsa2VyKQotICAgICAgICBjbG9uZS5tX3ByZXZXYWxrZXIgPSBtX3ByZXZXYWxrZXIuY2xvbmVEZWVwKGNsb25lT3duZXIsIGNsb25lTGlzdCk7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBpZihudWxsICE9IG1fbmV4dFdhbGtlcikKLSAgICAgICAgY2xvbmUubV9uZXh0V2Fsa2VyLm1fcHJldldhbGtlciA9IGNsb25lOwotICAgIH0KLSAgICByZXR1cm4gY2xvbmU7Ci0gIH0KLQotICAvKioKLSAgICogRmluZCBhIGNsb25lIHRoYXQgY29ycmVzcG9uZHMgdG8gdGhlIGtleSBhcmd1bWVudC4KLSAgICoKLSAgICogQHBhcmFtIGtleSBUaGUgb3JpZ2luYWwgQXhlc1dhbGtlciBmb3Igd2hpY2ggdGhlcmUgbWF5IGJlIGEgY2xvbmUuCi0gICAqIEBwYXJhbSBjbG9uZUxpc3QgdmVjdG9yIG9mIHNvdXJjZXMgaW4gb2RkIGVsZW1lbnRzLCBhbmQgdGhlCi0gICAqICAgICAgICAgICAgICAgICAgY29ycmVzcG9uZGluZyBjbG9uZXMgaW4gZXZlbiB2ZWN0b3JzLCBtYXkgYmUgbnVsbC4KLSAgICoKLSAgICogQHJldHVybiBBIGNsb25lIHRoYXQgY29ycmVzcG9uZHMgdG8gdGhlIGtleSwgb3IgbnVsbCBpZiBrZXkgbm90IGZvdW5kLgotICAgKi8KLSAgc3RhdGljIEF4ZXNXYWxrZXIgZmluZENsb25lKEF4ZXNXYWxrZXIga2V5LCBWZWN0b3IgY2xvbmVMaXN0KQotICB7Ci0gICAgaWYobnVsbCAhPSBjbG9uZUxpc3QpCi0gICAgewotICAgICAgLy8gRmlyc3QsIGxvb2sgZm9yIGNsb25lIG9uIGxpc3QuCi0gICAgICBpbnQgbiA9IGNsb25lTGlzdC5zaXplKCk7Ci0gICAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrPTIpCi0gICAgICB7Ci0gICAgICAgIGlmKGtleSA9PSBjbG9uZUxpc3QuZWxlbWVudEF0KGkpKQotICAgICAgICAgIHJldHVybiAoQXhlc1dhbGtlciljbG9uZUxpc3QuZWxlbWVudEF0KGkrMSk7Ci0gICAgICB9Ci0gICAgfQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIERldGFjaGVzIHRoZSB3YWxrZXIgZnJvbSB0aGUgc2V0IHdoaWNoIGl0IGl0ZXJhdGVkIG92ZXIsIHJlbGVhc2luZwotICAgKiBhbnkgY29tcHV0YXRpb25hbCByZXNvdXJjZXMgYW5kIHBsYWNpbmcgdGhlIGl0ZXJhdG9yIGluIHRoZSBJTlZBTElECi0gICAqIHN0YXRlLgotICAgKi8KLSAgcHVibGljIHZvaWQgZGV0YWNoKCkKLSAgewotICAgICAgICBtX2N1cnJlbnROb2RlID0gRFRNLk5VTEw7Ci0gICAgICAgIG1fZHRtID0gbnVsbDsKLSAgICAgICAgbV90cmF2ZXJzZXIgPSBudWxsOwotICAgICAgICBtX2lzRnJlc2ggPSB0cnVlOwotICAgICAgICBtX3Jvb3QgPSBEVE0uTlVMTDsKLSAgfQotCi0gIC8vPT09PT09PT09PT09PT09IFRyZWVXYWxrZXIgSW1wbGVtZW50YXRpb24gPT09PT09PT09PT09PT09Ci0KLSAgLyoqCi0gICAqIFRoZSByb290IG5vZGUgb2YgdGhlIFRyZWVXYWxrZXIsIGFzIHNwZWNpZmllZCBpbiBzZXRSb290KGludCByb290KS4KLSAgICogTm90ZSB0aGF0IHRoaXMgbWF5IGFjdHVhbGx5IGJlIGJlbG93IHRoZSBjdXJyZW50IG5vZGUuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGNvbnRleHQgbm9kZSBvZiB0aGUgc3RlcC4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0Um9vdCgpCi0gIHsKLSAgICByZXR1cm4gbV9yb290OwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgYW5hbHlzaXMgYml0cyBmb3IgdGhpcyB3YWxrZXIsIGFzIGRlZmluZWQgaW4gdGhlIFdhbGtlckZhY3RvcnkuCi0gICAqIEByZXR1cm4gT25lIG9mIFdhbGtlckZhY3RvcnkjQklUX0RFU0NFTkRBTlQsIGV0Yy4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0QW5hbHlzaXNCaXRzKCkKLSAgewotICAgICAgICBpbnQgYXhpcyA9IGdldEF4aXMoKTsKLSAgICAgICAgaW50IGJpdCA9IFdhbGtlckZhY3RvcnkuZ2V0QW5hbHlzaXNCaXRGcm9tQXhlcyhheGlzKTsKLSAgICAgICAgcmV0dXJuIGJpdDsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIHJvb3Qgbm9kZSBvZiB0aGUgVHJlZVdhbGtlci4KLSAgICogKE5vdCBwYXJ0IG9mIHRoZSBET00yIFRyZWVXYWxrZXIgaW50ZXJmYWNlKS4KLSAgICoKLSAgICogQHBhcmFtIHJvb3QgVGhlIGNvbnRleHQgbm9kZSBvZiB0aGlzIHN0ZXAuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRSb290KGludCByb290KQotICB7Ci0gICAgLy8gJU9QVCUgR2V0IHRoaXMgZGlyZWN0bHkgZnJvbSB0aGUgbHBpLgotICAgIFhQYXRoQ29udGV4dCB4Y3R4dCA9IHdpKCkuZ2V0WFBhdGhDb250ZXh0KCk7Ci0gICAgbV9kdG0gPSB4Y3R4dC5nZXREVE0ocm9vdCk7Ci0gICAgbV90cmF2ZXJzZXIgPSBtX2R0bS5nZXRBeGlzVHJhdmVyc2VyKG1fYXhpcyk7Ci0gICAgbV9pc0ZyZXNoID0gdHJ1ZTsKLSAgICBtX2ZvdW5kTGFzdCA9IGZhbHNlOwotICAgIG1fcm9vdCA9IHJvb3Q7Ci0gICAgbV9jdXJyZW50Tm9kZSA9IHJvb3Q7Ci0KLSAgICBpZiAoRFRNLk5VTEwgPT0gcm9vdCkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKLSAgICAgICAgWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfU0VUVElOR19XQUxLRVJfUk9PVF9UT19OVUxMLCBudWxsKSk7IC8vIlxuICEhISEgRXJyb3IhIFNldHRpbmcgdGhlIHJvb3Qgb2YgYSB3YWxrZXIgdG8gbnVsbCEhISIpOwotICAgIH0KLQotICAgIHJlc2V0UHJveGltaXR5UG9zaXRpb25zKCk7Ci0gIH0KLQotICAvKioKLSAgICogVGhlIG5vZGUgYXQgd2hpY2ggdGhlIFRyZWVXYWxrZXIgaXMgY3VycmVudGx5IHBvc2l0aW9uZWQuCi0gICAqIDxicj4gVGhlIHZhbHVlIG11c3Qgbm90IGJlIG51bGwuIEFsdGVyYXRpb25zIHRvIHRoZSBET00gdHJlZSBtYXkgY2F1c2UKLSAgICogdGhlIGN1cnJlbnQgbm9kZSB0byBubyBsb25nZXIgYmUgYWNjZXB0ZWQgYnkgdGhlIFRyZWVXYWxrZXIncwotICAgKiBhc3NvY2lhdGVkIGZpbHRlci4gY3VycmVudE5vZGUgbWF5IGFsc28gYmUgZXhwbGljaXRseSBzZXQgdG8gYW55IG5vZGUsCi0gICAqIHdoZXRoZXIgb3Igbm90IGl0IGlzIHdpdGhpbiB0aGUgc3VidHJlZSBzcGVjaWZpZWQgYnkgdGhlIHJvb3Qgbm9kZSBvcgotICAgKiB3b3VsZCBiZSBhY2NlcHRlZCBieSB0aGUgZmlsdGVyIGFuZCB3aGF0VG9TaG93IGZsYWdzLiBGdXJ0aGVyCi0gICAqIHRyYXZlcnNhbCBvY2N1cnMgcmVsYXRpdmUgdG8gY3VycmVudE5vZGUgZXZlbiBpZiBpdCBpcyBub3QgcGFydCBvZiB0aGUKLSAgICogY3VycmVudCB2aWV3IGJ5IGFwcGx5aW5nIHRoZSBmaWx0ZXJzIGluIHRoZSByZXF1ZXN0ZWQgZGlyZWN0aW9uIChub3QKLSAgICogY2hhbmdpbmcgY3VycmVudE5vZGUgd2hlcmUgbm8gdHJhdmVyc2FsIGlzIHBvc3NpYmxlKS4KLSAgICoKLSAgICogQHJldHVybiBUaGUgbm9kZSBhdCB3aGljaCB0aGUgVHJlZVdhbGtlciBpcyBjdXJyZW50bHkgcG9zaXRpb25lZCwgb25seSBudWxsCi0gICAqIGlmIHNldFJvb3QgaGFzIG5vdCB5ZXQgYmVlbiBjYWxsZWQuCi0gICAqLwotICBwdWJsaWMgZmluYWwgaW50IGdldEN1cnJlbnROb2RlKCkKLSAgewotICAgIHJldHVybiBtX2N1cnJlbnROb2RlOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgbmV4dCB3YWxrZXIgaW4gdGhlIGxvY2F0aW9uIHN0ZXAgY2hhaW4uCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSB3YWxrZXIgUmVmZXJlbmNlIHRvIEF4ZXNXYWxrZXIgZGVyaXZhdGl2ZSwgb3IgbWF5IGJlIG51bGwuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXROZXh0V2Fsa2VyKEF4ZXNXYWxrZXIgd2Fsa2VyKQotICB7Ci0gICAgbV9uZXh0V2Fsa2VyID0gd2Fsa2VyOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbmV4dCB3YWxrZXIgaW4gdGhlIGxvY2F0aW9uIHN0ZXAgY2hhaW4uCi0gICAqCi0gICAqCi0gICAqIEByZXR1cm4gUmVmZXJlbmNlIHRvIEF4ZXNXYWxrZXIgZGVyaXZhdGl2ZSwgb3IgbnVsbC4KLSAgICovCi0gIHB1YmxpYyBBeGVzV2Fsa2VyIGdldE5leHRXYWxrZXIoKQotICB7Ci0gICAgcmV0dXJuIG1fbmV4dFdhbGtlcjsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgb3IgY2xlYXIgdGhlIHByZXZpb3VzIHdhbGtlciByZWZlcmVuY2UgaW4gdGhlIGxvY2F0aW9uIHN0ZXAgY2hhaW4uCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSB3YWxrZXIgUmVmZXJlbmNlIHRvIHByZXZpb3VzIHdhbGtlciByZWZlcmVuY2UgaW4gdGhlIGxvY2F0aW9uCi0gICAqICAgICAgICAgICAgICAgc3RlcCBjaGFpbiwgb3IgbnVsbC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFByZXZXYWxrZXIoQXhlc1dhbGtlciB3YWxrZXIpCi0gIHsKLSAgICBtX3ByZXZXYWxrZXIgPSB3YWxrZXI7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBwcmV2aW91cyB3YWxrZXIgcmVmZXJlbmNlIGluIHRoZSBsb2NhdGlvbiBzdGVwIGNoYWluLgotICAgKgotICAgKgotICAgKiBAcmV0dXJuIFJlZmVyZW5jZSB0byBwcmV2aW91cyB3YWxrZXIgcmVmZXJlbmNlIGluIHRoZSBsb2NhdGlvbgotICAgKiAgICAgICAgICAgICAgIHN0ZXAgY2hhaW4sIG9yIG51bGwuCi0gICAqLwotICBwdWJsaWMgQXhlc1dhbGtlciBnZXRQcmV2V2Fsa2VyKCkKLSAgewotICAgIHJldHVybiBtX3ByZXZXYWxrZXI7Ci0gIH0KLQotICAvKioKLSAgICogVGhpcyBpcyBzaW1wbHkgYSB3YXkgdG8gYm90dGxlLW5lY2sgdGhlIHJldHVybiBvZiB0aGUgbmV4dCBub2RlLCBmb3IKLSAgICogZGlhZ25vc3RpYyBwdXJwb3Nlcy4KLSAgICoKLSAgICogQHBhcmFtIG4gTm9kZSB0byByZXR1cm4sIG9yIG51bGwuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGFyZ3VtZW50LgotICAgKi8KLSAgcHJpdmF0ZSBpbnQgcmV0dXJuTmV4dE5vZGUoaW50IG4pCi0gIHsKLQotICAgIHJldHVybiBuOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbmV4dCBub2RlIGluIGRvY3VtZW50IG9yZGVyIG9uIHRoZSBheGVzLgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBuZXh0IG5vZGUgaW4gZG9jdW1lbnQgb3JkZXIgb24gdGhlIGF4ZXMsIG9yIG51bGwuCi0gICAqLwotICBwcm90ZWN0ZWQgaW50IGdldE5leHROb2RlKCkKLSAgewotICAgIGlmIChtX2ZvdW5kTGFzdCkKLSAgICAgIHJldHVybiBEVE0uTlVMTDsKLQotICAgIGlmIChtX2lzRnJlc2gpCi0gICAgewotICAgICAgbV9jdXJyZW50Tm9kZSA9IG1fdHJhdmVyc2VyLmZpcnN0KG1fcm9vdCk7Ci0gICAgICBtX2lzRnJlc2ggPSBmYWxzZTsKLSAgICB9Ci0gICAgLy8gSSBzaG91bGRuJ3QgaGF2ZSB0byBkbyB0aGlzIHRoZSBjaGVjayBmb3IgY3VycmVudCBub2RlLCBJIHRoaW5rLgotICAgIC8vIG51bWJlcmluZ1xudW1iZXJpbmcyNC54c2wgZmFpbHMgaWYgSSBkb24ndCBkbyB0aGlzLiAgSSB0aGluawotICAgIC8vIGl0IG9jY3VycyBhcyB0aGUgd2Fsa2VycyBhcmUgYmFja2luZyB1cC4gLXNiCi0gICAgZWxzZSBpZihEVE0uTlVMTCAhPSBtX2N1cnJlbnROb2RlKQotICAgIHsKLSAgICAgIG1fY3VycmVudE5vZGUgPSBtX3RyYXZlcnNlci5uZXh0KG1fcm9vdCwgbV9jdXJyZW50Tm9kZSk7Ci0gICAgfQotCi0gICAgaWYgKERUTS5OVUxMID09IG1fY3VycmVudE5vZGUpCi0gICAgICB0aGlzLm1fZm91bmRMYXN0ID0gdHJ1ZTsKLQotICAgIHJldHVybiBtX2N1cnJlbnROb2RlOwotICB9Ci0KLSAgLyoqCi0gICAqICBNb3ZlcyB0aGUgPGNvZGU+VHJlZVdhbGtlcjwvY29kZT4gdG8gdGhlIG5leHQgdmlzaWJsZSBub2RlIGluIGRvY3VtZW50Ci0gICAqIG9yZGVyIHJlbGF0aXZlIHRvIHRoZSBjdXJyZW50IG5vZGUsIGFuZCByZXR1cm5zIHRoZSBuZXcgbm9kZS4gSWYgdGhlCi0gICAqIGN1cnJlbnQgbm9kZSBoYXMgbm8gbmV4dCBub2RlLCAgb3IgaWYgdGhlIHNlYXJjaCBmb3IgbmV4dE5vZGUgYXR0ZW1wdHMKLSAgICogdG8gc3RlcCB1cHdhcmQgZnJvbSB0aGUgVHJlZVdhbGtlcidzIHJvb3Qgbm9kZSwgcmV0dXJucwotICAgKiA8Y29kZT5udWxsPC9jb2RlPiAsIGFuZCByZXRhaW5zIHRoZSBjdXJyZW50IG5vZGUuCi0gICAqIEByZXR1cm4gIFRoZSBuZXcgbm9kZSwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlIGN1cnJlbnQgbm9kZSBoYXMgbm8KLSAgICogICBuZXh0IG5vZGUgIGluIHRoZSBUcmVlV2Fsa2VyJ3MgbG9naWNhbCB2aWV3LgotICAgKi8KLSAgcHVibGljIGludCBuZXh0Tm9kZSgpCi0gIHsKLSAgICBpbnQgbmV4dE5vZGUgPSBEVE0uTlVMTDsKLSAgICBBeGVzV2Fsa2VyIHdhbGtlciA9IHdpKCkuZ2V0TGFzdFVzZWRXYWxrZXIoKTsKLQotICAgIHdoaWxlICh0cnVlKQotICAgIHsKLSAgICAgIGlmIChudWxsID09IHdhbGtlcikKLSAgICAgICAgYnJlYWs7Ci0KLSAgICAgIG5leHROb2RlID0gd2Fsa2VyLmdldE5leHROb2RlKCk7Ci0KLSAgICAgIGlmIChEVE0uTlVMTCA9PSBuZXh0Tm9kZSkKLSAgICAgIHsKLQotICAgICAgICB3YWxrZXIgPSB3YWxrZXIubV9wcmV2V2Fsa2VyOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBpZiAod2Fsa2VyLmFjY2VwdE5vZGUobmV4dE5vZGUpICE9IERUTUl0ZXJhdG9yLkZJTFRFUl9BQ0NFUFQpCi0gICAgICAgIHsKLSAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChudWxsID09IHdhbGtlci5tX25leHRXYWxrZXIpCi0gICAgICAgIHsKLSAgICAgICAgICB3aSgpLnNldExhc3RVc2VkV2Fsa2VyKHdhbGtlcik7Ci0KLSAgICAgICAgICAvLyByZXR1cm4gd2Fsa2VyLnJldHVybk5leHROb2RlKG5leHROb2RlKTsKLSAgICAgICAgICBicmVhazsKLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgIHsKLSAgICAgICAgICBBeGVzV2Fsa2VyIHByZXYgPSB3YWxrZXI7Ci0KLSAgICAgICAgICB3YWxrZXIgPSB3YWxrZXIubV9uZXh0V2Fsa2VyOwotCi0gICAgICAgICAgd2Fsa2VyLnNldFJvb3QobmV4dE5vZGUpOwotCi0gICAgICAgICAgd2Fsa2VyLm1fcHJldldhbGtlciA9IHByZXY7Ci0KLSAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgfQotICAgICAgfSAgLy8gaWYobnVsbCAhPSBuZXh0Tm9kZSkKLSAgICB9ICAvLyB3aGlsZShudWxsICE9IHdhbGtlcikKLQotICAgIHJldHVybiBuZXh0Tm9kZTsKLSAgfQotCi0gIC8vPT09PT09PT09PT09PSBFbmQgVHJlZVdhbGtlciBJbXBsZW1lbnRhdGlvbiA9PT09PT09PT09PT09Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgaW5kZXggb2YgdGhlIGxhc3Qgbm9kZSB0aGF0IGNhbiBiZSBpdHRlcmF0ZWQgdG8uCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBYUGF0aCBydW50aW1lIGNvbnRleHQuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIGluZGV4IG9mIHRoZSBsYXN0IG5vZGUgdGhhdCBjYW4gYmUgaXR0ZXJhdGVkIHRvLgotICAgKi8KLSAgcHVibGljIGludCBnZXRMYXN0UG9zKFhQYXRoQ29udGV4dCB4Y3R4dCkKLSAgewotCi0gICAgaW50IHBvcyA9IGdldFByb3hpbWl0eVBvc2l0aW9uKCk7Ci0KLSAgICBBeGVzV2Fsa2VyIHdhbGtlcjsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIHdhbGtlciA9IChBeGVzV2Fsa2VyKSBjbG9uZSgpOwotICAgIH0KLSAgICBjYXRjaCAoQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gY25zZSkKLSAgICB7Ci0gICAgICByZXR1cm4gLTE7Ci0gICAgfQotCi0gICAgd2Fsa2VyLnNldFByZWRpY2F0ZUNvdW50KG1fcHJlZGljYXRlSW5kZXgpOwotICAgIHdhbGtlci5zZXROZXh0V2Fsa2VyKG51bGwpOwotICAgIHdhbGtlci5zZXRQcmV2V2Fsa2VyKG51bGwpOwotCi0gICAgV2Fsa2luZ0l0ZXJhdG9yIGxwaSA9IHdpKCk7Ci0gICAgQXhlc1dhbGtlciBzYXZlZFdhbGtlciA9IGxwaS5nZXRMYXN0VXNlZFdhbGtlcigpOwotCi0gICAgdHJ5Ci0gICAgewotICAgICAgbHBpLnNldExhc3RVc2VkV2Fsa2VyKHdhbGtlcik7Ci0KLSAgICAgIGludCBuZXh0OwotCi0gICAgICB3aGlsZSAoRFRNLk5VTEwgIT0gKG5leHQgPSB3YWxrZXIubmV4dE5vZGUoKSkpCi0gICAgICB7Ci0gICAgICAgIHBvcysrOwotICAgICAgfQotCi0gICAgICAvLyBUT0RPOiBTaG91bGQgcHJvYmFibHkgc2F2ZSB0aGlzIGluIHRoZSBpdGVyYXRvci4KLSAgICB9Ci0gICAgZmluYWxseQotICAgIHsKLSAgICAgIGxwaS5zZXRMYXN0VXNlZFdhbGtlcihzYXZlZFdhbGtlcik7Ci0gICAgfQotCi0gICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJwb3M6ICIrcG9zKTsKLSAgICByZXR1cm4gcG9zOwotICB9Ci0KLSAgLy89PT09PT09PT09PT09IFN0YXRlIERhdGEgPT09PT09PT09PT09PQotCi0gIC8qKgotICAgKiBUaGUgRFRNIGZvciB0aGUgcm9vdC4gIFRoaXMgY2FuIG5vdCBiZSB1c2VkLCBvciBtdXN0IGJlIGNoYW5nZWQsCi0gICAqIGZvciB0aGUgZmlsdGVyIHdhbGtlciwgb3IgYW55IHdhbGtlciB0aGF0IGNhbiBoYXZlIG5vZGVzCi0gICAqIGZyb20gbXVsdGlwbGUgZG9jdW1lbnRzLgotICAgKiBOZXZlciwgZXZlciwgYWNjZXNzIHRoaXMgdmFsdWUgd2l0aG91dCBnb2luZyB0aHJvdWdoIGdldERUTShpbnQgbm9kZSkuCi0gICAqLwotICBwcml2YXRlIERUTSBtX2R0bTsKLQotICAvKioKLSAgICogU2V0IHRoZSBEVE0gZm9yIHRoaXMgd2Fsa2VyLgotICAgKgotICAgKiBAcGFyYW0gZHRtIE5vbi1udWxsIHJlZmVyZW5jZSB0byBhIERUTS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldERlZmF1bHREVE0oRFRNIGR0bSkKLSAgewotICAgIG1fZHRtID0gZHRtOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgRFRNIGZvciB0aGlzIHdhbGtlci4KLSAgICoKLSAgICogQHJldHVybiBOb24tbnVsbCByZWZlcmVuY2UgdG8gYSBEVE0uCi0gICAqLwotICBwdWJsaWMgRFRNIGdldERUTShpbnQgbm9kZSkKLSAgewotICAgIC8vCi0gICAgcmV0dXJuIHdpKCkuZ2V0WFBhdGhDb250ZXh0KCkuZ2V0RFRNKG5vZGUpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdHJ1ZSBpZiBhbGwgdGhlIG5vZGVzIGluIHRoZSBpdGVyYXRpb24gd2VsbCBiZSByZXR1cm5lZCBpbiBkb2N1bWVudAotICAgKiBvcmRlci4KLSAgICogV2FybmluZzogVGhpcyBjYW4gb25seSBiZSBjYWxsZWQgYWZ0ZXIgc2V0Um9vdCBoYXMgYmVlbiBjYWxsZWQhCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBhcyBhIGRlZmF1bHQuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBpc0RvY09yZGVyZWQoKQotICB7Ci0gICAgcmV0dXJuIHRydWU7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgYXhpcyBiZWluZyBpdGVyYXRlZCwgaWYgaXQgaXMga25vd24uCi0gICAqCi0gICAqIEByZXR1cm4gQXhpcy5DSElMRCwgZXRjLiwgb3IgLTEgaWYgdGhlIGF4aXMgaXMgbm90IGtub3duIG9yIGlzIG9mIG11bHRpcGxlCi0gICAqIHR5cGVzLgotICAgKi8KLSAgcHVibGljIGludCBnZXRBeGlzKCkKLSAgewotICAgIHJldHVybiBtX2F4aXM7Ci0gIH0KLQotICAvKioKLSAgICogVGhpcyB3aWxsIHRyYXZlcnNlIHRoZSBoZWFyYXJjaHksIGNhbGxpbmcgdGhlIHZpc2l0b3IgZm9yCi0gICAqIGVhY2ggbWVtYmVyLiAgSWYgdGhlIGNhbGxlZCB2aXNpdG9yIG1ldGhvZCByZXR1cm5zCi0gICAqIGZhbHNlLCB0aGUgc3VidHJlZSBzaG91bGQgbm90IGJlIGNhbGxlZC4KLSAgICoKLSAgICogQHBhcmFtIG93bmVyIFRoZSBvd25lciBvZiB0aGUgdmlzaXRvciwgd2hlcmUgdGhhdCBwYXRoIG1heSBiZQotICAgKiAgICAgICAgICAgICAgcmV3cml0dGVuIGlmIG5lZWRlZC4KLSAgICogQHBhcmFtIHZpc2l0b3IgVGhlIHZpc2l0b3Igd2hvc2UgYXBwcm9wcmlhdGUgbWV0aG9kIHdpbGwgYmUgY2FsbGVkLgotICAgKi8KLSAgcHVibGljIHZvaWQgY2FsbFZpc2l0b3JzKEV4cHJlc3Npb25Pd25lciBvd25lciwgWFBhdGhWaXNpdG9yIHZpc2l0b3IpCi0gIHsKLSAgICAgICAgaWYodmlzaXRvci52aXNpdFN0ZXAob3duZXIsIHRoaXMpKQotICAgICAgICB7Ci0gICAgICAgICAgICAgICAgY2FsbFByZWRpY2F0ZVZpc2l0b3JzKHZpc2l0b3IpOwotICAgICAgICAgICAgICAgIGlmKG51bGwgIT0gbV9uZXh0V2Fsa2VyKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIG1fbmV4dFdhbGtlci5jYWxsVmlzaXRvcnModGhpcywgdmlzaXRvcik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICB9Ci0gIH0KLQotICAvKioKLSAgICogQHNlZSBFeHByZXNzaW9uT3duZXIjZ2V0RXhwcmVzc2lvbigpCi0gICAqLwotICBwdWJsaWMgRXhwcmVzc2lvbiBnZXRFeHByZXNzaW9uKCkKLSAgewotICAgIHJldHVybiBtX25leHRXYWxrZXI7Ci0gIH0KLQotICAvKioKLSAgICogQHNlZSBFeHByZXNzaW9uT3duZXIjc2V0RXhwcmVzc2lvbihFeHByZXNzaW9uKQotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0RXhwcmVzc2lvbihFeHByZXNzaW9uIGV4cCkKLSAgewotICAgICAgICBleHAuZXhwclNldFBhcmVudCh0aGlzKTsKLSAgICAgICAgbV9uZXh0V2Fsa2VyID0gKEF4ZXNXYWxrZXIpZXhwOwotICB9Ci0KLSAgICAvKioKLSAgICAgKiBAc2VlIEV4cHJlc3Npb24jZGVlcEVxdWFscyhFeHByZXNzaW9uKQotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGRlZXBFcXVhbHMoRXhwcmVzc2lvbiBleHByKQotICAgIHsKLSAgICAgIGlmICghc3VwZXIuZGVlcEVxdWFscyhleHByKSkKLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0KLSAgICAgIEF4ZXNXYWxrZXIgd2Fsa2VyID0gKEF4ZXNXYWxrZXIpZXhwcjsKLSAgICAgIGlmKHRoaXMubV9heGlzICE9IHdhbGtlci5tX2F4aXMpCi0gICAgICAgIHJldHVybiBmYWxzZTsKLQotICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotCi0gIC8qKgotICAgKiAgVGhlIHJvb3Qgbm9kZSBvZiB0aGUgVHJlZVdhbGtlciwgYXMgc3BlY2lmaWVkIHdoZW4gaXQgd2FzIGNyZWF0ZWQuCi0gICAqLwotICB0cmFuc2llbnQgaW50IG1fcm9vdCA9IERUTS5OVUxMOwotCi0gIC8qKgotICAgKiAgVGhlIG5vZGUgYXQgd2hpY2ggdGhlIFRyZWVXYWxrZXIgaXMgY3VycmVudGx5IHBvc2l0aW9uZWQuCi0gICAqLwotICBwcml2YXRlIHRyYW5zaWVudCBpbnQgbV9jdXJyZW50Tm9kZSA9IERUTS5OVUxMOwotCi0gIC8qKiBUcnVlIGlmIGFuIGl0dGVyYXRpb24gaGFzIG5vdCBiZWd1bi4gICovCi0gIHRyYW5zaWVudCBib29sZWFuIG1faXNGcmVzaDsKLQotICAvKiogVGhlIG5leHQgd2Fsa2VyIGluIHRoZSBsb2NhdGlvbiBzdGVwIGNoYWluLgotICAgKiAgQHNlcmlhbCAgKi8KLSAgcHJvdGVjdGVkIEF4ZXNXYWxrZXIgbV9uZXh0V2Fsa2VyOwotCi0gIC8qKiBUaGUgcHJldmlvdXMgd2Fsa2VyIGluIHRoZSBsb2NhdGlvbiBzdGVwIGNoYWluLCBvciBudWxsLgotICAgKiAgQHNlcmlhbCAgICovCi0gIEF4ZXNXYWxrZXIgbV9wcmV2V2Fsa2VyOwotCi0gIC8qKiBUaGUgdHJhdmVyc2FsIGF4aXMgZnJvbSB3aGVyZSB0aGUgbm9kZXMgd2lsbCBiZSBmaWx0ZXJlZC4gKi8KLSAgcHJvdGVjdGVkIGludCBtX2F4aXMgPSAtMTsKLQotICAvKiogVGhlIERUTSBpbm5lciB0cmF2ZXJzYWwgY2xhc3MsIHRoYXQgY29ycmVzcG9uZHMgdG8gdGhlIHN1cGVyIGF4aXMuICovCi0gIHByb3RlY3RlZCBEVE1BeGlzVHJhdmVyc2VyIG1fdHJhdmVyc2VyOwotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9heGVzL0Jhc2ljVGVzdEl0ZXJhdG9yLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2F4ZXMvQmFzaWNUZXN0SXRlcmF0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggY2JlYTZkYi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2F4ZXMvQmFzaWNUZXN0SXRlcmF0b3IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIyNyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBCYXNpY1Rlc3RJdGVyYXRvci5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE0IDE5OjQ1OjIwIGplZmZzdXR0b3IgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuYXhlczsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1GaWx0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNSXRlcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5QcmVmaXhSZXNvbHZlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuY29tcGlsZXIuQ29tcGlsZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmNvbXBpbGVyLk9wTWFwOwotCi0vKioKLSAqIEJhc2UgZm9yIGl0ZXJhdG9ycyB0aGF0IGhhbmRsZSBwcmVkaWNhdGVzLiAgRG9lcyB0aGUgYmFzaWMgbmV4dAotICogbm9kZSBsb2dpYywgc28gYWxsIHRoZSBkZXJpdmVkIGl0ZXJhdG9yIGhhcyB0byBkbyBpcyBnZXQgdGhlCi0gKiBuZXh0IG5vZGUuCi0gKi8KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBCYXNpY1Rlc3RJdGVyYXRvciBleHRlbmRzIExvY1BhdGhJdGVyYXRvcgotewotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAzNTA1Mzc4MDc5Mzc4MDk2NjIzTDsKLSAgLyoqCi0gICAqIENyZWF0ZSBhIExvY1BhdGhJdGVyYXRvciBvYmplY3QuCi0gICAqCi0gICAqIEBwYXJhbSBuc2NvbnRleHQgVGhlIG5hbWVzcGFjZSBjb250ZXh0IGZvciB0aGlzIGl0ZXJhdG9yLAotICAgKiBzaG91bGQgYmUgT0sgaWYgbnVsbC4KLSAgICovCi0gIHByb3RlY3RlZCBCYXNpY1Rlc3RJdGVyYXRvcigpCi0gIHsKLSAgfQotCi0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIExvY1BhdGhJdGVyYXRvciBvYmplY3QuCi0gICAqCi0gICAqIEBwYXJhbSBuc2NvbnRleHQgVGhlIG5hbWVzcGFjZSBjb250ZXh0IGZvciB0aGlzIGl0ZXJhdG9yLAotICAgKiBzaG91bGQgYmUgT0sgaWYgbnVsbC4KLSAgICovCi0gIHByb3RlY3RlZCBCYXNpY1Rlc3RJdGVyYXRvcihQcmVmaXhSZXNvbHZlciBuc2NvbnRleHQpCi0gIHsKLQotICAgIHN1cGVyKG5zY29udGV4dCk7Ci0gIH0KLQotICAvKioKLSAgICogQ3JlYXRlIGEgTG9jUGF0aEl0ZXJhdG9yIG9iamVjdCwgaW5jbHVkaW5nIGNyZWF0aW9uCi0gICAqIG9mIHN0ZXAgd2Fsa2VycyBmcm9tIHRoZSBvcGNvZGUgbGlzdCwgYW5kIGNhbGwgYmFjawotICAgKiBpbnRvIHRoZSBDb21waWxlciB0byBjcmVhdGUgcHJlZGljYXRlIGV4cHJlc3Npb25zLgotICAgKgotICAgKiBAcGFyYW0gY29tcGlsZXIgVGhlIENvbXBpbGVyIHdoaWNoIGlzIGNyZWF0aW5nCi0gICAqIHRoaXMgZXhwcmVzc2lvbi4KLSAgICogQHBhcmFtIG9wUG9zIFRoZSBwb3NpdGlvbiBvZiB0aGlzIGl0ZXJhdG9yIGluIHRoZQotICAgKiBvcGNvZGUgbGlzdCBmcm9tIHRoZSBjb21waWxlci4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwcm90ZWN0ZWQgQmFzaWNUZXN0SXRlcmF0b3IoQ29tcGlsZXIgY29tcGlsZXIsIGludCBvcFBvcywgaW50IGFuYWx5c2lzKQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICBzdXBlcihjb21waWxlciwgb3BQb3MsIGFuYWx5c2lzLCBmYWxzZSk7Ci0KLSAgICBpbnQgZmlyc3RTdGVwUG9zID0gT3BNYXAuZ2V0Rmlyc3RDaGlsZFBvcyhvcFBvcyk7Ci0gICAgaW50IHdoYXRUb1Nob3cgPSBjb21waWxlci5nZXRXaGF0VG9TaG93KGZpcnN0U3RlcFBvcyk7Ci0KLSAgICBpZiAoKDAgPT0gKHdoYXRUb1Nob3cKLSAgICAgICAgICAgICAgICYgKERUTUZpbHRlci5TSE9XX0FUVFJJQlVURQotICAgICAgICAgICAgICAgfCBEVE1GaWx0ZXIuU0hPV19OQU1FU1BBQ0UKLSAgICAgICAgICAgICAgIHwgRFRNRmlsdGVyLlNIT1dfRUxFTUVOVAotICAgICAgICAgICAgICAgfCBEVE1GaWx0ZXIuU0hPV19QUk9DRVNTSU5HX0lOU1RSVUNUSU9OKSkpCi0gICAgICAgICAgICAgICB8fCAod2hhdFRvU2hvdyA9PSBEVE1GaWx0ZXIuU0hPV19BTEwpKQotICAgICAgaW5pdE5vZGVUZXN0KHdoYXRUb1Nob3cpOwotICAgIGVsc2UKLSAgICB7Ci0gICAgICBpbml0Tm9kZVRlc3Qod2hhdFRvU2hvdywgY29tcGlsZXIuZ2V0U3RlcE5TKGZpcnN0U3RlcFBvcyksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21waWxlci5nZXRTdGVwTG9jYWxOYW1lKGZpcnN0U3RlcFBvcykpOwotICAgIH0KLSAgICBpbml0UHJlZGljYXRlSW5mbyhjb21waWxlciwgZmlyc3RTdGVwUG9zKTsKLSAgfQotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBMb2NQYXRoSXRlcmF0b3Igb2JqZWN0LCBpbmNsdWRpbmcgY3JlYXRpb24KLSAgICogb2Ygc3RlcCB3YWxrZXJzIGZyb20gdGhlIG9wY29kZSBsaXN0LCBhbmQgY2FsbCBiYWNrCi0gICAqIGludG8gdGhlIENvbXBpbGVyIHRvIGNyZWF0ZSBwcmVkaWNhdGUgZXhwcmVzc2lvbnMuCi0gICAqCi0gICAqIEBwYXJhbSBjb21waWxlciBUaGUgQ29tcGlsZXIgd2hpY2ggaXMgY3JlYXRpbmcKLSAgICogdGhpcyBleHByZXNzaW9uLgotICAgKiBAcGFyYW0gb3BQb3MgVGhlIHBvc2l0aW9uIG9mIHRoaXMgaXRlcmF0b3IgaW4gdGhlCi0gICAqIG9wY29kZSBsaXN0IGZyb20gdGhlIGNvbXBpbGVyLgotICAgKiBAcGFyYW0gc2hvdWxkTG9hZFdhbGtlcnMgVHJ1ZSBpZiB3YWxrZXJzIHNob3VsZCBiZQotICAgKiBsb2FkZWQsIG9yIGZhbHNlIGlmIHRoaXMgaXMgYSBkZXJpdmVkIGl0ZXJhdG9yIGFuZAotICAgKiBpdCBkb2Vzbid0IHdpc2ggdG8gbG9hZCBjaGlsZCB3YWxrZXJzLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHByb3RlY3RlZCBCYXNpY1Rlc3RJdGVyYXRvcigKLSAgICAgICAgICBDb21waWxlciBjb21waWxlciwgaW50IG9wUG9zLCBpbnQgYW5hbHlzaXMsIGJvb2xlYW4gc2hvdWxkTG9hZFdhbGtlcnMpCi0gICAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgc3VwZXIoY29tcGlsZXIsIG9wUG9zLCBhbmFseXNpcywgc2hvdWxkTG9hZFdhbGtlcnMpOwotICB9Ci0KLQotICAvKioKLSAgICogR2V0IHRoZSBuZXh0IG5vZGUgdmlhIGdldE5leHRYWFguICBCb3R0bGVuZWNrZWQgZm9yIGRlcml2ZWQgY2xhc3Mgb3ZlcnJpZGUuCi0gICAqIEByZXR1cm4gVGhlIG5leHQgbm9kZSBvbiB0aGUgYXhpcywgb3IgRFRNLk5VTEwuCi0gICAqLwotICBwcm90ZWN0ZWQgYWJzdHJhY3QgaW50IGdldE5leHROb2RlKCk7Ci0KLSAgLyoqCi0gICAqICBSZXR1cm5zIHRoZSBuZXh0IG5vZGUgaW4gdGhlIHNldCBhbmQgYWR2YW5jZXMgdGhlIHBvc2l0aW9uIG9mIHRoZQotICAgKiBpdGVyYXRvciBpbiB0aGUgc2V0LiBBZnRlciBhIE5vZGVJdGVyYXRvciBpcyBjcmVhdGVkLCB0aGUgZmlyc3QgY2FsbAotICAgKiB0byBuZXh0Tm9kZSgpIHJldHVybnMgdGhlIGZpcnN0IG5vZGUgaW4gdGhlIHNldC4KLSAgICoKLSAgICogQHJldHVybiAgVGhlIG5leHQgPGNvZGU+Tm9kZTwvY29kZT4gaW4gdGhlIHNldCBiZWluZyBpdGVyYXRlZCBvdmVyLCBvcgotICAgKiAgIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoZXJlIGFyZSBubyBtb3JlIG1lbWJlcnMgaW4gdGhhdCBzZXQuCi0gICAqLwotICBwdWJsaWMgaW50IG5leHROb2RlKCkKLSAgewotICAgICAgICBpZihtX2ZvdW5kTGFzdCkKLSAgICAgICAgewotICAgICAgICAgICAgICAgIG1fbGFzdEZldGNoZWQgPSBEVE0uTlVMTDsKLSAgICAgICAgICAgICAgICByZXR1cm4gRFRNLk5VTEw7Ci0gICAgICAgIH0KLQotICAgIGlmKERUTS5OVUxMID09IG1fbGFzdEZldGNoZWQpCi0gICAgewotICAgICAgcmVzZXRQcm94aW1pdHlQb3NpdGlvbnMoKTsKLSAgICB9Ci0KLSAgICBpbnQgbmV4dDsKLQotICAgIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5WYXJpYWJsZVN0YWNrIHZhcnM7Ci0gICAgaW50IHNhdmVkU3RhcnQ7Ci0gICAgaWYgKC0xICE9IG1fc3RhY2tGcmFtZSkKLSAgICB7Ci0gICAgICB2YXJzID0gbV9leGVjQ29udGV4dC5nZXRWYXJTdGFjaygpOwotCi0gICAgICAvLyBUaGVzZSB0aHJlZSBzdGF0ZW1lbnRzIG5lZWQgdG8gYmUgY29tYmluZWQgaW50byBvbmUgb3BlcmF0aW9uLgotICAgICAgc2F2ZWRTdGFydCA9IHZhcnMuZ2V0U3RhY2tGcmFtZSgpOwotCi0gICAgICB2YXJzLnNldFN0YWNrRnJhbWUobV9zdGFja0ZyYW1lKTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIC8vIFl1Y2suICBKdXN0IHRvIHNodXQgdXAgdGhlIGNvbXBpbGVyIQotICAgICAgdmFycyA9IG51bGw7Ci0gICAgICBzYXZlZFN0YXJ0ID0gMDsKLSAgICB9Ci0KLSAgICB0cnkKLSAgICB7Ci0gICAgICBkbwotICAgICAgewotICAgICAgICBuZXh0ID0gZ2V0TmV4dE5vZGUoKTsKLQotICAgICAgICBpZiAoRFRNLk5VTEwgIT0gbmV4dCkKLSAgICAgICAgewotICAgICAgICAgIGlmKERUTUl0ZXJhdG9yLkZJTFRFUl9BQ0NFUFQgPT0gYWNjZXB0Tm9kZShuZXh0KSkKLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICBicmVhazsKLSAgICAgIH0KLSAgICAgIHdoaWxlIChuZXh0ICE9IERUTS5OVUxMKTsKLQotICAgICAgaWYgKERUTS5OVUxMICE9IG5leHQpCi0gICAgICB7Ci0gICAgICAgIG1fcG9zKys7Ci0gICAgICAgIHJldHVybiBuZXh0OwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBtX2ZvdW5kTGFzdCA9IHRydWU7Ci0KLSAgICAgICAgcmV0dXJuIERUTS5OVUxMOwotICAgICAgfQotICAgIH0KLSAgICBmaW5hbGx5Ci0gICAgewotICAgICAgaWYgKC0xICE9IG1fc3RhY2tGcmFtZSkKLSAgICAgIHsKLSAgICAgICAgLy8gVGhlc2UgdHdvIHN0YXRlbWVudHMgbmVlZCB0byBiZSBjb21iaW5lZCBpbnRvIG9uZSBvcGVyYXRpb24uCi0gICAgICAgIHZhcnMuc2V0U3RhY2tGcmFtZShzYXZlZFN0YXJ0KTsKLSAgICAgIH0KLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogIEdldCBhIGNsb25lZCBJdGVyYXRvciB0aGF0IGlzIHJlc2V0IHRvIHRoZSBiZWdpbm5pbmcKLSAgICogIG9mIHRoZSBxdWVyeS4KLSAgICoKLSAgICogIEByZXR1cm4gQSBjbG9uZWQgTm9kZUl0ZXJhdG9yIHNldCBvZiB0aGUgc3RhcnQgb2YgdGhlIHF1ZXJ5LgotICAgKgotICAgKiAgQHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIERUTUl0ZXJhdG9yIGNsb25lV2l0aFJlc2V0KCkgdGhyb3dzIENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uCi0gIHsKLQotICAgIENoaWxkVGVzdEl0ZXJhdG9yIGNsb25lID0gKENoaWxkVGVzdEl0ZXJhdG9yKSBzdXBlci5jbG9uZVdpdGhSZXNldCgpOwotCi0gICAgY2xvbmUucmVzZXRQcm94aW1pdHlQb3NpdGlvbnMoKTsKLQotICAgIHJldHVybiBjbG9uZTsKLSAgfQotCi0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvYXhlcy9DaGlsZEl0ZXJhdG9yLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2F4ZXMvQ2hpbGRJdGVyYXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiZTUzMjAwLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvYXhlcy9DaGlsZEl0ZXJhdG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMjMgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogQ2hpbGRJdGVyYXRvci5qYXZhLHYgMS4yLjQuMiAyMDA1LzA5LzE0IDE5OjQ1OjIwIGplZmZzdXR0b3IgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuYXhlczsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1GaWx0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoQ29udGV4dDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuY29tcGlsZXIuQ29tcGlsZXI7Ci0KLS8qKgotICogVGhpcyBjbGFzcyBpbXBsZW1lbnRzIGFuIG9wdGltaXplZCBpdGVyYXRvciBmb3IKLSAqICJub2RlKCkiIHBhdHRlcm5zLCB0aGF0IGlzLCBhbnkgY2hpbGRyZW4gb2YgdGhlCi0gKiBjb250ZXh0IG5vZGUuCi0gKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5heGVzLkxvY1BhdGhJdGVyYXRvcgotICogQHhzbC51c2FnZSBhZHZhbmNlZAotICovCi1wdWJsaWMgY2xhc3MgQ2hpbGRJdGVyYXRvciBleHRlbmRzIExvY1BhdGhJdGVyYXRvcgotewotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNjkzNTQyODAxNTE0Mjk5MzU4M0w7Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIENoaWxkSXRlcmF0b3Igb2JqZWN0LgotICAgKgotICAgKiBAcGFyYW0gY29tcGlsZXIgQSByZWZlcmVuY2UgdG8gdGhlIENvbXBpbGVyIHRoYXQgY29udGFpbnMgdGhlIG9wIG1hcC4KLSAgICogQHBhcmFtIG9wUG9zIFRoZSBwb3NpdGlvbiB3aXRoaW4gdGhlIG9wIG1hcCwgd2hpY2ggY29udGFpbnMgdGhlCi0gICAqIGxvY2F0aW9uIHBhdGggZXhwcmVzc2lvbiBmb3IgdGhpcyBpdHRlcmF0b3IuCi0gICAqIEBwYXJhbSBhbmFseXNpcyBBbmFseXNpcyBiaXRzIG9mIHRoZSBlbnRpcmUgcGF0dGVybi4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBDaGlsZEl0ZXJhdG9yKENvbXBpbGVyIGNvbXBpbGVyLCBpbnQgb3BQb3MsIGludCBhbmFseXNpcykKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgc3VwZXIoY29tcGlsZXIsIG9wUG9zLCBhbmFseXNpcywgZmFsc2UpOwotCi0gICAgLy8gVGhpcyBpdGVyYXRvciBtYXRjaGVzIGFsbCBraW5kcyBvZiBub2RlcwotICAgIGluaXROb2RlVGVzdChEVE1GaWx0ZXIuU0hPV19BTEwpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgZmlyc3Qgbm9kZSBvdXQgb2YgdGhlIG5vZGVzZXQsIGlmIHRoaXMgZXhwcmVzc2lvbiBpcwotICAgKiBhIG5vZGVzZXQgZXhwcmVzc2lvbi4gIFRoaXMgaXMgdGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gZm9yCi0gICAqIG5vZGVzZXRzLgotICAgKiA8cD5XQVJOSU5HOiBEbyBub3QgbXV0YXRlIHRoaXMgY2xhc3MgZnJvbSB0aGlzIGZ1bmN0aW9uITwvcD4KLSAgICogQHBhcmFtIHhjdHh0IFRoZSBYUGF0aCBydW50aW1lIGNvbnRleHQuCi0gICAqIEByZXR1cm4gdGhlIGZpcnN0IG5vZGUgb3V0IG9mIHRoZSBub2Rlc2V0LCBvciBEVE0uTlVMTC4KLSAgICovCi0gIHB1YmxpYyBpbnQgYXNOb2RlKFhQYXRoQ29udGV4dCB4Y3R4dCkKLSAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgaW50IGN1cnJlbnQgPSB4Y3R4dC5nZXRDdXJyZW50Tm9kZSgpOwotCi0gICAgRFRNIGR0bSA9IHhjdHh0LmdldERUTShjdXJyZW50KTsKLQotICAgIHJldHVybiBkdG0uZ2V0Rmlyc3RDaGlsZChjdXJyZW50KTsKLSAgfQotCi0gIC8qKgotICAgKiAgUmV0dXJucyB0aGUgbmV4dCBub2RlIGluIHRoZSBzZXQgYW5kIGFkdmFuY2VzIHRoZSBwb3NpdGlvbiBvZiB0aGUKLSAgICogaXRlcmF0b3IgaW4gdGhlIHNldC4gQWZ0ZXIgYSBOb2RlSXRlcmF0b3IgaXMgY3JlYXRlZCwgdGhlIGZpcnN0IGNhbGwKLSAgICogdG8gbmV4dE5vZGUoKSByZXR1cm5zIHRoZSBmaXJzdCBub2RlIGluIHRoZSBzZXQuCi0gICAqCi0gICAqIEByZXR1cm4gIFRoZSBuZXh0IDxjb2RlPk5vZGU8L2NvZGU+IGluIHRoZSBzZXQgYmVpbmcgaXRlcmF0ZWQgb3Zlciwgb3IKLSAgICogICA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGVyZSBhcmUgbm8gbW9yZSBtZW1iZXJzIGluIHRoYXQgc2V0LgotICAgKi8KLSAgcHVibGljIGludCBuZXh0Tm9kZSgpCi0gIHsKLSAgICAgICAgaWYobV9mb3VuZExhc3QpCi0gICAgICAgICAgICAgICAgcmV0dXJuIERUTS5OVUxMOwotCi0gICAgaW50IG5leHQ7Ci0KLSAgICBtX2xhc3RGZXRjaGVkID0gbmV4dCA9IChEVE0uTlVMTCA9PSBtX2xhc3RGZXRjaGVkKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBtX2NkdG0uZ2V0Rmlyc3RDaGlsZChtX2NvbnRleHQpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICA6IG1fY2R0bS5nZXROZXh0U2libGluZyhtX2xhc3RGZXRjaGVkKTsKLQotICAgIC8vIG1fbGFzdEZldGNoZWQgPSBuZXh0OwotICAgIGlmIChEVE0uTlVMTCAhPSBuZXh0KQotICAgIHsKLSAgICAgIG1fcG9zKys7Ci0gICAgICByZXR1cm4gbmV4dDsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIG1fZm91bmRMYXN0ID0gdHJ1ZTsKLQotICAgICAgcmV0dXJuIERUTS5OVUxMOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBheGlzIGJlaW5nIGl0ZXJhdGVkLCBpZiBpdCBpcyBrbm93bi4KLSAgICoKLSAgICogQHJldHVybiBBeGlzLkNISUxELCBldGMuLCBvciAtMSBpZiB0aGUgYXhpcyBpcyBub3Qga25vd24gb3IgaXMgb2YgbXVsdGlwbGUKLSAgICogdHlwZXMuCi0gICAqLwotICBwdWJsaWMgaW50IGdldEF4aXMoKQotICB7Ci0gICAgcmV0dXJuIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkF4aXMuQ0hJTEQ7Ci0gIH0KLQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2F4ZXMvQ2hpbGRUZXN0SXRlcmF0b3IuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvYXhlcy9DaGlsZFRlc3RJdGVyYXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlYmJmOWI2Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvYXhlcy9DaGlsZFRlc3RJdGVyYXRvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTgwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IENoaWxkVGVzdEl0ZXJhdG9yLmphdmEsdiAxLjIuNC4yIDIwMDUvMDkvMTQgMTk6NDU6MjAgamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5heGVzOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uQXhpczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE07Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNQXhpc1RyYXZlcnNlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1JdGVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuY29tcGlsZXIuQ29tcGlsZXI7Ci0KLS8qKgotICogVGhpcyBjbGFzcyBpbXBsZW1lbnRzIGFuIG9wdGltaXplZCBpdGVyYXRvciBmb3IKLSAqIGNoaWxkcmVuIHBhdHRlcm5zIHRoYXQgaGF2ZSBhIG5vZGUgdGVzdCwgYW5kIHBvc3NpYmx5IGEgcHJlZGljYXRlLgotICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuYXhlcy5CYXNpY1Rlc3RJdGVyYXRvcgotICogQHhzbC51c2FnZSBhZHZhbmNlZAotICovCi1wdWJsaWMgY2xhc3MgQ2hpbGRUZXN0SXRlcmF0b3IgZXh0ZW5kcyBCYXNpY1Rlc3RJdGVyYXRvcgotewotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNzkzNjgzNTk1Nzk2MDcwNTcyMkw7Ci0gIC8qKiBUaGUgdHJhdmVyc2VyIHRvIHVzZSB0byBuYXZpZ2F0ZSBvdmVyIHRoZSBkZXNjZW5kYW50cy4gKi8KLSAgdHJhbnNpZW50IHByb3RlY3RlZCBEVE1BeGlzVHJhdmVyc2VyIG1fdHJhdmVyc2VyOwotCi0gIC8qKiBUaGUgZXh0ZW5kZWQgdHlwZSBJRCwgbm90IHNldCB1bnRpbCBzZXRSb290LiAqLwotLy8gIHByb3RlY3RlZCBpbnQgbV9leHRlbmRlZFR5cGVJRDsKLQotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBDaGlsZFRlc3RJdGVyYXRvciBvYmplY3QuCi0gICAqCi0gICAqIEBwYXJhbSBjb21waWxlciBBIHJlZmVyZW5jZSB0byB0aGUgQ29tcGlsZXIgdGhhdCBjb250YWlucyB0aGUgb3AgbWFwLgotICAgKiBAcGFyYW0gb3BQb3MgVGhlIHBvc2l0aW9uIHdpdGhpbiB0aGUgb3AgbWFwLCB3aGljaCBjb250YWlucyB0aGUKLSAgICogbG9jYXRpb24gcGF0aCBleHByZXNzaW9uIGZvciB0aGlzIGl0dGVyYXRvci4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBDaGlsZFRlc3RJdGVyYXRvcihDb21waWxlciBjb21waWxlciwgaW50IG9wUG9zLCBpbnQgYW5hbHlzaXMpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHN1cGVyKGNvbXBpbGVyLCBvcFBvcywgYW5hbHlzaXMpOwotICB9Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIENoaWxkVGVzdEl0ZXJhdG9yIG9iamVjdC4KLSAgICoKLSAgICogQHBhcmFtIHRyYXZlcnNlciBUcmF2ZXJzZXIgdGhhdCB0ZWxscyBob3cgdGhlIEtleUl0ZXJhdG9yIGlzIHRvIGJlIGhhbmRsZWQuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIENoaWxkVGVzdEl0ZXJhdG9yKERUTUF4aXNUcmF2ZXJzZXIgdHJhdmVyc2VyKQotICB7Ci0KLSAgICBzdXBlcihudWxsKTsKLQotICAgIG1fdHJhdmVyc2VyID0gdHJhdmVyc2VyOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbmV4dCBub2RlIHZpYSBnZXROZXh0WFhYLiAgQm90dGxlbmVja2VkIGZvciBkZXJpdmVkIGNsYXNzIG92ZXJyaWRlLgotICAgKiBAcmV0dXJuIFRoZSBuZXh0IG5vZGUgb24gdGhlIGF4aXMsIG9yIERUTS5OVUxMLgotICAgKi8KLSAgcHJvdGVjdGVkIGludCBnZXROZXh0Tm9kZSgpCi0gIHsKLSAgICBpZih0cnVlIC8qIDAgPT0gbV9leHRlbmRlZFR5cGVJRCAqLykKLSAgICB7Ci0gICAgICBtX2xhc3RGZXRjaGVkID0gKERUTS5OVUxMID09IG1fbGFzdEZldGNoZWQpCi0gICAgICAgICAgICAgICAgICAgPyBtX3RyYXZlcnNlci5maXJzdChtX2NvbnRleHQpCi0gICAgICAgICAgICAgICAgICAgOiBtX3RyYXZlcnNlci5uZXh0KG1fY29udGV4dCwgbV9sYXN0RmV0Y2hlZCk7Ci0gICAgfQotLy8gICAgZWxzZQotLy8gICAgewotLy8gICAgICBtX2xhc3RGZXRjaGVkID0gKERUTS5OVUxMID09IG1fbGFzdEZldGNoZWQpCi0vLyAgICAgICAgICAgICAgICAgICA/IG1fdHJhdmVyc2VyLmZpcnN0KG1fY29udGV4dCwgbV9leHRlbmRlZFR5cGVJRCkKLS8vICAgICAgICAgICAgICAgICAgIDogbV90cmF2ZXJzZXIubmV4dChtX2NvbnRleHQsIG1fbGFzdEZldGNoZWQsCi0vLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbV9leHRlbmRlZFR5cGVJRCk7Ci0vLyAgICB9Ci0KLSAgICByZXR1cm4gbV9sYXN0RmV0Y2hlZDsKLSAgfQotCi0KLSAgLyoqCi0gICAqICBHZXQgYSBjbG9uZWQgSXRlcmF0b3IgdGhhdCBpcyByZXNldCB0byB0aGUgYmVnaW5uaW5nCi0gICAqICBvZiB0aGUgcXVlcnkuCi0gICAqCi0gICAqICBAcmV0dXJuIEEgY2xvbmVkIE5vZGVJdGVyYXRvciBzZXQgb2YgdGhlIHN0YXJ0IG9mIHRoZSBxdWVyeS4KLSAgICoKLSAgICogIEB0aHJvd3MgQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBEVE1JdGVyYXRvciBjbG9uZVdpdGhSZXNldCgpIHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbgotICB7Ci0KLSAgICBDaGlsZFRlc3RJdGVyYXRvciBjbG9uZSA9IChDaGlsZFRlc3RJdGVyYXRvcikgc3VwZXIuY2xvbmVXaXRoUmVzZXQoKTsKLSAgICBjbG9uZS5tX3RyYXZlcnNlciA9IG1fdHJhdmVyc2VyOwotCi0gICAgcmV0dXJuIGNsb25lOwotICB9Ci0KLQotICAvKioKLSAgICogSW5pdGlhbGl6ZSB0aGUgY29udGV4dCB2YWx1ZXMgZm9yIHRoaXMgZXhwcmVzc2lvbgotICAgKiBhZnRlciBpdCBpcyBjbG9uZWQuCi0gICAqCi0gICAqIEBwYXJhbSBjb250ZXh0IFRoZSBYUGF0aCBydW50aW1lIGNvbnRleHQgZm9yIHRoaXMKLSAgICogdHJhbnNmb3JtYXRpb24uCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRSb290KGludCBjb250ZXh0LCBPYmplY3QgZW52aXJvbm1lbnQpCi0gIHsKLSAgICBzdXBlci5zZXRSb290KGNvbnRleHQsIGVudmlyb25tZW50KTsKLSAgICBtX3RyYXZlcnNlciA9IG1fY2R0bS5nZXRBeGlzVHJhdmVyc2VyKEF4aXMuQ0hJTEQpOwotCi0vLyAgICBTdHJpbmcgbG9jYWxOYW1lID0gZ2V0TG9jYWxOYW1lKCk7Ci0vLyAgICBTdHJpbmcgbmFtZXNwYWNlID0gZ2V0TmFtZXNwYWNlKCk7Ci0vLyAgICBpbnQgd2hhdCA9IG1fd2hhdFRvU2hvdzsKLS8vICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigid2hhdDogIik7Ci0vLyAgICAvLyBOb2RlVGVzdC5kZWJ1Z1doYXRUb1Nob3cod2hhdCk7Ci0vLyAgICBpZihEVE1GaWx0ZXIuU0hPV19BTEwgPT0gd2hhdCB8fAotLy8gICAgICAgKChEVE1GaWx0ZXIuU0hPV19FTEVNRU5UICYgd2hhdCkgPT0gMCkKLS8vICAgICAgIHx8IGxvY2FsTmFtZSA9PSBOb2RlVGVzdC5XSUxECi0vLyAgICAgICB8fCBuYW1lc3BhY2UgPT0gTm9kZVRlc3QuV0lMRCkKLS8vICAgIHsKLS8vICAgICAgbV9leHRlbmRlZFR5cGVJRCA9IDA7Ci0vLyAgICB9Ci0vLyAgICBlbHNlCi0vLyAgICB7Ci0vLyAgICAgIGludCB0eXBlID0gZ2V0Tm9kZVR5cGVUZXN0KHdoYXQpOwotLy8gICAgICBtX2V4dGVuZGVkVHlwZUlEID0gbV9jZHRtLmdldEV4cGFuZGVkVHlwZUlEKG5hbWVzcGFjZSwgbG9jYWxOYW1lLCB0eXBlKTsKLS8vICAgIH0KLQotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIGF4aXMgYmVpbmcgaXRlcmF0ZWQsIGlmIGl0IGlzIGtub3duLgotICAgKgotICAgKiBAcmV0dXJuIEF4aXMuQ0hJTEQsIGV0Yy4sIG9yIC0xIGlmIHRoZSBheGlzIGlzIG5vdCBrbm93biBvciBpcyBvZiBtdWx0aXBsZQotICAgKiB0eXBlcy4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0QXhpcygpCi0gIHsKLSAgICByZXR1cm4gY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uQXhpcy5DSElMRDsKLSAgfQotCi0gIC8qKgotICAgKiAgRGV0YWNoZXMgdGhlIGl0ZXJhdG9yIGZyb20gdGhlIHNldCB3aGljaCBpdCBpdGVyYXRlZCBvdmVyLCByZWxlYXNpbmcKLSAgICogYW55IGNvbXB1dGF0aW9uYWwgcmVzb3VyY2VzIGFuZCBwbGFjaW5nIHRoZSBpdGVyYXRvciBpbiB0aGUgSU5WQUxJRAotICAgKiBzdGF0ZS4gQWZ0ZXI8Y29kZT5kZXRhY2g8L2NvZGU+IGhhcyBiZWVuIGludm9rZWQsIGNhbGxzIHRvCi0gICAqIDxjb2RlPm5leHROb2RlPC9jb2RlPiBvcjxjb2RlPnByZXZpb3VzTm9kZTwvY29kZT4gd2lsbCByYWlzZSB0aGUKLSAgICogZXhjZXB0aW9uIElOVkFMSURfU1RBVEVfRVJSLgotICAgKi8KLSAgcHVibGljIHZvaWQgZGV0YWNoKCkKLSAgewotICAgIGlmKG1fYWxsb3dEZXRhY2gpCi0gICAgewotICAgICAgbV90cmF2ZXJzZXIgPSBudWxsOwotCi0gICAgICAvLyBBbHdheXMgY2FsbCB0aGUgc3VwZXJjbGFzcyBkZXRhY2ggbGFzdCEKLSAgICAgIHN1cGVyLmRldGFjaCgpOwotICAgIH0KLSAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2F4ZXMvQ29udGV4dE5vZGVMaXN0LmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2F4ZXMvQ29udGV4dE5vZGVMaXN0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDBjNDkyNGMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9heGVzL0NvbnRleHROb2RlTGlzdC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTM4ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IENvbnRleHROb2RlTGlzdC5qYXZhLHYgMS4xLjIuMSAyMDA1LzA4LzAxIDAxOjMwOjIwIGplZmZzdXR0b3IgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuYXhlczsKLQotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci1pbXBvcnQgb3JnLnczYy5kb20udHJhdmVyc2FsLk5vZGVJdGVyYXRvcjsKLQotLyoqCi0gKiBDbGFzc2VzIHdobyBpbXBsZW1lbnQgdGhpcyBpbnRlcmZhY2UgY2FuIGJlIGEKLSAqIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjZHQtY3VycmVudC1ub2RlLWxpc3QiPmN1cnJlbnQgbm9kZSBsaXN0PC9hPiwKLSAqIGFsc28gcmVmZXJlZCB0byBoZXJlIGFzIGEgPHRlcm0+Y29udGV4dCBub2RlIGxpc3Q8L3Rlcm0+LgotICogQHhzbC51c2FnZSBhZHZhbmNlZAotICovCi1wdWJsaWMgaW50ZXJmYWNlIENvbnRleHROb2RlTGlzdAotewotCi0gIC8qKgotICAgKiBHZXQgdGhlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjZHQtY3VycmVudC1ub2RlIj5jdXJyZW50IG5vZGU8L2E+LgotICAgKgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBjdXJyZW50IG5vZGUsIG9yIG51bGwuCi0gICAqLwotICBwdWJsaWMgTm9kZSBnZXRDdXJyZW50Tm9kZSgpOwotCi0gIC8qKgotICAgKiBHZXQgdGhlIGN1cnJlbnQgcG9zaXRpb24sIHdoaWNoIGlzIG9uZSBsZXNzIHRoYW4KLSAgICogdGhlIG5leHQgbmV4dE5vZGUoKSBjYWxsIHdpbGwgcmV0cmlldmUuICBpLmUuIGlmCi0gICAqIHlvdSBjYWxsIGdldEN1cnJlbnRQb3MoKSBhbmQgdGhlIHJldHVybiBpcyAwLCB0aGUgbmV4dAotICAgKiBmZXRjaCB3aWxsIHRha2UgcGxhY2UgYXQgaW5kZXggMS4KLSAgICoKLSAgICogQHJldHVybiBUaGUgcG9zaXRpb24gb2YgdGhlCi0gICAqIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjZHQtY3VycmVudC1ub2RlIj5jdXJyZW50IG5vZGU8L2E+Ci0gICAqIGluIHRoZSAgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNkdC1jdXJyZW50LW5vZGUtbGlzdCI+Y3VycmVudCBub2RlIGxpc3Q8L2E+LgotICAgKi8KLSAgcHVibGljIGludCBnZXRDdXJyZW50UG9zKCk7Ci0KLSAgLyoqCi0gICAqIFJlc2V0IHRoZSBpdGVyYXRvci4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHJlc2V0KCk7Ci0KLSAgLyoqCi0gICAqIElmIHNldFNob3VsZENhY2hlTm9kZXModHJ1ZSkgaXMgY2FsbGVkLCB0aGVuIG5vZGVzIHdpbGwKLSAgICogYmUgY2FjaGVkLiAgVGhleSBhcmUgbm90IGNhY2hlZCBieSBkZWZhdWx0LgotICAgKgotICAgKiBAcGFyYW0gYiB0cnVlIGlmIHRoZSBub2RlcyBzaG91bGQgYmUgY2FjaGVkLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0U2hvdWxkQ2FjaGVOb2Rlcyhib29sZWFuIGIpOwotCi0gIC8qKgotICAgKiBJZiBhbiBpbmRleCBpcyByZXF1ZXN0ZWQsIE5vZGVTZXREVE0gd2lsbCBjYWxsIHRoaXMgbWV0aG9kCi0gICAqIHRvIHJ1biB0aGUgaXRlcmF0b3IgdG8gdGhlIGluZGV4LiAgQnkgZGVmYXVsdCB0aGlzIHNldHMKLSAgICogbV9uZXh0IHRvIHRoZSBpbmRleC4gIElmIHRoZSBpbmRleCBhcmd1bWVudCBpcyAtMSwgdGhpcwotICAgKiBzaWduYWxzIHRoYXQgdGhlIGl0ZXJhdG9yIHNob3VsZCBiZSBydW4gdG8gdGhlIGVuZC4KLSAgICoKLSAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBydW4gdG8sIG9yIC0xIGlmIHRoZSBpdGVyYXRvciBzaG91bGQgYmUgcnVuCi0gICAqICAgICAgICAgICAgICB0byB0aGUgZW5kLgotICAgKi8KLSAgcHVibGljIHZvaWQgcnVuVG8oaW50IGluZGV4KTsKLQotICAvKioKLSAgICogU2V0IHRoZSBjdXJyZW50IHBvc2l0aW9uIGluIHRoZSBub2RlIHNldC4KLSAgICogQHBhcmFtIGkgTXVzdCBiZSBhIHZhbGlkIGluZGV4LgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0Q3VycmVudFBvcyhpbnQgaSk7Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbGVuZ3RoIG9mIHRoZSBsaXN0LgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBudW1iZXIgb2Ygbm9kZXMgaW4gdGhpcyBub2RlIGxpc3QuCi0gICAqLwotICBwdWJsaWMgaW50IHNpemUoKTsKLQotICAvKioKLSAgICogVGVsbHMgaWYgdGhpcyBOb2RlU2V0RFRNIGlzICJmcmVzaCIsIGluIG90aGVyIHdvcmRzLCBpZgotICAgKiB0aGUgZmlyc3QgbmV4dE5vZGUoKSB0aGF0IGlzIGNhbGxlZCB3aWxsIHJldHVybiB0aGUKLSAgICogZmlyc3Qgbm9kZSBpbiB0aGUgc2V0LgotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGl0ZXJhdGlvbiBvZiB0aGlzIGxpc3QgaGFzIG5vdCB5ZXQgYmVndW4uCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBpc0ZyZXNoKCk7Ci0KLSAgLyoqCi0gICAqIEdldCBhIGNsb25lZCBJdGVyYXRvciB0aGF0IGlzIHJlc2V0IHRvIHRoZSBzdGFydCBvZiB0aGUgaXRlcmF0aW9uLgotICAgKgotICAgKiBAcmV0dXJuIEEgY2xvbmUgb2YgdGhpcyBpdGVyYXRpb24gdGhhdCBoYXMgYmVlbiByZXNldC4KLSAgICoKLSAgICogQHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIE5vZGVJdGVyYXRvciBjbG9uZVdpdGhSZXNldCgpIHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbjsKLQotICAvKioKLSAgICogR2V0IGEgY2xvbmUgb2YgdGhpcyBpdGVyYXRvci4gIEJlIGF3YXJlIHRoYXQgdGhpcyBvcGVyYXRpb24gbWF5IGJlCi0gICAqIHNvbWV3aGF0IGV4cGVuc2l2ZS4KLSAgICoKLSAgICoKLSAgICogQHJldHVybiBBIGNsb25lIG9mIHRoaXMgb2JqZWN0LgotICAgKgotICAgKiBAdGhyb3dzIENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgT2JqZWN0IGNsb25lKCkgdGhyb3dzIENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uOwotCi0gIC8qKgotICAgKiBHZXQgdGhlIGluZGV4IG9mIHRoZSBsYXN0IG5vZGUgaW4gdGhpcyBsaXN0LgotICAgKgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBpbmRleCBvZiB0aGUgbGFzdCBub2RlIGluIHRoaXMgbGlzdC4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0TGFzdCgpOwotCi0gIC8qKgotICAgKiBTZXQgdGhlIGluZGV4IG9mIHRoZSBsYXN0IG5vZGUgaW4gdGhpcyBsaXN0LgotICAgKgotICAgKgotICAgKiBAcGFyYW0gbGFzdCB0aGUgaW5kZXggb2YgdGhlIGxhc3Qgbm9kZSBpbiB0aGlzIGxpc3QuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRMYXN0KGludCBsYXN0KTsKLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvYXhlcy9EZXNjZW5kYW50SXRlcmF0b3IuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvYXhlcy9EZXNjZW5kYW50SXRlcmF0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNzI5Zjg5ZC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2F4ZXMvRGVzY2VuZGFudEl0ZXJhdG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzODMgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRGVzY2VuZGFudEl0ZXJhdG9yLmphdmEsdiAxLjIuNC4yIDIwMDUvMDkvMTQgMTk6NDU6MjEgamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5heGVzOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uQXhpczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE07Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNQXhpc1RyYXZlcnNlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1GaWx0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNSXRlcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLkV4cHJlc3Npb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoQ29udGV4dDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuY29tcGlsZXIuQ29tcGlsZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmNvbXBpbGVyLk9wQ29kZXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmNvbXBpbGVyLk9wTWFwOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5wYXR0ZXJucy5Ob2RlVGVzdDsKLWltcG9ydCBvcmcudzNjLmRvbS5ET01FeGNlcHRpb247Ci0KLS8qKgotICogVGhpcyBjbGFzcyBpbXBsZW1lbnRzIGFuIG9wdGltaXplZCBpdGVyYXRvciBmb3IKLSAqIGRlc2NlbmRhbnQsIGRlc2NlbmRhbnQtb3Itc2VsZiwgb3IgIi8vZm9vIiBwYXR0ZXJucy4KLSAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmF4ZXMuTG9jUGF0aEl0ZXJhdG9yCi0gKiBAeHNsLnVzYWdlIGFkdmFuY2VkCi0gKi8KLXB1YmxpYyBjbGFzcyBEZXNjZW5kYW50SXRlcmF0b3IgZXh0ZW5kcyBMb2NQYXRoSXRlcmF0b3IKLXsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTExOTAzMzg2MDc3NDM5NzY5MzhMOwotICAvKioKLSAgICogQ3JlYXRlIGEgRGVzY2VuZGFudEl0ZXJhdG9yIG9iamVjdC4KLSAgICoKLSAgICogQHBhcmFtIGNvbXBpbGVyIEEgcmVmZXJlbmNlIHRvIHRoZSBDb21waWxlciB0aGF0IGNvbnRhaW5zIHRoZSBvcCBtYXAuCi0gICAqIEBwYXJhbSBvcFBvcyBUaGUgcG9zaXRpb24gd2l0aGluIHRoZSBvcCBtYXAsIHdoaWNoIGNvbnRhaW5zIHRoZQotICAgKiBsb2NhdGlvbiBwYXRoIGV4cHJlc3Npb24gZm9yIHRoaXMgaXR0ZXJhdG9yLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIERlc2NlbmRhbnRJdGVyYXRvcihDb21waWxlciBjb21waWxlciwgaW50IG9wUG9zLCBpbnQgYW5hbHlzaXMpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgc3VwZXIoY29tcGlsZXIsIG9wUG9zLCBhbmFseXNpcywgZmFsc2UpOwotCi0gICAgaW50IGZpcnN0U3RlcFBvcyA9IE9wTWFwLmdldEZpcnN0Q2hpbGRQb3Mob3BQb3MpOwotICAgIGludCBzdGVwVHlwZSA9IGNvbXBpbGVyLmdldE9wKGZpcnN0U3RlcFBvcyk7Ci0KLSAgICBib29sZWFuIG9yU2VsZiA9IChPcENvZGVzLkZST01fREVTQ0VOREFOVFNfT1JfU0VMRiA9PSBzdGVwVHlwZSk7Ci0gICAgYm9vbGVhbiBmcm9tUm9vdCA9IGZhbHNlOwotICAgIGlmIChPcENvZGVzLkZST01fU0VMRiA9PSBzdGVwVHlwZSkKLSAgICB7Ci0gICAgICBvclNlbGYgPSB0cnVlOwotICAgICAgLy8gZmlyc3RTdGVwUG9zICs9IDg7Ci0gICAgfQotICAgIGVsc2UgaWYoT3BDb2Rlcy5GUk9NX1JPT1QgPT0gc3RlcFR5cGUpCi0gICAgewotICAgICAgZnJvbVJvb3QgPSB0cnVlOwotICAgICAgLy8gVWdseSBjb2RlLi4uIHdpbGwgZ28gYXdheSB3aGVuIEFTVCB3b3JrIGlzIGRvbmUuCi0gICAgICBpbnQgbmV4dFN0ZXBQb3MgPSBjb21waWxlci5nZXROZXh0U3RlcFBvcyhmaXJzdFN0ZXBQb3MpOwotICAgICAgaWYoY29tcGlsZXIuZ2V0T3AobmV4dFN0ZXBQb3MpID09IE9wQ29kZXMuRlJPTV9ERVNDRU5EQU5UU19PUl9TRUxGKQotICAgICAgICBvclNlbGYgPSB0cnVlOwotICAgICAgLy8gZmlyc3RTdGVwUG9zICs9IDg7Ci0gICAgfQotCi0gICAgLy8gRmluZCB0aGUgcG9zaXRpb24gb2YgdGhlIGxhc3Qgc3RlcC4KLSAgICBpbnQgbmV4dFN0ZXBQb3MgPSBmaXJzdFN0ZXBQb3M7Ci0gICAgd2hpbGUodHJ1ZSkKLSAgICB7Ci0gICAgICBuZXh0U3RlcFBvcyA9IGNvbXBpbGVyLmdldE5leHRTdGVwUG9zKG5leHRTdGVwUG9zKTsKLSAgICAgIGlmKG5leHRTdGVwUG9zID4gMCkKLSAgICAgIHsKLSAgICAgICAgaW50IHN0ZXBPcCA9IGNvbXBpbGVyLmdldE9wKG5leHRTdGVwUG9zKTsKLSAgICAgICAgaWYoT3BDb2Rlcy5FTkRPUCAhPSBzdGVwT3ApCi0gICAgICAgICAgZmlyc3RTdGVwUG9zID0gbmV4dFN0ZXBQb3M7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICBicmVhazsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgICAgYnJlYWs7Ci0KLSAgICB9Ci0KLSAgICAvLyBGaXggZm9yIGh0dHA6Ly9uYWdveWEuYXBhY2hlLm9yZy9idWd6aWxsYS9zaG93X2J1Zy5jZ2k/aWQ9MTMzNgotICAgIGlmKChhbmFseXNpcyAmIFdhbGtlckZhY3RvcnkuQklUX0NISUxEKSAhPSAwKQotICAgICAgb3JTZWxmID0gZmFsc2U7Ci0KLSAgICBpZihmcm9tUm9vdCkKLSAgICB7Ci0gICAgICBpZihvclNlbGYpCi0gICAgICAgIG1fYXhpcyA9IEF4aXMuREVTQ0VOREFOVFNPUlNFTEZGUk9NUk9PVDsKLSAgICAgIGVsc2UKLSAgICAgICAgbV9heGlzID0gQXhpcy5ERVNDRU5EQU5UU0ZST01ST09UOwotICAgIH0KLSAgICBlbHNlIGlmKG9yU2VsZikKLSAgICAgIG1fYXhpcyA9IEF4aXMuREVTQ0VOREFOVE9SU0VMRjsKLSAgICBlbHNlCi0gICAgICBtX2F4aXMgPSBBeGlzLkRFU0NFTkRBTlQ7Ci0KLSAgICBpbnQgd2hhdFRvU2hvdyA9IGNvbXBpbGVyLmdldFdoYXRUb1Nob3coZmlyc3RTdGVwUG9zKTsKLQotICAgIGlmICgoMCA9PSAod2hhdFRvU2hvdwotICAgICAgICAgICAgICAgJiAoRFRNRmlsdGVyLlNIT1dfQVRUUklCVVRFIHwgRFRNRmlsdGVyLlNIT1dfRUxFTUVOVAotICAgICAgICAgICAgICAgICAgfCBEVE1GaWx0ZXIuU0hPV19QUk9DRVNTSU5HX0lOU1RSVUNUSU9OKSkpIHx8Ci0gICAgICAgICAgICAgICAgICAgKHdoYXRUb1Nob3cgPT0gRFRNRmlsdGVyLlNIT1dfQUxMKSkKLSAgICAgIGluaXROb2RlVGVzdCh3aGF0VG9TaG93KTsKLSAgICBlbHNlCi0gICAgewotICAgICAgaW5pdE5vZGVUZXN0KHdoYXRUb1Nob3csIGNvbXBpbGVyLmdldFN0ZXBOUyhmaXJzdFN0ZXBQb3MpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tcGlsZXIuZ2V0U3RlcExvY2FsTmFtZShmaXJzdFN0ZXBQb3MpKTsKLSAgICB9Ci0gICAgaW5pdFByZWRpY2F0ZUluZm8oY29tcGlsZXIsIGZpcnN0U3RlcFBvcyk7Ci0gIH0KLQotICAvKioKLSAgICogQ3JlYXRlIGEgRGVzY2VuZGFudEl0ZXJhdG9yIG9iamVjdC4KLSAgICoKLSAgICovCi0gIHB1YmxpYyBEZXNjZW5kYW50SXRlcmF0b3IoKQotICB7Ci0gICAgc3VwZXIobnVsbCk7Ci0gICAgbV9heGlzID0gQXhpcy5ERVNDRU5EQU5UU09SU0VMRkZST01ST09UOwotICAgIGludCB3aGF0VG9TaG93ID0gRFRNRmlsdGVyLlNIT1dfQUxMOwotICAgIGluaXROb2RlVGVzdCh3aGF0VG9TaG93KTsKLSAgfQotCi0KLSAgLyoqCi0gICAqICBHZXQgYSBjbG9uZWQgSXRlcmF0b3IgdGhhdCBpcyByZXNldCB0byB0aGUgYmVnaW5uaW5nCi0gICAqICBvZiB0aGUgcXVlcnkuCi0gICAqCi0gICAqICBAcmV0dXJuIEEgY2xvbmVkIE5vZGVJdGVyYXRvciBzZXQgb2YgdGhlIHN0YXJ0IG9mIHRoZSBxdWVyeS4KLSAgICoKLSAgICogIEB0aHJvd3MgQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBEVE1JdGVyYXRvciBjbG9uZVdpdGhSZXNldCgpIHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbgotICB7Ci0KLSAgICBEZXNjZW5kYW50SXRlcmF0b3IgY2xvbmUgPSAoRGVzY2VuZGFudEl0ZXJhdG9yKSBzdXBlci5jbG9uZVdpdGhSZXNldCgpOwotICAgIGNsb25lLm1fdHJhdmVyc2VyID0gbV90cmF2ZXJzZXI7Ci0KLSAgICBjbG9uZS5yZXNldFByb3hpbWl0eVBvc2l0aW9ucygpOwotCi0gICAgcmV0dXJuIGNsb25lOwotICB9Ci0KLSAgLyoqCi0gICAqICBSZXR1cm5zIHRoZSBuZXh0IG5vZGUgaW4gdGhlIHNldCBhbmQgYWR2YW5jZXMgdGhlIHBvc2l0aW9uIG9mIHRoZQotICAgKiBpdGVyYXRvciBpbiB0aGUgc2V0LiBBZnRlciBhIE5vZGVJdGVyYXRvciBpcyBjcmVhdGVkLCB0aGUgZmlyc3QgY2FsbAotICAgKiB0byBuZXh0Tm9kZSgpIHJldHVybnMgdGhlIGZpcnN0IG5vZGUgaW4gdGhlIHNldC4KLSAgICoKLSAgICogQHJldHVybiAgVGhlIG5leHQgPGNvZGU+Tm9kZTwvY29kZT4gaW4gdGhlIHNldCBiZWluZyBpdGVyYXRlZCBvdmVyLCBvcgotICAgKiAgIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoZXJlIGFyZSBubyBtb3JlIG1lbWJlcnMgaW4gdGhhdCBzZXQuCi0gICAqCi0gICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gICAqICAgIElOVkFMSURfU1RBVEVfRVJSOiBSYWlzZWQgaWYgdGhpcyBtZXRob2QgaXMgY2FsbGVkIGFmdGVyIHRoZQotICAgKiAgIDxjb2RlPmRldGFjaDwvY29kZT4gbWV0aG9kIHdhcyBpbnZva2VkLgotICAgKi8KLSAgcHVibGljIGludCBuZXh0Tm9kZSgpCi0gIHsKLSAgICAgICAgaWYobV9mb3VuZExhc3QpCi0gICAgICAgICAgICAgICAgcmV0dXJuIERUTS5OVUxMOwotCi0gICAgaWYoRFRNLk5VTEwgPT0gbV9sYXN0RmV0Y2hlZCkKLSAgICB7Ci0gICAgICByZXNldFByb3hpbWl0eVBvc2l0aW9ucygpOwotICAgIH0KLQotICAgIGludCBuZXh0OwotCi0gICAgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlZhcmlhYmxlU3RhY2sgdmFyczsKLSAgICBpbnQgc2F2ZWRTdGFydDsKLSAgICBpZiAoLTEgIT0gbV9zdGFja0ZyYW1lKQotICAgIHsKLSAgICAgIHZhcnMgPSBtX2V4ZWNDb250ZXh0LmdldFZhclN0YWNrKCk7Ci0KLSAgICAgIC8vIFRoZXNlIHRocmVlIHN0YXRlbWVudHMgbmVlZCB0byBiZSBjb21iaW5lZCBpbnRvIG9uZSBvcGVyYXRpb24uCi0gICAgICBzYXZlZFN0YXJ0ID0gdmFycy5nZXRTdGFja0ZyYW1lKCk7Ci0KLSAgICAgIHZhcnMuc2V0U3RhY2tGcmFtZShtX3N0YWNrRnJhbWUpOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgLy8gWXVjay4gIEp1c3QgdG8gc2h1dCB1cCB0aGUgY29tcGlsZXIhCi0gICAgICB2YXJzID0gbnVsbDsKLSAgICAgIHNhdmVkU3RhcnQgPSAwOwotICAgIH0KLQotICAgIHRyeQotICAgIHsKLSAgICAgIGRvCi0gICAgICB7Ci0gICAgICAgIGlmKDAgPT0gbV9leHRlbmRlZFR5cGVJRCkKLSAgICAgICAgewotICAgICAgICAgIG5leHQgPSBtX2xhc3RGZXRjaGVkID0gKERUTS5OVUxMID09IG1fbGFzdEZldGNoZWQpCi0gICAgICAgICAgICAgICAgICAgICAgID8gbV90cmF2ZXJzZXIuZmlyc3QobV9jb250ZXh0KQotICAgICAgICAgICAgICAgICAgICAgICA6IG1fdHJhdmVyc2VyLm5leHQobV9jb250ZXh0LCBtX2xhc3RGZXRjaGVkKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgIHsKLSAgICAgICAgICBuZXh0ID0gbV9sYXN0RmV0Y2hlZCA9IChEVE0uTlVMTCA9PSBtX2xhc3RGZXRjaGVkKQotICAgICAgICAgICAgICAgICAgICAgICA/IG1fdHJhdmVyc2VyLmZpcnN0KG1fY29udGV4dCwgbV9leHRlbmRlZFR5cGVJRCkKLSAgICAgICAgICAgICAgICAgICAgICAgOiBtX3RyYXZlcnNlci5uZXh0KG1fY29udGV4dCwgbV9sYXN0RmV0Y2hlZCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fZXh0ZW5kZWRUeXBlSUQpOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKERUTS5OVUxMICE9IG5leHQpCi0gICAgICAgIHsKLSAgICAgICAgICBpZihEVE1JdGVyYXRvci5GSUxURVJfQUNDRVBUID09IGFjY2VwdE5vZGUobmV4dCkpCi0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgICBlbHNlCi0gICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgICAgYnJlYWs7Ci0gICAgICB9Ci0gICAgICB3aGlsZSAobmV4dCAhPSBEVE0uTlVMTCk7Ci0KLSAgICAgIGlmIChEVE0uTlVMTCAhPSBuZXh0KQotICAgICAgewotICAgICAgICBtX3BvcysrOwotICAgICAgICByZXR1cm4gbmV4dDsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgbV9mb3VuZExhc3QgPSB0cnVlOwotCi0gICAgICAgIHJldHVybiBEVE0uTlVMTDsKLSAgICAgIH0KLSAgICB9Ci0gICAgZmluYWxseQotICAgIHsKLSAgICAgIGlmICgtMSAhPSBtX3N0YWNrRnJhbWUpCi0gICAgICB7Ci0gICAgICAgIC8vIFRoZXNlIHR3byBzdGF0ZW1lbnRzIG5lZWQgdG8gYmUgY29tYmluZWQgaW50byBvbmUgb3BlcmF0aW9uLgotICAgICAgICB2YXJzLnNldFN0YWNrRnJhbWUoc2F2ZWRTdGFydCk7Ci0gICAgICB9Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEluaXRpYWxpemUgdGhlIGNvbnRleHQgdmFsdWVzIGZvciB0aGlzIGV4cHJlc3Npb24KLSAgICogYWZ0ZXIgaXQgaXMgY2xvbmVkLgotICAgKgotICAgKiBAcGFyYW0gY29udGV4dCBUaGUgWFBhdGggcnVudGltZSBjb250ZXh0IGZvciB0aGlzCi0gICAqIHRyYW5zZm9ybWF0aW9uLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0Um9vdChpbnQgY29udGV4dCwgT2JqZWN0IGVudmlyb25tZW50KQotICB7Ci0gICAgc3VwZXIuc2V0Um9vdChjb250ZXh0LCBlbnZpcm9ubWVudCk7Ci0gICAgbV90cmF2ZXJzZXIgPSBtX2NkdG0uZ2V0QXhpc1RyYXZlcnNlcihtX2F4aXMpOwotCi0gICAgU3RyaW5nIGxvY2FsTmFtZSA9IGdldExvY2FsTmFtZSgpOwotICAgIFN0cmluZyBuYW1lc3BhY2UgPSBnZXROYW1lc3BhY2UoKTsKLSAgICBpbnQgd2hhdCA9IG1fd2hhdFRvU2hvdzsKLSAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIndoYXQ6ICIpOwotICAgIC8vIE5vZGVUZXN0LmRlYnVnV2hhdFRvU2hvdyh3aGF0KTsKLSAgICBpZihEVE1GaWx0ZXIuU0hPV19BTEwgPT0gd2hhdAotICAgICAgIHx8IE5vZGVUZXN0LldJTEQuZXF1YWxzKGxvY2FsTmFtZSkKLSAgICAgICB8fCBOb2RlVGVzdC5XSUxELmVxdWFscyhuYW1lc3BhY2UpKQotICAgIHsKLSAgICAgIG1fZXh0ZW5kZWRUeXBlSUQgPSAwOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgaW50IHR5cGUgPSBnZXROb2RlVHlwZVRlc3Qod2hhdCk7Ci0gICAgICBtX2V4dGVuZGVkVHlwZUlEID0gbV9jZHRtLmdldEV4cGFuZGVkVHlwZUlEKG5hbWVzcGFjZSwgbG9jYWxOYW1lLCB0eXBlKTsKLSAgICB9Ci0KLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIGZpcnN0IG5vZGUgb3V0IG9mIHRoZSBub2Rlc2V0LCBpZiB0aGlzIGV4cHJlc3Npb24gaXMKLSAgICogYSBub2Rlc2V0IGV4cHJlc3Npb24uICBUaGlzIGlzIHRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIGZvcgotICAgKiBub2Rlc2V0cy4KLSAgICogPHA+V0FSTklORzogRG8gbm90IG11dGF0ZSB0aGlzIGNsYXNzIGZyb20gdGhpcyBmdW5jdGlvbiE8L3A+Ci0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgWFBhdGggcnVudGltZSBjb250ZXh0LgotICAgKiBAcmV0dXJuIHRoZSBmaXJzdCBub2RlIG91dCBvZiB0aGUgbm9kZXNldCwgb3IgRFRNLk5VTEwuCi0gICAqLwotICBwdWJsaWMgaW50IGFzTm9kZShYUGF0aENvbnRleHQgeGN0eHQpCi0gICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIGlmKGdldFByZWRpY2F0ZUNvdW50KCkgPiAwKQotICAgICAgcmV0dXJuIHN1cGVyLmFzTm9kZSh4Y3R4dCk7Ci0KLSAgICBpbnQgY3VycmVudCA9IHhjdHh0LmdldEN1cnJlbnROb2RlKCk7Ci0KLSAgICBEVE0gZHRtID0geGN0eHQuZ2V0RFRNKGN1cnJlbnQpOwotICAgIERUTUF4aXNUcmF2ZXJzZXIgdHJhdmVyc2VyID0gZHRtLmdldEF4aXNUcmF2ZXJzZXIobV9heGlzKTsKLQotICAgIFN0cmluZyBsb2NhbE5hbWUgPSBnZXRMb2NhbE5hbWUoKTsKLSAgICBTdHJpbmcgbmFtZXNwYWNlID0gZ2V0TmFtZXNwYWNlKCk7Ci0gICAgaW50IHdoYXQgPSBtX3doYXRUb1Nob3c7Ci0KLSAgICAvLyBTeXN0ZW0ub3V0LnByaW50KCIgKERlc2NlbmRhbnRJdGVyYXRvcikgIik7Ci0KLSAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIndoYXQ6ICIpOwotICAgIC8vIE5vZGVUZXN0LmRlYnVnV2hhdFRvU2hvdyh3aGF0KTsKLSAgICBpZihEVE1GaWx0ZXIuU0hPV19BTEwgPT0gd2hhdAotICAgICAgIHx8IGxvY2FsTmFtZSA9PSBOb2RlVGVzdC5XSUxECi0gICAgICAgfHwgbmFtZXNwYWNlID09IE5vZGVUZXN0LldJTEQpCi0gICAgewotICAgICAgcmV0dXJuIHRyYXZlcnNlci5maXJzdChjdXJyZW50KTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIGludCB0eXBlID0gZ2V0Tm9kZVR5cGVUZXN0KHdoYXQpOwotICAgICAgaW50IGV4dGVuZGVkVHlwZSA9IGR0bS5nZXRFeHBhbmRlZFR5cGVJRChuYW1lc3BhY2UsIGxvY2FsTmFtZSwgdHlwZSk7Ci0gICAgICByZXR1cm4gdHJhdmVyc2VyLmZpcnN0KGN1cnJlbnQsIGV4dGVuZGVkVHlwZSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqICBEZXRhY2hlcyB0aGUgaXRlcmF0b3IgZnJvbSB0aGUgc2V0IHdoaWNoIGl0IGl0ZXJhdGVkIG92ZXIsIHJlbGVhc2luZwotICAgKiBhbnkgY29tcHV0YXRpb25hbCByZXNvdXJjZXMgYW5kIHBsYWNpbmcgdGhlIGl0ZXJhdG9yIGluIHRoZSBJTlZBTElECi0gICAqIHN0YXRlLiBBZnRlcjxjb2RlPmRldGFjaDwvY29kZT4gaGFzIGJlZW4gaW52b2tlZCwgY2FsbHMgdG8KLSAgICogPGNvZGU+bmV4dE5vZGU8L2NvZGU+IG9yPGNvZGU+cHJldmlvdXNOb2RlPC9jb2RlPiB3aWxsIHJhaXNlIHRoZQotICAgKiBleGNlcHRpb24gSU5WQUxJRF9TVEFURV9FUlIuCi0gICAqLwotICBwdWJsaWMgdm9pZCBkZXRhY2goKQotICB7Ci0gICAgaWYgKG1fYWxsb3dEZXRhY2gpIHsKLSAgICAgIG1fdHJhdmVyc2VyID0gbnVsbDsKLSAgICAgIG1fZXh0ZW5kZWRUeXBlSUQgPSAwOwotCi0gICAgICAvLyBBbHdheXMgY2FsbCB0aGUgc3VwZXJjbGFzcyBkZXRhY2ggbGFzdCEKLSAgICAgIHN1cGVyLmRldGFjaCgpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBheGlzIGJlaW5nIGl0ZXJhdGVkLCBpZiBpdCBpcyBrbm93bi4KLSAgICoKLSAgICogQHJldHVybiBBeGlzLkNISUxELCBldGMuLCBvciAtMSBpZiB0aGUgYXhpcyBpcyBub3Qga25vd24gb3IgaXMgb2YgbXVsdGlwbGUKLSAgICogdHlwZXMuCi0gICAqLwotICBwdWJsaWMgaW50IGdldEF4aXMoKQotICB7Ci0gICAgcmV0dXJuIG1fYXhpczsKLSAgfQotCi0KLSAgLyoqIFRoZSB0cmF2ZXJzZXIgdG8gdXNlIHRvIG5hdmlnYXRlIG92ZXIgdGhlIGRlc2NlbmRhbnRzLiAqLwotICB0cmFuc2llbnQgcHJvdGVjdGVkIERUTUF4aXNUcmF2ZXJzZXIgbV90cmF2ZXJzZXI7Ci0KLSAgLyoqIFRoZSBheGlzIHRoYXQgd2UgYXJlIHRyYXZlcnNpbmcuICovCi0gIHByb3RlY3RlZCBpbnQgbV9heGlzOwotCi0gIC8qKiBUaGUgZXh0ZW5kZWQgdHlwZSBJRCwgbm90IHNldCB1bnRpbCBzZXRSb290LiAqLwotICBwcm90ZWN0ZWQgaW50IG1fZXh0ZW5kZWRUeXBlSUQ7Ci0KLSAgLyoqCi0gICAqIEBzZWUgRXhwcmVzc2lvbiNkZWVwRXF1YWxzKEV4cHJlc3Npb24pCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBkZWVwRXF1YWxzKEV4cHJlc3Npb24gZXhwcikKLSAgewotICAgICAgICBpZighc3VwZXIuZGVlcEVxdWFscyhleHByKSkKLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0KLSAgICAgICAgaWYobV9heGlzICE9ICgoRGVzY2VuZGFudEl0ZXJhdG9yKWV4cHIpLm1fYXhpcykKLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0KLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gIH0KLQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2F4ZXMvRmlsdGVyRXhwckl0ZXJhdG9yLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2F4ZXMvRmlsdGVyRXhwckl0ZXJhdG9yLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGQ3NDkyNzMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9heGVzL0ZpbHRlckV4cHJJdGVyYXRvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjE2ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IEZpbHRlckV4cHJJdGVyYXRvci5qYXZhLHYgMS4yLjQuMiAyMDA1LzA5LzE0IDE5OjQ1OjIyIGplZmZzdXR0b3IgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuYXhlczsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuRXhwcmVzc2lvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuRXhwcmVzc2lvbk93bmVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5YUGF0aFZpc2l0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWE5vZGVTZXQ7Ci0KLXB1YmxpYyBjbGFzcyBGaWx0ZXJFeHBySXRlcmF0b3IgZXh0ZW5kcyBCYXNpY1Rlc3RJdGVyYXRvcgotewotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAyNTUyMTc2MTA1MTY1NzM3NjE0TDsKLSAgLyoqIFRoZSBjb250YWluZWQgZXhwcmVzc2lvbi4gU2hvdWxkIGJlIG5vbi1udWxsLgotICAgKiAgQHNlcmlhbCAgICovCi0gIHByaXZhdGUgRXhwcmVzc2lvbiBtX2V4cHI7Ci0KLSAgLyoqIFRoZSByZXN1bHQgb2YgZXhlY3V0aW5nIG1fZXhwci4gIE5lZWRzIHRvIGJlIGRlZXAgY2xvbmVkIG9uIGNsb25lIG9wLiAgKi8KLSAgdHJhbnNpZW50IHByaXZhdGUgWE5vZGVTZXQgbV9leHByT2JqOwotCi0gIHByaXZhdGUgYm9vbGVhbiBtX211c3RIYXJkUmVzZXQgPSBmYWxzZTsKLSAgcHJpdmF0ZSBib29sZWFuIG1fY2FuRGV0YWNoTm9kZXNldCA9IHRydWU7Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIEZpbHRlckV4cHJJdGVyYXRvciBvYmplY3QuCi0gICAqCi0gICAqLwotICBwdWJsaWMgRmlsdGVyRXhwckl0ZXJhdG9yKCkKLSAgewotICAgIHN1cGVyKG51bGwpOwotICB9Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIEZpbHRlckV4cHJJdGVyYXRvciBvYmplY3QuCi0gICAqCi0gICAqLwotICBwdWJsaWMgRmlsdGVyRXhwckl0ZXJhdG9yKEV4cHJlc3Npb24gZXhwcikKLSAgewotICAgIHN1cGVyKG51bGwpOwotICAgIG1fZXhwciA9IGV4cHI7Ci0gIH0KLQotICAvKioKLSAgICogSW5pdGlhbGl6ZSB0aGUgY29udGV4dCB2YWx1ZXMgZm9yIHRoaXMgZXhwcmVzc2lvbgotICAgKiBhZnRlciBpdCBpcyBjbG9uZWQuCi0gICAqCi0gICAqIEBwYXJhbSBjb250ZXh0IFRoZSBYUGF0aCBydW50aW1lIGNvbnRleHQgZm9yIHRoaXMKLSAgICogdHJhbnNmb3JtYXRpb24uCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRSb290KGludCBjb250ZXh0LCBPYmplY3QgZW52aXJvbm1lbnQpCi0gIHsKLSAgICAgICAgc3VwZXIuc2V0Um9vdChjb250ZXh0LCBlbnZpcm9ubWVudCk7Ci0KLSAgICAgICAgbV9leHByT2JqID0gRmlsdGVyRXhwckl0ZXJhdG9yU2ltcGxlLmV4ZWN1dGVGaWx0ZXJFeHByKGNvbnRleHQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIG1fZXhlY0NvbnRleHQsIGdldFByZWZpeFJlc29sdmVyKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgIGdldElzVG9wTGV2ZWwoKSwgbV9zdGFja0ZyYW1lLCBtX2V4cHIpOwotICAgfQotCi0KLSAgLyoqCi0gICAqIEdldCB0aGUgbmV4dCBub2RlIHZpYSBnZXROZXh0WFhYLiAgQm90dGxlbmVja2VkIGZvciBkZXJpdmVkIGNsYXNzIG92ZXJyaWRlLgotICAgKiBAcmV0dXJuIFRoZSBuZXh0IG5vZGUgb24gdGhlIGF4aXMsIG9yIERUTS5OVUxMLgotICAgKi8KLSAgcHJvdGVjdGVkIGludCBnZXROZXh0Tm9kZSgpCi0gIHsKLSAgICBpZiAobnVsbCAhPSBtX2V4cHJPYmopCi0gICAgewotICAgICAgbV9sYXN0RmV0Y2hlZCA9IG1fZXhwck9iai5uZXh0Tm9kZSgpOwotICAgIH0KLSAgICBlbHNlCi0gICAgICBtX2xhc3RGZXRjaGVkID0gRFRNLk5VTEw7Ci0KLSAgICByZXR1cm4gbV9sYXN0RmV0Y2hlZDsKLSAgfQotCi0gIC8qKgotICAgKiBEZXRhY2hlcyB0aGUgd2Fsa2VyIGZyb20gdGhlIHNldCB3aGljaCBpdCBpdGVyYXRlZCBvdmVyLCByZWxlYXNpbmcKLSAgICogYW55IGNvbXB1dGF0aW9uYWwgcmVzb3VyY2VzIGFuZCBwbGFjaW5nIHRoZSBpdGVyYXRvciBpbiB0aGUgSU5WQUxJRAotICAgKiBzdGF0ZS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGRldGFjaCgpCi0gIHsKLSAgICAgICAgc3VwZXIuZGV0YWNoKCk7Ci0gICAgICAgIG1fZXhwck9iai5kZXRhY2goKTsKLSAgICAgICAgbV9leHByT2JqID0gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgdG8gZml4dXAgdmFyaWFibGVzIGZyb20gUU5hbWVzIHRvIHN0YWNrIGZyYW1lCi0gICAqIGluZGV4ZXMgYXQgc3R5bGVzaGVldCBidWlsZCB0aW1lLgotICAgKiBAcGFyYW0gdmFycyBMaXN0IG9mIFFOYW1lcyB0aGF0IGNvcnJlc3BvbmQgdG8gdmFyaWFibGVzLiAgVGhpcyBsaXN0Ci0gICAqIHNob3VsZCBiZSBzZWFyY2hlZCBiYWNrd2FyZHMgZm9yIHRoZSBmaXJzdCBxdWFsaWZpZWQgbmFtZSB0aGF0Ci0gICAqIGNvcnJlc3BvbmRzIHRvIHRoZSB2YXJpYWJsZSByZWZlcmVuY2UgcW5hbWUuICBUaGUgcG9zaXRpb24gb2YgdGhlCi0gICAqIFFOYW1lIGluIHRoZSB2ZWN0b3IgZnJvbSB0aGUgc3RhcnQgb2YgdGhlIHZlY3RvciB3aWxsIGJlIGl0cyBwb3NpdGlvbgotICAgKiBpbiB0aGUgc3RhY2sgZnJhbWUgKGJ1dCB2YXJpYWJsZXMgYWJvdmUgdGhlIGdsb2JhbHNUb3AgdmFsdWUgd2lsbCBuZWVkCi0gICAqIHRvIGJlIG9mZnNldCB0byB0aGUgY3VycmVudCBzdGFjayBmcmFtZSkuCi0gICAqLwotICBwdWJsaWMgdm9pZCBmaXh1cFZhcmlhYmxlcyhqYXZhLnV0aWwuVmVjdG9yIHZhcnMsIGludCBnbG9iYWxzU2l6ZSkKLSAgewotICAgIHN1cGVyLmZpeHVwVmFyaWFibGVzKHZhcnMsIGdsb2JhbHNTaXplKTsKLSAgICBtX2V4cHIuZml4dXBWYXJpYWJsZXModmFycywgZ2xvYmFsc1NpemUpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgaW5uZXIgY29udGFpbmVkIGV4cHJlc3Npb24gb2YgdGhpcyBmaWx0ZXIuCi0gICAqLwotICBwdWJsaWMgRXhwcmVzc2lvbiBnZXRJbm5lckV4cHJlc3Npb24oKQotICB7Ci0gICAgcmV0dXJuIG1fZXhwcjsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIGlubmVyIGNvbnRhaW5lZCBleHByZXNzaW9uIG9mIHRoaXMgZmlsdGVyLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0SW5uZXJFeHByZXNzaW9uKEV4cHJlc3Npb24gZXhwcikKLSAgewotICAgIGV4cHIuZXhwclNldFBhcmVudCh0aGlzKTsKLSAgICBtX2V4cHIgPSBleHByOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgYW5hbHlzaXMgYml0cyBmb3IgdGhpcyB3YWxrZXIsIGFzIGRlZmluZWQgaW4gdGhlIFdhbGtlckZhY3RvcnkuCi0gICAqIEByZXR1cm4gT25lIG9mIFdhbGtlckZhY3RvcnkjQklUX0RFU0NFTkRBTlQsIGV0Yy4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0QW5hbHlzaXNCaXRzKCkKLSAgewotICAgIGlmIChudWxsICE9IG1fZXhwciAmJiBtX2V4cHIgaW5zdGFuY2VvZiBQYXRoQ29tcG9uZW50KQotICAgIHsKLSAgICAgIHJldHVybiAoKFBhdGhDb21wb25lbnQpIG1fZXhwcikuZ2V0QW5hbHlzaXNCaXRzKCk7Ci0gICAgfQotICAgIHJldHVybiBXYWxrZXJGYWN0b3J5LkJJVF9GSUxURVI7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyB0cnVlIGlmIGFsbCB0aGUgbm9kZXMgaW4gdGhlIGl0ZXJhdGlvbiB3ZWxsIGJlIHJldHVybmVkIGluIGRvY3VtZW50Ci0gICAqIG9yZGVyLgotICAgKiBXYXJuaW5nOiBUaGlzIGNhbiBvbmx5IGJlIGNhbGxlZCBhZnRlciBzZXRSb290IGhhcyBiZWVuIGNhbGxlZCEKLSAgICoKLSAgICogQHJldHVybiB0cnVlIGFzIGEgZGVmYXVsdC4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzRG9jT3JkZXJlZCgpCi0gIHsKLSAgICByZXR1cm4gbV9leHByT2JqLmlzRG9jT3JkZXJlZCgpOwotICB9Ci0KLSAgY2xhc3MgZmlsdGVyRXhwck93bmVyIGltcGxlbWVudHMgRXhwcmVzc2lvbk93bmVyCi0gIHsKLSAgICAvKioKLSAgICAqIEBzZWUgRXhwcmVzc2lvbk93bmVyI2dldEV4cHJlc3Npb24oKQotICAgICovCi0gICAgcHVibGljIEV4cHJlc3Npb24gZ2V0RXhwcmVzc2lvbigpCi0gICAgewotICAgICAgcmV0dXJuIG1fZXhwcjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAc2VlIEV4cHJlc3Npb25Pd25lciNzZXRFeHByZXNzaW9uKEV4cHJlc3Npb24pCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RXhwcmVzc2lvbihFeHByZXNzaW9uIGV4cCkKLSAgICB7Ci0gICAgICBleHAuZXhwclNldFBhcmVudChGaWx0ZXJFeHBySXRlcmF0b3IudGhpcyk7Ci0gICAgICBtX2V4cHIgPSBleHA7Ci0gICAgfQotCi0gIH0KLQotICAvKioKLSAgICogVGhpcyB3aWxsIHRyYXZlcnNlIHRoZSBoZWFyYXJjaHksIGNhbGxpbmcgdGhlIHZpc2l0b3IgZm9yCi0gICAqIGVhY2ggbWVtYmVyLiAgSWYgdGhlIGNhbGxlZCB2aXNpdG9yIG1ldGhvZCByZXR1cm5zCi0gICAqIGZhbHNlLCB0aGUgc3VidHJlZSBzaG91bGQgbm90IGJlIGNhbGxlZC4KLSAgICoKLSAgICogQHBhcmFtIHZpc2l0b3IgVGhlIHZpc2l0b3Igd2hvc2UgYXBwcm9wcmlhdGUgbWV0aG9kIHdpbGwgYmUgY2FsbGVkLgotICAgKi8KLSAgcHVibGljIHZvaWQgY2FsbFByZWRpY2F0ZVZpc2l0b3JzKFhQYXRoVmlzaXRvciB2aXNpdG9yKQotICB7Ci0gICAgbV9leHByLmNhbGxWaXNpdG9ycyhuZXcgZmlsdGVyRXhwck93bmVyKCksIHZpc2l0b3IpOwotCi0gICAgc3VwZXIuY2FsbFByZWRpY2F0ZVZpc2l0b3JzKHZpc2l0b3IpOwotICB9Ci0KLSAgLyoqCi0gICAqIEBzZWUgRXhwcmVzc2lvbiNkZWVwRXF1YWxzKEV4cHJlc3Npb24pCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBkZWVwRXF1YWxzKEV4cHJlc3Npb24gZXhwcikKLSAgewotICAgIGlmICghc3VwZXIuZGVlcEVxdWFscyhleHByKSkKLSAgICAgIHJldHVybiBmYWxzZTsKLQotICAgIEZpbHRlckV4cHJJdGVyYXRvciBmZXQgPSAoRmlsdGVyRXhwckl0ZXJhdG9yKSBleHByOwotICAgIGlmICghbV9leHByLmRlZXBFcXVhbHMoZmV0Lm1fZXhwcikpCi0gICAgICByZXR1cm4gZmFsc2U7Ci0KLSAgICByZXR1cm4gdHJ1ZTsKLSAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2F4ZXMvRmlsdGVyRXhwckl0ZXJhdG9yU2ltcGxlLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2F4ZXMvRmlsdGVyRXhwckl0ZXJhdG9yU2ltcGxlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDI5YjA2NGUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9heGVzL0ZpbHRlckV4cHJJdGVyYXRvclNpbXBsZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzE2ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IEZpbHRlckV4cHJJdGVyYXRvclNpbXBsZS5qYXZhLHYgMS4yLjQuMiAyMDA1LzA5LzE0IDE5OjQ1OjIxIGplZmZzdXR0b3IgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuYXhlczsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkF4aXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuUHJlZml4UmVzb2x2ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLkV4cHJlc3Npb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLkV4cHJlc3Npb25Pd25lcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuVmFyaWFibGVTdGFjazsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuWFBhdGhDb250ZXh0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5YUGF0aFZpc2l0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWE5vZGVTZXQ7Ci0KLS8qKgotICogQ2xhc3MgdG8gdXNlIGZvciBvbmUtc3RlcCBpdGVyYXRpb24gdGhhdCBkb2Vzbid0IGhhdmUgYSBwcmVkaWNhdGUsIGFuZAotICogZG9lc24ndCBuZWVkIHRvIHNldCB0aGUgY29udGV4dC4KLSAqLwotcHVibGljIGNsYXNzIEZpbHRlckV4cHJJdGVyYXRvclNpbXBsZSBleHRlbmRzIExvY1BhdGhJdGVyYXRvcgotewotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNjk3ODk3NzE4NzAyNTM3NTU3OUw7Ci0gIC8qKiBUaGUgY29udGFpbmVkIGV4cHJlc3Npb24uIFNob3VsZCBiZSBub24tbnVsbC4KLSAgICogIEBzZXJpYWwgICAqLwotICBwcml2YXRlIEV4cHJlc3Npb24gbV9leHByOwotCi0gIC8qKiBUaGUgcmVzdWx0IG9mIGV4ZWN1dGluZyBtX2V4cHIuICBOZWVkcyB0byBiZSBkZWVwIGNsb25lZCBvbiBjbG9uZSBvcC4gICovCi0gIHRyYW5zaWVudCBwcml2YXRlIFhOb2RlU2V0IG1fZXhwck9iajsKLQotICBwcml2YXRlIGJvb2xlYW4gbV9tdXN0SGFyZFJlc2V0ID0gZmFsc2U7Ci0gIHByaXZhdGUgYm9vbGVhbiBtX2NhbkRldGFjaE5vZGVzZXQgPSB0cnVlOwotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBGaWx0ZXJFeHBySXRlcmF0b3JTaW1wbGUgb2JqZWN0LgotICAgKgotICAgKi8KLSAgcHVibGljIEZpbHRlckV4cHJJdGVyYXRvclNpbXBsZSgpCi0gIHsKLSAgICBzdXBlcihudWxsKTsKLSAgfQotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBGaWx0ZXJFeHBySXRlcmF0b3JTaW1wbGUgb2JqZWN0LgotICAgKgotICAgKi8KLSAgcHVibGljIEZpbHRlckV4cHJJdGVyYXRvclNpbXBsZShFeHByZXNzaW9uIGV4cHIpCi0gIHsKLSAgICBzdXBlcihudWxsKTsKLSAgICBtX2V4cHIgPSBleHByOwotICB9Ci0KLSAgLyoqCi0gICAqIEluaXRpYWxpemUgdGhlIGNvbnRleHQgdmFsdWVzIGZvciB0aGlzIGV4cHJlc3Npb24KLSAgICogYWZ0ZXIgaXQgaXMgY2xvbmVkLgotICAgKgotICAgKiBAcGFyYW0gY29udGV4dCBUaGUgWFBhdGggcnVudGltZSBjb250ZXh0IGZvciB0aGlzCi0gICAqIHRyYW5zZm9ybWF0aW9uLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0Um9vdChpbnQgY29udGV4dCwgT2JqZWN0IGVudmlyb25tZW50KQotICB7Ci0gICAgICAgIHN1cGVyLnNldFJvb3QoY29udGV4dCwgZW52aXJvbm1lbnQpOwotICAgICAgICBtX2V4cHJPYmogPSBleGVjdXRlRmlsdGVyRXhwcihjb250ZXh0LCBtX2V4ZWNDb250ZXh0LCBnZXRQcmVmaXhSZXNvbHZlcigpLAotICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRJc1RvcExldmVsKCksIG1fc3RhY2tGcmFtZSwgbV9leHByKTsKLSAgfQotCi0gIC8qKgotICAgKiBFeGVjdXRlIHRoZSBleHByZXNzaW9uLiAgTWVhbnQgZm9yIHJldXNlIGJ5IG90aGVyIEZpbHRlckV4cHIgaXRlcmF0b3JzCi0gICAqIHRoYXQgYXJlIG5vdCBkZXJpdmVkIGZyb20gdGhpcyBvYmplY3QuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIFhOb2RlU2V0IGV4ZWN1dGVGaWx0ZXJFeHByKGludCBjb250ZXh0LCBYUGF0aENvbnRleHQgeGN0eHQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQcmVmaXhSZXNvbHZlciBwcmVmaXhSZXNvbHZlciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gaXNUb3BMZXZlbCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBzdGFja0ZyYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRXhwcmVzc2lvbiBleHByICkKLSAgICB0aHJvd3MgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5XcmFwcGVkUnVudGltZUV4Y2VwdGlvbgotICB7Ci0gICAgUHJlZml4UmVzb2x2ZXIgc2F2ZWRSZXNvbHZlciA9IHhjdHh0LmdldE5hbWVzcGFjZUNvbnRleHQoKTsKLSAgICBYTm9kZVNldCByZXN1bHQgPSBudWxsOwotCi0gICAgdHJ5Ci0gICAgewotICAgICAgeGN0eHQucHVzaEN1cnJlbnROb2RlKGNvbnRleHQpOwotICAgICAgeGN0eHQuc2V0TmFtZXNwYWNlQ29udGV4dChwcmVmaXhSZXNvbHZlcik7Ci0KLSAgICAgIC8vIFRoZSBzZXRSb290IG9wZXJhdGlvbiBjYW4gdGFrZSBwbGFjZSB3aXRoIGEgcmVzZXQgb3BlcmF0aW9uLAotICAgICAgLy8gYW5kIHNvIHdlIG1heSBub3QgYmUgaW4gdGhlIGNvbnRleHQgb2YgTG9jUGF0aEl0ZXJhdG9yI25leHROb2RlLAotICAgICAgLy8gc28gd2UgaGF2ZSB0byBzZXQgdXAgdGhlIHZhcmlhYmxlIGNvbnRleHQsIGV4ZWN1dGUgdGhlIGV4cHJlc3Npb24sCi0gICAgICAvLyBhbmQgdGhlbiByZXN0b3JlIHRoZSB2YXJpYWJsZSBjb250ZXh0LgotCi0gICAgICBpZiAoaXNUb3BMZXZlbCkKLSAgICAgIHsKLSAgICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJjYWxsaW5nIG1fZXhwci5leGVjdXRlKGdldFhQYXRoQ29udGV4dCgpKSIpOwotICAgICAgICBWYXJpYWJsZVN0YWNrIHZhcnMgPSB4Y3R4dC5nZXRWYXJTdGFjaygpOwotCi0gICAgICAgIC8vIFRoZXNlIHRocmVlIHN0YXRlbWVudHMgbmVlZCB0byBiZSBjb21iaW5lZCBpbnRvIG9uZSBvcGVyYXRpb24uCi0gICAgICAgIGludCBzYXZlZFN0YXJ0ID0gdmFycy5nZXRTdGFja0ZyYW1lKCk7Ci0gICAgICAgIHZhcnMuc2V0U3RhY2tGcmFtZShzdGFja0ZyYW1lKTsKLQotICAgICAgICByZXN1bHQgPSAoY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWE5vZGVTZXQpIGV4cHIuZXhlY3V0ZSh4Y3R4dCk7Ci0gICAgICAgIHJlc3VsdC5zZXRTaG91bGRDYWNoZU5vZGVzKHRydWUpOwotCi0gICAgICAgIC8vIFRoZXNlIHR3byBzdGF0ZW1lbnRzIG5lZWQgdG8gYmUgY29tYmluZWQgaW50byBvbmUgb3BlcmF0aW9uLgotICAgICAgICB2YXJzLnNldFN0YWNrRnJhbWUoc2F2ZWRTdGFydCk7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICAgICAgcmVzdWx0ID0gKGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhOb2RlU2V0KSBleHByLmV4ZWN1dGUoeGN0eHQpOwotCi0gICAgfQotICAgIGNhdGNoIChqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uIHNlKQotICAgIHsKLQotICAgICAgLy8gVE9ETzogRml4Li4uCi0gICAgICB0aHJvdyBuZXcgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5XcmFwcGVkUnVudGltZUV4Y2VwdGlvbihzZSk7Ci0gICAgfQotICAgIGZpbmFsbHkKLSAgICB7Ci0gICAgICB4Y3R4dC5wb3BDdXJyZW50Tm9kZSgpOwotICAgICAgeGN0eHQuc2V0TmFtZXNwYWNlQ29udGV4dChzYXZlZFJlc29sdmVyKTsKLSAgICB9Ci0gICAgcmV0dXJuIHJlc3VsdDsKLSAgfQotCi0gIC8qKgotICAgKiAgUmV0dXJucyB0aGUgbmV4dCBub2RlIGluIHRoZSBzZXQgYW5kIGFkdmFuY2VzIHRoZSBwb3NpdGlvbiBvZiB0aGUKLSAgICogaXRlcmF0b3IgaW4gdGhlIHNldC4gQWZ0ZXIgYSBOb2RlSXRlcmF0b3IgaXMgY3JlYXRlZCwgdGhlIGZpcnN0IGNhbGwKLSAgICogdG8gbmV4dE5vZGUoKSByZXR1cm5zIHRoZSBmaXJzdCBub2RlIGluIHRoZSBzZXQuCi0gICAqCi0gICAqIEByZXR1cm4gIFRoZSBuZXh0IDxjb2RlPk5vZGU8L2NvZGU+IGluIHRoZSBzZXQgYmVpbmcgaXRlcmF0ZWQgb3Zlciwgb3IKLSAgICogICA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGVyZSBhcmUgbm8gbW9yZSBtZW1iZXJzIGluIHRoYXQgc2V0LgotICAgKi8KLSAgcHVibGljIGludCBuZXh0Tm9kZSgpCi0gIHsKLSAgICAgICAgaWYobV9mb3VuZExhc3QpCi0gICAgICAgICAgICAgICAgcmV0dXJuIERUTS5OVUxMOwotCi0gICAgaW50IG5leHQ7Ci0KLSAgICBpZiAobnVsbCAhPSBtX2V4cHJPYmopCi0gICAgewotICAgICAgbV9sYXN0RmV0Y2hlZCA9IG5leHQgPSBtX2V4cHJPYmoubmV4dE5vZGUoKTsKLSAgICB9Ci0gICAgZWxzZQotICAgICAgbV9sYXN0RmV0Y2hlZCA9IG5leHQgPSBEVE0uTlVMTDsKLQotICAgIC8vIG1fbGFzdEZldGNoZWQgPSBuZXh0OwotICAgIGlmIChEVE0uTlVMTCAhPSBuZXh0KQotICAgIHsKLSAgICAgIG1fcG9zKys7Ci0gICAgICByZXR1cm4gbmV4dDsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIG1fZm91bmRMYXN0ID0gdHJ1ZTsKLQotICAgICAgcmV0dXJuIERUTS5OVUxMOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBEZXRhY2hlcyB0aGUgd2Fsa2VyIGZyb20gdGhlIHNldCB3aGljaCBpdCBpdGVyYXRlZCBvdmVyLCByZWxlYXNpbmcKLSAgICogYW55IGNvbXB1dGF0aW9uYWwgcmVzb3VyY2VzIGFuZCBwbGFjaW5nIHRoZSBpdGVyYXRvciBpbiB0aGUgSU5WQUxJRAotICAgKiBzdGF0ZS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGRldGFjaCgpCi0gIHsKLSAgICBpZihtX2FsbG93RGV0YWNoKQotICAgIHsKLSAgICAgICAgICAgICAgICBzdXBlci5kZXRhY2goKTsKLSAgICAgICAgICAgICAgICBtX2V4cHJPYmouZGV0YWNoKCk7Ci0gICAgICAgICAgICAgICAgbV9leHByT2JqID0gbnVsbDsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogVGhpcyBmdW5jdGlvbiBpcyB1c2VkIHRvIGZpeHVwIHZhcmlhYmxlcyBmcm9tIFFOYW1lcyB0byBzdGFjayBmcmFtZQotICAgKiBpbmRleGVzIGF0IHN0eWxlc2hlZXQgYnVpbGQgdGltZS4KLSAgICogQHBhcmFtIHZhcnMgTGlzdCBvZiBRTmFtZXMgdGhhdCBjb3JyZXNwb25kIHRvIHZhcmlhYmxlcy4gIFRoaXMgbGlzdAotICAgKiBzaG91bGQgYmUgc2VhcmNoZWQgYmFja3dhcmRzIGZvciB0aGUgZmlyc3QgcXVhbGlmaWVkIG5hbWUgdGhhdAotICAgKiBjb3JyZXNwb25kcyB0byB0aGUgdmFyaWFibGUgcmVmZXJlbmNlIHFuYW1lLiAgVGhlIHBvc2l0aW9uIG9mIHRoZQotICAgKiBRTmFtZSBpbiB0aGUgdmVjdG9yIGZyb20gdGhlIHN0YXJ0IG9mIHRoZSB2ZWN0b3Igd2lsbCBiZSBpdHMgcG9zaXRpb24KLSAgICogaW4gdGhlIHN0YWNrIGZyYW1lIChidXQgdmFyaWFibGVzIGFib3ZlIHRoZSBnbG9iYWxzVG9wIHZhbHVlIHdpbGwgbmVlZAotICAgKiB0byBiZSBvZmZzZXQgdG8gdGhlIGN1cnJlbnQgc3RhY2sgZnJhbWUpLgotICAgKi8KLSAgcHVibGljIHZvaWQgZml4dXBWYXJpYWJsZXMoamF2YS51dGlsLlZlY3RvciB2YXJzLCBpbnQgZ2xvYmFsc1NpemUpCi0gIHsKLSAgICBzdXBlci5maXh1cFZhcmlhYmxlcyh2YXJzLCBnbG9iYWxzU2l6ZSk7Ci0gICAgbV9leHByLmZpeHVwVmFyaWFibGVzKHZhcnMsIGdsb2JhbHNTaXplKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGlubmVyIGNvbnRhaW5lZCBleHByZXNzaW9uIG9mIHRoaXMgZmlsdGVyLgotICAgKi8KLSAgcHVibGljIEV4cHJlc3Npb24gZ2V0SW5uZXJFeHByZXNzaW9uKCkKLSAgewotICAgIHJldHVybiBtX2V4cHI7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBpbm5lciBjb250YWluZWQgZXhwcmVzc2lvbiBvZiB0aGlzIGZpbHRlci4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldElubmVyRXhwcmVzc2lvbihFeHByZXNzaW9uIGV4cHIpCi0gIHsKLSAgICBleHByLmV4cHJTZXRQYXJlbnQodGhpcyk7Ci0gICAgbV9leHByID0gZXhwcjsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGFuYWx5c2lzIGJpdHMgZm9yIHRoaXMgd2Fsa2VyLCBhcyBkZWZpbmVkIGluIHRoZSBXYWxrZXJGYWN0b3J5LgotICAgKiBAcmV0dXJuIE9uZSBvZiBXYWxrZXJGYWN0b3J5I0JJVF9ERVNDRU5EQU5ULCBldGMuCi0gICAqLwotICBwdWJsaWMgaW50IGdldEFuYWx5c2lzQml0cygpCi0gIHsKLSAgICBpZiAobnVsbCAhPSBtX2V4cHIgJiYgbV9leHByIGluc3RhbmNlb2YgUGF0aENvbXBvbmVudCkKLSAgICB7Ci0gICAgICByZXR1cm4gKChQYXRoQ29tcG9uZW50KSBtX2V4cHIpLmdldEFuYWx5c2lzQml0cygpOwotICAgIH0KLSAgICByZXR1cm4gV2Fsa2VyRmFjdG9yeS5CSVRfRklMVEVSOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdHJ1ZSBpZiBhbGwgdGhlIG5vZGVzIGluIHRoZSBpdGVyYXRpb24gd2VsbCBiZSByZXR1cm5lZCBpbiBkb2N1bWVudAotICAgKiBvcmRlci4KLSAgICogV2FybmluZzogVGhpcyBjYW4gb25seSBiZSBjYWxsZWQgYWZ0ZXIgc2V0Um9vdCBoYXMgYmVlbiBjYWxsZWQhCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBhcyBhIGRlZmF1bHQuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBpc0RvY09yZGVyZWQoKQotICB7Ci0gICAgcmV0dXJuIG1fZXhwck9iai5pc0RvY09yZGVyZWQoKTsKLSAgfQotCi0gIGNsYXNzIGZpbHRlckV4cHJPd25lciBpbXBsZW1lbnRzIEV4cHJlc3Npb25Pd25lcgotICB7Ci0gICAgLyoqCi0gICAgKiBAc2VlIEV4cHJlc3Npb25Pd25lciNnZXRFeHByZXNzaW9uKCkKLSAgICAqLwotICAgIHB1YmxpYyBFeHByZXNzaW9uIGdldEV4cHJlc3Npb24oKQotICAgIHsKLSAgICAgIHJldHVybiBtX2V4cHI7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBFeHByZXNzaW9uT3duZXIjc2V0RXhwcmVzc2lvbihFeHByZXNzaW9uKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEV4cHJlc3Npb24oRXhwcmVzc2lvbiBleHApCi0gICAgewotICAgICAgZXhwLmV4cHJTZXRQYXJlbnQoRmlsdGVyRXhwckl0ZXJhdG9yU2ltcGxlLnRoaXMpOwotICAgICAgbV9leHByID0gZXhwOwotICAgIH0KLQotICB9Ci0KLSAgLyoqCi0gICAqIFRoaXMgd2lsbCB0cmF2ZXJzZSB0aGUgaGVhcmFyY2h5LCBjYWxsaW5nIHRoZSB2aXNpdG9yIGZvcgotICAgKiBlYWNoIG1lbWJlci4gIElmIHRoZSBjYWxsZWQgdmlzaXRvciBtZXRob2QgcmV0dXJucwotICAgKiBmYWxzZSwgdGhlIHN1YnRyZWUgc2hvdWxkIG5vdCBiZSBjYWxsZWQuCi0gICAqCi0gICAqIEBwYXJhbSB2aXNpdG9yIFRoZSB2aXNpdG9yIHdob3NlIGFwcHJvcHJpYXRlIG1ldGhvZCB3aWxsIGJlIGNhbGxlZC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGNhbGxQcmVkaWNhdGVWaXNpdG9ycyhYUGF0aFZpc2l0b3IgdmlzaXRvcikKLSAgewotICAgIG1fZXhwci5jYWxsVmlzaXRvcnMobmV3IGZpbHRlckV4cHJPd25lcigpLCB2aXNpdG9yKTsKLQotICAgIHN1cGVyLmNhbGxQcmVkaWNhdGVWaXNpdG9ycyh2aXNpdG9yKTsKLSAgfQotCi0gIC8qKgotICAgKiBAc2VlIEV4cHJlc3Npb24jZGVlcEVxdWFscyhFeHByZXNzaW9uKQotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZGVlcEVxdWFscyhFeHByZXNzaW9uIGV4cHIpCi0gIHsKLSAgICBpZiAoIXN1cGVyLmRlZXBFcXVhbHMoZXhwcikpCi0gICAgICByZXR1cm4gZmFsc2U7Ci0KLSAgICBGaWx0ZXJFeHBySXRlcmF0b3JTaW1wbGUgZmV0ID0gKEZpbHRlckV4cHJJdGVyYXRvclNpbXBsZSkgZXhwcjsKLSAgICBpZiAoIW1fZXhwci5kZWVwRXF1YWxzKGZldC5tX2V4cHIpKQotICAgICAgcmV0dXJuIGZhbHNlOwotCi0gICAgcmV0dXJuIHRydWU7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgYXhpcyBiZWluZyBpdGVyYXRlZCwgaWYgaXQgaXMga25vd24uCi0gICAqCi0gICAqIEByZXR1cm4gQXhpcy5DSElMRCwgZXRjLiwgb3IgLTEgaWYgdGhlIGF4aXMgaXMgbm90IGtub3duIG9yIGlzIG9mIG11bHRpcGxlCi0gICAqIHR5cGVzLgotICAgKi8KLSAgcHVibGljIGludCBnZXRBeGlzKCkKLSAgewotICAgICAgICBpZihudWxsICE9IG1fZXhwck9iaikKLSAgICAgICAgcmV0dXJuIG1fZXhwck9iai5nZXRBeGlzKCk7Ci0gICAgZWxzZQotICAgICAgICByZXR1cm4gQXhpcy5GSUxURVJFRExJU1Q7Ci0gIH0KLQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2F4ZXMvRmlsdGVyRXhwcldhbGtlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9heGVzL0ZpbHRlckV4cHJXYWxrZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNDA2MzhlNi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2F4ZXMvRmlsdGVyRXhwcldhbGtlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzUyICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IEZpbHRlckV4cHJXYWxrZXIuamF2YSx2IDEuMi40LjIgMjAwNS8wOS8xNCAxOTo0NToyMyBqZWZmc3V0dG9yIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmF4ZXM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5BeGlzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1JdGVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuRXhwcmVzc2lvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuRXhwcmVzc2lvbk93bmVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5YUGF0aENvbnRleHQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoVmlzaXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuY29tcGlsZXIuQ29tcGlsZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmNvbXBpbGVyLk9wQ29kZXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWE5vZGVTZXQ7Ci0KLS8qKgotICogV2Fsa2VyIGZvciB0aGUgT1BfVkFSSUFCTEUsIG9yIE9QX0VYVEZVTkNUSU9OLCBvciBPUF9GVU5DVElPTiwgb3IgT1BfR1JPVVAsCi0gKiBvcCBjb2Rlcy4KLSAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGgjTlQtRmlsdGVyRXhwciI+WFBhdGggRmlsdGVyRXhwciBkZXNjcmlwdGlvbnM8L2E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBGaWx0ZXJFeHByV2Fsa2VyIGV4dGVuZHMgQXhlc1dhbGtlcgotewotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA1NDU3MTgyNDcxNDI0NDg4Mzc1TDsKLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgRmlsdGVyRXhwcldhbGtlciB1c2luZyBhIExvY1BhdGhJdGVyYXRvci4KLSAgICoKLSAgICogQHBhcmFtIGxvY1BhdGhJdGVyYXRvciBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIHBhcmVudCBpdGVyYXRvci4KLSAgICovCi0gIHB1YmxpYyBGaWx0ZXJFeHByV2Fsa2VyKFdhbGtpbmdJdGVyYXRvciBsb2NQYXRoSXRlcmF0b3IpCi0gIHsKLSAgICBzdXBlcihsb2NQYXRoSXRlcmF0b3IsIEF4aXMuRklMVEVSRURMSVNUKTsKLSAgfQotCi0gIC8qKgotICAgKiBJbml0IGEgRmlsdGVyRXhwcldhbGtlci4KLSAgICoKLSAgICogQHBhcmFtIGNvbXBpbGVyIG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgQ29tcGlsZXIgdGhhdCBpcyBjb25zdHJ1Y3RpbmcuCi0gICAqIEBwYXJhbSBvcFBvcyBwb3NpdGl2ZSBvcGNvZGUgcG9zaXRpb24gZm9yIHRoaXMgc3RlcC4KLSAgICogQHBhcmFtIHN0ZXBUeXBlIFRoZSB0eXBlIG9mIHN0ZXAuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgaW5pdChDb21waWxlciBjb21waWxlciwgaW50IG9wUG9zLCBpbnQgc3RlcFR5cGUpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgc3VwZXIuaW5pdChjb21waWxlciwgb3BQb3MsIHN0ZXBUeXBlKTsKLQotICAgIC8vIFNtb290aCBvdmVyIGFuIGFub21pbHkgaW4gdGhlIG9wY29kZSBtYXAuLi4KLSAgICBzd2l0Y2ggKHN0ZXBUeXBlKQotICAgIHsKLSAgICBjYXNlIE9wQ29kZXMuT1BfRlVOQ1RJT04gOgotICAgIGNhc2UgT3BDb2Rlcy5PUF9FWFRGVU5DVElPTiA6Ci0gICAgICAgIG1fbXVzdEhhcmRSZXNldCA9IHRydWU7Ci0gICAgY2FzZSBPcENvZGVzLk9QX0dST1VQIDoKLSAgICBjYXNlIE9wQ29kZXMuT1BfVkFSSUFCTEUgOgotICAgICAgbV9leHByID0gY29tcGlsZXIuY29tcGlsZShvcFBvcyk7Ci0gICAgICBtX2V4cHIuZXhwclNldFBhcmVudCh0aGlzKTsKLSAgICAgIC8vaWYoKE9wQ29kZXMuT1BfRlVOQ1RJT04gPT0gc3RlcFR5cGUpICYmIChtX2V4cHIgaW5zdGFuY2VvZiBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwudGVtcGxhdGVzLkZ1bmNLZXkpKQotICAgICAgaWYobV9leHByIGluc3RhbmNlb2YgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9wZXJhdGlvbnMuVmFyaWFibGUpCi0gICAgICB7Ci0gICAgICAgIC8vIGhhY2svdGVtcCB3b3JrYXJvdW5kCi0gICAgICAgIG1fY2FuRGV0YWNoTm9kZXNldCA9IGZhbHNlOwotICAgICAgfQotICAgICAgYnJlYWs7Ci0gICAgZGVmYXVsdCA6Ci0gICAgICBtX2V4cHIgPSBjb21waWxlci5jb21waWxlKG9wUG9zICsgMik7Ci0gICAgICBtX2V4cHIuZXhwclNldFBhcmVudCh0aGlzKTsKLSAgICB9Ci0vLyAgICBpZihtX2V4cHIgaW5zdGFuY2VvZiBXYWxraW5nSXRlcmF0b3IpCi0vLyAgICB7Ci0vLyAgICAgIFdhbGtpbmdJdGVyYXRvciB3aSA9IChXYWxraW5nSXRlcmF0b3IpbV9leHByOwotLy8gICAgICBpZih3aS5nZXRGaXJzdFdhbGtlcigpIGluc3RhbmNlb2YgRmlsdGVyRXhwcldhbGtlcikKLS8vICAgICAgewotLy8gICAgICAgICAgICAgIEZpbHRlckV4cHJXYWxrZXIgZncgPSAoRmlsdGVyRXhwcldhbGtlcil3aS5nZXRGaXJzdFdhbGtlcigpOwotLy8gICAgICAgICAgICAgIGlmKG51bGwgPT0gZncuZ2V0TmV4dFdhbGtlcigpKQotLy8gICAgICAgICAgICAgIHsKLS8vICAgICAgICAgICAgICAgICAgICAgIG1fZXhwciA9IGZ3Lm1fZXhwcjsKLS8vICAgICAgICAgICAgICAgICAgICAgIG1fZXhwci5leHByU2V0UGFyZW50KHRoaXMpOwotLy8gICAgICAgICAgICAgIH0KLS8vICAgICAgfQotLy8KLS8vICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBEZXRhY2hlcyB0aGUgd2Fsa2VyIGZyb20gdGhlIHNldCB3aGljaCBpdCBpdGVyYXRlZCBvdmVyLCByZWxlYXNpbmcKLSAgICogYW55IGNvbXB1dGF0aW9uYWwgcmVzb3VyY2VzIGFuZCBwbGFjaW5nIHRoZSBpdGVyYXRvciBpbiB0aGUgSU5WQUxJRAotICAgKiBzdGF0ZS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGRldGFjaCgpCi0gIHsKLSAgICAgICAgc3VwZXIuZGV0YWNoKCk7Ci0gICAgICAgIGlmIChtX2NhbkRldGFjaE5vZGVzZXQpCi0gICAgICAgIHsKLSAgICAgICAgICBtX2V4cHJPYmouZGV0YWNoKCk7Ci0gICAgICAgIH0KLSAgICAgICAgbV9leHByT2JqID0gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiAgU2V0IHRoZSByb290IG5vZGUgb2YgdGhlIFRyZWVXYWxrZXIuCi0gICAqCi0gICAqIEBwYXJhbSByb290IG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgcm9vdCwgb3Igc3RhcnRpbmcgcG9pbnQgb2YKLSAgICogICAgICAgIHRoZSBxdWVyeS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFJvb3QoaW50IHJvb3QpCi0gIHsKLQotICAgIHN1cGVyLnNldFJvb3Qocm9vdCk7Ci0KLSAgICAgICAgbV9leHByT2JqID0gRmlsdGVyRXhwckl0ZXJhdG9yU2ltcGxlLmV4ZWN1dGVGaWx0ZXJFeHByKHJvb3QsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIG1fbHBpLmdldFhQYXRoQ29udGV4dCgpLCBtX2xwaS5nZXRQcmVmaXhSZXNvbHZlcigpLAotICAgICAgICAgICAgICAgICAgICAgICAgICBtX2xwaS5nZXRJc1RvcExldmVsKCksIG1fbHBpLm1fc3RhY2tGcmFtZSwgbV9leHByKTsKLQotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBhIGNsb25lZCBGaWx0ZXJFeHByV2Fsa2VyLgotICAgKgotICAgKiBAcmV0dXJuIEEgbmV3IEZpbHRlckV4cHJXYWxrZXIgdGhhdCBjYW4gYmUgdXNlZCB3aXRob3V0IG11dGF0aW5nIHRoaXMgb25lLgotICAgKgotICAgKiBAdGhyb3dzIENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgT2JqZWN0IGNsb25lKCkgdGhyb3dzIENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uCi0gIHsKLQotICAgIEZpbHRlckV4cHJXYWxrZXIgY2xvbmUgPSAoRmlsdGVyRXhwcldhbGtlcikgc3VwZXIuY2xvbmUoKTsKLQotICAgIC8vIGNsb25lLm1fZXhwciA9IChFeHByZXNzaW9uKSgoRXhwcmVzc2lvbiltX2V4cHIpLmNsb25lKCk7Ci0gICAgaWYgKG51bGwgIT0gbV9leHByT2JqKQotICAgICAgY2xvbmUubV9leHByT2JqID0gKFhOb2RlU2V0KSBtX2V4cHJPYmouY2xvbmUoKTsKLQotICAgIHJldHVybiBjbG9uZTsKLSAgfQotCi0gIC8qKgotICAgKiBUaGlzIG1ldGhvZCBuZWVkcyB0byBvdmVycmlkZSBBeGVzV2Fsa2VyLmFjY2VwdE5vZGUgYmVjYXVzZSBGaWx0ZXJFeHByV2Fsa2VycwotICAgKiBkb24ndCBuZWVkIHRvLCBhbmQgc2hvdWxkbid0LCBkbyBhIG5vZGUgdGVzdC4KLSAgICogQHBhcmFtIG4gIFRoZSBub2RlIHRvIGNoZWNrIHRvIHNlZSBpZiBpdCBwYXNzZXMgdGhlIGZpbHRlciBvciBub3QuCi0gICAqIEByZXR1cm4gIGEgY29uc3RhbnQgdG8gZGV0ZXJtaW5lIHdoZXRoZXIgdGhlIG5vZGUgaXMgYWNjZXB0ZWQsCi0gICAqICAgcmVqZWN0ZWQsIG9yIHNraXBwZWQsIGFzIGRlZmluZWQgIGFib3ZlIC4KLSAgICovCi0gIHB1YmxpYyBzaG9ydCBhY2NlcHROb2RlKGludCBuKQotICB7Ci0KLSAgICB0cnkKLSAgICB7Ci0gICAgICBpZiAoZ2V0UHJlZGljYXRlQ291bnQoKSA+IDApCi0gICAgICB7Ci0gICAgICAgIGNvdW50UHJveGltaXR5UG9zaXRpb24oMCk7Ci0KLSAgICAgICAgaWYgKCFleGVjdXRlUHJlZGljYXRlcyhuLCBtX2xwaS5nZXRYUGF0aENvbnRleHQoKSkpCi0gICAgICAgICAgcmV0dXJuIERUTUl0ZXJhdG9yLkZJTFRFUl9TS0lQOwotICAgICAgfQotCi0gICAgICByZXR1cm4gRFRNSXRlcmF0b3IuRklMVEVSX0FDQ0VQVDsKLSAgICB9Ci0gICAgY2F0Y2ggKGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24gc2UpCi0gICAgewotICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oc2UuZ2V0TWVzc2FnZSgpKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogIE1vdmVzIHRoZSA8Y29kZT5UcmVlV2Fsa2VyPC9jb2RlPiB0byB0aGUgbmV4dCB2aXNpYmxlIG5vZGUgaW4gZG9jdW1lbnQKLSAgICogb3JkZXIgcmVsYXRpdmUgdG8gdGhlIGN1cnJlbnQgbm9kZSwgYW5kIHJldHVybnMgdGhlIG5ldyBub2RlLiBJZiB0aGUKLSAgICogY3VycmVudCBub2RlIGhhcyBubyBuZXh0IG5vZGUsICBvciBpZiB0aGUgc2VhcmNoIGZvciBuZXh0Tm9kZSBhdHRlbXB0cwotICAgKiB0byBzdGVwIHVwd2FyZCBmcm9tIHRoZSBUcmVlV2Fsa2VyJ3Mgcm9vdCBub2RlLCByZXR1cm5zCi0gICAqIDxjb2RlPm51bGw8L2NvZGU+ICwgYW5kIHJldGFpbnMgdGhlIGN1cnJlbnQgbm9kZS4KLSAgICogQHJldHVybiAgVGhlIG5ldyBub2RlLCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGUgY3VycmVudCBub2RlIGhhcyBubwotICAgKiAgIG5leHQgbm9kZSAgaW4gdGhlIFRyZWVXYWxrZXIncyBsb2dpY2FsIHZpZXcuCi0gICAqLwotICBwdWJsaWMgaW50IGdldE5leHROb2RlKCkKLSAgewotCi0gICAgaWYgKG51bGwgIT0gbV9leHByT2JqKQotICAgIHsKLSAgICAgICBpbnQgbmV4dCA9IG1fZXhwck9iai5uZXh0Tm9kZSgpOwotICAgICAgIHJldHVybiBuZXh0OwotICAgIH0KLSAgICBlbHNlCi0gICAgICByZXR1cm4gRFRNLk5VTEw7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBpbmRleCBvZiB0aGUgbGFzdCBub2RlIHRoYXQgY2FuIGJlIGl0dGVyYXRlZCB0by4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IFhQYXRoIHJ1bnRpbWUgY29udGV4dC4KLSAgICoKLSAgICogQHJldHVybiB0aGUgaW5kZXggb2YgdGhlIGxhc3Qgbm9kZSB0aGF0IGNhbiBiZSBpdHRlcmF0ZWQgdG8uCi0gICAqLwotICBwdWJsaWMgaW50IGdldExhc3RQb3MoWFBhdGhDb250ZXh0IHhjdHh0KQotICB7Ci0gICAgcmV0dXJuIG1fZXhwck9iai5nZXRMZW5ndGgoKTsKLSAgfQotCi0gIC8qKiBUaGUgY29udGFpbmVkIGV4cHJlc3Npb24uIFNob3VsZCBiZSBub24tbnVsbC4KLSAgICogIEBzZXJpYWwgICAqLwotICBwcml2YXRlIEV4cHJlc3Npb24gbV9leHByOwotCi0gIC8qKiBUaGUgcmVzdWx0IG9mIGV4ZWN1dGluZyBtX2V4cHIuICBOZWVkcyB0byBiZSBkZWVwIGNsb25lZCBvbiBjbG9uZSBvcC4gICovCi0gIHRyYW5zaWVudCBwcml2YXRlIFhOb2RlU2V0IG1fZXhwck9iajsKLQotICBwcml2YXRlIGJvb2xlYW4gbV9tdXN0SGFyZFJlc2V0ID0gZmFsc2U7Ci0gIHByaXZhdGUgYm9vbGVhbiBtX2NhbkRldGFjaE5vZGVzZXQgPSB0cnVlOwotCi0gIC8qKgotICAgKiBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgdG8gZml4dXAgdmFyaWFibGVzIGZyb20gUU5hbWVzIHRvIHN0YWNrIGZyYW1lCi0gICAqIGluZGV4ZXMgYXQgc3R5bGVzaGVldCBidWlsZCB0aW1lLgotICAgKiBAcGFyYW0gdmFycyBMaXN0IG9mIFFOYW1lcyB0aGF0IGNvcnJlc3BvbmQgdG8gdmFyaWFibGVzLiAgVGhpcyBsaXN0Ci0gICAqIHNob3VsZCBiZSBzZWFyY2hlZCBiYWNrd2FyZHMgZm9yIHRoZSBmaXJzdCBxdWFsaWZpZWQgbmFtZSB0aGF0Ci0gICAqIGNvcnJlc3BvbmRzIHRvIHRoZSB2YXJpYWJsZSByZWZlcmVuY2UgcW5hbWUuICBUaGUgcG9zaXRpb24gb2YgdGhlCi0gICAqIFFOYW1lIGluIHRoZSB2ZWN0b3IgZnJvbSB0aGUgc3RhcnQgb2YgdGhlIHZlY3RvciB3aWxsIGJlIGl0cyBwb3NpdGlvbgotICAgKiBpbiB0aGUgc3RhY2sgZnJhbWUgKGJ1dCB2YXJpYWJsZXMgYWJvdmUgdGhlIGdsb2JhbHNUb3AgdmFsdWUgd2lsbCBuZWVkCi0gICAqIHRvIGJlIG9mZnNldCB0byB0aGUgY3VycmVudCBzdGFjayBmcmFtZSkuCi0gICAqLwotICBwdWJsaWMgdm9pZCBmaXh1cFZhcmlhYmxlcyhqYXZhLnV0aWwuVmVjdG9yIHZhcnMsIGludCBnbG9iYWxzU2l6ZSkKLSAgewotICAgIHN1cGVyLmZpeHVwVmFyaWFibGVzKHZhcnMsIGdsb2JhbHNTaXplKTsKLSAgICBtX2V4cHIuZml4dXBWYXJpYWJsZXModmFycywgZ2xvYmFsc1NpemUpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgaW5uZXIgY29udGFpbmVkIGV4cHJlc3Npb24gb2YgdGhpcyBmaWx0ZXIuCi0gICAqLwotICBwdWJsaWMgRXhwcmVzc2lvbiBnZXRJbm5lckV4cHJlc3Npb24oKQotICB7Ci0gICAgICAgIHJldHVybiBtX2V4cHI7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBpbm5lciBjb250YWluZWQgZXhwcmVzc2lvbiBvZiB0aGlzIGZpbHRlci4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldElubmVyRXhwcmVzc2lvbihFeHByZXNzaW9uIGV4cHIpCi0gIHsKLSAgICAgICAgZXhwci5leHByU2V0UGFyZW50KHRoaXMpOwotICAgICAgICBtX2V4cHIgPSBleHByOwotICB9Ci0KLQotICAvKioKLSAgICogR2V0IHRoZSBhbmFseXNpcyBiaXRzIGZvciB0aGlzIHdhbGtlciwgYXMgZGVmaW5lZCBpbiB0aGUgV2Fsa2VyRmFjdG9yeS4KLSAgICogQHJldHVybiBPbmUgb2YgV2Fsa2VyRmFjdG9yeSNCSVRfREVTQ0VOREFOVCwgZXRjLgotICAgKi8KLSAgcHVibGljIGludCBnZXRBbmFseXNpc0JpdHMoKQotICB7Ci0gICAgICBpZiAobnVsbCAhPSBtX2V4cHIgJiYgbV9leHByIGluc3RhbmNlb2YgUGF0aENvbXBvbmVudCkKLSAgICAgIHsKLSAgICAgICAgcmV0dXJuICgoUGF0aENvbXBvbmVudCkgbV9leHByKS5nZXRBbmFseXNpc0JpdHMoKTsKLSAgICAgIH0KLSAgICAgIHJldHVybiBXYWxrZXJGYWN0b3J5LkJJVF9GSUxURVI7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyB0cnVlIGlmIGFsbCB0aGUgbm9kZXMgaW4gdGhlIGl0ZXJhdGlvbiB3ZWxsIGJlIHJldHVybmVkIGluIGRvY3VtZW50Ci0gICAqIG9yZGVyLgotICAgKiBXYXJuaW5nOiBUaGlzIGNhbiBvbmx5IGJlIGNhbGxlZCBhZnRlciBzZXRSb290IGhhcyBiZWVuIGNhbGxlZCEKLSAgICoKLSAgICogQHJldHVybiB0cnVlIGFzIGEgZGVmYXVsdC4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzRG9jT3JkZXJlZCgpCi0gIHsKLSAgICByZXR1cm4gbV9leHByT2JqLmlzRG9jT3JkZXJlZCgpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIGF4aXMgYmVpbmcgaXRlcmF0ZWQsIGlmIGl0IGlzIGtub3duLgotICAgKgotICAgKiBAcmV0dXJuIEF4aXMuQ0hJTEQsIGV0Yy4sIG9yIC0xIGlmIHRoZSBheGlzIGlzIG5vdCBrbm93biBvciBpcyBvZiBtdWx0aXBsZQotICAgKiB0eXBlcy4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0QXhpcygpCi0gIHsKLSAgICByZXR1cm4gbV9leHByT2JqLmdldEF4aXMoKTsKLSAgfQotCi0gIGNsYXNzIGZpbHRlckV4cHJPd25lciBpbXBsZW1lbnRzIEV4cHJlc3Npb25Pd25lcgotICB7Ci0gICAgICAvKioKLSAgICAgKiBAc2VlIEV4cHJlc3Npb25Pd25lciNnZXRFeHByZXNzaW9uKCkKLSAgICAgKi8KLSAgICBwdWJsaWMgRXhwcmVzc2lvbiBnZXRFeHByZXNzaW9uKCkKLSAgICB7Ci0gICAgICByZXR1cm4gbV9leHByOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgRXhwcmVzc2lvbk93bmVyI3NldEV4cHJlc3Npb24oRXhwcmVzc2lvbikKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRFeHByZXNzaW9uKEV4cHJlc3Npb24gZXhwKQotICAgIHsKLSAgICAgICAgZXhwLmV4cHJTZXRQYXJlbnQoRmlsdGVyRXhwcldhbGtlci50aGlzKTsKLSAgICAgICAgbV9leHByID0gZXhwOwotICAgIH0KLSAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBUaGlzIHdpbGwgdHJhdmVyc2UgdGhlIGhlYXJhcmNoeSwgY2FsbGluZyB0aGUgdmlzaXRvciBmb3IKLSAgICAgICAgICogZWFjaCBtZW1iZXIuICBJZiB0aGUgY2FsbGVkIHZpc2l0b3IgbWV0aG9kIHJldHVybnMKLSAgICAgICAgICogZmFsc2UsIHRoZSBzdWJ0cmVlIHNob3VsZCBub3QgYmUgY2FsbGVkLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gdmlzaXRvciBUaGUgdmlzaXRvciB3aG9zZSBhcHByb3ByaWF0ZSBtZXRob2Qgd2lsbCBiZSBjYWxsZWQuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgdm9pZCBjYWxsUHJlZGljYXRlVmlzaXRvcnMoWFBhdGhWaXNpdG9yIHZpc2l0b3IpCi0gICAgICAgIHsKLSAgICAgICAgICBtX2V4cHIuY2FsbFZpc2l0b3JzKG5ldyBmaWx0ZXJFeHByT3duZXIoKSwgdmlzaXRvcik7Ci0KLSAgICAgICAgICBzdXBlci5jYWxsUHJlZGljYXRlVmlzaXRvcnModmlzaXRvcik7Ci0gICAgICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogQHNlZSBFeHByZXNzaW9uI2RlZXBFcXVhbHMoRXhwcmVzc2lvbikKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBkZWVwRXF1YWxzKEV4cHJlc3Npb24gZXhwcikKLSAgICB7Ci0gICAgICBpZiAoIXN1cGVyLmRlZXBFcXVhbHMoZXhwcikpCi0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotCi0gICAgICBGaWx0ZXJFeHByV2Fsa2VyIHdhbGtlciA9IChGaWx0ZXJFeHByV2Fsa2VyKWV4cHI7Ci0gICAgICBpZighbV9leHByLmRlZXBFcXVhbHMod2Fsa2VyLm1fZXhwcikpCi0gICAgICAgIHJldHVybiBmYWxzZTsKLQotICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotCi0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9heGVzL0hhc1Bvc2l0aW9uYWxQcmVkQ2hlY2tlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9heGVzL0hhc1Bvc2l0aW9uYWxQcmVkQ2hlY2tlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiMDg5ZWMwLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvYXhlcy9IYXNQb3NpdGlvbmFsUHJlZENoZWNrZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEyNSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBIYXNQb3NpdGlvbmFsUHJlZENoZWNrZXIuamF2YSx2IDEuMS4yLjEgMjAwNS8wOC8wMSAwMTozMDoyNCBqZWZmc3V0dG9yIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmF4ZXM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuRXhwcmVzc2lvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuRXhwcmVzc2lvbk93bmVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5YUGF0aFZpc2l0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmZ1bmN0aW9ucy5GdW5jTGFzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuZnVuY3Rpb25zLkZ1bmNQb3NpdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuZnVuY3Rpb25zLkZ1bmN0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhOdW1iZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9wZXJhdGlvbnMuRGl2OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vcGVyYXRpb25zLk1pbnVzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vcGVyYXRpb25zLk1vZDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub3BlcmF0aW9ucy5NdWx0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vcGVyYXRpb25zLlBsdXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9wZXJhdGlvbnMuUXVvOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vcGVyYXRpb25zLlZhcmlhYmxlOwotCi1wdWJsaWMgY2xhc3MgSGFzUG9zaXRpb25hbFByZWRDaGVja2VyIGV4dGVuZHMgWFBhdGhWaXNpdG9yCi17Ci0gICAgICAgIHByaXZhdGUgYm9vbGVhbiBtX2hhc1Bvc2l0aW9uYWxQcmVkID0gZmFsc2U7Ci0gICAgICAgIHByaXZhdGUgaW50IG1fcHJlZERlcHRoID0gMDsKLQotICAgICAgICAvKioKLSAgICAgICAgICogUHJvY2VzcyB0aGUgTG9jUGF0aEl0ZXJhdG9yIHRvIHNlZSBpZiBpdCBjb250YWlucyB2YXJpYWJsZXMKLSAgICAgICAgICogb3IgZnVuY3Rpb25zIHRoYXQgbWF5IG1ha2UgaXQgY29udGV4dCBkZXBlbmRlbnQuCi0gICAgICAgICAqIEBwYXJhbSBwYXRoIExvY1BhdGhJdGVyYXRvciB0aGF0IGlzIGFzc3VtZWQgdG8gYmUgYWJzb2x1dGUsIGJ1dCBuZWVkcyBjaGVja2luZy4KLSAgICAgICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBwYXRoIGlzIGNvbmZpcm1lZCB0byBiZSBhYnNvbHV0ZSwgZmFsc2UgaWYgaXQKLSAgICAgICAgICogbWF5IGNvbnRhaW4gY29udGV4dCBkZXBlbmRlbmNpZXMuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gY2hlY2soTG9jUGF0aEl0ZXJhdG9yIHBhdGgpCi0gICAgICAgIHsKLSAgICAgICAgICAgICAgICBIYXNQb3NpdGlvbmFsUHJlZENoZWNrZXIgaHBwYyA9IG5ldyBIYXNQb3NpdGlvbmFsUHJlZENoZWNrZXIoKTsKLSAgICAgICAgICAgICAgICBwYXRoLmNhbGxWaXNpdG9ycyhudWxsLCBocHBjKTsKLSAgICAgICAgICAgICAgICByZXR1cm4gaHBwYy5tX2hhc1Bvc2l0aW9uYWxQcmVkOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFZpc2l0IGEgZnVuY3Rpb24uCi0gICAgICAgICAqIEBwYXJhbSBvd25lciBUaGUgb3duZXIgb2YgdGhlIGV4cHJlc3Npb24sIHRvIHdoaWNoIHRoZSBleHByZXNzaW9uIGNhbgotICAgICAgICAgKiAgICAgICAgICAgICAgYmUgcmVzZXQgaWYgcmV3cml0aW5nIHRha2VzIHBsYWNlLgotICAgICAgICAgKiBAcGFyYW0gZnVuYyBUaGUgZnVuY3Rpb24gcmVmZXJlbmNlIG9iamVjdC4KLSAgICAgICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBzdWIgZXhwcmVzc2lvbnMgc2hvdWxkIGJlIHRyYXZlcnNlZC4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBib29sZWFuIHZpc2l0RnVuY3Rpb24oRXhwcmVzc2lvbk93bmVyIG93bmVyLCBGdW5jdGlvbiBmdW5jKQotICAgICAgICB7Ci0gICAgICAgICAgICAgICAgaWYoKGZ1bmMgaW5zdGFuY2VvZiBGdW5jUG9zaXRpb24pIHx8Ci0gICAgICAgICAgICAgICAgICAgKGZ1bmMgaW5zdGFuY2VvZiBGdW5jTGFzdCkpCi0gICAgICAgICAgICAgICAgICAgICAgICBtX2hhc1Bvc2l0aW9uYWxQcmVkID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgfQotCi0vLyAgICAgIC8qKgotLy8gICAgICAgKiBWaXNpdCBhIHZhcmlhYmxlIHJlZmVyZW5jZS4KLS8vICAgICAgICogQHBhcmFtIG93bmVyIFRoZSBvd25lciBvZiB0aGUgZXhwcmVzc2lvbiwgdG8gd2hpY2ggdGhlIGV4cHJlc3Npb24gY2FuCi0vLyAgICAgICAqICAgICAgICAgICAgICBiZSByZXNldCBpZiByZXdyaXRpbmcgdGFrZXMgcGxhY2UuCi0vLyAgICAgICAqIEBwYXJhbSB2YXIgVGhlIHZhcmlhYmxlIHJlZmVyZW5jZSBvYmplY3QuCi0vLyAgICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgc3ViIGV4cHJlc3Npb25zIHNob3VsZCBiZSB0cmF2ZXJzZWQuCi0vLyAgICAgICAqLwotLy8gICAgICBwdWJsaWMgYm9vbGVhbiB2aXNpdFZhcmlhYmxlUmVmKEV4cHJlc3Npb25Pd25lciBvd25lciwgVmFyaWFibGUgdmFyKQotLy8gICAgICB7Ci0vLyAgICAgICAgICAgICAgbV9oYXNQb3NpdGlvbmFsUHJlZCA9IHRydWU7Ci0vLyAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0vLyAgICAgIH0KLQotICAvKioKLSAgICogVmlzaXQgYSBwcmVkaWNhdGUgd2l0aGluIGEgbG9jYXRpb24gcGF0aC4gIE5vdGUgdGhhdCB0aGVyZSBpc24ndCBhCi0gICAqIHByb3BlciB1bmlxdWUgY29tcG9uZW50IGZvciBwcmVkaWNhdGVzLCBhbmQgdGhhdCB0aGUgZXhwcmVzc2lvbiB3aWxsCi0gICAqIGJlIGNhbGxlZCBhbHNvIGZvciB3aGF0ZXZlciB0eXBlIEV4cHJlc3Npb24gaXMuCi0gICAqCi0gICAqIEBwYXJhbSBvd25lciBUaGUgb3duZXIgb2YgdGhlIGV4cHJlc3Npb24sIHRvIHdoaWNoIHRoZSBleHByZXNzaW9uIGNhbgotICAgKiAgICAgICAgICAgICAgYmUgcmVzZXQgaWYgcmV3cml0aW5nIHRha2VzIHBsYWNlLgotICAgKiBAcGFyYW0gcHJlZCBUaGUgcHJlZGljYXRlIG9iamVjdC4KLSAgICogQHJldHVybiB0cnVlIGlmIHRoZSBzdWIgZXhwcmVzc2lvbnMgc2hvdWxkIGJlIHRyYXZlcnNlZC4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIHZpc2l0UHJlZGljYXRlKEV4cHJlc3Npb25Pd25lciBvd25lciwgRXhwcmVzc2lvbiBwcmVkKQotICB7Ci0gICAgbV9wcmVkRGVwdGgrKzsKLQotICAgIGlmKG1fcHJlZERlcHRoID09IDEpCi0gICAgewotICAgICAgaWYoKHByZWQgaW5zdGFuY2VvZiBWYXJpYWJsZSkgfHwKLSAgICAgICAgIChwcmVkIGluc3RhbmNlb2YgWE51bWJlcikgfHwKLSAgICAgICAgIChwcmVkIGluc3RhbmNlb2YgRGl2KSB8fAotICAgICAgICAgKHByZWQgaW5zdGFuY2VvZiBQbHVzKSB8fAotICAgICAgICAgKHByZWQgaW5zdGFuY2VvZiBNaW51cykgfHwKLSAgICAgICAgIChwcmVkIGluc3RhbmNlb2YgTW9kKSB8fAotICAgICAgICAgKHByZWQgaW5zdGFuY2VvZiBRdW8pIHx8Ci0gICAgICAgICAocHJlZCBpbnN0YW5jZW9mIE11bHQpIHx8Ci0gICAgICAgICAocHJlZCBpbnN0YW5jZW9mIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vcGVyYXRpb25zLk51bWJlcikgfHwKLSAgICAgICAgIChwcmVkIGluc3RhbmNlb2YgRnVuY3Rpb24pKQotICAgICAgICAgIG1faGFzUG9zaXRpb25hbFByZWQgPSB0cnVlOwotICAgICAgZWxzZQotICAgICAgICBwcmVkLmNhbGxWaXNpdG9ycyhvd25lciwgdGhpcyk7Ci0gICAgfQotCi0gICAgbV9wcmVkRGVwdGgtLTsKLQotICAgIC8vIERvbid0IGdvIGhhdmUgdGhlIGNhbGxlciBnbyBhbnkgZnVydGhlciBkb3duIHRoZSBzdWJ0cmVlLgotICAgIHJldHVybiBmYWxzZTsKLSAgfQotCi0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvYXhlcy9JdGVyYXRvclBvb2wuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvYXhlcy9JdGVyYXRvclBvb2wuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggY2NhY2EzMS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2F4ZXMvSXRlcmF0b3JQb29sLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMjEgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogSXRlcmF0b3JQb29sLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTQgMTk6NDU6MTkgamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5heGVzOwotCi1pbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTUl0ZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuV3JhcHBlZFJ1bnRpbWVFeGNlcHRpb247Ci0KLS8qKgotICogUG9vbCBvZiBvYmplY3Qgb2YgYSBnaXZlbiB0eXBlIHRvIHBpY2sgZnJvbSB0byBoZWxwIG1lbW9yeSB1c2FnZQotICogQHhzbC51c2FnZSBpbnRlcm5hbAotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgSXRlcmF0b3JQb29sIGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUKLXsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTQ2MDkyNzMzMTE0OTU2Njk5OEw7Ci0KLSAgLyoqCi0gICAqIFR5cGUgb2Ygb2JqZWN0cyBpbiB0aGlzIHBvb2wuCi0gICAqLwotICBwcml2YXRlIGZpbmFsIERUTUl0ZXJhdG9yIG1fb3JpZzsKLQotICAvKioKLSAgICogU3RhY2sgb2YgZ2l2ZW4gb2JqZWN0cyB0aGlzIHBvaW50cyB0by4KLSAgICovCi0gIHByaXZhdGUgZmluYWwgQXJyYXlMaXN0IG1fZnJlZVN0YWNrOwotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3RvciBJdGVyYXRvclBvb2wKLSAgICoKLSAgICogQHBhcmFtIG9yaWdpbmFsIFRoZSBvcmlnaW5hbCBpdGVyYXRvciBmcm9tIHdoaWNoIGFsbCBvdGhlcnMgd2lsbCBiZSBjbG9uZWQuCi0gICAqLwotICBwdWJsaWMgSXRlcmF0b3JQb29sKERUTUl0ZXJhdG9yIG9yaWdpbmFsKQotICB7Ci0gICAgbV9vcmlnID0gb3JpZ2luYWw7Ci0gICAgbV9mcmVlU3RhY2sgPSBuZXcgQXJyYXlMaXN0KCk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IGFuIGluc3RhbmNlIG9mIHRoZSBnaXZlbiBvYmplY3QgaW4gdGhpcyBwb29sCi0gICAqCi0gICAqIEByZXR1cm4gQW4gaW5zdGFuY2Ugb2YgdGhlIGdpdmVuIG9iamVjdAotICAgKi8KLSAgcHVibGljIHN5bmNocm9uaXplZCBEVE1JdGVyYXRvciBnZXRJbnN0YW5jZU9yVGhyb3coKQotICAgIHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbgotICB7Ci0gICAgLy8gQ2hlY2sgaWYgdGhlIHBvb2wgaXMgZW1wdHkuCi0gICAgaWYgKG1fZnJlZVN0YWNrLmlzRW1wdHkoKSkKLSAgICB7Ci0KLSAgICAgIC8vIENyZWF0ZSBhIG5ldyBvYmplY3QgaWYgc28uCi0gICAgICByZXR1cm4gKERUTUl0ZXJhdG9yKW1fb3JpZy5jbG9uZSgpOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgLy8gUmVtb3ZlIG9iamVjdCBmcm9tIGVuZCBvZiBmcmVlIHBvb2wuCi0gICAgICBEVE1JdGVyYXRvciByZXN1bHQgPSAoRFRNSXRlcmF0b3IpbV9mcmVlU3RhY2sucmVtb3ZlKG1fZnJlZVN0YWNrLnNpemUoKSAtIDEpOwotICAgICAgcmV0dXJuIHJlc3VsdDsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogR2V0IGFuIGluc3RhbmNlIG9mIHRoZSBnaXZlbiBvYmplY3QgaW4gdGhpcyBwb29sCi0gICAqCi0gICAqIEByZXR1cm4gQW4gaW5zdGFuY2Ugb2YgdGhlIGdpdmVuIG9iamVjdAotICAgKi8KLSAgcHVibGljIHN5bmNocm9uaXplZCBEVE1JdGVyYXRvciBnZXRJbnN0YW5jZSgpCi0gIHsKLSAgICAvLyBDaGVjayBpZiB0aGUgcG9vbCBpcyBlbXB0eS4KLSAgICBpZiAobV9mcmVlU3RhY2suaXNFbXB0eSgpKQotICAgIHsKLQotICAgICAgLy8gQ3JlYXRlIGEgbmV3IG9iamVjdCBpZiBzby4KLSAgICAgIHRyeQotICAgICAgewotICAgICAgICByZXR1cm4gKERUTUl0ZXJhdG9yKW1fb3JpZy5jbG9uZSgpOwotICAgICAgfQotICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkKLSAgICAgIHsKLSAgICAgICAgdGhyb3cgbmV3IFdyYXBwZWRSdW50aW1lRXhjZXB0aW9uKGV4KTsKLSAgICAgIH0KLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIC8vIFJlbW92ZSBvYmplY3QgZnJvbSBlbmQgb2YgZnJlZSBwb29sLgotICAgICAgRFRNSXRlcmF0b3IgcmVzdWx0ID0gKERUTUl0ZXJhdG9yKW1fZnJlZVN0YWNrLnJlbW92ZShtX2ZyZWVTdGFjay5zaXplKCkgLSAxKTsKLSAgICAgIHJldHVybiByZXN1bHQ7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEFkZCBhbiBpbnN0YW5jZSBvZiB0aGUgZ2l2ZW4gb2JqZWN0IHRvIHRoZSBwb29sCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBvYmogT2JqZWN0IHRvIGFkZC4KLSAgICovCi0gIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBmcmVlSW5zdGFuY2UoRFRNSXRlcmF0b3Igb2JqKQotICB7Ci0gICAgbV9mcmVlU3RhY2suYWRkKG9iaik7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvYXhlcy9Mb2NQYXRoSXRlcmF0b3IuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvYXhlcy9Mb2NQYXRoSXRlcmF0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNDAwZTY5ZC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2F4ZXMvTG9jUGF0aEl0ZXJhdG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMDM1ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IExvY1BhdGhJdGVyYXRvci5qYXZhLHYgMS4yLjQuMiAyMDA1LzA5LzE0IDE5OjQ1OjIyIGplZmZzdXR0b3IgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuYXhlczsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC5yZXMuWFNMTWVzc2FnZXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTUZpbHRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1JdGVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1NYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuUHJlZml4UmVzb2x2ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLkV4cHJlc3Npb25Pd25lcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuWFBhdGhDb250ZXh0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5YUGF0aFZpc2l0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmNvbXBpbGVyLkNvbXBpbGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhOb2RlU2V0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhPYmplY3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLnJlcy5YUEFUSEVycm9yUmVzb3VyY2VzOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgZXh0ZW5kcyBOb2RlU2V0RFRNLCB3aGljaCBpbXBsZW1lbnRzIE5vZGVJdGVyYXRvciwKLSAqIGFuZCBmZXRjaGVzIG5vZGVzIG9uZSBhdCBhIHRpbWUgaW4gZG9jdW1lbnQgb3JkZXIgYmFzZWQgb24gYSBYUGF0aAotICogPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGgjTlQtTG9jYXRpb25QYXRoPkxvY2F0aW9uUGF0aDwvYT4uCi0gKgotICogPHA+SWYgc2V0U2hvdWxkQ2FjaGVOb2Rlcyh0cnVlKSBpcyBjYWxsZWQsCi0gKiBhcyBlYWNoIG5vZGUgaXMgaXRlcmF0ZWQgdmlhIG5leHROb2RlKCksIHRoZSBub2RlIGlzIGFsc28gc3RvcmVkCi0gKiBpbiB0aGUgTm9kZVZlY3Rvciwgc28gdGhhdCBwcmV2aW91c05vZGUoKSBjYW4gZWFzaWx5IGJlIGRvbmUsIGV4Y2VwdCBpbgotICogdGhlIGNhc2Ugd2hlcmUgdGhlIExvY1BhdGhJdGVyYXRvciBpcyAib3duZWQiIGJ5IGEgVW5pb25QYXRoSXRlcmF0b3IsCi0gKiBpbiB3aGljaCBjYXNlIHRoZSBVbmlvblBhdGhJdGVyYXRvciB3aWxsIGNhY2hlIHRoZSBub2Rlcy48L3A+Ci0gKiBAeHNsLnVzYWdlIGFkdmFuY2VkCi0gKi8KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBMb2NQYXRoSXRlcmF0b3IgZXh0ZW5kcyBQcmVkaWNhdGVkTm9kZVRlc3QKLSAgICAgICAgaW1wbGVtZW50cyBDbG9uZWFibGUsIERUTUl0ZXJhdG9yLCBqYXZhLmlvLlNlcmlhbGl6YWJsZSwgUGF0aENvbXBvbmVudAotewotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNDYwMjQ3NjM1NzI2ODQwNTc1NEw7Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIExvY1BhdGhJdGVyYXRvciBvYmplY3QuCi0gICAqCi0gICAqLwotICBwcm90ZWN0ZWQgTG9jUGF0aEl0ZXJhdG9yKCkKLSAgewotICB9Ci0KLQotICAvKioKLSAgICogQ3JlYXRlIGEgTG9jUGF0aEl0ZXJhdG9yIG9iamVjdC4KLSAgICoKLSAgICogQHBhcmFtIG5zY29udGV4dCBUaGUgbmFtZXNwYWNlIGNvbnRleHQgZm9yIHRoaXMgaXRlcmF0b3IsCi0gICAqIHNob3VsZCBiZSBPSyBpZiBudWxsLgotICAgKi8KLSAgcHJvdGVjdGVkIExvY1BhdGhJdGVyYXRvcihQcmVmaXhSZXNvbHZlciBuc2NvbnRleHQpCi0gIHsKLQotICAgIHNldExvY1BhdGhJdGVyYXRvcih0aGlzKTsKLSAgICBtX3ByZWZpeFJlc29sdmVyID0gbnNjb250ZXh0OwotICB9Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIExvY1BhdGhJdGVyYXRvciBvYmplY3QsIGluY2x1ZGluZyBjcmVhdGlvbgotICAgKiBvZiBzdGVwIHdhbGtlcnMgZnJvbSB0aGUgb3Bjb2RlIGxpc3QsIGFuZCBjYWxsIGJhY2sKLSAgICogaW50byB0aGUgQ29tcGlsZXIgdG8gY3JlYXRlIHByZWRpY2F0ZSBleHByZXNzaW9ucy4KLSAgICoKLSAgICogQHBhcmFtIGNvbXBpbGVyIFRoZSBDb21waWxlciB3aGljaCBpcyBjcmVhdGluZwotICAgKiB0aGlzIGV4cHJlc3Npb24uCi0gICAqIEBwYXJhbSBvcFBvcyBUaGUgcG9zaXRpb24gb2YgdGhpcyBpdGVyYXRvciBpbiB0aGUKLSAgICogb3Bjb2RlIGxpc3QgZnJvbSB0aGUgY29tcGlsZXIuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHJvdGVjdGVkIExvY1BhdGhJdGVyYXRvcihDb21waWxlciBjb21waWxlciwgaW50IG9wUG9zLCBpbnQgYW5hbHlzaXMpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHRoaXMoY29tcGlsZXIsIG9wUG9zLCBhbmFseXNpcywgdHJ1ZSk7Ci0gIH0KLQotICAvKioKLSAgICogQ3JlYXRlIGEgTG9jUGF0aEl0ZXJhdG9yIG9iamVjdCwgaW5jbHVkaW5nIGNyZWF0aW9uCi0gICAqIG9mIHN0ZXAgd2Fsa2VycyBmcm9tIHRoZSBvcGNvZGUgbGlzdCwgYW5kIGNhbGwgYmFjawotICAgKiBpbnRvIHRoZSBDb21waWxlciB0byBjcmVhdGUgcHJlZGljYXRlIGV4cHJlc3Npb25zLgotICAgKgotICAgKiBAcGFyYW0gY29tcGlsZXIgVGhlIENvbXBpbGVyIHdoaWNoIGlzIGNyZWF0aW5nCi0gICAqIHRoaXMgZXhwcmVzc2lvbi4KLSAgICogQHBhcmFtIG9wUG9zIFRoZSBwb3NpdGlvbiBvZiB0aGlzIGl0ZXJhdG9yIGluIHRoZQotICAgKiBvcGNvZGUgbGlzdCBmcm9tIHRoZSBjb21waWxlci4KLSAgICogQHBhcmFtIHNob3VsZExvYWRXYWxrZXJzIFRydWUgaWYgd2Fsa2VycyBzaG91bGQgYmUKLSAgICogbG9hZGVkLCBvciBmYWxzZSBpZiB0aGlzIGlzIGEgZGVyaXZlZCBpdGVyYXRvciBhbmQKLSAgICogaXQgZG9lc24ndCB3aXNoIHRvIGxvYWQgY2hpbGQgd2Fsa2Vycy4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwcm90ZWN0ZWQgTG9jUGF0aEl0ZXJhdG9yKAotICAgICAgICAgIENvbXBpbGVyIGNvbXBpbGVyLCBpbnQgb3BQb3MsIGludCBhbmFseXNpcywgYm9vbGVhbiBzaG91bGRMb2FkV2Fsa2VycykKLSAgICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICBzZXRMb2NQYXRoSXRlcmF0b3IodGhpcyk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBhbmFseXNpcyBiaXRzIGZvciB0aGlzIHdhbGtlciwgYXMgZGVmaW5lZCBpbiB0aGUgV2Fsa2VyRmFjdG9yeS4KLSAgICogQHJldHVybiBPbmUgb2YgV2Fsa2VyRmFjdG9yeSNCSVRfREVTQ0VOREFOVCwgZXRjLgotICAgKi8KLSAgcHVibGljIGludCBnZXRBbmFseXNpc0JpdHMoKQotICB7Ci0gICAgICAgIGludCBheGlzID0gZ2V0QXhpcygpOwotICAgICAgICBpbnQgYml0ID0gV2Fsa2VyRmFjdG9yeS5nZXRBbmFseXNpc0JpdEZyb21BeGVzKGF4aXMpOwotICAgICAgICByZXR1cm4gYml0OwotICB9Ci0KLSAgLyoqCi0gICAqIFJlYWQgdGhlIG9iamVjdCBmcm9tIGEgc2VyaWFsaXphdGlvbiBzdHJlYW0uCi0gICAqCi0gICAqIEBwYXJhbSBzdHJlYW0gSW5wdXQgc3RyZWFtIHRvIHJlYWQgZnJvbQotICAgKgotICAgKiBAdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24KLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwcml2YXRlIHZvaWQgcmVhZE9iamVjdChqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtIHN0cmVhbSkKLSAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiwgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgdHJ5Ci0gICAgewotICAgICAgc3RyZWFtLmRlZmF1bHRSZWFkT2JqZWN0KCk7Ci0gICAgICBtX2Nsb25lcyA9ICBuZXcgSXRlcmF0b3JQb29sKHRoaXMpOwotICAgIH0KLSAgICBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBjbmZlKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uKGNuZmUpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIGVudmlyb25tZW50IGluIHdoaWNoIHRoaXMgaXRlcmF0b3Igb3BlcmF0ZXMsIHdoaWNoIHNob3VsZCBwcm92aWRlOgotICAgKiBhIG5vZGUgKHRoZSBjb250ZXh0IG5vZGUuLi4gc2FtZSB2YWx1ZSBhcyAicm9vdCIgZGVmaW5lZCBiZWxvdykKLSAgICogYSBwYWlyIG9mIG5vbi16ZXJvIHBvc2l0aXZlIGludGVnZXJzICh0aGUgY29udGV4dCBwb3NpdGlvbiBhbmQgdGhlIGNvbnRleHQgc2l6ZSkKLSAgICogYSBzZXQgb2YgdmFyaWFibGUgYmluZGluZ3MKLSAgICogYSBmdW5jdGlvbiBsaWJyYXJ5Ci0gICAqIHRoZSBzZXQgb2YgbmFtZXNwYWNlIGRlY2xhcmF0aW9ucyBpbiBzY29wZSBmb3IgdGhlIGV4cHJlc3Npb24uCi0gICAqCi0gICAqIDxwPkF0IHRoaXMgdGltZSB0aGUgZXhhY3QgaW1wbGVtZW50YXRpb24gb2YgdGhpcyBlbnZpcm9ubWVudCBpcyBhcHBsaWNhdGlvbgotICAgKiBkZXBlbmRlbnQuICBQcm9iYWJseSBhIHByb3BlciBpbnRlcmZhY2Ugd2lsbCBiZSBjcmVhdGVkIGZhaXJseSBzb29uLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIGVudmlyb25tZW50IFRoZSBlbnZpcm9ubWVudCBvYmplY3QuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRFbnZpcm9ubWVudChPYmplY3QgZW52aXJvbm1lbnQpCi0gIHsKLSAgICAvLyBuby1vcCBmb3Igbm93LgotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBhbiBpbnN0YW5jZSBvZiBhIERUTSB0aGF0ICJvd25zIiBhIG5vZGUgaGFuZGxlLiAgU2luY2UgYSBub2RlCi0gICAqIGl0ZXJhdG9yIG1heSBiZSBwYXNzZWQgd2l0aG91dCBhIERUTU1hbmFnZXIsIHRoaXMgYWxsb3dzIHRoZQotICAgKiBjYWxsZXIgdG8gZWFzaWx5IGdldCB0aGUgRFRNIHVzaW5nIGp1c3QgdGhlIGl0ZXJhdG9yLgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSB0aGUgbm9kZUhhbmRsZS4KLSAgICoKLSAgICogQHJldHVybiBhIG5vbi1udWxsIERUTSByZWZlcmVuY2UuCi0gICAqLwotICBwdWJsaWMgRFRNIGdldERUTShpbnQgbm9kZUhhbmRsZSkKLSAgewotICAgIC8vICVPUFQlCi0gICAgcmV0dXJuIG1fZXhlY0NvbnRleHQuZ2V0RFRNKG5vZGVIYW5kbGUpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBhbiBpbnN0YW5jZSBvZiB0aGUgRFRNTWFuYWdlci4gIFNpbmNlIGEgbm9kZQotICAgKiBpdGVyYXRvciBtYXkgYmUgcGFzc2VkIHdpdGhvdXQgYSBEVE1NYW5hZ2VyLCB0aGlzIGFsbG93cyB0aGUKLSAgICogY2FsbGVyIHRvIGVhc2lseSBnZXQgdGhlIERUTU1hbmFnZXIgdXNpbmcganVzdCB0aGUgaXRlcmF0b3IuCi0gICAqCi0gICAqIEByZXR1cm4gYSBub24tbnVsbCBEVE1NYW5hZ2VyIHJlZmVyZW5jZS4KLSAgICovCi0gIHB1YmxpYyBEVE1NYW5hZ2VyIGdldERUTU1hbmFnZXIoKQotICB7Ci0gICAgcmV0dXJuIG1fZXhlY0NvbnRleHQuZ2V0RFRNTWFuYWdlcigpOwotICB9Ci0KLSAgLyoqCi0gICAqIEV4ZWN1dGUgdGhpcyBpdGVyYXRvciwgbWVhbmluZyBjcmVhdGUgYSBjbG9uZSB0aGF0IGNhbgotICAgKiBzdG9yZSBzdGF0ZSwgYW5kIGluaXRpYWxpemUgaXQgZm9yIGZhc3QgZXhlY3V0aW9uIGZyb20KLSAgICogdGhlIGN1cnJlbnQgcnVudGltZSBzdGF0ZS4gIFdoZW4gdGhpcyBpcyBjYWxsZWQsIG5vIGFjdHVhbAotICAgKiBxdWVyeSBmcm9tIHRoZSBjdXJyZW50IGNvbnRleHQgbm9kZSBpcyBwZXJmb3JtZWQuCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgWFBhdGggZXhlY3V0aW9uIGNvbnRleHQuCi0gICAqCi0gICAqIEByZXR1cm4gQW4gWE5vZGVTZXQgcmVmZXJlbmNlIHRoYXQgaG9sZHMgdGhpcyBpdGVyYXRvci4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBleGVjdXRlKFhQYXRoQ29udGV4dCB4Y3R4dCkKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBYTm9kZVNldCBpdGVyID0gbmV3IFhOb2RlU2V0KChMb2NQYXRoSXRlcmF0b3IpbV9jbG9uZXMuZ2V0SW5zdGFuY2UoKSk7Ci0KLSAgICBpdGVyLnNldFJvb3QoeGN0eHQuZ2V0Q3VycmVudE5vZGUoKSwgeGN0eHQpOwotCi0gICAgcmV0dXJuIGl0ZXI7Ci0gIH0KLQotICAvKioKLSAgICogRXhlY3V0ZSBhbiBleHByZXNzaW9uIGluIHRoZSBYUGF0aCBydW50aW1lIGNvbnRleHQsIGFuZCByZXR1cm4gdGhlCi0gICAqIHJlc3VsdCBvZiB0aGUgZXhwcmVzc2lvbi4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IFRoZSBYUGF0aCBydW50aW1lIGNvbnRleHQuCi0gICAqIEBwYXJhbSBoYW5kbGVyIFRoZSB0YXJnZXQgY29udGVudCBoYW5kbGVyLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSByZXN1bHQgb2YgdGhlIGV4cHJlc3Npb24gaW4gdGhlIGZvcm0gb2YgYSA8Y29kZT5YT2JqZWN0PC9jb2RlPi4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uIGlmIGEgcnVudGltZSBleGNlcHRpb24KLSAgICogICAgICAgICBvY2N1cnMuCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBleGVjdXRlQ2hhcnNUb0NvbnRlbnRIYW5kbGVyKAotICAgICAgICAgIFhQYXRoQ29udGV4dCB4Y3R4dCwgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIgaGFuZGxlcikKLSAgICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uLAotICAgICAgICAgICAgICAgICAgIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgTG9jUGF0aEl0ZXJhdG9yIGNsb25lID0gKExvY1BhdGhJdGVyYXRvciltX2Nsb25lcy5nZXRJbnN0YW5jZSgpOwotCi0gICAgaW50IGN1cnJlbnQgPSB4Y3R4dC5nZXRDdXJyZW50Tm9kZSgpOwotICAgIGNsb25lLnNldFJvb3QoY3VycmVudCwgeGN0eHQpOwotCi0gICAgaW50IG5vZGUgPSBjbG9uZS5uZXh0Tm9kZSgpOwotICAgIERUTSBkdG0gPSBjbG9uZS5nZXREVE0obm9kZSk7Ci0gICAgY2xvbmUuZGV0YWNoKCk7Ci0KLSAgICBpZihub2RlICE9IERUTS5OVUxMKQotICAgIHsKLSAgICAgIGR0bS5kaXNwYXRjaENoYXJhY3RlcnNFdmVudHMobm9kZSwgaGFuZGxlciwgZmFsc2UpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBHaXZlbiBhbiBzZWxlY3QgZXhwcmVzc2lvbiBhbmQgYSBjb250ZXh0LCBldmFsdWF0ZSB0aGUgWFBhdGgKLSAgICogYW5kIHJldHVybiB0aGUgcmVzdWx0aW5nIGl0ZXJhdG9yLgotICAgKgotICAgKiBAcGFyYW0geGN0eHQgVGhlIGV4ZWN1dGlvbiBjb250ZXh0LgotICAgKiBAcGFyYW0gY29udGV4dE5vZGUgVGhlIG5vZGUgdGhhdCAiLiIgZXhwcmVzc2VzLgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uIHRocm93biBpZiB0aGUgYWN0aXZlIFByb2JsZW1MaXN0ZW5lciBkZWNpZGVzCi0gICAqIHRoZSBlcnJvciBjb25kaXRpb24gaXMgc2V2ZXJlIGVub3VnaCB0byBoYWx0IHByb2Nlc3NpbmcuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKiBAeHNsLnVzYWdlIGV4cGVyaW1lbnRhbAotICAgKi8KLSAgcHVibGljIERUTUl0ZXJhdG9yIGFzSXRlcmF0b3IoCi0gICAgICAgICAgWFBhdGhDb250ZXh0IHhjdHh0LCBpbnQgY29udGV4dE5vZGUpCi0gICAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgWE5vZGVTZXQgaXRlciA9IG5ldyBYTm9kZVNldCgoTG9jUGF0aEl0ZXJhdG9yKW1fY2xvbmVzLmdldEluc3RhbmNlKCkpOwotCi0gICAgaXRlci5zZXRSb290KGNvbnRleHROb2RlLCB4Y3R4dCk7Ci0KLSAgICByZXR1cm4gaXRlcjsKLSAgfQotCi0KLSAgLyoqCi0gICAqIFRlbGwgaWYgdGhlIGV4cHJlc3Npb24gaXMgYSBub2Rlc2V0IGV4cHJlc3Npb24uCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgZXhwcmVzc2lvbiBjYW4gYmUgcmVwcmVzZW50ZWQgYXMgYSBub2Rlc2V0LgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNOb2Rlc2V0RXhwcigpCi0gIHsKLSAgICByZXR1cm4gdHJ1ZTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIGZpcnN0IG5vZGUgb3V0IG9mIHRoZSBub2Rlc2V0LCBpZiB0aGlzIGV4cHJlc3Npb24gaXMKLSAgICogYSBub2Rlc2V0IGV4cHJlc3Npb24uICBUaGlzIGlzIHRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIGZvcgotICAgKiBub2Rlc2V0cy4gIERlcml2ZWQgY2xhc3NlcyBzaG91bGQgdHJ5IGFuZCBvdmVycmlkZSB0aGlzIGFuZCByZXR1cm4gYQotICAgKiB2YWx1ZSB3aXRob3V0IGhhdmluZyB0byBkbyBhIGNsb25lIG9wZXJhdGlvbi4KLSAgICogQHBhcmFtIHhjdHh0IFRoZSBYUGF0aCBydW50aW1lIGNvbnRleHQuCi0gICAqIEByZXR1cm4gdGhlIGZpcnN0IG5vZGUgb3V0IG9mIHRoZSBub2Rlc2V0LCBvciBEVE0uTlVMTC4KLSAgICovCi0gIHB1YmxpYyBpbnQgYXNOb2RlKFhQYXRoQ29udGV4dCB4Y3R4dCkKLSAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgRFRNSXRlcmF0b3IgaXRlciA9IChEVE1JdGVyYXRvciltX2Nsb25lcy5nZXRJbnN0YW5jZSgpOwotCi0gICAgaW50IGN1cnJlbnQgPSB4Y3R4dC5nZXRDdXJyZW50Tm9kZSgpOwotCi0gICAgaXRlci5zZXRSb290KGN1cnJlbnQsIHhjdHh0KTsKLQotICAgIGludCBuZXh0ID0gaXRlci5uZXh0Tm9kZSgpOwotICAgIC8vIG1fY2xvbmVzLmZyZWVJbnN0YW5jZShpdGVyKTsKLSAgICBpdGVyLmRldGFjaCgpOwotICAgIHJldHVybiBuZXh0OwotICB9Ci0KLSAgLyoqCi0gICAqIEV2YWx1YXRlIHRoaXMgb3BlcmF0aW9uIGRpcmVjdGx5IHRvIGEgYm9vbGVhbi4KLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IFRoZSBydW50aW1lIGV4ZWN1dGlvbiBjb250ZXh0LgotICAgKgotICAgKiBAcmV0dXJuIFRoZSByZXN1bHQgb2YgdGhlIG9wZXJhdGlvbiBhcyBhIGJvb2xlYW4uCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gYm9vbChYUGF0aENvbnRleHQgeGN0eHQpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHJldHVybiAoYXNOb2RlKHhjdHh0KSAhPSBEVE0uTlVMTCk7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBTZXQgaWYgdGhpcyBpcyBhbiBpdGVyYXRvciBhdCB0aGUgdXBwZXIgbGV2ZWwgb2YKLSAgICogdGhlIFhQYXRoLgotICAgKgotICAgKiBAcGFyYW0gYiB0cnVlIGlmIHRoaXMgbG9jYXRpb24gcGF0aCBpcyBhdCB0aGUgdG9wIGxldmVsIG9mIHRoZQotICAgKiAgICAgICAgICBleHByZXNzaW9uLgotICAgKiBAeHNsLnVzYWdlIGFkdmFuY2VkCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRJc1RvcExldmVsKGJvb2xlYW4gYikKLSAgewotICAgIG1faXNUb3BMZXZlbCA9IGI7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IGlmIHRoaXMgaXMgYW4gaXRlcmF0b3IgYXQgdGhlIHVwcGVyIGxldmVsIG9mCi0gICAqIHRoZSBYUGF0aC4KLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHRoaXMgbG9jYXRpb24gcGF0aCBpcyBhdCB0aGUgdG9wIGxldmVsIG9mIHRoZQotICAgKiAgICAgICAgICBleHByZXNzaW9uLgotICAgKiBAeHNsLnVzYWdlIGFkdmFuY2VkCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBnZXRJc1RvcExldmVsKCkKLSAgewotICAgIHJldHVybiBtX2lzVG9wTGV2ZWw7Ci0gIH0KLQotICAvKioKLSAgICogSW5pdGlhbGl6ZSB0aGUgY29udGV4dCB2YWx1ZXMgZm9yIHRoaXMgZXhwcmVzc2lvbgotICAgKiBhZnRlciBpdCBpcyBjbG9uZWQuCi0gICAqCi0gICAqIEBwYXJhbSBjb250ZXh0IFRoZSBYUGF0aCBydW50aW1lIGNvbnRleHQgZm9yIHRoaXMKLSAgICogdHJhbnNmb3JtYXRpb24uCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRSb290KGludCBjb250ZXh0LCBPYmplY3QgZW52aXJvbm1lbnQpCi0gIHsKLQotICAgIG1fY29udGV4dCA9IGNvbnRleHQ7Ci0KLSAgICBYUGF0aENvbnRleHQgeGN0eHQgPSAoWFBhdGhDb250ZXh0KWVudmlyb25tZW50OwotICAgIG1fZXhlY0NvbnRleHQgPSB4Y3R4dDsKLSAgICBtX2NkdG0gPSB4Y3R4dC5nZXREVE0oY29udGV4dCk7Ci0KLSAgICBtX2N1cnJlbnRDb250ZXh0Tm9kZSA9IGNvbnRleHQ7IC8vIG9ubHkgaWYgdG9wIGxldmVsPwotCi0gICAgLy8gWWVjaCwgc2hvdWxkbid0IGhhdmUgdG8gZG8gdGhpcy4gIC1zYgotICAgIGlmKG51bGwgPT0gbV9wcmVmaXhSZXNvbHZlcikKLSAgICAgICAgbV9wcmVmaXhSZXNvbHZlciA9IHhjdHh0LmdldE5hbWVzcGFjZUNvbnRleHQoKTsKLQotICAgIG1fbGFzdEZldGNoZWQgPSBEVE0uTlVMTDsKLSAgICBtX2ZvdW5kTGFzdCA9IGZhbHNlOwotICAgIG1fcG9zID0gMDsKLSAgICBtX2xlbmd0aCA9IC0xOwotCi0gICAgaWYgKG1faXNUb3BMZXZlbCkKLSAgICAgIHRoaXMubV9zdGFja0ZyYW1lID0geGN0eHQuZ2V0VmFyU3RhY2soKS5nZXRTdGFja0ZyYW1lKCk7Ci0KLSAgICAvLyByZXNldCgpOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgbmV4dCBwb3NpdGlvbiBpbmRleCBvZiB0aGlzIGl0ZXJhdG9yLgotICAgKgotICAgKiBAcGFyYW0gbmV4dCBBIHZhbHVlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byB6ZXJvIHRoYXQgaW5kaWNhdGVzIHRoZSBuZXh0Ci0gICAqIG5vZGUgcG9zaXRpb24gdG8gZmV0Y2guCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBzZXROZXh0UG9zaXRpb24oaW50IG5leHQpCi0gIHsKLSAgICBhc3NlcnRpb24oZmFsc2UsICJzZXROZXh0UG9zaXRpb24gbm90IHN1cHBvcnRlZCBpbiB0aGlzIGl0ZXJhdG9yISIpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgY3VycmVudCBwb3NpdGlvbiwgd2hpY2ggaXMgb25lIGxlc3MgdGhhbgotICAgKiB0aGUgbmV4dCBuZXh0Tm9kZSgpIGNhbGwgd2lsbCByZXRyaWV2ZS4gIGkuZS4gaWYKLSAgICogeW91IGNhbGwgZ2V0Q3VycmVudFBvcygpIGFuZCB0aGUgcmV0dXJuIGlzIDAsIHRoZSBuZXh0Ci0gICAqIGZldGNoIHdpbGwgdGFrZSBwbGFjZSBhdCBpbmRleCAxLgotICAgKgotICAgKiBAcmV0dXJuIEEgdmFsdWUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHplcm8gdGhhdCBpbmRpY2F0ZXMgdGhlIG5leHQKLSAgICogbm9kZSBwb3NpdGlvbiB0byBmZXRjaC4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBpbnQgZ2V0Q3VycmVudFBvcygpCi0gIHsKLSAgICByZXR1cm4gbV9wb3M7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBJZiBzZXRTaG91bGRDYWNoZU5vZGVzKHRydWUpIGlzIGNhbGxlZCwgdGhlbiBub2RlcyB3aWxsCi0gICAqIGJlIGNhY2hlZC4gIFRoZXkgYXJlIG5vdCBjYWNoZWQgYnkgZGVmYXVsdC4KLSAgICoKLSAgICogQHBhcmFtIGIgVHJ1ZSBpZiB0aGlzIGl0ZXJhdG9yIHNob3VsZCBjYWNoZSBub2Rlcy4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFNob3VsZENhY2hlTm9kZXMoYm9vbGVhbiBiKQotICB7Ci0KLSAgICBhc3NlcnRpb24oZmFsc2UsICJzZXRTaG91bGRDYWNoZU5vZGVzIG5vdCBzdXBwb3J0ZWQgYnkgdGhpcyBpdGVyYXRlciEiKTsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxscyBpZiB0aGlzIGl0ZXJhdG9yIGNhbiBoYXZlIG5vZGVzIGFkZGVkIHRvIGl0IG9yIHNldCB2aWEKLSAgICogdGhlIDxjb2RlPnNldEl0ZW0oaW50IG5vZGUsIGludCBpbmRleCk8L2NvZGU+IG1ldGhvZC4KLSAgICoKLSAgICogQHJldHVybiBUcnVlIGlmIHRoZSBub2RlbGlzdCBjYW4gYmUgbXV0YXRlZC4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzTXV0YWJsZSgpCi0gIHsKLSAgICByZXR1cm4gZmFsc2U7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBjdXJyZW50IHBvc2l0aW9uIGluIHRoZSBub2RlIHNldC4KLSAgICoKLSAgICogQHBhcmFtIGkgTXVzdCBiZSBhIHZhbGlkIGluZGV4IGdyZWF0ZXIKLSAgICogdGhhbiBvciBlcXVhbCB0byB6ZXJvIGFuZCBsZXNzIHRoYW4gbV9jYWNoZWROb2Rlcy5zaXplKCkuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRDdXJyZW50UG9zKGludCBpKQotICB7Ci0gICAgICAgIGFzc2VydGlvbihmYWxzZSwgInNldEN1cnJlbnRQb3Mgbm90IHN1cHBvcnRlZCBieSB0aGlzIGl0ZXJhdG9yISIpOwotICB9Ci0KLSAgLyoqCi0gICAqIEluY3JlbWVudCB0aGUgY3VycmVudCBwb3NpdGlvbiBpbiB0aGUgbm9kZSBzZXQuCi0gICAqLwotICBwdWJsaWMgdm9pZCBpbmNyZW1lbnRDdXJyZW50UG9zKCkKLSAgewotICAgICAgICBtX3BvcysrOwotICB9Ci0KLQotICAvKioKLSAgICogR2V0IHRoZSBsZW5ndGggb2YgdGhlIGNhY2hlZCBub2Rlcy4KLSAgICoKLSAgICogPHA+Tm90ZTogZm9yIHRoZSBtb21lbnQgYXQgbGVhc3QsIHRoaXMgb25seSByZXR1cm5zCi0gICAqIHRoZSBzaXplIG9mIHRoZSBub2RlcyB0aGF0IGhhdmUgYmVlbiBmZXRjaGVkIHRvIGRhdGUsCi0gICAqIGl0IGRvZXNuJ3QgYXR0ZW1wdCB0byBydW4gdG8gdGhlIGVuZCB0byBtYWtlIHN1cmUgd2UKLSAgICogaGF2ZSBmb3VuZCBldmVyeXRoaW5nLiAgVGhpcyBzaG91bGQgYmUgcmV2aWV3ZWQuPC9wPgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBzaXplIG9mIHRoZSBjdXJyZW50IGNhY2hlIGxpc3QuCi0gICAqLwotICBwdWJsaWMgaW50IHNpemUoKQotICB7Ci0gICAgICAgIGFzc2VydGlvbihmYWxzZSwgInNpemUoKSBub3Qgc3VwcG9ydGVkIGJ5IHRoaXMgaXRlcmF0b3IhIik7Ci0gICAgICAgIHJldHVybiAwOwotICB9Ci0KLSAgLyoqCi0gICAqICBSZXR1cm5zIHRoZSA8Y29kZT5pbmRleDwvY29kZT4gdGggaXRlbSBpbiB0aGUgY29sbGVjdGlvbi4gSWYKLSAgICogPGNvZGU+aW5kZXg8L2NvZGU+IGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byB0aGUgbnVtYmVyIG9mIG5vZGVzIGluCi0gICAqIHRoZSBsaXN0LCB0aGlzIHJldHVybnMgPGNvZGU+bnVsbDwvY29kZT4gLgotICAgKiBAcGFyYW0gaW5kZXggIEluZGV4IGludG8gdGhlIGNvbGxlY3Rpb24uCi0gICAqIEByZXR1cm4gIFRoZSBub2RlIGF0IHRoZSA8Y29kZT5pbmRleDwvY29kZT4gdGggcG9zaXRpb24gaW4gdGhlCi0gICAqICAgPGNvZGU+Tm9kZUxpc3Q8L2NvZGU+ICwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhhdCBpcyBub3QgYSB2YWxpZAotICAgKiAgIGluZGV4LgotICAgKi8KLSAgcHVibGljIGludCBpdGVtKGludCBpbmRleCkKLSAgewotICAgICAgICBhc3NlcnRpb24oZmFsc2UsICJpdGVtKGludCBpbmRleCkgbm90IHN1cHBvcnRlZCBieSB0aGlzIGl0ZXJhdG9yISIpOwotICAgICAgICByZXR1cm4gMDsKLSAgfQotCi0gIC8qKgotICAgKiBTZXRzIHRoZSBub2RlIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXggb2YgdGhpcyB2ZWN0b3IgdG8gYmUgdGhlCi0gICAqIHNwZWNpZmllZCBub2RlLiBUaGUgcHJldmlvdXMgY29tcG9uZW50IGF0IHRoYXQgcG9zaXRpb24gaXMgZGlzY2FyZGVkLgotICAgKgotICAgKiA8cD5UaGUgaW5kZXggbXVzdCBiZSBhIHZhbHVlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAwIGFuZCBsZXNzCi0gICAqIHRoYW4gdGhlIGN1cnJlbnQgc2l6ZSBvZiB0aGUgdmVjdG9yLgotICAgKiBUaGUgaXRlcmF0b3IgbXVzdCBiZSBpbiBjYWNoZWQgbW9kZS48L3A+Ci0gICAqCi0gICAqIDxwPk1lYW50IHRvIGJlIHVzZWQgZm9yIHNvcnRlZCBpdGVyYXRvcnMuPC9wPgotICAgKgotICAgKiBAcGFyYW0gbm9kZSBOb2RlIHRvIHNldAotICAgKiBAcGFyYW0gaW5kZXggSW5kZXggb2Ygd2hlcmUgdG8gc2V0IHRoZSBub2RlCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRJdGVtKGludCBub2RlLCBpbnQgaW5kZXgpCi0gIHsKLSAgICAgICAgYXNzZXJ0aW9uKGZhbHNlLCAic2V0SXRlbSBub3Qgc3VwcG9ydGVkIGJ5IHRoaXMgaXRlcmF0b3IhIik7Ci0gIH0KLQotICAvKioKLSAgICogIFRoZSBudW1iZXIgb2Ygbm9kZXMgaW4gdGhlIGxpc3QuIFRoZSByYW5nZSBvZiB2YWxpZCBjaGlsZCBub2RlIGluZGljZXMKLSAgICogaXMgMCB0byA8Y29kZT5sZW5ndGgtMTwvY29kZT4gaW5jbHVzaXZlLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBudW1iZXIgb2Ygbm9kZXMgaW4gdGhlIGxpc3QsIGFsd2F5cyBncmVhdGVyIG9yIGVxdWFsIHRvIHplcm8uCi0gICAqLwotICBwdWJsaWMgaW50IGdldExlbmd0aCgpCi0gIHsKLSAgICAvLyBUZWxsIGlmIHRoaXMgaXMgYmVpbmcgY2FsbGVkIGZyb20gd2l0aGluIGEgcHJlZGljYXRlLgotICAgICAgICBib29sZWFuIGlzUHJlZGljYXRlVGVzdCA9ICh0aGlzID09IG1fZXhlY0NvbnRleHQuZ2V0U3ViQ29udGV4dExpc3QoKSk7Ci0KLSAgICAvLyBBbmQgZ2V0IGhvdyBtYW55IHRvdGFsIHByZWRpY2F0ZXMgYXJlIHBhcnQgb2YgdGhpcyBzdGVwLgotICAgICAgICBpbnQgcHJlZENvdW50ID0gZ2V0UHJlZGljYXRlQ291bnQoKTsKLQotICAgIC8vIElmIHdlIGhhdmUgYWxyZWFkeSBjYWxjdWxhdGVkIHRoZSBsZW5ndGgsIGFuZCB0aGUgY3VycmVudCBwcmVkaWNhdGUKLSAgICAvLyBpcyB0aGUgZmlyc3QgcHJlZGljYXRlLCB0aGVuIHJldHVybiB0aGUgbGVuZ3RoLiAgV2UgZG9uJ3QgY2FjaGUKLSAgICAvLyB0aGUgYW55dGhpbmcgYnV0IHRoZSBsZW5ndGggb2YgdGhlIGxpc3QgdG8gdGhlIGZpcnN0IHByZWRpY2F0ZS4KLSAgICBpZiAoLTEgIT0gbV9sZW5ndGggJiYgaXNQcmVkaWNhdGVUZXN0ICYmIG1fcHJlZGljYXRlSW5kZXggPCAxKQotICAgICAgICAgICAgICAgIHJldHVybiBtX2xlbmd0aDsKLQotICAgIC8vIEknbSBhIGJpdCB3b3JyaWVkIGFib3V0IHRoaXMgb25lLCBzaW5jZSBpdCBkb2Vzbid0IGhhdmUgdGhlCi0gICAgLy8gY2hlY2tzIGZvdW5kIGFib3ZlLiAgSSBzdXNwZWN0IGl0J3MgZmluZS4gIC1zYgotICAgIGlmIChtX2ZvdW5kTGFzdCkKLSAgICAgICAgICAgICAgICByZXR1cm4gbV9wb3M7Ci0KLSAgICAvLyBDcmVhdGUgYSBjbG9uZSwgYW5kIGNvdW50IGZyb20gdGhlIGN1cnJlbnQgcG9zaXRpb24gdG8gdGhlIGVuZAotICAgIC8vIG9mIHRoZSBsaXN0LCBub3QgdGFraW5nIGludG8gYWNjb3VudCB0aGUgY3VycmVudCBwcmVkaWNhdGUgYW5kCi0gICAgLy8gcHJlZGljYXRlcyBhZnRlciB0aGUgY3VycmVudCBvbmUuCi0gICAgaW50IHBvcyA9IChtX3ByZWRpY2F0ZUluZGV4ID49IDApID8gZ2V0UHJveGltaXR5UG9zaXRpb24oKSA6IG1fcG9zOwotCi0gICAgTG9jUGF0aEl0ZXJhdG9yIGNsb25lOwotCi0gICAgdHJ5Ci0gICAgewotICAgICAgY2xvbmUgPSAoTG9jUGF0aEl0ZXJhdG9yKSBjbG9uZSgpOwotICAgIH0KLSAgICBjYXRjaCAoQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gY25zZSkKLSAgICB7Ci0gICAgICByZXR1cm4gLTE7Ci0gICAgfQotCi0gICAgLy8gV2Ugd2FudCB0byBjbGlwIG9mZiB0aGUgbGFzdCBwcmVkaWNhdGUsIGJ1dCBvbmx5IGlmIHdlIGFyZSBhIHN1YgotICAgIC8vIGNvbnRleHQgbm9kZSBsaXN0LCBOT1QgaWYgd2UgYXJlIGEgY29udGV4dCBsaXN0LiAgU2VlIHBvczY4IHRlc3QsCi0gICAgLy8gYWxzbyB0ZXN0IGFnYWluc3QgYnVnNDYzOC4KLSAgICBpZiAocHJlZENvdW50ID4gMCAmJiBpc1ByZWRpY2F0ZVRlc3QpCi0gICAgewotICAgICAgLy8gRG9uJ3QgY2FsbCBzZXRQcmVkaWNhdGVDb3VudCwgYmVjYXVzZSBpdCBjbG9uZXMgYW5kIGlzIHNsb3dlci4KLSAgICAgIGNsb25lLm1fcHJlZENvdW50ID0gbV9wcmVkaWNhdGVJbmRleDsKLSAgICAgIC8vIFRoZSBsaW5lIGFib3ZlIHVzZWQgdG8gYmU6Ci0gICAgICAvLyBjbG9uZS5tX3ByZWRDb3VudCA9IHByZWRDb3VudCAtIDE7Ci0gICAgICAvLyAuLi53aGljaCBsb29rcyBsaWtlIGEgZHVtYiBidWcgdG8gbWUuIC1zYgotICAgIH0KLQotICAgIGludCBuZXh0OwotCi0gICAgd2hpbGUgKERUTS5OVUxMICE9IChuZXh0ID0gY2xvbmUubmV4dE5vZGUoKSkpCi0gICAgewotICAgICAgcG9zKys7Ci0gICAgfQotCi0gICAgaWYgKGlzUHJlZGljYXRlVGVzdCAmJiBtX3ByZWRpY2F0ZUluZGV4IDwgMSkKLSAgICAgIG1fbGVuZ3RoID0gcG9zOwotCi0gICAgcmV0dXJuIHBvczsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxscyBpZiB0aGlzIE5vZGVTZXREVE0gaXMgImZyZXNoIiwgaW4gb3RoZXIgd29yZHMsIGlmCi0gICAqIHRoZSBmaXJzdCBuZXh0Tm9kZSgpIHRoYXQgaXMgY2FsbGVkIHdpbGwgcmV0dXJuIHRoZQotICAgKiBmaXJzdCBub2RlIGluIHRoZSBzZXQuCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBvZiBuZXh0Tm9kZSBoYXMgbm90IGJlZW4gY2FsbGVkLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNGcmVzaCgpCi0gIHsKLSAgICByZXR1cm4gKG1fcG9zID09IDApOwotICB9Ci0KLSAgLyoqCi0gICAqICBSZXR1cm5zIHRoZSBwcmV2aW91cyBub2RlIGluIHRoZSBzZXQgYW5kIG1vdmVzIHRoZSBwb3NpdGlvbiBvZiB0aGUKLSAgICogaXRlcmF0b3IgYmFja3dhcmRzIGluIHRoZSBzZXQuCi0gICAqIEByZXR1cm4gIFRoZSBwcmV2aW91cyA8Y29kZT5Ob2RlPC9jb2RlPiBpbiB0aGUgc2V0IGJlaW5nIGl0ZXJhdGVkIG92ZXIsCi0gICAqICAgb3I8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGVyZSBhcmUgbm8gbW9yZSBtZW1iZXJzIGluIHRoYXQgc2V0LgotICAgKi8KLSAgcHVibGljIGludCBwcmV2aW91c05vZGUoKQotICB7Ci0gICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCi0gICAgICBYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoWFBBVEhFcnJvclJlc291cmNlcy5FUl9OT0RFU0VURFRNX0NBTk5PVF9JVEVSQVRFLCBudWxsKSk7IC8vIlRoaXMgTm9kZVNldERUTSBjYW4gbm90IGl0ZXJhdGUgdG8gYSBwcmV2aW91cyBub2RlISIpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoaXMgYXR0cmlidXRlIGRldGVybWluZXMgd2hpY2ggbm9kZSB0eXBlcyBhcmUgcHJlc2VudGVkIHZpYSB0aGUKLSAgICogaXRlcmF0b3IuIFRoZSBhdmFpbGFibGUgc2V0IG9mIGNvbnN0YW50cyBpcyBkZWZpbmVkIGluIHRoZQotICAgKiA8Y29kZT5Ob2RlRmlsdGVyPC9jb2RlPiBpbnRlcmZhY2UuCi0gICAqCi0gICAqIDxwPlRoaXMgaXMgc29tZXdoYXQgdXNlbGVzcyBhdCB0aGlzIHRpbWUsIHNpbmNlIGl0IGRvZXNuJ3QKLSAgICogcmVhbGx5IHJldHVybiBpbmZvcm1hdGlvbiB0aGF0IHRlbGxzIHdoYXQgdGhpcyBpdGVyYXRvciB3aWxsCi0gICAqIHNob3cuICBJdCBpcyBoZXJlIG9ubHkgdG8gZnVsbGZpbGwgdGhlIERPTSBOb2RlSXRlcmF0b3IKLSAgICogaW50ZXJmYWNlLjwvcD4KLSAgICoKLSAgICogQHJldHVybiBGb3Igbm93LCBhbHdheXMgTm9kZUZpbHRlci5TSE9XX0FMTCAmIH5Ob2RlRmlsdGVyLlNIT1dfRU5USVRZX1JFRkVSRU5DRS4KLSAgICogQHNlZSBvcmcudzNjLmRvbS50cmF2ZXJzYWwuTm9kZUl0ZXJhdG9yCi0gICAqLwotICBwdWJsaWMgaW50IGdldFdoYXRUb1Nob3coKQotICB7Ci0KLSAgICAvLyBUT0RPOiA/PwotICAgIHJldHVybiBEVE1GaWx0ZXIuU0hPV19BTEwgJiB+RFRNRmlsdGVyLlNIT1dfRU5USVRZX1JFRkVSRU5DRTsKLSAgfQotCi0gIC8qKgotICAgKiAgVGhlIGZpbHRlciB1c2VkIHRvIHNjcmVlbiBub2Rlcy4gIE5vdCB1c2VkIGF0IHRoaXMgdGltZSwKLSAgICogdGhpcyBpcyBoZXJlIG9ubHkgdG8gZnVsbGZpbGwgdGhlIERPTSBOb2RlSXRlcmF0b3IKLSAgICogaW50ZXJmYWNlLgotICAgKgotICAgKiBAcmV0dXJuIEFsd2F5cyBudWxsLgotICAgKiBAc2VlIG9yZy53M2MuZG9tLnRyYXZlcnNhbC5Ob2RlSXRlcmF0b3IKLSAgICovCi0gIHB1YmxpYyBEVE1GaWx0ZXIgZ2V0RmlsdGVyKCkKLSAgewotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoZSByb290IG5vZGUgb2YgdGhlIEl0ZXJhdG9yLCBhcyBzcGVjaWZpZWQgd2hlbiBpdCB3YXMgY3JlYXRlZC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgInJvb3QiIG9mIHRoaXMgaXRlcmF0b3IsIHdoaWNoLCBpbiBYUGF0aCB0ZXJtcywKLSAgICogaXMgdGhlIG5vZGUgY29udGV4dCBmb3IgdGhpcyBpdGVyYXRvci4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0Um9vdCgpCi0gIHsKLSAgICByZXR1cm4gbV9jb250ZXh0OwotICB9Ci0KLSAgLyoqCi0gICAqICBUaGUgdmFsdWUgb2YgdGhpcyBmbGFnIGRldGVybWluZXMgd2hldGhlciB0aGUgY2hpbGRyZW4gb2YgZW50aXR5Ci0gICAqIHJlZmVyZW5jZSBub2RlcyBhcmUgdmlzaWJsZSB0byB0aGUgaXRlcmF0b3IuIElmIGZhbHNlLCB0aGV5IHdpbGwgYmUKLSAgICogc2tpcHBlZCBvdmVyLgotICAgKiA8YnI+IFRvIHByb2R1Y2UgYSB2aWV3IG9mIHRoZSBkb2N1bWVudCB0aGF0IGhhcyBlbnRpdHkgcmVmZXJlbmNlcwotICAgKiBleHBhbmRlZCBhbmQgZG9lcyBub3QgZXhwb3NlIHRoZSBlbnRpdHkgcmVmZXJlbmNlIG5vZGUgaXRzZWxmLCB1c2UgdGhlCi0gICAqIHdoYXRUb1Nob3cgZmxhZ3MgdG8gaGlkZSB0aGUgZW50aXR5IHJlZmVyZW5jZSBub2RlIGFuZCBzZXQKLSAgICogZXhwYW5kRW50aXR5UmVmZXJlbmNlcyB0byB0cnVlIHdoZW4gY3JlYXRpbmcgdGhlIGl0ZXJhdG9yLiBUbyBwcm9kdWNlCi0gICAqIGEgdmlldyBvZiB0aGUgZG9jdW1lbnQgdGhhdCBoYXMgZW50aXR5IHJlZmVyZW5jZSBub2RlcyBidXQgbm8gZW50aXR5Ci0gICAqIGV4cGFuc2lvbiwgdXNlIHRoZSB3aGF0VG9TaG93IGZsYWdzIHRvIHNob3cgdGhlIGVudGl0eSByZWZlcmVuY2Ugbm9kZQotICAgKiBhbmQgc2V0IGV4cGFuZEVudGl0eVJlZmVyZW5jZXMgdG8gZmFsc2UuCi0gICAqCi0gICAqIEByZXR1cm4gQWx3YXlzIHRydWUsIHNpbmNlIGVudGl0eSByZWZlcmVuY2Ugbm9kZXMgYXJlIG5vdAotICAgKiB2aXNpYmxlIGluIHRoZSBYUGF0aCBtb2RlbC4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGdldEV4cGFuZEVudGl0eVJlZmVyZW5jZXMoKQotICB7Ci0gICAgcmV0dXJuIHRydWU7Ci0gIH0KLQotICAvKiogQ29udHJvbCBvdmVyIHdoZXRoZXIgaXQgaXMgT0sgZm9yIGRldGFjaCB0byByZXNldCB0aGUgaXRlcmF0b3IuICovCi0gIHByb3RlY3RlZCBib29sZWFuIG1fYWxsb3dEZXRhY2ggPSB0cnVlOwotCi0gIC8qKgotICAgKiBTcGVjaWZ5IGlmIGl0J3MgT0sgZm9yIGRldGFjaCB0byByZWxlYXNlIHRoZSBpdGVyYXRvciBmb3IgcmV1c2UuCi0gICAqCi0gICAqIEBwYXJhbSBhbGxvd1JlbGVhc2UgdHJ1ZSBpZiBpdCBpcyBPSyBmb3IgZGV0YWNoIHRvIHJlbGVhc2UgdGhpcyBpdGVyYXRvcgotICAgKiBmb3IgcG9vbGluZy4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGFsbG93RGV0YWNoVG9SZWxlYXNlKGJvb2xlYW4gYWxsb3dSZWxlYXNlKQotICB7Ci0gICAgbV9hbGxvd0RldGFjaCA9IGFsbG93UmVsZWFzZTsKLSAgfQotCi0gIC8qKgotICAgKiAgRGV0YWNoZXMgdGhlIGl0ZXJhdG9yIGZyb20gdGhlIHNldCB3aGljaCBpdCBpdGVyYXRlZCBvdmVyLCByZWxlYXNpbmcKLSAgICogYW55IGNvbXB1dGF0aW9uYWwgcmVzb3VyY2VzIGFuZCBwbGFjaW5nIHRoZSBpdGVyYXRvciBpbiB0aGUgSU5WQUxJRAotICAgKiBzdGF0ZS4gQWZ0ZXI8Y29kZT5kZXRhY2g8L2NvZGU+IGhhcyBiZWVuIGludm9rZWQsIGNhbGxzIHRvCi0gICAqIDxjb2RlPm5leHROb2RlPC9jb2RlPiBvcjxjb2RlPnByZXZpb3VzTm9kZTwvY29kZT4gd2lsbCByYWlzZSB0aGUKLSAgICogZXhjZXB0aW9uIElOVkFMSURfU1RBVEVfRVJSLgotICAgKi8KLSAgcHVibGljIHZvaWQgZGV0YWNoKCkKLSAgewotICAgIGlmKG1fYWxsb3dEZXRhY2gpCi0gICAgewotICAgICAgLy8gc2I6IGFsbG93IHJldXNpbmcgb2YgY2FjaGVkIG5vZGVzIHdoZW4gcG9zc2libGU/Ci0gICAgICAvLyBtX2NhY2hlZE5vZGVzID0gbnVsbDsKLSAgICAgIG1fZXhlY0NvbnRleHQgPSBudWxsOwotICAgICAgLy8gbV9wcmVmaXhSZXNvbHZlciA9IG51bGw7ICBzYjogV2h5IHdvdWxkIHRoaXMgZXZlciB3YW50IHRvIGJlIG51bGw/Ci0gICAgICBtX2NkdG0gPSBudWxsOwotICAgICAgbV9sZW5ndGggPSAtMTsKLSAgICAgIG1fcG9zID0gMDsKLSAgICAgIG1fbGFzdEZldGNoZWQgPSBEVE0uTlVMTDsKLSAgICAgIG1fY29udGV4dCA9IERUTS5OVUxMOwotICAgICAgbV9jdXJyZW50Q29udGV4dE5vZGUgPSBEVE0uTlVMTDsKLQotICAgICAgbV9jbG9uZXMuZnJlZUluc3RhbmNlKHRoaXMpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBSZXNldCB0aGUgaXRlcmF0b3IuCi0gICAqLwotICBwdWJsaWMgdm9pZCByZXNldCgpCi0gIHsKLSAgICAgICAgYXNzZXJ0aW9uKGZhbHNlLCAiVGhpcyBpdGVyYXRvciBjYW4gbm90IHJlc2V0ISIpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBhIGNsb25lZCBJdGVyYXRvciB0aGF0IGlzIHJlc2V0IHRvIHRoZSBiZWdpbm5pbmcKLSAgICogb2YgdGhlIHF1ZXJ5LgotICAgKgotICAgKiBAcmV0dXJuIEEgY2xvbmVkIE5vZGVJdGVyYXRvciBzZXQgb2YgdGhlIHN0YXJ0IG9mIHRoZSBxdWVyeS4KLSAgICoKLSAgICogQHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIERUTUl0ZXJhdG9yIGNsb25lV2l0aFJlc2V0KCkgdGhyb3dzIENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uCi0gIHsKLSAgICBMb2NQYXRoSXRlcmF0b3IgY2xvbmU7Ci0vLyAgICBjbG9uZSA9IChMb2NQYXRoSXRlcmF0b3IpIGNsb25lKCk7Ci0gICAgY2xvbmUgPSAoTG9jUGF0aEl0ZXJhdG9yKW1fY2xvbmVzLmdldEluc3RhbmNlT3JUaHJvdygpOwotICAgIGNsb25lLm1fZXhlY0NvbnRleHQgPSBtX2V4ZWNDb250ZXh0OwotICAgIGNsb25lLm1fY2R0bSA9IG1fY2R0bTsKLQotICAgIGNsb25lLm1fY29udGV4dCA9IG1fY29udGV4dDsKLSAgICBjbG9uZS5tX2N1cnJlbnRDb250ZXh0Tm9kZSA9IG1fY3VycmVudENvbnRleHROb2RlOwotICAgIGNsb25lLm1fc3RhY2tGcmFtZSA9IG1fc3RhY2tGcmFtZTsKLQotICAgIC8vIGNsb25lLnJlc2V0KCk7Ci0KLSAgICByZXR1cm4gY2xvbmU7Ci0gIH0KLQotLy8gIC8qKgotLy8gICAqIEdldCBhIGNsb25lZCBMb2NQYXRoSXRlcmF0b3IgdGhhdCBob2xkcyB0aGUgc2FtZQotLy8gICAqIHBvc2l0aW9uIGFzIHRoaXMgaXRlcmF0b3IuCi0vLyAgICoKLS8vICAgKiBAcmV0dXJuIEEgY2xvbmUgb2YgdGhpcyBpdGVyYXRvciB0aGF0IGhvbGRzIHRoZSBzYW1lIG5vZGUgcG9zaXRpb24uCi0vLyAgICoKLS8vICAgKiBAdGhyb3dzIENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uCi0vLyAgICovCi0vLyAgcHVibGljIE9iamVjdCBjbG9uZSgpIHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbgotLy8gIHsKLS8vCi0vLyAgICBMb2NQYXRoSXRlcmF0b3IgY2xvbmUgPSAoTG9jUGF0aEl0ZXJhdG9yKSBzdXBlci5jbG9uZSgpOwotLy8KLS8vICAgIHJldHVybiBjbG9uZTsKLS8vICB9Ci0KLSAgLyoqCi0gICAqICBSZXR1cm5zIHRoZSBuZXh0IG5vZGUgaW4gdGhlIHNldCBhbmQgYWR2YW5jZXMgdGhlIHBvc2l0aW9uIG9mIHRoZQotICAgKiBpdGVyYXRvciBpbiB0aGUgc2V0LiBBZnRlciBhIE5vZGVJdGVyYXRvciBpcyBjcmVhdGVkLCB0aGUgZmlyc3QgY2FsbAotICAgKiB0byBuZXh0Tm9kZSgpIHJldHVybnMgdGhlIGZpcnN0IG5vZGUgaW4gdGhlIHNldC4KLSAgICogQHJldHVybiAgVGhlIG5leHQgPGNvZGU+Tm9kZTwvY29kZT4gaW4gdGhlIHNldCBiZWluZyBpdGVyYXRlZCBvdmVyLCBvcgotICAgKiAgIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoZXJlIGFyZSBubyBtb3JlIG1lbWJlcnMgaW4gdGhhdCBzZXQuCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgaW50IG5leHROb2RlKCk7Ci0KLSAgLyoqCi0gICAqIEJvdHRsZW5lY2sgdGhlIHJldHVybiBvZiBhIG5leHQgbm9kZSwgdG8gbWFrZSByZXR1cm5zCi0gICAqIGVhc2llciBmcm9tIG5leHROb2RlKCkuCi0gICAqCi0gICAqIEBwYXJhbSBuZXh0Tm9kZSBUaGUgbmV4dCBub2RlIGZvdW5kLCBtYXkgYmUgbnVsbC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgc2FtZSBub2RlIHRoYXQgd2FzIHBhc3NlZCBhcyBhbiBhcmd1bWVudC4KLSAgICovCi0gIHByb3RlY3RlZCBpbnQgcmV0dXJuTmV4dE5vZGUoaW50IG5leHROb2RlKQotICB7Ci0KLSAgICBpZiAoRFRNLk5VTEwgIT0gbmV4dE5vZGUpCi0gICAgewotICAgICAgbV9wb3MrKzsKLSAgICB9Ci0KLSAgICBtX2xhc3RGZXRjaGVkID0gbmV4dE5vZGU7Ci0KLSAgICBpZiAoRFRNLk5VTEwgPT0gbmV4dE5vZGUpCi0gICAgICBtX2ZvdW5kTGFzdCA9IHRydWU7Ci0KLSAgICByZXR1cm4gbmV4dE5vZGU7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBsYXN0IGZldGNoZWQgbm9kZS4gIE5lZWRlZCB0byBzdXBwb3J0IHRoZSBVbmlvblBhdGhJdGVyYXRvci4KLSAgICoKLSAgICogQHJldHVybiBUaGUgbGFzdCBmZXRjaGVkIG5vZGUsIG9yIG51bGwgaWYgdGhlIGxhc3QgZmV0Y2ggd2FzIG51bGwuCi0gICAqLwotICBwdWJsaWMgaW50IGdldEN1cnJlbnROb2RlKCkKLSAgewotICAgIHJldHVybiBtX2xhc3RGZXRjaGVkOwotICB9Ci0KLSAgLyoqCi0gICAqIElmIGFuIGluZGV4IGlzIHJlcXVlc3RlZCwgTm9kZVNldERUTSB3aWxsIGNhbGwgdGhpcyBtZXRob2QKLSAgICogdG8gcnVuIHRoZSBpdGVyYXRvciB0byB0aGUgaW5kZXguICBCeSBkZWZhdWx0IHRoaXMgc2V0cwotICAgKiBtX25leHQgdG8gdGhlIGluZGV4LiAgSWYgdGhlIGluZGV4IGFyZ3VtZW50IGlzIC0xLCB0aGlzCi0gICAqIHNpZ25hbHMgdGhhdCB0aGUgaXRlcmF0b3Igc2hvdWxkIGJlIHJ1biB0byB0aGUgZW5kLgotICAgKgotICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHJ1biB0bywgb3IgLTEgaWYgdGhlIGl0ZXJhdG9yCi0gICAqIHNob3VsZCBydW4gdG8gdGhlIGVuZC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHJ1blRvKGludCBpbmRleCkKLSAgewotCi0gICAgaWYgKG1fZm91bmRMYXN0IHx8ICgoaW5kZXggPj0gMCkgJiYgKGluZGV4IDw9IGdldEN1cnJlbnRQb3MoKSkpKQotICAgICAgcmV0dXJuOwotCi0gICAgaW50IG47Ci0KLSAgICBpZiAoLTEgPT0gaW5kZXgpCi0gICAgewotICAgICAgd2hpbGUgKERUTS5OVUxMICE9IChuID0gbmV4dE5vZGUoKSkpOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgd2hpbGUgKERUTS5OVUxMICE9IChuID0gbmV4dE5vZGUoKSkpCi0gICAgICB7Ci0gICAgICAgIGlmIChnZXRDdXJyZW50UG9zKCkgPj0gaW5kZXgpCi0gICAgICAgICAgYnJlYWs7Ci0gICAgICB9Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGxzIGlmIHdlJ3ZlIGZvdW5kIHRoZSBsYXN0IG5vZGUgeWV0LgotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGxhc3QgbmV4dE5vZGUgcmV0dXJuZWQgbnVsbC4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBib29sZWFuIGdldEZvdW5kTGFzdCgpCi0gIHsKLSAgICByZXR1cm4gbV9mb3VuZExhc3Q7Ci0gIH0KLQotICAvKioKLSAgICogVGhlIFhQYXRoIGV4ZWN1dGlvbiBjb250ZXh0IHdlIGFyZSBvcGVyYXRpbmcgb24uCi0gICAqCi0gICAqIEByZXR1cm4gWFBhdGggZXhlY3V0aW9uIGNvbnRleHQgdGhpcyBpdGVyYXRvciBpcyBvcGVyYXRpbmcgb24sCi0gICAqIG9yIG51bGwgaWYgc2V0Um9vdCBoYXMgbm90IGJlZW4gY2FsbGVkLgotICAgKi8KLSAgcHVibGljIGZpbmFsIFhQYXRoQ29udGV4dCBnZXRYUGF0aENvbnRleHQoKQotICB7Ci0gICAgcmV0dXJuIG1fZXhlY0NvbnRleHQ7Ci0gIH0KLQotICAvKioKLSAgICogVGhlIG5vZGUgY29udGV4dCBmb3IgdGhlIGl0ZXJhdG9yLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBub2RlIGNvbnRleHQsIHNhbWUgYXMgZ2V0Um9vdCgpLgotICAgKi8KLSAgcHVibGljIGZpbmFsIGludCBnZXRDb250ZXh0KCkKLSAgewotICAgIHJldHVybiBtX2NvbnRleHQ7Ci0gIH0KLQotICAvKioKLSAgICogVGhlIG5vZGUgY29udGV4dCBmcm9tIHdoZXJlIHRoZSBleHByZXNzaW9uIGlzIGJlaW5nCi0gICAqIGV4ZWN1dGVkIGZyb20gKGkuZS4gZm9yIGN1cnJlbnQoKSBzdXBwb3J0KS4KLSAgICoKLSAgICogQHJldHVybiBUaGUgdG9wLWxldmVsIG5vZGUgY29udGV4dCBvZiB0aGUgZW50aXJlIGV4cHJlc3Npb24uCi0gICAqLwotICBwdWJsaWMgZmluYWwgaW50IGdldEN1cnJlbnRDb250ZXh0Tm9kZSgpCi0gIHsKLSAgICByZXR1cm4gbV9jdXJyZW50Q29udGV4dE5vZGU7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBjdXJyZW50IGNvbnRleHQgbm9kZSBmb3IgdGhpcyBpdGVyYXRvci4KLSAgICoKLSAgICogQHBhcmFtIG4gTXVzdCBiZSBhIG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgbm9kZSBjb250ZXh0LgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgc2V0Q3VycmVudENvbnRleHROb2RlKGludCBuKQotICB7Ci0gICAgbV9jdXJyZW50Q29udGV4dE5vZGUgPSBuOwotICB9Ci0KLS8vICAvKioKLS8vICAgKiBTZXQgdGhlIGN1cnJlbnQgY29udGV4dCBub2RlIGZvciB0aGlzIGl0ZXJhdG9yLgotLy8gICAqCi0vLyAgICogQHBhcmFtIG4gTXVzdCBiZSBhIG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgbm9kZSBjb250ZXh0LgotLy8gICAqLwotLy8gIHB1YmxpYyB2b2lkIHNldFJvb3QoaW50IG4pCi0vLyAgewotLy8gICAgbV9jb250ZXh0ID0gbjsKLS8vICAgIG1fY2R0bSA9IG1fZXhlY0NvbnRleHQuZ2V0RFRNKG4pOwotLy8gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBzYXZlZCByZWZlcmVuY2UgdG8gdGhlIHByZWZpeCByZXNvbHZlciB0aGF0Ci0gICAqIHdhcyBpbiBlZmZlY3Qgd2hlbiB0aGlzIGl0ZXJhdG9yIHdhcyBjcmVhdGVkLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBwcmVmaXggcmVzb2x2ZXIgb3IgdGhpcyBpdGVyYXRvciwgd2hpY2ggbWF5IGJlIG51bGwuCi0gICAqLwotICBwdWJsaWMgZmluYWwgUHJlZml4UmVzb2x2ZXIgZ2V0UHJlZml4UmVzb2x2ZXIoKQotICB7Ci0gICAgICAgIGlmKG51bGwgPT0gbV9wcmVmaXhSZXNvbHZlcikKLSAgICAgICAgewotICAgICAgICBtX3ByZWZpeFJlc29sdmVyID0gKFByZWZpeFJlc29sdmVyKWdldEV4cHJlc3Npb25Pd25lcigpOwotICAgICAgICB9Ci0KLSAgICByZXR1cm4gbV9wcmVmaXhSZXNvbHZlcjsKLSAgfQotCi0vLyAgLyoqCi0vLyAgICogR2V0IHRoZSBhbmFseXNpcyBwYXR0ZXJuIGJ1aWx0IGJ5IHRoZSBXYWxrZXJGYWN0b3J5LgotLy8gICAqCi0vLyAgICogQHJldHVybiBUaGUgYW5hbHlzaXMgcGF0dGVybiBidWlsdCBieSB0aGUgV2Fsa2VyRmFjdG9yeS4KLS8vICAgKi8KLS8vICBpbnQgZ2V0QW5hbHlzaXMoKQotLy8gIHsKLS8vICAgIHJldHVybiBtX2FuYWx5c2lzOwotLy8gIH0KLQotLy8gIC8qKgotLy8gICAqIFNldCB0aGUgYW5hbHlzaXMgcGF0dGVybiBidWlsdCBieSB0aGUgV2Fsa2VyRmFjdG9yeS4KLS8vICAgKgotLy8gICAqIEBwYXJhbSBhIFRoZSBhbmFseXNpcyBwYXR0ZXJuIGJ1aWx0IGJ5IHRoZSBXYWxrZXJGYWN0b3J5LgotLy8gICAqLwotLy8gIHZvaWQgc2V0QW5hbHlzaXMoaW50IGEpCi0vLyAgewotLy8gICAgbV9hbmFseXNpcyA9IGE7Ci0vLyAgfQotCi0gIC8qKgotICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5YUGF0aFZpc2l0YWJsZSNjYWxsVmlzaXRvcnMoRXhwcmVzc2lvbk93bmVyLCBYUGF0aFZpc2l0b3IpCi0gICAqLwotICBwdWJsaWMgdm9pZCBjYWxsVmlzaXRvcnMoRXhwcmVzc2lvbk93bmVyIG93bmVyLCBYUGF0aFZpc2l0b3IgdmlzaXRvcikKLSAgewotICAgICAgICAgICAgICAgIGlmKHZpc2l0b3IudmlzaXRMb2NhdGlvblBhdGgob3duZXIsIHRoaXMpKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHZpc2l0b3IudmlzaXRTdGVwKG93bmVyLCB0aGlzKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxQcmVkaWNhdGVWaXNpdG9ycyh2aXNpdG9yKTsKLSAgICAgICAgICAgICAgICB9Ci0gIH0KLQotCi0gIC8vPT09PT09PT09PT09PSBTdGF0ZSBEYXRhID09PT09PT09PT09PT0KLQotICAvKioKLSAgICogVGhlIHBvb2wgZm9yIGNsb25lZCBpdGVyYXRvcnMuICBJdGVyYXRvcnMgbmVlZCB0byBiZSBjbG9uZWQKLSAgICogYmVjYXVzZSB0aGUgaG9sZCBydW5uaW5nIHN0YXRlLCBhbmQgdGh1cyB0aGUgb3JpZ2luYWwgaXRlcmF0b3IKLSAgICogZXhwcmVzc2lvbiBmcm9tIHRoZSBzdHlsZXNoZWV0IHBvb2wgY2FuIG5vdCBiZSB1c2VkLgotICAgKi8KLSAgdHJhbnNpZW50IHByb3RlY3RlZCBJdGVyYXRvclBvb2wgbV9jbG9uZXMgPSBuZXcgSXRlcmF0b3JQb29sKHRoaXMpOwotCi0gIC8qKgotICAgKiBUaGUgZHRtIG9mIHRoZSBjb250ZXh0IG5vZGUuICBDYXJlZnVsIGFib3V0IHVzaW5nIHRoaXMuLi4gaXQgbWF5IG5vdAotICAgKiBiZSB0aGUgZHRtIG9mIHRoZSBjdXJyZW50IG5vZGUuCi0gICAqLwotICB0cmFuc2llbnQgcHJvdGVjdGVkIERUTSBtX2NkdG07Ci0KLSAgLyoqCi0gICAqIFRoZSBzdGFjayBmcmFtZSBpbmRleCBmb3IgdGhpcyBpdGVyYXRvci4KLSAgICovCi0gIHRyYW5zaWVudCBpbnQgbV9zdGFja0ZyYW1lID0gLTE7Ci0KLSAgLyoqCi0gICAqIFZhbHVlIGRldGVybWluZWQgYXQgY29tcGlsZSB0aW1lLCBpbmRpY2F0ZXMgdGhhdCB0aGlzIGlzIGFuCi0gICAqIGl0ZXJhdG9yIGF0IHRoZSB0b3AgbGV2ZWwgb2YgdGhlIGV4cHJlc3Npb24sIHJhdGhlciB0aGFuIGluc2lkZQotICAgKiBhIHByZWRpY2F0ZS4KLSAgICogQHNlcmlhbAotICAgKi8KLSAgcHJpdmF0ZSBib29sZWFuIG1faXNUb3BMZXZlbCA9IGZhbHNlOwotCi0gIC8qKiBUaGUgbGFzdCBub2RlIHRoYXQgd2FzIGZldGNoZWQsIHVzdWFsbHkgYnkgbmV4dE5vZGUuICovCi0gIHRyYW5zaWVudCBwdWJsaWMgaW50IG1fbGFzdEZldGNoZWQgPSBEVE0uTlVMTDsKLQotICAvKioKLSAgICogVGhlIGNvbnRleHQgbm9kZSBmb3IgdGhpcyBpdGVyYXRvciwgd2hpY2ggZG9lc24ndCBjaGFuZ2UgdGhyb3VnaAotICAgKiB0aGUgY291cnNlIG9mIHRoZSBpdGVyYXRpb24uCi0gICAqLwotICB0cmFuc2llbnQgcHJvdGVjdGVkIGludCBtX2NvbnRleHQgPSBEVE0uTlVMTDsKLQotICAvKioKLSAgICogVGhlIG5vZGUgY29udGV4dCBmcm9tIHdoZXJlIHRoZSBleHByZXNzaW9uIGlzIGJlaW5nCi0gICAqIGV4ZWN1dGVkIGZyb20gKGkuZS4gZm9yIGN1cnJlbnQoKSBzdXBwb3J0KS4gIERpZmZlcmVudAotICAgKiBmcm9tIG1fY29udGV4dCBpbiB0aGF0IHRoaXMgaXMgdGhlIGNvbnRleHQgZm9yIHRoZSBlbnRpcmUKLSAgICogZXhwcmVzc2lvbiwgcmF0aGVyIHRoYW4gdGhlIGNvbnRleHQgZm9yIHRoZSBzdWJleHByZXNzaW9uLgotICAgKi8KLSAgdHJhbnNpZW50IHByb3RlY3RlZCBpbnQgbV9jdXJyZW50Q29udGV4dE5vZGUgPSBEVE0uTlVMTDsKLQotICAvKioKLSAgICogVGhlIGN1cnJlbnQgcG9zaXRpb24gb2YgdGhlIGNvbnRleHQgbm9kZS4KLSAgICovCi0gIHRyYW5zaWVudCBwcm90ZWN0ZWQgaW50IG1fcG9zID0gMDsKLQotICB0cmFuc2llbnQgcHJvdGVjdGVkIGludCBtX2xlbmd0aCA9IC0xOwotCi0gIC8qKgotICAgKiBGYXN0IGFjY2VzcyB0byB0aGUgY3VycmVudCBwcmVmaXggcmVzb2x2ZXIuICBJdCBpc24ndCByZWFsbHkKLSAgICogY2xlYXIgdGhhdCB0aGlzIGlzIG5lZWRlZC4KLSAgICogQHNlcmlhbAotICAgKi8KLSAgcHJpdmF0ZSBQcmVmaXhSZXNvbHZlciBtX3ByZWZpeFJlc29sdmVyOwotCi0gIC8qKgotICAgKiBUaGUgWFBhdGhDb250ZXh0IHJlZmVyZW5jZSwgbmVlZGVkIGZvciBleGVjdXRpb24gb2YgbWFueQotICAgKiBvcGVyYXRpb25zLgotICAgKi8KLSAgdHJhbnNpZW50IHByb3RlY3RlZCBYUGF0aENvbnRleHQgbV9leGVjQ29udGV4dDsKLQotICAvKioKLSAgICogUmV0dXJucyB0cnVlIGlmIGFsbCB0aGUgbm9kZXMgaW4gdGhlIGl0ZXJhdGlvbiB3ZWxsIGJlIHJldHVybmVkIGluIGRvY3VtZW50Ci0gICAqIG9yZGVyLgotICAgKgotICAgKiBAcmV0dXJuIHRydWUgYXMgYSBkZWZhdWx0LgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNEb2NPcmRlcmVkKCkKLSAgewotICAgIHJldHVybiB0cnVlOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIGF4aXMgYmVpbmcgaXRlcmF0ZWQsIGlmIGl0IGlzIGtub3duLgotICAgKgotICAgKiBAcmV0dXJuIEF4aXMuQ0hJTEQsIGV0Yy4sIG9yIC0xIGlmIHRoZSBheGlzIGlzIG5vdCBrbm93biBvciBpcyBvZiBtdWx0aXBsZQotICAgKiB0eXBlcy4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0QXhpcygpCi0gIHsKLSAgICByZXR1cm4gLTE7Ci0gIH0KLQotCi0vLyAgLyoqCi0vLyAgICogVGhlIGFuYWx5c2lzIHBhdHRlcm4gYnVpbHQgYnkgdGhlIFdhbGtlckZhY3RvcnkuCi0vLyAgICogVE9ETzogTW92ZSB0byBMb2NQYXRoSXRlcmF0b3IuCi0vLyAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuYXhlcy5XYWxrZXJGYWN0b3J5Ci0vLyAgICogQHNlcmlhbAotLy8gICAqLwotLy8gIHByb3RlY3RlZCBpbnQgbV9hbmFseXNpcyA9IDB4MDAwMDAwMDA7Ci0gIC8qKgotICAgKiBAc2VlIFByZWRpY2F0ZWROb2RlVGVzdCNnZXRMYXN0UG9zKFhQYXRoQ29udGV4dCkKLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0TGFzdFBvcyhYUGF0aENvbnRleHQgeGN0eHQpCi0gIHsKLSAgICByZXR1cm4gZ2V0TGVuZ3RoKCk7Ci0gIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9heGVzL01hdGNoUGF0dGVybkl0ZXJhdG9yLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2F4ZXMvTWF0Y2hQYXR0ZXJuSXRlcmF0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZWRiYTNhMi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2F4ZXMvTWF0Y2hQYXR0ZXJuSXRlcmF0b3IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDMzMyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBNYXRjaFBhdHRlcm5JdGVyYXRvci5qYXZhLHYgMS4yLjQuMiAyMDA1LzA5LzE0IDE5OjQ1OjIyIGplZmZzdXR0b3IgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuYXhlczsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkF4aXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTUF4aXNUcmF2ZXJzZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNSXRlcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoQ29udGV4dDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuY29tcGlsZXIuQ29tcGlsZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmNvbXBpbGVyLk9wTWFwOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhPYmplY3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLnBhdHRlcm5zLk5vZGVUZXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5wYXR0ZXJucy5TdGVwUGF0dGVybjsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIHRyZWF0cyBhCi0gKiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aCNsb2NhdGlvbi1wYXRocyI+TG9jYXRpb25QYXRoPC9hPiBhcyBhCi0gKiBmaWx0ZXJlZCBpdGVyYXRpb24gb3ZlciB0aGUgdHJlZSwgZXZhbHVhdGluZyBlYWNoIG5vZGUgaW4gYSBzdXBlciBheGlzCi0gKiB0cmF2ZXJzYWwgYWdhaW5zdCB0aGUgTG9jYXRpb25QYXRoIGludGVycHJldGVkIGFzIGEgbWF0Y2ggcGF0dGVybi4gIFRoaXMKLSAqIGNsYXNzIGlzIHVzZWZ1bCB0byBmaW5kIG5vZGVzIGluIGRvY3VtZW50IG9yZGVyIHRoYXQgYXJlIGNvbXBsZXggcGF0aHMKLSAqIHdob3NlIHN0ZXBzIHByb2JhYmx5IGNyaXNzLWNyb3NzIGVhY2ggb3RoZXIuCi0gKi8KLXB1YmxpYyBjbGFzcyBNYXRjaFBhdHRlcm5JdGVyYXRvciBleHRlbmRzIExvY1BhdGhJdGVyYXRvcgotewotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNTIwMTE1Mzc2NzM5NjI5NjQ3NEw7Ci0KLSAgLyoqIFRoaXMgaXMgdGhlIHNlbGVjdCBwYXR0ZXJuLCB0cmFuc2xhdGVkIGludG8gYSBtYXRjaCBwYXR0ZXJuLiAqLwotICBwcm90ZWN0ZWQgU3RlcFBhdHRlcm4gbV9wYXR0ZXJuOwotCi0gIC8qKiBUaGUgdHJhdmVyc2FsIGF4aXMgZnJvbSB3aGVyZSB0aGUgbm9kZXMgd2lsbCBiZSBmaWx0ZXJlZC4gKi8KLSAgcHJvdGVjdGVkIGludCBtX3N1cGVyQXhpcyA9IC0xOwotCi0gIC8qKiBUaGUgRFRNIGlubmVyIHRyYXZlcnNhbCBjbGFzcywgdGhhdCBjb3JyZXNwb25kcyB0byB0aGUgc3VwZXIgYXhpcy4gKi8KLSAgcHJvdGVjdGVkIERUTUF4aXNUcmF2ZXJzZXIgbV90cmF2ZXJzZXI7Ci0KLSAgLyoqIERFQlVHIGZsYWcgZm9yIGRpYWdub3N0aWMgZHVtcHMuICovCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW4gREVCVUcgPSBmYWxzZTsKLQotLy8gIHByb3RlY3RlZCBpbnQgbV9uc0VsZW1CYXNlID0gRFRNLk5VTEw7Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIExvY1BhdGhJdGVyYXRvciBvYmplY3QsIGluY2x1ZGluZyBjcmVhdGlvbgotICAgKiBvZiBzdGVwIHdhbGtlcnMgZnJvbSB0aGUgb3Bjb2RlIGxpc3QsIGFuZCBjYWxsIGJhY2sKLSAgICogaW50byB0aGUgQ29tcGlsZXIgdG8gY3JlYXRlIHByZWRpY2F0ZSBleHByZXNzaW9ucy4KLSAgICoKLSAgICogQHBhcmFtIGNvbXBpbGVyIFRoZSBDb21waWxlciB3aGljaCBpcyBjcmVhdGluZwotICAgKiB0aGlzIGV4cHJlc3Npb24uCi0gICAqIEBwYXJhbSBvcFBvcyBUaGUgcG9zaXRpb24gb2YgdGhpcyBpdGVyYXRvciBpbiB0aGUKLSAgICogb3Bjb2RlIGxpc3QgZnJvbSB0aGUgY29tcGlsZXIuCi0gICAqIEBwYXJhbSBhbmFseXNpcyBBbmFseXNpcyBiaXRzIHRoYXQgZ2l2ZSBnZW5lcmFsIGluZm9ybWF0aW9uIGFib3V0IHRoZQotICAgKiBMb2NhdGlvblBhdGguCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgTWF0Y2hQYXR0ZXJuSXRlcmF0b3IoQ29tcGlsZXIgY29tcGlsZXIsIGludCBvcFBvcywgaW50IGFuYWx5c2lzKQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIHN1cGVyKGNvbXBpbGVyLCBvcFBvcywgYW5hbHlzaXMsIGZhbHNlKTsKLQotICAgIGludCBmaXJzdFN0ZXBQb3MgPSBPcE1hcC5nZXRGaXJzdENoaWxkUG9zKG9wUG9zKTsKLQotICAgIG1fcGF0dGVybiA9IFdhbGtlckZhY3RvcnkubG9hZFN0ZXBzKHRoaXMsIGNvbXBpbGVyLCBmaXJzdFN0ZXBQb3MsIDApOwotCi0gICAgYm9vbGVhbiBmcm9tUm9vdCA9IGZhbHNlOwotICAgIGJvb2xlYW4gd2Fsa0JhY2sgPSBmYWxzZTsKLSAgICBib29sZWFuIHdhbGtEZXNjZW5kYW50cyA9IGZhbHNlOwotICAgIGJvb2xlYW4gd2Fsa0F0dHJpYnV0ZXMgPSBmYWxzZTsKLQotICAgIGlmICgwICE9IChhbmFseXNpcyAmIChXYWxrZXJGYWN0b3J5LkJJVF9ST09UIHwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgV2Fsa2VyRmFjdG9yeS5CSVRfQU5ZX0RFU0NFTkRBTlRfRlJPTV9ST09UKSkpCi0gICAgICBmcm9tUm9vdCA9IHRydWU7Ci0KLSAgICBpZiAoMCAhPSAoYW5hbHlzaXMKLSAgICAgICAgICAgICAgJiAoV2Fsa2VyRmFjdG9yeS5CSVRfQU5DRVNUT1IKLSAgICAgICAgICAgICAgICAgfCBXYWxrZXJGYWN0b3J5LkJJVF9BTkNFU1RPUl9PUl9TRUxGCi0gICAgICAgICAgICAgICAgIHwgV2Fsa2VyRmFjdG9yeS5CSVRfUFJFQ0VESU5HCi0gICAgICAgICAgICAgICAgIHwgV2Fsa2VyRmFjdG9yeS5CSVRfUFJFQ0VESU5HX1NJQkxJTkcKLSAgICAgICAgICAgICAgICAgfCBXYWxrZXJGYWN0b3J5LkJJVF9GT0xMT1dJTkcKLSAgICAgICAgICAgICAgICAgfCBXYWxrZXJGYWN0b3J5LkJJVF9GT0xMT1dJTkdfU0lCTElORwotICAgICAgICAgICAgICAgICB8IFdhbGtlckZhY3RvcnkuQklUX1BBUkVOVCB8IFdhbGtlckZhY3RvcnkuQklUX0ZJTFRFUikpKQotICAgICAgd2Fsa0JhY2sgPSB0cnVlOwotCi0gICAgaWYgKDAgIT0gKGFuYWx5c2lzCi0gICAgICAgICAgICAgICYgKFdhbGtlckZhY3RvcnkuQklUX0RFU0NFTkRBTlRfT1JfU0VMRgotICAgICAgICAgICAgICAgICB8IFdhbGtlckZhY3RvcnkuQklUX0RFU0NFTkRBTlQKLSAgICAgICAgICAgICAgICAgfCBXYWxrZXJGYWN0b3J5LkJJVF9DSElMRCkpKQotICAgICAgd2Fsa0Rlc2NlbmRhbnRzID0gdHJ1ZTsKLQotICAgIGlmICgwICE9IChhbmFseXNpcwotICAgICAgICAgICAgICAmIChXYWxrZXJGYWN0b3J5LkJJVF9BVFRSSUJVVEUgfCBXYWxrZXJGYWN0b3J5LkJJVF9OQU1FU1BBQ0UpKSkKLSAgICAgIHdhbGtBdHRyaWJ1dGVzID0gdHJ1ZTsKLQotICAgIGlmKGZhbHNlIHx8IERFQlVHKQotICAgIHsKLSAgICAgIFN5c3RlbS5vdXQucHJpbnQoImFuYWx5c2lzOiAiK0ludGVnZXIudG9CaW5hcnlTdHJpbmcoYW5hbHlzaXMpKTsKLSAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiLCAiK1dhbGtlckZhY3RvcnkuZ2V0QW5hbHlzaXNTdHJpbmcoYW5hbHlzaXMpKTsKLSAgICB9Ci0KLSAgICBpZihmcm9tUm9vdCB8fCB3YWxrQmFjaykKLSAgICB7Ci0gICAgICBpZih3YWxrQXR0cmlidXRlcykKLSAgICAgIHsKLSAgICAgICAgbV9zdXBlckF4aXMgPSBBeGlzLkFMTDsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgbV9zdXBlckF4aXMgPSBBeGlzLkRFU0NFTkRBTlRTRlJPTVJPT1Q7Ci0gICAgICB9Ci0gICAgfQotICAgIGVsc2UgaWYod2Fsa0Rlc2NlbmRhbnRzKQotICAgIHsKLSAgICAgIGlmKHdhbGtBdHRyaWJ1dGVzKQotICAgICAgewotICAgICAgICBtX3N1cGVyQXhpcyA9IEF4aXMuQUxMRlJPTU5PREU7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIG1fc3VwZXJBeGlzID0gQXhpcy5ERVNDRU5EQU5UT1JTRUxGOwotICAgICAgfQotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgbV9zdXBlckF4aXMgPSBBeGlzLkFMTDsKLSAgICB9Ci0gICAgaWYoZmFsc2UgfHwgREVCVUcpCi0gICAgewotICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJheGlzOiAiK0F4aXMuZ2V0TmFtZXMobV9zdXBlckF4aXMpKTsKLSAgICB9Ci0KLSAgfQotCi0KLSAgLyoqCi0gICAqIEluaXRpYWxpemUgdGhlIGNvbnRleHQgdmFsdWVzIGZvciB0aGlzIGV4cHJlc3Npb24KLSAgICogYWZ0ZXIgaXQgaXMgY2xvbmVkLgotICAgKgotICAgKiBAcGFyYW0gY29udGV4dCBUaGUgWFBhdGggcnVudGltZSBjb250ZXh0IGZvciB0aGlzCi0gICAqIHRyYW5zZm9ybWF0aW9uLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0Um9vdChpbnQgY29udGV4dCwgT2JqZWN0IGVudmlyb25tZW50KQotICB7Ci0gICAgc3VwZXIuc2V0Um9vdChjb250ZXh0LCBlbnZpcm9ubWVudCk7Ci0gICAgbV90cmF2ZXJzZXIgPSBtX2NkdG0uZ2V0QXhpc1RyYXZlcnNlcihtX3N1cGVyQXhpcyk7Ci0gIH0KLQotICAvKioKLSAgICogIERldGFjaGVzIHRoZSBpdGVyYXRvciBmcm9tIHRoZSBzZXQgd2hpY2ggaXQgaXRlcmF0ZWQgb3ZlciwgcmVsZWFzaW5nCi0gICAqIGFueSBjb21wdXRhdGlvbmFsIHJlc291cmNlcyBhbmQgcGxhY2luZyB0aGUgaXRlcmF0b3IgaW4gdGhlIElOVkFMSUQKLSAgICogc3RhdGUuIEFmdGVyPGNvZGU+ZGV0YWNoPC9jb2RlPiBoYXMgYmVlbiBpbnZva2VkLCBjYWxscyB0bwotICAgKiA8Y29kZT5uZXh0Tm9kZTwvY29kZT4gb3I8Y29kZT5wcmV2aW91c05vZGU8L2NvZGU+IHdpbGwgcmFpc2UgdGhlCi0gICAqIGV4Y2VwdGlvbiBJTlZBTElEX1NUQVRFX0VSUi4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGRldGFjaCgpCi0gIHsKLSAgICBpZihtX2FsbG93RGV0YWNoKQotICAgIHsKLSAgICAgIG1fdHJhdmVyc2VyID0gbnVsbDsKLQotICAgICAgLy8gQWx3YXlzIGNhbGwgdGhlIHN1cGVyY2xhc3MgZGV0YWNoIGxhc3QhCi0gICAgICBzdXBlci5kZXRhY2goKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBuZXh0IG5vZGUgdmlhIGdldE5leHRYWFguICBCb3R0bGVuZWNrZWQgZm9yIGRlcml2ZWQgY2xhc3Mgb3ZlcnJpZGUuCi0gICAqIEByZXR1cm4gVGhlIG5leHQgbm9kZSBvbiB0aGUgYXhpcywgb3IgRFRNLk5VTEwuCi0gICAqLwotICBwcm90ZWN0ZWQgaW50IGdldE5leHROb2RlKCkKLSAgewotICAgIG1fbGFzdEZldGNoZWQgPSAoRFRNLk5VTEwgPT0gbV9sYXN0RmV0Y2hlZCkKLSAgICAgICAgICAgICAgICAgICAgID8gbV90cmF2ZXJzZXIuZmlyc3QobV9jb250ZXh0KQotICAgICAgICAgICAgICAgICAgICAgOiBtX3RyYXZlcnNlci5uZXh0KG1fY29udGV4dCwgbV9sYXN0RmV0Y2hlZCk7Ci0gICAgcmV0dXJuIG1fbGFzdEZldGNoZWQ7Ci0gIH0KLQotICAvKioKLSAgICogIFJldHVybnMgdGhlIG5leHQgbm9kZSBpbiB0aGUgc2V0IGFuZCBhZHZhbmNlcyB0aGUgcG9zaXRpb24gb2YgdGhlCi0gICAqIGl0ZXJhdG9yIGluIHRoZSBzZXQuIEFmdGVyIGEgTm9kZUl0ZXJhdG9yIGlzIGNyZWF0ZWQsIHRoZSBmaXJzdCBjYWxsCi0gICAqIHRvIG5leHROb2RlKCkgcmV0dXJucyB0aGUgZmlyc3Qgbm9kZSBpbiB0aGUgc2V0LgotICAgKiBAcmV0dXJuICBUaGUgbmV4dCA8Y29kZT5Ob2RlPC9jb2RlPiBpbiB0aGUgc2V0IGJlaW5nIGl0ZXJhdGVkIG92ZXIsIG9yCi0gICAqICAgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlcmUgYXJlIG5vIG1vcmUgbWVtYmVycyBpbiB0aGF0IHNldC4KLSAgICovCi0gIHB1YmxpYyBpbnQgbmV4dE5vZGUoKQotICB7Ci0gICAgICAgIGlmKG1fZm91bmRMYXN0KQotICAgICAgICAgICAgICAgIHJldHVybiBEVE0uTlVMTDsKLQotICAgIGludCBuZXh0OwotCi0gICAgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlZhcmlhYmxlU3RhY2sgdmFyczsKLSAgICBpbnQgc2F2ZWRTdGFydDsKLSAgICBpZiAoLTEgIT0gbV9zdGFja0ZyYW1lKQotICAgIHsKLSAgICAgIHZhcnMgPSBtX2V4ZWNDb250ZXh0LmdldFZhclN0YWNrKCk7Ci0KLSAgICAgIC8vIFRoZXNlIHRocmVlIHN0YXRlbWVudHMgbmVlZCB0byBiZSBjb21iaW5lZCBpbnRvIG9uZSBvcGVyYXRpb24uCi0gICAgICBzYXZlZFN0YXJ0ID0gdmFycy5nZXRTdGFja0ZyYW1lKCk7Ci0KLSAgICAgIHZhcnMuc2V0U3RhY2tGcmFtZShtX3N0YWNrRnJhbWUpOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgLy8gWXVjay4gIEp1c3QgdG8gc2h1dCB1cCB0aGUgY29tcGlsZXIhCi0gICAgICB2YXJzID0gbnVsbDsKLSAgICAgIHNhdmVkU3RhcnQgPSAwOwotICAgIH0KLQotICAgIHRyeQotICAgIHsKLSAgICAgIGlmKERFQlVHKQotICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIm1fcGF0dGVybiIrbV9wYXR0ZXJuLnRvU3RyaW5nKCkpOwotCi0gICAgICBkbwotICAgICAgewotICAgICAgICBuZXh0ID0gZ2V0TmV4dE5vZGUoKTsKLQotICAgICAgICBpZiAoRFRNLk5VTEwgIT0gbmV4dCkKLSAgICAgICAgewotICAgICAgICAgIGlmKERUTUl0ZXJhdG9yLkZJTFRFUl9BQ0NFUFQgPT0gYWNjZXB0Tm9kZShuZXh0LCBtX2V4ZWNDb250ZXh0KSkKLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICBicmVhazsKLSAgICAgIH0KLSAgICAgIHdoaWxlIChuZXh0ICE9IERUTS5OVUxMKTsKLQotICAgICAgaWYgKERUTS5OVUxMICE9IG5leHQpCi0gICAgICB7Ci0gICAgICAgIGlmKERFQlVHKQotICAgICAgICB7Ci0gICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJuZXh0OiAiK25leHQpOwotICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigibmFtZTogIittX2NkdG0uZ2V0Tm9kZU5hbWUobmV4dCkpOwotICAgICAgICB9Ci0gICAgICAgIGluY3JlbWVudEN1cnJlbnRQb3MoKTsKLQotICAgICAgICByZXR1cm4gbmV4dDsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgbV9mb3VuZExhc3QgPSB0cnVlOwotCi0gICAgICAgIHJldHVybiBEVE0uTlVMTDsKLSAgICAgIH0KLSAgICB9Ci0gICAgZmluYWxseQotICAgIHsKLSAgICAgIGlmICgtMSAhPSBtX3N0YWNrRnJhbWUpCi0gICAgICB7Ci0gICAgICAgIC8vIFRoZXNlIHR3byBzdGF0ZW1lbnRzIG5lZWQgdG8gYmUgY29tYmluZWQgaW50byBvbmUgb3BlcmF0aW9uLgotICAgICAgICB2YXJzLnNldFN0YWNrRnJhbWUoc2F2ZWRTdGFydCk7Ci0gICAgICB9Ci0gICAgfQotCi0gIH0KLQotICAvKioKLSAgICogIFRlc3Qgd2hldGhlciBhIHNwZWNpZmllZCBub2RlIGlzIHZpc2libGUgaW4gdGhlIGxvZ2ljYWwgdmlldyBvZiBhCi0gICAqIFRyZWVXYWxrZXIgb3IgTm9kZUl0ZXJhdG9yLiBUaGlzIGZ1bmN0aW9uIHdpbGwgYmUgY2FsbGVkIGJ5IHRoZQotICAgKiBpbXBsZW1lbnRhdGlvbiBvZiBUcmVlV2Fsa2VyIGFuZCBOb2RlSXRlcmF0b3I7IGl0IGlzIG5vdCBpbnRlbmRlZCB0bwotICAgKiBiZSBjYWxsZWQgZGlyZWN0bHkgZnJvbSB1c2VyIGNvZGUuCi0gICAqIEBwYXJhbSBuICBUaGUgbm9kZSB0byBjaGVjayB0byBzZWUgaWYgaXQgcGFzc2VzIHRoZSBmaWx0ZXIgb3Igbm90LgotICAgKiBAcmV0dXJuICBhIGNvbnN0YW50IHRvIGRldGVybWluZSB3aGV0aGVyIHRoZSBub2RlIGlzIGFjY2VwdGVkLAotICAgKiAgIHJlamVjdGVkLCBvciBza2lwcGVkLCBhcyBkZWZpbmVkICBhYm92ZSAuCi0gICAqLwotICBwdWJsaWMgc2hvcnQgYWNjZXB0Tm9kZShpbnQgbiwgWFBhdGhDb250ZXh0IHhjdHh0KQotICB7Ci0KLSAgICB0cnkKLSAgICB7Ci0gICAgICB4Y3R4dC5wdXNoQ3VycmVudE5vZGUobik7Ci0gICAgICB4Y3R4dC5wdXNoSXRlcmF0b3JSb290KG1fY29udGV4dCk7Ci0gICAgICBpZihERUJVRykKLSAgICAgIHsKLSAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJ0cmF2ZXJzZXI6ICIrbV90cmF2ZXJzZXIpOwotICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCJub2RlOiAiK24pOwotICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIiwgIittX2NkdG0uZ2V0Tm9kZU5hbWUobikpOwotICAgICAgICAvLyBpZihtX2NkdG0uZ2V0Tm9kZU5hbWUobikuZXF1YWxzKCJuZWFyLWVhc3QiKSkKLSAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJwYXR0ZXJuOiAiK21fcGF0dGVybi50b1N0cmluZygpKTsKLSAgICAgICAgbV9wYXR0ZXJuLmRlYnVnV2hhdFRvU2hvdyhtX3BhdHRlcm4uZ2V0V2hhdFRvU2hvdygpKTsKLSAgICAgIH0KLQotICAgICAgWE9iamVjdCBzY29yZSA9IG1fcGF0dGVybi5leGVjdXRlKHhjdHh0KTsKLQotICAgICAgaWYoREVCVUcpCi0gICAgICB7Ci0gICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiYW5hbHlzaXM6ICIrSW50ZWdlci50b0JpbmFyeVN0cmluZyhtX2FuYWx5c2lzKSk7Ci0gICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigic2NvcmU6ICIrc2NvcmUpOwotICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oInNraXA6ICIrKHNjb3JlID09IE5vZGVUZXN0LlNDT1JFX05PTkUpKTsKLSAgICAgIH0KLQotICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJcbjo6YWNjZXB0Tm9kZSAtIHNjb3JlOiAiK3Njb3JlLm51bSgpKyI6OiIpOwotICAgICAgcmV0dXJuIChzY29yZSA9PSBOb2RlVGVzdC5TQ09SRV9OT05FKSA/IERUTUl0ZXJhdG9yLkZJTFRFUl9TS0lQCi0gICAgICAgICAgICAgICAgICAgIDogRFRNSXRlcmF0b3IuRklMVEVSX0FDQ0VQVDsKLSAgICB9Ci0gICAgY2F0Y2ggKGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24gc2UpCi0gICAgewotCi0gICAgICAvLyBUT0RPOiBGaXggdGhpcy4KLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKHNlLmdldE1lc3NhZ2UoKSk7Ci0gICAgfQotICAgIGZpbmFsbHkKLSAgICB7Ci0gICAgICB4Y3R4dC5wb3BDdXJyZW50Tm9kZSgpOwotICAgICAgeGN0eHQucG9wSXRlcmF0b3JSb290KCk7Ci0gICAgfQotCi0gIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9heGVzL05vZGVTZXF1ZW5jZS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9heGVzL05vZGVTZXF1ZW5jZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1M2U1Mjg3Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvYXhlcy9Ob2RlU2VxdWVuY2UuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDk2MSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAyLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBOb2RlU2VxdWVuY2UuamF2YSx2IDEuNiAyMDA3LzAxLzEyIDE5OjI2OjQyIHNwZXJpY2FzIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmF4ZXM7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTUZpbHRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1JdGVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1NYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuTm9kZVZlY3RvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuTm9kZVNldERUTTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuWFBhdGhDb250ZXh0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhPYmplY3Q7Ci0KLS8qKgotICogVGhpcyBjbGFzcyBpcyB0aGUgZHluYW1pYyB3cmFwcGVyIGZvciBhIFhhbGFuIERUTUl0ZXJhdG9yIGluc3RhbmNlLCBhbmQKLSAqIHByb3ZpZGVzIHJhbmRvbSBhY2Nlc3MgY2FwYWJpbGl0aWVzLgotICovCi1wdWJsaWMgY2xhc3MgTm9kZVNlcXVlbmNlIGV4dGVuZHMgWE9iamVjdAotICBpbXBsZW1lbnRzIERUTUl0ZXJhdG9yLCBDbG9uZWFibGUsIFBhdGhDb21wb25lbnQKLXsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMzg2NjI2MTkzNDcyNjU4MTA0NEw7Ci0gIC8qKiBUaGUgaW5kZXggb2YgdGhlIGxhc3Qgbm9kZSBpbiB0aGUgaXRlcmF0aW9uLiAqLwotICBwcm90ZWN0ZWQgaW50IG1fbGFzdCA9IC0xOwotCi0gIC8qKgotICAgKiBUaGUgaW5kZXggb2YgdGhlIG5leHQgbm9kZSB0byBiZSBmZXRjaGVkLiAgVXNlZnVsIGlmIHRoaXMKLSAgICogaXMgYSBjYWNoZWQgaXRlcmF0b3IsIGFuZCBpcyBiZWluZyB1c2VkIGFzIHJhbmRvbSBhY2Nlc3MKLSAgICogTm9kZUxpc3QuCi0gICAqLwotICBwcm90ZWN0ZWQgaW50IG1fbmV4dCA9IDA7Ci0KLSAgLyoqCi0gICAqIEEgY2FjaGUgb2YgYSBsaXN0IG9mIG5vZGVzIG9idGFpbmVkIGZyb20gdGhlIGl0ZXJhdG9yIHNvIGZhci4KLSAgICogVGhpcyBsaXN0IGlzIGFwcGVuZGVkIHRvIHVudGlsIHRoZSBpdGVyYXRvciBpcyBleGhhdXN0ZWQgYW5kCi0gICAqIHRoZSBjYWNoZSBpcyBjb21wbGV0ZS4KLSAgICogPHA+Ci0gICAqIE11bHRpcGxlIE5vZGVTZXF1ZW5jZSBvYmplY3RzIG1heSBzaGFyZSB0aGUgc2FtZSBjYWNoZS4KLSAgICovCi0gIHByaXZhdGUgSXRlcmF0b3JDYWNoZSBtX2NhY2hlOwotCi0gIC8qKgotICAgKiBJZiB0aGlzIGl0ZXJhdG9yIG5lZWRzIHRvIGNhY2hlIG5vZGVzIHRoYXQgYXJlIGZldGNoZWQsIHRoZXkKLSAgICogYXJlIHN0b3JlZCBpbiB0aGUgVmVjdG9yIGluIHRoZSBnZW5lcmljIG9iamVjdC4KLSAgICovCi0gIHByb3RlY3RlZCBOb2RlVmVjdG9yIGdldFZlY3RvcigpIHsKLSAgICAgIE5vZGVWZWN0b3IgbnYgPSAobV9jYWNoZSAhPSBudWxsKSA/ICBtX2NhY2hlLmdldFZlY3RvcigpIDogbnVsbDsKLSAgICAgIHJldHVybiBudjsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGNhY2hlIChpZiBhbnkpIG9mIG5vZGVzIG9idGFpbmVkIGZyb20KLSAgICogdGhlIGl0ZXJhdG9yIHNvIGZhci4gTm90ZSB0aGF0IHRoZSBjYWNoZSBrZWVwcwotICAgKiBncm93aW5nIHVudGlsIHRoZSBpdGVyYXRvciBpcyB3YWxrZWQgdG8gZXhoYXVzdGlvbiwKLSAgICogYXQgd2hpY2ggcG9pbnQgdGhlIGNhY2hlIGlzICJjb21wbGV0ZSIuCi0gICAqLwotICBwcml2YXRlIEl0ZXJhdG9yQ2FjaGUgZ2V0Q2FjaGUoKSB7Ci0gICAgICByZXR1cm4gbV9jYWNoZTsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIHZlY3RvciB3aGVyZSBub2RlcyB3aWxsIGJlIGNhY2hlZC4KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIFNldFZlY3RvcihOb2RlVmVjdG9yIHYpCi0gIHsKLSAgICAgICAgc2V0T2JqZWN0KHYpOwotICB9Ci0KLQotICAvKioKLSAgICogSWYgdGhlIGl0ZXJhdG9yIG5lZWRzIHRvIGNhY2hlIG5vZGVzIGFzIHRoZXkgYXJlIGZldGNoZWQsCi0gICAqIHRoZW4gdGhpcyBtZXRob2QgcmV0dXJucyB0cnVlLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaGFzQ2FjaGUoKQotICB7Ci0gICAgZmluYWwgTm9kZVZlY3RvciBudiA9IGdldFZlY3RvcigpOwotICAgICAgICByZXR1cm4gKG52ICE9IG51bGwpOwotICB9Ci0KLSAgLyoqCi0gICAqIElmIHRoaXMgTm9kZVNlcXVlbmNlIGhhcyBhIGNhY2hlLCBhbmQgdGhhdCBjYWNoZSBpcwotICAgKiBmdWxseSBwb3B1bGF0ZWQgdGhlbiB0aGlzIG1ldGhvZCByZXR1cm5zIHRydWUsIG90aGVyd2lzZQotICAgKiBpZiB0aGVyZSBpcyBubyBjYWNoZSBvciBpdCBpcyBub3QgY29tcGxldGUgaXQgcmV0dXJucyBmYWxzZS4KLSAgICovCi0gIHByaXZhdGUgYm9vbGVhbiBjYWNoZUNvbXBsZXRlKCkgewotICAgICAgZmluYWwgYm9vbGVhbiBjb21wbGV0ZTsKLSAgICAgIGlmIChtX2NhY2hlICE9IG51bGwpIHsKLSAgICAgICAgICBjb21wbGV0ZSA9IG1fY2FjaGUuaXNDb21wbGV0ZSgpOwotICAgICAgfSBlbHNlIHsKLSAgICAgICAgICBjb21wbGV0ZSA9IGZhbHNlOwotICAgICAgfQotICAgICAgcmV0dXJuIGNvbXBsZXRlOwotICB9Ci0KLSAgLyoqCi0gICAqIElmIHRoaXMgTm9kZVNlcXVlbmNlIGhhcyBhIGNhY2hlLCBtYXJrIHRoYXQgaXQgaXMgY29tcGxldGUuCi0gICAqIFRoaXMgbWV0aG9kIHNob3VsZCBiZSBjYWxsZWQgYWZ0ZXIgdGhlIGl0ZXJhdG9yIGlzIGV4aGF1c3RlZC4KLSAgICovCi0gIHByaXZhdGUgdm9pZCBtYXJrQ2FjaGVDb21wbGV0ZSgpIHsKLSAgICAgIE5vZGVWZWN0b3IgbnYgPSBnZXRWZWN0b3IoKTsKLSAgICAgIGlmIChudiAhPSBudWxsKSB7Ci0gICAgICAgICAgbV9jYWNoZS5zZXRDYWNoZUNvbXBsZXRlKHRydWUpOwotICAgICAgfQotICB9Ci0KLQotICAvKioKLSAgICogVGhlIGZ1bmN0aW9uYWwgaXRlcmF0b3IgdGhhdCBmZXRjaGVzIG5vZGVzLgotICAgKi8KLSAgcHJvdGVjdGVkIERUTUl0ZXJhdG9yIG1faXRlcjsKLQotICAvKioKLSAgICogU2V0IHRoZSBmdW5jdGlvbmFsIGl0ZXJhdG9yIHRoYXQgZmV0Y2hlcyBub2Rlcy4KLSAgICogQHBhcmFtIGl0ZXIgVGhlIGl0ZXJhdG9yIHRoYXQgaXMgdG8gYmUgY29udGFpbmVkLgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgc2V0SXRlcihEVE1JdGVyYXRvciBpdGVyKQotICB7Ci0gICAgICAgIG1faXRlciA9IGl0ZXI7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBmdW5jdGlvbmFsIGl0ZXJhdG9yIHRoYXQgZmV0Y2hlcyBub2Rlcy4KLSAgICogQHJldHVybiBUaGUgY29udGFpbmVkIGl0ZXJhdG9yLgotICAgKi8KLSAgcHVibGljIGZpbmFsIERUTUl0ZXJhdG9yIGdldENvbnRhaW5lZEl0ZXIoKQotICB7Ci0gICAgICAgIHJldHVybiBtX2l0ZXI7Ci0gIH0KLQotICAvKioKLSAgICogVGhlIERUTU1hbmFnZXIgdG8gdXNlIGlmIHdlJ3JlIHVzaW5nIGEgTm9kZVZlY3RvciBvbmx5LgotICAgKiBXZSBtYXkgd2VsbCB3YW50IHRvIGRvIGF3YXkgd2l0aCB0aGlzLCBhbmQgc3RvcmUgaXQgaW4gdGhlIE5vZGVWZWN0b3IuCi0gICAqLwotICBwcm90ZWN0ZWQgRFRNTWFuYWdlciBtX2R0bU1ncjsKLQotICAvLyA9PT09IENvbnN0cnVjdG9ycyA9PT09Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIG5ldyBOb2RlU2VxdWVuY2UgZnJvbSBhIChhbHJlYWR5IGNsb25lZCkgaXRlcmF0b3IuCi0gICAqCi0gICAqIEBwYXJhbSBpdGVyIENsb25lZCAobm90IHN0YXRpYykgRFRNSXRlcmF0b3IuCi0gICAqIEBwYXJhbSBjb250ZXh0IFRoZSBpbml0aWFsIGNvbnRleHQgbm9kZS4KLSAgICogQHBhcmFtIHhjdHh0IFRoZSBleGVjdXRpb24gY29udGV4dC4KLSAgICogQHBhcmFtIHNob3VsZENhY2hlTm9kZXMgVHJ1ZSBpZiB0aGlzIHNlcXVlbmNlIGNhbiByYW5kb20gYWNjZXNzLgotICAgKi8KLSAgcHJpdmF0ZSBOb2RlU2VxdWVuY2UoRFRNSXRlcmF0b3IgaXRlciwgaW50IGNvbnRleHQsIFhQYXRoQ29udGV4dCB4Y3R4dCwgYm9vbGVhbiBzaG91bGRDYWNoZU5vZGVzKQotICB7Ci0gICAgICAgIHNldEl0ZXIoaXRlcik7Ci0gICAgICAgIHNldFJvb3QoY29udGV4dCwgeGN0eHQpOwotICAgICAgICBzZXRTaG91bGRDYWNoZU5vZGVzKHNob3VsZENhY2hlTm9kZXMpOwotICB9Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIG5ldyBOb2RlU2VxdWVuY2UgZnJvbSBhIChhbHJlYWR5IGNsb25lZCkgaXRlcmF0b3IuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlVmVjdG9yCi0gICAqLwotICBwdWJsaWMgTm9kZVNlcXVlbmNlKE9iamVjdCBub2RlVmVjdG9yKQotICB7Ci0gICAgICAgIHN1cGVyKG5vZGVWZWN0b3IpOwotICAgIGlmIChub2RlVmVjdG9yIGluc3RhbmNlb2YgTm9kZVZlY3RvcikgewotICAgICAgICBTZXRWZWN0b3IoKE5vZGVWZWN0b3IpIG5vZGVWZWN0b3IpOwotICAgIH0KLSAgICAgICAgaWYobnVsbCAhPSBub2RlVmVjdG9yKQotICAgICAgICB7Ci0gICAgICAgICAgICAgICAgYXNzZXJ0aW9uKG5vZGVWZWN0b3IgaW5zdGFuY2VvZiBOb2RlVmVjdG9yLAotICAgICAgICAgICAgICAgICAgICAgICAgIk11c3QgaGF2ZSBhIE5vZGVWZWN0b3IgYXMgdGhlIG9iamVjdCBmb3IgTm9kZVNlcXVlbmNlISIpOwotICAgICAgICAgICAgICAgIGlmKG5vZGVWZWN0b3IgaW5zdGFuY2VvZiBEVE1JdGVyYXRvcikKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzZXRJdGVyKChEVE1JdGVyYXRvcilub2RlVmVjdG9yKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIG1fbGFzdCA9ICgoRFRNSXRlcmF0b3Ipbm9kZVZlY3RvcikuZ2V0TGVuZ3RoKCk7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYW4gZW1wdHkgWE5vZGVTZXQgb2JqZWN0LiAgVGhpcyBpcyB1c2VkIHRvIGNyZWF0ZSBhIG11dGFibGUKLSAgICogbm9kZXNldCB0byB3aGljaCByYW5kb20gbm9kZXMgbWF5IGJlIGFkZGVkLgotICAgKi8KLSAgcHJpdmF0ZSBOb2RlU2VxdWVuY2UoRFRNTWFuYWdlciBkdG1NZ3IpCi0gIHsKLSAgICBzdXBlcihuZXcgTm9kZVZlY3RvcigpKTsKLSAgICBtX2xhc3QgPSAwOwotICAgIG1fZHRtTWdyID0gZHRtTWdyOwotICB9Ci0KLQotICAvKioKLSAgICogQ3JlYXRlIGEgbmV3IE5vZGVTZXF1ZW5jZSBpbiBhbiBpbnZhbGlkIChudWxsKSBzdGF0ZS4KLSAgICovCi0gIHB1YmxpYyBOb2RlU2VxdWVuY2UoKQotICB7Ci0gICAgICByZXR1cm47Ci0gIH0KLQotCi0gIC8qKgotICAgKiBAc2VlIERUTUl0ZXJhdG9yI2dldERUTShpbnQpCi0gICAqLwotICBwdWJsaWMgRFRNIGdldERUTShpbnQgbm9kZUhhbmRsZSkKLSAgewotICAgICAgICBEVE1NYW5hZ2VyIG1nciA9IGdldERUTU1hbmFnZXIoKTsKLSAgICAgICAgaWYobnVsbCAhPSBtZ3IpCi0gICAgICAgIHJldHVybiBnZXREVE1NYW5hZ2VyKCkuZ2V0RFRNKG5vZGVIYW5kbGUpOwotICAgIGVsc2UKLSAgICB7Ci0gICAgICAgIGFzc2VydGlvbihmYWxzZSwgIkNhbiBub3QgZ2V0IGEgRFRNIFVubGVzcyBhIERUTU1hbmFnZXIgaGFzIGJlZW4gc2V0ISIpOwotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogQHNlZSBEVE1JdGVyYXRvciNnZXREVE1NYW5hZ2VyKCkKLSAgICovCi0gIHB1YmxpYyBEVE1NYW5hZ2VyIGdldERUTU1hbmFnZXIoKQotICB7Ci0gICAgcmV0dXJuIG1fZHRtTWdyOwotICB9Ci0KLSAgLyoqCi0gICAqIEBzZWUgRFRNSXRlcmF0b3IjZ2V0Um9vdCgpCi0gICAqLwotICBwdWJsaWMgaW50IGdldFJvb3QoKQotICB7Ci0gICAgICAgIGlmKG51bGwgIT0gbV9pdGVyKQotICAgICAgICByZXR1cm4gbV9pdGVyLmdldFJvb3QoKTsKLSAgICAgICAgZWxzZQotICAgICAgICB7Ci0gICAgICAgICAgICAgICAgLy8gTm9kZVNldERUTSB3aWxsIGNhbGwgdGhpcywgYW5kIHNvIGl0J3Mgbm90IGEgZ29vZCB0aGluZyB0byB0aHJvdwotICAgICAgICAgICAgICAgIC8vIGFuIGFzc2VydGlvbiBoZXJlLgotICAgICAgICAgICAgICAgIC8vIGFzc2VydGlvbihmYWxzZSwgIkNhbiBub3QgZ2V0IHRoZSByb290IGZyb20gYSBub24taXRlcmF0ZWQgTm9kZVNlcXVlbmNlISIpOwotICAgICAgICAgICAgICAgIHJldHVybiBEVE0uTlVMTDsKLSAgICAgICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEBzZWUgRFRNSXRlcmF0b3Ijc2V0Um9vdChpbnQsIE9iamVjdCkKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFJvb3QoaW50IG5vZGVIYW5kbGUsIE9iamVjdCBlbnZpcm9ubWVudCkKLSAgewotICAgICAgICAvLyBJZiByb290IGlzIERUTS5OVUxMLCB0aGVuIHNvbWV0aGluZydzIHdyb25nIHdpdGggdGhlIGNvbnRleHQKLSAgICAgICAgaWYgKG5vZGVIYW5kbGUgPT0gRFRNLk5VTEwpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJVbmFibGUgdG8gZXZhbHVhdGUgZXhwcmVzc2lvbiB1c2luZyAiICsKLSAgICAgICAgICAgICAgICAgICAgInRoaXMgY29udGV4dCIpOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYobnVsbCAhPSBtX2l0ZXIpCi0gICAgICAgIHsKLSAgICAgICAgICAgICAgICBYUGF0aENvbnRleHQgeGN0eHQgPSAoWFBhdGhDb250ZXh0KWVudmlyb25tZW50OwotICAgICAgICAgICAgICAgIG1fZHRtTWdyID0geGN0eHQuZ2V0RFRNTWFuYWdlcigpOwotICAgICAgICAgICAgICAgIG1faXRlci5zZXRSb290KG5vZGVIYW5kbGUsIGVudmlyb25tZW50KTsKLSAgICAgICAgICAgICAgICBpZighbV9pdGVyLmlzRG9jT3JkZXJlZCgpKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmKCFoYXNDYWNoZSgpKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRTaG91bGRDYWNoZU5vZGVzKHRydWUpOwotICAgICAgICAgICAgICAgICAgICAgICAgcnVuVG8oLTEpOwotICAgICAgICAgICAgICAgICAgICAgICAgbV9uZXh0PTA7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICBhc3NlcnRpb24oZmFsc2UsICJDYW4gbm90IHNldFJvb3Qgb24gYSBub24taXRlcmF0ZWQgTm9kZVNlcXVlbmNlISIpOwotICB9Ci0KLSAgLyoqCi0gICAqIEBzZWUgRFRNSXRlcmF0b3IjcmVzZXQoKQotICAgKi8KLSAgcHVibGljIHZvaWQgcmVzZXQoKQotICB7Ci0gICAgICAgIG1fbmV4dCA9IDA7Ci0gICAgICAgIC8vIG5vdCByZXNldHRpbmcgdGhlIGl0ZXJhdG9yIG9uIHB1cnBvc2UhISEKLSAgfQotCi0gIC8qKgotICAgKiBAc2VlIERUTUl0ZXJhdG9yI2dldFdoYXRUb1Nob3coKQotICAgKi8KLSAgcHVibGljIGludCBnZXRXaGF0VG9TaG93KCkKLSAgewotICAgIHJldHVybiBoYXNDYWNoZSgpID8gKERUTUZpbHRlci5TSE9XX0FMTCAmIH5EVE1GaWx0ZXIuU0hPV19FTlRJVFlfUkVGRVJFTkNFKQotICAgICAgICA6IG1faXRlci5nZXRXaGF0VG9TaG93KCk7Ci0gIH0KLQotICAvKioKLSAgICogQHNlZSBEVE1JdGVyYXRvciNnZXRFeHBhbmRFbnRpdHlSZWZlcmVuY2VzKCkKLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGdldEV4cGFuZEVudGl0eVJlZmVyZW5jZXMoKQotICB7Ci0gICAgICAgIGlmKG51bGwgIT0gbV9pdGVyKQotICAgICAgICAgICAgICAgIHJldHVybiBtX2l0ZXIuZ2V0RXhwYW5kRW50aXR5UmVmZXJlbmNlcygpOwotICAgICAgICBlbHNlCi0gICAgICAgIHJldHVybiB0cnVlOwotICB9Ci0KLSAgLyoqCi0gICAqIEBzZWUgRFRNSXRlcmF0b3IjbmV4dE5vZGUoKQotICAgKi8KLSAgcHVibGljIGludCBuZXh0Tm9kZSgpCi0gIHsKLSAgICAvLyBJZiB0aGUgY2FjaGUgaXMgb24sIGFuZCB0aGUgbm9kZSBoYXMgYWxyZWFkeSBiZWVuIGZvdW5kLCB0aGVuCi0gICAgLy8ganVzdCByZXR1cm4gZnJvbSB0aGUgbGlzdC4KLSAgICBOb2RlVmVjdG9yIHZlYyA9IGdldFZlY3RvcigpOwotICAgIGlmIChudWxsICE9IHZlYykKLSAgICB7Ci0gICAgICAgIC8vIFRoZXJlIGlzIGEgY2FjaGUKLSAgICAgICAgaWYobV9uZXh0IDwgdmVjLnNpemUoKSkKLSAgICAgICAgewotICAgICAgICAgICAgLy8gVGhlIG5vZGUgaXMgaW4gdGhlIGNhY2hlLCBzbyBqdXN0IHJldHVybiBpdC4KLSAgICAgICAgICAgICAgICAgICAgICAgIGludCBuZXh0ID0gdmVjLmVsZW1lbnRBdChtX25leHQpOwotICAgICAgICAgICAgICAgIG1fbmV4dCsrOwotICAgICAgICAgICAgICAgIHJldHVybiBuZXh0OwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYoY2FjaGVDb21wbGV0ZSgpIHx8ICgtMSAhPSBtX2xhc3QpIHx8IChudWxsID09IG1faXRlcikpCi0gICAgICAgIHsKLSAgICAgICAgICAgICAgICBtX25leHQrKzsKLSAgICAgICAgICAgICAgICByZXR1cm4gRFRNLk5VTEw7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgaWYgKG51bGwgPT0gbV9pdGVyKQotICAgIHJldHVybiBEVE0uTlVMTDsKLQotICAgICAgICBpbnQgbmV4dCA9IG1faXRlci5uZXh0Tm9kZSgpOwotICAgIGlmKERUTS5OVUxMICE9IG5leHQpCi0gICAgewotICAgICAgICBpZihoYXNDYWNoZSgpKQotICAgICAgICB7Ci0gICAgICAgICAgICAgICAgaWYobV9pdGVyLmlzRG9jT3JkZXJlZCgpKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgZ2V0VmVjdG9yKCkuYWRkRWxlbWVudChuZXh0KTsKLSAgICAgICAgICAgICAgICAgICAgICAgIG1fbmV4dCsrOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgaW50IGluc2VydEluZGV4ID0gYWRkTm9kZUluRG9jT3JkZXIobmV4dCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZihpbnNlcnRJbmRleCA+PSAwKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX25leHQrKzsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIG1fbmV4dCsrOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgICAvLyBXZSBoYXZlIGV4aGF1c3RlZCB0aGUgaXRlcmF0b3IsIGFuZCBpZiB0aGVyZSBpcyBhIGNhY2hlCi0gICAgICAgIC8vIGl0IG11c3QgaGF2ZSBhbGwgbm9kZXMgaW4gaXQgYnkgbm93LCBzbyBsZXQgdGhlIGNhY2hlCi0gICAgICAgIC8vIGtub3cgdGhhdCBpdCBpcyBjb21wbGV0ZS4KLSAgICAgICAgbWFya0NhY2hlQ29tcGxldGUoKTsKLQotICAgICAgICBtX2xhc3QgPSBtX25leHQ7Ci0gICAgICAgIG1fbmV4dCsrOwotICAgIH0KLQotICAgIHJldHVybiBuZXh0OwotICB9Ci0KLSAgLyoqCi0gICAqIEBzZWUgRFRNSXRlcmF0b3IjcHJldmlvdXNOb2RlKCkKLSAgICovCi0gIHB1YmxpYyBpbnQgcHJldmlvdXNOb2RlKCkKLSAgewotICAgICAgICBpZihoYXNDYWNoZSgpKQotICAgICAgICB7Ci0gICAgICAgICAgICAgICAgaWYobV9uZXh0IDw9IDApCi0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gRFRNLk5VTEw7Ci0gICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIG1fbmV4dC0tOwotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGl0ZW0obV9uZXh0KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICB7Ci0gICAgICAgICAgICBpbnQgbiA9IG1faXRlci5wcmV2aW91c05vZGUoKTsKLSAgICAgICAgICAgIG1fbmV4dCA9IG1faXRlci5nZXRDdXJyZW50UG9zKCk7Ci0gICAgICAgICAgICByZXR1cm4gbV9uZXh0OwotICAgICAgICB9Ci0gIH0KLQotICAvKioKLSAgICogQHNlZSBEVE1JdGVyYXRvciNkZXRhY2goKQotICAgKi8KLSAgcHVibGljIHZvaWQgZGV0YWNoKCkKLSAgewotICAgICAgICBpZihudWxsICE9IG1faXRlcikKLSAgICAgICAgICAgICAgICBtX2l0ZXIuZGV0YWNoKCk7Ci0gICAgICAgIHN1cGVyLmRldGFjaCgpOwotICB9Ci0KLSAgLyoqCi0gICAqIENhbGxpbmcgdGhpcyB3aXRoIGEgdmFsdWUgb2YgZmFsc2Ugd2lsbCBjYXVzZSB0aGUgbm9kZXNldAotICAgKiB0byBiZSBjYWNoZWQuCi0gICAqIEBzZWUgRFRNSXRlcmF0b3IjYWxsb3dEZXRhY2hUb1JlbGVhc2UoYm9vbGVhbikKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFsbG93RGV0YWNoVG9SZWxlYXNlKGJvb2xlYW4gYWxsb3dSZWxlYXNlKQotICB7Ci0gICAgICAgIGlmKChmYWxzZSA9PSBhbGxvd1JlbGVhc2UpICYmICFoYXNDYWNoZSgpKQotICAgICAgICB7Ci0gICAgICAgICAgICAgICAgc2V0U2hvdWxkQ2FjaGVOb2Rlcyh0cnVlKTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmKG51bGwgIT0gbV9pdGVyKQotICAgICAgICAgICAgICAgIG1faXRlci5hbGxvd0RldGFjaFRvUmVsZWFzZShhbGxvd1JlbGVhc2UpOwotICAgICAgICBzdXBlci5hbGxvd0RldGFjaFRvUmVsZWFzZShhbGxvd1JlbGVhc2UpOwotICB9Ci0KLSAgLyoqCi0gICAqIEBzZWUgRFRNSXRlcmF0b3IjZ2V0Q3VycmVudE5vZGUoKQotICAgKi8KLSAgcHVibGljIGludCBnZXRDdXJyZW50Tm9kZSgpCi0gIHsKLSAgICAgICAgaWYoaGFzQ2FjaGUoKSkKLSAgICAgICAgewotICAgICAgICAgICAgICAgIGludCBjdXJyZW50SW5kZXggPSBtX25leHQtMTsKLSAgICAgICAgICAgICAgICBOb2RlVmVjdG9yIHZlYyA9IGdldFZlY3RvcigpOwotICAgICAgICAgICAgICAgIGlmKChjdXJyZW50SW5kZXggPj0gMCkgJiYgKGN1cnJlbnRJbmRleCA8IHZlYy5zaXplKCkpKQotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZlYy5lbGVtZW50QXQoY3VycmVudEluZGV4KTsKLSAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gRFRNLk5VTEw7Ci0gICAgICAgIH0KLQotICAgICAgICBpZihudWxsICE9IG1faXRlcikKLSAgICAgICAgewotICAgICAgICByZXR1cm4gbV9pdGVyLmdldEN1cnJlbnROb2RlKCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIHJldHVybiBEVE0uTlVMTDsKLSAgfQotCi0gIC8qKgotICAgKiBAc2VlIERUTUl0ZXJhdG9yI2lzRnJlc2goKQotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNGcmVzaCgpCi0gIHsKLSAgICByZXR1cm4gKDAgPT0gbV9uZXh0KTsKLSAgfQotCi0gIC8qKgotICAgKiBAc2VlIERUTUl0ZXJhdG9yI3NldFNob3VsZENhY2hlTm9kZXMoYm9vbGVhbikKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFNob3VsZENhY2hlTm9kZXMoYm9vbGVhbiBiKQotICB7Ci0gICAgaWYgKGIpCi0gICAgewotICAgICAgaWYoIWhhc0NhY2hlKCkpCi0gICAgICB7Ci0gICAgICAgIFNldFZlY3RvcihuZXcgTm9kZVZlY3RvcigpKTsKLSAgICAgIH0KLS8vICAgICAgICBlbHNlCi0vLyAgICAgICAgICBnZXRWZWN0b3IoKS5SZW1vdmVBbGxOb0NsZWFyKCk7ICAvLyBJcyB0aGlzIGdvb2Q/Ci0gICAgfQotICAgIGVsc2UKLSAgICAgIFNldFZlY3RvcihudWxsKTsKLSAgfQotCi0gIC8qKgotICAgKiBAc2VlIERUTUl0ZXJhdG9yI2lzTXV0YWJsZSgpCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBpc011dGFibGUoKQotICB7Ci0gICAgcmV0dXJuIGhhc0NhY2hlKCk7IC8vIHRob3VnaCBtYXkgYmUgc3VycHJpc2luZyBpZiBpdCBhbHNvIGhhcyBhbiBpdGVyYXRvciEKLSAgfQotCi0gIC8qKgotICAgKiBAc2VlIERUTUl0ZXJhdG9yI2dldEN1cnJlbnRQb3MoKQotICAgKi8KLSAgcHVibGljIGludCBnZXRDdXJyZW50UG9zKCkKLSAgewotICAgIHJldHVybiBtX25leHQ7Ci0gIH0KLQotICAvKioKLSAgICogQHNlZSBEVE1JdGVyYXRvciNydW5UbyhpbnQpCi0gICAqLwotICBwdWJsaWMgdm9pZCBydW5UbyhpbnQgaW5kZXgpCi0gIHsKLSAgICBpbnQgbjsKLQotICAgIGlmICgtMSA9PSBpbmRleCkKLSAgICB7Ci0gICAgICBpbnQgcG9zID0gbV9uZXh0OwotICAgICAgd2hpbGUgKERUTS5OVUxMICE9IChuID0gbmV4dE5vZGUoKSkpOwotICAgICAgbV9uZXh0ID0gcG9zOwotICAgIH0KLSAgICBlbHNlIGlmKG1fbmV4dCA9PSBpbmRleCkKLSAgICB7Ci0gICAgICByZXR1cm47Ci0gICAgfQotICAgIGVsc2UgaWYoaGFzQ2FjaGUoKSAmJiBpbmRleCA8IGdldFZlY3RvcigpLnNpemUoKSkKLSAgICB7Ci0gICAgICBtX25leHQgPSBpbmRleDsKLSAgICB9Ci0gICAgZWxzZSBpZigobnVsbCA9PSBnZXRWZWN0b3IoKSkgJiYgKGluZGV4IDwgbV9uZXh0KSkKLSAgICB7Ci0gICAgICB3aGlsZSAoKG1fbmV4dCA+PSBpbmRleCkgJiYgRFRNLk5VTEwgIT0gKG4gPSBwcmV2aW91c05vZGUoKSkpOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgd2hpbGUgKChtX25leHQgPCBpbmRleCkgJiYgRFRNLk5VTEwgIT0gKG4gPSBuZXh0Tm9kZSgpKSk7Ci0gICAgfQotCi0gIH0KLQotICAvKioKLSAgICogQHNlZSBEVE1JdGVyYXRvciNzZXRDdXJyZW50UG9zKGludCkKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldEN1cnJlbnRQb3MoaW50IGkpCi0gIHsKLSAgICAgICAgcnVuVG8oaSk7Ci0gIH0KLQotICAvKioKLSAgICogQHNlZSBEVE1JdGVyYXRvciNpdGVtKGludCkKLSAgICovCi0gIHB1YmxpYyBpbnQgaXRlbShpbnQgaW5kZXgpCi0gIHsKLSAgICAgICAgc2V0Q3VycmVudFBvcyhpbmRleCk7Ci0gICAgICAgIGludCBuID0gbmV4dE5vZGUoKTsKLSAgICAgICAgbV9uZXh0ID0gaW5kZXg7Ci0gICAgICAgIHJldHVybiBuOwotICB9Ci0KLSAgLyoqCi0gICAqIEBzZWUgRFRNSXRlcmF0b3Ijc2V0SXRlbShpbnQsIGludCkKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldEl0ZW0oaW50IG5vZGUsIGludCBpbmRleCkKLSAgewotICAgICAgICBOb2RlVmVjdG9yIHZlYyA9IGdldFZlY3RvcigpOwotICAgICAgICBpZihudWxsICE9IHZlYykKLSAgICAgICAgewotICAgICAgICBpbnQgb2xkTm9kZSA9IHZlYy5lbGVtZW50QXQoaW5kZXgpOwotICAgICAgICBpZiAob2xkTm9kZSAhPSBub2RlICYmIG1fY2FjaGUudXNlQ291bnQoKSA+IDEpIHsKLSAgICAgICAgICAgIC8qIElmIHdlIGFyZSBnb2luZyB0byBzZXQgdGhlIG5vZGUgYXQgdGhlIGdpdmVuIGluZGV4Ci0gICAgICAgICAgICAgKiB0byBhIGRpZmZlcmVudCB2YWx1ZSwgYW5kIHRoZSBjYWNoZSBpcyBzaGFyZWQKLSAgICAgICAgICAgICAqIChoYXMgYSB1c2UgY291bnQgZ3JlYXRlciB0aGFuIDEpCi0gICAgICAgICAgICAgKiB0aGVuIG1ha2UgYSBjb3B5IG9mIHRoZSBjYWNoZSBhbmQgdXNlIGl0Ci0gICAgICAgICAgICAgKiBzbyB3ZSBkb24ndCBvdmVyd3JpdGUgdGhlIHZhbHVlIGZvciBvdGhlcgotICAgICAgICAgICAgICogdXNlcnMgb2YgdGhlIGNhY2hlLgotICAgICAgICAgICAgICovCi0gICAgICAgICAgICBJdGVyYXRvckNhY2hlIG5ld0NhY2hlID0gbmV3IEl0ZXJhdG9yQ2FjaGUoKTsKLSAgICAgICAgICAgIGZpbmFsIE5vZGVWZWN0b3IgbnY7Ci0gICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgIG52ID0gKE5vZGVWZWN0b3IpIHZlYy5jbG9uZSgpOwotICAgICAgICAgICAgfSBjYXRjaCAoQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgIC8vIFRoaXMgc2hvdWxkIG5ldmVyIGhhcHBlbgotICAgICAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgICAgICAgICAgUnVudGltZUV4Y2VwdGlvbiBydGUgPSBuZXcgUnVudGltZUV4Y2VwdGlvbihlLmdldE1lc3NhZ2UoKSk7Ci0gICAgICAgICAgICAgICAgdGhyb3cgcnRlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgbmV3Q2FjaGUuc2V0VmVjdG9yKG52KTsKLSAgICAgICAgICAgIG5ld0NhY2hlLnNldENhY2hlQ29tcGxldGUodHJ1ZSk7Ci0gICAgICAgICAgICBtX2NhY2hlID0gbmV3Q2FjaGU7Ci0gICAgICAgICAgICB2ZWMgPSBudjsKLQotICAgICAgICAgICAgLy8gS2VlcCBvdXIgc3VwZXJjbGFzcyBpbmZvcm1lZCBvZiB0aGUgY3VycmVudCBOb2RlVmVjdG9yCi0gICAgICAgICAgICBzdXBlci5zZXRPYmplY3QobnYpOwotCi0gICAgICAgICAgICAvKiBXaGVuIHdlIGdldCB0byBoZXJlIHRoZSBuZXcgY2FjaGUgaGFzCi0gICAgICAgICAgICAgKiBhIHVzZSBjb3VudCBvZiAxIGFuZCB3aGVuIHNldHRpbmcgYQotICAgICAgICAgICAgICogYnVuY2ggb2YgdmFsdWVzIG9uIHRoZSBzYW1lIE5vZGVTZXF1ZW5jZSwKLSAgICAgICAgICAgICAqIHN1Y2ggYXMgd2hlbiBzb3J0aW5nLCB3ZSB3aWxsIGtlZXAgc2V0dGluZwotICAgICAgICAgICAgICogdmFsdWVzIGluIHRoYXQgc2FtZSBjb3B5IHdoaWNoIGhhcyBhIHVzZSBjb3VudCBvZiAxLgotICAgICAgICAgICAgICovCi0gICAgICAgIH0KLSAgICAgICAgICAgICAgICB2ZWMuc2V0RWxlbWVudEF0KG5vZGUsIGluZGV4KTsKLSAgICAgICAgICAgICAgICBtX2xhc3QgPSB2ZWMuc2l6ZSgpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICBtX2l0ZXIuc2V0SXRlbShub2RlLCBpbmRleCk7Ci0gIH0KLQotICAvKioKLSAgICogQHNlZSBEVE1JdGVyYXRvciNnZXRMZW5ndGgoKQotICAgKi8KLSAgcHVibGljIGludCBnZXRMZW5ndGgoKQotICB7Ci0gICAgSXRlcmF0b3JDYWNoZSBjYWNoZSA9IGdldENhY2hlKCk7Ci0KLSAgICAgICAgaWYoY2FjaGUgIT0gbnVsbCkKLSAgICAgICAgewotICAgICAgICAvLyBOb2RlcyBmcm9tIHRoZSBpdGVyYXRvciBhcmUgY2FjaGVkCi0gICAgICAgIGlmIChjYWNoZS5pc0NvbXBsZXRlKCkpIHsKLSAgICAgICAgICAgIC8vIEFsbCBvZiB0aGUgbm9kZXMgZnJvbSB0aGUgaXRlcmF0b3IgYXJlIGNhY2hlZAotICAgICAgICAgICAgLy8gc28ganVzdCByZXR1cm4gdGhlIG51bWJlciBvZiBub2RlcyBpbiB0aGUgY2FjaGUKLSAgICAgICAgICAgIE5vZGVWZWN0b3IgbnYgPSBjYWNoZS5nZXRWZWN0b3IoKTsKLSAgICAgICAgICAgIHJldHVybiBudi5zaXplKCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBJZiB0aGlzIE5vZGVTZXF1ZW5jZSB3cmFwcyBhIG11dGFibGUgbm9kZXNldCwgdGhlbgotICAgICAgICAvLyBtX2xhc3Qgd2lsbCBub3QgcmVmbGVjdCB0aGUgc2l6ZSBvZiB0aGUgbm9kZXNldCBpZgotICAgICAgICAvLyBpdCBoYXMgYmVlbiBtdXRhdGVkLi4uCi0gICAgICAgIGlmIChtX2l0ZXIgaW5zdGFuY2VvZiBOb2RlU2V0RFRNKQotICAgICAgICB7Ci0gICAgICAgICAgICByZXR1cm4gbV9pdGVyLmdldExlbmd0aCgpOwotICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBpZigtMSA9PSBtX2xhc3QpCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgaW50IHBvcyA9IG1fbmV4dDsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJ1blRvKC0xKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIG1fbmV4dCA9IHBvczsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gbV9sYXN0OwotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotICAgICAgICAgICAgICAgIHJldHVybiAoLTEgPT0gbV9sYXN0KSA/IChtX2xhc3QgPSBtX2l0ZXIuZ2V0TGVuZ3RoKCkpIDogbV9sYXN0OwotICAgICAgICB9Ci0gIH0KLQotICAvKioKLSAgICogTm90ZTogTm90IGEgZGVlcCBjbG9uZS4KLSAgICogQHNlZSBEVE1JdGVyYXRvciNjbG9uZVdpdGhSZXNldCgpCi0gICAqLwotICBwdWJsaWMgRFRNSXRlcmF0b3IgY2xvbmVXaXRoUmVzZXQoKSB0aHJvd3MgQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24KLSAgewotICAgICAgICBOb2RlU2VxdWVuY2Ugc2VxID0gKE5vZGVTZXF1ZW5jZSlzdXBlci5jbG9uZSgpOwotICAgIHNlcS5tX25leHQgPSAwOwotICAgIGlmIChtX2NhY2hlICE9IG51bGwpIHsKLSAgICAgICAgLy8gSW4gbWFraW5nIHRoaXMgY2xvbmUgb2YgYW4gaXRlcmF0b3Igd2UgYXJlIG1ha2luZwotICAgICAgICAvLyBhbm90aGVyIE5vZGVTZXF1ZW5jZSBvYmplY3QgaXQgaGFzIGEgcmVmZXJlbmNlCi0gICAgICAgIC8vIHRvIHRoZSBzYW1lIEl0ZXJhdG9yQ2FjaGUgb2JqZWN0IGFzIHRoZSBvcmlnaW5hbAotICAgICAgICAvLyBzbyB3ZSBuZWVkIHRvIHJlbWVtYmVyIHRoYXQgbW9yZSB0aGFuIG9uZQotICAgICAgICAvLyBOb2RlU2VxdWVuY2Ugb2JqZWN0IHNoYXJlcyB0aGUgY2FjaGUuCi0gICAgICAgIG1fY2FjaGUuaW5jcmVhc2VVc2VDb3VudCgpOwotICAgIH0KLQotICAgIHJldHVybiBzZXE7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IGEgY2xvbmUgb2YgdGhpcyBpdGVyYXRvciwgYnV0IGRvbid0IHJlc2V0IHRoZSBpdGVyYXRpb24gaW4gdGhlCi0gICAqIHByb2Nlc3MsIHNvIHRoYXQgaXQgbWF5IGJlIHVzZWQgZnJvbSB0aGUgY3VycmVudCBwb3NpdGlvbi4KLSAgICogTm90ZTogTm90IGEgZGVlcCBjbG9uZS4KLSAgICoKLSAgICogQHJldHVybiBBIGNsb25lIG9mIHRoaXMgb2JqZWN0LgotICAgKgotICAgKiBAdGhyb3dzIENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgT2JqZWN0IGNsb25lKCkgdGhyb3dzIENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uCi0gIHsKLSAgICAgICAgICBOb2RlU2VxdWVuY2UgY2xvbmUgPSAoTm9kZVNlcXVlbmNlKSBzdXBlci5jbG9uZSgpOwotICAgICAgICAgIGlmIChudWxsICE9IG1faXRlcikgY2xvbmUubV9pdGVyID0gKERUTUl0ZXJhdG9yKSBtX2l0ZXIuY2xvbmUoKTsKLSAgICAgICAgICBpZiAobV9jYWNoZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgIC8vIEluIG1ha2luZyB0aGlzIGNsb25lIG9mIGFuIGl0ZXJhdG9yIHdlIGFyZSBtYWtpbmcKLSAgICAgICAgICAgICAgLy8gYW5vdGhlciBOb2RlU2VxdWVuY2Ugb2JqZWN0IGl0IGhhcyBhIHJlZmVyZW5jZQotICAgICAgICAgICAgICAvLyB0byB0aGUgc2FtZSBJdGVyYXRvckNhY2hlIG9iamVjdCBhcyB0aGUgb3JpZ2luYWwKLSAgICAgICAgICAgICAgLy8gc28gd2UgbmVlZCB0byByZW1lbWJlciB0aGF0IG1vcmUgdGhhbiBvbmUKLSAgICAgICAgICAgICAgLy8gTm9kZVNlcXVlbmNlIG9iamVjdCBzaGFyZXMgdGhlIGNhY2hlLgotICAgICAgICAgICAgICBtX2NhY2hlLmluY3JlYXNlVXNlQ291bnQoKTsKLSAgICAgICAgICB9Ci0KLSAgICAgICAgICByZXR1cm4gY2xvbmU7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBAc2VlIERUTUl0ZXJhdG9yI2lzRG9jT3JkZXJlZCgpCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBpc0RvY09yZGVyZWQoKQotICB7Ci0gICAgICAgIGlmKG51bGwgIT0gbV9pdGVyKQotICAgICAgICAgICAgICAgIHJldHVybiBtX2l0ZXIuaXNEb2NPcmRlcmVkKCk7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgcmV0dXJuIHRydWU7IC8vIGNhbid0IGJlIHN1cmU/Ci0gIH0KLQotICAvKioKLSAgICogQHNlZSBEVE1JdGVyYXRvciNnZXRBeGlzKCkKLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0QXhpcygpCi0gIHsKLSAgICAgICAgaWYobnVsbCAhPSBtX2l0ZXIpCi0gICAgICAgIHJldHVybiBtX2l0ZXIuZ2V0QXhpcygpOwotICAgIGVsc2UKLSAgICB7Ci0gICAgICAgIGFzc2VydGlvbihmYWxzZSwgIkNhbiBub3QgZ2V0QXhpcyBmcm9tIGEgbm9uLWl0ZXJhdGVkIG5vZGUgc2VxdWVuY2UhIik7Ci0gICAgICAgIHJldHVybiAwOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBAc2VlIFBhdGhDb21wb25lbnQjZ2V0QW5hbHlzaXNCaXRzKCkKLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0QW5hbHlzaXNCaXRzKCkKLSAgewotICAgICAgICBpZigobnVsbCAhPSBtX2l0ZXIpICYmIChtX2l0ZXIgaW5zdGFuY2VvZiBQYXRoQ29tcG9uZW50KSkKLSAgICAgICAgcmV0dXJuICgoUGF0aENvbXBvbmVudCltX2l0ZXIpLmdldEFuYWx5c2lzQml0cygpOwotICAgIGVsc2UKLSAgICAgICAgcmV0dXJuIDA7Ci0gIH0KLQotICAvKioKLSAgICogQHNlZSBvcmcuYXBhY2hlLnhwYXRoLkV4cHJlc3Npb24jZml4dXBWYXJpYWJsZXMoVmVjdG9yLCBpbnQpCi0gICAqLwotICBwdWJsaWMgdm9pZCBmaXh1cFZhcmlhYmxlcyhWZWN0b3IgdmFycywgaW50IGdsb2JhbHNTaXplKQotICB7Ci0gICAgICAgIHN1cGVyLmZpeHVwVmFyaWFibGVzKHZhcnMsIGdsb2JhbHNTaXplKTsKLSAgfQotCi0gIC8qKgotICAgKiBBZGQgdGhlIG5vZGUgaW50byBhIHZlY3RvciBvZiBub2RlcyB3aGVyZSBpdCBzaG91bGQgb2NjdXIgaW4KLSAgICogZG9jdW1lbnQgb3JkZXIuCi0gICAqIEBwYXJhbSBub2RlIFRoZSBub2RlIHRvIGJlIGFkZGVkLgotICAgKiBAcmV0dXJuIGluc2VydEluZGV4LgotICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gdGhyb3duIGlmIHRoaXMgTm9kZVNldERUTSBpcyBub3Qgb2YKLSAgICogYSBtdXRhYmxlIHR5cGUuCi0gICAqLwotICAgcHJvdGVjdGVkIGludCBhZGROb2RlSW5Eb2NPcmRlcihpbnQgbm9kZSkKLSAgIHsKLSAgICAgIGFzc2VydGlvbihoYXNDYWNoZSgpLCAiYWRkTm9kZUluRG9jT3JkZXIgbXVzdCBiZSBkb25lIG9uIGEgbXV0YWJsZSBzZXF1ZW5jZSEiKTsKLQotICAgICAgaW50IGluc2VydEluZGV4ID0gLTE7Ci0KLSAgICAgIE5vZGVWZWN0b3IgdmVjID0gZ2V0VmVjdG9yKCk7Ci0KLSAgICAgIC8vIFRoaXMgbmVlZHMgdG8gZG8gYSBiaW5hcnkgc2VhcmNoLCBidXQgYSBiaW5hcnkgc2VhcmNoCi0gICAgICAvLyBpcyBzb21ld2hhdCB0b3VnaCBiZWNhdXNlIHRoZSBzZXF1ZW5jZSB0ZXN0IGludm9sdmVzCi0gICAgICAvLyB0d28gbm9kZXMuCi0gICAgICBpbnQgc2l6ZSA9IHZlYy5zaXplKCksIGk7Ci0KLSAgICAgIGZvciAoaSA9IHNpemUgLSAxOyBpID49IDA7IGktLSkKLSAgICAgIHsKLSAgICAgICAgaW50IGNoaWxkID0gdmVjLmVsZW1lbnRBdChpKTsKLQotICAgICAgICBpZiAoY2hpbGQgPT0gbm9kZSkKLSAgICAgICAgewotICAgICAgICAgIGkgPSAtMjsgLy8gRHVwbGljYXRlLCBzdXBwcmVzcyBpbnNlcnQKLQotICAgICAgICAgIGJyZWFrOwotICAgICAgICB9Ci0KLSAgICAgICAgRFRNIGR0bSA9IG1fZHRtTWdyLmdldERUTShub2RlKTsKLSAgICAgICAgaWYgKCFkdG0uaXNOb2RlQWZ0ZXIobm9kZSwgY2hpbGQpKQotICAgICAgICB7Ci0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIH0KLSAgICAgIH0KLQotICAgICAgaWYgKGkgIT0gLTIpCi0gICAgICB7Ci0gICAgICAgIGluc2VydEluZGV4ID0gaSArIDE7Ci0KLSAgICAgICAgdmVjLmluc2VydEVsZW1lbnRBdChub2RlLCBpbnNlcnRJbmRleCk7Ci0gICAgICB9Ci0KLSAgICAgIC8vIGNoZWNrRHVwcygpOwotICAgICAgcmV0dXJuIGluc2VydEluZGV4OwotICAgIH0gLy8gZW5kIGFkZE5vZGVJbkRvY09yZGVyKFZlY3RvciB2LCBPYmplY3Qgb2JqKQotCi0gICAvKioKLSAgICAqIEl0IHVzZWQgdG8gYmUgdGhhdCBtYW55IGxvY2F0aW9ucyBpbiB0aGUgY29kZSBzaW1wbHkKLSAgICAqIGRpZCBhbiBhc3NpZ25tZW50IHRvIHRoaXMubV9vYmogZGlyZWN0bHksIHJhdGhlciB0aGFuCi0gICAgKiBjYWxsaW5nIHRoZSBzZXRPYmplY3QoT2JqZWN0KSBtZXRob2QuIFRoZSBwcm9ibGVtIGlzCi0gICAgKiB0aGF0IG91ciBzdXBlci1jbGFzcyB3b3VsZCBiZSB1cGRhdGVkIG9uIHdoYXQgdGhlCi0gICAgKiBjYWNoZSBhc3NvY2lhdGVkIHdpdGggdGhpcyBOb2RlU2VxdWVuY2UsIGJ1dAotICAgICogd2Ugd291bGRuJ3Qga25vdyBvdXJzZWx2ZXMuCi0gICAgKiA8cD4KLSAgICAqIEFsbCBzZXR0aW5nIG9mIG1fb2JqIGlzIGRvbmUgdGhyb3VnaCBzZXRPYmplY3QoKSBub3csCi0gICAgKiBhbmQgdGhpcyBtZXRob2Qgb3Zlci1yaWRlcyB0aGUgc3VwZXItY2xhc3MgbWV0aG9kLgotICAgICogU28gbm93IHdlIGFyZSBpbiB0aGUgbG9vcCBoYXZlIGFuIG9wcG9ydHVuaXR5Ci0gICAgKiB0byB1cGRhdGUgc29tZSBjYWNoaW5nIGluZm9ybWF0aW9uLgotICAgICoKLSAgICAqLwotICAgcHJvdGVjdGVkIHZvaWQgc2V0T2JqZWN0KE9iamVjdCBvYmopIHsKLSAgICAgICBpZiAob2JqIGluc3RhbmNlb2YgTm9kZVZlY3RvcikgewotICAgICAgICAgICAvLyBLZWVwIG91ciBzdXBlcmNsYXNzIGluZm9ybWVkIG9mIHRoZSBjdXJyZW50IE5vZGVWZWN0b3IKLSAgICAgICAgICAgLy8gLi4uIGlmIHdlIGRvbid0IHRoZSBzbW9rZXRlc3QgZmFpbHMgKGRvbid0IGtub3cgd2h5KS4KLSAgICAgICAgICAgc3VwZXIuc2V0T2JqZWN0KG9iaik7Ci0KLSAgICAgICAgICAgLy8gQSBjb3B5IG9mIHRoZSBjb2RlIG9mIHdoYXQgU2V0VmVjdG9yKCkgd291bGQgZG8uCi0gICAgICAgICAgIE5vZGVWZWN0b3IgdiA9IChOb2RlVmVjdG9yKW9iajsKLSAgICAgICAgICAgaWYgKG1fY2FjaGUgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgbV9jYWNoZS5zZXRWZWN0b3Iodik7Ci0gICAgICAgICAgIH0gZWxzZSBpZiAodiE9bnVsbCkgewotICAgICAgICAgICAgICAgbV9jYWNoZSA9IG5ldyBJdGVyYXRvckNhY2hlKCk7Ci0gICAgICAgICAgICAgICBtX2NhY2hlLnNldFZlY3Rvcih2KTsKLSAgICAgICAgICAgfQotICAgICAgIH0gZWxzZSBpZiAob2JqIGluc3RhbmNlb2YgSXRlcmF0b3JDYWNoZSkgewotICAgICAgICAgICBJdGVyYXRvckNhY2hlIGNhY2hlID0gKEl0ZXJhdG9yQ2FjaGUpIG9iajsKLSAgICAgICAgICAgbV9jYWNoZSA9IGNhY2hlOwotICAgICAgICAgICBtX2NhY2hlLmluY3JlYXNlVXNlQ291bnQoKTsKLQotICAgICAgICAgICAvLyBLZWVwIG91ciBzdXBlcmNsYXNzIGluZm9ybWVkIG9mIHRoZSBjdXJyZW50IE5vZGVWZWN0b3IKLSAgICAgICAgICAgc3VwZXIuc2V0T2JqZWN0KGNhY2hlLmdldFZlY3RvcigpKTsKLSAgICAgICB9IGVsc2UgewotICAgICAgICAgICBzdXBlci5zZXRPYmplY3Qob2JqKTsKLSAgICAgICB9Ci0KLSAgIH0KLQotICAgLyoqCi0gICAgKiBFYWNoIE5vZGVTZXF1ZW5jZSBvYmplY3QgaGFzIGFuIGl0ZXJhdG9yIHdoaWNoIGlzICJ3YWxrZWQiLgotICAgICogQXMgYW4gaXRlcmF0b3IgaXMgd2Fsa2VkIG9uZSBvYnRhaW5zIG5vZGVzIGZyb20gaXQuCi0gICAgKiBBcyB0aG9zZSBub2RlcyBhcmUgb2J0YWluZWQgdGhleSBtYXkgYmUgY2FjaGVkLCBtYWtpbmcKLSAgICAqIHRoZSBuZXh0IHdhbGtpbmcgb2YgYSBjb3B5IG9yIGNsb25lIG9mIHRoZSBpdGVyYXRvciBmYXN0ZXIuCi0gICAgKiBUaGlzIGZpZWxkIChtX2NhY2hlKSBpcyBhIHJlZmVyZW5jZSB0byBzdWNoIGEgY2FjaGUsCi0gICAgKiB3aGljaCBpcyBwb3B1bGF0ZWQgYXMgdGhlIGl0ZXJhdG9yIGlzIHdhbGtlZC4KLSAgICAqIDxwPgotICAgICogTm90ZSB0aGF0IG11bHRpcGxlIE5vZGVTZXF1ZW5jZSBvYmplY3RzIG1heSBob2xkIGEKLSAgICAqIHJlZmVyZW5jZSB0byB0aGUgc2FtZSBjYWNoZSwgYW5kIGFsc28KLSAgICAqIChhbmQgdGhpcyBpcyBpbXBvcnRhbnQpIHRoZSBzYW1lIGl0ZXJhdG9yLgotICAgICogVGhlIGl0ZXJhdG9yIGFuZCBpdHMgY2FjaGUgbWF5IGJlIHNoYXJlZCBhbW9uZwotICAgICogbWFueSBOb2RlU2VxdWVuY2Ugb2JqZWN0cy4KLSAgICAqIDxwPgotICAgICogSWYgb25lIG9mIHRoZSBOb2RlU2VxdWVuY2Ugb2JqZWN0cyB3YWxrcyBhaGVhZAotICAgICogb2YgdGhlIG90aGVycyBpdCBmaWxscyBpbiB0aGUgY2FjaGUuCi0gICAgKiBBcyB0aGUgb3RoZXJzIE5vZGVTZXF1ZW5jZSBvYmplY3RzIGNhdGNoIHVwIHRoZXkKLSAgICAqIGdldCB0aGVpciB2YWx1ZXMgZnJvbQotICAgICogdGhlIGNhY2hlIHJhdGhlciB0aGFuIHRoZSBpdGVyYXRvciBpdHNlbGYsIHNvCi0gICAgKiB0aGUgaXRlcmF0b3IgaXMgb25seSBldmVyIHdhbGtlZCBvbmNlIGFuZCBldmVyeW9uZQotICAgICogYmVuZWZpdHMgZnJvbSB0aGUgY2FjaGUuCi0gICAgKiA8cD4KLSAgICAqIEF0IHNvbWUgcG9pbnQgdGhlIGNhY2hlIG1heSBiZQotICAgICogY29tcGxldGUgZHVlIHRvIHdhbGtpbmcgdG8gdGhlIGVuZCBvZiBvbmUgb2YKLSAgICAqIHRoZSBjb3BpZXMgb2YgdGhlIGl0ZXJhdG9yLCBhbmQgdGhlIGNhY2hlIGlzCi0gICAgKiB0aGVuIG1hcmtlZCBhcyAiY29tcGxldGUiLgotICAgICogYW5kIHRoZSBjYWNoZSB3aWxsIGhhdmUgbm8gbW9yZSBub2RlcyBhZGRlZCB0byBpdC4KLSAgICAqIDxwPgotICAgICogSXRzIHVzZS1jb3VudCBpcyB0aGUgbnVtYmVyIG9mIE5vZGVTZXF1ZW5jZSBvYmplY3RzIHRoYXQgdXNlIGl0LgotICAgICovCi0gICBwcml2YXRlIGZpbmFsIHN0YXRpYyBjbGFzcyBJdGVyYXRvckNhY2hlIHsKLSAgICAgICAvKioKLSAgICAgICAgKiBBIGxpc3Qgb2Ygbm9kZXMgYWxyZWFkeSBvYnRhaW5lZCBmcm9tIHRoZSBpdGVyYXRvci4KLSAgICAgICAgKiBBcyB0aGUgaXRlcmF0b3IgaXMgd2Fsa2VkIHRoZSBub2RlcyBvYnRhaW5lZCBmcm9tCi0gICAgICAgICogaXQgYXJlIGFwcGVuZGVkIHRvIHRoaXMgbGlzdC4KLSAgICAgICAgKiA8cD4KLSAgICAgICAgKiBCb3RoIGFuIGl0ZXJhdG9yIGFuZCBpdHMgY29ycmVzcG9uZGluZyBjYWNoZSBjYW4KLSAgICAgICAgKiBiZSBzaGFyZWQgYnkgbXVsdGlwbGUgTm9kZVNlcXVlbmNlIG9iamVjdHMuCi0gICAgICAgICogPHA+Ci0gICAgICAgICogRm9yIGV4YW1wbGUsIGNvbnNpZGVyIHRocmVlIE5vZGVTZXF1ZW5jZSBvYmplY3RzCi0gICAgICAgICogbnMxLCBuczIgYW5kIG5zMyBkb2luZyBzdWNoIHNoYXJpbmcsIGFuZCB0aGUKLSAgICAgICAgKiBub2RlcyB0byBiZSBvYnRhaW5kIGZyb20gdGhlIGl0ZXJhdG9yIGJlaW5nCi0gICAgICAgICogdGhlIHNlcXVlbmNlIHsgMzMsIDExLCA0NCwgMjIsIDU1IH0uCi0gICAgICAgICogPHA+Ci0gICAgICAgICogSWYgbnMzLm5leHROb2RlKCkgaXMgY2FsbGVkIDMgdGltZXMgdGhlIHRoZQotICAgICAgICAqIHVuZGVybHlpbmcgaXRlcmF0b3Igd2lsbCBoYXZlIHdhbGtlZCB0aHJvdWdoCi0gICAgICAgICogMzMsIDExLCA1NSBhbmQgdGhlc2UgdGhyZWUgbm9kZXMgd2lsbCBoYXZlIGJlZW4gcHV0Ci0gICAgICAgICogaW4gdGhlIGNhY2hlLgotICAgICAgICAqIDxwPgotICAgICAgICAqIElmIG5zMi5uZXh0Tm9kZSgpIGlzIGNhbGxlZCAyIHRpbWVzIGl0IHdpbGwgcmV0dXJuCi0gICAgICAgICogMzMgYW5kIDExIGZyb20gdGhlIGNhY2hlLCBsZWF2aW5nIHRoZSBpdGVyYXRvciBhbG9uZS4KLSAgICAgICAgKiA8cD4KLSAgICAgICAgKiBJZiBuczEubmV4dE5vZGUoKSBpcyBjYWxsZWQgNiB0aW1lcyBpdCB3aWxsIHJldHVybgotICAgICAgICAqIDMzIGFuZCAxMSBmcm9tIHRoZSBjYWNoZSwgdGhlbiBnZXQgNDQsIDIyLCA1NSBmcm9tCi0gICAgICAgICogdGhlIGl0ZXJhdG9yLCBhbmQgYXBwZW5kaW5nIDQ0LCAyMiwgNTUgdG8gdGhlIGNhY2hlLgotICAgICAgICAqIE9uIHRoZSBzaXh0aCBjYWxsIGl0IGlzIGZvdW5kIHRoYXQgdGhlIGl0ZXJhdG9yIGlzCi0gICAgICAgICogZXhoYXVzdGVkIGFuZCB0aGUgY2FjaGUgaXMgbWFya2VkIGNvbXBsZXRlLgotICAgICAgICAqIDxwPgotICAgICAgICAqIFNob3VsZCBuczIgb3IgbnMzIGhhdmUgbmV4dE5vZGUoKSBjYWxsZWQgdGhleSB3aWxsCi0gICAgICAgICoga25vdyB0aGF0IHRoZSBjYWNoZSBpcyBjb21wbGV0ZSwgYW5kIHRoZXkgd2lsbAotICAgICAgICAqIG9idGFpbiBhbGwgc3Vic2VxdWVudCBub2RlcyBmcm9tIHRoZSBjYWNoZS4KLSAgICAgICAgKiA8cD4KLSAgICAgICAgKiBOb3RlIHRoYXQgdGhlIHVuZGVybHlpbmcgaXRlcmF0b3IsIHRob3VnaCBzaGFyZWQKLSAgICAgICAgKiBpcyBvbmx5IGV2ZXIgd2Fsa2VkIG9uY2UuCi0gICAgICAgICovCi0gICAgICAgIHByaXZhdGUgTm9kZVZlY3RvciBtX3ZlYzI7Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIHRydWUgaWYgdGhlIGFzc29jaWF0ZWQgaXRlcmF0b3IgaXMgZXhoYXVzdGVkIGFuZAotICAgICAgICAgKiBhbGwgbm9kZXMgb2J0YWluZWQgZnJvbSBpdCBhcmUgaW4gdGhlIGNhY2hlLgotICAgICAgICAgKi8KLSAgICAgICAgcHJpdmF0ZSBib29sZWFuIG1faXNDb21wbGV0ZTI7Ci0KLSAgICAgICAgcHJpdmF0ZSBpbnQgbV91c2VDb3VudDI7Ci0KLSAgICAgICAgSXRlcmF0b3JDYWNoZSgpIHsKLSAgICAgICAgICAgIG1fdmVjMiA9IG51bGw7Ci0gICAgICAgICAgICBtX2lzQ29tcGxldGUyID0gZmFsc2U7Ci0gICAgICAgICAgICBtX3VzZUNvdW50MiA9IDE7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogUmV0dXJucyBjb3VudCBvZiBob3cgbWFueSBOb2RlU2VxdWVuY2Ugb2JqZWN0cyBzaGFyZSB0aGlzCi0gICAgICAgICAqIEl0ZXJhdG9yQ2FjaGUgb2JqZWN0LgotICAgICAgICAgKi8KLSAgICAgICAgcHJpdmF0ZSBpbnQgdXNlQ291bnQoKSB7Ci0gICAgICAgICAgICByZXR1cm4gbV91c2VDb3VudDI7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIHdoZW4geWV0IGFub3RoZXIKLSAgICAgICAgICogTm9kZVNlcXVlbmNlIG9iamVjdCB1c2VzLCBvciBzaGFyZXMKLSAgICAgICAgICogdGhpcyBzYW1lIGNhY2hlLgotICAgICAgICAgKgotICAgICAgICAgKi8KLSAgICAgICAgcHJpdmF0ZSB2b2lkIGluY3JlYXNlVXNlQ291bnQoKSB7Ci0gICAgICAgICAgICBpZiAobV92ZWMyICE9IG51bGwpCi0gICAgICAgICAgICAgICAgbV91c2VDb3VudDIrKzsKLQotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFNldHMgdGhlIE5vZGVWZWN0b3IgdGhhdCBob2xkcyB0aGUKLSAgICAgICAgICogZ3Jvd2luZyBsaXN0IG9mIG5vZGVzIGFzIHRoZXkgYXJlIGFwcGVuZGVkCi0gICAgICAgICAqIHRvIHRoZSBjYWNoZWQgbGlzdC4KLSAgICAgICAgICovCi0gICAgICAgIHByaXZhdGUgdm9pZCBzZXRWZWN0b3IoTm9kZVZlY3RvciBudikgewotICAgICAgICAgICAgbV92ZWMyID0gbnY7Ci0gICAgICAgICAgICBtX3VzZUNvdW50MiA9IDE7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogR2V0IHRoZSBjYWNoZWQgbGlzdCBvZiBub2RlcyBvYnRhaW5lZCBmcm9tCi0gICAgICAgICAqIHRoZSBpdGVyYXRvciBzbyBmYXIuCi0gICAgICAgICAqLwotICAgICAgICBwcml2YXRlIE5vZGVWZWN0b3IgZ2V0VmVjdG9yKCkgewotICAgICAgICAgICAgcmV0dXJuIG1fdmVjMjsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBDYWxsIHRoaXMgbWV0aG9kIHdpdGggJ3RydWUnIGlmIHRoZQotICAgICAgICAgKiBpdGVyYXRvciBpcyBleGhhdXN0ZWQgYW5kIHRoZSBjYWNoZWQgbGlzdAotICAgICAgICAgKiBpcyBjb21wbGV0ZSwgb3Igbm8gbG9uZ2VyIGdyb3dpbmcuCi0gICAgICAgICAqLwotICAgICAgICBwcml2YXRlIHZvaWQgc2V0Q2FjaGVDb21wbGV0ZShib29sZWFuIGIpIHsKLSAgICAgICAgICAgIG1faXNDb21wbGV0ZTIgPSBiOwotCi0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogUmV0dXJucyB0cnVlIGlmIG5vIGNhY2hlIGlzIGNvbXBsZXRlCi0gICAgICAgICAqIGFuZCBpbW11dGFibGUuCi0gICAgICAgICAqLwotICAgICAgICBwcml2YXRlIGJvb2xlYW4gaXNDb21wbGV0ZSgpIHsKLSAgICAgICAgICAgIHJldHVybiBtX2lzQ29tcGxldGUyOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBjYWNoZWQgbGlzdCBvZiBub2RlcyBhcHBlbmRlZCB3aXRoCi0gICAgICogdmFsdWVzIG9idGFpbmVkIGZyb20gdGhlIGl0ZXJhdG9yIGFzCi0gICAgICogYSBOb2RlU2VxdWVuY2UgaXMgd2Fsa2VkIHdoZW4gaXRzCi0gICAgICogbmV4dE5vZGUoKSBtZXRob2QgaXMgY2FsbGVkLgotICAgICAqLwotICAgIHByb3RlY3RlZCBJdGVyYXRvckNhY2hlIGdldEl0ZXJhdG9yQ2FjaGUoKSB7Ci0gICAgICAgIHJldHVybiBtX2NhY2hlOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvYXhlcy9PbmVTdGVwSXRlcmF0b3IuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvYXhlcy9PbmVTdGVwSXRlcmF0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNTM5MDY4NC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2F4ZXMvT25lU3RlcEl0ZXJhdG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzNDcgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogT25lU3RlcEl0ZXJhdG9yLmphdmEsdiAxLjIuNC4yIDIwMDUvMDkvMTQgMTk6NDU6MjIgamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5heGVzOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTUF4aXNJdGVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1GaWx0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNSXRlcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLkV4cHJlc3Npb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoQ29udGV4dDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuY29tcGlsZXIuQ29tcGlsZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmNvbXBpbGVyLk9wTWFwOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgaW1wbGVtZW50cyBhIGdlbmVyYWwgaXRlcmF0b3IgZm9yCi0gKiB0aG9zZSBMb2NhdGlvblN0ZXBzIHdpdGggb25seSBvbmUgc3RlcCwgYW5kIHBlcmhhcHMgYSBwcmVkaWNhdGUuCi0gKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5heGVzI0xvY1BhdGhJdGVyYXRvcgotICogQHhzbC51c2FnZSBhZHZhbmNlZAotICovCi1wdWJsaWMgY2xhc3MgT25lU3RlcEl0ZXJhdG9yIGV4dGVuZHMgQ2hpbGRUZXN0SXRlcmF0b3IKLXsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNDYyMzcxMDc3OTY2NDk5ODI4M0w7Ci0gIC8qKiBUaGUgdHJhdmVyc2FsIGF4aXMgZnJvbSB3aGVyZSB0aGUgbm9kZXMgd2lsbCBiZSBmaWx0ZXJlZC4gKi8KLSAgcHJvdGVjdGVkIGludCBtX2F4aXMgPSAtMTsKLQotICAvKiogVGhlIERUTSBpbm5lciB0cmF2ZXJzYWwgY2xhc3MsIHRoYXQgY29ycmVzcG9uZHMgdG8gdGhlIHN1cGVyIGF4aXMuICovCi0gIHByb3RlY3RlZCBEVE1BeGlzSXRlcmF0b3IgbV9pdGVyYXRvcjsKLQotICAvKioKLSAgICogQ3JlYXRlIGEgT25lU3RlcEl0ZXJhdG9yIG9iamVjdC4KLSAgICoKLSAgICogQHBhcmFtIGNvbXBpbGVyIEEgcmVmZXJlbmNlIHRvIHRoZSBDb21waWxlciB0aGF0IGNvbnRhaW5zIHRoZSBvcCBtYXAuCi0gICAqIEBwYXJhbSBvcFBvcyBUaGUgcG9zaXRpb24gd2l0aGluIHRoZSBvcCBtYXAsIHdoaWNoIGNvbnRhaW5zIHRoZQotICAgKiBsb2NhdGlvbiBwYXRoIGV4cHJlc3Npb24gZm9yIHRoaXMgaXR0ZXJhdG9yLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIE9uZVN0ZXBJdGVyYXRvcihDb21waWxlciBjb21waWxlciwgaW50IG9wUG9zLCBpbnQgYW5hbHlzaXMpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHN1cGVyKGNvbXBpbGVyLCBvcFBvcywgYW5hbHlzaXMpOwotICAgIGludCBmaXJzdFN0ZXBQb3MgPSBPcE1hcC5nZXRGaXJzdENoaWxkUG9zKG9wUG9zKTsKLQotICAgIG1fYXhpcyA9IFdhbGtlckZhY3RvcnkuZ2V0QXhpc0Zyb21TdGVwKGNvbXBpbGVyLCBmaXJzdFN0ZXBQb3MpOwotCi0gIH0KLQotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBPbmVTdGVwSXRlcmF0b3Igb2JqZWN0LgotICAgKgotICAgKiBAcGFyYW0gaXRlcmF0b3IgVGhlIERUTSBpdGVyYXRvciB3aGljaCB0aGlzIGl0ZXJhdG9yIHdpbGwgdXNlLgotICAgKiBAcGFyYW0gYXhpcyBPbmUgb2YgQXhpcy5DaGlsZCwgZXRjLiwgb3IgLTEgaWYgdGhlIGF4aXMgaXMgdW5rbm93bi4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgT25lU3RlcEl0ZXJhdG9yKERUTUF4aXNJdGVyYXRvciBpdGVyYXRvciwgaW50IGF4aXMpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHN1cGVyKG51bGwpOwotCi0gICAgbV9pdGVyYXRvciA9IGl0ZXJhdG9yOwotICAgIG1fYXhpcyA9IGF4aXM7Ci0gICAgaW50IHdoYXRUb1Nob3cgPSBEVE1GaWx0ZXIuU0hPV19BTEw7Ci0gICAgaW5pdE5vZGVUZXN0KHdoYXRUb1Nob3cpOwotICB9Ci0KLSAgLyoqCi0gICAqIEluaXRpYWxpemUgdGhlIGNvbnRleHQgdmFsdWVzIGZvciB0aGlzIGV4cHJlc3Npb24KLSAgICogYWZ0ZXIgaXQgaXMgY2xvbmVkLgotICAgKgotICAgKiBAcGFyYW0gY29udGV4dCBUaGUgWFBhdGggcnVudGltZSBjb250ZXh0IGZvciB0aGlzCi0gICAqIHRyYW5zZm9ybWF0aW9uLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0Um9vdChpbnQgY29udGV4dCwgT2JqZWN0IGVudmlyb25tZW50KQotICB7Ci0gICAgc3VwZXIuc2V0Um9vdChjb250ZXh0LCBlbnZpcm9ubWVudCk7Ci0gICAgaWYobV9heGlzID4gLTEpCi0gICAgICBtX2l0ZXJhdG9yID0gbV9jZHRtLmdldEF4aXNJdGVyYXRvcihtX2F4aXMpOwotICAgIG1faXRlcmF0b3Iuc2V0U3RhcnROb2RlKG1fY29udGV4dCk7Ci0gIH0KLQotICAvKioKLSAgICogIERldGFjaGVzIHRoZSBpdGVyYXRvciBmcm9tIHRoZSBzZXQgd2hpY2ggaXQgaXRlcmF0ZWQgb3ZlciwgcmVsZWFzaW5nCi0gICAqIGFueSBjb21wdXRhdGlvbmFsIHJlc291cmNlcyBhbmQgcGxhY2luZyB0aGUgaXRlcmF0b3IgaW4gdGhlIElOVkFMSUQKLSAgICogc3RhdGUuIEFmdGVyPGNvZGU+ZGV0YWNoPC9jb2RlPiBoYXMgYmVlbiBpbnZva2VkLCBjYWxscyB0bwotICAgKiA8Y29kZT5uZXh0Tm9kZTwvY29kZT4gb3I8Y29kZT5wcmV2aW91c05vZGU8L2NvZGU+IHdpbGwgcmFpc2UgdGhlCi0gICAqIGV4Y2VwdGlvbiBJTlZBTElEX1NUQVRFX0VSUi4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGRldGFjaCgpCi0gIHsKLSAgICBpZihtX2FsbG93RGV0YWNoKQotICAgIHsKLSAgICAgIGlmKG1fYXhpcyA+IC0xKQotICAgICAgICBtX2l0ZXJhdG9yID0gbnVsbDsKLQotICAgICAgLy8gQWx3YXlzIGNhbGwgdGhlIHN1cGVyY2xhc3MgZGV0YWNoIGxhc3QhCi0gICAgICBzdXBlci5kZXRhY2goKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBuZXh0IG5vZGUgdmlhIGdldEZpcnN0QXR0cmlidXRlICYmIGdldE5leHRBdHRyaWJ1dGUuCi0gICAqLwotICBwcm90ZWN0ZWQgaW50IGdldE5leHROb2RlKCkKLSAgewotICAgIHJldHVybiBtX2xhc3RGZXRjaGVkID0gbV9pdGVyYXRvci5uZXh0KCk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IGEgY2xvbmVkIGl0ZXJhdG9yLgotICAgKgotICAgKiBAcmV0dXJuIEEgbmV3IGl0ZXJhdG9yIHRoYXQgY2FuIGJlIHVzZWQgd2l0aG91dCBtdXRhdGluZyB0aGlzIG9uZS4KLSAgICoKLSAgICogQHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIE9iamVjdCBjbG9uZSgpIHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbgotICB7Ci0gICAgLy8gRG8gbm90IGFjY2VzcyB0aGUgbG9jYXRpb24gcGF0aCBpdHRlcmF0b3IgZHVyaW5nIHRoaXMgb3BlcmF0aW9uIQotCi0gICAgT25lU3RlcEl0ZXJhdG9yIGNsb25lID0gKE9uZVN0ZXBJdGVyYXRvcikgc3VwZXIuY2xvbmUoKTsKLQotICAgIGlmKG1faXRlcmF0b3IgIT0gbnVsbCkKLSAgICB7Ci0gICAgICBjbG9uZS5tX2l0ZXJhdG9yID0gbV9pdGVyYXRvci5jbG9uZUl0ZXJhdG9yKCk7Ci0gICAgfQotICAgIHJldHVybiBjbG9uZTsKLSAgfQotCi0gIC8qKgotICAgKiAgR2V0IGEgY2xvbmVkIEl0ZXJhdG9yIHRoYXQgaXMgcmVzZXQgdG8gdGhlIGJlZ2lubmluZwotICAgKiAgb2YgdGhlIHF1ZXJ5LgotICAgKgotICAgKiAgQHJldHVybiBBIGNsb25lZCBOb2RlSXRlcmF0b3Igc2V0IG9mIHRoZSBzdGFydCBvZiB0aGUgcXVlcnkuCi0gICAqCi0gICAqICBAdGhyb3dzIENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgRFRNSXRlcmF0b3IgY2xvbmVXaXRoUmVzZXQoKSB0aHJvd3MgQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24KLSAgewotCi0gICAgT25lU3RlcEl0ZXJhdG9yIGNsb25lID0gKE9uZVN0ZXBJdGVyYXRvcikgc3VwZXIuY2xvbmVXaXRoUmVzZXQoKTsKLSAgICBjbG9uZS5tX2l0ZXJhdG9yID0gbV9pdGVyYXRvcjsKLQotICAgIHJldHVybiBjbG9uZTsKLSAgfQotCi0KLQotICAvKioKLSAgICogVGVsbHMgaWYgdGhpcyBpcyBhIHJldmVyc2UgYXhlcy4gIE92ZXJyaWRlcyBBeGVzV2Fsa2VyI2lzUmV2ZXJzZUF4ZXMuCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBmb3IgdGhpcyBjbGFzcy4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzUmV2ZXJzZUF4ZXMoKQotICB7Ci0gICAgcmV0dXJuIG1faXRlcmF0b3IuaXNSZXZlcnNlKCk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBjdXJyZW50IHN1Yi1jb250ZXh0IHBvc2l0aW9uLiAgSW4gb3JkZXIgdG8gZG8gdGhlCi0gICAqIHJldmVyc2UgYXhlcyBjb3VudCwgZm9yIHRoZSBtb21lbnQgdGhpcyByZS1zZWFyY2hlcyB0aGUgYXhlcwotICAgKiB1cCB0byB0aGUgcHJlZGljYXRlLiAgQW4gb3B0aW1pemF0aW9uIG9uIHRoaXMgaXMgdG8gY2FjaGUKLSAgICogdGhlIG5vZGVzIHNlYXJjaGVkLCBidXQsIGZvciB0aGUgbW9tZW50LCB0aGlzIGNhc2UgaXMgcHJvYmFibHkKLSAgICogcmFyZSBlbm91Z2ggdGhhdCB0aGUgYWRkZWQgY29tcGxleGl0eSBpc24ndCB3b3J0aCBpdC4KLSAgICoKLSAgICogQHBhcmFtIHByZWRpY2F0ZUluZGV4IFRoZSBwcmVkaWNhdGUgaW5kZXggb2YgdGhlIHByb3hpbWl0eSBwb3NpdGlvbi4KLSAgICoKLSAgICogQHJldHVybiBUaGUgcHJpZGljYXRlIGluZGV4LCBvciAtMS4KLSAgICovCi0gIHByb3RlY3RlZCBpbnQgZ2V0UHJveGltaXR5UG9zaXRpb24oaW50IHByZWRpY2F0ZUluZGV4KQotICB7Ci0gICAgaWYoIWlzUmV2ZXJzZUF4ZXMoKSkKLSAgICAgIHJldHVybiBzdXBlci5nZXRQcm94aW1pdHlQb3NpdGlvbihwcmVkaWNhdGVJbmRleCk7Ci0KLSAgICAvLyBBIG5lZ2F0aXZlIHByZWRpY2F0ZSBpbmRleCBzZWVtcyB0byBvY2N1ciB3aXRoCi0gICAgLy8gKHByZWNlZGluZy1zaWJsaW5nOjoqfGZvbGxvd2luZy1zaWJsaW5nOjoqKS9hbmNlc3Rvcjo6Kltwb3NpdGlvbigpXS8qW3Bvc2l0aW9uKCldCi0gICAgLy8gLXNiCi0gICAgaWYocHJlZGljYXRlSW5kZXggPCAwKQotICAgICAgcmV0dXJuIC0xOwotCi0gICAgaWYgKG1fcHJveGltaXR5UG9zaXRpb25zW3ByZWRpY2F0ZUluZGV4XSA8PSAwKQotICAgIHsKLSAgICAgIFhQYXRoQ29udGV4dCB4Y3R4dCA9IGdldFhQYXRoQ29udGV4dCgpOwotICAgICAgdHJ5Ci0gICAgICB7Ci0gICAgICAgIE9uZVN0ZXBJdGVyYXRvciBjbG9uZSA9IChPbmVTdGVwSXRlcmF0b3IpIHRoaXMuY2xvbmUoKTsKLQotICAgICAgICBpbnQgcm9vdCA9IGdldFJvb3QoKTsKLSAgICAgICAgeGN0eHQucHVzaEN1cnJlbnROb2RlKHJvb3QpOwotICAgICAgICBjbG9uZS5zZXRSb290KHJvb3QsIHhjdHh0KTsKLQotICAgICAgICAvLyBjbG9uZS5zZXRQcmVkaWNhdGVDb3VudChwcmVkaWNhdGVJbmRleCk7Ci0gICAgICAgIGNsb25lLm1fcHJlZENvdW50ID0gcHJlZGljYXRlSW5kZXg7Ci0KLSAgICAgICAgLy8gQ291bnQgJ2VtIGFsbAotICAgICAgICBpbnQgY291bnQgPSAxOwotICAgICAgICBpbnQgbmV4dDsKLQotICAgICAgICB3aGlsZSAoRFRNLk5VTEwgIT0gKG5leHQgPSBjbG9uZS5uZXh0Tm9kZSgpKSkKLSAgICAgICAgewotICAgICAgICAgIGNvdW50Kys7Ci0gICAgICAgIH0KLQotICAgICAgICBtX3Byb3hpbWl0eVBvc2l0aW9uc1twcmVkaWNhdGVJbmRleF0gKz0gY291bnQ7Ci0gICAgICB9Ci0gICAgICBjYXRjaCAoQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gY25zZSkKLSAgICAgIHsKLQotICAgICAgICAvLyBjYW4ndCBoYXBwZW4KLSAgICAgIH0KLSAgICAgIGZpbmFsbHkKLSAgICAgIHsKLSAgICAgICAgeGN0eHQucG9wQ3VycmVudE5vZGUoKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gbV9wcm94aW1pdHlQb3NpdGlvbnNbcHJlZGljYXRlSW5kZXhdOwotICB9Ci0KLSAgLyoqCi0gICAqICBUaGUgbnVtYmVyIG9mIG5vZGVzIGluIHRoZSBsaXN0LiBUaGUgcmFuZ2Ugb2YgdmFsaWQgY2hpbGQgbm9kZSBpbmRpY2VzCi0gICAqIGlzIDAgdG8gPGNvZGU+bGVuZ3RoLTE8L2NvZGU+IGluY2x1c2l2ZS4KLSAgICoKLSAgICogQHJldHVybiBUaGUgbnVtYmVyIG9mIG5vZGVzIGluIHRoZSBsaXN0LCBhbHdheXMgZ3JlYXRlciBvciBlcXVhbCB0byB6ZXJvLgotICAgKi8KLSAgcHVibGljIGludCBnZXRMZW5ndGgoKQotICB7Ci0gICAgaWYoIWlzUmV2ZXJzZUF4ZXMoKSkKLSAgICAgIHJldHVybiBzdXBlci5nZXRMZW5ndGgoKTsKLQotICAgIC8vIFRlbGwgaWYgdGhpcyBpcyBiZWluZyBjYWxsZWQgZnJvbSB3aXRoaW4gYSBwcmVkaWNhdGUuCi0gICAgYm9vbGVhbiBpc1ByZWRpY2F0ZVRlc3QgPSAodGhpcyA9PSBtX2V4ZWNDb250ZXh0LmdldFN1YkNvbnRleHRMaXN0KCkpOwotCi0gICAgLy8gQW5kIGdldCBob3cgbWFueSB0b3RhbCBwcmVkaWNhdGVzIGFyZSBwYXJ0IG9mIHRoaXMgc3RlcC4KLSAgICBpbnQgcHJlZENvdW50ID0gZ2V0UHJlZGljYXRlQ291bnQoKTsKLQotICAgIC8vIElmIHdlIGhhdmUgYWxyZWFkeSBjYWxjdWxhdGVkIHRoZSBsZW5ndGgsIGFuZCB0aGUgY3VycmVudCBwcmVkaWNhdGUKLSAgICAvLyBpcyB0aGUgZmlyc3QgcHJlZGljYXRlLCB0aGVuIHJldHVybiB0aGUgbGVuZ3RoLiAgV2UgZG9uJ3QgY2FjaGUKLSAgICAvLyB0aGUgYW55dGhpbmcgYnV0IHRoZSBsZW5ndGggb2YgdGhlIGxpc3QgdG8gdGhlIGZpcnN0IHByZWRpY2F0ZS4KLSAgICBpZiAoLTEgIT0gbV9sZW5ndGggJiYgaXNQcmVkaWNhdGVUZXN0ICYmIG1fcHJlZGljYXRlSW5kZXggPCAxKQotICAgICAgIHJldHVybiBtX2xlbmd0aDsKLQotICAgIGludCBjb3VudCA9IDA7Ci0KLSAgICBYUGF0aENvbnRleHQgeGN0eHQgPSBnZXRYUGF0aENvbnRleHQoKTsKLSAgICB0cnkKLSAgICB7Ci0gICAgICBPbmVTdGVwSXRlcmF0b3IgY2xvbmUgPSAoT25lU3RlcEl0ZXJhdG9yKSB0aGlzLmNsb25lV2l0aFJlc2V0KCk7Ci0KLSAgICAgIGludCByb290ID0gZ2V0Um9vdCgpOwotICAgICAgeGN0eHQucHVzaEN1cnJlbnROb2RlKHJvb3QpOwotICAgICAgY2xvbmUuc2V0Um9vdChyb290LCB4Y3R4dCk7Ci0KLSAgICAgIGNsb25lLm1fcHJlZENvdW50ID0gbV9wcmVkaWNhdGVJbmRleDsKLQotICAgICAgaW50IG5leHQ7Ci0KLSAgICAgIHdoaWxlIChEVE0uTlVMTCAhPSAobmV4dCA9IGNsb25lLm5leHROb2RlKCkpKQotICAgICAgewotICAgICAgICBjb3VudCsrOwotICAgICAgfQotICAgIH0KLSAgICBjYXRjaCAoQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gY25zZSkKLSAgICB7Ci0gICAgICAgLy8gY2FuJ3QgaGFwcGVuCi0gICAgfQotICAgIGZpbmFsbHkKLSAgICB7Ci0gICAgICB4Y3R4dC5wb3BDdXJyZW50Tm9kZSgpOwotICAgIH0KLSAgICBpZiAoaXNQcmVkaWNhdGVUZXN0ICYmIG1fcHJlZGljYXRlSW5kZXggPCAxKQotICAgICAgbV9sZW5ndGggPSBjb3VudDsKLQotICAgIHJldHVybiBjb3VudDsKLSAgfQotCi0gIC8qKgotICAgKiBDb3VudCBiYWNrd2FyZHMgb25lIHByb3hpbWl0eSBwb3NpdGlvbi4KLSAgICoKLSAgICogQHBhcmFtIGkgVGhlIHByZWRpY2F0ZSBpbmRleC4KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIGNvdW50UHJveGltaXR5UG9zaXRpb24oaW50IGkpCi0gIHsKLSAgICBpZighaXNSZXZlcnNlQXhlcygpKQotICAgICAgc3VwZXIuY291bnRQcm94aW1pdHlQb3NpdGlvbihpKTsKLSAgICBlbHNlIGlmIChpIDwgbV9wcm94aW1pdHlQb3NpdGlvbnMubGVuZ3RoKQotICAgICAgbV9wcm94aW1pdHlQb3NpdGlvbnNbaV0tLTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXNldCB0aGUgaXRlcmF0b3IuCi0gICAqLwotICBwdWJsaWMgdm9pZCByZXNldCgpCi0gIHsKLQotICAgIHN1cGVyLnJlc2V0KCk7Ci0gICAgaWYobnVsbCAhPSBtX2l0ZXJhdG9yKQotICAgICAgbV9pdGVyYXRvci5yZXNldCgpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIGF4aXMgYmVpbmcgaXRlcmF0ZWQsIGlmIGl0IGlzIGtub3duLgotICAgKgotICAgKiBAcmV0dXJuIEF4aXMuQ0hJTEQsIGV0Yy4sIG9yIC0xIGlmIHRoZSBheGlzIGlzIG5vdCBrbm93biBvciBpcyBvZiBtdWx0aXBsZQotICAgKiB0eXBlcy4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0QXhpcygpCi0gIHsKLSAgICByZXR1cm4gbV9heGlzOwotICB9Ci0KLSAgLyoqCi0gICAqIEBzZWUgRXhwcmVzc2lvbiNkZWVwRXF1YWxzKEV4cHJlc3Npb24pCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBkZWVwRXF1YWxzKEV4cHJlc3Npb24gZXhwcikKLSAgewotICAgICAgICBpZighc3VwZXIuZGVlcEVxdWFscyhleHByKSkKLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0KLSAgICAgICAgaWYobV9heGlzICE9ICgoT25lU3RlcEl0ZXJhdG9yKWV4cHIpLm1fYXhpcykKLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0KLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gIH0KLQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2F4ZXMvT25lU3RlcEl0ZXJhdG9yRm9yd2FyZC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9heGVzL09uZVN0ZXBJdGVyYXRvckZvcndhcmQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZWExYTgyOS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2F4ZXMvT25lU3RlcEl0ZXJhdG9yRm9yd2FyZC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTc0ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IE9uZVN0ZXBJdGVyYXRvckZvcndhcmQuamF2YSx2IDEuMi40LjIgMjAwNS8wOS8xNCAxOTo0NToyMiBqZWZmc3V0dG9yIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmF4ZXM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE07Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNRmlsdGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5FeHByZXNzaW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5jb21waWxlci5Db21waWxlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuY29tcGlsZXIuT3BNYXA7Ci0KLS8qKgotICogVGhpcyBjbGFzcyBpbXBsZW1lbnRzIGEgZ2VuZXJhbCBpdGVyYXRvciBmb3IKLSAqIHRob3NlIExvY2F0aW9uU3RlcHMgd2l0aCBvbmx5IG9uZSBzdGVwLCBhbmQgcGVyaGFwcyBhIHByZWRpY2F0ZSwKLSAqIHRoYXQgb25seSBnbyBmb3J3YXJkIChpLmUuIGl0IGNhbiBub3QgYmUgdXNlZCB3aXRoIGFuY2VzdG9ycywKLSAqIHByZWNlZGluZywgZXRjLikKLSAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmF4ZXMjQ2hpbGRUZXN0SXRlcmF0b3IKLSAqIEB4c2wudXNhZ2UgYWR2YW5jZWQKLSAqLwotcHVibGljIGNsYXNzIE9uZVN0ZXBJdGVyYXRvckZvcndhcmQgZXh0ZW5kcyBDaGlsZFRlc3RJdGVyYXRvcgotewotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMTU3NjkzNjYwNjE3ODE5MDU2Nkw7Ci0gIC8qKiBUaGUgdHJhdmVyc2FsIGF4aXMgZnJvbSB3aGVyZSB0aGUgbm9kZXMgd2lsbCBiZSBmaWx0ZXJlZC4gKi8KLSAgcHJvdGVjdGVkIGludCBtX2F4aXMgPSAtMTsKLQotICAvKioKLSAgICogQ3JlYXRlIGEgT25lU3RlcEl0ZXJhdG9yIG9iamVjdC4KLSAgICoKLSAgICogQHBhcmFtIGNvbXBpbGVyIEEgcmVmZXJlbmNlIHRvIHRoZSBDb21waWxlciB0aGF0IGNvbnRhaW5zIHRoZSBvcCBtYXAuCi0gICAqIEBwYXJhbSBvcFBvcyBUaGUgcG9zaXRpb24gd2l0aGluIHRoZSBvcCBtYXAsIHdoaWNoIGNvbnRhaW5zIHRoZQotICAgKiBsb2NhdGlvbiBwYXRoIGV4cHJlc3Npb24gZm9yIHRoaXMgaXR0ZXJhdG9yLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIE9uZVN0ZXBJdGVyYXRvckZvcndhcmQoQ29tcGlsZXIgY29tcGlsZXIsIGludCBvcFBvcywgaW50IGFuYWx5c2lzKQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICBzdXBlcihjb21waWxlciwgb3BQb3MsIGFuYWx5c2lzKTsKLSAgICBpbnQgZmlyc3RTdGVwUG9zID0gT3BNYXAuZ2V0Rmlyc3RDaGlsZFBvcyhvcFBvcyk7Ci0KLSAgICBtX2F4aXMgPSBXYWxrZXJGYWN0b3J5LmdldEF4aXNGcm9tU3RlcChjb21waWxlciwgZmlyc3RTdGVwUG9zKTsKLQotICB9Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIE9uZVN0ZXBJdGVyYXRvciBvYmplY3QgdGhhdCB3aWxsIGp1c3QgdHJhdmVyc2UgdGhlIHNlbGYgYXhlcy4KLSAgICoKLSAgICogQHBhcmFtIGF4aXMgT25lIG9mIHRoZSBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5BeGlzIGludGVnZXJzLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBPbmVTdGVwSXRlcmF0b3JGb3J3YXJkKGludCBheGlzKQotICB7Ci0gICAgc3VwZXIobnVsbCk7Ci0KLSAgICBtX2F4aXMgPSBheGlzOwotICAgIGludCB3aGF0VG9TaG93ID0gRFRNRmlsdGVyLlNIT1dfQUxMOwotICAgIGluaXROb2RlVGVzdCh3aGF0VG9TaG93KTsKLSAgfQotCi0KLQotCi0gIC8qKgotICAgKiBJbml0aWFsaXplIHRoZSBjb250ZXh0IHZhbHVlcyBmb3IgdGhpcyBleHByZXNzaW9uCi0gICAqIGFmdGVyIGl0IGlzIGNsb25lZC4KLSAgICoKLSAgICogQHBhcmFtIGNvbnRleHQgVGhlIFhQYXRoIHJ1bnRpbWUgY29udGV4dCBmb3IgdGhpcwotICAgKiB0cmFuc2Zvcm1hdGlvbi4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFJvb3QoaW50IGNvbnRleHQsIE9iamVjdCBlbnZpcm9ubWVudCkKLSAgewotICAgIHN1cGVyLnNldFJvb3QoY29udGV4dCwgZW52aXJvbm1lbnQpOwotICAgIG1fdHJhdmVyc2VyID0gbV9jZHRtLmdldEF4aXNUcmF2ZXJzZXIobV9heGlzKTsKLQotICB9Ci0KLS8vICAvKioKLS8vICAgKiBSZXR1cm4gdGhlIGZpcnN0IG5vZGUgb3V0IG9mIHRoZSBub2Rlc2V0LCBpZiB0aGlzIGV4cHJlc3Npb24gaXMKLS8vICAgKiBhIG5vZGVzZXQgZXhwcmVzc2lvbi4gIFRoaXMgaXMgdGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gZm9yCi0vLyAgICogbm9kZXNldHMuCi0vLyAgICogPHA+V0FSTklORzogRG8gbm90IG11dGF0ZSB0aGlzIGNsYXNzIGZyb20gdGhpcyBmdW5jdGlvbiE8L3A+Ci0vLyAgICogQHBhcmFtIHhjdHh0IFRoZSBYUGF0aCBydW50aW1lIGNvbnRleHQuCi0vLyAgICogQHJldHVybiB0aGUgZmlyc3Qgbm9kZSBvdXQgb2YgdGhlIG5vZGVzZXQsIG9yIERUTS5OVUxMLgotLy8gICAqLwotLy8gIHB1YmxpYyBpbnQgYXNOb2RlKFhQYXRoQ29udGV4dCB4Y3R4dCkKLS8vICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0vLyAgewotLy8gICAgaWYoZ2V0UHJlZGljYXRlQ291bnQoKSA+IDApCi0vLyAgICAgIHJldHVybiBzdXBlci5hc05vZGUoeGN0eHQpOwotLy8KLS8vICAgIGludCBjdXJyZW50ID0geGN0eHQuZ2V0Q3VycmVudE5vZGUoKTsKLS8vCi0vLyAgICBEVE0gZHRtID0geGN0eHQuZ2V0RFRNKGN1cnJlbnQpOwotLy8gICAgRFRNQXhpc1RyYXZlcnNlciB0cmF2ZXJzZXIgPSBkdG0uZ2V0QXhpc1RyYXZlcnNlcihtX2F4aXMpOwotLy8KLS8vICAgIFN0cmluZyBsb2NhbE5hbWUgPSBnZXRMb2NhbE5hbWUoKTsKLS8vICAgIFN0cmluZyBuYW1lc3BhY2UgPSBnZXROYW1lc3BhY2UoKTsKLS8vICAgIGludCB3aGF0ID0gbV93aGF0VG9TaG93OwotLy8KLS8vICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigid2hhdDogIik7Ci0vLyAgICAvLyBOb2RlVGVzdC5kZWJ1Z1doYXRUb1Nob3cod2hhdCk7Ci0vLyAgICBpZihEVE1GaWx0ZXIuU0hPV19BTEwgPT0gd2hhdAotLy8gICAgICAgfHwgKChEVE1GaWx0ZXIuU0hPV19FTEVNRU5UICYgd2hhdCkgPT0gMCkKLS8vICAgICAgIHx8IGxvY2FsTmFtZSA9PSBOb2RlVGVzdC5XSUxECi0vLyAgICAgICB8fCBuYW1lc3BhY2UgPT0gTm9kZVRlc3QuV0lMRCkKLS8vICAgIHsKLS8vICAgICAgcmV0dXJuIHRyYXZlcnNlci5maXJzdChjdXJyZW50KTsKLS8vICAgIH0KLS8vICAgIGVsc2UKLS8vICAgIHsKLS8vICAgICAgaW50IHR5cGUgPSBnZXROb2RlVHlwZVRlc3Qod2hhdCk7Ci0vLyAgICAgIGludCBleHRlbmRlZFR5cGUgPSBkdG0uZ2V0RXhwYW5kZWRUeXBlSUQobmFtZXNwYWNlLCBsb2NhbE5hbWUsIHR5cGUpOwotLy8gICAgICByZXR1cm4gdHJhdmVyc2VyLmZpcnN0KGN1cnJlbnQsIGV4dGVuZGVkVHlwZSk7Ci0vLyAgICB9Ci0vLyAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIG5leHQgbm9kZSB2aWEgZ2V0Rmlyc3RBdHRyaWJ1dGUgJiYgZ2V0TmV4dEF0dHJpYnV0ZS4KLSAgICovCi0gIHByb3RlY3RlZCBpbnQgZ2V0TmV4dE5vZGUoKQotICB7Ci0gICAgbV9sYXN0RmV0Y2hlZCA9IChEVE0uTlVMTCA9PSBtX2xhc3RGZXRjaGVkKQotICAgICAgICAgICAgICAgICAgICAgPyBtX3RyYXZlcnNlci5maXJzdChtX2NvbnRleHQpCi0gICAgICAgICAgICAgICAgICAgICA6IG1fdHJhdmVyc2VyLm5leHQobV9jb250ZXh0LCBtX2xhc3RGZXRjaGVkKTsKLSAgICByZXR1cm4gbV9sYXN0RmV0Y2hlZDsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBheGlzIGJlaW5nIGl0ZXJhdGVkLCBpZiBpdCBpcyBrbm93bi4KLSAgICoKLSAgICogQHJldHVybiBBeGlzLkNISUxELCBldGMuLCBvciAtMSBpZiB0aGUgYXhpcyBpcyBub3Qga25vd24gb3IgaXMgb2YgbXVsdGlwbGUKLSAgICogdHlwZXMuCi0gICAqLwotICBwdWJsaWMgaW50IGdldEF4aXMoKQotICB7Ci0gICAgcmV0dXJuIG1fYXhpczsKLSAgfQotCi0gIC8qKgotICAgKiBAc2VlIEV4cHJlc3Npb24jZGVlcEVxdWFscyhFeHByZXNzaW9uKQotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZGVlcEVxdWFscyhFeHByZXNzaW9uIGV4cHIpCi0gIHsKLSAgICAgICAgaWYoIXN1cGVyLmRlZXBFcXVhbHMoZXhwcikpCi0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotCi0gICAgICAgIGlmKG1fYXhpcyAhPSAoKE9uZVN0ZXBJdGVyYXRvckZvcndhcmQpZXhwcikubV9heGlzKQotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLQotICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgfQotCi0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvYXhlcy9QYXRoQ29tcG9uZW50LmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2F4ZXMvUGF0aENvbXBvbmVudC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhNzI4MjlkLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvYXhlcy9QYXRoQ29tcG9uZW50LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzNyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBQYXRoQ29tcG9uZW50LmphdmEsdiAxLjEuMi4xIDIwMDUvMDgvMDEgMDE6MzA6MjcgamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5heGVzOwotCi0vKioKLSAqIENsYXNzZXMgd2hvIGltcGxlbWVudCB0aGlzIGluZm9ybWF0aW9uIHByb3ZpZGUgaW5mb3JtYXRpb24gbmVlZGVkIGZvcgotICogc3RhdGljIGFuYWx5c2lzIG9mIGEgcGF0aCBjb21wb25lbnQuCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgUGF0aENvbXBvbmVudAotewotICAvKioKLSAgICogR2V0IHRoZSBhbmFseXNpcyBiaXRzIGZvciB0aGlzIHBhdGggY29tcG9uZW50LCBhcyBkZWZpbmVkIGluIHRoZSBXYWxrZXJGYWN0b3J5LgotICAgKiBAcmV0dXJuIE9uZSBvZiBXYWxrZXJGYWN0b3J5I0JJVF9ERVNDRU5EQU5ULCBldGMuCi0gICAqLwotICBwdWJsaWMgaW50IGdldEFuYWx5c2lzQml0cygpOwotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2F4ZXMvUHJlZGljYXRlZE5vZGVUZXN0LmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2F4ZXMvUHJlZGljYXRlZE5vZGVUZXN0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDk2NWYzZjMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9heGVzL1ByZWRpY2F0ZWROb2RlVGVzdC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNjQ5ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFByZWRpY2F0ZWROb2RlVGVzdC5qYXZhLHYgMS4yLjQuMiAyMDA1LzA5LzE0IDE5OjQ1OjIwIGplZmZzdXR0b3IgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuYXhlczsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1JdGVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLlByZWZpeFJlc29sdmVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5FeHByZXNzaW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5FeHByZXNzaW9uT3duZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoQ29udGV4dDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuWFBhdGhWaXNpdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5jb21waWxlci5Db21waWxlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YT2JqZWN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5wYXR0ZXJucy5Ob2RlVGVzdDsKLQotcHVibGljIGFic3RyYWN0IGNsYXNzIFByZWRpY2F0ZWROb2RlVGVzdCBleHRlbmRzIE5vZGVUZXN0IGltcGxlbWVudHMgU3ViQ29udGV4dExpc3QKLXsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTYxOTM1MzA3NTcyOTYzNzczNTFMOwotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYW4gQXhlc1dhbGtlciB1c2luZyBhIExvY1BhdGhJdGVyYXRvci4KLSAgICoKLSAgICogQHBhcmFtIGxvY1BhdGhJdGVyYXRvciBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIHBhcmVudCBpdGVyYXRvci4KLSAgICovCi0gIFByZWRpY2F0ZWROb2RlVGVzdChMb2NQYXRoSXRlcmF0b3IgbG9jUGF0aEl0ZXJhdG9yKQotICB7Ci0gICAgbV9scGkgPSBsb2NQYXRoSXRlcmF0b3I7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IGFuIEF4ZXNXYWxrZXIuICBUaGUgbG9jYXRpb24gcGF0aCBpdGVyYXRvciB3aWxsIGhhdmUgdG8gYmUgc2V0Ci0gICAqIGJlZm9yZSB1c2UuCi0gICAqLwotICBQcmVkaWNhdGVkTm9kZVRlc3QoKQotICB7Ci0gIH0KLQotICAvKioKLSAgICogUmVhZCB0aGUgb2JqZWN0IGZyb20gYSBzZXJpYWxpemF0aW9uIHN0cmVhbS4KLSAgICoKLSAgICogQHBhcmFtIHN0cmVhbSBJbnB1dCBzdHJlYW0gdG8gcmVhZCBmcm9tCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHByaXZhdGUgdm9pZCByZWFkT2JqZWN0KGphdmEuaW8uT2JqZWN0SW5wdXRTdHJlYW0gc3RyZWFtKQotICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uLCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICB0cnkKLSAgICB7Ci0gICAgICBzdHJlYW0uZGVmYXVsdFJlYWRPYmplY3QoKTsKLSAgICAgIG1fcHJlZGljYXRlSW5kZXggPSAtMTsKLSAgICAgIHJlc2V0UHJveGltaXR5UG9zaXRpb25zKCk7Ci0gICAgfQotICAgIGNhdGNoIChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGNuZmUpCi0gICAgewotICAgICAgdGhyb3cgbmV3IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24oY25mZSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBhIGNsb25lZCBQcmRpY2F0ZWROb2RlVGVzdC4KLSAgICoKLSAgICogQHJldHVybiBBIG5ldyBQcmVkaWNhdGVkTm9kZVRlc3QgdGhhdCBjYW4gYmUgdXNlZCB3aXRob3V0IG11dGF0aW5nIHRoaXMgb25lLgotICAgKgotICAgKiBAdGhyb3dzIENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgT2JqZWN0IGNsb25lKCkgdGhyb3dzIENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uCi0gIHsKLSAgICAvLyBEbyBub3QgYWNjZXNzIHRoZSBsb2NhdGlvbiBwYXRoIGl0dGVyYXRvciBkdXJpbmcgdGhpcyBvcGVyYXRpb24hCi0KLSAgICBQcmVkaWNhdGVkTm9kZVRlc3QgY2xvbmUgPSAoUHJlZGljYXRlZE5vZGVUZXN0KSBzdXBlci5jbG9uZSgpOwotCi0gICAgaWYgKChudWxsICE9IHRoaXMubV9wcm94aW1pdHlQb3NpdGlvbnMpCi0gICAgICAgICAgICAmJiAodGhpcy5tX3Byb3hpbWl0eVBvc2l0aW9ucyA9PSBjbG9uZS5tX3Byb3hpbWl0eVBvc2l0aW9ucykpCi0gICAgewotICAgICAgY2xvbmUubV9wcm94aW1pdHlQb3NpdGlvbnMgPSBuZXcgaW50W3RoaXMubV9wcm94aW1pdHlQb3NpdGlvbnMubGVuZ3RoXTsKLQotICAgICAgU3lzdGVtLmFycmF5Y29weSh0aGlzLm1fcHJveGltaXR5UG9zaXRpb25zLCAwLAotICAgICAgICAgICAgICAgICAgICAgICBjbG9uZS5tX3Byb3hpbWl0eVBvc2l0aW9ucywgMCwKLSAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5tX3Byb3hpbWl0eVBvc2l0aW9ucy5sZW5ndGgpOwotICAgIH0KLQotICAgIGlmKGNsb25lLm1fbHBpID09IHRoaXMpCi0gICAgICBjbG9uZS5tX2xwaSA9IChMb2NQYXRoSXRlcmF0b3IpY2xvbmU7Ci0KLSAgICByZXR1cm4gY2xvbmU7Ci0gIH0KLQotICAvLyBPbmx5IGZvciBjbG9uZXMgZm9yIGZpbmRMYXN0UG9zLiAgU2VlIGJ1ZzQ2MzguCi0gIHByb3RlY3RlZCBpbnQgbV9wcmVkQ291bnQgPSAtMTsKLQotICAvKioKLSAgICogR2V0IHRoZSBudW1iZXIgb2YgcHJlZGljYXRlcyB0aGF0IHRoaXMgd2Fsa2VyIGhhcy4KLSAgICoKLSAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIHByZWRpY2F0ZXMgdGhhdCB0aGlzIHdhbGtlciBoYXMuCi0gICAqLwotICBwdWJsaWMgaW50IGdldFByZWRpY2F0ZUNvdW50KCkKLSAgewotICAgIGlmKC0xID09IG1fcHJlZENvdW50KQotICAgICAgcmV0dXJuIChudWxsID09IG1fcHJlZGljYXRlcykgPyAwIDogbV9wcmVkaWNhdGVzLmxlbmd0aDsKLSAgICBlbHNlCi0gICAgICByZXR1cm4gbV9wcmVkQ291bnQ7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBudW1iZXIgb2YgcHJlZGljYXRlcyB0aGF0IHRoaXMgd2Fsa2VyIGhhcy4gIFRoaXMgZG9lcyBtb3JlCi0gICAqIHRoYXQgb25lIHdvdWxkIHRoaW5rLCBhcyBpdCBjcmVhdGVzIGEgbmV3IHByZWRpY2F0ZSBhcnJheSBvZiB0aGUKLSAgICogc2l6ZSBvZiB0aGUgY291bnQgYXJndW1lbnQsIGFuZCBjb3BpZXMgY291bnQgcHJlZGljYXRlcyBpbnRvIHRoZSBuZXcKLSAgICogb25lIGZyb20gdGhlIG9sZCwgYW5kIHRoZW4gcmVhc3NpZ25zIHRoZSBwcmVkaWNhdGVzIHZhbHVlLiAgQWxsIHRoaXMKLSAgICogdG8ga2VlcCBmcm9tIGhhdmluZyB0byBoYXZlIGEgcHJlZGljYXRlIGNvdW50IHZhbHVlLgotICAgKgotICAgKiBAcGFyYW0gY291bnQgVGhlIG51bWJlciBvZiBwcmVkaWNhdGVzLCB3aGljaCBtdXN0IGJlIGVxdWFsIG9yIGxlc3MKLSAgICogICAgICAgICAgICAgICB0aGFuIHRoZSBleGlzdGluZyBjb3VudC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFByZWRpY2F0ZUNvdW50KGludCBjb3VudCkKLSAgewotICAgIGlmKGNvdW50ID4gMCkKLSAgICB7Ci0gICAgICBFeHByZXNzaW9uW10gbmV3UHJlZGljYXRlcyA9IG5ldyBFeHByZXNzaW9uW2NvdW50XTsKLSAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykKLSAgICAgIHsKLSAgICAgICAgbmV3UHJlZGljYXRlc1tpXSA9IG1fcHJlZGljYXRlc1tpXTsKLSAgICAgIH0KLSAgICAgIG1fcHJlZGljYXRlcyA9IG5ld1ByZWRpY2F0ZXM7Ci0gICAgfQotICAgIGVsc2UKLSAgICAgIG1fcHJlZGljYXRlcyA9IG51bGw7Ci0KLSAgfQotCi0gIC8qKgotICAgKiBJbml0IHByZWRpY2F0ZSBpbmZvLgotICAgKgotICAgKiBAcGFyYW0gY29tcGlsZXIgVGhlIENvbXBpbGVyIG9iamVjdCB0aGF0IGhhcyBpbmZvcm1hdGlvbiBhYm91dCB0aGlzCi0gICAqICAgICAgICAgICAgICAgICB3YWxrZXIgaW4gdGhlIG9wIG1hcC4KLSAgICogQHBhcmFtIG9wUG9zIFRoZSBvcCBjb2RlIHBvc2l0aW9uIG9mIHRoaXMgbG9jYXRpb24gc3RlcC4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBpbml0UHJlZGljYXRlSW5mbyhDb21waWxlciBjb21waWxlciwgaW50IG9wUG9zKQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGludCBwb3MgPSBjb21waWxlci5nZXRGaXJzdFByZWRpY2F0ZU9wUG9zKG9wUG9zKTsKLQotICAgIGlmKHBvcyA+IDApCi0gICAgewotICAgICAgbV9wcmVkaWNhdGVzID0gY29tcGlsZXIuZ2V0Q29tcGlsZWRQcmVkaWNhdGVzKHBvcyk7Ci0gICAgICBpZihudWxsICE9IG1fcHJlZGljYXRlcykKLSAgICAgIHsKLSAgICAgICAgZm9yKGludCBpID0gMDsgaSA8IG1fcHJlZGljYXRlcy5sZW5ndGg7IGkrKykKLSAgICAgICAgewotICAgICAgICAgICAgICAgIG1fcHJlZGljYXRlc1tpXS5leHByU2V0UGFyZW50KHRoaXMpOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBhIHByZWRpY2F0ZSBleHByZXNzaW9uIGF0IHRoZSBnaXZlbiBpbmRleC4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIGluZGV4IEluZGV4IG9mIHRoZSBwcmVkaWNhdGUuCi0gICAqCi0gICAqIEByZXR1cm4gQSBwcmVkaWNhdGUgZXhwcmVzc2lvbi4KLSAgICovCi0gIHB1YmxpYyBFeHByZXNzaW9uIGdldFByZWRpY2F0ZShpbnQgaW5kZXgpCi0gIHsKLSAgICByZXR1cm4gbV9wcmVkaWNhdGVzW2luZGV4XTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGN1cnJlbnQgc3ViLWNvbnRleHQgcG9zaXRpb24uCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIG5vZGUgcG9zaXRpb24gb2YgdGhpcyB3YWxrZXIgaW4gdGhlIHN1Yi1jb250ZXh0IG5vZGUgbGlzdC4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0UHJveGltaXR5UG9zaXRpb24oKQotICB7Ci0KLSAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oImdldFByb3hpbWl0eVBvc2l0aW9uIC0gbV9wcmVkaWNhdGVJbmRleDogIittX3ByZWRpY2F0ZUluZGV4KTsKLSAgICByZXR1cm4gZ2V0UHJveGltaXR5UG9zaXRpb24obV9wcmVkaWNhdGVJbmRleCk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBjdXJyZW50IHN1Yi1jb250ZXh0IHBvc2l0aW9uLgotICAgKgotICAgKiBAcGFyYW0geGN0eHQgVGhlIFhQYXRoIHJ1bnRpbWUgY29udGV4dC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgbm9kZSBwb3NpdGlvbiBvZiB0aGlzIHdhbGtlciBpbiB0aGUgc3ViLWNvbnRleHQgbm9kZSBsaXN0LgotICAgKi8KLSAgcHVibGljIGludCBnZXRQcm94aW1pdHlQb3NpdGlvbihYUGF0aENvbnRleHQgeGN0eHQpCi0gIHsKLSAgICByZXR1cm4gZ2V0UHJveGltaXR5UG9zaXRpb24oKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGluZGV4IG9mIHRoZSBsYXN0IG5vZGUgdGhhdCBjYW4gYmUgaXR0ZXJhdGVkIHRvLgotICAgKgotICAgKgotICAgKiBAcGFyYW0geGN0eHQgWFBhdGggcnVudGltZSBjb250ZXh0LgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBpbmRleCBvZiB0aGUgbGFzdCBub2RlIHRoYXQgY2FuIGJlIGl0dGVyYXRlZCB0by4KLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBpbnQgZ2V0TGFzdFBvcyhYUGF0aENvbnRleHQgeGN0eHQpOwotCi0gIC8qKgotICAgKiBHZXQgdGhlIGN1cnJlbnQgc3ViLWNvbnRleHQgcG9zaXRpb24uCi0gICAqCi0gICAqIEBwYXJhbSBwcmVkaWNhdGVJbmRleCBUaGUgaW5kZXggb2YgdGhlIHByZWRpY2F0ZSB3aGVyZSB0aGUgcHJveGltaXR5Ci0gICAqICAgICAgICAgICAgICAgICAgICAgICBzaG91bGQgYmUgdGFrZW4gZnJvbS4KLSAgICoKLSAgICogQHJldHVybiBUaGUgbm9kZSBwb3NpdGlvbiBvZiB0aGlzIHdhbGtlciBpbiB0aGUgc3ViLWNvbnRleHQgbm9kZSBsaXN0LgotICAgKi8KLSAgcHJvdGVjdGVkIGludCBnZXRQcm94aW1pdHlQb3NpdGlvbihpbnQgcHJlZGljYXRlSW5kZXgpCi0gIHsKLSAgICByZXR1cm4gKHByZWRpY2F0ZUluZGV4ID49IDApID8gbV9wcm94aW1pdHlQb3NpdGlvbnNbcHJlZGljYXRlSW5kZXhdIDogMDsKLSAgfQotCi0gIC8qKgotICAgKiBSZXNldCB0aGUgcHJveGltaXR5IHBvc2l0aW9ucyBjb3VudHMuCi0gICAqLwotICBwdWJsaWMgdm9pZCByZXNldFByb3hpbWl0eVBvc2l0aW9ucygpCi0gIHsKLSAgICBpbnQgblByZWRpY2F0ZXMgPSBnZXRQcmVkaWNhdGVDb3VudCgpOwotICAgIGlmIChuUHJlZGljYXRlcyA+IDApCi0gICAgewotICAgICAgaWYgKG51bGwgPT0gbV9wcm94aW1pdHlQb3NpdGlvbnMpCi0gICAgICAgIG1fcHJveGltaXR5UG9zaXRpb25zID0gbmV3IGludFtuUHJlZGljYXRlc107Ci0KLSAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgblByZWRpY2F0ZXM7IGkrKykKLSAgICAgIHsKLSAgICAgICAgdHJ5Ci0gICAgICAgIHsKLSAgICAgICAgICBpbml0UHJveGltaXR5UG9zaXRpb24oaSk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2goRXhjZXB0aW9uIGUpCi0gICAgICAgIHsKLSAgICAgICAgICAvLyBUT0RPOiBGaXggdGhpcy4uLgotICAgICAgICAgIHRocm93IG5ldyBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLldyYXBwZWRSdW50aW1lRXhjZXB0aW9uKGUpOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEluaXQgdGhlIHByb3hpbWl0eSBwb3NpdGlvbiB0byB6ZXJvIGZvciBhIGZvcndhcmQgYXhlcy4KLSAgICoKLSAgICogQHBhcmFtIGkgVGhlIGluZGV4IGludG8gdGhlIG1fcHJveGltaXR5UG9zaXRpb25zIGFycmF5LgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGluaXRQcm94aW1pdHlQb3NpdGlvbihpbnQgaSkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIG1fcHJveGltaXR5UG9zaXRpb25zW2ldID0gMDsKLSAgfQotCi0gIC8qKgotICAgKiBDb3VudCBmb3J3YXJkIG9uZSBwcm94aW1pdHkgcG9zaXRpb24uCi0gICAqCi0gICAqIEBwYXJhbSBpIFRoZSBpbmRleCBpbnRvIHRoZSBtX3Byb3hpbWl0eVBvc2l0aW9ucyBhcnJheSwgd2hlcmUgdGhlIGluY3JlbWVudAotICAgKiAgICAgICAgICB3aWxsIG9jY3VyLgotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgY291bnRQcm94aW1pdHlQb3NpdGlvbihpbnQgaSkKLSAgewotICAgICAgICAvLyBOb3RlIHRoYXQgaW4gdGhlIGNhc2Ugb2YgYSBVbmlvbkNoaWxkSXRlcmF0b3IsIHRoaXMgbWF5IGJlIGEKLSAgICAgICAgLy8gc3RhdGljIG9iamVjdCBhbmQgc28gbV9wcm94aW1pdHlQb3NpdGlvbnMgbWF5IGluZGVlZCBiZSBudWxsIQotICAgICAgICBpbnRbXSBwcCA9IG1fcHJveGltaXR5UG9zaXRpb25zOwotICAgIGlmICgobnVsbCAhPSBwcCkgJiYgKGkgPCBwcC5sZW5ndGgpKQotICAgICAgcHBbaV0rKzsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxscyBpZiB0aGlzIGlzIGEgcmV2ZXJzZSBheGVzLgotICAgKgotICAgKiBAcmV0dXJuIGZhbHNlLCB1bmxlc3MgYSBkZXJpdmVkIGNsYXNzIG92ZXJyaWRlcy4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzUmV2ZXJzZUF4ZXMoKQotICB7Ci0gICAgcmV0dXJuIGZhbHNlOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB3aGljaCBwcmVkaWNhdGUgaXMgZXhlY3V0aW5nLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBjdXJyZW50IHByZWRpY2F0ZSBpbmRleCwgb3IgLTEgaWYgbm8gcHJlZGljYXRlIGlzIGV4ZWN1dGluZy4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0UHJlZGljYXRlSW5kZXgoKQotICB7Ci0gICAgcmV0dXJuIG1fcHJlZGljYXRlSW5kZXg7Ci0gIH0KLQotICAvKioKLSAgICogUHJvY2VzcyB0aGUgcHJlZGljYXRlcy4KLSAgICoKLSAgICogQHBhcmFtIGNvbnRleHQgVGhlIGN1cnJlbnQgY29udGV4dCBub2RlLgotICAgKiBAcGFyYW0geGN0eHQgVGhlIFhQYXRoIHJ1bnRpbWUgY29udGV4dC4KLSAgICoKLSAgICogQHJldHVybiB0aGUgcmVzdWx0IG9mIGV4ZWN1dGluZyB0aGUgcHJlZGljYXRlIGV4cHJlc3Npb25zLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIGJvb2xlYW4gZXhlY3V0ZVByZWRpY2F0ZXMoaW50IGNvbnRleHQsIFhQYXRoQ29udGV4dCB4Y3R4dCkKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpbnQgblByZWRpY2F0ZXMgPSBnZXRQcmVkaWNhdGVDb3VudCgpOwotICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiblByZWRpY2F0ZXM6ICIrblByZWRpY2F0ZXMpOwotICAgIGlmIChuUHJlZGljYXRlcyA9PSAwKQotICAgICAgcmV0dXJuIHRydWU7Ci0KLSAgICBQcmVmaXhSZXNvbHZlciBzYXZlZFJlc29sdmVyID0geGN0eHQuZ2V0TmFtZXNwYWNlQ29udGV4dCgpOwotCi0gICAgdHJ5Ci0gICAgewotICAgICAgbV9wcmVkaWNhdGVJbmRleCA9IDA7Ci0gICAgICB4Y3R4dC5wdXNoU3ViQ29udGV4dExpc3QodGhpcyk7Ci0gICAgICB4Y3R4dC5wdXNoTmFtZXNwYWNlQ29udGV4dChtX2xwaS5nZXRQcmVmaXhSZXNvbHZlcigpKTsKLSAgICAgIHhjdHh0LnB1c2hDdXJyZW50Tm9kZShjb250ZXh0KTsKLQotICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuUHJlZGljYXRlczsgaSsrKQotICAgICAgewotICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIkV4ZWN1dGluZyBwcmVkaWNhdGUgZXhwcmVzc2lvbiAtIHdhaXRpbmcgY291bnQ6ICIrbV9scGkuZ2V0V2FpdGluZ0NvdW50KCkpOwotICAgICAgICBYT2JqZWN0IHByZWQgPSBtX3ByZWRpY2F0ZXNbaV0uZXhlY3V0ZSh4Y3R4dCk7Ci0gICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiXG5CYWNrIGZyb20gZXhlY3V0aW5nIHByZWRpY2F0ZSBleHByZXNzaW9uIC0gd2FpdGluZyBjb3VudDogIittX2xwaS5nZXRXYWl0aW5nQ291bnQoKSk7Ci0gICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigicHJlZC5nZXRUeXBlKCk6ICIrcHJlZC5nZXRUeXBlKCkpOwotICAgICAgICBpZiAoWE9iamVjdC5DTEFTU19OVU1CRVIgPT0gcHJlZC5nZXRUeXBlKCkpCi0gICAgICAgIHsKLSAgICAgICAgICBpZiAoREVCVUdfUFJFRElDQVRFQ09VTlRJTkcpCi0gICAgICAgICAgewotICAgICAgICAgICAgU3lzdGVtLm91dC5mbHVzaCgpOwotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJcbj09PT09IHN0YXJ0IHByZWRpY2F0ZSBjb3VudCA9PT09PT09PSIpOwotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJtX3ByZWRpY2F0ZUluZGV4OiAiICsgbV9wcmVkaWNhdGVJbmRleCk7Ci0gICAgICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oImdldFByb3hpbWl0eVBvc2l0aW9uKG1fcHJlZGljYXRlSW5kZXgpOiAiCi0gICAgICAgICAgICAvLyAgICAgICAgICAgICAgICAgICArIGdldFByb3hpbWl0eVBvc2l0aW9uKG1fcHJlZGljYXRlSW5kZXgpKTsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigicHJlZC5udW0oKTogIiArIHByZWQubnVtKCkpOwotICAgICAgICAgIH0KLQotICAgICAgICAgIGludCBwcm94UG9zID0gdGhpcy5nZXRQcm94aW1pdHlQb3NpdGlvbihtX3ByZWRpY2F0ZUluZGV4KTsKLSAgICAgICAgICBpbnQgcHJlZEluZGV4ID0gKGludCkgcHJlZC5udW0oKTsKLSAgICAgICAgICBpZiAocHJveFBvcyAhPSBwcmVkSW5kZXgpCi0gICAgICAgICAgewotICAgICAgICAgICAgaWYgKERFQlVHX1BSRURJQ0FURUNPVU5USU5HKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlxubm9kZSBjb250ZXh0OiAiK25vZGVUb1N0cmluZyhjb250ZXh0KSk7Ci0gICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiaW5kZXggcHJlZGljYXRlIGlzIGZhbHNlOiAiK3Byb3hQb3MpOwotICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlxuPT09PT0gZW5kIHByZWRpY2F0ZSBjb3VudCA9PT09PT09PSIpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgIH0KLSAgICAgICAgICBlbHNlIGlmIChERUJVR19QUkVESUNBVEVDT1VOVElORykKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlxubm9kZSBjb250ZXh0OiAiK25vZGVUb1N0cmluZyhjb250ZXh0KSk7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oImluZGV4IHByZWRpY2F0ZSBpcyB0cnVlOiAiK3Byb3hQb3MpOwotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJcbj09PT09IGVuZCBwcmVkaWNhdGUgY291bnQgPT09PT09PT0iKTsKLSAgICAgICAgICB9Ci0KLSAgICAgICAgICAvLyBJZiB0aGVyZSBpcyBhIHByb3hpbWl0eSBpbmRleCB0aGF0IHdpbGwgbm90IGNoYW5nZSBkdXJpbmcgdGhlCi0gICAgICAgICAgLy8gY291cnNlIG9mIGl0dGVyYXRpb24sIHRoZW4gd2Uga25vdyB0aGVyZSBjYW4gYmUgbm8gbW9yZSB0cnVlCi0gICAgICAgICAgLy8gb2NjdXJhbmNlcyBvZiB0aGlzIHByZWRpY2F0ZSwgc28gZmxhZyB0aGF0IHdlJ3JlIGRvbmUgYWZ0ZXIKLSAgICAgICAgICAvLyB0aGlzLgotICAgICAgICAgIC8vCi0gICAgICAgICAgLy8gYnVnemlsbGEgMTQzNjUKLSAgICAgICAgICAvLyBXZSBjYW4ndCBzZXQgbV9mb3VuZExhc3QgPSB0cnVlIHVubGVzcyB3ZSdyZSBzdXJlIHRoYXQgLWFsbC0KLSAgICAgICAgICAvLyByZW1haW5pbmcgcGFyYW1ldGVycyBhcmUgc3RhYmxlLCBvciBlbHNlIGxhc3QoKSBmYWlscy4gRml4ZWQgc28KLSAgICAgICAgICAvLyBvbmx5IHNldHMgbV9mb3VuZExhc3QgaWYgb24gdGhlIGxhc3QgcHJlZGljYXRlCi0gICAgICAgICAgaWYobV9wcmVkaWNhdGVzW2ldLmlzU3RhYmxlTnVtYmVyKCkgJiYgaSA9PSBuUHJlZGljYXRlcyAtIDEpCi0gICAgICAgICAgewotICAgICAgICAgICAgbV9mb3VuZExhc3QgPSB0cnVlOwotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICghcHJlZC5ib29sKCkpCi0gICAgICAgICAgcmV0dXJuIGZhbHNlOwotCi0gICAgICAgIGNvdW50UHJveGltaXR5UG9zaXRpb24oKyttX3ByZWRpY2F0ZUluZGV4KTsKLSAgICAgIH0KLSAgICB9Ci0gICAgZmluYWxseQotICAgIHsKLSAgICAgIHhjdHh0LnBvcEN1cnJlbnROb2RlKCk7Ci0gICAgICB4Y3R4dC5wb3BOYW1lc3BhY2VDb250ZXh0KCk7Ci0gICAgICB4Y3R4dC5wb3BTdWJDb250ZXh0TGlzdCgpOwotICAgICAgbV9wcmVkaWNhdGVJbmRleCA9IC0xOwotICAgIH0KLQotICAgIHJldHVybiB0cnVlOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoaXMgZnVuY3Rpb24gaXMgdXNlZCB0byBmaXh1cCB2YXJpYWJsZXMgZnJvbSBRTmFtZXMgdG8gc3RhY2sgZnJhbWUKLSAgICogaW5kZXhlcyBhdCBzdHlsZXNoZWV0IGJ1aWxkIHRpbWUuCi0gICAqIEBwYXJhbSB2YXJzIExpc3Qgb2YgUU5hbWVzIHRoYXQgY29ycmVzcG9uZCB0byB2YXJpYWJsZXMuICBUaGlzIGxpc3QKLSAgICogc2hvdWxkIGJlIHNlYXJjaGVkIGJhY2t3YXJkcyBmb3IgdGhlIGZpcnN0IHF1YWxpZmllZCBuYW1lIHRoYXQKLSAgICogY29ycmVzcG9uZHMgdG8gdGhlIHZhcmlhYmxlIHJlZmVyZW5jZSBxbmFtZS4gIFRoZSBwb3NpdGlvbiBvZiB0aGUKLSAgICogUU5hbWUgaW4gdGhlIHZlY3RvciBmcm9tIHRoZSBzdGFydCBvZiB0aGUgdmVjdG9yIHdpbGwgYmUgaXRzIHBvc2l0aW9uCi0gICAqIGluIHRoZSBzdGFjayBmcmFtZSAoYnV0IHZhcmlhYmxlcyBhYm92ZSB0aGUgZ2xvYmFsc1RvcCB2YWx1ZSB3aWxsIG5lZWQKLSAgICogdG8gYmUgb2Zmc2V0IHRvIHRoZSBjdXJyZW50IHN0YWNrIGZyYW1lKS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGZpeHVwVmFyaWFibGVzKGphdmEudXRpbC5WZWN0b3IgdmFycywgaW50IGdsb2JhbHNTaXplKQotICB7Ci0gICAgc3VwZXIuZml4dXBWYXJpYWJsZXModmFycywgZ2xvYmFsc1NpemUpOwotCi0gICAgaW50IG5QcmVkaWNhdGVzID0gZ2V0UHJlZGljYXRlQ291bnQoKTsKLQotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgblByZWRpY2F0ZXM7IGkrKykKLSAgICB7Ci0gICAgICBtX3ByZWRpY2F0ZXNbaV0uZml4dXBWYXJpYWJsZXModmFycywgZ2xvYmFsc1NpemUpOwotICAgIH0KLSAgfQotCi0KLSAgLyoqCi0gICAqIERpYWdub3N0aWNzLgotICAgKgotICAgKiBAcGFyYW0gbiBOb2RlIHRvIGdpdmUgZGlhZ25vc3RpYyBpbmZvcm1hdGlvbiBhYm91dCwgb3IgbnVsbC4KLSAgICoKLSAgICogQHJldHVybiBJbmZvcm1hdGl2ZSBzdHJpbmcgYWJvdXQgdGhlIGFyZ3VtZW50LgotICAgKi8KLSAgcHJvdGVjdGVkIFN0cmluZyBub2RlVG9TdHJpbmcoaW50IG4pCi0gIHsKLSAgICBpZihEVE0uTlVMTCAhPSBuKQotICAgIHsKLSAgICAgIERUTSBkdG0gPSBtX2xwaS5nZXRYUGF0aENvbnRleHQoKS5nZXREVE0obik7Ci0gICAgICByZXR1cm4gZHRtLmdldE5vZGVOYW1lKG4pICsgInsiICsgKG4rMSkgKyAifSI7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICByZXR1cm4gIm51bGwiOwotICAgIH0KLSAgfQotCi0gIC8vPT09PT09PT09PT09PT09IE5vZGVGaWx0ZXIgSW1wbGVtZW50YXRpb24gPT09PT09PT09PT09PT09Ci0KLSAgLyoqCi0gICAqICBUZXN0IHdoZXRoZXIgYSBzcGVjaWZpZWQgbm9kZSBpcyB2aXNpYmxlIGluIHRoZSBsb2dpY2FsIHZpZXcgb2YgYQotICAgKiBUcmVlV2Fsa2VyIG9yIE5vZGVJdGVyYXRvci4gVGhpcyBmdW5jdGlvbiB3aWxsIGJlIGNhbGxlZCBieSB0aGUKLSAgICogaW1wbGVtZW50YXRpb24gb2YgVHJlZVdhbGtlciBhbmQgTm9kZUl0ZXJhdG9yOyBpdCBpcyBub3QgaW50ZW5kZWQgdG8KLSAgICogYmUgY2FsbGVkIGRpcmVjdGx5IGZyb20gdXNlciBjb2RlLgotICAgKiBAcGFyYW0gbiAgVGhlIG5vZGUgdG8gY2hlY2sgdG8gc2VlIGlmIGl0IHBhc3NlcyB0aGUgZmlsdGVyIG9yIG5vdC4KLSAgICogQHJldHVybiAgYSBjb25zdGFudCB0byBkZXRlcm1pbmUgd2hldGhlciB0aGUgbm9kZSBpcyBhY2NlcHRlZCwKLSAgICogICByZWplY3RlZCwgb3Igc2tpcHBlZCwgYXMgZGVmaW5lZCAgYWJvdmUgLgotICAgKi8KLSAgcHVibGljIHNob3J0IGFjY2VwdE5vZGUoaW50IG4pCi0gIHsKLQotICAgIFhQYXRoQ29udGV4dCB4Y3R4dCA9IG1fbHBpLmdldFhQYXRoQ29udGV4dCgpOwotCi0gICAgdHJ5Ci0gICAgewotICAgICAgeGN0eHQucHVzaEN1cnJlbnROb2RlKG4pOwotCi0gICAgICBYT2JqZWN0IHNjb3JlID0gZXhlY3V0ZSh4Y3R4dCwgbik7Ci0KLSAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiXG46OmFjY2VwdE5vZGUgLSBzY29yZTogIitzY29yZS5udW0oKSsiOjoiKTsKLSAgICAgIGlmIChzY29yZSAhPSBOb2RlVGVzdC5TQ09SRV9OT05FKQotICAgICAgewotICAgICAgICBpZiAoZ2V0UHJlZGljYXRlQ291bnQoKSA+IDApCi0gICAgICAgIHsKLSAgICAgICAgICBjb3VudFByb3hpbWl0eVBvc2l0aW9uKDApOwotCi0gICAgICAgICAgaWYgKCFleGVjdXRlUHJlZGljYXRlcyhuLCB4Y3R4dCkpCi0gICAgICAgICAgICByZXR1cm4gRFRNSXRlcmF0b3IuRklMVEVSX1NLSVA7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gRFRNSXRlcmF0b3IuRklMVEVSX0FDQ0VQVDsKLSAgICAgIH0KLSAgICB9Ci0gICAgY2F0Y2ggKGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24gc2UpCi0gICAgewotCi0gICAgICAvLyBUT0RPOiBGaXggdGhpcy4KLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKHNlLmdldE1lc3NhZ2UoKSk7Ci0gICAgfQotICAgIGZpbmFsbHkKLSAgICB7Ci0gICAgICB4Y3R4dC5wb3BDdXJyZW50Tm9kZSgpOwotICAgIH0KLQotICAgIHJldHVybiBEVE1JdGVyYXRvci5GSUxURVJfU0tJUDsKLSAgfQotCi0KLSAgLyoqCi0gICAqIEdldCB0aGUgb3duaW5nIGxvY2F0aW9uIHBhdGggaXRlcmF0b3IuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIG93bmluZyBsb2NhdGlvbiBwYXRoIGl0ZXJhdG9yLCB3aGljaCBzaG91bGQgbm90IGJlIG51bGwuCi0gICAqLwotICBwdWJsaWMgTG9jUGF0aEl0ZXJhdG9yIGdldExvY1BhdGhJdGVyYXRvcigpCi0gIHsKLSAgICByZXR1cm4gbV9scGk7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBsb2NhdGlvbiBwYXRoIGl0ZXJhdG9yIG93bmVyIGZvciB0aGlzIHdhbGtlci4gIEJlc2lkZXMKLSAgICogaW5pdGlhbGl6YXRpb24sIHRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGR1cmluZyBjbG9uaW5nIG9wZXJhdGlvbnMuCi0gICAqCi0gICAqIEBwYXJhbSBsaSBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIG93bmluZyBsb2NhdGlvbiBwYXRoIGl0ZXJhdG9yLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0TG9jUGF0aEl0ZXJhdG9yKExvY1BhdGhJdGVyYXRvciBsaSkKLSAgewotICAgIG1fbHBpID0gbGk7Ci0gICAgaWYodGhpcyAhPSBsaSkKLSAgICAgIGxpLmV4cHJTZXRQYXJlbnQodGhpcyk7Ci0gIH0KLQotICAvKioKLSAgICogVGVsbCBpZiB0aGlzIGV4cHJlc3Npb24gb3IgaXQncyBzdWJleHByZXNzaW9ucyBjYW4gdHJhdmVyc2Ugb3V0c2lkZQotICAgKiB0aGUgY3VycmVudCBzdWJ0cmVlLgotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYgdHJhdmVyc2FsIG91dHNpZGUgdGhlIGNvbnRleHQgbm9kZSdzIHN1YnRyZWUgY2FuIG9jY3VyLgotICAgKi8KLSAgIHB1YmxpYyBib29sZWFuIGNhblRyYXZlcnNlT3V0c2lkZVN1YnRyZWUoKQotICAgewotICAgIGludCBuID0gZ2V0UHJlZGljYXRlQ291bnQoKTsKLSAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykKLSAgICB7Ci0gICAgICBpZihnZXRQcmVkaWNhdGUoaSkuY2FuVHJhdmVyc2VPdXRzaWRlU3VidHJlZSgpKQotICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICB9Ci0gICAgcmV0dXJuIGZhbHNlOwotICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBUaGlzIHdpbGwgdHJhdmVyc2UgdGhlIGhlYXJhcmNoeSwgY2FsbGluZyB0aGUgdmlzaXRvciBmb3IKLSAgICAgICAgICogZWFjaCBtZW1iZXIuICBJZiB0aGUgY2FsbGVkIHZpc2l0b3IgbWV0aG9kIHJldHVybnMKLSAgICAgICAgICogZmFsc2UsIHRoZSBzdWJ0cmVlIHNob3VsZCBub3QgYmUgY2FsbGVkLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gdmlzaXRvciBUaGUgdmlzaXRvciB3aG9zZSBhcHByb3ByaWF0ZSBtZXRob2Qgd2lsbCBiZSBjYWxsZWQuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgdm9pZCBjYWxsUHJlZGljYXRlVmlzaXRvcnMoWFBhdGhWaXNpdG9yIHZpc2l0b3IpCi0gICAgICAgIHsKLSAgICAgICAgICBpZiAobnVsbCAhPSBtX3ByZWRpY2F0ZXMpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICBpbnQgbiA9IG1fcHJlZGljYXRlcy5sZW5ndGg7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykKLSAgICAgICAgICAgICAgewotICAgICAgICAgICAgICBFeHByZXNzaW9uT3duZXIgcHJlZE93bmVyID0gbmV3IFByZWRPd25lcihpKTsKLSAgICAgICAgICAgICAgaWYgKHZpc2l0b3IudmlzaXRQcmVkaWNhdGUocHJlZE93bmVyLCBtX3ByZWRpY2F0ZXNbaV0pKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBtX3ByZWRpY2F0ZXNbaV0uY2FsbFZpc2l0b3JzKHByZWRPd25lciwgdmlzaXRvcik7Ci0gICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgfQotICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBFeHByZXNzaW9uI2RlZXBFcXVhbHMoRXhwcmVzc2lvbikKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBkZWVwRXF1YWxzKEV4cHJlc3Npb24gZXhwcikKLSAgICB7Ci0gICAgICBpZiAoIXN1cGVyLmRlZXBFcXVhbHMoZXhwcikpCi0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0KLSAgICAgIFByZWRpY2F0ZWROb2RlVGVzdCBwbnQgPSAoUHJlZGljYXRlZE5vZGVUZXN0KSBleHByOwotICAgICAgaWYgKG51bGwgIT0gbV9wcmVkaWNhdGVzKQotICAgICAgewotCi0gICAgICAgIGludCBuID0gbV9wcmVkaWNhdGVzLmxlbmd0aDsKLSAgICAgICAgaWYgKChudWxsID09IHBudC5tX3ByZWRpY2F0ZXMpIHx8IChwbnQubV9wcmVkaWNhdGVzLmxlbmd0aCAhPSBuKSkKLSAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykKLSAgICAgICAgewotICAgICAgICAgIGlmICghbV9wcmVkaWNhdGVzW2ldLmRlZXBFcXVhbHMocG50Lm1fcHJlZGljYXRlc1tpXSkpCi0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmIChudWxsICE9IHBudC5tX3ByZWRpY2F0ZXMpCi0gICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLQotICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotCi0gIC8qKiBUaGlzIGlzIHRydWUgaWYgbmV4dE5vZGUgcmV0dXJucyBudWxsLiAqLwotICB0cmFuc2llbnQgcHJvdGVjdGVkIGJvb2xlYW4gbV9mb3VuZExhc3QgPSBmYWxzZTsKLQotICAvKiogVGhlIG93bmluZyBsb2NhdGlvbiBwYXRoIGl0ZXJhdG9yLgotICAgKiAgQHNlcmlhbCAqLwotICBwcm90ZWN0ZWQgTG9jUGF0aEl0ZXJhdG9yIG1fbHBpOwotCi0gIC8qKgotICAgKiBXaGljaCBwcmVkaWNhdGUgd2UgYXJlIGV4ZWN1dGluZy4KLSAgICovCi0gIHRyYW5zaWVudCBpbnQgbV9wcmVkaWNhdGVJbmRleCA9IC0xOwotCi0gIC8qKiBUaGUgbGlzdCBvZiBwcmVkaWNhdGUgZXhwcmVzc2lvbnMuIElzIHN0YXRpYyBhbmQgZG9lcyBub3QgbmVlZAotICAgKiAgdG8gYmUgZGVlcCBjbG9uZWQuCi0gICAqICBAc2VyaWFsCi0gICAqLwotICBwcml2YXRlIEV4cHJlc3Npb25bXSBtX3ByZWRpY2F0ZXM7Ci0KLSAgLyoqCi0gICAqIEFuIGFycmF5IG9mIGNvdW50cyB0aGF0IGNvcnJlc3BvbmQgdG8gdGhlIG51bWJlcgotICAgKiBvZiBwcmVkaWNhdGVzIHRoZSBzdGVwIGNvbnRhaW5zLgotICAgKi8KLSAgdHJhbnNpZW50IHByb3RlY3RlZCBpbnRbXSBtX3Byb3hpbWl0eVBvc2l0aW9uczsKLQotICAvKiogSWYgdHJ1ZSwgZGlhZ25vc3RpYyBtZXNzYWdlcyBhYm91dCBwcmVkaWNhdGUgZXhlY3V0aW9uIHdpbGwgYmUgcG9zdGVkLiAgKi8KLSAgc3RhdGljIGZpbmFsIGJvb2xlYW4gREVCVUdfUFJFRElDQVRFQ09VTlRJTkcgPSBmYWxzZTsKLQotICBjbGFzcyBQcmVkT3duZXIgaW1wbGVtZW50cyBFeHByZXNzaW9uT3duZXIKLSAgewotICAgICAgICBpbnQgbV9pbmRleDsKLQotICAgICAgICBQcmVkT3duZXIoaW50IGluZGV4KQotICAgICAgICB7Ci0gICAgICAgICAgICAgICAgbV9pbmRleCA9IGluZGV4OwotICAgICAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAc2VlIEV4cHJlc3Npb25Pd25lciNnZXRFeHByZXNzaW9uKCkKLSAgICAgKi8KLSAgICBwdWJsaWMgRXhwcmVzc2lvbiBnZXRFeHByZXNzaW9uKCkKLSAgICB7Ci0gICAgICByZXR1cm4gbV9wcmVkaWNhdGVzW21faW5kZXhdOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogQHNlZSBFeHByZXNzaW9uT3duZXIjc2V0RXhwcmVzc2lvbihFeHByZXNzaW9uKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEV4cHJlc3Npb24oRXhwcmVzc2lvbiBleHApCi0gICAgewotICAgICAgICBleHAuZXhwclNldFBhcmVudChQcmVkaWNhdGVkTm9kZVRlc3QudGhpcyk7Ci0gICAgICAgIG1fcHJlZGljYXRlc1ttX2luZGV4XSA9IGV4cDsKLSAgICB9Ci0gIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9heGVzL1JURkl0ZXJhdG9yLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2F4ZXMvUlRGSXRlcmF0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMWYwMjA2NC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2F4ZXMvUlRGSXRlcmF0b3IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQ0ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFJURkl0ZXJhdG9yLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTQgMTk6NDU6MTYgamVmZnN1dHRvciBFeHAgJAotICovCi0KLS8qKgotICogVGhpcyBjbGFzcyBpbXBsZW1lbnRzIGFuIFJURiBJdGVyYXRvci4gQ3VycmVudGx5IGV4aXN0cyBmb3Igc29sZQotICogcHVycG9zZSBvZiBlbmFibGluZyBFWFNMVCBvYmplY3QtdHlwZSBmdW5jdGlvbiB0byByZXR1cm4gIlJURiIuCi0gKgotICAqIEB4c2wudXNhZ2UgYWR2YW5jZWQKLSAgKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmF4ZXM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1NYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5Ob2RlU2V0RFRNOwotCi1wdWJsaWMgY2xhc3MgUlRGSXRlcmF0b3IgZXh0ZW5kcyBOb2RlU2V0RFRNIHsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNzY1ODExNzM2NjI1ODUyODk5Nkw7Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIENvbnN0cnVjdG9yIGZvciBSVEZJdGVyYXRvcgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIFJURkl0ZXJhdG9yKGludCByb290LCBEVE1NYW5hZ2VyIG1hbmFnZXIpIHsKLSAgICAgICAgICAgICAgICBzdXBlcihyb290LCBtYW5hZ2VyKTsKLSAgICAgICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9heGVzL1JldmVyc2VBeGVzV2Fsa2VyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2F4ZXMvUmV2ZXJzZUF4ZXNXYWxrZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNDE5ZDZlZi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2F4ZXMvUmV2ZXJzZUF4ZXNXYWxrZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI0OSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBSZXZlcnNlQXhlc1dhbGtlci5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE0IDE5OjQ1OjIxIGplZmZzdXR0b3IgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuYXhlczsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1BeGlzSXRlcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoQ29udGV4dDsKLQotLyoqCi0gKiBXYWxrZXIgZm9yIGEgcmV2ZXJzZSBheGVzLgotICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aCNwcmVkaWNhdGVzIj5YUGF0aCAyLjQgUHJlZGljYXRlczwvYT4KLSAqLwotcHVibGljIGNsYXNzIFJldmVyc2VBeGVzV2Fsa2VyIGV4dGVuZHMgQXhlc1dhbGtlcgotewotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAyODQ3MDA3NjQ3ODMyNzY4OTQxTDsKLQotICAvKioKLSAgICogQ29uc3RydWN0IGFuIEF4ZXNXYWxrZXIgdXNpbmcgYSBMb2NQYXRoSXRlcmF0b3IuCi0gICAqCi0gICAqIEBwYXJhbSBsb2NQYXRoSXRlcmF0b3IgVGhlIGxvY2F0aW9uIHBhdGggaXRlcmF0b3IgdGhhdCAnb3ducycgdGhpcyB3YWxrZXIuCi0gICAqLwotICBSZXZlcnNlQXhlc1dhbGtlcihMb2NQYXRoSXRlcmF0b3IgbG9jUGF0aEl0ZXJhdG9yLCBpbnQgYXhpcykKLSAgewotICAgIHN1cGVyKGxvY1BhdGhJdGVyYXRvciwgYXhpcyk7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSByb290IG5vZGUgb2YgdGhlIFRyZWVXYWxrZXIuCi0gICAqIChOb3QgcGFydCBvZiB0aGUgRE9NMiBUcmVlV2Fsa2VyIGludGVyZmFjZSkuCi0gICAqCi0gICAqIEBwYXJhbSByb290IFRoZSBjb250ZXh0IG5vZGUgb2YgdGhpcyBzdGVwLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0Um9vdChpbnQgcm9vdCkKLSAgewotICAgIHN1cGVyLnNldFJvb3Qocm9vdCk7Ci0gICAgbV9pdGVyYXRvciA9IGdldERUTShyb290KS5nZXRBeGlzSXRlcmF0b3IobV9heGlzKTsKLSAgICBtX2l0ZXJhdG9yLnNldFN0YXJ0Tm9kZShyb290KTsKLSAgfQotCi0gIC8qKgotICAgKiBEZXRhY2hlcyB0aGUgd2Fsa2VyIGZyb20gdGhlIHNldCB3aGljaCBpdCBpdGVyYXRlZCBvdmVyLCByZWxlYXNpbmcKLSAgICogYW55IGNvbXB1dGF0aW9uYWwgcmVzb3VyY2VzIGFuZCBwbGFjaW5nIHRoZSBpdGVyYXRvciBpbiB0aGUgSU5WQUxJRAotICAgKiBzdGF0ZS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGRldGFjaCgpCi0gIHsKLSAgICBtX2l0ZXJhdG9yID0gbnVsbDsKLSAgICBzdXBlci5kZXRhY2goKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIG5leHQgbm9kZSBpbiBkb2N1bWVudCBvcmRlciBvbiB0aGUgYXhlcy4KLSAgICoKLSAgICogQHJldHVybiB0aGUgbmV4dCBub2RlIGluIGRvY3VtZW50IG9yZGVyIG9uIHRoZSBheGVzLCBvciBudWxsLgotICAgKi8KLSAgcHJvdGVjdGVkIGludCBnZXROZXh0Tm9kZSgpCi0gIHsKLSAgICBpZiAobV9mb3VuZExhc3QpCi0gICAgICByZXR1cm4gRFRNLk5VTEw7Ci0KLSAgICBpbnQgbmV4dCA9IG1faXRlcmF0b3IubmV4dCgpOwotCi0gICAgaWYgKG1faXNGcmVzaCkKLSAgICAgIG1faXNGcmVzaCA9IGZhbHNlOwotCi0gICAgaWYgKERUTS5OVUxMID09IG5leHQpCi0gICAgICB0aGlzLm1fZm91bmRMYXN0ID0gdHJ1ZTsKLQotICAgIHJldHVybiBuZXh0OwotICB9Ci0KLQotICAvKioKLSAgICogVGVsbHMgaWYgdGhpcyBpcyBhIHJldmVyc2UgYXhlcy4gIE92ZXJyaWRlcyBBeGVzV2Fsa2VyI2lzUmV2ZXJzZUF4ZXMuCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBmb3IgdGhpcyBjbGFzcy4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzUmV2ZXJzZUF4ZXMoKQotICB7Ci0gICAgcmV0dXJuIHRydWU7Ci0gIH0KLQotLy8gIC8qKgotLy8gICAqICBTZXQgdGhlIHJvb3Qgbm9kZSBvZiB0aGUgVHJlZVdhbGtlci4KLS8vICAgKgotLy8gICAqIEBwYXJhbSByb290IFRoZSBjb250ZXh0IG5vZGUgb2YgdGhpcyBzdGVwLgotLy8gICAqLwotLy8gIHB1YmxpYyB2b2lkIHNldFJvb3QoaW50IHJvb3QpCi0vLyAgewotLy8gICAgc3VwZXIuc2V0Um9vdChyb290KTsKLS8vICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgY3VycmVudCBzdWItY29udGV4dCBwb3NpdGlvbi4gIEluIG9yZGVyIHRvIGRvIHRoZQotICAgKiByZXZlcnNlIGF4ZXMgY291bnQsIGZvciB0aGUgbW9tZW50IHRoaXMgcmUtc2VhcmNoZXMgdGhlIGF4ZXMKLSAgICogdXAgdG8gdGhlIHByZWRpY2F0ZS4gIEFuIG9wdGltaXphdGlvbiBvbiB0aGlzIGlzIHRvIGNhY2hlCi0gICAqIHRoZSBub2RlcyBzZWFyY2hlZCwgYnV0LCBmb3IgdGhlIG1vbWVudCwgdGhpcyBjYXNlIGlzIHByb2JhYmx5Ci0gICAqIHJhcmUgZW5vdWdoIHRoYXQgdGhlIGFkZGVkIGNvbXBsZXhpdHkgaXNuJ3Qgd29ydGggaXQuCi0gICAqCi0gICAqIEBwYXJhbSBwcmVkaWNhdGVJbmRleCBUaGUgcHJlZGljYXRlIGluZGV4IG9mIHRoZSBwcm94aW1pdHkgcG9zaXRpb24uCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHByaWRpY2F0ZSBpbmRleCwgb3IgLTEuCi0gICAqLwotICBwcm90ZWN0ZWQgaW50IGdldFByb3hpbWl0eVBvc2l0aW9uKGludCBwcmVkaWNhdGVJbmRleCkKLSAgewotICAgIC8vIEEgbmVnYXRpdmUgcHJlZGljYXRlIGluZGV4IHNlZW1zIHRvIG9jY3VyIHdpdGgKLSAgICAvLyAocHJlY2VkaW5nLXNpYmxpbmc6Oip8Zm9sbG93aW5nLXNpYmxpbmc6OiopL2FuY2VzdG9yOjoqW3Bvc2l0aW9uKCldLypbcG9zaXRpb24oKV0KLSAgICAvLyAtc2IKLSAgICBpZihwcmVkaWNhdGVJbmRleCA8IDApCi0gICAgICByZXR1cm4gLTE7Ci0KLSAgICBpbnQgY291bnQgPSBtX3Byb3hpbWl0eVBvc2l0aW9uc1twcmVkaWNhdGVJbmRleF07Ci0KLSAgICBpZiAoY291bnQgPD0gMCkKLSAgICB7Ci0gICAgICBBeGVzV2Fsa2VyIHNhdmVkV2Fsa2VyID0gd2koKS5nZXRMYXN0VXNlZFdhbGtlcigpOwotCi0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgUmV2ZXJzZUF4ZXNXYWxrZXIgY2xvbmUgPSAoUmV2ZXJzZUF4ZXNXYWxrZXIpIHRoaXMuY2xvbmUoKTsKLQotICAgICAgICBjbG9uZS5zZXRSb290KHRoaXMuZ2V0Um9vdCgpKTsKLQotICAgICAgICBjbG9uZS5zZXRQcmVkaWNhdGVDb3VudChwcmVkaWNhdGVJbmRleCk7Ci0KLSAgICAgICAgY2xvbmUuc2V0UHJldldhbGtlcihudWxsKTsKLSAgICAgICAgY2xvbmUuc2V0TmV4dFdhbGtlcihudWxsKTsKLSAgICAgICAgd2koKS5zZXRMYXN0VXNlZFdhbGtlcihjbG9uZSk7Ci0KLSAgICAgICAgLy8gQ291bnQgJ2VtIGFsbAotICAgICAgICBjb3VudCsrOwotICAgICAgICBpbnQgbmV4dDsKLQotICAgICAgICB3aGlsZSAoRFRNLk5VTEwgIT0gKG5leHQgPSBjbG9uZS5uZXh0Tm9kZSgpKSkKLSAgICAgICAgewotICAgICAgICAgIGNvdW50Kys7Ci0gICAgICAgIH0KLQotICAgICAgICBtX3Byb3hpbWl0eVBvc2l0aW9uc1twcmVkaWNhdGVJbmRleF0gPSBjb3VudDsKLSAgICAgIH0KLSAgICAgIGNhdGNoIChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBjbnNlKQotICAgICAgewotCi0gICAgICAgIC8vIGNhbid0IGhhcHBlbgotICAgICAgfQotICAgICAgZmluYWxseQotICAgICAgewotICAgICAgICB3aSgpLnNldExhc3RVc2VkV2Fsa2VyKHNhdmVkV2Fsa2VyKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gY291bnQ7Ci0gIH0KLQotICAvKioKLSAgICogQ291bnQgYmFja3dhcmRzIG9uZSBwcm94aW1pdHkgcG9zaXRpb24uCi0gICAqCi0gICAqIEBwYXJhbSBpIFRoZSBwcmVkaWNhdGUgaW5kZXguCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBjb3VudFByb3hpbWl0eVBvc2l0aW9uKGludCBpKQotICB7Ci0gICAgaWYgKGkgPCBtX3Byb3hpbWl0eVBvc2l0aW9ucy5sZW5ndGgpCi0gICAgICBtX3Byb3hpbWl0eVBvc2l0aW9uc1tpXS0tOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbnVtYmVyIG9mIG5vZGVzIGluIHRoaXMgbm9kZSBsaXN0LiAgVGhlIGZ1bmN0aW9uIGlzIHByb2JhYmx5IGlsbAotICAgKiBuYW1lZD8KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IFRoZSBYUGF0aCBydW50aW1lIGNvbnRleHQuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBub2RlcyBpbiB0aGlzIG5vZGUgbGlzdC4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0TGFzdFBvcyhYUGF0aENvbnRleHQgeGN0eHQpCi0gIHsKLQotICAgIGludCBjb3VudCA9IDA7Ci0gICAgQXhlc1dhbGtlciBzYXZlZFdhbGtlciA9IHdpKCkuZ2V0TGFzdFVzZWRXYWxrZXIoKTsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIFJldmVyc2VBeGVzV2Fsa2VyIGNsb25lID0gKFJldmVyc2VBeGVzV2Fsa2VyKSB0aGlzLmNsb25lKCk7Ci0KLSAgICAgIGNsb25lLnNldFJvb3QodGhpcy5nZXRSb290KCkpOwotCi0gICAgICBjbG9uZS5zZXRQcmVkaWNhdGVDb3VudCh0aGlzLmdldFByZWRpY2F0ZUNvdW50KCkgLSAxKTsKLQotICAgICAgY2xvbmUuc2V0UHJldldhbGtlcihudWxsKTsKLSAgICAgIGNsb25lLnNldE5leHRXYWxrZXIobnVsbCk7Ci0gICAgICB3aSgpLnNldExhc3RVc2VkV2Fsa2VyKGNsb25lKTsKLQotICAgICAgLy8gQ291bnQgJ2VtIGFsbAotICAgICAgLy8gY291bnQgPSAxOwotICAgICAgaW50IG5leHQ7Ci0KLSAgICAgIHdoaWxlIChEVE0uTlVMTCAhPSAobmV4dCA9IGNsb25lLm5leHROb2RlKCkpKQotICAgICAgewotICAgICAgICBjb3VudCsrOwotICAgICAgfQotICAgIH0KLSAgICBjYXRjaCAoQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gY25zZSkKLSAgICB7Ci0KLSAgICAgIC8vIGNhbid0IGhhcHBlbgotICAgIH0KLSAgICBmaW5hbGx5Ci0gICAgewotICAgICAgd2koKS5zZXRMYXN0VXNlZFdhbGtlcihzYXZlZFdhbGtlcik7Ci0gICAgfQotCi0gICAgcmV0dXJuIGNvdW50OwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdHJ1ZSBpZiBhbGwgdGhlIG5vZGVzIGluIHRoZSBpdGVyYXRpb24gd2VsbCBiZSByZXR1cm5lZCBpbiBkb2N1bWVudAotICAgKiBvcmRlci4KLSAgICogV2FybmluZzogVGhpcyBjYW4gb25seSBiZSBjYWxsZWQgYWZ0ZXIgc2V0Um9vdCBoYXMgYmVlbiBjYWxsZWQhCi0gICAqCi0gICAqIEByZXR1cm4gZmFsc2UuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBpc0RvY09yZGVyZWQoKQotICB7Ci0gICAgcmV0dXJuIGZhbHNlOyAgLy8gSSB0aGluay4KLSAgfQotCi0gIC8qKiBUaGUgRFRNIGlubmVyIHRyYXZlcnNhbCBjbGFzcywgdGhhdCBjb3JyZXNwb25kcyB0byB0aGUgc3VwZXIgYXhpcy4gKi8KLSAgcHJvdGVjdGVkIERUTUF4aXNJdGVyYXRvciBtX2l0ZXJhdG9yOwotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9heGVzL1NlbGZJdGVyYXRvck5vUHJlZGljYXRlLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2F4ZXMvU2VsZkl0ZXJhdG9yTm9QcmVkaWNhdGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZjE1YzY5Zi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2F4ZXMvU2VsZkl0ZXJhdG9yTm9QcmVkaWNhdGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEzMCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBTZWxmSXRlcmF0b3JOb1ByZWRpY2F0ZS5qYXZhLHYgMS4yLjQuMiAyMDA1LzA5LzE0IDE5OjQ1OjIxIGplZmZzdXR0b3IgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuYXhlczsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuWFBhdGhDb250ZXh0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5jb21waWxlci5Db21waWxlcjsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGltcGxlbWVudHMgYW4gb3B0aW1pemVkIGl0ZXJhdG9yIGZvcgotICogIi4iIHBhdHRlcm5zLCB0aGF0IGlzLCB0aGUgc2VsZiBheGVzIHdpdGhvdXQgYW55IHByZWRpY2F0ZXMuCi0gKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5heGVzLkxvY1BhdGhJdGVyYXRvcgotICogQHhzbC51c2FnZSBhZHZhbmNlZAotICovCi1wdWJsaWMgY2xhc3MgU2VsZkl0ZXJhdG9yTm9QcmVkaWNhdGUgZXh0ZW5kcyBMb2NQYXRoSXRlcmF0b3IKLXsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTQyMjY4ODc5MDUyNzk4MTQyMDFMOwotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBTZWxmSXRlcmF0b3JOb1ByZWRpY2F0ZSBvYmplY3QuCi0gICAqCi0gICAqIEBwYXJhbSBjb21waWxlciBBIHJlZmVyZW5jZSB0byB0aGUgQ29tcGlsZXIgdGhhdCBjb250YWlucyB0aGUgb3AgbWFwLgotICAgKiBAcGFyYW0gb3BQb3MgVGhlIHBvc2l0aW9uIHdpdGhpbiB0aGUgb3AgbWFwLCB3aGljaCBjb250YWlucyB0aGUKLSAgICogbG9jYXRpb24gcGF0aCBleHByZXNzaW9uIGZvciB0aGlzIGl0dGVyYXRvci4KLSAgICogQHBhcmFtIGFuYWx5c2lzIEFuYWx5c2lzIGJpdHMuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgU2VsZkl0ZXJhdG9yTm9QcmVkaWNhdGUoQ29tcGlsZXIgY29tcGlsZXIsIGludCBvcFBvcywgaW50IGFuYWx5c2lzKQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICBzdXBlcihjb21waWxlciwgb3BQb3MsIGFuYWx5c2lzLCBmYWxzZSk7Ci0gIH0KLQotICAvKioKLSAgICogQ3JlYXRlIGEgU2VsZkl0ZXJhdG9yTm9QcmVkaWNhdGUgb2JqZWN0LgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBTZWxmSXRlcmF0b3JOb1ByZWRpY2F0ZSgpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHN1cGVyKG51bGwpOwotICB9Ci0KLQotICAvKioKLSAgICogIFJldHVybnMgdGhlIG5leHQgbm9kZSBpbiB0aGUgc2V0IGFuZCBhZHZhbmNlcyB0aGUgcG9zaXRpb24gb2YgdGhlCi0gICAqIGl0ZXJhdG9yIGluIHRoZSBzZXQuIEFmdGVyIGEgTm9kZUl0ZXJhdG9yIGlzIGNyZWF0ZWQsIHRoZSBmaXJzdCBjYWxsCi0gICAqIHRvIG5leHROb2RlKCkgcmV0dXJucyB0aGUgZmlyc3Qgbm9kZSBpbiB0aGUgc2V0LgotICAgKgotICAgKiBAcmV0dXJuICBUaGUgbmV4dCA8Y29kZT5Ob2RlPC9jb2RlPiBpbiB0aGUgc2V0IGJlaW5nIGl0ZXJhdGVkIG92ZXIsIG9yCi0gICAqICAgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlcmUgYXJlIG5vIG1vcmUgbWVtYmVycyBpbiB0aGF0IHNldC4KLSAgICovCi0gIHB1YmxpYyBpbnQgbmV4dE5vZGUoKQotICB7Ci0gICAgaWYgKG1fZm91bmRMYXN0KQotICAgICAgcmV0dXJuIERUTS5OVUxMOwotCi0gICAgaW50IG5leHQ7Ci0gICAgRFRNIGR0bSA9IG1fY2R0bTsKLQotICAgIG1fbGFzdEZldGNoZWQgPSBuZXh0ID0gKERUTS5OVUxMID09IG1fbGFzdEZldGNoZWQpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICA/IG1fY29udGV4dAotICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBEVE0uTlVMTDsKLQotICAgIC8vIG1fbGFzdEZldGNoZWQgPSBuZXh0OwotICAgIGlmIChEVE0uTlVMTCAhPSBuZXh0KQotICAgIHsKLSAgICAgIG1fcG9zKys7Ci0KLSAgICAgIHJldHVybiBuZXh0OwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgbV9mb3VuZExhc3QgPSB0cnVlOwotCi0gICAgICByZXR1cm4gRFRNLk5VTEw7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgZmlyc3Qgbm9kZSBvdXQgb2YgdGhlIG5vZGVzZXQsIGlmIHRoaXMgZXhwcmVzc2lvbiBpcwotICAgKiBhIG5vZGVzZXQgZXhwcmVzc2lvbi4gIFRoaXMgaXMgdGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gZm9yCi0gICAqIG5vZGVzZXRzLiAgRGVyaXZlZCBjbGFzc2VzIHNob3VsZCB0cnkgYW5kIG92ZXJyaWRlIHRoaXMgYW5kIHJldHVybiBhCi0gICAqIHZhbHVlIHdpdGhvdXQgaGF2aW5nIHRvIGRvIGEgY2xvbmUgb3BlcmF0aW9uLgotICAgKiBAcGFyYW0geGN0eHQgVGhlIFhQYXRoIHJ1bnRpbWUgY29udGV4dC4KLSAgICogQHJldHVybiB0aGUgZmlyc3Qgbm9kZSBvdXQgb2YgdGhlIG5vZGVzZXQsIG9yIERUTS5OVUxMLgotICAgKi8KLSAgcHVibGljIGludCBhc05vZGUoWFBhdGhDb250ZXh0IHhjdHh0KQotICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4geGN0eHQuZ2V0Q3VycmVudE5vZGUoKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGluZGV4IG9mIHRoZSBsYXN0IG5vZGUgdGhhdCBjYW4gYmUgaXR0ZXJhdGVkIHRvLgotICAgKiBUaGlzIHByb2JhYmx5IHdpbGwgbmVlZCB0byBiZSBvdmVycmlkZGVkIGJ5IGRlcml2ZWQgY2xhc3Nlcy4KLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IFhQYXRoIHJ1bnRpbWUgY29udGV4dC4KLSAgICoKLSAgICogQHJldHVybiB0aGUgaW5kZXggb2YgdGhlIGxhc3Qgbm9kZSB0aGF0IGNhbiBiZSBpdHRlcmF0ZWQgdG8uCi0gICAqLwotICBwdWJsaWMgaW50IGdldExhc3RQb3MoWFBhdGhDb250ZXh0IHhjdHh0KQotICB7Ci0gICAgcmV0dXJuIDE7Ci0gIH0KLQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2F4ZXMvU3ViQ29udGV4dExpc3QuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvYXhlcy9TdWJDb250ZXh0TGlzdC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlMTY5NzQzLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvYXhlcy9TdWJDb250ZXh0TGlzdC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTQgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogU3ViQ29udGV4dExpc3QuamF2YSx2IDEuMS4yLjEgMjAwNS8wOC8wMSAwMTozMDoyOCBqZWZmc3V0dG9yIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmF4ZXM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuWFBhdGhDb250ZXh0OwotCi0vKioKLSAqIEEgY2xhc3MgdGhhdCBpbXBsZW1lbnRzIHRoaXMgaW50ZXJmYWNlIGlzIGEgc3ViIGNvbnRleHQgbm9kZSBsaXN0LCBtZWFuaW5nIGl0Ci0gKiBpcyBhIG5vZGUgbGlzdCBmb3IgYSBsb2NhdGlvbiBwYXRoIHN0ZXAgZm9yIGEgcHJlZGljYXRlLgotICogQHhzbC51c2FnZSBhZHZhbmNlZAotICovCi1wdWJsaWMgaW50ZXJmYWNlIFN1YkNvbnRleHRMaXN0Ci17Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbnVtYmVyIG9mIG5vZGVzIGluIHRoZSBub2RlIGxpc3QsIHdoaWNoLCBpbiB0aGUgWFNMVCAxIGJhc2VkCi0gICAqIGNvdW50aW5nIHN5c3RlbSwgaXMgdGhlIGxhc3QgaW5kZXggcG9zaXRpb24uCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgWFBhdGggcnVudGltZSBjb250ZXh0LgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2Ygbm9kZXMgaW4gdGhlIG5vZGUgbGlzdC4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0TGFzdFBvcyhYUGF0aENvbnRleHQgeGN0eHQpOwotCi0gIC8qKgotICAgKiBHZXQgdGhlIGN1cnJlbnQgc3ViLWNvbnRleHQgcG9zaXRpb24uCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgWFBhdGggcnVudGltZSBjb250ZXh0LgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBwb3NpdGlvbiBvZiB0aGUgY3VycmVudCBub2RlIGluIHRoZSBsaXN0LgotICAgKi8KLSAgcHVibGljIGludCBnZXRQcm94aW1pdHlQb3NpdGlvbihYUGF0aENvbnRleHQgeGN0eHQpOwotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9heGVzL1VuaW9uQ2hpbGRJdGVyYXRvci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9heGVzL1VuaW9uQ2hpbGRJdGVyYXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA5YWZjMmNmLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvYXhlcy9VbmlvbkNoaWxkSXRlcmF0b3IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE1MiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBVbmlvbkNoaWxkSXRlcmF0b3IuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNCAxOTo0NToyMCBqZWZmc3V0dG9yIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmF4ZXM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1JdGVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuWFBhdGhDb250ZXh0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhPYmplY3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLnBhdHRlcm5zLk5vZGVUZXN0OwotCi0vKioKLSAqIFRoaXMgY2xhc3MgZGVmaW5lcyBhIHNpbXBsaWZpZWQgdHlwZSBvZiB1bmlvbiBpdGVyYXRvciB0aGF0IG9ubHkKLSAqIHRlc3RzIGFsb25nIHRoZSBjaGlsZCBheGVzLiAgSWYgdGhlIGNvbmRpdGlvbnMgYXJlIHJpZ2h0LCBpdCBpcwotICogbXVjaCBmYXN0ZXIgdGhhbiB1c2luZyBhIFVuaW9uUGF0aEl0ZXJhdG9yLgotICovCi1wdWJsaWMgY2xhc3MgVW5pb25DaGlsZEl0ZXJhdG9yIGV4dGVuZHMgQ2hpbGRUZXN0SXRlcmF0b3IKLXsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMzUwMDI5ODQ4MjE5MzAwMzQ5NUw7Ci0gIC8qKgotICAgKiBFdmVuIHRob3VnaCB0aGVzZSBtYXkgaG9sZCBmdWxsIExvY1BhdGhJdGVyYXRvcnMsIHRoaXMgYXJyYXkgZG9lcwotICAgKiBub3QgaGF2ZSB0byBiZSBjbG9uZWQsIHNpbmNlIG9ubHkgdGhlIG5vZGUgdGVzdCBhbmQgcHJlZGljYXRlCi0gICAqIHBvcnRpb24gYXJlIHVzZWQsIGFuZCB0aGVzZSBvbmx5IG5lZWQgc3RhdGljIGluZm9ybWF0aW9uLiAgSG93ZXZlciwKLSAgICogYWxzbyBub3RlIHRoYXQgaW5kZXggcHJlZGljYXRlcyBjYW4gbm90IGJlIHVzZWQhCi0gICAqLwotICBwcml2YXRlIFByZWRpY2F0ZWROb2RlVGVzdFtdIG1fbm9kZVRlc3RzID0gbnVsbDsKLQotICAvKioKLSAgICogQ29uc3RydWN0b3IgZm9yIFVuaW9uQ2hpbGRJdGVyYXRvcgotICAgKi8KLSAgcHVibGljIFVuaW9uQ2hpbGRJdGVyYXRvcigpCi0gIHsKLSAgICBzdXBlcihudWxsKTsKLSAgfQotCi0gIC8qKgotICAgKiBBZGQgYSBub2RlIHRlc3QgdG8gdGhlIHVuaW9uIGxpc3QuCi0gICAqCi0gICAqIEBwYXJhbSB0ZXN0IHJlZmVyZW5jZSB0byBhIE5vZGVUZXN0LCB3aGljaCB3aWxsIGJlIGFkZGVkCi0gICAqIGRpcmVjdGx5IHRvIHRoZSBsaXN0IG9mIG5vZGUgdGVzdHMgKGluIG90aGVyIHdvcmRzLCBpdCB3aWxsCi0gICAqIG5vdCBiZSBjbG9uZWQpLiAgVGhlIHBhcmVudCBvZiB0aGlzIHRlc3Qgd2lsbCBiZSBzZXQgdG8KLSAgICogdGhpcyBvYmplY3QuCi0gICAqLwotICBwdWJsaWMgdm9pZCBhZGROb2RlVGVzdChQcmVkaWNhdGVkTm9kZVRlc3QgdGVzdCkKLSAgewotCi0gICAgLy8gSW5jcmVhc2UgYXJyYXkgc2l6ZSBieSBvbmx5IDEgYXQgYSB0aW1lLiAgRml4IHRoaXMKLSAgICAvLyBpZiBpdCBsb29rcyB0byBiZSBhIHByb2JsZW0uCi0gICAgaWYgKG51bGwgPT0gbV9ub2RlVGVzdHMpCi0gICAgewotICAgICAgbV9ub2RlVGVzdHMgPSBuZXcgUHJlZGljYXRlZE5vZGVUZXN0WzFdOwotICAgICAgbV9ub2RlVGVzdHNbMF0gPSB0ZXN0OwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgUHJlZGljYXRlZE5vZGVUZXN0W10gdGVzdHMgPSBtX25vZGVUZXN0czsKLSAgICAgIGludCBsZW4gPSBtX25vZGVUZXN0cy5sZW5ndGg7Ci0KLSAgICAgIG1fbm9kZVRlc3RzID0gbmV3IFByZWRpY2F0ZWROb2RlVGVzdFtsZW4gKyAxXTsKLQotICAgICAgU3lzdGVtLmFycmF5Y29weSh0ZXN0cywgMCwgbV9ub2RlVGVzdHMsIDAsIGxlbik7Ci0KLSAgICAgIG1fbm9kZVRlc3RzW2xlbl0gPSB0ZXN0OwotICAgIH0KLSAgICB0ZXN0LmV4cHJTZXRQYXJlbnQodGhpcyk7Ci0gIH0KLQotICAvKioKLSAgICogVGhpcyBmdW5jdGlvbiBpcyB1c2VkIHRvIGZpeHVwIHZhcmlhYmxlcyBmcm9tIFFOYW1lcyB0byBzdGFjayBmcmFtZQotICAgKiBpbmRleGVzIGF0IHN0eWxlc2hlZXQgYnVpbGQgdGltZS4KLSAgICogQHBhcmFtIHZhcnMgTGlzdCBvZiBRTmFtZXMgdGhhdCBjb3JyZXNwb25kIHRvIHZhcmlhYmxlcy4gIFRoaXMgbGlzdAotICAgKiBzaG91bGQgYmUgc2VhcmNoZWQgYmFja3dhcmRzIGZvciB0aGUgZmlyc3QgcXVhbGlmaWVkIG5hbWUgdGhhdAotICAgKiBjb3JyZXNwb25kcyB0byB0aGUgdmFyaWFibGUgcmVmZXJlbmNlIHFuYW1lLiAgVGhlIHBvc2l0aW9uIG9mIHRoZQotICAgKiBRTmFtZSBpbiB0aGUgdmVjdG9yIGZyb20gdGhlIHN0YXJ0IG9mIHRoZSB2ZWN0b3Igd2lsbCBiZSBpdHMgcG9zaXRpb24KLSAgICogaW4gdGhlIHN0YWNrIGZyYW1lIChidXQgdmFyaWFibGVzIGFib3ZlIHRoZSBnbG9iYWxzVG9wIHZhbHVlIHdpbGwgbmVlZAotICAgKiB0byBiZSBvZmZzZXQgdG8gdGhlIGN1cnJlbnQgc3RhY2sgZnJhbWUpLgotICAgKi8KLSAgcHVibGljIHZvaWQgZml4dXBWYXJpYWJsZXMoamF2YS51dGlsLlZlY3RvciB2YXJzLCBpbnQgZ2xvYmFsc1NpemUpCi0gIHsKLSAgICBzdXBlci5maXh1cFZhcmlhYmxlcyh2YXJzLCBnbG9iYWxzU2l6ZSk7Ci0gICAgaWYgKG1fbm9kZVRlc3RzICE9IG51bGwpIHsKLSAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbV9ub2RlVGVzdHMubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgbV9ub2RlVGVzdHNbaV0uZml4dXBWYXJpYWJsZXModmFycywgZ2xvYmFsc1NpemUpOwotICAgICAgfQotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBUZXN0IHdoZXRoZXIgYSBzcGVjaWZpZWQgbm9kZSBpcyB2aXNpYmxlIGluIHRoZSBsb2dpY2FsIHZpZXcgb2YgYQotICAgKiBUcmVlV2Fsa2VyIG9yIE5vZGVJdGVyYXRvci4gVGhpcyBmdW5jdGlvbiB3aWxsIGJlIGNhbGxlZCBieSB0aGUKLSAgICogaW1wbGVtZW50YXRpb24gb2YgVHJlZVdhbGtlciBhbmQgTm9kZUl0ZXJhdG9yOyBpdCBpcyBub3QgaW50ZW5kZWQgdG8KLSAgICogYmUgY2FsbGVkIGRpcmVjdGx5IGZyb20gdXNlciBjb2RlLgotICAgKiBAcGFyYW0gbiAgVGhlIG5vZGUgdG8gY2hlY2sgdG8gc2VlIGlmIGl0IHBhc3NlcyB0aGUgZmlsdGVyIG9yIG5vdC4KLSAgICogQHJldHVybiAgYSBjb25zdGFudCB0byBkZXRlcm1pbmUgd2hldGhlciB0aGUgbm9kZSBpcyBhY2NlcHRlZCwKLSAgICogICByZWplY3RlZCwgb3Igc2tpcHBlZCwgYXMgZGVmaW5lZCAgYWJvdmUgLgotICAgKi8KLSAgcHVibGljIHNob3J0IGFjY2VwdE5vZGUoaW50IG4pCi0gIHsKLSAgICBYUGF0aENvbnRleHQgeGN0eHQgPSBnZXRYUGF0aENvbnRleHQoKTsKLSAgICB0cnkKLSAgICB7Ci0gICAgICB4Y3R4dC5wdXNoQ3VycmVudE5vZGUobik7Ci0gICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1fbm9kZVRlc3RzLmxlbmd0aDsgaSsrKQotICAgICAgewotICAgICAgICBQcmVkaWNhdGVkTm9kZVRlc3QgcG50ID0gbV9ub2RlVGVzdHNbaV07Ci0gICAgICAgIFhPYmplY3Qgc2NvcmUgPSBwbnQuZXhlY3V0ZSh4Y3R4dCwgbik7Ci0gICAgICAgIGlmIChzY29yZSAhPSBOb2RlVGVzdC5TQ09SRV9OT05FKQotICAgICAgICB7Ci0gICAgICAgICAgLy8gTm90ZSB0aGF0IHdlIGFyZSBhc3N1bWluZyB0aGVyZSBhcmUgbm8gcG9zaXRpb25hbCBwcmVkaWNhdGVzIQotICAgICAgICAgIGlmIChwbnQuZ2V0UHJlZGljYXRlQ291bnQoKSA+IDApCi0gICAgICAgICAgewotICAgICAgICAgICAgaWYgKHBudC5leGVjdXRlUHJlZGljYXRlcyhuLCB4Y3R4dCkpCi0gICAgICAgICAgICAgIHJldHVybiBEVE1JdGVyYXRvci5GSUxURVJfQUNDRVBUOwotICAgICAgICAgIH0KLSAgICAgICAgICBlbHNlCi0gICAgICAgICAgICByZXR1cm4gRFRNSXRlcmF0b3IuRklMVEVSX0FDQ0VQVDsKLQotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotICAgIGNhdGNoIChqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uIHNlKQotICAgIHsKLQotICAgICAgLy8gVE9ETzogRml4IHRoaXMuCi0gICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihzZS5nZXRNZXNzYWdlKCkpOwotICAgIH0KLSAgICBmaW5hbGx5Ci0gICAgewotICAgICAgeGN0eHQucG9wQ3VycmVudE5vZGUoKTsKLSAgICB9Ci0gICAgcmV0dXJuIERUTUl0ZXJhdG9yLkZJTFRFUl9TS0lQOwotICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvYXhlcy9VbmlvblBhdGhJdGVyYXRvci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9heGVzL1VuaW9uUGF0aEl0ZXJhdG9yLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGM4M2Y0ZTUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9heGVzL1VuaW9uUGF0aEl0ZXJhdG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw1ODYgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogVW5pb25QYXRoSXRlcmF0b3IuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNCAxOTo0MzoyNSBqZWZmc3V0dG9yIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmF4ZXM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5BeGlzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1JdGVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuRXhwcmVzc2lvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuRXhwcmVzc2lvbk93bmVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5YUGF0aFZpc2l0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmNvbXBpbGVyLkNvbXBpbGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5jb21waWxlci5PcENvZGVzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5jb21waWxlci5PcE1hcDsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGV4dGVuZHMgTm9kZVNldERUTSwgd2hpY2ggaW1wbGVtZW50cyBEVE1JdGVyYXRvciwKLSAqIGFuZCBmZXRjaGVzIG5vZGVzIG9uZSBhdCBhIHRpbWUgaW4gZG9jdW1lbnQgb3JkZXIgYmFzZWQgb24gYSBYUGF0aAotICogPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGgjTlQtVW5pb25FeHByIj5VbmlvbkV4cHI8L2E+LgotICogQXMgZWFjaCBub2RlIGlzIGl0ZXJhdGVkIHZpYSBuZXh0Tm9kZSgpLCB0aGUgbm9kZSBpcyBhbHNvIHN0b3JlZAotICogaW4gdGhlIE5vZGVWZWN0b3IsIHNvIHRoYXQgcHJldmlvdXNOb2RlKCkgY2FuIGVhc2lseSBiZSBkb25lLgotICogQHhzbC51c2FnZSBhZHZhbmNlZAotICovCi1wdWJsaWMgY2xhc3MgVW5pb25QYXRoSXRlcmF0b3IgZXh0ZW5kcyBMb2NQYXRoSXRlcmF0b3IKLSAgICAgICAgaW1wbGVtZW50cyBDbG9uZWFibGUsIERUTUl0ZXJhdG9yLCBqYXZhLmlvLlNlcmlhbGl6YWJsZSwgUGF0aENvbXBvbmVudAotewotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMzkxMDM1MTU0Njg0MzgyNjc4MUw7Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdG9yIHRvIGNyZWF0ZSBhbiBpbnN0YW5jZSB3aGljaCB5b3UgY2FuIGFkZCBsb2NhdGlvbiBwYXRocyB0by4KLSAgICovCi0gIHB1YmxpYyBVbmlvblBhdGhJdGVyYXRvcigpCi0gIHsKLQotICAgIHN1cGVyKCk7Ci0KLSAgICAvLyBtX211dGFibGUgPSBmYWxzZTsKLSAgICAvLyBtX2NhY2hlTm9kZXMgPSBmYWxzZTsKLSAgICBtX2l0ZXJhdG9ycyA9IG51bGw7Ci0gICAgbV9leHBycyA9IG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogSW5pdGlhbGl6ZSB0aGUgY29udGV4dCB2YWx1ZXMgZm9yIHRoaXMgZXhwcmVzc2lvbgotICAgKiBhZnRlciBpdCBpcyBjbG9uZWQuCi0gICAqCi0gICAqIEBwYXJhbSBjb250ZXh0IFRoZSBYUGF0aCBydW50aW1lIGNvbnRleHQgZm9yIHRoaXMKLSAgICogdHJhbnNmb3JtYXRpb24uCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRSb290KGludCBjb250ZXh0LCBPYmplY3QgZW52aXJvbm1lbnQpCi0gIHsKLSAgICBzdXBlci5zZXRSb290KGNvbnRleHQsIGVudmlyb25tZW50KTsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIGlmIChudWxsICE9IG1fZXhwcnMpCi0gICAgICB7Ci0gICAgICAgIGludCBuID0gbV9leHBycy5sZW5ndGg7Ci0gICAgICAgIERUTUl0ZXJhdG9yIG5ld0l0ZXJzW10gPSBuZXcgRFRNSXRlcmF0b3Jbbl07Ci0KLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspCi0gICAgICAgIHsKLSAgICAgICAgICBEVE1JdGVyYXRvciBpdGVyID0gbV9leHByc1tpXS5hc0l0ZXJhdG9yKG1fZXhlY0NvbnRleHQsIGNvbnRleHQpOwotICAgICAgICAgIG5ld0l0ZXJzW2ldID0gaXRlcjsKLSAgICAgICAgICBpdGVyLm5leHROb2RlKCk7Ci0gICAgICAgIH0KLSAgICAgICAgbV9pdGVyYXRvcnMgPSBuZXdJdGVyczsKLSAgICAgIH0KLSAgICB9Ci0gICAgY2F0Y2goRXhjZXB0aW9uIGUpCi0gICAgewotICAgICAgdGhyb3cgbmV3IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuV3JhcHBlZFJ1bnRpbWVFeGNlcHRpb24oZSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEFkZCBhbiBpdGVyYXRvciB0byB0aGUgdW5pb24gbGlzdC4KLSAgICoKLSAgICogQHBhcmFtIGV4cHIgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGEgbG9jYXRpb24gcGF0aCBpdGVyYXRvci4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGFkZEl0ZXJhdG9yKERUTUl0ZXJhdG9yIGV4cHIpCi0gIHsKLQotICAgIC8vIEluY3JlYXNlIGFycmF5IHNpemUgYnkgb25seSAxIGF0IGEgdGltZS4gIEZpeCB0aGlzCi0gICAgLy8gaWYgaXQgbG9va3MgdG8gYmUgYSBwcm9ibGVtLgotICAgIGlmIChudWxsID09IG1faXRlcmF0b3JzKQotICAgIHsKLSAgICAgIG1faXRlcmF0b3JzID0gbmV3IERUTUl0ZXJhdG9yWzFdOwotICAgICAgbV9pdGVyYXRvcnNbMF0gPSBleHByOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgRFRNSXRlcmF0b3JbXSBleHBycyA9IG1faXRlcmF0b3JzOwotICAgICAgaW50IGxlbiA9IG1faXRlcmF0b3JzLmxlbmd0aDsKLQotICAgICAgbV9pdGVyYXRvcnMgPSBuZXcgRFRNSXRlcmF0b3JbbGVuICsgMV07Ci0KLSAgICAgIFN5c3RlbS5hcnJheWNvcHkoZXhwcnMsIDAsIG1faXRlcmF0b3JzLCAwLCBsZW4pOwotCi0gICAgICBtX2l0ZXJhdG9yc1tsZW5dID0gZXhwcjsKLSAgICB9Ci0gICAgZXhwci5uZXh0Tm9kZSgpOwotICAgIGlmKGV4cHIgaW5zdGFuY2VvZiBFeHByZXNzaW9uKQotICAgICAgICAoKEV4cHJlc3Npb24pZXhwcikuZXhwclNldFBhcmVudCh0aGlzKTsKLSAgfQotCi0gIC8qKgotICAgKiAgRGV0YWNoZXMgdGhlIGl0ZXJhdG9yIGZyb20gdGhlIHNldCB3aGljaCBpdCBpdGVyYXRlZCBvdmVyLCByZWxlYXNpbmcKLSAgICogYW55IGNvbXB1dGF0aW9uYWwgcmVzb3VyY2VzIGFuZCBwbGFjaW5nIHRoZSBpdGVyYXRvciBpbiB0aGUgSU5WQUxJRAotICAgKiBzdGF0ZS4gQWZ0ZXI8Y29kZT5kZXRhY2g8L2NvZGU+IGhhcyBiZWVuIGludm9rZWQsIGNhbGxzIHRvCi0gICAqIDxjb2RlPm5leHROb2RlPC9jb2RlPiBvcjxjb2RlPnByZXZpb3VzTm9kZTwvY29kZT4gd2lsbCByYWlzZSB0aGUKLSAgICogZXhjZXB0aW9uIElOVkFMSURfU1RBVEVfRVJSLgotICAgKi8KLSAgcHVibGljIHZvaWQgZGV0YWNoKCkKLSAgewotICAgICAgICAgIGlmKG1fYWxsb3dEZXRhY2ggJiYgbnVsbCAhPSBtX2l0ZXJhdG9ycyl7Ci0gICAgICAgICAgICAgICAgICBpbnQgbiA9IG1faXRlcmF0b3JzLmxlbmd0aDsKLSAgICAgICAgICAgICAgICAgIGZvcihpbnQgaSA9IDA7IGkgPCBuOyBpKyspCi0gICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgIG1faXRlcmF0b3JzW2ldLmRldGFjaCgpOwotICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgbV9pdGVyYXRvcnMgPSBudWxsOwotICAgICAgICAgIH0KLSAgfQotCi0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIFVuaW9uUGF0aEl0ZXJhdG9yIG9iamVjdCwgaW5jbHVkaW5nIGNyZWF0aW9uCi0gICAqIG9mIGxvY2F0aW9uIHBhdGggaXRlcmF0b3JzIGZyb20gdGhlIG9wY29kZSBsaXN0LCBhbmQgY2FsbCBiYWNrCi0gICAqIGludG8gdGhlIENvbXBpbGVyIHRvIGNyZWF0ZSBwcmVkaWNhdGUgZXhwcmVzc2lvbnMuCi0gICAqCi0gICAqIEBwYXJhbSBjb21waWxlciBUaGUgQ29tcGlsZXIgd2hpY2ggaXMgY3JlYXRpbmcKLSAgICogdGhpcyBleHByZXNzaW9uLgotICAgKiBAcGFyYW0gb3BQb3MgVGhlIHBvc2l0aW9uIG9mIHRoaXMgaXRlcmF0b3IgaW4gdGhlCi0gICAqIG9wY29kZSBsaXN0IGZyb20gdGhlIGNvbXBpbGVyLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBVbmlvblBhdGhJdGVyYXRvcihDb21waWxlciBjb21waWxlciwgaW50IG9wUG9zKQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIHN1cGVyKCk7Ci0KLSAgICBvcFBvcyA9IE9wTWFwLmdldEZpcnN0Q2hpbGRQb3Mob3BQb3MpOwotCi0gICAgbG9hZExvY2F0aW9uUGF0aHMoY29tcGlsZXIsIG9wUG9zLCAwKTsKLSAgfQotCi0gIC8qKgotICAgKiBUaGlzIHdpbGwgcmV0dXJuIGFuIGl0ZXJhdG9yIGNhcGFibGUgb2YgaGFuZGxpbmcgdGhlIHVuaW9uIG9mIHBhdGhzIGdpdmVuLgotICAgKgotICAgKiBAcGFyYW0gY29tcGlsZXIgVGhlIENvbXBpbGVyIHdoaWNoIGlzIGNyZWF0aW5nCi0gICAqIHRoaXMgZXhwcmVzc2lvbi4KLSAgICogQHBhcmFtIG9wUG9zIFRoZSBwb3NpdGlvbiBvZiB0aGlzIGl0ZXJhdG9yIGluIHRoZQotICAgKiBvcGNvZGUgbGlzdCBmcm9tIHRoZSBjb21waWxlci4KLSAgICoKLSAgICogQHJldHVybiBPYmplY3QgdGhhdCBpcyBkZXJpdmVkIGZyb20gTG9jUGF0aEl0ZXJhdG9yLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgTG9jUGF0aEl0ZXJhdG9yIGNyZWF0ZVVuaW9uSXRlcmF0b3IoQ29tcGlsZXIgY29tcGlsZXIsIGludCBvcFBvcykKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgICAgIC8vIEZvciB0aGUgbW9tZW50LCBJJ20gZ29pbmcgdG8gZmlyc3QgY3JlYXRlIGEgZnVsbCBVbmlvblBhdGhJdGVyYXRvciwgYW5kCi0gICAgICAgIC8vIHRoZW4gc2VlIGlmIEkgY2FuIHJlZHVjZSBpdCB0byBhIFVuaW9uQ2hpbGRJdGVyYXRvci4gIEl0IHdvdWxkIG9idmlvdXNseQotICAgICAgICAvLyBiZSBtb3JlIGVmZmVjaWVudCB0byBqdXN0IHRlc3QgZm9yIHRoZSBjb25kaXRpb25zIGZvciBhIFVuaW9uQ2hpbGRJdGVyYXRvciwKLSAgICAgICAgLy8gYW5kIHRoZW4gY3JlYXRlIHRoYXQgZGlyZWN0bHkuCi0gICAgICAgIFVuaW9uUGF0aEl0ZXJhdG9yIHVwaSA9IG5ldyBVbmlvblBhdGhJdGVyYXRvcihjb21waWxlciwgb3BQb3MpOwotICAgICAgICBpbnQgblBhdGhzID0gdXBpLm1fZXhwcnMubGVuZ3RoOwotICAgICAgICBib29sZWFuIGlzQWxsQ2hpbGRJdGVyYXRvcnMgPSB0cnVlOwotICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgblBhdGhzOyBpKyspCi0gICAgICAgIHsKLSAgICAgICAgICAgICAgICBMb2NQYXRoSXRlcmF0b3IgbHBpID0gdXBpLm1fZXhwcnNbaV07Ci0KLSAgICAgICAgICAgICAgICBpZihscGkuZ2V0QXhpcygpICE9IEF4aXMuQ0hJTEQpCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgaXNBbGxDaGlsZEl0ZXJhdG9ycyA9IGZhbHNlOwotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBjaGVjayBmb3IgcG9zaXRpb25hbCBwcmVkaWNhdGVzIG9yIHBvc2l0aW9uIGZ1bmN0aW9uLCB3aGljaCB3b24ndCB3b3JrLgotICAgICAgICAgICAgICAgICAgICAgICAgaWYoSGFzUG9zaXRpb25hbFByZWRDaGVja2VyLmNoZWNrKGxwaSkpCi0gICAgICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzQWxsQ2hpbGRJdGVyYXRvcnMgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGlmKGlzQWxsQ2hpbGRJdGVyYXRvcnMpCi0gICAgICAgIHsKLSAgICAgICAgICAgICAgICBVbmlvbkNoaWxkSXRlcmF0b3IgdWNpID0gbmV3IFVuaW9uQ2hpbGRJdGVyYXRvcigpOwotCi0gICAgICAgICAgICAgICAgZm9yKGludCBpID0gMDsgaSA8IG5QYXRoczsgaSsrKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIFByZWRpY2F0ZWROb2RlVGVzdCBscGkgPSB1cGkubV9leHByc1tpXTsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIEkgY291bGQgc3RyaXAgdGhlIGxwaSBkb3duIHRvIGEgcHVyZSBQcmVkaWNhdGVkTm9kZVRlc3QsIGJ1dAotICAgICAgICAgICAgICAgICAgICAgICAgLy8gSSBkb24ndCB0aGluayBpdCdzIHdvcnRoIGl0LiAgTm90ZSB0aGF0IHRoZSB0ZXN0IGNhbiBiZSB1c2VkCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBhcyBhIHN0YXRpYyBvYmplY3QuLi4gc28gaXQgZG9lc24ndCBoYXZlIHRvIGJlIGNsb25lZC4KLSAgICAgICAgICAgICAgICAgICAgICAgIHVjaS5hZGROb2RlVGVzdChscGkpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICByZXR1cm4gdWNpOwotCi0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIHJldHVybiB1cGk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBhbmFseXNpcyBiaXRzIGZvciB0aGlzIHdhbGtlciwgYXMgZGVmaW5lZCBpbiB0aGUgV2Fsa2VyRmFjdG9yeS4KLSAgICogQHJldHVybiBPbmUgb2YgV2Fsa2VyRmFjdG9yeSNCSVRfREVTQ0VOREFOVCwgZXRjLgotICAgKi8KLSAgcHVibGljIGludCBnZXRBbmFseXNpc0JpdHMoKQotICB7Ci0gICAgaW50IGJpdHMgPSAwOwotCi0gICAgaWYgKG1fZXhwcnMgIT0gbnVsbCkKLSAgICB7Ci0gICAgICBpbnQgbiA9IG1fZXhwcnMubGVuZ3RoOwotCi0gICAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykKLSAgICAgIHsKLSAgICAgICAgaW50IGJpdCA9IG1fZXhwcnNbaV0uZ2V0QW5hbHlzaXNCaXRzKCk7Ci0gICAgICAgIGJpdHMgfD0gYml0OwotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiBiaXRzOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlYWQgdGhlIG9iamVjdCBmcm9tIGEgc2VyaWFsaXphdGlvbiBzdHJlYW0uCi0gICAqCi0gICAqIEBwYXJhbSBzdHJlYW0gSW5wdXQgc3RyZWFtIHRvIHJlYWQgZnJvbQotICAgKgotICAgKiBAdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24KLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwcml2YXRlIHZvaWQgcmVhZE9iamVjdChqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtIHN0cmVhbSkKLSAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiwgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgdHJ5Ci0gICAgewotICAgICAgc3RyZWFtLmRlZmF1bHRSZWFkT2JqZWN0KCk7Ci0gICAgICBtX2Nsb25lcyA9ICBuZXcgSXRlcmF0b3JQb29sKHRoaXMpOwotICAgIH0KLSAgICBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBjbmZlKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uKGNuZmUpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBHZXQgYSBjbG9uZWQgTG9jUGF0aEl0ZXJhdG9yIHRoYXQgaG9sZHMgdGhlIHNhbWUKLSAgICogcG9zaXRpb24gYXMgdGhpcyBpdGVyYXRvci4KLSAgICoKLSAgICogQHJldHVybiBBIGNsb25lIG9mIHRoaXMgaXRlcmF0b3IgdGhhdCBob2xkcyB0aGUgc2FtZSBub2RlIHBvc2l0aW9uLgotICAgKgotICAgKiBAdGhyb3dzIENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgT2JqZWN0IGNsb25lKCkgdGhyb3dzIENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uCi0gIHsKLQotICAgIFVuaW9uUGF0aEl0ZXJhdG9yIGNsb25lID0gKFVuaW9uUGF0aEl0ZXJhdG9yKSBzdXBlci5jbG9uZSgpOwotICAgIGlmIChtX2l0ZXJhdG9ycyAhPSBudWxsKQotICAgIHsKLSAgICAgIGludCBuID0gbV9pdGVyYXRvcnMubGVuZ3RoOwotCi0gICAgICBjbG9uZS5tX2l0ZXJhdG9ycyA9IG5ldyBEVE1JdGVyYXRvcltuXTsKLQotICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspCi0gICAgICB7Ci0gICAgICAgIGNsb25lLm1faXRlcmF0b3JzW2ldID0gKERUTUl0ZXJhdG9yKW1faXRlcmF0b3JzW2ldLmNsb25lKCk7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgcmV0dXJuIGNsb25lOwotICB9Ci0KLQotICAvKioKLSAgICogQ3JlYXRlIGEgbmV3IGxvY2F0aW9uIHBhdGggaXRlcmF0b3IuCi0gICAqCi0gICAqIEBwYXJhbSBjb21waWxlciBUaGUgQ29tcGlsZXIgd2hpY2ggaXMgY3JlYXRpbmcKLSAgICogdGhpcyBleHByZXNzaW9uLgotICAgKiBAcGFyYW0gb3BQb3MgVGhlIHBvc2l0aW9uIG9mIHRoaXMgaXRlcmF0b3IgaW4gdGhlCi0gICAqCi0gICAqIEByZXR1cm4gTmV3IGxvY2F0aW9uIHBhdGggaXRlcmF0b3IuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHJvdGVjdGVkIExvY1BhdGhJdGVyYXRvciBjcmVhdGVEVE1JdGVyYXRvcigKLSAgICAgICAgICBDb21waWxlciBjb21waWxlciwgaW50IG9wUG9zKSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgTG9jUGF0aEl0ZXJhdG9yIGxwaSA9IChMb2NQYXRoSXRlcmF0b3IpV2Fsa2VyRmFjdG9yeS5uZXdEVE1JdGVyYXRvcihjb21waWxlciwgb3BQb3MsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjb21waWxlci5nZXRMb2NhdGlvblBhdGhEZXB0aCgpIDw9IDApKTsKLSAgICByZXR1cm4gbHBpOwotICB9Ci0KLSAgLyoqCi0gICAqIEluaXRpYWxpemUgdGhlIGxvY2F0aW9uIHBhdGggaXRlcmF0b3JzLiAgUmVjdXJzaXZlLgotICAgKgotICAgKiBAcGFyYW0gY29tcGlsZXIgVGhlIENvbXBpbGVyIHdoaWNoIGlzIGNyZWF0aW5nCi0gICAqIHRoaXMgZXhwcmVzc2lvbi4KLSAgICogQHBhcmFtIG9wUG9zIFRoZSBwb3NpdGlvbiBvZiB0aGlzIGl0ZXJhdG9yIGluIHRoZQotICAgKiBvcGNvZGUgbGlzdCBmcm9tIHRoZSBjb21waWxlci4KLSAgICogQHBhcmFtIGNvdW50IFRoZSBpbnNlcnQgcG9zaXRpb24gb2YgdGhlIGl0ZXJhdG9yLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIGxvYWRMb2NhdGlvblBhdGhzKENvbXBpbGVyIGNvbXBpbGVyLCBpbnQgb3BQb3MsIGludCBjb3VudCkKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICAvLyBUT0RPOiBIYW5kbGUgdW53cmFwcGVkIEZpbHRlckV4cHIKLSAgICBpbnQgc3RlcHR5cGUgPSBjb21waWxlci5nZXRPcChvcFBvcyk7Ci0KLSAgICBpZiAoc3RlcHR5cGUgPT0gT3BDb2Rlcy5PUF9MT0NBVElPTlBBVEgpCi0gICAgewotICAgICAgbG9hZExvY2F0aW9uUGF0aHMoY29tcGlsZXIsIGNvbXBpbGVyLmdldE5leHRPcFBvcyhvcFBvcyksIGNvdW50ICsgMSk7Ci0KLSAgICAgIG1fZXhwcnNbY291bnRdID0gY3JlYXRlRFRNSXRlcmF0b3IoY29tcGlsZXIsIG9wUG9zKTsKLSAgICAgIG1fZXhwcnNbY291bnRdLmV4cHJTZXRQYXJlbnQodGhpcyk7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0KLSAgICAgIC8vIEhhdmUgdG8gY2hlY2sgZm9yIHVud3JhcHBlZCBmdW5jdGlvbnMsIHdoaWNoIHRoZSBMb2NQYXRoSXRlcmF0b3IKLSAgICAgIC8vIGRvZXNuJ3QgaGFuZGxlLgotICAgICAgc3dpdGNoIChzdGVwdHlwZSkKLSAgICAgIHsKLSAgICAgIGNhc2UgT3BDb2Rlcy5PUF9WQVJJQUJMRSA6Ci0gICAgICBjYXNlIE9wQ29kZXMuT1BfRVhURlVOQ1RJT04gOgotICAgICAgY2FzZSBPcENvZGVzLk9QX0ZVTkNUSU9OIDoKLSAgICAgIGNhc2UgT3BDb2Rlcy5PUF9HUk9VUCA6Ci0gICAgICAgIGxvYWRMb2NhdGlvblBhdGhzKGNvbXBpbGVyLCBjb21waWxlci5nZXROZXh0T3BQb3Mob3BQb3MpLCBjb3VudCArIDEpOwotCi0gICAgICAgIFdhbGtpbmdJdGVyYXRvciBpdGVyID0KLSAgICAgICAgICBuZXcgV2Fsa2luZ0l0ZXJhdG9yKGNvbXBpbGVyLmdldE5hbWVzcGFjZUNvbnRleHQoKSk7Ci0gICAgICAgIGl0ZXIuZXhwclNldFBhcmVudCh0aGlzKTsKLQotICAgICAgICBpZihjb21waWxlci5nZXRMb2NhdGlvblBhdGhEZXB0aCgpIDw9IDApCi0gICAgICAgICAgaXRlci5zZXRJc1RvcExldmVsKHRydWUpOwotCi0gICAgICAgIGl0ZXIubV9maXJzdFdhbGtlciA9IG5ldyBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuYXhlcy5GaWx0ZXJFeHByV2Fsa2VyKGl0ZXIpOwotCi0gICAgICAgIGl0ZXIubV9maXJzdFdhbGtlci5pbml0KGNvbXBpbGVyLCBvcFBvcywgc3RlcHR5cGUpOwotCi0gICAgICAgIG1fZXhwcnNbY291bnRdID0gaXRlcjsKLSAgICAgICAgYnJlYWs7Ci0gICAgICBkZWZhdWx0IDoKLSAgICAgICAgbV9leHBycyA9IG5ldyBMb2NQYXRoSXRlcmF0b3JbY291bnRdOwotICAgICAgfQotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiAgUmV0dXJucyB0aGUgbmV4dCBub2RlIGluIHRoZSBzZXQgYW5kIGFkdmFuY2VzIHRoZSBwb3NpdGlvbiBvZiB0aGUKLSAgICogaXRlcmF0b3IgaW4gdGhlIHNldC4gQWZ0ZXIgYSBEVE1JdGVyYXRvciBpcyBjcmVhdGVkLCB0aGUgZmlyc3QgY2FsbAotICAgKiB0byBuZXh0Tm9kZSgpIHJldHVybnMgdGhlIGZpcnN0IG5vZGUgaW4gdGhlIHNldC4KLSAgICogQHJldHVybiAgVGhlIG5leHQgPGNvZGU+Tm9kZTwvY29kZT4gaW4gdGhlIHNldCBiZWluZyBpdGVyYXRlZCBvdmVyLCBvcgotICAgKiAgIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoZXJlIGFyZSBubyBtb3JlIG1lbWJlcnMgaW4gdGhhdCBzZXQuCi0gICAqLwotICBwdWJsaWMgaW50IG5leHROb2RlKCkKLSAgewotICAgICAgICBpZihtX2ZvdW5kTGFzdCkKLSAgICAgICAgICAgICAgICByZXR1cm4gRFRNLk5VTEw7Ci0KLSAgICAvLyBMb29wIHRocm91Z2ggdGhlIGl0ZXJhdG9ycyBnZXR0aW5nIHRoZSBjdXJyZW50IGZldGNoZWQKLSAgICAvLyBub2RlLCBhbmQgZ2V0IHRoZSBlYXJsaWVzdCBvY2N1cmluZyBpbiBkb2N1bWVudCBvcmRlcgotICAgIGludCBlYXJsaWVzdE5vZGUgPSBEVE0uTlVMTDsKLQotICAgIGlmIChudWxsICE9IG1faXRlcmF0b3JzKQotICAgIHsKLSAgICAgIGludCBuID0gbV9pdGVyYXRvcnMubGVuZ3RoOwotICAgICAgaW50IGl0ZXJhdG9yVXNlZCA9IC0xOwotCi0gICAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykKLSAgICAgIHsKLSAgICAgICAgaW50IG5vZGUgPSBtX2l0ZXJhdG9yc1tpXS5nZXRDdXJyZW50Tm9kZSgpOwotCi0gICAgICAgIGlmIChEVE0uTlVMTCA9PSBub2RlKQotICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICBlbHNlIGlmIChEVE0uTlVMTCA9PSBlYXJsaWVzdE5vZGUpCi0gICAgICAgIHsKLSAgICAgICAgICBpdGVyYXRvclVzZWQgPSBpOwotICAgICAgICAgIGVhcmxpZXN0Tm9kZSA9IG5vZGU7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICB7Ci0gICAgICAgICAgaWYgKG5vZGUgPT0gZWFybGllc3ROb2RlKQotICAgICAgICAgIHsKLQotICAgICAgICAgICAgLy8gRm91bmQgYSBkdXBsaWNhdGUsIHNvIHNraXAgcGFzdCBpdC4KLSAgICAgICAgICAgIG1faXRlcmF0b3JzW2ldLm5leHROb2RlKCk7Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBEVE0gZHRtID0gZ2V0RFRNKG5vZGUpOwotCi0gICAgICAgICAgICBpZiAoZHRtLmlzTm9kZUFmdGVyKG5vZGUsIGVhcmxpZXN0Tm9kZSkpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIGl0ZXJhdG9yVXNlZCA9IGk7Ci0gICAgICAgICAgICAgIGVhcmxpZXN0Tm9kZSA9IG5vZGU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICB9Ci0KLSAgICAgIGlmIChEVE0uTlVMTCAhPSBlYXJsaWVzdE5vZGUpCi0gICAgICB7Ci0gICAgICAgIG1faXRlcmF0b3JzW2l0ZXJhdG9yVXNlZF0ubmV4dE5vZGUoKTsKLQotICAgICAgICBpbmNyZW1lbnRDdXJyZW50UG9zKCk7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICAgIG1fZm91bmRMYXN0ID0gdHJ1ZTsKLSAgICB9Ci0KLSAgICBtX2xhc3RGZXRjaGVkID0gZWFybGllc3ROb2RlOwotCi0gICAgcmV0dXJuIGVhcmxpZXN0Tm9kZTsKLSAgfQotCi0gIC8qKgotICAgKiBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgdG8gZml4dXAgdmFyaWFibGVzIGZyb20gUU5hbWVzIHRvIHN0YWNrIGZyYW1lCi0gICAqIGluZGV4ZXMgYXQgc3R5bGVzaGVldCBidWlsZCB0aW1lLgotICAgKiBAcGFyYW0gdmFycyBMaXN0IG9mIFFOYW1lcyB0aGF0IGNvcnJlc3BvbmQgdG8gdmFyaWFibGVzLiAgVGhpcyBsaXN0Ci0gICAqIHNob3VsZCBiZSBzZWFyY2hlZCBiYWNrd2FyZHMgZm9yIHRoZSBmaXJzdCBxdWFsaWZpZWQgbmFtZSB0aGF0Ci0gICAqIGNvcnJlc3BvbmRzIHRvIHRoZSB2YXJpYWJsZSByZWZlcmVuY2UgcW5hbWUuICBUaGUgcG9zaXRpb24gb2YgdGhlCi0gICAqIFFOYW1lIGluIHRoZSB2ZWN0b3IgZnJvbSB0aGUgc3RhcnQgb2YgdGhlIHZlY3RvciB3aWxsIGJlIGl0cyBwb3NpdGlvbgotICAgKiBpbiB0aGUgc3RhY2sgZnJhbWUgKGJ1dCB2YXJpYWJsZXMgYWJvdmUgdGhlIGdsb2JhbHNUb3AgdmFsdWUgd2lsbCBuZWVkCi0gICAqIHRvIGJlIG9mZnNldCB0byB0aGUgY3VycmVudCBzdGFjayBmcmFtZSkuCi0gICAqLwotICBwdWJsaWMgdm9pZCBmaXh1cFZhcmlhYmxlcyhqYXZhLnV0aWwuVmVjdG9yIHZhcnMsIGludCBnbG9iYWxzU2l6ZSkKLSAgewotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbV9leHBycy5sZW5ndGg7IGkrKykKLSAgICB7Ci0gICAgICBtX2V4cHJzW2ldLmZpeHVwVmFyaWFibGVzKHZhcnMsIGdsb2JhbHNTaXplKTsKLSAgICB9Ci0KLSAgfQotCi0gIC8qKgotICAgKiBUaGUgbG9jYXRpb24gcGF0aCBpdGVyYXRvcnMsIG9uZSBmb3IgZWFjaAotICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aCNOVC1Mb2NhdGlvblBhdGgiPmxvY2F0aW9uCi0gICAqIHBhdGg8L2E+IGNvbnRhaW5lZCBpbiB0aGUgdW5pb24gZXhwcmVzc2lvbi4KLSAgICogQHNlcmlhbAotICAgKi8KLSAgcHJvdGVjdGVkIExvY1BhdGhJdGVyYXRvcltdIG1fZXhwcnM7Ci0KLQotICAvKioKLSAgICogVGhlIGxvY2F0aW9uIHBhdGggaXRlcmF0b3JzLCBvbmUgZm9yIGVhY2gKLSAgICogPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGgjTlQtTG9jYXRpb25QYXRoIj5sb2NhdGlvbgotICAgKiBwYXRoPC9hPiBjb250YWluZWQgaW4gdGhlIHVuaW9uIGV4cHJlc3Npb24uCi0gICAqIEBzZXJpYWwKLSAgICovCi0gIHByb3RlY3RlZCBEVE1JdGVyYXRvcltdIG1faXRlcmF0b3JzOwotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBheGlzIGJlaW5nIGl0ZXJhdGVkLCBpZiBpdCBpcyBrbm93bi4KLSAgICoKLSAgICogQHJldHVybiBBeGlzLkNISUxELCBldGMuLCBvciAtMSBpZiB0aGUgYXhpcyBpcyBub3Qga25vd24gb3IgaXMgb2YgbXVsdGlwbGUKLSAgICogdHlwZXMuCi0gICAqLwotICBwdWJsaWMgaW50IGdldEF4aXMoKQotICB7Ci0gICAgLy8gQ291bGQgYmUgc21hcnRlci4KLSAgICByZXR1cm4gLTE7Ci0gIH0KLQotICBjbGFzcyBpdGVyT3duZXIgaW1wbGVtZW50cyBFeHByZXNzaW9uT3duZXIKLSAgewotICAgICAgICBpbnQgbV9pbmRleDsKLQotICAgICAgICBpdGVyT3duZXIoaW50IGluZGV4KQotICAgICAgICB7Ci0gICAgICAgICAgICAgICAgbV9pbmRleCA9IGluZGV4OwotICAgICAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAc2VlIEV4cHJlc3Npb25Pd25lciNnZXRFeHByZXNzaW9uKCkKLSAgICAgKi8KLSAgICBwdWJsaWMgRXhwcmVzc2lvbiBnZXRFeHByZXNzaW9uKCkKLSAgICB7Ci0gICAgICByZXR1cm4gbV9leHByc1ttX2luZGV4XTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAc2VlIEV4cHJlc3Npb25Pd25lciNzZXRFeHByZXNzaW9uKEV4cHJlc3Npb24pCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RXhwcmVzc2lvbihFeHByZXNzaW9uIGV4cCkKLSAgICB7Ci0KLSAgICAgICAgaWYoIShleHAgaW5zdGFuY2VvZiBMb2NQYXRoSXRlcmF0b3IpKQotICAgICAgICB7Ci0gICAgICAgICAgICAgICAgLy8gWXVjay4gIE5lZWQgRmlsdGVyRXhwckl0ZXIuICBPciBtYWtlIGl0IHNvIG1fZXhwcnMgY2FuIGJlIGp1c3QKLSAgICAgICAgICAgICAgICAvLyBwbGFpbiBleHByZXNzaW9ucz8KLSAgICAgICAgICAgICAgICBXYWxraW5nSXRlcmF0b3Igd2kgPSBuZXcgV2Fsa2luZ0l0ZXJhdG9yKGdldFByZWZpeFJlc29sdmVyKCkpOwotICAgICAgICAgICAgICAgIEZpbHRlckV4cHJXYWxrZXIgZmV3ID0gbmV3IEZpbHRlckV4cHJXYWxrZXIod2kpOwotICAgICAgICAgICAgICAgIHdpLnNldEZpcnN0V2Fsa2VyKGZldyk7Ci0gICAgICAgICAgICAgICAgZmV3LnNldElubmVyRXhwcmVzc2lvbihleHApOwotICAgICAgICAgICAgICAgIHdpLmV4cHJTZXRQYXJlbnQoVW5pb25QYXRoSXRlcmF0b3IudGhpcyk7Ci0gICAgICAgICAgICAgICAgZmV3LmV4cHJTZXRQYXJlbnQod2kpOwotICAgICAgICAgICAgICAgIGV4cC5leHByU2V0UGFyZW50KGZldyk7Ci0gICAgICAgICAgICAgICAgZXhwID0gd2k7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIGV4cC5leHByU2V0UGFyZW50KFVuaW9uUGF0aEl0ZXJhdG9yLnRoaXMpOwotICAgICAgICBtX2V4cHJzW21faW5kZXhdID0gKExvY1BhdGhJdGVyYXRvcilleHA7Ci0gICAgfQotCi0gIH0KLQotICAvKioKLSAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuWFBhdGhWaXNpdGFibGUjY2FsbFZpc2l0b3JzKEV4cHJlc3Npb25Pd25lciwgWFBhdGhWaXNpdG9yKQotICAgKi8KLSAgcHVibGljIHZvaWQgY2FsbFZpc2l0b3JzKEV4cHJlc3Npb25Pd25lciBvd25lciwgWFBhdGhWaXNpdG9yIHZpc2l0b3IpCi0gIHsKLSAgICAgICAgICAgICAgICBpZih2aXNpdG9yLnZpc2l0VW5pb25QYXRoKG93bmVyLCB0aGlzKSkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZihudWxsICE9IG1fZXhwcnMpCi0gICAgICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBuID0gbV9leHBycy5sZW5ndGg7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcihpbnQgaSA9IDA7IGkgPCBuOyBpKyspCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX2V4cHJzW2ldLmNhbGxWaXNpdG9ycyhuZXcgaXRlck93bmVyKGkpLCB2aXNpdG9yKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBFeHByZXNzaW9uI2RlZXBFcXVhbHMoRXhwcmVzc2lvbikKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBkZWVwRXF1YWxzKEV4cHJlc3Npb24gZXhwcikKLSAgICB7Ci0gICAgICBpZiAoIXN1cGVyLmRlZXBFcXVhbHMoZXhwcikpCi0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0KLSAgICAgIFVuaW9uUGF0aEl0ZXJhdG9yIHVwaSA9IChVbmlvblBhdGhJdGVyYXRvcikgZXhwcjsKLQotICAgICAgaWYgKG51bGwgIT0gbV9leHBycykKLSAgICAgIHsKLSAgICAgICAgaW50IG4gPSBtX2V4cHJzLmxlbmd0aDsKLQotICAgICAgICBpZigobnVsbCA9PSB1cGkubV9leHBycykgfHwgKHVwaS5tX2V4cHJzLmxlbmd0aCAhPSBuKSkKLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0KLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspCi0gICAgICAgIHsKLSAgICAgICAgICBpZighbV9leHByc1tpXS5kZWVwRXF1YWxzKHVwaS5tX2V4cHJzW2ldKSkKLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICAgIGVsc2UgaWYgKG51bGwgIT0gdXBpLm1fZXhwcnMpCi0gICAgICB7Ci0gICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgfQotCi0gICAgICByZXR1cm4gdHJ1ZTsKLSAgICB9Ci0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9heGVzL1dhbGtlckZhY3RvcnkuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvYXhlcy9XYWxrZXJGYWN0b3J5LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDJmMDU1MzUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9heGVzL1dhbGtlckZhY3RvcnkuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE4MjcgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogV2Fsa2VyRmFjdG9yeS5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzEwIDAzOjQyOjE5IGplZmZzdXR0b3IgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuYXhlczsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC5yZXMuWFNMTWVzc2FnZXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uQXhpczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1GaWx0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNSXRlcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLkV4cHJlc3Npb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmNvbXBpbGVyLkNvbXBpbGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5jb21waWxlci5GdW5jdGlvblRhYmxlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5jb21waWxlci5PcENvZGVzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5jb21waWxlci5PcE1hcDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YTnVtYmVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5wYXR0ZXJucy5Db250ZXh0TWF0Y2hTdGVwUGF0dGVybjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucGF0dGVybnMuRnVuY3Rpb25QYXR0ZXJuOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5wYXR0ZXJucy5Ob2RlVGVzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucGF0dGVybnMuU3RlcFBhdHRlcm47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLnJlcy5YUEFUSEVycm9yUmVzb3VyY2VzOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgaXMgYm90aCBhIGZhY3RvcnkgZm9yIFhQYXRoIGxvY2F0aW9uIHBhdGggZXhwcmVzc2lvbnMsCi0gKiB3aGljaCBhcmUgYnVpbHQgZnJvbSB0aGUgb3Bjb2RlIG1hcCBvdXRwdXQsIGFuZCBhbiBhbmFseXNpcyBlbmdpbmUKLSAqIGZvciB0aGUgbG9jYXRpb24gcGF0aCBleHByZXNzaW9ucyBpbiBvcmRlciB0byBwcm92aWRlIG9wdGltaXphdGlvbiBoaW50cy4KLSAqLwotcHVibGljIGNsYXNzIFdhbGtlckZhY3RvcnkKLXsKLQotICAvKioKLSAgICogVGhpcyBtZXRob2QgaXMgZm9yIGJ1aWxkaW5nIGFuIGFycmF5IG9mIHBvc3NpYmxlIGxldmVscwotICAgKiB3aGVyZSB0aGUgdGFyZ2V0IGVsZW1lbnQocykgY291bGQgYmUgZm91bmQgZm9yIGEgbWF0Y2guCi0gICAqIEBwYXJhbSBscGkgVGhlIG93bmluZyBsb2NhdGlvbiBwYXRoIGl0ZXJhdG9yLgotICAgKiBAcGFyYW0gY29tcGlsZXIgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGNvbXBpbGVyIG9iamVjdCB0aGF0IGhhcyBwcm9jZXNzZWQKLSAgICogICAgICAgICAgICAgICAgIHRoZSBYUGF0aCBvcGVyYXRpb25zIGludG8gYW4gb3Bjb2RlIG1hcC4KLSAgICogQHBhcmFtIHN0ZXBPcENvZGVQb3MgVGhlIG9wY29kZSBwb3NpdGlvbiBmb3IgdGhlIHN0ZXAuCi0gICAqCi0gICAqIEByZXR1cm4gbm9uLW51bGwgQXhlc1dhbGtlciBkZXJpdmF0aXZlLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICogQHhzbC51c2FnZSBhZHZhbmNlZAotICAgKi8KLSAgc3RhdGljIEF4ZXNXYWxrZXIgbG9hZE9uZVdhbGtlcigKLSAgICAgICAgICBXYWxraW5nSXRlcmF0b3IgbHBpLCBDb21waWxlciBjb21waWxlciwgaW50IHN0ZXBPcENvZGVQb3MpCi0gICAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBBeGVzV2Fsa2VyIGZpcnN0V2Fsa2VyID0gbnVsbDsKLSAgICBpbnQgc3RlcFR5cGUgPSBjb21waWxlci5nZXRPcChzdGVwT3BDb2RlUG9zKTsKLQotICAgIGlmIChzdGVwVHlwZSAhPSBPcENvZGVzLkVORE9QKQotICAgIHsKLQotICAgICAgLy8gbV9heGVzV2Fsa2VycyA9IG5ldyBBeGVzV2Fsa2VyWzFdOwotICAgICAgLy8gQXMgd2UgdW53aW5kIGZyb20gdGhlIHJlY3Vyc2lvbiwgY3JlYXRlIHRoZSBpdGVyYXRvcnMuCi0gICAgICBmaXJzdFdhbGtlciA9IGNyZWF0ZURlZmF1bHRXYWxrZXIoY29tcGlsZXIsIHN0ZXBUeXBlLCBscGksIDApOwotCi0gICAgICBmaXJzdFdhbGtlci5pbml0KGNvbXBpbGVyLCBzdGVwT3BDb2RlUG9zLCBzdGVwVHlwZSk7Ci0gICAgfQotCi0gICAgcmV0dXJuIGZpcnN0V2Fsa2VyOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoaXMgbWV0aG9kIGlzIGZvciBidWlsZGluZyBhbiBhcnJheSBvZiBwb3NzaWJsZSBsZXZlbHMKLSAgICogd2hlcmUgdGhlIHRhcmdldCBlbGVtZW50KHMpIGNvdWxkIGJlIGZvdW5kIGZvciBhIG1hdGNoLgotICAgKiBAcGFyYW0gbHBpIFRoZSBvd25pbmcgbG9jYXRpb24gcGF0aCBpdGVyYXRvciBvYmplY3QuCi0gICAqIEBwYXJhbSBjb21waWxlciBub24tbnVsbCByZWZlcmVuY2UgdG8gY29tcGlsZXIgb2JqZWN0IHRoYXQgaGFzIHByb2Nlc3NlZAotICAgKiAgICAgICAgICAgICAgICAgdGhlIFhQYXRoIG9wZXJhdGlvbnMgaW50byBhbiBvcGNvZGUgbWFwLgotICAgKiBAcGFyYW0gc3RlcE9wQ29kZVBvcyBUaGUgb3Bjb2RlIHBvc2l0aW9uIGZvciB0aGUgc3RlcC4KLSAgICogQHBhcmFtIHN0ZXBJbmRleCBUaGUgdG9wLWxldmVsIHN0ZXAgaW5kZXggd2l0aGluZyB0aGUgaXRlcmF0b3IuCi0gICAqCi0gICAqIEByZXR1cm4gbm9uLW51bGwgQXhlc1dhbGtlciBkZXJpdmF0aXZlLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICogQHhzbC51c2FnZSBhZHZhbmNlZAotICAgKi8KLSAgc3RhdGljIEF4ZXNXYWxrZXIgbG9hZFdhbGtlcnMoCi0gICAgICAgICAgV2Fsa2luZ0l0ZXJhdG9yIGxwaSwgQ29tcGlsZXIgY29tcGlsZXIsIGludCBzdGVwT3BDb2RlUG9zLCBpbnQgc3RlcEluZGV4KQotICAgICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaW50IHN0ZXBUeXBlOwotICAgIEF4ZXNXYWxrZXIgZmlyc3RXYWxrZXIgPSBudWxsOwotICAgIEF4ZXNXYWxrZXIgd2Fsa2VyLCBwcmV2V2Fsa2VyID0gbnVsbDsKLQotICAgIGludCBhbmFseXNpcyA9IGFuYWx5emUoY29tcGlsZXIsIHN0ZXBPcENvZGVQb3MsIHN0ZXBJbmRleCk7Ci0KLSAgICB3aGlsZSAoT3BDb2Rlcy5FTkRPUCAhPSAoc3RlcFR5cGUgPSBjb21waWxlci5nZXRPcChzdGVwT3BDb2RlUG9zKSkpCi0gICAgewotICAgICAgd2Fsa2VyID0gY3JlYXRlRGVmYXVsdFdhbGtlcihjb21waWxlciwgc3RlcE9wQ29kZVBvcywgbHBpLCBhbmFseXNpcyk7Ci0KLSAgICAgIHdhbGtlci5pbml0KGNvbXBpbGVyLCBzdGVwT3BDb2RlUG9zLCBzdGVwVHlwZSk7Ci0gICAgICB3YWxrZXIuZXhwclNldFBhcmVudChscGkpOwotCi0gICAgICAvLyB3YWxrZXIuc2V0QW5hbHlzaXMoYW5hbHlzaXMpOwotICAgICAgaWYgKG51bGwgPT0gZmlyc3RXYWxrZXIpCi0gICAgICB7Ci0gICAgICAgIGZpcnN0V2Fsa2VyID0gd2Fsa2VyOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBwcmV2V2Fsa2VyLnNldE5leHRXYWxrZXIod2Fsa2VyKTsKLSAgICAgICAgd2Fsa2VyLnNldFByZXZXYWxrZXIocHJldldhbGtlcik7Ci0gICAgICB9Ci0KLSAgICAgIHByZXZXYWxrZXIgPSB3YWxrZXI7Ci0gICAgICBzdGVwT3BDb2RlUG9zID0gY29tcGlsZXIuZ2V0TmV4dFN0ZXBQb3Moc3RlcE9wQ29kZVBvcyk7Ci0KLSAgICAgIGlmIChzdGVwT3BDb2RlUG9zIDwgMCkKLSAgICAgICAgYnJlYWs7Ci0gICAgfQotCi0gICAgcmV0dXJuIGZpcnN0V2Fsa2VyOwotICB9Ci0KLSAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzU2V0KGludCBhbmFseXNpcywgaW50IGJpdHMpCi0gIHsKLSAgICByZXR1cm4gKDAgIT0gKGFuYWx5c2lzICYgYml0cykpOwotICB9Ci0KLSAgcHVibGljIHN0YXRpYyB2b2lkIGRpYWdub3NlSXRlcmF0b3IoU3RyaW5nIG5hbWUsIGludCBhbmFseXNpcywgQ29tcGlsZXIgY29tcGlsZXIpCi0gIHsKLSAgICBTeXN0ZW0ub3V0LnByaW50bG4oY29tcGlsZXIudG9TdHJpbmcoKSsiLCAiK25hbWUrIiwgIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIEludGVnZXIudG9CaW5hcnlTdHJpbmcoYW5hbHlzaXMpICsgIiwgIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGdldEFuYWx5c2lzU3RyaW5nKGFuYWx5c2lzKSk7Ci0gIH0KLQotICAvKioKLSAgICogQ3JlYXRlIGEgbmV3IExvY1BhdGhJdGVyYXRvciBpdGVyYXRvci4gIFRoZSBleGFjdCB0eXBlIG9mIGl0ZXJhdG9yCi0gICAqIHJldHVybmVkIGlzIGJhc2VkIG9uIGFuIGFuYWx5c2lzIG9mIHRoZSBYUGF0aCBvcGVyYXRpb25zLgotICAgKgotICAgKiBAcGFyYW0gY29tcGlsZXIgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGNvbXBpbGVyIG9iamVjdCB0aGF0IGhhcyBwcm9jZXNzZWQKLSAgICogICAgICAgICAgICAgICAgIHRoZSBYUGF0aCBvcGVyYXRpb25zIGludG8gYW4gb3Bjb2RlIG1hcC4KLSAgICogQHBhcmFtIG9wUG9zIFRoZSBwb3NpdGlvbiBvZiB0aGUgb3BlcmF0aW9uIGNvZGUgZm9yIHRoaXMgaXR0ZXJhdG9yLgotICAgKgotICAgKiBAcmV0dXJuIG5vbi1udWxsIHJlZmVyZW5jZSB0byBhIExvY1BhdGhJdGVyYXRvciBvciBkZXJpdmF0aXZlLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgRFRNSXRlcmF0b3IgbmV3RFRNSXRlcmF0b3IoCi0gICAgICAgICAgQ29tcGlsZXIgY29tcGlsZXIsIGludCBvcFBvcywKLSAgICAgICAgICBib29sZWFuIGlzVG9wTGV2ZWwpCi0gICAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpbnQgZmlyc3RTdGVwUG9zID0gT3BNYXAuZ2V0Rmlyc3RDaGlsZFBvcyhvcFBvcyk7Ci0gICAgaW50IGFuYWx5c2lzID0gYW5hbHl6ZShjb21waWxlciwgZmlyc3RTdGVwUG9zLCAwKTsKLSAgICBib29sZWFuIGlzT25lU3RlcCA9IGlzT25lU3RlcChhbmFseXNpcyk7Ci0gICAgRFRNSXRlcmF0b3IgaXRlcjsKLQotICAgIC8vIElzIHRoZSBpdGVyYXRpb24gYSBvbmUtc3RlcCBhdHRyaWJ1dGUgcGF0dGVybiAoaS5lLiBzZWxlY3Q9IkBmb28iKT8KLSAgICBpZiAoaXNPbmVTdGVwICYmIHdhbGtzU2VsZk9ubHkoYW5hbHlzaXMpICYmCi0gICAgICAgIGlzV2lsZChhbmFseXNpcykgJiYgIWhhc1ByZWRpY2F0ZShhbmFseXNpcykpCi0gICAgewotICAgICAgaWYgKERFQlVHX0lURVJBVE9SX0NSRUFUSU9OKQotICAgICAgICBkaWFnbm9zZUl0ZXJhdG9yKCJTZWxmSXRlcmF0b3JOb1ByZWRpY2F0ZSIsIGFuYWx5c2lzLCBjb21waWxlcik7Ci0KLSAgICAgIC8vIFRoZW4gdXNlIGEgc2ltcGxlIGl0ZXJhdGlvbiBvZiB0aGUgYXR0cmlidXRlcywgd2l0aCBub2RlIHRlc3QKLSAgICAgIC8vIGFuZCBwcmVkaWNhdGUgdGVzdGluZy4KLSAgICAgIGl0ZXIgPSBuZXcgU2VsZkl0ZXJhdG9yTm9QcmVkaWNhdGUoY29tcGlsZXIsIG9wUG9zLCBhbmFseXNpcyk7Ci0gICAgfQotICAgIC8vIElzIHRoZSBpdGVyYXRpb24gZXhhY3RseSBvbmUgY2hpbGQgc3RlcD8KLSAgICBlbHNlIGlmICh3YWxrc0NoaWxkcmVuT25seShhbmFseXNpcykgJiYgaXNPbmVTdGVwKQotICAgIHsKLQotICAgICAgLy8gRG9lcyB0aGUgcGF0dGVybiBzcGVjaWZ5ICphbnkqIGNoaWxkIHdpdGggbm8gcHJlZGljYXRlPyAoaS5lLiBzZWxlY3Q9ImNoaWxkOjpub2RlKCkiLgotICAgICAgaWYgKGlzV2lsZChhbmFseXNpcykgJiYgIWhhc1ByZWRpY2F0ZShhbmFseXNpcykpCi0gICAgICB7Ci0gICAgICAgIGlmIChERUJVR19JVEVSQVRPUl9DUkVBVElPTikKLSAgICAgICAgICBkaWFnbm9zZUl0ZXJhdG9yKCJDaGlsZEl0ZXJhdG9yIiwgYW5hbHlzaXMsIGNvbXBpbGVyKTsKLQotICAgICAgICAvLyBVc2Ugc2ltcGxlIGNoaWxkIGl0ZXJhdGlvbiB3aXRob3V0IGFueSB0ZXN0LgotICAgICAgICBpdGVyID0gbmV3IENoaWxkSXRlcmF0b3IoY29tcGlsZXIsIG9wUG9zLCBhbmFseXNpcyk7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIGlmIChERUJVR19JVEVSQVRPUl9DUkVBVElPTikKLSAgICAgICAgICBkaWFnbm9zZUl0ZXJhdG9yKCJDaGlsZFRlc3RJdGVyYXRvciIsIGFuYWx5c2lzLCBjb21waWxlcik7Ci0KLSAgICAgICAgLy8gRWxzZSB1c2Ugc2ltcGxlIG5vZGUgdGVzdCBpdGVyYXRpb24gd2l0aCBwcmVkaWNhdGUgdGVzdC4KLSAgICAgICAgaXRlciA9IG5ldyBDaGlsZFRlc3RJdGVyYXRvcihjb21waWxlciwgb3BQb3MsIGFuYWx5c2lzKTsKLSAgICAgIH0KLSAgICB9Ci0gICAgLy8gSXMgdGhlIGl0ZXJhdGlvbiBhIG9uZS1zdGVwIGF0dHJpYnV0ZSBwYXR0ZXJuIChpLmUuIHNlbGVjdD0iQGZvbyIpPwotICAgIGVsc2UgaWYgKGlzT25lU3RlcCAmJiB3YWxrc0F0dHJpYnV0ZXMoYW5hbHlzaXMpKQotICAgIHsKLSAgICAgIGlmIChERUJVR19JVEVSQVRPUl9DUkVBVElPTikKLSAgICAgICAgZGlhZ25vc2VJdGVyYXRvcigiQXR0cmlidXRlSXRlcmF0b3IiLCBhbmFseXNpcywgY29tcGlsZXIpOwotCi0gICAgICAvLyBUaGVuIHVzZSBhIHNpbXBsZSBpdGVyYXRpb24gb2YgdGhlIGF0dHJpYnV0ZXMsIHdpdGggbm9kZSB0ZXN0Ci0gICAgICAvLyBhbmQgcHJlZGljYXRlIHRlc3RpbmcuCi0gICAgICBpdGVyID0gbmV3IEF0dHJpYnV0ZUl0ZXJhdG9yKGNvbXBpbGVyLCBvcFBvcywgYW5hbHlzaXMpOwotICAgIH0KLSAgICBlbHNlIGlmKGlzT25lU3RlcCAmJiAhd2Fsa3NGaWx0ZXJlZExpc3QoYW5hbHlzaXMpKQotICAgIHsKLSAgICAgIGlmKCAhd2Fsa3NOYW1lc3BhY2VzKGFuYWx5c2lzKQotICAgICAgJiYgKHdhbGtzSW5Eb2NPcmRlcihhbmFseXNpcykgfHwgaXNTZXQoYW5hbHlzaXMsIEJJVF9QQVJFTlQpKSkKLSAgICAgIHsKLSAgICAgICAgaWYgKGZhbHNlIHx8IERFQlVHX0lURVJBVE9SX0NSRUFUSU9OKQotICAgICAgICAgIGRpYWdub3NlSXRlcmF0b3IoIk9uZVN0ZXBJdGVyYXRvckZvcndhcmQiLCBhbmFseXNpcywgY29tcGlsZXIpOwotCi0gICAgICAgIC8vIFRoZW4gdXNlIGEgc2ltcGxlIGl0ZXJhdGlvbiBvZiB0aGUgYXR0cmlidXRlcywgd2l0aCBub2RlIHRlc3QKLSAgICAgICAgLy8gYW5kIHByZWRpY2F0ZSB0ZXN0aW5nLgotICAgICAgICBpdGVyID0gbmV3IE9uZVN0ZXBJdGVyYXRvckZvcndhcmQoY29tcGlsZXIsIG9wUG9zLCBhbmFseXNpcyk7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIGlmIChmYWxzZSB8fCBERUJVR19JVEVSQVRPUl9DUkVBVElPTikKLSAgICAgICAgICBkaWFnbm9zZUl0ZXJhdG9yKCJPbmVTdGVwSXRlcmF0b3IiLCBhbmFseXNpcywgY29tcGlsZXIpOwotCi0gICAgICAgIC8vIFRoZW4gdXNlIGEgc2ltcGxlIGl0ZXJhdGlvbiBvZiB0aGUgYXR0cmlidXRlcywgd2l0aCBub2RlIHRlc3QKLSAgICAgICAgLy8gYW5kIHByZWRpY2F0ZSB0ZXN0aW5nLgotICAgICAgICBpdGVyID0gbmV3IE9uZVN0ZXBJdGVyYXRvcihjb21waWxlciwgb3BQb3MsIGFuYWx5c2lzKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICAvLyBBbmFseXNpcyBvZiAiLy9jZW50ZXIiOgotICAgIC8vIGJpdHM6IDEwMDEwMDAwMDAwMDEwMTAwMDAwMDAwMDAwMDAwMTEKLSAgICAvLyBjb3VudDogMwotICAgIC8vIHJvb3QKLSAgICAvLyBjaGlsZDpub2RlKCkKLSAgICAvLyBCSVRfREVTQ0VOREFOVF9PUl9TRUxGCi0gICAgLy8gSXQncyBoaWdobHkgcG9zc2libGUgdGhhdCB3ZSBzaG91bGQgaGF2ZSBhIHNlcGVyYXRlIGJpdCBzZXQgZm9yCi0gICAgLy8gIi8vZm9vIiBwYXR0ZXJucy4KLSAgICAvLyBGb3IgYXQgbGVhc3QgdGhlIHRpbWUgYmVpbmcsIHdlIGNhbid0IG9wdGltaXplIHBhdHRlcm5zIGxpa2UKLSAgICAvLyAiLy90YWJsZVszXSIsIGJlY2F1c2UgdGhpcyBoYXMgdG8gYmUgYW5hbHl6ZWQgYXMKLSAgICAvLyAiL2Rlc2NlbmRhbnQtb3Itc2VsZjo6bm9kZSgpL3RhYmxlWzNdIiBpbiBvcmRlciBmb3IgdGhlIGluZGV4ZXMKLSAgICAvLyB0byB3b3JrIHJpZ2h0LgotICAgIGVsc2UgaWYgKGlzT3B0aW1pemFibGVGb3JEZXNjZW5kYW50SXRlcmF0b3IoY29tcGlsZXIsIGZpcnN0U3RlcFBvcywgMCkKLSAgICAgICAgICAgICAgLy8gJiYgZ2V0U3RlcENvdW50KGFuYWx5c2lzKSA8PSAzCi0gICAgICAgICAgICAgIC8vICYmIHdhbGtzRGVzY2VuZGFudHMoYW5hbHlzaXMpCi0gICAgICAgICAgICAgIC8vICYmIHdhbGtzU3VidHJlZU9ubHlGcm9tUm9vdE9yQ29udGV4dChhbmFseXNpcykKLSAgICAgICAgICAgICApCi0gICAgewotICAgICAgaWYgKERFQlVHX0lURVJBVE9SX0NSRUFUSU9OKQotICAgICAgICBkaWFnbm9zZUl0ZXJhdG9yKCJEZXNjZW5kYW50SXRlcmF0b3IiLCBhbmFseXNpcywgY29tcGlsZXIpOwotCi0gICAgICBpdGVyID0gbmV3IERlc2NlbmRhbnRJdGVyYXRvcihjb21waWxlciwgb3BQb3MsIGFuYWx5c2lzKTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIGlmKGlzTmF0dXJhbERvY09yZGVyKGNvbXBpbGVyLCBmaXJzdFN0ZXBQb3MsIDAsIGFuYWx5c2lzKSkKLSAgICAgIHsKLSAgICAgICAgaWYgKGZhbHNlIHx8IERFQlVHX0lURVJBVE9SX0NSRUFUSU9OKQotICAgICAgICB7Ci0gICAgICAgICAgZGlhZ25vc2VJdGVyYXRvcigiV2Fsa2luZ0l0ZXJhdG9yIiwgYW5hbHlzaXMsIGNvbXBpbGVyKTsKLSAgICAgICAgfQotCi0gICAgICAgIGl0ZXIgPSBuZXcgV2Fsa2luZ0l0ZXJhdG9yKGNvbXBpbGVyLCBvcFBvcywgYW5hbHlzaXMsIHRydWUpOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotLy8gICAgICAgIGlmIChERUJVR19JVEVSQVRPUl9DUkVBVElPTikKLS8vICAgICAgICAgIGRpYWdub3NlSXRlcmF0b3IoIk1hdGNoUGF0dGVybkl0ZXJhdG9yIiwgYW5hbHlzaXMsIGNvbXBpbGVyKTsKLS8vCi0vLyAgICAgICAgcmV0dXJuIG5ldyBNYXRjaFBhdHRlcm5JdGVyYXRvcihjb21waWxlciwgb3BQb3MsIGFuYWx5c2lzKTsKLSAgICAgICAgaWYgKERFQlVHX0lURVJBVE9SX0NSRUFUSU9OKQotICAgICAgICAgIGRpYWdub3NlSXRlcmF0b3IoIldhbGtpbmdJdGVyYXRvclNvcnRlZCIsIGFuYWx5c2lzLCBjb21waWxlcik7Ci0KLSAgICAgICAgaXRlciA9IG5ldyBXYWxraW5nSXRlcmF0b3JTb3J0ZWQoY29tcGlsZXIsIG9wUG9zLCBhbmFseXNpcywgdHJ1ZSk7Ci0gICAgICB9Ci0gICAgfQotICAgIGlmKGl0ZXIgaW5zdGFuY2VvZiBMb2NQYXRoSXRlcmF0b3IpCi0gICAgICAoKExvY1BhdGhJdGVyYXRvcilpdGVyKS5zZXRJc1RvcExldmVsKGlzVG9wTGV2ZWwpOwotCi0gICAgcmV0dXJuIGl0ZXI7Ci0gIH0KLQotICAvKioKLSAgICogU3BlY2lhbCBwdXJwb3NlIGZ1bmN0aW9uIHRvIHNlZSBpZiB3ZSBjYW4gb3B0aW1pemUgdGhlIHBhdHRlcm4gZm9yCi0gICAqIGEgRGVzY2VuZGFudEl0ZXJhdG9yLgotICAgKgotICAgKiBAcGFyYW0gY29tcGlsZXIgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGNvbXBpbGVyIG9iamVjdCB0aGF0IGhhcyBwcm9jZXNzZWQKLSAgICogICAgICAgICAgICAgICAgIHRoZSBYUGF0aCBvcGVyYXRpb25zIGludG8gYW4gb3Bjb2RlIG1hcC4KLSAgICogQHBhcmFtIHN0ZXBPcENvZGVQb3MgVGhlIG9wY29kZSBwb3NpdGlvbiBmb3IgdGhlIHN0ZXAuCi0gICAqCi0gICAqIEByZXR1cm4gMzIgYml0cyBhcyBhbiBpbnRlZ2VyIHRoYXQgZ2l2ZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgbG9jYXRpb24KLSAgICogcGF0aCBhcyBhIHdob2xlLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgaW50IGdldEF4aXNGcm9tU3RlcCgKLSAgICAgICAgICBDb21waWxlciBjb21waWxlciwgaW50IHN0ZXBPcENvZGVQb3MpCi0gICAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpbnQgc3RlcFR5cGUgPSBjb21waWxlci5nZXRPcChzdGVwT3BDb2RlUG9zKTsKLQotICAgIHN3aXRjaCAoc3RlcFR5cGUpCi0gICAgewotICAgIGNhc2UgT3BDb2Rlcy5GUk9NX0ZPTExPV0lORyA6Ci0gICAgICByZXR1cm4gQXhpcy5GT0xMT1dJTkc7Ci0gICAgY2FzZSBPcENvZGVzLkZST01fRk9MTE9XSU5HX1NJQkxJTkdTIDoKLSAgICAgIHJldHVybiBBeGlzLkZPTExPV0lOR1NJQkxJTkc7Ci0gICAgY2FzZSBPcENvZGVzLkZST01fUFJFQ0VESU5HIDoKLSAgICAgIHJldHVybiBBeGlzLlBSRUNFRElORzsKLSAgICBjYXNlIE9wQ29kZXMuRlJPTV9QUkVDRURJTkdfU0lCTElOR1MgOgotICAgICAgcmV0dXJuIEF4aXMuUFJFQ0VESU5HU0lCTElORzsKLSAgICBjYXNlIE9wQ29kZXMuRlJPTV9QQVJFTlQgOgotICAgICAgcmV0dXJuIEF4aXMuUEFSRU5UOwotICAgIGNhc2UgT3BDb2Rlcy5GUk9NX05BTUVTUEFDRSA6Ci0gICAgICByZXR1cm4gQXhpcy5OQU1FU1BBQ0U7Ci0gICAgY2FzZSBPcENvZGVzLkZST01fQU5DRVNUT1JTIDoKLSAgICAgIHJldHVybiBBeGlzLkFOQ0VTVE9SOwotICAgIGNhc2UgT3BDb2Rlcy5GUk9NX0FOQ0VTVE9SU19PUl9TRUxGIDoKLSAgICAgIHJldHVybiBBeGlzLkFOQ0VTVE9ST1JTRUxGOwotICAgIGNhc2UgT3BDb2Rlcy5GUk9NX0FUVFJJQlVURVMgOgotICAgICAgcmV0dXJuIEF4aXMuQVRUUklCVVRFOwotICAgIGNhc2UgT3BDb2Rlcy5GUk9NX1JPT1QgOgotICAgICAgcmV0dXJuIEF4aXMuUk9PVDsKLSAgICBjYXNlIE9wQ29kZXMuRlJPTV9DSElMRFJFTiA6Ci0gICAgICByZXR1cm4gQXhpcy5DSElMRDsKLSAgICBjYXNlIE9wQ29kZXMuRlJPTV9ERVNDRU5EQU5UU19PUl9TRUxGIDoKLSAgICAgIHJldHVybiBBeGlzLkRFU0NFTkRBTlRPUlNFTEY7Ci0gICAgY2FzZSBPcENvZGVzLkZST01fREVTQ0VOREFOVFMgOgotICAgICAgcmV0dXJuIEF4aXMuREVTQ0VOREFOVDsKLSAgICBjYXNlIE9wQ29kZXMuRlJPTV9TRUxGIDoKLSAgICAgIHJldHVybiBBeGlzLlNFTEY7Ci0gICAgY2FzZSBPcENvZGVzLk9QX0VYVEZVTkNUSU9OIDoKLSAgICBjYXNlIE9wQ29kZXMuT1BfRlVOQ1RJT04gOgotICAgIGNhc2UgT3BDb2Rlcy5PUF9HUk9VUCA6Ci0gICAgY2FzZSBPcENvZGVzLk9QX1ZBUklBQkxFIDoKLSAgICAgIHJldHVybiBBeGlzLkZJTFRFUkVETElTVDsKLSAgICB9Ci0KLSAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoWFBBVEhFcnJvclJlc291cmNlcy5FUl9OVUxMX0VSUk9SX0hBTkRMRVIsIG5ldyBPYmplY3RbXXtJbnRlZ2VyLnRvU3RyaW5nKHN0ZXBUeXBlKX0pKTsgLy8iUHJvZ3JhbW1lcidzIGFzc2VydGlvbjogdW5rbm93biBvcGNvZGU6ICIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLysgc3RlcFR5cGUpOwotICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IGEgY29ycmVzcG9uZGluZyBCSVRfWFhYIGZyb20gYW4gYXhpcy4KLSAgICAgKiBAcGFyYW0gYXhpcyBPbmUgb2YgQXhpcy5BTkNFU1RPUiwgZXRjLgotICAgICAqIEByZXR1cm4gT25lIG9mIEJJVF9BTkNFU1RPUiwgZXRjLgotICAgICAqLwotICAgIHN0YXRpYyBwdWJsaWMgaW50IGdldEFuYWx5c2lzQml0RnJvbUF4ZXMoaW50IGF4aXMpCi0gICAgewotICAgICAgc3dpdGNoIChheGlzKSAvLyBHZW5lcmF0ZSBuZXcgdHJhdmVyc2VyCi0gICAgICAgIHsKLSAgICAgICAgY2FzZSBBeGlzLkFOQ0VTVE9SIDoKLSAgICAgICAgICByZXR1cm4gQklUX0FOQ0VTVE9SOwotICAgICAgICBjYXNlIEF4aXMuQU5DRVNUT1JPUlNFTEYgOgotICAgICAgICAgIHJldHVybiBCSVRfQU5DRVNUT1JfT1JfU0VMRjsKLSAgICAgICAgY2FzZSBBeGlzLkFUVFJJQlVURSA6Ci0gICAgICAgICAgcmV0dXJuIEJJVF9BVFRSSUJVVEU7Ci0gICAgICAgIGNhc2UgQXhpcy5DSElMRCA6Ci0gICAgICAgICAgcmV0dXJuIEJJVF9DSElMRDsKLSAgICAgICAgY2FzZSBBeGlzLkRFU0NFTkRBTlQgOgotICAgICAgICAgIHJldHVybiBCSVRfREVTQ0VOREFOVDsKLSAgICAgICAgY2FzZSBBeGlzLkRFU0NFTkRBTlRPUlNFTEYgOgotICAgICAgICAgIHJldHVybiBCSVRfREVTQ0VOREFOVF9PUl9TRUxGOwotICAgICAgICBjYXNlIEF4aXMuRk9MTE9XSU5HIDoKLSAgICAgICAgICByZXR1cm4gQklUX0ZPTExPV0lORzsKLSAgICAgICAgY2FzZSBBeGlzLkZPTExPV0lOR1NJQkxJTkcgOgotICAgICAgICAgIHJldHVybiBCSVRfRk9MTE9XSU5HX1NJQkxJTkc7Ci0gICAgICAgIGNhc2UgQXhpcy5OQU1FU1BBQ0UgOgotICAgICAgICBjYXNlIEF4aXMuTkFNRVNQQUNFREVDTFMgOgotICAgICAgICAgIHJldHVybiBCSVRfTkFNRVNQQUNFOwotICAgICAgICBjYXNlIEF4aXMuUEFSRU5UIDoKLSAgICAgICAgICByZXR1cm4gQklUX1BBUkVOVDsKLSAgICAgICAgY2FzZSBBeGlzLlBSRUNFRElORyA6Ci0gICAgICAgICAgcmV0dXJuIEJJVF9QUkVDRURJTkc7Ci0gICAgICAgIGNhc2UgQXhpcy5QUkVDRURJTkdTSUJMSU5HIDoKLSAgICAgICAgICByZXR1cm4gQklUX1BSRUNFRElOR19TSUJMSU5HOwotICAgICAgICBjYXNlIEF4aXMuU0VMRiA6Ci0gICAgICAgICAgcmV0dXJuIEJJVF9TRUxGOwotICAgICAgICBjYXNlIEF4aXMuQUxMRlJPTU5PREUgOgotICAgICAgICAgIHJldHVybiBCSVRfREVTQ0VOREFOVF9PUl9TRUxGOwotICAgICAgICAgIC8vIGNhc2UgQXhpcy5QUkVDRURJTkdBTkRBTkNFU1RPUiA6Ci0gICAgICAgIGNhc2UgQXhpcy5ERVNDRU5EQU5UU0ZST01ST09UIDoKLSAgICAgICAgY2FzZSBBeGlzLkFMTCA6Ci0gICAgICAgIGNhc2UgQXhpcy5ERVNDRU5EQU5UU09SU0VMRkZST01ST09UIDoKLSAgICAgICAgICByZXR1cm4gQklUX0FOWV9ERVNDRU5EQU5UX0ZST01fUk9PVDsKLSAgICAgICAgY2FzZSBBeGlzLlJPT1QgOgotICAgICAgICAgIHJldHVybiBCSVRfUk9PVDsKLSAgICAgICAgY2FzZSBBeGlzLkZJTFRFUkVETElTVCA6Ci0gICAgICAgICAgcmV0dXJuIEJJVF9GSUxURVI7Ci0gICAgICAgIGRlZmF1bHQgOgotICAgICAgICAgIHJldHVybiBCSVRfRklMVEVSOwotICAgICAgfQotICAgIH0KLQotICBzdGF0aWMgYm9vbGVhbiBmdW5jdGlvblByb3hpbWF0ZU9yQ29udGFpbnNQcm94aW1hdGUoQ29tcGlsZXIgY29tcGlsZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgb3BQb3MpCi0gIHsKLSAgICBpbnQgZW5kRnVuYyA9IG9wUG9zICsgY29tcGlsZXIuZ2V0T3Aob3BQb3MgKyAxKSAtIDE7Ci0gICAgb3BQb3MgPSBPcE1hcC5nZXRGaXJzdENoaWxkUG9zKG9wUG9zKTsKLSAgICBpbnQgZnVuY0lEID0gY29tcGlsZXIuZ2V0T3Aob3BQb3MpOwotICAgIC8vICBTeXN0ZW0ub3V0LnByaW50bG4oImZ1bmNJRDogIitmdW5jSUQpOwotICAgIC8vICBTeXN0ZW0ub3V0LnByaW50bG4oIm9wUG9zOiAiK29wUG9zKTsKLSAgICAvLyAgU3lzdGVtLm91dC5wcmludGxuKCJlbmRGdW5jOiAiK2VuZEZ1bmMpOwotICAgIHN3aXRjaChmdW5jSUQpCi0gICAgewotICAgICAgY2FzZSBGdW5jdGlvblRhYmxlLkZVTkNfTEFTVDoKLSAgICAgIGNhc2UgRnVuY3Rpb25UYWJsZS5GVU5DX1BPU0lUSU9OOgotICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgIGRlZmF1bHQ6Ci0gICAgICAgIG9wUG9zKys7Ci0gICAgICAgIGludCBpID0gMDsKLSAgICAgICAgZm9yIChpbnQgcCA9IG9wUG9zOyBwIDwgZW5kRnVuYzsgcCA9IGNvbXBpbGVyLmdldE5leHRPcFBvcyhwKSwgaSsrKQotICAgICAgICB7Ci0gICAgICAgICAgaW50IGlubmVyRXhwck9wUG9zID0gcCsyOwotICAgICAgICAgIGludCBhcmdPcCA9IGNvbXBpbGVyLmdldE9wKGlubmVyRXhwck9wUG9zKTsKLSAgICAgICAgICBib29sZWFuIHByb3ggPSBpc1Byb3hpbWF0ZUlubmVyRXhwcihjb21waWxlciwgaW5uZXJFeHByT3BQb3MpOwotICAgICAgICAgIGlmKHByb3gpCi0gICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgfQotCi0gICAgfQotICAgIHJldHVybiBmYWxzZTsKLSAgfQotCi0gIHN0YXRpYyBib29sZWFuIGlzUHJveGltYXRlSW5uZXJFeHByKENvbXBpbGVyIGNvbXBpbGVyLCBpbnQgb3BQb3MpCi0gIHsKLSAgICBpbnQgb3AgPSBjb21waWxlci5nZXRPcChvcFBvcyk7Ci0gICAgaW50IGlubmVyRXhwck9wUG9zID0gb3BQb3MrMjsKLSAgICBzd2l0Y2gob3ApCi0gICAgewotICAgICAgY2FzZSBPcENvZGVzLk9QX0FSR1VNRU5UOgotICAgICAgICBpZihpc1Byb3hpbWF0ZUlubmVyRXhwcihjb21waWxlciwgaW5uZXJFeHByT3BQb3MpKQotICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICBicmVhazsKLSAgICAgIGNhc2UgT3BDb2Rlcy5PUF9WQVJJQUJMRToKLSAgICAgIGNhc2UgT3BDb2Rlcy5PUF9OVU1CRVJMSVQ6Ci0gICAgICBjYXNlIE9wQ29kZXMuT1BfTElURVJBTDoKLSAgICAgIGNhc2UgT3BDb2Rlcy5PUF9MT0NBVElPTlBBVEg6Ci0gICAgICAgIGJyZWFrOyAvLyBPSwotICAgICAgY2FzZSBPcENvZGVzLk9QX0ZVTkNUSU9OOgotICAgICAgICBib29sZWFuIGlzUHJveCA9IGZ1bmN0aW9uUHJveGltYXRlT3JDb250YWluc1Byb3hpbWF0ZShjb21waWxlciwgb3BQb3MpOwotICAgICAgICBpZihpc1Byb3gpCi0gICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgIGJyZWFrOwotICAgICAgY2FzZSBPcENvZGVzLk9QX0dUOgotICAgICAgY2FzZSBPcENvZGVzLk9QX0dURToKLSAgICAgIGNhc2UgT3BDb2Rlcy5PUF9MVDoKLSAgICAgIGNhc2UgT3BDb2Rlcy5PUF9MVEU6Ci0gICAgICBjYXNlIE9wQ29kZXMuT1BfRVFVQUxTOgotICAgICAgICBpbnQgbGVmdFBvcyA9IE9wTWFwLmdldEZpcnN0Q2hpbGRQb3Mob3ApOwotICAgICAgICBpbnQgcmlnaHRQb3MgPSBjb21waWxlci5nZXROZXh0T3BQb3MobGVmdFBvcyk7Ci0gICAgICAgIGlzUHJveCA9IGlzUHJveGltYXRlSW5uZXJFeHByKGNvbXBpbGVyLCBsZWZ0UG9zKTsKLSAgICAgICAgaWYoaXNQcm94KQotICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICBpc1Byb3ggPSBpc1Byb3hpbWF0ZUlubmVyRXhwcihjb21waWxlciwgcmlnaHRQb3MpOwotICAgICAgICBpZihpc1Byb3gpCi0gICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgIGJyZWFrOwotICAgICAgZGVmYXVsdDoKLSAgICAgICAgcmV0dXJuIHRydWU7IC8vIGJlIGNvbnNlcnZhdGl2ZS4uLgotICAgIH0KLSAgICByZXR1cm4gZmFsc2U7Ci0gIH0KLQotICAvKioKLSAgICogVGVsbCBpZiB0aGUgcHJlZGljYXRlcyBuZWVkIHRvIGhhdmUgcHJveGltaXR5IGtub3dsZWRnZS4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBtaWdodEJlUHJveGltYXRlKENvbXBpbGVyIGNvbXBpbGVyLCBpbnQgb3BQb3MsIGludCBzdGVwVHlwZSkKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBib29sZWFuIG1pZ2h0QmVQcm94aW1hdGUgPSBmYWxzZTsKLSAgICBpbnQgYXJnTGVuOwotCi0gICAgc3dpdGNoIChzdGVwVHlwZSkKLSAgICB7Ci0gICAgY2FzZSBPcENvZGVzLk9QX1ZBUklBQkxFIDoKLSAgICBjYXNlIE9wQ29kZXMuT1BfRVhURlVOQ1RJT04gOgotICAgIGNhc2UgT3BDb2Rlcy5PUF9GVU5DVElPTiA6Ci0gICAgY2FzZSBPcENvZGVzLk9QX0dST1VQIDoKLSAgICAgIGFyZ0xlbiA9IGNvbXBpbGVyLmdldEFyZ0xlbmd0aChvcFBvcyk7Ci0gICAgICBicmVhazsKLSAgICBkZWZhdWx0IDoKLSAgICAgIGFyZ0xlbiA9IGNvbXBpbGVyLmdldEFyZ0xlbmd0aE9mU3RlcChvcFBvcyk7Ci0gICAgfQotCi0gICAgaW50IHByZWRQb3MgPSBjb21waWxlci5nZXRGaXJzdFByZWRpY2F0ZU9wUG9zKG9wUG9zKTsKLSAgICBpbnQgY291bnQgPSAwOwotCi0gICAgd2hpbGUgKE9wQ29kZXMuT1BfUFJFRElDQVRFID09IGNvbXBpbGVyLmdldE9wKHByZWRQb3MpKQotICAgIHsKLSAgICAgIGNvdW50Kys7Ci0KLSAgICAgIGludCBpbm5lckV4cHJPcFBvcyA9IHByZWRQb3MrMjsKLSAgICAgIGludCBwcmVkT3AgPSBjb21waWxlci5nZXRPcChpbm5lckV4cHJPcFBvcyk7Ci0KLSAgICAgIHN3aXRjaChwcmVkT3ApCi0gICAgICB7Ci0gICAgICAgIGNhc2UgT3BDb2Rlcy5PUF9WQVJJQUJMRToKLSAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsgLy8gV291bGQgbmVlZCBtb3JlIHNtYXJ0cyB0byB0ZWxsIGlmIHRoaXMgY291bGQgYmUgYSBudW1iZXIgb3Igbm90IQotICAgICAgICBjYXNlIE9wQ29kZXMuT1BfTE9DQVRJT05QQVRIOgotICAgICAgICAgIC8vIE9LLgotICAgICAgICAgIGJyZWFrOwotICAgICAgICBjYXNlIE9wQ29kZXMuT1BfTlVNQkVSOgotICAgICAgICBjYXNlIE9wQ29kZXMuT1BfTlVNQkVSTElUOgotICAgICAgICAgIHJldHVybiB0cnVlOyAvLyB0aGF0J3MgYWxsIHNoZSB3cm90ZSEKLSAgICAgICAgY2FzZSBPcENvZGVzLk9QX0ZVTkNUSU9OOgotICAgICAgICAgIGJvb2xlYW4gaXNQcm94Ci0gICAgICAgICAgICA9IGZ1bmN0aW9uUHJveGltYXRlT3JDb250YWluc1Byb3hpbWF0ZShjb21waWxlciwgaW5uZXJFeHByT3BQb3MpOwotICAgICAgICAgIGlmKGlzUHJveCkKLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgIGJyZWFrOwotICAgICAgICBjYXNlIE9wQ29kZXMuT1BfR1Q6Ci0gICAgICAgIGNhc2UgT3BDb2Rlcy5PUF9HVEU6Ci0gICAgICAgIGNhc2UgT3BDb2Rlcy5PUF9MVDoKLSAgICAgICAgY2FzZSBPcENvZGVzLk9QX0xURToKLSAgICAgICAgY2FzZSBPcENvZGVzLk9QX0VRVUFMUzoKLSAgICAgICAgICBpbnQgbGVmdFBvcyA9IE9wTWFwLmdldEZpcnN0Q2hpbGRQb3MoaW5uZXJFeHByT3BQb3MpOwotICAgICAgICAgIGludCByaWdodFBvcyA9IGNvbXBpbGVyLmdldE5leHRPcFBvcyhsZWZ0UG9zKTsKLSAgICAgICAgICBpc1Byb3ggPSBpc1Byb3hpbWF0ZUlubmVyRXhwcihjb21waWxlciwgbGVmdFBvcyk7Ci0gICAgICAgICAgaWYoaXNQcm94KQotICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgaXNQcm94ID0gaXNQcm94aW1hdGVJbm5lckV4cHIoY29tcGlsZXIsIHJpZ2h0UG9zKTsKLSAgICAgICAgICBpZihpc1Byb3gpCi0gICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgICBicmVhazsKLSAgICAgICAgZGVmYXVsdDoKLSAgICAgICAgICByZXR1cm4gdHJ1ZTsgLy8gYmUgY29uc2VydmF0aXZlLi4uCi0gICAgICB9Ci0KLSAgICAgIHByZWRQb3MgPSBjb21waWxlci5nZXROZXh0T3BQb3MocHJlZFBvcyk7Ci0gICAgfQotCi0gICAgcmV0dXJuIG1pZ2h0QmVQcm94aW1hdGU7Ci0gIH0KLQotICAvKioKLSAgICogU3BlY2lhbCBwdXJwb3NlIGZ1bmN0aW9uIHRvIHNlZSBpZiB3ZSBjYW4gb3B0aW1pemUgdGhlIHBhdHRlcm4gZm9yCi0gICAqIGEgRGVzY2VuZGFudEl0ZXJhdG9yLgotICAgKgotICAgKiBAcGFyYW0gY29tcGlsZXIgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGNvbXBpbGVyIG9iamVjdCB0aGF0IGhhcyBwcm9jZXNzZWQKLSAgICogICAgICAgICAgICAgICAgIHRoZSBYUGF0aCBvcGVyYXRpb25zIGludG8gYW4gb3Bjb2RlIG1hcC4KLSAgICogQHBhcmFtIHN0ZXBPcENvZGVQb3MgVGhlIG9wY29kZSBwb3NpdGlvbiBmb3IgdGhlIHN0ZXAuCi0gICAqIEBwYXJhbSBzdGVwSW5kZXggVGhlIHRvcC1sZXZlbCBzdGVwIGluZGV4IHdpdGhpbmcgdGhlIGl0ZXJhdG9yLgotICAgKgotICAgKiBAcmV0dXJuIDMyIGJpdHMgYXMgYW4gaW50ZWdlciB0aGF0IGdpdmUgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGxvY2F0aW9uCi0gICAqIHBhdGggYXMgYSB3aG9sZS4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGlzT3B0aW1pemFibGVGb3JEZXNjZW5kYW50SXRlcmF0b3IoCi0gICAgICAgICAgQ29tcGlsZXIgY29tcGlsZXIsIGludCBzdGVwT3BDb2RlUG9zLCBpbnQgc3RlcEluZGV4KQotICAgICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaW50IHN0ZXBUeXBlOwotICAgIGludCBzdGVwQ291bnQgPSAwOwotICAgIGJvb2xlYW4gZm91bmREb3JEUyA9IGZhbHNlOwotICAgIGJvb2xlYW4gZm91bmRTZWxmID0gZmFsc2U7Ci0gICAgYm9vbGVhbiBmb3VuZERTID0gZmFsc2U7Ci0KLSAgICBpbnQgbm9kZVRlc3RUeXBlID0gT3BDb2Rlcy5OT0RFVFlQRV9OT0RFOwotCi0gICAgd2hpbGUgKE9wQ29kZXMuRU5ET1AgIT0gKHN0ZXBUeXBlID0gY29tcGlsZXIuZ2V0T3Aoc3RlcE9wQ29kZVBvcykpKQotICAgIHsKLSAgICAgIC8vIFRoZSBEZXNjZW5kYW50SXRlcmF0b3IgY2FuIG9ubHkgZG8gb25lIG5vZGUgdGVzdC4gIElmIHRoZXJlJ3MgbW9yZQotICAgICAgLy8gdGhhbiBvbmUsIHVzZSBhbm90aGVyIGl0ZXJhdG9yLgotICAgICAgaWYobm9kZVRlc3RUeXBlICE9IE9wQ29kZXMuTk9ERVRZUEVfTk9ERSAmJiBub2RlVGVzdFR5cGUgIT0gT3BDb2Rlcy5OT0RFVFlQRV9ST09UKQotICAgICAgICByZXR1cm4gZmFsc2U7Ci0KLSAgICAgIHN0ZXBDb3VudCsrOwotICAgICAgaWYoc3RlcENvdW50ID4gMykKLSAgICAgICAgcmV0dXJuIGZhbHNlOwotCi0gICAgICBib29sZWFuIG1pZ2h0QmVQcm94aW1hdGUgPSBtaWdodEJlUHJveGltYXRlKGNvbXBpbGVyLCBzdGVwT3BDb2RlUG9zLCBzdGVwVHlwZSk7Ci0gICAgICBpZihtaWdodEJlUHJveGltYXRlKQotICAgICAgICByZXR1cm4gZmFsc2U7Ci0KLSAgICAgIHN3aXRjaCAoc3RlcFR5cGUpCi0gICAgICB7Ci0gICAgICBjYXNlIE9wQ29kZXMuRlJPTV9GT0xMT1dJTkcgOgotICAgICAgY2FzZSBPcENvZGVzLkZST01fRk9MTE9XSU5HX1NJQkxJTkdTIDoKLSAgICAgIGNhc2UgT3BDb2Rlcy5GUk9NX1BSRUNFRElORyA6Ci0gICAgICBjYXNlIE9wQ29kZXMuRlJPTV9QUkVDRURJTkdfU0lCTElOR1MgOgotICAgICAgY2FzZSBPcENvZGVzLkZST01fUEFSRU5UIDoKLSAgICAgIGNhc2UgT3BDb2Rlcy5PUF9WQVJJQUJMRSA6Ci0gICAgICBjYXNlIE9wQ29kZXMuT1BfRVhURlVOQ1RJT04gOgotICAgICAgY2FzZSBPcENvZGVzLk9QX0ZVTkNUSU9OIDoKLSAgICAgIGNhc2UgT3BDb2Rlcy5PUF9HUk9VUCA6Ci0gICAgICBjYXNlIE9wQ29kZXMuRlJPTV9OQU1FU1BBQ0UgOgotICAgICAgY2FzZSBPcENvZGVzLkZST01fQU5DRVNUT1JTIDoKLSAgICAgIGNhc2UgT3BDb2Rlcy5GUk9NX0FOQ0VTVE9SU19PUl9TRUxGIDoKLSAgICAgIGNhc2UgT3BDb2Rlcy5GUk9NX0FUVFJJQlVURVMgOgotICAgICAgY2FzZSBPcENvZGVzLk1BVENIX0FUVFJJQlVURSA6Ci0gICAgICBjYXNlIE9wQ29kZXMuTUFUQ0hfQU5ZX0FOQ0VTVE9SIDoKLSAgICAgIGNhc2UgT3BDb2Rlcy5NQVRDSF9JTU1FRElBVEVfQU5DRVNUT1IgOgotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICBjYXNlIE9wQ29kZXMuRlJPTV9ST09UIDoKLSAgICAgICAgaWYoMSAhPSBzdGVwQ291bnQpCi0gICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICBicmVhazsKLSAgICAgIGNhc2UgT3BDb2Rlcy5GUk9NX0NISUxEUkVOIDoKLSAgICAgICAgaWYoIWZvdW5kRFMgJiYgIShmb3VuZERvckRTICYmIGZvdW5kU2VsZikpCi0gICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICBicmVhazsKLSAgICAgIGNhc2UgT3BDb2Rlcy5GUk9NX0RFU0NFTkRBTlRTX09SX1NFTEYgOgotICAgICAgICBmb3VuZERTID0gdHJ1ZTsKLSAgICAgIGNhc2UgT3BDb2Rlcy5GUk9NX0RFU0NFTkRBTlRTIDoKLSAgICAgICAgaWYoMyA9PSBzdGVwQ291bnQpCi0gICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICBmb3VuZERvckRTID0gdHJ1ZTsKLSAgICAgICAgYnJlYWs7Ci0gICAgICBjYXNlIE9wQ29kZXMuRlJPTV9TRUxGIDoKLSAgICAgICAgaWYoMSAhPSBzdGVwQ291bnQpCi0gICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICBmb3VuZFNlbGYgPSB0cnVlOwotICAgICAgICBicmVhazsKLSAgICAgIGRlZmF1bHQgOgotICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoWFBBVEhFcnJvclJlc291cmNlcy5FUl9OVUxMX0VSUk9SX0hBTkRMRVIsIG5ldyBPYmplY3RbXXtJbnRlZ2VyLnRvU3RyaW5nKHN0ZXBUeXBlKX0pKTsgLy8iUHJvZ3JhbW1lcidzIGFzc2VydGlvbjogdW5rbm93biBvcGNvZGU6ICIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyArIHN0ZXBUeXBlKTsKLSAgICAgIH0KLQotICAgICAgbm9kZVRlc3RUeXBlID0gY29tcGlsZXIuZ2V0U3RlcFRlc3RUeXBlKHN0ZXBPcENvZGVQb3MpOwotCi0gICAgICBpbnQgbmV4dFN0ZXBPcENvZGVQb3MgPSBjb21waWxlci5nZXROZXh0U3RlcFBvcyhzdGVwT3BDb2RlUG9zKTsKLQotICAgICAgaWYgKG5leHRTdGVwT3BDb2RlUG9zIDwgMCkKLSAgICAgICAgYnJlYWs7Ci0KLSAgICAgIGlmKE9wQ29kZXMuRU5ET1AgIT0gY29tcGlsZXIuZ2V0T3AobmV4dFN0ZXBPcENvZGVQb3MpKQotICAgICAgewotICAgICAgICBpZihjb21waWxlci5jb3VudFByZWRpY2F0ZXMoc3RlcE9wQ29kZVBvcykgPiAwKQotICAgICAgICB7Ci0gICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0gICAgICB9Ci0KLSAgICAgIHN0ZXBPcENvZGVQb3MgPSBuZXh0U3RlcE9wQ29kZVBvczsKLSAgICB9Ci0KLSAgICByZXR1cm4gdHJ1ZTsKLSAgfQotCi0gIC8qKgotICAgKiBBbmFseXplIHRoZSBsb2NhdGlvbiBwYXRoIGFuZCByZXR1cm4gMzIgYml0cyB0aGF0IGdpdmUgaW5mb3JtYXRpb24gYWJvdXQKLSAgICogdGhlIGxvY2F0aW9uIHBhdGggYXMgYSB3aG9sZS4gIFNlZSB0aGUgQklUX1hYWCBjb25zdGFudHMgZm9yIG1lYW5pbmcgYWJvdXQKLSAgICogZWFjaCBvZiB0aGUgYml0cy4KLSAgICoKLSAgICogQHBhcmFtIGNvbXBpbGVyIG5vbi1udWxsIHJlZmVyZW5jZSB0byBjb21waWxlciBvYmplY3QgdGhhdCBoYXMgcHJvY2Vzc2VkCi0gICAqICAgICAgICAgICAgICAgICB0aGUgWFBhdGggb3BlcmF0aW9ucyBpbnRvIGFuIG9wY29kZSBtYXAuCi0gICAqIEBwYXJhbSBzdGVwT3BDb2RlUG9zIFRoZSBvcGNvZGUgcG9zaXRpb24gZm9yIHRoZSBzdGVwLgotICAgKiBAcGFyYW0gc3RlcEluZGV4IFRoZSB0b3AtbGV2ZWwgc3RlcCBpbmRleCB3aXRoaW5nIHRoZSBpdGVyYXRvci4KLSAgICoKLSAgICogQHJldHVybiAzMiBiaXRzIGFzIGFuIGludGVnZXIgdGhhdCBnaXZlIGluZm9ybWF0aW9uIGFib3V0IHRoZSBsb2NhdGlvbgotICAgKiBwYXRoIGFzIGEgd2hvbGUuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgaW50IGFuYWx5emUoCi0gICAgICAgICAgQ29tcGlsZXIgY29tcGlsZXIsIGludCBzdGVwT3BDb2RlUG9zLCBpbnQgc3RlcEluZGV4KQotICAgICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaW50IHN0ZXBUeXBlOwotICAgIGludCBzdGVwQ291bnQgPSAwOwotICAgIGludCBhbmFseXNpc1Jlc3VsdCA9IDB4MDAwMDAwMDA7ICAvLyAzMiBiaXRzIG9mIGFuYWx5c2lzCi0KLSAgICB3aGlsZSAoT3BDb2Rlcy5FTkRPUCAhPSAoc3RlcFR5cGUgPSBjb21waWxlci5nZXRPcChzdGVwT3BDb2RlUG9zKSkpCi0gICAgewotICAgICAgc3RlcENvdW50Kys7Ci0KLSAgICAgIC8vIFN0cmluZyBuYW1lc3BhY2UgPSBjb21waWxlci5nZXRTdGVwTlMoc3RlcE9wQ29kZVBvcyk7Ci0gICAgICAvLyBib29sZWFuIGlzTlNXaWxkID0gKG51bGwgIT0gbmFtZXNwYWNlKQotICAgICAgLy8gICAgICAgICAgICAgICAgICAgPyBuYW1lc3BhY2UuZXF1YWxzKE5vZGVUZXN0LldJTEQpIDogZmFsc2U7Ci0gICAgICAvLyBTdHJpbmcgbG9jYWxuYW1lID0gY29tcGlsZXIuZ2V0U3RlcExvY2FsTmFtZShzdGVwT3BDb2RlUG9zKTsKLSAgICAgIC8vIGJvb2xlYW4gaXNXaWxkID0gKG51bGwgIT0gbG9jYWxuYW1lKSA/IGxvY2FsbmFtZS5lcXVhbHMoTm9kZVRlc3QuV0lMRCkgOiBmYWxzZTsKLSAgICAgIGJvb2xlYW4gcHJlZEFuYWx5c2lzID0gYW5hbHl6ZVByZWRpY2F0ZShjb21waWxlciwgc3RlcE9wQ29kZVBvcywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGVwVHlwZSk7Ci0KLSAgICAgIGlmIChwcmVkQW5hbHlzaXMpCi0gICAgICAgIGFuYWx5c2lzUmVzdWx0IHw9IEJJVF9QUkVESUNBVEU7Ci0KLSAgICAgIHN3aXRjaCAoc3RlcFR5cGUpCi0gICAgICB7Ci0gICAgICBjYXNlIE9wQ29kZXMuT1BfVkFSSUFCTEUgOgotICAgICAgY2FzZSBPcENvZGVzLk9QX0VYVEZVTkNUSU9OIDoKLSAgICAgIGNhc2UgT3BDb2Rlcy5PUF9GVU5DVElPTiA6Ci0gICAgICBjYXNlIE9wQ29kZXMuT1BfR1JPVVAgOgotICAgICAgICBhbmFseXNpc1Jlc3VsdCB8PSBCSVRfRklMVEVSOwotICAgICAgICBicmVhazsKLSAgICAgIGNhc2UgT3BDb2Rlcy5GUk9NX1JPT1QgOgotICAgICAgICBhbmFseXNpc1Jlc3VsdCB8PSBCSVRfUk9PVDsKLSAgICAgICAgYnJlYWs7Ci0gICAgICBjYXNlIE9wQ29kZXMuRlJPTV9BTkNFU1RPUlMgOgotICAgICAgICBhbmFseXNpc1Jlc3VsdCB8PSBCSVRfQU5DRVNUT1I7Ci0gICAgICAgIGJyZWFrOwotICAgICAgY2FzZSBPcENvZGVzLkZST01fQU5DRVNUT1JTX09SX1NFTEYgOgotICAgICAgICBhbmFseXNpc1Jlc3VsdCB8PSBCSVRfQU5DRVNUT1JfT1JfU0VMRjsKLSAgICAgICAgYnJlYWs7Ci0gICAgICBjYXNlIE9wQ29kZXMuRlJPTV9BVFRSSUJVVEVTIDoKLSAgICAgICAgYW5hbHlzaXNSZXN1bHQgfD0gQklUX0FUVFJJQlVURTsKLSAgICAgICAgYnJlYWs7Ci0gICAgICBjYXNlIE9wQ29kZXMuRlJPTV9OQU1FU1BBQ0UgOgotICAgICAgICBhbmFseXNpc1Jlc3VsdCB8PSBCSVRfTkFNRVNQQUNFOwotICAgICAgICBicmVhazsKLSAgICAgIGNhc2UgT3BDb2Rlcy5GUk9NX0NISUxEUkVOIDoKLSAgICAgICAgYW5hbHlzaXNSZXN1bHQgfD0gQklUX0NISUxEOwotICAgICAgICBicmVhazsKLSAgICAgIGNhc2UgT3BDb2Rlcy5GUk9NX0RFU0NFTkRBTlRTIDoKLSAgICAgICAgYW5hbHlzaXNSZXN1bHQgfD0gQklUX0RFU0NFTkRBTlQ7Ci0gICAgICAgIGJyZWFrOwotICAgICAgY2FzZSBPcENvZGVzLkZST01fREVTQ0VOREFOVFNfT1JfU0VMRiA6Ci0KLSAgICAgICAgLy8gVXNlIGEgc3BlY2lhbCBiaXQgdG8gdG8gbWFrZSBzdXJlIHdlIGdldCB0aGUgcmlnaHQgYW5hbHlzaXMgb2YgIi8vZm9vIi4KLSAgICAgICAgaWYgKDIgPT0gc3RlcENvdW50ICYmIEJJVF9ST09UID09IGFuYWx5c2lzUmVzdWx0KQotICAgICAgICB7Ci0gICAgICAgICAgYW5hbHlzaXNSZXN1bHQgfD0gQklUX0FOWV9ERVNDRU5EQU5UX0ZST01fUk9PVDsKLSAgICAgICAgfQotCi0gICAgICAgIGFuYWx5c2lzUmVzdWx0IHw9IEJJVF9ERVNDRU5EQU5UX09SX1NFTEY7Ci0gICAgICAgIGJyZWFrOwotICAgICAgY2FzZSBPcENvZGVzLkZST01fRk9MTE9XSU5HIDoKLSAgICAgICAgYW5hbHlzaXNSZXN1bHQgfD0gQklUX0ZPTExPV0lORzsKLSAgICAgICAgYnJlYWs7Ci0gICAgICBjYXNlIE9wQ29kZXMuRlJPTV9GT0xMT1dJTkdfU0lCTElOR1MgOgotICAgICAgICBhbmFseXNpc1Jlc3VsdCB8PSBCSVRfRk9MTE9XSU5HX1NJQkxJTkc7Ci0gICAgICAgIGJyZWFrOwotICAgICAgY2FzZSBPcENvZGVzLkZST01fUFJFQ0VESU5HIDoKLSAgICAgICAgYW5hbHlzaXNSZXN1bHQgfD0gQklUX1BSRUNFRElORzsKLSAgICAgICAgYnJlYWs7Ci0gICAgICBjYXNlIE9wQ29kZXMuRlJPTV9QUkVDRURJTkdfU0lCTElOR1MgOgotICAgICAgICBhbmFseXNpc1Jlc3VsdCB8PSBCSVRfUFJFQ0VESU5HX1NJQkxJTkc7Ci0gICAgICAgIGJyZWFrOwotICAgICAgY2FzZSBPcENvZGVzLkZST01fUEFSRU5UIDoKLSAgICAgICAgYW5hbHlzaXNSZXN1bHQgfD0gQklUX1BBUkVOVDsKLSAgICAgICAgYnJlYWs7Ci0gICAgICBjYXNlIE9wQ29kZXMuRlJPTV9TRUxGIDoKLSAgICAgICAgYW5hbHlzaXNSZXN1bHQgfD0gQklUX1NFTEY7Ci0gICAgICAgIGJyZWFrOwotICAgICAgY2FzZSBPcENvZGVzLk1BVENIX0FUVFJJQlVURSA6Ci0gICAgICAgIGFuYWx5c2lzUmVzdWx0IHw9IChCSVRfTUFUQ0hfUEFUVEVSTiB8IEJJVF9BVFRSSUJVVEUpOwotICAgICAgICBicmVhazsKLSAgICAgIGNhc2UgT3BDb2Rlcy5NQVRDSF9BTllfQU5DRVNUT1IgOgotICAgICAgICBhbmFseXNpc1Jlc3VsdCB8PSAoQklUX01BVENIX1BBVFRFUk4gfCBCSVRfQU5DRVNUT1IpOwotICAgICAgICBicmVhazsKLSAgICAgIGNhc2UgT3BDb2Rlcy5NQVRDSF9JTU1FRElBVEVfQU5DRVNUT1IgOgotICAgICAgICBhbmFseXNpc1Jlc3VsdCB8PSAoQklUX01BVENIX1BBVFRFUk4gfCBCSVRfUEFSRU5UKTsKLSAgICAgICAgYnJlYWs7Ci0gICAgICBkZWZhdWx0IDoKLSAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfTlVMTF9FUlJPUl9IQU5ETEVSLCBuZXcgT2JqZWN0W117SW50ZWdlci50b1N0cmluZyhzdGVwVHlwZSl9KSk7IC8vIlByb2dyYW1tZXIncyBhc3NlcnRpb246IHVua25vd24gb3Bjb2RlOiAiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vKyBzdGVwVHlwZSk7Ci0gICAgICB9Ci0KLSAgICAgIGlmIChPcENvZGVzLk5PREVUWVBFX05PREUgPT0gY29tcGlsZXIuZ2V0T3Aoc3RlcE9wQ29kZVBvcyArIDMpKSAgLy8gY2hpbGQ6Om5vZGUoKQotICAgICAgewotICAgICAgICBhbmFseXNpc1Jlc3VsdCB8PSBCSVRfTk9ERVRFU1RfQU5ZOwotICAgICAgfQotCi0gICAgICBzdGVwT3BDb2RlUG9zID0gY29tcGlsZXIuZ2V0TmV4dFN0ZXBQb3Moc3RlcE9wQ29kZVBvcyk7Ci0KLSAgICAgIGlmIChzdGVwT3BDb2RlUG9zIDwgMCkKLSAgICAgICAgYnJlYWs7Ci0gICAgfQotCi0gICAgYW5hbHlzaXNSZXN1bHQgfD0gKHN0ZXBDb3VudCAmIEJJVFNfQ09VTlQpOwotCi0gICAgcmV0dXJuIGFuYWx5c2lzUmVzdWx0OwotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgdGhlIGdpdmVuIGF4aXMgZ29lcyBkb3dud29yZC4gIEJvZ3VzIG5hbWUsIGlmIHlvdSBjYW4gdGhpbmsgb2YKLSAgICogYSBiZXR0ZXIgb25lLCBwbGVhc2UgZG8gdGVsbC4gIFRoaXMgcmVhbGx5IGhhcyB0byBkbyB3aXRoIGludmVydGluZwotICAgKiBhdHRyaWJ1dGUgYXhpcy4KLSAgICogQHBhcmFtIGF4aXMgT25lIG9mIEF4aXMuWFhYLgotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGF4aXMgaXMgbm90IGEgY2hpbGQgYXhpcyBhbmQgZG9lcyBub3QgZ28gdXAgZnJvbQotICAgKiB0aGUgYXhpcyByb290LgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzRG93bndhcmRBeGlzT2ZNYW55KGludCBheGlzKQotICB7Ci0gICAgcmV0dXJuICgoQXhpcy5ERVNDRU5EQU5UT1JTRUxGID09IGF4aXMpIHx8Ci0gICAgICAgICAgKEF4aXMuREVTQ0VOREFOVCA9PSBheGlzKQotICAgICAgICAgIHx8IChBeGlzLkZPTExPV0lORyA9PSBheGlzKQotLy8gICAgICAgICAgfHwgKEF4aXMuRk9MTE9XSU5HU0lCTElORyA9PSBheGlzKQotICAgICAgICAgIHx8IChBeGlzLlBSRUNFRElORyA9PSBheGlzKQotLy8gICAgICAgICAgfHwgKEF4aXMuUFJFQ0VESU5HU0lCTElORyA9PSBheGlzKQotICAgICAgICAgICk7Ci0gIH0KLQotICAvKioKLSAgICogUmVhZCBhIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hwYXRoI2xvY2F0aW9uLXBhdGhzIj5Mb2NhdGlvblBhdGg8L2E+Ci0gICAqIGFzIGEgZ2VuZXJhbGl6ZWQgbWF0Y2ggcGF0dGVybi4gIFdoYXQgdGhpcyBtZWFucyBpcyB0aGF0IHRoZSBMb2NhdGlvblBhdGgKLSAgICogaXMgcmVhZCBiYWNrd2FyZHMsIGFzIGEgdGVzdCBvbiBhIGdpdmVuIG5vZGUsIHRvIHNlZSBpZiBpdCBtYXRjaGVzIHRoZQotICAgKiBjcml0ZXJpYSBvZiB0aGUgc2VsZWN0aW9uLCBhbmQgZW5kcyB1cCBhdCB0aGUgY29udGV4dCBub2RlLiAgRXNzZW50aWFsbHksCi0gICAqIHRoaXMgaXMgYSBiYWNrd2FyZHMgcXVlcnkgZnJvbSBhIGdpdmVuIG5vZGUsIHRvIGZpbmQgdGhlIGNvbnRleHQgbm9kZS4KLSAgICogPHA+U28sIHRoZSBzZWxlY3Rpb24gImZvby9kYXpbMl0iIGlzLCBpbiBub24tYWJyZXZpYXRlZCBleHBhbmRlZCBzeW50YXgsCi0gICAqICJzZWxmOjpub2RlKCkvZm9sbG93aW5nLXNpYmxpbmc6OmZvby9jaGlsZDo6ZGF6W3Bvc2l0aW9uKCk9Ml0iLgotICAgKiBUYWtpbmcgdGhpcyBhcyBhIG1hdGNoIHBhdHRlcm4gZm9yIGEgcHJvYmFibGUgbm9kZSwgaXQgd29ya3Mgb3V0IHRvCi0gICAqICJzZWxmOjpkYXovcGFyZW50Ojpmb29bY2hpbGQ6OmRheltwb3NpdGlvbigpPTIgYW5kIGlzUHJldlN0ZXBOb2RlKCldCi0gICAqIHByZWNlZGluZ1NpYmxpbmc6Om5vZGUoKVtpc0NvbnRleHROb2RlT2ZMb2NhdGlvblBhdGgoKV0iLCBhZGRpbmcgbWFnaWMKLSAgICogaXNQcmV2U3RlcE5vZGUgYW5kIGlzQ29udGV4dE5vZGVPZkxvY2F0aW9uUGF0aCBvcGVyYXRpb25zLiAgUHJlZGljYXRlcyBpbgotICAgKiB0aGUgbG9jYXRpb24gcGF0aCBoYXZlIHRvIGJlIGV4ZWN1dGVkIGJ5IHRoZSBmb2xsb3dpbmcgc3RlcCwKLSAgICogYmVjYXVzZSB0aGV5IGhhdmUgdG8ga25vdyB0aGUgY29udGV4dCBvZiB0aGVpciBleGVjdXRpb24uCi0gICAqCi0gICAqIEBwYXJhbSBtcGkgVGhlIE1hdGNoUGF0dGVybkl0ZXJhdG9yIHRvIHdoaWNoIHRoZSBzdGVwcyB3aWxsIGJlIGF0dGFjaGVkLgotICAgKiBAcGFyYW0gY29tcGlsZXIgVGhlIGNvbXBpbGVyIHRoYXQgaG9sZHMgdGhlIHN5bnRheCB0cmVlL29wIG1hcCB0bwotICAgKiBjb25zdHJ1Y3QgZnJvbS4KLSAgICogQHBhcmFtIHN0ZXBPcENvZGVQb3MgVGhlIGN1cnJlbnQgb3AgY29kZSBwb3NpdGlvbiB3aXRoaW4gdGhlIG9wbWFwLgotICAgKiBAcGFyYW0gc3RlcEluZGV4IFRoZSB0b3AtbGV2ZWwgc3RlcCBpbmRleCB3aXRoaW5nIHRoZSBpdGVyYXRvci4KLSAgICoKLSAgICogQHJldHVybiBBIFN0ZXBQYXR0ZXJuIG9iamVjdCwgd2hpY2ggbWF5IGNvbnRhaW4gcmVsYXRpdmUgU3RlcFBhdHRlcm5zLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHN0YXRpYyBTdGVwUGF0dGVybiBsb2FkU3RlcHMoCi0gICAgICAgICAgTWF0Y2hQYXR0ZXJuSXRlcmF0b3IgbXBpLCBDb21waWxlciBjb21waWxlciwgaW50IHN0ZXBPcENvZGVQb3MsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHN0ZXBJbmRleCkKLSAgICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICBpZiAoREVCVUdfUEFUVEVSTl9DUkVBVElPTikKLSAgICB7Ci0gICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIj09PT09PT09PT09PT09PT0iKTsKLSAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigibG9hZFN0ZXBzIGZvcjogIitjb21waWxlci5nZXRQYXR0ZXJuU3RyaW5nKCkpOwotICAgIH0KLSAgICBpbnQgc3RlcFR5cGU7Ci0gICAgU3RlcFBhdHRlcm4gc3RlcCA9IG51bGw7Ci0gICAgU3RlcFBhdHRlcm4gZmlyc3RTdGVwID0gbnVsbCwgcHJldlN0ZXAgPSBudWxsOwotICAgIGludCBhbmFseXNpcyA9IGFuYWx5emUoY29tcGlsZXIsIHN0ZXBPcENvZGVQb3MsIHN0ZXBJbmRleCk7Ci0KLSAgICB3aGlsZSAoT3BDb2Rlcy5FTkRPUCAhPSAoc3RlcFR5cGUgPSBjb21waWxlci5nZXRPcChzdGVwT3BDb2RlUG9zKSkpCi0gICAgewotICAgICAgc3RlcCA9IGNyZWF0ZURlZmF1bHRTdGVwUGF0dGVybihjb21waWxlciwgc3RlcE9wQ29kZVBvcywgbXBpLCBhbmFseXNpcywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlyc3RTdGVwLCBwcmV2U3RlcCk7Ci0KLSAgICAgIGlmIChudWxsID09IGZpcnN0U3RlcCkKLSAgICAgIHsKLSAgICAgICAgZmlyc3RTdGVwID0gc3RlcDsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLQotICAgICAgICAvL3ByZXZTdGVwLnNldE5leHRXYWxrZXIoc3RlcCk7Ci0gICAgICAgIHN0ZXAuc2V0UmVsYXRpdmVQYXRoUGF0dGVybihwcmV2U3RlcCk7Ci0gICAgICB9Ci0KLSAgICAgIHByZXZTdGVwID0gc3RlcDsKLSAgICAgIHN0ZXBPcENvZGVQb3MgPSBjb21waWxlci5nZXROZXh0U3RlcFBvcyhzdGVwT3BDb2RlUG9zKTsKLQotICAgICAgaWYgKHN0ZXBPcENvZGVQb3MgPCAwKQotICAgICAgICBicmVhazsKLSAgICB9Ci0KLSAgICBpbnQgYXhpcyA9IEF4aXMuU0VMRjsKLSAgICBpbnQgcGF4aXMgPSBBeGlzLlNFTEY7Ci0gICAgU3RlcFBhdHRlcm4gdGFpbCA9IHN0ZXA7Ci0gICAgZm9yIChTdGVwUGF0dGVybiBwYXQgPSBzdGVwOyBudWxsICE9IHBhdDsKLSAgICAgICAgIHBhdCA9IHBhdC5nZXRSZWxhdGl2ZVBhdGhQYXR0ZXJuKCkpCi0gICAgewotICAgICAgaW50IG5leHRBeGlzID0gcGF0LmdldEF4aXMoKTsKLSAgICAgIC8vaW50IG5leHRQYXhpcyA9IHBhdC5nZXRQcmVkaWNhdGVBeGlzKCk7Ci0gICAgICBwYXQuc2V0QXhpcyhheGlzKTsKLQotICAgICAgLy8gVGhlIHByZWRpY2F0ZSBheGlzIGNhbid0IGJlIG1vdmVkISEhICBUZXN0IEF4ZXMxMDMKLSAgICAgIC8vIHBhdC5zZXRQcmVkaWNhdGVBeGlzKHBheGlzKTsKLQotICAgICAgLy8gSWYgd2UgaGF2ZSBhbiBhdHRyaWJ1dGUgb3IgbmFtZXNwYWNlIGF4aXMgdGhhdCB3ZW50IHVwLCB0aGVuCi0gICAgICAvLyBpdCB3b24ndCBmaW5kIHRoZSBhdHRyaWJ1dGUgaW4gdGhlIGludmVyc2UsIHNpbmNlIHRoZSBzZWxlY3QtdG8tbWF0Y2gKLSAgICAgIC8vIGF4ZXMgYXJlIG5vdCBpbnZlcnRhYmxlIChhbiBlbGVtZW50IGlzIGEgcGFyZW50IG9mIGFuIGF0dHJpYnV0ZSwgYnV0Ci0gICAgICAvLyBhbmQgYXR0cmlidXRlIGlzIG5vdCBhIGNoaWxkIG9mIGFuIGVsZW1lbnQpLgotICAgICAgLy8gSWYgd2UgZG9uJ3QgZG8gdGhlIG1hZ2ljIGJlbG93LCB0aGVuICJAKi9hbmNlc3Rvci1vci1zZWxmOjoqIiBnZXRzCi0gICAgICAvLyBpbnZlcnRlZCBmb3IgbWF0Y2ggdG8gInNlbGY6OiovZGVzY2VuZGFudC1vci1zZWxmOjpAKi9wYXJlbnQ6Om5vZGUoKSIsCi0gICAgICAvLyB3aGljaCBvYnZpb3VzbHkgd29uJ3Qgd29yay4KLSAgICAgIC8vIFNvIHdlIHdpbGwgcmV3cml0ZSB0aGlzIGFzOgotICAgICAgLy8gInNlbGY6OiovZGVzY2VuZGFudC1vci1zZWxmOjoqL2F0dHJpYnV0ZTo6Ki9wYXJlbnQ6Om5vZGUoKSIKLSAgICAgIC8vIENoaWxkIGhhcyB0byBiZSByZXdyaXR0ZW4gYSBsaXR0bGUgZGlmZmVyZW50bHk6Ci0gICAgICAvLyBzZWxlY3Q6ICJAKi9wYXJlbnQ6OioiCi0gICAgICAvLyBpbnZlcnRlZCBtYXRjaDogInNlbGY6OiovY2hpbGQ6OkAqL3BhcmVudDo6bm9kZSgpIgotICAgICAgLy8gcmV3cml0ZTogInNlbGY6OiovYXR0cmlidXRlOjoqL3BhcmVudDo6bm9kZSgpIgotICAgICAgLy8gQXhlcyB0aGF0IGdvIGRvd24gaW4gdGhlIHNlbGVjdCwgZG8gbm90IGhhdmUgdG8gaGF2ZSBzcGVjaWFsIHRyZWF0bWVudAotICAgICAgLy8gaW4gdGhlIHJld3JpdGUuIFRoZSBmb2xsb3dpbmcgaW52ZXJ0ZWQgbWF0Y2ggd2lsbCBzdGlsbCBub3Qgc2VsZWN0Ci0gICAgICAvLyBhbnl0aGluZy4KLSAgICAgIC8vIHNlbGVjdDogIkAqL2NoaWxkOjoqIgotICAgICAgLy8gaW52ZXJ0ZWQgbWF0Y2g6ICJzZWxmOjoqL3BhcmVudDo6QCovcGFyZW50Ojpub2RlKCkiCi0gICAgICAvLyBMb3ZlbHkgYnVzaW5lc3MsIHRoaXMuCi0gICAgICAvLyAtc2IKLSAgICAgIGludCB3aGF0VG9TaG93ID0gcGF0LmdldFdoYXRUb1Nob3coKTsKLSAgICAgIGlmKHdoYXRUb1Nob3cgPT0gRFRNRmlsdGVyLlNIT1dfQVRUUklCVVRFIHx8Ci0gICAgICAgICB3aGF0VG9TaG93ID09IERUTUZpbHRlci5TSE9XX05BTUVTUEFDRSkKLSAgICAgIHsKLSAgICAgICAgaW50IG5ld0F4aXMgPSAod2hhdFRvU2hvdyA9PSBEVE1GaWx0ZXIuU0hPV19BVFRSSUJVVEUpID8KLSAgICAgICAgICAgICAgICAgICAgICAgQXhpcy5BVFRSSUJVVEUgOiBBeGlzLk5BTUVTUEFDRTsKLSAgICAgICAgaWYoaXNEb3dud2FyZEF4aXNPZk1hbnkoYXhpcykpCi0gICAgICAgIHsKLSAgICAgICAgICBTdGVwUGF0dGVybiBhdHRyUGF0ID0gbmV3IFN0ZXBQYXR0ZXJuKHdoYXRUb1Nob3csCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXQuZ2V0TmFtZXNwYWNlKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXQuZ2V0TG9jYWxOYW1lKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vbmV3QXhpcywgcGF0LmdldFByZWRpY2F0ZUF4aXMpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3QXhpcywgMCk7IC8vIGRvbid0IGNhcmUgYWJvdXQgdGhlIHByZWRpY2F0ZSBheGlzCi0gICAgICAgICAgWE51bWJlciBzY29yZSA9IHBhdC5nZXRTdGF0aWNTY29yZSgpOwotICAgICAgICAgIHBhdC5zZXROYW1lc3BhY2UobnVsbCk7Ci0gICAgICAgICAgcGF0LnNldExvY2FsTmFtZShOb2RlVGVzdC5XSUxEKTsKLSAgICAgICAgICBhdHRyUGF0LnNldFByZWRpY2F0ZXMocGF0LmdldFByZWRpY2F0ZXMoKSk7Ci0gICAgICAgICAgcGF0LnNldFByZWRpY2F0ZXMobnVsbCk7Ci0gICAgICAgICAgcGF0LnNldFdoYXRUb1Nob3coRFRNRmlsdGVyLlNIT1dfRUxFTUVOVCk7Ci0gICAgICAgICAgU3RlcFBhdHRlcm4gcmVsID0gcGF0LmdldFJlbGF0aXZlUGF0aFBhdHRlcm4oKTsKLSAgICAgICAgICBwYXQuc2V0UmVsYXRpdmVQYXRoUGF0dGVybihhdHRyUGF0KTsKLSAgICAgICAgICBhdHRyUGF0LnNldFJlbGF0aXZlUGF0aFBhdHRlcm4ocmVsKTsKLSAgICAgICAgICBhdHRyUGF0LnNldFN0YXRpY1Njb3JlKHNjb3JlKTsKLQotICAgICAgICAgIC8vIFRoaXMgaXMgbmVlZGVkIHRvIGludmVyc2UgYSBmb2xsb3dpbmcgcGF0dGVybiwgYmVjYXVzZSBvZiB0aGUKLSAgICAgICAgICAvLyB3YWNreSBYYWxhbiBydWxlcyBmb3IgZm9sbG93aW5nIGZyb20gYW4gYXR0cmlidXRlLiAgU2VlIGF4ZXMxMDguCi0gICAgICAgICAgLy8gQnkgdGhlc2UgcnVsZXMsIGZvbGxvd2luZyBmcm9tIGFuIGF0dHJpYnV0ZSBpcyBub3Qgc3RyaWN0bHkKLSAgICAgICAgICAvLyBpbnZlcnNlYWJsZS4KLSAgICAgICAgICBpZihBeGlzLlBSRUNFRElORyA9PSBwYXQuZ2V0QXhpcygpKQotICAgICAgICAgICAgcGF0LnNldEF4aXMoQXhpcy5QUkVDRURJTkdBTkRBTkNFU1RPUik7Ci0KLSAgICAgICAgICBlbHNlIGlmKEF4aXMuREVTQ0VOREFOVCA9PSBwYXQuZ2V0QXhpcygpKQotICAgICAgICAgICAgcGF0LnNldEF4aXMoQXhpcy5ERVNDRU5EQU5UT1JTRUxGKTsKLQotICAgICAgICAgIHBhdCA9IGF0dHJQYXQ7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZihBeGlzLkNISUxEID09IHBhdC5nZXRBeGlzKCkpCi0gICAgICAgIHsKLSAgICAgICAgICAvLyBJbiB0aGlzIGNhc2UganVzdCBjaGFuZ2UgdGhlIGF4aXMuCi0gICAgICAgICAgLy8gcGF0LnNldFdoYXRUb1Nob3cod2hhdFRvU2hvdyk7Ci0gICAgICAgICAgcGF0LnNldEF4aXMoQXhpcy5BVFRSSUJVVEUpOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgICBheGlzID0gbmV4dEF4aXM7Ci0gICAgICAvL3BheGlzID0gbmV4dFBheGlzOwotICAgICAgdGFpbCA9IHBhdDsKLSAgICB9Ci0KLSAgICBpZihheGlzIDwgQXhpcy5BTEwpCi0gICAgewotICAgICAgU3RlcFBhdHRlcm4gc2VsZlBhdHRlcm4gPSBuZXcgQ29udGV4dE1hdGNoU3RlcFBhdHRlcm4oYXhpcywgcGF4aXMpOwotICAgICAgLy8gV2UgbmVlZCB0byBrZWVwIHRoZSBuZXcgbm9kZXRlc3QgZnJvbSBhZmZlY3RpbmcgdGhlIHNjb3JlLi4uCi0gICAgICBYTnVtYmVyIHNjb3JlID0gdGFpbC5nZXRTdGF0aWNTY29yZSgpOwotICAgICAgdGFpbC5zZXRSZWxhdGl2ZVBhdGhQYXR0ZXJuKHNlbGZQYXR0ZXJuKTsKLSAgICAgIHRhaWwuc2V0U3RhdGljU2NvcmUoc2NvcmUpOwotICAgICAgc2VsZlBhdHRlcm4uc2V0U3RhdGljU2NvcmUoc2NvcmUpOwotICAgIH0KLQotICAgIGlmIChERUJVR19QQVRURVJOX0NSRUFUSU9OKQotICAgIHsKLSAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiRG9uZSBsb2FkaW5nIHN0ZXBzOiAiK3N0ZXAudG9TdHJpbmcoKSk7Ci0KLSAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiIik7Ci0gICAgfQotICAgIHJldHVybiBzdGVwOyAgLy8gc3RhcnQgZnJvbSBsYXN0IHBhdHRlcm4/PyAvL2ZpcnN0U3RlcDsKLSAgfQotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBTdGVwUGF0dGVybiB0aGF0IGlzIGNvbnRhaW5lZCB3aXRoaW4gYSBMb2NhdGlvblBhdGguCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBjb21waWxlciBUaGUgY29tcGlsZXIgdGhhdCBob2xkcyB0aGUgc3ludGF4IHRyZWUvb3AgbWFwIHRvCi0gICAqIGNvbnN0cnVjdCBmcm9tLgotICAgKiBAcGFyYW0gc3RlcE9wQ29kZVBvcyBUaGUgY3VycmVudCBvcCBjb2RlIHBvc2l0aW9uIHdpdGhpbiB0aGUgb3BtYXAuCi0gICAqIEBwYXJhbSBtcGkgVGhlIE1hdGNoUGF0dGVybkl0ZXJhdG9yIHRvIHdoaWNoIHRoZSBzdGVwcyB3aWxsIGJlIGF0dGFjaGVkLgotICAgKiBAcGFyYW0gYW5hbHlzaXMgMzIgYml0cyBvZiBhbmFseXNpcywgZnJvbSB3aGljaCB0aGUgdHlwZSBvZiBBeGVzV2Fsa2VyCi0gICAqICAgICAgICAgICAgICAgICBtYXkgYmUgaW5mbHVlbmNlZC4KLSAgICogQHBhcmFtIHRhaWwgVGhlIHN0ZXAgdGhhdCBpcyB0aGUgZmlyc3Qgc3RlcCBhbmFseXplZCwgYnV0IHRoZSBsYXN0Ci0gICAqICAgICAgICAgICAgICAgICAgc3RlcCBpbiB0aGUgcmVsYXRpdmUgbWF0Y2ggbGlua2VkIGxpc3QsIGkuZS4gdGhlIHRhaWwuCi0gICAqICAgICAgICAgICAgICAgICAgTWF5IGJlIG51bGwuCi0gICAqIEBwYXJhbSBoZWFkIFRoZSBzdGVwIHRoYXQgaXMgdGhlIGN1cnJlbnQgaGVhZCBvZiB0aGUgcmVsYXRpdmUKLSAgICogICAgICAgICAgICAgICAgIG1hdGNoIHN0ZXAgbGlua2VkIGxpc3QuCi0gICAqICAgICAgICAgICAgICAgICBNYXkgYmUgbnVsbC4KLSAgICoKLSAgICogQHJldHVybiB0aGUgaGVhZCBvZiB0aGUgbGlzdC4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwcml2YXRlIHN0YXRpYyBTdGVwUGF0dGVybiBjcmVhdGVEZWZhdWx0U3RlcFBhdHRlcm4oCi0gICAgICAgICAgQ29tcGlsZXIgY29tcGlsZXIsIGludCBvcFBvcywgTWF0Y2hQYXR0ZXJuSXRlcmF0b3IgbXBpLAotICAgICAgICAgIGludCBhbmFseXNpcywgU3RlcFBhdHRlcm4gdGFpbCwgU3RlcFBhdHRlcm4gaGVhZCkKLSAgICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGludCBzdGVwVHlwZSA9IGNvbXBpbGVyLmdldE9wKG9wUG9zKTsKLSAgICBib29sZWFuIHNpbXBsZUluaXQgPSBmYWxzZTsKLSAgICBib29sZWFuIHByZXZJc09uZVN0ZXBEb3duID0gdHJ1ZTsKLQotICAgIGludCB3aGF0VG9TaG93ID0gY29tcGlsZXIuZ2V0V2hhdFRvU2hvdyhvcFBvcyk7Ci0gICAgU3RlcFBhdHRlcm4gYWkgPSBudWxsOwotICAgIGludCBheGlzLCBwcmVkaWNhdGVBeGlzOwotCi0gICAgc3dpdGNoIChzdGVwVHlwZSkKLSAgICB7Ci0gICAgY2FzZSBPcENvZGVzLk9QX1ZBUklBQkxFIDoKLSAgICBjYXNlIE9wQ29kZXMuT1BfRVhURlVOQ1RJT04gOgotICAgIGNhc2UgT3BDb2Rlcy5PUF9GVU5DVElPTiA6Ci0gICAgY2FzZSBPcENvZGVzLk9QX0dST1VQIDoKLSAgICAgIHByZXZJc09uZVN0ZXBEb3duID0gZmFsc2U7Ci0KLSAgICAgIEV4cHJlc3Npb24gZXhwcjsKLQotICAgICAgc3dpdGNoIChzdGVwVHlwZSkKLSAgICAgIHsKLSAgICAgIGNhc2UgT3BDb2Rlcy5PUF9WQVJJQUJMRSA6Ci0gICAgICBjYXNlIE9wQ29kZXMuT1BfRVhURlVOQ1RJT04gOgotICAgICAgY2FzZSBPcENvZGVzLk9QX0ZVTkNUSU9OIDoKLSAgICAgIGNhc2UgT3BDb2Rlcy5PUF9HUk9VUCA6Ci0gICAgICAgIGV4cHIgPSBjb21waWxlci5jb21waWxlKG9wUG9zKTsKLSAgICAgICAgYnJlYWs7Ci0gICAgICBkZWZhdWx0IDoKLSAgICAgICAgZXhwciA9IGNvbXBpbGVyLmNvbXBpbGUob3BQb3MgKyAyKTsKLSAgICAgIH0KLQotICAgICAgYXhpcyA9IEF4aXMuRklMVEVSRURMSVNUOwotICAgICAgcHJlZGljYXRlQXhpcyA9IEF4aXMuRklMVEVSRURMSVNUOwotICAgICAgYWkgPSBuZXcgRnVuY3Rpb25QYXR0ZXJuKGV4cHIsIGF4aXMsIHByZWRpY2F0ZUF4aXMpOwotICAgICAgc2ltcGxlSW5pdCA9IHRydWU7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIE9wQ29kZXMuRlJPTV9ST09UIDoKLSAgICAgIHdoYXRUb1Nob3cgPSBEVE1GaWx0ZXIuU0hPV19ET0NVTUVOVAotICAgICAgICAgICAgICAgICAgIHwgRFRNRmlsdGVyLlNIT1dfRE9DVU1FTlRfRlJBR01FTlQ7Ci0KLSAgICAgIGF4aXMgPSBBeGlzLlJPT1Q7Ci0gICAgICBwcmVkaWNhdGVBeGlzID0gQXhpcy5ST09UOwotICAgICAgYWkgPSBuZXcgU3RlcFBhdHRlcm4oRFRNRmlsdGVyLlNIT1dfRE9DVU1FTlQgfAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEVE1GaWx0ZXIuU0hPV19ET0NVTUVOVF9GUkFHTUVOVCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXhpcywgcHJlZGljYXRlQXhpcyk7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIE9wQ29kZXMuRlJPTV9BVFRSSUJVVEVTIDoKLSAgICAgIHdoYXRUb1Nob3cgPSBEVE1GaWx0ZXIuU0hPV19BVFRSSUJVVEU7Ci0gICAgICBheGlzID0gQXhpcy5QQVJFTlQ7Ci0gICAgICBwcmVkaWNhdGVBeGlzID0gQXhpcy5BVFRSSUJVVEU7Ci0gICAgICAvLyBhaSA9IG5ldyBTdGVwUGF0dGVybih3aGF0VG9TaG93LCBBeGlzLlNFTEYsIEF4aXMuU0VMRik7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIE9wQ29kZXMuRlJPTV9OQU1FU1BBQ0UgOgotICAgICAgd2hhdFRvU2hvdyA9IERUTUZpbHRlci5TSE9XX05BTUVTUEFDRTsKLSAgICAgIGF4aXMgPSBBeGlzLlBBUkVOVDsKLSAgICAgIHByZWRpY2F0ZUF4aXMgPSBBeGlzLk5BTUVTUEFDRTsKLSAgICAgIC8vIGFpID0gbmV3IFN0ZXBQYXR0ZXJuKHdoYXRUb1Nob3csIGF4aXMsIHByZWRpY2F0ZUF4aXMpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBPcENvZGVzLkZST01fQU5DRVNUT1JTIDoKLSAgICAgIGF4aXMgPSBBeGlzLkRFU0NFTkRBTlQ7Ci0gICAgICBwcmVkaWNhdGVBeGlzID0gQXhpcy5BTkNFU1RPUjsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgT3BDb2Rlcy5GUk9NX0NISUxEUkVOIDoKLSAgICAgIGF4aXMgPSBBeGlzLlBBUkVOVDsKLSAgICAgIHByZWRpY2F0ZUF4aXMgPSBBeGlzLkNISUxEOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBPcENvZGVzLkZST01fQU5DRVNUT1JTX09SX1NFTEYgOgotICAgICAgYXhpcyA9IEF4aXMuREVTQ0VOREFOVE9SU0VMRjsKLSAgICAgIHByZWRpY2F0ZUF4aXMgPSBBeGlzLkFOQ0VTVE9ST1JTRUxGOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBPcENvZGVzLkZST01fU0VMRiA6Ci0gICAgICBheGlzID0gQXhpcy5TRUxGOwotICAgICAgcHJlZGljYXRlQXhpcyA9IEF4aXMuU0VMRjsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgT3BDb2Rlcy5GUk9NX1BBUkVOVCA6Ci0gICAgICBheGlzID0gQXhpcy5DSElMRDsKLSAgICAgIHByZWRpY2F0ZUF4aXMgPSBBeGlzLlBBUkVOVDsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgT3BDb2Rlcy5GUk9NX1BSRUNFRElOR19TSUJMSU5HUyA6Ci0gICAgICBheGlzID0gQXhpcy5GT0xMT1dJTkdTSUJMSU5HOwotICAgICAgcHJlZGljYXRlQXhpcyA9IEF4aXMuUFJFQ0VESU5HU0lCTElORzsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgT3BDb2Rlcy5GUk9NX1BSRUNFRElORyA6Ci0gICAgICBheGlzID0gQXhpcy5GT0xMT1dJTkc7Ci0gICAgICBwcmVkaWNhdGVBeGlzID0gQXhpcy5QUkVDRURJTkc7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIE9wQ29kZXMuRlJPTV9GT0xMT1dJTkdfU0lCTElOR1MgOgotICAgICAgYXhpcyA9IEF4aXMuUFJFQ0VESU5HU0lCTElORzsKLSAgICAgIHByZWRpY2F0ZUF4aXMgPSBBeGlzLkZPTExPV0lOR1NJQkxJTkc7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIE9wQ29kZXMuRlJPTV9GT0xMT1dJTkcgOgotICAgICAgYXhpcyA9IEF4aXMuUFJFQ0VESU5HOwotICAgICAgcHJlZGljYXRlQXhpcyA9IEF4aXMuRk9MTE9XSU5HOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBPcENvZGVzLkZST01fREVTQ0VOREFOVFNfT1JfU0VMRiA6Ci0gICAgICBheGlzID0gQXhpcy5BTkNFU1RPUk9SU0VMRjsKLSAgICAgIHByZWRpY2F0ZUF4aXMgPSBBeGlzLkRFU0NFTkRBTlRPUlNFTEY7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIE9wQ29kZXMuRlJPTV9ERVNDRU5EQU5UUyA6Ci0gICAgICBheGlzID0gQXhpcy5BTkNFU1RPUjsKLSAgICAgIHByZWRpY2F0ZUF4aXMgPSBBeGlzLkRFU0NFTkRBTlQ7Ci0gICAgICBicmVhazsKLSAgICBkZWZhdWx0IDoKLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShYUEFUSEVycm9yUmVzb3VyY2VzLkVSX05VTExfRVJST1JfSEFORExFUiwgbmV3IE9iamVjdFtde0ludGVnZXIudG9TdHJpbmcoc3RlcFR5cGUpfSkpOyAvLyJQcm9ncmFtbWVyJ3MgYXNzZXJ0aW9uOiB1bmtub3duIG9wY29kZTogIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8rIHN0ZXBUeXBlKTsKLSAgICB9Ci0gICAgaWYobnVsbCA9PSBhaSkKLSAgICB7Ci0gICAgICB3aGF0VG9TaG93ID0gY29tcGlsZXIuZ2V0V2hhdFRvU2hvdyhvcFBvcyk7IC8vICVSRVZJRVclCi0gICAgICBhaSA9IG5ldyBTdGVwUGF0dGVybih3aGF0VG9TaG93LCBjb21waWxlci5nZXRTdGVwTlMob3BQb3MpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21waWxlci5nZXRTdGVwTG9jYWxOYW1lKG9wUG9zKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXhpcywgcHJlZGljYXRlQXhpcyk7Ci0gICAgfQotCi0gICAgaWYgKGZhbHNlIHx8IERFQlVHX1BBVFRFUk5fQ1JFQVRJT04pCi0gICAgewotICAgICAgU3lzdGVtLm91dC5wcmludCgibmV3IHN0ZXA6ICIrIGFpKTsKLSAgICAgIFN5c3RlbS5vdXQucHJpbnQoIiwgYXhpczogIiArIEF4aXMuZ2V0TmFtZXMoYWkuZ2V0QXhpcygpKSk7Ci0gICAgICBTeXN0ZW0ub3V0LnByaW50KCIsIHByZWRBeGlzOiAiICsgQXhpcy5nZXROYW1lcyhhaS5nZXRBeGlzKCkpKTsKLSAgICAgIFN5c3RlbS5vdXQucHJpbnQoIiwgd2hhdDogIik7Ci0gICAgICBTeXN0ZW0ub3V0LnByaW50KCIgICAgIik7Ci0gICAgICBhaS5kZWJ1Z1doYXRUb1Nob3coYWkuZ2V0V2hhdFRvU2hvdygpKTsKLSAgICB9Ci0KLSAgICBpbnQgYXJnTGVuID0gY29tcGlsZXIuZ2V0Rmlyc3RQcmVkaWNhdGVPcFBvcyhvcFBvcyk7Ci0KLSAgICBhaS5zZXRQcmVkaWNhdGVzKGNvbXBpbGVyLmdldENvbXBpbGVkUHJlZGljYXRlcyhhcmdMZW4pKTsKLQotICAgIHJldHVybiBhaTsKLSAgfQotCi0gIC8qKgotICAgKiBBbmFseXplIGEgc3RlcCBhbmQgZ2l2ZSBpbmZvcm1hdGlvbiBhYm91dCBpdCdzIHByZWRpY2F0ZXMuICBSaWdodCBub3cgdGhpcwotICAgKiBqdXN0IHJldHVybnMgdHJ1ZSBvciBmYWxzZSBpZiB0aGUgc3RlcCBoYXMgYSBwcmVkaWNhdGUuCi0gICAqCi0gICAqIEBwYXJhbSBjb21waWxlciBub24tbnVsbCByZWZlcmVuY2UgdG8gY29tcGlsZXIgb2JqZWN0IHRoYXQgaGFzIHByb2Nlc3NlZAotICAgKiAgICAgICAgICAgICAgICAgdGhlIFhQYXRoIG9wZXJhdGlvbnMgaW50byBhbiBvcGNvZGUgbWFwLgotICAgKiBAcGFyYW0gb3BQb3MgVGhlIG9wY29kZSBwb3NpdGlvbiBmb3IgdGhlIHN0ZXAuCi0gICAqIEBwYXJhbSBzdGVwVHlwZSBUaGUgdHlwZSBvZiBzdGVwLCBvbmUgb2YgT1BfR1JPVVAsIGV0Yy4KLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHN0ZXAgaGFzIGEgcHJlZGljYXRlLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHN0YXRpYyBib29sZWFuIGFuYWx5emVQcmVkaWNhdGUoQ29tcGlsZXIgY29tcGlsZXIsIGludCBvcFBvcywgaW50IHN0ZXBUeXBlKQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGludCBhcmdMZW47Ci0KLSAgICBzd2l0Y2ggKHN0ZXBUeXBlKQotICAgIHsKLSAgICBjYXNlIE9wQ29kZXMuT1BfVkFSSUFCTEUgOgotICAgIGNhc2UgT3BDb2Rlcy5PUF9FWFRGVU5DVElPTiA6Ci0gICAgY2FzZSBPcENvZGVzLk9QX0ZVTkNUSU9OIDoKLSAgICBjYXNlIE9wQ29kZXMuT1BfR1JPVVAgOgotICAgICAgYXJnTGVuID0gY29tcGlsZXIuZ2V0QXJnTGVuZ3RoKG9wUG9zKTsKLSAgICAgIGJyZWFrOwotICAgIGRlZmF1bHQgOgotICAgICAgYXJnTGVuID0gY29tcGlsZXIuZ2V0QXJnTGVuZ3RoT2ZTdGVwKG9wUG9zKTsKLSAgICB9Ci0KLSAgICBpbnQgcG9zID0gY29tcGlsZXIuZ2V0Rmlyc3RQcmVkaWNhdGVPcFBvcyhvcFBvcyk7Ci0gICAgaW50IG5QcmVkaWNhdGVzID0gY29tcGlsZXIuY291bnRQcmVkaWNhdGVzKHBvcyk7Ci0KLSAgICByZXR1cm4gKG5QcmVkaWNhdGVzID4gMCkgPyB0cnVlIDogZmFsc2U7Ci0gIH0KLQotICAvKioKLSAgICogQ3JlYXRlIHRoZSBwcm9wZXIgV2Fsa2VyIGZyb20gdGhlIGF4ZXMgdHlwZS4KLSAgICoKLSAgICogQHBhcmFtIGNvbXBpbGVyIG5vbi1udWxsIHJlZmVyZW5jZSB0byBjb21waWxlciBvYmplY3QgdGhhdCBoYXMgcHJvY2Vzc2VkCi0gICAqICAgICAgICAgICAgICAgICB0aGUgWFBhdGggb3BlcmF0aW9ucyBpbnRvIGFuIG9wY29kZSBtYXAuCi0gICAqIEBwYXJhbSBvcFBvcyBUaGUgb3Bjb2RlIHBvc2l0aW9uIGZvciB0aGUgc3RlcC4KLSAgICogQHBhcmFtIGxwaSBUaGUgb3duaW5nIGxvY2F0aW9uIHBhdGggaXRlcmF0b3IuCi0gICAqIEBwYXJhbSBhbmFseXNpcyAzMiBiaXRzIG9mIGFuYWx5c2lzLCBmcm9tIHdoaWNoIHRoZSB0eXBlIG9mIEF4ZXNXYWxrZXIKLSAgICogICAgICAgICAgICAgICAgIG1heSBiZSBpbmZsdWVuY2VkLgotICAgKgotICAgKiBAcmV0dXJuIG5vbi1udWxsIHJlZmVyZW5jZSB0byBBeGVzV2Fsa2VyIGRlcml2YXRpdmUuCi0gICAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiBpZiB0aGUgaW5wdXQgaXMgYmFkLgotICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgQXhlc1dhbGtlciBjcmVhdGVEZWZhdWx0V2Fsa2VyKENvbXBpbGVyIGNvbXBpbGVyLCBpbnQgb3BQb3MsCi0gICAgICAgICAgV2Fsa2luZ0l0ZXJhdG9yIGxwaSwgaW50IGFuYWx5c2lzKQotICB7Ci0KLSAgICBBeGVzV2Fsa2VyIGFpID0gbnVsbDsKLSAgICBpbnQgc3RlcFR5cGUgPSBjb21waWxlci5nZXRPcChvcFBvcyk7Ci0KLSAgICAvKgotICAgIFN5c3RlbS5vdXQucHJpbnRsbigiMDogIitjb21waWxlci5nZXRPcChvcFBvcykpOwotICAgIFN5c3RlbS5vdXQucHJpbnRsbigiMTogIitjb21waWxlci5nZXRPcChvcFBvcysxKSk7Ci0gICAgU3lzdGVtLm91dC5wcmludGxuKCIyOiAiK2NvbXBpbGVyLmdldE9wKG9wUG9zKzIpKTsKLSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIjM6ICIrY29tcGlsZXIuZ2V0T3Aob3BQb3MrMykpOwotICAgIFN5c3RlbS5vdXQucHJpbnRsbigiNDogIitjb21waWxlci5nZXRPcChvcFBvcys0KSk7Ci0gICAgU3lzdGVtLm91dC5wcmludGxuKCI1OiAiK2NvbXBpbGVyLmdldE9wKG9wUG9zKzUpKTsKLSAgICAqLwotICAgIGJvb2xlYW4gc2ltcGxlSW5pdCA9IGZhbHNlOwotICAgIGludCB0b3RhbE51bWJlcldhbGtlcnMgPSAoYW5hbHlzaXMgJiBCSVRTX0NPVU5UKTsKLSAgICBib29sZWFuIHByZXZJc09uZVN0ZXBEb3duID0gdHJ1ZTsKLQotICAgIHN3aXRjaCAoc3RlcFR5cGUpCi0gICAgewotICAgIGNhc2UgT3BDb2Rlcy5PUF9WQVJJQUJMRSA6Ci0gICAgY2FzZSBPcENvZGVzLk9QX0VYVEZVTkNUSU9OIDoKLSAgICBjYXNlIE9wQ29kZXMuT1BfRlVOQ1RJT04gOgotICAgIGNhc2UgT3BDb2Rlcy5PUF9HUk9VUCA6Ci0gICAgICBwcmV2SXNPbmVTdGVwRG93biA9IGZhbHNlOwotCi0gICAgICBpZiAoREVCVUdfV0FMS0VSX0NSRUFUSU9OKQotICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIm5ldyB3YWxrZXI6ICBGaWx0ZXJFeHByV2Fsa2VyOiAiICsgYW5hbHlzaXMKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiwgIiArIGNvbXBpbGVyLnRvU3RyaW5nKCkpOwotCi0gICAgICBhaSA9IG5ldyBGaWx0ZXJFeHByV2Fsa2VyKGxwaSk7Ci0gICAgICBzaW1wbGVJbml0ID0gdHJ1ZTsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgT3BDb2Rlcy5GUk9NX1JPT1QgOgotICAgICAgYWkgPSBuZXcgQXhlc1dhbGtlcihscGksIEF4aXMuUk9PVCk7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIE9wQ29kZXMuRlJPTV9BTkNFU1RPUlMgOgotICAgICAgcHJldklzT25lU3RlcERvd24gPSBmYWxzZTsKLSAgICAgIGFpID0gbmV3IFJldmVyc2VBeGVzV2Fsa2VyKGxwaSwgQXhpcy5BTkNFU1RPUik7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIE9wQ29kZXMuRlJPTV9BTkNFU1RPUlNfT1JfU0VMRiA6Ci0gICAgICBwcmV2SXNPbmVTdGVwRG93biA9IGZhbHNlOwotICAgICAgYWkgPSBuZXcgUmV2ZXJzZUF4ZXNXYWxrZXIobHBpLCBBeGlzLkFOQ0VTVE9ST1JTRUxGKTsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgT3BDb2Rlcy5GUk9NX0FUVFJJQlVURVMgOgotICAgICAgYWkgPSBuZXcgQXhlc1dhbGtlcihscGksIEF4aXMuQVRUUklCVVRFKTsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgT3BDb2Rlcy5GUk9NX05BTUVTUEFDRSA6Ci0gICAgICBhaSA9IG5ldyBBeGVzV2Fsa2VyKGxwaSwgQXhpcy5OQU1FU1BBQ0UpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBPcENvZGVzLkZST01fQ0hJTERSRU4gOgotICAgICAgYWkgPSBuZXcgQXhlc1dhbGtlcihscGksIEF4aXMuQ0hJTEQpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBPcENvZGVzLkZST01fREVTQ0VOREFOVFMgOgotICAgICAgcHJldklzT25lU3RlcERvd24gPSBmYWxzZTsKLSAgICAgIGFpID0gbmV3IEF4ZXNXYWxrZXIobHBpLCBBeGlzLkRFU0NFTkRBTlQpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBPcENvZGVzLkZST01fREVTQ0VOREFOVFNfT1JfU0VMRiA6Ci0gICAgICBwcmV2SXNPbmVTdGVwRG93biA9IGZhbHNlOwotICAgICAgYWkgPSBuZXcgQXhlc1dhbGtlcihscGksIEF4aXMuREVTQ0VOREFOVE9SU0VMRik7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIE9wQ29kZXMuRlJPTV9GT0xMT1dJTkcgOgotICAgICAgcHJldklzT25lU3RlcERvd24gPSBmYWxzZTsKLSAgICAgIGFpID0gbmV3IEF4ZXNXYWxrZXIobHBpLCBBeGlzLkZPTExPV0lORyk7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIE9wQ29kZXMuRlJPTV9GT0xMT1dJTkdfU0lCTElOR1MgOgotICAgICAgcHJldklzT25lU3RlcERvd24gPSBmYWxzZTsKLSAgICAgIGFpID0gbmV3IEF4ZXNXYWxrZXIobHBpLCBBeGlzLkZPTExPV0lOR1NJQkxJTkcpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBPcENvZGVzLkZST01fUFJFQ0VESU5HIDoKLSAgICAgIHByZXZJc09uZVN0ZXBEb3duID0gZmFsc2U7Ci0gICAgICBhaSA9IG5ldyBSZXZlcnNlQXhlc1dhbGtlcihscGksIEF4aXMuUFJFQ0VESU5HKTsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgT3BDb2Rlcy5GUk9NX1BSRUNFRElOR19TSUJMSU5HUyA6Ci0gICAgICBwcmV2SXNPbmVTdGVwRG93biA9IGZhbHNlOwotICAgICAgYWkgPSBuZXcgUmV2ZXJzZUF4ZXNXYWxrZXIobHBpLCBBeGlzLlBSRUNFRElOR1NJQkxJTkcpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBPcENvZGVzLkZST01fUEFSRU5UIDoKLSAgICAgIHByZXZJc09uZVN0ZXBEb3duID0gZmFsc2U7Ci0gICAgICBhaSA9IG5ldyBSZXZlcnNlQXhlc1dhbGtlcihscGksIEF4aXMuUEFSRU5UKTsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgT3BDb2Rlcy5GUk9NX1NFTEYgOgotICAgICAgYWkgPSBuZXcgQXhlc1dhbGtlcihscGksIEF4aXMuU0VMRik7Ci0gICAgICBicmVhazsKLSAgICBkZWZhdWx0IDoKLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShYUEFUSEVycm9yUmVzb3VyY2VzLkVSX05VTExfRVJST1JfSEFORExFUiwgbmV3IE9iamVjdFtde0ludGVnZXIudG9TdHJpbmcoc3RlcFR5cGUpfSkpOyAvLyJQcm9ncmFtbWVyJ3MgYXNzZXJ0aW9uOiB1bmtub3duIG9wY29kZTogIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8rIHN0ZXBUeXBlKTsKLSAgICB9Ci0KLSAgICBpZiAoc2ltcGxlSW5pdCkKLSAgICB7Ci0gICAgICBhaS5pbml0Tm9kZVRlc3QoRFRNRmlsdGVyLlNIT1dfQUxMKTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIGludCB3aGF0VG9TaG93ID0gY29tcGlsZXIuZ2V0V2hhdFRvU2hvdyhvcFBvcyk7Ci0KLSAgICAgIC8qCi0gICAgICBTeXN0ZW0ub3V0LnByaW50KCJjb25zdHJ1Y3Q6ICIpOwotICAgICAgTm9kZVRlc3QuZGVidWdXaGF0VG9TaG93KHdoYXRUb1Nob3cpOwotICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJvciBzdHVmZjogIisod2hhdFRvU2hvdyAmIChEVE1GaWx0ZXIuU0hPV19BVFRSSUJVVEUKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBEVE1GaWx0ZXIuU0hPV19FTEVNRU5UCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgRFRNRmlsdGVyLlNIT1dfUFJPQ0VTU0lOR19JTlNUUlVDVElPTikpKTsKLSAgICAgICovCi0gICAgICBpZiAoKDAgPT0gKHdoYXRUb1Nob3cKLSAgICAgICAgICAgICAgICAgJiAoRFRNRmlsdGVyLlNIT1dfQVRUUklCVVRFIHwgRFRNRmlsdGVyLlNIT1dfTkFNRVNQQUNFIHwgRFRNRmlsdGVyLlNIT1dfRUxFTUVOVAotICAgICAgICAgICAgICAgICAgICB8IERUTUZpbHRlci5TSE9XX1BST0NFU1NJTkdfSU5TVFJVQ1RJT04pKSkgfHwgKHdoYXRUb1Nob3cgPT0gRFRNRmlsdGVyLlNIT1dfQUxMKSkKLSAgICAgICAgYWkuaW5pdE5vZGVUZXN0KHdoYXRUb1Nob3cpOwotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBhaS5pbml0Tm9kZVRlc3Qod2hhdFRvU2hvdywgY29tcGlsZXIuZ2V0U3RlcE5TKG9wUG9zKSwKLSAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBpbGVyLmdldFN0ZXBMb2NhbE5hbWUob3BQb3MpKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gYWk7Ci0gIH0KLQotICBwdWJsaWMgc3RhdGljIFN0cmluZyBnZXRBbmFseXNpc1N0cmluZyhpbnQgYW5hbHlzaXMpCi0gIHsKLSAgICBTdHJpbmdCdWZmZXIgYnVmID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotICAgIGJ1Zi5hcHBlbmQoImNvdW50OiAiKS5hcHBlbmQoZ2V0U3RlcENvdW50KGFuYWx5c2lzKSkuYXBwZW5kKCcgJyk7Ci0gICAgaWYoKGFuYWx5c2lzICYgQklUX05PREVURVNUX0FOWSkgIT0gMCkKLSAgICB7Ci0gICAgICBidWYuYXBwZW5kKCJOVEFOWXwiKTsKLSAgICB9Ci0gICAgaWYoKGFuYWx5c2lzICYgQklUX1BSRURJQ0FURSkgIT0gMCkKLSAgICB7Ci0gICAgICBidWYuYXBwZW5kKCJQUkVEfCIpOwotICAgIH0KLSAgICBpZigoYW5hbHlzaXMgJiBCSVRfQU5DRVNUT1IpICE9IDApCi0gICAgewotICAgICAgYnVmLmFwcGVuZCgiQU5DfCIpOwotICAgIH0KLSAgICBpZigoYW5hbHlzaXMgJiBCSVRfQU5DRVNUT1JfT1JfU0VMRikgIT0gMCkKLSAgICB7Ci0gICAgICBidWYuYXBwZW5kKCJBTkNPU3wiKTsKLSAgICB9Ci0gICAgaWYoKGFuYWx5c2lzICYgQklUX0FUVFJJQlVURSkgIT0gMCkKLSAgICB7Ci0gICAgICBidWYuYXBwZW5kKCJBVFRSfCIpOwotICAgIH0KLSAgICBpZigoYW5hbHlzaXMgJiBCSVRfQ0hJTEQpICE9IDApCi0gICAgewotICAgICAgYnVmLmFwcGVuZCgiQ0h8Iik7Ci0gICAgfQotICAgIGlmKChhbmFseXNpcyAmIEJJVF9ERVNDRU5EQU5UKSAhPSAwKQotICAgIHsKLSAgICAgIGJ1Zi5hcHBlbmQoIkRFU0N8Iik7Ci0gICAgfQotICAgIGlmKChhbmFseXNpcyAmIEJJVF9ERVNDRU5EQU5UX09SX1NFTEYpICE9IDApCi0gICAgewotICAgICAgYnVmLmFwcGVuZCgiREVTQ09TfCIpOwotICAgIH0KLSAgICBpZigoYW5hbHlzaXMgJiBCSVRfRk9MTE9XSU5HKSAhPSAwKQotICAgIHsKLSAgICAgIGJ1Zi5hcHBlbmQoIkZPTHwiKTsKLSAgICB9Ci0gICAgaWYoKGFuYWx5c2lzICYgQklUX0ZPTExPV0lOR19TSUJMSU5HKSAhPSAwKQotICAgIHsKLSAgICAgIGJ1Zi5hcHBlbmQoIkZPTFN8Iik7Ci0gICAgfQotICAgIGlmKChhbmFseXNpcyAmIEJJVF9OQU1FU1BBQ0UpICE9IDApCi0gICAgewotICAgICAgYnVmLmFwcGVuZCgiTlN8Iik7Ci0gICAgfQotICAgIGlmKChhbmFseXNpcyAmIEJJVF9QQVJFTlQpICE9IDApCi0gICAgewotICAgICAgYnVmLmFwcGVuZCgiUHwiKTsKLSAgICB9Ci0gICAgaWYoKGFuYWx5c2lzICYgQklUX1BSRUNFRElORykgIT0gMCkKLSAgICB7Ci0gICAgICBidWYuYXBwZW5kKCJQUkVDfCIpOwotICAgIH0KLSAgICBpZigoYW5hbHlzaXMgJiBCSVRfUFJFQ0VESU5HX1NJQkxJTkcpICE9IDApCi0gICAgewotICAgICAgYnVmLmFwcGVuZCgiUFJFQ1N8Iik7Ci0gICAgfQotICAgIGlmKChhbmFseXNpcyAmIEJJVF9TRUxGKSAhPSAwKQotICAgIHsKLSAgICAgIGJ1Zi5hcHBlbmQoIi58Iik7Ci0gICAgfQotICAgIGlmKChhbmFseXNpcyAmIEJJVF9GSUxURVIpICE9IDApCi0gICAgewotICAgICAgYnVmLmFwcGVuZCgiRkxUfCIpOwotICAgIH0KLSAgICBpZigoYW5hbHlzaXMgJiBCSVRfUk9PVCkgIT0gMCkKLSAgICB7Ci0gICAgICBidWYuYXBwZW5kKCJSfCIpOwotICAgIH0KLSAgICByZXR1cm4gYnVmLnRvU3RyaW5nKCk7Ci0gIH0KLQotICAvKiogU2V0IHRvIHRydWUgZm9yIGRpYWdub3N0aWNzIGFib3V0IHdhbGtlciBjcmVhdGlvbiAqLwotICBzdGF0aWMgZmluYWwgYm9vbGVhbiBERUJVR19QQVRURVJOX0NSRUFUSU9OID0gZmFsc2U7Ci0KLSAgLyoqIFNldCB0byB0cnVlIGZvciBkaWFnbm9zdGljcyBhYm91dCB3YWxrZXIgY3JlYXRpb24gKi8KLSAgc3RhdGljIGZpbmFsIGJvb2xlYW4gREVCVUdfV0FMS0VSX0NSRUFUSU9OID0gZmFsc2U7Ci0KLSAgLyoqIFNldCB0byB0cnVlIGZvciBkaWFnbm9zdGljcyBhYm91dCBpdGVyYXRvciBjcmVhdGlvbiAqLwotICBzdGF0aWMgZmluYWwgYm9vbGVhbiBERUJVR19JVEVSQVRPUl9DUkVBVElPTiA9IGZhbHNlOwotCi0gIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBoYXNQcmVkaWNhdGUoaW50IGFuYWx5c2lzKQotICB7Ci0gICAgcmV0dXJuICgwICE9IChhbmFseXNpcyAmIEJJVF9QUkVESUNBVEUpKTsKLSAgfQotCi0gIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc1dpbGQoaW50IGFuYWx5c2lzKQotICB7Ci0gICAgcmV0dXJuICgwICE9IChhbmFseXNpcyAmIEJJVF9OT0RFVEVTVF9BTlkpKTsKLSAgfQotCi0gIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiB3YWxrc0FuY2VzdG9ycyhpbnQgYW5hbHlzaXMpCi0gIHsKLSAgICByZXR1cm4gaXNTZXQoYW5hbHlzaXMsIEJJVF9BTkNFU1RPUiB8IEJJVF9BTkNFU1RPUl9PUl9TRUxGKTsKLSAgfQotCi0gIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiB3YWxrc0F0dHJpYnV0ZXMoaW50IGFuYWx5c2lzKQotICB7Ci0gICAgcmV0dXJuICgwICE9IChhbmFseXNpcyAmIEJJVF9BVFRSSUJVVEUpKTsKLSAgfQotCi0gIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiB3YWxrc05hbWVzcGFjZXMoaW50IGFuYWx5c2lzKQotICB7Ci0gICAgcmV0dXJuICgwICE9IChhbmFseXNpcyAmIEJJVF9OQU1FU1BBQ0UpKTsKLSAgfQotCi0gIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiB3YWxrc0NoaWxkcmVuKGludCBhbmFseXNpcykKLSAgewotICAgIHJldHVybiAoMCAhPSAoYW5hbHlzaXMgJiBCSVRfQ0hJTEQpKTsKLSAgfQotCi0gIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiB3YWxrc0Rlc2NlbmRhbnRzKGludCBhbmFseXNpcykKLSAgewotICAgIHJldHVybiBpc1NldChhbmFseXNpcywgQklUX0RFU0NFTkRBTlQgfCBCSVRfREVTQ0VOREFOVF9PUl9TRUxGKTsKLSAgfQotCi0gIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiB3YWxrc1N1YnRyZWUoaW50IGFuYWx5c2lzKQotICB7Ci0gICAgcmV0dXJuIGlzU2V0KGFuYWx5c2lzLCBCSVRfREVTQ0VOREFOVCB8IEJJVF9ERVNDRU5EQU5UX09SX1NFTEYgfCBCSVRfQ0hJTEQpOwotICB9Ci0KLSAgcHVibGljIHN0YXRpYyBib29sZWFuIHdhbGtzU3VidHJlZU9ubHlNYXliZUFic29sdXRlKGludCBhbmFseXNpcykKLSAgewotICAgIHJldHVybiB3YWxrc1N1YnRyZWUoYW5hbHlzaXMpCi0gICAgICAgICAgICYmICF3YWxrc0V4dHJhTm9kZXMoYW5hbHlzaXMpCi0gICAgICAgICAgICYmICF3YWxrc1VwKGFuYWx5c2lzKQotICAgICAgICAgICAmJiAhd2Fsa3NTaWRld2F5cyhhbmFseXNpcykKLSAgICAgICAgICAgOwotICB9Ci0KLSAgcHVibGljIHN0YXRpYyBib29sZWFuIHdhbGtzU3VidHJlZU9ubHkoaW50IGFuYWx5c2lzKQotICB7Ci0gICAgcmV0dXJuIHdhbGtzU3VidHJlZU9ubHlNYXliZUFic29sdXRlKGFuYWx5c2lzKQotICAgICAgICAgICAmJiAhaXNBYnNvbHV0ZShhbmFseXNpcykKLSAgICAgICAgICAgOwotICB9Ci0KLSAgcHVibGljIHN0YXRpYyBib29sZWFuIHdhbGtzRmlsdGVyZWRMaXN0KGludCBhbmFseXNpcykKLSAgewotICAgIHJldHVybiBpc1NldChhbmFseXNpcywgQklUX0ZJTFRFUik7Ci0gIH0KLQotICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gd2Fsa3NTdWJ0cmVlT25seUZyb21Sb290T3JDb250ZXh0KGludCBhbmFseXNpcykKLSAgewotICAgIHJldHVybiB3YWxrc1N1YnRyZWUoYW5hbHlzaXMpCi0gICAgICAgICAgICYmICF3YWxrc0V4dHJhTm9kZXMoYW5hbHlzaXMpCi0gICAgICAgICAgICYmICF3YWxrc1VwKGFuYWx5c2lzKQotICAgICAgICAgICAmJiAhd2Fsa3NTaWRld2F5cyhhbmFseXNpcykKLSAgICAgICAgICAgJiYgIWlzU2V0KGFuYWx5c2lzLCBCSVRfRklMVEVSKQotICAgICAgICAgICA7Ci0gIH0KLQotICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gd2Fsa3NJbkRvY09yZGVyKGludCBhbmFseXNpcykKLSAgewotICAgIHJldHVybiAod2Fsa3NTdWJ0cmVlT25seU1heWJlQWJzb2x1dGUoYW5hbHlzaXMpCi0gICAgICAgICAgIHx8IHdhbGtzRXh0cmFOb2Rlc09ubHkoYW5hbHlzaXMpCi0gICAgICAgICAgIHx8IHdhbGtzRm9sbG93aW5nT25seU1heWJlQWJzb2x1dGUoYW5hbHlzaXMpKQotICAgICAgICAgICAmJiAhaXNTZXQoYW5hbHlzaXMsIEJJVF9GSUxURVIpCi0gICAgICAgICAgIDsKLSAgfQotCi0gIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiB3YWxrc0ZvbGxvd2luZ09ubHlNYXliZUFic29sdXRlKGludCBhbmFseXNpcykKLSAgewotICAgIHJldHVybiBpc1NldChhbmFseXNpcywgQklUX1NFTEYgfCBCSVRfRk9MTE9XSU5HX1NJQkxJTkcgfCBCSVRfRk9MTE9XSU5HKQotICAgICAgICAgICAmJiAhd2Fsa3NTdWJ0cmVlKGFuYWx5c2lzKQotICAgICAgICAgICAmJiAhd2Fsa3NVcChhbmFseXNpcykKLSAgICAgICAgICAgJiYgIXdhbGtzU2lkZXdheXMoYW5hbHlzaXMpCi0gICAgICAgICAgIDsKLSAgfQotCi0gIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiB3YWxrc1VwKGludCBhbmFseXNpcykKLSAgewotICAgIHJldHVybiBpc1NldChhbmFseXNpcywgQklUX1BBUkVOVCB8IEJJVF9BTkNFU1RPUiB8IEJJVF9BTkNFU1RPUl9PUl9TRUxGKTsKLSAgfQotCi0gIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiB3YWxrc1NpZGV3YXlzKGludCBhbmFseXNpcykKLSAgewotICAgIHJldHVybiBpc1NldChhbmFseXNpcywgQklUX0ZPTExPV0lORyB8IEJJVF9GT0xMT1dJTkdfU0lCTElORyB8Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICBCSVRfUFJFQ0VESU5HIHwgQklUX1BSRUNFRElOR19TSUJMSU5HKTsKLSAgfQotCi0gIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiB3YWxrc0V4dHJhTm9kZXMoaW50IGFuYWx5c2lzKQotICB7Ci0gICAgcmV0dXJuIGlzU2V0KGFuYWx5c2lzLCBCSVRfTkFNRVNQQUNFIHwgQklUX0FUVFJJQlVURSk7Ci0gIH0KLQotICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gd2Fsa3NFeHRyYU5vZGVzT25seShpbnQgYW5hbHlzaXMpCi0gIHsKLSAgICByZXR1cm4gd2Fsa3NFeHRyYU5vZGVzKGFuYWx5c2lzKQotICAgICAgICAgICAmJiAhaXNTZXQoYW5hbHlzaXMsIEJJVF9TRUxGKQotICAgICAgICAgICAmJiAhd2Fsa3NTdWJ0cmVlKGFuYWx5c2lzKQotICAgICAgICAgICAmJiAhd2Fsa3NVcChhbmFseXNpcykKLSAgICAgICAgICAgJiYgIXdhbGtzU2lkZXdheXMoYW5hbHlzaXMpCi0gICAgICAgICAgICYmICFpc0Fic29sdXRlKGFuYWx5c2lzKQotICAgICAgICAgICA7Ci0gIH0KLQotICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNBYnNvbHV0ZShpbnQgYW5hbHlzaXMpCi0gIHsKLSAgICByZXR1cm4gaXNTZXQoYW5hbHlzaXMsIEJJVF9ST09UIHwgQklUX0ZJTFRFUik7Ci0gIH0KLQotICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gd2Fsa3NDaGlsZHJlbk9ubHkoaW50IGFuYWx5c2lzKQotICB7Ci0gICAgcmV0dXJuIHdhbGtzQ2hpbGRyZW4oYW5hbHlzaXMpCi0gICAgICAgICAgICYmICFpc1NldChhbmFseXNpcywgQklUX1NFTEYpCi0gICAgICAgICAgICYmICF3YWxrc0V4dHJhTm9kZXMoYW5hbHlzaXMpCi0gICAgICAgICAgICYmICF3YWxrc0Rlc2NlbmRhbnRzKGFuYWx5c2lzKQotICAgICAgICAgICAmJiAhd2Fsa3NVcChhbmFseXNpcykKLSAgICAgICAgICAgJiYgIXdhbGtzU2lkZXdheXMoYW5hbHlzaXMpCi0gICAgICAgICAgICYmICghaXNBYnNvbHV0ZShhbmFseXNpcykgfHwgaXNTZXQoYW5hbHlzaXMsIEJJVF9ST09UKSkKLSAgICAgICAgICAgOwotICB9Ci0KLSAgcHVibGljIHN0YXRpYyBib29sZWFuIHdhbGtzQ2hpbGRyZW5BbmRFeHRyYUFuZFNlbGZPbmx5KGludCBhbmFseXNpcykKLSAgewotICAgIHJldHVybiB3YWxrc0NoaWxkcmVuKGFuYWx5c2lzKQotICAgICAgICAgICAmJiAhd2Fsa3NEZXNjZW5kYW50cyhhbmFseXNpcykKLSAgICAgICAgICAgJiYgIXdhbGtzVXAoYW5hbHlzaXMpCi0gICAgICAgICAgICYmICF3YWxrc1NpZGV3YXlzKGFuYWx5c2lzKQotICAgICAgICAgICAmJiAoIWlzQWJzb2x1dGUoYW5hbHlzaXMpIHx8IGlzU2V0KGFuYWx5c2lzLCBCSVRfUk9PVCkpCi0gICAgICAgICAgIDsKLSAgfQotCi0gIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiB3YWxrc0Rlc2NlbmRhbnRzQW5kRXh0cmFBbmRTZWxmT25seShpbnQgYW5hbHlzaXMpCi0gIHsKLSAgICByZXR1cm4gIXdhbGtzQ2hpbGRyZW4oYW5hbHlzaXMpCi0gICAgICAgICAgICYmIHdhbGtzRGVzY2VuZGFudHMoYW5hbHlzaXMpCi0gICAgICAgICAgICYmICF3YWxrc1VwKGFuYWx5c2lzKQotICAgICAgICAgICAmJiAhd2Fsa3NTaWRld2F5cyhhbmFseXNpcykKLSAgICAgICAgICAgJiYgKCFpc0Fic29sdXRlKGFuYWx5c2lzKSB8fCBpc1NldChhbmFseXNpcywgQklUX1JPT1QpKQotICAgICAgICAgICA7Ci0gIH0KLQotICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gd2Fsa3NTZWxmT25seShpbnQgYW5hbHlzaXMpCi0gIHsKLSAgICByZXR1cm4gaXNTZXQoYW5hbHlzaXMsIEJJVF9TRUxGKQotICAgICAgICAgICAmJiAhd2Fsa3NTdWJ0cmVlKGFuYWx5c2lzKQotICAgICAgICAgICAmJiAhd2Fsa3NVcChhbmFseXNpcykKLSAgICAgICAgICAgJiYgIXdhbGtzU2lkZXdheXMoYW5hbHlzaXMpCi0gICAgICAgICAgICYmICFpc0Fic29sdXRlKGFuYWx5c2lzKQotICAgICAgICAgICA7Ci0gIH0KLQotCi0gIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiB3YWxrc1VwT25seShpbnQgYW5hbHlzaXMpCi0gIHsKLSAgICByZXR1cm4gIXdhbGtzU3VidHJlZShhbmFseXNpcykKLSAgICAgICAgICAgJiYgd2Fsa3NVcChhbmFseXNpcykKLSAgICAgICAgICAgJiYgIXdhbGtzU2lkZXdheXMoYW5hbHlzaXMpCi0gICAgICAgICAgICYmICFpc0Fic29sdXRlKGFuYWx5c2lzKQotICAgICAgICAgICA7Ci0gIH0KLQotICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gd2Fsa3NEb3duT25seShpbnQgYW5hbHlzaXMpCi0gIHsKLSAgICByZXR1cm4gd2Fsa3NTdWJ0cmVlKGFuYWx5c2lzKQotICAgICAgICAgICAmJiAhd2Fsa3NVcChhbmFseXNpcykKLSAgICAgICAgICAgJiYgIXdhbGtzU2lkZXdheXMoYW5hbHlzaXMpCi0gICAgICAgICAgICYmICFpc0Fic29sdXRlKGFuYWx5c2lzKQotICAgICAgICAgICA7Ci0gIH0KLQotICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gd2Fsa3NEb3duRXh0cmFPbmx5KGludCBhbmFseXNpcykKLSAgewotICAgIHJldHVybiB3YWxrc1N1YnRyZWUoYW5hbHlzaXMpICYmICB3YWxrc0V4dHJhTm9kZXMoYW5hbHlzaXMpCi0gICAgICAgICAgICYmICF3YWxrc1VwKGFuYWx5c2lzKQotICAgICAgICAgICAmJiAhd2Fsa3NTaWRld2F5cyhhbmFseXNpcykKLSAgICAgICAgICAgJiYgIWlzQWJzb2x1dGUoYW5hbHlzaXMpCi0gICAgICAgICAgIDsKLSAgfQotCi0gIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBjYW5Ta2lwU3VidHJlZXMoaW50IGFuYWx5c2lzKQotICB7Ci0gICAgcmV0dXJuIGlzU2V0KGFuYWx5c2lzLCBCSVRfQ0hJTEQpIHwgd2Fsa3NTaWRld2F5cyhhbmFseXNpcyk7Ci0gIH0KLQotICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gY2FuQ3Jpc3NDcm9zcyhpbnQgYW5hbHlzaXMpCi0gIHsKLSAgICAvLyBUaGlzIGNvdWxkIGJlIGRvbmUgZmFzdGVyLiAgQ29kZWQgZm9yIGNsYXJpdHkuCi0gICAgaWYod2Fsa3NTZWxmT25seShhbmFseXNpcykpCi0gICAgICByZXR1cm4gZmFsc2U7Ci0gICAgZWxzZSBpZih3YWxrc0Rvd25Pbmx5KGFuYWx5c2lzKSAmJiAhY2FuU2tpcFN1YnRyZWVzKGFuYWx5c2lzKSkKLSAgICAgIHJldHVybiBmYWxzZTsKLSAgICBlbHNlIGlmKHdhbGtzQ2hpbGRyZW5BbmRFeHRyYUFuZFNlbGZPbmx5KGFuYWx5c2lzKSkKLSAgICAgIHJldHVybiBmYWxzZTsKLSAgICBlbHNlIGlmKHdhbGtzRGVzY2VuZGFudHNBbmRFeHRyYUFuZFNlbGZPbmx5KGFuYWx5c2lzKSkKLSAgICAgIHJldHVybiBmYWxzZTsKLSAgICBlbHNlIGlmKHdhbGtzVXBPbmx5KGFuYWx5c2lzKSkKLSAgICAgIHJldHVybiBmYWxzZTsKLSAgICBlbHNlIGlmKHdhbGtzRXh0cmFOb2Rlc09ubHkoYW5hbHlzaXMpKQotICAgICAgcmV0dXJuIGZhbHNlOwotICAgIGVsc2UgaWYod2Fsa3NTdWJ0cmVlKGFuYWx5c2lzKQotICAgICAgICAgICAmJiAod2Fsa3NTaWRld2F5cyhhbmFseXNpcykKLSAgICAgICAgICAgIHx8IHdhbGtzVXAoYW5hbHlzaXMpCi0gICAgICAgICAgICB8fCBjYW5Ta2lwU3VidHJlZXMoYW5hbHlzaXMpKSkKLSAgICAgIHJldHVybiB0cnVlOwotICAgIGVsc2UKLSAgICAgIHJldHVybiBmYWxzZTsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIGlmIHRoZSBwYXR0ZXJuIGNhbiBiZSAnd2Fsa2VkJyB3aXRoIHRoZSBpdGVyYXRpb24gc3RlcHMgaW4gbmF0dXJhbAotICAgKiBkb2N1bWVudCBvcmRlciwgd2l0aG91dCBkdXBsaWNhdGVzLgotICAgKgotICAgKiBAcGFyYW0gYW5hbHlzaXMgVGhlIGdlbmVyYWwgYW5hbHlzaXMgb2YgdGhlIHBhdHRlcm4uCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgd2FsayBjYW4gYmUgZG9uZSBpbiBuYXR1cmFsIG9yZGVyLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHN0YXRpYyBwdWJsaWMgYm9vbGVhbiBpc05hdHVyYWxEb2NPcmRlcihpbnQgYW5hbHlzaXMpCi0gIHsKLSAgICBpZihjYW5Dcmlzc0Nyb3NzKGFuYWx5c2lzKSB8fCBpc1NldChhbmFseXNpcywgQklUX05BTUVTUEFDRSkgfHwKLSAgICAgICB3YWxrc0ZpbHRlcmVkTGlzdChhbmFseXNpcykpCi0gICAgICByZXR1cm4gZmFsc2U7Ci0KLSAgICBpZih3YWxrc0luRG9jT3JkZXIoYW5hbHlzaXMpKQotICAgICAgcmV0dXJuIHRydWU7Ci0KLSAgICByZXR1cm4gZmFsc2U7Ci0gIH0KLQotICAvKioKLSAgICogVGVsbCBpZiB0aGUgcGF0dGVybiBjYW4gYmUgJ3dhbGtlZCcgd2l0aCB0aGUgaXRlcmF0aW9uIHN0ZXBzIGluIG5hdHVyYWwKLSAgICogZG9jdW1lbnQgb3JkZXIsIHdpdGhvdXQgZHVwbGljYXRlcy4KLSAgICoKLSAgICogQHBhcmFtIGNvbXBpbGVyIG5vbi1udWxsIHJlZmVyZW5jZSB0byBjb21waWxlciBvYmplY3QgdGhhdCBoYXMgcHJvY2Vzc2VkCi0gICAqICAgICAgICAgICAgICAgICB0aGUgWFBhdGggb3BlcmF0aW9ucyBpbnRvIGFuIG9wY29kZSBtYXAuCi0gICAqIEBwYXJhbSBzdGVwT3BDb2RlUG9zIFRoZSBvcGNvZGUgcG9zaXRpb24gZm9yIHRoZSBzdGVwLgotICAgKiBAcGFyYW0gc3RlcEluZGV4IFRoZSB0b3AtbGV2ZWwgc3RlcCBpbmRleCB3aXRoaW5nIHRoZSBpdGVyYXRvci4KLSAgICogQHBhcmFtIGFuYWx5c2lzIFRoZSBnZW5lcmFsIGFuYWx5c2lzIG9mIHRoZSBwYXR0ZXJuLgotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHdhbGsgY2FuIGJlIGRvbmUgaW4gbmF0dXJhbCBvcmRlci4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGlzTmF0dXJhbERvY09yZGVyKAotICAgICAgICAgIENvbXBpbGVyIGNvbXBpbGVyLCBpbnQgc3RlcE9wQ29kZVBvcywgaW50IHN0ZXBJbmRleCwgaW50IGFuYWx5c2lzKQotICAgICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIGlmKGNhbkNyaXNzQ3Jvc3MoYW5hbHlzaXMpKQotICAgICAgcmV0dXJuIGZhbHNlOwotCi0gICAgLy8gTmFtZXNwYWNlcyBjYW4gcHJlc2VudCBzb21lIHByb2JsZW1zLCBzbyBqdXN0IHB1bnQgaWYgd2UncmUgbG9va2luZyBmb3IKLSAgICAvLyB0aGVzZS4KLSAgICBpZihpc1NldChhbmFseXNpcywgQklUX05BTUVTUEFDRSkpCi0gICAgICByZXR1cm4gZmFsc2U7Ci0KLSAgICAvLyBUaGUgZm9sbG93aW5nLCBwcmVjZWRpbmcsIGZvbGxvd2luZy1zaWJsaW5nLCBhbmQgcHJlY2VkaW5nIHNpYmxpbmcgY2FuCi0gICAgLy8gYmUgZm91bmQgaW4gZG9jIG9yZGVyIGlmIHdlIGdldCB0byB0aGlzIHBvaW50LCBidXQgaWYgdGhleSBvY2N1cgotICAgIC8vIHRvZ2V0aGVyLCB0aGV5IHByb2R1Y2UKLSAgICAvLyBkdXBsaWNhdGVzLCBzbyBpdCdzIGJldHRlciBmb3IgdXMgdG8gZWxpbWluYXRlIHRoaXMgY2FzZSBzbyB3ZSBkb24ndAotICAgIC8vIGhhdmUgdG8gY2hlY2sgZm9yIGR1cGxpY2F0ZXMgZHVyaW5nIHJ1bnRpbWUgaWYgd2UncmUgdXNpbmcgYQotICAgIC8vIFdhbGtpbmdJdGVyYXRvci4KLSAgICBpZihpc1NldChhbmFseXNpcywgQklUX0ZPTExPV0lORyB8IEJJVF9GT0xMT1dJTkdfU0lCTElORykgJiYKLSAgICAgICBpc1NldChhbmFseXNpcywgQklUX1BSRUNFRElORyB8IEJJVF9QUkVDRURJTkdfU0lCTElORykpCi0gICAgICByZXR1cm4gIGZhbHNlOwotCi0gICAgLy8gT0ssIG5vdyB3ZSBoYXZlIHRvIGNoZWNrIGZvciBzZWxlY3Q9IkAqL2F4aXM6OioiIHBhdHRlcm5zLCB3aGljaAotICAgIC8vIGNhbiBhbHNvIGNhdXNlIGR1cGxpY2F0ZXMgdG8gaGFwcGVuLiAgQnV0IHNlbGVjdD0iYXhpcyovQDo6KiIgcGF0dGVybnMKLSAgICAvLyBhcmUgT0ssIGFzIGFyZSBzZWxlY3Q9IkBmb28vYXhpczo6KiIgcGF0dGVybnMuCi0gICAgLy8gVW5mb3J0dW5hdGVseSwgd2UgY2FuJ3QgZG8gdGhpcyBqdXN0IHZpYSB0aGUgYW5hbHlzaXMgYml0cy4KLQotICAgIGludCBzdGVwVHlwZTsKLSAgICBpbnQgc3RlcENvdW50ID0gMDsKLSAgICBib29sZWFuIGZvdW5kV2lsZEF0dHJpYnV0ZSA9IGZhbHNlOwotCi0gICAgLy8gU3RlcHMgdGhhdCBjYW4gdHJhdmVyc2UgYW55dGhpbmcgb3RoZXIgdGhhbiBkb3duIGEKLSAgICAvLyBzdWJ0cmVlIG9yIHRoYXQgY2FuIHByb2R1Y2UgZHVwbGljYXRlcyB3aGVuIHVzZWQgaW4KLSAgICAvLyBjb21ib25hdGlvbiBhcmUgY291bnRlZCB3aXRoIHRoaXMgdmFyaWFibGUuCi0gICAgaW50IHBvdGVudGlhbER1cGxpY2F0ZU1ha2luZ1N0ZXBDb3VudCA9IDA7Ci0KLSAgICB3aGlsZSAoT3BDb2Rlcy5FTkRPUCAhPSAoc3RlcFR5cGUgPSBjb21waWxlci5nZXRPcChzdGVwT3BDb2RlUG9zKSkpCi0gICAgewotICAgICAgc3RlcENvdW50Kys7Ci0KLSAgICAgIHN3aXRjaCAoc3RlcFR5cGUpCi0gICAgICB7Ci0gICAgICBjYXNlIE9wQ29kZXMuRlJPTV9BVFRSSUJVVEVTIDoKLSAgICAgIGNhc2UgT3BDb2Rlcy5NQVRDSF9BVFRSSUJVVEUgOgotICAgICAgICBpZihmb3VuZFdpbGRBdHRyaWJ1dGUpIC8vIE1heWJlIG5vdCBuZWVkZWQsIGJ1dCBiZSBzYWZlLgotICAgICAgICAgIHJldHVybiBmYWxzZTsKLQotICAgICAgICAvLyBUaGlzIGRvZXNuJ3Qgc2VlbSB0byB3b3JrIGFzIGEgdGVzdCBmb3Igd2lsZCBjYXJkLiAgSG1waC4KLSAgICAgICAgLy8gaW50IG5vZGVUZXN0VHlwZSA9IGNvbXBpbGVyLmdldFN0ZXBUZXN0VHlwZShzdGVwT3BDb2RlUG9zKTsKLQotICAgICAgICBTdHJpbmcgbG9jYWxOYW1lID0gY29tcGlsZXIuZ2V0U3RlcExvY2FsTmFtZShzdGVwT3BDb2RlUG9zKTsKLSAgICAgICAgLy8gU3lzdGVtLmVyci5wcmludGxuKCJsb2NhbE5hbWU6ICIrbG9jYWxOYW1lKTsKLSAgICAgICAgaWYobG9jYWxOYW1lLmVxdWFscygiKiIpKQotICAgICAgICB7Ci0gICAgICAgICAgZm91bmRXaWxkQXR0cmlidXRlID0gdHJ1ZTsKLSAgICAgICAgfQotICAgICAgICBicmVhazsKLSAgICAgIGNhc2UgT3BDb2Rlcy5GUk9NX0ZPTExPV0lORyA6Ci0gICAgICBjYXNlIE9wQ29kZXMuRlJPTV9GT0xMT1dJTkdfU0lCTElOR1MgOgotICAgICAgY2FzZSBPcENvZGVzLkZST01fUFJFQ0VESU5HIDoKLSAgICAgIGNhc2UgT3BDb2Rlcy5GUk9NX1BSRUNFRElOR19TSUJMSU5HUyA6Ci0gICAgICBjYXNlIE9wQ29kZXMuRlJPTV9QQVJFTlQgOgotICAgICAgY2FzZSBPcENvZGVzLk9QX1ZBUklBQkxFIDoKLSAgICAgIGNhc2UgT3BDb2Rlcy5PUF9FWFRGVU5DVElPTiA6Ci0gICAgICBjYXNlIE9wQ29kZXMuT1BfRlVOQ1RJT04gOgotICAgICAgY2FzZSBPcENvZGVzLk9QX0dST1VQIDoKLSAgICAgIGNhc2UgT3BDb2Rlcy5GUk9NX05BTUVTUEFDRSA6Ci0gICAgICBjYXNlIE9wQ29kZXMuRlJPTV9BTkNFU1RPUlMgOgotICAgICAgY2FzZSBPcENvZGVzLkZST01fQU5DRVNUT1JTX09SX1NFTEYgOgotICAgICAgY2FzZSBPcENvZGVzLk1BVENIX0FOWV9BTkNFU1RPUiA6Ci0gICAgICBjYXNlIE9wQ29kZXMuTUFUQ0hfSU1NRURJQVRFX0FOQ0VTVE9SIDoKLSAgICAgIGNhc2UgT3BDb2Rlcy5GUk9NX0RFU0NFTkRBTlRTX09SX1NFTEYgOgotICAgICAgY2FzZSBPcENvZGVzLkZST01fREVTQ0VOREFOVFMgOgotICAgICAgICBpZihwb3RlbnRpYWxEdXBsaWNhdGVNYWtpbmdTdGVwQ291bnQgPiAwKQotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICBwb3RlbnRpYWxEdXBsaWNhdGVNYWtpbmdTdGVwQ291bnQrKzsKLSAgICAgIGNhc2UgT3BDb2Rlcy5GUk9NX1JPT1QgOgotICAgICAgY2FzZSBPcENvZGVzLkZST01fQ0hJTERSRU4gOgotICAgICAgY2FzZSBPcENvZGVzLkZST01fU0VMRiA6Ci0gICAgICAgIGlmKGZvdW5kV2lsZEF0dHJpYnV0ZSkKLSAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIGJyZWFrOwotICAgICAgZGVmYXVsdCA6Ci0gICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShYUEFUSEVycm9yUmVzb3VyY2VzLkVSX05VTExfRVJST1JfSEFORExFUiwgbmV3IE9iamVjdFtde0ludGVnZXIudG9TdHJpbmcoc3RlcFR5cGUpfSkpOyAvLyJQcm9ncmFtbWVyJ3MgYXNzZXJ0aW9uOiB1bmtub3duIG9wY29kZTogIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICsgc3RlcFR5cGUpOwotICAgICAgfQotCi0gICAgICBpbnQgbmV4dFN0ZXBPcENvZGVQb3MgPSBjb21waWxlci5nZXROZXh0U3RlcFBvcyhzdGVwT3BDb2RlUG9zKTsKLQotICAgICAgaWYgKG5leHRTdGVwT3BDb2RlUG9zIDwgMCkKLSAgICAgICAgYnJlYWs7Ci0KLSAgICAgIHN0ZXBPcENvZGVQb3MgPSBuZXh0U3RlcE9wQ29kZVBvczsKLSAgICB9Ci0KLSAgICByZXR1cm4gdHJ1ZTsKLSAgfQotCi0gIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc09uZVN0ZXAoaW50IGFuYWx5c2lzKQotICB7Ci0gICAgcmV0dXJuIChhbmFseXNpcyAmIEJJVFNfQ09VTlQpID09IDB4MDAwMDAwMDE7Ci0gIH0KLQotICBwdWJsaWMgc3RhdGljIGludCBnZXRTdGVwQ291bnQoaW50IGFuYWx5c2lzKQotICB7Ci0gICAgcmV0dXJuIChhbmFseXNpcyAmIEJJVFNfQ09VTlQpOwotICB9Ci0KLSAgLyoqCi0gICAqIEZpcnN0IDggYml0cyBhcmUgdGhlIG51bWJlciBvZiB0b3AtbGV2ZWwgbG9jYXRpb24gc3RlcHMuICBIb3BlZnVsbHkKLSAgICogIHRoZXJlIHdpbGwgbmV2ZXIgYmUgbW9yZSB0aGF0IDI1NSBsb2NhdGlvbiBzdGVwcyEhIQotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQklUU19DT1VOVCA9IDB4MDAwMDAwRkY7Ci0KLSAgLyoqIDQgYml0cyBhcmUgcmVzZXJ2ZWQgZm9yIGZ1dHVyZSB1c2UuICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJJVFNfUkVTRVJWRUQgPSAweDAwMDAwRjAwOwotCi0gIC8qKiBCaXQgaXMgb24gaWYgdGhlIGV4cHJlc3Npb24gY29udGFpbnMgYSB0b3AtbGV2ZWwgcHJlZGljYXRlLiAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCSVRfUFJFRElDQVRFID0gKDB4MDAwMDEwMDApOwotCi0gIC8qKiBCaXQgaXMgb24gaWYgYW55IG9mIHRoZSB3YWxrZXJzIGNvbnRhaW4gYW4gYW5jZXN0b3Igc3RlcC4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQklUX0FOQ0VTVE9SID0gKDB4MDAwMDEwMDAgPDwgMSk7Ci0KLSAgLyoqIEJpdCBpcyBvbiBpZiBhbnkgb2YgdGhlIHdhbGtlcnMgY29udGFpbiBhbiBhbmNlc3Rvci1vci1zZWxmIHN0ZXAuICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJJVF9BTkNFU1RPUl9PUl9TRUxGID0gKDB4MDAwMDEwMDAgPDwgMik7Ci0KLSAgLyoqIEJpdCBpcyBvbiBpZiBhbnkgb2YgdGhlIHdhbGtlcnMgY29udGFpbiBhbiBhdHRyaWJ1dGUgc3RlcC4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQklUX0FUVFJJQlVURSA9ICgweDAwMDAxMDAwIDw8IDMpOwotCi0gIC8qKiBCaXQgaXMgb24gaWYgYW55IG9mIHRoZSB3YWxrZXJzIGNvbnRhaW4gYSBjaGlsZCBzdGVwLiAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCSVRfQ0hJTEQgPSAoMHgwMDAwMTAwMCA8PCA0KTsKLQotICAvKiogQml0IGlzIG9uIGlmIGFueSBvZiB0aGUgd2Fsa2VycyBjb250YWluIGEgZGVzY2VuZGFudCBzdGVwLiAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCSVRfREVTQ0VOREFOVCA9ICgweDAwMDAxMDAwIDw8IDUpOwotCi0gIC8qKiBCaXQgaXMgb24gaWYgYW55IG9mIHRoZSB3YWxrZXJzIGNvbnRhaW4gYSBkZXNjZW5kYW50LW9yLXNlbGYgc3RlcC4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQklUX0RFU0NFTkRBTlRfT1JfU0VMRiA9ICgweDAwMDAxMDAwIDw8IDYpOwotCi0gIC8qKiBCaXQgaXMgb24gaWYgYW55IG9mIHRoZSB3YWxrZXJzIGNvbnRhaW4gYSBmb2xsb3dpbmcgc3RlcC4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQklUX0ZPTExPV0lORyA9ICgweDAwMDAxMDAwIDw8IDcpOwotCi0gIC8qKiBCaXQgaXMgb24gaWYgYW55IG9mIHRoZSB3YWxrZXJzIGNvbnRhaW4gYSBmb2xsb3dpbmctc2liaWxpbmcgc3RlcC4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQklUX0ZPTExPV0lOR19TSUJMSU5HID0gKDB4MDAwMDEwMDAgPDwgOCk7Ci0KLSAgLyoqIEJpdCBpcyBvbiBpZiBhbnkgb2YgdGhlIHdhbGtlcnMgY29udGFpbiBhIG5hbWVzcGFjZSBzdGVwLiAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCSVRfTkFNRVNQQUNFID0gKDB4MDAwMDEwMDAgPDwgOSk7Ci0KLSAgLyoqIEJpdCBpcyBvbiBpZiBhbnkgb2YgdGhlIHdhbGtlcnMgY29udGFpbiBhIHBhcmVudCBzdGVwLiAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCSVRfUEFSRU5UID0gKDB4MDAwMDEwMDAgPDwgMTApOwotCi0gIC8qKiBCaXQgaXMgb24gaWYgYW55IG9mIHRoZSB3YWxrZXJzIGNvbnRhaW4gYSBwcmVjZWRpbmcgc3RlcC4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQklUX1BSRUNFRElORyA9ICgweDAwMDAxMDAwIDw8IDExKTsKLQotICAvKiogQml0IGlzIG9uIGlmIGFueSBvZiB0aGUgd2Fsa2VycyBjb250YWluIGEgcHJlY2VkaW5nLXNpYmxpbmcgc3RlcC4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQklUX1BSRUNFRElOR19TSUJMSU5HID0gKDB4MDAwMDEwMDAgPDwgMTIpOwotCi0gIC8qKiBCaXQgaXMgb24gaWYgYW55IG9mIHRoZSB3YWxrZXJzIGNvbnRhaW4gYSBzZWxmIHN0ZXAuICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJJVF9TRUxGID0gKDB4MDAwMDEwMDAgPDwgMTMpOwotCi0gIC8qKgotICAgKiBCaXQgaXMgb24gaWYgYW55IG9mIHRoZSB3YWxrZXJzIGNvbnRhaW4gYSBmaWx0ZXIgKGkuZS4gaWQoKSwgZXh0ZW5zaW9uCi0gICAqICBmdW5jdGlvbiwgZXRjLikgc3RlcC4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJJVF9GSUxURVIgPSAoMHgwMDAwMTAwMCA8PCAxNCk7Ci0KLSAgLyoqIEJpdCBpcyBvbiBpZiBhbnkgb2YgdGhlIHdhbGtlcnMgY29udGFpbiBhIHJvb3Qgc3RlcC4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQklUX1JPT1QgPSAoMHgwMDAwMTAwMCA8PCAxNSk7Ci0KLSAgLyoqCi0gICAqIElmIGFueSBvZiB0aGVzZSBiaXRzIGFyZSBvbiwgdGhlIGV4cHJlc3Npb24gbWF5IGxpa2VseSB0cmF2ZXJzZSBvdXRzaWRlCi0gICAqICB0aGUgZ2l2ZW4gc3VidHJlZS4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJJVE1BU0tfVFJBVkVSU0VTX09VVFNJREVfU1VCVFJFRSA9IChCSVRfTkFNRVNQQUNFICAvLyA/PwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgQklUX1BSRUNFRElOR19TSUJMSU5HCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBCSVRfUFJFQ0VESU5HCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBCSVRfRk9MTE9XSU5HX1NJQkxJTkcKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IEJJVF9GT0xMT1dJTkcKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IEJJVF9QQVJFTlQgIC8vIGV4Y2VwdCBwYXJlbnQgb2YgYXR0cnMuCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBCSVRfQU5DRVNUT1JfT1JfU0VMRgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgQklUX0FOQ0VTVE9SCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBCSVRfRklMVEVSCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBCSVRfUk9PVCk7Ci0KLSAgLyoqCi0gICAqIEJpdCBpcyBvbiBpZiBhbnkgb2YgdGhlIHdhbGtlcnMgY2FuIGdvIGJhY2t3YXJkcyBpbiBkb2N1bWVudAotICAgKiAgb3JkZXIgZnJvbSB0aGUgY29udGV4dCBub2RlLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQklUX0JBQ0tXQVJEU19TRUxGID0gKDB4MDAwMDEwMDAgPDwgMTYpOwotCi0gIC8qKiBGb3VuZCAiLy9mb28iIHBhdHRlcm4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQklUX0FOWV9ERVNDRU5EQU5UX0ZST01fUk9PVCA9ICgweDAwMDAxMDAwIDw8IDE3KTsKLQotICAvKioKLSAgICogQml0IGlzIG9uIGlmIGFueSBvZiB0aGUgd2Fsa2VycyBjb250YWluIGFuIG5vZGUoKSB0ZXN0LiAgVGhpcyBpcwotICAgKiAgcmVhbGx5IG9ubHkgdXNlZnVsIGlmIHRoZSBjb3VudCBpcyAxLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQklUX05PREVURVNUX0FOWSA9ICgweDAwMDAxMDAwIDw8IDE4KTsKLQotICAvLyBjYW4ndCBnbyBoaWdoZXIgdGhhbiAxOCEKLQotICAvKiogQml0IGlzIG9uIGlmIHRoZSBleHByZXNzaW9uIGlzIGEgbWF0Y2ggcGF0dGVybi4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQklUX01BVENIX1BBVFRFUk4gPSAoMHgwMDAwMTAwMCA8PCAxOSk7Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2F4ZXMvV2Fsa2luZ0l0ZXJhdG9yLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2F4ZXMvV2Fsa2luZ0l0ZXJhdG9yLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDA4NTAyZmUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9heGVzL1dhbGtpbmdJdGVyYXRvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzY1ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFdhbGtpbmdJdGVyYXRvci5qYXZhLHYgMS4yLjQuMiAyMDA1LzA5LzE0IDE5OjQ1OjE5IGplZmZzdXR0b3IgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuYXhlczsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLlByZWZpeFJlc29sdmVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5FeHByZXNzaW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5FeHByZXNzaW9uT3duZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlZhcmlhYmxlU3RhY2s7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoVmlzaXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuY29tcGlsZXIuQ29tcGlsZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmNvbXBpbGVyLk9wTWFwOwotCi0vKioKLSAqIExvY2F0aW9uIHBhdGggaXRlcmF0b3IgdGhhdCB1c2VzIFdhbGtlcnMuCi0gKi8KLQotcHVibGljIGNsYXNzIFdhbGtpbmdJdGVyYXRvciBleHRlbmRzIExvY1BhdGhJdGVyYXRvciBpbXBsZW1lbnRzIEV4cHJlc3Npb25Pd25lcgotewotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA5MTEwMjI1OTQxODE1NjY1OTA2TDsKLSAgLyoqCi0gICAqIENyZWF0ZSBhIFdhbGtpbmdJdGVyYXRvciBpdGVyYXRvciwgaW5jbHVkaW5nIGNyZWF0aW9uCi0gICAqIG9mIHN0ZXAgd2Fsa2VycyBmcm9tIHRoZSBvcGNvZGUgbGlzdCwgYW5kIGNhbGwgYmFjawotICAgKiBpbnRvIHRoZSBDb21waWxlciB0byBjcmVhdGUgcHJlZGljYXRlIGV4cHJlc3Npb25zLgotICAgKgotICAgKiBAcGFyYW0gY29tcGlsZXIgVGhlIENvbXBpbGVyIHdoaWNoIGlzIGNyZWF0aW5nCi0gICAqIHRoaXMgZXhwcmVzc2lvbi4KLSAgICogQHBhcmFtIG9wUG9zIFRoZSBwb3NpdGlvbiBvZiB0aGlzIGl0ZXJhdG9yIGluIHRoZQotICAgKiBvcGNvZGUgbGlzdCBmcm9tIHRoZSBjb21waWxlci4KLSAgICogQHBhcmFtIHNob3VsZExvYWRXYWxrZXJzIFRydWUgaWYgd2Fsa2VycyBzaG91bGQgYmUKLSAgICogbG9hZGVkLCBvciBmYWxzZSBpZiB0aGlzIGlzIGEgZGVyaXZlZCBpdGVyYXRvciBhbmQKLSAgICogaXQgZG9lc24ndCB3aXNoIHRvIGxvYWQgY2hpbGQgd2Fsa2Vycy4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBXYWxraW5nSXRlcmF0b3IoCi0gICAgICAgICAgQ29tcGlsZXIgY29tcGlsZXIsIGludCBvcFBvcywgaW50IGFuYWx5c2lzLCBib29sZWFuIHNob3VsZExvYWRXYWxrZXJzKQotICAgICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHN1cGVyKGNvbXBpbGVyLCBvcFBvcywgYW5hbHlzaXMsIHNob3VsZExvYWRXYWxrZXJzKTsKLQotICAgIGludCBmaXJzdFN0ZXBQb3MgPSBPcE1hcC5nZXRGaXJzdENoaWxkUG9zKG9wUG9zKTsKLQotICAgIGlmIChzaG91bGRMb2FkV2Fsa2VycykKLSAgICB7Ci0gICAgICBtX2ZpcnN0V2Fsa2VyID0gV2Fsa2VyRmFjdG9yeS5sb2FkV2Fsa2Vycyh0aGlzLCBjb21waWxlciwgZmlyc3RTdGVwUG9zLCAwKTsKLSAgICAgIG1fbGFzdFVzZWRXYWxrZXIgPSBtX2ZpcnN0V2Fsa2VyOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBXYWxraW5nSXRlcmF0b3Igb2JqZWN0LgotICAgKgotICAgKiBAcGFyYW0gbnNjb250ZXh0IFRoZSBuYW1lc3BhY2UgY29udGV4dCBmb3IgdGhpcyBpdGVyYXRvciwKLSAgICogc2hvdWxkIGJlIE9LIGlmIG51bGwuCi0gICAqLwotICBwdWJsaWMgV2Fsa2luZ0l0ZXJhdG9yKFByZWZpeFJlc29sdmVyIG5zY29udGV4dCkKLSAgewotCi0gICAgc3VwZXIobnNjb250ZXh0KTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIEdldCB0aGUgYW5hbHlzaXMgYml0cyBmb3IgdGhpcyB3YWxrZXIsIGFzIGRlZmluZWQgaW4gdGhlIFdhbGtlckZhY3RvcnkuCi0gICAqIEByZXR1cm4gT25lIG9mIFdhbGtlckZhY3RvcnkjQklUX0RFU0NFTkRBTlQsIGV0Yy4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0QW5hbHlzaXNCaXRzKCkKLSAgewotICAgIGludCBiaXRzID0gMDsKLSAgICBpZiAobnVsbCAhPSBtX2ZpcnN0V2Fsa2VyKQotICAgIHsKLSAgICAgIEF4ZXNXYWxrZXIgd2Fsa2VyID0gbV9maXJzdFdhbGtlcjsKLQotICAgICAgd2hpbGUgKG51bGwgIT0gd2Fsa2VyKQotICAgICAgewotICAgICAgICBpbnQgYml0ID0gd2Fsa2VyLmdldEFuYWx5c2lzQml0cygpOwotICAgICAgICBiaXRzIHw9IGJpdDsKLSAgICAgICAgd2Fsa2VyID0gd2Fsa2VyLmdldE5leHRXYWxrZXIoKTsKLSAgICAgIH0KLSAgICB9Ci0gICAgcmV0dXJuIGJpdHM7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IGEgY2xvbmVkIFdhbGtpbmdJdGVyYXRvciB0aGF0IGhvbGRzIHRoZSBzYW1lCi0gICAqIHBvc2l0aW9uIGFzIHRoaXMgaXRlcmF0b3IuCi0gICAqCi0gICAqIEByZXR1cm4gQSBjbG9uZSBvZiB0aGlzIGl0ZXJhdG9yIHRoYXQgaG9sZHMgdGhlIHNhbWUgbm9kZSBwb3NpdGlvbi4KLSAgICoKLSAgICogQHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIE9iamVjdCBjbG9uZSgpIHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbgotICB7Ci0KLSAgICBXYWxraW5nSXRlcmF0b3IgY2xvbmUgPSAoV2Fsa2luZ0l0ZXJhdG9yKSBzdXBlci5jbG9uZSgpOwotCi0gICAgLy8gICAgY2xvbmUubV92YXJTdGFja1BvcyA9IHRoaXMubV92YXJTdGFja1BvczsKLSAgICAvLyAgICBjbG9uZS5tX3ZhclN0YWNrQ29udGV4dCA9IHRoaXMubV92YXJTdGFja0NvbnRleHQ7Ci0gICAgaWYgKG51bGwgIT0gbV9maXJzdFdhbGtlcikKLSAgICB7Ci0gICAgICBjbG9uZS5tX2ZpcnN0V2Fsa2VyID0gbV9maXJzdFdhbGtlci5jbG9uZURlZXAoY2xvbmUsIG51bGwpOwotICAgIH0KLQotICAgIHJldHVybiBjbG9uZTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXNldCB0aGUgaXRlcmF0b3IuCi0gICAqLwotICBwdWJsaWMgdm9pZCByZXNldCgpCi0gIHsKLQotICAgIHN1cGVyLnJlc2V0KCk7Ci0KLSAgICBpZiAobnVsbCAhPSBtX2ZpcnN0V2Fsa2VyKQotICAgIHsKLSAgICAgIG1fbGFzdFVzZWRXYWxrZXIgPSBtX2ZpcnN0V2Fsa2VyOwotCi0gICAgICBtX2ZpcnN0V2Fsa2VyLnNldFJvb3QobV9jb250ZXh0KTsKLSAgICB9Ci0KLSAgfQotCi0gIC8qKgotICAgKiBJbml0aWFsaXplIHRoZSBjb250ZXh0IHZhbHVlcyBmb3IgdGhpcyBleHByZXNzaW9uCi0gICAqIGFmdGVyIGl0IGlzIGNsb25lZC4KLSAgICoKLSAgICogQHBhcmFtIGNvbnRleHQgVGhlIFhQYXRoIHJ1bnRpbWUgY29udGV4dCBmb3IgdGhpcwotICAgKiB0cmFuc2Zvcm1hdGlvbi4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFJvb3QoaW50IGNvbnRleHQsIE9iamVjdCBlbnZpcm9ubWVudCkKLSAgewotCi0gICAgc3VwZXIuc2V0Um9vdChjb250ZXh0LCBlbnZpcm9ubWVudCk7Ci0KLSAgICBpZihudWxsICE9IG1fZmlyc3RXYWxrZXIpCi0gICAgewotICAgICAgbV9maXJzdFdhbGtlci5zZXRSb290KGNvbnRleHQpOwotICAgICAgbV9sYXN0VXNlZFdhbGtlciA9IG1fZmlyc3RXYWxrZXI7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqICBSZXR1cm5zIHRoZSBuZXh0IG5vZGUgaW4gdGhlIHNldCBhbmQgYWR2YW5jZXMgdGhlIHBvc2l0aW9uIG9mIHRoZQotICAgKiBpdGVyYXRvciBpbiB0aGUgc2V0LiBBZnRlciBhIE5vZGVJdGVyYXRvciBpcyBjcmVhdGVkLCB0aGUgZmlyc3QgY2FsbAotICAgKiB0byBuZXh0Tm9kZSgpIHJldHVybnMgdGhlIGZpcnN0IG5vZGUgaW4gdGhlIHNldC4KLSAgICogQHJldHVybiAgVGhlIG5leHQgPGNvZGU+Tm9kZTwvY29kZT4gaW4gdGhlIHNldCBiZWluZyBpdGVyYXRlZCBvdmVyLCBvcgotICAgKiAgIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoZXJlIGFyZSBubyBtb3JlIG1lbWJlcnMgaW4gdGhhdCBzZXQuCi0gICAqLwotICBwdWJsaWMgaW50IG5leHROb2RlKCkKLSAgewotICAgICAgICBpZihtX2ZvdW5kTGFzdCkKLSAgICAgICAgICAgICAgICByZXR1cm4gRFRNLk5VTEw7Ci0KLSAgICAvLyBJZiB0aGUgdmFyaWFibGUgc3RhY2sgcG9zaXRpb24gaXMgbm90IC0xLCB3ZSdsbCBoYXZlIHRvCi0gICAgLy8gc2V0IG91ciBwb3NpdGlvbiBpbiB0aGUgdmFyaWFibGUgc3RhY2ssIHNvIG91ciB2YXJpYWJsZSBhY2Nlc3MKLSAgICAvLyB3aWxsIGJlIGNvcnJlY3QuICBJdGVyYXRvcnMgdGhhdCBhcmUgYXQgdGhlIHRvcCBsZXZlbCBvZiB0aGUKLSAgICAvLyBleHByZXNzaW9uIG5lZWQgdG8gcmVzZXQgdGhlIHZhcmlhYmxlIHN0YWNrLCB3aGlsZSBpdGVyYXRvcnMKLSAgICAvLyBpbiBwcmVkaWNhdGVzIGRvIG5vdCBuZWVkIHRvLCBhbmQgc2hvdWxkIG5vdCwgc2luY2UgdGhlaXIgZXhlY3V0aW9uCi0gICAgLy8gbWF5IGJlIG11Y2ggbGF0ZXIgdGhhbiB0b3AtbGV2ZWwgaXRlcmF0b3JzLgotICAgIC8vIG1fdmFyU3RhY2tQb3MgaXMgc2V0IGluIHNldFJvb3QsIHdoaWNoIGlzIGNhbGxlZAotICAgIC8vIGZyb20gdGhlIGV4ZWN1dGUgbWV0aG9kLgotICAgIGlmICgtMSA9PSBtX3N0YWNrRnJhbWUpCi0gICAgewotICAgICAgcmV0dXJuIHJldHVybk5leHROb2RlKG1fZmlyc3RXYWxrZXIubmV4dE5vZGUoKSk7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBWYXJpYWJsZVN0YWNrIHZhcnMgPSBtX2V4ZWNDb250ZXh0LmdldFZhclN0YWNrKCk7Ci0KLSAgICAgIC8vIFRoZXNlIHRocmVlIHN0YXRlbWVudHMgbmVlZCB0byBiZSBjb21iaW5lZCBpbnRvIG9uZSBvcGVyYXRpb24uCi0gICAgICBpbnQgc2F2ZWRTdGFydCA9IHZhcnMuZ2V0U3RhY2tGcmFtZSgpOwotCi0gICAgICB2YXJzLnNldFN0YWNrRnJhbWUobV9zdGFja0ZyYW1lKTsKLQotICAgICAgaW50IG4gPSByZXR1cm5OZXh0Tm9kZShtX2ZpcnN0V2Fsa2VyLm5leHROb2RlKCkpOwotCi0gICAgICAvLyBUaGVzZSB0d28gc3RhdGVtZW50cyBuZWVkIHRvIGJlIGNvbWJpbmVkIGludG8gb25lIG9wZXJhdGlvbi4KLSAgICAgIHZhcnMuc2V0U3RhY2tGcmFtZShzYXZlZFN0YXJ0KTsKLQotICAgICAgcmV0dXJuIG47Ci0gICAgfQotICB9Ci0KLQotICAvKioKLSAgICogR2V0IHRoZSBoZWFkIG9mIHRoZSB3YWxrZXIgbGlzdC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgaGVhZCBvZiB0aGUgd2Fsa2VyIGxpc3QsIG9yIG51bGwKLSAgICogaWYgdGhpcyBpdGVyYXRvciBkb2VzIG5vdCBpbXBsZW1lbnQgd2Fsa2Vycy4KLSAgICogQHhzbC51c2FnZSBhZHZhbmNlZAotICAgKi8KLSAgcHVibGljIGZpbmFsIEF4ZXNXYWxrZXIgZ2V0Rmlyc3RXYWxrZXIoKQotICB7Ci0gICAgcmV0dXJuIG1fZmlyc3RXYWxrZXI7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBoZWFkIG9mIHRoZSB3YWxrZXIgbGlzdC4KLSAgICoKLSAgICogQHBhcmFtIHdhbGtlciBTaG91bGQgYmUgYSB2YWxpZCBBeGVzV2Fsa2VyLgotICAgKiBAeHNsLnVzYWdlIGFkdmFuY2VkCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBzZXRGaXJzdFdhbGtlcihBeGVzV2Fsa2VyIHdhbGtlcikKLSAgewotICAgIG1fZmlyc3RXYWxrZXIgPSB3YWxrZXI7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBTZXQgdGhlIGxhc3QgdXNlZCB3YWxrZXIuCi0gICAqCi0gICAqIEBwYXJhbSB3YWxrZXIgVGhlIGxhc3QgdXNlZCB3YWxrZXIsIG9yIG51bGwuCi0gICAqIEB4c2wudXNhZ2UgYWR2YW5jZWQKLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHNldExhc3RVc2VkV2Fsa2VyKEF4ZXNXYWxrZXIgd2Fsa2VyKQotICB7Ci0gICAgbV9sYXN0VXNlZFdhbGtlciA9IHdhbGtlcjsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGxhc3QgdXNlZCB3YWxrZXIuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGxhc3QgdXNlZCB3YWxrZXIsIG9yIG51bGwuCi0gICAqIEB4c2wudXNhZ2UgYWR2YW5jZWQKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBBeGVzV2Fsa2VyIGdldExhc3RVc2VkV2Fsa2VyKCkKLSAgewotICAgIHJldHVybiBtX2xhc3RVc2VkV2Fsa2VyOwotICB9Ci0KLSAgLyoqCi0gICAqICBEZXRhY2hlcyB0aGUgaXRlcmF0b3IgZnJvbSB0aGUgc2V0IHdoaWNoIGl0IGl0ZXJhdGVkIG92ZXIsIHJlbGVhc2luZwotICAgKiBhbnkgY29tcHV0YXRpb25hbCByZXNvdXJjZXMgYW5kIHBsYWNpbmcgdGhlIGl0ZXJhdG9yIGluIHRoZSBJTlZBTElECi0gICAqIHN0YXRlLiBBZnRlcjxjb2RlPmRldGFjaDwvY29kZT4gaGFzIGJlZW4gaW52b2tlZCwgY2FsbHMgdG8KLSAgICogPGNvZGU+bmV4dE5vZGU8L2NvZGU+IG9yPGNvZGU+cHJldmlvdXNOb2RlPC9jb2RlPiB3aWxsIHJhaXNlIHRoZQotICAgKiBleGNlcHRpb24gSU5WQUxJRF9TVEFURV9FUlIuCi0gICAqLwotICBwdWJsaWMgdm9pZCBkZXRhY2goKQotICB7Ci0gICAgaWYobV9hbGxvd0RldGFjaCkKLSAgICB7Ci0gICAgICAgICAgICAgICAgQXhlc1dhbGtlciB3YWxrZXIgPSBtX2ZpcnN0V2Fsa2VyOwotICAgICAgICAgICAgd2hpbGUgKG51bGwgIT0gd2Fsa2VyKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICB3YWxrZXIuZGV0YWNoKCk7Ci0gICAgICAgICAgICAgIHdhbGtlciA9IHdhbGtlci5nZXROZXh0V2Fsa2VyKCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIG1fbGFzdFVzZWRXYWxrZXIgPSBudWxsOwotCi0gICAgICAgICAgICAvLyBBbHdheXMgY2FsbCB0aGUgc3VwZXJjbGFzcyBkZXRhY2ggbGFzdCEKLSAgICAgICAgICAgIHN1cGVyLmRldGFjaCgpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgdG8gZml4dXAgdmFyaWFibGVzIGZyb20gUU5hbWVzIHRvIHN0YWNrIGZyYW1lCi0gICAqIGluZGV4ZXMgYXQgc3R5bGVzaGVldCBidWlsZCB0aW1lLgotICAgKiBAcGFyYW0gdmFycyBMaXN0IG9mIFFOYW1lcyB0aGF0IGNvcnJlc3BvbmQgdG8gdmFyaWFibGVzLiAgVGhpcyBsaXN0Ci0gICAqIHNob3VsZCBiZSBzZWFyY2hlZCBiYWNrd2FyZHMgZm9yIHRoZSBmaXJzdCBxdWFsaWZpZWQgbmFtZSB0aGF0Ci0gICAqIGNvcnJlc3BvbmRzIHRvIHRoZSB2YXJpYWJsZSByZWZlcmVuY2UgcW5hbWUuICBUaGUgcG9zaXRpb24gb2YgdGhlCi0gICAqIFFOYW1lIGluIHRoZSB2ZWN0b3IgZnJvbSB0aGUgc3RhcnQgb2YgdGhlIHZlY3RvciB3aWxsIGJlIGl0cyBwb3NpdGlvbgotICAgKiBpbiB0aGUgc3RhY2sgZnJhbWUgKGJ1dCB2YXJpYWJsZXMgYWJvdmUgdGhlIGdsb2JhbHNUb3AgdmFsdWUgd2lsbCBuZWVkCi0gICAqIHRvIGJlIG9mZnNldCB0byB0aGUgY3VycmVudCBzdGFjayBmcmFtZSkuCi0gICAqLwotICBwdWJsaWMgdm9pZCBmaXh1cFZhcmlhYmxlcyhqYXZhLnV0aWwuVmVjdG9yIHZhcnMsIGludCBnbG9iYWxzU2l6ZSkKLSAgewotICAgIG1fcHJlZGljYXRlSW5kZXggPSAtMTsKLQotICAgIEF4ZXNXYWxrZXIgd2Fsa2VyID0gbV9maXJzdFdhbGtlcjsKLQotICAgIHdoaWxlIChudWxsICE9IHdhbGtlcikKLSAgICB7Ci0gICAgICB3YWxrZXIuZml4dXBWYXJpYWJsZXModmFycywgZ2xvYmFsc1NpemUpOwotICAgICAgd2Fsa2VyID0gd2Fsa2VyLmdldE5leHRXYWxrZXIoKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuWFBhdGhWaXNpdGFibGUjY2FsbFZpc2l0b3JzKEV4cHJlc3Npb25Pd25lciwgWFBhdGhWaXNpdG9yKQotICAgKi8KLSAgcHVibGljIHZvaWQgY2FsbFZpc2l0b3JzKEV4cHJlc3Npb25Pd25lciBvd25lciwgWFBhdGhWaXNpdG9yIHZpc2l0b3IpCi0gIHsKLSAgICAgICAgICAgICAgICBpZih2aXNpdG9yLnZpc2l0TG9jYXRpb25QYXRoKG93bmVyLCB0aGlzKSkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZihudWxsICE9IG1fZmlyc3RXYWxrZXIpCi0gICAgICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fZmlyc3RXYWxrZXIuY2FsbFZpc2l0b3JzKHRoaXMsIHZpc2l0b3IpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgfQotCi0KLSAgLyoqIFRoZSBsYXN0IHVzZWQgc3RlcCB3YWxrZXIgaW4gdGhlIHdhbGtlciBsaXN0LgotICAgKiAgQHNlcmlhbCAqLwotICBwcm90ZWN0ZWQgQXhlc1dhbGtlciBtX2xhc3RVc2VkV2Fsa2VyOwotCi0gIC8qKiBUaGUgaGVhZCBvZiB0aGUgc3RlcCB3YWxrZXIgbGlzdC4KLSAgICogIEBzZXJpYWwgKi8KLSAgcHJvdGVjdGVkIEF4ZXNXYWxrZXIgbV9maXJzdFdhbGtlcjsKLQotICAvKioKLSAgICogQHNlZSBFeHByZXNzaW9uT3duZXIjZ2V0RXhwcmVzc2lvbigpCi0gICAqLwotICBwdWJsaWMgRXhwcmVzc2lvbiBnZXRFeHByZXNzaW9uKCkKLSAgewotICAgIHJldHVybiBtX2ZpcnN0V2Fsa2VyOwotICB9Ci0KLSAgLyoqCi0gICAqIEBzZWUgRXhwcmVzc2lvbk93bmVyI3NldEV4cHJlc3Npb24oRXhwcmVzc2lvbikKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldEV4cHJlc3Npb24oRXhwcmVzc2lvbiBleHApCi0gIHsKLSAgICAgICAgZXhwLmV4cHJTZXRQYXJlbnQodGhpcyk7Ci0gICAgICAgIG1fZmlyc3RXYWxrZXIgPSAoQXhlc1dhbGtlcilleHA7Ci0gIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgRXhwcmVzc2lvbiNkZWVwRXF1YWxzKEV4cHJlc3Npb24pCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZGVlcEVxdWFscyhFeHByZXNzaW9uIGV4cHIpCi0gICAgewotICAgICAgaWYgKCFzdXBlci5kZWVwRXF1YWxzKGV4cHIpKQotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLQotICAgICAgQXhlc1dhbGtlciB3YWxrZXIxID0gbV9maXJzdFdhbGtlcjsKLSAgICAgIEF4ZXNXYWxrZXIgd2Fsa2VyMiA9ICgoV2Fsa2luZ0l0ZXJhdG9yKWV4cHIpLm1fZmlyc3RXYWxrZXI7Ci0gICAgICB3aGlsZSAoKG51bGwgIT0gd2Fsa2VyMSkgJiYgKG51bGwgIT0gd2Fsa2VyMikpCi0gICAgICB7Ci0gICAgICAgIGlmKCF3YWxrZXIxLmRlZXBFcXVhbHMod2Fsa2VyMikpCi0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB3YWxrZXIxID0gd2Fsa2VyMS5nZXROZXh0V2Fsa2VyKCk7Ci0gICAgICAgIHdhbGtlcjIgPSB3YWxrZXIyLmdldE5leHRXYWxrZXIoKTsKLSAgICAgIH0KLQotICAgICAgaWYoKG51bGwgIT0gd2Fsa2VyMSkgfHwgKG51bGwgIT0gd2Fsa2VyMikpCi0gICAgICAgIHJldHVybiBmYWxzZTsKLQotICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2F4ZXMvV2Fsa2luZ0l0ZXJhdG9yU29ydGVkLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2F4ZXMvV2Fsa2luZ0l0ZXJhdG9yU29ydGVkLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDFhMWZlOTQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9heGVzL1dhbGtpbmdJdGVyYXRvclNvcnRlZC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjE2ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFdhbGtpbmdJdGVyYXRvclNvcnRlZC5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE0IDE5OjQ1OjIzIGplZmZzdXR0b3IgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuYXhlczsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkF4aXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5QcmVmaXhSZXNvbHZlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuY29tcGlsZXIuQ29tcGlsZXI7Ci0KLS8qKgotICogVGhpcyBjbGFzcyBpdGVyYXRlcyBvdmVyIHNldCBvZiBub2RlcyB0aGF0IG5lZWRzIHRvIGJlIHNvcnRlZC4KLSAqIEB4c2wudXNhZ2UgaW50ZXJuYWwKLSAqLwotcHVibGljIGNsYXNzIFdhbGtpbmdJdGVyYXRvclNvcnRlZCBleHRlbmRzIFdhbGtpbmdJdGVyYXRvcgotewotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNDUxMjUxMjAwNzU0MjM2ODIxM0w7Ci0KLS8vICAvKiogVHJ1ZSBpZiB0aGUgbm9kZXMgd2lsbCBiZSBmb3VuZCBpbiBkb2N1bWVudCBvcmRlciAqLwotLy8gIHByb3RlY3RlZCBib29sZWFuIG1faW5OYXR1cmFsT3JkZXIgPSBmYWxzZTsKLQotICAvKiogVHJ1ZSBpZiB0aGUgbm9kZXMgd2lsbCBiZSBmb3VuZCBpbiBkb2N1bWVudCBvcmRlciwgYW5kIHRoaXMgY2FuCi0gICAqIGJlIGRldGVybWluZWQgc3RhdGljYWxseS4gKi8KLSAgcHJvdGVjdGVkIGJvb2xlYW4gbV9pbk5hdHVyYWxPcmRlclN0YXRpYyA9IGZhbHNlOwotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBXYWxraW5nSXRlcmF0b3JTb3J0ZWQgb2JqZWN0LgotICAgKgotICAgKiBAcGFyYW0gbnNjb250ZXh0IFRoZSBuYW1lc3BhY2UgY29udGV4dCBmb3IgdGhpcyBpdGVyYXRvciwKLSAgICogc2hvdWxkIGJlIE9LIGlmIG51bGwuCi0gICAqLwotICBwdWJsaWMgV2Fsa2luZ0l0ZXJhdG9yU29ydGVkKFByZWZpeFJlc29sdmVyIG5zY29udGV4dCkKLSAgewotICAgIHN1cGVyKG5zY29udGV4dCk7Ci0gIH0KLQotICAvKioKLSAgICogQ3JlYXRlIGEgV2Fsa2luZ0l0ZXJhdG9yIGl0ZXJhdG9yLCBpbmNsdWRpbmcgY3JlYXRpb24KLSAgICogb2Ygc3RlcCB3YWxrZXJzIGZyb20gdGhlIG9wY29kZSBsaXN0LCBhbmQgY2FsbCBiYWNrCi0gICAqIGludG8gdGhlIENvbXBpbGVyIHRvIGNyZWF0ZSBwcmVkaWNhdGUgZXhwcmVzc2lvbnMuCi0gICAqCi0gICAqIEBwYXJhbSBjb21waWxlciBUaGUgQ29tcGlsZXIgd2hpY2ggaXMgY3JlYXRpbmcKLSAgICogdGhpcyBleHByZXNzaW9uLgotICAgKiBAcGFyYW0gb3BQb3MgVGhlIHBvc2l0aW9uIG9mIHRoaXMgaXRlcmF0b3IgaW4gdGhlCi0gICAqIG9wY29kZSBsaXN0IGZyb20gdGhlIGNvbXBpbGVyLgotICAgKiBAcGFyYW0gc2hvdWxkTG9hZFdhbGtlcnMgVHJ1ZSBpZiB3YWxrZXJzIHNob3VsZCBiZQotICAgKiBsb2FkZWQsIG9yIGZhbHNlIGlmIHRoaXMgaXMgYSBkZXJpdmVkIGl0ZXJhdG9yIGFuZAotICAgKiBpdCBkb2Vzbid0IHdpc2ggdG8gbG9hZCBjaGlsZCB3YWxrZXJzLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIFdhbGtpbmdJdGVyYXRvclNvcnRlZCgKLSAgICAgICAgICBDb21waWxlciBjb21waWxlciwgaW50IG9wUG9zLCBpbnQgYW5hbHlzaXMsIGJvb2xlYW4gc2hvdWxkTG9hZFdhbGtlcnMpCi0gICAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgc3VwZXIoY29tcGlsZXIsIG9wUG9zLCBhbmFseXNpcywgc2hvdWxkTG9hZFdhbGtlcnMpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdHJ1ZSBpZiBhbGwgdGhlIG5vZGVzIGluIHRoZSBpdGVyYXRpb24gd2VsbCBiZSByZXR1cm5lZCBpbiBkb2N1bWVudAotICAgKiBvcmRlci4KLSAgICoKLSAgICogQHJldHVybiB0cnVlIGFzIGEgZGVmYXVsdC4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzRG9jT3JkZXJlZCgpCi0gIHsKLSAgICByZXR1cm4gbV9pbk5hdHVyYWxPcmRlclN0YXRpYzsKLSAgfQotCi0KLSAgLyoqCi0gICAqIFRlbGwgaWYgdGhlIG5vZGVzZXQgY2FuIGJlIHdhbGtlZCBpbiBkb2Mgb3JkZXIsIHZpYSBzdGF0aWMgYW5hbHlzaXMuCi0gICAqCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgbm9kZXNldCBjYW4gYmUgd2Fsa2VkIGluIGRvYyBvcmRlciwgd2l0aG91dCBzb3J0aW5nLgotICAgKi8KLSAgYm9vbGVhbiBjYW5CZVdhbGtlZEluTmF0dXJhbERvY09yZGVyU3RhdGljKCkKLSAgewotCi0gICAgaWYgKG51bGwgIT0gbV9maXJzdFdhbGtlcikKLSAgICB7Ci0gICAgICBBeGVzV2Fsa2VyIHdhbGtlciA9IG1fZmlyc3RXYWxrZXI7Ci0gICAgICBpbnQgcHJldkF4aXMgPSAtMTsKLSAgICAgIGJvb2xlYW4gcHJldklzU2ltcGxlRG93bkF4aXMgPSB0cnVlOwotCi0gICAgICBmb3IoaW50IGkgPSAwOyBudWxsICE9IHdhbGtlcjsgaSsrKQotICAgICAgewotICAgICAgICBpbnQgYXhpcyA9IHdhbGtlci5nZXRBeGlzKCk7Ci0KLSAgICAgICAgaWYod2Fsa2VyLmlzRG9jT3JkZXJlZCgpKQotICAgICAgICB7Ci0gICAgICAgICAgYm9vbGVhbiBpc1NpbXBsZURvd25BeGlzID0gKChheGlzID09IEF4aXMuQ0hJTEQpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IChheGlzID09IEF4aXMuU0VMRikKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgKGF4aXMgPT0gQXhpcy5ST09UKSk7Ci0gICAgICAgICAgLy8gQ2F0Y2hpbmcgdGhlIGZpbHRlcmVkIGxpc3QgaGVyZSBpcyBvbmx5IE9LIGJlY2F1c2UKLSAgICAgICAgICAvLyBGaWx0ZXJFeHByV2Fsa2VyI2lzRG9jT3JkZXJlZCgpIGRpZCB0aGUgcmlnaHQgdGhpbmcuCi0gICAgICAgICAgaWYoaXNTaW1wbGVEb3duQXhpcyB8fCAoYXhpcyA9PSAtMSkpCi0gICAgICAgICAgICB3YWxrZXIgPSB3YWxrZXIuZ2V0TmV4dFdhbGtlcigpOwotICAgICAgICAgIGVsc2UKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBib29sZWFuIGlzTGFzdFdhbGtlciA9IChudWxsID09IHdhbGtlci5nZXROZXh0V2Fsa2VyKCkpOwotICAgICAgICAgICAgaWYoaXNMYXN0V2Fsa2VyKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICBpZih3YWxrZXIuaXNEb2NPcmRlcmVkKCkgJiYgKGF4aXMgPT0gQXhpcy5ERVNDRU5EQU5UIHx8Ci0gICAgICAgICAgICAgICAgIGF4aXMgPT0gQXhpcy5ERVNDRU5EQU5UT1JTRUxGIHx8IGF4aXMgPT0gQXhpcy5ERVNDRU5EQU5UU0ZST01ST09UCi0gICAgICAgICAgICAgICAgIHx8IGF4aXMgPT0gQXhpcy5ERVNDRU5EQU5UU09SU0VMRkZST01ST09UKSB8fCAoYXhpcyA9PSBBeGlzLkFUVFJJQlVURSkpCi0gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICB9Ci0gICAgICByZXR1cm4gdHJ1ZTsKLSAgICB9Ci0gICAgcmV0dXJuIGZhbHNlOwotICB9Ci0KLQotLy8gIC8qKgotLy8gICAqIE5FRURTRE9DIE1ldGhvZCBjYW5CZVdhbGtlZEluTmF0dXJhbERvY09yZGVyCi0vLyAgICoKLS8vICAgKgotLy8gICAqIE5FRURTRE9DIChjYW5CZVdhbGtlZEluTmF0dXJhbERvY09yZGVyKSBAcmV0dXJuCi0vLyAgICovCi0vLyAgYm9vbGVhbiBjYW5CZVdhbGtlZEluTmF0dXJhbERvY09yZGVyKCkKLS8vICB7Ci0vLwotLy8gICAgaWYgKG51bGwgIT0gbV9maXJzdFdhbGtlcikKLS8vICAgIHsKLS8vICAgICAgQXhlc1dhbGtlciB3YWxrZXIgPSBtX2ZpcnN0V2Fsa2VyOwotLy8gICAgICBpbnQgcHJldkF4aXMgPSAtMTsKLS8vICAgICAgYm9vbGVhbiBwcmV2SXNTaW1wbGVEb3duQXhpcyA9IHRydWU7Ci0vLwotLy8gICAgICBmb3IoaW50IGkgPSAwOyBudWxsICE9IHdhbGtlcjsgaSsrKQotLy8gICAgICB7Ci0vLyAgICAgICAgaW50IGF4aXMgPSB3YWxrZXIuZ2V0QXhpcygpOwotLy8KLS8vICAgICAgICBpZih3YWxrZXIuaXNEb2NPcmRlcmVkKCkpCi0vLyAgICAgICAgewotLy8gICAgICAgICAgYm9vbGVhbiBpc1NpbXBsZURvd25BeGlzID0gKChheGlzID09IEF4aXMuQ0hJTEQpCi0vLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgKGF4aXMgPT0gQXhpcy5TRUxGKQotLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IChheGlzID09IEF4aXMuUk9PVCkpOwotLy8gICAgICAgICAgLy8gQ2F0Y2hpbmcgdGhlIGZpbHRlcmVkIGxpc3QgaGVyZSBpcyBvbmx5IE9LIGJlY2F1c2UKLS8vICAgICAgICAgIC8vIEZpbHRlckV4cHJXYWxrZXIjaXNEb2NPcmRlcmVkKCkgZGlkIHRoZSByaWdodCB0aGluZy4KLS8vICAgICAgICAgIGlmKGlzU2ltcGxlRG93bkF4aXMgfHwgKGF4aXMgPT0gLTEpKQotLy8gICAgICAgICAgICB3YWxrZXIgPSB3YWxrZXIuZ2V0TmV4dFdhbGtlcigpOwotLy8gICAgICAgICAgZWxzZQotLy8gICAgICAgICAgewotLy8gICAgICAgICAgICBib29sZWFuIGlzTGFzdFdhbGtlciA9IChudWxsID09IHdhbGtlci5nZXROZXh0V2Fsa2VyKCkpOwotLy8gICAgICAgICAgICBpZihpc0xhc3RXYWxrZXIpCi0vLyAgICAgICAgICAgIHsKLS8vICAgICAgICAgICAgICBpZih3YWxrZXIuaXNEb2NPcmRlcmVkKCkgJiYgKGF4aXMgPT0gQXhpcy5ERVNDRU5EQU5UIHx8Ci0vLyAgICAgICAgICAgICAgICAgYXhpcyA9PSBBeGlzLkRFU0NFTkRBTlRPUlNFTEYgfHwgYXhpcyA9PSBBeGlzLkRFU0NFTkRBTlRTRlJPTVJPT1QKLS8vICAgICAgICAgICAgICAgICB8fCBheGlzID09IEF4aXMuREVTQ0VOREFOVFNPUlNFTEZGUk9NUk9PVCkgfHwgKGF4aXMgPT0gQXhpcy5BVFRSSUJVVEUpKQotLy8gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0vLyAgICAgICAgICAgIH0KLS8vICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotLy8gICAgICAgICAgfQotLy8gICAgICAgIH0KLS8vICAgICAgICBlbHNlCi0vLyAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0vLyAgICAgIH0KLS8vICAgICAgcmV0dXJuIHRydWU7Ci0vLyAgICB9Ci0vLyAgICByZXR1cm4gZmFsc2U7Ci0vLyAgfQotCi0gIC8qKgotICAgKiBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgdG8gcGVyZm9ybSBzb21lIGV4dHJhIGFuYWx5c2lzIG9mIHRoZSBpdGVyYXRvci4KLSAgICoKLSAgICogQHBhcmFtIHZhcnMgTGlzdCBvZiBRTmFtZXMgdGhhdCBjb3JyZXNwb25kIHRvIHZhcmlhYmxlcy4gIFRoaXMgbGlzdAotICAgKiBzaG91bGQgYmUgc2VhcmNoZWQgYmFja3dhcmRzIGZvciB0aGUgZmlyc3QgcXVhbGlmaWVkIG5hbWUgdGhhdAotICAgKiBjb3JyZXNwb25kcyB0byB0aGUgdmFyaWFibGUgcmVmZXJlbmNlIHFuYW1lLiAgVGhlIHBvc2l0aW9uIG9mIHRoZQotICAgKiBRTmFtZSBpbiB0aGUgdmVjdG9yIGZyb20gdGhlIHN0YXJ0IG9mIHRoZSB2ZWN0b3Igd2lsbCBiZSBpdHMgcG9zaXRpb24KLSAgICogaW4gdGhlIHN0YWNrIGZyYW1lIChidXQgdmFyaWFibGVzIGFib3ZlIHRoZSBnbG9iYWxzVG9wIHZhbHVlIHdpbGwgbmVlZAotICAgKiB0byBiZSBvZmZzZXQgdG8gdGhlIGN1cnJlbnQgc3RhY2sgZnJhbWUpLgotICAgKi8KLSAgcHVibGljIHZvaWQgZml4dXBWYXJpYWJsZXMoamF2YS51dGlsLlZlY3RvciB2YXJzLCBpbnQgZ2xvYmFsc1NpemUpCi0gIHsKLSAgICBzdXBlci5maXh1cFZhcmlhYmxlcyh2YXJzLCBnbG9iYWxzU2l6ZSk7Ci0KLSAgICBpbnQgYW5hbHlzaXMgPSBnZXRBbmFseXNpc0JpdHMoKTsKLSAgICBpZihXYWxrZXJGYWN0b3J5LmlzTmF0dXJhbERvY09yZGVyKGFuYWx5c2lzKSkKLSAgICB7Ci0gICAgICAgIG1faW5OYXR1cmFsT3JkZXJTdGF0aWMgPSB0cnVlOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgICBtX2luTmF0dXJhbE9yZGVyU3RhdGljID0gZmFsc2U7Ci0gICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiU2V0dGluZyBuYXR1cmFsIGRvYyBvcmRlciB0byBmYWxzZTogIisKLSAgICAgICAgLy8gICAgV2Fsa2VyRmFjdG9yeS5nZXRBbmFseXNpc1N0cmluZyhhbmFseXNpcykpOwotICAgIH0KLQotICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvYXhlcy9wYWNrYWdlLmh0bWwgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2F4ZXMvcGFja2FnZS5odG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkMzdjN2UyLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvYXhlcy9wYWNrYWdlLmh0bWwKKysrIC9kZXYvbnVsbApAQCAtMSwyOSArMCwwIEBACi08IS0tCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotLS0+Ci08IS0tCi0gKiBDb3B5cmlnaHQgMjAwMC0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLS0tPgotPCEtLSAkSWQ6IHBhY2thZ2UuaHRtbCx2IDEuMS4yLjEgMjAwNS8wOC8wMSAwMTozMDoyMiBqZWZmc3V0dG9yIEV4cCAkIC0tPgotPGh0bWw+Ci0gIDx0aXRsZT5YUGF0aCBMb2NhdGlvblBhdGggc3VwcG9ydC48L3RpdGxlPgotICA8Ym9keT4KLSAgICA8cD5JbXBsZW1lbnRhdGlvbiBvZiBYUGF0aCBMb2NhdGlvblBhdGggc3VwcG9ydCAtLSBwcmltYXJ5IGNsYXNzZXMgYXJlIAotICAgIExvY1BhdGhJdGVyYXRvciBhbmQgVW5pb25QYXRoSXRlcmF0b3IuPHA+Ci0gPC9ib2R5PgotPC9odG1sPgotCi0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvY29tcGlsZXIvQ29tcGlsZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvY29tcGlsZXIvQ29tcGlsZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZmQyZmJhZS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2NvbXBpbGVyL0NvbXBpbGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMjcwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IENvbXBpbGVyLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTQgMTk6NDc6MTAgamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5jb21waWxlcjsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uRXJyb3JMaXN0ZW5lcjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlNvdXJjZUxvY2F0b3I7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC5yZXMuWFNMTWVzc2FnZXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uQXhpczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1GaWx0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNSXRlcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5QcmVmaXhSZXNvbHZlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLlFOYW1lOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuU0FYU291cmNlTG9jYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuRXhwcmVzc2lvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuYXhlcy5VbmlvblBhdGhJdGVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuYXhlcy5XYWxrZXJGYWN0b3J5OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5mdW5jdGlvbnMuRnVuY0V4dEZ1bmN0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5mdW5jdGlvbnMuRnVuY0V4dEZ1bmN0aW9uQXZhaWxhYmxlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5mdW5jdGlvbnMuRnVuY3Rpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmZ1bmN0aW9ucy5Xcm9uZ051bWJlckFyZ3NFeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWE51bWJlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YU3RyaW5nOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vcGVyYXRpb25zLkFuZDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub3BlcmF0aW9ucy5EaXY7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9wZXJhdGlvbnMuRXF1YWxzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vcGVyYXRpb25zLkd0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vcGVyYXRpb25zLkd0ZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub3BlcmF0aW9ucy5MdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub3BlcmF0aW9ucy5MdGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9wZXJhdGlvbnMuTWludXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9wZXJhdGlvbnMuTW9kOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vcGVyYXRpb25zLk11bHQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9wZXJhdGlvbnMuTmVnOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vcGVyYXRpb25zLk5vdEVxdWFsczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub3BlcmF0aW9ucy5PcGVyYXRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9wZXJhdGlvbnMuT3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9wZXJhdGlvbnMuUGx1czsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub3BlcmF0aW9ucy5VbmFyeU9wZXJhdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub3BlcmF0aW9ucy5WYXJpYWJsZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucGF0dGVybnMuRnVuY3Rpb25QYXR0ZXJuOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5wYXR0ZXJucy5Ob2RlVGVzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucGF0dGVybnMuU3RlcFBhdHRlcm47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLnBhdHRlcm5zLlVuaW9uUGF0dGVybjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucmVzLlhQQVRIRXJyb3JSZXNvdXJjZXM7Ci0KLS8qKgotICogQW4gaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcyBjb21waWxlcyBhbiBYUGF0aCBzdHJpbmcgZXhwcmVzc2lvbiBpbnRvCi0gKiBhIEV4cHJlc3Npb24gb2JqZWN0LiAgVGhpcyBjbGFzcyBjb21waWxlcyB0aGUgc3RyaW5nIGludG8gYSBzZXF1ZW5jZQotICogb2Ygb3BlcmF0aW9uIGNvZGVzIChvcCBtYXApIGFuZCB0aGVuIGJ1aWxkcyBmcm9tIHRoYXQgaW50byBhbiBFeHByZXNzaW9uCi0gKiB0cmVlLgotICogQHhzbC51c2FnZSBhZHZhbmNlZAotICovCi1wdWJsaWMgY2xhc3MgQ29tcGlsZXIgZXh0ZW5kcyBPcE1hcAotewotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBDb21waWxlciBvYmplY3Qgd2l0aCBhIHNwZWNpZmljIEVycm9yTGlzdGVuZXIgYW5kCi0gICAqIFNvdXJjZUxvY2F0b3Igd2hlcmUgdGhlIGV4cHJlc3Npb24gaXMgbG9jYXRlZC4KLSAgICoKLSAgICogQHBhcmFtIGVycm9ySGFuZGxlciBFcnJvciBsaXN0ZW5lciB3aGVyZSBtZXNzYWdlcyB3aWxsIGJlIHNlbnQsIG9yIG51bGwKLSAgICogICAgICAgICAgICAgICAgICAgICBpZiBtZXNzYWdlcyBzaG91bGQgYmUgc2VudCB0byBTeXN0ZW0gZXJyLgotICAgKiBAcGFyYW0gbG9jYXRvciBUaGUgbG9jYXRpb24gb2JqZWN0IHdoZXJlIHRoZSBleHByZXNzaW9uIGxpdmVzLCB3aGljaAotICAgKiAgICAgICAgICAgICAgICBtYXkgYmUgbnVsbCwgYnV0IHdoaWNoLCBpZiBub3QgbnVsbCwgbXVzdCBiZSB2YWxpZCBvdmVyCi0gICAqICAgICAgICAgICAgICAgIHRoZSBsb25nIGhhdWwsIGluIG90aGVyIHdvcmRzLCBpdCB3aWxsIG5vdCBiZSBjbG9uZWQuCi0gICAqIEBwYXJhbSBmVGFibGUgIFRoZSBGdW5jdGlvblRhYmxlIG9iamVjdCB3aGVyZSB0aGUgeHBhdGggYnVpbGQtaW4KLSAgICogICAgICAgICAgICAgICAgZnVuY3Rpb25zIGFyZSBzdG9yZWQuCi0gICAqLwotICBwdWJsaWMgQ29tcGlsZXIoRXJyb3JMaXN0ZW5lciBlcnJvckhhbmRsZXIsIFNvdXJjZUxvY2F0b3IgbG9jYXRvciwKLSAgICAgICAgICAgIEZ1bmN0aW9uVGFibGUgZlRhYmxlKQotICB7Ci0gICAgbV9lcnJvckhhbmRsZXIgPSBlcnJvckhhbmRsZXI7Ci0gICAgbV9sb2NhdG9yID0gbG9jYXRvcjsKLSAgICBtX2Z1bmN0aW9uVGFibGUgPSBmVGFibGU7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgQ29tcGlsZXIgaW5zdGFuY2UgdGhhdCBoYXMgYSBudWxsIGVycm9yIGxpc3RlbmVyIGFuZCBhCi0gICAqIG51bGwgc291cmNlIGxvY2F0b3IuCi0gICAqLwotICBwdWJsaWMgQ29tcGlsZXIoKQotICB7Ci0gICAgbV9lcnJvckhhbmRsZXIgPSBudWxsOwotICAgIG1fbG9jYXRvciA9IG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogRXhlY3V0ZSB0aGUgWFBhdGggb2JqZWN0IGZyb20gYSBnaXZlbiBvcGNvZGUgcG9zaXRpb24uCi0gICAqIEBwYXJhbSBvcFBvcyBUaGUgY3VycmVudCBwb3NpdGlvbiBpbiB0aGUgeHBhdGgubV9vcE1hcCBhcnJheS4KLSAgICogQHJldHVybiBUaGUgcmVzdWx0IG9mIHRoZSBYUGF0aC4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBpZiB0aGVyZSBpcyBhIHN5bnRheCBvciBvdGhlciBlcnJvci4KLSAgICogQHhzbC51c2FnZSBhZHZhbmNlZAotICAgKi8KLSAgcHVibGljIEV4cHJlc3Npb24gY29tcGlsZShpbnQgb3BQb3MpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpbnQgb3AgPSBnZXRPcChvcFBvcyk7Ci0KLSAgICBFeHByZXNzaW9uIGV4cHIgPSBudWxsOwotICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbihnZXRQYXR0ZXJuU3RyaW5nKCkrIm9wOiAiK29wKTsKLSAgICBzd2l0Y2ggKG9wKQotICAgIHsKLSAgICBjYXNlIE9wQ29kZXMuT1BfWFBBVEggOgotICAgICAgZXhwciA9IGNvbXBpbGUob3BQb3MgKyAyKTsgYnJlYWs7Ci0gICAgY2FzZSBPcENvZGVzLk9QX09SIDoKLSAgICAgIGV4cHIgPSBvcihvcFBvcyk7IGJyZWFrOwotICAgIGNhc2UgT3BDb2Rlcy5PUF9BTkQgOgotICAgICAgZXhwciA9IGFuZChvcFBvcyk7IGJyZWFrOwotICAgIGNhc2UgT3BDb2Rlcy5PUF9OT1RFUVVBTFMgOgotICAgICAgZXhwciA9IG5vdGVxdWFscyhvcFBvcyk7IGJyZWFrOwotICAgIGNhc2UgT3BDb2Rlcy5PUF9FUVVBTFMgOgotICAgICAgZXhwciA9IGVxdWFscyhvcFBvcyk7IGJyZWFrOwotICAgIGNhc2UgT3BDb2Rlcy5PUF9MVEUgOgotICAgICAgZXhwciA9IGx0ZShvcFBvcyk7IGJyZWFrOwotICAgIGNhc2UgT3BDb2Rlcy5PUF9MVCA6Ci0gICAgICBleHByID0gbHQob3BQb3MpOyBicmVhazsKLSAgICBjYXNlIE9wQ29kZXMuT1BfR1RFIDoKLSAgICAgIGV4cHIgPSBndGUob3BQb3MpOyBicmVhazsKLSAgICBjYXNlIE9wQ29kZXMuT1BfR1QgOgotICAgICAgZXhwciA9IGd0KG9wUG9zKTsgYnJlYWs7Ci0gICAgY2FzZSBPcENvZGVzLk9QX1BMVVMgOgotICAgICAgZXhwciA9IHBsdXMob3BQb3MpOyBicmVhazsKLSAgICBjYXNlIE9wQ29kZXMuT1BfTUlOVVMgOgotICAgICAgZXhwciA9IG1pbnVzKG9wUG9zKTsgYnJlYWs7Ci0gICAgY2FzZSBPcENvZGVzLk9QX01VTFQgOgotICAgICAgZXhwciA9IG11bHQob3BQb3MpOyBicmVhazsKLSAgICBjYXNlIE9wQ29kZXMuT1BfRElWIDoKLSAgICAgIGV4cHIgPSBkaXYob3BQb3MpOyBicmVhazsKLSAgICBjYXNlIE9wQ29kZXMuT1BfTU9EIDoKLSAgICAgIGV4cHIgPSBtb2Qob3BQb3MpOyBicmVhazsKLS8vICAgIGNhc2UgT3BDb2Rlcy5PUF9RVU8gOgotLy8gICAgICBleHByID0gcXVvKG9wUG9zKTsgYnJlYWs7Ci0gICAgY2FzZSBPcENvZGVzLk9QX05FRyA6Ci0gICAgICBleHByID0gbmVnKG9wUG9zKTsgYnJlYWs7Ci0gICAgY2FzZSBPcENvZGVzLk9QX1NUUklORyA6Ci0gICAgICBleHByID0gc3RyaW5nKG9wUG9zKTsgYnJlYWs7Ci0gICAgY2FzZSBPcENvZGVzLk9QX0JPT0wgOgotICAgICAgZXhwciA9IGJvb2wob3BQb3MpOyBicmVhazsKLSAgICBjYXNlIE9wQ29kZXMuT1BfTlVNQkVSIDoKLSAgICAgIGV4cHIgPSBudW1iZXIob3BQb3MpOyBicmVhazsKLSAgICBjYXNlIE9wQ29kZXMuT1BfVU5JT04gOgotICAgICAgZXhwciA9IHVuaW9uKG9wUG9zKTsgYnJlYWs7Ci0gICAgY2FzZSBPcENvZGVzLk9QX0xJVEVSQUwgOgotICAgICAgZXhwciA9IGxpdGVyYWwob3BQb3MpOyBicmVhazsKLSAgICBjYXNlIE9wQ29kZXMuT1BfVkFSSUFCTEUgOgotICAgICAgZXhwciA9IHZhcmlhYmxlKG9wUG9zKTsgYnJlYWs7Ci0gICAgY2FzZSBPcENvZGVzLk9QX0dST1VQIDoKLSAgICAgIGV4cHIgPSBncm91cChvcFBvcyk7IGJyZWFrOwotICAgIGNhc2UgT3BDb2Rlcy5PUF9OVU1CRVJMSVQgOgotICAgICAgZXhwciA9IG51bWJlcmxpdChvcFBvcyk7IGJyZWFrOwotICAgIGNhc2UgT3BDb2Rlcy5PUF9BUkdVTUVOVCA6Ci0gICAgICBleHByID0gYXJnKG9wUG9zKTsgYnJlYWs7Ci0gICAgY2FzZSBPcENvZGVzLk9QX0VYVEZVTkNUSU9OIDoKLSAgICAgIGV4cHIgPSBjb21waWxlRXh0ZW5zaW9uKG9wUG9zKTsgYnJlYWs7Ci0gICAgY2FzZSBPcENvZGVzLk9QX0ZVTkNUSU9OIDoKLSAgICAgIGV4cHIgPSBjb21waWxlRnVuY3Rpb24ob3BQb3MpOyBicmVhazsKLSAgICBjYXNlIE9wQ29kZXMuT1BfTE9DQVRJT05QQVRIIDoKLSAgICAgIGV4cHIgPSBsb2NhdGlvblBhdGgob3BQb3MpOyBicmVhazsKLSAgICBjYXNlIE9wQ29kZXMuT1BfUFJFRElDQVRFIDoKLSAgICAgIGV4cHIgPSBudWxsOyBicmVhazsgIC8vIHNob3VsZCBuZXZlciBoaXQgdGhpcyBoZXJlLgotICAgIGNhc2UgT3BDb2Rlcy5PUF9NQVRDSFBBVFRFUk4gOgotICAgICAgZXhwciA9IG1hdGNoUGF0dGVybihvcFBvcyArIDIpOyBicmVhazsKLSAgICBjYXNlIE9wQ29kZXMuT1BfTE9DQVRJT05QQVRIUEFUVEVSTiA6Ci0gICAgICBleHByID0gbG9jYXRpb25QYXRoUGF0dGVybihvcFBvcyk7IGJyZWFrOwotICAgIGNhc2UgT3BDb2Rlcy5PUF9RVU86Ci0gICAgICBlcnJvcihYUEFUSEVycm9yUmVzb3VyY2VzLkVSX1VOS05PV05fT1BDT0RFLAotICAgICAgICAgICAgbmV3IE9iamVjdFtdeyAicXVvIiB9KTsgIC8vIkVSUk9SISBVbmtub3duIG9wIGNvZGU6ICIrbV9vcE1hcFtvcFBvc10pOwotICAgICAgYnJlYWs7Ci0gICAgZGVmYXVsdCA6Ci0gICAgICBlcnJvcihYUEFUSEVycm9yUmVzb3VyY2VzLkVSX1VOS05PV05fT1BDT0RFLAotICAgICAgICAgICAgbmV3IE9iamVjdFtdeyBJbnRlZ2VyLnRvU3RyaW5nKGdldE9wKG9wUG9zKSkgfSk7ICAvLyJFUlJPUiEgVW5rbm93biBvcCBjb2RlOiAiK21fb3BNYXBbb3BQb3NdKTsKLSAgICB9Ci0vLyAgICBpZihudWxsICE9IGV4cHIpCi0vLyAgICAgIGV4cHIuc2V0U291cmNlTG9jYXRvcihtX2xvY2F0b3IpOwotCi0gICAgcmV0dXJuIGV4cHI7Ci0gIH0KLQotICAvKioKLSAgICogQm90dGxlLW5lY2sgY29tcGlsYXRpb24gb2YgYW4gb3BlcmF0aW9uIHdpdGggbGVmdCBhbmQgcmlnaHQgb3BlcmFuZHMuCi0gICAqCi0gICAqIEBwYXJhbSBvcGVyYXRpb24gbm9uLW51bGwgcmVmZXJlbmNlIHRvIHBhcmVudCBvcGVyYXRpb24uCi0gICAqIEBwYXJhbSBvcFBvcyBUaGUgb3AgbWFwIHBvc2l0aW9uIG9mIHRoZSBwYXJlbnQgb3BlcmF0aW9uLgotICAgKgotICAgKiBAcmV0dXJuIHJlZmVyZW5jZSB0byB7QGxpbmsgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9wZXJhdGlvbnMuT3BlcmF0aW9ufSBpbnN0YW5jZS4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBpZiB0aGVyZSBpcyBhIHN5bnRheCBvciBvdGhlciBlcnJvci4KLSAgICovCi0gIHByaXZhdGUgRXhwcmVzc2lvbiBjb21waWxlT3BlcmF0aW9uKE9wZXJhdGlvbiBvcGVyYXRpb24sIGludCBvcFBvcykKLSAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaW50IGxlZnRQb3MgPSBnZXRGaXJzdENoaWxkUG9zKG9wUG9zKTsKLSAgICBpbnQgcmlnaHRQb3MgPSBnZXROZXh0T3BQb3MobGVmdFBvcyk7Ci0KLSAgICBvcGVyYXRpb24uc2V0TGVmdFJpZ2h0KGNvbXBpbGUobGVmdFBvcyksIGNvbXBpbGUocmlnaHRQb3MpKTsKLQotICAgIHJldHVybiBvcGVyYXRpb247Ci0gIH0KLQotICAvKioKLSAgICogQm90dGxlLW5lY2sgY29tcGlsYXRpb24gb2YgYSB1bmFyeSBvcGVyYXRpb24uCi0gICAqCi0gICAqIEBwYXJhbSB1bmFyeSBUaGUgcGFyZW50IHVuYXJ5IG9wZXJhdGlvbi4KLSAgICogQHBhcmFtIG9wUG9zIFRoZSBwb3NpdGlvbiBpbiB0aGUgb3AgbWFwIG9mIHRoZSBwYXJlbnQgb3BlcmF0aW9uLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSB1bmFyeSBhcmd1bWVudC4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBpZiBzeW50YXggb3Igb3RoZXIgZXJyb3Igb2NjdXJzLgotICAgKi8KLSAgcHJpdmF0ZSBFeHByZXNzaW9uIGNvbXBpbGVVbmFyeShVbmFyeU9wZXJhdGlvbiB1bmFyeSwgaW50IG9wUG9zKQotICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpbnQgcmlnaHRQb3MgPSBnZXRGaXJzdENoaWxkUG9zKG9wUG9zKTsKLQotICAgIHVuYXJ5LnNldFJpZ2h0KGNvbXBpbGUocmlnaHRQb3MpKTsKLQotICAgIHJldHVybiB1bmFyeTsKLSAgfQotCi0gIC8qKgotICAgKiBDb21waWxlIGFuICdvcicgb3BlcmF0aW9uLgotICAgKgotICAgKiBAcGFyYW0gb3BQb3MgVGhlIGN1cnJlbnQgcG9zaXRpb24gaW4gdGhlIG1fb3BNYXAgYXJyYXkuCi0gICAqCi0gICAqIEByZXR1cm4gcmVmZXJlbmNlIHRvIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub3BlcmF0aW9ucy5Pcn0gaW5zdGFuY2UuCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24gaWYgYSBlcnJvciBvY2N1cnMgY3JlYXRpbmcgdGhlIEV4cHJlc3Npb24uCi0gICAqLwotICBwcm90ZWN0ZWQgRXhwcmVzc2lvbiBvcihpbnQgb3BQb3MpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIGNvbXBpbGVPcGVyYXRpb24obmV3IE9yKCksIG9wUG9zKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb21waWxlIGFuICdhbmQnIG9wZXJhdGlvbi4KLSAgICoKLSAgICogQHBhcmFtIG9wUG9zIFRoZSBjdXJyZW50IHBvc2l0aW9uIGluIHRoZSBtX29wTWFwIGFycmF5LgotICAgKgotICAgKiBAcmV0dXJuIHJlZmVyZW5jZSB0byB7QGxpbmsgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9wZXJhdGlvbnMuQW5kfSBpbnN0YW5jZS4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBpZiBhIGVycm9yIG9jY3VycyBjcmVhdGluZyB0aGUgRXhwcmVzc2lvbi4KLSAgICovCi0gIHByb3RlY3RlZCBFeHByZXNzaW9uIGFuZChpbnQgb3BQb3MpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIGNvbXBpbGVPcGVyYXRpb24obmV3IEFuZCgpLCBvcFBvcyk7Ci0gIH0KLQotICAvKioKLSAgICogQ29tcGlsZSBhICchPScgb3BlcmF0aW9uLgotICAgKgotICAgKiBAcGFyYW0gb3BQb3MgVGhlIGN1cnJlbnQgcG9zaXRpb24gaW4gdGhlIG1fb3BNYXAgYXJyYXkuCi0gICAqCi0gICAqIEByZXR1cm4gcmVmZXJlbmNlIHRvIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub3BlcmF0aW9ucy5Ob3RFcXVhbHN9IGluc3RhbmNlLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uIGlmIGEgZXJyb3Igb2NjdXJzIGNyZWF0aW5nIHRoZSBFeHByZXNzaW9uLgotICAgKi8KLSAgcHJvdGVjdGVkIEV4cHJlc3Npb24gbm90ZXF1YWxzKGludCBvcFBvcykgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gY29tcGlsZU9wZXJhdGlvbihuZXcgTm90RXF1YWxzKCksIG9wUG9zKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb21waWxlIGEgJz0nIG9wZXJhdGlvbi4KLSAgICoKLSAgICogQHBhcmFtIG9wUG9zIFRoZSBjdXJyZW50IHBvc2l0aW9uIGluIHRoZSBtX29wTWFwIGFycmF5LgotICAgKgotICAgKiBAcmV0dXJuIHJlZmVyZW5jZSB0byB7QGxpbmsgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9wZXJhdGlvbnMuRXF1YWxzfSBpbnN0YW5jZS4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBpZiBhIGVycm9yIG9jY3VycyBjcmVhdGluZyB0aGUgRXhwcmVzc2lvbi4KLSAgICovCi0gIHByb3RlY3RlZCBFeHByZXNzaW9uIGVxdWFscyhpbnQgb3BQb3MpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIGNvbXBpbGVPcGVyYXRpb24obmV3IEVxdWFscygpLCBvcFBvcyk7Ci0gIH0KLQotICAvKioKLSAgICogQ29tcGlsZSBhICc8PScgb3BlcmF0aW9uLgotICAgKgotICAgKiBAcGFyYW0gb3BQb3MgVGhlIGN1cnJlbnQgcG9zaXRpb24gaW4gdGhlIG1fb3BNYXAgYXJyYXkuCi0gICAqCi0gICAqIEByZXR1cm4gcmVmZXJlbmNlIHRvIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub3BlcmF0aW9ucy5MdGV9IGluc3RhbmNlLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uIGlmIGEgZXJyb3Igb2NjdXJzIGNyZWF0aW5nIHRoZSBFeHByZXNzaW9uLgotICAgKi8KLSAgcHJvdGVjdGVkIEV4cHJlc3Npb24gbHRlKGludCBvcFBvcykgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gY29tcGlsZU9wZXJhdGlvbihuZXcgTHRlKCksIG9wUG9zKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb21waWxlIGEgJzwnIG9wZXJhdGlvbi4KLSAgICoKLSAgICogQHBhcmFtIG9wUG9zIFRoZSBjdXJyZW50IHBvc2l0aW9uIGluIHRoZSBtX29wTWFwIGFycmF5LgotICAgKgotICAgKiBAcmV0dXJuIHJlZmVyZW5jZSB0byB7QGxpbmsgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9wZXJhdGlvbnMuTHR9IGluc3RhbmNlLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uIGlmIGEgZXJyb3Igb2NjdXJzIGNyZWF0aW5nIHRoZSBFeHByZXNzaW9uLgotICAgKi8KLSAgcHJvdGVjdGVkIEV4cHJlc3Npb24gbHQoaW50IG9wUG9zKSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHJldHVybiBjb21waWxlT3BlcmF0aW9uKG5ldyBMdCgpLCBvcFBvcyk7Ci0gIH0KLQotICAvKioKLSAgICogQ29tcGlsZSBhICc+PScgb3BlcmF0aW9uLgotICAgKgotICAgKiBAcGFyYW0gb3BQb3MgVGhlIGN1cnJlbnQgcG9zaXRpb24gaW4gdGhlIG1fb3BNYXAgYXJyYXkuCi0gICAqCi0gICAqIEByZXR1cm4gcmVmZXJlbmNlIHRvIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub3BlcmF0aW9ucy5HdGV9IGluc3RhbmNlLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uIGlmIGEgZXJyb3Igb2NjdXJzIGNyZWF0aW5nIHRoZSBFeHByZXNzaW9uLgotICAgKi8KLSAgcHJvdGVjdGVkIEV4cHJlc3Npb24gZ3RlKGludCBvcFBvcykgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gY29tcGlsZU9wZXJhdGlvbihuZXcgR3RlKCksIG9wUG9zKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb21waWxlIGEgJz4nIG9wZXJhdGlvbi4KLSAgICoKLSAgICogQHBhcmFtIG9wUG9zIFRoZSBjdXJyZW50IHBvc2l0aW9uIGluIHRoZSBtX29wTWFwIGFycmF5LgotICAgKgotICAgKiBAcmV0dXJuIHJlZmVyZW5jZSB0byB7QGxpbmsgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9wZXJhdGlvbnMuR3R9IGluc3RhbmNlLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uIGlmIGEgZXJyb3Igb2NjdXJzIGNyZWF0aW5nIHRoZSBFeHByZXNzaW9uLgotICAgKi8KLSAgcHJvdGVjdGVkIEV4cHJlc3Npb24gZ3QoaW50IG9wUG9zKSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHJldHVybiBjb21waWxlT3BlcmF0aW9uKG5ldyBHdCgpLCBvcFBvcyk7Ci0gIH0KLQotICAvKioKLSAgICogQ29tcGlsZSBhICcrJyBvcGVyYXRpb24uCi0gICAqCi0gICAqIEBwYXJhbSBvcFBvcyBUaGUgY3VycmVudCBwb3NpdGlvbiBpbiB0aGUgbV9vcE1hcCBhcnJheS4KLSAgICoKLSAgICogQHJldHVybiByZWZlcmVuY2UgdG8ge0BsaW5rIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vcGVyYXRpb25zLlBsdXN9IGluc3RhbmNlLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uIGlmIGEgZXJyb3Igb2NjdXJzIGNyZWF0aW5nIHRoZSBFeHByZXNzaW9uLgotICAgKi8KLSAgcHJvdGVjdGVkIEV4cHJlc3Npb24gcGx1cyhpbnQgb3BQb3MpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIGNvbXBpbGVPcGVyYXRpb24obmV3IFBsdXMoKSwgb3BQb3MpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbXBpbGUgYSAnLScgb3BlcmF0aW9uLgotICAgKgotICAgKiBAcGFyYW0gb3BQb3MgVGhlIGN1cnJlbnQgcG9zaXRpb24gaW4gdGhlIG1fb3BNYXAgYXJyYXkuCi0gICAqCi0gICAqIEByZXR1cm4gcmVmZXJlbmNlIHRvIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub3BlcmF0aW9ucy5NaW51c30gaW5zdGFuY2UuCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24gaWYgYSBlcnJvciBvY2N1cnMgY3JlYXRpbmcgdGhlIEV4cHJlc3Npb24uCi0gICAqLwotICBwcm90ZWN0ZWQgRXhwcmVzc2lvbiBtaW51cyhpbnQgb3BQb3MpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIGNvbXBpbGVPcGVyYXRpb24obmV3IE1pbnVzKCksIG9wUG9zKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb21waWxlIGEgJyonIG9wZXJhdGlvbi4KLSAgICoKLSAgICogQHBhcmFtIG9wUG9zIFRoZSBjdXJyZW50IHBvc2l0aW9uIGluIHRoZSBtX29wTWFwIGFycmF5LgotICAgKgotICAgKiBAcmV0dXJuIHJlZmVyZW5jZSB0byB7QGxpbmsgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9wZXJhdGlvbnMuTXVsdH0gaW5zdGFuY2UuCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24gaWYgYSBlcnJvciBvY2N1cnMgY3JlYXRpbmcgdGhlIEV4cHJlc3Npb24uCi0gICAqLwotICBwcm90ZWN0ZWQgRXhwcmVzc2lvbiBtdWx0KGludCBvcFBvcykgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gY29tcGlsZU9wZXJhdGlvbihuZXcgTXVsdCgpLCBvcFBvcyk7Ci0gIH0KLQotICAvKioKLSAgICogQ29tcGlsZSBhICdkaXYnIG9wZXJhdGlvbi4KLSAgICoKLSAgICogQHBhcmFtIG9wUG9zIFRoZSBjdXJyZW50IHBvc2l0aW9uIGluIHRoZSBtX29wTWFwIGFycmF5LgotICAgKgotICAgKiBAcmV0dXJuIHJlZmVyZW5jZSB0byB7QGxpbmsgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9wZXJhdGlvbnMuRGl2fSBpbnN0YW5jZS4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBpZiBhIGVycm9yIG9jY3VycyBjcmVhdGluZyB0aGUgRXhwcmVzc2lvbi4KLSAgICovCi0gIHByb3RlY3RlZCBFeHByZXNzaW9uIGRpdihpbnQgb3BQb3MpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIGNvbXBpbGVPcGVyYXRpb24obmV3IERpdigpLCBvcFBvcyk7Ci0gIH0KLQotICAvKioKLSAgICogQ29tcGlsZSBhICdtb2QnIG9wZXJhdGlvbi4KLSAgICoKLSAgICogQHBhcmFtIG9wUG9zIFRoZSBjdXJyZW50IHBvc2l0aW9uIGluIHRoZSBtX29wTWFwIGFycmF5LgotICAgKgotICAgKiBAcmV0dXJuIHJlZmVyZW5jZSB0byB7QGxpbmsgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9wZXJhdGlvbnMuTW9kfSBpbnN0YW5jZS4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBpZiBhIGVycm9yIG9jY3VycyBjcmVhdGluZyB0aGUgRXhwcmVzc2lvbi4KLSAgICovCi0gIHByb3RlY3RlZCBFeHByZXNzaW9uIG1vZChpbnQgb3BQb3MpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIGNvbXBpbGVPcGVyYXRpb24obmV3IE1vZCgpLCBvcFBvcyk7Ci0gIH0KLQotICAvKgotICAgKiBDb21waWxlIGEgJ3F1bycgb3BlcmF0aW9uLgotICAgKgotICAgKiBAcGFyYW0gb3BQb3MgVGhlIGN1cnJlbnQgcG9zaXRpb24gaW4gdGhlIG1fb3BNYXAgYXJyYXkuCi0gICAqCi0gICAqIEByZXR1cm4gcmVmZXJlbmNlIHRvIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub3BlcmF0aW9ucy5RdW99IGluc3RhbmNlLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uIGlmIGEgZXJyb3Igb2NjdXJzIGNyZWF0aW5nIHRoZSBFeHByZXNzaW9uLgotICAgKi8KLS8vICBwcm90ZWN0ZWQgRXhwcmVzc2lvbiBxdW8oaW50IG9wUG9zKSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLS8vICB7Ci0vLyAgICByZXR1cm4gY29tcGlsZU9wZXJhdGlvbihuZXcgUXVvKCksIG9wUG9zKTsKLS8vICB9Ci0KLSAgLyoqCi0gICAqIENvbXBpbGUgYSB1bmFyeSAnLScgb3BlcmF0aW9uLgotICAgKgotICAgKiBAcGFyYW0gb3BQb3MgVGhlIGN1cnJlbnQgcG9zaXRpb24gaW4gdGhlIG1fb3BNYXAgYXJyYXkuCi0gICAqCi0gICAqIEByZXR1cm4gcmVmZXJlbmNlIHRvIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub3BlcmF0aW9ucy5OZWd9IGluc3RhbmNlLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uIGlmIGEgZXJyb3Igb2NjdXJzIGNyZWF0aW5nIHRoZSBFeHByZXNzaW9uLgotICAgKi8KLSAgcHJvdGVjdGVkIEV4cHJlc3Npb24gbmVnKGludCBvcFBvcykgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gY29tcGlsZVVuYXJ5KG5ldyBOZWcoKSwgb3BQb3MpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbXBpbGUgYSAnc3RyaW5nKC4uLiknIG9wZXJhdGlvbi4KLSAgICoKLSAgICogQHBhcmFtIG9wUG9zIFRoZSBjdXJyZW50IHBvc2l0aW9uIGluIHRoZSBtX29wTWFwIGFycmF5LgotICAgKgotICAgKiBAcmV0dXJuIHJlZmVyZW5jZSB0byB7QGxpbmsgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9wZXJhdGlvbnMuU3RyaW5nfSBpbnN0YW5jZS4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBpZiBhIGVycm9yIG9jY3VycyBjcmVhdGluZyB0aGUgRXhwcmVzc2lvbi4KLSAgICovCi0gIHByb3RlY3RlZCBFeHByZXNzaW9uIHN0cmluZyhpbnQgb3BQb3MpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIGNvbXBpbGVVbmFyeShuZXcgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9wZXJhdGlvbnMuU3RyaW5nKCksIG9wUG9zKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb21waWxlIGEgJ2Jvb2xlYW4oLi4uKScgb3BlcmF0aW9uLgotICAgKgotICAgKiBAcGFyYW0gb3BQb3MgVGhlIGN1cnJlbnQgcG9zaXRpb24gaW4gdGhlIG1fb3BNYXAgYXJyYXkuCi0gICAqCi0gICAqIEByZXR1cm4gcmVmZXJlbmNlIHRvIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub3BlcmF0aW9ucy5Cb29sfSBpbnN0YW5jZS4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBpZiBhIGVycm9yIG9jY3VycyBjcmVhdGluZyB0aGUgRXhwcmVzc2lvbi4KLSAgICovCi0gIHByb3RlY3RlZCBFeHByZXNzaW9uIGJvb2woaW50IG9wUG9zKSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHJldHVybiBjb21waWxlVW5hcnkobmV3IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vcGVyYXRpb25zLkJvb2woKSwgb3BQb3MpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbXBpbGUgYSAnbnVtYmVyKC4uLiknIG9wZXJhdGlvbi4KLSAgICoKLSAgICogQHBhcmFtIG9wUG9zIFRoZSBjdXJyZW50IHBvc2l0aW9uIGluIHRoZSBtX29wTWFwIGFycmF5LgotICAgKgotICAgKiBAcmV0dXJuIHJlZmVyZW5jZSB0byB7QGxpbmsgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9wZXJhdGlvbnMuTnVtYmVyfSBpbnN0YW5jZS4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBpZiBhIGVycm9yIG9jY3VycyBjcmVhdGluZyB0aGUgRXhwcmVzc2lvbi4KLSAgICovCi0gIHByb3RlY3RlZCBFeHByZXNzaW9uIG51bWJlcihpbnQgb3BQb3MpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIGNvbXBpbGVVbmFyeShuZXcgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9wZXJhdGlvbnMuTnVtYmVyKCksIG9wUG9zKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb21waWxlIGEgbGl0ZXJhbCBzdHJpbmcgdmFsdWUuCi0gICAqCi0gICAqIEBwYXJhbSBvcFBvcyBUaGUgY3VycmVudCBwb3NpdGlvbiBpbiB0aGUgbV9vcE1hcCBhcnJheS4KLSAgICoKLSAgICogQHJldHVybiByZWZlcmVuY2UgdG8ge0BsaW5rIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhTdHJpbmd9IGluc3RhbmNlLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uIGlmIGEgZXJyb3Igb2NjdXJzIGNyZWF0aW5nIHRoZSBFeHByZXNzaW9uLgotICAgKi8KLSAgcHJvdGVjdGVkIEV4cHJlc3Npb24gbGl0ZXJhbChpbnQgb3BQb3MpCi0gIHsKLQotICAgIG9wUG9zID0gZ2V0Rmlyc3RDaGlsZFBvcyhvcFBvcyk7Ci0KLSAgICByZXR1cm4gKFhTdHJpbmcpIGdldFRva2VuUXVldWUoKS5lbGVtZW50QXQoZ2V0T3Aob3BQb3MpKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb21waWxlIGEgbGl0ZXJhbCBudW1iZXIgdmFsdWUuCi0gICAqCi0gICAqIEBwYXJhbSBvcFBvcyBUaGUgY3VycmVudCBwb3NpdGlvbiBpbiB0aGUgbV9vcE1hcCBhcnJheS4KLSAgICoKLSAgICogQHJldHVybiByZWZlcmVuY2UgdG8ge0BsaW5rIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhOdW1iZXJ9IGluc3RhbmNlLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uIGlmIGEgZXJyb3Igb2NjdXJzIGNyZWF0aW5nIHRoZSBFeHByZXNzaW9uLgotICAgKi8KLSAgcHJvdGVjdGVkIEV4cHJlc3Npb24gbnVtYmVybGl0KGludCBvcFBvcykKLSAgewotCi0gICAgb3BQb3MgPSBnZXRGaXJzdENoaWxkUG9zKG9wUG9zKTsKLQotICAgIHJldHVybiAoWE51bWJlcikgZ2V0VG9rZW5RdWV1ZSgpLmVsZW1lbnRBdChnZXRPcChvcFBvcykpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbXBpbGUgYSB2YXJpYWJsZSByZWZlcmVuY2UuCi0gICAqCi0gICAqIEBwYXJhbSBvcFBvcyBUaGUgY3VycmVudCBwb3NpdGlvbiBpbiB0aGUgbV9vcE1hcCBhcnJheS4KLSAgICoKLSAgICogQHJldHVybiByZWZlcmVuY2UgdG8ge0BsaW5rIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vcGVyYXRpb25zLlZhcmlhYmxlfSBpbnN0YW5jZS4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBpZiBhIGVycm9yIG9jY3VycyBjcmVhdGluZyB0aGUgRXhwcmVzc2lvbi4KLSAgICovCi0gIHByb3RlY3RlZCBFeHByZXNzaW9uIHZhcmlhYmxlKGludCBvcFBvcykgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIFZhcmlhYmxlIHZhciA9IG5ldyBWYXJpYWJsZSgpOwotCi0gICAgb3BQb3MgPSBnZXRGaXJzdENoaWxkUG9zKG9wUG9zKTsKLQotICAgIGludCBuc1BvcyA9IGdldE9wKG9wUG9zKTsKLSAgICBqYXZhLmxhbmcuU3RyaW5nIG5hbWVzcGFjZQotICAgICAgPSAoT3BDb2Rlcy5FTVBUWSA9PSBuc1BvcykgPyBudWxsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogKGphdmEubGFuZy5TdHJpbmcpIGdldFRva2VuUXVldWUoKS5lbGVtZW50QXQobnNQb3MpOwotICAgIGphdmEubGFuZy5TdHJpbmcgbG9jYWxuYW1lCi0gICAgICA9IChqYXZhLmxhbmcuU3RyaW5nKSBnZXRUb2tlblF1ZXVlKCkuZWxlbWVudEF0KGdldE9wKG9wUG9zKzEpKTsKLSAgICBRTmFtZSBxbmFtZSA9IG5ldyBRTmFtZShuYW1lc3BhY2UsIGxvY2FsbmFtZSk7Ci0KLSAgICB2YXIuc2V0UU5hbWUocW5hbWUpOwotCi0gICAgcmV0dXJuIHZhcjsKLSAgfQotCi0gIC8qKgotICAgKiBDb21waWxlIGFuIGV4cHJlc3Npb24gZ3JvdXAuCi0gICAqCi0gICAqIEBwYXJhbSBvcFBvcyBUaGUgY3VycmVudCBwb3NpdGlvbiBpbiB0aGUgbV9vcE1hcCBhcnJheS4KLSAgICoKLSAgICogQHJldHVybiByZWZlcmVuY2UgdG8gdGhlIGNvbnRhaW5lZCBleHByZXNzaW9uLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uIGlmIGEgZXJyb3Igb2NjdXJzIGNyZWF0aW5nIHRoZSBFeHByZXNzaW9uLgotICAgKi8KLSAgcHJvdGVjdGVkIEV4cHJlc3Npb24gZ3JvdXAoaW50IG9wUG9zKSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgLy8gbm8tb3AKLSAgICByZXR1cm4gY29tcGlsZShvcFBvcyArIDIpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbXBpbGUgYSBmdW5jdGlvbiBhcmd1bWVudC4KLSAgICoKLSAgICogQHBhcmFtIG9wUG9zIFRoZSBjdXJyZW50IHBvc2l0aW9uIGluIHRoZSBtX29wTWFwIGFycmF5LgotICAgKgotICAgKiBAcmV0dXJuIHJlZmVyZW5jZSB0byB0aGUgYXJndW1lbnQgZXhwcmVzc2lvbi4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBpZiBhIGVycm9yIG9jY3VycyBjcmVhdGluZyB0aGUgRXhwcmVzc2lvbi4KLSAgICovCi0gIHByb3RlY3RlZCBFeHByZXNzaW9uIGFyZyhpbnQgb3BQb3MpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICAvLyBuby1vcAotICAgIHJldHVybiBjb21waWxlKG9wUG9zICsgMik7Ci0gIH0KLQotICAvKioKLSAgICogQ29tcGlsZSBhIGxvY2F0aW9uIHBhdGggdW5pb24uIFRoZSBVbmlvblBhdGhJdGVyYXRvciBpdHNlbGYgbWF5IGNyZWF0ZQotICAgKiB7QGxpbmsgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmF4ZXMuTG9jUGF0aEl0ZXJhdG9yfSBjaGlsZHJlbi4KLSAgICoKLSAgICogQHBhcmFtIG9wUG9zIFRoZSBjdXJyZW50IHBvc2l0aW9uIGluIHRoZSBtX29wTWFwIGFycmF5LgotICAgKgotICAgKiBAcmV0dXJuIHJlZmVyZW5jZSB0byB7QGxpbmsgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmF4ZXMuTG9jUGF0aEl0ZXJhdG9yfSBpbnN0YW5jZS4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBpZiBhIGVycm9yIG9jY3VycyBjcmVhdGluZyB0aGUgRXhwcmVzc2lvbi4KLSAgICovCi0gIHByb3RlY3RlZCBFeHByZXNzaW9uIHVuaW9uKGludCBvcFBvcykgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICBsb2NQYXRoRGVwdGgrKzsKLSAgICB0cnkKLSAgICB7Ci0gICAgICByZXR1cm4gVW5pb25QYXRoSXRlcmF0b3IuY3JlYXRlVW5pb25JdGVyYXRvcih0aGlzLCBvcFBvcyk7Ci0gICAgfQotICAgIGZpbmFsbHkKLSAgICB7Ci0gICAgICBsb2NQYXRoRGVwdGgtLTsKLSAgICB9Ci0gIH0KLQotICBwcml2YXRlIGludCBsb2NQYXRoRGVwdGggPSAtMTsKLQotICAvKioKLSAgICogR2V0IHRoZSBsZXZlbCBvZiB0aGUgbG9jYXRpb24gcGF0aCBvciB1bmlvbiBiZWluZyBjb25zdHJ1Y3RlZC4KLSAgICogQHJldHVybiAwIGlmIGl0IGlzIGEgdG9wLWxldmVsIHBhdGguCi0gICAqLwotICBwdWJsaWMgaW50IGdldExvY2F0aW9uUGF0aERlcHRoKCkKLSAgewotICAgIHJldHVybiBsb2NQYXRoRGVwdGg7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBmdW5jdGlvbiB0YWJsZQotICAgKi8KLSAgRnVuY3Rpb25UYWJsZSBnZXRGdW5jdGlvblRhYmxlKCkKLSAgewotICAgIHJldHVybiBtX2Z1bmN0aW9uVGFibGU7Ci0gIH0KLQotICAvKioKLSAgICogQ29tcGlsZSBhIGxvY2F0aW9uIHBhdGguICBUaGUgTG9jUGF0aEl0ZXJhdG9yIGl0c2VsZiBtYXkgY3JlYXRlCi0gICAqIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuYXhlcy5BeGVzV2Fsa2VyfSBjaGlsZHJlbi4KLSAgICoKLSAgICogQHBhcmFtIG9wUG9zIFRoZSBjdXJyZW50IHBvc2l0aW9uIGluIHRoZSBtX29wTWFwIGFycmF5LgotICAgKgotICAgKiBAcmV0dXJuIHJlZmVyZW5jZSB0byB7QGxpbmsgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmF4ZXMuTG9jUGF0aEl0ZXJhdG9yfSBpbnN0YW5jZS4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBpZiBhIGVycm9yIG9jY3VycyBjcmVhdGluZyB0aGUgRXhwcmVzc2lvbi4KLSAgICovCi0gIHB1YmxpYyBFeHByZXNzaW9uIGxvY2F0aW9uUGF0aChpbnQgb3BQb3MpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgbG9jUGF0aERlcHRoKys7Ci0gICAgdHJ5Ci0gICAgewotICAgICAgRFRNSXRlcmF0b3IgaXRlciA9IFdhbGtlckZhY3RvcnkubmV3RFRNSXRlcmF0b3IodGhpcywgb3BQb3MsIChsb2NQYXRoRGVwdGggPT0gMCkpOwotICAgICAgcmV0dXJuIChFeHByZXNzaW9uKWl0ZXI7IC8vIGNhc3QgT0ssIEkgZ3Vlc3MuCi0gICAgfQotICAgIGZpbmFsbHkKLSAgICB7Ci0gICAgICBsb2NQYXRoRGVwdGgtLTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogQ29tcGlsZSBhIGxvY2F0aW9uIHN0ZXAgcHJlZGljYXRlIGV4cHJlc3Npb24uCi0gICAqCi0gICAqIEBwYXJhbSBvcFBvcyBUaGUgY3VycmVudCBwb3NpdGlvbiBpbiB0aGUgbV9vcE1hcCBhcnJheS4KLSAgICoKLSAgICogQHJldHVybiB0aGUgY29udGFpbmVkIHByZWRpY2F0ZSBleHByZXNzaW9uLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uIGlmIGEgZXJyb3Igb2NjdXJzIGNyZWF0aW5nIHRoZSBFeHByZXNzaW9uLgotICAgKi8KLSAgcHVibGljIEV4cHJlc3Npb24gcHJlZGljYXRlKGludCBvcFBvcykgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gY29tcGlsZShvcFBvcyArIDIpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbXBpbGUgYW4gZW50aXJlIG1hdGNoIHBhdHRlcm4gZXhwcmVzc2lvbi4KLSAgICoKLSAgICogQHBhcmFtIG9wUG9zIFRoZSBjdXJyZW50IHBvc2l0aW9uIGluIHRoZSBtX29wTWFwIGFycmF5LgotICAgKgotICAgKiBAcmV0dXJuIHJlZmVyZW5jZSB0byB7QGxpbmsgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLnBhdHRlcm5zLlVuaW9uUGF0dGVybn0gaW5zdGFuY2UuCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24gaWYgYSBlcnJvciBvY2N1cnMgY3JlYXRpbmcgdGhlIEV4cHJlc3Npb24uCi0gICAqLwotICBwcm90ZWN0ZWQgRXhwcmVzc2lvbiBtYXRjaFBhdHRlcm4oaW50IG9wUG9zKSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIGxvY1BhdGhEZXB0aCsrOwotICAgIHRyeQotICAgIHsKLSAgICAgIC8vIEZpcnN0LCBjb3VudC4uLgotICAgICAgaW50IG5leHRPcFBvcyA9IG9wUG9zOwotICAgICAgaW50IGk7Ci0KLSAgICAgIGZvciAoaSA9IDA7IGdldE9wKG5leHRPcFBvcykgPT0gT3BDb2Rlcy5PUF9MT0NBVElPTlBBVEhQQVRURVJOOyBpKyspCi0gICAgICB7Ci0gICAgICAgIG5leHRPcFBvcyA9IGdldE5leHRPcFBvcyhuZXh0T3BQb3MpOwotICAgICAgfQotCi0gICAgICBpZiAoaSA9PSAxKQotICAgICAgICByZXR1cm4gY29tcGlsZShvcFBvcyk7Ci0KLSAgICAgIFVuaW9uUGF0dGVybiB1cCA9IG5ldyBVbmlvblBhdHRlcm4oKTsKLSAgICAgIFN0ZXBQYXR0ZXJuW10gcGF0dGVybnMgPSBuZXcgU3RlcFBhdHRlcm5baV07Ci0KLSAgICAgIGZvciAoaSA9IDA7IGdldE9wKG9wUG9zKSA9PSBPcENvZGVzLk9QX0xPQ0FUSU9OUEFUSFBBVFRFUk47IGkrKykKLSAgICAgIHsKLSAgICAgICAgbmV4dE9wUG9zID0gZ2V0TmV4dE9wUG9zKG9wUG9zKTsKLSAgICAgICAgcGF0dGVybnNbaV0gPSAoU3RlcFBhdHRlcm4pIGNvbXBpbGUob3BQb3MpOwotICAgICAgICBvcFBvcyA9IG5leHRPcFBvczsKLSAgICAgIH0KLQotICAgICAgdXAuc2V0UGF0dGVybnMocGF0dGVybnMpOwotCi0gICAgICByZXR1cm4gdXA7Ci0gICAgfQotICAgIGZpbmFsbHkKLSAgICB7Ci0gICAgICBsb2NQYXRoRGVwdGgtLTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogQ29tcGlsZSBhIGxvY2F0aW9uIG1hdGNoIHBhdHRlcm4gdW5pdCBleHByZXNzaW9uLgotICAgKgotICAgKiBAcGFyYW0gb3BQb3MgVGhlIGN1cnJlbnQgcG9zaXRpb24gaW4gdGhlIG1fb3BNYXAgYXJyYXkuCi0gICAqCi0gICAqIEByZXR1cm4gcmVmZXJlbmNlIHRvIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucGF0dGVybnMuU3RlcFBhdHRlcm59IGluc3RhbmNlLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uIGlmIGEgZXJyb3Igb2NjdXJzIGNyZWF0aW5nIHRoZSBFeHByZXNzaW9uLgotICAgKi8KLSAgcHVibGljIEV4cHJlc3Npb24gbG9jYXRpb25QYXRoUGF0dGVybihpbnQgb3BQb3MpCi0gICAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIG9wUG9zID0gZ2V0Rmlyc3RDaGlsZFBvcyhvcFBvcyk7Ci0KLSAgICByZXR1cm4gc3RlcFBhdHRlcm4ob3BQb3MsIDAsIG51bGwpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBhIHtAbGluayBvcmcudzNjLmRvbS50cmF2ZXJzYWwuTm9kZUZpbHRlcn0gYml0IHNldCB0aGF0IHRlbGxzIHdoYXQKLSAgICogdG8gc2hvdyBmb3IgYSBnaXZlbiBub2RlIHRlc3QuCi0gICAqCi0gICAqIEBwYXJhbSBvcFBvcyB0aGUgb3AgbWFwIHBvc2l0aW9uIGZvciB0aGUgbG9jYXRpb24gc3RlcC4KLSAgICoKLSAgICogQHJldHVybiB7QGxpbmsgb3JnLnczYy5kb20udHJhdmVyc2FsLk5vZGVGaWx0ZXJ9IGJpdCBzZXQgdGhhdCB0ZWxscyB3aGF0Ci0gICAqICAgICAgICAgdG8gc2hvdyBmb3IgYSBnaXZlbiBub2RlIHRlc3QuCi0gICAqLwotICBwdWJsaWMgaW50IGdldFdoYXRUb1Nob3coaW50IG9wUG9zKQotICB7Ci0KLSAgICBpbnQgYXhlc1R5cGUgPSBnZXRPcChvcFBvcyk7Ci0gICAgaW50IHRlc3RUeXBlID0gZ2V0T3Aob3BQb3MgKyAzKTsKLQotICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigidGVzdFR5cGU6ICIrdGVzdFR5cGUpOwotICAgIHN3aXRjaCAodGVzdFR5cGUpCi0gICAgewotICAgIGNhc2UgT3BDb2Rlcy5OT0RFVFlQRV9DT01NRU5UIDoKLSAgICAgIHJldHVybiBEVE1GaWx0ZXIuU0hPV19DT01NRU5UOwotICAgIGNhc2UgT3BDb2Rlcy5OT0RFVFlQRV9URVhUIDoKLS8vICAgICAgcmV0dXJuIERUTUZpbHRlci5TSE9XX1RFWFQgfCBEVE1GaWx0ZXIuU0hPV19DT01NRU5UOwotICAgICAgcmV0dXJuIERUTUZpbHRlci5TSE9XX1RFWFQgfCBEVE1GaWx0ZXIuU0hPV19DREFUQV9TRUNUSU9OIDsKLSAgICBjYXNlIE9wQ29kZXMuTk9ERVRZUEVfUEkgOgotICAgICAgcmV0dXJuIERUTUZpbHRlci5TSE9XX1BST0NFU1NJTkdfSU5TVFJVQ1RJT047Ci0gICAgY2FzZSBPcENvZGVzLk5PREVUWVBFX05PREUgOgotLy8gICAgICByZXR1cm4gRFRNRmlsdGVyLlNIT1dfQUxMOwotICAgICAgc3dpdGNoIChheGVzVHlwZSkKLSAgICAgIHsKLSAgICAgIGNhc2UgT3BDb2Rlcy5GUk9NX05BTUVTUEFDRToKLSAgICAgICAgcmV0dXJuIERUTUZpbHRlci5TSE9XX05BTUVTUEFDRTsKLSAgICAgIGNhc2UgT3BDb2Rlcy5GUk9NX0FUVFJJQlVURVMgOgotICAgICAgY2FzZSBPcENvZGVzLk1BVENIX0FUVFJJQlVURSA6Ci0gICAgICAgIHJldHVybiBEVE1GaWx0ZXIuU0hPV19BVFRSSUJVVEU7Ci0gICAgICBjYXNlIE9wQ29kZXMuRlJPTV9TRUxGOgotICAgICAgY2FzZSBPcENvZGVzLkZST01fQU5DRVNUT1JTX09SX1NFTEY6Ci0gICAgICBjYXNlIE9wQ29kZXMuRlJPTV9ERVNDRU5EQU5UU19PUl9TRUxGOgotICAgICAgICByZXR1cm4gRFRNRmlsdGVyLlNIT1dfQUxMOwotICAgICAgZGVmYXVsdDoKLSAgICAgICAgaWYgKGdldE9wKDApID09IE9wQ29kZXMuT1BfTUFUQ0hQQVRURVJOKQotICAgICAgICAgIHJldHVybiB+RFRNRmlsdGVyLlNIT1dfQVRUUklCVVRFCi0gICAgICAgICAgICAgICAgICAmIH5EVE1GaWx0ZXIuU0hPV19ET0NVTUVOVAotICAgICAgICAgICAgICAgICAgJiB+RFRNRmlsdGVyLlNIT1dfRE9DVU1FTlRfRlJBR01FTlQ7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICByZXR1cm4gfkRUTUZpbHRlci5TSE9XX0FUVFJJQlVURTsKLSAgICAgIH0KLSAgICBjYXNlIE9wQ29kZXMuTk9ERVRZUEVfUk9PVCA6Ci0gICAgICByZXR1cm4gRFRNRmlsdGVyLlNIT1dfRE9DVU1FTlQgfCBEVE1GaWx0ZXIuU0hPV19ET0NVTUVOVF9GUkFHTUVOVDsKLSAgICBjYXNlIE9wQ29kZXMuTk9ERVRZUEVfRlVOQ1RFU1QgOgotICAgICAgcmV0dXJuIE5vZGVUZXN0LlNIT1dfQllGVU5DVElPTjsKLSAgICBjYXNlIE9wQ29kZXMuTk9ERU5BTUUgOgotICAgICAgc3dpdGNoIChheGVzVHlwZSkKLSAgICAgIHsKLSAgICAgIGNhc2UgT3BDb2Rlcy5GUk9NX05BTUVTUEFDRSA6Ci0gICAgICAgIHJldHVybiBEVE1GaWx0ZXIuU0hPV19OQU1FU1BBQ0U7Ci0gICAgICBjYXNlIE9wQ29kZXMuRlJPTV9BVFRSSUJVVEVTIDoKLSAgICAgIGNhc2UgT3BDb2Rlcy5NQVRDSF9BVFRSSUJVVEUgOgotICAgICAgICByZXR1cm4gRFRNRmlsdGVyLlNIT1dfQVRUUklCVVRFOwotCi0gICAgICAvLyBicmVhazsKLSAgICAgIGNhc2UgT3BDb2Rlcy5NQVRDSF9BTllfQU5DRVNUT1IgOgotICAgICAgY2FzZSBPcENvZGVzLk1BVENIX0lNTUVESUFURV9BTkNFU1RPUiA6Ci0gICAgICAgIHJldHVybiBEVE1GaWx0ZXIuU0hPV19FTEVNRU5UOwotCi0gICAgICAvLyBicmVhazsKLSAgICAgIGRlZmF1bHQgOgotICAgICAgICByZXR1cm4gRFRNRmlsdGVyLlNIT1dfRUxFTUVOVDsKLSAgICAgIH0KLSAgICBkZWZhdWx0IDoKLSAgICAgIC8vIFN5c3RlbS5lcnIucHJpbnRsbigiV2Ugc2hvdWxkIG5ldmVyIHJlYWNoIGhlcmUuIik7Ci0gICAgICByZXR1cm4gRFRNRmlsdGVyLlNIT1dfQUxMOwotICAgIH0KLSAgfQotCi1wcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIERFQlVHID0gZmFsc2U7Ci0KLSAgLyoqCi0gICAqIENvbXBpbGUgYSBzdGVwIHBhdHRlcm4gdW5pdCBleHByZXNzaW9uLCB1c2VkIGZvciBib3RoIGxvY2F0aW9uIHBhdGhzCi0gICAqIGFuZCBtYXRjaCBwYXR0ZXJucy4KLSAgICoKLSAgICogQHBhcmFtIG9wUG9zIFRoZSBjdXJyZW50IHBvc2l0aW9uIGluIHRoZSBtX29wTWFwIGFycmF5LgotICAgKiBAcGFyYW0gc3RlcENvdW50IFRoZSBudW1iZXIgb2Ygc3RlcHMgdG8gZXhwZWN0LgotICAgKiBAcGFyYW0gYW5jZXN0b3JQYXR0ZXJuIFRoZSBvd25pbmcgU3RlcFBhdHRlcm4sIHdoaWNoIG1heSBiZSBudWxsLgotICAgKgotICAgKiBAcmV0dXJuIHJlZmVyZW5jZSB0byB7QGxpbmsgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLnBhdHRlcm5zLlN0ZXBQYXR0ZXJufSBpbnN0YW5jZS4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBpZiBhIGVycm9yIG9jY3VycyBjcmVhdGluZyB0aGUgRXhwcmVzc2lvbi4KLSAgICovCi0gIHByb3RlY3RlZCBTdGVwUGF0dGVybiBzdGVwUGF0dGVybigKLSAgICAgICAgICBpbnQgb3BQb3MsIGludCBzdGVwQ291bnQsIFN0ZXBQYXR0ZXJuIGFuY2VzdG9yUGF0dGVybikKLSAgICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpbnQgc3RhcnRPcFBvcyA9IG9wUG9zOwotICAgIGludCBzdGVwVHlwZSA9IGdldE9wKG9wUG9zKTsKLQotICAgIGlmIChPcENvZGVzLkVORE9QID09IHN0ZXBUeXBlKQotICAgIHsKLSAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIGJvb2xlYW4gYWRkTWFnaWNTZWxmID0gdHJ1ZTsKLQotICAgIGludCBlbmRTdGVwID0gZ2V0TmV4dE9wUG9zKG9wUG9zKTsKLQotICAgIC8vIGludCBuZXh0U3RlcFR5cGUgPSBnZXRPcE1hcCgpW2VuZFN0ZXBdOwotICAgIFN0ZXBQYXR0ZXJuIHBhdHRlcm47Ci0KLSAgICAvLyBib29sZWFuIGlzU2ltcGxlID0gKChPcENvZGVzLkVORE9QID09IG5leHRTdGVwVHlwZSkgJiYgKHN0ZXBDb3VudCA9PSAwKSk7Ci0gICAgaW50IGFyZ0xlbjsKLQotICAgIHN3aXRjaCAoc3RlcFR5cGUpCi0gICAgewotICAgIGNhc2UgT3BDb2Rlcy5PUF9GVU5DVElPTiA6Ci0gICAgICBpZihERUJVRykKLSAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJNQVRDSF9GVU5DVElPTjogIittX2N1cnJlbnRQYXR0ZXJuKTsKLSAgICAgIGFkZE1hZ2ljU2VsZiA9IGZhbHNlOwotICAgICAgYXJnTGVuID0gZ2V0T3Aob3BQb3MgKyBPcE1hcC5NQVBJTkRFWF9MRU5HVEgpOwotICAgICAgcGF0dGVybiA9IG5ldyBGdW5jdGlvblBhdHRlcm4oY29tcGlsZUZ1bmN0aW9uKG9wUG9zKSwgQXhpcy5QQVJFTlQsIEF4aXMuQ0hJTEQpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBPcENvZGVzLkZST01fUk9PVCA6Ci0gICAgICBpZihERUJVRykKLSAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJGUk9NX1JPT1QsICIrbV9jdXJyZW50UGF0dGVybik7Ci0gICAgICBhZGRNYWdpY1NlbGYgPSBmYWxzZTsKLSAgICAgIGFyZ0xlbiA9IGdldEFyZ0xlbmd0aE9mU3RlcChvcFBvcyk7Ci0gICAgICBvcFBvcyA9IGdldEZpcnN0Q2hpbGRQb3NPZlN0ZXAob3BQb3MpOwotICAgICAgcGF0dGVybiA9IG5ldyBTdGVwUGF0dGVybihEVE1GaWx0ZXIuU0hPV19ET0NVTUVOVCB8Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERUTUZpbHRlci5TSE9XX0RPQ1VNRU5UX0ZSQUdNRU5ULAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBeGlzLlBBUkVOVCwgQXhpcy5DSElMRCk7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIE9wQ29kZXMuTUFUQ0hfQVRUUklCVVRFIDoKLSAgICAgaWYoREVCVUcpCi0gICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiTUFUQ0hfQVRUUklCVVRFOiAiK2dldFN0ZXBMb2NhbE5hbWUoc3RhcnRPcFBvcykrIiwgIittX2N1cnJlbnRQYXR0ZXJuKTsKLSAgICAgIGFyZ0xlbiA9IGdldEFyZ0xlbmd0aE9mU3RlcChvcFBvcyk7Ci0gICAgICBvcFBvcyA9IGdldEZpcnN0Q2hpbGRQb3NPZlN0ZXAob3BQb3MpOwotICAgICAgcGF0dGVybiA9IG5ldyBTdGVwUGF0dGVybihEVE1GaWx0ZXIuU0hPV19BVFRSSUJVVEUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldFN0ZXBOUyhzdGFydE9wUG9zKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0U3RlcExvY2FsTmFtZShzdGFydE9wUG9zKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXhpcy5QQVJFTlQsIEF4aXMuQVRUUklCVVRFKTsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgT3BDb2Rlcy5NQVRDSF9BTllfQU5DRVNUT1IgOgotICAgICAgaWYoREVCVUcpCi0gICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiTUFUQ0hfQU5ZX0FOQ0VTVE9SOiAiK2dldFN0ZXBMb2NhbE5hbWUoc3RhcnRPcFBvcykrIiwgIittX2N1cnJlbnRQYXR0ZXJuKTsKLSAgICAgIGFyZ0xlbiA9IGdldEFyZ0xlbmd0aE9mU3RlcChvcFBvcyk7Ci0gICAgICBvcFBvcyA9IGdldEZpcnN0Q2hpbGRQb3NPZlN0ZXAob3BQb3MpOwotICAgICAgaW50IHdoYXQgPSBnZXRXaGF0VG9TaG93KHN0YXJ0T3BQb3MpOwotICAgICAgLy8gYml0LW8taGFja2VyeSwgYnV0IHRoaXMgY29kZSBpcyBkdWUgZm9yIHRoZSBtb3JndWUgYW55d2F5Li4uCi0gICAgICBpZigweDAwMDAwNTAwID09IHdoYXQpCi0gICAgICAgIGFkZE1hZ2ljU2VsZiA9IGZhbHNlOwotICAgICAgcGF0dGVybiA9IG5ldyBTdGVwUGF0dGVybihnZXRXaGF0VG9TaG93KHN0YXJ0T3BQb3MpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldFN0ZXBOUyhzdGFydE9wUG9zKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRTdGVwTG9jYWxOYW1lKHN0YXJ0T3BQb3MpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF4aXMuQU5DRVNUT1IsIEF4aXMuQ0hJTEQpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBPcENvZGVzLk1BVENIX0lNTUVESUFURV9BTkNFU1RPUiA6Ci0gICAgICBpZihERUJVRykKLSAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJNQVRDSF9JTU1FRElBVEVfQU5DRVNUT1I6ICIrZ2V0U3RlcExvY2FsTmFtZShzdGFydE9wUG9zKSsiLCAiK21fY3VycmVudFBhdHRlcm4pOwotICAgICAgYXJnTGVuID0gZ2V0QXJnTGVuZ3RoT2ZTdGVwKG9wUG9zKTsKLSAgICAgIG9wUG9zID0gZ2V0Rmlyc3RDaGlsZFBvc09mU3RlcChvcFBvcyk7Ci0gICAgICBwYXR0ZXJuID0gbmV3IFN0ZXBQYXR0ZXJuKGdldFdoYXRUb1Nob3coc3RhcnRPcFBvcyksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldFN0ZXBOUyhzdGFydE9wUG9zKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0U3RlcExvY2FsTmFtZShzdGFydE9wUG9zKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXhpcy5QQVJFTlQsIEF4aXMuQ0hJTEQpOwotICAgICAgYnJlYWs7Ci0gICAgZGVmYXVsdCA6Ci0gICAgICBlcnJvcihYUEFUSEVycm9yUmVzb3VyY2VzLkVSX1VOS05PV05fTUFUQ0hfT1BFUkFUSU9OLCBudWxsKTsgIC8vInVua25vd24gbWF0Y2ggb3BlcmF0aW9uISIpOwotCi0gICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICBwYXR0ZXJuLnNldFByZWRpY2F0ZXMoZ2V0Q29tcGlsZWRQcmVkaWNhdGVzKG9wUG9zICsgYXJnTGVuKSk7Ci0gICAgaWYobnVsbCA9PSBhbmNlc3RvclBhdHRlcm4pCi0gICAgewotICAgICAgLy8gVGhpcyBpcyB0aGUgbWFnaWMgYW5kIGludmlzaWJsZSAiLiIgYXQgdGhlIGhlYWQgb2YgZXZlcnkKLSAgICAgIC8vIG1hdGNoIHBhdHRlcm4sIGFuZCBjb3JyZXNwb25kcyB0byB0aGUgY3VycmVudCBub2RlIGluIHRoZSBjb250ZXh0Ci0gICAgICAvLyBsaXN0LCBmcm9tIHdoZXJlIHByZWRpY2F0ZXMgYXJlIGNvdW50ZWQuCi0gICAgICAvLyBTbywgaW4gb3JkZXIgdG8gY2FsY3VsYXRlICJmb29bM10iLCBpdCBoYXMgdG8gY291bnQgZnJvbSB0aGUKLSAgICAgIC8vIGN1cnJlbnQgbm9kZSBpbiB0aGUgY29udGV4dCBsaXN0LCBzbywgZnJvbSB0aGF0IGN1cnJlbnQgbm9kZSwKLSAgICAgIC8vIHRoZSBmdWxsIHBhdHRlcm4gaXMgcmVhbGx5ICJzZWxmOjpub2RlKCkvY2hpbGQ6OmZvb1szXSIuICBJZiB5b3UKLSAgICAgIC8vIHRyYW5zbGF0ZSB0aGlzIHRvIGEgc2VsZWN0IHBhdHRlcm4gZnJvbSB0aGUgbm9kZSBiZWluZyB0ZXN0ZWQsCi0gICAgICAvLyB3aGljaCBpcyByZWFsbHkgaG93IHdlJ3JlIHRyZWF0aW5nIG1hdGNoIHBhdHRlcm5zLCBpdCB3b3JrcyBvdXQgdG8KLSAgICAgIC8vIHNlbGY6OmZvby9wYXJlbnQ6Om5vZGVbY2hpbGQ6OmZvb1szXV0iLCBvciBjbG9zZSBlbm91Z2guCi0gICAgICAgIC8qICAgICAgaWYoYWRkTWFnaWNTZWxmICYmIHBhdHRlcm4uZ2V0UHJlZGljYXRlQ291bnQoKSA+IDApCi0gICAgICB7Ci0gICAgICAgIFN0ZXBQYXR0ZXJuIHNlbGZQYXR0ZXJuID0gbmV3IFN0ZXBQYXR0ZXJuKERUTUZpbHRlci5TSE9XX0FMTCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXhpcy5QQVJFTlQsIEF4aXMuQ0hJTEQpOwotICAgICAgICAvLyBXZSBuZWVkIHRvIGtlZXAgdGhlIG5ldyBub2RldGVzdCBmcm9tIGFmZmVjdGluZyB0aGUgc2NvcmUuLi4KLSAgICAgICAgWE51bWJlciBzY29yZSA9IHBhdHRlcm4uZ2V0U3RhdGljU2NvcmUoKTsKLSAgICAgICAgcGF0dGVybi5zZXRSZWxhdGl2ZVBhdGhQYXR0ZXJuKHNlbGZQYXR0ZXJuKTsKLSAgICAgICAgcGF0dGVybi5zZXRTdGF0aWNTY29yZShzY29yZSk7Ci0gICAgICAgIHNlbGZQYXR0ZXJuLnNldFN0YXRpY1Njb3JlKHNjb3JlKTsKLSAgICAgICAgfSovCi0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIlNldHRpbmcgIithbmNlc3RvclBhdHRlcm4rIiBhcyByZWxhdGl2ZSB0byAiK3BhdHRlcm4pOwotICAgICAgcGF0dGVybi5zZXRSZWxhdGl2ZVBhdGhQYXR0ZXJuKGFuY2VzdG9yUGF0dGVybik7Ci0gICAgfQotCi0gICAgU3RlcFBhdHRlcm4gcmVsYXRpdmVQYXRoUGF0dGVybiA9IHN0ZXBQYXR0ZXJuKGVuZFN0ZXAsIHN0ZXBDb3VudCArIDEsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF0dGVybik7Ci0KLSAgICByZXR1cm4gKG51bGwgIT0gcmVsYXRpdmVQYXRoUGF0dGVybikgPyByZWxhdGl2ZVBhdGhQYXR0ZXJuIDogcGF0dGVybjsKLSAgfQotCi0gIC8qKgotICAgKiBDb21waWxlIGEgemVybyBvciBtb3JlIHByZWRpY2F0ZXMgZm9yIGEgZ2l2ZW4gbWF0Y2ggcGF0dGVybi4KLSAgICoKLSAgICogQHBhcmFtIG9wUG9zIFRoZSBwb3NpdGlvbiBvZiB0aGUgZmlyc3QgcHJlZGljYXRlIHRoZSBtX29wTWFwIGFycmF5LgotICAgKgotICAgKiBAcmV0dXJuIHJlZmVyZW5jZSB0byBhcnJheSBvZiB7QGxpbmsgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLkV4cHJlc3Npb259IGluc3RhbmNlcy4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBpZiBhIGVycm9yIG9jY3VycyBjcmVhdGluZyB0aGUgRXhwcmVzc2lvbi4KLSAgICovCi0gIHB1YmxpYyBFeHByZXNzaW9uW10gZ2V0Q29tcGlsZWRQcmVkaWNhdGVzKGludCBvcFBvcykKLSAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaW50IGNvdW50ID0gY291bnRQcmVkaWNhdGVzKG9wUG9zKTsKLQotICAgIGlmIChjb3VudCA+IDApCi0gICAgewotICAgICAgRXhwcmVzc2lvbltdIHByZWRpY2F0ZXMgPSBuZXcgRXhwcmVzc2lvbltjb3VudF07Ci0KLSAgICAgIGNvbXBpbGVQcmVkaWNhdGVzKG9wUG9zLCBwcmVkaWNhdGVzKTsKLQotICAgICAgcmV0dXJuIHByZWRpY2F0ZXM7Ci0gICAgfQotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogQ291bnQgdGhlIG51bWJlciBvZiBwcmVkaWNhdGVzIGluIHRoZSBzdGVwLgotICAgKgotICAgKiBAcGFyYW0gb3BQb3MgVGhlIHBvc2l0aW9uIG9mIHRoZSBmaXJzdCBwcmVkaWNhdGUgdGhlIG1fb3BNYXAgYXJyYXkuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIG51bWJlciBvZiBwcmVkaWNhdGVzIGZvciB0aGlzIHN0ZXAuCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24gaWYgYSBlcnJvciBvY2N1cnMgY3JlYXRpbmcgdGhlIEV4cHJlc3Npb24uCi0gICAqLwotICBwdWJsaWMgaW50IGNvdW50UHJlZGljYXRlcyhpbnQgb3BQb3MpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpbnQgY291bnQgPSAwOwotCi0gICAgd2hpbGUgKE9wQ29kZXMuT1BfUFJFRElDQVRFID09IGdldE9wKG9wUG9zKSkKLSAgICB7Ci0gICAgICBjb3VudCsrOwotCi0gICAgICBvcFBvcyA9IGdldE5leHRPcFBvcyhvcFBvcyk7Ci0gICAgfQotCi0gICAgcmV0dXJuIGNvdW50OwotICB9Ci0KLSAgLyoqCi0gICAqIENvbXBpbGVzIHByZWRpY2F0ZXMgaW4gdGhlIHN0ZXAuCi0gICAqCi0gICAqIEBwYXJhbSBvcFBvcyBUaGUgcG9zaXRpb24gb2YgdGhlIGZpcnN0IHByZWRpY2F0ZSB0aGUgbV9vcE1hcCBhcnJheS4KLSAgICogQHBhcmFtIHByZWRpY2F0ZXMgQW4gZW1wdHkgcHJlLWRldGVybWluZWQgYXJyYXkgb2YKLSAgICogICAgICAgICAgICB7QGxpbmsgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLkV4cHJlc3Npb259cywgdGhhdCB3aWxsIGJlIGZpbGxlZCBpbi4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHJpdmF0ZSB2b2lkIGNvbXBpbGVQcmVkaWNhdGVzKGludCBvcFBvcywgRXhwcmVzc2lvbltdIHByZWRpY2F0ZXMpCi0gICAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGZvciAoaW50IGkgPSAwOyBPcENvZGVzLk9QX1BSRURJQ0FURSA9PSBnZXRPcChvcFBvcyk7IGkrKykKLSAgICB7Ci0gICAgICBwcmVkaWNhdGVzW2ldID0gcHJlZGljYXRlKG9wUG9zKTsKLSAgICAgIG9wUG9zID0gZ2V0TmV4dE9wUG9zKG9wUG9zKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogQ29tcGlsZSBhIGJ1aWx0LWluIFhQYXRoIGZ1bmN0aW9uLgotICAgKgotICAgKiBAcGFyYW0gb3BQb3MgVGhlIGN1cnJlbnQgcG9zaXRpb24gaW4gdGhlIG1fb3BNYXAgYXJyYXkuCi0gICAqCi0gICAqIEByZXR1cm4gcmVmZXJlbmNlIHRvIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuZnVuY3Rpb25zLkZ1bmN0aW9ufSBpbnN0YW5jZS4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBpZiBhIGVycm9yIG9jY3VycyBjcmVhdGluZyB0aGUgRXhwcmVzc2lvbi4KLSAgICovCi0gIEV4cHJlc3Npb24gY29tcGlsZUZ1bmN0aW9uKGludCBvcFBvcykgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGludCBlbmRGdW5jID0gb3BQb3MgKyBnZXRPcChvcFBvcyArIDEpIC0gMTsKLQotICAgIG9wUG9zID0gZ2V0Rmlyc3RDaGlsZFBvcyhvcFBvcyk7Ci0KLSAgICBpbnQgZnVuY0lEID0gZ2V0T3Aob3BQb3MpOwotCi0gICAgb3BQb3MrKzsKLQotICAgIGlmICgtMSAhPSBmdW5jSUQpCi0gICAgewotICAgICAgRnVuY3Rpb24gZnVuYyA9IG1fZnVuY3Rpb25UYWJsZS5nZXRGdW5jdGlvbihmdW5jSUQpOwotCi0gICAgICAvKioKLSAgICAgICAqIEl0IGlzIGEgdHJpY2sgZm9yIGZ1bmN0aW9uLWF2YWlsYWJsZS4gU2luY2UgdGhlIGZ1bmN0aW9uIHRhYmxlIGlzIGFuCi0gICAgICAgKiBpbnN0YW5jZSBmaWVsZCwgaW5zZXJ0IHRoaXMgdGFibGUgYXQgY29tcGlsYXRpb24gdGltZSBmb3IgbGF0ZXIgdXNhZ2UKLSAgICAgICAqLwotCi0gICAgICBpZiAoZnVuYyBpbnN0YW5jZW9mIEZ1bmNFeHRGdW5jdGlvbkF2YWlsYWJsZSkKLSAgICAgICAgICAoKEZ1bmNFeHRGdW5jdGlvbkF2YWlsYWJsZSkgZnVuYykuc2V0RnVuY3Rpb25UYWJsZShtX2Z1bmN0aW9uVGFibGUpOwotCi0gICAgICBmdW5jLnBvc3RDb21waWxlU3RlcCh0aGlzKTsKLQotICAgICAgdHJ5Ci0gICAgICB7Ci0gICAgICAgIGludCBpID0gMDsKLQotICAgICAgICBmb3IgKGludCBwID0gb3BQb3M7IHAgPCBlbmRGdW5jOyBwID0gZ2V0TmV4dE9wUG9zKHApLCBpKyspCi0gICAgICAgIHsKLQotICAgICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiYXJnUG9zOiAiKyBwKTsKLSAgICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oImFyZ0NvZGU6ICIrIG1fb3BNYXBbcF0pOwotICAgICAgICAgIGZ1bmMuc2V0QXJnKGNvbXBpbGUocCksIGkpOwotICAgICAgICB9Ci0KLSAgICAgICAgZnVuYy5jaGVja051bWJlckFyZ3MoaSk7Ci0gICAgICB9Ci0gICAgICBjYXRjaCAoV3JvbmdOdW1iZXJBcmdzRXhjZXB0aW9uIHduYWUpCi0gICAgICB7Ci0gICAgICAgIGphdmEubGFuZy5TdHJpbmcgbmFtZSA9IG1fZnVuY3Rpb25UYWJsZS5nZXRGdW5jdGlvbk5hbWUoZnVuY0lEKTsKLQotICAgICAgICBtX2Vycm9ySGFuZGxlci5mYXRhbEVycm9yKCBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICBYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoWFBBVEhFcnJvclJlc291cmNlcy5FUl9PTkxZX0FMTE9XUywKLSAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117bmFtZSwgd25hZS5nZXRNZXNzYWdlKCl9KSwgbV9sb2NhdG9yKSk7Ci0gICAgICAgICAgICAgIC8vIm5hbWUgKyAiIG9ubHkgYWxsb3dzICIgKyB3bmFlLmdldE1lc3NhZ2UoKSArICIgYXJndW1lbnRzIiwgbV9sb2NhdG9yKSk7Ci0gICAgICB9Ci0KLSAgICAgIHJldHVybiBmdW5jOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgZXJyb3IoWFBBVEhFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9UT0tFTl9OT1RfRk9VTkQsIG51bGwpOyAgLy8iZnVuY3Rpb24gdG9rZW4gbm90IGZvdW5kLiIpOwotCi0gICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0gIH0KLQotICAvLyBUaGUgY3VycmVudCBpZCBmb3IgZXh0ZW5zaW9uIGZ1bmN0aW9ucy4KLSAgcHJpdmF0ZSBzdGF0aWMgbG9uZyBzX25leHRNZXRob2RJZCA9IDA7Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbmV4dCBhdmFpbGFibGUgbWV0aG9kIGlkCi0gICAqLwotICBzeW5jaHJvbml6ZWQgcHJpdmF0ZSBsb25nIGdldE5leHRNZXRob2RJZCgpCi0gIHsKLSAgICBpZiAoc19uZXh0TWV0aG9kSWQgPT0gTG9uZy5NQVhfVkFMVUUpCi0gICAgICBzX25leHRNZXRob2RJZCA9IDA7Ci0KLSAgICByZXR1cm4gc19uZXh0TWV0aG9kSWQrKzsKLSAgfQotCi0gIC8qKgotICAgKiBDb21waWxlIGFuIGV4dGVuc2lvbiBmdW5jdGlvbi4KLSAgICoKLSAgICogQHBhcmFtIG9wUG9zIFRoZSBjdXJyZW50IHBvc2l0aW9uIGluIHRoZSBtX29wTWFwIGFycmF5LgotICAgKgotICAgKiBAcmV0dXJuIHJlZmVyZW5jZSB0byB7QGxpbmsgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmZ1bmN0aW9ucy5GdW5jRXh0RnVuY3Rpb259IGluc3RhbmNlLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uIGlmIGEgZXJyb3Igb2NjdXJzIGNyZWF0aW5nIHRoZSBFeHByZXNzaW9uLgotICAgKi8KLSAgcHJpdmF0ZSBFeHByZXNzaW9uIGNvbXBpbGVFeHRlbnNpb24oaW50IG9wUG9zKQotICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpbnQgZW5kRXh0RnVuYyA9IG9wUG9zICsgZ2V0T3Aob3BQb3MgKyAxKSAtIDE7Ci0KLSAgICBvcFBvcyA9IGdldEZpcnN0Q2hpbGRQb3Mob3BQb3MpOwotCi0gICAgamF2YS5sYW5nLlN0cmluZyBucyA9IChqYXZhLmxhbmcuU3RyaW5nKSBnZXRUb2tlblF1ZXVlKCkuZWxlbWVudEF0KGdldE9wKG9wUG9zKSk7Ci0KLSAgICBvcFBvcysrOwotCi0gICAgamF2YS5sYW5nLlN0cmluZyBmdW5jTmFtZSA9Ci0gICAgICAoamF2YS5sYW5nLlN0cmluZykgZ2V0VG9rZW5RdWV1ZSgpLmVsZW1lbnRBdChnZXRPcChvcFBvcykpOwotCi0gICAgb3BQb3MrKzsKLQotICAgIC8vIFdlIGNyZWF0ZSBhIG1ldGhvZCBrZXkgdG8gdW5pcXVlbHkgaWRlbnRpZnkgdGhpcyBmdW5jdGlvbiBzbyB0aGF0IHdlCi0gICAgLy8gY2FuIGNhY2hlIHRoZSBvYmplY3QgbmVlZGVkIHRvIGludm9rZSBpdC4gIFRoaXMgd2F5LCB3ZSBvbmx5IHBheSB0aGUKLSAgICAvLyByZWZsZWN0aW9uIG92ZXJoZWFkIG9uIHRoZSBmaXJzdCBjYWxsLgotCi0gICAgRnVuY3Rpb24gZXh0ZW5zaW9uID0gbmV3IEZ1bmNFeHRGdW5jdGlvbihucywgZnVuY05hbWUsIFN0cmluZy52YWx1ZU9mKGdldE5leHRNZXRob2RJZCgpKSk7Ci0KLSAgICB0cnkKLSAgICB7Ci0gICAgICBpbnQgaSA9IDA7Ci0KLSAgICAgIHdoaWxlIChvcFBvcyA8IGVuZEV4dEZ1bmMpCi0gICAgICB7Ci0gICAgICAgIGludCBuZXh0T3BQb3MgPSBnZXROZXh0T3BQb3Mob3BQb3MpOwotCi0gICAgICAgIGV4dGVuc2lvbi5zZXRBcmcodGhpcy5jb21waWxlKG9wUG9zKSwgaSk7Ci0KLSAgICAgICAgb3BQb3MgPSBuZXh0T3BQb3M7Ci0KLSAgICAgICAgaSsrOwotICAgICAgfQotICAgIH0KLSAgICBjYXRjaCAoV3JvbmdOdW1iZXJBcmdzRXhjZXB0aW9uIHduYWUpCi0gICAgewotICAgICAgOyAgLy8gc2hvdWxkIG5ldmVyIGhhcHBlbgotICAgIH0KLQotICAgIHJldHVybiBleHRlbnNpb247Ci0gIH0KLQotICAvKioKLSAgICogV2FybiB0aGUgdXNlciBvZiBhbiBwcm9ibGVtLgotICAgKgotICAgKiBAcGFyYW0gbXNnIEFuIGVycm9yIG1zZ2tleSB0aGF0IGNvcnJlc3BvbmRzIHRvIG9uZSBvZiB0aGUgY29uc3RhbnRzIGZvdW5kCi0gICAqICAgICAgICAgICAgaW4ge0BsaW5rIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5yZXMuWFBBVEhFcnJvclJlc291cmNlc30sIHdoaWNoIGlzCi0gICAqICAgICAgICAgICAgYSBrZXkgZm9yIGEgZm9ybWF0IHN0cmluZy4KLSAgICogQHBhcmFtIGFyZ3MgQW4gYXJyYXkgb2YgYXJndW1lbnRzIHJlcHJlc2VudGVkIGluIHRoZSBmb3JtYXQgc3RyaW5nLCB3aGljaAotICAgKiAgICAgICAgICAgICBtYXkgYmUgbnVsbC4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBpZiB0aGUgY3VycmVudCBFcnJvckxpc3RvbmVyIGRldGVybWluZXMgdG8KLSAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBhbiBleGNlcHRpb24uCi0gICAqLwotICBwdWJsaWMgdm9pZCB3YXJuKFN0cmluZyBtc2csIE9iamVjdFtdIGFyZ3MpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBqYXZhLmxhbmcuU3RyaW5nIGZtc2cgPSBYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSFdhcm5pbmcobXNnLCBhcmdzKTsKLQotICAgIGlmIChudWxsICE9IG1fZXJyb3JIYW5kbGVyKQotICAgIHsKLSAgICAgIG1fZXJyb3JIYW5kbGVyLndhcm5pbmcobmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKGZtc2csIG1fbG9jYXRvcikpOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgU3lzdGVtLm91dC5wcmludGxuKGZtc2cKLSAgICAgICAgICAgICAgICAgICAgICAgICAgKyI7IGZpbGUgIittX2xvY2F0b3IuZ2V0U3lzdGVtSWQoKQotICAgICAgICAgICAgICAgICAgICAgICAgICArIjsgbGluZSAiK21fbG9jYXRvci5nZXRMaW5lTnVtYmVyKCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgKyI7IGNvbHVtbiAiK21fbG9jYXRvci5nZXRDb2x1bW5OdW1iZXIoKSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgdGhlIHVzZXIgb2YgYW4gYXNzZXJ0aW9uIGVycm9yLCBhbmQgcHJvYmFibHkgdGhyb3cgYW4KLSAgICogZXhjZXB0aW9uLgotICAgKgotICAgKiBAcGFyYW0gYiAgSWYgZmFsc2UsIGEgcnVudGltZSBleGNlcHRpb24gd2lsbCBiZSB0aHJvd24uCi0gICAqIEBwYXJhbSBtc2cgVGhlIGFzc2VydGlvbiBtZXNzYWdlLCB3aGljaCBzaG91bGQgYmUgaW5mb3JtYXRpdmUuCi0gICAqCi0gICAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiBpZiB0aGUgYiBhcmd1bWVudCBpcyBmYWxzZS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGFzc2VydGlvbihib29sZWFuIGIsIGphdmEubGFuZy5TdHJpbmcgbXNnKQotICB7Ci0KLSAgICBpZiAoIWIpCi0gICAgewotICAgICAgamF2YS5sYW5nLlN0cmluZyBmTXNnID0gWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKAotICAgICAgICBYUEFUSEVycm9yUmVzb3VyY2VzLkVSX0lOQ09SUkVDVF9QUk9HUkFNTUVSX0FTU0VSVElPTiwKLSAgICAgICAgbmV3IE9iamVjdFtdeyBtc2cgfSk7Ci0KLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGZNc2cpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIHRoZSB1c2VyIG9mIGFuIGVycm9yLCBhbmQgcHJvYmFibHkgdGhyb3cgYW4KLSAgICogZXhjZXB0aW9uLgotICAgKgotICAgKiBAcGFyYW0gbXNnIEFuIGVycm9yIG1zZ2tleSB0aGF0IGNvcnJlc3BvbmRzIHRvIG9uZSBvZiB0aGUgY29uc3RhbnRzIGZvdW5kCi0gICAqICAgICAgICAgICAgaW4ge0BsaW5rIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5yZXMuWFBBVEhFcnJvclJlc291cmNlc30sIHdoaWNoIGlzCi0gICAqICAgICAgICAgICAgYSBrZXkgZm9yIGEgZm9ybWF0IHN0cmluZy4KLSAgICogQHBhcmFtIGFyZ3MgQW4gYXJyYXkgb2YgYXJndW1lbnRzIHJlcHJlc2VudGVkIGluIHRoZSBmb3JtYXQgc3RyaW5nLCB3aGljaAotICAgKiAgICAgICAgICAgICBtYXkgYmUgbnVsbC4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBpZiB0aGUgY3VycmVudCBFcnJvckxpc3RvbmVyIGRldGVybWluZXMgdG8KLSAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBhbiBleGNlcHRpb24uCi0gICAqLwotICBwdWJsaWMgdm9pZCBlcnJvcihTdHJpbmcgbXNnLCBPYmplY3RbXSBhcmdzKSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgamF2YS5sYW5nLlN0cmluZyBmbXNnID0gWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKG1zZywgYXJncyk7Ci0KLQotICAgIGlmIChudWxsICE9IG1fZXJyb3JIYW5kbGVyKQotICAgIHsKLSAgICAgIG1fZXJyb3JIYW5kbGVyLmZhdGFsRXJyb3IobmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKGZtc2csIG1fbG9jYXRvcikpOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotCi0gICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4odGUuZ2V0TWVzc2FnZSgpCi0gICAgICAvLyAgICAgICAgICAgICAgICAgICAgKyI7IGZpbGUgIit0ZS5nZXRTeXN0ZW1JZCgpCi0gICAgICAvLyAgICAgICAgICAgICAgICAgICAgKyI7IGxpbmUgIit0ZS5nZXRMaW5lTnVtYmVyKCkKLSAgICAgIC8vICAgICAgICAgICAgICAgICAgICArIjsgY29sdW1uICIrdGUuZ2V0Q29sdW1uTnVtYmVyKCkpOwotICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKGZtc2csIChTQVhTb3VyY2VMb2NhdG9yKW1fbG9jYXRvcik7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFRoZSBjdXJyZW50IHByZWZpeFJlc29sdmVyIGZvciB0aGUgZXhlY3V0aW9uIGNvbnRleHQuCi0gICAqLwotICBwcml2YXRlIFByZWZpeFJlc29sdmVyIG1fY3VycmVudFByZWZpeFJlc29sdmVyID0gbnVsbDsKLQotICAvKioKLSAgICogR2V0IHRoZSBjdXJyZW50IG5hbWVzcGFjZSBjb250ZXh0IGZvciB0aGUgeHBhdGguCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGN1cnJlbnQgcHJlZml4IHJlc29sdmVyLCAqbWF5KiBiZSBudWxsLCB0aG91Z2ggaG9wZWZ1bGx5IG5vdC4KLSAgICovCi0gIHB1YmxpYyBQcmVmaXhSZXNvbHZlciBnZXROYW1lc3BhY2VDb250ZXh0KCkKLSAgewotICAgIHJldHVybiBtX2N1cnJlbnRQcmVmaXhSZXNvbHZlcjsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIGN1cnJlbnQgbmFtZXNwYWNlIGNvbnRleHQgZm9yIHRoZSB4cGF0aC4KLSAgICoKLSAgICogQHBhcmFtIHByIFRoZSByZXNvbHZlciBmb3IgcHJlZml4ZXMgaW4gdGhlIFhQYXRoIGV4cHJlc3Npb24uCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXROYW1lc3BhY2VDb250ZXh0KFByZWZpeFJlc29sdmVyIHByKQotICB7Ci0gICAgbV9jdXJyZW50UHJlZml4UmVzb2x2ZXIgPSBwcjsKLSAgfQotCi0gIC8qKiBUaGUgZXJyb3IgbGlzdGVuZXIgd2hlcmUgZXJyb3JzIHdpbGwgYmUgc2VudC4gIElmIHRoaXMgaXMgbnVsbCwgZXJyb3JzCi0gICAqICBhbmQgd2FybmluZ3Mgd2lsbCBiZSBzZW50IHRvIFN5c3RlbS5lcnIuICBNYXkgYmUgbnVsbC4gICAgKi8KLSAgRXJyb3JMaXN0ZW5lciBtX2Vycm9ySGFuZGxlcjsKLQotICAvKiogVGhlIHNvdXJjZSBsb2NhdG9yIGZvciB0aGUgZXhwcmVzc2lvbiBiZWluZyBjb21waWxlZC4gIE1heSBiZSBudWxsLiAqLwotICBTb3VyY2VMb2NhdG9yIG1fbG9jYXRvcjsKLQotICAvKioKLSAgICogVGhlIEZ1bmN0aW9uVGFibGUgZm9yIGFsbCB4cGF0aCBidWlsZC1pbiBmdW5jdGlvbnMKLSAgICovCi0gIHByaXZhdGUgRnVuY3Rpb25UYWJsZSBtX2Z1bmN0aW9uVGFibGU7Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2NvbXBpbGVyL0Z1bmNMb2FkZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvY29tcGlsZXIvRnVuY0xvYWRlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2ODM0NzJhLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvY29tcGlsZXIvRnVuY0xvYWRlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTA5ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IEZ1bmNMb2FkZXIuamF2YSx2IDEuMS4yLjEgMjAwNS8wOC8wMSAwMTozMDozNSBqZWZmc3V0dG9yIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmNvbXBpbGVyOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5mdW5jdGlvbnMuRnVuY3Rpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnV0aWxzLk9iamVjdEZhY3Rvcnk7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnV0aWxzLkNvbmZpZ3VyYXRpb25FcnJvcjsKLQotLyoqCi0gKiBMYXp5IGxvYWQgb2YgZnVuY3Rpb25zIGludG8gdGhlIGZ1bmN0aW9uIHRhYmxlIGFzIG5lZWRlZCwgc28gd2UgZG9uJ3QKLSAqIGhhdmUgdG8gbG9hZCBhbGwgdGhlIGZ1bmN0aW9ucyBhbGxvd2VkIGluIFhQYXRoIGFuZCBYU0xUIG9uIHN0YXJ0dXAuCi0gKiBAeHNsLnVzYWdlIGFkdmFuY2VkCi0gKi8KLXB1YmxpYyBjbGFzcyBGdW5jTG9hZGVyCi17Ci0KLSAgLyoqIFRoZSBmdW5jdGlvbiBJRCwgd2hpY2ggbWF5IGNvcnJlc3BvbmQgdG8gb25lIG9mIHRoZSBGVU5DX1hYWCB2YWx1ZXMKLSAgICogIGZvdW5kIGluIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuY29tcGlsZXIuRnVuY3Rpb25UYWJsZX0sIGJ1dCBtYXkKLSAgICogIGJlIGEgdmFsdWUgaW5zdGFsbGVkIGJ5IGFuIGV4dGVybmFsIG1vZHVsZS4gICovCi0gIHByaXZhdGUgaW50IG1fZnVuY0lEOwotCi0gIC8qKiBUaGUgY2xhc3MgbmFtZSBvZiB0aGUgZnVuY3Rpb24uICBNdXN0IG5vdCBiZSBudWxsLiAgICovCi0gIHByaXZhdGUgU3RyaW5nIG1fZnVuY05hbWU7Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbG9jYWwgY2xhc3MgbmFtZSBvZiB0aGUgZnVuY3Rpb24gY2xhc3MuICBJZiBmdW5jdGlvbiBuYW1lIGRvZXMKLSAgICogbm90IGhhdmUgYSAnLicgaW4gaXQsIGl0IGlzIGFzc3VtZWQgdG8gYmUgcmVsYXRpdmUgdG8KLSAgICogJ2NvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5mdW5jdGlvbnMnLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBjbGFzcyBuYW1lIG9mIHRoZSB7Y29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmZ1bmN0aW9ucy5GdW5jdGlvbn0gY2xhc3MuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKQotICB7Ci0gICAgcmV0dXJuIG1fZnVuY05hbWU7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgZnVuY3Rpb24gbG9hZGVyCi0gICAqCi0gICAqIEBwYXJhbSBmdW5jTmFtZSBUaGUgY2xhc3MgbmFtZSBvZiB0aGUge2NvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5mdW5jdGlvbnMuRnVuY3Rpb259Ci0gICAqICAgICAgICAgICAgIGNsYXNzLCB3aGljaCwgaWYgaXQgZG9lcyBub3QgaGF2ZSBhICcuJyBpbiBpdCwgaXMgYXNzdW1lZCB0bwotICAgKiAgICAgICAgICAgICBiZSByZWxhdGl2ZSB0byAnY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmZ1bmN0aW9ucycuCi0gICAqIEBwYXJhbSBmdW5jSUQgIFRoZSBmdW5jdGlvbiBJRCwgd2hpY2ggbWF5IGNvcnJlc3BvbmQgdG8gb25lIG9mIHRoZSBGVU5DX1hYWAotICAgKiAgICB2YWx1ZXMgZm91bmQgaW4ge0BsaW5rIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5jb21waWxlci5GdW5jdGlvblRhYmxlfSwgYnV0IG1heQotICAgKiAgICBiZSBhIHZhbHVlIGluc3RhbGxlZCBieSBhbiBleHRlcm5hbCBtb2R1bGUuCi0gICAqLwotICBwdWJsaWMgRnVuY0xvYWRlcihTdHJpbmcgZnVuY05hbWUsIGludCBmdW5jSUQpCi0gIHsKLQotICAgIHN1cGVyKCk7Ci0KLSAgICBtX2Z1bmNJRCA9IGZ1bmNJRDsKLSAgICBtX2Z1bmNOYW1lID0gZnVuY05hbWU7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IGEgRnVuY3Rpb24gaW5zdGFuY2UgdGhhdCB0aGlzIGluc3RhbmNlIGlzIGxpYWlzb25pbmcgZm9yLgotICAgKgotICAgKiBAcmV0dXJuIG5vbi1udWxsIHJlZmVyZW5jZSB0byBGdW5jdGlvbiBkZXJpdmF0aXZlLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24gaWYgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiwKLSAgICogICAgSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiwgb3IgSW5zdGFudGlhdGlvbkV4Y2VwdGlvbiBpcyB0aHJvd24uCi0gICAqLwotICBGdW5jdGlvbiBnZXRGdW5jdGlvbigpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgdHJ5Ci0gICAgewotICAgICAgU3RyaW5nIGNsYXNzTmFtZSA9IG1fZnVuY05hbWU7Ci0gICAgICBpZiAoY2xhc3NOYW1lLmluZGV4T2YoIi4iKSA8IDApIHsKLSAgICAgICAgY2xhc3NOYW1lID0gImNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5mdW5jdGlvbnMuIiArIGNsYXNzTmFtZTsKLSAgICAgIH0KLSAgICAgIC8vaGFjayBmb3IgbG9hZGluZyBvbmx5IGJ1aWx0LWluIGZ1bmN0aW9uIGNsYXNzZXMuCi0gICAgICBTdHJpbmcgc3ViU3RyaW5nID0gY2xhc3NOYW1lLnN1YnN0cmluZygwLGNsYXNzTmFtZS5sYXN0SW5kZXhPZignLicpKTsKLSAgICAgIGlmKCEoc3ViU3RyaW5nLmVxdWFscyAoImNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC50ZW1wbGF0ZXMiKSB8fAotICAgICAgICAgICBzdWJTdHJpbmcuZXF1YWxzICgiY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmZ1bmN0aW9ucyIpKSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKCJBcHBsaWNhdGlvbiBjYW4ndCBpbnN0YWxsIGhpcyBvd24geHBhdGggZnVuY3Rpb24uIik7Ci0gICAgICB9Ci0KLSAgICAgIHJldHVybiAoRnVuY3Rpb24pIE9iamVjdEZhY3RvcnkubmV3SW5zdGFuY2UoY2xhc3NOYW1lLCB0cnVlKTsKLQotICAgIH0KLSAgICBjYXRjaCAoQ29uZmlndXJhdGlvbkVycm9yIGUpCi0gICAgewotICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKGUuZ2V0RXhjZXB0aW9uKCkpOwotICAgIH0KLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9jb21waWxlci9GdW5jdGlvblRhYmxlLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2NvbXBpbGVyL0Z1bmN0aW9uVGFibGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMmI2NTNhYy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2NvbXBpbGVyL0Z1bmN0aW9uVGFibGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQxMCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBGdW5jdGlvblRhYmxlLmphdmEsdiAxLjMgMjAwNS8wOS8yOCAxMzo0OTozNCBwdmVkdWxhIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmNvbXBpbGVyOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLkV4cHJlc3Npb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmZ1bmN0aW9ucy5GdW5jdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotCi0vKioKLSAqIFRoZSBmdW5jdGlvbiB0YWJsZSBmb3IgWFBhdGguCi0gKi8KLXB1YmxpYyBjbGFzcyBGdW5jdGlvblRhYmxlCi17Ci0KLSAgLyoqIFRoZSAnY3VycmVudCgpJyBpZC4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRlVOQ19DVVJSRU5UID0gMDsKLQotICAvKiogVGhlICdsYXN0KCknIGlkLiAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGVU5DX0xBU1QgPSAxOwotCi0gIC8qKiBUaGUgJ3Bvc2l0aW9uKCknIGlkLiAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGVU5DX1BPU0lUSU9OID0gMjsKLQotICAvKiogVGhlICdjb3VudCgpJyBpZC4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRlVOQ19DT1VOVCA9IDM7Ci0KLSAgLyoqIFRoZSAnaWQoKScgaWQuICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZVTkNfSUQgPSA0OwotCi0gIC8qKiBUaGUgJ2tleSgpJyBpZCAoWFNMVCkuICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZVTkNfS0VZID0gNTsKLQotICAvKiogVGhlICdsb2NhbC1uYW1lKCknIGlkLiAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGVU5DX0xPQ0FMX1BBUlQgPSA3OwotCi0gIC8qKiBUaGUgJ25hbWVzcGFjZS11cmkoKScgaWQuICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZVTkNfTkFNRVNQQUNFID0gODsKLQotICAvKiogVGhlICduYW1lKCknIGlkLiAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGVU5DX1FOQU1FID0gOTsKLQotICAvKiogVGhlICdnZW5lcmF0ZS1pZCgpJyBpZC4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRlVOQ19HRU5FUkFURV9JRCA9IDEwOwotCi0gIC8qKiBUaGUgJ25vdCgpJyBpZC4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRlVOQ19OT1QgPSAxMTsKLQotICAvKiogVGhlICd0cnVlKCknIGlkLiAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGVU5DX1RSVUUgPSAxMjsKLQotICAvKiogVGhlICdmYWxzZSgpJyBpZC4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRlVOQ19GQUxTRSA9IDEzOwotCi0gIC8qKiBUaGUgJ2Jvb2xlYW4oKScgaWQuICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZVTkNfQk9PTEVBTiA9IDE0OwotCi0gIC8qKiBUaGUgJ251bWJlcigpJyBpZC4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRlVOQ19OVU1CRVIgPSAxNTsKLQotICAvKiogVGhlICdmbG9vcigpJyBpZC4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRlVOQ19GTE9PUiA9IDE2OwotCi0gIC8qKiBUaGUgJ2NlaWxpbmcoKScgaWQuICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZVTkNfQ0VJTElORyA9IDE3OwotCi0gIC8qKiBUaGUgJ3JvdW5kKCknIGlkLiAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGVU5DX1JPVU5EID0gMTg7Ci0KLSAgLyoqIFRoZSAnc3VtKCknIGlkLiAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGVU5DX1NVTSA9IDE5OwotCi0gIC8qKiBUaGUgJ3N0cmluZygpJyBpZC4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRlVOQ19TVFJJTkcgPSAyMDsKLQotICAvKiogVGhlICdzdGFydHMtd2l0aCgpJyBpZC4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRlVOQ19TVEFSVFNfV0lUSCA9IDIxOwotCi0gIC8qKiBUaGUgJ2NvbnRhaW5zKCknIGlkLiAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGVU5DX0NPTlRBSU5TID0gMjI7Ci0KLSAgLyoqIFRoZSAnc3Vic3RyaW5nLWJlZm9yZSgpJyBpZC4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRlVOQ19TVUJTVFJJTkdfQkVGT1JFID0gMjM7Ci0KLSAgLyoqIFRoZSAnc3Vic3RyaW5nLWFmdGVyKCknIGlkLiAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGVU5DX1NVQlNUUklOR19BRlRFUiA9IDI0OwotCi0gIC8qKiBUaGUgJ25vcm1hbGl6ZS1zcGFjZSgpJyBpZC4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRlVOQ19OT1JNQUxJWkVfU1BBQ0UgPSAyNTsKLQotICAvKiogVGhlICd0cmFuc2xhdGUoKScgaWQuICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZVTkNfVFJBTlNMQVRFID0gMjY7Ci0KLSAgLyoqIFRoZSAnY29uY2F0KCknIGlkLiAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGVU5DX0NPTkNBVCA9IDI3OwotCi0gIC8qKiBUaGUgJ3N1YnN0cmluZygpJyBpZC4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRlVOQ19TVUJTVFJJTkcgPSAyOTsKLQotICAvKiogVGhlICdzdHJpbmctbGVuZ3RoKCknIGlkLiAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGVU5DX1NUUklOR19MRU5HVEggPSAzMDsKLQotICAvKiogVGhlICdzeXN0ZW0tcHJvcGVydHkoKScgaWQuICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZVTkNfU1lTVEVNX1BST1BFUlRZID0gMzE7Ci0KLSAgLyoqIFRoZSAnbGFuZygpJyBpZC4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRlVOQ19MQU5HID0gMzI7Ci0KLSAgLyoqIFRoZSAnZnVuY3Rpb24tYXZhaWxhYmxlKCknIGlkIChYU0xUKS4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRlVOQ19FWFRfRlVOQ1RJT05fQVZBSUxBQkxFID0gMzM7Ci0KLSAgLyoqIFRoZSAnZWxlbWVudC1hdmFpbGFibGUoKScgaWQgKFhTTFQpLiAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGVU5DX0VYVF9FTEVNX0FWQUlMQUJMRSA9IDM0OwotCi0gIC8qKiBUaGUgJ3VucGFyc2VkLWVudGl0eS11cmkoKScgaWQgKFhTTFQpLiAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGVU5DX1VOUEFSU0VEX0VOVElUWV9VUkkgPSAzNjsKLQotICAvLyBQcm9wcmlldGFyeQotCi0gIC8qKiBUaGUgJ2RvY3VtZW50LWxvY2F0aW9uKCknIGlkIChQcm9wcmlldGFyeSkuICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZVTkNfRE9DTE9DQVRJT04gPSAzNTsKLQotICAvKioKLSAgICogVGhlIGZ1bmN0aW9uIHRhYmxlLgotICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgQ2xhc3MgbV9mdW5jdGlvbnNbXTsKLQotICAvKiogVGFibGUgb2YgZnVuY3Rpb24gbmFtZSB0byBmdW5jdGlvbiBJRCBhc3NvY2lhdGlvbnMuICovCi0gIHByaXZhdGUgc3RhdGljIEhhc2hNYXAgbV9mdW5jdGlvbklEID0gbmV3IEhhc2hNYXAoKTsKLQotICAvKioKLSAgICogVGhlIGZ1bmN0aW9uIHRhYmxlIGNvbnRhaW5zIGN1c3RvbWl6ZWQgZnVuY3Rpb25zCi0gICAqLwotICBwcml2YXRlIENsYXNzIG1fZnVuY3Rpb25zX2N1c3RvbWVyW10gPSBuZXcgQ2xhc3NbTlVNX0FMTE9XQUJMRV9BRERJTlNdOwotCi0gIC8qKgotICAgKiBUYWJsZSBvZiBmdW5jdGlvbiBuYW1lIHRvIGZ1bmN0aW9uIElEIGFzc29jaWF0aW9ucyBmb3IgY3VzdG9taXplZCBmdW5jdGlvbnMKLSAgICovCi0gIHByaXZhdGUgSGFzaE1hcCBtX2Z1bmN0aW9uSURfY3VzdG9tZXIgPSBuZXcgSGFzaE1hcCgpOwotCi0gIC8qKgotICAgKiBOdW1iZXIgb2YgYnVpbHQgaW4gZnVuY3Rpb25zLiAgQmUgc3VyZSB0byB1cGRhdGUgdGhpcyBhcwotICAgKiBidWlsdC1pbiBmdW5jdGlvbnMgYXJlIGFkZGVkLgotICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE5VTV9CVUlMVF9JTl9GVU5DUyA9IDM3OwotCi0gIC8qKgotICAgKiBOdW1iZXIgb2YgYnVpbHQtaW4gZnVuY3Rpb25zIHRoYXQgbWF5IGJlIGFkZGVkLgotICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE5VTV9BTExPV0FCTEVfQURESU5TID0gMzA7Ci0KLSAgLyoqCi0gICAqIFRoZSBpbmRleCB0byB0aGUgbmV4dCBmcmVlIGZ1bmN0aW9uIGluZGV4LgotICAgKi8KLSAgcHJpdmF0ZSBpbnQgbV9mdW5jTmV4dEZyZWVJbmRleCA9IE5VTV9CVUlMVF9JTl9GVU5DUzsKLQotICBzdGF0aWMKLSAgewotICAgIG1fZnVuY3Rpb25zID0gbmV3IENsYXNzW05VTV9CVUlMVF9JTl9GVU5DU107Ci0gICAgbV9mdW5jdGlvbnNbRlVOQ19DVVJSRU5UXSA9IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5mdW5jdGlvbnMuRnVuY0N1cnJlbnQuY2xhc3M7Ci0gICAgbV9mdW5jdGlvbnNbRlVOQ19MQVNUXSA9IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5mdW5jdGlvbnMuRnVuY0xhc3QuY2xhc3M7Ci0gICAgbV9mdW5jdGlvbnNbRlVOQ19QT1NJVElPTl0gPSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuZnVuY3Rpb25zLkZ1bmNQb3NpdGlvbi5jbGFzczsKLSAgICBtX2Z1bmN0aW9uc1tGVU5DX0NPVU5UXSA9IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5mdW5jdGlvbnMuRnVuY0NvdW50LmNsYXNzOwotICAgIG1fZnVuY3Rpb25zW0ZVTkNfSURdID0gY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmZ1bmN0aW9ucy5GdW5jSWQuY2xhc3M7Ci0gICAgLy8gSjJTRSBkb2VzIG5vdCBzdXBwb3J0IFhhbGFuIGludGVycHJldGl2ZQotICAgIC8vIG1fZnVuY3Rpb25zW0ZVTkNfS0VZXSA9Ci0gICAgLy8gICBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwudGVtcGxhdGVzLkZ1bmNLZXkuY2xhc3M7Ci0gICAgbV9mdW5jdGlvbnNbRlVOQ19MT0NBTF9QQVJUXSA9Ci0gICAgICBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuZnVuY3Rpb25zLkZ1bmNMb2NhbFBhcnQuY2xhc3M7Ci0gICAgbV9mdW5jdGlvbnNbRlVOQ19OQU1FU1BBQ0VdID0KLSAgICAgIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5mdW5jdGlvbnMuRnVuY05hbWVzcGFjZS5jbGFzczsKLSAgICBtX2Z1bmN0aW9uc1tGVU5DX1FOQU1FXSA9IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5mdW5jdGlvbnMuRnVuY1FuYW1lLmNsYXNzOwotICAgIG1fZnVuY3Rpb25zW0ZVTkNfR0VORVJBVEVfSURdID0KLSAgICAgIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5mdW5jdGlvbnMuRnVuY0dlbmVyYXRlSWQuY2xhc3M7Ci0gICAgbV9mdW5jdGlvbnNbRlVOQ19OT1RdID0gY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmZ1bmN0aW9ucy5GdW5jTm90LmNsYXNzOwotICAgIG1fZnVuY3Rpb25zW0ZVTkNfVFJVRV0gPSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuZnVuY3Rpb25zLkZ1bmNUcnVlLmNsYXNzOwotICAgIG1fZnVuY3Rpb25zW0ZVTkNfRkFMU0VdID0gY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmZ1bmN0aW9ucy5GdW5jRmFsc2UuY2xhc3M7Ci0gICAgbV9mdW5jdGlvbnNbRlVOQ19CT09MRUFOXSA9IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5mdW5jdGlvbnMuRnVuY0Jvb2xlYW4uY2xhc3M7Ci0gICAgbV9mdW5jdGlvbnNbRlVOQ19MQU5HXSA9IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5mdW5jdGlvbnMuRnVuY0xhbmcuY2xhc3M7Ci0gICAgbV9mdW5jdGlvbnNbRlVOQ19OVU1CRVJdID0gY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmZ1bmN0aW9ucy5GdW5jTnVtYmVyLmNsYXNzOwotICAgIG1fZnVuY3Rpb25zW0ZVTkNfRkxPT1JdID0gY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmZ1bmN0aW9ucy5GdW5jRmxvb3IuY2xhc3M7Ci0gICAgbV9mdW5jdGlvbnNbRlVOQ19DRUlMSU5HXSA9IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5mdW5jdGlvbnMuRnVuY0NlaWxpbmcuY2xhc3M7Ci0gICAgbV9mdW5jdGlvbnNbRlVOQ19ST1VORF0gPSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuZnVuY3Rpb25zLkZ1bmNSb3VuZC5jbGFzczsKLSAgICBtX2Z1bmN0aW9uc1tGVU5DX1NVTV0gPSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuZnVuY3Rpb25zLkZ1bmNTdW0uY2xhc3M7Ci0gICAgbV9mdW5jdGlvbnNbRlVOQ19TVFJJTkddID0gY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmZ1bmN0aW9ucy5GdW5jU3RyaW5nLmNsYXNzOwotICAgIG1fZnVuY3Rpb25zW0ZVTkNfU1RBUlRTX1dJVEhdID0KLSAgICAgIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5mdW5jdGlvbnMuRnVuY1N0YXJ0c1dpdGguY2xhc3M7Ci0gICAgbV9mdW5jdGlvbnNbRlVOQ19DT05UQUlOU10gPSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuZnVuY3Rpb25zLkZ1bmNDb250YWlucy5jbGFzczsKLSAgICBtX2Z1bmN0aW9uc1tGVU5DX1NVQlNUUklOR19CRUZPUkVdID0KLSAgICAgIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5mdW5jdGlvbnMuRnVuY1N1YnN0cmluZ0JlZm9yZS5jbGFzczsKLSAgICBtX2Z1bmN0aW9uc1tGVU5DX1NVQlNUUklOR19BRlRFUl0gPQotICAgICAgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmZ1bmN0aW9ucy5GdW5jU3Vic3RyaW5nQWZ0ZXIuY2xhc3M7Ci0gICAgbV9mdW5jdGlvbnNbRlVOQ19OT1JNQUxJWkVfU1BBQ0VdID0KLSAgICAgIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5mdW5jdGlvbnMuRnVuY05vcm1hbGl6ZVNwYWNlLmNsYXNzOwotICAgIG1fZnVuY3Rpb25zW0ZVTkNfVFJBTlNMQVRFXSA9Ci0gICAgICBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuZnVuY3Rpb25zLkZ1bmNUcmFuc2xhdGUuY2xhc3M7Ci0gICAgbV9mdW5jdGlvbnNbRlVOQ19DT05DQVRdID0gY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmZ1bmN0aW9ucy5GdW5jQ29uY2F0LmNsYXNzOwotICAgIG1fZnVuY3Rpb25zW0ZVTkNfU1lTVEVNX1BST1BFUlRZXSA9Ci0gICAgICBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuZnVuY3Rpb25zLkZ1bmNTeXN0ZW1Qcm9wZXJ0eS5jbGFzczsKLSAgICBtX2Z1bmN0aW9uc1tGVU5DX0VYVF9GVU5DVElPTl9BVkFJTEFCTEVdID0KLSAgICAgIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5mdW5jdGlvbnMuRnVuY0V4dEZ1bmN0aW9uQXZhaWxhYmxlLmNsYXNzOwotICAgIG1fZnVuY3Rpb25zW0ZVTkNfRVhUX0VMRU1fQVZBSUxBQkxFXSA9Ci0gICAgICBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuZnVuY3Rpb25zLkZ1bmNFeHRFbGVtZW50QXZhaWxhYmxlLmNsYXNzOwotICAgIG1fZnVuY3Rpb25zW0ZVTkNfU1VCU1RSSU5HXSA9Ci0gICAgICBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuZnVuY3Rpb25zLkZ1bmNTdWJzdHJpbmcuY2xhc3M7Ci0gICAgbV9mdW5jdGlvbnNbRlVOQ19TVFJJTkdfTEVOR1RIXSA9Ci0gICAgICBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuZnVuY3Rpb25zLkZ1bmNTdHJpbmdMZW5ndGguY2xhc3M7Ci0gICAgbV9mdW5jdGlvbnNbRlVOQ19ET0NMT0NBVElPTl0gPQotICAgICAgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmZ1bmN0aW9ucy5GdW5jRG9jbG9jYXRpb24uY2xhc3M7Ci0gICAgbV9mdW5jdGlvbnNbRlVOQ19VTlBBUlNFRF9FTlRJVFlfVVJJXSA9Ci0gICAgICBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuZnVuY3Rpb25zLkZ1bmNVbnBhcnNlZEVudGl0eVVSSS5jbGFzczsKLSAgfQotCi0gIHN0YXRpY3sKLSAgICAgICAgICBtX2Z1bmN0aW9uSUQucHV0KEtleXdvcmRzLkZVTkNfQ1VSUkVOVF9TVFJJTkcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBJbnRlZ2VyKEZ1bmN0aW9uVGFibGUuRlVOQ19DVVJSRU5UKSk7Ci0gICAgICAgICAgbV9mdW5jdGlvbklELnB1dChLZXl3b3Jkcy5GVU5DX0xBU1RfU1RSSU5HLAotICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgSW50ZWdlcihGdW5jdGlvblRhYmxlLkZVTkNfTEFTVCkpOwotICAgICAgICAgIG1fZnVuY3Rpb25JRC5wdXQoS2V5d29yZHMuRlVOQ19QT1NJVElPTl9TVFJJTkcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBJbnRlZ2VyKEZ1bmN0aW9uVGFibGUuRlVOQ19QT1NJVElPTikpOwotICAgICAgICAgIG1fZnVuY3Rpb25JRC5wdXQoS2V5d29yZHMuRlVOQ19DT1VOVF9TVFJJTkcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBJbnRlZ2VyKEZ1bmN0aW9uVGFibGUuRlVOQ19DT1VOVCkpOwotICAgICAgICAgIG1fZnVuY3Rpb25JRC5wdXQoS2V5d29yZHMuRlVOQ19JRF9TVFJJTkcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBJbnRlZ2VyKEZ1bmN0aW9uVGFibGUuRlVOQ19JRCkpOwotICAgICAgICAgIG1fZnVuY3Rpb25JRC5wdXQoS2V5d29yZHMuRlVOQ19LRVlfU1RSSU5HLAotICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgSW50ZWdlcihGdW5jdGlvblRhYmxlLkZVTkNfS0VZKSk7Ci0gICAgICAgICAgbV9mdW5jdGlvbklELnB1dChLZXl3b3Jkcy5GVU5DX0xPQ0FMX1BBUlRfU1RSSU5HLAotICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgSW50ZWdlcihGdW5jdGlvblRhYmxlLkZVTkNfTE9DQUxfUEFSVCkpOwotICAgICAgICAgIG1fZnVuY3Rpb25JRC5wdXQoS2V5d29yZHMuRlVOQ19OQU1FU1BBQ0VfU1RSSU5HLAotICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgSW50ZWdlcihGdW5jdGlvblRhYmxlLkZVTkNfTkFNRVNQQUNFKSk7Ci0gICAgICAgICAgbV9mdW5jdGlvbklELnB1dChLZXl3b3Jkcy5GVU5DX05BTUVfU1RSSU5HLAotICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgSW50ZWdlcihGdW5jdGlvblRhYmxlLkZVTkNfUU5BTUUpKTsKLSAgICAgICAgICBtX2Z1bmN0aW9uSUQucHV0KEtleXdvcmRzLkZVTkNfR0VORVJBVEVfSURfU1RSSU5HLAotICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgSW50ZWdlcihGdW5jdGlvblRhYmxlLkZVTkNfR0VORVJBVEVfSUQpKTsKLSAgICAgICAgICBtX2Z1bmN0aW9uSUQucHV0KEtleXdvcmRzLkZVTkNfTk9UX1NUUklORywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IEludGVnZXIoRnVuY3Rpb25UYWJsZS5GVU5DX05PVCkpOwotICAgICAgICAgIG1fZnVuY3Rpb25JRC5wdXQoS2V5d29yZHMuRlVOQ19UUlVFX1NUUklORywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IEludGVnZXIoRnVuY3Rpb25UYWJsZS5GVU5DX1RSVUUpKTsKLSAgICAgICAgICBtX2Z1bmN0aW9uSUQucHV0KEtleXdvcmRzLkZVTkNfRkFMU0VfU1RSSU5HLAotICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgSW50ZWdlcihGdW5jdGlvblRhYmxlLkZVTkNfRkFMU0UpKTsKLSAgICAgICAgICBtX2Z1bmN0aW9uSUQucHV0KEtleXdvcmRzLkZVTkNfQk9PTEVBTl9TVFJJTkcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBJbnRlZ2VyKEZ1bmN0aW9uVGFibGUuRlVOQ19CT09MRUFOKSk7Ci0gICAgICAgICAgbV9mdW5jdGlvbklELnB1dChLZXl3b3Jkcy5GVU5DX0xBTkdfU1RSSU5HLAotICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgSW50ZWdlcihGdW5jdGlvblRhYmxlLkZVTkNfTEFORykpOwotICAgICAgICAgIG1fZnVuY3Rpb25JRC5wdXQoS2V5d29yZHMuRlVOQ19OVU1CRVJfU1RSSU5HLAotICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgSW50ZWdlcihGdW5jdGlvblRhYmxlLkZVTkNfTlVNQkVSKSk7Ci0gICAgICAgICAgbV9mdW5jdGlvbklELnB1dChLZXl3b3Jkcy5GVU5DX0ZMT09SX1NUUklORywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IEludGVnZXIoRnVuY3Rpb25UYWJsZS5GVU5DX0ZMT09SKSk7Ci0gICAgICAgICAgbV9mdW5jdGlvbklELnB1dChLZXl3b3Jkcy5GVU5DX0NFSUxJTkdfU1RSSU5HLAotICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgSW50ZWdlcihGdW5jdGlvblRhYmxlLkZVTkNfQ0VJTElORykpOwotICAgICAgICAgIG1fZnVuY3Rpb25JRC5wdXQoS2V5d29yZHMuRlVOQ19ST1VORF9TVFJJTkcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBJbnRlZ2VyKEZ1bmN0aW9uVGFibGUuRlVOQ19ST1VORCkpOwotICAgICAgICAgIG1fZnVuY3Rpb25JRC5wdXQoS2V5d29yZHMuRlVOQ19TVU1fU1RSSU5HLAotICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgSW50ZWdlcihGdW5jdGlvblRhYmxlLkZVTkNfU1VNKSk7Ci0gICAgICAgICAgbV9mdW5jdGlvbklELnB1dChLZXl3b3Jkcy5GVU5DX1NUUklOR19TVFJJTkcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBJbnRlZ2VyKEZ1bmN0aW9uVGFibGUuRlVOQ19TVFJJTkcpKTsKLSAgICAgICAgICBtX2Z1bmN0aW9uSUQucHV0KEtleXdvcmRzLkZVTkNfU1RBUlRTX1dJVEhfU1RSSU5HLAotICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgSW50ZWdlcihGdW5jdGlvblRhYmxlLkZVTkNfU1RBUlRTX1dJVEgpKTsKLSAgICAgICAgICBtX2Z1bmN0aW9uSUQucHV0KEtleXdvcmRzLkZVTkNfQ09OVEFJTlNfU1RSSU5HLAotICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgSW50ZWdlcihGdW5jdGlvblRhYmxlLkZVTkNfQ09OVEFJTlMpKTsKLSAgICAgICAgICBtX2Z1bmN0aW9uSUQucHV0KEtleXdvcmRzLkZVTkNfU1VCU1RSSU5HX0JFRk9SRV9TVFJJTkcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBJbnRlZ2VyKEZ1bmN0aW9uVGFibGUuRlVOQ19TVUJTVFJJTkdfQkVGT1JFKSk7Ci0gICAgICAgICAgbV9mdW5jdGlvbklELnB1dChLZXl3b3Jkcy5GVU5DX1NVQlNUUklOR19BRlRFUl9TVFJJTkcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBJbnRlZ2VyKEZ1bmN0aW9uVGFibGUuRlVOQ19TVUJTVFJJTkdfQUZURVIpKTsKLSAgICAgICAgICBtX2Z1bmN0aW9uSUQucHV0KEtleXdvcmRzLkZVTkNfTk9STUFMSVpFX1NQQUNFX1NUUklORywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IEludGVnZXIoRnVuY3Rpb25UYWJsZS5GVU5DX05PUk1BTElaRV9TUEFDRSkpOwotICAgICAgICAgIG1fZnVuY3Rpb25JRC5wdXQoS2V5d29yZHMuRlVOQ19UUkFOU0xBVEVfU1RSSU5HLAotICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgSW50ZWdlcihGdW5jdGlvblRhYmxlLkZVTkNfVFJBTlNMQVRFKSk7Ci0gICAgICAgICAgbV9mdW5jdGlvbklELnB1dChLZXl3b3Jkcy5GVU5DX0NPTkNBVF9TVFJJTkcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBJbnRlZ2VyKEZ1bmN0aW9uVGFibGUuRlVOQ19DT05DQVQpKTsKLSAgICAgICAgICBtX2Z1bmN0aW9uSUQucHV0KEtleXdvcmRzLkZVTkNfU1lTVEVNX1BST1BFUlRZX1NUUklORywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IEludGVnZXIoRnVuY3Rpb25UYWJsZS5GVU5DX1NZU1RFTV9QUk9QRVJUWSkpOwotICAgICAgICAgIG1fZnVuY3Rpb25JRC5wdXQoS2V5d29yZHMuRlVOQ19FWFRfRlVOQ1RJT05fQVZBSUxBQkxFX1NUUklORywKLSAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBJbnRlZ2VyKEZ1bmN0aW9uVGFibGUuRlVOQ19FWFRfRlVOQ1RJT05fQVZBSUxBQkxFKSk7Ci0gICAgICAgICAgbV9mdW5jdGlvbklELnB1dChLZXl3b3Jkcy5GVU5DX0VYVF9FTEVNX0FWQUlMQUJMRV9TVFJJTkcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBJbnRlZ2VyKEZ1bmN0aW9uVGFibGUuRlVOQ19FWFRfRUxFTV9BVkFJTEFCTEUpKTsKLSAgICAgICAgICBtX2Z1bmN0aW9uSUQucHV0KEtleXdvcmRzLkZVTkNfU1VCU1RSSU5HX1NUUklORywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IEludGVnZXIoRnVuY3Rpb25UYWJsZS5GVU5DX1NVQlNUUklORykpOwotICAgICAgICAgIG1fZnVuY3Rpb25JRC5wdXQoS2V5d29yZHMuRlVOQ19TVFJJTkdfTEVOR1RIX1NUUklORywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IEludGVnZXIoRnVuY3Rpb25UYWJsZS5GVU5DX1NUUklOR19MRU5HVEgpKTsKLSAgICAgICAgICBtX2Z1bmN0aW9uSUQucHV0KEtleXdvcmRzLkZVTkNfVU5QQVJTRURfRU5USVRZX1VSSV9TVFJJTkcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBJbnRlZ2VyKEZ1bmN0aW9uVGFibGUuRlVOQ19VTlBBUlNFRF9FTlRJVFlfVVJJKSk7Ci0gICAgICAgICAgbV9mdW5jdGlvbklELnB1dChLZXl3b3Jkcy5GVU5DX0RPQ0xPQ0FUSU9OX1NUUklORywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IEludGVnZXIoRnVuY3Rpb25UYWJsZS5GVU5DX0RPQ0xPQ0FUSU9OKSk7Ci0gIH0KLQotICBwdWJsaWMgRnVuY3Rpb25UYWJsZSgpewotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgbmFtZSBvZiB0aGUgYSBmdW5jdGlvbiBpbiB0aGUgc3RhdGljIHRhYmxlLiBOZWVkZWQgdG8gYXZvaWQKLSAgICogbWFraW5nIHRoZSB0YWJsZSBwdWJsaWNseSBhdmFpbGFibGUuCi0gICAqLwotICBTdHJpbmcgZ2V0RnVuY3Rpb25OYW1lKGludCBmdW5jSUQpIHsKLSAgICAgIGlmIChmdW5jSUQgPCBOVU1fQlVJTFRfSU5fRlVOQ1MpIHJldHVybiBtX2Z1bmN0aW9uc1tmdW5jSURdLmdldE5hbWUoKTsKLSAgICAgIGVsc2UgcmV0dXJuIG1fZnVuY3Rpb25zX2N1c3RvbWVyW2Z1bmNJRCAtIE5VTV9CVUlMVF9JTl9GVU5DU10uZ2V0TmFtZSgpOwotICB9Ci0KLSAgLyoqCi0gICAqIE9idGFpbiBhIG5ldyBGdW5jdGlvbiBvYmplY3QgZnJvbSBhIGZ1bmN0aW9uIElELgotICAgKgotICAgKiBAcGFyYW0gd2hpY2ggIFRoZSBmdW5jdGlvbiBJRCwgd2hpY2ggbWF5IGNvcnJlc3BvbmQgdG8gb25lIG9mIHRoZSBGVU5DX1hYWAotICAgKiAgICB2YWx1ZXMgZm91bmQgaW4ge0BsaW5rIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5jb21waWxlci5GdW5jdGlvblRhYmxlfSwgYnV0IG1heQotICAgKiAgICBiZSBhIHZhbHVlIGluc3RhbGxlZCBieSBhbiBleHRlcm5hbCBtb2R1bGUuCi0gICAqCi0gICAqIEByZXR1cm4gYSBhIG5ldyBGdW5jdGlvbiBpbnN0YW5jZS4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uIGlmIENsYXNzTm90Rm91bmRFeGNlcHRpb24sCi0gICAqICAgIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24sIG9yIEluc3RhbnRpYXRpb25FeGNlcHRpb24gaXMgdGhyb3duLgotICAgKi8KLSAgRnVuY3Rpb24gZ2V0RnVuY3Rpb24oaW50IHdoaWNoKQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICAgICAgICB0cnl7Ci0gICAgICAgICAgICAgIGlmICh3aGljaCA8IE5VTV9CVUlMVF9JTl9GVU5DUykKLSAgICAgICAgICAgICAgICAgIHJldHVybiAoRnVuY3Rpb24pIG1fZnVuY3Rpb25zW3doaWNoXS5uZXdJbnN0YW5jZSgpOwotICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICByZXR1cm4gKEZ1bmN0aW9uKSBtX2Z1bmN0aW9uc19jdXN0b21lclsKLSAgICAgICAgICAgICAgICAgICAgICB3aGljaC1OVU1fQlVJTFRfSU5fRlVOQ1NdLm5ld0luc3RhbmNlKCk7Ci0gICAgICAgICAgfWNhdGNoIChJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIGV4KXsKLSAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihleC5nZXRNZXNzYWdlKCkpOwotICAgICAgICAgIH1jYXRjaCAoSW5zdGFudGlhdGlvbkV4Y2VwdGlvbiBleCl7Ci0gICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oZXguZ2V0TWVzc2FnZSgpKTsKLSAgICAgICAgICB9Ci0gIH0KLQotICAvKioKLSAgICogT2J0YWluIGEgZnVuY3Rpb24gSUQgZnJvbSBhIGdpdmVuIGZ1bmN0aW9uIG5hbWUKLSAgICogQHBhcmFtIGtleSB0aGUgZnVuY3Rpb24gbmFtZSBpbiBhIGphdmEubGFuZy5TdHJpbmcgZm9ybWF0LgotICAgKiBAcmV0dXJuIGEgZnVuY3Rpb24gSUQsIHdoaWNoIG1heSBjb3JyZXNwb25kIHRvIG9uZSBvZiB0aGUgRlVOQ19YWFggdmFsdWVzCi0gICAqIGZvdW5kIGluIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuY29tcGlsZXIuRnVuY3Rpb25UYWJsZX0sIGJ1dCBtYXkgYmUgYQotICAgKiB2YWx1ZSBpbnN0YWxsZWQgYnkgYW4gZXh0ZXJuYWwgbW9kdWxlLgotICAgKi8KLSAgT2JqZWN0IGdldEZ1bmN0aW9uSUQoU3RyaW5nIGtleSl7Ci0gICAgICAgICAgT2JqZWN0IGlkID0gbV9mdW5jdGlvbklEX2N1c3RvbWVyLmdldChrZXkpOwotICAgICAgICAgIGlmIChudWxsID09IGlkKSBpZCA9IG1fZnVuY3Rpb25JRC5nZXQoa2V5KTsKLSAgICAgICAgICByZXR1cm4gaWQ7Ci0gIH0KLQotICAvKioKLSAgICogSW5zdGFsbCBhIGJ1aWx0LWluIGZ1bmN0aW9uLgotICAgKiBAcGFyYW0gbmFtZSBUaGUgdW5xdWFsaWZpZWQgbmFtZSBvZiB0aGUgZnVuY3Rpb24sIG11c3Qgbm90IGJlIG51bGwKLSAgICogQHBhcmFtIGZ1bmMgQSBJbXBsZW1lbnRhdGlvbiBvZiBhbiBYUGF0aCBGdW5jdGlvbiBvYmplY3QuCi0gICAqIEByZXR1cm4gdGhlIHBvc2l0aW9uIG9mIHRoZSBmdW5jdGlvbiBpbiB0aGUgaW50ZXJuYWwgaW5kZXguCi0gICAqLwotICBwdWJsaWMgaW50IGluc3RhbGxGdW5jdGlvbihTdHJpbmcgbmFtZSwgQ2xhc3MgZnVuYykKLSAgewotCi0gICAgaW50IGZ1bmNJbmRleDsKLSAgICBPYmplY3QgZnVuY0luZGV4T2JqID0gZ2V0RnVuY3Rpb25JRChuYW1lKTsKLQotICAgIGlmIChudWxsICE9IGZ1bmNJbmRleE9iaikKLSAgICB7Ci0gICAgICBmdW5jSW5kZXggPSAoKEludGVnZXIpIGZ1bmNJbmRleE9iaikuaW50VmFsdWUoKTsKLQotICAgICAgaWYgKGZ1bmNJbmRleCA8IE5VTV9CVUlMVF9JTl9GVU5DUyl7Ci0gICAgICAgICAgICAgIGZ1bmNJbmRleCA9IG1fZnVuY05leHRGcmVlSW5kZXgrKzsKLSAgICAgICAgICAgICAgbV9mdW5jdGlvbklEX2N1c3RvbWVyLnB1dChuYW1lLCBuZXcgSW50ZWdlcihmdW5jSW5kZXgpKTsKLSAgICAgIH0KLSAgICAgIG1fZnVuY3Rpb25zX2N1c3RvbWVyW2Z1bmNJbmRleCAtIE5VTV9CVUlMVF9JTl9GVU5DU10gPSBmdW5jOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgICAgICAgZnVuY0luZGV4ID0gbV9mdW5jTmV4dEZyZWVJbmRleCsrOwotCi0gICAgICAgICAgICBtX2Z1bmN0aW9uc19jdXN0b21lcltmdW5jSW5kZXgtTlVNX0JVSUxUX0lOX0ZVTkNTXSA9IGZ1bmM7Ci0KLSAgICAgICAgICAgIG1fZnVuY3Rpb25JRF9jdXN0b21lci5wdXQobmFtZSwKLSAgICAgICAgICAgICAgICBuZXcgSW50ZWdlcihmdW5jSW5kZXgpKTsKLSAgICB9Ci0gICAgcmV0dXJuIGZ1bmNJbmRleDsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIGlmIGEgYnVpbHQtaW4sIG5vbi1uYW1lc3BhY2VkIGZ1bmN0aW9uIGlzIGF2YWlsYWJsZS4KLSAgICoKLSAgICogQHBhcmFtIG1ldGhOYW1lIFRoZSBsb2NhbCBuYW1lIG9mIHRoZSBmdW5jdGlvbi4KLSAgICoKLSAgICogQHJldHVybiBUcnVlIGlmIHRoZSBmdW5jdGlvbiBjYW4gYmUgZXhlY3V0ZWQuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBmdW5jdGlvbkF2YWlsYWJsZShTdHJpbmcgbWV0aE5hbWUpCi0gIHsKLSAgICAgIE9iamVjdCB0YmxFbnRyeSA9IG1fZnVuY3Rpb25JRC5nZXQobWV0aE5hbWUpOwotICAgICAgaWYgKG51bGwgIT0gdGJsRW50cnkpIHJldHVybiB0cnVlOwotICAgICAgZWxzZXsKLSAgICAgICAgICAgICAgdGJsRW50cnkgPSBtX2Z1bmN0aW9uSURfY3VzdG9tZXIuZ2V0KG1ldGhOYW1lKTsKLSAgICAgICAgICAgICAgcmV0dXJuIChudWxsICE9IHRibEVudHJ5KT8gdHJ1ZSA6IGZhbHNlOwotICAgICAgfQotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2NvbXBpbGVyL0tleXdvcmRzLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2NvbXBpbGVyL0tleXdvcmRzLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGI5MTBiNGQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9jb21waWxlci9LZXl3b3Jkcy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzkwICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKi8KLS8qCi0gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKLSAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAotICogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgotICogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKLSAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCi0gKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IEtleXdvcmRzLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTQgMTk6NDY6MDEgamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5jb21waWxlcjsKLQotaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKLWltcG9ydCBqYXZhLnV0aWwuTWFwOwotCi0vKioKLSAqIFRhYmxlIG9mIHN0cmluZ3MgdG8gb3BlcmF0aW9uIGNvZGUgbG9va3Vwcy4KLSAqCi0gKiBAeHNsLnVzYWdlIGludGVybmFsCi0gKi8KLXB1YmxpYyBjbGFzcyBLZXl3b3JkcyB7Ci0KLSAgICAvKioKLSAgICAgKiBUYWJsZSBvZiBrZXl3b3JkcyB0byBvcGNvZGUgYXNzb2NpYXRpb25zLgotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIE1hcDxTdHJpbmcsIEludGVnZXI+IG1fa2V5d29yZHM7Ci0KLSAgICAvKioKLSAgICAgKiBUYWJsZSBvZiBheGVzIG5hbWVzIHRvIG9wY29kZSBhc3NvY2lhdGlvbnMuCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTWFwPFN0cmluZywgSW50ZWdlcj4gbV9heGlzbmFtZXM7Ci0KLSAgICAvKioKLSAgICAgKiBUYWJsZSBvZiBmdW5jdGlvbiBuYW1lIHRvIGZ1bmN0aW9uIElEIGFzc29jaWF0aW9ucy4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBNYXA8U3RyaW5nLCBJbnRlZ2VyPiBtX25vZGV0ZXN0czsKLQotICAgIC8qKgotICAgICAqIFRhYmxlIG9mIG5vZGUgdHlwZSBzdHJpbmdzIHRvIG9wY29kZSBhc3NvY2lhdGlvbnMuCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTWFwPFN0cmluZywgSW50ZWdlcj4gbV9ub2RldHlwZXM7Ci0KLSAgICAvKioKLSAgICAgKiBhbmNlc3RvciBheGVzIHN0cmluZy4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRlJPTV9BTkNFU1RPUlNfU1RSSU5HID0gImFuY2VzdG9yIjsKLQotICAgIC8qKgotICAgICAqIGFuY2VzdG9yLW9yLXNlbGYgYXhlcyBzdHJpbmcuCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEZST01fQU5DRVNUT1JTX09SX1NFTEZfU1RSSU5HCi0gICAgICAgICAgICA9ICJhbmNlc3Rvci1vci1zZWxmIjsKLQotICAgIC8qKgotICAgICAqIGF0dHJpYnV0ZSBheGVzIHN0cmluZy4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRlJPTV9BVFRSSUJVVEVTX1NUUklORyA9ICJhdHRyaWJ1dGUiOwotCi0gICAgLyoqCi0gICAgICogY2hpbGQgYXhlcyBzdHJpbmcuCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEZST01fQ0hJTERSRU5fU1RSSU5HID0gImNoaWxkIjsKLQotICAgIC8qKgotICAgICAqIGRlc2NlbmRhbnQtb3Itc2VsZiBheGVzIHN0cmluZy4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRlJPTV9ERVNDRU5EQU5UU19TVFJJTkcgPSAiZGVzY2VuZGFudCI7Ci0KLSAgICAvKioKLSAgICAgKiBhbmNlc3RvciBheGVzIHN0cmluZy4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRlJPTV9ERVNDRU5EQU5UU19PUl9TRUxGX1NUUklORwotICAgICAgICAgICAgPSAiZGVzY2VuZGFudC1vci1zZWxmIjsKLQotICAgIC8qKgotICAgICAqIGZvbGxvd2luZyBheGVzIHN0cmluZy4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRlJPTV9GT0xMT1dJTkdfU1RSSU5HID0gImZvbGxvd2luZyI7Ci0KLSAgICAvKioKLSAgICAgKiBmb2xsb3dpbmctc2libGluZyBheGVzIHN0cmluZy4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRlJPTV9GT0xMT1dJTkdfU0lCTElOR1NfU1RSSU5HCi0gICAgICAgICAgICA9ICJmb2xsb3dpbmctc2libGluZyI7Ci0KLSAgICAvKioKLSAgICAgKiBwYXJlbnQgYXhlcyBzdHJpbmcuCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEZST01fUEFSRU5UX1NUUklORyA9ICJwYXJlbnQiOwotCi0gICAgLyoqCi0gICAgICogcHJlY2VkaW5nIGF4ZXMgc3RyaW5nLgotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBGUk9NX1BSRUNFRElOR19TVFJJTkcgPSAicHJlY2VkaW5nIjsKLQotICAgIC8qKgotICAgICAqIHByZWNlZGluZy1zaWJsaW5nIGF4ZXMgc3RyaW5nLgotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBGUk9NX1BSRUNFRElOR19TSUJMSU5HU19TVFJJTkcKLSAgICAgICAgICAgID0gInByZWNlZGluZy1zaWJsaW5nIjsKLQotICAgIC8qKgotICAgICAqIHNlbGYgYXhlcyBzdHJpbmcuCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEZST01fU0VMRl9TVFJJTkcgPSAic2VsZiI7Ci0KLSAgICAvKioKLSAgICAgKiBuYW1lc3BhY2UgYXhlcyBzdHJpbmcuCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEZST01fTkFNRVNQQUNFX1NUUklORyA9ICJuYW1lc3BhY2UiOwotCi0gICAgLyoqCi0gICAgICogc2VsZiBheGVzIGFicmV2aWF0ZWQgc3RyaW5nLgotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBGUk9NX1NFTEZfQUJCUkVWSUFURURfU1RSSU5HID0gIi4iOwotCi0gICAgLyoqCi0gICAgICogY29tbWVudCBub2RlIHRlc3Qgc3RyaW5nLgotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBOT0RFVFlQRV9DT01NRU5UX1NUUklORyA9ICJjb21tZW50IjsKLQotICAgIC8qKgotICAgICAqIHRleHQgbm9kZSB0ZXN0IHN0cmluZy4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgTk9ERVRZUEVfVEVYVF9TVFJJTkcgPSAidGV4dCI7Ci0KLSAgICAvKioKLSAgICAgKiBwcm9jZXNzaW5nLWluc3RydWN0aW9uIG5vZGUgdGVzdCBzdHJpbmcuCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIE5PREVUWVBFX1BJX1NUUklORyA9ICJwcm9jZXNzaW5nLWluc3RydWN0aW9uIjsKLQotICAgIC8qKgotICAgICAqIEFueSBub2RlIHRlc3Qgc3RyaW5nLgotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBOT0RFVFlQRV9OT0RFX1NUUklORyA9ICJub2RlIjsKLQotICAgIC8qKgotICAgICAqIFdpbGRjYXJkIGVsZW1lbnQgc3RyaW5nLgotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBOT0RFVFlQRV9BTllFTEVNRU5UX1NUUklORyA9ICIqIjsKLQotICAgIC8qKgotICAgICAqIGN1cnJlbnQgZnVuY3Rpb24gc3RyaW5nLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEZVTkNfQ1VSUkVOVF9TVFJJTkcgPSAiY3VycmVudCI7Ci0KLSAgICAvKioKLSAgICAgKiBsYXN0IGZ1bmN0aW9uIHN0cmluZy4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBGVU5DX0xBU1RfU1RSSU5HID0gImxhc3QiOwotCi0gICAgLyoqCi0gICAgICogcG9zaXRpb24gZnVuY3Rpb24gc3RyaW5nLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEZVTkNfUE9TSVRJT05fU1RSSU5HID0gInBvc2l0aW9uIjsKLQotICAgIC8qKgotICAgICAqIGNvdW50IGZ1bmN0aW9uIHN0cmluZy4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBGVU5DX0NPVU5UX1NUUklORyA9ICJjb3VudCI7Ci0KLSAgICAvKioKLSAgICAgKiBpZCBmdW5jdGlvbiBzdHJpbmcuCi0gICAgICovCi0gICAgc3RhdGljIGZpbmFsIFN0cmluZyBGVU5DX0lEX1NUUklORyA9ICJpZCI7Ci0KLSAgICAvKioKLSAgICAgKiBrZXkgZnVuY3Rpb24gc3RyaW5nIChYU0xUKS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBGVU5DX0tFWV9TVFJJTkcgPSAia2V5IjsKLQotICAgIC8qKgotICAgICAqIGxvY2FsLW5hbWUgZnVuY3Rpb24gc3RyaW5nLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEZVTkNfTE9DQUxfUEFSVF9TVFJJTkcgPSAibG9jYWwtbmFtZSI7Ci0KLSAgICAvKioKLSAgICAgKiBuYW1lc3BhY2UtdXJpIGZ1bmN0aW9uIHN0cmluZy4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBGVU5DX05BTUVTUEFDRV9TVFJJTkcgPSAibmFtZXNwYWNlLXVyaSI7Ci0KLSAgICAvKioKLSAgICAgKiBuYW1lIGZ1bmN0aW9uIHN0cmluZy4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBGVU5DX05BTUVfU1RSSU5HID0gIm5hbWUiOwotCi0gICAgLyoqCi0gICAgICogZ2VuZXJhdGUtaWQgZnVuY3Rpb24gc3RyaW5nIChYU0xUKS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBGVU5DX0dFTkVSQVRFX0lEX1NUUklORyA9ICJnZW5lcmF0ZS1pZCI7Ci0KLSAgICAvKioKLSAgICAgKiBub3QgZnVuY3Rpb24gc3RyaW5nLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEZVTkNfTk9UX1NUUklORyA9ICJub3QiOwotCi0gICAgLyoqCi0gICAgICogdHJ1ZSBmdW5jdGlvbiBzdHJpbmcuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRlVOQ19UUlVFX1NUUklORyA9ICJ0cnVlIjsKLQotICAgIC8qKgotICAgICAqIGZhbHNlIGZ1bmN0aW9uIHN0cmluZy4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBGVU5DX0ZBTFNFX1NUUklORyA9ICJmYWxzZSI7Ci0KLSAgICAvKioKLSAgICAgKiBib29sZWFuIGZ1bmN0aW9uIHN0cmluZy4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBGVU5DX0JPT0xFQU5fU1RSSU5HID0gImJvb2xlYW4iOwotCi0gICAgLyoqCi0gICAgICogbGFuZyBmdW5jdGlvbiBzdHJpbmcuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRlVOQ19MQU5HX1NUUklORyA9ICJsYW5nIjsKLQotICAgIC8qKgotICAgICAqIG51bWJlciBmdW5jdGlvbiBzdHJpbmcuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRlVOQ19OVU1CRVJfU1RSSU5HID0gIm51bWJlciI7Ci0KLSAgICAvKioKLSAgICAgKiBmbG9vciBmdW5jdGlvbiBzdHJpbmcuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRlVOQ19GTE9PUl9TVFJJTkcgPSAiZmxvb3IiOwotCi0gICAgLyoqCi0gICAgICogY2VpbGluZyBmdW5jdGlvbiBzdHJpbmcuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRlVOQ19DRUlMSU5HX1NUUklORyA9ICJjZWlsaW5nIjsKLQotICAgIC8qKgotICAgICAqIHJvdW5kIGZ1bmN0aW9uIHN0cmluZy4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBGVU5DX1JPVU5EX1NUUklORyA9ICJyb3VuZCI7Ci0KLSAgICAvKioKLSAgICAgKiBzdW0gZnVuY3Rpb24gc3RyaW5nLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEZVTkNfU1VNX1NUUklORyA9ICJzdW0iOwotCi0gICAgLyoqCi0gICAgICogc3RyaW5nIGZ1bmN0aW9uIHN0cmluZy4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBGVU5DX1NUUklOR19TVFJJTkcgPSAic3RyaW5nIjsKLQotICAgIC8qKgotICAgICAqIHN0YXJ0cy13aXRoIGZ1bmN0aW9uIHN0cmluZy4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBGVU5DX1NUQVJUU19XSVRIX1NUUklORyA9ICJzdGFydHMtd2l0aCI7Ci0KLSAgICAvKioKLSAgICAgKiBjb250YWlucyBmdW5jdGlvbiBzdHJpbmcuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRlVOQ19DT05UQUlOU19TVFJJTkcgPSAiY29udGFpbnMiOwotCi0gICAgLyoqCi0gICAgICogc3Vic3RyaW5nLWJlZm9yZSBmdW5jdGlvbiBzdHJpbmcuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRlVOQ19TVUJTVFJJTkdfQkVGT1JFX1NUUklORwotICAgICAgICAgICAgPSAic3Vic3RyaW5nLWJlZm9yZSI7Ci0KLSAgICAvKioKLSAgICAgKiBzdWJzdHJpbmctYWZ0ZXIgZnVuY3Rpb24gc3RyaW5nLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEZVTkNfU1VCU1RSSU5HX0FGVEVSX1NUUklORyA9ICJzdWJzdHJpbmctYWZ0ZXIiOwotCi0gICAgLyoqCi0gICAgICogbm9ybWFsaXplLXNwYWNlIGZ1bmN0aW9uIHN0cmluZy4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBGVU5DX05PUk1BTElaRV9TUEFDRV9TVFJJTkcgPSAibm9ybWFsaXplLXNwYWNlIjsKLQotICAgIC8qKgotICAgICAqIHRyYW5zbGF0ZSBmdW5jdGlvbiBzdHJpbmcuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRlVOQ19UUkFOU0xBVEVfU1RSSU5HID0gInRyYW5zbGF0ZSI7Ci0KLSAgICAvKioKLSAgICAgKiBjb25jYXQgZnVuY3Rpb24gc3RyaW5nLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEZVTkNfQ09OQ0FUX1NUUklORyA9ICJjb25jYXQiOwotCi0gICAgLyoqCi0gICAgICogc3lzdGVtLXByb3BlcnR5IGZ1bmN0aW9uIHN0cmluZy4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBGVU5DX1NZU1RFTV9QUk9QRVJUWV9TVFJJTkcgPSAic3lzdGVtLXByb3BlcnR5IjsKLQotICAgIC8qKgotICAgICAqIGZ1bmN0aW9uLWF2YWlsYWJsZSBmdW5jdGlvbiBzdHJpbmcgKFhTTFQpLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEZVTkNfRVhUX0ZVTkNUSU9OX0FWQUlMQUJMRV9TVFJJTkcKLSAgICAgICAgICAgID0gImZ1bmN0aW9uLWF2YWlsYWJsZSI7Ci0KLSAgICAvKioKLSAgICAgKiBlbGVtZW50LWF2YWlsYWJsZSBmdW5jdGlvbiBzdHJpbmcgKFhTTFQpLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEZVTkNfRVhUX0VMRU1fQVZBSUxBQkxFX1NUUklORwotICAgICAgICAgICAgPSAiZWxlbWVudC1hdmFpbGFibGUiOwotCi0gICAgLyoqCi0gICAgICogc3Vic3RyaW5nIGZ1bmN0aW9uIHN0cmluZy4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBGVU5DX1NVQlNUUklOR19TVFJJTkcgPSAic3Vic3RyaW5nIjsKLQotICAgIC8qKgotICAgICAqIHN0cmluZy1sZW5ndGggZnVuY3Rpb24gc3RyaW5nLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEZVTkNfU1RSSU5HX0xFTkdUSF9TVFJJTkcgPSAic3RyaW5nLWxlbmd0aCI7Ci0KLSAgICAvKioKLSAgICAgKiB1bnBhcnNlZC1lbnRpdHktdXJpIGZ1bmN0aW9uIHN0cmluZyAoWFNMVCkuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRlVOQ19VTlBBUlNFRF9FTlRJVFlfVVJJX1NUUklORwotICAgICAgICAgICAgPSAidW5wYXJzZWQtZW50aXR5LXVyaSI7Ci0KLSAgLy8gUHJvcHJpZXRhcnksIGJ1aWx0IGluIGZ1bmN0aW9ucwotICAgIC8qKgotICAgICAqIGN1cnJlbnQgZnVuY3Rpb24gc3RyaW5nIChQcm9wcmlldGFyeSkuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRlVOQ19ET0NMT0NBVElPTl9TVFJJTkcgPSAiZG9jdW1lbnQtbG9jYXRpb24iOwotCi0gICAgc3RhdGljIHsKLSAgICAgICAgTWFwPFN0cmluZywgSW50ZWdlcj4ga2V5d29yZHMgPSBuZXcgSGFzaE1hcDw+KCk7Ci0gICAgICAgIE1hcDxTdHJpbmcsIEludGVnZXI+IGF4aXNuYW1lcyA9IG5ldyBIYXNoTWFwPD4oKTsKLSAgICAgICAgTWFwPFN0cmluZywgSW50ZWdlcj4gbm9kZXRlc3RzID0gbmV3IEhhc2hNYXA8PigpOwotICAgICAgICBNYXA8U3RyaW5nLCBJbnRlZ2VyPiBub2RldHlwZXMgPSBuZXcgSGFzaE1hcDw+KCk7Ci0KLSAgICAgICAgYXhpc25hbWVzLnB1dChGUk9NX0FOQ0VTVE9SU19TVFJJTkcsIE9wQ29kZXMuRlJPTV9BTkNFU1RPUlMpOwotICAgICAgICBheGlzbmFtZXMucHV0KEZST01fQU5DRVNUT1JTX09SX1NFTEZfU1RSSU5HLCBPcENvZGVzLkZST01fQU5DRVNUT1JTX09SX1NFTEYpOwotICAgICAgICBheGlzbmFtZXMucHV0KEZST01fQVRUUklCVVRFU19TVFJJTkcsIE9wQ29kZXMuRlJPTV9BVFRSSUJVVEVTKTsKLSAgICAgICAgYXhpc25hbWVzLnB1dChGUk9NX0NISUxEUkVOX1NUUklORywgT3BDb2Rlcy5GUk9NX0NISUxEUkVOKTsKLSAgICAgICAgYXhpc25hbWVzLnB1dChGUk9NX0RFU0NFTkRBTlRTX1NUUklORywgT3BDb2Rlcy5GUk9NX0RFU0NFTkRBTlRTKTsKLSAgICAgICAgYXhpc25hbWVzLnB1dChGUk9NX0RFU0NFTkRBTlRTX09SX1NFTEZfU1RSSU5HLCBPcENvZGVzLkZST01fREVTQ0VOREFOVFNfT1JfU0VMRik7Ci0gICAgICAgIGF4aXNuYW1lcy5wdXQoRlJPTV9GT0xMT1dJTkdfU1RSSU5HLCBPcENvZGVzLkZST01fRk9MTE9XSU5HKTsKLSAgICAgICAgYXhpc25hbWVzLnB1dChGUk9NX0ZPTExPV0lOR19TSUJMSU5HU19TVFJJTkcsIE9wQ29kZXMuRlJPTV9GT0xMT1dJTkdfU0lCTElOR1MpOwotICAgICAgICBheGlzbmFtZXMucHV0KEZST01fUEFSRU5UX1NUUklORywgT3BDb2Rlcy5GUk9NX1BBUkVOVCk7Ci0gICAgICAgIGF4aXNuYW1lcy5wdXQoRlJPTV9QUkVDRURJTkdfU1RSSU5HLCBPcENvZGVzLkZST01fUFJFQ0VESU5HKTsKLSAgICAgICAgYXhpc25hbWVzLnB1dChGUk9NX1BSRUNFRElOR19TSUJMSU5HU19TVFJJTkcsIE9wQ29kZXMuRlJPTV9QUkVDRURJTkdfU0lCTElOR1MpOwotICAgICAgICBheGlzbmFtZXMucHV0KEZST01fU0VMRl9TVFJJTkcsIE9wQ29kZXMuRlJPTV9TRUxGKTsKLSAgICAgICAgYXhpc25hbWVzLnB1dChGUk9NX05BTUVTUEFDRV9TVFJJTkcsIE9wQ29kZXMuRlJPTV9OQU1FU1BBQ0UpOwotICAgICAgICBtX2F4aXNuYW1lcyA9IENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZU1hcChheGlzbmFtZXMpOwotCi0gICAgICAgIG5vZGV0eXBlcy5wdXQoTk9ERVRZUEVfQ09NTUVOVF9TVFJJTkcsIE9wQ29kZXMuTk9ERVRZUEVfQ09NTUVOVCk7Ci0gICAgICAgIG5vZGV0eXBlcy5wdXQoTk9ERVRZUEVfVEVYVF9TVFJJTkcsIE9wQ29kZXMuTk9ERVRZUEVfVEVYVCk7Ci0gICAgICAgIG5vZGV0eXBlcy5wdXQoTk9ERVRZUEVfUElfU1RSSU5HLCBPcENvZGVzLk5PREVUWVBFX1BJKTsKLSAgICAgICAgbm9kZXR5cGVzLnB1dChOT0RFVFlQRV9OT0RFX1NUUklORywgT3BDb2Rlcy5OT0RFVFlQRV9OT0RFKTsKLSAgICAgICAgbm9kZXR5cGVzLnB1dChOT0RFVFlQRV9BTllFTEVNRU5UX1NUUklORywgT3BDb2Rlcy5OT0RFVFlQRV9BTllFTEVNRU5UKTsKLSAgICAgICAgbV9ub2RldHlwZXMgPSBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVNYXAobm9kZXR5cGVzKTsKLQotICAgICAgICBrZXl3b3Jkcy5wdXQoRlJPTV9TRUxGX0FCQlJFVklBVEVEX1NUUklORywgT3BDb2Rlcy5GUk9NX1NFTEYpOwotICAgICAgICBrZXl3b3Jkcy5wdXQoRlVOQ19JRF9TVFJJTkcsIEZ1bmN0aW9uVGFibGUuRlVOQ19JRCk7Ci0gICAgICAgIGtleXdvcmRzLnB1dChGVU5DX0tFWV9TVFJJTkcsIEZ1bmN0aW9uVGFibGUuRlVOQ19LRVkpOwotICAgICAgICBtX2tleXdvcmRzID0gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTWFwKGtleXdvcmRzKTsKLQotICAgICAgICBub2RldGVzdHMucHV0KE5PREVUWVBFX0NPTU1FTlRfU1RSSU5HLCBPcENvZGVzLk5PREVUWVBFX0NPTU1FTlQpOwotICAgICAgICBub2RldGVzdHMucHV0KE5PREVUWVBFX1RFWFRfU1RSSU5HLCBPcENvZGVzLk5PREVUWVBFX1RFWFQpOwotICAgICAgICBub2RldGVzdHMucHV0KE5PREVUWVBFX1BJX1NUUklORywgT3BDb2Rlcy5OT0RFVFlQRV9QSSk7Ci0gICAgICAgIG5vZGV0ZXN0cy5wdXQoTk9ERVRZUEVfTk9ERV9TVFJJTkcsIE9wQ29kZXMuTk9ERVRZUEVfTk9ERSk7Ci0gICAgICAgIG1fbm9kZXRlc3RzID0gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTWFwKG5vZGV0ZXN0cyk7Ci0gICAgfQotCi0gICAgc3RhdGljIEludGVnZXIgZ2V0QXhpc05hbWUoU3RyaW5nIGtleSkgewotICAgICAgICByZXR1cm4gbV9heGlzbmFtZXMuZ2V0KGtleSk7Ci0gICAgfQotCi0gICAgc3RhdGljIEludGVnZXIgbG9va3VwTm9kZVRlc3QoU3RyaW5nIGtleSkgewotICAgICAgICByZXR1cm4gbV9ub2RldGVzdHMuZ2V0KGtleSk7Ci0gICAgfQotCi0gICAgc3RhdGljIEludGVnZXIgZ2V0S2V5V29yZChTdHJpbmcga2V5KSB7Ci0gICAgICAgIHJldHVybiBtX2tleXdvcmRzLmdldChrZXkpOwotICAgIH0KLQotICAgIHN0YXRpYyBJbnRlZ2VyIGdldE5vZGVUeXBlKFN0cmluZyBrZXkpIHsKLSAgICAgICAgcmV0dXJuIG1fbm9kZXR5cGVzLmdldChrZXkpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvY29tcGlsZXIvTGV4ZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvY29tcGlsZXIvTGV4ZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNWFmNmYxOC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2NvbXBpbGVyL0xleGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw2NjQgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogTGV4ZXIuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xMCAwMzo1NTo0NSBqZWZmc3V0dG9yIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmNvbXBpbGVyOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuUHJlZml4UmVzb2x2ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLnJlcy5YUEFUSEVycm9yUmVzb3VyY2VzOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgaXMgaW4gY2hhcmdlIG9mIGxleGljYWwgcHJvY2Vzc2luZyBvZiB0aGUgWFBhdGgKLSAqIGV4cHJlc3Npb24gaW50byB0b2tlbnMuCi0gKi8KLWNsYXNzIExleGVyCi17Ci0KLSAgLyoqCi0gICAqIFRoZSB0YXJnZXQgWFBhdGguCi0gICAqLwotICBwcml2YXRlIENvbXBpbGVyIG1fY29tcGlsZXI7Ci0KLSAgLyoqCi0gICAqIFRoZSBwcmVmaXggcmVzb2x2ZXIgdG8gbWFwIHByZWZpeGVzIHRvIG5hbWVzcGFjZXMgaW4gdGhlIFhQYXRoLgotICAgKi8KLSAgUHJlZml4UmVzb2x2ZXIgbV9uYW1lc3BhY2VDb250ZXh0OwotCi0gIC8qKgotICAgKiBUaGUgWFBhdGggcHJvY2Vzc29yIG9iamVjdC4KLSAgICovCi0gIFhQYXRoUGFyc2VyIG1fcHJvY2Vzc29yOwotCi0gIC8qKgotICAgKiBUaGlzIHZhbHVlIGlzIGFkZGVkIHRvIGVhY2ggZWxlbWVudCBuYW1lIGluIHRoZSBUQVJHRVRFWFRSQQotICAgKiB0aGF0IGlzIGEgJ3RhcmdldCcgKHJpZ2h0LW1vc3QgdG9wLWxldmVsIGVsZW1lbnQgbmFtZSkuCi0gICAqLwotICBzdGF0aWMgZmluYWwgaW50IFRBUkdFVEVYVFJBID0gMTAwMDA7Ci0KLSAgLyoqCi0gICAqIElnbm9yZSB0aGlzLCBpdCBpcyBnb2luZyBhd2F5LgotICAgKiBUaGlzIGhvbGRzIGEgbWFwIHRvIHRoZSBtX3Rva2VuUXVldWUgdGhhdCB0ZWxscyB3aGVyZSB0aGUgdG9wLWxldmVsIGVsZW1lbnRzIGFyZS4KLSAgICogSXQgaXMgdXNlZCBmb3IgcGF0dGVybiBtYXRjaGluZyBzbyB0aGUgbV90b2tlblF1ZXVlIGNhbiBiZSB3YWxrZWQgYmFja3dhcmRzLgotICAgKiBFYWNoIGVsZW1lbnQgdGhhdCBpcyBhICd0YXJnZXQnLCAocmlnaHQtbW9zdCB0b3AgbGV2ZWwgZWxlbWVudCBuYW1lKSBoYXMKLSAgICogVEFSR0VURVhUUkEgYWRkZWQgdG8gaXQuCi0gICAqCi0gICAqLwotICBwcml2YXRlIGludCBtX3BhdHRlcm5NYXBbXSA9IG5ldyBpbnRbMTAwXTsKLQotICAvKioKLSAgICogSWdub3JlIHRoaXMsIGl0IGlzIGdvaW5nIGF3YXkuCi0gICAqIFRoZSBudW1iZXIgb2YgZWxlbWVudHMgdGhhdCBtX3BhdHRlcm5NYXAgbWFwczsKLSAgICovCi0gIHByaXZhdGUgaW50IG1fcGF0dGVybk1hcFNpemU7Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIExleGVyIG9iamVjdC4KLSAgICoKLSAgICogQHBhcmFtIGNvbXBpbGVyIFRoZSBvd25pbmcgY29tcGlsZXIgZm9yIHRoaXMgbGV4ZXIuCi0gICAqIEBwYXJhbSByZXNvbHZlciBUaGUgcHJlZml4IHJlc29sdmVyIGZvciBtYXBwaW5nIHF1YWxpZmllZCBuYW1lIHByZWZpeGVzCi0gICAqICAgICAgICAgICAgICAgICB0byBuYW1lc3BhY2UgVVJJcy4KLSAgICogQHBhcmFtIHhwYXRoUHJvY2Vzc29yIFRoZSBwYXJzZXIgdGhhdCBpcyBwcm9jZXNzaW5nIHN0cmluZ3MgdG8gb3Bjb2Rlcy4KLSAgICovCi0gIExleGVyKENvbXBpbGVyIGNvbXBpbGVyLCBQcmVmaXhSZXNvbHZlciByZXNvbHZlciwKLSAgICAgICAgWFBhdGhQYXJzZXIgeHBhdGhQcm9jZXNzb3IpCi0gIHsKLQotICAgIG1fY29tcGlsZXIgPSBjb21waWxlcjsKLSAgICBtX25hbWVzcGFjZUNvbnRleHQgPSByZXNvbHZlcjsKLSAgICBtX3Byb2Nlc3NvciA9IHhwYXRoUHJvY2Vzc29yOwotICB9Ci0KLSAgLyoqCi0gICAqIFdhbGsgdGhyb3VnaCB0aGUgZXhwcmVzc2lvbiBhbmQgYnVpbGQgYSB0b2tlbiBxdWV1ZSwgYW5kIGEgbWFwIG9mIHRoZSB0b3AtbGV2ZWwKLSAgICogZWxlbWVudHMuCi0gICAqIEBwYXJhbSBwYXQgWFNMVCBFeHByZXNzaW9uLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHZvaWQgdG9rZW5pemUoU3RyaW5nIHBhdCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHRva2VuaXplKHBhdCwgbnVsbCk7Ci0gIH0KLQotICAvKioKLSAgICogV2FsayB0aHJvdWdoIHRoZSBleHByZXNzaW9uIGFuZCBidWlsZCBhIHRva2VuIHF1ZXVlLCBhbmQgYSBtYXAgb2YgdGhlIHRvcC1sZXZlbAotICAgKiBlbGVtZW50cy4KLSAgICogQHBhcmFtIHBhdCBYU0xUIEV4cHJlc3Npb24uCi0gICAqIEBwYXJhbSB0YXJnZXRTdHJpbmdzIFZlY3RvciB0byBob2xkIFN0cmluZ3MsIG1heSBiZSBudWxsLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHZvaWQgdG9rZW5pemUoU3RyaW5nIHBhdCwgVmVjdG9yIHRhcmdldFN0cmluZ3MpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgbV9jb21waWxlci5tX2N1cnJlbnRQYXR0ZXJuID0gcGF0OwotICAgIG1fcGF0dGVybk1hcFNpemUgPSAwOwotCi0gICAgLy8gVGhpcyBuZWVkcyB0byBncm93IHRvby4KLSAgICBtX2NvbXBpbGVyLm1fb3BNYXAgPSBuZXcgT3BNYXBWZWN0b3IoT3BNYXAuTUFYVE9LRU5RVUVVRVNJWkUgKiA1LCBPcE1hcC5CTE9DS1RPS0VOUVVFVUVTSVpFICogNSwgT3BNYXAuTUFQSU5ERVhfTEVOR1RIKTsKLQotICAgIGludCBuQ2hhcnMgPSBwYXQubGVuZ3RoKCk7Ci0gICAgaW50IHN0YXJ0U3Vic3RyaW5nID0gLTE7Ci0gICAgaW50IHBvc09mTlNTZXAgPSAtMTsKLSAgICBib29sZWFuIGlzU3RhcnRPZlBhdCA9IHRydWU7Ci0gICAgYm9vbGVhbiBpc0F0dHJOYW1lID0gZmFsc2U7Ci0gICAgYm9vbGVhbiBpc051bSA9IGZhbHNlOwotCi0gICAgLy8gTmVzdGluZyBvZiAnWycgc28gd2UgY2FuIGtub3cgaWYgdGhlIGdpdmVuIGVsZW1lbnQgc2hvdWxkIGJlCi0gICAgLy8gY291bnRlZCBpbnNpZGUgdGhlIG1fcGF0dGVybk1hcC4KLSAgICBpbnQgbmVzdGluZyA9IDA7Ci0KLSAgICAvLyBjaGFyW10gY2hhcnMgPSBwYXQudG9DaGFyQXJyYXkoKTsKLSAgICBmb3IgKGludCBpID0gMDsgaSA8IG5DaGFyczsgaSsrKQotICAgIHsKLSAgICAgIGNoYXIgYyA9IHBhdC5jaGFyQXQoaSk7Ci0KLSAgICAgIHN3aXRjaCAoYykKLSAgICAgIHsKLSAgICAgIGNhc2UgJ1wiJyA6Ci0gICAgICB7Ci0gICAgICAgIGlmIChzdGFydFN1YnN0cmluZyAhPSAtMSkKLSAgICAgICAgewotICAgICAgICAgIGlzTnVtID0gZmFsc2U7Ci0gICAgICAgICAgaXNTdGFydE9mUGF0ID0gbWFwUGF0dGVybkVsZW1Qb3MobmVzdGluZywgaXNTdGFydE9mUGF0LCBpc0F0dHJOYW1lKTsKLSAgICAgICAgICBpc0F0dHJOYW1lID0gZmFsc2U7Ci0KLSAgICAgICAgICBpZiAoLTEgIT0gcG9zT2ZOU1NlcCkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBwb3NPZk5TU2VwID0gbWFwTlNUb2tlbnMocGF0LCBzdGFydFN1YnN0cmluZywgcG9zT2ZOU1NlcCwgaSk7Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBhZGRUb1Rva2VuUXVldWUocGF0LnN1YnN0cmluZyhzdGFydFN1YnN0cmluZywgaSkpOwotICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHN0YXJ0U3Vic3RyaW5nID0gaTsKLQotICAgICAgICBmb3IgKGkrKzsgKGkgPCBuQ2hhcnMpICYmICgoYyA9IHBhdC5jaGFyQXQoaSkpICE9ICdcIicpOyBpKyspOwotCi0gICAgICAgIGlmIChjID09ICdcIicgJiYgaSA8IG5DaGFycykKLSAgICAgICAgewotICAgICAgICAgIGFkZFRvVG9rZW5RdWV1ZShwYXQuc3Vic3RyaW5nKHN0YXJ0U3Vic3RyaW5nLCBpICsgMSkpOwotCi0gICAgICAgICAgc3RhcnRTdWJzdHJpbmcgPSAtMTsKLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgIHsKLSAgICAgICAgICBtX3Byb2Nlc3Nvci5lcnJvcihYUEFUSEVycm9yUmVzb3VyY2VzLkVSX0VYUEVDVEVEX0RPVUJMRV9RVU9URSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsKTsgIC8vIm1pc3F1b3RlZCBsaXRlcmFsLi4uIGV4cGVjdGVkIGRvdWJsZSBxdW90ZSEiKTsKLSAgICAgICAgfQotICAgICAgfQotICAgICAgYnJlYWs7Ci0gICAgICBjYXNlICdcJycgOgotICAgICAgICBpZiAoc3RhcnRTdWJzdHJpbmcgIT0gLTEpCi0gICAgICAgIHsKLSAgICAgICAgICBpc051bSA9IGZhbHNlOwotICAgICAgICAgIGlzU3RhcnRPZlBhdCA9IG1hcFBhdHRlcm5FbGVtUG9zKG5lc3RpbmcsIGlzU3RhcnRPZlBhdCwgaXNBdHRyTmFtZSk7Ci0gICAgICAgICAgaXNBdHRyTmFtZSA9IGZhbHNlOwotCi0gICAgICAgICAgaWYgKC0xICE9IHBvc09mTlNTZXApCi0gICAgICAgICAgewotICAgICAgICAgICAgcG9zT2ZOU1NlcCA9IG1hcE5TVG9rZW5zKHBhdCwgc3RhcnRTdWJzdHJpbmcsIHBvc09mTlNTZXAsIGkpOwotICAgICAgICAgIH0KLSAgICAgICAgICBlbHNlCi0gICAgICAgICAgewotICAgICAgICAgICAgYWRkVG9Ub2tlblF1ZXVlKHBhdC5zdWJzdHJpbmcoc3RhcnRTdWJzdHJpbmcsIGkpKTsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBzdGFydFN1YnN0cmluZyA9IGk7Ci0KLSAgICAgICAgZm9yIChpKys7IChpIDwgbkNoYXJzKSAmJiAoKGMgPSBwYXQuY2hhckF0KGkpKSAhPSAnXCcnKTsgaSsrKTsKLQotICAgICAgICBpZiAoYyA9PSAnXCcnICYmIGkgPCBuQ2hhcnMpCi0gICAgICAgIHsKLSAgICAgICAgICBhZGRUb1Rva2VuUXVldWUocGF0LnN1YnN0cmluZyhzdGFydFN1YnN0cmluZywgaSArIDEpKTsKLQotICAgICAgICAgIHN0YXJ0U3Vic3RyaW5nID0gLTE7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICB7Ci0gICAgICAgICAgbV9wcm9jZXNzb3IuZXJyb3IoWFBBVEhFcnJvclJlc291cmNlcy5FUl9FWFBFQ1RFRF9TSU5HTEVfUVVPVEUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCk7ICAvLyJtaXNxdW90ZWQgbGl0ZXJhbC4uLiBleHBlY3RlZCBzaW5nbGUgcXVvdGUhIik7Ci0gICAgICAgIH0KLSAgICAgICAgYnJlYWs7Ci0gICAgICBjYXNlIDB4MEEgOgotICAgICAgY2FzZSAweDBEIDoKLSAgICAgIGNhc2UgJyAnIDoKLSAgICAgIGNhc2UgJ1x0JyA6Ci0gICAgICAgIGlmIChzdGFydFN1YnN0cmluZyAhPSAtMSkKLSAgICAgICAgewotICAgICAgICAgIGlzTnVtID0gZmFsc2U7Ci0gICAgICAgICAgaXNTdGFydE9mUGF0ID0gbWFwUGF0dGVybkVsZW1Qb3MobmVzdGluZywgaXNTdGFydE9mUGF0LCBpc0F0dHJOYW1lKTsKLSAgICAgICAgICBpc0F0dHJOYW1lID0gZmFsc2U7Ci0KLSAgICAgICAgICBpZiAoLTEgIT0gcG9zT2ZOU1NlcCkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBwb3NPZk5TU2VwID0gbWFwTlNUb2tlbnMocGF0LCBzdGFydFN1YnN0cmluZywgcG9zT2ZOU1NlcCwgaSk7Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBhZGRUb1Rva2VuUXVldWUocGF0LnN1YnN0cmluZyhzdGFydFN1YnN0cmluZywgaSkpOwotICAgICAgICAgIH0KLQotICAgICAgICAgIHN0YXJ0U3Vic3RyaW5nID0gLTE7Ci0gICAgICAgIH0KLSAgICAgICAgYnJlYWs7Ci0gICAgICBjYXNlICdAJyA6Ci0gICAgICAgIGlzQXR0ck5hbWUgPSB0cnVlOwotCi0gICAgICAvLyBmYWxsLXRocm91Z2ggb24gcHVycG9zZQotICAgICAgY2FzZSAnLScgOgotICAgICAgICBpZiAoJy0nID09IGMpCi0gICAgICAgIHsKLSAgICAgICAgICBpZiAoIShpc051bSB8fCAoc3RhcnRTdWJzdHJpbmcgPT0gLTEpKSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgICB9Ci0KLSAgICAgICAgICBpc051bSA9IGZhbHNlOwotICAgICAgICB9Ci0KLSAgICAgIC8vIGZhbGwtdGhyb3VnaCBvbiBwdXJwb3NlCi0gICAgICBjYXNlICcoJyA6Ci0gICAgICBjYXNlICdbJyA6Ci0gICAgICBjYXNlICcpJyA6Ci0gICAgICBjYXNlICddJyA6Ci0gICAgICBjYXNlICd8JyA6Ci0gICAgICBjYXNlICcvJyA6Ci0gICAgICBjYXNlICcqJyA6Ci0gICAgICBjYXNlICcrJyA6Ci0gICAgICBjYXNlICc9JyA6Ci0gICAgICBjYXNlICcsJyA6Ci0gICAgICBjYXNlICdcXCcgOiAgLy8gVW51c2VkIGF0IHRoZSBtb21lbnQKLSAgICAgIGNhc2UgJ14nIDogIC8vIFVudXNlZCBhdCB0aGUgbW9tZW50Ci0gICAgICBjYXNlICchJyA6ICAvLyBVbnVzZWQgYXQgdGhlIG1vbWVudAotICAgICAgY2FzZSAnJCcgOgotICAgICAgY2FzZSAnPCcgOgotICAgICAgY2FzZSAnPicgOgotICAgICAgICBpZiAoc3RhcnRTdWJzdHJpbmcgIT0gLTEpCi0gICAgICAgIHsKLSAgICAgICAgICBpc051bSA9IGZhbHNlOwotICAgICAgICAgIGlzU3RhcnRPZlBhdCA9IG1hcFBhdHRlcm5FbGVtUG9zKG5lc3RpbmcsIGlzU3RhcnRPZlBhdCwgaXNBdHRyTmFtZSk7Ci0gICAgICAgICAgaXNBdHRyTmFtZSA9IGZhbHNlOwotCi0gICAgICAgICAgaWYgKC0xICE9IHBvc09mTlNTZXApCi0gICAgICAgICAgewotICAgICAgICAgICAgcG9zT2ZOU1NlcCA9IG1hcE5TVG9rZW5zKHBhdCwgc3RhcnRTdWJzdHJpbmcsIHBvc09mTlNTZXAsIGkpOwotICAgICAgICAgIH0KLSAgICAgICAgICBlbHNlCi0gICAgICAgICAgewotICAgICAgICAgICAgYWRkVG9Ub2tlblF1ZXVlKHBhdC5zdWJzdHJpbmcoc3RhcnRTdWJzdHJpbmcsIGkpKTsKLSAgICAgICAgICB9Ci0KLSAgICAgICAgICBzdGFydFN1YnN0cmluZyA9IC0xOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKCgnLycgPT0gYykgJiYgaXNTdGFydE9mUGF0KQotICAgICAgICB7Ci0gICAgICAgICAgaXNTdGFydE9mUGF0ID0gbWFwUGF0dGVybkVsZW1Qb3MobmVzdGluZywgaXNTdGFydE9mUGF0LCBpc0F0dHJOYW1lKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICgnKicgPT0gYykKLSAgICAgICAgewotICAgICAgICAgIGlzU3RhcnRPZlBhdCA9IG1hcFBhdHRlcm5FbGVtUG9zKG5lc3RpbmcsIGlzU3RhcnRPZlBhdCwgaXNBdHRyTmFtZSk7Ci0gICAgICAgICAgaXNBdHRyTmFtZSA9IGZhbHNlOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKDAgPT0gbmVzdGluZykKLSAgICAgICAgewotICAgICAgICAgIGlmICgnfCcgPT0gYykKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBpZiAobnVsbCAhPSB0YXJnZXRTdHJpbmdzKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICByZWNvcmRUb2tlblN0cmluZyh0YXJnZXRTdHJpbmdzKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaXNTdGFydE9mUGF0ID0gdHJ1ZTsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoKCcpJyA9PSBjKSB8fCAoJ10nID09IGMpKQotICAgICAgICB7Ci0gICAgICAgICAgbmVzdGluZy0tOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKCgnKCcgPT0gYykgfHwgKCdbJyA9PSBjKSkKLSAgICAgICAgewotICAgICAgICAgIG5lc3RpbmcrKzsKLSAgICAgICAgfQotCi0gICAgICAgIGFkZFRvVG9rZW5RdWV1ZShwYXQuc3Vic3RyaW5nKGksIGkgKyAxKSk7Ci0gICAgICAgIGJyZWFrOwotICAgICAgY2FzZSAnOicgOgotICAgICAgICBpZiAoaT4wKQotICAgICAgICB7Ci0gICAgICAgICAgaWYgKHBvc09mTlNTZXAgPT0gKGkgLSAxKSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBpZiAoc3RhcnRTdWJzdHJpbmcgIT0gLTEpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIGlmIChzdGFydFN1YnN0cmluZyA8IChpIC0gMSkpCi0gICAgICAgICAgICAgICAgYWRkVG9Ub2tlblF1ZXVlKHBhdC5zdWJzdHJpbmcoc3RhcnRTdWJzdHJpbmcsIGkgLSAxKSk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlzTnVtID0gZmFsc2U7Ci0gICAgICAgICAgICBpc0F0dHJOYW1lID0gZmFsc2U7Ci0gICAgICAgICAgICBzdGFydFN1YnN0cmluZyA9IC0xOwotICAgICAgICAgICAgcG9zT2ZOU1NlcCA9IC0xOwotCi0gICAgICAgICAgICBhZGRUb1Rva2VuUXVldWUocGF0LnN1YnN0cmluZyhpIC0gMSwgaSArIDEpKTsKLQotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBwb3NPZk5TU2VwID0gaTsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgLy8gZmFsbCB0aHJvdWdoIG9uIHB1cnBvc2UKLSAgICAgIGRlZmF1bHQgOgotICAgICAgICBpZiAoLTEgPT0gc3RhcnRTdWJzdHJpbmcpCi0gICAgICAgIHsKLSAgICAgICAgICBzdGFydFN1YnN0cmluZyA9IGk7Ci0gICAgICAgICAgaXNOdW0gPSBDaGFyYWN0ZXIuaXNEaWdpdChjKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChpc051bSkKLSAgICAgICAgewotICAgICAgICAgIGlzTnVtID0gQ2hhcmFjdGVyLmlzRGlnaXQoYyk7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICB9Ci0KLSAgICBpZiAoc3RhcnRTdWJzdHJpbmcgIT0gLTEpCi0gICAgewotICAgICAgaXNOdW0gPSBmYWxzZTsKLSAgICAgIGlzU3RhcnRPZlBhdCA9IG1hcFBhdHRlcm5FbGVtUG9zKG5lc3RpbmcsIGlzU3RhcnRPZlBhdCwgaXNBdHRyTmFtZSk7Ci0KLSAgICAgIGlmICgoLTEgIT0gcG9zT2ZOU1NlcCkgfHwKLSAgICAgICAgICgobV9uYW1lc3BhY2VDb250ZXh0ICE9IG51bGwpICYmIChtX25hbWVzcGFjZUNvbnRleHQuaGFuZGxlc051bGxQcmVmaXhlcygpKSkpCi0gICAgICB7Ci0gICAgICAgIHBvc09mTlNTZXAgPSBtYXBOU1Rva2VucyhwYXQsIHN0YXJ0U3Vic3RyaW5nLCBwb3NPZk5TU2VwLCBuQ2hhcnMpOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBhZGRUb1Rva2VuUXVldWUocGF0LnN1YnN0cmluZyhzdGFydFN1YnN0cmluZywgbkNoYXJzKSk7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgaWYgKDAgPT0gbV9jb21waWxlci5nZXRUb2tlblF1ZXVlU2l6ZSgpKQotICAgIHsKLSAgICAgIG1fcHJvY2Vzc29yLmVycm9yKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfRU1QVFlfRVhQUkVTU0lPTiwgbnVsbCk7ICAvLyJFbXB0eSBleHByZXNzaW9uISIpOwotICAgIH0KLSAgICBlbHNlIGlmIChudWxsICE9IHRhcmdldFN0cmluZ3MpCi0gICAgewotICAgICAgcmVjb3JkVG9rZW5TdHJpbmcodGFyZ2V0U3RyaW5ncyk7Ci0gICAgfQotCi0gICAgbV9wcm9jZXNzb3IubV9xdWV1ZU1hcmsgPSAwOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlY29yZCB0aGUgY3VycmVudCBwb3NpdGlvbiBvbiB0aGUgdG9rZW4gcXVldWUgYXMgbG9uZyBhcwotICAgKiB0aGlzIGlzIGEgdG9wLWxldmVsIGVsZW1lbnQuICBNdXN0IGJlIGNhbGxlZCBiZWZvcmUgdGhlCi0gICAqIG5leHQgdG9rZW4gaXMgYWRkZWQgdG8gdGhlIG1fdG9rZW5RdWV1ZS4KLSAgICoKLSAgICogQHBhcmFtIG5lc3RpbmcgVGhlIG5lc3RpbmcgY291bnQgZm9yIHRoZSBwYXR0ZXJuIGVsZW1lbnQuCi0gICAqIEBwYXJhbSBpc1N0YXJ0IHRydWUgaWYgdGhpcyBpcyB0aGUgc3RhcnQgb2YgYSBwYXR0ZXJuLgotICAgKiBAcGFyYW0gaXNBdHRyTmFtZSB0cnVlIGlmIHdlIGhhdmUgZGV0ZXJtaW5lZCB0aGF0IHRoaXMgaXMgYW4gYXR0cmlidXRlIG5hbWUuCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGlzIGlzIHRoZSBzdGFydCBvZiBhIHBhdHRlcm4uCi0gICAqLwotICBwcml2YXRlIGJvb2xlYW4gbWFwUGF0dGVybkVsZW1Qb3MoaW50IG5lc3RpbmcsIGJvb2xlYW4gaXNTdGFydCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gaXNBdHRyTmFtZSkKLSAgewotCi0gICAgaWYgKDAgPT0gbmVzdGluZykKLSAgICB7Ci0gICAgICBpZihtX3BhdHRlcm5NYXBTaXplID49IG1fcGF0dGVybk1hcC5sZW5ndGgpCi0gICAgICB7Ci0gICAgICAgIGludCBwYXR0ZXJuTWFwW10gPSBtX3BhdHRlcm5NYXA7Ci0gICAgICAgIGludCBsZW4gPSBtX3BhdHRlcm5NYXAubGVuZ3RoOwotICAgICAgICBtX3BhdHRlcm5NYXAgPSBuZXcgaW50W21fcGF0dGVybk1hcFNpemUgKyAxMDBdOwotICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHBhdHRlcm5NYXAsIDAsIG1fcGF0dGVybk1hcCwgMCwgbGVuKTsKLSAgICAgIH0KLSAgICAgIGlmICghaXNTdGFydCkKLSAgICAgIHsKLSAgICAgICAgbV9wYXR0ZXJuTWFwW21fcGF0dGVybk1hcFNpemUgLSAxXSAtPSBUQVJHRVRFWFRSQTsKLSAgICAgIH0KLSAgICAgIG1fcGF0dGVybk1hcFttX3BhdHRlcm5NYXBTaXplXSA9Ci0gICAgICAgIChtX2NvbXBpbGVyLmdldFRva2VuUXVldWVTaXplKCkgLSAoaXNBdHRyTmFtZSA/IDEgOiAwKSkgKyBUQVJHRVRFWFRSQTsKLQotICAgICAgbV9wYXR0ZXJuTWFwU2l6ZSsrOwotCi0gICAgICBpc1N0YXJ0ID0gZmFsc2U7Ci0gICAgfQotCi0gICAgcmV0dXJuIGlzU3RhcnQ7Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYSBtYXAgcG9zLCByZXR1cm4gdGhlIGNvcnJlc3BvbmRpbmcgdG9rZW4gcXVldWUgcG9zLgotICAgKgotICAgKiBAcGFyYW0gaSBUaGUgaW5kZXggaW4gdGhlIG1fcGF0dGVybk1hcC4KLSAgICoKLSAgICogQHJldHVybiB0aGUgdG9rZW4gcXVldWUgcG9zaXRpb24uCi0gICAqLwotICBwcml2YXRlIGludCBnZXRUb2tlblF1ZXVlUG9zRnJvbU1hcChpbnQgaSkKLSAgewotCi0gICAgaW50IHBvcyA9IG1fcGF0dGVybk1hcFtpXTsKLQotICAgIHJldHVybiAocG9zID49IFRBUkdFVEVYVFJBKSA/IChwb3MgLSBUQVJHRVRFWFRSQSkgOiBwb3M7Ci0gIH0KLQotICAvKioKLSAgICogUmVzZXQgdG9rZW4gcXVldWUgbWFyayBhbmQgbV90b2tlbiB0byBhCi0gICAqIGdpdmVuIHBvc2l0aW9uLgotICAgKiBAcGFyYW0gbWFyayBUaGUgbmV3IHBvc2l0aW9uLgotICAgKi8KLSAgcHJpdmF0ZSBmaW5hbCB2b2lkIHJlc2V0VG9rZW5NYXJrKGludCBtYXJrKQotICB7Ci0KLSAgICBpbnQgcXN6ID0gbV9jb21waWxlci5nZXRUb2tlblF1ZXVlU2l6ZSgpOwotCi0gICAgbV9wcm9jZXNzb3IubV9xdWV1ZU1hcmsgPSAobWFyayA+IDApCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/ICgobWFyayA8PSBxc3opID8gbWFyayAtIDEgOiBtYXJrKSA6IDA7Ci0KLSAgICBpZiAobV9wcm9jZXNzb3IubV9xdWV1ZU1hcmsgPCBxc3opCi0gICAgewotICAgICAgbV9wcm9jZXNzb3IubV90b2tlbiA9Ci0gICAgICAgIChTdHJpbmcpIG1fY29tcGlsZXIuZ2V0VG9rZW5RdWV1ZSgpLmVsZW1lbnRBdChtX3Byb2Nlc3Nvci5tX3F1ZXVlTWFyaysrKTsKLSAgICAgIG1fcHJvY2Vzc29yLm1fdG9rZW5DaGFyID0gbV9wcm9jZXNzb3IubV90b2tlbi5jaGFyQXQoMCk7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBtX3Byb2Nlc3Nvci5tX3Rva2VuID0gbnVsbDsKLSAgICAgIG1fcHJvY2Vzc29yLm1fdG9rZW5DaGFyID0gMDsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYSBzdHJpbmcsIHJldHVybiB0aGUgY29ycmVzcG9uZGluZyBrZXl3b3JkIHRva2VuLgotICAgKgotICAgKiBAcGFyYW0ga2V5IFRoZSBrZXl3b3JkLgotICAgKgotICAgKiBAcmV0dXJuIEFuIG9wY29kZSB2YWx1ZS4KLSAgICovCi0gIGZpbmFsIGludCBnZXRLZXl3b3JkVG9rZW4oU3RyaW5nIGtleSkKLSAgewotCi0gICAgaW50IHRvazsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIEludGVnZXIgaXRvayA9IChJbnRlZ2VyKSBLZXl3b3Jkcy5nZXRLZXlXb3JkKGtleSk7Ci0KLSAgICAgIHRvayA9IChudWxsICE9IGl0b2spID8gaXRvay5pbnRWYWx1ZSgpIDogMDsKLSAgICB9Ci0gICAgY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIG5wZSkKLSAgICB7Ci0gICAgICB0b2sgPSAwOwotICAgIH0KLSAgICBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGNjZSkKLSAgICB7Ci0gICAgICB0b2sgPSAwOwotICAgIH0KLQotICAgIHJldHVybiB0b2s7Ci0gIH0KLQotICAvKioKLSAgICogUmVjb3JkIHRoZSBjdXJyZW50IHRva2VuIGluIHRoZSBwYXNzZWQgdmVjdG9yLgotICAgKgotICAgKiBAcGFyYW0gdGFyZ2V0U3RyaW5ncyBWZWN0b3Igb2Ygc3RyaW5nLgotICAgKi8KLSAgcHJpdmF0ZSB2b2lkIHJlY29yZFRva2VuU3RyaW5nKFZlY3RvciB0YXJnZXRTdHJpbmdzKQotICB7Ci0KLSAgICBpbnQgdG9rUG9zID0gZ2V0VG9rZW5RdWV1ZVBvc0Zyb21NYXAobV9wYXR0ZXJuTWFwU2l6ZSAtIDEpOwotCi0gICAgcmVzZXRUb2tlbk1hcmsodG9rUG9zICsgMSk7Ci0KLSAgICBpZiAobV9wcm9jZXNzb3IubG9va2FoZWFkKCcoJywgMSkpCi0gICAgewotICAgICAgaW50IHRvayA9IGdldEtleXdvcmRUb2tlbihtX3Byb2Nlc3Nvci5tX3Rva2VuKTsKLQotICAgICAgc3dpdGNoICh0b2spCi0gICAgICB7Ci0gICAgICBjYXNlIE9wQ29kZXMuTk9ERVRZUEVfQ09NTUVOVCA6Ci0gICAgICAgIHRhcmdldFN0cmluZ3MuYWRkRWxlbWVudChQc3VlZG9OYW1lcy5QU0VVRE9OQU1FX0NPTU1FTlQpOwotICAgICAgICBicmVhazsKLSAgICAgIGNhc2UgT3BDb2Rlcy5OT0RFVFlQRV9URVhUIDoKLSAgICAgICAgdGFyZ2V0U3RyaW5ncy5hZGRFbGVtZW50KFBzdWVkb05hbWVzLlBTRVVET05BTUVfVEVYVCk7Ci0gICAgICAgIGJyZWFrOwotICAgICAgY2FzZSBPcENvZGVzLk5PREVUWVBFX05PREUgOgotICAgICAgICB0YXJnZXRTdHJpbmdzLmFkZEVsZW1lbnQoUHN1ZWRvTmFtZXMuUFNFVURPTkFNRV9BTlkpOwotICAgICAgICBicmVhazsKLSAgICAgIGNhc2UgT3BDb2Rlcy5OT0RFVFlQRV9ST09UIDoKLSAgICAgICAgdGFyZ2V0U3RyaW5ncy5hZGRFbGVtZW50KFBzdWVkb05hbWVzLlBTRVVET05BTUVfUk9PVCk7Ci0gICAgICAgIGJyZWFrOwotICAgICAgY2FzZSBPcENvZGVzLk5PREVUWVBFX0FOWUVMRU1FTlQgOgotICAgICAgICB0YXJnZXRTdHJpbmdzLmFkZEVsZW1lbnQoUHN1ZWRvTmFtZXMuUFNFVURPTkFNRV9BTlkpOwotICAgICAgICBicmVhazsKLSAgICAgIGNhc2UgT3BDb2Rlcy5OT0RFVFlQRV9QSSA6Ci0gICAgICAgIHRhcmdldFN0cmluZ3MuYWRkRWxlbWVudChQc3VlZG9OYW1lcy5QU0VVRE9OQU1FX0FOWSk7Ci0gICAgICAgIGJyZWFrOwotICAgICAgZGVmYXVsdCA6Ci0gICAgICAgIHRhcmdldFN0cmluZ3MuYWRkRWxlbWVudChQc3VlZG9OYW1lcy5QU0VVRE9OQU1FX0FOWSk7Ci0gICAgICB9Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBpZiAobV9wcm9jZXNzb3IudG9rZW5JcygnQCcpKQotICAgICAgewotICAgICAgICB0b2tQb3MrKzsKLQotICAgICAgICByZXNldFRva2VuTWFyayh0b2tQb3MgKyAxKTsKLSAgICAgIH0KLQotICAgICAgaWYgKG1fcHJvY2Vzc29yLmxvb2thaGVhZCgnOicsIDEpKQotICAgICAgewotICAgICAgICB0b2tQb3MgKz0gMjsKLSAgICAgIH0KLQotICAgICAgdGFyZ2V0U3RyaW5ncy5hZGRFbGVtZW50KG1fY29tcGlsZXIuZ2V0VG9rZW5RdWV1ZSgpLmVsZW1lbnRBdCh0b2tQb3MpKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogQWRkIGEgdG9rZW4gdG8gdGhlIHRva2VuIHF1ZXVlLgotICAgKgotICAgKgotICAgKiBAcGFyYW0gcyBUaGUgdG9rZW4uCi0gICAqLwotICBwcml2YXRlIGZpbmFsIHZvaWQgYWRkVG9Ub2tlblF1ZXVlKFN0cmluZyBzKQotICB7Ci0gICAgbV9jb21waWxlci5nZXRUb2tlblF1ZXVlKCkuYWRkRWxlbWVudChzKTsKLSAgfQotCi0gIC8qKgotICAgKiBXaGVuIGEgc2VwZXJhdG9yIHRva2VuIGlzIGZvdW5kLCBzZWUgaWYgdGhlcmUncyBhIGVsZW1lbnQgbmFtZSBvcgotICAgKiB0aGUgbGlrZSB0byBtYXAuCi0gICAqCi0gICAqIEBwYXJhbSBwYXQgVGhlIFhQYXRoIG5hbWUgc3RyaW5nLgotICAgKiBAcGFyYW0gc3RhcnRTdWJzdHJpbmcgVGhlIHN0YXJ0IG9mIHRoZSBuYW1lIHN0cmluZy4KLSAgICogQHBhcmFtIHBvc09mTlNTZXAgVGhlIHBvc2l0aW9uIG9mIHRoZSBuYW1lc3BhY2Ugc2VwZXJhdG9yICgnOicpLgotICAgKiBAcGFyYW0gcG9zT2ZTY2FuIFRoZSBlbmQgb2YgdGhlIG5hbWUgaW5kZXguCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKgotICAgKiBAcmV0dXJuIC0xIGFsd2F5cy4KLSAgICovCi0gIHByaXZhdGUgaW50IG1hcE5TVG9rZW5zKFN0cmluZyBwYXQsIGludCBzdGFydFN1YnN0cmluZywgaW50IHBvc09mTlNTZXAsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIGludCBwb3NPZlNjYW4pCi0gICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gewotCi0gICAgU3RyaW5nIHByZWZpeCA9ICIiOwotCi0gICAgaWYgKChzdGFydFN1YnN0cmluZyA+PSAwKSAmJiAocG9zT2ZOU1NlcCA+PSAwKSkKLSAgICB7Ci0gICAgICAgcHJlZml4ID0gcGF0LnN1YnN0cmluZyhzdGFydFN1YnN0cmluZywgcG9zT2ZOU1NlcCk7Ci0gICAgfQotICAgIFN0cmluZyB1TmFtZTsKLQotICAgIGlmICgobnVsbCAhPSBtX25hbWVzcGFjZUNvbnRleHQpICYmIXByZWZpeC5lcXVhbHMoIioiKQotICAgICAgICAgICAgJiYhcHJlZml4LmVxdWFscygieG1sbnMiKSkKLSAgICB7Ci0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgaWYgKHByZWZpeC5sZW5ndGgoKSA+IDApCi0gICAgICAgICAgdU5hbWUgPSAoKFByZWZpeFJlc29sdmVyKSBtX25hbWVzcGFjZUNvbnRleHQpLmdldE5hbWVzcGFjZUZvclByZWZpeCgKLSAgICAgICAgICAgIHByZWZpeCk7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotCi0gICAgICAgICAgLy8gQXNzdW1lIGxhc3Qgd2FzIHdpbGRjYXJkLiBUaGlzIGlzIG5vdCBsZWdhbCBhY2NvcmRpbmcKLSAgICAgICAgICAvLyB0byB0aGUgZHJhZnQuIFNldCB0aGUgYmVsb3cgdG8gdHJ1ZSB0byBtYWtlIG5hbWVzcGFjZQotICAgICAgICAgIC8vIHdpbGRjYXJkcyB3b3JrLgotICAgICAgICAgIGlmIChmYWxzZSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBhZGRUb1Rva2VuUXVldWUoIjoiKTsKLQotICAgICAgICAgICAgU3RyaW5nIHMgPSBwYXQuc3Vic3RyaW5nKHBvc09mTlNTZXAgKyAxLCBwb3NPZlNjYW4pOwotCi0gICAgICAgICAgICBpZiAocy5sZW5ndGgoKSA+IDApCi0gICAgICAgICAgICAgIGFkZFRvVG9rZW5RdWV1ZShzKTsKLQotICAgICAgICAgICAgcmV0dXJuIC0xOwotICAgICAgICAgIH0KLSAgICAgICAgICBlbHNlCi0gICAgICAgICAgewotICAgICAgICAgICAgdU5hbWUgPQotICAgICAgICAgICAgICAoKFByZWZpeFJlc29sdmVyKSBtX25hbWVzcGFjZUNvbnRleHQpLmdldE5hbWVzcGFjZUZvclByZWZpeCgKLSAgICAgICAgICAgICAgICBwcmVmaXgpOwotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgfQotICAgICAgY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBjY2UpCi0gICAgICB7Ci0gICAgICAgIHVOYW1lID0gbV9uYW1lc3BhY2VDb250ZXh0LmdldE5hbWVzcGFjZUZvclByZWZpeChwcmVmaXgpOwotICAgICAgfQotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgdU5hbWUgPSBwcmVmaXg7Ci0gICAgfQotCi0gICAgaWYgKChudWxsICE9IHVOYW1lKSAmJiAodU5hbWUubGVuZ3RoKCkgPiAwKSkKLSAgICB7Ci0gICAgICBhZGRUb1Rva2VuUXVldWUodU5hbWUpOwotICAgICAgYWRkVG9Ub2tlblF1ZXVlKCI6Iik7Ci0KLSAgICAgIFN0cmluZyBzID0gcGF0LnN1YnN0cmluZyhwb3NPZk5TU2VwICsgMSwgcG9zT2ZTY2FuKTsKLQotICAgICAgaWYgKHMubGVuZ3RoKCkgPiAwKQotICAgICAgICBhZGRUb1Rva2VuUXVldWUocyk7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICAgIC8vIFRvIG9sZGVyIFhQYXRoIGNvZGUgaXQgZG9lc24ndCBtYXR0ZXIgaWYKLSAgICAgICAgLy8gZXJyb3IoKSBpcyBjYWxsZWQgb3IgZXJyb3JGb3JET00zKCkuCi0gICAgICAgICAgICAgICAgbV9wcm9jZXNzb3IuZXJyb3JGb3JET00zKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfUFJFRklYX01VU1RfUkVTT0xWRSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgU3RyaW5nW10ge3ByZWZpeH0pOyAgLy8iUHJlZml4IG11c3QgcmVzb2x2ZSB0byBhIG5hbWVzcGFjZTogezB9IjsKLQotLyoqIG9sZCBjb2RlIGNvbW1lbnRlZCBvdXQgMTctU2VwLTIwMDQKLS8vIGVycm9yKCJDb3VsZCBub3QgbG9jYXRlIG5hbWVzcGFjZSBmb3IgcHJlZml4OiAiK3ByZWZpeCk7Ci0vLyAgICAgICAgICAgICAgICBtX3Byb2Nlc3Nvci5lcnJvcihYUEFUSEVycm9yUmVzb3VyY2VzLkVSX1BSRUZJWF9NVVNUX1JFU09MVkUsCi0vLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7cHJlZml4fSk7ICAvLyJQcmVmaXggbXVzdCByZXNvbHZlIHRvIGEgbmFtZXNwYWNlOiB7MH0iOwotKi8KLQotICAgICAgLyoqKiAgT2xkIGNvZGUgY29tbWVudGVkIG91dCAxMC1KYW4tMjAwMQotICAgICAgYWRkVG9Ub2tlblF1ZXVlKHByZWZpeCk7Ci0gICAgICBhZGRUb1Rva2VuUXVldWUoIjoiKTsKLQotICAgICAgU3RyaW5nIHMgPSBwYXQuc3Vic3RyaW5nKHBvc09mTlNTZXAgKyAxLCBwb3NPZlNjYW4pOwotCi0gICAgICBpZiAocy5sZW5ndGgoKSA+IDApCi0gICAgICAgIGFkZFRvVG9rZW5RdWV1ZShzKTsKLSAgICAgICoqKi8KLSAgICB9Ci0KLSAgICByZXR1cm4gLTE7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvY29tcGlsZXIvT3BDb2Rlcy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9jb21waWxlci9PcENvZGVzLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDEzODRjMmEuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9jb21waWxlci9PcENvZGVzLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw2MzQgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogT3BDb2Rlcy5qYXZhLHYgMS4xLjIuMSAyMDA1LzA4LzAxIDAxOjMwOjMzIGplZmZzdXR0b3IgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuY29tcGlsZXI7Ci0KLS8qKgotICogT3BlcmF0aW9ucyBjb2RlcyBmb3IgWFBhdGguCi0gKgotICogQ29kZSBmb3IgdGhlIGRlc2NyaXB0aW9ucyBvZiB0aGUgb3BlcmF0aW9ucyBjb2RlczoKLSAqIFtVUFBFUiBDQVNFXSBpbmRpY2F0ZXMgYSBsaXRlcmFsIHZhbHVlLAotICogW2xvd2VyIGNhc2VdIGlzIGEgZGVzY3JpcHRpb24gb2YgYSB2YWx1ZSwKLSAqICAgICAgKFtsZW5ndGhdIGFsd2F5cyBpbmRpY2F0ZXMgdGhlIGxlbmd0aCBvZiB0aGUgb3BlcmF0aW9uLAotICogICAgICAgaW5jbHVkaW5nIHRoZSBvcGVyYXRpb25zIGNvZGUgYW5kIHRoZSBsZW5ndGggaW50ZWdlci4pCi0gKiB7VVBQRVIgQ0FTRX0gaW5kaWNhdGVzIHRoZSBnaXZlbiBwcm9kdWN0aW9uLAotICoge2Rlc2NyaXB0aW9ufSBpcyB0aGUgZGVzY3JpcHRpb24gb2YgYSBuZXcgcHJvZHVjdGlvbiwKLSAqICAgICAgKEZvciBpbnN0YW5jZSwge2Jvb2xlYW4gZXhwcmVzc2lvbn0gbWVhbnMgc29tZSBleHByZXNzaW9uCi0gKiAgICAgICB0aGF0IHNob3VsZCBiZSByZXNvbHZlZCB0byBhIGJvb2xlYW4uKQotICogICogbWVhbnMgdGhhdCBpdCBvY2N1cnMgemVybyBvciBtb3JlIHRpbWVzLAotICogICsgbWVhbnMgdGhhdCBpdCBvY2N1cnMgb25lIG9yIG1vcmUgdGltZXMsCi0gKiAgPyBtZWFucyB0aGF0IGl0IGlzIG9wdGlvbmFsLgotICoKLSAqIHJldHVybnM6IGluZGljYXRlcyB3aGF0IHRoZSBwcm9kdWN0aW9uIHNob3VsZCByZXR1cm4uCi0gKi8KLXB1YmxpYyBjbGFzcyBPcENvZGVzCi17Ci0KLSAgLyoqCi0gICAqIFtFTkRPUF0KLSAgICogU29tZSBvcGVyYXRvcnMgbWF5IGxpa2UgdG8gaGF2ZSBhIHRlcm1pbmF0b3IuCi0gICAqIEB4c2wudXNhZ2UgYWR2YW5jZWQKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVORE9QID0gLTE7Ci0KLSAgLyoqCi0gICAqIFtFTVBUWV0KLSAgICogRW1wdHkgc2xvdCB0byBpbmRpY2F0ZSBOVUxMLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU1QVFkgPSAtMjsKLQotICAvKioKLSAgICogW0VMRU1XSUxEQ0FSRF0KLSAgICogTWVhbnMgRUxFTVdJTERDQVJEICgiKiIpLCB1c2VkIGluc3RlYWQKLSAgICogb2Ygc3RyaW5nIGluZGV4IGluIHNvbWUgcGxhY2VzLgotICAgKiBAeHNsLnVzYWdlIGFkdmFuY2VkCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTEVNV0lMRENBUkQgPSAtMzsKLQotICAvKioKLSAgICogW09QX1hQQVRIXQotICAgKiBbbGVuZ3RoXQotICAgKiAge2V4cHJlc3Npb259Ci0gICAqCi0gICAqIHJldHVybnM6Ci0gICAqICBYTm9kZVNldAotICAgKiAgWE51bWJlcgotICAgKiAgWFN0cmluZwotICAgKiAgWEJvb2xlYW4KLSAgICogIFhSVHJlZQotICAgKiAgWE9iamVjdAotICAgKiBAeHNsLnVzYWdlIGFkdmFuY2VkCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUF9YUEFUSCA9IDE7Ci0KLSAgLyoqCi0gICAqIFtPUF9PUl0KLSAgICogW2xlbmd0aF0KLSAgICogIHtib29sZWFuIGV4cHJlc3Npb259Ci0gICAqICB7Ym9vbGVhbiBleHByZXNzaW9ufQotICAgKgotICAgKiByZXR1cm5zOgotICAgKiAgWEJvb2xlYW4KLSAgICogQHhzbC51c2FnZSBhZHZhbmNlZAotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BfT1IgPSAyOwotCi0gIC8qKgotICAgKiBbT1BfQU5EXQotICAgKiBbbGVuZ3RoXQotICAgKiAge2Jvb2xlYW4gZXhwcmVzc2lvbn0KLSAgICogIHtib29sZWFuIGV4cHJlc3Npb259Ci0gICAqCi0gICAqIHJldHVybnM6Ci0gICAqICBYQm9vbGVhbgotICAgKiBAeHNsLnVzYWdlIGFkdmFuY2VkCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUF9BTkQgPSAzOwotCi0gIC8qKgotICAgKiBbT1BfTk9URVFVQUxTXQotICAgKiBbbGVuZ3RoXQotICAgKiAge2V4cHJlc3Npb259Ci0gICAqICB7ZXhwcmVzc2lvbn0KLSAgICoKLSAgICogcmV0dXJuczoKLSAgICogIFhCb29sZWFuCi0gICAqIEB4c2wudXNhZ2UgYWR2YW5jZWQKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QX05PVEVRVUFMUyA9IDQ7Ci0KLSAgLyoqCi0gICAqIFtPUF9FUVVBTFNdCi0gICAqIFtsZW5ndGhdCi0gICAqICB7ZXhwcmVzc2lvbn0KLSAgICogIHtleHByZXNzaW9ufQotICAgKgotICAgKiByZXR1cm5zOgotICAgKiAgWEJvb2xlYW4KLSAgICogQHhzbC51c2FnZSBhZHZhbmNlZAotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BfRVFVQUxTID0gNTsKLQotICAvKioKLSAgICogW09QX0xURV0gKGxlc3MtdGhhbi1vci1lcXVhbHMpCi0gICAqIFtsZW5ndGhdCi0gICAqICB7bnVtYmVyIGV4cHJlc3Npb259Ci0gICAqICB7bnVtYmVyIGV4cHJlc3Npb259Ci0gICAqCi0gICAqIHJldHVybnM6Ci0gICAqICBYQm9vbGVhbgotICAgKiBAeHNsLnVzYWdlIGFkdmFuY2VkCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUF9MVEUgPSA2OwotCi0gIC8qKgotICAgKiBbT1BfTFRdIChsZXNzLXRoYW4pCi0gICAqIFtsZW5ndGhdCi0gICAqICB7bnVtYmVyIGV4cHJlc3Npb259Ci0gICAqICB7bnVtYmVyIGV4cHJlc3Npb259Ci0gICAqCi0gICAqIHJldHVybnM6Ci0gICAqICBYQm9vbGVhbgotICAgKiBAeHNsLnVzYWdlIGFkdmFuY2VkCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUF9MVCA9IDc7Ci0KLSAgLyoqCi0gICAqIFtPUF9HVEVdIChncmVhdGVyLXRoYW4tb3ItZXF1YWxzKQotICAgKiBbbGVuZ3RoXQotICAgKiAge251bWJlciBleHByZXNzaW9ufQotICAgKiAge251bWJlciBleHByZXNzaW9ufQotICAgKgotICAgKiByZXR1cm5zOgotICAgKiAgWEJvb2xlYW4KLSAgICogQHhzbC51c2FnZSBhZHZhbmNlZAotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BfR1RFID0gODsKLQotICAvKioKLSAgICogW09QX0dUXSAoZ3JlYXRlci10aGFuKQotICAgKiBbbGVuZ3RoXQotICAgKiAge251bWJlciBleHByZXNzaW9ufQotICAgKiAge251bWJlciBleHByZXNzaW9ufQotICAgKgotICAgKiByZXR1cm5zOgotICAgKiAgWEJvb2xlYW4KLSAgICogQHhzbC51c2FnZSBhZHZhbmNlZAotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BfR1QgPSA5OwotCi0gIC8qKgotICAgKiBbT1BfUExVU10KLSAgICogW2xlbmd0aF0KLSAgICogIHtudW1iZXIgZXhwcmVzc2lvbn0KLSAgICogIHtudW1iZXIgZXhwcmVzc2lvbn0KLSAgICoKLSAgICogcmV0dXJuczoKLSAgICogIFhOdW1iZXIKLSAgICogQHhzbC51c2FnZSBhZHZhbmNlZAotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BfUExVUyA9IDEwOwotCi0gIC8qKgotICAgKiBbT1BfTUlOVVNdCi0gICAqIFtsZW5ndGhdCi0gICAqICB7bnVtYmVyIGV4cHJlc3Npb259Ci0gICAqICB7bnVtYmVyIGV4cHJlc3Npb259Ci0gICAqCi0gICAqIHJldHVybnM6Ci0gICAqICBYTnVtYmVyCi0gICAqIEB4c2wudXNhZ2UgYWR2YW5jZWQKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QX01JTlVTID0gMTE7Ci0KLSAgLyoqCi0gICAqIFtPUF9NVUxUXQotICAgKiBbbGVuZ3RoXQotICAgKiAge251bWJlciBleHByZXNzaW9ufQotICAgKiAge251bWJlciBleHByZXNzaW9ufQotICAgKgotICAgKiByZXR1cm5zOgotICAgKiAgWE51bWJlcgotICAgKiBAeHNsLnVzYWdlIGFkdmFuY2VkCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUF9NVUxUID0gMTI7Ci0KLSAgLyoqCi0gICAqIFtPUF9ESVZdCi0gICAqIFtsZW5ndGhdCi0gICAqICB7bnVtYmVyIGV4cHJlc3Npb259Ci0gICAqICB7bnVtYmVyIGV4cHJlc3Npb259Ci0gICAqCi0gICAqIHJldHVybnM6Ci0gICAqICBYTnVtYmVyCi0gICAqIEB4c2wudXNhZ2UgYWR2YW5jZWQKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QX0RJViA9IDEzOwotCi0gIC8qKgotICAgKiBbT1BfTU9EXQotICAgKiBbbGVuZ3RoXQotICAgKiAge251bWJlciBleHByZXNzaW9ufQotICAgKiAge251bWJlciBleHByZXNzaW9ufQotICAgKgotICAgKiByZXR1cm5zOgotICAgKiAgWE51bWJlcgotICAgKiBAeHNsLnVzYWdlIGFkdmFuY2VkCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUF9NT0QgPSAxNDsKLQotICAvKioKLSAgICogW09QX1FVT10KLSAgICogW2xlbmd0aF0KLSAgICogIHtudW1iZXIgZXhwcmVzc2lvbn0KLSAgICogIHtudW1iZXIgZXhwcmVzc2lvbn0KLSAgICoKLSAgICogcmV0dXJuczoKLSAgICogIFhOdW1iZXIKLSAgICogQHhzbC51c2FnZSBhZHZhbmNlZAotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BfUVVPID0gMTU7Ci0KLSAgLyoqCi0gICAqIFtPUF9ORUddCi0gICAqIFtsZW5ndGhdCi0gICAqICB7bnVtYmVyIGV4cHJlc3Npb259Ci0gICAqCi0gICAqIHJldHVybnM6Ci0gICAqICBYTnVtYmVyCi0gICAqIEB4c2wudXNhZ2UgYWR2YW5jZWQKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QX05FRyA9IDE2OwotCi0gIC8qKgotICAgKiBbT1BfU1RSSU5HXSAoY2FzdCBvcGVyYXRpb24pCi0gICAqIFtsZW5ndGhdCi0gICAqICB7ZXhwcmVzc2lvbn0KLSAgICoKLSAgICogcmV0dXJuczoKLSAgICogIFhTdHJpbmcKLSAgICogQHhzbC51c2FnZSBhZHZhbmNlZAotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BfU1RSSU5HID0gMTc7Ci0KLSAgLyoqCi0gICAqIFtPUF9CT09MXSAoY2FzdCBvcGVyYXRpb24pCi0gICAqIFtsZW5ndGhdCi0gICAqICB7ZXhwcmVzc2lvbn0KLSAgICoKLSAgICogcmV0dXJuczoKLSAgICogIFhCb29sZWFuCi0gICAqIEB4c2wudXNhZ2UgYWR2YW5jZWQKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QX0JPT0wgPSAxODsKLQotICAvKioKLSAgICogW09QX05VTUJFUl0gKGNhc3Qgb3BlcmF0aW9uKQotICAgKiBbbGVuZ3RoXQotICAgKiAge2V4cHJlc3Npb259Ci0gICAqCi0gICAqIHJldHVybnM6Ci0gICAqICBYQm9vbGVhbgotICAgKiBAeHNsLnVzYWdlIGFkdmFuY2VkCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUF9OVU1CRVIgPSAxOTsKLQotICAvKioKLSAgICogW09QX1VOSU9OXQotICAgKiBbbGVuZ3RoXQotICAgKiAge1BhdGhFeHByfSsKLSAgICoKLSAgICogcmV0dXJuczoKLSAgICogIFhOb2RlU2V0Ci0gICAqIEB4c2wudXNhZ2UgYWR2YW5jZWQKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QX1VOSU9OID0gMjA7Ci0KLSAgLyoqCi0gICAqIFtPUF9MSVRFUkFMXQotICAgKiBbM10KLSAgICogW2luZGV4IHRvIHRva2VuXQotICAgKgotICAgKiByZXR1cm5zOgotICAgKiAgWFN0cmluZwotICAgKiBAeHNsLnVzYWdlIGFkdmFuY2VkCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUF9MSVRFUkFMID0gMjE7Ci0KLSAgLyoqIFRoZSBsb3cgb3Bjb2RlIGZvciBub2Rlc2V0cywgbmVlZGVkIGJ5IGdldEZpcnN0UHJlZGljYXRlT3BQb3MgYW5kCi0gICAqICBnZXROZXh0U3RlcFBvcy4gICAgICAgICAgKi8KLSAgc3RhdGljIGZpbmFsIGludCBGSVJTVF9OT0RFU0VUX09QID0gMjI7Ci0KLSAgLyoqCi0gICAqIFtPUF9WQVJJQUJMRV0KLSAgICogWzRdCi0gICAqIFtpbmRleCB0byBuYW1lc3BhY2UgdG9rZW4sIG9yIEVNUFRZXQotICAgKiBbaW5kZXggdG8gZnVuY3Rpb24gbmFtZSB0b2tlbl0KLSAgICoKLSAgICogcmV0dXJuczoKLSAgICogIFhTdHJpbmcKLSAgICogQHhzbC51c2FnZSBhZHZhbmNlZAotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BfVkFSSUFCTEUgPSAyMjsKLQotICAvKioKLSAgICogW09QX0dST1VQXQotICAgKiBbbGVuZ3RoXQotICAgKiAge2V4cHJlc3Npb259Ci0gICAqCi0gICAqIHJldHVybnM6Ci0gICAqICBYTm9kZVNldAotICAgKiAgWE51bWJlcgotICAgKiAgWFN0cmluZwotICAgKiAgWEJvb2xlYW4KLSAgICogIFhSVHJlZQotICAgKiAgWE9iamVjdAotICAgKiBAeHNsLnVzYWdlIGFkdmFuY2VkCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUF9HUk9VUCA9IDIzOwotCi0gIC8qKgotICAgKiBbT1BfRVhURlVOQ1RJT05dIChFeHRlbnNpb24gZnVuY3Rpb24uKQotICAgKiBbbGVuZ3RoXQotICAgKiBbaW5kZXggdG8gbmFtZXNwYWNlIHRva2VuXQotICAgKiBbaW5kZXggdG8gZnVuY3Rpb24gbmFtZSB0b2tlbl0KLSAgICogIHtPUF9BUkdVTUVOVH0KLSAgICoKLSAgICogcmV0dXJuczoKLSAgICogIFhOb2RlU2V0Ci0gICAqICBYTnVtYmVyCi0gICAqICBYU3RyaW5nCi0gICAqICBYQm9vbGVhbgotICAgKiAgWFJUcmVlCi0gICAqICBYT2JqZWN0Ci0gICAqIEB4c2wudXNhZ2UgYWR2YW5jZWQKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QX0VYVEZVTkNUSU9OID0gMjQ7Ci0KLSAgLyoqCi0gICAqIFtPUF9GVU5DVElPTl0KLSAgICogW2xlbmd0aF0KLSAgICogW0ZVTkNfbmFtZV0KLSAgICogIHtPUF9BUkdVTUVOVH0KLSAgICogW0VORE9QXQotICAgKgotICAgKiByZXR1cm5zOgotICAgKiAgWE5vZGVTZXQKLSAgICogIFhOdW1iZXIKLSAgICogIFhTdHJpbmcKLSAgICogIFhCb29sZWFuCi0gICAqICBYUlRyZWUKLSAgICogIFhPYmplY3QKLSAgICogQHhzbC51c2FnZSBhZHZhbmNlZAotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BfRlVOQ1RJT04gPSAyNTsKLQotICAvKiogVGhlIGxhc3Qgb3Bjb2RlIGZvciBzdHVmZiB0aGF0IGNhbiBiZSBhIG5vZGVzZXQuICAgICAgICAgKi8KLSAgc3RhdGljIGZpbmFsIGludCBMQVNUX05PREVTRVRfT1AgPSAyNTsKLQotICAvKioKLSAgICogW09QX0FSR1VNRU5UXSAoRnVuY3Rpb24gYXJndW1lbnQuKQotICAgKiBbbGVuZ3RoXQotICAgKiAge2V4cHJlc3Npb259Ci0gICAqCi0gICAqIHJldHVybnM6Ci0gICAqICBYTm9kZVNldAotICAgKiAgWE51bWJlcgotICAgKiAgWFN0cmluZwotICAgKiAgWEJvb2xlYW4KLSAgICogIFhSVHJlZQotICAgKiAgWE9iamVjdAotICAgKiBAeHNsLnVzYWdlIGFkdmFuY2VkCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUF9BUkdVTUVOVCA9IDI2OwotCi0gIC8qKgotICAgKiBbT1BfTlVNQkVSTElUXSAoTnVtYmVyIGxpdGVyYWwuKQotICAgKiBbM10KLSAgICogW2luZGV4IHRvIHRva2VuXQotICAgKgotICAgKiByZXR1cm5zOgotICAgKiAgWFN0cmluZwotICAgKiBAeHNsLnVzYWdlIGFkdmFuY2VkCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUF9OVU1CRVJMSVQgPSAyNzsKLQotICAvKioKLSAgICogW09QX0xPQ0FUSU9OUEFUSF0KLSAgICogW2xlbmd0aF0KLSAgICogICB7RlJPTV9zdGVwVHlwZX0KLSAgICogfCB7ZnVuY3Rpb259Ci0gICAqIHtwcmVkaWNhdGV9Ci0gICAqIFtFTkRPUF0KLSAgICoKLSAgICogKE5vdGUgdGhhdCBlbGVtZW50IGFuZCBhdHRyaWJ1dGUgbmFtZXNwYWNlcyBhbmQKLSAgICogbmFtZXMgY2FuIGJlIHdpbGRjYXJkZWQgJyonLikKLSAgICoKLSAgICogcmV0dXJuczoKLSAgICogIFhOb2RlU2V0Ci0gICAqIEB4c2wudXNhZ2UgYWR2YW5jZWQKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QX0xPQ0FUSU9OUEFUSCA9IDI4OwotCi0gIC8vIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPQ0FUSU9OUEFUSEVYX01BU0sgPSAweDAwMDBGRkZGOwotICAvLyBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT0NBVElPTlBBVEhFWF9JU1NJTVBMRSA9IDB4MDAwMTAwMDA7Ci0gIC8vIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QX0xPQ0FUSU9OUEFUSF9FWCA9ICgyOCB8IDB4MDAwMTAwMDApOwotCi0gIC8qKgotICAgKiBbT1BfUFJFRElDQVRFXQotICAgKiBbbGVuZ3RoXQotICAgKiAge2V4cHJlc3Npb259Ci0gICAqIFtFTkRPUF0gKEZvciBzYWZldHkpCi0gICAqCi0gICAqIHJldHVybnM6Ci0gICAqICBYQm9vbGVhbiBvciBYTnVtYmVyCi0gICAqIEB4c2wudXNhZ2UgYWR2YW5jZWQKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QX1BSRURJQ0FURSA9IDI5OwotCi0gIC8qKgotICAgKiBbT1BfTUFUQ0hQQVRURVJOXQotICAgKiBbbGVuZ3RoXQotICAgKiAge1BhdGhFeHByfSsKLSAgICoKLSAgICogcmV0dXJuczoKLSAgICogIFhOb2RlU2V0Ci0gICAqIEB4c2wudXNhZ2UgYWR2YW5jZWQKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QX01BVENIUEFUVEVSTiA9IDMwOwotCi0gIC8qKgotICAgKiBbT1BfTE9DQVRJT05QQVRIUEFUVEVSTl0KLSAgICogW2xlbmd0aF0KLSAgICogICB7RlJPTV9zdGVwVHlwZX0KLSAgICogfCB7ZnVuY3Rpb259e3ByZWRpY2F0ZX0KLSAgICogW0VORE9QXQotICAgKiByZXR1cm5zOgotICAgKiAgWE5vZGVTZXQKLSAgICogQHhzbC51c2FnZSBhZHZhbmNlZAotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BfTE9DQVRJT05QQVRIUEFUVEVSTiA9IDMxOwotCi0gIC8qKgotICAgKiBbTk9ERVRZUEVfQ09NTUVOVF0KLSAgICogTm8gc2l6ZSBvciBhcmd1bWVudHMuCi0gICAqIE5vdGU6IG11c3Qgbm90IG92ZXJsYXAgZnVuY3Rpb24gT1AgbnVtYmVyIQotICAgKgotICAgKiByZXR1cm5zOgotICAgKiAgWEJvb2xlYW4KLSAgICogQHhzbC51c2FnZSBhZHZhbmNlZAotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTk9ERVRZUEVfQ09NTUVOVCA9IDEwMzA7Ci0KLSAgLyoqCi0gICAqIFtOT0RFVFlQRV9URVhUXQotICAgKiBObyBzaXplIG9yIGFyZ3VtZW50cy4KLSAgICogTm90ZTogbXVzdCBub3Qgb3ZlcmxhcCBmdW5jdGlvbiBPUCBudW1iZXIhCi0gICAqCi0gICAqIHJldHVybnM6Ci0gICAqICBYQm9vbGVhbgotICAgKiBAeHNsLnVzYWdlIGFkdmFuY2VkCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBOT0RFVFlQRV9URVhUID0gMTAzMTsKLQotICAvKioKLSAgICogW05PREVUWVBFX1BJXQotICAgKiBbaW5kZXggdG8gdG9rZW5dCi0gICAqIE5vdGU6IG11c3Qgbm90IG92ZXJsYXAgZnVuY3Rpb24gT1AgbnVtYmVyIQotICAgKgotICAgKiByZXR1cm5zOgotICAgKiAgWEJvb2xlYW4KLSAgICogQHhzbC51c2FnZSBhZHZhbmNlZAotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTk9ERVRZUEVfUEkgPSAxMDMyOwotCi0gIC8qKgotICAgKiBbTk9ERVRZUEVfTk9ERV0KLSAgICogTm8gc2l6ZSBvciBhcmd1bWVudHMuCi0gICAqIE5vdGU6IG11c3Qgbm90IG92ZXJsYXAgZnVuY3Rpb24gT1AgbnVtYmVyIQotICAgKgotICAgKiByZXR1cm5zOgotICAgKiAgWEJvb2xlYW4KLSAgICogQHhzbC51c2FnZSBhZHZhbmNlZAotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTk9ERVRZUEVfTk9ERSA9IDEwMzM7Ci0KLSAgLyoqCi0gICAqIFtOT0RFTkFNRV0KLSAgICogW2luZGV4IHRvIG5zIHRva2VuIG9yIEVNUFRZXQotICAgKiBbaW5kZXggdG8gbmFtZSB0b2tlbl0KLSAgICoKLSAgICogcmV0dXJuczoKLSAgICogIFhCb29sZWFuCi0gICAqIEB4c2wudXNhZ2UgYWR2YW5jZWQKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE5PREVOQU1FID0gMzQ7Ci0KLSAgLyoqCi0gICAqIFtOT0RFVFlQRV9ST09UXQotICAgKiBObyBzaXplIG9yIGFyZ3VtZW50cy4KLSAgICoKLSAgICogcmV0dXJuczoKLSAgICogIFhCb29sZWFuCi0gICAqIEB4c2wudXNhZ2UgYWR2YW5jZWQKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE5PREVUWVBFX1JPT1QgPSAzNTsKLQotICAvKioKLSAgICogW05PREVUWVBFX0FOWV0KLSAgICogTm8gc2l6ZSBvciBhcmd1bWVudHMuCi0gICAqCi0gICAqIHJldHVybnM6Ci0gICAqICBYQm9vbGVhbgotICAgKiBAeHNsLnVzYWdlIGFkdmFuY2VkCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBOT0RFVFlQRV9BTllFTEVNRU5UID0gMzY7Ci0KLSAgLyoqCi0gICAqIFtOT0RFVFlQRV9BTlldCi0gICAqIE5vIHNpemUgb3IgYXJndW1lbnRzLgotICAgKgotICAgKiByZXR1cm5zOgotICAgKiAgWEJvb2xlYW4KLSAgICogQHhzbC51c2FnZSBhZHZhbmNlZAotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTk9ERVRZUEVfRlVOQ1RFU1QgPSAxMDM0OwotCi0gIC8qKgotICAgKiBbRlJPTV9zdGVwVHlwZV0KLSAgICogW2xlbmd0aCwgaW5jbHVkaW5nIHByZWRpY2F0ZXNdCi0gICAqIFtsZW5ndGggb2YganVzdCB0aGUgc3RlcCwgd2l0aG91dCB0aGUgcHJlZGljYXRlc10KLSAgICoge25vZGUgdGVzdH0KLSAgICoge3ByZWRpY2F0ZXN9PwotICAgKgotICAgKiByZXR1cm5zOgotICAgKiAgWEJvb2xlYW4KLSAgICogQHhzbC51c2FnZSBhZHZhbmNlZAotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQVhFU19TVEFSVF9UWVBFUyA9IDM3OwotCi0gIC8qKiBhbmNlc3RvciBheGVzIG9wY29kZS4gICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGUk9NX0FOQ0VTVE9SUyA9IDM3OwotCi0gIC8qKiBhbmNlc3Rvci1vci1zZWxmIGF4ZXMgb3Bjb2RlLiAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZST01fQU5DRVNUT1JTX09SX1NFTEYgPSAzODsKLQotICAvKiogYXR0cmlidXRlIGF4ZXMgb3Bjb2RlLiAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZST01fQVRUUklCVVRFUyA9IDM5OwotCi0gIC8qKiBjaGlsZHJlbiBheGVzIG9wY29kZS4gICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGUk9NX0NISUxEUkVOID0gNDA7Ci0KLSAgLyoqIGRlc2NlbmRhbnRzIGF4ZXMgb3Bjb2RlLiAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZST01fREVTQ0VOREFOVFMgPSA0MTsKLQotICAvKiogZGVzY2VuZGFudHMtb2Ytc2VsZiBheGVzIG9wY29kZS4gICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGUk9NX0RFU0NFTkRBTlRTX09SX1NFTEYgPSA0MjsKLQotICAvKiogZm9sbG93aW5nIGF4ZXMgb3Bjb2RlLiAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZST01fRk9MTE9XSU5HID0gNDM7Ci0KLSAgLyoqIGZvbGxvd2luZy1zaWJsaW5ncyBheGVzIG9wY29kZS4gICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGUk9NX0ZPTExPV0lOR19TSUJMSU5HUyA9IDQ0OwotCi0gIC8qKiBwYXJlbnQgYXhlcyBvcGNvZGUuICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRlJPTV9QQVJFTlQgPSA0NTsKLQotICAvKiogcHJlY2VkaW5nIGF4ZXMgb3Bjb2RlLiAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZST01fUFJFQ0VESU5HID0gNDY7Ci0KLSAgLyoqIHByZWNlZGluZy1zaWJsaW5nIGF4ZXMgb3Bjb2RlLiAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZST01fUFJFQ0VESU5HX1NJQkxJTkdTID0gNDc7Ci0KLSAgLyoqIHNlbGYgYXhlcyBvcGNvZGUuICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRlJPTV9TRUxGID0gNDg7Ci0KLSAgLyoqIG5hbWVzcGFjZSBheGVzIG9wY29kZS4gICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGUk9NX05BTUVTUEFDRSA9IDQ5OwotCi0gIC8qKiAnLycgYXhlcyBvcGNvZGUuICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRlJPTV9ST09UID0gNTA7Ci0KLSAgLyoqCi0gICAqIEZvciBtYXRjaCBwYXR0ZXJucy4KLSAgICogQHhzbC51c2FnZSBhZHZhbmNlZAotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFUQ0hfQVRUUklCVVRFID0gNTE7Ci0KLSAgLyoqCi0gICAqIEZvciBtYXRjaCBwYXR0ZXJucy4KLSAgICogQHhzbC51c2FnZSBhZHZhbmNlZAotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFUQ0hfQU5ZX0FOQ0VTVE9SID0gNTI7Ci0KLSAgLyoqCi0gICAqIEZvciBtYXRjaCBwYXR0ZXJucy4KLSAgICogQHhzbC51c2FnZSBhZHZhbmNlZAotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFUQ0hfSU1NRURJQVRFX0FOQ0VTVE9SID0gNTM7Ci0KLSAgLyoqIFRoZSBlbmQgb2YgdGhlIGF4ZXMgdHlwZXMuICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFYRVNfRU5EX1RZUEVTID0gNTM7Ci0KLSAgLyoqIFRoZSBuZXh0IGZyZWUgSUQuICBQbGVhc2Uga2VlcCB0aGlzIHVwIHRvIGRhdGUuICAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTkVYVF9GUkVFX0lEID0gOTk7Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2NvbXBpbGVyL09wTWFwLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2NvbXBpbGVyL09wTWFwLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGYwY2ZhOTQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9jb21waWxlci9PcE1hcC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDU3ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IE9wTWFwLmphdmEsdiAxLjEuMi4xIDIwMDUvMDgvMDEgMDE6MzA6MzEgamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5jb21waWxlcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC5yZXMuWFNMTWVzc2FnZXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5PYmplY3RWZWN0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLnBhdHRlcm5zLk5vZGVUZXN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5yZXMuWFBBVEhFcnJvclJlc291cmNlczsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIHJlcHJlc2VudHMgdGhlIGRhdGEgc3RydWN0dXJlIGJhc2ljcyBvZiB0aGUgWFBhdGgKLSAqIG9iamVjdC4KLSAqLwotcHVibGljIGNsYXNzIE9wTWFwCi17Ci0KLSAgLyoqCi0gICAqIFRoZSBjdXJyZW50IHBhdHRlcm4gc3RyaW5nLCBmb3IgZGlhZ25vc3RpY3MgcHVycG9zZXMKLSAgICovCi0gIHByb3RlY3RlZCBTdHJpbmcgbV9jdXJyZW50UGF0dGVybjsKLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBleHByZXNzaW9uIGFzIGEgc3RyaW5nIGZvciBkaWFnbm9zdGljcy4KLSAgICoKLSAgICogQHJldHVybiBUaGUgZXhwcmVzc2lvbiBzdHJpbmcuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkKLSAgewotICAgIHJldHVybiBtX2N1cnJlbnRQYXR0ZXJuOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgZXhwcmVzc2lvbiBhcyBhIHN0cmluZyBmb3IgZGlhZ25vc3RpY3MuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGV4cHJlc3Npb24gc3RyaW5nLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRQYXR0ZXJuU3RyaW5nKCkKLSAgewotICAgIHJldHVybiBtX2N1cnJlbnRQYXR0ZXJuOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoZSBzdGFydGluZyBzaXplIG9mIHRoZSB0b2tlbiBxdWV1ZS4KLSAgICovCi0gIHN0YXRpYyBmaW5hbCBpbnQgTUFYVE9LRU5RVUVVRVNJWkUgPSA1MDA7Ci0KLSAgLyoKLSAgICogQW1vdW50IHRvIGdyb3cgdG9rZW4gcXVldWUgd2hlbiBpdCBiZWNvbWVzIGZ1bGwKLSAgICovCi0gIHN0YXRpYyBmaW5hbCBpbnQgQkxPQ0tUT0tFTlFVRVVFU0laRSA9IDUwMDsKLQotICAvKioKLSAgICogIFRva2VuU3RhY2sgaXMgdGhlIHF1ZXVlIG9mIHVzZWQgdG9rZW5zLiBUaGUgY3VycmVudCB0b2tlbiBpcyB0aGUgdG9rZW4gYXQgdGhlCi0gICAqIGVuZCBvZiB0aGUgbV90b2tlblF1ZXVlLiBUaGUgaWRlYSBpcyB0aGF0IHRoZSBxdWV1ZSBjYW4gYmUgbWFya2VkIGFuZCBhIHNlcXVlbmNlCi0gICAqIG9mIHRva2VucyBjYW4gYmUgcmV1c2VkLgotICAgKi8KLSAgT2JqZWN0VmVjdG9yIG1fdG9rZW5RdWV1ZSA9IG5ldyBPYmplY3RWZWN0b3IoTUFYVE9LRU5RVUVVRVNJWkUsIEJMT0NLVE9LRU5RVUVVRVNJWkUpOwotCi0gIC8qKgotICAgKiBHZXQgdGhlIFhQYXRoIGFzIGEgbGlzdCBvZiB0b2tlbnMuCi0gICAqCi0gICAqIEByZXR1cm4gT2JqZWN0VmVjdG9yIG9mIHRva2Vucy4KLSAgICovCi0gIHB1YmxpYyBPYmplY3RWZWN0b3IgZ2V0VG9rZW5RdWV1ZSgpCi0gIHsKLSAgICByZXR1cm4gbV90b2tlblF1ZXVlOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgWFBhdGggYXMgYSBsaXN0IG9mIHRva2Vucy4KLSAgICoKLSAgICogQHBhcmFtIHBvcyBpbmRleCBpbnRvIHRva2VuIHF1ZXVlLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSB0b2tlbiwgbm9ybWFsbHkgYSBzdHJpbmcuCi0gICAqLwotICBwdWJsaWMgT2JqZWN0IGdldFRva2VuKGludCBwb3MpCi0gIHsKLSAgICByZXR1cm4gbV90b2tlblF1ZXVlLmVsZW1lbnRBdChwb3MpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoZSBjdXJyZW50IHNpemUgb2YgdGhlIHRva2VuIHF1ZXVlLgotICAgKi8KLS8vICBwdWJsaWMgaW50IG1fdG9rZW5RdWV1ZVNpemUgPSAwOwotCi0gIC8qKgotICAgICogR2V0IHNpemUgb2YgdGhlIHRva2VuIHF1ZXVlLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBzaXplIG9mIHRoZSB0b2tlbiBxdWV1ZS4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0VG9rZW5RdWV1ZVNpemUoKQotICB7Ci0gICAgcmV0dXJuIG1fdG9rZW5RdWV1ZS5zaXplKCk7Ci0KLSAgfQotCi0gIC8qKgotICAgKiBBbiBvcGVyYXRpb25zIG1hcCBpcyB1c2VkIGluc3RlYWQgb2YgYSBwcm9wZXIgcGFyc2UgdHJlZS4gIEl0IGNvbnRhaW5zCi0gICAqIG9wZXJhdGlvbnMgY29kZXMgYW5kIGluZGV4ZXMgaW50byB0aGUgbV90b2tlblF1ZXVlLgotICAgKiBJIHVzZSBhbiBhcnJheSBpbnN0ZWFkIG9mIGEgZnVsbCBwYXJzZSB0cmVlIGluIG9yZGVyIHRvIGN1dCBkb3duCi0gICAqIG9uIHRoZSBudW1iZXIgb2Ygb2JqZWN0cyBjcmVhdGVkLgotICAgKi8KLSAgT3BNYXBWZWN0b3IgbV9vcE1hcCA9IG51bGw7Ci0KLSAgLyoqCi0gICAgKiBHZXQgdGhlIG9wY29kZSBsaXN0IHRoYXQgZGVzY3JpYmVzIHRoZSBYUGF0aCBvcGVyYXRpb25zLiAgSXQgY29udGFpbnMKLSAgICogb3BlcmF0aW9ucyBjb2RlcyBhbmQgaW5kZXhlcyBpbnRvIHRoZSBtX3Rva2VuUXVldWUuCi0gICAqIEkgdXNlIGFuIGFycmF5IGluc3RlYWQgb2YgYSBmdWxsIHBhcnNlIHRyZWUgaW4gb3JkZXIgdG8gY3V0IGRvd24KLSAgICogb24gdGhlIG51bWJlciBvZiBvYmplY3RzIGNyZWF0ZWQuCi0gICAqCi0gICAqIEByZXR1cm4gQW4gSW50VmVjdG9yIHRoYXQgaXMgdGhlIG9wY29kZSBsaXN0IHRoYXQgZGVzY3JpYmVzIHRoZSBYUGF0aCBvcGVyYXRpb25zLgotICAgKi8KLSAgcHVibGljIE9wTWFwVmVjdG9yIGdldE9wTWFwKCkKLSAgewotICAgIHJldHVybiBtX29wTWFwOwotICB9Ci0KLSAgLy8gUG9zaXRpb24gaW5kZXhlcwotCi0gIC8qKgotICAgKiBUaGUgbGVuZ3RoIGlzIGFsd2F5cyB0aGUgb3Bjb2RlIHBvc2l0aW9uICsgMS4KLSAgICogTGVuZ3RoIGlzIGFsd2F5cyBleHByZXNzZWQgYXMgdGhlIG9wY29kZStsZW5ndGggYnl0ZXMsCi0gICAqIHNvIGl0IGlzIGFsd2F5cyAyIG9yIGdyZWF0ZXIuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVBJTkRFWF9MRU5HVEggPSAxOwotCi0gIC8qKgotICAgKiBSZXBsYWNlIHRoZSBsYXJnZSBhcnJheXMKLSAgICogd2l0aCBhIHNtYWxsIGFycmF5LgotICAgKi8KLSAgdm9pZCBzaHJpbmsoKQotICB7Ci0KLSAgICBpbnQgbiA9IG1fb3BNYXAuZWxlbWVudEF0KE1BUElOREVYX0xFTkdUSCk7Ci0gICAgbV9vcE1hcC5zZXRUb1NpemUobiArIDQpOwotCi0gICAgbV9vcE1hcC5zZXRFbGVtZW50QXQoMCxuKTsKLSAgICBtX29wTWFwLnNldEVsZW1lbnRBdCgwLG4rMSk7Ci0gICAgbV9vcE1hcC5zZXRFbGVtZW50QXQoMCxuKzIpOwotCi0KLSAgICBuID0gbV90b2tlblF1ZXVlLnNpemUoKTsKLSAgICBtX3Rva2VuUXVldWUuc2V0VG9TaXplKG4gKyA0KTsKLQotICAgIG1fdG9rZW5RdWV1ZS5zZXRFbGVtZW50QXQobnVsbCxuKTsKLSAgICBtX3Rva2VuUXVldWUuc2V0RWxlbWVudEF0KG51bGwsbiArIDEpOwotICAgIG1fdG9rZW5RdWV1ZS5zZXRFbGVtZW50QXQobnVsbCxuICsgMik7Ci0gIH0KLQotICAvKioKLSAgKiBHaXZlbiBhbiBvcGVyYXRpb24gcG9zaXRpb24sIHJldHVybiB0aGUgY3VycmVudCBvcC4KLSAgICoKLSAgICogQHBhcmFtIG9wUG9zIGluZGV4IGludG8gb3AgbWFwLgotICAgKiBAcmV0dXJuIHRoZSBvcCB0aGF0IGNvcnJlc3BvbmRzIHRvIHRoZSBvcFBvcyBhcmd1bWVudC4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0T3AoaW50IG9wUG9zKQotICB7Ci0gICAgcmV0dXJuIG1fb3BNYXAuZWxlbWVudEF0KG9wUG9zKTsKLSAgfQotCi0gIC8qKgotICAqIFNldCB0aGUgb3AgYXQgaW5kZXggdG8gdGhlIGdpdmVuIGludC4KLSAgICoKLSAgICogQHBhcmFtIG9wUG9zIGluZGV4IGludG8gb3AgbWFwLgotICAgKiBAcGFyYW0gdmFsdWUgVmFsdWUgdG8gc2V0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRPcChpbnQgb3BQb3MsIGludCB2YWx1ZSkKLSAgewotICAgICBtX29wTWFwLnNldEVsZW1lbnRBdCh2YWx1ZSxvcFBvcyk7Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYW4gb3BlcmF0aW9uIHBvc2l0aW9uLCByZXR1cm4gdGhlIGVuZCBwb3NpdGlvbiwgaS5lLiB0aGUKLSAgICogYmVnaW5uaW5nIG9mIHRoZSBuZXh0IG9wZXJhdGlvbi4KLSAgICoKLSAgICogQHBhcmFtIG9wUG9zIEFuIG9wIHBvc2l0aW9uIG9mIGFuIG9wZXJhdGlvbiBmb3Igd2hpY2ggdGhlcmUgaXMgYSBzaXplCi0gICAqICAgICAgICAgICAgICBlbnRyeSBmb2xsb3dpbmcuCi0gICAqIEByZXR1cm4gcG9zaXRpb24gb2YgbmV4dCBvcGVyYXRpb24gaW4gbV9vcE1hcC4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0TmV4dE9wUG9zKGludCBvcFBvcykKLSAgewotICAgIHJldHVybiBvcFBvcyArIG1fb3BNYXAuZWxlbWVudEF0KG9wUG9zICsgMSk7Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYSBsb2NhdGlvbiBzdGVwIHBvc2l0aW9uLCByZXR1cm4gdGhlIGVuZCBwb3NpdGlvbiwgaS5lLiB0aGUKLSAgICogYmVnaW5uaW5nIG9mIHRoZSBuZXh0IHN0ZXAuCi0gICAqCi0gICAqIEBwYXJhbSBvcFBvcyB0aGUgcG9zaXRpb24gb2YgYSBsb2NhdGlvbiBzdGVwLgotICAgKiBAcmV0dXJuIHRoZSBwb3NpdGlvbiBvZiB0aGUgbmV4dCBsb2NhdGlvbiBzdGVwLgotICAgKi8KLSAgcHVibGljIGludCBnZXROZXh0U3RlcFBvcyhpbnQgb3BQb3MpCi0gIHsKLQotICAgIGludCBzdGVwVHlwZSA9IGdldE9wKG9wUG9zKTsKLQotICAgIGlmICgoc3RlcFR5cGUgPj0gT3BDb2Rlcy5BWEVTX1NUQVJUX1RZUEVTKQotICAgICAgICAgICAgJiYgKHN0ZXBUeXBlIDw9IE9wQ29kZXMuQVhFU19FTkRfVFlQRVMpKQotICAgIHsKLSAgICAgIHJldHVybiBnZXROZXh0T3BQb3Mob3BQb3MpOwotICAgIH0KLSAgICBlbHNlIGlmICgoc3RlcFR5cGUgPj0gT3BDb2Rlcy5GSVJTVF9OT0RFU0VUX09QKQotICAgICAgICAgICAgICYmIChzdGVwVHlwZSA8PSBPcENvZGVzLkxBU1RfTk9ERVNFVF9PUCkpCi0gICAgewotICAgICAgaW50IG5ld09wUG9zID0gZ2V0TmV4dE9wUG9zKG9wUG9zKTsKLQotICAgICAgd2hpbGUgKE9wQ29kZXMuT1BfUFJFRElDQVRFID09IGdldE9wKG5ld09wUG9zKSkKLSAgICAgIHsKLSAgICAgICAgbmV3T3BQb3MgPSBnZXROZXh0T3BQb3MobmV3T3BQb3MpOwotICAgICAgfQotCi0gICAgICBzdGVwVHlwZSA9IGdldE9wKG5ld09wUG9zKTsKLQotICAgICAgaWYgKCEoKHN0ZXBUeXBlID49IE9wQ29kZXMuQVhFU19TVEFSVF9UWVBFUykKLSAgICAgICAgICAgICYmIChzdGVwVHlwZSA8PSBPcENvZGVzLkFYRVNfRU5EX1RZUEVTKSkpCi0gICAgICB7Ci0gICAgICAgIHJldHVybiBPcENvZGVzLkVORE9QOwotICAgICAgfQotCi0gICAgICByZXR1cm4gbmV3T3BQb3M7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKLSAgICAgICAgWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfVU5LTk9XTl9TVEVQLCBuZXcgT2JqZWN0W117U3RyaW5nLnZhbHVlT2Yoc3RlcFR5cGUpfSkpOwotICAgICAgLy8iUHJvZ3JhbW1lcidzIGFzc2VydGlvbiBpbiBnZXROZXh0U3RlcFBvczogdW5rbm93biBzdGVwVHlwZTogIiArIHN0ZXBUeXBlKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYW4gb3BlcmF0aW9uIHBvc2l0aW9uLCByZXR1cm4gdGhlIGVuZCBwb3NpdGlvbiwgaS5lLiB0aGUKLSAgICogYmVnaW5uaW5nIG9mIHRoZSBuZXh0IG9wZXJhdGlvbi4KLSAgICoKLSAgICogQHBhcmFtIG9wTWFwIFRoZSBvcGVyYXRpb25zIG1hcC4KLSAgICogQHBhcmFtIG9wUG9zIGluZGV4IHRvIG9wZXJhdGlvbiwgZm9yIHdoaWNoIHRoZXJlIGlzIGEgc2l6ZSBlbnRyeSBmb2xsb3dpbmcuCi0gICAqIEByZXR1cm4gcG9zaXRpb24gb2YgbmV4dCBvcGVyYXRpb24gaW4gbV9vcE1hcC4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgaW50IGdldE5leHRPcFBvcyhpbnRbXSBvcE1hcCwgaW50IG9wUG9zKQotICB7Ci0gICAgcmV0dXJuIG9wUG9zICsgb3BNYXBbb3BQb3MgKyAxXTsKLSAgfQotCi0gIC8qKgotICAgKiBHaXZlbiBhbiBGUk9NX3N0ZXBUeXBlIHBvc2l0aW9uLCByZXR1cm4gdGhlIHBvc2l0aW9uIG9mIHRoZQotICAgKiBmaXJzdCBwcmVkaWNhdGUsIGlmIHRoZXJlIGlzIG9uZSwgb3IgZWxzZSB0aGlzIHdpbGwgcG9pbnQKLSAgICogdG8gdGhlIGVuZCBvZiB0aGUgRlJPTV9zdGVwVHlwZS4KLSAgICogRXhhbXBsZToKLSAgICogIGludCBwb3NPZlByZWRpY2F0ZSA9IHhwYXRoLmdldE5leHRPcFBvcyhzdGVwUG9zKTsKLSAgICogIGJvb2xlYW4gaGFzUHJlZGljYXRlcyA9Ci0gICAqICAgICAgICAgICAgT3BDb2Rlcy5PUF9QUkVESUNBVEUgPT0geHBhdGguZ2V0T3AocG9zT2ZQcmVkaWNhdGUpOwotICAgKgotICAgKiBAcGFyYW0gb3BQb3MgcG9zaXRpb24gb2YgRlJPTV9zdGVwVHlwZSBvcC4KLSAgICogQHJldHVybiBwb3NpdGlvbiBvZiBwcmVkaWNhdGUgaW4gRlJPTV9zdGVwVHlwZSBzdHJ1Y3R1cmUuCi0gICAqLwotICBwdWJsaWMgaW50IGdldEZpcnN0UHJlZGljYXRlT3BQb3MoaW50IG9wUG9zKQotICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpbnQgc3RlcFR5cGUgPSBtX29wTWFwLmVsZW1lbnRBdChvcFBvcyk7Ci0KLSAgICBpZiAoKHN0ZXBUeXBlID49IE9wQ29kZXMuQVhFU19TVEFSVF9UWVBFUykKLSAgICAgICAgICAgICYmIChzdGVwVHlwZSA8PSBPcENvZGVzLkFYRVNfRU5EX1RZUEVTKSkKLSAgICB7Ci0gICAgICByZXR1cm4gb3BQb3MgKyBtX29wTWFwLmVsZW1lbnRBdChvcFBvcyArIDIpOwotICAgIH0KLSAgICBlbHNlIGlmICgoc3RlcFR5cGUgPj0gT3BDb2Rlcy5GSVJTVF9OT0RFU0VUX09QKQotICAgICAgICAgICAgICYmIChzdGVwVHlwZSA8PSBPcENvZGVzLkxBU1RfTk9ERVNFVF9PUCkpCi0gICAgewotICAgICAgcmV0dXJuIG9wUG9zICsgbV9vcE1hcC5lbGVtZW50QXQob3BQb3MgKyAxKTsKLSAgICB9Ci0gICAgZWxzZSBpZigtMiA9PSBzdGVwVHlwZSkKLSAgICB7Ci0gICAgICByZXR1cm4gLTI7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBlcnJvcihjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucmVzLlhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfVU5LTk9XTl9PUENPREUsCi0gICAgICAgICAgICBuZXcgT2JqZWN0W117IFN0cmluZy52YWx1ZU9mKHN0ZXBUeXBlKSB9KTsgIC8vIkVSUk9SISBVbmtub3duIG9wIGNvZGU6ICIrbV9vcE1hcFtvcFBvc10pOwotICAgICAgcmV0dXJuIC0xOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIHRoZSB1c2VyIG9mIGFuIGVycm9yLCBhbmQgcHJvYmFibHkgdGhyb3cgYW4KLSAgICogZXhjZXB0aW9uLgotICAgKgotICAgKiBAcGFyYW0gbXNnIEFuIGVycm9yIG1zZ2tleSB0aGF0IGNvcnJlc3BvbmRzIHRvIG9uZSBvZiB0aGUgY29uc3RhbnRzIGZvdW5kCi0gICAqICAgICAgICAgICAgaW4ge0BsaW5rIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5yZXMuWFBBVEhFcnJvclJlc291cmNlc30sIHdoaWNoIGlzCi0gICAqICAgICAgICAgICAgYSBrZXkgZm9yIGEgZm9ybWF0IHN0cmluZy4KLSAgICogQHBhcmFtIGFyZ3MgQW4gYXJyYXkgb2YgYXJndW1lbnRzIHJlcHJlc2VudGVkIGluIHRoZSBmb3JtYXQgc3RyaW5nLCB3aGljaAotICAgKiAgICAgICAgICAgICBtYXkgYmUgbnVsbC4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBpZiB0aGUgY3VycmVudCBFcnJvckxpc3RvbmVyIGRldGVybWluZXMgdG8KLSAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBhbiBleGNlcHRpb24uCi0gICAqLwotICBwdWJsaWMgdm9pZCBlcnJvcihTdHJpbmcgbXNnLCBPYmplY3RbXSBhcmdzKSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBqYXZhLmxhbmcuU3RyaW5nIGZtc2cgPSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwucmVzLlhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShtc2csIGFyZ3MpOwotCi0KLSAgICB0aHJvdyBuZXcgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbihmbXNnKTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIEdvIHRvIHRoZSBmaXJzdCBjaGlsZCBvZiBhIGdpdmVuIG9wZXJhdGlvbi4KLSAgICoKLSAgICogQHBhcmFtIG9wUG9zIHBvc2l0aW9uIG9mIG9wZXJhdGlvbi4KLSAgICoKLSAgICogQHJldHVybiBUaGUgcG9zaXRpb24gb2YgdGhlIGZpcnN0IGNoaWxkIG9mIHRoZSBvcGVyYXRpb24uCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGludCBnZXRGaXJzdENoaWxkUG9zKGludCBvcFBvcykKLSAgewotICAgIHJldHVybiBvcFBvcyArIDI7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBsZW5ndGggb2YgYW4gb3BlcmF0aW9uLgotICAgKgotICAgKiBAcGFyYW0gb3BQb3MgVGhlIHBvc2l0aW9uIG9mIHRoZSBvcGVyYXRpb24gaW4gdGhlIG9wIG1hcC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgc2l6ZSBvZiB0aGUgb3BlcmF0aW9uLgotICAgKi8KLSAgcHVibGljIGludCBnZXRBcmdMZW5ndGgoaW50IG9wUG9zKQotICB7Ci0gICAgcmV0dXJuIG1fb3BNYXAuZWxlbWVudEF0KG9wUG9zICsgTUFQSU5ERVhfTEVOR1RIKTsKLSAgfQotCi0gIC8qKgotICAgKiBHaXZlbiBhIGxvY2F0aW9uIHN0ZXAsIGdldCB0aGUgbGVuZ3RoIG9mIHRoYXQgc3RlcC4KLSAgICoKLSAgICogQHBhcmFtIG9wUG9zIFBvc2l0aW9uIG9mIGxvY2F0aW9uIHN0ZXAgaW4gb3AgbWFwLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBsZW5ndGggb2YgdGhlIHN0ZXAuCi0gICAqLwotICBwdWJsaWMgaW50IGdldEFyZ0xlbmd0aE9mU3RlcChpbnQgb3BQb3MpCi0gIHsKLSAgICByZXR1cm4gbV9vcE1hcC5lbGVtZW50QXQob3BQb3MgKyBNQVBJTkRFWF9MRU5HVEggKyAxKSAtIDM7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBmaXJzdCBjaGlsZCBwb3NpdGlvbiBvZiBhIGdpdmVuIGxvY2F0aW9uIHN0ZXAuCi0gICAqCi0gICAqIEBwYXJhbSBvcFBvcyBQb3NpdGlvbiBvZiBsb2NhdGlvbiBzdGVwIGluIHRoZSBsb2NhdGlvbiBtYXAuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGZpcnN0IGNoaWxkIHBvc2l0aW9uIG9mIHRoZSBzdGVwLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBpbnQgZ2V0Rmlyc3RDaGlsZFBvc09mU3RlcChpbnQgb3BQb3MpCi0gIHsKLSAgICByZXR1cm4gb3BQb3MgKyAzOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgdGVzdCB0eXBlIG9mIHRoZSBzdGVwLCBpLmUuIE5PREVUWVBFX1hYWCB2YWx1ZS4KLSAgICoKLSAgICogQHBhcmFtIG9wUG9zT2ZTdGVwIFRoZSBwb3NpdGlvbiBvZiB0aGUgRlJPTV9YWFggc3RlcC4KLSAgICoKLSAgICogQHJldHVybiBOT0RFVFlQRV9YWFggdmFsdWUuCi0gICAqLwotICBwdWJsaWMgaW50IGdldFN0ZXBUZXN0VHlwZShpbnQgb3BQb3NPZlN0ZXApCi0gIHsKLSAgICByZXR1cm4gbV9vcE1hcC5lbGVtZW50QXQob3BQb3NPZlN0ZXAgKyAzKTsgIC8vIHNraXAgcGFzdCBvcCwgbGVuLCBsZW4gd2l0aG91dCBwcmVkaWNhdGVzCi0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBuYW1lc3BhY2Ugb2YgdGhlIHN0ZXAuCi0gICAqCi0gICAqIEBwYXJhbSBvcFBvc09mU3RlcCBUaGUgcG9zaXRpb24gb2YgdGhlIEZST01fWFhYIHN0ZXAuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHN0ZXAncyBuYW1lc3BhY2UsIE5vZGVUZXN0LldJTEQsIG9yIG51bGwgZm9yIG51bGwgbmFtZXNwYWNlLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRTdGVwTlMoaW50IG9wUG9zT2ZTdGVwKQotICB7Ci0KLSAgICBpbnQgYXJnTGVuT2ZTdGVwID0gZ2V0QXJnTGVuZ3RoT2ZTdGVwKG9wUG9zT2ZTdGVwKTsKLQotICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiZ2V0U3RlcE5TLmFyZ0xlbk9mU3RlcDogIithcmdMZW5PZlN0ZXApOwotICAgIGlmIChhcmdMZW5PZlN0ZXAgPT0gMykKLSAgICB7Ci0gICAgICBpbnQgaW5kZXggPSBtX29wTWFwLmVsZW1lbnRBdChvcFBvc09mU3RlcCArIDQpOwotCi0gICAgICBpZiAoaW5kZXggPj0gMCkKLSAgICAgICAgcmV0dXJuIChTdHJpbmcpIG1fdG9rZW5RdWV1ZS5lbGVtZW50QXQoaW5kZXgpOwotICAgICAgZWxzZSBpZiAoT3BDb2Rlcy5FTEVNV0lMRENBUkQgPT0gaW5kZXgpCi0gICAgICAgIHJldHVybiBOb2RlVGVzdC5XSUxEOwotICAgICAgZWxzZQotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0gICAgZWxzZQotICAgICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBsb2NhbCBuYW1lIG9mIHRoZSBzdGVwLgotICAgKiBAcGFyYW0gb3BQb3NPZlN0ZXAgVGhlIHBvc2l0aW9uIG9mIHRoZSBGUk9NX1hYWCBzdGVwLgotICAgKgotICAgKiBAcmV0dXJuIE9wQ29kZXMuRU1QVFksIE9wQ29kZXMuRUxFTVdJTERDQVJELCBvciB0aGUgbG9jYWwgbmFtZS4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0U3RlcExvY2FsTmFtZShpbnQgb3BQb3NPZlN0ZXApCi0gIHsKLQotICAgIGludCBhcmdMZW5PZlN0ZXAgPSBnZXRBcmdMZW5ndGhPZlN0ZXAob3BQb3NPZlN0ZXApOwotCi0gICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJnZXRTdGVwTG9jYWxOYW1lLmFyZ0xlbk9mU3RlcDogIithcmdMZW5PZlN0ZXApOwotICAgIGludCBpbmRleDsKLQotICAgIHN3aXRjaCAoYXJnTGVuT2ZTdGVwKQotICAgIHsKLSAgICBjYXNlIDAgOgotICAgICAgaW5kZXggPSBPcENvZGVzLkVNUFRZOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSAxIDoKLSAgICAgIGluZGV4ID0gT3BDb2Rlcy5FTEVNV0lMRENBUkQ7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIDIgOgotICAgICAgaW5kZXggPSBtX29wTWFwLmVsZW1lbnRBdChvcFBvc09mU3RlcCArIDQpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSAzIDoKLSAgICAgIGluZGV4ID0gbV9vcE1hcC5lbGVtZW50QXQob3BQb3NPZlN0ZXAgKyA1KTsKLSAgICAgIGJyZWFrOwotICAgIGRlZmF1bHQgOgotICAgICAgaW5kZXggPSBPcENvZGVzLkVNUFRZOwotICAgICAgYnJlYWs7ICAvLyBTaG91bGQgYXNzZXJ0IGVycm9yCi0gICAgfQotCi0gICAgLy8gaW50IGluZGV4ID0gKGFyZ0xlbk9mU3RlcCA9PSAzKSA/IG1fb3BNYXBbb3BQb3NPZlN0ZXArNV0KLSAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6ICgoYXJnTGVuT2ZTdGVwID09IDEpID8gLTMgOiAtMik7Ci0gICAgaWYgKGluZGV4ID49IDApCi0gICAgICByZXR1cm4gKFN0cmluZykgbV90b2tlblF1ZXVlLmVsZW1lbnRBdChpbmRleCkudG9TdHJpbmcoKTsKLSAgICBlbHNlIGlmIChPcENvZGVzLkVMRU1XSUxEQ0FSRCA9PSBpbmRleCkKLSAgICAgIHJldHVybiBOb2RlVGVzdC5XSUxEOwotICAgIGVsc2UKLSAgICAgIHJldHVybiBudWxsOwotICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvY29tcGlsZXIvT3BNYXBWZWN0b3IuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvY29tcGlsZXIvT3BNYXBWZWN0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggN2NmYTg2ZS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2NvbXBpbGVyL09wTWFwVmVjdG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMTggKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMi0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogT3BNYXBWZWN0b3IuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xMCAwMzo1NzoxNCBqZWZmc3V0dG9yIEV4cCAkCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuY29tcGlsZXI7Ci0KLS8qKgotICoKLSAqIExpa2UgSW50VmVjdG9yLCBidXQgdXNlZCBvbmx5IGZvciB0aGUgT3BNYXAgYXJyYXkuICBMZW5ndGggb2YgYXJyYXkKLSAqIGlzIGtlcHQgaW4gdGhlIG1fbGVuZ3RoUG9zIHBvc2l0aW9uIG9mIHRoZSBhcnJheS4gIE9ubHkgdGhlIHJlcXVpcmVkIG1ldGhvZHMKLSAqIGFyZSBpbiBpbmNsdWRlZCBoZXJlLgotICogQHhzbC51c2FnZSBpbnRlcm5hbAotICovCi1wdWJsaWMgY2xhc3MgT3BNYXBWZWN0b3IgewotCi0gLyoqIFNpemUgb2YgYmxvY2tzIHRvIGFsbG9jYXRlICAgICAgICAgICovCi0gIHByb3RlY3RlZCBpbnQgbV9ibG9ja3NpemU7Ci0KLSAgLyoqIEFycmF5IG9mIGludHMgICAgICAgICAgKi8KLSAgcHJvdGVjdGVkIGludCBtX21hcFtdOyAvLyBJbnRTdGFjayBpcyB0cnlpbmcgdG8gc2VlIHRoaXMgZGlyZWN0bHkKLQotICAvKiogUG9zaXRpb24gd2hlcmUgc2l6ZSBvZiBhcnJheSBpcyBrZXB0ICAgICAgICAgICovCi0gIHByb3RlY3RlZCBpbnQgbV9sZW5ndGhQb3MgPSAwOwotCi0gIC8qKiBTaXplIG9mIGFycmF5ICAgICAgICAgICovCi0gIHByb3RlY3RlZCBpbnQgbV9tYXBTaXplOwotCi0gICAgLyoqCi0gICAqIENvbnN0cnVjdCBhIE9wTWFwVmVjdG9yLCB1c2luZyB0aGUgZ2l2ZW4gYmxvY2sgc2l6ZS4KLSAgICoKLSAgICogQHBhcmFtIGJsb2Nrc2l6ZSBTaXplIG9mIGJsb2NrIHRvIGFsbG9jYXRlCi0gICAqLwotICBwdWJsaWMgT3BNYXBWZWN0b3IoaW50IGJsb2Nrc2l6ZSwgaW50IGluY3JlYXNlU2l6ZSwgaW50IGxlbmd0aFBvcykKLSAgewotCi0gICAgbV9ibG9ja3NpemUgPSBpbmNyZWFzZVNpemU7Ci0gICAgbV9tYXBTaXplID0gYmxvY2tzaXplOwotICAgIG1fbGVuZ3RoUG9zID0gbGVuZ3RoUG9zOwotICAgIG1fbWFwID0gbmV3IGludFtibG9ja3NpemVdOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbnRoIGVsZW1lbnQuCi0gICAqCi0gICAqIEBwYXJhbSBpIGluZGV4IG9mIG9iamVjdCB0byBnZXQKLSAgICoKLSAgICogQHJldHVybiBvYmplY3QgYXQgZ2l2ZW4gaW5kZXgKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBpbnQgZWxlbWVudEF0KGludCBpKQotICB7Ci0gICAgcmV0dXJuIG1fbWFwW2ldOwotICB9Ci0KLSAgICAvKioKLSAgICogU2V0cyB0aGUgY29tcG9uZW50IGF0IHRoZSBzcGVjaWZpZWQgaW5kZXggb2YgdGhpcyB2ZWN0b3IgdG8gYmUgdGhlCi0gICAqIHNwZWNpZmllZCBvYmplY3QuIFRoZSBwcmV2aW91cyBjb21wb25lbnQgYXQgdGhhdCBwb3NpdGlvbiBpcyBkaXNjYXJkZWQuCi0gICAqCi0gICAqIFRoZSBpbmRleCBtdXN0IGJlIGEgdmFsdWUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIDAgYW5kIGxlc3MKLSAgICogdGhhbiB0aGUgY3VycmVudCBzaXplIG9mIHRoZSB2ZWN0b3IuCi0gICAqCi0gICAqIEBwYXJhbSB2YWx1ZSBvYmplY3QgdG8gc2V0Ci0gICAqIEBwYXJhbSBpbmRleCBJbmRleCBvZiB3aGVyZSB0byBzZXQgdGhlIG9iamVjdAotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgc2V0RWxlbWVudEF0KGludCB2YWx1ZSwgaW50IGluZGV4KQotICB7Ci0gICAgaWYgKGluZGV4ID49IG1fbWFwU2l6ZSkKLSAgICB7Ci0gICAgICBpbnQgb2xkU2l6ZSA9IG1fbWFwU2l6ZTsKLQotICAgICAgbV9tYXBTaXplICs9IG1fYmxvY2tzaXplOwotCi0gICAgICBpbnQgbmV3TWFwW10gPSBuZXcgaW50W21fbWFwU2l6ZV07Ci0KLSAgICAgIFN5c3RlbS5hcnJheWNvcHkobV9tYXAsIDAsIG5ld01hcCwgMCwgb2xkU2l6ZSk7Ci0KLSAgICAgIG1fbWFwID0gbmV3TWFwOwotICAgIH0KLQotICAgIG1fbWFwW2luZGV4XSA9IHZhbHVlOwotICB9Ci0KLQotICAvKgotICAgKiBSZXNldCB0aGUgYXJyYXkgdG8gdGhlIHN1cHBsaWVkIHNpemUuICBObyBjaGVja2luZyBpcyBkb25lLgotICAgKgotICAgKiBAcGFyYW0gc2l6ZSBUaGUgc2l6ZSB0byB0cmltIHRvLgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgc2V0VG9TaXplKGludCBzaXplKSB7Ci0KLSAgICBpbnQgbmV3TWFwW10gPSBuZXcgaW50W3NpemVdOwotCi0gICAgU3lzdGVtLmFycmF5Y29weShtX21hcCwgMCwgbmV3TWFwLCAwLCBtX21hcFttX2xlbmd0aFBvc10pOwotCi0gICAgbV9tYXBTaXplID0gc2l6ZTsKLSAgICBtX21hcCA9IG5ld01hcDsKLQotICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvY29tcGlsZXIvUHN1ZWRvTmFtZXMuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvY29tcGlsZXIvUHN1ZWRvTmFtZXMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZTYwM2NiZi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2NvbXBpbGVyL1BzdWVkb05hbWVzLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw2MSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBQc3VlZG9OYW1lcy5qYXZhLHYgMS4xLjIuMSAyMDA1LzA4LzAxIDAxOjMwOjMzIGplZmZzdXR0b3IgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuY29tcGlsZXI7Ci0KLS8qKgotICogVGhpcyBpcyB1c2VkIHRvIHJlcHJlc2VudCBuYW1lcyBvZiBub2RlcyB0aGF0IG1heSBub3QgYmUgbmFtZWQsIGxpa2UgYQotICogY29tbWVudCBub2RlLgotICovCi1wdWJsaWMgY2xhc3MgUHN1ZWRvTmFtZXMKLXsKLQotICAvKioKLSAgICogUHN1ZWRvIG5hbWUgZm9yIGEgd2lsZCBjYXJkIHBhdHRlcm4gKCcqJykuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBQU0VVRE9OQU1FX0FOWSA9ICIqIjsKLQotICAvKioKLSAgICogUHN1ZWRvIG5hbWUgZm9yIHRoZSByb290IG5vZGUuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBQU0VVRE9OQU1FX1JPT1QgPSAiLyI7Ci0KLSAgLyoqCi0gICAqIFBzdWVkbyBuYW1lIGZvciBhIHRleHQgbm9kZS4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFBTRVVET05BTUVfVEVYVCA9ICIjdGV4dCI7Ci0KLSAgLyoqCi0gICAqIFBzdWVkbyBuYW1lIGZvciBhIGNvbW1lbnQgbm9kZS4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFBTRVVET05BTUVfQ09NTUVOVCA9ICIjY29tbWVudCI7Ci0KLSAgLyoqCi0gICAqIFBzdWVkbyBuYW1lIGZvciBhIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gbm9kZS4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFBTRVVET05BTUVfUEkgPSAiI3BpIjsKLQotICAvKioKLSAgICogUHN1ZWRvIG5hbWUgZm9yIGFuIHVua25vd24gdHlwZSB2YWx1ZS4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFBTRVVET05BTUVfT1RIRVIgPSAiKiI7Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2NvbXBpbGVyL1hQYXRoRHVtcGVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2NvbXBpbGVyL1hQYXRoRHVtcGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGU1MjY2Y2IuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9jb21waWxlci9YUGF0aER1bXBlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzMgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogWFBhdGhEdW1wZXIuamF2YSx2IDEuMS4yLjEgMjAwNS8wOC8wMSAwMTozMDozMSBqZWZmc3V0dG9yIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmNvbXBpbGVyOwotCi0KLS8qKgotICogQ2xhc3MgZm9yIFhQYXRoIGRpYWdub3N0aWMgZnVuY3Rpb25zLgotICovCi1wdWJsaWMgY2xhc3MgWFBhdGhEdW1wZXIKLXsKLQotICAvLyBkZWxldGVkIGZvciB0aGUgdGltZSBiZWluZy4KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvY29tcGlsZXIvWFBhdGhQYXJzZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvY29tcGlsZXIvWFBhdGhQYXJzZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMWI1NTU5OS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2NvbXBpbGVyL1hQYXRoUGFyc2VyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyNDAzICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFhQYXRoUGFyc2VyLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTQgMTk6NDY6MDIgamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5jb21waWxlcjsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uRXJyb3JMaXN0ZW5lcjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnJlcy5YU0xNZXNzYWdlczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLlByZWZpeFJlc29sdmVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5YUGF0aFByb2Nlc3NvckV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuZG9tYXBpLlhQYXRoU3R5bGVzaGVldERPTTNFeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWE51bWJlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YU3RyaW5nOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5yZXMuWFBBVEhFcnJvclJlc291cmNlczsKLQotLyoqCi0gKiBUb2tlbml6ZXMgYW5kIHBhcnNlcyBYUGF0aCBleHByZXNzaW9ucy4gVGhpcyBzaG91bGQgcmVhbGx5IGJlIG5hbWVkCi0gKiBYUGF0aFBhcnNlckltcGwsIGFuZCBtYXkgYmUgcmVuYW1lZCBpbiB0aGUgZnV0dXJlLgotICogQHhzbC51c2FnZSBnZW5lcmFsCi0gKi8KLXB1YmxpYyBjbGFzcyBYUGF0aFBhcnNlcgotewotICAgICAgICAvLyAlUkVWSUVXJSBJcyB0aGVyZSBhIGJldHRlciB3YXkgb2YgZG9pbmcgdGhpcz8KLSAgICAgICAgLy8gVXBzaWRlIGlzIG1pbmltdW0gb2JqZWN0IGNodXJuLiBEb3duc2lkZSBpcyB0aGF0IHdlIGRvbid0IGhhdmUgYSB1c2VmdWwKLSAgICAgICAgLy8gYmFja3RyYWNlIGluIHRoZSBleGNlcHRpb24gaXRzZWxmIC0tIGJ1dCB3ZSBkb24ndCBleHBlY3QgdG8gbmVlZCBvbmUuCi0gICAgICAgIHN0YXRpYyBwdWJsaWMgZmluYWwgU3RyaW5nIENPTlRJTlVFX0FGVEVSX0ZBVEFMX0VSUk9SPSJDT05USU5VRV9BRlRFUl9GQVRBTF9FUlJPUiI7Ci0KLSAgLyoqCi0gICAqIFRoZSBYUGF0aCB0byBiZSBwcm9jZXNzZWQuCi0gICAqLwotICBwcml2YXRlIE9wTWFwIG1fb3BzOwotCi0gIC8qKgotICAgKiBUaGUgbmV4dCB0b2tlbiBpbiB0aGUgcGF0dGVybi4KLSAgICovCi0gIHRyYW5zaWVudCBTdHJpbmcgbV90b2tlbjsKLQotICAvKioKLSAgICogVGhlIGZpcnN0IGNoYXIgaW4gbV90b2tlbiwgdGhlIHRoZW9yeSBiZWluZyB0aGF0IHRoaXMKLSAgICogaXMgYW4gb3B0aW1pemF0aW9uIGJlY2F1c2Ugd2Ugd29uJ3QgaGF2ZSB0byBkbyBjaGFyQXQoMCkgYXMKLSAgICogb2Z0ZW4uCi0gICAqLwotICB0cmFuc2llbnQgY2hhciBtX3Rva2VuQ2hhciA9IDA7Ci0KLSAgLyoqCi0gICAqIFRoZSBwb3NpdGlvbiBpbiB0aGUgdG9rZW4gcXVldWUgaXMgdHJhY2tlZCBieSBtX3F1ZXVlTWFyay4KLSAgICovCi0gIGludCBtX3F1ZXVlTWFyayA9IDA7Ci0KLSAgLyoqCi0gICAqIFJlc3VsdHMgZnJvbSBjaGVja2luZyBGaWx0ZXJFeHByIHN5bnRheAotICAgKi8KLSAgcHJvdGVjdGVkIGZpbmFsIHN0YXRpYyBpbnQgRklMVEVSX01BVENIX0ZBSUxFRCAgICAgPSAwOwotICBwcm90ZWN0ZWQgZmluYWwgc3RhdGljIGludCBGSUxURVJfTUFUQ0hfUFJJTUFSWSAgICA9IDE7Ci0gIHByb3RlY3RlZCBmaW5hbCBzdGF0aWMgaW50IEZJTFRFUl9NQVRDSF9QUkVESUNBVEVTID0gMjsKLQotICAvKioKLSAgICogVGhlIHBhcnNlciBjb25zdHJ1Y3Rvci4KLSAgICovCi0gIHB1YmxpYyBYUGF0aFBhcnNlcihFcnJvckxpc3RlbmVyIGVycm9yTGlzdGVuZXIsIGphdmF4LnhtbC50cmFuc2Zvcm0uU291cmNlTG9jYXRvciBzb3VyY2VMb2NhdG9yKQotICB7Ci0gICAgbV9lcnJvckxpc3RlbmVyID0gZXJyb3JMaXN0ZW5lcjsKLSAgICBtX3NvdXJjZUxvY2F0b3IgPSBzb3VyY2VMb2NhdG9yOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoZSBwcmVmaXggcmVzb2x2ZXIgdG8gbWFwIHByZWZpeGVzIHRvIG5hbWVzcGFjZXMgaW4gdGhlIE9wTWFwLgotICAgKi8KLSAgUHJlZml4UmVzb2x2ZXIgbV9uYW1lc3BhY2VDb250ZXh0OwotCi0gIC8qKgotICAgKiBHaXZlbiBhbiBzdHJpbmcsIGluaXQgYW4gWFBhdGggb2JqZWN0IGZvciBzZWxlY3Rpb25zLAotICAgKiBpbiBvcmRlciB0aGF0IGEgcGFyc2UgZG9lc24ndAotICAgKiBoYXZlIHRvIGJlIGRvbmUgZWFjaCB0aW1lIHRoZSBleHByZXNzaW9uIGlzIGV2YWx1YXRlZC4KLSAgICoKLSAgICogQHBhcmFtIGNvbXBpbGVyIFRoZSBjb21waWxlciBvYmplY3QuCi0gICAqIEBwYXJhbSBleHByZXNzaW9uIEEgc3RyaW5nIGNvbmZvcm1pbmcgdG8gdGhlIFhQYXRoIGdyYW1tYXIuCi0gICAqIEBwYXJhbSBuYW1lc3BhY2VDb250ZXh0IEFuIG9iamVjdCB0aGF0IGlzIGFibGUgdG8gcmVzb2x2ZSBwcmVmaXhlcyBpbgotICAgKiB0aGUgWFBhdGggdG8gbmFtZXNwYWNlcy4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBpbml0WFBhdGgoCi0gICAgICAgICAgQ29tcGlsZXIgY29tcGlsZXIsIFN0cmluZyBleHByZXNzaW9uLCBQcmVmaXhSZXNvbHZlciBuYW1lc3BhY2VDb250ZXh0KQotICAgICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgbV9vcHMgPSBjb21waWxlcjsKLSAgICBtX25hbWVzcGFjZUNvbnRleHQgPSBuYW1lc3BhY2VDb250ZXh0OwotICAgIG1fZnVuY3Rpb25UYWJsZSA9IGNvbXBpbGVyLmdldEZ1bmN0aW9uVGFibGUoKTsKLQotICAgIExleGVyIGxleGVyID0gbmV3IExleGVyKGNvbXBpbGVyLCBuYW1lc3BhY2VDb250ZXh0LCB0aGlzKTsKLQotICAgIGxleGVyLnRva2VuaXplKGV4cHJlc3Npb24pOwotCi0gICAgbV9vcHMuc2V0T3AoMCxPcENvZGVzLk9QX1hQQVRIKTsKLSAgICBtX29wcy5zZXRPcChPcE1hcC5NQVBJTkRFWF9MRU5HVEgsMik7Ci0KLQotICAgICAgICAvLyBQYXRjaCBmb3IgQ2hyaXN0aW5lJ3MgZ3JpcGUuIFNoZSB3YW50cyBoZXIgZXJyb3JIYW5kbGVyIHRvIHJldHVybiBmcm9tCi0gICAgICAgIC8vIGEgZmF0YWwgZXJyb3IgYW5kIGNvbnRpbnVlIHRyeWluZyB0byBwYXJzZSwgcmF0aGVyIHRoYW4gdGhyb3dpbmcgYW4gZXhjZXB0aW9uLgotICAgICAgICAvLyBXaXRob3V0IHRoZSBwYXRjaCwgdGhhdCBwdXQgdXMgaW50byBhbiBlbmRsZXNzIGxvb3AuCi0gICAgICAgIC8vCi0gICAgICAgIC8vICVSRVZJRVclIElzIHRoZXJlIGEgYmV0dGVyIHdheSBvZiBkb2luZyB0aGlzPwotICAgICAgICAvLyAlUkVWSUVXJSBBcmUgdGhlcmUgYW55IG90aGVyIGNhc2VzIHdoaWNoIG5lZWQgdGhlIHNhZmV0eSBuZXQ/Ci0gICAgICAgIC8vICAgICAgKGFuZCBpZiBzbyBkbyB3ZSBjYXJlIHJpZ2h0IG5vdywgb3Igc2hvdWxkIHdlIHJld3JpdGUgdGhlIFhQYXRoCi0gICAgICAgIC8vICAgICAgZ3JhbW1hciBlbmdpbmUgYW5kIGNhbiBmaXggaXQgYXQgdGhhdCB0aW1lPykKLSAgICAgICAgdHJ5IHsKLQotICAgICAgbmV4dFRva2VuKCk7Ci0gICAgICBFeHByKCk7Ci0KLSAgICAgIGlmIChudWxsICE9IG1fdG9rZW4pCi0gICAgICB7Ci0gICAgICAgIFN0cmluZyBleHRyYVRva2VucyA9ICIiOwotCi0gICAgICAgIHdoaWxlIChudWxsICE9IG1fdG9rZW4pCi0gICAgICAgIHsKLSAgICAgICAgICBleHRyYVRva2VucyArPSAiJyIgKyBtX3Rva2VuICsgIiciOwotCi0gICAgICAgICAgbmV4dFRva2VuKCk7Ci0KLSAgICAgICAgICBpZiAobnVsbCAhPSBtX3Rva2VuKQotICAgICAgICAgICAgZXh0cmFUb2tlbnMgKz0gIiwgIjsKLSAgICAgICAgfQotCi0gICAgICAgIGVycm9yKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfRVhUUkFfSUxMRUdBTF9UT0tFTlMsCi0gICAgICAgICAgICAgIG5ldyBPYmplY3RbXXsgZXh0cmFUb2tlbnMgfSk7ICAvLyJFeHRyYSBpbGxlZ2FsIHRva2VuczogIitleHRyYVRva2Vucyk7Ci0gICAgICB9Ci0KLSAgICB9Ci0gICAgY2F0Y2ggKGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5YUGF0aFByb2Nlc3NvckV4Y2VwdGlvbiBlKQotICAgIHsKLSAgICAgICAgICBpZihDT05USU5VRV9BRlRFUl9GQVRBTF9FUlJPUi5lcXVhbHMoZS5nZXRNZXNzYWdlKCkpKQotICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAvLyBXaGF0IEkgX3dhbnRfIHRvIGRvIGlzIG51bGwgb3V0IHRoaXMgWFBhdGguCi0gICAgICAgICAgICAgICAgLy8gSSBkb3VidCB0aGlzIGhhcyB0aGUgZGVzaXJlZCBlZmZlY3QsIGJ1dCBJJ20gbm90IHN1cmUgd2hhdCBlbHNlIHRvIGRvLgotICAgICAgICAgICAgICAgIC8vICVSRVZJRVclISEhCi0gICAgICAgICAgICAgICAgaW5pdFhQYXRoKGNvbXBpbGVyLCAiLy4uIiwgIG5hbWVzcGFjZUNvbnRleHQpOwotICAgICAgICAgIH0KLSAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgdGhyb3cgZTsKLSAgICB9Ci0KLSAgICBjb21waWxlci5zaHJpbmsoKTsKLSAgfQotCi0gIC8qKgotICAgKiBHaXZlbiBhbiBzdHJpbmcsIGluaXQgYW4gWFBhdGggb2JqZWN0IGZvciBwYXR0ZXJuIG1hdGNoZXMsCi0gICAqIGluIG9yZGVyIHRoYXQgYSBwYXJzZSBkb2Vzbid0Ci0gICAqIGhhdmUgdG8gYmUgZG9uZSBlYWNoIHRpbWUgdGhlIGV4cHJlc3Npb24gaXMgZXZhbHVhdGVkLgotICAgKiBAcGFyYW0gY29tcGlsZXIgVGhlIFhQYXRoIG9iamVjdCB0byBiZSBpbml0aWFsaXplZC4KLSAgICogQHBhcmFtIGV4cHJlc3Npb24gQSBTdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBYUGF0aC4KLSAgICogQHBhcmFtIG5hbWVzcGFjZUNvbnRleHQgQW4gb2JqZWN0IHRoYXQgaXMgYWJsZSB0byByZXNvbHZlIHByZWZpeGVzIGluCi0gICAqIHRoZSBYUGF0aCB0byBuYW1lc3BhY2VzLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGluaXRNYXRjaFBhdHRlcm4oCi0gICAgICAgICAgQ29tcGlsZXIgY29tcGlsZXIsIFN0cmluZyBleHByZXNzaW9uLCBQcmVmaXhSZXNvbHZlciBuYW1lc3BhY2VDb250ZXh0KQotICAgICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgbV9vcHMgPSBjb21waWxlcjsKLSAgICBtX25hbWVzcGFjZUNvbnRleHQgPSBuYW1lc3BhY2VDb250ZXh0OwotICAgIG1fZnVuY3Rpb25UYWJsZSA9IGNvbXBpbGVyLmdldEZ1bmN0aW9uVGFibGUoKTsKLQotICAgIExleGVyIGxleGVyID0gbmV3IExleGVyKGNvbXBpbGVyLCBuYW1lc3BhY2VDb250ZXh0LCB0aGlzKTsKLQotICAgIGxleGVyLnRva2VuaXplKGV4cHJlc3Npb24pOwotCi0gICAgbV9vcHMuc2V0T3AoMCwgT3BDb2Rlcy5PUF9NQVRDSFBBVFRFUk4pOwotICAgIG1fb3BzLnNldE9wKE9wTWFwLk1BUElOREVYX0xFTkdUSCwgMik7Ci0KLSAgICBuZXh0VG9rZW4oKTsKLSAgICBQYXR0ZXJuKCk7Ci0KLSAgICBpZiAobnVsbCAhPSBtX3Rva2VuKQotICAgIHsKLSAgICAgIFN0cmluZyBleHRyYVRva2VucyA9ICIiOwotCi0gICAgICB3aGlsZSAobnVsbCAhPSBtX3Rva2VuKQotICAgICAgewotICAgICAgICBleHRyYVRva2VucyArPSAiJyIgKyBtX3Rva2VuICsgIiciOwotCi0gICAgICAgIG5leHRUb2tlbigpOwotCi0gICAgICAgIGlmIChudWxsICE9IG1fdG9rZW4pCi0gICAgICAgICAgZXh0cmFUb2tlbnMgKz0gIiwgIjsKLSAgICAgIH0KLQotICAgICAgZXJyb3IoWFBBVEhFcnJvclJlc291cmNlcy5FUl9FWFRSQV9JTExFR0FMX1RPS0VOUywKLSAgICAgICAgICAgIG5ldyBPYmplY3RbXXsgZXh0cmFUb2tlbnMgfSk7ICAvLyJFeHRyYSBpbGxlZ2FsIHRva2VuczogIitleHRyYVRva2Vucyk7Ci0gICAgfQotCi0gICAgLy8gVGVybWluYXRlIGZvciBzYWZldHkuCi0gICAgbV9vcHMuc2V0T3AobV9vcHMuZ2V0T3AoT3BNYXAuTUFQSU5ERVhfTEVOR1RIKSwgT3BDb2Rlcy5FTkRPUCk7Ci0gICAgbV9vcHMuc2V0T3AoT3BNYXAuTUFQSU5ERVhfTEVOR1RILCBtX29wcy5nZXRPcChPcE1hcC5NQVBJTkRFWF9MRU5HVEgpKzEpOwotCi0gICAgbV9vcHMuc2hyaW5rKCk7Ci0gIH0KLQotICAvKiogVGhlIGVycm9yIGxpc3RlbmVyIHdoZXJlIHN5bnRheCBlcnJvcnMgYXJlIHRvIGJlIHNlbnQuCi0gICAqLwotICBwcml2YXRlIEVycm9yTGlzdGVuZXIgbV9lcnJvckxpc3RlbmVyOwotCi0gIC8qKiBUaGUgc291cmNlIGxvY2F0aW9uIG9mIHRoZSBYUGF0aC4gKi8KLSAgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2VMb2NhdG9yIG1fc291cmNlTG9jYXRvcjsKLQotICAvKiogVGhlIHRhYmxlIGNvbnRhaW5zIGJ1aWxkLWluIGZ1bmN0aW9ucyBhbmQgY3VzdG9taXplZCBmdW5jdGlvbnMgKi8KLSAgcHJpdmF0ZSBGdW5jdGlvblRhYmxlIG1fZnVuY3Rpb25UYWJsZTsKLQotICAvKioKLSAgICogQWxsb3cgYW4gYXBwbGljYXRpb24gdG8gcmVnaXN0ZXIgYW4gZXJyb3IgZXZlbnQgaGFuZGxlciwgd2hlcmUgc3ludGF4Ci0gICAqIGVycm9ycyB3aWxsIGJlIHNlbnQuICBJZiB0aGUgZXJyb3IgbGlzdGVuZXIgaXMgbm90IHNldCwgc3ludGF4IGVycm9ycwotICAgKiB3aWxsIGJlIHNlbnQgdG8gU3lzdGVtLmVyci4KLSAgICoKLSAgICogQHBhcmFtIGhhbmRsZXIgUmVmZXJlbmNlIHRvIGVycm9yIGxpc3RlbmVyIHdoZXJlIHN5bnRheCBlcnJvcnMgd2lsbCBiZQotICAgKiAgICAgICAgICAgICAgICBzZW50LgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0RXJyb3JIYW5kbGVyKEVycm9yTGlzdGVuZXIgaGFuZGxlcikKLSAgewotICAgIG1fZXJyb3JMaXN0ZW5lciA9IGhhbmRsZXI7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBjdXJyZW50IGVycm9yIGxpc3RlbmVyLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBlcnJvciBsaXN0ZW5lciwgd2hpY2ggc2hvdWxkIG5vdCBub3JtYWxseSBiZSBudWxsLCBidXQgbWF5IGJlLgotICAgKi8KLSAgcHVibGljIEVycm9yTGlzdGVuZXIgZ2V0RXJyb3JMaXN0ZW5lcigpCi0gIHsKLSAgICByZXR1cm4gbV9lcnJvckxpc3RlbmVyOwotICB9Ci0KLSAgLyoqCi0gICAqIENoZWNrIHdoZXRoZXIgbV90b2tlbiBtYXRjaGVzIHRoZSB0YXJnZXQgc3RyaW5nLgotICAgKgotICAgKiBAcGFyYW0gcyBBIHN0cmluZyByZWZlcmVuY2Ugb3IgbnVsbC4KLSAgICoKLSAgICogQHJldHVybiBJZiBtX3Rva2VuIGlzIG51bGwsIHJldHVybnMgZmFsc2UgKG9yIHRydWUgaWYgcyBpcyBhbHNvIG51bGwpLCBvcgotICAgKiByZXR1cm4gdHJ1ZSBpZiB0aGUgY3VycmVudCB0b2tlbiBtYXRjaGVzIHRoZSBzdHJpbmcsIGVsc2UgZmFsc2UuCi0gICAqLwotICBmaW5hbCBib29sZWFuIHRva2VuSXMoU3RyaW5nIHMpCi0gIHsKLSAgICByZXR1cm4gKG1fdG9rZW4gIT0gbnVsbCkgPyAobV90b2tlbi5lcXVhbHMocykpIDogKHMgPT0gbnVsbCk7Ci0gIH0KLQotICAvKioKLSAgICogQ2hlY2sgd2hldGhlciBtX3Rva2VuQ2hhcj09Yy4KLSAgICoKLSAgICogQHBhcmFtIGMgQSBjaGFyYWN0ZXIgdG8gYmUgdGVzdGVkLgotICAgKgotICAgKiBAcmV0dXJuIElmIG1fdG9rZW4gaXMgbnVsbCwgcmV0dXJucyBmYWxzZSwgb3IgcmV0dXJuIHRydWUgaWYgYyBtYXRjaGVzCi0gICAqICAgICAgICAgdGhlIGN1cnJlbnQgdG9rZW4uCi0gICAqLwotICBmaW5hbCBib29sZWFuIHRva2VuSXMoY2hhciBjKQotICB7Ci0gICAgcmV0dXJuIChtX3Rva2VuICE9IG51bGwpID8gKG1fdG9rZW5DaGFyID09IGMpIDogZmFsc2U7Ci0gIH0KLQotICAvKioKLSAgICogTG9vayBhaGVhZCBvZiB0aGUgY3VycmVudCB0b2tlbiBpbiBvcmRlciB0bwotICAgKiBtYWtlIGEgYnJhbmNoaW5nIGRlY2lzaW9uLgotICAgKgotICAgKiBAcGFyYW0gYyB0aGUgY2hhcmFjdGVyIHRvIGJlIHRlc3RlZCBmb3IuCi0gICAqIEBwYXJhbSBuIG51bWJlciBvZiB0b2tlbnMgdG8gbG9vayBhaGVhZC4gIE11c3QgYmUKLSAgICogZ3JlYXRlciB0aGFuIDEuCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgbmV4dCB0b2tlbiBtYXRjaGVzIHRoZSBjaGFyYWN0ZXIgYXJndW1lbnQuCi0gICAqLwotICBmaW5hbCBib29sZWFuIGxvb2thaGVhZChjaGFyIGMsIGludCBuKQotICB7Ci0KLSAgICBpbnQgcG9zID0gKG1fcXVldWVNYXJrICsgbik7Ci0gICAgYm9vbGVhbiBiOwotCi0gICAgaWYgKChwb3MgPD0gbV9vcHMuZ2V0VG9rZW5RdWV1ZVNpemUoKSkgJiYgKHBvcyA+IDApCi0gICAgICAgICAgICAmJiAobV9vcHMuZ2V0VG9rZW5RdWV1ZVNpemUoKSAhPSAwKSkKLSAgICB7Ci0gICAgICBTdHJpbmcgdG9rID0gKChTdHJpbmcpIG1fb3BzLm1fdG9rZW5RdWV1ZS5lbGVtZW50QXQocG9zIC0gMSkpOwotCi0gICAgICBiID0gKHRvay5sZW5ndGgoKSA9PSAxKSA/ICh0b2suY2hhckF0KDApID09IGMpIDogZmFsc2U7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBiID0gZmFsc2U7Ci0gICAgfQotCi0gICAgcmV0dXJuIGI7Ci0gIH0KLQotICAvKioKLSAgICogTG9vayBiZWhpbmQgdGhlIGZpcnN0IGNoYXJhY3RlciBvZiB0aGUgY3VycmVudCB0b2tlbiBpbiBvcmRlciB0bwotICAgKiBtYWtlIGEgYnJhbmNoaW5nIGRlY2lzaW9uLgotICAgKgotICAgKiBAcGFyYW0gYyB0aGUgY2hhcmFjdGVyIHRvIGNvbXBhcmUgaXQgdG8uCi0gICAqIEBwYXJhbSBuIG51bWJlciBvZiB0b2tlbnMgdG8gbG9vayBiZWhpbmQuICBNdXN0IGJlCi0gICAqIGdyZWF0ZXIgdGhhbiAxLiAgTm90ZSB0aGF0IHRoZSBsb29rIGJlaGluZCB0ZXJtaW5hdGVzCi0gICAqIGF0IGVpdGhlciB0aGUgYmVnaW5uaW5nIG9mIHRoZSBzdHJpbmcgb3Igb24gYSAnfCcKLSAgICogY2hhcmFjdGVyLiAgQmVjYXVzZSBvZiB0aGlzLCB0aGlzIG1ldGhvZCBzaG91bGQgb25seQotICAgKiBiZSB1c2VkIGZvciBwYXR0ZXJuIG1hdGNoaW5nLgotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHRva2VuIGJlaGluZCB0aGUgY3VycmVudCB0b2tlbiBtYXRjaGVzIHRoZSBjaGFyYWN0ZXIKLSAgICogICAgICAgICBhcmd1bWVudC4KLSAgICovCi0gIHByaXZhdGUgZmluYWwgYm9vbGVhbiBsb29rYmVoaW5kKGNoYXIgYywgaW50IG4pCi0gIHsKLQotICAgIGJvb2xlYW4gaXNUb2tlbjsKLSAgICBpbnQgbG9va0JlaGluZFBvcyA9IG1fcXVldWVNYXJrIC0gKG4gKyAxKTsKLQotICAgIGlmIChsb29rQmVoaW5kUG9zID49IDApCi0gICAgewotICAgICAgU3RyaW5nIGxvb2tiZWhpbmQgPSAoU3RyaW5nKSBtX29wcy5tX3Rva2VuUXVldWUuZWxlbWVudEF0KGxvb2tCZWhpbmRQb3MpOwotCi0gICAgICBpZiAobG9va2JlaGluZC5sZW5ndGgoKSA9PSAxKQotICAgICAgewotICAgICAgICBjaGFyIGMwID0gKGxvb2tiZWhpbmQgPT0gbnVsbCkgPyAnfCcgOiBsb29rYmVoaW5kLmNoYXJBdCgwKTsKLQotICAgICAgICBpc1Rva2VuID0gKGMwID09ICd8JykgPyBmYWxzZSA6IChjMCA9PSBjKTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgaXNUb2tlbiA9IGZhbHNlOwotICAgICAgfQotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgaXNUb2tlbiA9IGZhbHNlOwotICAgIH0KLQotICAgIHJldHVybiBpc1Rva2VuOwotICB9Ci0KLSAgLyoqCi0gICAqIGxvb2sgYmVoaW5kIHRoZSBjdXJyZW50IHRva2VuIGluIG9yZGVyIHRvCi0gICAqIHNlZSBpZiB0aGVyZSBpcyBhIHVzZWFibGUgdG9rZW4uCi0gICAqCi0gICAqIEBwYXJhbSBuIG51bWJlciBvZiB0b2tlbnMgdG8gbG9vayBiZWhpbmQuICBNdXN0IGJlCi0gICAqIGdyZWF0ZXIgdGhhbiAxLiAgTm90ZSB0aGF0IHRoZSBsb29rIGJlaGluZCB0ZXJtaW5hdGVzCi0gICAqIGF0IGVpdGhlciB0aGUgYmVnaW5uaW5nIG9mIHRoZSBzdHJpbmcgb3Igb24gYSAnfCcKLSAgICogY2hhcmFjdGVyLiAgQmVjYXVzZSBvZiB0aGlzLCB0aGlzIG1ldGhvZCBzaG91bGQgb25seQotICAgKiBiZSB1c2VkIGZvciBwYXR0ZXJuIG1hdGNoaW5nLgotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYgbG9vayBiZWhpbmQgaGFzIGEgdG9rZW4sIGZhbHNlIG90aGVyd2lzZS4KLSAgICovCi0gIHByaXZhdGUgZmluYWwgYm9vbGVhbiBsb29rYmVoaW5kSGFzVG9rZW4oaW50IG4pCi0gIHsKLQotICAgIGJvb2xlYW4gaGFzVG9rZW47Ci0KLSAgICBpZiAoKG1fcXVldWVNYXJrIC0gbikgPiAwKQotICAgIHsKLSAgICAgIFN0cmluZyBsb29rYmVoaW5kID0gKFN0cmluZykgbV9vcHMubV90b2tlblF1ZXVlLmVsZW1lbnRBdChtX3F1ZXVlTWFyayAtIChuIC0gMSkpOwotICAgICAgY2hhciBjMCA9IChsb29rYmVoaW5kID09IG51bGwpID8gJ3wnIDogbG9va2JlaGluZC5jaGFyQXQoMCk7Ci0KLSAgICAgIGhhc1Rva2VuID0gKGMwID09ICd8JykgPyBmYWxzZSA6IHRydWU7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBoYXNUb2tlbiA9IGZhbHNlOwotICAgIH0KLQotICAgIHJldHVybiBoYXNUb2tlbjsKLSAgfQotCi0gIC8qKgotICAgKiBMb29rIGFoZWFkIG9mIHRoZSBjdXJyZW50IHRva2VuIGluIG9yZGVyIHRvCi0gICAqIG1ha2UgYSBicmFuY2hpbmcgZGVjaXNpb24uCi0gICAqCi0gICAqIEBwYXJhbSBzIHRoZSBzdHJpbmcgdG8gY29tcGFyZSBpdCB0by4KLSAgICogQHBhcmFtIG4gbnVtYmVyIG9mIHRva2VucyB0byBsb29rYWhlYWQuICBNdXN0IGJlCi0gICAqIGdyZWF0ZXIgdGhhbiAxLgotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHRva2VuIGJlaGluZCB0aGUgY3VycmVudCB0b2tlbiBtYXRjaGVzIHRoZSBzdHJpbmcKLSAgICogICAgICAgICBhcmd1bWVudC4KLSAgICovCi0gIHByaXZhdGUgZmluYWwgYm9vbGVhbiBsb29rYWhlYWQoU3RyaW5nIHMsIGludCBuKQotICB7Ci0KLSAgICBib29sZWFuIGlzVG9rZW47Ci0KLSAgICBpZiAoKG1fcXVldWVNYXJrICsgbikgPD0gbV9vcHMuZ2V0VG9rZW5RdWV1ZVNpemUoKSkKLSAgICB7Ci0gICAgICBTdHJpbmcgbG9va2FoZWFkID0gKFN0cmluZykgbV9vcHMubV90b2tlblF1ZXVlLmVsZW1lbnRBdChtX3F1ZXVlTWFyayArIChuIC0gMSkpOwotCi0gICAgICBpc1Rva2VuID0gKGxvb2thaGVhZCAhPSBudWxsKSA/IGxvb2thaGVhZC5lcXVhbHMocykgOiAocyA9PSBudWxsKTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIGlzVG9rZW4gPSAobnVsbCA9PSBzKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gaXNUb2tlbjsKLSAgfQotCi0gIC8qKgotICAgKiBSZXRyaWV2ZSB0aGUgbmV4dCB0b2tlbiBmcm9tIHRoZSBjb21tYW5kIGFuZAotICAgKiBzdG9yZSBpdCBpbiBtX3Rva2VuIHN0cmluZy4KLSAgICovCi0gIHByaXZhdGUgZmluYWwgdm9pZCBuZXh0VG9rZW4oKQotICB7Ci0KLSAgICBpZiAobV9xdWV1ZU1hcmsgPCBtX29wcy5nZXRUb2tlblF1ZXVlU2l6ZSgpKQotICAgIHsKLSAgICAgIG1fdG9rZW4gPSAoU3RyaW5nKSBtX29wcy5tX3Rva2VuUXVldWUuZWxlbWVudEF0KG1fcXVldWVNYXJrKyspOwotICAgICAgbV90b2tlbkNoYXIgPSBtX3Rva2VuLmNoYXJBdCgwKTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIG1fdG9rZW4gPSBudWxsOwotICAgICAgbV90b2tlbkNoYXIgPSAwOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBSZXRyaWV2ZSBhIHRva2VuIHJlbGF0aXZlIHRvIHRoZSBjdXJyZW50IHRva2VuLgotICAgKgotICAgKiBAcGFyYW0gaSBQb3NpdGlvbiByZWxhdGl2ZSB0byBjdXJyZW50IHRva2VuLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBzdHJpbmcgYXQgdGhlIGdpdmVuIGluZGV4LCBvciBudWxsIGlmIHRoZSBpbmRleCBpcyBvdXQKLSAgICogICAgICAgICBvZiByYW5nZS4KLSAgICovCi0gIHByaXZhdGUgZmluYWwgU3RyaW5nIGdldFRva2VuUmVsYXRpdmUoaW50IGkpCi0gIHsKLQotICAgIFN0cmluZyB0b2s7Ci0gICAgaW50IHJlbGF0aXZlID0gbV9xdWV1ZU1hcmsgKyBpOwotCi0gICAgaWYgKChyZWxhdGl2ZSA+IDApICYmIChyZWxhdGl2ZSA8IG1fb3BzLmdldFRva2VuUXVldWVTaXplKCkpKQotICAgIHsKLSAgICAgIHRvayA9IChTdHJpbmcpIG1fb3BzLm1fdG9rZW5RdWV1ZS5lbGVtZW50QXQocmVsYXRpdmUpOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgdG9rID0gbnVsbDsKLSAgICB9Ci0KLSAgICByZXR1cm4gdG9rOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHJpZXZlIHRoZSBwcmV2aW91cyB0b2tlbiBmcm9tIHRoZSBjb21tYW5kIGFuZAotICAgKiBzdG9yZSBpdCBpbiBtX3Rva2VuIHN0cmluZy4KLSAgICovCi0gIHByaXZhdGUgZmluYWwgdm9pZCBwcmV2VG9rZW4oKQotICB7Ci0KLSAgICBpZiAobV9xdWV1ZU1hcmsgPiAwKQotICAgIHsKLSAgICAgIG1fcXVldWVNYXJrLS07Ci0KLSAgICAgIG1fdG9rZW4gPSAoU3RyaW5nKSBtX29wcy5tX3Rva2VuUXVldWUuZWxlbWVudEF0KG1fcXVldWVNYXJrKTsKLSAgICAgIG1fdG9rZW5DaGFyID0gbV90b2tlbi5jaGFyQXQoMCk7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBtX3Rva2VuID0gbnVsbDsKLSAgICAgIG1fdG9rZW5DaGFyID0gMDsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3VtZSBhbiBleHBlY3RlZCB0b2tlbiwgdGhyb3dpbmcgYW4gZXhjZXB0aW9uIGlmIGl0Ci0gICAqIGlzbid0IHRoZXJlLgotICAgKgotICAgKiBAcGFyYW0gZXhwZWN0ZWQgVGhlIHN0cmluZyB0byBiZSBleHBlY3RlZC4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwcml2YXRlIGZpbmFsIHZvaWQgY29uc3VtZUV4cGVjdGVkKFN0cmluZyBleHBlY3RlZCkKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAodG9rZW5JcyhleHBlY3RlZCkpCi0gICAgewotICAgICAgbmV4dFRva2VuKCk7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBlcnJvcihYUEFUSEVycm9yUmVzb3VyY2VzLkVSX0VYUEVDVEVEX0JVVF9GT1VORCwgbmV3IE9iamVjdFtdeyBleHBlY3RlZCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fdG9rZW4gfSk7ICAvLyJFeHBlY3RlZCAiK2V4cGVjdGVkKyIsIGJ1dCBmb3VuZDogIittX3Rva2VuKTsKLQotICAgICAgICAgIC8vIFBhdGNoIGZvciBDaHJpc3RpbmEncyBncmlwZS4gU2hlIHdhbnRzIGhlciBlcnJvckhhbmRsZXIgdG8gcmV0dXJuIGZyb20KLSAgICAgICAgICAvLyB0aGlzIGVycm9yIGFuZCBjb250aW51ZSB0cnlpbmcgdG8gcGFyc2UsIHJhdGhlciB0aGFuIHRocm93aW5nIGFuIGV4Y2VwdGlvbi4KLSAgICAgICAgICAvLyBXaXRob3V0IHRoZSBwYXRjaCwgdGhhdCBwdXQgdXMgaW50byBhbiBlbmRsZXNzIGxvb3AuCi0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFhQYXRoUHJvY2Vzc29yRXhjZXB0aW9uKENPTlRJTlVFX0FGVEVSX0ZBVEFMX0VSUk9SKTsKLSAgICAgICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIENvbnN1bWUgYW4gZXhwZWN0ZWQgdG9rZW4sIHRocm93aW5nIGFuIGV4Y2VwdGlvbiBpZiBpdAotICAgKiBpc24ndCB0aGVyZS4KLSAgICoKLSAgICogQHBhcmFtIGV4cGVjdGVkIHRoZSBjaGFyYWN0ZXIgdG8gYmUgZXhwZWN0ZWQuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHJpdmF0ZSBmaW5hbCB2b2lkIGNvbnN1bWVFeHBlY3RlZChjaGFyIGV4cGVjdGVkKQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmICh0b2tlbklzKGV4cGVjdGVkKSkKLSAgICB7Ci0gICAgICBuZXh0VG9rZW4oKTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIGVycm9yKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfRVhQRUNURURfQlVUX0ZPVU5ELAotICAgICAgICAgICAgbmV3IE9iamVjdFtdeyBTdHJpbmcudmFsdWVPZihleHBlY3RlZCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgIG1fdG9rZW4gfSk7ICAvLyJFeHBlY3RlZCAiK2V4cGVjdGVkKyIsIGJ1dCBmb3VuZDogIittX3Rva2VuKTsKLQotICAgICAgICAgIC8vIFBhdGNoIGZvciBDaHJpc3RpbmEncyBncmlwZS4gU2hlIHdhbnRzIGhlciBlcnJvckhhbmRsZXIgdG8gcmV0dXJuIGZyb20KLSAgICAgICAgICAvLyB0aGlzIGVycm9yIGFuZCBjb250aW51ZSB0cnlpbmcgdG8gcGFyc2UsIHJhdGhlciB0aGFuIHRocm93aW5nIGFuIGV4Y2VwdGlvbi4KLSAgICAgICAgICAvLyBXaXRob3V0IHRoZSBwYXRjaCwgdGhhdCBwdXQgdXMgaW50byBhbiBlbmRsZXNzIGxvb3AuCi0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFhQYXRoUHJvY2Vzc29yRXhjZXB0aW9uKENPTlRJTlVFX0FGVEVSX0ZBVEFMX0VSUk9SKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogV2FybiB0aGUgdXNlciBvZiBhIHByb2JsZW0uCi0gICAqCi0gICAqIEBwYXJhbSBtc2cgQW4gZXJyb3IgbXNna2V5IHRoYXQgY29ycmVzcG9uZHMgdG8gb25lIG9mIHRoZSBjb25zdGFudHMgZm91bmQKLSAgICogICAgICAgICAgICBpbiB7QGxpbmsgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLnJlcy5YUEFUSEVycm9yUmVzb3VyY2VzfSwgd2hpY2ggaXMKLSAgICogICAgICAgICAgICBhIGtleSBmb3IgYSBmb3JtYXQgc3RyaW5nLgotICAgKiBAcGFyYW0gYXJncyBBbiBhcnJheSBvZiBhcmd1bWVudHMgcmVwcmVzZW50ZWQgaW4gdGhlIGZvcm1hdCBzdHJpbmcsIHdoaWNoCi0gICAqICAgICAgICAgICAgIG1heSBiZSBudWxsLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uIGlmIHRoZSBjdXJyZW50IEVycm9yTGlzdG9uZXIgZGV0ZXJtaW5lcyB0bwotICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGFuIGV4Y2VwdGlvbi4KLSAgICovCi0gIHZvaWQgd2FybihTdHJpbmcgbXNnLCBPYmplY3RbXSBhcmdzKSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgU3RyaW5nIGZtc2cgPSBYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSFdhcm5pbmcobXNnLCBhcmdzKTsKLSAgICBFcnJvckxpc3RlbmVyIGVoYW5kbGVyID0gdGhpcy5nZXRFcnJvckxpc3RlbmVyKCk7Ci0KLSAgICBpZiAobnVsbCAhPSBlaGFuZGxlcikKLSAgICB7Ci0gICAgICAvLyBUTyBETzogTmVlZCB0byBnZXQgc3R5bGVzaGVldCBMb2NhdG9yIGZyb20gaGVyZS4KLSAgICAgIGVoYW5kbGVyLndhcm5pbmcobmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKGZtc2csIG1fc291cmNlTG9jYXRvcikpOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgLy8gU2hvdWxkIG5ldmVyIGhhcHBlbi4KLSAgICAgIFN5c3RlbS5lcnIucHJpbnRsbihmbXNnKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogTm90aWZ5IHRoZSB1c2VyIG9mIGFuIGFzc2VydGlvbiBlcnJvciwgYW5kIHByb2JhYmx5IHRocm93IGFuCi0gICAqIGV4Y2VwdGlvbi4KLSAgICoKLSAgICogQHBhcmFtIGIgIElmIGZhbHNlLCBhIHJ1bnRpbWUgZXhjZXB0aW9uIHdpbGwgYmUgdGhyb3duLgotICAgKiBAcGFyYW0gbXNnIFRoZSBhc3NlcnRpb24gbWVzc2FnZSwgd2hpY2ggc2hvdWxkIGJlIGluZm9ybWF0aXZlLgotICAgKgotICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gaWYgdGhlIGIgYXJndW1lbnQgaXMgZmFsc2UuCi0gICAqLwotICBwcml2YXRlIHZvaWQgYXNzZXJ0aW9uKGJvb2xlYW4gYiwgU3RyaW5nIG1zZykKLSAgewotCi0gICAgaWYgKCFiKQotICAgIHsKLSAgICAgIFN0cmluZyBmTXNnID0gWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKAotICAgICAgICBYUEFUSEVycm9yUmVzb3VyY2VzLkVSX0lOQ09SUkVDVF9QUk9HUkFNTUVSX0FTU0VSVElPTiwKLSAgICAgICAgbmV3IE9iamVjdFtdeyBtc2cgfSk7Ci0KLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGZNc2cpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBOb3RpZnkgdGhlIHVzZXIgb2YgYW4gZXJyb3IsIGFuZCBwcm9iYWJseSB0aHJvdyBhbgotICAgKiBleGNlcHRpb24uCi0gICAqCi0gICAqIEBwYXJhbSBtc2cgQW4gZXJyb3IgbXNna2V5IHRoYXQgY29ycmVzcG9uZHMgdG8gb25lIG9mIHRoZSBjb25zdGFudHMgZm91bmQKLSAgICogICAgICAgICAgICBpbiB7QGxpbmsgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLnJlcy5YUEFUSEVycm9yUmVzb3VyY2VzfSwgd2hpY2ggaXMKLSAgICogICAgICAgICAgICBhIGtleSBmb3IgYSBmb3JtYXQgc3RyaW5nLgotICAgKiBAcGFyYW0gYXJncyBBbiBhcnJheSBvZiBhcmd1bWVudHMgcmVwcmVzZW50ZWQgaW4gdGhlIGZvcm1hdCBzdHJpbmcsIHdoaWNoCi0gICAqICAgICAgICAgICAgIG1heSBiZSBudWxsLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uIGlmIHRoZSBjdXJyZW50IEVycm9yTGlzdG9uZXIgZGV0ZXJtaW5lcyB0bwotICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGFuIGV4Y2VwdGlvbi4KLSAgICovCi0gIHZvaWQgZXJyb3IoU3RyaW5nIG1zZywgT2JqZWN0W10gYXJncykgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIFN0cmluZyBmbXNnID0gWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKG1zZywgYXJncyk7Ci0gICAgRXJyb3JMaXN0ZW5lciBlaGFuZGxlciA9IHRoaXMuZ2V0RXJyb3JMaXN0ZW5lcigpOwotCi0gICAgVHJhbnNmb3JtZXJFeGNlcHRpb24gdGUgPSBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oZm1zZywgbV9zb3VyY2VMb2NhdG9yKTsKLSAgICBpZiAobnVsbCAhPSBlaGFuZGxlcikKLSAgICB7Ci0gICAgICAvLyBUTyBETzogTmVlZCB0byBnZXQgc3R5bGVzaGVldCBMb2NhdG9yIGZyb20gaGVyZS4KLSAgICAgIGVoYW5kbGVyLmZhdGFsRXJyb3IodGUpOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgLy8gU3lzdGVtLmVyci5wcmludGxuKGZtc2cpOwotICAgICAgdGhyb3cgdGU7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFRoaXMgbWV0aG9kIGlzIGFkZGVkIHRvIHN1cHBvcnQgRE9NIDMgWFBhdGggQVBJLgotICAgKiA8cD4KLSAgICogVGhpcyBtZXRob2QgaXMgZXhhY3RseSBsaWtlIGVycm9yKFN0cmluZywgT2JqZWN0W10pOyBleGNlcHQgdGhhdAotICAgKiB0aGUgdW5kZXJseWluZyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBpcwotICAgKiBYcGF0aFN0eWxlc2hlZXRET00zRXhjZXB0aW9uICh3aGljaCBleHRlbmRzIFRyYW5zZm9ybWVyRXhjZXB0aW9uKS4KLSAgICogPHA+Ci0gICAqIFNvIG9sZGVyIFhQYXRoIGNvZGUgaW4gWGFsYW4gaXMgbm90IGFmZmVjdGVkIGJ5IHRoaXMuIFRvIG9sZGVyIFhQYXRoIGNvZGUKLSAgICogdGhlIGJlaGF2aW9yIG9mIHdoZXRoZXIgZXJyb3IoKSBvciBlcnJvckZvckRPTTMoKSBpcyBjYWxsZWQgYmVjYXVzZSBpdCBpcwotICAgKiBhbHdheXMgY2F0Y2hpbmcgVHJhbnNmb3JtZXJFeGNlcHRpb24gb2JqZWN0cyBhbmQgaXMgb2JsaXZpb3VzIHRvCi0gICAqIHRoZSBuZXcgc3ViY2xhc3Mgb2YgWFBhdGhTdHlsZXNoZWV0RE9NM0V4Y2VwdGlvbi4gT2xkZXIgWFBhdGggY29kZQotICAgKiBydW5zIGFzIGJlZm9yZS4KLSAgICogPHA+Ci0gICAqIEhvd2V2ZXIsIG5ld2VyIERPTTMgWFBhdGggY29kZSB1cG9uIGNhdGNoaW5nIGEgVHJhbnNmb3JtZXJFeGNlcHRpb24gY2FuCi0gICAqIGNhbiBjaGVjayBpZiB0aGUgZXhjZXB0aW9uIGlzIGFuIGluc3RhbmNlIG9mIFhQYXRoU3R5bGVzaGVldERPTTNFeGNlcHRpb24KLSAgICogYW5kIHRha2UgYXBwcm9wcmlhdGUgYWN0aW9uLgotICAgKgotICAgKiBAcGFyYW0gbXNnIEFuIGVycm9yIG1zZ2tleSB0aGF0IGNvcnJlc3BvbmRzIHRvIG9uZSBvZiB0aGUgY29uc3RhbnRzIGZvdW5kCi0gICAqICAgICAgICAgICAgaW4ge0BsaW5rIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5yZXMuWFBBVEhFcnJvclJlc291cmNlc30sIHdoaWNoIGlzCi0gICAqICAgICAgICAgICAgYSBrZXkgZm9yIGEgZm9ybWF0IHN0cmluZy4KLSAgICogQHBhcmFtIGFyZ3MgQW4gYXJyYXkgb2YgYXJndW1lbnRzIHJlcHJlc2VudGVkIGluIHRoZSBmb3JtYXQgc3RyaW5nLCB3aGljaAotICAgKiAgICAgICAgICAgICBtYXkgYmUgbnVsbC4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBpZiB0aGUgY3VycmVudCBFcnJvckxpc3RvbmVyIGRldGVybWluZXMgdG8KLSAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBhbiBleGNlcHRpb24uCi0gICAqLwotICB2b2lkIGVycm9yRm9yRE9NMyhTdHJpbmcgbXNnLCBPYmplY3RbXSBhcmdzKSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgICAgIFN0cmluZyBmbXNnID0gWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKG1zZywgYXJncyk7Ci0gICAgICAgIEVycm9yTGlzdGVuZXIgZWhhbmRsZXIgPSB0aGlzLmdldEVycm9yTGlzdGVuZXIoKTsKLQotICAgICAgICBUcmFuc2Zvcm1lckV4Y2VwdGlvbiB0ZSA9IG5ldyBYUGF0aFN0eWxlc2hlZXRET00zRXhjZXB0aW9uKGZtc2csIG1fc291cmNlTG9jYXRvcik7Ci0gICAgICAgIGlmIChudWxsICE9IGVoYW5kbGVyKQotICAgICAgICB7Ci0gICAgICAgICAgLy8gVE8gRE86IE5lZWQgdG8gZ2V0IHN0eWxlc2hlZXQgTG9jYXRvciBmcm9tIGhlcmUuCi0gICAgICAgICAgZWhhbmRsZXIuZmF0YWxFcnJvcih0ZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICB7Ci0gICAgICAgICAgLy8gU3lzdGVtLmVyci5wcmludGxuKGZtc2cpOwotICAgICAgICAgIHRocm93IHRlOwotICAgICAgICB9Ci0gIH0KLSAgLyoqCi0gICAqIER1bXAgdGhlIHJlbWFpbmluZyB0b2tlbiBxdWV1ZS4KLSAgICogVGhhbmtzIHRvIENyYWlnIGZvciB0aGlzLgotICAgKgotICAgKiBAcmV0dXJuIEEgZHVtcCBvZiB0aGUgcmVtYWluaW5nIHRva2VuIHF1ZXVlLCB3aGljaCBtYXkgYmUgYXBwZW5kZWQgdG8KLSAgICogICAgICAgICBhbiBlcnJvciBtZXNzYWdlLgotICAgKi8KLSAgcHJvdGVjdGVkIFN0cmluZyBkdW1wUmVtYWluaW5nVG9rZW5RdWV1ZSgpCi0gIHsKLQotICAgIGludCBxID0gbV9xdWV1ZU1hcms7Ci0gICAgU3RyaW5nIHJldHVybk1zZzsKLQotICAgIGlmIChxIDwgbV9vcHMuZ2V0VG9rZW5RdWV1ZVNpemUoKSkKLSAgICB7Ci0gICAgICBTdHJpbmcgbXNnID0gIlxuIFJlbWFpbmluZyB0b2tlbnM6ICgiOwotCi0gICAgICB3aGlsZSAocSA8IG1fb3BzLmdldFRva2VuUXVldWVTaXplKCkpCi0gICAgICB7Ci0gICAgICAgIFN0cmluZyB0ID0gKFN0cmluZykgbV9vcHMubV90b2tlblF1ZXVlLmVsZW1lbnRBdChxKyspOwotCi0gICAgICAgIG1zZyArPSAoIiAnIiArIHQgKyAiJyIpOwotICAgICAgfQotCi0gICAgICByZXR1cm5Nc2cgPSBtc2cgKyAiKSI7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICByZXR1cm5Nc2cgPSAiIjsKLSAgICB9Ci0KLSAgICByZXR1cm4gcmV0dXJuTXNnOwotICB9Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgc3RyaW5nLCByZXR1cm4gdGhlIGNvcnJlc3BvbmRpbmcgZnVuY3Rpb24gdG9rZW4uCi0gICAqCi0gICAqIEBwYXJhbSBrZXkgQSBsb2NhbCBuYW1lIG9mIGEgZnVuY3Rpb24uCi0gICAqCi0gICAqIEByZXR1cm4gICBUaGUgZnVuY3Rpb24gSUQsIHdoaWNoIG1heSBjb3JyZXNwb25kIHRvIG9uZSBvZiB0aGUgRlVOQ19YWFgKLSAgICogICAgdmFsdWVzIGZvdW5kIGluIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuY29tcGlsZXIuRnVuY3Rpb25UYWJsZX0sIGJ1dCBtYXkKLSAgICogICAgYmUgYSB2YWx1ZSBpbnN0YWxsZWQgYnkgYW4gZXh0ZXJuYWwgbW9kdWxlLgotICAgKi8KLSAgZmluYWwgaW50IGdldEZ1bmN0aW9uVG9rZW4oU3RyaW5nIGtleSkKLSAgewotCi0gICAgaW50IHRvazsKLQotICAgIE9iamVjdCBpZDsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIC8vIFRoZXNlIGFyZSBub2RldGVzdHMsIHhwYXRocGFyc2VyIHRyZWF0cyB0aGVtIGFzIGZ1bmN0aW9ucyB3aGVuIHBhcnNpbmcKLSAgICAgIC8vIGEgRmlsdGVyRXhwci4KLSAgICAgIGlkID0gS2V5d29yZHMubG9va3VwTm9kZVRlc3Qoa2V5KTsKLSAgICAgIGlmIChudWxsID09IGlkKSBpZCA9IG1fZnVuY3Rpb25UYWJsZS5nZXRGdW5jdGlvbklEKGtleSk7Ci0gICAgICB0b2sgPSAoKEludGVnZXIpIGlkKS5pbnRWYWx1ZSgpOwotICAgIH0KLSAgICBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gbnBlKQotICAgIHsKLSAgICAgIHRvayA9IC0xOwotICAgIH0KLSAgICBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGNjZSkKLSAgICB7Ci0gICAgICB0b2sgPSAtMTsKLSAgICB9Ci0KLSAgICByZXR1cm4gdG9rOwotICB9Ci0KLSAgLyoqCi0gICAqIEluc2VydCByb29tIGZvciBvcGVyYXRpb24uICBUaGlzIHdpbGwgTk9UIHNldAotICAgKiB0aGUgbGVuZ3RoIHZhbHVlIG9mIHRoZSBvcGVyYXRpb24sIGJ1dCB3aWxsIHVwZGF0ZQotICAgKiB0aGUgbGVuZ3RoIHZhbHVlIGZvciB0aGUgdG90YWwgZXhwcmVzc2lvbi4KLSAgICoKLSAgICogQHBhcmFtIHBvcyBUaGUgcG9zaXRpb24gd2hlcmUgdGhlIG9wIGlzIHRvIGJlIGluc2VydGVkLgotICAgKiBAcGFyYW0gbGVuZ3RoIFRoZSBsZW5ndGggb2YgdGhlIG9wZXJhdGlvbiBzcGFjZSBpbiB0aGUgb3AgbWFwLgotICAgKiBAcGFyYW0gb3AgVGhlIG9wIGNvZGUgdG8gdGhlIGluc2VydGVkLgotICAgKi8KLSAgdm9pZCBpbnNlcnRPcChpbnQgcG9zLCBpbnQgbGVuZ3RoLCBpbnQgb3ApCi0gIHsKLQotICAgIGludCB0b3RhbExlbiA9IG1fb3BzLmdldE9wKE9wTWFwLk1BUElOREVYX0xFTkdUSCk7Ci0KLSAgICBmb3IgKGludCBpID0gdG90YWxMZW4gLSAxOyBpID49IHBvczsgaS0tKQotICAgIHsKLSAgICAgIG1fb3BzLnNldE9wKGkgKyBsZW5ndGgsIG1fb3BzLmdldE9wKGkpKTsKLSAgICB9Ci0KLSAgICBtX29wcy5zZXRPcChwb3Msb3ApOwotICAgIG1fb3BzLnNldE9wKE9wTWFwLk1BUElOREVYX0xFTkdUSCx0b3RhbExlbiArIGxlbmd0aCk7Ci0gIH0KLQotICAvKioKLSAgICogSW5zZXJ0IHJvb20gZm9yIG9wZXJhdGlvbi4gIFRoaXMgV0lMTCBzZXQKLSAgICogdGhlIGxlbmd0aCB2YWx1ZSBvZiB0aGUgb3BlcmF0aW9uLCBhbmQgd2lsbCB1cGRhdGUKLSAgICogdGhlIGxlbmd0aCB2YWx1ZSBmb3IgdGhlIHRvdGFsIGV4cHJlc3Npb24uCi0gICAqCi0gICAqIEBwYXJhbSBsZW5ndGggVGhlIGxlbmd0aCBvZiB0aGUgb3BlcmF0aW9uLgotICAgKiBAcGFyYW0gb3AgVGhlIG9wIGNvZGUgdG8gdGhlIGluc2VydGVkLgotICAgKi8KLSAgdm9pZCBhcHBlbmRPcChpbnQgbGVuZ3RoLCBpbnQgb3ApCi0gIHsKLQotICAgIGludCB0b3RhbExlbiA9IG1fb3BzLmdldE9wKE9wTWFwLk1BUElOREVYX0xFTkdUSCk7Ci0KLSAgICBtX29wcy5zZXRPcCh0b3RhbExlbiwgb3ApOwotICAgIG1fb3BzLnNldE9wKHRvdGFsTGVuICsgT3BNYXAuTUFQSU5ERVhfTEVOR1RILCBsZW5ndGgpOwotICAgIG1fb3BzLnNldE9wKE9wTWFwLk1BUElOREVYX0xFTkdUSCwgdG90YWxMZW4gKyBsZW5ndGgpOwotICB9Ci0KLSAgLy8gPT09PT09PT09PT09PSBFWFBSRVNTSU9OUyBGVU5DVElPTlMgPT09PT09PT09PT09PT09PT0KLQotICAvKioKLSAgICoKLSAgICoKLSAgICogRXhwciAgOjo9ICBPckV4cHIKLSAgICoKLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBFeHByKCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIE9yRXhwcigpOwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqCi0gICAqIE9yRXhwciAgOjo9ICBBbmRFeHByCi0gICAqIHwgT3JFeHByICdvcicgQW5kRXhwcgotICAgKgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIE9yRXhwcigpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGludCBvcFBvcyA9IG1fb3BzLmdldE9wKE9wTWFwLk1BUElOREVYX0xFTkdUSCk7Ci0KLSAgICBBbmRFeHByKCk7Ci0KLSAgICBpZiAoKG51bGwgIT0gbV90b2tlbikgJiYgdG9rZW5Jcygib3IiKSkKLSAgICB7Ci0gICAgICBuZXh0VG9rZW4oKTsKLSAgICAgIGluc2VydE9wKG9wUG9zLCAyLCBPcENvZGVzLk9QX09SKTsKLSAgICAgIE9yRXhwcigpOwotCi0gICAgICBtX29wcy5zZXRPcChvcFBvcyArIE9wTWFwLk1BUElOREVYX0xFTkdUSCwKLSAgICAgICAgbV9vcHMuZ2V0T3AoT3BNYXAuTUFQSU5ERVhfTEVOR1RIKSAtIG9wUG9zKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICoKLSAgICogQW5kRXhwciAgOjo9ICBFcXVhbGl0eUV4cHIKLSAgICogfCBBbmRFeHByICdhbmQnIEVxdWFsaXR5RXhwcgotICAgKgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIEFuZEV4cHIoKSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpbnQgb3BQb3MgPSBtX29wcy5nZXRPcChPcE1hcC5NQVBJTkRFWF9MRU5HVEgpOwotCi0gICAgRXF1YWxpdHlFeHByKC0xKTsKLQotICAgIGlmICgobnVsbCAhPSBtX3Rva2VuKSAmJiB0b2tlbklzKCJhbmQiKSkKLSAgICB7Ci0gICAgICBuZXh0VG9rZW4oKTsKLSAgICAgIGluc2VydE9wKG9wUG9zLCAyLCBPcENvZGVzLk9QX0FORCk7Ci0gICAgICBBbmRFeHByKCk7Ci0KLSAgICAgIG1fb3BzLnNldE9wKG9wUG9zICsgT3BNYXAuTUFQSU5ERVhfTEVOR1RILAotICAgICAgICBtX29wcy5nZXRPcChPcE1hcC5NQVBJTkRFWF9MRU5HVEgpIC0gb3BQb3MpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKgotICAgKiBAcmV0dXJucyBhbiBPYmplY3Qgd2hpY2ggaXMgZWl0aGVyIGEgU3RyaW5nLCBhIE51bWJlciwgYSBCb29sZWFuLCBvciBhIHZlY3RvcgotICAgKiBvZiBub2Rlcy4KLSAgICoKLSAgICogRXF1YWxpdHlFeHByICA6Oj0gIFJlbGF0aW9uYWxFeHByCi0gICAqIHwgRXF1YWxpdHlFeHByICc9JyBSZWxhdGlvbmFsRXhwcgotICAgKgotICAgKgotICAgKiBAcGFyYW0gYWRkUG9zIFBvc2l0aW9uIHdoZXJlIGV4cHJlc3Npb24gaXMgdG8gYmUgYWRkZWQsIG9yIC0xIGZvciBhcHBlbmQuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIHBvc2l0aW9uIGF0IHRoZSBlbmQgb2YgdGhlIGVxdWFsaXR5IGV4cHJlc3Npb24uCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHJvdGVjdGVkIGludCBFcXVhbGl0eUV4cHIoaW50IGFkZFBvcykgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaW50IG9wUG9zID0gbV9vcHMuZ2V0T3AoT3BNYXAuTUFQSU5ERVhfTEVOR1RIKTsKLQotICAgIGlmICgtMSA9PSBhZGRQb3MpCi0gICAgICBhZGRQb3MgPSBvcFBvczsKLQotICAgIFJlbGF0aW9uYWxFeHByKC0xKTsKLQotICAgIGlmIChudWxsICE9IG1fdG9rZW4pCi0gICAgewotICAgICAgaWYgKHRva2VuSXMoJyEnKSAmJiBsb29rYWhlYWQoJz0nLCAxKSkKLSAgICAgIHsKLSAgICAgICAgbmV4dFRva2VuKCk7Ci0gICAgICAgIG5leHRUb2tlbigpOwotICAgICAgICBpbnNlcnRPcChhZGRQb3MsIDIsIE9wQ29kZXMuT1BfTk9URVFVQUxTKTsKLQotICAgICAgICBpbnQgb3BQbHVzTGVmdEhhbmRMZW4gPSBtX29wcy5nZXRPcChPcE1hcC5NQVBJTkRFWF9MRU5HVEgpIC0gYWRkUG9zOwotCi0gICAgICAgIGFkZFBvcyA9IEVxdWFsaXR5RXhwcihhZGRQb3MpOwotICAgICAgICBtX29wcy5zZXRPcChhZGRQb3MgKyBPcE1hcC5NQVBJTkRFWF9MRU5HVEgsCi0gICAgICAgICAgbV9vcHMuZ2V0T3AoYWRkUG9zICsgb3BQbHVzTGVmdEhhbmRMZW4gKyAxKSArIG9wUGx1c0xlZnRIYW5kTGVuKTsKLSAgICAgICAgYWRkUG9zICs9IDI7Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmICh0b2tlbklzKCc9JykpCi0gICAgICB7Ci0gICAgICAgIG5leHRUb2tlbigpOwotICAgICAgICBpbnNlcnRPcChhZGRQb3MsIDIsIE9wQ29kZXMuT1BfRVFVQUxTKTsKLQotICAgICAgICBpbnQgb3BQbHVzTGVmdEhhbmRMZW4gPSBtX29wcy5nZXRPcChPcE1hcC5NQVBJTkRFWF9MRU5HVEgpIC0gYWRkUG9zOwotCi0gICAgICAgIGFkZFBvcyA9IEVxdWFsaXR5RXhwcihhZGRQb3MpOwotICAgICAgICBtX29wcy5zZXRPcChhZGRQb3MgKyBPcE1hcC5NQVBJTkRFWF9MRU5HVEgsCi0gICAgICAgICAgbV9vcHMuZ2V0T3AoYWRkUG9zICsgb3BQbHVzTGVmdEhhbmRMZW4gKyAxKSArIG9wUGx1c0xlZnRIYW5kTGVuKTsKLSAgICAgICAgYWRkUG9zICs9IDI7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgcmV0dXJuIGFkZFBvczsKLSAgfQotCi0gIC8qKgotICAgKiAuCi0gICAqIEByZXR1cm5zIGFuIE9iamVjdCB3aGljaCBpcyBlaXRoZXIgYSBTdHJpbmcsIGEgTnVtYmVyLCBhIEJvb2xlYW4sIG9yIGEgdmVjdG9yCi0gICAqIG9mIG5vZGVzLgotICAgKgotICAgKiBSZWxhdGlvbmFsRXhwciAgOjo9ICBBZGRpdGl2ZUV4cHIKLSAgICogfCBSZWxhdGlvbmFsRXhwciAnPCcgQWRkaXRpdmVFeHByCi0gICAqIHwgUmVsYXRpb25hbEV4cHIgJz4nIEFkZGl0aXZlRXhwcgotICAgKiB8IFJlbGF0aW9uYWxFeHByICc8PScgQWRkaXRpdmVFeHByCi0gICAqIHwgUmVsYXRpb25hbEV4cHIgJz49JyBBZGRpdGl2ZUV4cHIKLSAgICoKLSAgICoKLSAgICogQHBhcmFtIGFkZFBvcyBQb3NpdGlvbiB3aGVyZSBleHByZXNzaW9uIGlzIHRvIGJlIGFkZGVkLCBvciAtMSBmb3IgYXBwZW5kLgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBwb3NpdGlvbiBhdCB0aGUgZW5kIG9mIHRoZSByZWxhdGlvbmFsIGV4cHJlc3Npb24uCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHJvdGVjdGVkIGludCBSZWxhdGlvbmFsRXhwcihpbnQgYWRkUG9zKSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpbnQgb3BQb3MgPSBtX29wcy5nZXRPcChPcE1hcC5NQVBJTkRFWF9MRU5HVEgpOwotCi0gICAgaWYgKC0xID09IGFkZFBvcykKLSAgICAgIGFkZFBvcyA9IG9wUG9zOwotCi0gICAgQWRkaXRpdmVFeHByKC0xKTsKLQotICAgIGlmIChudWxsICE9IG1fdG9rZW4pCi0gICAgewotICAgICAgaWYgKHRva2VuSXMoJzwnKSkKLSAgICAgIHsKLSAgICAgICAgbmV4dFRva2VuKCk7Ci0KLSAgICAgICAgaWYgKHRva2VuSXMoJz0nKSkKLSAgICAgICAgewotICAgICAgICAgIG5leHRUb2tlbigpOwotICAgICAgICAgIGluc2VydE9wKGFkZFBvcywgMiwgT3BDb2Rlcy5PUF9MVEUpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotICAgICAgICAgIGluc2VydE9wKGFkZFBvcywgMiwgT3BDb2Rlcy5PUF9MVCk7Ci0gICAgICAgIH0KLQotICAgICAgICBpbnQgb3BQbHVzTGVmdEhhbmRMZW4gPSBtX29wcy5nZXRPcChPcE1hcC5NQVBJTkRFWF9MRU5HVEgpIC0gYWRkUG9zOwotCi0gICAgICAgIGFkZFBvcyA9IFJlbGF0aW9uYWxFeHByKGFkZFBvcyk7Ci0gICAgICAgIG1fb3BzLnNldE9wKGFkZFBvcyArIE9wTWFwLk1BUElOREVYX0xFTkdUSCwKLSAgICAgICAgICBtX29wcy5nZXRPcChhZGRQb3MgKyBvcFBsdXNMZWZ0SGFuZExlbiArIDEpICsgb3BQbHVzTGVmdEhhbmRMZW4pOwotICAgICAgICBhZGRQb3MgKz0gMjsKLSAgICAgIH0KLSAgICAgIGVsc2UgaWYgKHRva2VuSXMoJz4nKSkKLSAgICAgIHsKLSAgICAgICAgbmV4dFRva2VuKCk7Ci0KLSAgICAgICAgaWYgKHRva2VuSXMoJz0nKSkKLSAgICAgICAgewotICAgICAgICAgIG5leHRUb2tlbigpOwotICAgICAgICAgIGluc2VydE9wKGFkZFBvcywgMiwgT3BDb2Rlcy5PUF9HVEUpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotICAgICAgICAgIGluc2VydE9wKGFkZFBvcywgMiwgT3BDb2Rlcy5PUF9HVCk7Ci0gICAgICAgIH0KLQotICAgICAgICBpbnQgb3BQbHVzTGVmdEhhbmRMZW4gPSBtX29wcy5nZXRPcChPcE1hcC5NQVBJTkRFWF9MRU5HVEgpIC0gYWRkUG9zOwotCi0gICAgICAgIGFkZFBvcyA9IFJlbGF0aW9uYWxFeHByKGFkZFBvcyk7Ci0gICAgICAgIG1fb3BzLnNldE9wKGFkZFBvcyArIE9wTWFwLk1BUElOREVYX0xFTkdUSCwKLSAgICAgICAgICBtX29wcy5nZXRPcChhZGRQb3MgKyBvcFBsdXNMZWZ0SGFuZExlbiArIDEpICsgb3BQbHVzTGVmdEhhbmRMZW4pOwotICAgICAgICBhZGRQb3MgKz0gMjsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gYWRkUG9zOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoaXMgaGFzIHRvIGhhbmRsZSBjb25zdHJ1Y3Rpb24gb2YgdGhlIG9wZXJhdGlvbnMgc28gdGhhdCB0aGV5IGFyZSBldmFsdWF0ZWQKLSAgICogaW4gcHJlLWZpeCBvcmRlci4gIFNvLCBmb3IgOSs3LTYsIGluc3RlYWQgb2YgfCt8OXwtfDd8NnwsIHRoaXMgbmVlZHMgdG8gYmUKLSAgICogZXZhbHVhdGVkIGFzIHwtfCt8OXw3fDZ8LgotICAgKgotICAgKiBBZGRpdGl2ZUV4cHIgIDo6PSAgTXVsdGlwbGljYXRpdmVFeHByCi0gICAqIHwgQWRkaXRpdmVFeHByICcrJyBNdWx0aXBsaWNhdGl2ZUV4cHIKLSAgICogfCBBZGRpdGl2ZUV4cHIgJy0nIE11bHRpcGxpY2F0aXZlRXhwcgotICAgKgotICAgKgotICAgKiBAcGFyYW0gYWRkUG9zIFBvc2l0aW9uIHdoZXJlIGV4cHJlc3Npb24gaXMgdG8gYmUgYWRkZWQsIG9yIC0xIGZvciBhcHBlbmQuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIHBvc2l0aW9uIGF0IHRoZSBlbmQgb2YgdGhlIGVxdWFsaXR5IGV4cHJlc3Npb24uCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHJvdGVjdGVkIGludCBBZGRpdGl2ZUV4cHIoaW50IGFkZFBvcykgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaW50IG9wUG9zID0gbV9vcHMuZ2V0T3AoT3BNYXAuTUFQSU5ERVhfTEVOR1RIKTsKLQotICAgIGlmICgtMSA9PSBhZGRQb3MpCi0gICAgICBhZGRQb3MgPSBvcFBvczsKLQotICAgIE11bHRpcGxpY2F0aXZlRXhwcigtMSk7Ci0KLSAgICBpZiAobnVsbCAhPSBtX3Rva2VuKQotICAgIHsKLSAgICAgIGlmICh0b2tlbklzKCcrJykpCi0gICAgICB7Ci0gICAgICAgIG5leHRUb2tlbigpOwotICAgICAgICBpbnNlcnRPcChhZGRQb3MsIDIsIE9wQ29kZXMuT1BfUExVUyk7Ci0KLSAgICAgICAgaW50IG9wUGx1c0xlZnRIYW5kTGVuID0gbV9vcHMuZ2V0T3AoT3BNYXAuTUFQSU5ERVhfTEVOR1RIKSAtIGFkZFBvczsKLQotICAgICAgICBhZGRQb3MgPSBBZGRpdGl2ZUV4cHIoYWRkUG9zKTsKLSAgICAgICAgbV9vcHMuc2V0T3AoYWRkUG9zICsgT3BNYXAuTUFQSU5ERVhfTEVOR1RILAotICAgICAgICAgIG1fb3BzLmdldE9wKGFkZFBvcyArIG9wUGx1c0xlZnRIYW5kTGVuICsgMSkgKyBvcFBsdXNMZWZ0SGFuZExlbik7Ci0gICAgICAgIGFkZFBvcyArPSAyOwotICAgICAgfQotICAgICAgZWxzZSBpZiAodG9rZW5JcygnLScpKQotICAgICAgewotICAgICAgICBuZXh0VG9rZW4oKTsKLSAgICAgICAgaW5zZXJ0T3AoYWRkUG9zLCAyLCBPcENvZGVzLk9QX01JTlVTKTsKLQotICAgICAgICBpbnQgb3BQbHVzTGVmdEhhbmRMZW4gPSBtX29wcy5nZXRPcChPcE1hcC5NQVBJTkRFWF9MRU5HVEgpIC0gYWRkUG9zOwotCi0gICAgICAgIGFkZFBvcyA9IEFkZGl0aXZlRXhwcihhZGRQb3MpOwotICAgICAgICBtX29wcy5zZXRPcChhZGRQb3MgKyBPcE1hcC5NQVBJTkRFWF9MRU5HVEgsCi0gICAgICAgICAgbV9vcHMuZ2V0T3AoYWRkUG9zICsgb3BQbHVzTGVmdEhhbmRMZW4gKyAxKSArIG9wUGx1c0xlZnRIYW5kTGVuKTsKLSAgICAgICAgYWRkUG9zICs9IDI7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgcmV0dXJuIGFkZFBvczsKLSAgfQotCi0gIC8qKgotICAgKiBUaGlzIGhhcyB0byBoYW5kbGUgY29uc3RydWN0aW9uIG9mIHRoZSBvcGVyYXRpb25zIHNvIHRoYXQgdGhleSBhcmUgZXZhbHVhdGVkCi0gICAqIGluIHByZS1maXggb3JkZXIuICBTbywgZm9yIDkrNy02LCBpbnN0ZWFkIG9mIHwrfDl8LXw3fDZ8LCB0aGlzIG5lZWRzIHRvIGJlCi0gICAqIGV2YWx1YXRlZCBhcyB8LXwrfDl8N3w2fC4KLSAgICoKLSAgICogTXVsdGlwbGljYXRpdmVFeHByICA6Oj0gIFVuYXJ5RXhwcgotICAgKiB8IE11bHRpcGxpY2F0aXZlRXhwciBNdWx0aXBseU9wZXJhdG9yIFVuYXJ5RXhwcgotICAgKiB8IE11bHRpcGxpY2F0aXZlRXhwciAnZGl2JyBVbmFyeUV4cHIKLSAgICogfCBNdWx0aXBsaWNhdGl2ZUV4cHIgJ21vZCcgVW5hcnlFeHByCi0gICAqIHwgTXVsdGlwbGljYXRpdmVFeHByICdxdW8nIFVuYXJ5RXhwcgotICAgKgotICAgKiBAcGFyYW0gYWRkUG9zIFBvc2l0aW9uIHdoZXJlIGV4cHJlc3Npb24gaXMgdG8gYmUgYWRkZWQsIG9yIC0xIGZvciBhcHBlbmQuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIHBvc2l0aW9uIGF0IHRoZSBlbmQgb2YgdGhlIGVxdWFsaXR5IGV4cHJlc3Npb24uCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHJvdGVjdGVkIGludCBNdWx0aXBsaWNhdGl2ZUV4cHIoaW50IGFkZFBvcykgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaW50IG9wUG9zID0gbV9vcHMuZ2V0T3AoT3BNYXAuTUFQSU5ERVhfTEVOR1RIKTsKLQotICAgIGlmICgtMSA9PSBhZGRQb3MpCi0gICAgICBhZGRQb3MgPSBvcFBvczsKLQotICAgIFVuYXJ5RXhwcigpOwotCi0gICAgaWYgKG51bGwgIT0gbV90b2tlbikKLSAgICB7Ci0gICAgICBpZiAodG9rZW5JcygnKicpKQotICAgICAgewotICAgICAgICBuZXh0VG9rZW4oKTsKLSAgICAgICAgaW5zZXJ0T3AoYWRkUG9zLCAyLCBPcENvZGVzLk9QX01VTFQpOwotCi0gICAgICAgIGludCBvcFBsdXNMZWZ0SGFuZExlbiA9IG1fb3BzLmdldE9wKE9wTWFwLk1BUElOREVYX0xFTkdUSCkgLSBhZGRQb3M7Ci0KLSAgICAgICAgYWRkUG9zID0gTXVsdGlwbGljYXRpdmVFeHByKGFkZFBvcyk7Ci0gICAgICAgIG1fb3BzLnNldE9wKGFkZFBvcyArIE9wTWFwLk1BUElOREVYX0xFTkdUSCwKLSAgICAgICAgICBtX29wcy5nZXRPcChhZGRQb3MgKyBvcFBsdXNMZWZ0SGFuZExlbiArIDEpICsgb3BQbHVzTGVmdEhhbmRMZW4pOwotICAgICAgICBhZGRQb3MgKz0gMjsKLSAgICAgIH0KLSAgICAgIGVsc2UgaWYgKHRva2VuSXMoImRpdiIpKQotICAgICAgewotICAgICAgICBuZXh0VG9rZW4oKTsKLSAgICAgICAgaW5zZXJ0T3AoYWRkUG9zLCAyLCBPcENvZGVzLk9QX0RJVik7Ci0KLSAgICAgICAgaW50IG9wUGx1c0xlZnRIYW5kTGVuID0gbV9vcHMuZ2V0T3AoT3BNYXAuTUFQSU5ERVhfTEVOR1RIKSAtIGFkZFBvczsKLQotICAgICAgICBhZGRQb3MgPSBNdWx0aXBsaWNhdGl2ZUV4cHIoYWRkUG9zKTsKLSAgICAgICAgbV9vcHMuc2V0T3AoYWRkUG9zICsgT3BNYXAuTUFQSU5ERVhfTEVOR1RILAotICAgICAgICAgIG1fb3BzLmdldE9wKGFkZFBvcyArIG9wUGx1c0xlZnRIYW5kTGVuICsgMSkgKyBvcFBsdXNMZWZ0SGFuZExlbik7Ci0gICAgICAgIGFkZFBvcyArPSAyOwotICAgICAgfQotICAgICAgZWxzZSBpZiAodG9rZW5JcygibW9kIikpCi0gICAgICB7Ci0gICAgICAgIG5leHRUb2tlbigpOwotICAgICAgICBpbnNlcnRPcChhZGRQb3MsIDIsIE9wQ29kZXMuT1BfTU9EKTsKLQotICAgICAgICBpbnQgb3BQbHVzTGVmdEhhbmRMZW4gPSBtX29wcy5nZXRPcChPcE1hcC5NQVBJTkRFWF9MRU5HVEgpIC0gYWRkUG9zOwotCi0gICAgICAgIGFkZFBvcyA9IE11bHRpcGxpY2F0aXZlRXhwcihhZGRQb3MpOwotICAgICAgICBtX29wcy5zZXRPcChhZGRQb3MgKyBPcE1hcC5NQVBJTkRFWF9MRU5HVEgsCi0gICAgICAgICAgbV9vcHMuZ2V0T3AoYWRkUG9zICsgb3BQbHVzTGVmdEhhbmRMZW4gKyAxKSArIG9wUGx1c0xlZnRIYW5kTGVuKTsKLSAgICAgICAgYWRkUG9zICs9IDI7Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmICh0b2tlbklzKCJxdW8iKSkKLSAgICAgIHsKLSAgICAgICAgbmV4dFRva2VuKCk7Ci0gICAgICAgIGluc2VydE9wKGFkZFBvcywgMiwgT3BDb2Rlcy5PUF9RVU8pOwotCi0gICAgICAgIGludCBvcFBsdXNMZWZ0SGFuZExlbiA9IG1fb3BzLmdldE9wKE9wTWFwLk1BUElOREVYX0xFTkdUSCkgLSBhZGRQb3M7Ci0KLSAgICAgICAgYWRkUG9zID0gTXVsdGlwbGljYXRpdmVFeHByKGFkZFBvcyk7Ci0gICAgICAgIG1fb3BzLnNldE9wKGFkZFBvcyArIE9wTWFwLk1BUElOREVYX0xFTkdUSCwKLSAgICAgICAgICBtX29wcy5nZXRPcChhZGRQb3MgKyBvcFBsdXNMZWZ0SGFuZExlbiArIDEpICsgb3BQbHVzTGVmdEhhbmRMZW4pOwotICAgICAgICBhZGRQb3MgKz0gMjsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gYWRkUG9zOwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqIFVuYXJ5RXhwciAgOjo9ICBVbmlvbkV4cHIKLSAgICogfCAnLScgVW5hcnlFeHByCi0gICAqCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgVW5hcnlFeHByKCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaW50IG9wUG9zID0gbV9vcHMuZ2V0T3AoT3BNYXAuTUFQSU5ERVhfTEVOR1RIKTsKLSAgICBib29sZWFuIGlzTmVnID0gZmFsc2U7Ci0KLSAgICBpZiAobV90b2tlbkNoYXIgPT0gJy0nKQotICAgIHsKLSAgICAgIG5leHRUb2tlbigpOwotICAgICAgYXBwZW5kT3AoMiwgT3BDb2Rlcy5PUF9ORUcpOwotCi0gICAgICBpc05lZyA9IHRydWU7Ci0gICAgfQotCi0gICAgVW5pb25FeHByKCk7Ci0KLSAgICBpZiAoaXNOZWcpCi0gICAgICBtX29wcy5zZXRPcChvcFBvcyArIE9wTWFwLk1BUElOREVYX0xFTkdUSCwKLSAgICAgICAgbV9vcHMuZ2V0T3AoT3BNYXAuTUFQSU5ERVhfTEVOR1RIKSAtIG9wUG9zKTsKLSAgfQotCi0gIC8qKgotICAgKgotICAgKiBTdHJpbmdFeHByICA6Oj0gIEV4cHIKLSAgICoKLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBTdHJpbmdFeHByKCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaW50IG9wUG9zID0gbV9vcHMuZ2V0T3AoT3BNYXAuTUFQSU5ERVhfTEVOR1RIKTsKLQotICAgIGFwcGVuZE9wKDIsIE9wQ29kZXMuT1BfU1RSSU5HKTsKLSAgICBFeHByKCk7Ci0KLSAgICBtX29wcy5zZXRPcChvcFBvcyArIE9wTWFwLk1BUElOREVYX0xFTkdUSCwKLSAgICAgIG1fb3BzLmdldE9wKE9wTWFwLk1BUElOREVYX0xFTkdUSCkgLSBvcFBvcyk7Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICoKLSAgICogU3RyaW5nRXhwciAgOjo9ICBFeHByCi0gICAqCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgQm9vbGVhbkV4cHIoKSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpbnQgb3BQb3MgPSBtX29wcy5nZXRPcChPcE1hcC5NQVBJTkRFWF9MRU5HVEgpOwotCi0gICAgYXBwZW5kT3AoMiwgT3BDb2Rlcy5PUF9CT09MKTsKLSAgICBFeHByKCk7Ci0KLSAgICBpbnQgb3BMZW4gPSBtX29wcy5nZXRPcChPcE1hcC5NQVBJTkRFWF9MRU5HVEgpIC0gb3BQb3M7Ci0KLSAgICBpZiAob3BMZW4gPT0gMikKLSAgICB7Ci0gICAgICBlcnJvcihYUEFUSEVycm9yUmVzb3VyY2VzLkVSX0JPT0xFQU5fQVJHX05PX0xPTkdFUl9PUFRJT05BTCwgbnVsbCk7ICAvLyJib29sZWFuKC4uLikgYXJndW1lbnQgaXMgbm8gbG9uZ2VyIG9wdGlvbmFsIHdpdGggMTk5OTA3MDkgWFBhdGggZHJhZnQuIik7Ci0gICAgfQotCi0gICAgbV9vcHMuc2V0T3Aob3BQb3MgKyBPcE1hcC5NQVBJTkRFWF9MRU5HVEgsIG9wTGVuKTsKLSAgfQotCi0gIC8qKgotICAgKgotICAgKgotICAgKiBOdW1iZXJFeHByICA6Oj0gIEV4cHIKLSAgICoKLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBOdW1iZXJFeHByKCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaW50IG9wUG9zID0gbV9vcHMuZ2V0T3AoT3BNYXAuTUFQSU5ERVhfTEVOR1RIKTsKLQotICAgIGFwcGVuZE9wKDIsIE9wQ29kZXMuT1BfTlVNQkVSKTsKLSAgICBFeHByKCk7Ci0KLSAgICBtX29wcy5zZXRPcChvcFBvcyArIE9wTWFwLk1BUElOREVYX0xFTkdUSCwKLSAgICAgIG1fb3BzLmdldE9wKE9wTWFwLk1BUElOREVYX0xFTkdUSCkgLSBvcFBvcyk7Ci0gIH0KLQotICAvKioKLSAgICogVGhlIGNvbnRleHQgb2YgdGhlIHJpZ2h0IGhhbmQgc2lkZSBleHByZXNzaW9ucyBpcyB0aGUgY29udGV4dCBvZiB0aGUKLSAgICogbGVmdCBoYW5kIHNpZGUgZXhwcmVzc2lvbi4gVGhlIHJlc3VsdHMgb2YgdGhlIHJpZ2h0IGhhbmQgc2lkZSBleHByZXNzaW9ucwotICAgKiBhcmUgbm9kZSBzZXRzLiBUaGUgcmVzdWx0IG9mIHRoZSBsZWZ0IGhhbmQgc2lkZSBVbmlvbkV4cHIgaXMgdGhlIHVuaW9uCi0gICAqIG9mIHRoZSByZXN1bHRzIG9mIHRoZSByaWdodCBoYW5kIHNpZGUgZXhwcmVzc2lvbnMuCi0gICAqCi0gICAqCi0gICAqIFVuaW9uRXhwciAgICA6Oj0gICAgUGF0aEV4cHIKLSAgICogfCBVbmlvbkV4cHIgJ3wnIFBhdGhFeHByCi0gICAqCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgVW5pb25FeHByKCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaW50IG9wUG9zID0gbV9vcHMuZ2V0T3AoT3BNYXAuTUFQSU5ERVhfTEVOR1RIKTsKLSAgICBib29sZWFuIGNvbnRpbnVlT3JMb29wID0gdHJ1ZTsKLSAgICBib29sZWFuIGZvdW5kVW5pb24gPSBmYWxzZTsKLQotICAgIGRvCi0gICAgewotICAgICAgUGF0aEV4cHIoKTsKLQotICAgICAgaWYgKHRva2VuSXMoJ3wnKSkKLSAgICAgIHsKLSAgICAgICAgaWYgKGZhbHNlID09IGZvdW5kVW5pb24pCi0gICAgICAgIHsKLSAgICAgICAgICBmb3VuZFVuaW9uID0gdHJ1ZTsKLQotICAgICAgICAgIGluc2VydE9wKG9wUG9zLCAyLCBPcENvZGVzLk9QX1VOSU9OKTsKLSAgICAgICAgfQotCi0gICAgICAgIG5leHRUb2tlbigpOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBicmVhazsKLSAgICAgIH0KLQotICAgICAgLy8gdGhpcy5tX3Rlc3RGb3JEb2NPcmRlciA9IHRydWU7Ci0gICAgfQotICAgIHdoaWxlIChjb250aW51ZU9yTG9vcCk7Ci0KLSAgICBtX29wcy5zZXRPcChvcFBvcyArIE9wTWFwLk1BUElOREVYX0xFTkdUSCwKLSAgICAgICAgICBtX29wcy5nZXRPcChPcE1hcC5NQVBJTkRFWF9MRU5HVEgpIC0gb3BQb3MpOwotICB9Ci0KLSAgLyoqCi0gICAqIFBhdGhFeHByICA6Oj0gIExvY2F0aW9uUGF0aAotICAgKiB8IEZpbHRlckV4cHIKLSAgICogfCBGaWx0ZXJFeHByICcvJyBSZWxhdGl2ZUxvY2F0aW9uUGF0aAotICAgKiB8IEZpbHRlckV4cHIgJy8vJyBSZWxhdGl2ZUxvY2F0aW9uUGF0aAotICAgKgotICAgKiBAdGhyb3dzIFhTTFByb2Nlc3NvckV4Y2VwdGlvbiB0aHJvd24gaWYgdGhlIGFjdGl2ZSBQcm9ibGVtTGlzdGVuZXIgYW5kIFhQYXRoQ29udGV4dCBkZWNpZGUKLSAgICogdGhlIGVycm9yIGNvbmRpdGlvbiBpcyBzZXZlcmUgZW5vdWdoIHRvIGhhbHQgcHJvY2Vzc2luZy4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBQYXRoRXhwcigpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGludCBvcFBvcyA9IG1fb3BzLmdldE9wKE9wTWFwLk1BUElOREVYX0xFTkdUSCk7Ci0KLSAgICBpbnQgZmlsdGVyRXhwck1hdGNoID0gRmlsdGVyRXhwcigpOwotCi0gICAgaWYgKGZpbHRlckV4cHJNYXRjaCAhPSBGSUxURVJfTUFUQ0hfRkFJTEVEKQotICAgIHsKLSAgICAgIC8vIElmIEZpbHRlckV4cHIgaGFkIFByZWRpY2F0ZXMsIGEgT1BfTE9DQVRJT05QQVRIIG9wY29kZSB3b3VsZCBhbHJlYWR5Ci0gICAgICAvLyBoYXZlIGJlZW4gaW5zZXJ0ZWQuCi0gICAgICBib29sZWFuIGxvY2F0aW9uUGF0aFN0YXJ0ZWQgPSAoZmlsdGVyRXhwck1hdGNoPT1GSUxURVJfTUFUQ0hfUFJFRElDQVRFUyk7Ci0KLSAgICAgIGlmICh0b2tlbklzKCcvJykpCi0gICAgICB7Ci0gICAgICAgIG5leHRUb2tlbigpOwotCi0gICAgICAgIGlmICghbG9jYXRpb25QYXRoU3RhcnRlZCkKLSAgICAgICAgewotICAgICAgICAgIC8vIGludCBsb2NhdGlvblBhdGhPcFBvcyA9IG9wUG9zOwotICAgICAgICAgIGluc2VydE9wKG9wUG9zLCAyLCBPcENvZGVzLk9QX0xPQ0FUSU9OUEFUSCk7Ci0KLSAgICAgICAgICBsb2NhdGlvblBhdGhTdGFydGVkID0gdHJ1ZTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmICghUmVsYXRpdmVMb2NhdGlvblBhdGgoKSkKLSAgICAgICAgewotICAgICAgICAgIC8vICJSZWxhdGl2ZSBsb2NhdGlvbiBwYXRoIGV4cGVjdGVkIGZvbGxvd2luZyAnLycgb3IgJy8vJyIKLSAgICAgICAgICBlcnJvcihYUEFUSEVycm9yUmVzb3VyY2VzLkVSX0VYUEVDVEVEX1JFTF9MT0NfUEFUSCwgbnVsbCk7Ci0gICAgICAgIH0KLQotICAgICAgfQotCi0gICAgICAvLyBUZXJtaW5hdGUgZm9yIHNhZmV0eS4KLSAgICAgIGlmIChsb2NhdGlvblBhdGhTdGFydGVkKQotICAgICAgewotICAgICAgICBtX29wcy5zZXRPcChtX29wcy5nZXRPcChPcE1hcC5NQVBJTkRFWF9MRU5HVEgpLCBPcENvZGVzLkVORE9QKTsKLSAgICAgICAgbV9vcHMuc2V0T3AoT3BNYXAuTUFQSU5ERVhfTEVOR1RILCBtX29wcy5nZXRPcChPcE1hcC5NQVBJTkRFWF9MRU5HVEgpICsgMSk7Ci0gICAgICAgIG1fb3BzLnNldE9wKG9wUG9zICsgT3BNYXAuTUFQSU5ERVhfTEVOR1RILAotICAgICAgICAgIG1fb3BzLmdldE9wKE9wTWFwLk1BUElOREVYX0xFTkdUSCkgLSBvcFBvcyk7Ci0gICAgICB9Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBMb2NhdGlvblBhdGgoKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICoKLSAgICogRmlsdGVyRXhwciAgOjo9ICBQcmltYXJ5RXhwcgotICAgKiB8IEZpbHRlckV4cHIgUHJlZGljYXRlCi0gICAqCi0gICAqIEB0aHJvd3MgWFNMUHJvY2Vzc29yRXhjZXB0aW9uIHRocm93biBpZiB0aGUgYWN0aXZlIFByb2JsZW1MaXN0ZW5lciBhbmQgWFBhdGhDb250ZXh0IGRlY2lkZQotICAgKiB0aGUgZXJyb3IgY29uZGl0aW9uIGlzIHNldmVyZSBlbm91Z2ggdG8gaGFsdCBwcm9jZXNzaW5nLgotICAgKgotICAgKiBAcmV0dXJuICBGSUxURVJfTUFUQ0hfUFJFRElDQVRFUywgaWYgdGhpcyBtZXRob2Qgc3VjY2Vzc2Z1bGx5IG1hdGNoZWQgYQotICAgKiAgICAgICAgICBGaWx0ZXJFeHByIHdpdGggb25lIG9yIG1vcmUgUHJlZGljYXRlczsKLSAgICogICAgICAgICAgRklMVEVSX01BVENIX1BSSU1BUlksIGlmIHRoaXMgbWV0aG9kIHN1Y2Nlc3NmdWxseSBtYXRjaGVkIGEKLSAgICogICAgICAgICAgRmlsdGVyRXhwciB0aGF0IHdhcyBqdXN0IGEgUHJpbWFyeUV4cHI7IG9yCi0gICAqICAgICAgICAgIEZJTFRFUl9NQVRDSF9GQUlMRUQsIGlmIHRoaXMgbWV0aG9kIGRpZCBub3QgbWF0Y2ggYSBGaWx0ZXJFeHByCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHJvdGVjdGVkIGludCBGaWx0ZXJFeHByKCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaW50IG9wUG9zID0gbV9vcHMuZ2V0T3AoT3BNYXAuTUFQSU5ERVhfTEVOR1RIKTsKLQotICAgIGludCBmaWx0ZXJNYXRjaDsKLQotICAgIGlmIChQcmltYXJ5RXhwcigpKQotICAgIHsKLSAgICAgIGlmICh0b2tlbklzKCdbJykpCi0gICAgICB7Ci0KLSAgICAgICAgLy8gaW50IGxvY2F0aW9uUGF0aE9wUG9zID0gb3BQb3M7Ci0gICAgICAgIGluc2VydE9wKG9wUG9zLCAyLCBPcENvZGVzLk9QX0xPQ0FUSU9OUEFUSCk7Ci0KLSAgICAgICAgd2hpbGUgKHRva2VuSXMoJ1snKSkKLSAgICAgICAgewotICAgICAgICAgIFByZWRpY2F0ZSgpOwotICAgICAgICB9Ci0KLSAgICAgICAgZmlsdGVyTWF0Y2ggPSBGSUxURVJfTUFUQ0hfUFJFRElDQVRFUzsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgZmlsdGVyTWF0Y2ggPSBGSUxURVJfTUFUQ0hfUFJJTUFSWTsKLSAgICAgIH0KLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIGZpbHRlck1hdGNoID0gRklMVEVSX01BVENIX0ZBSUxFRDsKLSAgICB9Ci0KLSAgICByZXR1cm4gZmlsdGVyTWF0Y2g7Ci0KLSAgICAvKgotICAgICAqIGlmKHRva2VuSXMoJ1snKSkKLSAgICAgKiB7Ci0gICAgICogICBQcmVkaWNhdGUoKTsKLSAgICAgKiAgIG1fb3BzLm1fb3BNYXBbb3BQb3MgKyBPcE1hcC5NQVBJTkRFWF9MRU5HVEhdID0gbV9vcHMubV9vcE1hcFtPcE1hcC5NQVBJTkRFWF9MRU5HVEhdIC0gb3BQb3M7Ci0gICAgICogfQotICAgICAqLwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqIFByaW1hcnlFeHByICA6Oj0gIFZhcmlhYmxlUmVmZXJlbmNlCi0gICAqIHwgJygnIEV4cHIgJyknCi0gICAqIHwgTGl0ZXJhbAotICAgKiB8IE51bWJlcgotICAgKiB8IEZ1bmN0aW9uQ2FsbAotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhpcyBtZXRob2Qgc3VjY2Vzc2Z1bGx5IG1hdGNoZWQgYSBQcmltYXJ5RXhwcgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICoKLSAgICovCi0gIHByb3RlY3RlZCBib29sZWFuIFByaW1hcnlFeHByKCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgYm9vbGVhbiBtYXRjaEZvdW5kOwotICAgIGludCBvcFBvcyA9IG1fb3BzLmdldE9wKE9wTWFwLk1BUElOREVYX0xFTkdUSCk7Ci0KLSAgICBpZiAoKG1fdG9rZW5DaGFyID09ICdcJycpIHx8IChtX3Rva2VuQ2hhciA9PSAnIicpKQotICAgIHsKLSAgICAgIGFwcGVuZE9wKDIsIE9wQ29kZXMuT1BfTElURVJBTCk7Ci0gICAgICBMaXRlcmFsKCk7Ci0KLSAgICAgIG1fb3BzLnNldE9wKG9wUG9zICsgT3BNYXAuTUFQSU5ERVhfTEVOR1RILAotICAgICAgICBtX29wcy5nZXRPcChPcE1hcC5NQVBJTkRFWF9MRU5HVEgpIC0gb3BQb3MpOwotCi0gICAgICBtYXRjaEZvdW5kID0gdHJ1ZTsKLSAgICB9Ci0gICAgZWxzZSBpZiAobV90b2tlbkNoYXIgPT0gJyQnKQotICAgIHsKLSAgICAgIG5leHRUb2tlbigpOyAgLy8gY29uc3VtZSAnJCcKLSAgICAgIGFwcGVuZE9wKDIsIE9wQ29kZXMuT1BfVkFSSUFCTEUpOwotICAgICAgUU5hbWUoKTsKLQotICAgICAgbV9vcHMuc2V0T3Aob3BQb3MgKyBPcE1hcC5NQVBJTkRFWF9MRU5HVEgsCi0gICAgICAgIG1fb3BzLmdldE9wKE9wTWFwLk1BUElOREVYX0xFTkdUSCkgLSBvcFBvcyk7Ci0KLSAgICAgIG1hdGNoRm91bmQgPSB0cnVlOwotICAgIH0KLSAgICBlbHNlIGlmIChtX3Rva2VuQ2hhciA9PSAnKCcpCi0gICAgewotICAgICAgbmV4dFRva2VuKCk7Ci0gICAgICBhcHBlbmRPcCgyLCBPcENvZGVzLk9QX0dST1VQKTsKLSAgICAgIEV4cHIoKTsKLSAgICAgIGNvbnN1bWVFeHBlY3RlZCgnKScpOwotCi0gICAgICBtX29wcy5zZXRPcChvcFBvcyArIE9wTWFwLk1BUElOREVYX0xFTkdUSCwKLSAgICAgICAgbV9vcHMuZ2V0T3AoT3BNYXAuTUFQSU5ERVhfTEVOR1RIKSAtIG9wUG9zKTsKLQotICAgICAgbWF0Y2hGb3VuZCA9IHRydWU7Ci0gICAgfQotICAgIGVsc2UgaWYgKChudWxsICE9IG1fdG9rZW4pICYmICgoKCcuJyA9PSBtX3Rva2VuQ2hhcikgJiYgKG1fdG9rZW4ubGVuZ3RoKCkgPiAxKSAmJiBDaGFyYWN0ZXIuaXNEaWdpdCgKLSAgICAgICAgICAgIG1fdG9rZW4uY2hhckF0KDEpKSkgfHwgQ2hhcmFjdGVyLmlzRGlnaXQobV90b2tlbkNoYXIpKSkKLSAgICB7Ci0gICAgICBhcHBlbmRPcCgyLCBPcENvZGVzLk9QX05VTUJFUkxJVCk7Ci0gICAgICBOdW1iZXIoKTsKLQotICAgICAgbV9vcHMuc2V0T3Aob3BQb3MgKyBPcE1hcC5NQVBJTkRFWF9MRU5HVEgsCi0gICAgICAgIG1fb3BzLmdldE9wKE9wTWFwLk1BUElOREVYX0xFTkdUSCkgLSBvcFBvcyk7Ci0KLSAgICAgIG1hdGNoRm91bmQgPSB0cnVlOwotICAgIH0KLSAgICBlbHNlIGlmIChsb29rYWhlYWQoJygnLCAxKSB8fCAobG9va2FoZWFkKCc6JywgMSkgJiYgbG9va2FoZWFkKCcoJywgMykpKQotICAgIHsKLSAgICAgIG1hdGNoRm91bmQgPSBGdW5jdGlvbkNhbGwoKTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIG1hdGNoRm91bmQgPSBmYWxzZTsKLSAgICB9Ci0KLSAgICByZXR1cm4gbWF0Y2hGb3VuZDsKLSAgfQotCi0gIC8qKgotICAgKgotICAgKiBBcmd1bWVudCAgICA6Oj0gICAgRXhwcgotICAgKgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIEFyZ3VtZW50KCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaW50IG9wUG9zID0gbV9vcHMuZ2V0T3AoT3BNYXAuTUFQSU5ERVhfTEVOR1RIKTsKLQotICAgIGFwcGVuZE9wKDIsIE9wQ29kZXMuT1BfQVJHVU1FTlQpOwotICAgIEV4cHIoKTsKLQotICAgIG1fb3BzLnNldE9wKG9wUG9zICsgT3BNYXAuTUFQSU5ERVhfTEVOR1RILAotICAgICAgbV9vcHMuZ2V0T3AoT3BNYXAuTUFQSU5ERVhfTEVOR1RIKSAtIG9wUG9zKTsKLSAgfQotCi0gIC8qKgotICAgKgotICAgKiBGdW5jdGlvbkNhbGwgICAgOjo9ICAgIEZ1bmN0aW9uTmFtZSAnKCcgKCBBcmd1bWVudCAoICcsJyBBcmd1bWVudCkqKT8gJyknCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiwgYW5kIG9ubHkgaWYsIGEgRnVuY3Rpb25DYWxsIHdhcyBtYXRjaGVkCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHJvdGVjdGVkIGJvb2xlYW4gRnVuY3Rpb25DYWxsKCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaW50IG9wUG9zID0gbV9vcHMuZ2V0T3AoT3BNYXAuTUFQSU5ERVhfTEVOR1RIKTsKLQotICAgIGlmIChsb29rYWhlYWQoJzonLCAxKSkKLSAgICB7Ci0gICAgICBhcHBlbmRPcCg0LCBPcENvZGVzLk9QX0VYVEZVTkNUSU9OKTsKLQotICAgICAgbV9vcHMuc2V0T3Aob3BQb3MgKyBPcE1hcC5NQVBJTkRFWF9MRU5HVEggKyAxLCBtX3F1ZXVlTWFyayAtIDEpOwotCi0gICAgICBuZXh0VG9rZW4oKTsKLSAgICAgIGNvbnN1bWVFeHBlY3RlZCgnOicpOwotCi0gICAgICBtX29wcy5zZXRPcChvcFBvcyArIE9wTWFwLk1BUElOREVYX0xFTkdUSCArIDIsIG1fcXVldWVNYXJrIC0gMSk7Ci0KLSAgICAgIG5leHRUb2tlbigpOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgaW50IGZ1bmNUb2sgPSBnZXRGdW5jdGlvblRva2VuKG1fdG9rZW4pOwotCi0gICAgICBpZiAoLTEgPT0gZnVuY1RvaykKLSAgICAgIHsKLSAgICAgICAgZXJyb3IoWFBBVEhFcnJvclJlc291cmNlcy5FUl9DT1VMRE5PVF9GSU5EX0ZVTkNUSU9OLAotICAgICAgICAgICAgICBuZXcgT2JqZWN0W117IG1fdG9rZW4gfSk7ICAvLyJDb3VsZCBub3QgZmluZCBmdW5jdGlvbjogIittX3Rva2VuKyIoKSIpOwotICAgICAgfQotCi0gICAgICBzd2l0Y2ggKGZ1bmNUb2spCi0gICAgICB7Ci0gICAgICBjYXNlIE9wQ29kZXMuTk9ERVRZUEVfUEkgOgotICAgICAgY2FzZSBPcENvZGVzLk5PREVUWVBFX0NPTU1FTlQgOgotICAgICAgY2FzZSBPcENvZGVzLk5PREVUWVBFX1RFWFQgOgotICAgICAgY2FzZSBPcENvZGVzLk5PREVUWVBFX05PREUgOgotICAgICAgICAvLyBOb2RlIHR5cGUgdGVzdHMgbG9vayBsaWtlIGZ1bmN0aW9uIGNhbGxzLCBidXQgdGhleSdyZSBub3QKLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgZGVmYXVsdCA6Ci0gICAgICAgIGFwcGVuZE9wKDMsIE9wQ29kZXMuT1BfRlVOQ1RJT04pOwotCi0gICAgICAgIG1fb3BzLnNldE9wKG9wUG9zICsgT3BNYXAuTUFQSU5ERVhfTEVOR1RIICsgMSwgZnVuY1Rvayk7Ci0gICAgICB9Ci0KLSAgICAgIG5leHRUb2tlbigpOwotICAgIH0KLQotICAgIGNvbnN1bWVFeHBlY3RlZCgnKCcpOwotCi0gICAgd2hpbGUgKCF0b2tlbklzKCcpJykgJiYgbV90b2tlbiAhPSBudWxsKQotICAgIHsKLSAgICAgIGlmICh0b2tlbklzKCcsJykpCi0gICAgICB7Ci0gICAgICAgIGVycm9yKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfRk9VTkRfQ09NTUFfQlVUX05PX1BSRUNFRElOR19BUkcsIG51bGwpOyAgLy8iRm91bmQgJywnIGJ1dCBubyBwcmVjZWRpbmcgYXJndW1lbnQhIik7Ci0gICAgICB9Ci0KLSAgICAgIEFyZ3VtZW50KCk7Ci0KLSAgICAgIGlmICghdG9rZW5JcygnKScpKQotICAgICAgewotICAgICAgICBjb25zdW1lRXhwZWN0ZWQoJywnKTsKLQotICAgICAgICBpZiAodG9rZW5JcygnKScpKQotICAgICAgICB7Ci0gICAgICAgICAgZXJyb3IoWFBBVEhFcnJvclJlc291cmNlcy5FUl9GT1VORF9DT01NQV9CVVRfTk9fRk9MTE9XSU5HX0FSRywKLSAgICAgICAgICAgICAgICBudWxsKTsgIC8vIkZvdW5kICcsJyBidXQgbm8gZm9sbG93aW5nIGFyZ3VtZW50ISIpOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotCi0gICAgY29uc3VtZUV4cGVjdGVkKCcpJyk7Ci0KLSAgICAvLyBUZXJtaW5hdGUgZm9yIHNhZmV0eS4KLSAgICBtX29wcy5zZXRPcChtX29wcy5nZXRPcChPcE1hcC5NQVBJTkRFWF9MRU5HVEgpLCBPcENvZGVzLkVORE9QKTsKLSAgICBtX29wcy5zZXRPcChPcE1hcC5NQVBJTkRFWF9MRU5HVEgsbV9vcHMuZ2V0T3AoT3BNYXAuTUFQSU5ERVhfTEVOR1RIKSArIDEpOwotICAgIG1fb3BzLnNldE9wKG9wUG9zICsgT3BNYXAuTUFQSU5ERVhfTEVOR1RILAotICAgICAgbV9vcHMuZ2V0T3AoT3BNYXAuTUFQSU5ERVhfTEVOR1RIKSAtIG9wUG9zKTsKLQotICAgIHJldHVybiB0cnVlOwotICB9Ci0KLSAgLy8gPT09PT09PT09PT09PSBHUkFNTUFSIEZVTkNUSU9OUyA9PT09PT09PT09PT09PT09PQotCi0gIC8qKgotICAgKgotICAgKiBMb2NhdGlvblBhdGggOjo9IFJlbGF0aXZlTG9jYXRpb25QYXRoCi0gICAqIHwgQWJzb2x1dGVMb2NhdGlvblBhdGgKLSAgICoKLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBMb2NhdGlvblBhdGgoKSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpbnQgb3BQb3MgPSBtX29wcy5nZXRPcChPcE1hcC5NQVBJTkRFWF9MRU5HVEgpOwotCi0gICAgLy8gaW50IGxvY2F0aW9uUGF0aE9wUG9zID0gb3BQb3M7Ci0gICAgYXBwZW5kT3AoMiwgT3BDb2Rlcy5PUF9MT0NBVElPTlBBVEgpOwotCi0gICAgYm9vbGVhbiBzZWVuU2xhc2ggPSB0b2tlbklzKCcvJyk7Ci0KLSAgICBpZiAoc2VlblNsYXNoKQotICAgIHsKLSAgICAgIGFwcGVuZE9wKDQsIE9wQ29kZXMuRlJPTV9ST09UKTsKLQotICAgICAgLy8gVGVsbCBob3cgbG9uZyB0aGUgc3RlcCBpcyB3aXRob3V0IHRoZSBwcmVkaWNhdGUKLSAgICAgIG1fb3BzLnNldE9wKG1fb3BzLmdldE9wKE9wTWFwLk1BUElOREVYX0xFTkdUSCkgLSAyLCA0KTsKLSAgICAgIG1fb3BzLnNldE9wKG1fb3BzLmdldE9wKE9wTWFwLk1BUElOREVYX0xFTkdUSCkgLSAxLCBPcENvZGVzLk5PREVUWVBFX1JPT1QpOwotCi0gICAgICBuZXh0VG9rZW4oKTsKLSAgICB9IGVsc2UgaWYgKG1fdG9rZW4gPT0gbnVsbCkgewotICAgICAgZXJyb3IoWFBBVEhFcnJvclJlc291cmNlcy5FUl9FWFBFQ1RFRF9MT0NfUEFUSF9BVF9FTkRfRVhQUiwgbnVsbCk7Ci0gICAgfQotCi0gICAgaWYgKG1fdG9rZW4gIT0gbnVsbCkKLSAgICB7Ci0gICAgICBpZiAoIVJlbGF0aXZlTG9jYXRpb25QYXRoKCkgJiYgIXNlZW5TbGFzaCkKLSAgICAgIHsKLSAgICAgICAgLy8gTmVpdGhlciBhICcvJyBub3IgYSBSZWxhdGl2ZUxvY2F0aW9uUGF0aCAtIGkuZS4sIG1hdGNoZWQgbm90aGluZwotICAgICAgICAvLyAiTG9jYXRpb24gcGF0aCBleHBlY3RlZCwgYnV0IGZvdW5kICIrbV90b2tlbisiIHdhcyBlbmNvdW50ZXJlZC4iCi0gICAgICAgIGVycm9yKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfRVhQRUNURURfTE9DX1BBVEgsCi0gICAgICAgICAgICAgIG5ldyBPYmplY3QgW10ge21fdG9rZW59KTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICAvLyBUZXJtaW5hdGUgZm9yIHNhZmV0eS4KLSAgICBtX29wcy5zZXRPcChtX29wcy5nZXRPcChPcE1hcC5NQVBJTkRFWF9MRU5HVEgpLCBPcENvZGVzLkVORE9QKTsKLSAgICBtX29wcy5zZXRPcChPcE1hcC5NQVBJTkRFWF9MRU5HVEgsbV9vcHMuZ2V0T3AoT3BNYXAuTUFQSU5ERVhfTEVOR1RIKSArIDEpOwotICAgIG1fb3BzLnNldE9wKG9wUG9zICsgT3BNYXAuTUFQSU5ERVhfTEVOR1RILAotICAgICAgbV9vcHMuZ2V0T3AoT3BNYXAuTUFQSU5ERVhfTEVOR1RIKSAtIG9wUG9zKTsKLSAgfQotCi0gIC8qKgotICAgKgotICAgKiBSZWxhdGl2ZUxvY2F0aW9uUGF0aCA6Oj0gU3RlcAotICAgKiB8IFJlbGF0aXZlTG9jYXRpb25QYXRoICcvJyBTdGVwCi0gICAqIHwgQWJicmV2aWF0ZWRSZWxhdGl2ZUxvY2F0aW9uUGF0aAotICAgKgotICAgKiBAcmV0dXJucyB0cnVlIGlmLCBhbmQgb25seSBpZiwgYSBSZWxhdGl2ZUxvY2F0aW9uUGF0aCB3YXMgbWF0Y2hlZAotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHByb3RlY3RlZCBib29sZWFuIFJlbGF0aXZlTG9jYXRpb25QYXRoKCkKLSAgICAgICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICBpZiAoIVN0ZXAoKSkKLSAgICB7Ci0gICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgd2hpbGUgKHRva2VuSXMoJy8nKSkKLSAgICB7Ci0gICAgICBuZXh0VG9rZW4oKTsKLQotICAgICAgaWYgKCFTdGVwKCkpCi0gICAgICB7Ci0gICAgICAgIC8vIFJlbGF0aXZlTG9jYXRpb25QYXRoIGNhbid0IGVuZCB3aXRoIGEgdHJhaWxpbmcgJy8nCi0gICAgICAgIC8vICJMb2NhdGlvbiBzdGVwIGV4cGVjdGVkIGZvbGxvd2luZyAnLycgb3IgJy8vJyIKLSAgICAgICAgZXJyb3IoWFBBVEhFcnJvclJlc291cmNlcy5FUl9FWFBFQ1RFRF9MT0NfU1RFUCwgbnVsbCk7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgcmV0dXJuIHRydWU7Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICogU3RlcCAgICA6Oj0gICAgQmFzaXMgUHJlZGljYXRlCi0gICAqIHwgQWJicmV2aWF0ZWRTdGVwCi0gICAqCi0gICAqIEByZXR1cm5zIGZhbHNlIGlmIHN0ZXAgd2FzIGVtcHR5IChvciBvbmx5IGEgJy8nKTsgdHJ1ZSwgb3RoZXJ3aXNlCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHJvdGVjdGVkIGJvb2xlYW4gU3RlcCgpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICBpbnQgb3BQb3MgPSBtX29wcy5nZXRPcChPcE1hcC5NQVBJTkRFWF9MRU5HVEgpOwotCi0gICAgYm9vbGVhbiBkb3VibGVTbGFzaCA9IHRva2VuSXMoJy8nKTsKLQotICAgIC8vIEF0IG1vc3QgYSBzaW5nbGUgJy8nIGJlZm9yZSBlYWNoIFN0ZXAgaXMgY29uc3VtZWQgYnkgY2FsbGVyOyBpZiB0aGUKLSAgICAvLyBmaXJzdCB0aGluZyBpcyBhICcvJywgdGhhdCBtZWFucyB3ZSBoYWQgJy8vJyBhbmQgdGhlIFN0ZXAgbXVzdCBub3QKLSAgICAvLyBiZSBlbXB0eS4KLSAgICBpZiAoZG91YmxlU2xhc2gpCi0gICAgewotICAgICAgbmV4dFRva2VuKCk7Ci0KLSAgICAgIGFwcGVuZE9wKDIsIE9wQ29kZXMuRlJPTV9ERVNDRU5EQU5UU19PUl9TRUxGKTsKLQotICAgICAgLy8gSGF2ZSB0byBmaXggdXAgZm9yIHBhdHRlcm5zIHN1Y2ggYXMgJy8vQGZvbycgb3IgJy8vYXR0cmlidXRlOjpmb28nLAotICAgICAgLy8gd2hpY2ggdHJhbnNsYXRlIHRvICdkZXNjZW5kYW50LW9yLXNlbGY6Om5vZGUoKS9hdHRyaWJ1dGU6OmZvbycuCi0gICAgICAvLyBub3RpY2UgSSBsZWF2ZSB0aGUgJy8nIG9uIHRoZSBxdWV1ZSwgc28gdGhlIG5leHQgd2lsbCBiZSBwcm9jZXNzZWQKLSAgICAgIC8vIGJ5IGEgcmVndWxhciBzdGVwIHBhdHRlcm4uCi0KLSAgICAgIC8vIE1ha2Ugcm9vbSBmb3IgdGVsbGluZyBob3cgbG9uZyB0aGUgc3RlcCBpcyB3aXRob3V0IHRoZSBwcmVkaWNhdGUKLSAgICAgIG1fb3BzLnNldE9wKE9wTWFwLk1BUElOREVYX0xFTkdUSCxtX29wcy5nZXRPcChPcE1hcC5NQVBJTkRFWF9MRU5HVEgpICsgMSk7Ci0gICAgICBtX29wcy5zZXRPcChtX29wcy5nZXRPcChPcE1hcC5NQVBJTkRFWF9MRU5HVEgpLCBPcENvZGVzLk5PREVUWVBFX05PREUpOwotICAgICAgbV9vcHMuc2V0T3AoT3BNYXAuTUFQSU5ERVhfTEVOR1RILG1fb3BzLmdldE9wKE9wTWFwLk1BUElOREVYX0xFTkdUSCkgKyAxKTsKLQotICAgICAgLy8gVGVsbCBob3cgbG9uZyB0aGUgc3RlcCBpcyB3aXRob3V0IHRoZSBwcmVkaWNhdGUKLSAgICAgIG1fb3BzLnNldE9wKG9wUG9zICsgT3BNYXAuTUFQSU5ERVhfTEVOR1RIICsgMSwKLSAgICAgICAgICBtX29wcy5nZXRPcChPcE1hcC5NQVBJTkRFWF9MRU5HVEgpIC0gb3BQb3MpOwotCi0gICAgICAvLyBUZWxsIGhvdyBsb25nIHRoZSBzdGVwIGlzIHdpdGggdGhlIHByZWRpY2F0ZQotICAgICAgbV9vcHMuc2V0T3Aob3BQb3MgKyBPcE1hcC5NQVBJTkRFWF9MRU5HVEgsCi0gICAgICAgICAgbV9vcHMuZ2V0T3AoT3BNYXAuTUFQSU5ERVhfTEVOR1RIKSAtIG9wUG9zKTsKLQotICAgICAgb3BQb3MgPSBtX29wcy5nZXRPcChPcE1hcC5NQVBJTkRFWF9MRU5HVEgpOwotICAgIH0KLQotICAgIGlmICh0b2tlbklzKCIuIikpCi0gICAgewotICAgICAgbmV4dFRva2VuKCk7Ci0KLSAgICAgIGlmICh0b2tlbklzKCdbJykpCi0gICAgICB7Ci0gICAgICAgIGVycm9yKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfUFJFRElDQVRFX0lMTEVHQUxfU1lOVEFYLCBudWxsKTsgIC8vIicuLltwcmVkaWNhdGVdJyBvciAnLltwcmVkaWNhdGVdJyBpcyBpbGxlZ2FsIHN5bnRheC4gIFVzZSAnc2VsZjo6bm9kZSgpW3ByZWRpY2F0ZV0nIGluc3RlYWQuIik7Ci0gICAgICB9Ci0KLSAgICAgIGFwcGVuZE9wKDQsIE9wQ29kZXMuRlJPTV9TRUxGKTsKLQotICAgICAgLy8gVGVsbCBob3cgbG9uZyB0aGUgc3RlcCBpcyB3aXRob3V0IHRoZSBwcmVkaWNhdGUKLSAgICAgIG1fb3BzLnNldE9wKG1fb3BzLmdldE9wKE9wTWFwLk1BUElOREVYX0xFTkdUSCkgLSAyLDQpOwotICAgICAgbV9vcHMuc2V0T3AobV9vcHMuZ2V0T3AoT3BNYXAuTUFQSU5ERVhfTEVOR1RIKSAtIDEsIE9wQ29kZXMuTk9ERVRZUEVfTk9ERSk7Ci0gICAgfQotICAgIGVsc2UgaWYgKHRva2VuSXMoIi4uIikpCi0gICAgewotICAgICAgbmV4dFRva2VuKCk7Ci0gICAgICBhcHBlbmRPcCg0LCBPcENvZGVzLkZST01fUEFSRU5UKTsKLQotICAgICAgLy8gVGVsbCBob3cgbG9uZyB0aGUgc3RlcCBpcyB3aXRob3V0IHRoZSBwcmVkaWNhdGUKLSAgICAgIG1fb3BzLnNldE9wKG1fb3BzLmdldE9wKE9wTWFwLk1BUElOREVYX0xFTkdUSCkgLSAyLDQpOwotICAgICAgbV9vcHMuc2V0T3AobV9vcHMuZ2V0T3AoT3BNYXAuTUFQSU5ERVhfTEVOR1RIKSAtIDEsIE9wQ29kZXMuTk9ERVRZUEVfTk9ERSk7Ci0gICAgfQotCi0gICAgLy8gVGhlcmUgaXMgcHJvYmFibHkgYSBiZXR0ZXIgd2F5IHRvIHRlc3QgZm9yIHRoaXMKLSAgICAvLyB0cmFuc2l0aW9uLi4uIGJ1dCBpdCBnZXRzIHJlYWwgaGFpcnkgaWYgeW91IHRyeQotICAgIC8vIHRvIGRvIGl0IGluIGJhc2lzKCkuCi0gICAgZWxzZSBpZiAodG9rZW5JcygnKicpIHx8IHRva2VuSXMoJ0AnKSB8fCB0b2tlbklzKCdfJykKLSAgICAgICAgICAgICB8fCAobV90b2tlbiE9IG51bGwgJiYgQ2hhcmFjdGVyLmlzTGV0dGVyKG1fdG9rZW4uY2hhckF0KDApKSkpCi0gICAgewotICAgICAgQmFzaXMoKTsKLQotICAgICAgd2hpbGUgKHRva2VuSXMoJ1snKSkKLSAgICAgIHsKLSAgICAgICAgUHJlZGljYXRlKCk7Ci0gICAgICB9Ci0KLSAgICAgIC8vIFRlbGwgaG93IGxvbmcgdGhlIGVudGlyZSBzdGVwIGlzLgotICAgICAgbV9vcHMuc2V0T3Aob3BQb3MgKyBPcE1hcC5NQVBJTkRFWF9MRU5HVEgsCi0gICAgICAgIG1fb3BzLmdldE9wKE9wTWFwLk1BUElOREVYX0xFTkdUSCkgLSBvcFBvcyk7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICAvLyBObyBTdGVwIG1hdGNoZWQgLSB0aGF0J3MgYW4gZXJyb3IgaWYgcHJldmlvdXMgdGhpbmcgd2FzIGEgJy8vJwotICAgICAgaWYgKGRvdWJsZVNsYXNoKQotICAgICAgewotICAgICAgICAvLyAiTG9jYXRpb24gc3RlcCBleHBlY3RlZCBmb2xsb3dpbmcgJy8nIG9yICcvLyciCi0gICAgICAgIGVycm9yKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfRVhQRUNURURfTE9DX1NURVAsIG51bGwpOwotICAgICAgfQotCi0gICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgcmV0dXJuIHRydWU7Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICogQmFzaXMgICAgOjo9ICAgIEF4aXNOYW1lICc6OicgTm9kZVRlc3QKLSAgICogfCBBYmJyZXZpYXRlZEJhc2lzCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgQmFzaXMoKSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpbnQgb3BQb3MgPSBtX29wcy5nZXRPcChPcE1hcC5NQVBJTkRFWF9MRU5HVEgpOwotICAgIGludCBheGVzVHlwZTsKLQotICAgIC8vIFRoZSBuZXh0IGJsb2NrcyBndWFyYW50ZWUgdGhhdCBhIEZST01fWFhYIHdpbGwgYmUgYWRkZWQuCi0gICAgaWYgKGxvb2thaGVhZCgiOjoiLCAxKSkKLSAgICB7Ci0gICAgICBheGVzVHlwZSA9IEF4aXNOYW1lKCk7Ci0KLSAgICAgIG5leHRUb2tlbigpOwotICAgICAgbmV4dFRva2VuKCk7Ci0gICAgfQotICAgIGVsc2UgaWYgKHRva2VuSXMoJ0AnKSkKLSAgICB7Ci0gICAgICBheGVzVHlwZSA9IE9wQ29kZXMuRlJPTV9BVFRSSUJVVEVTOwotCi0gICAgICBhcHBlbmRPcCgyLCBheGVzVHlwZSk7Ci0gICAgICBuZXh0VG9rZW4oKTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIGF4ZXNUeXBlID0gT3BDb2Rlcy5GUk9NX0NISUxEUkVOOwotCi0gICAgICBhcHBlbmRPcCgyLCBheGVzVHlwZSk7Ci0gICAgfQotCi0gICAgLy8gTWFrZSByb29tIGZvciB0ZWxsaW5nIGhvdyBsb25nIHRoZSBzdGVwIGlzIHdpdGhvdXQgdGhlIHByZWRpY2F0ZQotICAgIG1fb3BzLnNldE9wKE9wTWFwLk1BUElOREVYX0xFTkdUSCwgbV9vcHMuZ2V0T3AoT3BNYXAuTUFQSU5ERVhfTEVOR1RIKSArIDEpOwotCi0gICAgTm9kZVRlc3QoYXhlc1R5cGUpOwotCi0gICAgLy8gVGVsbCBob3cgbG9uZyB0aGUgc3RlcCBpcyB3aXRob3V0IHRoZSBwcmVkaWNhdGUKLSAgICBtX29wcy5zZXRPcChvcFBvcyArIE9wTWFwLk1BUElOREVYX0xFTkdUSCArIDEsCi0gICAgICBtX29wcy5nZXRPcChPcE1hcC5NQVBJTkRFWF9MRU5HVEgpIC0gb3BQb3MpOwotICAgfQotCi0gIC8qKgotICAgKgotICAgKiBCYXNpcyAgICA6Oj0gICAgQXhpc05hbWUgJzo6JyBOb2RlVGVzdAotICAgKiB8IEFiYnJldmlhdGVkQmFzaXMKLSAgICoKLSAgICogQHJldHVybiBGUk9NX1hYWCBheGVzIHR5cGUsIGZvdW5kIGluIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuY29tcGlsZXIuS2V5d29yZHN9LgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHByb3RlY3RlZCBpbnQgQXhpc05hbWUoKSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBPYmplY3QgdmFsID0gS2V5d29yZHMuZ2V0QXhpc05hbWUobV90b2tlbik7Ci0KLSAgICBpZiAobnVsbCA9PSB2YWwpCi0gICAgewotICAgICAgZXJyb3IoWFBBVEhFcnJvclJlc291cmNlcy5FUl9JTExFR0FMX0FYSVNfTkFNRSwKLSAgICAgICAgICAgIG5ldyBPYmplY3RbXXsgbV90b2tlbiB9KTsgIC8vImlsbGVnYWwgYXhpcyBuYW1lOiAiK21fdG9rZW4pOwotICAgIH0KLQotICAgIGludCBheGVzVHlwZSA9ICgoSW50ZWdlcikgdmFsKS5pbnRWYWx1ZSgpOwotCi0gICAgYXBwZW5kT3AoMiwgYXhlc1R5cGUpOwotCi0gICAgcmV0dXJuIGF4ZXNUeXBlOwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqIE5vZGVUZXN0ICAgIDo6PSAgICBXaWxkY2FyZE5hbWUKLSAgICogfCBOb2RlVHlwZSAnKCcgJyknCi0gICAqIHwgJ3Byb2Nlc3NpbmctaW5zdHJ1Y3Rpb24nICcoJyBMaXRlcmFsICcpJwotICAgKgotICAgKiBAcGFyYW0gYXhlc1R5cGUgRlJPTV9YWFggYXhlcyB0eXBlLCBmb3VuZCBpbiB7QGxpbmsgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmNvbXBpbGVyLktleXdvcmRzfS4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBOb2RlVGVzdChpbnQgYXhlc1R5cGUpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChsb29rYWhlYWQoJygnLCAxKSkKLSAgICB7Ci0gICAgICBPYmplY3Qgbm9kZVRlc3RPcCA9IEtleXdvcmRzLmdldE5vZGVUeXBlKG1fdG9rZW4pOwotCi0gICAgICBpZiAobnVsbCA9PSBub2RlVGVzdE9wKQotICAgICAgewotICAgICAgICBlcnJvcihYUEFUSEVycm9yUmVzb3VyY2VzLkVSX1VOS05PV05fTk9ERVRZUEUsCi0gICAgICAgICAgICAgIG5ldyBPYmplY3RbXXsgbV90b2tlbiB9KTsgIC8vIlVua25vd24gbm9kZXR5cGU6ICIrbV90b2tlbik7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIG5leHRUb2tlbigpOwotCi0gICAgICAgIGludCBudCA9ICgoSW50ZWdlcikgbm9kZVRlc3RPcCkuaW50VmFsdWUoKTsKLQotICAgICAgICBtX29wcy5zZXRPcChtX29wcy5nZXRPcChPcE1hcC5NQVBJTkRFWF9MRU5HVEgpLCBudCk7Ci0gICAgICAgIG1fb3BzLnNldE9wKE9wTWFwLk1BUElOREVYX0xFTkdUSCwgbV9vcHMuZ2V0T3AoT3BNYXAuTUFQSU5ERVhfTEVOR1RIKSArIDEpOwotCi0gICAgICAgIGNvbnN1bWVFeHBlY3RlZCgnKCcpOwotCi0gICAgICAgIGlmIChPcENvZGVzLk5PREVUWVBFX1BJID09IG50KQotICAgICAgICB7Ci0gICAgICAgICAgaWYgKCF0b2tlbklzKCcpJykpCi0gICAgICAgICAgewotICAgICAgICAgICAgTGl0ZXJhbCgpOwotICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGNvbnN1bWVFeHBlY3RlZCgnKScpOwotICAgICAgfQotICAgIH0KLSAgICBlbHNlCi0gICAgewotCi0gICAgICAvLyBBc3N1bWUgbmFtZSBvZiBhdHRyaWJ1dGUgb3IgZWxlbWVudC4KLSAgICAgIG1fb3BzLnNldE9wKG1fb3BzLmdldE9wKE9wTWFwLk1BUElOREVYX0xFTkdUSCksIE9wQ29kZXMuTk9ERU5BTUUpOwotICAgICAgbV9vcHMuc2V0T3AoT3BNYXAuTUFQSU5ERVhfTEVOR1RILCBtX29wcy5nZXRPcChPcE1hcC5NQVBJTkRFWF9MRU5HVEgpICsgMSk7Ci0KLSAgICAgIGlmIChsb29rYWhlYWQoJzonLCAxKSkKLSAgICAgIHsKLSAgICAgICAgaWYgKHRva2VuSXMoJyonKSkKLSAgICAgICAgewotICAgICAgICAgIG1fb3BzLnNldE9wKG1fb3BzLmdldE9wKE9wTWFwLk1BUElOREVYX0xFTkdUSCksIE9wQ29kZXMuRUxFTVdJTERDQVJEKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgIHsKLSAgICAgICAgICBtX29wcy5zZXRPcChtX29wcy5nZXRPcChPcE1hcC5NQVBJTkRFWF9MRU5HVEgpLCBtX3F1ZXVlTWFyayAtIDEpOwotCi0gICAgICAgICAgLy8gTWluaW1hbGlzdCBjaGVjayBmb3IgYW4gTkNOYW1lIC0ganVzdCBjaGVjayBmaXJzdCBjaGFyYWN0ZXIKLSAgICAgICAgICAvLyB0byBkaXN0aW5ndWlzaCBmcm9tIG90aGVyIHBvc3NpYmxlIHRva2VucwotICAgICAgICAgIGlmICghQ2hhcmFjdGVyLmlzTGV0dGVyKG1fdG9rZW5DaGFyKSAmJiAhdG9rZW5JcygnXycpKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIC8vICJOb2RlIHRlc3QgdGhhdCBtYXRjaGVzIGVpdGhlciBOQ05hbWU6KiBvciBRTmFtZSB3YXMgZXhwZWN0ZWQuIgotICAgICAgICAgICAgZXJyb3IoWFBBVEhFcnJvclJlc291cmNlcy5FUl9FWFBFQ1RFRF9OT0RFX1RFU1QsIG51bGwpOwotICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIG5leHRUb2tlbigpOwotICAgICAgICBjb25zdW1lRXhwZWN0ZWQoJzonKTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgbV9vcHMuc2V0T3AobV9vcHMuZ2V0T3AoT3BNYXAuTUFQSU5ERVhfTEVOR1RIKSwgT3BDb2Rlcy5FTVBUWSk7Ci0gICAgICB9Ci0KLSAgICAgIG1fb3BzLnNldE9wKE9wTWFwLk1BUElOREVYX0xFTkdUSCwgbV9vcHMuZ2V0T3AoT3BNYXAuTUFQSU5ERVhfTEVOR1RIKSArIDEpOwotCi0gICAgICBpZiAodG9rZW5JcygnKicpKQotICAgICAgewotICAgICAgICBtX29wcy5zZXRPcChtX29wcy5nZXRPcChPcE1hcC5NQVBJTkRFWF9MRU5HVEgpLCBPcENvZGVzLkVMRU1XSUxEQ0FSRCk7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIG1fb3BzLnNldE9wKG1fb3BzLmdldE9wKE9wTWFwLk1BUElOREVYX0xFTkdUSCksIG1fcXVldWVNYXJrIC0gMSk7Ci0KLSAgICAgICAgLy8gTWluaW1hbGlzdCBjaGVjayBmb3IgYW4gTkNOYW1lIC0ganVzdCBjaGVjayBmaXJzdCBjaGFyYWN0ZXIKLSAgICAgICAgLy8gdG8gZGlzdGluZ3Vpc2ggZnJvbSBvdGhlciBwb3NzaWJsZSB0b2tlbnMKLSAgICAgICAgaWYgKCFDaGFyYWN0ZXIuaXNMZXR0ZXIobV90b2tlbkNoYXIpICYmICF0b2tlbklzKCdfJykpCi0gICAgICAgIHsKLSAgICAgICAgICAvLyAiTm9kZSB0ZXN0IHRoYXQgbWF0Y2hlcyBlaXRoZXIgTkNOYW1lOiogb3IgUU5hbWUgd2FzIGV4cGVjdGVkLiIKLSAgICAgICAgICBlcnJvcihYUEFUSEVycm9yUmVzb3VyY2VzLkVSX0VYUEVDVEVEX05PREVfVEVTVCwgbnVsbCk7Ci0gICAgICAgIH0KLSAgICAgIH0KLQotICAgICAgbV9vcHMuc2V0T3AoT3BNYXAuTUFQSU5ERVhfTEVOR1RILCBtX29wcy5nZXRPcChPcE1hcC5NQVBJTkRFWF9MRU5HVEgpICsgMSk7Ci0KLSAgICAgIG5leHRUb2tlbigpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKgotICAgKiBQcmVkaWNhdGUgOjo9ICdbJyBQcmVkaWNhdGVFeHByICddJwotICAgKgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIFByZWRpY2F0ZSgpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmICh0b2tlbklzKCdbJykpCi0gICAgewotICAgICAgbmV4dFRva2VuKCk7Ci0gICAgICBQcmVkaWNhdGVFeHByKCk7Ci0gICAgICBjb25zdW1lRXhwZWN0ZWQoJ10nKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICogUHJlZGljYXRlRXhwciA6Oj0gRXhwcgotICAgKgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIFByZWRpY2F0ZUV4cHIoKSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpbnQgb3BQb3MgPSBtX29wcy5nZXRPcChPcE1hcC5NQVBJTkRFWF9MRU5HVEgpOwotCi0gICAgYXBwZW5kT3AoMiwgT3BDb2Rlcy5PUF9QUkVESUNBVEUpOwotICAgIEV4cHIoKTsKLQotICAgIC8vIFRlcm1pbmF0ZSBmb3Igc2FmZXR5LgotICAgIG1fb3BzLnNldE9wKG1fb3BzLmdldE9wKE9wTWFwLk1BUElOREVYX0xFTkdUSCksIE9wQ29kZXMuRU5ET1ApOwotICAgIG1fb3BzLnNldE9wKE9wTWFwLk1BUElOREVYX0xFTkdUSCwgbV9vcHMuZ2V0T3AoT3BNYXAuTUFQSU5ERVhfTEVOR1RIKSArIDEpOwotICAgIG1fb3BzLnNldE9wKG9wUG9zICsgT3BNYXAuTUFQSU5ERVhfTEVOR1RILAotICAgICAgbV9vcHMuZ2V0T3AoT3BNYXAuTUFQSU5ERVhfTEVOR1RIKSAtIG9wUG9zKTsKLSAgfQotCi0gIC8qKgotICAgKiBRTmFtZSA6Oj0gIChQcmVmaXggJzonKT8gTG9jYWxQYXJ0Ci0gICAqIFByZWZpeCA6Oj0gIE5DTmFtZQotICAgKiBMb2NhbFBhcnQgOjo9ICBOQ05hbWUKLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBRTmFtZSgpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICAvLyBOYW1lc3BhY2UKLSAgICBpZihsb29rYWhlYWQoJzonLCAxKSkKLSAgICB7Ci0gICAgICBtX29wcy5zZXRPcChtX29wcy5nZXRPcChPcE1hcC5NQVBJTkRFWF9MRU5HVEgpLCBtX3F1ZXVlTWFyayAtIDEpOwotICAgICAgbV9vcHMuc2V0T3AoT3BNYXAuTUFQSU5ERVhfTEVOR1RILCBtX29wcy5nZXRPcChPcE1hcC5NQVBJTkRFWF9MRU5HVEgpICsgMSk7Ci0KLSAgICAgIG5leHRUb2tlbigpOwotICAgICAgY29uc3VtZUV4cGVjdGVkKCc6Jyk7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBtX29wcy5zZXRPcChtX29wcy5nZXRPcChPcE1hcC5NQVBJTkRFWF9MRU5HVEgpLCBPcENvZGVzLkVNUFRZKTsKLSAgICAgIG1fb3BzLnNldE9wKE9wTWFwLk1BUElOREVYX0xFTkdUSCwgbV9vcHMuZ2V0T3AoT3BNYXAuTUFQSU5ERVhfTEVOR1RIKSArIDEpOwotICAgIH0KLQotICAgIC8vIExvY2FsIG5hbWUKLSAgICBtX29wcy5zZXRPcChtX29wcy5nZXRPcChPcE1hcC5NQVBJTkRFWF9MRU5HVEgpLCBtX3F1ZXVlTWFyayAtIDEpOwotICAgIG1fb3BzLnNldE9wKE9wTWFwLk1BUElOREVYX0xFTkdUSCwgbV9vcHMuZ2V0T3AoT3BNYXAuTUFQSU5ERVhfTEVOR1RIKSArIDEpOwotCi0gICAgbmV4dFRva2VuKCk7Ci0gIH0KLQotICAvKioKLSAgICogTkNOYW1lIDo6PSAgKExldHRlciB8ICdfJykgKE5DTmFtZUNoYXIpCi0gICAqIE5DTmFtZUNoYXIgOjo9ICBMZXR0ZXIgfCBEaWdpdCB8ICcuJyB8ICctJyB8ICdfJyB8IENvbWJpbmluZ0NoYXIgfCBFeHRlbmRlcgotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgTkNOYW1lKCkKLSAgewotCi0gICAgbV9vcHMuc2V0T3AobV9vcHMuZ2V0T3AoT3BNYXAuTUFQSU5ERVhfTEVOR1RIKSwgbV9xdWV1ZU1hcmsgLSAxKTsKLSAgICBtX29wcy5zZXRPcChPcE1hcC5NQVBJTkRFWF9MRU5HVEgsIG1fb3BzLmdldE9wKE9wTWFwLk1BUElOREVYX0xFTkdUSCkgKyAxKTsKLQotICAgIG5leHRUb2tlbigpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoZSB2YWx1ZSBvZiB0aGUgTGl0ZXJhbCBpcyB0aGUgc2VxdWVuY2Ugb2YgY2hhcmFjdGVycyBpbnNpZGUKLSAgICogdGhlICIgb3IgJyBjaGFyYWN0ZXJzPi4KLSAgICoKLSAgICogTGl0ZXJhbCAgOjo9ICAnIicgW14iXSogJyInCi0gICAqIHwgIiciIFteJ10qICInIgotICAgKgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIExpdGVyYWwoKSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpbnQgbGFzdCA9IG1fdG9rZW4ubGVuZ3RoKCkgLSAxOwotICAgIGNoYXIgYzAgPSBtX3Rva2VuQ2hhcjsKLSAgICBjaGFyIGNYID0gbV90b2tlbi5jaGFyQXQobGFzdCk7Ci0KLSAgICBpZiAoKChjMCA9PSAnXCInKSAmJiAoY1ggPT0gJ1wiJykpIHx8ICgoYzAgPT0gJ1wnJykgJiYgKGNYID09ICdcJycpKSkKLSAgICB7Ci0KLSAgICAgIC8vIE11dGF0ZSB0aGUgdG9rZW4gdG8gcmVtb3ZlIHRoZSBxdW90ZXMgYW5kIGhhdmUgdGhlIFhTdHJpbmcgb2JqZWN0Ci0gICAgICAvLyBhbHJlYWR5IG1hZGUuCi0gICAgICBpbnQgdG9rZW5RdWV1ZVBvcyA9IG1fcXVldWVNYXJrIC0gMTsKLQotICAgICAgbV9vcHMubV90b2tlblF1ZXVlLnNldEVsZW1lbnRBdChudWxsLHRva2VuUXVldWVQb3MpOwotCi0gICAgICBPYmplY3Qgb2JqID0gbmV3IFhTdHJpbmcobV90b2tlbi5zdWJzdHJpbmcoMSwgbGFzdCkpOwotCi0gICAgICBtX29wcy5tX3Rva2VuUXVldWUuc2V0RWxlbWVudEF0KG9iaix0b2tlblF1ZXVlUG9zKTsKLQotICAgICAgLy8gbGl0ID0gbV90b2tlbi5zdWJzdHJpbmcoMSwgbGFzdCk7Ci0gICAgICBtX29wcy5zZXRPcChtX29wcy5nZXRPcChPcE1hcC5NQVBJTkRFWF9MRU5HVEgpLCB0b2tlblF1ZXVlUG9zKTsKLSAgICAgIG1fb3BzLnNldE9wKE9wTWFwLk1BUElOREVYX0xFTkdUSCwgbV9vcHMuZ2V0T3AoT3BNYXAuTUFQSU5ERVhfTEVOR1RIKSArIDEpOwotCi0gICAgICBuZXh0VG9rZW4oKTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIGVycm9yKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfUEFUVEVSTl9MSVRFUkFMX05FRURTX0JFX1FVT1RFRCwKLSAgICAgICAgICAgIG5ldyBPYmplY3RbXXsgbV90b2tlbiB9KTsgIC8vIlBhdHRlcm4gbGl0ZXJhbCAoIittX3Rva2VuKyIpIG5lZWRzIHRvIGJlIHF1b3RlZCEiKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICogTnVtYmVyIDo6PSBbMC05XSsoJy4nWzAtOV0rKT8gfCAnLidbMC05XSsKLSAgICoKLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBOdW1iZXIoKSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAobnVsbCAhPSBtX3Rva2VuKQotICAgIHsKLQotICAgICAgLy8gTXV0YXRlIHRoZSB0b2tlbiB0byByZW1vdmUgdGhlIHF1b3RlcyBhbmQgaGF2ZSB0aGUgWE51bWJlciBvYmplY3QKLSAgICAgIC8vIGFscmVhZHkgbWFkZS4KLSAgICAgIGRvdWJsZSBudW07Ci0KLSAgICAgIHRyeQotICAgICAgewotICAgICAgICAvLyBYUGF0aCAxLjAgZG9lcyBub3Qgc3VwcG9ydCBudW1iZXIgaW4gZXhwIG5vdGF0aW9uCi0gICAgICAgIGlmICgobV90b2tlbi5pbmRleE9mKCdlJykgPiAtMSl8fChtX3Rva2VuLmluZGV4T2YoJ0UnKSA+IC0xKSkKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVtYmVyRm9ybWF0RXhjZXB0aW9uKCk7Ci0gICAgICAgIG51bSA9IERvdWJsZS52YWx1ZU9mKG1fdG9rZW4pLmRvdWJsZVZhbHVlKCk7Ci0gICAgICB9Ci0gICAgICBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIG5mZSkKLSAgICAgIHsKLSAgICAgICAgbnVtID0gMC4wOyAgLy8gdG8gc2h1dCB1cCBjb21waWxlci4KLQotICAgICAgICBlcnJvcihYUEFUSEVycm9yUmVzb3VyY2VzLkVSX0NPVUxETk9UX0JFX0ZPUk1BVFRFRF9UT19OVU1CRVIsCi0gICAgICAgICAgICAgIG5ldyBPYmplY3RbXXsgbV90b2tlbiB9KTsgIC8vbV90b2tlbisiIGNvdWxkIG5vdCBiZSBmb3JtYXR0ZWQgdG8gYSBudW1iZXIhIik7Ci0gICAgICB9Ci0KLSAgICAgIG1fb3BzLm1fdG9rZW5RdWV1ZS5zZXRFbGVtZW50QXQobmV3IFhOdW1iZXIobnVtKSxtX3F1ZXVlTWFyayAtIDEpOwotICAgICAgbV9vcHMuc2V0T3AobV9vcHMuZ2V0T3AoT3BNYXAuTUFQSU5ERVhfTEVOR1RIKSwgbV9xdWV1ZU1hcmsgLSAxKTsKLSAgICAgIG1fb3BzLnNldE9wKE9wTWFwLk1BUElOREVYX0xFTkdUSCwgbV9vcHMuZ2V0T3AoT3BNYXAuTUFQSU5ERVhfTEVOR1RIKSArIDEpOwotCi0gICAgICBuZXh0VG9rZW4oKTsKLSAgICB9Ci0gIH0KLQotICAvLyA9PT09PT09PT09PT09IFBBVFRFUk4gRlVOQ1RJT05TID09PT09PT09PT09PT09PT09Ci0KLSAgLyoqCi0gICAqCi0gICAqIFBhdHRlcm4gIDo6PSAgTG9jYXRpb25QYXRoUGF0dGVybgotICAgKiB8IFBhdHRlcm4gJ3wnIExvY2F0aW9uUGF0aFBhdHRlcm4KLSAgICoKLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBQYXR0ZXJuKCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgd2hpbGUgKHRydWUpCi0gICAgewotICAgICAgTG9jYXRpb25QYXRoUGF0dGVybigpOwotCi0gICAgICBpZiAodG9rZW5JcygnfCcpKQotICAgICAgewotICAgICAgICBuZXh0VG9rZW4oKTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgYnJlYWs7Ci0gICAgICB9Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqCi0gICAqIExvY2F0aW9uUGF0aFBhdHRlcm4gIDo6PSAgJy8nIFJlbGF0aXZlUGF0aFBhdHRlcm4/Ci0gICAqIHwgSWRLZXlQYXR0ZXJuICgoJy8nIHwgJy8vJykgUmVsYXRpdmVQYXRoUGF0dGVybik/Ci0gICAqIHwgJy8vJz8gUmVsYXRpdmVQYXRoUGF0dGVybgotICAgKgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIExvY2F0aW9uUGF0aFBhdHRlcm4oKSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpbnQgb3BQb3MgPSBtX29wcy5nZXRPcChPcE1hcC5NQVBJTkRFWF9MRU5HVEgpOwotCi0gICAgZmluYWwgaW50IFJFTEFUSVZFX1BBVEhfTk9UX1BFUk1JVFRFRCA9IDA7Ci0gICAgZmluYWwgaW50IFJFTEFUSVZFX1BBVEhfUEVSTUlUVEVEICAgICA9IDE7Ci0gICAgZmluYWwgaW50IFJFTEFUSVZFX1BBVEhfUkVRVUlSRUQgICAgICA9IDI7Ci0KLSAgICBpbnQgcmVsYXRpdmVQYXRoU3RhdHVzID0gUkVMQVRJVkVfUEFUSF9OT1RfUEVSTUlUVEVEOwotCi0gICAgYXBwZW5kT3AoMiwgT3BDb2Rlcy5PUF9MT0NBVElPTlBBVEhQQVRURVJOKTsKLQotICAgIGlmIChsb29rYWhlYWQoJygnLCAxKQotICAgICAgICAgICAgJiYgKHRva2VuSXMoS2V5d29yZHMuRlVOQ19JRF9TVFJJTkcpCi0gICAgICAgICAgICAgICAgfHwgdG9rZW5JcyhLZXl3b3Jkcy5GVU5DX0tFWV9TVFJJTkcpKSkKLSAgICB7Ci0gICAgICBJZEtleVBhdHRlcm4oKTsKLQotICAgICAgaWYgKHRva2VuSXMoJy8nKSkKLSAgICAgIHsKLSAgICAgICAgbmV4dFRva2VuKCk7Ci0KLSAgICAgICAgaWYgKHRva2VuSXMoJy8nKSkKLSAgICAgICAgewotICAgICAgICAgIGFwcGVuZE9wKDQsIE9wQ29kZXMuTUFUQ0hfQU5ZX0FOQ0VTVE9SKTsKLQotICAgICAgICAgIG5leHRUb2tlbigpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotICAgICAgICAgIGFwcGVuZE9wKDQsIE9wQ29kZXMuTUFUQ0hfSU1NRURJQVRFX0FOQ0VTVE9SKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIFRlbGwgaG93IGxvbmcgdGhlIHN0ZXAgaXMgd2l0aG91dCB0aGUgcHJlZGljYXRlCi0gICAgICAgIG1fb3BzLnNldE9wKG1fb3BzLmdldE9wKE9wTWFwLk1BUElOREVYX0xFTkdUSCkgLSAyLCA0KTsKLSAgICAgICAgbV9vcHMuc2V0T3AobV9vcHMuZ2V0T3AoT3BNYXAuTUFQSU5ERVhfTEVOR1RIKSAtIDEsIE9wQ29kZXMuTk9ERVRZUEVfRlVOQ1RFU1QpOwotCi0gICAgICAgIHJlbGF0aXZlUGF0aFN0YXR1cyA9IFJFTEFUSVZFX1BBVEhfUkVRVUlSRUQ7Ci0gICAgICB9Ci0gICAgfQotICAgIGVsc2UgaWYgKHRva2VuSXMoJy8nKSkKLSAgICB7Ci0gICAgICBpZiAobG9va2FoZWFkKCcvJywgMSkpCi0gICAgICB7Ci0gICAgICAgIGFwcGVuZE9wKDQsIE9wQ29kZXMuTUFUQ0hfQU5ZX0FOQ0VTVE9SKTsKLQotICAgICAgICAvLyBBZGRlZCB0aGlzIHRvIGZpeCBidWcgcmVwb3J0ZWQgYnkgTXlyaWFtIGZvciBtYXRjaD0iLy94L2EiCi0gICAgICAgIC8vIHBhdHRlcm5zLiAgSWYgeW91IGRvbid0IGRvIHRoaXMsIHRoZSAneCcgc3RlcCB3aWxsIHRoaW5rIGl0J3MgcGFydAotICAgICAgICAvLyBvZiBhICcvLycgcGF0dGVybiwgYW5kIHNvIHdpbGwgY2F1c2UgJ2EnIHRvIGJlIG1hdGNoZWQgd2hlbiBpdCBoYXMKLSAgICAgICAgLy8gYW55IGFuY2VzdG9yIHRoYXQgaXMgJ3gnLgotICAgICAgICBuZXh0VG9rZW4oKTsKLQotICAgICAgICByZWxhdGl2ZVBhdGhTdGF0dXMgPSBSRUxBVElWRV9QQVRIX1JFUVVJUkVEOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBhcHBlbmRPcCg0LCBPcENvZGVzLkZST01fUk9PVCk7Ci0KLSAgICAgICAgcmVsYXRpdmVQYXRoU3RhdHVzID0gUkVMQVRJVkVfUEFUSF9QRVJNSVRURUQ7Ci0gICAgICB9Ci0KLQotICAgICAgLy8gVGVsbCBob3cgbG9uZyB0aGUgc3RlcCBpcyB3aXRob3V0IHRoZSBwcmVkaWNhdGUKLSAgICAgIG1fb3BzLnNldE9wKG1fb3BzLmdldE9wKE9wTWFwLk1BUElOREVYX0xFTkdUSCkgLSAyLCA0KTsKLSAgICAgIG1fb3BzLnNldE9wKG1fb3BzLmdldE9wKE9wTWFwLk1BUElOREVYX0xFTkdUSCkgLSAxLCBPcENvZGVzLk5PREVUWVBFX1JPT1QpOwotCi0gICAgICBuZXh0VG9rZW4oKTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIHJlbGF0aXZlUGF0aFN0YXR1cyA9IFJFTEFUSVZFX1BBVEhfUkVRVUlSRUQ7Ci0gICAgfQotCi0gICAgaWYgKHJlbGF0aXZlUGF0aFN0YXR1cyAhPSBSRUxBVElWRV9QQVRIX05PVF9QRVJNSVRURUQpCi0gICAgewotICAgICAgaWYgKCF0b2tlbklzKCd8JykgJiYgKG51bGwgIT0gbV90b2tlbikpCi0gICAgICB7Ci0gICAgICAgIFJlbGF0aXZlUGF0aFBhdHRlcm4oKTsKLSAgICAgIH0KLSAgICAgIGVsc2UgaWYgKHJlbGF0aXZlUGF0aFN0YXR1cyA9PSBSRUxBVElWRV9QQVRIX1JFUVVJUkVEKQotICAgICAgewotICAgICAgICAvLyAiQSByZWxhdGl2ZSBwYXRoIHBhdHRlcm4gd2FzIGV4cGVjdGVkLiIKLSAgICAgICAgZXJyb3IoWFBBVEhFcnJvclJlc291cmNlcy5FUl9FWFBFQ1RFRF9SRUxfUEFUSF9QQVRURVJOLCBudWxsKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICAvLyBUZXJtaW5hdGUgZm9yIHNhZmV0eS4KLSAgICBtX29wcy5zZXRPcChtX29wcy5nZXRPcChPcE1hcC5NQVBJTkRFWF9MRU5HVEgpLCBPcENvZGVzLkVORE9QKTsKLSAgICBtX29wcy5zZXRPcChPcE1hcC5NQVBJTkRFWF9MRU5HVEgsIG1fb3BzLmdldE9wKE9wTWFwLk1BUElOREVYX0xFTkdUSCkgKyAxKTsKLSAgICBtX29wcy5zZXRPcChvcFBvcyArIE9wTWFwLk1BUElOREVYX0xFTkdUSCwKLSAgICAgIG1fb3BzLmdldE9wKE9wTWFwLk1BUElOREVYX0xFTkdUSCkgLSBvcFBvcyk7Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICogSWRLZXlQYXR0ZXJuICA6Oj0gICdpZCcgJygnIExpdGVyYWwgJyknCi0gICAqIHwgJ2tleScgJygnIExpdGVyYWwgJywnIExpdGVyYWwgJyknCi0gICAqIChBbHNvIGhhbmRsZSBkb2MoKSkKLSAgICoKLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBJZEtleVBhdHRlcm4oKSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgRnVuY3Rpb25DYWxsKCk7Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICogUmVsYXRpdmVQYXRoUGF0dGVybiAgOjo9ICBTdGVwUGF0dGVybgotICAgKiB8IFJlbGF0aXZlUGF0aFBhdHRlcm4gJy8nIFN0ZXBQYXR0ZXJuCi0gICAqIHwgUmVsYXRpdmVQYXRoUGF0dGVybiAnLy8nIFN0ZXBQYXR0ZXJuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgUmVsYXRpdmVQYXRoUGF0dGVybigpCi0gICAgICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIC8vIENhbGxlciB3aWxsIGhhdmUgY29uc3VtZWQgYW55ICcvJyBvciAnLy8nIHByZWNlZGluZyB0aGUKLSAgICAvLyBSZWxhdGl2ZVBhdGhQYXR0ZXJuLCBzbyBsZXQgU3RlcFBhdHRlcm4ga25vdyBpdCBjYW4ndCBiZWdpbiB3aXRoIGEgJy8nCi0gICAgYm9vbGVhbiB0cmFpbGluZ1NsYXNoQ29uc3VtZWQgPSBTdGVwUGF0dGVybihmYWxzZSk7Ci0KLSAgICB3aGlsZSAodG9rZW5JcygnLycpKQotICAgIHsKLSAgICAgIG5leHRUb2tlbigpOwotCi0gICAgICAvLyBTdGVwUGF0dGVybigpIG1heSBjb25zdW1lIGZpcnN0IHNsYXNoIG9mIHBhaXIgaW4gImEvL2IiIHdoaWxlCi0gICAgICAvLyBwcm9jZXNzaW5nIFN0ZXBQYXR0ZXJuICJhIi4gIE9uIG5leHQgaXRlcmF0aW9uLCBsZXQgU3RlcFBhdHRlcm4ga25vdwotICAgICAgLy8gdGhhdCBoYXBwZW5lZCwgc28gaXQgZG9lc24ndCBtYXRjaCBpbGwtZm9ybWVkIHBhdHRlcm5zIGxpa2UgImEvLy9iIi4KLSAgICAgIHRyYWlsaW5nU2xhc2hDb25zdW1lZCA9IFN0ZXBQYXR0ZXJuKCF0cmFpbGluZ1NsYXNoQ29uc3VtZWQpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKgotICAgKiBTdGVwUGF0dGVybiAgOjo9ICBBYmJyZXZpYXRlZE5vZGVUZXN0U3RlcAotICAgKgotICAgKiBAcGFyYW0gaXNMZWFkaW5nU2xhc2hQZXJtaXR0ZWQgYSBib29sZWFuIGluZGljYXRpbmcgd2hldGhlciBhIHNsYXNoIGNhbgotICAgKiAgICAgICAgYXBwZWFyIGF0IHRoZSBzdGFydCBvZiB0aGlzIHN0ZXAKLSAgICoKLSAgICogQHJldHVybiBib29sZWFuIGluZGljYXRpbmcgd2hldGhlciBhIHNsYXNoIGZvbGxvd2luZyB0aGUgc3RlcCB3YXMgY29uc3VtZWQKLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwcm90ZWN0ZWQgYm9vbGVhbiBTdGVwUGF0dGVybihib29sZWFuIGlzTGVhZGluZ1NsYXNoUGVybWl0dGVkKQotICAgICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHJldHVybiBBYmJyZXZpYXRlZE5vZGVUZXN0U3RlcChpc0xlYWRpbmdTbGFzaFBlcm1pdHRlZCk7Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICogQWJicmV2aWF0ZWROb2RlVGVzdFN0ZXAgICAgOjo9ICAgICdAJz8gTm9kZVRlc3QgUHJlZGljYXRlCi0gICAqCi0gICAqIEBwYXJhbSBpc0xlYWRpbmdTbGFzaFBlcm1pdHRlZCBhIGJvb2xlYW4gaW5kaWNhdGluZyB3aGV0aGVyIGEgc2xhc2ggY2FuCi0gICAqICAgICAgICBhcHBlYXIgYXQgdGhlIHN0YXJ0IG9mIHRoaXMgc3RlcAotICAgKgotICAgKiBAcmV0dXJuIGJvb2xlYW4gaW5kaWNhdGluZyB3aGV0aGVyIGEgc2xhc2ggZm9sbG93aW5nIHRoZSBzdGVwIHdhcyBjb25zdW1lZAotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHByb3RlY3RlZCBib29sZWFuIEFiYnJldmlhdGVkTm9kZVRlc3RTdGVwKGJvb2xlYW4gaXNMZWFkaW5nU2xhc2hQZXJtaXR0ZWQpCi0gICAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpbnQgb3BQb3MgPSBtX29wcy5nZXRPcChPcE1hcC5NQVBJTkRFWF9MRU5HVEgpOwotICAgIGludCBheGVzVHlwZTsKLQotICAgIC8vIFRoZSBuZXh0IGJsb2NrcyBndWFyYW50ZWUgdGhhdCBhIE1BVENIX1hYWCB3aWxsIGJlIGFkZGVkLgotICAgIGludCBtYXRjaFR5cGVQb3MgPSAtMTsKLQotICAgIGlmICh0b2tlbklzKCdAJykpCi0gICAgewotICAgICAgYXhlc1R5cGUgPSBPcENvZGVzLk1BVENIX0FUVFJJQlVURTsKLQotICAgICAgYXBwZW5kT3AoMiwgYXhlc1R5cGUpOwotICAgICAgbmV4dFRva2VuKCk7Ci0gICAgfQotICAgIGVsc2UgaWYgKHRoaXMubG9va2FoZWFkKCI6OiIsIDEpKQotICAgIHsKLSAgICAgIGlmICh0b2tlbklzKCJhdHRyaWJ1dGUiKSkKLSAgICAgIHsKLSAgICAgICAgYXhlc1R5cGUgPSBPcENvZGVzLk1BVENIX0FUVFJJQlVURTsKLQotICAgICAgICBhcHBlbmRPcCgyLCBheGVzVHlwZSk7Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmICh0b2tlbklzKCJjaGlsZCIpKQotICAgICAgewotICAgICAgICBtYXRjaFR5cGVQb3MgPSBtX29wcy5nZXRPcChPcE1hcC5NQVBJTkRFWF9MRU5HVEgpOwotICAgICAgICBheGVzVHlwZSA9IE9wQ29kZXMuTUFUQ0hfSU1NRURJQVRFX0FOQ0VTVE9SOwotCi0gICAgICAgIGFwcGVuZE9wKDIsIGF4ZXNUeXBlKTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgYXhlc1R5cGUgPSAtMTsKLQotICAgICAgICB0aGlzLmVycm9yKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfQVhFU19OT1RfQUxMT1dFRCwKLSAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117IHRoaXMubV90b2tlbiB9KTsKLSAgICAgIH0KLQotICAgICAgbmV4dFRva2VuKCk7Ci0gICAgICBuZXh0VG9rZW4oKTsKLSAgICB9Ci0gICAgZWxzZSBpZiAodG9rZW5JcygnLycpKQotICAgIHsKLSAgICAgIGlmICghaXNMZWFkaW5nU2xhc2hQZXJtaXR0ZWQpCi0gICAgICB7Ci0gICAgICAgIC8vICJBIHN0ZXAgd2FzIGV4cGVjdGVkIGluIHRoZSBwYXR0ZXJuLCBidXQgJy8nIHdhcyBlbmNvdW50ZXJlZC4iCi0gICAgICAgIGVycm9yKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfRVhQRUNURURfU1RFUF9QQVRURVJOLCBudWxsKTsKLSAgICAgIH0KLSAgICAgIGF4ZXNUeXBlID0gT3BDb2Rlcy5NQVRDSF9BTllfQU5DRVNUT1I7Ci0KLSAgICAgIGFwcGVuZE9wKDIsIGF4ZXNUeXBlKTsKLSAgICAgIG5leHRUb2tlbigpOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgbWF0Y2hUeXBlUG9zID0gbV9vcHMuZ2V0T3AoT3BNYXAuTUFQSU5ERVhfTEVOR1RIKTsKLSAgICAgIGF4ZXNUeXBlID0gT3BDb2Rlcy5NQVRDSF9JTU1FRElBVEVfQU5DRVNUT1I7Ci0KLSAgICAgIGFwcGVuZE9wKDIsIGF4ZXNUeXBlKTsKLSAgICB9Ci0KLSAgICAvLyBNYWtlIHJvb20gZm9yIHRlbGxpbmcgaG93IGxvbmcgdGhlIHN0ZXAgaXMgd2l0aG91dCB0aGUgcHJlZGljYXRlCi0gICAgbV9vcHMuc2V0T3AoT3BNYXAuTUFQSU5ERVhfTEVOR1RILCBtX29wcy5nZXRPcChPcE1hcC5NQVBJTkRFWF9MRU5HVEgpICsgMSk7Ci0KLSAgICBOb2RlVGVzdChheGVzVHlwZSk7Ci0KLSAgICAvLyBUZWxsIGhvdyBsb25nIHRoZSBzdGVwIGlzIHdpdGhvdXQgdGhlIHByZWRpY2F0ZQotICAgIG1fb3BzLnNldE9wKG9wUG9zICsgT3BNYXAuTUFQSU5ERVhfTEVOR1RIICsgMSwKLSAgICAgIG1fb3BzLmdldE9wKE9wTWFwLk1BUElOREVYX0xFTkdUSCkgLSBvcFBvcyk7Ci0KLSAgICB3aGlsZSAodG9rZW5JcygnWycpKQotICAgIHsKLSAgICAgIFByZWRpY2F0ZSgpOwotICAgIH0KLQotICAgIGJvb2xlYW4gdHJhaWxpbmdTbGFzaENvbnN1bWVkOwotCi0gICAgLy8gRm9yICJhLy9iIiwgd2hlcmUgImEiIGlzIGN1cnJlbnQgc3RlcCwgd2UgbmVlZCB0byBtYXJrIG9wZXJhdGlvbiBvZgotICAgIC8vIGN1cnJlbnQgc3RlcCBhcyAiTUFUQ0hfQU5ZX0FOQ0VTVE9SIi4gIFRoZW4gd2UnbGwgY29uc3VtZSB0aGUgZmlyc3QKLSAgICAvLyBzbGFzaCBhbmQgc3Vic2VxdWVudCBzdGVwIHdpbGwgYmUgdHJlYXRlZCBhcyBhIE1BVENIX0lNTUVESUFURV9BTkNFU1RPUgotICAgIC8vICh1bmxlc3MgaXQgdG9vIGlzIGZvbGxvd2VkIGJ5ICcvLycuKQotICAgIC8vCi0gICAgLy8gJVJFVklFVyUgIEZvbGxvd2luZyBpcyB3aGF0IGhhcHBlbnMgdG9kYXksIGJ1dCBJJ20gbm90IHN1cmUgdGhhdCdzCi0gICAgLy8gJVJFVklFVyUgIGNvcnJlY3QgYmVoYXZpb3VyLiAgUGVyaGFwcyBubyB2YWxpZCBjYXNlIGNvdWxkIGJlIGNvbnN0cnVjdGVkCi0gICAgLy8gJVJFVklFVyUgIHdoZXJlIGl0IHdvdWxkIG1hdHRlcj8KLSAgICAvLwotICAgIC8vIElmIGN1cnJlbnQgc3RlcCBpcyBvbiB0aGUgYXR0cmlidXRlIGF4aXMgKGUuZy4sICJAeC8vYiIpLCB3ZSB3b24ndAotICAgIC8vIGNoYW5nZSB0aGUgY3VycmVudCBzdGVwLCBhbmQgbGV0IGZvbGxvd2luZyBzdGVwIGJlIG1hcmtlZCBhcwotICAgIC8vIE1BVENIX0FOWV9BTkNFU1RPUiBvbiBuZXh0IGNhbGwgaW5zdGVhZC4KLSAgICBpZiAoKG1hdGNoVHlwZVBvcyA+IC0xKSAmJiB0b2tlbklzKCcvJykgJiYgbG9va2FoZWFkKCcvJywgMSkpCi0gICAgewotICAgICAgbV9vcHMuc2V0T3AobWF0Y2hUeXBlUG9zLCBPcENvZGVzLk1BVENIX0FOWV9BTkNFU1RPUik7Ci0KLSAgICAgIG5leHRUb2tlbigpOwotCi0gICAgICB0cmFpbGluZ1NsYXNoQ29uc3VtZWQgPSB0cnVlOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgdHJhaWxpbmdTbGFzaENvbnN1bWVkID0gZmFsc2U7Ci0gICAgfQotCi0gICAgLy8gVGVsbCBob3cgbG9uZyB0aGUgZW50aXJlIHN0ZXAgaXMuCi0gICAgbV9vcHMuc2V0T3Aob3BQb3MgKyBPcE1hcC5NQVBJTkRFWF9MRU5HVEgsCi0gICAgICBtX29wcy5nZXRPcChPcE1hcC5NQVBJTkRFWF9MRU5HVEgpIC0gb3BQb3MpOwotCi0gICAgcmV0dXJuIHRyYWlsaW5nU2xhc2hDb25zdW1lZDsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9jb21waWxlci9wYWNrYWdlLmh0bWwgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2NvbXBpbGVyL3BhY2thZ2UuaHRtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMGViMTQ1Zi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2NvbXBpbGVyL3BhY2thZ2UuaHRtbAorKysgL2Rldi9udWxsCkBAIC0xLDI4ICswLDAgQEAKLTwhLS0KLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0tLT4KLTwhLS0KLSAqIENvcHlyaWdodCAyMDAwLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotLS0+Ci08aHRtbD4KLSAgPHRpdGxlPlhQYXRoIHBhcnNpbmcgYW5kIGNvbXBpbGF0aW9uIHN1cHBvcnQgUGFja2FnZS48L3RpdGxlPgotICA8Ym9keT4KLSAgICA8cD5JbXBsZW1lbnRzIGFuIFhQYXRoIHBhcnNlciB3aGljaCBwcm9kdWNlcyBhbiBPcE1hcCwgYW5kIGEgc28tY2FsbGVkIENvbXBpbGVyCi0gICAgd2hpY2ggcHJvZHVjZXMgYW4gZXhwcmVzc2lvbiB0cmVlIGZvciBmYXN0IGV2YWx1YXRpb24uPHA+Ci0gPC9ib2R5PgotPC9odG1sPgotCi0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvZG9tYXBpL1hQYXRoRXZhbHVhdG9ySW1wbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9kb21hcGkvWFBhdGhFdmFsdWF0b3JJbXBsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDA5NmEyMzIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9kb21hcGkvWFBhdGhFdmFsdWF0b3JJbXBsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyNzMgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMi0yMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogWFBhdGhFdmFsdWF0b3JJbXBsLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTAgMDQ6MDQ6MDcgamVmZnN1dHRvciBFeHAgJAotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmRvbWFwaTsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLlByZWZpeFJlc29sdmVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5YUGF0aDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucmVzLlhQQVRIRXJyb3JSZXNvdXJjZXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLnJlcy5YUEFUSE1lc3NhZ2VzOwotaW1wb3J0IG9yZy53M2MuZG9tLkRPTUV4Y2VwdGlvbjsKLWltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotaW1wb3J0IG9yZy53M2MuZG9tLnhwYXRoLlhQYXRoRXZhbHVhdG9yOwotaW1wb3J0IG9yZy53M2MuZG9tLnhwYXRoLlhQYXRoRXhjZXB0aW9uOwotaW1wb3J0IG9yZy53M2MuZG9tLnhwYXRoLlhQYXRoRXhwcmVzc2lvbjsKLWltcG9ydCBvcmcudzNjLmRvbS54cGF0aC5YUGF0aE5TUmVzb2x2ZXI7Ci0KLS8qKgotICoKLSAqIFRoZSBjbGFzcyBwcm92aWRlcyBhbiBpbXBsZW1lbnRhdGlvbiBvZiBYUGF0aEV2YWx1YXRvciBhY2NvcmRpbmcKLSAqIHRvIHRoZSBET00gTDMgWFBhdGggU3BlY2lmaWNhdGlvbiwgV29ya2luZyBHcm91cCBOb3RlIDI2IEZlYnJ1YXJ5IDIwMDQuCi0gKgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvTk9URS1ET00tTGV2ZWwtMy1YUGF0aC0yMDA0MDIyNic+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDMgWFBhdGggU3BlY2lmaWNhdGlvbjwvYT4uPC9wPgotICoKLSAqIDwvcD5UaGUgZXZhbHVhdGlvbiBvZiBYUGF0aCBleHByZXNzaW9ucyBpcyBwcm92aWRlZCBieQotICogPGNvZGU+WFBhdGhFdmFsdWF0b3I8L2NvZGU+LCB3aGljaCB3aWxsIHByb3ZpZGUgZXZhbHVhdGlvbiBvZiBYUGF0aCAxLjAKLSAqIGV4cHJlc3Npb25zIHdpdGggbm8gc3BlY2lhbGl6ZWQgZXh0ZW5zaW9uIGZ1bmN0aW9ucyBvciB2YXJpYWJsZXMuIEl0IGlzCi0gKiBleHBlY3RlZCB0aGF0IHRoZSA8Y29kZT5YUGF0aEV2YWx1YXRvcjwvY29kZT4gaW50ZXJmYWNlIHdpbGwgYmUKLSAqIGltcGxlbWVudGVkIG9uIHRoZSBzYW1lIG9iamVjdCB3aGljaCBpbXBsZW1lbnRzIHRoZSA8Y29kZT5Eb2N1bWVudDwvY29kZT4KLSAqIGludGVyZmFjZSBpbiBhbiBpbXBsZW1lbnRhdGlvbiB3aGljaCBzdXBwb3J0cyB0aGUgWFBhdGggRE9NIG1vZHVsZS4KLSAqIDxjb2RlPlhQYXRoRXZhbHVhdG9yPC9jb2RlPiBpbXBsZW1lbnRhdGlvbnMgbWF5IGJlIGF2YWlsYWJsZSBmcm9tIG90aGVyCi0gKiBzb3VyY2VzIHRoYXQgbWF5IHByb3ZpZGUgc3VwcG9ydCBmb3Igc3BlY2lhbCBleHRlbnNpb24gZnVuY3Rpb25zIG9yCi0gKiB2YXJpYWJsZXMgd2hpY2ggYXJlIG5vdCBkZWZpbmVkIGluIHRoaXMgc3BlY2lmaWNhdGlvbi48L3A+Ci0gKgotICogQHNlZSBvcmcudzNjLmRvbS54cGF0aC5YUGF0aEV2YWx1YXRvcgotICoKLSAqIEB4c2wudXNhZ2UgaW50ZXJuYWwKLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIFhQYXRoRXZhbHVhdG9ySW1wbCBpbXBsZW1lbnRzIFhQYXRoRXZhbHVhdG9yIHsKLQotICAgICAgICAvKioKLSAgICAgICAgICogVGhpcyBwcmVmaXggcmVzb2x2ZXIgaXMgY3JlYXRlZCB3aGVuZXZlciBudWxsIGlzIHBhc3NlZCB0byB0aGUKLSAgICAgICAgICogZXZhbHVhdGUgbWV0aG9kLiAgSXRzIHB1cnBvc2UgaXMgdG8gc2F0aXNmeSB0aGUgRE9NIEwzIFhQYXRoIEFQSQotICAgICAgICAgKiByZXF1aXJlbWVudCB0aGF0IGlmIGEgbnVsbCBwcmVmaXggcmVzb2x2ZXIgaXMgdXNlZCwgYW4gZXhjZXB0aW9uCi0gICAgICAgICAqIHNob3VsZCBvbmx5IGJlIHRocm93biB3aGVuIGFuIGF0dGVtcHQgaXMgbWFkZSB0byByZXNvbHZlIGEgcHJlZml4LgotICAgICAgICAgKi8KLSAgICAgICAgcHJpdmF0ZSBjbGFzcyBEdW1teVByZWZpeFJlc29sdmVyIGltcGxlbWVudHMgUHJlZml4UmVzb2x2ZXIgewotCi0gICAgICAgICAgICAgICAgLyoqCi0gICAgICAgICAgICAgICAgICogQ29uc3RydWN0b3IgZm9yIER1bW15UHJlZml4UmVzb2x2ZXIuCi0gICAgICAgICAgICAgICAgICovCi0gICAgICAgICAgICAgICAgRHVtbXlQcmVmaXhSZXNvbHZlcigpIHt9Ci0KLSAgICAgICAgICAgICAgICAvKioKLSAgICAgICAgICAgICAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAgICAgKiAgIE5BTUVTUEFDRV9FUlI6IEFsd2F5cyB0aHJvd3MgdGhpcyBleGNlcHRpb25uCi0gICAgICAgICAgICAgICAgICoKLSAgICAgICAgICAgICAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuUHJlZml4UmVzb2x2ZXIjZ2V0TmFtZXNwYWNlRm9yUHJlZml4KFN0cmluZywgTm9kZSkKLSAgICAgICAgICAgICAgICAgKi8KLSAgICAgICAgICAgICAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWVzcGFjZUZvclByZWZpeChTdHJpbmcgcHJlZml4LCBOb2RlIGNvbnRleHQpIHsKLSAgICAgICAgICAgIFN0cmluZyBmbXNnID0gWFBBVEhNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoWFBBVEhFcnJvclJlc291cmNlcy5FUl9OVUxMX1JFU09MVkVSLCBudWxsKTsKLSAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5BTUVTUEFDRV9FUlIsIGZtc2cpOyAgIC8vIFVuYWJsZSB0byByZXNvbHZlIHByZWZpeCB3aXRoIG51bGwgcHJlZml4IHJlc29sdmVyLgotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8qKgotICAgICAgICAgICAgICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICAgICAqICAgTkFNRVNQQUNFX0VSUjogQWx3YXlzIHRocm93cyB0aGlzIGV4Y2VwdGlvbm4KLSAgICAgICAgICoKLSAgICAgICAgICAgICAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuUHJlZml4UmVzb2x2ZXIjZ2V0TmFtZXNwYWNlRm9yUHJlZml4KFN0cmluZykKLSAgICAgICAgICAgICAgICAgKi8KLSAgICAgICAgICAgICAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWVzcGFjZUZvclByZWZpeChTdHJpbmcgcHJlZml4KSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZ2V0TmFtZXNwYWNlRm9yUHJlZml4KHByZWZpeCxudWxsKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvKioKLSAgICAgICAgICAgICAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuUHJlZml4UmVzb2x2ZXIjaGFuZGxlc051bGxQcmVmaXhlcygpCi0gICAgICAgICAgICAgICAgICovCi0gICAgICAgICAgICAgICAgcHVibGljIGJvb2xlYW4gaGFuZGxlc051bGxQcmVmaXhlcygpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvKioKLSAgICAgICAgICAgICAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuUHJlZml4UmVzb2x2ZXIjZ2V0QmFzZUlkZW50aWZpZXIoKQotICAgICAgICAgICAgICAgICAqLwotICAgICAgICAgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0QmFzZUlkZW50aWZpZXIoKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgfQotCi0gICAgLyoqCi0gICAgICogVGhlIGRvY3VtZW50IHRvIGJlIHNlYXJjaGVkIHRvIHBhcmFsbGVsIHRoZSBjYXNlIHdoZXJlIHRoZSBYUGF0aEV2YWx1YXRvcgotICAgICAqIGlzIG9idGFpbmVkIGJ5IGNhc3RpbmcgYSBEb2N1bWVudC4KLSAgICAgKi8KLSAgICBwcml2YXRlIGZpbmFsIERvY3VtZW50IG1fZG9jOwotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0b3IgZm9yIFhQYXRoRXZhbHVhdG9ySW1wbC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBkb2MgVGhlIGRvY3VtZW50IHRvIGJlIHNlYXJjaGVkLCB0byBwYXJhbGxlbCB0aGUgY2FzZSB3aGVyZScnCi0gICAgICogICAgICAgICAgICB0aGUgWFBhdGhFdmFsdWF0b3IgaXMgb2J0YWluZWQgYnkgY2FzdGluZyB0aGUgZG9jdW1lbnQuCi0gICAgICovCi0gICAgcHVibGljIFhQYXRoRXZhbHVhdG9ySW1wbChEb2N1bWVudCBkb2MpIHsKLSAgICAgICAgbV9kb2MgPSBkb2M7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0b3IgaW4gdGhlIGNhc2UgdGhhdCB0aGUgWFBhdGggZXhwcmVzc2lvbiBjYW4gYmUgZXZhbHVhdGVkCi0gICAgICogd2l0aG91dCBuZWVkaW5nIGFuIFhNTCBkb2N1bWVudCBhdCBhbGwuCi0gICAgICoKLSAgICAgKi8KLSAgICBwdWJsaWMgWFBhdGhFdmFsdWF0b3JJbXBsKCkgewotICAgICAgICAgICAgbV9kb2MgPSBudWxsOwotICAgIH0KLQotICAgICAgICAvKioKLSAgICAgKiBDcmVhdGVzIGEgcGFyc2VkIFhQYXRoIGV4cHJlc3Npb24gd2l0aCByZXNvbHZlZCBuYW1lc3BhY2VzLiBUaGlzIGlzCi0gICAgICogdXNlZnVsIHdoZW4gYW4gZXhwcmVzc2lvbiB3aWxsIGJlIHJldXNlZCBpbiBhbiBhcHBsaWNhdGlvbiBzaW5jZSBpdAotICAgICAqIG1ha2VzIGl0IHBvc3NpYmxlIHRvIGNvbXBpbGUgdGhlIGV4cHJlc3Npb24gc3RyaW5nIGludG8gYSBtb3JlCi0gICAgICogZWZmaWNpZW50IGludGVybmFsIGZvcm0gYW5kIHByZXJlc29sdmUgYWxsIG5hbWVzcGFjZSBwcmVmaXhlcyB3aGljaAotICAgICAqIG9jY3VyIHdpdGhpbiB0aGUgZXhwcmVzc2lvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBleHByZXNzaW9uIFRoZSBYUGF0aCBleHByZXNzaW9uIHN0cmluZyB0byBiZSBwYXJzZWQuCi0gICAgICogQHBhcmFtIHJlc29sdmVyIFRoZSA8Y29kZT5yZXNvbHZlcjwvY29kZT4gcGVybWl0cyB0cmFuc2xhdGlvbiBvZgotICAgICAqICAgcHJlZml4ZXMgd2l0aGluIHRoZSBYUGF0aCBleHByZXNzaW9uIGludG8gYXBwcm9wcmlhdGUgbmFtZXNwYWNlIFVSSXMKLSAgICAgKiAgIC4gSWYgdGhpcyBpcyBzcGVjaWZpZWQgYXMgPGNvZGU+bnVsbDwvY29kZT4sIGFueSBuYW1lc3BhY2UgcHJlZml4Ci0gICAgICogICB3aXRoaW4gdGhlIGV4cHJlc3Npb24gd2lsbCByZXN1bHQgaW4gPGNvZGU+RE9NRXhjZXB0aW9uPC9jb2RlPgotICAgICAqICAgYmVpbmcgdGhyb3duIHdpdGggdGhlIGNvZGUgPGNvZGU+TkFNRVNQQUNFX0VSUjwvY29kZT4uCi0gICAgICogQHJldHVybiBUaGUgY29tcGlsZWQgZm9ybSBvZiB0aGUgWFBhdGggZXhwcmVzc2lvbi4KLSAgICAgKiBAZXhjZXB0aW9uIFhQYXRoRXhjZXB0aW9uCi0gICAgICogICBJTlZBTElEX0VYUFJFU1NJT05fRVJSOiBSYWlzZWQgaWYgdGhlIGV4cHJlc3Npb24gaXMgbm90IGxlZ2FsCi0gICAgICogICBhY2NvcmRpbmcgdG8gdGhlIHJ1bGVzIG9mIHRoZSA8Y29kZT5YUGF0aEV2YWx1YXRvcjwvY29kZT5pCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIE5BTUVTUEFDRV9FUlI6IFJhaXNlZCBpZiB0aGUgZXhwcmVzc2lvbiBjb250YWlucyBuYW1lc3BhY2UgcHJlZml4ZXMKLSAgICAgKiAgIHdoaWNoIGNhbm5vdCBiZSByZXNvbHZlZCBieSB0aGUgc3BlY2lmaWVkCi0gICAgICogICA8Y29kZT5YUGF0aE5TUmVzb2x2ZXI8L2NvZGU+LgotICAgICAqCi0gICAgICAgICAqIEBzZWUgb3JnLnczYy5kb20ueHBhdGguWFBhdGhFdmFsdWF0b3IjY3JlYXRlRXhwcmVzc2lvbihTdHJpbmcsIFhQYXRoTlNSZXNvbHZlcikKLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBYUGF0aEV4cHJlc3Npb24gY3JlYXRlRXhwcmVzc2lvbigKLSAgICAgICAgICAgICAgICBTdHJpbmcgZXhwcmVzc2lvbiwKLSAgICAgICAgICAgICAgICBYUGF0aE5TUmVzb2x2ZXIgcmVzb2x2ZXIpCi0gICAgICAgICAgICAgICAgdGhyb3dzIFhQYXRoRXhjZXB0aW9uLCBET01FeGNlcHRpb24gewotCi0gICAgICAgICAgICAgICAgdHJ5IHsKLQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gSWYgdGhlIHJlc29sdmVyIGlzIG51bGwsIGNyZWF0ZSBhIGR1bW15IHByZWZpeCByZXNvbHZlcgotICAgICAgICAgICAgICAgICAgICAgICAgWFBhdGggeHBhdGggPSAgbmV3IFhQYXRoKGV4cHJlc3Npb24sbnVsbCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKChudWxsID09IHJlc29sdmVyKSA/IG5ldyBEdW1teVByZWZpeFJlc29sdmVyKCkgOiAoKFByZWZpeFJlc29sdmVyKXJlc29sdmVyKSksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYUGF0aC5TRUxFQ1QpOwotCi0gICAgICAgICAgICByZXR1cm4gbmV3IFhQYXRoRXhwcmVzc2lvbkltcGwoeHBhdGgsIG1fZG9jKTsKLQotICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFRyYW5zZm9ybWVyRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5lZWQgdG8gcGFzcyBiYWNrIGV4Y2VwdGlvbiBjb2RlIERPTUV4Y2VwdGlvbi5OQU1FU1BBQ0VfRVJSIGFsc28uCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBFcnJvciBmb3VuZCBpbiBET00gTGV2ZWwgMyBYUGF0aCBUZXN0IFN1aXRlLgotICAgICAgICAgICAgICAgICAgICAgICAgaWYoZSBpbnN0YW5jZW9mIFhQYXRoU3R5bGVzaGVldERPTTNFeGNlcHRpb24pCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5BTUVTUEFDRV9FUlIsZS5nZXRNZXNzYWdlQW5kTG9jYXRpb24oKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBYUGF0aEV4Y2VwdGlvbihYUGF0aEV4Y2VwdGlvbi5JTlZBTElEX0VYUFJFU1NJT05fRVJSLGUuZ2V0TWVzc2FnZUFuZExvY2F0aW9uKCkpOwotCi0gICAgICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICogQWRhcHRzIGFueSBET00gbm9kZSB0byByZXNvbHZlIG5hbWVzcGFjZXMgc28gdGhhdCBhbiBYUGF0aCBleHByZXNzaW9uCi0gICAgICogY2FuIGJlIGVhc2lseSBldmFsdWF0ZWQgcmVsYXRpdmUgdG8gdGhlIGNvbnRleHQgb2YgdGhlIG5vZGUgd2hlcmUgaXQKLSAgICAgKiBhcHBlYXJlZCB3aXRoaW4gdGhlIGRvY3VtZW50LiBUaGlzIGFkYXB0ZXIgd29ya3MgbGlrZSB0aGUgRE9NIExldmVsIDMKLSAgICAgKiBtZXRob2QgPGNvZGU+bG9va3VwTmFtZXNwYWNlVVJJPC9jb2RlPiBvbiBub2RlcyBpbiByZXNvbHZpbmcgdGhlCi0gICAgICogbmFtZXNwYWNlVVJJIGZyb20gYSBnaXZlbiBwcmVmaXggdXNpbmcgdGhlIGN1cnJlbnQgaW5mb3JtYXRpb24gYXZhaWxhYmxlCi0gICAgICogaW4gdGhlIG5vZGUncyBoaWVyYXJjaHkgYXQgdGhlIHRpbWUgbG9va3VwTmFtZXNwYWNlVVJJIGlzIGNhbGxlZCwgYWxzbwotICAgICAqIGNvcnJlY3RseSByZXNvbHZpbmcgdGhlIGltcGxpY2l0IHhtbCBwcmVmaXguCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbm9kZVJlc29sdmVyIFRoZSBub2RlIHRvIGJlIHVzZWQgYXMgYSBjb250ZXh0IGZvciBuYW1lc3BhY2UKLSAgICAgKiAgIHJlc29sdXRpb24uCi0gICAgICogQHJldHVybiA8Y29kZT5YUGF0aE5TUmVzb2x2ZXI8L2NvZGU+IHdoaWNoIHJlc29sdmVzIG5hbWVzcGFjZXMgd2l0aAotICAgICAqICAgcmVzcGVjdCB0byB0aGUgZGVmaW5pdGlvbnMgaW4gc2NvcGUgZm9yIGEgc3BlY2lmaWVkIG5vZGUuCi0gICAgICoKLSAgICAgICAgICogQHNlZSBvcmcudzNjLmRvbS54cGF0aC5YUGF0aEV2YWx1YXRvciNjcmVhdGVOU1Jlc29sdmVyKE5vZGUpCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgWFBhdGhOU1Jlc29sdmVyIGNyZWF0ZU5TUmVzb2x2ZXIoTm9kZSBub2RlUmVzb2x2ZXIpIHsKLQotICAgICAgICAgICAgICAgIHJldHVybiBuZXcgWFBhdGhOU1Jlc29sdmVySW1wbCgobm9kZVJlc29sdmVyLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5ET0NVTUVOVF9OT0RFKQotICAgICAgICAgICAgICAgICAgID8gKChEb2N1bWVudCkgbm9kZVJlc29sdmVyKS5nZXREb2N1bWVudEVsZW1lbnQoKSA6IG5vZGVSZXNvbHZlcik7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgKiBFdmFsdWF0ZXMgYW4gWFBhdGggZXhwcmVzc2lvbiBzdHJpbmcgYW5kIHJldHVybnMgYSByZXN1bHQgb2YgdGhlCi0gICAgICogc3BlY2lmaWVkIHR5cGUgaWYgcG9zc2libGUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZXhwcmVzc2lvbiBUaGUgWFBhdGggZXhwcmVzc2lvbiBzdHJpbmcgdG8gYmUgcGFyc2VkIGFuZAotICAgICAqICAgZXZhbHVhdGVkLgotICAgICAqIEBwYXJhbSBjb250ZXh0Tm9kZSBUaGUgPGNvZGU+Y29udGV4dDwvY29kZT4gaXMgY29udGV4dCBub2RlIGZvciB0aGUKLSAgICAgKiAgIGV2YWx1YXRpb24gb2YgdGhpcyBYUGF0aCBleHByZXNzaW9uLiBJZiB0aGUgWFBhdGhFdmFsdWF0b3Igd2FzCi0gICAgICogICBvYnRhaW5lZCBieSBjYXN0aW5nIHRoZSA8Y29kZT5Eb2N1bWVudDwvY29kZT4gdGhlbiB0aGlzIG11c3QgYmUKLSAgICAgKiAgIG93bmVkIGJ5IHRoZSBzYW1lIGRvY3VtZW50IGFuZCBtdXN0IGJlIGEgPGNvZGU+RG9jdW1lbnQ8L2NvZGU+LAotICAgICAqICAgPGNvZGU+RWxlbWVudDwvY29kZT4sIDxjb2RlPkF0dHJpYnV0ZTwvY29kZT4sIDxjb2RlPlRleHQ8L2NvZGU+LAotICAgICAqICAgPGNvZGU+Q0RBVEFTZWN0aW9uPC9jb2RlPiwgPGNvZGU+Q29tbWVudDwvY29kZT4sCi0gICAgICogICA8Y29kZT5Qcm9jZXNzaW5nSW5zdHJ1Y3Rpb248L2NvZGU+LCBvciA8Y29kZT5YUGF0aE5hbWVzcGFjZTwvY29kZT4KLSAgICAgKiAgIG5vZGUuIElmIHRoZSBjb250ZXh0IG5vZGUgaXMgYSA8Y29kZT5UZXh0PC9jb2RlPiBvciBhCi0gICAgICogICA8Y29kZT5DREFUQVNlY3Rpb248L2NvZGU+LCB0aGVuIHRoZSBjb250ZXh0IGlzIGludGVycHJldGVkIGFzIHRoZQotICAgICAqICAgd2hvbGUgbG9naWNhbCB0ZXh0IG5vZGUgYXMgc2VlbiBieSBYUGF0aCwgdW5sZXNzIHRoZSBub2RlIGlzIGVtcHR5Ci0gICAgICogICBpbiB3aGljaCBjYXNlIGl0IG1heSBub3Qgc2VydmUgYXMgdGhlIFhQYXRoIGNvbnRleHQuCi0gICAgICogQHBhcmFtIHJlc29sdmVyIFRoZSA8Y29kZT5yZXNvbHZlcjwvY29kZT4gcGVybWl0cyB0cmFuc2xhdGlvbiBvZgotICAgICAqICAgcHJlZml4ZXMgd2l0aGluIHRoZSBYUGF0aCBleHByZXNzaW9uIGludG8gYXBwcm9wcmlhdGUgbmFtZXNwYWNlIFVSSXMKLSAgICAgKiAgIC4gSWYgdGhpcyBpcyBzcGVjaWZpZWQgYXMgPGNvZGU+bnVsbDwvY29kZT4sIGFueSBuYW1lc3BhY2UgcHJlZml4Ci0gICAgICogICB3aXRoaW4gdGhlIGV4cHJlc3Npb24gd2lsbCByZXN1bHQgaW4gPGNvZGU+RE9NRXhjZXB0aW9uPC9jb2RlPgotICAgICAqICAgYmVpbmcgdGhyb3duIHdpdGggdGhlIGNvZGUgPGNvZGU+TkFNRVNQQUNFX0VSUjwvY29kZT4uCi0gICAgICogQHBhcmFtIHR5cGUgSWYgYSBzcGVjaWZpYyA8Y29kZT50eXBlPC9jb2RlPiBpcyBzcGVjaWZpZWQsIHRoZW4gdGhlCi0gICAgICogICByZXN1bHQgd2lsbCBiZSBjb2VyY2VkIHRvIHJldHVybiB0aGUgc3BlY2lmaWVkIHR5cGUgcmVseWluZyBvbgotICAgICAqICAgWFBhdGggdHlwZSBjb252ZXJzaW9ucyBhbmQgZmFpbCBpZiB0aGUgZGVzaXJlZCBjb2VyY2lvbiBpcyBub3QKLSAgICAgKiAgIHBvc3NpYmxlLiBUaGlzIG11c3QgYmUgb25lIG9mIHRoZSB0eXBlIGNvZGVzIG9mCi0gICAgICogICA8Y29kZT5YUGF0aFJlc3VsdDwvY29kZT4uCi0gICAgICogQHBhcmFtIHJlc3VsdCBUaGUgPGNvZGU+cmVzdWx0PC9jb2RlPiBzcGVjaWZpZXMgYSBzcGVjaWZpYyByZXN1bHQKLSAgICAgKiAgIG9iamVjdCB3aGljaCBtYXkgYmUgcmV1c2VkIGFuZCByZXR1cm5lZCBieSB0aGlzIG1ldGhvZC4gSWYgdGhpcyBpcwotICAgICAqICAgc3BlY2lmaWVkIGFzIDxjb2RlPm51bGw8L2NvZGU+b3IgdGhlIGltcGxlbWVudGF0aW9uIGRvZXMgbm90IHJldXNlCi0gICAgICogICB0aGUgc3BlY2lmaWVkIHJlc3VsdCwgYSBuZXcgcmVzdWx0IG9iamVjdCB3aWxsIGJlIGNvbnN0cnVjdGVkIGFuZAotICAgICAqICAgcmV0dXJuZWQuRm9yIFhQYXRoIDEuMCByZXN1bHRzLCB0aGlzIG9iamVjdCB3aWxsIGJlIG9mIHR5cGUKLSAgICAgKiAgIDxjb2RlPlhQYXRoUmVzdWx0PC9jb2RlPi4KLSAgICAgKiBAcmV0dXJuIFRoZSByZXN1bHQgb2YgdGhlIGV2YWx1YXRpb24gb2YgdGhlIFhQYXRoIGV4cHJlc3Npb24uRm9yIFhQYXRoCi0gICAgICogICAxLjAgcmVzdWx0cywgdGhpcyBvYmplY3Qgd2lsbCBiZSBvZiB0eXBlIDxjb2RlPlhQYXRoUmVzdWx0PC9jb2RlPi4KLSAgICAgKiBAZXhjZXB0aW9uIFhQYXRoRXhjZXB0aW9uCi0gICAgICogICBJTlZBTElEX0VYUFJFU1NJT05fRVJSOiBSYWlzZWQgaWYgdGhlIGV4cHJlc3Npb24gaXMgbm90IGxlZ2FsCi0gICAgICogICBhY2NvcmRpbmcgdG8gdGhlIHJ1bGVzIG9mIHRoZSA8Y29kZT5YUGF0aEV2YWx1YXRvcjwvY29kZT5pCi0gICAgICogICA8YnI+VFlQRV9FUlI6IFJhaXNlZCBpZiB0aGUgcmVzdWx0IGNhbm5vdCBiZSBjb252ZXJ0ZWQgdG8gcmV0dXJuIHRoZQotICAgICAqICAgc3BlY2lmaWVkIHR5cGUuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIE5BTUVTUEFDRV9FUlI6IFJhaXNlZCBpZiB0aGUgZXhwcmVzc2lvbiBjb250YWlucyBuYW1lc3BhY2UgcHJlZml4ZXMKLSAgICAgKiAgIHdoaWNoIGNhbm5vdCBiZSByZXNvbHZlZCBieSB0aGUgc3BlY2lmaWVkCi0gICAgICogICA8Y29kZT5YUGF0aE5TUmVzb2x2ZXI8L2NvZGU+LgotICAgICAqICAgPGJyPldST05HX0RPQ1VNRU5UX0VSUjogVGhlIE5vZGUgaXMgZnJvbSBhIGRvY3VtZW50IHRoYXQgaXMgbm90Ci0gICAgICogICBzdXBwb3J0ZWQgYnkgdGhpcyBYUGF0aEV2YWx1YXRvci4KLSAgICAgKiAgIDxicj5OT1RfU1VQUE9SVEVEX0VSUjogVGhlIE5vZGUgaXMgbm90IGEgdHlwZSBwZXJtaXR0ZWQgYXMgYW4gWFBhdGgKLSAgICAgKiAgIGNvbnRleHQgbm9kZS4KLSAgICAgICAgICoKLSAgICAgICAgICogQHNlZSBvcmcudzNjLmRvbS54cGF0aC5YUGF0aEV2YWx1YXRvciNldmFsdWF0ZShTdHJpbmcsIE5vZGUsIFhQYXRoTlNSZXNvbHZlciwgc2hvcnQsIFhQYXRoUmVzdWx0KQotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIE9iamVjdCBldmFsdWF0ZSgKLSAgICAgICAgICAgICAgICBTdHJpbmcgZXhwcmVzc2lvbiwKLSAgICAgICAgICAgICAgICBOb2RlIGNvbnRleHROb2RlLAotICAgICAgICAgICAgICAgIFhQYXRoTlNSZXNvbHZlciByZXNvbHZlciwKLSAgICAgICAgICAgICAgICBzaG9ydCB0eXBlLAotICAgICAgICAgICAgICAgIE9iamVjdCByZXN1bHQpCi0gICAgICAgICAgICAgICAgdGhyb3dzIFhQYXRoRXhjZXB0aW9uLCBET01FeGNlcHRpb24gewotCi0gICAgICAgICAgICAgICAgWFBhdGhFeHByZXNzaW9uIHhwYXRoRXhwcmVzc2lvbiA9IGNyZWF0ZUV4cHJlc3Npb24oZXhwcmVzc2lvbiwgcmVzb2x2ZXIpOwotCi0gICAgICAgICAgICAgICAgcmV0dXJuICB4cGF0aEV4cHJlc3Npb24uZXZhbHVhdGUoY29udGV4dE5vZGUsIHR5cGUsIHJlc3VsdCk7Ci0gICAgICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9kb21hcGkvWFBhdGhFeHByZXNzaW9uSW1wbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9kb21hcGkvWFBhdGhFeHByZXNzaW9uSW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1YzkyZDU5Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvZG9tYXBpL1hQYXRoRXhwcmVzc2lvbkltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE4NSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAyLTIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBYUGF0aEV4cHJlc3Npb25JbXBsLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTAgMDQ6MDY6NTUgamVmZnN1dHRvciBFeHAgJAotICovCi0KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuZG9tYXBpOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5YUGF0aDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuWFBhdGhDb250ZXh0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhPYmplY3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLnJlcy5YUEFUSEVycm9yUmVzb3VyY2VzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5yZXMuWFBBVEhNZXNzYWdlczsKLWltcG9ydCBvcmcudzNjLmRvbS5ET01FeGNlcHRpb247Ci1pbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcudzNjLmRvbS54cGF0aC5YUGF0aEV4Y2VwdGlvbjsKLWltcG9ydCBvcmcudzNjLmRvbS54cGF0aC5YUGF0aEV4cHJlc3Npb247Ci1pbXBvcnQgb3JnLnczYy5kb20ueHBhdGguWFBhdGhOYW1lc3BhY2U7Ci0KLS8qKgotICoKLSAqIFRoZSBjbGFzcyBwcm92aWRlcyBhbiBpbXBsZW1lbnRhdGlvbiBvZiBYUGF0aEV4cHJlc3Npb24gYWNjb3JkaW5nCi0gKiB0byB0aGUgRE9NIEwzIFhQYXRoIFNwZWNpZmljYXRpb24sIFdvcmtpbmcgR3JvdXAgTm90ZSAyNiBGZWJydWFyeSAyMDA0LgotICoKLSAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L05PVEUtRE9NLUxldmVsLTMtWFBhdGgtMjAwNDAyMjYnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAzIFhQYXRoIFNwZWNpZmljYXRpb248L2E+LjwvcD4KLSAqCi0gKiA8cD5UaGUgPGNvZGU+WFBhdGhFeHByZXNzaW9uPC9jb2RlPiBpbnRlcmZhY2UgcmVwcmVzZW50cyBhIHBhcnNlZCBhbmQgcmVzb2x2ZWQKLSAqIFhQYXRoIGV4cHJlc3Npb24uPC9wPgotICoKLSAqIEBzZWUgb3JnLnczYy5kb20ueHBhdGguWFBhdGhFeHByZXNzaW9uCi0gKgotICogQHhzbC51c2FnZSBpbnRlcm5hbAotICovCi1jbGFzcyBYUGF0aEV4cHJlc3Npb25JbXBsIGltcGxlbWVudHMgWFBhdGhFeHByZXNzaW9uIHsKLQotICAvKioKLSAgICogVGhlIHhwYXRoIG9iamVjdCB0aGF0IHRoaXMgZXhwcmVzc2lvbiB3cmFwcwotICAgKi8KLSAgZmluYWwgcHJpdmF0ZSBYUGF0aCBtX3hwYXRoOwotCi0gIC8qKgotICAgKiBUaGUgZG9jdW1lbnQgdG8gYmUgc2VhcmNoZWQgdG8gcGFyYWxsZWwgdGhlIGNhc2Ugd2hlcmUgdGhlIFhQYXRoRXZhbHVhdG9yCi0gICAqIGlzIG9idGFpbmVkIGJ5IGNhc3RpbmcgYSBEb2N1bWVudC4KLSAgICovCi0gIGZpbmFsIHByaXZhdGUgRG9jdW1lbnQgbV9kb2M7Ci0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RvciBmb3IgWFBhdGhFeHByZXNzaW9uSW1wbC4KLSAgICAgKgotICAgICAqIEBwYXJhbSB4cGF0aCBUaGUgd3JhcHBlZCBYUGF0aCBvYmplY3QuCi0gICAgICogQHBhcmFtIGRvYyBUaGUgZG9jdW1lbnQgdG8gYmUgc2VhcmNoZWQsIHRvIHBhcmFsbGVsIHRoZSBjYXNlIHdoZXJlJycKLSAgICAgKiAgICAgICAgICAgIHRoZSBYUGF0aEV2YWx1YXRvciBpcyBvYnRhaW5lZCBieSBjYXN0aW5nIHRoZSBkb2N1bWVudC4KLSAgICAgKi8KLSAgICBYUGF0aEV4cHJlc3Npb25JbXBsKFhQYXRoIHhwYXRoLCBEb2N1bWVudCBkb2MpIHsKLSAgICAgICAgbV94cGF0aCA9IHhwYXRoOwotICAgICAgICBtX2RvYyA9IGRvYzsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKgotICAgICAqIFRoaXMgbWV0aG9kIHByb3ZpZGVzIGFuIGltcGxlbWVudGF0aW9uIFhQYXRoUmVzdWx0LmV2YWx1YXRlIGFjY29yZGluZwotICAgICAqIHRvIHRoZSBET00gTDMgWFBhdGggU3BlY2lmaWNhdGlvbiwgV29ya2luZyBHcm91cCBOb3RlIDI2IEZlYnJ1YXJ5IDIwMDQuCi0gICAgICoKLSAgICAgKiA8cD5TZWUgYWxzbyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9OT1RFLURPTS1MZXZlbC0zLVhQYXRoLTIwMDQwMjI2Jz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMyBYUGF0aCBTcGVjaWZpY2F0aW9uPC9hPi48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5FdmFsdWF0ZXMgdGhpcyBYUGF0aCBleHByZXNzaW9uIGFuZCByZXR1cm5zIGEgcmVzdWx0LjwvcD4KLSAgICAgKiBAcGFyYW0gY29udGV4dE5vZGUgVGhlIDxjb2RlPmNvbnRleHQ8L2NvZGU+IGlzIGNvbnRleHQgbm9kZSBmb3IgdGhlCi0gICAgICogICBldmFsdWF0aW9uIG9mIHRoaXMgWFBhdGggZXhwcmVzc2lvbi5JZiB0aGUgWFBhdGhFdmFsdWF0b3Igd2FzCi0gICAgICogICBvYnRhaW5lZCBieSBjYXN0aW5nIHRoZSA8Y29kZT5Eb2N1bWVudDwvY29kZT4gdGhlbiB0aGlzIG11c3QgYmUKLSAgICAgKiAgIG93bmVkIGJ5IHRoZSBzYW1lIGRvY3VtZW50IGFuZCBtdXN0IGJlIGEgPGNvZGU+RG9jdW1lbnQ8L2NvZGU+LAotICAgICAqICAgPGNvZGU+RWxlbWVudDwvY29kZT4sIDxjb2RlPkF0dHJpYnV0ZTwvY29kZT4sIDxjb2RlPlRleHQ8L2NvZGU+LAotICAgICAqICAgPGNvZGU+Q0RBVEFTZWN0aW9uPC9jb2RlPiwgPGNvZGU+Q29tbWVudDwvY29kZT4sCi0gICAgICogICA8Y29kZT5Qcm9jZXNzaW5nSW5zdHJ1Y3Rpb248L2NvZGU+LCBvciA8Y29kZT5YUGF0aE5hbWVzcGFjZTwvY29kZT4KLSAgICAgKiAgIG5vZGUuSWYgdGhlIGNvbnRleHQgbm9kZSBpcyBhIDxjb2RlPlRleHQ8L2NvZGU+IG9yIGEKLSAgICAgKiAgIDxjb2RlPkNEQVRBU2VjdGlvbjwvY29kZT4sIHRoZW4gdGhlIGNvbnRleHQgaXMgaW50ZXJwcmV0ZWQgYXMgdGhlCi0gICAgICogICB3aG9sZSBsb2dpY2FsIHRleHQgbm9kZSBhcyBzZWVuIGJ5IFhQYXRoLCB1bmxlc3MgdGhlIG5vZGUgaXMgZW1wdHkKLSAgICAgKiAgIGluIHdoaWNoIGNhc2UgaXQgbWF5IG5vdCBzZXJ2ZSBhcyB0aGUgWFBhdGggY29udGV4dC4KLSAgICAgKiBAcGFyYW0gdHlwZSBJZiBhIHNwZWNpZmljIDxjb2RlPnR5cGU8L2NvZGU+IGlzIHNwZWNpZmllZCwgdGhlbiB0aGUKLSAgICAgKiAgIHJlc3VsdCB3aWxsIGJlIGNvZXJjZWQgdG8gcmV0dXJuIHRoZSBzcGVjaWZpZWQgdHlwZSByZWx5aW5nIG9uCi0gICAgICogICBYUGF0aCBjb252ZXJzaW9ucyBhbmQgZmFpbCBpZiB0aGUgZGVzaXJlZCBjb2VyY2lvbiBpcyBub3QgcG9zc2libGUuCi0gICAgICogICBUaGlzIG11c3QgYmUgb25lIG9mIHRoZSB0eXBlIGNvZGVzIG9mIDxjb2RlPlhQYXRoUmVzdWx0PC9jb2RlPi4KLSAgICAqICBAcGFyYW0gcmVzdWx0IFRoZSA8Y29kZT5yZXN1bHQ8L2NvZGU+IHNwZWNpZmllcyBhIHNwZWNpZmljIHJlc3VsdAotICAgICAqICAgb2JqZWN0IHdoaWNoIG1heSBiZSByZXVzZWQgYW5kIHJldHVybmVkIGJ5IHRoaXMgbWV0aG9kLiBJZiB0aGlzIGlzCi0gICAgICogICBzcGVjaWZpZWQgYXMgPGNvZGU+bnVsbDwvY29kZT5vciB0aGUgaW1wbGVtZW50YXRpb24gZG9lcyBub3QgcmV1c2UKLSAgICAgKiAgIHRoZSBzcGVjaWZpZWQgcmVzdWx0LCBhIG5ldyByZXN1bHQgb2JqZWN0IHdpbGwgYmUgY29uc3RydWN0ZWQgYW5kCi0gICAgICogICByZXR1cm5lZC5Gb3IgWFBhdGggMS4wIHJlc3VsdHMsIHRoaXMgb2JqZWN0IHdpbGwgYmUgb2YgdHlwZQotICAgICAqICAgPGNvZGU+WFBhdGhSZXN1bHQ8L2NvZGU+LgotICAgICAqIEByZXR1cm4gVGhlIHJlc3VsdCBvZiB0aGUgZXZhbHVhdGlvbiBvZiB0aGUgWFBhdGggZXhwcmVzc2lvbi5Gb3IgWFBhdGgKLSAgICAgKiAgIDEuMCByZXN1bHRzLCB0aGlzIG9iamVjdCB3aWxsIGJlIG9mIHR5cGUgPGNvZGU+WFBhdGhSZXN1bHQ8L2NvZGU+LgotICAgICAqIEBleGNlcHRpb24gWFBhdGhFeGNlcHRpb24KLSAgICAgKiAgIFRZUEVfRVJSOiBSYWlzZWQgaWYgdGhlIHJlc3VsdCBjYW5ub3QgYmUgY29udmVydGVkIHRvIHJldHVybiB0aGUKLSAgICAgKiAgIHNwZWNpZmllZCB0eXBlLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBXUk9OR19ET0NVTUVOVF9FUlI6IFRoZSBOb2RlIGlzIGZyb20gYSBkb2N1bWVudCB0aGF0IGlzIG5vdCBzdXBwb3J0ZWQKLSAgICAgKiAgIGJ5IHRoZSBYUGF0aEV2YWx1YXRvciB0aGF0IGNyZWF0ZWQgdGhpcwotICAgICAqICAgPGNvZGU+WFBhdGhFeHByZXNzaW9uPC9jb2RlPi4KLSAgICAgKiAgIDxicj5OT1RfU1VQUE9SVEVEX0VSUjogVGhlIE5vZGUgaXMgbm90IGEgdHlwZSBwZXJtaXR0ZWQgYXMgYW4gWFBhdGgKLSAgICAgKiAgIGNvbnRleHQgbm9kZS4KLSAgICAgKgotICAgICAqIEBzZWUgb3JnLnczYy5kb20ueHBhdGguWFBhdGhFeHByZXNzaW9uI2V2YWx1YXRlKE5vZGUsIHNob3J0LCBYUGF0aFJlc3VsdCkKLSAgICAgKiBAeHNsLnVzYWdlIGludGVybmFsCi0gICAgICovCi0gICAgcHVibGljIE9iamVjdCBldmFsdWF0ZSgKLSAgICAgICAgTm9kZSBjb250ZXh0Tm9kZSwKLSAgICAgICAgc2hvcnQgdHlwZSwKLSAgICAgICAgT2JqZWN0IHJlc3VsdCkKLSAgICAgICAgdGhyb3dzIFhQYXRoRXhjZXB0aW9uLCBET01FeGNlcHRpb24gewotCi0gICAgICAgIC8vIElmIHRoZSBYUGF0aEV2YWx1YXRvciB3YXMgZGV0ZXJtaW5lZCBieSAiY2FzdGluZyIgdGhlIGRvY3VtZW50Ci0gICAgICAgIGlmIChtX2RvYyAhPSBudWxsKSB7Ci0KLSAgICAgICAgICAgIC8vIENoZWNrIHRoYXQgdGhlIGNvbnRleHQgbm9kZSBpcyBvd25lZCBieSB0aGUgc2FtZSBkb2N1bWVudAotICAgICAgICAgICAgaWYgKChjb250ZXh0Tm9kZSAhPSBtX2RvYykgJiYgKCFjb250ZXh0Tm9kZS5nZXRPd25lckRvY3VtZW50KCkuZXF1YWxzKG1fZG9jKSkpIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgZm1zZyA9IFhQQVRITWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfV1JPTkdfRE9DVU1FTlQsIG51bGwpOwotICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLldST05HX0RPQ1VNRU5UX0VSUiwgZm1zZyk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIENoZWNrIHRoYXQgdGhlIGNvbnRleHQgbm9kZSBpcyBhbiBhY2NlcHRhYmxlIG5vZGUgdHlwZQotICAgICAgICAgICAgc2hvcnQgbm9kZVR5cGUgPSBjb250ZXh0Tm9kZS5nZXROb2RlVHlwZSgpOwotICAgICAgICAgICAgaWYgKChub2RlVHlwZSAhPSBEb2N1bWVudC5ET0NVTUVOVF9OT0RFKSAmJgotICAgICAgICAgICAgICAgIChub2RlVHlwZSAhPSBEb2N1bWVudC5FTEVNRU5UX05PREUpICYmCi0gICAgICAgICAgICAgICAgKG5vZGVUeXBlICE9IERvY3VtZW50LkFUVFJJQlVURV9OT0RFKSAmJgotICAgICAgICAgICAgICAgIChub2RlVHlwZSAhPSBEb2N1bWVudC5URVhUX05PREUpICYmCi0gICAgICAgICAgICAgICAgKG5vZGVUeXBlICE9IERvY3VtZW50LkNEQVRBX1NFQ1RJT05fTk9ERSkgJiYKLSAgICAgICAgICAgICAgICAobm9kZVR5cGUgIT0gRG9jdW1lbnQuQ09NTUVOVF9OT0RFKSAmJgotICAgICAgICAgICAgICAgIChub2RlVHlwZSAhPSBEb2N1bWVudC5QUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREUpICYmCi0gICAgICAgICAgICAgICAgKG5vZGVUeXBlICE9IFhQYXRoTmFtZXNwYWNlLlhQQVRIX05BTUVTUEFDRV9OT0RFKSkgewotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgZm1zZyA9IFhQQVRITWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfV1JPTkdfTk9ERVRZUEUsIG51bGwpOwotICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUiwgZm1zZyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLwotICAgICAgICAvLyBJZiB0aGUgdHlwZSBpcyBub3QgYSBzdXBwb3J0ZWQgdHlwZSwgdGhyb3cgYW4gZXhjZXB0aW9uIGFuZCBiZQotICAgICAgICAvLyBkb25lIHdpdGggaXQhCi0gICAgICAgIGlmICghWFBhdGhSZXN1bHRJbXBsLmlzVmFsaWRUeXBlKHR5cGUpKSB7Ci0gICAgICAgICAgICBTdHJpbmcgZm1zZyA9IFhQQVRITWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfSU5WQUxJRF9YUEFUSF9UWVBFLCBuZXcgT2JqZWN0W10ge25ldyBJbnRlZ2VyKHR5cGUpfSk7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWFBhdGhFeGNlcHRpb24oWFBhdGhFeGNlcHRpb24uVFlQRV9FUlIsZm1zZyk7IC8vIEludmFsaWQgWFBhdGggdHlwZSBhcmd1bWVudDogezB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBDYWNoZSB4cGF0aCBjb250ZXh0PwotICAgICAgICBYUGF0aENvbnRleHQgeHBhdGhTdXBwb3J0ID0gbmV3IFhQYXRoQ29udGV4dCgpOwotCi0gICAgICAgIC8vIGlmIG1fZG9jdW1lbnQgaXMgbm90IG51bGwsIGJ1aWxkIHRoZSBEVE0gZnJvbSB0aGUgZG9jdW1lbnQKLSAgICAgICAgaWYgKG51bGwgIT0gbV9kb2MpIHsKLSAgICAgICAgICAgIHhwYXRoU3VwcG9ydC5nZXREVE1IYW5kbGVGcm9tTm9kZShtX2RvYyk7Ci0gICAgICAgIH0KLQotICAgICAgICBYT2JqZWN0IHhvYmogPSBudWxsOwotICAgICAgICB0cnkgewotICAgICAgICAgICAgeG9iaiA9IG1feHBhdGguZXhlY3V0ZSh4cGF0aFN1cHBvcnQsIGNvbnRleHROb2RlLCBudWxsKTsKLSAgICAgICAgfSBjYXRjaCAoVHJhbnNmb3JtZXJFeGNlcHRpb24gdGUpIHsKLSAgICAgICAgICAgIC8vIFdoYXQgc2hvdWxkIHdlIGRvIGhlcmU/Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWFBhdGhFeGNlcHRpb24oWFBhdGhFeGNlcHRpb24uSU5WQUxJRF9FWFBSRVNTSU9OX0VSUix0ZS5nZXRNZXNzYWdlQW5kTG9jYXRpb24oKSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBDcmVhdGUgYSBuZXcgWFBhdGhSZXN1bHQgb2JqZWN0Ci0gICAgICAgIC8vIFJldXNlIHJlc3VsdCBvYmplY3QgcGFzc2VkIGluPwotICAgICAgICAvLyBUaGUgY29uc3RydWN0b3Igd2lsbCBjaGVjayB0aGUgY29tcGF0aWJpbGl0eSBvZiB0eXBlIGFuZCB4b2JqIGFuZAotICAgICAgICAvLyB0aHJvdyBhbiBleGNlcHRpb24gaWYgdGhleSBhcmUgbm90IGNvbXBhdGlibGUuCi0gICAgICAgIHJldHVybiBuZXcgWFBhdGhSZXN1bHRJbXBsKHR5cGUseG9iaixjb250ZXh0Tm9kZSwgbV94cGF0aCk7Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2RvbWFwaS9YUGF0aE5TUmVzb2x2ZXJJbXBsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2RvbWFwaS9YUGF0aE5TUmVzb2x2ZXJJbXBsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDZjMTEwNjAuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9kb21hcGkvWFBhdGhOU1Jlc29sdmVySW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNjMgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMjAwMi0yMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogWFBhdGhOU1Jlc29sdmVySW1wbC5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzEwIDA0OjEzOjE5IGplZmZzdXR0b3IgRXhwICQKLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5kb21hcGk7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLlByZWZpeFJlc29sdmVyRGVmYXVsdDsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotaW1wb3J0IG9yZy53M2MuZG9tLnhwYXRoLlhQYXRoTlNSZXNvbHZlcjsKLQotLyoqCi0gKgotICogVGhlIGNsYXNzIHByb3ZpZGVzIGFuIGltcGxlbWVudGF0aW9uIFhQYXRoTlNSZXNvbHZlciBhY2NvcmRpbmcKLSAqIHRvIHRoZSBET00gTDMgWFBhdGggU3BlY2lmaWNhdGlvbiwgV29ya2luZyBHcm91cCBOb3RlIDI2IEZlYnJ1YXJ5IDIwMDQuCi0gKgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvTk9URS1ET00tTGV2ZWwtMy1YUGF0aC0yMDA0MDIyNic+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDMgWFBhdGggU3BlY2lmaWNhdGlvbjwvYT4uPC9wPgotICoKLSAqIDxwPlRoZSA8Y29kZT5YUGF0aE5TUmVzb2x2ZXI8L2NvZGU+IGludGVyZmFjZSBwZXJtaXQgPGNvZGU+cHJlZml4PC9jb2RlPgotICogc3RyaW5ncyBpbiB0aGUgZXhwcmVzc2lvbiB0byBiZSBwcm9wZXJseSBib3VuZCB0bwotICogPGNvZGU+bmFtZXNwYWNlVVJJPC9jb2RlPiBzdHJpbmdzLiA8Y29kZT5YUGF0aEV2YWx1YXRvcjwvY29kZT4gY2FuCi0gKiBjb25zdHJ1Y3QgYW4gaW1wbGVtZW50YXRpb24gb2YgPGNvZGU+WFBhdGhOU1Jlc29sdmVyPC9jb2RlPiBmcm9tIGEgbm9kZSwKLSAqIG9yIHRoZSBpbnRlcmZhY2UgbWF5IGJlIGltcGxlbWVudGVkIGJ5IGFueSBhcHBsaWNhdGlvbi48L3A+Ci0gKgotICogQHNlZSBvcmcudzNjLmRvbS54cGF0aC5YUGF0aE5TUmVzb2x2ZXIKLSAqIEB4c2wudXNhZ2UgaW50ZXJuYWwKLSAqLwotY2xhc3MgWFBhdGhOU1Jlc29sdmVySW1wbCBleHRlbmRzIFByZWZpeFJlc29sdmVyRGVmYXVsdCBpbXBsZW1lbnRzIFhQYXRoTlNSZXNvbHZlciB7Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIENvbnN0cnVjdG9yIGZvciBYUGF0aE5TUmVzb2x2ZXJJbXBsLgotICAgICAgICAgKiBAcGFyYW0geHBhdGhFeHByZXNzaW9uQ29udGV4dAotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIFhQYXRoTlNSZXNvbHZlckltcGwoTm9kZSB4cGF0aEV4cHJlc3Npb25Db250ZXh0KSB7Ci0gICAgICAgICAgICAgICAgc3VwZXIoeHBhdGhFeHByZXNzaW9uQ29udGV4dCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogQHNlZSBvcmcudzNjLmRvbS54cGF0aC5YUGF0aE5TUmVzb2x2ZXIjbG9va3VwTmFtZXNwYWNlVVJJKFN0cmluZykKLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBTdHJpbmcgbG9va3VwTmFtZXNwYWNlVVJJKFN0cmluZyBwcmVmaXgpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gc3VwZXIuZ2V0TmFtZXNwYWNlRm9yUHJlZml4KHByZWZpeCk7Ci0gICAgICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9kb21hcGkvWFBhdGhOYW1lc3BhY2VJbXBsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2RvbWFwaS9YUGF0aE5hbWVzcGFjZUltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNDFhMWQxNi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2RvbWFwaS9YUGF0aE5hbWVzcGFjZUltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDMyNCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAyLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBYUGF0aE5hbWVzcGFjZUltcGwuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xMCAwNDoxMDowMiBqZWZmc3V0dG9yIEV4cCAkCi0gKi8KLQotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5kb21hcGk7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5BdHRyOwotaW1wb3J0IG9yZy53M2MuZG9tLkRPTUV4Y2VwdGlvbjsKLWltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKLWltcG9ydCBvcmcudzNjLmRvbS5FbGVtZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLk5hbWVkTm9kZU1hcDsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGVMaXN0OwotaW1wb3J0IG9yZy53M2MuZG9tLnhwYXRoLlhQYXRoTmFtZXNwYWNlOwotCi1pbXBvcnQgb3JnLnczYy5kb20uVXNlckRhdGFIYW5kbGVyOwotCi0vKioKLSAqCi0gKgotICogVGhlIDxjb2RlPlhQYXRoTmFtZXNwYWNlPC9jb2RlPiBpbnRlcmZhY2UgaXMgcmV0dXJuZWQgYnkKLSAqIDxjb2RlPlhQYXRoUmVzdWx0PC9jb2RlPiBpbnRlcmZhY2VzIHRvIHJlcHJlc2VudCB0aGUgWFBhdGggbmFtZXNwYWNlIG5vZGUKLSAqIHR5cGUgdGhhdCBET00gbGFja3MuIFRoZXJlIGlzIG5vIHB1YmxpYyBjb25zdHJ1Y3RvciBmb3IgdGhpcyBub2RlIHR5cGUuCi0gKiBBdHRlbXB0cyB0byBwbGFjZSBpdCBpbnRvIGEgaGllcmFyY2h5IG9yIGEgTmFtZWROb2RlTWFwIHJlc3VsdCBpbiBhCi0gKiA8Y29kZT5ET01FeGNlcHRpb248L2NvZGU+IHdpdGggdGhlIGNvZGUgPGNvZGU+SElFUkFSQ0hZX1JFUVVFU1RfRVJSPC9jb2RlPgotICogLiBUaGlzIG5vZGUgaXMgcmVhZCBvbmx5LCBzbyBtZXRob2RzIG9yIHNldHRpbmcgb2YgYXR0cmlidXRlcyB0aGF0IHdvdWxkCi0gKiBtdXRhdGUgdGhlIG5vZGUgcmVzdWx0IGluIGEgRE9NRXhjZXB0aW9uIHdpdGggdGhlIGNvZGUKLSAqIDxjb2RlPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjwvY29kZT4uCi0gKiA8cD5UaGUgY29yZSBzcGVjaWZpY2F0aW9uIGRlc2NyaWJlcyBhdHRyaWJ1dGVzIG9mIHRoZSA8Y29kZT5Ob2RlPC9jb2RlPgotICogaW50ZXJmYWNlIHRoYXQgYXJlIGRpZmZlcmVudCBmb3IgZGlmZmVyZW50IG5vZGUgbm9kZSB0eXBlcyBidXQgZG9lcyBub3QKLSAqIGRlc2NyaWJlIDxjb2RlPlhQQVRIX05BTUVTUEFDRV9OT0RFPC9jb2RlPiwgc28gaGVyZSBpcyBhIGRlc2NyaXB0aW9uIG9mCi0gKiB0aG9zZSBhdHRyaWJ1dGVzIGZvciB0aGlzIG5vZGUgdHlwZS4gQWxsIGF0dHJpYnV0ZXMgb2YgPGNvZGU+Tm9kZTwvY29kZT4KLSAqIG5vdCBkZXNjcmliZWQgaW4gdGhpcyBzZWN0aW9uIGhhdmUgYSA8Y29kZT5udWxsPC9jb2RlPiBvcgotICogPGNvZGU+ZmFsc2U8L2NvZGU+IHZhbHVlLgotICogPHA+PGNvZGU+b3duZXJEb2N1bWVudDwvY29kZT4gbWF0Y2hlcyB0aGUgPGNvZGU+b3duZXJEb2N1bWVudDwvY29kZT4gb2YgdGhlCi0gKiA8Y29kZT5vd25lckVsZW1lbnQ8L2NvZGU+IGV2ZW4gaWYgdGhlIGVsZW1lbnQgaXMgbGF0ZXIgYWRvcHRlZC4KLSAqIDxwPjxjb2RlPnByZWZpeDwvY29kZT4gaXMgdGhlIHByZWZpeCBvZiB0aGUgbmFtZXNwYWNlIHJlcHJlc2VudGVkIGJ5IHRoZQotICogbm9kZS4KLSAqIDxwPjxjb2RlPm5vZGVOYW1lPC9jb2RlPiBpcyB0aGUgc2FtZSBhcyA8Y29kZT5wcmVmaXg8L2NvZGU+LgotICogPHA+PGNvZGU+bm9kZVR5cGU8L2NvZGU+IGlzIGVxdWFsIHRvIDxjb2RlPlhQQVRIX05BTUVTUEFDRV9OT0RFPC9jb2RlPi4KLSAqIDxwPjxjb2RlPm5hbWVzcGFjZVVSSTwvY29kZT4gaXMgdGhlIG5hbWVzcGFjZSBVUkkgb2YgdGhlIG5hbWVzcGFjZQotICogcmVwcmVzZW50ZWQgYnkgdGhlIG5vZGUuCi0gKiA8cD48Y29kZT5hZG9wdE5vZGU8L2NvZGU+LCA8Y29kZT5jbG9uZU5vZGU8L2NvZGU+LCBhbmQKLSAqIDxjb2RlPmltcG9ydE5vZGU8L2NvZGU+IGZhaWwgb24gdGhpcyBub2RlIHR5cGUgYnkgcmFpc2luZyBhCi0gKiA8Y29kZT5ET01FeGNlcHRpb248L2NvZGU+IHdpdGggdGhlIGNvZGUgPGNvZGU+Tk9UX1NVUFBPUlRFRF9FUlI8L2NvZGU+LkluCi0gKiBmdXR1cmUgdmVyc2lvbnMgb2YgdGhlIFhQYXRoIHNwZWNpZmljYXRpb24sIHRoZSBkZWZpbml0aW9uIG9mIGEgbmFtZXNwYWNlCi0gKiBub2RlIG1heSBiZSBjaGFuZ2VkIGluY29tYXRpYmx5LCBpbiB3aGljaCBjYXNlIGluY29tcGF0aWJsZSBjaGFuZ2VzIHRvCi0gKiBmaWVsZCB2YWx1ZXMgbWF5IGJlIHJlcXVpcmVkIHRvIGltcGxlbWVudCB2ZXJzaW9ucyBiZXlvbmQgWFBhdGggMS4wLgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvTk9URS1ET00tTGV2ZWwtMy1YUGF0aC0yMDA0MDIyNic+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDMgWFBhdGggU3BlY2lmaWNhdGlvbjwvYT4uCi0gKgotICogVGhpcyBpbXBsZW1lbnRhdGlvbiB3cmFwcyB0aGUgRE9NIGF0dHJpYnV0ZSBub2RlIHRoYXQgY29udGFpbmVkIHRoZQotICogbmFtZXNwYWNlIGRlY2xhcmF0aW9uLgotICogQHhzbC51c2FnZSBpbnRlcm5hbAotICovCi0KLWNsYXNzIFhQYXRoTmFtZXNwYWNlSW1wbCBpbXBsZW1lbnRzIFhQYXRoTmFtZXNwYWNlIHsKLQotICAgIC8vIE5vZGUgdGhhdCBYUGF0aE5hbWVzcGFjZUltcGwgd3JhcHMKLSAgICBmaW5hbCBwcml2YXRlIE5vZGUgbV9hdHRyaWJ1dGVOb2RlOwotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0b3IgZm9yIFhQYXRoTmFtZXNwYWNlSW1wbC4KLSAgICAgKi8KLSAgICBYUGF0aE5hbWVzcGFjZUltcGwoTm9kZSBub2RlKSB7Ci0gICAgICAgIG1fYXR0cmlidXRlTm9kZSA9IG5vZGU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwuZG9tMy54cGF0aC5YUGF0aE5hbWVzcGFjZSNnZXRPd25lckVsZW1lbnQoKQotICAgICAqLwotICAgIHB1YmxpYyBFbGVtZW50IGdldE93bmVyRWxlbWVudCgpIHsKLSAgICAgICAgcmV0dXJuICgoQXR0ciltX2F0dHJpYnV0ZU5vZGUpLmdldE93bmVyRWxlbWVudCgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgb3JnLnczYy5kb20uTm9kZSNnZXROb2RlTmFtZSgpCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXROb2RlTmFtZSgpIHsKLSAgICAgICAgcmV0dXJuICIjbmFtZXNwYWNlIjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAc2VlIG9yZy53M2MuZG9tLk5vZGUjZ2V0Tm9kZVZhbHVlKCkKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE5vZGVWYWx1ZSgpIHRocm93cyBET01FeGNlcHRpb24gewotICAgICAgICByZXR1cm4gbV9hdHRyaWJ1dGVOb2RlLmdldE5vZGVWYWx1ZSgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgb3JnLnczYy5kb20uTm9kZSNzZXROb2RlVmFsdWUoU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldE5vZGVWYWx1ZShTdHJpbmcgYXJnMCkgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBvcmcudzNjLmRvbS5Ob2RlI2dldE5vZGVUeXBlKCkKLSAgICAgKi8KLSAgICBwdWJsaWMgc2hvcnQgZ2V0Tm9kZVR5cGUoKSB7Ci0gICAgICAgIHJldHVybiBYUGF0aE5hbWVzcGFjZS5YUEFUSF9OQU1FU1BBQ0VfTk9ERTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAc2VlIG9yZy53M2MuZG9tLk5vZGUjZ2V0UGFyZW50Tm9kZSgpCi0gICAgICovCi0gICAgcHVibGljIE5vZGUgZ2V0UGFyZW50Tm9kZSgpIHsKLSAgICAgICAgcmV0dXJuIG1fYXR0cmlidXRlTm9kZS5nZXRQYXJlbnROb2RlKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBvcmcudzNjLmRvbS5Ob2RlI2dldENoaWxkTm9kZXMoKQotICAgICAqLwotICAgIHB1YmxpYyBOb2RlTGlzdCBnZXRDaGlsZE5vZGVzKCkgewotICAgICAgICByZXR1cm4gbV9hdHRyaWJ1dGVOb2RlLmdldENoaWxkTm9kZXMoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAc2VlIG9yZy53M2MuZG9tLk5vZGUjZ2V0Rmlyc3RDaGlsZCgpCi0gICAgICovCi0gICAgcHVibGljIE5vZGUgZ2V0Rmlyc3RDaGlsZCgpIHsKLSAgICAgICAgcmV0dXJuIG1fYXR0cmlidXRlTm9kZS5nZXRGaXJzdENoaWxkKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBvcmcudzNjLmRvbS5Ob2RlI2dldExhc3RDaGlsZCgpCi0gICAgICovCi0gICAgcHVibGljIE5vZGUgZ2V0TGFzdENoaWxkKCkgewotICAgICAgICByZXR1cm4gbV9hdHRyaWJ1dGVOb2RlLmdldExhc3RDaGlsZCgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgb3JnLnczYy5kb20uTm9kZSNnZXRQcmV2aW91c1NpYmxpbmcoKQotICAgICAqLwotICAgIHB1YmxpYyBOb2RlIGdldFByZXZpb3VzU2libGluZygpIHsKLSAgICAgICAgcmV0dXJuIG1fYXR0cmlidXRlTm9kZS5nZXRQcmV2aW91c1NpYmxpbmcoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAc2VlIG9yZy53M2MuZG9tLk5vZGUjZ2V0TmV4dFNpYmxpbmcoKQotICAgICAqLwotICAgIHB1YmxpYyBOb2RlIGdldE5leHRTaWJsaW5nKCkgewotICAgICAgICByZXR1cm4gbV9hdHRyaWJ1dGVOb2RlLmdldE5leHRTaWJsaW5nKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBvcmcudzNjLmRvbS5Ob2RlI2dldEF0dHJpYnV0ZXMoKQotICAgICAqLwotICAgIHB1YmxpYyBOYW1lZE5vZGVNYXAgZ2V0QXR0cmlidXRlcygpIHsKLSAgICAgICAgcmV0dXJuIG1fYXR0cmlidXRlTm9kZS5nZXRBdHRyaWJ1dGVzKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBvcmcudzNjLmRvbS5Ob2RlI2dldE93bmVyRG9jdW1lbnQoKQotICAgICAqLwotICAgIHB1YmxpYyBEb2N1bWVudCBnZXRPd25lckRvY3VtZW50KCkgewotICAgICAgICByZXR1cm4gbV9hdHRyaWJ1dGVOb2RlLmdldE93bmVyRG9jdW1lbnQoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAc2VlIG9yZy53M2MuZG9tLk5vZGUjaW5zZXJ0QmVmb3JlKE5vZGUsIE5vZGUpCi0gICAgICovCi0gICAgcHVibGljIE5vZGUgaW5zZXJ0QmVmb3JlKE5vZGUgYXJnMCwgTm9kZSBhcmcxKSB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBvcmcudzNjLmRvbS5Ob2RlI3JlcGxhY2VDaGlsZChOb2RlLCBOb2RlKQotICAgICAqLwotICAgIHB1YmxpYyBOb2RlIHJlcGxhY2VDaGlsZChOb2RlIGFyZzAsIE5vZGUgYXJnMSkgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgb3JnLnczYy5kb20uTm9kZSNyZW1vdmVDaGlsZChOb2RlKQotICAgICAqLwotICAgIHB1YmxpYyBOb2RlIHJlbW92ZUNoaWxkKE5vZGUgYXJnMCkgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgb3JnLnczYy5kb20uTm9kZSNhcHBlbmRDaGlsZChOb2RlKQotICAgICAqLwotICAgIHB1YmxpYyBOb2RlIGFwcGVuZENoaWxkKE5vZGUgYXJnMCkgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgb3JnLnczYy5kb20uTm9kZSNoYXNDaGlsZE5vZGVzKCkKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBoYXNDaGlsZE5vZGVzKCkgewotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBvcmcudzNjLmRvbS5Ob2RlI2Nsb25lTm9kZShib29sZWFuKQotICAgICAqLwotICAgIHB1YmxpYyBOb2RlIGNsb25lTm9kZShib29sZWFuIGFyZzApIHsKLSAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIsbnVsbCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBvcmcudzNjLmRvbS5Ob2RlI25vcm1hbGl6ZSgpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgbm9ybWFsaXplKCkgewotICAgICAgICBtX2F0dHJpYnV0ZU5vZGUubm9ybWFsaXplKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBvcmcudzNjLmRvbS5Ob2RlI2lzU3VwcG9ydGVkKFN0cmluZywgU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzU3VwcG9ydGVkKFN0cmluZyBhcmcwLCBTdHJpbmcgYXJnMSkgewotICAgICAgICByZXR1cm4gbV9hdHRyaWJ1dGVOb2RlLmlzU3VwcG9ydGVkKGFyZzAsIGFyZzEpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgb3JnLnczYy5kb20uTm9kZSNnZXROYW1lc3BhY2VVUkkoKQotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZXNwYWNlVVJJKCkgewotCi0gICAgICAgIC8vIEZvciBuYW1lc3BhY2Ugbm9kZSwgdGhlIG5hbWVzcGFjZVVSSSBpcyB0aGUgbmFtZXNwYWNlIFVSSQotICAgICAgICAvLyBvZiB0aGUgbmFtZXNwYWNlIHJlcHJlc2VudGVkIGJ5IHRoZSBub2RlLgotICAgICAgICByZXR1cm4gbV9hdHRyaWJ1dGVOb2RlLmdldE5vZGVWYWx1ZSgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgb3JnLnczYy5kb20uTm9kZSNnZXRQcmVmaXgoKQotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0UHJlZml4KCkgewotICAgICAgICByZXR1cm4gbV9hdHRyaWJ1dGVOb2RlLmdldFByZWZpeCgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgb3JnLnczYy5kb20uTm9kZSNzZXRQcmVmaXgoU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFByZWZpeChTdHJpbmcgYXJnMCkgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBvcmcudzNjLmRvbS5Ob2RlI2dldExvY2FsTmFtZSgpCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRMb2NhbE5hbWUoKSB7Ci0KLSAgICAgICAgLy8gRm9yIG5hbWVzcGFjZSBub2RlLCB0aGUgbG9jYWwgbmFtZSBpcyB0aGUgc2FtZSBhcyB0aGUgcHJlZml4Ci0gICAgICAgIHJldHVybiBtX2F0dHJpYnV0ZU5vZGUuZ2V0UHJlZml4KCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBvcmcudzNjLmRvbS5Ob2RlI2hhc0F0dHJpYnV0ZXMoKQotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGhhc0F0dHJpYnV0ZXMoKSB7Ci0gICAgICAgIHJldHVybiBtX2F0dHJpYnV0ZU5vZGUuaGFzQXR0cmlidXRlcygpOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0QmFzZVVSSSAoICkgewotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgc2hvcnQgY29tcGFyZURvY3VtZW50UG9zaXRpb24oTm9kZSBvdGhlcikgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0gICAgICAgIHJldHVybiAwOwotICAgIH0KLQotICAgIHByaXZhdGUgU3RyaW5nIHRleHRDb250ZW50OwotCi0gICAgcHVibGljIFN0cmluZyBnZXRUZXh0Q29udGVudCgpIHRocm93cyBET01FeGNlcHRpb24gewotICAgICAgICByZXR1cm4gdGV4dENvbnRlbnQ7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0VGV4dENvbnRlbnQoU3RyaW5nIHRleHRDb250ZW50KSB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKLSAgICAgICAgdGhpcy50ZXh0Q29udGVudCA9IHRleHRDb250ZW50OwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGlzU2FtZU5vZGUoTm9kZSBvdGhlcikgewotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBsb29rdXBQcmVmaXgoU3RyaW5nIG5hbWVzcGFjZVVSSSkgewotICAgICAgICByZXR1cm4gIiI7IC8vUEVORElORwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGlzRGVmYXVsdE5hbWVzcGFjZShTdHJpbmcgbmFtZXNwYWNlVVJJKSB7Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGxvb2t1cE5hbWVzcGFjZVVSSShTdHJpbmcgcHJlZml4KSB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGlzRXF1YWxOb2RlKE5vZGUgYXJnKSB7Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgT2JqZWN0IGdldEZlYXR1cmUoU3RyaW5nIGZlYXR1cmUsIFN0cmluZyB2ZXJzaW9uKSB7Ci0gICAgICAgIHJldHVybiBudWxsOyAvL1BFTkRJTkcKLSAgICB9Ci0KLSAgICBwdWJsaWMgT2JqZWN0IHNldFVzZXJEYXRhKFN0cmluZyBrZXksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPYmplY3QgZGF0YSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVzZXJEYXRhSGFuZGxlciBoYW5kbGVyKSB7Ci0gICAgICAgIHJldHVybiBudWxsOyAvL1BFTkRJTkcKLSAgICB9Ci0KLSAgICBwdWJsaWMgT2JqZWN0IGdldFVzZXJEYXRhKFN0cmluZyBrZXkpIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9kb21hcGkvWFBhdGhSZXN1bHRJbXBsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2RvbWFwaS9YUGF0aFJlc3VsdEltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNzY1NzZmNC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2RvbWFwaS9YUGF0aFJlc3VsdEltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDUxMiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAyMDAyLTIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBYUGF0aFJlc3VsdEltcGwuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xMCAwNDoxODo1NCBqZWZmc3V0dG9yIEV4cCAkCi0gKi8KLQotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5kb21hcGk7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhPYmplY3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLnJlcy5YUEFUSEVycm9yUmVzb3VyY2VzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5yZXMuWFBBVEhNZXNzYWdlczsKLWltcG9ydCBvcmcudzNjLmRvbS5ET01FeGNlcHRpb247Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlTGlzdDsKLWltcG9ydCBvcmcudzNjLmRvbS5ldmVudHMuRXZlbnQ7Ci1pbXBvcnQgb3JnLnczYy5kb20uZXZlbnRzLkV2ZW50TGlzdGVuZXI7Ci1pbXBvcnQgb3JnLnczYy5kb20uZXZlbnRzLkV2ZW50VGFyZ2V0OwotaW1wb3J0IG9yZy53M2MuZG9tLnRyYXZlcnNhbC5Ob2RlSXRlcmF0b3I7Ci1pbXBvcnQgb3JnLnczYy5kb20ueHBhdGguWFBhdGhFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnczYy5kb20ueHBhdGguWFBhdGhSZXN1bHQ7Ci0KLS8qKgotICoKLSAqIFRoZSBjbGFzcyBwcm92aWRlcyBhbiBpbXBsZW1lbnRhdGlvbiBYUGF0aFJlc3VsdCBhY2NvcmRpbmcKLSAqIHRvIHRoZSBET00gTDMgWFBhdGggU3BlY2lmaWNhdGlvbiwgV29ya2luZyBHcm91cCBOb3RlIDI2IEZlYnJ1YXJ5IDIwMDQuCi0gKgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvTk9URS1ET00tTGV2ZWwtMy1YUGF0aC0yMDA0MDIyNic+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDMgWFBhdGggU3BlY2lmaWNhdGlvbjwvYT4uPC9wPgotICoKLSAqIDxwPlRoZSA8Y29kZT5YUGF0aFJlc3VsdDwvY29kZT4gaW50ZXJmYWNlIHJlcHJlc2VudHMgdGhlIHJlc3VsdCBvZiB0aGUKLSAqIGV2YWx1YXRpb24gb2YgYW4gWFBhdGggZXhwcmVzc2lvbiB3aXRoaW4gdGhlIGNvbnRleHQgb2YgYSBwYXJ0aWN1bGFyCi0gKiBub2RlLiBTaW5jZSBldmFsdWF0aW9uIG9mIGFuIFhQYXRoIGV4cHJlc3Npb24gY2FuIHJlc3VsdCBpbiB2YXJpb3VzCi0gKiByZXN1bHQgdHlwZXMsIHRoaXMgb2JqZWN0IG1ha2VzIGl0IHBvc3NpYmxlIHRvIGRpc2NvdmVyIGFuZCBtYW5pcHVsYXRlCi0gKiB0aGUgdHlwZSBhbmQgdmFsdWUgb2YgdGhlIHJlc3VsdC48L3A+Ci0gKgotICogPHA+VGhpcyBpbXBsZW1lbnRhdGlvbiB3cmFwcyBhbiA8Y29kZT5YT2JqZWN0PC9jb2RlPi4KLSAqCi0gKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhPYmplY3QKLSAqIEBzZWUgb3JnLnczYy5kb20ueHBhdGguWFBhdGhSZXN1bHQKLSAqCi0gKiBAeHNsLnVzYWdlIGludGVybmFsCi0gKi8KLWNsYXNzIFhQYXRoUmVzdWx0SW1wbCBpbXBsZW1lbnRzIFhQYXRoUmVzdWx0LCBFdmVudExpc3RlbmVyIHsKLQotICAgICAgICAvKioKLSAgICAgKiAgVGhlIHdyYXBwZWQgWE9iamVjdAotICAgICAqLwotICAgICAgICBmaW5hbCBwcml2YXRlIFhPYmplY3QgbV9yZXN1bHRPYmo7Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFRoZSB4cGF0aCBvYmplY3QgdGhhdCB3cmFwcyB0aGUgZXhwcmVzc2lvbiB1c2VkIGZvciB0aGlzIHJlc3VsdC4KLSAgICAgICAgICovCi0gICAgICAgIGZpbmFsIHByaXZhdGUgWFBhdGggbV94cGF0aDsKLQotICAgICAgICAvKioKLSAgICAgKiAgVGhpcyB0aGUgdHlwZSBzcGVjaWZpZWQgYnkgdGhlIHVzZXIgZHVyaW5nIGNvbnN0cnVjdGlvbi4gIFR5cGljYWxseQotICAgICAgICAgKiAgdGhlIGNvbnN0cnVjdG9yIHdpbGwgYmUgY2FsbGVkIGJ5IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5YUGF0aC5ldmFsdWF0ZSgpLgotICAgICAqLwotICAgICAgICBmaW5hbCBwcml2YXRlIHNob3J0IG1fcmVzdWx0VHlwZTsKLQotICAgICAgICBwcml2YXRlIGJvb2xlYW4gbV9pc0ludmFsaWRJdGVyYXRvclN0YXRlID0gZmFsc2U7Ci0KLSAgICAvKioKLSAgICAgKiBPbmx5IHVzZWQgdG8gYXR0YWNoIGEgbXV0YXRpb24gZXZlbnQgaGFuZGxlciB3aGVuIHNwZWNpZmllZAotICAgICAqIHR5cGUgaXMgYW4gaXRlcmF0b3IgdHlwZS4KLSAgICAgKi8KLSAgICAgICAgZmluYWwgcHJpdmF0ZSBOb2RlIG1fY29udGV4dE5vZGU7Ci0KLSAgICAgICAgLyoqCi0gICAgICogIFRoZSBpdGVyYXRvciwgaWYgdGhpcyBpcyBhbiBpdGVyYXRvciB0eXBlLgotICAgICAqLwotICAgICAgICBwcml2YXRlIE5vZGVJdGVyYXRvciBtX2l0ZXJhdG9yID0gbnVsbDs7Ci0KLSAgICAgICAgLyoqCi0gICAgICogIFRoZSBsaXN0LCBpZiB0aGlzIGlzIGEgc25hcHNob3QgdHlwZS4KLSAgICAgKi8KLSAgICAgICAgcHJpdmF0ZSBOb2RlTGlzdCBtX2xpc3QgPSBudWxsOwotCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIENvbnN0cnVjdG9yIGZvciBYUGF0aFJlc3VsdEltcGwuCi0gICAgICoKLSAgICAgKiBGb3IgaW50ZXJuYWwgdXNlIG9ubHkuCi0gICAgICAgICAqLwotICAgICAgICAgWFBhdGhSZXN1bHRJbXBsKHNob3J0IHR5cGUsIFhPYmplY3QgcmVzdWx0LCBOb2RlIGNvbnRleHROb2RlLCBYUGF0aCB4cGF0aCkgewotICAgICAgICAgICAgICAgIC8vIENoZWNrIHRoYXQgdGhlIHR5cGUgaXMgdmFsaWQKLSAgICAgICAgICAgICAgICBpZiAoIWlzVmFsaWRUeXBlKHR5cGUpKSB7Ci0gICAgICAgICAgICBTdHJpbmcgZm1zZyA9IFhQQVRITWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfSU5WQUxJRF9YUEFUSF9UWVBFLCBuZXcgT2JqZWN0W10ge25ldyBJbnRlZ2VyKHR5cGUpfSk7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWFBhdGhFeGNlcHRpb24oWFBhdGhFeGNlcHRpb24uVFlQRV9FUlIsZm1zZyk7IC8vIEludmFsaWQgWFBhdGggdHlwZSBhcmd1bWVudDogezB9Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgIC8vIFJlc3VsdCBvYmplY3Qgc2hvdWxkIG5ldmVyIGJlIG51bGwhCi0gICAgICAgIGlmIChudWxsID09IHJlc3VsdCkgewotICAgICAgICAgICAgU3RyaW5nIGZtc2cgPSBYUEFUSE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShYUEFUSEVycm9yUmVzb3VyY2VzLkVSX0VNUFRZX1hQQVRIX1JFU1VMVCwgbnVsbCk7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWFBhdGhFeGNlcHRpb24oWFBhdGhFeGNlcHRpb24uSU5WQUxJRF9FWFBSRVNTSU9OX0VSUixmbXNnKTsgLy8gRW1wdHkgWFBhdGggcmVzdWx0IG9iamVjdAotICAgICAgICB9Ci0KLSAgICAgICAgdGhpcy5tX3Jlc3VsdE9iaiA9IHJlc3VsdDsKLSAgICAgICAgdGhpcy5tX2NvbnRleHROb2RlID0gY29udGV4dE5vZGU7Ci0gICAgICAgIHRoaXMubV94cGF0aCA9IHhwYXRoOwotCi0gICAgICAgIC8vIElmIHNwZWNpZmllZCByZXN1bHQgd2FzIEFOWV9UWVBFLCBkZXRlcm1pbmUgWE9iamVjdCB0eXBlCi0gICAgICAgIGlmICh0eXBlID09IEFOWV9UWVBFKSB7Ci0gICAgICAgICAgICB0aGlzLm1fcmVzdWx0VHlwZSA9IGdldFR5cGVGcm9tWE9iamVjdChyZXN1bHQpOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgdGhpcy5tX3Jlc3VsdFR5cGUgPSB0eXBlOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gSWYgdGhlIGNvbnRleHQgbm9kZSBzdXBwb3J0cyBET00gRXZlbnRzIGFuZCB0aGUgdHlwZSBpcyBvbmUgb2YgdGhlIGl0ZXJhdG9yCi0gICAgICAgIC8vIHR5cGVzIHJlZ2lzdGVyIHRoaXMgcmVzdWx0IGFzIGFuIGV2ZW50IGxpc3RlbmVyCi0gICAgICAgIGlmICgoKG1fcmVzdWx0VHlwZSA9PSBYUGF0aFJlc3VsdC5PUkRFUkVEX05PREVfSVRFUkFUT1JfVFlQRSkgfHwKLSAgICAgICAgICAgIChtX3Jlc3VsdFR5cGUgPT0gWFBhdGhSZXN1bHQuVU5PUkRFUkVEX05PREVfSVRFUkFUT1JfVFlQRSkpKSB7Ci0gICAgICAgICAgICAgICAgYWRkRXZlbnRMaXN0ZW5lcigpOwotCi0gICAgICAgIH0vLyBlbHNlIGNhbiB3ZSBoYW5kbGUgaXRlcmF0b3IgdHlwZXMgaWYgY29udGV4dE5vZGUgZG9lc24ndCBzdXBwb3J0IEV2ZW50VGFyZ2V0Pz8KLQotICAgICAgICAvLyBJZiB0aGlzIGlzIGFuIGl0ZXJhdG9yIHR5cGUgZ2V0IHRoZSBpdGVyYXRvcgotICAgICAgICBpZiAoKG1fcmVzdWx0VHlwZSA9PSBPUkRFUkVEX05PREVfSVRFUkFUT1JfVFlQRSkgfHwKLSAgICAgICAgICAgIChtX3Jlc3VsdFR5cGUgPT0gVU5PUkRFUkVEX05PREVfSVRFUkFUT1JfVFlQRSkgfHwKLSAgICAgICAgICAgIChtX3Jlc3VsdFR5cGUgPT0gQU5ZX1VOT1JERVJFRF9OT0RFX1RZUEUpIHx8Ci0gICAgICAgICAgICAobV9yZXN1bHRUeXBlID09IEZJUlNUX09SREVSRURfTk9ERV9UWVBFKSkgIHsKLQotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICBtX2l0ZXJhdG9yID0gbV9yZXN1bHRPYmoubm9kZXNldCgpOwotICAgICAgICAgICAgfSBjYXRjaCAoVHJhbnNmb3JtZXJFeGNlcHRpb24gdGUpIHsKLSAgICAgICAgICAgICAgICAvLyBwcm9iYWJseSBub3QgYSBub2RlIHR5cGUKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGZtc2cgPSBYUEFUSE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShYUEFUSEVycm9yUmVzb3VyY2VzLkVSX0lOQ09NUEFUSUJMRV9UWVBFUywgbmV3IE9iamVjdFtdIHttX3hwYXRoLmdldFBhdHRlcm5TdHJpbmcoKSwgZ2V0VHlwZVN0cmluZyhnZXRUeXBlRnJvbVhPYmplY3QobV9yZXN1bHRPYmopKSxnZXRUeXBlU3RyaW5nKG1fcmVzdWx0VHlwZSl9KTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWFBhdGhFeGNlcHRpb24oWFBhdGhFeGNlcHRpb24uVFlQRV9FUlIsIGZtc2cpOyAgLy8gIlRoZSBYUGF0aFJlc3VsdCBvZiBYUGF0aCBleHByZXNzaW9uIHswfSBoYXMgYW4gWFBhdGhSZXN1bHRUeXBlIG9mIHsxfSB3aGljaCBjYW5ub3QgYmUgY29lcmNlZCBpbnRvIHRoZSBzcGVjaWZpZWQgWFBhdGhSZXN1bHRUeXBlIG9mIHsyfS4ifSwKLSAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgLy8gSWYgdXNlciByZXF1ZXN0ZWQgb3JkZXJlZCBub2Rlc2V0IGFuZCByZXN1bHQgaXMgdW5vcmRlcmVkCi0gICAgICAgICAgICAgICAgLy8gbmVlZCB0byBzb3J0Li4uVE9ETwotICAgIC8vICAgICAgICAgICAgaWYgKChtX3Jlc3VsdFR5cGUgPT0gT1JERVJFRF9OT0RFX0lURVJBVE9SX1RZUEUpICYmCi0gICAgLy8gICAgICAgICAgICAgICAgKCEoKChEVE1Ob2RlSXRlcmF0b3IpbV9pdGVyYXRvcikuZ2V0RFRNSXRlcmF0b3IoKS5pc0RvY09yZGVyZWQoKSkpKSB7Ci0gICAgLy8KLSAgICAvLyAgICAgICAgICAgIH0KLQotICAgICAgICAvLyBJZiBpdCdzIGEgc25hcHNob3QgdHlwZSwgZ2V0IHRoZSBub2RlbGlzdAotICAgICAgICB9IGVsc2UgaWYgKChtX3Jlc3VsdFR5cGUgPT0gVU5PUkRFUkVEX05PREVfU05BUFNIT1RfVFlQRSkgfHwKLSAgICAgICAgICAgICAgICAgICAobV9yZXN1bHRUeXBlID09IE9SREVSRURfTk9ERV9TTkFQU0hPVF9UWVBFKSkgewotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICBtX2xpc3QgPSBtX3Jlc3VsdE9iai5ub2RlbGlzdCgpOwotICAgICAgICAgICAgfSBjYXRjaCAoVHJhbnNmb3JtZXJFeGNlcHRpb24gdGUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIHByb2JhYmx5IG5vdCBhIG5vZGUgdHlwZQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgZm1zZyA9IFhQQVRITWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfSU5DT01QQVRJQkxFX1RZUEVTLCBuZXcgT2JqZWN0W10ge21feHBhdGguZ2V0UGF0dGVyblN0cmluZygpLCBnZXRUeXBlU3RyaW5nKGdldFR5cGVGcm9tWE9iamVjdChtX3Jlc3VsdE9iaikpLGdldFR5cGVTdHJpbmcobV9yZXN1bHRUeXBlKX0pOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWFBhdGhFeGNlcHRpb24oWFBhdGhFeGNlcHRpb24uVFlQRV9FUlIsIGZtc2cpOyAvLyAiVGhlIFhQYXRoUmVzdWx0IG9mIFhQYXRoIGV4cHJlc3Npb24gezB9IGhhcyBhbiBYUGF0aFJlc3VsdFR5cGUgb2YgezF9IHdoaWNoIGNhbm5vdCBiZSBjb2VyY2VkIGludG8gdGhlIHNwZWNpZmllZCBYUGF0aFJlc3VsdFR5cGUgb2YgezJ9LiJ9LAotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogQHNlZSBvcmcudzNjLmRvbS54cGF0aC5YUGF0aFJlc3VsdCNnZXRSZXN1bHRUeXBlKCkKLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBzaG9ydCBnZXRSZXN1bHRUeXBlKCkgewotICAgICAgICAgICAgICAgIHJldHVybiBtX3Jlc3VsdFR5cGU7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogIFRoZSB2YWx1ZSBvZiB0aGlzIG51bWJlciByZXN1bHQuCi0gICAgICogQGV4Y2VwdGlvbiBYUGF0aEV4Y2VwdGlvbgotICAgICAqICAgVFlQRV9FUlI6IHJhaXNlZCBpZiA8Y29kZT5yZXN1bHRUeXBlPC9jb2RlPiBpcyBub3QKLSAgICAgKiAgIDxjb2RlPk5VTUJFUl9UWVBFPC9jb2RlPi4KLSAgICAgICAgICogQHNlZSBvcmcudzNjLmRvbS54cGF0aC5YUGF0aFJlc3VsdCNnZXROdW1iZXJWYWx1ZSgpCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgZG91YmxlIGdldE51bWJlclZhbHVlKCkgdGhyb3dzIFhQYXRoRXhjZXB0aW9uIHsKLSAgICAgICAgICAgICAgICBpZiAoZ2V0UmVzdWx0VHlwZSgpICE9IE5VTUJFUl9UWVBFKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgZm1zZyA9IFhQQVRITWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfQ0FOVF9DT05WRVJUX1hQQVRIUkVTVUxUVFlQRV9UT19OVU1CRVIsIG5ldyBPYmplY3RbXSB7bV94cGF0aC5nZXRQYXR0ZXJuU3RyaW5nKCksIGdldFR5cGVTdHJpbmcobV9yZXN1bHRUeXBlKX0pOwotICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFhQYXRoRXhjZXB0aW9uKFhQYXRoRXhjZXB0aW9uLlRZUEVfRVJSLGZtc2cpOwotLy8gICAgICAgICAgICAgICJUaGUgWFBhdGhSZXN1bHQgb2YgWFBhdGggZXhwcmVzc2lvbiB7MH0gaGFzIGFuIFhQYXRoUmVzdWx0VHlwZSBvZiB7MX0gd2hpY2ggY2Fubm90IGJlIGNvbnZlcnRlZCB0byBhIG51bWJlciIKLSAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBtX3Jlc3VsdE9iai5udW0oKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFR5cGUgY2hlY2sgYWJvdmUgc2hvdWxkIHByZXZlbnQgdGhpcyBleGNlcHRpb24gZnJvbSBvY2N1cnJpbmcuCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBYUGF0aEV4Y2VwdGlvbihYUGF0aEV4Y2VwdGlvbi5UWVBFX0VSUixlLmdldE1lc3NhZ2UoKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFRoZSB2YWx1ZSBvZiB0aGlzIHN0cmluZyByZXN1bHQuCi0gICAgICogQGV4Y2VwdGlvbiBYUGF0aEV4Y2VwdGlvbgotICAgICAqICAgVFlQRV9FUlI6IHJhaXNlZCBpZiA8Y29kZT5yZXN1bHRUeXBlPC9jb2RlPiBpcyBub3QKLSAgICAgKiAgIDxjb2RlPlNUUklOR19UWVBFPC9jb2RlPi4KLSAgICAgKgotICAgICAgICAgKiBAc2VlIG9yZy53M2MuZG9tLnhwYXRoLlhQYXRoUmVzdWx0I2dldFN0cmluZ1ZhbHVlKCkKLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3RyaW5nVmFsdWUoKSB0aHJvd3MgWFBhdGhFeGNlcHRpb24gewotICAgICAgICAgICAgICAgIGlmIChnZXRSZXN1bHRUeXBlKCkgIT0gU1RSSU5HX1RZUEUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBmbXNnID0gWFBBVEhNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoWFBBVEhFcnJvclJlc291cmNlcy5FUl9DQU5UX0NPTlZFUlRfVE9fU1RSSU5HLCBuZXcgT2JqZWN0W10ge21feHBhdGguZ2V0UGF0dGVyblN0cmluZygpLCBtX3Jlc3VsdE9iai5nZXRUeXBlU3RyaW5nKCl9KTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBYUGF0aEV4Y2VwdGlvbihYUGF0aEV4Y2VwdGlvbi5UWVBFX0VSUixmbXNnKTsKLS8vICAgICAgICAgICAgICAiVGhlIFhQYXRoUmVzdWx0IG9mIFhQYXRoIGV4cHJlc3Npb24gezB9IGhhcyBhbiBYUGF0aFJlc3VsdFR5cGUgb2YgezF9IHdoaWNoIGNhbm5vdCBiZSBjb252ZXJ0ZWQgdG8gYSBzdHJpbmcuIgotICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG1fcmVzdWx0T2JqLnN0cigpOwotICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVHlwZSBjaGVjayBhYm92ZSBzaG91bGQgcHJldmVudCB0aGlzIGV4Y2VwdGlvbiBmcm9tIG9jY3VycmluZy4KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFhQYXRoRXhjZXB0aW9uKFhQYXRoRXhjZXB0aW9uLlRZUEVfRVJSLGUuZ2V0TWVzc2FnZSgpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogQHNlZSBvcmcudzNjLmRvbS54cGF0aC5YUGF0aFJlc3VsdCNnZXRCb29sZWFuVmFsdWUoKQotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIGJvb2xlYW4gZ2V0Qm9vbGVhblZhbHVlKCkgdGhyb3dzIFhQYXRoRXhjZXB0aW9uIHsKLSAgICAgICAgICAgICAgICBpZiAoZ2V0UmVzdWx0VHlwZSgpICE9IEJPT0xFQU5fVFlQRSkgewotICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGZtc2cgPSBYUEFUSE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShYUEFUSEVycm9yUmVzb3VyY2VzLkVSX0NBTlRfQ09OVkVSVF9UT19CT09MRUFOLCBuZXcgT2JqZWN0W10ge21feHBhdGguZ2V0UGF0dGVyblN0cmluZygpLCBnZXRUeXBlU3RyaW5nKG1fcmVzdWx0VHlwZSl9KTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBYUGF0aEV4Y2VwdGlvbihYUGF0aEV4Y2VwdGlvbi5UWVBFX0VSUixmbXNnKTsKLS8vICAgICAgICAgICAgICAiVGhlIFhQYXRoUmVzdWx0IG9mIFhQYXRoIGV4cHJlc3Npb24gezB9IGhhcyBhbiBYUGF0aFJlc3VsdFR5cGUgb2YgezF9IHdoaWNoIGNhbm5vdCBiZSBjb252ZXJ0ZWQgdG8gYSBib29sZWFuLiIKLSAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBtX3Jlc3VsdE9iai5ib29sKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChUcmFuc2Zvcm1lckV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFR5cGUgY2hlY2sgYWJvdmUgc2hvdWxkIHByZXZlbnQgdGhpcyBleGNlcHRpb24gZnJvbSBvY2N1cnJpbmcuCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBYUGF0aEV4Y2VwdGlvbihYUGF0aEV4Y2VwdGlvbi5UWVBFX0VSUixlLmdldE1lc3NhZ2UoKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFRoZSB2YWx1ZSBvZiB0aGlzIHNpbmdsZSBub2RlIHJlc3VsdCwgd2hpY2ggbWF5IGJlIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAqIEBleGNlcHRpb24gWFBhdGhFeGNlcHRpb24KLSAgICAgKiAgIFRZUEVfRVJSOiByYWlzZWQgaWYgPGNvZGU+cmVzdWx0VHlwZTwvY29kZT4gaXMgbm90Ci0gICAgICogICA8Y29kZT5BTllfVU5PUkRFUkVEX05PREVfVFlQRTwvY29kZT4gb3IKLSAgICAgKiAgIDxjb2RlPkZJUlNUX09SREVSRURfTk9ERV9UWVBFPC9jb2RlPi4KLSAgICAgKgotICAgICAgICAgKiBAc2VlIG9yZy53M2MuZG9tLnhwYXRoLlhQYXRoUmVzdWx0I2dldFNpbmdsZU5vZGVWYWx1ZSgpCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgTm9kZSBnZXRTaW5nbGVOb2RlVmFsdWUoKSB0aHJvd3MgWFBhdGhFeGNlcHRpb24gewotCi0gICAgICAgICAgICAgICAgaWYgKChtX3Jlc3VsdFR5cGUgIT0gQU5ZX1VOT1JERVJFRF9OT0RFX1RZUEUpICYmCi0gICAgICAgICAgICAgICAgICAgIChtX3Jlc3VsdFR5cGUgIT0gRklSU1RfT1JERVJFRF9OT0RFX1RZUEUpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBmbXNnID0gWFBBVEhNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoWFBBVEhFcnJvclJlc291cmNlcy5FUl9DQU5UX0NPTlZFUlRfVE9fU0lOR0xFTk9ERSwgbmV3IE9iamVjdFtdIHttX3hwYXRoLmdldFBhdHRlcm5TdHJpbmcoKSwgZ2V0VHlwZVN0cmluZyhtX3Jlc3VsdFR5cGUpfSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBYUGF0aEV4Y2VwdGlvbihYUGF0aEV4Y2VwdGlvbi5UWVBFX0VSUixmbXNnKTsKLS8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlRoZSBYUGF0aFJlc3VsdCBvZiBYUGF0aCBleHByZXNzaW9uIHswfSBoYXMgYW4gWFBhdGhSZXN1bHRUeXBlIG9mIHsxfSB3aGljaCBjYW5ub3QgYmUgY29udmVydGVkIHRvIGEgc2luZ2xlIG5vZGUuCi0vLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzIG1ldGhvZCBhcHBsaWVzIG9ubHkgdG8gdHlwZXMgQU5ZX1VOT1JERVJFRF9OT0RFX1RZUEUgYW5kIEZJUlNUX09SREVSRURfTk9ERV9UWVBFLiIKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIE5vZGVJdGVyYXRvciByZXN1bHQgPSBudWxsOwotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBtX3Jlc3VsdE9iai5ub2Rlc2V0KCk7Ci0gICAgICAgICAgICAgICAgfSBjYXRjaCAoVHJhbnNmb3JtZXJFeGNlcHRpb24gdGUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBYUGF0aEV4Y2VwdGlvbihYUGF0aEV4Y2VwdGlvbi5UWVBFX0VSUix0ZS5nZXRNZXNzYWdlKCkpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICBpZiAobnVsbCA9PSByZXN1bHQpIHJldHVybiBudWxsOwotCi0gICAgICAgIE5vZGUgbm9kZSA9IHJlc3VsdC5uZXh0Tm9kZSgpOwotCi0gICAgICAgIC8vIFdyYXAgIm5hbWVzcGFjZSBub2RlIiBpbiBhbiBYUGF0aE5hbWVzcGFjZQotICAgICAgICBpZiAoaXNOYW1lc3BhY2VOb2RlKG5vZGUpKSB7Ci0gICAgICAgICAgICByZXR1cm4gbmV3IFhQYXRoTmFtZXNwYWNlSW1wbChub2RlKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiBub2RlOwotICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogQHNlZSBvcmcudzNjLmRvbS54cGF0aC5YUGF0aFJlc3VsdCNnZXRJbnZhbGlkSXRlcmF0b3JTdGF0ZSgpCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgYm9vbGVhbiBnZXRJbnZhbGlkSXRlcmF0b3JTdGF0ZSgpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gbV9pc0ludmFsaWRJdGVyYXRvclN0YXRlOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFRoZSBudW1iZXIgb2Ygbm9kZXMgaW4gdGhlIHJlc3VsdCBzbmFwc2hvdC4gVmFsaWQgdmFsdWVzIGZvcgotICAgICAqIHNuYXBzaG90SXRlbSBpbmRpY2VzIGFyZSA8Y29kZT4wPC9jb2RlPiB0bwotICAgICAqIDxjb2RlPnNuYXBzaG90TGVuZ3RoLTE8L2NvZGU+IGluY2x1c2l2ZS4KLSAgICAgKiBAZXhjZXB0aW9uIFhQYXRoRXhjZXB0aW9uCi0gICAgICogICBUWVBFX0VSUjogcmFpc2VkIGlmIDxjb2RlPnJlc3VsdFR5cGU8L2NvZGU+IGlzIG5vdAotICAgICAqICAgPGNvZGU+VU5PUkRFUkVEX05PREVfU05BUFNIT1RfVFlQRTwvY29kZT4gb3IKLSAgICAgKiAgIDxjb2RlPk9SREVSRURfTk9ERV9TTkFQU0hPVF9UWVBFPC9jb2RlPi4KLSAgICAgKgotICAgICAgICAgKiBAc2VlIG9yZy53M2MuZG9tLnhwYXRoLlhQYXRoUmVzdWx0I2dldFNuYXBzaG90TGVuZ3RoKCkKLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBpbnQgZ2V0U25hcHNob3RMZW5ndGgoKSB0aHJvd3MgWFBhdGhFeGNlcHRpb24gewotCi0gICAgICAgICAgICAgICAgaWYgKChtX3Jlc3VsdFR5cGUgIT0gVU5PUkRFUkVEX05PREVfU05BUFNIT1RfVFlQRSkgJiYKLSAgICAgICAgICAgICAgICAgICAgKG1fcmVzdWx0VHlwZSAhPSBPUkRFUkVEX05PREVfU05BUFNIT1RfVFlQRSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGZtc2cgPSBYUEFUSE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShYUEFUSEVycm9yUmVzb3VyY2VzLkVSX0NBTlRfR0VUX1NOQVBTSE9UX0xFTkdUSCwgbmV3IE9iamVjdFtdIHttX3hwYXRoLmdldFBhdHRlcm5TdHJpbmcoKSwgZ2V0VHlwZVN0cmluZyhtX3Jlc3VsdFR5cGUpfSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBYUGF0aEV4Y2VwdGlvbihYUGF0aEV4Y2VwdGlvbi5UWVBFX0VSUixmbXNnKTsKLS8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlRoZSBtZXRob2QgZ2V0U25hcHNob3RMZW5ndGggY2Fubm90IGJlIGNhbGxlZCBvbiB0aGUgWFBhdGhSZXN1bHQgb2YgWFBhdGggZXhwcmVzc2lvbiB7MH0gYmVjYXVzZSBpdHMgWFBhdGhSZXN1bHRUeXBlIGlzIHsxfS4KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIHJldHVybiBtX2xpc3QuZ2V0TGVuZ3RoKCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogSXRlcmF0ZXMgYW5kIHJldHVybnMgdGhlIG5leHQgbm9kZSBmcm9tIHRoZSBub2RlIHNldCBvcgotICAgICAqIDxjb2RlPm51bGw8L2NvZGU+aWYgdGhlcmUgYXJlIG5vIG1vcmUgbm9kZXMuCi0gICAgICogQHJldHVybiBSZXR1cm5zIHRoZSBuZXh0IG5vZGUuCi0gICAgICogQGV4Y2VwdGlvbiBYUGF0aEV4Y2VwdGlvbgotICAgICAqICAgVFlQRV9FUlI6IHJhaXNlZCBpZiA8Y29kZT5yZXN1bHRUeXBlPC9jb2RlPiBpcyBub3QKLSAgICAgKiAgIDxjb2RlPlVOT1JERVJFRF9OT0RFX0lURVJBVE9SX1RZUEU8L2NvZGU+IG9yCi0gICAgICogICA8Y29kZT5PUkRFUkVEX05PREVfSVRFUkFUT1JfVFlQRTwvY29kZT4uCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIElOVkFMSURfU1RBVEVfRVJSOiBUaGUgZG9jdW1lbnQgaGFzIGJlZW4gbXV0YXRlZCBzaW5jZSB0aGUgcmVzdWx0IHdhcwotICAgICAqICAgcmV0dXJuZWQuCi0gICAgICAgICAqIEBzZWUgb3JnLnczYy5kb20ueHBhdGguWFBhdGhSZXN1bHQjaXRlcmF0ZU5leHQoKQotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIE5vZGUgaXRlcmF0ZU5leHQoKSB0aHJvd3MgWFBhdGhFeGNlcHRpb24sIERPTUV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICAgICAgaWYgKChtX3Jlc3VsdFR5cGUgIT0gVU5PUkRFUkVEX05PREVfSVRFUkFUT1JfVFlQRSkgJiYKLSAgICAgICAgICAgICAgICAgICAgKG1fcmVzdWx0VHlwZSAhPSBPUkRFUkVEX05PREVfSVRFUkFUT1JfVFlQRSkpIHsKLSAgICAgICAgICBTdHJpbmcgZm1zZyA9IFhQQVRITWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfTk9OX0lURVJBVE9SX1RZUEUsIG5ldyBPYmplY3RbXSB7bV94cGF0aC5nZXRQYXR0ZXJuU3RyaW5nKCksIGdldFR5cGVTdHJpbmcobV9yZXN1bHRUeXBlKX0pOwotICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFhQYXRoRXhjZXB0aW9uKFhQYXRoRXhjZXB0aW9uLlRZUEVfRVJSLCBmbXNnKTsKLS8vICAgICAgICAgICAgICAgICJUaGUgbWV0aG9kIGl0ZXJhdGVOZXh0IGNhbm5vdCBiZSBjYWxsZWQgb24gdGhlIFhQYXRoUmVzdWx0IG9mIFhQYXRoIGV4cHJlc3Npb24gezB9IGJlY2F1c2UgaXRzIFhQYXRoUmVzdWx0VHlwZSBpcyB7MX0uCi0vLyAgICAgICAgICAgICAgICBUaGlzIG1ldGhvZCBhcHBsaWVzIG9ubHkgdG8gdHlwZXMgVU5PUkRFUkVEX05PREVfSVRFUkFUT1JfVFlQRSBhbmQgT1JERVJFRF9OT0RFX0lURVJBVE9SX1RZUEUuIn0sCi0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBpZiAoZ2V0SW52YWxpZEl0ZXJhdG9yU3RhdGUoKSkgewotICAgICAgICAgIFN0cmluZyBmbXNnID0gWFBBVEhNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoWFBBVEhFcnJvclJlc291cmNlcy5FUl9ET0NfTVVUQVRFRCwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5JTlZBTElEX1NUQVRFX0VSUixmbXNnKTsgIC8vIERvY3VtZW50IG11dGF0ZWQgc2luY2UgcmVzdWx0IHdhcyByZXR1cm5lZC4gSXRlcmF0b3IgaXMgaW52YWxpZC4KLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgTm9kZSBub2RlID0gbV9pdGVyYXRvci5uZXh0Tm9kZSgpOwotICAgICAgICBpZihudWxsID09IG5vZGUpCi0gICAgICAgICAgICAgICAgcmVtb3ZlRXZlbnRMaXN0ZW5lcigpOyAvLyBKSVJBIDE2NzMKLSAgICAgICAgLy8gV3JhcCAibmFtZXNwYWNlIG5vZGUiIGluIGFuIFhQYXRoTmFtZXNwYWNlCi0gICAgICAgIGlmIChpc05hbWVzcGFjZU5vZGUobm9kZSkpIHsKLSAgICAgICAgICAgIHJldHVybiBuZXcgWFBhdGhOYW1lc3BhY2VJbXBsKG5vZGUpOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIG5vZGU7Ci0gICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgPGNvZGU+aW5kZXg8L2NvZGU+dGggaXRlbSBpbiB0aGUgc25hcHNob3QgY29sbGVjdGlvbi4gSWYKLSAgICAgKiA8Y29kZT5pbmRleDwvY29kZT4gaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHRoZSBudW1iZXIgb2Ygbm9kZXMgaW4KLSAgICAgKiB0aGUgbGlzdCwgdGhpcyBtZXRob2QgcmV0dXJucyA8Y29kZT5udWxsPC9jb2RlPi4gVW5saWtlIHRoZSBpdGVyYXRvcgotICAgICAqIHJlc3VsdCwgdGhlIHNuYXBzaG90IGRvZXMgbm90IGJlY29tZSBpbnZhbGlkLCBidXQgbWF5IG5vdCBjb3JyZXNwb25kCi0gICAgICogdG8gdGhlIGN1cnJlbnQgZG9jdW1lbnQgaWYgaXQgaXMgbXV0YXRlZC4KLSAgICAgKiBAcGFyYW0gaW5kZXggSW5kZXggaW50byB0aGUgc25hcHNob3QgY29sbGVjdGlvbi4KLSAgICAgKiBAcmV0dXJuIFRoZSBub2RlIGF0IHRoZSA8Y29kZT5pbmRleDwvY29kZT50aCBwb3NpdGlvbiBpbiB0aGUKLSAgICAgKiAgIDxjb2RlPk5vZGVMaXN0PC9jb2RlPiwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhhdCBpcyBub3QgYSB2YWxpZAotICAgICAqICAgaW5kZXguCi0gICAgICogQGV4Y2VwdGlvbiBYUGF0aEV4Y2VwdGlvbgotICAgICAqICAgVFlQRV9FUlI6IHJhaXNlZCBpZiA8Y29kZT5yZXN1bHRUeXBlPC9jb2RlPiBpcyBub3QKLSAgICAgKiAgIDxjb2RlPlVOT1JERVJFRF9OT0RFX1NOQVBTSE9UX1RZUEU8L2NvZGU+IG9yCi0gICAgICogICA8Y29kZT5PUkRFUkVEX05PREVfU05BUFNIT1RfVFlQRTwvY29kZT4uCi0gICAgICoKLSAgICAgICAgICogQHNlZSBvcmcudzNjLmRvbS54cGF0aC5YUGF0aFJlc3VsdCNzbmFwc2hvdEl0ZW0oaW50KQotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIE5vZGUgc25hcHNob3RJdGVtKGludCBpbmRleCkgdGhyb3dzIFhQYXRoRXhjZXB0aW9uIHsKLQotICAgICAgICAgICAgICAgIGlmICgobV9yZXN1bHRUeXBlICE9IFVOT1JERVJFRF9OT0RFX1NOQVBTSE9UX1RZUEUpICYmCi0gICAgICAgICAgICAgICAgICAgIChtX3Jlc3VsdFR5cGUgIT0gT1JERVJFRF9OT0RFX1NOQVBTSE9UX1RZUEUpKSB7Ci0gICAgICAgICAgIFN0cmluZyBmbXNnID0gWFBBVEhNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoWFBBVEhFcnJvclJlc291cmNlcy5FUl9OT05fU05BUFNIT1RfVFlQRSwgbmV3IE9iamVjdFtdIHttX3hwYXRoLmdldFBhdHRlcm5TdHJpbmcoKSwgZ2V0VHlwZVN0cmluZyhtX3Jlc3VsdFR5cGUpfSk7Ci0gICAgICAgICAgIHRocm93IG5ldyBYUGF0aEV4Y2VwdGlvbihYUGF0aEV4Y2VwdGlvbi5UWVBFX0VSUiwgZm1zZyk7Ci0vLyAgICAgICAgICAgICAgIlRoZSBtZXRob2Qgc25hcHNob3RJdGVtIGNhbm5vdCBiZSBjYWxsZWQgb24gdGhlIFhQYXRoUmVzdWx0IG9mIFhQYXRoIGV4cHJlc3Npb24gezB9IGJlY2F1c2UgaXRzIFhQYXRoUmVzdWx0VHlwZSBpcyB7MX0uCi0vLyAgICAgICAgICAgICAgVGhpcyBtZXRob2QgYXBwbGllcyBvbmx5IHRvIHR5cGVzIFVOT1JERVJFRF9OT0RFX1NOQVBTSE9UX1RZUEUgYW5kIE9SREVSRURfTk9ERV9TTkFQU0hPVF9UWVBFLiJ9LAotICAgICAgICAgICAgfQotCi0gICAgICAgIE5vZGUgbm9kZSA9IG1fbGlzdC5pdGVtKGluZGV4KTsKLQotICAgICAgICAvLyBXcmFwICJuYW1lc3BhY2Ugbm9kZSIgaW4gYW4gWFBhdGhOYW1lc3BhY2UKLSAgICAgICAgaWYgKGlzTmFtZXNwYWNlTm9kZShub2RlKSkgewotICAgICAgICAgICAgcmV0dXJuIG5ldyBYUGF0aE5hbWVzcGFjZUltcGwobm9kZSk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gbm9kZTsKLSAgICAgICAgfQotICAgICAgICB9Ci0KLQotICAgICAgICAvKioKLSAgICAgICAgICogQ2hlY2sgaWYgdGhlIHNwZWNpZmllZCB0eXBlIGlzIG9uZSBvZiB0aGUgc3VwcG9ydGVkIHR5cGVzLgotICAgICAgICAgKiBAcGFyYW0gdHlwZSBUaGUgc3BlY2lmaWVkIHR5cGUKLSAgICAgICAgICoKLSAgICAgICAgICogQHJldHVybiB0cnVlIElmIHRoZSBzcGVjaWZpZWQgdHlwZSBpcyBzdXBwb3J0ZWQ7IG90aGVyd2lzZSwgcmV0dXJucyBmYWxzZS4KLSAgICAgICAgICovCi0gICAgICAgIHN0YXRpYyBib29sZWFuIGlzVmFsaWRUeXBlKCBzaG9ydCB0eXBlICkgewotICAgICAgICAgICAgICAgIHN3aXRjaCAodHlwZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBBTllfVFlQRToKLSAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgTlVNQkVSX1RZUEU6Ci0gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFNUUklOR19UWVBFOgotICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBCT09MRUFOX1RZUEU6Ci0gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFVOT1JERVJFRF9OT0RFX0lURVJBVE9SX1RZUEU6Ci0gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIE9SREVSRURfTk9ERV9JVEVSQVRPUl9UWVBFOgotICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBVTk9SREVSRURfTk9ERV9TTkFQU0hPVF9UWVBFOgotICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBPUkRFUkVEX05PREVfU05BUFNIT1RfVFlQRToKLSAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgQU5ZX1VOT1JERVJFRF9OT0RFX1RZUEU6Ci0gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIEZJUlNUX09SREVSRURfTk9ERV9UWVBFOiByZXR1cm4gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogQHNlZSBvcmcudzNjLmRvbS5ldmVudHMuRXZlbnRMaXN0ZW5lciNoYW5kbGVFdmVudChFdmVudCkKLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyB2b2lkIGhhbmRsZUV2ZW50KEV2ZW50IGV2ZW50KSB7Ci0KLSAgICAgICAgICAgICAgICBpZiAoZXZlbnQuZ2V0VHlwZSgpLmVxdWFscygiRE9NU3VidHJlZU1vZGlmaWVkIikpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGludmFsaWRhdGUgdGhlIGl0ZXJhdG9yCi0gICAgICAgICAgICAgICAgICAgICAgICBtX2lzSW52YWxpZEl0ZXJhdG9yU3RhdGUgPSB0cnVlOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBkZXJlZ2lzdGVyIGFzIGEgbGlzdGVuZXIgdG8gcmVkdWNlIGNvbXB1dGF0aW9uYWwgbG9hZAotICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlRXZlbnRMaXN0ZW5lcigpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gIC8qKgotICAgKiBHaXZlbiBhIHJlcXVlc3QgdHlwZSwgcmV0dXJuIHRoZSBlcXVpdmFsZW50IHN0cmluZy4KLSAgICogRm9yIGRpYWdub3N0aWMgcHVycG9zZXMuCi0gICAqCi0gICAqIEByZXR1cm4gdHlwZSBzdHJpbmcKLSAgICovCi0gIHByaXZhdGUgU3RyaW5nIGdldFR5cGVTdHJpbmcoaW50IHR5cGUpCi0gIHsKLSAgICAgc3dpdGNoICh0eXBlKSB7Ci0gICAgICBjYXNlIEFOWV9UWVBFOiByZXR1cm4gIkFOWV9UWVBFIjsKLSAgICAgIGNhc2UgQU5ZX1VOT1JERVJFRF9OT0RFX1RZUEU6IHJldHVybiAiQU5ZX1VOT1JERVJFRF9OT0RFX1RZUEUiOwotICAgICAgY2FzZSBCT09MRUFOX1RZUEU6IHJldHVybiAiQk9PTEVBTiI7Ci0gICAgICBjYXNlIEZJUlNUX09SREVSRURfTk9ERV9UWVBFOiByZXR1cm4gIkZJUlNUX09SREVSRURfTk9ERV9UWVBFIjsKLSAgICAgIGNhc2UgTlVNQkVSX1RZUEU6IHJldHVybiAiTlVNQkVSX1RZUEUiOwotICAgICAgY2FzZSBPUkRFUkVEX05PREVfSVRFUkFUT1JfVFlQRTogcmV0dXJuICJPUkRFUkVEX05PREVfSVRFUkFUT1JfVFlQRSI7Ci0gICAgICBjYXNlIE9SREVSRURfTk9ERV9TTkFQU0hPVF9UWVBFOiByZXR1cm4gIk9SREVSRURfTk9ERV9TTkFQU0hPVF9UWVBFIjsKLSAgICAgIGNhc2UgU1RSSU5HX1RZUEU6IHJldHVybiAiU1RSSU5HX1RZUEUiOwotICAgICAgY2FzZSBVTk9SREVSRURfTk9ERV9JVEVSQVRPUl9UWVBFOiByZXR1cm4gIlVOT1JERVJFRF9OT0RFX0lURVJBVE9SX1RZUEUiOwotICAgICAgY2FzZSBVTk9SREVSRURfTk9ERV9TTkFQU0hPVF9UWVBFOiByZXR1cm4gIlVOT1JERVJFRF9OT0RFX1NOQVBTSE9UX1RZUEUiOwotICAgICAgZGVmYXVsdDogcmV0dXJuICIjVU5LTk9XTiI7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGFuIFhPYmplY3QsIGRldGVybWluZSB0aGUgY29ycmVzcG9uZGluZyBET00gWFBhdGggdHlwZQotICAgKgotICAgKiBAcmV0dXJuIHR5cGUgc3RyaW5nCi0gICAqLwotICBwcml2YXRlIHNob3J0IGdldFR5cGVGcm9tWE9iamVjdChYT2JqZWN0IG9iamVjdCkgewotICAgICAgc3dpdGNoIChvYmplY3QuZ2V0VHlwZSgpKSB7Ci0gICAgICAgIGNhc2UgWE9iamVjdC5DTEFTU19CT09MRUFOOiByZXR1cm4gQk9PTEVBTl9UWVBFOwotICAgICAgICBjYXNlIFhPYmplY3QuQ0xBU1NfTk9ERVNFVDogcmV0dXJuIFVOT1JERVJFRF9OT0RFX0lURVJBVE9SX1RZUEU7Ci0gICAgICAgIGNhc2UgWE9iamVjdC5DTEFTU19OVU1CRVI6IHJldHVybiBOVU1CRVJfVFlQRTsKLSAgICAgICAgY2FzZSBYT2JqZWN0LkNMQVNTX1NUUklORzogcmV0dXJuIFNUUklOR19UWVBFOwotICAgICAgICAvLyBYUGF0aCAyLjAgdHlwZXMKLS8vICAgICAgICAgIGNhc2UgWE9iamVjdC5DTEFTU19EQVRFOgotLy8gICAgICAgICAgY2FzZSBYT2JqZWN0LkNMQVNTX0RBVEVUSU1FOgotLy8gICAgICAgICAgY2FzZSBYT2JqZWN0LkNMQVNTX0RURFVSQVRJT046Ci0vLyAgICAgICAgICBjYXNlIFhPYmplY3QuQ0xBU1NfR0RBWToKLS8vICAgICAgICAgIGNhc2UgWE9iamVjdC5DTEFTU19HTU9OVEg6Ci0vLyAgICAgICAgICBjYXNlIFhPYmplY3QuQ0xBU1NfR01PTlRIREFZOgotLy8gICAgICAgICAgY2FzZSBYT2JqZWN0LkNMQVNTX0dZRUFSOgotLy8gICAgICAgICAgY2FzZSBYT2JqZWN0LkNMQVNTX0dZRUFSTU9OVEg6Ci0vLyAgICAgICAgICBjYXNlIFhPYmplY3QuQ0xBU1NfVElNRToKLS8vICAgICAgICAgIGNhc2UgWE9iamVjdC5DTEFTU19ZTURVUkFUSU9OOiByZXR1cm4gU1RSSU5HX1RZUEU7IC8vIHRyZWF0IGFsbCBkYXRlIHR5cGVzIGFzIHN0cmluZ3M/Ci0KLSAgICAgICAgY2FzZSBYT2JqZWN0LkNMQVNTX1JUUkVFRlJBRzogcmV0dXJuIFVOT1JERVJFRF9OT0RFX0lURVJBVE9SX1RZUEU7Ci0gICAgICAgIGNhc2UgWE9iamVjdC5DTEFTU19OVUxMOiByZXR1cm4gQU5ZX1RZUEU7IC8vIHRocm93IGV4Y2VwdGlvbiA/Ci0gICAgICAgIGRlZmF1bHQ6IHJldHVybiBBTllfVFlQRTsgLy8gdGhyb3cgZXhjZXB0aW9uID8KLSAgICB9Ci0KLSAgfQotCi0vKioKLSAqIEdpdmVuIGEgbm9kZSwgZGV0ZXJtaW5lIGlmIGl0IGlzIGEgbmFtZXNwYWNlIG5vZGUuCi0gKgotICogQHBhcmFtIG5vZGUKLSAqCi0gKiBAcmV0dXJuIGJvb2xlYW4gUmV0dXJucyB0cnVlIGlmIHRoaXMgaXMgYSBuYW1lc3BhY2Ugbm9kZTsgb3RoZXJ3aXNlLCByZXR1cm5zIGZhbHNlLgotICovCi0gIHByaXZhdGUgYm9vbGVhbiBpc05hbWVzcGFjZU5vZGUoTm9kZSBub2RlKSB7Ci0KLSAgICAgaWYgKChudWxsICE9IG5vZGUpICYmCi0gICAgICAgICAobm9kZS5nZXROb2RlVHlwZSgpID09IE5vZGUuQVRUUklCVVRFX05PREUpICYmCi0gICAgICAgICAobm9kZS5nZXROb2RlTmFtZSgpLnN0YXJ0c1dpdGgoInhtbG5zOiIpIHx8IG5vZGUuZ2V0Tm9kZU5hbWUoKS5lcXVhbHMoInhtbG5zIikpKSB7Ci0gICAgICAgIHJldHVybiB0cnVlOwotICAgICB9IGVsc2UgewotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgIH0KLSAgfQotCi0vKioKLSAqIEFkZCBtX2NvbnRleHROb2RlIHRvIEV2ZW50IExpc3RuZXIgdG8gbGlzdGVuIGZvciBNdXRhdGlvbnMgRXZlbnRzCi0gKgotICovCi0gIHByaXZhdGUgdm9pZCBhZGRFdmVudExpc3RlbmVyKCl7Ci0gICAgICAgIGlmKG1fY29udGV4dE5vZGUgaW5zdGFuY2VvZiBFdmVudFRhcmdldCkKLSAgICAgICAgICAgICAgICAoKEV2ZW50VGFyZ2V0KW1fY29udGV4dE5vZGUpLmFkZEV2ZW50TGlzdGVuZXIoIkRPTVN1YnRyZWVNb2RpZmllZCIsdGhpcyx0cnVlKTsKLQotICB9Ci0KLQotLyoqCi0gKiBSZW1vdmUgbV9jb250ZXh0Tm9kZSB0byBFdmVudCBMaXN0bmVyIHRvIGxpc3RlbiBmb3IgTXV0YXRpb25zIEV2ZW50cwotICoKLSAqLwotcHJpdmF0ZSB2b2lkIHJlbW92ZUV2ZW50TGlzdGVuZXIoKXsKLSAgICAgICAgaWYobV9jb250ZXh0Tm9kZSBpbnN0YW5jZW9mIEV2ZW50VGFyZ2V0KQotICAgICAgICAgICAgICAgICgoRXZlbnRUYXJnZXQpbV9jb250ZXh0Tm9kZSkucmVtb3ZlRXZlbnRMaXN0ZW5lcigiRE9NU3VidHJlZU1vZGlmaWVkIix0aGlzLHRydWUpOwotfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2RvbWFwaS9YUGF0aFN0eWxlc2hlZXRET00zRXhjZXB0aW9uLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2RvbWFwaS9YUGF0aFN0eWxlc2hlZXRET00zRXhjZXB0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGMyMzIwMDMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9kb21hcGkvWFBhdGhTdHlsZXNoZWV0RE9NM0V4Y2VwdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNjMgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIFRoaXMgZmlsZSBpcyBhdmFpbGFibGUgdW5kZXIgYW5kIGdvdmVybmVkIGJ5IHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKLSAqIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICogSG93ZXZlciwgdGhlIGZvbGxvd2luZyBub3RpY2UgYWNjb21wYW5pZWQgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcwotICogZmlsZSBhbmQsIHBlciBpdHMgdGVybXMsIHNob3VsZCBub3QgYmUgcmVtb3ZlZDoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDIgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKLSAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQotICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCi0gKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKLSAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCi0gKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCi0gKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCi0gKiBQVVJQT1NFLgotICogU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuZG9tYXBpOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2VMb2NhdG9yOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci0KLS8qKgotICoKLSAqIEEgbmV3IGV4Y2VwdGlvbiB0byBhZGQgc3VwcG9ydCBmb3IgRE9NIExldmVsIDMgWFBhdGggQVBJLgotICogVGhpcyBjbGFzcyBpcyBuZWVkZWQgdG8gdGhyb3cgYSBvcmcudzNjLmRvbS5ET01FeGNlcHRpb24gd2l0aCBwcm9wZXIgZXJyb3IgY29kZSBpbgotICogY3JlYXRlRXhwcmVzc2lvbiBtZXRob2Qgb2YgWFBhdGhFdmFsdWF0b3JJbXBsIChhIERPTSBMZXZlbCAzIGNsYXNzKS4KLSAqCi0gKiBUaGlzIGNsYXNzIGV4dGVuZHMgVHJhbnNmb3JtZXJFeGNlcHRpb24gYmVjYXVzZSB0aGUgZXJyb3IgbWVzc2FnZSBpbmNsdWRlcyBpbmZvcm1hdGlvbgotICogYWJvdXQgd2hlcmUgdGhlIFhQYXRoIHByb2JsZW0gaXMgaW4gdGhlIHN0eWxlc2hlZXQgYXMgd2VsbCBhcyB0aGUgWFBhdGggZXhwcmVzc2lvbiBpdHNlbGYuCi0gKgotICogQHhzbC51c2FnZSBpbnRlcm5hbAotICovCi1maW5hbCBwdWJsaWMgY2xhc3MgWFBhdGhTdHlsZXNoZWV0RE9NM0V4Y2VwdGlvbiBleHRlbmRzIFRyYW5zZm9ybWVyRXhjZXB0aW9uIHsKLSAgICAgICAgcHVibGljIFhQYXRoU3R5bGVzaGVldERPTTNFeGNlcHRpb24oU3RyaW5nIG1zZywgU291cmNlTG9jYXRvciBhcmcxKQotICAgICAgICB7Ci0gICAgICAgICAgICAgICAgc3VwZXIobXNnLCBhcmcxKTsKLSAgICAgICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9kb21hcGkvcGFja2FnZS5odG1sIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9kb21hcGkvcGFja2FnZS5odG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmNzBkMGM0Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvZG9tYXBpL3BhY2thZ2UuaHRtbAorKysgL2Rldi9udWxsCkBAIC0xLDI4ICswLDAgQEAKLTwhLS0KLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0tLT4KLTwhLS0KLSAqIENvcHlyaWdodCAyMDAwLTIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotLS0+Ci08IS0tICRJZDogcGFja2FnZS5odG1sLHYgMS4xLjQuMSAyMDA1LzA5LzA3IDIyOjI3OjI4IGplZmZzdXR0b3IgRXhwICQgLS0+Ci08aHRtbD4KLSAgPHRpdGxlPlhQYXRoIGRvbWFwaSBQYWNrYWdlLjwvdGl0bGU+Ci0gIDxib2R5PgotICAgIDxwPkltcGxlbWVudHMgRE9NIExldmVsIDMgWFBhdGggQVBJPHA+Ci0gPC9ib2R5PgotPC9odG1sPgotCi0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvZnVuY3Rpb25zL0Z1bmNCb29sZWFuLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2Z1bmN0aW9ucy9GdW5jQm9vbGVhbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2MjhiZjIyLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvZnVuY3Rpb25zL0Z1bmNCb29sZWFuLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw1MCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBGdW5jQm9vbGVhbi5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE0IDE5OjUzOjQ1IGplZmZzdXR0b3IgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuZnVuY3Rpb25zOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoQ29udGV4dDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YQm9vbGVhbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YT2JqZWN0OwotCi0vKioKLSAqIEV4ZWN1dGUgdGhlIEJvb2xlYW4oKSBmdW5jdGlvbi4KLSAqIEB4c2wudXNhZ2UgYWR2YW5jZWQKLSAqLwotcHVibGljIGNsYXNzIEZ1bmNCb29sZWFuIGV4dGVuZHMgRnVuY3Rpb25PbmVBcmcKLXsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNDMyODY2MDc2MDA3MDAzNDU5Mkw7Ci0KLSAgLyoqCi0gICAqIEV4ZWN1dGUgdGhlIGZ1bmN0aW9uLiAgVGhlIGZ1bmN0aW9uIG11c3QgcmV0dXJuCi0gICAqIGEgdmFsaWQgb2JqZWN0LgotICAgKiBAcGFyYW0geGN0eHQgVGhlIGN1cnJlbnQgZXhlY3V0aW9uIGNvbnRleHQuCi0gICAqIEByZXR1cm4gQSB2YWxpZCBYT2JqZWN0LgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IGV4ZWN1dGUoWFBhdGhDb250ZXh0IHhjdHh0KSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIG1fYXJnMC5leGVjdXRlKHhjdHh0KS5ib29sKCkgPyBYQm9vbGVhbi5TX1RSVUUgOiBYQm9vbGVhbi5TX0ZBTFNFOwotICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvZnVuY3Rpb25zL0Z1bmNDZWlsaW5nLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2Z1bmN0aW9ucy9GdW5jQ2VpbGluZy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4MmNkNDVjLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvZnVuY3Rpb25zL0Z1bmNDZWlsaW5nLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0OSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBGdW5jQ2VpbGluZy5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE0IDE5OjUzOjQ0IGplZmZzdXR0b3IgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuZnVuY3Rpb25zOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoQ29udGV4dDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YTnVtYmVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhPYmplY3Q7Ci0KLS8qKgotICogRXhlY3V0ZSB0aGUgQ2VpbGluZygpIGZ1bmN0aW9uLgotICogQHhzbC51c2FnZSBhZHZhbmNlZAotICovCi1wdWJsaWMgY2xhc3MgRnVuY0NlaWxpbmcgZXh0ZW5kcyBGdW5jdGlvbk9uZUFyZwotewotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMTI3NTk4ODkzNjM5MDQ2NDczOUw7Ci0KLSAgLyoqCi0gICAqIEV4ZWN1dGUgdGhlIGZ1bmN0aW9uLiAgVGhlIGZ1bmN0aW9uIG11c3QgcmV0dXJuCi0gICAqIGEgdmFsaWQgb2JqZWN0LgotICAgKiBAcGFyYW0geGN0eHQgVGhlIGN1cnJlbnQgZXhlY3V0aW9uIGNvbnRleHQuCi0gICAqIEByZXR1cm4gQSB2YWxpZCBYT2JqZWN0LgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IGV4ZWN1dGUoWFBhdGhDb250ZXh0IHhjdHh0KSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIG5ldyBYTnVtYmVyKE1hdGguY2VpbChtX2FyZzAuZXhlY3V0ZSh4Y3R4dCkubnVtKCkpKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9mdW5jdGlvbnMvRnVuY0NvbmNhdC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9mdW5jdGlvbnMvRnVuY0NvbmNhdC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2ZjJhMTczLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvZnVuY3Rpb25zL0Z1bmNDb25jYXQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDkyICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IEZ1bmNDb25jYXQuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNCAxOTo1Mzo0NCBqZWZmc3V0dG9yIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmZ1bmN0aW9uczsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC5yZXMuWFNMTWVzc2FnZXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoQ29udGV4dDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YT2JqZWN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhTdHJpbmc7Ci0KLS8qKgotICogRXhlY3V0ZSB0aGUgQ29uY2F0KCkgZnVuY3Rpb24uCi0gKiBAeHNsLnVzYWdlIGFkdmFuY2VkCi0gKi8KLXB1YmxpYyBjbGFzcyBGdW5jQ29uY2F0IGV4dGVuZHMgRnVuY3Rpb25NdWx0aUFyZ3MKLXsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMTczNzIyODg4NTIwMjMxNDQxM0w7Ci0KLSAgLyoqCi0gICAqIEV4ZWN1dGUgdGhlIGZ1bmN0aW9uLiAgVGhlIGZ1bmN0aW9uIG11c3QgcmV0dXJuCi0gICAqIGEgdmFsaWQgb2JqZWN0LgotICAgKiBAcGFyYW0geGN0eHQgVGhlIGN1cnJlbnQgZXhlY3V0aW9uIGNvbnRleHQuCi0gICAqIEByZXR1cm4gQSB2YWxpZCBYT2JqZWN0LgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IGV4ZWN1dGUoWFBhdGhDb250ZXh0IHhjdHh0KSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBTdHJpbmdCdWZmZXIgc2IgPSBuZXcgU3RyaW5nQnVmZmVyKCk7Ci0KLSAgICAvLyBDb21waWxlciBzYXlzIHdlIG11c3QgaGF2ZSBhdCBsZWFzdCB0d28gYXJndW1lbnRzLgotICAgIHNiLmFwcGVuZChtX2FyZzAuZXhlY3V0ZSh4Y3R4dCkuc3RyKCkpOwotICAgIHNiLmFwcGVuZChtX2FyZzEuZXhlY3V0ZSh4Y3R4dCkuc3RyKCkpOwotCi0gICAgaWYgKG51bGwgIT0gbV9hcmcyKQotICAgICAgc2IuYXBwZW5kKG1fYXJnMi5leGVjdXRlKHhjdHh0KS5zdHIoKSk7Ci0KLSAgICBpZiAobnVsbCAhPSBtX2FyZ3MpCi0gICAgewotICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtX2FyZ3MubGVuZ3RoOyBpKyspCi0gICAgICB7Ci0gICAgICAgIHNiLmFwcGVuZChtX2FyZ3NbaV0uZXhlY3V0ZSh4Y3R4dCkuc3RyKCkpOwotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiBuZXcgWFN0cmluZyhzYi50b1N0cmluZygpKTsKLSAgfQotCi0gIC8qKgotICAgKiBDaGVjayB0aGF0IHRoZSBudW1iZXIgb2YgYXJndW1lbnRzIHBhc3NlZCB0byB0aGlzIGZ1bmN0aW9uIGlzIGNvcnJlY3QuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBhcmdOdW0gVGhlIG51bWJlciBvZiBhcmd1bWVudHMgdGhhdCBpcyBiZWluZyBwYXNzZWQgdG8gdGhlIGZ1bmN0aW9uLgotICAgKgotICAgKiBAdGhyb3dzIFdyb25nTnVtYmVyQXJnc0V4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgY2hlY2tOdW1iZXJBcmdzKGludCBhcmdOdW0pIHRocm93cyBXcm9uZ051bWJlckFyZ3NFeGNlcHRpb24KLSAgewotICAgIGlmIChhcmdOdW0gPCAyKQotICAgICAgcmVwb3J0V3JvbmdOdW1iZXJBcmdzKCk7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0cyBhbmQgdGhyb3dzIGEgV3JvbmdOdW1iZXJBcmdFeGNlcHRpb24gd2l0aCB0aGUgYXBwcm9wcmlhdGUKLSAgICogbWVzc2FnZSBmb3IgdGhpcyBmdW5jdGlvbiBvYmplY3QuCi0gICAqCi0gICAqIEB0aHJvd3MgV3JvbmdOdW1iZXJBcmdzRXhjZXB0aW9uCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCByZXBvcnRXcm9uZ051bWJlckFyZ3MoKSB0aHJvd3MgV3JvbmdOdW1iZXJBcmdzRXhjZXB0aW9uIHsKLSAgICAgIHRocm93IG5ldyBXcm9uZ051bWJlckFyZ3NFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKCJndG9uZSIsIG51bGwpKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9mdW5jdGlvbnMvRnVuY0NvbnRhaW5zLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2Z1bmN0aW9ucy9GdW5jQ29udGFpbnMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZTdjYTNhYS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2Z1bmN0aW9ucy9GdW5jQ29udGFpbnMuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDU5ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IEZ1bmNDb250YWlucy5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE0IDE5OjUzOjQ0IGplZmZzdXR0b3IgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuZnVuY3Rpb25zOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoQ29udGV4dDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YQm9vbGVhbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YT2JqZWN0OwotCi0vKioKLSAqIEV4ZWN1dGUgdGhlIENvbnRhaW5zKCkgZnVuY3Rpb24uCi0gKiBAeHNsLnVzYWdlIGFkdmFuY2VkCi0gKi8KLXB1YmxpYyBjbGFzcyBGdW5jQ29udGFpbnMgZXh0ZW5kcyBGdW5jdGlvbjJBcmdzCi17Ci0gICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDUwODQ3NTM3ODE4ODc5MTk3MjNMOwotCi0gIC8qKgotICAgKiBFeGVjdXRlIHRoZSBmdW5jdGlvbi4gIFRoZSBmdW5jdGlvbiBtdXN0IHJldHVybgotICAgKiBhIHZhbGlkIG9iamVjdC4KLSAgICogQHBhcmFtIHhjdHh0IFRoZSBjdXJyZW50IGV4ZWN1dGlvbiBjb250ZXh0LgotICAgKiBAcmV0dXJuIEEgdmFsaWQgWE9iamVjdC4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBleGVjdXRlKFhQYXRoQ29udGV4dCB4Y3R4dCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgU3RyaW5nIHMxID0gbV9hcmcwLmV4ZWN1dGUoeGN0eHQpLnN0cigpOwotICAgIFN0cmluZyBzMiA9IG1fYXJnMS5leGVjdXRlKHhjdHh0KS5zdHIoKTsKLQotICAgIC8vIEFkZCB0aGlzIGNoZWNrIGZvciBKREsgY29uc2lzdGVuY3kgZm9yIGVtcHR5IHN0cmluZ3MuCi0gICAgaWYgKHMxLmxlbmd0aCgpID09IDAgJiYgczIubGVuZ3RoKCkgPT0gMCkKLSAgICAgIHJldHVybiBYQm9vbGVhbi5TX1RSVUU7Ci0KLSAgICBpbnQgaW5kZXggPSBzMS5pbmRleE9mKHMyKTsKLQotICAgIHJldHVybiAoaW5kZXggPiAtMSkgPyBYQm9vbGVhbi5TX1RSVUUgOiBYQm9vbGVhbi5TX0ZBTFNFOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2Z1bmN0aW9ucy9GdW5jQ291bnQuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvZnVuY3Rpb25zL0Z1bmNDb3VudC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiOWIxMzI2Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvZnVuY3Rpb25zL0Z1bmNDb3VudC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNjYgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRnVuY0NvdW50LmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTQgMTk6NTM6NDUgamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5mdW5jdGlvbnM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1JdGVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuWFBhdGhDb250ZXh0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhOdW1iZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWE9iamVjdDsKLQotLyoqCi0gKiBFeGVjdXRlIHRoZSBDb3VudCgpIGZ1bmN0aW9uLgotICogQHhzbC51c2FnZSBhZHZhbmNlZAotICovCi1wdWJsaWMgY2xhc3MgRnVuY0NvdW50IGV4dGVuZHMgRnVuY3Rpb25PbmVBcmcKLXsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTcxMTYyMjUxMDA0NzQxNTM3NTFMOwotCi0gIC8qKgotICAgKiBFeGVjdXRlIHRoZSBmdW5jdGlvbi4gIFRoZSBmdW5jdGlvbiBtdXN0IHJldHVybgotICAgKiBhIHZhbGlkIG9iamVjdC4KLSAgICogQHBhcmFtIHhjdHh0IFRoZSBjdXJyZW50IGV4ZWN1dGlvbiBjb250ZXh0LgotICAgKiBAcmV0dXJuIEEgdmFsaWQgWE9iamVjdC4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBleGVjdXRlKFhQYXRoQ29udGV4dCB4Y3R4dCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0vLyAgICBEVE1JdGVyYXRvciBubCA9IG1fYXJnMC5hc0l0ZXJhdG9yKHhjdHh0LCB4Y3R4dC5nZXRDdXJyZW50Tm9kZSgpKTsKLQotLy8gICAgLy8gV2Ugc2hvdWxkIHByb2JhYmx5IG1ha2UgYSBmdW5jdGlvbiBvbiB0aGUgaXRlcmF0b3IgZm9yIHRoaXMsCi0vLyAgICAvLyBhcyBhIGdpdmVuIGltcGxlbWVudGF0aW9uIGNvdWxkIG9wdGltaXplLgotLy8gICAgaW50IGkgPSAwOwotLy8KLS8vICAgIHdoaWxlIChEVE0uTlVMTCAhPSBubC5uZXh0Tm9kZSgpKQotLy8gICAgewotLy8gICAgICBpKys7Ci0vLyAgICB9Ci0vLyAgICBubC5kZXRhY2goKTsKLSAgICAgICAgRFRNSXRlcmF0b3IgbmwgPSBtX2FyZzAuYXNJdGVyYXRvcih4Y3R4dCwgeGN0eHQuZ2V0Q3VycmVudE5vZGUoKSk7Ci0gICAgICAgIGludCBpID0gbmwuZ2V0TGVuZ3RoKCk7Ci0gICAgICAgIG5sLmRldGFjaCgpOwotCi0gICAgcmV0dXJuIG5ldyBYTnVtYmVyKChkb3VibGUpIGkpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2Z1bmN0aW9ucy9GdW5jQ3VycmVudC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9mdW5jdGlvbnMvRnVuY0N1cnJlbnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYjM4NDU0OS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2Z1bmN0aW9ucy9GdW5jQ3VycmVudC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsODQgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRnVuY0N1cnJlbnQuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNCAxOTo1Mzo0NCBqZWZmc3V0dG9yIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmZ1bmN0aW9uczsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1JdGVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuWFBhdGhDb250ZXh0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5heGVzLkxvY1BhdGhJdGVyYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuYXhlcy5QcmVkaWNhdGVkTm9kZVRlc3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWE5vZGVTZXQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWE9iamVjdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuYXhlcy5TdWJDb250ZXh0TGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucGF0dGVybnMuU3RlcFBhdHRlcm47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnJlcy5YU0xNZXNzYWdlczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwucmVzLlhTTFRFcnJvclJlc291cmNlczsKLQotCi0vKioKLSAqIEV4ZWN1dGUgdGhlIGN1cnJlbnQoKSBmdW5jdGlvbi4KLSAqIEB4c2wudXNhZ2UgYWR2YW5jZWQKLSAqLwotcHVibGljIGNsYXNzIEZ1bmNDdXJyZW50IGV4dGVuZHMgRnVuY3Rpb24KLXsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNTcxNTMxNjgwNDg3NzcxNTAwOEw7Ci0KLSAgLyoqCi0gICAqIEV4ZWN1dGUgdGhlIGZ1bmN0aW9uLiAgVGhlIGZ1bmN0aW9uIG11c3QgcmV0dXJuCi0gICAqIGEgdmFsaWQgb2JqZWN0LgotICAgKiBAcGFyYW0geGN0eHQgVGhlIGN1cnJlbnQgZXhlY3V0aW9uIGNvbnRleHQuCi0gICAqIEByZXR1cm4gQSB2YWxpZCBYT2JqZWN0LgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IGV4ZWN1dGUoWFBhdGhDb250ZXh0IHhjdHh0KSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBTdWJDb250ZXh0TGlzdCBzdWJDb250ZXh0TGlzdCA9IHhjdHh0LmdldEN1cnJlbnROb2RlTGlzdCgpOwotICAgIGludCBjdXJyZW50Tm9kZSA9IERUTS5OVUxMOwotCi0gICAgaWYgKG51bGwgIT0gc3ViQ29udGV4dExpc3QpIHsKLSAgICAgICAgaWYgKHN1YkNvbnRleHRMaXN0IGluc3RhbmNlb2YgUHJlZGljYXRlZE5vZGVUZXN0KSB7Ci0gICAgICAgICAgICBMb2NQYXRoSXRlcmF0b3IgaXRlciA9ICgoUHJlZGljYXRlZE5vZGVUZXN0KXN1YkNvbnRleHRMaXN0KQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRMb2NQYXRoSXRlcmF0b3IoKTsKLSAgICAgICAgICAgIGN1cnJlbnROb2RlID0gaXRlci5nZXRDdXJyZW50Q29udGV4dE5vZGUoKTsKLSAgICAgICAgIH0gZWxzZSBpZihzdWJDb250ZXh0TGlzdCBpbnN0YW5jZW9mIFN0ZXBQYXR0ZXJuKSB7Ci0gICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoCi0gICAgICAgICAgICAgIFhTTFRFcnJvclJlc291cmNlcy5FUl9QUk9DRVNTT1JfRVJST1IsbnVsbCkpOwotICAgICAgICAgfQotICAgIH0gZWxzZSB7Ci0gICAgICAgIC8vIG5vdCBwcmVkaWNhdGUgPT4gQ29udGV4dE5vZGUgPT0gQ3VycmVudE5vZGUKLSAgICAgICAgY3VycmVudE5vZGUgPSB4Y3R4dC5nZXRDb250ZXh0Tm9kZSgpOwotICAgIH0KLSAgICByZXR1cm4gbmV3IFhOb2RlU2V0KGN1cnJlbnROb2RlLCB4Y3R4dC5nZXREVE1NYW5hZ2VyKCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIE5vIGFyZ3VtZW50cyB0byBwcm9jZXNzLCBzbyB0aGlzIGRvZXMgbm90aGluZy4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGZpeHVwVmFyaWFibGVzKGphdmEudXRpbC5WZWN0b3IgdmFycywgaW50IGdsb2JhbHNTaXplKQotICB7Ci0gICAgLy8gbm8tb3AKLSAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2Z1bmN0aW9ucy9GdW5jRG9jbG9jYXRpb24uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvZnVuY3Rpb25zL0Z1bmNEb2Nsb2NhdGlvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxMjE3YWY3Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvZnVuY3Rpb25zL0Z1bmNEb2Nsb2NhdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNzMgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRnVuY0RvY2xvY2F0aW9uLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTQgMTk6NTM6NDQgamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5mdW5jdGlvbnM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE07Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoQ29udGV4dDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YT2JqZWN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhTdHJpbmc7Ci0KLS8qKgotICogRXhlY3V0ZSB0aGUgcHJvcHJpZXRhcnkgZG9jdW1lbnQtbG9jYXRpb24oKSBmdW5jdGlvbiwgd2hpY2ggcmV0dXJucwotICogYSBub2RlIHNldCBvZiBkb2N1bWVudHMuCi0gKiBAeHNsLnVzYWdlIGFkdmFuY2VkCi0gKi8KLXB1YmxpYyBjbGFzcyBGdW5jRG9jbG9jYXRpb24gZXh0ZW5kcyBGdW5jdGlvbkRlZjFBcmcKLXsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNzQ2OTIxMzk0NjM0MzU2ODc2OUw7Ci0KLSAgLyoqCi0gICAqIEV4ZWN1dGUgdGhlIGZ1bmN0aW9uLiAgVGhlIGZ1bmN0aW9uIG11c3QgcmV0dXJuCi0gICAqIGEgdmFsaWQgb2JqZWN0LgotICAgKiBAcGFyYW0geGN0eHQgVGhlIGN1cnJlbnQgZXhlY3V0aW9uIGNvbnRleHQuCi0gICAqIEByZXR1cm4gQSB2YWxpZCBYT2JqZWN0LgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IGV4ZWN1dGUoWFBhdGhDb250ZXh0IHhjdHh0KSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpbnQgd2hlcmVOb2RlID0gZ2V0QXJnMEFzTm9kZSh4Y3R4dCk7Ci0gICAgU3RyaW5nIGZpbGVMb2NhdGlvbiA9IG51bGw7Ci0KLSAgICBpZiAoRFRNLk5VTEwgIT0gd2hlcmVOb2RlKQotICAgIHsKLSAgICAgIERUTSBkdG0gPSB4Y3R4dC5nZXREVE0od2hlcmVOb2RlKTsKLQotICAgICAgLy8gJVJFVklFVyUKLSAgICAgIGlmIChEVE0uRE9DVU1FTlRfRlJBR01FTlRfTk9ERSA9PSAgZHRtLmdldE5vZGVUeXBlKHdoZXJlTm9kZSkpCi0gICAgICB7Ci0gICAgICAgIHdoZXJlTm9kZSA9IGR0bS5nZXRGaXJzdENoaWxkKHdoZXJlTm9kZSk7Ci0gICAgICB9Ci0KLSAgICAgIGlmIChEVE0uTlVMTCAhPSB3aGVyZU5vZGUpCi0gICAgICB7Ci0gICAgICAgIGZpbGVMb2NhdGlvbiA9IGR0bS5nZXREb2N1bWVudEJhc2VVUkkoKTsKLS8vICAgICAgICBpbnQgb3duZXIgPSBkdG0uZ2V0RG9jdW1lbnQoKTsKLS8vICAgICAgICBmaWxlTG9jYXRpb24gPSB4Y3R4dC5nZXRTb3VyY2VUcmVlTWFuYWdlcigpLmZpbmRVUklGcm9tRG9jKG93bmVyKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gbmV3IFhTdHJpbmcoKG51bGwgIT0gZmlsZUxvY2F0aW9uKSA/IGZpbGVMb2NhdGlvbiA6ICIiKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9mdW5jdGlvbnMvRnVuY0V4dEVsZW1lbnRBdmFpbGFibGUuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvZnVuY3Rpb25zL0Z1bmNFeHRFbGVtZW50QXZhaWxhYmxlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGJjNDU4NWEuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9mdW5jdGlvbnMvRnVuY0V4dEVsZW1lbnRBdmFpbGFibGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDk5ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IEZ1bmNFeHRFbGVtZW50QXZhaWxhYmxlLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTQgMTk6NTg6MzIgamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5mdW5jdGlvbnM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwudGVtcGxhdGVzLkNvbnN0YW50czsKLS8vIEoyU0UgZG9lcyBub3Qgc3VwcG9ydCBYYWxhbiBpbnRlcnByZXRpdmUKLS8qCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnRyYW5zZm9ybWVyLlRyYW5zZm9ybWVySW1wbDsKLSovCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5RTmFtZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuRXh0ZW5zaW9uc1Byb3ZpZGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5YUGF0aENvbnRleHQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWEJvb2xlYW47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWE9iamVjdDsKLQotLyoqCi0gKiBFeGVjdXRlIHRoZSBFeHRFbGVtZW50QXZhaWxhYmxlKCkgZnVuY3Rpb24uCi0gKiBAeHNsLnVzYWdlIGFkdmFuY2VkCi0gKi8KLXB1YmxpYyBjbGFzcyBGdW5jRXh0RWxlbWVudEF2YWlsYWJsZSBleHRlbmRzIEZ1bmN0aW9uT25lQXJnCi17Ci0gICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC00NzI1MzM2OTkyNTc5Njg1NDZMOwotCi0gIC8qKgotICAgKiBFeGVjdXRlIHRoZSBmdW5jdGlvbi4gIFRoZSBmdW5jdGlvbiBtdXN0IHJldHVybgotICAgKiBhIHZhbGlkIG9iamVjdC4KLSAgICogQHBhcmFtIHhjdHh0IFRoZSBjdXJyZW50IGV4ZWN1dGlvbiBjb250ZXh0LgotICAgKiBAcmV0dXJuIEEgdmFsaWQgWE9iamVjdC4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBleGVjdXRlKFhQYXRoQ29udGV4dCB4Y3R4dCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgU3RyaW5nIHByZWZpeDsKLSAgICBTdHJpbmcgbmFtZXNwYWNlOwotICAgIFN0cmluZyBtZXRoTmFtZTsKLQotICAgIFN0cmluZyBmdWxsTmFtZSA9IG1fYXJnMC5leGVjdXRlKHhjdHh0KS5zdHIoKTsKLSAgICBpbnQgaW5kZXhPZk5TU2VwID0gZnVsbE5hbWUuaW5kZXhPZignOicpOwotCi0gICAgaWYgKGluZGV4T2ZOU1NlcCA8IDApCi0gICAgewotICAgICAgcHJlZml4ID0gIiI7Ci0gICAgICBuYW1lc3BhY2UgPSBDb25zdGFudHMuU19YU0xOQU1FU1BBQ0VVUkw7Ci0gICAgICBtZXRoTmFtZSA9IGZ1bGxOYW1lOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgcHJlZml4ID0gZnVsbE5hbWUuc3Vic3RyaW5nKDAsIGluZGV4T2ZOU1NlcCk7Ci0gICAgICBuYW1lc3BhY2UgPSB4Y3R4dC5nZXROYW1lc3BhY2VDb250ZXh0KCkuZ2V0TmFtZXNwYWNlRm9yUHJlZml4KHByZWZpeCk7Ci0gICAgICBpZiAobnVsbCA9PSBuYW1lc3BhY2UpCi0gICAgICAgIHJldHVybiBYQm9vbGVhbi5TX0ZBTFNFOwotICAgICAgbWV0aE5hbWU9IGZ1bGxOYW1lLnN1YnN0cmluZyhpbmRleE9mTlNTZXAgKyAxKTsKLSAgICB9Ci0KLSAgICBpZiAobmFtZXNwYWNlLmVxdWFscyhDb25zdGFudHMuU19YU0xOQU1FU1BBQ0VVUkwpCi0gICAgfHwgIG5hbWVzcGFjZS5lcXVhbHMoQ29uc3RhbnRzLlNfQlVJTFRJTl9FWFRFTlNJT05TX1VSTCkpIHsKLQotICAgICAgICAvLyBKMlNFIGRvZXMgbm90IHN1cHBvcnQgWGFsYW4gaW50ZXJwcmV0aXZlCi0gICAgICAgIC8qCi0gICAgICB0cnkgewotICAgICAgICBUcmFuc2Zvcm1lckltcGwgdHJhbnNmb3JtZXIgPSAoVHJhbnNmb3JtZXJJbXBsKSB4Y3R4dC5nZXRPd25lck9iamVjdCgpOwotICAgICAgICByZXR1cm4gdHJhbnNmb3JtZXIuZ2V0U3R5bGVzaGVldCgpLmdldEF2YWlsYWJsZUVsZW1lbnRzKCkuY29udGFpbnNLZXkoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgUU5hbWUobmFtZXNwYWNlLCBtZXRoTmFtZSkpCi0gICAgICAgICAgICAgICA/IFhCb29sZWFuLlNfVFJVRSA6IFhCb29sZWFuLlNfRkFMU0U7Ci0gICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgICByZXR1cm4gWEJvb2xlYW4uU19GQUxTRTsKLSAgICAgIH0KLSAgICAgICovCi0gICAgICAgIHJldHVybiBYQm9vbGVhbi5TX0ZBTFNFOwotICAgIH0gZWxzZSB7Ci0gICAgICAvL2RtbAotICAgICAgRXh0ZW5zaW9uc1Byb3ZpZGVyIGV4dFByb3ZpZGVyID0gKEV4dGVuc2lvbnNQcm92aWRlcil4Y3R4dC5nZXRPd25lck9iamVjdCgpOwotICAgICAgcmV0dXJuIGV4dFByb3ZpZGVyLmVsZW1lbnRBdmFpbGFibGUobmFtZXNwYWNlLCBtZXRoTmFtZSkKLSAgICAgICAgICAgICA/IFhCb29sZWFuLlNfVFJVRSA6IFhCb29sZWFuLlNfRkFMU0U7Ci0gICAgfQotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2Z1bmN0aW9ucy9GdW5jRXh0RnVuY3Rpb24uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvZnVuY3Rpb25zL0Z1bmNFeHRGdW5jdGlvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1ZWFhNGM0Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvZnVuY3Rpb25zL0Z1bmNFeHRGdW5jdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzQyICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IEZ1bmNFeHRGdW5jdGlvbi5qYXZhLHYgMS4yLjQuMiAyMDA1LzA5LzE0IDIwOjE4OjQzIGplZmZzdXR0b3IgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuZnVuY3Rpb25zOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC5yZXMuWFNMTWVzc2FnZXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLkV4cHJlc3Npb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLkV4cHJlc3Npb25Ob2RlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5FeHByZXNzaW9uT3duZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLkV4dGVuc2lvbnNQcm92aWRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuWFBhdGhDb250ZXh0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5YUGF0aFZpc2l0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWE51bGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWE9iamVjdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucmVzLlhQQVRIRXJyb3JSZXNvdXJjZXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLnJlcy5YUEFUSE1lc3NhZ2VzOwotCi0vKioKLSAqIEFuIG9iamVjdCBvZiB0aGlzIGNsYXNzIHJlcHJlc2VudHMgYW4gZXh0ZW5zaW9uIGNhbGwgZXhwcmVzc2lvbi4gIFdoZW4KLSAqIHRoZSBleHByZXNzaW9uIGV4ZWN1dGVzLCBpdCBjYWxscyBFeHRlbnNpb25zVGFibGUjZXh0RnVuY3Rpb24sIGFuZCB0aGVuCi0gKiBjb252ZXJ0cyB0aGUgcmVzdWx0IHRvIHRoZSBhcHByb3ByaWF0ZSBYT2JqZWN0LgotICogQHhzbC51c2FnZSBhZHZhbmNlZAotICovCi1wdWJsaWMgY2xhc3MgRnVuY0V4dEZ1bmN0aW9uIGV4dGVuZHMgRnVuY3Rpb24KLXsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNTE5NjExNTU1NDY5MzcwODcxOEw7Ci0KLSAgLyoqCi0gICAqIFRoZSBuYW1lc3BhY2UgZm9yIHRoZSBleHRlbnNpb24gZnVuY3Rpb24sIHdoaWNoIHNob3VsZCBub3Qgbm9ybWFsbHkKLSAgICogIGJlIG51bGwgb3IgZW1wdHkuCi0gICAqICBAc2VyaWFsCi0gICAqLwotICBTdHJpbmcgbV9uYW1lc3BhY2U7Ci0KLSAgLyoqCi0gICAqIFRoZSBsb2NhbCBuYW1lIG9mIHRoZSBleHRlbnNpb24uCi0gICAqICBAc2VyaWFsCi0gICAqLwotICBTdHJpbmcgbV9leHRlbnNpb25OYW1lOwotCi0gIC8qKgotICAgKiBVbmlxdWUgbWV0aG9kIGtleSwgd2hpY2ggaXMgcGFzc2VkIHRvIEV4dGVuc2lvbnNUYWJsZSNleHRGdW5jdGlvbiBpbgotICAgKiAgb3JkZXIgdG8gYWxsb3cgY2FjaGluZyBvZiB0aGUgbWV0aG9kLgotICAgKiAgQHNlcmlhbAotICAgKi8KLSAgT2JqZWN0IG1fbWV0aG9kS2V5OwotCi0gIC8qKgotICAgKiBBcnJheSBvZiBzdGF0aWMgZXhwcmVzc2lvbnMgd2hpY2ggcmVwcmVzZW50IHRoZSBwYXJhbWV0ZXJzIHRvIHRoZQotICAgKiAgZnVuY3Rpb24uCi0gICAqICBAc2VyaWFsCi0gICAqLwotICBWZWN0b3IgbV9hcmdWZWMgPSBuZXcgVmVjdG9yKCk7Ci0KLSAgLyoqCi0gICAqIFRoaXMgZnVuY3Rpb24gaXMgdXNlZCB0byBmaXh1cCB2YXJpYWJsZXMgZnJvbSBRTmFtZXMgdG8gc3RhY2sgZnJhbWUKLSAgICogaW5kZXhlcyBhdCBzdHlsZXNoZWV0IGJ1aWxkIHRpbWUuCi0gICAqIEBwYXJhbSB2YXJzIExpc3Qgb2YgUU5hbWVzIHRoYXQgY29ycmVzcG9uZCB0byB2YXJpYWJsZXMuICBUaGlzIGxpc3QKLSAgICogc2hvdWxkIGJlIHNlYXJjaGVkIGJhY2t3YXJkcyBmb3IgdGhlIGZpcnN0IHF1YWxpZmllZCBuYW1lIHRoYXQKLSAgICogY29ycmVzcG9uZHMgdG8gdGhlIHZhcmlhYmxlIHJlZmVyZW5jZSBxbmFtZS4gIFRoZSBwb3NpdGlvbiBvZiB0aGUKLSAgICogUU5hbWUgaW4gdGhlIHZlY3RvciBmcm9tIHRoZSBzdGFydCBvZiB0aGUgdmVjdG9yIHdpbGwgYmUgaXRzIHBvc2l0aW9uCi0gICAqIGluIHRoZSBzdGFjayBmcmFtZSAoYnV0IHZhcmlhYmxlcyBhYm92ZSB0aGUgZ2xvYmFsc1RvcCB2YWx1ZSB3aWxsIG5lZWQKLSAgICogdG8gYmUgb2Zmc2V0IHRvIHRoZSBjdXJyZW50IHN0YWNrIGZyYW1lKS4KLSAgICogTkVFRFNET0MgQHBhcmFtIGdsb2JhbHNTaXplCi0gICAqLwotICBwdWJsaWMgdm9pZCBmaXh1cFZhcmlhYmxlcyhqYXZhLnV0aWwuVmVjdG9yIHZhcnMsIGludCBnbG9iYWxzU2l6ZSkKLSAgewotCi0gICAgaWYgKG51bGwgIT0gbV9hcmdWZWMpCi0gICAgewotICAgICAgaW50IG5BcmdzID0gbV9hcmdWZWMuc2l6ZSgpOwotCi0gICAgICBmb3IgKGludCBpID0gMDsgaSA8IG5BcmdzOyBpKyspCi0gICAgICB7Ci0gICAgICAgIEV4cHJlc3Npb24gYXJnID0gKEV4cHJlc3Npb24pIG1fYXJnVmVjLmVsZW1lbnRBdChpKTsKLQotICAgICAgICBhcmcuZml4dXBWYXJpYWJsZXModmFycywgZ2xvYmFsc1NpemUpOwotICAgICAgfQotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIG5hbWVzcGFjZSBvZiB0aGUgZXh0ZW5zaW9uIGZ1bmN0aW9uLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBuYW1lc3BhY2Ugb2YgdGhlIGV4dGVuc2lvbiBmdW5jdGlvbi4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZXNwYWNlKCkKLSAgewotICAgIHJldHVybiBtX25hbWVzcGFjZTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIG5hbWUgb2YgdGhlIGV4dGVuc2lvbiBmdW5jdGlvbi4KLSAgICoKLSAgICogQHJldHVybiBUaGUgbmFtZSBvZiB0aGUgZXh0ZW5zaW9uIGZ1bmN0aW9uLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRGdW5jdGlvbk5hbWUoKQotICB7Ci0gICAgcmV0dXJuIG1fZXh0ZW5zaW9uTmFtZTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIG1ldGhvZCBrZXkgb2YgdGhlIGV4dGVuc2lvbiBmdW5jdGlvbi4KLSAgICoKLSAgICogQHJldHVybiBUaGUgbWV0aG9kIGtleSBvZiB0aGUgZXh0ZW5zaW9uIGZ1bmN0aW9uLgotICAgKi8KLSAgcHVibGljIE9iamVjdCBnZXRNZXRob2RLZXkoKQotICB7Ci0gICAgcmV0dXJuIG1fbWV0aG9kS2V5OwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgbnRoIGFyZ3VtZW50IHBhc3NlZCB0byB0aGUgZXh0ZW5zaW9uIGZ1bmN0aW9uLgotICAgKgotICAgKiBAcGFyYW0gbiBUaGUgYXJndW1lbnQgbnVtYmVyIGluZGV4LgotICAgKiBAcmV0dXJuIFRoZSBFeHByZXNzaW9uIG9iamVjdCBhdCB0aGUgZ2l2ZW4gaW5kZXguCi0gICAqLwotICBwdWJsaWMgRXhwcmVzc2lvbiBnZXRBcmcoaW50IG4pIHsKLSAgICBpZiAobiA+PSAwICYmIG4gPCBtX2FyZ1ZlYy5zaXplKCkpCi0gICAgICByZXR1cm4gKEV4cHJlc3Npb24pIG1fYXJnVmVjLmVsZW1lbnRBdChuKTsKLSAgICBlbHNlCi0gICAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIG51bWJlciBvZiBhcmd1bWVudHMgdGhhdCB3ZXJlIHBhc3NlZAotICAgKiBpbnRvIHRoaXMgZXh0ZW5zaW9uIGZ1bmN0aW9uLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBudW1iZXIgb2YgYXJndW1lbnRzLgotICAgKi8KLSAgcHVibGljIGludCBnZXRBcmdDb3VudCgpIHsKLSAgICByZXR1cm4gbV9hcmdWZWMuc2l6ZSgpOwotICB9Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIG5ldyBGdW5jRXh0RnVuY3Rpb24gYmFzZWQgb24gdGhlIHF1YWxpZmllZCBuYW1lIG9mIHRoZSBleHRlbnNpb24sCi0gICAqIGFuZCBhIHVuaXF1ZSBtZXRob2Qga2V5LgotICAgKgotICAgKiBAcGFyYW0gbmFtZXNwYWNlIFRoZSBuYW1lc3BhY2UgZm9yIHRoZSBleHRlbnNpb24gZnVuY3Rpb24sIHdoaWNoIHNob3VsZAotICAgKiAgICAgICAgICAgICAgICAgIG5vdCBub3JtYWxseSBiZSBudWxsIG9yIGVtcHR5LgotICAgKiBAcGFyYW0gZXh0ZW5zaW9uTmFtZSBUaGUgbG9jYWwgbmFtZSBvZiB0aGUgZXh0ZW5zaW9uLgotICAgKiBAcGFyYW0gbWV0aG9kS2V5IFVuaXF1ZSBtZXRob2Qga2V5LCB3aGljaCBpcyBwYXNzZWQgdG8KLSAgICogICAgICAgICAgICAgICAgICBFeHRlbnNpb25zVGFibGUjZXh0RnVuY3Rpb24gaW4gb3JkZXIgdG8gYWxsb3cgY2FjaGluZwotICAgKiAgICAgICAgICAgICAgICAgIG9mIHRoZSBtZXRob2QuCi0gICAqLwotICBwdWJsaWMgRnVuY0V4dEZ1bmN0aW9uKGphdmEubGFuZy5TdHJpbmcgbmFtZXNwYWNlLAotICAgICAgICAgICAgICAgICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgZXh0ZW5zaW9uTmFtZSwgT2JqZWN0IG1ldGhvZEtleSkKLSAgewotICAgIC8vdHJ5e3Rocm93IG5ldyBFeGNlcHRpb24oIkZ1bmNFeHRGdW5jdGlvbigpICIgKyBuYW1lc3BhY2UgKyAiICIgKyBleHRlbnNpb25OYW1lKTt9IGNhdGNoIChFeGNlcHRpb24gZSl7ZS5wcmludFN0YWNrVHJhY2UoKTt9Ci0gICAgbV9uYW1lc3BhY2UgPSBuYW1lc3BhY2U7Ci0gICAgbV9leHRlbnNpb25OYW1lID0gZXh0ZW5zaW9uTmFtZTsKLSAgICBtX21ldGhvZEtleSA9IG1ldGhvZEtleTsKLSAgfQotCi0gIC8qKgotICAgKiBFeGVjdXRlIHRoZSBmdW5jdGlvbi4gIFRoZSBmdW5jdGlvbiBtdXN0IHJldHVybgotICAgKiBhIHZhbGlkIG9iamVjdC4KLSAgICogQHBhcmFtIHhjdHh0IFRoZSBjdXJyZW50IGV4ZWN1dGlvbiBjb250ZXh0LgotICAgKiBAcmV0dXJuIEEgdmFsaWQgWE9iamVjdC4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBleGVjdXRlKFhQYXRoQ29udGV4dCB4Y3R4dCkKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgaWYgKHhjdHh0LmlzU2VjdXJlUHJvY2Vzc2luZygpKQotICAgICAgdGhyb3cgbmV3IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24oCi0gICAgICAgIFhQQVRITWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKAotICAgICAgICAgIFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfRVhURU5TSU9OX0ZVTkNUSU9OX0NBTk5PVF9CRV9JTlZPS0VELAotICAgICAgICAgIG5ldyBPYmplY3RbXSB7dG9TdHJpbmcoKX0pKTsKLQotICAgIFhPYmplY3QgcmVzdWx0OwotICAgIFZlY3RvciBhcmdWZWMgPSBuZXcgVmVjdG9yKCk7Ci0gICAgaW50IG5BcmdzID0gbV9hcmdWZWMuc2l6ZSgpOwotCi0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuQXJnczsgaSsrKQotICAgIHsKLSAgICAgIEV4cHJlc3Npb24gYXJnID0gKEV4cHJlc3Npb24pIG1fYXJnVmVjLmVsZW1lbnRBdChpKTsKLQotICAgICAgWE9iamVjdCB4b2JqID0gYXJnLmV4ZWN1dGUoeGN0eHQpOwotICAgICAgLyoKLSAgICAgICAqIFNob3VsZCBjYWNoZSB0aGUgYXJndW1lbnRzIGZvciBmdW5jOmZ1bmN0aW9uCi0gICAgICAgKi8KLSAgICAgIHhvYmouYWxsb3dEZXRhY2hUb1JlbGVhc2UoZmFsc2UpOwotICAgICAgYXJnVmVjLmFkZEVsZW1lbnQoeG9iaik7Ci0gICAgfQotICAgIC8vZG1sCi0gICAgRXh0ZW5zaW9uc1Byb3ZpZGVyIGV4dFByb3ZpZGVyID0gKEV4dGVuc2lvbnNQcm92aWRlcil4Y3R4dC5nZXRPd25lck9iamVjdCgpOwotICAgIE9iamVjdCB2YWwgPSBleHRQcm92aWRlci5leHRGdW5jdGlvbih0aGlzLCBhcmdWZWMpOwotCi0gICAgaWYgKG51bGwgIT0gdmFsKQotICAgIHsKLSAgICAgIHJlc3VsdCA9IFhPYmplY3QuY3JlYXRlKHZhbCwgeGN0eHQpOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgcmVzdWx0ID0gbmV3IFhOdWxsKCk7Ci0gICAgfQotCi0gICAgcmV0dXJuIHJlc3VsdDsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgYW4gYXJndW1lbnQgZXhwcmVzc2lvbiBmb3IgYSBmdW5jdGlvbi4gIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSB0aGUKLSAgICogWFBhdGggY29tcGlsZXIuCi0gICAqCi0gICAqIEBwYXJhbSBhcmcgbm9uLW51bGwgZXhwcmVzc2lvbiB0aGF0IHJlcHJlc2VudHMgdGhlIGFyZ3VtZW50LgotICAgKiBAcGFyYW0gYXJnTnVtIFRoZSBhcmd1bWVudCBudW1iZXIgaW5kZXguCi0gICAqCi0gICAqIEB0aHJvd3MgV3JvbmdOdW1iZXJBcmdzRXhjZXB0aW9uIElmIHRoZSBhcmdOdW0gcGFyYW1ldGVyIGlzIGJleW9uZCB3aGF0Ci0gICAqIGlzIHNwZWNpZmllZCBmb3IgdGhpcyBmdW5jdGlvbi4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldEFyZyhFeHByZXNzaW9uIGFyZywgaW50IGFyZ051bSkKLSAgICAgICAgICB0aHJvd3MgV3JvbmdOdW1iZXJBcmdzRXhjZXB0aW9uCi0gIHsKLSAgICBtX2FyZ1ZlYy5hZGRFbGVtZW50KGFyZyk7Ci0gICAgYXJnLmV4cHJTZXRQYXJlbnQodGhpcyk7Ci0gIH0KLQotICAvKioKLSAgICogQ2hlY2sgdGhhdCB0aGUgbnVtYmVyIG9mIGFyZ3VtZW50cyBwYXNzZWQgdG8gdGhpcyBmdW5jdGlvbiBpcyBjb3JyZWN0LgotICAgKgotICAgKgotICAgKiBAcGFyYW0gYXJnTnVtIFRoZSBudW1iZXIgb2YgYXJndW1lbnRzIHRoYXQgaXMgYmVpbmcgcGFzc2VkIHRvIHRoZSBmdW5jdGlvbi4KLSAgICoKLSAgICogQHRocm93cyBXcm9uZ051bWJlckFyZ3NFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGNoZWNrTnVtYmVyQXJncyhpbnQgYXJnTnVtKSB0aHJvd3MgV3JvbmdOdW1iZXJBcmdzRXhjZXB0aW9ue30KLQotCi0gIGNsYXNzIEFyZ0V4dE93bmVyIGltcGxlbWVudHMgRXhwcmVzc2lvbk93bmVyCi0gIHsKLQotICAgIEV4cHJlc3Npb24gbV9leHA7Ci0KLSAgICAgICAgQXJnRXh0T3duZXIoRXhwcmVzc2lvbiBleHApCi0gICAgICAgIHsKLSAgICAgICAgICAgICAgICBtX2V4cCA9IGV4cDsKLSAgICAgICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBFeHByZXNzaW9uT3duZXIjZ2V0RXhwcmVzc2lvbigpCi0gICAgICovCi0gICAgcHVibGljIEV4cHJlc3Npb24gZ2V0RXhwcmVzc2lvbigpCi0gICAgewotICAgICAgcmV0dXJuIG1fZXhwOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogQHNlZSBFeHByZXNzaW9uT3duZXIjc2V0RXhwcmVzc2lvbihFeHByZXNzaW9uKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEV4cHJlc3Npb24oRXhwcmVzc2lvbiBleHApCi0gICAgewotICAgICAgICBleHAuZXhwclNldFBhcmVudChGdW5jRXh0RnVuY3Rpb24udGhpcyk7Ci0gICAgICAgIG1fZXhwID0gZXhwOwotICAgIH0KLSAgfQotCi0KLSAgLyoqCi0gICAqIENhbGwgdGhlIHZpc2l0b3JzIGZvciB0aGUgZnVuY3Rpb24gYXJndW1lbnRzLgotICAgKi8KLSAgcHVibGljIHZvaWQgY2FsbEFyZ1Zpc2l0b3JzKFhQYXRoVmlzaXRvciB2aXNpdG9yKQotICB7Ci0gICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1fYXJnVmVjLnNpemUoKTsgaSsrKQotICAgICAgewotICAgICAgICAgRXhwcmVzc2lvbiBleHAgPSAoRXhwcmVzc2lvbiltX2FyZ1ZlYy5lbGVtZW50QXQoaSk7Ci0gICAgICAgICBleHAuY2FsbFZpc2l0b3JzKG5ldyBBcmdFeHRPd25lcihleHApLCB2aXNpdG9yKTsKLSAgICAgIH0KLQotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgcGFyZW50IG5vZGUuCi0gICAqIEZvciBhbiBleHRlbnNpb24gZnVuY3Rpb24sIHdlIGFsc28gbmVlZCB0byBzZXQgdGhlIHBhcmVudAotICAgKiBub2RlIGZvciBhbGwgYXJndW1lbnQgZXhwcmVzc2lvbnMuCi0gICAqCi0gICAqIEBwYXJhbSBuIFRoZSBwYXJlbnQgbm9kZQotICAgKi8KLSAgcHVibGljIHZvaWQgZXhwclNldFBhcmVudChFeHByZXNzaW9uTm9kZSBuKQotICB7Ci0KLSAgICBzdXBlci5leHByU2V0UGFyZW50KG4pOwotCi0gICAgaW50IG5BcmdzID0gbV9hcmdWZWMuc2l6ZSgpOwotCi0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuQXJnczsgaSsrKQotICAgIHsKLSAgICAgIEV4cHJlc3Npb24gYXJnID0gKEV4cHJlc3Npb24pIG1fYXJnVmVjLmVsZW1lbnRBdChpKTsKLQotICAgICAgYXJnLmV4cHJTZXRQYXJlbnQobik7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdHMgYW5kIHRocm93cyBhIFdyb25nTnVtYmVyQXJnRXhjZXB0aW9uIHdpdGggdGhlIGFwcHJvcHJpYXRlCi0gICAqIG1lc3NhZ2UgZm9yIHRoaXMgZnVuY3Rpb24gb2JqZWN0LiAgVGhpcyBjbGFzcyBzdXBwb3J0cyBhbiBhcmJpdHJhcnkKLSAgICogbnVtYmVyIG9mIGFyZ3VtZW50cywgc28gdGhpcyBtZXRob2QgbXVzdCBuZXZlciBiZSBjYWxsZWQuCi0gICAqCi0gICAqIEB0aHJvd3MgV3JvbmdOdW1iZXJBcmdzRXhjZXB0aW9uCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCByZXBvcnRXcm9uZ051bWJlckFyZ3MoKSB0aHJvd3MgV3JvbmdOdW1iZXJBcmdzRXhjZXB0aW9uIHsKLSAgICBTdHJpbmcgZk1zZyA9IFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZSgKLSAgICAgICAgWFBBVEhFcnJvclJlc291cmNlcy5FUl9JTkNPUlJFQ1RfUFJPR1JBTU1FUl9BU1NFUlRJT04sCi0gICAgICAgIG5ldyBPYmplY3RbXXsgIlByb2dyYW1tZXIncyBhc3NlcnRpb246ICB0aGUgbWV0aG9kIEZ1bmN0aW9uTXVsdGlBcmdzLnJlcG9ydFdyb25nTnVtYmVyQXJncygpIHNob3VsZCBuZXZlciBiZSBjYWxsZWQuIiB9KTsKLQotICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGZNc2cpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgbmFtZSBvZiB0aGUgZXh0ZXNpb24gZnVuY3Rpb24gaW4gc3RyaW5nIGZvcm1hdAotICAgKi8KLSAgcHVibGljIFN0cmluZyB0b1N0cmluZygpCi0gIHsKLSAgICBpZiAobV9uYW1lc3BhY2UgIT0gbnVsbCAmJiBtX25hbWVzcGFjZS5sZW5ndGgoKSA+IDApCi0gICAgICByZXR1cm4gInsiICsgbV9uYW1lc3BhY2UgKyAifSIgKyBtX2V4dGVuc2lvbk5hbWU7Ci0gICAgZWxzZQotICAgICAgcmV0dXJuIG1fZXh0ZW5zaW9uTmFtZTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9mdW5jdGlvbnMvRnVuY0V4dEZ1bmN0aW9uQXZhaWxhYmxlLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2Z1bmN0aW9ucy9GdW5jRXh0RnVuY3Rpb25BdmFpbGFibGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZjQ3NDkwMS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2Z1bmN0aW9ucy9GdW5jRXh0RnVuY3Rpb25BdmFpbGFibGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEwNiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBGdW5jRXh0RnVuY3Rpb25BdmFpbGFibGUuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNCAyMDowNTowOCBqZWZmc3V0dG9yIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmZ1bmN0aW9uczsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC50ZW1wbGF0ZXMuQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5FeHRlbnNpb25zUHJvdmlkZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoQ29udGV4dDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuY29tcGlsZXIuRnVuY3Rpb25UYWJsZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YQm9vbGVhbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YT2JqZWN0OwotCi0vKioKLSAqIEV4ZWN1dGUgdGhlIEV4dEZ1bmN0aW9uQXZhaWxhYmxlKCkgZnVuY3Rpb24uCi0gKiBAeHNsLnVzYWdlIGFkdmFuY2VkCi0gKi8KLXB1YmxpYyBjbGFzcyBGdW5jRXh0RnVuY3Rpb25BdmFpbGFibGUgZXh0ZW5kcyBGdW5jdGlvbk9uZUFyZwotewotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA1MTE4ODE0MzE0OTE4NTkyMjQxTDsKLQotICAgIHRyYW5zaWVudCBwcml2YXRlIEZ1bmN0aW9uVGFibGUgbV9mdW5jdGlvblRhYmxlID0gbnVsbDsKLQotICAvKioKLSAgICogRXhlY3V0ZSB0aGUgZnVuY3Rpb24uICBUaGUgZnVuY3Rpb24gbXVzdCByZXR1cm4KLSAgICogYSB2YWxpZCBvYmplY3QuCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgY3VycmVudCBleGVjdXRpb24gY29udGV4dC4KLSAgICogQHJldHVybiBBIHZhbGlkIFhPYmplY3QuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFhPYmplY3QgZXhlY3V0ZShYUGF0aENvbnRleHQgeGN0eHQpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIFN0cmluZyBwcmVmaXg7Ci0gICAgU3RyaW5nIG5hbWVzcGFjZTsKLSAgICBTdHJpbmcgbWV0aE5hbWU7Ci0KLSAgICBTdHJpbmcgZnVsbE5hbWUgPSBtX2FyZzAuZXhlY3V0ZSh4Y3R4dCkuc3RyKCk7Ci0gICAgaW50IGluZGV4T2ZOU1NlcCA9IGZ1bGxOYW1lLmluZGV4T2YoJzonKTsKLQotICAgIGlmIChpbmRleE9mTlNTZXAgPCAwKQotICAgIHsKLSAgICAgIHByZWZpeCA9ICIiOwotICAgICAgbmFtZXNwYWNlID0gQ29uc3RhbnRzLlNfWFNMTkFNRVNQQUNFVVJMOwotICAgICAgbWV0aE5hbWUgPSBmdWxsTmFtZTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIHByZWZpeCA9IGZ1bGxOYW1lLnN1YnN0cmluZygwLCBpbmRleE9mTlNTZXApOwotICAgICAgbmFtZXNwYWNlID0geGN0eHQuZ2V0TmFtZXNwYWNlQ29udGV4dCgpLmdldE5hbWVzcGFjZUZvclByZWZpeChwcmVmaXgpOwotICAgICAgaWYgKG51bGwgPT0gbmFtZXNwYWNlKQotICAgICAgICByZXR1cm4gWEJvb2xlYW4uU19GQUxTRTsKLSAgICAgICAgbWV0aE5hbWUgPSBmdWxsTmFtZS5zdWJzdHJpbmcoaW5kZXhPZk5TU2VwICsgMSk7Ci0gICAgfQotCi0gICAgaWYgKG5hbWVzcGFjZS5lcXVhbHMoQ29uc3RhbnRzLlNfWFNMTkFNRVNQQUNFVVJMKSkKLSAgICB7Ci0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgaWYgKG51bGwgPT0gbV9mdW5jdGlvblRhYmxlKSBtX2Z1bmN0aW9uVGFibGUgPSBuZXcgRnVuY3Rpb25UYWJsZSgpOwotICAgICAgICByZXR1cm4gbV9mdW5jdGlvblRhYmxlLmZ1bmN0aW9uQXZhaWxhYmxlKG1ldGhOYW1lKSA/IFhCb29sZWFuLlNfVFJVRSA6IFhCb29sZWFuLlNfRkFMU0U7Ci0gICAgICB9Ci0gICAgICBjYXRjaCAoRXhjZXB0aW9uIGUpCi0gICAgICB7Ci0gICAgICAgIHJldHVybiBYQm9vbGVhbi5TX0ZBTFNFOwotICAgICAgfQotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgLy9kbWwKLSAgICAgIEV4dGVuc2lvbnNQcm92aWRlciBleHRQcm92aWRlciA9IChFeHRlbnNpb25zUHJvdmlkZXIpeGN0eHQuZ2V0T3duZXJPYmplY3QoKTsKLSAgICAgIHJldHVybiBleHRQcm92aWRlci5mdW5jdGlvbkF2YWlsYWJsZShuYW1lc3BhY2UsIG1ldGhOYW1lKQotICAgICAgICAgICAgID8gWEJvb2xlYW4uU19UUlVFIDogWEJvb2xlYW4uU19GQUxTRTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogVGhlIGZ1bmN0aW9uIHRhYmxlIGlzIGFuIGluc3RhbmNlIGZpZWxkLiBJbiBvcmRlciB0byBhY2Nlc3MgdGhpcyBpbnN0YW5jZQotICAgKiBmaWVsZCBkdXJpbmcgZXZhbHVhdGlvbiwgdGhpcyBtZXRob2QgaXMgY2FsbGVkIGF0IGNvbXBpbGF0aW9uIHRpbWUgdG8KLSAgICogaW5zZXJ0IGZ1bmN0aW9uIHRhYmxlIGluZm9ybWF0aW9uIGZvciBsYXRlciB1c2FnZS4gSXQgc2hvdWxkIG9ubHkgYmUgdXNlZAotICAgKiBkdXJpbmcgY29tcGlsaW5nIG9mIFhQYXRoIGV4cHJlc3Npb25zLgotICAgKiBAcGFyYW0gYVRhYmxlIGFuIGluc3RhbmNlIG9mIHRoZSBmdW5jdGlvbiB0YWJsZQotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0RnVuY3Rpb25UYWJsZShGdW5jdGlvblRhYmxlIGFUYWJsZSl7Ci0gICAgICAgICAgbV9mdW5jdGlvblRhYmxlID0gYVRhYmxlOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2Z1bmN0aW9ucy9GdW5jRmFsc2UuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvZnVuY3Rpb25zL0Z1bmNGYWxzZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3ZjFjOTc1Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvZnVuY3Rpb25zL0Z1bmNGYWxzZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTggKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRnVuY0ZhbHNlLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTQgMjA6MTg6NDYgamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5mdW5jdGlvbnM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuWFBhdGhDb250ZXh0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhCb29sZWFuOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhPYmplY3Q7Ci0KLS8qKgotICogRXhlY3V0ZSB0aGUgRmFsc2UoKSBmdW5jdGlvbi4KLSAqIEB4c2wudXNhZ2UgYWR2YW5jZWQKLSAqLwotcHVibGljIGNsYXNzIEZ1bmNGYWxzZSBleHRlbmRzIEZ1bmN0aW9uCi17Ci0gICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDYxNTA5MTgwNjI3NTk3Njk4ODdMOwotCi0gIC8qKgotICAgKiBFeGVjdXRlIHRoZSBmdW5jdGlvbi4gIFRoZSBmdW5jdGlvbiBtdXN0IHJldHVybgotICAgKiBhIHZhbGlkIG9iamVjdC4KLSAgICogQHBhcmFtIHhjdHh0IFRoZSBjdXJyZW50IGV4ZWN1dGlvbiBjb250ZXh0LgotICAgKiBAcmV0dXJuIEEgdmFsaWQgWE9iamVjdC4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBleGVjdXRlKFhQYXRoQ29udGV4dCB4Y3R4dCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHJldHVybiBYQm9vbGVhbi5TX0ZBTFNFOwotICB9Ci0KLSAgLyoqCi0gICAqIE5vIGFyZ3VtZW50cyB0byBwcm9jZXNzLCBzbyB0aGlzIGRvZXMgbm90aGluZy4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGZpeHVwVmFyaWFibGVzKGphdmEudXRpbC5WZWN0b3IgdmFycywgaW50IGdsb2JhbHNTaXplKQotICB7Ci0gICAgLy8gbm8tb3AKLSAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2Z1bmN0aW9ucy9GdW5jRmxvb3IuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvZnVuY3Rpb25zL0Z1bmNGbG9vci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxZTljMzM1Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvZnVuY3Rpb25zL0Z1bmNGbG9vci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDkgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRnVuY0Zsb29yLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTQgMjA6MTg6NDIgamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5mdW5jdGlvbnM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuWFBhdGhDb250ZXh0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhOdW1iZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWE9iamVjdDsKLQotLyoqCi0gKiBFeGVjdXRlIHRoZSBGbG9vcigpIGZ1bmN0aW9uLgotICogQHhzbC51c2FnZSBhZHZhbmNlZAotICovCi1wdWJsaWMgY2xhc3MgRnVuY0Zsb29yIGV4dGVuZHMgRnVuY3Rpb25PbmVBcmcKLXsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMjMyNjc1MjIzMzIzNjMwOTI2NUw7Ci0KLSAgLyoqCi0gICAqIEV4ZWN1dGUgdGhlIGZ1bmN0aW9uLiAgVGhlIGZ1bmN0aW9uIG11c3QgcmV0dXJuCi0gICAqIGEgdmFsaWQgb2JqZWN0LgotICAgKiBAcGFyYW0geGN0eHQgVGhlIGN1cnJlbnQgZXhlY3V0aW9uIGNvbnRleHQuCi0gICAqIEByZXR1cm4gQSB2YWxpZCBYT2JqZWN0LgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IGV4ZWN1dGUoWFBhdGhDb250ZXh0IHhjdHh0KSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIG5ldyBYTnVtYmVyKGphdmEubGFuZy5NYXRoLmZsb29yKG1fYXJnMC5leGVjdXRlKHhjdHh0KS5udW0oKSkpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2Z1bmN0aW9ucy9GdW5jR2VuZXJhdGVJZC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9mdW5jdGlvbnMvRnVuY0dlbmVyYXRlSWQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYzA2ZWE4Mi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2Z1bmN0aW9ucy9GdW5jR2VuZXJhdGVJZC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNjQgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRnVuY0dlbmVyYXRlSWQuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNCAyMDoxODo0NSBqZWZmc3V0dG9yIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmZ1bmN0aW9uczsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuWFBhdGhDb250ZXh0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhPYmplY3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWFN0cmluZzsKLQotLyoqCi0gKiBFeGVjdXRlIHRoZSBHZW5lcmF0ZUlkKCkgZnVuY3Rpb24uCi0gKiBAeHNsLnVzYWdlIGFkdmFuY2VkCi0gKi8KLXB1YmxpYyBjbGFzcyBGdW5jR2VuZXJhdGVJZCBleHRlbmRzIEZ1bmN0aW9uRGVmMUFyZwotewotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA5NzM1NDQ4NDIwOTE3MjQyNzNMOwotCi0gIC8qKgotICAgKiBFeGVjdXRlIHRoZSBmdW5jdGlvbi4gIFRoZSBmdW5jdGlvbiBtdXN0IHJldHVybgotICAgKiBhIHZhbGlkIG9iamVjdC4KLSAgICogQHBhcmFtIHhjdHh0IFRoZSBjdXJyZW50IGV4ZWN1dGlvbiBjb250ZXh0LgotICAgKiBAcmV0dXJuIEEgdmFsaWQgWE9iamVjdC4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBleGVjdXRlKFhQYXRoQ29udGV4dCB4Y3R4dCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaW50IHdoaWNoID0gZ2V0QXJnMEFzTm9kZSh4Y3R4dCk7Ci0KLSAgICBpZiAoRFRNLk5VTEwgIT0gd2hpY2gpCi0gICAgewotICAgICAgLy8gTm90ZSB0aGF0IHRoaXMgaXMgYSBkaWZmZXJlbnQgdmFsdWUgdGhhbiBpbiBwcmV2aW91cyByZWxlYXNlcwotICAgICAgLy8gb2YgWGFsYW4uIEl0J3Mgc2Vuc2l0aXZlIHRvIHRoZSBleGFjdCBlbmNvZGluZyBvZiB0aGUgbm9kZQotICAgICAgLy8gaGFuZGxlIGFueXdheSwgc28gZmlnaHRpbmcgdG8gbWFpbnRhaW4gYmFja3dhcmQgY29tcGF0YWJpbGl0eQotICAgICAgLy8gcmVhbGx5IGRpZG4ndCBtYWtlIHNlbnNlOyBpdCBtYXkgY2hhbmdlIGFnYWluIGFzIHdlIGNvbnRpbnVlCi0gICAgICAvLyB0byBleHBlcmltZW50IHdpdGggYmFsYW5jaW5nIGRvY3VtZW50IGFuZCBub2RlIG51bWJlcnMgd2l0aGluCi0gICAgICAvLyB0aGF0IHZhbHVlLgotICAgICAgcmV0dXJuIG5ldyBYU3RyaW5nKCJOIiArIEludGVnZXIudG9IZXhTdHJpbmcod2hpY2gpLnRvVXBwZXJDYXNlKCkpOwotICAgIH0KLSAgICBlbHNlCi0gICAgICByZXR1cm4gWFN0cmluZy5FTVBUWVNUUklORzsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9mdW5jdGlvbnMvRnVuY0lkLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2Z1bmN0aW9ucy9GdW5jSWQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMTBjZmE2OC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2Z1bmN0aW9ucy9GdW5jSWQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE1MyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBGdW5jSWQuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNCAyMDoxODo0NSBqZWZmc3V0dG9yIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmZ1bmN0aW9uczsKLQotaW1wb3J0IGphdmEudXRpbC5TdHJpbmdUb2tlbml6ZXI7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE07Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNSXRlcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5TdHJpbmdWZWN0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLk5vZGVTZXREVE07Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoQ29udGV4dDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YTm9kZVNldDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YT2JqZWN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5yZXMuWFBBVEhFcnJvclJlc291cmNlczsKLQotLyoqCi0gKiBFeGVjdXRlIHRoZSBJZCgpIGZ1bmN0aW9uLgotICogQHhzbC51c2FnZSBhZHZhbmNlZAotICovCi1wdWJsaWMgY2xhc3MgRnVuY0lkIGV4dGVuZHMgRnVuY3Rpb25PbmVBcmcKLXsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gODkzMDU3Mzk2NjE0MzU2NzMxMEw7Ci0KLSAgLyoqCi0gICAqIEZpbGwgaW4gYSBsaXN0IHdpdGggbm9kZXMgdGhhdCBtYXRjaCBhIHNwYWNlIGRlbGltaXRlZCBsaXN0IGlmIElECi0gICAqIElEIHJlZmVyZW5jZXMuCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgcnVudGltZSBYUGF0aCBjb250ZXh0LgotICAgKiBAcGFyYW0gZG9jQ29udGV4dCBUaGUgZG9jdW1lbnQgd2hlcmUgdGhlIG5vZGVzIGFyZSBiZWluZyBsb29rZWQgZm9yLgotICAgKiBAcGFyYW0gcmVmdmFsIEEgc3BhY2UgZGVsaW1pdGVkIGxpc3Qgb2YgSUQgcmVmZXJlbmNlcy4KLSAgICogQHBhcmFtIHVzZWRyZWZzIExpc3Qgb2YgcmVmZXJlbmNlcyBmb3Igd2hpY2ggbm9kZXMgd2VyZSBmb3VuZC4KLSAgICogQHBhcmFtIG5vZGVTZXQgTm9kZSBzZXQgd2hlcmUgdGhlIG5vZGVzIHdpbGwgYmUgYWRkZWQgdG8uCi0gICAqIEBwYXJhbSBtYXlCZU1vcmUgdHJ1ZSBpZiB0aGVyZSBpcyBhbm90aGVyIHNldCBvZiBub2RlcyB0byBiZSBsb29rZWQgZm9yLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSB1c2VkcmVmcyB2YWx1ZS4KLSAgICovCi0gIHByaXZhdGUgU3RyaW5nVmVjdG9yIGdldE5vZGVzQnlJRChYUGF0aENvbnRleHQgeGN0eHQsIGludCBkb2NDb250ZXh0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHJlZnZhbCwgU3RyaW5nVmVjdG9yIHVzZWRyZWZzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTm9kZVNldERUTSBub2RlU2V0LCBib29sZWFuIG1heUJlTW9yZSkKLSAgewotCi0gICAgaWYgKG51bGwgIT0gcmVmdmFsKQotICAgIHsKLSAgICAgIFN0cmluZyByZWYgPSBudWxsOwotLy8gICAgICBET01IZWxwZXIgZGggPSB4Y3R4dC5nZXRET01IZWxwZXIoKTsKLSAgICAgIFN0cmluZ1Rva2VuaXplciB0b2tlbml6ZXIgPSBuZXcgU3RyaW5nVG9rZW5pemVyKHJlZnZhbCk7Ci0gICAgICBib29sZWFuIGhhc01vcmUgPSB0b2tlbml6ZXIuaGFzTW9yZVRva2VucygpOwotICAgICAgRFRNIGR0bSA9IHhjdHh0LmdldERUTShkb2NDb250ZXh0KTsKLQotICAgICAgd2hpbGUgKGhhc01vcmUpCi0gICAgICB7Ci0gICAgICAgIHJlZiA9IHRva2VuaXplci5uZXh0VG9rZW4oKTsKLSAgICAgICAgaGFzTW9yZSA9IHRva2VuaXplci5oYXNNb3JlVG9rZW5zKCk7Ci0KLSAgICAgICAgaWYgKChudWxsICE9IHVzZWRyZWZzKSAmJiB1c2VkcmVmcy5jb250YWlucyhyZWYpKQotICAgICAgICB7Ci0gICAgICAgICAgcmVmID0gbnVsbDsKLQotICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICB9Ci0KLSAgICAgICAgaW50IG5vZGUgPSBkdG0uZ2V0RWxlbWVudEJ5SWQocmVmKTsKLQotICAgICAgICBpZiAoRFRNLk5VTEwgIT0gbm9kZSkKLSAgICAgICAgICBub2RlU2V0LmFkZE5vZGVJbkRvY09yZGVyKG5vZGUsIHhjdHh0KTsKLQotICAgICAgICBpZiAoKG51bGwgIT0gcmVmKSAmJiAoaGFzTW9yZSB8fCBtYXlCZU1vcmUpKQotICAgICAgICB7Ci0gICAgICAgICAgaWYgKG51bGwgPT0gdXNlZHJlZnMpCi0gICAgICAgICAgICB1c2VkcmVmcyA9IG5ldyBTdHJpbmdWZWN0b3IoKTsKLQotICAgICAgICAgIHVzZWRyZWZzLmFkZEVsZW1lbnQocmVmKTsKLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiB1c2VkcmVmczsKLSAgfQotCi0gIC8qKgotICAgKiBFeGVjdXRlIHRoZSBmdW5jdGlvbi4gIFRoZSBmdW5jdGlvbiBtdXN0IHJldHVybgotICAgKiBhIHZhbGlkIG9iamVjdC4KLSAgICogQHBhcmFtIHhjdHh0IFRoZSBjdXJyZW50IGV4ZWN1dGlvbiBjb250ZXh0LgotICAgKiBAcmV0dXJuIEEgdmFsaWQgWE9iamVjdC4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBleGVjdXRlKFhQYXRoQ29udGV4dCB4Y3R4dCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaW50IGNvbnRleHQgPSB4Y3R4dC5nZXRDdXJyZW50Tm9kZSgpOwotICAgIERUTSBkdG0gPSB4Y3R4dC5nZXREVE0oY29udGV4dCk7Ci0gICAgaW50IGRvY0NvbnRleHQgPSBkdG0uZ2V0RG9jdW1lbnQoKTsKLQotICAgIGlmIChEVE0uTlVMTCA9PSBkb2NDb250ZXh0KQotICAgICAgZXJyb3IoeGN0eHQsIFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfQ09OVEVYVF9IQVNfTk9fT1dORVJET0MsIG51bGwpOwotCi0gICAgWE9iamVjdCBhcmcgPSBtX2FyZzAuZXhlY3V0ZSh4Y3R4dCk7Ci0gICAgaW50IGFyZ1R5cGUgPSBhcmcuZ2V0VHlwZSgpOwotICAgIFhOb2RlU2V0IG5vZGVzID0gbmV3IFhOb2RlU2V0KHhjdHh0LmdldERUTU1hbmFnZXIoKSk7Ci0gICAgTm9kZVNldERUTSBub2RlU2V0ID0gbm9kZXMubXV0YWJsZU5vZGVzZXQoKTsKLQotICAgIGlmIChYT2JqZWN0LkNMQVNTX05PREVTRVQgPT0gYXJnVHlwZSkKLSAgICB7Ci0gICAgICBEVE1JdGVyYXRvciBuaSA9IGFyZy5pdGVyKCk7Ci0gICAgICBTdHJpbmdWZWN0b3IgdXNlZHJlZnMgPSBudWxsOwotICAgICAgaW50IHBvcyA9IG5pLm5leHROb2RlKCk7Ci0KLSAgICAgIHdoaWxlIChEVE0uTlVMTCAhPSBwb3MpCi0gICAgICB7Ci0gICAgICAgIERUTSBuZHRtID0gbmkuZ2V0RFRNKHBvcyk7Ci0gICAgICAgIFN0cmluZyByZWZ2YWwgPSBuZHRtLmdldFN0cmluZ1ZhbHVlKHBvcykudG9TdHJpbmcoKTsKLQotICAgICAgICBwb3MgPSBuaS5uZXh0Tm9kZSgpOwotICAgICAgICB1c2VkcmVmcyA9IGdldE5vZGVzQnlJRCh4Y3R4dCwgZG9jQ29udGV4dCwgcmVmdmFsLCB1c2VkcmVmcywgbm9kZVNldCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFRNLk5VTEwgIT0gcG9zKTsKLSAgICAgIH0KLSAgICAgIC8vIG5pLmRldGFjaCgpOwotICAgIH0KLSAgICBlbHNlIGlmIChYT2JqZWN0LkNMQVNTX05VTEwgPT0gYXJnVHlwZSkKLSAgICB7Ci0gICAgICByZXR1cm4gbm9kZXM7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBTdHJpbmcgcmVmdmFsID0gYXJnLnN0cigpOwotCi0gICAgICBnZXROb2Rlc0J5SUQoeGN0eHQsIGRvY0NvbnRleHQsIHJlZnZhbCwgbnVsbCwgbm9kZVNldCwgZmFsc2UpOwotICAgIH0KLQotICAgIHJldHVybiBub2RlczsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9mdW5jdGlvbnMvRnVuY0xhbmcuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvZnVuY3Rpb25zL0Z1bmNMYW5nLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDg2OWIwOGYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9mdW5jdGlvbnMvRnVuY0xhbmcuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDg0ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IEZ1bmNMYW5nLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTQgMjA6MTg6NDQgamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5mdW5jdGlvbnM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE07Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoQ29udGV4dDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YQm9vbGVhbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YT2JqZWN0OwotCi0vKioKLSAqIEV4ZWN1dGUgdGhlIExhbmcoKSBmdW5jdGlvbi4KLSAqIEB4c2wudXNhZ2UgYWR2YW5jZWQKLSAqLwotcHVibGljIGNsYXNzIEZ1bmNMYW5nIGV4dGVuZHMgRnVuY3Rpb25PbmVBcmcKLXsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTc4Njg3MDUxMzkzNTQ4NzIxODVMOwotCi0gIC8qKgotICAgKiBFeGVjdXRlIHRoZSBmdW5jdGlvbi4gIFRoZSBmdW5jdGlvbiBtdXN0IHJldHVybgotICAgKiBhIHZhbGlkIG9iamVjdC4KLSAgICogQHBhcmFtIHhjdHh0IFRoZSBjdXJyZW50IGV4ZWN1dGlvbiBjb250ZXh0LgotICAgKiBAcmV0dXJuIEEgdmFsaWQgWE9iamVjdC4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBleGVjdXRlKFhQYXRoQ29udGV4dCB4Y3R4dCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgU3RyaW5nIGxhbmcgPSBtX2FyZzAuZXhlY3V0ZSh4Y3R4dCkuc3RyKCk7Ci0gICAgaW50IHBhcmVudCA9IHhjdHh0LmdldEN1cnJlbnROb2RlKCk7Ci0gICAgYm9vbGVhbiBpc0xhbmcgPSBmYWxzZTsKLSAgICBEVE0gZHRtID0geGN0eHQuZ2V0RFRNKHBhcmVudCk7Ci0KLSAgICB3aGlsZSAoRFRNLk5VTEwgIT0gcGFyZW50KQotICAgIHsKLSAgICAgIGlmIChEVE0uRUxFTUVOVF9OT0RFID09IGR0bS5nZXROb2RlVHlwZShwYXJlbnQpKQotICAgICAgewotICAgICAgICBpbnQgbGFuZ0F0dHIgPSBkdG0uZ2V0QXR0cmlidXRlTm9kZShwYXJlbnQsICJodHRwOi8vd3d3LnczLm9yZy9YTUwvMTk5OC9uYW1lc3BhY2UiLCAibGFuZyIpOwotCi0gICAgICAgIGlmIChEVE0uTlVMTCAhPSBsYW5nQXR0cikKLSAgICAgICAgewotICAgICAgICAgIFN0cmluZyBsYW5nVmFsID0gZHRtLmdldE5vZGVWYWx1ZShsYW5nQXR0cik7Ci0gICAgICAgICAgLy8gJU9QVCUKLSAgICAgICAgICBpZiAobGFuZ1ZhbC50b0xvd2VyQ2FzZSgpLnN0YXJ0c1dpdGgobGFuZy50b0xvd2VyQ2FzZSgpKSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBpbnQgdmFsTGVuID0gbGFuZy5sZW5ndGgoKTsKLQotICAgICAgICAgICAgaWYgKChsYW5nVmFsLmxlbmd0aCgpID09IHZhbExlbikKLSAgICAgICAgICAgICAgICAgICAgfHwgKGxhbmdWYWwuY2hhckF0KHZhbExlbikgPT0gJy0nKSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgaXNMYW5nID0gdHJ1ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICB9Ci0KLSAgICAgICAgICBicmVhazsKLSAgICAgICAgfQotICAgICAgfQotCi0gICAgICBwYXJlbnQgPSBkdG0uZ2V0UGFyZW50KHBhcmVudCk7Ci0gICAgfQotCi0gICAgcmV0dXJuIGlzTGFuZyA/IFhCb29sZWFuLlNfVFJVRSA6IFhCb29sZWFuLlNfRkFMU0U7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvZnVuY3Rpb25zL0Z1bmNMYXN0LmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2Z1bmN0aW9ucy9GdW5jTGFzdC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA5MTcyODU1Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvZnVuY3Rpb25zL0Z1bmNMYXN0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMDggKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRnVuY0xhc3QuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNCAyMDoxODo0MyBqZWZmc3V0dG9yIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmZ1bmN0aW9uczsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTUl0ZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5YUGF0aENvbnRleHQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmF4ZXMuU3ViQ29udGV4dExpc3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmNvbXBpbGVyLkNvbXBpbGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhOdW1iZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWE9iamVjdDsKLQotCi0vKioKLSAqIEV4ZWN1dGUgdGhlIExhc3QoKSBmdW5jdGlvbi4KLSAqIEB4c2wudXNhZ2UgYWR2YW5jZWQKLSAqLwotcHVibGljIGNsYXNzIEZ1bmNMYXN0IGV4dGVuZHMgRnVuY3Rpb24KLXsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gOTIwNTgxMjQwMzA4NTQzMjk0M0w7Ci0KLSAgcHJpdmF0ZSBib29sZWFuIG1faXNUb3BMZXZlbDsKLQotICAvKioKLSAgICogRmlndXJlIG91dCBpZiB3ZSdyZSBleGVjdXRpbmcgYSB0b3BsZXZlbCBleHByZXNzaW9uLgotICAgKiBJZiBzbywgd2UgY2FuJ3QgYmUgaW5zaWRlIG9mIGEgcHJlZGljYXRlLgotICAgKi8KLSAgcHVibGljIHZvaWQgcG9zdENvbXBpbGVTdGVwKENvbXBpbGVyIGNvbXBpbGVyKQotICB7Ci0gICAgbV9pc1RvcExldmVsID0gY29tcGlsZXIuZ2V0TG9jYXRpb25QYXRoRGVwdGgoKSA9PSAtMTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIHBvc2l0aW9uIGluIHRoZSBjdXJyZW50IGNvbnRleHQgbm9kZSBsaXN0LgotICAgKgotICAgKiBAcGFyYW0geGN0eHQgbm9uLW51bGwgcmVmZXJlbmNlIHRvIFhQYXRoIHJ1bnRpbWUgY29udGV4dC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgbnVtYmVyIG9mIG5vZGVzIGluIHRoZSBsaXN0LgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0Q291bnRPZkNvbnRleHROb2RlTGlzdChYUGF0aENvbnRleHQgeGN0eHQpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgLy8gYXNzZXJ0KG51bGwgIT0gbV9jb250ZXh0Tm9kZUxpc3QsICJtX2NvbnRleHROb2RlTGlzdCBtdXN0IGJlIG5vbi1udWxsIik7Ci0gICAgLy8gSWYgd2UncmUgaW4gYSBwcmVkaWNhdGUsIHRoZW4gdGhpcyB3aWxsIHJldHVybiBub24tbnVsbC4KLSAgICBTdWJDb250ZXh0TGlzdCBpdGVyID0gbV9pc1RvcExldmVsID8gbnVsbCA6IHhjdHh0LmdldFN1YkNvbnRleHRMaXN0KCk7Ci0KLSAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIml0ZXI6ICIraXRlcik7Ci0gICAgaWYgKG51bGwgIT0gaXRlcikKLSAgICAgIHJldHVybiBpdGVyLmdldExhc3RQb3MoeGN0eHQpOwotCi0gICAgRFRNSXRlcmF0b3IgY25sID0geGN0eHQuZ2V0Q29udGV4dE5vZGVMaXN0KCk7Ci0gICAgaW50IGNvdW50OwotICAgIGlmKG51bGwgIT0gY25sKQotICAgIHsKLSAgICAgIGNvdW50ID0gY25sLmdldExlbmd0aCgpOwotICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJjb3VudDogIitjb3VudCk7Ci0gICAgfQotICAgIGVsc2UKLSAgICAgIGNvdW50ID0gMDsKLSAgICByZXR1cm4gY291bnQ7Ci0gIH0KLQotICAvKioKLSAgICogRXhlY3V0ZSB0aGUgZnVuY3Rpb24uICBUaGUgZnVuY3Rpb24gbXVzdCByZXR1cm4KLSAgICogYSB2YWxpZCBvYmplY3QuCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgY3VycmVudCBleGVjdXRpb24gY29udGV4dC4KLSAgICogQHJldHVybiBBIHZhbGlkIFhPYmplY3QuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFhPYmplY3QgZXhlY3V0ZShYUGF0aENvbnRleHQgeGN0eHQpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICBYTnVtYmVyIHhudW0gPSBuZXcgWE51bWJlcigoZG91YmxlKSBnZXRDb3VudE9mQ29udGV4dE5vZGVMaXN0KHhjdHh0KSk7Ci0gICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJsYXN0OiAiK3hudW0ubnVtKCkpOwotICAgIHJldHVybiB4bnVtOwotICB9Ci0KLSAgLyoqCi0gICAqIE5vIGFyZ3VtZW50cyB0byBwcm9jZXNzLCBzbyB0aGlzIGRvZXMgbm90aGluZy4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGZpeHVwVmFyaWFibGVzKGphdmEudXRpbC5WZWN0b3IgdmFycywgaW50IGdsb2JhbHNTaXplKQotICB7Ci0gICAgLy8gbm8tb3AKLSAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2Z1bmN0aW9ucy9GdW5jTG9jYWxQYXJ0LmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2Z1bmN0aW9ucy9GdW5jTG9jYWxQYXJ0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGI0ZTFhOTcuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9mdW5jdGlvbnMvRnVuY0xvY2FsUGFydC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTkgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRnVuY0xvY2FsUGFydC5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE0IDIwOjE4OjQ0IGplZmZzdXR0b3IgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuZnVuY3Rpb25zOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5YUGF0aENvbnRleHQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWE9iamVjdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YU3RyaW5nOwotCi0vKioKLSAqIEV4ZWN1dGUgdGhlIExvY2FsUGFydCgpIGZ1bmN0aW9uLgotICogQHhzbC51c2FnZSBhZHZhbmNlZAotICovCi1wdWJsaWMgY2xhc3MgRnVuY0xvY2FsUGFydCBleHRlbmRzIEZ1bmN0aW9uRGVmMUFyZwotewotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA3NTkxNzk4NzcwMzI1ODE0NzQ2TDsKLQotICAvKioKLSAgICogRXhlY3V0ZSB0aGUgZnVuY3Rpb24uICBUaGUgZnVuY3Rpb24gbXVzdCByZXR1cm4KLSAgICogYSB2YWxpZCBvYmplY3QuCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgY3VycmVudCBleGVjdXRpb24gY29udGV4dC4KLSAgICogQHJldHVybiBBIHZhbGlkIFhPYmplY3QuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFhPYmplY3QgZXhlY3V0ZShYUGF0aENvbnRleHQgeGN0eHQpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGludCBjb250ZXh0ID0gZ2V0QXJnMEFzTm9kZSh4Y3R4dCk7Ci0gICAgaWYoRFRNLk5VTEwgPT0gY29udGV4dCkKLSAgICAgIHJldHVybiBYU3RyaW5nLkVNUFRZU1RSSU5HOwotICAgIERUTSBkdG0gPSB4Y3R4dC5nZXREVE0oY29udGV4dCk7Ci0gICAgU3RyaW5nIHMgPSAoY29udGV4dCAhPSBEVE0uTlVMTCkgPyBkdG0uZ2V0TG9jYWxOYW1lKGNvbnRleHQpIDogIiI7Ci0gICAgaWYocy5zdGFydHNXaXRoKCIjIikgfHwgcy5lcXVhbHMoInhtbG5zIikpCi0gICAgICByZXR1cm4gWFN0cmluZy5FTVBUWVNUUklORzsKLQotICAgIHJldHVybiBuZXcgWFN0cmluZyhzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9mdW5jdGlvbnMvRnVuY05hbWVzcGFjZS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9mdW5jdGlvbnMvRnVuY05hbWVzcGFjZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA5ZTg1ZTI2Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvZnVuY3Rpb25zL0Z1bmNOYW1lc3BhY2UuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDgwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IEZ1bmNOYW1lc3BhY2UuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNCAyMDoxODo0NiBqZWZmc3V0dG9yIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmZ1bmN0aW9uczsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuWFBhdGhDb250ZXh0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhPYmplY3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWFN0cmluZzsKLQotLyoqCi0gKiBFeGVjdXRlIHRoZSBOYW1lc3BhY2UoKSBmdW5jdGlvbi4KLSAqIEB4c2wudXNhZ2UgYWR2YW5jZWQKLSAqLwotcHVibGljIGNsYXNzIEZ1bmNOYW1lc3BhY2UgZXh0ZW5kcyBGdW5jdGlvbkRlZjFBcmcKLXsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTQ2OTU2NzQ1NjY3MjIzMjEyMzdMOwotCi0gIC8qKgotICAgKiBFeGVjdXRlIHRoZSBmdW5jdGlvbi4gIFRoZSBmdW5jdGlvbiBtdXN0IHJldHVybgotICAgKiBhIHZhbGlkIG9iamVjdC4KLSAgICogQHBhcmFtIHhjdHh0IFRoZSBjdXJyZW50IGV4ZWN1dGlvbiBjb250ZXh0LgotICAgKiBAcmV0dXJuIEEgdmFsaWQgWE9iamVjdC4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBleGVjdXRlKFhQYXRoQ29udGV4dCB4Y3R4dCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaW50IGNvbnRleHQgPSBnZXRBcmcwQXNOb2RlKHhjdHh0KTsKLQotICAgIFN0cmluZyBzOwotICAgIGlmKGNvbnRleHQgIT0gRFRNLk5VTEwpCi0gICAgewotICAgICAgRFRNIGR0bSA9IHhjdHh0LmdldERUTShjb250ZXh0KTsKLSAgICAgIGludCB0ID0gZHRtLmdldE5vZGVUeXBlKGNvbnRleHQpOwotICAgICAgaWYodCA9PSBEVE0uRUxFTUVOVF9OT0RFKQotICAgICAgewotICAgICAgICBzID0gZHRtLmdldE5hbWVzcGFjZVVSSShjb250ZXh0KTsKLSAgICAgIH0KLSAgICAgIGVsc2UgaWYodCA9PSBEVE0uQVRUUklCVVRFX05PREUpCi0gICAgICB7Ci0KLSAgICAgICAgLy8gVGhpcyBmdW5jdGlvbiBhbHdheXMgcmV0dXJucyBhbiBlbXB0eSBzdHJpbmcgZm9yIG5hbWVzcGFjZSBub2Rlcy4KLSAgICAgICAgLy8gV2UgY2hlY2sgZm9yIHRob3NlIGhlcmUuICBGaXggaW5zcGlyZWQgYnkgRGF2YW51bSBTcmluaXZhcy4KLQotICAgICAgICBzID0gZHRtLmdldE5vZGVOYW1lKGNvbnRleHQpOwotICAgICAgICBpZihzLnN0YXJ0c1dpdGgoInhtbG5zOiIpIHx8IHMuZXF1YWxzKCJ4bWxucyIpKQotICAgICAgICAgIHJldHVybiBYU3RyaW5nLkVNUFRZU1RSSU5HOwotCi0gICAgICAgIHMgPSBkdG0uZ2V0TmFtZXNwYWNlVVJJKGNvbnRleHQpOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgICByZXR1cm4gWFN0cmluZy5FTVBUWVNUUklORzsKLSAgICB9Ci0gICAgZWxzZQotICAgICAgcmV0dXJuIFhTdHJpbmcuRU1QVFlTVFJJTkc7Ci0KLSAgICByZXR1cm4gKChudWxsID09IHMpID8gWFN0cmluZy5FTVBUWVNUUklORyA6IG5ldyBYU3RyaW5nKHMpKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9mdW5jdGlvbnMvRnVuY05vcm1hbGl6ZVNwYWNlLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2Z1bmN0aW9ucy9GdW5jTm9ybWFsaXplU3BhY2UuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOWJlNjI1OS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2Z1bmN0aW9ucy9GdW5jTm9ybWFsaXplU3BhY2UuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDg4ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IEZ1bmNOb3JtYWxpemVTcGFjZS5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE0IDIwOjE4OjQ2IGplZmZzdXR0b3IgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuZnVuY3Rpb25zOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuWE1MU3RyaW5nOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5YUGF0aENvbnRleHQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWE9iamVjdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YU3RyaW5nOwotaW1wb3J0IG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyOwotCi0vKioKLSAqIEV4ZWN1dGUgdGhlIG5vcm1hbGl6ZS1zcGFjZSgpIGZ1bmN0aW9uLgotICogQHhzbC51c2FnZSBhZHZhbmNlZAotICovCi1wdWJsaWMgY2xhc3MgRnVuY05vcm1hbGl6ZVNwYWNlIGV4dGVuZHMgRnVuY3Rpb25EZWYxQXJnCi17Ci0gICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC0zMzc3OTU2ODcyMDMyMTkwODgwTDsKLQotICAvKioKLSAgICogRXhlY3V0ZSB0aGUgZnVuY3Rpb24uICBUaGUgZnVuY3Rpb24gbXVzdCByZXR1cm4KLSAgICogYSB2YWxpZCBvYmplY3QuCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgY3VycmVudCBleGVjdXRpb24gY29udGV4dC4KLSAgICogQHJldHVybiBBIHZhbGlkIFhPYmplY3QuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFhPYmplY3QgZXhlY3V0ZShYUGF0aENvbnRleHQgeGN0eHQpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICBYTUxTdHJpbmcgczEgPSBnZXRBcmcwQXNTdHJpbmcoeGN0eHQpOwotCi0gICAgcmV0dXJuIChYU3RyaW5nKXMxLmZpeFdoaXRlU3BhY2UodHJ1ZSwgdHJ1ZSwgZmFsc2UpOwotICB9Ci0KLSAgLyoqCi0gICAqIEV4ZWN1dGUgYW4gZXhwcmVzc2lvbiBpbiB0aGUgWFBhdGggcnVudGltZSBjb250ZXh0LCBhbmQgcmV0dXJuIHRoZQotICAgKiByZXN1bHQgb2YgdGhlIGV4cHJlc3Npb24uCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgWFBhdGggcnVudGltZSBjb250ZXh0LgotICAgKgotICAgKiBAcmV0dXJuIFRoZSByZXN1bHQgb2YgdGhlIGV4cHJlc3Npb24gaW4gdGhlIGZvcm0gb2YgYSA8Y29kZT5YT2JqZWN0PC9jb2RlPi4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uIGlmIGEgcnVudGltZSBleGNlcHRpb24KLSAgICogICAgICAgICBvY2N1cnMuCi0gICAqLwotICBwdWJsaWMgdm9pZCBleGVjdXRlQ2hhcnNUb0NvbnRlbnRIYW5kbGVyKFhQYXRoQ29udGV4dCB4Y3R4dCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb250ZW50SGFuZGxlciBoYW5kbGVyKQotICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uLAotICAgICAgICAgICBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIGlmKEFyZzBJc05vZGVzZXRFeHByKCkpCi0gICAgewotICAgICAgaW50IG5vZGUgPSBnZXRBcmcwQXNOb2RlKHhjdHh0KTsKLSAgICAgIGlmKERUTS5OVUxMICE9IG5vZGUpCi0gICAgICB7Ci0gICAgICAgIERUTSBkdG0gPSB4Y3R4dC5nZXREVE0obm9kZSk7Ci0gICAgICAgIGR0bS5kaXNwYXRjaENoYXJhY3RlcnNFdmVudHMobm9kZSwgaGFuZGxlciwgdHJ1ZSk7Ci0gICAgICB9Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBYT2JqZWN0IG9iaiA9IGV4ZWN1dGUoeGN0eHQpOwotICAgICAgb2JqLmRpc3BhdGNoQ2hhcmFjdGVyc0V2ZW50cyhoYW5kbGVyKTsKLSAgICB9Ci0gIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9mdW5jdGlvbnMvRnVuY05vdC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9mdW5jdGlvbnMvRnVuY05vdC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0NzZkNDMyLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvZnVuY3Rpb25zL0Z1bmNOb3QuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQ5ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IEZ1bmNOb3QuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNCAyMDoxODo0NCBqZWZmc3V0dG9yIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmZ1bmN0aW9uczsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5YUGF0aENvbnRleHQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWEJvb2xlYW47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWE9iamVjdDsKLQotLyoqCi0gKiBFeGVjdXRlIHRoZSBOb3QoKSBmdW5jdGlvbi4KLSAqIEB4c2wudXNhZ2UgYWR2YW5jZWQKLSAqLwotcHVibGljIGNsYXNzIEZ1bmNOb3QgZXh0ZW5kcyBGdW5jdGlvbk9uZUFyZwotewotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA3Mjk5Njk5OTYxMDc2MzI5NzkwTDsKLQotICAvKioKLSAgICogRXhlY3V0ZSB0aGUgZnVuY3Rpb24uICBUaGUgZnVuY3Rpb24gbXVzdCByZXR1cm4KLSAgICogYSB2YWxpZCBvYmplY3QuCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgY3VycmVudCBleGVjdXRpb24gY29udGV4dC4KLSAgICogQHJldHVybiBBIHZhbGlkIFhPYmplY3QuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFhPYmplY3QgZXhlY3V0ZShYUGF0aENvbnRleHQgeGN0eHQpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gbV9hcmcwLmV4ZWN1dGUoeGN0eHQpLmJvb2woKSA/IFhCb29sZWFuLlNfRkFMU0UgOiBYQm9vbGVhbi5TX1RSVUU7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvZnVuY3Rpb25zL0Z1bmNOdW1iZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvZnVuY3Rpb25zL0Z1bmNOdW1iZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggODdjMzgwOC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2Z1bmN0aW9ucy9GdW5jTnVtYmVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0OSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBGdW5jTnVtYmVyLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTQgMjA6MTg6NDQgamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5mdW5jdGlvbnM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuWFBhdGhDb250ZXh0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhOdW1iZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWE9iamVjdDsKLQotLyoqCi0gKiBFeGVjdXRlIHRoZSBOdW1iZXIoKSBmdW5jdGlvbi4KLSAqIEB4c2wudXNhZ2UgYWR2YW5jZWQKLSAqLwotcHVibGljIGNsYXNzIEZ1bmNOdW1iZXIgZXh0ZW5kcyBGdW5jdGlvbkRlZjFBcmcKLXsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNzI2Njc0NTM0MjI2NDE1MzA3Nkw7Ci0KLSAgLyoqCi0gICAqIEV4ZWN1dGUgdGhlIGZ1bmN0aW9uLiAgVGhlIGZ1bmN0aW9uIG11c3QgcmV0dXJuCi0gICAqIGEgdmFsaWQgb2JqZWN0LgotICAgKiBAcGFyYW0geGN0eHQgVGhlIGN1cnJlbnQgZXhlY3V0aW9uIGNvbnRleHQuCi0gICAqIEByZXR1cm4gQSB2YWxpZCBYT2JqZWN0LgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IGV4ZWN1dGUoWFBhdGhDb250ZXh0IHhjdHh0KSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIG5ldyBYTnVtYmVyKGdldEFyZzBBc051bWJlcih4Y3R4dCkpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2Z1bmN0aW9ucy9GdW5jUG9zaXRpb24uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvZnVuY3Rpb25zL0Z1bmNQb3NpdGlvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3MTljZWNlLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvZnVuY3Rpb25zL0Z1bmNQb3NpdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTM2ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IEZ1bmNQb3NpdGlvbi5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE0IDIwOjE4OjQ1IGplZmZzdXR0b3IgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuZnVuY3Rpb25zOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTUl0ZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5YUGF0aENvbnRleHQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmF4ZXMuU3ViQ29udGV4dExpc3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmNvbXBpbGVyLkNvbXBpbGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhOdW1iZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWE9iamVjdDsKLQotLyoqCi0gKiBFeGVjdXRlIHRoZSBQb3NpdGlvbigpIGZ1bmN0aW9uLgotICogQHhzbC51c2FnZSBhZHZhbmNlZAotICovCi1wdWJsaWMgY2xhc3MgRnVuY1Bvc2l0aW9uIGV4dGVuZHMgRnVuY3Rpb24KLXsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTkwOTI4NDYzNDgxOTcyNzE1ODJMOwotICBwcml2YXRlIGJvb2xlYW4gbV9pc1RvcExldmVsOwotCi0gIC8qKgotICAgKiBGaWd1cmUgb3V0IGlmIHdlJ3JlIGV4ZWN1dGluZyBhIHRvcGxldmVsIGV4cHJlc3Npb24uCi0gICAqIElmIHNvLCB3ZSBjYW4ndCBiZSBpbnNpZGUgb2YgYSBwcmVkaWNhdGUuCi0gICAqLwotICBwdWJsaWMgdm9pZCBwb3N0Q29tcGlsZVN0ZXAoQ29tcGlsZXIgY29tcGlsZXIpCi0gIHsKLSAgICBtX2lzVG9wTGV2ZWwgPSBjb21waWxlci5nZXRMb2NhdGlvblBhdGhEZXB0aCgpID09IC0xOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgcG9zaXRpb24gaW4gdGhlIGN1cnJlbnQgY29udGV4dCBub2RlIGxpc3QuCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBSdW50aW1lIFhQYXRoIGNvbnRleHQuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGN1cnJlbnQgcG9zaXRpb24gb2YgdGhlIGl0dGVyYXRpb24gaW4gdGhlIGNvbnRleHQgbm9kZSBsaXN0LAotICAgKiAgICAgICAgIG9yIC0xIGlmIHRoZXJlIGlzIG5vIGFjdGl2ZSBjb250ZXh0IG5vZGUgbGlzdC4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0UG9zaXRpb25JbkNvbnRleHROb2RlTGlzdChYUGF0aENvbnRleHQgeGN0eHQpCi0gIHsKLQotICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiRnVuY1Bvc2l0aW9uLSBlbnRyeSIpOwotICAgIC8vIElmIHdlJ3JlIGluIGEgcHJlZGljYXRlLCB0aGVuIHRoaXMgd2lsbCByZXR1cm4gbm9uLW51bGwuCi0gICAgU3ViQ29udGV4dExpc3QgaXRlciA9IG1faXNUb3BMZXZlbCA/IG51bGwgOiB4Y3R4dC5nZXRTdWJDb250ZXh0TGlzdCgpOwotCi0gICAgaWYgKG51bGwgIT0gaXRlcikKLSAgICB7Ci0gICAgICBpbnQgcHJveCA9IGl0ZXIuZ2V0UHJveGltaXR5UG9zaXRpb24oeGN0eHQpOwotCi0gICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIkZ1bmNQb3NpdGlvbi0gcHJveDogIitwcm94KTsKLSAgICAgIHJldHVybiBwcm94OwotICAgIH0KLQotICAgIERUTUl0ZXJhdG9yIGNubCA9IHhjdHh0LmdldENvbnRleHROb2RlTGlzdCgpOwotCi0gICAgaWYgKG51bGwgIT0gY25sKQotICAgIHsKLSAgICAgIGludCBuID0gY25sLmdldEN1cnJlbnROb2RlKCk7Ci0gICAgICBpZihuID09IERUTS5OVUxMKQotICAgICAgewotICAgICAgICBpZihjbmwuZ2V0Q3VycmVudFBvcygpID09IDApCi0gICAgICAgICAgcmV0dXJuIDA7Ci0KLSAgICAgICAgLy8gVGhlbiBJIHRoaW5rIHdlJ3JlIGluIGEgc29ydC4gIFNlZSBzb3J0MjEueHNsLiBTbyB0aGUgaXRlcmF0b3IgaGFzCi0gICAgICAgIC8vIGFscmVhZHkgYmVlbiBzcGVudCwgYW5kIGlzIG5vdCBvbiB0aGUgbm9kZSB3ZSdyZSBwcm9jZXNzaW5nLgotICAgICAgICAvLyBJdCdzIGhpZ2hseSBwb3NzaWJsZSB0aGF0IHRoaXMgaXMgYW4gaXNzdWUgZm9yIG90aGVyIGNvbnRleHQtbGlzdAotICAgICAgICAvLyBmdW5jdGlvbnMuICBTaG91bGRuJ3QgYmUgYSBwcm9ibGVtIGZvciBsYXN0KCksIGFuZCBpdCBzaG91bGRuJ3QgYmUKLSAgICAgICAgLy8gYSBwcm9ibGVtIGZvciBjdXJyZW50KCkuCi0gICAgICAgIHRyeQotICAgICAgICB7Ci0gICAgICAgICAgY25sID0gY25sLmNsb25lV2l0aFJlc2V0KCk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2goQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gY25zZSkKLSAgICAgICAgewotICAgICAgICAgIHRocm93IG5ldyBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLldyYXBwZWRSdW50aW1lRXhjZXB0aW9uKGNuc2UpOwotICAgICAgICB9Ci0gICAgICAgIGludCBjdXJyZW50Tm9kZSA9IHhjdHh0LmdldENvbnRleHROb2RlKCk7Ci0gICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiY3VycmVudE5vZGU6ICIrY3VycmVudE5vZGUpOwotICAgICAgICB3aGlsZShEVE0uTlVMTCAhPSAobiA9IGNubC5uZXh0Tm9kZSgpKSkKLSAgICAgICAgewotICAgICAgICAgIGlmKG4gPT0gY3VycmVudE5vZGUpCi0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgfQotICAgICAgfQotICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJuOiAiK24pOwotICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJGdW5jUG9zaXRpb24tIGNubC5nZXRDdXJyZW50UG9zKCk6ICIrY25sLmdldEN1cnJlbnRQb3MoKSk7Ci0gICAgICByZXR1cm4gY25sLmdldEN1cnJlbnRQb3MoKTsKLSAgICB9Ci0KLSAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIkZ1bmNQb3NpdGlvbiAtIG91dCBvZiBndWVzc2VzOiAtMSIpOwotICAgIHJldHVybiAtMTsKLSAgfQotCi0gIC8qKgotICAgKiBFeGVjdXRlIHRoZSBmdW5jdGlvbi4gIFRoZSBmdW5jdGlvbiBtdXN0IHJldHVybgotICAgKiBhIHZhbGlkIG9iamVjdC4KLSAgICogQHBhcmFtIHhjdHh0IFRoZSBjdXJyZW50IGV4ZWN1dGlvbiBjb250ZXh0LgotICAgKiBAcmV0dXJuIEEgdmFsaWQgWE9iamVjdC4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBleGVjdXRlKFhQYXRoQ29udGV4dCB4Y3R4dCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIGRvdWJsZSBwb3MgPSAoZG91YmxlKSBnZXRQb3NpdGlvbkluQ29udGV4dE5vZGVMaXN0KHhjdHh0KTsKLQotICAgIHJldHVybiBuZXcgWE51bWJlcihwb3MpOwotICB9Ci0KLSAgLyoqCi0gICAqIE5vIGFyZ3VtZW50cyB0byBwcm9jZXNzLCBzbyB0aGlzIGRvZXMgbm90aGluZy4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGZpeHVwVmFyaWFibGVzKGphdmEudXRpbC5WZWN0b3IgdmFycywgaW50IGdsb2JhbHNTaXplKQotICB7Ci0gICAgLy8gbm8tb3AKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9mdW5jdGlvbnMvRnVuY1FuYW1lLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2Z1bmN0aW9ucy9GdW5jUW5hbWUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggODM0ZDczZi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2Z1bmN0aW9ucy9GdW5jUW5hbWUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDY1ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IEZ1bmNRbmFtZS5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE0IDIwOjE4OjQ2IGplZmZzdXR0b3IgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuZnVuY3Rpb25zOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5YUGF0aENvbnRleHQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWE9iamVjdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YU3RyaW5nOwotCi0vKioKLSAqIEV4ZWN1dGUgdGhlIFFuYW1lKCkgZnVuY3Rpb24uCi0gKiBAeHNsLnVzYWdlIGFkdmFuY2VkCi0gKi8KLXB1YmxpYyBjbGFzcyBGdW5jUW5hbWUgZXh0ZW5kcyBGdW5jdGlvbkRlZjFBcmcKLXsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTE1MzIzMDc4NzU1MzI2MTczODBMOwotCi0gIC8qKgotICAgKiBFeGVjdXRlIHRoZSBmdW5jdGlvbi4gIFRoZSBmdW5jdGlvbiBtdXN0IHJldHVybgotICAgKiBhIHZhbGlkIG9iamVjdC4KLSAgICogQHBhcmFtIHhjdHh0IFRoZSBjdXJyZW50IGV4ZWN1dGlvbiBjb250ZXh0LgotICAgKiBAcmV0dXJuIEEgdmFsaWQgWE9iamVjdC4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBleGVjdXRlKFhQYXRoQ29udGV4dCB4Y3R4dCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaW50IGNvbnRleHQgPSBnZXRBcmcwQXNOb2RlKHhjdHh0KTsKLSAgICBYT2JqZWN0IHZhbDsKLQotICAgIGlmIChEVE0uTlVMTCAhPSBjb250ZXh0KQotICAgIHsKLSAgICAgIERUTSBkdG0gPSB4Y3R4dC5nZXREVE0oY29udGV4dCk7Ci0gICAgICBTdHJpbmcgcW5hbWUgPSBkdG0uZ2V0Tm9kZU5hbWVYKGNvbnRleHQpOwotICAgICAgdmFsID0gKG51bGwgPT0gcW5hbWUpID8gWFN0cmluZy5FTVBUWVNUUklORyA6IG5ldyBYU3RyaW5nKHFuYW1lKTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIHZhbCA9IFhTdHJpbmcuRU1QVFlTVFJJTkc7Ci0gICAgfQotCi0gICAgcmV0dXJuIHZhbDsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9mdW5jdGlvbnMvRnVuY1JvdW5kLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2Z1bmN0aW9ucy9GdW5jUm91bmQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZWYyM2VjYy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2Z1bmN0aW9ucy9GdW5jUm91bmQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDU0ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IEZ1bmNSb3VuZC5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE0IDIwOjE4OjQyIGplZmZzdXR0b3IgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuZnVuY3Rpb25zOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoQ29udGV4dDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YTnVtYmVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhPYmplY3Q7Ci0KLS8qKgotICogRXhlY3V0ZSB0aGUgcm91bmQoKSBmdW5jdGlvbi4KLSAqIEB4c2wudXNhZ2UgYWR2YW5jZWQKLSAqLwotcHVibGljIGNsYXNzIEZ1bmNSb3VuZCBleHRlbmRzIEZ1bmN0aW9uT25lQXJnCi17Ci0gICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC03OTcwNTgzOTAyNTczODI2NjExTDsKLQotICAvKioKLSAgICogRXhlY3V0ZSB0aGUgZnVuY3Rpb24uICBUaGUgZnVuY3Rpb24gbXVzdCByZXR1cm4KLSAgICogYSB2YWxpZCBvYmplY3QuCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgY3VycmVudCBleGVjdXRpb24gY29udGV4dC4KLSAgICogQHJldHVybiBBIHZhbGlkIFhPYmplY3QuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFhPYmplY3QgZXhlY3V0ZShYUGF0aENvbnRleHQgeGN0eHQpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICAgICAgICBmaW5hbCBYT2JqZWN0IG9iaiA9IG1fYXJnMC5leGVjdXRlKHhjdHh0KTsKLSAgICAgICAgICBmaW5hbCBkb3VibGUgdmFsPSBvYmoubnVtKCk7Ci0gICAgICAgICAgaWYgKHZhbCA+PSAtMC41ICYmIHZhbCA8IDApIHJldHVybiBuZXcgWE51bWJlcigtMC4wKTsKLSAgICAgICAgICBpZiAodmFsID09IDAuMCkgcmV0dXJuIG5ldyBYTnVtYmVyKHZhbCk7Ci0gICAgICAgICAgcmV0dXJuIG5ldyBYTnVtYmVyKGphdmEubGFuZy5NYXRoLmZsb29yKHZhbAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIDAuNSkpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2Z1bmN0aW9ucy9GdW5jU3RhcnRzV2l0aC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9mdW5jdGlvbnMvRnVuY1N0YXJ0c1dpdGguamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNDNiNzY2MS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2Z1bmN0aW9ucy9GdW5jU3RhcnRzV2l0aC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTAgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRnVuY1N0YXJ0c1dpdGguamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNCAyMDoxODo0MyBqZWZmc3V0dG9yIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmZ1bmN0aW9uczsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5YUGF0aENvbnRleHQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWEJvb2xlYW47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWE9iamVjdDsKLQotLyoqCi0gKiBFeGVjdXRlIHRoZSBTdGFydHNXaXRoKCkgZnVuY3Rpb24uCi0gKiBAeHNsLnVzYWdlIGFkdmFuY2VkCi0gKi8KLXB1YmxpYyBjbGFzcyBGdW5jU3RhcnRzV2l0aCBleHRlbmRzIEZ1bmN0aW9uMkFyZ3MKLXsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMjE5NDU4NTc3NDY5OTU2NzkyOEw7Ci0KLSAgLyoqCi0gICAqIEV4ZWN1dGUgdGhlIGZ1bmN0aW9uLiAgVGhlIGZ1bmN0aW9uIG11c3QgcmV0dXJuCi0gICAqIGEgdmFsaWQgb2JqZWN0LgotICAgKiBAcGFyYW0geGN0eHQgVGhlIGN1cnJlbnQgZXhlY3V0aW9uIGNvbnRleHQuCi0gICAqIEByZXR1cm4gQSB2YWxpZCBYT2JqZWN0LgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IGV4ZWN1dGUoWFBhdGhDb250ZXh0IHhjdHh0KSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIG1fYXJnMC5leGVjdXRlKHhjdHh0KS54c3RyKCkuc3RhcnRzV2l0aChtX2FyZzEuZXhlY3V0ZSh4Y3R4dCkueHN0cigpKQotICAgICAgICAgICA/IFhCb29sZWFuLlNfVFJVRSA6IFhCb29sZWFuLlNfRkFMU0U7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvZnVuY3Rpb25zL0Z1bmNTdHJpbmcuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvZnVuY3Rpb25zL0Z1bmNTdHJpbmcuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNzViMTA4NS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2Z1bmN0aW9ucy9GdW5jU3RyaW5nLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0OSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBGdW5jU3RyaW5nLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTQgMjA6MTg6NDQgamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5mdW5jdGlvbnM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuWFBhdGhDb250ZXh0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhPYmplY3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWFN0cmluZzsKLQotLyoqCi0gKiBFeGVjdXRlIHRoZSBTdHJpbmcoKSBmdW5jdGlvbi4KLSAqIEB4c2wudXNhZ2UgYWR2YW5jZWQKLSAqLwotcHVibGljIGNsYXNzIEZ1bmNTdHJpbmcgZXh0ZW5kcyBGdW5jdGlvbkRlZjFBcmcKLXsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTIyMDY2NzcxNDk0OTc3MTI4ODNMOwotCi0gIC8qKgotICAgKiBFeGVjdXRlIHRoZSBmdW5jdGlvbi4gIFRoZSBmdW5jdGlvbiBtdXN0IHJldHVybgotICAgKiBhIHZhbGlkIG9iamVjdC4KLSAgICogQHBhcmFtIHhjdHh0IFRoZSBjdXJyZW50IGV4ZWN1dGlvbiBjb250ZXh0LgotICAgKiBAcmV0dXJuIEEgdmFsaWQgWE9iamVjdC4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBleGVjdXRlKFhQYXRoQ29udGV4dCB4Y3R4dCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHJldHVybiAoWFN0cmluZylnZXRBcmcwQXNTdHJpbmcoeGN0eHQpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2Z1bmN0aW9ucy9GdW5jU3RyaW5nTGVuZ3RoLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2Z1bmN0aW9ucy9GdW5jU3RyaW5nTGVuZ3RoLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDVkNjliYTMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9mdW5jdGlvbnMvRnVuY1N0cmluZ0xlbmd0aC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDkgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRnVuY1N0cmluZ0xlbmd0aC5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE0IDIwOjE4OjQ0IGplZmZzdXR0b3IgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuZnVuY3Rpb25zOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoQ29udGV4dDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YTnVtYmVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhPYmplY3Q7Ci0KLS8qKgotICogRXhlY3V0ZSB0aGUgU3RyaW5nTGVuZ3RoKCkgZnVuY3Rpb24uCi0gKiBAeHNsLnVzYWdlIGFkdmFuY2VkCi0gKi8KLXB1YmxpYyBjbGFzcyBGdW5jU3RyaW5nTGVuZ3RoIGV4dGVuZHMgRnVuY3Rpb25EZWYxQXJnCi17Ci0gICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC0xNTk2MTY0MTc5OTY1MTk4MzlMOwotCi0gIC8qKgotICAgKiBFeGVjdXRlIHRoZSBmdW5jdGlvbi4gIFRoZSBmdW5jdGlvbiBtdXN0IHJldHVybgotICAgKiBhIHZhbGlkIG9iamVjdC4KLSAgICogQHBhcmFtIHhjdHh0IFRoZSBjdXJyZW50IGV4ZWN1dGlvbiBjb250ZXh0LgotICAgKiBAcmV0dXJuIEEgdmFsaWQgWE9iamVjdC4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBleGVjdXRlKFhQYXRoQ29udGV4dCB4Y3R4dCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHJldHVybiBuZXcgWE51bWJlcihnZXRBcmcwQXNTdHJpbmcoeGN0eHQpLmxlbmd0aCgpKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9mdW5jdGlvbnMvRnVuY1N1YnN0cmluZy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9mdW5jdGlvbnMvRnVuY1N1YnN0cmluZy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA5OGFlZGY3Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvZnVuY3Rpb25zL0Z1bmNTdWJzdHJpbmcuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEyNiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBGdW5jU3Vic3RyaW5nLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTQgMjA6MTg6NDUgamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5mdW5jdGlvbnM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwucmVzLlhTTE1lc3NhZ2VzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuWE1MU3RyaW5nOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5YUGF0aENvbnRleHQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWE9iamVjdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YU3RyaW5nOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5yZXMuWFBBVEhFcnJvclJlc291cmNlczsKLQotLyoqCi0gKiBFeGVjdXRlIHRoZSBTdWJzdHJpbmcoKSBmdW5jdGlvbi4KLSAqIEB4c2wudXNhZ2UgYWR2YW5jZWQKLSAqLwotcHVibGljIGNsYXNzIEZ1bmNTdWJzdHJpbmcgZXh0ZW5kcyBGdW5jdGlvbjNBcmdzCi17Ci0gICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC01OTk2Njc2MDk1MDI0NzE1NTAyTDsKLQotICAvKioKLSAgICogRXhlY3V0ZSB0aGUgZnVuY3Rpb24uICBUaGUgZnVuY3Rpb24gbXVzdCByZXR1cm4KLSAgICogYSB2YWxpZCBvYmplY3QuCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgY3VycmVudCBleGVjdXRpb24gY29udGV4dC4KLSAgICogQHJldHVybiBBIHZhbGlkIFhPYmplY3QuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFhPYmplY3QgZXhlY3V0ZShYUGF0aENvbnRleHQgeGN0eHQpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIFhNTFN0cmluZyBzMSA9IG1fYXJnMC5leGVjdXRlKHhjdHh0KS54c3RyKCk7Ci0gICAgZG91YmxlIHN0YXJ0ID0gbV9hcmcxLmV4ZWN1dGUoeGN0eHQpLm51bSgpOwotICAgIGludCBsZW5PZlMxID0gczEubGVuZ3RoKCk7Ci0gICAgWE1MU3RyaW5nIHN1YnN0cjsKLQotICAgIGlmIChsZW5PZlMxIDw9IDApCi0gICAgICByZXR1cm4gWFN0cmluZy5FTVBUWVNUUklORzsKLSAgICBlbHNlCi0gICAgewotICAgICAgaW50IHN0YXJ0SW5kZXg7Ci0KLSAgICAgIGlmIChEb3VibGUuaXNOYU4oc3RhcnQpKQotICAgICAgewotCi0gICAgICAgIC8vIERvdWJsZS5NSU5fVkFMVUUgZG9lc24ndCB3b3JrIHdpdGggbWF0aCBiZWxvdwotICAgICAgICAvLyBzbyBqdXN0IHVzZSBhIGJpZyBudW1iZXIgYW5kIGhvcGUgSSBuZXZlciBnZXQgY2F1Z2h0LgotICAgICAgICBzdGFydCA9IC0xMDAwMDAwOwotICAgICAgICBzdGFydEluZGV4ID0gMDsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgc3RhcnQgPSBNYXRoLnJvdW5kKHN0YXJ0KTsKLSAgICAgICAgc3RhcnRJbmRleCA9IChzdGFydCA+IDApID8gKGludCkgc3RhcnQgLSAxIDogMDsKLSAgICAgIH0KLQotICAgICAgaWYgKG51bGwgIT0gbV9hcmcyKQotICAgICAgewotICAgICAgICBkb3VibGUgbGVuID0gbV9hcmcyLm51bSh4Y3R4dCk7Ci0gICAgICAgIGludCBlbmQgPSAoaW50KSAoTWF0aC5yb3VuZChsZW4pICsgc3RhcnQpIC0gMTsKLQotICAgICAgICAvLyBOb3JtYWxpemUgZW5kIGluZGV4LgotICAgICAgICBpZiAoZW5kIDwgMCkKLSAgICAgICAgICBlbmQgPSAwOwotICAgICAgICBlbHNlIGlmIChlbmQgPiBsZW5PZlMxKQotICAgICAgICAgIGVuZCA9IGxlbk9mUzE7Ci0KLSAgICAgICAgaWYgKHN0YXJ0SW5kZXggPiBsZW5PZlMxKQotICAgICAgICAgIHN0YXJ0SW5kZXggPSBsZW5PZlMxOwotCi0gICAgICAgIHN1YnN0ciA9IHMxLnN1YnN0cmluZyhzdGFydEluZGV4LCBlbmQpOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBpZiAoc3RhcnRJbmRleCA+IGxlbk9mUzEpCi0gICAgICAgICAgc3RhcnRJbmRleCA9IGxlbk9mUzE7Ci0gICAgICAgIHN1YnN0ciA9IHMxLnN1YnN0cmluZyhzdGFydEluZGV4KTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gKFhTdHJpbmcpc3Vic3RyOyAvLyBjYXN0IHNlbWktc2FmZQotICB9Ci0KLSAgLyoqCi0gICAqIENoZWNrIHRoYXQgdGhlIG51bWJlciBvZiBhcmd1bWVudHMgcGFzc2VkIHRvIHRoaXMgZnVuY3Rpb24gaXMgY29ycmVjdC4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIGFyZ051bSBUaGUgbnVtYmVyIG9mIGFyZ3VtZW50cyB0aGF0IGlzIGJlaW5nIHBhc3NlZCB0byB0aGUgZnVuY3Rpb24uCi0gICAqCi0gICAqIEB0aHJvd3MgV3JvbmdOdW1iZXJBcmdzRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBjaGVja051bWJlckFyZ3MoaW50IGFyZ051bSkgdGhyb3dzIFdyb25nTnVtYmVyQXJnc0V4Y2VwdGlvbgotICB7Ci0gICAgaWYgKGFyZ051bSA8IDIpCi0gICAgICByZXBvcnRXcm9uZ051bWJlckFyZ3MoKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3RzIGFuZCB0aHJvd3MgYSBXcm9uZ051bWJlckFyZ0V4Y2VwdGlvbiB3aXRoIHRoZSBhcHByb3ByaWF0ZQotICAgKiBtZXNzYWdlIGZvciB0aGlzIGZ1bmN0aW9uIG9iamVjdC4KLSAgICoKLSAgICogQHRocm93cyBXcm9uZ051bWJlckFyZ3NFeGNlcHRpb24KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIHJlcG9ydFdyb25nTnVtYmVyQXJncygpIHRocm93cyBXcm9uZ051bWJlckFyZ3NFeGNlcHRpb24gewotICAgICAgdGhyb3cgbmV3IFdyb25nTnVtYmVyQXJnc0V4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoWFBBVEhFcnJvclJlc291cmNlcy5FUl9UV09fT1JfVEhSRUUsIG51bGwpKTsgLy8iMiBvciAzIik7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvZnVuY3Rpb25zL0Z1bmNTdWJzdHJpbmdBZnRlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9mdW5jdGlvbnMvRnVuY1N1YnN0cmluZ0FmdGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDlhYjg5MDYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9mdW5jdGlvbnMvRnVuY1N1YnN0cmluZ0FmdGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw1NyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBGdW5jU3Vic3RyaW5nQWZ0ZXIuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNCAyMDoxODo0MyBqZWZmc3V0dG9yIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmZ1bmN0aW9uczsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuWE1MU3RyaW5nOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5YUGF0aENvbnRleHQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWE9iamVjdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YU3RyaW5nOwotCi0vKioKLSAqIEV4ZWN1dGUgdGhlIFN1YnN0cmluZ0FmdGVyKCkgZnVuY3Rpb24uCi0gKiBAeHNsLnVzYWdlIGFkdmFuY2VkCi0gKi8KLXB1YmxpYyBjbGFzcyBGdW5jU3Vic3RyaW5nQWZ0ZXIgZXh0ZW5kcyBGdW5jdGlvbjJBcmdzCi17Ci0gICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC04MTE5NzMxODg5ODYyNTEyMTk0TDsKLQotICAvKioKLSAgICogRXhlY3V0ZSB0aGUgZnVuY3Rpb24uICBUaGUgZnVuY3Rpb24gbXVzdCByZXR1cm4KLSAgICogYSB2YWxpZCBvYmplY3QuCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgY3VycmVudCBleGVjdXRpb24gY29udGV4dC4KLSAgICogQHJldHVybiBBIHZhbGlkIFhPYmplY3QuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFhPYmplY3QgZXhlY3V0ZShYUGF0aENvbnRleHQgeGN0eHQpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIFhNTFN0cmluZyBzMSA9IG1fYXJnMC5leGVjdXRlKHhjdHh0KS54c3RyKCk7Ci0gICAgWE1MU3RyaW5nIHMyID0gbV9hcmcxLmV4ZWN1dGUoeGN0eHQpLnhzdHIoKTsKLSAgICBpbnQgaW5kZXggPSBzMS5pbmRleE9mKHMyKTsKLQotICAgIHJldHVybiAoLTEgPT0gaW5kZXgpCi0gICAgICAgICAgID8gWFN0cmluZy5FTVBUWVNUUklORwotICAgICAgICAgICA6IChYU3RyaW5nKXMxLnN1YnN0cmluZyhpbmRleCArIHMyLmxlbmd0aCgpKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9mdW5jdGlvbnMvRnVuY1N1YnN0cmluZ0JlZm9yZS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9mdW5jdGlvbnMvRnVuY1N1YnN0cmluZ0JlZm9yZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkY2NjODY4Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvZnVuY3Rpb25zL0Z1bmNTdWJzdHJpbmdCZWZvcmUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDU1ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IEZ1bmNTdWJzdHJpbmdCZWZvcmUuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNCAyMDoxODo0NyBqZWZmc3V0dG9yIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmZ1bmN0aW9uczsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5YUGF0aENvbnRleHQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWE9iamVjdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YU3RyaW5nOwotCi0vKioKLSAqIEV4ZWN1dGUgdGhlIFN1YnN0cmluZ0JlZm9yZSgpIGZ1bmN0aW9uLgotICogQHhzbC51c2FnZSBhZHZhbmNlZAotICovCi1wdWJsaWMgY2xhc3MgRnVuY1N1YnN0cmluZ0JlZm9yZSBleHRlbmRzIEZ1bmN0aW9uMkFyZ3MKLXsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNDExMDU0NzE2MTY3MjQzMTc3NUw7Ci0KLSAgLyoqCi0gICAqIEV4ZWN1dGUgdGhlIGZ1bmN0aW9uLiAgVGhlIGZ1bmN0aW9uIG11c3QgcmV0dXJuCi0gICAqIGEgdmFsaWQgb2JqZWN0LgotICAgKiBAcGFyYW0geGN0eHQgVGhlIGN1cnJlbnQgZXhlY3V0aW9uIGNvbnRleHQuCi0gICAqIEByZXR1cm4gQSB2YWxpZCBYT2JqZWN0LgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IGV4ZWN1dGUoWFBhdGhDb250ZXh0IHhjdHh0KSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBTdHJpbmcgczEgPSBtX2FyZzAuZXhlY3V0ZSh4Y3R4dCkuc3RyKCk7Ci0gICAgU3RyaW5nIHMyID0gbV9hcmcxLmV4ZWN1dGUoeGN0eHQpLnN0cigpOwotICAgIGludCBpbmRleCA9IHMxLmluZGV4T2YoczIpOwotCi0gICAgcmV0dXJuICgtMSA9PSBpbmRleCkKLSAgICAgICAgICAgPyBYU3RyaW5nLkVNUFRZU1RSSU5HIDogbmV3IFhTdHJpbmcoczEuc3Vic3RyaW5nKDAsIGluZGV4KSk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvZnVuY3Rpb25zL0Z1bmNTdW0uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvZnVuY3Rpb25zL0Z1bmNTdW0uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZjFhNmQxZC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2Z1bmN0aW9ucy9GdW5jU3VtLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw2NyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBGdW5jU3VtLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTQgMjA6MTg6NDYgamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5mdW5jdGlvbnM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE07Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNSXRlcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5YTUxTdHJpbmc7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoQ29udGV4dDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YTnVtYmVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhPYmplY3Q7Ci0KLS8qKgotICogRXhlY3V0ZSB0aGUgU3VtKCkgZnVuY3Rpb24uCi0gKiBAeHNsLnVzYWdlIGFkdmFuY2VkCi0gKi8KLXB1YmxpYyBjbGFzcyBGdW5jU3VtIGV4dGVuZHMgRnVuY3Rpb25PbmVBcmcKLXsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTI3MTkwNDkyNTk1NzQ2Nzc1MTlMOwotCi0gIC8qKgotICAgKiBFeGVjdXRlIHRoZSBmdW5jdGlvbi4gIFRoZSBmdW5jdGlvbiBtdXN0IHJldHVybgotICAgKiBhIHZhbGlkIG9iamVjdC4KLSAgICogQHBhcmFtIHhjdHh0IFRoZSBjdXJyZW50IGV4ZWN1dGlvbiBjb250ZXh0LgotICAgKiBAcmV0dXJuIEEgdmFsaWQgWE9iamVjdC4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBleGVjdXRlKFhQYXRoQ29udGV4dCB4Y3R4dCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgRFRNSXRlcmF0b3Igbm9kZXMgPSBtX2FyZzAuYXNJdGVyYXRvcih4Y3R4dCwgeGN0eHQuZ2V0Q3VycmVudE5vZGUoKSk7Ci0gICAgZG91YmxlIHN1bSA9IDAuMDsKLSAgICBpbnQgcG9zOwotCi0gICAgd2hpbGUgKERUTS5OVUxMICE9IChwb3MgPSBub2Rlcy5uZXh0Tm9kZSgpKSkKLSAgICB7Ci0gICAgICBEVE0gZHRtID0gbm9kZXMuZ2V0RFRNKHBvcyk7Ci0gICAgICBYTUxTdHJpbmcgcyA9IGR0bS5nZXRTdHJpbmdWYWx1ZShwb3MpOwotCi0gICAgICBpZiAobnVsbCAhPSBzKQotICAgICAgICBzdW0gKz0gcy50b0RvdWJsZSgpOwotICAgIH0KLSAgICBub2Rlcy5kZXRhY2goKTsKLQotICAgIHJldHVybiBuZXcgWE51bWJlcihzdW0pOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2Z1bmN0aW9ucy9GdW5jU3lzdGVtUHJvcGVydHkuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvZnVuY3Rpb25zL0Z1bmNTeXN0ZW1Qcm9wZXJ0eS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0ZjlhOTY4Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvZnVuY3Rpb25zL0Z1bmNTeXN0ZW1Qcm9wZXJ0eS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTg4ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IEZ1bmNTeXN0ZW1Qcm9wZXJ0eS5qYXZhLHYgMS4yLjQuMiAyMDA1LzA5LzE0IDIwOjE4OjQ1IGplZmZzdXR0b3IgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuZnVuY3Rpb25zOwotCi1pbXBvcnQgamF2YS5pby5CdWZmZXJlZElucHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07Ci1pbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuWFBhdGhDb250ZXh0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhOdW1iZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWE9iamVjdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YU3RyaW5nOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5yZXMuWFBBVEhFcnJvclJlc291cmNlczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwudXRpbHMuT2JqZWN0RmFjdG9yeTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwudXRpbHMuU2VjdXJpdHlTdXBwb3J0OwotCi0vKioKLSAqIEV4ZWN1dGUgdGhlIFN5c3RlbVByb3BlcnR5KCkgZnVuY3Rpb24uCi0gKiBAeHNsLnVzYWdlIGFkdmFuY2VkCi0gKi8KLXB1YmxpYyBjbGFzcyBGdW5jU3lzdGVtUHJvcGVydHkgZXh0ZW5kcyBGdW5jdGlvbk9uZUFyZwotewotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAzNjk0ODc0OTgwOTkyMjA0ODY3TDsKLSAgLyoqCi0gICAqIFRoZSBwYXRoL2ZpbGVuYW1lIG9mIHRoZSBwcm9wZXJ0eSBmaWxlOiBYU0xUSW5mby5wcm9wZXJ0aWVzCi0gICAqIE1haW50ZW5hbmNlIG5vdGU6IHNlZSBhbHNvCi0gICAqIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC5wcm9jZXNzb3IuVHJhbnNmb3JtZXJGYWN0b3J5SW1wbC5YU0xUX1BST1BFUlRJRVMKLSAgICovCi0gIHN0YXRpYyBmaW5hbCBTdHJpbmcgWFNMVF9QUk9QRVJUSUVTID0KLSAgICAgICAgICAgICJjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwvcmVzL1hTTFRJbmZvLnByb3BlcnRpZXMiOwotCi0gIC8qKgotICAgKiBFeGVjdXRlIHRoZSBmdW5jdGlvbi4gIFRoZSBmdW5jdGlvbiBtdXN0IHJldHVybgotICAgKiBhIHZhbGlkIG9iamVjdC4KLSAgICogQHBhcmFtIHhjdHh0IFRoZSBjdXJyZW50IGV4ZWN1dGlvbiBjb250ZXh0LgotICAgKiBAcmV0dXJuIEEgdmFsaWQgWE9iamVjdC4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBleGVjdXRlKFhQYXRoQ29udGV4dCB4Y3R4dCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgU3RyaW5nIGZ1bGxOYW1lID0gbV9hcmcwLmV4ZWN1dGUoeGN0eHQpLnN0cigpOwotICAgIGludCBpbmRleE9mTlNTZXAgPSBmdWxsTmFtZS5pbmRleE9mKCc6Jyk7Ci0gICAgU3RyaW5nIHJlc3VsdDsKLSAgICBTdHJpbmcgcHJvcE5hbWUgPSAiIjsKLQotICAgIC8vIExpc3Qgb2YgcHJvcGVydGllcyB3aGVyZSB0aGUgbmFtZSBvZiB0aGUKLSAgICAvLyBwcm9wZXJ0eSBhcmd1bWVudCBpcyB0byBiZSBsb29rZWQgZm9yLgotICAgIFByb3BlcnRpZXMgeHNsdEluZm8gPSBuZXcgUHJvcGVydGllcygpOwotCi0gICAgbG9hZFByb3BlcnR5RmlsZShYU0xUX1BST1BFUlRJRVMsIHhzbHRJbmZvKTsKLQotICAgIGlmIChpbmRleE9mTlNTZXAgPiAwKQotICAgIHsKLSAgICAgIFN0cmluZyBwcmVmaXggPSAoaW5kZXhPZk5TU2VwID49IDApCi0gICAgICAgICAgICAgICAgICAgICAgPyBmdWxsTmFtZS5zdWJzdHJpbmcoMCwgaW5kZXhPZk5TU2VwKSA6ICIiOwotICAgICAgU3RyaW5nIG5hbWVzcGFjZTsKLQotICAgICAgbmFtZXNwYWNlID0geGN0eHQuZ2V0TmFtZXNwYWNlQ29udGV4dCgpLmdldE5hbWVzcGFjZUZvclByZWZpeChwcmVmaXgpOwotICAgICAgcHJvcE5hbWUgPSAoaW5kZXhPZk5TU2VwIDwgMCkKLSAgICAgICAgICAgICAgICAgPyBmdWxsTmFtZSA6IGZ1bGxOYW1lLnN1YnN0cmluZyhpbmRleE9mTlNTZXAgKyAxKTsKLQotICAgICAgaWYgKG5hbWVzcGFjZS5zdGFydHNXaXRoKCJodHRwOi8vd3d3LnczLm9yZy9YU0wvVHJhbnNmb3JtIikKLSAgICAgICAgICAgICAgfHwgbmFtZXNwYWNlLmVxdWFscygiaHR0cDovL3d3dy53My5vcmcvMTk5OS9YU0wvVHJhbnNmb3JtIikpCi0gICAgICB7Ci0gICAgICAgIHJlc3VsdCA9IHhzbHRJbmZvLmdldFByb3BlcnR5KHByb3BOYW1lKTsKLQotICAgICAgICBpZiAobnVsbCA9PSByZXN1bHQpCi0gICAgICAgIHsKLSAgICAgICAgICB3YXJuKHhjdHh0LCBYUEFUSEVycm9yUmVzb3VyY2VzLldHX1BST1BFUlRZX05PVF9TVVBQT1JURUQsCi0gICAgICAgICAgICAgICBuZXcgT2JqZWN0W117IGZ1bGxOYW1lIH0pOyAgLy8iWFNMIFByb3BlcnR5IG5vdCBzdXBwb3J0ZWQ6ICIrZnVsbE5hbWUpOwotCi0gICAgICAgICAgcmV0dXJuIFhTdHJpbmcuRU1QVFlTVFJJTkc7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgd2Fybih4Y3R4dCwgWFBBVEhFcnJvclJlc291cmNlcy5XR19ET05UX0RPX0FOWVRISU5HX1dJVEhfTlMsCi0gICAgICAgICAgICAgbmV3IE9iamVjdFtdeyBuYW1lc3BhY2UsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICBmdWxsTmFtZSB9KTsgIC8vIkRvbid0IGN1cnJlbnRseSBkbyBhbnl0aGluZyB3aXRoIG5hbWVzcGFjZSAiK25hbWVzcGFjZSsiIGluIHByb3BlcnR5OiAiK2Z1bGxOYW1lKTsKLQotICAgICAgICB0cnkKLSAgICAgICAgewotICAgICAgICAgIHJlc3VsdCA9IFNlY3VyaXR5U3VwcG9ydC5nZXRTeXN0ZW1Qcm9wZXJ0eShwcm9wTmFtZSk7Ci0KLSAgICAgICAgICBpZiAobnVsbCA9PSByZXN1bHQpCi0gICAgICAgICAgewotCi0gICAgICAgICAgICAvLyByZXN1bHQgPSBTeXN0ZW0uZ2V0ZW52KHByb3BOYW1lKTsKLSAgICAgICAgICAgIHJldHVybiBYU3RyaW5nLkVNUFRZU1RSSU5HOwotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gc2UpCi0gICAgICAgIHsKLSAgICAgICAgICB3YXJuKHhjdHh0LCBYUEFUSEVycm9yUmVzb3VyY2VzLldHX1NFQ1VSSVRZX0VYQ0VQVElPTiwKLSAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXsgZnVsbE5hbWUgfSk7ICAvLyJTZWN1cml0eUV4Y2VwdGlvbiB3aGVuIHRyeWluZyB0byBhY2Nlc3MgWFNMIHN5c3RlbSBwcm9wZXJ0eTogIitmdWxsTmFtZSk7Ci0KLSAgICAgICAgICByZXR1cm4gWFN0cmluZy5FTVBUWVNUUklORzsKLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgdHJ5Ci0gICAgICB7Ci0gICAgICAgIHJlc3VsdCA9IFNlY3VyaXR5U3VwcG9ydC5nZXRTeXN0ZW1Qcm9wZXJ0eShmdWxsTmFtZSk7Ci0KLSAgICAgICAgaWYgKG51bGwgPT0gcmVzdWx0KQotICAgICAgICB7Ci0KLSAgICAgICAgICAvLyByZXN1bHQgPSBTeXN0ZW0uZ2V0ZW52KGZ1bGxOYW1lKTsKLSAgICAgICAgICByZXR1cm4gWFN0cmluZy5FTVBUWVNUUklORzsKLSAgICAgICAgfQotICAgICAgfQotICAgICAgY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIHNlKQotICAgICAgewotICAgICAgICB3YXJuKHhjdHh0LCBYUEFUSEVycm9yUmVzb3VyY2VzLldHX1NFQ1VSSVRZX0VYQ0VQVElPTiwKLSAgICAgICAgICAgICBuZXcgT2JqZWN0W117IGZ1bGxOYW1lIH0pOyAgLy8iU2VjdXJpdHlFeGNlcHRpb24gd2hlbiB0cnlpbmcgdG8gYWNjZXNzIFhTTCBzeXN0ZW0gcHJvcGVydHk6ICIrZnVsbE5hbWUpOwotCi0gICAgICAgIHJldHVybiBYU3RyaW5nLkVNUFRZU1RSSU5HOwotICAgICAgfQotICAgIH0KLQotICAgIGlmIChwcm9wTmFtZS5lcXVhbHMoInZlcnNpb24iKSAmJiByZXN1bHQubGVuZ3RoKCkgPiAwKQotICAgIHsKLSAgICAgIHRyeQotICAgICAgewotICAgICAgICAvLyBOZWVkcyB0byByZXR1cm4gdGhlIHZlcnNpb24gbnVtYmVyIG9mIHRoZSBzcGVjIHdlIGNvbmZvcm0gdG8uCi0gICAgICAgIHJldHVybiBuZXcgWFN0cmluZygiMS4wIik7Ci0gICAgICB9Ci0gICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KQotICAgICAgewotICAgICAgICByZXR1cm4gbmV3IFhTdHJpbmcocmVzdWx0KTsKLSAgICAgIH0KLSAgICB9Ci0gICAgZWxzZQotICAgICAgcmV0dXJuIG5ldyBYU3RyaW5nKHJlc3VsdCk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0cmlldmUgYSBwcm9wZXJ5IGJ1bmRsZSBmcm9tIGEgc3BlY2lmaWVkIGZpbGUKLSAgICoKLSAgICogQHBhcmFtIGZpbGUgVGhlIHN0cmluZyBuYW1lIG9mIHRoZSBwcm9wZXJ0eSBmaWxlLiAgVGhlIG5hbWUKLSAgICogc2hvdWxkIGFscmVhZHkgYmUgZnVsbHkgcXVhbGlmaWVkIGFzIHBhdGgvZmlsZW5hbWUKLSAgICogQHBhcmFtIHRhcmdldCBUaGUgdGFyZ2V0IHByb3BlcnR5IGJhZyB0aGUgZmlsZSB3aWxsIGJlIHBsYWNlZCBpbnRvLgotICAgKi8KLSAgcHVibGljIHZvaWQgbG9hZFByb3BlcnR5RmlsZShTdHJpbmcgZmlsZSwgUHJvcGVydGllcyB0YXJnZXQpCi0gIHsKLSAgICB0cnkKLSAgICB7Ci0gICAgICAvLyBVc2UgU2VjdXJpdHlTdXBwb3J0IGNsYXNzIHRvIHByb3ZpZGUgcHJpdmVsZWdlZCBhY2Nlc3MgdG8gcHJvcGVydHkgZmlsZQotICAgICAgSW5wdXRTdHJlYW0gaXMgPSBTZWN1cml0eVN1cHBvcnQuZ2V0UmVzb3VyY2VBc1N0cmVhbShPYmplY3RGYWN0b3J5LmZpbmRDbGFzc0xvYWRlcigpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGUpOwotCi0gICAgICAvLyBnZXQgYSBidWZmZXJlZCB2ZXJzaW9uCi0gICAgICBCdWZmZXJlZElucHV0U3RyZWFtIGJpcyA9IG5ldyBCdWZmZXJlZElucHV0U3RyZWFtKGlzKTsKLQotICAgICAgdGFyZ2V0LmxvYWQoYmlzKTsgIC8vIGFuZCBsb2FkIHVwIHRoZSBwcm9wZXJ0eSBiYWcgZnJvbSB0aGlzCi0gICAgICBiaXMuY2xvc2UoKTsgIC8vIGNsb3NlIG91dCBhZnRlciByZWFkaW5nCi0gICAgfQotICAgIGNhdGNoIChFeGNlcHRpb24gZXgpCi0gICAgewotICAgICAgLy8gZXgucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICB0aHJvdyBuZXcgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5XcmFwcGVkUnVudGltZUV4Y2VwdGlvbihleCk7Ci0gICAgfQotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2Z1bmN0aW9ucy9GdW5jVHJhbnNsYXRlLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2Z1bmN0aW9ucy9GdW5jVHJhbnNsYXRlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDk4NzgxOTUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9mdW5jdGlvbnMvRnVuY1RyYW5zbGF0ZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTAgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRnVuY1RyYW5zbGF0ZS5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE0IDIwOjE4OjQ1IGplZmZzdXR0b3IgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuZnVuY3Rpb25zOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoQ29udGV4dDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YT2JqZWN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhTdHJpbmc7Ci0KLS8qKgotICogRXhlY3V0ZSB0aGUgVHJhbnNsYXRlKCkgZnVuY3Rpb24uCi0gKiBAeHNsLnVzYWdlIGFkdmFuY2VkCi0gKi8KLXB1YmxpYyBjbGFzcyBGdW5jVHJhbnNsYXRlIGV4dGVuZHMgRnVuY3Rpb24zQXJncwotewotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMTY3MjgzNDM0MDAyNjExNjQ4Mkw7Ci0KLSAgLyoqCi0gICAqIEV4ZWN1dGUgdGhlIGZ1bmN0aW9uLiAgVGhlIGZ1bmN0aW9uIG11c3QgcmV0dXJuCi0gICAqIGEgdmFsaWQgb2JqZWN0LgotICAgKiBAcGFyYW0geGN0eHQgVGhlIGN1cnJlbnQgZXhlY3V0aW9uIGNvbnRleHQuCi0gICAqIEByZXR1cm4gQSB2YWxpZCBYT2JqZWN0LgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IGV4ZWN1dGUoWFBhdGhDb250ZXh0IHhjdHh0KSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBTdHJpbmcgdGhlRmlyc3RTdHJpbmcgPSBtX2FyZzAuZXhlY3V0ZSh4Y3R4dCkuc3RyKCk7Ci0gICAgU3RyaW5nIHRoZVNlY29uZFN0cmluZyA9IG1fYXJnMS5leGVjdXRlKHhjdHh0KS5zdHIoKTsKLSAgICBTdHJpbmcgdGhlVGhpcmRTdHJpbmcgPSBtX2FyZzIuZXhlY3V0ZSh4Y3R4dCkuc3RyKCk7Ci0gICAgaW50IHRoZUZpcnN0U3RyaW5nTGVuZ3RoID0gdGhlRmlyc3RTdHJpbmcubGVuZ3RoKCk7Ci0gICAgaW50IHRoZVRoaXJkU3RyaW5nTGVuZ3RoID0gdGhlVGhpcmRTdHJpbmcubGVuZ3RoKCk7Ci0KLSAgICAvLyBBIHZlY3RvciB0byBjb250YWluIHRoZSBuZXcgY2hhcmFjdGVycy4gIFdlJ2xsIHVzZSBpdCB0byBjb25zdHJ1Y3QKLSAgICAvLyB0aGUgcmVzdWx0IHN0cmluZy4KLSAgICBTdHJpbmdCdWZmZXIgc2J1ZmZlciA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLQotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdGhlRmlyc3RTdHJpbmdMZW5ndGg7IGkrKykKLSAgICB7Ci0gICAgICBjaGFyIHRoZUN1cnJlbnRDaGFyID0gdGhlRmlyc3RTdHJpbmcuY2hhckF0KGkpOwotICAgICAgaW50IHRoZUluZGV4ID0gdGhlU2Vjb25kU3RyaW5nLmluZGV4T2YodGhlQ3VycmVudENoYXIpOwotCi0gICAgICBpZiAodGhlSW5kZXggPCAwKQotICAgICAgewotCi0gICAgICAgIC8vIERpZG4ndCBmaW5kIHRoZSBjaGFyYWN0ZXIgaW4gdGhlIHNlY29uZCBzdHJpbmcsIHNvIGl0Ci0gICAgICAgIC8vIGlzIG5vdCB0cmFuc2xhdGVkLgotICAgICAgICBzYnVmZmVyLmFwcGVuZCh0aGVDdXJyZW50Q2hhcik7Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmICh0aGVJbmRleCA8IHRoZVRoaXJkU3RyaW5nTGVuZ3RoKQotICAgICAgewotCi0gICAgICAgIC8vIE9LLCB0aGVyZSdzIGEgY29ycmVzcG9uZGluZyBjaGFyYWN0ZXIgaW4gdGhlCi0gICAgICAgIC8vIHRoaXJkIHN0cmluZywgc28gZG8gdGhlIHRyYW5zbGF0aW9uLi4uCi0gICAgICAgIHNidWZmZXIuYXBwZW5kKHRoZVRoaXJkU3RyaW5nLmNoYXJBdCh0aGVJbmRleCkpOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotCi0gICAgICAgIC8vIFRoZXJlJ3Mgbm8gY29ycmVzcG9uZGluZyBjaGFyYWN0ZXIgaW4gdGhlCi0gICAgICAgIC8vIHRoaXJkIHN0cmluZywgc2luY2UgaXQncyBzaG9ydGVyIHRoYW4gdGhlCi0gICAgICAgIC8vIHNlY29uZCBzdHJpbmcuICBJbiB0aGlzIGNhc2UsIHRoZSBjaGFyYWN0ZXIKLSAgICAgICAgLy8gaXMgcmVtb3ZlZCBmcm9tIHRoZSBvdXRwdXQgc3RyaW5nLCBzbyBkb24ndAotICAgICAgICAvLyBkbyBhbnl0aGluZy4KLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gbmV3IFhTdHJpbmcoc2J1ZmZlci50b1N0cmluZygpKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9mdW5jdGlvbnMvRnVuY1RydWUuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvZnVuY3Rpb25zL0Z1bmNUcnVlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDljMDliYzUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9mdW5jdGlvbnMvRnVuY1RydWUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDU4ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IEZ1bmNUcnVlLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTQgMjA6MTg6NDQgamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5mdW5jdGlvbnM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuWFBhdGhDb250ZXh0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhCb29sZWFuOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhPYmplY3Q7Ci0KLS8qKgotICogRXhlY3V0ZSB0aGUgVHJ1ZSgpIGZ1bmN0aW9uLgotICogQHhzbC51c2FnZSBhZHZhbmNlZAotICovCi1wdWJsaWMgY2xhc3MgRnVuY1RydWUgZXh0ZW5kcyBGdW5jdGlvbgotewotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA1NjYzMzE0NTQ3MzQ2MzM5NDQ3TDsKLQotICAvKioKLSAgICogRXhlY3V0ZSB0aGUgZnVuY3Rpb24uICBUaGUgZnVuY3Rpb24gbXVzdCByZXR1cm4KLSAgICogYSB2YWxpZCBvYmplY3QuCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgY3VycmVudCBleGVjdXRpb24gY29udGV4dC4KLSAgICogQHJldHVybiBBIHZhbGlkIFhPYmplY3QuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFhPYmplY3QgZXhlY3V0ZShYUGF0aENvbnRleHQgeGN0eHQpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gWEJvb2xlYW4uU19UUlVFOwotICB9Ci0KLSAgLyoqCi0gICAqIE5vIGFyZ3VtZW50cyB0byBwcm9jZXNzLCBzbyB0aGlzIGRvZXMgbm90aGluZy4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGZpeHVwVmFyaWFibGVzKGphdmEudXRpbC5WZWN0b3IgdmFycywgaW50IGdsb2JhbHNTaXplKQotICB7Ci0gICAgLy8gbm8tb3AKLSAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2Z1bmN0aW9ucy9GdW5jVW5wYXJzZWRFbnRpdHlVUkkuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvZnVuY3Rpb25zL0Z1bmNVbnBhcnNlZEVudGl0eVVSSS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhMmE1ODdkLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvZnVuY3Rpb25zL0Z1bmNVbnBhcnNlZEVudGl0eVVSSS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTcgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRnVuY1VucGFyc2VkRW50aXR5VVJJLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTQgMjA6MTg6NDYgamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5mdW5jdGlvbnM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE07Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoQ29udGV4dDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YT2JqZWN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhTdHJpbmc7Ci0KLS8qKgotICogQHhzbC51c2FnZSBhZHZhbmNlZAotICovCi1wdWJsaWMgY2xhc3MgRnVuY1VucGFyc2VkRW50aXR5VVJJIGV4dGVuZHMgRnVuY3Rpb25PbmVBcmcKLXsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gODQ1MzA5NzU5MDk3NDQ4MTc4TDsKLQotICAvKioKLSAgICogRXhlY3V0ZSB0aGUgZnVuY3Rpb24uICBUaGUgZnVuY3Rpb24gbXVzdCByZXR1cm4KLSAgICogYSB2YWxpZCBvYmplY3QuCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgY3VycmVudCBleGVjdXRpb24gY29udGV4dC4KLSAgICogQHJldHVybiBBIHZhbGlkIFhPYmplY3QuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFhPYmplY3QgZXhlY3V0ZShYUGF0aENvbnRleHQgeGN0eHQpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIFN0cmluZyBuYW1lID0gbV9hcmcwLmV4ZWN1dGUoeGN0eHQpLnN0cigpOwotICAgIGludCBjb250ZXh0ID0geGN0eHQuZ2V0Q3VycmVudE5vZGUoKTsKLSAgICBEVE0gZHRtID0geGN0eHQuZ2V0RFRNKGNvbnRleHQpOwotICAgIGludCBkb2MgPSBkdG0uZ2V0RG9jdW1lbnQoKTsKLQotICAgIFN0cmluZyB1cmkgPSBkdG0uZ2V0VW5wYXJzZWRFbnRpdHlVUkkobmFtZSk7Ci0KLSAgICByZXR1cm4gbmV3IFhTdHJpbmcodXJpKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9mdW5jdGlvbnMvRnVuY3Rpb24uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvZnVuY3Rpb25zL0Z1bmN0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDNhYWI5ZWYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9mdW5jdGlvbnMvRnVuY3Rpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE0NiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBGdW5jdGlvbi5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE0IDIwOjE4OjQzIGplZmZzdXR0b3IgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuZnVuY3Rpb25zOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnJlcy5YU0xNZXNzYWdlczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuRXhwcmVzc2lvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuRXhwcmVzc2lvbk93bmVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5YUGF0aENvbnRleHQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoVmlzaXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuY29tcGlsZXIuQ29tcGlsZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWE9iamVjdDsKLQotLyoqCi0gKiBUaGlzIGlzIGEgc3VwZXJjbGFzcyBvZiBhbGwgWFBhdGggZnVuY3Rpb25zLiAgVGhpcyBhbGxvd3MgdHdvCi0gKiB3YXlzIGZvciB0aGUgY2xhc3MgdG8gYmUgY2FsbGVkLiBPbmUgbWV0aG9kIGlzIHRoYXQgdGhlCi0gKiBzdXBlciBjbGFzcyBwcm9jZXNzZXMgdGhlIGFyZ3VtZW50cyBhbmQgaGFuZHMgdGhlIHJlc3VsdHMgdG8KLSAqIHRoZSBkZXJpdmVkIGNsYXNzLCB0aGUgb3RoZXIgbWV0aG9kIGlzIHRoYXQgdGhlIGRlcml2ZWQKLSAqIGNsYXNzIG1heSBwcm9jZXNzIGl0J3Mgb3duIGFyZ3VtZW50cywgd2hpY2ggaXMgZmFzdGVyIHNpbmNlCi0gKiB0aGUgYXJndW1lbnRzIGRvbid0IGhhdmUgdG8gYmUgYWRkZWQgdG8gYW4gYXJyYXksIGJ1dCBjYXVzZXMKLSAqIGEgbGFyZ2VyIGNvZGUgZm9vdHByaW50LgotICogQHhzbC51c2FnZSBhZHZhbmNlZAotICovCi1wdWJsaWMgYWJzdHJhY3QgY2xhc3MgRnVuY3Rpb24gZXh0ZW5kcyBFeHByZXNzaW9uCi17Ci0gICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDY5Mjc2NjEyNDA4NTQ1OTk3NjhMOwotCi0gIC8qKgotICAgKiBTZXQgYW4gYXJndW1lbnQgZXhwcmVzc2lvbiBmb3IgYSBmdW5jdGlvbi4gIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSB0aGUKLSAgICogWFBhdGggY29tcGlsZXIuCi0gICAqCi0gICAqIEBwYXJhbSBhcmcgbm9uLW51bGwgZXhwcmVzc2lvbiB0aGF0IHJlcHJlc2VudHMgdGhlIGFyZ3VtZW50LgotICAgKiBAcGFyYW0gYXJnTnVtIFRoZSBhcmd1bWVudCBudW1iZXIgaW5kZXguCi0gICAqCi0gICAqIEB0aHJvd3MgV3JvbmdOdW1iZXJBcmdzRXhjZXB0aW9uIElmIHRoZSBhcmdOdW0gcGFyYW1ldGVyIGlzIGJleW9uZCB3aGF0Ci0gICAqIGlzIHNwZWNpZmllZCBmb3IgdGhpcyBmdW5jdGlvbi4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldEFyZyhFeHByZXNzaW9uIGFyZywgaW50IGFyZ051bSkKLSAgICAgICAgICB0aHJvd3MgV3JvbmdOdW1iZXJBcmdzRXhjZXB0aW9uCi0gIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRocm93IG5ldyBXcm9uZ051bWJlckFyZ3NFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKCJ6ZXJvIiwgbnVsbCkpOwotICAgICAgcmVwb3J0V3JvbmdOdW1iZXJBcmdzKCk7Ci0gIH0KLQotICAvKioKLSAgICogQ2hlY2sgdGhhdCB0aGUgbnVtYmVyIG9mIGFyZ3VtZW50cyBwYXNzZWQgdG8gdGhpcyBmdW5jdGlvbiBpcyBjb3JyZWN0LgotICAgKiBUaGlzIG1ldGhvZCBpcyBtZWFudCB0byBiZSBvdmVybG9hZGVkIGJ5IGRlcml2ZWQgY2xhc3NlcywgdG8gY2hlY2sgZm9yCi0gICAqIHRoZSBudW1iZXIgb2YgYXJndW1lbnRzIGZvciBhIHNwZWNpZmljIGZ1bmN0aW9uIHR5cGUuICBUaGlzIG1ldGhvZCBpcwotICAgKiBjYWxsZWQgYnkgdGhlIGNvbXBpbGVyIGZvciBzdGF0aWMgbnVtYmVyIG9mIGFyZ3VtZW50cyBjaGVja2luZy4KLSAgICoKLSAgICogQHBhcmFtIGFyZ051bSBUaGUgbnVtYmVyIG9mIGFyZ3VtZW50cyB0aGF0IGlzIGJlaW5nIHBhc3NlZCB0byB0aGUgZnVuY3Rpb24uCi0gICAqCi0gICAqIEB0aHJvd3MgV3JvbmdOdW1iZXJBcmdzRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBjaGVja051bWJlckFyZ3MoaW50IGFyZ051bSkgdGhyb3dzIFdyb25nTnVtYmVyQXJnc0V4Y2VwdGlvbgotICB7Ci0gICAgaWYgKGFyZ051bSAhPSAwKQotICAgICAgcmVwb3J0V3JvbmdOdW1iZXJBcmdzKCk7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0cyBhbmQgdGhyb3dzIGEgV3JvbmdOdW1iZXJBcmdFeGNlcHRpb24gd2l0aCB0aGUgYXBwcm9wcmlhdGUKLSAgICogbWVzc2FnZSBmb3IgdGhpcyBmdW5jdGlvbiBvYmplY3QuICBUaGlzIG1ldGhvZCBpcyBtZWFudCB0byBiZSBvdmVybG9hZGVkCi0gICAqIGJ5IGRlcml2ZWQgY2xhc3NlcyBzbyB0aGF0IHRoZSBtZXNzYWdlIHdpbGwgYmUgYXMgc3BlY2lmaWMgYXMgcG9zc2libGUuCi0gICAqCi0gICAqIEB0aHJvd3MgV3JvbmdOdW1iZXJBcmdzRXhjZXB0aW9uCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCByZXBvcnRXcm9uZ051bWJlckFyZ3MoKSB0aHJvd3MgV3JvbmdOdW1iZXJBcmdzRXhjZXB0aW9uIHsKLSAgICAgIHRocm93IG5ldyBXcm9uZ051bWJlckFyZ3NFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKCJ6ZXJvIiwgbnVsbCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIEV4ZWN1dGUgYW4gWFBhdGggZnVuY3Rpb24gb2JqZWN0LiAgVGhlIGZ1bmN0aW9uIG11c3QgcmV0dXJuCi0gICAqIGEgdmFsaWQgb2JqZWN0LgotICAgKiBAcGFyYW0geGN0eHQgVGhlIGV4ZWN1dGlvbiBjdXJyZW50IGNvbnRleHQuCi0gICAqIEByZXR1cm4gQSB2YWxpZCBYT2JqZWN0LgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IGV4ZWN1dGUoWFBhdGhDb250ZXh0IHhjdHh0KSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICAvLyBQcm9ncmFtbWVyJ3MgYXNzZXJ0LiAgKEFuZCwgbm8sIEkgZG9uJ3Qgd2FudCB0aGUgbWV0aG9kIHRvIGJlIGFic3RyYWN0KS4KLSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkVycm9yISBGdW5jdGlvbi5leGVjdXRlIHNob3VsZCBub3QgYmUgY2FsbGVkISIpOwotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogQ2FsbCB0aGUgdmlzaXRvcnMgZm9yIHRoZSBmdW5jdGlvbiBhcmd1bWVudHMuCi0gICAqLwotICBwdWJsaWMgdm9pZCBjYWxsQXJnVmlzaXRvcnMoWFBhdGhWaXNpdG9yIHZpc2l0b3IpCi0gIHsKLSAgfQotCi0KLSAgLyoqCi0gICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoVmlzaXRhYmxlI2NhbGxWaXNpdG9ycyhFeHByZXNzaW9uT3duZXIsIFhQYXRoVmlzaXRvcikKLSAgICovCi0gIHB1YmxpYyB2b2lkIGNhbGxWaXNpdG9ycyhFeHByZXNzaW9uT3duZXIgb3duZXIsIFhQYXRoVmlzaXRvciB2aXNpdG9yKQotICB7Ci0gICAgICAgIGlmKHZpc2l0b3IudmlzaXRGdW5jdGlvbihvd25lciwgdGhpcykpCi0gICAgICAgIHsKLSAgICAgICAgICAgICAgICBjYWxsQXJnVmlzaXRvcnModmlzaXRvcik7Ci0gICAgICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBAc2VlIEV4cHJlc3Npb24jZGVlcEVxdWFscyhFeHByZXNzaW9uKQotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZGVlcEVxdWFscyhFeHByZXNzaW9uIGV4cHIpCi0gIHsKLSAgICAgICAgaWYoIWlzU2FtZUNsYXNzKGV4cHIpKQotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLQotICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgfQotCi0gIC8qKgotICAgKiBUaGlzIGZ1bmN0aW9uIGlzIGN1cnJlbnRseSBvbmx5IGJlaW5nIHVzZWQgYnkgUG9zaXRpb24oKQotICAgKiBhbmQgTGFzdCgpLiBTZWUgcmVzcGVjdGl2ZSBmdW5jdGlvbnMgZm9yIG1vcmUgZGV0YWlsLgotICAgKi8KLSAgcHVibGljIHZvaWQgcG9zdENvbXBpbGVTdGVwKENvbXBpbGVyIGNvbXBpbGVyKQotICB7Ci0gICAgLy8gbm8gZGVmYXVsdCBhY3Rpb24KLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9mdW5jdGlvbnMvRnVuY3Rpb24yQXJncy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9mdW5jdGlvbnMvRnVuY3Rpb24yQXJncy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2NGY4ZTdmLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvZnVuY3Rpb25zL0Z1bmN0aW9uMkFyZ3MuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE4NiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBGdW5jdGlvbjJBcmdzLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTQgMjA6MTg6NDYgamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5mdW5jdGlvbnM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwucmVzLlhTTE1lc3NhZ2VzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5FeHByZXNzaW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5FeHByZXNzaW9uT3duZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoVmlzaXRvcjsKLQotLyoqCi0gKiBCYXNlIGNsYXNzIGZvciBmdW5jdGlvbnMgdGhhdCBhY2NlcHQgdHdvIGFyZ3VtZW50cy4KLSAqIEB4c2wudXNhZ2UgYWR2YW5jZWQKLSAqLwotcHVibGljIGNsYXNzIEZ1bmN0aW9uMkFyZ3MgZXh0ZW5kcyBGdW5jdGlvbk9uZUFyZwotewotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA1NTc0Mjk0OTk2ODQyNzEwNjQxTDsKLQotICAvKiogVGhlIHNlY29uZCBhcmd1bWVudCBwYXNzZWQgdG8gdGhlIGZ1bmN0aW9uIChhdCBpbmRleCAxKS4KLSAgICogIEBzZXJpYWwgICovCi0gIEV4cHJlc3Npb24gbV9hcmcxOwotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIHNlY29uZCBhcmd1bWVudCBwYXNzZWQgdG8gdGhlIGZ1bmN0aW9uIChhdCBpbmRleCAxKS4KLSAgICoKLSAgICogQHJldHVybiBBbiBleHByZXNzaW9uIHRoYXQgcmVwcmVzZW50cyB0aGUgc2Vjb25kIGFyZ3VtZW50IHBhc3NlZCB0byB0aGUKLSAgICogICAgICAgICBmdW5jdGlvbi4KLSAgICovCi0gIHB1YmxpYyBFeHByZXNzaW9uIGdldEFyZzEoKQotICB7Ci0gICAgcmV0dXJuIG1fYXJnMTsKLSAgfQotCi0gIC8qKgotICAgKiBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgdG8gZml4dXAgdmFyaWFibGVzIGZyb20gUU5hbWVzIHRvIHN0YWNrIGZyYW1lCi0gICAqIGluZGV4ZXMgYXQgc3R5bGVzaGVldCBidWlsZCB0aW1lLgotICAgKiBAcGFyYW0gdmFycyBMaXN0IG9mIFFOYW1lcyB0aGF0IGNvcnJlc3BvbmQgdG8gdmFyaWFibGVzLiAgVGhpcyBsaXN0Ci0gICAqIHNob3VsZCBiZSBzZWFyY2hlZCBiYWNrd2FyZHMgZm9yIHRoZSBmaXJzdCBxdWFsaWZpZWQgbmFtZSB0aGF0Ci0gICAqIGNvcnJlc3BvbmRzIHRvIHRoZSB2YXJpYWJsZSByZWZlcmVuY2UgcW5hbWUuICBUaGUgcG9zaXRpb24gb2YgdGhlCi0gICAqIFFOYW1lIGluIHRoZSB2ZWN0b3IgZnJvbSB0aGUgc3RhcnQgb2YgdGhlIHZlY3RvciB3aWxsIGJlIGl0cyBwb3NpdGlvbgotICAgKiBpbiB0aGUgc3RhY2sgZnJhbWUgKGJ1dCB2YXJpYWJsZXMgYWJvdmUgdGhlIGdsb2JhbHNUb3AgdmFsdWUgd2lsbCBuZWVkCi0gICAqIHRvIGJlIG9mZnNldCB0byB0aGUgY3VycmVudCBzdGFjayBmcmFtZSkuCi0gICAqLwotICBwdWJsaWMgdm9pZCBmaXh1cFZhcmlhYmxlcyhqYXZhLnV0aWwuVmVjdG9yIHZhcnMsIGludCBnbG9iYWxzU2l6ZSkKLSAgewotICAgIHN1cGVyLmZpeHVwVmFyaWFibGVzKHZhcnMsIGdsb2JhbHNTaXplKTsKLSAgICBpZihudWxsICE9IG1fYXJnMSkKLSAgICAgIG1fYXJnMS5maXh1cFZhcmlhYmxlcyh2YXJzLCBnbG9iYWxzU2l6ZSk7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBTZXQgYW4gYXJndW1lbnQgZXhwcmVzc2lvbiBmb3IgYSBmdW5jdGlvbi4gIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSB0aGUKLSAgICogWFBhdGggY29tcGlsZXIuCi0gICAqCi0gICAqIEBwYXJhbSBhcmcgbm9uLW51bGwgZXhwcmVzc2lvbiB0aGF0IHJlcHJlc2VudHMgdGhlIGFyZ3VtZW50LgotICAgKiBAcGFyYW0gYXJnTnVtIFRoZSBhcmd1bWVudCBudW1iZXIgaW5kZXguCi0gICAqCi0gICAqIEB0aHJvd3MgV3JvbmdOdW1iZXJBcmdzRXhjZXB0aW9uIElmIHRoZSBhcmdOdW0gcGFyYW1ldGVyIGlzIGdyZWF0ZXIgdGhhbiAxLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0QXJnKEV4cHJlc3Npb24gYXJnLCBpbnQgYXJnTnVtKQotICAgICAgICAgIHRocm93cyBXcm9uZ051bWJlckFyZ3NFeGNlcHRpb24KLSAgewotCi0gICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJhcmdOdW06ICIrYXJnTnVtKTsKLSAgICBpZiAoYXJnTnVtID09IDApCi0gICAgICBzdXBlci5zZXRBcmcoYXJnLCBhcmdOdW0pOwotICAgIGVsc2UgaWYgKDEgPT0gYXJnTnVtKQotICAgIHsKLSAgICAgIG1fYXJnMSA9IGFyZzsKLSAgICAgIGFyZy5leHByU2V0UGFyZW50KHRoaXMpOwotICAgIH0KLSAgICBlbHNlCi0gICAgICAgICAgICAgICAgICByZXBvcnRXcm9uZ051bWJlckFyZ3MoKTsKLSAgfQotCi0gIC8qKgotICAgKiBDaGVjayB0aGF0IHRoZSBudW1iZXIgb2YgYXJndW1lbnRzIHBhc3NlZCB0byB0aGlzIGZ1bmN0aW9uIGlzIGNvcnJlY3QuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBhcmdOdW0gVGhlIG51bWJlciBvZiBhcmd1bWVudHMgdGhhdCBpcyBiZWluZyBwYXNzZWQgdG8gdGhlIGZ1bmN0aW9uLgotICAgKgotICAgKiBAdGhyb3dzIFdyb25nTnVtYmVyQXJnc0V4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgY2hlY2tOdW1iZXJBcmdzKGludCBhcmdOdW0pIHRocm93cyBXcm9uZ051bWJlckFyZ3NFeGNlcHRpb24KLSAgewotICAgIGlmIChhcmdOdW0gIT0gMikKLSAgICAgIHJlcG9ydFdyb25nTnVtYmVyQXJncygpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdHMgYW5kIHRocm93cyBhIFdyb25nTnVtYmVyQXJnRXhjZXB0aW9uIHdpdGggdGhlIGFwcHJvcHJpYXRlCi0gICAqIG1lc3NhZ2UgZm9yIHRoaXMgZnVuY3Rpb24gb2JqZWN0LgotICAgKgotICAgKiBAdGhyb3dzIFdyb25nTnVtYmVyQXJnc0V4Y2VwdGlvbgotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgcmVwb3J0V3JvbmdOdW1iZXJBcmdzKCkgdGhyb3dzIFdyb25nTnVtYmVyQXJnc0V4Y2VwdGlvbiB7Ci0gICAgICB0aHJvdyBuZXcgV3JvbmdOdW1iZXJBcmdzRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZSgidHdvIiwgbnVsbCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgdGhpcyBleHByZXNzaW9uIG9yIGl0J3Mgc3ViZXhwcmVzc2lvbnMgY2FuIHRyYXZlcnNlIG91dHNpZGUKLSAgICogdGhlIGN1cnJlbnQgc3VidHJlZS4KLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHRyYXZlcnNhbCBvdXRzaWRlIHRoZSBjb250ZXh0IG5vZGUncyBzdWJ0cmVlIGNhbiBvY2N1ci4KLSAgICovCi0gICBwdWJsaWMgYm9vbGVhbiBjYW5UcmF2ZXJzZU91dHNpZGVTdWJ0cmVlKCkKLSAgIHsKLSAgICByZXR1cm4gc3VwZXIuY2FuVHJhdmVyc2VPdXRzaWRlU3VidHJlZSgpCi0gICAgPyB0cnVlIDogbV9hcmcxLmNhblRyYXZlcnNlT3V0c2lkZVN1YnRyZWUoKTsKLSAgIH0KLQotICBjbGFzcyBBcmcxT3duZXIgaW1wbGVtZW50cyBFeHByZXNzaW9uT3duZXIKLSAgewotICAgIC8qKgotICAgICAqIEBzZWUgRXhwcmVzc2lvbk93bmVyI2dldEV4cHJlc3Npb24oKQotICAgICAqLwotICAgIHB1YmxpYyBFeHByZXNzaW9uIGdldEV4cHJlc3Npb24oKQotICAgIHsKLSAgICAgIHJldHVybiBtX2FyZzE7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBAc2VlIEV4cHJlc3Npb25Pd25lciNzZXRFeHByZXNzaW9uKEV4cHJlc3Npb24pCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RXhwcmVzc2lvbihFeHByZXNzaW9uIGV4cCkKLSAgICB7Ci0gICAgICAgIGV4cC5leHByU2V0UGFyZW50KEZ1bmN0aW9uMkFyZ3MudGhpcyk7Ci0gICAgICAgIG1fYXJnMSA9IGV4cDsKLSAgICB9Ci0gIH0KLQotCi0gIC8qKgotICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5YUGF0aFZpc2l0YWJsZSNjYWxsVmlzaXRvcnMoRXhwcmVzc2lvbk93bmVyLCBYUGF0aFZpc2l0b3IpCi0gICAqLwotICBwdWJsaWMgdm9pZCBjYWxsQXJnVmlzaXRvcnMoWFBhdGhWaXNpdG9yIHZpc2l0b3IpCi0gIHsKLSAgICAgICAgc3VwZXIuY2FsbEFyZ1Zpc2l0b3JzKHZpc2l0b3IpOwotICAgICAgICBpZihudWxsICE9IG1fYXJnMSkKLSAgICAgICAgICAgICAgICBtX2FyZzEuY2FsbFZpc2l0b3JzKG5ldyBBcmcxT3duZXIoKSwgdmlzaXRvcik7Ci0gIH0KLQotICAvKioKLSAgICogQHNlZSBFeHByZXNzaW9uI2RlZXBFcXVhbHMoRXhwcmVzc2lvbikKLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGRlZXBFcXVhbHMoRXhwcmVzc2lvbiBleHByKQotICB7Ci0gICAgICAgIGlmKCFzdXBlci5kZWVwRXF1YWxzKGV4cHIpKQotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLQotICAgICAgICBpZihudWxsICE9IG1fYXJnMSkKLSAgICAgICAgewotICAgICAgICAgICAgICAgIGlmKG51bGwgPT0gKChGdW5jdGlvbjJBcmdzKWV4cHIpLm1fYXJnMSkKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLQotICAgICAgICAgICAgICAgIGlmKCFtX2FyZzEuZGVlcEVxdWFscygoKEZ1bmN0aW9uMkFyZ3MpZXhwcikubV9hcmcxKSkKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmKG51bGwgIT0gKChGdW5jdGlvbjJBcmdzKWV4cHIpLm1fYXJnMSkKLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0KLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9mdW5jdGlvbnMvRnVuY3Rpb24zQXJncy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9mdW5jdGlvbnMvRnVuY3Rpb24zQXJncy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmZDc1Nzg0Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvZnVuY3Rpb25zL0Z1bmN0aW9uM0FyZ3MuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE4NSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBGdW5jdGlvbjNBcmdzLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTQgMjA6MTg6NDIgamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5mdW5jdGlvbnM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwucmVzLlhTTE1lc3NhZ2VzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5FeHByZXNzaW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5FeHByZXNzaW9uT3duZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoVmlzaXRvcjsKLQotLyoqCi0gKiBCYXNlIGNsYXNzIGZvciBmdW5jdGlvbnMgdGhhdCBhY2NlcHQgdGhyZWUgYXJndW1lbnRzLgotICogQHhzbC51c2FnZSBhZHZhbmNlZAotICovCi1wdWJsaWMgY2xhc3MgRnVuY3Rpb24zQXJncyBleHRlbmRzIEZ1bmN0aW9uMkFyZ3MKLXsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNzkxNTI0MDc0NzE2MTUwNjY0Nkw7Ci0KLSAgLyoqIFRoZSB0aGlyZCBhcmd1bWVudCBwYXNzZWQgdG8gdGhlIGZ1bmN0aW9uIChhdCBpbmRleCAyKS4KLSAgICogIEBzZXJpYWwgICovCi0gIEV4cHJlc3Npb24gbV9hcmcyOwotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIHRoaXJkIGFyZ3VtZW50IHBhc3NlZCB0byB0aGUgZnVuY3Rpb24gKGF0IGluZGV4IDIpLgotICAgKgotICAgKiBAcmV0dXJuIEFuIGV4cHJlc3Npb24gdGhhdCByZXByZXNlbnRzIHRoZSB0aGlyZCBhcmd1bWVudCBwYXNzZWQgdG8gdGhlCi0gICAqICAgICAgICAgZnVuY3Rpb24uCi0gICAqLwotICBwdWJsaWMgRXhwcmVzc2lvbiBnZXRBcmcyKCkKLSAgewotICAgIHJldHVybiBtX2FyZzI7Ci0gIH0KLQotICAvKioKLSAgICogVGhpcyBmdW5jdGlvbiBpcyB1c2VkIHRvIGZpeHVwIHZhcmlhYmxlcyBmcm9tIFFOYW1lcyB0byBzdGFjayBmcmFtZQotICAgKiBpbmRleGVzIGF0IHN0eWxlc2hlZXQgYnVpbGQgdGltZS4KLSAgICogQHBhcmFtIHZhcnMgTGlzdCBvZiBRTmFtZXMgdGhhdCBjb3JyZXNwb25kIHRvIHZhcmlhYmxlcy4gIFRoaXMgbGlzdAotICAgKiBzaG91bGQgYmUgc2VhcmNoZWQgYmFja3dhcmRzIGZvciB0aGUgZmlyc3QgcXVhbGlmaWVkIG5hbWUgdGhhdAotICAgKiBjb3JyZXNwb25kcyB0byB0aGUgdmFyaWFibGUgcmVmZXJlbmNlIHFuYW1lLiAgVGhlIHBvc2l0aW9uIG9mIHRoZQotICAgKiBRTmFtZSBpbiB0aGUgdmVjdG9yIGZyb20gdGhlIHN0YXJ0IG9mIHRoZSB2ZWN0b3Igd2lsbCBiZSBpdHMgcG9zaXRpb24KLSAgICogaW4gdGhlIHN0YWNrIGZyYW1lIChidXQgdmFyaWFibGVzIGFib3ZlIHRoZSBnbG9iYWxzVG9wIHZhbHVlIHdpbGwgbmVlZAotICAgKiB0byBiZSBvZmZzZXQgdG8gdGhlIGN1cnJlbnQgc3RhY2sgZnJhbWUpLgotICAgKi8KLSAgcHVibGljIHZvaWQgZml4dXBWYXJpYWJsZXMoamF2YS51dGlsLlZlY3RvciB2YXJzLCBpbnQgZ2xvYmFsc1NpemUpCi0gIHsKLSAgICBzdXBlci5maXh1cFZhcmlhYmxlcyh2YXJzLCBnbG9iYWxzU2l6ZSk7Ci0gICAgaWYobnVsbCAhPSBtX2FyZzIpCi0gICAgICBtX2FyZzIuZml4dXBWYXJpYWJsZXModmFycywgZ2xvYmFsc1NpemUpOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCBhbiBhcmd1bWVudCBleHByZXNzaW9uIGZvciBhIGZ1bmN0aW9uLiAgVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZQotICAgKiBYUGF0aCBjb21waWxlci4KLSAgICoKLSAgICogQHBhcmFtIGFyZyBub24tbnVsbCBleHByZXNzaW9uIHRoYXQgcmVwcmVzZW50cyB0aGUgYXJndW1lbnQuCi0gICAqIEBwYXJhbSBhcmdOdW0gVGhlIGFyZ3VtZW50IG51bWJlciBpbmRleC4KLSAgICoKLSAgICogQHRocm93cyBXcm9uZ051bWJlckFyZ3NFeGNlcHRpb24gSWYgdGhlIGFyZ051bSBwYXJhbWV0ZXIgaXMgZ3JlYXRlciB0aGFuIDIuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRBcmcoRXhwcmVzc2lvbiBhcmcsIGludCBhcmdOdW0pCi0gICAgICAgICAgdGhyb3dzIFdyb25nTnVtYmVyQXJnc0V4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAoYXJnTnVtIDwgMikKLSAgICAgIHN1cGVyLnNldEFyZyhhcmcsIGFyZ051bSk7Ci0gICAgZWxzZSBpZiAoMiA9PSBhcmdOdW0pCi0gICAgewotICAgICAgbV9hcmcyID0gYXJnOwotICAgICAgYXJnLmV4cHJTZXRQYXJlbnQodGhpcyk7Ci0gICAgfQotICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgIHJlcG9ydFdyb25nTnVtYmVyQXJncygpOwotICB9Ci0KLSAgLyoqCi0gICAqIENoZWNrIHRoYXQgdGhlIG51bWJlciBvZiBhcmd1bWVudHMgcGFzc2VkIHRvIHRoaXMgZnVuY3Rpb24gaXMgY29ycmVjdC4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIGFyZ051bSBUaGUgbnVtYmVyIG9mIGFyZ3VtZW50cyB0aGF0IGlzIGJlaW5nIHBhc3NlZCB0byB0aGUgZnVuY3Rpb24uCi0gICAqCi0gICAqIEB0aHJvd3MgV3JvbmdOdW1iZXJBcmdzRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBjaGVja051bWJlckFyZ3MoaW50IGFyZ051bSkgdGhyb3dzIFdyb25nTnVtYmVyQXJnc0V4Y2VwdGlvbgotICB7Ci0gICAgaWYgKGFyZ051bSAhPSAzKQotICAgICAgcmVwb3J0V3JvbmdOdW1iZXJBcmdzKCk7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0cyBhbmQgdGhyb3dzIGEgV3JvbmdOdW1iZXJBcmdFeGNlcHRpb24gd2l0aCB0aGUgYXBwcm9wcmlhdGUKLSAgICogbWVzc2FnZSBmb3IgdGhpcyBmdW5jdGlvbiBvYmplY3QuCi0gICAqCi0gICAqIEB0aHJvd3MgV3JvbmdOdW1iZXJBcmdzRXhjZXB0aW9uCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCByZXBvcnRXcm9uZ051bWJlckFyZ3MoKSB0aHJvd3MgV3JvbmdOdW1iZXJBcmdzRXhjZXB0aW9uIHsKLSAgICAgIHRocm93IG5ldyBXcm9uZ051bWJlckFyZ3NFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKCJ0aHJlZSIsIG51bGwpKTsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIGlmIHRoaXMgZXhwcmVzc2lvbiBvciBpdCdzIHN1YmV4cHJlc3Npb25zIGNhbiB0cmF2ZXJzZSBvdXRzaWRlCi0gICAqIHRoZSBjdXJyZW50IHN1YnRyZWUuCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0cmF2ZXJzYWwgb3V0c2lkZSB0aGUgY29udGV4dCBub2RlJ3Mgc3VidHJlZSBjYW4gb2NjdXIuCi0gICAqLwotICAgcHVibGljIGJvb2xlYW4gY2FuVHJhdmVyc2VPdXRzaWRlU3VidHJlZSgpCi0gICB7Ci0gICAgcmV0dXJuIHN1cGVyLmNhblRyYXZlcnNlT3V0c2lkZVN1YnRyZWUoKQotICAgID8gdHJ1ZSA6IG1fYXJnMi5jYW5UcmF2ZXJzZU91dHNpZGVTdWJ0cmVlKCk7Ci0gICB9Ci0KLSAgY2xhc3MgQXJnMk93bmVyIGltcGxlbWVudHMgRXhwcmVzc2lvbk93bmVyCi0gIHsKLSAgICAvKioKLSAgICAgKiBAc2VlIEV4cHJlc3Npb25Pd25lciNnZXRFeHByZXNzaW9uKCkKLSAgICAgKi8KLSAgICBwdWJsaWMgRXhwcmVzc2lvbiBnZXRFeHByZXNzaW9uKCkKLSAgICB7Ci0gICAgICByZXR1cm4gbV9hcmcyOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogQHNlZSBFeHByZXNzaW9uT3duZXIjc2V0RXhwcmVzc2lvbihFeHByZXNzaW9uKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEV4cHJlc3Npb24oRXhwcmVzc2lvbiBleHApCi0gICAgewotICAgICAgICBleHAuZXhwclNldFBhcmVudChGdW5jdGlvbjNBcmdzLnRoaXMpOwotICAgICAgICBtX2FyZzIgPSBleHA7Ci0gICAgfQotICB9Ci0KLQotICAvKioKLSAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuWFBhdGhWaXNpdGFibGUjY2FsbFZpc2l0b3JzKEV4cHJlc3Npb25Pd25lciwgWFBhdGhWaXNpdG9yKQotICAgKi8KLSAgcHVibGljIHZvaWQgY2FsbEFyZ1Zpc2l0b3JzKFhQYXRoVmlzaXRvciB2aXNpdG9yKQotICB7Ci0gICAgICAgIHN1cGVyLmNhbGxBcmdWaXNpdG9ycyh2aXNpdG9yKTsKLSAgICAgICAgaWYobnVsbCAhPSBtX2FyZzIpCi0gICAgICAgICAgICAgICAgbV9hcmcyLmNhbGxWaXNpdG9ycyhuZXcgQXJnMk93bmVyKCksIHZpc2l0b3IpOwotICB9Ci0KLSAgLyoqCi0gICAqIEBzZWUgRXhwcmVzc2lvbiNkZWVwRXF1YWxzKEV4cHJlc3Npb24pCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBkZWVwRXF1YWxzKEV4cHJlc3Npb24gZXhwcikKLSAgewotICAgICAgICBpZighc3VwZXIuZGVlcEVxdWFscyhleHByKSkKLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0KLSAgICAgICAgaWYobnVsbCAhPSBtX2FyZzIpCi0gICAgICAgIHsKLSAgICAgICAgICAgICAgICBpZihudWxsID09ICgoRnVuY3Rpb24zQXJncylleHByKS5tX2FyZzIpCi0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0KLSAgICAgICAgICAgICAgICBpZighbV9hcmcyLmRlZXBFcXVhbHMoKChGdW5jdGlvbjNBcmdzKWV4cHIpLm1fYXJnMikpCi0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAobnVsbCAhPSAoKEZ1bmN0aW9uM0FyZ3MpZXhwcikubV9hcmcyKQotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLQotICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgfQotCi0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvZnVuY3Rpb25zL0Z1bmN0aW9uRGVmMUFyZy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9mdW5jdGlvbnMvRnVuY3Rpb25EZWYxQXJnLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAxNTc0ZmEuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9mdW5jdGlvbnMvRnVuY3Rpb25EZWYxQXJnLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNjkgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogRnVuY3Rpb25EZWYxQXJnLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTQgMjA6MTg6NDIgamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5mdW5jdGlvbnM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwucmVzLlhTTE1lc3NhZ2VzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLlhNTFN0cmluZzsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuWFBhdGhDb250ZXh0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhTdHJpbmc7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLnJlcy5YUEFUSEVycm9yUmVzb3VyY2VzOwotCi0vKioKLSAqIEJhc2UgY2xhc3MgZm9yIGZ1bmN0aW9ucyB0aGF0IGFjY2VwdCBvbmUgYXJndW1lbnQgdGhhdCBjYW4gYmUgZGVmYXVsdGVkIGlmCi0gKiBub3Qgc3BlY2lmaWVkLgotICogQHhzbC51c2FnZSBhZHZhbmNlZAotICovCi1wdWJsaWMgY2xhc3MgRnVuY3Rpb25EZWYxQXJnIGV4dGVuZHMgRnVuY3Rpb25PbmVBcmcKLXsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMjMyNTE4OTQxMjgxNDE0OTI2NEw7Ci0KLSAgLyoqCi0gICAqIEV4ZWN1dGUgdGhlIGZpcnN0IGFyZ3VtZW50IGV4cHJlc3Npb24gdGhhdCBpcyBleHBlY3RlZCB0byByZXR1cm4gYQotICAgKiBub2Rlc2V0LiAgSWYgdGhlIGFyZ3VtZW50IGlzIG51bGwsIHRoZW4gcmV0dXJuIHRoZSBjdXJyZW50IGNvbnRleHQgbm9kZS4KLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IFJ1bnRpbWUgWFBhdGggY29udGV4dC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgZmlyc3Qgbm9kZSBvZiB0aGUgZXhlY3V0ZWQgbm9kZXNldCwgb3IgdGhlIGN1cnJlbnQgY29udGV4dAotICAgKiAgICAgICAgIG5vZGUgaWYgdGhlIGZpcnN0IGFyZ3VtZW50IGlzIG51bGwuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbiBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUKLSAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4ZWN1dGluZyB0aGUgYXJndW1lbnQgZXhwcmVzc2lvbi4KLSAgICovCi0gIHByb3RlY3RlZCBpbnQgZ2V0QXJnMEFzTm9kZShYUGF0aENvbnRleHQgeGN0eHQpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgcmV0dXJuIChudWxsID09IG1fYXJnMCkKLSAgICAgICAgICAgPyB4Y3R4dC5nZXRDdXJyZW50Tm9kZSgpIDogbV9hcmcwLmFzTm9kZSh4Y3R4dCk7Ci0gIH0KLQotICAvKioKLSAgICogVGVsbCBpZiB0aGUgZXhwcmVzc2lvbiBpcyBhIG5vZGVzZXQgZXhwcmVzc2lvbi4KLSAgICogQHJldHVybiB0cnVlIGlmIHRoZSBleHByZXNzaW9uIGNhbiBiZSByZXByZXNlbnRlZCBhcyBhIG5vZGVzZXQuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBBcmcwSXNOb2Rlc2V0RXhwcigpCi0gIHsKLSAgICByZXR1cm4gKG51bGwgPT0gbV9hcmcwKSA/IHRydWUgOiBtX2FyZzAuaXNOb2Rlc2V0RXhwcigpOwotICB9Ci0KLSAgLyoqCi0gICAqIEV4ZWN1dGUgdGhlIGZpcnN0IGFyZ3VtZW50IGV4cHJlc3Npb24gdGhhdCBpcyBleHBlY3RlZCB0byByZXR1cm4gYQotICAgKiBzdHJpbmcuICBJZiB0aGUgYXJndW1lbnQgaXMgbnVsbCwgdGhlbiBnZXQgdGhlIHN0cmluZyB2YWx1ZSBmcm9tIHRoZQotICAgKiBjdXJyZW50IGNvbnRleHQgbm9kZS4KLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IFJ1bnRpbWUgWFBhdGggY29udGV4dC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgc3RyaW5nIHZhbHVlIG9mIHRoZSBmaXJzdCBhcmd1bWVudCwgb3IgdGhlIHN0cmluZyB2YWx1ZSBvZiB0aGUKLSAgICogICAgICAgICBjdXJyZW50IGNvbnRleHQgbm9kZSBpZiB0aGUgZmlyc3QgYXJndW1lbnQgaXMgbnVsbC4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZQotICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhlY3V0aW5nIHRoZSBhcmd1bWVudCBleHByZXNzaW9uLgotICAgKi8KLSAgcHJvdGVjdGVkIFhNTFN0cmluZyBnZXRBcmcwQXNTdHJpbmcoWFBhdGhDb250ZXh0IHhjdHh0KQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICBpZihudWxsID09IG1fYXJnMCkKLSAgICB7Ci0gICAgICBpbnQgY3VycmVudE5vZGUgPSB4Y3R4dC5nZXRDdXJyZW50Tm9kZSgpOwotICAgICAgaWYoRFRNLk5VTEwgPT0gY3VycmVudE5vZGUpCi0gICAgICAgIHJldHVybiBYU3RyaW5nLkVNUFRZU1RSSU5HOwotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBEVE0gZHRtID0geGN0eHQuZ2V0RFRNKGN1cnJlbnROb2RlKTsKLSAgICAgICAgcmV0dXJuIGR0bS5nZXRTdHJpbmdWYWx1ZShjdXJyZW50Tm9kZSk7Ci0gICAgICB9Ci0KLSAgICB9Ci0gICAgZWxzZQotICAgICAgcmV0dXJuIG1fYXJnMC5leGVjdXRlKHhjdHh0KS54c3RyKCk7Ci0gIH0KLQotICAvKioKLSAgICogRXhlY3V0ZSB0aGUgZmlyc3QgYXJndW1lbnQgZXhwcmVzc2lvbiB0aGF0IGlzIGV4cGVjdGVkIHRvIHJldHVybiBhCi0gICAqIG51bWJlci4gIElmIHRoZSBhcmd1bWVudCBpcyBudWxsLCB0aGVuIGdldCB0aGUgbnVtYmVyIHZhbHVlIGZyb20gdGhlCi0gICAqIGN1cnJlbnQgY29udGV4dCBub2RlLgotICAgKgotICAgKiBAcGFyYW0geGN0eHQgUnVudGltZSBYUGF0aCBjb250ZXh0LgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBudW1iZXIgdmFsdWUgb2YgdGhlIGZpcnN0IGFyZ3VtZW50LCBvciB0aGUgbnVtYmVyIHZhbHVlIG9mIHRoZQotICAgKiAgICAgICAgIGN1cnJlbnQgY29udGV4dCBub2RlIGlmIHRoZSBmaXJzdCBhcmd1bWVudCBpcyBudWxsLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24gaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlCi0gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleGVjdXRpbmcgdGhlIGFyZ3VtZW50IGV4cHJlc3Npb24uCi0gICAqLwotICBwcm90ZWN0ZWQgZG91YmxlIGdldEFyZzBBc051bWJlcihYUGF0aENvbnRleHQgeGN0eHQpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaWYobnVsbCA9PSBtX2FyZzApCi0gICAgewotICAgICAgaW50IGN1cnJlbnROb2RlID0geGN0eHQuZ2V0Q3VycmVudE5vZGUoKTsKLSAgICAgIGlmKERUTS5OVUxMID09IGN1cnJlbnROb2RlKQotICAgICAgICByZXR1cm4gMDsKLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgRFRNIGR0bSA9IHhjdHh0LmdldERUTShjdXJyZW50Tm9kZSk7Ci0gICAgICAgIFhNTFN0cmluZyBzdHIgPSBkdG0uZ2V0U3RyaW5nVmFsdWUoY3VycmVudE5vZGUpOwotICAgICAgICByZXR1cm4gc3RyLnRvRG91YmxlKCk7Ci0gICAgICB9Ci0KLSAgICB9Ci0gICAgZWxzZQotICAgICAgcmV0dXJuIG1fYXJnMC5leGVjdXRlKHhjdHh0KS5udW0oKTsKLSAgfQotCi0gIC8qKgotICAgKiBDaGVjayB0aGF0IHRoZSBudW1iZXIgb2YgYXJndW1lbnRzIHBhc3NlZCB0byB0aGlzIGZ1bmN0aW9uIGlzIGNvcnJlY3QuCi0gICAqCi0gICAqIEBwYXJhbSBhcmdOdW0gVGhlIG51bWJlciBvZiBhcmd1bWVudHMgdGhhdCBpcyBiZWluZyBwYXNzZWQgdG8gdGhlIGZ1bmN0aW9uLgotICAgKgotICAgKiBAdGhyb3dzIFdyb25nTnVtYmVyQXJnc0V4Y2VwdGlvbiBpZiB0aGUgbnVtYmVyIG9mIGFyZ3VtZW50cyBpcyBub3QgMCBvciAxLgotICAgKi8KLSAgcHVibGljIHZvaWQgY2hlY2tOdW1iZXJBcmdzKGludCBhcmdOdW0pIHRocm93cyBXcm9uZ051bWJlckFyZ3NFeGNlcHRpb24KLSAgewotICAgIGlmIChhcmdOdW0gPiAxKQotICAgICAgcmVwb3J0V3JvbmdOdW1iZXJBcmdzKCk7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0cyBhbmQgdGhyb3dzIGEgV3JvbmdOdW1iZXJBcmdFeGNlcHRpb24gd2l0aCB0aGUgYXBwcm9wcmlhdGUKLSAgICogbWVzc2FnZSBmb3IgdGhpcyBmdW5jdGlvbiBvYmplY3QuCi0gICAqCi0gICAqIEB0aHJvd3MgV3JvbmdOdW1iZXJBcmdzRXhjZXB0aW9uCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCByZXBvcnRXcm9uZ051bWJlckFyZ3MoKSB0aHJvd3MgV3JvbmdOdW1iZXJBcmdzRXhjZXB0aW9uIHsKLSAgICAgIHRocm93IG5ldyBXcm9uZ051bWJlckFyZ3NFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfWkVST19PUl9PTkUsIG51bGwpKTsgLy8iMCBvciAxIik7Ci0gIH0KLQotICAvKioKLSAgICogVGVsbCBpZiB0aGlzIGV4cHJlc3Npb24gb3IgaXQncyBzdWJleHByZXNzaW9ucyBjYW4gdHJhdmVyc2Ugb3V0c2lkZQotICAgKiB0aGUgY3VycmVudCBzdWJ0cmVlLgotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYgdHJhdmVyc2FsIG91dHNpZGUgdGhlIGNvbnRleHQgbm9kZSdzIHN1YnRyZWUgY2FuIG9jY3VyLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gY2FuVHJhdmVyc2VPdXRzaWRlU3VidHJlZSgpCi0gIHsKLSAgICByZXR1cm4gKG51bGwgPT0gbV9hcmcwKSA/IGZhbHNlIDogc3VwZXIuY2FuVHJhdmVyc2VPdXRzaWRlU3VidHJlZSgpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2Z1bmN0aW9ucy9GdW5jdGlvbk11bHRpQXJncy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9mdW5jdGlvbnMvRnVuY3Rpb25NdWx0aUFyZ3MuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYzc4ZjNhNi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2Z1bmN0aW9ucy9GdW5jdGlvbk11bHRpQXJncy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjM4ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IEZ1bmN0aW9uTXVsdGlBcmdzLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTQgMjA6MTg6NDMgamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5mdW5jdGlvbnM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwucmVzLlhTTE1lc3NhZ2VzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5FeHByZXNzaW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5FeHByZXNzaW9uT3duZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoVmlzaXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucmVzLlhQQVRIRXJyb3JSZXNvdXJjZXM7Ci0KLS8qKgotICogQmFzZSBjbGFzcyBmb3IgZnVuY3Rpb25zIHRoYXQgYWNjZXB0IGFuIHVuZGV0ZXJtaW5lZCBudW1iZXIgb2YgbXVsdGlwbGUKLSAqIGFyZ3VtZW50cy4KLSAqIEB4c2wudXNhZ2UgYWR2YW5jZWQKLSAqLwotcHVibGljIGNsYXNzIEZ1bmN0aW9uTXVsdGlBcmdzIGV4dGVuZHMgRnVuY3Rpb24zQXJncwotewotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA3MTE3MjU3NzQ2MTM4NDE3MTgxTDsKLQotICAvKiogQXJndW1lbnQgZXhwcmVzc2lvbnMgdGhhdCBhcmUgYXQgaW5kZXggMyBvciBncmVhdGVyLgotICAgKiAgQHNlcmlhbCAqLwotICBFeHByZXNzaW9uW10gbV9hcmdzOwotCi0gIC8qKgotICAgKiBSZXR1cm4gYW4gZXhwcmVzc2lvbiBhcnJheSBjb250YWluaW5nIGFyZ3VtZW50cyBhdCBpbmRleCAzIG9yIGdyZWF0ZXIuCi0gICAqCi0gICAqIEByZXR1cm4gQW4gYXJyYXkgdGhhdCBjb250YWlucyB0aGUgYXJndW1lbnRzIGF0IGluZGV4IDMgb3IgZ3JlYXRlci4KLSAgICovCi0gIHB1YmxpYyBFeHByZXNzaW9uW10gZ2V0QXJncygpCi0gIHsKLSAgICByZXR1cm4gbV9hcmdzOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCBhbiBhcmd1bWVudCBleHByZXNzaW9uIGZvciBhIGZ1bmN0aW9uLiAgVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZQotICAgKiBYUGF0aCBjb21waWxlci4KLSAgICoKLSAgICogQHBhcmFtIGFyZyBub24tbnVsbCBleHByZXNzaW9uIHRoYXQgcmVwcmVzZW50cyB0aGUgYXJndW1lbnQuCi0gICAqIEBwYXJhbSBhcmdOdW0gVGhlIGFyZ3VtZW50IG51bWJlciBpbmRleC4KLSAgICoKLSAgICogQHRocm93cyBXcm9uZ051bWJlckFyZ3NFeGNlcHRpb24gSWYgYSBkZXJpdmVkIGNsYXNzIGRldGVybWluZXMgdGhhdCB0aGUKLSAgICogbnVtYmVyIG9mIGFyZ3VtZW50cyBpcyBpbmNvcnJlY3QuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRBcmcoRXhwcmVzc2lvbiBhcmcsIGludCBhcmdOdW0pCi0gICAgICAgICAgdGhyb3dzIFdyb25nTnVtYmVyQXJnc0V4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAoYXJnTnVtIDwgMykKLSAgICAgIHN1cGVyLnNldEFyZyhhcmcsIGFyZ051bSk7Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIGlmIChudWxsID09IG1fYXJncykKLSAgICAgIHsKLSAgICAgICAgbV9hcmdzID0gbmV3IEV4cHJlc3Npb25bMV07Ci0gICAgICAgIG1fYXJnc1swXSA9IGFyZzsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLQotICAgICAgICAvLyBTbG93IGJ1dCBzcGFjZSBjb25zZXJ2YXRpdmUuCi0gICAgICAgIEV4cHJlc3Npb25bXSBhcmdzID0gbmV3IEV4cHJlc3Npb25bbV9hcmdzLmxlbmd0aCArIDFdOwotCi0gICAgICAgIFN5c3RlbS5hcnJheWNvcHkobV9hcmdzLCAwLCBhcmdzLCAwLCBtX2FyZ3MubGVuZ3RoKTsKLQotICAgICAgICBhcmdzW21fYXJncy5sZW5ndGhdID0gYXJnOwotICAgICAgICBtX2FyZ3MgPSBhcmdzOwotICAgICAgfQotICAgICAgYXJnLmV4cHJTZXRQYXJlbnQodGhpcyk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFRoaXMgZnVuY3Rpb24gaXMgdXNlZCB0byBmaXh1cCB2YXJpYWJsZXMgZnJvbSBRTmFtZXMgdG8gc3RhY2sgZnJhbWUKLSAgICogaW5kZXhlcyBhdCBzdHlsZXNoZWV0IGJ1aWxkIHRpbWUuCi0gICAqIEBwYXJhbSB2YXJzIExpc3Qgb2YgUU5hbWVzIHRoYXQgY29ycmVzcG9uZCB0byB2YXJpYWJsZXMuICBUaGlzIGxpc3QKLSAgICogc2hvdWxkIGJlIHNlYXJjaGVkIGJhY2t3YXJkcyBmb3IgdGhlIGZpcnN0IHF1YWxpZmllZCBuYW1lIHRoYXQKLSAgICogY29ycmVzcG9uZHMgdG8gdGhlIHZhcmlhYmxlIHJlZmVyZW5jZSBxbmFtZS4gIFRoZSBwb3NpdGlvbiBvZiB0aGUKLSAgICogUU5hbWUgaW4gdGhlIHZlY3RvciBmcm9tIHRoZSBzdGFydCBvZiB0aGUgdmVjdG9yIHdpbGwgYmUgaXRzIHBvc2l0aW9uCi0gICAqIGluIHRoZSBzdGFjayBmcmFtZSAoYnV0IHZhcmlhYmxlcyBhYm92ZSB0aGUgZ2xvYmFsc1RvcCB2YWx1ZSB3aWxsIG5lZWQKLSAgICogdG8gYmUgb2Zmc2V0IHRvIHRoZSBjdXJyZW50IHN0YWNrIGZyYW1lKS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGZpeHVwVmFyaWFibGVzKGphdmEudXRpbC5WZWN0b3IgdmFycywgaW50IGdsb2JhbHNTaXplKQotICB7Ci0gICAgc3VwZXIuZml4dXBWYXJpYWJsZXModmFycywgZ2xvYmFsc1NpemUpOwotICAgIGlmKG51bGwgIT0gbV9hcmdzKQotICAgIHsKLSAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbV9hcmdzLmxlbmd0aDsgaSsrKQotICAgICAgewotICAgICAgICBtX2FyZ3NbaV0uZml4dXBWYXJpYWJsZXModmFycywgZ2xvYmFsc1NpemUpOwotICAgICAgfQotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBDaGVjayB0aGF0IHRoZSBudW1iZXIgb2YgYXJndW1lbnRzIHBhc3NlZCB0byB0aGlzIGZ1bmN0aW9uIGlzIGNvcnJlY3QuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBhcmdOdW0gVGhlIG51bWJlciBvZiBhcmd1bWVudHMgdGhhdCBpcyBiZWluZyBwYXNzZWQgdG8gdGhlIGZ1bmN0aW9uLgotICAgKgotICAgKiBAdGhyb3dzIFdyb25nTnVtYmVyQXJnc0V4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgY2hlY2tOdW1iZXJBcmdzKGludCBhcmdOdW0pIHRocm93cyBXcm9uZ051bWJlckFyZ3NFeGNlcHRpb257fQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3RzIGFuZCB0aHJvd3MgYSBXcm9uZ051bWJlckFyZ0V4Y2VwdGlvbiB3aXRoIHRoZSBhcHByb3ByaWF0ZQotICAgKiBtZXNzYWdlIGZvciB0aGlzIGZ1bmN0aW9uIG9iamVjdC4gIFRoaXMgY2xhc3Mgc3VwcG9ydHMgYW4gYXJiaXRyYXJ5Ci0gICAqIG51bWJlciBvZiBhcmd1bWVudHMsIHNvIHRoaXMgbWV0aG9kIG11c3QgbmV2ZXIgYmUgY2FsbGVkLgotICAgKgotICAgKiBAdGhyb3dzIFdyb25nTnVtYmVyQXJnc0V4Y2VwdGlvbgotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgcmVwb3J0V3JvbmdOdW1iZXJBcmdzKCkgdGhyb3dzIFdyb25nTnVtYmVyQXJnc0V4Y2VwdGlvbiB7Ci0gICAgU3RyaW5nIGZNc2cgPSBYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoCi0gICAgICAgIFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfSU5DT1JSRUNUX1BST0dSQU1NRVJfQVNTRVJUSU9OLAotICAgICAgICBuZXcgT2JqZWN0W117ICJQcm9ncmFtbWVyJ3MgYXNzZXJ0aW9uOiAgdGhlIG1ldGhvZCBGdW5jdGlvbk11bHRpQXJncy5yZXBvcnRXcm9uZ051bWJlckFyZ3MoKSBzaG91bGQgbmV2ZXIgYmUgY2FsbGVkLiIgfSk7Ci0KLSAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihmTXNnKTsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIGlmIHRoaXMgZXhwcmVzc2lvbiBvciBpdCdzIHN1YmV4cHJlc3Npb25zIGNhbiB0cmF2ZXJzZSBvdXRzaWRlCi0gICAqIHRoZSBjdXJyZW50IHN1YnRyZWUuCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0cmF2ZXJzYWwgb3V0c2lkZSB0aGUgY29udGV4dCBub2RlJ3Mgc3VidHJlZSBjYW4gb2NjdXIuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBjYW5UcmF2ZXJzZU91dHNpZGVTdWJ0cmVlKCkKLSAgewotCi0gICAgaWYgKHN1cGVyLmNhblRyYXZlcnNlT3V0c2lkZVN1YnRyZWUoKSkKLSAgICAgIHJldHVybiB0cnVlOwotICAgIGVsc2UKLSAgICB7Ci0gICAgICBpbnQgbiA9IG1fYXJncy5sZW5ndGg7Ci0KLSAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKQotICAgICAgewotICAgICAgICBpZiAobV9hcmdzW2ldLmNhblRyYXZlcnNlT3V0c2lkZVN1YnRyZWUoKSkKLSAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgIH0KLQotICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLSAgfQotCi0gIGNsYXNzIEFyZ011bHRpT3duZXIgaW1wbGVtZW50cyBFeHByZXNzaW9uT3duZXIKLSAgewotICAgICAgICBpbnQgbV9hcmdJbmRleDsKLQotICAgICAgICBBcmdNdWx0aU93bmVyKGludCBpbmRleCkKLSAgICAgICAgewotICAgICAgICAgICAgICAgIG1fYXJnSW5kZXggPSBpbmRleDsKLSAgICAgICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBFeHByZXNzaW9uT3duZXIjZ2V0RXhwcmVzc2lvbigpCi0gICAgICovCi0gICAgcHVibGljIEV4cHJlc3Npb24gZ2V0RXhwcmVzc2lvbigpCi0gICAgewotICAgICAgcmV0dXJuIG1fYXJnc1ttX2FyZ0luZGV4XTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIEBzZWUgRXhwcmVzc2lvbk93bmVyI3NldEV4cHJlc3Npb24oRXhwcmVzc2lvbikKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRFeHByZXNzaW9uKEV4cHJlc3Npb24gZXhwKQotICAgIHsKLSAgICAgICAgZXhwLmV4cHJTZXRQYXJlbnQoRnVuY3Rpb25NdWx0aUFyZ3MudGhpcyk7Ci0gICAgICAgIG1fYXJnc1ttX2FyZ0luZGV4XSA9IGV4cDsKLSAgICB9Ci0gIH0KLQotCi0gICAgLyoqCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuWFBhdGhWaXNpdGFibGUjY2FsbFZpc2l0b3JzKEV4cHJlc3Npb25Pd25lciwgWFBhdGhWaXNpdG9yKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGNhbGxBcmdWaXNpdG9ycyhYUGF0aFZpc2l0b3IgdmlzaXRvcikKLSAgICB7Ci0gICAgICBzdXBlci5jYWxsQXJnVmlzaXRvcnModmlzaXRvcik7Ci0gICAgICBpZiAobnVsbCAhPSBtX2FyZ3MpCi0gICAgICB7Ci0gICAgICAgIGludCBuID0gbV9hcmdzLmxlbmd0aDsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspCi0gICAgICAgIHsKLSAgICAgICAgICBtX2FyZ3NbaV0uY2FsbFZpc2l0b3JzKG5ldyBBcmdNdWx0aU93bmVyKGkpLCB2aXNpdG9yKTsKLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgRXhwcmVzc2lvbiNkZWVwRXF1YWxzKEV4cHJlc3Npb24pCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZGVlcEVxdWFscyhFeHByZXNzaW9uIGV4cHIpCi0gICAgewotICAgICAgaWYgKCFzdXBlci5kZWVwRXF1YWxzKGV4cHIpKQotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotCi0gICAgICBGdW5jdGlvbk11bHRpQXJncyBmbWEgPSAoRnVuY3Rpb25NdWx0aUFyZ3MpIGV4cHI7Ci0gICAgICBpZiAobnVsbCAhPSBtX2FyZ3MpCi0gICAgICB7Ci0gICAgICAgIGludCBuID0gbV9hcmdzLmxlbmd0aDsKLSAgICAgICAgaWYgKChudWxsID09IGZtYSkgfHwgKGZtYS5tX2FyZ3MubGVuZ3RoICE9IG4pKQotICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0KLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspCi0gICAgICAgIHsKLSAgICAgICAgICBpZiAoIW1fYXJnc1tpXS5kZWVwRXF1YWxzKGZtYS5tX2FyZ3NbaV0pKQotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotCi0gICAgICB9Ci0gICAgICBlbHNlIGlmIChudWxsICE9IGZtYS5tX2FyZ3MpCi0gICAgICB7Ci0gICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgfQotCi0gICAgICByZXR1cm4gdHJ1ZTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2Z1bmN0aW9ucy9GdW5jdGlvbk9uZUFyZy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9mdW5jdGlvbnMvRnVuY3Rpb25PbmVBcmcuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMTJkZWJlNi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2Z1bmN0aW9ucy9GdW5jdGlvbk9uZUFyZy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTc2ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IEZ1bmN0aW9uT25lQXJnLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTQgMjA6MTg6NDUgamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5mdW5jdGlvbnM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwucmVzLlhTTE1lc3NhZ2VzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5FeHByZXNzaW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5FeHByZXNzaW9uT3duZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoVmlzaXRvcjsKLQotLyoqCi0gKiBCYXNlIGNsYXNzIGZvciBmdW5jdGlvbnMgdGhhdCBhY2NlcHQgb25lIGFyZ3VtZW50LgotICogQHhzbC51c2FnZSBhZHZhbmNlZAotICovCi1wdWJsaWMgY2xhc3MgRnVuY3Rpb25PbmVBcmcgZXh0ZW5kcyBGdW5jdGlvbiBpbXBsZW1lbnRzIEV4cHJlc3Npb25Pd25lcgotewotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNTE4MDE3NDE4MDc2NTYwOTc1OEw7Ci0KLSAgLyoqIFRoZSBmaXJzdCBhcmd1bWVudCBwYXNzZWQgdG8gdGhlIGZ1bmN0aW9uIChhdCBpbmRleCAwKS4KLSAgICogIEBzZXJpYWwgICovCi0gIEV4cHJlc3Npb24gbV9hcmcwOwotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIGZpcnN0IGFyZ3VtZW50IHBhc3NlZCB0byB0aGUgZnVuY3Rpb24gKGF0IGluZGV4IDApLgotICAgKgotICAgKiBAcmV0dXJuIEFuIGV4cHJlc3Npb24gdGhhdCByZXByZXNlbnRzIHRoZSBmaXJzdCBhcmd1bWVudCBwYXNzZWQgdG8gdGhlCi0gICAqICAgICAgICAgZnVuY3Rpb24uCi0gICAqLwotICBwdWJsaWMgRXhwcmVzc2lvbiBnZXRBcmcwKCkKLSAgewotICAgIHJldHVybiBtX2FyZzA7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IGFuIGFyZ3VtZW50IGV4cHJlc3Npb24gZm9yIGEgZnVuY3Rpb24uICBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgdGhlCi0gICAqIFhQYXRoIGNvbXBpbGVyLgotICAgKgotICAgKiBAcGFyYW0gYXJnIG5vbi1udWxsIGV4cHJlc3Npb24gdGhhdCByZXByZXNlbnRzIHRoZSBhcmd1bWVudC4KLSAgICogQHBhcmFtIGFyZ051bSBUaGUgYXJndW1lbnQgbnVtYmVyIGluZGV4LgotICAgKgotICAgKiBAdGhyb3dzIFdyb25nTnVtYmVyQXJnc0V4Y2VwdGlvbiBJZiB0aGUgYXJnTnVtIHBhcmFtZXRlciBpcyBncmVhdGVyIHRoYW4gMC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldEFyZyhFeHByZXNzaW9uIGFyZywgaW50IGFyZ051bSkKLSAgICAgICAgICB0aHJvd3MgV3JvbmdOdW1iZXJBcmdzRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmICgwID09IGFyZ051bSkKLSAgICB7Ci0gICAgICBtX2FyZzAgPSBhcmc7Ci0gICAgICBhcmcuZXhwclNldFBhcmVudCh0aGlzKTsKLSAgICB9Ci0gICAgZWxzZQotICAgICAgcmVwb3J0V3JvbmdOdW1iZXJBcmdzKCk7Ci0gIH0KLQotICAvKioKLSAgICogQ2hlY2sgdGhhdCB0aGUgbnVtYmVyIG9mIGFyZ3VtZW50cyBwYXNzZWQgdG8gdGhpcyBmdW5jdGlvbiBpcyBjb3JyZWN0LgotICAgKgotICAgKgotICAgKiBAcGFyYW0gYXJnTnVtIFRoZSBudW1iZXIgb2YgYXJndW1lbnRzIHRoYXQgaXMgYmVpbmcgcGFzc2VkIHRvIHRoZSBmdW5jdGlvbi4KLSAgICoKLSAgICogQHRocm93cyBXcm9uZ051bWJlckFyZ3NFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGNoZWNrTnVtYmVyQXJncyhpbnQgYXJnTnVtKSB0aHJvd3MgV3JvbmdOdW1iZXJBcmdzRXhjZXB0aW9uCi0gIHsKLSAgICBpZiAoYXJnTnVtICE9IDEpCi0gICAgICByZXBvcnRXcm9uZ051bWJlckFyZ3MoKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3RzIGFuZCB0aHJvd3MgYSBXcm9uZ051bWJlckFyZ0V4Y2VwdGlvbiB3aXRoIHRoZSBhcHByb3ByaWF0ZQotICAgKiBtZXNzYWdlIGZvciB0aGlzIGZ1bmN0aW9uIG9iamVjdC4KLSAgICoKLSAgICogQHRocm93cyBXcm9uZ051bWJlckFyZ3NFeGNlcHRpb24KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIHJlcG9ydFdyb25nTnVtYmVyQXJncygpIHRocm93cyBXcm9uZ051bWJlckFyZ3NFeGNlcHRpb24gewotICAgICAgdGhyb3cgbmV3IFdyb25nTnVtYmVyQXJnc0V4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoIm9uZSIsIG51bGwpKTsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIGlmIHRoaXMgZXhwcmVzc2lvbiBvciBpdCdzIHN1YmV4cHJlc3Npb25zIGNhbiB0cmF2ZXJzZSBvdXRzaWRlCi0gICAqIHRoZSBjdXJyZW50IHN1YnRyZWUuCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0cmF2ZXJzYWwgb3V0c2lkZSB0aGUgY29udGV4dCBub2RlJ3Mgc3VidHJlZSBjYW4gb2NjdXIuCi0gICAqLwotICAgcHVibGljIGJvb2xlYW4gY2FuVHJhdmVyc2VPdXRzaWRlU3VidHJlZSgpCi0gICB7Ci0gICAgcmV0dXJuIG1fYXJnMC5jYW5UcmF2ZXJzZU91dHNpZGVTdWJ0cmVlKCk7Ci0gICB9Ci0KLSAgLyoqCi0gICAqIFRoaXMgZnVuY3Rpb24gaXMgdXNlZCB0byBmaXh1cCB2YXJpYWJsZXMgZnJvbSBRTmFtZXMgdG8gc3RhY2sgZnJhbWUKLSAgICogaW5kZXhlcyBhdCBzdHlsZXNoZWV0IGJ1aWxkIHRpbWUuCi0gICAqIEBwYXJhbSB2YXJzIExpc3Qgb2YgUU5hbWVzIHRoYXQgY29ycmVzcG9uZCB0byB2YXJpYWJsZXMuICBUaGlzIGxpc3QKLSAgICogc2hvdWxkIGJlIHNlYXJjaGVkIGJhY2t3YXJkcyBmb3IgdGhlIGZpcnN0IHF1YWxpZmllZCBuYW1lIHRoYXQKLSAgICogY29ycmVzcG9uZHMgdG8gdGhlIHZhcmlhYmxlIHJlZmVyZW5jZSBxbmFtZS4gIFRoZSBwb3NpdGlvbiBvZiB0aGUKLSAgICogUU5hbWUgaW4gdGhlIHZlY3RvciBmcm9tIHRoZSBzdGFydCBvZiB0aGUgdmVjdG9yIHdpbGwgYmUgaXRzIHBvc2l0aW9uCi0gICAqIGluIHRoZSBzdGFjayBmcmFtZSAoYnV0IHZhcmlhYmxlcyBhYm92ZSB0aGUgZ2xvYmFsc1RvcCB2YWx1ZSB3aWxsIG5lZWQKLSAgICogdG8gYmUgb2Zmc2V0IHRvIHRoZSBjdXJyZW50IHN0YWNrIGZyYW1lKS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGZpeHVwVmFyaWFibGVzKGphdmEudXRpbC5WZWN0b3IgdmFycywgaW50IGdsb2JhbHNTaXplKQotICB7Ci0gICAgaWYobnVsbCAhPSBtX2FyZzApCi0gICAgICBtX2FyZzAuZml4dXBWYXJpYWJsZXModmFycywgZ2xvYmFsc1NpemUpOwotICB9Ci0KLSAgLyoqCi0gICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoVmlzaXRhYmxlI2NhbGxWaXNpdG9ycyhFeHByZXNzaW9uT3duZXIsIFhQYXRoVmlzaXRvcikKLSAgICovCi0gIHB1YmxpYyB2b2lkIGNhbGxBcmdWaXNpdG9ycyhYUGF0aFZpc2l0b3IgdmlzaXRvcikKLSAgewotICAgICAgICBpZihudWxsICE9IG1fYXJnMCkKLSAgICAgICAgICAgICAgICBtX2FyZzAuY2FsbFZpc2l0b3JzKHRoaXMsIHZpc2l0b3IpOwotICB9Ci0KLQotICAvKioKLSAgICogQHNlZSBFeHByZXNzaW9uT3duZXIjZ2V0RXhwcmVzc2lvbigpCi0gICAqLwotICBwdWJsaWMgRXhwcmVzc2lvbiBnZXRFeHByZXNzaW9uKCkKLSAgewotICAgIHJldHVybiBtX2FyZzA7Ci0gIH0KLQotICAvKioKLSAgICogQHNlZSBFeHByZXNzaW9uT3duZXIjc2V0RXhwcmVzc2lvbihFeHByZXNzaW9uKQotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0RXhwcmVzc2lvbihFeHByZXNzaW9uIGV4cCkKLSAgewotICAgICAgICBleHAuZXhwclNldFBhcmVudCh0aGlzKTsKLSAgICAgICAgbV9hcmcwID0gZXhwOwotICB9Ci0KLSAgLyoqCi0gICAqIEBzZWUgRXhwcmVzc2lvbiNkZWVwRXF1YWxzKEV4cHJlc3Npb24pCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBkZWVwRXF1YWxzKEV4cHJlc3Npb24gZXhwcikKLSAgewotICAgICAgICBpZighc3VwZXIuZGVlcEVxdWFscyhleHByKSkKLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0KLSAgICAgICAgaWYobnVsbCAhPSBtX2FyZzApCi0gICAgICAgIHsKLSAgICAgICAgICAgICAgICBpZihudWxsID09ICgoRnVuY3Rpb25PbmVBcmcpZXhwcikubV9hcmcwKQotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotCi0gICAgICAgICAgICAgICAgaWYoIW1fYXJnMC5kZWVwRXF1YWxzKCgoRnVuY3Rpb25PbmVBcmcpZXhwcikubV9hcmcwKSkKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmKG51bGwgIT0gKChGdW5jdGlvbk9uZUFyZylleHByKS5tX2FyZzApCi0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotCi0gICAgICAgIHJldHVybiB0cnVlOwotICB9Ci0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9mdW5jdGlvbnMvV3JvbmdOdW1iZXJBcmdzRXhjZXB0aW9uLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2Z1bmN0aW9ucy9Xcm9uZ051bWJlckFyZ3NFeGNlcHRpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZjE2MzQ3ZS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2Z1bmN0aW9ucy9Xcm9uZ051bWJlckFyZ3NFeGNlcHRpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQ1ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFdyb25nTnVtYmVyQXJnc0V4Y2VwdGlvbi5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE0IDIwOjI3OjA0IGplZmZzdXR0b3IgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuZnVuY3Rpb25zOwotCi0vKioKLSAqIEFuIGV4Y2VwdGlvbiB0aGF0IGlzIHRocm93biBpZiB0aGUgd3JvbmcgbnVtYmVyIG9mIGFyZ3VtZW50cyB0byBhbiBleGNlcHRpb24KLSAqIGFyZSBzcGVjaWZpZWQgYnkgdGhlIHN0eWxlc2hlZXQuCi0gKiBAeHNsLnVzYWdlIGFkdmFuY2VkCi0gKi8KLXB1YmxpYyBjbGFzcyBXcm9uZ051bWJlckFyZ3NFeGNlcHRpb24gZXh0ZW5kcyBFeGNlcHRpb24KLXsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTQ1NTE1NzcwOTc1NzYyNDI0MzJMOwotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3RvciBXcm9uZ051bWJlckFyZ3NFeGNlcHRpb24KLSAgICoKLSAgICogQHBhcmFtIGFyZ3NFeHBlY3RlZCBFcnJvciBtZXNzYWdlIHRoYXQgdGVsbHMgdGhlIG51bWJlciBvZiBhcmd1bWVudHMgdGhhdAotICAgKiB3ZXJlIGV4cGVjdGVkLgotICAgKi8KLSAgcHVibGljIFdyb25nTnVtYmVyQXJnc0V4Y2VwdGlvbihTdHJpbmcgYXJnc0V4cGVjdGVkKQotICB7Ci0KLSAgICBzdXBlcihhcmdzRXhwZWN0ZWQpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2Z1bmN0aW9ucy9wYWNrYWdlLmh0bWwgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2Z1bmN0aW9ucy9wYWNrYWdlLmh0bWwKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDllZDhlZTkuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9mdW5jdGlvbnMvcGFja2FnZS5odG1sCisrKyAvZGV2L251bGwKQEAgLTEsMzEgKzAsMCBAQAotPCEtLQotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLS0tPgotPCEtLQotICogQ29weXJpZ2h0IDIwMDAtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0tLT4KLTwhLS0gJElkOiBwYWNrYWdlLmh0bWwsdiAxLjEuMi4xIDIwMDUvMDgvMDEgMDE6Mjk6MzggamVmZnN1dHRvciBFeHAgJCAtLT4KLTxodG1sPgotICA8dGl0bGU+WFBhdGggZnVuY3Rpb25zIFBhY2thZ2UuPC90aXRsZT4KLSAgPGJvZHk+Ci0gICAgPHA+SW1wbGVtZW50cyBYUGF0aCBmdW5jdGlvbnMgLS0gZWFjaCBmdW5jdGlvbiBpcyBkZXJpdmVkIGZyb20gRnVuY3Rpb24sIAotICAgIEZ1bmN0aW9uT25lQXJnLCBGdW5jdGlvbjJBcmdzLCBldGMsIHdpdGggbnVtYmVyLW9mLWFyZ3VtZW50cyBjaGVja2luZyBiZWluZyAKLSAgICBhcHBsaWVkIG1haW5seSBhdCBjb21waWxlIHRpbWUgLS0gdGhpcyBwYWNrYWdlIG9ubHkgaW1wbGVtZW50cyBYUGF0aCBmdW5jdGlvbnMsIAotICAgIFhTTFQgZnVuY3Rpb25zIGFyZSBmb3VuZCBpbiB0aGUgInRlbXBsYXRlcyIgcGFja2FnZS48cD4KLSA8L2JvZHk+Ci08L2h0bWw+Ci0KLQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9qYXhwL0pBWFBFeHRlbnNpb25zUHJvdmlkZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvamF4cC9KQVhQRXh0ZW5zaW9uc1Byb3ZpZGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGZlZTA1N2YuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9qYXhwL0pBWFBFeHRlbnNpb25zUHJvdmlkZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIxNCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLS8vICRJZDogSkFYUEV4dGVuc2lvbnNQcm92aWRlci5qYXZhLHYgMS4xLjIuMSAyMDA1LzA4LzAxIDAxOjMwOjE3IGplZmZzdXR0b3IgRXhwICQKLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuamF4cDsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci1pbXBvcnQgamF2YXgueG1sLnhwYXRoLlhQYXRoRnVuY3Rpb25SZXNvbHZlcjsKLWltcG9ydCBqYXZheC54bWwueHBhdGguWFBhdGhGdW5jdGlvbjsKLWltcG9ydCBqYXZheC54bWwueHBhdGguWFBhdGhGdW5jdGlvbkV4Y2VwdGlvbjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5FeHRlbnNpb25zUHJvdmlkZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoQ29udGV4dDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YT2JqZWN0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhOb2RlU2V0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5yZXMuWFBBVEhFcnJvclJlc291cmNlczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwucmVzLlhTTE1lc3NhZ2VzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC51dGlscy5GZWF0dXJlTWFuYWdlcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5mdW5jdGlvbnMuRnVuY0V4dEZ1bmN0aW9uOwotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci1pbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKLWltcG9ydCBqYXZheC54bWwubmFtZXNwYWNlLlFOYW1lOwotCi0vKioKLSAqCi0gKiBAYXV0aG9yIFJhbWVzaCBNYW5kYXZhICggcmFtZXNoLm1hbmRhdmFAc3VuLmNvbSApCi0gKi8KLXB1YmxpYyBjbGFzcyBKQVhQRXh0ZW5zaW9uc1Byb3ZpZGVyIGltcGxlbWVudHMgRXh0ZW5zaW9uc1Byb3ZpZGVyIHsKLQotICAgIHByaXZhdGUgZmluYWwgWFBhdGhGdW5jdGlvblJlc29sdmVyIHJlc29sdmVyOwotICAgIHByaXZhdGUgYm9vbGVhbiBleHRlbnNpb25JbnZvY2F0aW9uRGlzYWJsZWQgPSBmYWxzZTsKLQotICAgIHB1YmxpYyBKQVhQRXh0ZW5zaW9uc1Byb3ZpZGVyKFhQYXRoRnVuY3Rpb25SZXNvbHZlciByZXNvbHZlcikgewotICAgICAgICB0aGlzLnJlc29sdmVyID0gcmVzb2x2ZXI7Ci0gICAgICAgIHRoaXMuZXh0ZW5zaW9uSW52b2NhdGlvbkRpc2FibGVkID0gZmFsc2U7Ci0gICAgfQotCi0gICAgcHVibGljIEpBWFBFeHRlbnNpb25zUHJvdmlkZXIoWFBhdGhGdW5jdGlvblJlc29sdmVyIHJlc29sdmVyLAotICAgICAgICBib29sZWFuIGZlYXR1cmVTZWN1cmVQcm9jZXNzaW5nLCBGZWF0dXJlTWFuYWdlciBmZWF0dXJlTWFuYWdlciApIHsKLSAgICAgICAgdGhpcy5yZXNvbHZlciA9IHJlc29sdmVyOwotICAgICAgICBpZiAoZmVhdHVyZVNlY3VyZVByb2Nlc3NpbmcgJiYKLSAgICAgICAgICAgICAgICAhZmVhdHVyZU1hbmFnZXIuaXNGZWF0dXJlRW5hYmxlZChGZWF0dXJlTWFuYWdlci5GZWF0dXJlLk9SQUNMRV9FTkFCTEVfRVhURU5TSU9OX0ZVTkNUSU9OKSkgewotICAgICAgICAgICAgdGhpcy5leHRlbnNpb25JbnZvY2F0aW9uRGlzYWJsZWQgPSB0cnVlOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSXMgdGhlIGV4dGVuc2lvbiBmdW5jdGlvbiBhdmFpbGFibGU/Ci0gICAgICovCi0KLSAgICBwdWJsaWMgYm9vbGVhbiBmdW5jdGlvbkF2YWlsYWJsZShTdHJpbmcgbnMsIFN0cmluZyBmdW5jTmFtZSkKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbiB7Ci0gICAgICB0cnkgewotICAgICAgICBpZiAoIGZ1bmNOYW1lID09IG51bGwgKSB7Ci0gICAgICAgICAgICBTdHJpbmcgZm1zZyA9IFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZSgKLSAgICAgICAgICAgICAgICBYUEFUSEVycm9yUmVzb3VyY2VzLkVSX0FSR19DQU5OT1RfQkVfTlVMTCwKLSAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyJGdW5jdGlvbiBOYW1lIn0gKTsKLSAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbiAoIGZtc2cgKTsKLSAgICAgICAgfQotICAgICAgICAvL0ZpbmQgdGhlIFhQYXRoRnVuY3Rpb24gY29ycmVzcG9uZGluZyB0byBuYW1lc3BhY2UgYW5kIGZ1bmNOYW1lCi0gICAgICAgIGphdmF4LnhtbC5uYW1lc3BhY2UuUU5hbWUgbXlRTmFtZSA9IG5ldyBRTmFtZSggbnMsIGZ1bmNOYW1lICk7Ci0gICAgICAgIGphdmF4LnhtbC54cGF0aC5YUGF0aEZ1bmN0aW9uIHhwYXRoRnVuY3Rpb24gPQotICAgICAgICAgICAgcmVzb2x2ZXIucmVzb2x2ZUZ1bmN0aW9uICggbXlRTmFtZSwgMCApOwotICAgICAgICBpZiAoICB4cGF0aEZ1bmN0aW9uID09IG51bGwgKSB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICB9IGNhdGNoICggRXhjZXB0aW9uIGUgKSB7Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgIH0KLQotCi0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBJcyB0aGUgZXh0ZW5zaW9uIGVsZW1lbnQgYXZhaWxhYmxlPwotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGVsZW1lbnRBdmFpbGFibGUoU3RyaW5nIG5zLCBTdHJpbmcgZWxlbU5hbWUpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24gewotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRXhlY3V0ZSB0aGUgZXh0ZW5zaW9uIGZ1bmN0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBPYmplY3QgZXh0RnVuY3Rpb24oU3RyaW5nIG5zLCBTdHJpbmcgZnVuY05hbWUsIFZlY3RvciBhcmdWZWMsCi0gICAgICAgIE9iamVjdCBtZXRob2RLZXkpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uIHsKLSAgICAgICAgdHJ5IHsKLQotICAgICAgICAgICAgaWYgKCBmdW5jTmFtZSA9PSBudWxsICkgewotICAgICAgICAgICAgICAgIFN0cmluZyBmbXNnID0gWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKAotICAgICAgICAgICAgICAgICAgICBYUEFUSEVycm9yUmVzb3VyY2VzLkVSX0FSR19DQU5OT1RfQkVfTlVMTCwKLSAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsiRnVuY3Rpb24gTmFtZSJ9ICk7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uICggZm1zZyApOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy9GaW5kIHRoZSBYUGF0aEZ1bmN0aW9uIGNvcnJlc3BvbmRpbmcgdG8gbmFtZXNwYWNlIGFuZCBmdW5jTmFtZQotICAgICAgICAgICAgamF2YXgueG1sLm5hbWVzcGFjZS5RTmFtZSBteVFOYW1lID0gbmV3IFFOYW1lKCBucywgZnVuY05hbWUgKTsKLQotICAgICAgICAgICAgLy8gSkFYUCAxLjMgc3BlYyBzYXlzIFdoZW4gWE1MQ29uc3RhbnRzLkZFQVRVUkVfU0VDVVJFX1BST0NFU1NJTkcKLSAgICAgICAgICAgIC8vIGZlYXR1cmUgaXMgc2V0IHRoZW4gaW52b2NhdGlvbiBvZiBleHRlbnNpb24gZnVuY3Rpb25zIG5lZWQgdG8KLSAgICAgICAgICAgIC8vIHRocm93IFhQYXRoRnVuY3Rpb25FeGNlcHRpb24KLSAgICAgICAgICAgIGlmICggZXh0ZW5zaW9uSW52b2NhdGlvbkRpc2FibGVkICkgewotICAgICAgICAgICAgICAgIFN0cmluZyBmbXNnID0gWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKAotICAgICAgICAgICAgICAgICAgICBYUEFUSEVycm9yUmVzb3VyY2VzLkVSX0VYVEVOU0lPTl9GVU5DVElPTl9DQU5OT1RfQkVfSU5WT0tFRCwKLSAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgbXlRTmFtZS50b1N0cmluZygpIH0gKTsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWFBhdGhGdW5jdGlvbkV4Y2VwdGlvbiAoIGZtc2cgKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gQXNzdW1pbmcgdXNlciBpcyBwYXNzaW5nIGFsbCB0aGUgbmVlZGVkIHBhcmFtZXRlcnMgKCBpbmNsdWRpbmcKLSAgICAgICAgICAgIC8vIGRlZmF1bHQgdmFsdWVzICkKLSAgICAgICAgICAgIGludCBhcml0eSA9IGFyZ1ZlYy5zaXplKCk7Ci0KLSAgICAgICAgICAgIGphdmF4LnhtbC54cGF0aC5YUGF0aEZ1bmN0aW9uIHhwYXRoRnVuY3Rpb24gPQotICAgICAgICAgICAgICAgIHJlc29sdmVyLnJlc29sdmVGdW5jdGlvbiAoIG15UU5hbWUsIGFyaXR5ICk7Ci0KLSAgICAgICAgICAgIC8vIG5vdCB1c2luZyBtZXRob2RLZXkKLSAgICAgICAgICAgIEFycmF5TGlzdCBhcmdMaXN0ID0gbmV3IEFycmF5TGlzdCggYXJpdHkpOwotICAgICAgICAgICAgZm9yICggaW50IGk9MDsgaTxhcml0eTsgaSsrICkgewotICAgICAgICAgICAgICAgIE9iamVjdCBhcmd1bWVudCA9IGFyZ1ZlYy5lbGVtZW50QXQoIGkgKTsKLSAgICAgICAgICAgICAgICAvLyBYTm9kZVNldCBvYmplY3QoKSByZXR1cm5zIE5vZGVWZWN0b3IgYW5kIG5vdCBOb2RlTGlzdAotICAgICAgICAgICAgICAgIC8vIEV4cGxpY2l0bHkgZ2V0dGluZyBOb2RlTGlzdCBieSB1c2luZyBub2RlbGlzdCgpCi0gICAgICAgICAgICAgICAgaWYgKCBhcmd1bWVudCBpbnN0YW5jZW9mIFhOb2RlU2V0ICkgewotICAgICAgICAgICAgICAgICAgICBhcmdMaXN0LmFkZCAoIGksICgoWE5vZGVTZXQpYXJndW1lbnQpLm5vZGVsaXN0KCkgKTsKLSAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCBhcmd1bWVudCBpbnN0YW5jZW9mIFhPYmplY3QgKSB7Ci0gICAgICAgICAgICAgICAgICAgIE9iamVjdCBwYXNzZWRBcmd1bWVudCA9ICgoWE9iamVjdClhcmd1bWVudCkub2JqZWN0KCk7Ci0gICAgICAgICAgICAgICAgICAgIGFyZ0xpc3QuYWRkICggaSwgcGFzc2VkQXJndW1lbnQgKTsKLSAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICBhcmdMaXN0LmFkZCAoIGksIGFyZ3VtZW50ICk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICByZXR1cm4gKCB4cGF0aEZ1bmN0aW9uLmV2YWx1YXRlICggYXJnTGlzdCApKTsKLSAgICAgICAgfSBjYXRjaCAoIFhQYXRoRnVuY3Rpb25FeGNlcHRpb24geGZlICkgewotICAgICAgICAgICAgLy8gSWYgd2UgZ2V0IFhQYXRoRnVuY3Rpb25FeGNlcHRpb24gdGhlbiB3ZSB3YW50IHRvIHRlcm1pbmF0ZQotICAgICAgICAgICAgLy8gZnVydGhlciBleGVjdXRpb24gYnkgdGhyb3dpbmcgV3JhcHBlZFJ1bnRpbWVFeGNlcHRpb24KLSAgICAgICAgICAgIHRocm93IG5ldyBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLldyYXBwZWRSdW50aW1lRXhjZXB0aW9uICggeGZlICk7Ci0gICAgICAgIH0gY2F0Y2ggKCBFeGNlcHRpb24gZSApIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uICggZSApOwotICAgICAgICB9Ci0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBFeGVjdXRlIHRoZSBleHRlbnNpb24gZnVuY3Rpb24uCi0gICAgICovCi0gICAgcHVibGljIE9iamVjdCBleHRGdW5jdGlvbihGdW5jRXh0RnVuY3Rpb24gZXh0RnVuY3Rpb24sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWZWN0b3IgYXJnVmVjKQotICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbiB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBTdHJpbmcgbmFtZXNwYWNlID0gZXh0RnVuY3Rpb24uZ2V0TmFtZXNwYWNlKCk7Ci0gICAgICAgICAgICBTdHJpbmcgZnVuY3Rpb25OYW1lID0gZXh0RnVuY3Rpb24uZ2V0RnVuY3Rpb25OYW1lKCk7Ci0gICAgICAgICAgICBpbnQgYXJpdHkgPSBleHRGdW5jdGlvbi5nZXRBcmdDb3VudCgpOwotICAgICAgICAgICAgamF2YXgueG1sLm5hbWVzcGFjZS5RTmFtZSBteVFOYW1lID0KLSAgICAgICAgICAgICAgICBuZXcgamF2YXgueG1sLm5hbWVzcGFjZS5RTmFtZSggbmFtZXNwYWNlLCBmdW5jdGlvbk5hbWUgKTsKLQotICAgICAgICAgICAgLy8gSkFYUCAxLjMgc3BlYyBzYXlzICBXaGVuIFhNTENvbnN0YW50cy5GRUFUVVJFX1NFQ1VSRV9QUk9DRVNTSU5HCi0gICAgICAgICAgICAvLyBmZWF0dXJlIGlzIHNldCB0aGVuIGludm9jYXRpb24gb2YgZXh0ZW5zaW9uIGZ1bmN0aW9ucyBuZWVkIHRvCi0gICAgICAgICAgICAvLyB0aHJvdyBYUGF0aEZ1bmN0aW9uRXhjZXB0aW9uCi0gICAgICAgICAgICBpZiAoIGV4dGVuc2lvbkludm9jYXRpb25EaXNhYmxlZCApIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgZm1zZyA9IFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZSgKLSAgICAgICAgICAgICAgICAgICAgWFBBVEhFcnJvclJlc291cmNlcy5FUl9FWFRFTlNJT05fRlVOQ1RJT05fQ0FOTk9UX0JFX0lOVk9LRUQsICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBteVFOYW1lLnRvU3RyaW5nKCkgfSApOwotICAgICAgICAgICAgICAgIHRocm93IG5ldyBYUGF0aEZ1bmN0aW9uRXhjZXB0aW9uICggZm1zZyApOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBYUGF0aEZ1bmN0aW9uIHhwYXRoRnVuY3Rpb24gPQotICAgICAgICAgICAgICAgIHJlc29sdmVyLnJlc29sdmVGdW5jdGlvbiggbXlRTmFtZSwgYXJpdHkgKTsKLQotICAgICAgICAgICAgQXJyYXlMaXN0IGFyZ0xpc3QgPSBuZXcgQXJyYXlMaXN0KCBhcml0eSk7Ci0gICAgICAgICAgICBmb3IgKCBpbnQgaT0wOyBpPGFyaXR5OyBpKysgKSB7Ci0gICAgICAgICAgICAgICAgT2JqZWN0IGFyZ3VtZW50ID0gYXJnVmVjLmVsZW1lbnRBdCggaSApOwotICAgICAgICAgICAgICAgIC8vIFhOb2RlU2V0IG9iamVjdCgpIHJldHVybnMgTm9kZVZlY3RvciBhbmQgbm90IE5vZGVMaXN0Ci0gICAgICAgICAgICAgICAgLy8gRXhwbGljaXRseSBnZXR0aW5nIE5vZGVMaXN0IGJ5IHVzaW5nIG5vZGVsaXN0KCkKLSAgICAgICAgICAgICAgICBpZiAoIGFyZ3VtZW50IGluc3RhbmNlb2YgWE5vZGVTZXQgKSB7Ci0gICAgICAgICAgICAgICAgICAgIGFyZ0xpc3QuYWRkICggaSwgKChYTm9kZVNldClhcmd1bWVudCkubm9kZWxpc3QoKSApOwotICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIGFyZ3VtZW50IGluc3RhbmNlb2YgWE9iamVjdCApIHsKLSAgICAgICAgICAgICAgICAgICAgT2JqZWN0IHBhc3NlZEFyZ3VtZW50ID0gKChYT2JqZWN0KWFyZ3VtZW50KS5vYmplY3QoKTsKLSAgICAgICAgICAgICAgICAgICAgYXJnTGlzdC5hZGQgKCBpLCBwYXNzZWRBcmd1bWVudCApOwotICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIGFyZ0xpc3QuYWRkICggaSwgYXJndW1lbnQgKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIHJldHVybiAoIHhwYXRoRnVuY3Rpb24uZXZhbHVhdGUgKCBhcmdMaXN0ICkpOwotCi0gICAgICAgIH0gY2F0Y2ggKCBYUGF0aEZ1bmN0aW9uRXhjZXB0aW9uIHhmZSApIHsKLSAgICAgICAgICAgIC8vIElmIHdlIGdldCBYUGF0aEZ1bmN0aW9uRXhjZXB0aW9uIHRoZW4gd2Ugd2FudCB0byB0ZXJtaW5hdGUKLSAgICAgICAgICAgIC8vIGZ1cnRoZXIgZXhlY3V0aW9uIGJ5IHRocm93aW5nIFdyYXBwZWRSdW50aW1lRXhjZXB0aW9uCi0gICAgICAgICAgICB0aHJvdyBuZXcgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5XcmFwcGVkUnVudGltZUV4Y2VwdGlvbiAoIHhmZSApOwotICAgICAgICB9IGNhdGNoICggRXhjZXB0aW9uIGUgKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbiAoIGUgKTsKLSAgICAgICAgfQotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9qYXhwL0pBWFBQcmVmaXhSZXNvbHZlci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9qYXhwL0pBWFBQcmVmaXhSZXNvbHZlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyMGM2Njc4Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvamF4cC9KQVhQUHJlZml4UmVzb2x2ZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEyOCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vLyAkSWQ6IEpBWFBQcmVmaXhSZXNvbHZlci5qYXZhLHYgMS4xLjIuMSAyMDA1LzA4LzAxIDAxOjMwOjE4IGplZmZzdXR0b3IgRXhwICQKLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuamF4cDsKLQotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci1pbXBvcnQgb3JnLnczYy5kb20uTmFtZWROb2RlTWFwOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuUHJlZml4UmVzb2x2ZXI7Ci0KLWltcG9ydCBqYXZheC54bWwubmFtZXNwYWNlLk5hbWVzcGFjZUNvbnRleHQ7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImdlbmVyYWwiLz4KLSAqIFRoaXMgY2xhc3MgaW1wbGVtZW50cyBhIERlZmF1bHQgUHJlZml4UmVzb2x2ZXIgd2hpY2gKLSAqIGNhbiBiZSB1c2VkIHRvIHBlcmZvcm0gcHJlZml4LXRvLW5hbWVzcGFjZSBsb29rdXAKLSAqIGZvciB0aGUgWFBhdGggb2JqZWN0LgotICogVGhpcyBjbGFzcyBkZWxlZ2F0ZXMgdGhlIHJlc29sdXRpb24gdG8gdGhlIHBhc3NlZCBOYW1lc3BhY2VDb250ZXh0Ci0gKi8KLXB1YmxpYyBjbGFzcyBKQVhQUHJlZml4UmVzb2x2ZXIgaW1wbGVtZW50cyBQcmVmaXhSZXNvbHZlcgotewotCi0gICAgcHJpdmF0ZSBOYW1lc3BhY2VDb250ZXh0IG5hbWVzcGFjZUNvbnRleHQ7Ci0KLQotICAgIHB1YmxpYyBKQVhQUHJlZml4UmVzb2x2ZXIgKCBOYW1lc3BhY2VDb250ZXh0IG5zQ29udGV4dCApIHsKLSAgICAgICAgdGhpcy5uYW1lc3BhY2VDb250ZXh0ID0gbnNDb250ZXh0OwotICAgIH0KLQotCi0gICAgcHVibGljIFN0cmluZyBnZXROYW1lc3BhY2VGb3JQcmVmaXgoIFN0cmluZyBwcmVmaXggKSB7Ci0gICAgICAgIHJldHVybiBuYW1lc3BhY2VDb250ZXh0LmdldE5hbWVzcGFjZVVSSSggcHJlZml4ICk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSBiYXNlIGlkZW50aWZpZXIuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIG51bGwKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEJhc2VJZGVudGlmaWVyKCkgewotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAc2VlIFByZWZpeFJlc29sdmVyI2hhbmRsZXNOdWxsUHJlZml4ZXMoKQotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGhhbmRsZXNOdWxsUHJlZml4ZXMoKSB7Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFRoZSBVUkkgZm9yIHRoZSBYTUwgbmFtZXNwYWNlLgotICAgICAqIChEdXBsaWNhdGUgb2YgdGhhdCBmb3VuZCBpbiBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuWFBhdGhDb250ZXh0KS4KLSAgICAgKi8KLQotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFNfWE1MTkFNRVNQQUNFVVJJID0KLSAgICAgICAgImh0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZSI7Ci0KLQotICAgIC8qKgotICAgICAqIEdpdmVuIGEgcHJlZml4IGFuZCBhIENvbnRleHQgTm9kZSwgZ2V0IHRoZSBjb3JyZXNwb25kaW5nIG5hbWVzcGFjZS4KLSAgICAgKiBXYXJuaW5nOiBUaGlzIHdpbGwgbm90IHdvcmsgY29ycmVjdGx5IGlmIG5hbWVzcGFjZUNvbnRleHQKLSAgICAgKiBpcyBhbiBhdHRyaWJ1dGUgbm9kZS4KLSAgICAgKiBAcGFyYW0gcHJlZml4IFByZWZpeCB0byByZXNvbHZlLgotICAgICAqIEBwYXJhbSBuYW1lc3BhY2VDb250ZXh0IE5vZGUgZnJvbSB3aGljaCB0byBzdGFydCBzZWFyY2hpbmcgZm9yIGEKLSAgICAgKiB4bWxucyBhdHRyaWJ1dGUgdGhhdCBiaW5kcyBhIHByZWZpeCB0byBhIG5hbWVzcGFjZS4KLSAgICAgKiBAcmV0dXJuIE5hbWVzcGFjZSB0aGF0IHByZWZpeCByZXNvbHZlcyB0bywgb3IgbnVsbCBpZiBwcmVmaXgKLSAgICAgKiBpcyBub3QgYm91bmQuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXROYW1lc3BhY2VGb3JQcmVmaXgoU3RyaW5nIHByZWZpeCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JnLnczYy5kb20uTm9kZSBuYW1lc3BhY2VDb250ZXh0KSB7Ci0gICAgICAgIE5vZGUgcGFyZW50ID0gbmFtZXNwYWNlQ29udGV4dDsKLSAgICAgICAgU3RyaW5nIG5hbWVzcGFjZSA9IG51bGw7Ci0KLSAgICAgICAgaWYgKHByZWZpeC5lcXVhbHMoInhtbCIpKSB7Ci0gICAgICAgICAgICBuYW1lc3BhY2UgPSBTX1hNTE5BTUVTUEFDRVVSSTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIGludCB0eXBlOwotCi0gICAgICAgICAgICB3aGlsZSAoKG51bGwgIT0gcGFyZW50KSAmJiAobnVsbCA9PSBuYW1lc3BhY2UpCi0gICAgICAgICAgICAgICAgJiYgKCgodHlwZSA9IHBhcmVudC5nZXROb2RlVHlwZSgpKSA9PSBOb2RlLkVMRU1FTlRfTk9ERSkKLSAgICAgICAgICAgICAgICAgICAgfHwgKHR5cGUgPT0gTm9kZS5FTlRJVFlfUkVGRVJFTkNFX05PREUpKSkgewotCi0gICAgICAgICAgICAgICAgaWYgKHR5cGUgPT0gTm9kZS5FTEVNRU5UX05PREUpIHsKLSAgICAgICAgICAgICAgICAgICAgTmFtZWROb2RlTWFwIG5ubSA9IHBhcmVudC5nZXRBdHRyaWJ1dGVzKCk7Ci0KLSAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBubm0uZ2V0TGVuZ3RoKCk7IGkrKykgewotICAgICAgICAgICAgICAgICAgICAgICAgTm9kZSBhdHRyID0gbm5tLml0ZW0oaSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgYW5hbWUgPSBhdHRyLmdldE5vZGVOYW1lKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGlzUHJlZml4ID0gYW5hbWUuc3RhcnRzV2l0aCgieG1sbnM6Iik7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc1ByZWZpeCB8fCBhbmFtZS5lcXVhbHMoInhtbG5zIikpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaW5kZXggPSBhbmFtZS5pbmRleE9mKCc6Jyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHAgPWlzUHJlZml4ID9hbmFtZS5zdWJzdHJpbmcoaW5kZXggKyAxKSA6IiI7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocC5lcXVhbHMocHJlZml4KSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lc3BhY2UgPSBhdHRyLmdldE5vZGVWYWx1ZSgpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBwYXJlbnQgPSBwYXJlbnQuZ2V0UGFyZW50Tm9kZSgpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBuYW1lc3BhY2U7Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2pheHAvSkFYUFZhcmlhYmxlU3RhY2suamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvamF4cC9KQVhQVmFyaWFibGVTdGFjay5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA5ZDlmMTlkLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvamF4cC9KQVhQVmFyaWFibGVTdGFjay5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNzQgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLy8gJElkOiBKQVhQVmFyaWFibGVTdGFjay5qYXZhLHYgMS4xLjIuMSAyMDA1LzA4LzAxIDAxOjMwOjE3IGplZmZzdXR0b3IgRXhwICQKLQotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuamF4cDsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci1pbXBvcnQgamF2YXgueG1sLnhwYXRoLlhQYXRoVmFyaWFibGVSZXNvbHZlcjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuUU5hbWU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlZhcmlhYmxlU3RhY2s7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoQ29udGV4dDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YT2JqZWN0OwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLnJlcy5YUEFUSEVycm9yUmVzb3VyY2VzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC5yZXMuWFNMTWVzc2FnZXM7Ci0KLQotLyoqCi0gKiBPdmVycmlkZXMge0BsaW5rIFZhcmlhYmxlU3RhY2t9IGFuZCBkZWxlZ2F0ZXMgdGhlIGNhbGwgdG8KLSAqIHtAbGluayBqYXZheC54bWwueHBhdGguWFBhdGhWYXJpYWJsZVJlc29sdmVyfS4KLSAqCi0gKiBAYXV0aG9yIFJhbWVzaCBNYW5kYXZhICggcmFtZXNoLm1hbmRhdmFAc3VuLmNvbSApCi0gKi8KLXB1YmxpYyBjbGFzcyBKQVhQVmFyaWFibGVTdGFjayBleHRlbmRzIFZhcmlhYmxlU3RhY2sgewotCi0gICAgcHJpdmF0ZSBmaW5hbCBYUGF0aFZhcmlhYmxlUmVzb2x2ZXIgcmVzb2x2ZXI7Ci0KLSAgICBwdWJsaWMgSkFYUFZhcmlhYmxlU3RhY2soWFBhdGhWYXJpYWJsZVJlc29sdmVyIHJlc29sdmVyKSB7Ci0gICAgICAgIHRoaXMucmVzb2x2ZXIgPSByZXNvbHZlcjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgWE9iamVjdCBnZXRWYXJpYWJsZU9yUGFyYW0oWFBhdGhDb250ZXh0IHhjdHh0LCBRTmFtZSBxbmFtZSkKLSAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uLElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmICggcW5hbWUgPT0gbnVsbCApIHsKLSAgICAgICAgICAgIC8vSkFYUCAxLjMgc3BlYyBzYXlzIHRoYXQgaWYgdmFyaWFibGUgbmFtZSBpcyBudWxsIHRoZW4KLSAgICAgICAgICAgIC8vIHdlIG5lZWQgdG8gdGhyb3VnaCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KLSAgICAgICAgICAgIFN0cmluZyBmbXNnID0gWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKAotICAgICAgICAgICAgICAgIFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfQVJHX0NBTk5PVF9CRV9OVUxMLAotICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7IlZhcmlhYmxlIHFuYW1lIn0gKTsKLSAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIGZtc2cgKTsKLSAgICAgICAgfQotICAgICAgICBqYXZheC54bWwubmFtZXNwYWNlLlFOYW1lIG5hbWUgPQotICAgICAgICAgICAgbmV3IGphdmF4LnhtbC5uYW1lc3BhY2UuUU5hbWUoCi0gICAgICAgICAgICAgICAgcW5hbWUuZ2V0TmFtZXNwYWNlKCksCi0gICAgICAgICAgICAgICAgcW5hbWUuZ2V0TG9jYWxQYXJ0KCkpOwotICAgICAgICBPYmplY3QgdmFyVmFsdWUgPSByZXNvbHZlci5yZXNvbHZlVmFyaWFibGUoIG5hbWUgKTsKLSAgICAgICAgaWYgKCB2YXJWYWx1ZSA9PSBudWxsICkgewotICAgICAgICAgICAgU3RyaW5nIGZtc2cgPSBYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoCi0gICAgICAgICAgICAgICAgWFBBVEhFcnJvclJlc291cmNlcy5FUl9SRVNPTFZFX1ZBUklBQkxFX1JFVFVSTlNfTlVMTCwKLSAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBuYW1lLnRvU3RyaW5nKCl9ICk7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oIGZtc2cgKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gWE9iamVjdC5jcmVhdGUoIHZhclZhbHVlLCB4Y3R4dCApOwotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9qYXhwL1hQYXRoRXhwcmVzc2lvbkltcGwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvamF4cC9YUGF0aEV4cHJlc3Npb25JbXBsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDkyNWNlOWMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9qYXhwL1hQYXRoRXhwcmVzc2lvbkltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDM4MCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vLyAkSWQ6IFhQYXRoRXhwcmVzc2lvbkltcGwuamF2YSx2IDEuMyAyMDA1LzA5LzI3IDA5OjQwOjQzIHN1bml0aGFyZWRkeSBFeHAgJAotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5qYXhwOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLio7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhPYmplY3Q7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuUHJlZml4UmVzb2x2ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLnJlcy5YUEFUSEVycm9yUmVzb3VyY2VzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC5yZXMuWFNMTWVzc2FnZXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnV0aWxzLkZhY3RvcnlJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC51dGlscy5GZWF0dXJlTWFuYWdlcjsKLQotaW1wb3J0IGphdmF4LnhtbC5uYW1lc3BhY2UuTmFtZXNwYWNlQ29udGV4dDsKLWltcG9ydCBqYXZheC54bWwubmFtZXNwYWNlLlFOYW1lOwotaW1wb3J0IGphdmF4LnhtbC54cGF0aC5YUGF0aEV4cHJlc3Npb25FeGNlcHRpb247Ci1pbXBvcnQgamF2YXgueG1sLnhwYXRoLlhQYXRoQ29uc3RhbnRzOwotaW1wb3J0IGphdmF4LnhtbC54cGF0aC5YUGF0aEZ1bmN0aW9uUmVzb2x2ZXI7Ci1pbXBvcnQgamF2YXgueG1sLnhwYXRoLlhQYXRoVmFyaWFibGVSZXNvbHZlcjsKLWltcG9ydCBqYXZheC54bWwueHBhdGguWFBhdGhDb25zdGFudHM7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLkRPTUltcGxlbWVudGF0aW9uOwotaW1wb3J0IG9yZy53M2MuZG9tLnRyYXZlcnNhbC5Ob2RlSXRlcmF0b3I7Ci1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXI7Ci0KLWltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKLQotLyoqCi0gKiBUaGUgWFBhdGhFeHByZXNzaW9uIGludGVyZmFjZSBlbmNhcHN1bGF0ZXMgYSAoY29tcGlsZWQpIFhQYXRoIGV4cHJlc3Npb24uCi0gKgotICogQHZlcnNpb24gJFJldmlzaW9uOiAxLjEwICQKLSAqIEBhdXRob3IgIFJhbWVzaCBNYW5kYXZhCi0gKi8KLXB1YmxpYyBjbGFzcyBYUGF0aEV4cHJlc3Npb25JbXBsICBpbXBsZW1lbnRzIGphdmF4LnhtbC54cGF0aC5YUGF0aEV4cHJlc3Npb257Ci0KLSAgICBwcml2YXRlIFhQYXRoRnVuY3Rpb25SZXNvbHZlciBmdW5jdGlvblJlc29sdmVyOwotICAgIHByaXZhdGUgWFBhdGhWYXJpYWJsZVJlc29sdmVyIHZhcmlhYmxlUmVzb2x2ZXI7Ci0gICAgcHJpdmF0ZSBKQVhQUHJlZml4UmVzb2x2ZXIgcHJlZml4UmVzb2x2ZXI7Ci0gICAgcHJpdmF0ZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuWFBhdGggeHBhdGg7Ci0KLSAgICAvLyBCeSBkZWZhdWx0IEV4dGVuc2lvbiBGdW5jdGlvbnMgYXJlIGFsbG93ZWQgaW4gWFBhdGggRXhwcmVzc2lvbnMuIElmCi0gICAgLy8gU2VjdXJlIFByb2Nlc3NpbmcgRmVhdHVyZSBpcyBzZXQgb24gWFBhdGhGYWN0b3J5IHRoZW4gdGhlIGludm9jYXRpb24gb2YKLSAgICAvLyBleHRlbnNpb25zIGZ1bmN0aW9uIG5lZWQgdG8gdGhyb3cgWFBhdGhGdW5jdGlvbkV4Y2VwdGlvbgotICAgIHByaXZhdGUgYm9vbGVhbiBmZWF0dXJlU2VjdXJlUHJvY2Vzc2luZyA9IGZhbHNlOwotCi0gICAgcHJpdmF0ZSBib29sZWFuIHVzZVNlcnZpY2VzTWVjaGFuaXNtID0gdHJ1ZTsKLQotICAgIHByaXZhdGUgZmluYWwgRmVhdHVyZU1hbmFnZXIgZmVhdHVyZU1hbmFnZXI7Ci0KLSAgICAvKiogUHJvdGVjdGVkIGNvbnN0cnVjdG9yIHRvIHByZXZlbnQgZGlyZWN0IGluc3RhbnRpYXRpb247IHVzZSBjb21waWxlKCkKLSAgICAgKiBmcm9tIHRoZSBjb250ZXh0LgotICAgICAqLwotICAgIHByb3RlY3RlZCBYUGF0aEV4cHJlc3Npb25JbXBsKCkgewotICAgICAgICB0aGlzKG51bGwsIG51bGwsIG51bGwsIG51bGwsCi0gICAgICAgICAgICAgZmFsc2UsIHRydWUsIG5ldyBGZWF0dXJlTWFuYWdlcigpKTsKLSAgICB9OwotCi0gICAgcHJvdGVjdGVkIFhQYXRoRXhwcmVzc2lvbkltcGwoY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoIHhwYXRoLAotICAgICAgICAgICAgSkFYUFByZWZpeFJlc29sdmVyIHByZWZpeFJlc29sdmVyLAotICAgICAgICAgICAgWFBhdGhGdW5jdGlvblJlc29sdmVyIGZ1bmN0aW9uUmVzb2x2ZXIsCi0gICAgICAgICAgICBYUGF0aFZhcmlhYmxlUmVzb2x2ZXIgdmFyaWFibGVSZXNvbHZlciApIHsKLSAgICAgICAgdGhpcyh4cGF0aCwgcHJlZml4UmVzb2x2ZXIsIGZ1bmN0aW9uUmVzb2x2ZXIsIHZhcmlhYmxlUmVzb2x2ZXIsCi0gICAgICAgICAgICAgZmFsc2UsIHRydWUsIG5ldyBGZWF0dXJlTWFuYWdlcigpKTsKLSAgICB9OwotCi0gICAgcHJvdGVjdGVkIFhQYXRoRXhwcmVzc2lvbkltcGwoY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoIHhwYXRoLAotICAgICAgICAgICAgSkFYUFByZWZpeFJlc29sdmVyIHByZWZpeFJlc29sdmVyLFhQYXRoRnVuY3Rpb25SZXNvbHZlciBmdW5jdGlvblJlc29sdmVyLAotICAgICAgICAgICAgWFBhdGhWYXJpYWJsZVJlc29sdmVyIHZhcmlhYmxlUmVzb2x2ZXIsIGJvb2xlYW4gZmVhdHVyZVNlY3VyZVByb2Nlc3NpbmcsCi0gICAgICAgICAgICBib29sZWFuIHVzZVNlcnZpY2VzTWVjaGFuaXNtLCBGZWF0dXJlTWFuYWdlciBmZWF0dXJlTWFuYWdlciApIHsKLSAgICAgICAgdGhpcy54cGF0aCA9IHhwYXRoOwotICAgICAgICB0aGlzLnByZWZpeFJlc29sdmVyID0gcHJlZml4UmVzb2x2ZXI7Ci0gICAgICAgIHRoaXMuZnVuY3Rpb25SZXNvbHZlciA9IGZ1bmN0aW9uUmVzb2x2ZXI7Ci0gICAgICAgIHRoaXMudmFyaWFibGVSZXNvbHZlciA9IHZhcmlhYmxlUmVzb2x2ZXI7Ci0gICAgICAgIHRoaXMuZmVhdHVyZVNlY3VyZVByb2Nlc3NpbmcgPSBmZWF0dXJlU2VjdXJlUHJvY2Vzc2luZzsKLSAgICAgICAgdGhpcy51c2VTZXJ2aWNlc01lY2hhbmlzbSA9IHVzZVNlcnZpY2VzTWVjaGFuaXNtOwotICAgICAgICB0aGlzLmZlYXR1cmVNYW5hZ2VyID0gZmVhdHVyZU1hbmFnZXI7Ci0gICAgfTsKLQotICAgIHB1YmxpYyB2b2lkIHNldFhQYXRoIChjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuWFBhdGggeHBhdGggKSB7Ci0gICAgICAgIHRoaXMueHBhdGggPSB4cGF0aDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgT2JqZWN0IGV2YWwoT2JqZWN0IGl0ZW0sIFFOYW1lIHJldHVyblR5cGUpCi0gICAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbiB7Ci0gICAgICAgIFhPYmplY3QgcmVzdWx0T2JqZWN0ID0gZXZhbCAoIGl0ZW0gKTsKLSAgICAgICAgcmV0dXJuIGdldFJlc3VsdEFzVHlwZSggcmVzdWx0T2JqZWN0LCByZXR1cm5UeXBlICk7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBYT2JqZWN0IGV2YWwgKCBPYmplY3QgY29udGV4dEl0ZW0gKQotICAgICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24gewotICAgICAgICBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuWFBhdGhDb250ZXh0IHhwYXRoU3VwcG9ydCA9IG51bGw7Ci0gICAgICAgIGlmICggZnVuY3Rpb25SZXNvbHZlciAhPSBudWxsICkgewotICAgICAgICAgICAgSkFYUEV4dGVuc2lvbnNQcm92aWRlciBqZXAgPSBuZXcgSkFYUEV4dGVuc2lvbnNQcm92aWRlcigKLSAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb25SZXNvbHZlciwgZmVhdHVyZVNlY3VyZVByb2Nlc3NpbmcsIGZlYXR1cmVNYW5hZ2VyICk7Ci0gICAgICAgICAgICB4cGF0aFN1cHBvcnQgPSBuZXcgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoQ29udGV4dCggamVwICk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICB4cGF0aFN1cHBvcnQgPSBuZXcgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoQ29udGV4dCgpOwotICAgICAgICB9Ci0KLSAgICAgICAgeHBhdGhTdXBwb3J0LnNldFZhclN0YWNrKG5ldyBKQVhQVmFyaWFibGVTdGFjayh2YXJpYWJsZVJlc29sdmVyKSk7Ci0gICAgICAgIFhPYmplY3QgeG9iaiA9IG51bGw7Ci0KLSAgICAgICAgTm9kZSBjb250ZXh0Tm9kZSA9IChOb2RlKWNvbnRleHRJdGVtOwotICAgICAgICAvLyBXZSBhbHdheXMgbmVlZCB0byBoYXZlIGEgQ29udGV4dE5vZGUgd2l0aCBYYWxhbiBYUGF0aCBpbXBsZW1lbnRhdGlvbgotICAgICAgICAvLyBUbyBhbGxvdyBzaW1wbGUgZXhwcmVzc2lvbiBldmFsdWF0aW9uIGxpa2UgMSsxIHdlIGFyZSBzZXR0aW5nCi0gICAgICAgIC8vIGR1bW15IERvY3VtZW50IGFzIENvbnRleHQgTm9kZQotCi0gICAgICAgIGlmICggY29udGV4dE5vZGUgPT0gbnVsbCApCi0gICAgICAgICAgICB4b2JqID0geHBhdGguZXhlY3V0ZSh4cGF0aFN1cHBvcnQsIERUTS5OVUxMLCBwcmVmaXhSZXNvbHZlcik7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICAgIHhvYmogPSB4cGF0aC5leGVjdXRlKHhwYXRoU3VwcG9ydCwgY29udGV4dE5vZGUsIHByZWZpeFJlc29sdmVyKTsKLQotICAgICAgICByZXR1cm4geG9iajsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIDxwPkV2YWx1YXRlIHRoZSBjb21waWxlZCBYUGF0aCBleHByZXNzaW9uIGluIHRoZSBzcGVjaWZpZWQgY29udGV4dCBhbmQKLSAgICAgKiAgcmV0dXJuIHRoZSByZXN1bHQgYXMgdGhlIHNwZWNpZmllZCB0eXBlLjwvcD4KLSAgICAgKgotICAgICAqIDxwPlNlZSAiRXZhbHVhdGlvbiBvZiBYUGF0aCBFeHByZXNzaW9ucyIgc2VjdGlvbiBvZiBKQVhQIDEuMyBzcGVjCi0gICAgICogZm9yIGNvbnRleHQgaXRlbSBldmFsdWF0aW9uLAotICAgICAqIHZhcmlhYmxlLCBmdW5jdGlvbiBhbmQgUU5hbWUgcmVzb2x1dGlvbiBhbmQgcmV0dXJuIHR5cGUgY29udmVyc2lvbi48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5JZiA8Y29kZT5yZXR1cm5UeXBlPC9jb2RlPiBpcyBub3Qgb25lIG9mIHRoZSB0eXBlcyBkZWZpbmVkCi0gICAgICogaW4ge0BsaW5rIFhQYXRoQ29uc3RhbnRzfSwKLSAgICAgKiB0aGVuIGFuIDxjb2RlPklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbjwvY29kZT4gaXMgdGhyb3duLjwvcD4KLSAgICAgKgotICAgICAqIDxwPklmIGEgPGNvZGU+bnVsbDwvY29kZT4gdmFsdWUgaXMgcHJvdmlkZWQgZm9yCi0gICAgICogPGNvZGU+aXRlbTwvY29kZT4sIGFuIGVtcHR5IGRvY3VtZW50IHdpbGwgYmUgdXNlZCBmb3IgdGhlCi0gICAgICogY29udGV4dC4KLSAgICAgKiBJZiA8Y29kZT5yZXR1cm5UeXBlPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPiwgdGhlbiBhCi0gICAgICogPGNvZGU+TnVsbFBvaW50ZXJFeGNlcHRpb248L2NvZGU+IGlzIHRocm93bi48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gaXRlbSBUaGUgc3RhcnRpbmcgY29udGV4dCAobm9kZSBvciBub2RlIGxpc3QsIGZvciBleGFtcGxlKS4KLSAgICAgKiBAcGFyYW0gcmV0dXJuVHlwZSBUaGUgZGVzaXJlZCByZXR1cm4gdHlwZS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIDxjb2RlPk9iamVjdDwvY29kZT4gdGhhdCBpcyB0aGUgcmVzdWx0IG9mIGV2YWx1YXRpbmcgdGhlCi0gICAgICogZXhwcmVzc2lvbiBhbmQgY29udmVydGluZyB0aGUgcmVzdWx0IHRvCi0gICAgICogICA8Y29kZT5yZXR1cm5UeXBlPC9jb2RlPi4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWFBhdGhFeHByZXNzaW9uRXhjZXB0aW9uIElmIHRoZSBleHByZXNzaW9uIGNhbm5vdCBiZSBldmFsdWF0ZWQuCi0gICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gSWYgPGNvZGU+cmV0dXJuVHlwZTwvY29kZT4gaXMgbm90IG9uZQotICAgICAqIG9mIHRoZSB0eXBlcyBkZWZpbmVkIGluIHtAbGluayBYUGF0aENvbnN0YW50c30uCi0gICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBJZiAgPGNvZGU+cmV0dXJuVHlwZTwvY29kZT4gaXMKLSAgICAgKiA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0IGV2YWx1YXRlKE9iamVjdCBpdGVtLCBRTmFtZSByZXR1cm5UeXBlKQotICAgICAgICB0aHJvd3MgWFBhdGhFeHByZXNzaW9uRXhjZXB0aW9uIHsKLSAgICAgICAgLy9WYWxpZGF0aW5nIHBhcmFtZXRlcnMgdG8gZW5mb3JjZSBjb25zdHJhaW50cyBkZWZpbmVkIGJ5IEpBWFAgc3BlYwotICAgICAgICBpZiAoIHJldHVyblR5cGUgPT0gbnVsbCApIHsKLSAgICAgICAgICAgLy9UaHJvd2luZyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBhcyBkZWZpbmVkIGluIHNwZWMKLSAgICAgICAgICAgIFN0cmluZyBmbXNnID0gWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKAotICAgICAgICAgICAgICAgICAgICBYUEFUSEVycm9yUmVzb3VyY2VzLkVSX0FSR19DQU5OT1RfQkVfTlVMTCwKLSAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsicmV0dXJuVHlwZSJ9ICk7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIGZtc2cgKTsKLSAgICAgICAgfQotICAgICAgICAvLyBDaGVja2luZyBpZiByZXF1ZXN0ZWQgcmV0dXJuVHlwZSBpcyBzdXBwb3J0ZWQuIHJldHVyblR5cGUgbmVlZCB0byBiZQotICAgICAgICAvLyBkZWZpbmVkIGluIFhQYXRoQ29uc3RhbnRzCi0gICAgICAgIGlmICggIWlzU3VwcG9ydGVkICggcmV0dXJuVHlwZSApICkgewotICAgICAgICAgICAgU3RyaW5nIGZtc2cgPSBYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoCi0gICAgICAgICAgICAgICAgICAgIFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfVU5TVVBQT1JURURfUkVUVVJOX1RZUEUsCi0gICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7IHJldHVyblR5cGUudG9TdHJpbmcoKSB9ICk7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uICggZm1zZyApOwotICAgICAgICB9Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICByZXR1cm4gZXZhbCggaXRlbSwgcmV0dXJuVHlwZSk7Ci0gICAgICAgIH0gY2F0Y2ggKCBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24gbnBlICkgewotICAgICAgICAgICAgLy8gSWYgVmFyaWFibGVSZXNvbHZlciByZXR1cm5zIG51bGwgT3IgaWYgd2UgZ2V0Ci0gICAgICAgICAgICAvLyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBhdCB0aGlzIHN0YWdlIGZvciBzb21lIG90aGVyIHJlYXNvbgotICAgICAgICAgICAgLy8gdGhlbiB3ZSBoYXZlIHRvIHJldXJuIFhQYXRoRXhjZXB0aW9uCi0gICAgICAgICAgICB0aHJvdyBuZXcgWFBhdGhFeHByZXNzaW9uRXhjZXB0aW9uICggbnBlICk7Ci0gICAgICAgIH0gY2F0Y2ggKCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uIHRlICkgewotICAgICAgICAgICAgVGhyb3dhYmxlIG5lc3RlZEV4Y2VwdGlvbiA9IHRlLmdldEV4Y2VwdGlvbigpOwotICAgICAgICAgICAgaWYgKCBuZXN0ZWRFeGNlcHRpb24gaW5zdGFuY2VvZiBqYXZheC54bWwueHBhdGguWFBhdGhGdW5jdGlvbkV4Y2VwdGlvbiApIHsKLSAgICAgICAgICAgICAgICB0aHJvdyAoamF2YXgueG1sLnhwYXRoLlhQYXRoRnVuY3Rpb25FeGNlcHRpb24pbmVzdGVkRXhjZXB0aW9uOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAvLyBGb3IgYW55IG90aGVyIGV4Y2VwdGlvbnMgd2UgbmVlZCB0byB0aHJvdwotICAgICAgICAgICAgICAgIC8vIFhQYXRoRXhwcmVzc2lvbkV4Y2VwdGlvbiAoIGFzIHBlciBzcGVjICkKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWFBhdGhFeHByZXNzaW9uRXhjZXB0aW9uKCB0ZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPkV2YWx1YXRlIHRoZSBjb21waWxlZCBYUGF0aCBleHByZXNzaW9uIGluIHRoZSBzcGVjaWZpZWQgY29udGV4dCBhbmQKLSAgICAgKiByZXR1cm4gdGhlIHJlc3VsdCBhcyBhIDxjb2RlPlN0cmluZzwvY29kZT4uPC9wPgotICAgICAqCi0gICAgICogPHA+VGhpcyBtZXRob2QgY2FsbHMge0BsaW5rICNldmFsdWF0ZShPYmplY3QgaXRlbSwgUU5hbWUgcmV0dXJuVHlwZSl9Ci0gICAgICogd2l0aCBhIDxjb2RlPnJldHVyblR5cGU8L2NvZGU+IG9mCi0gICAgICoge0BsaW5rIFhQYXRoQ29uc3RhbnRzI1NUUklOR30uPC9wPgotICAgICAqCi0gICAgICogPHA+U2VlICJFdmFsdWF0aW9uIG9mIFhQYXRoIEV4cHJlc3Npb25zIiBzZWN0aW9uIG9mIEpBWFAgMS4zIHNwZWMKLSAgICAgKiAgZm9yIGNvbnRleHQgaXRlbSBldmFsdWF0aW9uLAotICAgICAqIHZhcmlhYmxlLCBmdW5jdGlvbiBhbmQgUU5hbWUgcmVzb2x1dGlvbiBhbmQgcmV0dXJuIHR5cGUgY29udmVyc2lvbi48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5JZiBhIDxjb2RlPm51bGw8L2NvZGU+IHZhbHVlIGlzIHByb3ZpZGVkIGZvcgotICAgICAqIDxjb2RlPml0ZW08L2NvZGU+LCBhbiBlbXB0eSBkb2N1bWVudCB3aWxsIGJlIHVzZWQgZm9yIHRoZQotICAgICAqIGNvbnRleHQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaXRlbSBUaGUgc3RhcnRpbmcgY29udGV4dCAobm9kZSBvciBub2RlIGxpc3QsIGZvciBleGFtcGxlKS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIDxjb2RlPlN0cmluZzwvY29kZT4gdGhhdCBpcyB0aGUgcmVzdWx0IG9mIGV2YWx1YXRpbmcgdGhlCi0gICAgICogZXhwcmVzc2lvbiBhbmQgY29udmVydGluZyB0aGUgcmVzdWx0IHRvIGEKLSAgICAgKiAgIDxjb2RlPlN0cmluZzwvY29kZT4uCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhQYXRoRXhwcmVzc2lvbkV4Y2VwdGlvbiBJZiB0aGUgZXhwcmVzc2lvbiBjYW5ub3QgYmUgZXZhbHVhdGVkLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZXZhbHVhdGUoT2JqZWN0IGl0ZW0pCi0gICAgICAgIHRocm93cyBYUGF0aEV4cHJlc3Npb25FeGNlcHRpb24gewotICAgICAgICByZXR1cm4gKFN0cmluZyl0aGlzLmV2YWx1YXRlKCBpdGVtLCBYUGF0aENvbnN0YW50cy5TVFJJTkcgKTsKLSAgICB9Ci0KLQotCi0gICAgc3RhdGljIERvY3VtZW50QnVpbGRlckZhY3RvcnkgZGJmID0gbnVsbDsKLSAgICBzdGF0aWMgRG9jdW1lbnRCdWlsZGVyIGRiID0gbnVsbDsKLSAgICBzdGF0aWMgRG9jdW1lbnQgZCA9IG51bGw7Ci0KLSAgICAvKioKLSAgICAgKiA8cD5FdmFsdWF0ZSB0aGUgY29tcGlsZWQgWFBhdGggZXhwcmVzc2lvbiBpbiB0aGUgY29udGV4dCBvZiB0aGUKLSAgICAgKiBzcGVjaWZpZWQgPGNvZGU+SW5wdXRTb3VyY2U8L2NvZGU+IGFuZCByZXR1cm4gdGhlIHJlc3VsdCBhcyB0aGUKLSAgICAgKiAgc3BlY2lmaWVkIHR5cGUuPC9wPgotICAgICAqCi0gICAgICogPHA+VGhpcyBtZXRob2QgYnVpbGRzIGEgZGF0YSBtb2RlbCBmb3IgdGhlIHtAbGluayBJbnB1dFNvdXJjZX0gYW5kIGNhbGxzCi0gICAgICoge0BsaW5rICNldmFsdWF0ZShPYmplY3QgaXRlbSwgUU5hbWUgcmV0dXJuVHlwZSl9IG9uIHRoZSByZXN1bHRpbmcKLSAgICAgKiBkb2N1bWVudCBvYmplY3QuPC9wPgotICAgICAqCi0gICAgICogPHA+U2VlICJFdmFsdWF0aW9uIG9mIFhQYXRoIEV4cHJlc3Npb25zIiBzZWN0aW9uIG9mIEpBWFAgMS4zIHNwZWMKLSAgICAgKiAgZm9yIGNvbnRleHQgaXRlbSBldmFsdWF0aW9uLAotICAgICAqIHZhcmlhYmxlLCBmdW5jdGlvbiBhbmQgUU5hbWUgcmVzb2x1dGlvbiBhbmQgcmV0dXJuIHR5cGUgY29udmVyc2lvbi48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5JZiA8Y29kZT5yZXR1cm5UeXBlPC9jb2RlPiBpcyBub3Qgb25lIG9mIHRoZSB0eXBlcyBkZWZpbmVkIGluCi0gICAgICoge0BsaW5rIFhQYXRoQ29uc3RhbnRzfSwKLSAgICAgKiB0aGVuIGFuIDxjb2RlPklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbjwvY29kZT4gaXMgdGhyb3duLjwvcD4KLSAgICAgKgotICAgICAqPHA+SWYgPGNvZGU+c291cmNlPC9jb2RlPiBvciA8Y29kZT5yZXR1cm5UeXBlPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPiwKLSAgICAgKiB0aGVuIGEgPGNvZGU+TnVsbFBvaW50ZXJFeGNlcHRpb248L2NvZGU+IGlzIHRocm93bi48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gc291cmNlIFRoZSA8Y29kZT5JbnB1dFNvdXJjZTwvY29kZT4gb2YgdGhlIGRvY3VtZW50IHRvIGV2YWx1YXRlCi0gICAgICogb3Zlci4KLSAgICAgKiBAcGFyYW0gcmV0dXJuVHlwZSBUaGUgZGVzaXJlZCByZXR1cm4gdHlwZS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIDxjb2RlPk9iamVjdDwvY29kZT4gdGhhdCBpcyB0aGUgcmVzdWx0IG9mIGV2YWx1YXRpbmcgdGhlCi0gICAgICogZXhwcmVzc2lvbiBhbmQgY29udmVydGluZyB0aGUgcmVzdWx0IHRvCi0gICAgICogICA8Y29kZT5yZXR1cm5UeXBlPC9jb2RlPi4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWFBhdGhFeHByZXNzaW9uRXhjZXB0aW9uIElmIHRoZSBleHByZXNzaW9uIGNhbm5vdCBiZSBldmFsdWF0ZWQuCi0gICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gSWYgPGNvZGU+cmV0dXJuVHlwZTwvY29kZT4gaXMgbm90IG9uZQotICAgICAqIG9mIHRoZSB0eXBlcyBkZWZpbmVkIGluIHtAbGluayBYUGF0aENvbnN0YW50c30uCi0gICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBJZiAgPGNvZGU+c291cmNlPC9jb2RlPiBvcgotICAgICAqIDxjb2RlPnJldHVyblR5cGU8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBPYmplY3QgZXZhbHVhdGUoSW5wdXRTb3VyY2Ugc291cmNlLCBRTmFtZSByZXR1cm5UeXBlKQotICAgICAgICB0aHJvd3MgWFBhdGhFeHByZXNzaW9uRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKCAoIHNvdXJjZSA9PSBudWxsICkgfHwgKCByZXR1cm5UeXBlID09IG51bGwgKSApIHsKLSAgICAgICAgICAgIFN0cmluZyBmbXNnID0gWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKAotICAgICAgICAgICAgICAgICAgICBYUEFUSEVycm9yUmVzb3VyY2VzLkVSX1NPVVJDRV9SRVRVUk5fVFlQRV9DQU5OT1RfQkVfTlVMTCwKLSAgICAgICAgICAgICAgICAgICAgbnVsbCApOwotICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uICggZm1zZyApOwotICAgICAgICB9Ci0gICAgICAgIC8vIENoZWNraW5nIGlmIHJlcXVlc3RlZCByZXR1cm5UeXBlIGlzIHN1cHBvcnRlZC4gcmV0dXJuVHlwZSBuZWVkIHRvIGJlCi0gICAgICAgIC8vIGRlZmluZWQgaW4gWFBhdGhDb25zdGFudHMKLSAgICAgICAgaWYgKCAhaXNTdXBwb3J0ZWQgKCByZXR1cm5UeXBlICkgKSB7Ci0gICAgICAgICAgICBTdHJpbmcgZm1zZyA9IFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZSgKLSAgICAgICAgICAgICAgICAgICAgWFBBVEhFcnJvclJlc291cmNlcy5FUl9VTlNVUFBPUlRFRF9SRVRVUk5fVFlQRSwKLSAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgcmV0dXJuVHlwZS50b1N0cmluZygpIH0gKTsKLSAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gKCBmbXNnICk7Ci0gICAgICAgIH0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGlmICggZGJmID09IG51bGwgKSB7Ci0gICAgICAgICAgICAgICAgZGJmID0gRmFjdG9yeUltcGwuZ2V0RE9NRmFjdG9yeSh1c2VTZXJ2aWNlc01lY2hhbmlzbSk7Ci0gICAgICAgICAgICAgICAgZGJmLnNldE5hbWVzcGFjZUF3YXJlKCB0cnVlICk7Ci0gICAgICAgICAgICAgICAgZGJmLnNldFZhbGlkYXRpbmcoIGZhbHNlICk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBkYiA9IGRiZi5uZXdEb2N1bWVudEJ1aWxkZXIoKTsKLSAgICAgICAgICAgIERvY3VtZW50IGRvY3VtZW50ID0gZGIucGFyc2UoIHNvdXJjZSApOwotICAgICAgICAgICAgcmV0dXJuIGV2YWwoICBkb2N1bWVudCwgcmV0dXJuVHlwZSApOwotICAgICAgICB9IGNhdGNoICggRXhjZXB0aW9uIGUgKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWFBhdGhFeHByZXNzaW9uRXhjZXB0aW9uICggZSApOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+RXZhbHVhdGUgdGhlIGNvbXBpbGVkIFhQYXRoIGV4cHJlc3Npb24gaW4gdGhlIGNvbnRleHQgb2YgdGhlIHNwZWNpZmllZCA8Y29kZT5JbnB1dFNvdXJjZTwvY29kZT4gYW5kIHJldHVybiB0aGUgcmVzdWx0IGFzIGEKLSAgICAgKiA8Y29kZT5TdHJpbmc8L2NvZGU+LjwvcD4KLSAgICAgKgotICAgICAqIDxwPlRoaXMgbWV0aG9kIGNhbGxzIHtAbGluayAjZXZhbHVhdGUoSW5wdXRTb3VyY2Ugc291cmNlLCBRTmFtZSByZXR1cm5UeXBlKX0gd2l0aCBhIDxjb2RlPnJldHVyblR5cGU8L2NvZGU+IG9mCi0gICAgICoge0BsaW5rIFhQYXRoQ29uc3RhbnRzI1NUUklOR30uPC9wPgotICAgICAqCi0gICAgICogPHA+U2VlICJFdmFsdWF0aW9uIG9mIFhQYXRoIEV4cHJlc3Npb25zIiBzZWN0aW9uIG9mIEpBWFAgMS4zIHNwZWMKLSAgICAgKiBmb3IgY29udGV4dCBpdGVtIGV2YWx1YXRpb24sCi0gICAgICogdmFyaWFibGUsIGZ1bmN0aW9uIGFuZCBRTmFtZSByZXNvbHV0aW9uIGFuZCByZXR1cm4gdHlwZSBjb252ZXJzaW9uLjwvcD4KLSAgICAgKgotICAgICAqIDxwPklmIDxjb2RlPnNvdXJjZTwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4sIHRoZW4gYSA8Y29kZT5OdWxsUG9pbnRlckV4Y2VwdGlvbjwvY29kZT4gaXMgdGhyb3duLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzb3VyY2UgVGhlIDxjb2RlPklucHV0U291cmNlPC9jb2RlPiBvZiB0aGUgZG9jdW1lbnQgdG8gZXZhbHVhdGUgb3Zlci4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIDxjb2RlPlN0cmluZzwvY29kZT4gdGhhdCBpcyB0aGUgcmVzdWx0IG9mIGV2YWx1YXRpbmcgdGhlIGV4cHJlc3Npb24gYW5kIGNvbnZlcnRpbmcgdGhlIHJlc3VsdCB0byBhCi0gICAgICogICA8Y29kZT5TdHJpbmc8L2NvZGU+LgotICAgICAqCi0gICAgICogQHRocm93cyBYUGF0aEV4cHJlc3Npb25FeGNlcHRpb24gSWYgdGhlIGV4cHJlc3Npb24gY2Fubm90IGJlIGV2YWx1YXRlZC4KLSAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIElmICA8Y29kZT5zb3VyY2U8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZXZhbHVhdGUoSW5wdXRTb3VyY2Ugc291cmNlKQotICAgICAgICB0aHJvd3MgWFBhdGhFeHByZXNzaW9uRXhjZXB0aW9uIHsKLSAgICAgICAgcmV0dXJuIChTdHJpbmcpdGhpcy5ldmFsdWF0ZSggc291cmNlLCBYUGF0aENvbnN0YW50cy5TVFJJTkcgKTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIGJvb2xlYW4gaXNTdXBwb3J0ZWQoIFFOYW1lIHJldHVyblR5cGUgKSB7Ci0gICAgICAgIC8vIFhQYXRoQ29uc3RhbnRzLlNUUklORwotICAgICAgICBpZiAoICggcmV0dXJuVHlwZS5lcXVhbHMoIFhQYXRoQ29uc3RhbnRzLlNUUklORyApICkgfHwKLSAgICAgICAgICAgICAoIHJldHVyblR5cGUuZXF1YWxzKCBYUGF0aENvbnN0YW50cy5OVU1CRVIgKSApIHx8Ci0gICAgICAgICAgICAgKCByZXR1cm5UeXBlLmVxdWFscyggWFBhdGhDb25zdGFudHMuQk9PTEVBTiApICkgfHwKLSAgICAgICAgICAgICAoIHJldHVyblR5cGUuZXF1YWxzKCBYUGF0aENvbnN0YW50cy5OT0RFICkgKSB8fAotICAgICAgICAgICAgICggcmV0dXJuVHlwZS5lcXVhbHMoIFhQYXRoQ29uc3RhbnRzLk5PREVTRVQgKSApICApIHsKLQotICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICB9Ci0KLSAgICAgcHJpdmF0ZSBPYmplY3QgZ2V0UmVzdWx0QXNUeXBlKCBYT2JqZWN0IHJlc3VsdE9iamVjdCwgUU5hbWUgcmV0dXJuVHlwZSApCi0gICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uIHsKLSAgICAgICAgLy8gWFBhdGhDb25zdGFudHMuU1RSSU5HCi0gICAgICAgIGlmICggcmV0dXJuVHlwZS5lcXVhbHMoIFhQYXRoQ29uc3RhbnRzLlNUUklORyApICkgewotICAgICAgICAgICAgcmV0dXJuIHJlc3VsdE9iamVjdC5zdHIoKTsKLSAgICAgICAgfQotICAgICAgICAvLyBYUGF0aENvbnN0YW50cy5OVU1CRVIKLSAgICAgICAgaWYgKCByZXR1cm5UeXBlLmVxdWFscyggWFBhdGhDb25zdGFudHMuTlVNQkVSICkgKSB7Ci0gICAgICAgICAgICByZXR1cm4gbmV3IERvdWJsZSAoIHJlc3VsdE9iamVjdC5udW0oKSk7Ci0gICAgICAgIH0KLSAgICAgICAgLy8gWFBhdGhDb25zdGFudHMuQk9PTEVBTgotICAgICAgICBpZiAoIHJldHVyblR5cGUuZXF1YWxzKCBYUGF0aENvbnN0YW50cy5CT09MRUFOICkgKSB7Ci0gICAgICAgICAgICByZXR1cm4gbmV3IEJvb2xlYW4oIHJlc3VsdE9iamVjdC5ib29sKCkpOwotICAgICAgICB9Ci0gICAgICAgIC8vIFhQYXRoQ29uc3RhbnRzLk5PREVTRVQgLS0tT1JkZXJlZCwgVU5PcmRlcmVkPz8/Ci0gICAgICAgIGlmICggcmV0dXJuVHlwZS5lcXVhbHMoIFhQYXRoQ29uc3RhbnRzLk5PREVTRVQgKSApIHsKLSAgICAgICAgICAgIHJldHVybiByZXN1bHRPYmplY3Qubm9kZWxpc3QoKTsKLSAgICAgICAgfQotICAgICAgICAvLyBYUGF0aENvbnN0YW50cy5OT0RFCi0gICAgICAgIGlmICggcmV0dXJuVHlwZS5lcXVhbHMoIFhQYXRoQ29uc3RhbnRzLk5PREUgKSApIHsKLSAgICAgICAgICAgIE5vZGVJdGVyYXRvciBuaSA9IHJlc3VsdE9iamVjdC5ub2Rlc2V0KCk7Ci0gICAgICAgICAgICAvL1JldHVybiB0aGUgZmlyc3Qgbm9kZSwgb3IgbnVsbAotICAgICAgICAgICAgcmV0dXJuIG5pLm5leHROb2RlKCk7Ci0gICAgICAgIH0KLSAgICAgICAgLy8gSWYgaXNTdXBwb3J0ZWQgY2hlY2sgaXMgYWxyZWFkeSBkb25lIHRoZW4gdGhlIGV4ZWN1dGlvbiBwYXRoCi0gICAgICAgIC8vIHNob3VsZG4ndCBjb21lIGhlcmUuIEJlaW5nIGRlZmVuc2l2ZQotICAgICAgICBTdHJpbmcgZm1zZyA9IFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZSgKLSAgICAgICAgICAgICAgICBYUEFUSEVycm9yUmVzb3VyY2VzLkVSX1VOU1VQUE9SVEVEX1JFVFVSTl9UWVBFLAotICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7IHJldHVyblR5cGUudG9TdHJpbmcoKX0pOwotICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uICggZm1zZyApOwotICAgIH0KLQotIH0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvamF4cC9YUGF0aEZhY3RvcnlJbXBsLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL2pheHAvWFBhdGhGYWN0b3J5SW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiMDUwYWY0Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvamF4cC9YUGF0aEZhY3RvcnlJbXBsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzMjggKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLy8gJElkOiBYUGF0aEZhY3RvcnlJbXBsLmphdmEsdiAxLjIgMjAwNS8wOC8xNiAyMjo0MToxMyBqZWZmc3V0dG9yIEV4cCAkCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmpheHA7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwuWGFsYW5Db25zdGFudHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLnJlcy5YUEFUSEVycm9yUmVzb3VyY2VzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC5yZXMuWFNMTWVzc2FnZXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnV0aWxzLkZlYXR1cmVNYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC51dGlscy5GZWF0dXJlUHJvcGVydHlCYXNlOwotCi1pbXBvcnQgamF2YXgueG1sLlhNTENvbnN0YW50czsKLWltcG9ydCBqYXZheC54bWwueHBhdGguWFBhdGhGYWN0b3J5OwotaW1wb3J0IGphdmF4LnhtbC54cGF0aC5YUGF0aEZhY3RvcnlDb25maWd1cmF0aW9uRXhjZXB0aW9uOwotaW1wb3J0IGphdmF4LnhtbC54cGF0aC5YUGF0aEZ1bmN0aW9uUmVzb2x2ZXI7Ci1pbXBvcnQgamF2YXgueG1sLnhwYXRoLlhQYXRoVmFyaWFibGVSZXNvbHZlcjsKLQotLyoqCi0gKiBUaGUgWFBhdGhGYWN0b3J5IGJ1aWxkcyBYUGF0aHMuCi0gKgotICogQHZlcnNpb24gJFJldmlzaW9uOiAxLjExICQKLSAqIEBhdXRob3IgIFJhbWVzaCBNYW5kYXZhCi0gKi8KLXB1YmxpYyAgY2xhc3MgWFBhdGhGYWN0b3J5SW1wbCBleHRlbmRzIFhQYXRoRmFjdG9yeSB7Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIDxwPk5hbWUgb2YgY2xhc3MgYXMgYSBjb25zdGFudCB0byB1c2UgZm9yIGRlYnVnZ2luZy48L3A+Ci0gICAgICAgICAqLwotICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ0xBU1NfTkFNRSA9ICJYUGF0aEZhY3RvcnlJbXBsIjsKLQotICAgICAgICAvKioKLSAgICAgICAgICo8cD5YUGF0aEZ1bmN0aW9uUmVzb2x2ZXIgZm9yIHRoaXMgWFBhdGhGYWN0b3J5IGFuZCBjcmVhdGVkIFhQYXRocy48L3A+Ci0gICAgICAgICAqLwotICAgICAgICBwcml2YXRlIFhQYXRoRnVuY3Rpb25SZXNvbHZlciB4UGF0aEZ1bmN0aW9uUmVzb2x2ZXIgPSBudWxsOwotCi0gICAgICAgIC8qKgotICAgICAgICAgKiA8cD5YUGF0aFZhcmlhYmxlUmVzb2x2ZXIgZm9yIHRoaXMgWFBhdGhGYWN0b3J5IGFuZCBjcmVhdGVkIFhQYXRoczwvcD4KLSAgICAgICAgICovCi0gICAgICAgIHByaXZhdGUgWFBhdGhWYXJpYWJsZVJlc29sdmVyIHhQYXRoVmFyaWFibGVSZXNvbHZlciA9IG51bGw7Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIDxwPlN0YXRlIG9mIHNlY3VyZSBwcm9jZXNzaW5nIGZlYXR1cmUuPC9wPgotICAgICAgICAgKi8KLSAgICAgICAgcHJpdmF0ZSBib29sZWFuIF9pc05vdFNlY3VyZVByb2Nlc3NpbmcgPSB0cnVlOwotICAgICAgICAvKioKLSAgICAgICAgICogPHA+U3RhdGUgb2Ygc2VjdXJlIG1vZGUuPC9wPgotICAgICAgICAgKi8KLSAgICAgICAgcHJpdmF0ZSBib29sZWFuIF9pc1NlY3VyZU1vZGUgPSBmYWxzZTsKLSAgICAgICAgLyoqCi0gICAgICAgICAqIGphdmF4LnhtbC54cGF0aC5YUGF0aEZhY3RvcnkgaW1wbGVtZW50YXRpb24uCi0gICAgICAgICAqLwotCi0gICAgICAgIHByaXZhdGUgYm9vbGVhbiBfdXNlU2VydmljZXNNZWNoYW5pc20gPSB0cnVlOwotCi0gICAgICAgIHByaXZhdGUgZmluYWwgRmVhdHVyZU1hbmFnZXIgX2ZlYXR1cmVNYW5hZ2VyOwotCi0gICAgICAgIHB1YmxpYyBYUGF0aEZhY3RvcnlJbXBsKCkgewotICAgICAgICAgICAgdGhpcyh0cnVlKTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyBzdGF0aWMgWFBhdGhGYWN0b3J5IG5ld1hQYXRoRmFjdG9yeU5vU2VydmljZUxvYWRlcigpIHsKLSAgICAgICAgICAgIHJldHVybiBuZXcgWFBhdGhGYWN0b3J5SW1wbChmYWxzZSk7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgWFBhdGhGYWN0b3J5SW1wbChib29sZWFuIHVzZVNlcnZpY2VzTWVjaGFuaXNtKSB7Ci0gICAgICAgICAgICBfZmVhdHVyZU1hbmFnZXIgPSBuZXcgRmVhdHVyZU1hbmFnZXIoKTsKLSAgICAgICAgICAgIGlmIChTeXN0ZW0uZ2V0U2VjdXJpdHlNYW5hZ2VyKCkgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIF9pc1NlY3VyZU1vZGUgPSB0cnVlOwotICAgICAgICAgICAgICAgIF9pc05vdFNlY3VyZVByb2Nlc3NpbmcgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICBfZmVhdHVyZU1hbmFnZXIuc2V0VmFsdWUoRmVhdHVyZU1hbmFnZXIuRmVhdHVyZS5PUkFDTEVfRU5BQkxFX0VYVEVOU0lPTl9GVU5DVElPTiwKLSAgICAgICAgICAgICAgICAgICAgICAgIEZlYXR1cmVQcm9wZXJ0eUJhc2UuU3RhdGUuRlNQLCBYYWxhbkNvbnN0YW50cy5GRUFUVVJFX0ZBTFNFKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHRoaXMuX3VzZVNlcnZpY2VzTWVjaGFuaXNtID0gdXNlU2VydmljZXNNZWNoYW5pc207Ci0gICAgICAgIH0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIDxwPklzIHNwZWNpZmllZCBvYmplY3QgbW9kZWwgc3VwcG9ydGVkIGJ5IHRoaXMKLSAgICAgICAgICogPGNvZGU+WFBhdGhGYWN0b3J5PC9jb2RlPj88L3A+Ci0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBvYmplY3RNb2RlbCBTcGVjaWZpZXMgdGhlIG9iamVjdCBtb2RlbCB3aGljaCB0aGUgcmV0dXJuZWQKLSAgICAgICAgICogPGNvZGU+WFBhdGhGYWN0b3J5PC9jb2RlPiB3aWxsIHVuZGVyc3RhbmQuCi0gICAgICAgICAqCi0gICAgICAgICAqIEByZXR1cm4gPGNvZGU+dHJ1ZTwvY29kZT4gaWYgPGNvZGU+WFBhdGhGYWN0b3J5PC9jb2RlPiBzdXBwb3J0cwotICAgICAgICAgKiA8Y29kZT5vYmplY3RNb2RlbDwvY29kZT4sIGVsc2UgPGNvZGU+ZmFsc2U8L2NvZGU+LgotICAgICAgICAgKgotICAgICAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIElmIDxjb2RlPm9iamVjdE1vZGVsPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICAgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gSWYgPGNvZGU+b2JqZWN0TW9kZWwubGVuZ3RoKCkgPT0gMDwvY29kZT4uCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc09iamVjdE1vZGVsU3VwcG9ydGVkKFN0cmluZyBvYmplY3RNb2RlbCkgewotCi0gICAgICAgICAgICBpZiAob2JqZWN0TW9kZWwgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIFN0cmluZyBmbXNnID0gWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKAotICAgICAgICAgICAgICAgICAgICAgICAgWFBBVEhFcnJvclJlc291cmNlcy5FUl9PQkpFQ1RfTU9ERUxfTlVMTCwKLSAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7IHRoaXMuZ2V0Q2xhc3MoKS5nZXROYW1lKCkgfSApOwotCi0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCBmbXNnICk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmIChvYmplY3RNb2RlbC5sZW5ndGgoKSA9PSAwKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIGZtc2cgPSBYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoCi0gICAgICAgICAgICAgICAgICAgICAgICBYUEFUSEVycm9yUmVzb3VyY2VzLkVSX09CSkVDVF9NT0RFTF9FTVBUWSwKLSAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7IHRoaXMuZ2V0Q2xhc3MoKS5nZXROYW1lKCkgfSApOwotICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIGZtc2cgKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8ga25vdyBob3cgdG8gc3VwcG9ydCBkZWZhdWx0IG9iamVjdCBtb2RlbCwgVzNDIERPTQotICAgICAgICAgICAgaWYgKG9iamVjdE1vZGVsLmVxdWFscyhYUGF0aEZhY3RvcnkuREVGQVVMVF9PQkpFQ1RfTU9ERUxfVVJJKSkgewotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBkb24ndCBrbm93IGhvdyB0byBzdXBwb3J0IGFueXRoaW5nIGVsc2UKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiA8cD5SZXR1cm5zIGEgbmV3IDxjb2RlPlhQYXRoPC9jb2RlPiBvYmplY3QgdXNpbmcgdGhlIHVuZGVybHlpbmcKLSAgICAgICAgICogb2JqZWN0IG1vZGVsIGRldGVybWluZWQgd2hlbiB0aGUgZmFjdG9yeSB3YXMgaW5zdGFudGlhdGVkLjwvcD4KLSAgICAgICAgICoKLSAgICAgICAgICogQHJldHVybiBOZXcgPGNvZGU+WFBhdGg8L2NvZGU+Ci0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgamF2YXgueG1sLnhwYXRoLlhQYXRoIG5ld1hQYXRoKCkgewotICAgICAgICAgICAgcmV0dXJuIG5ldyBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuamF4cC5YUGF0aEltcGwoCi0gICAgICAgICAgICAgICAgICAgIHhQYXRoVmFyaWFibGVSZXNvbHZlciwgeFBhdGhGdW5jdGlvblJlc29sdmVyLAotICAgICAgICAgICAgICAgICAgICAhX2lzTm90U2VjdXJlUHJvY2Vzc2luZywgX3VzZVNlcnZpY2VzTWVjaGFuaXNtLAotICAgICAgICAgICAgICAgICAgICBfZmVhdHVyZU1hbmFnZXIgKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiA8cD5TZXQgYSBmZWF0dXJlIGZvciB0aGlzIDxjb2RlPlhQYXRoRmFjdG9yeTwvY29kZT4gYW5kCi0gICAgICAgICAqIDxjb2RlPlhQYXRoPC9jb2RlPnMgY3JlYXRlZCBieSB0aGlzIGZhY3RvcnkuPC9wPgotICAgICAgICAgKgotICAgICAgICAgKiA8cD4KLSAgICAgICAgICogRmVhdHVyZSBuYW1lcyBhcmUgZnVsbHkgcXVhbGlmaWVkIHtAbGluayBqYXZhLm5ldC5VUkl9cy4KLSAgICAgICAgICogSW1wbGVtZW50YXRpb25zIG1heSBkZWZpbmUgdGhlaXIgb3duIGZlYXR1cmVzLgotICAgICAgICAgKiBBbiB7QGxpbmsgWFBhdGhGYWN0b3J5Q29uZmlndXJhdGlvbkV4Y2VwdGlvbn0gaXMgdGhyb3duIGlmIHRoaXMKLSAgICAgICAgICogPGNvZGU+WFBhdGhGYWN0b3J5PC9jb2RlPiBvciB0aGUgPGNvZGU+WFBhdGg8L2NvZGU+cwotICAgICAgICAgKiAgaXQgY3JlYXRlcyBjYW5ub3Qgc3VwcG9ydCB0aGUgZmVhdHVyZS4KLSAgICAgICAgICogSXQgaXMgcG9zc2libGUgZm9yIGFuIDxjb2RlPlhQYXRoRmFjdG9yeTwvY29kZT4gdG8gZXhwb3NlIGEgZmVhdHVyZQotICAgICAgICAgKiB2YWx1ZSBidXQgYmUgdW5hYmxlIHRvIGNoYW5nZSBpdHMgc3RhdGUuCi0gICAgICAgICAqIDwvcD4KLSAgICAgICAgICoKLSAgICAgICAgICogPHA+U2VlIHtAbGluayBqYXZheC54bWwueHBhdGguWFBhdGhGYWN0b3J5fSBmb3IgZnVsbCBkb2N1bWVudGF0aW9uCi0gICAgICAgICAqIG9mIHNwZWNpZmljIGZlYXR1cmVzLjwvcD4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIG5hbWUgRmVhdHVyZSBuYW1lLgotICAgICAgICAgKiBAcGFyYW0gdmFsdWUgSXMgZmVhdHVyZSBzdGF0ZSA8Y29kZT50cnVlPC9jb2RlPiBvciA8Y29kZT5mYWxzZTwvY29kZT4uCi0gICAgICAgICAqCi0gICAgICAgICAqIEB0aHJvd3MgWFBhdGhGYWN0b3J5Q29uZmlndXJhdGlvbkV4Y2VwdGlvbiBpZiB0aGlzCi0gICAgICAgICAqIDxjb2RlPlhQYXRoRmFjdG9yeTwvY29kZT4gb3IgdGhlIDxjb2RlPlhQYXRoPC9jb2RlPnMKLSAgICAgICAgICogICBpdCBjcmVhdGVzIGNhbm5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KLSAgICAgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiA8Y29kZT5uYW1lPC9jb2RlPiBpcwotICAgICAgICAgKiA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyB2b2lkIHNldEZlYXR1cmUoU3RyaW5nIG5hbWUsIGJvb2xlYW4gdmFsdWUpCi0gICAgICAgICAgICAgICAgdGhyb3dzIFhQYXRoRmFjdG9yeUNvbmZpZ3VyYXRpb25FeGNlcHRpb24gewotCi0gICAgICAgICAgICAvLyBmZWF0dXJlIG5hbWUgY2Fubm90IGJlIG51bGwKLSAgICAgICAgICAgIGlmIChuYW1lID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgZm1zZyA9IFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZSgKLSAgICAgICAgICAgICAgICAgICAgICAgIFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfRkVBVFVSRV9OQU1FX05VTEwsCi0gICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBDTEFTU19OQU1FLCBuZXcgQm9vbGVhbiggdmFsdWUpIH0gKTsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIGZtc2cgKTsKLSAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIHNlY3VyZSBwcm9jZXNzaW5nPwotICAgICAgICAgICAgaWYgKG5hbWUuZXF1YWxzKFhNTENvbnN0YW50cy5GRUFUVVJFX1NFQ1VSRV9QUk9DRVNTSU5HKSkgewotICAgICAgICAgICAgICAgIGlmICgoX2lzU2VjdXJlTW9kZSkgJiYgKCF2YWx1ZSkpIHsKLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGZtc2cgPSBYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgWFBBVEhFcnJvclJlc291cmNlcy5FUl9TRUNVUkVQUk9DRVNTSU5HX0ZFQVRVUkUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgbmFtZSwgQ0xBU1NfTkFNRSwgbmV3IEJvb2xlYW4odmFsdWUpIH0gKTsKLSAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFhQYXRoRmFjdG9yeUNvbmZpZ3VyYXRpb25FeGNlcHRpb24oIGZtc2cgKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBfaXNOb3RTZWN1cmVQcm9jZXNzaW5nID0gIXZhbHVlOwotICAgICAgICAgICAgICAgIGlmICh2YWx1ZSAmJiBfZmVhdHVyZU1hbmFnZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBfZmVhdHVyZU1hbmFnZXIuc2V0VmFsdWUoRmVhdHVyZU1hbmFnZXIuRmVhdHVyZS5PUkFDTEVfRU5BQkxFX0VYVEVOU0lPTl9GVU5DVElPTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBGZWF0dXJlUHJvcGVydHlCYXNlLlN0YXRlLkZTUCwgWGFsYW5Db25zdGFudHMuRkVBVFVSRV9GQUxTRSk7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgLy8gYWxsIGRvbmUgcHJvY2Vzc2luZyBmZWF0dXJlCi0gICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKG5hbWUuZXF1YWxzKFhhbGFuQ29uc3RhbnRzLk9SQUNMRV9GRUFUVVJFX1NFUlZJQ0VfTUVDSEFOSVNNKSkgewotICAgICAgICAgICAgICAgIC8vaW4gc2VjdXJlIG1vZGUsIGxldCBfdXNlU2VydmljZXNNZWNoYW5pc20gYmUgZGV0ZXJtaW5lZCBieSB0aGUgY29uc3RydWN0b3IKLSAgICAgICAgICAgICAgICBpZiAoIV9pc1NlY3VyZU1vZGUpCi0gICAgICAgICAgICAgICAgICAgIF91c2VTZXJ2aWNlc01lY2hhbmlzbSA9IHZhbHVlOwotICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKF9mZWF0dXJlTWFuYWdlciAhPSBudWxsICYmCi0gICAgICAgICAgICAgICAgICAgIF9mZWF0dXJlTWFuYWdlci5zZXRWYWx1ZShuYW1lLCBGZWF0dXJlUHJvcGVydHlCYXNlLlN0YXRlLkFQSVBST1BFUlRZLCB2YWx1ZSkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIHVua25vd24gZmVhdHVyZQotICAgICAgICAgICAgU3RyaW5nIGZtc2cgPSBYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoCi0gICAgICAgICAgICAgICAgICAgIFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfRkVBVFVSRV9VTktOT1dOLAotICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyBuYW1lLCBDTEFTU19OQU1FLCBuZXcgQm9vbGVhbih2YWx1ZSkgfSApOwotICAgICAgICAgICAgdGhyb3cgbmV3IFhQYXRoRmFjdG9yeUNvbmZpZ3VyYXRpb25FeGNlcHRpb24oIGZtc2cgKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiA8cD5HZXQgdGhlIHN0YXRlIG9mIHRoZSBuYW1lZCBmZWF0dXJlLjwvcD4KLSAgICAgICAgICoKLSAgICAgICAgICogPHA+Ci0gICAgICAgICAqIEZlYXR1cmUgbmFtZXMgYXJlIGZ1bGx5IHF1YWxpZmllZCB7QGxpbmsgamF2YS5uZXQuVVJJfXMuCi0gICAgICAgICAqIEltcGxlbWVudGF0aW9ucyBtYXkgZGVmaW5lIHRoZWlyIG93biBmZWF0dXJlcy4KLSAgICAgICAgICogQW4ge0BsaW5rIFhQYXRoRmFjdG9yeUNvbmZpZ3VyYXRpb25FeGNlcHRpb259IGlzIHRocm93biBpZiB0aGlzCi0gICAgICAgICAqIDxjb2RlPlhQYXRoRmFjdG9yeTwvY29kZT4gb3IgdGhlIDxjb2RlPlhQYXRoPC9jb2RlPnMKLSAgICAgICAgICogaXQgY3JlYXRlcyBjYW5ub3Qgc3VwcG9ydCB0aGUgZmVhdHVyZS4KLSAgICAgICAgICogSXQgaXMgcG9zc2libGUgZm9yIGFuIDxjb2RlPlhQYXRoRmFjdG9yeTwvY29kZT4gdG8gZXhwb3NlIGEgZmVhdHVyZQotICAgICAgICAgKiB2YWx1ZSBidXQgYmUgdW5hYmxlIHRvIGNoYW5nZSBpdHMgc3RhdGUuCi0gICAgICAgICAqIDwvcD4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIG5hbWUgRmVhdHVyZSBuYW1lLgotICAgICAgICAgKgotICAgICAgICAgKiBAcmV0dXJuIFN0YXRlIG9mIHRoZSBuYW1lZCBmZWF0dXJlLgotICAgICAgICAgKgotICAgICAgICAgKiBAdGhyb3dzIFhQYXRoRmFjdG9yeUNvbmZpZ3VyYXRpb25FeGNlcHRpb24gaWYgdGhpcwotICAgICAgICAgKiA8Y29kZT5YUGF0aEZhY3Rvcnk8L2NvZGU+IG9yIHRoZSA8Y29kZT5YUGF0aDwvY29kZT5zCi0gICAgICAgICAqICAgaXQgY3JlYXRlcyBjYW5ub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCi0gICAgICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgPGNvZGU+bmFtZTwvY29kZT4gaXMKLSAgICAgICAgICogPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgYm9vbGVhbiBnZXRGZWF0dXJlKFN0cmluZyBuYW1lKQotICAgICAgICAgICAgICAgIHRocm93cyBYUGF0aEZhY3RvcnlDb25maWd1cmF0aW9uRXhjZXB0aW9uIHsKLQotICAgICAgICAgICAgLy8gZmVhdHVyZSBuYW1lIGNhbm5vdCBiZSBudWxsCi0gICAgICAgICAgICBpZiAobmFtZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIGZtc2cgPSBYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoCi0gICAgICAgICAgICAgICAgICAgICAgICBYUEFUSEVycm9yUmVzb3VyY2VzLkVSX0dFVFRJTkdfTlVMTF9GRUFUVVJFLAotICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgQ0xBU1NfTkFNRSB9ICk7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCBmbXNnICk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIHNlY3VyZSBwcm9jZXNzaW5nPwotICAgICAgICAgICAgaWYgKG5hbWUuZXF1YWxzKFhNTENvbnN0YW50cy5GRUFUVVJFX1NFQ1VSRV9QUk9DRVNTSU5HKSkgewotICAgICAgICAgICAgICAgIHJldHVybiAhX2lzTm90U2VjdXJlUHJvY2Vzc2luZzsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChuYW1lLmVxdWFscyhYYWxhbkNvbnN0YW50cy5PUkFDTEVfRkVBVFVSRV9TRVJWSUNFX01FQ0hBTklTTSkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gX3VzZVNlcnZpY2VzTWVjaGFuaXNtOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvKiogQ2hlY2sgdG8gc2VlIGlmIHRoZSBwcm9wZXJ0eSBpcyBtYW5hZ2VkIGJ5IHRoZSBzZWN1cml0eSBtYW5hZ2VyICoqLwotICAgICAgICAgICAgU3RyaW5nIHByb3BlcnR5VmFsdWUgPSAoX2ZlYXR1cmVNYW5hZ2VyICE9IG51bGwpID8KLSAgICAgICAgICAgICAgICAgICAgX2ZlYXR1cmVNYW5hZ2VyLmdldFZhbHVlQXNTdHJpbmcobmFtZSkgOiBudWxsOwotICAgICAgICAgICAgaWYgKHByb3BlcnR5VmFsdWUgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJldHVybiBfZmVhdHVyZU1hbmFnZXIuaXNGZWF0dXJlRW5hYmxlZChuYW1lKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gdW5rbm93biBmZWF0dXJlCi0gICAgICAgICAgICBTdHJpbmcgZm1zZyA9IFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZSgKLSAgICAgICAgICAgICAgICAgICAgWFBBVEhFcnJvclJlc291cmNlcy5FUl9HRVRUSU5HX1VOS05PV05fRkVBVFVSRSwKLSAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgbmFtZSwgQ0xBU1NfTkFNRSB9ICk7Ci0KLSAgICAgICAgICAgIHRocm93IG5ldyBYUGF0aEZhY3RvcnlDb25maWd1cmF0aW9uRXhjZXB0aW9uKCBmbXNnICk7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogPHA+RXN0YWJsaXNoIGEgZGVmYXVsdCBmdW5jdGlvbiByZXNvbHZlci48L3A+Ci0gICAgICAgICAqCi0gICAgICAgICAqIDxwPkFueSA8Y29kZT5YUGF0aDwvY29kZT4gb2JqZWN0cyBjb25zdHJ1Y3RlZCBmcm9tIHRoaXMgZmFjdG9yeSB3aWxsIHVzZQotICAgICAgICAgKiB0aGUgc3BlY2lmaWVkIHJlc29sdmVyIGJ5IGRlZmF1bHQuPC9wPgotICAgICAgICAgKgotICAgICAgICAgKiA8cD5BIDxjb2RlPk51bGxQb2ludGVyRXhjZXB0aW9uPC9jb2RlPiBpcyB0aHJvd24gaWYKLSAgICAgICAgICogPGNvZGU+cmVzb2x2ZXI8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LjwvcD4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIHJlc29sdmVyIFhQYXRoIGZ1bmN0aW9uIHJlc29sdmVyLgotICAgICAgICAgKgotICAgICAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIElmIDxjb2RlPnJlc29sdmVyPC9jb2RlPiBpcwotICAgICAgICAgKiA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyB2b2lkIHNldFhQYXRoRnVuY3Rpb25SZXNvbHZlcihYUGF0aEZ1bmN0aW9uUmVzb2x2ZXIgcmVzb2x2ZXIpIHsKLQotICAgICAgICAgICAgLy8gcmVzb2x2ZXIgY2Fubm90IGJlIG51bGwKLSAgICAgICAgICAgIGlmIChyZXNvbHZlciA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIGZtc2cgPSBYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoCi0gICAgICAgICAgICAgICAgICAgICAgICBYUEFUSEVycm9yUmVzb3VyY2VzLkVSX05VTExfWFBBVEhfRlVOQ1RJT05fUkVTT0xWRVIsCi0gICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyAgQ0xBU1NfTkFNRSB9ICk7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCBmbXNnICk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIHhQYXRoRnVuY3Rpb25SZXNvbHZlciA9IHJlc29sdmVyOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIDxwPkVzdGFibGlzaCBhIGRlZmF1bHQgdmFyaWFibGUgcmVzb2x2ZXIuPC9wPgotICAgICAgICAgKgotICAgICAgICAgKiA8cD5BbnkgPGNvZGU+WFBhdGg8L2NvZGU+IG9iamVjdHMgY29uc3RydWN0ZWQgZnJvbSB0aGlzIGZhY3Rvcnkgd2lsbCB1c2UKLSAgICAgICAgICogdGhlIHNwZWNpZmllZCByZXNvbHZlciBieSBkZWZhdWx0LjwvcD4KLSAgICAgICAgICoKLSAgICAgICAgICogPHA+QSA8Y29kZT5OdWxsUG9pbnRlckV4Y2VwdGlvbjwvY29kZT4gaXMgdGhyb3duIGlmIDxjb2RlPnJlc29sdmVyPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPi48L3A+Ci0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSByZXNvbHZlciBWYXJpYWJsZSByZXNvbHZlci4KLSAgICAgICAgICoKLSAgICAgICAgICogIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gSWYgPGNvZGU+cmVzb2x2ZXI8L2NvZGU+IGlzCi0gICAgICAgICAqIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIHZvaWQgc2V0WFBhdGhWYXJpYWJsZVJlc29sdmVyKFhQYXRoVmFyaWFibGVSZXNvbHZlciByZXNvbHZlcikgewotCi0gICAgICAgICAgICAgICAgLy8gcmVzb2x2ZXIgY2Fubm90IGJlIG51bGwKLSAgICAgICAgICAgICAgICBpZiAocmVzb2x2ZXIgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgZm1zZyA9IFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZSgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBYUEFUSEVycm9yUmVzb3VyY2VzLkVSX05VTExfWFBBVEhfVkFSSUFCTEVfUkVTT0xWRVIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgIENMQVNTX05BTUUgfSApOwotICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIGZtc2cgKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICB4UGF0aFZhcmlhYmxlUmVzb2x2ZXIgPSByZXNvbHZlcjsKLSAgICAgICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9qYXhwL1hQYXRoSW1wbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9qYXhwL1hQYXRoSW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhZjgyZjM3Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvamF4cC9YUGF0aEltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDUzNyArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vLyAkSWQ6IFhQYXRoSW1wbC5qYXZhLHYgMS4yIDIwMDUvMDgvMTYgMjI6NDE6MDggamVmZnN1dHRvciBFeHAgJAotCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5qYXhwOwotCi1pbXBvcnQgamF2YXgueG1sLm5hbWVzcGFjZS5RTmFtZTsKLWltcG9ydCBqYXZheC54bWwubmFtZXNwYWNlLk5hbWVzcGFjZUNvbnRleHQ7Ci1pbXBvcnQgamF2YXgueG1sLnhwYXRoLlhQYXRoRXhwcmVzc2lvbkV4Y2VwdGlvbjsKLWltcG9ydCBqYXZheC54bWwueHBhdGguWFBhdGhDb25zdGFudHM7Ci1pbXBvcnQgamF2YXgueG1sLnhwYXRoLlhQYXRoRnVuY3Rpb25SZXNvbHZlcjsKLWltcG9ydCBqYXZheC54bWwueHBhdGguWFBhdGhWYXJpYWJsZVJlc29sdmVyOwotaW1wb3J0IGphdmF4LnhtbC54cGF0aC5YUGF0aEV4cHJlc3Npb247Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE07Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLio7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWE9iamVjdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucmVzLlhQQVRIRXJyb3JSZXNvdXJjZXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnJlcy5YU0xNZXNzYWdlczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwudXRpbHMuRmFjdG9yeUltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnV0aWxzLkZlYXR1cmVNYW5hZ2VyOwotCi1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKLWltcG9ydCBvcmcudzNjLmRvbS50cmF2ZXJzYWwuTm9kZUl0ZXJhdG9yOwotCi1pbXBvcnQgb3JnLnhtbC5zYXguSW5wdXRTb3VyY2U7Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotCi1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuKjsKLQotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci0KLS8qKgotICogVGhlIFhQYXRoSW1wbCBjbGFzcyBwcm92aWRlcyBpbXBsZW1lbnRhdGlvbiBmb3IgdGhlIG1ldGhvZHMgZGVmaW5lZCAgaW4KLSAqIGphdmF4LnhtbC54cGF0aC5YUGF0aCBpbnRlcmZhY2UuIFRoaXMgcHJvdmlkZSBzaW1wbGUgYWNjZXNzIHRvIHRoZSByZXN1bHRzCi0gKiBvZiBhbiBYUGF0aCBleHByZXNzaW9uLgotICoKLSAqCi0gKiBAdmVyc2lvbiAkUmV2aXNpb246IDEuMTAgJAotICogQGF1dGhvciAgUmFtZXNoIE1hbmRhdmEKLSAqLwotcHVibGljIGNsYXNzIFhQYXRoSW1wbCBpbXBsZW1lbnRzIGphdmF4LnhtbC54cGF0aC5YUGF0aCB7Ci0KLSAgICAvLyBQcml2YXRlIHZhcmlhYmxlcwotICAgIHByaXZhdGUgWFBhdGhWYXJpYWJsZVJlc29sdmVyIHZhcmlhYmxlUmVzb2x2ZXI7Ci0gICAgcHJpdmF0ZSBYUGF0aEZ1bmN0aW9uUmVzb2x2ZXIgZnVuY3Rpb25SZXNvbHZlcjsKLSAgICBwcml2YXRlIFhQYXRoVmFyaWFibGVSZXNvbHZlciBvcmlnVmFyaWFibGVSZXNvbHZlcjsKLSAgICBwcml2YXRlIFhQYXRoRnVuY3Rpb25SZXNvbHZlciBvcmlnRnVuY3Rpb25SZXNvbHZlcjsKLSAgICBwcml2YXRlIE5hbWVzcGFjZUNvbnRleHQgbmFtZXNwYWNlQ29udGV4dD1udWxsOwotICAgIHByaXZhdGUgSkFYUFByZWZpeFJlc29sdmVyIHByZWZpeFJlc29sdmVyOwotICAgIC8vIEJ5IGRlZmF1bHQgRXh0ZW5zaW9uIEZ1bmN0aW9ucyBhcmUgYWxsb3dlZCBpbiBYUGF0aCBFeHByZXNzaW9ucy4gSWYKLSAgICAvLyBTZWN1cmUgUHJvY2Vzc2luZyBGZWF0dXJlIGlzIHNldCBvbiBYUGF0aEZhY3RvcnkgdGhlbiB0aGUgaW52b2NhdGlvbiBvZgotICAgIC8vIGV4dGVuc2lvbnMgZnVuY3Rpb24gbmVlZCB0byB0aHJvdyBYUGF0aEZ1bmN0aW9uRXhjZXB0aW9uCi0gICAgcHJpdmF0ZSBib29sZWFuIGZlYXR1cmVTZWN1cmVQcm9jZXNzaW5nID0gZmFsc2U7Ci0gICAgcHJpdmF0ZSBib29sZWFuIHVzZVNlcnZpY2VNZWNoYW5pc20gPSB0cnVlOwotICAgIHByaXZhdGUgZmluYWwgRmVhdHVyZU1hbmFnZXIgZmVhdHVyZU1hbmFnZXI7Ci0KLSAgICBYUGF0aEltcGwoIFhQYXRoVmFyaWFibGVSZXNvbHZlciB2ciwgWFBhdGhGdW5jdGlvblJlc29sdmVyIGZyICkgewotICAgICAgICB0aGlzKHZyLCBmciwgZmFsc2UsIHRydWUsIG5ldyBGZWF0dXJlTWFuYWdlcigpKTsKLSAgICB9Ci0KLSAgICBYUGF0aEltcGwoIFhQYXRoVmFyaWFibGVSZXNvbHZlciB2ciwgWFBhdGhGdW5jdGlvblJlc29sdmVyIGZyLAotICAgICAgICAgICAgYm9vbGVhbiBmZWF0dXJlU2VjdXJlUHJvY2Vzc2luZywgYm9vbGVhbiB1c2VTZXJ2aWNlTWVjaGFuaXNtLAotICAgICAgICAgICAgRmVhdHVyZU1hbmFnZXIgZmVhdHVyZU1hbmFnZXIpIHsKLSAgICAgICAgdGhpcy5vcmlnVmFyaWFibGVSZXNvbHZlciA9IHRoaXMudmFyaWFibGVSZXNvbHZlciA9IHZyOwotICAgICAgICB0aGlzLm9yaWdGdW5jdGlvblJlc29sdmVyID0gdGhpcy5mdW5jdGlvblJlc29sdmVyID0gZnI7Ci0gICAgICAgIHRoaXMuZmVhdHVyZVNlY3VyZVByb2Nlc3NpbmcgPSBmZWF0dXJlU2VjdXJlUHJvY2Vzc2luZzsKLSAgICAgICAgdGhpcy51c2VTZXJ2aWNlTWVjaGFuaXNtID0gdXNlU2VydmljZU1lY2hhbmlzbTsKLSAgICAgICAgdGhpcy5mZWF0dXJlTWFuYWdlciA9IGZlYXR1cmVNYW5hZ2VyOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPkVzdGFibGlzaGVzIGEgdmFyaWFibGUgcmVzb2x2ZXIuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIHJlc29sdmVyIFZhcmlhYmxlIFJlc29sdmVyCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0WFBhdGhWYXJpYWJsZVJlc29sdmVyKFhQYXRoVmFyaWFibGVSZXNvbHZlciByZXNvbHZlcikgewotICAgICAgICBpZiAoIHJlc29sdmVyID09IG51bGwgKSB7Ci0gICAgICAgICAgICBTdHJpbmcgZm1zZyA9IFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZSgKLSAgICAgICAgICAgICAgICAgICAgWFBBVEhFcnJvclJlc291cmNlcy5FUl9BUkdfQ0FOTk9UX0JFX05VTEwsCi0gICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7IlhQYXRoVmFyaWFibGVSZXNvbHZlciJ9ICk7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIGZtc2cgKTsKLSAgICAgICAgfQotICAgICAgICB0aGlzLnZhcmlhYmxlUmVzb2x2ZXIgPSByZXNvbHZlcjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5SZXR1cm5zIHRoZSBjdXJyZW50IHZhcmlhYmxlIHJlc29sdmVyLjwvcD4KLSAgICAgKgotICAgICAqIEByZXR1cm4gQ3VycmVudCB2YXJpYWJsZSByZXNvbHZlcgotICAgICAqLwotICAgIHB1YmxpYyBYUGF0aFZhcmlhYmxlUmVzb2x2ZXIgZ2V0WFBhdGhWYXJpYWJsZVJlc29sdmVyKCkgewotICAgICAgICByZXR1cm4gdmFyaWFibGVSZXNvbHZlcjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5Fc3RhYmxpc2hlcyBhIGZ1bmN0aW9uIHJlc29sdmVyLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSByZXNvbHZlciBYUGF0aCBmdW5jdGlvbiByZXNvbHZlcgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFhQYXRoRnVuY3Rpb25SZXNvbHZlcihYUGF0aEZ1bmN0aW9uUmVzb2x2ZXIgcmVzb2x2ZXIpIHsKLSAgICAgICAgaWYgKCByZXNvbHZlciA9PSBudWxsICkgewotICAgICAgICAgICAgU3RyaW5nIGZtc2cgPSBYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoCi0gICAgICAgICAgICAgICAgICAgIFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfQVJHX0NBTk5PVF9CRV9OVUxMLAotICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyJYUGF0aEZ1bmN0aW9uUmVzb2x2ZXIifSApOwotICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCBmbXNnICk7Ci0gICAgICAgIH0KLSAgICAgICAgdGhpcy5mdW5jdGlvblJlc29sdmVyID0gcmVzb2x2ZXI7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+UmV0dXJucyB0aGUgY3VycmVudCBmdW5jdGlvbiByZXNvbHZlci48L3A+Ci0gICAgICoKLSAgICAgKiBAcmV0dXJuIEN1cnJlbnQgZnVuY3Rpb24gcmVzb2x2ZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgWFBhdGhGdW5jdGlvblJlc29sdmVyIGdldFhQYXRoRnVuY3Rpb25SZXNvbHZlcigpIHsKLSAgICAgICAgcmV0dXJuIGZ1bmN0aW9uUmVzb2x2ZXI7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+RXN0YWJsaXNoZXMgYSBuYW1lc3BhY2UgY29udGV4dC48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gbnNDb250ZXh0IE5hbWVzcGFjZSBjb250ZXh0IHRvIHVzZQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldE5hbWVzcGFjZUNvbnRleHQoTmFtZXNwYWNlQ29udGV4dCBuc0NvbnRleHQpIHsKLSAgICAgICAgaWYgKCBuc0NvbnRleHQgPT0gbnVsbCApIHsKLSAgICAgICAgICAgIFN0cmluZyBmbXNnID0gWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKAotICAgICAgICAgICAgICAgICAgICBYUEFUSEVycm9yUmVzb3VyY2VzLkVSX0FSR19DQU5OT1RfQkVfTlVMTCwKLSAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsiTmFtZXNwYWNlQ29udGV4dCJ9ICk7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIGZtc2cgKTsKLSAgICAgICAgfQotICAgICAgICB0aGlzLm5hbWVzcGFjZUNvbnRleHQgPSBuc0NvbnRleHQ7Ci0gICAgICAgIHRoaXMucHJlZml4UmVzb2x2ZXIgPSBuZXcgSkFYUFByZWZpeFJlc29sdmVyICggbnNDb250ZXh0ICk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+UmV0dXJucyB0aGUgY3VycmVudCBuYW1lc3BhY2UgY29udGV4dC48L3A+Ci0gICAgICoKLSAgICAgKiBAcmV0dXJuIEN1cnJlbnQgTmFtZXNwYWNlIGNvbnRleHQKLSAgICAgKi8KLSAgICBwdWJsaWMgTmFtZXNwYWNlQ29udGV4dCBnZXROYW1lc3BhY2VDb250ZXh0KCkgewotICAgICAgICByZXR1cm4gbmFtZXNwYWNlQ29udGV4dDsKLSAgICB9Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBEb2N1bWVudCBkID0gbnVsbDsKLQotICAgIHByaXZhdGUgRG9jdW1lbnRCdWlsZGVyIGdldFBhcnNlcigpIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIC8vIHdlJ2QgcmVhbGx5IGxpa2UgdG8gY2FjaGUgdGhvc2UgRG9jdW1lbnRCdWlsZGVycywgYnV0IHdlIGNhbid0IGJlY2F1c2U6Ci0gICAgICAgICAgICAvLyAxLiB0aHJlYWQgc2FmZXR5LiBwYXJzZXJzIGFyZSBub3QgdGhyZWFkLXNhZmUsIHNvIGF0IGxlYXN0Ci0gICAgICAgICAgICAvLyAgICB3ZSBuZWVkIG9uZSBpbnN0YW5jZSBwZXIgYSB0aHJlYWQuCi0gICAgICAgICAgICAvLyAyLiBwYXJzZXJzIGFyZSBub24tcmVlbnRyYW50LCBzbyBub3cgd2UgYXJlIGxvb2tpbmcgYXQgaGF2aW5nIGEKLSAgICAgICAgICAgIC8vIHBvb2wgb2YgcGFyc2Vycy4KLSAgICAgICAgICAgIC8vIDMuIHRoZW4gdGhlIGNsYXNzIGxvYWRpbmcgaXNzdWUuIFRoZSBsb29rLXVwIHByb2NlZHVyZSBvZgotICAgICAgICAgICAgLy8gICAgRG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5uZXdJbnN0YW5jZSgpIGRlcGVuZHMgb24gY29udGV4dCBjbGFzcyBsb2FkZXIKLSAgICAgICAgICAgIC8vICAgIGFuZCBzeXN0ZW0gcHJvcGVydGllcywgd2hpY2ggbWF5IGNoYW5nZSBkdXJpbmcgdGhlIGV4ZWN1dGlvbiBvZiBKVk0uCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgLy8gc28gd2UgcmVhbGx5IGhhdmUgdG8gY3JlYXRlIGEgZnJlc2ggRG9jdW1lbnRCdWlsZGVyIGV2ZXJ5IHRpbWUgd2UgbmVlZCBvbmUKLSAgICAgICAgICAgIC8vIC0gS0sKLSAgICAgICAgICAgIERvY3VtZW50QnVpbGRlckZhY3RvcnkgZGJmID0gRmFjdG9yeUltcGwuZ2V0RE9NRmFjdG9yeSh1c2VTZXJ2aWNlTWVjaGFuaXNtKTsKLSAgICAgICAgICAgIGRiZi5zZXROYW1lc3BhY2VBd2FyZSggdHJ1ZSApOwotICAgICAgICAgICAgZGJmLnNldFZhbGlkYXRpbmcoIGZhbHNlICk7Ci0gICAgICAgICAgICByZXR1cm4gZGJmLm5ld0RvY3VtZW50QnVpbGRlcigpOwotICAgICAgICB9IGNhdGNoIChQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIC8vIHRoaXMgc2hvdWxkIG5ldmVyIGhhcHBlbiB3aXRoIGEgd2VsbC1iZWhhdmluZyBKQVhQIGltcGxlbWVudGF0aW9uLgotICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGUpOwotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICBwcml2YXRlIFhPYmplY3QgZXZhbChTdHJpbmcgZXhwcmVzc2lvbiwgT2JqZWN0IGNvbnRleHRJdGVtKQotICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbiB7Ci0gICAgICAgIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5YUGF0aCB4cGF0aCA9IG5ldyBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuWFBhdGgoIGV4cHJlc3Npb24sCi0gICAgICAgICAgICBudWxsLCBwcmVmaXhSZXNvbHZlciwgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoLlNFTEVDVCApOwotICAgICAgICBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuWFBhdGhDb250ZXh0IHhwYXRoU3VwcG9ydCA9IG51bGw7Ci0gICAgICAgIGlmICggZnVuY3Rpb25SZXNvbHZlciAhPSBudWxsICkgewotICAgICAgICAgICAgSkFYUEV4dGVuc2lvbnNQcm92aWRlciBqZXAgPSBuZXcgSkFYUEV4dGVuc2lvbnNQcm92aWRlcigKLSAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb25SZXNvbHZlciwgZmVhdHVyZVNlY3VyZVByb2Nlc3NpbmcsIGZlYXR1cmVNYW5hZ2VyICk7Ci0gICAgICAgICAgICB4cGF0aFN1cHBvcnQgPSBuZXcgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoQ29udGV4dCggamVwICk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICB4cGF0aFN1cHBvcnQgPSBuZXcgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoQ29udGV4dCgpOwotICAgICAgICB9Ci0KLSAgICAgICAgWE9iamVjdCB4b2JqID0gbnVsbDsKLQotICAgICAgICB4cGF0aFN1cHBvcnQuc2V0VmFyU3RhY2sobmV3IEpBWFBWYXJpYWJsZVN0YWNrKHZhcmlhYmxlUmVzb2x2ZXIpKTsKLQotICAgICAgICAvLyBJZiBpdGVtIGlzIG51bGwsIHRoZW4gd2Ugd2lsbCBjcmVhdGUgYSBhIER1bW15IGNvbnRleHROb2RlCi0gICAgICAgIGlmICggY29udGV4dEl0ZW0gaW5zdGFuY2VvZiBOb2RlICkgewotICAgICAgICAgICAgeG9iaiA9IHhwYXRoLmV4ZWN1dGUgKHhwYXRoU3VwcG9ydCwgKE5vZGUpY29udGV4dEl0ZW0sCi0gICAgICAgICAgICAgICAgICAgIHByZWZpeFJlc29sdmVyICk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICB4b2JqID0geHBhdGguZXhlY3V0ZSAoIHhwYXRoU3VwcG9ydCwgRFRNLk5VTEwsIHByZWZpeFJlc29sdmVyICk7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4geG9iajsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5FdmFsdWF0ZSBhbiA8Y29kZT5YUGF0aDwvY29kZT4gZXhwcmVzc2lvbiBpbiB0aGUgc3BlY2lmaWVkIGNvbnRleHQgYW5kIHJldHVybiB0aGUgcmVzdWx0IGFzIHRoZSBzcGVjaWZpZWQgdHlwZS48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5TZWUgIkV2YWx1YXRpb24gb2YgWFBhdGggRXhwcmVzc2lvbnMiIHNlY3Rpb24gb2YgSkFYUCAxLjMgc3BlYwotICAgICAqIGZvciBjb250ZXh0IGl0ZW0gZXZhbHVhdGlvbiwKLSAgICAgKiB2YXJpYWJsZSwgZnVuY3Rpb24gYW5kIDxjb2RlPlFOYW1lPC9jb2RlPiByZXNvbHV0aW9uIGFuZCByZXR1cm4gdHlwZSBjb252ZXJzaW9uLjwvcD4KLSAgICAgKgotICAgICAqIDxwPklmIDxjb2RlPnJldHVyblR5cGU8L2NvZGU+IGlzIG5vdCBvbmUgb2YgdGhlIHR5cGVzIGRlZmluZWQgaW4ge0BsaW5rIFhQYXRoQ29uc3RhbnRzfSAoCi0gICAgICoge0BsaW5rIFhQYXRoQ29uc3RhbnRzI05VTUJFUiBOVU1CRVJ9LAotICAgICAqIHtAbGluayBYUGF0aENvbnN0YW50cyNTVFJJTkcgU1RSSU5HfSwKLSAgICAgKiB7QGxpbmsgWFBhdGhDb25zdGFudHMjQk9PTEVBTiBCT09MRUFOfSwKLSAgICAgKiB7QGxpbmsgWFBhdGhDb25zdGFudHMjTk9ERSBOT0RFfSBvcgotICAgICAqIHtAbGluayBYUGF0aENvbnN0YW50cyNOT0RFU0VUIE5PREVTRVR9KQotICAgICAqIHRoZW4gYW4gPGNvZGU+SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uPC9jb2RlPiBpcyB0aHJvd24uPC9wPgotICAgICAqCi0gICAgICogPHA+SWYgYSA8Y29kZT5udWxsPC9jb2RlPiB2YWx1ZSBpcyBwcm92aWRlZCBmb3IKLSAgICAgKiA8Y29kZT5pdGVtPC9jb2RlPiwgYW4gZW1wdHkgZG9jdW1lbnQgd2lsbCBiZSB1c2VkIGZvciB0aGUKLSAgICAgKiBjb250ZXh0LgotICAgICAqIElmIDxjb2RlPmV4cHJlc3Npb248L2NvZGU+IG9yIDxjb2RlPnJldHVyblR5cGU8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LCB0aGVuIGEKLSAgICAgKiA8Y29kZT5OdWxsUG9pbnRlckV4Y2VwdGlvbjwvY29kZT4gaXMgdGhyb3duLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBleHByZXNzaW9uIFRoZSBYUGF0aCBleHByZXNzaW9uLgotICAgICAqIEBwYXJhbSBpdGVtIFRoZSBzdGFydGluZyBjb250ZXh0IChub2RlIG9yIG5vZGUgbGlzdCwgZm9yIGV4YW1wbGUpLgotICAgICAqIEBwYXJhbSByZXR1cm5UeXBlIFRoZSBkZXNpcmVkIHJldHVybiB0eXBlLgotICAgICAqCi0gICAgICogQHJldHVybiBSZXN1bHQgb2YgZXZhbHVhdGluZyBhbiBYUGF0aCBleHByZXNzaW9uIGFzIGFuIDxjb2RlPk9iamVjdDwvY29kZT4gb2YgPGNvZGU+cmV0dXJuVHlwZTwvY29kZT4uCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhQYXRoRXhwcmVzc2lvbkV4Y2VwdGlvbiBJZiA8Y29kZT5leHByZXNzaW9uPC9jb2RlPiBjYW5ub3QgYmUgZXZhbHVhdGVkLgotICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIElmIDxjb2RlPnJldHVyblR5cGU8L2NvZGU+IGlzIG5vdCBvbmUgb2YgdGhlIHR5cGVzIGRlZmluZWQgaW4ge0BsaW5rIFhQYXRoQ29uc3RhbnRzfS4KLSAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIElmIDxjb2RlPmV4cHJlc3Npb248L2NvZGU+IG9yIDxjb2RlPnJldHVyblR5cGU8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBPYmplY3QgZXZhbHVhdGUoU3RyaW5nIGV4cHJlc3Npb24sIE9iamVjdCBpdGVtLCBRTmFtZSByZXR1cm5UeXBlKQotICAgICAgICAgICAgdGhyb3dzIFhQYXRoRXhwcmVzc2lvbkV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmICggZXhwcmVzc2lvbiA9PSBudWxsICkgewotICAgICAgICAgICAgU3RyaW5nIGZtc2cgPSBYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoCi0gICAgICAgICAgICAgICAgICAgIFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfQVJHX0NBTk5PVF9CRV9OVUxMLAotICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyJYUGF0aCBleHByZXNzaW9uIn0gKTsKLSAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbiAoIGZtc2cgKTsKLSAgICAgICAgfQotICAgICAgICBpZiAoIHJldHVyblR5cGUgPT0gbnVsbCApIHsKLSAgICAgICAgICAgIFN0cmluZyBmbXNnID0gWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKAotICAgICAgICAgICAgICAgICAgICBYUEFUSEVycm9yUmVzb3VyY2VzLkVSX0FSR19DQU5OT1RfQkVfTlVMTCwKLSAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsicmV0dXJuVHlwZSJ9ICk7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24gKCBmbXNnICk7Ci0gICAgICAgIH0KLSAgICAgICAgLy8gQ2hlY2tpbmcgaWYgcmVxdWVzdGVkIHJldHVyblR5cGUgaXMgc3VwcG9ydGVkLiByZXR1cm5UeXBlIG5lZWQgdG8KLSAgICAgICAgLy8gYmUgZGVmaW5lZCBpbiBYUGF0aENvbnN0YW50cwotICAgICAgICBpZiAoICFpc1N1cHBvcnRlZCAoIHJldHVyblR5cGUgKSApIHsKLSAgICAgICAgICAgIFN0cmluZyBmbXNnID0gWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKAotICAgICAgICAgICAgICAgICAgICBYUEFUSEVycm9yUmVzb3VyY2VzLkVSX1VOU1VQUE9SVEVEX1JFVFVSTl9UWVBFLAotICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyByZXR1cm5UeXBlLnRvU3RyaW5nKCkgfSApOwotICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiAoIGZtc2cgKTsKLSAgICAgICAgfQotCi0gICAgICAgIHRyeSB7Ci0KLSAgICAgICAgICAgIFhPYmplY3QgcmVzdWx0T2JqZWN0ID0gZXZhbCggZXhwcmVzc2lvbiwgaXRlbSApOwotICAgICAgICAgICAgcmV0dXJuIGdldFJlc3VsdEFzVHlwZSggcmVzdWx0T2JqZWN0LCByZXR1cm5UeXBlICk7Ci0gICAgICAgIH0gY2F0Y2ggKCBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24gbnBlICkgewotICAgICAgICAgICAgLy8gSWYgVmFyaWFibGVSZXNvbHZlciByZXR1cm5zIG51bGwgT3IgaWYgd2UgZ2V0Ci0gICAgICAgICAgICAvLyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBhdCB0aGlzIHN0YWdlIGZvciBzb21lIG90aGVyIHJlYXNvbgotICAgICAgICAgICAgLy8gdGhlbiB3ZSBoYXZlIHRvIHJldXJuIFhQYXRoRXhjZXB0aW9uCi0gICAgICAgICAgICB0aHJvdyBuZXcgWFBhdGhFeHByZXNzaW9uRXhjZXB0aW9uICggbnBlICk7Ci0gICAgICAgIH0gY2F0Y2ggKCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uIHRlICkgewotICAgICAgICAgICAgVGhyb3dhYmxlIG5lc3RlZEV4Y2VwdGlvbiA9IHRlLmdldEV4Y2VwdGlvbigpOwotICAgICAgICAgICAgaWYgKCBuZXN0ZWRFeGNlcHRpb24gaW5zdGFuY2VvZiBqYXZheC54bWwueHBhdGguWFBhdGhGdW5jdGlvbkV4Y2VwdGlvbiApIHsKLSAgICAgICAgICAgICAgICB0aHJvdyAoamF2YXgueG1sLnhwYXRoLlhQYXRoRnVuY3Rpb25FeGNlcHRpb24pbmVzdGVkRXhjZXB0aW9uOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAvLyBGb3IgYW55IG90aGVyIGV4Y2VwdGlvbnMgd2UgbmVlZCB0byB0aHJvdwotICAgICAgICAgICAgICAgIC8vIFhQYXRoRXhwcmVzc2lvbkV4Y2VwdGlvbiAoIGFzIHBlciBzcGVjICkKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWFBhdGhFeHByZXNzaW9uRXhjZXB0aW9uICggdGUgKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgfQotCi0gICAgcHJpdmF0ZSBib29sZWFuIGlzU3VwcG9ydGVkKCBRTmFtZSByZXR1cm5UeXBlICkgewotICAgICAgICBpZiAoICggcmV0dXJuVHlwZS5lcXVhbHMoIFhQYXRoQ29uc3RhbnRzLlNUUklORyApICkgfHwKLSAgICAgICAgICAgICAoIHJldHVyblR5cGUuZXF1YWxzKCBYUGF0aENvbnN0YW50cy5OVU1CRVIgKSApIHx8Ci0gICAgICAgICAgICAgKCByZXR1cm5UeXBlLmVxdWFscyggWFBhdGhDb25zdGFudHMuQk9PTEVBTiApICkgfHwKLSAgICAgICAgICAgICAoIHJldHVyblR5cGUuZXF1YWxzKCBYUGF0aENvbnN0YW50cy5OT0RFICkgKSB8fAotICAgICAgICAgICAgICggcmV0dXJuVHlwZS5lcXVhbHMoIFhQYXRoQ29uc3RhbnRzLk5PREVTRVQgKSApICApIHsKLQotICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICB9Ci0KLSAgICBwcml2YXRlIE9iamVjdCBnZXRSZXN1bHRBc1R5cGUoIFhPYmplY3QgcmVzdWx0T2JqZWN0LCBRTmFtZSByZXR1cm5UeXBlICkKLSAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24gewotICAgICAgICAvLyBYUGF0aENvbnN0YW50cy5TVFJJTkcKLSAgICAgICAgaWYgKCByZXR1cm5UeXBlLmVxdWFscyggWFBhdGhDb25zdGFudHMuU1RSSU5HICkgKSB7Ci0gICAgICAgICAgICByZXR1cm4gcmVzdWx0T2JqZWN0LnN0cigpOwotICAgICAgICB9Ci0gICAgICAgIC8vIFhQYXRoQ29uc3RhbnRzLk5VTUJFUgotICAgICAgICBpZiAoIHJldHVyblR5cGUuZXF1YWxzKCBYUGF0aENvbnN0YW50cy5OVU1CRVIgKSApIHsKLSAgICAgICAgICAgIHJldHVybiBuZXcgRG91YmxlICggcmVzdWx0T2JqZWN0Lm51bSgpKTsKLSAgICAgICAgfQotICAgICAgICAvLyBYUGF0aENvbnN0YW50cy5CT09MRUFOCi0gICAgICAgIGlmICggcmV0dXJuVHlwZS5lcXVhbHMoIFhQYXRoQ29uc3RhbnRzLkJPT0xFQU4gKSApIHsKLSAgICAgICAgICAgIHJldHVybiBuZXcgQm9vbGVhbiggcmVzdWx0T2JqZWN0LmJvb2woKSk7Ci0gICAgICAgIH0KLSAgICAgICAgLy8gWFBhdGhDb25zdGFudHMuTk9ERVNFVCAtLS1PUmRlcmVkLCBVTk9yZGVyZWQ/Pz8KLSAgICAgICAgaWYgKCByZXR1cm5UeXBlLmVxdWFscyggWFBhdGhDb25zdGFudHMuTk9ERVNFVCApICkgewotICAgICAgICAgICAgcmV0dXJuIHJlc3VsdE9iamVjdC5ub2RlbGlzdCgpOwotICAgICAgICB9Ci0gICAgICAgIC8vIFhQYXRoQ29uc3RhbnRzLk5PREUKLSAgICAgICAgaWYgKCByZXR1cm5UeXBlLmVxdWFscyggWFBhdGhDb25zdGFudHMuTk9ERSApICkgewotICAgICAgICAgICAgTm9kZUl0ZXJhdG9yIG5pID0gcmVzdWx0T2JqZWN0Lm5vZGVzZXQoKTsKLSAgICAgICAgICAgIC8vUmV0dXJuIHRoZSBmaXJzdCBub2RlLCBvciBudWxsCi0gICAgICAgICAgICByZXR1cm4gbmkubmV4dE5vZGUoKTsKLSAgICAgICAgfQotICAgICAgICBTdHJpbmcgZm1zZyA9IFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZSgKLSAgICAgICAgICAgICAgICBYUEFUSEVycm9yUmVzb3VyY2VzLkVSX1VOU1VQUE9SVEVEX1JFVFVSTl9UWVBFLAotICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7IHJldHVyblR5cGUudG9TdHJpbmcoKX0pOwotICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCBmbXNnICk7Ci0gICAgfQotCi0KLQotICAgIC8qKgotICAgICAqIDxwPkV2YWx1YXRlIGFuIFhQYXRoIGV4cHJlc3Npb24gaW4gdGhlIHNwZWNpZmllZCBjb250ZXh0IGFuZCByZXR1cm4gdGhlIHJlc3VsdCBhcyBhIDxjb2RlPlN0cmluZzwvY29kZT4uPC9wPgotICAgICAqCi0gICAgICogPHA+VGhpcyBtZXRob2QgY2FsbHMge0BsaW5rICNldmFsdWF0ZShTdHJpbmcgZXhwcmVzc2lvbiwgT2JqZWN0IGl0ZW0sIFFOYW1lIHJldHVyblR5cGUpfSB3aXRoIGEgPGNvZGU+cmV0dXJuVHlwZTwvY29kZT4gb2YKLSAgICAgKiB7QGxpbmsgWFBhdGhDb25zdGFudHMjU1RSSU5HfS48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5TZWUgIkV2YWx1YXRpb24gb2YgWFBhdGggRXhwcmVzc2lvbnMiIG9mIEpBWFAgMS4zIHNwZWMKLSAgICAgKiBmb3IgY29udGV4dCBpdGVtIGV2YWx1YXRpb24sCi0gICAgICogdmFyaWFibGUsIGZ1bmN0aW9uIGFuZCBRTmFtZSByZXNvbHV0aW9uIGFuZCByZXR1cm4gdHlwZSBjb252ZXJzaW9uLjwvcD4KLSAgICAgKgotICAgICAqIDxwPklmIGEgPGNvZGU+bnVsbDwvY29kZT4gdmFsdWUgaXMgcHJvdmlkZWQgZm9yCi0gICAgICogPGNvZGU+aXRlbTwvY29kZT4sIGFuIGVtcHR5IGRvY3VtZW50IHdpbGwgYmUgdXNlZCBmb3IgdGhlCi0gICAgICogY29udGV4dC4KLSAgICAgKiBJZiA8Y29kZT5leHByZXNzaW9uPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPiwgdGhlbiBhIDxjb2RlPk51bGxQb2ludGVyRXhjZXB0aW9uPC9jb2RlPiBpcyB0aHJvd24uPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGV4cHJlc3Npb24gVGhlIFhQYXRoIGV4cHJlc3Npb24uCi0gICAgICogQHBhcmFtIGl0ZW0gVGhlIHN0YXJ0aW5nIGNvbnRleHQgKG5vZGUgb3Igbm9kZSBsaXN0LCBmb3IgZXhhbXBsZSkuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSA8Y29kZT5TdHJpbmc8L2NvZGU+IHRoYXQgaXMgdGhlIHJlc3VsdCBvZiBldmFsdWF0aW5nIHRoZSBleHByZXNzaW9uIGFuZAotICAgICAqICAgY29udmVydGluZyB0aGUgcmVzdWx0IHRvIGEgPGNvZGU+U3RyaW5nPC9jb2RlPi4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWFBhdGhFeHByZXNzaW9uRXhjZXB0aW9uIElmIDxjb2RlPmV4cHJlc3Npb248L2NvZGU+IGNhbm5vdCBiZSBldmFsdWF0ZWQuCi0gICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBJZiA8Y29kZT5leHByZXNzaW9uPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGV2YWx1YXRlKFN0cmluZyBleHByZXNzaW9uLCBPYmplY3QgaXRlbSkKLSAgICAgICAgdGhyb3dzIFhQYXRoRXhwcmVzc2lvbkV4Y2VwdGlvbiB7Ci0gICAgICAgIHJldHVybiAoU3RyaW5nKXRoaXMuZXZhbHVhdGUoIGV4cHJlc3Npb24sIGl0ZW0sIFhQYXRoQ29uc3RhbnRzLlNUUklORyApOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPkNvbXBpbGUgYW4gWFBhdGggZXhwcmVzc2lvbiBmb3IgbGF0ZXIgZXZhbHVhdGlvbi48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5JZiA8Y29kZT5leHByZXNzaW9uPC9jb2RlPiBjb250YWlucyBhbnkge0BsaW5rIFhQYXRoRnVuY3Rpb259cywKLSAgICAgKiB0aGV5IG11c3QgYmUgYXZhaWxhYmxlIHZpYSB0aGUge0BsaW5rIFhQYXRoRnVuY3Rpb25SZXNvbHZlcn0uCi0gICAgICogQW4ge0BsaW5rIFhQYXRoRXhwcmVzc2lvbkV4Y2VwdGlvbn0gd2lsbCBiZSB0aHJvd24gaWYgdGhlIDxjb2RlPlhQYXRoRnVuY3Rpb248L2NvZGU+Ci0gICAgICogY2Fubm90IGJlIHJlc292bGVkIHdpdGggdGhlIDxjb2RlPlhQYXRoRnVuY3Rpb25SZXNvbHZlcjwvY29kZT4uPC9wPgotICAgICAqCi0gICAgICogPHA+SWYgPGNvZGU+ZXhwcmVzc2lvbjwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4sIGEgPGNvZGU+TnVsbFBvaW50ZXJFeGNlcHRpb248L2NvZGU+IGlzIHRocm93bi48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gZXhwcmVzc2lvbiBUaGUgWFBhdGggZXhwcmVzc2lvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gQ29tcGlsZWQgWFBhdGggZXhwcmVzc2lvbi4KLQotICAgICAqIEB0aHJvd3MgWFBhdGhFeHByZXNzaW9uRXhjZXB0aW9uIElmIDxjb2RlPmV4cHJlc3Npb248L2NvZGU+IGNhbm5vdCBiZSBjb21waWxlZC4KLSAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIElmIDxjb2RlPmV4cHJlc3Npb248L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBYUGF0aEV4cHJlc3Npb24gY29tcGlsZShTdHJpbmcgZXhwcmVzc2lvbikKLSAgICAgICAgdGhyb3dzIFhQYXRoRXhwcmVzc2lvbkV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmICggZXhwcmVzc2lvbiA9PSBudWxsICkgewotICAgICAgICAgICAgU3RyaW5nIGZtc2cgPSBYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoCi0gICAgICAgICAgICAgICAgICAgIFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfQVJHX0NBTk5PVF9CRV9OVUxMLAotICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10geyJYUGF0aCBleHByZXNzaW9uIn0gKTsKLSAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbiAoIGZtc2cgKTsKLSAgICAgICAgfQotICAgICAgICB0cnkgewotICAgICAgICAgICAgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoIHhwYXRoID0gbmV3IFhQYXRoIChleHByZXNzaW9uLCBudWxsLAotICAgICAgICAgICAgICAgICAgICBwcmVmaXhSZXNvbHZlciwgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoLlNFTEVDVCApOwotICAgICAgICAgICAgLy8gQ2FuIGhhdmUgZXJyb3JMaXN0ZW5lcgotICAgICAgICAgICAgWFBhdGhFeHByZXNzaW9uSW1wbCB4aW1wbCA9IG5ldyBYUGF0aEV4cHJlc3Npb25JbXBsICh4cGF0aCwKLSAgICAgICAgICAgICAgICAgICAgcHJlZml4UmVzb2x2ZXIsIGZ1bmN0aW9uUmVzb2x2ZXIsIHZhcmlhYmxlUmVzb2x2ZXIsCi0gICAgICAgICAgICAgICAgICAgIGZlYXR1cmVTZWN1cmVQcm9jZXNzaW5nLCB1c2VTZXJ2aWNlTWVjaGFuaXNtLCBmZWF0dXJlTWFuYWdlciApOwotICAgICAgICAgICAgcmV0dXJuIHhpbXBsOwotICAgICAgICB9IGNhdGNoICggamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbiB0ZSApIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBYUGF0aEV4cHJlc3Npb25FeGNlcHRpb24gKCB0ZSApIDsKLSAgICAgICAgfQotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogPHA+RXZhbHVhdGUgYW4gWFBhdGggZXhwcmVzc2lvbiBpbiB0aGUgY29udGV4dCBvZiB0aGUgc3BlY2lmaWVkIDxjb2RlPklucHV0U291cmNlPC9jb2RlPgotICAgICAqIGFuZCByZXR1cm4gdGhlIHJlc3VsdCBhcyB0aGUgc3BlY2lmaWVkIHR5cGUuPC9wPgotICAgICAqCi0gICAgICogPHA+VGhpcyBtZXRob2QgYnVpbGRzIGEgZGF0YSBtb2RlbCBmb3IgdGhlIHtAbGluayBJbnB1dFNvdXJjZX0gYW5kIGNhbGxzCi0gICAgICoge0BsaW5rICNldmFsdWF0ZShTdHJpbmcgZXhwcmVzc2lvbiwgT2JqZWN0IGl0ZW0sIFFOYW1lIHJldHVyblR5cGUpfSBvbiB0aGUgcmVzdWx0aW5nIGRvY3VtZW50IG9iamVjdC48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5TZWUgIkV2YWx1YXRpb24gb2YgWFBhdGggRXhwcmVzc2lvbnMiIHNlY3Rpb24gb2YgSkFYUCAxLjMgc3BlYwotICAgICAqIGZvciBjb250ZXh0IGl0ZW0gZXZhbHVhdGlvbiwKLSAgICAgKiB2YXJpYWJsZSwgZnVuY3Rpb24gYW5kIFFOYW1lIHJlc29sdXRpb24gYW5kIHJldHVybiB0eXBlIGNvbnZlcnNpb24uPC9wPgotICAgICAqCi0gICAgICogPHA+SWYgPGNvZGU+cmV0dXJuVHlwZTwvY29kZT4gaXMgbm90IG9uZSBvZiB0aGUgdHlwZXMgZGVmaW5lZCBpbiB7QGxpbmsgWFBhdGhDb25zdGFudHN9LAotICAgICAqIHRoZW4gYW4gPGNvZGU+SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uPC9jb2RlPiBpcyB0aHJvd24uPC9wPgotICAgICAqCi0gICAgICogPHA+SWYgPGNvZGU+ZXhwcmVzc2lvbjwvY29kZT4sIDxjb2RlPnNvdXJjZTwvY29kZT4gb3IgPGNvZGU+cmV0dXJuVHlwZTwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4sCi0gICAgICogdGhlbiBhIDxjb2RlPk51bGxQb2ludGVyRXhjZXB0aW9uPC9jb2RlPiBpcyB0aHJvd24uPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGV4cHJlc3Npb24gVGhlIFhQYXRoIGV4cHJlc3Npb24uCi0gICAgICogQHBhcmFtIHNvdXJjZSBUaGUgaW5wdXQgc291cmNlIG9mIHRoZSBkb2N1bWVudCB0byBldmFsdWF0ZSBvdmVyLgotICAgICAqIEBwYXJhbSByZXR1cm5UeXBlIFRoZSBkZXNpcmVkIHJldHVybiB0eXBlLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgPGNvZGU+T2JqZWN0PC9jb2RlPiB0aGF0IGVuY2Fwc3VsYXRlcyB0aGUgcmVzdWx0IG9mIGV2YWx1YXRpbmcgdGhlIGV4cHJlc3Npb24uCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhQYXRoRXhwcmVzc2lvbkV4Y2VwdGlvbiBJZiBleHByZXNzaW9uIGNhbm5vdCBiZSBldmFsdWF0ZWQuCi0gICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gSWYgPGNvZGU+cmV0dXJuVHlwZTwvY29kZT4gaXMgbm90IG9uZSBvZiB0aGUgdHlwZXMgZGVmaW5lZCBpbiB7QGxpbmsgWFBhdGhDb25zdGFudHN9LgotICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gSWYgPGNvZGU+ZXhwcmVzc2lvbjwvY29kZT4sIDxjb2RlPnNvdXJjZTwvY29kZT4gb3IgPGNvZGU+cmV0dXJuVHlwZTwvY29kZT4KLSAgICAgKiAgIGlzIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBPYmplY3QgZXZhbHVhdGUoU3RyaW5nIGV4cHJlc3Npb24sIElucHV0U291cmNlIHNvdXJjZSwKLSAgICAgICAgICAgIFFOYW1lIHJldHVyblR5cGUpIHRocm93cyBYUGF0aEV4cHJlc3Npb25FeGNlcHRpb24gewotICAgICAgICAvLyBDaGVja2luZyB2YWxpZGl0eSBvZiBkaWZmZXJlbnQgcGFyYW1ldGVycwotICAgICAgICBpZiggc291cmNlPT0gbnVsbCApIHsKLSAgICAgICAgICAgIFN0cmluZyBmbXNnID0gWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKAotICAgICAgICAgICAgICAgICAgICBYUEFUSEVycm9yUmVzb3VyY2VzLkVSX0FSR19DQU5OT1RfQkVfTlVMTCwKLSAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsic291cmNlIn0gKTsKLSAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbiAoIGZtc2cgKTsKLSAgICAgICAgfQotICAgICAgICBpZiAoIGV4cHJlc3Npb24gPT0gbnVsbCApIHsKLSAgICAgICAgICAgIFN0cmluZyBmbXNnID0gWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKAotICAgICAgICAgICAgICAgICAgICBYUEFUSEVycm9yUmVzb3VyY2VzLkVSX0FSR19DQU5OT1RfQkVfTlVMTCwKLSAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsiWFBhdGggZXhwcmVzc2lvbiJ9ICk7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24gKCBmbXNnICk7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKCByZXR1cm5UeXBlID09IG51bGwgKSB7Ci0gICAgICAgICAgICBTdHJpbmcgZm1zZyA9IFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZSgKLSAgICAgICAgICAgICAgICAgICAgWFBBVEhFcnJvclJlc291cmNlcy5FUl9BUkdfQ0FOTk9UX0JFX05VTEwsCi0gICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7InJldHVyblR5cGUifSApOwotICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uICggZm1zZyApOwotICAgICAgICB9Ci0KLSAgICAgICAgLy9DaGVja2luZyBpZiByZXF1ZXN0ZWQgcmV0dXJuVHlwZSBpcyBzdXBwb3J0ZWQuCi0gICAgICAgIC8vcmV0dXJuVHlwZSBuZWVkIHRvIGJlIGRlZmluZWQgaW4gWFBhdGhDb25zdGFudHMKLSAgICAgICAgaWYgKCAhaXNTdXBwb3J0ZWQgKCByZXR1cm5UeXBlICkgKSB7Ci0gICAgICAgICAgICBTdHJpbmcgZm1zZyA9IFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZSgKLSAgICAgICAgICAgICAgICAgICAgWFBBVEhFcnJvclJlc291cmNlcy5FUl9VTlNVUFBPUlRFRF9SRVRVUk5fVFlQRSwKLSAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHsgcmV0dXJuVHlwZS50b1N0cmluZygpIH0gKTsKLSAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gKCBmbXNnICk7Ci0gICAgICAgIH0KLQotICAgICAgICB0cnkgewotCi0gICAgICAgICAgICBEb2N1bWVudCBkb2N1bWVudCA9IGdldFBhcnNlcigpLnBhcnNlKCBzb3VyY2UgKTsKLQotICAgICAgICAgICAgWE9iamVjdCByZXN1bHRPYmplY3QgPSBldmFsKCBleHByZXNzaW9uLCBkb2N1bWVudCApOwotICAgICAgICAgICAgcmV0dXJuIGdldFJlc3VsdEFzVHlwZSggcmVzdWx0T2JqZWN0LCByZXR1cm5UeXBlICk7Ci0gICAgICAgIH0gY2F0Y2ggKCBTQVhFeGNlcHRpb24gZSApIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBYUGF0aEV4cHJlc3Npb25FeGNlcHRpb24gKCBlICk7Ci0gICAgICAgIH0gY2F0Y2goIElPRXhjZXB0aW9uIGUgKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWFBhdGhFeHByZXNzaW9uRXhjZXB0aW9uICggZSApOwotICAgICAgICB9IGNhdGNoICggamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbiB0ZSApIHsKLSAgICAgICAgICAgIFRocm93YWJsZSBuZXN0ZWRFeGNlcHRpb24gPSB0ZS5nZXRFeGNlcHRpb24oKTsKLSAgICAgICAgICAgIGlmICggbmVzdGVkRXhjZXB0aW9uIGluc3RhbmNlb2YgamF2YXgueG1sLnhwYXRoLlhQYXRoRnVuY3Rpb25FeGNlcHRpb24gKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgKGphdmF4LnhtbC54cGF0aC5YUGF0aEZ1bmN0aW9uRXhjZXB0aW9uKW5lc3RlZEV4Y2VwdGlvbjsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFhQYXRoRXhwcmVzc2lvbkV4Y2VwdGlvbiAoIHRlICk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgIH0KLQotCi0KLQotICAgIC8qKgotICAgICAqIDxwPkV2YWx1YXRlIGFuIFhQYXRoIGV4cHJlc3Npb24gaW4gdGhlIGNvbnRleHQgb2YgdGhlIHNwZWNpZmllZCA8Y29kZT5JbnB1dFNvdXJjZTwvY29kZT4KLSAgICAgKiBhbmQgcmV0dXJuIHRoZSByZXN1bHQgYXMgYSA8Y29kZT5TdHJpbmc8L2NvZGU+LjwvcD4KLSAgICAgKgotICAgICAqIDxwPlRoaXMgbWV0aG9kIGNhbGxzIHtAbGluayAjZXZhbHVhdGUoU3RyaW5nIGV4cHJlc3Npb24sIElucHV0U291cmNlIHNvdXJjZSwgUU5hbWUgcmV0dXJuVHlwZSl9IHdpdGggYQotICAgICAqIDxjb2RlPnJldHVyblR5cGU8L2NvZGU+IG9mIHtAbGluayBYUGF0aENvbnN0YW50cyNTVFJJTkd9LjwvcD4KLSAgICAgKgotICAgICAqIDxwPlNlZSAiRXZhbHVhdGlvbiBvZiBYUGF0aCBFeHByZXNzaW9ucyIgc2VjdGlvbiBvZiBKQVhQIDEuMyBzcGVjCi0gICAgICogZm9yIGNvbnRleHQgaXRlbSBldmFsdWF0aW9uLAotICAgICAqIHZhcmlhYmxlLCBmdW5jdGlvbiBhbmQgUU5hbWUgcmVzb2x1dGlvbiBhbmQgcmV0dXJuIHR5cGUgY29udmVyc2lvbi48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5JZiA8Y29kZT5leHByZXNzaW9uPC9jb2RlPiBvciA8Y29kZT5zb3VyY2U8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LAotICAgICAqIHRoZW4gYSA8Y29kZT5OdWxsUG9pbnRlckV4Y2VwdGlvbjwvY29kZT4gaXMgdGhyb3duLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBleHByZXNzaW9uIFRoZSBYUGF0aCBleHByZXNzaW9uLgotICAgICAqIEBwYXJhbSBzb3VyY2UgVGhlIDxjb2RlPklucHV0U291cmNlPC9jb2RlPiBvZiB0aGUgZG9jdW1lbnQgdG8gZXZhbHVhdGUgb3Zlci4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIDxjb2RlPlN0cmluZzwvY29kZT4gdGhhdCBpcyB0aGUgcmVzdWx0IG9mIGV2YWx1YXRpbmcgdGhlIGV4cHJlc3Npb24gYW5kCi0gICAgICogICBjb252ZXJ0aW5nIHRoZSByZXN1bHQgdG8gYSA8Y29kZT5TdHJpbmc8L2NvZGU+LgotICAgICAqCi0gICAgICogQHRocm93cyBYUGF0aEV4cHJlc3Npb25FeGNlcHRpb24gSWYgZXhwcmVzc2lvbiBjYW5ub3QgYmUgZXZhbHVhdGVkLgotICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gSWYgPGNvZGU+ZXhwcmVzc2lvbjwvY29kZT4gb3IgPGNvZGU+c291cmNlPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGV2YWx1YXRlKFN0cmluZyBleHByZXNzaW9uLCBJbnB1dFNvdXJjZSBzb3VyY2UpCi0gICAgICAgIHRocm93cyBYUGF0aEV4cHJlc3Npb25FeGNlcHRpb24gewotICAgICAgICByZXR1cm4gKFN0cmluZyl0aGlzLmV2YWx1YXRlKCBleHByZXNzaW9uLCBzb3VyY2UsIFhQYXRoQ29uc3RhbnRzLlNUUklORyApOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPlJlc2V0IHRoaXMgPGNvZGU+WFBhdGg8L2NvZGU+IHRvIGl0cyBvcmlnaW5hbCBjb25maWd1cmF0aW9uLjwvcD4KLSAgICAgKgotICAgICAqIDxwPjxjb2RlPlhQYXRoPC9jb2RlPiBpcyByZXNldCB0byB0aGUgc2FtZSBzdGF0ZSBhcyB3aGVuIGl0IHdhcyBjcmVhdGVkIHdpdGgKLSAgICAgKiB7QGxpbmsgWFBhdGhGYWN0b3J5I25ld1hQYXRoKCl9LgotICAgICAqIDxjb2RlPnJlc2V0KCk8L2NvZGU+IGlzIGRlc2lnbmVkIHRvIGFsbG93IHRoZSByZXVzZSBvZiBleGlzdGluZyA8Y29kZT5YUGF0aDwvY29kZT5zCi0gICAgICogdGh1cyBzYXZpbmcgcmVzb3VyY2VzIGFzc29jaWF0ZWQgd2l0aCB0aGUgY3JlYXRpb24gb2YgbmV3IDxjb2RlPlhQYXRoPC9jb2RlPnMuPC9wPgotICAgICAqCi0gICAgICogPHA+VGhlIHJlc2V0IDxjb2RlPlhQYXRoPC9jb2RlPiBpcyBub3QgZ3VhcmFudGVlZCB0byBoYXZlIHRoZSBzYW1lCi0gICAgICoge0BsaW5rIFhQYXRoRnVuY3Rpb25SZXNvbHZlcn0sIHtAbGluayBYUGF0aFZhcmlhYmxlUmVzb2x2ZXJ9Ci0gICAgICogb3Ige0BsaW5rIE5hbWVzcGFjZUNvbnRleHR9IDxjb2RlPk9iamVjdDwvY29kZT5zLCBlLmcuIHtAbGluayBPYmplY3QjZXF1YWxzKE9iamVjdCBvYmopfS4KLSAgICAgKiBJdCBpcyBndWFyYW50ZWVkIHRvIGhhdmUgYSBmdW5jdGlvbmFsbHkgZXF1YWwgPGNvZGU+WFBhdGhGdW5jdGlvblJlc29sdmVyPC9jb2RlPiwKLSAgICAgKiA8Y29kZT5YUGF0aFZhcmlhYmxlUmVzb2x2ZXI8L2NvZGU+Ci0gICAgICogYW5kIDxjb2RlPk5hbWVzcGFjZUNvbnRleHQ8L2NvZGU+LjwvcD4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCByZXNldCgpIHsKLSAgICAgICAgdGhpcy52YXJpYWJsZVJlc29sdmVyID0gdGhpcy5vcmlnVmFyaWFibGVSZXNvbHZlcjsKLSAgICAgICAgdGhpcy5mdW5jdGlvblJlc29sdmVyID0gdGhpcy5vcmlnRnVuY3Rpb25SZXNvbHZlcjsKLSAgICAgICAgdGhpcy5uYW1lc3BhY2VDb250ZXh0ID0gbnVsbDsKLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvb2JqZWN0cy9EVE1YUlRyZWVGcmFnLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL29iamVjdHMvRFRNWFJUcmVlRnJhZy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyYjMyMWE5Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvb2JqZWN0cy9EVE1YUlRyZWVGcmFnLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw2MCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE07Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoQ29udGV4dDsKLS8qCi0gKgotICogQGF1dGhvciBpZ29yaAotICoKLSAqIFNpbXBsZSB3cmFwcGVyIHRvIERUTSBhbmQgWFBhdGhDb250ZXh0IG9iamVjdHMuCi0gKiBVc2VkIGluIFhSVHJlZUZyYWcgZm9yIGNhY2hpbmcgcmVmZXJlbmNlcyB0byB0aGUgb2JqZWN0cy4KLSAqLwotIHB1YmxpYyBmaW5hbCBjbGFzcyBEVE1YUlRyZWVGcmFnIHsKLSAgcHJpdmF0ZSBEVE0gbV9kdG07Ci0gIHByaXZhdGUgaW50IG1fZHRtSWRlbnRpdHkgPSBEVE0uTlVMTDsKLSAgcHJpdmF0ZSBYUGF0aENvbnRleHQgbV94Y3R4dDsKLQotICBwdWJsaWMgRFRNWFJUcmVlRnJhZyhpbnQgZHRtSWRlbnRpdHksIFhQYXRoQ29udGV4dCB4Y3R4dCl7Ci0gICAgICBtX3hjdHh0ID0geGN0eHQ7Ci0gICAgICBtX2R0bUlkZW50aXR5ID0gZHRtSWRlbnRpdHk7Ci0gICAgICBtX2R0bSA9IHhjdHh0LmdldERUTShkdG1JZGVudGl0eSk7Ci0gICAgfQotCi0gIHB1YmxpYyBmaW5hbCB2b2lkIGRlc3RydWN0KCl7Ci0gICAgbV9kdG0gPSBudWxsOwotICAgIG1feGN0eHQgPSBudWxsOwotIH0KLQotZmluYWwgIERUTSBnZXREVE0oKXtyZXR1cm4gbV9kdG07fQotcHVibGljIGZpbmFsICBpbnQgZ2V0RFRNSWRlbnRpdHkoKXtyZXR1cm4gbV9kdG1JZGVudGl0eTt9Ci1maW5hbCAgWFBhdGhDb250ZXh0IGdldFhQYXRoQ29udGV4dCgpe3JldHVybiBtX3hjdHh0O30KLQotcHVibGljIGZpbmFsIGludCBoYXNoQ29kZSgpIHsgcmV0dXJuIG1fZHRtSWRlbnRpdHk7IH0KLXB1YmxpYyBmaW5hbCBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqKSB7Ci0gICBpZiAob2JqIGluc3RhbmNlb2YgRFRNWFJUcmVlRnJhZykgewotICAgICAgIHJldHVybiAobV9kdG1JZGVudGl0eSA9PSAoKERUTVhSVHJlZUZyYWcpb2JqKS5nZXREVE1JZGVudGl0eSgpKTsKLSAgIH0KLSAgIHJldHVybiBmYWxzZTsKLSB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvb2JqZWN0cy9YQm9vbGVhbi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9vYmplY3RzL1hCb29sZWFuLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDYxY2FlZjQuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9vYmplY3RzL1hCb29sZWFuLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNzAgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogWEJvb2xlYW4uamF2YSx2IDEuMi40LjIgMjAwNS8wOS8xNCAyMDozNDo0NSBqZWZmc3V0dG9yIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHM7Ci0KLS8qKgotICogVGhpcyBjbGFzcyByZXByZXNlbnRzIGFuIFhQYXRoIGJvb2xlYW4gb2JqZWN0LCBhbmQgaXMgY2FwYWJsZSBvZgotICogY29udmVydGluZyB0aGUgYm9vbGVhbiB0byBvdGhlciB0eXBlcywgc3VjaCBhcyBhIHN0cmluZy4KLSAqIEB4c2wudXNhZ2UgYWR2YW5jZWQKLSAqLwotcHVibGljIGNsYXNzIFhCb29sZWFuIGV4dGVuZHMgWE9iamVjdAotewotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMjk2NDkzMzA1ODg2NjEwMDg4MUw7Ci0KLSAgLyoqCi0gICAqIEEgdHJ1ZSBib29sZWFuIG9iamVjdCBzbyB3ZSBkb24ndCBoYXZlIHRvIGtlZXAgY3JlYXRpbmcgdGhlbS4KLSAgICogQHhzbC51c2FnZSBpbnRlcm5hbAotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBYQm9vbGVhbiBTX1RSVUUgPSBuZXcgWEJvb2xlYW5TdGF0aWModHJ1ZSk7Ci0KLSAgLyoqCi0gICAqIEEgdHJ1ZSBib29sZWFuIG9iamVjdCBzbyB3ZSBkb24ndCBoYXZlIHRvIGtlZXAgY3JlYXRpbmcgdGhlbS4KLSAgICogQHhzbC51c2FnZSBpbnRlcm5hbAotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBYQm9vbGVhbiBTX0ZBTFNFID0gbmV3IFhCb29sZWFuU3RhdGljKGZhbHNlKTsKLQotICAvKiogVmFsdWUgb2YgdGhlIG9iamVjdC4KLSAgICogIEBzZXJpYWwgICAgICAgICAqLwotICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gbV92YWw7Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhIFhCb29sZWFuIG9iamVjdC4KLSAgICoKLSAgICogQHBhcmFtIGIgVmFsdWUgb2YgdGhlIGJvb2xlYW4gb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgWEJvb2xlYW4oYm9vbGVhbiBiKQotICB7Ci0KLSAgICBzdXBlcigpOwotCi0gICAgbV92YWwgPSBiOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhIFhCb29sZWFuIG9iamVjdC4KLSAgICoKLSAgICogQHBhcmFtIGIgVmFsdWUgb2YgdGhlIGJvb2xlYW4gb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgWEJvb2xlYW4oQm9vbGVhbiBiKQotICB7Ci0KLSAgICBzdXBlcigpOwotCi0gICAgbV92YWwgPSBiLmJvb2xlYW5WYWx1ZSgpOwotICAgIHNldE9iamVjdChiKTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIFRlbGwgdGhhdCB0aGlzIGlzIGEgQ0xBU1NfQk9PTEVBTi4KLSAgICoKLSAgICogQHJldHVybiB0eXBlIG9mIENMQVNTX0JPT0xFQU4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0VHlwZSgpCi0gIHsKLSAgICByZXR1cm4gQ0xBU1NfQk9PTEVBTjsKLSAgfQotCi0gIC8qKgotICAgKiBHaXZlbiBhIHJlcXVlc3QgdHlwZSwgcmV0dXJuIHRoZSBlcXVpdmFsZW50IHN0cmluZy4KLSAgICogRm9yIGRpYWdub3N0aWMgcHVycG9zZXMuCi0gICAqCi0gICAqIEByZXR1cm4gdHlwZSBzdHJpbmcgIiNCT09MRUFOIgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRUeXBlU3RyaW5nKCkKLSAgewotICAgIHJldHVybiAiI0JPT0xFQU4iOwotICB9Ci0KLSAgLyoqCi0gICAqIENhc3QgcmVzdWx0IG9iamVjdCB0byBhIG51bWJlci4KLSAgICoKLSAgICogQHJldHVybiBudW1lcmljIHZhbHVlIG9mIHRoZSBvYmplY3QgdmFsdWUKLSAgICovCi0gIHB1YmxpYyBkb3VibGUgbnVtKCkKLSAgewotICAgIHJldHVybiBtX3ZhbCA/IDEuMCA6IDAuMDsKLSAgfQotCi0gIC8qKgotICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYSBib29sZWFuLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBvYmplY3QgdmFsdWUgYXMgYSBib29sZWFuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBib29sKCkKLSAgewotICAgIHJldHVybiBtX3ZhbDsKLSAgfQotCi0gIC8qKgotICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYSBzdHJpbmcuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIG9iamVjdCdzIHZhbHVlIGFzIGEgc3RyaW5nCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIHN0cigpCi0gIHsKLSAgICByZXR1cm4gbV92YWwgPyAidHJ1ZSIgOiAiZmFsc2UiOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiBhIGphdmEgb2JqZWN0IHRoYXQncyBjbG9zZXN0IHRvIHRoZSByZXByZXNlbnRhdGlvbgotICAgKiB0aGF0IHNob3VsZCBiZSBoYW5kZWQgdG8gYW4gZXh0ZW5zaW9uLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBvYmplY3QncyB2YWx1ZSBhcyBhIGphdmEgb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgT2JqZWN0IG9iamVjdCgpCi0gIHsKLSAgICBpZihudWxsID09IG1fb2JqKQotICAgICAgc2V0T2JqZWN0KG5ldyBCb29sZWFuKG1fdmFsKSk7Ci0gICAgcmV0dXJuIG1fb2JqOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgdHdvIG9iamVjdHMgYXJlIGZ1bmN0aW9uYWxseSBlcXVhbC4KLSAgICoKLSAgICogQHBhcmFtIG9iajIgT2JqZWN0IHRvIGNvbXBhcmUgdG8gdGhpcwotICAgKgotICAgKiBAcmV0dXJuIFRydWUgaWYgdGhlIHR3byBvYmplY3RzIGFyZSBlcXVhbAotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGVxdWFscyhYT2JqZWN0IG9iajIpCi0gIHsKLQotICAgIC8vIEluIG9yZGVyIHRvIGhhbmRsZSB0aGUgJ2FsbCcgc2VtYW50aWNzIG9mCi0gICAgLy8gbm9kZXNldCBjb21wYXJpc29ucywgd2UgYWx3YXlzIGNhbGwgdGhlCi0gICAgLy8gbm9kZXNldCBmdW5jdGlvbi4KLSAgICBpZiAob2JqMi5nZXRUeXBlKCkgPT0gWE9iamVjdC5DTEFTU19OT0RFU0VUKQotICAgICAgcmV0dXJuIG9iajIuZXF1YWxzKHRoaXMpOwotCi0gICAgdHJ5Ci0gICAgewotICAgICAgcmV0dXJuIG1fdmFsID09IG9iajIuYm9vbCgpOwotICAgIH0KLSAgICBjYXRjaChqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uIHRlKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLldyYXBwZWRSdW50aW1lRXhjZXB0aW9uKHRlKTsKLSAgICB9Ci0gIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9vYmplY3RzL1hCb29sZWFuU3RhdGljLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL29iamVjdHMvWEJvb2xlYW5TdGF0aWMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNzE2OGYwOC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL29iamVjdHMvWEJvb2xlYW5TdGF0aWMuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDcxICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFhCb29sZWFuU3RhdGljLmphdmEsdiAxLjIuNC4yIDIwMDUvMDkvMTQgMjA6MzQ6NDYgamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgZG9lc24ndCBoYXZlIGFueSBYUGF0aENvbnRleHQsIHNvIG92ZXJyaWRlCi0gKiB3aGF0ZXZlciB0byBlbnN1cmUgaXQgd29ya3MgT0suCi0gKiBAeHNsLnVzYWdlIGludGVybmFsCi0gKi8KLXB1YmxpYyBjbGFzcyBYQm9vbGVhblN0YXRpYyBleHRlbmRzIFhCb29sZWFuCi17Ci0gICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC04MDY0MTQ3Mjc1NzcyNjg3NDA5TDsKLQotICAvKiogVGhlIHZhbHVlIG9mIHRoZSBvYmplY3QuCi0gICAqICBAc2VyaWFsICAgICAgICAgICovCi0gIHByaXZhdGUgZmluYWwgYm9vbGVhbiBtX3ZhbDsKLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgWEJvb2xlYW5TdGF0aWMgb2JqZWN0LgotICAgKgotICAgKiBAcGFyYW0gYiBUaGUgdmFsdWUgb2YgdGhlIG9iamVjdAotICAgKi8KLSAgcHVibGljIFhCb29sZWFuU3RhdGljKGJvb2xlYW4gYikKLSAgewotCi0gICAgc3VwZXIoYik7Ci0KLSAgICBtX3ZhbCA9IGI7Ci0gIH0KLQotICAvKioKLSAgICogVGVsbCBpZiB0d28gb2JqZWN0cyBhcmUgZnVuY3Rpb25hbGx5IGVxdWFsLgotICAgKgotICAgKiBAcGFyYW0gb2JqMiBPYmplY3QgdG8gY29tcGFyZSB0byB0aGlzCi0gICAqCi0gICAqIEByZXR1cm4gVHJ1ZSBpZiB0aGUgdHdvIG9iamVjdHMgYXJlIGVxdWFsCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZXF1YWxzKFhPYmplY3Qgb2JqMikKLSAgewotICAgIHRyeQotICAgIHsKLSAgICAgIHJldHVybiBtX3ZhbCA9PSBvYmoyLmJvb2woKTsKLSAgICB9Ci0gICAgY2F0Y2goamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbiB0ZSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5XcmFwcGVkUnVudGltZUV4Y2VwdGlvbih0ZSk7Ci0gICAgfQotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL29iamVjdHMvWE1MU3RyaW5nRmFjdG9yeUltcGwuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvb2JqZWN0cy9YTUxTdHJpbmdGYWN0b3J5SW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmNDc1ZTdkLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvb2JqZWN0cy9YTUxTdHJpbmdGYWN0b3J5SW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTAzICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFhNTFN0cmluZ0ZhY3RvcnlJbXBsLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTAgMTc6NDQ6MjkgamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5GYXN0U3RyaW5nQnVmZmVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuWE1MU3RyaW5nOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuWE1MU3RyaW5nRmFjdG9yeTsKLQotLyoqCi0gKiBDbGFzcyBYTUxTdHJpbmdGYWN0b3J5SW1wbCBjcmVhdGVzIFhTdHJpbmcgdmVyc2lvbnMgb2YgWE1MU3RyaW5ncy4KLSAqIEB4c2wudXNhZ2UgaW50ZXJuYWwKLSAqLwotcHVibGljIGNsYXNzIFhNTFN0cmluZ0ZhY3RvcnlJbXBsIGV4dGVuZHMgWE1MU3RyaW5nRmFjdG9yeQotewotICAvKiogVGhlIFhNTFN0cmluZ0ZhY3RvcnkgdG8gcGFzcyB0byBEVE0gY29uc3RydWN0aW9uLiAgICovCi0gIHByaXZhdGUgc3RhdGljIFhNTFN0cmluZ0ZhY3RvcnkgbV94c3RyaW5nZmFjdG9yeSA9Ci0gICAgbmV3IFhNTFN0cmluZ0ZhY3RvcnlJbXBsKCk7Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgWE1MU3RyaW5nRmFjdG9yeSB0byBwYXNzIHRvIERUTSBjb25zdHJ1Y3Rpb24uCi0gICAqCi0gICAqCi0gICAqIEByZXR1cm4gQSBuZXZlci1udWxsIHN0YXRpYyByZWZlcmVuY2UgdG8gYSBTdHJpbmcgZmFjdG9yeS4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgWE1MU3RyaW5nRmFjdG9yeSBnZXRGYWN0b3J5KCkKLSAgewotICAgIHJldHVybiBtX3hzdHJpbmdmYWN0b3J5OwotICB9Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIG5ldyBYTUxTdHJpbmcgZnJvbSBhIEphdmEgc3RyaW5nLgotICAgKgotICAgKgotICAgKiBAcGFyYW0gc3RyaW5nIEphdmEgU3RyaW5nIHJlZmVyZW5jZSwgd2hpY2ggbXVzdCBiZSBub24tbnVsbC4KLSAgICoKLSAgICogQHJldHVybiBBbiBYTUxTdHJpbmcgb2JqZWN0IHRoYXQgd3JhcHMgdGhlIFN0cmluZyByZWZlcmVuY2UuCi0gICAqLwotICBwdWJsaWMgWE1MU3RyaW5nIG5ld3N0cihTdHJpbmcgc3RyaW5nKQotICB7Ci0gICAgcmV0dXJuIG5ldyBYU3RyaW5nKHN0cmluZyk7Ci0gIH0KLQotICAvKioKLSAgICogQ3JlYXRlIGEgWE1MU3RyaW5nIGZyb20gYSBGYXN0U3RyaW5nQnVmZmVyLgotICAgKgotICAgKgotICAgKiBAcGFyYW0gZnNiIEZhc3RTdHJpbmdCdWZmZXIgcmVmZXJlbmNlLCB3aGljaCBtdXN0IGJlIG5vbi1udWxsLgotICAgKiBAcGFyYW0gc3RhcnQgVGhlIHN0YXJ0IHBvc2l0aW9uIGluIHRoZSBhcnJheS4KLSAgICogQHBhcmFtIGxlbmd0aCBUaGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gcmVhZCBmcm9tIHRoZSBhcnJheS4KLSAgICoKLSAgICogQHJldHVybiBBbiBYTUxTdHJpbmcgb2JqZWN0IHRoYXQgd3JhcHMgdGhlIEZhc3RTdHJpbmdCdWZmZXIgcmVmZXJlbmNlLgotICAgKi8KLSAgcHVibGljIFhNTFN0cmluZyBuZXdzdHIoRmFzdFN0cmluZ0J1ZmZlciBmc2IsIGludCBzdGFydCwgaW50IGxlbmd0aCkKLSAgewotICAgIHJldHVybiBuZXcgWFN0cmluZ0ZvckZTQihmc2IsIHN0YXJ0LCBsZW5ndGgpOwotICB9Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIFhNTFN0cmluZyBmcm9tIGEgRmFzdFN0cmluZ0J1ZmZlci4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHN0cmluZyBGYXN0U3RyaW5nQnVmZmVyIHJlZmVyZW5jZSwgd2hpY2ggbXVzdCBiZSBub24tbnVsbC4KLSAgICogQHBhcmFtIHN0YXJ0IFRoZSBzdGFydCBwb3NpdGlvbiBpbiB0aGUgYXJyYXkuCi0gICAqIEBwYXJhbSBsZW5ndGggVGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHJlYWQgZnJvbSB0aGUgYXJyYXkuCi0gICAqCi0gICAqIEByZXR1cm4gQW4gWE1MU3RyaW5nIG9iamVjdCB0aGF0IHdyYXBzIHRoZSBGYXN0U3RyaW5nQnVmZmVyIHJlZmVyZW5jZS4KLSAgICovCi0gIHB1YmxpYyBYTUxTdHJpbmcgbmV3c3RyKGNoYXJbXSBzdHJpbmcsIGludCBzdGFydCwgaW50IGxlbmd0aCkKLSAgewotICAgIHJldHVybiBuZXcgWFN0cmluZ0ZvckNoYXJzKHN0cmluZywgc3RhcnQsIGxlbmd0aCk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IGEgY2hlYXAgcmVwcmVzZW50YXRpb24gb2YgYW4gZW1wdHkgc3RyaW5nLgotICAgKgotICAgKiBAcmV0dXJuIEFuIG5vbi1udWxsIHJlZmVyZW5jZSB0byBhbiBYTUxTdHJpbmcgdGhhdCByZXByZXNlbnRzICIiLgotICAgKi8KLSAgcHVibGljIFhNTFN0cmluZyBlbXB0eXN0cigpCi0gIHsKLSAgICByZXR1cm4gWFN0cmluZy5FTVBUWVNUUklORzsKLSAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL29iamVjdHMvWE5vZGVTZXQuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvb2JqZWN0cy9YTm9kZVNldC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwN2RhYmMzLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvb2JqZWN0cy9YTm9kZVNldC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTcxICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFhOb2RlU2V0LmphdmEsdiAxLjIuNC4yIDIwMDUvMDkvMTQgMjA6MzQ6NDUgamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTUl0ZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTU1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5YTUxTdHJpbmc7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLk5vZGVTZXREVE07Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmF4ZXMuTm9kZVNlcXVlbmNlOwotCi1pbXBvcnQgb3JnLnczYy5kb20uTm9kZUxpc3Q7Ci1pbXBvcnQgb3JnLnczYy5kb20udHJhdmVyc2FsLk5vZGVJdGVyYXRvcjsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIHJlcHJlc2VudHMgYW4gWFBhdGggbm9kZXNldCBvYmplY3QsIGFuZCBpcyBjYXBhYmxlIG9mCi0gKiBjb252ZXJ0aW5nIHRoZSBub2Rlc2V0IHRvIG90aGVyIHR5cGVzLCBzdWNoIGFzIGEgc3RyaW5nLgotICogQHhzbC51c2FnZSBnZW5lcmFsCi0gKi8KLXB1YmxpYyBjbGFzcyBYTm9kZVNldCBleHRlbmRzIE5vZGVTZXF1ZW5jZQotewotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxOTE2MDI2MzY4MDM1NjM5NjY3TDsKLSAgLyoqCi0gICAqIERlZmF1bHQgY29uc3RydWN0b3IgZm9yIGRlcml2ZWQgb2JqZWN0cy4KLSAgICovCi0gIHByb3RlY3RlZCBYTm9kZVNldCgpCi0gIHsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBYTm9kZVNldCBvYmplY3QuCi0gICAqCi0gICAqIEBwYXJhbSB2YWwgVmFsdWUgb2YgdGhlIFhOb2RlU2V0IG9iamVjdAotICAgKi8KLSAgcHVibGljIFhOb2RlU2V0KERUTUl0ZXJhdG9yIHZhbCkKLSAgewotICAgICAgICBzdXBlcigpOwotICAgICAgICBpZih2YWwgaW5zdGFuY2VvZiBYTm9kZVNldCkKLSAgICAgICAgewotICAgICAgICAgICAgZmluYWwgWE5vZGVTZXQgbm9kZVNldCA9IChYTm9kZVNldCkgdmFsOwotICAgICAgICAgICAgc2V0SXRlcihub2RlU2V0Lm1faXRlcik7Ci0gICAgICAgICAgICBtX2R0bU1nciA9IG5vZGVTZXQubV9kdG1NZ3I7Ci0gICAgICAgICAgICBtX2xhc3QgPSBub2RlU2V0Lm1fbGFzdDsKLSAgICAgICAgICAgIC8vIEZpcnN0IG1ha2Ugc3VyZSB0aGUgRFRNSXRlcmF0b3IgdmFsIGhhcyBhIGNhY2hlLAotICAgICAgICAgICAgLy8gc28gaWYgaXQgZG9lc24ndCBoYXZlIG9uZSwgbWFrZSBvbmUuCi0gICAgICAgICAgICBpZighbm9kZVNldC5oYXNDYWNoZSgpKQotICAgICAgICAgICAgICAgIG5vZGVTZXQuc2V0U2hvdWxkQ2FjaGVOb2Rlcyh0cnVlKTsKLQotICAgICAgICAgICAgLy8gR2V0IHRoZSBjYWNoZSBmcm9tIHZhbCBhbmQgdXNlIGl0IG91cnNlbHZlcyAod2Ugc2hhcmUgaXQpLgotICAgICAgICAgICAgc2V0T2JqZWN0KG5vZGVTZXQuZ2V0SXRlcmF0b3JDYWNoZSgpKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgIHNldEl0ZXIodmFsKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBYTm9kZVNldCBvYmplY3QuCi0gICAqCi0gICAqIEBwYXJhbSB2YWwgVmFsdWUgb2YgdGhlIFhOb2RlU2V0IG9iamVjdAotICAgKi8KLSAgcHVibGljIFhOb2RlU2V0KFhOb2RlU2V0IHZhbCkKLSAgewotICAgICAgICBzdXBlcigpOwotICAgIHNldEl0ZXIodmFsLm1faXRlcik7Ci0gICAgbV9kdG1NZ3IgPSB2YWwubV9kdG1NZ3I7Ci0gICAgbV9sYXN0ID0gdmFsLm1fbGFzdDsKLSAgICBpZighdmFsLmhhc0NhY2hlKCkpCi0gICAgICAgIHZhbC5zZXRTaG91bGRDYWNoZU5vZGVzKHRydWUpOwotICAgIHNldE9iamVjdCh2YWwubV9vYmopOwotICB9Ci0KLQotICAvKioKLSAgICogQ29uc3RydWN0IGFuIGVtcHR5IFhOb2RlU2V0IG9iamVjdC4gIFRoaXMgaXMgdXNlZCB0byBjcmVhdGUgYSBtdXRhYmxlCi0gICAqIG5vZGVzZXQgdG8gd2hpY2ggcmFuZG9tIG5vZGVzIG1heSBiZSBhZGRlZC4KLSAgICovCi0gIHB1YmxpYyBYTm9kZVNldChEVE1NYW5hZ2VyIGR0bU1ncikKLSAgewotICAgICB0aGlzKERUTS5OVUxMLGR0bU1ncik7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgWE5vZGVTZXQgb2JqZWN0IGZvciBvbmUgbm9kZS4KLSAgICoKLSAgICogQHBhcmFtIG4gTm9kZSB0byBhZGQgdG8gdGhlIG5ldyBYTm9kZVNldCBvYmplY3QKLSAgICovCi0gIHB1YmxpYyBYTm9kZVNldChpbnQgbiwgRFRNTWFuYWdlciBkdG1NZ3IpCi0gIHsKLQotICAgIHN1cGVyKG5ldyBOb2RlU2V0RFRNKGR0bU1ncikpOwotICAgIG1fZHRtTWdyID0gZHRtTWdyOwotCi0gICAgaWYgKERUTS5OVUxMICE9IG4pCi0gICAgewotICAgICAgKChOb2RlU2V0RFRNKSBtX29iaikuYWRkTm9kZShuKTsKLSAgICAgIG1fbGFzdCA9IDE7Ci0gICAgfQotICAgIGVsc2UKLSAgICAgICAgbV9sYXN0ID0gMDsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIHRoYXQgdGhpcyBpcyBhIENMQVNTX05PREVTRVQuCi0gICAqCi0gICAqIEByZXR1cm4gdHlwZSBDTEFTU19OT0RFU0VUCi0gICAqLwotICBwdWJsaWMgaW50IGdldFR5cGUoKQotICB7Ci0gICAgcmV0dXJuIENMQVNTX05PREVTRVQ7Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYSByZXF1ZXN0IHR5cGUsIHJldHVybiB0aGUgZXF1aXZhbGVudCBzdHJpbmcuCi0gICAqIEZvciBkaWFnbm9zdGljIHB1cnBvc2VzLgotICAgKgotICAgKiBAcmV0dXJuIHR5cGUgc3RyaW5nICIjTk9ERVNFVCIKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0VHlwZVN0cmluZygpCi0gIHsKLSAgICByZXR1cm4gIiNOT0RFU0VUIjsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgbnVtZXJpYyB2YWx1ZSBvZiB0aGUgc3RyaW5nIGNvbnZlcnNpb24gZnJvbSBhIHNpbmdsZSBub2RlLgotICAgKgotICAgKiBAcGFyYW0gbiBOb2RlIHRvIGNvbnZlcnQKLSAgICoKLSAgICogQHJldHVybiBudW1lcmljIHZhbHVlIG9mIHRoZSBzdHJpbmcgY29udmVyc2lvbiBmcm9tIGEgc2luZ2xlIG5vZGUuCi0gICAqLwotICBwdWJsaWMgZG91YmxlIGdldE51bWJlckZyb21Ob2RlKGludCBuKQotICB7Ci0gICAgWE1MU3RyaW5nIHhzdHIgPSBtX2R0bU1nci5nZXREVE0obikuZ2V0U3RyaW5nVmFsdWUobik7Ci0gICAgcmV0dXJuIHhzdHIudG9Eb3VibGUoKTsKLSAgfQotCi0gIC8qKgotICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYSBudW1iZXIuCi0gICAqCi0gICAqIEByZXR1cm4gbnVtZXJpYyB2YWx1ZSBvZiB0aGUgc3RyaW5nIGNvbnZlcnNpb24gZnJvbSB0aGUKLSAgICogbmV4dCBub2RlIGluIHRoZSBOb2RlU2V0RFRNLCBvciBOQU4gaWYgbm8gbm9kZSB3YXMgZm91bmQKLSAgICovCi0gIHB1YmxpYyBkb3VibGUgbnVtKCkKLSAgewotCi0gICAgaW50IG5vZGUgPSBpdGVtKDApOwotICAgIHJldHVybiAobm9kZSAhPSBEVE0uTlVMTCkgPyBnZXROdW1iZXJGcm9tTm9kZShub2RlKSA6IERvdWJsZS5OYU47Ci0gIH0KLQotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGEgbnVtYmVyLCBidXQgYWxsb3cgc2lkZSBlZmZlY3RzLCBzdWNoIGFzIHRoZQotICAgKiBpbmNyZW1lbnRpbmcgb2YgYW4gaXRlcmF0b3IuCi0gICAqCi0gICAqIEByZXR1cm4gbnVtZXJpYyB2YWx1ZSBvZiB0aGUgc3RyaW5nIGNvbnZlcnNpb24gZnJvbSB0aGUKLSAgICogbmV4dCBub2RlIGluIHRoZSBOb2RlU2V0RFRNLCBvciBOQU4gaWYgbm8gbm9kZSB3YXMgZm91bmQKLSAgICovCi0gIHB1YmxpYyBkb3VibGUgbnVtV2l0aFNpZGVFZmZlY3RzKCkKLSAgewotICAgIGludCBub2RlID0gbmV4dE5vZGUoKTsKLQotICAgIHJldHVybiAobm9kZSAhPSBEVE0uTlVMTCkgPyBnZXROdW1iZXJGcm9tTm9kZShub2RlKSA6IERvdWJsZS5OYU47Ci0gIH0KLQotCi0gIC8qKgotICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYSBib29sZWFuLgotICAgKgotICAgKiBAcmV0dXJuIFRydWUgaWYgdGhlcmUgaXMgYSBuZXh0IG5vZGUgaW4gdGhlIG5vZGVzZXQKLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGJvb2woKQotICB7Ci0gICAgcmV0dXJuIChpdGVtKDApICE9IERUTS5OVUxMKTsKLSAgfQotCi0gIC8qKgotICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYSBib29sZWFuLCBidXQgYWxsb3cgc2lkZSBlZmZlY3RzLCBzdWNoIGFzIHRoZQotICAgKiBpbmNyZW1lbnRpbmcgb2YgYW4gaXRlcmF0b3IuCi0gICAqCi0gICAqIEByZXR1cm4gVHJ1ZSBpZiB0aGVyZSBpcyBhIG5leHQgbm9kZSBpbiB0aGUgbm9kZXNldAotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gYm9vbFdpdGhTaWRlRWZmZWN0cygpCi0gIHsKLSAgICByZXR1cm4gKG5leHROb2RlKCkgIT0gRFRNLk5VTEwpOwotICB9Ci0KLQotICAvKioKLSAgICogR2V0IHRoZSBzdHJpbmcgY29udmVyc2lvbiBmcm9tIGEgc2luZ2xlIG5vZGUuCi0gICAqCi0gICAqIEBwYXJhbSBuIE5vZGUgdG8gY29udmVydAotICAgKgotICAgKiBAcmV0dXJuIHRoZSBzdHJpbmcgY29udmVyc2lvbiBmcm9tIGEgc2luZ2xlIG5vZGUuCi0gICAqLwotICBwdWJsaWMgWE1MU3RyaW5nIGdldFN0cmluZ0Zyb21Ob2RlKGludCBuKQotICB7Ci0gICAgLy8gJU9QVCUKLSAgICAvLyBJIGd1ZXNzIHdlJ2xsIGhhdmUgdG8gZ2V0IGEgc3RhdGljIGluc3RhbmNlIG9mIHRoZSBEVE0gbWFuYWdlci4uLgotICAgIGlmKERUTS5OVUxMICE9IG4pCi0gICAgewotICAgICAgcmV0dXJuIG1fZHRtTWdyLmdldERUTShuKS5nZXRTdHJpbmdWYWx1ZShuKTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIHJldHVybiBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YU3RyaW5nLkVNUFRZU1RSSU5HOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBEaXJlY3RseSBjYWxsIHRoZQotICAgKiBjaGFyYWN0ZXJzIG1ldGhvZCBvbiB0aGUgcGFzc2VkIENvbnRlbnRIYW5kbGVyIGZvciB0aGUKLSAgICogc3RyaW5nLXZhbHVlLiBNdWx0aXBsZSBjYWxscyB0byB0aGUKLSAgICogQ29udGVudEhhbmRsZXIncyBjaGFyYWN0ZXJzIG1ldGhvZHMgbWF5IHdlbGwgb2NjdXIgZm9yIGEgc2luZ2xlIGNhbGwgdG8KLSAgICogdGhpcyBtZXRob2QuCi0gICAqCi0gICAqIEBwYXJhbSBjaCBBIG5vbi1udWxsIHJlZmVyZW5jZSB0byBhIENvbnRlbnRIYW5kbGVyLgotICAgKgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgZGlzcGF0Y2hDaGFyYWN0ZXJzRXZlbnRzKG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyIGNoKQotICAgICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIGludCBub2RlID0gaXRlbSgwKTsKLQotICAgIGlmKG5vZGUgIT0gRFRNLk5VTEwpCi0gICAgewotICAgICAgbV9kdG1NZ3IuZ2V0RFRNKG5vZGUpLmRpc3BhdGNoQ2hhcmFjdGVyc0V2ZW50cyhub2RlLCBjaCwgZmFsc2UpOwotICAgIH0KLQotICB9Ci0KLSAgLyoqCi0gICAqIENhc3QgcmVzdWx0IG9iamVjdCB0byBhbiBYTUxTdHJpbmcuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGRvY3VtZW50IGZyYWdtZW50IG5vZGUgZGF0YSBvciB0aGUgZW1wdHkgc3RyaW5nLgotICAgKi8KLSAgcHVibGljIFhNTFN0cmluZyB4c3RyKCkKLSAgewotICAgIGludCBub2RlID0gaXRlbSgwKTsKLSAgICByZXR1cm4gKG5vZGUgIT0gRFRNLk5VTEwpID8gZ2V0U3RyaW5nRnJvbU5vZGUobm9kZSkgOiBYU3RyaW5nLkVNUFRZU1RSSU5HOwotICB9Ci0KLSAgLyoqCi0gICAqIENhc3QgcmVzdWx0IG9iamVjdCB0byBhIHN0cmluZy4KLSAgICoKLSAgICogQHJldHVybiBUaGUgc3RyaW5nIHRoaXMgd3JhcHMgb3IgdGhlIGVtcHR5IHN0cmluZyBpZiBudWxsCi0gICAqLwotICBwdWJsaWMgdm9pZCBhcHBlbmRUb0ZzYihjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLkZhc3RTdHJpbmdCdWZmZXIgZnNiKQotICB7Ci0gICAgWFN0cmluZyB4c3RyaW5nID0gKFhTdHJpbmcpeHN0cigpOwotICAgIHhzdHJpbmcuYXBwZW5kVG9Gc2IoZnNiKTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIENhc3QgcmVzdWx0IG9iamVjdCB0byBhIHN0cmluZy4KLSAgICoKLSAgICogQHJldHVybiB0aGUgc3RyaW5nIGNvbnZlcnNpb24gZnJvbSB0aGUgbmV4dCBub2RlIGluIHRoZSBub2Rlc2V0Ci0gICAqIG9yICIiIGlmIHRoZXJlIGlzIG5vIG5leHQgbm9kZQotICAgKi8KLSAgcHVibGljIFN0cmluZyBzdHIoKQotICB7Ci0gICAgaW50IG5vZGUgPSBpdGVtKDApOwotICAgIHJldHVybiAobm9kZSAhPSBEVE0uTlVMTCkgPyBnZXRTdHJpbmdGcm9tTm9kZShub2RlKS50b1N0cmluZygpIDogIiI7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIGEgamF2YSBvYmplY3QgdGhhdCdzIGNsb3Nlc3QgdG8gdGhlIHJlcHJlc2VudGF0aW9uCi0gICAqIHRoYXQgc2hvdWxkIGJlIGhhbmRlZCB0byBhbiBleHRlbnNpb24uCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIG9iamVjdCB0aGF0IHRoaXMgY2xhc3Mgd3JhcHMKLSAgICovCi0gIHB1YmxpYyBPYmplY3Qgb2JqZWN0KCkKLSAgewotICAgIGlmKG51bGwgPT0gbV9vYmopCi0gICAgICAgIHJldHVybiB0aGlzOwotICAgIGVsc2UKLSAgICAgICAgcmV0dXJuIG1fb2JqOwotICB9Ci0KLSAgLy8gJVJFVklFVyUKLSAgLy8gaG1tbS4uLgotLy8gIC8qKgotLy8gICAqIENhc3QgcmVzdWx0IG9iamVjdCB0byBhIHJlc3VsdCB0cmVlIGZyYWdtZW50LgotLy8gICAqCi0vLyAgICogQHBhcmFtIHN1cHBvcnQgVGhlIFhQYXRoIGNvbnRleHQgdG8gdXNlIGZvciB0aGUgY29udmVyc2lvbgotLy8gICAqCi0vLyAgICogQHJldHVybiB0aGUgbm9kZXNldCBhcyBhIHJlc3VsdCB0cmVlIGZyYWdtZW50LgotLy8gICAqLwotLy8gIHB1YmxpYyBEb2N1bWVudEZyYWdtZW50IHJ0cmVlKFhQYXRoQ29udGV4dCBzdXBwb3J0KQotLy8gIHsKLS8vICAgIERvY3VtZW50QnVpbGRlckZhY3RvcnkgZGJmID0gRG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5uZXdJbnN0YW5jZSgpOwotLy8gICAgRG9jdW1lbnRCdWlsZGVyIGRiID0gZGJmLm5ld0RvY3VtZW50QnVpbGRlcigpOwotLy8gICAgRG9jdW1lbnQgbXlEb2MgPSBkYi5uZXdEb2N1bWVudCgpOwotLy8KLS8vICAgIERvY3VtZW50RnJhZ21lbnQgZG9jRnJhZyA9IG15RG9jLmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTsKLS8vCi0vLyAgICBEVE1JdGVyYXRvciBubCA9IGl0ZXIoKTsKLS8vICAgIGludCBub2RlOwotLy8KLS8vICAgIHdoaWxlIChEVE0uTlVMTCAhPSAobm9kZSA9IG5sLm5leHROb2RlKCkpKQotLy8gICAgewotLy8gICAgICBmcmFnLmFwcGVuZENoaWxkKG5vZGUsIHRydWUsIHRydWUpOwotLy8gICAgfQotLy8KLS8vICAgIHJldHVybiBmcmFnLmdldERvY3VtZW50KCk7Ci0vLyAgfQotCi0gIC8qKgotICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYSBub2RlbGlzdC4KLSAgICoKLSAgICogQHJldHVybiBhIE5vZGVJdGVyYXRvci4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgTm9kZUl0ZXJhdG9yIG5vZGVzZXQoKSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIG5ldyBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5yZWYuRFRNTm9kZUl0ZXJhdG9yKGl0ZXIoKSk7Ci0gIH0KLQotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGEgbm9kZWxpc3QuCi0gICAqCi0gICAqIEByZXR1cm4gYSBOb2RlTGlzdC4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgTm9kZUxpc3Qgbm9kZWxpc3QoKSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0ucmVmLkRUTU5vZGVMaXN0IG5vZGVsaXN0ID0gbmV3IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLnJlZi5EVE1Ob2RlTGlzdCh0aGlzKTsKLSAgICAvLyBDcmVhdGluZyBhIERUTU5vZGVMaXN0IGhhcyB0aGUgc2lkZS1lZmZlY3QgdGhhdCBpdCB3aWxsIGNyZWF0ZSBhIGNsb25lCi0gICAgLy8gWE5vZGVTZXQgd2l0aCBjYWNoZSBhbmQgcnVuIG1faXRlciB0byB0aGUgZW5kLiBZb3UgY2Fubm90IGdldCBhbnkgbm9kZQotICAgIC8vIGZyb20gbV9pdGVyIGFmdGVyIHRoaXMgY2FsbC4gQXMgYSBmaXgsIHdlIGNhbGwgU2V0VmVjdG9yKCkgb24gdGhlIGNsb25lJ3MKLSAgICAvLyBjYWNoZS4gU2VlIEJ1Z3ppbGxhIDE0NDA2LgotICAgIFhOb2RlU2V0IGNsb25lID0gKFhOb2RlU2V0KW5vZGVsaXN0LmdldERUTUl0ZXJhdG9yKCk7Ci0gICAgU2V0VmVjdG9yKGNsb25lLmdldFZlY3RvcigpKTsKLSAgICByZXR1cm4gbm9kZWxpc3Q7Ci0gIH0KLQotCi0vLyAgLyoqCi0vLyAgICogUmV0dXJuIGEgamF2YSBvYmplY3QgdGhhdCdzIGNsb3Nlc3QgdG8gdGhlIHJlcHJlc2VudGF0aW9uCi0vLyAgICogdGhhdCBzaG91bGQgYmUgaGFuZGVkIHRvIGFuIGV4dGVuc2lvbi4KLS8vICAgKgotLy8gICAqIEByZXR1cm4gVGhlIG9iamVjdCB0aGF0IHRoaXMgY2xhc3Mgd3JhcHMKLS8vICAgKi8KLS8vICBwdWJsaWMgT2JqZWN0IG9iamVjdCgpCi0vLyAgewotLy8gICAgcmV0dXJuIG5ldyBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5yZWYuRFRNTm9kZUxpc3QoaXRlcigpKTsKLS8vICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgaXRlcmF0b3Igd2l0aG91dCBjbG9uaW5nLCBldGMuCi0gICAqLwotICBwdWJsaWMgRFRNSXRlcmF0b3IgaXRlclJhdygpCi0gIHsKLSAgICByZXR1cm4gdGhpczsKLSAgfQotCi0gIHB1YmxpYyB2b2lkIHJlbGVhc2UoRFRNSXRlcmF0b3IgaXRlcikKLSAgewotICB9Ci0KLSAgLyoqCi0gICAqIENhc3QgcmVzdWx0IG9iamVjdCB0byBhIG5vZGVsaXN0LgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBub2Rlc2V0IGFzIGEgbm9kZWxpc3QKLSAgICovCi0gIHB1YmxpYyBEVE1JdGVyYXRvciBpdGVyKCkKLSAgewotICAgIHRyeQotICAgIHsKLSAgICAgICAgaWYoaGFzQ2FjaGUoKSkKLSAgICAgICAgICAgICAgICByZXR1cm4gY2xvbmVXaXRoUmVzZXQoKTsKLSAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIHJldHVybiB0aGlzOyAvLyBkb24ndCBib3RoZXIgdG8gY2xvbmUuLi4gd29uJ3QgZG8gYW55IGdvb2QhCi0gICAgfQotICAgIGNhdGNoIChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBjbnNlKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGNuc2UuZ2V0TWVzc2FnZSgpKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogR2V0IGEgZnJlc2ggY29weSBvZiB0aGUgb2JqZWN0LiAgRm9yIHVzZSB3aXRoIHZhcmlhYmxlcy4KLSAgICoKLSAgICogQHJldHVybiBBIGZyZXNoIG5vZGVsaXN0LgotICAgKi8KLSAgcHVibGljIFhPYmplY3QgZ2V0RnJlc2goKQotICB7Ci0gICAgdHJ5Ci0gICAgewotICAgICAgICBpZihoYXNDYWNoZSgpKQotICAgICAgICAgICAgICAgIHJldHVybiAoWE9iamVjdCljbG9uZVdpdGhSZXNldCgpOwotICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7IC8vIGRvbid0IGJvdGhlciB0byBjbG9uZS4uLiB3b24ndCBkbyBhbnkgZ29vZCEKLSAgICB9Ci0gICAgY2F0Y2ggKENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGNuc2UpCi0gICAgewotICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oY25zZS5nZXRNZXNzYWdlKCkpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYSBtdXRhYmxlTm9kZXNldC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgbm9kZXNldCBhcyBhIG11dGFibGVOb2Rlc2V0Ci0gICAqLwotICBwdWJsaWMgTm9kZVNldERUTSBtdXRhYmxlTm9kZXNldCgpCi0gIHsKLSAgICBOb2RlU2V0RFRNIG1ubDsKLQotICAgIGlmKG1fb2JqIGluc3RhbmNlb2YgTm9kZVNldERUTSkKLSAgICB7Ci0gICAgICBtbmwgPSAoTm9kZVNldERUTSkgbV9vYmo7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBtbmwgPSBuZXcgTm9kZVNldERUTShpdGVyKCkpOwotICAgICAgc2V0T2JqZWN0KG1ubCk7Ci0gICAgICBzZXRDdXJyZW50UG9zKDApOwotICAgIH0KLQotICAgIHJldHVybiBtbmw7Ci0gIH0KLQotICAvKiogTGVzcyB0aGFuIGNvbXBhcmF0b3IgICAgICAgICAqLwotICBzdGF0aWMgZmluYWwgTGVzc1RoYW5Db21wYXJhdG9yIFNfTFQgPSBuZXcgTGVzc1RoYW5Db21wYXJhdG9yKCk7Ci0KLSAgLyoqIExlc3MgdGhhbiBvciBlcXVhbCBjb21wYXJhdG9yICAgICAgICAgICovCi0gIHN0YXRpYyBmaW5hbCBMZXNzVGhhbk9yRXF1YWxDb21wYXJhdG9yIFNfTFRFID0gbmV3IExlc3NUaGFuT3JFcXVhbENvbXBhcmF0b3IoKTsKLQotICAvKiogR3JlYXRlciB0aGFuIGNvbXBhcmF0b3IgICAgICAgICAqLwotICBzdGF0aWMgZmluYWwgR3JlYXRlclRoYW5Db21wYXJhdG9yIFNfR1QgPSBuZXcgR3JlYXRlclRoYW5Db21wYXJhdG9yKCk7Ci0KLSAgLyoqIEdyZWF0ZXIgdGhhbiBvciBlcXVhbCBjb21wYXJhdG9yICAgICAgICAgICovCi0gIHN0YXRpYyBmaW5hbCBHcmVhdGVyVGhhbk9yRXF1YWxDb21wYXJhdG9yIFNfR1RFID0KLSAgICBuZXcgR3JlYXRlclRoYW5PckVxdWFsQ29tcGFyYXRvcigpOwotCi0gIC8qKiBFcXVhbCBjb21wYXJhdG9yICAgICAgICAgKi8KLSAgc3RhdGljIGZpbmFsIEVxdWFsQ29tcGFyYXRvciBTX0VRID0gbmV3IEVxdWFsQ29tcGFyYXRvcigpOwotCi0gIC8qKiBOb3QgZXF1YWwgY29tcGFyYXRvciAgICAgICAgICovCi0gIHN0YXRpYyBmaW5hbCBOb3RFcXVhbENvbXBhcmF0b3IgU19ORVEgPSBuZXcgTm90RXF1YWxDb21wYXJhdG9yKCk7Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgb25lIG9iamVjdCBpcyBsZXNzIHRoYW4gdGhlIG90aGVyLgotICAgKgotICAgKiBAcGFyYW0gb2JqMiBPYmplY3QgdG8gY29tcGFyZSB0aGlzIG5vZGVzZXQgdG8KLSAgICogQHBhcmFtIGNvbXBhcmF0b3IgQ29tcGFyYXRvciB0byB1c2UKLSAgICoKLSAgICogQHJldHVybiBTZWUgdGhlIGNvbW1lbnRzIGJlbG93IGZvciBlYWNoIG9iamVjdCB0eXBlIGNvbXBhcmlzb24KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBjb21wYXJlKFhPYmplY3Qgb2JqMiwgQ29tcGFyYXRvciBjb21wYXJhdG9yKQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGJvb2xlYW4gcmVzdWx0ID0gZmFsc2U7Ci0gICAgaW50IHR5cGUgPSBvYmoyLmdldFR5cGUoKTsKLQotICAgIGlmIChYT2JqZWN0LkNMQVNTX05PREVTRVQgPT0gdHlwZSkKLSAgICB7Ci0gICAgICAvLyAlT1BUJSBUaGlzIHNob3VsZCBiZSBYTUxTdHJpbmcgYmFzZWQgaW5zdGVhZCBvZiBzdHJpbmcgYmFzZWQuLi4KLQotICAgICAgLy8gRnJvbSBodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aDoKLSAgICAgIC8vIElmIGJvdGggb2JqZWN0cyB0byBiZSBjb21wYXJlZCBhcmUgbm9kZS1zZXRzLCB0aGVuIHRoZSBjb21wYXJpc29uCi0gICAgICAvLyB3aWxsIGJlIHRydWUgaWYgYW5kIG9ubHkgaWYgdGhlcmUgaXMgYSBub2RlIGluIHRoZSBmaXJzdCBub2RlLXNldAotICAgICAgLy8gYW5kIGEgbm9kZSBpbiB0aGUgc2Vjb25kIG5vZGUtc2V0IHN1Y2ggdGhhdCB0aGUgcmVzdWx0IG9mIHBlcmZvcm1pbmcKLSAgICAgIC8vIHRoZSBjb21wYXJpc29uIG9uIHRoZSBzdHJpbmctdmFsdWVzIG9mIHRoZSB0d28gbm9kZXMgaXMgdHJ1ZS4KLSAgICAgIC8vIE5vdGUgdGhpcyBsaXR0bGUgZ2VtIGZyb20gdGhlIGRyYWZ0OgotICAgICAgLy8gTk9URTogSWYgJHggaXMgYm91bmQgdG8gYSBub2RlLXNldCwgdGhlbiAkeD0iZm9vIgotICAgICAgLy8gZG9lcyBub3QgbWVhbiB0aGUgc2FtZSBhcyBub3QoJHghPSJmb28iKTogdGhlIGZvcm1lcgotICAgICAgLy8gaXMgdHJ1ZSBpZiBhbmQgb25seSBpZiBzb21lIG5vZGUgaW4gJHggaGFzIHRoZSBzdHJpbmctdmFsdWUKLSAgICAgIC8vIGZvbzsgdGhlIGxhdHRlciBpcyB0cnVlIGlmIGFuZCBvbmx5IGlmIGFsbCBub2RlcyBpbiAkeCBoYXZlCi0gICAgICAvLyB0aGUgc3RyaW5nLXZhbHVlIGZvby4KLSAgICAgIERUTUl0ZXJhdG9yIGxpc3QxID0gaXRlclJhdygpOwotICAgICAgRFRNSXRlcmF0b3IgbGlzdDIgPSAoKFhOb2RlU2V0KSBvYmoyKS5pdGVyUmF3KCk7Ci0gICAgICBpbnQgbm9kZTE7Ci0gICAgICBqYXZhLnV0aWwuVmVjdG9yIG5vZGUyU3RyaW5ncyA9IG51bGw7Ci0KLSAgICAgIHdoaWxlIChEVE0uTlVMTCAhPSAobm9kZTEgPSBsaXN0MS5uZXh0Tm9kZSgpKSkKLSAgICAgIHsKLSAgICAgICAgWE1MU3RyaW5nIHMxID0gZ2V0U3RyaW5nRnJvbU5vZGUobm9kZTEpOwotCi0gICAgICAgIGlmIChudWxsID09IG5vZGUyU3RyaW5ncykKLSAgICAgICAgewotICAgICAgICAgIGludCBub2RlMjsKLQotICAgICAgICAgIHdoaWxlIChEVE0uTlVMTCAhPSAobm9kZTIgPSBsaXN0Mi5uZXh0Tm9kZSgpKSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBYTUxTdHJpbmcgczIgPSBnZXRTdHJpbmdGcm9tTm9kZShub2RlMik7Ci0KLSAgICAgICAgICAgIGlmIChjb21wYXJhdG9yLmNvbXBhcmVTdHJpbmdzKHMxLCBzMikpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIHJlc3VsdCA9IHRydWU7Ci0KLSAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmIChudWxsID09IG5vZGUyU3RyaW5ncykKLSAgICAgICAgICAgICAgbm9kZTJTdHJpbmdzID0gbmV3IGphdmEudXRpbC5WZWN0b3IoKTsKLQotICAgICAgICAgICAgbm9kZTJTdHJpbmdzLmFkZEVsZW1lbnQoczIpOwotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgIHsKLSAgICAgICAgICBpbnQgbiA9IG5vZGUyU3RyaW5ncy5zaXplKCk7Ci0KLSAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBpZiAoY29tcGFyYXRvci5jb21wYXJlU3RyaW5ncyhzMSwgKFhNTFN0cmluZylub2RlMlN0cmluZ3MuZWxlbWVudEF0KGkpKSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgcmVzdWx0ID0gdHJ1ZTsKLQotICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICAgIGxpc3QxLnJlc2V0KCk7Ci0gICAgICBsaXN0Mi5yZXNldCgpOwotICAgIH0KLSAgICBlbHNlIGlmIChYT2JqZWN0LkNMQVNTX0JPT0xFQU4gPT0gdHlwZSkKLSAgICB7Ci0KLSAgICAgIC8vIEZyb20gaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGg6Ci0gICAgICAvLyBJZiBvbmUgb2JqZWN0IHRvIGJlIGNvbXBhcmVkIGlzIGEgbm9kZS1zZXQgYW5kIHRoZSBvdGhlciBpcyBhIGJvb2xlYW4sCi0gICAgICAvLyB0aGVuIHRoZSBjb21wYXJpc29uIHdpbGwgYmUgdHJ1ZSBpZiBhbmQgb25seSBpZiB0aGUgcmVzdWx0IG9mCi0gICAgICAvLyBwZXJmb3JtaW5nIHRoZSBjb21wYXJpc29uIG9uIHRoZSBib29sZWFuIGFuZCBvbiB0aGUgcmVzdWx0IG9mCi0gICAgICAvLyBjb252ZXJ0aW5nIHRoZSBub2RlLXNldCB0byBhIGJvb2xlYW4gdXNpbmcgdGhlIGJvb2xlYW4gZnVuY3Rpb24KLSAgICAgIC8vIGlzIHRydWUuCi0gICAgICBkb3VibGUgbnVtMSA9IGJvb2woKSA/IDEuMCA6IDAuMDsKLSAgICAgIGRvdWJsZSBudW0yID0gb2JqMi5udW0oKTsKLQotICAgICAgcmVzdWx0ID0gY29tcGFyYXRvci5jb21wYXJlTnVtYmVycyhudW0xLCBudW0yKTsKLSAgICB9Ci0gICAgZWxzZSBpZiAoWE9iamVjdC5DTEFTU19OVU1CRVIgPT0gdHlwZSkKLSAgICB7Ci0KLSAgICAgIC8vIEZyb20gaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGg6Ci0gICAgICAvLyBJZiBvbmUgb2JqZWN0IHRvIGJlIGNvbXBhcmVkIGlzIGEgbm9kZS1zZXQgYW5kIHRoZSBvdGhlciBpcyBhIG51bWJlciwKLSAgICAgIC8vIHRoZW4gdGhlIGNvbXBhcmlzb24gd2lsbCBiZSB0cnVlIGlmIGFuZCBvbmx5IGlmIHRoZXJlIGlzIGEKLSAgICAgIC8vIG5vZGUgaW4gdGhlIG5vZGUtc2V0IHN1Y2ggdGhhdCB0aGUgcmVzdWx0IG9mIHBlcmZvcm1pbmcgdGhlCi0gICAgICAvLyBjb21wYXJpc29uIG9uIHRoZSBudW1iZXIgdG8gYmUgY29tcGFyZWQgYW5kIG9uIHRoZSByZXN1bHQgb2YKLSAgICAgIC8vIGNvbnZlcnRpbmcgdGhlIHN0cmluZy12YWx1ZSBvZiB0aGF0IG5vZGUgdG8gYSBudW1iZXIgdXNpbmcKLSAgICAgIC8vIHRoZSBudW1iZXIgZnVuY3Rpb24gaXMgdHJ1ZS4KLSAgICAgIERUTUl0ZXJhdG9yIGxpc3QxID0gaXRlclJhdygpOwotICAgICAgZG91YmxlIG51bTIgPSBvYmoyLm51bSgpOwotICAgICAgaW50IG5vZGU7Ci0KLSAgICAgIHdoaWxlIChEVE0uTlVMTCAhPSAobm9kZSA9IGxpc3QxLm5leHROb2RlKCkpKQotICAgICAgewotICAgICAgICBkb3VibGUgbnVtMSA9IGdldE51bWJlckZyb21Ob2RlKG5vZGUpOwotCi0gICAgICAgIGlmIChjb21wYXJhdG9yLmNvbXBhcmVOdW1iZXJzKG51bTEsIG51bTIpKQotICAgICAgICB7Ci0gICAgICAgICAgcmVzdWx0ID0gdHJ1ZTsKLQotICAgICAgICAgIGJyZWFrOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgICBsaXN0MS5yZXNldCgpOwotICAgIH0KLSAgICBlbHNlIGlmIChYT2JqZWN0LkNMQVNTX1JUUkVFRlJBRyA9PSB0eXBlKQotICAgIHsKLSAgICAgIFhNTFN0cmluZyBzMiA9IG9iajIueHN0cigpOwotICAgICAgRFRNSXRlcmF0b3IgbGlzdDEgPSBpdGVyUmF3KCk7Ci0gICAgICBpbnQgbm9kZTsKLQotICAgICAgd2hpbGUgKERUTS5OVUxMICE9IChub2RlID0gbGlzdDEubmV4dE5vZGUoKSkpCi0gICAgICB7Ci0gICAgICAgIFhNTFN0cmluZyBzMSA9IGdldFN0cmluZ0Zyb21Ob2RlKG5vZGUpOwotCi0gICAgICAgIGlmIChjb21wYXJhdG9yLmNvbXBhcmVTdHJpbmdzKHMxLCBzMikpCi0gICAgICAgIHsKLSAgICAgICAgICByZXN1bHQgPSB0cnVlOwotCi0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICAgIGxpc3QxLnJlc2V0KCk7Ci0gICAgfQotICAgIGVsc2UgaWYgKFhPYmplY3QuQ0xBU1NfU1RSSU5HID09IHR5cGUpCi0gICAgewotCi0gICAgICAvLyBGcm9tIGh0dHA6Ly93d3cudzMub3JnL1RSL3hwYXRoOgotICAgICAgLy8gSWYgb25lIG9iamVjdCB0byBiZSBjb21wYXJlZCBpcyBhIG5vZGUtc2V0IGFuZCB0aGUgb3RoZXIgaXMgYQotICAgICAgLy8gc3RyaW5nLCB0aGVuIHRoZSBjb21wYXJpc29uIHdpbGwgYmUgdHJ1ZSBpZiBhbmQgb25seSBpZiB0aGVyZQotICAgICAgLy8gaXMgYSBub2RlIGluIHRoZSBub2RlLXNldCBzdWNoIHRoYXQgdGhlIHJlc3VsdCBvZiBwZXJmb3JtaW5nCi0gICAgICAvLyB0aGUgY29tcGFyaXNvbiBvbiB0aGUgc3RyaW5nLXZhbHVlIG9mIHRoZSBub2RlIGFuZCB0aGUgb3RoZXIKLSAgICAgIC8vIHN0cmluZyBpcyB0cnVlLgotICAgICAgWE1MU3RyaW5nIHMyID0gb2JqMi54c3RyKCk7Ci0gICAgICBEVE1JdGVyYXRvciBsaXN0MSA9IGl0ZXJSYXcoKTsKLSAgICAgIGludCBub2RlOwotCi0gICAgICB3aGlsZSAoRFRNLk5VTEwgIT0gKG5vZGUgPSBsaXN0MS5uZXh0Tm9kZSgpKSkKLSAgICAgIHsKLSAgICAgICAgWE1MU3RyaW5nIHMxID0gZ2V0U3RyaW5nRnJvbU5vZGUobm9kZSk7Ci0gICAgICAgIGlmIChjb21wYXJhdG9yLmNvbXBhcmVTdHJpbmdzKHMxLCBzMikpCi0gICAgICAgIHsKLSAgICAgICAgICByZXN1bHQgPSB0cnVlOwotCi0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICAgIGxpc3QxLnJlc2V0KCk7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICByZXN1bHQgPSBjb21wYXJhdG9yLmNvbXBhcmVOdW1iZXJzKHRoaXMubnVtKCksIG9iajIubnVtKCkpOwotICAgIH0KLQotICAgIHJldHVybiByZXN1bHQ7Ci0gIH0KLQotICAvKioKLSAgICogVGVsbCBpZiBvbmUgb2JqZWN0IGlzIGxlc3MgdGhhbiB0aGUgb3RoZXIuCi0gICAqCi0gICAqIEBwYXJhbSBvYmoyIG9iamVjdCB0byBjb21wYXJlIHRoaXMgbm9kZXNldCB0bwotICAgKgotICAgKiBAcmV0dXJuIHNlZSB0aGlzLmNvbXBhcmUoLi4uKQotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGxlc3NUaGFuKFhPYmplY3Qgb2JqMikgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHJldHVybiBjb21wYXJlKG9iajIsIFNfTFQpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgb25lIG9iamVjdCBpcyBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gdGhlIG90aGVyLgotICAgKgotICAgKiBAcGFyYW0gb2JqMiBvYmplY3QgdG8gY29tcGFyZSB0aGlzIG5vZGVzZXQgdG8KLSAgICoKLSAgICogQHJldHVybiBzZWUgdGhpcy5jb21wYXJlKC4uLikKLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBsZXNzVGhhbk9yRXF1YWwoWE9iamVjdCBvYmoyKSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIGNvbXBhcmUob2JqMiwgU19MVEUpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgb25lIG9iamVjdCBpcyBsZXNzIHRoYW4gdGhlIG90aGVyLgotICAgKgotICAgKiBAcGFyYW0gb2JqMiBvYmplY3QgdG8gY29tcGFyZSB0aGlzIG5vZGVzZXQgdG8KLSAgICoKLSAgICogQHJldHVybiBzZWUgdGhpcy5jb21wYXJlKC4uLikKLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBncmVhdGVyVGhhbihYT2JqZWN0IG9iajIpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gY29tcGFyZShvYmoyLCBTX0dUKTsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIGlmIG9uZSBvYmplY3QgaXMgbGVzcyB0aGFuIHRoZSBvdGhlci4KLSAgICoKLSAgICogQHBhcmFtIG9iajIgb2JqZWN0IHRvIGNvbXBhcmUgdGhpcyBub2Rlc2V0IHRvCi0gICAqCi0gICAqIEByZXR1cm4gc2VlIHRoaXMuY29tcGFyZSguLi4pCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZ3JlYXRlclRoYW5PckVxdWFsKFhPYmplY3Qgb2JqMikKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIGNvbXBhcmUob2JqMiwgU19HVEUpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgdHdvIG9iamVjdHMgYXJlIGZ1bmN0aW9uYWxseSBlcXVhbC4KLSAgICoKLSAgICogQHBhcmFtIG9iajIgb2JqZWN0IHRvIGNvbXBhcmUgdGhpcyBub2Rlc2V0IHRvCi0gICAqCi0gICAqIEByZXR1cm4gc2VlIHRoaXMuY29tcGFyZSguLi4pCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZXF1YWxzKFhPYmplY3Qgb2JqMikKLSAgewotICAgIHRyeQotICAgIHsKLSAgICAgIHJldHVybiBjb21wYXJlKG9iajIsIFNfRVEpOwotICAgIH0KLSAgICBjYXRjaChqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uIHRlKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLldyYXBwZWRSdW50aW1lRXhjZXB0aW9uKHRlKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogVGVsbCBpZiB0d28gb2JqZWN0cyBhcmUgZnVuY3Rpb25hbGx5IG5vdCBlcXVhbC4KLSAgICoKLSAgICogQHBhcmFtIG9iajIgb2JqZWN0IHRvIGNvbXBhcmUgdGhpcyBub2Rlc2V0IHRvCi0gICAqCi0gICAqIEByZXR1cm4gc2VlIHRoaXMuY29tcGFyZSguLi4pCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gbm90RXF1YWxzKFhPYmplY3Qgb2JqMikgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHJldHVybiBjb21wYXJlKG9iajIsIFNfTkVRKTsKLSAgfQotfQotCi0vKioKLSAqIGNvbXBhcmVzIG5vZGVzIGZvciB2YXJpb3VzIGJvb2xlYW4gb3BlcmF0aW9ucy4KLSAqLwotYWJzdHJhY3QgY2xhc3MgQ29tcGFyYXRvcgotewotCi0gIC8qKgotICAgKiBDb21wYXJlIHR3byBzdHJpbmdzCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBzMSBGaXJzdCBzdHJpbmcgdG8gY29tcGFyZQotICAgKiBAcGFyYW0gczIgU2Vjb25kIFN0cmluZyB0byBjb21wYXJlCi0gICAqCi0gICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyaW5ncyBhcmUgZXF1YWwgb3Igbm90Ci0gICAqLwotICBhYnN0cmFjdCBib29sZWFuIGNvbXBhcmVTdHJpbmdzKFhNTFN0cmluZyBzMSwgWE1MU3RyaW5nIHMyKTsKLQotICAvKioKLSAgICogQ29tcGFyZSB0d28gbnVtYmVycwotICAgKgotICAgKgotICAgKiBAcGFyYW0gbjEgRmlyc3QgbnVtYmVyIHRvIGNvbXBhcmUKLSAgICogQHBhcmFtIG4yIFNlY29uZCBudW1iZXIgdG8gY29tcGFyZQotICAgKgotICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG51bWJlcnMgYXJlIGVxdWFsIG9yIG5vdAotICAgKi8KLSAgYWJzdHJhY3QgYm9vbGVhbiBjb21wYXJlTnVtYmVycyhkb3VibGUgbjEsIGRvdWJsZSBuMik7Ci19Ci0KLS8qKgotICogQ29tcGFyZSBzdHJpbmdzIG9yIG51bWJlcnMgZm9yIGxlc3MgdGhhbi4KLSAqLwotY2xhc3MgTGVzc1RoYW5Db21wYXJhdG9yIGV4dGVuZHMgQ29tcGFyYXRvcgotewotCi0gIC8qKgotICAgKiBDb21wYXJlIHR3byBzdHJpbmdzIGZvciBsZXNzIHRoYW4uCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBzMSBGaXJzdCBzdHJpbmcgdG8gY29tcGFyZQotICAgKiBAcGFyYW0gczIgU2Vjb25kIFN0cmluZyB0byBjb21wYXJlCi0gICAqCi0gICAqIEByZXR1cm4gVHJ1ZSBpZiBzMSBpcyBsZXNzIHRoYW4gczIKLSAgICovCi0gIGJvb2xlYW4gY29tcGFyZVN0cmluZ3MoWE1MU3RyaW5nIHMxLCBYTUxTdHJpbmcgczIpCi0gIHsKLSAgICByZXR1cm4gKHMxLnRvRG91YmxlKCkgPCBzMi50b0RvdWJsZSgpKTsKLSAgICAvLyByZXR1cm4gczEuY29tcGFyZVRvKHMyKSA8IDA7Ci0gIH0KLQotICAvKioKLSAgICogQ29tcGFyZSB0d28gbnVtYmVycyBmb3IgbGVzcyB0aGFuLgotICAgKgotICAgKgotICAgKiBAcGFyYW0gbjEgRmlyc3QgbnVtYmVyIHRvIGNvbXBhcmUKLSAgICogQHBhcmFtIG4yIFNlY29uZCBudW1iZXIgdG8gY29tcGFyZQotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYgbjEgaXMgbGVzcyB0aGFuIG4yCi0gICAqLwotICBib29sZWFuIGNvbXBhcmVOdW1iZXJzKGRvdWJsZSBuMSwgZG91YmxlIG4yKQotICB7Ci0gICAgcmV0dXJuIG4xIDwgbjI7Ci0gIH0KLX0KLQotLyoqCi0gKiBDb21wYXJlIHN0cmluZ3Mgb3IgbnVtYmVycyBmb3IgbGVzcyB0aGFuIG9yIGVxdWFsLgotICovCi1jbGFzcyBMZXNzVGhhbk9yRXF1YWxDb21wYXJhdG9yIGV4dGVuZHMgQ29tcGFyYXRvcgotewotCi0gIC8qKgotICAgKiBDb21wYXJlIHR3byBzdHJpbmdzIGZvciBsZXNzIHRoYW4gb3IgZXF1YWwuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBzMSBGaXJzdCBzdHJpbmcgdG8gY29tcGFyZQotICAgKiBAcGFyYW0gczIgU2Vjb25kIFN0cmluZyB0byBjb21wYXJlCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiBzMSBpcyBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gczIKLSAgICovCi0gIGJvb2xlYW4gY29tcGFyZVN0cmluZ3MoWE1MU3RyaW5nIHMxLCBYTUxTdHJpbmcgczIpCi0gIHsKLSAgICByZXR1cm4gKHMxLnRvRG91YmxlKCkgPD0gczIudG9Eb3VibGUoKSk7Ci0gICAgLy8gcmV0dXJuIHMxLmNvbXBhcmVUbyhzMikgPD0gMDsKLSAgfQotCi0gIC8qKgotICAgKiBDb21wYXJlIHR3byBudW1iZXJzIGZvciBsZXNzIHRoYW4gb3IgZXF1YWwuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBuMSBGaXJzdCBudW1iZXIgdG8gY29tcGFyZQotICAgKiBAcGFyYW0gbjIgU2Vjb25kIG51bWJlciB0byBjb21wYXJlCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiBuMSBpcyBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gbjIKLSAgICovCi0gIGJvb2xlYW4gY29tcGFyZU51bWJlcnMoZG91YmxlIG4xLCBkb3VibGUgbjIpCi0gIHsKLSAgICByZXR1cm4gbjEgPD0gbjI7Ci0gIH0KLX0KLQotLyoqCi0gKiBDb21wYXJlIHN0cmluZ3Mgb3IgbnVtYmVycyBmb3IgZ3JlYXRlciB0aGFuLgotICovCi1jbGFzcyBHcmVhdGVyVGhhbkNvbXBhcmF0b3IgZXh0ZW5kcyBDb21wYXJhdG9yCi17Ci0KLSAgLyoqCi0gICAqIENvbXBhcmUgdHdvIHN0cmluZ3MgZm9yIGdyZWF0ZXIgdGhhbi4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHMxIEZpcnN0IHN0cmluZyB0byBjb21wYXJlCi0gICAqIEBwYXJhbSBzMiBTZWNvbmQgU3RyaW5nIHRvIGNvbXBhcmUKLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHMxIGlzIGdyZWF0ZXIgdGhhbiBzMgotICAgKi8KLSAgYm9vbGVhbiBjb21wYXJlU3RyaW5ncyhYTUxTdHJpbmcgczEsIFhNTFN0cmluZyBzMikKLSAgewotICAgIHJldHVybiAoczEudG9Eb3VibGUoKSA+IHMyLnRvRG91YmxlKCkpOwotICAgIC8vIHJldHVybiBzMS5jb21wYXJlVG8oczIpID4gMDsKLSAgfQotCi0gIC8qKgotICAgKiBDb21wYXJlIHR3byBudW1iZXJzIGZvciBncmVhdGVyIHRoYW4uCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBuMSBGaXJzdCBudW1iZXIgdG8gY29tcGFyZQotICAgKiBAcGFyYW0gbjIgU2Vjb25kIG51bWJlciB0byBjb21wYXJlCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiBuMSBpcyBncmVhdGVyIHRoYW4gbjIKLSAgICovCi0gIGJvb2xlYW4gY29tcGFyZU51bWJlcnMoZG91YmxlIG4xLCBkb3VibGUgbjIpCi0gIHsKLSAgICByZXR1cm4gbjEgPiBuMjsKLSAgfQotfQotCi0vKioKLSAqIENvbXBhcmUgc3RyaW5ncyBvciBudW1iZXJzIGZvciBncmVhdGVyIHRoYW4gb3IgZXF1YWwuCi0gKi8KLWNsYXNzIEdyZWF0ZXJUaGFuT3JFcXVhbENvbXBhcmF0b3IgZXh0ZW5kcyBDb21wYXJhdG9yCi17Ci0KLSAgLyoqCi0gICAqIENvbXBhcmUgdHdvIHN0cmluZ3MgZm9yIGdyZWF0ZXIgdGhhbiBvciBlcXVhbC4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHMxIEZpcnN0IHN0cmluZyB0byBjb21wYXJlCi0gICAqIEBwYXJhbSBzMiBTZWNvbmQgU3RyaW5nIHRvIGNvbXBhcmUKLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHMxIGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byBzMgotICAgKi8KLSAgYm9vbGVhbiBjb21wYXJlU3RyaW5ncyhYTUxTdHJpbmcgczEsIFhNTFN0cmluZyBzMikKLSAgewotICAgIHJldHVybiAoczEudG9Eb3VibGUoKSA+PSBzMi50b0RvdWJsZSgpKTsKLSAgICAvLyByZXR1cm4gczEuY29tcGFyZVRvKHMyKSA+PSAwOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbXBhcmUgdHdvIG51bWJlcnMgZm9yIGdyZWF0ZXIgdGhhbiBvciBlcXVhbC4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIG4xIEZpcnN0IG51bWJlciB0byBjb21wYXJlCi0gICAqIEBwYXJhbSBuMiBTZWNvbmQgbnVtYmVyIHRvIGNvbXBhcmUKLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIG4xIGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byBuMgotICAgKi8KLSAgYm9vbGVhbiBjb21wYXJlTnVtYmVycyhkb3VibGUgbjEsIGRvdWJsZSBuMikKLSAgewotICAgIHJldHVybiBuMSA+PSBuMjsKLSAgfQotfQotCi0vKioKLSAqIENvbXBhcmUgc3RyaW5ncyBvciBudW1iZXJzIGZvciBlcXVhbGl0eS4KLSAqLwotY2xhc3MgRXF1YWxDb21wYXJhdG9yIGV4dGVuZHMgQ29tcGFyYXRvcgotewotCi0gIC8qKgotICAgKiBDb21wYXJlIHR3byBzdHJpbmdzIGZvciBlcXVhbGl0eS4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHMxIEZpcnN0IHN0cmluZyB0byBjb21wYXJlCi0gICAqIEBwYXJhbSBzMiBTZWNvbmQgU3RyaW5nIHRvIGNvbXBhcmUKLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHMxIGlzIGVxdWFsIHRvIHMyCi0gICAqLwotICBib29sZWFuIGNvbXBhcmVTdHJpbmdzKFhNTFN0cmluZyBzMSwgWE1MU3RyaW5nIHMyKQotICB7Ci0gICAgcmV0dXJuIHMxLmVxdWFscyhzMik7Ci0gIH0KLQotICAvKioKLSAgICogQ29tcGFyZSB0d28gbnVtYmVycyBmb3IgZXF1YWxpdHkuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBuMSBGaXJzdCBudW1iZXIgdG8gY29tcGFyZQotICAgKiBAcGFyYW0gbjIgU2Vjb25kIG51bWJlciB0byBjb21wYXJlCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiBuMSBpcyBlcXVhbCB0byBuMgotICAgKi8KLSAgYm9vbGVhbiBjb21wYXJlTnVtYmVycyhkb3VibGUgbjEsIGRvdWJsZSBuMikKLSAgewotICAgIHJldHVybiBuMSA9PSBuMjsKLSAgfQotfQotCi0vKioKLSAqIENvbXBhcmUgc3RyaW5ncyBvciBudW1iZXJzIGZvciBub24tZXF1YWxpdHkuCi0gKi8KLWNsYXNzIE5vdEVxdWFsQ29tcGFyYXRvciBleHRlbmRzIENvbXBhcmF0b3IKLXsKLQotICAvKioKLSAgICogQ29tcGFyZSB0d28gc3RyaW5ncyBmb3Igbm9uLWVxdWFsaXR5LgotICAgKgotICAgKgotICAgKiBAcGFyYW0gczEgRmlyc3Qgc3RyaW5nIHRvIGNvbXBhcmUKLSAgICogQHBhcmFtIHMyIFNlY29uZCBTdHJpbmcgdG8gY29tcGFyZQotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYgczEgaXMgbm90IGVxdWFsIHRvIHMyCi0gICAqLwotICBib29sZWFuIGNvbXBhcmVTdHJpbmdzKFhNTFN0cmluZyBzMSwgWE1MU3RyaW5nIHMyKQotICB7Ci0gICAgcmV0dXJuICFzMS5lcXVhbHMoczIpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbXBhcmUgdHdvIG51bWJlcnMgZm9yIG5vbi1lcXVhbGl0eS4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIG4xIEZpcnN0IG51bWJlciB0byBjb21wYXJlCi0gICAqIEBwYXJhbSBuMiBTZWNvbmQgbnVtYmVyIHRvIGNvbXBhcmUKLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIG4xIGlzIG5vdCBlcXVhbCB0byBuMgotICAgKi8KLSAgYm9vbGVhbiBjb21wYXJlTnVtYmVycyhkb3VibGUgbjEsIGRvdWJsZSBuMikKLSAgewotICAgIHJldHVybiBuMSAhPSBuMjsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9vYmplY3RzL1hOb2RlU2V0Rm9yRE9NLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL29iamVjdHMvWE5vZGVTZXRGb3JET00uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYzdhYWM0My4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL29iamVjdHMvWE5vZGVTZXRGb3JET00uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEzMCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBYTm9kZVNldEZvckRPTS5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE0IDIwOjM0OjQ2IGplZmZzdXR0b3IgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0czsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTU1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLk5vZGVTZXREVE07Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoQ29udGV4dDsKLQotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZUxpc3Q7Ci1pbXBvcnQgb3JnLnczYy5kb20udHJhdmVyc2FsLk5vZGVJdGVyYXRvcjsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIG92ZXJyaWRlcyB0aGUgWE5vZGVTZXQjb2JqZWN0KCkgbWV0aG9kIHRvIHByb3ZpZGUgdGhlIG9yaWdpbmFsCi0gKiBOb2RlIG9iamVjdCwgTm9kZUxpc3Qgb2JqZWN0LCBvciBOb2RlSXRlcmF0b3IuCi0gKi8KLXB1YmxpYyBjbGFzcyBYTm9kZVNldEZvckRPTSBleHRlbmRzIFhOb2RlU2V0Ci17Ci0gICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC04Mzk2MTkwNzEzNzU0NjI0NjQwTDsKLSAgT2JqZWN0IG1fb3JpZ09iajsKLQotICBwdWJsaWMgWE5vZGVTZXRGb3JET00oTm9kZSBub2RlLCBEVE1NYW5hZ2VyIGR0bU1ncikKLSAgewotICAgIG1fZHRtTWdyID0gZHRtTWdyOwotICAgIG1fb3JpZ09iaiA9IG5vZGU7Ci0gICAgaW50IGR0bUhhbmRsZSA9IGR0bU1nci5nZXREVE1IYW5kbGVGcm9tTm9kZShub2RlKTsKLSAgICBzZXRPYmplY3QobmV3IE5vZGVTZXREVE0oZHRtTWdyKSk7Ci0gICAgKChOb2RlU2V0RFRNKSBtX29iaikuYWRkTm9kZShkdG1IYW5kbGUpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhIFhOb2RlU2V0IG9iamVjdC4KLSAgICoKLSAgICogQHBhcmFtIHZhbCBWYWx1ZSBvZiB0aGUgWE5vZGVTZXQgb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgWE5vZGVTZXRGb3JET00oWE5vZGVTZXQgdmFsKQotICB7Ci0gICAgICAgIHN1cGVyKHZhbCk7Ci0gICAgICAgIGlmKHZhbCBpbnN0YW5jZW9mIFhOb2RlU2V0Rm9yRE9NKQotICAgICAgICBtX29yaWdPYmogPSAoKFhOb2RlU2V0Rm9yRE9NKXZhbCkubV9vcmlnT2JqOwotICB9Ci0KLSAgcHVibGljIFhOb2RlU2V0Rm9yRE9NKE5vZGVMaXN0IG5vZGVMaXN0LCBYUGF0aENvbnRleHQgeGN0eHQpCi0gIHsKLSAgICBtX2R0bU1nciA9IHhjdHh0LmdldERUTU1hbmFnZXIoKTsKLSAgICBtX29yaWdPYmogPSBub2RlTGlzdDsKLQotICAgIC8vIEpLRVNTIDIwMDIwNTE0OiBMb25nZXItdGVybSBzb2x1dGlvbiBpcyB0byBmb3JjZQotICAgIC8vIGZvbGtzIHRvIHJlcXVlc3QgbGVuZ3RoIHRocm91Z2ggYW4gYWNjZXNzb3IsIHNvIHdlIGNhbiBkZWZlciB0aGlzCi0gICAgLy8gcmV0cmlldmFsLi4uIGJ1dCB0aGF0IHJlcXVpcmVzIGFuIEFQSSBjaGFuZ2UuCi0gICAgLy8gbV9vYmo9bmV3IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5Ob2RlU2V0RFRNKG5vZGVMaXN0LCB4Y3R4dCk7Ci0gICAgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLk5vZGVTZXREVE0gbnNkdG09bmV3IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5Ob2RlU2V0RFRNKG5vZGVMaXN0LCB4Y3R4dCk7Ci0gICAgbV9sYXN0PW5zZHRtLmdldExlbmd0aCgpOwotICAgIHNldE9iamVjdChuc2R0bSk7Ci0gIH0KLQotICBwdWJsaWMgWE5vZGVTZXRGb3JET00oTm9kZUl0ZXJhdG9yIG5vZGVJdGVyLCBYUGF0aENvbnRleHQgeGN0eHQpCi0gIHsKLSAgICBtX2R0bU1nciA9IHhjdHh0LmdldERUTU1hbmFnZXIoKTsKLSAgICBtX29yaWdPYmogPSBub2RlSXRlcjsKLQotICAgIC8vIEpLRVNTIDIwMDIwNTE0OiBMb25nZXItdGVybSBzb2x1dGlvbiBpcyB0byBmb3JjZQotICAgIC8vIGZvbGtzIHRvIHJlcXVlc3QgbGVuZ3RoIHRocm91Z2ggYW4gYWNjZXNzb3IsIHNvIHdlIGNhbiBkZWZlciB0aGlzCi0gICAgLy8gcmV0cmlldmFsLi4uIGJ1dCB0aGF0IHJlcXVpcmVzIGFuIEFQSSBjaGFuZ2UuCi0gICAgLy8gbV9vYmogPSBuZXcgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLk5vZGVTZXREVE0obm9kZUl0ZXIsIHhjdHh0KTsKLSAgICBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuTm9kZVNldERUTSBuc2R0bT1uZXcgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLk5vZGVTZXREVE0obm9kZUl0ZXIsIHhjdHh0KTsKLSAgICBtX2xhc3Q9bnNkdG0uZ2V0TGVuZ3RoKCk7Ci0gICAgc2V0T2JqZWN0KG5zZHRtKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIG9yaWdpbmFsIERPTSBvYmplY3QgdGhhdCB0aGUgdXNlciBwYXNzZWQgaW4uICBGb3IgdXNlIHByaW1hcmlseQotICAgKiBieSB0aGUgZXh0ZW5zaW9uIG1lY2hhbmlzbS4KLSAgICoKLSAgICogQHJldHVybiBUaGUgb2JqZWN0IHRoYXQgdGhpcyBjbGFzcyB3cmFwcwotICAgKi8KLSAgcHVibGljIE9iamVjdCBvYmplY3QoKQotICB7Ci0gICAgcmV0dXJuIG1fb3JpZ09iajsKLSAgfQotCi0gIC8qKgotICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYSBub2RlbGlzdC4gQWx3YXlzIGlzc3VlcyBhbiBlcnJvci4KLSAgICoKLSAgICogQHJldHVybiBudWxsCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIE5vZGVJdGVyYXRvciBub2Rlc2V0KCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHJldHVybiAobV9vcmlnT2JqIGluc3RhbmNlb2YgTm9kZUl0ZXJhdG9yKQotICAgICAgICAgICAgICAgICAgID8gKE5vZGVJdGVyYXRvciltX29yaWdPYmogOiBzdXBlci5ub2Rlc2V0KCk7Ci0gIH0KLQotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGEgbm9kZWxpc3QuIEFsd2F5cyBpc3N1ZXMgYW4gZXJyb3IuCi0gICAqCi0gICAqIEByZXR1cm4gbnVsbAotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBOb2RlTGlzdCBub2RlbGlzdCgpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gKG1fb3JpZ09iaiBpbnN0YW5jZW9mIE5vZGVMaXN0KQotICAgICAgICAgICAgICAgICAgID8gKE5vZGVMaXN0KW1fb3JpZ09iaiA6IHN1cGVyLm5vZGVsaXN0KCk7Ci0gIH0KLQotCi0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvb2JqZWN0cy9YTnVsbC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9vYmplY3RzL1hOdWxsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDNiOTEzODcuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9vYmplY3RzL1hOdWxsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMzIgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogWE51bGwuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNCAyMDozNDo0NiBqZWZmc3V0dG9yIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE07Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoQ29udGV4dDsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIHJlcHJlc2VudHMgYW4gWFBhdGggbnVsbCBvYmplY3QsIGFuZCBpcyBjYXBhYmxlIG9mCi0gKiBjb252ZXJ0aW5nIHRoZSBudWxsIHRvIG90aGVyIHR5cGVzLCBzdWNoIGFzIGEgc3RyaW5nLgotICogQHhzbC51c2FnZSBnZW5lcmFsCi0gKi8KLXB1YmxpYyBjbGFzcyBYTnVsbCBleHRlbmRzIFhOb2RlU2V0Ci17Ci0gICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC02ODQxNjgzNzExNDU4OTgzMDA1TDsKLQotICAvKioKLSAgICogQ3JlYXRlIGFuIFhPYmplY3QuCi0gICAqLwotICBwdWJsaWMgWE51bGwoKQotICB7Ci0gICAgc3VwZXIoKTsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIHdoYXQga2luZCBvZiBjbGFzcyB0aGlzIGlzLgotICAgKgotICAgKiBAcmV0dXJuIHR5cGUgQ0xBU1NfTlVMTAotICAgKi8KLSAgcHVibGljIGludCBnZXRUeXBlKCkKLSAgewotICAgIHJldHVybiBDTEFTU19OVUxMOwotICB9Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgcmVxdWVzdCB0eXBlLCByZXR1cm4gdGhlIGVxdWl2YWxlbnQgc3RyaW5nLgotICAgKiBGb3IgZGlhZ25vc3RpYyBwdXJwb3Nlcy4KLSAgICoKLSAgICogQHJldHVybiB0eXBlIHN0cmluZyAiI0NMQVNTX05VTEwiCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFR5cGVTdHJpbmcoKQotICB7Ci0gICAgcmV0dXJuICIjQ0xBU1NfTlVMTCI7Ci0gIH0KLQotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGEgbnVtYmVyLgotICAgKgotICAgKiBAcmV0dXJuIDAuMAotICAgKi8KLQotICBwdWJsaWMgZG91YmxlIG51bSgpCi0gIHsKLSAgICByZXR1cm4gMC4wOwotICB9Ci0KLSAgLyoqCi0gICAqIENhc3QgcmVzdWx0IG9iamVjdCB0byBhIGJvb2xlYW4uCi0gICAqCi0gICAqIEByZXR1cm4gZmFsc2UKLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGJvb2woKQotICB7Ci0gICAgcmV0dXJuIGZhbHNlOwotICB9Ci0KLSAgLyoqCi0gICAqIENhc3QgcmVzdWx0IG9iamVjdCB0byBhIHN0cmluZy4KLSAgICoKLSAgICogQHJldHVybiBlbXB0eSBzdHJpbmcgIiIKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgc3RyKCkKLSAgewotICAgIHJldHVybiAiIjsKLSAgfQotCi0gIC8qKgotICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYSByZXN1bHQgdHJlZSBmcmFnbWVudC4KLSAgICoKLSAgICogQHBhcmFtIHN1cHBvcnQgWFBhdGggY29udGV4dCB0byB1c2UgZm9yIHRoZSBjb252ZXJzaW9uCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIG9iamVjdCBhcyBhIHJlc3VsdCB0cmVlIGZyYWdtZW50LgotICAgKi8KLSAgcHVibGljIGludCBydGYoWFBhdGhDb250ZXh0IHN1cHBvcnQpCi0gIHsKLSAgICAvLyBEVE0gZnJhZyA9IHN1cHBvcnQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpOwotICAgIC8vICVSRVZJRVclCi0gICAgcmV0dXJuIERUTS5OVUxMOwotICB9Ci0KLS8vICAvKioKLS8vICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYSBub2RlbGlzdC4KLS8vICAgKgotLy8gICAqIEByZXR1cm4gbnVsbAotLy8gICAqLwotLy8gIHB1YmxpYyBEVE1JdGVyYXRvciBpdGVyKCkKLS8vICB7Ci0vLyAgICByZXR1cm4gbnVsbDsKLS8vICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgdHdvIG9iamVjdHMgYXJlIGZ1bmN0aW9uYWxseSBlcXVhbC4KLSAgICoKLSAgICogQHBhcmFtIG9iajIgT2JqZWN0IHRvIGNvbXBhcmUgdGhpcyB0bwotICAgKgotICAgKiBAcmV0dXJuIFRydWUgaWYgdGhlIGdpdmVuIG9iamVjdCBpcyBvZiB0eXBlIENMQVNTX05VTEwKLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGVxdWFscyhYT2JqZWN0IG9iajIpCi0gIHsKLSAgICByZXR1cm4gb2JqMi5nZXRUeXBlKCkgPT0gQ0xBU1NfTlVMTDsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9vYmplY3RzL1hOdW1iZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvb2JqZWN0cy9YTnVtYmVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDViNmM2ZjIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9vYmplY3RzL1hOdW1iZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQzOSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBYTnVtYmVyLmphdmEsdiAxLjIuNC4yIDIwMDUvMDkvMTQgMjA6MzQ6NDYgamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLkV4cHJlc3Npb25Pd25lcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuWFBhdGhDb250ZXh0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5YUGF0aFZpc2l0b3I7Ci0KLS8qKgotICogVGhpcyBjbGFzcyByZXByZXNlbnRzIGFuIFhQYXRoIG51bWJlciwgYW5kIGlzIGNhcGFibGUgb2YKLSAqIGNvbnZlcnRpbmcgdGhlIG51bWJlciB0byBvdGhlciB0eXBlcywgc3VjaCBhcyBhIHN0cmluZy4KLSAqIEB4c2wudXNhZ2UgZ2VuZXJhbAotICovCi1wdWJsaWMgY2xhc3MgWE51bWJlciBleHRlbmRzIFhPYmplY3QKLXsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTI3MjA0MDA3MDk2MTkwMjAxOTNMOwotCi0gIC8qKiBWYWx1ZSBvZiB0aGUgWE51bWJlciBvYmplY3QuCi0gICAqICBAc2VyaWFsICAgICAgICAgKi8KLSAgZG91YmxlIG1fdmFsOwotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBYTm9kZVNldCBvYmplY3QuCi0gICAqCi0gICAqIEBwYXJhbSBkIFZhbHVlIG9mIHRoZSBvYmplY3QKLSAgICovCi0gIHB1YmxpYyBYTnVtYmVyKGRvdWJsZSBkKQotICB7Ci0gICAgc3VwZXIoKTsKLQotICAgIG1fdmFsID0gZDsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBYTm9kZVNldCBvYmplY3QuCi0gICAqCi0gICAqIEBwYXJhbSBudW0gVmFsdWUgb2YgdGhlIG9iamVjdAotICAgKi8KLSAgcHVibGljIFhOdW1iZXIoTnVtYmVyIG51bSkKLSAgewotCi0gICAgc3VwZXIoKTsKLQotICAgIG1fdmFsID0gbnVtLmRvdWJsZVZhbHVlKCk7Ci0gICAgc2V0T2JqZWN0KG51bSk7Ci0gIH0KLQotICAvKioKLSAgICogVGVsbCB0aGF0IHRoaXMgaXMgYSBDTEFTU19OVU1CRVIuCi0gICAqCi0gICAqIEByZXR1cm4gbm9kZSB0eXBlIENMQVNTX05VTUJFUgotICAgKi8KLSAgcHVibGljIGludCBnZXRUeXBlKCkKLSAgewotICAgIHJldHVybiBDTEFTU19OVU1CRVI7Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYSByZXF1ZXN0IHR5cGUsIHJldHVybiB0aGUgZXF1aXZhbGVudCBzdHJpbmcuCi0gICAqIEZvciBkaWFnbm9zdGljIHB1cnBvc2VzLgotICAgKgotICAgKiBAcmV0dXJuIHR5cGUgc3RyaW5nICIjTlVNQkVSIgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRUeXBlU3RyaW5nKCkKLSAgewotICAgIHJldHVybiAiI05VTUJFUiI7Ci0gIH0KLQotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGEgbnVtYmVyLgotICAgKgotICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgWE51bWJlciBvYmplY3QKLSAgICovCi0gIHB1YmxpYyBkb3VibGUgbnVtKCkKLSAgewotICAgIHJldHVybiBtX3ZhbDsKLSAgfQotCi0gIC8qKgotICAgKiBFdmFsdWF0ZSBleHByZXNzaW9uIHRvIGEgbnVtYmVyLgotICAgKgotICAgKiBAcmV0dXJuIDAuMAotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBkb3VibGUgbnVtKFhQYXRoQ29udGV4dCB4Y3R4dCkKLSAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICByZXR1cm4gbV92YWw7Ci0gIH0KLQotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGEgYm9vbGVhbi4KLSAgICoKLSAgICogQHJldHVybiBmYWxzZSBpZiB0aGUgdmFsdWUgaXMgTmFOIG9yIGVxdWFsIHRvIDAuMAotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gYm9vbCgpCi0gIHsKLSAgICByZXR1cm4gKERvdWJsZS5pc05hTihtX3ZhbCkgfHwgKG1fdmFsID09IDAuMCkpID8gZmFsc2UgOiB0cnVlOwotICB9Ci0KLS8vICAvKioKLS8vICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYSBzdHJpbmcuCi0vLyAgICoKLS8vICAgKiBAcmV0dXJuICJOYU4iIGlmIHRoZSBudW1iZXIgaXMgTmFOLCBJbmZpbml0eSBvciAtSW5maW5pdHkgaWYKLS8vICAgKiB0aGUgbnVtYmVyIGlzIGluZmluaXRlIG9yIHRoZSBzdHJpbmcgdmFsdWUgb2YgdGhlIG51bWJlci4KLS8vICAgKi8KLS8vICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgUFJFQ0lTSU9OID0gMTY7Ci0vLyAgcHVibGljIFN0cmluZyBzdHIoKQotLy8gIHsKLS8vCi0vLyAgICBpZiAoRG91YmxlLmlzTmFOKG1fdmFsKSkKLS8vICAgIHsKLS8vICAgICAgcmV0dXJuICJOYU4iOwotLy8gICAgfQotLy8gICAgZWxzZSBpZiAoRG91YmxlLmlzSW5maW5pdGUobV92YWwpKQotLy8gICAgewotLy8gICAgICBpZiAobV92YWwgPiAwKQotLy8gICAgICAgIHJldHVybiAiSW5maW5pdHkiOwotLy8gICAgICBlbHNlCi0vLyAgICAgICAgcmV0dXJuICItSW5maW5pdHkiOwotLy8gICAgfQotLy8KLS8vICAgIGxvbmcgbG9uZ1ZhbCA9IChsb25nKW1fdmFsOwotLy8gICAgaWYgKChkb3VibGUpbG9uZ1ZhbCA9PSBtX3ZhbCkKLS8vICAgICAgcmV0dXJuIExvbmcudG9TdHJpbmcobG9uZ1ZhbCk7Ci0vLwotLy8KLS8vICAgIFN0cmluZyBzID0gRG91YmxlLnRvU3RyaW5nKG1fdmFsKTsKLS8vICAgIGludCBsZW4gPSBzLmxlbmd0aCgpOwotLy8KLS8vICAgIGlmIChzLmNoYXJBdChsZW4gLSAyKSA9PSAnLicgJiYgcy5jaGFyQXQobGVuIC0gMSkgPT0gJzAnKQotLy8gICAgewotLy8gICAgICByZXR1cm4gcy5zdWJzdHJpbmcoMCwgbGVuIC0gMik7Ci0vLyAgICB9Ci0vLwotLy8gICAgaW50IGV4cCA9IDA7Ci0vLyAgICBpbnQgZSA9IHMuaW5kZXhPZignRScpOwotLy8gICAgaWYgKGUgIT0gLTEpCi0vLyAgICB7Ci0vLyAgICAgIGV4cCA9IEludGVnZXIucGFyc2VJbnQocy5zdWJzdHJpbmcoZSArIDEpKTsKLS8vICAgICAgcyA9IHMuc3Vic3RyaW5nKDAsZSk7Ci0vLyAgICAgIGxlbiA9IGU7Ci0vLyAgICB9Ci0vLwotLy8gICAgLy8gQ2FsY3VsYXRlIFNpZ25pZmljYW50IERpZ2l0czoKLS8vICAgIC8vIGxvb2sgZnJvbSBzdGFydCBvZiBzdHJpbmcgZm9yIGZpcnN0IGRpZ2l0Ci0vLyAgICAvLyBsb29rIGZyb20gZW5kIGZvciBsYXN0IGRpZ2l0Ci0vLyAgICAvLyBzaWduaWZpY2FudCBkaWdpdHMgPSBlbmQgLSBzdGFydCArICgwIG9yIDEgZGVwZW5kaW5nIG9uIGRlY2ltYWwgbG9jYXRpb24pCi0vLwotLy8gICAgaW50IGRlY2ltYWxQb3MgPSAtMTsKLS8vICAgIGludCBzdGFydCA9IChzLmNoYXJBdCgwKSA9PSAnLScpID8gMSA6IDA7Ci0vLyAgICBmaW5kU3RhcnQ6IGZvciggOyBzdGFydCA8IGxlbjsgc3RhcnQrKyApCi0vLyAgICB7Ci0vLyAgICAgIHN3aXRjaCAocy5jaGFyQXQoc3RhcnQpKQotLy8gICAgICB7Ci0vLyAgICAgIGNhc2UgJzAnOgotLy8gICAgICAgIGJyZWFrOwotLy8gICAgICBjYXNlICcuJzoKLS8vICAgICAgICBkZWNpbWFsUG9zID0gc3RhcnQ7Ci0vLyAgICAgICAgYnJlYWs7Ci0vLyAgICAgIGRlZmF1bHQ6Ci0vLyAgICAgICAgYnJlYWsgZmluZFN0YXJ0OwotLy8gICAgICB9Ci0vLyAgICB9Ci0vLyAgICBpbnQgZW5kID0gcy5sZW5ndGgoKSAtIDE7Ci0vLyAgICBmaW5kRW5kOiBmb3IoIDsgZW5kID4gc3RhcnQ7IGVuZC0tICkKLS8vICAgIHsKLS8vICAgICAgc3dpdGNoIChzLmNoYXJBdChlbmQpKQotLy8gICAgICB7Ci0vLyAgICAgIGNhc2UgJzAnOgotLy8gICAgICAgIGJyZWFrOwotLy8gICAgICBjYXNlICcuJzoKLS8vICAgICAgICBkZWNpbWFsUG9zID0gZW5kOwotLy8gICAgICAgIGJyZWFrOwotLy8gICAgICBkZWZhdWx0OgotLy8gICAgICAgIGJyZWFrIGZpbmRFbmQ7Ci0vLyAgICAgIH0KLS8vICAgIH0KLS8vCi0vLyAgICBpbnQgc2lnRGlnID0gZW5kIC0gc3RhcnQ7Ci0vLwotLy8gICAgLy8gY2xhcmlmeSBkZWNpbWFsIGxvY2F0aW9uIGlmIGl0IGhhcyBub3QgeWV0IGJlZW4gZm91bmQKLS8vICAgIGlmIChkZWNpbWFsUG9zID09IC0xKQotLy8gICAgICBkZWNpbWFsUG9zID0gcy5pbmRleE9mKCcuJyk7Ci0vLwotLy8gICAgLy8gaWYgZGVjaW1hbCBpcyBub3QgYmV0d2VlbiBzdGFydCBhbmQgZW5kLCBhZGQgb25lIHRvIHNpZ0RpZwotLy8gICAgaWYgKGRlY2ltYWxQb3MgPCBzdGFydCB8fCBkZWNpbWFsUG9zID4gZW5kKQotLy8gICAgICArK3NpZ0RpZzsKLS8vCi0vLyAgICAvLyByZWR1Y2Ugc2lnbmlmaWNhbnQgZGlnaXRzIHRvIFBSRUNJU0lPTiBpZiBuZWNlc3NhcnkKLS8vICAgIGlmIChzaWdEaWcgPiBQUkVDSVNJT04pCi0vLyAgICB7Ci0vLyAgICAgIC8vIHJlLXNjYWxlIEJpZ0RlY2ltYWwgaW4gb3JkZXIgdG8gZ2V0IHNpZ25pZmljYW50IGRpZ2l0cyA9IFBSRUNJU0lPTgotLy8gICAgICBCaWdEZWNpbWFsIG51bSA9IG5ldyBCaWdEZWNpbWFsKHMpOwotLy8gICAgICBpbnQgbmV3U2NhbGUgPSBudW0uc2NhbGUoKSAtIChzaWdEaWcgLSBQUkVDSVNJT04pOwotLy8gICAgICBpZiAobmV3U2NhbGUgPCAwKQotLy8gICAgICAgIG5ld1NjYWxlID0gMDsKLS8vICAgICAgcyA9IG51bS5zZXRTY2FsZShuZXdTY2FsZSwgQmlnRGVjaW1hbC5ST1VORF9IQUxGX1VQKS50b1N0cmluZygpOwotLy8KLS8vICAgICAgLy8gcmVtb3ZlIHRyYWlsaW5nICcwJ3M7IGtlZXAgdHJhY2sgb2YgZGVjaW1hbFBvcwotLy8gICAgICBpbnQgdHJ1bmNhdGVQb2ludCA9IHMubGVuZ3RoKCk7Ci0vLyAgICAgIHdoaWxlIChzLmNoYXJBdCgtLXRydW5jYXRlUG9pbnQpID09ICcwJykKLS8vICAgICAgICA7Ci0vLwotLy8gICAgICBpZiAocy5jaGFyQXQodHJ1bmNhdGVQb2ludCkgPT0gJy4nKQotLy8gICAgICB7Ci0vLyAgICAgICAgZGVjaW1hbFBvcyA9IHRydW5jYXRlUG9pbnQ7Ci0vLyAgICAgIH0KLS8vICAgICAgZWxzZQotLy8gICAgICB7Ci0vLyAgICAgICAgZGVjaW1hbFBvcyA9IHMuaW5kZXhPZignLicpOwotLy8gICAgICAgIHRydW5jYXRlUG9pbnQgKz0gMTsKLS8vICAgICAgfQotLy8KLS8vICAgICAgcyA9IHMuc3Vic3RyaW5nKDAsIHRydW5jYXRlUG9pbnQpOwotLy8gICAgICBsZW4gPSBzLmxlbmd0aCgpOwotLy8gICAgfQotLy8KLS8vICAgIC8vIEFjY291bnQgZm9yIGV4cG9uZW50IGJ5IGFkZGluZyB6ZXJvcyBhcyBuZWVkZWQKLS8vICAgIC8vIGFuZCBtb3ZpbmcgdGhlIGRlY2ltYWwgcGxhY2UKLS8vCi0vLyAgICBpZiAoZXhwID09IDApCi0vLyAgICAgICByZXR1cm4gczsKLS8vCi0vLyAgICBzdGFydCA9IDA7Ci0vLyAgICBTdHJpbmcgc2lnbjsKLS8vICAgIGlmIChzLmNoYXJBdCgwKSA9PSAnLScpCi0vLyAgICB7Ci0vLyAgICAgIHNpZ24gPSAiLSI7Ci0vLyAgICAgIHN0YXJ0Kys7Ci0vLyAgICB9Ci0vLyAgICBlbHNlCi0vLyAgICAgIHNpZ24gPSAiIjsKLS8vCi0vLyAgICBTdHJpbmcgd2hvbGVQYXJ0ID0gcy5zdWJzdHJpbmcoc3RhcnQsIGRlY2ltYWxQb3MpOwotLy8gICAgU3RyaW5nIGRlY2ltYWxQYXJ0ID0gcy5zdWJzdHJpbmcoZGVjaW1hbFBvcyArIDEpOwotLy8KLS8vICAgIC8vIGdldCB0aGUgbnVtYmVyIG9mIGRpZ2l0cyByaWdodCBvZiB0aGUgZGVjaW1hbAotLy8gICAgaW50IGRlY2ltYWxMZW4gPSBkZWNpbWFsUGFydC5sZW5ndGgoKTsKLS8vCi0vLyAgICBpZiAoZXhwID49IGRlY2ltYWxMZW4pCi0vLyAgICAgIHJldHVybiBzaWduICsgd2hvbGVQYXJ0ICsgZGVjaW1hbFBhcnQgKyB6ZXJvcyhleHAgLSBkZWNpbWFsTGVuKTsKLS8vCi0vLyAgICBpZiAoZXhwID4gMCkKLS8vICAgICAgcmV0dXJuIHNpZ24gKyB3aG9sZVBhcnQgKyBkZWNpbWFsUGFydC5zdWJzdHJpbmcoMCwgZXhwKSArICIuIgotLy8gICAgICAgICAgICAgKyBkZWNpbWFsUGFydC5zdWJzdHJpbmcoZXhwKTsKLS8vCi0vLyAgICByZXR1cm4gc2lnbiArICIwLiIgKyB6ZXJvcygtMSAtIGV4cCkgKyB3aG9sZVBhcnQgKyBkZWNpbWFsUGFydDsKLS8vICB9Ci0KLSAgLyoqCi0gICAqIENhc3QgcmVzdWx0IG9iamVjdCB0byBhIHN0cmluZy4KLSAgICoKLSAgICogQHJldHVybiAiTmFOIiBpZiB0aGUgbnVtYmVyIGlzIE5hTiwgSW5maW5pdHkgb3IgLUluZmluaXR5IGlmCi0gICAqIHRoZSBudW1iZXIgaXMgaW5maW5pdGUgb3IgdGhlIHN0cmluZyB2YWx1ZSBvZiB0aGUgbnVtYmVyLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBzdHIoKQotICB7Ci0KLSAgICBpZiAoRG91YmxlLmlzTmFOKG1fdmFsKSkKLSAgICB7Ci0gICAgICByZXR1cm4gIk5hTiI7Ci0gICAgfQotICAgIGVsc2UgaWYgKERvdWJsZS5pc0luZmluaXRlKG1fdmFsKSkKLSAgICB7Ci0gICAgICBpZiAobV92YWwgPiAwKQotICAgICAgICByZXR1cm4gIkluZmluaXR5IjsKLSAgICAgIGVsc2UKLSAgICAgICAgcmV0dXJuICItSW5maW5pdHkiOwotICAgIH0KLQotICAgIGRvdWJsZSBudW0gPSBtX3ZhbDsKLSAgICBTdHJpbmcgcyA9IERvdWJsZS50b1N0cmluZyhudW0pOwotICAgIGludCBsZW4gPSBzLmxlbmd0aCgpOwotCi0gICAgaWYgKHMuY2hhckF0KGxlbiAtIDIpID09ICcuJyAmJiBzLmNoYXJBdChsZW4gLSAxKSA9PSAnMCcpCi0gICAgewotICAgICAgcyA9IHMuc3Vic3RyaW5nKDAsIGxlbiAtIDIpOwotCi0gICAgICBpZiAocy5lcXVhbHMoIi0wIikpCi0gICAgICAgIHJldHVybiAiMCI7Ci0KLSAgICAgIHJldHVybiBzOwotICAgIH0KLQotICAgIGludCBlID0gcy5pbmRleE9mKCdFJyk7Ci0KLSAgICBpZiAoZSA8IDApCi0gICAgewotICAgICAgaWYgKHMuY2hhckF0KGxlbiAtIDEpID09ICcwJykKLSAgICAgICAgcmV0dXJuIHMuc3Vic3RyaW5nKDAsIGxlbiAtIDEpOwotICAgICAgZWxzZQotICAgICAgICByZXR1cm4gczsKLSAgICB9Ci0KLSAgICBpbnQgZXhwID0gSW50ZWdlci5wYXJzZUludChzLnN1YnN0cmluZyhlICsgMSkpOwotICAgIFN0cmluZyBzaWduOwotCi0gICAgaWYgKHMuY2hhckF0KDApID09ICctJykKLSAgICB7Ci0gICAgICBzaWduID0gIi0iOwotICAgICAgcyA9IHMuc3Vic3RyaW5nKDEpOwotCi0gICAgICAtLWU7Ci0gICAgfQotICAgIGVsc2UKLSAgICAgIHNpZ24gPSAiIjsKLQotICAgIGludCBuRGlnaXRzID0gZSAtIDI7Ci0KLSAgICBpZiAoZXhwID49IG5EaWdpdHMpCi0gICAgICByZXR1cm4gc2lnbiArIHMuc3Vic3RyaW5nKDAsIDEpICsgcy5zdWJzdHJpbmcoMiwgZSkKLSAgICAgICAgICAgICArIHplcm9zKGV4cCAtIG5EaWdpdHMpOwotCi0gICAgLy8gRWxpbWluYXRlIHRyYWlsaW5nIDAncyAtIGJ1Z3ppbGxhIDE0MjQxCi0gICAgd2hpbGUgKHMuY2hhckF0KGUtMSkgPT0gJzAnKQotICAgICAgZS0tOwotCi0gICAgaWYgKGV4cCA+IDApCi0gICAgICByZXR1cm4gc2lnbiArIHMuc3Vic3RyaW5nKDAsIDEpICsgcy5zdWJzdHJpbmcoMiwgMiArIGV4cCkgKyAiLiIKLSAgICAgICAgICAgICArIHMuc3Vic3RyaW5nKDIgKyBleHAsIGUpOwotCi0gICAgcmV0dXJuIHNpZ24gKyAiMC4iICsgemVyb3MoLTEgLSBleHApICsgcy5zdWJzdHJpbmcoMCwgMSkKLSAgICAgICAgICAgKyBzLnN1YnN0cmluZygyLCBlKTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIFJldHVybiBhIHN0cmluZyBvZiAnMCcgb2YgdGhlIGdpdmVuIGxlbmd0aAotICAgKgotICAgKgotICAgKiBAcGFyYW0gbiBMZW5ndGggb2YgdGhlIHN0cmluZyB0byBiZSByZXR1cm5lZAotICAgKgotICAgKiBAcmV0dXJuIGEgc3RyaW5nIG9mICcwJyB3aXRoIHRoZSBnaXZlbiBsZW5ndGgKLSAgICovCi0gIHN0YXRpYyBwcml2YXRlIFN0cmluZyB6ZXJvcyhpbnQgbikKLSAgewotICAgIGlmIChuIDwgMSkKLSAgICAgIHJldHVybiAiIjsKLQotICAgIGNoYXJbXSBidWYgPSBuZXcgY2hhcltuXTsKLQotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKQotICAgIHsKLSAgICAgIGJ1ZltpXSA9ICcwJzsKLSAgICB9Ci0KLSAgICByZXR1cm4gbmV3IFN0cmluZyhidWYpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiBhIGphdmEgb2JqZWN0IHRoYXQncyBjbG9zZXN0IHRvIHRoZSByZXByZXNlbnRhdGlvbgotICAgKiB0aGF0IHNob3VsZCBiZSBoYW5kZWQgdG8gYW4gZXh0ZW5zaW9uLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSB2YWx1ZSBvZiB0aGlzIFhOdW1iZXIgYXMgYSBEb3VibGUgb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgT2JqZWN0IG9iamVjdCgpCi0gIHsKLSAgICBpZihudWxsID09IG1fb2JqKQotICAgICAgc2V0T2JqZWN0KG5ldyBEb3VibGUobV92YWwpKTsKLSAgICByZXR1cm4gbV9vYmo7Ci0gIH0KLQotICAvKioKLSAgICogVGVsbCBpZiB0d28gb2JqZWN0cyBhcmUgZnVuY3Rpb25hbGx5IGVxdWFsLgotICAgKgotICAgKiBAcGFyYW0gb2JqMiBPYmplY3QgdG8gY29tcGFyZSB0aGlzIHRvCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgdHdvIG9iamVjdHMgYXJlIGVxdWFsCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZXF1YWxzKFhPYmplY3Qgb2JqMikKLSAgewotCi0gICAgLy8gSW4gb3JkZXIgdG8gaGFuZGxlIHRoZSAnYWxsJyBzZW1hbnRpY3Mgb2YKLSAgICAvLyBub2Rlc2V0IGNvbXBhcmlzb25zLCB3ZSBhbHdheXMgY2FsbCB0aGUKLSAgICAvLyBub2Rlc2V0IGZ1bmN0aW9uLgotICAgIGludCB0ID0gb2JqMi5nZXRUeXBlKCk7Ci0gICAgdHJ5Ci0gICAgewotICAgICAgICAgICAgaWYgKHQgPT0gWE9iamVjdC5DTEFTU19OT0RFU0VUKQotICAgICAgICAgICAgICByZXR1cm4gb2JqMi5lcXVhbHModGhpcyk7Ci0gICAgICAgICAgICBlbHNlIGlmKHQgPT0gWE9iamVjdC5DTEFTU19CT09MRUFOKQotICAgICAgICAgICAgICByZXR1cm4gb2JqMi5ib29sKCkgPT0gYm9vbCgpOwotICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgIHJldHVybiBtX3ZhbCA9PSBvYmoyLm51bSgpOwotICAgIH0KLSAgICBjYXRjaChqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uIHRlKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLldyYXBwZWRSdW50aW1lRXhjZXB0aW9uKHRlKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogVGVsbCBpZiB0aGlzIGV4cHJlc3Npb24gcmV0dXJucyBhIHN0YWJsZSBudW1iZXIgdGhhdCB3aWxsIG5vdCBjaGFuZ2UgZHVyaW5nCi0gICAqIGl0ZXJhdGlvbnMgd2l0aGluIHRoZSBleHByZXNzaW9uLiAgVGhpcyBpcyB1c2VkIHRvIGRldGVybWluZSBpZiBhIHByb3hpbWl0eQotICAgKiBwb3NpdGlvbiBwcmVkaWNhdGUgY2FuIGluZGljYXRlIHRoYXQgbm8gbW9yZSBzZWFyY2hpbmcgaGFzIHRvIG9jY3VyLgotICAgKgotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGV4cHJlc3Npb24gcmVwcmVzZW50cyBhIHN0YWJsZSBudW1iZXIuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBpc1N0YWJsZU51bWJlcigpCi0gIHsKLSAgICByZXR1cm4gdHJ1ZTsKLSAgfQotCi0gIC8qKgotICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5YUGF0aFZpc2l0YWJsZSNjYWxsVmlzaXRvcnMoRXhwcmVzc2lvbk93bmVyLCBYUGF0aFZpc2l0b3IpCi0gICAqLwotICBwdWJsaWMgdm9pZCBjYWxsVmlzaXRvcnMoRXhwcmVzc2lvbk93bmVyIG93bmVyLCBYUGF0aFZpc2l0b3IgdmlzaXRvcikKLSAgewotICAgICAgICB2aXNpdG9yLnZpc2l0TnVtYmVyTGl0ZXJhbChvd25lciwgdGhpcyk7Ci0gIH0KLQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL29iamVjdHMvWE9iamVjdC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9vYmplY3RzL1hPYmplY3QuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggODBkMjI1MC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL29iamVjdHMvWE9iamVjdC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNzYxICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFhPYmplY3QuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNCAyMDozNDo0NSBqZWZmc3V0dG9yIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHM7Ci0KLWltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC5yZXMuWFNMTWVzc2FnZXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTUl0ZXJhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuWE1MU3RyaW5nOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5FeHByZXNzaW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5FeHByZXNzaW9uT3duZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLk5vZGVTZXREVE07Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoQ29udGV4dDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuWFBhdGhFeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoVmlzaXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucmVzLlhQQVRIRXJyb3JSZXNvdXJjZXM7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudEZyYWdtZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGVMaXN0OwotaW1wb3J0IG9yZy53M2MuZG9tLnRyYXZlcnNhbC5Ob2RlSXRlcmF0b3I7Ci0KLS8qKgotICogVGhpcyBjbGFzcyByZXByZXNlbnRzIGFuIFhQYXRoIG9iamVjdCwgYW5kIGlzIGNhcGFibGUgb2YKLSAqIGNvbnZlcnRpbmcgdGhlIG9iamVjdCB0byB2YXJpb3VzIHR5cGVzLCBzdWNoIGFzIGEgc3RyaW5nLgotICogVGhpcyBjbGFzcyBhY3RzIGFzIHRoZSBiYXNlIGNsYXNzIHRvIG90aGVyIFhQYXRoIHR5cGUgb2JqZWN0cywKLSAqIHN1Y2ggYXMgWFN0cmluZywgYW5kIHByb3ZpZGVzIHBvbHltb3JwaGljIGNhc3RpbmcgY2FwYWJpbGl0aWVzLgotICogQHhzbC51c2FnZSBnZW5lcmFsCi0gKi8KLXB1YmxpYyBjbGFzcyBYT2JqZWN0IGV4dGVuZHMgRXhwcmVzc2lvbiBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZSwgQ2xvbmVhYmxlCi17Ci0gICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC04MjE4ODcwOTg5ODU2NjI5NTFMOwotCi0gIC8qKgotICAgKiBUaGUgamF2YSBvYmplY3Qgd2hpY2ggdGhpcyBvYmplY3Qgd3JhcHMuCi0gICAqICBAc2VyaWFsCi0gICAqLwotICBwcm90ZWN0ZWQgT2JqZWN0IG1fb2JqOyAgLy8gVGhpcyBtYXkgYmUgTlVMTCEhIQotCi0gIC8qKgotICAgKiBDcmVhdGUgYW4gWE9iamVjdC4KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0KCl7fQotCi0gIC8qKgotICAgKiBDcmVhdGUgYW4gWE9iamVjdC4KLSAgICoKLSAgICogQHBhcmFtIG9iaiBDYW4gYmUgYW55IG9iamVjdCwgc2hvdWxkIGJlIGEgc3BlY2lmaWMgdHlwZQotICAgKiBmb3IgZGVyaXZlZCBjbGFzc2VzLCBvciBudWxsLgotICAgKi8KLSAgcHVibGljIFhPYmplY3QoT2JqZWN0IG9iaikKLSAgewotICAgIHNldE9iamVjdChvYmopOwotICB9Ci0KLSAgcHJvdGVjdGVkIHZvaWQgc2V0T2JqZWN0KE9iamVjdCBvYmopIHsKLSAgICAgIG1fb2JqID0gb2JqOwotICB9Ci0KLSAgLyoqCi0gICAqIEZvciBzdXBwb3J0IG9mIGxpdGVyYWwgb2JqZWN0cyBpbiB4cGF0aHMuCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgWFBhdGggZXhlY3V0aW9uIGNvbnRleHQuCi0gICAqCi0gICAqIEByZXR1cm4gVGhpcyBvYmplY3QuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFhPYmplY3QgZXhlY3V0ZShYUGF0aENvbnRleHQgeGN0eHQpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHJldHVybiB0aGlzOwotICB9Ci0KLSAgLyoqCi0gICAqIFNwZWNpZnkgaWYgaXQncyBPSyBmb3IgZGV0YWNoIHRvIHJlbGVhc2UgdGhlIGl0ZXJhdG9yIGZvciByZXVzZS4KLSAgICogVGhpcyBmdW5jdGlvbiBzaG91bGQgYmUgY2FsbGVkIHdpdGggYSB2YWx1ZSBvZiBmYWxzZSBmb3Igb2JqZWN0cyB0aGF0IGFyZQotICAgKiBzdG9yZWQgaW4gdmFyaWFibGVzLgotICAgKiBDYWxsaW5nIHRoaXMgd2l0aCBhIHZhbHVlIG9mIGZhbHNlIG9uIGEgWE5vZGVTZXQgd2lsbCBjYXVzZSB0aGUgbm9kZXNldAotICAgKiB0byBiZSBjYWNoZWQuCi0gICAqCi0gICAqIEBwYXJhbSBhbGxvd1JlbGVhc2UgdHJ1ZSBpZiBpdCBpcyBPSyBmb3IgZGV0YWNoIHRvIHJlbGVhc2UgdGhpcyBpdGVyYXRvcgotICAgKiBmb3IgcG9vbGluZy4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGFsbG93RGV0YWNoVG9SZWxlYXNlKGJvb2xlYW4gYWxsb3dSZWxlYXNlKXt9Ci0KLSAgLyoqCi0gICAqIERldGFjaGVzIHRoZSA8Y29kZT5EVE1JdGVyYXRvcjwvY29kZT4gZnJvbSB0aGUgc2V0IHdoaWNoIGl0IGl0ZXJhdGVkCi0gICAqIG92ZXIsIHJlbGVhc2luZyBhbnkgY29tcHV0YXRpb25hbCByZXNvdXJjZXMgYW5kIHBsYWNpbmcgdGhlIGl0ZXJhdG9yCi0gICAqIGluIHRoZSBJTlZBTElEIHN0YXRlLiBBZnRlciA8Y29kZT5kZXRhY2g8L2NvZGU+IGhhcyBiZWVuIGludm9rZWQsCi0gICAqIGNhbGxzIHRvIDxjb2RlPm5leHROb2RlPC9jb2RlPiBvciA8Y29kZT5wcmV2aW91c05vZGU8L2NvZGU+IHdpbGwKLSAgICogcmFpc2UgYSBydW50aW1lIGV4Y2VwdGlvbi4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGRldGFjaCgpe30KLQotICAvKioKLSAgICogRm9yY2VzIHRoZSBvYmplY3QgdG8gcmVsZWFzZSBpdCdzIHJlc291cmNlcy4gIFRoaXMgaXMgbW9yZSBoYXJzaCB0aGFuCi0gICAqIGRldGFjaCgpLgotICAgKi8KLSAgcHVibGljIHZvaWQgZGVzdHJ1Y3QoKQotICB7Ci0KLSAgICBpZiAobnVsbCAhPSBtX29iaikKLSAgICB7Ci0gICAgICBhbGxvd0RldGFjaFRvUmVsZWFzZSh0cnVlKTsKLSAgICAgIGRldGFjaCgpOwotCi0gICAgICBzZXRPYmplY3QobnVsbCk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFJlc2V0IGZvciBmcmVzaCByZXVzZS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHJlc2V0KCkKLSAgewotICB9Ci0KLSAgLyoqCi0gICAqIERpcmVjdGx5IGNhbGwgdGhlCi0gICAqIGNoYXJhY3RlcnMgbWV0aG9kIG9uIHRoZSBwYXNzZWQgQ29udGVudEhhbmRsZXIgZm9yIHRoZQotICAgKiBzdHJpbmctdmFsdWUuIE11bHRpcGxlIGNhbGxzIHRvIHRoZQotICAgKiBDb250ZW50SGFuZGxlcidzIGNoYXJhY3RlcnMgbWV0aG9kcyBtYXkgd2VsbCBvY2N1ciBmb3IgYSBzaW5nbGUgY2FsbCB0bwotICAgKiB0aGlzIG1ldGhvZC4KLSAgICoKLSAgICogQHBhcmFtIGNoIEEgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGEgQ29udGVudEhhbmRsZXIuCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBkaXNwYXRjaENoYXJhY3RlcnNFdmVudHMob3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIgY2gpCi0gICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgeHN0cigpLmRpc3BhdGNoQ2hhcmFjdGVyc0V2ZW50cyhjaCk7Ci0gIH0KLQotICAvKioKLSAgICogQ3JlYXRlIHRoZSByaWdodCBYT2JqZWN0IGJhc2VkIG9uIHRoZSB0eXBlIG9mIHRoZSBvYmplY3QgcGFzc2VkLiAgVGhpcwotICAgKiBmdW5jdGlvbiBjYW4gbm90IG1ha2UgYW4gWE9iamVjdCB0aGF0IGV4cG9zZXMgRE9NIE5vZGVzLCBOb2RlTGlzdHMsIGFuZAotICAgKiBOb2RlSXRlcmF0b3JzIHRvIHRoZSBYU0xUIHN0eWxlc2hlZXQgYXMgbm9kZS1zZXRzLgotICAgKgotICAgKiBAcGFyYW0gdmFsIFRoZSBqYXZhIG9iamVjdCB3aGljaCB0aGlzIG9iamVjdCB3aWxsIHdyYXAuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIHJpZ2h0IFhPYmplY3QgYmFzZWQgb24gdGhlIHR5cGUgb2YgdGhlIG9iamVjdCBwYXNzZWQuCi0gICAqLwotICBzdGF0aWMgcHVibGljIFhPYmplY3QgY3JlYXRlKE9iamVjdCB2YWwpCi0gIHsKLSAgICByZXR1cm4gWE9iamVjdEZhY3RvcnkuY3JlYXRlKHZhbCk7Ci0gIH0KLQotICAvKioKLSAgICogQ3JlYXRlIHRoZSByaWdodCBYT2JqZWN0IGJhc2VkIG9uIHRoZSB0eXBlIG9mIHRoZSBvYmplY3QgcGFzc2VkLgotICAgKiBUaGlzIGZ1bmN0aW9uIDxlbXBoPmNhbjwvZW1waD4gbWFrZSBhbiBYT2JqZWN0IHRoYXQgZXhwb3NlcyBET00gTm9kZXMsIE5vZGVMaXN0cywgYW5kCi0gICAqIE5vZGVJdGVyYXRvcnMgdG8gdGhlIFhTTFQgc3R5bGVzaGVldCBhcyBub2RlLXNldHMuCi0gICAqCi0gICAqIEBwYXJhbSB2YWwgVGhlIGphdmEgb2JqZWN0IHdoaWNoIHRoaXMgb2JqZWN0IHdpbGwgd3JhcC4KLSAgICogQHBhcmFtIHhjdHh0IFRoZSBYUGF0aCBjb250ZXh0LgotICAgKgotICAgKiBAcmV0dXJuIHRoZSByaWdodCBYT2JqZWN0IGJhc2VkIG9uIHRoZSB0eXBlIG9mIHRoZSBvYmplY3QgcGFzc2VkLgotICAgKi8KLSAgc3RhdGljIHB1YmxpYyBYT2JqZWN0IGNyZWF0ZShPYmplY3QgdmFsLCBYUGF0aENvbnRleHQgeGN0eHQpCi0gIHsKLSAgICByZXR1cm4gWE9iamVjdEZhY3RvcnkuY3JlYXRlKHZhbCwgeGN0eHQpOwotICB9Ci0KLSAgLyoqIENvbnN0YW50IGZvciBOVUxMIG9iamVjdCB0eXBlICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENMQVNTX05VTEwgPSAtMTsKLQotICAvKiogQ29uc3RhbnQgZm9yIFVOS05PV04gb2JqZWN0IHR5cGUgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ0xBU1NfVU5LTk9XTiA9IDA7Ci0KLSAgLyoqIENvbnN0YW50IGZvciBCT09MRUFOICBvYmplY3QgdHlwZSAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDTEFTU19CT09MRUFOID0gMTsKLQotICAvKiogQ29uc3RhbnQgZm9yIE5VTUJFUiBvYmplY3QgdHlwZSAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDTEFTU19OVU1CRVIgPSAyOwotCi0gIC8qKiBDb25zdGFudCBmb3IgU1RSSU5HIG9iamVjdCB0eXBlICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENMQVNTX1NUUklORyA9IDM7Ci0KLSAgLyoqIENvbnN0YW50IGZvciBOT0RFU0VUIG9iamVjdCB0eXBlICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENMQVNTX05PREVTRVQgPSA0OwotCi0gIC8qKiBDb25zdGFudCBmb3IgUkVTVUxUIFRSRUUgRlJBR01FTlQgb2JqZWN0IHR5cGUgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ0xBU1NfUlRSRUVGUkFHID0gNTsKLQotICAvKiogUmVwcmVzZW50cyBhbiB1bnJlc29sdmVkIHZhcmlhYmxlIHR5cGUgYXMgYW4gaW50ZWdlci4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ0xBU1NfVU5SRVNPTFZFRFZBUklBQkxFID0gNjAwOwotCi0gIC8qKgotICAgKiBUZWxsIHdoYXQga2luZCBvZiBjbGFzcyB0aGlzIGlzLgotICAgKgotICAgKiBAcmV0dXJuIENMQVNTX1VOS05PV04KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0VHlwZSgpCi0gIHsKLSAgICByZXR1cm4gQ0xBU1NfVU5LTk9XTjsKLSAgfQotCi0gIC8qKgotICAgKiBHaXZlbiBhIHJlcXVlc3QgdHlwZSwgcmV0dXJuIHRoZSBlcXVpdmFsZW50IHN0cmluZy4KLSAgICogRm9yIGRpYWdub3N0aWMgcHVycG9zZXMuCi0gICAqCi0gICAqIEByZXR1cm4gdHlwZSBzdHJpbmcgIiNVTktOT1dOIiArIG9iamVjdCBjbGFzcyBuYW1lCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFR5cGVTdHJpbmcoKQotICB7Ci0gICAgcmV0dXJuICIjVU5LTk9XTiAoIiArIG9iamVjdCgpLmdldENsYXNzKCkuZ2V0TmFtZSgpICsgIikiOwotICB9Ci0KLSAgLyoqCi0gICAqIENhc3QgcmVzdWx0IG9iamVjdCB0byBhIG51bWJlci4gQWx3YXlzIGlzc3VlcyBhbiBlcnJvci4KLSAgICoKLSAgICogQHJldHVybiAwLjAKLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgZG91YmxlIG51bSgpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGVycm9yKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfQ0FOVF9DT05WRVJUX1RPX05VTUJFUiwKLSAgICAgICAgICBuZXcgT2JqZWN0W117IGdldFR5cGVTdHJpbmcoKSB9KTsgIC8vIkNhbiBub3QgY29udmVydCAiK2dldFR5cGVTdHJpbmcoKSsiIHRvIGEgbnVtYmVyIik7Ci0KLSAgICByZXR1cm4gMC4wOwotICB9Ci0KLSAgLyoqCi0gICAqIENhc3QgcmVzdWx0IG9iamVjdCB0byBhIG51bWJlciwgYnV0IGFsbG93IHNpZGUgZWZmZWN0cywgc3VjaCBhcyB0aGUKLSAgICogaW5jcmVtZW50aW5nIG9mIGFuIGl0ZXJhdG9yLgotICAgKgotICAgKiBAcmV0dXJuIG51bWVyaWMgdmFsdWUgb2YgdGhlIHN0cmluZyBjb252ZXJzaW9uIGZyb20gdGhlCi0gICAqIG5leHQgbm9kZSBpbiB0aGUgTm9kZVNldERUTSwgb3IgTkFOIGlmIG5vIG5vZGUgd2FzIGZvdW5kCi0gICAqLwotICBwdWJsaWMgZG91YmxlIG51bVdpdGhTaWRlRWZmZWN0cygpICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIG51bSgpOwotICB9Ci0KLSAgLyoqCi0gICAqIENhc3QgcmVzdWx0IG9iamVjdCB0byBhIGJvb2xlYW4uIEFsd2F5cyBpc3N1ZXMgYW4gZXJyb3IuCi0gICAqCi0gICAqIEByZXR1cm4gZmFsc2UKLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBib29sKCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgZXJyb3IoWFBBVEhFcnJvclJlc291cmNlcy5FUl9DQU5UX0NPTlZFUlRfVE9fTlVNQkVSLAotICAgICAgICAgIG5ldyBPYmplY3RbXXsgZ2V0VHlwZVN0cmluZygpIH0pOyAgLy8iQ2FuIG5vdCBjb252ZXJ0ICIrZ2V0VHlwZVN0cmluZygpKyIgdG8gYSBudW1iZXIiKTsKLQotICAgIHJldHVybiBmYWxzZTsKLSAgfQotCi0gIC8qKgotICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYSBib29sZWFuLCBidXQgYWxsb3cgc2lkZSBlZmZlY3RzLCBzdWNoIGFzIHRoZQotICAgKiBpbmNyZW1lbnRpbmcgb2YgYW4gaXRlcmF0b3IuCi0gICAqCi0gICAqIEByZXR1cm4gVHJ1ZSBpZiB0aGVyZSBpcyBhIG5leHQgbm9kZSBpbiB0aGUgbm9kZXNldAotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gYm9vbFdpdGhTaWRlRWZmZWN0cygpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gYm9vbCgpOwotICB9Ci0KLQotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGEgc3RyaW5nLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBzdHJpbmcgdGhpcyB3cmFwcyBvciB0aGUgZW1wdHkgc3RyaW5nIGlmIG51bGwKLSAgICovCi0gIHB1YmxpYyBYTUxTdHJpbmcgeHN0cigpCi0gIHsKLSAgICByZXR1cm4gWE1MU3RyaW5nRmFjdG9yeUltcGwuZ2V0RmFjdG9yeSgpLm5ld3N0cihzdHIoKSk7Ci0gIH0KLQotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGEgc3RyaW5nLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBvYmplY3QgYXMgYSBzdHJpbmcKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgc3RyKCkKLSAgewotICAgIHJldHVybiAobV9vYmogIT0gbnVsbCkgPyBtX29iai50b1N0cmluZygpIDogIiI7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIG9iamVjdAotICAgKgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIG9iamVjdAotICAgKi8KLSAgcHVibGljIFN0cmluZyB0b1N0cmluZygpCi0gIHsKLSAgICByZXR1cm4gc3RyKCk7Ci0gIH0KLQotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGEgcmVzdWx0IHRyZWUgZnJhZ21lbnQuCi0gICAqCi0gICAqIEBwYXJhbSBzdXBwb3J0IFhQYXRoIGNvbnRleHQgdG8gdXNlIGZvciB0aGUgY29udmVyc2lvbgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBvYmplYyBhcyBhIHJlc3VsdCB0cmVlIGZyYWdtZW50LgotICAgKi8KLSAgcHVibGljIGludCBydGYoWFBhdGhDb250ZXh0IHN1cHBvcnQpCi0gIHsKLQotICAgIGludCByZXN1bHQgPSBydGYoKTsKLQotICAgIGlmIChEVE0uTlVMTCA9PSByZXN1bHQpCi0gICAgewotICAgICAgRFRNIGZyYWcgPSBzdXBwb3J0LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTsKLQotICAgICAgLy8gJU9QVCUKLSAgICAgIGZyYWcuYXBwZW5kVGV4dENoaWxkKHN0cigpKTsKLQotICAgICAgcmVzdWx0ID0gZnJhZy5nZXREb2N1bWVudCgpOwotICAgIH0KLQotICAgIHJldHVybiByZXN1bHQ7Ci0gIH0KLQotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGEgcmVzdWx0IHRyZWUgZnJhZ21lbnQuCi0gICAqCi0gICAqIEBwYXJhbSBzdXBwb3J0IFhQYXRoIGNvbnRleHQgdG8gdXNlIGZvciB0aGUgY29udmVyc2lvbgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBvYmplYyBhcyBhIHJlc3VsdCB0cmVlIGZyYWdtZW50LgotICAgKi8KLSAgcHVibGljIERvY3VtZW50RnJhZ21lbnQgcnRyZWUoWFBhdGhDb250ZXh0IHN1cHBvcnQpCi0gIHsKLSAgICBEb2N1bWVudEZyYWdtZW50IGRvY0ZyYWcgPSBudWxsOwotICAgIGludCByZXN1bHQgPSBydGYoKTsKLQotICAgIGlmIChEVE0uTlVMTCA9PSByZXN1bHQpCi0gICAgewotICAgICAgRFRNIGZyYWcgPSBzdXBwb3J0LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTsKLQotICAgICAgLy8gJU9QVCUKLSAgICAgIGZyYWcuYXBwZW5kVGV4dENoaWxkKHN0cigpKTsKLQotICAgICAgZG9jRnJhZyA9IChEb2N1bWVudEZyYWdtZW50KWZyYWcuZ2V0Tm9kZShmcmFnLmdldERvY3VtZW50KCkpOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgRFRNIGZyYWcgPSBzdXBwb3J0LmdldERUTShyZXN1bHQpOwotICAgICAgZG9jRnJhZyA9IChEb2N1bWVudEZyYWdtZW50KWZyYWcuZ2V0Tm9kZShmcmFnLmdldERvY3VtZW50KCkpOwotICAgIH0KLQotICAgIHJldHVybiBkb2NGcmFnOwotICB9Ci0KLQotICAvKioKLSAgICogRm9yIGZ1bmN0aW9ucyB0byBvdmVycmlkZS4KLSAgICoKLSAgICogQHJldHVybiBudWxsCi0gICAqLwotICBwdWJsaWMgRG9jdW1lbnRGcmFnbWVudCBydHJlZSgpCi0gIHsKLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBGb3IgZnVuY3Rpb25zIHRvIG92ZXJyaWRlLgotICAgKgotICAgKiBAcmV0dXJuIG51bGwKLSAgICovCi0gIHB1YmxpYyBpbnQgcnRmKCkKLSAgewotICAgIHJldHVybiBEVE0uTlVMTDsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gYSBqYXZhIG9iamVjdCB0aGF0J3MgY2xvc2VzdCB0byB0aGUgcmVwcmVzZW50YXRpb24KLSAgICogdGhhdCBzaG91bGQgYmUgaGFuZGVkIHRvIGFuIGV4dGVuc2lvbi4KLSAgICoKLSAgICogQHJldHVybiBUaGUgb2JqZWN0IHRoYXQgdGhpcyBjbGFzcyB3cmFwcwotICAgKi8KLSAgcHVibGljIE9iamVjdCBvYmplY3QoKQotICB7Ci0gICAgcmV0dXJuIG1fb2JqOwotICB9Ci0KLSAgLyoqCi0gICAqIENhc3QgcmVzdWx0IG9iamVjdCB0byBhIG5vZGVsaXN0LiBBbHdheXMgaXNzdWVzIGFuIGVycm9yLgotICAgKgotICAgKiBAcmV0dXJuIG51bGwKLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgRFRNSXRlcmF0b3IgaXRlcigpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGVycm9yKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfQ0FOVF9DT05WRVJUX1RPX05PREVMSVNULAotICAgICAgICAgIG5ldyBPYmplY3RbXXsgZ2V0VHlwZVN0cmluZygpIH0pOyAgLy8iQ2FuIG5vdCBjb252ZXJ0ICIrZ2V0VHlwZVN0cmluZygpKyIgdG8gYSBOb2RlTGlzdCEiKTsKLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBhIGZyZXNoIGNvcHkgb2YgdGhlIG9iamVjdC4gIEZvciB1c2Ugd2l0aCB2YXJpYWJsZXMuCi0gICAqCi0gICAqIEByZXR1cm4gVGhpcyBvYmplY3QsIHVubGVzcyBvdmVycmlkZGVuIGJ5IHN1YmNsYXNzLgotICAgKi8KLSAgcHVibGljIFhPYmplY3QgZ2V0RnJlc2goKQotICB7Ci0gICAgcmV0dXJuIHRoaXM7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYSBub2RlbGlzdC4gQWx3YXlzIGlzc3VlcyBhbiBlcnJvci4KLSAgICoKLSAgICogQHJldHVybiBudWxsCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIE5vZGVJdGVyYXRvciBub2Rlc2V0KCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgZXJyb3IoWFBBVEhFcnJvclJlc291cmNlcy5FUl9DQU5UX0NPTlZFUlRfVE9fTk9ERUxJU1QsCi0gICAgICAgICAgbmV3IE9iamVjdFtdeyBnZXRUeXBlU3RyaW5nKCkgfSk7ICAvLyJDYW4gbm90IGNvbnZlcnQgIitnZXRUeXBlU3RyaW5nKCkrIiB0byBhIE5vZGVMaXN0ISIpOwotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGEgbm9kZWxpc3QuIEFsd2F5cyBpc3N1ZXMgYW4gZXJyb3IuCi0gICAqCi0gICAqIEByZXR1cm4gbnVsbAotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBOb2RlTGlzdCBub2RlbGlzdCgpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGVycm9yKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfQ0FOVF9DT05WRVJUX1RPX05PREVMSVNULAotICAgICAgICAgIG5ldyBPYmplY3RbXXsgZ2V0VHlwZVN0cmluZygpIH0pOyAgLy8iQ2FuIG5vdCBjb252ZXJ0ICIrZ2V0VHlwZVN0cmluZygpKyIgdG8gYSBOb2RlTGlzdCEiKTsKLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLQotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGEgbm9kZWxpc3QuIEFsd2F5cyBpc3N1ZXMgYW4gZXJyb3IuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIG9iamVjdCBhcyBhIE5vZGVTZXREVE0uCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIE5vZGVTZXREVE0gbXV0YWJsZU5vZGVzZXQoKQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGVycm9yKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfQ0FOVF9DT05WRVJUX1RPX01VVEFCTEVOT0RFTElTVCwKLSAgICAgICAgICBuZXcgT2JqZWN0W117IGdldFR5cGVTdHJpbmcoKSB9KTsgIC8vIkNhbiBub3QgY29udmVydCAiK2dldFR5cGVTdHJpbmcoKSsiIHRvIGEgTm9kZVNldERUTSEiKTsKLQotICAgIHJldHVybiAoTm9kZVNldERUTSkgbV9vYmo7Ci0gIH0KLQotICAvKioKLSAgICogQ2FzdCBvYmplY3QgdG8gdHlwZSB0LgotICAgKgotICAgKiBAcGFyYW0gdCBUeXBlIG9mIG9iamVjdCB0byBjYXN0IHRoaXMgdG8KLSAgICogQHBhcmFtIHN1cHBvcnQgWFBhdGggY29udGV4dCB0byB1c2UgZm9yIHRoZSBjb252ZXJzaW9uCi0gICAqCi0gICAqIEByZXR1cm4gVGhpcyBvYmplY3QgYXMgdGhlIGdpdmVuIHR5cGUgdAotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBPYmplY3QgY2FzdFRvVHlwZShpbnQgdCwgWFBhdGhDb250ZXh0IHN1cHBvcnQpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgT2JqZWN0IHJlc3VsdDsKLQotICAgIHN3aXRjaCAodCkKLSAgICB7Ci0gICAgY2FzZSBDTEFTU19TVFJJTkcgOgotICAgICAgcmVzdWx0ID0gc3RyKCk7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIENMQVNTX05VTUJFUiA6Ci0gICAgICByZXN1bHQgPSBuZXcgRG91YmxlKG51bSgpKTsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgQ0xBU1NfTk9ERVNFVCA6Ci0gICAgICByZXN1bHQgPSBpdGVyKCk7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIENMQVNTX0JPT0xFQU4gOgotICAgICAgcmVzdWx0ID0gbmV3IEJvb2xlYW4oYm9vbCgpKTsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgQ0xBU1NfVU5LTk9XTiA6Ci0gICAgICByZXN1bHQgPSBtX29iajsKLSAgICAgIGJyZWFrOwotCi0gICAgLy8gJVRCRCUgIFdoYXQgdG8gZG8gaGVyZT8KLSAgICAvLyAgICBjYXNlIENMQVNTX1JUUkVFRlJBRyA6Ci0gICAgLy8gICAgICByZXN1bHQgPSBydHJlZShzdXBwb3J0KTsKLSAgICAvLyAgICAgIGJyZWFrOwotICAgIGRlZmF1bHQgOgotICAgICAgZXJyb3IoWFBBVEhFcnJvclJlc291cmNlcy5FUl9DQU5UX0NPTlZFUlRfVE9fVFlQRSwKLSAgICAgICAgICAgIG5ldyBPYmplY3RbXXsgZ2V0VHlwZVN0cmluZygpLAotICAgICAgICAgICAgICAgICAgICAgICAgICBJbnRlZ2VyLnRvU3RyaW5nKHQpIH0pOyAgLy8iQ2FuIG5vdCBjb252ZXJ0ICIrZ2V0VHlwZVN0cmluZygpKyIgdG8gYSB0eXBlIyIrdCk7Ci0KLSAgICAgIHJlc3VsdCA9IG51bGw7Ci0gICAgfQotCi0gICAgcmV0dXJuIHJlc3VsdDsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIGlmIG9uZSBvYmplY3QgaXMgbGVzcyB0aGFuIHRoZSBvdGhlci4KLSAgICoKLSAgICogQHBhcmFtIG9iajIgT2JqZWN0IHRvIGNvbXBhcmUgdGhpcyB0bwotICAgKgotICAgKiBAcmV0dXJuIFRydWUgaWYgdGhpcyBvYmplY3QgaXMgbGVzcyB0aGFuIHRoZSBnaXZlbiBvYmplY3QKLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBsZXNzVGhhbihYT2JqZWN0IG9iajIpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgLy8gSW4gb3JkZXIgdG8gaGFuZGxlIHRoZSAnYWxsJyBzZW1hbnRpY3Mgb2YKLSAgICAvLyBub2Rlc2V0IGNvbXBhcmlzb25zLCB3ZSBhbHdheXMgY2FsbCB0aGUKLSAgICAvLyBub2Rlc2V0IGZ1bmN0aW9uLiAgQmVjYXVzZSB0aGUgYXJndW1lbnRzCi0gICAgLy8gYXJlIGJhY2t3YXJkcywgd2UgY2FsbCB0aGUgb3Bwb3NpdGUgY29tcGFyaXNvbgotICAgIC8vIGZ1bmN0aW9uLgotICAgIGlmIChvYmoyLmdldFR5cGUoKSA9PSBYT2JqZWN0LkNMQVNTX05PREVTRVQpCi0gICAgICByZXR1cm4gb2JqMi5ncmVhdGVyVGhhbih0aGlzKTsKLQotICAgIHJldHVybiB0aGlzLm51bSgpIDwgb2JqMi5udW0oKTsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIGlmIG9uZSBvYmplY3QgaXMgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIHRoZSBvdGhlci4KLSAgICoKLSAgICogQHBhcmFtIG9iajIgT2JqZWN0IHRvIGNvbXBhcmUgdGhpcyB0bwotICAgKgotICAgKiBAcmV0dXJuIFRydWUgaWYgdGhpcyBvYmplY3QgaXMgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIHRoZSBnaXZlbiBvYmplY3QKLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBsZXNzVGhhbk9yRXF1YWwoWE9iamVjdCBvYmoyKQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIC8vIEluIG9yZGVyIHRvIGhhbmRsZSB0aGUgJ2FsbCcgc2VtYW50aWNzIG9mCi0gICAgLy8gbm9kZXNldCBjb21wYXJpc29ucywgd2UgYWx3YXlzIGNhbGwgdGhlCi0gICAgLy8gbm9kZXNldCBmdW5jdGlvbi4gIEJlY2F1c2UgdGhlIGFyZ3VtZW50cwotICAgIC8vIGFyZSBiYWNrd2FyZHMsIHdlIGNhbGwgdGhlIG9wcG9zaXRlIGNvbXBhcmlzb24KLSAgICAvLyBmdW5jdGlvbi4KLSAgICBpZiAob2JqMi5nZXRUeXBlKCkgPT0gWE9iamVjdC5DTEFTU19OT0RFU0VUKQotICAgICAgcmV0dXJuIG9iajIuZ3JlYXRlclRoYW5PckVxdWFsKHRoaXMpOwotCi0gICAgcmV0dXJuIHRoaXMubnVtKCkgPD0gb2JqMi5udW0oKTsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIGlmIG9uZSBvYmplY3QgaXMgZ3JlYXRlciB0aGFuIHRoZSBvdGhlci4KLSAgICoKLSAgICogQHBhcmFtIG9iajIgT2JqZWN0IHRvIGNvbXBhcmUgdGhpcyB0bwotICAgKgotICAgKiBAcmV0dXJuIFRydWUgaWYgdGhpcyBvYmplY3QgaXMgZ3JlYXRlciB0aGFuIHRoZSBnaXZlbiBvYmplY3QKLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBncmVhdGVyVGhhbihYT2JqZWN0IG9iajIpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgLy8gSW4gb3JkZXIgdG8gaGFuZGxlIHRoZSAnYWxsJyBzZW1hbnRpY3Mgb2YKLSAgICAvLyBub2Rlc2V0IGNvbXBhcmlzb25zLCB3ZSBhbHdheXMgY2FsbCB0aGUKLSAgICAvLyBub2Rlc2V0IGZ1bmN0aW9uLiAgQmVjYXVzZSB0aGUgYXJndW1lbnRzCi0gICAgLy8gYXJlIGJhY2t3YXJkcywgd2UgY2FsbCB0aGUgb3Bwb3NpdGUgY29tcGFyaXNvbgotICAgIC8vIGZ1bmN0aW9uLgotICAgIGlmIChvYmoyLmdldFR5cGUoKSA9PSBYT2JqZWN0LkNMQVNTX05PREVTRVQpCi0gICAgICByZXR1cm4gb2JqMi5sZXNzVGhhbih0aGlzKTsKLQotICAgIHJldHVybiB0aGlzLm51bSgpID4gb2JqMi5udW0oKTsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIGlmIG9uZSBvYmplY3QgaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHRoZSBvdGhlci4KLSAgICoKLSAgICogQHBhcmFtIG9iajIgT2JqZWN0IHRvIGNvbXBhcmUgdGhpcyB0bwotICAgKgotICAgKiBAcmV0dXJuIFRydWUgaWYgdGhpcyBvYmplY3QgaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHRoZSBnaXZlbiBvYmplY3QKLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBncmVhdGVyVGhhbk9yRXF1YWwoWE9iamVjdCBvYmoyKQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIC8vIEluIG9yZGVyIHRvIGhhbmRsZSB0aGUgJ2FsbCcgc2VtYW50aWNzIG9mCi0gICAgLy8gbm9kZXNldCBjb21wYXJpc29ucywgd2UgYWx3YXlzIGNhbGwgdGhlCi0gICAgLy8gbm9kZXNldCBmdW5jdGlvbi4gIEJlY2F1c2UgdGhlIGFyZ3VtZW50cwotICAgIC8vIGFyZSBiYWNrd2FyZHMsIHdlIGNhbGwgdGhlIG9wcG9zaXRlIGNvbXBhcmlzb24KLSAgICAvLyBmdW5jdGlvbi4KLSAgICBpZiAob2JqMi5nZXRUeXBlKCkgPT0gWE9iamVjdC5DTEFTU19OT0RFU0VUKQotICAgICAgcmV0dXJuIG9iajIubGVzc1RoYW5PckVxdWFsKHRoaXMpOwotCi0gICAgcmV0dXJuIHRoaXMubnVtKCkgPj0gb2JqMi5udW0oKTsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIGlmIHR3byBvYmplY3RzIGFyZSBmdW5jdGlvbmFsbHkgZXF1YWwuCi0gICAqCi0gICAqIEBwYXJhbSBvYmoyIE9iamVjdCB0byBjb21wYXJlIHRoaXMgdG8KLSAgICoKLSAgICogQHJldHVybiBUcnVlIGlmIHRoaXMgb2JqZWN0IGlzIGVxdWFsIHRvIHRoZSBnaXZlbiBvYmplY3QKLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoWE9iamVjdCBvYmoyKQotICB7Ci0KLSAgICAvLyBJbiBvcmRlciB0byBoYW5kbGUgdGhlICdhbGwnIHNlbWFudGljcyBvZgotICAgIC8vIG5vZGVzZXQgY29tcGFyaXNvbnMsIHdlIGFsd2F5cyBjYWxsIHRoZQotICAgIC8vIG5vZGVzZXQgZnVuY3Rpb24uCi0gICAgaWYgKG9iajIuZ2V0VHlwZSgpID09IFhPYmplY3QuQ0xBU1NfTk9ERVNFVCkKLSAgICAgIHJldHVybiBvYmoyLmVxdWFscyh0aGlzKTsKLQotICAgIGlmIChudWxsICE9IG1fb2JqKQotICAgIHsKLSAgICAgIHJldHVybiBtX29iai5lcXVhbHMob2JqMi5tX29iaik7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICByZXR1cm4gb2JqMi5tX29iaiA9PSBudWxsOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIGlmIHR3byBvYmplY3RzIGFyZSBmdW5jdGlvbmFsbHkgbm90IGVxdWFsLgotICAgKgotICAgKiBAcGFyYW0gb2JqMiBPYmplY3QgdG8gY29tcGFyZSB0aGlzIHRvCi0gICAqCi0gICAqIEByZXR1cm4gVHJ1ZSBpZiB0aGlzIG9iamVjdCBpcyBub3QgZXF1YWwgdG8gdGhlIGdpdmVuIG9iamVjdAotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIG5vdEVxdWFscyhYT2JqZWN0IG9iajIpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgLy8gSW4gb3JkZXIgdG8gaGFuZGxlIHRoZSAnYWxsJyBzZW1hbnRpY3Mgb2YKLSAgICAvLyBub2Rlc2V0IGNvbXBhcmlzb25zLCB3ZSBhbHdheXMgY2FsbCB0aGUKLSAgICAvLyBub2Rlc2V0IGZ1bmN0aW9uLgotICAgIGlmIChvYmoyLmdldFR5cGUoKSA9PSBYT2JqZWN0LkNMQVNTX05PREVTRVQpCi0gICAgICByZXR1cm4gb2JqMi5ub3RFcXVhbHModGhpcyk7Ci0KLSAgICByZXR1cm4gIWVxdWFscyhvYmoyKTsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIHRoZSB1c2VyIG9mIGFuIGVycm9yLCBhbmQgcHJvYmFibHkgdGhyb3cgYW4KLSAgICogZXhjZXB0aW9uLgotICAgKgotICAgKiBAcGFyYW0gbXNnIEVycm9yIG1lc3NhZ2UgdG8gaXNzdWUKLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBlcnJvcihTdHJpbmcgbXNnKQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICBlcnJvcihtc2csIG51bGwpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgdGhlIHVzZXIgb2YgYW4gZXJyb3IsIGFuZCBwcm9iYWJseSB0aHJvdyBhbgotICAgKiBleGNlcHRpb24uCi0gICAqCi0gICAqIEBwYXJhbSBtc2cgRXJyb3IgbWVzc2FnZSB0byBpc3N1ZQotICAgKiBAcGFyYW0gYXJncyBBcmd1bWVudHMgdG8gdXNlIGluIHRoZSBtZXNzYWdlCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgZXJyb3IoU3RyaW5nIG1zZywgT2JqZWN0W10gYXJncykKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBTdHJpbmcgZm1zZyA9IFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShtc2csIGFyZ3MpOwotCi0gICAgLy8gYm9vbGVhbiBzaG91bGRUaHJvdyA9IHN1cHBvcnQucHJvYmxlbShtX3N1cHBvcnQuWFBBVEhQUk9DRVNTT1IsCi0gICAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fc3VwcG9ydC5FUlJPUiwKLSAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwKLSAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwgZm1zZywgMCwgMCk7Ci0gICAgLy8gaWYoc2hvdWxkVGhyb3cpCi0gICAgewotICAgICAgdGhyb3cgbmV3IFhQYXRoRXhjZXB0aW9uKGZtc2csIHRoaXMpOwotICAgIH0KLSAgfQotCi0KLSAgLyoqCi0gICAqIFhPYmplY3RzIHNob3VsZCBub3Qgbm9ybWFsbHkgbmVlZCB0byBmaXggdXAgdmFyaWFibGVzLgotICAgKi8KLSAgcHVibGljIHZvaWQgZml4dXBWYXJpYWJsZXMoamF2YS51dGlsLlZlY3RvciB2YXJzLCBpbnQgZ2xvYmFsc1NpemUpCi0gIHsKLSAgICAvLyBuby1vcAotICB9Ci0KLQotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGEgc3RyaW5nLgotICAgKgotICAgKgotICAgKiBORUVEU0RPQyBAcGFyYW0gZnNiCi0gICAqIEByZXR1cm4gVGhlIHN0cmluZyB0aGlzIHdyYXBzIG9yIHRoZSBlbXB0eSBzdHJpbmcgaWYgbnVsbAotICAgKi8KLSAgcHVibGljIHZvaWQgYXBwZW5kVG9Gc2IoY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5GYXN0U3RyaW5nQnVmZmVyIGZzYikKLSAgewotICAgIGZzYi5hcHBlbmQoc3RyKCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoVmlzaXRhYmxlI2NhbGxWaXNpdG9ycyhFeHByZXNzaW9uT3duZXIsIFhQYXRoVmlzaXRvcikKLSAgICovCi0gIHB1YmxpYyB2b2lkIGNhbGxWaXNpdG9ycyhFeHByZXNzaW9uT3duZXIgb3duZXIsIFhQYXRoVmlzaXRvciB2aXNpdG9yKQotICB7Ci0gICAgICAgIGFzc2VydGlvbihmYWxzZSwgImNhbGxWaXNpdG9ycyBzaG91bGQgbm90IGJlIGNhbGxlZCBmb3IgdGhpcyBvYmplY3QhISEiKTsKLSAgfQotICAvKioKLSAgICogQHNlZSBFeHByZXNzaW9uI2RlZXBFcXVhbHMoRXhwcmVzc2lvbikKLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGRlZXBFcXVhbHMoRXhwcmVzc2lvbiBleHByKQotICB7Ci0gICAgICAgIGlmKCFpc1NhbWVDbGFzcyhleHByKSkKLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0KLSAgICAgICAgLy8gSWYgZXF1YWxzIGF0IHRoZSBleHByZXNzaW9uIGxldmVsIGNhbGxzIGRlZXBFcXVhbHMsIEkgdGhpbmsgd2UncmUKLSAgICAgICAgLy8gc3RpbGwgc2FmZSBmcm9tIGluZmluaXRlIHJlY3Vyc2lvbiBzaW5jZSB0aGlzIG9iamVjdCBvdmVycmlkZXMKLSAgICAgICAgLy8gZXF1YWxzLiAgSSBob3BlLgotICAgICAgICBpZighdGhpcy5lcXVhbHMoKFhPYmplY3QpZXhwcikpCi0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotCi0gICAgICAgIHJldHVybiB0cnVlOwotICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvb2JqZWN0cy9YT2JqZWN0RmFjdG9yeS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9vYmplY3RzL1hPYmplY3RGYWN0b3J5LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGJmZDgzMDMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9vYmplY3RzL1hPYmplY3RGYWN0b3J5LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNjMgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogWE9iamVjdEZhY3RvcnkuamF2YSx2IDEuMS4yLjEgMjAwNS8wOC8wMSAwMToyOTozMCBqZWZmc3V0dG9yIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5BeGlzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1BeGlzSXRlcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNSXRlcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoQ29udGV4dDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuYXhlcy5PbmVTdGVwSXRlcmF0b3I7Ci0KLQotcHVibGljIGNsYXNzIFhPYmplY3RGYWN0b3J5Ci17Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSB0aGUgcmlnaHQgWE9iamVjdCBiYXNlZCBvbiB0aGUgdHlwZSBvZiB0aGUgb2JqZWN0IHBhc3NlZC4gIFRoaXMKLSAgICogZnVuY3Rpb24gY2FuIG5vdCBtYWtlIGFuIFhPYmplY3QgdGhhdCBleHBvc2VzIERPTSBOb2RlcywgTm9kZUxpc3RzLCBhbmQKLSAgICogTm9kZUl0ZXJhdG9ycyB0byB0aGUgWFNMVCBzdHlsZXNoZWV0IGFzIG5vZGUtc2V0cy4KLSAgICoKLSAgICogQHBhcmFtIHZhbCBUaGUgamF2YSBvYmplY3Qgd2hpY2ggdGhpcyBvYmplY3Qgd2lsbCB3cmFwLgotICAgKgotICAgKiBAcmV0dXJuIHRoZSByaWdodCBYT2JqZWN0IGJhc2VkIG9uIHRoZSB0eXBlIG9mIHRoZSBvYmplY3QgcGFzc2VkLgotICAgKi8KLSAgc3RhdGljIHB1YmxpYyBYT2JqZWN0IGNyZWF0ZShPYmplY3QgdmFsKQotICB7Ci0KLSAgICBYT2JqZWN0IHJlc3VsdDsKLQotICAgIGlmICh2YWwgaW5zdGFuY2VvZiBYT2JqZWN0KQotICAgIHsKLSAgICAgIHJlc3VsdCA9IChYT2JqZWN0KSB2YWw7Ci0gICAgfQotICAgIGVsc2UgaWYgKHZhbCBpbnN0YW5jZW9mIFN0cmluZykKLSAgICB7Ci0gICAgICByZXN1bHQgPSBuZXcgWFN0cmluZygoU3RyaW5nKSB2YWwpOwotICAgIH0KLSAgICBlbHNlIGlmICh2YWwgaW5zdGFuY2VvZiBCb29sZWFuKQotICAgIHsKLSAgICAgIHJlc3VsdCA9IG5ldyBYQm9vbGVhbigoQm9vbGVhbil2YWwpOwotICAgIH0KLSAgICBlbHNlIGlmICh2YWwgaW5zdGFuY2VvZiBEb3VibGUpCi0gICAgewotICAgICAgcmVzdWx0ID0gbmV3IFhOdW1iZXIoKChEb3VibGUpIHZhbCkpOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgcmVzdWx0ID0gbmV3IFhPYmplY3QodmFsKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gcmVzdWx0OwotICB9Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSB0aGUgcmlnaHQgWE9iamVjdCBiYXNlZCBvbiB0aGUgdHlwZSBvZiB0aGUgb2JqZWN0IHBhc3NlZC4KLSAgICogVGhpcyBmdW5jdGlvbiA8ZW1waD5jYW48L2VtcGg+IG1ha2UgYW4gWE9iamVjdCB0aGF0IGV4cG9zZXMgRE9NIE5vZGVzLCBOb2RlTGlzdHMsIGFuZAotICAgKiBOb2RlSXRlcmF0b3JzIHRvIHRoZSBYU0xUIHN0eWxlc2hlZXQgYXMgbm9kZS1zZXRzLgotICAgKgotICAgKiBAcGFyYW0gdmFsIFRoZSBqYXZhIG9iamVjdCB3aGljaCB0aGlzIG9iamVjdCB3aWxsIHdyYXAuCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgWFBhdGggY29udGV4dC4KLSAgICoKLSAgICogQHJldHVybiB0aGUgcmlnaHQgWE9iamVjdCBiYXNlZCBvbiB0aGUgdHlwZSBvZiB0aGUgb2JqZWN0IHBhc3NlZC4KLSAgICovCi0gIHN0YXRpYyBwdWJsaWMgWE9iamVjdCBjcmVhdGUoT2JqZWN0IHZhbCwgWFBhdGhDb250ZXh0IHhjdHh0KQotICB7Ci0KLSAgICBYT2JqZWN0IHJlc3VsdDsKLQotICAgIGlmICh2YWwgaW5zdGFuY2VvZiBYT2JqZWN0KQotICAgIHsKLSAgICAgIHJlc3VsdCA9IChYT2JqZWN0KSB2YWw7Ci0gICAgfQotICAgIGVsc2UgaWYgKHZhbCBpbnN0YW5jZW9mIFN0cmluZykKLSAgICB7Ci0gICAgICByZXN1bHQgPSBuZXcgWFN0cmluZygoU3RyaW5nKSB2YWwpOwotICAgIH0KLSAgICBlbHNlIGlmICh2YWwgaW5zdGFuY2VvZiBCb29sZWFuKQotICAgIHsKLSAgICAgIHJlc3VsdCA9IG5ldyBYQm9vbGVhbigoQm9vbGVhbil2YWwpOwotICAgIH0KLSAgICBlbHNlIGlmICh2YWwgaW5zdGFuY2VvZiBOdW1iZXIpCi0gICAgewotICAgICAgcmVzdWx0ID0gbmV3IFhOdW1iZXIoKChOdW1iZXIpIHZhbCkpOwotICAgIH0KLSAgICBlbHNlIGlmICh2YWwgaW5zdGFuY2VvZiBEVE0pCi0gICAgewotICAgICAgRFRNIGR0bSA9IChEVE0pdmFsOwotICAgICAgdHJ5Ci0gICAgICB7Ci0gICAgICAgIGludCBkdG1Sb290ID0gZHRtLmdldERvY3VtZW50KCk7Ci0gICAgICAgIERUTUF4aXNJdGVyYXRvciBpdGVyID0gZHRtLmdldEF4aXNJdGVyYXRvcihBeGlzLlNFTEYpOwotICAgICAgICBpdGVyLnNldFN0YXJ0Tm9kZShkdG1Sb290KTsKLSAgICAgICAgRFRNSXRlcmF0b3IgaXRlcmF0b3IgPSBuZXcgT25lU3RlcEl0ZXJhdG9yKGl0ZXIsIEF4aXMuU0VMRik7Ci0gICAgICAgIGl0ZXJhdG9yLnNldFJvb3QoZHRtUm9vdCwgeGN0eHQpOwotICAgICAgICByZXN1bHQgPSBuZXcgWE5vZGVTZXQoaXRlcmF0b3IpOwotICAgICAgfQotICAgICAgY2F0Y2goRXhjZXB0aW9uIGV4KQotICAgICAgewotICAgICAgICB0aHJvdyBuZXcgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5XcmFwcGVkUnVudGltZUV4Y2VwdGlvbihleCk7Ci0gICAgICB9Ci0gICAgfQotICAgIGVsc2UgaWYgKHZhbCBpbnN0YW5jZW9mIERUTUF4aXNJdGVyYXRvcikKLSAgICB7Ci0gICAgICBEVE1BeGlzSXRlcmF0b3IgaXRlciA9IChEVE1BeGlzSXRlcmF0b3IpdmFsOwotICAgICAgdHJ5Ci0gICAgICB7Ci0gICAgICAgIERUTUl0ZXJhdG9yIGl0ZXJhdG9yID0gbmV3IE9uZVN0ZXBJdGVyYXRvcihpdGVyLCBBeGlzLlNFTEYpOwotICAgICAgICBpdGVyYXRvci5zZXRSb290KGl0ZXIuZ2V0U3RhcnROb2RlKCksIHhjdHh0KTsKLSAgICAgICAgcmVzdWx0ID0gbmV3IFhOb2RlU2V0KGl0ZXJhdG9yKTsKLSAgICAgIH0KLSAgICAgIGNhdGNoKEV4Y2VwdGlvbiBleCkKLSAgICAgIHsKLSAgICAgICAgdGhyb3cgbmV3IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuV3JhcHBlZFJ1bnRpbWVFeGNlcHRpb24oZXgpOwotICAgICAgfQotICAgIH0KLSAgICBlbHNlIGlmICh2YWwgaW5zdGFuY2VvZiBEVE1JdGVyYXRvcikKLSAgICB7Ci0gICAgICByZXN1bHQgPSBuZXcgWE5vZGVTZXQoKERUTUl0ZXJhdG9yKSB2YWwpOwotICAgIH0KLSAgICAvLyBUaGlzIG5leHQgdGhyZWUgaW5zdGFuY2VvZnMgYXJlIGEgbGl0dGxlIHdvcnJ5c29tZSwgc2luY2UgYSBOb2RlTGlzdAotICAgIC8vIG1pZ2h0IGFsc28gaW1wbGVtZW50IGEgTm9kZSEKLSAgICBlbHNlIGlmICh2YWwgaW5zdGFuY2VvZiBvcmcudzNjLmRvbS5Ob2RlKQotICAgIHsKLSAgICAgIHJlc3VsdCA9IG5ldyBYTm9kZVNldEZvckRPTSgob3JnLnczYy5kb20uTm9kZSl2YWwsIHhjdHh0KTsKLSAgICB9Ci0gICAgLy8gVGhpcyBtdXN0IGNvbWUgYWZ0ZXIgb3JnLnczYy5kb20uTm9kZSwgc2luY2UgbWFueSBOb2RlIGltcGxlbWVudGF0aW9ucwotICAgIC8vIGFsc28gaW1wbGVtZW50IE5vZGVMaXN0LgotICAgIGVsc2UgaWYgKHZhbCBpbnN0YW5jZW9mIG9yZy53M2MuZG9tLk5vZGVMaXN0KQotICAgIHsKLSAgICAgIHJlc3VsdCA9IG5ldyBYTm9kZVNldEZvckRPTSgob3JnLnczYy5kb20uTm9kZUxpc3QpdmFsLCB4Y3R4dCk7Ci0gICAgfQotICAgIGVsc2UgaWYgKHZhbCBpbnN0YW5jZW9mIG9yZy53M2MuZG9tLnRyYXZlcnNhbC5Ob2RlSXRlcmF0b3IpCi0gICAgewotICAgICAgcmVzdWx0ID0gbmV3IFhOb2RlU2V0Rm9yRE9NKChvcmcudzNjLmRvbS50cmF2ZXJzYWwuTm9kZUl0ZXJhdG9yKXZhbCwgeGN0eHQpOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgcmVzdWx0ID0gbmV3IFhPYmplY3QodmFsKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gcmVzdWx0OwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL29iamVjdHMvWFJUcmVlRnJhZy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9vYmplY3RzL1hSVHJlZUZyYWcuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYWY3NzZmYy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL29iamVjdHMvWFJUcmVlRnJhZy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzAzICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFhSVHJlZUZyYWcuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNCAyMDo0NDo0OCBqZWZmc3V0dG9yIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE07Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNSXRlcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5YTUxTdHJpbmc7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLkV4cHJlc3Npb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLkV4cHJlc3Npb25Ob2RlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5YUGF0aENvbnRleHQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmF4ZXMuUlRGSXRlcmF0b3I7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlTGlzdDsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIHJlcHJlc2VudHMgYW4gWFBhdGggcmVzdWx0IHRyZWUgZnJhZ21lbnQgb2JqZWN0LCBhbmQgaXMgY2FwYWJsZSBvZgotICogY29udmVydGluZyB0aGUgUlRGIHRvIG90aGVyIHR5cGVzLCBzdWNoIGFzIGEgc3RyaW5nLgotICogQHhzbC51c2FnZSBnZW5lcmFsCi0gKi8KLXB1YmxpYyBjbGFzcyBYUlRyZWVGcmFnIGV4dGVuZHMgWE9iamVjdCBpbXBsZW1lbnRzIENsb25lYWJsZQotewotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMzIwMTU1MzgyMjI1NDkxMTU2N0w7Ci0gIHByaXZhdGUgRFRNWFJUcmVlRnJhZyBtX0RUTVhSVHJlZUZyYWc7Ci0gIHByaXZhdGUgaW50IG1fZHRtUm9vdCA9IERUTS5OVUxMOwotICBwcm90ZWN0ZWQgYm9vbGVhbiBtX2FsbG93UmVsZWFzZSA9IGZhbHNlOwotCi0KLSAgLyoqCi0gICAqIENyZWF0ZSBhbiBYUlRyZWVGcmFnIE9iamVjdC4KLSAgICoKLSAgICovCi0gIHB1YmxpYyBYUlRyZWVGcmFnKGludCByb290LCBYUGF0aENvbnRleHQgeGN0eHQsIEV4cHJlc3Npb25Ob2RlIHBhcmVudCkKLSAgewotICAgIHN1cGVyKG51bGwpOwotICAgIGV4cHJTZXRQYXJlbnQocGFyZW50KTsKLSAgICBpbml0RFRNKHJvb3QsIHhjdHh0KTsKLSAgfQotCi0gIC8qKgotICAgKiBDcmVhdGUgYW4gWFJUcmVlRnJhZyBPYmplY3QuCi0gICAqCi0gICAqLwotICBwdWJsaWMgWFJUcmVlRnJhZyhpbnQgcm9vdCwgWFBhdGhDb250ZXh0IHhjdHh0KQotICB7Ci0gICAgc3VwZXIobnVsbCk7Ci0gICBpbml0RFRNKHJvb3QsIHhjdHh0KTsKLSAgfQotCi0gIHByaXZhdGUgZmluYWwgdm9pZCBpbml0RFRNKGludCByb290LCBYUGF0aENvbnRleHQgeGN0eHQpewotICAgIG1fZHRtUm9vdCA9IHJvb3Q7Ci0gICAgZmluYWwgRFRNIGR0bSA9IHhjdHh0LmdldERUTShyb290KTsKLSAgICBpZihkdG0gIT0gbnVsbCl7Ci0gICAgICBtX0RUTVhSVHJlZUZyYWcgPSB4Y3R4dC5nZXREVE1YUlRyZWVGcmFnKHhjdHh0LmdldERUTUlkZW50aXR5KGR0bSkpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gYSBqYXZhIG9iamVjdCB0aGF0J3MgY2xvc2VzdCB0byB0aGUgcmVwcmVzZW50YXRpb24KLSAgICogdGhhdCBzaG91bGQgYmUgaGFuZGVkIHRvIGFuIGV4dGVuc2lvbi4KLSAgICoKLSAgICogQHJldHVybiBUaGUgb2JqZWN0IHRoYXQgdGhpcyBjbGFzcyB3cmFwcwotICAgKi8KLSAgcHVibGljIE9iamVjdCBvYmplY3QoKQotICB7Ci0gICAgaWYgKG1fRFRNWFJUcmVlRnJhZy5nZXRYUGF0aENvbnRleHQoKSAhPSBudWxsKQotICAgICAgcmV0dXJuIG5ldyBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5yZWYuRFRNTm9kZUl0ZXJhdG9yKChEVE1JdGVyYXRvcikobmV3IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5Ob2RlU2V0RFRNKG1fZHRtUm9vdCwgbV9EVE1YUlRyZWVGcmFnLmdldFhQYXRoQ29udGV4dCgpLmdldERUTU1hbmFnZXIoKSkpKTsKLSAgICBlbHNlCi0gICAgICByZXR1cm4gc3VwZXIub2JqZWN0KCk7Ci0gIH0KLQotICAvKioKLSAgICogQ3JlYXRlIGFuIFhSVHJlZUZyYWcgT2JqZWN0LgotICAgKgotICAgKi8KLSAgcHVibGljIFhSVHJlZUZyYWcoRXhwcmVzc2lvbiBleHByKQotICB7Ci0gICAgc3VwZXIoZXhwcik7Ci0gIH0KLQotICAvKioKLSAgICogU3BlY2lmeSBpZiBpdCdzIE9LIGZvciBkZXRhY2ggdG8gcmVsZWFzZSB0aGUgaXRlcmF0b3IgZm9yIHJldXNlLgotICAgKgotICAgKiBAcGFyYW0gYWxsb3dSZWxlYXNlIHRydWUgaWYgaXQgaXMgT0sgZm9yIGRldGFjaCB0byByZWxlYXNlIHRoaXMgaXRlcmF0b3IKLSAgICogZm9yIHBvb2xpbmcuCi0gICAqLwotICBwdWJsaWMgdm9pZCBhbGxvd0RldGFjaFRvUmVsZWFzZShib29sZWFuIGFsbG93UmVsZWFzZSkKLSAgewotICAgIG1fYWxsb3dSZWxlYXNlID0gYWxsb3dSZWxlYXNlOwotICB9Ci0KLSAgLyoqCi0gICAqIERldGFjaGVzIHRoZSA8Y29kZT5EVE1JdGVyYXRvcjwvY29kZT4gZnJvbSB0aGUgc2V0IHdoaWNoIGl0IGl0ZXJhdGVkCi0gICAqIG92ZXIsIHJlbGVhc2luZyBhbnkgY29tcHV0YXRpb25hbCByZXNvdXJjZXMgYW5kIHBsYWNpbmcgdGhlIGl0ZXJhdG9yCi0gICAqIGluIHRoZSBJTlZBTElEIHN0YXRlLiBBZnRlciA8Y29kZT5kZXRhY2g8L2NvZGU+IGhhcyBiZWVuIGludm9rZWQsCi0gICAqIGNhbGxzIHRvIDxjb2RlPm5leHROb2RlPC9jb2RlPiBvciA8Y29kZT5wcmV2aW91c05vZGU8L2NvZGU+IHdpbGwKLSAgICogcmFpc2UgYSBydW50aW1lIGV4Y2VwdGlvbi4KLSAgICoKLSAgICogSW4gZ2VuZXJhbCwgZGV0YWNoIHNob3VsZCBvbmx5IGJlIGNhbGxlZCBvbmNlIG9uIHRoZSBvYmplY3QuCi0gICAqLwotICBwdWJsaWMgdm9pZCBkZXRhY2goKXsKLSAgICBpZihtX2FsbG93UmVsZWFzZSl7Ci0gICAgICAgIG1fRFRNWFJUcmVlRnJhZy5kZXN0cnVjdCgpOwotICAgICAgc2V0T2JqZWN0KG51bGwpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIHdoYXQga2luZCBvZiBjbGFzcyB0aGlzIGlzLgotICAgKgotICAgKiBAcmV0dXJuIHR5cGUgQ0xBU1NfUlRSRUVGUkFHCi0gICAqLwotICBwdWJsaWMgaW50IGdldFR5cGUoKQotICB7Ci0gICAgcmV0dXJuIENMQVNTX1JUUkVFRlJBRzsKLSAgfQotCi0gIC8qKgotICAgKiBHaXZlbiBhIHJlcXVlc3QgdHlwZSwgcmV0dXJuIHRoZSBlcXVpdmFsZW50IHN0cmluZy4KLSAgICogRm9yIGRpYWdub3N0aWMgcHVycG9zZXMuCi0gICAqCi0gICAqIEByZXR1cm4gdHlwZSBzdHJpbmcgIiNSVFJFRUZSQUciCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFR5cGVTdHJpbmcoKQotICB7Ci0gICAgcmV0dXJuICIjUlRSRUVGUkFHIjsKLSAgfQotCi0gIC8qKgotICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYSBudW1iZXIuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHJlc3VsdCB0cmVlIGZyYWdtZW50IGFzIGEgbnVtYmVyIG9yIE5hTgotICAgKi8KLSAgcHVibGljIGRvdWJsZSBudW0oKQotICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIFhNTFN0cmluZyBzID0geHN0cigpOwotCi0gICAgcmV0dXJuIHMudG9Eb3VibGUoKTsKLSAgfQotCi0gIC8qKgotICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYSBib29sZWFuLiAgVGhpcyBhbHdheXMgcmV0dXJucyB0cnVlIGZvciBhIFJUcmVlRnJhZwotICAgKiBiZWNhdXNlIGl0IGlzIHRyZWF0ZWQgbGlrZSBhIG5vZGUtc2V0IHdpdGggYSBzaW5nbGUgcm9vdCBub2RlLgotICAgKgotICAgKiBAcmV0dXJuIHRydWUKLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGJvb2woKQotICB7Ci0gICAgcmV0dXJuIHRydWU7Ci0gIH0KLQotICBwcml2YXRlIFhNTFN0cmluZyBtX3htbFN0ciA9IG51bGw7Ci0KLSAgLyoqCi0gICAqIENhc3QgcmVzdWx0IG9iamVjdCB0byBhbiBYTUxTdHJpbmcuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGRvY3VtZW50IGZyYWdtZW50IG5vZGUgZGF0YSBvciB0aGUgZW1wdHkgc3RyaW5nLgotICAgKi8KLSAgcHVibGljIFhNTFN0cmluZyB4c3RyKCkKLSAgewotICAgIGlmKG51bGwgPT0gbV94bWxTdHIpCi0gICAgICBtX3htbFN0ciA9IG1fRFRNWFJUcmVlRnJhZy5nZXREVE0oKS5nZXRTdHJpbmdWYWx1ZShtX2R0bVJvb3QpOwotCi0gICAgcmV0dXJuIG1feG1sU3RyOwotICB9Ci0KLSAgLyoqCi0gICAqIENhc3QgcmVzdWx0IG9iamVjdCB0byBhIHN0cmluZy4KLSAgICoKLSAgICogQHJldHVybiBUaGUgc3RyaW5nIHRoaXMgd3JhcHMgb3IgdGhlIGVtcHR5IHN0cmluZyBpZiBudWxsCi0gICAqLwotICBwdWJsaWMgdm9pZCBhcHBlbmRUb0ZzYihjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLkZhc3RTdHJpbmdCdWZmZXIgZnNiKQotICB7Ci0gICAgWFN0cmluZyB4c3RyaW5nID0gKFhTdHJpbmcpeHN0cigpOwotICAgIHhzdHJpbmcuYXBwZW5kVG9Gc2IoZnNiKTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIENhc3QgcmVzdWx0IG9iamVjdCB0byBhIHN0cmluZy4KLSAgICoKLSAgICogQHJldHVybiBUaGUgZG9jdW1lbnQgZnJhZ21lbnQgbm9kZSBkYXRhIG9yIHRoZSBlbXB0eSBzdHJpbmcuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIHN0cigpCi0gIHsKLSAgICBTdHJpbmcgc3RyID0gbV9EVE1YUlRyZWVGcmFnLmdldERUTSgpLmdldFN0cmluZ1ZhbHVlKG1fZHRtUm9vdCkudG9TdHJpbmcoKTsKLQotICAgIHJldHVybiAobnVsbCA9PSBzdHIpID8gIiIgOiBzdHI7Ci0gIH0KLQotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGEgcmVzdWx0IHRyZWUgZnJhZ21lbnQuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGRvY3VtZW50IGZyYWdtZW50IHRoaXMgd3JhcHMKLSAgICovCi0gIHB1YmxpYyBpbnQgcnRmKCkKLSAgewotICAgIHJldHVybiBtX2R0bVJvb3Q7Ci0gIH0KLQotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGEgRFRNSXRlcmF0b3IuCi0gICAqIGRtbCAtIG1vZGlmaWVkIHRvIHJldHVybiBhbiBSVEZJdGVyYXRvciBmb3IKLSAgICogYmVuZWZpdCBvZiBFWFNMVCBvYmplY3QtdHlwZSBmdW5jdGlvbiBpbgotICAgKiB7QGxpbmsgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLmxpYi5FeHNsdENvbW1vbn0uCi0gICAqIEByZXR1cm4gVGhlIGRvY3VtZW50IGZyYWdtZW50IGFzIGEgRFRNSXRlcmF0b3IKLSAgICovCi0gIHB1YmxpYyBEVE1JdGVyYXRvciBhc05vZGVJdGVyYXRvcigpCi0gIHsKLSAgICByZXR1cm4gbmV3IFJURkl0ZXJhdG9yKG1fZHRtUm9vdCwgbV9EVE1YUlRyZWVGcmFnLmdldFhQYXRoQ29udGV4dCgpLmdldERUTU1hbmFnZXIoKSk7Ci0gIH0KLQotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGEgbm9kZWxpc3QuIChzcGVjaWFsIGZ1bmN0aW9uKS4KLSAgICoKLSAgICogQHJldHVybiBUaGUgZG9jdW1lbnQgZnJhZ21lbnQgYXMgYSBub2RlbGlzdAotICAgKi8KLSAgcHVibGljIE5vZGVMaXN0IGNvbnZlcnRUb05vZGVzZXQoKQotICB7Ci0KLSAgICBpZiAobV9vYmogaW5zdGFuY2VvZiBOb2RlTGlzdCkKLSAgICAgIHJldHVybiAoTm9kZUxpc3QpIG1fb2JqOwotICAgIGVsc2UKLSAgICAgIHJldHVybiBuZXcgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0ucmVmLkRUTU5vZGVMaXN0KGFzTm9kZUl0ZXJhdG9yKCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgdHdvIG9iamVjdHMgYXJlIGZ1bmN0aW9uYWxseSBlcXVhbC4KLSAgICoKLSAgICogQHBhcmFtIG9iajIgT2JqZWN0IHRvIGNvbXBhcmUgdGhpcyB0bwotICAgKgotICAgKiBAcmV0dXJuIFRydWUgaWYgdGhlIHR3byBvYmplY3RzIGFyZSBlcXVhbAotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGVxdWFscyhYT2JqZWN0IG9iajIpCi0gIHsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIGlmIChYT2JqZWN0LkNMQVNTX05PREVTRVQgPT0gb2JqMi5nZXRUeXBlKCkpCi0gICAgICB7Ci0KLSAgICAgICAgLy8gSW4gb3JkZXIgdG8gaGFuZGxlIHRoZSAnYWxsJyBzZW1hbnRpY3Mgb2YKLSAgICAgICAgLy8gbm9kZXNldCBjb21wYXJpc29ucywgd2UgYWx3YXlzIGNhbGwgdGhlCi0gICAgICAgIC8vIG5vZGVzZXQgZnVuY3Rpb24uCi0gICAgICAgIHJldHVybiBvYmoyLmVxdWFscyh0aGlzKTsKLSAgICAgIH0KLSAgICAgIGVsc2UgaWYgKFhPYmplY3QuQ0xBU1NfQk9PTEVBTiA9PSBvYmoyLmdldFR5cGUoKSkKLSAgICAgIHsKLSAgICAgICAgcmV0dXJuIGJvb2woKSA9PSBvYmoyLmJvb2woKTsKLSAgICAgIH0KLSAgICAgIGVsc2UgaWYgKFhPYmplY3QuQ0xBU1NfTlVNQkVSID09IG9iajIuZ2V0VHlwZSgpKQotICAgICAgewotICAgICAgICByZXR1cm4gbnVtKCkgPT0gb2JqMi5udW0oKTsKLSAgICAgIH0KLSAgICAgIGVsc2UgaWYgKFhPYmplY3QuQ0xBU1NfTk9ERVNFVCA9PSBvYmoyLmdldFR5cGUoKSkKLSAgICAgIHsKLSAgICAgICAgcmV0dXJuIHhzdHIoKS5lcXVhbHMob2JqMi54c3RyKCkpOwotICAgICAgfQotICAgICAgZWxzZSBpZiAoWE9iamVjdC5DTEFTU19TVFJJTkcgPT0gb2JqMi5nZXRUeXBlKCkpCi0gICAgICB7Ci0gICAgICAgIHJldHVybiB4c3RyKCkuZXF1YWxzKG9iajIueHN0cigpKTsKLSAgICAgIH0KLSAgICAgIGVsc2UgaWYgKFhPYmplY3QuQ0xBU1NfUlRSRUVGUkFHID09IG9iajIuZ2V0VHlwZSgpKQotICAgICAgewotCi0gICAgICAgIC8vIFByb2JhYmx5IG5vdCBzbyBnb29kLiAgVGhpbmsgYWJvdXQgdGhpcy4KLSAgICAgICAgcmV0dXJuIHhzdHIoKS5lcXVhbHMob2JqMi54c3RyKCkpOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iajIpOwotICAgICAgfQotICAgIH0KLSAgICBjYXRjaChqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uIHRlKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLldyYXBwZWRSdW50aW1lRXhjZXB0aW9uKHRlKTsKLSAgICB9Ci0gIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9vYmplY3RzL1hSVHJlZUZyYWdTZWxlY3RXcmFwcGVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL29iamVjdHMvWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZTYxOGY3NS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL29iamVjdHMvWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE1NiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlci5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE1IDAyOjAyOjM1IGplZmZzdXR0b3IgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0czsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC5yZXMuWFNMTWVzc2FnZXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNSXRlcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5YTUxTdHJpbmc7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLkV4cHJlc3Npb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoQ29udGV4dDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucmVzLlhQQVRIRXJyb3JSZXNvdXJjZXM7Ci0KLS8qKgotICogVGhpcyBjbGFzcyBtYWtlcyBhbiBzZWxlY3Qgc3RhdGVtZW50IGFjdCBsaWtlIGFuIHJlc3VsdCB0cmVlIGZyYWdtZW50LgotICovCi1wdWJsaWMgY2xhc3MgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIgZXh0ZW5kcyBYUlRyZWVGcmFnIGltcGxlbWVudHMgQ2xvbmVhYmxlCi17Ci0gICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC02NTI2MTc3OTA1NTkwNDYxMjUxTDsKLSAgcHVibGljIFhSVHJlZUZyYWdTZWxlY3RXcmFwcGVyKEV4cHJlc3Npb24gZXhwcikKLSAgewotICAgIHN1cGVyKGV4cHIpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoaXMgZnVuY3Rpb24gaXMgdXNlZCB0byBmaXh1cCB2YXJpYWJsZXMgZnJvbSBRTmFtZXMgdG8gc3RhY2sgZnJhbWUKLSAgICogaW5kZXhlcyBhdCBzdHlsZXNoZWV0IGJ1aWxkIHRpbWUuCi0gICAqIEBwYXJhbSB2YXJzIExpc3Qgb2YgUU5hbWVzIHRoYXQgY29ycmVzcG9uZCB0byB2YXJpYWJsZXMuICBUaGlzIGxpc3QKLSAgICogc2hvdWxkIGJlIHNlYXJjaGVkIGJhY2t3YXJkcyBmb3IgdGhlIGZpcnN0IHF1YWxpZmllZCBuYW1lIHRoYXQKLSAgICogY29ycmVzcG9uZHMgdG8gdGhlIHZhcmlhYmxlIHJlZmVyZW5jZSBxbmFtZS4gIFRoZSBwb3NpdGlvbiBvZiB0aGUKLSAgICogUU5hbWUgaW4gdGhlIHZlY3RvciBmcm9tIHRoZSBzdGFydCBvZiB0aGUgdmVjdG9yIHdpbGwgYmUgaXRzIHBvc2l0aW9uCi0gICAqIGluIHRoZSBzdGFjayBmcmFtZSAoYnV0IHZhcmlhYmxlcyBhYm92ZSB0aGUgZ2xvYmFsc1RvcCB2YWx1ZSB3aWxsIG5lZWQKLSAgICogdG8gYmUgb2Zmc2V0IHRvIHRoZSBjdXJyZW50IHN0YWNrIGZyYW1lKS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGZpeHVwVmFyaWFibGVzKGphdmEudXRpbC5WZWN0b3IgdmFycywgaW50IGdsb2JhbHNTaXplKQotICB7Ci0gICAgKChFeHByZXNzaW9uKW1fb2JqKS5maXh1cFZhcmlhYmxlcyh2YXJzLCBnbG9iYWxzU2l6ZSk7Ci0gIH0KLQotICAvKioKLSAgICogRm9yIHN1cHBvcnQgb2YgbGl0ZXJhbCBvYmplY3RzIGluIHhwYXRocy4KLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IFRoZSBYUGF0aCBleGVjdXRpb24gY29udGV4dC4KLSAgICoKLSAgICogQHJldHVybiB0aGUgcmVzdWx0IG9mIGV4ZWN1dGluZyB0aGUgc2VsZWN0IGV4cHJlc3Npb24KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBleGVjdXRlKFhQYXRoQ29udGV4dCB4Y3R4dCkKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgICAgICBYT2JqZWN0IG1fc2VsZWN0ZWQ7Ci0gICAgIG1fc2VsZWN0ZWQgPSAoKEV4cHJlc3Npb24pbV9vYmopLmV4ZWN1dGUoeGN0eHQpOwotICAgICBtX3NlbGVjdGVkLmFsbG93RGV0YWNoVG9SZWxlYXNlKG1fYWxsb3dSZWxlYXNlKTsKLSAgICAgaWYgKG1fc2VsZWN0ZWQuZ2V0VHlwZSgpID09IENMQVNTX1NUUklORykKLSAgICAgICByZXR1cm4gbV9zZWxlY3RlZDsKLSAgICAgZWxzZQotICAgICAgIHJldHVybiBuZXcgWFN0cmluZyhtX3NlbGVjdGVkLnN0cigpKTsKLSAgfQotCi0gIC8qKgotICAgKiBEZXRhY2hlcyB0aGUgPGNvZGU+RFRNSXRlcmF0b3I8L2NvZGU+IGZyb20gdGhlIHNldCB3aGljaCBpdCBpdGVyYXRlZAotICAgKiBvdmVyLCByZWxlYXNpbmcgYW55IGNvbXB1dGF0aW9uYWwgcmVzb3VyY2VzIGFuZCBwbGFjaW5nIHRoZSBpdGVyYXRvcgotICAgKiBpbiB0aGUgSU5WQUxJRCBzdGF0ZS4gQWZ0ZXIgPGNvZGU+ZGV0YWNoPC9jb2RlPiBoYXMgYmVlbiBpbnZva2VkLAotICAgKiBjYWxscyB0byA8Y29kZT5uZXh0Tm9kZTwvY29kZT4gb3IgPGNvZGU+cHJldmlvdXNOb2RlPC9jb2RlPiB3aWxsCi0gICAqIHJhaXNlIGEgcnVudGltZSBleGNlcHRpb24uCi0gICAqCi0gICAqIEluIGdlbmVyYWwsIGRldGFjaCBzaG91bGQgb25seSBiZSBjYWxsZWQgb25jZSBvbiB0aGUgb2JqZWN0LgotICAgKi8KLSAgcHVibGljIHZvaWQgZGV0YWNoKCkKLSAgewotICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoWFBBVEhFcnJvclJlc291cmNlcy5FUl9ERVRBQ0hfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiwgbnVsbCkpOyAvLyJkZXRhY2goKSBub3Qgc3VwcG9ydGVkIGJ5IFhSVHJlZUZyYWdTZWxlY3RXcmFwcGVyISIpOwotICB9Ci0KLSAgLyoqCi0gICAqIENhc3QgcmVzdWx0IG9iamVjdCB0byBhIG51bWJlci4KLSAgICoKLSAgICogQHJldHVybiBUaGUgcmVzdWx0IHRyZWUgZnJhZ21lbnQgYXMgYSBudW1iZXIgb3IgTmFOCi0gICAqLwotICBwdWJsaWMgZG91YmxlIG51bSgpCi0gICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShYUEFUSEVycm9yUmVzb3VyY2VzLkVSX05VTV9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSLCBudWxsKSk7IC8vIm51bSgpIG5vdCBzdXBwb3J0ZWQgYnkgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIhIik7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYW4gWE1MU3RyaW5nLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBkb2N1bWVudCBmcmFnbWVudCBub2RlIGRhdGEgb3IgdGhlIGVtcHR5IHN0cmluZy4KLSAgICovCi0gIHB1YmxpYyBYTUxTdHJpbmcgeHN0cigpCi0gIHsKLSAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfWFNUUl9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSLCBudWxsKSk7IC8vInhzdHIoKSBub3Qgc3VwcG9ydGVkIGJ5IFhSVHJlZUZyYWdTZWxlY3RXcmFwcGVyISIpOwotICB9Ci0KLSAgLyoqCi0gICAqIENhc3QgcmVzdWx0IG9iamVjdCB0byBhIHN0cmluZy4KLSAgICoKLSAgICogQHJldHVybiBUaGUgZG9jdW1lbnQgZnJhZ21lbnQgbm9kZSBkYXRhIG9yIHRoZSBlbXB0eSBzdHJpbmcuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIHN0cigpCi0gIHsKLSAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfU1RSX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIsIG51bGwpKTsgLy8ic3RyKCkgbm90IHN1cHBvcnRlZCBieSBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciEiKTsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIHdoYXQga2luZCBvZiBjbGFzcyB0aGlzIGlzLgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBzdHJpbmcgdHlwZQotICAgKi8KLSAgcHVibGljIGludCBnZXRUeXBlKCkKLSAgewotICAgIHJldHVybiBDTEFTU19TVFJJTkc7Ci0gIH0KLQotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGEgcmVzdWx0IHRyZWUgZnJhZ21lbnQuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGRvY3VtZW50IGZyYWdtZW50IHRoaXMgd3JhcHMKLSAgICovCi0gIHB1YmxpYyBpbnQgcnRmKCkKLSAgewotICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShYUEFUSEVycm9yUmVzb3VyY2VzLkVSX1JURl9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSLCBudWxsKSk7IC8vInJ0ZigpIG5vdCBzdXBwb3J0ZWQgYnkgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIhIik7Ci0gIH0KLQotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGEgRFRNSXRlcmF0b3IuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGRvY3VtZW50IGZyYWdtZW50IGFzIGEgRFRNSXRlcmF0b3IKLSAgICovCi0gIHB1YmxpYyBEVE1JdGVyYXRvciBhc05vZGVJdGVyYXRvcigpCi0gIHsKLSAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoWFBBVEhFcnJvclJlc291cmNlcy5FUl9SVEZfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiwgbnVsbCkpOyAvLyJhc05vZGVJdGVyYXRvcigpIG5vdCBzdXBwb3J0ZWQgYnkgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIhIik7Ci0gIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9vYmplY3RzL1hTdHJpbmcuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvb2JqZWN0cy9YU3RyaW5nLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDBmZjJiNTUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9vYmplY3RzL1hTdHJpbmcuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExMjQgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogWFN0cmluZy5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE0IDIwOjQ3OjIwIGplZmZzdXR0b3IgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0czsKLQotaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE07Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5YTUxDaGFyYWN0ZXJSZWNvZ25pemVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuWE1MU3RyaW5nOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuWE1MU3RyaW5nRmFjdG9yeTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuRXhwcmVzc2lvbk93bmVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5YUGF0aENvbnRleHQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoVmlzaXRvcjsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIHJlcHJlc2VudHMgYW4gWFBhdGggc3RyaW5nIG9iamVjdCwgYW5kIGlzIGNhcGFibGUgb2YKLSAqIGNvbnZlcnRpbmcgdGhlIHN0cmluZyB0byBvdGhlciB0eXBlcywgc3VjaCBhcyBhIG51bWJlci4KLSAqIEB4c2wudXNhZ2UgZ2VuZXJhbAotICovCi1wdWJsaWMgY2xhc3MgWFN0cmluZyBleHRlbmRzIFhPYmplY3QgaW1wbGVtZW50cyBYTUxTdHJpbmcKLXsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMjAyMDQ3MDUxODM5NTA5NDUyNUw7Ci0KLSAgLyoqIEVtcHR5IHN0cmluZyBYU3RyaW5nIG9iamVjdCAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFhTdHJpbmcgRU1QVFlTVFJJTkcgPSBuZXcgWFN0cmluZygiIik7Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhIFhTdHJpbmcgb2JqZWN0LiAgVGhpcyBjb25zdHJ1Y3RvciBleGlzdHMgZm9yIGRlcml2ZWQgY2xhc3Nlcy4KLSAgICoKLSAgICogQHBhcmFtIHZhbCBTdHJpbmcgb2JqZWN0IHRoaXMgd2lsbCB3cmFwLgotICAgKi8KLSAgcHJvdGVjdGVkIFhTdHJpbmcoT2JqZWN0IHZhbCkKLSAgewotICAgIHN1cGVyKHZhbCk7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgWE5vZGVTZXQgb2JqZWN0LgotICAgKgotICAgKiBAcGFyYW0gdmFsIFN0cmluZyBvYmplY3QgdGhpcyB3aWxsIHdyYXAuCi0gICAqLwotICBwdWJsaWMgWFN0cmluZyhTdHJpbmcgdmFsKQotICB7Ci0gICAgc3VwZXIodmFsKTsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIHRoYXQgdGhpcyBpcyBhIENMQVNTX1NUUklORy4KLSAgICoKLSAgICogQHJldHVybiB0eXBlIENMQVNTX1NUUklORwotICAgKi8KLSAgcHVibGljIGludCBnZXRUeXBlKCkKLSAgewotICAgIHJldHVybiBDTEFTU19TVFJJTkc7Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYSByZXF1ZXN0IHR5cGUsIHJldHVybiB0aGUgZXF1aXZhbGVudCBzdHJpbmcuCi0gICAqIEZvciBkaWFnbm9zdGljIHB1cnBvc2VzLgotICAgKgotICAgKiBAcmV0dXJuIHR5cGUgc3RyaW5nICIjU1RSSU5HIgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRUeXBlU3RyaW5nKCkKLSAgewotICAgIHJldHVybiAiI1NUUklORyI7Ci0gIH0KLQotICAvKioKLSAgICogVGVsbCBpZiB0aGlzIG9iamVjdCBjb250YWlucyBhIGphdmEgU3RyaW5nIG9iamVjdC4KLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHRoaXMgWE1MU3RyaW5nIGNhbiByZXR1cm4gYSBzdHJpbmcgd2l0aG91dCBjcmVhdGluZyBvbmUuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBoYXNTdHJpbmcoKQotICB7Ci0gICAgcmV0dXJuIHRydWU7Ci0gIH0KLQotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGEgbnVtYmVyLgotICAgKgotICAgKiBAcmV0dXJuIDAuMCBpZiB0aGlzIHN0cmluZyBpcyBudWxsLCBudW1lcmljIHZhbHVlIG9mIHRoaXMgc3RyaW5nCi0gICAqIG9yIE5hTgotICAgKi8KLSAgcHVibGljIGRvdWJsZSBudW0oKQotICB7Ci0gICAgcmV0dXJuIHRvRG91YmxlKCk7Ci0gIH0KLQotICAvKioKLSAgICogQ29udmVydCBhIHN0cmluZyB0byBhIGRvdWJsZSAtLSBBbGxvd2VkIGlucHV0IGlzIGluIGZpeGVkCi0gICAqIG5vdGF0aW9uIGRkZC5mZmYuCi0gICAqCi0gICAqIEByZXR1cm4gQSBkb3VibGUgdmFsdWUgcmVwcmVzZW50YXRpb24gb2YgdGhlIHN0cmluZywgb3IgcmV0dXJuIERvdWJsZS5OYU4KLSAgICogaWYgdGhlIHN0cmluZyBjYW4gbm90IGJlIGNvbnZlcnRlZC4KLSAgICovCi0gIHB1YmxpYyBkb3VibGUgdG9Eb3VibGUoKQotICB7Ci0gICAgLyogWE1MQ2hhcmFjdGVyUmVjb2duaXplci5pc1doaXRlU3BhY2UoY2hhciBjKSBtZXRob2RzIHRyZWF0cyB0aGUgZm9sbG93aW5nCi0gICAgICogY2hhcmFjdGVycyBhcyB3aGl0ZSBzcGFjZSBjaGFyYWN0ZXJzLgotICAgICAqIGh0IC0gaG9yaXpvbnRhbCB0YWIsIG5sIC0gbmV3bGluZSAsIGNyIC0gY2FycmlhZ2UgcmV0dXJuIGFuZCBzcCAtIHNwYWNlCi0gICAgICogdHJpbSgpIG1ldGhvZHMgYnkgZGVmYXVsdCBhbHNvIHRha2VzIGNhcmUgb2YgdGhlc2Ugd2hpdGUgc3BhY2UgY2hhcmFjdGVycwotICAgICAqIFNvIHRyaW0oKSBtZXRob2QgaXMgdXNlZCB0byByZW1vdmUgbGVhZGluZyBhbmQgdHJhaWxpbmcgd2hpdGUgc3BhY2VzLgotICAgICAqLwotICAgICAgICBYTUxTdHJpbmcgcyA9IHRyaW0oKTsKLSAgICAgICAgZG91YmxlIHJlc3VsdCA9IERvdWJsZS5OYU47Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcy5sZW5ndGgoKTsgaSsrKQotICAgICAgICB7Ci0gICAgICAgICAgICAgICAgY2hhciBjID0gcy5jaGFyQXQoaSk7Ci0gICAgaWYgKGMgIT0gJy0nICYmIGMgIT0gJy4nICYmICggYyA8IDBYMzAgfHwgYyA+IDB4MzkpKSB7Ci0gICAgICAgICAgICAvLyBUaGUgY2hhcmFjdGVyIGlzIG5vdCBhICctJyBvciBhICcuJyBvciBhIGRpZ2l0Ci0gICAgICAgICAgICAvLyB0aGVuIHJldHVybiBOYU4gYmVjYXVzZSBzb21ldGhpbmcgaXMgd3JvbmcuCi0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0OwotICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgdHJ5Ci0gICAgICAgIHsKLSAgICAgICAgICAgICAgICByZXN1bHQgPSBEb3VibGUucGFyc2VEb3VibGUocy50b1N0cmluZygpKTsKLSAgICAgICAgfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGUpe30KLQotICAgICAgICByZXR1cm4gcmVzdWx0OwotfQotCi0gIC8qKgotICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYSBib29sZWFuLgotICAgKgotICAgKiBAcmV0dXJuIFRydWUgaWYgdGhlIGxlbmd0aCBvZiB0aGlzIHN0cmluZyBvYmplY3QgaXMgZ3JlYXRlcgotICAgKiB0aGFuIDAuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBib29sKCkKLSAgewotICAgIHJldHVybiBzdHIoKS5sZW5ndGgoKSA+IDA7Ci0gIH0KLQotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGEgc3RyaW5nLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBzdHJpbmcgdGhpcyB3cmFwcyBvciB0aGUgZW1wdHkgc3RyaW5nIGlmIG51bGwKLSAgICovCi0gIHB1YmxpYyBYTUxTdHJpbmcgeHN0cigpCi0gIHsKLSAgICByZXR1cm4gdGhpczsKLSAgfQotCi0gIC8qKgotICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYSBzdHJpbmcuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHN0cmluZyB0aGlzIHdyYXBzIG9yIHRoZSBlbXB0eSBzdHJpbmcgaWYgbnVsbAotICAgKi8KLSAgcHVibGljIFN0cmluZyBzdHIoKQotICB7Ci0gICAgcmV0dXJuIChudWxsICE9IG1fb2JqKSA/ICgoU3RyaW5nKSBtX29iaikgOiAiIjsKLSAgfQotCi0gIC8qKgotICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYSByZXN1bHQgdHJlZSBmcmFnbWVudC4KLSAgICoKLSAgICogQHBhcmFtIHN1cHBvcnQgWHBhdGggY29udGV4dCB0byB1c2UgZm9yIHRoZSBjb252ZXJzaW9uCi0gICAqCi0gICAqIEByZXR1cm4gQSBkb2N1bWVudCBmcmFnbWVudCB3aXRoIHRoaXMgc3RyaW5nIGFzIGEgY2hpbGQgbm9kZQotICAgKi8KLSAgcHVibGljIGludCBydGYoWFBhdGhDb250ZXh0IHN1cHBvcnQpCi0gIHsKLQotICAgIERUTSBmcmFnID0gc3VwcG9ydC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7Ci0KLSAgICBmcmFnLmFwcGVuZFRleHRDaGlsZChzdHIoKSk7Ci0KLSAgICByZXR1cm4gZnJhZy5nZXREb2N1bWVudCgpOwotICB9Ci0KLSAgLyoqCi0gICAqIERpcmVjdGx5IGNhbGwgdGhlCi0gICAqIGNoYXJhY3RlcnMgbWV0aG9kIG9uIHRoZSBwYXNzZWQgQ29udGVudEhhbmRsZXIgZm9yIHRoZQotICAgKiBzdHJpbmctdmFsdWUuIE11bHRpcGxlIGNhbGxzIHRvIHRoZQotICAgKiBDb250ZW50SGFuZGxlcidzIGNoYXJhY3RlcnMgbWV0aG9kcyBtYXkgd2VsbCBvY2N1ciBmb3IgYSBzaW5nbGUgY2FsbCB0bwotICAgKiB0aGlzIG1ldGhvZC4KLSAgICoKLSAgICogQHBhcmFtIGNoIEEgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGEgQ29udGVudEhhbmRsZXIuCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBkaXNwYXRjaENoYXJhY3RlcnNFdmVudHMob3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIgY2gpCi0gICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICBTdHJpbmcgc3RyID0gc3RyKCk7Ci0KLSAgICBjaC5jaGFyYWN0ZXJzKHN0ci50b0NoYXJBcnJheSgpLCAwLCBzdHIubGVuZ3RoKCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIERpcmVjdGx5IGNhbGwgdGhlCi0gICAqIGNvbW1lbnQgbWV0aG9kIG9uIHRoZSBwYXNzZWQgTGV4aWNhbEhhbmRsZXIgZm9yIHRoZQotICAgKiBzdHJpbmctdmFsdWUuCi0gICAqCi0gICAqIEBwYXJhbSBsaCBBIG5vbi1udWxsIHJlZmVyZW5jZSB0byBhIExleGljYWxIYW5kbGVyLgotICAgKgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgZGlzcGF0Y2hBc0NvbW1lbnQob3JnLnhtbC5zYXguZXh0LkxleGljYWxIYW5kbGVyIGxoKQotICAgICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgU3RyaW5nIHN0ciA9IHN0cigpOwotCi0gICAgbGguY29tbWVudChzdHIudG9DaGFyQXJyYXkoKSwgMCwgc3RyLmxlbmd0aCgpKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBsZW5ndGggb2YgdGhpcyBzdHJpbmcuCi0gICAqCi0gICAqIEByZXR1cm4gIHRoZSBsZW5ndGggb2YgdGhlIHNlcXVlbmNlIG9mIGNoYXJhY3RlcnMgcmVwcmVzZW50ZWQgYnkgdGhpcwotICAgKiAgICAgICAgICBvYmplY3QuCi0gICAqLwotICBwdWJsaWMgaW50IGxlbmd0aCgpCi0gIHsKLSAgICByZXR1cm4gc3RyKCkubGVuZ3RoKCk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgY2hhcmFjdGVyIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXguIEFuIGluZGV4IHJhbmdlcwotICAgKiBmcm9tIDxjb2RlPjA8L2NvZGU+IHRvIDxjb2RlPmxlbmd0aCgpIC0gMTwvY29kZT4uIFRoZSBmaXJzdCBjaGFyYWN0ZXIKLSAgICogb2YgdGhlIHNlcXVlbmNlIGlzIGF0IGluZGV4IDxjb2RlPjA8L2NvZGU+LCB0aGUgbmV4dCBhdCBpbmRleAotICAgKiA8Y29kZT4xPC9jb2RlPiwgYW5kIHNvIG9uLCBhcyBmb3IgYXJyYXkgaW5kZXhpbmcuCi0gICAqCi0gICAqIEBwYXJhbSAgICAgIGluZGV4ICAgdGhlIGluZGV4IG9mIHRoZSBjaGFyYWN0ZXIuCi0gICAqIEByZXR1cm4gICAgIHRoZSBjaGFyYWN0ZXIgYXQgdGhlIHNwZWNpZmllZCBpbmRleCBvZiB0aGlzIHN0cmluZy4KLSAgICogICAgICAgICAgICAgVGhlIGZpcnN0IGNoYXJhY3RlciBpcyBhdCBpbmRleCA8Y29kZT4wPC9jb2RlPi4KLSAgICogQGV4Y2VwdGlvbiAgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiAgaWYgdGhlIDxjb2RlPmluZGV4PC9jb2RlPgotICAgKiAgICAgICAgICAgICBhcmd1bWVudCBpcyBuZWdhdGl2ZSBvciBub3QgbGVzcyB0aGFuIHRoZSBsZW5ndGggb2YgdGhpcwotICAgKiAgICAgICAgICAgICBzdHJpbmcuCi0gICAqLwotICBwdWJsaWMgY2hhciBjaGFyQXQoaW50IGluZGV4KQotICB7Ci0gICAgcmV0dXJuIHN0cigpLmNoYXJBdChpbmRleCk7Ci0gIH0KLQotICAvKioKLSAgICogQ29waWVzIGNoYXJhY3RlcnMgZnJvbSB0aGlzIHN0cmluZyBpbnRvIHRoZSBkZXN0aW5hdGlvbiBjaGFyYWN0ZXIKLSAgICogYXJyYXkuCi0gICAqCi0gICAqIEBwYXJhbSAgICAgIHNyY0JlZ2luICAgaW5kZXggb2YgdGhlIGZpcnN0IGNoYXJhY3RlciBpbiB0aGUgc3RyaW5nCi0gICAqICAgICAgICAgICAgICAgICAgICAgICAgdG8gY29weS4KLSAgICogQHBhcmFtICAgICAgc3JjRW5kICAgICBpbmRleCBhZnRlciB0aGUgbGFzdCBjaGFyYWN0ZXIgaW4gdGhlIHN0cmluZwotICAgKiAgICAgICAgICAgICAgICAgICAgICAgIHRvIGNvcHkuCi0gICAqIEBwYXJhbSAgICAgIGRzdCAgICAgICAgdGhlIGRlc3RpbmF0aW9uIGFycmF5LgotICAgKiBAcGFyYW0gICAgICBkc3RCZWdpbiAgIHRoZSBzdGFydCBvZmZzZXQgaW4gdGhlIGRlc3RpbmF0aW9uIGFycmF5LgotICAgKiBAZXhjZXB0aW9uIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gSWYgYW55IG9mIHRoZSBmb2xsb3dpbmcKLSAgICogICAgICAgICAgICBpcyB0cnVlOgotICAgKiAgICAgICAgICAgIDx1bD48bGk+PGNvZGU+c3JjQmVnaW48L2NvZGU+IGlzIG5lZ2F0aXZlLgotICAgKiAgICAgICAgICAgIDxsaT48Y29kZT5zcmNCZWdpbjwvY29kZT4gaXMgZ3JlYXRlciB0aGFuIDxjb2RlPnNyY0VuZDwvY29kZT4KLSAgICogICAgICAgICAgICA8bGk+PGNvZGU+c3JjRW5kPC9jb2RlPiBpcyBncmVhdGVyIHRoYW4gdGhlIGxlbmd0aCBvZiB0aGlzCi0gICAqICAgICAgICAgICAgICAgIHN0cmluZwotICAgKiAgICAgICAgICAgIDxsaT48Y29kZT5kc3RCZWdpbjwvY29kZT4gaXMgbmVnYXRpdmUKLSAgICogICAgICAgICAgICA8bGk+PGNvZGU+ZHN0QmVnaW4rKHNyY0VuZC1zcmNCZWdpbik8L2NvZGU+IGlzIGxhcmdlciB0aGFuCi0gICAqICAgICAgICAgICAgICAgIDxjb2RlPmRzdC5sZW5ndGg8L2NvZGU+PC91bD4KLSAgICogQGV4Y2VwdGlvbiBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiA8Y29kZT5kc3Q8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+Ci0gICAqLwotICBwdWJsaWMgdm9pZCBnZXRDaGFycyhpbnQgc3JjQmVnaW4sIGludCBzcmNFbmQsIGNoYXIgZHN0W10sIGludCBkc3RCZWdpbikKLSAgewotICAgIHN0cigpLmdldENoYXJzKHNyY0JlZ2luLCBzcmNFbmQsIGRzdCwgZHN0QmVnaW4pOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgdHdvIG9iamVjdHMgYXJlIGZ1bmN0aW9uYWxseSBlcXVhbC4KLSAgICoKLSAgICogQHBhcmFtIG9iajIgT2JqZWN0IHRvIGNvbXBhcmUgdGhpcyB0bwotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHR3byBvYmplY3RzIGFyZSBlcXVhbAotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGVxdWFscyhYT2JqZWN0IG9iajIpCi0gIHsKLQotICAgIC8vIEluIG9yZGVyIHRvIGhhbmRsZSB0aGUgJ2FsbCcgc2VtYW50aWNzIG9mCi0gICAgLy8gbm9kZXNldCBjb21wYXJpc29ucywgd2UgYWx3YXlzIGNhbGwgdGhlCi0gICAgLy8gbm9kZXNldCBmdW5jdGlvbi4KLSAgICBpbnQgdCA9IG9iajIuZ2V0VHlwZSgpOwotICAgIHRyeQotICAgIHsKLSAgICAgICAgICAgIGlmIChYT2JqZWN0LkNMQVNTX05PREVTRVQgPT0gdCkKLSAgICAgICAgICAgICAgcmV0dXJuIG9iajIuZXF1YWxzKHRoaXMpOwotICAgICAgICAgICAgLy8gSWYgYXQgbGVhc3Qgb25lIG9iamVjdCB0byBiZSBjb21wYXJlZCBpcyBhIGJvb2xlYW4sIHRoZW4gZWFjaCBvYmplY3QKLSAgICAgICAgICAgIC8vIHRvIGJlIGNvbXBhcmVkIGlzIGNvbnZlcnRlZCB0byBhIGJvb2xlYW4gYXMgaWYgYnkgYXBwbHlpbmcgdGhlCi0gICAgICAgICAgICAvLyBib29sZWFuIGZ1bmN0aW9uLgotICAgICAgICAgICAgZWxzZSBpZihYT2JqZWN0LkNMQVNTX0JPT0xFQU4gPT0gdCkKLSAgICAgICAgICAgICAgICByZXR1cm4gb2JqMi5ib29sKCkgPT0gYm9vbCgpOwotICAgICAgICAgICAgLy8gT3RoZXJ3aXNlLCBpZiBhdCBsZWFzdCBvbmUgb2JqZWN0IHRvIGJlIGNvbXBhcmVkIGlzIGEgbnVtYmVyLCB0aGVuIGVhY2ggb2JqZWN0Ci0gICAgICAgICAgICAvLyB0byBiZSBjb21wYXJlZCBpcyBjb252ZXJ0ZWQgdG8gYSBudW1iZXIgYXMgaWYgYnkgYXBwbHlpbmcgdGhlIG51bWJlciBmdW5jdGlvbi4KLSAgICAgICAgICAgIGVsc2UgaWYoWE9iamVjdC5DTEFTU19OVU1CRVIgPT0gdCkKLSAgICAgICAgICAgICAgICByZXR1cm4gb2JqMi5udW0oKSA9PSBudW0oKTsKLSAgICB9Ci0gICAgY2F0Y2goamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbiB0ZSkKLSAgICB7Ci0gICAgICAgIHRocm93IG5ldyBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLldyYXBwZWRSdW50aW1lRXhjZXB0aW9uKHRlKTsKLSAgICB9Ci0KLSAgICAvLyBPdGhlcndpc2UsIGJvdGggb2JqZWN0cyB0byBiZSBjb21wYXJlZCBhcmUgY29udmVydGVkIHRvIHN0cmluZ3MgYXMKLSAgICAvLyBpZiBieSBhcHBseWluZyB0aGUgc3RyaW5nIGZ1bmN0aW9uLgotICAgIHJldHVybiB4c3RyKCkuZXF1YWxzKG9iajIueHN0cigpKTsKLSAgfQotCi0gICAvKioKLSAgICogQ29tcGFyZXMgdGhpcyBzdHJpbmcgdG8gdGhlIHNwZWNpZmllZCA8Y29kZT5TdHJpbmc8L2NvZGU+LgotICAgKiBUaGUgcmVzdWx0IGlzIDxjb2RlPnRydWU8L2NvZGU+IGlmIGFuZCBvbmx5IGlmIHRoZSBhcmd1bWVudCBpcyBub3QKLSAgICogPGNvZGU+bnVsbDwvY29kZT4gYW5kIGlzIGEgPGNvZGU+U3RyaW5nPC9jb2RlPiBvYmplY3QgdGhhdCByZXByZXNlbnRzCi0gICAqIHRoZSBzYW1lIHNlcXVlbmNlIG9mIGNoYXJhY3RlcnMgYXMgdGhpcyBvYmplY3QuCi0gICAqCi0gICAqIEBwYXJhbSAgIG9iajIgICB0aGUgb2JqZWN0IHRvIGNvbXBhcmUgdGhpcyA8Y29kZT5TdHJpbmc8L2NvZGU+IGFnYWluc3QuCi0gICAqIEByZXR1cm4gIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSA8Y29kZT5TdHJpbmc8L2NvZGU+cyBhcmUgZXF1YWw7Ci0gICAqICAgICAgICAgIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuCi0gICAqIEBzZWUgICAgIGphdmEubGFuZy5TdHJpbmcjY29tcGFyZVRvKGphdmEubGFuZy5TdHJpbmcpCi0gICAqIEBzZWUgICAgIGphdmEubGFuZy5TdHJpbmcjZXF1YWxzSWdub3JlQ2FzZShqYXZhLmxhbmcuU3RyaW5nKQotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZXF1YWxzKFN0cmluZyBvYmoyKSB7Ci0gICAgcmV0dXJuIHN0cigpLmVxdWFscyhvYmoyKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb21wYXJlcyB0aGlzIHN0cmluZyB0byB0aGUgc3BlY2lmaWVkIG9iamVjdC4KLSAgICogVGhlIHJlc3VsdCBpcyA8Y29kZT50cnVlPC9jb2RlPiBpZiBhbmQgb25seSBpZiB0aGUgYXJndW1lbnQgaXMgbm90Ci0gICAqIDxjb2RlPm51bGw8L2NvZGU+IGFuZCBpcyBhIDxjb2RlPlN0cmluZzwvY29kZT4gb2JqZWN0IHRoYXQgcmVwcmVzZW50cwotICAgKiB0aGUgc2FtZSBzZXF1ZW5jZSBvZiBjaGFyYWN0ZXJzIGFzIHRoaXMgb2JqZWN0LgotICAgKgotICAgKiBAcGFyYW0gb2JqMiAgIHRoZSBvYmplY3QgdG8gY29tcGFyZSB0aGlzIDxjb2RlPlN0cmluZzwvY29kZT4KLSAgICogICAgICAgICAgICAgICAgICAgICBhZ2FpbnN0LgotICAgKiBAcmV0dXJuICA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgPGNvZGU+U3RyaW5nIDwvY29kZT5hcmUgZXF1YWw7Ci0gICAqICAgICAgICAgIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuCi0gICAqIEBzZWUgICAgIGphdmEubGFuZy5TdHJpbmcjY29tcGFyZVRvKGphdmEubGFuZy5TdHJpbmcpCi0gICAqIEBzZWUgICAgIGphdmEubGFuZy5TdHJpbmcjZXF1YWxzSWdub3JlQ2FzZShqYXZhLmxhbmcuU3RyaW5nKQotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZXF1YWxzKFhNTFN0cmluZyBvYmoyKQotICB7Ci0gICAgaWYgKG9iajIgIT0gbnVsbCkgewotICAgICAgaWYgKCFvYmoyLmhhc1N0cmluZygpKSB7Ci0gICAgICAgIHJldHVybiBvYmoyLmVxdWFscyhzdHIoKSk7Ci0gICAgICB9IGVsc2UgewotICAgICAgICByZXR1cm4gc3RyKCkuZXF1YWxzKG9iajIudG9TdHJpbmcoKSk7Ci0gICAgICB9Ci0gICAgfQotICAgIHJldHVybiBmYWxzZTsKLSAgfQotCi0gIC8qKgotICAgKiBDb21wYXJlcyB0aGlzIHN0cmluZyB0byB0aGUgc3BlY2lmaWVkIG9iamVjdC4KLSAgICogVGhlIHJlc3VsdCBpcyA8Y29kZT50cnVlPC9jb2RlPiBpZiBhbmQgb25seSBpZiB0aGUgYXJndW1lbnQgaXMgbm90Ci0gICAqIDxjb2RlPm51bGw8L2NvZGU+IGFuZCBpcyBhIDxjb2RlPlN0cmluZzwvY29kZT4gb2JqZWN0IHRoYXQgcmVwcmVzZW50cwotICAgKiB0aGUgc2FtZSBzZXF1ZW5jZSBvZiBjaGFyYWN0ZXJzIGFzIHRoaXMgb2JqZWN0LgotICAgKgotICAgKiBAcGFyYW0gICBvYmoyICAgICAgIHRoZSBvYmplY3QgdG8gY29tcGFyZSB0aGlzIDxjb2RlPlN0cmluZzwvY29kZT4KLSAgICogICAgICAgICAgICAgICAgICAgICBhZ2FpbnN0LgotICAgKiBAcmV0dXJuICA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgPGNvZGU+U3RyaW5nIDwvY29kZT5hcmUgZXF1YWw7Ci0gICAqICAgICAgICAgIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuCi0gICAqIEBzZWUgICAgIGphdmEubGFuZy5TdHJpbmcjY29tcGFyZVRvKGphdmEubGFuZy5TdHJpbmcpCi0gICAqIEBzZWUgICAgIGphdmEubGFuZy5TdHJpbmcjZXF1YWxzSWdub3JlQ2FzZShqYXZhLmxhbmcuU3RyaW5nKQotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmoyKQotICB7Ci0KLSAgICBpZiAobnVsbCA9PSBvYmoyKQotICAgICAgcmV0dXJuIGZhbHNlOwotCi0gICAgICAvLyBJbiBvcmRlciB0byBoYW5kbGUgdGhlICdhbGwnIHNlbWFudGljcyBvZgotICAgICAgLy8gbm9kZXNldCBjb21wYXJpc29ucywgd2UgYWx3YXlzIGNhbGwgdGhlCi0gICAgICAvLyBub2Rlc2V0IGZ1bmN0aW9uLgotICAgIGVsc2UgaWYgKG9iajIgaW5zdGFuY2VvZiBYTm9kZVNldCkKLSAgICAgIHJldHVybiBvYmoyLmVxdWFscyh0aGlzKTsKLSAgICBlbHNlIGlmKG9iajIgaW5zdGFuY2VvZiBYTnVtYmVyKQotICAgICAgICByZXR1cm4gb2JqMi5lcXVhbHModGhpcyk7Ci0gICAgZWxzZQotICAgICAgcmV0dXJuIHN0cigpLmVxdWFscyhvYmoyLnRvU3RyaW5nKCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbXBhcmVzIHRoaXMgPGNvZGU+U3RyaW5nPC9jb2RlPiB0byBhbm90aGVyIDxjb2RlPlN0cmluZzwvY29kZT4sCi0gICAqIGlnbm9yaW5nIGNhc2UgY29uc2lkZXJhdGlvbnMuICBUd28gc3RyaW5ncyBhcmUgY29uc2lkZXJlZCBlcXVhbAotICAgKiBpZ25vcmluZyBjYXNlIGlmIHRoZXkgYXJlIG9mIHRoZSBzYW1lIGxlbmd0aCwgYW5kIGNvcnJlc3BvbmRpbmcKLSAgICogY2hhcmFjdGVycyBpbiB0aGUgdHdvIHN0cmluZ3MgYXJlIGVxdWFsIGlnbm9yaW5nIGNhc2UuCi0gICAqCi0gICAqIEBwYXJhbSAgIGFub3RoZXJTdHJpbmcgICB0aGUgPGNvZGU+U3RyaW5nPC9jb2RlPiB0byBjb21wYXJlIHRoaXMKLSAgICogICAgICAgICAgICAgICAgICAgICAgICAgIDxjb2RlPlN0cmluZzwvY29kZT4gYWdhaW5zdC4KLSAgICogQHJldHVybiAgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIGFyZ3VtZW50IGlzIG5vdCA8Y29kZT5udWxsPC9jb2RlPgotICAgKiAgICAgICAgICBhbmQgdGhlIDxjb2RlPlN0cmluZzwvY29kZT5zIGFyZSBlcXVhbCwKLSAgICogICAgICAgICAgaWdub3JpbmcgY2FzZTsgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4KLSAgICogQHNlZSAgICAgI2VxdWFscyhPYmplY3QpCi0gICAqIEBzZWUgICAgIGphdmEubGFuZy5DaGFyYWN0ZXIjdG9Mb3dlckNhc2UoY2hhcikKLSAgICogQHNlZSBqYXZhLmxhbmcuQ2hhcmFjdGVyI3RvVXBwZXJDYXNlKGNoYXIpCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBlcXVhbHNJZ25vcmVDYXNlKFN0cmluZyBhbm90aGVyU3RyaW5nKQotICB7Ci0gICAgcmV0dXJuIHN0cigpLmVxdWFsc0lnbm9yZUNhc2UoYW5vdGhlclN0cmluZyk7Ci0gIH0KLQotICAvKioKLSAgICogQ29tcGFyZXMgdHdvIHN0cmluZ3MgbGV4aWNvZ3JhcGhpY2FsbHkuCi0gICAqCi0gICAqIEBwYXJhbSAgIHhzdHIgICB0aGUgPGNvZGU+U3RyaW5nPC9jb2RlPiB0byBiZSBjb21wYXJlZC4KLSAgICoKLSAgICogQHJldHVybiAgdGhlIHZhbHVlIDxjb2RlPjA8L2NvZGU+IGlmIHRoZSBhcmd1bWVudCBzdHJpbmcgaXMgZXF1YWwgdG8KLSAgICogICAgICAgICAgdGhpcyBzdHJpbmc7IGEgdmFsdWUgbGVzcyB0aGFuIDxjb2RlPjA8L2NvZGU+IGlmIHRoaXMgc3RyaW5nCi0gICAqICAgICAgICAgIGlzIGxleGljb2dyYXBoaWNhbGx5IGxlc3MgdGhhbiB0aGUgc3RyaW5nIGFyZ3VtZW50OyBhbmQgYQotICAgKiAgICAgICAgICB2YWx1ZSBncmVhdGVyIHRoYW4gPGNvZGU+MDwvY29kZT4gaWYgdGhpcyBzdHJpbmcgaXMKLSAgICogICAgICAgICAgbGV4aWNvZ3JhcGhpY2FsbHkgZ3JlYXRlciB0aGFuIHRoZSBzdHJpbmcgYXJndW1lbnQuCi0gICAqIEBleGNlcHRpb24gamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uIGlmIDxjb2RlPmFub3RoZXJTdHJpbmc8L2NvZGU+Ci0gICAqICAgICAgICAgIGlzIDxjb2RlPm51bGw8L2NvZGU+LgotICAgKi8KLSAgcHVibGljIGludCBjb21wYXJlVG8oWE1MU3RyaW5nIHhzdHIpCi0gIHsKLQotICAgIGludCBsZW4xID0gdGhpcy5sZW5ndGgoKTsKLSAgICBpbnQgbGVuMiA9IHhzdHIubGVuZ3RoKCk7Ci0gICAgaW50IG4gPSBNYXRoLm1pbihsZW4xLCBsZW4yKTsKLSAgICBpbnQgaSA9IDA7Ci0gICAgaW50IGogPSAwOwotCi0gICAgd2hpbGUgKG4tLSAhPSAwKQotICAgIHsKLSAgICAgIGNoYXIgYzEgPSB0aGlzLmNoYXJBdChpKTsKLSAgICAgIGNoYXIgYzIgPSB4c3RyLmNoYXJBdChqKTsKLQotICAgICAgaWYgKGMxICE9IGMyKQotICAgICAgewotICAgICAgICByZXR1cm4gYzEgLSBjMjsKLSAgICAgIH0KLQotICAgICAgaSsrOwotICAgICAgaisrOwotICAgIH0KLQotICAgIHJldHVybiBsZW4xIC0gbGVuMjsKLSAgfQotCi0gIC8qKgotICAgKiBDb21wYXJlcyB0d28gc3RyaW5ncyBsZXhpY29ncmFwaGljYWxseSwgaWdub3JpbmcgY2FzZSBjb25zaWRlcmF0aW9ucy4KLSAgICogVGhpcyBtZXRob2QgcmV0dXJucyBhbiBpbnRlZ2VyIHdob3NlIHNpZ24gaXMgdGhhdCBvZgotICAgKiA8Y29kZT50aGlzLnRvVXBwZXJDYXNlKCkudG9Mb3dlckNhc2UoKS5jb21wYXJlVG8oCi0gICAqIHN0ci50b1VwcGVyQ2FzZSgpLnRvTG93ZXJDYXNlKCkpPC9jb2RlPi4KLSAgICogPHA+Ci0gICAqIE5vdGUgdGhhdCB0aGlzIG1ldGhvZCBkb2VzIDxlbT5ub3Q8L2VtPiB0YWtlIGxvY2FsZSBpbnRvIGFjY291bnQsCi0gICAqIGFuZCB3aWxsIHJlc3VsdCBpbiBhbiB1bnNhdGlzZmFjdG9yeSBvcmRlcmluZyBmb3IgY2VydGFpbiBsb2NhbGVzLgotICAgKiBUaGUgamF2YS50ZXh0IHBhY2thZ2UgcHJvdmlkZXMgPGVtPmNvbGxhdG9yczwvZW0+IHRvIGFsbG93Ci0gICAqIGxvY2FsZS1zZW5zaXRpdmUgb3JkZXJpbmcuCi0gICAqCi0gICAqIEBwYXJhbSAgIHN0ciAgIHRoZSA8Y29kZT5TdHJpbmc8L2NvZGU+IHRvIGJlIGNvbXBhcmVkLgotICAgKiBAcmV0dXJuICBhIG5lZ2F0aXZlIGludGVnZXIsIHplcm8sIG9yIGEgcG9zaXRpdmUgaW50ZWdlciBhcyB0aGUKLSAgICogICAgICAgICAgdGhlIHNwZWNpZmllZCBTdHJpbmcgaXMgZ3JlYXRlciB0aGFuLCBlcXVhbCB0bywgb3IgbGVzcwotICAgKiAgICAgICAgICB0aGFuIHRoaXMgU3RyaW5nLCBpZ25vcmluZyBjYXNlIGNvbnNpZGVyYXRpb25zLgotICAgKiBAc2VlICAgICBqYXZhLnRleHQuQ29sbGF0b3IjY29tcGFyZShTdHJpbmcsIFN0cmluZykKLSAgICogQHNpbmNlICAgMS4yCi0gICAqLwotICBwdWJsaWMgaW50IGNvbXBhcmVUb0lnbm9yZUNhc2UoWE1MU3RyaW5nIHN0cikKLSAgewotICAgIC8vICVSRVZJRVclICBMaWtlIGl0IHNheXMsIEBzaW5jZSAxLjIuIERvZXNuJ3QgZXhpc3QgaW4gZWFybGllcgotICAgIC8vIHZlcnNpb25zIG9mIEphdmEsIGhlbmNlIHdlIGNhbid0IHlldCBzaGVsbCBvdXQgdG8gaXQuIFdlIGNhbiBpbXBsZW1lbnQKLSAgICAvLyBpdCBhcyBjaGFyYWN0ZXItYnktY2hhcmFjdGVyIGNvbXBhcmUsIGJ1dCBkb2luZyBzbyBlZmZpY2llbnRseQotICAgIC8vIGlzIGxpa2VseSB0byBiZSAoYWhlbSkgaW50ZXJlc3RpbmcuCi0gICAgLy8KLSAgICAvLyBIb3dldmVyLCBzaW5jZSBub2JvZHkgaXMgYWN0dWFsbHkgX3VzaW5nXyB0aGlzIG1ldGhvZCB5ZXQ6Ci0gICAgLy8gICAgcmV0dXJuIHN0cigpLmNvbXBhcmVUb0lnbm9yZUNhc2Uoc3RyLnRvU3RyaW5nKCkpOwotCi0gICAgdGhyb3cgbmV3IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuV3JhcHBlZFJ1bnRpbWVFeGNlcHRpb24oCi0gICAgICBuZXcgamF2YS5sYW5nLk5vU3VjaE1ldGhvZEV4Y2VwdGlvbigKLSAgICAgICAgIkphdmEgMS4yIG1ldGhvZCwgbm90IHlldCBpbXBsZW1lbnRlZCIpKTsKLSAgfQotCi0gIC8qKgotICAgKiBUZXN0cyBpZiB0aGlzIHN0cmluZyBzdGFydHMgd2l0aCB0aGUgc3BlY2lmaWVkIHByZWZpeCBiZWdpbm5pbmcKLSAgICogYSBzcGVjaWZpZWQgaW5kZXguCi0gICAqCi0gICAqIEBwYXJhbSAgIHByZWZpeCAgICB0aGUgcHJlZml4LgotICAgKiBAcGFyYW0gICB0b2Zmc2V0ICAgd2hlcmUgdG8gYmVnaW4gbG9va2luZyBpbiB0aGUgc3RyaW5nLgotICAgKiBAcmV0dXJuICA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgY2hhcmFjdGVyIHNlcXVlbmNlIHJlcHJlc2VudGVkIGJ5IHRoZQotICAgKiAgICAgICAgICBhcmd1bWVudCBpcyBhIHByZWZpeCBvZiB0aGUgc3Vic3RyaW5nIG9mIHRoaXMgb2JqZWN0IHN0YXJ0aW5nCi0gICAqICAgICAgICAgIGF0IGluZGV4IDxjb2RlPnRvZmZzZXQ8L2NvZGU+OyA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLgotICAgKiAgICAgICAgICBUaGUgcmVzdWx0IGlzIDxjb2RlPmZhbHNlPC9jb2RlPiBpZiA8Y29kZT50b2Zmc2V0PC9jb2RlPiBpcwotICAgKiAgICAgICAgICBuZWdhdGl2ZSBvciBncmVhdGVyIHRoYW4gdGhlIGxlbmd0aCBvZiB0aGlzCi0gICAqICAgICAgICAgIDxjb2RlPlN0cmluZzwvY29kZT4gb2JqZWN0OyBvdGhlcndpc2UgdGhlIHJlc3VsdCBpcyB0aGUgc2FtZQotICAgKiAgICAgICAgICBhcyB0aGUgcmVzdWx0IG9mIHRoZSBleHByZXNzaW9uCi0gICAqICAgICAgICAgIDxwcmU+Ci0gICAqICAgICAgICAgIHRoaXMuc3ViU3RyaW5nKHRvZmZzZXQpLnN0YXJ0c1dpdGgocHJlZml4KQotICAgKiAgICAgICAgICA8L3ByZT4KLSAgICogQGV4Y2VwdGlvbiBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgPGNvZGU+cHJlZml4PC9jb2RlPiBpcwotICAgKiAgICAgICAgICA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIHN0YXJ0c1dpdGgoU3RyaW5nIHByZWZpeCwgaW50IHRvZmZzZXQpCi0gIHsKLSAgICByZXR1cm4gc3RyKCkuc3RhcnRzV2l0aChwcmVmaXgsIHRvZmZzZXQpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlc3RzIGlmIHRoaXMgc3RyaW5nIHN0YXJ0cyB3aXRoIHRoZSBzcGVjaWZpZWQgcHJlZml4LgotICAgKgotICAgKiBAcGFyYW0gICBwcmVmaXggICB0aGUgcHJlZml4LgotICAgKiBAcmV0dXJuICA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgY2hhcmFjdGVyIHNlcXVlbmNlIHJlcHJlc2VudGVkIGJ5IHRoZQotICAgKiAgICAgICAgICBhcmd1bWVudCBpcyBhIHByZWZpeCBvZiB0aGUgY2hhcmFjdGVyIHNlcXVlbmNlIHJlcHJlc2VudGVkIGJ5Ci0gICAqICAgICAgICAgIHRoaXMgc3RyaW5nOyA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLgotICAgKiAgICAgICAgICBOb3RlIGFsc28gdGhhdCA8Y29kZT50cnVlPC9jb2RlPiB3aWxsIGJlIHJldHVybmVkIGlmIHRoZQotICAgKiAgICAgICAgICBhcmd1bWVudCBpcyBhbiBlbXB0eSBzdHJpbmcgb3IgaXMgZXF1YWwgdG8gdGhpcwotICAgKiAgICAgICAgICA8Y29kZT5TdHJpbmc8L2NvZGU+IG9iamVjdCBhcyBkZXRlcm1pbmVkIGJ5IHRoZQotICAgKiAgICAgICAgICB7QGxpbmsgI2VxdWFscyhPYmplY3QpfSBtZXRob2QuCi0gICAqIEBleGNlcHRpb24gamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uIGlmIDxjb2RlPnByZWZpeDwvY29kZT4gaXMKLSAgICogICAgICAgICAgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBzdGFydHNXaXRoKFN0cmluZyBwcmVmaXgpCi0gIHsKLSAgICByZXR1cm4gc3RhcnRzV2l0aChwcmVmaXgsIDApOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlc3RzIGlmIHRoaXMgc3RyaW5nIHN0YXJ0cyB3aXRoIHRoZSBzcGVjaWZpZWQgcHJlZml4IGJlZ2lubmluZwotICAgKiBhIHNwZWNpZmllZCBpbmRleC4KLSAgICoKLSAgICogQHBhcmFtICAgcHJlZml4ICAgIHRoZSBwcmVmaXguCi0gICAqIEBwYXJhbSAgIHRvZmZzZXQgICB3aGVyZSB0byBiZWdpbiBsb29raW5nIGluIHRoZSBzdHJpbmcuCi0gICAqIEByZXR1cm4gIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBjaGFyYWN0ZXIgc2VxdWVuY2UgcmVwcmVzZW50ZWQgYnkgdGhlCi0gICAqICAgICAgICAgIGFyZ3VtZW50IGlzIGEgcHJlZml4IG9mIHRoZSBzdWJzdHJpbmcgb2YgdGhpcyBvYmplY3Qgc3RhcnRpbmcKLSAgICogICAgICAgICAgYXQgaW5kZXggPGNvZGU+dG9mZnNldDwvY29kZT47IDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuCi0gICAqICAgICAgICAgIFRoZSByZXN1bHQgaXMgPGNvZGU+ZmFsc2U8L2NvZGU+IGlmIDxjb2RlPnRvZmZzZXQ8L2NvZGU+IGlzCi0gICAqICAgICAgICAgIG5lZ2F0aXZlIG9yIGdyZWF0ZXIgdGhhbiB0aGUgbGVuZ3RoIG9mIHRoaXMKLSAgICogICAgICAgICAgPGNvZGU+U3RyaW5nPC9jb2RlPiBvYmplY3Q7IG90aGVyd2lzZSB0aGUgcmVzdWx0IGlzIHRoZSBzYW1lCi0gICAqICAgICAgICAgIGFzIHRoZSByZXN1bHQgb2YgdGhlIGV4cHJlc3Npb24KLSAgICogICAgICAgICAgPHByZT4KLSAgICogICAgICAgICAgdGhpcy5zdWJTdHJpbmcodG9mZnNldCkuc3RhcnRzV2l0aChwcmVmaXgpCi0gICAqICAgICAgICAgIDwvcHJlPgotICAgKiBAZXhjZXB0aW9uIGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiA8Y29kZT5wcmVmaXg8L2NvZGU+IGlzCi0gICAqICAgICAgICAgIDxjb2RlPm51bGw8L2NvZGU+LgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gc3RhcnRzV2l0aChYTUxTdHJpbmcgcHJlZml4LCBpbnQgdG9mZnNldCkKLSAgewotCi0gICAgaW50IHRvID0gdG9mZnNldDsKLSAgICBpbnQgdGxpbSA9IHRoaXMubGVuZ3RoKCk7Ci0gICAgaW50IHBvID0gMDsKLSAgICBpbnQgcGMgPSBwcmVmaXgubGVuZ3RoKCk7Ci0KLSAgICAvLyBOb3RlOiB0b2Zmc2V0IG1pZ2h0IGJlIG5lYXIgLTE+Pj4xLgotICAgIGlmICgodG9mZnNldCA8IDApIHx8ICh0b2Zmc2V0ID4gdGxpbSAtIHBjKSkKLSAgICB7Ci0gICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgd2hpbGUgKC0tcGMgPj0gMCkKLSAgICB7Ci0gICAgICBpZiAodGhpcy5jaGFyQXQodG8pICE9IHByZWZpeC5jaGFyQXQocG8pKQotICAgICAgewotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICB9Ci0KLSAgICAgIHRvKys7Ci0gICAgICBwbysrOwotICAgIH0KLQotICAgIHJldHVybiB0cnVlOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlc3RzIGlmIHRoaXMgc3RyaW5nIHN0YXJ0cyB3aXRoIHRoZSBzcGVjaWZpZWQgcHJlZml4LgotICAgKgotICAgKiBAcGFyYW0gICBwcmVmaXggICB0aGUgcHJlZml4LgotICAgKiBAcmV0dXJuICA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgY2hhcmFjdGVyIHNlcXVlbmNlIHJlcHJlc2VudGVkIGJ5IHRoZQotICAgKiAgICAgICAgICBhcmd1bWVudCBpcyBhIHByZWZpeCBvZiB0aGUgY2hhcmFjdGVyIHNlcXVlbmNlIHJlcHJlc2VudGVkIGJ5Ci0gICAqICAgICAgICAgIHRoaXMgc3RyaW5nOyA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLgotICAgKiAgICAgICAgICBOb3RlIGFsc28gdGhhdCA8Y29kZT50cnVlPC9jb2RlPiB3aWxsIGJlIHJldHVybmVkIGlmIHRoZQotICAgKiAgICAgICAgICBhcmd1bWVudCBpcyBhbiBlbXB0eSBzdHJpbmcgb3IgaXMgZXF1YWwgdG8gdGhpcwotICAgKiAgICAgICAgICA8Y29kZT5TdHJpbmc8L2NvZGU+IG9iamVjdCBhcyBkZXRlcm1pbmVkIGJ5IHRoZQotICAgKiAgICAgICAgICB7QGxpbmsgI2VxdWFscyhPYmplY3QpfSBtZXRob2QuCi0gICAqIEBleGNlcHRpb24gamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uIGlmIDxjb2RlPnByZWZpeDwvY29kZT4gaXMKLSAgICogICAgICAgICAgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBzdGFydHNXaXRoKFhNTFN0cmluZyBwcmVmaXgpCi0gIHsKLSAgICByZXR1cm4gc3RhcnRzV2l0aChwcmVmaXgsIDApOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlc3RzIGlmIHRoaXMgc3RyaW5nIGVuZHMgd2l0aCB0aGUgc3BlY2lmaWVkIHN1ZmZpeC4KLSAgICoKLSAgICogQHBhcmFtICAgc3VmZml4ICAgdGhlIHN1ZmZpeC4KLSAgICogQHJldHVybiAgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIGNoYXJhY3RlciBzZXF1ZW5jZSByZXByZXNlbnRlZCBieSB0aGUKLSAgICogICAgICAgICAgYXJndW1lbnQgaXMgYSBzdWZmaXggb2YgdGhlIGNoYXJhY3RlciBzZXF1ZW5jZSByZXByZXNlbnRlZCBieQotICAgKiAgICAgICAgICB0aGlzIG9iamVjdDsgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4gTm90ZSB0aGF0IHRoZQotICAgKiAgICAgICAgICByZXN1bHQgd2lsbCBiZSA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgYXJndW1lbnQgaXMgdGhlCi0gICAqICAgICAgICAgIGVtcHR5IHN0cmluZyBvciBpcyBlcXVhbCB0byB0aGlzIDxjb2RlPlN0cmluZzwvY29kZT4gb2JqZWN0Ci0gICAqICAgICAgICAgIGFzIGRldGVybWluZWQgYnkgdGhlIHtAbGluayAjZXF1YWxzKE9iamVjdCl9IG1ldGhvZC4KLSAgICogQGV4Y2VwdGlvbiBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgPGNvZGU+c3VmZml4PC9jb2RlPiBpcwotICAgKiAgICAgICAgICA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGVuZHNXaXRoKFN0cmluZyBzdWZmaXgpCi0gIHsKLSAgICByZXR1cm4gc3RyKCkuZW5kc1dpdGgoc3VmZml4KTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIGEgaGFzaGNvZGUgZm9yIHRoaXMgc3RyaW5nLiBUaGUgaGFzaGNvZGUgZm9yIGEKLSAgICogPGNvZGU+U3RyaW5nPC9jb2RlPiBvYmplY3QgaXMgY29tcHV0ZWQgYXMKLSAgICogPGJsb2NrcXVvdGU+PHByZT4KLSAgICogc1swXSozMV4obi0xKSArIHNbMV0qMzFeKG4tMikgKyAuLi4gKyBzW24tMV0KLSAgICogPC9wcmU+PC9ibG9ja3F1b3RlPgotICAgKiB1c2luZyA8Y29kZT5pbnQ8L2NvZGU+IGFyaXRobWV0aWMsIHdoZXJlIDxjb2RlPnNbaV08L2NvZGU+IGlzIHRoZQotICAgKiA8aT5pPC9pPnRoIGNoYXJhY3RlciBvZiB0aGUgc3RyaW5nLCA8Y29kZT5uPC9jb2RlPiBpcyB0aGUgbGVuZ3RoIG9mCi0gICAqIHRoZSBzdHJpbmcsIGFuZCA8Y29kZT5ePC9jb2RlPiBpbmRpY2F0ZXMgZXhwb25lbnRpYXRpb24uCi0gICAqIChUaGUgaGFzaCB2YWx1ZSBvZiB0aGUgZW1wdHkgc3RyaW5nIGlzIHplcm8uKQotICAgKgotICAgKiBAcmV0dXJuICBhIGhhc2ggY29kZSB2YWx1ZSBmb3IgdGhpcyBvYmplY3QuCi0gICAqLwotICBwdWJsaWMgaW50IGhhc2hDb2RlKCkKLSAgewotICAgIHJldHVybiBzdHIoKS5oYXNoQ29kZSgpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIGluZGV4IHdpdGhpbiB0aGlzIHN0cmluZyBvZiB0aGUgZmlyc3Qgb2NjdXJyZW5jZSBvZiB0aGUKLSAgICogc3BlY2lmaWVkIGNoYXJhY3Rlci4gSWYgYSBjaGFyYWN0ZXIgd2l0aCB2YWx1ZSA8Y29kZT5jaDwvY29kZT4gb2NjdXJzCi0gICAqIGluIHRoZSBjaGFyYWN0ZXIgc2VxdWVuY2UgcmVwcmVzZW50ZWQgYnkgdGhpcyA8Y29kZT5TdHJpbmc8L2NvZGU+Ci0gICAqIG9iamVjdCwgdGhlbiB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IHN1Y2ggb2NjdXJyZW5jZSBpcyByZXR1cm5lZCAtLQotICAgKiB0aGF0IGlzLCB0aGUgc21hbGxlc3QgdmFsdWUgPGk+azwvaT4gc3VjaCB0aGF0OgotICAgKiA8YmxvY2txdW90ZT48cHJlPgotICAgKiB0aGlzLmNoYXJBdCg8aT5rPC9pPikgPT0gY2gKLSAgICogPC9wcmU+PC9ibG9ja3F1b3RlPgotICAgKiBpcyA8Y29kZT50cnVlPC9jb2RlPi4gSWYgbm8gc3VjaCBjaGFyYWN0ZXIgb2NjdXJzIGluIHRoaXMgc3RyaW5nLAotICAgKiB0aGVuIDxjb2RlPi0xPC9jb2RlPiBpcyByZXR1cm5lZC4KLSAgICoKLSAgICogQHBhcmFtICAgY2ggICBhIGNoYXJhY3Rlci4KLSAgICogQHJldHVybiAgdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZSBjaGFyYWN0ZXIgaW4gdGhlCi0gICAqICAgICAgICAgIGNoYXJhY3RlciBzZXF1ZW5jZSByZXByZXNlbnRlZCBieSB0aGlzIG9iamVjdCwgb3IKLSAgICogICAgICAgICAgPGNvZGU+LTE8L2NvZGU+IGlmIHRoZSBjaGFyYWN0ZXIgZG9lcyBub3Qgb2NjdXIuCi0gICAqLwotICBwdWJsaWMgaW50IGluZGV4T2YoaW50IGNoKQotICB7Ci0gICAgcmV0dXJuIHN0cigpLmluZGV4T2YoY2gpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIGluZGV4IHdpdGhpbiB0aGlzIHN0cmluZyBvZiB0aGUgZmlyc3Qgb2NjdXJyZW5jZSBvZiB0aGUKLSAgICogc3BlY2lmaWVkIGNoYXJhY3Rlciwgc3RhcnRpbmcgdGhlIHNlYXJjaCBhdCB0aGUgc3BlY2lmaWVkIGluZGV4LgotICAgKiA8cD4KLSAgICogSWYgYSBjaGFyYWN0ZXIgd2l0aCB2YWx1ZSA8Y29kZT5jaDwvY29kZT4gb2NjdXJzIGluIHRoZSBjaGFyYWN0ZXIKLSAgICogc2VxdWVuY2UgcmVwcmVzZW50ZWQgYnkgdGhpcyA8Y29kZT5TdHJpbmc8L2NvZGU+IG9iamVjdCBhdCBhbiBpbmRleAotICAgKiBubyBzbWFsbGVyIHRoYW4gPGNvZGU+ZnJvbUluZGV4PC9jb2RlPiwgdGhlbiB0aGUgaW5kZXggb2YgdGhlIGZpcnN0Ci0gICAqIHN1Y2ggb2NjdXJyZW5jZSBpcyByZXR1cm5lZC0tdGhhdCBpcywgdGhlIHNtYWxsZXN0IHZhbHVlIDxpPms8L2k+Ci0gICAqIHN1Y2ggdGhhdDoKLSAgICogPGJsb2NrcXVvdGU+PHByZT4KLSAgICogKHRoaXMuY2hhckF0KDxpPms8L2k+KSA9PSBjaCkgJiYgKDxpPms8L2k+ID49IGZyb21JbmRleCkKLSAgICogPC9wcmU+PC9ibG9ja3F1b3RlPgotICAgKiBpcyB0cnVlLiBJZiBubyBzdWNoIGNoYXJhY3RlciBvY2N1cnMgaW4gdGhpcyBzdHJpbmcgYXQgb3IgYWZ0ZXIKLSAgICogcG9zaXRpb24gPGNvZGU+ZnJvbUluZGV4PC9jb2RlPiwgdGhlbiA8Y29kZT4tMTwvY29kZT4gaXMgcmV0dXJuZWQuCi0gICAqIDxwPgotICAgKiBUaGVyZSBpcyBubyByZXN0cmljdGlvbiBvbiB0aGUgdmFsdWUgb2YgPGNvZGU+ZnJvbUluZGV4PC9jb2RlPi4gSWYgaXQKLSAgICogaXMgbmVnYXRpdmUsIGl0IGhhcyB0aGUgc2FtZSBlZmZlY3QgYXMgaWYgaXQgd2VyZSB6ZXJvOiB0aGlzIGVudGlyZQotICAgKiBzdHJpbmcgbWF5IGJlIHNlYXJjaGVkLiBJZiBpdCBpcyBncmVhdGVyIHRoYW4gdGhlIGxlbmd0aCBvZiB0aGlzCi0gICAqIHN0cmluZywgaXQgaGFzIHRoZSBzYW1lIGVmZmVjdCBhcyBpZiBpdCB3ZXJlIGVxdWFsIHRvIHRoZSBsZW5ndGggb2YKLSAgICogdGhpcyBzdHJpbmc6IDxjb2RlPi0xPC9jb2RlPiBpcyByZXR1cm5lZC4KLSAgICoKLSAgICogQHBhcmFtICAgY2ggICAgICAgICAgYSBjaGFyYWN0ZXIuCi0gICAqIEBwYXJhbSAgIGZyb21JbmRleCAgIHRoZSBpbmRleCB0byBzdGFydCB0aGUgc2VhcmNoIGZyb20uCi0gICAqIEByZXR1cm4gIHRoZSBpbmRleCBvZiB0aGUgZmlyc3Qgb2NjdXJyZW5jZSBvZiB0aGUgY2hhcmFjdGVyIGluIHRoZQotICAgKiAgICAgICAgICBjaGFyYWN0ZXIgc2VxdWVuY2UgcmVwcmVzZW50ZWQgYnkgdGhpcyBvYmplY3QgdGhhdCBpcyBncmVhdGVyCi0gICAqICAgICAgICAgIHRoYW4gb3IgZXF1YWwgdG8gPGNvZGU+ZnJvbUluZGV4PC9jb2RlPiwgb3IgPGNvZGU+LTE8L2NvZGU+Ci0gICAqICAgICAgICAgIGlmIHRoZSBjaGFyYWN0ZXIgZG9lcyBub3Qgb2NjdXIuCi0gICAqLwotICBwdWJsaWMgaW50IGluZGV4T2YoaW50IGNoLCBpbnQgZnJvbUluZGV4KQotICB7Ci0gICAgcmV0dXJuIHN0cigpLmluZGV4T2YoY2gsIGZyb21JbmRleCk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgaW5kZXggd2l0aGluIHRoaXMgc3RyaW5nIG9mIHRoZSBsYXN0IG9jY3VycmVuY2Ugb2YgdGhlCi0gICAqIHNwZWNpZmllZCBjaGFyYWN0ZXIuIFRoYXQgaXMsIHRoZSBpbmRleCByZXR1cm5lZCBpcyB0aGUgbGFyZ2VzdAotICAgKiB2YWx1ZSA8aT5rPC9pPiBzdWNoIHRoYXQ6Ci0gICAqIDxibG9ja3F1b3RlPjxwcmU+Ci0gICAqIHRoaXMuY2hhckF0KDxpPms8L2k+KSA9PSBjaAotICAgKiA8L3ByZT48L2Jsb2NrcXVvdGU+Ci0gICAqIGlzIHRydWUuCi0gICAqIFRoZSBTdHJpbmcgaXMgc2VhcmNoZWQgYmFja3dhcmRzIHN0YXJ0aW5nIGF0IHRoZSBsYXN0IGNoYXJhY3Rlci4KLSAgICoKLSAgICogQHBhcmFtICAgY2ggICBhIGNoYXJhY3Rlci4KLSAgICogQHJldHVybiAgdGhlIGluZGV4IG9mIHRoZSBsYXN0IG9jY3VycmVuY2Ugb2YgdGhlIGNoYXJhY3RlciBpbiB0aGUKLSAgICogICAgICAgICAgY2hhcmFjdGVyIHNlcXVlbmNlIHJlcHJlc2VudGVkIGJ5IHRoaXMgb2JqZWN0LCBvcgotICAgKiAgICAgICAgICA8Y29kZT4tMTwvY29kZT4gaWYgdGhlIGNoYXJhY3RlciBkb2VzIG5vdCBvY2N1ci4KLSAgICovCi0gIHB1YmxpYyBpbnQgbGFzdEluZGV4T2YoaW50IGNoKQotICB7Ci0gICAgcmV0dXJuIHN0cigpLmxhc3RJbmRleE9mKGNoKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBpbmRleCB3aXRoaW4gdGhpcyBzdHJpbmcgb2YgdGhlIGxhc3Qgb2NjdXJyZW5jZSBvZiB0aGUKLSAgICogc3BlY2lmaWVkIGNoYXJhY3Rlciwgc2VhcmNoaW5nIGJhY2t3YXJkIHN0YXJ0aW5nIGF0IHRoZSBzcGVjaWZpZWQKLSAgICogaW5kZXguIFRoYXQgaXMsIHRoZSBpbmRleCByZXR1cm5lZCBpcyB0aGUgbGFyZ2VzdCB2YWx1ZSA8aT5rPC9pPgotICAgKiBzdWNoIHRoYXQ6Ci0gICAqIDxibG9ja3F1b3RlPjxwcmU+Ci0gICAqIHRoaXMuY2hhckF0KGspID09IGNoKSAmJiAoayA8PSBmcm9tSW5kZXgpCi0gICAqIDwvcHJlPjwvYmxvY2txdW90ZT4KLSAgICogaXMgdHJ1ZS4KLSAgICoKLSAgICogQHBhcmFtICAgY2ggICAgICAgICAgYSBjaGFyYWN0ZXIuCi0gICAqIEBwYXJhbSAgIGZyb21JbmRleCAgIHRoZSBpbmRleCB0byBzdGFydCB0aGUgc2VhcmNoIGZyb20uIFRoZXJlIGlzIG5vCi0gICAqICAgICAgICAgIHJlc3RyaWN0aW9uIG9uIHRoZSB2YWx1ZSBvZiA8Y29kZT5mcm9tSW5kZXg8L2NvZGU+LiBJZiBpdCBpcwotICAgKiAgICAgICAgICBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gdGhlIGxlbmd0aCBvZiB0aGlzIHN0cmluZywgaXQgaGFzCi0gICAqICAgICAgICAgIHRoZSBzYW1lIGVmZmVjdCBhcyBpZiBpdCB3ZXJlIGVxdWFsIHRvIG9uZSBsZXNzIHRoYW4gdGhlCi0gICAqICAgICAgICAgIGxlbmd0aCBvZiB0aGlzIHN0cmluZzogdGhpcyBlbnRpcmUgc3RyaW5nIG1heSBiZSBzZWFyY2hlZC4KLSAgICogICAgICAgICAgSWYgaXQgaXMgbmVnYXRpdmUsIGl0IGhhcyB0aGUgc2FtZSBlZmZlY3QgYXMgaWYgaXQgd2VyZSAtMToKLSAgICogICAgICAgICAgLTEgaXMgcmV0dXJuZWQuCi0gICAqIEByZXR1cm4gIHRoZSBpbmRleCBvZiB0aGUgbGFzdCBvY2N1cnJlbmNlIG9mIHRoZSBjaGFyYWN0ZXIgaW4gdGhlCi0gICAqICAgICAgICAgIGNoYXJhY3RlciBzZXF1ZW5jZSByZXByZXNlbnRlZCBieSB0aGlzIG9iamVjdCB0aGF0IGlzIGxlc3MKLSAgICogICAgICAgICAgdGhhbiBvciBlcXVhbCB0byA8Y29kZT5mcm9tSW5kZXg8L2NvZGU+LCBvciA8Y29kZT4tMTwvY29kZT4KLSAgICogICAgICAgICAgaWYgdGhlIGNoYXJhY3RlciBkb2VzIG5vdCBvY2N1ciBiZWZvcmUgdGhhdCBwb2ludC4KLSAgICovCi0gIHB1YmxpYyBpbnQgbGFzdEluZGV4T2YoaW50IGNoLCBpbnQgZnJvbUluZGV4KQotICB7Ci0gICAgcmV0dXJuIHN0cigpLmxhc3RJbmRleE9mKGNoLCBmcm9tSW5kZXgpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIGluZGV4IHdpdGhpbiB0aGlzIHN0cmluZyBvZiB0aGUgZmlyc3Qgb2NjdXJyZW5jZSBvZiB0aGUKLSAgICogc3BlY2lmaWVkIHN1YnN0cmluZy4gVGhlIGludGVnZXIgcmV0dXJuZWQgaXMgdGhlIHNtYWxsZXN0IHZhbHVlCi0gICAqIDxpPms8L2k+IHN1Y2ggdGhhdDoKLSAgICogPGJsb2NrcXVvdGU+PHByZT4KLSAgICogdGhpcy5zdGFydHNXaXRoKHN0ciwgPGk+azwvaT4pCi0gICAqIDwvcHJlPjwvYmxvY2txdW90ZT4KLSAgICogaXMgPGNvZGU+dHJ1ZTwvY29kZT4uCi0gICAqCi0gICAqIEBwYXJhbSAgIHN0ciAgIGFueSBzdHJpbmcuCi0gICAqIEByZXR1cm4gIGlmIHRoZSBzdHJpbmcgYXJndW1lbnQgb2NjdXJzIGFzIGEgc3Vic3RyaW5nIHdpdGhpbiB0aGlzCi0gICAqICAgICAgICAgIG9iamVjdCwgdGhlbiB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IGNoYXJhY3RlciBvZiB0aGUgZmlyc3QKLSAgICogICAgICAgICAgc3VjaCBzdWJzdHJpbmcgaXMgcmV0dXJuZWQ7IGlmIGl0IGRvZXMgbm90IG9jY3VyIGFzIGEKLSAgICogICAgICAgICAgc3Vic3RyaW5nLCA8Y29kZT4tMTwvY29kZT4gaXMgcmV0dXJuZWQuCi0gICAqIEBleGNlcHRpb24gamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uIGlmIDxjb2RlPnN0cjwvY29kZT4gaXMKLSAgICogICAgICAgICAgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAqLwotICBwdWJsaWMgaW50IGluZGV4T2YoU3RyaW5nIHN0cikKLSAgewotICAgIHJldHVybiBzdHIoKS5pbmRleE9mKHN0cik7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgaW5kZXggd2l0aGluIHRoaXMgc3RyaW5nIG9mIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZQotICAgKiBzcGVjaWZpZWQgc3Vic3RyaW5nLiBUaGUgaW50ZWdlciByZXR1cm5lZCBpcyB0aGUgc21hbGxlc3QgdmFsdWUKLSAgICogPGk+azwvaT4gc3VjaCB0aGF0OgotICAgKiA8YmxvY2txdW90ZT48cHJlPgotICAgKiB0aGlzLnN0YXJ0c1dpdGgoc3RyLCA8aT5rPC9pPikKLSAgICogPC9wcmU+PC9ibG9ja3F1b3RlPgotICAgKiBpcyA8Y29kZT50cnVlPC9jb2RlPi4KLSAgICoKLSAgICogQHBhcmFtICAgc3RyICAgYW55IHN0cmluZy4KLSAgICogQHJldHVybiAgaWYgdGhlIHN0cmluZyBhcmd1bWVudCBvY2N1cnMgYXMgYSBzdWJzdHJpbmcgd2l0aGluIHRoaXMKLSAgICogICAgICAgICAgb2JqZWN0LCB0aGVuIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgY2hhcmFjdGVyIG9mIHRoZSBmaXJzdAotICAgKiAgICAgICAgICBzdWNoIHN1YnN0cmluZyBpcyByZXR1cm5lZDsgaWYgaXQgZG9lcyBub3Qgb2NjdXIgYXMgYQotICAgKiAgICAgICAgICBzdWJzdHJpbmcsIDxjb2RlPi0xPC9jb2RlPiBpcyByZXR1cm5lZC4KLSAgICogQGV4Y2VwdGlvbiBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgPGNvZGU+c3RyPC9jb2RlPiBpcwotICAgKiAgICAgICAgICA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICovCi0gIHB1YmxpYyBpbnQgaW5kZXhPZihYTUxTdHJpbmcgc3RyKQotICB7Ci0gICAgcmV0dXJuIHN0cigpLmluZGV4T2Yoc3RyLnRvU3RyaW5nKCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIGluZGV4IHdpdGhpbiB0aGlzIHN0cmluZyBvZiB0aGUgZmlyc3Qgb2NjdXJyZW5jZSBvZiB0aGUKLSAgICogc3BlY2lmaWVkIHN1YnN0cmluZywgc3RhcnRpbmcgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4gVGhlIGludGVnZXIKLSAgICogcmV0dXJuZWQgaXMgdGhlIHNtYWxsZXN0IHZhbHVlIDxpPms8L2k+IHN1Y2ggdGhhdDoKLSAgICogPGJsb2NrcXVvdGU+PHByZT4KLSAgICogdGhpcy5zdGFydHNXaXRoKHN0ciwgPGk+azwvaT4pICYmICg8aT5rPC9pPiA+PSBmcm9tSW5kZXgpCi0gICAqIDwvcHJlPjwvYmxvY2txdW90ZT4KLSAgICogaXMgPGNvZGU+dHJ1ZTwvY29kZT4uCi0gICAqIDxwPgotICAgKiBUaGVyZSBpcyBubyByZXN0cmljdGlvbiBvbiB0aGUgdmFsdWUgb2YgPGNvZGU+ZnJvbUluZGV4PC9jb2RlPi4gSWYKLSAgICogaXQgaXMgbmVnYXRpdmUsIGl0IGhhcyB0aGUgc2FtZSBlZmZlY3QgYXMgaWYgaXQgd2VyZSB6ZXJvOiB0aGlzIGVudGlyZQotICAgKiBzdHJpbmcgbWF5IGJlIHNlYXJjaGVkLiBJZiBpdCBpcyBncmVhdGVyIHRoYW4gdGhlIGxlbmd0aCBvZiB0aGlzCi0gICAqIHN0cmluZywgaXQgaGFzIHRoZSBzYW1lIGVmZmVjdCBhcyBpZiBpdCB3ZXJlIGVxdWFsIHRvIHRoZSBsZW5ndGggb2YKLSAgICogdGhpcyBzdHJpbmc6IDxjb2RlPi0xPC9jb2RlPiBpcyByZXR1cm5lZC4KLSAgICoKLSAgICogQHBhcmFtICAgc3RyICAgICAgICAgdGhlIHN1YnN0cmluZyB0byBzZWFyY2ggZm9yLgotICAgKiBAcGFyYW0gICBmcm9tSW5kZXggICB0aGUgaW5kZXggdG8gc3RhcnQgdGhlIHNlYXJjaCBmcm9tLgotICAgKiBAcmV0dXJuICBJZiB0aGUgc3RyaW5nIGFyZ3VtZW50IG9jY3VycyBhcyBhIHN1YnN0cmluZyB3aXRoaW4gdGhpcwotICAgKiAgICAgICAgICBvYmplY3QgYXQgYSBzdGFydGluZyBpbmRleCBubyBzbWFsbGVyIHRoYW4KLSAgICogICAgICAgICAgPGNvZGU+ZnJvbUluZGV4PC9jb2RlPiwgdGhlbiB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IGNoYXJhY3RlcgotICAgKiAgICAgICAgICBvZiB0aGUgZmlyc3Qgc3VjaCBzdWJzdHJpbmcgaXMgcmV0dXJuZWQuIElmIGl0IGRvZXMgbm90IG9jY3VyCi0gICAqICAgICAgICAgIGFzIGEgc3Vic3RyaW5nIHN0YXJ0aW5nIGF0IDxjb2RlPmZyb21JbmRleDwvY29kZT4gb3IgYmV5b25kLAotICAgKiAgICAgICAgICA8Y29kZT4tMTwvY29kZT4gaXMgcmV0dXJuZWQuCi0gICAqIEBleGNlcHRpb24gamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uIGlmIDxjb2RlPnN0cjwvY29kZT4gaXMKLSAgICogICAgICAgICAgPGNvZGU+bnVsbDwvY29kZT4KLSAgICovCi0gIHB1YmxpYyBpbnQgaW5kZXhPZihTdHJpbmcgc3RyLCBpbnQgZnJvbUluZGV4KQotICB7Ci0gICAgcmV0dXJuIHN0cigpLmluZGV4T2Yoc3RyLCBmcm9tSW5kZXgpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIGluZGV4IHdpdGhpbiB0aGlzIHN0cmluZyBvZiB0aGUgcmlnaHRtb3N0IG9jY3VycmVuY2UKLSAgICogb2YgdGhlIHNwZWNpZmllZCBzdWJzdHJpbmcuICBUaGUgcmlnaHRtb3N0IGVtcHR5IHN0cmluZyAiIiBpcwotICAgKiBjb25zaWRlcmVkIHRvIG9jY3VyIGF0IHRoZSBpbmRleCB2YWx1ZSA8Y29kZT50aGlzLmxlbmd0aCgpPC9jb2RlPi4KLSAgICogVGhlIHJldHVybmVkIGluZGV4IGlzIHRoZSBsYXJnZXN0IHZhbHVlIDxpPms8L2k+IHN1Y2ggdGhhdAotICAgKiA8YmxvY2txdW90ZT48cHJlPgotICAgKiB0aGlzLnN0YXJ0c1dpdGgoc3RyLCBrKQotICAgKiA8L3ByZT48L2Jsb2NrcXVvdGU+Ci0gICAqIGlzIHRydWUuCi0gICAqCi0gICAqIEBwYXJhbSAgIHN0ciAgIHRoZSBzdWJzdHJpbmcgdG8gc2VhcmNoIGZvci4KLSAgICogQHJldHVybiAgaWYgdGhlIHN0cmluZyBhcmd1bWVudCBvY2N1cnMgb25lIG9yIG1vcmUgdGltZXMgYXMgYSBzdWJzdHJpbmcKLSAgICogICAgICAgICAgd2l0aGluIHRoaXMgb2JqZWN0LCB0aGVuIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgY2hhcmFjdGVyIG9mCi0gICAqICAgICAgICAgIHRoZSBsYXN0IHN1Y2ggc3Vic3RyaW5nIGlzIHJldHVybmVkLiBJZiBpdCBkb2VzIG5vdCBvY2N1ciBhcwotICAgKiAgICAgICAgICBhIHN1YnN0cmluZywgPGNvZGU+LTE8L2NvZGU+IGlzIHJldHVybmVkLgotICAgKiBAZXhjZXB0aW9uIGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbiAgaWYgPGNvZGU+c3RyPC9jb2RlPiBpcwotICAgKiAgICAgICAgICA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICovCi0gIHB1YmxpYyBpbnQgbGFzdEluZGV4T2YoU3RyaW5nIHN0cikKLSAgewotICAgIHJldHVybiBzdHIoKS5sYXN0SW5kZXhPZihzdHIpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIGluZGV4IHdpdGhpbiB0aGlzIHN0cmluZyBvZiB0aGUgbGFzdCBvY2N1cnJlbmNlIG9mCi0gICAqIHRoZSBzcGVjaWZpZWQgc3Vic3RyaW5nLgotICAgKgotICAgKiBAcGFyYW0gICBzdHIgICAgICAgICB0aGUgc3Vic3RyaW5nIHRvIHNlYXJjaCBmb3IuCi0gICAqIEBwYXJhbSAgIGZyb21JbmRleCAgIHRoZSBpbmRleCB0byBzdGFydCB0aGUgc2VhcmNoIGZyb20uIFRoZXJlIGlzIG5vCi0gICAqICAgICAgICAgIHJlc3RyaWN0aW9uIG9uIHRoZSB2YWx1ZSBvZiBmcm9tSW5kZXguIElmIGl0IGlzIGdyZWF0ZXIgdGhhbgotICAgKiAgICAgICAgICB0aGUgbGVuZ3RoIG9mIHRoaXMgc3RyaW5nLCBpdCBoYXMgdGhlIHNhbWUgZWZmZWN0IGFzIGlmIGl0Ci0gICAqICAgICAgICAgIHdlcmUgZXF1YWwgdG8gdGhlIGxlbmd0aCBvZiB0aGlzIHN0cmluZzogdGhpcyBlbnRpcmUgc3RyaW5nCi0gICAqICAgICAgICAgIG1heSBiZSBzZWFyY2hlZC4gSWYgaXQgaXMgbmVnYXRpdmUsIGl0IGhhcyB0aGUgc2FtZSBlZmZlY3QKLSAgICogICAgICAgICAgYXMgaWYgaXQgd2VyZSAtMTogLTEgaXMgcmV0dXJuZWQuCi0gICAqIEByZXR1cm4gIElmIHRoZSBzdHJpbmcgYXJndW1lbnQgb2NjdXJzIG9uZSBvciBtb3JlIHRpbWVzIGFzIGEgc3Vic3RyaW5nCi0gICAqICAgICAgICAgIHdpdGhpbiB0aGlzIG9iamVjdCBhdCBhIHN0YXJ0aW5nIGluZGV4IG5vIGdyZWF0ZXIgdGhhbgotICAgKiAgICAgICAgICA8Y29kZT5mcm9tSW5kZXg8L2NvZGU+LCB0aGVuIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgY2hhcmFjdGVyIG9mCi0gICAqICAgICAgICAgIHRoZSBsYXN0IHN1Y2ggc3Vic3RyaW5nIGlzIHJldHVybmVkLiBJZiBpdCBkb2VzIG5vdCBvY2N1ciBhcyBhCi0gICAqICAgICAgICAgIHN1YnN0cmluZyBzdGFydGluZyBhdCA8Y29kZT5mcm9tSW5kZXg8L2NvZGU+IG9yIGVhcmxpZXIsCi0gICAqICAgICAgICAgIDxjb2RlPi0xPC9jb2RlPiBpcyByZXR1cm5lZC4KLSAgICogQGV4Y2VwdGlvbiBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgPGNvZGU+c3RyPC9jb2RlPiBpcwotICAgKiAgICAgICAgICA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICovCi0gIHB1YmxpYyBpbnQgbGFzdEluZGV4T2YoU3RyaW5nIHN0ciwgaW50IGZyb21JbmRleCkKLSAgewotICAgIHJldHVybiBzdHIoKS5sYXN0SW5kZXhPZihzdHIsIGZyb21JbmRleCk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyBhIG5ldyBzdHJpbmcgdGhhdCBpcyBhIHN1YnN0cmluZyBvZiB0aGlzIHN0cmluZy4gVGhlCi0gICAqIHN1YnN0cmluZyBiZWdpbnMgd2l0aCB0aGUgY2hhcmFjdGVyIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXggYW5kCi0gICAqIGV4dGVuZHMgdG8gdGhlIGVuZCBvZiB0aGlzIHN0cmluZy4gPHA+Ci0gICAqIEV4YW1wbGVzOgotICAgKiA8YmxvY2txdW90ZT48cHJlPgotICAgKiAidW5oYXBweSIuc3Vic3RyaW5nKDIpIHJldHVybnMgImhhcHB5IgotICAgKiAiSGFyYmlzb24iLnN1YnN0cmluZygzKSByZXR1cm5zICJiaXNvbiIKLSAgICogImVtcHRpbmVzcyIuc3Vic3RyaW5nKDkpIHJldHVybnMgIiIgKGFuIGVtcHR5IHN0cmluZykKLSAgICogPC9wcmU+PC9ibG9ja3F1b3RlPgotICAgKgotICAgKiBAcGFyYW0gICAgICBiZWdpbkluZGV4ICAgdGhlIGJlZ2lubmluZyBpbmRleCwgaW5jbHVzaXZlLgotICAgKiBAcmV0dXJuICAgICB0aGUgc3BlY2lmaWVkIHN1YnN0cmluZy4KLSAgICogQGV4Y2VwdGlvbiAgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiAgaWYKLSAgICogICAgICAgICAgICAgPGNvZGU+YmVnaW5JbmRleDwvY29kZT4gaXMgbmVnYXRpdmUgb3IgbGFyZ2VyIHRoYW4gdGhlCi0gICAqICAgICAgICAgICAgIGxlbmd0aCBvZiB0aGlzIDxjb2RlPlN0cmluZzwvY29kZT4gb2JqZWN0LgotICAgKi8KLSAgcHVibGljIFhNTFN0cmluZyBzdWJzdHJpbmcoaW50IGJlZ2luSW5kZXgpCi0gIHsKLSAgICByZXR1cm4gbmV3IFhTdHJpbmcoc3RyKCkuc3Vic3RyaW5nKGJlZ2luSW5kZXgpKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIGEgbmV3IHN0cmluZyB0aGF0IGlzIGEgc3Vic3RyaW5nIG9mIHRoaXMgc3RyaW5nLiBUaGUKLSAgICogc3Vic3RyaW5nIGJlZ2lucyBhdCB0aGUgc3BlY2lmaWVkIDxjb2RlPmJlZ2luSW5kZXg8L2NvZGU+IGFuZAotICAgKiBleHRlbmRzIHRvIHRoZSBjaGFyYWN0ZXIgYXQgaW5kZXggPGNvZGU+ZW5kSW5kZXggLSAxPC9jb2RlPi4KLSAgICogVGh1cyB0aGUgbGVuZ3RoIG9mIHRoZSBzdWJzdHJpbmcgaXMgPGNvZGU+ZW5kSW5kZXgtYmVnaW5JbmRleDwvY29kZT4uCi0gICAqCi0gICAqIEBwYXJhbSAgICAgIGJlZ2luSW5kZXggICB0aGUgYmVnaW5uaW5nIGluZGV4LCBpbmNsdXNpdmUuCi0gICAqIEBwYXJhbSAgICAgIGVuZEluZGV4ICAgICB0aGUgZW5kaW5nIGluZGV4LCBleGNsdXNpdmUuCi0gICAqIEByZXR1cm4gICAgIHRoZSBzcGVjaWZpZWQgc3Vic3RyaW5nLgotICAgKiBAZXhjZXB0aW9uICBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uICBpZiB0aGUKLSAgICogICAgICAgICAgICAgPGNvZGU+YmVnaW5JbmRleDwvY29kZT4gaXMgbmVnYXRpdmUsIG9yCi0gICAqICAgICAgICAgICAgIDxjb2RlPmVuZEluZGV4PC9jb2RlPiBpcyBsYXJnZXIgdGhhbiB0aGUgbGVuZ3RoIG9mCi0gICAqICAgICAgICAgICAgIHRoaXMgPGNvZGU+U3RyaW5nPC9jb2RlPiBvYmplY3QsIG9yCi0gICAqICAgICAgICAgICAgIDxjb2RlPmJlZ2luSW5kZXg8L2NvZGU+IGlzIGxhcmdlciB0aGFuCi0gICAqICAgICAgICAgICAgIDxjb2RlPmVuZEluZGV4PC9jb2RlPi4KLSAgICovCi0gIHB1YmxpYyBYTUxTdHJpbmcgc3Vic3RyaW5nKGludCBiZWdpbkluZGV4LCBpbnQgZW5kSW5kZXgpCi0gIHsKLSAgICByZXR1cm4gbmV3IFhTdHJpbmcoc3RyKCkuc3Vic3RyaW5nKGJlZ2luSW5kZXgsIGVuZEluZGV4KSk7Ci0gIH0KLQotICAvKioKLSAgICogQ29uY2F0ZW5hdGVzIHRoZSBzcGVjaWZpZWQgc3RyaW5nIHRvIHRoZSBlbmQgb2YgdGhpcyBzdHJpbmcuCi0gICAqCi0gICAqIEBwYXJhbSAgIHN0ciAgIHRoZSA8Y29kZT5TdHJpbmc8L2NvZGU+IHRoYXQgaXMgY29uY2F0ZW5hdGVkIHRvIHRoZSBlbmQKLSAgICogICAgICAgICAgICAgICAgb2YgdGhpcyA8Y29kZT5TdHJpbmc8L2NvZGU+LgotICAgKiBAcmV0dXJuICBhIHN0cmluZyB0aGF0IHJlcHJlc2VudHMgdGhlIGNvbmNhdGVuYXRpb24gb2YgdGhpcyBvYmplY3QncwotICAgKiAgICAgICAgICBjaGFyYWN0ZXJzIGZvbGxvd2VkIGJ5IHRoZSBzdHJpbmcgYXJndW1lbnQncyBjaGFyYWN0ZXJzLgotICAgKiBAZXhjZXB0aW9uIGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiA8Y29kZT5zdHI8L2NvZGU+IGlzCi0gICAqICAgICAgICAgIDxjb2RlPm51bGw8L2NvZGU+LgotICAgKi8KLSAgcHVibGljIFhNTFN0cmluZyBjb25jYXQoU3RyaW5nIHN0cikKLSAgewotCi0gICAgLy8gJVJFVklFVyUgTWFrZSBhbiBGU0IgaGVyZT8KLSAgICByZXR1cm4gbmV3IFhTdHJpbmcoc3RyKCkuY29uY2F0KHN0cikpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbnZlcnRzIGFsbCBvZiB0aGUgY2hhcmFjdGVycyBpbiB0aGlzIDxjb2RlPlN0cmluZzwvY29kZT4gdG8gbG93ZXIKLSAgICogY2FzZSB1c2luZyB0aGUgcnVsZXMgb2YgdGhlIGdpdmVuIDxjb2RlPkxvY2FsZTwvY29kZT4uCi0gICAqCi0gICAqIEBwYXJhbSBsb2NhbGUgdXNlIHRoZSBjYXNlIHRyYW5zZm9ybWF0aW9uIHJ1bGVzIGZvciB0aGlzIGxvY2FsZQotICAgKiBAcmV0dXJuIHRoZSBTdHJpbmcsIGNvbnZlcnRlZCB0byBsb3dlcmNhc2UuCi0gICAqIEBzZWUgICAgIGphdmEubGFuZy5DaGFyYWN0ZXIjdG9Mb3dlckNhc2UoY2hhcikKLSAgICogQHNlZSAgICAgamF2YS5sYW5nLlN0cmluZyN0b1VwcGVyQ2FzZShMb2NhbGUpCi0gICAqLwotICBwdWJsaWMgWE1MU3RyaW5nIHRvTG93ZXJDYXNlKExvY2FsZSBsb2NhbGUpCi0gIHsKLSAgICByZXR1cm4gbmV3IFhTdHJpbmcoc3RyKCkudG9Mb3dlckNhc2UobG9jYWxlKSk7Ci0gIH0KLQotICAvKioKLSAgICogQ29udmVydHMgYWxsIG9mIHRoZSBjaGFyYWN0ZXJzIGluIHRoaXMgPGNvZGU+U3RyaW5nPC9jb2RlPiB0byBsb3dlcgotICAgKiBjYXNlIHVzaW5nIHRoZSBydWxlcyBvZiB0aGUgZGVmYXVsdCBsb2NhbGUsIHdoaWNoIGlzIHJldHVybmVkCi0gICAqIGJ5IDxjb2RlPkxvY2FsZS5nZXREZWZhdWx0PC9jb2RlPi4KLSAgICogPHA+Ci0gICAqCi0gICAqIEByZXR1cm4gIHRoZSBzdHJpbmcsIGNvbnZlcnRlZCB0byBsb3dlcmNhc2UuCi0gICAqIEBzZWUgICAgIGphdmEubGFuZy5DaGFyYWN0ZXIjdG9Mb3dlckNhc2UoY2hhcikKLSAgICogQHNlZSAgICAgamF2YS5sYW5nLlN0cmluZyN0b0xvd2VyQ2FzZShMb2NhbGUpCi0gICAqLwotICBwdWJsaWMgWE1MU3RyaW5nIHRvTG93ZXJDYXNlKCkKLSAgewotICAgIHJldHVybiBuZXcgWFN0cmluZyhzdHIoKS50b0xvd2VyQ2FzZSgpKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb252ZXJ0cyBhbGwgb2YgdGhlIGNoYXJhY3RlcnMgaW4gdGhpcyA8Y29kZT5TdHJpbmc8L2NvZGU+IHRvIHVwcGVyCi0gICAqIGNhc2UgdXNpbmcgdGhlIHJ1bGVzIG9mIHRoZSBnaXZlbiBsb2NhbGUuCi0gICAqIEBwYXJhbSBsb2NhbGUgdXNlIHRoZSBjYXNlIHRyYW5zZm9ybWF0aW9uIHJ1bGVzIGZvciB0aGlzIGxvY2FsZQotICAgKiBAcmV0dXJuIHRoZSBTdHJpbmcsIGNvbnZlcnRlZCB0byB1cHBlcmNhc2UuCi0gICAqIEBzZWUgICAgIGphdmEubGFuZy5DaGFyYWN0ZXIjdG9VcHBlckNhc2UoY2hhcikKLSAgICogQHNlZSAgICAgamF2YS5sYW5nLlN0cmluZyN0b0xvd2VyQ2FzZShMb2NhbGUpCi0gICAqLwotICBwdWJsaWMgWE1MU3RyaW5nIHRvVXBwZXJDYXNlKExvY2FsZSBsb2NhbGUpCi0gIHsKLSAgICByZXR1cm4gbmV3IFhTdHJpbmcoc3RyKCkudG9VcHBlckNhc2UobG9jYWxlKSk7Ci0gIH0KLQotICAvKioKLSAgICogQ29udmVydHMgYWxsIG9mIHRoZSBjaGFyYWN0ZXJzIGluIHRoaXMgPGNvZGU+U3RyaW5nPC9jb2RlPiB0byB1cHBlcgotICAgKiBjYXNlIHVzaW5nIHRoZSBydWxlcyBvZiB0aGUgZGVmYXVsdCBsb2NhbGUsIHdoaWNoIGlzIHJldHVybmVkCi0gICAqIGJ5IDxjb2RlPkxvY2FsZS5nZXREZWZhdWx0PC9jb2RlPi4KLSAgICoKLSAgICogPHA+Ci0gICAqIElmIG5vIGNoYXJhY3RlciBpbiB0aGlzIHN0cmluZyBoYXMgYSBkaWZmZXJlbnQgdXBwZXJjYXNlIHZlcnNpb24sCi0gICAqIGJhc2VkIG9uIGNhbGxpbmcgdGhlIDxjb2RlPnRvVXBwZXJDYXNlPC9jb2RlPiBtZXRob2QgZGVmaW5lZCBieQotICAgKiA8Y29kZT5DaGFyYWN0ZXI8L2NvZGU+LCB0aGVuIHRoZSBvcmlnaW5hbCBzdHJpbmcgaXMgcmV0dXJuZWQuCi0gICAqIDxwPgotICAgKiBPdGhlcndpc2UsIHRoaXMgbWV0aG9kIGNyZWF0ZXMgYSBuZXcgPGNvZGU+U3RyaW5nPC9jb2RlPiBvYmplY3QKLSAgICogcmVwcmVzZW50aW5nIGEgY2hhcmFjdGVyIHNlcXVlbmNlIGlkZW50aWNhbCBpbiBsZW5ndGggdG8gdGhlCi0gICAqIGNoYXJhY3RlciBzZXF1ZW5jZSByZXByZXNlbnRlZCBieSB0aGlzIDxjb2RlPlN0cmluZzwvY29kZT4gb2JqZWN0IGFuZAotICAgKiB3aXRoIGV2ZXJ5IGNoYXJhY3RlciBlcXVhbCB0byB0aGUgcmVzdWx0IG9mIGFwcGx5aW5nIHRoZSBtZXRob2QKLSAgICogPGNvZGU+Q2hhcmFjdGVyLnRvVXBwZXJDYXNlPC9jb2RlPiB0byB0aGUgY29ycmVzcG9uZGluZyBjaGFyYWN0ZXIgb2YKLSAgICogdGhpcyA8Y29kZT5TdHJpbmc8L2NvZGU+IG9iamVjdC4gPHA+Ci0gICAqIEV4YW1wbGVzOgotICAgKiA8YmxvY2txdW90ZT48cHJlPgotICAgKiAiRmFocnZlcmduJnV1bWw7Z2VuIi50b1VwcGVyQ2FzZSgpIHJldHVybnMgIkZBSFJWRVJHTiZVdW1sO0dFTiIKLSAgICogIlZpc2l0IExqdWJpbmplISIudG9VcHBlckNhc2UoKSByZXR1cm5zICJWSVNJVCBMSlVCSU5KRSEiCi0gICAqIDwvcHJlPjwvYmxvY2txdW90ZT4KLSAgICoKLSAgICogQHJldHVybiAgdGhlIHN0cmluZywgY29udmVydGVkIHRvIHVwcGVyY2FzZS4KLSAgICogQHNlZSAgICAgamF2YS5sYW5nLkNoYXJhY3RlciN0b1VwcGVyQ2FzZShjaGFyKQotICAgKiBAc2VlICAgICBqYXZhLmxhbmcuU3RyaW5nI3RvVXBwZXJDYXNlKExvY2FsZSkKLSAgICovCi0gIHB1YmxpYyBYTUxTdHJpbmcgdG9VcHBlckNhc2UoKQotICB7Ci0gICAgcmV0dXJuIG5ldyBYU3RyaW5nKHN0cigpLnRvVXBwZXJDYXNlKCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlbW92ZXMgd2hpdGUgc3BhY2UgZnJvbSBib3RoIGVuZHMgb2YgdGhpcyBzdHJpbmcuCi0gICAqCi0gICAqIEByZXR1cm4gIHRoaXMgc3RyaW5nLCB3aXRoIHdoaXRlIHNwYWNlIHJlbW92ZWQgZnJvbSB0aGUgZnJvbnQgYW5kIGVuZC4KLSAgICovCi0gIHB1YmxpYyBYTUxTdHJpbmcgdHJpbSgpCi0gIHsKLSAgICByZXR1cm4gbmV3IFhTdHJpbmcoc3RyKCkudHJpbSgpKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhlIHNwZWNpZmllZCA8dmFyPmNoPC92YXI+IGNvbmZvcm1zIHRvIHRoZSBYTUwgMS4wIGRlZmluaXRpb24KLSAgICogb2Ygd2hpdGVzcGFjZS4gIFJlZmVyIHRvIDxBIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLXhtbC0xOTk4MDIxMCNOVC1TIj4KLSAgICogdGhlIGRlZmluaXRpb24gb2YgPENPREU+UzwvQ09ERT48L0E+IGZvciBkZXRhaWxzLgotICAgKiBAcGFyYW0gICBjaCAgICAgIENoYXJhY3RlciB0byBjaGVjayBhcyBYTUwgd2hpdGVzcGFjZS4KLSAgICogQHJldHVybiAgICAgICAgICA9dHJ1ZSBpZiA8dmFyPmNoPC92YXI+IGlzIFhNTCB3aGl0ZXNwYWNlOyBvdGhlcndpc2UgPWZhbHNlLgotICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBpc1NwYWNlKGNoYXIgY2gpCi0gIHsKLSAgICByZXR1cm4gWE1MQ2hhcmFjdGVyUmVjb2duaXplci5pc1doaXRlU3BhY2UoY2gpOyAgLy8gVGFrZSB0aGUgZWFzeSB3YXkgb3V0IGZvciBub3cuCi0gIH0KLQotICAvKioKLSAgICogQ29uZGl0aW9uYWxseSB0cmltIGFsbCBsZWFkaW5nIGFuZCB0cmFpbGluZyB3aGl0ZXNwYWNlIGluIHRoZSBzcGVjaWZpZWQgU3RyaW5nLgotICAgKiBBbGwgc3RyaW5ncyBvZiB3aGl0ZSBzcGFjZSBhcmUKLSAgICogcmVwbGFjZWQgYnkgYSBzaW5nbGUgc3BhY2UgY2hhcmFjdGVyICgjeDIwKSwgZXhjZXB0IHNwYWNlcyBhZnRlciBwdW5jdHVhdGlvbiB3aGljaAotICAgKiByZWNlaXZlIGRvdWJsZSBzcGFjZXMgaWYgZG91YmxlUHVuY3R1YXRpb25TcGFjZXMgaXMgdHJ1ZS4KLSAgICogVGhpcyBmdW5jdGlvbiBtYXkgYmUgdXNlZnVsIHRvIGEgZm9ybWF0dGVyLCBidXQgdG8gZ2V0IGZpcnN0IGNsYXNzCi0gICAqIHJlc3VsdHMsIHRoZSBmb3JtYXR0ZXIgc2hvdWxkIHByb2JhYmx5IGRvIGl0J3Mgb3duIHdoaXRlIHNwYWNlIGhhbmRsaW5nCi0gICAqIGJhc2VkIG9uIHRoZSBzZW1hbnRpY3Mgb2YgdGhlIGZvcm1hdHRpbmcgb2JqZWN0LgotICAgKgotICAgKiBAcGFyYW0gICB0cmltSGVhZCAgICBUcmltIGxlYWRpbmcgd2hpdGVzcGFjZT8KLSAgICogQHBhcmFtICAgdHJpbVRhaWwgICAgVHJpbSB0cmFpbGluZyB3aGl0ZXNwYWNlPwotICAgKiBAcGFyYW0gICBkb3VibGVQdW5jdHVhdGlvblNwYWNlcyAgICBVc2UgZG91YmxlIHNwYWNlcyBmb3IgcHVuY3R1YXRpb24/Ci0gICAqIEByZXR1cm4gICAgICAgICAgICAgIFRoZSB0cmltbWVkIHN0cmluZy4KLSAgICovCi0gIHB1YmxpYyBYTUxTdHJpbmcgZml4V2hpdGVTcGFjZShib29sZWFuIHRyaW1IZWFkLCBib29sZWFuIHRyaW1UYWlsLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBkb3VibGVQdW5jdHVhdGlvblNwYWNlcykKLSAgewotCi0gICAgLy8gJU9QVCUgISEhISEhIQotICAgIGludCBsZW4gPSB0aGlzLmxlbmd0aCgpOwotICAgIGNoYXJbXSBidWYgPSBuZXcgY2hhcltsZW5dOwotCi0gICAgdGhpcy5nZXRDaGFycygwLCBsZW4sIGJ1ZiwgMCk7Ci0KLSAgICBib29sZWFuIGVkaXQgPSBmYWxzZTsKLSAgICBpbnQgczsKLQotICAgIGZvciAocyA9IDA7IHMgPCBsZW47IHMrKykKLSAgICB7Ci0gICAgICBpZiAoaXNTcGFjZShidWZbc10pKQotICAgICAgewotICAgICAgICBicmVhazsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICAvKiByZXBsYWNlIFMgdG8gJyAnLiBhbmQgJyAnKyAtPiBzaW5nbGUgJyAnLiAqLwotICAgIGludCBkID0gczsKLSAgICBib29sZWFuIHByZXMgPSBmYWxzZTsKLQotICAgIGZvciAoOyBzIDwgbGVuOyBzKyspCi0gICAgewotICAgICAgY2hhciBjID0gYnVmW3NdOwotCi0gICAgICBpZiAoaXNTcGFjZShjKSkKLSAgICAgIHsKLSAgICAgICAgaWYgKCFwcmVzKQotICAgICAgICB7Ci0gICAgICAgICAgaWYgKCcgJyAhPSBjKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGVkaXQgPSB0cnVlOwotICAgICAgICAgIH0KLQotICAgICAgICAgIGJ1ZltkKytdID0gJyAnOwotCi0gICAgICAgICAgaWYgKGRvdWJsZVB1bmN0dWF0aW9uU3BhY2VzICYmIChzICE9IDApKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGNoYXIgcHJldkNoYXIgPSBidWZbcyAtIDFdOwotCi0gICAgICAgICAgICBpZiAoISgocHJldkNoYXIgPT0gJy4nKSB8fCAocHJldkNoYXIgPT0gJyEnKQotICAgICAgICAgICAgICAgICAgfHwgKHByZXZDaGFyID09ICc/JykpKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICBwcmVzID0gdHJ1ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICB9Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgIHsKLSAgICAgICAgICAgIHByZXMgPSB0cnVlOwotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgIHsKLSAgICAgICAgICBlZGl0ID0gdHJ1ZTsKLSAgICAgICAgICBwcmVzID0gdHJ1ZTsKLSAgICAgICAgfQotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBidWZbZCsrXSA9IGM7Ci0gICAgICAgIHByZXMgPSBmYWxzZTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICBpZiAodHJpbVRhaWwgJiYgMSA8PSBkICYmICcgJyA9PSBidWZbZCAtIDFdKQotICAgIHsKLSAgICAgIGVkaXQgPSB0cnVlOwotCi0gICAgICBkLS07Ci0gICAgfQotCi0gICAgaW50IHN0YXJ0ID0gMDsKLQotICAgIGlmICh0cmltSGVhZCAmJiAwIDwgZCAmJiAnICcgPT0gYnVmWzBdKQotICAgIHsKLSAgICAgIGVkaXQgPSB0cnVlOwotCi0gICAgICBzdGFydCsrOwotICAgIH0KLQotICAgIFhNTFN0cmluZ0ZhY3RvcnkgeHNmID0gWE1MU3RyaW5nRmFjdG9yeUltcGwuZ2V0RmFjdG9yeSgpOwotCi0gICAgcmV0dXJuIGVkaXQgPyB4c2YubmV3c3RyKG5ldyBTdHJpbmcoYnVmLCBzdGFydCwgZCAtIHN0YXJ0KSkgOiB0aGlzOwotICB9Ci0KLSAgLyoqCi0gICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoVmlzaXRhYmxlI2NhbGxWaXNpdG9ycyhFeHByZXNzaW9uT3duZXIsIFhQYXRoVmlzaXRvcikKLSAgICovCi0gIHB1YmxpYyB2b2lkIGNhbGxWaXNpdG9ycyhFeHByZXNzaW9uT3duZXIgb3duZXIsIFhQYXRoVmlzaXRvciB2aXNpdG9yKQotICB7Ci0gICAgICAgIHZpc2l0b3IudmlzaXRTdHJpbmdMaXRlcmFsKG93bmVyLCB0aGlzKTsKLSAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL29iamVjdHMvWFN0cmluZ0ZvckNoYXJzLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL29iamVjdHMvWFN0cmluZ0ZvckNoYXJzLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDRmYjczNjMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9vYmplY3RzL1hTdHJpbmdGb3JDaGFycy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjE4ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFhTdHJpbmdGb3JDaGFycy5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE0IDIwOjQ2OjI3IGplZmZzdXR0b3IgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0czsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC5yZXMuWFNMTWVzc2FnZXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5GYXN0U3RyaW5nQnVmZmVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5yZXMuWFBBVEhFcnJvclJlc291cmNlczsKLQotCi0vKioKLSAqIFRoaXMgY2xhc3Mgd2lsbCB3cmFwIGEgRmFzdFN0cmluZ0J1ZmZlciBhbmQgYWxsb3cgZm9yCi0gKi8KLXB1YmxpYyBjbGFzcyBYU3RyaW5nRm9yQ2hhcnMgZXh0ZW5kcyBYU3RyaW5nCi17Ci0gICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC0yMjM1MjQ4ODg3MjIwODUwNDY3TDsKLSAgLyoqIFRoZSBzdGFydCBwb3NpdGlvbiBpbiB0aGUgZnNiLiAqLwotICBpbnQgbV9zdGFydDsKLQotICAvKiogVGhlIGxlbmd0aCBvZiB0aGUgc3RyaW5nLiAqLwotICBpbnQgbV9sZW5ndGg7Ci0KLSAgcHJvdGVjdGVkIFN0cmluZyBtX3N0ckNhY2hlID0gbnVsbDsKLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgWE5vZGVTZXQgb2JqZWN0LgotICAgKgotICAgKiBAcGFyYW0gdmFsIEZhc3RTdHJpbmdCdWZmZXIgb2JqZWN0IHRoaXMgd2lsbCB3cmFwLCBtdXN0IGJlIG5vbi1udWxsLgotICAgKiBAcGFyYW0gc3RhcnQgVGhlIHN0YXJ0IHBvc2l0aW9uIGluIHRoZSBhcnJheS4KLSAgICogQHBhcmFtIGxlbmd0aCBUaGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gcmVhZCBmcm9tIHRoZSBhcnJheS4KLSAgICovCi0gIHB1YmxpYyBYU3RyaW5nRm9yQ2hhcnMoY2hhcltdIHZhbCwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKQotICB7Ci0gICAgc3VwZXIodmFsKTsKLSAgICBtX3N0YXJ0ID0gc3RhcnQ7Ci0gICAgbV9sZW5ndGggPSBsZW5ndGg7Ci0gICAgaWYobnVsbCA9PSB2YWwpCi0gICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICAgICAgICBYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoWFBBVEhFcnJvclJlc291cmNlcy5FUl9GQVNUU1RSSU5HQlVGRkVSX0NBTk5PVF9CRV9OVUxMLCBudWxsKSk7IC8vIlRoZSBGYXN0U3RyaW5nQnVmZmVyIGFyZ3VtZW50IGNhbiBub3QgYmUgbnVsbCEhIik7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBYTm9kZVNldCBvYmplY3QuCi0gICAqCi0gICAqIEBwYXJhbSB2YWwgU3RyaW5nIG9iamVjdCB0aGlzIHdpbGwgd3JhcC4KLSAgICovCi0gIHByaXZhdGUgWFN0cmluZ0ZvckNoYXJzKFN0cmluZyB2YWwpCi0gIHsKLSAgICBzdXBlcih2YWwpOwotICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgICAgWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfWFNUUklOR0ZPUkNIQVJTX0NBTk5PVF9UQUtFX1NUUklORywgbnVsbCkpOyAvLyJYU3RyaW5nRm9yQ2hhcnMgY2FuIG5vdCB0YWtlIGEgc3RyaW5nIGZvciBhbiBhcmd1bWVudCEiKTsKLSAgfQotCi0gIC8qKgotICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYSBzdHJpbmcuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHN0cmluZyB0aGlzIHdyYXBzIG9yIHRoZSBlbXB0eSBzdHJpbmcgaWYgbnVsbAotICAgKi8KLSAgcHVibGljIEZhc3RTdHJpbmdCdWZmZXIgZnNiKCkKLSAgewotICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShYUEFUSEVycm9yUmVzb3VyY2VzLkVSX0ZTQl9OT1RfU1VQUE9SVEVEX1hTVFJJTkdGT1JDSEFSUywgbnVsbCkpOyAvLyJmc2IoKSBub3Qgc3VwcG9ydGVkIGZvciBYU3RyaW5nRm9yQ2hhcnMhIik7Ci0gIH0KLQotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGEgc3RyaW5nLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBzdHJpbmcgdGhpcyB3cmFwcyBvciB0aGUgZW1wdHkgc3RyaW5nIGlmIG51bGwKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFwcGVuZFRvRnNiKGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuRmFzdFN0cmluZ0J1ZmZlciBmc2IpCi0gIHsKLSAgICBmc2IuYXBwZW5kKChjaGFyW10pbV9vYmosIG1fc3RhcnQsIG1fbGVuZ3RoKTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIFRlbGwgaWYgdGhpcyBvYmplY3QgY29udGFpbnMgYSBqYXZhIFN0cmluZyBvYmplY3QuCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGlzIFhNTFN0cmluZyBjYW4gcmV0dXJuIGEgc3RyaW5nIHdpdGhvdXQgY3JlYXRpbmcgb25lLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaGFzU3RyaW5nKCkKLSAgewotICAgIHJldHVybiAobnVsbCAhPSBtX3N0ckNhY2hlKTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIENhc3QgcmVzdWx0IG9iamVjdCB0byBhIHN0cmluZy4KLSAgICoKLSAgICogQHJldHVybiBUaGUgc3RyaW5nIHRoaXMgd3JhcHMgb3IgdGhlIGVtcHR5IHN0cmluZyBpZiBudWxsCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIHN0cigpCi0gIHsKLSAgICBpZihudWxsID09IG1fc3RyQ2FjaGUpCi0gICAgICBtX3N0ckNhY2hlID0gbmV3IFN0cmluZygoY2hhcltdKW1fb2JqLCBtX3N0YXJ0LCBtX2xlbmd0aCk7Ci0KLSAgICByZXR1cm4gbV9zdHJDYWNoZTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIFNpbmNlIHRoaXMgb2JqZWN0IGlzIGluY29tcGxldGUgd2l0aG91dCB0aGUgbGVuZ3RoIGFuZCB0aGUgb2Zmc2V0LCB3ZQotICAgKiBoYXZlIHRvIGNvbnZlcnQgdG8gYSBzdHJpbmcgd2hlbiB0aGlzIGZ1bmN0aW9uIGlzIGNhbGxlZC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgamF2YSBTdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBvYmplY3QuCi0gICAqLwotICBwdWJsaWMgT2JqZWN0IG9iamVjdCgpCi0gIHsKLSAgICByZXR1cm4gc3RyKCk7Ci0gIH0KLQotICAvKioKLSAgICogRGlyZWN0bHkgY2FsbCB0aGUKLSAgICogY2hhcmFjdGVycyBtZXRob2Qgb24gdGhlIHBhc3NlZCBDb250ZW50SGFuZGxlciBmb3IgdGhlCi0gICAqIHN0cmluZy12YWx1ZS4gTXVsdGlwbGUgY2FsbHMgdG8gdGhlCi0gICAqIENvbnRlbnRIYW5kbGVyJ3MgY2hhcmFjdGVycyBtZXRob2RzIG1heSB3ZWxsIG9jY3VyIGZvciBhIHNpbmdsZSBjYWxsIHRvCi0gICAqIHRoaXMgbWV0aG9kLgotICAgKgotICAgKiBAcGFyYW0gY2ggQSBub24tbnVsbCByZWZlcmVuY2UgdG8gYSBDb250ZW50SGFuZGxlci4KLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGRpc3BhdGNoQ2hhcmFjdGVyc0V2ZW50cyhvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciBjaCkKLSAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIGNoLmNoYXJhY3RlcnMoKGNoYXJbXSltX29iaiwgbV9zdGFydCwgbV9sZW5ndGgpOwotICB9Ci0KLSAgLyoqCi0gICAqIERpcmVjdGx5IGNhbGwgdGhlCi0gICAqIGNvbW1lbnQgbWV0aG9kIG9uIHRoZSBwYXNzZWQgTGV4aWNhbEhhbmRsZXIgZm9yIHRoZQotICAgKiBzdHJpbmctdmFsdWUuCi0gICAqCi0gICAqIEBwYXJhbSBsaCBBIG5vbi1udWxsIHJlZmVyZW5jZSB0byBhIExleGljYWxIYW5kbGVyLgotICAgKgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgZGlzcGF0Y2hBc0NvbW1lbnQob3JnLnhtbC5zYXguZXh0LkxleGljYWxIYW5kbGVyIGxoKQotICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgbGguY29tbWVudCgoY2hhcltdKW1fb2JqLCBtX3N0YXJ0LCBtX2xlbmd0aCk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgbGVuZ3RoIG9mIHRoaXMgc3RyaW5nLgotICAgKgotICAgKiBAcmV0dXJuICB0aGUgbGVuZ3RoIG9mIHRoZSBzZXF1ZW5jZSBvZiBjaGFyYWN0ZXJzIHJlcHJlc2VudGVkIGJ5IHRoaXMKLSAgICogICAgICAgICAgb2JqZWN0LgotICAgKi8KLSAgcHVibGljIGludCBsZW5ndGgoKQotICB7Ci0gICAgcmV0dXJuIG1fbGVuZ3RoOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIGNoYXJhY3RlciBhdCB0aGUgc3BlY2lmaWVkIGluZGV4LiBBbiBpbmRleCByYW5nZXMKLSAgICogZnJvbSA8Y29kZT4wPC9jb2RlPiB0byA8Y29kZT5sZW5ndGgoKSAtIDE8L2NvZGU+LiBUaGUgZmlyc3QgY2hhcmFjdGVyCi0gICAqIG9mIHRoZSBzZXF1ZW5jZSBpcyBhdCBpbmRleCA8Y29kZT4wPC9jb2RlPiwgdGhlIG5leHQgYXQgaW5kZXgKLSAgICogPGNvZGU+MTwvY29kZT4sIGFuZCBzbyBvbiwgYXMgZm9yIGFycmF5IGluZGV4aW5nLgotICAgKgotICAgKiBAcGFyYW0gICAgICBpbmRleCAgIHRoZSBpbmRleCBvZiB0aGUgY2hhcmFjdGVyLgotICAgKiBAcmV0dXJuICAgICB0aGUgY2hhcmFjdGVyIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXggb2YgdGhpcyBzdHJpbmcuCi0gICAqICAgICAgICAgICAgIFRoZSBmaXJzdCBjaGFyYWN0ZXIgaXMgYXQgaW5kZXggPGNvZGU+MDwvY29kZT4uCi0gICAqIEBleGNlcHRpb24gIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gIGlmIHRoZSA8Y29kZT5pbmRleDwvY29kZT4KLSAgICogICAgICAgICAgICAgYXJndW1lbnQgaXMgbmVnYXRpdmUgb3Igbm90IGxlc3MgdGhhbiB0aGUgbGVuZ3RoIG9mIHRoaXMKLSAgICogICAgICAgICAgICAgc3RyaW5nLgotICAgKi8KLSAgcHVibGljIGNoYXIgY2hhckF0KGludCBpbmRleCkKLSAgewotICAgIHJldHVybiAoKGNoYXJbXSltX29iailbaW5kZXgrbV9zdGFydF07Ci0gIH0KLQotICAvKioKLSAgICogQ29waWVzIGNoYXJhY3RlcnMgZnJvbSB0aGlzIHN0cmluZyBpbnRvIHRoZSBkZXN0aW5hdGlvbiBjaGFyYWN0ZXIKLSAgICogYXJyYXkuCi0gICAqCi0gICAqIEBwYXJhbSAgICAgIHNyY0JlZ2luICAgaW5kZXggb2YgdGhlIGZpcnN0IGNoYXJhY3RlciBpbiB0aGUgc3RyaW5nCi0gICAqICAgICAgICAgICAgICAgICAgICAgICAgdG8gY29weS4KLSAgICogQHBhcmFtICAgICAgc3JjRW5kICAgICBpbmRleCBhZnRlciB0aGUgbGFzdCBjaGFyYWN0ZXIgaW4gdGhlIHN0cmluZwotICAgKiAgICAgICAgICAgICAgICAgICAgICAgIHRvIGNvcHkuCi0gICAqIEBwYXJhbSAgICAgIGRzdCAgICAgICAgdGhlIGRlc3RpbmF0aW9uIGFycmF5LgotICAgKiBAcGFyYW0gICAgICBkc3RCZWdpbiAgIHRoZSBzdGFydCBvZmZzZXQgaW4gdGhlIGRlc3RpbmF0aW9uIGFycmF5LgotICAgKiBAZXhjZXB0aW9uIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gSWYgYW55IG9mIHRoZSBmb2xsb3dpbmcKLSAgICogICAgICAgICAgICBpcyB0cnVlOgotICAgKiAgICAgICAgICAgIDx1bD48bGk+PGNvZGU+c3JjQmVnaW48L2NvZGU+IGlzIG5lZ2F0aXZlLgotICAgKiAgICAgICAgICAgIDxsaT48Y29kZT5zcmNCZWdpbjwvY29kZT4gaXMgZ3JlYXRlciB0aGFuIDxjb2RlPnNyY0VuZDwvY29kZT4KLSAgICogICAgICAgICAgICA8bGk+PGNvZGU+c3JjRW5kPC9jb2RlPiBpcyBncmVhdGVyIHRoYW4gdGhlIGxlbmd0aCBvZiB0aGlzCi0gICAqICAgICAgICAgICAgICAgIHN0cmluZwotICAgKiAgICAgICAgICAgIDxsaT48Y29kZT5kc3RCZWdpbjwvY29kZT4gaXMgbmVnYXRpdmUKLSAgICogICAgICAgICAgICA8bGk+PGNvZGU+ZHN0QmVnaW4rKHNyY0VuZC1zcmNCZWdpbik8L2NvZGU+IGlzIGxhcmdlciB0aGFuCi0gICAqICAgICAgICAgICAgICAgIDxjb2RlPmRzdC5sZW5ndGg8L2NvZGU+PC91bD4KLSAgICogQGV4Y2VwdGlvbiBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiA8Y29kZT5kc3Q8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+Ci0gICAqLwotICBwdWJsaWMgdm9pZCBnZXRDaGFycyhpbnQgc3JjQmVnaW4sIGludCBzcmNFbmQsIGNoYXIgZHN0W10sIGludCBkc3RCZWdpbikKLSAgewotICAgIFN5c3RlbS5hcnJheWNvcHkoKGNoYXJbXSltX29iaiwgbV9zdGFydCtzcmNCZWdpbiwgZHN0LCBkc3RCZWdpbiwgc3JjRW5kKTsKLSAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL29iamVjdHMvWFN0cmluZ0ZvckZTQi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9vYmplY3RzL1hTdHJpbmdGb3JGU0IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZDYzMTA2NC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL29iamVjdHMvWFN0cmluZ0ZvckZTQi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTg4ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFhTdHJpbmdGb3JGU0IuamF2YSx2IDEuMi40LjIgMjAwNS8wOS8xNCAyMDo0NjoyNyBqZWZmc3V0dG9yIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwucmVzLlhTTE1lc3NhZ2VzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuRmFzdFN0cmluZ0J1ZmZlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLlhNTENoYXJhY3RlclJlY29nbml6ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5YTUxTdHJpbmc7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5YTUxTdHJpbmdGYWN0b3J5OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5yZXMuWFBBVEhFcnJvclJlc291cmNlczsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIHdpbGwgd3JhcCBhIEZhc3RTdHJpbmdCdWZmZXIgYW5kIGFsbG93IGZvcgotICovCi1wdWJsaWMgY2xhc3MgWFN0cmluZ0ZvckZTQiBleHRlbmRzIFhTdHJpbmcKLXsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTE1MzMwMzkxODY1NTA2NzQ1NDhMOwotCi0gIC8qKiBUaGUgc3RhcnQgcG9zaXRpb24gaW4gdGhlIGZzYi4gKi8KLSAgaW50IG1fc3RhcnQ7Ci0KLSAgLyoqIFRoZSBsZW5ndGggb2YgdGhlIHN0cmluZy4gKi8KLSAgaW50IG1fbGVuZ3RoOwotCi0gIC8qKiBJZiB0aGUgc3RyKCkgZnVuY3Rpb24gaXMgY2FsbGVkLCB0aGUgc3RyaW5nIHdpbGwgYmUgY2FjaGVkIGhlcmUuICovCi0gIHByb3RlY3RlZCBTdHJpbmcgbV9zdHJDYWNoZSA9IG51bGw7Ci0KLSAgLyoqIGNhY2hlZCBoYXNoIGNvZGUgKi8KLSAgcHJvdGVjdGVkIGludCBtX2hhc2ggPSAwOwotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBYTm9kZVNldCBvYmplY3QuCi0gICAqCi0gICAqIEBwYXJhbSB2YWwgRmFzdFN0cmluZ0J1ZmZlciBvYmplY3QgdGhpcyB3aWxsIHdyYXAsIG11c3QgYmUgbm9uLW51bGwuCi0gICAqIEBwYXJhbSBzdGFydCBUaGUgc3RhcnQgcG9zaXRpb24gaW4gdGhlIGFycmF5LgotICAgKiBAcGFyYW0gbGVuZ3RoIFRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyB0byByZWFkIGZyb20gdGhlIGFycmF5LgotICAgKi8KLSAgcHVibGljIFhTdHJpbmdGb3JGU0IoRmFzdFN0cmluZ0J1ZmZlciB2YWwsIGludCBzdGFydCwgaW50IGxlbmd0aCkKLSAgewotCi0gICAgc3VwZXIodmFsKTsKLQotICAgIG1fc3RhcnQgPSBzdGFydDsKLSAgICBtX2xlbmd0aCA9IGxlbmd0aDsKLQotICAgIGlmIChudWxsID09IHZhbCkKLSAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCi0gICAgICAgIFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShYUEFUSEVycm9yUmVzb3VyY2VzLkVSX0ZBU1RTVFJJTkdCVUZGRVJfQ0FOTk9UX0JFX05VTEwsIG51bGwpKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBYTm9kZVNldCBvYmplY3QuCi0gICAqCi0gICAqIEBwYXJhbSB2YWwgU3RyaW5nIG9iamVjdCB0aGlzIHdpbGwgd3JhcC4KLSAgICovCi0gIHByaXZhdGUgWFN0cmluZ0ZvckZTQihTdHJpbmcgdmFsKQotICB7Ci0KLSAgICBzdXBlcih2YWwpOwotCi0gICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKLSAgICAgIFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShYUEFUSEVycm9yUmVzb3VyY2VzLkVSX0ZTQl9DQU5OT1RfVEFLRV9TVFJJTkcsIG51bGwpKTsgLy8gIlhTdHJpbmdGb3JGU0IgY2FuIG5vdCB0YWtlIGEgc3RyaW5nIGZvciBhbiBhcmd1bWVudCEiKTsKLSAgfQotCi0gIC8qKgotICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYSBzdHJpbmcuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHN0cmluZyB0aGlzIHdyYXBzIG9yIHRoZSBlbXB0eSBzdHJpbmcgaWYgbnVsbAotICAgKi8KLSAgcHVibGljIEZhc3RTdHJpbmdCdWZmZXIgZnNiKCkKLSAgewotICAgIHJldHVybiAoKEZhc3RTdHJpbmdCdWZmZXIpIG1fb2JqKTsKLSAgfQotCi0gIC8qKgotICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYSBzdHJpbmcuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHN0cmluZyB0aGlzIHdyYXBzIG9yIHRoZSBlbXB0eSBzdHJpbmcgaWYgbnVsbAotICAgKi8KLSAgcHVibGljIHZvaWQgYXBwZW5kVG9Gc2IoY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy5GYXN0U3RyaW5nQnVmZmVyIGZzYikKLSAgewotICAgIC8vICVPUFQlICEhISBGU0IgaGFzIHRvIGJlIHVwZGF0ZWQgdG8gdGFrZSBwYXJ0aWFsIGZzYidzIGZvciBhcHBlbmQuCi0gICAgZnNiLmFwcGVuZChzdHIoKSk7Ci0gIH0KLQotICAvKioKLSAgICogVGVsbCBpZiB0aGlzIG9iamVjdCBjb250YWlucyBhIGphdmEgU3RyaW5nIG9iamVjdC4KLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHRoaXMgWE1MU3RyaW5nIGNhbiByZXR1cm4gYSBzdHJpbmcgd2l0aG91dCBjcmVhdGluZyBvbmUuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBoYXNTdHJpbmcoKQotICB7Ci0gICAgcmV0dXJuIChudWxsICE9IG1fc3RyQ2FjaGUpOwotICB9Ci0KLS8vICAvKiogTkVFRFNET0MgRmllbGQgc3RyQ291bnQgKi8KLS8vICBwdWJsaWMgc3RhdGljIGludCBzdHJDb3VudCA9IDA7Ci0vLwotLy8gIC8qKiBORUVEU0RPQyBGaWVsZCB4dGFibGUgKi8KLS8vICBzdGF0aWMgamF2YS51dGlsLkhhc2h0YWJsZSB4dGFibGUgPSBuZXcgamF2YS51dGlsLkhhc2h0YWJsZSgpOwotCi0gIC8qKgotICAgKiBTaW5jZSB0aGlzIG9iamVjdCBpcyBpbmNvbXBsZXRlIHdpdGhvdXQgdGhlIGxlbmd0aCBhbmQgdGhlIG9mZnNldCwgd2UKLSAgICogaGF2ZSB0byBjb252ZXJ0IHRvIGEgc3RyaW5nIHdoZW4gdGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGphdmEgU3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgb2JqZWN0LgotICAgKi8KLSAgcHVibGljIE9iamVjdCBvYmplY3QoKQotICB7Ci0gICAgcmV0dXJuIHN0cigpOwotICB9Ci0KLSAgLyoqCi0gICAqIENhc3QgcmVzdWx0IG9iamVjdCB0byBhIHN0cmluZy4KLSAgICoKLSAgICogQHJldHVybiBUaGUgc3RyaW5nIHRoaXMgd3JhcHMgb3IgdGhlIGVtcHR5IHN0cmluZyBpZiBudWxsCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIHN0cigpCi0gIHsKLQotICAgIGlmIChudWxsID09IG1fc3RyQ2FjaGUpCi0gICAgewotICAgICAgbV9zdHJDYWNoZSA9IGZzYigpLmdldFN0cmluZyhtX3N0YXJ0LCBtX2xlbmd0aCk7Ci0KLS8vICAgICAgc3RyQ291bnQrKzsKLS8vCi0vLyAgICAgIFJ1bnRpbWVFeGNlcHRpb24gZSA9IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJCYWQhICBCYWQhIik7Ci0vLyAgICAgIGphdmEuaW8uQ2hhckFycmF5V3JpdGVyIHdyaXRlciA9IG5ldyBqYXZhLmlvLkNoYXJBcnJheVdyaXRlcigpOwotLy8gICAgICBqYXZhLmlvLlByaW50V3JpdGVyIHB3ID0gbmV3IGphdmEuaW8uUHJpbnRXcml0ZXIod3JpdGVyKTsKLS8vCi0vLyAgICAgIGUucHJpbnRTdGFja1RyYWNlKHB3KTsKLS8vCi0vLyAgICAgIFN0cmluZyBzdHIgPSB3cml0ZXIudG9TdHJpbmcoKTsKLS8vCi0vLyAgICAgIHN0ciA9IHN0ci5zdWJzdHJpbmcoMCwgNjAwKTsKLS8vCi0vLyAgICAgIGlmIChudWxsID09IHh0YWJsZS5nZXQoc3RyKSkKLS8vICAgICAgewotLy8gICAgICAgIHh0YWJsZS5wdXQoc3RyLCBzdHIpOwotLy8gICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbihzdHIpOwotLy8gICAgICB9Ci0vLyAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigic3RyQ291bnQ6ICIgKyBzdHJDb3VudCk7Ci0KLS8vICAgICAgdGhyb3cgZTsKLS8vICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgIC8vIFN5c3RlbS5leGl0KC0xKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gbV9zdHJDYWNoZTsKLSAgfQotCi0gIC8qKgotICAgKiBEaXJlY3RseSBjYWxsIHRoZQotICAgKiBjaGFyYWN0ZXJzIG1ldGhvZCBvbiB0aGUgcGFzc2VkIENvbnRlbnRIYW5kbGVyIGZvciB0aGUKLSAgICogc3RyaW5nLXZhbHVlLiBNdWx0aXBsZSBjYWxscyB0byB0aGUKLSAgICogQ29udGVudEhhbmRsZXIncyBjaGFyYWN0ZXJzIG1ldGhvZHMgbWF5IHdlbGwgb2NjdXIgZm9yIGEgc2luZ2xlIGNhbGwgdG8KLSAgICogdGhpcyBtZXRob2QuCi0gICAqCi0gICAqIEBwYXJhbSBjaCBBIG5vbi1udWxsIHJlZmVyZW5jZSB0byBhIENvbnRlbnRIYW5kbGVyLgotICAgKgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgZGlzcGF0Y2hDaGFyYWN0ZXJzRXZlbnRzKG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyIGNoKQotICAgICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIGZzYigpLnNlbmRTQVhjaGFyYWN0ZXJzKGNoLCBtX3N0YXJ0LCBtX2xlbmd0aCk7Ci0gIH0KLQotICAvKioKLSAgICogRGlyZWN0bHkgY2FsbCB0aGUKLSAgICogY29tbWVudCBtZXRob2Qgb24gdGhlIHBhc3NlZCBMZXhpY2FsSGFuZGxlciBmb3IgdGhlCi0gICAqIHN0cmluZy12YWx1ZS4KLSAgICoKLSAgICogQHBhcmFtIGxoIEEgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGEgTGV4aWNhbEhhbmRsZXIuCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBkaXNwYXRjaEFzQ29tbWVudChvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXIgbGgpCi0gICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgZnNiKCkuc2VuZFNBWENvbW1lbnQobGgsIG1fc3RhcnQsIG1fbGVuZ3RoKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBsZW5ndGggb2YgdGhpcyBzdHJpbmcuCi0gICAqCi0gICAqIEByZXR1cm4gIHRoZSBsZW5ndGggb2YgdGhlIHNlcXVlbmNlIG9mIGNoYXJhY3RlcnMgcmVwcmVzZW50ZWQgYnkgdGhpcwotICAgKiAgICAgICAgICBvYmplY3QuCi0gICAqLwotICBwdWJsaWMgaW50IGxlbmd0aCgpCi0gIHsKLSAgICByZXR1cm4gbV9sZW5ndGg7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgY2hhcmFjdGVyIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXguIEFuIGluZGV4IHJhbmdlcwotICAgKiBmcm9tIDxjb2RlPjA8L2NvZGU+IHRvIDxjb2RlPmxlbmd0aCgpIC0gMTwvY29kZT4uIFRoZSBmaXJzdCBjaGFyYWN0ZXIKLSAgICogb2YgdGhlIHNlcXVlbmNlIGlzIGF0IGluZGV4IDxjb2RlPjA8L2NvZGU+LCB0aGUgbmV4dCBhdCBpbmRleAotICAgKiA8Y29kZT4xPC9jb2RlPiwgYW5kIHNvIG9uLCBhcyBmb3IgYXJyYXkgaW5kZXhpbmcuCi0gICAqCi0gICAqIEBwYXJhbSAgICAgIGluZGV4ICAgdGhlIGluZGV4IG9mIHRoZSBjaGFyYWN0ZXIuCi0gICAqIEByZXR1cm4gICAgIHRoZSBjaGFyYWN0ZXIgYXQgdGhlIHNwZWNpZmllZCBpbmRleCBvZiB0aGlzIHN0cmluZy4KLSAgICogICAgICAgICAgICAgVGhlIGZpcnN0IGNoYXJhY3RlciBpcyBhdCBpbmRleCA8Y29kZT4wPC9jb2RlPi4KLSAgICogQGV4Y2VwdGlvbiAgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiAgaWYgdGhlIDxjb2RlPmluZGV4PC9jb2RlPgotICAgKiAgICAgICAgICAgICBhcmd1bWVudCBpcyBuZWdhdGl2ZSBvciBub3QgbGVzcyB0aGFuIHRoZSBsZW5ndGggb2YgdGhpcwotICAgKiAgICAgICAgICAgICBzdHJpbmcuCi0gICAqLwotICBwdWJsaWMgY2hhciBjaGFyQXQoaW50IGluZGV4KQotICB7Ci0gICAgcmV0dXJuIGZzYigpLmNoYXJBdChtX3N0YXJ0ICsgaW5kZXgpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvcGllcyBjaGFyYWN0ZXJzIGZyb20gdGhpcyBzdHJpbmcgaW50byB0aGUgZGVzdGluYXRpb24gY2hhcmFjdGVyCi0gICAqIGFycmF5LgotICAgKgotICAgKiBAcGFyYW0gICAgICBzcmNCZWdpbiAgIGluZGV4IG9mIHRoZSBmaXJzdCBjaGFyYWN0ZXIgaW4gdGhlIHN0cmluZwotICAgKiAgICAgICAgICAgICAgICAgICAgICAgIHRvIGNvcHkuCi0gICAqIEBwYXJhbSAgICAgIHNyY0VuZCAgICAgaW5kZXggYWZ0ZXIgdGhlIGxhc3QgY2hhcmFjdGVyIGluIHRoZSBzdHJpbmcKLSAgICogICAgICAgICAgICAgICAgICAgICAgICB0byBjb3B5LgotICAgKiBAcGFyYW0gICAgICBkc3QgICAgICAgIHRoZSBkZXN0aW5hdGlvbiBhcnJheS4KLSAgICogQHBhcmFtICAgICAgZHN0QmVnaW4gICB0aGUgc3RhcnQgb2Zmc2V0IGluIHRoZSBkZXN0aW5hdGlvbiBhcnJheS4KLSAgICogQGV4Y2VwdGlvbiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIElmIGFueSBvZiB0aGUgZm9sbG93aW5nCi0gICAqICAgICAgICAgICAgaXMgdHJ1ZToKLSAgICogICAgICAgICAgICA8dWw+PGxpPjxjb2RlPnNyY0JlZ2luPC9jb2RlPiBpcyBuZWdhdGl2ZS4KLSAgICogICAgICAgICAgICA8bGk+PGNvZGU+c3JjQmVnaW48L2NvZGU+IGlzIGdyZWF0ZXIgdGhhbiA8Y29kZT5zcmNFbmQ8L2NvZGU+Ci0gICAqICAgICAgICAgICAgPGxpPjxjb2RlPnNyY0VuZDwvY29kZT4gaXMgZ3JlYXRlciB0aGFuIHRoZSBsZW5ndGggb2YgdGhpcwotICAgKiAgICAgICAgICAgICAgICBzdHJpbmcKLSAgICogICAgICAgICAgICA8bGk+PGNvZGU+ZHN0QmVnaW48L2NvZGU+IGlzIG5lZ2F0aXZlCi0gICAqICAgICAgICAgICAgPGxpPjxjb2RlPmRzdEJlZ2luKyhzcmNFbmQtc3JjQmVnaW4pPC9jb2RlPiBpcyBsYXJnZXIgdGhhbgotICAgKiAgICAgICAgICAgICAgICA8Y29kZT5kc3QubGVuZ3RoPC9jb2RlPjwvdWw+Ci0gICAqIEBleGNlcHRpb24gTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgPGNvZGU+ZHN0PC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPgotICAgKi8KLSAgcHVibGljIHZvaWQgZ2V0Q2hhcnMoaW50IHNyY0JlZ2luLCBpbnQgc3JjRW5kLCBjaGFyIGRzdFtdLCBpbnQgZHN0QmVnaW4pCi0gIHsKLQotICAgIC8vICVPUFQlIE5lZWQgdG8gY2FsbCB0aGlzIG9uIEZTQiB3aGVuIGl0IGlzIGltcGxlbWVudGVkLgotICAgIC8vICVVTlRFU1RFRCUgKEkgZG9uJ3QgdGhpbmsgYW55b25lIGNhbGxzIHRoaXMgeWV0PykKLSAgICBpbnQgbiA9IHNyY0VuZCAtIHNyY0JlZ2luOwotCi0gICAgaWYgKG4gPiBtX2xlbmd0aCkKLSAgICAgIG4gPSBtX2xlbmd0aDsKLQotICAgIGlmIChuID4gKGRzdC5sZW5ndGggLSBkc3RCZWdpbikpCi0gICAgICBuID0gKGRzdC5sZW5ndGggLSBkc3RCZWdpbik7Ci0KLSAgICBpbnQgZW5kID0gc3JjQmVnaW4gKyBtX3N0YXJ0ICsgbjsKLSAgICBpbnQgZCA9IGRzdEJlZ2luOwotICAgIEZhc3RTdHJpbmdCdWZmZXIgZnNiID0gZnNiKCk7Ci0KLSAgICBmb3IgKGludCBpID0gc3JjQmVnaW4gKyBtX3N0YXJ0OyBpIDwgZW5kOyBpKyspCi0gICAgewotICAgICAgZHN0W2QrK10gPSBmc2IuY2hhckF0KGkpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBDb21wYXJlcyB0aGlzIHN0cmluZyB0byB0aGUgc3BlY2lmaWVkIG9iamVjdC4KLSAgICogVGhlIHJlc3VsdCBpcyA8Y29kZT50cnVlPC9jb2RlPiBpZiBhbmQgb25seSBpZiB0aGUgYXJndW1lbnQgaXMgbm90Ci0gICAqIDxjb2RlPm51bGw8L2NvZGU+IGFuZCBpcyBhIDxjb2RlPlN0cmluZzwvY29kZT4gb2JqZWN0IHRoYXQgcmVwcmVzZW50cwotICAgKiB0aGUgc2FtZSBzZXF1ZW5jZSBvZiBjaGFyYWN0ZXJzIGFzIHRoaXMgb2JqZWN0LgotICAgKgotICAgKiBAcGFyYW0gICBvYmoyICAgICAgIHRoZSBvYmplY3QgdG8gY29tcGFyZSB0aGlzIDxjb2RlPlN0cmluZzwvY29kZT4KLSAgICogICAgICAgICAgICAgICAgICAgICBhZ2FpbnN0LgotICAgKgotICAgKiBAcmV0dXJuICA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgPGNvZGU+U3RyaW5nIDwvY29kZT5hcmUgZXF1YWw7Ci0gICAqICAgICAgICAgIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuCi0gICAqIEBzZWUgICAgIGphdmEubGFuZy5TdHJpbmcjY29tcGFyZVRvKGphdmEubGFuZy5TdHJpbmcpCi0gICAqIEBzZWUgICAgIGphdmEubGFuZy5TdHJpbmcjZXF1YWxzSWdub3JlQ2FzZShqYXZhLmxhbmcuU3RyaW5nKQotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZXF1YWxzKFhNTFN0cmluZyBvYmoyKQotICB7Ci0KLSAgICBpZiAodGhpcyA9PSBvYmoyKQotICAgIHsKLSAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotICAgIGludCBuID0gbV9sZW5ndGg7Ci0KLSAgICBpZiAobiA9PSBvYmoyLmxlbmd0aCgpKQotICAgIHsKLSAgICAgIEZhc3RTdHJpbmdCdWZmZXIgZnNiID0gZnNiKCk7Ci0gICAgICBpbnQgaSA9IG1fc3RhcnQ7Ci0gICAgICBpbnQgaiA9IDA7Ci0KLSAgICAgIHdoaWxlIChuLS0gIT0gMCkKLSAgICAgIHsKLSAgICAgICAgaWYgKGZzYi5jaGFyQXQoaSkgIT0gb2JqMi5jaGFyQXQoaikpCi0gICAgICAgIHsKLSAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLQotICAgICAgICBpKys7Ci0gICAgICAgIGorKzsKLSAgICAgIH0KLQotICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotCi0gICAgcmV0dXJuIGZhbHNlOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgdHdvIG9iamVjdHMgYXJlIGZ1bmN0aW9uYWxseSBlcXVhbC4KLSAgICoKLSAgICogQHBhcmFtIG9iajIgT2JqZWN0IHRvIGNvbXBhcmUgdGhpcyB0bwotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHR3byBvYmplY3RzIGFyZSBlcXVhbAotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGVxdWFscyhYT2JqZWN0IG9iajIpCi0gIHsKLQotICAgIGlmICh0aGlzID09IG9iajIpCi0gICAgewotICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotICAgIGlmKG9iajIuZ2V0VHlwZSgpID09IFhPYmplY3QuQ0xBU1NfTlVNQkVSKQotICAgICAgICByZXR1cm4gb2JqMi5lcXVhbHModGhpcyk7Ci0KLSAgICBTdHJpbmcgc3RyID0gb2JqMi5zdHIoKTsKLSAgICBpbnQgbiA9IG1fbGVuZ3RoOwotCi0gICAgaWYgKG4gPT0gc3RyLmxlbmd0aCgpKQotICAgIHsKLSAgICAgIEZhc3RTdHJpbmdCdWZmZXIgZnNiID0gZnNiKCk7Ci0gICAgICBpbnQgaSA9IG1fc3RhcnQ7Ci0gICAgICBpbnQgaiA9IDA7Ci0KLSAgICAgIHdoaWxlIChuLS0gIT0gMCkKLSAgICAgIHsKLSAgICAgICAgaWYgKGZzYi5jaGFyQXQoaSkgIT0gc3RyLmNoYXJBdChqKSkKLSAgICAgICAgewotICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotCi0gICAgICAgIGkrKzsKLSAgICAgICAgaisrOwotICAgICAgfQotCi0gICAgICByZXR1cm4gdHJ1ZTsKLSAgICB9Ci0KLSAgICByZXR1cm4gZmFsc2U7Ci0gIH0KLQotICAvKioKLSAgICogVGVsbCBpZiB0d28gb2JqZWN0cyBhcmUgZnVuY3Rpb25hbGx5IGVxdWFsLgotICAgKgotICAgKiBAcGFyYW0gYW5vdGhlclN0cmluZyBPYmplY3QgdG8gY29tcGFyZSB0aGlzIHRvCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgdHdvIG9iamVjdHMgYXJlIGVxdWFsCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZXF1YWxzKFN0cmluZyBhbm90aGVyU3RyaW5nKQotICB7Ci0KLSAgICBpbnQgbiA9IG1fbGVuZ3RoOwotCi0gICAgaWYgKG4gPT0gYW5vdGhlclN0cmluZy5sZW5ndGgoKSkKLSAgICB7Ci0gICAgICBGYXN0U3RyaW5nQnVmZmVyIGZzYiA9IGZzYigpOwotICAgICAgaW50IGkgPSBtX3N0YXJ0OwotICAgICAgaW50IGogPSAwOwotCi0gICAgICB3aGlsZSAobi0tICE9IDApCi0gICAgICB7Ci0gICAgICAgIGlmIChmc2IuY2hhckF0KGkpICE9IGFub3RoZXJTdHJpbmcuY2hhckF0KGopKQotICAgICAgICB7Ci0gICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0KLSAgICAgICAgaSsrOwotICAgICAgICBqKys7Ci0gICAgICB9Ci0KLSAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotICAgIHJldHVybiBmYWxzZTsKLSAgfQotCi0gIC8qKgotICAgKiBDb21wYXJlcyB0aGlzIHN0cmluZyB0byB0aGUgc3BlY2lmaWVkIG9iamVjdC4KLSAgICogVGhlIHJlc3VsdCBpcyA8Y29kZT50cnVlPC9jb2RlPiBpZiBhbmQgb25seSBpZiB0aGUgYXJndW1lbnQgaXMgbm90Ci0gICAqIDxjb2RlPm51bGw8L2NvZGU+IGFuZCBpcyBhIDxjb2RlPlN0cmluZzwvY29kZT4gb2JqZWN0IHRoYXQgcmVwcmVzZW50cwotICAgKiB0aGUgc2FtZSBzZXF1ZW5jZSBvZiBjaGFyYWN0ZXJzIGFzIHRoaXMgb2JqZWN0LgotICAgKgotICAgKiBAcGFyYW0gICBvYmoyICAgICAgIHRoZSBvYmplY3QgdG8gY29tcGFyZSB0aGlzIDxjb2RlPlN0cmluZzwvY29kZT4KLSAgICogICAgICAgICAgICAgICAgICAgICBhZ2FpbnN0LgotICAgKgotICAgKiBAcmV0dXJuICA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgPGNvZGU+U3RyaW5nIDwvY29kZT5hcmUgZXF1YWw7Ci0gICAqICAgICAgICAgIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuCi0gICAqIEBzZWUgICAgIGphdmEubGFuZy5TdHJpbmcjY29tcGFyZVRvKGphdmEubGFuZy5TdHJpbmcpCi0gICAqIEBzZWUgICAgIGphdmEubGFuZy5TdHJpbmcjZXF1YWxzSWdub3JlQ2FzZShqYXZhLmxhbmcuU3RyaW5nKQotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmoyKQotICB7Ci0KLSAgICBpZiAobnVsbCA9PSBvYmoyKQotICAgICAgcmV0dXJuIGZhbHNlOwotCi0gICAgaWYob2JqMiBpbnN0YW5jZW9mIFhOdW1iZXIpCi0gICAgICAgIHJldHVybiBvYmoyLmVxdWFscyh0aGlzKTsKLQotICAgICAgLy8gSW4gb3JkZXIgdG8gaGFuZGxlIHRoZSAnYWxsJyBzZW1hbnRpY3Mgb2YKLSAgICAgIC8vIG5vZGVzZXQgY29tcGFyaXNvbnMsIHdlIGFsd2F5cyBjYWxsIHRoZQotICAgICAgLy8gbm9kZXNldCBmdW5jdGlvbi4KLSAgICBlbHNlIGlmIChvYmoyIGluc3RhbmNlb2YgWE5vZGVTZXQpCi0gICAgICByZXR1cm4gb2JqMi5lcXVhbHModGhpcyk7Ci0gICAgZWxzZSBpZiAob2JqMiBpbnN0YW5jZW9mIFhTdHJpbmdGb3JGU0IpCi0gICAgICByZXR1cm4gZXF1YWxzKChYTUxTdHJpbmcpIG9iajIpOwotICAgIGVsc2UKLSAgICAgIHJldHVybiBlcXVhbHMob2JqMi50b1N0cmluZygpKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb21wYXJlcyB0aGlzIDxjb2RlPlN0cmluZzwvY29kZT4gdG8gYW5vdGhlciA8Y29kZT5TdHJpbmc8L2NvZGU+LAotICAgKiBpZ25vcmluZyBjYXNlIGNvbnNpZGVyYXRpb25zLiAgVHdvIHN0cmluZ3MgYXJlIGNvbnNpZGVyZWQgZXF1YWwKLSAgICogaWdub3JpbmcgY2FzZSBpZiB0aGV5IGFyZSBvZiB0aGUgc2FtZSBsZW5ndGgsIGFuZCBjb3JyZXNwb25kaW5nCi0gICAqIGNoYXJhY3RlcnMgaW4gdGhlIHR3byBzdHJpbmdzIGFyZSBlcXVhbCBpZ25vcmluZyBjYXNlLgotICAgKgotICAgKiBAcGFyYW0gICBhbm90aGVyU3RyaW5nICAgdGhlIDxjb2RlPlN0cmluZzwvY29kZT4gdG8gY29tcGFyZSB0aGlzCi0gICAqICAgICAgICAgICAgICAgICAgICAgICAgICA8Y29kZT5TdHJpbmc8L2NvZGU+IGFnYWluc3QuCi0gICAqIEByZXR1cm4gIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBhcmd1bWVudCBpcyBub3QgPGNvZGU+bnVsbDwvY29kZT4KLSAgICogICAgICAgICAgYW5kIHRoZSA8Y29kZT5TdHJpbmc8L2NvZGU+cyBhcmUgZXF1YWwsCi0gICAqICAgICAgICAgIGlnbm9yaW5nIGNhc2U7IDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuCi0gICAqIEBzZWUgICAgICNlcXVhbHMoT2JqZWN0KQotICAgKiBAc2VlICAgICBqYXZhLmxhbmcuQ2hhcmFjdGVyI3RvTG93ZXJDYXNlKGNoYXIpCi0gICAqIEBzZWUgamF2YS5sYW5nLkNoYXJhY3RlciN0b1VwcGVyQ2FzZShjaGFyKQotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZXF1YWxzSWdub3JlQ2FzZShTdHJpbmcgYW5vdGhlclN0cmluZykKLSAgewotICAgIHJldHVybiAobV9sZW5ndGggPT0gYW5vdGhlclN0cmluZy5sZW5ndGgoKSkKLSAgICAgICAgICAgPyBzdHIoKS5lcXVhbHNJZ25vcmVDYXNlKGFub3RoZXJTdHJpbmcpIDogZmFsc2U7Ci0gIH0KLQotICAvKioKLSAgICogQ29tcGFyZXMgdHdvIHN0cmluZ3MgbGV4aWNvZ3JhcGhpY2FsbHkuCi0gICAqCi0gICAqIEBwYXJhbSAgIHhzdHIgICB0aGUgPGNvZGU+U3RyaW5nPC9jb2RlPiB0byBiZSBjb21wYXJlZC4KLSAgICoKLSAgICogQHJldHVybiAgdGhlIHZhbHVlIDxjb2RlPjA8L2NvZGU+IGlmIHRoZSBhcmd1bWVudCBzdHJpbmcgaXMgZXF1YWwgdG8KLSAgICogICAgICAgICAgdGhpcyBzdHJpbmc7IGEgdmFsdWUgbGVzcyB0aGFuIDxjb2RlPjA8L2NvZGU+IGlmIHRoaXMgc3RyaW5nCi0gICAqICAgICAgICAgIGlzIGxleGljb2dyYXBoaWNhbGx5IGxlc3MgdGhhbiB0aGUgc3RyaW5nIGFyZ3VtZW50OyBhbmQgYQotICAgKiAgICAgICAgICB2YWx1ZSBncmVhdGVyIHRoYW4gPGNvZGU+MDwvY29kZT4gaWYgdGhpcyBzdHJpbmcgaXMKLSAgICogICAgICAgICAgbGV4aWNvZ3JhcGhpY2FsbHkgZ3JlYXRlciB0aGFuIHRoZSBzdHJpbmcgYXJndW1lbnQuCi0gICAqIEBleGNlcHRpb24gamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uIGlmIDxjb2RlPmFub3RoZXJTdHJpbmc8L2NvZGU+Ci0gICAqICAgICAgICAgIGlzIDxjb2RlPm51bGw8L2NvZGU+LgotICAgKi8KLSAgcHVibGljIGludCBjb21wYXJlVG8oWE1MU3RyaW5nIHhzdHIpCi0gIHsKLQotICAgIGludCBsZW4xID0gbV9sZW5ndGg7Ci0gICAgaW50IGxlbjIgPSB4c3RyLmxlbmd0aCgpOwotICAgIGludCBuID0gTWF0aC5taW4obGVuMSwgbGVuMik7Ci0gICAgRmFzdFN0cmluZ0J1ZmZlciBmc2IgPSBmc2IoKTsKLSAgICBpbnQgaSA9IG1fc3RhcnQ7Ci0gICAgaW50IGogPSAwOwotCi0gICAgd2hpbGUgKG4tLSAhPSAwKQotICAgIHsKLSAgICAgIGNoYXIgYzEgPSBmc2IuY2hhckF0KGkpOwotICAgICAgY2hhciBjMiA9IHhzdHIuY2hhckF0KGopOwotCi0gICAgICBpZiAoYzEgIT0gYzIpCi0gICAgICB7Ci0gICAgICAgIHJldHVybiBjMSAtIGMyOwotICAgICAgfQotCi0gICAgICBpKys7Ci0gICAgICBqKys7Ci0gICAgfQotCi0gICAgcmV0dXJuIGxlbjEgLSBsZW4yOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbXBhcmVzIHR3byBzdHJpbmdzIGxleGljb2dyYXBoaWNhbGx5LCBpZ25vcmluZyBjYXNlIGNvbnNpZGVyYXRpb25zLgotICAgKiBUaGlzIG1ldGhvZCByZXR1cm5zIGFuIGludGVnZXIgd2hvc2Ugc2lnbiBpcyB0aGF0IG9mCi0gICAqIDxjb2RlPnRoaXMudG9VcHBlckNhc2UoKS50b0xvd2VyQ2FzZSgpLmNvbXBhcmVUbygKLSAgICogc3RyLnRvVXBwZXJDYXNlKCkudG9Mb3dlckNhc2UoKSk8L2NvZGU+LgotICAgKiA8cD4KLSAgICogTm90ZSB0aGF0IHRoaXMgbWV0aG9kIGRvZXMgPGVtPm5vdDwvZW0+IHRha2UgbG9jYWxlIGludG8gYWNjb3VudCwKLSAgICogYW5kIHdpbGwgcmVzdWx0IGluIGFuIHVuc2F0aXNmYWN0b3J5IG9yZGVyaW5nIGZvciBjZXJ0YWluIGxvY2FsZXMuCi0gICAqIFRoZSBqYXZhLnRleHQgcGFja2FnZSBwcm92aWRlcyA8ZW0+Y29sbGF0b3JzPC9lbT4gdG8gYWxsb3cKLSAgICogbG9jYWxlLXNlbnNpdGl2ZSBvcmRlcmluZy4KLSAgICoKLSAgICogQHBhcmFtICAgeHN0ciAgIHRoZSA8Y29kZT5TdHJpbmc8L2NvZGU+IHRvIGJlIGNvbXBhcmVkLgotICAgKgotICAgKiBAcmV0dXJuICBhIG5lZ2F0aXZlIGludGVnZXIsIHplcm8sIG9yIGEgcG9zaXRpdmUgaW50ZWdlciBhcyB0aGUKLSAgICogICAgICAgICAgdGhlIHNwZWNpZmllZCBTdHJpbmcgaXMgZ3JlYXRlciB0aGFuLCBlcXVhbCB0bywgb3IgbGVzcwotICAgKiAgICAgICAgICB0aGFuIHRoaXMgU3RyaW5nLCBpZ25vcmluZyBjYXNlIGNvbnNpZGVyYXRpb25zLgotICAgKiBAc2VlICAgICBqYXZhLnRleHQuQ29sbGF0b3IjY29tcGFyZShTdHJpbmcsIFN0cmluZykKLSAgICogQHNpbmNlICAgMS4yCi0gICAqLwotICBwdWJsaWMgaW50IGNvbXBhcmVUb0lnbm9yZUNhc2UoWE1MU3RyaW5nIHhzdHIpCi0gIHsKLQotICAgIGludCBsZW4xID0gbV9sZW5ndGg7Ci0gICAgaW50IGxlbjIgPSB4c3RyLmxlbmd0aCgpOwotICAgIGludCBuID0gTWF0aC5taW4obGVuMSwgbGVuMik7Ci0gICAgRmFzdFN0cmluZ0J1ZmZlciBmc2IgPSBmc2IoKTsKLSAgICBpbnQgaSA9IG1fc3RhcnQ7Ci0gICAgaW50IGogPSAwOwotCi0gICAgd2hpbGUgKG4tLSAhPSAwKQotICAgIHsKLSAgICAgIGNoYXIgYzEgPSBDaGFyYWN0ZXIudG9Mb3dlckNhc2UoZnNiLmNoYXJBdChpKSk7Ci0gICAgICBjaGFyIGMyID0gQ2hhcmFjdGVyLnRvTG93ZXJDYXNlKHhzdHIuY2hhckF0KGopKTsKLQotICAgICAgaWYgKGMxICE9IGMyKQotICAgICAgewotICAgICAgICByZXR1cm4gYzEgLSBjMjsKLSAgICAgIH0KLQotICAgICAgaSsrOwotICAgICAgaisrOwotICAgIH0KLQotICAgIHJldHVybiBsZW4xIC0gbGVuMjsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIGEgaGFzaGNvZGUgZm9yIHRoaXMgc3RyaW5nLiBUaGUgaGFzaGNvZGUgZm9yIGEKLSAgICogPGNvZGU+U3RyaW5nPC9jb2RlPiBvYmplY3QgaXMgY29tcHV0ZWQgYXMKLSAgICogPGJsb2NrcXVvdGU+PHByZT4KLSAgICogc1swXSozMV4obi0xKSArIHNbMV0qMzFeKG4tMikgKyAuLi4gKyBzW24tMV0KLSAgICogPC9wcmU+PC9ibG9ja3F1b3RlPgotICAgKiB1c2luZyA8Y29kZT5pbnQ8L2NvZGU+IGFyaXRobWV0aWMsIHdoZXJlIDxjb2RlPnNbaV08L2NvZGU+IGlzIHRoZQotICAgKiA8aT5pPC9pPnRoIGNoYXJhY3RlciBvZiB0aGUgc3RyaW5nLCA8Y29kZT5uPC9jb2RlPiBpcyB0aGUgbGVuZ3RoIG9mCi0gICAqIHRoZSBzdHJpbmcsIGFuZCA8Y29kZT5ePC9jb2RlPiBpbmRpY2F0ZXMgZXhwb25lbnRpYXRpb24uCi0gICAqIChUaGUgaGFzaCB2YWx1ZSBvZiB0aGUgZW1wdHkgc3RyaW5nIGlzIHplcm8uKQotICAgKgotICAgKiBAcmV0dXJuICBhIGhhc2ggY29kZSB2YWx1ZSBmb3IgdGhpcyBvYmplY3QuCi0gICAqLwotICBwdWJsaWMgaW50IGhhc2hDb2RlKCkKLSAgewotICAgIC8vIENvbW1lbnRpbmcgdGhpcyBvdXQgYmVjYXVzZSBpbiBKREsxLjEuOCBhbmQgVkorKwotICAgIC8vIHdlIGRvbid0IG1hdGNoIFhNTFN0cmluZ3MuIERlZmF1bHRpbmcgdG8gdGhlIHN1cGVyCi0gICAgLy8gY2F1c2VzIHVzIHRvIGNyZWF0ZSBhIHN0cmluZywgYnV0IGF0IHRoaXMgcG9pbnQKLSAgICAvLyB0aGlzIG9ubHkgc2VlbXMgdG8gZ2V0IGNhbGxlZCBpbiBrZXkgcHJvY2Vzc2luZy4KLSAgICAvLyBNYXliZSB3ZSBjYW4gbGl2ZSB3aXRoIGl0PwotCi0vKgotICAgIGludCBoID0gbV9oYXNoOwotCi0gICAgaWYgKGggPT0gMCkKLSAgICB7Ci0gICAgICBpbnQgb2ZmID0gbV9zdGFydDsKLSAgICAgIGludCBsZW4gPSBtX2xlbmd0aDsKLSAgICAgIEZhc3RTdHJpbmdCdWZmZXIgZnNiID0gZnNiKCk7Ci0KLSAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuOyBpKyspCi0gICAgICB7Ci0gICAgICAgIGggPSAzMSAqIGggKyBmc2IuY2hhckF0KG9mZik7Ci0KLSAgICAgICAgb2ZmKys7Ci0gICAgICB9Ci0KLSAgICAgIG1faGFzaCA9IGg7Ci0gICAgfQotICAgICovCi0KLSAgICByZXR1cm4gc3VwZXIuaGFzaENvZGUoKTsgLy8gaDsKLSAgfQotCi0gIC8qKgotICAgKiBUZXN0cyBpZiB0aGlzIHN0cmluZyBzdGFydHMgd2l0aCB0aGUgc3BlY2lmaWVkIHByZWZpeCBiZWdpbm5pbmcKLSAgICogYSBzcGVjaWZpZWQgaW5kZXguCi0gICAqCi0gICAqIEBwYXJhbSAgIHByZWZpeCAgICB0aGUgcHJlZml4LgotICAgKiBAcGFyYW0gICB0b2Zmc2V0ICAgd2hlcmUgdG8gYmVnaW4gbG9va2luZyBpbiB0aGUgc3RyaW5nLgotICAgKiBAcmV0dXJuICA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgY2hhcmFjdGVyIHNlcXVlbmNlIHJlcHJlc2VudGVkIGJ5IHRoZQotICAgKiAgICAgICAgICBhcmd1bWVudCBpcyBhIHByZWZpeCBvZiB0aGUgc3Vic3RyaW5nIG9mIHRoaXMgb2JqZWN0IHN0YXJ0aW5nCi0gICAqICAgICAgICAgIGF0IGluZGV4IDxjb2RlPnRvZmZzZXQ8L2NvZGU+OyA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLgotICAgKiAgICAgICAgICBUaGUgcmVzdWx0IGlzIDxjb2RlPmZhbHNlPC9jb2RlPiBpZiA8Y29kZT50b2Zmc2V0PC9jb2RlPiBpcwotICAgKiAgICAgICAgICBuZWdhdGl2ZSBvciBncmVhdGVyIHRoYW4gdGhlIGxlbmd0aCBvZiB0aGlzCi0gICAqICAgICAgICAgIDxjb2RlPlN0cmluZzwvY29kZT4gb2JqZWN0OyBvdGhlcndpc2UgdGhlIHJlc3VsdCBpcyB0aGUgc2FtZQotICAgKiAgICAgICAgICBhcyB0aGUgcmVzdWx0IG9mIHRoZSBleHByZXNzaW9uCi0gICAqICAgICAgICAgIDxwcmU+Ci0gICAqICAgICAgICAgIHRoaXMuc3ViU3RyaW5nKHRvZmZzZXQpLnN0YXJ0c1dpdGgocHJlZml4KQotICAgKiAgICAgICAgICA8L3ByZT4KLSAgICogQGV4Y2VwdGlvbiBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgPGNvZGU+cHJlZml4PC9jb2RlPiBpcwotICAgKiAgICAgICAgICA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIHN0YXJ0c1dpdGgoWE1MU3RyaW5nIHByZWZpeCwgaW50IHRvZmZzZXQpCi0gIHsKLQotICAgIEZhc3RTdHJpbmdCdWZmZXIgZnNiID0gZnNiKCk7Ci0gICAgaW50IHRvID0gbV9zdGFydCArIHRvZmZzZXQ7Ci0gICAgaW50IHRsaW0gPSBtX3N0YXJ0ICsgbV9sZW5ndGg7Ci0gICAgaW50IHBvID0gMDsKLSAgICBpbnQgcGMgPSBwcmVmaXgubGVuZ3RoKCk7Ci0KLSAgICAvLyBOb3RlOiB0b2Zmc2V0IG1pZ2h0IGJlIG5lYXIgLTE+Pj4xLgotICAgIGlmICgodG9mZnNldCA8IDApIHx8ICh0b2Zmc2V0ID4gbV9sZW5ndGggLSBwYykpCi0gICAgewotICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIHdoaWxlICgtLXBjID49IDApCi0gICAgewotICAgICAgaWYgKGZzYi5jaGFyQXQodG8pICE9IHByZWZpeC5jaGFyQXQocG8pKQotICAgICAgewotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICB9Ci0KLSAgICAgIHRvKys7Ci0gICAgICBwbysrOwotICAgIH0KLQotICAgIHJldHVybiB0cnVlOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlc3RzIGlmIHRoaXMgc3RyaW5nIHN0YXJ0cyB3aXRoIHRoZSBzcGVjaWZpZWQgcHJlZml4LgotICAgKgotICAgKiBAcGFyYW0gICBwcmVmaXggICB0aGUgcHJlZml4LgotICAgKiBAcmV0dXJuICA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgY2hhcmFjdGVyIHNlcXVlbmNlIHJlcHJlc2VudGVkIGJ5IHRoZQotICAgKiAgICAgICAgICBhcmd1bWVudCBpcyBhIHByZWZpeCBvZiB0aGUgY2hhcmFjdGVyIHNlcXVlbmNlIHJlcHJlc2VudGVkIGJ5Ci0gICAqICAgICAgICAgIHRoaXMgc3RyaW5nOyA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLgotICAgKiAgICAgICAgICBOb3RlIGFsc28gdGhhdCA8Y29kZT50cnVlPC9jb2RlPiB3aWxsIGJlIHJldHVybmVkIGlmIHRoZQotICAgKiAgICAgICAgICBhcmd1bWVudCBpcyBhbiBlbXB0eSBzdHJpbmcgb3IgaXMgZXF1YWwgdG8gdGhpcwotICAgKiAgICAgICAgICA8Y29kZT5TdHJpbmc8L2NvZGU+IG9iamVjdCBhcyBkZXRlcm1pbmVkIGJ5IHRoZQotICAgKiAgICAgICAgICB7QGxpbmsgI2VxdWFscyhPYmplY3QpfSBtZXRob2QuCi0gICAqIEBleGNlcHRpb24gamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uIGlmIDxjb2RlPnByZWZpeDwvY29kZT4gaXMKLSAgICogICAgICAgICAgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAqIEBzaW5jZSAgIEpESzEuIDAKLSAgICovCi0gIHB1YmxpYyBib29sZWFuIHN0YXJ0c1dpdGgoWE1MU3RyaW5nIHByZWZpeCkKLSAgewotICAgIHJldHVybiBzdGFydHNXaXRoKHByZWZpeCwgMCk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgaW5kZXggd2l0aGluIHRoaXMgc3RyaW5nIG9mIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZQotICAgKiBzcGVjaWZpZWQgY2hhcmFjdGVyLiBJZiBhIGNoYXJhY3RlciB3aXRoIHZhbHVlIDxjb2RlPmNoPC9jb2RlPiBvY2N1cnMKLSAgICogaW4gdGhlIGNoYXJhY3RlciBzZXF1ZW5jZSByZXByZXNlbnRlZCBieSB0aGlzIDxjb2RlPlN0cmluZzwvY29kZT4KLSAgICogb2JqZWN0LCB0aGVuIHRoZSBpbmRleCBvZiB0aGUgZmlyc3Qgc3VjaCBvY2N1cnJlbmNlIGlzIHJldHVybmVkIC0tCi0gICAqIHRoYXQgaXMsIHRoZSBzbWFsbGVzdCB2YWx1ZSA8aT5rPC9pPiBzdWNoIHRoYXQ6Ci0gICAqIDxibG9ja3F1b3RlPjxwcmU+Ci0gICAqIHRoaXMuY2hhckF0KDxpPms8L2k+KSA9PSBjaAotICAgKiA8L3ByZT48L2Jsb2NrcXVvdGU+Ci0gICAqIGlzIDxjb2RlPnRydWU8L2NvZGU+LiBJZiBubyBzdWNoIGNoYXJhY3RlciBvY2N1cnMgaW4gdGhpcyBzdHJpbmcsCi0gICAqIHRoZW4gPGNvZGU+LTE8L2NvZGU+IGlzIHJldHVybmVkLgotICAgKgotICAgKiBAcGFyYW0gICBjaCAgIGEgY2hhcmFjdGVyLgotICAgKiBAcmV0dXJuICB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgdGhlIGNoYXJhY3RlciBpbiB0aGUKLSAgICogICAgICAgICAgY2hhcmFjdGVyIHNlcXVlbmNlIHJlcHJlc2VudGVkIGJ5IHRoaXMgb2JqZWN0LCBvcgotICAgKiAgICAgICAgICA8Y29kZT4tMTwvY29kZT4gaWYgdGhlIGNoYXJhY3RlciBkb2VzIG5vdCBvY2N1ci4KLSAgICovCi0gIHB1YmxpYyBpbnQgaW5kZXhPZihpbnQgY2gpCi0gIHsKLSAgICByZXR1cm4gaW5kZXhPZihjaCwgMCk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgaW5kZXggd2l0aGluIHRoaXMgc3RyaW5nIG9mIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZQotICAgKiBzcGVjaWZpZWQgY2hhcmFjdGVyLCBzdGFydGluZyB0aGUgc2VhcmNoIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXguCi0gICAqIDxwPgotICAgKiBJZiBhIGNoYXJhY3RlciB3aXRoIHZhbHVlIDxjb2RlPmNoPC9jb2RlPiBvY2N1cnMgaW4gdGhlIGNoYXJhY3RlcgotICAgKiBzZXF1ZW5jZSByZXByZXNlbnRlZCBieSB0aGlzIDxjb2RlPlN0cmluZzwvY29kZT4gb2JqZWN0IGF0IGFuIGluZGV4Ci0gICAqIG5vIHNtYWxsZXIgdGhhbiA8Y29kZT5mcm9tSW5kZXg8L2NvZGU+LCB0aGVuIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QKLSAgICogc3VjaCBvY2N1cnJlbmNlIGlzIHJldHVybmVkLS10aGF0IGlzLCB0aGUgc21hbGxlc3QgdmFsdWUgPGk+azwvaT4KLSAgICogc3VjaCB0aGF0OgotICAgKiA8YmxvY2txdW90ZT48cHJlPgotICAgKiAodGhpcy5jaGFyQXQoPGk+azwvaT4pID09IGNoKSAmJiAoPGk+azwvaT4gPj0gZnJvbUluZGV4KQotICAgKiA8L3ByZT48L2Jsb2NrcXVvdGU+Ci0gICAqIGlzIHRydWUuIElmIG5vIHN1Y2ggY2hhcmFjdGVyIG9jY3VycyBpbiB0aGlzIHN0cmluZyBhdCBvciBhZnRlcgotICAgKiBwb3NpdGlvbiA8Y29kZT5mcm9tSW5kZXg8L2NvZGU+LCB0aGVuIDxjb2RlPi0xPC9jb2RlPiBpcyByZXR1cm5lZC4KLSAgICogPHA+Ci0gICAqIFRoZXJlIGlzIG5vIHJlc3RyaWN0aW9uIG9uIHRoZSB2YWx1ZSBvZiA8Y29kZT5mcm9tSW5kZXg8L2NvZGU+LiBJZiBpdAotICAgKiBpcyBuZWdhdGl2ZSwgaXQgaGFzIHRoZSBzYW1lIGVmZmVjdCBhcyBpZiBpdCB3ZXJlIHplcm86IHRoaXMgZW50aXJlCi0gICAqIHN0cmluZyBtYXkgYmUgc2VhcmNoZWQuIElmIGl0IGlzIGdyZWF0ZXIgdGhhbiB0aGUgbGVuZ3RoIG9mIHRoaXMKLSAgICogc3RyaW5nLCBpdCBoYXMgdGhlIHNhbWUgZWZmZWN0IGFzIGlmIGl0IHdlcmUgZXF1YWwgdG8gdGhlIGxlbmd0aCBvZgotICAgKiB0aGlzIHN0cmluZzogPGNvZGU+LTE8L2NvZGU+IGlzIHJldHVybmVkLgotICAgKgotICAgKiBAcGFyYW0gICBjaCAgICAgICAgICBhIGNoYXJhY3Rlci4KLSAgICogQHBhcmFtICAgZnJvbUluZGV4ICAgdGhlIGluZGV4IHRvIHN0YXJ0IHRoZSBzZWFyY2ggZnJvbS4KLSAgICogQHJldHVybiAgdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZSBjaGFyYWN0ZXIgaW4gdGhlCi0gICAqICAgICAgICAgIGNoYXJhY3RlciBzZXF1ZW5jZSByZXByZXNlbnRlZCBieSB0aGlzIG9iamVjdCB0aGF0IGlzIGdyZWF0ZXIKLSAgICogICAgICAgICAgdGhhbiBvciBlcXVhbCB0byA8Y29kZT5mcm9tSW5kZXg8L2NvZGU+LCBvciA8Y29kZT4tMTwvY29kZT4KLSAgICogICAgICAgICAgaWYgdGhlIGNoYXJhY3RlciBkb2VzIG5vdCBvY2N1ci4KLSAgICovCi0gIHB1YmxpYyBpbnQgaW5kZXhPZihpbnQgY2gsIGludCBmcm9tSW5kZXgpCi0gIHsKLQotICAgIGludCBtYXggPSBtX3N0YXJ0ICsgbV9sZW5ndGg7Ci0gICAgRmFzdFN0cmluZ0J1ZmZlciBmc2IgPSBmc2IoKTsKLQotICAgIGlmIChmcm9tSW5kZXggPCAwKQotICAgIHsKLSAgICAgIGZyb21JbmRleCA9IDA7Ci0gICAgfQotICAgIGVsc2UgaWYgKGZyb21JbmRleCA+PSBtX2xlbmd0aCkKLSAgICB7Ci0KLSAgICAgIC8vIE5vdGU6IGZyb21JbmRleCBtaWdodCBiZSBuZWFyIC0xPj4+MS4KLSAgICAgIHJldHVybiAtMTsKLSAgICB9Ci0KLSAgICBmb3IgKGludCBpID0gbV9zdGFydCArIGZyb21JbmRleDsgaSA8IG1heDsgaSsrKQotICAgIHsKLSAgICAgIGlmIChmc2IuY2hhckF0KGkpID09IGNoKQotICAgICAgewotICAgICAgICByZXR1cm4gaSAtIG1fc3RhcnQ7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgcmV0dXJuIC0xOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgYSBuZXcgc3RyaW5nIHRoYXQgaXMgYSBzdWJzdHJpbmcgb2YgdGhpcyBzdHJpbmcuIFRoZQotICAgKiBzdWJzdHJpbmcgYmVnaW5zIHdpdGggdGhlIGNoYXJhY3RlciBhdCB0aGUgc3BlY2lmaWVkIGluZGV4IGFuZAotICAgKiBleHRlbmRzIHRvIHRoZSBlbmQgb2YgdGhpcyBzdHJpbmcuIDxwPgotICAgKiBFeGFtcGxlczoKLSAgICogPGJsb2NrcXVvdGU+PHByZT4KLSAgICogInVuaGFwcHkiLnN1YnN0cmluZygyKSByZXR1cm5zICJoYXBweSIKLSAgICogIkhhcmJpc29uIi5zdWJzdHJpbmcoMykgcmV0dXJucyAiYmlzb24iCi0gICAqICJlbXB0aW5lc3MiLnN1YnN0cmluZyg5KSByZXR1cm5zICIiIChhbiBlbXB0eSBzdHJpbmcpCi0gICAqIDwvcHJlPjwvYmxvY2txdW90ZT4KLSAgICoKLSAgICogQHBhcmFtICAgICAgYmVnaW5JbmRleCAgIHRoZSBiZWdpbm5pbmcgaW5kZXgsIGluY2x1c2l2ZS4KLSAgICogQHJldHVybiAgICAgdGhlIHNwZWNpZmllZCBzdWJzdHJpbmcuCi0gICAqIEBleGNlcHRpb24gIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gIGlmCi0gICAqICAgICAgICAgICAgIDxjb2RlPmJlZ2luSW5kZXg8L2NvZGU+IGlzIG5lZ2F0aXZlIG9yIGxhcmdlciB0aGFuIHRoZQotICAgKiAgICAgICAgICAgICBsZW5ndGggb2YgdGhpcyA8Y29kZT5TdHJpbmc8L2NvZGU+IG9iamVjdC4KLSAgICovCi0gIHB1YmxpYyBYTUxTdHJpbmcgc3Vic3RyaW5nKGludCBiZWdpbkluZGV4KQotICB7Ci0KLSAgICBpbnQgbGVuID0gbV9sZW5ndGggLSBiZWdpbkluZGV4OwotCi0gICAgaWYgKGxlbiA8PSAwKQotICAgICAgcmV0dXJuIFhTdHJpbmcuRU1QVFlTVFJJTkc7Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIGludCBzdGFydCA9IG1fc3RhcnQgKyBiZWdpbkluZGV4OwotCi0gICAgICByZXR1cm4gbmV3IFhTdHJpbmdGb3JGU0IoZnNiKCksIHN0YXJ0LCBsZW4pOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIGEgbmV3IHN0cmluZyB0aGF0IGlzIGEgc3Vic3RyaW5nIG9mIHRoaXMgc3RyaW5nLiBUaGUKLSAgICogc3Vic3RyaW5nIGJlZ2lucyBhdCB0aGUgc3BlY2lmaWVkIDxjb2RlPmJlZ2luSW5kZXg8L2NvZGU+IGFuZAotICAgKiBleHRlbmRzIHRvIHRoZSBjaGFyYWN0ZXIgYXQgaW5kZXggPGNvZGU+ZW5kSW5kZXggLSAxPC9jb2RlPi4KLSAgICogVGh1cyB0aGUgbGVuZ3RoIG9mIHRoZSBzdWJzdHJpbmcgaXMgPGNvZGU+ZW5kSW5kZXgtYmVnaW5JbmRleDwvY29kZT4uCi0gICAqCi0gICAqIEBwYXJhbSAgICAgIGJlZ2luSW5kZXggICB0aGUgYmVnaW5uaW5nIGluZGV4LCBpbmNsdXNpdmUuCi0gICAqIEBwYXJhbSAgICAgIGVuZEluZGV4ICAgICB0aGUgZW5kaW5nIGluZGV4LCBleGNsdXNpdmUuCi0gICAqIEByZXR1cm4gICAgIHRoZSBzcGVjaWZpZWQgc3Vic3RyaW5nLgotICAgKiBAZXhjZXB0aW9uICBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uICBpZiB0aGUKLSAgICogICAgICAgICAgICAgPGNvZGU+YmVnaW5JbmRleDwvY29kZT4gaXMgbmVnYXRpdmUsIG9yCi0gICAqICAgICAgICAgICAgIDxjb2RlPmVuZEluZGV4PC9jb2RlPiBpcyBsYXJnZXIgdGhhbiB0aGUgbGVuZ3RoIG9mCi0gICAqICAgICAgICAgICAgIHRoaXMgPGNvZGU+U3RyaW5nPC9jb2RlPiBvYmplY3QsIG9yCi0gICAqICAgICAgICAgICAgIDxjb2RlPmJlZ2luSW5kZXg8L2NvZGU+IGlzIGxhcmdlciB0aGFuCi0gICAqICAgICAgICAgICAgIDxjb2RlPmVuZEluZGV4PC9jb2RlPi4KLSAgICovCi0gIHB1YmxpYyBYTUxTdHJpbmcgc3Vic3RyaW5nKGludCBiZWdpbkluZGV4LCBpbnQgZW5kSW5kZXgpCi0gIHsKLQotICAgIGludCBsZW4gPSBlbmRJbmRleCAtIGJlZ2luSW5kZXg7Ci0KLSAgICBpZiAobGVuID4gbV9sZW5ndGgpCi0gICAgICBsZW4gPSBtX2xlbmd0aDsKLQotICAgIGlmIChsZW4gPD0gMCkKLSAgICAgIHJldHVybiBYU3RyaW5nLkVNUFRZU1RSSU5HOwotICAgIGVsc2UKLSAgICB7Ci0gICAgICBpbnQgc3RhcnQgPSBtX3N0YXJ0ICsgYmVnaW5JbmRleDsKLQotICAgICAgcmV0dXJuIG5ldyBYU3RyaW5nRm9yRlNCKGZzYigpLCBzdGFydCwgbGVuKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogQ29uY2F0ZW5hdGVzIHRoZSBzcGVjaWZpZWQgc3RyaW5nIHRvIHRoZSBlbmQgb2YgdGhpcyBzdHJpbmcuCi0gICAqCi0gICAqIEBwYXJhbSAgIHN0ciAgIHRoZSA8Y29kZT5TdHJpbmc8L2NvZGU+IHRoYXQgaXMgY29uY2F0ZW5hdGVkIHRvIHRoZSBlbmQKLSAgICogICAgICAgICAgICAgICAgb2YgdGhpcyA8Y29kZT5TdHJpbmc8L2NvZGU+LgotICAgKiBAcmV0dXJuICBhIHN0cmluZyB0aGF0IHJlcHJlc2VudHMgdGhlIGNvbmNhdGVuYXRpb24gb2YgdGhpcyBvYmplY3QncwotICAgKiAgICAgICAgICBjaGFyYWN0ZXJzIGZvbGxvd2VkIGJ5IHRoZSBzdHJpbmcgYXJndW1lbnQncyBjaGFyYWN0ZXJzLgotICAgKiBAZXhjZXB0aW9uIGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiA8Y29kZT5zdHI8L2NvZGU+IGlzCi0gICAqICAgICAgICAgIDxjb2RlPm51bGw8L2NvZGU+LgotICAgKi8KLSAgcHVibGljIFhNTFN0cmluZyBjb25jYXQoU3RyaW5nIHN0cikKLSAgewotCi0gICAgLy8gJU9QVCUgTWFrZSBhbiBGU0IgaGVyZT8KLSAgICByZXR1cm4gbmV3IFhTdHJpbmcoc3RyKCkuY29uY2F0KHN0cikpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlbW92ZXMgd2hpdGUgc3BhY2UgZnJvbSBib3RoIGVuZHMgb2YgdGhpcyBzdHJpbmcuCi0gICAqCi0gICAqIEByZXR1cm4gIHRoaXMgc3RyaW5nLCB3aXRoIHdoaXRlIHNwYWNlIHJlbW92ZWQgZnJvbSB0aGUgZnJvbnQgYW5kIGVuZC4KLSAgICovCi0gIHB1YmxpYyBYTUxTdHJpbmcgdHJpbSgpCi0gIHsKLSAgICByZXR1cm4gZml4V2hpdGVTcGFjZSh0cnVlLCB0cnVlLCBmYWxzZSk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgPHZhcj5jaDwvdmFyPiBjb25mb3JtcyB0byB0aGUgWE1MIDEuMCBkZWZpbml0aW9uCi0gICAqIG9mIHdoaXRlc3BhY2UuICBSZWZlciB0byA8QSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy14bWwtMTk5ODAyMTAjTlQtUyI+Ci0gICAqIHRoZSBkZWZpbml0aW9uIG9mIDxDT0RFPlM8L0NPREU+PC9BPiBmb3IgZGV0YWlscy4KLSAgICogQHBhcmFtICAgY2ggICAgICBDaGFyYWN0ZXIgdG8gY2hlY2sgYXMgWE1MIHdoaXRlc3BhY2UuCi0gICAqIEByZXR1cm4gICAgICAgICAgPXRydWUgaWYgPHZhcj5jaDwvdmFyPiBpcyBYTUwgd2hpdGVzcGFjZTsgb3RoZXJ3aXNlID1mYWxzZS4KLSAgICovCi0gIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNTcGFjZShjaGFyIGNoKQotICB7Ci0gICAgcmV0dXJuIFhNTENoYXJhY3RlclJlY29nbml6ZXIuaXNXaGl0ZVNwYWNlKGNoKTsgIC8vIFRha2UgdGhlIGVhc3kgd2F5IG91dCBmb3Igbm93LgotICB9Ci0KLSAgLyoqCi0gICAqIENvbmRpdGlvbmFsbHkgdHJpbSBhbGwgbGVhZGluZyBhbmQgdHJhaWxpbmcgd2hpdGVzcGFjZSBpbiB0aGUgc3BlY2lmaWVkIFN0cmluZy4KLSAgICogQWxsIHN0cmluZ3Mgb2Ygd2hpdGUgc3BhY2UgYXJlCi0gICAqIHJlcGxhY2VkIGJ5IGEgc2luZ2xlIHNwYWNlIGNoYXJhY3RlciAoI3gyMCksIGV4Y2VwdCBzcGFjZXMgYWZ0ZXIgcHVuY3R1YXRpb24gd2hpY2gKLSAgICogcmVjZWl2ZSBkb3VibGUgc3BhY2VzIGlmIGRvdWJsZVB1bmN0dWF0aW9uU3BhY2VzIGlzIHRydWUuCi0gICAqIFRoaXMgZnVuY3Rpb24gbWF5IGJlIHVzZWZ1bCB0byBhIGZvcm1hdHRlciwgYnV0IHRvIGdldCBmaXJzdCBjbGFzcwotICAgKiByZXN1bHRzLCB0aGUgZm9ybWF0dGVyIHNob3VsZCBwcm9iYWJseSBkbyBpdCdzIG93biB3aGl0ZSBzcGFjZSBoYW5kbGluZwotICAgKiBiYXNlZCBvbiB0aGUgc2VtYW50aWNzIG9mIHRoZSBmb3JtYXR0aW5nIG9iamVjdC4KLSAgICoKLSAgICogQHBhcmFtICAgdHJpbUhlYWQgICAgVHJpbSBsZWFkaW5nIHdoaXRlc3BhY2U/Ci0gICAqIEBwYXJhbSAgIHRyaW1UYWlsICAgIFRyaW0gdHJhaWxpbmcgd2hpdGVzcGFjZT8KLSAgICogQHBhcmFtICAgZG91YmxlUHVuY3R1YXRpb25TcGFjZXMgICAgVXNlIGRvdWJsZSBzcGFjZXMgZm9yIHB1bmN0dWF0aW9uPwotICAgKiBAcmV0dXJuICAgICAgICAgICAgICBUaGUgdHJpbW1lZCBzdHJpbmcuCi0gICAqLwotICBwdWJsaWMgWE1MU3RyaW5nIGZpeFdoaXRlU3BhY2UoYm9vbGVhbiB0cmltSGVhZCwgYm9vbGVhbiB0cmltVGFpbCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gZG91YmxlUHVuY3R1YXRpb25TcGFjZXMpCi0gIHsKLQotICAgIGludCBlbmQgPSBtX2xlbmd0aCArIG1fc3RhcnQ7Ci0gICAgY2hhcltdIGJ1ZiA9IG5ldyBjaGFyW21fbGVuZ3RoXTsKLSAgICBGYXN0U3RyaW5nQnVmZmVyIGZzYiA9IGZzYigpOwotICAgIGJvb2xlYW4gZWRpdCA9IGZhbHNlOwotCi0gICAgLyogcmVwbGFjZSBTIHRvICcgJy4gYW5kICcgJysgLT4gc2luZ2xlICcgJy4gKi8KLSAgICBpbnQgZCA9IDA7Ci0gICAgYm9vbGVhbiBwcmVzID0gZmFsc2U7Ci0KLSAgICBmb3IgKGludCBzID0gbV9zdGFydDsgcyA8IGVuZDsgcysrKQotICAgIHsKLSAgICAgIGNoYXIgYyA9IGZzYi5jaGFyQXQocyk7Ci0KLSAgICAgIGlmIChpc1NwYWNlKGMpKQotICAgICAgewotICAgICAgICBpZiAoIXByZXMpCi0gICAgICAgIHsKLSAgICAgICAgICBpZiAoJyAnICE9IGMpCi0gICAgICAgICAgewotICAgICAgICAgICAgZWRpdCA9IHRydWU7Ci0gICAgICAgICAgfQotCi0gICAgICAgICAgYnVmW2QrK10gPSAnICc7Ci0KLSAgICAgICAgICBpZiAoZG91YmxlUHVuY3R1YXRpb25TcGFjZXMgJiYgKGQgIT0gMCkpCi0gICAgICAgICAgewotICAgICAgICAgICAgY2hhciBwcmV2Q2hhciA9IGJ1ZltkIC0gMV07Ci0KLSAgICAgICAgICAgIGlmICghKChwcmV2Q2hhciA9PSAnLicpIHx8IChwcmV2Q2hhciA9PSAnIScpCi0gICAgICAgICAgICAgICAgICB8fCAocHJldkNoYXIgPT0gJz8nKSkpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIHByZXMgPSB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICAgIH0KLSAgICAgICAgICBlbHNlCi0gICAgICAgICAgewotICAgICAgICAgICAgcHJlcyA9IHRydWU7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotICAgICAgICAgIGVkaXQgPSB0cnVlOwotICAgICAgICAgIHByZXMgPSB0cnVlOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIGJ1ZltkKytdID0gYzsKLSAgICAgICAgcHJlcyA9IGZhbHNlOwotICAgICAgfQotICAgIH0KLQotICAgIGlmICh0cmltVGFpbCAmJiAxIDw9IGQgJiYgJyAnID09IGJ1ZltkIC0gMV0pCi0gICAgewotICAgICAgZWRpdCA9IHRydWU7Ci0KLSAgICAgIGQtLTsKLSAgICB9Ci0KLSAgICBpbnQgc3RhcnQgPSAwOwotCi0gICAgaWYgKHRyaW1IZWFkICYmIDAgPCBkICYmICcgJyA9PSBidWZbMF0pCi0gICAgewotICAgICAgZWRpdCA9IHRydWU7Ci0KLSAgICAgIHN0YXJ0Kys7Ci0gICAgfQotCi0gICAgWE1MU3RyaW5nRmFjdG9yeSB4c2YgPSBYTUxTdHJpbmdGYWN0b3J5SW1wbC5nZXRGYWN0b3J5KCk7Ci0KLSAgICByZXR1cm4gZWRpdCA/IHhzZi5uZXdzdHIoYnVmLCBzdGFydCwgZCAtIHN0YXJ0KSA6IHRoaXM7Ci0gIH0KLQotICAvKioKLSAgICogQ29udmVydCBhIHN0cmluZyB0byBhIGRvdWJsZSAtLSBBbGxvd2VkIGlucHV0IGlzIGluIGZpeGVkCi0gICAqIG5vdGF0aW9uIGRkZC5mZmYuCi0gICAqCi0gICAqICVPUFQlIENIRUNLIFBFUkZPUk1BTkNFIGFnYWluc3QgZ2VuZXJhdGluZyBhIEphdmEgU3RyaW5nIGFuZAotICAgKiBjb252ZXJ0aW5nIGl0IHRvIGRvdWJsZS4gVGhlIGFkdmFudGFnZSBvZiBydW5uaW5nIGluIG5hdGl2ZQotICAgKiBtYWNoaW5lIGNvZGUgLS0gcGVyaGFwcyBldmVuIG1pY3JvY29kZSwgb24gc29tZSBzeXN0ZW1zIC0tIG1heQotICAgKiBtb3JlIHRoYW4gbWFrZSB1cCBmb3IgdGhlIGNvc3Qgb2YgYWxsb2NhdGluZyBhbmQgZGlzY2FyZGluZyB0aGUKLSAgICogYWRkaXRpb25hbCBvYmplY3QuIFdlIG5lZWQgdG8gYmVuY2htYXJrIHRoaXMuCi0gICAqCi0gICAqICVPUFQlIE1vcmUgaW1wb3J0YW50bHksIHdlIG5lZWQgdG8gZGVjaWRlIHdoZXRoZXIgd2UgX2NhcmVfIGFib3V0Ci0gICAqIHRoZSBwZXJmb3JtYW5jZSBvZiB0aGlzIG9wZXJhdGlvbi4gRG9lcyBYU3RyaW5nLnRvRG91YmxlIGNvbnN0aXR1dGUKLSAgICogYW55IG1lYXN1cmFibGUgcGVyY2VudGFnZSBvZiBvdXIgdHlwaWNhbCBydW50aW1lPyBJIHN1c3BlY3Qgbm90IQotICAgKgotICAgKiBAcmV0dXJuIEEgZG91YmxlIHZhbHVlIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBzdHJpbmcsIG9yIHJldHVybiBEb3VibGUuTmFOCi0gICAqIGlmIHRoZSBzdHJpbmcgY2FuIG5vdCBiZSBjb252ZXJ0ZWQuICAqLwotICBwdWJsaWMgZG91YmxlIHRvRG91YmxlKCkKLSAgewotICAgIGlmKG1fbGVuZ3RoID09IDApCi0gICAgICByZXR1cm4gRG91YmxlLk5hTjsKLSAgICBpbnQgaTsKLSAgICBjaGFyIGM7Ci0gICAgU3RyaW5nIHZhbHVlU3RyaW5nID0gZnNiKCkuZ2V0U3RyaW5nKG1fc3RhcnQsbV9sZW5ndGgpOwotCi0gICAgLy8gVGhlIGZvbGxvd2luZyBhcmUgcGVybWl0dGVkIGluIHRoZSBEb3VibGUudmFsdWVPZiwgYnV0IG5vdCBieSB0aGUgWFBhdGggc3BlYzoKLSAgICAvLyAtIGEgcGx1cyBzaWduCi0gICAgLy8gLSBUaGUgdXNlIG9mIGUgb3IgRSB0byBpbmRpY2F0ZSBleHBvbmVudHMKLSAgICAvLyAtIHRyYWlsaW5nIGYsIEYsIGQsIG9yIEQKLSAgICAvLyBTZWUgZnVuY3Rpb24gY29tbWVudHM7IG5vdCBzdXJlIGlmIHRoaXMgaXMgc2xvd2VyIHRoYW4gYWN0dWFsbHkgZG9pbmcgdGhlCi0gICAgLy8gY29udmVyc2lvbiBvdXJzZWx2ZXMgKGFzIHdhcyBiZWZvcmUpLgotCi0gICAgZm9yIChpPTA7aTxtX2xlbmd0aDtpKyspCi0gICAgICBpZiAoIVhNTENoYXJhY3RlclJlY29nbml6ZXIuaXNXaGl0ZVNwYWNlKHZhbHVlU3RyaW5nLmNoYXJBdChpKSkpCi0gICAgICAgIGJyZWFrOwotICAgIGlmIChpID09IG1fbGVuZ3RoKSByZXR1cm4gRG91YmxlLk5hTjsKLSAgICBpZiAodmFsdWVTdHJpbmcuY2hhckF0KGkpID09ICctJykKLSAgICAgIGkrKzsKLSAgICBmb3IgKDtpPG1fbGVuZ3RoO2krKykgewotICAgICAgYyA9IHZhbHVlU3RyaW5nLmNoYXJBdChpKTsKLSAgICAgIGlmIChjICE9ICcuJyAmJiAoYyA8ICcwJyB8fCBjID4gJzknKSkKLSAgICAgICAgYnJlYWs7Ci0gICAgfQotICAgIGZvciAoO2k8bV9sZW5ndGg7aSsrKQotICAgICAgaWYgKCFYTUxDaGFyYWN0ZXJSZWNvZ25pemVyLmlzV2hpdGVTcGFjZSh2YWx1ZVN0cmluZy5jaGFyQXQoaSkpKQotICAgICAgICBicmVhazsKLSAgICBpZiAoaSAhPSBtX2xlbmd0aCkKLSAgICAgIHJldHVybiBEb3VibGUuTmFOOwotCi0gICAgdHJ5IHsKLSAgICAgIHJldHVybiBEb3VibGUucGFyc2VEb3VibGUodmFsdWVTdHJpbmcpOwotICAgIH0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBuZmUpIHsKLSAgICAgIC8vIFRoaXMgc2hvdWxkIGNhdGNoIGRvdWJsZSBwZXJpb2RzLCBlbXB0eSBzdHJpbmdzLgotICAgICAgcmV0dXJuIERvdWJsZS5OYU47Ci0gICAgfQotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL29iamVjdHMvcGFja2FnZS5odG1sIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9vYmplY3RzL3BhY2thZ2UuaHRtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDdmMmEzMi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL29iamVjdHMvcGFja2FnZS5odG1sCisrKyAvZGV2L251bGwKQEAgLTEsMjkgKzAsMCBAQAotPCEtLQotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLS0tPgotPCEtLQotICogQ29weXJpZ2h0IDIwMDAtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0tLT4KLTwhLS0gJElkOiBwYWNrYWdlLmh0bWwsdiAxLjEuMi4xIDIwMDUvMDgvMDEgMDE6Mjk6MzAgamVmZnN1dHRvciBFeHAgJCAtLT4KLTxodG1sPgotICA8dGl0bGU+WFBhdGggb2JqZWN0cyBQYWNrYWdlLjwvdGl0bGU+Ci0gIDxib2R5PgotICAgIDxwPkltcGxlbWVudGF0aW9uIG9mIFhQYXRoIHBvbHltb3JwaGljIHR5cGUgb2JqZWN0cyAtLSB0aGlzIHBhY2thZ2Ugd2lsbCBncm93IAotICAgIGFzIFhQYXRoIG9iamVjdHMgYXJlIGV4cGFuZGVkIHRvIHN1cHBvcnQgWE1MIFNjaGVtYSBkYXRhIHR5cGVzLjxwPgotIDwvYm9keT4KLTwvaHRtbD4KLQotCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL29wZXJhdGlvbnMvQW5kLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL29wZXJhdGlvbnMvQW5kLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGY2ZmEwYzguLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9vcGVyYXRpb25zL0FuZC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNzcgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogQW5kLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTQgMjE6MzE6NDIgamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vcGVyYXRpb25zOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoQ29udGV4dDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YQm9vbGVhbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YT2JqZWN0OwotCi0vKioKLSAqIFRoZSAnYW5kJyBvcGVyYXRpb24gZXhwcmVzc2lvbiBleGVjdXRlci4KLSAqLwotcHVibGljIGNsYXNzIEFuZCBleHRlbmRzIE9wZXJhdGlvbgotewotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAzOTIzMzAwNzcxMjY1MzQwMjJMOwotCi0gIC8qKgotICAgKiBBTkQgdHdvIGV4cHJlc3Npb25zIGFuZCByZXR1cm4gdGhlIGJvb2xlYW4gcmVzdWx0LiBPdmVycmlkZQotICAgKiBzdXBlcmNsYXNzIG1ldGhvZCBmb3Igb3B0aW1pemF0aW9uIHB1cnBvc2VzLgotICAgKgotICAgKiBAcGFyYW0geGN0eHQgVGhlIHJ1bnRpbWUgZXhlY3V0aW9uIGNvbnRleHQuCi0gICAqCi0gICAqIEByZXR1cm4ge0BsaW5rIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhCb29sZWFuI1NfVFJVRX0gb3IKLSAgICoge0BsaW5rIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhCb29sZWFuI1NfRkFMU0V9LgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IGV4ZWN1dGUoWFBhdGhDb250ZXh0IHhjdHh0KSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBYT2JqZWN0IGV4cHIxID0gbV9sZWZ0LmV4ZWN1dGUoeGN0eHQpOwotCi0gICAgaWYgKGV4cHIxLmJvb2woKSkKLSAgICB7Ci0gICAgICBYT2JqZWN0IGV4cHIyID0gbV9yaWdodC5leGVjdXRlKHhjdHh0KTsKLQotICAgICAgcmV0dXJuIGV4cHIyLmJvb2woKSA/IFhCb29sZWFuLlNfVFJVRSA6IFhCb29sZWFuLlNfRkFMU0U7Ci0gICAgfQotICAgIGVsc2UKLSAgICAgIHJldHVybiBYQm9vbGVhbi5TX0ZBTFNFOwotICB9Ci0KLSAgLyoqCi0gICAqIEV2YWx1YXRlIHRoaXMgb3BlcmF0aW9uIGRpcmVjdGx5IHRvIGEgYm9vbGVhbi4KLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IFRoZSBydW50aW1lIGV4ZWN1dGlvbiBjb250ZXh0LgotICAgKgotICAgKiBAcmV0dXJuIFRoZSByZXN1bHQgb2YgdGhlIG9wZXJhdGlvbiBhcyBhIGJvb2xlYW4uCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gYm9vbChYUGF0aENvbnRleHQgeGN0eHQpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHJldHVybiAobV9sZWZ0LmJvb2woeGN0eHQpICYmIG1fcmlnaHQuYm9vbCh4Y3R4dCkpOwotICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvb3BlcmF0aW9ucy9Cb29sLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL29wZXJhdGlvbnMvQm9vbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmYzY1ZTVhLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvb3BlcmF0aW9ucy9Cb29sLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3MCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBCb29sLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTQgMjE6MzE6NDMgamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vcGVyYXRpb25zOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoQ29udGV4dDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YQm9vbGVhbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YT2JqZWN0OwotCi0vKioKLSAqIFRoZSAnYm9vbGVhbigpJyBvcGVyYXRpb24gZXhwcmVzc2lvbiBleGVjdXRlci4KLSAqLwotcHVibGljIGNsYXNzIEJvb2wgZXh0ZW5kcyBVbmFyeU9wZXJhdGlvbgotewotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA0NDcwNTM3NTMyMTkxNDYzNUw7Ci0KLSAgLyoqCi0gICAqIEFwcGx5IHRoZSBvcGVyYXRpb24gdG8gdHdvIG9wZXJhbmRzLCBhbmQgcmV0dXJuIHRoZSByZXN1bHQuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSByaWdodCBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIGV2YWx1YXRlZCByaWdodCBvcGVyYW5kLgotICAgKgotICAgKiBAcmV0dXJuIG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgWE9iamVjdCB0aGF0IHJlcHJlc2VudHMgdGhlIHJlc3VsdCBvZiB0aGUgb3BlcmF0aW9uLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IG9wZXJhdGUoWE9iamVjdCByaWdodCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKFhPYmplY3QuQ0xBU1NfQk9PTEVBTiA9PSByaWdodC5nZXRUeXBlKCkpCi0gICAgICByZXR1cm4gcmlnaHQ7Ci0gICAgZWxzZQotICAgICAgcmV0dXJuIHJpZ2h0LmJvb2woKSA/IFhCb29sZWFuLlNfVFJVRSA6IFhCb29sZWFuLlNfRkFMU0U7Ci0gIH0KLQotICAvKioKLSAgICogRXZhbHVhdGUgdGhpcyBvcGVyYXRpb24gZGlyZWN0bHkgdG8gYSBib29sZWFuLgotICAgKgotICAgKiBAcGFyYW0geGN0eHQgVGhlIHJ1bnRpbWUgZXhlY3V0aW9uIGNvbnRleHQuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHJlc3VsdCBvZiB0aGUgb3BlcmF0aW9uIGFzIGEgYm9vbGVhbi4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBib29sKFhQYXRoQ29udGV4dCB4Y3R4dCkKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIG1fcmlnaHQuYm9vbCh4Y3R4dCk7Ci0gIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9vcGVyYXRpb25zL0Rpdi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9vcGVyYXRpb25zL0Rpdi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhYTY4NTk4Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvb3BlcmF0aW9ucy9EaXYuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDY5ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IERpdi5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE0IDIxOjMxOjQ1IGplZmZzdXR0b3IgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub3BlcmF0aW9uczsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5YUGF0aENvbnRleHQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWE51bWJlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YT2JqZWN0OwotCi0vKioKLSAqIFRoZSAnZGl2JyBvcGVyYXRpb24gZXhwcmVzc2lvbiBleGVjdXRlci4KLSAqLwotcHVibGljIGNsYXNzIERpdiBleHRlbmRzIE9wZXJhdGlvbgotewotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA2MjIwNzU2NTk1OTU5Nzk4MTM1TDsKLQotICAvKioKLSAgICogQXBwbHkgdGhlIG9wZXJhdGlvbiB0byB0d28gb3BlcmFuZHMsIGFuZCByZXR1cm4gdGhlIHJlc3VsdC4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIGxlZnQgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSBldmFsdWF0ZWQgbGVmdCBvcGVyYW5kLgotICAgKiBAcGFyYW0gcmlnaHQgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSBldmFsdWF0ZWQgcmlnaHQgb3BlcmFuZC4KLSAgICoKLSAgICogQHJldHVybiBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIFhPYmplY3QgdGhhdCByZXByZXNlbnRzIHRoZSByZXN1bHQgb2YgdGhlIG9wZXJhdGlvbi4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBvcGVyYXRlKFhPYmplY3QgbGVmdCwgWE9iamVjdCByaWdodCkKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIG5ldyBYTnVtYmVyKGxlZnQubnVtKCkgLyByaWdodC5udW0oKSk7Ci0gIH0KLQotICAvKioKLSAgICogRXZhbHVhdGUgdGhpcyBvcGVyYXRpb24gZGlyZWN0bHkgdG8gYSBkb3VibGUuCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgcnVudGltZSBleGVjdXRpb24gY29udGV4dC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgcmVzdWx0IG9mIHRoZSBvcGVyYXRpb24gYXMgYSBkb3VibGUuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGRvdWJsZSBudW0oWFBhdGhDb250ZXh0IHhjdHh0KQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIHJldHVybiAobV9sZWZ0Lm51bSh4Y3R4dCkgLyBtX3JpZ2h0Lm51bSh4Y3R4dCkpOwotICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvb3BlcmF0aW9ucy9FcXVhbHMuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvb3BlcmF0aW9ucy9FcXVhbHMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZDhhY2VmNi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL29wZXJhdGlvbnMvRXF1YWxzLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3NiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBFcXVhbHMuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNCAyMTozMTo0NCBqZWZmc3V0dG9yIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9wZXJhdGlvbnM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuWFBhdGhDb250ZXh0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhCb29sZWFuOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhPYmplY3Q7Ci0KLS8qKgotICogVGhlICc9JyBvcGVyYXRpb24gZXhwcmVzc2lvbiBleGVjdXRlci4KLSAqLwotcHVibGljIGNsYXNzIEVxdWFscyBleHRlbmRzIE9wZXJhdGlvbgotewotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMjY1ODMxNTYzMzkwMzQyNjEzNEw7Ci0KLSAgLyoqCi0gICAqIEFwcGx5IHRoZSBvcGVyYXRpb24gdG8gdHdvIG9wZXJhbmRzLCBhbmQgcmV0dXJuIHRoZSByZXN1bHQuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBsZWZ0IG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgZXZhbHVhdGVkIGxlZnQgb3BlcmFuZC4KLSAgICogQHBhcmFtIHJpZ2h0IG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgZXZhbHVhdGVkIHJpZ2h0IG9wZXJhbmQuCi0gICAqCi0gICAqIEByZXR1cm4gbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSBYT2JqZWN0IHRoYXQgcmVwcmVzZW50cyB0aGUgcmVzdWx0IG9mIHRoZSBvcGVyYXRpb24uCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFhPYmplY3Qgb3BlcmF0ZShYT2JqZWN0IGxlZnQsIFhPYmplY3QgcmlnaHQpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHJldHVybiBsZWZ0LmVxdWFscyhyaWdodCkgPyBYQm9vbGVhbi5TX1RSVUUgOiBYQm9vbGVhbi5TX0ZBTFNFOwotICB9Ci0KLSAgLyoqCi0gICAqIEV4ZWN1dGUgYSBiaW5hcnkgb3BlcmF0aW9uIGJ5IGNhbGxpbmcgZXhlY3V0ZSBvbiBlYWNoIG9mIHRoZSBvcGVyYW5kcywKLSAgICogYW5kIHRoZW4gY2FsbGluZyB0aGUgb3BlcmF0ZSBtZXRob2Qgb24gdGhlIGRlcml2ZWQgY2xhc3MuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgcnVudGltZSBleGVjdXRpb24gY29udGV4dC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgWE9iamVjdCByZXN1bHQgb2YgdGhlIG9wZXJhdGlvbi4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBib29sKFhQYXRoQ29udGV4dCB4Y3R4dCkKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgWE9iamVjdCBsZWZ0ID0gbV9sZWZ0LmV4ZWN1dGUoeGN0eHQsIHRydWUpOwotICAgIFhPYmplY3QgcmlnaHQgPSBtX3JpZ2h0LmV4ZWN1dGUoeGN0eHQsIHRydWUpOwotCi0gICAgYm9vbGVhbiByZXN1bHQgPSBsZWZ0LmVxdWFscyhyaWdodCkgPyB0cnVlIDogZmFsc2U7Ci0gICAgICAgIGxlZnQuZGV0YWNoKCk7Ci0gICAgICAgIHJpZ2h0LmRldGFjaCgpOwotICAgIHJldHVybiByZXN1bHQ7Ci0gIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9vcGVyYXRpb25zL0d0LmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL29wZXJhdGlvbnMvR3QuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYjQ1OGQxNi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL29wZXJhdGlvbnMvR3QuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDUxICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IEd0LmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTQgMjE6MzE6NDQgamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vcGVyYXRpb25zOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWEJvb2xlYW47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWE9iamVjdDsKLQotLyoqCi0gKiBUaGUgJz4nIG9wZXJhdGlvbiBleHByZXNzaW9uIGV4ZWN1dGVyLgotICovCi1wdWJsaWMgY2xhc3MgR3QgZXh0ZW5kcyBPcGVyYXRpb24KLXsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gODkyNzA3ODc1MTAxNDM3NTk1MEw7Ci0KLSAgLyoqCi0gICAqIEFwcGx5IHRoZSBvcGVyYXRpb24gdG8gdHdvIG9wZXJhbmRzLCBhbmQgcmV0dXJuIHRoZSByZXN1bHQuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBsZWZ0IG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgZXZhbHVhdGVkIGxlZnQgb3BlcmFuZC4KLSAgICogQHBhcmFtIHJpZ2h0IG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgZXZhbHVhdGVkIHJpZ2h0IG9wZXJhbmQuCi0gICAqCi0gICAqIEByZXR1cm4gbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSBYT2JqZWN0IHRoYXQgcmVwcmVzZW50cyB0aGUgcmVzdWx0IG9mIHRoZSBvcGVyYXRpb24uCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFhPYmplY3Qgb3BlcmF0ZShYT2JqZWN0IGxlZnQsIFhPYmplY3QgcmlnaHQpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHJldHVybiBsZWZ0LmdyZWF0ZXJUaGFuKHJpZ2h0KSA/IFhCb29sZWFuLlNfVFJVRSA6IFhCb29sZWFuLlNfRkFMU0U7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvb3BlcmF0aW9ucy9HdGUuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvb3BlcmF0aW9ucy9HdGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMGY3YjA2My4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL29wZXJhdGlvbnMvR3RlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw1MiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBHdGUuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNCAyMTozMTo0MiBqZWZmc3V0dG9yIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9wZXJhdGlvbnM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YQm9vbGVhbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YT2JqZWN0OwotCi0vKioKLSAqIFRoZSAnPj0nIG9wZXJhdGlvbiBleHByZXNzaW9uIGV4ZWN1dGVyLgotICovCi1wdWJsaWMgY2xhc3MgR3RlIGV4dGVuZHMgT3BlcmF0aW9uCi17Ci0gICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDkxNDI5NDU5MDk5MDY2ODAyMjBMOwotCi0gIC8qKgotICAgKiBBcHBseSB0aGUgb3BlcmF0aW9uIHRvIHR3byBvcGVyYW5kcywgYW5kIHJldHVybiB0aGUgcmVzdWx0LgotICAgKgotICAgKgotICAgKiBAcGFyYW0gbGVmdCBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIGV2YWx1YXRlZCBsZWZ0IG9wZXJhbmQuCi0gICAqIEBwYXJhbSByaWdodCBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIGV2YWx1YXRlZCByaWdodCBvcGVyYW5kLgotICAgKgotICAgKiBAcmV0dXJuIG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgWE9iamVjdCB0aGF0IHJlcHJlc2VudHMgdGhlIHJlc3VsdCBvZiB0aGUgb3BlcmF0aW9uLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IG9wZXJhdGUoWE9iamVjdCBsZWZ0LCBYT2JqZWN0IHJpZ2h0KQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gbGVmdC5ncmVhdGVyVGhhbk9yRXF1YWwocmlnaHQpCi0gICAgICAgICAgID8gWEJvb2xlYW4uU19UUlVFIDogWEJvb2xlYW4uU19GQUxTRTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9vcGVyYXRpb25zL0x0LmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL29wZXJhdGlvbnMvTHQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZmIyODc2NC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL29wZXJhdGlvbnMvTHQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDUxICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IEx0LmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTQgMjE6MzE6NDEgamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vcGVyYXRpb25zOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWEJvb2xlYW47Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWE9iamVjdDsKLQotLyoqCi0gKiBUaGUgJzwnIG9wZXJhdGlvbiBleHByZXNzaW9uIGV4ZWN1dGVyLgotICovCi1wdWJsaWMgY2xhc3MgTHQgZXh0ZW5kcyBPcGVyYXRpb24KLXsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMzM4ODQyMDUwOTI4OTM1OTQyMkw7Ci0KLSAgLyoqCi0gICAqIEFwcGx5IHRoZSBvcGVyYXRpb24gdG8gdHdvIG9wZXJhbmRzLCBhbmQgcmV0dXJuIHRoZSByZXN1bHQuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBsZWZ0IG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgZXZhbHVhdGVkIGxlZnQgb3BlcmFuZC4KLSAgICogQHBhcmFtIHJpZ2h0IG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgZXZhbHVhdGVkIHJpZ2h0IG9wZXJhbmQuCi0gICAqCi0gICAqIEByZXR1cm4gbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSBYT2JqZWN0IHRoYXQgcmVwcmVzZW50cyB0aGUgcmVzdWx0IG9mIHRoZSBvcGVyYXRpb24uCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFhPYmplY3Qgb3BlcmF0ZShYT2JqZWN0IGxlZnQsIFhPYmplY3QgcmlnaHQpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHJldHVybiBsZWZ0Lmxlc3NUaGFuKHJpZ2h0KSA/IFhCb29sZWFuLlNfVFJVRSA6IFhCb29sZWFuLlNfRkFMU0U7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvb3BlcmF0aW9ucy9MdGUuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvb3BlcmF0aW9ucy9MdGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZGQyNzhlMS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL29wZXJhdGlvbnMvTHRlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw1MSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBMdGUuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNCAyMTozMTo0NSBqZWZmc3V0dG9yIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9wZXJhdGlvbnM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YQm9vbGVhbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YT2JqZWN0OwotCi0vKioKLSAqIFRoZSAnPD0nIG9wZXJhdGlvbiBleHByZXNzaW9uIGV4ZWN1dGVyLgotICovCi1wdWJsaWMgY2xhc3MgTHRlIGV4dGVuZHMgT3BlcmF0aW9uCi17Ci0gICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDY5NDU2NTA4MTA1MjcxNDAyMjhMOwotCi0gIC8qKgotICAgKiBBcHBseSB0aGUgb3BlcmF0aW9uIHRvIHR3byBvcGVyYW5kcywgYW5kIHJldHVybiB0aGUgcmVzdWx0LgotICAgKgotICAgKgotICAgKiBAcGFyYW0gbGVmdCBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIGV2YWx1YXRlZCBsZWZ0IG9wZXJhbmQuCi0gICAqIEBwYXJhbSByaWdodCBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIGV2YWx1YXRlZCByaWdodCBvcGVyYW5kLgotICAgKgotICAgKiBAcmV0dXJuIG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgWE9iamVjdCB0aGF0IHJlcHJlc2VudHMgdGhlIHJlc3VsdCBvZiB0aGUgb3BlcmF0aW9uLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IG9wZXJhdGUoWE9iamVjdCBsZWZ0LCBYT2JqZWN0IHJpZ2h0KQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gbGVmdC5sZXNzVGhhbk9yRXF1YWwocmlnaHQpID8gWEJvb2xlYW4uU19UUlVFIDogWEJvb2xlYW4uU19GQUxTRTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9vcGVyYXRpb25zL01pbnVzLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL29wZXJhdGlvbnMvTWludXMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZGI0MDRjZC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL29wZXJhdGlvbnMvTWludXMuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDcwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IE1pbnVzLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTQgMjE6MzE6NDQgamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vcGVyYXRpb25zOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoQ29udGV4dDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YTnVtYmVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhPYmplY3Q7Ci0KLS8qKgotICogVGhlIGJpbmFyeSAnLScgb3BlcmF0aW9uIGV4cHJlc3Npb24gZXhlY3V0ZXIuCi0gKi8KLXB1YmxpYyBjbGFzcyBNaW51cyBleHRlbmRzIE9wZXJhdGlvbgotewotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNTI5NzY3MjgzODE3MDg3MTA0M0w7Ci0KLSAgLyoqCi0gICAqIEFwcGx5IHRoZSBvcGVyYXRpb24gdG8gdHdvIG9wZXJhbmRzLCBhbmQgcmV0dXJuIHRoZSByZXN1bHQuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBsZWZ0IG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgZXZhbHVhdGVkIGxlZnQgb3BlcmFuZC4KLSAgICogQHBhcmFtIHJpZ2h0IG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgZXZhbHVhdGVkIHJpZ2h0IG9wZXJhbmQuCi0gICAqCi0gICAqIEByZXR1cm4gbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSBYT2JqZWN0IHRoYXQgcmVwcmVzZW50cyB0aGUKLSAgICogICAgICAgICByZXN1bHQgb2YgdGhlIG9wZXJhdGlvbi4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBvcGVyYXRlKFhPYmplY3QgbGVmdCwgWE9iamVjdCByaWdodCkKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIG5ldyBYTnVtYmVyKGxlZnQubnVtKCkgLSByaWdodC5udW0oKSk7Ci0gIH0KLQotICAvKioKLSAgICogRXZhbHVhdGUgdGhpcyBvcGVyYXRpb24gZGlyZWN0bHkgdG8gYSBkb3VibGUuCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgcnVudGltZSBleGVjdXRpb24gY29udGV4dC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgcmVzdWx0IG9mIHRoZSBvcGVyYXRpb24gYXMgYSBkb3VibGUuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGRvdWJsZSBudW0oWFBhdGhDb250ZXh0IHhjdHh0KQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIHJldHVybiAobV9sZWZ0Lm51bSh4Y3R4dCkgLSBtX3JpZ2h0Lm51bSh4Y3R4dCkpOwotICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvb3BlcmF0aW9ucy9Nb2QuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvb3BlcmF0aW9ucy9Nb2QuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZjNhNWQ4Yi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL29wZXJhdGlvbnMvTW9kLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw2OSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBNb2QuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNCAyMTozMTo0NSBqZWZmc3V0dG9yIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9wZXJhdGlvbnM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuWFBhdGhDb250ZXh0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhOdW1iZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWE9iamVjdDsKLQotLyoqCi0gKiBUaGUgJ21vZCcgb3BlcmF0aW9uIGV4cHJlc3Npb24gZXhlY3V0ZXIuCi0gKi8KLXB1YmxpYyBjbGFzcyBNb2QgZXh0ZW5kcyBPcGVyYXRpb24KLXsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNTAwOTQ3MTE1NDIzODkxODIwMUw7Ci0KLSAgLyoqCi0gICAqIEFwcGx5IHRoZSBvcGVyYXRpb24gdG8gdHdvIG9wZXJhbmRzLCBhbmQgcmV0dXJuIHRoZSByZXN1bHQuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBsZWZ0IG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgZXZhbHVhdGVkIGxlZnQgb3BlcmFuZC4KLSAgICogQHBhcmFtIHJpZ2h0IG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgZXZhbHVhdGVkIHJpZ2h0IG9wZXJhbmQuCi0gICAqCi0gICAqIEByZXR1cm4gbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSBYT2JqZWN0IHRoYXQgcmVwcmVzZW50cyB0aGUgcmVzdWx0IG9mIHRoZSBvcGVyYXRpb24uCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFhPYmplY3Qgb3BlcmF0ZShYT2JqZWN0IGxlZnQsIFhPYmplY3QgcmlnaHQpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHJldHVybiBuZXcgWE51bWJlcihsZWZ0Lm51bSgpICUgcmlnaHQubnVtKCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIEV2YWx1YXRlIHRoaXMgb3BlcmF0aW9uIGRpcmVjdGx5IHRvIGEgZG91YmxlLgotICAgKgotICAgKiBAcGFyYW0geGN0eHQgVGhlIHJ1bnRpbWUgZXhlY3V0aW9uIGNvbnRleHQuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHJlc3VsdCBvZiB0aGUgb3BlcmF0aW9uIGFzIGEgZG91YmxlLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBkb3VibGUgbnVtKFhQYXRoQ29udGV4dCB4Y3R4dCkKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICByZXR1cm4gKG1fbGVmdC5udW0oeGN0eHQpICUgbV9yaWdodC5udW0oeGN0eHQpKTsKLSAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL29wZXJhdGlvbnMvTXVsdC5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9vcGVyYXRpb25zL011bHQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYjllNGMyYi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL29wZXJhdGlvbnMvTXVsdC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNjggKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogTXVsdC5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE0IDIxOjMxOjQ2IGplZmZzdXR0b3IgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub3BlcmF0aW9uczsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5YUGF0aENvbnRleHQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWE51bWJlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YT2JqZWN0OwotCi0vKioKLSAqIFRoZSAnKicgb3BlcmF0aW9uIGV4cHJlc3Npb24gZXhlY3V0ZXIuCi0gKi8KLXB1YmxpYyBjbGFzcyBNdWx0IGV4dGVuZHMgT3BlcmF0aW9uCi17Ci0gICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC00OTU2NzcwMTQ3MDEzNDE0Njc1TDsKLQotICAvKioKLSAgICogQXBwbHkgdGhlIG9wZXJhdGlvbiB0byB0d28gb3BlcmFuZHMsIGFuZCByZXR1cm4gdGhlIHJlc3VsdC4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIGxlZnQgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSBldmFsdWF0ZWQgbGVmdCBvcGVyYW5kLgotICAgKiBAcGFyYW0gcmlnaHQgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSBldmFsdWF0ZWQgcmlnaHQgb3BlcmFuZC4KLSAgICoKLSAgICogQHJldHVybiBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIFhPYmplY3QgdGhhdCByZXByZXNlbnRzIHRoZSByZXN1bHQgb2YgdGhlIG9wZXJhdGlvbi4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBvcGVyYXRlKFhPYmplY3QgbGVmdCwgWE9iamVjdCByaWdodCkKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIG5ldyBYTnVtYmVyKGxlZnQubnVtKCkgKiByaWdodC5udW0oKSk7Ci0gIH0KLQotICAvKioKLSAgICogRXZhbHVhdGUgdGhpcyBvcGVyYXRpb24gZGlyZWN0bHkgdG8gYSBkb3VibGUuCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgcnVudGltZSBleGVjdXRpb24gY29udGV4dC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgcmVzdWx0IG9mIHRoZSBvcGVyYXRpb24gYXMgYSBkb3VibGUuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGRvdWJsZSBudW0oWFBhdGhDb250ZXh0IHhjdHh0KQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gKG1fbGVmdC5udW0oeGN0eHQpICogbV9yaWdodC5udW0oeGN0eHQpKTsKLSAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL29wZXJhdGlvbnMvTmVnLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL29wZXJhdGlvbnMvTmVnLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGRmNGMwNmUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9vcGVyYXRpb25zL05lZy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNjcgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogTmVnLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTQgMjE6MzE6NDUgamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vcGVyYXRpb25zOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoQ29udGV4dDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YTnVtYmVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhPYmplY3Q7Ci0KLS8qKgotICogVGhlIHVuYXJ5ICctJyBvcGVyYXRpb24gZXhwcmVzc2lvbiBleGVjdXRlci4KLSAqLwotcHVibGljIGNsYXNzIE5lZyBleHRlbmRzIFVuYXJ5T3BlcmF0aW9uCi17Ci0gICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC02MjgwNjA3NzAyMzc1NzAyMjkxTDsKLQotICAvKioKLSAgICogQXBwbHkgdGhlIG9wZXJhdGlvbiB0byB0d28gb3BlcmFuZHMsIGFuZCByZXR1cm4gdGhlIHJlc3VsdC4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHJpZ2h0IG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgZXZhbHVhdGVkIHJpZ2h0IG9wZXJhbmQuCi0gICAqCi0gICAqIEByZXR1cm4gbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSBYT2JqZWN0IHRoYXQgcmVwcmVzZW50cyB0aGUgcmVzdWx0IG9mIHRoZSBvcGVyYXRpb24uCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFhPYmplY3Qgb3BlcmF0ZShYT2JqZWN0IHJpZ2h0KSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIG5ldyBYTnVtYmVyKC1yaWdodC5udW0oKSk7Ci0gIH0KLQotICAvKioKLSAgICogRXZhbHVhdGUgdGhpcyBvcGVyYXRpb24gZGlyZWN0bHkgdG8gYSBkb3VibGUuCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgcnVudGltZSBleGVjdXRpb24gY29udGV4dC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgcmVzdWx0IG9mIHRoZSBvcGVyYXRpb24gYXMgYSBkb3VibGUuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGRvdWJsZSBudW0oWFBhdGhDb250ZXh0IHhjdHh0KQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIHJldHVybiAtKG1fcmlnaHQubnVtKHhjdHh0KSk7Ci0gIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9vcGVyYXRpb25zL05vdEVxdWFscy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9vcGVyYXRpb25zL05vdEVxdWFscy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxODgwODAzLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvb3BlcmF0aW9ucy9Ob3RFcXVhbHMuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDUxICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IE5vdEVxdWFscy5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE0IDIxOjMxOjQ0IGplZmZzdXR0b3IgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub3BlcmF0aW9uczsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhCb29sZWFuOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhPYmplY3Q7Ci0KLS8qKgotICogVGhlICchPScgb3BlcmF0aW9uIGV4cHJlc3Npb24gZXhlY3V0ZXIuCi0gKi8KLXB1YmxpYyBjbGFzcyBOb3RFcXVhbHMgZXh0ZW5kcyBPcGVyYXRpb24KLXsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTc4NjkwNzI4NjMwNzA1ODY5MDBMOwotCi0gIC8qKgotICAgKiBBcHBseSB0aGUgb3BlcmF0aW9uIHRvIHR3byBvcGVyYW5kcywgYW5kIHJldHVybiB0aGUgcmVzdWx0LgotICAgKgotICAgKgotICAgKiBAcGFyYW0gbGVmdCBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIGV2YWx1YXRlZCBsZWZ0IG9wZXJhbmQuCi0gICAqIEBwYXJhbSByaWdodCBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIGV2YWx1YXRlZCByaWdodCBvcGVyYW5kLgotICAgKgotICAgKiBAcmV0dXJuIG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgWE9iamVjdCB0aGF0IHJlcHJlc2VudHMgdGhlIHJlc3VsdCBvZiB0aGUgb3BlcmF0aW9uLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IG9wZXJhdGUoWE9iamVjdCBsZWZ0LCBYT2JqZWN0IHJpZ2h0KQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gKGxlZnQubm90RXF1YWxzKHJpZ2h0KSkgPyBYQm9vbGVhbi5TX1RSVUUgOiBYQm9vbGVhbi5TX0ZBTFNFOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL29wZXJhdGlvbnMvTnVtYmVyLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL29wZXJhdGlvbnMvTnVtYmVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDI0NGExZGIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9vcGVyYXRpb25zL051bWJlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNzEgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogTnVtYmVyLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTQgMjE6MzE6NDIgamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vcGVyYXRpb25zOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoQ29udGV4dDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YTnVtYmVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhPYmplY3Q7Ci0KLS8qKgotICogVGhlICdudW1iZXIoKScgb3BlcmF0aW9uIGV4cHJlc3Npb24gZXhlY3V0ZXIuCi0gKi8KLXB1YmxpYyBjbGFzcyBOdW1iZXIgZXh0ZW5kcyBVbmFyeU9wZXJhdGlvbgotewotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA3MTk2OTU0NDgyODcxNjE5NzY1TDsKLQotICAvKioKLSAgICogQXBwbHkgdGhlIG9wZXJhdGlvbiB0byB0d28gb3BlcmFuZHMsIGFuZCByZXR1cm4gdGhlIHJlc3VsdC4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHJpZ2h0IG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgZXZhbHVhdGVkIHJpZ2h0IG9wZXJhbmQuCi0gICAqCi0gICAqIEByZXR1cm4gbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSBYT2JqZWN0IHRoYXQgcmVwcmVzZW50cyB0aGUgcmVzdWx0IG9mIHRoZSBvcGVyYXRpb24uCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFhPYmplY3Qgb3BlcmF0ZShYT2JqZWN0IHJpZ2h0KSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAoWE9iamVjdC5DTEFTU19OVU1CRVIgPT0gcmlnaHQuZ2V0VHlwZSgpKQotICAgICAgcmV0dXJuIHJpZ2h0OwotICAgIGVsc2UKLSAgICAgIHJldHVybiBuZXcgWE51bWJlcihyaWdodC5udW0oKSk7Ci0gIH0KLQotICAvKioKLSAgICogRXZhbHVhdGUgdGhpcyBvcGVyYXRpb24gZGlyZWN0bHkgdG8gYSBkb3VibGUuCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgcnVudGltZSBleGVjdXRpb24gY29udGV4dC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgcmVzdWx0IG9mIHRoZSBvcGVyYXRpb24gYXMgYSBkb3VibGUuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGRvdWJsZSBudW0oWFBhdGhDb250ZXh0IHhjdHh0KQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIHJldHVybiBtX3JpZ2h0Lm51bSh4Y3R4dCk7Ci0gIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9vcGVyYXRpb25zL09wZXJhdGlvbi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9vcGVyYXRpb25zL09wZXJhdGlvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4NGJkZDMyLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvb3BlcmF0aW9ucy9PcGVyYXRpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIxNCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBPcGVyYXRpb24uamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNCAyMTozMTo0MiBqZWZmc3V0dG9yIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9wZXJhdGlvbnM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuRXhwcmVzc2lvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuRXhwcmVzc2lvbk93bmVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5YUGF0aENvbnRleHQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoVmlzaXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YT2JqZWN0OwotCi0vKioKLSAqIFRoZSBiYXNlY2xhc3MgZm9yIGEgYmluYXJ5IG9wZXJhdGlvbi4KLSAqLwotcHVibGljIGNsYXNzIE9wZXJhdGlvbiBleHRlbmRzIEV4cHJlc3Npb24gaW1wbGVtZW50cyBFeHByZXNzaW9uT3duZXIKLXsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTMwMzcxMzk1MzcxNzEwNTA0MzBMOwotCi0gIC8qKiBUaGUgbGVmdCBvcGVyYW5kIGV4cHJlc3Npb24uCi0gICAqICBAc2VyaWFsICovCi0gIHByb3RlY3RlZCBFeHByZXNzaW9uIG1fbGVmdDsKLQotICAvKiogVGhlIHJpZ2h0IG9wZXJhbmQgZXhwcmVzc2lvbi4KLSAgICogIEBzZXJpYWwgKi8KLSAgcHJvdGVjdGVkIEV4cHJlc3Npb24gbV9yaWdodDsKLQotICAvKioKLSAgICogVGhpcyBmdW5jdGlvbiBpcyB1c2VkIHRvIGZpeHVwIHZhcmlhYmxlcyBmcm9tIFFOYW1lcyB0byBzdGFjayBmcmFtZQotICAgKiBpbmRleGVzIGF0IHN0eWxlc2hlZXQgYnVpbGQgdGltZS4KLSAgICogQHBhcmFtIHZhcnMgTGlzdCBvZiBRTmFtZXMgdGhhdCBjb3JyZXNwb25kIHRvIHZhcmlhYmxlcy4gIFRoaXMgbGlzdAotICAgKiBzaG91bGQgYmUgc2VhcmNoZWQgYmFja3dhcmRzIGZvciB0aGUgZmlyc3QgcXVhbGlmaWVkIG5hbWUgdGhhdAotICAgKiBjb3JyZXNwb25kcyB0byB0aGUgdmFyaWFibGUgcmVmZXJlbmNlIHFuYW1lLiAgVGhlIHBvc2l0aW9uIG9mIHRoZQotICAgKiBRTmFtZSBpbiB0aGUgdmVjdG9yIGZyb20gdGhlIHN0YXJ0IG9mIHRoZSB2ZWN0b3Igd2lsbCBiZSBpdHMgcG9zaXRpb24KLSAgICogaW4gdGhlIHN0YWNrIGZyYW1lIChidXQgdmFyaWFibGVzIGFib3ZlIHRoZSBnbG9iYWxzVG9wIHZhbHVlIHdpbGwgbmVlZAotICAgKiB0byBiZSBvZmZzZXQgdG8gdGhlIGN1cnJlbnQgc3RhY2sgZnJhbWUpLgotICAgKi8KLSAgcHVibGljIHZvaWQgZml4dXBWYXJpYWJsZXMoamF2YS51dGlsLlZlY3RvciB2YXJzLCBpbnQgZ2xvYmFsc1NpemUpCi0gIHsKLSAgICBtX2xlZnQuZml4dXBWYXJpYWJsZXModmFycywgZ2xvYmFsc1NpemUpOwotICAgIG1fcmlnaHQuZml4dXBWYXJpYWJsZXModmFycywgZ2xvYmFsc1NpemUpOwotICB9Ci0KLQotICAvKioKLSAgICogVGVsbCBpZiB0aGlzIGV4cHJlc3Npb24gb3IgaXQncyBzdWJleHByZXNzaW9ucyBjYW4gdHJhdmVyc2Ugb3V0c2lkZQotICAgKiB0aGUgY3VycmVudCBzdWJ0cmVlLgotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYgdHJhdmVyc2FsIG91dHNpZGUgdGhlIGNvbnRleHQgbm9kZSdzIHN1YnRyZWUgY2FuIG9jY3VyLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gY2FuVHJhdmVyc2VPdXRzaWRlU3VidHJlZSgpCi0gIHsKLQotICAgIGlmIChudWxsICE9IG1fbGVmdCAmJiBtX2xlZnQuY2FuVHJhdmVyc2VPdXRzaWRlU3VidHJlZSgpKQotICAgICAgcmV0dXJuIHRydWU7Ci0KLSAgICBpZiAobnVsbCAhPSBtX3JpZ2h0ICYmIG1fcmlnaHQuY2FuVHJhdmVyc2VPdXRzaWRlU3VidHJlZSgpKQotICAgICAgcmV0dXJuIHRydWU7Ci0KLSAgICByZXR1cm4gZmFsc2U7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBsZWZ0IGFuZCByaWdodCBvcGVyYW5kIGV4cHJlc3Npb25zIGZvciB0aGlzIG9wZXJhdGlvbi4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIGwgVGhlIGxlZnQgZXhwcmVzc2lvbiBvcGVyYW5kLgotICAgKiBAcGFyYW0gciBUaGUgcmlnaHQgZXhwcmVzc2lvbiBvcGVyYW5kLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0TGVmdFJpZ2h0KEV4cHJlc3Npb24gbCwgRXhwcmVzc2lvbiByKQotICB7Ci0gICAgbV9sZWZ0ID0gbDsKLSAgICBtX3JpZ2h0ID0gcjsKLSAgICBsLmV4cHJTZXRQYXJlbnQodGhpcyk7Ci0gICAgci5leHByU2V0UGFyZW50KHRoaXMpOwotICB9Ci0KLSAgLyoqCi0gICAqIEV4ZWN1dGUgYSBiaW5hcnkgb3BlcmF0aW9uIGJ5IGNhbGxpbmcgZXhlY3V0ZSBvbiBlYWNoIG9mIHRoZSBvcGVyYW5kcywKLSAgICogYW5kIHRoZW4gY2FsbGluZyB0aGUgb3BlcmF0ZSBtZXRob2Qgb24gdGhlIGRlcml2ZWQgY2xhc3MuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgcnVudGltZSBleGVjdXRpb24gY29udGV4dC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgWE9iamVjdCByZXN1bHQgb2YgdGhlIG9wZXJhdGlvbi4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBleGVjdXRlKFhQYXRoQ29udGV4dCB4Y3R4dCkKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBYT2JqZWN0IGxlZnQgPSBtX2xlZnQuZXhlY3V0ZSh4Y3R4dCwgdHJ1ZSk7Ci0gICAgWE9iamVjdCByaWdodCA9IG1fcmlnaHQuZXhlY3V0ZSh4Y3R4dCwgdHJ1ZSk7Ci0KLSAgICBYT2JqZWN0IHJlc3VsdCA9IG9wZXJhdGUobGVmdCwgcmlnaHQpOwotICAgIGxlZnQuZGV0YWNoKCk7Ci0gICAgcmlnaHQuZGV0YWNoKCk7Ci0gICAgcmV0dXJuIHJlc3VsdDsKLSAgfQotCi0gIC8qKgotICAgKiBBcHBseSB0aGUgb3BlcmF0aW9uIHRvIHR3byBvcGVyYW5kcywgYW5kIHJldHVybiB0aGUgcmVzdWx0LgotICAgKgotICAgKgotICAgKiBAcGFyYW0gbGVmdCBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIGV2YWx1YXRlZCBsZWZ0IG9wZXJhbmQuCi0gICAqIEBwYXJhbSByaWdodCBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIGV2YWx1YXRlZCByaWdodCBvcGVyYW5kLgotICAgKgotICAgKiBAcmV0dXJuIG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgWE9iamVjdCB0aGF0IHJlcHJlc2VudHMgdGhlIHJlc3VsdCBvZiB0aGUgb3BlcmF0aW9uLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IG9wZXJhdGUoWE9iamVjdCBsZWZ0LCBYT2JqZWN0IHJpZ2h0KQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gbnVsbDsgIC8vIG5vLW9wCi0gIH0KLQotICAvKiogQHJldHVybiB0aGUgbGVmdCBvcGVyYW5kIG9mIGJpbmFyeSBvcGVyYXRpb24sIGFzIGFuIEV4cHJlc3Npb24uCi0gICAqLwotICBwdWJsaWMgRXhwcmVzc2lvbiBnZXRMZWZ0T3BlcmFuZCgpewotICAgIHJldHVybiBtX2xlZnQ7Ci0gIH0KLQotICAvKiogQHJldHVybiB0aGUgcmlnaHQgb3BlcmFuZCBvZiBiaW5hcnkgb3BlcmF0aW9uLCBhcyBhbiBFeHByZXNzaW9uLgotICAgKi8KLSAgcHVibGljIEV4cHJlc3Npb24gZ2V0UmlnaHRPcGVyYW5kKCl7Ci0gICAgcmV0dXJuIG1fcmlnaHQ7Ci0gIH0KLQotICBjbGFzcyBMZWZ0RXhwck93bmVyIGltcGxlbWVudHMgRXhwcmVzc2lvbk93bmVyCi0gIHsKLSAgICAvKioKLSAgICAgKiBAc2VlIEV4cHJlc3Npb25Pd25lciNnZXRFeHByZXNzaW9uKCkKLSAgICAgKi8KLSAgICBwdWJsaWMgRXhwcmVzc2lvbiBnZXRFeHByZXNzaW9uKCkKLSAgICB7Ci0gICAgICByZXR1cm4gbV9sZWZ0OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgRXhwcmVzc2lvbk93bmVyI3NldEV4cHJlc3Npb24oRXhwcmVzc2lvbikKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRFeHByZXNzaW9uKEV4cHJlc3Npb24gZXhwKQotICAgIHsKLSAgICAgICAgZXhwLmV4cHJTZXRQYXJlbnQoT3BlcmF0aW9uLnRoaXMpOwotICAgICAgICBtX2xlZnQgPSBleHA7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoVmlzaXRhYmxlI2NhbGxWaXNpdG9ycyhFeHByZXNzaW9uT3duZXIsIFhQYXRoVmlzaXRvcikKLSAgICovCi0gIHB1YmxpYyB2b2lkIGNhbGxWaXNpdG9ycyhFeHByZXNzaW9uT3duZXIgb3duZXIsIFhQYXRoVmlzaXRvciB2aXNpdG9yKQotICB7Ci0gICAgICAgIGlmKHZpc2l0b3IudmlzaXRCaW5hcnlPcGVyYXRpb24ob3duZXIsIHRoaXMpKQotICAgICAgICB7Ci0gICAgICAgICAgICAgICAgbV9sZWZ0LmNhbGxWaXNpdG9ycyhuZXcgTGVmdEV4cHJPd25lcigpLCB2aXNpdG9yKTsKLSAgICAgICAgICAgICAgICBtX3JpZ2h0LmNhbGxWaXNpdG9ycyh0aGlzLCB2aXNpdG9yKTsKLSAgICAgICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEBzZWUgRXhwcmVzc2lvbk93bmVyI2dldEV4cHJlc3Npb24oKQotICAgKi8KLSAgcHVibGljIEV4cHJlc3Npb24gZ2V0RXhwcmVzc2lvbigpCi0gIHsKLSAgICByZXR1cm4gbV9yaWdodDsKLSAgfQotCi0gIC8qKgotICAgKiBAc2VlIEV4cHJlc3Npb25Pd25lciNzZXRFeHByZXNzaW9uKEV4cHJlc3Npb24pCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRFeHByZXNzaW9uKEV4cHJlc3Npb24gZXhwKQotICB7Ci0gICAgICAgIGV4cC5leHByU2V0UGFyZW50KHRoaXMpOwotICAgICAgICBtX3JpZ2h0ID0gZXhwOwotICB9Ci0KLSAgLyoqCi0gICAqIEBzZWUgRXhwcmVzc2lvbiNkZWVwRXF1YWxzKEV4cHJlc3Npb24pCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBkZWVwRXF1YWxzKEV4cHJlc3Npb24gZXhwcikKLSAgewotICAgICAgICBpZighaXNTYW1lQ2xhc3MoZXhwcikpCi0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotCi0gICAgICAgIGlmKCFtX2xlZnQuZGVlcEVxdWFscygoKE9wZXJhdGlvbilleHByKS5tX2xlZnQpKQotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLQotICAgICAgICBpZighbV9yaWdodC5kZWVwRXF1YWxzKCgoT3BlcmF0aW9uKWV4cHIpLm1fcmlnaHQpKQotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLQotICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9vcGVyYXRpb25zL09yLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL29wZXJhdGlvbnMvT3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMjZlNWI4Mi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL29wZXJhdGlvbnMvT3IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDc3ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IE9yLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTQgMjE6MzE6NDEgamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vcGVyYXRpb25zOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoQ29udGV4dDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YQm9vbGVhbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YT2JqZWN0OwotCi0vKioKLSAqIFRoZSAnb3InIG9wZXJhdGlvbiBleHByZXNzaW9uIGV4ZWN1dGVyLgotICovCi1wdWJsaWMgY2xhc3MgT3IgZXh0ZW5kcyBPcGVyYXRpb24KLXsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTY0NDEwNzE5MTM1Mzg1MzA3OUw7Ci0KLSAgLyoqCi0gICAqIE9SIHR3byBleHByZXNzaW9ucyBhbmQgcmV0dXJuIHRoZSBib29sZWFuIHJlc3VsdC4gT3ZlcnJpZGUKLSAgICogc3VwZXJjbGFzcyBtZXRob2QgZm9yIG9wdGltaXphdGlvbiBwdXJwb3Nlcy4KLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IFRoZSBydW50aW1lIGV4ZWN1dGlvbiBjb250ZXh0LgotICAgKgotICAgKiBAcmV0dXJuIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YQm9vbGVhbiNTX1RSVUV9IG9yCi0gICAqIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YQm9vbGVhbiNTX0ZBTFNFfS4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBleGVjdXRlKFhQYXRoQ29udGV4dCB4Y3R4dCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgWE9iamVjdCBleHByMSA9IG1fbGVmdC5leGVjdXRlKHhjdHh0KTsKLQotICAgIGlmICghZXhwcjEuYm9vbCgpKQotICAgIHsKLSAgICAgIFhPYmplY3QgZXhwcjIgPSBtX3JpZ2h0LmV4ZWN1dGUoeGN0eHQpOwotCi0gICAgICByZXR1cm4gZXhwcjIuYm9vbCgpID8gWEJvb2xlYW4uU19UUlVFIDogWEJvb2xlYW4uU19GQUxTRTsKLSAgICB9Ci0gICAgZWxzZQotICAgICAgcmV0dXJuIFhCb29sZWFuLlNfVFJVRTsKLSAgfQotCi0gIC8qKgotICAgKiBFdmFsdWF0ZSB0aGlzIG9wZXJhdGlvbiBkaXJlY3RseSB0byBhIGJvb2xlYW4uCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgcnVudGltZSBleGVjdXRpb24gY29udGV4dC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgcmVzdWx0IG9mIHRoZSBvcGVyYXRpb24gYXMgYSBib29sZWFuLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGJvb2woWFBhdGhDb250ZXh0IHhjdHh0KQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gKG1fbGVmdC5ib29sKHhjdHh0KSB8fCBtX3JpZ2h0LmJvb2woeGN0eHQpKTsKLSAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL29wZXJhdGlvbnMvUGx1cy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9vcGVyYXRpb25zL1BsdXMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZTViOTg1My4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL29wZXJhdGlvbnMvUGx1cy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNjkgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogUGx1cy5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE0IDIxOjMxOjQzIGplZmZzdXR0b3IgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub3BlcmF0aW9uczsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5YUGF0aENvbnRleHQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWE51bWJlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YT2JqZWN0OwotCi0vKioKLSAqIFRoZSAnKycgb3BlcmF0aW9uIGV4cHJlc3Npb24gZXhlY3V0ZXIuCi0gKi8KLXB1YmxpYyBjbGFzcyBQbHVzIGV4dGVuZHMgT3BlcmF0aW9uCi17Ci0gICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC00NDkyMDcyODYxNjE2NTA0MjU2TDsKLQotICAvKioKLSAgICogQXBwbHkgdGhlIG9wZXJhdGlvbiB0byB0d28gb3BlcmFuZHMsIGFuZCByZXR1cm4gdGhlIHJlc3VsdC4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIGxlZnQgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSBldmFsdWF0ZWQgbGVmdCBvcGVyYW5kLgotICAgKiBAcGFyYW0gcmlnaHQgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSBldmFsdWF0ZWQgcmlnaHQgb3BlcmFuZC4KLSAgICoKLSAgICogQHJldHVybiBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIFhPYmplY3QgdGhhdCByZXByZXNlbnRzIHRoZSByZXN1bHQgb2YgdGhlIG9wZXJhdGlvbi4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBvcGVyYXRlKFhPYmplY3QgbGVmdCwgWE9iamVjdCByaWdodCkKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIG5ldyBYTnVtYmVyKGxlZnQubnVtKCkgKyByaWdodC5udW0oKSk7Ci0gIH0KLQotICAvKioKLSAgICogRXZhbHVhdGUgdGhpcyBvcGVyYXRpb24gZGlyZWN0bHkgdG8gYSBkb3VibGUuCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgcnVudGltZSBleGVjdXRpb24gY29udGV4dC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgcmVzdWx0IG9mIHRoZSBvcGVyYXRpb24gYXMgYSBkb3VibGUuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGRvdWJsZSBudW0oWFBhdGhDb250ZXh0IHhjdHh0KQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIHJldHVybiAobV9yaWdodC5udW0oeGN0eHQpICsgbV9sZWZ0Lm51bSh4Y3R4dCkpOwotICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvb3BlcmF0aW9ucy9RdW8uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvb3BlcmF0aW9ucy9RdW8uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZGI2Yjg4Mi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL29wZXJhdGlvbnMvUXVvLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw1NCArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBRdW8uamF2YSx2IDEuMi40LjIgMjAwNS8wOS8xNCAyMTozMTo0NCBqZWZmc3V0dG9yIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9wZXJhdGlvbnM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YTnVtYmVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzLlhPYmplY3Q7Ci0KLS8qKgotICogVGhlICdxdW8nIG9wZXJhdGlvbiBleHByZXNzaW9uIGV4ZWN1dGVyLiAobm8gbG9uZ2VyIHN1cHBvcnRlZCBieSBYUGF0aCkuCi0gKiBAZGVwcmVjYXRlZAotICovCi1wdWJsaWMgY2xhc3MgUXVvIGV4dGVuZHMgT3BlcmF0aW9uCi17Ci0gICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDY5Mzc2NTI5OTE5NjE2OTkwNUw7Ci0KLSAgLy8gQWN0dWFsbHksIHRoaXMgaXMgbm8gbG9uZ2VyIHN1cHBvcnRlZCBieSB4cGF0aC4uLgotCi0gIC8qKgotICAgKiBBcHBseSB0aGUgb3BlcmF0aW9uIHRvIHR3byBvcGVyYW5kcywgYW5kIHJldHVybiB0aGUgcmVzdWx0LgotICAgKgotICAgKgotICAgKiBAcGFyYW0gbGVmdCBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIGV2YWx1YXRlZCBsZWZ0IG9wZXJhbmQuCi0gICAqIEBwYXJhbSByaWdodCBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIGV2YWx1YXRlZCByaWdodCBvcGVyYW5kLgotICAgKgotICAgKiBAcmV0dXJuIG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgWE9iamVjdCB0aGF0IHJlcHJlc2VudHMgdGhlIHJlc3VsdCBvZiB0aGUgb3BlcmF0aW9uLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IG9wZXJhdGUoWE9iamVjdCBsZWZ0LCBYT2JqZWN0IHJpZ2h0KQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gbmV3IFhOdW1iZXIoKGludCkgKGxlZnQubnVtKCkgLyByaWdodC5udW0oKSkpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL29wZXJhdGlvbnMvU3RyaW5nLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL29wZXJhdGlvbnMvU3RyaW5nLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAzNzE0YmUuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9vcGVyYXRpb25zL1N0cmluZy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDkgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogU3RyaW5nLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTQgMjE6MzE6NDQgamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vcGVyYXRpb25zOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWE9iamVjdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YU3RyaW5nOwotCi0vKioKLSAqIFRoZSAnc3RyaW5nKCknIG9wZXJhdGlvbiBleHByZXNzaW9uIGV4ZWN1dGVyLgotICovCi1wdWJsaWMgY2xhc3MgU3RyaW5nIGV4dGVuZHMgVW5hcnlPcGVyYXRpb24KLXsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMjk3MzM3NDM3NzQ1MzAyMjg4OEw7Ci0KLSAgLyoqCi0gICAqIEFwcGx5IHRoZSBvcGVyYXRpb24gdG8gdHdvIG9wZXJhbmRzLCBhbmQgcmV0dXJuIHRoZSByZXN1bHQuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSByaWdodCBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIGV2YWx1YXRlZCByaWdodCBvcGVyYW5kLgotICAgKgotICAgKiBAcmV0dXJuIG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgWE9iamVjdCB0aGF0IHJlcHJlc2VudHMgdGhlIHJlc3VsdCBvZiB0aGUgb3BlcmF0aW9uLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IG9wZXJhdGUoWE9iamVjdCByaWdodCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHJldHVybiAoWFN0cmluZylyaWdodC54c3RyKCk7IC8vIHNlbWktc2FmZSBjYXN0LgotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL29wZXJhdGlvbnMvVW5hcnlPcGVyYXRpb24uamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvb3BlcmF0aW9ucy9VbmFyeU9wZXJhdGlvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmZDA2NmEzLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvb3BlcmF0aW9ucy9VbmFyeU9wZXJhdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTY1ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFVuYXJ5T3BlcmF0aW9uLmphdmEsdiAxLjIuNC4xIDIwMDUvMDkvMTQgMjE6MzE6NDQgamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vcGVyYXRpb25zOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLkV4cHJlc3Npb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLkV4cHJlc3Npb25Pd25lcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuWFBhdGhDb250ZXh0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5YUGF0aFZpc2l0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWE9iamVjdDsKLQotLyoqCi0gKiBUaGUgdW5hcnkgb3BlcmF0aW9uIGJhc2UgY2xhc3MuCi0gKi8KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBVbmFyeU9wZXJhdGlvbiBleHRlbmRzIEV4cHJlc3Npb24gaW1wbGVtZW50cyBFeHByZXNzaW9uT3duZXIKLXsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNjUzNjA4MzgwODQyNDI4NjE2Nkw7Ci0KLSAgLyoqIFRoZSBvcGVyYW5kIGZvciB0aGUgb3BlcmF0aW9uLgotICAgKiAgQHNlcmlhbCAqLwotICBwcm90ZWN0ZWQgRXhwcmVzc2lvbiBtX3JpZ2h0OwotCi0gIC8qKgotICAgKiBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgdG8gZml4dXAgdmFyaWFibGVzIGZyb20gUU5hbWVzIHRvIHN0YWNrIGZyYW1lCi0gICAqIGluZGV4ZXMgYXQgc3R5bGVzaGVldCBidWlsZCB0aW1lLgotICAgKiBAcGFyYW0gdmFycyBMaXN0IG9mIFFOYW1lcyB0aGF0IGNvcnJlc3BvbmQgdG8gdmFyaWFibGVzLiAgVGhpcyBsaXN0Ci0gICAqIHNob3VsZCBiZSBzZWFyY2hlZCBiYWNrd2FyZHMgZm9yIHRoZSBmaXJzdCBxdWFsaWZpZWQgbmFtZSB0aGF0Ci0gICAqIGNvcnJlc3BvbmRzIHRvIHRoZSB2YXJpYWJsZSByZWZlcmVuY2UgcW5hbWUuICBUaGUgcG9zaXRpb24gb2YgdGhlCi0gICAqIFFOYW1lIGluIHRoZSB2ZWN0b3IgZnJvbSB0aGUgc3RhcnQgb2YgdGhlIHZlY3RvciB3aWxsIGJlIGl0cyBwb3NpdGlvbgotICAgKiBpbiB0aGUgc3RhY2sgZnJhbWUgKGJ1dCB2YXJpYWJsZXMgYWJvdmUgdGhlIGdsb2JhbHNUb3AgdmFsdWUgd2lsbCBuZWVkCi0gICAqIHRvIGJlIG9mZnNldCB0byB0aGUgY3VycmVudCBzdGFjayBmcmFtZSkuCi0gICAqLwotICBwdWJsaWMgdm9pZCBmaXh1cFZhcmlhYmxlcyhqYXZhLnV0aWwuVmVjdG9yIHZhcnMsIGludCBnbG9iYWxzU2l6ZSkKLSAgewotICAgIG1fcmlnaHQuZml4dXBWYXJpYWJsZXModmFycywgZ2xvYmFsc1NpemUpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgdGhpcyBleHByZXNzaW9uIG9yIGl0J3Mgc3ViZXhwcmVzc2lvbnMgY2FuIHRyYXZlcnNlIG91dHNpZGUKLSAgICogdGhlIGN1cnJlbnQgc3VidHJlZS4KLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHRyYXZlcnNhbCBvdXRzaWRlIHRoZSBjb250ZXh0IG5vZGUncyBzdWJ0cmVlIGNhbiBvY2N1ci4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGNhblRyYXZlcnNlT3V0c2lkZVN1YnRyZWUoKQotICB7Ci0KLSAgICBpZiAobnVsbCAhPSBtX3JpZ2h0ICYmIG1fcmlnaHQuY2FuVHJhdmVyc2VPdXRzaWRlU3VidHJlZSgpKQotICAgICAgcmV0dXJuIHRydWU7Ci0KLSAgICByZXR1cm4gZmFsc2U7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBleHByZXNzaW9uIG9wZXJhbmQgZm9yIHRoZSBvcGVyYXRpb24uCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSByIFRoZSBleHByZXNzaW9uIG9wZXJhbmQgdG8gd2hpY2ggdGhlIHVuYXJ5IG9wZXJhdGlvbiB3aWxsIGJlCi0gICAqICAgICAgICAgIGFwcGxpZWQuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRSaWdodChFeHByZXNzaW9uIHIpCi0gIHsKLSAgICBtX3JpZ2h0ID0gcjsKLSAgICByLmV4cHJTZXRQYXJlbnQodGhpcyk7Ci0gIH0KLQotICAvKioKLSAgICogRXhlY3V0ZSB0aGUgb3BlcmFuZCBhbmQgYXBwbHkgdGhlIHVuYXJ5IG9wZXJhdGlvbiB0byB0aGUgcmVzdWx0LgotICAgKgotICAgKgotICAgKiBAcGFyYW0geGN0eHQgVGhlIHJ1bnRpbWUgZXhlY3V0aW9uIGNvbnRleHQuCi0gICAqCi0gICAqIEByZXR1cm4gQW4gWE9iamVjdCB0aGF0IHJlcHJlc2VudHMgdGhlIHJlc3VsdCBvZiBhcHBseWluZyB0aGUgdW5hcnkKLSAgICogICAgICAgICBvcGVyYXRpb24gdG8gdGhlIGV2YWx1YXRlZCBvcGVyYW5kLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IGV4ZWN1dGUoWFBhdGhDb250ZXh0IHhjdHh0KSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICByZXR1cm4gb3BlcmF0ZShtX3JpZ2h0LmV4ZWN1dGUoeGN0eHQpKTsKLSAgfQotCi0gIC8qKgotICAgKiBBcHBseSB0aGUgb3BlcmF0aW9uIHRvIHR3byBvcGVyYW5kcywgYW5kIHJldHVybiB0aGUgcmVzdWx0LgotICAgKgotICAgKgotICAgKiBAcGFyYW0gcmlnaHQgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSBldmFsdWF0ZWQgcmlnaHQgb3BlcmFuZC4KLSAgICoKLSAgICogQHJldHVybiBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIFhPYmplY3QgdGhhdCByZXByZXNlbnRzIHRoZSByZXN1bHQgb2YgdGhlIG9wZXJhdGlvbi4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgWE9iamVjdCBvcGVyYXRlKFhPYmplY3QgcmlnaHQpCi0gICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci0KLSAgLyoqIEByZXR1cm4gdGhlIG9wZXJhbmQgb2YgdW5hcnkgb3BlcmF0aW9uLCBhcyBhbiBFeHByZXNzaW9uLgotICAgKi8KLSAgcHVibGljIEV4cHJlc3Npb24gZ2V0T3BlcmFuZCgpewotICAgIHJldHVybiBtX3JpZ2h0OwotICB9Ci0KLSAgLyoqCi0gICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoVmlzaXRhYmxlI2NhbGxWaXNpdG9ycyhFeHByZXNzaW9uT3duZXIsIFhQYXRoVmlzaXRvcikKLSAgICovCi0gIHB1YmxpYyB2b2lkIGNhbGxWaXNpdG9ycyhFeHByZXNzaW9uT3duZXIgb3duZXIsIFhQYXRoVmlzaXRvciB2aXNpdG9yKQotICB7Ci0gICAgICAgIGlmKHZpc2l0b3IudmlzaXRVbmFyeU9wZXJhdGlvbihvd25lciwgdGhpcykpCi0gICAgICAgIHsKLSAgICAgICAgICAgICAgICBtX3JpZ2h0LmNhbGxWaXNpdG9ycyh0aGlzLCB2aXNpdG9yKTsKLSAgICAgICAgfQotICB9Ci0KLQotICAvKioKLSAgICogQHNlZSBFeHByZXNzaW9uT3duZXIjZ2V0RXhwcmVzc2lvbigpCi0gICAqLwotICBwdWJsaWMgRXhwcmVzc2lvbiBnZXRFeHByZXNzaW9uKCkKLSAgewotICAgIHJldHVybiBtX3JpZ2h0OwotICB9Ci0KLSAgLyoqCi0gICAqIEBzZWUgRXhwcmVzc2lvbk93bmVyI3NldEV4cHJlc3Npb24oRXhwcmVzc2lvbikKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldEV4cHJlc3Npb24oRXhwcmVzc2lvbiBleHApCi0gIHsKLSAgICAgICAgZXhwLmV4cHJTZXRQYXJlbnQodGhpcyk7Ci0gICAgICAgIG1fcmlnaHQgPSBleHA7Ci0gIH0KLQotICAvKioKLSAgICogQHNlZSBFeHByZXNzaW9uI2RlZXBFcXVhbHMoRXhwcmVzc2lvbikKLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGRlZXBFcXVhbHMoRXhwcmVzc2lvbiBleHByKQotICB7Ci0gICAgICAgIGlmKCFpc1NhbWVDbGFzcyhleHByKSkKLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0KLSAgICAgICAgaWYoIW1fcmlnaHQuZGVlcEVxdWFscygoKFVuYXJ5T3BlcmF0aW9uKWV4cHIpLm1fcmlnaHQpKQotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLQotICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgfQotCi0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvb3BlcmF0aW9ucy9WYXJpYWJsZS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9vcGVyYXRpb25zL1ZhcmlhYmxlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDc4NTU0YjcuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9vcGVyYXRpb25zL1ZhcmlhYmxlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzOTkgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogVmFyaWFibGUuamF2YSx2IDEuMi40LjEgMjAwNS8wOS8xNCAyMToyNDozMyBqZWZmc3V0dG9yIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9wZXJhdGlvbnM7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnJlcy5YU0xNZXNzYWdlczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLlFOYW1lOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5FeHByZXNzaW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5FeHByZXNzaW9uT3duZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5YUGF0aENvbnRleHQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoVmlzaXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuYXhlcy5QYXRoQ29tcG9uZW50OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5heGVzLldhbGtlckZhY3Rvcnk7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWE5vZGVTZXQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWE9iamVjdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucmVzLlhQQVRIRXJyb3JSZXNvdXJjZXM7Ci0KLQotLyoqCi0gKiBUaGUgdmFyaWFibGUgcmVmZXJlbmNlIGV4cHJlc3Npb24gZXhlY3V0ZXIuCi0gKi8KLXB1YmxpYyBjbGFzcyBWYXJpYWJsZSBleHRlbmRzIEV4cHJlc3Npb24gaW1wbGVtZW50cyBQYXRoQ29tcG9uZW50Ci17Ci0gICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC00MzM0OTc1Mzc1NjA5Mjk3MDQ5TDsKLSAgLyoqIFRlbGwgaWYgZml4dXBWYXJpYWJsZXMgd2FzIGNhbGxlZC4KLSAgICogIEBzZXJpYWwgICAqLwotICBwcml2YXRlIGJvb2xlYW4gbV9maXhVcFdhc0NhbGxlZCA9IGZhbHNlOwotCi0gIC8qKiBUaGUgcXVhbGlmaWVkIG5hbWUgb2YgdGhlIHZhcmlhYmxlLgotICAgKiAgQHNlcmlhbCAgICovCi0gIHByb3RlY3RlZCBRTmFtZSBtX3FuYW1lOwotCi0gIC8qKgotICAgKiBUaGUgaW5kZXggb2YgdGhlIHZhcmlhYmxlLCB3aGljaCBpcyBlaXRoZXIgYW4gYWJzb2x1dGUgaW5kZXggdG8gYQotICAgKiBnbG9iYWwsIG9yLCBpZiBoaWdoZXIgdGhhbiB0aGUgZ2xvYmFscyBhcmVhLCBtdXN0IGJlIGFkanVzdGVkIGJ5IGFkZGluZwotICAgKiB0aGUgb2Zmc2V0IHRvIHRoZSBjdXJyZW50IHN0YWNrIGZyYW1lLgotICAgKi8KLSAgcHJvdGVjdGVkIGludCBtX2luZGV4OwotCi0gIC8qKgotICAgKiBTZXQgdGhlIGluZGV4IGZvciB0aGUgdmFyaWFibGUgaW50byB0aGUgc3RhY2suICBGb3IgYWR2YW5jZWQgdXNlIG9ubHkuIFlvdQotICAgKiBtdXN0IGtub3cgd2hhdCB5b3UgYXJlIGRvaW5nIHRvIHVzZSB0aGlzLgotICAgKgotICAgKiBAcGFyYW0gaW5kZXggYSBnbG9iYWwgb3IgbG9jYWwgaW5kZXguCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRJbmRleChpbnQgaW5kZXgpCi0gIHsKLSAgICAgICAgbV9pbmRleCA9IGluZGV4OwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgaW5kZXggZm9yIHRoZSB2YXJpYWJsZSBpbnRvIHRoZSBzdGFjay4gIEZvciBhZHZhbmNlZCB1c2Ugb25seS4KLSAgICoKLSAgICogQHJldHVybiBpbmRleCBhIGdsb2JhbCBvciBsb2NhbCBpbmRleC4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0SW5kZXgoKQotICB7Ci0gICAgICAgIHJldHVybiBtX2luZGV4OwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB3aGV0aGVyIG9yIG5vdCB0aGlzIGlzIGEgZ2xvYmFsIHJlZmVyZW5jZS4gIEZvciBhZHZhbmNlZCB1c2Ugb25seS4KLSAgICoKLSAgICogQHBhcmFtIGlzR2xvYmFsIHRydWUgaWYgdGhpcyBzaG91bGQgYmUgYSBnbG9iYWwgdmFyaWFibGUgcmVmZXJlbmNlLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0SXNHbG9iYWwoYm9vbGVhbiBpc0dsb2JhbCkKLSAgewotICAgICAgICBtX2lzR2xvYmFsID0gaXNHbG9iYWw7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBpbmRleCBmb3IgdGhlIHZhcmlhYmxlIGludG8gdGhlIHN0YWNrLiAgRm9yIGFkdmFuY2VkIHVzZSBvbmx5LgotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhpcyBzaG91bGQgYmUgYSBnbG9iYWwgdmFyaWFibGUgcmVmZXJlbmNlLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZ2V0R2xvYmFsKCkKLSAgewotICAgICAgICByZXR1cm4gbV9pc0dsb2JhbDsKLSAgfQotCi0KLQotCi0KLSAgcHJvdGVjdGVkIGJvb2xlYW4gbV9pc0dsb2JhbCA9IGZhbHNlOwotCi0gIC8qKgotICAgKiBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgdG8gZml4dXAgdmFyaWFibGVzIGZyb20gUU5hbWVzIHRvIHN0YWNrIGZyYW1lCi0gICAqIGluZGV4ZXMgYXQgc3R5bGVzaGVldCBidWlsZCB0aW1lLgotICAgKiBAcGFyYW0gdmFycyBMaXN0IG9mIFFOYW1lcyB0aGF0IGNvcnJlc3BvbmQgdG8gdmFyaWFibGVzLiAgVGhpcyBsaXN0Ci0gICAqIHNob3VsZCBiZSBzZWFyY2hlZCBiYWNrd2FyZHMgZm9yIHRoZSBmaXJzdCBxdWFsaWZpZWQgbmFtZSB0aGF0Ci0gICAqIGNvcnJlc3BvbmRzIHRvIHRoZSB2YXJpYWJsZSByZWZlcmVuY2UgcW5hbWUuICBUaGUgcG9zaXRpb24gb2YgdGhlCi0gICAqIFFOYW1lIGluIHRoZSB2ZWN0b3IgZnJvbSB0aGUgc3RhcnQgb2YgdGhlIHZlY3RvciB3aWxsIGJlIGl0cyBwb3NpdGlvbgotICAgKiBpbiB0aGUgc3RhY2sgZnJhbWUgKGJ1dCB2YXJpYWJsZXMgYWJvdmUgdGhlIGdsb2JhbHNUb3AgdmFsdWUgd2lsbCBuZWVkCi0gICAqIHRvIGJlIG9mZnNldCB0byB0aGUgY3VycmVudCBzdGFjayBmcmFtZSkuCi0gICAqLwotICBwdWJsaWMgdm9pZCBmaXh1cFZhcmlhYmxlcyhqYXZhLnV0aWwuVmVjdG9yIHZhcnMsIGludCBnbG9iYWxzU2l6ZSkKLSAgewotICAgIG1fZml4VXBXYXNDYWxsZWQgPSB0cnVlOwotICAgIGludCBzeiA9IHZhcnMuc2l6ZSgpOwotCi0gICAgZm9yIChpbnQgaSA9IHZhcnMuc2l6ZSgpLTE7IGkgPj0gMDsgaS0tKQotICAgIHsKLSAgICAgIFFOYW1lIHFuID0gKFFOYW1lKXZhcnMuZWxlbWVudEF0KGkpOwotICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJxbjogIitxbik7Ci0gICAgICBpZihxbi5lcXVhbHMobV9xbmFtZSkpCi0gICAgICB7Ci0KLSAgICAgICAgaWYoaSA8IGdsb2JhbHNTaXplKQotICAgICAgICB7Ci0gICAgICAgICAgbV9pc0dsb2JhbCA9IHRydWU7Ci0gICAgICAgICAgbV9pbmRleCA9IGk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICB7Ci0gICAgICAgICAgbV9pbmRleCA9IGktZ2xvYmFsc1NpemU7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm47Ci0gICAgICB9Ci0gICAgfQotCi0gICAgamF2YS5sYW5nLlN0cmluZyBtc2cgPSBYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoWFBBVEhFcnJvclJlc291cmNlcy5FUl9DT1VMRF9OT1RfRklORF9WQVIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117bV9xbmFtZS50b1N0cmluZygpfSk7Ci0KLSAgICBUcmFuc2Zvcm1lckV4Y2VwdGlvbiB0ZSA9IG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihtc2csIHRoaXMpOwotCi0gICAgdGhyb3cgbmV3IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuV3JhcHBlZFJ1bnRpbWVFeGNlcHRpb24odGUpOwotCi0gIH0KLQotCi0gIC8qKgotICAgKiBTZXQgdGhlIHF1YWxpZmllZCBuYW1lIG9mIHRoZSB2YXJpYWJsZS4KLSAgICoKLSAgICogQHBhcmFtIHFuYW1lIE11c3QgYmUgYSBub24tbnVsbCByZWZlcmVuY2UgdG8gYSBxdWFsaWZpZWQgbmFtZS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFFOYW1lKFFOYW1lIHFuYW1lKQotICB7Ci0gICAgbV9xbmFtZSA9IHFuYW1lOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgcXVhbGlmaWVkIG5hbWUgb2YgdGhlIHZhcmlhYmxlLgotICAgKgotICAgKiBAcmV0dXJuIEEgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGEgcXVhbGlmaWVkIG5hbWUuCi0gICAqLwotICBwdWJsaWMgUU5hbWUgZ2V0UU5hbWUoKQotICB7Ci0gICAgcmV0dXJuIG1fcW5hbWU7Ci0gIH0KLQotICAvKioKLSAgICogRXhlY3V0ZSBhbiBleHByZXNzaW9uIGluIHRoZSBYUGF0aCBydW50aW1lIGNvbnRleHQsIGFuZCByZXR1cm4gdGhlCi0gICAqIHJlc3VsdCBvZiB0aGUgZXhwcmVzc2lvbi4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IFRoZSBYUGF0aCBydW50aW1lIGNvbnRleHQuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHJlc3VsdCBvZiB0aGUgZXhwcmVzc2lvbiBpbiB0aGUgZm9ybSBvZiBhIDxjb2RlPlhPYmplY3Q8L2NvZGU+LgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24gaWYgYSBydW50aW1lIGV4Y2VwdGlvbgotICAgKiAgICAgICAgIG9jY3Vycy4KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IGV4ZWN1dGUoWFBhdGhDb250ZXh0IHhjdHh0KQotICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICAgICAgcmV0dXJuIGV4ZWN1dGUoeGN0eHQsIGZhbHNlKTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIERlcmVmZXJlbmNlIHRoZSB2YXJpYWJsZSwgYW5kIHJldHVybiB0aGUgcmVmZXJlbmNlIHZhbHVlLiAgTm90ZSB0aGF0IGxhenkKLSAgICogZXZhbHVhdGlvbiB3aWxsIG9jY3VyLiAgSWYgYSB2YXJpYWJsZSB3aXRoaW4gc2NvcGUgaXMgbm90IGZvdW5kLCBhIHdhcm5pbmcKLSAgICogd2lsbCBiZSBzZW50IHRvIHRoZSBlcnJvciBsaXN0ZW5lciwgYW5kIGFuIGVtcHR5IG5vZGVzZXQgd2lsbCBiZSByZXR1cm5lZC4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IFRoZSBydW50aW1lIGV4ZWN1dGlvbiBjb250ZXh0LgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBldmFsdWF0ZWQgdmFyaWFibGUsIG9yIGFuIGVtcHR5IG5vZGVzZXQgaWYgbm90IGZvdW5kLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IGV4ZWN1dGUoWFBhdGhDb250ZXh0IHhjdHh0LCBib29sZWFuIGRlc3RydWN0aXZlT0spIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLlByZWZpeFJlc29sdmVyIHhwcmVmaXhSZXNvbHZlciA9IHhjdHh0LmdldE5hbWVzcGFjZUNvbnRleHQoKTsKLQotICAgIFhPYmplY3QgcmVzdWx0OwotICAgIC8vIElzIHRoZSB2YXJpYWJsZSBmZXRjaGVkIGFsd2F5cyB0aGUgc2FtZT8KLSAgICAvLyBYT2JqZWN0IHJlc3VsdCA9IHhjdHh0LmdldFZhcmlhYmxlKG1fcW5hbWUpOwotICAgIGlmKG1fZml4VXBXYXNDYWxsZWQpCi0gICAgewotICAgICAgaWYobV9pc0dsb2JhbCkKLSAgICAgICAgcmVzdWx0ID0geGN0eHQuZ2V0VmFyU3RhY2soKS5nZXRHbG9iYWxWYXJpYWJsZSh4Y3R4dCwgbV9pbmRleCwgZGVzdHJ1Y3RpdmVPSyk7Ci0gICAgICBlbHNlCi0gICAgICAgIHJlc3VsdCA9IHhjdHh0LmdldFZhclN0YWNrKCkuZ2V0TG9jYWxWYXJpYWJsZSh4Y3R4dCwgbV9pbmRleCwgZGVzdHJ1Y3RpdmVPSyk7Ci0gICAgfQotICAgIGVsc2UgewotICAgICAgICByZXN1bHQgPSB4Y3R4dC5nZXRWYXJTdGFjaygpLmdldFZhcmlhYmxlT3JQYXJhbSh4Y3R4dCxtX3FuYW1lKTsKLSAgICB9Ci0KLSAgICAgIGlmIChudWxsID09IHJlc3VsdCkKLSAgICAgIHsKLSAgICAgICAgLy8gVGhpcyBzaG91bGQgbm93IG5ldmVyIGhhcHBlbi4uLgotICAgICAgICB3YXJuKHhjdHh0LCBYUEFUSEVycm9yUmVzb3VyY2VzLldHX0lMTEVHQUxfVkFSSUFCTEVfUkVGRVJFTkNFLAotICAgICAgICAgICAgIG5ldyBPYmplY3RbXXsgbV9xbmFtZS5nZXRMb2NhbFBhcnQoKSB9KTsgIC8vIlZhcmlhYmxlUmVmZXJlbmNlIGdpdmVuIGZvciB2YXJpYWJsZSBvdXQgIisKLSAgLy8gICAgICAobmV3IFJ1bnRpbWVFeGNlcHRpb24oKSkucHJpbnRTdGFja1RyYWNlKCk7Ci0gIC8vICAgICAgZXJyb3IoeGN0eHQsIFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfQ09VTEROT1RfR0VUX1ZBUl9OQU1FRCwKLSAgLy8gICAgICAgICAgICBuZXcgT2JqZWN0W117IG1fcW5hbWUuZ2V0TG9jYWxQYXJ0KCkgfSk7ICAvLyJDb3VsZCBub3QgZ2V0IHZhcmlhYmxlIG5hbWVkICIrdmFyTmFtZSk7Ci0KLSAgICAgICAgcmVzdWx0ID0gbmV3IFhOb2RlU2V0KHhjdHh0LmdldERUTU1hbmFnZXIoKSk7Ci0gICAgICB9Ci0KLSAgICAgIHJldHVybiByZXN1bHQ7Ci0vLyAgICB9Ci0vLyAgICBlbHNlCi0vLyAgICB7Ci0vLyAgICAgIC8vIEhhY2sgY2l0eS4uLiBiaWcgdGltZS4gIFRoaXMgaXMgbmVlZGVkIHRvIGV2YWx1YXRlIHhwYXRocyBmcm9tIGV4dGVuc2lvbnMsCi0vLyAgICAgIC8vIHBlbmRpbmcgc29tZSBicmlnaHQgbGlnaHQgZ29pbmcgb2ZmIGluIG15IGhlYWQuICBTb21lIHNvcnQgb2YgY2FsbGJhY2s/Ci0vLyAgICAgIHN5bmNocm9uaXplZCh0aGlzKQotLy8gICAgICB7Ci0vLyAgICAgICAgICAgICAgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnRlbXBsYXRlcy5FbGVtVmFyaWFibGUgdnZhcj0gZ2V0RWxlbVZhcmlhYmxlKCk7Ci0vLyAgICAgICAgICAgICAgaWYobnVsbCAhPSB2dmFyKQotLy8gICAgICAgICAgICAgIHsKLS8vICAgICAgICAgIG1faW5kZXggPSB2dmFyLmdldEluZGV4KCk7Ci0vLyAgICAgICAgICBtX2lzR2xvYmFsID0gdnZhci5nZXRJc1RvcExldmVsKCk7Ci0vLyAgICAgICAgICBtX2ZpeFVwV2FzQ2FsbGVkID0gdHJ1ZTsKLS8vICAgICAgICAgIHJldHVybiBleGVjdXRlKHhjdHh0KTsKLS8vICAgICAgICAgICAgICB9Ci0vLyAgICAgIH0KLS8vICAgICAgdGhyb3cgbmV3IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfVkFSX05PVF9SRVNPTFZBQkxFLCBuZXcgT2JqZWN0W117bV9xbmFtZS50b1N0cmluZygpfSkpOyAvLyJWYXJpYWJsZSBub3QgcmVzb2x2YWJsZTogIittX3FuYW1lKTsKLS8vICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIFhTTFQgRWxlbVZhcmlhYmxlIHRoYXQgdGhpcyBzdWItZXhwcmVzc2lvbiByZWZlcmVuY2VzLiAgSW4gb3JkZXIgZm9yCi0gICAqIHRoaXMgdG8gd29yaywgdGhlIFNvdXJjZUxvY2F0b3IgbXVzdCBiZSB0aGUgb3duaW5nIEVsZW1UZW1wbGF0ZUVsZW1lbnQuCi0gICAqIEByZXR1cm4gVGhlIGRlcmVmZXJlbmNlIHRvIHRoZSBFbGVtVmFyaWFibGUsIG9yIG51bGwgaWYgbm90IGZvdW5kLgotICAgKi8KLSAgLy8gSjJTRSBkb2VzIG5vdCBzdXBwb3J0IFhhbGFuIGludGVycHJldGl2ZQotICAvKgotICBwdWJsaWMgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnRlbXBsYXRlcy5FbGVtVmFyaWFibGUgZ2V0RWxlbVZhcmlhYmxlKCkKLSAgewotCi0gICAgLy8gR2V0IHRoZSBjdXJyZW50IEVsZW1UZW1wbGF0ZUVsZW1lbnQsIGFuZCB0aGVuIHdhbGsgYmFja3dhcmRzIGluCi0gICAgLy8gZG9jdW1lbnQgb3JkZXIsIHNlYXJjaGluZwotICAgIC8vIGZvciBhbiB4c2w6cGFyYW0gZWxlbWVudCBvciB4c2w6dmFyaWFibGUgZWxlbWVudCB0aGF0IG1hdGNoZXMgb3VyCi0gICAgLy8gcW5hbWUuICBJZiB3ZSByZWFjaCB0aGUgdG9wIGxldmVsLCB1c2UgdGhlIFN0eWxlc2hlZXRSb290J3MgY29tcG9zZWQKLSAgICAvLyBsaXN0IG9mIHRvcCBsZXZlbCB2YXJpYWJsZXMgYW5kIHBhcmFtZXRlcnMuCi0KLSAgICBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwudGVtcGxhdGVzLkVsZW1WYXJpYWJsZSB2dmFyID0gbnVsbDsKLSAgICBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuRXhwcmVzc2lvbk5vZGUgb3duZXIgPSBnZXRFeHByZXNzaW9uT3duZXIoKTsKLQotICAgIGlmIChudWxsICE9IG93bmVyICYmIG93bmVyIGluc3RhbmNlb2YgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnRlbXBsYXRlcy5FbGVtVGVtcGxhdGVFbGVtZW50KQotICAgIHsKLQotICAgICAgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnRlbXBsYXRlcy5FbGVtVGVtcGxhdGVFbGVtZW50IHByZXYgPQotICAgICAgICAoY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnRlbXBsYXRlcy5FbGVtVGVtcGxhdGVFbGVtZW50KSBvd25lcjsKLQotICAgICAgaWYgKCEocHJldiBpbnN0YW5jZW9mIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC50ZW1wbGF0ZXMuU3R5bGVzaGVldCkpCi0gICAgICB7Ci0gICAgICAgIHdoaWxlICggcHJldiAhPSBudWxsICYmICEocHJldi5nZXRQYXJlbnROb2RlKCkgaW5zdGFuY2VvZiBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwudGVtcGxhdGVzLlN0eWxlc2hlZXQpICkKLSAgICAgICAgewotICAgICAgICAgIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC50ZW1wbGF0ZXMuRWxlbVRlbXBsYXRlRWxlbWVudCBzYXZlZHByZXYgPSBwcmV2OwotCi0gICAgICAgICAgd2hpbGUgKG51bGwgIT0gKHByZXYgPSBwcmV2LmdldFByZXZpb3VzU2libGluZ0VsZW0oKSkpCi0gICAgICAgICAgewotICAgICAgICAgICAgaWYocHJldiBpbnN0YW5jZW9mIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC50ZW1wbGF0ZXMuRWxlbVZhcmlhYmxlKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICB2dmFyID0gKGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC50ZW1wbGF0ZXMuRWxlbVZhcmlhYmxlKSBwcmV2OwotCi0gICAgICAgICAgICAgIGlmICh2dmFyLmdldE5hbWUoKS5lcXVhbHMobV9xbmFtZSkpCi0gICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gdnZhcjsKLSAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICB2dmFyID0gbnVsbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICB9Ci0gICAgICAgICAgcHJldiA9IHNhdmVkcHJldi5nZXRQYXJlbnRFbGVtKCk7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICAgIGlmIChwcmV2ICE9IG51bGwpCi0gICAgICAgIHZ2YXIgPSBwcmV2LmdldFN0eWxlc2hlZXRSb290KCkuZ2V0VmFyaWFibGVPclBhcmFtQ29tcG9zZWQobV9xbmFtZSk7Ci0gICAgfQotICAgIHJldHVybiB2dmFyOwotCi0gIH0KLSAgKi8KLSAgLyoqCi0gICAqIFRlbGwgaWYgdGhpcyBleHByZXNzaW9uIHJldHVybnMgYSBzdGFibGUgbnVtYmVyIHRoYXQgd2lsbCBub3QgY2hhbmdlIGR1cmluZwotICAgKiBpdGVyYXRpb25zIHdpdGhpbiB0aGUgZXhwcmVzc2lvbi4gIFRoaXMgaXMgdXNlZCB0byBkZXRlcm1pbmUgaWYgYSBwcm94aW1pdHkKLSAgICogcG9zaXRpb24gcHJlZGljYXRlIGNhbiBpbmRpY2F0ZSB0aGF0IG5vIG1vcmUgc2VhcmNoaW5nIGhhcyB0byBvY2N1ci4KLSAgICoKLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHRoZSBleHByZXNzaW9uIHJlcHJlc2VudHMgYSBzdGFibGUgbnVtYmVyLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNTdGFibGVOdW1iZXIoKQotICB7Ci0gICAgcmV0dXJuIHRydWU7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBhbmFseXNpcyBiaXRzIGZvciB0aGlzIHdhbGtlciwgYXMgZGVmaW5lZCBpbiB0aGUgV2Fsa2VyRmFjdG9yeS4KLSAgICogQHJldHVybiBPbmUgb2YgV2Fsa2VyRmFjdG9yeSNCSVRfREVTQ0VOREFOVCwgZXRjLgotICAgKi8KLSAgcHVibGljIGludCBnZXRBbmFseXNpc0JpdHMoKQotICB7Ci0KLSAgICAvLyBKMlNFIGRvZXMgbm90IHN1cHBvcnQgWGFsYW4gaW50ZXJwcmV0aXZlCi0gICAgLyoKLSAgICAgICAgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnRlbXBsYXRlcy5FbGVtVmFyaWFibGUgdnZhciA9IGdldEVsZW1WYXJpYWJsZSgpOwotICAgICAgICBpZihudWxsICE9IHZ2YXIpCi0gICAgICAgIHsKLSAgICAgICAgICAgICAgICBYUGF0aCB4cGF0aCA9IHZ2YXIuZ2V0U2VsZWN0KCk7Ci0gICAgICAgICAgICAgICAgaWYobnVsbCAhPSB4cGF0aCkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBFeHByZXNzaW9uIGV4cHIgPSB4cGF0aC5nZXRFeHByZXNzaW9uKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZihudWxsICE9IGV4cHIgJiYgZXhwciBpbnN0YW5jZW9mIFBhdGhDb21wb25lbnQpCi0gICAgICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoKFBhdGhDb21wb25lbnQpZXhwcikuZ2V0QW5hbHlzaXNCaXRzKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgKi8KLQotICAgIHJldHVybiBXYWxrZXJGYWN0b3J5LkJJVF9GSUxURVI7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5YUGF0aFZpc2l0YWJsZSNjYWxsVmlzaXRvcnMoRXhwcmVzc2lvbk93bmVyLCBYUGF0aFZpc2l0b3IpCi0gICAqLwotICBwdWJsaWMgdm9pZCBjYWxsVmlzaXRvcnMoRXhwcmVzc2lvbk93bmVyIG93bmVyLCBYUGF0aFZpc2l0b3IgdmlzaXRvcikKLSAgewotICAgICAgICB2aXNpdG9yLnZpc2l0VmFyaWFibGVSZWYob3duZXIsIHRoaXMpOwotICB9Ci0gIC8qKgotICAgKiBAc2VlIEV4cHJlc3Npb24jZGVlcEVxdWFscyhFeHByZXNzaW9uKQotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZGVlcEVxdWFscyhFeHByZXNzaW9uIGV4cHIpCi0gIHsKLSAgICAgICAgaWYoIWlzU2FtZUNsYXNzKGV4cHIpKQotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLQotICAgICAgICBpZighbV9xbmFtZS5lcXVhbHMoKChWYXJpYWJsZSlleHByKS5tX3FuYW1lKSkKLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0KLSAgICAvLyBKMlNFIGRvZXMgbm90IHN1cHBvcnQgWGFsYW4gaW50ZXJwcmV0aXZlCi0gICAgLyoKLSAgICAgICAgLy8gV2UgaGF2ZSB0byBtYWtlIHN1cmUgdGhhdCB0aGUgcW5hbWUgcmVhbGx5IHJlZmVyZW5jZXMKLSAgICAgICAgLy8gdGhlIHNhbWUgdmFyaWFibGUgZWxlbWVudC4KLSAgICBpZihnZXRFbGVtVmFyaWFibGUoKSAhPSAoKFZhcmlhYmxlKWV4cHIpLmdldEVsZW1WYXJpYWJsZSgpKQotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICovCi0KLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gIH0KLQotICBzdGF0aWMgZmluYWwgamF2YS5sYW5nLlN0cmluZyBQU1VFRE9WQVJOQU1FU1BBQ0UgPSAiaHR0cDovL3htbC5hcGFjaGUub3JnL3hhbGFuL3BzdWVkb3ZhciI7Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgdGhpcyBpcyBhIHBzdWVkbyB2YXJpYWJsZSByZWZlcmVuY2UsIGRlY2xhcmVkIGJ5IFhhbGFuIGluc3RlYWQKLSAgICogb2YgYnkgdGhlIHVzZXIuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBpc1BzdWVkb1ZhclJlZigpCi0gIHsKLSAgICAgICAgamF2YS5sYW5nLlN0cmluZyBucyA9IG1fcW5hbWUuZ2V0TmFtZXNwYWNlVVJJKCk7Ci0gICAgICAgIGlmKChudWxsICE9IG5zKSAmJiBucy5lcXVhbHMoUFNVRURPVkFSTkFNRVNQQUNFKSkKLSAgICAgICAgewotICAgICAgICAgICAgICAgIGlmKG1fcW5hbWUuZ2V0TG9jYWxOYW1lKCkuc3RhcnRzV2l0aCgiIyIpKQotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICB9Ci0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9vcGVyYXRpb25zL1ZhcmlhYmxlU2FmZUFic1JlZi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9vcGVyYXRpb25zL1ZhcmlhYmxlU2FmZUFic1JlZi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkODU5NzhkLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvb3BlcmF0aW9ucy9WYXJpYWJsZVNhZmVBYnNSZWYuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDc1ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFZhcmlhYmxlU2FmZUFic1JlZi5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE0IDIxOjMxOjQ1IGplZmZzdXR0b3IgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub3BlcmF0aW9uczsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTU1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLkV4cHJlc3Npb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoQ29udGV4dDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YTm9kZVNldDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YT2JqZWN0OwotCi0KLS8qKgotICogVGhpcyBpcyBhICJzbWFydCIgdmFyaWFibGUgcmVmZXJlbmNlIHRoYXQgaXMgdXNlZCBpbiBzaXR1YXRpb25zIHdoZXJlCi0gKiBhbiBhYnNvbHV0ZSBwYXRoIGlzIG9wdGltaXplZCBpbnRvIGEgdmFyaWFibGUgcmVmZXJlbmNlLCBidXQgbWF5Ci0gKiBiZSB1c2VkIGluIHNvbWUgc2l0dWF0aW9ucyB3aGVyZSB0aGUgZG9jdW1lbnQgY29udGV4dCBtYXkgaGF2ZSBjaGFuZ2VkLgotICogRm9yIGluc3RhbmNlLCBpbiBzZWxlY3Q9ImRvY3VtZW50KGRvYy9AaHJlZikvL25hbWVbLy9zYWxhcnkgJmd0OyA3MjUwXSIsIHRoZQotICogcm9vdCBpbiB0aGUgcHJlZGljYXRlIHdpbGwgYmUgZGlmZmVyZW50IGZvciBlYWNoIG5vZGUgaW4gdGhlIHNldC4gIFdoaWxlCi0gKiB0aGlzIGlzIGVhc3kgdG8gZGV0ZWN0IHN0YXRpY2FsbHkgaW4gdGhpcyBjYXNlLCBpbiBvdGhlciBjYXNlcyBzdGF0aWMKLSAqIGRldGVjdGlvbiB3b3VsZCBiZSB2ZXJ5IGhhcmQgb3IgaW1wb3NzaWJsZS4gIFNvLCB0aGlzIGNsYXNzIGRvZXMgYSBkeW5hbWljIGNoZWNrCi0gKiB0byBtYWtlIHN1cmUgdGhlIGRvY3VtZW50IGNvbnRleHQgb2YgdGhlIHJlZmVyZW5jZWQgdmFyaWFibGUgaXMgdGhlIHNhbWUgYXMKLSAqIHRoZSBjdXJyZW50IGRvY3VtZW50IGNvbnRleHQsIGFuZCwgaWYgaXQgaXMgbm90LCBleGVjdXRlIHRoZSByZWZlcmVuY2VkIHZhcmlhYmxlJ3MKLSAqIGV4cHJlc3Npb24gd2l0aCB0aGUgY3VycmVudCBjb250ZXh0IGluc3RlYWQuCi0gKi8KLXB1YmxpYyBjbGFzcyBWYXJpYWJsZVNhZmVBYnNSZWYgZXh0ZW5kcyBWYXJpYWJsZQotewotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtOTE3NDY2MTk5MDgxOTk2NzQ1Mkw7Ci0KLSAgLyoqCi0gICAqIERlcmVmZXJlbmNlIHRoZSB2YXJpYWJsZSwgYW5kIHJldHVybiB0aGUgcmVmZXJlbmNlIHZhbHVlLiAgTm90ZSB0aGF0IGxhenkKLSAgICogZXZhbHVhdGlvbiB3aWxsIG9jY3VyLiAgSWYgYSB2YXJpYWJsZSB3aXRoaW4gc2NvcGUgaXMgbm90IGZvdW5kLCBhIHdhcm5pbmcKLSAgICogd2lsbCBiZSBzZW50IHRvIHRoZSBlcnJvciBsaXN0ZW5lciwgYW5kIGFuIGVtcHR5IG5vZGVzZXQgd2lsbCBiZSByZXR1cm5lZC4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IFRoZSBydW50aW1lIGV4ZWN1dGlvbiBjb250ZXh0LgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBldmFsdWF0ZWQgdmFyaWFibGUsIG9yIGFuIGVtcHR5IG5vZGVzZXQgaWYgbm90IGZvdW5kLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IGV4ZWN1dGUoWFBhdGhDb250ZXh0IHhjdHh0LCBib29sZWFuIGRlc3RydWN0aXZlT0spCi0gICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICAgICAgWE5vZGVTZXQgeG5zID0gKFhOb2RlU2V0KXN1cGVyLmV4ZWN1dGUoeGN0eHQsIGRlc3RydWN0aXZlT0spOwotICAgICAgICBEVE1NYW5hZ2VyIGR0bU1nciA9IHhjdHh0LmdldERUTU1hbmFnZXIoKTsKLSAgICAgICAgaW50IGNvbnRleHQgPSB4Y3R4dC5nZXRDb250ZXh0Tm9kZSgpOwotICAgICAgICBpZihkdG1NZ3IuZ2V0RFRNKHhucy5nZXRSb290KCkpLmdldERvY3VtZW50KCkgIT0KLSAgICAgICAgICAgZHRtTWdyLmdldERUTShjb250ZXh0KS5nZXREb2N1bWVudCgpKQotICAgICAgICB7Ci0gICAgICAgICAgICAgICAgRXhwcmVzc2lvbiBleHByID0gKEV4cHJlc3Npb24peG5zLmdldENvbnRhaW5lZEl0ZXIoKTsKLSAgICAgICAgICAgICAgICB4bnMgPSAoWE5vZGVTZXQpZXhwci5hc0l0ZXJhdG9yKHhjdHh0LCBjb250ZXh0KTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4geG5zOwotICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvb3BlcmF0aW9ucy9wYWNrYWdlLmh0bWwgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL29wZXJhdGlvbnMvcGFja2FnZS5odG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyZmU4OTI0Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvb3BlcmF0aW9ucy9wYWNrYWdlLmh0bWwKKysrIC9kZXYvbnVsbApAQCAtMSwyOCArMCwwIEBACi08IS0tCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotLS0+Ci08IS0tCi0gKiBDb3B5cmlnaHQgMjAwMC0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLS0tPgotPCEtLSAkSWQ6IHBhY2thZ2UuaHRtbCx2IDEuMS4yLjEgMjAwNS8wOC8wMSAwMTozMDowNyBqZWZmc3V0dG9yIEV4cCAkIC0tPgotPGh0bWw+Ci0gIDx0aXRsZT5YYWxhbiBYUGF0aCBvcGVyYXRpb25zLjwvdGl0bGU+Ci0gIDxib2R5PgotICAgIDxwPlN1cHBvcnQgZm9yIFhQYXRoIG9wZXJhdGlvbnMsIHN1Y2ggYXMgKywgLSwgc3RyaW5nKCksIGV0Yy48cD4KLSA8L2JvZHk+Ci08L2h0bWw+Ci0KLQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9wYWNrYWdlLmh0bWwgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL3BhY2thZ2UuaHRtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNTRlMWMxNS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL3BhY2thZ2UuaHRtbAorKysgL2Rldi9udWxsCkBAIC0xLDI5ICswLDAgQEAKLTwhLS0KLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0tLT4KLTwhLS0KLSAqIENvcHlyaWdodCAyMDAwLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotLS0+Ci08IS0tICRJZDogcGFja2FnZS5odG1sLHYgMS4xLjIuMSAyMDA1LzA4LzAxIDAxOjMwOjE0IGplZmZzdXR0b3IgRXhwICQgLS0+Ci08aHRtbD4KLSAgPHRpdGxlPlhQYXRoIHN1cHBvcnQgUGFja2FnZS48L3RpdGxlPgotICA8Ym9keT4KLSAgICA8cD5JbXBsZW1lbnRhdGlvbiBvZiBYUGF0aDsgZm9yIHRoZSBtb3N0IHBhcnQsIG9ubHkgY2xhc3NlcyBtZWFudCBmb3IgcHVibGljIHVzZSBhcmUKLSAgICBmb3VuZCBhdCB0aGlzIHJvb3QgbGV2ZWwgb2YgdGhlIFhQYXRoIHBhY2thZ2VzLjxwPgotIDwvYm9keT4KLTwvaHRtbD4KLQotCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL3BhdHRlcm5zL0NvbnRleHRNYXRjaFN0ZXBQYXR0ZXJuLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL3BhdHRlcm5zL0NvbnRleHRNYXRjaFN0ZXBQYXR0ZXJuLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGY1N2Y3MjIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9wYXR0ZXJucy9Db250ZXh0TWF0Y2hTdGVwUGF0dGVybi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTgxICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IENvbnRleHRNYXRjaFN0ZXBQYXR0ZXJuLmphdmEsdiAxLjIuNC4yIDIwMDUvMDkvMTUgMDA6MjE6MTUgamVmZnN1dHRvciBFeHAgJAotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5wYXR0ZXJuczsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkF4aXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTUF4aXNUcmF2ZXJzZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNRmlsdGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5YUGF0aENvbnRleHQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmF4ZXMuV2Fsa2VyRmFjdG9yeTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YT2JqZWN0OwotLyoqCi0gKiBTcGVjaWFsIGNvbnRleHQgbm9kZSBwYXR0ZXJuIG1hdGNoZXIuCi0gKi8KLXB1YmxpYyBjbGFzcyBDb250ZXh0TWF0Y2hTdGVwUGF0dGVybiBleHRlbmRzIFN0ZXBQYXR0ZXJuCi17Ci0gICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC0xODg4MDkyNzc5MzEzMjExOTQyTDsKLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgQ29udGV4dE1hdGNoU3RlcFBhdHRlcm4uCi0gICAqCi0gICAqLwotICBwdWJsaWMgQ29udGV4dE1hdGNoU3RlcFBhdHRlcm4oaW50IGF4aXMsIGludCBwYXhpcykKLSAgewotICAgIHN1cGVyKERUTUZpbHRlci5TSE9XX0FMTCwgYXhpcywgcGF4aXMpOwotICB9Ci0KLSAgLyoqCi0gICAqIEV4ZWN1dGUgdGhpcyBwYXR0ZXJuIHN0ZXAsIGluY2x1ZGluZyBwcmVkaWNhdGVzLgotICAgKgotICAgKgotICAgKiBAcGFyYW0geGN0eHQgWFBhdGggcnVudGltZSBjb250ZXh0LgotICAgKgotICAgKiBAcmV0dXJuIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfTk9ERVRFU1R9LAotICAgKiAgICAgICAgIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfTk9ORX0sCi0gICAqICAgICAgICAge0BsaW5rIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5wYXR0ZXJucy5Ob2RlVGVzdCNTQ09SRV9OU1dJTER9LAotICAgKiAgICAgICAgIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfUU5BTUV9LCBvcgotICAgKiAgICAgICAgIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfT1RIRVJ9LgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IGV4ZWN1dGUoWFBhdGhDb250ZXh0IHhjdHh0KQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmICh4Y3R4dC5nZXRJdGVyYXRvclJvb3QoKSA9PSB4Y3R4dC5nZXRDdXJyZW50Tm9kZSgpKQotICAgICAgcmV0dXJuIGdldFN0YXRpY1Njb3JlKCk7Ci0gICAgZWxzZQotICAgICAgcmV0dXJuIHRoaXMuU0NPUkVfTk9ORTsKLSAgfQotCi0gIC8qKgotICAgKiBFeGVjdXRlIHRoZSBtYXRjaCBwYXR0ZXJuIHN0ZXAgcmVsYXRpdmUgdG8gYW5vdGhlciBzdGVwLgotICAgKgotICAgKgotICAgKiBAcGFyYW0geGN0eHQgVGhlIFhQYXRoIHJ1bnRpbWUgY29udGV4dC4KLSAgICogTkVFRFNET0MgQHBhcmFtIHByZXZTdGVwCi0gICAqCi0gICAqIEByZXR1cm4ge0BsaW5rIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5wYXR0ZXJucy5Ob2RlVGVzdCNTQ09SRV9OT0RFVEVTVH0sCi0gICAqICAgICAgICAge0BsaW5rIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5wYXR0ZXJucy5Ob2RlVGVzdCNTQ09SRV9OT05FfSwKLSAgICogICAgICAgICB7QGxpbmsgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLnBhdHRlcm5zLk5vZGVUZXN0I1NDT1JFX05TV0lMRH0sCi0gICAqICAgICAgICAge0BsaW5rIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5wYXR0ZXJucy5Ob2RlVGVzdCNTQ09SRV9RTkFNRX0sIG9yCi0gICAqICAgICAgICAge0BsaW5rIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5wYXR0ZXJucy5Ob2RlVGVzdCNTQ09SRV9PVEhFUn0uCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFhPYmplY3QgZXhlY3V0ZVJlbGF0aXZlUGF0aFBhdHRlcm4oCi0gICAgICAgICAgWFBhdGhDb250ZXh0IHhjdHh0LCBTdGVwUGF0dGVybiBwcmV2U3RlcCkKLSAgICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIFhPYmplY3Qgc2NvcmUgPSBOb2RlVGVzdC5TQ09SRV9OT05FOwotICAgIGludCBjb250ZXh0ID0geGN0eHQuZ2V0Q3VycmVudE5vZGUoKTsKLSAgICBEVE0gZHRtID0geGN0eHQuZ2V0RFRNKGNvbnRleHQpOwotCi0gICAgaWYgKG51bGwgIT0gZHRtKQotICAgIHsKLSAgICAgIGludCBwcmVkQ29udGV4dCA9IHhjdHh0LmdldEN1cnJlbnROb2RlKCk7Ci0gICAgICBEVE1BeGlzVHJhdmVyc2VyIHRyYXZlcnNlcjsKLQotICAgICAgaW50IGF4aXMgPSBtX2F4aXM7Ci0KLSAgICAgIGJvb2xlYW4gbmVlZFRvVHJhdmVyc2VBdHRycyA9IFdhbGtlckZhY3RvcnkuaXNEb3dud2FyZEF4aXNPZk1hbnkoYXhpcyk7Ci0gICAgICBib29sZWFuIGl0ZXJSb290SXNBdHRyID0gKGR0bS5nZXROb2RlVHlwZSh4Y3R4dC5nZXRJdGVyYXRvclJvb3QoKSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID09IERUTS5BVFRSSUJVVEVfTk9ERSk7Ci0KLSAgICAgIGlmKChBeGlzLlBSRUNFRElORyA9PSBheGlzKSAmJiBpdGVyUm9vdElzQXR0cikKLSAgICAgIHsKLSAgICAgICAgYXhpcyA9IEF4aXMuUFJFQ0VESU5HQU5EQU5DRVNUT1I7Ci0gICAgICB9Ci0KLSAgICAgIHRyYXZlcnNlciA9IGR0bS5nZXRBeGlzVHJhdmVyc2VyKGF4aXMpOwotCi0gICAgICBmb3IgKGludCByZWxhdGl2ZSA9IHRyYXZlcnNlci5maXJzdChjb250ZXh0KTsgRFRNLk5VTEwgIT0gcmVsYXRpdmU7Ci0gICAgICAgICAgICAgIHJlbGF0aXZlID0gdHJhdmVyc2VyLm5leHQoY29udGV4dCwgcmVsYXRpdmUpKQotICAgICAgewotICAgICAgICB0cnkKLSAgICAgICAgewotICAgICAgICAgIHhjdHh0LnB1c2hDdXJyZW50Tm9kZShyZWxhdGl2ZSk7Ci0KLSAgICAgICAgICBzY29yZSA9IGV4ZWN1dGUoeGN0eHQpOwotCi0gICAgICAgICAgaWYgKHNjb3JlICE9IE5vZGVUZXN0LlNDT1JFX05PTkUpCi0gICAgICAgICAgewotICAgICAgICAgICAgICAvL3Njb3JlID0gZXhlY3V0ZVByZWRpY2F0ZXMoIHhjdHh0LCBwcmV2U3RlcCwgU0NPUkVfT1RIRVIsCi0gICAgICAgICAgICAgIC8vICAgICAgIHByZWRDb250ZXh0LCByZWxhdGl2ZSk7Ci0gICAgICAgICAgICAgIGlmIChleGVjdXRlUHJlZGljYXRlcyh4Y3R4dCwgZHRtLCBjb250ZXh0KSkKLSAgICAgICAgICAgICAgICAgIHJldHVybiBzY29yZTsKLQotICAgICAgICAgICAgICBzY29yZSA9IE5vZGVUZXN0LlNDT1JFX05PTkU7Ci0gICAgICAgICAgfQotCi0gICAgICAgICAgaWYobmVlZFRvVHJhdmVyc2VBdHRycyAmJiBpdGVyUm9vdElzQXR0cgotICAgICAgICAgICAgICYmIChEVE0uRUxFTUVOVF9OT0RFID09IGR0bS5nZXROb2RlVHlwZShyZWxhdGl2ZSkpKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGludCB4YXhpcyA9IEF4aXMuQVRUUklCVVRFOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAyOyBpKyspCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIERUTUF4aXNUcmF2ZXJzZXIgYXRyYXZlcnNlciA9IGR0bS5nZXRBeGlzVHJhdmVyc2VyKHhheGlzKTsKLQotICAgICAgICAgICAgICBmb3IgKGludCBhcmVsYXRpdmUgPSBhdHJhdmVyc2VyLmZpcnN0KHJlbGF0aXZlKTsKLSAgICAgICAgICAgICAgICAgICAgICBEVE0uTlVMTCAhPSBhcmVsYXRpdmU7Ci0gICAgICAgICAgICAgICAgICAgICAgYXJlbGF0aXZlID0gYXRyYXZlcnNlci5uZXh0KHJlbGF0aXZlLCBhcmVsYXRpdmUpKQotICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgdHJ5Ci0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgeGN0eHQucHVzaEN1cnJlbnROb2RlKGFyZWxhdGl2ZSk7Ci0KLSAgICAgICAgICAgICAgICAgIHNjb3JlID0gZXhlY3V0ZSh4Y3R4dCk7Ci0KLSAgICAgICAgICAgICAgICAgIGlmIChzY29yZSAhPSBOb2RlVGVzdC5TQ09SRV9OT05FKQotICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgIC8vc2NvcmUgPSBleGVjdXRlUHJlZGljYXRlcyggeGN0eHQsIHByZXZTdGVwLCBTQ09SRV9PVEhFUiwKLSAgICAgICAgICAgICAgICAgICAgICAvLyAgICAgICBwcmVkQ29udGV4dCwgYXJlbGF0aXZlKTsKLQotICAgICAgICAgICAgICAgICAgICBpZiAoc2NvcmUgIT0gTm9kZVRlc3QuU0NPUkVfTk9ORSkKLSAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2NvcmU7Ci0gICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGZpbmFsbHkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICB4Y3R4dC5wb3BDdXJyZW50Tm9kZSgpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICB4YXhpcyA9IEF4aXMuTkFNRVNQQUNFOwotICAgICAgICAgICAgfQotICAgICAgICAgIH0KLQotICAgICAgICB9Ci0gICAgICAgIGZpbmFsbHkKLSAgICAgICAgewotICAgICAgICAgIHhjdHh0LnBvcEN1cnJlbnROb2RlKCk7Ci0gICAgICAgIH0KLSAgICAgIH0KLQotICAgIH0KLQotICAgIHJldHVybiBzY29yZTsKLSAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL3BhdHRlcm5zL0Z1bmN0aW9uUGF0dGVybi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9wYXR0ZXJucy9GdW5jdGlvblBhdHRlcm4uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggM2QwMjAyMy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL3BhdHRlcm5zL0Z1bmN0aW9uUGF0dGVybi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjUwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IEZ1bmN0aW9uUGF0dGVybi5qYXZhLHYgMS4yLjQuMiAyMDA1LzA5LzE1IDAwOjIxOjE1IGplZmZzdXR0b3IgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucGF0dGVybnM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE07Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNSXRlcmF0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLkV4cHJlc3Npb247Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLkV4cHJlc3Npb25Pd25lcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuWFBhdGhDb250ZXh0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5YUGF0aFZpc2l0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWE51bWJlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YT2JqZWN0OwotCi0vKioKLSAqIE1hdGNoIHBhdHRlcm4gc3RlcCB0aGF0IGNvbnRhaW5zIGEgZnVuY3Rpb24uCi0gKiBAeHNsLnVzYWdlIGFkdmFuY2VkCi0gKi8KLXB1YmxpYyBjbGFzcyBGdW5jdGlvblBhdHRlcm4gZXh0ZW5kcyBTdGVwUGF0dGVybgotewotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNTQyNjc5MzQxMzA5MTIwOTk0NEw7Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhIEZ1bmN0aW9uUGF0dGVybiBmcm9tIGEKLSAgICoge0BsaW5rIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5mdW5jdGlvbnMuRnVuY3Rpb24gZXhwcmVzc2lvbn0uCi0gICAqCi0gICAqIE5FRURTRE9DIEBwYXJhbSBleHByCi0gICAqLwotICBwdWJsaWMgRnVuY3Rpb25QYXR0ZXJuKEV4cHJlc3Npb24gZXhwciwgaW50IGF4aXMsIGludCBwcmVkYXhpcykKLSAgewotCi0gICAgc3VwZXIoMCwgbnVsbCwgbnVsbCwgYXhpcywgcHJlZGF4aXMpOwotCi0gICAgbV9mdW5jdGlvbkV4cHIgPSBleHByOwotICB9Ci0KLSAgLyoqCi0gICAqIFN0YXRpYyBjYWxjIG9mIG1hdGNoIHNjb3JlLgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgY2FsY1Njb3JlKCkKLSAgewotCi0gICAgbV9zY29yZSA9IFNDT1JFX09USEVSOwotCi0gICAgaWYgKG51bGwgPT0gbV90YXJnZXRTdHJpbmcpCi0gICAgICBjYWxjVGFyZ2V0U3RyaW5nKCk7Ci0gIH0KLQotICAvKioKLSAgICogU2hvdWxkIGJlIGEge0BsaW5rIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5mdW5jdGlvbnMuRnVuY3Rpb24gZXhwcmVzc2lvbn0uCi0gICAqICBAc2VyaWFsCi0gICAqLwotICBFeHByZXNzaW9uIG1fZnVuY3Rpb25FeHByOwotCi0gIC8qKgotICAgKiBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgdG8gZml4dXAgdmFyaWFibGVzIGZyb20gUU5hbWVzIHRvIHN0YWNrIGZyYW1lCi0gICAqIGluZGV4ZXMgYXQgc3R5bGVzaGVldCBidWlsZCB0aW1lLgotICAgKiBAcGFyYW0gdmFycyBMaXN0IG9mIFFOYW1lcyB0aGF0IGNvcnJlc3BvbmQgdG8gdmFyaWFibGVzLiAgVGhpcyBsaXN0Ci0gICAqIHNob3VsZCBiZSBzZWFyY2hlZCBiYWNrd2FyZHMgZm9yIHRoZSBmaXJzdCBxdWFsaWZpZWQgbmFtZSB0aGF0Ci0gICAqIGNvcnJlc3BvbmRzIHRvIHRoZSB2YXJpYWJsZSByZWZlcmVuY2UgcW5hbWUuICBUaGUgcG9zaXRpb24gb2YgdGhlCi0gICAqIFFOYW1lIGluIHRoZSB2ZWN0b3IgZnJvbSB0aGUgc3RhcnQgb2YgdGhlIHZlY3RvciB3aWxsIGJlIGl0cyBwb3NpdGlvbgotICAgKiBpbiB0aGUgc3RhY2sgZnJhbWUgKGJ1dCB2YXJpYWJsZXMgYWJvdmUgdGhlIGdsb2JhbHNUb3AgdmFsdWUgd2lsbCBuZWVkCi0gICAqIHRvIGJlIG9mZnNldCB0byB0aGUgY3VycmVudCBzdGFjayBmcmFtZSkuCi0gICAqLwotICBwdWJsaWMgdm9pZCBmaXh1cFZhcmlhYmxlcyhqYXZhLnV0aWwuVmVjdG9yIHZhcnMsIGludCBnbG9iYWxzU2l6ZSkKLSAgewotICAgIHN1cGVyLmZpeHVwVmFyaWFibGVzKHZhcnMsIGdsb2JhbHNTaXplKTsKLSAgICBtX2Z1bmN0aW9uRXhwci5maXh1cFZhcmlhYmxlcyh2YXJzLCBnbG9iYWxzU2l6ZSk7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBUZXN0IGEgbm9kZSB0byBzZWUgaWYgaXQgbWF0Y2hlcyB0aGUgZ2l2ZW4gbm9kZSB0ZXN0LgotICAgKgotICAgKiBAcGFyYW0geGN0eHQgWFBhdGggcnVudGltZSBjb250ZXh0LgotICAgKgotICAgKiBAcmV0dXJuIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfTk9ERVRFU1R9LAotICAgKiAgICAgICAgIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfTk9ORX0sCi0gICAqICAgICAgICAge0BsaW5rIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5wYXR0ZXJucy5Ob2RlVGVzdCNTQ09SRV9OU1dJTER9LAotICAgKiAgICAgICAgIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfUU5BTUV9LCBvcgotICAgKiAgICAgICAgIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfT1RIRVJ9LgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IGV4ZWN1dGUoWFBhdGhDb250ZXh0IHhjdHh0LCBpbnQgY29udGV4dCkKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBEVE1JdGVyYXRvciBubCA9IG1fZnVuY3Rpb25FeHByLmFzSXRlcmF0b3IoeGN0eHQsIGNvbnRleHQpOwotICAgIFhOdW1iZXIgc2NvcmUgPSBTQ09SRV9OT05FOwotCi0gICAgaWYgKG51bGwgIT0gbmwpCi0gICAgewotICAgICAgaW50IG47Ci0KLSAgICAgIHdoaWxlIChEVE0uTlVMTCAhPSAobiA9IG5sLm5leHROb2RlKCkpKQotICAgICAgewotICAgICAgICBzY29yZSA9IChuID09IGNvbnRleHQpID8gU0NPUkVfT1RIRVIgOiBTQ09SRV9OT05FOwotCi0gICAgICAgIGlmIChzY29yZSA9PSBTQ09SRV9PVEhFUikKLSAgICAgICAgewotICAgICAgICAgIGNvbnRleHQgPSBuOwotCi0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIH0KLSAgICAgIH0KLQotICAgICAgLy8gbmwuZGV0YWNoKCk7Ci0gICAgfQotICAgIG5sLmRldGFjaCgpOwotCi0gICAgcmV0dXJuIHNjb3JlOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlc3QgYSBub2RlIHRvIHNlZSBpZiBpdCBtYXRjaGVzIHRoZSBnaXZlbiBub2RlIHRlc3QuCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBYUGF0aCBydW50aW1lIGNvbnRleHQuCi0gICAqCi0gICAqIEByZXR1cm4ge0BsaW5rIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5wYXR0ZXJucy5Ob2RlVGVzdCNTQ09SRV9OT0RFVEVTVH0sCi0gICAqICAgICAgICAge0BsaW5rIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5wYXR0ZXJucy5Ob2RlVGVzdCNTQ09SRV9OT05FfSwKLSAgICogICAgICAgICB7QGxpbmsgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLnBhdHRlcm5zLk5vZGVUZXN0I1NDT1JFX05TV0lMRH0sCi0gICAqICAgICAgICAge0BsaW5rIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5wYXR0ZXJucy5Ob2RlVGVzdCNTQ09SRV9RTkFNRX0sIG9yCi0gICAqICAgICAgICAge0BsaW5rIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5wYXR0ZXJucy5Ob2RlVGVzdCNTQ09SRV9PVEhFUn0uCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFhPYmplY3QgZXhlY3V0ZShYUGF0aENvbnRleHQgeGN0eHQsIGludCBjb250ZXh0LAotICAgICAgICAgICAgICAgICAgICAgICAgIERUTSBkdG0sIGludCBleHBUeXBlKQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIERUTUl0ZXJhdG9yIG5sID0gbV9mdW5jdGlvbkV4cHIuYXNJdGVyYXRvcih4Y3R4dCwgY29udGV4dCk7Ci0gICAgWE51bWJlciBzY29yZSA9IFNDT1JFX05PTkU7Ci0KLSAgICBpZiAobnVsbCAhPSBubCkKLSAgICB7Ci0gICAgICBpbnQgbjsKLQotICAgICAgd2hpbGUgKERUTS5OVUxMICE9IChuID0gbmwubmV4dE5vZGUoKSkpCi0gICAgICB7Ci0gICAgICAgIHNjb3JlID0gKG4gPT0gY29udGV4dCkgPyBTQ09SRV9PVEhFUiA6IFNDT1JFX05PTkU7Ci0KLSAgICAgICAgaWYgKHNjb3JlID09IFNDT1JFX09USEVSKQotICAgICAgICB7Ci0gICAgICAgICAgY29udGV4dCA9IG47Ci0KLSAgICAgICAgICBicmVhazsKLSAgICAgICAgfQotICAgICAgfQotCi0gICAgICBubC5kZXRhY2goKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gc2NvcmU7Ci0gIH0KLQotICAvKioKLSAgICogVGVzdCBhIG5vZGUgdG8gc2VlIGlmIGl0IG1hdGNoZXMgdGhlIGdpdmVuIG5vZGUgdGVzdC4KLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IFhQYXRoIHJ1bnRpbWUgY29udGV4dC4KLSAgICoKLSAgICogQHJldHVybiB7QGxpbmsgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLnBhdHRlcm5zLk5vZGVUZXN0I1NDT1JFX05PREVURVNUfSwKLSAgICogICAgICAgICB7QGxpbmsgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLnBhdHRlcm5zLk5vZGVUZXN0I1NDT1JFX05PTkV9LAotICAgKiAgICAgICAgIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfTlNXSUxEfSwKLSAgICogICAgICAgICB7QGxpbmsgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLnBhdHRlcm5zLk5vZGVUZXN0I1NDT1JFX1FOQU1FfSwgb3IKLSAgICogICAgICAgICB7QGxpbmsgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLnBhdHRlcm5zLk5vZGVUZXN0I1NDT1JFX09USEVSfS4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBleGVjdXRlKFhQYXRoQ29udGV4dCB4Y3R4dCkKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpbnQgY29udGV4dCA9IHhjdHh0LmdldEN1cnJlbnROb2RlKCk7Ci0gICAgRFRNSXRlcmF0b3IgbmwgPSBtX2Z1bmN0aW9uRXhwci5hc0l0ZXJhdG9yKHhjdHh0LCBjb250ZXh0KTsKLSAgICBYTnVtYmVyIHNjb3JlID0gU0NPUkVfTk9ORTsKLQotICAgIGlmIChudWxsICE9IG5sKQotICAgIHsKLSAgICAgIGludCBuOwotCi0gICAgICB3aGlsZSAoRFRNLk5VTEwgIT0gKG4gPSBubC5uZXh0Tm9kZSgpKSkKLSAgICAgIHsKLSAgICAgICAgc2NvcmUgPSAobiA9PSBjb250ZXh0KSA/IFNDT1JFX09USEVSIDogU0NPUkVfTk9ORTsKLQotICAgICAgICBpZiAoc2NvcmUgPT0gU0NPUkVfT1RIRVIpCi0gICAgICAgIHsKLSAgICAgICAgICBjb250ZXh0ID0gbjsKLQotICAgICAgICAgIGJyZWFrOwotICAgICAgICB9Ci0gICAgICB9Ci0KLSAgICAgIG5sLmRldGFjaCgpOwotICAgIH0KLQotICAgIHJldHVybiBzY29yZTsKLSAgfQotCi0gIGNsYXNzIEZ1bmN0aW9uT3duZXIgaW1wbGVtZW50cyBFeHByZXNzaW9uT3duZXIKLSAgewotICAgIC8qKgotICAgICAqIEBzZWUgRXhwcmVzc2lvbk93bmVyI2dldEV4cHJlc3Npb24oKQotICAgICAqLwotICAgIHB1YmxpYyBFeHByZXNzaW9uIGdldEV4cHJlc3Npb24oKQotICAgIHsKLSAgICAgIHJldHVybiBtX2Z1bmN0aW9uRXhwcjsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIEBzZWUgRXhwcmVzc2lvbk93bmVyI3NldEV4cHJlc3Npb24oRXhwcmVzc2lvbikKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRFeHByZXNzaW9uKEV4cHJlc3Npb24gZXhwKQotICAgIHsKLSAgICAgICAgZXhwLmV4cHJTZXRQYXJlbnQoRnVuY3Rpb25QYXR0ZXJuLnRoaXMpOwotICAgICAgICBtX2Z1bmN0aW9uRXhwciA9IGV4cDsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogQ2FsbCB0aGUgdmlzaXRvciBmb3IgdGhlIGZ1bmN0aW9uLgotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgY2FsbFN1YnRyZWVWaXNpdG9ycyhYUGF0aFZpc2l0b3IgdmlzaXRvcikKLSAgewotICAgIG1fZnVuY3Rpb25FeHByLmNhbGxWaXNpdG9ycyhuZXcgRnVuY3Rpb25Pd25lcigpLCB2aXNpdG9yKTsKLSAgICBzdXBlci5jYWxsU3VidHJlZVZpc2l0b3JzKHZpc2l0b3IpOwotICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvcGF0dGVybnMvTm9kZVRlc3QuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvcGF0dGVybnMvTm9kZVRlc3QuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNWJiOTVmYi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL3BhdHRlcm5zL05vZGVUZXN0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw2OTQgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogTm9kZVRlc3QuamF2YSx2IDEuMi40LjIgMjAwNS8wOS8xNSAwMDoyMToxNCBqZWZmc3V0dG9yIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLnBhdHRlcm5zOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uRFRNOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTUZpbHRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuRXhwcmVzc2lvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuRXhwcmVzc2lvbk93bmVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5YUGF0aDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuWFBhdGhDb250ZXh0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5YUGF0aFZpc2l0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWE51bWJlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YT2JqZWN0OwotCi0vKioKLSAqIFRoaXMgaXMgdGhlIGJhc2ljIG5vZGUgdGVzdCBjbGFzcyBmb3IgYm90aCBtYXRjaCBwYXR0ZXJucyBhbmQgbG9jYXRpb24gcGF0aAotICogc3RlcHMuCi0gKiBAeHNsLnVzYWdlIGFkdmFuY2VkCi0gKi8KLXB1YmxpYyBjbGFzcyBOb2RlVGVzdCBleHRlbmRzIEV4cHJlc3Npb24KLXsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTU3MzY3MjE4NjY3NDc5MDYxODJMOwotCi0gIC8qKgotICAgKiBUaGUgbmFtZXNwYWNlIG9yIGxvY2FsIG5hbWUgZm9yIG5vZGUgdGVzdHMgd2l0aCBhIHdpbGRjYXJkLgotICAgKiAgQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aCNOVC1OYW1lVGVzdCI+dGhlIFhQYXRoIE5hbWVUZXN0IHByb2R1Y3Rpb24uPC9hPgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0lMRCA9ICIqIjsKLQotICAvKioKLSAgICogVGhlIFVSTCB0byBwYXNzIHRvIHRoZSBOb2RlI3N1cHBvcnRzIG1ldGhvZCwgdG8gc2VlIGlmIHRoZQotICAgKiBET00gaGFzIGFscmVhZHkgYmVlbiBzdHJpcHBlZCBvZiB3aGl0ZXNwYWNlIG5vZGVzLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1VQUE9SVFNfUFJFX1NUUklQUElORyA9Ci0gICAgImh0dHA6Ly94bWwuYXBhY2hlLm9yZy94cGF0aC9mZWF0dXJlcy93aGl0ZXNwYWNlLXByZS1zdHJpcHBpbmciOwotCi0gIC8qKgotICAgKiBUaGlzIGF0dHJpYnV0ZSBkZXRlcm1pbmVzIHdoaWNoIG5vZGUgdHlwZXMgYXJlIGFjY2VwdGVkLgotICAgKiBAc2VyaWFsCi0gICAqLwotICBwcm90ZWN0ZWQgaW50IG1fd2hhdFRvU2hvdzsKLQotICAvKioKLSAgICogU3BlY2lhbCBiaXRtYXAgZm9yIG1hdGNoIHBhdHRlcm5zIHN0YXJ0aW5nIHdpdGggYSBmdW5jdGlvbi4KLSAgICogTWFrZSBzdXJlIHRoaXMgZG9lcyBub3QgY29uZmxpY3Qgd2l0aCB7QGxpbmsgb3JnLnczYy5kb20udHJhdmVyc2FsLk5vZGVGaWx0ZXJ9LgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0hPV19CWUZVTkNUSU9OID0gMHgwMDAxMDAwMDsKLQotICAvKioKLSAgICogVGhpcyBhdHRyaWJ1dGUgZGV0ZXJtaW5lcyB3aGljaCBub2RlIHR5cGVzIGFyZSBhY2NlcHRlZC4KLSAgICogVGhlc2UgY29uc3RhbnRzIGFyZSBkZWZpbmVkIGluIHRoZSB7QGxpbmsgb3JnLnczYy5kb20udHJhdmVyc2FsLk5vZGVGaWx0ZXJ9Ci0gICAqIGludGVyZmFjZS4KLSAgICoKLSAgICogQHJldHVybiBiaXRzZXQgbWFpbmx5IGRlZmluZWQgaW4ge0BsaW5rIG9yZy53M2MuZG9tLnRyYXZlcnNhbC5Ob2RlRmlsdGVyfS4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0V2hhdFRvU2hvdygpCi0gIHsKLSAgICByZXR1cm4gbV93aGF0VG9TaG93OwotICB9Ci0KLSAgLyoqCi0gICAqIFRoaXMgYXR0cmlidXRlIGRldGVybWluZXMgd2hpY2ggbm9kZSB0eXBlcyBhcmUgYWNjZXB0ZWQuCi0gICAqIFRoZXNlIGNvbnN0YW50cyBhcmUgZGVmaW5lZCBpbiB0aGUge0BsaW5rIG9yZy53M2MuZG9tLnRyYXZlcnNhbC5Ob2RlRmlsdGVyfQotICAgKiBpbnRlcmZhY2UuCi0gICAqCi0gICAqIEBwYXJhbSB3aGF0IGJpdHNldCBtYWlubHkgZGVmaW5lZCBpbiB7QGxpbmsgb3JnLnczYy5kb20udHJhdmVyc2FsLk5vZGVGaWx0ZXJ9LgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0V2hhdFRvU2hvdyhpbnQgd2hhdCkKLSAgewotICAgIG1fd2hhdFRvU2hvdyA9IHdoYXQ7Ci0gIH0KLQotICAvKioKLSAgICogVGhlIG5hbWVzcGFjZSB0byBiZSB0ZXN0ZWQgZm9yLCB3aGljaCBtYXkgYmUgbnVsbC4KLSAgICogIEBzZXJpYWwKLSAgICovCi0gIFN0cmluZyBtX25hbWVzcGFjZTsKLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBuYW1lc3BhY2UgdG8gYmUgdGVzdGVkLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBuYW1lc3BhY2UgdG8gYmUgdGVzdGVkIGZvciwgb3Ige0BsaW5rICNXSUxEfSwgb3IgbnVsbC4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZXNwYWNlKCkKLSAgewotICAgIHJldHVybiBtX25hbWVzcGFjZTsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIG5hbWVzcGFjZSB0byBiZSB0ZXN0ZWQuCi0gICAqCi0gICAqIEBwYXJhbSBucyBUaGUgbmFtZXNwYWNlIHRvIGJlIHRlc3RlZCBmb3IsIG9yIHtAbGluayAjV0lMRH0sIG9yIG51bGwuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXROYW1lc3BhY2UoU3RyaW5nIG5zKQotICB7Ci0gICAgbV9uYW1lc3BhY2UgPSBuczsKLSAgfQotCi0gIC8qKgotICAgKiBUaGUgbG9jYWwgbmFtZSB0byBiZSB0ZXN0ZWQgZm9yLgotICAgKiAgQHNlcmlhbAotICAgKi8KLSAgcHJvdGVjdGVkIFN0cmluZyBtX25hbWU7Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgbG9jYWwgbmFtZSB0byBiZSB0ZXN0ZWQuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIGxvY2FsIG5hbWUgdG8gYmUgdGVzdGVkLCBvciB7QGxpbmsgI1dJTER9LCBvciBhbiBlbXB0eSBzdHJpbmcuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldExvY2FsTmFtZSgpCi0gIHsKLSAgICByZXR1cm4gKG51bGwgPT0gbV9uYW1lKSA/ICIiIDogbV9uYW1lOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgbG9jYWwgbmFtZSB0byBiZSB0ZXN0ZWQuCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lIHRoZSBsb2NhbCBuYW1lIHRvIGJlIHRlc3RlZCwgb3Ige0BsaW5rICNXSUxEfSwgb3IgYW4gZW1wdHkgc3RyaW5nLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0TG9jYWxOYW1lKFN0cmluZyBuYW1lKQotICB7Ci0gICAgbV9uYW1lID0gbmFtZTsKLSAgfQotCi0gIC8qKgotICAgKiBTdGF0aWNhbGx5IGNhbGN1bGF0ZWQgc2NvcmUgZm9yIHRoaXMgdGVzdC4gIE9uZSBvZgotICAgKiAge0BsaW5rICNTQ09SRV9OT0RFVEVTVH0sCi0gICAqICB7QGxpbmsgI1NDT1JFX05PTkV9LAotICAgKiAge0BsaW5rICNTQ09SRV9OU1dJTER9LAotICAgKiAge0BsaW5rICNTQ09SRV9RTkFNRX0sIG9yCi0gICAqICB7QGxpbmsgI1NDT1JFX09USEVSfS4KLSAgICogIEBzZXJpYWwKLSAgICovCi0gIFhOdW1iZXIgbV9zY29yZTsKLQotICAvKioKLSAgICogVGhlIG1hdGNoIHNjb3JlIGlmIHRoZSBwYXR0ZXJuIGNvbnNpc3RzIG9mIGp1c3QgYSBOb2RlVGVzdC4KLSAgICogIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNjb25mbGljdCI+WFNMVCBTcGVjaWZpY2F0aW9uIC0gNS41IENvbmZsaWN0IFJlc29sdXRpb24gZm9yIFRlbXBsYXRlIFJ1bGVzPC9hPgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBYTnVtYmVyIFNDT1JFX05PREVURVNUID0KLSAgICBuZXcgWE51bWJlcihYUGF0aC5NQVRDSF9TQ09SRV9OT0RFVEVTVCk7Ci0KLSAgLyoqCi0gICAqIFRoZSBtYXRjaCBzY29yZSBpZiB0aGUgcGF0dGVybiBwYXR0ZXJuIGhhcyB0aGUgZm9ybSBOQ05hbWU6Ki4KLSAgICogIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNjb25mbGljdCI+WFNMVCBTcGVjaWZpY2F0aW9uIC0gNS41IENvbmZsaWN0IFJlc29sdXRpb24gZm9yIFRlbXBsYXRlIFJ1bGVzPC9hPgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBYTnVtYmVyIFNDT1JFX05TV0lMRCA9Ci0gICAgbmV3IFhOdW1iZXIoWFBhdGguTUFUQ0hfU0NPUkVfTlNXSUxEKTsKLQotICAvKioKLSAgICogVGhlIG1hdGNoIHNjb3JlIGlmIHRoZSBwYXR0ZXJuIGhhcyB0aGUgZm9ybQotICAgKiBvZiBhIFFOYW1lIG9wdGlvbmFsbHkgcHJlY2VkZWQgYnkgYW4gQCBjaGFyYWN0ZXIuCi0gICAqICBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjY29uZmxpY3QiPlhTTFQgU3BlY2lmaWNhdGlvbiAtIDUuNSBDb25mbGljdCBSZXNvbHV0aW9uIGZvciBUZW1wbGF0ZSBSdWxlczwvYT4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgWE51bWJlciBTQ09SRV9RTkFNRSA9Ci0gICAgbmV3IFhOdW1iZXIoWFBhdGguTUFUQ0hfU0NPUkVfUU5BTUUpOwotCi0gIC8qKgotICAgKiBUaGUgbWF0Y2ggc2NvcmUgaWYgdGhlIHBhdHRlcm4gY29uc2lzdHMgb2Ygc29tZXRoaW5nCi0gICAqIG90aGVyIHRoYW4ganVzdCBhIE5vZGVUZXN0IG9yIGp1c3QgYSBxbmFtZS4KLSAgICogIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNjb25mbGljdCI+WFNMVCBTcGVjaWZpY2F0aW9uIC0gNS41IENvbmZsaWN0IFJlc29sdXRpb24gZm9yIFRlbXBsYXRlIFJ1bGVzPC9hPgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBYTnVtYmVyIFNDT1JFX09USEVSID0KLSAgICBuZXcgWE51bWJlcihYUGF0aC5NQVRDSF9TQ09SRV9PVEhFUik7Ci0KLSAgLyoqCi0gICAqIFRoZSBtYXRjaCBzY29yZSBpZiBubyBtYXRjaCBpcyBtYWRlLgotICAgKiAgQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2NvbmZsaWN0Ij5YU0xUIFNwZWNpZmljYXRpb24gLSA1LjUgQ29uZmxpY3QgUmVzb2x1dGlvbiBmb3IgVGVtcGxhdGUgUnVsZXM8L2E+Ci0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFhOdW1iZXIgU0NPUkVfTk9ORSA9Ci0gICAgbmV3IFhOdW1iZXIoWFBhdGguTUFUQ0hfU0NPUkVfTk9ORSk7Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhbiBOb2RlVGVzdCB0aGF0IHRlc3RzIGZvciBuYW1lc3BhY2VzIGFuZCBub2RlIG5hbWVzLgotICAgKgotICAgKgotICAgKiBAcGFyYW0gd2hhdFRvU2hvdyBCaXQgc2V0IGRlZmluZWQgbWFpbmx5IGJ5IHtAbGluayBvcmcudzNjLmRvbS50cmF2ZXJzYWwuTm9kZUZpbHRlcn0uCi0gICAqIEBwYXJhbSBuYW1lc3BhY2UgVGhlIG5hbWVzcGFjZSB0byBiZSB0ZXN0ZWQuCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBsb2NhbCBuYW1lIHRvIGJlIHRlc3RlZC4KLSAgICovCi0gIHB1YmxpYyBOb2RlVGVzdChpbnQgd2hhdFRvU2hvdywgU3RyaW5nIG5hbWVzcGFjZSwgU3RyaW5nIG5hbWUpCi0gIHsKLSAgICBpbml0Tm9kZVRlc3Qod2hhdFRvU2hvdywgbmFtZXNwYWNlLCBuYW1lKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYW4gTm9kZVRlc3QgdGhhdCBkb2Vzbid0IHRlc3QgZm9yIG5vZGUgbmFtZXMuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSB3aGF0VG9TaG93IEJpdCBzZXQgZGVmaW5lZCBtYWlubHkgYnkge0BsaW5rIG9yZy53M2MuZG9tLnRyYXZlcnNhbC5Ob2RlRmlsdGVyfS4KLSAgICovCi0gIHB1YmxpYyBOb2RlVGVzdChpbnQgd2hhdFRvU2hvdykKLSAgewotICAgIGluaXROb2RlVGVzdCh3aGF0VG9TaG93KTsKLSAgfQotCi0gIC8qKgotICAgKiBAc2VlIEV4cHJlc3Npb24jZGVlcEVxdWFscyhFeHByZXNzaW9uKQotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZGVlcEVxdWFscyhFeHByZXNzaW9uIGV4cHIpCi0gIHsKLSAgICAgICAgaWYoIWlzU2FtZUNsYXNzKGV4cHIpKQotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLQotICAgICAgICBOb2RlVGVzdCBudCA9IChOb2RlVGVzdClleHByOwotCi0gICAgICAgIGlmKG51bGwgIT0gbnQubV9uYW1lKQotICAgICAgICB7Ci0gICAgICAgICAgICAgICAgaWYobnVsbCA9PSBtX25hbWUpCi0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICAgICAgZWxzZSBpZighbnQubV9uYW1lLmVxdWFscyhtX25hbWUpKQotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYobnVsbCAhPSBtX25hbWUpCi0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotCi0gICAgICAgIGlmKG51bGwgIT0gbnQubV9uYW1lc3BhY2UpCi0gICAgICAgIHsKLSAgICAgICAgICAgICAgICBpZihudWxsID09IG1fbmFtZXNwYWNlKQotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgICAgIGVsc2UgaWYoIW50Lm1fbmFtZXNwYWNlLmVxdWFscyhtX25hbWVzcGFjZSkpCi0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZihudWxsICE9IG1fbmFtZXNwYWNlKQotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLQotICAgICAgICBpZihtX3doYXRUb1Nob3cgIT0gbnQubV93aGF0VG9TaG93KQotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLQotICAgICAgICBpZihtX2lzVG90YWxseVdpbGQgIT0gbnQubV9pc1RvdGFsbHlXaWxkKQotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLQotICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgfQotCi0gIC8qKgotICAgKiBOdWxsIGFyZ3VtZW50IGNvbnN0cnVjdG9yLgotICAgKi8KLSAgcHVibGljIE5vZGVUZXN0KCl7fQotCi0gIC8qKgotICAgKiBJbml0aWFsaXplIHRoaXMgbm9kZSB0ZXN0IGJ5IHNldHRpbmcgdGhlIHdoYXRUb1Nob3cgcHJvcGVydHksIGFuZAotICAgKiBjYWxjdWxhdGluZyB0aGUgc2NvcmUgdGhhdCB0aGlzIHRlc3Qgd2lsbCByZXR1cm4gaWYgYSB0ZXN0IHN1Y2NlZWRzLgotICAgKgotICAgKgotICAgKiBAcGFyYW0gd2hhdFRvU2hvdyBCaXQgc2V0IGRlZmluZWQgbWFpbmx5IGJ5IHtAbGluayBvcmcudzNjLmRvbS50cmF2ZXJzYWwuTm9kZUZpbHRlcn0uCi0gICAqLwotICBwdWJsaWMgdm9pZCBpbml0Tm9kZVRlc3QoaW50IHdoYXRUb1Nob3cpCi0gIHsKLQotICAgIG1fd2hhdFRvU2hvdyA9IHdoYXRUb1Nob3c7Ci0KLSAgICBjYWxjU2NvcmUoKTsKLSAgfQotCi0gIC8qKgotICAgKiBJbml0aWFsaXplIHRoaXMgbm9kZSB0ZXN0IGJ5IHNldHRpbmcgdGhlIHdoYXRUb1Nob3cgcHJvcGVydHkgYW5kIHRoZQotICAgKiBuYW1lc3BhY2UgYW5kIGxvY2FsIG5hbWUsIGFuZAotICAgKiBjYWxjdWxhdGluZyB0aGUgc2NvcmUgdGhhdCB0aGlzIHRlc3Qgd2lsbCByZXR1cm4gaWYgYSB0ZXN0IHN1Y2NlZWRzLgotICAgKgotICAgKgotICAgKiBAcGFyYW0gd2hhdFRvU2hvdyBCaXQgc2V0IGRlZmluZWQgbWFpbmx5IGJ5IHtAbGluayBvcmcudzNjLmRvbS50cmF2ZXJzYWwuTm9kZUZpbHRlcn0uCi0gICAqIEBwYXJhbSBuYW1lc3BhY2UgVGhlIG5hbWVzcGFjZSB0byBiZSB0ZXN0ZWQuCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBsb2NhbCBuYW1lIHRvIGJlIHRlc3RlZC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGluaXROb2RlVGVzdChpbnQgd2hhdFRvU2hvdywgU3RyaW5nIG5hbWVzcGFjZSwgU3RyaW5nIG5hbWUpCi0gIHsKLQotICAgIG1fd2hhdFRvU2hvdyA9IHdoYXRUb1Nob3c7Ci0gICAgbV9uYW1lc3BhY2UgPSBuYW1lc3BhY2U7Ci0gICAgbV9uYW1lID0gbmFtZTsKLQotICAgIGNhbGNTY29yZSgpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRydWUgaWYgdGhpcyB0ZXN0IGhhcyBhIG51bGwgbmFtZXNwYWNlIGFuZCBhIGxvY2FsIG5hbWUgb2Yge0BsaW5rICNXSUxEfS4KLSAgICogIEBzZXJpYWwKLSAgICovCi0gIHByaXZhdGUgYm9vbGVhbiBtX2lzVG90YWxseVdpbGQ7Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgc3RhdGljIHNjb3JlIGZvciB0aGlzIG5vZGUgdGVzdC4KLSAgICogQHJldHVybiBTaG91bGQgYmUgb25lIG9mIHRoZSBTQ09SRV9YWFggY29uc3RhbnRzLgotICAgKi8KLSAgcHVibGljIFhOdW1iZXIgZ2V0U3RhdGljU2NvcmUoKQotICB7Ci0gICAgcmV0dXJuIG1fc2NvcmU7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBzdGF0aWMgc2NvcmUgZm9yIHRoaXMgbm9kZSB0ZXN0LgotICAgKiBAcGFyYW0gc2NvcmUgU2hvdWxkIGJlIG9uZSBvZiB0aGUgU0NPUkVfWFhYIGNvbnN0YW50cy4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFN0YXRpY1Njb3JlKFhOdW1iZXIgc2NvcmUpCi0gIHsKLSAgICBtX3Njb3JlID0gc2NvcmU7Ci0gIH0KLQotICAvKioKLSAgICogU3RhdGljIGNhbGMgb2YgbWF0Y2ggc2NvcmUuCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBjYWxjU2NvcmUoKQotICB7Ci0KLSAgICBpZiAoKG1fbmFtZXNwYWNlID09IG51bGwpICYmIChtX25hbWUgPT0gbnVsbCkpCi0gICAgICBtX3Njb3JlID0gU0NPUkVfTk9ERVRFU1Q7Ci0gICAgZWxzZSBpZiAoKChtX25hbWVzcGFjZSA9PSBXSUxEKSB8fCAobV9uYW1lc3BhY2UgPT0gbnVsbCkpCi0gICAgICAgICAgICAgJiYgKG1fbmFtZSA9PSBXSUxEKSkKLSAgICAgIG1fc2NvcmUgPSBTQ09SRV9OT0RFVEVTVDsKLSAgICBlbHNlIGlmICgobV9uYW1lc3BhY2UgIT0gV0lMRCkgJiYgKG1fbmFtZSA9PSBXSUxEKSkKLSAgICAgIG1fc2NvcmUgPSBTQ09SRV9OU1dJTEQ7Ci0gICAgZWxzZQotICAgICAgbV9zY29yZSA9IFNDT1JFX1FOQU1FOwotCi0gICAgbV9pc1RvdGFsbHlXaWxkID0gKG1fbmFtZXNwYWNlID09IG51bGwgJiYgbV9uYW1lID09IFdJTEQpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgc2NvcmUgdGhhdCB0aGlzIHRlc3Qgd2lsbCByZXR1cm4gaWYgYSB0ZXN0IHN1Y2NlZWRzLgotICAgKgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBzY29yZSB0aGF0IHRoaXMgdGVzdCB3aWxsIHJldHVybiBpZiBhIHRlc3Qgc3VjY2VlZHMuCi0gICAqLwotICBwdWJsaWMgZG91YmxlIGdldERlZmF1bHRTY29yZSgpCi0gIHsKLSAgICByZXR1cm4gbV9zY29yZS5udW0oKTsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIHdoYXQgbm9kZSB0eXBlIHRvIHRlc3QsIGlmIG5vdCBEVE1GaWx0ZXIuU0hPV19BTEwuCi0gICAqCi0gICAqIEBwYXJhbSB3aGF0VG9TaG93IEJpdCBzZXQgZGVmaW5lZCBtYWlubHkgYnkKLSAgICogICAgICAgIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1GaWx0ZXJ9LgotICAgKiBAcmV0dXJuIHRoZSBub2RlIHR5cGUgZm9yIHRoZSB3aGF0VG9TaG93LiAgU2luY2Ugd2hhdFRvU2hvdyBjYW4gc3BlY2lmeQotICAgKiAgICAgICAgIG11bHRpcGxlIHR5cGVzLCBpdCB3aWxsIHJldHVybiB0aGUgZmlyc3QgYml0IHRlc3RlZCB0aGF0IGlzIG9uLAotICAgKiAgICAgICAgIHNvIHRoZSBjYWxsZXIgb2YgdGhpcyBmdW5jdGlvbiBzaG91bGQgdGFrZSBjYXJlIHRoYXQgdGhpcyBpcwotICAgKiAgICAgICAgIHRoZSBmdW5jdGlvbiB0aGV5IHJlYWxseSB3YW50IHRvIGNhbGwuICBJZiBub25lIG9mIHRoZSBrbm93biBiaXRzCi0gICAqICAgICAgICAgYXJlIHNldCwgdGhpcyBmdW5jdGlvbiB3aWxsIHJldHVybiB6ZXJvLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBpbnQgZ2V0Tm9kZVR5cGVUZXN0KGludCB3aGF0VG9TaG93KQotICB7Ci0gICAgLy8gJVJFVklFVyUgSXMgdGhlcmUgYSBiZXR0ZXIgd2F5PwotICAgIGlmICgwICE9ICh3aGF0VG9TaG93ICYgRFRNRmlsdGVyLlNIT1dfRUxFTUVOVCkpCi0gICAgICByZXR1cm4gRFRNLkVMRU1FTlRfTk9ERTsKLQotICAgIGlmICgwICE9ICh3aGF0VG9TaG93ICYgRFRNRmlsdGVyLlNIT1dfQVRUUklCVVRFKSkKLSAgICAgIHJldHVybiBEVE0uQVRUUklCVVRFX05PREU7Ci0KLSAgICBpZiAoMCAhPSAod2hhdFRvU2hvdyAmIERUTUZpbHRlci5TSE9XX1RFWFQpKQotICAgICAgcmV0dXJuIERUTS5URVhUX05PREU7Ci0KLSAgICBpZiAoMCAhPSAod2hhdFRvU2hvdyAmIERUTUZpbHRlci5TSE9XX0RPQ1VNRU5UKSkKLSAgICAgIHJldHVybiBEVE0uRE9DVU1FTlRfTk9ERTsKLQotICAgIGlmICgwICE9ICh3aGF0VG9TaG93ICYgRFRNRmlsdGVyLlNIT1dfRE9DVU1FTlRfRlJBR01FTlQpKQotICAgICAgcmV0dXJuIERUTS5ET0NVTUVOVF9GUkFHTUVOVF9OT0RFOwotCi0gICAgaWYgKDAgIT0gKHdoYXRUb1Nob3cgJiBEVE1GaWx0ZXIuU0hPV19OQU1FU1BBQ0UpKQotICAgICAgcmV0dXJuIERUTS5OQU1FU1BBQ0VfTk9ERTsKLQotICAgIGlmICgwICE9ICh3aGF0VG9TaG93ICYgRFRNRmlsdGVyLlNIT1dfQ09NTUVOVCkpCi0gICAgICByZXR1cm4gRFRNLkNPTU1FTlRfTk9ERTsKLQotICAgIGlmICgwICE9ICh3aGF0VG9TaG93ICYgRFRNRmlsdGVyLlNIT1dfUFJPQ0VTU0lOR19JTlNUUlVDVElPTikpCi0gICAgICByZXR1cm4gRFRNLlBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERTsKLQotICAgIGlmICgwICE9ICh3aGF0VG9TaG93ICYgRFRNRmlsdGVyLlNIT1dfRE9DVU1FTlRfVFlQRSkpCi0gICAgICByZXR1cm4gRFRNLkRPQ1VNRU5UX1RZUEVfTk9ERTsKLQotICAgIGlmICgwICE9ICh3aGF0VG9TaG93ICYgRFRNRmlsdGVyLlNIT1dfRU5USVRZKSkKLSAgICAgIHJldHVybiBEVE0uRU5USVRZX05PREU7Ci0KLSAgICBpZiAoMCAhPSAod2hhdFRvU2hvdyAmIERUTUZpbHRlci5TSE9XX0VOVElUWV9SRUZFUkVOQ0UpKQotICAgICAgcmV0dXJuIERUTS5FTlRJVFlfUkVGRVJFTkNFX05PREU7Ci0KLSAgICBpZiAoMCAhPSAod2hhdFRvU2hvdyAmIERUTUZpbHRlci5TSE9XX05PVEFUSU9OKSkKLSAgICAgIHJldHVybiBEVE0uTk9UQVRJT05fTk9ERTsKLQotICAgIGlmICgwICE9ICh3aGF0VG9TaG93ICYgRFRNRmlsdGVyLlNIT1dfQ0RBVEFfU0VDVElPTikpCi0gICAgICByZXR1cm4gRFRNLkNEQVRBX1NFQ1RJT05fTk9ERTsKLQotCi0gICAgcmV0dXJuIDA7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBEbyBhIGRpYWdub3N0aWNzIGR1bXAgb2YgYSB3aGF0VG9TaG93IGJpdCBzZXQuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSB3aGF0VG9TaG93IEJpdCBzZXQgZGVmaW5lZCBtYWlubHkgYnkKLSAgICogICAgICAgIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1GaWx0ZXJ9LgotICAgKi8KLSAgcHVibGljIHN0YXRpYyB2b2lkIGRlYnVnV2hhdFRvU2hvdyhpbnQgd2hhdFRvU2hvdykKLSAgewotCi0gICAgamF2YS51dGlsLlZlY3RvciB2ID0gbmV3IGphdmEudXRpbC5WZWN0b3IoKTsKLQotICAgIGlmICgwICE9ICh3aGF0VG9TaG93ICYgRFRNRmlsdGVyLlNIT1dfQVRUUklCVVRFKSkKLSAgICAgIHYuYWRkRWxlbWVudCgiU0hPV19BVFRSSUJVVEUiKTsKLQotICAgIGlmICgwICE9ICh3aGF0VG9TaG93ICYgRFRNRmlsdGVyLlNIT1dfTkFNRVNQQUNFKSkKLSAgICAgIHYuYWRkRWxlbWVudCgiU0hPV19OQU1FU1BBQ0UiKTsKLQotICAgIGlmICgwICE9ICh3aGF0VG9TaG93ICYgRFRNRmlsdGVyLlNIT1dfQ0RBVEFfU0VDVElPTikpCi0gICAgICB2LmFkZEVsZW1lbnQoIlNIT1dfQ0RBVEFfU0VDVElPTiIpOwotCi0gICAgaWYgKDAgIT0gKHdoYXRUb1Nob3cgJiBEVE1GaWx0ZXIuU0hPV19DT01NRU5UKSkKLSAgICAgIHYuYWRkRWxlbWVudCgiU0hPV19DT01NRU5UIik7Ci0KLSAgICBpZiAoMCAhPSAod2hhdFRvU2hvdyAmIERUTUZpbHRlci5TSE9XX0RPQ1VNRU5UKSkKLSAgICAgIHYuYWRkRWxlbWVudCgiU0hPV19ET0NVTUVOVCIpOwotCi0gICAgaWYgKDAgIT0gKHdoYXRUb1Nob3cgJiBEVE1GaWx0ZXIuU0hPV19ET0NVTUVOVF9GUkFHTUVOVCkpCi0gICAgICB2LmFkZEVsZW1lbnQoIlNIT1dfRE9DVU1FTlRfRlJBR01FTlQiKTsKLQotICAgIGlmICgwICE9ICh3aGF0VG9TaG93ICYgRFRNRmlsdGVyLlNIT1dfRE9DVU1FTlRfVFlQRSkpCi0gICAgICB2LmFkZEVsZW1lbnQoIlNIT1dfRE9DVU1FTlRfVFlQRSIpOwotCi0gICAgaWYgKDAgIT0gKHdoYXRUb1Nob3cgJiBEVE1GaWx0ZXIuU0hPV19FTEVNRU5UKSkKLSAgICAgIHYuYWRkRWxlbWVudCgiU0hPV19FTEVNRU5UIik7Ci0KLSAgICBpZiAoMCAhPSAod2hhdFRvU2hvdyAmIERUTUZpbHRlci5TSE9XX0VOVElUWSkpCi0gICAgICB2LmFkZEVsZW1lbnQoIlNIT1dfRU5USVRZIik7Ci0KLSAgICBpZiAoMCAhPSAod2hhdFRvU2hvdyAmIERUTUZpbHRlci5TSE9XX0VOVElUWV9SRUZFUkVOQ0UpKQotICAgICAgdi5hZGRFbGVtZW50KCJTSE9XX0VOVElUWV9SRUZFUkVOQ0UiKTsKLQotICAgIGlmICgwICE9ICh3aGF0VG9TaG93ICYgRFRNRmlsdGVyLlNIT1dfTk9UQVRJT04pKQotICAgICAgdi5hZGRFbGVtZW50KCJTSE9XX05PVEFUSU9OIik7Ci0KLSAgICBpZiAoMCAhPSAod2hhdFRvU2hvdyAmIERUTUZpbHRlci5TSE9XX1BST0NFU1NJTkdfSU5TVFJVQ1RJT04pKQotICAgICAgdi5hZGRFbGVtZW50KCJTSE9XX1BST0NFU1NJTkdfSU5TVFJVQ1RJT04iKTsKLQotICAgIGlmICgwICE9ICh3aGF0VG9TaG93ICYgRFRNRmlsdGVyLlNIT1dfVEVYVCkpCi0gICAgICB2LmFkZEVsZW1lbnQoIlNIT1dfVEVYVCIpOwotCi0gICAgaW50IG4gPSB2LnNpemUoKTsKLQotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKQotICAgIHsKLSAgICAgIGlmIChpID4gMCkKLSAgICAgICAgU3lzdGVtLm91dC5wcmludCgiIHwgIik7Ci0KLSAgICAgIFN5c3RlbS5vdXQucHJpbnQodi5lbGVtZW50QXQoaSkpOwotICAgIH0KLQotICAgIGlmICgwID09IG4pCi0gICAgICBTeXN0ZW0ub3V0LnByaW50KCJlbXB0eSB3aGF0VG9TaG93OiAiICsgd2hhdFRvU2hvdyk7Ci0KLSAgICBTeXN0ZW0ub3V0LnByaW50bG4oKTsKLSAgfQotCi0gIC8qKgotICAgKiBUd28gbmFtZXMgYXJlIGVxdWFsIGlmIHRoZXkgYW5kIGVpdGhlciBib3RoIGFyZSBudWxsIG9yCi0gICAqIHRoZSBuYW1lIHQgaXMgd2lsZCBhbmQgdGhlIG5hbWUgcCBpcyBub24tbnVsbCwgb3IgdGhlIHR3bwotICAgKiBzdHJpbmdzIGFyZSBlcXVhbC4KLSAgICoKLSAgICogQHBhcmFtIHAgcGFydCBzdHJpbmcgZnJvbSB0aGUgbm9kZS4KLSAgICogQHBhcmFtIHQgdGFyZ2V0IHN0cmluZywgd2hpY2ggbWF5IGJlIHtAbGluayAjV0lMRH0uCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgc3RyaW5ncyBtYXRjaCBhY2NvcmRpbmcgdG8gdGhlIHJ1bGVzIG9mIHRoaXMgbWV0aG9kLgotICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbiBzdWJQYXJ0TWF0Y2goU3RyaW5nIHAsIFN0cmluZyB0KQotICB7Ci0KLSAgICAvLyBib29sZWFuIGIgPSAocCA9PSB0KSB8fCAoKG51bGwgIT0gcCkgJiYgKCh0ID09IFdJTEQpIHx8IHAuZXF1YWxzKHQpKSk7Ci0gICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJzdWJQYXJ0TWF0Y2ggLSBwOiAiK3ArIiwgdDogIit0KyIsIHJlc3VsdDogIitiKTsKLSAgICByZXR1cm4gKHAgPT0gdCkgfHwgKChudWxsICE9IHApICYmICgodCA9PSBXSUxEKSB8fCBwLmVxdWFscyh0KSkpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoaXMgaXMgdGVtcG9yYXJ5IHRvIHBhdGNoIG92ZXIgWGVyY2VzIGlzc3VlIHdpdGggcmVwcmVzZW50aW5nIERPTQotICAgKiBuYW1lc3BhY2VzIGFzICIiLgotICAgKgotICAgKiBAcGFyYW0gcCBwYXJ0IHN0cmluZyBmcm9tIHRoZSBub2RlLCB3aGljaCBtYXkgcmVwcmVzZW50IHRoZSBudWxsIG5hbWVzcGFjZQotICAgKiAgICAgICAgYXMgbnVsbCBvciBhcyAiIi4KLSAgICogQHBhcmFtIHQgdGFyZ2V0IHN0cmluZywgd2hpY2ggbWF5IGJlIHtAbGluayAjV0lMRH0uCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgc3RyaW5ncyBtYXRjaCBhY2NvcmRpbmcgdG8gdGhlIHJ1bGVzIG9mIHRoaXMgbWV0aG9kLgotICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbiBzdWJQYXJ0TWF0Y2hOUyhTdHJpbmcgcCwgU3RyaW5nIHQpCi0gIHsKLQotICAgIHJldHVybiAocCA9PSB0KQotICAgICAgICAgICB8fCAoKG51bGwgIT0gcCkKLSAgICAgICAgICAgICAgICYmICgocC5sZW5ndGgoKSA+IDApCi0gICAgICAgICAgICAgICAgICAgPyAoKHQgPT0gV0lMRCkgfHwgcC5lcXVhbHModCkpIDogbnVsbCA9PSB0KSk7Ci0gIH0KLQotICAvKioKLSAgICogVGVsbCB3aGF0IHRoZSB0ZXN0IHNjb3JlIGlzIGZvciB0aGUgZ2l2ZW4gbm9kZS4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IFhQYXRoIHJ1bnRpbWUgY29udGV4dC4KLSAgICogQHBhcmFtIGNvbnRleHQgVGhlIG5vZGUgYmVpbmcgdGVzdGVkLgotICAgKgotICAgKiBAcmV0dXJuIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfTk9ERVRFU1R9LAotICAgKiAgICAgICAgIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfTk9ORX0sCi0gICAqICAgICAgICAge0BsaW5rIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5wYXR0ZXJucy5Ob2RlVGVzdCNTQ09SRV9OU1dJTER9LAotICAgKiAgICAgICAgIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfUU5BTUV9LCBvcgotICAgKiAgICAgICAgIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfT1RIRVJ9LgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IGV4ZWN1dGUoWFBhdGhDb250ZXh0IHhjdHh0LCBpbnQgY29udGV4dCkKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBEVE0gZHRtID0geGN0eHQuZ2V0RFRNKGNvbnRleHQpOwotICAgIHNob3J0IG5vZGVUeXBlID0gZHRtLmdldE5vZGVUeXBlKGNvbnRleHQpOwotCi0gICAgaWYgKG1fd2hhdFRvU2hvdyA9PSBEVE1GaWx0ZXIuU0hPV19BTEwpCi0gICAgICByZXR1cm4gbV9zY29yZTsKLQotICAgIGludCBub2RlQml0ID0gKG1fd2hhdFRvU2hvdyAmICgweDAwMDAwMDAxIDw8IChub2RlVHlwZSAtIDEpKSk7Ci0KLSAgICBzd2l0Y2ggKG5vZGVCaXQpCi0gICAgewotICAgIGNhc2UgRFRNRmlsdGVyLlNIT1dfRE9DVU1FTlRfRlJBR01FTlQgOgotICAgIGNhc2UgRFRNRmlsdGVyLlNIT1dfRE9DVU1FTlQgOgotICAgICAgcmV0dXJuIFNDT1JFX09USEVSOwotICAgIGNhc2UgRFRNRmlsdGVyLlNIT1dfQ09NTUVOVCA6Ci0gICAgICByZXR1cm4gbV9zY29yZTsKLSAgICBjYXNlIERUTUZpbHRlci5TSE9XX0NEQVRBX1NFQ1RJT04gOgotICAgIGNhc2UgRFRNRmlsdGVyLlNIT1dfVEVYVCA6Ci0KLSAgICAgIC8vIHdhczoKLSAgICAgIC8vIHJldHVybiAoIXhjdHh0LmdldERPTUhlbHBlcigpLnNob3VsZFN0cmlwU291cmNlTm9kZShjb250ZXh0KSkKLSAgICAgIC8vICAgICAgID8gbV9zY29yZSA6IFNDT1JFX05PTkU7Ci0gICAgICByZXR1cm4gbV9zY29yZTsKLSAgICBjYXNlIERUTUZpbHRlci5TSE9XX1BST0NFU1NJTkdfSU5TVFJVQ1RJT04gOgotICAgICAgcmV0dXJuIHN1YlBhcnRNYXRjaChkdG0uZ2V0Tm9kZU5hbWUoY29udGV4dCksIG1fbmFtZSkKLSAgICAgICAgICAgICA/IG1fc2NvcmUgOiBTQ09SRV9OT05FOwotCi0gICAgLy8gRnJvbSB0aGUgZHJhZnQ6ICJUd28gZXhwYW5kZWQgbmFtZXMgYXJlIGVxdWFsIGlmIHRoZXkKLSAgICAvLyBoYXZlIHRoZSBzYW1lIGxvY2FsIHBhcnQsIGFuZCBlaXRoZXIgYm90aCBoYXZlIG5vIFVSSSBvcgotICAgIC8vIGJvdGggaGF2ZSB0aGUgc2FtZSBVUkkuIgotICAgIC8vICJBIG5vZGUgdGVzdCAqIGlzIHRydWUgZm9yIGFueSBub2RlIG9mIHRoZSBwcmluY2lwYWwgbm9kZSB0eXBlLgotICAgIC8vIEZvciBleGFtcGxlLCBjaGlsZDo6KiB3aWxsIHNlbGVjdCBhbGwgZWxlbWVudCBjaGlsZHJlbiBvZiB0aGUKLSAgICAvLyBjb250ZXh0IG5vZGUsIGFuZCBhdHRyaWJ1dGU6Oiogd2lsbCBzZWxlY3QgYWxsIGF0dHJpYnV0ZXMgb2YKLSAgICAvLyB0aGUgY29udGV4dCBub2RlLiIKLSAgICAvLyAiQSBub2RlIHRlc3QgY2FuIGhhdmUgdGhlIGZvcm0gTkNOYW1lOiouIEluIHRoaXMgY2FzZSwgdGhlIHByZWZpeAotICAgIC8vIGlzIGV4cGFuZGVkIGluIHRoZSBzYW1lIHdheSBhcyB3aXRoIGEgUU5hbWUgdXNpbmcgdGhlIGNvbnRleHQKLSAgICAvLyBuYW1lc3BhY2UgZGVjbGFyYXRpb25zLiBUaGUgbm9kZSB0ZXN0IHdpbGwgYmUgdHJ1ZSBmb3IgYW55IG5vZGUKLSAgICAvLyBvZiB0aGUgcHJpbmNpcGFsIHR5cGUgd2hvc2UgZXhwYW5kZWQgbmFtZSBoYXMgdGhlIFVSSSB0byB3aGljaAotICAgIC8vIHRoZSBwcmVmaXggZXhwYW5kcywgcmVnYXJkbGVzcyBvZiB0aGUgbG9jYWwgcGFydCBvZiB0aGUgbmFtZS4iCi0gICAgY2FzZSBEVE1GaWx0ZXIuU0hPV19OQU1FU1BBQ0UgOgotICAgIHsKLSAgICAgIFN0cmluZyBucyA9IGR0bS5nZXRMb2NhbE5hbWUoY29udGV4dCk7Ci0KLSAgICAgIHJldHVybiAoc3ViUGFydE1hdGNoKG5zLCBtX25hbWUpKSA/IG1fc2NvcmUgOiBTQ09SRV9OT05FOwotICAgIH0KLSAgICBjYXNlIERUTUZpbHRlci5TSE9XX0FUVFJJQlVURSA6Ci0gICAgY2FzZSBEVE1GaWx0ZXIuU0hPV19FTEVNRU5UIDoKLSAgICB7Ci0gICAgICByZXR1cm4gKG1faXNUb3RhbGx5V2lsZCB8fCAoc3ViUGFydE1hdGNoTlMoZHRtLmdldE5hbWVzcGFjZVVSSShjb250ZXh0KSwgbV9uYW1lc3BhY2UpICYmIHN1YlBhcnRNYXRjaChkdG0uZ2V0TG9jYWxOYW1lKGNvbnRleHQpLCBtX25hbWUpKSkKLSAgICAgICAgICAgICA/IG1fc2NvcmUgOiBTQ09SRV9OT05FOwotICAgIH0KLSAgICBkZWZhdWx0IDoKLSAgICAgIHJldHVybiBTQ09SRV9OT05FOwotICAgIH0gIC8vIGVuZCBzd2l0Y2godGVzdFR5cGUpCi0gIH0KLQotICAvKioKLSAgICogVGVsbCB3aGF0IHRoZSB0ZXN0IHNjb3JlIGlzIGZvciB0aGUgZ2l2ZW4gbm9kZS4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IFhQYXRoIHJ1bnRpbWUgY29udGV4dC4KLSAgICogQHBhcmFtIGNvbnRleHQgVGhlIG5vZGUgYmVpbmcgdGVzdGVkLgotICAgKgotICAgKiBAcmV0dXJuIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfTk9ERVRFU1R9LAotICAgKiAgICAgICAgIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfTk9ORX0sCi0gICAqICAgICAgICAge0BsaW5rIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5wYXR0ZXJucy5Ob2RlVGVzdCNTQ09SRV9OU1dJTER9LAotICAgKiAgICAgICAgIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfUU5BTUV9LCBvcgotICAgKiAgICAgICAgIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfT1RIRVJ9LgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IGV4ZWN1dGUoWFBhdGhDb250ZXh0IHhjdHh0LCBpbnQgY29udGV4dCwKLSAgICAgICAgICAgICAgICAgICAgICAgICBEVE0gZHRtLCBpbnQgZXhwVHlwZSkKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAobV93aGF0VG9TaG93ID09IERUTUZpbHRlci5TSE9XX0FMTCkKLSAgICAgIHJldHVybiBtX3Njb3JlOwotCi0gICAgaW50IG5vZGVCaXQgPSAobV93aGF0VG9TaG93ICYgKDB4MDAwMDAwMDEKLSAgICAgICAgICAgICAgICAgICA8PCAoKGR0bS5nZXROb2RlVHlwZShjb250ZXh0KSkgLSAxKSkpOwotCi0gICAgc3dpdGNoIChub2RlQml0KQotICAgIHsKLSAgICBjYXNlIERUTUZpbHRlci5TSE9XX0RPQ1VNRU5UX0ZSQUdNRU5UIDoKLSAgICBjYXNlIERUTUZpbHRlci5TSE9XX0RPQ1VNRU5UIDoKLSAgICAgIHJldHVybiBTQ09SRV9PVEhFUjsKLSAgICBjYXNlIERUTUZpbHRlci5TSE9XX0NPTU1FTlQgOgotICAgICAgcmV0dXJuIG1fc2NvcmU7Ci0gICAgY2FzZSBEVE1GaWx0ZXIuU0hPV19DREFUQV9TRUNUSU9OIDoKLSAgICBjYXNlIERUTUZpbHRlci5TSE9XX1RFWFQgOgotCi0gICAgICAvLyB3YXM6Ci0gICAgICAvLyByZXR1cm4gKCF4Y3R4dC5nZXRET01IZWxwZXIoKS5zaG91bGRTdHJpcFNvdXJjZU5vZGUoY29udGV4dCkpCi0gICAgICAvLyAgICAgICA/IG1fc2NvcmUgOiBTQ09SRV9OT05FOwotICAgICAgcmV0dXJuIG1fc2NvcmU7Ci0gICAgY2FzZSBEVE1GaWx0ZXIuU0hPV19QUk9DRVNTSU5HX0lOU1RSVUNUSU9OIDoKLSAgICAgIHJldHVybiBzdWJQYXJ0TWF0Y2goZHRtLmdldE5vZGVOYW1lKGNvbnRleHQpLCBtX25hbWUpCi0gICAgICAgICAgICAgPyBtX3Njb3JlIDogU0NPUkVfTk9ORTsKLQotICAgIC8vIEZyb20gdGhlIGRyYWZ0OiAiVHdvIGV4cGFuZGVkIG5hbWVzIGFyZSBlcXVhbCBpZiB0aGV5Ci0gICAgLy8gaGF2ZSB0aGUgc2FtZSBsb2NhbCBwYXJ0LCBhbmQgZWl0aGVyIGJvdGggaGF2ZSBubyBVUkkgb3IKLSAgICAvLyBib3RoIGhhdmUgdGhlIHNhbWUgVVJJLiIKLSAgICAvLyAiQSBub2RlIHRlc3QgKiBpcyB0cnVlIGZvciBhbnkgbm9kZSBvZiB0aGUgcHJpbmNpcGFsIG5vZGUgdHlwZS4KLSAgICAvLyBGb3IgZXhhbXBsZSwgY2hpbGQ6Oiogd2lsbCBzZWxlY3QgYWxsIGVsZW1lbnQgY2hpbGRyZW4gb2YgdGhlCi0gICAgLy8gY29udGV4dCBub2RlLCBhbmQgYXR0cmlidXRlOjoqIHdpbGwgc2VsZWN0IGFsbCBhdHRyaWJ1dGVzIG9mCi0gICAgLy8gdGhlIGNvbnRleHQgbm9kZS4iCi0gICAgLy8gIkEgbm9kZSB0ZXN0IGNhbiBoYXZlIHRoZSBmb3JtIE5DTmFtZToqLiBJbiB0aGlzIGNhc2UsIHRoZSBwcmVmaXgKLSAgICAvLyBpcyBleHBhbmRlZCBpbiB0aGUgc2FtZSB3YXkgYXMgd2l0aCBhIFFOYW1lIHVzaW5nIHRoZSBjb250ZXh0Ci0gICAgLy8gbmFtZXNwYWNlIGRlY2xhcmF0aW9ucy4gVGhlIG5vZGUgdGVzdCB3aWxsIGJlIHRydWUgZm9yIGFueSBub2RlCi0gICAgLy8gb2YgdGhlIHByaW5jaXBhbCB0eXBlIHdob3NlIGV4cGFuZGVkIG5hbWUgaGFzIHRoZSBVUkkgdG8gd2hpY2gKLSAgICAvLyB0aGUgcHJlZml4IGV4cGFuZHMsIHJlZ2FyZGxlc3Mgb2YgdGhlIGxvY2FsIHBhcnQgb2YgdGhlIG5hbWUuIgotICAgIGNhc2UgRFRNRmlsdGVyLlNIT1dfTkFNRVNQQUNFIDoKLSAgICB7Ci0gICAgICBTdHJpbmcgbnMgPSBkdG0uZ2V0TG9jYWxOYW1lKGNvbnRleHQpOwotCi0gICAgICByZXR1cm4gKHN1YlBhcnRNYXRjaChucywgbV9uYW1lKSkgPyBtX3Njb3JlIDogU0NPUkVfTk9ORTsKLSAgICB9Ci0gICAgY2FzZSBEVE1GaWx0ZXIuU0hPV19BVFRSSUJVVEUgOgotICAgIGNhc2UgRFRNRmlsdGVyLlNIT1dfRUxFTUVOVCA6Ci0gICAgewotICAgICAgcmV0dXJuIChtX2lzVG90YWxseVdpbGQgfHwgKHN1YlBhcnRNYXRjaE5TKGR0bS5nZXROYW1lc3BhY2VVUkkoY29udGV4dCksIG1fbmFtZXNwYWNlKSAmJiBzdWJQYXJ0TWF0Y2goZHRtLmdldExvY2FsTmFtZShjb250ZXh0KSwgbV9uYW1lKSkpCi0gICAgICAgICAgICAgPyBtX3Njb3JlIDogU0NPUkVfTk9ORTsKLSAgICB9Ci0gICAgZGVmYXVsdCA6Ci0gICAgICByZXR1cm4gU0NPUkVfTk9ORTsKLSAgICB9ICAvLyBlbmQgc3dpdGNoKHRlc3RUeXBlKQotICB9Ci0KLSAgLyoqCi0gICAqIFRlc3QgdGhlIGN1cnJlbnQgbm9kZSB0byBzZWUgaWYgaXQgbWF0Y2hlcyB0aGUgZ2l2ZW4gbm9kZSB0ZXN0LgotICAgKgotICAgKiBAcGFyYW0geGN0eHQgWFBhdGggcnVudGltZSBjb250ZXh0LgotICAgKgotICAgKiBAcmV0dXJuIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfTk9ERVRFU1R9LAotICAgKiAgICAgICAgIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfTk9ORX0sCi0gICAqICAgICAgICAge0BsaW5rIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5wYXR0ZXJucy5Ob2RlVGVzdCNTQ09SRV9OU1dJTER9LAotICAgKiAgICAgICAgIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfUU5BTUV9LCBvcgotICAgKiAgICAgICAgIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfT1RIRVJ9LgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IGV4ZWN1dGUoWFBhdGhDb250ZXh0IHhjdHh0KQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gZXhlY3V0ZSh4Y3R4dCwgeGN0eHQuZ2V0Q3VycmVudE5vZGUoKSk7Ci0gIH0KLQotICAvKioKLSAgICogTm9kZSB0ZXN0cyBieSB0aGVtc2VsdmVzIGRvIG5vdCBuZWVkIHRvIGZpeCB1cCB2YXJpYWJsZXMuCi0gICAqLwotICBwdWJsaWMgdm9pZCBmaXh1cFZhcmlhYmxlcyhqYXZhLnV0aWwuVmVjdG9yIHZhcnMsIGludCBnbG9iYWxzU2l6ZSkKLSAgewotICAgIC8vIG5vLW9wCi0gIH0KLQotICAvKioKLSAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuWFBhdGhWaXNpdGFibGUjY2FsbFZpc2l0b3JzKEV4cHJlc3Npb25Pd25lciwgWFBhdGhWaXNpdG9yKQotICAgKi8KLSAgcHVibGljIHZvaWQgY2FsbFZpc2l0b3JzKEV4cHJlc3Npb25Pd25lciBvd25lciwgWFBhdGhWaXNpdG9yIHZpc2l0b3IpCi0gIHsKLSAgICAgICAgYXNzZXJ0aW9uKGZhbHNlLCAiY2FsbFZpc2l0b3JzIHNob3VsZCBub3QgYmUgY2FsbGVkIGZvciB0aGlzIG9iamVjdCEhISIpOwotICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvcGF0dGVybnMvTm9kZVRlc3RGaWx0ZXIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvcGF0dGVybnMvTm9kZVRlc3RGaWx0ZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYzUzMjkzNy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL3BhdHRlcm5zL05vZGVUZXN0RmlsdGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0MSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBOb2RlVGVzdEZpbHRlci5qYXZhLHYgMS4xLjIuMSAyMDA1LzA4LzAxIDAxOjMwOjMwIGplZmZzdXR0b3IgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucGF0dGVybnM7Ci0KLS8qKgotICogVGhpcyBpbnRlcmZhY2Ugc2hvdWxkIGJlIGltcGxlbWVudGVkIGJ5IE5vZGVzIGFuZC9vciBpdGVyYXRvcnMsCi0gKiB3aGVuIHRoZXkgbmVlZCB0byBrbm93IHdoYXQgdGhlIG5vZGUgdGVzdCBpcyBiZWZvcmUgdGhleSBkbwotICogZ2V0TmV4dENoaWxkLCBldGMuCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgTm9kZVRlc3RGaWx0ZXIKLXsKLQotICAvKioKLSAgICogU2V0IHRoZSBub2RlIHRlc3QgZm9yIHRoaXMgZmlsdGVyLgotICAgKgotICAgKgotICAgKiBAcGFyYW0gbm9kZVRlc3QgUmVmZXJlbmNlIHRvIGEgTm9kZVRlc3QgdGhhdCBtYXkgYmUgdXNlZCB0byBwcmVkZXRlcm1pbmUKLSAgICogICAgICAgICAgICAgICAgIHdoYXQgbm9kZXMgdG8gcmV0dXJuLgotICAgKi8KLSAgdm9pZCBzZXROb2RlVGVzdChOb2RlVGVzdCBub2RlVGVzdCk7Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL3BhdHRlcm5zL1N0ZXBQYXR0ZXJuLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL3BhdHRlcm5zL1N0ZXBQYXR0ZXJuLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGNlNGIzYWYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9wYXR0ZXJucy9TdGVwUGF0dGVybi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTA1NSArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0vKgotICogJElkOiBTdGVwUGF0dGVybi5qYXZhLHYgMS4yLjQuMiAyMDA1LzA5LzE1IDAwOjIxOjE2IGplZmZzdXR0b3IgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucGF0dGVybnM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5BeGlzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLmR0bS5EVE1BeGlzVHJhdmVyc2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLkRUTUZpbHRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuRXhwcmVzc2lvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuRXhwcmVzc2lvbk93bmVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5YUGF0aENvbnRleHQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoVmlzaXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuYXhlcy5TdWJDb250ZXh0TGlzdDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuY29tcGlsZXIuUHN1ZWRvTmFtZXM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuWE9iamVjdDsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIHJlcHJlc2VudHMgYSBzaW5nbGUgcGF0dGVybiBtYXRjaCBzdGVwLgotICogQHhzbC51c2FnZSBhZHZhbmNlZAotICovCi1wdWJsaWMgY2xhc3MgU3RlcFBhdHRlcm4gZXh0ZW5kcyBOb2RlVGVzdCBpbXBsZW1lbnRzIFN1YkNvbnRleHRMaXN0LCBFeHByZXNzaW9uT3duZXIKLXsKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gOTA3MTY2ODk2MDE2ODE1MjY0NEw7Ci0KLSAgLyoqIFRoZSBheGlzIGZvciB0aGlzIHRlc3QuICovCi0gIHByb3RlY3RlZCBpbnQgbV9heGlzOwotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBTdGVwUGF0dGVybiB0aGF0IHRlc3RzIGZvciBuYW1lc3BhY2VzIGFuZCBub2RlIG5hbWVzLgotICAgKgotICAgKgotICAgKiBAcGFyYW0gd2hhdFRvU2hvdyBCaXQgc2V0IGRlZmluZWQgbWFpbmx5IGJ5IHtAbGluayBvcmcudzNjLmRvbS50cmF2ZXJzYWwuTm9kZUZpbHRlcn0uCi0gICAqIEBwYXJhbSBuYW1lc3BhY2UgVGhlIG5hbWVzcGFjZSB0byBiZSB0ZXN0ZWQuCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBsb2NhbCBuYW1lIHRvIGJlIHRlc3RlZC4KLSAgICogQHBhcmFtIGF4aXMgVGhlIEF4aXMgZm9yIHRoaXMgdGVzdCwgb25lIG9mIG9mIEF4ZXMuQU5DRVNUT1JPUlNFTEYsIGV0Yy4KLSAgICogQHBhcmFtIGF4aXNGb3JQcmVkaWNhdGUgTm8gbG9uZ2VyIHVzZWQuCi0gICAqLwotICBwdWJsaWMgU3RlcFBhdHRlcm4oaW50IHdoYXRUb1Nob3csIFN0cmluZyBuYW1lc3BhY2UsIFN0cmluZyBuYW1lLCBpbnQgYXhpcywKLSAgICAgICAgICAgICAgICAgICAgIGludCBheGlzRm9yUHJlZGljYXRlKQotICB7Ci0KLSAgICBzdXBlcih3aGF0VG9TaG93LCBuYW1lc3BhY2UsIG5hbWUpOwotCi0gICAgbV9heGlzID0gYXhpczsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBTdGVwUGF0dGVybiB0aGF0IGRvZXNuJ3QgdGVzdCBmb3Igbm9kZSBuYW1lcy4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHdoYXRUb1Nob3cgQml0IHNldCBkZWZpbmVkIG1haW5seSBieSB7QGxpbmsgb3JnLnczYy5kb20udHJhdmVyc2FsLk5vZGVGaWx0ZXJ9LgotICAgKiBAcGFyYW0gYXhpcyBUaGUgQXhpcyBmb3IgdGhpcyB0ZXN0LCBvbmUgb2Ygb2YgQXhlcy5BTkNFU1RPUk9SU0VMRiwgZXRjLgotICAgKiBAcGFyYW0gYXhpc0ZvclByZWRpY2F0ZSBObyBsb25nZXIgdXNlZC4KLSAgICovCi0gIHB1YmxpYyBTdGVwUGF0dGVybihpbnQgd2hhdFRvU2hvdywgaW50IGF4aXMsIGludCBheGlzRm9yUHJlZGljYXRlKQotICB7Ci0KLSAgICBzdXBlcih3aGF0VG9TaG93KTsKLQotICAgIG1fYXhpcyA9IGF4aXM7Ci0gIH0KLQotICAvKioKLSAgICogVGhlIHRhcmdldCBsb2NhbCBuYW1lIG9yIHBzdWVkbyBuYW1lLCBmb3IgaGFzaCB0YWJsZSBsb29rdXAgb3B0aW1pemF0aW9uLgotICAgKiAgQHNlcmlhbAotICAgKi8KLSAgU3RyaW5nIG1fdGFyZ2V0U3RyaW5nOyAgLy8gb25seSBjYWxjdWxhdGUgb24gaGVhZAotCi0gIC8qKgotICAgKiBDYWxjdWxhdGUgdGhlIGxvY2FsIG5hbWUgb3IgcHN1ZWRvIG5hbWUgb2YgdGhlIG5vZGUgdGhhdCB0aGlzIHBhdHRlcm4gd2lsbCB0ZXN0LAotICAgKiBmb3IgaGFzaCB0YWJsZSBsb29rdXAgb3B0aW1pemF0aW9uLgotICAgKgotICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5jb21waWxlci5Qc3VlZG9OYW1lcwotICAgKi8KLSAgcHVibGljIHZvaWQgY2FsY1RhcmdldFN0cmluZygpCi0gIHsKLQotICAgIGludCB3aGF0VG9TaG93ID0gZ2V0V2hhdFRvU2hvdygpOwotCi0gICAgc3dpdGNoICh3aGF0VG9TaG93KQotICAgIHsKLSAgICBjYXNlIERUTUZpbHRlci5TSE9XX0NPTU1FTlQgOgotICAgICAgbV90YXJnZXRTdHJpbmcgPSBQc3VlZG9OYW1lcy5QU0VVRE9OQU1FX0NPTU1FTlQ7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIERUTUZpbHRlci5TSE9XX1RFWFQgOgotICAgIGNhc2UgRFRNRmlsdGVyLlNIT1dfQ0RBVEFfU0VDVElPTiA6Ci0gICAgY2FzZSAoRFRNRmlsdGVyLlNIT1dfVEVYVCB8IERUTUZpbHRlci5TSE9XX0NEQVRBX1NFQ1RJT04pIDoKLSAgICAgIG1fdGFyZ2V0U3RyaW5nID0gUHN1ZWRvTmFtZXMuUFNFVURPTkFNRV9URVhUOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBEVE1GaWx0ZXIuU0hPV19BTEwgOgotICAgICAgbV90YXJnZXRTdHJpbmcgPSBQc3VlZG9OYW1lcy5QU0VVRE9OQU1FX0FOWTsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgRFRNRmlsdGVyLlNIT1dfRE9DVU1FTlQgOgotICAgIGNhc2UgRFRNRmlsdGVyLlNIT1dfRE9DVU1FTlQgfCBEVE1GaWx0ZXIuU0hPV19ET0NVTUVOVF9GUkFHTUVOVCA6Ci0gICAgICBtX3RhcmdldFN0cmluZyA9IFBzdWVkb05hbWVzLlBTRVVET05BTUVfUk9PVDsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgRFRNRmlsdGVyLlNIT1dfRUxFTUVOVCA6Ci0gICAgICBpZiAodGhpcy5XSUxEID09IG1fbmFtZSkKLSAgICAgICAgbV90YXJnZXRTdHJpbmcgPSBQc3VlZG9OYW1lcy5QU0VVRE9OQU1FX0FOWTsKLSAgICAgIGVsc2UKLSAgICAgICAgbV90YXJnZXRTdHJpbmcgPSBtX25hbWU7Ci0gICAgICBicmVhazsKLSAgICBkZWZhdWx0IDoKLSAgICAgIG1fdGFyZ2V0U3RyaW5nID0gUHN1ZWRvTmFtZXMuUFNFVURPTkFNRV9BTlk7Ci0gICAgICBicmVhazsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBsb2NhbCBuYW1lIG9yIHBzdWVkbyBuYW1lIG9mIHRoZSBub2RlIHRoYXQgdGhpcyBwYXR0ZXJuIHdpbGwgdGVzdCwKLSAgICogZm9yIGhhc2ggdGFibGUgbG9va3VwIG9wdGltaXphdGlvbi4KLSAgICoKLSAgICoKLSAgICogQHJldHVybiBsb2NhbCBuYW1lIG9yIHBzdWVkbyBuYW1lIG9mIHRoZSBub2RlLgotICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5jb21waWxlci5Qc3VlZG9OYW1lcwotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRTdHJpbmcoKQotICB7Ci0gICAgcmV0dXJuIG1fdGFyZ2V0U3RyaW5nOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlZmVyZW5jZSB0byBub2RldGVzdCBhbmQgcHJlZGljYXRlIGZvcgotICAgKiBwYXJlbnQgb3IgYW5jZXN0b3IuCi0gICAqIEBzZXJpYWwKLSAgICovCi0gIFN0ZXBQYXR0ZXJuIG1fcmVsYXRpdmVQYXRoUGF0dGVybjsKLQotICAvKioKLSAgICogVGhpcyBmdW5jdGlvbiBpcyB1c2VkIHRvIGZpeHVwIHZhcmlhYmxlcyBmcm9tIFFOYW1lcyB0byBzdGFjayBmcmFtZQotICAgKiBpbmRleGVzIGF0IHN0eWxlc2hlZXQgYnVpbGQgdGltZS4KLSAgICogQHBhcmFtIHZhcnMgTGlzdCBvZiBRTmFtZXMgdGhhdCBjb3JyZXNwb25kIHRvIHZhcmlhYmxlcy4gIFRoaXMgbGlzdAotICAgKiBzaG91bGQgYmUgc2VhcmNoZWQgYmFja3dhcmRzIGZvciB0aGUgZmlyc3QgcXVhbGlmaWVkIG5hbWUgdGhhdAotICAgKiBjb3JyZXNwb25kcyB0byB0aGUgdmFyaWFibGUgcmVmZXJlbmNlIHFuYW1lLiAgVGhlIHBvc2l0aW9uIG9mIHRoZQotICAgKiBRTmFtZSBpbiB0aGUgdmVjdG9yIGZyb20gdGhlIHN0YXJ0IG9mIHRoZSB2ZWN0b3Igd2lsbCBiZSBpdHMgcG9zaXRpb24KLSAgICogaW4gdGhlIHN0YWNrIGZyYW1lIChidXQgdmFyaWFibGVzIGFib3ZlIHRoZSBnbG9iYWxzVG9wIHZhbHVlIHdpbGwgbmVlZAotICAgKiB0byBiZSBvZmZzZXQgdG8gdGhlIGN1cnJlbnQgc3RhY2sgZnJhbWUpLgotICAgKiBAcGFyYW0gZ2xvYmFsc1NpemUgVGhlIG51bWJlciBvZiB2YXJpYWJsZXMgaW4gdGhlIGdsb2JhbCB2YXJpYWJsZSBhcmVhLgotICAgKi8KLSAgcHVibGljIHZvaWQgZml4dXBWYXJpYWJsZXMoamF2YS51dGlsLlZlY3RvciB2YXJzLCBpbnQgZ2xvYmFsc1NpemUpCi0gIHsKLQotICAgIHN1cGVyLmZpeHVwVmFyaWFibGVzKHZhcnMsIGdsb2JhbHNTaXplKTsKLQotICAgIGlmIChudWxsICE9IG1fcHJlZGljYXRlcykKLSAgICB7Ci0gICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1fcHJlZGljYXRlcy5sZW5ndGg7IGkrKykKLSAgICAgIHsKLSAgICAgICAgbV9wcmVkaWNhdGVzW2ldLmZpeHVwVmFyaWFibGVzKHZhcnMsIGdsb2JhbHNTaXplKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICBpZiAobnVsbCAhPSBtX3JlbGF0aXZlUGF0aFBhdHRlcm4pCi0gICAgewotICAgICAgbV9yZWxhdGl2ZVBhdGhQYXR0ZXJuLmZpeHVwVmFyaWFibGVzKHZhcnMsIGdsb2JhbHNTaXplKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSByZWZlcmVuY2UgdG8gbm9kZXRlc3QgYW5kIHByZWRpY2F0ZSBmb3IKLSAgICogcGFyZW50IG9yIGFuY2VzdG9yLgotICAgKgotICAgKgotICAgKiBAcGFyYW0gZXhwciBUaGUgcmVsYXRpdmUgcGF0dGVybiBleHByZXNzaW9uLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0UmVsYXRpdmVQYXRoUGF0dGVybihTdGVwUGF0dGVybiBleHByKQotICB7Ci0KLSAgICBtX3JlbGF0aXZlUGF0aFBhdHRlcm4gPSBleHByOwotICAgIGV4cHIuZXhwclNldFBhcmVudCh0aGlzKTsKLQotICAgIGNhbGNTY29yZSgpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgcmVmZXJlbmNlIHRvIG5vZGV0ZXN0IGFuZCBwcmVkaWNhdGUgZm9yCi0gICAqIHBhcmVudCBvciBhbmNlc3Rvci4KLSAgICoKLSAgICoKLSAgICogQHJldHVybiBUaGUgcmVsYXRpdmUgcGF0dGVybiBleHByZXNzaW9uLgotICAgKi8KLSAgcHVibGljIFN0ZXBQYXR0ZXJuIGdldFJlbGF0aXZlUGF0aFBhdHRlcm4oKQotICB7Ci0gICAgcmV0dXJuIG1fcmVsYXRpdmVQYXRoUGF0dGVybjsKLSAgfQotCi0gIC8vICAvKioKLSAgLy8gICAqIFNldCB0aGUgbGlzdCBvZiBwcmVkaWNhdGUgZXhwcmVzc2lvbnMgZm9yIHRoaXMgcGF0dGVybiBzdGVwLgotICAvLyAgICogQHBhcmFtIHByZWRpY2F0ZXMgTGlzdCBvZiBleHByZXNzaW9uIG9iamVjdHMuCi0gIC8vICAgKi8KLSAgLy8gIHB1YmxpYyB2b2lkIHNldFByZWRpY2F0ZXMoRXhwcmVzc2lvbltdIHByZWRpY2F0ZXMpCi0gIC8vICB7Ci0gIC8vICAgIG1fcHJlZGljYXRlcyA9IHByZWRpY2F0ZXM7Ci0gIC8vICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgbGlzdCBvZiBwcmVkaWNhdGUgZXhwcmVzc2lvbnMgZm9yIHRoaXMgcGF0dGVybiBzdGVwLgotICAgKiBAcmV0dXJuIExpc3Qgb2YgZXhwcmVzc2lvbiBvYmplY3RzLgotICAgKi8KLSAgcHVibGljIEV4cHJlc3Npb25bXSBnZXRQcmVkaWNhdGVzKCkKLSAgewotICAgIHJldHVybiBtX3ByZWRpY2F0ZXM7Ci0gIH0KLQotICAvKioKLSAgICogVGhlIGxpc3Qgb2YgcHJlZGljYXRlIGV4cHJlc3Npb25zIGZvciB0aGlzIHBhdHRlcm4gc3RlcC4KLSAgICogIEBzZXJpYWwKLSAgICovCi0gIEV4cHJlc3Npb25bXSBtX3ByZWRpY2F0ZXM7Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgdGhpcyBleHByZXNzaW9uIG9yIGl0J3Mgc3ViZXhwcmVzc2lvbnMgY2FuIHRyYXZlcnNlIG91dHNpZGUKLSAgICogdGhlIGN1cnJlbnQgc3VidHJlZS4KLSAgICoKLSAgICogTk9URTogQW5jZXN0b3JzIHRlc3RzIHdpdGggcHJlZGljYXRlcyBhcmUgcHJvYmxlbWF0aWMsIGFuZCB3aWxsIHJlcXVpcmUKLSAgICogc3BlY2lhbCB0cmVhdG1lbnQuCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0cmF2ZXJzYWwgb3V0c2lkZSB0aGUgY29udGV4dCBub2RlJ3Mgc3VidHJlZSBjYW4gb2NjdXIuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBjYW5UcmF2ZXJzZU91dHNpZGVTdWJ0cmVlKCkKLSAgewotCi0gICAgaW50IG4gPSBnZXRQcmVkaWNhdGVDb3VudCgpOwotCi0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspCi0gICAgewotICAgICAgaWYgKGdldFByZWRpY2F0ZShpKS5jYW5UcmF2ZXJzZU91dHNpZGVTdWJ0cmVlKCkpCi0gICAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotICAgIHJldHVybiBmYWxzZTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgYSBwcmVkaWNhdGUgZXhwcmVzc2lvbi4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIGkgVGhlIGluZGV4IG9mIHRoZSBwcmVkaWNhdGUuCi0gICAqCi0gICAqIEByZXR1cm4gQSBwcmVkaWNhdGUgZXhwcmVzc2lvbi4KLSAgICovCi0gIHB1YmxpYyBFeHByZXNzaW9uIGdldFByZWRpY2F0ZShpbnQgaSkKLSAgewotICAgIHJldHVybiBtX3ByZWRpY2F0ZXNbaV07Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBudW1iZXIgb2YgcHJlZGljYXRlcyBmb3IgdGhpcyBtYXRjaCBwYXR0ZXJuIHN0ZXAuCi0gICAqCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBwcmVkaWNhdGVzIGZvciB0aGlzIG1hdGNoIHBhdHRlcm4gc3RlcC4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBpbnQgZ2V0UHJlZGljYXRlQ291bnQoKQotICB7Ci0gICAgcmV0dXJuIChudWxsID09IG1fcHJlZGljYXRlcykgPyAwIDogbV9wcmVkaWNhdGVzLmxlbmd0aDsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIHByZWRpY2F0ZXMgZm9yIHRoaXMgbWF0Y2ggcGF0dGVybiBzdGVwLgotICAgKgotICAgKgotICAgKiBAcGFyYW0gcHJlZGljYXRlcyBBbiBhcnJheSBvZiBleHByZXNzaW9ucyB0aGF0IGRlZmluZSBwcmVkaWNhdGVzCi0gICAqICAgICAgICAgICAgICAgICAgIGZvciB0aGlzIHN0ZXAuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRQcmVkaWNhdGVzKEV4cHJlc3Npb25bXSBwcmVkaWNhdGVzKQotICB7Ci0KLSAgICBtX3ByZWRpY2F0ZXMgPSBwcmVkaWNhdGVzOwotICAgIGlmKG51bGwgIT0gcHJlZGljYXRlcykKLSAgICB7Ci0gICAgICAgIGZvcihpbnQgaSA9IDA7IGkgPCBwcmVkaWNhdGVzLmxlbmd0aDsgaSsrKQotICAgICAgICB7Ci0gICAgICAgICAgICAgICAgcHJlZGljYXRlc1tpXS5leHByU2V0UGFyZW50KHRoaXMpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgY2FsY1Njb3JlKCk7Ci0gIH0KLQotICAvKioKLSAgICogU3RhdGljIGNhbGMgb2YgbWF0Y2ggc2NvcmUuCi0gICAqLwotICBwdWJsaWMgdm9pZCBjYWxjU2NvcmUoKQotICB7Ci0KLSAgICBpZiAoKGdldFByZWRpY2F0ZUNvdW50KCkgPiAwKSB8fCAobnVsbCAhPSBtX3JlbGF0aXZlUGF0aFBhdHRlcm4pKQotICAgIHsKLSAgICAgIG1fc2NvcmUgPSBTQ09SRV9PVEhFUjsKLSAgICB9Ci0gICAgZWxzZQotICAgICAgc3VwZXIuY2FsY1Njb3JlKCk7Ci0KLSAgICBpZiAobnVsbCA9PSBtX3RhcmdldFN0cmluZykKLSAgICAgIGNhbGNUYXJnZXRTdHJpbmcoKTsKLSAgfQotCi0gIC8qKgotICAgKiBFeGVjdXRlIHRoaXMgcGF0dGVybiBzdGVwLCBpbmNsdWRpbmcgcHJlZGljYXRlcy4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IFhQYXRoIHJ1bnRpbWUgY29udGV4dC4KLSAgICogQHBhcmFtIGN1cnJlbnROb2RlIFRoZSBjdXJyZW50IG5vZGUgY29udGV4dC4KLSAgICoKLSAgICogQHJldHVybiB7QGxpbmsgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLnBhdHRlcm5zLk5vZGVUZXN0I1NDT1JFX05PREVURVNUfSwKLSAgICogICAgICAgICB7QGxpbmsgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLnBhdHRlcm5zLk5vZGVUZXN0I1NDT1JFX05PTkV9LAotICAgKiAgICAgICAgIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfTlNXSUxEfSwKLSAgICogICAgICAgICB7QGxpbmsgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLnBhdHRlcm5zLk5vZGVUZXN0I1NDT1JFX1FOQU1FfSwgb3IKLSAgICogICAgICAgICB7QGxpbmsgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLnBhdHRlcm5zLk5vZGVUZXN0I1NDT1JFX09USEVSfS4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBleGVjdXRlKFhQYXRoQ29udGV4dCB4Y3R4dCwgaW50IGN1cnJlbnROb2RlKQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIERUTSBkdG0gPSB4Y3R4dC5nZXREVE0oY3VycmVudE5vZGUpOwotCi0gICAgaWYgKGR0bSAhPSBudWxsKQotICAgIHsKLSAgICAgIGludCBleHBUeXBlID0gZHRtLmdldEV4cGFuZGVkVHlwZUlEKGN1cnJlbnROb2RlKTsKLQotICAgICAgcmV0dXJuIGV4ZWN1dGUoeGN0eHQsIGN1cnJlbnROb2RlLCBkdG0sIGV4cFR5cGUpOwotICAgIH0KLQotICAgIHJldHVybiBOb2RlVGVzdC5TQ09SRV9OT05FOwotICB9Ci0KLSAgLyoqCi0gICAqIEV4ZWN1dGUgdGhpcyBwYXR0ZXJuIHN0ZXAsIGluY2x1ZGluZyBwcmVkaWNhdGVzLgotICAgKgotICAgKgotICAgKiBAcGFyYW0geGN0eHQgWFBhdGggcnVudGltZSBjb250ZXh0LgotICAgKgotICAgKiBAcmV0dXJuIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfTk9ERVRFU1R9LAotICAgKiAgICAgICAgIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfTk9ORX0sCi0gICAqICAgICAgICAge0BsaW5rIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5wYXR0ZXJucy5Ob2RlVGVzdCNTQ09SRV9OU1dJTER9LAotICAgKiAgICAgICAgIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfUU5BTUV9LCBvcgotICAgKiAgICAgICAgIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfT1RIRVJ9LgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IGV4ZWN1dGUoWFBhdGhDb250ZXh0IHhjdHh0KQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gZXhlY3V0ZSh4Y3R4dCwgeGN0eHQuZ2V0Q3VycmVudE5vZGUoKSk7Ci0gIH0KLQotICAvKioKLSAgICogRXhlY3V0ZSBhbiBleHByZXNzaW9uIGluIHRoZSBYUGF0aCBydW50aW1lIGNvbnRleHQsIGFuZCByZXR1cm4gdGhlCi0gICAqIHJlc3VsdCBvZiB0aGUgZXhwcmVzc2lvbi4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IFRoZSBYUGF0aCBydW50aW1lIGNvbnRleHQuCi0gICAqIEBwYXJhbSBjdXJyZW50Tm9kZSBUaGUgY3VycmVudE5vZGUuCi0gICAqIEBwYXJhbSBkdG0gVGhlIERUTSBvZiB0aGUgY3VycmVudCBub2RlLgotICAgKiBAcGFyYW0gZXhwVHlwZSBUaGUgZXhwYW5kZWQgdHlwZSBJRCBvZiB0aGUgY3VycmVudCBub2RlLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSByZXN1bHQgb2YgdGhlIGV4cHJlc3Npb24gaW4gdGhlIGZvcm0gb2YgYSA8Y29kZT5YT2JqZWN0PC9jb2RlPi4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uIGlmIGEgcnVudGltZSBleGNlcHRpb24KLSAgICogICAgICAgICBvY2N1cnMuCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBleGVjdXRlKAotICAgICAgICAgIFhQYXRoQ29udGV4dCB4Y3R4dCwgaW50IGN1cnJlbnROb2RlLCBEVE0gZHRtLCBpbnQgZXhwVHlwZSkKLSAgICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChtX3doYXRUb1Nob3cgPT0gTm9kZVRlc3QuU0hPV19CWUZVTkNUSU9OKQotICAgIHsKLSAgICAgIGlmIChudWxsICE9IG1fcmVsYXRpdmVQYXRoUGF0dGVybikKLSAgICAgIHsKLSAgICAgICAgcmV0dXJuIG1fcmVsYXRpdmVQYXRoUGF0dGVybi5leGVjdXRlKHhjdHh0KTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgICAgcmV0dXJuIE5vZGVUZXN0LlNDT1JFX05PTkU7Ci0gICAgfQotCi0gICAgWE9iamVjdCBzY29yZTsKLQotICAgIHNjb3JlID0gc3VwZXIuZXhlY3V0ZSh4Y3R4dCwgY3VycmVudE5vZGUsIGR0bSwgZXhwVHlwZSk7Ci0KLSAgICBpZiAoc2NvcmUgPT0gTm9kZVRlc3QuU0NPUkVfTk9ORSkKLSAgICAgIHJldHVybiBOb2RlVGVzdC5TQ09SRV9OT05FOwotCi0gICAgaWYgKGdldFByZWRpY2F0ZUNvdW50KCkgIT0gMCkKLSAgICB7Ci0gICAgICBpZiAoIWV4ZWN1dGVQcmVkaWNhdGVzKHhjdHh0LCBkdG0sIGN1cnJlbnROb2RlKSkKLSAgICAgICAgcmV0dXJuIE5vZGVUZXN0LlNDT1JFX05PTkU7Ci0gICAgfQotCi0gICAgaWYgKG51bGwgIT0gbV9yZWxhdGl2ZVBhdGhQYXR0ZXJuKQotICAgICAgcmV0dXJuIG1fcmVsYXRpdmVQYXRoUGF0dGVybi5leGVjdXRlUmVsYXRpdmVQYXRoUGF0dGVybih4Y3R4dCwgZHRtLAotICAgICAgICAgICAgICBjdXJyZW50Tm9kZSk7Ci0KLSAgICByZXR1cm4gc2NvcmU7Ci0gIH0KLQotICAvKioKLSAgICogTmV3IE1ldGhvZCB0byBjaGVjayB3aGV0aGVyIHRoZSBjdXJyZW50IG5vZGUgc2F0aXNmaWVzIGEgcG9zaXRpb24gcHJlZGljYXRlCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgWFBhdGggcnVudGltZSBjb250ZXh0LgotICAgKiBAcGFyYW0gcHJlZFBvcyBXaGljaCBwcmVkaWNhdGUgd2UncmUgZXZhbHVhdGluZyBvZiBmb29bMV1bMl1bM10uCi0gICAqIEBwYXJhbSBkdG0gVGhlIERUTSBvZiB0aGUgY3VycmVudCBub2RlLgotICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY3VycmVudE5vZGUuCi0gICAqIEBwYXJhbSBwb3MgVGhlIHBvc2l0aW9uIGJlaW5nIHJlcXVlc3RlZCwgaS5lLiB0aGUgdmFsdWUgcmV0dXJuZWQgYnkKLSAgICogICAgICAgICAgICBtX3ByZWRpY2F0ZXNbcHJlZFBvc10uZXhlY3V0ZSh4Y3R4dCkuCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBvZiB0aGUgcG9zaXRpb24gb2YgdGhlIGNvbnRleHQgbWF0Y2hlcyBwb3MsIGZhbHNlIG90aGVyd2lzZS4KLSAgICovCi0gIHByaXZhdGUgZmluYWwgYm9vbGVhbiBjaGVja1Byb3hpbWl0eVBvc2l0aW9uKFhQYXRoQ29udGV4dCB4Y3R4dCwKLSAgICAgICAgICBpbnQgcHJlZFBvcywgRFRNIGR0bSwgaW50IGNvbnRleHQsIGludCBwb3MpCi0gIHsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIERUTUF4aXNUcmF2ZXJzZXIgdHJhdmVyc2VyID0KLSAgICAgICAgZHRtLmdldEF4aXNUcmF2ZXJzZXIoQXhpcy5QUkVDRURJTkdTSUJMSU5HKTsKLQotICAgICAgZm9yIChpbnQgY2hpbGQgPSB0cmF2ZXJzZXIuZmlyc3QoY29udGV4dCk7IERUTS5OVUxMICE9IGNoaWxkOwotICAgICAgICAgICAgICBjaGlsZCA9IHRyYXZlcnNlci5uZXh0KGNvbnRleHQsIGNoaWxkKSkKLSAgICAgIHsKLSAgICAgICAgdHJ5Ci0gICAgICAgIHsKLSAgICAgICAgICB4Y3R4dC5wdXNoQ3VycmVudE5vZGUoY2hpbGQpOwotCi0gICAgICAgICAgaWYgKE5vZGVUZXN0LlNDT1JFX05PTkUgIT0gc3VwZXIuZXhlY3V0ZSh4Y3R4dCwgY2hpbGQpKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGJvb2xlYW4gcGFzcyA9IHRydWU7Ci0KLSAgICAgICAgICAgIHRyeQotICAgICAgICAgICAgewotICAgICAgICAgICAgICB4Y3R4dC5wdXNoU3ViQ29udGV4dExpc3QodGhpcyk7Ci0KLSAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwcmVkUG9zOyBpKyspCi0gICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICB4Y3R4dC5wdXNoUHJlZGljYXRlUG9zKGkpOwotICAgICAgICAgICAgICAgIHRyeQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgIFhPYmplY3QgcHJlZCA9IG1fcHJlZGljYXRlc1tpXS5leGVjdXRlKHhjdHh0KTsKLQotICAgICAgICAgICAgICAgICAgdHJ5Ci0gICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChYT2JqZWN0LkNMQVNTX05VTUJFUiA9PSBwcmVkLmdldFR5cGUoKSkKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigiV2h5OiBTaG91bGQgbmV2ZXIgaGF2ZSBiZWVuIGNhbGxlZCIpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKCFwcmVkLmJvb2xXaXRoU2lkZUVmZmVjdHMoKSkKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgIHBhc3MgPSBmYWxzZTsKLQotICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICBmaW5hbGx5Ci0gICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIHByZWQuZGV0YWNoKCk7Ci0gICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGZpbmFsbHkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICB4Y3R4dC5wb3BQcmVkaWNhdGVQb3MoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGZpbmFsbHkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgeGN0eHQucG9wU3ViQ29udGV4dExpc3QoKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKHBhc3MpCi0gICAgICAgICAgICAgIHBvcy0tOwotCi0gICAgICAgICAgICBpZiAocG9zIDwgMSkKLSAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBmaW5hbGx5Ci0gICAgICAgIHsKLSAgICAgICAgICB4Y3R4dC5wb3BDdXJyZW50Tm9kZSgpOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotICAgIGNhdGNoIChqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uIHNlKQotICAgIHsKLQotICAgICAgLy8gVE9ETzogc2hvdWxkIGtlZXAgdGhyb3cgc2F4IGV4Y2VwdGlvbi4uLgotICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5SdW50aW1lRXhjZXB0aW9uKHNlLmdldE1lc3NhZ2UoKSk7Ci0gICAgfQotCi0gICAgcmV0dXJuIChwb3MgPT0gMSk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBwcm94aW1pdHkgcG9zaXRpb24gaW5kZXggb2YgdGhlIGN1cnJlbnQgbm9kZSBiYXNlZCBvbiB0aGlzCi0gICAqIG5vZGUgdGVzdC4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IFhQYXRoIHJ1bnRpbWUgY29udGV4dC4KLSAgICogQHBhcmFtIHByZWRQb3MgV2hpY2ggcHJlZGljYXRlIHdlJ3JlIGV2YWx1YXRpbmcgb2YgZm9vWzFdWzJdWzNdLgotICAgKiBAcGFyYW0gZmluZExhc3QgSWYgdHJ1ZSwgZG9uJ3QgdGVybWluYXRlIHdoZW4gdGhlIGNvbnRleHQgbm9kZSBpcyBmb3VuZC4KLSAgICoKLSAgICogQHJldHVybiB0aGUgcHJveGltaXR5IHBvc2l0aW9uIGluZGV4IG9mIHRoZSBjdXJyZW50IG5vZGUgYmFzZWQgb24gdGhlCi0gICAqICAgICAgICAgbm9kZSB0ZXN0LgotICAgKi8KLSAgcHJpdmF0ZSBmaW5hbCBpbnQgZ2V0UHJveGltaXR5UG9zaXRpb24oWFBhdGhDb250ZXh0IHhjdHh0LCBpbnQgcHJlZFBvcywKLSAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBmaW5kTGFzdCkKLSAgewotCi0gICAgaW50IHBvcyA9IDA7Ci0gICAgaW50IGNvbnRleHQgPSB4Y3R4dC5nZXRDdXJyZW50Tm9kZSgpOwotICAgIERUTSBkdG0gPSB4Y3R4dC5nZXREVE0oY29udGV4dCk7Ci0gICAgaW50IHBhcmVudCA9IGR0bS5nZXRQYXJlbnQoY29udGV4dCk7Ci0KLSAgICB0cnkKLSAgICB7Ci0gICAgICBEVE1BeGlzVHJhdmVyc2VyIHRyYXZlcnNlciA9IGR0bS5nZXRBeGlzVHJhdmVyc2VyKEF4aXMuQ0hJTEQpOwotCi0gICAgICBmb3IgKGludCBjaGlsZCA9IHRyYXZlcnNlci5maXJzdChwYXJlbnQpOyBEVE0uTlVMTCAhPSBjaGlsZDsKLSAgICAgICAgICAgICAgY2hpbGQgPSB0cmF2ZXJzZXIubmV4dChwYXJlbnQsIGNoaWxkKSkKLSAgICAgIHsKLSAgICAgICAgdHJ5Ci0gICAgICAgIHsKLSAgICAgICAgICB4Y3R4dC5wdXNoQ3VycmVudE5vZGUoY2hpbGQpOwotCi0gICAgICAgICAgaWYgKE5vZGVUZXN0LlNDT1JFX05PTkUgIT0gc3VwZXIuZXhlY3V0ZSh4Y3R4dCwgY2hpbGQpKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGJvb2xlYW4gcGFzcyA9IHRydWU7Ci0KLSAgICAgICAgICAgIHRyeQotICAgICAgICAgICAgewotICAgICAgICAgICAgICB4Y3R4dC5wdXNoU3ViQ29udGV4dExpc3QodGhpcyk7Ci0KLSAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwcmVkUG9zOyBpKyspCi0gICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICB4Y3R4dC5wdXNoUHJlZGljYXRlUG9zKGkpOwotICAgICAgICAgICAgICAgIHRyeQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgIFhPYmplY3QgcHJlZCA9IG1fcHJlZGljYXRlc1tpXS5leGVjdXRlKHhjdHh0KTsKLQotICAgICAgICAgICAgICAgICAgdHJ5Ci0gICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChYT2JqZWN0LkNMQVNTX05VTUJFUiA9PSBwcmVkLmdldFR5cGUoKSkKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgIGlmICgocG9zICsgMSkgIT0gKGludCkgcHJlZC5udW1XaXRoU2lkZUVmZmVjdHMoKSkKLSAgICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBwYXNzID0gZmFsc2U7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICghcHJlZC5ib29sV2l0aFNpZGVFZmZlY3RzKCkpCi0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICBwYXNzID0gZmFsc2U7Ci0KLSAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgZmluYWxseQotICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICBwcmVkLmRldGFjaCgpOwotICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBmaW5hbGx5Ci0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgeGN0eHQucG9wUHJlZGljYXRlUG9zKCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmaW5hbGx5Ci0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIHhjdHh0LnBvcFN1YkNvbnRleHRMaXN0KCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmIChwYXNzKQotICAgICAgICAgICAgICBwb3MrKzsKLQotICAgICAgICAgICAgaWYgKCFmaW5kTGFzdCAmJiBjaGlsZCA9PSBjb250ZXh0KQotICAgICAgICAgICAgewotICAgICAgICAgICAgICByZXR1cm4gcG9zOwotICAgICAgICAgICAgfQotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBmaW5hbGx5Ci0gICAgICAgIHsKLSAgICAgICAgICB4Y3R4dC5wb3BDdXJyZW50Tm9kZSgpOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotICAgIGNhdGNoIChqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uIHNlKQotICAgIHsKLQotICAgICAgLy8gVE9ETzogc2hvdWxkIGtlZXAgdGhyb3cgc2F4IGV4Y2VwdGlvbi4uLgotICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5SdW50aW1lRXhjZXB0aW9uKHNlLmdldE1lc3NhZ2UoKSk7Ci0gICAgfQotCi0gICAgcmV0dXJuIHBvczsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIHByb3hpbWl0eSBwb3NpdGlvbiBpbmRleCBvZiB0aGUgY3VycmVudCBub2RlIGJhc2VkIG9uIHRoaXMKLSAgICogbm9kZSB0ZXN0LgotICAgKgotICAgKgotICAgKiBAcGFyYW0geGN0eHQgWFBhdGggcnVudGltZSBjb250ZXh0LgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBwcm94aW1pdHkgcG9zaXRpb24gaW5kZXggb2YgdGhlIGN1cnJlbnQgbm9kZSBiYXNlZCBvbiB0aGUKLSAgICogICAgICAgICBub2RlIHRlc3QuCi0gICAqLwotICBwdWJsaWMgaW50IGdldFByb3hpbWl0eVBvc2l0aW9uKFhQYXRoQ29udGV4dCB4Y3R4dCkKLSAgewotICAgIHJldHVybiBnZXRQcm94aW1pdHlQb3NpdGlvbih4Y3R4dCwgeGN0eHQuZ2V0UHJlZGljYXRlUG9zKCksIGZhbHNlKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGNvdW50IG9mIHRoZSBub2RlcyB0aGF0IG1hdGNoIHRoZSB0ZXN0LCB3aGljaCBpcyB0aGUgcHJveGltaXR5Ci0gICAqIHBvc2l0aW9uIG9mIHRoZSBsYXN0IG5vZGUgdGhhdCBjYW4gcGFzcyB0aGlzIHRlc3QgaW4gdGhlIHN1YiBjb250ZXh0Ci0gICAqIHNlbGVjdGlvbi4gIEluIFhTTFQgMS1iYXNlZCBpbmRleGluZywgdGhpcyBjb3VudCBpcyB0aGUgaW5kZXggb2YgdGhlIGxhc3QKLSAgICogbm9kZS4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IFhQYXRoIHJ1bnRpbWUgY29udGV4dC4KLSAgICoKLSAgICogQHJldHVybiB0aGUgY291bnQgb2YgdGhlIG5vZGVzIHRoYXQgbWF0Y2ggdGhlIHRlc3QuCi0gICAqLwotICBwdWJsaWMgaW50IGdldExhc3RQb3MoWFBhdGhDb250ZXh0IHhjdHh0KQotICB7Ci0gICAgcmV0dXJuIGdldFByb3hpbWl0eVBvc2l0aW9uKHhjdHh0LCB4Y3R4dC5nZXRQcmVkaWNhdGVQb3MoKSwgdHJ1ZSk7Ci0gIH0KLQotICAvKioKLSAgICogRXhlY3V0ZSB0aGUgbWF0Y2ggcGF0dGVybiBzdGVwIHJlbGF0aXZlIHRvIGFub3RoZXIgc3RlcC4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IFRoZSBYUGF0aCBydW50aW1lIGNvbnRleHQuCi0gICAqIEBwYXJhbSBkdG0gVGhlIERUTSBvZiB0aGUgY3VycmVudCBub2RlLgotICAgKiBAcGFyYW0gY3VycmVudE5vZGUgVGhlIGN1cnJlbnQgbm9kZSBjb250ZXh0LgotICAgKgotICAgKiBAcmV0dXJuIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfTk9ERVRFU1R9LAotICAgKiAgICAgICAgIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfTk9ORX0sCi0gICAqICAgICAgICAge0BsaW5rIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5wYXR0ZXJucy5Ob2RlVGVzdCNTQ09SRV9OU1dJTER9LAotICAgKiAgICAgICAgIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfUU5BTUV9LCBvcgotICAgKiAgICAgICAgIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfT1RIRVJ9LgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHByb3RlY3RlZCBmaW5hbCBYT2JqZWN0IGV4ZWN1dGVSZWxhdGl2ZVBhdGhQYXR0ZXJuKAotICAgICAgICAgIFhQYXRoQ29udGV4dCB4Y3R4dCwgRFRNIGR0bSwgaW50IGN1cnJlbnROb2RlKQotICAgICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgWE9iamVjdCBzY29yZSA9IE5vZGVUZXN0LlNDT1JFX05PTkU7Ci0gICAgaW50IGNvbnRleHQgPSBjdXJyZW50Tm9kZTsKLSAgICBEVE1BeGlzVHJhdmVyc2VyIHRyYXZlcnNlcjsKLQotICAgIHRyYXZlcnNlciA9IGR0bS5nZXRBeGlzVHJhdmVyc2VyKG1fYXhpcyk7Ci0KLSAgICBmb3IgKGludCByZWxhdGl2ZSA9IHRyYXZlcnNlci5maXJzdChjb250ZXh0KTsgRFRNLk5VTEwgIT0gcmVsYXRpdmU7Ci0gICAgICAgICAgICByZWxhdGl2ZSA9IHRyYXZlcnNlci5uZXh0KGNvbnRleHQsIHJlbGF0aXZlKSkKLSAgICB7Ci0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgeGN0eHQucHVzaEN1cnJlbnROb2RlKHJlbGF0aXZlKTsKLQotICAgICAgICBzY29yZSA9IGV4ZWN1dGUoeGN0eHQpOwotCi0gICAgICAgIGlmIChzY29yZSAhPSBOb2RlVGVzdC5TQ09SRV9OT05FKQotICAgICAgICAgIGJyZWFrOwotICAgICAgfQotICAgICAgZmluYWxseQotICAgICAgewotICAgICAgICB4Y3R4dC5wb3BDdXJyZW50Tm9kZSgpOwotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiBzY29yZTsKLSAgfQotCi0gIC8qKgotICAgKiBFeGVjdXRlIHRoZSBwcmVkaWNhdGVzIG9uIHRoaXMgc3RlcCB0byBkZXRlcm1pbmUgaWYgdGhlIGN1cnJlbnQgbm9kZQotICAgKiBzaG91bGQgYmUgZmlsdGVyZWQgb3IgYWNjZXB0ZWQuCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgWFBhdGggcnVudGltZSBjb250ZXh0LgotICAgKiBAcGFyYW0gZHRtIFRoZSBEVE0gb2YgdGhlIGN1cnJlbnQgbm9kZS4KLSAgICogQHBhcmFtIGN1cnJlbnROb2RlIFRoZSBjdXJyZW50IG5vZGUgY29udGV4dC4KLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHRoZSBub2RlIHNob3VsZCBiZSBhY2NlcHRlZCwgZmFsc2Ugb3RoZXJ3aXNlLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHByb3RlY3RlZCBmaW5hbCBib29sZWFuIGV4ZWN1dGVQcmVkaWNhdGVzKAotICAgICAgICAgIFhQYXRoQ29udGV4dCB4Y3R4dCwgRFRNIGR0bSwgaW50IGN1cnJlbnROb2RlKQotICAgICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgYm9vbGVhbiByZXN1bHQgPSB0cnVlOwotICAgIGJvb2xlYW4gcG9zaXRpb25BbHJlYWR5U2VlbiA9IGZhbHNlOwotICAgIGludCBuID0gZ2V0UHJlZGljYXRlQ291bnQoKTsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIHhjdHh0LnB1c2hTdWJDb250ZXh0TGlzdCh0aGlzKTsKLQotICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspCi0gICAgICB7Ci0gICAgICAgIHhjdHh0LnB1c2hQcmVkaWNhdGVQb3MoaSk7Ci0KLSAgICAgICAgdHJ5Ci0gICAgICAgIHsKLSAgICAgICAgICBYT2JqZWN0IHByZWQgPSBtX3ByZWRpY2F0ZXNbaV0uZXhlY3V0ZSh4Y3R4dCk7Ci0KLSAgICAgICAgICB0cnkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBpZiAoWE9iamVjdC5DTEFTU19OVU1CRVIgPT0gcHJlZC5nZXRUeXBlKCkpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIGludCBwb3MgPSAoaW50KSBwcmVkLm51bSgpOwotCi0gICAgICAgICAgICAgIGlmIChwb3NpdGlvbkFscmVhZHlTZWVuKQotICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgcmVzdWx0ID0gKHBvcyA9PSAxKTsKLQotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIHBvc2l0aW9uQWxyZWFkeVNlZW4gPSB0cnVlOwotCi0gICAgICAgICAgICAgICAgaWYgKCFjaGVja1Byb3hpbWl0eVBvc2l0aW9uKHhjdHh0LCBpLCBkdG0sIGN1cnJlbnROb2RlLCBwb3MpKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IGZhbHNlOwotCi0gICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoIXByZWQuYm9vbFdpdGhTaWRlRWZmZWN0cygpKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICByZXN1bHQgPSBmYWxzZTsKLQotICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICB9Ci0gICAgICAgICAgZmluYWxseQotICAgICAgICAgIHsKLSAgICAgICAgICAgIHByZWQuZGV0YWNoKCk7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGZpbmFsbHkKLSAgICAgICAgewotICAgICAgICAgIHhjdHh0LnBvcFByZWRpY2F0ZVBvcygpOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotICAgIGZpbmFsbHkKLSAgICB7Ci0gICAgICB4Y3R4dC5wb3BTdWJDb250ZXh0TGlzdCgpOwotICAgIH0KLQotICAgIHJldHVybiByZXN1bHQ7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBzdHJpbmcgcmVwcmVzZW5lbnRhdGlvbiBvZiB0aGlzIHN0ZXAgZm9yIGRpYWdub3N0aWMgcHVycG9zZXMuCi0gICAqCi0gICAqCi0gICAqIEByZXR1cm4gQSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBzdGVwLCBidWlsdCBieSByZXZlcnNlLWVuZ2luZWVyaW5nCi0gICAqIHRoZSBjb250YWluZWQgaW5mby4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKQotICB7Ci0KLSAgICBTdHJpbmdCdWZmZXIgYnVmID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotCi0gICAgZm9yIChTdGVwUGF0dGVybiBwYXQgPSB0aGlzOyBwYXQgIT0gbnVsbDsgcGF0ID0gcGF0Lm1fcmVsYXRpdmVQYXRoUGF0dGVybikKLSAgICB7Ci0gICAgICBpZiAocGF0ICE9IHRoaXMpCi0gICAgICAgIGJ1Zi5hcHBlbmQoIi8iKTsKLQotICAgICAgYnVmLmFwcGVuZChBeGlzLmdldE5hbWVzKHBhdC5tX2F4aXMpKTsKLSAgICAgIGJ1Zi5hcHBlbmQoIjo6Iik7Ci0KLSAgICAgIGlmICgweDAwMDAwNTAwMCA9PSBwYXQubV93aGF0VG9TaG93KQotICAgICAgewotICAgICAgICBidWYuYXBwZW5kKCJkb2MoKSIpOwotICAgICAgfQotICAgICAgZWxzZSBpZiAoRFRNRmlsdGVyLlNIT1dfQllGVU5DVElPTiA9PSBwYXQubV93aGF0VG9TaG93KQotICAgICAgewotICAgICAgICBidWYuYXBwZW5kKCJmdW5jdGlvbigpIik7Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmIChEVE1GaWx0ZXIuU0hPV19BTEwgPT0gcGF0Lm1fd2hhdFRvU2hvdykKLSAgICAgIHsKLSAgICAgICAgYnVmLmFwcGVuZCgibm9kZSgpIik7Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmIChEVE1GaWx0ZXIuU0hPV19URVhUID09IHBhdC5tX3doYXRUb1Nob3cpCi0gICAgICB7Ci0gICAgICAgIGJ1Zi5hcHBlbmQoInRleHQoKSIpOwotICAgICAgfQotICAgICAgZWxzZSBpZiAoRFRNRmlsdGVyLlNIT1dfUFJPQ0VTU0lOR19JTlNUUlVDVElPTiA9PSBwYXQubV93aGF0VG9TaG93KQotICAgICAgewotICAgICAgICBidWYuYXBwZW5kKCJwcm9jZXNzaW5nLWluc3RydWN0aW9uKCIpOwotCi0gICAgICAgIGlmIChudWxsICE9IHBhdC5tX25hbWUpCi0gICAgICAgIHsKLSAgICAgICAgICBidWYuYXBwZW5kKHBhdC5tX25hbWUpOwotICAgICAgICB9Ci0KLSAgICAgICAgYnVmLmFwcGVuZCgiKSIpOwotICAgICAgfQotICAgICAgZWxzZSBpZiAoRFRNRmlsdGVyLlNIT1dfQ09NTUVOVCA9PSBwYXQubV93aGF0VG9TaG93KQotICAgICAgewotICAgICAgICBidWYuYXBwZW5kKCJjb21tZW50KCkiKTsKLSAgICAgIH0KLSAgICAgIGVsc2UgaWYgKG51bGwgIT0gcGF0Lm1fbmFtZSkKLSAgICAgIHsKLSAgICAgICAgaWYgKERUTUZpbHRlci5TSE9XX0FUVFJJQlVURSA9PSBwYXQubV93aGF0VG9TaG93KQotICAgICAgICB7Ci0gICAgICAgICAgYnVmLmFwcGVuZCgiQCIpOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKG51bGwgIT0gcGF0Lm1fbmFtZXNwYWNlKQotICAgICAgICB7Ci0gICAgICAgICAgYnVmLmFwcGVuZCgieyIpOwotICAgICAgICAgIGJ1Zi5hcHBlbmQocGF0Lm1fbmFtZXNwYWNlKTsKLSAgICAgICAgICBidWYuYXBwZW5kKCJ9Iik7Ci0gICAgICAgIH0KLQotICAgICAgICBidWYuYXBwZW5kKHBhdC5tX25hbWUpOwotICAgICAgfQotICAgICAgZWxzZSBpZiAoRFRNRmlsdGVyLlNIT1dfQVRUUklCVVRFID09IHBhdC5tX3doYXRUb1Nob3cpCi0gICAgICB7Ci0gICAgICAgIGJ1Zi5hcHBlbmQoIkAiKTsKLSAgICAgIH0KLSAgICAgIGVsc2UgaWYgKChEVE1GaWx0ZXIuU0hPV19ET0NVTUVOVCB8IERUTUZpbHRlci5TSE9XX0RPQ1VNRU5UX0ZSQUdNRU5UKQotICAgICAgICAgICAgICAgPT0gcGF0Lm1fd2hhdFRvU2hvdykKLSAgICAgIHsKLSAgICAgICAgYnVmLmFwcGVuZCgiZG9jLXJvb3QoKSIpOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBidWYuYXBwZW5kKCc/JykuYXBwZW5kKEludGVnZXIudG9IZXhTdHJpbmcocGF0Lm1fd2hhdFRvU2hvdykpOwotICAgICAgfQotCi0gICAgICBpZiAobnVsbCAhPSBwYXQubV9wcmVkaWNhdGVzKQotICAgICAgewotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhdC5tX3ByZWRpY2F0ZXMubGVuZ3RoOyBpKyspCi0gICAgICAgIHsKLSAgICAgICAgICBidWYuYXBwZW5kKCJbIik7Ci0gICAgICAgICAgYnVmLmFwcGVuZChwYXQubV9wcmVkaWNhdGVzW2ldKTsKLSAgICAgICAgICBidWYuYXBwZW5kKCJdIik7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gYnVmLnRvU3RyaW5nKCk7Ci0gIH0KLQotICAvKiogU2V0IHRvIHRydWUgdG8gc2VuZCBkaWFnbm9zdGljcyBhYm91dCBwYXR0ZXJuIG1hdGNoZXMgdG8gdGhlIGNvbnNvbC4gKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbiBERUJVR19NQVRDSEVTID0gZmFsc2U7Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbWF0Y2ggc2NvcmUgb2YgdGhlIGdpdmVuIG5vZGUuCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgWFBhdGggcnVudGltZSBjb250ZXh0LgotICAgKiBAcGFyYW0gY29udGV4dCBUaGUgbm9kZSB0byBiZSB0ZXN0ZWQuCi0gICAqCi0gICAqIEByZXR1cm4ge0BsaW5rIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5wYXR0ZXJucy5Ob2RlVGVzdCNTQ09SRV9OT0RFVEVTVH0sCi0gICAqICAgICAgICAge0BsaW5rIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5wYXR0ZXJucy5Ob2RlVGVzdCNTQ09SRV9OT05FfSwKLSAgICogICAgICAgICB7QGxpbmsgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLnBhdHRlcm5zLk5vZGVUZXN0I1NDT1JFX05TV0lMRH0sCi0gICAqICAgICAgICAge0BsaW5rIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5wYXR0ZXJucy5Ob2RlVGVzdCNTQ09SRV9RTkFNRX0sIG9yCi0gICAqICAgICAgICAge0BsaW5rIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5wYXR0ZXJucy5Ob2RlVGVzdCNTQ09SRV9PVEhFUn0uCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGRvdWJsZSBnZXRNYXRjaFNjb3JlKFhQYXRoQ29udGV4dCB4Y3R4dCwgaW50IGNvbnRleHQpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgeGN0eHQucHVzaEN1cnJlbnROb2RlKGNvbnRleHQpOwotICAgIHhjdHh0LnB1c2hDdXJyZW50RXhwcmVzc2lvbk5vZGUoY29udGV4dCk7Ci0KLSAgICB0cnkKLSAgICB7Ci0gICAgICBYT2JqZWN0IHNjb3JlID0gZXhlY3V0ZSh4Y3R4dCk7Ci0KLSAgICAgIHJldHVybiBzY29yZS5udW0oKTsKLSAgICB9Ci0gICAgZmluYWxseQotICAgIHsKLSAgICAgIHhjdHh0LnBvcEN1cnJlbnROb2RlKCk7Ci0gICAgICB4Y3R4dC5wb3BDdXJyZW50RXhwcmVzc2lvbk5vZGUoKTsKLSAgICB9Ci0KLSAgICAvLyByZXR1cm4gWFBhdGguTUFUQ0hfU0NPUkVfTk9ORTsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIGF4aXMgdGhhdCB0aGlzIHN0ZXAgc2hvdWxkIGZvbGxvdy4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIGF4aXMgVGhlIEF4aXMgZm9yIHRoaXMgdGVzdCwgb25lIG9mIG9mIEF4ZXMuQU5DRVNUT1JPUlNFTEYsIGV0Yy4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldEF4aXMoaW50IGF4aXMpCi0gIHsKLSAgICBtX2F4aXMgPSBheGlzOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgYXhpcyB0aGF0IHRoaXMgc3RlcCBmb2xsb3dzLgotICAgKgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBBeGlzIGZvciB0aGlzIHRlc3QsIG9uZSBvZiBvZiBBeGVzLkFOQ0VTVE9ST1JTRUxGLCBldGMuCi0gICAqLwotICBwdWJsaWMgaW50IGdldEF4aXMoKQotICB7Ci0gICAgcmV0dXJuIG1fYXhpczsKLSAgfQotCi0gIGNsYXNzIFByZWRPd25lciBpbXBsZW1lbnRzIEV4cHJlc3Npb25Pd25lcgotICB7Ci0gICAgICAgIGludCBtX2luZGV4OwotCi0gICAgICAgIFByZWRPd25lcihpbnQgaW5kZXgpCi0gICAgICAgIHsKLSAgICAgICAgICAgICAgICBtX2luZGV4ID0gaW5kZXg7Ci0gICAgICAgIH0KLQotICAgIC8qKgotICAgICAqIEBzZWUgRXhwcmVzc2lvbk93bmVyI2dldEV4cHJlc3Npb24oKQotICAgICAqLwotICAgIHB1YmxpYyBFeHByZXNzaW9uIGdldEV4cHJlc3Npb24oKQotICAgIHsKLSAgICAgIHJldHVybiBtX3ByZWRpY2F0ZXNbbV9pbmRleF07Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBAc2VlIEV4cHJlc3Npb25Pd25lciNzZXRFeHByZXNzaW9uKEV4cHJlc3Npb24pCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RXhwcmVzc2lvbihFeHByZXNzaW9uIGV4cCkKLSAgICB7Ci0gICAgICAgIGV4cC5leHByU2V0UGFyZW50KFN0ZXBQYXR0ZXJuLnRoaXMpOwotICAgICAgICBtX3ByZWRpY2F0ZXNbbV9pbmRleF0gPSBleHA7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoVmlzaXRhYmxlI2NhbGxWaXNpdG9ycyhFeHByZXNzaW9uT3duZXIsIFhQYXRoVmlzaXRvcikKLSAgICovCi0gIHB1YmxpYyB2b2lkIGNhbGxWaXNpdG9ycyhFeHByZXNzaW9uT3duZXIgb3duZXIsIFhQYXRoVmlzaXRvciB2aXNpdG9yKQotICB7Ci0gICAgICAgICAgICAgICAgaWYodmlzaXRvci52aXNpdE1hdGNoUGF0dGVybihvd25lciwgdGhpcykpCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgY2FsbFN1YnRyZWVWaXNpdG9ycyh2aXNpdG9yKTsKLSAgICAgICAgICAgICAgICB9Ci0gIH0KLQotICAvKioKLSAgICogQ2FsbCB0aGUgdmlzaXRvcnMgb24gdGhlIHN1YnRyZWUuICBGYWN0b3JlZCBvdXQgZnJvbSBjYWxsVmlzaXRvcnMKLSAgICogc28gaXQgbWF5IGJlIGNhbGxlZCBieSBkZXJpdmVkIGNsYXNzZXMuCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBjYWxsU3VidHJlZVZpc2l0b3JzKFhQYXRoVmlzaXRvciB2aXNpdG9yKQotICB7Ci0gICAgaWYgKG51bGwgIT0gbV9wcmVkaWNhdGVzKQotICAgIHsKLSAgICAgIGludCBuID0gbV9wcmVkaWNhdGVzLmxlbmd0aDsKLSAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKQotICAgICAgewotICAgICAgICBFeHByZXNzaW9uT3duZXIgcHJlZE93bmVyID0gbmV3IFByZWRPd25lcihpKTsKLSAgICAgICAgaWYgKHZpc2l0b3IudmlzaXRQcmVkaWNhdGUocHJlZE93bmVyLCBtX3ByZWRpY2F0ZXNbaV0pKQotICAgICAgICB7Ci0gICAgICAgICAgbV9wcmVkaWNhdGVzW2ldLmNhbGxWaXNpdG9ycyhwcmVkT3duZXIsIHZpc2l0b3IpOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotICAgIGlmIChudWxsICE9IG1fcmVsYXRpdmVQYXRoUGF0dGVybikKLSAgICB7Ci0gICAgICBtX3JlbGF0aXZlUGF0aFBhdHRlcm4uY2FsbFZpc2l0b3JzKHRoaXMsIHZpc2l0b3IpOwotICAgIH0KLSAgfQotCi0KLSAgLyoqCi0gICAqIEBzZWUgRXhwcmVzc2lvbk93bmVyI2dldEV4cHJlc3Npb24oKQotICAgKi8KLSAgcHVibGljIEV4cHJlc3Npb24gZ2V0RXhwcmVzc2lvbigpCi0gIHsKLSAgICByZXR1cm4gbV9yZWxhdGl2ZVBhdGhQYXR0ZXJuOwotICB9Ci0KLSAgLyoqCi0gICAqIEBzZWUgRXhwcmVzc2lvbk93bmVyI3NldEV4cHJlc3Npb24oRXhwcmVzc2lvbikKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldEV4cHJlc3Npb24oRXhwcmVzc2lvbiBleHApCi0gIHsKLSAgICBleHAuZXhwclNldFBhcmVudCh0aGlzKTsKLSAgICAgICAgbV9yZWxhdGl2ZVBhdGhQYXR0ZXJuID0gKFN0ZXBQYXR0ZXJuKWV4cDsKLSAgfQotCi0gIC8qKgotICAgKiBAc2VlIEV4cHJlc3Npb24jZGVlcEVxdWFscyhFeHByZXNzaW9uKQotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZGVlcEVxdWFscyhFeHByZXNzaW9uIGV4cHIpCi0gIHsKLSAgICAgICAgaWYoIXN1cGVyLmRlZXBFcXVhbHMoZXhwcikpCi0gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotCi0gICAgICAgIFN0ZXBQYXR0ZXJuIHNwID0gKFN0ZXBQYXR0ZXJuKWV4cHI7Ci0KLSAgICBpZiAobnVsbCAhPSBtX3ByZWRpY2F0ZXMpCi0gICAgewotICAgICAgICBpbnQgbiA9IG1fcHJlZGljYXRlcy5sZW5ndGg7Ci0gICAgICAgIGlmICgobnVsbCA9PSBzcC5tX3ByZWRpY2F0ZXMpIHx8IChzcC5tX3ByZWRpY2F0ZXMubGVuZ3RoICE9IG4pKQotICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKQotICAgICAgICB7Ci0gICAgICAgICAgaWYgKCFtX3ByZWRpY2F0ZXNbaV0uZGVlcEVxdWFscyhzcC5tX3ByZWRpY2F0ZXNbaV0pKQotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotICAgIH0KLSAgICBlbHNlIGlmIChudWxsICE9IHNwLm1fcHJlZGljYXRlcykKLSAgICAgICAgcmV0dXJuIGZhbHNlOwotCi0gICAgICAgIGlmKG51bGwgIT0gbV9yZWxhdGl2ZVBhdGhQYXR0ZXJuKQotICAgICAgICB7Ci0gICAgICAgICAgICAgICAgaWYoIW1fcmVsYXRpdmVQYXRoUGF0dGVybi5kZWVwRXF1YWxzKHNwLm1fcmVsYXRpdmVQYXRoUGF0dGVybikpCi0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZihzcC5tX3JlbGF0aXZlUGF0aFBhdHRlcm4gIT0gbnVsbCkKLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0KLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gIH0KLQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL3BhdHRlcm5zL1VuaW9uUGF0dGVybi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9wYXR0ZXJucy9VbmlvblBhdHRlcm4uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDE5OTE1Ni4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL3BhdHRlcm5zL1VuaW9uUGF0dGVybi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjIwICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFVuaW9uUGF0dGVybi5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzE1IDAwOjIxOjE1IGplZmZzdXR0b3IgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucGF0dGVybnM7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuRXhwcmVzc2lvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuRXhwcmVzc2lvbk93bmVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5YUGF0aENvbnRleHQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoVmlzaXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwub2JqZWN0cy5YT2JqZWN0OwotCi0vKioKLSAqIFRoaXMgY2xhc3MgcmVwcmVzZW50cyBhIHVuaW9uIHBhdHRlcm4sIHdoaWNoIGNhbiBoYXZlIG11bHRpcGxlIGluZGl2aWR1YWwKLSAqIFN0ZXBQYXR0ZXJuIHBhdHRlcm5zLgotICogQHhzbC51c2FnZSBhZHZhbmNlZAotICovCi1wdWJsaWMgY2xhc3MgVW5pb25QYXR0ZXJuIGV4dGVuZHMgRXhwcmVzc2lvbgotewotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNjY3MDQ0OTk2NzExNjkwNTgyMEw7Ci0KLSAgLyoqIEFycmF5IG9mIHRoZSBjb250YWluZWQgc3RlcCBwYXR0ZXJucyB0byBiZSB0ZXN0ZWQuCi0gICAqICBAc2VyaWFsICAqLwotICBwcml2YXRlIFN0ZXBQYXR0ZXJuW10gbV9wYXR0ZXJuczsKLQotICAvKioKLSAgICogTm8gYXJndW1lbnRzIHRvIHByb2Nlc3MsIHNvIHRoaXMgZG9lcyBub3RoaW5nLgotICAgKi8KLSAgcHVibGljIHZvaWQgZml4dXBWYXJpYWJsZXMoamF2YS51dGlsLlZlY3RvciB2YXJzLCBpbnQgZ2xvYmFsc1NpemUpCi0gIHsKLSAgICBmb3IgKGludCBpID0gMDsgaSA8IG1fcGF0dGVybnMubGVuZ3RoOyBpKyspCi0gICAgewotICAgICAgbV9wYXR0ZXJuc1tpXS5maXh1cFZhcmlhYmxlcyh2YXJzLCBnbG9iYWxzU2l6ZSk7Ci0gICAgfQotICB9Ci0KLQotICAvKioKLSAgICogVGVsbCBpZiB0aGlzIGV4cHJlc3Npb24gb3IgaXQncyBzdWJleHByZXNzaW9ucyBjYW4gdHJhdmVyc2Ugb3V0c2lkZQotICAgKiB0aGUgY3VycmVudCBzdWJ0cmVlLgotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYgdHJhdmVyc2FsIG91dHNpZGUgdGhlIGNvbnRleHQgbm9kZSdzIHN1YnRyZWUgY2FuIG9jY3VyLgotICAgKi8KLSAgIHB1YmxpYyBib29sZWFuIGNhblRyYXZlcnNlT3V0c2lkZVN1YnRyZWUoKQotICAgewotICAgICBpZihudWxsICE9IG1fcGF0dGVybnMpCi0gICAgIHsKLSAgICAgIGludCBuID0gbV9wYXR0ZXJucy5sZW5ndGg7Ci0gICAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykKLSAgICAgIHsKLSAgICAgICAgaWYobV9wYXR0ZXJuc1tpXS5jYW5UcmF2ZXJzZU91dHNpZGVTdWJ0cmVlKCkpCi0gICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICB9Ci0gICAgIH0KLSAgICAgcmV0dXJuIGZhbHNlOwotICAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIGNvbnRhaW5lZCBzdGVwIHBhdHRlcm5zIHRvIGJlIHRlc3RlZC4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHBhdHRlcm5zIHRoZSBjb250YWluZWQgc3RlcCBwYXR0ZXJucyB0byBiZSB0ZXN0ZWQuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRQYXR0ZXJucyhTdGVwUGF0dGVybltdIHBhdHRlcm5zKQotICB7Ci0gICAgbV9wYXR0ZXJucyA9IHBhdHRlcm5zOwotICAgIGlmKG51bGwgIT0gcGF0dGVybnMpCi0gICAgewotICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgcGF0dGVybnMubGVuZ3RoOyBpKyspCi0gICAgICAgIHsKLSAgICAgICAgICAgICAgICBwYXR0ZXJuc1tpXS5leHByU2V0UGFyZW50KHRoaXMpOwotICAgICAgICB9Ci0gICAgfQotCi0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBjb250YWluZWQgc3RlcCBwYXR0ZXJucyB0byBiZSB0ZXN0ZWQuCi0gICAqCi0gICAqCi0gICAqIEByZXR1cm4gYW4gYXJyYXkgb2YgdGhlIGNvbnRhaW5lZCBzdGVwIHBhdHRlcm5zIHRvIGJlIHRlc3RlZC4KLSAgICovCi0gIHB1YmxpYyBTdGVwUGF0dGVybltdIGdldFBhdHRlcm5zKCkKLSAgewotICAgIHJldHVybiBtX3BhdHRlcm5zOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlc3QgYSBub2RlIHRvIHNlZSBpZiBpdCBtYXRjaGVzIGFueSBvZiB0aGUgcGF0dGVybnMgaW4gdGhlIHVuaW9uLgotICAgKgotICAgKiBAcGFyYW0geGN0eHQgWFBhdGggcnVudGltZSBjb250ZXh0LgotICAgKgotICAgKiBAcmV0dXJuIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfTk9ERVRFU1R9LAotICAgKiAgICAgICAgIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfTk9ORX0sCi0gICAqICAgICAgICAge0BsaW5rIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5wYXR0ZXJucy5Ob2RlVGVzdCNTQ09SRV9OU1dJTER9LAotICAgKiAgICAgICAgIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfUU5BTUV9LCBvcgotICAgKiAgICAgICAgIHtAbGluayBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfT1RIRVJ9LgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IGV4ZWN1dGUoWFBhdGhDb250ZXh0IHhjdHh0KSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBYT2JqZWN0IGJlc3RTY29yZSA9IG51bGw7Ci0gICAgaW50IG4gPSBtX3BhdHRlcm5zLmxlbmd0aDsKLQotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKQotICAgIHsKLSAgICAgIFhPYmplY3Qgc2NvcmUgPSBtX3BhdHRlcm5zW2ldLmV4ZWN1dGUoeGN0eHQpOwotCi0gICAgICBpZiAoc2NvcmUgIT0gTm9kZVRlc3QuU0NPUkVfTk9ORSkKLSAgICAgIHsKLSAgICAgICAgaWYgKG51bGwgPT0gYmVzdFNjb3JlKQotICAgICAgICAgIGJlc3RTY29yZSA9IHNjb3JlOwotICAgICAgICBlbHNlIGlmIChzY29yZS5udW0oKSA+IGJlc3RTY29yZS5udW0oKSkKLSAgICAgICAgICBiZXN0U2NvcmUgPSBzY29yZTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICBpZiAobnVsbCA9PSBiZXN0U2NvcmUpCi0gICAgewotICAgICAgYmVzdFNjb3JlID0gTm9kZVRlc3QuU0NPUkVfTk9ORTsKLSAgICB9Ci0KLSAgICByZXR1cm4gYmVzdFNjb3JlOwotICB9Ci0KLSAgY2xhc3MgVW5pb25QYXRoUGFydE93bmVyIGltcGxlbWVudHMgRXhwcmVzc2lvbk93bmVyCi0gIHsKLSAgICAgICAgaW50IG1faW5kZXg7Ci0KLSAgICAgICAgVW5pb25QYXRoUGFydE93bmVyKGludCBpbmRleCkKLSAgICAgICAgewotICAgICAgICAgICAgICAgIG1faW5kZXggPSBpbmRleDsKLSAgICAgICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZSBFeHByZXNzaW9uT3duZXIjZ2V0RXhwcmVzc2lvbigpCi0gICAgICovCi0gICAgcHVibGljIEV4cHJlc3Npb24gZ2V0RXhwcmVzc2lvbigpCi0gICAgewotICAgICAgcmV0dXJuIG1fcGF0dGVybnNbbV9pbmRleF07Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBAc2VlIEV4cHJlc3Npb25Pd25lciNzZXRFeHByZXNzaW9uKEV4cHJlc3Npb24pCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RXhwcmVzc2lvbihFeHByZXNzaW9uIGV4cCkKLSAgICB7Ci0gICAgICAgIGV4cC5leHByU2V0UGFyZW50KFVuaW9uUGF0dGVybi50aGlzKTsKLSAgICAgICAgbV9wYXR0ZXJuc1ttX2luZGV4XSA9IChTdGVwUGF0dGVybilleHA7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLlhQYXRoVmlzaXRhYmxlI2NhbGxWaXNpdG9ycyhFeHByZXNzaW9uT3duZXIsIFhQYXRoVmlzaXRvcikKLSAgICovCi0gIHB1YmxpYyB2b2lkIGNhbGxWaXNpdG9ycyhFeHByZXNzaW9uT3duZXIgb3duZXIsIFhQYXRoVmlzaXRvciB2aXNpdG9yKQotICB7Ci0gICAgICAgIHZpc2l0b3IudmlzaXRVbmlvblBhdHRlcm4ob3duZXIsIHRoaXMpOwotICAgICAgICBpZihudWxsICE9IG1fcGF0dGVybnMpCi0gICAgICAgIHsKLSAgICAgICAgICAgICAgICBpbnQgbiA9IG1fcGF0dGVybnMubGVuZ3RoOwotICAgICAgICAgICAgICAgIGZvcihpbnQgaSA9IDA7IGkgPCBuOyBpKyspCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgbV9wYXR0ZXJuc1tpXS5jYWxsVmlzaXRvcnMobmV3IFVuaW9uUGF0aFBhcnRPd25lcihpKSwgdmlzaXRvcik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICB9Ci0gIH0KLQotICAvKioKLSAgICogQHNlZSBFeHByZXNzaW9uI2RlZXBFcXVhbHMoRXhwcmVzc2lvbikKLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGRlZXBFcXVhbHMoRXhwcmVzc2lvbiBleHByKQotICB7Ci0gICAgICAgIGlmKCFpc1NhbWVDbGFzcyhleHByKSkKLSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0KLSAgICAgICAgVW5pb25QYXR0ZXJuIHVwID0gKFVuaW9uUGF0dGVybilleHByOwotCi0gICAgICAgIGlmKG51bGwgIT0gbV9wYXR0ZXJucykKLSAgICAgICAgewotICAgICAgICAgICAgICAgIGludCBuID0gbV9wYXR0ZXJucy5sZW5ndGg7Ci0gICAgICAgICAgICAgICAgaWYoKG51bGwgPT0gdXAubV9wYXR0ZXJucykgfHwgKHVwLm1fcGF0dGVybnMubGVuZ3RoICE9IG4pKQotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotCi0gICAgICAgICAgICAgICAgZm9yKGludCBpID0gMDsgaSA8IG47IGkrKykKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZighbV9wYXR0ZXJuc1tpXS5kZWVwRXF1YWxzKHVwLm1fcGF0dGVybnNbaV0pKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYodXAubV9wYXR0ZXJucyAhPSBudWxsKQotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLQotICAgICAgICByZXR1cm4gdHJ1ZTsKLQotICB9Ci0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9wYXR0ZXJucy9wYWNrYWdlLmh0bWwgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL3BhdHRlcm5zL3BhY2thZ2UuaHRtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMjNiMzc3ZS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL3BhdHRlcm5zL3BhY2thZ2UuaHRtbAorKysgL2Rldi9udWxsCkBAIC0xLDI4ICswLDAgQEAKLTwhLS0KLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0tLT4KLTwhLS0KLSAqIENvcHlyaWdodCAyMDAwLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotLS0+Ci08IS0tICRJZDogcGFja2FnZS5odG1sLHYgMS4xLjIuMSAyMDA1LzA4LzAxIDAxOjMwOjI5IGplZmZzdXR0b3IgRXhwICQgLS0+Ci08aHRtbD4KLSAgPHRpdGxlPlhQYXRoIG5vZGV0ZXN0IGFuZCBYU0xUIHBhdHRlcm4gbWF0Y2hpbmcgc3VwcG9ydC48L3RpdGxlPgotICA8Ym9keT4KLSAgICA8cD5JbXBsZW1lbnRhdGlvbiBvZiBYUGF0aCBub2RlVGVzdCBzdXBwb3J0LCBhbmQgWFNMVCBwYXR0ZXJuIG1hdGNoaW5nIHN1cHBvcnQuPHA+Ci0gPC9ib2R5PgotPC9odG1sPgotCi0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvcmVzL1hQQVRIRXJyb3JSZXNvdXJjZXMuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvcmVzL1hQQVRIRXJyb3JSZXNvdXJjZXMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZjk2NTYxYi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL3Jlcy9YUEFUSEVycm9yUmVzb3VyY2VzLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5MzYgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucmVzOwotCi1pbXBvcnQgamF2YS51dGlsLkxpc3RSZXNvdXJjZUJ1bmRsZTsKLQotLyoqCi0gKiBTZXQgdXAgZXJyb3IgbWVzc2FnZXMuCi0gKiBXZSBidWlsZCBhIHR3byBkaW1lbnNpb25hbCBhcnJheSBvZiBtZXNzYWdlIGtleXMgYW5kCi0gKiBtZXNzYWdlIHN0cmluZ3MuIEluIG9yZGVyIHRvIGFkZCBhIG5ldyBtZXNzYWdlIGhlcmUsCi0gKiB5b3UgbmVlZCB0byBmaXJzdCBhZGQgYSBTdGF0aWMgc3RyaW5nIGNvbnN0YW50IGZvciB0aGUKLSAqIEtleSBhbmQgdXBkYXRlIHRoZSBjb250ZW50cyBhcnJheSB3aXRoIEtleSwgVmFsdWUgcGFpcgotICAqIEFsc28geW91IG5lZWQgdG8gIHVwZGF0ZSB0aGUgY291bnQgb2YgbWVzc2FnZXMoTUFYX0NPREUpb3IKLSAqIHRoZSBjb3VudCBvZiB3YXJuaW5ncyhNQVhfV0FSTklORykgWyBJbmZvcm1hdGlvbiBwdXJwb3NlIG9ubHldCi0gKiBAeHNsLnVzYWdlIGFkdmFuY2VkCi0gKi8KLXB1YmxpYyBjbGFzcyBYUEFUSEVycm9yUmVzb3VyY2VzIGV4dGVuZHMgTGlzdFJlc291cmNlQnVuZGxlCi17Ci0KLS8qCi0gKiBHZW5lcmFsIG5vdGVzIHRvIHRyYW5zbGF0b3JzOgotICoKLSAqIFRoaXMgZmlsZSBjb250YWlucyBlcnJvciBhbmQgd2FybmluZyBtZXNzYWdlcyByZWxhdGVkIHRvIFhQYXRoIEVycm9yCi0gKiBIYW5kbGluZy4KLSAqCi0gKiAgMSkgWGFsYW4gKG9yIG1vcmUgcHJvcGVybHksIFhhbGFuLWludGVycHJldGl2ZSkgYW5kIFhTTFRDIGFyZSBuYW1lcyBvZgotICogICAgIGNvbXBvbmVudHMuCi0gKiAgICAgWFNMVCBpcyBhbiBhY3JvbnltIGZvciAiWE1MIFN0eWxlc2hlZXQgTGFuZ3VhZ2U6IFRyYW5zZm9ybWF0aW9ucyIuCi0gKiAgICAgWFNMVEMgaXMgYW4gYWNyb255bSBmb3IgWFNMVCBDb21waWxlci4KLSAqCi0gKiAgMikgQSBzdHlsZXNoZWV0IGlzIGEgZGVzY3JpcHRpb24gb2YgaG93IHRvIHRyYW5zZm9ybSBhbiBpbnB1dCBYTUwgZG9jdW1lbnQKLSAqICAgICBpbnRvIGEgcmVzdWx0YW50IFhNTCBkb2N1bWVudCAob3IgSFRNTCBkb2N1bWVudCBvciB0ZXh0KS4gIFRoZQotICogICAgIHN0eWxlc2hlZXQgaXRzZWxmIGlzIGRlc2NyaWJlZCBpbiB0aGUgZm9ybSBvZiBhbiBYTUwgZG9jdW1lbnQuCi0gKgotICogIDMpIEEgdGVtcGxhdGUgaXMgYSBjb21wb25lbnQgb2YgYSBzdHlsZXNoZWV0IHRoYXQgaXMgdXNlZCB0byBtYXRjaCBhCi0gKiAgICAgcGFydGljdWxhciBwb3J0aW9uIG9mIGFuIGlucHV0IGRvY3VtZW50IGFuZCBzcGVjaWZpZXMgdGhlIGZvcm0gb2YgdGhlCi0gKiAgICAgY29ycmVzcG9uZGluZyBwb3J0aW9uIG9mIHRoZSBvdXRwdXQgZG9jdW1lbnQuCi0gKgotICogIDQpIEFuIGVsZW1lbnQgaXMgYSBtYXJrLXVwIHRhZyBpbiBhbiBYTUwgZG9jdW1lbnQ7IGFuIGF0dHJpYnV0ZSBpcyBhCi0gKiAgICAgbW9kaWZpZXIgb24gdGhlIHRhZy4gIEZvciBleGFtcGxlLCBpbiA8ZWxlbSBhdHRyPSd2YWwnIGF0dHIyPSd2YWwyJz4KLSAqICAgICAiZWxlbSIgaXMgYW4gZWxlbWVudCBuYW1lLCAiYXR0ciIgYW5kICJhdHRyMiIgYXJlIGF0dHJpYnV0ZSBuYW1lcyB3aXRoCi0gKiAgICAgdGhlIHZhbHVlcyAidmFsIiBhbmQgInZhbDIiLCByZXNwZWN0aXZlbHkuCi0gKgotICogIDUpIEEgbmFtZXNwYWNlIGRlY2xhcmF0aW9uIGlzIGEgc3BlY2lhbCBhdHRyaWJ1dGUgdGhhdCBpcyB1c2VkIHRvIGFzc29jaWF0ZQotICogICAgIGEgcHJlZml4IHdpdGggYSBVUkkgKHRoZSBuYW1lc3BhY2UpLiAgVGhlIG1lYW5pbmdzIG9mIGVsZW1lbnQgbmFtZXMgYW5kCi0gKiAgICAgYXR0cmlidXRlIG5hbWVzIHRoYXQgdXNlIHRoYXQgcHJlZml4IGFyZSBkZWZpbmVkIHdpdGggcmVzcGVjdCB0byB0aGF0Ci0gKiAgICAgbmFtZXNwYWNlLgotICoKLSAqICA2KSAiVHJhbnNsZXQiIGlzIGFuIGludmVudGVkIHRlcm0gdGhhdCBkZXNjcmliZXMgdGhlIGNsYXNzIGZpbGUgdGhhdAotICogICAgIHJlc3VsdHMgZnJvbSBjb21waWxpbmcgYW4gWE1MIHN0eWxlc2hlZXQgaW50byBhIEphdmEgY2xhc3MuCi0gKgotICogIDcpIFhQYXRoIGlzIGEgc3BlY2lmaWNhdGlvbiB0aGF0IGRlc2NyaWJlcyBhIG5vdGF0aW9uIGZvciBpZGVudGlmeWluZwotICogICAgIG5vZGVzIGluIGEgdHJlZS1zdHJ1Y3R1cmVkIHJlcHJlc2VudGF0aW9uIG9mIGFuIFhNTCBkb2N1bWVudC4gIEFuCi0gKiAgICAgaW5zdGFuY2Ugb2YgdGhhdCBub3RhdGlvbiBpcyByZWZlcnJlZCB0byBhcyBhbiBYUGF0aCBleHByZXNzaW9uLgotICoKLSAqICA4KSBUaGUgY29udGV4dCBub2RlIGlzIHRoZSBub2RlIGluIHRoZSBkb2N1bWVudCB3aXRoIHJlc3BlY3QgdG8gd2hpY2ggYW4KLSAqICAgICBYUGF0aCBleHByZXNzaW9uIGlzIGJlaW5nIGV2YWx1YXRlZC4KLSAqCi0gKiAgOSkgQW4gaXRlcmF0b3IgaXMgYW4gb2JqZWN0IHRoYXQgdHJhdmVyc2VzIG5vZGVzIGluIHRoZSB0cmVlLCBvbmUgYXQgYSB0aW1lLgotICoKLSAqICAxMCkgTkNOYW1lIGlzIGFuIFhNTCB0ZXJtIHVzZWQgdG8gZGVzY3JpYmUgYSBuYW1lIHRoYXQgZG9lcyBub3QgY29udGFpbiBhCi0gKiAgICAgY29sb24gKGEgIm5vLWNvbG9uIG5hbWUiKS4KLSAqCi0gKiAgMTEpIFFOYW1lIGlzIGFuIFhNTCB0ZXJtIG1lYW5pbmcgInF1YWxpZmllZCBuYW1lIi4KLSAqLwotCi0gIC8qCi0gICAqIHN0YXRpYyB2YXJpYWJsZXMKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUk9SMDAwMCA9ICJFUlJPUjAwMDAiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DVVJSRU5UX05PVF9BTExPV0VEX0lOX01BVENIID0KLSAgICAgICAgICJFUl9DVVJSRU5UX05PVF9BTExPV0VEX0lOX01BVENIIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ1VSUkVOVF9UQUtFU19OT19BUkdTID0KLSAgICAgICAgICJFUl9DVVJSRU5UX1RBS0VTX05PX0FSR1MiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9ET0NVTUVOVF9SRVBMQUNFRCA9ICJFUl9ET0NVTUVOVF9SRVBMQUNFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPTlRFWFRfSEFTX05PX09XTkVSRE9DID0KLSAgICAgICAgICJFUl9DT05URVhUX0hBU19OT19PV05FUkRPQyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0xPQ0FMTkFNRV9IQVNfVE9PX01BTllfQVJHUyA9Ci0gICAgICAgICAiRVJfTE9DQUxOQU1FX0hBU19UT09fTUFOWV9BUkdTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTkFNRVNQQUNFVVJJX0hBU19UT09fTUFOWV9BUkdTID0KLSAgICAgICAgICJFUl9OQU1FU1BBQ0VVUklfSEFTX1RPT19NQU5ZX0FSR1MiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT1JNQUxJWkVTUEFDRV9IQVNfVE9PX01BTllfQVJHUyA9Ci0gICAgICAgICAiRVJfTk9STUFMSVpFU1BBQ0VfSEFTX1RPT19NQU5ZX0FSR1MiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OVU1CRVJfSEFTX1RPT19NQU5ZX0FSR1MgPQotICAgICAgICAgIkVSX05VTUJFUl9IQVNfVE9PX01BTllfQVJHUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05BTUVfSEFTX1RPT19NQU5ZX0FSR1MgPQotICAgICAgICAgIkVSX05BTUVfSEFTX1RPT19NQU5ZX0FSR1MiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TVFJJTkdfSEFTX1RPT19NQU5ZX0FSR1MgPQotICAgICAgICAgIkVSX1NUUklOR19IQVNfVE9PX01BTllfQVJHUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NUUklOR0xFTkdUSF9IQVNfVE9PX01BTllfQVJHUyA9Ci0gICAgICAgICAiRVJfU1RSSU5HTEVOR1RIX0hBU19UT09fTUFOWV9BUkdTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVFJBTlNMQVRFX1RBS0VTXzNfQVJHUyA9Ci0gICAgICAgICAiRVJfVFJBTlNMQVRFX1RBS0VTXzNfQVJHUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1VOUEFSU0VERU5USVRZVVJJX1RBS0VTXzFfQVJHID0KLSAgICAgICAgICJFUl9VTlBBUlNFREVOVElUWVVSSV9UQUtFU18xX0FSRyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05BTUVTUEFDRUFYSVNfTk9UX0lNUExFTUVOVEVEID0KLSAgICAgICAgICJFUl9OQU1FU1BBQ0VBWElTX05PVF9JTVBMRU1FTlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1VOS05PV05fQVhJUyA9ICJFUl9VTktOT1dOX0FYSVMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTktOT1dOX01BVENIX09QRVJBVElPTiA9Ci0gICAgICAgICAiRVJfVU5LTk9XTl9NQVRDSF9PUEVSQVRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTkNPUlJFQ1RfQVJHX0xFTkdUSCA9IkVSX0lOQ09SUkVDVF9BUkdfTEVOR1RIIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9DT05WRVJUX1RPX05VTUJFUiA9Ci0gICAgICAgICAiRVJfQ0FOVF9DT05WRVJUX1RPX05VTUJFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfQ09OVkVSVF9YUEFUSFJFU1VMVFRZUEVfVE9fTlVNQkVSID0KLSAgICAgICAgICAgIkVSX0NBTlRfQ09OVkVSVF9YUEFUSFJFU1VMVFRZUEVfVE9fTlVNQkVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9DT05WRVJUX1RPX05PREVMSVNUID0KLSAgICAgICAgICJFUl9DQU5UX0NPTlZFUlRfVE9fTk9ERUxJU1QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX0NPTlZFUlRfVE9fTVVUQUJMRU5PREVMSVNUID0KLSAgICAgICAgICJFUl9DQU5UX0NPTlZFUlRfVE9fTVVUQUJMRU5PREVMSVNUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9DT05WRVJUX1RPX1RZUEUgPSJFUl9DQU5UX0NPTlZFUlRfVE9fVFlQRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYUEVDVEVEX01BVENIX1BBVFRFUk4gPQotICAgICAgICAgIkVSX0VYUEVDVEVEX01BVENIX1BBVFRFUk4iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRE5PVF9HRVRfVkFSX05BTUVEID0KLSAgICAgICAgICJFUl9DT1VMRE5PVF9HRVRfVkFSX05BTUVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5LTk9XTl9PUENPREUgPSAiRVJfVU5LTk9XTl9PUENPREUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FWFRSQV9JTExFR0FMX1RPS0VOUyA9IkVSX0VYVFJBX0lMTEVHQUxfVE9LRU5TIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhQRUNURURfRE9VQkxFX1FVT1RFID0KLSAgICAgICAgICJFUl9FWFBFQ1RFRF9ET1VCTEVfUVVPVEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FWFBFQ1RFRF9TSU5HTEVfUVVPVEUgPQotICAgICAgICAgIkVSX0VYUEVDVEVEX1NJTkdMRV9RVU9URSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VNUFRZX0VYUFJFU1NJT04gPSAiRVJfRU1QVFlfRVhQUkVTU0lPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYUEVDVEVEX0JVVF9GT1VORCA9ICJFUl9FWFBFQ1RFRF9CVVRfRk9VTkQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTkNPUlJFQ1RfUFJPR1JBTU1FUl9BU1NFUlRJT04gPQotICAgICAgICAgIkVSX0lOQ09SUkVDVF9QUk9HUkFNTUVSX0FTU0VSVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0JPT0xFQU5fQVJHX05PX0xPTkdFUl9PUFRJT05BTCA9Ci0gICAgICAgICAiRVJfQk9PTEVBTl9BUkdfTk9fTE9OR0VSX09QVElPTkFMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRk9VTkRfQ09NTUFfQlVUX05PX1BSRUNFRElOR19BUkcgPQotICAgICAgICAgIkVSX0ZPVU5EX0NPTU1BX0JVVF9OT19QUkVDRURJTkdfQVJHIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRk9VTkRfQ09NTUFfQlVUX05PX0ZPTExPV0lOR19BUkcgPQotICAgICAgICAgIkVSX0ZPVU5EX0NPTU1BX0JVVF9OT19GT0xMT1dJTkdfQVJHIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJFRElDQVRFX0lMTEVHQUxfU1lOVEFYID0KLSAgICAgICAgICJFUl9QUkVESUNBVEVfSUxMRUdBTF9TWU5UQVgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTExFR0FMX0FYSVNfTkFNRSA9ICJFUl9JTExFR0FMX0FYSVNfTkFNRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1VOS05PV05fTk9ERVRZUEUgPSAiRVJfVU5LTk9XTl9OT0RFVFlQRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BBVFRFUk5fTElURVJBTF9ORUVEU19CRV9RVU9URUQgPQotICAgICAgICAgIkVSX1BBVFRFUk5fTElURVJBTF9ORUVEU19CRV9RVU9URUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRE5PVF9CRV9GT1JNQVRURURfVE9fTlVNQkVSID0KLSAgICAgICAgICJFUl9DT1VMRE5PVF9CRV9GT1JNQVRURURfVE9fTlVNQkVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTEROT1RfQ1JFQVRFX1hNTFBST0NFU1NPUkxJQUlTT04gPQotICAgICAgICAgIkVSX0NPVUxETk9UX0NSRUFURV9YTUxQUk9DRVNTT1JMSUFJU09OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRElETk9UX0ZJTkRfWFBBVEhfU0VMRUNUX0VYUCA9Ci0gICAgICAgICAiRVJfRElETk9UX0ZJTkRfWFBBVEhfU0VMRUNUX0VYUCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxETk9UX0ZJTkRfRU5ET1BfQUZURVJfT1BMT0NBVElPTlBBVEggPQotICAgICAgICAgIkVSX0NPVUxETk9UX0ZJTkRfRU5ET1BfQUZURVJfT1BMT0NBVElPTlBBVEgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FUlJPUl9PQ0NVUkVEID0gIkVSX0VSUk9SX09DQ1VSRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTExFR0FMX1ZBUklBQkxFX1JFRkVSRU5DRSA9Ci0gICAgICAgICAiRVJfSUxMRUdBTF9WQVJJQUJMRV9SRUZFUkVOQ0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9BWEVTX05PVF9BTExPV0VEID0gIkVSX0FYRVNfTk9UX0FMTE9XRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9LRVlfSEFTX1RPT19NQU5ZX0FSR1MgPQotICAgICAgICAgIkVSX0tFWV9IQVNfVE9PX01BTllfQVJHUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVU5UX1RBS0VTXzFfQVJHID0gIkVSX0NPVU5UX1RBS0VTXzFfQVJHIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTEROT1RfRklORF9GVU5DVElPTiA9Ci0gICAgICAgICAiRVJfQ09VTEROT1RfRklORF9GVU5DVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1VOU1VQUE9SVEVEX0VOQ09ESU5HID0iRVJfVU5TVVBQT1JURURfRU5DT0RJTkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUk9CTEVNX0lOX0RUTV9ORVhUU0lCTElORyA9Ci0gICAgICAgICAiRVJfUFJPQkxFTV9JTl9EVE1fTkVYVFNJQkxJTkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfV1JJVEVfVE9fRU1QVFlOT0RFTElTVElNUEwgPQotICAgICAgICAgIkVSX0NBTk5PVF9XUklURV9UT19FTVBUWU5PREVMSVNUSU1QTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NFVERPTUZBQ1RPUllfTk9UX1NVUFBPUlRFRCA9Ci0gICAgICAgICAiRVJfU0VURE9NRkFDVE9SWV9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJFRklYX01VU1RfUkVTT0xWRSA9ICJFUl9QUkVGSVhfTVVTVF9SRVNPTFZFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUEFSU0VfTk9UX1NVUFBPUlRFRCA9ICJFUl9QQVJTRV9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU0FYX0FQSV9OT1RfSEFORExFRCA9ICJFUl9TQVhfQVBJX05PVF9IQU5ETEVEIjsKLXB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lHTk9SQUJMRV9XSElURVNQQUNFX05PVF9IQU5ETEVEID0KLSAgICAgICAgICJFUl9JR05PUkFCTEVfV0hJVEVTUEFDRV9OT1RfSEFORExFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0RUTV9DQU5OT1RfSEFORExFX05PREVTID0KLSAgICAgICAgICJFUl9EVE1fQ0FOTk9UX0hBTkRMRV9OT0RFUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hFUkNFU19DQU5OT1RfSEFORExFX05PREVTID0KLSAgICAgICAgICJFUl9YRVJDRVNfQ0FOTk9UX0hBTkRMRV9OT0RFUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hFUkNFU19QQVJTRV9FUlJPUl9ERVRBSUxTID0KLSAgICAgICAgICJFUl9YRVJDRVNfUEFSU0VfRVJST1JfREVUQUlMUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hFUkNFU19QQVJTRV9FUlJPUiA9ICJFUl9YRVJDRVNfUEFSU0VfRVJST1IiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX1VURjE2X1NVUlJPR0FURSA9Ci0gICAgICAgICAiRVJfSU5WQUxJRF9VVEYxNl9TVVJST0dBVEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9PSUVSUk9SID0gIkVSX09JRVJST1IiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfQ1JFQVRFX1VSTCA9ICJFUl9DQU5OT1RfQ1JFQVRFX1VSTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hQQVRIX1JFQURPQkpFQ1QgPSAiRVJfWFBBVEhfUkVBRE9CSkVDVCI7Ci0gcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRlVOQ1RJT05fVE9LRU5fTk9UX0ZPVU5EID0KLSAgICAgICAgICJFUl9GVU5DVElPTl9UT0tFTl9OT1RfRk9VTkQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfREVBTF9YUEFUSF9UWVBFID0KLSAgICAgICAgICJFUl9DQU5OT1RfREVBTF9YUEFUSF9UWVBFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9ERVNFVF9OT1RfTVVUQUJMRSA9ICJFUl9OT0RFU0VUX05PVF9NVVRBQkxFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9ERVNFVERUTV9OT1RfTVVUQUJMRSA9Ci0gICAgICAgICAiRVJfTk9ERVNFVERUTV9OT1RfTVVUQUJMRSI7Ci0gICAvKiogIFZhcmlhYmxlIG5vdCByZXNvbHZhYmxlOiAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1ZBUl9OT1RfUkVTT0xWQUJMRSA9ICJFUl9WQVJfTk9UX1JFU09MVkFCTEUiOwotICAgLyoqIE51bGwgZXJyb3IgaGFuZGxlciAgKi8KLSBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OVUxMX0VSUk9SX0hBTkRMRVIgPSAiRVJfTlVMTF9FUlJPUl9IQU5ETEVSIjsKLSAgIC8qKiAgUHJvZ3JhbW1lcidzIGFzc2VydGlvbjogdW5rbm93biBvcGNvZGUgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BST0dfQVNTRVJUX1VOS05PV05fT1BDT0RFID0KLSAgICAgICAgICJFUl9QUk9HX0FTU0VSVF9VTktOT1dOX09QQ09ERSI7Ci0gICAvKiogIDAgb3IgMSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1pFUk9fT1JfT05FID0gIkVSX1pFUk9fT1JfT05FIjsKLSAgIC8qKiAgcnRmKCkgbm90IHN1cHBvcnRlZCBieSBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1JURl9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSID0KLSAgICAgICAgICJFUl9SVEZfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiI7Ci0gICAvKiogIGFzTm9kZUl0ZXJhdG9yKCkgbm90IHN1cHBvcnRlZCBieSBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FTTk9ERUlURVJBVE9SX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIgPSAiRVJfQVNOT0RFSVRFUkFUT1JfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiI7Ci0gICAvKiogIGZzYigpIG5vdCBzdXBwb3J0ZWQgZm9yIFhTdHJpbmdGb3JDaGFycyAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZTQl9OT1RfU1VQUE9SVEVEX1hTVFJJTkdGT1JDSEFSUyA9Ci0gICAgICAgICAiRVJfRlNCX05PVF9TVVBQT1JURURfWFNUUklOR0ZPUkNIQVJTIjsKLSAgIC8qKiAgQ291bGQgbm90IGZpbmQgdmFyaWFibGUgd2l0aCB0aGUgbmFtZSBvZiAgICovCi0gcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTERfTk9UX0ZJTkRfVkFSID0gIkVSX0NPVUxEX05PVF9GSU5EX1ZBUiI7Ci0gICAvKiogIFhTdHJpbmdGb3JDaGFycyBjYW4gbm90IHRha2UgYSBzdHJpbmcgZm9yIGFuIGFyZ3VtZW50ICAgKi8KLSBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YU1RSSU5HRk9SQ0hBUlNfQ0FOTk9UX1RBS0VfU1RSSU5HID0KLSAgICAgICAgICJFUl9YU1RSSU5HRk9SQ0hBUlNfQ0FOTk9UX1RBS0VfU1RSSU5HIjsKLSAgIC8qKiAgVGhlIEZhc3RTdHJpbmdCdWZmZXIgYXJndW1lbnQgY2FuIG5vdCBiZSBudWxsICAgKi8KLSBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GQVNUU1RSSU5HQlVGRkVSX0NBTk5PVF9CRV9OVUxMID0KLSAgICAgICAgICJFUl9GQVNUU1RSSU5HQlVGRkVSX0NBTk5PVF9CRV9OVUxMIjsKLSAgIC8qKiAgMiBvciAzICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVFdPX09SX1RIUkVFID0gIkVSX1RXT19PUl9USFJFRSI7Ci0gICAvKiogVmFyaWFibGUgYWNjZXNzZWQgYmVmb3JlIGl0IGlzIGJvdW5kISAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9WQVJJQUJMRV9BQ0NFU1NFRF9CRUZPUkVfQklORCA9Ci0gICAgICAgICAiRVJfVkFSSUFCTEVfQUNDRVNTRURfQkVGT1JFX0JJTkQiOwotICAgLyoqIFhTdHJpbmdGb3JGU0IgY2FuIG5vdCB0YWtlIGEgc3RyaW5nIGZvciBhbiBhcmd1bWVudCEgKi8KLSBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GU0JfQ0FOTk9UX1RBS0VfU1RSSU5HID0KLSAgICAgICAgICJFUl9GU0JfQ0FOTk9UX1RBS0VfU1RSSU5HIjsKLSAgIC8qKiBFcnJvciEgU2V0dGluZyB0aGUgcm9vdCBvZiBhIHdhbGtlciB0byBudWxsISAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TRVRUSU5HX1dBTEtFUl9ST09UX1RPX05VTEwgPQotICAgICAgICAgIkVSX1NFVFRJTkdfV0FMS0VSX1JPT1RfVE9fTlVMTCI7Ci0gICAvKiogVGhpcyBOb2RlU2V0RFRNIGNhbiBub3QgaXRlcmF0ZSB0byBhIHByZXZpb3VzIG5vZGUhICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PREVTRVREVE1fQ0FOTk9UX0lURVJBVEUgPQotICAgICAgICAgIkVSX05PREVTRVREVE1fQ0FOTk9UX0lURVJBVEUiOwotICAvKiogVGhpcyBOb2RlU2V0IGNhbiBub3QgaXRlcmF0ZSB0byBhIHByZXZpb3VzIG5vZGUhICovCi0gcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9ERVNFVF9DQU5OT1RfSVRFUkFURSA9Ci0gICAgICAgICAiRVJfTk9ERVNFVF9DQU5OT1RfSVRFUkFURSI7Ci0gIC8qKiBUaGlzIE5vZGVTZXREVE0gY2FuIG5vdCBkbyBpbmRleGluZyBvciBjb3VudGluZyBmdW5jdGlvbnMhICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PREVTRVREVE1fQ0FOTk9UX0lOREVYID0KLSAgICAgICAgICJFUl9OT0RFU0VURFRNX0NBTk5PVF9JTkRFWCI7Ci0gIC8qKiBUaGlzIE5vZGVTZXQgY2FuIG5vdCBkbyBpbmRleGluZyBvciBjb3VudGluZyBmdW5jdGlvbnMhICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PREVTRVRfQ0FOTk9UX0lOREVYID0KLSAgICAgICAgICJFUl9OT0RFU0VUX0NBTk5PVF9JTkRFWCI7Ci0gIC8qKiBDYW4gbm90IGNhbGwgc2V0U2hvdWxkQ2FjaGVOb2RlcyBhZnRlciBuZXh0Tm9kZSBoYXMgYmVlbiBjYWxsZWQhICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9DQUxMX1NFVFNIT1VMRENBQ0hFTk9ERSA9Ci0gICAgICAgICAiRVJfQ0FOTk9UX0NBTExfU0VUU0hPVUxEQ0FDSEVOT0RFIjsKLSAgLyoqIHswfSBvbmx5IGFsbG93cyB7MX0gYXJndW1lbnRzICovCi0gcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfT05MWV9BTExPV1MgPSAiRVJfT05MWV9BTExPV1MiOwotICAvKiogUHJvZ3JhbW1lcidzIGFzc2VydGlvbiBpbiBnZXROZXh0U3RlcFBvczogdW5rbm93biBzdGVwVHlwZTogezB9ICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1VOS05PV05fU1RFUCA9ICJFUl9VTktOT1dOX1NURVAiOwotICAvKiogUHJvYmxlbSB3aXRoIFJlbGF0aXZlTG9jYXRpb25QYXRoICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYUEVDVEVEX1JFTF9MT0NfUEFUSCA9Ci0gICAgICAgICAiRVJfRVhQRUNURURfUkVMX0xPQ19QQVRIIjsKLSAgLyoqIFByb2JsZW0gd2l0aCBMb2NhdGlvblBhdGggKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhQRUNURURfTE9DX1BBVEggPSAiRVJfRVhQRUNURURfTE9DX1BBVEgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FWFBFQ1RFRF9MT0NfUEFUSF9BVF9FTkRfRVhQUiA9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkVSX0VYUEVDVEVEX0xPQ19QQVRIX0FUX0VORF9FWFBSIjsKLSAgLyoqIFByb2JsZW0gd2l0aCBTdGVwICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYUEVDVEVEX0xPQ19TVEVQID0gIkVSX0VYUEVDVEVEX0xPQ19TVEVQIjsKLSAgLyoqIFByb2JsZW0gd2l0aCBOb2RlVGVzdCAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FWFBFQ1RFRF9OT0RFX1RFU1QgPSAiRVJfRVhQRUNURURfTk9ERV9URVNUIjsKLSAgLyoqIEV4cGVjdGVkIHN0ZXAgcGF0dGVybiAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FWFBFQ1RFRF9TVEVQX1BBVFRFUk4gPQotICAgICAgICAiRVJfRVhQRUNURURfU1RFUF9QQVRURVJOIjsKLSAgLyoqIEV4cGVjdGVkIHJlbGF0aXZlIHBhdGggcGF0dGVybiAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FWFBFQ1RFRF9SRUxfUEFUSF9QQVRURVJOID0KLSAgICAgICAgICJFUl9FWFBFQ1RFRF9SRUxfUEFUSF9QQVRURVJOIjsKLSAgLyoqIEVSX0NBTlRfQ09OVkVSVF9YUEFUSFJFU1VMVFRZUEVfVE9fQk9PTEVBTiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX0NPTlZFUlRfVE9fQk9PTEVBTiA9Ci0gICAgICAgICAiRVJfQ0FOVF9DT05WRVJUX1RPX0JPT0xFQU4iOwotICAvKiogRmllbGQgRVJfQ0FOVF9DT05WRVJUX1RPX1NJTkdMRU5PREUgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9DT05WRVJUX1RPX1NJTkdMRU5PREUgPQotICAgICAgICAgIkVSX0NBTlRfQ09OVkVSVF9UT19TSU5HTEVOT0RFIjsKLSAgLyoqIEZpZWxkIEVSX0NBTlRfR0VUX1NOQVBTSE9UX0xFTkdUSCAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfR0VUX1NOQVBTSE9UX0xFTkdUSCA9Ci0gICAgICAgICAiRVJfQ0FOVF9HRVRfU05BUFNIT1RfTEVOR1RIIjsKLSAgLyoqIEZpZWxkIEVSX05PTl9JVEVSQVRPUl9UWVBFICAgICAgICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PTl9JVEVSQVRPUl9UWVBFID0gIkVSX05PTl9JVEVSQVRPUl9UWVBFIjsKLSAgLyoqIEZpZWxkIEVSX0RPQ19NVVRBVEVEICAgICAgICAgICAgICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0RPQ19NVVRBVEVEID0gIkVSX0RPQ19NVVRBVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9YUEFUSF9UWVBFID0gIkVSX0lOVkFMSURfWFBBVEhfVFlQRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VNUFRZX1hQQVRIX1JFU1VMVCA9ICJFUl9FTVBUWV9YUEFUSF9SRVNVTFQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTkNPTVBBVElCTEVfVFlQRVMgPSAiRVJfSU5DT01QQVRJQkxFX1RZUEVTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTlVMTF9SRVNPTFZFUiA9ICJFUl9OVUxMX1JFU09MVkVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9DT05WRVJUX1RPX1NUUklORyA9Ci0gICAgICAgICAiRVJfQ0FOVF9DT05WRVJUX1RPX1NUUklORyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PTl9TTkFQU0hPVF9UWVBFID0gIkVSX05PTl9TTkFQU0hPVF9UWVBFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfV1JPTkdfRE9DVU1FTlQgPSAiRVJfV1JPTkdfRE9DVU1FTlQiOwotICAvKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIFhQYXRoIGV4cHJlc3Npb24gY2Fubm90IGJlIGV2YWx1YXRlZCB3aXRoIHJlc3BlY3QKLSAgICogdG8gdGhpcyB0eXBlIG9mIG5vZGUuCi0gICAqLwotICAvKiogRmllbGQgRVJfV1JPTkdfTk9ERVRZUEUgICAgICAgICAgICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1dST05HX05PREVUWVBFID0gIkVSX1dST05HX05PREVUWVBFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWFBBVEhfRVJST1IgPSAiRVJfWFBBVEhfRVJST1IiOwotCi0gIC8vQkVHSU46IEtleXMgbmVlZGVkIGZvciBleGNlcHRpb24gbWVzc2FnZXMgb2YgIEpBWFAgMS4zIFhQYXRoIEFQSSBpbXBsZW1lbnRhdGlvbgotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FWFRFTlNJT05fRlVOQ1RJT05fQ0FOTk9UX0JFX0lOVk9LRUQgPSAiRVJfRVhURU5TSU9OX0ZVTkNUSU9OX0NBTk5PVF9CRV9JTlZPS0VEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUkVTT0xWRV9WQVJJQUJMRV9SRVRVUk5TX05VTEwgPSAiRVJfUkVTT0xWRV9WQVJJQUJMRV9SRVRVUk5TX05VTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTlNVUFBPUlRFRF9SRVRVUk5fVFlQRSA9ICJFUl9VTlNVUFBPUlRFRF9SRVRVUk5fVFlQRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NPVVJDRV9SRVRVUk5fVFlQRV9DQU5OT1RfQkVfTlVMTCA9ICJFUl9TT1VSQ0VfUkVUVVJOX1RZUEVfQ0FOTk9UX0JFX05VTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9BUkdfQ0FOTk9UX0JFX05VTEwgPSAiRVJfQVJHX0NBTk5PVF9CRV9OVUxMIjsKLQotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9PQkpFQ1RfTU9ERUxfTlVMTCA9ICJFUl9PQkpFQ1RfTU9ERUxfTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX09CSkVDVF9NT0RFTF9FTVBUWSA9ICJFUl9PQkpFQ1RfTU9ERUxfRU1QVFkiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GRUFUVVJFX05BTUVfTlVMTCA9ICJFUl9GRUFUVVJFX05BTUVfTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZFQVRVUkVfVU5LTk9XTiA9ICJFUl9GRUFUVVJFX1VOS05PV04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9HRVRUSU5HX05VTExfRkVBVFVSRSA9ICJFUl9HRVRUSU5HX05VTExfRkVBVFVSRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0dFVFRJTkdfVU5LTk9XTl9GRUFUVVJFID0gIkVSX0dFVFRJTkdfVU5LTk9XTl9GRUFUVVJFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU0VDVVJFUFJPQ0VTU0lOR19GRUFUVVJFID0gIkVSX1NFQ1VSRVBST0NFU1NJTkdfRkVBVFVSRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05VTExfWFBBVEhfRlVOQ1RJT05fUkVTT0xWRVIgPSAiRVJfTlVMTF9YUEFUSF9GVU5DVElPTl9SRVNPTFZFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05VTExfWFBBVEhfVkFSSUFCTEVfUkVTT0xWRVIgPSAiRVJfTlVMTF9YUEFUSF9WQVJJQUJMRV9SRVNPTFZFUiI7Ci0gIC8vRU5EOiBLZXlzIG5lZWRlZCBmb3IgZXhjZXB0aW9uIG1lc3NhZ2VzIG9mICBKQVhQIDEuMyBYUGF0aCBBUEkgaW1wbGVtZW50YXRpb24KLQotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19MT0NBTEVfTkFNRV9OT1RfSEFORExFRCA9Ci0gICAgICAgICAiV0dfTE9DQUxFX05BTUVfTk9UX0hBTkRMRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19QUk9QRVJUWV9OT1RfU1VQUE9SVEVEID0KLSAgICAgICAgICJXR19QUk9QRVJUWV9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfRE9OVF9ET19BTllUSElOR19XSVRIX05TID0KLSAgICAgICAgICJXR19ET05UX0RPX0FOWVRISU5HX1dJVEhfTlMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19TRUNVUklUWV9FWENFUFRJT04gPSAiV0dfU0VDVVJJVFlfRVhDRVBUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfUVVPX05PX0xPTkdFUl9ERUZJTkVEID0KLSAgICAgICAgICJXR19RVU9fTk9fTE9OR0VSX0RFRklORUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19ORUVEX0RFUklWRURfT0JKRUNUX1RPX0lNUExFTUVOVF9OT0RFVEVTVCA9Ci0gICAgICAgICAiV0dfTkVFRF9ERVJJVkVEX09CSkVDVF9UT19JTVBMRU1FTlRfTk9ERVRFU1QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19GVU5DVElPTl9UT0tFTl9OT1RfRk9VTkQgPQotICAgICAgICAgIldHX0ZVTkNUSU9OX1RPS0VOX05PVF9GT1VORCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0NPVUxETk9UX0ZJTkRfRlVOQ1RJT04gPQotICAgICAgICAgIldHX0NPVUxETk9UX0ZJTkRfRlVOQ1RJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19DQU5OT1RfTUFLRV9VUkxfRlJPTSA9IldHX0NBTk5PVF9NQUtFX1VSTF9GUk9NIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfRVhQQU5EX0VOVElUSUVTX05PVF9TVVBQT1JURUQgPQotICAgICAgICAgIldHX0VYUEFORF9FTlRJVElFU19OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfSUxMRUdBTF9WQVJJQUJMRV9SRUZFUkVOQ0UgPQotICAgICAgICAgIldHX0lMTEVHQUxfVkFSSUFCTEVfUkVGRVJFTkNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfVU5TVVBQT1JURURfRU5DT0RJTkcgPSJXR19VTlNVUFBPUlRFRF9FTkNPRElORyI7Ci0KLSAgLyoqICBkZXRhY2goKSBub3Qgc3VwcG9ydGVkIGJ5IFhSVHJlZUZyYWdTZWxlY3RXcmFwcGVyICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfREVUQUNIX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIgPQotICAgICAgICAgIkVSX0RFVEFDSF9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSIjsKLSAgLyoqICBudW0oKSBub3Qgc3VwcG9ydGVkIGJ5IFhSVHJlZUZyYWdTZWxlY3RXcmFwcGVyICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTlVNX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIgPQotICAgICAgICAgIkVSX05VTV9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSIjsKLSAgLyoqICB4c3RyKCkgbm90IHN1cHBvcnRlZCBieSBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hTVFJfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiA9Ci0gICAgICAgICAiRVJfWFNUUl9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSIjsKLSAgLyoqICBzdHIoKSBub3Qgc3VwcG9ydGVkIGJ5IFhSVHJlZUZyYWdTZWxlY3RXcmFwcGVyICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU1RSX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIgPQotICAgICAgICAgIkVSX1NUUl9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSIjsKLQotICAvLyBFcnJvciBtZXNzYWdlcy4uLgotCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIE9iamVjdFtdW10gX2NvbnRlbnRzID0gbmV3IE9iamVjdFtdW117Ci0KLSAgeyAiRVJST1IwMDAwIiAsICJ7MH0iIH0sCi0KLSAgeyBFUl9DVVJSRU5UX05PVF9BTExPV0VEX0lOX01BVENILCAiVGhlIGN1cnJlbnQoKSBmdW5jdGlvbiBpcyBub3QgYWxsb3dlZCBpbiBhIG1hdGNoIHBhdHRlcm4hIiB9LAotCi0gIHsgRVJfQ1VSUkVOVF9UQUtFU19OT19BUkdTLCAiVGhlIGN1cnJlbnQoKSBmdW5jdGlvbiBkb2VzIG5vdCBhY2NlcHQgYXJndW1lbnRzISIgfSwKLQotICB7IEVSX0RPQ1VNRU5UX1JFUExBQ0VELAotICAgICAgImRvY3VtZW50KCkgZnVuY3Rpb24gaW1wbGVtZW50YXRpb24gaGFzIGJlZW4gcmVwbGFjZWQgYnkgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHQuRnVuY0RvY3VtZW50ISJ9LAotCi0gIHsgRVJfQ09OVEVYVF9IQVNfTk9fT1dORVJET0MsCi0gICAgICAiY29udGV4dCBkb2VzIG5vdCBoYXZlIGFuIG93bmVyIGRvY3VtZW50ISJ9LAotCi0gIHsgRVJfTE9DQUxOQU1FX0hBU19UT09fTUFOWV9BUkdTLAotICAgICAgImxvY2FsLW5hbWUoKSBoYXMgdG9vIG1hbnkgYXJndW1lbnRzLiJ9LAotCi0gIHsgRVJfTkFNRVNQQUNFVVJJX0hBU19UT09fTUFOWV9BUkdTLAotICAgICAgIm5hbWVzcGFjZS11cmkoKSBoYXMgdG9vIG1hbnkgYXJndW1lbnRzLiJ9LAotCi0gIHsgRVJfTk9STUFMSVpFU1BBQ0VfSEFTX1RPT19NQU5ZX0FSR1MsCi0gICAgICAibm9ybWFsaXplLXNwYWNlKCkgaGFzIHRvbyBtYW55IGFyZ3VtZW50cy4ifSwKLQotICB7IEVSX05VTUJFUl9IQVNfVE9PX01BTllfQVJHUywKLSAgICAgICJudW1iZXIoKSBoYXMgdG9vIG1hbnkgYXJndW1lbnRzLiJ9LAotCi0gIHsgRVJfTkFNRV9IQVNfVE9PX01BTllfQVJHUywKLSAgICAgIm5hbWUoKSBoYXMgdG9vIG1hbnkgYXJndW1lbnRzLiJ9LAotCi0gIHsgRVJfU1RSSU5HX0hBU19UT09fTUFOWV9BUkdTLAotICAgICAgInN0cmluZygpIGhhcyB0b28gbWFueSBhcmd1bWVudHMuIn0sCi0KLSAgeyBFUl9TVFJJTkdMRU5HVEhfSEFTX1RPT19NQU5ZX0FSR1MsCi0gICAgICAic3RyaW5nLWxlbmd0aCgpIGhhcyB0b28gbWFueSBhcmd1bWVudHMuIn0sCi0KLSAgeyBFUl9UUkFOU0xBVEVfVEFLRVNfM19BUkdTLAotICAgICAgIlRoZSB0cmFuc2xhdGUoKSBmdW5jdGlvbiB0YWtlcyB0aHJlZSBhcmd1bWVudHMhIn0sCi0KLSAgeyBFUl9VTlBBUlNFREVOVElUWVVSSV9UQUtFU18xX0FSRywKLSAgICAgICJUaGUgdW5wYXJzZWQtZW50aXR5LXVyaSBmdW5jdGlvbiBzaG91bGQgdGFrZSBvbmUgYXJndW1lbnQhIn0sCi0KLSAgeyBFUl9OQU1FU1BBQ0VBWElTX05PVF9JTVBMRU1FTlRFRCwKLSAgICAgICJuYW1lc3BhY2UgYXhpcyBub3QgaW1wbGVtZW50ZWQgeWV0ISJ9LAotCi0gIHsgRVJfVU5LTk9XTl9BWElTLAotICAgICAidW5rbm93biBheGlzOiB7MH0ifSwKLQotICB7IEVSX1VOS05PV05fTUFUQ0hfT1BFUkFUSU9OLAotICAgICAidW5rbm93biBtYXRjaCBvcGVyYXRpb24hIn0sCi0KLSAgeyBFUl9JTkNPUlJFQ1RfQVJHX0xFTkdUSCwKLSAgICAgICJBcmcgbGVuZ3RoIG9mIHByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24oKSBub2RlIHRlc3QgaXMgaW5jb3JyZWN0ISJ9LAotCi0gIHsgRVJfQ0FOVF9DT05WRVJUX1RPX05VTUJFUiwKLSAgICAgICJDYW4gbm90IGNvbnZlcnQgezB9IHRvIGEgbnVtYmVyIn0sCi0KLSAgeyBFUl9DQU5UX0NPTlZFUlRfVE9fTk9ERUxJU1QsCi0gICAgICAiQ2FuIG5vdCBjb252ZXJ0IHswfSB0byBhIE5vZGVMaXN0ISJ9LAotCi0gIHsgRVJfQ0FOVF9DT05WRVJUX1RPX01VVEFCTEVOT0RFTElTVCwKLSAgICAgICJDYW4gbm90IGNvbnZlcnQgezB9IHRvIGEgTm9kZVNldERUTSEifSwKLQotICB7IEVSX0NBTlRfQ09OVkVSVF9UT19UWVBFLAotICAgICAgIkNhbiBub3QgY29udmVydCB7MH0gdG8gYSB0eXBlI3sxfSJ9LAotCi0gIHsgRVJfRVhQRUNURURfTUFUQ0hfUEFUVEVSTiwKLSAgICAgICJFeHBlY3RlZCBtYXRjaCBwYXR0ZXJuIGluIGdldE1hdGNoU2NvcmUhIn0sCi0KLSAgeyBFUl9DT1VMRE5PVF9HRVRfVkFSX05BTUVELAotICAgICAgIkNvdWxkIG5vdCBnZXQgdmFyaWFibGUgbmFtZWQgezB9In0sCi0KLSAgeyBFUl9VTktOT1dOX09QQ09ERSwKLSAgICAgIkVSUk9SISBVbmtub3duIG9wIGNvZGU6IHswfSJ9LAotCi0gIHsgRVJfRVhUUkFfSUxMRUdBTF9UT0tFTlMsCi0gICAgICJFeHRyYSBpbGxlZ2FsIHRva2VuczogezB9In0sCi0KLSAgeyBFUl9FWFBFQ1RFRF9ET1VCTEVfUVVPVEUsCi0gICAgICAibWlzcXVvdGVkIGxpdGVyYWwuLi4gZXhwZWN0ZWQgZG91YmxlIHF1b3RlISJ9LAotCi0gIHsgRVJfRVhQRUNURURfU0lOR0xFX1FVT1RFLAotICAgICAgIm1pc3F1b3RlZCBsaXRlcmFsLi4uIGV4cGVjdGVkIHNpbmdsZSBxdW90ZSEifSwKLQotICB7IEVSX0VNUFRZX0VYUFJFU1NJT04sCi0gICAgICJFbXB0eSBleHByZXNzaW9uISJ9LAotCi0gIHsgRVJfRVhQRUNURURfQlVUX0ZPVU5ELAotICAgICAiRXhwZWN0ZWQgezB9LCBidXQgZm91bmQ6IHsxfSJ9LAotCi0gIHsgRVJfSU5DT1JSRUNUX1BST0dSQU1NRVJfQVNTRVJUSU9OLAotICAgICAgIlByb2dyYW1tZXIgYXNzZXJ0aW9uIGlzIGluY29ycmVjdCEgLSB7MH0ifSwKLQotICB7IEVSX0JPT0xFQU5fQVJHX05PX0xPTkdFUl9PUFRJT05BTCwKLSAgICAgICJib29sZWFuKC4uLikgYXJndW1lbnQgaXMgbm8gbG9uZ2VyIG9wdGlvbmFsIHdpdGggMTk5OTA3MDkgWFBhdGggZHJhZnQuIn0sCi0KLSAgeyBFUl9GT1VORF9DT01NQV9CVVRfTk9fUFJFQ0VESU5HX0FSRywKLSAgICAgICJGb3VuZCAnLCcgYnV0IG5vIHByZWNlZGluZyBhcmd1bWVudCEifSwKLQotICB7IEVSX0ZPVU5EX0NPTU1BX0JVVF9OT19GT0xMT1dJTkdfQVJHLAotICAgICAgIkZvdW5kICcsJyBidXQgbm8gZm9sbG93aW5nIGFyZ3VtZW50ISJ9LAotCi0gIHsgRVJfUFJFRElDQVRFX0lMTEVHQUxfU1lOVEFYLAotICAgICAgIicuLltwcmVkaWNhdGVdJyBvciAnLltwcmVkaWNhdGVdJyBpcyBpbGxlZ2FsIHN5bnRheC4gIFVzZSAnc2VsZjo6bm9kZSgpW3ByZWRpY2F0ZV0nIGluc3RlYWQuIn0sCi0KLSAgeyBFUl9JTExFR0FMX0FYSVNfTkFNRSwKLSAgICAgImlsbGVnYWwgYXhpcyBuYW1lOiB7MH0ifSwKLQotICB7IEVSX1VOS05PV05fTk9ERVRZUEUsCi0gICAgICJVbmtub3duIG5vZGV0eXBlOiB7MH0ifSwKLQotICB7IEVSX1BBVFRFUk5fTElURVJBTF9ORUVEU19CRV9RVU9URUQsCi0gICAgICAiUGF0dGVybiBsaXRlcmFsICh7MH0pIG5lZWRzIHRvIGJlIHF1b3RlZCEifSwKLQotICB7IEVSX0NPVUxETk9UX0JFX0ZPUk1BVFRFRF9UT19OVU1CRVIsCi0gICAgICAiezB9IGNvdWxkIG5vdCBiZSBmb3JtYXR0ZWQgdG8gYSBudW1iZXIhIn0sCi0KLSAgeyBFUl9DT1VMRE5PVF9DUkVBVEVfWE1MUFJPQ0VTU09STElBSVNPTiwKLSAgICAgICJDb3VsZCBub3QgY3JlYXRlIFhNTCBUcmFuc2Zvcm1lckZhY3RvcnkgTGlhaXNvbjogezB9In0sCi0KLSAgeyBFUl9ESUROT1RfRklORF9YUEFUSF9TRUxFQ1RfRVhQLAotICAgICAgIkVycm9yISBEaWQgbm90IGZpbmQgeHBhdGggc2VsZWN0IGV4cHJlc3Npb24gKC1zZWxlY3QpLiJ9LAotCi0gIHsgRVJfQ09VTEROT1RfRklORF9FTkRPUF9BRlRFUl9PUExPQ0FUSU9OUEFUSCwKLSAgICAgICJFUlJPUiEgQ291bGQgbm90IGZpbmQgRU5ET1AgYWZ0ZXIgT1BfTE9DQVRJT05QQVRIIn0sCi0KLSAgeyBFUl9FUlJPUl9PQ0NVUkVELAotICAgICAiRXJyb3Igb2NjdXJlZCEifSwKLQotICB7IEVSX0lMTEVHQUxfVkFSSUFCTEVfUkVGRVJFTkNFLAotICAgICAgIlZhcmlhYmxlUmVmZXJlbmNlIGdpdmVuIGZvciB2YXJpYWJsZSBvdXQgb2YgY29udGV4dCBvciB3aXRob3V0IGRlZmluaXRpb24hICBOYW1lID0gezB9In0sCi0KLSAgeyBFUl9BWEVTX05PVF9BTExPV0VELAotICAgICAgIk9ubHkgY2hpbGQ6OiBhbmQgYXR0cmlidXRlOjogYXhlcyBhcmUgYWxsb3dlZCBpbiBtYXRjaCBwYXR0ZXJucyEgIE9mZmVuZGluZyBheGVzID0gezB9In0sCi0KLSAgeyBFUl9LRVlfSEFTX1RPT19NQU5ZX0FSR1MsCi0gICAgICAia2V5KCkgaGFzIGFuIGluY29ycmVjdCBudW1iZXIgb2YgYXJndW1lbnRzLiJ9LAotCi0gIHsgRVJfQ09VTlRfVEFLRVNfMV9BUkcsCi0gICAgICAiVGhlIGNvdW50IGZ1bmN0aW9uIHNob3VsZCB0YWtlIG9uZSBhcmd1bWVudCEifSwKLQotICB7IEVSX0NPVUxETk9UX0ZJTkRfRlVOQ1RJT04sCi0gICAgICJDb3VsZCBub3QgZmluZCBmdW5jdGlvbjogezB9In0sCi0KLSAgeyBFUl9VTlNVUFBPUlRFRF9FTkNPRElORywKLSAgICAgIlVuc3VwcG9ydGVkIGVuY29kaW5nOiB7MH0ifSwKLQotICB7IEVSX1BST0JMRU1fSU5fRFRNX05FWFRTSUJMSU5HLAotICAgICAgIlByb2JsZW0gb2NjdXJlZCBpbiBEVE0gaW4gZ2V0TmV4dFNpYmxpbmcuLi4gdHJ5aW5nIHRvIHJlY292ZXIifSwKLQotICB7IEVSX0NBTk5PVF9XUklURV9UT19FTVBUWU5PREVMSVNUSU1QTCwKLSAgICAgICJQcm9ncmFtbWVyIGVycm9yOiBFbXB0eU5vZGVMaXN0IGNhbiBub3QgYmUgd3JpdHRlbiB0by4ifSwKLQotICB7IEVSX1NFVERPTUZBQ1RPUllfTk9UX1NVUFBPUlRFRCwKLSAgICAgICJzZXRET01GYWN0b3J5IGlzIG5vdCBzdXBwb3J0ZWQgYnkgWFBhdGhDb250ZXh0ISJ9LAotCi0gIHsgRVJfUFJFRklYX01VU1RfUkVTT0xWRSwKLSAgICAgICJQcmVmaXggbXVzdCByZXNvbHZlIHRvIGEgbmFtZXNwYWNlOiB7MH0ifSwKLQotICB7IEVSX1BBUlNFX05PVF9TVVBQT1JURUQsCi0gICAgICAicGFyc2UgKElucHV0U291cmNlIHNvdXJjZSkgbm90IHN1cHBvcnRlZCBpbiBYUGF0aENvbnRleHQhIENhbiBub3Qgb3BlbiB7MH0ifSwKLQotICB7IEVSX1NBWF9BUElfTk9UX0hBTkRMRUQsCi0gICAgICAiU0FYIEFQSSBjaGFyYWN0ZXJzKGNoYXIgY2hbXS4uLiBub3QgaGFuZGxlZCBieSB0aGUgRFRNISJ9LAotCi0gIHsgRVJfSUdOT1JBQkxFX1dISVRFU1BBQ0VfTk9UX0hBTkRMRUQsCi0gICAgICAiaWdub3JhYmxlV2hpdGVzcGFjZShjaGFyIGNoW10uLi4gbm90IGhhbmRsZWQgYnkgdGhlIERUTSEifSwKLQotICB7IEVSX0RUTV9DQU5OT1RfSEFORExFX05PREVTLAotICAgICAgIkRUTUxpYWlzb24gY2FuIG5vdCBoYW5kbGUgbm9kZXMgb2YgdHlwZSB7MH0ifSwKLQotICB7IEVSX1hFUkNFU19DQU5OT1RfSEFORExFX05PREVTLAotICAgICAgIkRPTTJIZWxwZXIgY2FuIG5vdCBoYW5kbGUgbm9kZXMgb2YgdHlwZSB7MH0ifSwKLQotICB7IEVSX1hFUkNFU19QQVJTRV9FUlJPUl9ERVRBSUxTLAotICAgICAgIkRPTTJIZWxwZXIucGFyc2UgZXJyb3I6IFN5c3RlbUlEIC0gezB9IGxpbmUgLSB7MX0ifSwKLQotICB7IEVSX1hFUkNFU19QQVJTRV9FUlJPUiwKLSAgICAgIkRPTTJIZWxwZXIucGFyc2UgZXJyb3IifSwKLQotICB7IEVSX0lOVkFMSURfVVRGMTZfU1VSUk9HQVRFLAotICAgICAgIkludmFsaWQgVVRGLTE2IHN1cnJvZ2F0ZSBkZXRlY3RlZDogezB9ID8ifSwKLQotICB7IEVSX09JRVJST1IsCi0gICAgICJJTyBlcnJvciJ9LAotCi0gIHsgRVJfQ0FOTk9UX0NSRUFURV9VUkwsCi0gICAgICJDYW5ub3QgY3JlYXRlIHVybCBmb3I6IHswfSJ9LAotCi0gIHsgRVJfWFBBVEhfUkVBRE9CSkVDVCwKLSAgICAgIkluIFhQYXRoLnJlYWRPYmplY3Q6IHswfSJ9LAotCi0gIHsgRVJfRlVOQ1RJT05fVE9LRU5fTk9UX0ZPVU5ELAotICAgICAgImZ1bmN0aW9uIHRva2VuIG5vdCBmb3VuZC4ifSwKLQotICB7IEVSX0NBTk5PVF9ERUFMX1hQQVRIX1RZUEUsCi0gICAgICAgIkNhbiBub3QgZGVhbCB3aXRoIFhQYXRoIHR5cGU6IHswfSJ9LAotCi0gIHsgRVJfTk9ERVNFVF9OT1RfTVVUQUJMRSwKLSAgICAgICAiVGhpcyBOb2RlU2V0IGlzIG5vdCBtdXRhYmxlIn0sCi0KLSAgeyBFUl9OT0RFU0VURFRNX05PVF9NVVRBQkxFLAotICAgICAgICJUaGlzIE5vZGVTZXREVE0gaXMgbm90IG11dGFibGUifSwKLQotICB7IEVSX1ZBUl9OT1RfUkVTT0xWQUJMRSwKLSAgICAgICAgIlZhcmlhYmxlIG5vdCByZXNvbHZhYmxlOiB7MH0ifSwKLQotICB7IEVSX05VTExfRVJST1JfSEFORExFUiwKLSAgICAgICAgIk51bGwgZXJyb3IgaGFuZGxlciJ9LAotCi0gIHsgRVJfUFJPR19BU1NFUlRfVU5LTk9XTl9PUENPREUsCi0gICAgICAgIlByb2dyYW1tZXInJ3MgYXNzZXJ0aW9uOiB1bmtub3duIG9wY29kZTogezB9In0sCi0KLSAgeyBFUl9aRVJPX09SX09ORSwKLSAgICAgICAiMCBvciAxIn0sCi0KLSAgeyBFUl9SVEZfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiwKLSAgICAgICAicnRmKCkgbm90IHN1cHBvcnRlZCBieSBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciJ9LAotCi0gIHsgRVJfUlRGX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIsCi0gICAgICAgImFzTm9kZUl0ZXJhdG9yKCkgbm90IHN1cHBvcnRlZCBieSBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciJ9LAotCi0gICAgICAgIC8qKiAgZGV0YWNoKCkgbm90IHN1cHBvcnRlZCBieSBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciAgICovCi0gICB7IEVSX0RFVEFDSF9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSLAotICAgICAgICAgICAgICAgICJkZXRhY2goKSBub3Qgc3VwcG9ydGVkIGJ5IFhSVHJlZUZyYWdTZWxlY3RXcmFwcGVyIn0sCi0KLSAgICAgICAgLyoqICBudW0oKSBub3Qgc3VwcG9ydGVkIGJ5IFhSVHJlZUZyYWdTZWxlY3RXcmFwcGVyICAgKi8KLSAgIHsgRVJfTlVNX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIsCi0gICAgICAgICAgICAgICAgIm51bSgpIG5vdCBzdXBwb3J0ZWQgYnkgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIifSwKLQotICAgICAgICAvKiogIHhzdHIoKSBub3Qgc3VwcG9ydGVkIGJ5IFhSVHJlZUZyYWdTZWxlY3RXcmFwcGVyICAgKi8KLSAgIHsgRVJfWFNUUl9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSLAotICAgICAgICAgICAgICAgICJ4c3RyKCkgbm90IHN1cHBvcnRlZCBieSBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciJ9LAotCi0gICAgICAgIC8qKiAgc3RyKCkgbm90IHN1cHBvcnRlZCBieSBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciAgICovCi0gICB7IEVSX1NUUl9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSLAotICAgICAgICAgICAgICAgICJzdHIoKSBub3Qgc3VwcG9ydGVkIGJ5IFhSVHJlZUZyYWdTZWxlY3RXcmFwcGVyIn0sCi0KLSAgeyBFUl9GU0JfTk9UX1NVUFBPUlRFRF9YU1RSSU5HRk9SQ0hBUlMsCi0gICAgICAgImZzYigpIG5vdCBzdXBwb3J0ZWQgZm9yIFhTdHJpbmdGb3JDaGFycyJ9LAotCi0gIHsgRVJfQ09VTERfTk9UX0ZJTkRfVkFSLAotICAgICAgIkNvdWxkIG5vdCBmaW5kIHZhcmlhYmxlIHdpdGggdGhlIG5hbWUgb2YgezB9In0sCi0KLSAgeyBFUl9YU1RSSU5HRk9SQ0hBUlNfQ0FOTk9UX1RBS0VfU1RSSU5HLAotICAgICAgIlhTdHJpbmdGb3JDaGFycyBjYW4gbm90IHRha2UgYSBzdHJpbmcgZm9yIGFuIGFyZ3VtZW50In0sCi0KLSAgeyBFUl9GQVNUU1RSSU5HQlVGRkVSX0NBTk5PVF9CRV9OVUxMLAotICAgICAgIlRoZSBGYXN0U3RyaW5nQnVmZmVyIGFyZ3VtZW50IGNhbiBub3QgYmUgbnVsbCJ9LAotCi0gIHsgRVJfVFdPX09SX1RIUkVFLAotICAgICAgICIyIG9yIDMifSwKLQotICB7IEVSX1ZBUklBQkxFX0FDQ0VTU0VEX0JFRk9SRV9CSU5ELAotICAgICAgICJWYXJpYWJsZSBhY2Nlc3NlZCBiZWZvcmUgaXQgaXMgYm91bmQhIn0sCi0KLSAgeyBFUl9GU0JfQ0FOTk9UX1RBS0VfU1RSSU5HLAotICAgICAgICJYU3RyaW5nRm9yRlNCIGNhbiBub3QgdGFrZSBhIHN0cmluZyBmb3IgYW4gYXJndW1lbnQhIn0sCi0KLSAgeyBFUl9TRVRUSU5HX1dBTEtFUl9ST09UX1RPX05VTEwsCi0gICAgICAgIlxuICEhISEgRXJyb3IhIFNldHRpbmcgdGhlIHJvb3Qgb2YgYSB3YWxrZXIgdG8gbnVsbCEhISJ9LAotCi0gIHsgRVJfTk9ERVNFVERUTV9DQU5OT1RfSVRFUkFURSwKLSAgICAgICAiVGhpcyBOb2RlU2V0RFRNIGNhbiBub3QgaXRlcmF0ZSB0byBhIHByZXZpb3VzIG5vZGUhIn0sCi0KLSAgeyBFUl9OT0RFU0VUX0NBTk5PVF9JVEVSQVRFLAotICAgICAgICJUaGlzIE5vZGVTZXQgY2FuIG5vdCBpdGVyYXRlIHRvIGEgcHJldmlvdXMgbm9kZSEifSwKLQotICB7IEVSX05PREVTRVREVE1fQ0FOTk9UX0lOREVYLAotICAgICAgICJUaGlzIE5vZGVTZXREVE0gY2FuIG5vdCBkbyBpbmRleGluZyBvciBjb3VudGluZyBmdW5jdGlvbnMhIn0sCi0KLSAgeyBFUl9OT0RFU0VUX0NBTk5PVF9JTkRFWCwKLSAgICAgICAiVGhpcyBOb2RlU2V0IGNhbiBub3QgZG8gaW5kZXhpbmcgb3IgY291bnRpbmcgZnVuY3Rpb25zISJ9LAotCi0gIHsgRVJfQ0FOTk9UX0NBTExfU0VUU0hPVUxEQ0FDSEVOT0RFLAotICAgICAgICJDYW4gbm90IGNhbGwgc2V0U2hvdWxkQ2FjaGVOb2RlcyBhZnRlciBuZXh0Tm9kZSBoYXMgYmVlbiBjYWxsZWQhIn0sCi0KLSAgeyBFUl9PTkxZX0FMTE9XUywKLSAgICAgICAiezB9IG9ubHkgYWxsb3dzIHsxfSBhcmd1bWVudHMifSwKLQotICB7IEVSX1VOS05PV05fU1RFUCwKLSAgICAgICAiUHJvZ3JhbW1lcicncyBhc3NlcnRpb24gaW4gZ2V0TmV4dFN0ZXBQb3M6IHVua25vd24gc3RlcFR5cGU6IHswfSJ9LAotCi0gIC8vTm90ZSB0byB0cmFuc2xhdG9yczogIEEgcmVsYXRpdmUgbG9jYXRpb24gcGF0aCBpcyBhIGZvcm0gb2YgWFBhdGggZXhwcmVzc2lvbi4KLSAgLy8gVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgc3VjaCBhbiBleHByZXNzaW9uIHdhcyBleHBlY3RlZCBmb2xsb3dpbmcgdGhlCi0gIC8vIGNoYXJhY3RlcnMgJy8nIG9yICcvLycsIGJ1dCB3YXMgbm90IGZvdW5kLgotICB7IEVSX0VYUEVDVEVEX1JFTF9MT0NfUEFUSCwKLSAgICAgICJBIHJlbGF0aXZlIGxvY2F0aW9uIHBhdGggd2FzIGV4cGVjdGVkIGZvbGxvd2luZyB0aGUgJy8nIG9yICcvLycgdG9rZW4uIn0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIEEgbG9jYXRpb24gcGF0aCBpcyBhIGZvcm0gb2YgWFBhdGggZXhwcmVzc2lvbi4KLSAgLy8gVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgc3ludGFjdGljYWxseSBzdWNoIGFuIGV4cHJlc3Npb24gd2FzIGV4cGVjdGVkLGJ1dAotICAvLyB0aGUgY2hhcmFjdGVycyBzcGVjaWZpZWQgYnkgdGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHdlcmUgZW5jb3VudGVyZWQgaW5zdGVhZC4KLSAgeyBFUl9FWFBFQ1RFRF9MT0NfUEFUSCwKLSAgICAgICAiQSBsb2NhdGlvbiBwYXRoIHdhcyBleHBlY3RlZCwgYnV0IHRoZSBmb2xsb3dpbmcgdG9rZW4gd2FzIGVuY291bnRlcmVkXHUwMDNhICB7MH0ifSwKLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQSBsb2NhdGlvbiBwYXRoIGlzIGEgZm9ybSBvZiBYUGF0aCBleHByZXNzaW9uLgotICAvLyBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCBzeW50YWN0aWNhbGx5IHN1Y2ggYSBzdWJleHByZXNzaW9uIHdhcyBleHBlY3RlZCwKLSAgLy8gYnV0IG5vIG1vcmUgY2hhcmFjdGVycyB3ZXJlIGZvdW5kIGluIHRoZSBleHByZXNzaW9uLgotICB7IEVSX0VYUEVDVEVEX0xPQ19QQVRIX0FUX0VORF9FWFBSLAotICAgICAgICJBIGxvY2F0aW9uIHBhdGggd2FzIGV4cGVjdGVkLCBidXQgdGhlIGVuZCBvZiB0aGUgWFBhdGggZXhwcmVzc2lvbiB3YXMgZm91bmQgaW5zdGVhZC4ifSwKLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQSBsb2NhdGlvbiBzdGVwIGlzIHBhcnQgb2YgYW4gWFBhdGggZXhwcmVzc2lvbi4KLSAgLy8gVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgc3ludGFjdGljYWxseSBzdWNoIGFuIGV4cHJlc3Npb24gd2FzIGV4cGVjdGVkCi0gIC8vIGZvbGxvd2luZyB0aGUgc3BlY2lmaWVkIGNoYXJhY3RlcnMuCi0gIHsgRVJfRVhQRUNURURfTE9DX1NURVAsCi0gICAgICAgIkEgbG9jYXRpb24gc3RlcCB3YXMgZXhwZWN0ZWQgZm9sbG93aW5nIHRoZSAnLycgb3IgJy8vJyB0b2tlbi4ifSwKLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQSBub2RlIHRlc3QgaXMgcGFydCBvZiBhbiBYUGF0aCBleHByZXNzaW9uIHRoYXQgaXMKLSAgLy8gdXNlZCB0byB0ZXN0IGZvciBwYXJ0aWN1bGFyIGtpbmRzIG9mIG5vZGVzLiAgSW4gdGhpcyBjYXNlLCBhIG5vZGUgdGVzdCB0aGF0Ci0gIC8vIGNvbnNpc3RzIG9mIGFuIE5DTmFtZSBmb2xsb3dlZCBieSBhIGNvbG9uIGFuZCBhbiBhc3RlcmlzayBvciB0aGF0IGNvbnNpc3RzCi0gIC8vIG9mIGEgUU5hbWUgd2FzIGV4cGVjdGVkLCBidXQgd2FzIG5vdCBmb3VuZC4KLSAgeyBFUl9FWFBFQ1RFRF9OT0RFX1RFU1QsCi0gICAgICAgIkEgbm9kZSB0ZXN0IHRoYXQgbWF0Y2hlcyBlaXRoZXIgTkNOYW1lOiogb3IgUU5hbWUgd2FzIGV4cGVjdGVkLiJ9LAotCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBIHN0ZXAgcGF0dGVybiBpcyBwYXJ0IG9mIGFuIFhQYXRoIGV4cHJlc3Npb24uCi0gIC8vIFRoZSBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHN5bnRhY3RpY2FsbHkgc3VjaCBhbiBleHByZXNzaW9uIHdhcyBleHBlY3RlZCwKLSAgLy8gYnV0IHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyIHdhcyBmb3VuZCBpbiB0aGUgZXhwcmVzc2lvbiBpbnN0ZWFkLgotICB7IEVSX0VYUEVDVEVEX1NURVBfUEFUVEVSTiwKLSAgICAgICAiQSBzdGVwIHBhdHRlcm4gd2FzIGV4cGVjdGVkLCBidXQgJy8nIHdhcyBlbmNvdW50ZXJlZC4ifSwKLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiBBIHJlbGF0aXZlIHBhdGggcGF0dGVybiBpcyBwYXJ0IG9mIGFuIFhQYXRoIGV4cHJlc3Npb24uCi0gIC8vIFRoZSBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHN5bnRhY3RpY2FsbHkgc3VjaCBhbiBleHByZXNzaW9uIHdhcyBleHBlY3RlZCwKLSAgLy8gYnV0IHdhcyBub3QgZm91bmQuCi0gIHsgRVJfRVhQRUNURURfUkVMX1BBVEhfUEFUVEVSTiwKLSAgICAgICAiQSByZWxhdGl2ZSBwYXRoIHBhdHRlcm4gd2FzIGV4cGVjdGVkLiJ9LAotCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYSBkYXRhIHR5cGUuICBUaGUKLSAgLy8gbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCBhIHZhbHVlIG9mIGEgcGFydGljdWxhciB0eXBlIGNvdWxkIG5vdCBiZSBjb252ZXJ0ZWQKLSAgLy8gdG8gYSB2YWx1ZSBvZiB0eXBlIGJvb2xlYW4uCi0gIHsgRVJfQ0FOVF9DT05WRVJUX1RPX0JPT0xFQU4sCi0gICAgICAgIlRoZSBYUGF0aFJlc3VsdCBvZiBYUGF0aCBleHByZXNzaW9uICcnezB9JycgaGFzIGFuIFhQYXRoUmVzdWx0VHlwZSBvZiB7MX0gd2hpY2ggY2Fubm90IGJlIGNvbnZlcnRlZCB0byBhIGJvb2xlYW4uIn0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogRG8gbm90IHRyYW5zbGF0ZSBBTllfVU5PUkRFUkVEX05PREVfVFlQRSBhbmQKLSAgLy8gRklSU1RfT1JERVJFRF9OT0RFX1RZUEUuCi0gIHsgRVJfQ0FOVF9DT05WRVJUX1RPX1NJTkdMRU5PREUsCi0gICAgICAgIlRoZSBYUGF0aFJlc3VsdCBvZiBYUGF0aCBleHByZXNzaW9uICcnezB9JycgaGFzIGFuIFhQYXRoUmVzdWx0VHlwZSBvZiB7MX0gd2hpY2ggY2Fubm90IGJlIGNvbnZlcnRlZCB0byBhIHNpbmdsZSBub2RlLiBUaGUgbWV0aG9kIGdldFNpbmdsZU5vZGVWYWx1ZSBhcHBsaWVzIG9ubHkgdG8gdHlwZXMgQU5ZX1VOT1JERVJFRF9OT0RFX1RZUEUgYW5kIEZJUlNUX09SREVSRURfTk9ERV9UWVBFLiJ9LAotCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6IERvIG5vdCB0cmFuc2xhdGUgVU5PUkRFUkVEX05PREVfU05BUFNIT1RfVFlQRSBhbmQKLSAgLy8gT1JERVJFRF9OT0RFX1NOQVBTSE9UX1RZUEUuCi0gIHsgRVJfQ0FOVF9HRVRfU05BUFNIT1RfTEVOR1RILAotICAgICAgICJUaGUgbWV0aG9kIGdldFNuYXBzaG90TGVuZ3RoIGNhbm5vdCBiZSBjYWxsZWQgb24gdGhlIFhQYXRoUmVzdWx0IG9mIFhQYXRoIGV4cHJlc3Npb24gJyd7MH0nJyBiZWNhdXNlIGl0cyBYUGF0aFJlc3VsdFR5cGUgaXMgezF9LiBUaGlzIG1ldGhvZCBhcHBsaWVzIG9ubHkgdG8gdHlwZXMgVU5PUkRFUkVEX05PREVfU05BUFNIT1RfVFlQRSBhbmQgT1JERVJFRF9OT0RFX1NOQVBTSE9UX1RZUEUuIn0sCi0KLSAgeyBFUl9OT05fSVRFUkFUT1JfVFlQRSwKLSAgICAgICAiVGhlIG1ldGhvZCBpdGVyYXRlTmV4dCBjYW5ub3QgYmUgY2FsbGVkIG9uIHRoZSBYUGF0aFJlc3VsdCBvZiBYUGF0aCBleHByZXNzaW9uICcnezB9JycgYmVjYXVzZSBpdHMgWFBhdGhSZXN1bHRUeXBlIGlzIHsxfS4gVGhpcyBtZXRob2QgYXBwbGllcyBvbmx5IHRvIHR5cGVzIFVOT1JERVJFRF9OT0RFX0lURVJBVE9SX1RZUEUgYW5kIE9SREVSRURfTk9ERV9JVEVSQVRPUl9UWVBFLiJ9LAotCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6IFRoaXMgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUgZG9jdW1lbnQgYmVpbmcgb3BlcmF0ZWQKLSAgLy8gdXBvbiBjaGFuZ2VkLCBzbyB0aGUgaXRlcmF0b3Igb2JqZWN0IHRoYXQgd2FzIGJlaW5nIHVzZWQgdG8gdHJhdmVyc2UgdGhlCi0gIC8vIGRvY3VtZW50IGhhcyBub3cgYmVjb21lIGludmFsaWQuCi0gIHsgRVJfRE9DX01VVEFURUQsCi0gICAgICAgIkRvY3VtZW50IG11dGF0ZWQgc2luY2UgcmVzdWx0IHdhcyByZXR1cm5lZC4gSXRlcmF0b3IgaXMgaW52YWxpZC4ifSwKLQotICB7IEVSX0lOVkFMSURfWFBBVEhfVFlQRSwKLSAgICAgICAiSW52YWxpZCBYUGF0aCB0eXBlIGFyZ3VtZW50OiB7MH0ifSwKLQotICB7IEVSX0VNUFRZX1hQQVRIX1JFU1VMVCwKLSAgICAgICAiRW1wdHkgWFBhdGggcmVzdWx0IG9iamVjdCJ9LAotCi0gIHsgRVJfSU5DT01QQVRJQkxFX1RZUEVTLAotICAgICAgICJUaGUgWFBhdGhSZXN1bHQgb2YgWFBhdGggZXhwcmVzc2lvbiAnJ3swfScnIGhhcyBhbiBYUGF0aFJlc3VsdFR5cGUgb2YgezF9IHdoaWNoIGNhbm5vdCBiZSBjb2VyY2VkIGludG8gdGhlIHNwZWNpZmllZCBYUGF0aFJlc3VsdFR5cGUgb2YgezJ9LiJ9LAotCi0gIHsgRVJfTlVMTF9SRVNPTFZFUiwKLSAgICAgICAiVW5hYmxlIHRvIHJlc29sdmUgcHJlZml4IHdpdGggbnVsbCBwcmVmaXggcmVzb2x2ZXIuIn0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBhIGRhdGEgdHlwZS4gIFRoZQotICAvLyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IGEgdmFsdWUgb2YgYSBwYXJ0aWN1bGFyIHR5cGUgY291bGQgbm90IGJlIGNvbnZlcnRlZAotICAvLyB0byBhIHZhbHVlIG9mIHR5cGUgc3RyaW5nLgotICB7IEVSX0NBTlRfQ09OVkVSVF9UT19TVFJJTkcsCi0gICAgICAgIlRoZSBYUGF0aFJlc3VsdCBvZiBYUGF0aCBleHByZXNzaW9uICcnezB9JycgaGFzIGFuIFhQYXRoUmVzdWx0VHlwZSBvZiB7MX0gd2hpY2ggY2Fubm90IGJlIGNvbnZlcnRlZCB0byBhIHN0cmluZy4ifSwKLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiBEbyBub3QgdHJhbnNsYXRlIHNuYXBzaG90SXRlbSwKLSAgLy8gVU5PUkRFUkVEX05PREVfU05BUFNIT1RfVFlQRSBhbmQgT1JERVJFRF9OT0RFX1NOQVBTSE9UX1RZUEUuCi0gIHsgRVJfTk9OX1NOQVBTSE9UX1RZUEUsCi0gICAgICAgIlRoZSBtZXRob2Qgc25hcHNob3RJdGVtIGNhbm5vdCBiZSBjYWxsZWQgb24gdGhlIFhQYXRoUmVzdWx0IG9mIFhQYXRoIGV4cHJlc3Npb24gJyd7MH0nJyBiZWNhdXNlIGl0cyBYUGF0aFJlc3VsdFR5cGUgaXMgezF9LiBUaGlzIG1ldGhvZCBhcHBsaWVzIG9ubHkgdG8gdHlwZXMgVU5PUkRFUkVEX05PREVfU05BUFNIT1RfVFlQRSBhbmQgT1JERVJFRF9OT0RFX1NOQVBTSE9UX1RZUEUuIn0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFhQYXRoRXZhbHVhdG9yIGlzIGEgSmF2YSBpbnRlcmZhY2UgbmFtZS4gIEFuCi0gIC8vIFhQYXRoRXZhbHVhdG9yIGlzIGNyZWF0ZWQgd2l0aCByZXNwZWN0IHRvIGEgcGFydGljdWxhciBYTUwgZG9jdW1lbnQsIGFuZCBpbgotICAvLyB0aGlzIGNhc2UgdGhlIGV4cHJlc3Npb24gcmVwcmVzZW50ZWQgYnkgdGhpcyBvYmplY3Qgd2FzIGJlaW5nIGV2YWx1YXRlZCB3aXRoCi0gIC8vIHJlc3BlY3QgdG8gYSBjb250ZXh0IG5vZGUgZnJvbSBhIGRpZmZlcmVudCBkb2N1bWVudC4KLSAgeyBFUl9XUk9OR19ET0NVTUVOVCwKLSAgICAgICAiQ29udGV4dCBub2RlIGRvZXMgbm90IGJlbG9uZyB0byB0aGUgZG9jdW1lbnQgdGhhdCBpcyBib3VuZCB0byB0aGlzIFhQYXRoRXZhbHVhdG9yLiJ9LAotCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgWFBhdGggZXhwcmVzc2lvbiBjYW5ub3QgYmUgZXZhbHVhdGVkIHdpdGggcmVzcGVjdAotICAvLyB0byB0aGlzIHR5cGUgb2Ygbm9kZS4KLSAgeyBFUl9XUk9OR19OT0RFVFlQRSwKLSAgICAgICAiVGhlIGNvbnRleHQgbm9kZSB0eXBlIGlzIG5vdCBzdXBwb3J0ZWQuIn0sCi0KLSAgeyBFUl9YUEFUSF9FUlJPUiwKLSAgICAgICAiVW5rbm93biBlcnJvciBpbiBYUGF0aC4ifSwKLQotICB7IEVSX0NBTlRfQ09OVkVSVF9YUEFUSFJFU1VMVFRZUEVfVE9fTlVNQkVSLAotICAgICAgICAiVGhlIFhQYXRoUmVzdWx0IG9mIFhQYXRoIGV4cHJlc3Npb24gJyd7MH0nJyBoYXMgYW4gWFBhdGhSZXN1bHRUeXBlIG9mIHsxfSB3aGljaCBjYW5ub3QgYmUgY29udmVydGVkIHRvIGEgbnVtYmVyIn0sCi0KLSAgLy9CRUdJTjogIERlZmluaXRpb25zIG9mIGVycm9yIGtleXMgdXNlZCAgaW4gZXhjZXB0aW9uIG1lc3NhZ2VzIG9mICBKQVhQIDEuMyBYUGF0aCBBUEkgaW1wbGVtZW50YXRpb24KLQotICAvKiogRmllbGQgRVJfRVhURU5TSU9OX0ZVTkNUSU9OX0NBTk5PVF9CRV9JTlZPS0VEICAgICAgICAgICAgICAgICAgICAgICAqLwotCi0gIHsgRVJfRVhURU5TSU9OX0ZVTkNUSU9OX0NBTk5PVF9CRV9JTlZPS0VELAotICAgICAgICJFeHRlbnNpb24gZnVuY3Rpb246ICcnezB9JycgY2FuIG5vdCBiZSBpbnZva2VkIHdoZW4gdGhlIFhNTENvbnN0YW50cy5GRUFUVVJFX1NFQ1VSRV9QUk9DRVNTSU5HIGZlYXR1cmUgaXMgc2V0IHRvIHRydWUuIn0sCi0KLSAgLyoqIEZpZWxkIEVSX1JFU09MVkVfVkFSSUFCTEVfUkVUVVJOU19OVUxMICAgICAgICAgICAgICAgICAgICAgICAqLwotCi0gIHsgRVJfUkVTT0xWRV9WQVJJQUJMRV9SRVRVUk5TX05VTEwsCi0gICAgICAgInJlc29sdmVWYXJpYWJsZSBmb3IgdmFyaWFibGUgezB9IHJldHVybmluZyBudWxsIn0sCi0KLSAgLyoqIEZpZWxkIEVSX1VOU1VQUE9SVEVEX1JFVFVSTl9UWVBFICAgICAgICAgICAgICAgICAgICAgICAqLwotCi0gIHsgRVJfVU5TVVBQT1JURURfUkVUVVJOX1RZUEUsCi0gICAgICAgIlVuU3VwcG9ydGVkIFJldHVybiBUeXBlIDogezB9In0sCi0KLSAgLyoqIEZpZWxkIEVSX1NPVVJDRV9SRVRVUk5fVFlQRV9DQU5OT1RfQkVfTlVMTCAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX1NPVVJDRV9SRVRVUk5fVFlQRV9DQU5OT1RfQkVfTlVMTCwKLSAgICAgICAiU291cmNlIGFuZC9vciBSZXR1cm4gVHlwZSBjYW4gbm90IGJlIG51bGwifSwKLQotICAvKiogRmllbGQgRVJfU09VUkNFX1JFVFVSTl9UWVBFX0NBTk5PVF9CRV9OVUxMICAgICAgICAgICAgICAgICAgICAgICAqLwotCi0gIHsgRVJfU09VUkNFX1JFVFVSTl9UWVBFX0NBTk5PVF9CRV9OVUxMLAotICAgICAgICJTb3VyY2UgYW5kL29yIFJldHVybiBUeXBlIGNhbiBub3QgYmUgbnVsbCJ9LAotCi0gIC8qKiBGaWVsZCBFUl9BUkdfQ0FOTk9UX0JFX05VTEwgICAgICAgICAgICAgICAgICAgICAgICovCi0KLSAgeyBFUl9BUkdfQ0FOTk9UX0JFX05VTEwsCi0gICAgICAgInswfSBhcmd1bWVudCBjYW4gbm90IGJlIG51bGwifSwKLQotICAvKiogRmllbGQgRVJfT0JKRUNUX01PREVMX05VTEwgICAgICAgICAgICAgICAgICAgICAgICovCi0KLSAgeyBFUl9PQkpFQ1RfTU9ERUxfTlVMTCwKLSAgICAgICAiezB9I2lzT2JqZWN0TW9kZWxTdXBwb3J0ZWQoIFN0cmluZyBvYmplY3RNb2RlbCApIGNhbm5vdCBiZSBjYWxsZWQgd2l0aCBvYmplY3RNb2RlbCA9PSBudWxsIn0sCi0KLSAgLyoqIEZpZWxkIEVSX09CSkVDVF9NT0RFTF9FTVBUWSAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX09CSkVDVF9NT0RFTF9FTVBUWSwKLSAgICAgICAiezB9I2lzT2JqZWN0TW9kZWxTdXBwb3J0ZWQoIFN0cmluZyBvYmplY3RNb2RlbCApIGNhbm5vdCBiZSBjYWxsZWQgd2l0aCBvYmplY3RNb2RlbCA9PSBcIlwiIn0sCi0KLSAgLyoqIEZpZWxkIEVSX09CSkVDVF9NT0RFTF9FTVBUWSAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX0ZFQVRVUkVfTkFNRV9OVUxMLAotICAgICAgICJUcnlpbmcgdG8gc2V0IGEgZmVhdHVyZSB3aXRoIGEgbnVsbCBuYW1lOiB7MH0jc2V0RmVhdHVyZSggbnVsbCwgezF9KSJ9LAotCi0gIC8qKiBGaWVsZCBFUl9GRUFUVVJFX1VOS05PV04gICAgICAgICAgICAgICAgICAgICAgICovCi0KLSAgeyBFUl9GRUFUVVJFX1VOS05PV04sCi0gICAgICAgIlRyeWluZyB0byBzZXQgdGhlIHVua25vd24gZmVhdHVyZSBcInswfVwiOnsxfSNzZXRGZWF0dXJlKHswfSx7Mn0pIn0sCi0KLSAgLyoqIEZpZWxkIEVSX0dFVFRJTkdfTlVMTF9GRUFUVVJFICAgICAgICAgICAgICAgICAgICAgICAqLwotCi0gIHsgRVJfR0VUVElOR19OVUxMX0ZFQVRVUkUsCi0gICAgICAgIlRyeWluZyB0byBnZXQgYSBmZWF0dXJlIHdpdGggYSBudWxsIG5hbWU6IHswfSNnZXRGZWF0dXJlKG51bGwpIn0sCi0KLSAgLyoqIEZpZWxkIEVSX0dFVFRJTkdfTlVMTF9GRUFUVVJFICAgICAgICAgICAgICAgICAgICAgICAqLwotCi0gIHsgRVJfR0VUVElOR19VTktOT1dOX0ZFQVRVUkUsCi0gICAgICAgIlRyeWluZyB0byBnZXQgdGhlIHVua25vd24gZmVhdHVyZSBcInswfVwiOnsxfSNnZXRGZWF0dXJlKHswfSkifSwKLQotICB7RVJfU0VDVVJFUFJPQ0VTU0lOR19GRUFUVVJFLAotICAgICAgICAiRkVBVFVSRV9TRUNVUkVfUFJPQ0VTU0lORzogQ2Fubm90IHNldCB0aGUgZmVhdHVyZSB0byBmYWxzZSB3aGVuIHNlY3VyaXR5IG1hbmFnZXIgaXMgcHJlc2VudDogezF9I3NldEZlYXR1cmUoezB9LHsyfSkifSwKLQotICAvKiogRmllbGQgRVJfTlVMTF9YUEFUSF9GVU5DVElPTl9SRVNPTFZFUiAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX05VTExfWFBBVEhfRlVOQ1RJT05fUkVTT0xWRVIsCi0gICAgICAgIkF0dGVtcHRpbmcgdG8gc2V0IGEgbnVsbCBYUGF0aEZ1bmN0aW9uUmVzb2x2ZXI6ezB9I3NldFhQYXRoRnVuY3Rpb25SZXNvbHZlcihudWxsKSJ9LAotCi0gIC8qKiBGaWVsZCBFUl9OVUxMX1hQQVRIX1ZBUklBQkxFX1JFU09MVkVSICAgICAgICAgICAgICAgICAgICAgICAqLwotCi0gIHsgRVJfTlVMTF9YUEFUSF9WQVJJQUJMRV9SRVNPTFZFUiwKLSAgICAgICAiQXR0ZW1wdGluZyB0byBzZXQgYSBudWxsIFhQYXRoVmFyaWFibGVSZXNvbHZlcjp7MH0jc2V0WFBhdGhWYXJpYWJsZVJlc29sdmVyKG51bGwpIn0sCi0KLSAgLy9FTkQ6ICBEZWZpbml0aW9ucyBvZiBlcnJvciBrZXlzIHVzZWQgIGluIGV4Y2VwdGlvbiBtZXNzYWdlcyBvZiAgSkFYUCAxLjMgWFBhdGggQVBJIGltcGxlbWVudGF0aW9uCi0KLSAgLy8gV2FybmluZ3MuLi4KLQotICB7IFdHX0xPQ0FMRV9OQU1FX05PVF9IQU5ETEVELAotICAgICAgImxvY2FsZSBuYW1lIGluIHRoZSBmb3JtYXQtbnVtYmVyIGZ1bmN0aW9uIG5vdCB5ZXQgaGFuZGxlZCEifSwKLQotICB7IFdHX1BST1BFUlRZX05PVF9TVVBQT1JURUQsCi0gICAgICAiWFNMIFByb3BlcnR5IG5vdCBzdXBwb3J0ZWQ6IHswfSJ9LAotCi0gIHsgV0dfRE9OVF9ET19BTllUSElOR19XSVRIX05TLAotICAgICAgIkRvIG5vdCBjdXJyZW50bHkgZG8gYW55dGhpbmcgd2l0aCBuYW1lc3BhY2UgezB9IGluIHByb3BlcnR5OiB7MX0ifSwKLQotICB7IFdHX1NFQ1VSSVRZX0VYQ0VQVElPTiwKLSAgICAgICJTZWN1cml0eUV4Y2VwdGlvbiB3aGVuIHRyeWluZyB0byBhY2Nlc3MgWFNMIHN5c3RlbSBwcm9wZXJ0eTogezB9In0sCi0KLSAgeyBXR19RVU9fTk9fTE9OR0VSX0RFRklORUQsCi0gICAgICAiT2xkIHN5bnRheDogcXVvKC4uLikgaXMgbm8gbG9uZ2VyIGRlZmluZWQgaW4gWFBhdGguIn0sCi0KLSAgeyBXR19ORUVEX0RFUklWRURfT0JKRUNUX1RPX0lNUExFTUVOVF9OT0RFVEVTVCwKLSAgICAgICJYUGF0aCBuZWVkcyBhIGRlcml2ZWQgb2JqZWN0IHRvIGltcGxlbWVudCBub2RlVGVzdCEifSwKLQotICB7IFdHX0ZVTkNUSU9OX1RPS0VOX05PVF9GT1VORCwKLSAgICAgICJmdW5jdGlvbiB0b2tlbiBub3QgZm91bmQuIn0sCi0KLSAgeyBXR19DT1VMRE5PVF9GSU5EX0ZVTkNUSU9OLAotICAgICAgIkNvdWxkIG5vdCBmaW5kIGZ1bmN0aW9uOiB7MH0ifSwKLQotICB7IFdHX0NBTk5PVF9NQUtFX1VSTF9GUk9NLAotICAgICAgIkNhbiBub3QgbWFrZSBVUkwgZnJvbTogezB9In0sCi0KLSAgeyBXR19FWFBBTkRfRU5USVRJRVNfTk9UX1NVUFBPUlRFRCwKLSAgICAgICItRSBvcHRpb24gbm90IHN1cHBvcnRlZCBmb3IgRFRNIHBhcnNlciJ9LAotCi0gIHsgV0dfSUxMRUdBTF9WQVJJQUJMRV9SRUZFUkVOQ0UsCi0gICAgICAiVmFyaWFibGVSZWZlcmVuY2UgZ2l2ZW4gZm9yIHZhcmlhYmxlIG91dCBvZiBjb250ZXh0IG9yIHdpdGhvdXQgZGVmaW5pdGlvbiEgIE5hbWUgPSB7MH0ifSwKLQotICB7IFdHX1VOU1VQUE9SVEVEX0VOQ09ESU5HLAotICAgICAiVW5zdXBwb3J0ZWQgZW5jb2Rpbmc6IHswfSJ9LAotCi0KLQotICAvLyBPdGhlciBtaXNjZWxsYW5lb3VzIHRleHQgdXNlZCBpbnNpZGUgdGhlIGNvZGUuLi4KLSAgeyAidWlfbGFuZ3VhZ2UiLCAiZW4ifSwKLSAgeyAiaGVscF9sYW5ndWFnZSIsICJlbiJ9LAotICB7ICJsYW5ndWFnZSIsICJlbiJ9LAotICB7ICJCQURfQ09ERSIsICJQYXJhbWV0ZXIgdG8gY3JlYXRlTWVzc2FnZSB3YXMgb3V0IG9mIGJvdW5kcyJ9LAotICB7ICJGT1JNQVRfRkFJTEVEIiwgIkV4Y2VwdGlvbiB0aHJvd24gZHVyaW5nIG1lc3NhZ2VGb3JtYXQgY2FsbCJ9LAotICB7ICJ2ZXJzaW9uIiwgIj4+Pj4+Pj4gWGFsYW4gVmVyc2lvbiAifSwKLSAgeyAidmVyc2lvbjIiLCAiPDw8PDw8PCJ9LAotICB7ICJ5ZXMiLCAieWVzIn0sCi0gIHsgImxpbmUiLCAiTGluZSAjIn0sCi0gIHsgImNvbHVtbiIsICJDb2x1bW4gIyJ9LAotICB7ICJ4c2xkb25lIiwgIlhTTFByb2Nlc3NvcjogZG9uZSJ9LAotICB7ICJ4cGF0aF9vcHRpb24iLCAieHBhdGggb3B0aW9uczogIn0sCi0gIHsgIm9wdGlvbklOIiwgIiAgIFstaW4gaW5wdXRYTUxVUkxdIn0sCi0gIHsgIm9wdGlvblNlbGVjdCIsICIgICBbLXNlbGVjdCB4cGF0aCBleHByZXNzaW9uXSJ9LAotICB7ICJvcHRpb25NYXRjaCIsICIgICBbLW1hdGNoIG1hdGNoIHBhdHRlcm4gKGZvciBtYXRjaCBkaWFnbm9zdGljcyldIn0sCi0gIHsgIm9wdGlvbkFueUV4cHIiLCAiT3IganVzdCBhbiB4cGF0aCBleHByZXNzaW9uIHdpbGwgZG8gYSBkaWFnbm9zdGljIGR1bXAifSwKLSAgeyAibm9QYXJzZXJtc2cxIiwgIlhTTCBQcm9jZXNzIHdhcyBub3Qgc3VjY2Vzc2Z1bC4ifSwKLSAgeyAibm9QYXJzZXJtc2cyIiwgIioqIENvdWxkIG5vdCBmaW5kIHBhcnNlciAqKiJ9LAotICB7ICJub1BhcnNlcm1zZzMiLCAiUGxlYXNlIGNoZWNrIHlvdXIgY2xhc3NwYXRoLiJ9LAotICB7ICJub1BhcnNlcm1zZzQiLCAiSWYgeW91IGRvbid0IGhhdmUgSUJNJ3MgWE1MIFBhcnNlciBmb3IgSmF2YSwgeW91IGNhbiBkb3dubG9hZCBpdCBmcm9tIn0sCi0gIHsgIm5vUGFyc2VybXNnNSIsICJJQk0ncyBBbHBoYVdvcmtzOiBodHRwOi8vd3d3LmFscGhhd29ya3MuaWJtLmNvbS9mb3JtdWxhL3htbCJ9LAotICB7ICJndG9uZSIsICI+MSIgfSwKLSAgeyAiemVybyIsICIwIiB9LAotICB7ICJvbmUiLCAiMSIgfSwKLSAgeyAidHdvIiAsICIyIiB9LAotICB7ICJ0aHJlZSIsICIzIiB9Ci0KLSAgfTsKLQotICAvKioKLSAgICogR2V0IHRoZSBhc3NvY2lhdGlvbiBsaXN0LgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBhc3NvY2lhdGlvbiBsaXN0LgotICAgKi8KLSAgcHVibGljIE9iamVjdFtdW10gZ2V0Q29udGVudHMoKQotICB7Ci0gICAgICByZXR1cm4gX2NvbnRlbnRzOwotICB9Ci0KLQotICAvLyA9PT09PT09PT09PT09PT09PSBJTkZSQVNUUlVDVFVSRSA9PT09PT09PT09PT09PT09PT09PT09Ci0KLSAgLyoqIEZpZWxkIEJBRF9DT0RFICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEJBRF9DT0RFID0gIkJBRF9DT0RFIjsKLQotICAvKiogRmllbGQgRk9STUFUX0ZBSUxFRCAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBGT1JNQVRfRkFJTEVEID0gIkZPUk1BVF9GQUlMRUQiOwotCi0gIC8qKiBGaWVsZCBFUlJPUl9SRVNPVVJDRVMgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJST1JfUkVTT1VSQ0VTID0KLSAgICAiY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLnJlcy5YUEFUSEVycm9yUmVzb3VyY2VzIjsKLQotICAvKiogRmllbGQgRVJST1JfU1RSSU5HICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUk9SX1NUUklORyA9ICIjZXJyb3IiOwotCi0gIC8qKiBGaWVsZCBFUlJPUl9IRUFERVIgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJST1JfSEVBREVSID0gIkVycm9yOiAiOwotCi0gIC8qKiBGaWVsZCBXQVJOSU5HX0hFQURFUiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXQVJOSU5HX0hFQURFUiA9ICJXYXJuaW5nOiAiOwotCi0gIC8qKiBGaWVsZCBYU0xfSEVBREVSICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFhTTF9IRUFERVIgPSAiWFNMICI7Ci0KLSAgLyoqIEZpZWxkIFhNTF9IRUFERVIgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MX0hFQURFUiA9ICJYTUwgIjsKLQotICAvKiogRmllbGQgUVVFUllfSEVBREVSICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFFVRVJZX0hFQURFUiA9ICJQQVRURVJOICI7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvcmVzL1hQQVRIRXJyb3JSZXNvdXJjZXNfZGUuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvcmVzL1hQQVRIRXJyb3JSZXNvdXJjZXNfZGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZTc2MjRlZi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL3Jlcy9YUEFUSEVycm9yUmVzb3VyY2VzX2RlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5MzYgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucmVzOwotCi1pbXBvcnQgamF2YS51dGlsLkxpc3RSZXNvdXJjZUJ1bmRsZTsKLQotLyoqCi0gKiBTZXQgdXAgZXJyb3IgbWVzc2FnZXMuCi0gKiBXZSBidWlsZCBhIHR3byBkaW1lbnNpb25hbCBhcnJheSBvZiBtZXNzYWdlIGtleXMgYW5kCi0gKiBtZXNzYWdlIHN0cmluZ3MuIEluIG9yZGVyIHRvIGFkZCBhIG5ldyBtZXNzYWdlIGhlcmUsCi0gKiB5b3UgbmVlZCB0byBmaXJzdCBhZGQgYSBTdGF0aWMgc3RyaW5nIGNvbnN0YW50IGZvciB0aGUKLSAqIEtleSBhbmQgdXBkYXRlIHRoZSBjb250ZW50cyBhcnJheSB3aXRoIEtleSwgVmFsdWUgcGFpcgotICAqIEFsc28geW91IG5lZWQgdG8gIHVwZGF0ZSB0aGUgY291bnQgb2YgbWVzc2FnZXMoTUFYX0NPREUpb3IKLSAqIHRoZSBjb3VudCBvZiB3YXJuaW5ncyhNQVhfV0FSTklORykgWyBJbmZvcm1hdGlvbiBwdXJwb3NlIG9ubHldCi0gKiBAeHNsLnVzYWdlIGFkdmFuY2VkCi0gKi8KLXB1YmxpYyBjbGFzcyBYUEFUSEVycm9yUmVzb3VyY2VzX2RlIGV4dGVuZHMgTGlzdFJlc291cmNlQnVuZGxlCi17Ci0KLS8qCi0gKiBHZW5lcmFsIG5vdGVzIHRvIHRyYW5zbGF0b3JzOgotICoKLSAqIFRoaXMgZmlsZSBjb250YWlucyBlcnJvciBhbmQgd2FybmluZyBtZXNzYWdlcyByZWxhdGVkIHRvIFhQYXRoIEVycm9yCi0gKiBIYW5kbGluZy4KLSAqCi0gKiAgMSkgWGFsYW4gKG9yIG1vcmUgcHJvcGVybHksIFhhbGFuLWludGVycHJldGl2ZSkgYW5kIFhTTFRDIGFyZSBuYW1lcyBvZgotICogICAgIGNvbXBvbmVudHMuCi0gKiAgICAgWFNMVCBpcyBhbiBhY3JvbnltIGZvciAiWE1MIFN0eWxlc2hlZXQgTGFuZ3VhZ2U6IFRyYW5zZm9ybWF0aW9ucyIuCi0gKiAgICAgWFNMVEMgaXMgYW4gYWNyb255bSBmb3IgWFNMVCBDb21waWxlci4KLSAqCi0gKiAgMikgQSBzdHlsZXNoZWV0IGlzIGEgZGVzY3JpcHRpb24gb2YgaG93IHRvIHRyYW5zZm9ybSBhbiBpbnB1dCBYTUwgZG9jdW1lbnQKLSAqICAgICBpbnRvIGEgcmVzdWx0YW50IFhNTCBkb2N1bWVudCAob3IgSFRNTCBkb2N1bWVudCBvciB0ZXh0KS4gIFRoZQotICogICAgIHN0eWxlc2hlZXQgaXRzZWxmIGlzIGRlc2NyaWJlZCBpbiB0aGUgZm9ybSBvZiBhbiBYTUwgZG9jdW1lbnQuCi0gKgotICogIDMpIEEgdGVtcGxhdGUgaXMgYSBjb21wb25lbnQgb2YgYSBzdHlsZXNoZWV0IHRoYXQgaXMgdXNlZCB0byBtYXRjaCBhCi0gKiAgICAgcGFydGljdWxhciBwb3J0aW9uIG9mIGFuIGlucHV0IGRvY3VtZW50IGFuZCBzcGVjaWZpZXMgdGhlIGZvcm0gb2YgdGhlCi0gKiAgICAgY29ycmVzcG9uZGluZyBwb3J0aW9uIG9mIHRoZSBvdXRwdXQgZG9jdW1lbnQuCi0gKgotICogIDQpIEFuIGVsZW1lbnQgaXMgYSBtYXJrLXVwIHRhZyBpbiBhbiBYTUwgZG9jdW1lbnQ7IGFuIGF0dHJpYnV0ZSBpcyBhCi0gKiAgICAgbW9kaWZpZXIgb24gdGhlIHRhZy4gIEZvciBleGFtcGxlLCBpbiA8ZWxlbSBhdHRyPSd2YWwnIGF0dHIyPSd2YWwyJz4KLSAqICAgICAiZWxlbSIgaXMgYW4gZWxlbWVudCBuYW1lLCAiYXR0ciIgYW5kICJhdHRyMiIgYXJlIGF0dHJpYnV0ZSBuYW1lcyB3aXRoCi0gKiAgICAgdGhlIHZhbHVlcyAidmFsIiBhbmQgInZhbDIiLCByZXNwZWN0aXZlbHkuCi0gKgotICogIDUpIEEgbmFtZXNwYWNlIGRlY2xhcmF0aW9uIGlzIGEgc3BlY2lhbCBhdHRyaWJ1dGUgdGhhdCBpcyB1c2VkIHRvIGFzc29jaWF0ZQotICogICAgIGEgcHJlZml4IHdpdGggYSBVUkkgKHRoZSBuYW1lc3BhY2UpLiAgVGhlIG1lYW5pbmdzIG9mIGVsZW1lbnQgbmFtZXMgYW5kCi0gKiAgICAgYXR0cmlidXRlIG5hbWVzIHRoYXQgdXNlIHRoYXQgcHJlZml4IGFyZSBkZWZpbmVkIHdpdGggcmVzcGVjdCB0byB0aGF0Ci0gKiAgICAgbmFtZXNwYWNlLgotICoKLSAqICA2KSAiVHJhbnNsZXQiIGlzIGFuIGludmVudGVkIHRlcm0gdGhhdCBkZXNjcmliZXMgdGhlIGNsYXNzIGZpbGUgdGhhdAotICogICAgIHJlc3VsdHMgZnJvbSBjb21waWxpbmcgYW4gWE1MIHN0eWxlc2hlZXQgaW50byBhIEphdmEgY2xhc3MuCi0gKgotICogIDcpIFhQYXRoIGlzIGEgc3BlY2lmaWNhdGlvbiB0aGF0IGRlc2NyaWJlcyBhIG5vdGF0aW9uIGZvciBpZGVudGlmeWluZwotICogICAgIG5vZGVzIGluIGEgdHJlZS1zdHJ1Y3R1cmVkIHJlcHJlc2VudGF0aW9uIG9mIGFuIFhNTCBkb2N1bWVudC4gIEFuCi0gKiAgICAgaW5zdGFuY2Ugb2YgdGhhdCBub3RhdGlvbiBpcyByZWZlcnJlZCB0byBhcyBhbiBYUGF0aCBleHByZXNzaW9uLgotICoKLSAqICA4KSBUaGUgY29udGV4dCBub2RlIGlzIHRoZSBub2RlIGluIHRoZSBkb2N1bWVudCB3aXRoIHJlc3BlY3QgdG8gd2hpY2ggYW4KLSAqICAgICBYUGF0aCBleHByZXNzaW9uIGlzIGJlaW5nIGV2YWx1YXRlZC4KLSAqCi0gKiAgOSkgQW4gaXRlcmF0b3IgaXMgYW4gb2JqZWN0IHRoYXQgdHJhdmVyc2VzIG5vZGVzIGluIHRoZSB0cmVlLCBvbmUgYXQgYSB0aW1lLgotICoKLSAqICAxMCkgTkNOYW1lIGlzIGFuIFhNTCB0ZXJtIHVzZWQgdG8gZGVzY3JpYmUgYSBuYW1lIHRoYXQgZG9lcyBub3QgY29udGFpbiBhCi0gKiAgICAgY29sb24gKGEgIm5vLWNvbG9uIG5hbWUiKS4KLSAqCi0gKiAgMTEpIFFOYW1lIGlzIGFuIFhNTCB0ZXJtIG1lYW5pbmcgInF1YWxpZmllZCBuYW1lIi4KLSAqLwotCi0gIC8qCi0gICAqIHN0YXRpYyB2YXJpYWJsZXMKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUk9SMDAwMCA9ICJFUlJPUjAwMDAiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DVVJSRU5UX05PVF9BTExPV0VEX0lOX01BVENIID0KLSAgICAgICAgICJFUl9DVVJSRU5UX05PVF9BTExPV0VEX0lOX01BVENIIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ1VSUkVOVF9UQUtFU19OT19BUkdTID0KLSAgICAgICAgICJFUl9DVVJSRU5UX1RBS0VTX05PX0FSR1MiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9ET0NVTUVOVF9SRVBMQUNFRCA9ICJFUl9ET0NVTUVOVF9SRVBMQUNFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPTlRFWFRfSEFTX05PX09XTkVSRE9DID0KLSAgICAgICAgICJFUl9DT05URVhUX0hBU19OT19PV05FUkRPQyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0xPQ0FMTkFNRV9IQVNfVE9PX01BTllfQVJHUyA9Ci0gICAgICAgICAiRVJfTE9DQUxOQU1FX0hBU19UT09fTUFOWV9BUkdTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTkFNRVNQQUNFVVJJX0hBU19UT09fTUFOWV9BUkdTID0KLSAgICAgICAgICJFUl9OQU1FU1BBQ0VVUklfSEFTX1RPT19NQU5ZX0FSR1MiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT1JNQUxJWkVTUEFDRV9IQVNfVE9PX01BTllfQVJHUyA9Ci0gICAgICAgICAiRVJfTk9STUFMSVpFU1BBQ0VfSEFTX1RPT19NQU5ZX0FSR1MiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OVU1CRVJfSEFTX1RPT19NQU5ZX0FSR1MgPQotICAgICAgICAgIkVSX05VTUJFUl9IQVNfVE9PX01BTllfQVJHUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05BTUVfSEFTX1RPT19NQU5ZX0FSR1MgPQotICAgICAgICAgIkVSX05BTUVfSEFTX1RPT19NQU5ZX0FSR1MiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TVFJJTkdfSEFTX1RPT19NQU5ZX0FSR1MgPQotICAgICAgICAgIkVSX1NUUklOR19IQVNfVE9PX01BTllfQVJHUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NUUklOR0xFTkdUSF9IQVNfVE9PX01BTllfQVJHUyA9Ci0gICAgICAgICAiRVJfU1RSSU5HTEVOR1RIX0hBU19UT09fTUFOWV9BUkdTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVFJBTlNMQVRFX1RBS0VTXzNfQVJHUyA9Ci0gICAgICAgICAiRVJfVFJBTlNMQVRFX1RBS0VTXzNfQVJHUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1VOUEFSU0VERU5USVRZVVJJX1RBS0VTXzFfQVJHID0KLSAgICAgICAgICJFUl9VTlBBUlNFREVOVElUWVVSSV9UQUtFU18xX0FSRyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05BTUVTUEFDRUFYSVNfTk9UX0lNUExFTUVOVEVEID0KLSAgICAgICAgICJFUl9OQU1FU1BBQ0VBWElTX05PVF9JTVBMRU1FTlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1VOS05PV05fQVhJUyA9ICJFUl9VTktOT1dOX0FYSVMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTktOT1dOX01BVENIX09QRVJBVElPTiA9Ci0gICAgICAgICAiRVJfVU5LTk9XTl9NQVRDSF9PUEVSQVRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTkNPUlJFQ1RfQVJHX0xFTkdUSCA9IkVSX0lOQ09SUkVDVF9BUkdfTEVOR1RIIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9DT05WRVJUX1RPX05VTUJFUiA9Ci0gICAgICAgICAiRVJfQ0FOVF9DT05WRVJUX1RPX05VTUJFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfQ09OVkVSVF9YUEFUSFJFU1VMVFRZUEVfVE9fTlVNQkVSID0KLSAgICAgICAgICAgIkVSX0NBTlRfQ09OVkVSVF9YUEFUSFJFU1VMVFRZUEVfVE9fTlVNQkVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9DT05WRVJUX1RPX05PREVMSVNUID0KLSAgICAgICAgICJFUl9DQU5UX0NPTlZFUlRfVE9fTk9ERUxJU1QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX0NPTlZFUlRfVE9fTVVUQUJMRU5PREVMSVNUID0KLSAgICAgICAgICJFUl9DQU5UX0NPTlZFUlRfVE9fTVVUQUJMRU5PREVMSVNUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9DT05WRVJUX1RPX1RZUEUgPSJFUl9DQU5UX0NPTlZFUlRfVE9fVFlQRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYUEVDVEVEX01BVENIX1BBVFRFUk4gPQotICAgICAgICAgIkVSX0VYUEVDVEVEX01BVENIX1BBVFRFUk4iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRE5PVF9HRVRfVkFSX05BTUVEID0KLSAgICAgICAgICJFUl9DT1VMRE5PVF9HRVRfVkFSX05BTUVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5LTk9XTl9PUENPREUgPSAiRVJfVU5LTk9XTl9PUENPREUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FWFRSQV9JTExFR0FMX1RPS0VOUyA9IkVSX0VYVFJBX0lMTEVHQUxfVE9LRU5TIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhQRUNURURfRE9VQkxFX1FVT1RFID0KLSAgICAgICAgICJFUl9FWFBFQ1RFRF9ET1VCTEVfUVVPVEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FWFBFQ1RFRF9TSU5HTEVfUVVPVEUgPQotICAgICAgICAgIkVSX0VYUEVDVEVEX1NJTkdMRV9RVU9URSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VNUFRZX0VYUFJFU1NJT04gPSAiRVJfRU1QVFlfRVhQUkVTU0lPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYUEVDVEVEX0JVVF9GT1VORCA9ICJFUl9FWFBFQ1RFRF9CVVRfRk9VTkQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTkNPUlJFQ1RfUFJPR1JBTU1FUl9BU1NFUlRJT04gPQotICAgICAgICAgIkVSX0lOQ09SUkVDVF9QUk9HUkFNTUVSX0FTU0VSVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0JPT0xFQU5fQVJHX05PX0xPTkdFUl9PUFRJT05BTCA9Ci0gICAgICAgICAiRVJfQk9PTEVBTl9BUkdfTk9fTE9OR0VSX09QVElPTkFMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRk9VTkRfQ09NTUFfQlVUX05PX1BSRUNFRElOR19BUkcgPQotICAgICAgICAgIkVSX0ZPVU5EX0NPTU1BX0JVVF9OT19QUkVDRURJTkdfQVJHIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRk9VTkRfQ09NTUFfQlVUX05PX0ZPTExPV0lOR19BUkcgPQotICAgICAgICAgIkVSX0ZPVU5EX0NPTU1BX0JVVF9OT19GT0xMT1dJTkdfQVJHIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJFRElDQVRFX0lMTEVHQUxfU1lOVEFYID0KLSAgICAgICAgICJFUl9QUkVESUNBVEVfSUxMRUdBTF9TWU5UQVgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTExFR0FMX0FYSVNfTkFNRSA9ICJFUl9JTExFR0FMX0FYSVNfTkFNRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1VOS05PV05fTk9ERVRZUEUgPSAiRVJfVU5LTk9XTl9OT0RFVFlQRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BBVFRFUk5fTElURVJBTF9ORUVEU19CRV9RVU9URUQgPQotICAgICAgICAgIkVSX1BBVFRFUk5fTElURVJBTF9ORUVEU19CRV9RVU9URUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRE5PVF9CRV9GT1JNQVRURURfVE9fTlVNQkVSID0KLSAgICAgICAgICJFUl9DT1VMRE5PVF9CRV9GT1JNQVRURURfVE9fTlVNQkVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTEROT1RfQ1JFQVRFX1hNTFBST0NFU1NPUkxJQUlTT04gPQotICAgICAgICAgIkVSX0NPVUxETk9UX0NSRUFURV9YTUxQUk9DRVNTT1JMSUFJU09OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRElETk9UX0ZJTkRfWFBBVEhfU0VMRUNUX0VYUCA9Ci0gICAgICAgICAiRVJfRElETk9UX0ZJTkRfWFBBVEhfU0VMRUNUX0VYUCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxETk9UX0ZJTkRfRU5ET1BfQUZURVJfT1BMT0NBVElPTlBBVEggPQotICAgICAgICAgIkVSX0NPVUxETk9UX0ZJTkRfRU5ET1BfQUZURVJfT1BMT0NBVElPTlBBVEgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FUlJPUl9PQ0NVUkVEID0gIkVSX0VSUk9SX09DQ1VSRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTExFR0FMX1ZBUklBQkxFX1JFRkVSRU5DRSA9Ci0gICAgICAgICAiRVJfSUxMRUdBTF9WQVJJQUJMRV9SRUZFUkVOQ0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9BWEVTX05PVF9BTExPV0VEID0gIkVSX0FYRVNfTk9UX0FMTE9XRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9LRVlfSEFTX1RPT19NQU5ZX0FSR1MgPQotICAgICAgICAgIkVSX0tFWV9IQVNfVE9PX01BTllfQVJHUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVU5UX1RBS0VTXzFfQVJHID0gIkVSX0NPVU5UX1RBS0VTXzFfQVJHIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTEROT1RfRklORF9GVU5DVElPTiA9Ci0gICAgICAgICAiRVJfQ09VTEROT1RfRklORF9GVU5DVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1VOU1VQUE9SVEVEX0VOQ09ESU5HID0iRVJfVU5TVVBQT1JURURfRU5DT0RJTkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUk9CTEVNX0lOX0RUTV9ORVhUU0lCTElORyA9Ci0gICAgICAgICAiRVJfUFJPQkxFTV9JTl9EVE1fTkVYVFNJQkxJTkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfV1JJVEVfVE9fRU1QVFlOT0RFTElTVElNUEwgPQotICAgICAgICAgIkVSX0NBTk5PVF9XUklURV9UT19FTVBUWU5PREVMSVNUSU1QTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NFVERPTUZBQ1RPUllfTk9UX1NVUFBPUlRFRCA9Ci0gICAgICAgICAiRVJfU0VURE9NRkFDVE9SWV9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJFRklYX01VU1RfUkVTT0xWRSA9ICJFUl9QUkVGSVhfTVVTVF9SRVNPTFZFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUEFSU0VfTk9UX1NVUFBPUlRFRCA9ICJFUl9QQVJTRV9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU0FYX0FQSV9OT1RfSEFORExFRCA9ICJFUl9TQVhfQVBJX05PVF9IQU5ETEVEIjsKLXB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lHTk9SQUJMRV9XSElURVNQQUNFX05PVF9IQU5ETEVEID0KLSAgICAgICAgICJFUl9JR05PUkFCTEVfV0hJVEVTUEFDRV9OT1RfSEFORExFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0RUTV9DQU5OT1RfSEFORExFX05PREVTID0KLSAgICAgICAgICJFUl9EVE1fQ0FOTk9UX0hBTkRMRV9OT0RFUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hFUkNFU19DQU5OT1RfSEFORExFX05PREVTID0KLSAgICAgICAgICJFUl9YRVJDRVNfQ0FOTk9UX0hBTkRMRV9OT0RFUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hFUkNFU19QQVJTRV9FUlJPUl9ERVRBSUxTID0KLSAgICAgICAgICJFUl9YRVJDRVNfUEFSU0VfRVJST1JfREVUQUlMUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hFUkNFU19QQVJTRV9FUlJPUiA9ICJFUl9YRVJDRVNfUEFSU0VfRVJST1IiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX1VURjE2X1NVUlJPR0FURSA9Ci0gICAgICAgICAiRVJfSU5WQUxJRF9VVEYxNl9TVVJST0dBVEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9PSUVSUk9SID0gIkVSX09JRVJST1IiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfQ1JFQVRFX1VSTCA9ICJFUl9DQU5OT1RfQ1JFQVRFX1VSTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hQQVRIX1JFQURPQkpFQ1QgPSAiRVJfWFBBVEhfUkVBRE9CSkVDVCI7Ci0gcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRlVOQ1RJT05fVE9LRU5fTk9UX0ZPVU5EID0KLSAgICAgICAgICJFUl9GVU5DVElPTl9UT0tFTl9OT1RfRk9VTkQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfREVBTF9YUEFUSF9UWVBFID0KLSAgICAgICAgICJFUl9DQU5OT1RfREVBTF9YUEFUSF9UWVBFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9ERVNFVF9OT1RfTVVUQUJMRSA9ICJFUl9OT0RFU0VUX05PVF9NVVRBQkxFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9ERVNFVERUTV9OT1RfTVVUQUJMRSA9Ci0gICAgICAgICAiRVJfTk9ERVNFVERUTV9OT1RfTVVUQUJMRSI7Ci0gICAvKiogIFZhcmlhYmxlIG5vdCByZXNvbHZhYmxlOiAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1ZBUl9OT1RfUkVTT0xWQUJMRSA9ICJFUl9WQVJfTk9UX1JFU09MVkFCTEUiOwotICAgLyoqIE51bGwgZXJyb3IgaGFuZGxlciAgKi8KLSBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OVUxMX0VSUk9SX0hBTkRMRVIgPSAiRVJfTlVMTF9FUlJPUl9IQU5ETEVSIjsKLSAgIC8qKiAgUHJvZ3JhbW1lcidzIGFzc2VydGlvbjogdW5rbm93biBvcGNvZGUgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BST0dfQVNTRVJUX1VOS05PV05fT1BDT0RFID0KLSAgICAgICAgICJFUl9QUk9HX0FTU0VSVF9VTktOT1dOX09QQ09ERSI7Ci0gICAvKiogIDAgb3IgMSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1pFUk9fT1JfT05FID0gIkVSX1pFUk9fT1JfT05FIjsKLSAgIC8qKiAgcnRmKCkgbm90IHN1cHBvcnRlZCBieSBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1JURl9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSID0KLSAgICAgICAgICJFUl9SVEZfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiI7Ci0gICAvKiogIGFzTm9kZUl0ZXJhdG9yKCkgbm90IHN1cHBvcnRlZCBieSBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FTTk9ERUlURVJBVE9SX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIgPSAiRVJfQVNOT0RFSVRFUkFUT1JfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiI7Ci0gICAvKiogIGZzYigpIG5vdCBzdXBwb3J0ZWQgZm9yIFhTdHJpbmdGb3JDaGFycyAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZTQl9OT1RfU1VQUE9SVEVEX1hTVFJJTkdGT1JDSEFSUyA9Ci0gICAgICAgICAiRVJfRlNCX05PVF9TVVBQT1JURURfWFNUUklOR0ZPUkNIQVJTIjsKLSAgIC8qKiAgQ291bGQgbm90IGZpbmQgdmFyaWFibGUgd2l0aCB0aGUgbmFtZSBvZiAgICovCi0gcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTERfTk9UX0ZJTkRfVkFSID0gIkVSX0NPVUxEX05PVF9GSU5EX1ZBUiI7Ci0gICAvKiogIFhTdHJpbmdGb3JDaGFycyBjYW4gbm90IHRha2UgYSBzdHJpbmcgZm9yIGFuIGFyZ3VtZW50ICAgKi8KLSBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YU1RSSU5HRk9SQ0hBUlNfQ0FOTk9UX1RBS0VfU1RSSU5HID0KLSAgICAgICAgICJFUl9YU1RSSU5HRk9SQ0hBUlNfQ0FOTk9UX1RBS0VfU1RSSU5HIjsKLSAgIC8qKiAgVGhlIEZhc3RTdHJpbmdCdWZmZXIgYXJndW1lbnQgY2FuIG5vdCBiZSBudWxsICAgKi8KLSBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GQVNUU1RSSU5HQlVGRkVSX0NBTk5PVF9CRV9OVUxMID0KLSAgICAgICAgICJFUl9GQVNUU1RSSU5HQlVGRkVSX0NBTk5PVF9CRV9OVUxMIjsKLSAgIC8qKiAgMiBvciAzICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVFdPX09SX1RIUkVFID0gIkVSX1RXT19PUl9USFJFRSI7Ci0gICAvKiogVmFyaWFibGUgYWNjZXNzZWQgYmVmb3JlIGl0IGlzIGJvdW5kISAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9WQVJJQUJMRV9BQ0NFU1NFRF9CRUZPUkVfQklORCA9Ci0gICAgICAgICAiRVJfVkFSSUFCTEVfQUNDRVNTRURfQkVGT1JFX0JJTkQiOwotICAgLyoqIFhTdHJpbmdGb3JGU0IgY2FuIG5vdCB0YWtlIGEgc3RyaW5nIGZvciBhbiBhcmd1bWVudCEgKi8KLSBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GU0JfQ0FOTk9UX1RBS0VfU1RSSU5HID0KLSAgICAgICAgICJFUl9GU0JfQ0FOTk9UX1RBS0VfU1RSSU5HIjsKLSAgIC8qKiBFcnJvciEgU2V0dGluZyB0aGUgcm9vdCBvZiBhIHdhbGtlciB0byBudWxsISAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TRVRUSU5HX1dBTEtFUl9ST09UX1RPX05VTEwgPQotICAgICAgICAgIkVSX1NFVFRJTkdfV0FMS0VSX1JPT1RfVE9fTlVMTCI7Ci0gICAvKiogVGhpcyBOb2RlU2V0RFRNIGNhbiBub3QgaXRlcmF0ZSB0byBhIHByZXZpb3VzIG5vZGUhICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PREVTRVREVE1fQ0FOTk9UX0lURVJBVEUgPQotICAgICAgICAgIkVSX05PREVTRVREVE1fQ0FOTk9UX0lURVJBVEUiOwotICAvKiogVGhpcyBOb2RlU2V0IGNhbiBub3QgaXRlcmF0ZSB0byBhIHByZXZpb3VzIG5vZGUhICovCi0gcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9ERVNFVF9DQU5OT1RfSVRFUkFURSA9Ci0gICAgICAgICAiRVJfTk9ERVNFVF9DQU5OT1RfSVRFUkFURSI7Ci0gIC8qKiBUaGlzIE5vZGVTZXREVE0gY2FuIG5vdCBkbyBpbmRleGluZyBvciBjb3VudGluZyBmdW5jdGlvbnMhICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PREVTRVREVE1fQ0FOTk9UX0lOREVYID0KLSAgICAgICAgICJFUl9OT0RFU0VURFRNX0NBTk5PVF9JTkRFWCI7Ci0gIC8qKiBUaGlzIE5vZGVTZXQgY2FuIG5vdCBkbyBpbmRleGluZyBvciBjb3VudGluZyBmdW5jdGlvbnMhICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PREVTRVRfQ0FOTk9UX0lOREVYID0KLSAgICAgICAgICJFUl9OT0RFU0VUX0NBTk5PVF9JTkRFWCI7Ci0gIC8qKiBDYW4gbm90IGNhbGwgc2V0U2hvdWxkQ2FjaGVOb2RlcyBhZnRlciBuZXh0Tm9kZSBoYXMgYmVlbiBjYWxsZWQhICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9DQUxMX1NFVFNIT1VMRENBQ0hFTk9ERSA9Ci0gICAgICAgICAiRVJfQ0FOTk9UX0NBTExfU0VUU0hPVUxEQ0FDSEVOT0RFIjsKLSAgLyoqIHswfSBvbmx5IGFsbG93cyB7MX0gYXJndW1lbnRzICovCi0gcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfT05MWV9BTExPV1MgPSAiRVJfT05MWV9BTExPV1MiOwotICAvKiogUHJvZ3JhbW1lcidzIGFzc2VydGlvbiBpbiBnZXROZXh0U3RlcFBvczogdW5rbm93biBzdGVwVHlwZTogezB9ICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1VOS05PV05fU1RFUCA9ICJFUl9VTktOT1dOX1NURVAiOwotICAvKiogUHJvYmxlbSB3aXRoIFJlbGF0aXZlTG9jYXRpb25QYXRoICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYUEVDVEVEX1JFTF9MT0NfUEFUSCA9Ci0gICAgICAgICAiRVJfRVhQRUNURURfUkVMX0xPQ19QQVRIIjsKLSAgLyoqIFByb2JsZW0gd2l0aCBMb2NhdGlvblBhdGggKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhQRUNURURfTE9DX1BBVEggPSAiRVJfRVhQRUNURURfTE9DX1BBVEgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FWFBFQ1RFRF9MT0NfUEFUSF9BVF9FTkRfRVhQUiA9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkVSX0VYUEVDVEVEX0xPQ19QQVRIX0FUX0VORF9FWFBSIjsKLSAgLyoqIFByb2JsZW0gd2l0aCBTdGVwICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYUEVDVEVEX0xPQ19TVEVQID0gIkVSX0VYUEVDVEVEX0xPQ19TVEVQIjsKLSAgLyoqIFByb2JsZW0gd2l0aCBOb2RlVGVzdCAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FWFBFQ1RFRF9OT0RFX1RFU1QgPSAiRVJfRVhQRUNURURfTk9ERV9URVNUIjsKLSAgLyoqIEV4cGVjdGVkIHN0ZXAgcGF0dGVybiAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FWFBFQ1RFRF9TVEVQX1BBVFRFUk4gPQotICAgICAgICAiRVJfRVhQRUNURURfU1RFUF9QQVRURVJOIjsKLSAgLyoqIEV4cGVjdGVkIHJlbGF0aXZlIHBhdGggcGF0dGVybiAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FWFBFQ1RFRF9SRUxfUEFUSF9QQVRURVJOID0KLSAgICAgICAgICJFUl9FWFBFQ1RFRF9SRUxfUEFUSF9QQVRURVJOIjsKLSAgLyoqIEVSX0NBTlRfQ09OVkVSVF9YUEFUSFJFU1VMVFRZUEVfVE9fQk9PTEVBTiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX0NPTlZFUlRfVE9fQk9PTEVBTiA9Ci0gICAgICAgICAiRVJfQ0FOVF9DT05WRVJUX1RPX0JPT0xFQU4iOwotICAvKiogRmllbGQgRVJfQ0FOVF9DT05WRVJUX1RPX1NJTkdMRU5PREUgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9DT05WRVJUX1RPX1NJTkdMRU5PREUgPQotICAgICAgICAgIkVSX0NBTlRfQ09OVkVSVF9UT19TSU5HTEVOT0RFIjsKLSAgLyoqIEZpZWxkIEVSX0NBTlRfR0VUX1NOQVBTSE9UX0xFTkdUSCAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfR0VUX1NOQVBTSE9UX0xFTkdUSCA9Ci0gICAgICAgICAiRVJfQ0FOVF9HRVRfU05BUFNIT1RfTEVOR1RIIjsKLSAgLyoqIEZpZWxkIEVSX05PTl9JVEVSQVRPUl9UWVBFICAgICAgICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PTl9JVEVSQVRPUl9UWVBFID0gIkVSX05PTl9JVEVSQVRPUl9UWVBFIjsKLSAgLyoqIEZpZWxkIEVSX0RPQ19NVVRBVEVEICAgICAgICAgICAgICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0RPQ19NVVRBVEVEID0gIkVSX0RPQ19NVVRBVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9YUEFUSF9UWVBFID0gIkVSX0lOVkFMSURfWFBBVEhfVFlQRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VNUFRZX1hQQVRIX1JFU1VMVCA9ICJFUl9FTVBUWV9YUEFUSF9SRVNVTFQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTkNPTVBBVElCTEVfVFlQRVMgPSAiRVJfSU5DT01QQVRJQkxFX1RZUEVTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTlVMTF9SRVNPTFZFUiA9ICJFUl9OVUxMX1JFU09MVkVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9DT05WRVJUX1RPX1NUUklORyA9Ci0gICAgICAgICAiRVJfQ0FOVF9DT05WRVJUX1RPX1NUUklORyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PTl9TTkFQU0hPVF9UWVBFID0gIkVSX05PTl9TTkFQU0hPVF9UWVBFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfV1JPTkdfRE9DVU1FTlQgPSAiRVJfV1JPTkdfRE9DVU1FTlQiOwotICAvKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIFhQYXRoIGV4cHJlc3Npb24gY2Fubm90IGJlIGV2YWx1YXRlZCB3aXRoIHJlc3BlY3QKLSAgICogdG8gdGhpcyB0eXBlIG9mIG5vZGUuCi0gICAqLwotICAvKiogRmllbGQgRVJfV1JPTkdfTk9ERVRZUEUgICAgICAgICAgICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1dST05HX05PREVUWVBFID0gIkVSX1dST05HX05PREVUWVBFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWFBBVEhfRVJST1IgPSAiRVJfWFBBVEhfRVJST1IiOwotCi0gIC8vQkVHSU46IEtleXMgbmVlZGVkIGZvciBleGNlcHRpb24gbWVzc2FnZXMgb2YgIEpBWFAgMS4zIFhQYXRoIEFQSSBpbXBsZW1lbnRhdGlvbgotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FWFRFTlNJT05fRlVOQ1RJT05fQ0FOTk9UX0JFX0lOVk9LRUQgPSAiRVJfRVhURU5TSU9OX0ZVTkNUSU9OX0NBTk5PVF9CRV9JTlZPS0VEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUkVTT0xWRV9WQVJJQUJMRV9SRVRVUk5TX05VTEwgPSAiRVJfUkVTT0xWRV9WQVJJQUJMRV9SRVRVUk5TX05VTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTlNVUFBPUlRFRF9SRVRVUk5fVFlQRSA9ICJFUl9VTlNVUFBPUlRFRF9SRVRVUk5fVFlQRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NPVVJDRV9SRVRVUk5fVFlQRV9DQU5OT1RfQkVfTlVMTCA9ICJFUl9TT1VSQ0VfUkVUVVJOX1RZUEVfQ0FOTk9UX0JFX05VTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9BUkdfQ0FOTk9UX0JFX05VTEwgPSAiRVJfQVJHX0NBTk5PVF9CRV9OVUxMIjsKLQotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9PQkpFQ1RfTU9ERUxfTlVMTCA9ICJFUl9PQkpFQ1RfTU9ERUxfTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX09CSkVDVF9NT0RFTF9FTVBUWSA9ICJFUl9PQkpFQ1RfTU9ERUxfRU1QVFkiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GRUFUVVJFX05BTUVfTlVMTCA9ICJFUl9GRUFUVVJFX05BTUVfTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZFQVRVUkVfVU5LTk9XTiA9ICJFUl9GRUFUVVJFX1VOS05PV04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9HRVRUSU5HX05VTExfRkVBVFVSRSA9ICJFUl9HRVRUSU5HX05VTExfRkVBVFVSRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0dFVFRJTkdfVU5LTk9XTl9GRUFUVVJFID0gIkVSX0dFVFRJTkdfVU5LTk9XTl9GRUFUVVJFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU0VDVVJFUFJPQ0VTU0lOR19GRUFUVVJFID0gIkVSX1NFQ1VSRVBST0NFU1NJTkdfRkVBVFVSRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05VTExfWFBBVEhfRlVOQ1RJT05fUkVTT0xWRVIgPSAiRVJfTlVMTF9YUEFUSF9GVU5DVElPTl9SRVNPTFZFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05VTExfWFBBVEhfVkFSSUFCTEVfUkVTT0xWRVIgPSAiRVJfTlVMTF9YUEFUSF9WQVJJQUJMRV9SRVNPTFZFUiI7Ci0gIC8vRU5EOiBLZXlzIG5lZWRlZCBmb3IgZXhjZXB0aW9uIG1lc3NhZ2VzIG9mICBKQVhQIDEuMyBYUGF0aCBBUEkgaW1wbGVtZW50YXRpb24KLQotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19MT0NBTEVfTkFNRV9OT1RfSEFORExFRCA9Ci0gICAgICAgICAiV0dfTE9DQUxFX05BTUVfTk9UX0hBTkRMRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19QUk9QRVJUWV9OT1RfU1VQUE9SVEVEID0KLSAgICAgICAgICJXR19QUk9QRVJUWV9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfRE9OVF9ET19BTllUSElOR19XSVRIX05TID0KLSAgICAgICAgICJXR19ET05UX0RPX0FOWVRISU5HX1dJVEhfTlMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19TRUNVUklUWV9FWENFUFRJT04gPSAiV0dfU0VDVVJJVFlfRVhDRVBUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfUVVPX05PX0xPTkdFUl9ERUZJTkVEID0KLSAgICAgICAgICJXR19RVU9fTk9fTE9OR0VSX0RFRklORUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19ORUVEX0RFUklWRURfT0JKRUNUX1RPX0lNUExFTUVOVF9OT0RFVEVTVCA9Ci0gICAgICAgICAiV0dfTkVFRF9ERVJJVkVEX09CSkVDVF9UT19JTVBMRU1FTlRfTk9ERVRFU1QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19GVU5DVElPTl9UT0tFTl9OT1RfRk9VTkQgPQotICAgICAgICAgIldHX0ZVTkNUSU9OX1RPS0VOX05PVF9GT1VORCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0NPVUxETk9UX0ZJTkRfRlVOQ1RJT04gPQotICAgICAgICAgIldHX0NPVUxETk9UX0ZJTkRfRlVOQ1RJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19DQU5OT1RfTUFLRV9VUkxfRlJPTSA9IldHX0NBTk5PVF9NQUtFX1VSTF9GUk9NIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfRVhQQU5EX0VOVElUSUVTX05PVF9TVVBQT1JURUQgPQotICAgICAgICAgIldHX0VYUEFORF9FTlRJVElFU19OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfSUxMRUdBTF9WQVJJQUJMRV9SRUZFUkVOQ0UgPQotICAgICAgICAgIldHX0lMTEVHQUxfVkFSSUFCTEVfUkVGRVJFTkNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfVU5TVVBQT1JURURfRU5DT0RJTkcgPSJXR19VTlNVUFBPUlRFRF9FTkNPRElORyI7Ci0KLSAgLyoqICBkZXRhY2goKSBub3Qgc3VwcG9ydGVkIGJ5IFhSVHJlZUZyYWdTZWxlY3RXcmFwcGVyICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfREVUQUNIX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIgPQotICAgICAgICAgIkVSX0RFVEFDSF9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSIjsKLSAgLyoqICBudW0oKSBub3Qgc3VwcG9ydGVkIGJ5IFhSVHJlZUZyYWdTZWxlY3RXcmFwcGVyICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTlVNX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIgPQotICAgICAgICAgIkVSX05VTV9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSIjsKLSAgLyoqICB4c3RyKCkgbm90IHN1cHBvcnRlZCBieSBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hTVFJfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiA9Ci0gICAgICAgICAiRVJfWFNUUl9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSIjsKLSAgLyoqICBzdHIoKSBub3Qgc3VwcG9ydGVkIGJ5IFhSVHJlZUZyYWdTZWxlY3RXcmFwcGVyICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU1RSX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIgPQotICAgICAgICAgIkVSX1NUUl9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSIjsKLQotICAvLyBFcnJvciBtZXNzYWdlcy4uLgotCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIE9iamVjdFtdW10gX2NvbnRlbnRzID0gbmV3IE9iamVjdFtdW117Ci0KLSAgeyAiRVJST1IwMDAwIiAsICJ7MH0iIH0sCi0KLSAgeyBFUl9DVVJSRU5UX05PVF9BTExPV0VEX0lOX01BVENILCAiY3VycmVudCgpLUZ1bmt0aW9uIGlzdCBuaWNodCB6dWxcdTAwRTRzc2lnIGluIGVpbmVtIFZlcmdsZWljaHNtdXN0ZXIuIiB9LAotCi0gIHsgRVJfQ1VSUkVOVF9UQUtFU19OT19BUkdTLCAiY3VycmVudCgpLUZ1bmt0aW9uIGFremVwdGllcnQga2VpbmUgQXJndW1lbnRlLiIgfSwKLQotICB7IEVSX0RPQ1VNRU5UX1JFUExBQ0VELAotICAgICAgImRvY3VtZW50KCktRnVua3Rpb25zaW1wbGVtZW50aWVydW5nIHd1cmRlIGR1cmNoIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0LkZ1bmNEb2N1bWVudCBlcnNldHp0LiJ9LAotCi0gIHsgRVJfQ09OVEVYVF9IQVNfTk9fT1dORVJET0MsCi0gICAgICAiS29udGV4dCBoYXQga2VpbiBFaWdlbnRcdTAwRkNtZXJkb2t1bWVudC4ifSwKLQotICB7IEVSX0xPQ0FMTkFNRV9IQVNfVE9PX01BTllfQVJHUywKLSAgICAgICJsb2NhbC1uYW1lKCkgaGF0IHp1IHZpZWxlIEFyZ3VtZW50ZS4ifSwKLQotICB7IEVSX05BTUVTUEFDRVVSSV9IQVNfVE9PX01BTllfQVJHUywKLSAgICAgICJuYW1lc3BhY2UtdXJpKCkgaGF0IHp1IHZpZWxlIEFyZ3VtZW50ZS4ifSwKLQotICB7IEVSX05PUk1BTElaRVNQQUNFX0hBU19UT09fTUFOWV9BUkdTLAotICAgICAgIm5vcm1hbGl6ZS1zcGFjZSgpIGhhdCB6dSB2aWVsZSBBcmd1bWVudGUuIn0sCi0KLSAgeyBFUl9OVU1CRVJfSEFTX1RPT19NQU5ZX0FSR1MsCi0gICAgICAibnVtYmVyKCkgaGF0IHp1IHZpZWxlIEFyZ3VtZW50ZS4ifSwKLQotICB7IEVSX05BTUVfSEFTX1RPT19NQU5ZX0FSR1MsCi0gICAgICJuYW1lKCkgaGF0IHp1IHZpZWxlIEFyZ3VtZW50ZS4ifSwKLQotICB7IEVSX1NUUklOR19IQVNfVE9PX01BTllfQVJHUywKLSAgICAgICJzdHJpbmcoKSBoYXQgenUgdmllbGUgQXJndW1lbnRlLiJ9LAotCi0gIHsgRVJfU1RSSU5HTEVOR1RIX0hBU19UT09fTUFOWV9BUkdTLAotICAgICAgInN0cmluZy1sZW5ndGgoKSBoYXQgenUgdmllbGUgQXJndW1lbnRlLiJ9LAotCi0gIHsgRVJfVFJBTlNMQVRFX1RBS0VTXzNfQVJHUywKLSAgICAgICJ0cmFuc2xhdGUoKS1GdW5rdGlvbiBha3plcHRpZXJ0IGRyZWkgQXJndW1lbnRlLiJ9LAotCi0gIHsgRVJfVU5QQVJTRURFTlRJVFlVUklfVEFLRVNfMV9BUkcsCi0gICAgICAidW5wYXJzZWQtZW50aXR5LXVyaS1GdW5rdGlvbiBzb2xsdGUgZWluIEFyZ3VtZW50IGFremVwdGllcmVuLiJ9LAotCi0gIHsgRVJfTkFNRVNQQUNFQVhJU19OT1RfSU1QTEVNRU5URUQsCi0gICAgICAiTmFtZXNwYWNlLUFjaHNlIG5vY2ggbmljaHQgaW1wbGVtZW50aWVydC4ifSwKLQotICB7IEVSX1VOS05PV05fQVhJUywKLSAgICAgIlVuYmVrYW5udGUgQWNoc2U6IHswfSJ9LAotCi0gIHsgRVJfVU5LTk9XTl9NQVRDSF9PUEVSQVRJT04sCi0gICAgICJVbmJla2FubnRlciBWZXJnbGVpY2hzdm9yZ2FuZy4ifSwKLQotICB7IEVSX0lOQ09SUkVDVF9BUkdfTEVOR1RILAotICAgICAgIkFyZ3VtZW50bFx1MDBFNG5nZSB2b24gcHJvY2Vzc2luZy1pbnN0cnVjdGlvbigpLUtub3RlbnRlc3QgaXN0IGZhbHNjaC4ifSwKLQotICB7IEVSX0NBTlRfQ09OVkVSVF9UT19OVU1CRVIsCi0gICAgICAiezB9IGthbm4gbmljaHQgaW4gZWluZSBaYWhsIGtvbnZlcnRpZXJ0IHdlcmRlbiJ9LAotCi0gIHsgRVJfQ0FOVF9DT05WRVJUX1RPX05PREVMSVNULAotICAgICAgInswfSBrYW5uIG5pY2h0IGluIGVpbmUgTm9kZUxpc3Qga29udmVydGllcnQgd2VyZGVuLiJ9LAotCi0gIHsgRVJfQ0FOVF9DT05WRVJUX1RPX01VVEFCTEVOT0RFTElTVCwKLSAgICAgICJ7MH0ga2FubiBuaWNodCBpbiBOb2RlU2V0RFRNIGtvbnZlcnRpZXJ0IHdlcmRlbi4ifSwKLQotICB7IEVSX0NBTlRfQ09OVkVSVF9UT19UWVBFLAotICAgICAgInswfSBrYW5uIG5pY2h0IGluIHR5cGUjezF9IGtvbnZlcnRpZXJ0IHdlcmRlbiJ9LAotCi0gIHsgRVJfRVhQRUNURURfTUFUQ0hfUEFUVEVSTiwKLSAgICAgICJWZXJnbGVpY2hzbXVzdGVyIGluIGdldE1hdGNoU2NvcmUgZXJ3YXJ0ZXQuIn0sCi0KLSAgeyBFUl9DT1VMRE5PVF9HRVRfVkFSX05BTUVELAotICAgICAgIlZhcmlhYmxlIG1pdCBOYW1lbiB7MH0ga2FubiBuaWNodCBhYmdlcnVmZW4gd2VyZGVuIn0sCi0KLSAgeyBFUl9VTktOT1dOX09QQ09ERSwKLSAgICAgIkVSUk9SLiBVbmJla2FubnRlciBWb3JnYW5nc2NvZGU6IHswfSJ9LAotCi0gIHsgRVJfRVhUUkFfSUxMRUdBTF9UT0tFTlMsCi0gICAgICJadXNcdTAwRTR0emxpY2hlIHVuZ1x1MDBGQ2x0aWdlIFRva2VuczogezB9In0sCi0KLSAgeyBFUl9FWFBFQ1RFRF9ET1VCTEVfUVVPVEUsCi0gICAgICAiTGl0ZXJhbCBpbiBmYWxzY2hlbiBBbmZcdTAwRkNocnVuZ3N6ZWljaGVuLi4uIERvcHBlbHRlIEFuZlx1MDBGQ2hydW5nc3plaWNoZW4gZXJ3YXJ0ZXQuIn0sCi0KLSAgeyBFUl9FWFBFQ1RFRF9TSU5HTEVfUVVPVEUsCi0gICAgICAiTGl0ZXJhbCBpbiBmYWxzY2hlbiBBbmZcdTAwRkNocnVuZ3N6ZWljaGVuLi4uIEVpbnplbG5lIEFuZlx1MDBGQ2hydW5nc3plaWNoZW4gZXJ3YXJ0ZXQuIn0sCi0KLSAgeyBFUl9FTVBUWV9FWFBSRVNTSU9OLAotICAgICAiTGVlcmVyIEF1c2RydWNrLiJ9LAotCi0gIHsgRVJfRVhQRUNURURfQlVUX0ZPVU5ELAotICAgICAiezB9IGVyd2FydGV0LCBhYmVyIHsxfSBnZWZ1bmRlbiJ9LAotCi0gIHsgRVJfSU5DT1JSRUNUX1BST0dSQU1NRVJfQVNTRVJUSU9OLAotICAgICAgIlByb2dyYW1taWVyZXItQXNzZXJ0aW9uIGlzdCBmYWxzY2guIC0gezB9In0sCi0KLSAgeyBFUl9CT09MRUFOX0FSR19OT19MT05HRVJfT1BUSU9OQUwsCi0gICAgICAiYm9vbGVhbiguLi4pLUFyZ3VtZW50IGlzdCBuaWNodCBtZWhyIG9wdGlvbmFsIGJlaSAxOTk5MDcwOSBYUGF0aC1FbnR3dXJmLiJ9LAotCi0gIHsgRVJfRk9VTkRfQ09NTUFfQlVUX05PX1BSRUNFRElOR19BUkcsCi0gICAgICAiXCIsXCIgZ2VmdW5kZW4sIGFiZXIga2VpbiB2b3JhdXNnZWhlbmRlcyBBcmd1bWVudCB2b3JoYW5kZW4uIn0sCi0KLSAgeyBFUl9GT1VORF9DT01NQV9CVVRfTk9fRk9MTE9XSU5HX0FSRywKLSAgICAgICJcIixcIiBnZWZ1bmRlbiwgYWJlciBrZWluIGZvbGdlbmRlcyBBcmd1bWVudCB2b3JoYW5kZW4uIn0sCi0KLSAgeyBFUl9QUkVESUNBVEVfSUxMRUdBTF9TWU5UQVgsCi0gICAgICAiXCIuLltwcmVkaWNhdGVdXCIgb2RlciBcIi5bcHJlZGljYXRlXVwiIGlzdCB1bmdcdTAwRkNsdGlnZSBTeW50YXguIFZlcndlbmRlbiBTaWUgc3RhdHRkZXNzZW4gXCJzZWxmOjpub2RlKClbcHJlZGljYXRlXVwiLiJ9LAotCi0gIHsgRVJfSUxMRUdBTF9BWElTX05BTUUsCi0gICAgICJVbmdcdTAwRkNsdGlnZXIgQWNoc2VubmFtZTogezB9In0sCi0KLSAgeyBFUl9VTktOT1dOX05PREVUWVBFLAotICAgICAiVW5iZWthbm50ZXIgS25vdGVudHlwOiB7MH0ifSwKLQotICB7IEVSX1BBVFRFUk5fTElURVJBTF9ORUVEU19CRV9RVU9URUQsCi0gICAgICAiTXVzdGVybGl0ZXJhbCAoezB9KSBtdXNzIGluIEFuZlx1MDBGQ2hydW5nc3plaWNoZW4gZ2VzZXR6dCB3ZXJkZW4uIn0sCi0KLSAgeyBFUl9DT1VMRE5PVF9CRV9GT1JNQVRURURfVE9fTlVNQkVSLAotICAgICAgInswfSBrb25udGUgbmljaHQgYWxzIFphaGwgZm9ybWF0aWVydCB3ZXJkZW4uIn0sCi0KLSAgeyBFUl9DT1VMRE5PVF9DUkVBVEVfWE1MUFJPQ0VTU09STElBSVNPTiwKLSAgICAgICJYTUwtVHJhbnNmb3JtZXJGYWN0b3J5LUxpYWlzb24ga29ubnRlIG5pY2h0IGVyc3RlbGx0IHdlcmRlbjogezB9In0sCi0KLSAgeyBFUl9ESUROT1RfRklORF9YUEFUSF9TRUxFQ1RfRVhQLAotICAgICAgIkZlaGxlci4geHBhdGgtU0VMRUNULUF1c2RydWNrICgtc2VsZWN0KSBuaWNodCBnZWZ1bmRlbi4ifSwKLQotICB7IEVSX0NPVUxETk9UX0ZJTkRfRU5ET1BfQUZURVJfT1BMT0NBVElPTlBBVEgsCi0gICAgICAiRVJST1IuIEVORE9QIG5hY2ggT1BfTE9DQVRJT05QQVRIIGtvbm50ZSBuaWNodCBnZWZ1bmRlbiB3ZXJkZW4ifSwKLQotICB7IEVSX0VSUk9SX09DQ1VSRUQsCi0gICAgICJGZWhsZXIgYXVmZ2V0cmV0ZW4uIn0sCi0KLSAgeyBFUl9JTExFR0FMX1ZBUklBQkxFX1JFRkVSRU5DRSwKLSAgICAgICJWYXJpYWJsZVJlZmVyZW5jZSBhdVx1MDBERmVyaGFsYiBkZXMgS29udGV4dHMgb2RlciBvaG5lIERlZmluaXRpb24gZlx1MDBGQ3IgVmFyaWFibGUgYW5nZWdlYmVuLiBOYW1lID0gezB9In0sCi0KLSAgeyBFUl9BWEVTX05PVF9BTExPV0VELAotICAgICAgIk51ciBcImNoaWxkOjpcIi0gdW5kIFwiYXR0cmlidXRlOjpcIi1BY2hzZW4gc2luZCBpbiBWZXJnbGVpY2hzbXVzdGVybiB6dWxcdTAwRTRzc2lnLiBCZXRyZWZmZW5kZSBBY2hzZW4gPSB7MH0ifSwKLQotICB7IEVSX0tFWV9IQVNfVE9PX01BTllfQVJHUywKLSAgICAgICJrZXkoKSBoYXQgZWluZSBmYWxzY2hlIEFuemFobCBBcmd1bWVudGUuIn0sCi0KLSAgeyBFUl9DT1VOVF9UQUtFU18xX0FSRywKLSAgICAgICJjb3VudC1GdW5rdGlvbiBzb2xsdGUgZWluIEFyZ3VtZW50IGFremVwdGllcmVuLiJ9LAotCi0gIHsgRVJfQ09VTEROT1RfRklORF9GVU5DVElPTiwKLSAgICAgIkZ1bmt0aW9uIGtvbm50ZSBuaWNodCBnZWZ1bmRlbiB3ZXJkZW46IHswfSJ9LAotCi0gIHsgRVJfVU5TVVBQT1JURURfRU5DT0RJTkcsCi0gICAgICJOaWNodCB1bnRlcnN0XHUwMEZDdHp0ZSBDb2RpZXJ1bmc6IHswfSJ9LAotCi0gIHsgRVJfUFJPQkxFTV9JTl9EVE1fTkVYVFNJQkxJTkcsCi0gICAgICAiUHJvYmxlbSBpbiBEVE0gaW4gZ2V0TmV4dFNpYmxpbmcgYXVmZ2V0cmV0ZW4uLi4gRXMgd2lyZCB2ZXJzdWNodCwgZGFzIFByb2JsZW0genUgYmVoZWJlbiJ9LAotCi0gIHsgRVJfQ0FOTk9UX1dSSVRFX1RPX0VNUFRZTk9ERUxJU1RJTVBMLAotICAgICAgIlByb2dyYW1taWVyZXJmZWhsZXI6IEVzIGthbm4gbmljaHQgaW4gRW1wdHlOb2RlTGlzdCBnZXNjaHJpZWJlbiB3ZXJkZW4uIn0sCi0KLSAgeyBFUl9TRVRET01GQUNUT1JZX05PVF9TVVBQT1JURUQsCi0gICAgICAic2V0RE9NRmFjdG9yeSB3aXJkIG5pY2h0IHZvbiBYUGF0aENvbnRleHQgdW50ZXJzdFx1MDBGQ3R6dC4ifSwKLQotICB7IEVSX1BSRUZJWF9NVVNUX1JFU09MVkUsCi0gICAgICAiUHJcdTAwRTRmaXggbXVzcyBhbHMgTmFtZXNwYWNlIGF1ZmdlbFx1MDBGNnN0IHdlcmRlbjogezB9In0sCi0KLSAgeyBFUl9QQVJTRV9OT1RfU1VQUE9SVEVELAotICAgICAgInBhcnNlIChJbnB1dFNvdXJjZS1RdWVsbGUpIG5pY2h0IHVudGVyc3RcdTAwRkN0enQgaW4gWFBhdGhDb250ZXh0LiB7MH0ga2FubiBuaWNodCBnZVx1MDBGNmZmbmV0IHdlcmRlbiJ9LAotCi0gIHsgRVJfU0FYX0FQSV9OT1RfSEFORExFRCwKLSAgICAgICJTQVgtQVBJLVplaWNoZW4oY2hhciBjaFtdLi4uIG5pY2h0IHZlcmFyYmVpdGV0IHZvbiBEVE0uIn0sCi0KLSAgeyBFUl9JR05PUkFCTEVfV0hJVEVTUEFDRV9OT1RfSEFORExFRCwKLSAgICAgICJpZ25vcmFibGVXaGl0ZXNwYWNlKGNoYXIgY2hbXS4uLiBuaWNodCB2ZXJhcmJlaXRldCB2b24gRFRNLiJ9LAotCi0gIHsgRVJfRFRNX0NBTk5PVF9IQU5ETEVfTk9ERVMsCi0gICAgICAiRFRNTGlhaXNvbiBrYW5uIGtlaW5lIEtub3RlbiBkZXMgVHlwcyB7MH0gdmVyYXJiZWl0ZW4ifSwKLQotICB7IEVSX1hFUkNFU19DQU5OT1RfSEFORExFX05PREVTLAotICAgICAgIkRPTTJIZWxwZXIga2FubiBrZWluZSBLbm90ZW4gZGVzIFR5cHMgezB9IHZlcmFyYmVpdGVuIn0sCi0KLSAgeyBFUl9YRVJDRVNfUEFSU0VfRVJST1JfREVUQUlMUywKLSAgICAgICJET00ySGVscGVyLnBhcnNlLUZlaGxlcjogU3lzdGVtSUQgLSB7MH0gWmVpbGUgLSB7MX0ifSwKLQotICB7IEVSX1hFUkNFU19QQVJTRV9FUlJPUiwKLSAgICAgIkRPTTJIZWxwZXIucGFyc2UtRmVobGVyIn0sCi0KLSAgeyBFUl9JTlZBTElEX1VURjE2X1NVUlJPR0FURSwKLSAgICAgICJVbmdcdTAwRkNsdGlnZSBVVEYtMTYtRXJzZXR6dW5nIGZlc3RnZXN0ZWxsdDogezB9PyJ9LAotCi0gIHsgRVJfT0lFUlJPUiwKLSAgICAgIkkvTy1GZWhsZXIifSwKLQotICB7IEVSX0NBTk5PVF9DUkVBVEVfVVJMLAotICAgICAiVVJMIGZcdTAwRkNyIHswfSBrYW5uIG5pY2h0IGVyc3RlbGx0IHdlcmRlbiJ9LAotCi0gIHsgRVJfWFBBVEhfUkVBRE9CSkVDVCwKLSAgICAgIkluIFhQYXRoLnJlYWRPYmplY3Q6IHswfSJ9LAotCi0gIHsgRVJfRlVOQ1RJT05fVE9LRU5fTk9UX0ZPVU5ELAotICAgICAgIkZ1bmt0aW9uc3Rva2VuIG5pY2h0IGdlZnVuZGVuLiJ9LAotCi0gIHsgRVJfQ0FOTk9UX0RFQUxfWFBBVEhfVFlQRSwKLSAgICAgICAiWFBhdGgtVHlwIHswfSBrYW5uIG5pY2h0IGJlYXJiZWl0ZXQgd2VyZGVuIn0sCi0KLSAgeyBFUl9OT0RFU0VUX05PVF9NVVRBQkxFLAotICAgICAgICJEaWVzZXMgTm9kZVNldCBpc3QgbmljaHQgbXV0aWVyYmFyIn0sCi0KLSAgeyBFUl9OT0RFU0VURFRNX05PVF9NVVRBQkxFLAotICAgICAgICJEaWVzZXMgTm9kZVNldERUTSBpc3QgbmljaHQgbXV0aWVyYmFyIn0sCi0KLSAgeyBFUl9WQVJfTk9UX1JFU09MVkFCTEUsCi0gICAgICAgICJWYXJpYWJsZSBrYW5uIG5pY2h0IGF1ZmdlbFx1MDBGNnN0IHdlcmRlbjogezB9In0sCi0KLSAgeyBFUl9OVUxMX0VSUk9SX0hBTkRMRVIsCi0gICAgICAgICJOdWxsLUVycm9yIEhhbmRsZXIifSwKLQotICB7IEVSX1BST0dfQVNTRVJUX1VOS05PV05fT1BDT0RFLAotICAgICAgICJQcm9ncmFtbWllcmVyLUFzc2VydGlvbjogVW5iZWthbm50ZXIgVm9yZ2FuZ3Njb2RlOiB7MH0ifSwKLQotICB7IEVSX1pFUk9fT1JfT05FLAotICAgICAgICIwIG9kZXIgMSJ9LAotCi0gIHsgRVJfUlRGX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIsCi0gICAgICAgInJ0ZigpIG5pY2h0IHVudGVyc3RcdTAwRkN0enQgdm9uIFhSVHJlZUZyYWdTZWxlY3RXcmFwcGVyIn0sCi0KLSAgeyBFUl9SVEZfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiwKLSAgICAgICAiYXNOb2RlSXRlcmF0b3IoKSBuaWNodCB1bnRlcnN0XHUwMEZDdHp0IHZvbiBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciJ9LAotCi0gICAgICAgIC8qKiAgZGV0YWNoKCkgbm90IHN1cHBvcnRlZCBieSBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciAgICovCi0gICB7IEVSX0RFVEFDSF9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSLAotICAgICAgICAgICAgICAgICJkZXRhY2goKSBuaWNodCB1bnRlcnN0XHUwMEZDdHp0IHZvbiBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciJ9LAotCi0gICAgICAgIC8qKiAgbnVtKCkgbm90IHN1cHBvcnRlZCBieSBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciAgICovCi0gICB7IEVSX05VTV9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSLAotICAgICAgICAgICAgICAgICJudW0oKSBuaWNodCB1bnRlcnN0XHUwMEZDdHp0IHZvbiBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciJ9LAotCi0gICAgICAgIC8qKiAgeHN0cigpIG5vdCBzdXBwb3J0ZWQgYnkgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIgICAqLwotICAgeyBFUl9YU1RSX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIsCi0gICAgICAgICAgICAgICAgInhzdHIoKSBuaWNodCB1bnRlcnN0XHUwMEZDdHp0IHZvbiBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciJ9LAotCi0gICAgICAgIC8qKiAgc3RyKCkgbm90IHN1cHBvcnRlZCBieSBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciAgICovCi0gICB7IEVSX1NUUl9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSLAotICAgICAgICAgICAgICAgICJzdHIoKSBuaWNodCB1bnRlcnN0XHUwMEZDdHp0IHZvbiBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciJ9LAotCi0gIHsgRVJfRlNCX05PVF9TVVBQT1JURURfWFNUUklOR0ZPUkNIQVJTLAotICAgICAgICJmc2IoKSBuaWNodCB1bnRlcnN0XHUwMEZDdHp0IGZcdTAwRkNyIFhTdHJpbmdGb3JDaGFycyJ9LAotCi0gIHsgRVJfQ09VTERfTk9UX0ZJTkRfVkFSLAotICAgICAgIlZhcmlhYmxlIG1pdCBOYW1lbiB7MH0ga29ubnRlIG5pY2h0IGdlZnVuZGVuIHdlcmRlbiJ9LAotCi0gIHsgRVJfWFNUUklOR0ZPUkNIQVJTX0NBTk5PVF9UQUtFX1NUUklORywKLSAgICAgICJYU3RyaW5nRm9yQ2hhcnMga2FubiBrZWluZSBaZWljaGVuZm9sZ2UgYWxzIEFyZ3VtZW50IGFremVwdGllcmVuIn0sCi0KLSAgeyBFUl9GQVNUU1RSSU5HQlVGRkVSX0NBTk5PVF9CRV9OVUxMLAotICAgICAgIkZhc3RTdHJpbmdCdWZmZXItQXJndW1lbnQgZGFyZiBuaWNodCBudWxsIHNlaW4ifSwKLQotICB7IEVSX1RXT19PUl9USFJFRSwKLSAgICAgICAiMiBvZGVyIDMifSwKLQotICB7IEVSX1ZBUklBQkxFX0FDQ0VTU0VEX0JFRk9SRV9CSU5ELAotICAgICAgICJBdWYgVmFyaWFibGUgd3VyZGUgenVnZWdyaWZmZW4sIGJldm9yIHNpZSBnZWJ1bmRlbiB3dXJkZS4ifSwKLQotICB7IEVSX0ZTQl9DQU5OT1RfVEFLRV9TVFJJTkcsCi0gICAgICAgIlhTdHJpbmdGb3JGU0Iga2FubiBrZWluZSBaZWljaGVuZm9sZ2UgYWxzIEFyZ3VtZW50IGFremVwdGllcmVuLiJ9LAotCi0gIHsgRVJfU0VUVElOR19XQUxLRVJfUk9PVF9UT19OVUxMLAotICAgICAgICJcbiAhISEhIEZlaGxlci4gUm9vdCBlaW5lcyBXYWxrZXJzIHdpcmQgYXVmIG51bGwgZ2VzZXR6dC4ifSwKLQotICB7IEVSX05PREVTRVREVE1fQ0FOTk9UX0lURVJBVEUsCi0gICAgICAgIk5vZGVTZXREVE0ga2FubiBuaWNodCB6dSBlaW5lbSB2b3JoZXJpZ2VuIEtub3RlbiBpdGVyaWVyZW4uIn0sCi0KLSAgeyBFUl9OT0RFU0VUX0NBTk5PVF9JVEVSQVRFLAotICAgICAgICJOb2RlU2V0IGthbm4gbmljaHQgenUgZWluZW0gdm9yaGVyaWdlbiBLbm90ZW4gaXRlcmllcmVuLiJ9LAotCi0gIHsgRVJfTk9ERVNFVERUTV9DQU5OT1RfSU5ERVgsCi0gICAgICAgIk5vZGVTZXREVE0ga2FubiBrZWluZSBJbmRleGllcnVuZ3MtIG9kZXIgWlx1MDBFNGhsZnVua3Rpb25lbiBhdXNmXHUwMEZDaHJlbi4ifSwKLQotICB7IEVSX05PREVTRVRfQ0FOTk9UX0lOREVYLAotICAgICAgICJOb2RlU2V0IGthbm4ga2VpbmUgSW5kZXhpZXJ1bmdzLSBvZGVyIFpcdTAwRTRobGZ1bmt0aW9uZW4gYXVzZlx1MDBGQ2hyZW4uIn0sCi0KLSAgeyBFUl9DQU5OT1RfQ0FMTF9TRVRTSE9VTERDQUNIRU5PREUsCi0gICAgICAgInNldFNob3VsZENhY2hlTm9kZXMga2FubiBuaWNodCBhdWZnZXJ1ZmVuIHdlcmRlbiwgbmFjaGRlbSBuZXh0Tm9kZSBhdWZnZXJ1ZmVuIHd1cmRlLiJ9LAotCi0gIHsgRVJfT05MWV9BTExPV1MsCi0gICAgICAgInswfSBsXHUwMEU0c3N0IG51ciB7MX0gQXJndW1lbnRlIHp1In0sCi0KLSAgeyBFUl9VTktOT1dOX1NURVAsCi0gICAgICAgIlByb2dyYW1taWVyZXItQXNzZXJ0aW9uIGluIGdldE5leHRTdGVwUG9zOiBVbmJla2FubnRlciBzdGVwVHlwZTogezB9In0sCi0KLSAgLy9Ob3RlIHRvIHRyYW5zbGF0b3JzOiAgQSByZWxhdGl2ZSBsb2NhdGlvbiBwYXRoIGlzIGEgZm9ybSBvZiBYUGF0aCBleHByZXNzaW9uLgotICAvLyBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCBzdWNoIGFuIGV4cHJlc3Npb24gd2FzIGV4cGVjdGVkIGZvbGxvd2luZyB0aGUKLSAgLy8gY2hhcmFjdGVycyAnLycgb3IgJy8vJywgYnV0IHdhcyBub3QgZm91bmQuCi0gIHsgRVJfRVhQRUNURURfUkVMX0xPQ19QQVRILAotICAgICAgIk5hY2ggZGVtIFRva2VuIFwiL1wiIG9kZXIgXCIvL1wiIHd1cmRlIGVpbiByZWxhdGl2ZXIgVmVyemVpY2huaXNwZmFkIGVyd2FydGV0LiJ9LAotCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBIGxvY2F0aW9uIHBhdGggaXMgYSBmb3JtIG9mIFhQYXRoIGV4cHJlc3Npb24uCi0gIC8vIFRoZSBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHN5bnRhY3RpY2FsbHkgc3VjaCBhbiBleHByZXNzaW9uIHdhcyBleHBlY3RlZCxidXQKLSAgLy8gdGhlIGNoYXJhY3RlcnMgc3BlY2lmaWVkIGJ5IHRoZSBzdWJzdGl0dXRpb24gdGV4dCB3ZXJlIGVuY291bnRlcmVkIGluc3RlYWQuCi0gIHsgRVJfRVhQRUNURURfTE9DX1BBVEgsCi0gICAgICAgIkVpbiBWZXJ6ZWljaG5pc3BmYWQgd3VyZGUgZXJ3YXJ0ZXQsIGFiZXIgZGFzIGZvbGdlbmRlIFRva2VuIHd1cmRlIGdlZnVuZGVuOiB7MH0ifSwKLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQSBsb2NhdGlvbiBwYXRoIGlzIGEgZm9ybSBvZiBYUGF0aCBleHByZXNzaW9uLgotICAvLyBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCBzeW50YWN0aWNhbGx5IHN1Y2ggYSBzdWJleHByZXNzaW9uIHdhcyBleHBlY3RlZCwKLSAgLy8gYnV0IG5vIG1vcmUgY2hhcmFjdGVycyB3ZXJlIGZvdW5kIGluIHRoZSBleHByZXNzaW9uLgotICB7IEVSX0VYUEVDVEVEX0xPQ19QQVRIX0FUX0VORF9FWFBSLAotICAgICAgICJFaW4gVmVyemVpY2huaXNwZmFkIHd1cmRlIGVyd2FydGV0LCBhYmVyIHN0YXR0ZGVzc2VuIHd1cmRlIGRhcyBFbmRlIGRlcyBYUGF0aC1BdXNkcnVja3MgZ2VmdW5kZW4uIn0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIEEgbG9jYXRpb24gc3RlcCBpcyBwYXJ0IG9mIGFuIFhQYXRoIGV4cHJlc3Npb24uCi0gIC8vIFRoZSBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHN5bnRhY3RpY2FsbHkgc3VjaCBhbiBleHByZXNzaW9uIHdhcyBleHBlY3RlZAotICAvLyBmb2xsb3dpbmcgdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXJzLgotICB7IEVSX0VYUEVDVEVEX0xPQ19TVEVQLAotICAgICAgICJOYWNoIGRlbSBUb2tlbiBcIi9cIiBvZGVyIFwiLy9cIiB3dXJkZSBlaW4gVmVyemVpY2huaXNzY2hyaXR0IGVyd2FydGV0LiJ9LAotCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBIG5vZGUgdGVzdCBpcyBwYXJ0IG9mIGFuIFhQYXRoIGV4cHJlc3Npb24gdGhhdCBpcwotICAvLyB1c2VkIHRvIHRlc3QgZm9yIHBhcnRpY3VsYXIga2luZHMgb2Ygbm9kZXMuICBJbiB0aGlzIGNhc2UsIGEgbm9kZSB0ZXN0IHRoYXQKLSAgLy8gY29uc2lzdHMgb2YgYW4gTkNOYW1lIGZvbGxvd2VkIGJ5IGEgY29sb24gYW5kIGFuIGFzdGVyaXNrIG9yIHRoYXQgY29uc2lzdHMKLSAgLy8gb2YgYSBRTmFtZSB3YXMgZXhwZWN0ZWQsIGJ1dCB3YXMgbm90IGZvdW5kLgotICB7IEVSX0VYUEVDVEVEX05PREVfVEVTVCwKLSAgICAgICAiRXMgd3VyZGUgZWluIEtub3RlbnRlc3QgZXJ3YXJ0ZXQsIGRlciBlbnR3ZWRlciBOQ05hbWU6KiBvZGVyIFFOYW1lIGVudHNwcmljaHQuIn0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIEEgc3RlcCBwYXR0ZXJuIGlzIHBhcnQgb2YgYW4gWFBhdGggZXhwcmVzc2lvbi4KLSAgLy8gVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgc3ludGFjdGljYWxseSBzdWNoIGFuIGV4cHJlc3Npb24gd2FzIGV4cGVjdGVkLAotICAvLyBidXQgdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXIgd2FzIGZvdW5kIGluIHRoZSBleHByZXNzaW9uIGluc3RlYWQuCi0gIHsgRVJfRVhQRUNURURfU1RFUF9QQVRURVJOLAotICAgICAgICJFaW4gU2Nocml0dG11c3RlciB3dXJkZSBlcndhcnRldCwgYWJlciBcIi9cIiB3dXJkZSBnZWZ1bmRlbi4ifSwKLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiBBIHJlbGF0aXZlIHBhdGggcGF0dGVybiBpcyBwYXJ0IG9mIGFuIFhQYXRoIGV4cHJlc3Npb24uCi0gIC8vIFRoZSBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHN5bnRhY3RpY2FsbHkgc3VjaCBhbiBleHByZXNzaW9uIHdhcyBleHBlY3RlZCwKLSAgLy8gYnV0IHdhcyBub3QgZm91bmQuCi0gIHsgRVJfRVhQRUNURURfUkVMX1BBVEhfUEFUVEVSTiwKLSAgICAgICAiRWluIHJlbGF0aXZlcyBQZmFkbXVzdGVyIHd1cmRlIGVyd2FydGV0LiJ9LAotCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYSBkYXRhIHR5cGUuICBUaGUKLSAgLy8gbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCBhIHZhbHVlIG9mIGEgcGFydGljdWxhciB0eXBlIGNvdWxkIG5vdCBiZSBjb252ZXJ0ZWQKLSAgLy8gdG8gYSB2YWx1ZSBvZiB0eXBlIGJvb2xlYW4uCi0gIHsgRVJfQ0FOVF9DT05WRVJUX1RPX0JPT0xFQU4sCi0gICAgICAgIlhQYXRoUmVzdWx0IHZvbiBYUGF0aC1BdXNkcnVjayBcInswfVwiIGhhdCBYUGF0aFJlc3VsdFR5cGUgezF9LCBkZXIgbmljaHQgaW4gZWluZW4gYm9vbGVzY2hlbiBXZXJ0IGtvbnZlcnRpZXJ0IHdlcmRlbiBrYW5uLiJ9LAotCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6IERvIG5vdCB0cmFuc2xhdGUgQU5ZX1VOT1JERVJFRF9OT0RFX1RZUEUgYW5kCi0gIC8vIEZJUlNUX09SREVSRURfTk9ERV9UWVBFLgotICB7IEVSX0NBTlRfQ09OVkVSVF9UT19TSU5HTEVOT0RFLAotICAgICAgICJYUGF0aFJlc3VsdCB2b24gWFBhdGgtQXVzZHJ1Y2sgXCJ7MH1cIiBoYXQgWFBhdGhSZXN1bHRUeXBlIHsxfSwgZGVyIG5pY2h0IGluIGVpbmVuIGVpbnplbG5lbiBLbm90ZW4ga29udmVydGllcnQgd2VyZGVuIGthbm4uIERpZSBNZXRob2RlIFwiZ2V0U2luZ2xlTm9kZVZhbHVlXCIgZ2lsdCBudXIgZlx1MDBGQ3IgZGllIFR5cGVuIEFOWV9VTk9SREVSRURfTk9ERV9UWVBFIHVuZCBGSVJTVF9PUkRFUkVEX05PREVfVFlQRS4ifSwKLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiBEbyBub3QgdHJhbnNsYXRlIFVOT1JERVJFRF9OT0RFX1NOQVBTSE9UX1RZUEUgYW5kCi0gIC8vIE9SREVSRURfTk9ERV9TTkFQU0hPVF9UWVBFLgotICB7IEVSX0NBTlRfR0VUX1NOQVBTSE9UX0xFTkdUSCwKLSAgICAgICAiRGllIE1ldGhvZGUgXCJnZXRTbmFwc2hvdExlbmd0aFwiIGthbm4gbmljaHQgZlx1MDBGQ3IgWFBhdGhSZXN1bHQgdm9uIFhQYXRoLUF1c2RydWNrIFwiezB9XCIgYXVmZ2VydWZlbiB3ZXJkZW4sIGRhIGRlciB6dWdlaFx1MDBGNnJpZ2UgWFBhdGhSZXN1bHRUeXBlIHsxfSBpc3QuIERpZXNlIE1ldGhvZGUgZ2lsdCBudXIgZlx1MDBGQ3IgZGllIFR5cGVuIFVOT1JERVJFRF9OT0RFX1NOQVBTSE9UX1RZUEUgdW5kIE9SREVSRURfTk9ERV9TTkFQU0hPVF9UWVBFLiJ9LAotCi0gIHsgRVJfTk9OX0lURVJBVE9SX1RZUEUsCi0gICAgICAgIkRpZSBNZXRob2RlIFwiaXRlcmF0ZU5leHRcIiBrYW5uIG5pY2h0IGZcdTAwRkNyIFhQYXRoUmVzdWx0IHZvbiBYUGF0aC1BdXNkcnVjayBcInswfVwiIGF1ZmdlcnVmZW4gd2VyZGVuLCBkYSBkZXIgenVnZWhcdTAwRjZyaWdlIFhQYXRoUmVzdWx0VHlwZSB7MX0gaXN0LiBEaWVzZSBNZXRob2RlIGdpbHQgbnVyIGZcdTAwRkNyIGRpZSBUeXBlbiBVTk9SREVSRURfTk9ERV9JVEVSQVRPUl9UWVBFIHVuZCBPUkRFUkVEX05PREVfSVRFUkFUT1JfVFlQRS4ifSwKLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiBUaGlzIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhlIGRvY3VtZW50IGJlaW5nIG9wZXJhdGVkCi0gIC8vIHVwb24gY2hhbmdlZCwgc28gdGhlIGl0ZXJhdG9yIG9iamVjdCB0aGF0IHdhcyBiZWluZyB1c2VkIHRvIHRyYXZlcnNlIHRoZQotICAvLyBkb2N1bWVudCBoYXMgbm93IGJlY29tZSBpbnZhbGlkLgotICB7IEVSX0RPQ19NVVRBVEVELAotICAgICAgICJEb2t1bWVudCBnZVx1MDBFNG5kZXJ0LCBzZWl0IEVyZ2VibmlzIHp1clx1MDBGQ2NrZ2VnZWJlbiB3dXJkZS4gSXRlcmF0b3IgaXN0IHVuZ1x1MDBGQ2x0aWcuIn0sCi0KLSAgeyBFUl9JTlZBTElEX1hQQVRIX1RZUEUsCi0gICAgICAgIlVuZ1x1MDBGQ2x0aWdlcyBYUGF0aC1UeXBhcmd1bWVudDogezB9In0sCi0KLSAgeyBFUl9FTVBUWV9YUEFUSF9SRVNVTFQsCi0gICAgICAgIkxlZXJlcyBYUGF0aC1FcmdlYm5pc29iamVrdCJ9LAotCi0gIHsgRVJfSU5DT01QQVRJQkxFX1RZUEVTLAotICAgICAgICJYUGF0aFJlc3VsdCB2b24gWFBhdGgtQXVzZHJ1Y2sgXCJ7MH1cIiBoYXQgWFBhdGhSZXN1bHRUeXBlIHsxfSwgZGVyIG5pY2h0IGluIGRlbiBhbmdlZ2ViZW5lbiBYUGF0aFJlc3VsdFR5cGUgezJ9IGdlXHUwMEU0bmRlcnQgd2VyZGVuIGthbm4uIn0sCi0KLSAgeyBFUl9OVUxMX1JFU09MVkVSLAotICAgICAgICJQclx1MDBFNGZpeCBrYW5uIG5pY2h0IG1pdCBOdWxsLVByXHUwMEU0Zml4LVJlc29sdmVyIGF1ZmdlbFx1MDBGNnN0IHdlcmRlbi4ifSwKLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIGEgZGF0YSB0eXBlLiAgVGhlCi0gIC8vIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgYSB2YWx1ZSBvZiBhIHBhcnRpY3VsYXIgdHlwZSBjb3VsZCBub3QgYmUgY29udmVydGVkCi0gIC8vIHRvIGEgdmFsdWUgb2YgdHlwZSBzdHJpbmcuCi0gIHsgRVJfQ0FOVF9DT05WRVJUX1RPX1NUUklORywKLSAgICAgICAiWFBhdGhSZXN1bHQgdm9uIFhQYXRoLUF1c2RydWNrIFwiezB9XCIgaGF0IFhQYXRoUmVzdWx0VHlwZSB7MX0sIGRlciBuaWNodCBpbiBlaW5lIFplaWNoZW5mb2xnZSBrb252ZXJ0aWVydCB3ZXJkZW4ga2Fubi4ifSwKLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiBEbyBub3QgdHJhbnNsYXRlIHNuYXBzaG90SXRlbSwKLSAgLy8gVU5PUkRFUkVEX05PREVfU05BUFNIT1RfVFlQRSBhbmQgT1JERVJFRF9OT0RFX1NOQVBTSE9UX1RZUEUuCi0gIHsgRVJfTk9OX1NOQVBTSE9UX1RZUEUsCi0gICAgICAgIkRpZSBNZXRob2RlIFwic25hcHNob3RJdGVtXCIga2FubiBuaWNodCBmXHUwMEZDciBYUGF0aFJlc3VsdCB2b24gWFBhdGgtQXVzZHJ1Y2sgXCJ7MH1cIiBhdWZnZXJ1ZmVuIHdlcmRlbiwgZGEgZGVyIHp1Z2VoXHUwMEY2cmlnZSBYUGF0aFJlc3VsdFR5cGUgezF9IGlzdC4gRGllc2UgTWV0aG9kZSBnaWx0IG51ciBmXHUwMEZDciBkaWUgVHlwZW4gVU5PUkRFUkVEX05PREVfU05BUFNIT1RfVFlQRSB1bmQgT1JERVJFRF9OT0RFX1NOQVBTSE9UX1RZUEUuIn0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFhQYXRoRXZhbHVhdG9yIGlzIGEgSmF2YSBpbnRlcmZhY2UgbmFtZS4gIEFuCi0gIC8vIFhQYXRoRXZhbHVhdG9yIGlzIGNyZWF0ZWQgd2l0aCByZXNwZWN0IHRvIGEgcGFydGljdWxhciBYTUwgZG9jdW1lbnQsIGFuZCBpbgotICAvLyB0aGlzIGNhc2UgdGhlIGV4cHJlc3Npb24gcmVwcmVzZW50ZWQgYnkgdGhpcyBvYmplY3Qgd2FzIGJlaW5nIGV2YWx1YXRlZCB3aXRoCi0gIC8vIHJlc3BlY3QgdG8gYSBjb250ZXh0IG5vZGUgZnJvbSBhIGRpZmZlcmVudCBkb2N1bWVudC4KLSAgeyBFUl9XUk9OR19ET0NVTUVOVCwKLSAgICAgICAiS29udGV4dGtub3RlbiBnZWhcdTAwRjZydCBuaWNodCB6dW0gRG9rdW1lbnQsIGRhcyBhbiBkaWVzZW4gWFBhdGhFdmFsdWF0b3IgZ2VidW5kZW4gaXN0LiJ9LAotCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgWFBhdGggZXhwcmVzc2lvbiBjYW5ub3QgYmUgZXZhbHVhdGVkIHdpdGggcmVzcGVjdAotICAvLyB0byB0aGlzIHR5cGUgb2Ygbm9kZS4KLSAgeyBFUl9XUk9OR19OT0RFVFlQRSwKLSAgICAgICAiS29udGV4dGtub3RlbnR5cCB3aXJkIG5pY2h0IHVudGVyc3RcdTAwRkN0enQuIn0sCi0KLSAgeyBFUl9YUEFUSF9FUlJPUiwKLSAgICAgICAiVW5iZWthbm50ZXIgRmVobGVyIGluIFhQYXRoLiJ9LAotCi0gIHsgRVJfQ0FOVF9DT05WRVJUX1hQQVRIUkVTVUxUVFlQRV9UT19OVU1CRVIsCi0gICAgICAgICJYUGF0aFJlc3VsdCB2b24gWFBhdGgtQXVzZHJ1Y2sgXCJ7MH1cIiBoYXQgWFBhdGhSZXN1bHRUeXBlIHsxfSwgZGVyIG5pY2h0IGluIGVpbmUgWmFobCBrb252ZXJ0aWVydCB3ZXJkZW4ga2FubiJ9LAotCi0gIC8vQkVHSU46ICBEZWZpbml0aW9ucyBvZiBlcnJvciBrZXlzIHVzZWQgIGluIGV4Y2VwdGlvbiBtZXNzYWdlcyBvZiAgSkFYUCAxLjMgWFBhdGggQVBJIGltcGxlbWVudGF0aW9uCi0KLSAgLyoqIEZpZWxkIEVSX0VYVEVOU0lPTl9GVU5DVElPTl9DQU5OT1RfQkVfSU5WT0tFRCAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX0VYVEVOU0lPTl9GVU5DVElPTl9DQU5OT1RfQkVfSU5WT0tFRCwKLSAgICAgICAiRXJ3ZWl0ZXJ1bmdzZnVua3Rpb24gXCJ7MH1cIiBrYW5uIG5pY2h0IGF1ZmdlcnVmZW4gd2VyZGVuLCB3ZW5uIGRhcyBGZWF0dXJlIFwiWE1MQ29uc3RhbnRzLkZFQVRVUkVfU0VDVVJFX1BST0NFU1NJTkdcIiBhdWYgXCJ0cnVlXCIgZ2VzZXR6dCBpc3QuIn0sCi0KLSAgLyoqIEZpZWxkIEVSX1JFU09MVkVfVkFSSUFCTEVfUkVUVVJOU19OVUxMICAgICAgICAgICAgICAgICAgICAgICAqLwotCi0gIHsgRVJfUkVTT0xWRV9WQVJJQUJMRV9SRVRVUk5TX05VTEwsCi0gICAgICAgInJlc29sdmVWYXJpYWJsZSBmXHUwMEZDciBWYXJpYWJsZSB7MH0gZ2lidCBudWxsIHp1clx1MDBGQ2NrIn0sCi0KLSAgLyoqIEZpZWxkIEVSX1VOU1VQUE9SVEVEX1JFVFVSTl9UWVBFICAgICAgICAgICAgICAgICAgICAgICAqLwotCi0gIHsgRVJfVU5TVVBQT1JURURfUkVUVVJOX1RZUEUsCi0gICAgICAgIk5pY2h0IHVudGVyc3RcdTAwRkN0enRlciBSXHUwMEZDY2tnYWJldHlwOiB7MH0ifSwKLQotICAvKiogRmllbGQgRVJfU09VUkNFX1JFVFVSTl9UWVBFX0NBTk5PVF9CRV9OVUxMICAgICAgICAgICAgICAgICAgICAgICAqLwotCi0gIHsgRVJfU09VUkNFX1JFVFVSTl9UWVBFX0NBTk5PVF9CRV9OVUxMLAotICAgICAgICJRdWVsbGUgdW5kL29kZXIgUlx1MDBGQ2NrZ2FiZXR5cCBkXHUwMEZDcmZlbiBuaWNodCBudWxsIHNlaW4ifSwKLQotICAvKiogRmllbGQgRVJfU09VUkNFX1JFVFVSTl9UWVBFX0NBTk5PVF9CRV9OVUxMICAgICAgICAgICAgICAgICAgICAgICAqLwotCi0gIHsgRVJfU09VUkNFX1JFVFVSTl9UWVBFX0NBTk5PVF9CRV9OVUxMLAotICAgICAgICJRdWVsbGUgdW5kL29kZXIgUlx1MDBGQ2NrZ2FiZXR5cCBkXHUwMEZDcmZlbiBuaWNodCBudWxsIHNlaW4ifSwKLQotICAvKiogRmllbGQgRVJfQVJHX0NBTk5PVF9CRV9OVUxMICAgICAgICAgICAgICAgICAgICAgICAqLwotCi0gIHsgRVJfQVJHX0NBTk5PVF9CRV9OVUxMLAotICAgICAgICJ7MH0tQXJndW1lbnQgZGFyZiBuaWNodCBudWxsIHNlaW4ifSwKLQotICAvKiogRmllbGQgRVJfT0JKRUNUX01PREVMX05VTEwgICAgICAgICAgICAgICAgICAgICAgICovCi0KLSAgeyBFUl9PQkpFQ1RfTU9ERUxfTlVMTCwKLSAgICAgICAiezB9I2lzT2JqZWN0TW9kZWxTdXBwb3J0ZWQoIFN0cmluZyBvYmplY3RNb2RlbCApIGthbm4gbmljaHQgbWl0IG9iamVjdE1vZGVsID09IG51bGwgYXVmZ2VydWZlbiB3ZXJkZW4ifSwKLQotICAvKiogRmllbGQgRVJfT0JKRUNUX01PREVMX0VNUFRZICAgICAgICAgICAgICAgICAgICAgICAqLwotCi0gIHsgRVJfT0JKRUNUX01PREVMX0VNUFRZLAotICAgICAgICJ7MH0jaXNPYmplY3RNb2RlbFN1cHBvcnRlZCggU3RyaW5nIG9iamVjdE1vZGVsICkga2FubiBuaWNodCBtaXQgb2JqZWN0TW9kZWwgPT0gXCJcIiBhdWZnZXJ1ZmVuIHdlcmRlbiJ9LAotCi0gIC8qKiBGaWVsZCBFUl9PQkpFQ1RfTU9ERUxfRU1QVFkgICAgICAgICAgICAgICAgICAgICAgICovCi0KLSAgeyBFUl9GRUFUVVJFX05BTUVfTlVMTCwKLSAgICAgICAiRXMgd2lyZCB2ZXJzdWNodCwgZWluIEZlYXR1cmUgbWl0IGVpbmVtIE51bGwtTmFtZW4gZmVzdHp1bGVnZW46IHswfSNzZXRGZWF0dXJlKCBudWxsLCB7MX0pIn0sCi0KLSAgLyoqIEZpZWxkIEVSX0ZFQVRVUkVfVU5LTk9XTiAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX0ZFQVRVUkVfVU5LTk9XTiwKLSAgICAgICAiRXMgd2lyZCB2ZXJzdWNodCwgZWluIHVuYmVrYW5udGVzIEZlYXR1cmUgXCJ7MH1cIiBmZXN0enVsZWdlbjp7MX0jc2V0RmVhdHVyZSh7MH0sezJ9KSJ9LAotCi0gIC8qKiBGaWVsZCBFUl9HRVRUSU5HX05VTExfRkVBVFVSRSAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX0dFVFRJTkdfTlVMTF9GRUFUVVJFLAotICAgICAgICJFcyB3aXJkIHZlcnN1Y2h0LCBlaW4gRmVhdHVyZSBtaXQgZWluZW0gTnVsbC1OYW1lbiBhYnp1cnVmZW46IHswfSNnZXRGZWF0dXJlKG51bGwpIn0sCi0KLSAgLyoqIEZpZWxkIEVSX0dFVFRJTkdfTlVMTF9GRUFUVVJFICAgICAgICAgICAgICAgICAgICAgICAqLwotCi0gIHsgRVJfR0VUVElOR19VTktOT1dOX0ZFQVRVUkUsCi0gICAgICAgIkVzIHdpcmQgdmVyc3VjaHQsIGRhcyB1bmJla2FubnRlIEZlYXR1cmUgXCJ7MH1cIiBhYnp1cnVmZW46ezF9I2dldEZlYXR1cmUoezB9KSJ9LAotCi0gIHtFUl9TRUNVUkVQUk9DRVNTSU5HX0ZFQVRVUkUsCi0gICAgICAgICJGRUFUVVJFX1NFQ1VSRV9QUk9DRVNTSU5HOiBGZWF0dXJlIGthbm4gbmljaHQgYXVmIFwiZmFsc2VcIiBnZXNldHp0IHdlcmRlbiwgd2VubiBTZWN1cml0eSBNYW5hZ2VyIHZvcmhhbmRlbiBpc3Q6IHsxfSNzZXRGZWF0dXJlKHswfSx7Mn0pIn0sCi0KLSAgLyoqIEZpZWxkIEVSX05VTExfWFBBVEhfRlVOQ1RJT05fUkVTT0xWRVIgICAgICAgICAgICAgICAgICAgICAgICovCi0KLSAgeyBFUl9OVUxMX1hQQVRIX0ZVTkNUSU9OX1JFU09MVkVSLAotICAgICAgICJWZXJzdWNoLCBOdWxsLVhQYXRoRnVuY3Rpb25SZXNvbHZlciBmZXN0enVsZWdlbjp7MH0jc2V0WFBhdGhGdW5jdGlvblJlc29sdmVyKG51bGwpIn0sCi0KLSAgLyoqIEZpZWxkIEVSX05VTExfWFBBVEhfVkFSSUFCTEVfUkVTT0xWRVIgICAgICAgICAgICAgICAgICAgICAgICovCi0KLSAgeyBFUl9OVUxMX1hQQVRIX1ZBUklBQkxFX1JFU09MVkVSLAotICAgICAgICJWZXJzdWNoLCBOdWxsLVhQYXRoVmFyaWFibGVSZXNvbHZlciBmZXN0enVsZWdlbjp7MH0jc2V0WFBhdGhWYXJpYWJsZVJlc29sdmVyKG51bGwpIn0sCi0KLSAgLy9FTkQ6ICBEZWZpbml0aW9ucyBvZiBlcnJvciBrZXlzIHVzZWQgIGluIGV4Y2VwdGlvbiBtZXNzYWdlcyBvZiAgSkFYUCAxLjMgWFBhdGggQVBJIGltcGxlbWVudGF0aW9uCi0KLSAgLy8gV2FybmluZ3MuLi4KLQotICB7IFdHX0xPQ0FMRV9OQU1FX05PVF9IQU5ETEVELAotICAgICAgIkdlYmlldHNzY2hlbWFuYW1lIGluIGRlciBmb3JtYXQtbnVtYmVyLUZ1bmt0aW9uIHdpcmQgbm9jaCBuaWNodCB2ZXJhcmJlaXRldC4ifSwKLQotICB7IFdHX1BST1BFUlRZX05PVF9TVVBQT1JURUQsCi0gICAgICAiWFNMLUVpZ2Vuc2NoYWZ0IG5pY2h0IHVudGVyc3RcdTAwRkN0enQ6IHswfSJ9LAotCi0gIHsgV0dfRE9OVF9ET19BTllUSElOR19XSVRIX05TLAotICAgICAgIkRlcnplaXQga2VpbmUgQWt0aW9uIG1pdCBOYW1lc3BhY2UgezB9IGluIEVpZ2Vuc2NoYWZ0IHsxfSBhdXNmXHUwMEZDaHJlbiJ9LAotCi0gIHsgV0dfU0VDVVJJVFlfRVhDRVBUSU9OLAotICAgICAgIlNlY3VyaXR5RXhjZXB0aW9uIGJlaW0gVmVyc3VjaCwgYXVmIFhTTC1TeXN0ZW1laWdlbnNjaGFmdCB7MH0genV6dWdyZWlmZW4ifSwKLQotICB7IFdHX1FVT19OT19MT05HRVJfREVGSU5FRCwKLSAgICAgICJBbHRlIFN5bnRheDogcXVvKC4uLikgbmljaHQgbWVociBkZWZpbmllcnQgaW4gWFBhdGguIn0sCi0KLSAgeyBXR19ORUVEX0RFUklWRURfT0JKRUNUX1RPX0lNUExFTUVOVF9OT0RFVEVTVCwKLSAgICAgICJYUGF0aCBiZW5cdTAwRjZ0aWd0IGVpbiBhYmdlbGVpdGV0ZXMgT2JqZWt0LCB1bSBub2RlVGVzdCB6dSBpbXBsZW1lbnRpZXJlbi4ifSwKLQotICB7IFdHX0ZVTkNUSU9OX1RPS0VOX05PVF9GT1VORCwKLSAgICAgICJGdW5rdGlvbnN0b2tlbiBuaWNodCBnZWZ1bmRlbi4ifSwKLQotICB7IFdHX0NPVUxETk9UX0ZJTkRfRlVOQ1RJT04sCi0gICAgICAiRnVua3Rpb24ga29ubnRlIG5pY2h0IGdlZnVuZGVuIHdlcmRlbjogezB9In0sCi0KLSAgeyBXR19DQU5OT1RfTUFLRV9VUkxfRlJPTSwKLSAgICAgICJVUkwga2FubiBuaWNodCBlcnN0ZWxsdCB3ZXJkZW4gYXVzOiB7MH0ifSwKLQotICB7IFdHX0VYUEFORF9FTlRJVElFU19OT1RfU1VQUE9SVEVELAotICAgICAgIk9wdGlvbiBcIi1FXCIgbmljaHQgdW50ZXJzdFx1MDBGQ3R6dCBmXHUwMEZDciBEVE0tUGFyc2VyIn0sCi0KLSAgeyBXR19JTExFR0FMX1ZBUklBQkxFX1JFRkVSRU5DRSwKLSAgICAgICJWYXJpYWJsZVJlZmVyZW5jZSBhdVx1MDBERmVyaGFsYiBkZXMgS29udGV4dHMgb2RlciBvaG5lIERlZmluaXRpb24gZlx1MDBGQ3IgVmFyaWFibGUgYW5nZWdlYmVuLiBOYW1lID0gezB9In0sCi0KLSAgeyBXR19VTlNVUFBPUlRFRF9FTkNPRElORywKLSAgICAgIk5pY2h0IHVudGVyc3RcdTAwRkN0enRlIENvZGllcnVuZzogezB9In0sCi0KLQotCi0gIC8vIE90aGVyIG1pc2NlbGxhbmVvdXMgdGV4dCB1c2VkIGluc2lkZSB0aGUgY29kZS4uLgotICB7ICJ1aV9sYW5ndWFnZSIsICJkZSJ9LAotICB7ICJoZWxwX2xhbmd1YWdlIiwgImRlIn0sCi0gIHsgImxhbmd1YWdlIiwgImRlIn0sCi0gIHsgIkJBRF9DT0RFIiwgIlBhcmFtZXRlciBmXHUwMEZDciBjcmVhdGVNZXNzYWdlIHdhciBhdVx1MDBERmVyaGFsYiBkZXMgZ1x1MDBGQ2x0aWdlbiBCZXJlaWNocyJ9LAotICB7ICJGT1JNQVRfRkFJTEVEIiwgIkF1c25haG1lIGJlaSBtZXNzYWdlRm9ybWF0LUF1ZnJ1ZiBhdXNnZWxcdTAwRjZzdCJ9LAotICB7ICJ2ZXJzaW9uIiwgIj4+Pj4+Pj4gWGFsYW4tVmVyc2lvbiAifSwKLSAgeyAidmVyc2lvbjIiLCAiPDw8PDw8PCJ9LAotICB7ICJ5ZXMiLCAiSmEifSwKLSAgeyAibGluZSIsICJaZWlsZW5udW1tZXIifSwKLSAgeyAiY29sdW1uIiwgIlNwYWx0ZW5udW1tZXIifSwKLSAgeyAieHNsZG9uZSIsICJYU0xQcm9jZXNzb3I6IEZlcnRpZyJ9LAotICB7ICJ4cGF0aF9vcHRpb24iLCAieHBhdGgtT3B0aW9uZW46ICJ9LAotICB7ICJvcHRpb25JTiIsICIgICBbLWluIGlucHV0WE1MVVJMXSJ9LAotICB7ICJvcHRpb25TZWxlY3QiLCAiICAgWy1zZWxlY3QgeHBhdGggZXhwcmVzc2lvbl0ifSwKLSAgeyAib3B0aW9uTWF0Y2giLCAiICAgWy1tYXRjaCBtYXRjaCBwYXR0ZXJuIChmXHUwMEZDciBWZXJnbGVpY2hzZGlhZ25vc2UpXSJ9LAotICB7ICJvcHRpb25BbnlFeHByIiwgIk9kZXIgbnVyIGVpbiBYUGF0aC1BdXNkcnVjayBmXHUwMEZDaHJ0IGVpbmVuIERpYWdub3NlZHVtcCBhdXMifSwKLSAgeyAibm9QYXJzZXJtc2cxIiwgIlhTTC1Qcm96ZXNzIHdhciBuaWNodCBlcmZvbGdyZWljaC4ifSwKLSAgeyAibm9QYXJzZXJtc2cyIiwgIioqIFBhcnNlciBrb25udGUgbmljaHQgZ2VmdW5kZW4gd2VyZGVuICoqIn0sCi0gIHsgIm5vUGFyc2VybXNnMyIsICJQclx1MDBGQ2ZlbiBTaWUgZGVuIENsYXNzcGF0aC4ifSwKLSAgeyAibm9QYXJzZXJtc2c0IiwgIldlbm4gU2llIG5pY2h0IFx1MDBGQ2JlciBkZW4gWE1MLVBhcnNlciBmXHUwMEZDciBKYXZhIHZvbiBJQk0gdmVyZlx1MDBGQ2dlbiwga1x1MDBGNm5uZW4gU2llIGlobiBoaWVyIGhlcnVudGVybGFkZW46In0sCi0gIHsgIm5vUGFyc2VybXNnNSIsICJJQk1zIEFscGhhV29ya3M6IGh0dHA6Ly93d3cuYWxwaGF3b3Jrcy5pYm0uY29tL2Zvcm11bGEveG1sIn0sCi0gIHsgImd0b25lIiwgIj4xIiB9LAotICB7ICJ6ZXJvIiwgIjAiIH0sCi0gIHsgIm9uZSIsICIxIiB9LAotICB7ICJ0d28iICwgIjIiIH0sCi0gIHsgInRocmVlIiwgIjMiIH0KLQotICB9OwotCi0gIC8qKgotICAgKiBHZXQgdGhlIGFzc29jaWF0aW9uIGxpc3QuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGFzc29jaWF0aW9uIGxpc3QuCi0gICAqLwotICBwdWJsaWMgT2JqZWN0W11bXSBnZXRDb250ZW50cygpCi0gIHsKLSAgICAgIHJldHVybiBfY29udGVudHM7Ci0gIH0KLQotCi0gIC8vID09PT09PT09PT09PT09PT09IElORlJBU1RSVUNUVVJFID09PT09PT09PT09PT09PT09PT09PT0KLQotICAvKiogRmllbGQgQkFEX0NPREUgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQkFEX0NPREUgPSAiQkFEX0NPREUiOwotCi0gIC8qKiBGaWVsZCBGT1JNQVRfRkFJTEVEICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEZPUk1BVF9GQUlMRUQgPSAiRk9STUFUX0ZBSUxFRCI7Ci0KLSAgLyoqIEZpZWxkIEVSUk9SX1JFU09VUkNFUyAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJPUl9SRVNPVVJDRVMgPQotICAgICJjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucmVzLlhQQVRIRXJyb3JSZXNvdXJjZXMiOwotCi0gIC8qKiBGaWVsZCBFUlJPUl9TVFJJTkcgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJST1JfU1RSSU5HID0gIiNlcnJvciI7Ci0KLSAgLyoqIEZpZWxkIEVSUk9SX0hFQURFUiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJPUl9IRUFERVIgPSAiRXJyb3I6ICI7Ci0KLSAgLyoqIEZpZWxkIFdBUk5JTkdfSEVBREVSICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdBUk5JTkdfSEVBREVSID0gIldhcm5pbmc6ICI7Ci0KLSAgLyoqIEZpZWxkIFhTTF9IRUFERVIgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgWFNMX0hFQURFUiA9ICJYU0wgIjsKLQotICAvKiogRmllbGQgWE1MX0hFQURFUiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxfSEVBREVSID0gIlhNTCAiOwotCi0gIC8qKiBGaWVsZCBRVUVSWV9IRUFERVIgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgUVVFUllfSEVBREVSID0gIlBBVFRFUk4gIjsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9yZXMvWFBBVEhFcnJvclJlc291cmNlc19lbi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9yZXMvWFBBVEhFcnJvclJlc291cmNlc19lbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzM2YyNGJkLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvcmVzL1hQQVRIRXJyb3JSZXNvdXJjZXNfZW4uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDMzICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLS8qCi0gKiAkSWQ6IFhQQVRIRXJyb3JSZXNvdXJjZXNfZW4uamF2YSx2IDEuMS4yLjEgMjAwNS8wOC8wMSAwMToyOTo1MCBqZWZmc3V0dG9yIEV4cCAkCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLnJlczsKLQotCi0vKioKLSAqIERlZmF1bHQgaW1wbGVtZW50YXRpb24gb2YgWFBBVEhFcnJvclJlc291cmNlcy4gIFRoaXMgaXMganVzdAotICogYW4gZW1wdHkgY2xhc3MuCi0gKiBAeHNsLnVzYWdlIGFkdmFuY2VkCi0gKi8KLXB1YmxpYyBjbGFzcyBYUEFUSEVycm9yUmVzb3VyY2VzX2VuIGV4dGVuZHMgWFBBVEhFcnJvclJlc291cmNlcwotewotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9yZXMvWFBBVEhFcnJvclJlc291cmNlc19lcy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9yZXMvWFBBVEhFcnJvclJlc291cmNlc19lcy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDlhMzQ4Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvcmVzL1hQQVRIRXJyb3JSZXNvdXJjZXNfZXMuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDkzNiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5yZXM7Ci0KLWltcG9ydCBqYXZhLnV0aWwuTGlzdFJlc291cmNlQnVuZGxlOwotCi0vKioKLSAqIFNldCB1cCBlcnJvciBtZXNzYWdlcy4KLSAqIFdlIGJ1aWxkIGEgdHdvIGRpbWVuc2lvbmFsIGFycmF5IG9mIG1lc3NhZ2Uga2V5cyBhbmQKLSAqIG1lc3NhZ2Ugc3RyaW5ncy4gSW4gb3JkZXIgdG8gYWRkIGEgbmV3IG1lc3NhZ2UgaGVyZSwKLSAqIHlvdSBuZWVkIHRvIGZpcnN0IGFkZCBhIFN0YXRpYyBzdHJpbmcgY29uc3RhbnQgZm9yIHRoZQotICogS2V5IGFuZCB1cGRhdGUgdGhlIGNvbnRlbnRzIGFycmF5IHdpdGggS2V5LCBWYWx1ZSBwYWlyCi0gICogQWxzbyB5b3UgbmVlZCB0byAgdXBkYXRlIHRoZSBjb3VudCBvZiBtZXNzYWdlcyhNQVhfQ09ERSlvcgotICogdGhlIGNvdW50IG9mIHdhcm5pbmdzKE1BWF9XQVJOSU5HKSBbIEluZm9ybWF0aW9uIHB1cnBvc2Ugb25seV0KLSAqIEB4c2wudXNhZ2UgYWR2YW5jZWQKLSAqLwotcHVibGljIGNsYXNzIFhQQVRIRXJyb3JSZXNvdXJjZXNfZXMgZXh0ZW5kcyBMaXN0UmVzb3VyY2VCdW5kbGUKLXsKLQotLyoKLSAqIEdlbmVyYWwgbm90ZXMgdG8gdHJhbnNsYXRvcnM6Ci0gKgotICogVGhpcyBmaWxlIGNvbnRhaW5zIGVycm9yIGFuZCB3YXJuaW5nIG1lc3NhZ2VzIHJlbGF0ZWQgdG8gWFBhdGggRXJyb3IKLSAqIEhhbmRsaW5nLgotICoKLSAqICAxKSBYYWxhbiAob3IgbW9yZSBwcm9wZXJseSwgWGFsYW4taW50ZXJwcmV0aXZlKSBhbmQgWFNMVEMgYXJlIG5hbWVzIG9mCi0gKiAgICAgY29tcG9uZW50cy4KLSAqICAgICBYU0xUIGlzIGFuIGFjcm9ueW0gZm9yICJYTUwgU3R5bGVzaGVldCBMYW5ndWFnZTogVHJhbnNmb3JtYXRpb25zIi4KLSAqICAgICBYU0xUQyBpcyBhbiBhY3JvbnltIGZvciBYU0xUIENvbXBpbGVyLgotICoKLSAqICAyKSBBIHN0eWxlc2hlZXQgaXMgYSBkZXNjcmlwdGlvbiBvZiBob3cgdG8gdHJhbnNmb3JtIGFuIGlucHV0IFhNTCBkb2N1bWVudAotICogICAgIGludG8gYSByZXN1bHRhbnQgWE1MIGRvY3VtZW50IChvciBIVE1MIGRvY3VtZW50IG9yIHRleHQpLiAgVGhlCi0gKiAgICAgc3R5bGVzaGVldCBpdHNlbGYgaXMgZGVzY3JpYmVkIGluIHRoZSBmb3JtIG9mIGFuIFhNTCBkb2N1bWVudC4KLSAqCi0gKiAgMykgQSB0ZW1wbGF0ZSBpcyBhIGNvbXBvbmVudCBvZiBhIHN0eWxlc2hlZXQgdGhhdCBpcyB1c2VkIHRvIG1hdGNoIGEKLSAqICAgICBwYXJ0aWN1bGFyIHBvcnRpb24gb2YgYW4gaW5wdXQgZG9jdW1lbnQgYW5kIHNwZWNpZmllcyB0aGUgZm9ybSBvZiB0aGUKLSAqICAgICBjb3JyZXNwb25kaW5nIHBvcnRpb24gb2YgdGhlIG91dHB1dCBkb2N1bWVudC4KLSAqCi0gKiAgNCkgQW4gZWxlbWVudCBpcyBhIG1hcmstdXAgdGFnIGluIGFuIFhNTCBkb2N1bWVudDsgYW4gYXR0cmlidXRlIGlzIGEKLSAqICAgICBtb2RpZmllciBvbiB0aGUgdGFnLiAgRm9yIGV4YW1wbGUsIGluIDxlbGVtIGF0dHI9J3ZhbCcgYXR0cjI9J3ZhbDInPgotICogICAgICJlbGVtIiBpcyBhbiBlbGVtZW50IG5hbWUsICJhdHRyIiBhbmQgImF0dHIyIiBhcmUgYXR0cmlidXRlIG5hbWVzIHdpdGgKLSAqICAgICB0aGUgdmFsdWVzICJ2YWwiIGFuZCAidmFsMiIsIHJlc3BlY3RpdmVseS4KLSAqCi0gKiAgNSkgQSBuYW1lc3BhY2UgZGVjbGFyYXRpb24gaXMgYSBzcGVjaWFsIGF0dHJpYnV0ZSB0aGF0IGlzIHVzZWQgdG8gYXNzb2NpYXRlCi0gKiAgICAgYSBwcmVmaXggd2l0aCBhIFVSSSAodGhlIG5hbWVzcGFjZSkuICBUaGUgbWVhbmluZ3Mgb2YgZWxlbWVudCBuYW1lcyBhbmQKLSAqICAgICBhdHRyaWJ1dGUgbmFtZXMgdGhhdCB1c2UgdGhhdCBwcmVmaXggYXJlIGRlZmluZWQgd2l0aCByZXNwZWN0IHRvIHRoYXQKLSAqICAgICBuYW1lc3BhY2UuCi0gKgotICogIDYpICJUcmFuc2xldCIgaXMgYW4gaW52ZW50ZWQgdGVybSB0aGF0IGRlc2NyaWJlcyB0aGUgY2xhc3MgZmlsZSB0aGF0Ci0gKiAgICAgcmVzdWx0cyBmcm9tIGNvbXBpbGluZyBhbiBYTUwgc3R5bGVzaGVldCBpbnRvIGEgSmF2YSBjbGFzcy4KLSAqCi0gKiAgNykgWFBhdGggaXMgYSBzcGVjaWZpY2F0aW9uIHRoYXQgZGVzY3JpYmVzIGEgbm90YXRpb24gZm9yIGlkZW50aWZ5aW5nCi0gKiAgICAgbm9kZXMgaW4gYSB0cmVlLXN0cnVjdHVyZWQgcmVwcmVzZW50YXRpb24gb2YgYW4gWE1MIGRvY3VtZW50LiAgQW4KLSAqICAgICBpbnN0YW5jZSBvZiB0aGF0IG5vdGF0aW9uIGlzIHJlZmVycmVkIHRvIGFzIGFuIFhQYXRoIGV4cHJlc3Npb24uCi0gKgotICogIDgpIFRoZSBjb250ZXh0IG5vZGUgaXMgdGhlIG5vZGUgaW4gdGhlIGRvY3VtZW50IHdpdGggcmVzcGVjdCB0byB3aGljaCBhbgotICogICAgIFhQYXRoIGV4cHJlc3Npb24gaXMgYmVpbmcgZXZhbHVhdGVkLgotICoKLSAqICA5KSBBbiBpdGVyYXRvciBpcyBhbiBvYmplY3QgdGhhdCB0cmF2ZXJzZXMgbm9kZXMgaW4gdGhlIHRyZWUsIG9uZSBhdCBhIHRpbWUuCi0gKgotICogIDEwKSBOQ05hbWUgaXMgYW4gWE1MIHRlcm0gdXNlZCB0byBkZXNjcmliZSBhIG5hbWUgdGhhdCBkb2VzIG5vdCBjb250YWluIGEKLSAqICAgICBjb2xvbiAoYSAibm8tY29sb24gbmFtZSIpLgotICoKLSAqICAxMSkgUU5hbWUgaXMgYW4gWE1MIHRlcm0gbWVhbmluZyAicXVhbGlmaWVkIG5hbWUiLgotICovCi0KLSAgLyoKLSAgICogc3RhdGljIHZhcmlhYmxlcwotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJST1IwMDAwID0gIkVSUk9SMDAwMCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NVUlJFTlRfTk9UX0FMTE9XRURfSU5fTUFUQ0ggPQotICAgICAgICAgIkVSX0NVUlJFTlRfTk9UX0FMTE9XRURfSU5fTUFUQ0giOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DVVJSRU5UX1RBS0VTX05PX0FSR1MgPQotICAgICAgICAgIkVSX0NVUlJFTlRfVEFLRVNfTk9fQVJHUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0RPQ1VNRU5UX1JFUExBQ0VEID0gIkVSX0RPQ1VNRU5UX1JFUExBQ0VEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09OVEVYVF9IQVNfTk9fT1dORVJET0MgPQotICAgICAgICAgIkVSX0NPTlRFWFRfSEFTX05PX09XTkVSRE9DIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTE9DQUxOQU1FX0hBU19UT09fTUFOWV9BUkdTID0KLSAgICAgICAgICJFUl9MT0NBTE5BTUVfSEFTX1RPT19NQU5ZX0FSR1MiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OQU1FU1BBQ0VVUklfSEFTX1RPT19NQU5ZX0FSR1MgPQotICAgICAgICAgIkVSX05BTUVTUEFDRVVSSV9IQVNfVE9PX01BTllfQVJHUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PUk1BTElaRVNQQUNFX0hBU19UT09fTUFOWV9BUkdTID0KLSAgICAgICAgICJFUl9OT1JNQUxJWkVTUEFDRV9IQVNfVE9PX01BTllfQVJHUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05VTUJFUl9IQVNfVE9PX01BTllfQVJHUyA9Ci0gICAgICAgICAiRVJfTlVNQkVSX0hBU19UT09fTUFOWV9BUkdTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTkFNRV9IQVNfVE9PX01BTllfQVJHUyA9Ci0gICAgICAgICAiRVJfTkFNRV9IQVNfVE9PX01BTllfQVJHUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NUUklOR19IQVNfVE9PX01BTllfQVJHUyA9Ci0gICAgICAgICAiRVJfU1RSSU5HX0hBU19UT09fTUFOWV9BUkdTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU1RSSU5HTEVOR1RIX0hBU19UT09fTUFOWV9BUkdTID0KLSAgICAgICAgICJFUl9TVFJJTkdMRU5HVEhfSEFTX1RPT19NQU5ZX0FSR1MiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9UUkFOU0xBVEVfVEFLRVNfM19BUkdTID0KLSAgICAgICAgICJFUl9UUkFOU0xBVEVfVEFLRVNfM19BUkdTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5QQVJTRURFTlRJVFlVUklfVEFLRVNfMV9BUkcgPQotICAgICAgICAgIkVSX1VOUEFSU0VERU5USVRZVVJJX1RBS0VTXzFfQVJHIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTkFNRVNQQUNFQVhJU19OT1RfSU1QTEVNRU5URUQgPQotICAgICAgICAgIkVSX05BTUVTUEFDRUFYSVNfTk9UX0lNUExFTUVOVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5LTk9XTl9BWElTID0gIkVSX1VOS05PV05fQVhJUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1VOS05PV05fTUFUQ0hfT1BFUkFUSU9OID0KLSAgICAgICAgICJFUl9VTktOT1dOX01BVENIX09QRVJBVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOQ09SUkVDVF9BUkdfTEVOR1RIID0iRVJfSU5DT1JSRUNUX0FSR19MRU5HVEgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX0NPTlZFUlRfVE9fTlVNQkVSID0KLSAgICAgICAgICJFUl9DQU5UX0NPTlZFUlRfVE9fTlVNQkVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9DT05WRVJUX1hQQVRIUkVTVUxUVFlQRV9UT19OVU1CRVIgPQotICAgICAgICAgICAiRVJfQ0FOVF9DT05WRVJUX1hQQVRIUkVTVUxUVFlQRV9UT19OVU1CRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX0NPTlZFUlRfVE9fTk9ERUxJU1QgPQotICAgICAgICAgIkVSX0NBTlRfQ09OVkVSVF9UT19OT0RFTElTVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfQ09OVkVSVF9UT19NVVRBQkxFTk9ERUxJU1QgPQotICAgICAgICAgIkVSX0NBTlRfQ09OVkVSVF9UT19NVVRBQkxFTk9ERUxJU1QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX0NPTlZFUlRfVE9fVFlQRSA9IkVSX0NBTlRfQ09OVkVSVF9UT19UWVBFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhQRUNURURfTUFUQ0hfUEFUVEVSTiA9Ci0gICAgICAgICAiRVJfRVhQRUNURURfTUFUQ0hfUEFUVEVSTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxETk9UX0dFVF9WQVJfTkFNRUQgPQotICAgICAgICAgIkVSX0NPVUxETk9UX0dFVF9WQVJfTkFNRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTktOT1dOX09QQ09ERSA9ICJFUl9VTktOT1dOX09QQ09ERSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYVFJBX0lMTEVHQUxfVE9LRU5TID0iRVJfRVhUUkFfSUxMRUdBTF9UT0tFTlMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FWFBFQ1RFRF9ET1VCTEVfUVVPVEUgPQotICAgICAgICAgIkVSX0VYUEVDVEVEX0RPVUJMRV9RVU9URSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYUEVDVEVEX1NJTkdMRV9RVU9URSA9Ci0gICAgICAgICAiRVJfRVhQRUNURURfU0lOR0xFX1FVT1RFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRU1QVFlfRVhQUkVTU0lPTiA9ICJFUl9FTVBUWV9FWFBSRVNTSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhQRUNURURfQlVUX0ZPVU5EID0gIkVSX0VYUEVDVEVEX0JVVF9GT1VORCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOQ09SUkVDVF9QUk9HUkFNTUVSX0FTU0VSVElPTiA9Ci0gICAgICAgICAiRVJfSU5DT1JSRUNUX1BST0dSQU1NRVJfQVNTRVJUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQk9PTEVBTl9BUkdfTk9fTE9OR0VSX09QVElPTkFMID0KLSAgICAgICAgICJFUl9CT09MRUFOX0FSR19OT19MT05HRVJfT1BUSU9OQUwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GT1VORF9DT01NQV9CVVRfTk9fUFJFQ0VESU5HX0FSRyA9Ci0gICAgICAgICAiRVJfRk9VTkRfQ09NTUFfQlVUX05PX1BSRUNFRElOR19BUkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GT1VORF9DT01NQV9CVVRfTk9fRk9MTE9XSU5HX0FSRyA9Ci0gICAgICAgICAiRVJfRk9VTkRfQ09NTUFfQlVUX05PX0ZPTExPV0lOR19BUkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUkVESUNBVEVfSUxMRUdBTF9TWU5UQVggPQotICAgICAgICAgIkVSX1BSRURJQ0FURV9JTExFR0FMX1NZTlRBWCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lMTEVHQUxfQVhJU19OQU1FID0gIkVSX0lMTEVHQUxfQVhJU19OQU1FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5LTk9XTl9OT0RFVFlQRSA9ICJFUl9VTktOT1dOX05PREVUWVBFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUEFUVEVSTl9MSVRFUkFMX05FRURTX0JFX1FVT1RFRCA9Ci0gICAgICAgICAiRVJfUEFUVEVSTl9MSVRFUkFMX05FRURTX0JFX1FVT1RFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxETk9UX0JFX0ZPUk1BVFRFRF9UT19OVU1CRVIgPQotICAgICAgICAgIkVSX0NPVUxETk9UX0JFX0ZPUk1BVFRFRF9UT19OVU1CRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRE5PVF9DUkVBVEVfWE1MUFJPQ0VTU09STElBSVNPTiA9Ci0gICAgICAgICAiRVJfQ09VTEROT1RfQ1JFQVRFX1hNTFBST0NFU1NPUkxJQUlTT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9ESUROT1RfRklORF9YUEFUSF9TRUxFQ1RfRVhQID0KLSAgICAgICAgICJFUl9ESUROT1RfRklORF9YUEFUSF9TRUxFQ1RfRVhQIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTEROT1RfRklORF9FTkRPUF9BRlRFUl9PUExPQ0FUSU9OUEFUSCA9Ci0gICAgICAgICAiRVJfQ09VTEROT1RfRklORF9FTkRPUF9BRlRFUl9PUExPQ0FUSU9OUEFUSCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VSUk9SX09DQ1VSRUQgPSAiRVJfRVJST1JfT0NDVVJFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lMTEVHQUxfVkFSSUFCTEVfUkVGRVJFTkNFID0KLSAgICAgICAgICJFUl9JTExFR0FMX1ZBUklBQkxFX1JFRkVSRU5DRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FYRVNfTk9UX0FMTE9XRUQgPSAiRVJfQVhFU19OT1RfQUxMT1dFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0tFWV9IQVNfVE9PX01BTllfQVJHUyA9Ci0gICAgICAgICAiRVJfS0VZX0hBU19UT09fTUFOWV9BUkdTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTlRfVEFLRVNfMV9BUkcgPSAiRVJfQ09VTlRfVEFLRVNfMV9BUkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRE5PVF9GSU5EX0ZVTkNUSU9OID0KLSAgICAgICAgICJFUl9DT1VMRE5PVF9GSU5EX0ZVTkNUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5TVVBQT1JURURfRU5DT0RJTkcgPSJFUl9VTlNVUFBPUlRFRF9FTkNPRElORyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BST0JMRU1fSU5fRFRNX05FWFRTSUJMSU5HID0KLSAgICAgICAgICJFUl9QUk9CTEVNX0lOX0RUTV9ORVhUU0lCTElORyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9XUklURV9UT19FTVBUWU5PREVMSVNUSU1QTCA9Ci0gICAgICAgICAiRVJfQ0FOTk9UX1dSSVRFX1RPX0VNUFRZTk9ERUxJU1RJTVBMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU0VURE9NRkFDVE9SWV9OT1RfU1VQUE9SVEVEID0KLSAgICAgICAgICJFUl9TRVRET01GQUNUT1JZX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUkVGSVhfTVVTVF9SRVNPTFZFID0gIkVSX1BSRUZJWF9NVVNUX1JFU09MVkUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QQVJTRV9OT1RfU1VQUE9SVEVEID0gIkVSX1BBUlNFX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TQVhfQVBJX05PVF9IQU5ETEVEID0gIkVSX1NBWF9BUElfTk9UX0hBTkRMRUQiOwotcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSUdOT1JBQkxFX1dISVRFU1BBQ0VfTk9UX0hBTkRMRUQgPQotICAgICAgICAgIkVSX0lHTk9SQUJMRV9XSElURVNQQUNFX05PVF9IQU5ETEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRFRNX0NBTk5PVF9IQU5ETEVfTk9ERVMgPQotICAgICAgICAgIkVSX0RUTV9DQU5OT1RfSEFORExFX05PREVTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWEVSQ0VTX0NBTk5PVF9IQU5ETEVfTk9ERVMgPQotICAgICAgICAgIkVSX1hFUkNFU19DQU5OT1RfSEFORExFX05PREVTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWEVSQ0VTX1BBUlNFX0VSUk9SX0RFVEFJTFMgPQotICAgICAgICAgIkVSX1hFUkNFU19QQVJTRV9FUlJPUl9ERVRBSUxTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWEVSQ0VTX1BBUlNFX0VSUk9SID0gIkVSX1hFUkNFU19QQVJTRV9FUlJPUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfVVRGMTZfU1VSUk9HQVRFID0KLSAgICAgICAgICJFUl9JTlZBTElEX1VURjE2X1NVUlJPR0FURSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX09JRVJST1IgPSAiRVJfT0lFUlJPUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9DUkVBVEVfVVJMID0gIkVSX0NBTk5PVF9DUkVBVEVfVVJMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWFBBVEhfUkVBRE9CSkVDVCA9ICJFUl9YUEFUSF9SRUFET0JKRUNUIjsKLSBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GVU5DVElPTl9UT0tFTl9OT1RfRk9VTkQgPQotICAgICAgICAgIkVSX0ZVTkNUSU9OX1RPS0VOX05PVF9GT1VORCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9ERUFMX1hQQVRIX1RZUEUgPQotICAgICAgICAgIkVSX0NBTk5PVF9ERUFMX1hQQVRIX1RZUEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT0RFU0VUX05PVF9NVVRBQkxFID0gIkVSX05PREVTRVRfTk9UX01VVEFCTEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT0RFU0VURFRNX05PVF9NVVRBQkxFID0KLSAgICAgICAgICJFUl9OT0RFU0VURFRNX05PVF9NVVRBQkxFIjsKLSAgIC8qKiAgVmFyaWFibGUgbm90IHJlc29sdmFibGU6ICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVkFSX05PVF9SRVNPTFZBQkxFID0gIkVSX1ZBUl9OT1RfUkVTT0xWQUJMRSI7Ci0gICAvKiogTnVsbCBlcnJvciBoYW5kbGVyICAqLwotIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05VTExfRVJST1JfSEFORExFUiA9ICJFUl9OVUxMX0VSUk9SX0hBTkRMRVIiOwotICAgLyoqICBQcm9ncmFtbWVyJ3MgYXNzZXJ0aW9uOiB1bmtub3duIG9wY29kZSAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJPR19BU1NFUlRfVU5LTk9XTl9PUENPREUgPQotICAgICAgICAgIkVSX1BST0dfQVNTRVJUX1VOS05PV05fT1BDT0RFIjsKLSAgIC8qKiAgMCBvciAxICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWkVST19PUl9PTkUgPSAiRVJfWkVST19PUl9PTkUiOwotICAgLyoqICBydGYoKSBub3Qgc3VwcG9ydGVkIGJ5IFhSVHJlZUZyYWdTZWxlY3RXcmFwcGVyICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUlRGX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIgPQotICAgICAgICAgIkVSX1JURl9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSIjsKLSAgIC8qKiAgYXNOb2RlSXRlcmF0b3IoKSBub3Qgc3VwcG9ydGVkIGJ5IFhSVHJlZUZyYWdTZWxlY3RXcmFwcGVyICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQVNOT0RFSVRFUkFUT1JfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiA9ICJFUl9BU05PREVJVEVSQVRPUl9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSIjsKLSAgIC8qKiAgZnNiKCkgbm90IHN1cHBvcnRlZCBmb3IgWFN0cmluZ0ZvckNoYXJzICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRlNCX05PVF9TVVBQT1JURURfWFNUUklOR0ZPUkNIQVJTID0KLSAgICAgICAgICJFUl9GU0JfTk9UX1NVUFBPUlRFRF9YU1RSSU5HRk9SQ0hBUlMiOwotICAgLyoqICBDb3VsZCBub3QgZmluZCB2YXJpYWJsZSB3aXRoIHRoZSBuYW1lIG9mICAgKi8KLSBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRF9OT1RfRklORF9WQVIgPSAiRVJfQ09VTERfTk9UX0ZJTkRfVkFSIjsKLSAgIC8qKiAgWFN0cmluZ0ZvckNoYXJzIGNhbiBub3QgdGFrZSBhIHN0cmluZyBmb3IgYW4gYXJndW1lbnQgICAqLwotIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hTVFJJTkdGT1JDSEFSU19DQU5OT1RfVEFLRV9TVFJJTkcgPQotICAgICAgICAgIkVSX1hTVFJJTkdGT1JDSEFSU19DQU5OT1RfVEFLRV9TVFJJTkciOwotICAgLyoqICBUaGUgRmFzdFN0cmluZ0J1ZmZlciBhcmd1bWVudCBjYW4gbm90IGJlIG51bGwgICAqLwotIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZBU1RTVFJJTkdCVUZGRVJfQ0FOTk9UX0JFX05VTEwgPQotICAgICAgICAgIkVSX0ZBU1RTVFJJTkdCVUZGRVJfQ0FOTk9UX0JFX05VTEwiOwotICAgLyoqICAyIG9yIDMgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9UV09fT1JfVEhSRUUgPSAiRVJfVFdPX09SX1RIUkVFIjsKLSAgIC8qKiBWYXJpYWJsZSBhY2Nlc3NlZCBiZWZvcmUgaXQgaXMgYm91bmQhICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1ZBUklBQkxFX0FDQ0VTU0VEX0JFRk9SRV9CSU5EID0KLSAgICAgICAgICJFUl9WQVJJQUJMRV9BQ0NFU1NFRF9CRUZPUkVfQklORCI7Ci0gICAvKiogWFN0cmluZ0ZvckZTQiBjYW4gbm90IHRha2UgYSBzdHJpbmcgZm9yIGFuIGFyZ3VtZW50ISAqLwotIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZTQl9DQU5OT1RfVEFLRV9TVFJJTkcgPQotICAgICAgICAgIkVSX0ZTQl9DQU5OT1RfVEFLRV9TVFJJTkciOwotICAgLyoqIEVycm9yISBTZXR0aW5nIHRoZSByb290IG9mIGEgd2Fsa2VyIHRvIG51bGwhICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NFVFRJTkdfV0FMS0VSX1JPT1RfVE9fTlVMTCA9Ci0gICAgICAgICAiRVJfU0VUVElOR19XQUxLRVJfUk9PVF9UT19OVUxMIjsKLSAgIC8qKiBUaGlzIE5vZGVTZXREVE0gY2FuIG5vdCBpdGVyYXRlIHRvIGEgcHJldmlvdXMgbm9kZSEgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9ERVNFVERUTV9DQU5OT1RfSVRFUkFURSA9Ci0gICAgICAgICAiRVJfTk9ERVNFVERUTV9DQU5OT1RfSVRFUkFURSI7Ci0gIC8qKiBUaGlzIE5vZGVTZXQgY2FuIG5vdCBpdGVyYXRlIHRvIGEgcHJldmlvdXMgbm9kZSEgKi8KLSBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT0RFU0VUX0NBTk5PVF9JVEVSQVRFID0KLSAgICAgICAgICJFUl9OT0RFU0VUX0NBTk5PVF9JVEVSQVRFIjsKLSAgLyoqIFRoaXMgTm9kZVNldERUTSBjYW4gbm90IGRvIGluZGV4aW5nIG9yIGNvdW50aW5nIGZ1bmN0aW9ucyEgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9ERVNFVERUTV9DQU5OT1RfSU5ERVggPQotICAgICAgICAgIkVSX05PREVTRVREVE1fQ0FOTk9UX0lOREVYIjsKLSAgLyoqIFRoaXMgTm9kZVNldCBjYW4gbm90IGRvIGluZGV4aW5nIG9yIGNvdW50aW5nIGZ1bmN0aW9ucyEgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9ERVNFVF9DQU5OT1RfSU5ERVggPQotICAgICAgICAgIkVSX05PREVTRVRfQ0FOTk9UX0lOREVYIjsKLSAgLyoqIENhbiBub3QgY2FsbCBzZXRTaG91bGRDYWNoZU5vZGVzIGFmdGVyIG5leHROb2RlIGhhcyBiZWVuIGNhbGxlZCEgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX0NBTExfU0VUU0hPVUxEQ0FDSEVOT0RFID0KLSAgICAgICAgICJFUl9DQU5OT1RfQ0FMTF9TRVRTSE9VTERDQUNIRU5PREUiOwotICAvKiogezB9IG9ubHkgYWxsb3dzIHsxfSBhcmd1bWVudHMgKi8KLSBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9PTkxZX0FMTE9XUyA9ICJFUl9PTkxZX0FMTE9XUyI7Ci0gIC8qKiBQcm9ncmFtbWVyJ3MgYXNzZXJ0aW9uIGluIGdldE5leHRTdGVwUG9zOiB1bmtub3duIHN0ZXBUeXBlOiB7MH0gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5LTk9XTl9TVEVQID0gIkVSX1VOS05PV05fU1RFUCI7Ci0gIC8qKiBQcm9ibGVtIHdpdGggUmVsYXRpdmVMb2NhdGlvblBhdGggKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhQRUNURURfUkVMX0xPQ19QQVRIID0KLSAgICAgICAgICJFUl9FWFBFQ1RFRF9SRUxfTE9DX1BBVEgiOwotICAvKiogUHJvYmxlbSB3aXRoIExvY2F0aW9uUGF0aCAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FWFBFQ1RFRF9MT0NfUEFUSCA9ICJFUl9FWFBFQ1RFRF9MT0NfUEFUSCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYUEVDVEVEX0xPQ19QQVRIX0FUX0VORF9FWFBSID0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRVJfRVhQRUNURURfTE9DX1BBVEhfQVRfRU5EX0VYUFIiOwotICAvKiogUHJvYmxlbSB3aXRoIFN0ZXAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhQRUNURURfTE9DX1NURVAgPSAiRVJfRVhQRUNURURfTE9DX1NURVAiOwotICAvKiogUHJvYmxlbSB3aXRoIE5vZGVUZXN0ICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYUEVDVEVEX05PREVfVEVTVCA9ICJFUl9FWFBFQ1RFRF9OT0RFX1RFU1QiOwotICAvKiogRXhwZWN0ZWQgc3RlcCBwYXR0ZXJuICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYUEVDVEVEX1NURVBfUEFUVEVSTiA9Ci0gICAgICAgICJFUl9FWFBFQ1RFRF9TVEVQX1BBVFRFUk4iOwotICAvKiogRXhwZWN0ZWQgcmVsYXRpdmUgcGF0aCBwYXR0ZXJuICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYUEVDVEVEX1JFTF9QQVRIX1BBVFRFUk4gPQotICAgICAgICAgIkVSX0VYUEVDVEVEX1JFTF9QQVRIX1BBVFRFUk4iOwotICAvKiogRVJfQ0FOVF9DT05WRVJUX1hQQVRIUkVTVUxUVFlQRV9UT19CT09MRUFOICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfQ09OVkVSVF9UT19CT09MRUFOID0KLSAgICAgICAgICJFUl9DQU5UX0NPTlZFUlRfVE9fQk9PTEVBTiI7Ci0gIC8qKiBGaWVsZCBFUl9DQU5UX0NPTlZFUlRfVE9fU0lOR0xFTk9ERSAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX0NPTlZFUlRfVE9fU0lOR0xFTk9ERSA9Ci0gICAgICAgICAiRVJfQ0FOVF9DT05WRVJUX1RPX1NJTkdMRU5PREUiOwotICAvKiogRmllbGQgRVJfQ0FOVF9HRVRfU05BUFNIT1RfTEVOR1RIICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9HRVRfU05BUFNIT1RfTEVOR1RIID0KLSAgICAgICAgICJFUl9DQU5UX0dFVF9TTkFQU0hPVF9MRU5HVEgiOwotICAvKiogRmllbGQgRVJfTk9OX0lURVJBVE9SX1RZUEUgICAgICAgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9OX0lURVJBVE9SX1RZUEUgPSAiRVJfTk9OX0lURVJBVE9SX1RZUEUiOwotICAvKiogRmllbGQgRVJfRE9DX01VVEFURUQgICAgICAgICAgICAgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRE9DX01VVEFURUQgPSAiRVJfRE9DX01VVEFURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX1hQQVRIX1RZUEUgPSAiRVJfSU5WQUxJRF9YUEFUSF9UWVBFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRU1QVFlfWFBBVEhfUkVTVUxUID0gIkVSX0VNUFRZX1hQQVRIX1JFU1VMVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOQ09NUEFUSUJMRV9UWVBFUyA9ICJFUl9JTkNPTVBBVElCTEVfVFlQRVMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OVUxMX1JFU09MVkVSID0gIkVSX05VTExfUkVTT0xWRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX0NPTlZFUlRfVE9fU1RSSU5HID0KLSAgICAgICAgICJFUl9DQU5UX0NPTlZFUlRfVE9fU1RSSU5HIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9OX1NOQVBTSE9UX1RZUEUgPSAiRVJfTk9OX1NOQVBTSE9UX1RZUEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9XUk9OR19ET0NVTUVOVCA9ICJFUl9XUk9OR19ET0NVTUVOVCI7Ci0gIC8qIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgWFBhdGggZXhwcmVzc2lvbiBjYW5ub3QgYmUgZXZhbHVhdGVkIHdpdGggcmVzcGVjdAotICAgKiB0byB0aGlzIHR5cGUgb2Ygbm9kZS4KLSAgICovCi0gIC8qKiBGaWVsZCBFUl9XUk9OR19OT0RFVFlQRSAgICAgICAgICAgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfV1JPTkdfTk9ERVRZUEUgPSAiRVJfV1JPTkdfTk9ERVRZUEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YUEFUSF9FUlJPUiA9ICJFUl9YUEFUSF9FUlJPUiI7Ci0KLSAgLy9CRUdJTjogS2V5cyBuZWVkZWQgZm9yIGV4Y2VwdGlvbiBtZXNzYWdlcyBvZiAgSkFYUCAxLjMgWFBhdGggQVBJIGltcGxlbWVudGF0aW9uCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYVEVOU0lPTl9GVU5DVElPTl9DQU5OT1RfQkVfSU5WT0tFRCA9ICJFUl9FWFRFTlNJT05fRlVOQ1RJT05fQ0FOTk9UX0JFX0lOVk9LRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SRVNPTFZFX1ZBUklBQkxFX1JFVFVSTlNfTlVMTCA9ICJFUl9SRVNPTFZFX1ZBUklBQkxFX1JFVFVSTlNfTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1VOU1VQUE9SVEVEX1JFVFVSTl9UWVBFID0gIkVSX1VOU1VQUE9SVEVEX1JFVFVSTl9UWVBFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU09VUkNFX1JFVFVSTl9UWVBFX0NBTk5PVF9CRV9OVUxMID0gIkVSX1NPVVJDRV9SRVRVUk5fVFlQRV9DQU5OT1RfQkVfTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FSR19DQU5OT1RfQkVfTlVMTCA9ICJFUl9BUkdfQ0FOTk9UX0JFX05VTEwiOwotCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX09CSkVDVF9NT0RFTF9OVUxMID0gIkVSX09CSkVDVF9NT0RFTF9OVUxMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfT0JKRUNUX01PREVMX0VNUFRZID0gIkVSX09CSkVDVF9NT0RFTF9FTVBUWSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZFQVRVUkVfTkFNRV9OVUxMID0gIkVSX0ZFQVRVUkVfTkFNRV9OVUxMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRkVBVFVSRV9VTktOT1dOID0gIkVSX0ZFQVRVUkVfVU5LTk9XTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0dFVFRJTkdfTlVMTF9GRUFUVVJFID0gIkVSX0dFVFRJTkdfTlVMTF9GRUFUVVJFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfR0VUVElOR19VTktOT1dOX0ZFQVRVUkUgPSAiRVJfR0VUVElOR19VTktOT1dOX0ZFQVRVUkUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TRUNVUkVQUk9DRVNTSU5HX0ZFQVRVUkUgPSAiRVJfU0VDVVJFUFJPQ0VTU0lOR19GRUFUVVJFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTlVMTF9YUEFUSF9GVU5DVElPTl9SRVNPTFZFUiA9ICJFUl9OVUxMX1hQQVRIX0ZVTkNUSU9OX1JFU09MVkVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTlVMTF9YUEFUSF9WQVJJQUJMRV9SRVNPTFZFUiA9ICJFUl9OVUxMX1hQQVRIX1ZBUklBQkxFX1JFU09MVkVSIjsKLSAgLy9FTkQ6IEtleXMgbmVlZGVkIGZvciBleGNlcHRpb24gbWVzc2FnZXMgb2YgIEpBWFAgMS4zIFhQYXRoIEFQSSBpbXBsZW1lbnRhdGlvbgotCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0xPQ0FMRV9OQU1FX05PVF9IQU5ETEVEID0KLSAgICAgICAgICJXR19MT0NBTEVfTkFNRV9OT1RfSEFORExFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX1BST1BFUlRZX05PVF9TVVBQT1JURUQgPQotICAgICAgICAgIldHX1BST1BFUlRZX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19ET05UX0RPX0FOWVRISU5HX1dJVEhfTlMgPQotICAgICAgICAgIldHX0RPTlRfRE9fQU5ZVEhJTkdfV0lUSF9OUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX1NFQ1VSSVRZX0VYQ0VQVElPTiA9ICJXR19TRUNVUklUWV9FWENFUFRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19RVU9fTk9fTE9OR0VSX0RFRklORUQgPQotICAgICAgICAgIldHX1FVT19OT19MT05HRVJfREVGSU5FRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX05FRURfREVSSVZFRF9PQkpFQ1RfVE9fSU1QTEVNRU5UX05PREVURVNUID0KLSAgICAgICAgICJXR19ORUVEX0RFUklWRURfT0JKRUNUX1RPX0lNUExFTUVOVF9OT0RFVEVTVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0ZVTkNUSU9OX1RPS0VOX05PVF9GT1VORCA9Ci0gICAgICAgICAiV0dfRlVOQ1RJT05fVE9LRU5fTk9UX0ZPVU5EIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfQ09VTEROT1RfRklORF9GVU5DVElPTiA9Ci0gICAgICAgICAiV0dfQ09VTEROT1RfRklORF9GVU5DVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0NBTk5PVF9NQUtFX1VSTF9GUk9NID0iV0dfQ0FOTk9UX01BS0VfVVJMX0ZST00iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19FWFBBTkRfRU5USVRJRVNfTk9UX1NVUFBPUlRFRCA9Ci0gICAgICAgICAiV0dfRVhQQU5EX0VOVElUSUVTX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19JTExFR0FMX1ZBUklBQkxFX1JFRkVSRU5DRSA9Ci0gICAgICAgICAiV0dfSUxMRUdBTF9WQVJJQUJMRV9SRUZFUkVOQ0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19VTlNVUFBPUlRFRF9FTkNPRElORyA9IldHX1VOU1VQUE9SVEVEX0VOQ09ESU5HIjsKLQotICAvKiogIGRldGFjaCgpIG5vdCBzdXBwb3J0ZWQgYnkgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9ERVRBQ0hfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiA9Ci0gICAgICAgICAiRVJfREVUQUNIX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIiOwotICAvKiogIG51bSgpIG5vdCBzdXBwb3J0ZWQgYnkgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OVU1fTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiA9Ci0gICAgICAgICAiRVJfTlVNX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIiOwotICAvKiogIHhzdHIoKSBub3Qgc3VwcG9ydGVkIGJ5IFhSVHJlZUZyYWdTZWxlY3RXcmFwcGVyICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWFNUUl9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSID0KLSAgICAgICAgICJFUl9YU1RSX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIiOwotICAvKiogIHN0cigpIG5vdCBzdXBwb3J0ZWQgYnkgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TVFJfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiA9Ci0gICAgICAgICAiRVJfU1RSX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIiOwotCi0gIC8vIEVycm9yIG1lc3NhZ2VzLi4uCi0KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgT2JqZWN0W11bXSBfY29udGVudHMgPSBuZXcgT2JqZWN0W11bXXsKLQotICB7ICJFUlJPUjAwMDAiICwgInswfSIgfSwKLQotICB7IEVSX0NVUlJFTlRfTk9UX0FMTE9XRURfSU5fTUFUQ0gsICJMYSBmdW5jaVx1MDBGM24gY3VycmVudCgpIG5vIGVzdFx1MDBFMSBwZXJtaXRpZGEgZW4gdW4gcGF0clx1MDBGM24gZGUgY29pbmNpZGVuY2lhLiIgfSwKLQotICB7IEVSX0NVUlJFTlRfVEFLRVNfTk9fQVJHUywgIkxhIGZ1bmNpXHUwMEYzbiBjdXJyZW50KCkgbm8gYWNlcHRhIGFyZ3VtZW50b3MuIiB9LAotCi0gIHsgRVJfRE9DVU1FTlRfUkVQTEFDRUQsCi0gICAgICAiTGEgaW1wbGFudGFjaVx1MDBGM24gZGUgbGEgZnVuY2lcdTAwRjNuIGRvY3VtZW50KCkgc2UgaGEgc3VzdGl0dWlkbyBwb3IgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHQuRnVuY0RvY3VtZW50ISJ9LAotCi0gIHsgRVJfQ09OVEVYVF9IQVNfTk9fT1dORVJET0MsCi0gICAgICAiRWwgY29udGV4dG8gbm8gdGllbmUgdW4gZG9jdW1lbnRvIGRlIHByb3BpZXRhcmlvLiJ9LAotCi0gIHsgRVJfTE9DQUxOQU1FX0hBU19UT09fTUFOWV9BUkdTLAotICAgICAgImxvY2FsLW5hbWUoKSB0aWVuZSBkZW1hc2lhZG9zIGFyZ3VtZW50b3MuIn0sCi0KLSAgeyBFUl9OQU1FU1BBQ0VVUklfSEFTX1RPT19NQU5ZX0FSR1MsCi0gICAgICAibmFtZXNwYWNlLXVyaSgpIHRpZW5lIGRlbWFzaWFkb3MgYXJndW1lbnRvcy4ifSwKLQotICB7IEVSX05PUk1BTElaRVNQQUNFX0hBU19UT09fTUFOWV9BUkdTLAotICAgICAgIm5vcm1hbGl6ZS1zcGFjZSgpIHRpZW5lIGRlbWFzaWFkb3MgYXJndW1lbnRvcy4ifSwKLQotICB7IEVSX05VTUJFUl9IQVNfVE9PX01BTllfQVJHUywKLSAgICAgICJudW1iZXIoKSB0aWVuZSBkZW1hc2lhZG9zIGFyZ3VtZW50b3MuIn0sCi0KLSAgeyBFUl9OQU1FX0hBU19UT09fTUFOWV9BUkdTLAotICAgICAibmFtZSgpIHRpZW5lIGRlbWFzaWFkb3MgYXJndW1lbnRvcy4ifSwKLQotICB7IEVSX1NUUklOR19IQVNfVE9PX01BTllfQVJHUywKLSAgICAgICJzdHJpbmcoKSB0aWVuZSBkZW1hc2lhZG9zIGFyZ3VtZW50b3MuIn0sCi0KLSAgeyBFUl9TVFJJTkdMRU5HVEhfSEFTX1RPT19NQU5ZX0FSR1MsCi0gICAgICAic3RyaW5nLWxlbmd0aCgpIHRpZW5lIGRlbWFzaWFkb3MgYXJndW1lbnRvcy4ifSwKLQotICB7IEVSX1RSQU5TTEFURV9UQUtFU18zX0FSR1MsCi0gICAgICAiTGEgZnVuY2lcdTAwRjNuIHRyYW5zbGF0ZSgpIG5lY2VzaXRhIHRyZXMgYXJndW1lbnRvcy4ifSwKLQotICB7IEVSX1VOUEFSU0VERU5USVRZVVJJX1RBS0VTXzFfQVJHLAotICAgICAgIkxhIGZ1bmNpXHUwMEYzbiB1bnBhcnNlZC1lbnRpdHktdXJpIG5lY2VzaXRhIHVuIGFyZ3VtZW50by4ifSwKLQotICB7IEVSX05BTUVTUEFDRUFYSVNfTk9UX0lNUExFTUVOVEVELAotICAgICAgIkVsIGVqZSBkZSBlc3BhY2lvIGRlIG5vbWJyZXMgbm8gc2UgaGEgaW1wbGFudGFkbyBhXHUwMEZBbi4ifSwKLQotICB7IEVSX1VOS05PV05fQVhJUywKLSAgICAgImVqZSBkZXNjb25vY2lkbzogezB9In0sCi0KLSAgeyBFUl9VTktOT1dOX01BVENIX09QRVJBVElPTiwKLSAgICAgIk9wZXJhY2lcdTAwRjNuIGRlIGNvaW5jaWRlbmNpYSBkZXNjb25vY2lkYS4ifSwKLQotICB7IEVSX0lOQ09SUkVDVF9BUkdfTEVOR1RILAotICAgICAgIkxhIGxvbmdpdHVkIGRlbCBhcmd1bWVudG8gZGUgbGEgcHJ1ZWJhIGRlbCBub2RvIHByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24oKSBlcyBpbmNvcnJlY3RhLiJ9LAotCi0gIHsgRVJfQ0FOVF9DT05WRVJUX1RPX05VTUJFUiwKLSAgICAgICJObyBzZSBwdWVkZSBjb252ZXJ0aXIgezB9IGVuIHVuIG5cdTAwRkFtZXJvIn0sCi0KLSAgeyBFUl9DQU5UX0NPTlZFUlRfVE9fTk9ERUxJU1QsCi0gICAgICAiTm8gc2UgcHVlZGUgY29udmVydGlyIHswfSBlbiB1bmEgbGlzdGEgZGUgbm9kb3MuIn0sCi0KLSAgeyBFUl9DQU5UX0NPTlZFUlRfVE9fTVVUQUJMRU5PREVMSVNULAotICAgICAgIk5vIHNlIHB1ZWRlIGNvbnZlcnRpciB7MH0gZW4gdW4gRFRNIGRlIGp1ZWdvIGRlIG5vZG9zLiJ9LAotCi0gIHsgRVJfQ0FOVF9DT05WRVJUX1RPX1RZUEUsCi0gICAgICAiTm8gc2UgcHVlZGUgY29udmVydGlyIHswfSBlbiBlbCBuXHUwMEZBbWVybyBkZSB0aXBvIHsxfSJ9LAotCi0gIHsgRVJfRVhQRUNURURfTUFUQ0hfUEFUVEVSTiwKLSAgICAgICJQYXRyXHUwMEYzbiBkZSBjb2luY2lkZW5jaWEgZXNwZXJhZG8gZW4gZ2V0TWF0Y2hTY29yZS4ifSwKLQotICB7IEVSX0NPVUxETk9UX0dFVF9WQVJfTkFNRUQsCi0gICAgICAiTm8gc2UgaGEgZW5jb250cmFkbyBsYSB2YXJpYWJsZSBsbGFtYWRhIHswfSJ9LAotCi0gIHsgRVJfVU5LTk9XTl9PUENPREUsCi0gICAgICJFUlJPUi4gQ1x1MDBGM2RpZ28gZGUgb3BlcmFjaVx1MDBGM24gZGVzY29ub2NpZG86IHswfSJ9LAotCi0gIHsgRVJfRVhUUkFfSUxMRUdBTF9UT0tFTlMsCi0gICAgICJUb2tlbnMgbm8gcGVybWl0aWRvcyBhZGljaW9uYWxlczogezB9In0sCi0KLSAgeyBFUl9FWFBFQ1RFRF9ET1VCTEVfUVVPVEUsCi0gICAgICAibGl0ZXJhbCBjb24gY29taWxsYXMgaW5jb3JyZWN0YXMuLi4gc2UgZXNwZXJhYmFuIGNvbWlsbGFzIGRvYmxlcyJ9LAotCi0gIHsgRVJfRVhQRUNURURfU0lOR0xFX1FVT1RFLAotICAgICAgImxpdGVyYWwgY29uIGNvbWlsbGFzIGluY29ycmVjdGFzLi4uIHNlIGVzcGVyYWJhbiBjb21pbGxhcyBzaW1wbGVzIn0sCi0KLSAgeyBFUl9FTVBUWV9FWFBSRVNTSU9OLAotICAgICAiRXhwcmVzaVx1MDBGM24gdmFjXHUwMEVEYSJ9LAotCi0gIHsgRVJfRVhQRUNURURfQlVUX0ZPVU5ELAotICAgICAiU2UgZXNwZXJhYmEgezB9IHBlcm8gc2UgaGEgZW5jb250cmFkbzogezF9In0sCi0KLSAgeyBFUl9JTkNPUlJFQ1RfUFJPR1JBTU1FUl9BU1NFUlRJT04sCi0gICAgICAiTGEgYWZpcm1hY2lcdTAwRjNuIGRlbCBwcm9ncmFtYWRvciBlcyBpbmNvcnJlY3RhIC0gezB9In0sCi0KLSAgeyBFUl9CT09MRUFOX0FSR19OT19MT05HRVJfT1BUSU9OQUwsCi0gICAgICAiRWwgYXJndW1lbnRvIGJvb2xlYW4oLi4uKSB5YSBubyBlcyBvcGNpb25hbCBjb24gZWwgYm9ycmFkb3IgZGUgWFBhdGggMTk5OTA3MDkuIn0sCi0KLSAgeyBFUl9GT1VORF9DT01NQV9CVVRfTk9fUFJFQ0VESU5HX0FSRywKLSAgICAgICJTZSBoYW4gZW5jb250cmFkbyAnLCcgcGVybyBubyB2YSBzZWd1aWRvIGRlIG5pbmdcdTAwRkFuIGFyZ3VtZW50byJ9LAotCi0gIHsgRVJfRk9VTkRfQ09NTUFfQlVUX05PX0ZPTExPV0lOR19BUkcsCi0gICAgICAiU2UgaGFuIGVuY29udHJhZG8gJywnIHBlcm8gbm8gbGUgc2lndWUgbmluZ1x1MDBGQW4gYXJndW1lbnRvIn0sCi0KLSAgeyBFUl9QUkVESUNBVEVfSUxMRUdBTF9TWU5UQVgsCi0gICAgICAiJy4uW3ByZWRpY2F0ZV0nIG8gJy5bcHJlZGljYXRlXScgZXMgdW5hIHNpbnRheGlzIG5vIHZcdTAwRTFsaWRhLiBVdGlsaWNlICdzZWxmOjpub2RlKClbcHJlZGljYXRlXScgZW4gc3UgbHVnYXIuIn0sCi0KLSAgeyBFUl9JTExFR0FMX0FYSVNfTkFNRSwKLSAgICAgIm5vbWJyZSBkZSBlamUgbm8gcGVybWl0aWRvOiB7MH0ifSwKLQotICB7IEVSX1VOS05PV05fTk9ERVRZUEUsCi0gICAgICJUaXBvIGRlIG5vZG8gZGVzY29ub2NpZG86IHswfSJ9LAotCi0gIHsgRVJfUEFUVEVSTl9MSVRFUkFMX05FRURTX0JFX1FVT1RFRCwKLSAgICAgICJFbCBwYXRyXHUwMEYzbiBsaXRlcmFsICh7MH0pIGRlYmUgaW5jbHVpcnNlIGVudHJlIGNvbWlsbGFzIn0sCi0KLSAgeyBFUl9DT1VMRE5PVF9CRV9GT1JNQVRURURfVE9fTlVNQkVSLAotICAgICAgInswfSBubyBzZSBoYSBwb2RpZG8gZm9ybWF0ZWFyIGVuIHVuIG5cdTAwRkFtZXJvLiJ9LAotCi0gIHsgRVJfQ09VTEROT1RfQ1JFQVRFX1hNTFBST0NFU1NPUkxJQUlTT04sCi0gICAgICAiTm8gc2UgaGEgcG9kaWRvIGNyZWFyIGVsIGVubGFjZSBUcmFuc2Zvcm1lckZhY3RvcnkgWE1MOiB7MH0ifSwKLQotICB7IEVSX0RJRE5PVF9GSU5EX1hQQVRIX1NFTEVDVF9FWFAsCi0gICAgICAiRXJyb3IuIE5vIHNlIGhhIGVuY29udHJhZG8gbGEgZXhwcmVzaVx1MDBGM24gZGUgc2VsZWNjaVx1MDBGM24geHBhdGggKC1zZWxlY3QpLiJ9LAotCi0gIHsgRVJfQ09VTEROT1RfRklORF9FTkRPUF9BRlRFUl9PUExPQ0FUSU9OUEFUSCwKLSAgICAgICJFUlJPUi4gTm8gc2UgaGEgZW5jb250cmFkbyBFTkRPUCBkZXNwdVx1MDBFOXMgZGUgT1BfTE9DQVRJT05QQVRIIn0sCi0KLSAgeyBFUl9FUlJPUl9PQ0NVUkVELAotICAgICAiU2UgaGEgcHJvZHVjaWRvIHVuIGVycm9yLiJ9LAotCi0gIHsgRVJfSUxMRUdBTF9WQVJJQUJMRV9SRUZFUkVOQ0UsCi0gICAgICAiTGEgcmVmZXJlbmNpYSBkZSB2YXJpYWJsZSBwcm9wb3JjaW9uYWRhIHBhcmEgbGEgdmFyaWFibGUgZXN0XHUwMEUxIGZ1ZXJhIGRlIGNvbnRleHRvIG8gbm8gdGllbmUgZGVmaW5pY2lcdTAwRjNuLiBOb21icmUgPSB7MH0ifSwKLQotICB7IEVSX0FYRVNfTk9UX0FMTE9XRUQsCi0gICAgICAiU1x1MDBGM2xvIGxvcyBlamVzIGNoaWxkOjogeSBhdHRyaWJ1dGU6OiBlc3RcdTAwRTFuIHBlcm1pdGlkb3MgZW4gbG9zIHBhdHJvbmVzIGRlIGNvaW5jaWRlbmNpYS4gRWplcyBpbmNvcnJlY3RvcyA9IHswfSJ9LAotCi0gIHsgRVJfS0VZX0hBU19UT09fTUFOWV9BUkdTLAotICAgICAgImtleSgpIHRpZW5lIHVuIG5cdTAwRkFtZXJvIGluY29ycmVjdG8gZGUgYXJndW1lbnRvcy4ifSwKLQotICB7IEVSX0NPVU5UX1RBS0VTXzFfQVJHLAotICAgICAgIkxhIGZ1bmNpXHUwMEYzbiBjb3VudCBuZWNlc2l0YSB1biBhcmd1bWVudG8uIn0sCi0KLSAgeyBFUl9DT1VMRE5PVF9GSU5EX0ZVTkNUSU9OLAotICAgICAiTm8gc2UgaGEgZW5jb250cmFkbyBsYSBmdW5jaVx1MDBGM246IHswfSJ9LAotCi0gIHsgRVJfVU5TVVBQT1JURURfRU5DT0RJTkcsCi0gICAgICJDb2RpZmljYWNpXHUwMEYzbiBubyBzb3BvcnRhZGE6IHswfSJ9LAotCi0gIHsgRVJfUFJPQkxFTV9JTl9EVE1fTkVYVFNJQkxJTkcsCi0gICAgICAiU2UgaGEgcHJvZHVjaWRvIHVuIHByb2JsZW1hIGVuIERUTSBlbiBnZXROZXh0U2libGluZy4uLiBpbnRlbnRhbmRvIGxhIHJlY3VwZXJhY2lcdTAwRjNuIn0sCi0KLSAgeyBFUl9DQU5OT1RfV1JJVEVfVE9fRU1QVFlOT0RFTElTVElNUEwsCi0gICAgICAiRXJyb3IgZGUgcHJvZ3JhbWFkb3I6IG5vIHNlIHB1ZWRlIGVzY3JpYmlyIGVuIEVtcHR5Tm9kZUxpc3QuIn0sCi0KLSAgeyBFUl9TRVRET01GQUNUT1JZX05PVF9TVVBQT1JURUQsCi0gICAgICAic2V0RE9NRmFjdG9yeSBubyBlc3RcdTAwRTEgc29wb3J0YWRvIHBvciBYUGF0aENvbnRleHQuIn0sCi0KLSAgeyBFUl9QUkVGSVhfTVVTVF9SRVNPTFZFLAotICAgICAgIkVsIHByZWZpam8gc2UgZGViZSByZXNvbHZlciBlbiB1biBlc3BhY2lvIGRlIG5vbWJyZXM6IHswfSJ9LAotCi0gIHsgRVJfUEFSU0VfTk9UX1NVUFBPUlRFRCwKLSAgICAgICJFbCBhblx1MDBFMWxpc2lzIChvcmlnZW4gZGUgSW5wdXRTb3VyY2UpIG5vIGVzdFx1MDBFMSBzb3BvcnRhZG8gZW4gWFBhdGhDb250ZXh0LiBObyBzZSBwdWVkZSBhYnJpciB7MH0ifSwKLQotICB7IEVSX1NBWF9BUElfTk9UX0hBTkRMRUQsCi0gICAgICAiTG9zIGNhcmFjdGVyZXMgZGUgQVBJIFNBWCAoY2hhciBjaFtdLi4uIG5vIGxvcyBnZXN0aW9uYSBlbCBEVE0uIn0sCi0KLSAgeyBFUl9JR05PUkFCTEVfV0hJVEVTUEFDRV9OT1RfSEFORExFRCwKLSAgICAgICJpZ25vcmFibGVXaGl0ZXNwYWNlKGNoYXIgY2hbXS4uLiBubyBnZXN0aW9uYWRvIHBvciBEVE0uIn0sCi0KLSAgeyBFUl9EVE1fQ0FOTk9UX0hBTkRMRV9OT0RFUywKLSAgICAgICJEVE1MaWFpc29uIG5vIHB1ZWRlIGdlc3Rpb25hciBsb3Mgbm9kb3MgZGUgdGlwbyB7MH0ifSwKLQotICB7IEVSX1hFUkNFU19DQU5OT1RfSEFORExFX05PREVTLAotICAgICAgIkRPTTJIZWxwZXIgbm8gcHVlZGUgZ2VzdGlvbmFyIGxvcyBub2RvcyBkZSB0aXBvIHswfSJ9LAotCi0gIHsgRVJfWEVSQ0VTX1BBUlNFX0VSUk9SX0RFVEFJTFMsCi0gICAgICAiRXJyb3IgZGUgRE9NMkhlbHBlci5wYXJzZTogaWRlbnRpZmljYWRvciBkZSBzaXN0ZW1hIC0gezB9IGxcdTAwRURuZWEgLSB7MX0ifSwKLQotICB7IEVSX1hFUkNFU19QQVJTRV9FUlJPUiwKLSAgICAgIkVycm9yIGRlIERPTTJIZWxwZXIucGFyc2UifSwKLQotICB7IEVSX0lOVkFMSURfVVRGMTZfU1VSUk9HQVRFLAotICAgICAgIlx1MDBCRlNlIGhhIGRldGVjdGFkbyB1biBzdXN0aXR1dG8gVVRGLTE2IG5vIHZcdTAwRTFsaWRvOiB7MH0/In0sCi0KLSAgeyBFUl9PSUVSUk9SLAotICAgICAiRXJyb3IgZGUgRVMifSwKLQotICB7IEVSX0NBTk5PVF9DUkVBVEVfVVJMLAotICAgICAiTm8gc2UgcHVlZGUgY3JlYXIgbGEgVVJMIHBhcmE6IHswfSJ9LAotCi0gIHsgRVJfWFBBVEhfUkVBRE9CSkVDVCwKLSAgICAgIkVuIFhQYXRoLnJlYWRPYmplY3Q6IHswfSJ9LAotCi0gIHsgRVJfRlVOQ1RJT05fVE9LRU5fTk9UX0ZPVU5ELAotICAgICAgIk5vIHNlIGhhIGVuY29udHJhZG8gZWwgdG9rZW4gZGUgZnVuY2lcdTAwRjNuLiJ9LAotCi0gIHsgRVJfQ0FOTk9UX0RFQUxfWFBBVEhfVFlQRSwKLSAgICAgICAiTm8gc2UgcHVlZGUgbmVnb2NpYXIgY29uIGVsIHRpcG8gZGUgWFBhdGg6IHswfSJ9LAotCi0gIHsgRVJfTk9ERVNFVF9OT1RfTVVUQUJMRSwKLSAgICAgICAiRXN0ZSBqdWVnbyBkZSBub2RvcyBubyBlcyBtb2RpZmljYWJsZSJ9LAotCi0gIHsgRVJfTk9ERVNFVERUTV9OT1RfTVVUQUJMRSwKLSAgICAgICAiRXN0ZSBEVE0gZGUganVlZ28gZGUgbm9kb3Mgbm8gZXMgbW9kaWZpY2FibGUifSwKLQotICB7IEVSX1ZBUl9OT1RfUkVTT0xWQUJMRSwKLSAgICAgICAgIkxhIHZhcmlhYmxlIG5vIHNlIHB1ZWRlIHJlc29sdmVyOiB7MH0ifSwKLQotICB7IEVSX05VTExfRVJST1JfSEFORExFUiwKLSAgICAgICAgIk1hbmVqYWRvciBkZSBlcnJvcmVzIG51bG8ifSwKLQotICB7IEVSX1BST0dfQVNTRVJUX1VOS05PV05fT1BDT0RFLAotICAgICAgICJBZmlybWFjaVx1MDBGM24gZGVsIHByb2dyYW1hZG9yOiBjXHUwMEYzZGlnbyBkZSBvcGVyYWNpXHUwMEYzbiBkZXNjb25vY2lkbzogezB9In0sCi0KLSAgeyBFUl9aRVJPX09SX09ORSwKLSAgICAgICAiMCBvIDEifSwKLQotICB7IEVSX1JURl9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSLAotICAgICAgICJydGYoKSBubyBzb3BvcnRhZG8gcG9yIFhSVHJlZUZyYWdTZWxlY3RXcmFwcGVyIn0sCi0KLSAgeyBFUl9SVEZfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiwKLSAgICAgICAiYXNOb2RlSXRlcmF0b3IoKSBubyBzb3BvcnRhZG8gcG9yIFhSVHJlZUZyYWdTZWxlY3RXcmFwcGVyIn0sCi0KLSAgICAgICAgLyoqICBkZXRhY2goKSBub3Qgc3VwcG9ydGVkIGJ5IFhSVHJlZUZyYWdTZWxlY3RXcmFwcGVyICAgKi8KLSAgIHsgRVJfREVUQUNIX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIsCi0gICAgICAgICAgICAgICAgImRldGFjaCgpIG5vIHNvcG9ydGFkbyBwb3IgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIifSwKLQotICAgICAgICAvKiogIG51bSgpIG5vdCBzdXBwb3J0ZWQgYnkgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIgICAqLwotICAgeyBFUl9OVU1fTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiwKLSAgICAgICAgICAgICAgICAibnVtKCkgbm8gc29wb3J0YWRvIHBvciBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciJ9LAotCi0gICAgICAgIC8qKiAgeHN0cigpIG5vdCBzdXBwb3J0ZWQgYnkgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIgICAqLwotICAgeyBFUl9YU1RSX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIsCi0gICAgICAgICAgICAgICAgInhzdHIoKSBubyBzb3BvcnRhZG8gcG9yIFhSVHJlZUZyYWdTZWxlY3RXcmFwcGVyIn0sCi0KLSAgICAgICAgLyoqICBzdHIoKSBub3Qgc3VwcG9ydGVkIGJ5IFhSVHJlZUZyYWdTZWxlY3RXcmFwcGVyICAgKi8KLSAgIHsgRVJfU1RSX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIsCi0gICAgICAgICAgICAgICAgInN0cigpIG5vIHNvcG9ydGFkbyBwb3IgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIifSwKLQotICB7IEVSX0ZTQl9OT1RfU1VQUE9SVEVEX1hTVFJJTkdGT1JDSEFSUywKLSAgICAgICAiZnNiKCkgbm8gc29wb3J0YWRvIHBhcmEgWFN0cmluZ0ZvckNoYXJzIn0sCi0KLSAgeyBFUl9DT1VMRF9OT1RfRklORF9WQVIsCi0gICAgICAiTm8gc2UgaGEgZW5jb250cmFkbyBsYSB2YXJpYWJsZSBjb24gZWwgbm9tYnJlIGRlIHswfSJ9LAotCi0gIHsgRVJfWFNUUklOR0ZPUkNIQVJTX0NBTk5PVF9UQUtFX1NUUklORywKLSAgICAgICJYU3RyaW5nRm9yQ2hhcnMgbm8gcHVlZGUgdXRpbGl6YXIgdW5hIGNhZGVuYSBwYXJhIHVuIGFyZ3VtZW50byJ9LAotCi0gIHsgRVJfRkFTVFNUUklOR0JVRkZFUl9DQU5OT1RfQkVfTlVMTCwKLSAgICAgICJFbCBhcmd1bWVudG8gRmFzdFN0cmluZ0J1ZmZlciBubyBwdWVkZSBzZXIgbnVsbyJ9LAotCi0gIHsgRVJfVFdPX09SX1RIUkVFLAotICAgICAgICIyIG8gMyJ9LAotCi0gIHsgRVJfVkFSSUFCTEVfQUNDRVNTRURfQkVGT1JFX0JJTkQsCi0gICAgICAgIlNlIGhhIGFjY2VkaWRvIGEgbGEgdmFyaWFibGUgYW50ZXMgZGUgcXVlIHNlIGhheWEgZW5sYXphZG8uIn0sCi0KLSAgeyBFUl9GU0JfQ0FOTk9UX1RBS0VfU1RSSU5HLAotICAgICAgICJYU3RyaW5nRm9yRlNCIG5vIHB1ZWRlIHV0aWxpemFyIHVuYSBjYWRlbmEgcGFyYSB1biBhcmd1bWVudG8uIn0sCi0KLSAgeyBFUl9TRVRUSU5HX1dBTEtFUl9ST09UX1RPX05VTEwsCi0gICAgICAgIlxuIEVycm9yLiBEZWZpbmljaVx1MDBGM24gZGUgdW5hIHJhXHUwMEVEeiBkZSB1biB3YWxrZXIgY29tbyBudWxhLiJ9LAotCi0gIHsgRVJfTk9ERVNFVERUTV9DQU5OT1RfSVRFUkFURSwKLSAgICAgICAiRXN0ZSBEVE0gZGUganVlZ28gZGUgbm9kb3Mgbm8gcHVlZGUgaXRlcmFyc2UgZW4gdW4gbm9kbyBhbnRlcmlvci4ifSwKLQotICB7IEVSX05PREVTRVRfQ0FOTk9UX0lURVJBVEUsCi0gICAgICAgIkVzdGUganVlZ28gZGUgbm9kb3Mgbm8gc2UgcHVlZGUgaXRlcmFyIGVuIHVuIG5vZG8gYW50ZXJpb3IuIn0sCi0KLSAgeyBFUl9OT0RFU0VURFRNX0NBTk5PVF9JTkRFWCwKLSAgICAgICAiRXN0ZSBEVE0gZGUganVlZ28gZGUgbm9kb3Mgbm8gcHVlZGUgcmVhbGl6YXIgZnVuY2lvbmVzIGRlIGluZGV4YWNpXHUwMEYzbiBvIHJlY3VlbnRvLiJ9LAotCi0gIHsgRVJfTk9ERVNFVF9DQU5OT1RfSU5ERVgsCi0gICAgICAgIkVzdGUganVlZ28gZGUgbm9kb3Mgbm8gcHVlZGUgcmVhbGl6YXIgZnVuY2lvbmVzIGRlIGluZGV4YWNpXHUwMEYzbiBvIHJlY3VlbnRvLiJ9LAotCi0gIHsgRVJfQ0FOTk9UX0NBTExfU0VUU0hPVUxEQ0FDSEVOT0RFLAotICAgICAgICJObyBzZSBwdWVkZSBsbGFtYXIgYSBzZXRTaG91bGRDYWNoZU5vZGVzIGRlc3B1XHUwMEU5cyBkZSBoYWJlciBsbGFtYWRvIGEgbmV4dE5vZGUuIn0sCi0KLSAgeyBFUl9PTkxZX0FMTE9XUywKLSAgICAgICAiezB9IHNcdTAwRjNsbyBwZXJtaXRlIHsxfSBhcmd1bWVudG9zIn0sCi0KLSAgeyBFUl9VTktOT1dOX1NURVAsCi0gICAgICAgIkFmaXJtYWNpXHUwMEYzbiBkZWwgcHJvZ3JhbWFkb3IgZW4gZ2V0TmV4dFN0ZXBQb3M6IHRpcG8gZGUgcGFzbyBkZXNjb25vY2lkbzogezB9In0sCi0KLSAgLy9Ob3RlIHRvIHRyYW5zbGF0b3JzOiAgQSByZWxhdGl2ZSBsb2NhdGlvbiBwYXRoIGlzIGEgZm9ybSBvZiBYUGF0aCBleHByZXNzaW9uLgotICAvLyBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCBzdWNoIGFuIGV4cHJlc3Npb24gd2FzIGV4cGVjdGVkIGZvbGxvd2luZyB0aGUKLSAgLy8gY2hhcmFjdGVycyAnLycgb3IgJy8vJywgYnV0IHdhcyBub3QgZm91bmQuCi0gIHsgRVJfRVhQRUNURURfUkVMX0xPQ19QQVRILAotICAgICAgIlNlIGVzcGVyYWJhIHVuYSBydXRhIGRlIGFjY2VzbyBkZSB1YmljYWNpXHUwMEYzbiByZWxhdGl2YSBkZXNwdVx1MDBFOXMgZGVsIHRva2VuICcvJyBvICcvLycuIn0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIEEgbG9jYXRpb24gcGF0aCBpcyBhIGZvcm0gb2YgWFBhdGggZXhwcmVzc2lvbi4KLSAgLy8gVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgc3ludGFjdGljYWxseSBzdWNoIGFuIGV4cHJlc3Npb24gd2FzIGV4cGVjdGVkLGJ1dAotICAvLyB0aGUgY2hhcmFjdGVycyBzcGVjaWZpZWQgYnkgdGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHdlcmUgZW5jb3VudGVyZWQgaW5zdGVhZC4KLSAgeyBFUl9FWFBFQ1RFRF9MT0NfUEFUSCwKLSAgICAgICAiU2UgZXNwZXJhYmEgdW5hIHJ1dGEgZGUgYWNjZXNvIGRlIHViaWNhY2lcdTAwRjNuLCBwZXJvIHNlIGhhIGVuY29udHJhZG8gZWwgc2lndWllbnRlIHRva2VuOiB7MH0ifSwKLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQSBsb2NhdGlvbiBwYXRoIGlzIGEgZm9ybSBvZiBYUGF0aCBleHByZXNzaW9uLgotICAvLyBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCBzeW50YWN0aWNhbGx5IHN1Y2ggYSBzdWJleHByZXNzaW9uIHdhcyBleHBlY3RlZCwKLSAgLy8gYnV0IG5vIG1vcmUgY2hhcmFjdGVycyB3ZXJlIGZvdW5kIGluIHRoZSBleHByZXNzaW9uLgotICB7IEVSX0VYUEVDVEVEX0xPQ19QQVRIX0FUX0VORF9FWFBSLAotICAgICAgICJTZSBlc3BlcmFiYSB1bmEgcnV0YSBkZSBhY2Nlc28gZGUgdWJpY2FjaVx1MDBGM24sIHBlcm8gc2UgaGEgZW5jb250cmFkbyBlbCBmaW5hbCBkZSBsYSBleHByZXNpXHUwMEYzbiBYUGF0aCBlbiBzdSBsdWdhci4ifSwKLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQSBsb2NhdGlvbiBzdGVwIGlzIHBhcnQgb2YgYW4gWFBhdGggZXhwcmVzc2lvbi4KLSAgLy8gVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgc3ludGFjdGljYWxseSBzdWNoIGFuIGV4cHJlc3Npb24gd2FzIGV4cGVjdGVkCi0gIC8vIGZvbGxvd2luZyB0aGUgc3BlY2lmaWVkIGNoYXJhY3RlcnMuCi0gIHsgRVJfRVhQRUNURURfTE9DX1NURVAsCi0gICAgICAgIlNlIGVzcGVyYWJhIHVuIHBhc28gZGUgdWJpY2FjaVx1MDBGM24gZGVzcHVcdTAwRTlzIGRlbCB0b2tlbiAnLycgbyAnLy8nLiJ9LAotCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBIG5vZGUgdGVzdCBpcyBwYXJ0IG9mIGFuIFhQYXRoIGV4cHJlc3Npb24gdGhhdCBpcwotICAvLyB1c2VkIHRvIHRlc3QgZm9yIHBhcnRpY3VsYXIga2luZHMgb2Ygbm9kZXMuICBJbiB0aGlzIGNhc2UsIGEgbm9kZSB0ZXN0IHRoYXQKLSAgLy8gY29uc2lzdHMgb2YgYW4gTkNOYW1lIGZvbGxvd2VkIGJ5IGEgY29sb24gYW5kIGFuIGFzdGVyaXNrIG9yIHRoYXQgY29uc2lzdHMKLSAgLy8gb2YgYSBRTmFtZSB3YXMgZXhwZWN0ZWQsIGJ1dCB3YXMgbm90IGZvdW5kLgotICB7IEVSX0VYUEVDVEVEX05PREVfVEVTVCwKLSAgICAgICAiU2UgZXNwZXJhYmEgdW5hIHBydWViYSBkZSBub2RvIHF1ZSBjb2luY2lkaWVyYSBjb24gZWwgTkNOYW1lOiogbyBRTmFtZS4ifSwKLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQSBzdGVwIHBhdHRlcm4gaXMgcGFydCBvZiBhbiBYUGF0aCBleHByZXNzaW9uLgotICAvLyBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCBzeW50YWN0aWNhbGx5IHN1Y2ggYW4gZXhwcmVzc2lvbiB3YXMgZXhwZWN0ZWQsCi0gIC8vIGJ1dCB0aGUgc3BlY2lmaWVkIGNoYXJhY3RlciB3YXMgZm91bmQgaW4gdGhlIGV4cHJlc3Npb24gaW5zdGVhZC4KLSAgeyBFUl9FWFBFQ1RFRF9TVEVQX1BBVFRFUk4sCi0gICAgICAgIlNlIGVzcGVyYWJhIHVuIHBhdHJcdTAwRjNuIGRlIHBhc28sIHBlcm8gc2UgaGEgZW5jb250cmFkbyAnLycuIn0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogQSByZWxhdGl2ZSBwYXRoIHBhdHRlcm4gaXMgcGFydCBvZiBhbiBYUGF0aCBleHByZXNzaW9uLgotICAvLyBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCBzeW50YWN0aWNhbGx5IHN1Y2ggYW4gZXhwcmVzc2lvbiB3YXMgZXhwZWN0ZWQsCi0gIC8vIGJ1dCB3YXMgbm90IGZvdW5kLgotICB7IEVSX0VYUEVDVEVEX1JFTF9QQVRIX1BBVFRFUk4sCi0gICAgICAgIlNlIGVzcGVyYWJhIHVuIHBhdHJcdTAwRjNuIGRlIHJ1dGEgZGUgYWNjZXNvIHJlbGF0aXZhLiJ9LAotCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYSBkYXRhIHR5cGUuICBUaGUKLSAgLy8gbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCBhIHZhbHVlIG9mIGEgcGFydGljdWxhciB0eXBlIGNvdWxkIG5vdCBiZSBjb252ZXJ0ZWQKLSAgLy8gdG8gYSB2YWx1ZSBvZiB0eXBlIGJvb2xlYW4uCi0gIHsgRVJfQ0FOVF9DT05WRVJUX1RPX0JPT0xFQU4sCi0gICAgICAgIkVsIHZhbG9yIGRlIFhQYXRoUmVzdWx0IGRlIGxhIGV4cHJlc2lcdTAwRjNuIFhQYXRoICcnezB9JycgdGllbmUgdW4gdmFsb3IgZGUgWFBhdGhSZXN1bHRUeXBlIGRlIHsxfSBxdWUgbm8gc2UgcHVlZGUgY29udmVydGlyIGVuIHVuIHZhbG9yIGJvb2xlYW5vLiJ9LAotCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6IERvIG5vdCB0cmFuc2xhdGUgQU5ZX1VOT1JERVJFRF9OT0RFX1RZUEUgYW5kCi0gIC8vIEZJUlNUX09SREVSRURfTk9ERV9UWVBFLgotICB7IEVSX0NBTlRfQ09OVkVSVF9UT19TSU5HTEVOT0RFLAotICAgICAgICJFbCB2YWxvciBkZSBYUGF0aFJlc3VsdCBkZSBsYSBleHByZXNpXHUwMEYzbiBYUGF0aCAnJ3swfScnIHRpZW5lIHVuIHZhbG9yIGRlIFhQYXRoUmVzdWx0VHlwZSBkZSB7MX0gcXVlIG5vIHNlIHB1ZWRlIGNvbnZlcnRpciBhIHVuIG5vZG8gXHUwMEZBbmljby4gRWwgbVx1MDBFOXRvZG8gZ2V0U2luZ2xlTm9kZVZhbHVlIHNlIGFwbGljYSBzXHUwMEYzbG8gYSBsb3MgdGlwb3MgQU5ZX1VOT1JERVJFRF9OT0RFX1RZUEUgeSBGSVJTVF9PUkRFUkVEX05PREVfVFlQRS4ifSwKLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiBEbyBub3QgdHJhbnNsYXRlIFVOT1JERVJFRF9OT0RFX1NOQVBTSE9UX1RZUEUgYW5kCi0gIC8vIE9SREVSRURfTk9ERV9TTkFQU0hPVF9UWVBFLgotICB7IEVSX0NBTlRfR0VUX1NOQVBTSE9UX0xFTkdUSCwKLSAgICAgICAiTm8gc2UgcHVlZGUgbGxhbWFyIGFsIG1cdTAwRTl0b2RvIGdldFNuYXBzaG90TGVuZ3RoIGVuIGxhIGV4cHJlc2lcdTAwRjNuIFhQYXRoUmVzdWx0IGRlIFhQYXRoICcnezB9JycgcG9ycXVlIGVsIHZhbG9yIGRlIHN1IFhQYXRoUmVzdWx0VHlwZSBlcyB7MX0uIEVzdGUgbVx1MDBFOXRvZG8gc2UgYXBsaWNhIHNcdTAwRjNsbyBhIGxvcyB0aXBvcyBVTk9SREVSRURfTk9ERV9TTkFQU0hPVF9UWVBFIHkgT1JERVJFRF9OT0RFX1NOQVBTSE9UX1RZUEUuIn0sCi0KLSAgeyBFUl9OT05fSVRFUkFUT1JfVFlQRSwKLSAgICAgICAiTm8gc2UgcHVlZGUgbGxhbWFyIGFsIG1cdTAwRTl0b2RvIGl0ZXJhdGVOZXh0IGVuIGVsIFhQYXRoUmVzdWx0IGRlIGxhIGV4cHJlc2lcdTAwRjNuIFhQYXRoICcnezB9JycgcG9ycXVlIGVsIHZhbG9yIGRlIHN1IFhQYXRoUmVzdWx0VHlwZSBlcyB7MX0uIEVzdGUgbVx1MDBFOXRvZG8gc2UgYXBsaWNhIHNcdTAwRjNsbyBhIGxvcyB0aXBvcyBVTk9SREVSRURfTk9ERV9JVEVSQVRPUl9UWVBFIHkgT1JERVJFRF9OT0RFX0lURVJBVE9SX1RZUEUuIn0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogVGhpcyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoZSBkb2N1bWVudCBiZWluZyBvcGVyYXRlZAotICAvLyB1cG9uIGNoYW5nZWQsIHNvIHRoZSBpdGVyYXRvciBvYmplY3QgdGhhdCB3YXMgYmVpbmcgdXNlZCB0byB0cmF2ZXJzZSB0aGUKLSAgLy8gZG9jdW1lbnQgaGFzIG5vdyBiZWNvbWUgaW52YWxpZC4KLSAgeyBFUl9ET0NfTVVUQVRFRCwKLSAgICAgICAiRG9jdW1lbnRvIG11dGFkbyBkZWJpZG8gYSBxdWUgc2UgaGEgZGV2dWVsdG8gZWwgcmVzdWx0YWRvLiBFbCBpdGVyYWRvciBubyBlcyB2XHUwMEUxbGlkby4ifSwKLQotICB7IEVSX0lOVkFMSURfWFBBVEhfVFlQRSwKLSAgICAgICAiQXJndW1lbnRvIGRlIHRpcG8gWFBhdGggbm8gdlx1MDBFMWxpZG86IHswfSJ9LAotCi0gIHsgRVJfRU1QVFlfWFBBVEhfUkVTVUxULAotICAgICAgICJPYmpldG8gZGUgcmVzdWx0YWRvIFhQYXRoIHZhY1x1MDBFRG8ifSwKLQotICB7IEVSX0lOQ09NUEFUSUJMRV9UWVBFUywKLSAgICAgICAiRWwgdmFsb3IgZGUgWFBhdGhSZXN1bHQgZGUgbGEgZXhwcmVzaVx1MDBGM24gWFBhdGggJyd7MH0nJyB0aWVuZSB1biB2YWxvciBkZSBYUGF0aFJlc3VsdFR5cGUgZGUgezF9IHF1ZSBubyBzZSBwdWVkZSBmb3J6YXIgZW4gZWwgWFBhdGhSZXN1bHRUeXBlIGVzcGVjaWZpY2FkbyBkZSB7Mn0uIn0sCi0KLSAgeyBFUl9OVUxMX1JFU09MVkVSLAotICAgICAgICJObyBzZSBoYSBwb2RpZG8gcmVzb2x2ZXIgZWwgcHJlZmlqbyBjb24gZWwgc2lzdGVtYSBkZSByZXNvbHVjaVx1MDBGM24gZGUgcHJlZmlqb3MgbnVsby4ifSwKLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIGEgZGF0YSB0eXBlLiAgVGhlCi0gIC8vIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgYSB2YWx1ZSBvZiBhIHBhcnRpY3VsYXIgdHlwZSBjb3VsZCBub3QgYmUgY29udmVydGVkCi0gIC8vIHRvIGEgdmFsdWUgb2YgdHlwZSBzdHJpbmcuCi0gIHsgRVJfQ0FOVF9DT05WRVJUX1RPX1NUUklORywKLSAgICAgICAiRWwgdmFsb3IgZGUgWFBhdGhSZXN1bHQgZGUgbGEgZXhwcmVzaVx1MDBGM24gWFBhdGggJyd7MH0nJyB0aWVuZSB1biB2YWxvciBkZSBYUGF0aFJlc3VsdFR5cGUgZGUgezF9IHF1ZSBubyBzZSBwdWVkZSBjb252ZXJ0aXIgZW4gdW5hIGNhZGVuYS4ifSwKLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiBEbyBub3QgdHJhbnNsYXRlIHNuYXBzaG90SXRlbSwKLSAgLy8gVU5PUkRFUkVEX05PREVfU05BUFNIT1RfVFlQRSBhbmQgT1JERVJFRF9OT0RFX1NOQVBTSE9UX1RZUEUuCi0gIHsgRVJfTk9OX1NOQVBTSE9UX1RZUEUsCi0gICAgICAgIk5vIHNlIHB1ZWRlIGxsYW1hciBhbCBtXHUwMEU5dG9kbyBzbmFwc2hvdEl0ZW0gZW4gbGEgZXhwcmVzaVx1MDBGM24gWFBhdGhSZXN1bHQgZGUgWFBhdGggJyd7MH0nJyBwb3JxdWUgZWwgdmFsb3IgZGUgc3UgWFBhdGhSZXN1bHRUeXBlIGVzIHsxfS4gRXN0ZSBtXHUwMEU5dG9kbyBzZSBhcGxpY2Egc1x1MDBGM2xvIGEgbG9zIHRpcG9zIFVOT1JERVJFRF9OT0RFX1NOQVBTSE9UX1RZUEUgeSBPUkRFUkVEX05PREVfU05BUFNIT1RfVFlQRS4ifSwKLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgWFBhdGhFdmFsdWF0b3IgaXMgYSBKYXZhIGludGVyZmFjZSBuYW1lLiAgQW4KLSAgLy8gWFBhdGhFdmFsdWF0b3IgaXMgY3JlYXRlZCB3aXRoIHJlc3BlY3QgdG8gYSBwYXJ0aWN1bGFyIFhNTCBkb2N1bWVudCwgYW5kIGluCi0gIC8vIHRoaXMgY2FzZSB0aGUgZXhwcmVzc2lvbiByZXByZXNlbnRlZCBieSB0aGlzIG9iamVjdCB3YXMgYmVpbmcgZXZhbHVhdGVkIHdpdGgKLSAgLy8gcmVzcGVjdCB0byBhIGNvbnRleHQgbm9kZSBmcm9tIGEgZGlmZmVyZW50IGRvY3VtZW50LgotICB7IEVSX1dST05HX0RPQ1VNRU5ULAotICAgICAgICJFbCBub2RvIGRlIGNvbnRleHRvIG5vIHBlcnRlbmVjZSBhbCBkb2N1bWVudG8gcXVlIGVzdFx1MDBFMSBlbmxhemFkbyBhIGVzdGUgWFBhdGhFdmFsdWF0b3IuIn0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBYUGF0aCBleHByZXNzaW9uIGNhbm5vdCBiZSBldmFsdWF0ZWQgd2l0aCByZXNwZWN0Ci0gIC8vIHRvIHRoaXMgdHlwZSBvZiBub2RlLgotICB7IEVSX1dST05HX05PREVUWVBFLAotICAgICAgICJFbCB0aXBvIGRlIG5vZG8gZGUgY29udGV4dG8gbm8gZXN0XHUwMEUxIHNvcG9ydGFkby4ifSwKLQotICB7IEVSX1hQQVRIX0VSUk9SLAotICAgICAgICJFcnJvciBkZXNjb25vY2lkbyBlbiBYUGF0aC4ifSwKLQotICB7IEVSX0NBTlRfQ09OVkVSVF9YUEFUSFJFU1VMVFRZUEVfVE9fTlVNQkVSLAotICAgICAgICAiRWwgdmFsb3IgZGUgWFBhdGhSZXN1bHQgZGUgbGEgZXhwcmVzaVx1MDBGM24gWFBhdGggJyd7MH0nJyB0aWVuZSB1biB2YWxvciBkZSBYUGF0aFJlc3VsdFR5cGUgZGUgezF9IHF1ZSBubyBzZSBwdWVkZSBjb252ZXJ0aXIgZW4gdW4gblx1MDBGQW1lcm8ifSwKLQotICAvL0JFR0lOOiAgRGVmaW5pdGlvbnMgb2YgZXJyb3Iga2V5cyB1c2VkICBpbiBleGNlcHRpb24gbWVzc2FnZXMgb2YgIEpBWFAgMS4zIFhQYXRoIEFQSSBpbXBsZW1lbnRhdGlvbgotCi0gIC8qKiBGaWVsZCBFUl9FWFRFTlNJT05fRlVOQ1RJT05fQ0FOTk9UX0JFX0lOVk9LRUQgICAgICAgICAgICAgICAgICAgICAgICovCi0KLSAgeyBFUl9FWFRFTlNJT05fRlVOQ1RJT05fQ0FOTk9UX0JFX0lOVk9LRUQsCi0gICAgICAgIkZ1bmNpXHUwMEYzbiBkZSBleHRlbnNpXHUwMEYzbjogbm8gc2UgcHVlZGUgbGxhbWFyIGEgJyd7MH0nJyBjdWFuZG8gbGEgZnVuY2lcdTAwRjNuIFhNTENvbnN0YW50cy5GRUFUVVJFX1NFQ1VSRV9QUk9DRVNTSU5HIGVzdFx1MDBFMSBkZWZpbmlkYSBlbiB0cnVlLiJ9LAotCi0gIC8qKiBGaWVsZCBFUl9SRVNPTFZFX1ZBUklBQkxFX1JFVFVSTlNfTlVMTCAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX1JFU09MVkVfVkFSSUFCTEVfUkVUVVJOU19OVUxMLAotICAgICAgICJyZXNvbHZlVmFyaWFibGUgcGFyYSBsYSB2YXJpYWJsZSB7MH0gZGV2dWVsdmUgdW4gdmFsb3IgbnVsbyJ9LAotCi0gIC8qKiBGaWVsZCBFUl9VTlNVUFBPUlRFRF9SRVRVUk5fVFlQRSAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX1VOU1VQUE9SVEVEX1JFVFVSTl9UWVBFLAotICAgICAgICJUaXBvIGRlIHJldG9ybm8gbm8gc29wb3J0YWRvOiB7MH0ifSwKLQotICAvKiogRmllbGQgRVJfU09VUkNFX1JFVFVSTl9UWVBFX0NBTk5PVF9CRV9OVUxMICAgICAgICAgICAgICAgICAgICAgICAqLwotCi0gIHsgRVJfU09VUkNFX1JFVFVSTl9UWVBFX0NBTk5PVF9CRV9OVUxMLAotICAgICAgICJFbCB0aXBvIGRlIG9yaWdlbiB5L28gcmV0b3JubyBubyBwdWVkZSBzZXIgbnVsbyJ9LAotCi0gIC8qKiBGaWVsZCBFUl9TT1VSQ0VfUkVUVVJOX1RZUEVfQ0FOTk9UX0JFX05VTEwgICAgICAgICAgICAgICAgICAgICAgICovCi0KLSAgeyBFUl9TT1VSQ0VfUkVUVVJOX1RZUEVfQ0FOTk9UX0JFX05VTEwsCi0gICAgICAgIkVsIHRpcG8gZGUgb3JpZ2VuIHkvbyByZXRvcm5vIG5vIHB1ZWRlIHNlciBudWxvIn0sCi0KLSAgLyoqIEZpZWxkIEVSX0FSR19DQU5OT1RfQkVfTlVMTCAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX0FSR19DQU5OT1RfQkVfTlVMTCwKLSAgICAgICAiRWwgYXJndW1lbnRvIHswfSBubyBwdWVkZSBzZXIgbnVsbyJ9LAotCi0gIC8qKiBGaWVsZCBFUl9PQkpFQ1RfTU9ERUxfTlVMTCAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX09CSkVDVF9NT0RFTF9OVUxMLAotICAgICAgICJ7MH0jaXNPYmplY3RNb2RlbFN1cHBvcnRlZCggQ2FkZW5hIG9iamVjdE1vZGVsICkgbm8gc2UgcHVlZGUgbGxhbWFyIGNvbiBvYmplY3RNb2RlbCA9PSBudWxsIn0sCi0KLSAgLyoqIEZpZWxkIEVSX09CSkVDVF9NT0RFTF9FTVBUWSAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX09CSkVDVF9NT0RFTF9FTVBUWSwKLSAgICAgICAiezB9I2lzT2JqZWN0TW9kZWxTdXBwb3J0ZWQoIENhZGVuYSBvYmplY3RNb2RlbCApIG5vIHNlIHB1ZWRlIGxsYW1hciBjb24gb2JqZWN0TW9kZWwgPT0gXCJcIiJ9LAotCi0gIC8qKiBGaWVsZCBFUl9PQkpFQ1RfTU9ERUxfRU1QVFkgICAgICAgICAgICAgICAgICAgICAgICovCi0KLSAgeyBFUl9GRUFUVVJFX05BTUVfTlVMTCwKLSAgICAgICAiSW50ZW50YW5kbyBkZWZpbmlyIHVuYSBmdW5jaVx1MDBGM24gY29uIHVuIG5vbWJyZSBudWxvOiB7MH0jc2V0RmVhdHVyZSggbnVsbCwgezF9KSJ9LAotCi0gIC8qKiBGaWVsZCBFUl9GRUFUVVJFX1VOS05PV04gICAgICAgICAgICAgICAgICAgICAgICovCi0KLSAgeyBFUl9GRUFUVVJFX1VOS05PV04sCi0gICAgICAgIkludGVudGFuZG8gZGVmaW5pciBsYSBmdW5jaVx1MDBGM24gZGVzY29ub2NpZGEgXCJ7MH1cIjp7MX0jc2V0RmVhdHVyZSh7MH0sezJ9KSJ9LAotCi0gIC8qKiBGaWVsZCBFUl9HRVRUSU5HX05VTExfRkVBVFVSRSAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX0dFVFRJTkdfTlVMTF9GRUFUVVJFLAotICAgICAgICJJbnRlbnRhbmRvIG9idGVuZXIgdW5hIGZ1bmNpXHUwMEYzbiBjb24gdW4gbm9tYnJlIG51bG86IHswfSNnZXRGZWF0dXJlKG51bGwpIn0sCi0KLSAgLyoqIEZpZWxkIEVSX0dFVFRJTkdfTlVMTF9GRUFUVVJFICAgICAgICAgICAgICAgICAgICAgICAqLwotCi0gIHsgRVJfR0VUVElOR19VTktOT1dOX0ZFQVRVUkUsCi0gICAgICAgIkludGVudGFuZG8gb2J0ZW5lciBsYSBmdW5jaVx1MDBGM24gZGVzY29ub2NpZGEgXCJ7MH1cIjp7MX0jZ2V0RmVhdHVyZSh7MH0pIn0sCi0KLSAge0VSX1NFQ1VSRVBST0NFU1NJTkdfRkVBVFVSRSwKLSAgICAgICAgIkZFQVRVUkVfU0VDVVJFX1BST0NFU1NJTkc6IG5vIHNlIHB1ZWRlIGRlZmluaXIgbGEgZnVuY2lcdTAwRjNuIGVuIGZhbHNlIGN1YW5kbyBlc3RcdTAwRTEgcHJlc2VudGUgZWwgZ2VzdG9yIGRlIHNlZ3VyaWRhZDogezF9I3NldEZlYXR1cmUoezB9LHsyfSkifSwKLQotICAvKiogRmllbGQgRVJfTlVMTF9YUEFUSF9GVU5DVElPTl9SRVNPTFZFUiAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX05VTExfWFBBVEhfRlVOQ1RJT05fUkVTT0xWRVIsCi0gICAgICAgIlNlIGVzdFx1MDBFMSBpbnRlbnRhbmRvIGRlZmluaXIgdW4gdmFsb3IgZGUgWFBhdGhGdW5jdGlvblJlc29sdmVyIG51bG86ezB9I3NldFhQYXRoRnVuY3Rpb25SZXNvbHZlcihudWxsKSJ9LAotCi0gIC8qKiBGaWVsZCBFUl9OVUxMX1hQQVRIX1ZBUklBQkxFX1JFU09MVkVSICAgICAgICAgICAgICAgICAgICAgICAqLwotCi0gIHsgRVJfTlVMTF9YUEFUSF9WQVJJQUJMRV9SRVNPTFZFUiwKLSAgICAgICAiU2UgZXN0XHUwMEUxIGludGVudGFuZG8gZGVmaW5pciB1biB2YWxvciBYUGF0aFZhcmlhYmxlUmVzb2x2ZXIgbnVsbzp7MH0jc2V0WFBhdGhWYXJpYWJsZVJlc29sdmVyKG51bGwpIn0sCi0KLSAgLy9FTkQ6ICBEZWZpbml0aW9ucyBvZiBlcnJvciBrZXlzIHVzZWQgIGluIGV4Y2VwdGlvbiBtZXNzYWdlcyBvZiAgSkFYUCAxLjMgWFBhdGggQVBJIGltcGxlbWVudGF0aW9uCi0KLSAgLy8gV2FybmluZ3MuLi4KLQotICB7IFdHX0xPQ0FMRV9OQU1FX05PVF9IQU5ETEVELAotICAgICAgIkVsIG5vbWJyZSBkZSBsYSBjb25maWd1cmFjaVx1MDBGM24gcmVnaW9uYWwgZW4gbGEgZnVuY2lcdTAwRjNuIGZvcm1hdC1udW1iZXIgbm8gc2UgaGEgbWFuZWphZG8gYVx1MDBGQW4uIn0sCi0KLSAgeyBXR19QUk9QRVJUWV9OT1RfU1VQUE9SVEVELAotICAgICAgIlByb3BpZWRhZCBYU0wgbm8gc29wb3J0YWRhOiB7MH0ifSwKLQotICB7IFdHX0RPTlRfRE9fQU5ZVEhJTkdfV0lUSF9OUywKLSAgICAgICJObyByZWFsaWNlIG5pbmd1bmEgYWNjaVx1MDBGM24gY29uIGVsIGVzcGFjaW8gZGUgbm9tYnJlcyB7MH0gZW4gbGEgcHJvcGllZGFkOiB7MX0ifSwKLQotICB7IFdHX1NFQ1VSSVRZX0VYQ0VQVElPTiwKLSAgICAgICJFeGNlcGNpXHUwMEYzbiBkZSBzZWd1cmlkYWQgYWwgaW50ZW50YXIgYWNjZWRlciBhIGxhIHByb3BpZWRhZCBkZWwgc2lzdGVtYSBYU0w6IHswfSJ9LAotCi0gIHsgV0dfUVVPX05PX0xPTkdFUl9ERUZJTkVELAotICAgICAgIlNpbnRheGlzIGFudGVyaW9yOiBxdW8oLi4uKSB5YSBubyBzZSBkZWZpbmUgZW4gWFBhdGguIn0sCi0KLSAgeyBXR19ORUVEX0RFUklWRURfT0JKRUNUX1RPX0lNUExFTUVOVF9OT0RFVEVTVCwKLSAgICAgICJYUGF0aCBuZWNlc2l0YSB1biBvYmpldG8gZGVyaXZhZG8gcGFyYSBpbXBsYW50YXIgdW5hIHBydWViYSBkZSBub2RvLiJ9LAotCi0gIHsgV0dfRlVOQ1RJT05fVE9LRU5fTk9UX0ZPVU5ELAotICAgICAgIk5vIHNlIGhhIGVuY29udHJhZG8gZWwgdG9rZW4gZGUgZnVuY2lcdTAwRjNuLiJ9LAotCi0gIHsgV0dfQ09VTEROT1RfRklORF9GVU5DVElPTiwKLSAgICAgICJObyBzZSBoYSBlbmNvbnRyYWRvIGxhIGZ1bmNpXHUwMEYzbjogezB9In0sCi0KLSAgeyBXR19DQU5OT1RfTUFLRV9VUkxfRlJPTSwKLSAgICAgICJObyBzZSBwdWVkZSBjcmVhciBsYSBVUkwgZGVzZGU6IHswfSJ9LAotCi0gIHsgV0dfRVhQQU5EX0VOVElUSUVTX05PVF9TVVBQT1JURUQsCi0gICAgICAiT3BjaVx1MDBGM24gLUUgbm8gc29wb3J0YWRhIHBhcmEgZWwgYW5hbGl6YWRvciBEVE0ifSwKLQotICB7IFdHX0lMTEVHQUxfVkFSSUFCTEVfUkVGRVJFTkNFLAotICAgICAgIkxhIHJlZmVyZW5jaWEgZGUgdmFyaWFibGUgcHJvcG9yY2lvbmFkYSBwYXJhIGxhIHZhcmlhYmxlIGVzdFx1MDBFMSBmdWVyYSBkZSBjb250ZXh0byBvIG5vIHRpZW5lIGRlZmluaWNpXHUwMEYzbi4gTm9tYnJlID0gezB9In0sCi0KLSAgeyBXR19VTlNVUFBPUlRFRF9FTkNPRElORywKLSAgICAgIkNvZGlmaWNhY2lcdTAwRjNuIG5vIHNvcG9ydGFkYTogezB9In0sCi0KLQotCi0gIC8vIE90aGVyIG1pc2NlbGxhbmVvdXMgdGV4dCB1c2VkIGluc2lkZSB0aGUgY29kZS4uLgotICB7ICJ1aV9sYW5ndWFnZSIsICJlcyJ9LAotICB7ICJoZWxwX2xhbmd1YWdlIiwgImVzIn0sCi0gIHsgImxhbmd1YWdlIiwgImVzIn0sCi0gIHsgIkJBRF9DT0RFIiwgIkVsIHBhclx1MDBFMW1ldHJvIHBhcmEgY3JlYXIgdW4gbWVuc2FqZSBlc3RcdTAwRTEgZnVlcmEgZGUgbG9zIGxcdTAwRURtaXRlcyJ9LAotICB7ICJGT1JNQVRfRkFJTEVEIiwgIlNlIGhhIGVtaXRpZG8gdW5hIGV4Y2VwY2lcdTAwRjNuIGR1cmFudGUgbGEgbGxhbWFkYSBhIG1lc3NhZ2VGb3JtYXQifSwKLSAgeyAidmVyc2lvbiIsICI+Pj4+Pj4+IFZlcnNpXHUwMEYzbiBYYWxhbiAifSwKLSAgeyAidmVyc2lvbjIiLCAiPDw8PDw8PCJ9LAotICB7ICJ5ZXMiLCAic1x1MDBFRCJ9LAotICB7ICJsaW5lIiwgIk5cdTAwQkEgZGUgTFx1MDBFRG5lYSJ9LAotICB7ICJjb2x1bW4iLCAiTlx1MDBCQSBkZSBDb2x1bW5hIn0sCi0gIHsgInhzbGRvbmUiLCAiWFNMUHJvY2Vzc29yOiBsaXN0byJ9LAotICB7ICJ4cGF0aF9vcHRpb24iLCAiT3BjaW9uZXMgZGUgeHBhdGg6ICJ9LAotICB7ICJvcHRpb25JTiIsICIgICBbLWluIGlucHV0WE1MVVJMXSJ9LAotICB7ICJvcHRpb25TZWxlY3QiLCAiICAgWy1zZWxlY3QgZXhwcmVzaVx1MDBGM24geHBhdGhdIn0sCi0gIHsgIm9wdGlvbk1hdGNoIiwgIiAgIFstbWF0Y2ggcGF0clx1MDBGM24gZGUgY29pbmNpZGVuY2lhIChwYXJhIGRpYWduXHUwMEYzc3RpY29zIGRlIGNvaW5jaWRlbmNpYSldIn0sCi0gIHsgIm9wdGlvbkFueUV4cHIiLCAiTyBzXHUwMEYzbG8gdW5hIGV4cHJlc2lcdTAwRjNuIHhwYXRoIHJlYWxpemFyXHUwMEUxIHVuIHZvbGNhZG8gZGUgZGlhZ25cdTAwRjNzdGljbyJ9LAotICB7ICJub1BhcnNlcm1zZzEiLCAiRWwgcHJvY2VzbyBYU0wgbm8gc2UgaGEgcmVhbGl6YWRvIGNvcnJlY3RhbWVudGUuIn0sCi0gIHsgIm5vUGFyc2VybXNnMiIsICIqKiBObyBzZSBoYSBlbmNvbnRyYWRvIGVsIGFuYWxpemFkb3IgKioifSwKLSAgeyAibm9QYXJzZXJtc2czIiwgIkNvbXBydWViZSBsYSBjbGFzc3BhdGguIn0sCi0gIHsgIm5vUGFyc2VybXNnNCIsICJTaSBubyB0aWVuZSB1biBhbmFsaXphZG9yIFhNTCBkZSBJQk0gcGFyYSBKYXZhLCBwdWVkZSBkZXNjYXJnYXJsbyBkZSJ9LAotICB7ICJub1BhcnNlcm1zZzUiLCAiQWxwaGFXb3JrcyBkZSBJQk06IGh0dHA6Ly93d3cuYWxwaGF3b3Jrcy5pYm0uY29tL2Zvcm11bGEveG1sIn0sCi0gIHsgImd0b25lIiwgIj4xIiB9LAotICB7ICJ6ZXJvIiwgIjAiIH0sCi0gIHsgIm9uZSIsICIxIiB9LAotICB7ICJ0d28iICwgIjIiIH0sCi0gIHsgInRocmVlIiwgIjMiIH0KLQotICB9OwotCi0gIC8qKgotICAgKiBHZXQgdGhlIGFzc29jaWF0aW9uIGxpc3QuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGFzc29jaWF0aW9uIGxpc3QuCi0gICAqLwotICBwdWJsaWMgT2JqZWN0W11bXSBnZXRDb250ZW50cygpCi0gIHsKLSAgICAgIHJldHVybiBfY29udGVudHM7Ci0gIH0KLQotCi0gIC8vID09PT09PT09PT09PT09PT09IElORlJBU1RSVUNUVVJFID09PT09PT09PT09PT09PT09PT09PT0KLQotICAvKiogRmllbGQgQkFEX0NPREUgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQkFEX0NPREUgPSAiQkFEX0NPREUiOwotCi0gIC8qKiBGaWVsZCBGT1JNQVRfRkFJTEVEICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEZPUk1BVF9GQUlMRUQgPSAiRk9STUFUX0ZBSUxFRCI7Ci0KLSAgLyoqIEZpZWxkIEVSUk9SX1JFU09VUkNFUyAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJPUl9SRVNPVVJDRVMgPQotICAgICJjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucmVzLlhQQVRIRXJyb3JSZXNvdXJjZXMiOwotCi0gIC8qKiBGaWVsZCBFUlJPUl9TVFJJTkcgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJST1JfU1RSSU5HID0gIiNlcnJvciI7Ci0KLSAgLyoqIEZpZWxkIEVSUk9SX0hFQURFUiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJPUl9IRUFERVIgPSAiRXJyb3I6ICI7Ci0KLSAgLyoqIEZpZWxkIFdBUk5JTkdfSEVBREVSICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdBUk5JTkdfSEVBREVSID0gIldhcm5pbmc6ICI7Ci0KLSAgLyoqIEZpZWxkIFhTTF9IRUFERVIgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgWFNMX0hFQURFUiA9ICJYU0wgIjsKLQotICAvKiogRmllbGQgWE1MX0hFQURFUiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxfSEVBREVSID0gIlhNTCAiOwotCi0gIC8qKiBGaWVsZCBRVUVSWV9IRUFERVIgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgUVVFUllfSEVBREVSID0gIlBBVFRFUk4gIjsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9yZXMvWFBBVEhFcnJvclJlc291cmNlc19mci5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9yZXMvWFBBVEhFcnJvclJlc291cmNlc19mci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxZWI4MzE4Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvcmVzL1hQQVRIRXJyb3JSZXNvdXJjZXNfZnIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDkzNiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5yZXM7Ci0KLWltcG9ydCBqYXZhLnV0aWwuTGlzdFJlc291cmNlQnVuZGxlOwotCi0vKioKLSAqIFNldCB1cCBlcnJvciBtZXNzYWdlcy4KLSAqIFdlIGJ1aWxkIGEgdHdvIGRpbWVuc2lvbmFsIGFycmF5IG9mIG1lc3NhZ2Uga2V5cyBhbmQKLSAqIG1lc3NhZ2Ugc3RyaW5ncy4gSW4gb3JkZXIgdG8gYWRkIGEgbmV3IG1lc3NhZ2UgaGVyZSwKLSAqIHlvdSBuZWVkIHRvIGZpcnN0IGFkZCBhIFN0YXRpYyBzdHJpbmcgY29uc3RhbnQgZm9yIHRoZQotICogS2V5IGFuZCB1cGRhdGUgdGhlIGNvbnRlbnRzIGFycmF5IHdpdGggS2V5LCBWYWx1ZSBwYWlyCi0gICogQWxzbyB5b3UgbmVlZCB0byAgdXBkYXRlIHRoZSBjb3VudCBvZiBtZXNzYWdlcyhNQVhfQ09ERSlvcgotICogdGhlIGNvdW50IG9mIHdhcm5pbmdzKE1BWF9XQVJOSU5HKSBbIEluZm9ybWF0aW9uIHB1cnBvc2Ugb25seV0KLSAqIEB4c2wudXNhZ2UgYWR2YW5jZWQKLSAqLwotcHVibGljIGNsYXNzIFhQQVRIRXJyb3JSZXNvdXJjZXNfZnIgZXh0ZW5kcyBMaXN0UmVzb3VyY2VCdW5kbGUKLXsKLQotLyoKLSAqIEdlbmVyYWwgbm90ZXMgdG8gdHJhbnNsYXRvcnM6Ci0gKgotICogVGhpcyBmaWxlIGNvbnRhaW5zIGVycm9yIGFuZCB3YXJuaW5nIG1lc3NhZ2VzIHJlbGF0ZWQgdG8gWFBhdGggRXJyb3IKLSAqIEhhbmRsaW5nLgotICoKLSAqICAxKSBYYWxhbiAob3IgbW9yZSBwcm9wZXJseSwgWGFsYW4taW50ZXJwcmV0aXZlKSBhbmQgWFNMVEMgYXJlIG5hbWVzIG9mCi0gKiAgICAgY29tcG9uZW50cy4KLSAqICAgICBYU0xUIGlzIGFuIGFjcm9ueW0gZm9yICJYTUwgU3R5bGVzaGVldCBMYW5ndWFnZTogVHJhbnNmb3JtYXRpb25zIi4KLSAqICAgICBYU0xUQyBpcyBhbiBhY3JvbnltIGZvciBYU0xUIENvbXBpbGVyLgotICoKLSAqICAyKSBBIHN0eWxlc2hlZXQgaXMgYSBkZXNjcmlwdGlvbiBvZiBob3cgdG8gdHJhbnNmb3JtIGFuIGlucHV0IFhNTCBkb2N1bWVudAotICogICAgIGludG8gYSByZXN1bHRhbnQgWE1MIGRvY3VtZW50IChvciBIVE1MIGRvY3VtZW50IG9yIHRleHQpLiAgVGhlCi0gKiAgICAgc3R5bGVzaGVldCBpdHNlbGYgaXMgZGVzY3JpYmVkIGluIHRoZSBmb3JtIG9mIGFuIFhNTCBkb2N1bWVudC4KLSAqCi0gKiAgMykgQSB0ZW1wbGF0ZSBpcyBhIGNvbXBvbmVudCBvZiBhIHN0eWxlc2hlZXQgdGhhdCBpcyB1c2VkIHRvIG1hdGNoIGEKLSAqICAgICBwYXJ0aWN1bGFyIHBvcnRpb24gb2YgYW4gaW5wdXQgZG9jdW1lbnQgYW5kIHNwZWNpZmllcyB0aGUgZm9ybSBvZiB0aGUKLSAqICAgICBjb3JyZXNwb25kaW5nIHBvcnRpb24gb2YgdGhlIG91dHB1dCBkb2N1bWVudC4KLSAqCi0gKiAgNCkgQW4gZWxlbWVudCBpcyBhIG1hcmstdXAgdGFnIGluIGFuIFhNTCBkb2N1bWVudDsgYW4gYXR0cmlidXRlIGlzIGEKLSAqICAgICBtb2RpZmllciBvbiB0aGUgdGFnLiAgRm9yIGV4YW1wbGUsIGluIDxlbGVtIGF0dHI9J3ZhbCcgYXR0cjI9J3ZhbDInPgotICogICAgICJlbGVtIiBpcyBhbiBlbGVtZW50IG5hbWUsICJhdHRyIiBhbmQgImF0dHIyIiBhcmUgYXR0cmlidXRlIG5hbWVzIHdpdGgKLSAqICAgICB0aGUgdmFsdWVzICJ2YWwiIGFuZCAidmFsMiIsIHJlc3BlY3RpdmVseS4KLSAqCi0gKiAgNSkgQSBuYW1lc3BhY2UgZGVjbGFyYXRpb24gaXMgYSBzcGVjaWFsIGF0dHJpYnV0ZSB0aGF0IGlzIHVzZWQgdG8gYXNzb2NpYXRlCi0gKiAgICAgYSBwcmVmaXggd2l0aCBhIFVSSSAodGhlIG5hbWVzcGFjZSkuICBUaGUgbWVhbmluZ3Mgb2YgZWxlbWVudCBuYW1lcyBhbmQKLSAqICAgICBhdHRyaWJ1dGUgbmFtZXMgdGhhdCB1c2UgdGhhdCBwcmVmaXggYXJlIGRlZmluZWQgd2l0aCByZXNwZWN0IHRvIHRoYXQKLSAqICAgICBuYW1lc3BhY2UuCi0gKgotICogIDYpICJUcmFuc2xldCIgaXMgYW4gaW52ZW50ZWQgdGVybSB0aGF0IGRlc2NyaWJlcyB0aGUgY2xhc3MgZmlsZSB0aGF0Ci0gKiAgICAgcmVzdWx0cyBmcm9tIGNvbXBpbGluZyBhbiBYTUwgc3R5bGVzaGVldCBpbnRvIGEgSmF2YSBjbGFzcy4KLSAqCi0gKiAgNykgWFBhdGggaXMgYSBzcGVjaWZpY2F0aW9uIHRoYXQgZGVzY3JpYmVzIGEgbm90YXRpb24gZm9yIGlkZW50aWZ5aW5nCi0gKiAgICAgbm9kZXMgaW4gYSB0cmVlLXN0cnVjdHVyZWQgcmVwcmVzZW50YXRpb24gb2YgYW4gWE1MIGRvY3VtZW50LiAgQW4KLSAqICAgICBpbnN0YW5jZSBvZiB0aGF0IG5vdGF0aW9uIGlzIHJlZmVycmVkIHRvIGFzIGFuIFhQYXRoIGV4cHJlc3Npb24uCi0gKgotICogIDgpIFRoZSBjb250ZXh0IG5vZGUgaXMgdGhlIG5vZGUgaW4gdGhlIGRvY3VtZW50IHdpdGggcmVzcGVjdCB0byB3aGljaCBhbgotICogICAgIFhQYXRoIGV4cHJlc3Npb24gaXMgYmVpbmcgZXZhbHVhdGVkLgotICoKLSAqICA5KSBBbiBpdGVyYXRvciBpcyBhbiBvYmplY3QgdGhhdCB0cmF2ZXJzZXMgbm9kZXMgaW4gdGhlIHRyZWUsIG9uZSBhdCBhIHRpbWUuCi0gKgotICogIDEwKSBOQ05hbWUgaXMgYW4gWE1MIHRlcm0gdXNlZCB0byBkZXNjcmliZSBhIG5hbWUgdGhhdCBkb2VzIG5vdCBjb250YWluIGEKLSAqICAgICBjb2xvbiAoYSAibm8tY29sb24gbmFtZSIpLgotICoKLSAqICAxMSkgUU5hbWUgaXMgYW4gWE1MIHRlcm0gbWVhbmluZyAicXVhbGlmaWVkIG5hbWUiLgotICovCi0KLSAgLyoKLSAgICogc3RhdGljIHZhcmlhYmxlcwotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJST1IwMDAwID0gIkVSUk9SMDAwMCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NVUlJFTlRfTk9UX0FMTE9XRURfSU5fTUFUQ0ggPQotICAgICAgICAgIkVSX0NVUlJFTlRfTk9UX0FMTE9XRURfSU5fTUFUQ0giOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DVVJSRU5UX1RBS0VTX05PX0FSR1MgPQotICAgICAgICAgIkVSX0NVUlJFTlRfVEFLRVNfTk9fQVJHUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0RPQ1VNRU5UX1JFUExBQ0VEID0gIkVSX0RPQ1VNRU5UX1JFUExBQ0VEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09OVEVYVF9IQVNfTk9fT1dORVJET0MgPQotICAgICAgICAgIkVSX0NPTlRFWFRfSEFTX05PX09XTkVSRE9DIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTE9DQUxOQU1FX0hBU19UT09fTUFOWV9BUkdTID0KLSAgICAgICAgICJFUl9MT0NBTE5BTUVfSEFTX1RPT19NQU5ZX0FSR1MiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OQU1FU1BBQ0VVUklfSEFTX1RPT19NQU5ZX0FSR1MgPQotICAgICAgICAgIkVSX05BTUVTUEFDRVVSSV9IQVNfVE9PX01BTllfQVJHUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PUk1BTElaRVNQQUNFX0hBU19UT09fTUFOWV9BUkdTID0KLSAgICAgICAgICJFUl9OT1JNQUxJWkVTUEFDRV9IQVNfVE9PX01BTllfQVJHUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05VTUJFUl9IQVNfVE9PX01BTllfQVJHUyA9Ci0gICAgICAgICAiRVJfTlVNQkVSX0hBU19UT09fTUFOWV9BUkdTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTkFNRV9IQVNfVE9PX01BTllfQVJHUyA9Ci0gICAgICAgICAiRVJfTkFNRV9IQVNfVE9PX01BTllfQVJHUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NUUklOR19IQVNfVE9PX01BTllfQVJHUyA9Ci0gICAgICAgICAiRVJfU1RSSU5HX0hBU19UT09fTUFOWV9BUkdTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU1RSSU5HTEVOR1RIX0hBU19UT09fTUFOWV9BUkdTID0KLSAgICAgICAgICJFUl9TVFJJTkdMRU5HVEhfSEFTX1RPT19NQU5ZX0FSR1MiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9UUkFOU0xBVEVfVEFLRVNfM19BUkdTID0KLSAgICAgICAgICJFUl9UUkFOU0xBVEVfVEFLRVNfM19BUkdTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5QQVJTRURFTlRJVFlVUklfVEFLRVNfMV9BUkcgPQotICAgICAgICAgIkVSX1VOUEFSU0VERU5USVRZVVJJX1RBS0VTXzFfQVJHIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTkFNRVNQQUNFQVhJU19OT1RfSU1QTEVNRU5URUQgPQotICAgICAgICAgIkVSX05BTUVTUEFDRUFYSVNfTk9UX0lNUExFTUVOVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5LTk9XTl9BWElTID0gIkVSX1VOS05PV05fQVhJUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1VOS05PV05fTUFUQ0hfT1BFUkFUSU9OID0KLSAgICAgICAgICJFUl9VTktOT1dOX01BVENIX09QRVJBVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOQ09SUkVDVF9BUkdfTEVOR1RIID0iRVJfSU5DT1JSRUNUX0FSR19MRU5HVEgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX0NPTlZFUlRfVE9fTlVNQkVSID0KLSAgICAgICAgICJFUl9DQU5UX0NPTlZFUlRfVE9fTlVNQkVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9DT05WRVJUX1hQQVRIUkVTVUxUVFlQRV9UT19OVU1CRVIgPQotICAgICAgICAgICAiRVJfQ0FOVF9DT05WRVJUX1hQQVRIUkVTVUxUVFlQRV9UT19OVU1CRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX0NPTlZFUlRfVE9fTk9ERUxJU1QgPQotICAgICAgICAgIkVSX0NBTlRfQ09OVkVSVF9UT19OT0RFTElTVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfQ09OVkVSVF9UT19NVVRBQkxFTk9ERUxJU1QgPQotICAgICAgICAgIkVSX0NBTlRfQ09OVkVSVF9UT19NVVRBQkxFTk9ERUxJU1QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX0NPTlZFUlRfVE9fVFlQRSA9IkVSX0NBTlRfQ09OVkVSVF9UT19UWVBFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhQRUNURURfTUFUQ0hfUEFUVEVSTiA9Ci0gICAgICAgICAiRVJfRVhQRUNURURfTUFUQ0hfUEFUVEVSTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxETk9UX0dFVF9WQVJfTkFNRUQgPQotICAgICAgICAgIkVSX0NPVUxETk9UX0dFVF9WQVJfTkFNRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTktOT1dOX09QQ09ERSA9ICJFUl9VTktOT1dOX09QQ09ERSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYVFJBX0lMTEVHQUxfVE9LRU5TID0iRVJfRVhUUkFfSUxMRUdBTF9UT0tFTlMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FWFBFQ1RFRF9ET1VCTEVfUVVPVEUgPQotICAgICAgICAgIkVSX0VYUEVDVEVEX0RPVUJMRV9RVU9URSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYUEVDVEVEX1NJTkdMRV9RVU9URSA9Ci0gICAgICAgICAiRVJfRVhQRUNURURfU0lOR0xFX1FVT1RFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRU1QVFlfRVhQUkVTU0lPTiA9ICJFUl9FTVBUWV9FWFBSRVNTSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhQRUNURURfQlVUX0ZPVU5EID0gIkVSX0VYUEVDVEVEX0JVVF9GT1VORCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOQ09SUkVDVF9QUk9HUkFNTUVSX0FTU0VSVElPTiA9Ci0gICAgICAgICAiRVJfSU5DT1JSRUNUX1BST0dSQU1NRVJfQVNTRVJUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQk9PTEVBTl9BUkdfTk9fTE9OR0VSX09QVElPTkFMID0KLSAgICAgICAgICJFUl9CT09MRUFOX0FSR19OT19MT05HRVJfT1BUSU9OQUwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GT1VORF9DT01NQV9CVVRfTk9fUFJFQ0VESU5HX0FSRyA9Ci0gICAgICAgICAiRVJfRk9VTkRfQ09NTUFfQlVUX05PX1BSRUNFRElOR19BUkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GT1VORF9DT01NQV9CVVRfTk9fRk9MTE9XSU5HX0FSRyA9Ci0gICAgICAgICAiRVJfRk9VTkRfQ09NTUFfQlVUX05PX0ZPTExPV0lOR19BUkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUkVESUNBVEVfSUxMRUdBTF9TWU5UQVggPQotICAgICAgICAgIkVSX1BSRURJQ0FURV9JTExFR0FMX1NZTlRBWCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lMTEVHQUxfQVhJU19OQU1FID0gIkVSX0lMTEVHQUxfQVhJU19OQU1FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5LTk9XTl9OT0RFVFlQRSA9ICJFUl9VTktOT1dOX05PREVUWVBFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUEFUVEVSTl9MSVRFUkFMX05FRURTX0JFX1FVT1RFRCA9Ci0gICAgICAgICAiRVJfUEFUVEVSTl9MSVRFUkFMX05FRURTX0JFX1FVT1RFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxETk9UX0JFX0ZPUk1BVFRFRF9UT19OVU1CRVIgPQotICAgICAgICAgIkVSX0NPVUxETk9UX0JFX0ZPUk1BVFRFRF9UT19OVU1CRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRE5PVF9DUkVBVEVfWE1MUFJPQ0VTU09STElBSVNPTiA9Ci0gICAgICAgICAiRVJfQ09VTEROT1RfQ1JFQVRFX1hNTFBST0NFU1NPUkxJQUlTT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9ESUROT1RfRklORF9YUEFUSF9TRUxFQ1RfRVhQID0KLSAgICAgICAgICJFUl9ESUROT1RfRklORF9YUEFUSF9TRUxFQ1RfRVhQIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTEROT1RfRklORF9FTkRPUF9BRlRFUl9PUExPQ0FUSU9OUEFUSCA9Ci0gICAgICAgICAiRVJfQ09VTEROT1RfRklORF9FTkRPUF9BRlRFUl9PUExPQ0FUSU9OUEFUSCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VSUk9SX09DQ1VSRUQgPSAiRVJfRVJST1JfT0NDVVJFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lMTEVHQUxfVkFSSUFCTEVfUkVGRVJFTkNFID0KLSAgICAgICAgICJFUl9JTExFR0FMX1ZBUklBQkxFX1JFRkVSRU5DRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FYRVNfTk9UX0FMTE9XRUQgPSAiRVJfQVhFU19OT1RfQUxMT1dFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0tFWV9IQVNfVE9PX01BTllfQVJHUyA9Ci0gICAgICAgICAiRVJfS0VZX0hBU19UT09fTUFOWV9BUkdTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTlRfVEFLRVNfMV9BUkcgPSAiRVJfQ09VTlRfVEFLRVNfMV9BUkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRE5PVF9GSU5EX0ZVTkNUSU9OID0KLSAgICAgICAgICJFUl9DT1VMRE5PVF9GSU5EX0ZVTkNUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5TVVBQT1JURURfRU5DT0RJTkcgPSJFUl9VTlNVUFBPUlRFRF9FTkNPRElORyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BST0JMRU1fSU5fRFRNX05FWFRTSUJMSU5HID0KLSAgICAgICAgICJFUl9QUk9CTEVNX0lOX0RUTV9ORVhUU0lCTElORyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9XUklURV9UT19FTVBUWU5PREVMSVNUSU1QTCA9Ci0gICAgICAgICAiRVJfQ0FOTk9UX1dSSVRFX1RPX0VNUFRZTk9ERUxJU1RJTVBMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU0VURE9NRkFDVE9SWV9OT1RfU1VQUE9SVEVEID0KLSAgICAgICAgICJFUl9TRVRET01GQUNUT1JZX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUkVGSVhfTVVTVF9SRVNPTFZFID0gIkVSX1BSRUZJWF9NVVNUX1JFU09MVkUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QQVJTRV9OT1RfU1VQUE9SVEVEID0gIkVSX1BBUlNFX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TQVhfQVBJX05PVF9IQU5ETEVEID0gIkVSX1NBWF9BUElfTk9UX0hBTkRMRUQiOwotcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSUdOT1JBQkxFX1dISVRFU1BBQ0VfTk9UX0hBTkRMRUQgPQotICAgICAgICAgIkVSX0lHTk9SQUJMRV9XSElURVNQQUNFX05PVF9IQU5ETEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRFRNX0NBTk5PVF9IQU5ETEVfTk9ERVMgPQotICAgICAgICAgIkVSX0RUTV9DQU5OT1RfSEFORExFX05PREVTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWEVSQ0VTX0NBTk5PVF9IQU5ETEVfTk9ERVMgPQotICAgICAgICAgIkVSX1hFUkNFU19DQU5OT1RfSEFORExFX05PREVTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWEVSQ0VTX1BBUlNFX0VSUk9SX0RFVEFJTFMgPQotICAgICAgICAgIkVSX1hFUkNFU19QQVJTRV9FUlJPUl9ERVRBSUxTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWEVSQ0VTX1BBUlNFX0VSUk9SID0gIkVSX1hFUkNFU19QQVJTRV9FUlJPUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfVVRGMTZfU1VSUk9HQVRFID0KLSAgICAgICAgICJFUl9JTlZBTElEX1VURjE2X1NVUlJPR0FURSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX09JRVJST1IgPSAiRVJfT0lFUlJPUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9DUkVBVEVfVVJMID0gIkVSX0NBTk5PVF9DUkVBVEVfVVJMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWFBBVEhfUkVBRE9CSkVDVCA9ICJFUl9YUEFUSF9SRUFET0JKRUNUIjsKLSBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GVU5DVElPTl9UT0tFTl9OT1RfRk9VTkQgPQotICAgICAgICAgIkVSX0ZVTkNUSU9OX1RPS0VOX05PVF9GT1VORCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9ERUFMX1hQQVRIX1RZUEUgPQotICAgICAgICAgIkVSX0NBTk5PVF9ERUFMX1hQQVRIX1RZUEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT0RFU0VUX05PVF9NVVRBQkxFID0gIkVSX05PREVTRVRfTk9UX01VVEFCTEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT0RFU0VURFRNX05PVF9NVVRBQkxFID0KLSAgICAgICAgICJFUl9OT0RFU0VURFRNX05PVF9NVVRBQkxFIjsKLSAgIC8qKiAgVmFyaWFibGUgbm90IHJlc29sdmFibGU6ICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVkFSX05PVF9SRVNPTFZBQkxFID0gIkVSX1ZBUl9OT1RfUkVTT0xWQUJMRSI7Ci0gICAvKiogTnVsbCBlcnJvciBoYW5kbGVyICAqLwotIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05VTExfRVJST1JfSEFORExFUiA9ICJFUl9OVUxMX0VSUk9SX0hBTkRMRVIiOwotICAgLyoqICBQcm9ncmFtbWVyJ3MgYXNzZXJ0aW9uOiB1bmtub3duIG9wY29kZSAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJPR19BU1NFUlRfVU5LTk9XTl9PUENPREUgPQotICAgICAgICAgIkVSX1BST0dfQVNTRVJUX1VOS05PV05fT1BDT0RFIjsKLSAgIC8qKiAgMCBvciAxICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWkVST19PUl9PTkUgPSAiRVJfWkVST19PUl9PTkUiOwotICAgLyoqICBydGYoKSBub3Qgc3VwcG9ydGVkIGJ5IFhSVHJlZUZyYWdTZWxlY3RXcmFwcGVyICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUlRGX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIgPQotICAgICAgICAgIkVSX1JURl9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSIjsKLSAgIC8qKiAgYXNOb2RlSXRlcmF0b3IoKSBub3Qgc3VwcG9ydGVkIGJ5IFhSVHJlZUZyYWdTZWxlY3RXcmFwcGVyICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQVNOT0RFSVRFUkFUT1JfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiA9ICJFUl9BU05PREVJVEVSQVRPUl9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSIjsKLSAgIC8qKiAgZnNiKCkgbm90IHN1cHBvcnRlZCBmb3IgWFN0cmluZ0ZvckNoYXJzICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRlNCX05PVF9TVVBQT1JURURfWFNUUklOR0ZPUkNIQVJTID0KLSAgICAgICAgICJFUl9GU0JfTk9UX1NVUFBPUlRFRF9YU1RSSU5HRk9SQ0hBUlMiOwotICAgLyoqICBDb3VsZCBub3QgZmluZCB2YXJpYWJsZSB3aXRoIHRoZSBuYW1lIG9mICAgKi8KLSBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRF9OT1RfRklORF9WQVIgPSAiRVJfQ09VTERfTk9UX0ZJTkRfVkFSIjsKLSAgIC8qKiAgWFN0cmluZ0ZvckNoYXJzIGNhbiBub3QgdGFrZSBhIHN0cmluZyBmb3IgYW4gYXJndW1lbnQgICAqLwotIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hTVFJJTkdGT1JDSEFSU19DQU5OT1RfVEFLRV9TVFJJTkcgPQotICAgICAgICAgIkVSX1hTVFJJTkdGT1JDSEFSU19DQU5OT1RfVEFLRV9TVFJJTkciOwotICAgLyoqICBUaGUgRmFzdFN0cmluZ0J1ZmZlciBhcmd1bWVudCBjYW4gbm90IGJlIG51bGwgICAqLwotIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZBU1RTVFJJTkdCVUZGRVJfQ0FOTk9UX0JFX05VTEwgPQotICAgICAgICAgIkVSX0ZBU1RTVFJJTkdCVUZGRVJfQ0FOTk9UX0JFX05VTEwiOwotICAgLyoqICAyIG9yIDMgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9UV09fT1JfVEhSRUUgPSAiRVJfVFdPX09SX1RIUkVFIjsKLSAgIC8qKiBWYXJpYWJsZSBhY2Nlc3NlZCBiZWZvcmUgaXQgaXMgYm91bmQhICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1ZBUklBQkxFX0FDQ0VTU0VEX0JFRk9SRV9CSU5EID0KLSAgICAgICAgICJFUl9WQVJJQUJMRV9BQ0NFU1NFRF9CRUZPUkVfQklORCI7Ci0gICAvKiogWFN0cmluZ0ZvckZTQiBjYW4gbm90IHRha2UgYSBzdHJpbmcgZm9yIGFuIGFyZ3VtZW50ISAqLwotIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZTQl9DQU5OT1RfVEFLRV9TVFJJTkcgPQotICAgICAgICAgIkVSX0ZTQl9DQU5OT1RfVEFLRV9TVFJJTkciOwotICAgLyoqIEVycm9yISBTZXR0aW5nIHRoZSByb290IG9mIGEgd2Fsa2VyIHRvIG51bGwhICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NFVFRJTkdfV0FMS0VSX1JPT1RfVE9fTlVMTCA9Ci0gICAgICAgICAiRVJfU0VUVElOR19XQUxLRVJfUk9PVF9UT19OVUxMIjsKLSAgIC8qKiBUaGlzIE5vZGVTZXREVE0gY2FuIG5vdCBpdGVyYXRlIHRvIGEgcHJldmlvdXMgbm9kZSEgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9ERVNFVERUTV9DQU5OT1RfSVRFUkFURSA9Ci0gICAgICAgICAiRVJfTk9ERVNFVERUTV9DQU5OT1RfSVRFUkFURSI7Ci0gIC8qKiBUaGlzIE5vZGVTZXQgY2FuIG5vdCBpdGVyYXRlIHRvIGEgcHJldmlvdXMgbm9kZSEgKi8KLSBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT0RFU0VUX0NBTk5PVF9JVEVSQVRFID0KLSAgICAgICAgICJFUl9OT0RFU0VUX0NBTk5PVF9JVEVSQVRFIjsKLSAgLyoqIFRoaXMgTm9kZVNldERUTSBjYW4gbm90IGRvIGluZGV4aW5nIG9yIGNvdW50aW5nIGZ1bmN0aW9ucyEgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9ERVNFVERUTV9DQU5OT1RfSU5ERVggPQotICAgICAgICAgIkVSX05PREVTRVREVE1fQ0FOTk9UX0lOREVYIjsKLSAgLyoqIFRoaXMgTm9kZVNldCBjYW4gbm90IGRvIGluZGV4aW5nIG9yIGNvdW50aW5nIGZ1bmN0aW9ucyEgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9ERVNFVF9DQU5OT1RfSU5ERVggPQotICAgICAgICAgIkVSX05PREVTRVRfQ0FOTk9UX0lOREVYIjsKLSAgLyoqIENhbiBub3QgY2FsbCBzZXRTaG91bGRDYWNoZU5vZGVzIGFmdGVyIG5leHROb2RlIGhhcyBiZWVuIGNhbGxlZCEgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX0NBTExfU0VUU0hPVUxEQ0FDSEVOT0RFID0KLSAgICAgICAgICJFUl9DQU5OT1RfQ0FMTF9TRVRTSE9VTERDQUNIRU5PREUiOwotICAvKiogezB9IG9ubHkgYWxsb3dzIHsxfSBhcmd1bWVudHMgKi8KLSBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9PTkxZX0FMTE9XUyA9ICJFUl9PTkxZX0FMTE9XUyI7Ci0gIC8qKiBQcm9ncmFtbWVyJ3MgYXNzZXJ0aW9uIGluIGdldE5leHRTdGVwUG9zOiB1bmtub3duIHN0ZXBUeXBlOiB7MH0gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5LTk9XTl9TVEVQID0gIkVSX1VOS05PV05fU1RFUCI7Ci0gIC8qKiBQcm9ibGVtIHdpdGggUmVsYXRpdmVMb2NhdGlvblBhdGggKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhQRUNURURfUkVMX0xPQ19QQVRIID0KLSAgICAgICAgICJFUl9FWFBFQ1RFRF9SRUxfTE9DX1BBVEgiOwotICAvKiogUHJvYmxlbSB3aXRoIExvY2F0aW9uUGF0aCAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FWFBFQ1RFRF9MT0NfUEFUSCA9ICJFUl9FWFBFQ1RFRF9MT0NfUEFUSCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYUEVDVEVEX0xPQ19QQVRIX0FUX0VORF9FWFBSID0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRVJfRVhQRUNURURfTE9DX1BBVEhfQVRfRU5EX0VYUFIiOwotICAvKiogUHJvYmxlbSB3aXRoIFN0ZXAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhQRUNURURfTE9DX1NURVAgPSAiRVJfRVhQRUNURURfTE9DX1NURVAiOwotICAvKiogUHJvYmxlbSB3aXRoIE5vZGVUZXN0ICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYUEVDVEVEX05PREVfVEVTVCA9ICJFUl9FWFBFQ1RFRF9OT0RFX1RFU1QiOwotICAvKiogRXhwZWN0ZWQgc3RlcCBwYXR0ZXJuICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYUEVDVEVEX1NURVBfUEFUVEVSTiA9Ci0gICAgICAgICJFUl9FWFBFQ1RFRF9TVEVQX1BBVFRFUk4iOwotICAvKiogRXhwZWN0ZWQgcmVsYXRpdmUgcGF0aCBwYXR0ZXJuICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYUEVDVEVEX1JFTF9QQVRIX1BBVFRFUk4gPQotICAgICAgICAgIkVSX0VYUEVDVEVEX1JFTF9QQVRIX1BBVFRFUk4iOwotICAvKiogRVJfQ0FOVF9DT05WRVJUX1hQQVRIUkVTVUxUVFlQRV9UT19CT09MRUFOICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfQ09OVkVSVF9UT19CT09MRUFOID0KLSAgICAgICAgICJFUl9DQU5UX0NPTlZFUlRfVE9fQk9PTEVBTiI7Ci0gIC8qKiBGaWVsZCBFUl9DQU5UX0NPTlZFUlRfVE9fU0lOR0xFTk9ERSAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX0NPTlZFUlRfVE9fU0lOR0xFTk9ERSA9Ci0gICAgICAgICAiRVJfQ0FOVF9DT05WRVJUX1RPX1NJTkdMRU5PREUiOwotICAvKiogRmllbGQgRVJfQ0FOVF9HRVRfU05BUFNIT1RfTEVOR1RIICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9HRVRfU05BUFNIT1RfTEVOR1RIID0KLSAgICAgICAgICJFUl9DQU5UX0dFVF9TTkFQU0hPVF9MRU5HVEgiOwotICAvKiogRmllbGQgRVJfTk9OX0lURVJBVE9SX1RZUEUgICAgICAgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9OX0lURVJBVE9SX1RZUEUgPSAiRVJfTk9OX0lURVJBVE9SX1RZUEUiOwotICAvKiogRmllbGQgRVJfRE9DX01VVEFURUQgICAgICAgICAgICAgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRE9DX01VVEFURUQgPSAiRVJfRE9DX01VVEFURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX1hQQVRIX1RZUEUgPSAiRVJfSU5WQUxJRF9YUEFUSF9UWVBFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRU1QVFlfWFBBVEhfUkVTVUxUID0gIkVSX0VNUFRZX1hQQVRIX1JFU1VMVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOQ09NUEFUSUJMRV9UWVBFUyA9ICJFUl9JTkNPTVBBVElCTEVfVFlQRVMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OVUxMX1JFU09MVkVSID0gIkVSX05VTExfUkVTT0xWRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX0NPTlZFUlRfVE9fU1RSSU5HID0KLSAgICAgICAgICJFUl9DQU5UX0NPTlZFUlRfVE9fU1RSSU5HIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9OX1NOQVBTSE9UX1RZUEUgPSAiRVJfTk9OX1NOQVBTSE9UX1RZUEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9XUk9OR19ET0NVTUVOVCA9ICJFUl9XUk9OR19ET0NVTUVOVCI7Ci0gIC8qIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgWFBhdGggZXhwcmVzc2lvbiBjYW5ub3QgYmUgZXZhbHVhdGVkIHdpdGggcmVzcGVjdAotICAgKiB0byB0aGlzIHR5cGUgb2Ygbm9kZS4KLSAgICovCi0gIC8qKiBGaWVsZCBFUl9XUk9OR19OT0RFVFlQRSAgICAgICAgICAgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfV1JPTkdfTk9ERVRZUEUgPSAiRVJfV1JPTkdfTk9ERVRZUEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YUEFUSF9FUlJPUiA9ICJFUl9YUEFUSF9FUlJPUiI7Ci0KLSAgLy9CRUdJTjogS2V5cyBuZWVkZWQgZm9yIGV4Y2VwdGlvbiBtZXNzYWdlcyBvZiAgSkFYUCAxLjMgWFBhdGggQVBJIGltcGxlbWVudGF0aW9uCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYVEVOU0lPTl9GVU5DVElPTl9DQU5OT1RfQkVfSU5WT0tFRCA9ICJFUl9FWFRFTlNJT05fRlVOQ1RJT05fQ0FOTk9UX0JFX0lOVk9LRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SRVNPTFZFX1ZBUklBQkxFX1JFVFVSTlNfTlVMTCA9ICJFUl9SRVNPTFZFX1ZBUklBQkxFX1JFVFVSTlNfTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1VOU1VQUE9SVEVEX1JFVFVSTl9UWVBFID0gIkVSX1VOU1VQUE9SVEVEX1JFVFVSTl9UWVBFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU09VUkNFX1JFVFVSTl9UWVBFX0NBTk5PVF9CRV9OVUxMID0gIkVSX1NPVVJDRV9SRVRVUk5fVFlQRV9DQU5OT1RfQkVfTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FSR19DQU5OT1RfQkVfTlVMTCA9ICJFUl9BUkdfQ0FOTk9UX0JFX05VTEwiOwotCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX09CSkVDVF9NT0RFTF9OVUxMID0gIkVSX09CSkVDVF9NT0RFTF9OVUxMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfT0JKRUNUX01PREVMX0VNUFRZID0gIkVSX09CSkVDVF9NT0RFTF9FTVBUWSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZFQVRVUkVfTkFNRV9OVUxMID0gIkVSX0ZFQVRVUkVfTkFNRV9OVUxMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRkVBVFVSRV9VTktOT1dOID0gIkVSX0ZFQVRVUkVfVU5LTk9XTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0dFVFRJTkdfTlVMTF9GRUFUVVJFID0gIkVSX0dFVFRJTkdfTlVMTF9GRUFUVVJFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfR0VUVElOR19VTktOT1dOX0ZFQVRVUkUgPSAiRVJfR0VUVElOR19VTktOT1dOX0ZFQVRVUkUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TRUNVUkVQUk9DRVNTSU5HX0ZFQVRVUkUgPSAiRVJfU0VDVVJFUFJPQ0VTU0lOR19GRUFUVVJFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTlVMTF9YUEFUSF9GVU5DVElPTl9SRVNPTFZFUiA9ICJFUl9OVUxMX1hQQVRIX0ZVTkNUSU9OX1JFU09MVkVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTlVMTF9YUEFUSF9WQVJJQUJMRV9SRVNPTFZFUiA9ICJFUl9OVUxMX1hQQVRIX1ZBUklBQkxFX1JFU09MVkVSIjsKLSAgLy9FTkQ6IEtleXMgbmVlZGVkIGZvciBleGNlcHRpb24gbWVzc2FnZXMgb2YgIEpBWFAgMS4zIFhQYXRoIEFQSSBpbXBsZW1lbnRhdGlvbgotCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0xPQ0FMRV9OQU1FX05PVF9IQU5ETEVEID0KLSAgICAgICAgICJXR19MT0NBTEVfTkFNRV9OT1RfSEFORExFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX1BST1BFUlRZX05PVF9TVVBQT1JURUQgPQotICAgICAgICAgIldHX1BST1BFUlRZX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19ET05UX0RPX0FOWVRISU5HX1dJVEhfTlMgPQotICAgICAgICAgIldHX0RPTlRfRE9fQU5ZVEhJTkdfV0lUSF9OUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX1NFQ1VSSVRZX0VYQ0VQVElPTiA9ICJXR19TRUNVUklUWV9FWENFUFRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19RVU9fTk9fTE9OR0VSX0RFRklORUQgPQotICAgICAgICAgIldHX1FVT19OT19MT05HRVJfREVGSU5FRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX05FRURfREVSSVZFRF9PQkpFQ1RfVE9fSU1QTEVNRU5UX05PREVURVNUID0KLSAgICAgICAgICJXR19ORUVEX0RFUklWRURfT0JKRUNUX1RPX0lNUExFTUVOVF9OT0RFVEVTVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0ZVTkNUSU9OX1RPS0VOX05PVF9GT1VORCA9Ci0gICAgICAgICAiV0dfRlVOQ1RJT05fVE9LRU5fTk9UX0ZPVU5EIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfQ09VTEROT1RfRklORF9GVU5DVElPTiA9Ci0gICAgICAgICAiV0dfQ09VTEROT1RfRklORF9GVU5DVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0NBTk5PVF9NQUtFX1VSTF9GUk9NID0iV0dfQ0FOTk9UX01BS0VfVVJMX0ZST00iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19FWFBBTkRfRU5USVRJRVNfTk9UX1NVUFBPUlRFRCA9Ci0gICAgICAgICAiV0dfRVhQQU5EX0VOVElUSUVTX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19JTExFR0FMX1ZBUklBQkxFX1JFRkVSRU5DRSA9Ci0gICAgICAgICAiV0dfSUxMRUdBTF9WQVJJQUJMRV9SRUZFUkVOQ0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19VTlNVUFBPUlRFRF9FTkNPRElORyA9IldHX1VOU1VQUE9SVEVEX0VOQ09ESU5HIjsKLQotICAvKiogIGRldGFjaCgpIG5vdCBzdXBwb3J0ZWQgYnkgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9ERVRBQ0hfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiA9Ci0gICAgICAgICAiRVJfREVUQUNIX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIiOwotICAvKiogIG51bSgpIG5vdCBzdXBwb3J0ZWQgYnkgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OVU1fTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiA9Ci0gICAgICAgICAiRVJfTlVNX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIiOwotICAvKiogIHhzdHIoKSBub3Qgc3VwcG9ydGVkIGJ5IFhSVHJlZUZyYWdTZWxlY3RXcmFwcGVyICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWFNUUl9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSID0KLSAgICAgICAgICJFUl9YU1RSX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIiOwotICAvKiogIHN0cigpIG5vdCBzdXBwb3J0ZWQgYnkgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TVFJfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiA9Ci0gICAgICAgICAiRVJfU1RSX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIiOwotCi0gIC8vIEVycm9yIG1lc3NhZ2VzLi4uCi0KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgT2JqZWN0W11bXSBfY29udGVudHMgPSBuZXcgT2JqZWN0W11bXXsKLQotICB7ICJFUlJPUjAwMDAiICwgInswfSIgfSwKLQotICB7IEVSX0NVUlJFTlRfTk9UX0FMTE9XRURfSU5fTUFUQ0gsICJMYSBmb25jdGlvbiBjdXJyZW50KCkgbidlc3QgcGFzIGF1dG9yaXNcdTAwRTllIGRhbnMgdW4gbW9kXHUwMEU4bGUgZGUgcmVjaGVyY2hlLiIgfSwKLQotICB7IEVSX0NVUlJFTlRfVEFLRVNfTk9fQVJHUywgIkxhIGZvbmN0aW9uIGN1cnJlbnQoKSBuJ2FjY2VwdGUgcGFzIGQnYXJndW1lbnQuIiB9LAotCi0gIHsgRVJfRE9DVU1FTlRfUkVQTEFDRUQsCi0gICAgICAiTCdpbXBsXHUwMEU5bWVudGF0aW9uIGRlIGxhIGZvbmN0aW9uIGRvY3VtZW50KCkgYSBcdTAwRTl0XHUwMEU5IHJlbXBsYWNcdTAwRTllIHBhciBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdC5GdW5jRG9jdW1lbnQuIn0sCi0KLSAgeyBFUl9DT05URVhUX0hBU19OT19PV05FUkRPQywKLSAgICAgICJsZSBjb250ZXh0ZSBuZSBwb3NzXHUwMEU4ZGUgcGFzIGRlIGRvY3VtZW50IHByb3ByaVx1MDBFOXRhaXJlLiJ9LAotCi0gIHsgRVJfTE9DQUxOQU1FX0hBU19UT09fTUFOWV9BUkdTLAotICAgICAgImxvY2FsLW5hbWUoKSBwb3NzXHUwMEU4ZGUgdHJvcCBkJ2FyZ3VtZW50cy4ifSwKLQotICB7IEVSX05BTUVTUEFDRVVSSV9IQVNfVE9PX01BTllfQVJHUywKLSAgICAgICJuYW1lc3BhY2UtdXJpKCkgcG9zc1x1MDBFOGRlIHRyb3AgZCdhcmd1bWVudHMuIn0sCi0KLSAgeyBFUl9OT1JNQUxJWkVTUEFDRV9IQVNfVE9PX01BTllfQVJHUywKLSAgICAgICJub3JtYWxpemUtc3BhY2UoKSBwb3NzXHUwMEU4ZGUgdHJvcCBkJ2FyZ3VtZW50cy4ifSwKLQotICB7IEVSX05VTUJFUl9IQVNfVE9PX01BTllfQVJHUywKLSAgICAgICJudW1iZXIoKSBwb3NzXHUwMEU4ZGUgdHJvcCBkJ2FyZ3VtZW50cy4ifSwKLQotICB7IEVSX05BTUVfSEFTX1RPT19NQU5ZX0FSR1MsCi0gICAgICJuYW1lKCkgcG9zc1x1MDBFOGRlIHRyb3AgZCdhcmd1bWVudHMuIn0sCi0KLSAgeyBFUl9TVFJJTkdfSEFTX1RPT19NQU5ZX0FSR1MsCi0gICAgICAic3RyaW5nKCkgcG9zc1x1MDBFOGRlIHRyb3AgZCdhcmd1bWVudHMuIn0sCi0KLSAgeyBFUl9TVFJJTkdMRU5HVEhfSEFTX1RPT19NQU5ZX0FSR1MsCi0gICAgICAic3RyaW5nLWxlbmd0aCgpIHBvc3NcdTAwRThkZSB0cm9wIGQnYXJndW1lbnRzLiJ9LAotCi0gIHsgRVJfVFJBTlNMQVRFX1RBS0VTXzNfQVJHUywKLSAgICAgICJMYSBmb25jdGlvbiB0cmFuc2xhdGUoKSBhY2NlcHRlIHRyb2lzIGFyZ3VtZW50cy4ifSwKLQotICB7IEVSX1VOUEFSU0VERU5USVRZVVJJX1RBS0VTXzFfQVJHLAotICAgICAgIlVuIGFyZ3VtZW50IGRvaXQgXHUwMEVBdHJlIGZvdXJuaSBcdTAwRTAgbGEgZm9uY3Rpb24gdW5wYXJzZWQtZW50aXR5LXVyaS4ifSwKLQotICB7IEVSX05BTUVTUEFDRUFYSVNfTk9UX0lNUExFTUVOVEVELAotICAgICAgImwnYXhlIGRlIGwnZXNwYWNlIGRlIG5vbXMgbidlc3QgcGFzIGltcGxcdTAwRTltZW50XHUwMEU5LiJ9LAotCi0gIHsgRVJfVU5LTk9XTl9BWElTLAotICAgICAiYXhlIGluY29ubnUgOiB7MH0ifSwKLQotICB7IEVSX1VOS05PV05fTUFUQ0hfT1BFUkFUSU9OLAotICAgICAib3BcdTAwRTlyYXRpb24gZGUgY29ycmVzcG9uZGFuY2UgaW5jb25udWUuIn0sCi0KLSAgeyBFUl9JTkNPUlJFQ1RfQVJHX0xFTkdUSCwKLSAgICAgICJMYSBsb25ndWV1ciBkJ2FyZ3VtZW50IGR1IHRlc3QgZHUgbm9ldWQgcHJvY2Vzc2luZy1pbnN0cnVjdGlvbigpIG4nZXN0IHBhcyBjb3JyZWN0ZS4ifSwKLQotICB7IEVSX0NBTlRfQ09OVkVSVF9UT19OVU1CRVIsCi0gICAgICAiSW1wb3NzaWJsZSBkZSBjb252ZXJ0aXIgezB9IGVuIG5vbWJyZSJ9LAotCi0gIHsgRVJfQ0FOVF9DT05WRVJUX1RPX05PREVMSVNULAotICAgICAgIkltcG9zc2libGUgZGUgY29udmVydGlyIHswfSBlbiBOb2RlTGlzdC4ifSwKLQotICB7IEVSX0NBTlRfQ09OVkVSVF9UT19NVVRBQkxFTk9ERUxJU1QsCi0gICAgICAiSW1wb3NzaWJsZSBkZSBjb252ZXJ0aXIgezB9IGVuIE5vZGVTZXREVE0uIn0sCi0KLSAgeyBFUl9DQU5UX0NPTlZFUlRfVE9fVFlQRSwKLSAgICAgICJJbXBvc3NpYmxlIGRlIGNvbnZlcnRpciB7MH0gZW4gdHlwZSN7MX0ifSwKLQotICB7IEVSX0VYUEVDVEVEX01BVENIX1BBVFRFUk4sCi0gICAgICAiTW9kXHUwMEU4bGUgZGUgcmVjaGVyY2hlIGF0dGVuZHUgZGFucyBnZXRNYXRjaFNjb3JlLiJ9LAotCi0gIHsgRVJfQ09VTEROT1RfR0VUX1ZBUl9OQU1FRCwKLSAgICAgICJJbXBvc3NpYmxlIGQnJ29idGVuaXIgbGEgdmFyaWFibGUgbm9tbVx1MDBFOWUgezB9In0sCi0KLSAgeyBFUl9VTktOT1dOX09QQ09ERSwKLSAgICAgIkVSUkVVUi4gQ29kZSBkJydvcFx1MDBFOXJhdGlvbiBpbmNvbm51IDogezB9In0sCi0KLSAgeyBFUl9FWFRSQV9JTExFR0FMX1RPS0VOUywKLSAgICAgIkpldG9ucyBub24gYWRtaXMgc3VwcGxcdTAwRTltZW50YWlyZXMgOiB7MH0ifSwKLQotICB7IEVSX0VYUEVDVEVEX0RPVUJMRV9RVU9URSwKLSAgICAgICJFcnJldXIgZGUgZ3VpbGxlbWV0cyBkYW5zIHVuIGxpdHRcdTAwRTlyYWwuLi4gR3VpbGxlbWV0cyBvYmxpZ2F0b2lyZXMuIn0sCi0KLSAgeyBFUl9FWFBFQ1RFRF9TSU5HTEVfUVVPVEUsCi0gICAgICAiRXJyZXVyIGQnYXBvc3Ryb3BoZSBkYW5zIHVuIGxpdHRcdTAwRTlyYWwuLi4gQXBvc3Ryb3BoZSBvYmxpZ2F0b2lyZS4ifSwKLQotICB7IEVSX0VNUFRZX0VYUFJFU1NJT04sCi0gICAgICJFeHByZXNzaW9uIHZpZGUuIn0sCi0KLSAgeyBFUl9FWFBFQ1RFRF9CVVRfRk9VTkQsCi0gICAgICJWYWxldXIgYXR0ZW5kdWUgOiB7MH0sIG1haXMgezF9IGEgXHUwMEU5dFx1MDBFOSB0cm91dlx1MDBFOSJ9LAotCi0gIHsgRVJfSU5DT1JSRUNUX1BST0dSQU1NRVJfQVNTRVJUSU9OLAotICAgICAgIkFzc2VydGlvbiBkZSBwcm9ncmFtbWV1ciBpbmNvcnJlY3RlLiAtIHswfSJ9LAotCi0gIHsgRVJfQk9PTEVBTl9BUkdfTk9fTE9OR0VSX09QVElPTkFMLAotICAgICAgIkwnYXJndW1lbnQgYm9vbGVhbiguLi4pIG4nZXN0IHBsdXMgZmFjdWx0YXRpZiBhdmVjIGxlIGJyb3VpbGxvbiAoZHJhZnQpIFhQYXRoIDE5OTkwNzA5LiJ9LAotCi0gIHsgRVJfRk9VTkRfQ09NTUFfQlVUX05PX1BSRUNFRElOR19BUkcsCi0gICAgICAiQ2FyYWN0XHUwMEU4cmUgJywnIHRyb3V2XHUwMEU5IHNhbnMgYXJndW1lbnQgbGUgcHJcdTAwRTljXHUwMEU5ZGFudC4ifSwKLQotICB7IEVSX0ZPVU5EX0NPTU1BX0JVVF9OT19GT0xMT1dJTkdfQVJHLAotICAgICAgIkNhcmFjdFx1MDBFOHJlICcsJyB0cm91dlx1MDBFOSBzYW5zIGFyZ3VtZW50IGxlIHN1aXZhbnQuIn0sCi0KLSAgeyBFUl9QUkVESUNBVEVfSUxMRUdBTF9TWU5UQVgsCi0gICAgICAiU3ludGF4ZSAnLi5bcHJlZGljYXRlXScgb3UgJy5bcHJlZGljYXRlXScgbm9uIGFkbWlzZS4gVXRpbGlzZXogJ3NlbGY6Om5vZGUoKVtwcmVkaWNhdGVdJyBcdTAwRTAgbGEgcGxhY2UuIn0sCi0KLSAgeyBFUl9JTExFR0FMX0FYSVNfTkFNRSwKLSAgICAgIm5vbSBkJydheGUgbm9uIGFkbWlzIDogezB9In0sCi0KLSAgeyBFUl9VTktOT1dOX05PREVUWVBFLAotICAgICAiVHlwZSBkZSBub2V1ZCBpbmNvbm51IDogezB9In0sCi0KLSAgeyBFUl9QQVRURVJOX0xJVEVSQUxfTkVFRFNfQkVfUVVPVEVELAotICAgICAgIkxlIGxpdHRcdTAwRTlyYWwgZGUgbW9kXHUwMEU4bGUgKHswfSkgZG9pdCBmaWd1cmVyIGVudHJlIGd1aWxsZW1ldHMuIn0sCi0KLSAgeyBFUl9DT1VMRE5PVF9CRV9GT1JNQVRURURfVE9fTlVNQkVSLAotICAgICAgIkltcG9zc2libGUgZGUgZm9ybWF0ZXIgezB9IGVuIG5vbWJyZS4ifSwKLQotICB7IEVSX0NPVUxETk9UX0NSRUFURV9YTUxQUk9DRVNTT1JMSUFJU09OLAotICAgICAgIkltcG9zc2libGUgZGUgY3JcdTAwRTllciBsYSBsaWFpc29uIFhNTCBUcmFuc2Zvcm1lckZhY3RvcnkgOiB7MH0ifSwKLQotICB7IEVSX0RJRE5PVF9GSU5EX1hQQVRIX1NFTEVDVF9FWFAsCi0gICAgICAiRXJyZXVyLiBFeHByZXNzaW9uIGRlIHNcdTAwRTlsZWN0aW9uIFhQYXRoICgtc2VsZWN0KSBpbnRyb3V2YWJsZS4ifSwKLQotICB7IEVSX0NPVUxETk9UX0ZJTkRfRU5ET1BfQUZURVJfT1BMT0NBVElPTlBBVEgsCi0gICAgICAiRVJSRVVSLiBFTkRPUCBpbnRyb3V2YWJsZSBhcHJcdTAwRThzIE9QX0xPQ0FUSU9OUEFUSCJ9LAotCi0gIHsgRVJfRVJST1JfT0NDVVJFRCwKLSAgICAgIlVuZSBlcnJldXIgZXN0IHN1cnZlbnVlLiJ9LAotCi0gIHsgRVJfSUxMRUdBTF9WQVJJQUJMRV9SRUZFUkVOQ0UsCi0gICAgICAiTCcnXHUwMEU5bFx1MDBFOW1lbnQgVmFyaWFibGVSZWZlcmVuY2UgaW5kaXF1XHUwMEU5IHBvdXIgbGEgdmFyaWFibGUgZXN0IGhvcnMgY29udGV4dGUgb3Ugc2FucyBkXHUwMEU5ZmluaXRpb24uIE5vbSA9IHswfSJ9LAotCi0gIHsgRVJfQVhFU19OT1RfQUxMT1dFRCwKLSAgICAgICJTZXVscyBsZXMgYXhlcyBjaGlsZDo6IGV0IGF0dHJpYnV0ZTo6IHNvbnQgYXV0b3Jpc1x1MDBFOXMgZGFucyBkZXMgbW9kXHUwMEU4bGVzIGRlIHJlY2hlcmNoZS4gQXhlcyBlbiBjYXVzZSA9IHswfSJ9LAotCi0gIHsgRVJfS0VZX0hBU19UT09fTUFOWV9BUkdTLAotICAgICAgImtleSgpIHBvc3NcdTAwRThkZSB1biBub21icmUgaW5jb3JyZWN0IGQnYXJndW1lbnRzLiJ9LAotCi0gIHsgRVJfQ09VTlRfVEFLRVNfMV9BUkcsCi0gICAgICAiVW4gc2V1bCBhcmd1bWVudCBkb2l0IFx1MDBFQXRyZSBmb3VybmkgXHUwMEUwIGxhIGZvbmN0aW9uIGRlIGRcdTAwRTljb21wdGUuIn0sCi0KLSAgeyBFUl9DT1VMRE5PVF9GSU5EX0ZVTkNUSU9OLAotICAgICAiSW1wb3NzaWJsZSBkZSB0cm91dmVyIGxhIGZvbmN0aW9uIDogezB9In0sCi0KLSAgeyBFUl9VTlNVUFBPUlRFRF9FTkNPRElORywKLSAgICAgIkVuY29kYWdlIG5vbiBwcmlzIGVuIGNoYXJnZSA6IHswfSJ9LAotCi0gIHsgRVJfUFJPQkxFTV9JTl9EVE1fTkVYVFNJQkxJTkcsCi0gICAgICAiVW5lIGVycmV1ciBlc3Qgc3VydmVudWUgZGFucyBsZSBEVE0gZGUgZ2V0TmV4dFNpYmxpbmcuLi4gVGVudGF0aXZlIGRlIHJcdTAwRTljdXBcdTAwRTlyYXRpb24ifSwKLQotICB7IEVSX0NBTk5PVF9XUklURV9UT19FTVBUWU5PREVMSVNUSU1QTCwKLSAgICAgICJFcnJldXIgZGUgcHJvZ3JhbW1ldXIgOiBcdTAwRTljcml0dXJlIGltcG9zc2libGUgZGFucyBFbXB0eU5vZGVMaXN0LiJ9LAotCi0gIHsgRVJfU0VURE9NRkFDVE9SWV9OT1RfU1VQUE9SVEVELAotICAgICAgIlNldERPTUZhY3Rvcnkgbidlc3QgcGFzIHByaXMgZW4gY2hhcmdlIHBhciBYUGF0aENvbnRleHQuIn0sCi0KLSAgeyBFUl9QUkVGSVhfTVVTVF9SRVNPTFZFLAotICAgICAgIkxlIHByXHUwMEU5Zml4ZSBkb2l0IHByb2R1aXJlIHVuIGVzcGFjZSBkZSBub21zIDogezB9In0sCi0KLSAgeyBFUl9QQVJTRV9OT1RfU1VQUE9SVEVELAotICAgICAgImFuYWx5c2UgKHNvdXJjZSBJbnB1dFNvdXJjZSkgbm9uIHByaXNlIGVuIGNoYXJnZSBkYW5zIFhQYXRoQ29udGV4dC4gSW1wb3NzaWJsZSBkJydvdXZyaXIgezB9In0sCi0KLSAgeyBFUl9TQVhfQVBJX05PVF9IQU5ETEVELAotICAgICAgIkNhcmFjdFx1MDBFOHJlcyAoY2hhciBjaFtdLi4uKSBkZSBsJ0FQSSBTQVggbm9uIHByaXMgZW4gY2hhcmdlIHBhciBsZSBEVE0uIn0sCi0KLSAgeyBFUl9JR05PUkFCTEVfV0hJVEVTUEFDRV9OT1RfSEFORExFRCwKLSAgICAgICJpZ25vcmFibGVXaGl0ZXNwYWNlKGNoYXIgY2hbXS4uLiBub24gcHJpcyBlbiBjaGFyZ2UgcGFyIGxlIERUTS4ifSwKLQotICB7IEVSX0RUTV9DQU5OT1RfSEFORExFX05PREVTLAotICAgICAgIkRUTUxpYWlzb24gbmUgcHJlbmQgcGFzIGVuIGNoYXJnZSBsZXMgbm9ldWRzIGRlIHR5cGUgezB9In0sCi0KLSAgeyBFUl9YRVJDRVNfQ0FOTk9UX0hBTkRMRV9OT0RFUywKLSAgICAgICJET00ySGVscGVyIG5lIHByZW5kIHBhcyBlbiBjaGFyZ2UgbGVzIG5vZXVkcyBkZSB0eXBlIHswfSJ9LAotCi0gIHsgRVJfWEVSQ0VTX1BBUlNFX0VSUk9SX0RFVEFJTFMsCi0gICAgICAiRXJyZXVyIGRlIERPTTJIZWxwZXIucGFyc2UgOiBTeXN0ZW1JRCAtIHswfSBsaWduZSAtIHsxfSJ9LAotCi0gIHsgRVJfWEVSQ0VTX1BBUlNFX0VSUk9SLAotICAgICAiRXJyZXVyIGRlIERPTTJIZWxwZXIucGFyc2UifSwKLQotICB7IEVSX0lOVkFMSURfVVRGMTZfU1VSUk9HQVRFLAotICAgICAgIlN1YnN0aXR1dCBVVEYtMTYgbm9uIHZhbGlkZSBkXHUwMEU5dGVjdFx1MDBFOSA6IHswfSA/In0sCi0KLSAgeyBFUl9PSUVSUk9SLAotICAgICAiRXJyZXVyIGQnRS9TIn0sCi0KLSAgeyBFUl9DQU5OT1RfQ1JFQVRFX1VSTCwKLSAgICAgIkltcG9zc2libGUgZGUgY3JcdTAwRTllciB1bmUgVVJMIHBvdXIgOiB7MH0ifSwKLQotICB7IEVSX1hQQVRIX1JFQURPQkpFQ1QsCi0gICAgICJEYW5zIFhQYXRoLnJlYWRPYmplY3QgOiB7MH0ifSwKLQotICB7IEVSX0ZVTkNUSU9OX1RPS0VOX05PVF9GT1VORCwKLSAgICAgICJqZXRvbiBkZSBmb25jdGlvbiBpbnRyb3V2YWJsZS4ifSwKLQotICB7IEVSX0NBTk5PVF9ERUFMX1hQQVRIX1RZUEUsCi0gICAgICAgIkltcG9zc2libGUgZGUgdHJhaXRlciBsZSB0eXBlIFhQYXRoIDogezB9In0sCi0KLSAgeyBFUl9OT0RFU0VUX05PVF9NVVRBQkxFLAotICAgICAgICJOb2RlU2V0IG5vbiBtdXRhYmxlIn0sCi0KLSAgeyBFUl9OT0RFU0VURFRNX05PVF9NVVRBQkxFLAotICAgICAgICJOb2RlU2V0RFRNIG5vbiBtdXRhYmxlIn0sCi0KLSAgeyBFUl9WQVJfTk9UX1JFU09MVkFCTEUsCi0gICAgICAgICJJbXBvc3NpYmxlIGRlIHJcdTAwRTlzb3VkcmUgbGEgdmFyaWFibGUgOiB7MH0ifSwKLQotICB7IEVSX05VTExfRVJST1JfSEFORExFUiwKLSAgICAgICAgIkdlc3Rpb25uYWlyZSBkJ2VycmV1cnMgTlVMTCJ9LAotCi0gIHsgRVJfUFJPR19BU1NFUlRfVU5LTk9XTl9PUENPREUsCi0gICAgICAgIkFzc2VydGlvbiBkZSBwcm9ncmFtbWV1ciA6IGNvZGUgZCcnb3BcdTAwRTlyYXRpb24gaW5jb25udSA6IHswfSJ9LAotCi0gIHsgRVJfWkVST19PUl9PTkUsCi0gICAgICAgIjAgb3UgMSJ9LAotCi0gIHsgRVJfUlRGX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIsCi0gICAgICAgInJ0ZigpIG5vbiBwcmlzIGVuIGNoYXJnZSBwYXIgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIifSwKLQotICB7IEVSX1JURl9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSLAotICAgICAgICJhc05vZGVJdGVyYXRvcigpIG5vbiBwcmlzIGVuIGNoYXJnZSBwYXIgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIifSwKLQotICAgICAgICAvKiogIGRldGFjaCgpIG5vdCBzdXBwb3J0ZWQgYnkgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIgICAqLwotICAgeyBFUl9ERVRBQ0hfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiwKLSAgICAgICAgICAgICAgICAiZGV0YWNoKCkgbm9uIHByaXMgZW4gY2hhcmdlIHBhciBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciJ9LAotCi0gICAgICAgIC8qKiAgbnVtKCkgbm90IHN1cHBvcnRlZCBieSBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciAgICovCi0gICB7IEVSX05VTV9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSLAotICAgICAgICAgICAgICAgICJudW0oKSBub24gcHJpcyBlbiBjaGFyZ2UgcGFyIFhSVHJlZUZyYWdTZWxlY3RXcmFwcGVyIn0sCi0KLSAgICAgICAgLyoqICB4c3RyKCkgbm90IHN1cHBvcnRlZCBieSBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciAgICovCi0gICB7IEVSX1hTVFJfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiwKLSAgICAgICAgICAgICAgICAieHN0cigpIG5vbiBwcmlzIGVuIGNoYXJnZSBwYXIgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIifSwKLQotICAgICAgICAvKiogIHN0cigpIG5vdCBzdXBwb3J0ZWQgYnkgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIgICAqLwotICAgeyBFUl9TVFJfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiwKLSAgICAgICAgICAgICAgICAic3RyKCkgbm9uIHByaXMgZW4gY2hhcmdlIHBhciBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciJ9LAotCi0gIHsgRVJfRlNCX05PVF9TVVBQT1JURURfWFNUUklOR0ZPUkNIQVJTLAotICAgICAgICJmc2IoKSBub24gcHJpcyBlbiBjaGFyZ2UgcG91ciBYU3RyaW5nRm9yQ2hhcnMifSwKLQotICB7IEVSX0NPVUxEX05PVF9GSU5EX1ZBUiwKLSAgICAgICJJbXBvc3NpYmxlIGRlIHRyb3V2ZXIgbGEgdmFyaWFibGUgcG9ydGFudCBsZSBub20gezB9In0sCi0KLSAgeyBFUl9YU1RSSU5HRk9SQ0hBUlNfQ0FOTk9UX1RBS0VfU1RSSU5HLAotICAgICAgIlhTdHJpbmdGb3JDaGFycyBuJ2FjY2VwdGUgcGFzIGRlIGNoYVx1MDBFRW5lIGNvbW1lIGFyZ3VtZW50In0sCi0KLSAgeyBFUl9GQVNUU1RSSU5HQlVGRkVSX0NBTk5PVF9CRV9OVUxMLAotICAgICAgIkwnYXJndW1lbnQgRmFzdFN0cmluZ0J1ZmZlciBuZSBkb2l0IHBhcyBcdTAwRUF0cmUgTlVMTCJ9LAotCi0gIHsgRVJfVFdPX09SX1RIUkVFLAotICAgICAgICIyIG91IDMifSwKLQotICB7IEVSX1ZBUklBQkxFX0FDQ0VTU0VEX0JFRk9SRV9CSU5ELAotICAgICAgICJMJ2FjY1x1MDBFOHMgXHUwMEUwIGxhIHZhcmlhYmxlIGEgcHJcdTAwRTljXHUwMEU5ZFx1MDBFOSBsYSBsaWFpc29uIGRlIGNlbGxlLWNpLiJ9LAotCi0gIHsgRVJfRlNCX0NBTk5PVF9UQUtFX1NUUklORywKLSAgICAgICAiWFN0cmluZ0ZvckZTQiBuJ2FjY2VwdGUgcGFzIGRlIGNoYVx1MDBFRW5lIGNvbW1lIGFyZ3VtZW50LiJ9LAotCi0gIHsgRVJfU0VUVElOR19XQUxLRVJfUk9PVF9UT19OVUxMLAotICAgICAgICJcbiBFcnJldXIuIERcdTAwRTlmaW5pdGlvbiBkZSBsYSByYWNpbmUgZCd1biBjb21wb3NhbnQgZCdleHBsb3JhdGlvbiBzdXIgTlVMTC4ifSwKLQotICB7IEVSX05PREVTRVREVE1fQ0FOTk9UX0lURVJBVEUsCi0gICAgICAgIkNlIE5vZGVTZXREVE0gbmUgcGVybWV0IHBhcyBkJ2l0XHUwMEU5cmF0aW9uIHZlcnMgdW4gbm9ldWQgcHJcdTAwRTljXHUwMEU5ZGVudC4ifSwKLQotICB7IEVSX05PREVTRVRfQ0FOTk9UX0lURVJBVEUsCi0gICAgICAgIkNlIE5vZGVTZXQgbmUgcGVybWV0IHBhcyBkJ2l0XHUwMEU5cmF0aW9uIHZlcnMgdW4gbm9ldWQgcHJcdTAwRTljXHUwMEU5ZGVudC4ifSwKLQotICB7IEVSX05PREVTRVREVE1fQ0FOTk9UX0lOREVYLAotICAgICAgICJDZSBOb2RlU2V0RFRNIG5lIHBldXQgcGFzIHV0aWxpc2VyIGRlIGZvbmN0aW9ucyBkJ2luZGV4YXRpb24gb3UgZGUgZFx1MDBFOWNvbXB0ZS4ifSwKLQotICB7IEVSX05PREVTRVRfQ0FOTk9UX0lOREVYLAotICAgICAgICJDZSBOb2RlU2V0IG5lIHBldXQgcGFzIHV0aWxpc2VyIGRlIGZvbmN0aW9ucyBkJ2luZGV4YXRpb24gb3UgZGUgZFx1MDBFOWNvbXB0ZS4ifSwKLQotICB7IEVSX0NBTk5PVF9DQUxMX1NFVFNIT1VMRENBQ0hFTk9ERSwKLSAgICAgICAiSW1wb3NzaWJsZSBkJ2FwcGVsZXIgc2V0U2hvdWxkQ2FjaGVOb2RlcyBhcHJcdTAwRThzIG5leHROb2RlLiJ9LAotCi0gIHsgRVJfT05MWV9BTExPV1MsCi0gICAgICAgInswfSBhY2NlcHRlIHVuaXF1ZW1lbnQgezF9IGFyZ3VtZW50cyJ9LAotCi0gIHsgRVJfVU5LTk9XTl9TVEVQLAotICAgICAgICJBc3NlcnRpb24gZHUgcHJvZ3JhbW1ldXIgZGFucyBnZXROZXh0U3RlcFBvcyA6IHN0ZXBUeXBlIGluY29ubnUgOiB7MH0ifSwKLQotICAvL05vdGUgdG8gdHJhbnNsYXRvcnM6ICBBIHJlbGF0aXZlIGxvY2F0aW9uIHBhdGggaXMgYSBmb3JtIG9mIFhQYXRoIGV4cHJlc3Npb24uCi0gIC8vIFRoZSBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHN1Y2ggYW4gZXhwcmVzc2lvbiB3YXMgZXhwZWN0ZWQgZm9sbG93aW5nIHRoZQotICAvLyBjaGFyYWN0ZXJzICcvJyBvciAnLy8nLCBidXQgd2FzIG5vdCBmb3VuZC4KLSAgeyBFUl9FWFBFQ1RFRF9SRUxfTE9DX1BBVEgsCi0gICAgICAiVW4gY2hlbWluIGQnYWNjXHUwMEU4cyByZWxhdGlmIFx1MDBFOXRhaXQgYXR0ZW5kdSBhcHJcdTAwRThzIGxlIGpldG9uICcvJyBvdSAnLy8nLiJ9LAotCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBIGxvY2F0aW9uIHBhdGggaXMgYSBmb3JtIG9mIFhQYXRoIGV4cHJlc3Npb24uCi0gIC8vIFRoZSBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHN5bnRhY3RpY2FsbHkgc3VjaCBhbiBleHByZXNzaW9uIHdhcyBleHBlY3RlZCxidXQKLSAgLy8gdGhlIGNoYXJhY3RlcnMgc3BlY2lmaWVkIGJ5IHRoZSBzdWJzdGl0dXRpb24gdGV4dCB3ZXJlIGVuY291bnRlcmVkIGluc3RlYWQuCi0gIHsgRVJfRVhQRUNURURfTE9DX1BBVEgsCi0gICAgICAgIlVuIGNoZW1pbiBkJydhY2NcdTAwRThzIFx1MDBFOXRhaXQgYXR0ZW5kdSwgbWFpcyBsZSBqZXRvbiBzdWl2YW50IGEgXHUwMEU5dFx1MDBFOSBkXHUwMEU5dGVjdFx1MDBFOSA6IHswfSJ9LAotCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBIGxvY2F0aW9uIHBhdGggaXMgYSBmb3JtIG9mIFhQYXRoIGV4cHJlc3Npb24uCi0gIC8vIFRoZSBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHN5bnRhY3RpY2FsbHkgc3VjaCBhIHN1YmV4cHJlc3Npb24gd2FzIGV4cGVjdGVkLAotICAvLyBidXQgbm8gbW9yZSBjaGFyYWN0ZXJzIHdlcmUgZm91bmQgaW4gdGhlIGV4cHJlc3Npb24uCi0gIHsgRVJfRVhQRUNURURfTE9DX1BBVEhfQVRfRU5EX0VYUFIsCi0gICAgICAgIlVuIGNoZW1pbiBkJ2FjY1x1MDBFOHMgXHUwMEU5dGFpdCBhdHRlbmR1LCBtYWlzIGxhIGZpbiBkZSBsJ2V4cHJlc3Npb24gWFBhdGggYSBcdTAwRTl0XHUwMEU5IGRcdTAwRTl0ZWN0XHUwMEU5ZSBcdTAwRTAgbGEgcGxhY2UuIn0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIEEgbG9jYXRpb24gc3RlcCBpcyBwYXJ0IG9mIGFuIFhQYXRoIGV4cHJlc3Npb24uCi0gIC8vIFRoZSBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHN5bnRhY3RpY2FsbHkgc3VjaCBhbiBleHByZXNzaW9uIHdhcyBleHBlY3RlZAotICAvLyBmb2xsb3dpbmcgdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXJzLgotICB7IEVSX0VYUEVDVEVEX0xPQ19TVEVQLAotICAgICAgICJVbmUgXHUwMEU5dGFwZSBkJ2VtcGxhY2VtZW50IFx1MDBFOXRhaXQgYXR0ZW5kdWUgYXByXHUwMEU4cyBsZSBqZXRvbiAnLycgb3UgJy8vJy4ifSwKLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQSBub2RlIHRlc3QgaXMgcGFydCBvZiBhbiBYUGF0aCBleHByZXNzaW9uIHRoYXQgaXMKLSAgLy8gdXNlZCB0byB0ZXN0IGZvciBwYXJ0aWN1bGFyIGtpbmRzIG9mIG5vZGVzLiAgSW4gdGhpcyBjYXNlLCBhIG5vZGUgdGVzdCB0aGF0Ci0gIC8vIGNvbnNpc3RzIG9mIGFuIE5DTmFtZSBmb2xsb3dlZCBieSBhIGNvbG9uIGFuZCBhbiBhc3RlcmlzayBvciB0aGF0IGNvbnNpc3RzCi0gIC8vIG9mIGEgUU5hbWUgd2FzIGV4cGVjdGVkLCBidXQgd2FzIG5vdCBmb3VuZC4KLSAgeyBFUl9FWFBFQ1RFRF9OT0RFX1RFU1QsCi0gICAgICAgIlVuIHRlc3QgZGUgbm9ldWQgY29ycmVzcG9uZGFudCBcdTAwRTAgTkNOYW1lOiogb3UgUU5hbWUgXHUwMEU5dGFpdCBhdHRlbmR1LiJ9LAotCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBIHN0ZXAgcGF0dGVybiBpcyBwYXJ0IG9mIGFuIFhQYXRoIGV4cHJlc3Npb24uCi0gIC8vIFRoZSBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHN5bnRhY3RpY2FsbHkgc3VjaCBhbiBleHByZXNzaW9uIHdhcyBleHBlY3RlZCwKLSAgLy8gYnV0IHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyIHdhcyBmb3VuZCBpbiB0aGUgZXhwcmVzc2lvbiBpbnN0ZWFkLgotICB7IEVSX0VYUEVDVEVEX1NURVBfUEFUVEVSTiwKLSAgICAgICAiVW4gbW9kXHUwMEU4bGUgZCdcdTAwRTl0YXBlIFx1MDBFOXRhaXQgYXR0ZW5kdSwgbWFpcyAnLycgYSBcdTAwRTl0XHUwMEU5IGRcdTAwRTl0ZWN0XHUwMEU5LiJ9LAotCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6IEEgcmVsYXRpdmUgcGF0aCBwYXR0ZXJuIGlzIHBhcnQgb2YgYW4gWFBhdGggZXhwcmVzc2lvbi4KLSAgLy8gVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgc3ludGFjdGljYWxseSBzdWNoIGFuIGV4cHJlc3Npb24gd2FzIGV4cGVjdGVkLAotICAvLyBidXQgd2FzIG5vdCBmb3VuZC4KLSAgeyBFUl9FWFBFQ1RFRF9SRUxfUEFUSF9QQVRURVJOLAotICAgICAgICJVbiBtb2RcdTAwRThsZSBkZSBjaGVtaW4gcmVsYXRpZiBcdTAwRTl0YWl0IGF0dGVuZHUuIn0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBhIGRhdGEgdHlwZS4gIFRoZQotICAvLyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IGEgdmFsdWUgb2YgYSBwYXJ0aWN1bGFyIHR5cGUgY291bGQgbm90IGJlIGNvbnZlcnRlZAotICAvLyB0byBhIHZhbHVlIG9mIHR5cGUgYm9vbGVhbi4KLSAgeyBFUl9DQU5UX0NPTlZFUlRfVE9fQk9PTEVBTiwKLSAgICAgICAiTCcnXHUwMEU5bFx1MDBFOW1lbnQgWFBhdGhSZXN1bHQgZGUgbCcnZXhwcmVzc2lvbiBYUGF0aCAnJ3swfScnIGNvbXBvcnRlIHVuIFx1MDBFOWxcdTAwRTltZW50IFhQYXRoUmVzdWx0VHlwZSBkZSB7MX0gcXVpIG5lIHBldXQgcGFzIFx1MDBFQXRyZSBjb252ZXJ0aSBlbiB2YWxldXIgYm9vbFx1MDBFOWVubmUuIn0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogRG8gbm90IHRyYW5zbGF0ZSBBTllfVU5PUkRFUkVEX05PREVfVFlQRSBhbmQKLSAgLy8gRklSU1RfT1JERVJFRF9OT0RFX1RZUEUuCi0gIHsgRVJfQ0FOVF9DT05WRVJUX1RPX1NJTkdMRU5PREUsCi0gICAgICAgIkwnJ1x1MDBFOWxcdTAwRTltZW50IFhQYXRoUmVzdWx0IGRlIGwnJ2V4cHJlc3Npb24gWFBhdGggJyd7MH0nJyBjb21wb3J0ZSB1biBcdTAwRTlsXHUwMEU5bWVudCBYUGF0aFJlc3VsdFR5cGUgZGUgezF9IHF1aSBuZSBwZXV0IHBhcyBcdTAwRUF0cmUgY29udmVydGkgZW4gbm9ldWQgdW5pcXVlLiBMYSBtXHUwMEU5dGhvZGUgZ2V0U2luZ2xlTm9kZVZhbHVlIGVzdCBhcHBsaWNhYmxlIHVuaXF1ZW1lbnQgYXV4IHR5cGVzIEFOWV9VTk9SREVSRURfTk9ERV9UWVBFIGV0IEZJUlNUX09SREVSRURfTk9ERV9UWVBFLiJ9LAotCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6IERvIG5vdCB0cmFuc2xhdGUgVU5PUkRFUkVEX05PREVfU05BUFNIT1RfVFlQRSBhbmQKLSAgLy8gT1JERVJFRF9OT0RFX1NOQVBTSE9UX1RZUEUuCi0gIHsgRVJfQ0FOVF9HRVRfU05BUFNIT1RfTEVOR1RILAotICAgICAgICJMYSBtXHUwMEU5dGhvZGUgZ2V0U25hcHNob3RMZW5ndGggbmUgcGV1dCBwYXMgXHUwMEVBdHJlIGFwcGVsXHUwMEU5ZSBzdXIgbCcnXHUwMEU5bFx1MDBFOW1lbnQgWFBhdGhSZXN1bHQgZGUgbCcnZXhwcmVzc2lvbiBYUGF0aCAnJ3swfScnIGNhciBzb24gXHUwMEU5bFx1MDBFOW1lbnQgWFBhdGhSZXN1bHRUeXBlIGVzdCB7MX0uIENldHRlIG1cdTAwRTl0aG9kZSBlc3QgYXBwbGljYWJsZSB1bmlxdWVtZW50IGF1eCB0eXBlcyBVTk9SREVSRURfTk9ERV9TTkFQU0hPVF9UWVBFIGV0IE9SREVSRURfTk9ERV9TTkFQU0hPVF9UWVBFLiJ9LAotCi0gIHsgRVJfTk9OX0lURVJBVE9SX1RZUEUsCi0gICAgICAgIkxhIG1cdTAwRTl0aG9kZSBpdGVyYXRlTmV4dCBuZSBwZXV0IHBhcyBcdTAwRUF0cmUgYXBwZWxcdTAwRTllIHN1ciBsJydcdTAwRTlsXHUwMEU5bWVudCBYUGF0aFJlc3VsdCBkZSBsJydleHByZXNzaW9uIFhQYXRoICcnezB9JycgY2FyIHNvbiBcdTAwRTlsXHUwMEU5bWVudCBYUGF0aFJlc3VsdFR5cGUgZXN0IHsxfS4gQ2V0dGUgbVx1MDBFOXRob2RlIGVzdCBhcHBsaWNhYmxlIHVuaXF1ZW1lbnQgYXV4IHR5cGVzIFVOT1JERVJFRF9OT0RFX0lURVJBVE9SX1RZUEUgZXQgT1JERVJFRF9OT0RFX0lURVJBVE9SX1RZUEUuIn0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogVGhpcyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoZSBkb2N1bWVudCBiZWluZyBvcGVyYXRlZAotICAvLyB1cG9uIGNoYW5nZWQsIHNvIHRoZSBpdGVyYXRvciBvYmplY3QgdGhhdCB3YXMgYmVpbmcgdXNlZCB0byB0cmF2ZXJzZSB0aGUKLSAgLy8gZG9jdW1lbnQgaGFzIG5vdyBiZWNvbWUgaW52YWxpZC4KLSAgeyBFUl9ET0NfTVVUQVRFRCwKLSAgICAgICAiTXV0YXRpb24gZHUgZG9jdW1lbnQgc3VpdGUgYXUgcmVudm9pIGR1IHJcdTAwRTlzdWx0YXQuIEwnaXRcdTAwRTlyYXRldXIgZXN0IGluY29ycmVjdC4ifSwKLQotICB7IEVSX0lOVkFMSURfWFBBVEhfVFlQRSwKLSAgICAgICAiQXJndW1lbnQgZGUgdHlwZSBYUGF0aCBpbmNvcnJlY3QgOiB7MH0ifSwKLQotICB7IEVSX0VNUFRZX1hQQVRIX1JFU1VMVCwKLSAgICAgICAiT2JqZXQgZGUgclx1MDBFOXN1bHRhdCBYUGF0aCB2aWRlIn0sCi0KLSAgeyBFUl9JTkNPTVBBVElCTEVfVFlQRVMsCi0gICAgICAgIkwnJ1x1MDBFOWxcdTAwRTltZW50IFhQYXRoUmVzdWx0IGRlIGwnJ2V4cHJlc3Npb24gWFBhdGggJyd7MH0nJyBjb21wb3J0ZSB1biBcdTAwRTlsXHUwMEU5bWVudCBYUGF0aFJlc3VsdFR5cGUgZGUgezF9IHF1aSBuZSBwZXV0IHBhcyBcdTAwRUF0cmUgZm9yY1x1MDBFOSBkYW5zIGwnJ1x1MDBFOWxcdTAwRTltZW50IFhQYXRoUmVzdWx0VHlwZSBkZSB7Mn0gaW5kaXF1XHUwMEU5LiJ9LAotCi0gIHsgRVJfTlVMTF9SRVNPTFZFUiwKLSAgICAgICAiSW1wb3NzaWJsZSBkZSByXHUwMEU5c291ZHJlIGxlIHByXHUwMEU5Zml4ZSBhdmVjIHVuIHJcdTAwRTlzb2x2ZXVyIGRlIHByXHUwMEU5Zml4ZSBOVUxMLiJ9LAotCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYSBkYXRhIHR5cGUuICBUaGUKLSAgLy8gbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCBhIHZhbHVlIG9mIGEgcGFydGljdWxhciB0eXBlIGNvdWxkIG5vdCBiZSBjb252ZXJ0ZWQKLSAgLy8gdG8gYSB2YWx1ZSBvZiB0eXBlIHN0cmluZy4KLSAgeyBFUl9DQU5UX0NPTlZFUlRfVE9fU1RSSU5HLAotICAgICAgICJMJydcdTAwRTlsXHUwMEU5bWVudCBYUGF0aFJlc3VsdCBkZSBsJydleHByZXNzaW9uIFhQYXRoICcnezB9JycgY29tcG9ydGUgdW4gXHUwMEU5bFx1MDBFOW1lbnQgWFBhdGhSZXN1bHRUeXBlIGRlIHsxfSBxdWkgbmUgcGV1dCBwYXMgXHUwMEVBdHJlIGNvbnZlcnRpIGVuIGNoYVx1MDBFRW5lLiJ9LAotCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6IERvIG5vdCB0cmFuc2xhdGUgc25hcHNob3RJdGVtLAotICAvLyBVTk9SREVSRURfTk9ERV9TTkFQU0hPVF9UWVBFIGFuZCBPUkRFUkVEX05PREVfU05BUFNIT1RfVFlQRS4KLSAgeyBFUl9OT05fU05BUFNIT1RfVFlQRSwKLSAgICAgICAiTGEgbVx1MDBFOXRob2RlIHNuYXBzaG90SXRlbSBuZSBwZXV0IHBhcyBcdTAwRUF0cmUgYXBwZWxcdTAwRTllIHN1ciBsJydcdTAwRTlsXHUwMEU5bWVudCBYUGF0aFJlc3VsdCBkZSBsJydleHByZXNzaW9uIFhQYXRoICcnezB9JycgY2FyIHNvbiBcdTAwRTlsXHUwMEU5bWVudCBYUGF0aFJlc3VsdFR5cGUgZXN0IHsxfS4gQ2V0dGUgbVx1MDBFOXRob2RlIGVzdCBhcHBsaWNhYmxlIHVuaXF1ZW1lbnQgYXV4IHR5cGVzIFVOT1JERVJFRF9OT0RFX1NOQVBTSE9UX1RZUEUgZXQgT1JERVJFRF9OT0RFX1NOQVBTSE9UX1RZUEUuIn0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFhQYXRoRXZhbHVhdG9yIGlzIGEgSmF2YSBpbnRlcmZhY2UgbmFtZS4gIEFuCi0gIC8vIFhQYXRoRXZhbHVhdG9yIGlzIGNyZWF0ZWQgd2l0aCByZXNwZWN0IHRvIGEgcGFydGljdWxhciBYTUwgZG9jdW1lbnQsIGFuZCBpbgotICAvLyB0aGlzIGNhc2UgdGhlIGV4cHJlc3Npb24gcmVwcmVzZW50ZWQgYnkgdGhpcyBvYmplY3Qgd2FzIGJlaW5nIGV2YWx1YXRlZCB3aXRoCi0gIC8vIHJlc3BlY3QgdG8gYSBjb250ZXh0IG5vZGUgZnJvbSBhIGRpZmZlcmVudCBkb2N1bWVudC4KLSAgeyBFUl9XUk9OR19ET0NVTUVOVCwKLSAgICAgICAiTGUgbm9ldWQgZGUgY29udGV4dGUgbidhcHBhcnRpZW50IHBhcyBhdSBkb2N1bWVudCBsaVx1MDBFOSBcdTAwRTAgY2UgWFBhdGhFdmFsdWF0b3IuIn0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBYUGF0aCBleHByZXNzaW9uIGNhbm5vdCBiZSBldmFsdWF0ZWQgd2l0aCByZXNwZWN0Ci0gIC8vIHRvIHRoaXMgdHlwZSBvZiBub2RlLgotICB7IEVSX1dST05HX05PREVUWVBFLAotICAgICAgICJMZSB0eXBlIGRlIG5vZXVkIGRlIGNvbnRleHRlIG4nZXN0IHBhcyBwcmlzIGVuIGNoYXJnZS4ifSwKLQotICB7IEVSX1hQQVRIX0VSUk9SLAotICAgICAgICJFcnJldXIgaW5jb25udWUgZFx1MDBFOXRlY3RcdTAwRTllIGRhbnMgWFBhdGguIn0sCi0KLSAgeyBFUl9DQU5UX0NPTlZFUlRfWFBBVEhSRVNVTFRUWVBFX1RPX05VTUJFUiwKLSAgICAgICAgIkwnJ1x1MDBFOWxcdTAwRTltZW50IFhQYXRoUmVzdWx0IGRlIGwnJ2V4cHJlc3Npb24gWFBhdGggJyd7MH0nJyBjb21wb3J0ZSB1biBcdTAwRTlsXHUwMEU5bWVudCBYUGF0aFJlc3VsdFR5cGUgZGUgezF9IHF1aSBuZSBwZXV0IHBhcyBcdTAwRUF0cmUgY29udmVydGkgZW4gbm9tYnJlIn0sCi0KLSAgLy9CRUdJTjogIERlZmluaXRpb25zIG9mIGVycm9yIGtleXMgdXNlZCAgaW4gZXhjZXB0aW9uIG1lc3NhZ2VzIG9mICBKQVhQIDEuMyBYUGF0aCBBUEkgaW1wbGVtZW50YXRpb24KLQotICAvKiogRmllbGQgRVJfRVhURU5TSU9OX0ZVTkNUSU9OX0NBTk5PVF9CRV9JTlZPS0VEICAgICAgICAgICAgICAgICAgICAgICAqLwotCi0gIHsgRVJfRVhURU5TSU9OX0ZVTkNUSU9OX0NBTk5PVF9CRV9JTlZPS0VELAotICAgICAgICJMYSBmb25jdGlvbiBkJydleHRlbnNpb24gJyd7MH0nJyBuZSBwZXV0IHBhcyBcdTAwRUF0cmUgYXBwZWxcdTAwRTllIGxvcnNxdWUgbGEgZm9uY3Rpb25uYWxpdFx1MDBFOSBYTUxDb25zdGFudHMuRkVBVFVSRV9TRUNVUkVfUFJPQ0VTU0lORyBlc3QgZFx1MDBFOWZpbmllIHN1ciBUcnVlLiJ9LAotCi0gIC8qKiBGaWVsZCBFUl9SRVNPTFZFX1ZBUklBQkxFX1JFVFVSTlNfTlVMTCAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX1JFU09MVkVfVkFSSUFCTEVfUkVUVVJOU19OVUxMLAotICAgICAgICJyZXNvbHZlVmFyaWFibGUgcG91ciBsYSB2YXJpYWJsZSB7MH0gcmVudm9pZSBsYSB2YWxldXIgTlVMTCJ9LAotCi0gIC8qKiBGaWVsZCBFUl9VTlNVUFBPUlRFRF9SRVRVUk5fVFlQRSAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX1VOU1VQUE9SVEVEX1JFVFVSTl9UWVBFLAotICAgICAgICJUeXBlIGRlIHJldG91ciBub24gcHJpcyBlbiBjaGFyZ2UgOiB7MH0ifSwKLQotICAvKiogRmllbGQgRVJfU09VUkNFX1JFVFVSTl9UWVBFX0NBTk5PVF9CRV9OVUxMICAgICAgICAgICAgICAgICAgICAgICAqLwotCi0gIHsgRVJfU09VUkNFX1JFVFVSTl9UWVBFX0NBTk5PVF9CRV9OVUxMLAotICAgICAgICJMZSB0eXBlIGRlIHNvdXJjZSBldC9vdSBkZSByZXRvdXIgbmUgcGV1dCBwYXMgXHUwMEVBdHJlIE5VTEwifSwKLQotICAvKiogRmllbGQgRVJfU09VUkNFX1JFVFVSTl9UWVBFX0NBTk5PVF9CRV9OVUxMICAgICAgICAgICAgICAgICAgICAgICAqLwotCi0gIHsgRVJfU09VUkNFX1JFVFVSTl9UWVBFX0NBTk5PVF9CRV9OVUxMLAotICAgICAgICJMZSB0eXBlIGRlIHNvdXJjZSBldC9vdSBkZSByZXRvdXIgbmUgcGV1dCBwYXMgXHUwMEVBdHJlIE5VTEwifSwKLQotICAvKiogRmllbGQgRVJfQVJHX0NBTk5PVF9CRV9OVUxMICAgICAgICAgICAgICAgICAgICAgICAqLwotCi0gIHsgRVJfQVJHX0NBTk5PVF9CRV9OVUxMLAotICAgICAgICJMJydhcmd1bWVudCB7MH0gbmUgZG9pdCBwYXMgXHUwMEVBdHJlIE5VTEwifSwKLQotICAvKiogRmllbGQgRVJfT0JKRUNUX01PREVMX05VTEwgICAgICAgICAgICAgICAgICAgICAgICovCi0KLSAgeyBFUl9PQkpFQ1RfTU9ERUxfTlVMTCwKLSAgICAgICAiezB9I2lzT2JqZWN0TW9kZWxTdXBwb3J0ZWQoU3RyaW5nIG9iamVjdE1vZGVsKSBuZSBwZXV0IHBhcyBcdTAwRUF0cmUgYXBwZWxcdTAwRTkgYXZlYyBvYmplY3RNb2RlbCA9PSBudWxsIn0sCi0KLSAgLyoqIEZpZWxkIEVSX09CSkVDVF9NT0RFTF9FTVBUWSAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX09CSkVDVF9NT0RFTF9FTVBUWSwKLSAgICAgICAiezB9I2lzT2JqZWN0TW9kZWxTdXBwb3J0ZWQoU3RyaW5nIG9iamVjdE1vZGVsKSBuZSBwZXV0IHBhcyBcdTAwRUF0cmUgYXBwZWxcdTAwRTkgYXZlYyBvYmplY3RNb2RlbCA9PSBcIlwiIn0sCi0KLSAgLyoqIEZpZWxkIEVSX09CSkVDVF9NT0RFTF9FTVBUWSAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX0ZFQVRVUkVfTkFNRV9OVUxMLAotICAgICAgICJUZW50YXRpdmUgZGUgZFx1MDBFOWZpbml0aW9uIGQnJ3VuZSBmb25jdGlvbm5hbGl0XHUwMEU5IHBvcnRhbnQgdW4gbm9tIE5VTEwgOiB7MH0jc2V0RmVhdHVyZShudWxsLCB7MX0pIn0sCi0KLSAgLyoqIEZpZWxkIEVSX0ZFQVRVUkVfVU5LTk9XTiAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX0ZFQVRVUkVfVU5LTk9XTiwKLSAgICAgICAiVGVudGF0aXZlIGRlIGRcdTAwRTlmaW5pdGlvbiBkZSBsYSBmb25jdGlvbm5hbGl0XHUwMEU5IGluY29ubnVlIFwiezB9XCIgOiB7MX0jc2V0RmVhdHVyZSh7MH0sezJ9KSJ9LAotCi0gIC8qKiBGaWVsZCBFUl9HRVRUSU5HX05VTExfRkVBVFVSRSAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX0dFVFRJTkdfTlVMTF9GRUFUVVJFLAotICAgICAgICJUZW50YXRpdmUgZCcnb2J0ZW50aW9uIGQnJ3VuZSBmb25jdGlvbm5hbGl0XHUwMEU5IHBvcnRhbnQgdW4gbm9tIE5VTEwgOiB7MH0jZ2V0RmVhdHVyZShudWxsKSJ9LAotCi0gIC8qKiBGaWVsZCBFUl9HRVRUSU5HX05VTExfRkVBVFVSRSAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX0dFVFRJTkdfVU5LTk9XTl9GRUFUVVJFLAotICAgICAgICJUZW50YXRpdmUgZCcnb2J0ZW50aW9uIGRlIGxhIGZvbmN0aW9ubmFsaXRcdTAwRTkgaW5jb25udWUgXCJ7MH1cIiA6IHsxfSNnZXRGZWF0dXJlKHswfSkifSwKLQotICB7RVJfU0VDVVJFUFJPQ0VTU0lOR19GRUFUVVJFLAotICAgICAgICAiRkVBVFVSRV9TRUNVUkVfUFJPQ0VTU0lORyA6IGltcG9zc2libGUgZGUgZFx1MDBFOWZpbmlyIGxhIGZvbmN0aW9ubmFsaXRcdTAwRTkgc3VyIEZhbHNlIGVuIHByXHUwMEU5c2VuY2UgZHUgZ2VzdGlvbm5haXJlIGRlIHNcdTAwRTljdXJpdFx1MDBFOSA6IHsxfSNzZXRGZWF0dXJlKHswfSx7Mn0pIn0sCi0KLSAgLyoqIEZpZWxkIEVSX05VTExfWFBBVEhfRlVOQ1RJT05fUkVTT0xWRVIgICAgICAgICAgICAgICAgICAgICAgICovCi0KLSAgeyBFUl9OVUxMX1hQQVRIX0ZVTkNUSU9OX1JFU09MVkVSLAotICAgICAgICJUZW50YXRpdmUgZGUgZFx1MDBFOWZpbml0aW9uIGQnJ3VuIFx1MDBFOWxcdTAwRTltZW50IFhQYXRoRnVuY3Rpb25SZXNvbHZlciBOVUxMIDogezB9I3NldFhQYXRoRnVuY3Rpb25SZXNvbHZlcihudWxsKSJ9LAotCi0gIC8qKiBGaWVsZCBFUl9OVUxMX1hQQVRIX1ZBUklBQkxFX1JFU09MVkVSICAgICAgICAgICAgICAgICAgICAgICAqLwotCi0gIHsgRVJfTlVMTF9YUEFUSF9WQVJJQUJMRV9SRVNPTFZFUiwKLSAgICAgICAiVGVudGF0aXZlIGRlIGRcdTAwRTlmaW5pdGlvbiBkJyd1biBcdTAwRTlsXHUwMEU5bWVudCBYUGF0aFZhcmlhYmxlUmVzb2x2ZXIgTlVMTCA6IHswfSNzZXRYUGF0aFZhcmlhYmxlUmVzb2x2ZXIobnVsbCkifSwKLQotICAvL0VORDogIERlZmluaXRpb25zIG9mIGVycm9yIGtleXMgdXNlZCAgaW4gZXhjZXB0aW9uIG1lc3NhZ2VzIG9mICBKQVhQIDEuMyBYUGF0aCBBUEkgaW1wbGVtZW50YXRpb24KLQotICAvLyBXYXJuaW5ncy4uLgotCi0gIHsgV0dfTE9DQUxFX05BTUVfTk9UX0hBTkRMRUQsCi0gICAgICAibGUgbm9tIGQnZW52aXJvbm5lbWVudCBsb2NhbCBkZSBsYSBmb25jdGlvbiBmb3JtYXQtbnVtYmVyIG4nZXN0IHBhcyBlbmNvcmUgcHJpcyBlbiBjaGFyZ2UuIn0sCi0KLSAgeyBXR19QUk9QRVJUWV9OT1RfU1VQUE9SVEVELAotICAgICAgIlByb3ByaVx1MDBFOXRcdTAwRTkgWFNMIG5vbiBwcmlzZSBlbiBjaGFyZ2UgOiB7MH0ifSwKLQotICB7IFdHX0RPTlRfRE9fQU5ZVEhJTkdfV0lUSF9OUywKLSAgICAgICJFc3BhY2UgZGUgbm9tcyB7MH0gaW5leHBsb2l0YWJsZSBkYW5zIGxhIHByb3ByaVx1MDBFOXRcdTAwRTkgOiB7MX0ifSwKLQotICB7IFdHX1NFQ1VSSVRZX0VYQ0VQVElPTiwKLSAgICAgICJFeGNlcHRpb24gU2VjdXJpdHlFeGNlcHRpb24gZ1x1MDBFOW5cdTAwRTlyXHUwMEU5ZSBsb3JzIGRlIGxhIHRlbnRhdGl2ZSBkJydhY2NcdTAwRThzIFx1MDBFMCBsYSBwcm9wcmlcdTAwRTl0XHUwMEU5IHN5c3RcdTAwRThtZSBYU0wgOiB7MH0ifSwKLQotICB7IFdHX1FVT19OT19MT05HRVJfREVGSU5FRCwKLSAgICAgICJMJ2FuY2llbm5lIHN5bnRheGUgcXVvKC4uLikgbidlc3QgcGx1cyBkXHUwMEU5ZmluaWUgZGFucyBYUGF0aC4ifSwKLQotICB7IFdHX05FRURfREVSSVZFRF9PQkpFQ1RfVE9fSU1QTEVNRU5UX05PREVURVNULAotICAgICAgIlhQYXRoIHJlcXVpZXJ0IHVuIG9iamV0IGRcdTAwRTlyaXZcdTAwRTkgcG91ciBpbXBsXHUwMEU5bWVudGVyIG5vZGVUZXN0LiJ9LAotCi0gIHsgV0dfRlVOQ1RJT05fVE9LRU5fTk9UX0ZPVU5ELAotICAgICAgImpldG9uIGRlIGZvbmN0aW9uIGludHJvdXZhYmxlLiJ9LAotCi0gIHsgV0dfQ09VTEROT1RfRklORF9GVU5DVElPTiwKLSAgICAgICJJbXBvc3NpYmxlIGRlIHRyb3V2ZXIgbGEgZm9uY3Rpb24gOiB7MH0ifSwKLQotICB7IFdHX0NBTk5PVF9NQUtFX1VSTF9GUk9NLAotICAgICAgIkltcG9zc2libGUgZGUgY3JcdTAwRTllciBsJydVUkwgXHUwMEUwIHBhcnRpciBkZSA6IHswfSJ9LAotCi0gIHsgV0dfRVhQQU5EX0VOVElUSUVTX05PVF9TVVBQT1JURUQsCi0gICAgICAiTCdvcHRpb24gLUUgbidlc3QgcGFzIHByaXNlIGVuIGNoYXJnZSBwb3VyIGwnYW5hbHlzZXVyIERUTSJ9LAotCi0gIHsgV0dfSUxMRUdBTF9WQVJJQUJMRV9SRUZFUkVOQ0UsCi0gICAgICAiTCcnXHUwMEU5bFx1MDBFOW1lbnQgVmFyaWFibGVSZWZlcmVuY2UgaW5kaXF1XHUwMEU5IHBvdXIgbGEgdmFyaWFibGUgZXN0IGhvcnMgY29udGV4dGUgb3Ugc2FucyBkXHUwMEU5ZmluaXRpb24uIE5vbSA9IHswfSJ9LAotCi0gIHsgV0dfVU5TVVBQT1JURURfRU5DT0RJTkcsCi0gICAgICJFbmNvZGFnZSBub24gcHJpcyBlbiBjaGFyZ2UgOiB7MH0ifSwKLQotCi0KLSAgLy8gT3RoZXIgbWlzY2VsbGFuZW91cyB0ZXh0IHVzZWQgaW5zaWRlIHRoZSBjb2RlLi4uCi0gIHsgInVpX2xhbmd1YWdlIiwgImZyIn0sCi0gIHsgImhlbHBfbGFuZ3VhZ2UiLCAiZnIifSwKLSAgeyAibGFuZ3VhZ2UiLCAiZnIifSwKLSAgeyAiQkFEX0NPREUiLCAiTGUgcGFyYW1cdTAwRTh0cmUgZGUgY3JlYXRlTWVzc2FnZSBlc3QgaG9ycyBsaW1pdGVzIn0sCi0gIHsgIkZPUk1BVF9GQUlMRUQiLCAiRXhjZXB0aW9uIGdcdTAwRTluXHUwMEU5clx1MDBFOWUgbG9ycyBkZSBsJ2FwcGVsIGRlIG1lc3NhZ2VGb3JtYXQifSwKLSAgeyAidmVyc2lvbiIsICI+Pj4+Pj4+IFZlcnNpb24gZGUgWGFsYW4gIn0sCi0gIHsgInZlcnNpb24yIiwgIjw8PDw8PDwifSwKLSAgeyAieWVzIiwgIm91aSJ9LAotICB7ICJsaW5lIiwgIkxpZ25lIG5cdTAwQjAifSwKLSAgeyAiY29sdW1uIiwgIkNvbG9ubmUgblx1MDBCMCJ9LAotICB7ICJ4c2xkb25lIiwgIlhTTFByb2Nlc3NvciA6IHRlcm1pblx1MDBFOSJ9LAotICB7ICJ4cGF0aF9vcHRpb24iLCAib3B0aW9ucyB4cGF0aCA6ICJ9LAotICB7ICJvcHRpb25JTiIsICIgICBbLWluIGlucHV0WE1MVVJMXSJ9LAotICB7ICJvcHRpb25TZWxlY3QiLCAiICAgWy1zZWxlY3QgeHBhdGggZXhwcmVzc2lvbl0ifSwKLSAgeyAib3B0aW9uTWF0Y2giLCAiICAgWy1tYXRjaCBtYXRjaCBwYXR0ZXJuIChwb3VyIGxlcyBkaWFnbm9zdGljcyBkZSBjb3JyZXNwb25kYW5jZSldIn0sCi0gIHsgIm9wdGlvbkFueUV4cHIiLCAiT3Ugc2V1bGVtZW50IHVuZSBleHByZXNzaW9uIFhQYXRoIGdcdTAwRTluXHUwMEU5cmVyYSB1biBmaWNoaWVyIGR1bXAgZGUgZGlhZ25vc3RpYyJ9LAotICB7ICJub1BhcnNlcm1zZzEiLCAiRWNoZWMgZHUgcHJvY2Vzc3VzIFhTTC4ifSwKLSAgeyAibm9QYXJzZXJtc2cyIiwgIioqIEFuYWx5c2V1ciBpbnRyb3V2YWJsZSAqKiJ9LAotICB7ICJub1BhcnNlcm1zZzMiLCAiVlx1MDBFOXJpZmlleiB2b3RyZSB2YXJpYWJsZSBkJ2Vudmlyb25uZW1lbnQgQ0xBU1NQQVRILiJ9LAotICB7ICJub1BhcnNlcm1zZzQiLCAiU2kgdm91cyBuZSBkaXNwb3NleiBwYXMgZGUgbCdhbmFseXNldXIgWE1MIHBvdXIgSmF2YSBkJ0lCTSwgdm91cyBwb3V2ZXogbGUgdFx1MDBFOWxcdTAwRTljaGFyZ2VyIHN1ciBsZSBzaXRlIn0sCi0gIHsgIm5vUGFyc2VybXNnNSIsICJBbHBoYVdvcmtzIGQnSUJNIDogaHR0cDovL3d3dy5hbHBoYXdvcmtzLmlibS5jb20vZm9ybXVsYS94bWwifSwKLSAgeyAiZ3RvbmUiLCAiPjEiIH0sCi0gIHsgInplcm8iLCAiMCIgfSwKLSAgeyAib25lIiwgIjEiIH0sCi0gIHsgInR3byIgLCAiMiIgfSwKLSAgeyAidGhyZWUiLCAiMyIgfQotCi0gIH07Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgYXNzb2NpYXRpb24gbGlzdC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgYXNzb2NpYXRpb24gbGlzdC4KLSAgICovCi0gIHB1YmxpYyBPYmplY3RbXVtdIGdldENvbnRlbnRzKCkKLSAgewotICAgICAgcmV0dXJuIF9jb250ZW50czsKLSAgfQotCi0KLSAgLy8gPT09PT09PT09PT09PT09PT0gSU5GUkFTVFJVQ1RVUkUgPT09PT09PT09PT09PT09PT09PT09PQotCi0gIC8qKiBGaWVsZCBCQURfQ09ERSAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBCQURfQ09ERSA9ICJCQURfQ09ERSI7Ci0KLSAgLyoqIEZpZWxkIEZPUk1BVF9GQUlMRUQgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRk9STUFUX0ZBSUxFRCA9ICJGT1JNQVRfRkFJTEVEIjsKLQotICAvKiogRmllbGQgRVJST1JfUkVTT1VSQ0VTICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUk9SX1JFU09VUkNFUyA9Ci0gICAgImNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5yZXMuWFBBVEhFcnJvclJlc291cmNlcyI7Ci0KLSAgLyoqIEZpZWxkIEVSUk9SX1NUUklORyAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJPUl9TVFJJTkcgPSAiI2Vycm9yIjsKLQotICAvKiogRmllbGQgRVJST1JfSEVBREVSICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUk9SX0hFQURFUiA9ICJFcnJvcjogIjsKLQotICAvKiogRmllbGQgV0FSTklOR19IRUFERVIgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0FSTklOR19IRUFERVIgPSAiV2FybmluZzogIjsKLQotICAvKiogRmllbGQgWFNMX0hFQURFUiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBYU0xfSEVBREVSID0gIlhTTCAiOwotCi0gIC8qKiBGaWVsZCBYTUxfSEVBREVSICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFhNTF9IRUFERVIgPSAiWE1MICI7Ci0KLSAgLyoqIEZpZWxkIFFVRVJZX0hFQURFUiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBRVUVSWV9IRUFERVIgPSAiUEFUVEVSTiAiOwotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL3Jlcy9YUEFUSEVycm9yUmVzb3VyY2VzX2l0LmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL3Jlcy9YUEFUSEVycm9yUmVzb3VyY2VzX2l0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDJmMjdkZGIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9yZXMvWFBBVEhFcnJvclJlc291cmNlc19pdC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTM2ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLnJlczsKLQotaW1wb3J0IGphdmEudXRpbC5MaXN0UmVzb3VyY2VCdW5kbGU7Ci0KLS8qKgotICogU2V0IHVwIGVycm9yIG1lc3NhZ2VzLgotICogV2UgYnVpbGQgYSB0d28gZGltZW5zaW9uYWwgYXJyYXkgb2YgbWVzc2FnZSBrZXlzIGFuZAotICogbWVzc2FnZSBzdHJpbmdzLiBJbiBvcmRlciB0byBhZGQgYSBuZXcgbWVzc2FnZSBoZXJlLAotICogeW91IG5lZWQgdG8gZmlyc3QgYWRkIGEgU3RhdGljIHN0cmluZyBjb25zdGFudCBmb3IgdGhlCi0gKiBLZXkgYW5kIHVwZGF0ZSB0aGUgY29udGVudHMgYXJyYXkgd2l0aCBLZXksIFZhbHVlIHBhaXIKLSAgKiBBbHNvIHlvdSBuZWVkIHRvICB1cGRhdGUgdGhlIGNvdW50IG9mIG1lc3NhZ2VzKE1BWF9DT0RFKW9yCi0gKiB0aGUgY291bnQgb2Ygd2FybmluZ3MoTUFYX1dBUk5JTkcpIFsgSW5mb3JtYXRpb24gcHVycG9zZSBvbmx5XQotICogQHhzbC51c2FnZSBhZHZhbmNlZAotICovCi1wdWJsaWMgY2xhc3MgWFBBVEhFcnJvclJlc291cmNlc19pdCBleHRlbmRzIExpc3RSZXNvdXJjZUJ1bmRsZQotewotCi0vKgotICogR2VuZXJhbCBub3RlcyB0byB0cmFuc2xhdG9yczoKLSAqCi0gKiBUaGlzIGZpbGUgY29udGFpbnMgZXJyb3IgYW5kIHdhcm5pbmcgbWVzc2FnZXMgcmVsYXRlZCB0byBYUGF0aCBFcnJvcgotICogSGFuZGxpbmcuCi0gKgotICogIDEpIFhhbGFuIChvciBtb3JlIHByb3Blcmx5LCBYYWxhbi1pbnRlcnByZXRpdmUpIGFuZCBYU0xUQyBhcmUgbmFtZXMgb2YKLSAqICAgICBjb21wb25lbnRzLgotICogICAgIFhTTFQgaXMgYW4gYWNyb255bSBmb3IgIlhNTCBTdHlsZXNoZWV0IExhbmd1YWdlOiBUcmFuc2Zvcm1hdGlvbnMiLgotICogICAgIFhTTFRDIGlzIGFuIGFjcm9ueW0gZm9yIFhTTFQgQ29tcGlsZXIuCi0gKgotICogIDIpIEEgc3R5bGVzaGVldCBpcyBhIGRlc2NyaXB0aW9uIG9mIGhvdyB0byB0cmFuc2Zvcm0gYW4gaW5wdXQgWE1MIGRvY3VtZW50Ci0gKiAgICAgaW50byBhIHJlc3VsdGFudCBYTUwgZG9jdW1lbnQgKG9yIEhUTUwgZG9jdW1lbnQgb3IgdGV4dCkuICBUaGUKLSAqICAgICBzdHlsZXNoZWV0IGl0c2VsZiBpcyBkZXNjcmliZWQgaW4gdGhlIGZvcm0gb2YgYW4gWE1MIGRvY3VtZW50LgotICoKLSAqICAzKSBBIHRlbXBsYXRlIGlzIGEgY29tcG9uZW50IG9mIGEgc3R5bGVzaGVldCB0aGF0IGlzIHVzZWQgdG8gbWF0Y2ggYQotICogICAgIHBhcnRpY3VsYXIgcG9ydGlvbiBvZiBhbiBpbnB1dCBkb2N1bWVudCBhbmQgc3BlY2lmaWVzIHRoZSBmb3JtIG9mIHRoZQotICogICAgIGNvcnJlc3BvbmRpbmcgcG9ydGlvbiBvZiB0aGUgb3V0cHV0IGRvY3VtZW50LgotICoKLSAqICA0KSBBbiBlbGVtZW50IGlzIGEgbWFyay11cCB0YWcgaW4gYW4gWE1MIGRvY3VtZW50OyBhbiBhdHRyaWJ1dGUgaXMgYQotICogICAgIG1vZGlmaWVyIG9uIHRoZSB0YWcuICBGb3IgZXhhbXBsZSwgaW4gPGVsZW0gYXR0cj0ndmFsJyBhdHRyMj0ndmFsMic+Ci0gKiAgICAgImVsZW0iIGlzIGFuIGVsZW1lbnQgbmFtZSwgImF0dHIiIGFuZCAiYXR0cjIiIGFyZSBhdHRyaWJ1dGUgbmFtZXMgd2l0aAotICogICAgIHRoZSB2YWx1ZXMgInZhbCIgYW5kICJ2YWwyIiwgcmVzcGVjdGl2ZWx5LgotICoKLSAqICA1KSBBIG5hbWVzcGFjZSBkZWNsYXJhdGlvbiBpcyBhIHNwZWNpYWwgYXR0cmlidXRlIHRoYXQgaXMgdXNlZCB0byBhc3NvY2lhdGUKLSAqICAgICBhIHByZWZpeCB3aXRoIGEgVVJJICh0aGUgbmFtZXNwYWNlKS4gIFRoZSBtZWFuaW5ncyBvZiBlbGVtZW50IG5hbWVzIGFuZAotICogICAgIGF0dHJpYnV0ZSBuYW1lcyB0aGF0IHVzZSB0aGF0IHByZWZpeCBhcmUgZGVmaW5lZCB3aXRoIHJlc3BlY3QgdG8gdGhhdAotICogICAgIG5hbWVzcGFjZS4KLSAqCi0gKiAgNikgIlRyYW5zbGV0IiBpcyBhbiBpbnZlbnRlZCB0ZXJtIHRoYXQgZGVzY3JpYmVzIHRoZSBjbGFzcyBmaWxlIHRoYXQKLSAqICAgICByZXN1bHRzIGZyb20gY29tcGlsaW5nIGFuIFhNTCBzdHlsZXNoZWV0IGludG8gYSBKYXZhIGNsYXNzLgotICoKLSAqICA3KSBYUGF0aCBpcyBhIHNwZWNpZmljYXRpb24gdGhhdCBkZXNjcmliZXMgYSBub3RhdGlvbiBmb3IgaWRlbnRpZnlpbmcKLSAqICAgICBub2RlcyBpbiBhIHRyZWUtc3RydWN0dXJlZCByZXByZXNlbnRhdGlvbiBvZiBhbiBYTUwgZG9jdW1lbnQuICBBbgotICogICAgIGluc3RhbmNlIG9mIHRoYXQgbm90YXRpb24gaXMgcmVmZXJyZWQgdG8gYXMgYW4gWFBhdGggZXhwcmVzc2lvbi4KLSAqCi0gKiAgOCkgVGhlIGNvbnRleHQgbm9kZSBpcyB0aGUgbm9kZSBpbiB0aGUgZG9jdW1lbnQgd2l0aCByZXNwZWN0IHRvIHdoaWNoIGFuCi0gKiAgICAgWFBhdGggZXhwcmVzc2lvbiBpcyBiZWluZyBldmFsdWF0ZWQuCi0gKgotICogIDkpIEFuIGl0ZXJhdG9yIGlzIGFuIG9iamVjdCB0aGF0IHRyYXZlcnNlcyBub2RlcyBpbiB0aGUgdHJlZSwgb25lIGF0IGEgdGltZS4KLSAqCi0gKiAgMTApIE5DTmFtZSBpcyBhbiBYTUwgdGVybSB1c2VkIHRvIGRlc2NyaWJlIGEgbmFtZSB0aGF0IGRvZXMgbm90IGNvbnRhaW4gYQotICogICAgIGNvbG9uIChhICJuby1jb2xvbiBuYW1lIikuCi0gKgotICogIDExKSBRTmFtZSBpcyBhbiBYTUwgdGVybSBtZWFuaW5nICJxdWFsaWZpZWQgbmFtZSIuCi0gKi8KLQotICAvKgotICAgKiBzdGF0aWMgdmFyaWFibGVzCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJPUjAwMDAgPSAiRVJST1IwMDAwIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ1VSUkVOVF9OT1RfQUxMT1dFRF9JTl9NQVRDSCA9Ci0gICAgICAgICAiRVJfQ1VSUkVOVF9OT1RfQUxMT1dFRF9JTl9NQVRDSCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NVUlJFTlRfVEFLRVNfTk9fQVJHUyA9Ci0gICAgICAgICAiRVJfQ1VSUkVOVF9UQUtFU19OT19BUkdTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRE9DVU1FTlRfUkVQTEFDRUQgPSAiRVJfRE9DVU1FTlRfUkVQTEFDRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT05URVhUX0hBU19OT19PV05FUkRPQyA9Ci0gICAgICAgICAiRVJfQ09OVEVYVF9IQVNfTk9fT1dORVJET0MiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9MT0NBTE5BTUVfSEFTX1RPT19NQU5ZX0FSR1MgPQotICAgICAgICAgIkVSX0xPQ0FMTkFNRV9IQVNfVE9PX01BTllfQVJHUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05BTUVTUEFDRVVSSV9IQVNfVE9PX01BTllfQVJHUyA9Ci0gICAgICAgICAiRVJfTkFNRVNQQUNFVVJJX0hBU19UT09fTUFOWV9BUkdTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9STUFMSVpFU1BBQ0VfSEFTX1RPT19NQU5ZX0FSR1MgPQotICAgICAgICAgIkVSX05PUk1BTElaRVNQQUNFX0hBU19UT09fTUFOWV9BUkdTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTlVNQkVSX0hBU19UT09fTUFOWV9BUkdTID0KLSAgICAgICAgICJFUl9OVU1CRVJfSEFTX1RPT19NQU5ZX0FSR1MiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OQU1FX0hBU19UT09fTUFOWV9BUkdTID0KLSAgICAgICAgICJFUl9OQU1FX0hBU19UT09fTUFOWV9BUkdTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU1RSSU5HX0hBU19UT09fTUFOWV9BUkdTID0KLSAgICAgICAgICJFUl9TVFJJTkdfSEFTX1RPT19NQU5ZX0FSR1MiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TVFJJTkdMRU5HVEhfSEFTX1RPT19NQU5ZX0FSR1MgPQotICAgICAgICAgIkVSX1NUUklOR0xFTkdUSF9IQVNfVE9PX01BTllfQVJHUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1RSQU5TTEFURV9UQUtFU18zX0FSR1MgPQotICAgICAgICAgIkVSX1RSQU5TTEFURV9UQUtFU18zX0FSR1MiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTlBBUlNFREVOVElUWVVSSV9UQUtFU18xX0FSRyA9Ci0gICAgICAgICAiRVJfVU5QQVJTRURFTlRJVFlVUklfVEFLRVNfMV9BUkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OQU1FU1BBQ0VBWElTX05PVF9JTVBMRU1FTlRFRCA9Ci0gICAgICAgICAiRVJfTkFNRVNQQUNFQVhJU19OT1RfSU1QTEVNRU5URUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTktOT1dOX0FYSVMgPSAiRVJfVU5LTk9XTl9BWElTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5LTk9XTl9NQVRDSF9PUEVSQVRJT04gPQotICAgICAgICAgIkVSX1VOS05PV05fTUFUQ0hfT1BFUkFUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5DT1JSRUNUX0FSR19MRU5HVEggPSJFUl9JTkNPUlJFQ1RfQVJHX0xFTkdUSCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfQ09OVkVSVF9UT19OVU1CRVIgPQotICAgICAgICAgIkVSX0NBTlRfQ09OVkVSVF9UT19OVU1CRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX0NPTlZFUlRfWFBBVEhSRVNVTFRUWVBFX1RPX05VTUJFUiA9Ci0gICAgICAgICAgICJFUl9DQU5UX0NPTlZFUlRfWFBBVEhSRVNVTFRUWVBFX1RPX05VTUJFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfQ09OVkVSVF9UT19OT0RFTElTVCA9Ci0gICAgICAgICAiRVJfQ0FOVF9DT05WRVJUX1RPX05PREVMSVNUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9DT05WRVJUX1RPX01VVEFCTEVOT0RFTElTVCA9Ci0gICAgICAgICAiRVJfQ0FOVF9DT05WRVJUX1RPX01VVEFCTEVOT0RFTElTVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfQ09OVkVSVF9UT19UWVBFID0iRVJfQ0FOVF9DT05WRVJUX1RPX1RZUEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FWFBFQ1RFRF9NQVRDSF9QQVRURVJOID0KLSAgICAgICAgICJFUl9FWFBFQ1RFRF9NQVRDSF9QQVRURVJOIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTEROT1RfR0VUX1ZBUl9OQU1FRCA9Ci0gICAgICAgICAiRVJfQ09VTEROT1RfR0VUX1ZBUl9OQU1FRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1VOS05PV05fT1BDT0RFID0gIkVSX1VOS05PV05fT1BDT0RFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhUUkFfSUxMRUdBTF9UT0tFTlMgPSJFUl9FWFRSQV9JTExFR0FMX1RPS0VOUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYUEVDVEVEX0RPVUJMRV9RVU9URSA9Ci0gICAgICAgICAiRVJfRVhQRUNURURfRE9VQkxFX1FVT1RFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhQRUNURURfU0lOR0xFX1FVT1RFID0KLSAgICAgICAgICJFUl9FWFBFQ1RFRF9TSU5HTEVfUVVPVEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FTVBUWV9FWFBSRVNTSU9OID0gIkVSX0VNUFRZX0VYUFJFU1NJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FWFBFQ1RFRF9CVVRfRk9VTkQgPSAiRVJfRVhQRUNURURfQlVUX0ZPVU5EIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5DT1JSRUNUX1BST0dSQU1NRVJfQVNTRVJUSU9OID0KLSAgICAgICAgICJFUl9JTkNPUlJFQ1RfUFJPR1JBTU1FUl9BU1NFUlRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9CT09MRUFOX0FSR19OT19MT05HRVJfT1BUSU9OQUwgPQotICAgICAgICAgIkVSX0JPT0xFQU5fQVJHX05PX0xPTkdFUl9PUFRJT05BTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZPVU5EX0NPTU1BX0JVVF9OT19QUkVDRURJTkdfQVJHID0KLSAgICAgICAgICJFUl9GT1VORF9DT01NQV9CVVRfTk9fUFJFQ0VESU5HX0FSRyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZPVU5EX0NPTU1BX0JVVF9OT19GT0xMT1dJTkdfQVJHID0KLSAgICAgICAgICJFUl9GT1VORF9DT01NQV9CVVRfTk9fRk9MTE9XSU5HX0FSRyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BSRURJQ0FURV9JTExFR0FMX1NZTlRBWCA9Ci0gICAgICAgICAiRVJfUFJFRElDQVRFX0lMTEVHQUxfU1lOVEFYIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSUxMRUdBTF9BWElTX05BTUUgPSAiRVJfSUxMRUdBTF9BWElTX05BTUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTktOT1dOX05PREVUWVBFID0gIkVSX1VOS05PV05fTk9ERVRZUEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QQVRURVJOX0xJVEVSQUxfTkVFRFNfQkVfUVVPVEVEID0KLSAgICAgICAgICJFUl9QQVRURVJOX0xJVEVSQUxfTkVFRFNfQkVfUVVPVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTEROT1RfQkVfRk9STUFUVEVEX1RPX05VTUJFUiA9Ci0gICAgICAgICAiRVJfQ09VTEROT1RfQkVfRk9STUFUVEVEX1RPX05VTUJFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxETk9UX0NSRUFURV9YTUxQUk9DRVNTT1JMSUFJU09OID0KLSAgICAgICAgICJFUl9DT1VMRE5PVF9DUkVBVEVfWE1MUFJPQ0VTU09STElBSVNPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0RJRE5PVF9GSU5EX1hQQVRIX1NFTEVDVF9FWFAgPQotICAgICAgICAgIkVSX0RJRE5PVF9GSU5EX1hQQVRIX1NFTEVDVF9FWFAiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRE5PVF9GSU5EX0VORE9QX0FGVEVSX09QTE9DQVRJT05QQVRIID0KLSAgICAgICAgICJFUl9DT1VMRE5PVF9GSU5EX0VORE9QX0FGVEVSX09QTE9DQVRJT05QQVRIIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVJST1JfT0NDVVJFRCA9ICJFUl9FUlJPUl9PQ0NVUkVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSUxMRUdBTF9WQVJJQUJMRV9SRUZFUkVOQ0UgPQotICAgICAgICAgIkVSX0lMTEVHQUxfVkFSSUFCTEVfUkVGRVJFTkNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQVhFU19OT1RfQUxMT1dFRCA9ICJFUl9BWEVTX05PVF9BTExPV0VEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfS0VZX0hBU19UT09fTUFOWV9BUkdTID0KLSAgICAgICAgICJFUl9LRVlfSEFTX1RPT19NQU5ZX0FSR1MiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VOVF9UQUtFU18xX0FSRyA9ICJFUl9DT1VOVF9UQUtFU18xX0FSRyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxETk9UX0ZJTkRfRlVOQ1RJT04gPQotICAgICAgICAgIkVSX0NPVUxETk9UX0ZJTkRfRlVOQ1RJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTlNVUFBPUlRFRF9FTkNPRElORyA9IkVSX1VOU1VQUE9SVEVEX0VOQ09ESU5HIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJPQkxFTV9JTl9EVE1fTkVYVFNJQkxJTkcgPQotICAgICAgICAgIkVSX1BST0JMRU1fSU5fRFRNX05FWFRTSUJMSU5HIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX1dSSVRFX1RPX0VNUFRZTk9ERUxJU1RJTVBMID0KLSAgICAgICAgICJFUl9DQU5OT1RfV1JJVEVfVE9fRU1QVFlOT0RFTElTVElNUEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TRVRET01GQUNUT1JZX05PVF9TVVBQT1JURUQgPQotICAgICAgICAgIkVSX1NFVERPTUZBQ1RPUllfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BSRUZJWF9NVVNUX1JFU09MVkUgPSAiRVJfUFJFRklYX01VU1RfUkVTT0xWRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BBUlNFX05PVF9TVVBQT1JURUQgPSAiRVJfUEFSU0VfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NBWF9BUElfTk9UX0hBTkRMRUQgPSAiRVJfU0FYX0FQSV9OT1RfSEFORExFRCI7Ci1wdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JR05PUkFCTEVfV0hJVEVTUEFDRV9OT1RfSEFORExFRCA9Ci0gICAgICAgICAiRVJfSUdOT1JBQkxFX1dISVRFU1BBQ0VfTk9UX0hBTkRMRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9EVE1fQ0FOTk9UX0hBTkRMRV9OT0RFUyA9Ci0gICAgICAgICAiRVJfRFRNX0NBTk5PVF9IQU5ETEVfTk9ERVMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YRVJDRVNfQ0FOTk9UX0hBTkRMRV9OT0RFUyA9Ci0gICAgICAgICAiRVJfWEVSQ0VTX0NBTk5PVF9IQU5ETEVfTk9ERVMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YRVJDRVNfUEFSU0VfRVJST1JfREVUQUlMUyA9Ci0gICAgICAgICAiRVJfWEVSQ0VTX1BBUlNFX0VSUk9SX0RFVEFJTFMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YRVJDRVNfUEFSU0VfRVJST1IgPSAiRVJfWEVSQ0VTX1BBUlNFX0VSUk9SIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9VVEYxNl9TVVJST0dBVEUgPQotICAgICAgICAgIkVSX0lOVkFMSURfVVRGMTZfU1VSUk9HQVRFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfT0lFUlJPUiA9ICJFUl9PSUVSUk9SIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX0NSRUFURV9VUkwgPSAiRVJfQ0FOTk9UX0NSRUFURV9VUkwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YUEFUSF9SRUFET0JKRUNUID0gIkVSX1hQQVRIX1JFQURPQkpFQ1QiOwotIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZVTkNUSU9OX1RPS0VOX05PVF9GT1VORCA9Ci0gICAgICAgICAiRVJfRlVOQ1RJT05fVE9LRU5fTk9UX0ZPVU5EIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX0RFQUxfWFBBVEhfVFlQRSA9Ci0gICAgICAgICAiRVJfQ0FOTk9UX0RFQUxfWFBBVEhfVFlQRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PREVTRVRfTk9UX01VVEFCTEUgPSAiRVJfTk9ERVNFVF9OT1RfTVVUQUJMRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PREVTRVREVE1fTk9UX01VVEFCTEUgPQotICAgICAgICAgIkVSX05PREVTRVREVE1fTk9UX01VVEFCTEUiOwotICAgLyoqICBWYXJpYWJsZSBub3QgcmVzb2x2YWJsZTogICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9WQVJfTk9UX1JFU09MVkFCTEUgPSAiRVJfVkFSX05PVF9SRVNPTFZBQkxFIjsKLSAgIC8qKiBOdWxsIGVycm9yIGhhbmRsZXIgICovCi0gcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTlVMTF9FUlJPUl9IQU5ETEVSID0gIkVSX05VTExfRVJST1JfSEFORExFUiI7Ci0gICAvKiogIFByb2dyYW1tZXIncyBhc3NlcnRpb246IHVua25vd24gb3Bjb2RlICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUk9HX0FTU0VSVF9VTktOT1dOX09QQ09ERSA9Ci0gICAgICAgICAiRVJfUFJPR19BU1NFUlRfVU5LTk9XTl9PUENPREUiOwotICAgLyoqICAwIG9yIDEgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9aRVJPX09SX09ORSA9ICJFUl9aRVJPX09SX09ORSI7Ci0gICAvKiogIHJ0ZigpIG5vdCBzdXBwb3J0ZWQgYnkgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SVEZfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiA9Ci0gICAgICAgICAiRVJfUlRGX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIiOwotICAgLyoqICBhc05vZGVJdGVyYXRvcigpIG5vdCBzdXBwb3J0ZWQgYnkgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9BU05PREVJVEVSQVRPUl9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSID0gIkVSX0FTTk9ERUlURVJBVE9SX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIiOwotICAgLyoqICBmc2IoKSBub3Qgc3VwcG9ydGVkIGZvciBYU3RyaW5nRm9yQ2hhcnMgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GU0JfTk9UX1NVUFBPUlRFRF9YU1RSSU5HRk9SQ0hBUlMgPQotICAgICAgICAgIkVSX0ZTQl9OT1RfU1VQUE9SVEVEX1hTVFJJTkdGT1JDSEFSUyI7Ci0gICAvKiogIENvdWxkIG5vdCBmaW5kIHZhcmlhYmxlIHdpdGggdGhlIG5hbWUgb2YgICAqLwotIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxEX05PVF9GSU5EX1ZBUiA9ICJFUl9DT1VMRF9OT1RfRklORF9WQVIiOwotICAgLyoqICBYU3RyaW5nRm9yQ2hhcnMgY2FuIG5vdCB0YWtlIGEgc3RyaW5nIGZvciBhbiBhcmd1bWVudCAgICovCi0gcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWFNUUklOR0ZPUkNIQVJTX0NBTk5PVF9UQUtFX1NUUklORyA9Ci0gICAgICAgICAiRVJfWFNUUklOR0ZPUkNIQVJTX0NBTk5PVF9UQUtFX1NUUklORyI7Ci0gICAvKiogIFRoZSBGYXN0U3RyaW5nQnVmZmVyIGFyZ3VtZW50IGNhbiBub3QgYmUgbnVsbCAgICovCi0gcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRkFTVFNUUklOR0JVRkZFUl9DQU5OT1RfQkVfTlVMTCA9Ci0gICAgICAgICAiRVJfRkFTVFNUUklOR0JVRkZFUl9DQU5OT1RfQkVfTlVMTCI7Ci0gICAvKiogIDIgb3IgMyAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1RXT19PUl9USFJFRSA9ICJFUl9UV09fT1JfVEhSRUUiOwotICAgLyoqIFZhcmlhYmxlIGFjY2Vzc2VkIGJlZm9yZSBpdCBpcyBib3VuZCEgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVkFSSUFCTEVfQUNDRVNTRURfQkVGT1JFX0JJTkQgPQotICAgICAgICAgIkVSX1ZBUklBQkxFX0FDQ0VTU0VEX0JFRk9SRV9CSU5EIjsKLSAgIC8qKiBYU3RyaW5nRm9yRlNCIGNhbiBub3QgdGFrZSBhIHN0cmluZyBmb3IgYW4gYXJndW1lbnQhICovCi0gcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRlNCX0NBTk5PVF9UQUtFX1NUUklORyA9Ci0gICAgICAgICAiRVJfRlNCX0NBTk5PVF9UQUtFX1NUUklORyI7Ci0gICAvKiogRXJyb3IhIFNldHRpbmcgdGhlIHJvb3Qgb2YgYSB3YWxrZXIgdG8gbnVsbCEgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU0VUVElOR19XQUxLRVJfUk9PVF9UT19OVUxMID0KLSAgICAgICAgICJFUl9TRVRUSU5HX1dBTEtFUl9ST09UX1RPX05VTEwiOwotICAgLyoqIFRoaXMgTm9kZVNldERUTSBjYW4gbm90IGl0ZXJhdGUgdG8gYSBwcmV2aW91cyBub2RlISAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT0RFU0VURFRNX0NBTk5PVF9JVEVSQVRFID0KLSAgICAgICAgICJFUl9OT0RFU0VURFRNX0NBTk5PVF9JVEVSQVRFIjsKLSAgLyoqIFRoaXMgTm9kZVNldCBjYW4gbm90IGl0ZXJhdGUgdG8gYSBwcmV2aW91cyBub2RlISAqLwotIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PREVTRVRfQ0FOTk9UX0lURVJBVEUgPQotICAgICAgICAgIkVSX05PREVTRVRfQ0FOTk9UX0lURVJBVEUiOwotICAvKiogVGhpcyBOb2RlU2V0RFRNIGNhbiBub3QgZG8gaW5kZXhpbmcgb3IgY291bnRpbmcgZnVuY3Rpb25zISAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT0RFU0VURFRNX0NBTk5PVF9JTkRFWCA9Ci0gICAgICAgICAiRVJfTk9ERVNFVERUTV9DQU5OT1RfSU5ERVgiOwotICAvKiogVGhpcyBOb2RlU2V0IGNhbiBub3QgZG8gaW5kZXhpbmcgb3IgY291bnRpbmcgZnVuY3Rpb25zISAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT0RFU0VUX0NBTk5PVF9JTkRFWCA9Ci0gICAgICAgICAiRVJfTk9ERVNFVF9DQU5OT1RfSU5ERVgiOwotICAvKiogQ2FuIG5vdCBjYWxsIHNldFNob3VsZENhY2hlTm9kZXMgYWZ0ZXIgbmV4dE5vZGUgaGFzIGJlZW4gY2FsbGVkISAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfQ0FMTF9TRVRTSE9VTERDQUNIRU5PREUgPQotICAgICAgICAgIkVSX0NBTk5PVF9DQUxMX1NFVFNIT1VMRENBQ0hFTk9ERSI7Ci0gIC8qKiB7MH0gb25seSBhbGxvd3MgezF9IGFyZ3VtZW50cyAqLwotIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX09OTFlfQUxMT1dTID0gIkVSX09OTFlfQUxMT1dTIjsKLSAgLyoqIFByb2dyYW1tZXIncyBhc3NlcnRpb24gaW4gZ2V0TmV4dFN0ZXBQb3M6IHVua25vd24gc3RlcFR5cGU6IHswfSAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTktOT1dOX1NURVAgPSAiRVJfVU5LTk9XTl9TVEVQIjsKLSAgLyoqIFByb2JsZW0gd2l0aCBSZWxhdGl2ZUxvY2F0aW9uUGF0aCAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FWFBFQ1RFRF9SRUxfTE9DX1BBVEggPQotICAgICAgICAgIkVSX0VYUEVDVEVEX1JFTF9MT0NfUEFUSCI7Ci0gIC8qKiBQcm9ibGVtIHdpdGggTG9jYXRpb25QYXRoICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYUEVDVEVEX0xPQ19QQVRIID0gIkVSX0VYUEVDVEVEX0xPQ19QQVRIIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhQRUNURURfTE9DX1BBVEhfQVRfRU5EX0VYUFIgPQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJFUl9FWFBFQ1RFRF9MT0NfUEFUSF9BVF9FTkRfRVhQUiI7Ci0gIC8qKiBQcm9ibGVtIHdpdGggU3RlcCAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FWFBFQ1RFRF9MT0NfU1RFUCA9ICJFUl9FWFBFQ1RFRF9MT0NfU1RFUCI7Ci0gIC8qKiBQcm9ibGVtIHdpdGggTm9kZVRlc3QgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhQRUNURURfTk9ERV9URVNUID0gIkVSX0VYUEVDVEVEX05PREVfVEVTVCI7Ci0gIC8qKiBFeHBlY3RlZCBzdGVwIHBhdHRlcm4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhQRUNURURfU1RFUF9QQVRURVJOID0KLSAgICAgICAgIkVSX0VYUEVDVEVEX1NURVBfUEFUVEVSTiI7Ci0gIC8qKiBFeHBlY3RlZCByZWxhdGl2ZSBwYXRoIHBhdHRlcm4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhQRUNURURfUkVMX1BBVEhfUEFUVEVSTiA9Ci0gICAgICAgICAiRVJfRVhQRUNURURfUkVMX1BBVEhfUEFUVEVSTiI7Ci0gIC8qKiBFUl9DQU5UX0NPTlZFUlRfWFBBVEhSRVNVTFRUWVBFX1RPX0JPT0xFQU4gICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9DT05WRVJUX1RPX0JPT0xFQU4gPQotICAgICAgICAgIkVSX0NBTlRfQ09OVkVSVF9UT19CT09MRUFOIjsKLSAgLyoqIEZpZWxkIEVSX0NBTlRfQ09OVkVSVF9UT19TSU5HTEVOT0RFICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfQ09OVkVSVF9UT19TSU5HTEVOT0RFID0KLSAgICAgICAgICJFUl9DQU5UX0NPTlZFUlRfVE9fU0lOR0xFTk9ERSI7Ci0gIC8qKiBGaWVsZCBFUl9DQU5UX0dFVF9TTkFQU0hPVF9MRU5HVEggICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX0dFVF9TTkFQU0hPVF9MRU5HVEggPQotICAgICAgICAgIkVSX0NBTlRfR0VUX1NOQVBTSE9UX0xFTkdUSCI7Ci0gIC8qKiBGaWVsZCBFUl9OT05fSVRFUkFUT1JfVFlQRSAgICAgICAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT05fSVRFUkFUT1JfVFlQRSA9ICJFUl9OT05fSVRFUkFUT1JfVFlQRSI7Ci0gIC8qKiBGaWVsZCBFUl9ET0NfTVVUQVRFRCAgICAgICAgICAgICAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9ET0NfTVVUQVRFRCA9ICJFUl9ET0NfTVVUQVRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfWFBBVEhfVFlQRSA9ICJFUl9JTlZBTElEX1hQQVRIX1RZUEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FTVBUWV9YUEFUSF9SRVNVTFQgPSAiRVJfRU1QVFlfWFBBVEhfUkVTVUxUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5DT01QQVRJQkxFX1RZUEVTID0gIkVSX0lOQ09NUEFUSUJMRV9UWVBFUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05VTExfUkVTT0xWRVIgPSAiRVJfTlVMTF9SRVNPTFZFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfQ09OVkVSVF9UT19TVFJJTkcgPQotICAgICAgICAgIkVSX0NBTlRfQ09OVkVSVF9UT19TVFJJTkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT05fU05BUFNIT1RfVFlQRSA9ICJFUl9OT05fU05BUFNIT1RfVFlQRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1dST05HX0RPQ1VNRU5UID0gIkVSX1dST05HX0RPQ1VNRU5UIjsKLSAgLyogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBYUGF0aCBleHByZXNzaW9uIGNhbm5vdCBiZSBldmFsdWF0ZWQgd2l0aCByZXNwZWN0Ci0gICAqIHRvIHRoaXMgdHlwZSBvZiBub2RlLgotICAgKi8KLSAgLyoqIEZpZWxkIEVSX1dST05HX05PREVUWVBFICAgICAgICAgICAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9XUk9OR19OT0RFVFlQRSA9ICJFUl9XUk9OR19OT0RFVFlQRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hQQVRIX0VSUk9SID0gIkVSX1hQQVRIX0VSUk9SIjsKLQotICAvL0JFR0lOOiBLZXlzIG5lZWRlZCBmb3IgZXhjZXB0aW9uIG1lc3NhZ2VzIG9mICBKQVhQIDEuMyBYUGF0aCBBUEkgaW1wbGVtZW50YXRpb24KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhURU5TSU9OX0ZVTkNUSU9OX0NBTk5PVF9CRV9JTlZPS0VEID0gIkVSX0VYVEVOU0lPTl9GVU5DVElPTl9DQU5OT1RfQkVfSU5WT0tFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1JFU09MVkVfVkFSSUFCTEVfUkVUVVJOU19OVUxMID0gIkVSX1JFU09MVkVfVkFSSUFCTEVfUkVUVVJOU19OVUxMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5TVVBQT1JURURfUkVUVVJOX1RZUEUgPSAiRVJfVU5TVVBQT1JURURfUkVUVVJOX1RZUEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TT1VSQ0VfUkVUVVJOX1RZUEVfQ0FOTk9UX0JFX05VTEwgPSAiRVJfU09VUkNFX1JFVFVSTl9UWVBFX0NBTk5PVF9CRV9OVUxMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQVJHX0NBTk5PVF9CRV9OVUxMID0gIkVSX0FSR19DQU5OT1RfQkVfTlVMTCI7Ci0KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfT0JKRUNUX01PREVMX05VTEwgPSAiRVJfT0JKRUNUX01PREVMX05VTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9PQkpFQ1RfTU9ERUxfRU1QVFkgPSAiRVJfT0JKRUNUX01PREVMX0VNUFRZIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRkVBVFVSRV9OQU1FX05VTEwgPSAiRVJfRkVBVFVSRV9OQU1FX05VTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GRUFUVVJFX1VOS05PV04gPSAiRVJfRkVBVFVSRV9VTktOT1dOIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfR0VUVElOR19OVUxMX0ZFQVRVUkUgPSAiRVJfR0VUVElOR19OVUxMX0ZFQVRVUkUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9HRVRUSU5HX1VOS05PV05fRkVBVFVSRSA9ICJFUl9HRVRUSU5HX1VOS05PV05fRkVBVFVSRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NFQ1VSRVBST0NFU1NJTkdfRkVBVFVSRSA9ICJFUl9TRUNVUkVQUk9DRVNTSU5HX0ZFQVRVUkUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OVUxMX1hQQVRIX0ZVTkNUSU9OX1JFU09MVkVSID0gIkVSX05VTExfWFBBVEhfRlVOQ1RJT05fUkVTT0xWRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OVUxMX1hQQVRIX1ZBUklBQkxFX1JFU09MVkVSID0gIkVSX05VTExfWFBBVEhfVkFSSUFCTEVfUkVTT0xWRVIiOwotICAvL0VORDogS2V5cyBuZWVkZWQgZm9yIGV4Y2VwdGlvbiBtZXNzYWdlcyBvZiAgSkFYUCAxLjMgWFBhdGggQVBJIGltcGxlbWVudGF0aW9uCi0KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfTE9DQUxFX05BTUVfTk9UX0hBTkRMRUQgPQotICAgICAgICAgIldHX0xPQ0FMRV9OQU1FX05PVF9IQU5ETEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfUFJPUEVSVFlfTk9UX1NVUFBPUlRFRCA9Ci0gICAgICAgICAiV0dfUFJPUEVSVFlfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0RPTlRfRE9fQU5ZVEhJTkdfV0lUSF9OUyA9Ci0gICAgICAgICAiV0dfRE9OVF9ET19BTllUSElOR19XSVRIX05TIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfU0VDVVJJVFlfRVhDRVBUSU9OID0gIldHX1NFQ1VSSVRZX0VYQ0VQVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX1FVT19OT19MT05HRVJfREVGSU5FRCA9Ci0gICAgICAgICAiV0dfUVVPX05PX0xPTkdFUl9ERUZJTkVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfTkVFRF9ERVJJVkVEX09CSkVDVF9UT19JTVBMRU1FTlRfTk9ERVRFU1QgPQotICAgICAgICAgIldHX05FRURfREVSSVZFRF9PQkpFQ1RfVE9fSU1QTEVNRU5UX05PREVURVNUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfRlVOQ1RJT05fVE9LRU5fTk9UX0ZPVU5EID0KLSAgICAgICAgICJXR19GVU5DVElPTl9UT0tFTl9OT1RfRk9VTkQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19DT1VMRE5PVF9GSU5EX0ZVTkNUSU9OID0KLSAgICAgICAgICJXR19DT1VMRE5PVF9GSU5EX0ZVTkNUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfQ0FOTk9UX01BS0VfVVJMX0ZST00gPSJXR19DQU5OT1RfTUFLRV9VUkxfRlJPTSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0VYUEFORF9FTlRJVElFU19OT1RfU1VQUE9SVEVEID0KLSAgICAgICAgICJXR19FWFBBTkRfRU5USVRJRVNfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0lMTEVHQUxfVkFSSUFCTEVfUkVGRVJFTkNFID0KLSAgICAgICAgICJXR19JTExFR0FMX1ZBUklBQkxFX1JFRkVSRU5DRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX1VOU1VQUE9SVEVEX0VOQ09ESU5HID0iV0dfVU5TVVBQT1JURURfRU5DT0RJTkciOwotCi0gIC8qKiAgZGV0YWNoKCkgbm90IHN1cHBvcnRlZCBieSBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0RFVEFDSF9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSID0KLSAgICAgICAgICJFUl9ERVRBQ0hfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiI7Ci0gIC8qKiAgbnVtKCkgbm90IHN1cHBvcnRlZCBieSBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05VTV9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSID0KLSAgICAgICAgICJFUl9OVU1fTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiI7Ci0gIC8qKiAgeHN0cigpIG5vdCBzdXBwb3J0ZWQgYnkgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YU1RSX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIgPQotICAgICAgICAgIkVSX1hTVFJfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiI7Ci0gIC8qKiAgc3RyKCkgbm90IHN1cHBvcnRlZCBieSBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NUUl9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSID0KLSAgICAgICAgICJFUl9TVFJfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiI7Ci0KLSAgLy8gRXJyb3IgbWVzc2FnZXMuLi4KLQotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBPYmplY3RbXVtdIF9jb250ZW50cyA9IG5ldyBPYmplY3RbXVtdewotCi0gIHsgIkVSUk9SMDAwMCIgLCAiezB9IiB9LAotCi0gIHsgRVJfQ1VSUkVOVF9OT1RfQUxMT1dFRF9JTl9NQVRDSCwgIkxhIGZ1bnppb25lIGN1cnJlbnQoKSBub24gXHUwMEU4IGNvbnNlbnRpdGEgaW4gdW4gcGF0dGVybiBkaSBjb3JyaXNwb25kZW56YS4iIH0sCi0KLSAgeyBFUl9DVVJSRU5UX1RBS0VTX05PX0FSR1MsICJMYSBmdW56aW9uZSBjdXJyZW50KCkgbm9uIGFjY2V0dGEgYXJnb21lbnRpLiIgfSwKLQotICB7IEVSX0RPQ1VNRU5UX1JFUExBQ0VELAotICAgICAgIkwnaW1wbGVtZW50YXppb25lIGRlbGxhIGZ1bnppb25lIGRvY3VtZW50KCkgXHUwMEU4IHN0YXRhIHNvc3RpdHVpdGEgZGEgY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHQuRnVuY0RvY3VtZW50LiJ9LAotCi0gIHsgRVJfQ09OVEVYVF9IQVNfTk9fT1dORVJET0MsCi0gICAgICAiaWwgY29udGVzdG8gbm9uIGRpc3BvbmUgZGkgdW4gZG9jdW1lbnRvIHByb3ByaWV0YXJpby4ifSwKLQotICB7IEVSX0xPQ0FMTkFNRV9IQVNfVE9PX01BTllfQVJHUywKLSAgICAgICJsb2NhbC1uYW1lKCkgY29udGllbmUgdHJvcHBpIGFyZ29tZW50aS4ifSwKLQotICB7IEVSX05BTUVTUEFDRVVSSV9IQVNfVE9PX01BTllfQVJHUywKLSAgICAgICJuYW1lc3BhY2UtdXJpKCkgY29udGllbmUgdHJvcHBpIGFyZ29tZW50aS4ifSwKLQotICB7IEVSX05PUk1BTElaRVNQQUNFX0hBU19UT09fTUFOWV9BUkdTLAotICAgICAgIm5vcm1hbGl6ZS1zcGFjZSgpIGNvbnRpZW5lIHRyb3BwaSBhcmdvbWVudGkuIn0sCi0KLSAgeyBFUl9OVU1CRVJfSEFTX1RPT19NQU5ZX0FSR1MsCi0gICAgICAibnVtYmVyKCkgY29udGllbmUgdHJvcHBpIGFyZ29tZW50aS4ifSwKLQotICB7IEVSX05BTUVfSEFTX1RPT19NQU5ZX0FSR1MsCi0gICAgICJuYW1lKCkgY29udGllbmUgdHJvcHBpIGFyZ29tZW50aS4ifSwKLQotICB7IEVSX1NUUklOR19IQVNfVE9PX01BTllfQVJHUywKLSAgICAgICJzdHJpbmcoKSBjb250aWVuZSB0cm9wcGkgYXJnb21lbnRpLiJ9LAotCi0gIHsgRVJfU1RSSU5HTEVOR1RIX0hBU19UT09fTUFOWV9BUkdTLAotICAgICAgInN0cmluZy1sZW5ndGgoKSBjb250aWVuZSB0cm9wcGkgYXJnb21lbnRpLiJ9LAotCi0gIHsgRVJfVFJBTlNMQVRFX1RBS0VTXzNfQVJHUywKLSAgICAgICJMYSBmdW56aW9uZSB0cmFuc2xhdGUoKSBoYSB0cmUgYXJnb21lbnRpLiJ9LAotCi0gIHsgRVJfVU5QQVJTRURFTlRJVFlVUklfVEFLRVNfMV9BUkcsCi0gICAgICAiTGEgZnVuemlvbmUgdW5wYXJzZWQtZW50aXR5LXVyaSBkZXZlIGF2ZXJlIHVuIHNvbG8gYXJnb21lbnRvLiJ9LAotCi0gIHsgRVJfTkFNRVNQQUNFQVhJU19OT1RfSU1QTEVNRU5URUQsCi0gICAgICAibCdhc3NlIGRlbGxvIHNwYXppbyBkaSBub21pIG5vbiBcdTAwRTggYW5jb3JhIGltcGxlbWVudGF0by4ifSwKLQotICB7IEVSX1VOS05PV05fQVhJUywKLSAgICAgImFzc2Ugc2Nvbm9zY2l1dG86IHswfSJ9LAotCi0gIHsgRVJfVU5LTk9XTl9NQVRDSF9PUEVSQVRJT04sCi0gICAgICJvcGVyYXppb25lIGRpIGNvcnJpc3BvbmRlbnphIHNjb25vc2NpdXRhLiJ9LAotCi0gIHsgRVJfSU5DT1JSRUNUX0FSR19MRU5HVEgsCi0gICAgICAiTGEgbHVuZ2hlenphIGRlZ2xpIGFyZ29tZW50aSBkZWwgdGVzdG8gZGVsIG5vZG8gcHJvY2Vzc2luZy1pbnN0cnVjdGlvbigpIFx1MDBFOCBlcnJhdGEuIn0sCi0KLSAgeyBFUl9DQU5UX0NPTlZFUlRfVE9fTlVNQkVSLAotICAgICAgIkltcG9zc2liaWxlIGNvbnZlcnRpcmUgezB9IGluIHVuIG51bWVybyJ9LAotCi0gIHsgRVJfQ0FOVF9DT05WRVJUX1RPX05PREVMSVNULAotICAgICAgIkltcG9zc2liaWxlIGNvbnZlcnRpcmUgezB9IGluIE5vZGVMaXN0LiJ9LAotCi0gIHsgRVJfQ0FOVF9DT05WRVJUX1RPX01VVEFCTEVOT0RFTElTVCwKLSAgICAgICJJbXBvc3NpYmlsZSBjb252ZXJ0aXJlIHswfSBpbiBOb2RlU2V0RFRNLiJ9LAotCi0gIHsgRVJfQ0FOVF9DT05WRVJUX1RPX1RZUEUsCi0gICAgICAiSW1wb3NzaWJpbGUgY29udmVydGlyZSB7MH0gaW4gdHlwZSN7MX0ifSwKLQotICB7IEVSX0VYUEVDVEVEX01BVENIX1BBVFRFUk4sCi0gICAgICAiXHUwMEM4IHByZXZpc3RvIHVuIHBhdHRlcm4gZGkgY29ycmlzcG9uZGVuemEgaW4gZ2V0TWF0Y2hTY29yZS4ifSwKLQotICB7IEVSX0NPVUxETk9UX0dFVF9WQVJfTkFNRUQsCi0gICAgICAiSW1wb3NzaWJpbGUgcmVjdXBlcmFyZSBsYSB2YXJpYWJpbGUgZGVub21pbmF0YSB7MH0ifSwKLQotICB7IEVSX1VOS05PV05fT1BDT0RFLAotICAgICAiRVJST1JFLiBDb2RpY2UgZGkgb3BlcmF6aW9uZSBzY29ub3NjaXV0bzogezB9In0sCi0KLSAgeyBFUl9FWFRSQV9JTExFR0FMX1RPS0VOUywKLSAgICAgIkVzaXN0b25vIGFsdHJpIHRva2VuIG5vbiB2YWxpZGk6IHswfSJ9LAotCi0gIHsgRVJfRVhQRUNURURfRE9VQkxFX1FVT1RFLAotICAgICAgInZhbG9yZSBub24gdHJhIGFwaWNpLi4uIHNvbm8gcHJldmlzdGUgbGUgdmlyZ29sZXR0ZS4ifSwKLQotICB7IEVSX0VYUEVDVEVEX1NJTkdMRV9RVU9URSwKLSAgICAgICJ2YWxvcmUgbm9uIHRyYSBhcGljaS4uLiBcdTAwRTggcHJldmlzdG8gdW4gYXBpY2UuIn0sCi0KLSAgeyBFUl9FTVBUWV9FWFBSRVNTSU9OLAotICAgICAiRXNwcmVzc2lvbmUgdnVvdGEuIn0sCi0KLSAgeyBFUl9FWFBFQ1RFRF9CVVRfRk9VTkQsCi0gICAgICJQcmV2aXN0byB7MH0sIHRyb3ZhdG8gezF9LiJ9LAotCi0gIHsgRVJfSU5DT1JSRUNUX1BST0dSQU1NRVJfQVNTRVJUSU9OLAotICAgICAgIkwnJ2Fzc2VyemlvbmUgZGVsIHByb2dyYW1tYXRvcmUgXHUwMEU4IGVycmF0YSAtIHswfSJ9LAotCi0gIHsgRVJfQk9PTEVBTl9BUkdfTk9fTE9OR0VSX09QVElPTkFMLAotICAgICAgIkwnYXJnb21lbnRvIGJvb2xlYW4oLi4uKSBub24gXHUwMEU4IHBpXHUwMEY5IGZhY29sdGF0aXZvIG5lbGxhIGJvenphIFhQYXRoIDE5OTkwNzA5LiJ9LAotCi0gIHsgRVJfRk9VTkRfQ09NTUFfQlVUX05PX1BSRUNFRElOR19BUkcsCi0gICAgICAiXHUwMEM4IHN0YXRhIHRyb3ZhdGEgbGEgdmlyZ29sYSAoJywnKSwgbWEgbm9uIGwnYXJnb21lbnRvIGNoZSBsYSBwcmVjZWRlLiJ9LAotCi0gIHsgRVJfRk9VTkRfQ09NTUFfQlVUX05PX0ZPTExPV0lOR19BUkcsCi0gICAgICAiXHUwMEM4IHN0YXRhIHRyb3ZhdGEgbGEgdmlyZ29sYSAoJywnKSwgbWEgbm9uIGwnYXJnb21lbnRvIGNoZSBsYSBzZWd1ZS4ifSwKLQotICB7IEVSX1BSRURJQ0FURV9JTExFR0FMX1NZTlRBWCwKLSAgICAgICInLi5bcHJlZGljYXRlXScgbyAnLltwcmVkaWNhdGVdJyBcdTAwRTggdW5hIHNpbnRhc3NpIG5vbiB2YWxpZGEuICBVdGlsaXp6YXJlICdzZWxmOjpub2RlKClbcHJlZGljYXRlXScuIn0sCi0KLSAgeyBFUl9JTExFR0FMX0FYSVNfTkFNRSwKLSAgICAgIm5vbWUgYXNzZSBub24gdmFsaWRvOiB7MH0ifSwKLQotICB7IEVSX1VOS05PV05fTk9ERVRZUEUsCi0gICAgICJUaXBvIGRpIG5vZG8gc2Nvbm9zY2l1dG86IHswfSJ9LAotCi0gIHsgRVJfUEFUVEVSTl9MSVRFUkFMX05FRURTX0JFX1FVT1RFRCwKLSAgICAgICJJbCB2YWxvcmUgZGVsIHBhdHRlcm4gKHswfSkgZGV2ZSBlc3NlcmUgY29tcHJlc28gdHJhIGFwaWNpLiJ9LAotCi0gIHsgRVJfQ09VTEROT1RfQkVfRk9STUFUVEVEX1RPX05VTUJFUiwKLSAgICAgICJJbXBvc3NpYmlsZSBmb3JtYXR0YXJlIHswfSBpbiB1biBudW1lcm8uIn0sCi0KLSAgeyBFUl9DT1VMRE5PVF9DUkVBVEVfWE1MUFJPQ0VTU09STElBSVNPTiwKLSAgICAgICJJbXBvc3NpYmlsZSBjcmVhcmUgbGEgcmVsYXppb25lIFRyYW5zZm9ybWVyRmFjdG9yeSBYTUwgezB9In0sCi0KLSAgeyBFUl9ESUROT1RfRklORF9YUEFUSF9TRUxFQ1RfRVhQLAotICAgICAgIkVycm9yZS4gTCdlc3ByZXNzaW9uZSBkaSBzZWxlemlvbmUgZGVsbCd4cGF0aCAoLXNlbGVjdCkgbm9uIFx1MDBFOCBzdGF0YSB0cm92YXRhLiJ9LAotCi0gIHsgRVJfQ09VTEROT1RfRklORF9FTkRPUF9BRlRFUl9PUExPQ0FUSU9OUEFUSCwKLSAgICAgICJFUlJPUkUuIEltcG9zc2liaWxlIHRyb3ZhcmUgRU5ET1AgZG9wbyBPUF9MT0NBVElPTlBBVEguIn0sCi0KLSAgeyBFUl9FUlJPUl9PQ0NVUkVELAotICAgICAiU2kgXHUwMEU4IHZlcmlmaWNhdG8gdW4gZXJyb3JlLiJ9LAotCi0gIHsgRVJfSUxMRUdBTF9WQVJJQUJMRV9SRUZFUkVOQ0UsCi0gICAgICAiSWwgdmFsb3JlIGRpIFZhcmlhYmxlUmVmZXJlbmNlIHNwZWNpZmljYXRvIHBlciBsYSB2YXJpYWJpbGUgXHUwMEU4IGZ1b3JpIGNvbnRlc3RvIG8gc2VuemEgZGVmaW5pemlvbmUuIE5vbWUgPSB7MH0ifSwKLQotICB7IEVSX0FYRVNfTk9UX0FMTE9XRUQsCi0gICAgICAiU29sbyBnbGkgYXNzaSBjaGlsZDo6IGUgYXR0cmlidXRlOjogc29ubyBjb25zZW50aXRpIG5laSBwYXR0ZXJuIGRpIGNvcnJpc3BvbmRlbnphLiBBc3NpIGVycmF0aSA9IHswfSJ9LAotCi0gIHsgRVJfS0VZX0hBU19UT09fTUFOWV9BUkdTLAotICAgICAgImtleSgpIGNvbnRpZW5lIHVuIG51bWVybyBkaSBhcmdvbWVudGkgZXJyYXRvLiJ9LAotCi0gIHsgRVJfQ09VTlRfVEFLRVNfMV9BUkcsCi0gICAgICAiTGEgZnVuemlvbmUgY291bnQgZGV2ZSBhdmVyZSB1biBzb2xvIGFyZ29tZW50by4ifSwKLQotICB7IEVSX0NPVUxETk9UX0ZJTkRfRlVOQ1RJT04sCi0gICAgICJJbXBvc3NpYmlsZSB0cm92YXJlIGxhIGZ1bnppb25lIHswfSJ9LAotCi0gIHsgRVJfVU5TVVBQT1JURURfRU5DT0RJTkcsCi0gICAgICJDb2RpZmljYSBub24gc3VwcG9ydGF0YTogezB9In0sCi0KLSAgeyBFUl9QUk9CTEVNX0lOX0RUTV9ORVhUU0lCTElORywKLSAgICAgICJTaSBcdTAwRTggdmVyaWZpY2F0byB1biBwcm9ibGVtYSBpbiBEVE0gaW4gZ2V0TmV4dFNpYmxpbmcuLi4gVGVudGF0aXZvIGRpIHJlY3VwZXJvIGluIGNvcnNvLiJ9LAotCi0gIHsgRVJfQ0FOTk9UX1dSSVRFX1RPX0VNUFRZTk9ERUxJU1RJTVBMLAotICAgICAgIkVycm9yZSBkZWwgcHJvZ3JhbW1hdG9yZTogaW1wb3NzaWJpbGUgc2NyaXZlcmUgRW1wdHlOb2RlTGlzdC4ifSwKLQotICB7IEVSX1NFVERPTUZBQ1RPUllfTk9UX1NVUFBPUlRFRCwKLSAgICAgICJzZXRET01GYWN0b3J5IG5vbiBzdXBwb3J0YXRvIGRhIFhQYXRoQ29udGV4dCJ9LAotCi0gIHsgRVJfUFJFRklYX01VU1RfUkVTT0xWRSwKLSAgICAgICJJbCBwcmVmaXNzbyBkZXZlIGVzc2VyZSByaXNvbHRvIGluIHVubyBzcGF6aW8gZGkgbm9taTogezB9In0sCi0KLSAgeyBFUl9QQVJTRV9OT1RfU1VQUE9SVEVELAotICAgICAgImFuYWxpc2kgKG9yaWdpbmUgSW5wdXRTb3VyY2UpIG5vbiBzdXBwb3J0YXRhIGluIFhQYXRoQ29udGV4dC4gSW1wb3NzaWJpbGUgYXByaXJlIHswfS4ifSwKLQotICB7IEVSX1NBWF9BUElfTk9UX0hBTkRMRUQsCi0gICAgICAiQ2FyYXR0ZXJpIEFQSSBTQVggKGNoYXIgY2hbXS4uLiBub24gZ2VzdGl0aSBkYSBEVE0uIn0sCi0KLSAgeyBFUl9JR05PUkFCTEVfV0hJVEVTUEFDRV9OT1RfSEFORExFRCwKLSAgICAgICJpZ25vcmFibGVXaGl0ZXNwYWNlKGNoYXIgY2hbXS4uLiBub24gZ2VzdGl0byBkYSBEVE0uIn0sCi0KLSAgeyBFUl9EVE1fQ0FOTk9UX0hBTkRMRV9OT0RFUywKLSAgICAgICJEVE1MaWFpc29uIG5vbiBwdVx1MDBGMiBnZXN0aXJlIGkgbm9kaSBkaSB0aXBvIHswfSJ9LAotCi0gIHsgRVJfWEVSQ0VTX0NBTk5PVF9IQU5ETEVfTk9ERVMsCi0gICAgICAiRE9NMkhlbHBlciBub24gcHVcdTAwRjIgZ2VzdGlyZSBpIG5vZGkgZGkgdGlwbyB7MH0ifSwKLQotICB7IEVSX1hFUkNFU19QQVJTRV9FUlJPUl9ERVRBSUxTLAotICAgICAgIkVycm9yZSBET00ySGVscGVyLnBhcnNlOiBTeXN0ZW1JRCAtIHswfSBSaWdhIC0gezF9In0sCi0KLSAgeyBFUl9YRVJDRVNfUEFSU0VfRVJST1IsCi0gICAgICJFcnJvcmUgRE9NMkhlbHBlci5wYXJzZSJ9LAotCi0gIHsgRVJfSU5WQUxJRF9VVEYxNl9TVVJST0dBVEUsCi0gICAgICAiUmlsZXZhdG8gc3Vycm9nYXRvIFVURi0xNiBub24gdmFsaWRvOiB7MH0/In0sCi0KLSAgeyBFUl9PSUVSUk9SLAotICAgICAiRXJyb3JlIElPIn0sCi0KLSAgeyBFUl9DQU5OT1RfQ1JFQVRFX1VSTCwKLSAgICAgIkltcG9zc2liaWxlIGNyZWFyZSBsJydVUkwgcGVyIHswfSJ9LAotCi0gIHsgRVJfWFBBVEhfUkVBRE9CSkVDVCwKLSAgICAgIkluIFhQYXRoLnJlYWRPYmplY3Q6IHswfSJ9LAotCi0gIHsgRVJfRlVOQ1RJT05fVE9LRU5fTk9UX0ZPVU5ELAotICAgICAgInRva2VuIGRpIGZ1bnppb25lIG5vbiB0cm92YXRvLiJ9LAotCi0gIHsgRVJfQ0FOTk9UX0RFQUxfWFBBVEhfVFlQRSwKLSAgICAgICAiSW1wb3NzaWJpbGUgdXRpbGl6emFyZSBpbCB0aXBvIFhQYXRoOiB7MH0ifSwKLQotICB7IEVSX05PREVTRVRfTk9UX01VVEFCTEUsCi0gICAgICAgIkltcG9zc2liaWxlIG1vZGlmaWNhcmUgcXVlc3RvIE5vZGVTZXQifSwKLQotICB7IEVSX05PREVTRVREVE1fTk9UX01VVEFCTEUsCi0gICAgICAgIkltcG9zc2liaWxlIG1vZGlmaWNhcmUgcXVlc3RvIE5vZGVTZXREVE0ifSwKLQotICB7IEVSX1ZBUl9OT1RfUkVTT0xWQUJMRSwKLSAgICAgICAgIkltcG9zc2liaWxlIHJpc29sdmVyZSBsYSB2YXJpYWJpbGU6IHswfSJ9LAotCi0gIHsgRVJfTlVMTF9FUlJPUl9IQU5ETEVSLAotICAgICAgICAiSGFuZGxlciBkZWdsaSBlcnJvcmkgbnVsbG8ifSwKLQotICB7IEVSX1BST0dfQVNTRVJUX1VOS05PV05fT1BDT0RFLAotICAgICAgICJBc3Nlcnppb25lIGRlbCBwcm9ncmFtbWF0b3JlOiBvcGNvZGUgezB9IHNjb25vc2NpdXRvIn0sCi0KLSAgeyBFUl9aRVJPX09SX09ORSwKLSAgICAgICAiMCBvIDEifSwKLQotICB7IEVSX1JURl9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSLAotICAgICAgICJydGYoKSBub24gc3VwcG9ydGF0byBkYSBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciJ9LAotCi0gIHsgRVJfUlRGX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIsCi0gICAgICAgImFzTm9kZUl0ZXJhdG9yKCkgbm9uIHN1cHBvcnRhdG8gZGEgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIifSwKLQotICAgICAgICAvKiogIGRldGFjaCgpIG5vdCBzdXBwb3J0ZWQgYnkgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIgICAqLwotICAgeyBFUl9ERVRBQ0hfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiwKLSAgICAgICAgICAgICAgICAiZGV0YWNoKCkgbm9uIHN1cHBvcnRhdG8gZGEgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIifSwKLQotICAgICAgICAvKiogIG51bSgpIG5vdCBzdXBwb3J0ZWQgYnkgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIgICAqLwotICAgeyBFUl9OVU1fTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiwKLSAgICAgICAgICAgICAgICAibnVtKCkgbm9uIHN1cHBvcnRhdG8gZGEgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIifSwKLQotICAgICAgICAvKiogIHhzdHIoKSBub3Qgc3VwcG9ydGVkIGJ5IFhSVHJlZUZyYWdTZWxlY3RXcmFwcGVyICAgKi8KLSAgIHsgRVJfWFNUUl9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSLAotICAgICAgICAgICAgICAgICJ4c3RyKCkgbm9uIHN1cHBvcnRhdG8gZGEgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIifSwKLQotICAgICAgICAvKiogIHN0cigpIG5vdCBzdXBwb3J0ZWQgYnkgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIgICAqLwotICAgeyBFUl9TVFJfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiwKLSAgICAgICAgICAgICAgICAic3RyKCkgbm9uIHN1cHBvcnRhdG8gZGEgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIifSwKLQotICB7IEVSX0ZTQl9OT1RfU1VQUE9SVEVEX1hTVFJJTkdGT1JDSEFSUywKLSAgICAgICAiZnNiKCkgbm9uIHN1cHBvcnRhdG8gcGVyIFhTdHJpbmdGb3JDaGFycyJ9LAotCi0gIHsgRVJfQ09VTERfTk9UX0ZJTkRfVkFSLAotICAgICAgIkltcG9zc2liaWxlIHRyb3ZhcmUgbGEgdmFyaWFiaWxlIGNvbiBub21lIHswfSJ9LAotCi0gIHsgRVJfWFNUUklOR0ZPUkNIQVJTX0NBTk5PVF9UQUtFX1NUUklORywKLSAgICAgICJYU3RyaW5nRm9yQ2hhcnMgbm9uIHB1XHUwMEYyIGF2ZXJlIHVuYSBzdHJpbmdhIHBlciB1biBhcmdvbWVudG8ifSwKLQotICB7IEVSX0ZBU1RTVFJJTkdCVUZGRVJfQ0FOTk9UX0JFX05VTEwsCi0gICAgICAiTCdhcmdvbWVudG8gRmFzdFN0cmluZ0J1ZmZlciBub24gcHVcdTAwRjIgZXNzZXJlIG51bGxvIn0sCi0KLSAgeyBFUl9UV09fT1JfVEhSRUUsCi0gICAgICAgIjIgbyAzIn0sCi0KLSAgeyBFUl9WQVJJQUJMRV9BQ0NFU1NFRF9CRUZPUkVfQklORCwKLSAgICAgICAiQWNjZXNzbyBhbGxhIHZhcmlhYmlsZSBlc2VndWl0byBwcmltYSBjaGUgZm9zc2UgYXNzb2NpYXRhLiJ9LAotCi0gIHsgRVJfRlNCX0NBTk5PVF9UQUtFX1NUUklORywKLSAgICAgICAiWFN0cmluZ0ZvckZTQiBub24gcHVcdTAwRjIgYXZlcmUgdW5hIHN0cmluZ2EgcGVyIHVuIGFyZ29tZW50byJ9LAotCi0gIHsgRVJfU0VUVElOR19XQUxLRVJfUk9PVF9UT19OVUxMLAotICAgICAgICJcbiAhISEhIEVycm9yZS4gU2kgc3RhIGltcG9zdGFuZG8gcmFkaWNlIGRpIHVuIHdhbGtlciBzdSB1biB2YWxvcmUgbnVsbG8uIn0sCi0KLSAgeyBFUl9OT0RFU0VURFRNX0NBTk5PVF9JVEVSQVRFLAotICAgICAgICJRdWVzdG8gTm9kZVNldERUTSBub24gcHVcdTAwRjIgZXNlZ3VpcmUgdW4naXRlcmF6aW9uZSBhIHVuIG5vZG8gcHJlY2VkZW50ZS4ifSwKLQotICB7IEVSX05PREVTRVRfQ0FOTk9UX0lURVJBVEUsCi0gICAgICAgIlF1ZXN0byBOb2RlU2V0IG5vbiBwdVx1MDBGMiBlc2VndWlyZSB1bidpdGVyYXppb25lIGEgdW4gbm9kbyBwcmVjZWRlbnRlLiJ9LAotCi0gIHsgRVJfTk9ERVNFVERUTV9DQU5OT1RfSU5ERVgsCi0gICAgICAgIlF1ZXN0byBOb2RlU2V0RFRNIG5vbiBwdVx1MDBGMiBlc2VndWlyZSBsJ2luZGljaXp6YXppb25lIG8gaWwgY29udGVnZ2lvIGRlbGxlIGZ1bnppb25pLiJ9LAotCi0gIHsgRVJfTk9ERVNFVF9DQU5OT1RfSU5ERVgsCi0gICAgICAgIlF1ZXN0byBOb2RlU2V0IG5vbiBwdVx1MDBGMiBlc2VndWlyZSBsJ2luZGljaXp6YXppb25lIG8gaWwgY29udGVnZ2lvIGRlbGxlIGZ1bnppb25pLiJ9LAotCi0gIHsgRVJfQ0FOTk9UX0NBTExfU0VUU0hPVUxEQ0FDSEVOT0RFLAotICAgICAgICJJbXBvc3NpYmlsZSByaWNoaWFtYXJlIHNldFNob3VsZENhY2hlTm9kZXMgZG9wbyBhdmVyIHJpY2hpYW1hdG8gbmV4dE5vZGUuIn0sCi0KLSAgeyBFUl9PTkxZX0FMTE9XUywKLSAgICAgICAiezB9IGNvbnNlbnRlIHNvbG8gezF9IGFyZ29tZW50aSJ9LAotCi0gIHsgRVJfVU5LTk9XTl9TVEVQLAotICAgICAgICJBc3Nlcnppb25lIGRlbCBwcm9ncmFtbWF0b3JlIGluIGdldE5leHRTdGVwUG9zOiBzdGVwVHlwZSB7MH0gc2Nvbm9zY2l1dG8ifSwKLQotICAvL05vdGUgdG8gdHJhbnNsYXRvcnM6ICBBIHJlbGF0aXZlIGxvY2F0aW9uIHBhdGggaXMgYSBmb3JtIG9mIFhQYXRoIGV4cHJlc3Npb24uCi0gIC8vIFRoZSBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHN1Y2ggYW4gZXhwcmVzc2lvbiB3YXMgZXhwZWN0ZWQgZm9sbG93aW5nIHRoZQotICAvLyBjaGFyYWN0ZXJzICcvJyBvciAnLy8nLCBidXQgd2FzIG5vdCBmb3VuZC4KLSAgeyBFUl9FWFBFQ1RFRF9SRUxfTE9DX1BBVEgsCi0gICAgICAiXHUwMEM4IHByZXZpc3RvIHVuIHBlcmNvcnNvIGRpIHBvc2l6aW9uZSByZWxhdGl2YSBkb3BvIGlsIHRva2VuICcvJyBvICcvLycuIn0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIEEgbG9jYXRpb24gcGF0aCBpcyBhIGZvcm0gb2YgWFBhdGggZXhwcmVzc2lvbi4KLSAgLy8gVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgc3ludGFjdGljYWxseSBzdWNoIGFuIGV4cHJlc3Npb24gd2FzIGV4cGVjdGVkLGJ1dAotICAvLyB0aGUgY2hhcmFjdGVycyBzcGVjaWZpZWQgYnkgdGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHdlcmUgZW5jb3VudGVyZWQgaW5zdGVhZC4KLSAgeyBFUl9FWFBFQ1RFRF9MT0NfUEFUSCwKLSAgICAgICAiXHUwMEM4IHByZXZpc3RvIHVuIHBlcmNvcnNvIGRpIHBvc2l6aW9uZSwgbWEgXHUwMEU4IHN0YXRvIHRyb3ZhdG8gaWwgc2VndWVudGUgdG9rZW46ICB7MH0ifSwKLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQSBsb2NhdGlvbiBwYXRoIGlzIGEgZm9ybSBvZiBYUGF0aCBleHByZXNzaW9uLgotICAvLyBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCBzeW50YWN0aWNhbGx5IHN1Y2ggYSBzdWJleHByZXNzaW9uIHdhcyBleHBlY3RlZCwKLSAgLy8gYnV0IG5vIG1vcmUgY2hhcmFjdGVycyB3ZXJlIGZvdW5kIGluIHRoZSBleHByZXNzaW9uLgotICB7IEVSX0VYUEVDVEVEX0xPQ19QQVRIX0FUX0VORF9FWFBSLAotICAgICAgICJcdTAwQzggcHJldmlzdG8gdW4gcGVyY29yc28gZGkgcG9zaXppb25lLCBtYSBcdTAwRTggc3RhdGEgdHJvdmF0YSBsYSBmaW5lIGRlbGwnZXNwcmVzc2lvbmUgWFBhdGguIn0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIEEgbG9jYXRpb24gc3RlcCBpcyBwYXJ0IG9mIGFuIFhQYXRoIGV4cHJlc3Npb24uCi0gIC8vIFRoZSBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHN5bnRhY3RpY2FsbHkgc3VjaCBhbiBleHByZXNzaW9uIHdhcyBleHBlY3RlZAotICAvLyBmb2xsb3dpbmcgdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXJzLgotICB7IEVSX0VYUEVDVEVEX0xPQ19TVEVQLAotICAgICAgICJcdTAwQzggcHJldmlzdG8gdW4gcGFzc28gZGkgcG9zaXppb25lIGRvcG8gaWwgdG9rZW4gJy8nIG8gJy8vJy4ifSwKLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQSBub2RlIHRlc3QgaXMgcGFydCBvZiBhbiBYUGF0aCBleHByZXNzaW9uIHRoYXQgaXMKLSAgLy8gdXNlZCB0byB0ZXN0IGZvciBwYXJ0aWN1bGFyIGtpbmRzIG9mIG5vZGVzLiAgSW4gdGhpcyBjYXNlLCBhIG5vZGUgdGVzdCB0aGF0Ci0gIC8vIGNvbnNpc3RzIG9mIGFuIE5DTmFtZSBmb2xsb3dlZCBieSBhIGNvbG9uIGFuZCBhbiBhc3RlcmlzayBvciB0aGF0IGNvbnNpc3RzCi0gIC8vIG9mIGEgUU5hbWUgd2FzIGV4cGVjdGVkLCBidXQgd2FzIG5vdCBmb3VuZC4KLSAgeyBFUl9FWFBFQ1RFRF9OT0RFX1RFU1QsCi0gICAgICAgIlx1MDBDOCBwcmV2aXN0byB1biB0ZXN0IGRlbCBub2RvIGNoZSBjb3JyaXNwb25kYSBhIE5DTmFtZToqIG8gYSBRTmFtZS4ifSwKLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQSBzdGVwIHBhdHRlcm4gaXMgcGFydCBvZiBhbiBYUGF0aCBleHByZXNzaW9uLgotICAvLyBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCBzeW50YWN0aWNhbGx5IHN1Y2ggYW4gZXhwcmVzc2lvbiB3YXMgZXhwZWN0ZWQsCi0gIC8vIGJ1dCB0aGUgc3BlY2lmaWVkIGNoYXJhY3RlciB3YXMgZm91bmQgaW4gdGhlIGV4cHJlc3Npb24gaW5zdGVhZC4KLSAgeyBFUl9FWFBFQ1RFRF9TVEVQX1BBVFRFUk4sCi0gICAgICAgIlx1MDBDOCBwcmV2aXN0byB1biBwYXR0ZXJuIGRpIHBhc3NvLCBtYSBcdTAwRTggc3RhdG8gdHJvdmF0byAnLycuIn0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogQSByZWxhdGl2ZSBwYXRoIHBhdHRlcm4gaXMgcGFydCBvZiBhbiBYUGF0aCBleHByZXNzaW9uLgotICAvLyBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCBzeW50YWN0aWNhbGx5IHN1Y2ggYW4gZXhwcmVzc2lvbiB3YXMgZXhwZWN0ZWQsCi0gIC8vIGJ1dCB3YXMgbm90IGZvdW5kLgotICB7IEVSX0VYUEVDVEVEX1JFTF9QQVRIX1BBVFRFUk4sCi0gICAgICAgIlx1MDBDOCBwcmV2aXN0byB1biBwYXR0ZXJuIGRpIHBlcmNvcnNvIHJlbGF0aXZvLiJ9LAotCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYSBkYXRhIHR5cGUuICBUaGUKLSAgLy8gbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCBhIHZhbHVlIG9mIGEgcGFydGljdWxhciB0eXBlIGNvdWxkIG5vdCBiZSBjb252ZXJ0ZWQKLSAgLy8gdG8gYSB2YWx1ZSBvZiB0eXBlIGJvb2xlYW4uCi0gIHsgRVJfQ0FOVF9DT05WRVJUX1RPX0JPT0xFQU4sCi0gICAgICAgIlhQYXRoUmVzdWx0IGRlbGwnJ2VzcHJlc3Npb25lIFhQYXRoICcnezB9JycgYSB1biB2YWxvcmUgZGkgWFBhdGhSZXN1bHRUeXBlIHBhcmkgYSB7MX0gY2hlIG5vbiBwdVx1MDBGMiBlc3NlcmUgY29udmVydGl0byBpbiB1biB2YWxvcmUgYm9vbGVhbm8uIn0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogRG8gbm90IHRyYW5zbGF0ZSBBTllfVU5PUkRFUkVEX05PREVfVFlQRSBhbmQKLSAgLy8gRklSU1RfT1JERVJFRF9OT0RFX1RZUEUuCi0gIHsgRVJfQ0FOVF9DT05WRVJUX1RPX1NJTkdMRU5PREUsCi0gICAgICAgIlhQYXRoUmVzdWx0IGRlbGwnJ2VzcHJlc3Npb25lIFhQYXRoICcnezB9JycgYSB1biB2YWxvcmUgZGkgWFBhdGhSZXN1bHRUeXBlIHBhcmkgYSB7MX0gY2hlIG5vbiBwdVx1MDBGMiBlc3NlcmUgY29udmVydGl0byBpbiB1biBub2RvIHNpbmdvbG8uIElsIG1ldG9kbyBnZXRTaW5nbGVOb2RlVmFsdWUgXHUwMEU4IHZhbGlkbyBzb2xvIHBlciBpIHRpcGkgQU5ZX1VOT1JERVJFRF9OT0RFX1RZUEUgZSBGSVJTVF9PUkRFUkVEX05PREVfVFlQRS4ifSwKLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiBEbyBub3QgdHJhbnNsYXRlIFVOT1JERVJFRF9OT0RFX1NOQVBTSE9UX1RZUEUgYW5kCi0gIC8vIE9SREVSRURfTk9ERV9TTkFQU0hPVF9UWVBFLgotICB7IEVSX0NBTlRfR0VUX1NOQVBTSE9UX0xFTkdUSCwKLSAgICAgICAiSW1wb3NzaWJpbGUgcmljaGlhbWFyZSBpbCBtZXRvZG8gZ2V0U25hcHNob3RMZW5ndGggbmVsbCcnWFBhdGhSZXN1bHQgZGVsbCcnZXNwcmVzc2lvbmUgWFBhdGggJyd7MH0nJyBwb2ljaFx1MDBFOSBpbCB2YWxvcmUgZGkgWFBhdGhSZXN1bHRUeXBlIFx1MDBFOCB7MX0uIFF1ZXN0byBtZXRvZG8gXHUwMEU4IHZhbGlkbyBzb2xvIHBlciBpIHRpcGkgVU5PUkRFUkVEX05PREVfU05BUFNIT1RfVFlQRSBlIE9SREVSRURfTk9ERV9TTkFQU0hPVF9UWVBFLiJ9LAotCi0gIHsgRVJfTk9OX0lURVJBVE9SX1RZUEUsCi0gICAgICAgIkltcG9zc2liaWxlIHJpY2hpYW1hcmUgaWwgbWV0b2RvIGl0ZXJhdGVOZXh0IG5lbGwnJ1hQYXRoUmVzdWx0IGRlbGwnJ2VzcHJlc3Npb25lIFhQYXRoICcnezB9JycgcG9pY2hcdTAwRTkgaWwgdmFsb3JlIGRpIFhQYXRoUmVzdWx0VHlwZSBcdTAwRTggezF9LiBRdWVzdG8gbWV0b2RvIFx1MDBFOCB2YWxpZG8gc29sbyBwZXIgaSB0aXBpIFVOT1JERVJFRF9OT0RFX0lURVJBVE9SX1RZUEUgZSBPUkRFUkVEX05PREVfSVRFUkFUT1JfVFlQRS4ifSwKLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiBUaGlzIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhlIGRvY3VtZW50IGJlaW5nIG9wZXJhdGVkCi0gIC8vIHVwb24gY2hhbmdlZCwgc28gdGhlIGl0ZXJhdG9yIG9iamVjdCB0aGF0IHdhcyBiZWluZyB1c2VkIHRvIHRyYXZlcnNlIHRoZQotICAvLyBkb2N1bWVudCBoYXMgbm93IGJlY29tZSBpbnZhbGlkLgotICB7IEVSX0RPQ19NVVRBVEVELAotICAgICAgICJJbCBkb2N1bWVudG8gXHUwMEU4IGNhbWJpYXRvIGRhIHF1YW5kbyBcdTAwRTggc3RhdG8gcmVzdGl0dWl0byBsJ3VsdGltbyByaXN1bHRhdG8uIEwnaXRlcmF0b3JlIG5vbiBcdTAwRTggdmFsaWRvLiJ9LAotCi0gIHsgRVJfSU5WQUxJRF9YUEFUSF9UWVBFLAotICAgICAgICJUaXBvIGRpIGFyZ29tZW50byBYUGF0aCBub24gdmFsaWRvOiB7MH0ifSwKLQotICB7IEVSX0VNUFRZX1hQQVRIX1JFU1VMVCwKLSAgICAgICAiT2dnZXR0byByaXN1bHRhdGkgWFBhdGggdnVvdG8ifSwKLQotICB7IEVSX0lOQ09NUEFUSUJMRV9UWVBFUywKLSAgICAgICAiWFBhdGhSZXN1bHQgZGVsbCcnZXNwcmVzc2lvbmUgWFBhdGggJyd7MH0nJyBhIHVuIHZhbG9yZSBkaSBYUGF0aFJlc3VsdFR5cGUgcGFyaSBhIHsxfSBjaGUgbm9uIHB1XHUwMEYyIGVzc2VyZSBjb252ZXJ0aXRvIGZvcnphdGFtZW50ZSBuZWwgdmFsb3JlIFhQYXRoUmVzdWx0VHlwZSB7Mn0uIn0sCi0KLSAgeyBFUl9OVUxMX1JFU09MVkVSLAotICAgICAgICJJbXBvc3NpYmlsZSByaXNvbHZlcmUgaWwgcHJlZmlzc28gY29uIHVuIHJlc29sdmVyIGRpIHByZWZpc3NpIG51bGxvLiJ9LAotCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYSBkYXRhIHR5cGUuICBUaGUKLSAgLy8gbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCBhIHZhbHVlIG9mIGEgcGFydGljdWxhciB0eXBlIGNvdWxkIG5vdCBiZSBjb252ZXJ0ZWQKLSAgLy8gdG8gYSB2YWx1ZSBvZiB0eXBlIHN0cmluZy4KLSAgeyBFUl9DQU5UX0NPTlZFUlRfVE9fU1RSSU5HLAotICAgICAgICJYUGF0aFJlc3VsdCBkZWxsJydlc3ByZXNzaW9uZSBYUGF0aCAnJ3swfScnIGEgdW4gdmFsb3JlIGRpIFhQYXRoUmVzdWx0VHlwZSBwYXJpIGEgezF9IGNoZSBub24gcHVcdTAwRjIgZXNzZXJlIGNvbnZlcnRpdG8gaW4gdW5hIHN0cmluZ2EuIn0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogRG8gbm90IHRyYW5zbGF0ZSBzbmFwc2hvdEl0ZW0sCi0gIC8vIFVOT1JERVJFRF9OT0RFX1NOQVBTSE9UX1RZUEUgYW5kIE9SREVSRURfTk9ERV9TTkFQU0hPVF9UWVBFLgotICB7IEVSX05PTl9TTkFQU0hPVF9UWVBFLAotICAgICAgICJJbXBvc3NpYmlsZSByaWNoaWFtYXJlIGlsIG1ldG9kbyBzbmFwc2hvdEl0ZW0gbmVsbCcnWFBhdGhSZXN1bHQgZGVsbCcnZXNwcmVzc2lvbmUgWFBhdGggJyd7MH0nJyBwb2ljaFx1MDBFOSBpbCB2YWxvcmUgZGkgWFBhdGhSZXN1bHRUeXBlIFx1MDBFOCB7MX0uIFF1ZXN0byBtZXRvZG8gXHUwMEU4IHZhbGlkbyBzb2xvIHBlciBpIHRpcGkgVU5PUkRFUkVEX05PREVfU05BUFNIT1RfVFlQRSBlIE9SREVSRURfTk9ERV9TTkFQU0hPVF9UWVBFLiJ9LAotCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBYUGF0aEV2YWx1YXRvciBpcyBhIEphdmEgaW50ZXJmYWNlIG5hbWUuICBBbgotICAvLyBYUGF0aEV2YWx1YXRvciBpcyBjcmVhdGVkIHdpdGggcmVzcGVjdCB0byBhIHBhcnRpY3VsYXIgWE1MIGRvY3VtZW50LCBhbmQgaW4KLSAgLy8gdGhpcyBjYXNlIHRoZSBleHByZXNzaW9uIHJlcHJlc2VudGVkIGJ5IHRoaXMgb2JqZWN0IHdhcyBiZWluZyBldmFsdWF0ZWQgd2l0aAotICAvLyByZXNwZWN0IHRvIGEgY29udGV4dCBub2RlIGZyb20gYSBkaWZmZXJlbnQgZG9jdW1lbnQuCi0gIHsgRVJfV1JPTkdfRE9DVU1FTlQsCi0gICAgICAgIklsIG5vZG8gZGkgY29udGVzdG8gbm9uIGFwcGFydGllbmUgYWwgZG9jdW1lbnRvIGFzc29jaWF0byBhIHF1ZXN0byBYUGF0aEV2YWx1YXRvci4ifSwKLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIFhQYXRoIGV4cHJlc3Npb24gY2Fubm90IGJlIGV2YWx1YXRlZCB3aXRoIHJlc3BlY3QKLSAgLy8gdG8gdGhpcyB0eXBlIG9mIG5vZGUuCi0gIHsgRVJfV1JPTkdfTk9ERVRZUEUsCi0gICAgICAgIklsIHRpcG8gZGkgbm9kbyBkaSBjb250ZXN0byBub24gXHUwMEU4IHN1cHBvcnRhdG8uIn0sCi0KLSAgeyBFUl9YUEFUSF9FUlJPUiwKLSAgICAgICAiRXJyb3JlIHNjb25vc2NpdXRvIG5lbGwnWFBhdGguIn0sCi0KLSAgeyBFUl9DQU5UX0NPTlZFUlRfWFBBVEhSRVNVTFRUWVBFX1RPX05VTUJFUiwKLSAgICAgICAgIlhQYXRoUmVzdWx0IGRlbGwnJ2VzcHJlc3Npb25lIFhQYXRoICcnezB9JycgYSB1biB2YWxvcmUgZGkgWFBhdGhSZXN1bHRUeXBlIHBhcmkgYSB7MX0gY2hlIG5vbiBwdVx1MDBGMiBlc3NlcmUgY29udmVydGl0byBpbiB1biBudW1lcm8uIn0sCi0KLSAgLy9CRUdJTjogIERlZmluaXRpb25zIG9mIGVycm9yIGtleXMgdXNlZCAgaW4gZXhjZXB0aW9uIG1lc3NhZ2VzIG9mICBKQVhQIDEuMyBYUGF0aCBBUEkgaW1wbGVtZW50YXRpb24KLQotICAvKiogRmllbGQgRVJfRVhURU5TSU9OX0ZVTkNUSU9OX0NBTk5PVF9CRV9JTlZPS0VEICAgICAgICAgICAgICAgICAgICAgICAqLwotCi0gIHsgRVJfRVhURU5TSU9OX0ZVTkNUSU9OX0NBTk5PVF9CRV9JTlZPS0VELAotICAgICAgICJJbXBvc3NpYmlsZSByaWNoaWFtYXJlIGxhIGZ1bnppb25lIGRpIGVzdGVuc2lvbmUgJyd7MH0nJyBzZSBsYSBmdW56aW9uZSBYTUxDb25zdGFudHMuRkVBVFVSRV9TRUNVUkVfUFJPQ0VTU0lORyBcdTAwRTggaW1wb3N0YXRhIHN1IHRydWUuIn0sCi0KLSAgLyoqIEZpZWxkIEVSX1JFU09MVkVfVkFSSUFCTEVfUkVUVVJOU19OVUxMICAgICAgICAgICAgICAgICAgICAgICAqLwotCi0gIHsgRVJfUkVTT0xWRV9WQVJJQUJMRV9SRVRVUk5TX05VTEwsCi0gICAgICAgInJlc29sdmVWYXJpYWJsZSBwZXIgbGEgdmFyaWFiaWxlIHswfSBoYSByZXN0aXR1aXRvIHVuIHZhbG9yZSBudWxsbyJ9LAotCi0gIC8qKiBGaWVsZCBFUl9VTlNVUFBPUlRFRF9SRVRVUk5fVFlQRSAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX1VOU1VQUE9SVEVEX1JFVFVSTl9UWVBFLAotICAgICAgICJUaXBvIHJlc3RpdHVpdG8gbm9uIHN1cHBvcnRhdG86IHswfSJ9LAotCi0gIC8qKiBGaWVsZCBFUl9TT1VSQ0VfUkVUVVJOX1RZUEVfQ0FOTk9UX0JFX05VTEwgICAgICAgICAgICAgICAgICAgICAgICovCi0KLSAgeyBFUl9TT1VSQ0VfUkVUVVJOX1RZUEVfQ0FOTk9UX0JFX05VTEwsCi0gICAgICAgIklsIHRpcG8gZGkgb3JpZ2luZSBlL28gcmVzdGl0dWl0byBub24gcHVcdTAwRjIgZXNzZXJlIG51bGxvIn0sCi0KLSAgLyoqIEZpZWxkIEVSX1NPVVJDRV9SRVRVUk5fVFlQRV9DQU5OT1RfQkVfTlVMTCAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX1NPVVJDRV9SRVRVUk5fVFlQRV9DQU5OT1RfQkVfTlVMTCwKLSAgICAgICAiSWwgdGlwbyBkaSBvcmlnaW5lIGUvbyByZXN0aXR1aXRvIG5vbiBwdVx1MDBGMiBlc3NlcmUgbnVsbG8ifSwKLQotICAvKiogRmllbGQgRVJfQVJHX0NBTk5PVF9CRV9OVUxMICAgICAgICAgICAgICAgICAgICAgICAqLwotCi0gIHsgRVJfQVJHX0NBTk5PVF9CRV9OVUxMLAotICAgICAgICJMJydhcmdvbWVudG8gezB9IG5vbiBwdVx1MDBGMiBlc3NlcmUgbnVsbG8ifSwKLQotICAvKiogRmllbGQgRVJfT0JKRUNUX01PREVMX05VTEwgICAgICAgICAgICAgICAgICAgICAgICovCi0KLSAgeyBFUl9PQkpFQ1RfTU9ERUxfTlVMTCwKLSAgICAgICAiezB9I2lzT2JqZWN0TW9kZWxTdXBwb3J0ZWQoIFN0cmluZyBvYmplY3RNb2RlbCApIG5vbiBwdVx1MDBGMiBlc3NlcmUgcmljaGlhbWF0byBzZSBvYmplY3RNb2RlbCA9PSBudWxsIn0sCi0KLSAgLyoqIEZpZWxkIEVSX09CSkVDVF9NT0RFTF9FTVBUWSAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX09CSkVDVF9NT0RFTF9FTVBUWSwKLSAgICAgICAiezB9I2lzT2JqZWN0TW9kZWxTdXBwb3J0ZWQoIFN0cmluZyBvYmplY3RNb2RlbCApIG5vbiBwdVx1MDBGMiBlc3NlcmUgcmljaGlhbWF0byBzZSBvYmplY3RNb2RlbCA9PSBcIlwiIn0sCi0KLSAgLyoqIEZpZWxkIEVSX09CSkVDVF9NT0RFTF9FTVBUWSAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX0ZFQVRVUkVfTkFNRV9OVUxMLAotICAgICAgICJUZW50YXRpdm8gZGkgaW1wb3N0YXJlIHVuYSBmdW56aW9uZSBjb24gbm9tZSBudWxsbzogezB9I3NldEZlYXR1cmUoIG51bGwsIHsxfSkifSwKLQotICAvKiogRmllbGQgRVJfRkVBVFVSRV9VTktOT1dOICAgICAgICAgICAgICAgICAgICAgICAqLwotCi0gIHsgRVJfRkVBVFVSRV9VTktOT1dOLAotICAgICAgICJUZW50YXRpdm8gZGkgaW1wb3N0YXJlIGxhIGZ1bnppb25lIHNjb25vc2NpdXRhIFwiezB9XCI6ezF9I3NldEZlYXR1cmUoezB9LHsyfSkifSwKLQotICAvKiogRmllbGQgRVJfR0VUVElOR19OVUxMX0ZFQVRVUkUgICAgICAgICAgICAgICAgICAgICAgICovCi0KLSAgeyBFUl9HRVRUSU5HX05VTExfRkVBVFVSRSwKLSAgICAgICAiVGVudGF0aXZvIGRpIHJlY3VwZXJhcmUgdW5hIGZ1bnppb25lIGNvbiBub21lIG51bGxvOiB7MH0jZ2V0RmVhdHVyZShudWxsKSJ9LAotCi0gIC8qKiBGaWVsZCBFUl9HRVRUSU5HX05VTExfRkVBVFVSRSAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX0dFVFRJTkdfVU5LTk9XTl9GRUFUVVJFLAotICAgICAgICJUZW50YXRpdm8gZGkgcmVjdXBlcmFyZSBsYSBmdW56aW9uZSBzY29ub3NjaXV0YSBcInswfVwiOnsxfSNnZXRGZWF0dXJlKHswfSkifSwKLQotICB7RVJfU0VDVVJFUFJPQ0VTU0lOR19GRUFUVVJFLAotICAgICAgICAiRkVBVFVSRV9TRUNVUkVfUFJPQ0VTU0lORzogaW1wb3NzaWJpbGUgaW1wb3N0YXJlIGxhIGZ1bnppb25lIHN1IGZhbHNlIHNlIFx1MDBFOCBwcmVzZW50ZSBTZWN1cml0eSBNYW5hZ2VyOiB7MX0jc2V0RmVhdHVyZSh7MH0sezJ9KSJ9LAotCi0gIC8qKiBGaWVsZCBFUl9OVUxMX1hQQVRIX0ZVTkNUSU9OX1JFU09MVkVSICAgICAgICAgICAgICAgICAgICAgICAqLwotCi0gIHsgRVJfTlVMTF9YUEFUSF9GVU5DVElPTl9SRVNPTFZFUiwKLSAgICAgICAiVGVudGF0aXZvIGRpIGltcG9zdGFyZSB1biB2YWxvcmUgIG51bGxvIHBlciBYUGF0aEZ1bmN0aW9uUmVzb2x2ZXI6ezB9I3NldFhQYXRoRnVuY3Rpb25SZXNvbHZlcihudWxsKSJ9LAotCi0gIC8qKiBGaWVsZCBFUl9OVUxMX1hQQVRIX1ZBUklBQkxFX1JFU09MVkVSICAgICAgICAgICAgICAgICAgICAgICAqLwotCi0gIHsgRVJfTlVMTF9YUEFUSF9WQVJJQUJMRV9SRVNPTFZFUiwKLSAgICAgICAiVGVudGF0aXZvIGRpIGltcG9zdGFyZSB1biB2YWxvcmUgIG51bGxvIHBlciBYUGF0aFZhcmlhYmxlUmVzb2x2ZXI6ezB9I3NldFhQYXRoVmFyaWFibGVSZXNvbHZlcihudWxsKSJ9LAotCi0gIC8vRU5EOiAgRGVmaW5pdGlvbnMgb2YgZXJyb3Iga2V5cyB1c2VkICBpbiBleGNlcHRpb24gbWVzc2FnZXMgb2YgIEpBWFAgMS4zIFhQYXRoIEFQSSBpbXBsZW1lbnRhdGlvbgotCi0gIC8vIFdhcm5pbmdzLi4uCi0KLSAgeyBXR19MT0NBTEVfTkFNRV9OT1RfSEFORExFRCwKLSAgICAgICJpbCBub21lIGRpIGltcG9zdGF6aW9uaSBuYXppb25hbGkgbmVsbGEgZnVuemlvbmUgZm9ybWF0LW51bWJlciBub24gXHUwMEU4IGFuY29yYSBnZXN0aXRvLiJ9LAotCi0gIHsgV0dfUFJPUEVSVFlfTk9UX1NVUFBPUlRFRCwKLSAgICAgICJQcm9wcmlldFx1MDBFMCBYU0wgbm9uIHN1cHBvcnRhdGE6IHswfSJ9LAotCi0gIHsgV0dfRE9OVF9ET19BTllUSElOR19XSVRIX05TLAotICAgICAgIk5vbiBlZmZldHR1YXJlIGFsY3VuYSBvcGVyYXppb25lIHN1bGxvIHNwYXppbyBkaSBub21pIHswfSBuZWxsYSBwcm9wcmlldFx1MDBFMDogezF9In0sCi0KLSAgeyBXR19TRUNVUklUWV9FWENFUFRJT04sCi0gICAgICAiU2VjdXJpdHlFeGNlcHRpb24gbmVsIHRlbnRhdGl2byBkaSBhY2NlZGVyZSBhbGxhIHByb3ByaWV0XHUwMEUwIGRpIHNpc3RlbWEgWFNMIHswfSJ9LAotCi0gIHsgV0dfUVVPX05PX0xPTkdFUl9ERUZJTkVELAotICAgICAgIlNpbnRhc3NpIG9ic29sZXRhOiBxdW8oLi4uKSBub24gXHUwMEU4IHBpXHUwMEY5IGRlZmluaXRvIG5lbGwnWFBhdGguIn0sCi0KLSAgeyBXR19ORUVEX0RFUklWRURfT0JKRUNUX1RPX0lNUExFTUVOVF9OT0RFVEVTVCwKLSAgICAgICJMJ1hQYXRoIHJpY2hpZWRlIHVuIG9nZ2V0dG8gZGVyaXZhdG8gY2hlIGltcGxlbWVudGkgbm9kZVRlc3QuIn0sCi0KLSAgeyBXR19GVU5DVElPTl9UT0tFTl9OT1RfRk9VTkQsCi0gICAgICAidG9rZW4gZGkgZnVuemlvbmUgbm9uIHRyb3ZhdG8uIn0sCi0KLSAgeyBXR19DT1VMRE5PVF9GSU5EX0ZVTkNUSU9OLAotICAgICAgIkltcG9zc2liaWxlIHRyb3ZhcmUgbGEgZnVuemlvbmUgezB9In0sCi0KLSAgeyBXR19DQU5OT1RfTUFLRV9VUkxfRlJPTSwKLSAgICAgICJJbXBvc3NpYmlsZSBjcmVhcmUgdW4gVVJMIGRhIHswfSJ9LAotCi0gIHsgV0dfRVhQQU5EX0VOVElUSUVTX05PVF9TVVBQT1JURUQsCi0gICAgICAiT3B6aW9uZSAtRSBub24gc3VwcG9ydGF0YSBwZXIgaWwgcGFyc2VyIERUTSJ9LAotCi0gIHsgV0dfSUxMRUdBTF9WQVJJQUJMRV9SRUZFUkVOQ0UsCi0gICAgICAiSWwgdmFsb3JlIGRpIFZhcmlhYmxlUmVmZXJlbmNlIHNwZWNpZmljYXRvIHBlciBsYSB2YXJpYWJpbGUgXHUwMEU4IGZ1b3JpIGNvbnRlc3RvIG8gc2VuemEgZGVmaW5pemlvbmUuIE5vbWUgPSB7MH0ifSwKLQotICB7IFdHX1VOU1VQUE9SVEVEX0VOQ09ESU5HLAotICAgICAiQ29kaWZpY2Egbm9uIHN1cHBvcnRhdGE6IHswfSJ9LAotCi0KLQotICAvLyBPdGhlciBtaXNjZWxsYW5lb3VzIHRleHQgdXNlZCBpbnNpZGUgdGhlIGNvZGUuLi4KLSAgeyAidWlfbGFuZ3VhZ2UiLCAiaXQifSwKLSAgeyAiaGVscF9sYW5ndWFnZSIsICJpdCJ9LAotICB7ICJsYW5ndWFnZSIsICJpdCJ9LAotICB7ICJCQURfQ09ERSIsICJQYXJhbWV0cm8gcGVyIGNyZWF0ZU1lc3NhZ2UgZnVvcmkgbGltaXRlIn0sCi0gIHsgIkZPUk1BVF9GQUlMRUQiLCAiRWNjZXppb25lIGR1cmFudGUgbGEgY2hpYW1hdGEgbWVzc2FnZUZvcm1hdCJ9LAotICB7ICJ2ZXJzaW9uIiwgIj4+Pj4+Pj4gVmVyc2lvbmUgWGFsYW4gIn0sCi0gIHsgInZlcnNpb24yIiwgIjw8PDw8PDwifSwKLSAgeyAieWVzIiwgInNcdTAwRUMifSwKLSAgeyAibGluZSIsICJOLiByaWdhIn0sCi0gIHsgImNvbHVtbiIsICJOLiBjb2xvbm5hIn0sCi0gIHsgInhzbGRvbmUiLCAiWFNMUHJvY2Vzc29yOiBvcGVyYXppb25lIGNvbXBsZXRhdGEifSwKLSAgeyAieHBhdGhfb3B0aW9uIiwgIm9wemlvbmkgeHBhdGg6ICJ9LAotICB7ICJvcHRpb25JTiIsICIgICBbLWluIGlucHV0WE1MVVJMXSJ9LAotICB7ICJvcHRpb25TZWxlY3QiLCAiICAgWy1zZWxlY3QgeHBhdGggZXhwcmVzc2lvbl0ifSwKLSAgeyAib3B0aW9uTWF0Y2giLCAiICAgWy1tYXRjaCBtYXRjaCBwYXR0ZXJuIChwZXIgbGEgZGlhZ25vc3RpY2EgZGVsbGUgY29ycmlzcG9uZGVuemUpXSJ9LAotICB7ICJvcHRpb25BbnlFeHByIiwgIkluIGFsdGVybmF0aXZhLCB1bidlc3ByZXNzaW9uZSB4cGF0aCBlc2VndWlyXHUwMEUwIGlsIGR1bXAgZGVsbGEgZGlhZ25vc3RpY2EuIn0sCi0gIHsgIm5vUGFyc2VybXNnMSIsICJQcm9jZXNzbyBYU0wgbm9uIHJpdXNjaXRvLiJ9LAotICB7ICJub1BhcnNlcm1zZzIiLCAiKiogSW1wb3NzaWJpbGUgdHJvdmFyZSBpbCBwYXJzZXIgKioifSwKLSAgeyAibm9QYXJzZXJtc2czIiwgIkNvbnRyb2xsYXJlIGlsIGNsYXNzcGF0aC4ifSwKLSAgeyAibm9QYXJzZXJtc2c0IiwgIlNlIG5vbiBcdTAwRTggZGlzcG9uaWJpbGUgdW4gcGFyc2VyIFhNTCBkaSBJQk0gcGVyIEphdmEsIFx1MDBFOCBwb3NzaWJpbGUgc2NhcmljYXJsbyBkYSJ9LAotICB7ICJub1BhcnNlcm1zZzUiLCAiQWxwaGFXb3JrcyBkaSBJQk06IGh0dHA6Ly93d3cuYWxwaGF3b3Jrcy5pYm0uY29tL2Zvcm11bGEveG1sIn0sCi0gIHsgImd0b25lIiwgIj4xIiB9LAotICB7ICJ6ZXJvIiwgIjAiIH0sCi0gIHsgIm9uZSIsICIxIiB9LAotICB7ICJ0d28iICwgIjIiIH0sCi0gIHsgInRocmVlIiwgIjMiIH0KLQotICB9OwotCi0gIC8qKgotICAgKiBHZXQgdGhlIGFzc29jaWF0aW9uIGxpc3QuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGFzc29jaWF0aW9uIGxpc3QuCi0gICAqLwotICBwdWJsaWMgT2JqZWN0W11bXSBnZXRDb250ZW50cygpCi0gIHsKLSAgICAgIHJldHVybiBfY29udGVudHM7Ci0gIH0KLQotCi0gIC8vID09PT09PT09PT09PT09PT09IElORlJBU1RSVUNUVVJFID09PT09PT09PT09PT09PT09PT09PT0KLQotICAvKiogRmllbGQgQkFEX0NPREUgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQkFEX0NPREUgPSAiQkFEX0NPREUiOwotCi0gIC8qKiBGaWVsZCBGT1JNQVRfRkFJTEVEICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEZPUk1BVF9GQUlMRUQgPSAiRk9STUFUX0ZBSUxFRCI7Ci0KLSAgLyoqIEZpZWxkIEVSUk9SX1JFU09VUkNFUyAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJPUl9SRVNPVVJDRVMgPQotICAgICJjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucmVzLlhQQVRIRXJyb3JSZXNvdXJjZXMiOwotCi0gIC8qKiBGaWVsZCBFUlJPUl9TVFJJTkcgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJST1JfU1RSSU5HID0gIiNlcnJvciI7Ci0KLSAgLyoqIEZpZWxkIEVSUk9SX0hFQURFUiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJPUl9IRUFERVIgPSAiRXJyb3I6ICI7Ci0KLSAgLyoqIEZpZWxkIFdBUk5JTkdfSEVBREVSICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdBUk5JTkdfSEVBREVSID0gIldhcm5pbmc6ICI7Ci0KLSAgLyoqIEZpZWxkIFhTTF9IRUFERVIgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgWFNMX0hFQURFUiA9ICJYU0wgIjsKLQotICAvKiogRmllbGQgWE1MX0hFQURFUiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxfSEVBREVSID0gIlhNTCAiOwotCi0gIC8qKiBGaWVsZCBRVUVSWV9IRUFERVIgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgUVVFUllfSEVBREVSID0gIlBBVFRFUk4gIjsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9yZXMvWFBBVEhFcnJvclJlc291cmNlc19qYS5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9yZXMvWFBBVEhFcnJvclJlc291cmNlc19qYS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA5ZGNkMDI2Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvcmVzL1hQQVRIRXJyb3JSZXNvdXJjZXNfamEuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDkzNiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5yZXM7Ci0KLWltcG9ydCBqYXZhLnV0aWwuTGlzdFJlc291cmNlQnVuZGxlOwotCi0vKioKLSAqIFNldCB1cCBlcnJvciBtZXNzYWdlcy4KLSAqIFdlIGJ1aWxkIGEgdHdvIGRpbWVuc2lvbmFsIGFycmF5IG9mIG1lc3NhZ2Uga2V5cyBhbmQKLSAqIG1lc3NhZ2Ugc3RyaW5ncy4gSW4gb3JkZXIgdG8gYWRkIGEgbmV3IG1lc3NhZ2UgaGVyZSwKLSAqIHlvdSBuZWVkIHRvIGZpcnN0IGFkZCBhIFN0YXRpYyBzdHJpbmcgY29uc3RhbnQgZm9yIHRoZQotICogS2V5IGFuZCB1cGRhdGUgdGhlIGNvbnRlbnRzIGFycmF5IHdpdGggS2V5LCBWYWx1ZSBwYWlyCi0gICogQWxzbyB5b3UgbmVlZCB0byAgdXBkYXRlIHRoZSBjb3VudCBvZiBtZXNzYWdlcyhNQVhfQ09ERSlvcgotICogdGhlIGNvdW50IG9mIHdhcm5pbmdzKE1BWF9XQVJOSU5HKSBbIEluZm9ybWF0aW9uIHB1cnBvc2Ugb25seV0KLSAqIEB4c2wudXNhZ2UgYWR2YW5jZWQKLSAqLwotcHVibGljIGNsYXNzIFhQQVRIRXJyb3JSZXNvdXJjZXNfamEgZXh0ZW5kcyBMaXN0UmVzb3VyY2VCdW5kbGUKLXsKLQotLyoKLSAqIEdlbmVyYWwgbm90ZXMgdG8gdHJhbnNsYXRvcnM6Ci0gKgotICogVGhpcyBmaWxlIGNvbnRhaW5zIGVycm9yIGFuZCB3YXJuaW5nIG1lc3NhZ2VzIHJlbGF0ZWQgdG8gWFBhdGggRXJyb3IKLSAqIEhhbmRsaW5nLgotICoKLSAqICAxKSBYYWxhbiAob3IgbW9yZSBwcm9wZXJseSwgWGFsYW4taW50ZXJwcmV0aXZlKSBhbmQgWFNMVEMgYXJlIG5hbWVzIG9mCi0gKiAgICAgY29tcG9uZW50cy4KLSAqICAgICBYU0xUIGlzIGFuIGFjcm9ueW0gZm9yICJYTUwgU3R5bGVzaGVldCBMYW5ndWFnZTogVHJhbnNmb3JtYXRpb25zIi4KLSAqICAgICBYU0xUQyBpcyBhbiBhY3JvbnltIGZvciBYU0xUIENvbXBpbGVyLgotICoKLSAqICAyKSBBIHN0eWxlc2hlZXQgaXMgYSBkZXNjcmlwdGlvbiBvZiBob3cgdG8gdHJhbnNmb3JtIGFuIGlucHV0IFhNTCBkb2N1bWVudAotICogICAgIGludG8gYSByZXN1bHRhbnQgWE1MIGRvY3VtZW50IChvciBIVE1MIGRvY3VtZW50IG9yIHRleHQpLiAgVGhlCi0gKiAgICAgc3R5bGVzaGVldCBpdHNlbGYgaXMgZGVzY3JpYmVkIGluIHRoZSBmb3JtIG9mIGFuIFhNTCBkb2N1bWVudC4KLSAqCi0gKiAgMykgQSB0ZW1wbGF0ZSBpcyBhIGNvbXBvbmVudCBvZiBhIHN0eWxlc2hlZXQgdGhhdCBpcyB1c2VkIHRvIG1hdGNoIGEKLSAqICAgICBwYXJ0aWN1bGFyIHBvcnRpb24gb2YgYW4gaW5wdXQgZG9jdW1lbnQgYW5kIHNwZWNpZmllcyB0aGUgZm9ybSBvZiB0aGUKLSAqICAgICBjb3JyZXNwb25kaW5nIHBvcnRpb24gb2YgdGhlIG91dHB1dCBkb2N1bWVudC4KLSAqCi0gKiAgNCkgQW4gZWxlbWVudCBpcyBhIG1hcmstdXAgdGFnIGluIGFuIFhNTCBkb2N1bWVudDsgYW4gYXR0cmlidXRlIGlzIGEKLSAqICAgICBtb2RpZmllciBvbiB0aGUgdGFnLiAgRm9yIGV4YW1wbGUsIGluIDxlbGVtIGF0dHI9J3ZhbCcgYXR0cjI9J3ZhbDInPgotICogICAgICJlbGVtIiBpcyBhbiBlbGVtZW50IG5hbWUsICJhdHRyIiBhbmQgImF0dHIyIiBhcmUgYXR0cmlidXRlIG5hbWVzIHdpdGgKLSAqICAgICB0aGUgdmFsdWVzICJ2YWwiIGFuZCAidmFsMiIsIHJlc3BlY3RpdmVseS4KLSAqCi0gKiAgNSkgQSBuYW1lc3BhY2UgZGVjbGFyYXRpb24gaXMgYSBzcGVjaWFsIGF0dHJpYnV0ZSB0aGF0IGlzIHVzZWQgdG8gYXNzb2NpYXRlCi0gKiAgICAgYSBwcmVmaXggd2l0aCBhIFVSSSAodGhlIG5hbWVzcGFjZSkuICBUaGUgbWVhbmluZ3Mgb2YgZWxlbWVudCBuYW1lcyBhbmQKLSAqICAgICBhdHRyaWJ1dGUgbmFtZXMgdGhhdCB1c2UgdGhhdCBwcmVmaXggYXJlIGRlZmluZWQgd2l0aCByZXNwZWN0IHRvIHRoYXQKLSAqICAgICBuYW1lc3BhY2UuCi0gKgotICogIDYpICJUcmFuc2xldCIgaXMgYW4gaW52ZW50ZWQgdGVybSB0aGF0IGRlc2NyaWJlcyB0aGUgY2xhc3MgZmlsZSB0aGF0Ci0gKiAgICAgcmVzdWx0cyBmcm9tIGNvbXBpbGluZyBhbiBYTUwgc3R5bGVzaGVldCBpbnRvIGEgSmF2YSBjbGFzcy4KLSAqCi0gKiAgNykgWFBhdGggaXMgYSBzcGVjaWZpY2F0aW9uIHRoYXQgZGVzY3JpYmVzIGEgbm90YXRpb24gZm9yIGlkZW50aWZ5aW5nCi0gKiAgICAgbm9kZXMgaW4gYSB0cmVlLXN0cnVjdHVyZWQgcmVwcmVzZW50YXRpb24gb2YgYW4gWE1MIGRvY3VtZW50LiAgQW4KLSAqICAgICBpbnN0YW5jZSBvZiB0aGF0IG5vdGF0aW9uIGlzIHJlZmVycmVkIHRvIGFzIGFuIFhQYXRoIGV4cHJlc3Npb24uCi0gKgotICogIDgpIFRoZSBjb250ZXh0IG5vZGUgaXMgdGhlIG5vZGUgaW4gdGhlIGRvY3VtZW50IHdpdGggcmVzcGVjdCB0byB3aGljaCBhbgotICogICAgIFhQYXRoIGV4cHJlc3Npb24gaXMgYmVpbmcgZXZhbHVhdGVkLgotICoKLSAqICA5KSBBbiBpdGVyYXRvciBpcyBhbiBvYmplY3QgdGhhdCB0cmF2ZXJzZXMgbm9kZXMgaW4gdGhlIHRyZWUsIG9uZSBhdCBhIHRpbWUuCi0gKgotICogIDEwKSBOQ05hbWUgaXMgYW4gWE1MIHRlcm0gdXNlZCB0byBkZXNjcmliZSBhIG5hbWUgdGhhdCBkb2VzIG5vdCBjb250YWluIGEKLSAqICAgICBjb2xvbiAoYSAibm8tY29sb24gbmFtZSIpLgotICoKLSAqICAxMSkgUU5hbWUgaXMgYW4gWE1MIHRlcm0gbWVhbmluZyAicXVhbGlmaWVkIG5hbWUiLgotICovCi0KLSAgLyoKLSAgICogc3RhdGljIHZhcmlhYmxlcwotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJST1IwMDAwID0gIkVSUk9SMDAwMCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NVUlJFTlRfTk9UX0FMTE9XRURfSU5fTUFUQ0ggPQotICAgICAgICAgIkVSX0NVUlJFTlRfTk9UX0FMTE9XRURfSU5fTUFUQ0giOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DVVJSRU5UX1RBS0VTX05PX0FSR1MgPQotICAgICAgICAgIkVSX0NVUlJFTlRfVEFLRVNfTk9fQVJHUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0RPQ1VNRU5UX1JFUExBQ0VEID0gIkVSX0RPQ1VNRU5UX1JFUExBQ0VEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09OVEVYVF9IQVNfTk9fT1dORVJET0MgPQotICAgICAgICAgIkVSX0NPTlRFWFRfSEFTX05PX09XTkVSRE9DIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTE9DQUxOQU1FX0hBU19UT09fTUFOWV9BUkdTID0KLSAgICAgICAgICJFUl9MT0NBTE5BTUVfSEFTX1RPT19NQU5ZX0FSR1MiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OQU1FU1BBQ0VVUklfSEFTX1RPT19NQU5ZX0FSR1MgPQotICAgICAgICAgIkVSX05BTUVTUEFDRVVSSV9IQVNfVE9PX01BTllfQVJHUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PUk1BTElaRVNQQUNFX0hBU19UT09fTUFOWV9BUkdTID0KLSAgICAgICAgICJFUl9OT1JNQUxJWkVTUEFDRV9IQVNfVE9PX01BTllfQVJHUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05VTUJFUl9IQVNfVE9PX01BTllfQVJHUyA9Ci0gICAgICAgICAiRVJfTlVNQkVSX0hBU19UT09fTUFOWV9BUkdTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTkFNRV9IQVNfVE9PX01BTllfQVJHUyA9Ci0gICAgICAgICAiRVJfTkFNRV9IQVNfVE9PX01BTllfQVJHUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NUUklOR19IQVNfVE9PX01BTllfQVJHUyA9Ci0gICAgICAgICAiRVJfU1RSSU5HX0hBU19UT09fTUFOWV9BUkdTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU1RSSU5HTEVOR1RIX0hBU19UT09fTUFOWV9BUkdTID0KLSAgICAgICAgICJFUl9TVFJJTkdMRU5HVEhfSEFTX1RPT19NQU5ZX0FSR1MiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9UUkFOU0xBVEVfVEFLRVNfM19BUkdTID0KLSAgICAgICAgICJFUl9UUkFOU0xBVEVfVEFLRVNfM19BUkdTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5QQVJTRURFTlRJVFlVUklfVEFLRVNfMV9BUkcgPQotICAgICAgICAgIkVSX1VOUEFSU0VERU5USVRZVVJJX1RBS0VTXzFfQVJHIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTkFNRVNQQUNFQVhJU19OT1RfSU1QTEVNRU5URUQgPQotICAgICAgICAgIkVSX05BTUVTUEFDRUFYSVNfTk9UX0lNUExFTUVOVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5LTk9XTl9BWElTID0gIkVSX1VOS05PV05fQVhJUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1VOS05PV05fTUFUQ0hfT1BFUkFUSU9OID0KLSAgICAgICAgICJFUl9VTktOT1dOX01BVENIX09QRVJBVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOQ09SUkVDVF9BUkdfTEVOR1RIID0iRVJfSU5DT1JSRUNUX0FSR19MRU5HVEgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX0NPTlZFUlRfVE9fTlVNQkVSID0KLSAgICAgICAgICJFUl9DQU5UX0NPTlZFUlRfVE9fTlVNQkVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9DT05WRVJUX1hQQVRIUkVTVUxUVFlQRV9UT19OVU1CRVIgPQotICAgICAgICAgICAiRVJfQ0FOVF9DT05WRVJUX1hQQVRIUkVTVUxUVFlQRV9UT19OVU1CRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX0NPTlZFUlRfVE9fTk9ERUxJU1QgPQotICAgICAgICAgIkVSX0NBTlRfQ09OVkVSVF9UT19OT0RFTElTVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfQ09OVkVSVF9UT19NVVRBQkxFTk9ERUxJU1QgPQotICAgICAgICAgIkVSX0NBTlRfQ09OVkVSVF9UT19NVVRBQkxFTk9ERUxJU1QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX0NPTlZFUlRfVE9fVFlQRSA9IkVSX0NBTlRfQ09OVkVSVF9UT19UWVBFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhQRUNURURfTUFUQ0hfUEFUVEVSTiA9Ci0gICAgICAgICAiRVJfRVhQRUNURURfTUFUQ0hfUEFUVEVSTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxETk9UX0dFVF9WQVJfTkFNRUQgPQotICAgICAgICAgIkVSX0NPVUxETk9UX0dFVF9WQVJfTkFNRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTktOT1dOX09QQ09ERSA9ICJFUl9VTktOT1dOX09QQ09ERSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYVFJBX0lMTEVHQUxfVE9LRU5TID0iRVJfRVhUUkFfSUxMRUdBTF9UT0tFTlMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FWFBFQ1RFRF9ET1VCTEVfUVVPVEUgPQotICAgICAgICAgIkVSX0VYUEVDVEVEX0RPVUJMRV9RVU9URSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYUEVDVEVEX1NJTkdMRV9RVU9URSA9Ci0gICAgICAgICAiRVJfRVhQRUNURURfU0lOR0xFX1FVT1RFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRU1QVFlfRVhQUkVTU0lPTiA9ICJFUl9FTVBUWV9FWFBSRVNTSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhQRUNURURfQlVUX0ZPVU5EID0gIkVSX0VYUEVDVEVEX0JVVF9GT1VORCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOQ09SUkVDVF9QUk9HUkFNTUVSX0FTU0VSVElPTiA9Ci0gICAgICAgICAiRVJfSU5DT1JSRUNUX1BST0dSQU1NRVJfQVNTRVJUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQk9PTEVBTl9BUkdfTk9fTE9OR0VSX09QVElPTkFMID0KLSAgICAgICAgICJFUl9CT09MRUFOX0FSR19OT19MT05HRVJfT1BUSU9OQUwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GT1VORF9DT01NQV9CVVRfTk9fUFJFQ0VESU5HX0FSRyA9Ci0gICAgICAgICAiRVJfRk9VTkRfQ09NTUFfQlVUX05PX1BSRUNFRElOR19BUkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GT1VORF9DT01NQV9CVVRfTk9fRk9MTE9XSU5HX0FSRyA9Ci0gICAgICAgICAiRVJfRk9VTkRfQ09NTUFfQlVUX05PX0ZPTExPV0lOR19BUkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUkVESUNBVEVfSUxMRUdBTF9TWU5UQVggPQotICAgICAgICAgIkVSX1BSRURJQ0FURV9JTExFR0FMX1NZTlRBWCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lMTEVHQUxfQVhJU19OQU1FID0gIkVSX0lMTEVHQUxfQVhJU19OQU1FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5LTk9XTl9OT0RFVFlQRSA9ICJFUl9VTktOT1dOX05PREVUWVBFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUEFUVEVSTl9MSVRFUkFMX05FRURTX0JFX1FVT1RFRCA9Ci0gICAgICAgICAiRVJfUEFUVEVSTl9MSVRFUkFMX05FRURTX0JFX1FVT1RFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxETk9UX0JFX0ZPUk1BVFRFRF9UT19OVU1CRVIgPQotICAgICAgICAgIkVSX0NPVUxETk9UX0JFX0ZPUk1BVFRFRF9UT19OVU1CRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRE5PVF9DUkVBVEVfWE1MUFJPQ0VTU09STElBSVNPTiA9Ci0gICAgICAgICAiRVJfQ09VTEROT1RfQ1JFQVRFX1hNTFBST0NFU1NPUkxJQUlTT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9ESUROT1RfRklORF9YUEFUSF9TRUxFQ1RfRVhQID0KLSAgICAgICAgICJFUl9ESUROT1RfRklORF9YUEFUSF9TRUxFQ1RfRVhQIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTEROT1RfRklORF9FTkRPUF9BRlRFUl9PUExPQ0FUSU9OUEFUSCA9Ci0gICAgICAgICAiRVJfQ09VTEROT1RfRklORF9FTkRPUF9BRlRFUl9PUExPQ0FUSU9OUEFUSCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VSUk9SX09DQ1VSRUQgPSAiRVJfRVJST1JfT0NDVVJFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lMTEVHQUxfVkFSSUFCTEVfUkVGRVJFTkNFID0KLSAgICAgICAgICJFUl9JTExFR0FMX1ZBUklBQkxFX1JFRkVSRU5DRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FYRVNfTk9UX0FMTE9XRUQgPSAiRVJfQVhFU19OT1RfQUxMT1dFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0tFWV9IQVNfVE9PX01BTllfQVJHUyA9Ci0gICAgICAgICAiRVJfS0VZX0hBU19UT09fTUFOWV9BUkdTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTlRfVEFLRVNfMV9BUkcgPSAiRVJfQ09VTlRfVEFLRVNfMV9BUkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRE5PVF9GSU5EX0ZVTkNUSU9OID0KLSAgICAgICAgICJFUl9DT1VMRE5PVF9GSU5EX0ZVTkNUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5TVVBQT1JURURfRU5DT0RJTkcgPSJFUl9VTlNVUFBPUlRFRF9FTkNPRElORyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BST0JMRU1fSU5fRFRNX05FWFRTSUJMSU5HID0KLSAgICAgICAgICJFUl9QUk9CTEVNX0lOX0RUTV9ORVhUU0lCTElORyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9XUklURV9UT19FTVBUWU5PREVMSVNUSU1QTCA9Ci0gICAgICAgICAiRVJfQ0FOTk9UX1dSSVRFX1RPX0VNUFRZTk9ERUxJU1RJTVBMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU0VURE9NRkFDVE9SWV9OT1RfU1VQUE9SVEVEID0KLSAgICAgICAgICJFUl9TRVRET01GQUNUT1JZX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUkVGSVhfTVVTVF9SRVNPTFZFID0gIkVSX1BSRUZJWF9NVVNUX1JFU09MVkUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QQVJTRV9OT1RfU1VQUE9SVEVEID0gIkVSX1BBUlNFX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TQVhfQVBJX05PVF9IQU5ETEVEID0gIkVSX1NBWF9BUElfTk9UX0hBTkRMRUQiOwotcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSUdOT1JBQkxFX1dISVRFU1BBQ0VfTk9UX0hBTkRMRUQgPQotICAgICAgICAgIkVSX0lHTk9SQUJMRV9XSElURVNQQUNFX05PVF9IQU5ETEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRFRNX0NBTk5PVF9IQU5ETEVfTk9ERVMgPQotICAgICAgICAgIkVSX0RUTV9DQU5OT1RfSEFORExFX05PREVTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWEVSQ0VTX0NBTk5PVF9IQU5ETEVfTk9ERVMgPQotICAgICAgICAgIkVSX1hFUkNFU19DQU5OT1RfSEFORExFX05PREVTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWEVSQ0VTX1BBUlNFX0VSUk9SX0RFVEFJTFMgPQotICAgICAgICAgIkVSX1hFUkNFU19QQVJTRV9FUlJPUl9ERVRBSUxTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWEVSQ0VTX1BBUlNFX0VSUk9SID0gIkVSX1hFUkNFU19QQVJTRV9FUlJPUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfVVRGMTZfU1VSUk9HQVRFID0KLSAgICAgICAgICJFUl9JTlZBTElEX1VURjE2X1NVUlJPR0FURSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX09JRVJST1IgPSAiRVJfT0lFUlJPUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9DUkVBVEVfVVJMID0gIkVSX0NBTk5PVF9DUkVBVEVfVVJMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWFBBVEhfUkVBRE9CSkVDVCA9ICJFUl9YUEFUSF9SRUFET0JKRUNUIjsKLSBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GVU5DVElPTl9UT0tFTl9OT1RfRk9VTkQgPQotICAgICAgICAgIkVSX0ZVTkNUSU9OX1RPS0VOX05PVF9GT1VORCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9ERUFMX1hQQVRIX1RZUEUgPQotICAgICAgICAgIkVSX0NBTk5PVF9ERUFMX1hQQVRIX1RZUEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT0RFU0VUX05PVF9NVVRBQkxFID0gIkVSX05PREVTRVRfTk9UX01VVEFCTEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT0RFU0VURFRNX05PVF9NVVRBQkxFID0KLSAgICAgICAgICJFUl9OT0RFU0VURFRNX05PVF9NVVRBQkxFIjsKLSAgIC8qKiAgVmFyaWFibGUgbm90IHJlc29sdmFibGU6ICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVkFSX05PVF9SRVNPTFZBQkxFID0gIkVSX1ZBUl9OT1RfUkVTT0xWQUJMRSI7Ci0gICAvKiogTnVsbCBlcnJvciBoYW5kbGVyICAqLwotIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05VTExfRVJST1JfSEFORExFUiA9ICJFUl9OVUxMX0VSUk9SX0hBTkRMRVIiOwotICAgLyoqICBQcm9ncmFtbWVyJ3MgYXNzZXJ0aW9uOiB1bmtub3duIG9wY29kZSAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJPR19BU1NFUlRfVU5LTk9XTl9PUENPREUgPQotICAgICAgICAgIkVSX1BST0dfQVNTRVJUX1VOS05PV05fT1BDT0RFIjsKLSAgIC8qKiAgMCBvciAxICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWkVST19PUl9PTkUgPSAiRVJfWkVST19PUl9PTkUiOwotICAgLyoqICBydGYoKSBub3Qgc3VwcG9ydGVkIGJ5IFhSVHJlZUZyYWdTZWxlY3RXcmFwcGVyICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUlRGX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIgPQotICAgICAgICAgIkVSX1JURl9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSIjsKLSAgIC8qKiAgYXNOb2RlSXRlcmF0b3IoKSBub3Qgc3VwcG9ydGVkIGJ5IFhSVHJlZUZyYWdTZWxlY3RXcmFwcGVyICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQVNOT0RFSVRFUkFUT1JfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiA9ICJFUl9BU05PREVJVEVSQVRPUl9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSIjsKLSAgIC8qKiAgZnNiKCkgbm90IHN1cHBvcnRlZCBmb3IgWFN0cmluZ0ZvckNoYXJzICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRlNCX05PVF9TVVBQT1JURURfWFNUUklOR0ZPUkNIQVJTID0KLSAgICAgICAgICJFUl9GU0JfTk9UX1NVUFBPUlRFRF9YU1RSSU5HRk9SQ0hBUlMiOwotICAgLyoqICBDb3VsZCBub3QgZmluZCB2YXJpYWJsZSB3aXRoIHRoZSBuYW1lIG9mICAgKi8KLSBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRF9OT1RfRklORF9WQVIgPSAiRVJfQ09VTERfTk9UX0ZJTkRfVkFSIjsKLSAgIC8qKiAgWFN0cmluZ0ZvckNoYXJzIGNhbiBub3QgdGFrZSBhIHN0cmluZyBmb3IgYW4gYXJndW1lbnQgICAqLwotIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hTVFJJTkdGT1JDSEFSU19DQU5OT1RfVEFLRV9TVFJJTkcgPQotICAgICAgICAgIkVSX1hTVFJJTkdGT1JDSEFSU19DQU5OT1RfVEFLRV9TVFJJTkciOwotICAgLyoqICBUaGUgRmFzdFN0cmluZ0J1ZmZlciBhcmd1bWVudCBjYW4gbm90IGJlIG51bGwgICAqLwotIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZBU1RTVFJJTkdCVUZGRVJfQ0FOTk9UX0JFX05VTEwgPQotICAgICAgICAgIkVSX0ZBU1RTVFJJTkdCVUZGRVJfQ0FOTk9UX0JFX05VTEwiOwotICAgLyoqICAyIG9yIDMgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9UV09fT1JfVEhSRUUgPSAiRVJfVFdPX09SX1RIUkVFIjsKLSAgIC8qKiBWYXJpYWJsZSBhY2Nlc3NlZCBiZWZvcmUgaXQgaXMgYm91bmQhICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1ZBUklBQkxFX0FDQ0VTU0VEX0JFRk9SRV9CSU5EID0KLSAgICAgICAgICJFUl9WQVJJQUJMRV9BQ0NFU1NFRF9CRUZPUkVfQklORCI7Ci0gICAvKiogWFN0cmluZ0ZvckZTQiBjYW4gbm90IHRha2UgYSBzdHJpbmcgZm9yIGFuIGFyZ3VtZW50ISAqLwotIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZTQl9DQU5OT1RfVEFLRV9TVFJJTkcgPQotICAgICAgICAgIkVSX0ZTQl9DQU5OT1RfVEFLRV9TVFJJTkciOwotICAgLyoqIEVycm9yISBTZXR0aW5nIHRoZSByb290IG9mIGEgd2Fsa2VyIHRvIG51bGwhICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NFVFRJTkdfV0FMS0VSX1JPT1RfVE9fTlVMTCA9Ci0gICAgICAgICAiRVJfU0VUVElOR19XQUxLRVJfUk9PVF9UT19OVUxMIjsKLSAgIC8qKiBUaGlzIE5vZGVTZXREVE0gY2FuIG5vdCBpdGVyYXRlIHRvIGEgcHJldmlvdXMgbm9kZSEgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9ERVNFVERUTV9DQU5OT1RfSVRFUkFURSA9Ci0gICAgICAgICAiRVJfTk9ERVNFVERUTV9DQU5OT1RfSVRFUkFURSI7Ci0gIC8qKiBUaGlzIE5vZGVTZXQgY2FuIG5vdCBpdGVyYXRlIHRvIGEgcHJldmlvdXMgbm9kZSEgKi8KLSBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT0RFU0VUX0NBTk5PVF9JVEVSQVRFID0KLSAgICAgICAgICJFUl9OT0RFU0VUX0NBTk5PVF9JVEVSQVRFIjsKLSAgLyoqIFRoaXMgTm9kZVNldERUTSBjYW4gbm90IGRvIGluZGV4aW5nIG9yIGNvdW50aW5nIGZ1bmN0aW9ucyEgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9ERVNFVERUTV9DQU5OT1RfSU5ERVggPQotICAgICAgICAgIkVSX05PREVTRVREVE1fQ0FOTk9UX0lOREVYIjsKLSAgLyoqIFRoaXMgTm9kZVNldCBjYW4gbm90IGRvIGluZGV4aW5nIG9yIGNvdW50aW5nIGZ1bmN0aW9ucyEgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9ERVNFVF9DQU5OT1RfSU5ERVggPQotICAgICAgICAgIkVSX05PREVTRVRfQ0FOTk9UX0lOREVYIjsKLSAgLyoqIENhbiBub3QgY2FsbCBzZXRTaG91bGRDYWNoZU5vZGVzIGFmdGVyIG5leHROb2RlIGhhcyBiZWVuIGNhbGxlZCEgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX0NBTExfU0VUU0hPVUxEQ0FDSEVOT0RFID0KLSAgICAgICAgICJFUl9DQU5OT1RfQ0FMTF9TRVRTSE9VTERDQUNIRU5PREUiOwotICAvKiogezB9IG9ubHkgYWxsb3dzIHsxfSBhcmd1bWVudHMgKi8KLSBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9PTkxZX0FMTE9XUyA9ICJFUl9PTkxZX0FMTE9XUyI7Ci0gIC8qKiBQcm9ncmFtbWVyJ3MgYXNzZXJ0aW9uIGluIGdldE5leHRTdGVwUG9zOiB1bmtub3duIHN0ZXBUeXBlOiB7MH0gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5LTk9XTl9TVEVQID0gIkVSX1VOS05PV05fU1RFUCI7Ci0gIC8qKiBQcm9ibGVtIHdpdGggUmVsYXRpdmVMb2NhdGlvblBhdGggKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhQRUNURURfUkVMX0xPQ19QQVRIID0KLSAgICAgICAgICJFUl9FWFBFQ1RFRF9SRUxfTE9DX1BBVEgiOwotICAvKiogUHJvYmxlbSB3aXRoIExvY2F0aW9uUGF0aCAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FWFBFQ1RFRF9MT0NfUEFUSCA9ICJFUl9FWFBFQ1RFRF9MT0NfUEFUSCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYUEVDVEVEX0xPQ19QQVRIX0FUX0VORF9FWFBSID0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRVJfRVhQRUNURURfTE9DX1BBVEhfQVRfRU5EX0VYUFIiOwotICAvKiogUHJvYmxlbSB3aXRoIFN0ZXAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhQRUNURURfTE9DX1NURVAgPSAiRVJfRVhQRUNURURfTE9DX1NURVAiOwotICAvKiogUHJvYmxlbSB3aXRoIE5vZGVUZXN0ICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYUEVDVEVEX05PREVfVEVTVCA9ICJFUl9FWFBFQ1RFRF9OT0RFX1RFU1QiOwotICAvKiogRXhwZWN0ZWQgc3RlcCBwYXR0ZXJuICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYUEVDVEVEX1NURVBfUEFUVEVSTiA9Ci0gICAgICAgICJFUl9FWFBFQ1RFRF9TVEVQX1BBVFRFUk4iOwotICAvKiogRXhwZWN0ZWQgcmVsYXRpdmUgcGF0aCBwYXR0ZXJuICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYUEVDVEVEX1JFTF9QQVRIX1BBVFRFUk4gPQotICAgICAgICAgIkVSX0VYUEVDVEVEX1JFTF9QQVRIX1BBVFRFUk4iOwotICAvKiogRVJfQ0FOVF9DT05WRVJUX1hQQVRIUkVTVUxUVFlQRV9UT19CT09MRUFOICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfQ09OVkVSVF9UT19CT09MRUFOID0KLSAgICAgICAgICJFUl9DQU5UX0NPTlZFUlRfVE9fQk9PTEVBTiI7Ci0gIC8qKiBGaWVsZCBFUl9DQU5UX0NPTlZFUlRfVE9fU0lOR0xFTk9ERSAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX0NPTlZFUlRfVE9fU0lOR0xFTk9ERSA9Ci0gICAgICAgICAiRVJfQ0FOVF9DT05WRVJUX1RPX1NJTkdMRU5PREUiOwotICAvKiogRmllbGQgRVJfQ0FOVF9HRVRfU05BUFNIT1RfTEVOR1RIICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9HRVRfU05BUFNIT1RfTEVOR1RIID0KLSAgICAgICAgICJFUl9DQU5UX0dFVF9TTkFQU0hPVF9MRU5HVEgiOwotICAvKiogRmllbGQgRVJfTk9OX0lURVJBVE9SX1RZUEUgICAgICAgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9OX0lURVJBVE9SX1RZUEUgPSAiRVJfTk9OX0lURVJBVE9SX1RZUEUiOwotICAvKiogRmllbGQgRVJfRE9DX01VVEFURUQgICAgICAgICAgICAgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRE9DX01VVEFURUQgPSAiRVJfRE9DX01VVEFURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX1hQQVRIX1RZUEUgPSAiRVJfSU5WQUxJRF9YUEFUSF9UWVBFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRU1QVFlfWFBBVEhfUkVTVUxUID0gIkVSX0VNUFRZX1hQQVRIX1JFU1VMVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOQ09NUEFUSUJMRV9UWVBFUyA9ICJFUl9JTkNPTVBBVElCTEVfVFlQRVMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OVUxMX1JFU09MVkVSID0gIkVSX05VTExfUkVTT0xWRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX0NPTlZFUlRfVE9fU1RSSU5HID0KLSAgICAgICAgICJFUl9DQU5UX0NPTlZFUlRfVE9fU1RSSU5HIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9OX1NOQVBTSE9UX1RZUEUgPSAiRVJfTk9OX1NOQVBTSE9UX1RZUEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9XUk9OR19ET0NVTUVOVCA9ICJFUl9XUk9OR19ET0NVTUVOVCI7Ci0gIC8qIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgWFBhdGggZXhwcmVzc2lvbiBjYW5ub3QgYmUgZXZhbHVhdGVkIHdpdGggcmVzcGVjdAotICAgKiB0byB0aGlzIHR5cGUgb2Ygbm9kZS4KLSAgICovCi0gIC8qKiBGaWVsZCBFUl9XUk9OR19OT0RFVFlQRSAgICAgICAgICAgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfV1JPTkdfTk9ERVRZUEUgPSAiRVJfV1JPTkdfTk9ERVRZUEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YUEFUSF9FUlJPUiA9ICJFUl9YUEFUSF9FUlJPUiI7Ci0KLSAgLy9CRUdJTjogS2V5cyBuZWVkZWQgZm9yIGV4Y2VwdGlvbiBtZXNzYWdlcyBvZiAgSkFYUCAxLjMgWFBhdGggQVBJIGltcGxlbWVudGF0aW9uCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYVEVOU0lPTl9GVU5DVElPTl9DQU5OT1RfQkVfSU5WT0tFRCA9ICJFUl9FWFRFTlNJT05fRlVOQ1RJT05fQ0FOTk9UX0JFX0lOVk9LRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SRVNPTFZFX1ZBUklBQkxFX1JFVFVSTlNfTlVMTCA9ICJFUl9SRVNPTFZFX1ZBUklBQkxFX1JFVFVSTlNfTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1VOU1VQUE9SVEVEX1JFVFVSTl9UWVBFID0gIkVSX1VOU1VQUE9SVEVEX1JFVFVSTl9UWVBFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU09VUkNFX1JFVFVSTl9UWVBFX0NBTk5PVF9CRV9OVUxMID0gIkVSX1NPVVJDRV9SRVRVUk5fVFlQRV9DQU5OT1RfQkVfTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FSR19DQU5OT1RfQkVfTlVMTCA9ICJFUl9BUkdfQ0FOTk9UX0JFX05VTEwiOwotCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX09CSkVDVF9NT0RFTF9OVUxMID0gIkVSX09CSkVDVF9NT0RFTF9OVUxMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfT0JKRUNUX01PREVMX0VNUFRZID0gIkVSX09CSkVDVF9NT0RFTF9FTVBUWSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZFQVRVUkVfTkFNRV9OVUxMID0gIkVSX0ZFQVRVUkVfTkFNRV9OVUxMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRkVBVFVSRV9VTktOT1dOID0gIkVSX0ZFQVRVUkVfVU5LTk9XTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0dFVFRJTkdfTlVMTF9GRUFUVVJFID0gIkVSX0dFVFRJTkdfTlVMTF9GRUFUVVJFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfR0VUVElOR19VTktOT1dOX0ZFQVRVUkUgPSAiRVJfR0VUVElOR19VTktOT1dOX0ZFQVRVUkUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TRUNVUkVQUk9DRVNTSU5HX0ZFQVRVUkUgPSAiRVJfU0VDVVJFUFJPQ0VTU0lOR19GRUFUVVJFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTlVMTF9YUEFUSF9GVU5DVElPTl9SRVNPTFZFUiA9ICJFUl9OVUxMX1hQQVRIX0ZVTkNUSU9OX1JFU09MVkVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTlVMTF9YUEFUSF9WQVJJQUJMRV9SRVNPTFZFUiA9ICJFUl9OVUxMX1hQQVRIX1ZBUklBQkxFX1JFU09MVkVSIjsKLSAgLy9FTkQ6IEtleXMgbmVlZGVkIGZvciBleGNlcHRpb24gbWVzc2FnZXMgb2YgIEpBWFAgMS4zIFhQYXRoIEFQSSBpbXBsZW1lbnRhdGlvbgotCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0xPQ0FMRV9OQU1FX05PVF9IQU5ETEVEID0KLSAgICAgICAgICJXR19MT0NBTEVfTkFNRV9OT1RfSEFORExFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX1BST1BFUlRZX05PVF9TVVBQT1JURUQgPQotICAgICAgICAgIldHX1BST1BFUlRZX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19ET05UX0RPX0FOWVRISU5HX1dJVEhfTlMgPQotICAgICAgICAgIldHX0RPTlRfRE9fQU5ZVEhJTkdfV0lUSF9OUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX1NFQ1VSSVRZX0VYQ0VQVElPTiA9ICJXR19TRUNVUklUWV9FWENFUFRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19RVU9fTk9fTE9OR0VSX0RFRklORUQgPQotICAgICAgICAgIldHX1FVT19OT19MT05HRVJfREVGSU5FRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX05FRURfREVSSVZFRF9PQkpFQ1RfVE9fSU1QTEVNRU5UX05PREVURVNUID0KLSAgICAgICAgICJXR19ORUVEX0RFUklWRURfT0JKRUNUX1RPX0lNUExFTUVOVF9OT0RFVEVTVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0ZVTkNUSU9OX1RPS0VOX05PVF9GT1VORCA9Ci0gICAgICAgICAiV0dfRlVOQ1RJT05fVE9LRU5fTk9UX0ZPVU5EIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfQ09VTEROT1RfRklORF9GVU5DVElPTiA9Ci0gICAgICAgICAiV0dfQ09VTEROT1RfRklORF9GVU5DVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0NBTk5PVF9NQUtFX1VSTF9GUk9NID0iV0dfQ0FOTk9UX01BS0VfVVJMX0ZST00iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19FWFBBTkRfRU5USVRJRVNfTk9UX1NVUFBPUlRFRCA9Ci0gICAgICAgICAiV0dfRVhQQU5EX0VOVElUSUVTX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19JTExFR0FMX1ZBUklBQkxFX1JFRkVSRU5DRSA9Ci0gICAgICAgICAiV0dfSUxMRUdBTF9WQVJJQUJMRV9SRUZFUkVOQ0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19VTlNVUFBPUlRFRF9FTkNPRElORyA9IldHX1VOU1VQUE9SVEVEX0VOQ09ESU5HIjsKLQotICAvKiogIGRldGFjaCgpIG5vdCBzdXBwb3J0ZWQgYnkgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9ERVRBQ0hfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiA9Ci0gICAgICAgICAiRVJfREVUQUNIX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIiOwotICAvKiogIG51bSgpIG5vdCBzdXBwb3J0ZWQgYnkgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OVU1fTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiA9Ci0gICAgICAgICAiRVJfTlVNX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIiOwotICAvKiogIHhzdHIoKSBub3Qgc3VwcG9ydGVkIGJ5IFhSVHJlZUZyYWdTZWxlY3RXcmFwcGVyICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWFNUUl9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSID0KLSAgICAgICAgICJFUl9YU1RSX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIiOwotICAvKiogIHN0cigpIG5vdCBzdXBwb3J0ZWQgYnkgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TVFJfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiA9Ci0gICAgICAgICAiRVJfU1RSX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIiOwotCi0gIC8vIEVycm9yIG1lc3NhZ2VzLi4uCi0KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgT2JqZWN0W11bXSBfY29udGVudHMgPSBuZXcgT2JqZWN0W11bXXsKLQotICB7ICJFUlJPUjAwMDAiICwgInswfSIgfSwKLQotICB7IEVSX0NVUlJFTlRfTk9UX0FMTE9XRURfSU5fTUFUQ0gsICJjdXJyZW50KClcdTk1QTJcdTY1NzBcdTMwNkZcdTRFMDBcdTgxRjRcdTMwRDFcdTMwQkZcdTMwRkNcdTMwRjNcdTMwNjdcdTMwNkZcdThBMzFcdTUzRUZcdTMwNTVcdTMwOENcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIiIH0sCi0KLSAgeyBFUl9DVVJSRU5UX1RBS0VTX05PX0FSR1MsICJjdXJyZW50KClcdTk1QTJcdTY1NzBcdTMwNkZcdTVGMTVcdTY1NzBcdTMwOTJcdTUzRDdcdTMwNTFcdTUxNjVcdTMwOENcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIiIH0sCi0KLSAgeyBFUl9ET0NVTUVOVF9SRVBMQUNFRCwKLSAgICAgICJkb2N1bWVudCgpXHU5NUEyXHU2NTcwXHUzMDZFXHU1QjlGXHU4OEM1XHUzMDZGY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHQuRnVuY0RvY3VtZW50XHUzMDZCXHUzMDg4XHUzMDYzXHUzMDY2XHU3RjZFXHU2M0RCXHUzMDU1XHUzMDhDXHUzMDdFXHUzMDU3XHUzMDVGXHUzMDAyIn0sCi0KLSAgeyBFUl9DT05URVhUX0hBU19OT19PV05FUkRPQywKLSAgICAgICJcdTMwQjNcdTMwRjNcdTMwQzZcdTMwQURcdTMwQjlcdTMwQzhcdTMwNkJcdTYyNDBcdTY3MDlcdTgwMDVcdTMwQzlcdTMwQURcdTMwRTVcdTMwRTFcdTMwRjNcdTMwQzhcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIifSwKLQotICB7IEVSX0xPQ0FMTkFNRV9IQVNfVE9PX01BTllfQVJHUywKLSAgICAgICJsb2NhbC1uYW1lKClcdTMwNkVcdTVGMTVcdTY1NzBcdTMwNENcdTU5MUFcdTMwNTlcdTMwNEVcdTMwN0VcdTMwNTlcdTMwMDIifSwKLQotICB7IEVSX05BTUVTUEFDRVVSSV9IQVNfVE9PX01BTllfQVJHUywKLSAgICAgICJuYW1lc3BhY2UtdXJpKClcdTMwNkVcdTVGMTVcdTY1NzBcdTMwNENcdTU5MUFcdTMwNTlcdTMwNEVcdTMwN0VcdTMwNTlcdTMwMDIifSwKLQotICB7IEVSX05PUk1BTElaRVNQQUNFX0hBU19UT09fTUFOWV9BUkdTLAotICAgICAgIm5vcm1hbGl6ZS1zcGFjZSgpXHUzMDZFXHU1RjE1XHU2NTcwXHUzMDRDXHU1OTFBXHUzMDU5XHUzMDRFXHUzMDdFXHUzMDU5XHUzMDAyIn0sCi0KLSAgeyBFUl9OVU1CRVJfSEFTX1RPT19NQU5ZX0FSR1MsCi0gICAgICAibnVtYmVyKClcdTMwNkVcdTVGMTVcdTY1NzBcdTMwNENcdTU5MUFcdTMwNTlcdTMwNEVcdTMwN0VcdTMwNTlcdTMwMDIifSwKLQotICB7IEVSX05BTUVfSEFTX1RPT19NQU5ZX0FSR1MsCi0gICAgICJuYW1lKClcdTMwNkVcdTVGMTVcdTY1NzBcdTMwNENcdTU5MUFcdTMwNTlcdTMwNEVcdTMwN0VcdTMwNTlcdTMwMDIifSwKLQotICB7IEVSX1NUUklOR19IQVNfVE9PX01BTllfQVJHUywKLSAgICAgICJzdHJpbmcoKVx1MzA2RVx1NUYxNVx1NjU3MFx1MzA0Q1x1NTkxQVx1MzA1OVx1MzA0RVx1MzA3RVx1MzA1OVx1MzAwMiJ9LAotCi0gIHsgRVJfU1RSSU5HTEVOR1RIX0hBU19UT09fTUFOWV9BUkdTLAotICAgICAgInN0cmluZy1sZW5ndGgoKVx1MzA2RVx1NUYxNVx1NjU3MFx1MzA0Q1x1NTkxQVx1MzA1OVx1MzA0RVx1MzA3RVx1MzA1OVx1MzAwMiJ9LAotCi0gIHsgRVJfVFJBTlNMQVRFX1RBS0VTXzNfQVJHUywKLSAgICAgICJ0cmFuc2xhdGUoKVx1OTVBMlx1NjU3MFx1MzA2RjNcdTMwNjRcdTMwNkVcdTVGMTVcdTY1NzBcdTMwOTJcdTUzRDZcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIifSwKLQotICB7IEVSX1VOUEFSU0VERU5USVRZVVJJX1RBS0VTXzFfQVJHLAotICAgICAgInVucGFyc2VkLWVudGl0eS11cmlcdTk1QTJcdTY1NzBcdTMwNkZcdTVGMTVcdTY1NzBcdTMwOTIxXHUzMDY0XHU1M0Q2XHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyIn0sCi0KLSAgeyBFUl9OQU1FU1BBQ0VBWElTX05PVF9JTVBMRU1FTlRFRCwKLSAgICAgICJuYW1lc3BhY2VcdThFRjhcdTMwNkZcdTMwN0VcdTMwNjBcdTVCOUZcdTg4QzVcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIifSwKLQotICB7IEVSX1VOS05PV05fQVhJUywKLSAgICAgIlx1NEUwRFx1NjYwRVx1MzA2QVx1OEVGOFx1MzA2N1x1MzA1OTogezB9In0sCi0KLSAgeyBFUl9VTktOT1dOX01BVENIX09QRVJBVElPTiwKLSAgICAgIlx1NEUwRFx1NjYwRVx1MzA2QVx1NEUwMFx1ODFGNFx1NjRDRFx1NEY1Q1x1MzA2N1x1MzA1OVx1MzAwMiJ9LAotCi0gIHsgRVJfSU5DT1JSRUNUX0FSR19MRU5HVEgsCi0gICAgICAicHJvY2Vzc2luZy1pbnN0cnVjdGlvbigpXHUzMENFXHUzMEZDXHUzMEM5XHUzMEZCXHUzMEM2XHUzMEI5XHUzMEM4XHUzMDZFXHU1RjE1XHU2NTcwXHUzMDZFXHU5NTc3XHUzMDU1XHUzMDRDXHU0RTBEXHU2QjYzXHUzMDY3XHUzMDU5XHUzMDAyIn0sCi0KLSAgeyBFUl9DQU5UX0NPTlZFUlRfVE9fTlVNQkVSLAotICAgICAgInswfVx1MzA5Mlx1NjU3MFx1NTAyNFx1MzA2Qlx1NTkwOVx1NjNEQlx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MyJ9LAotCi0gIHsgRVJfQ0FOVF9DT05WRVJUX1RPX05PREVMSVNULAotICAgICAgInswfVx1MzA5Mk5vZGVMaXN0XHUzMDZCXHU1OTA5XHU2M0RCXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyIn0sCi0KLSAgeyBFUl9DQU5UX0NPTlZFUlRfVE9fTVVUQUJMRU5PREVMSVNULAotICAgICAgInswfVx1MzA5Mk5vZGVTZXREVE1cdTMwNkJcdTU5MDlcdTYzREJcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIifSwKLQotICB7IEVSX0NBTlRfQ09OVkVSVF9UT19UWVBFLAotICAgICAgInswfVx1MzA5MnR5cGUjezF9XHUzMDZCXHU1OTA5XHU2M0RCXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzIn0sCi0KLSAgeyBFUl9FWFBFQ1RFRF9NQVRDSF9QQVRURVJOLAotICAgICAgImdldE1hdGNoU2NvcmVcdTMwNkJcdTRFMDBcdTgxRjRcdTMwRDFcdTMwQkZcdTMwRkNcdTMwRjNcdTMwNENcdTVGQzVcdTg5ODFcdTMwNjdcdTMwNTlcdTMwMDIifSwKLQotICB7IEVSX0NPVUxETk9UX0dFVF9WQVJfTkFNRUQsCi0gICAgICAiXHU1NDBEXHU1MjREezB9XHUzMDZFXHU1OTA5XHU2NTcwXHUzMDkyXHU1M0Q2XHU1Rjk3XHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDY3XHUzMDU3XHUzMDVGIn0sCi0KLSAgeyBFUl9VTktOT1dOX09QQ09ERSwKLSAgICAgIlx1MzBBOFx1MzBFOVx1MzBGQ1x1MzAwMlx1NEUwRFx1NjYwRVx1MzA2QVx1NjRDRFx1NEY1Q1x1MzBCM1x1MzBGQ1x1MzBDOTogezB9In0sCi0KLSAgeyBFUl9FWFRSQV9JTExFR0FMX1RPS0VOUywKLSAgICAgIlx1NEY1OVx1NTIwNlx1MzA2RVx1NEUwRFx1NkI2M1x1MzA2QVx1MzBDOFx1MzBGQ1x1MzBBRlx1MzBGMzogezB9In0sCi0KLSAgeyBFUl9FWFBFQ1RFRF9ET1VCTEVfUVVPVEUsCi0gICAgICAiXHUzMEVBXHUzMEM2XHUzMEU5XHUzMEVCXHUzMDZFXHU1RjE1XHU3NTI4XHU3QjI2XHUzMDRDXHU0RTBEXHU2QjYzXHUzMDY3XHUzMDU5Li4uIFx1NEU4Q1x1OTFDRFx1NUYxNVx1NzUyOFx1N0IyNlx1MzA0Q1x1NUZDNVx1ODk4MVx1MzA2N1x1MzA1OVx1MzAwMiJ9LAotCi0gIHsgRVJfRVhQRUNURURfU0lOR0xFX1FVT1RFLAotICAgICAgIlx1MzBFQVx1MzBDNlx1MzBFOVx1MzBFQlx1MzA2RVx1NUYxNVx1NzUyOFx1N0IyNlx1MzA0Q1x1NEUwRFx1NkI2M1x1MzA2N1x1MzA1OS4uLiBcdTRFMDBcdTkxQ0RcdTVGMTVcdTc1MjhcdTdCMjZcdTMwNENcdTVGQzVcdTg5ODFcdTMwNjdcdTMwNTlcdTMwMDIifSwKLQotICB7IEVSX0VNUFRZX0VYUFJFU1NJT04sCi0gICAgICJcdTVGMEZcdTMwNENcdTdBN0FcdTMwNjdcdTMwNTlcdTMwMDIifSwKLQotICB7IEVSX0VYUEVDVEVEX0JVVF9GT1VORCwKLSAgICAgInswfVx1MzA2N1x1MzA2Rlx1MzA2QVx1MzA0RnsxfVx1MzA0Q1x1NjkxQ1x1NTFGQVx1MzA1NVx1MzA4Q1x1MzA3RVx1MzA1N1x1MzA1RiJ9LAotCi0gIHsgRVJfSU5DT1JSRUNUX1BST0dSQU1NRVJfQVNTRVJUSU9OLAotICAgICAgIlx1MzBEN1x1MzBFRFx1MzBCMFx1MzBFOVx1MzBERVx1MzBGQlx1MzBBMlx1MzBCNVx1MzBGQ1x1MzBCN1x1MzBFN1x1MzBGM1x1MzA0Q1x1NEUwRFx1NkI2M1x1MzA2N1x1MzA1OVx1MzAwMi0gezB9In0sCi0KLSAgeyBFUl9CT09MRUFOX0FSR19OT19MT05HRVJfT1BUSU9OQUwsCi0gICAgICAiYm9vbGVhbiguLi4pXHU1RjE1XHU2NTcwXHUzMDZGXHUzMDAxMTk5OTA3MDkgWFBhdGhcdTMwQzlcdTMwRTlcdTMwRDVcdTMwQzhcdTMwNkJcdTMwODhcdTMwNjNcdTMwNjZcdTMwQUFcdTMwRDdcdTMwQjdcdTMwRTdcdTMwRjNcdTMwNjdcdTMwNkFcdTMwNEZcdTMwNkFcdTMwOEFcdTMwN0VcdTMwNTdcdTMwNUZcdTMwMDIifSwKLQotICB7IEVSX0ZPVU5EX0NPTU1BX0JVVF9OT19QUkVDRURJTkdfQVJHLAotICAgICAgIicsJ1x1MzA0Q1x1ODk4Qlx1MzA2NFx1MzA0Qlx1MzA4QVx1MzA3RVx1MzA1N1x1MzA1Rlx1MzA0Q1x1NTI0RFx1MzA2Qlx1NUYxNVx1NjU3MFx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMiJ9LAotCi0gIHsgRVJfRk9VTkRfQ09NTUFfQlVUX05PX0ZPTExPV0lOR19BUkcsCi0gICAgICAiJywnXHUzMDRDXHU4OThCXHUzMDY0XHUzMDRCXHUzMDhBXHUzMDdFXHUzMDU3XHUzMDVGXHUzMDRDXHU1RjhDXHUzMDhEXHUzMDZCXHU1RjE1XHU2NTcwXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyIn0sCi0KLSAgeyBFUl9QUkVESUNBVEVfSUxMRUdBTF9TWU5UQVgsCi0gICAgICAiJy4uW3ByZWRpY2F0ZV0nXHUzMDdFXHUzMDVGXHUzMDZGJy5bcHJlZGljYXRlXSdcdTMwNkZcdTRFMERcdTZCNjNcdTMwNkFcdTY5Q0JcdTY1ODdcdTMwNjdcdTMwNTlcdTMwMDJcdTMwNEJcdTMwOEZcdTMwOEFcdTMwNkInc2VsZjo6bm9kZSgpW3ByZWRpY2F0ZV0nXHUzMDkyXHU0RjdGXHU3NTI4XHUzMDU3XHUzMDY2XHUzMDRGXHUzMDYwXHUzMDU1XHUzMDQ0XHUzMDAyIn0sCi0KLSAgeyBFUl9JTExFR0FMX0FYSVNfTkFNRSwKLSAgICAgIlx1NEUwRFx1NkI2M1x1MzA2QVx1OEVGOFx1NTQwRDogezB9In0sCi0KLSAgeyBFUl9VTktOT1dOX05PREVUWVBFLAotICAgICAiXHU0RTBEXHU2NjBFXHUzMDZBbm9kZXR5cGU6IHswfSJ9LAotCi0gIHsgRVJfUEFUVEVSTl9MSVRFUkFMX05FRURTX0JFX1FVT1RFRCwKLSAgICAgICJcdTMwRDFcdTMwQkZcdTMwRkNcdTMwRjNcdTMwRkJcdTMwRUFcdTMwQzZcdTMwRTlcdTMwRUIoezB9KVx1MzA2Qlx1NUYxNVx1NzUyOFx1N0IyNlx1MzA5Mlx1NEVEOFx1MzA1MVx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMiJ9LAotCi0gIHsgRVJfQ09VTEROT1RfQkVfRk9STUFUVEVEX1RPX05VTUJFUiwKLSAgICAgICJ7MH1cdTMwOTJcdTY1NzBcdTUwMjRcdTMwNkJcdTMwRDVcdTMwQTlcdTMwRkNcdTMwREVcdTMwQzNcdTMwQzhcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwNjdcdTMwNTdcdTMwNUZcdTMwMDIifSwKLQotICB7IEVSX0NPVUxETk9UX0NSRUFURV9YTUxQUk9DRVNTT1JMSUFJU09OLAotICAgICAgIlhNTCBUcmFuc2Zvcm1lckZhY3RvcnkgTGlhaXNvblx1MzA5Mlx1NEY1Q1x1NjIxMFx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzA2N1x1MzA1N1x1MzA1RjogezB9In0sCi0KLSAgeyBFUl9ESUROT1RfRklORF9YUEFUSF9TRUxFQ1RfRVhQLAotICAgICAgIlx1MzBBOFx1MzBFOVx1MzBGQ1x1MzAwMnhwYXRoXHU5MDc4XHU2MjlFXHU1RjBGKC1zZWxlY3QpXHUzMDRDXHU4OThCXHUzMDY0XHUzMDRCXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDY3XHUzMDU3XHUzMDVGXHUzMDAyIn0sCi0KLSAgeyBFUl9DT1VMRE5PVF9GSU5EX0VORE9QX0FGVEVSX09QTE9DQVRJT05QQVRILAotICAgICAgIlx1MzBBOFx1MzBFOVx1MzBGQ1x1MzAwMk9QX0xPQ0FUSU9OUEFUSFx1MzA2RVx1NUY4Q1x1MzA2QkVORE9QXHUzMDRDXHU4OThCXHUzMDY0XHUzMDRCXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDY3XHUzMDU3XHUzMDVGIn0sCi0KLSAgeyBFUl9FUlJPUl9PQ0NVUkVELAotICAgICAiXHUzMEE4XHUzMEU5XHUzMEZDXHUzMDRDXHU3NjdBXHU3NTFGXHUzMDU3XHUzMDdFXHUzMDU3XHUzMDVGXHUzMDAyIn0sCi0KLSAgeyBFUl9JTExFR0FMX1ZBUklBQkxFX1JFRkVSRU5DRSwKLSAgICAgICJcdTU5MDlcdTY1NzBcdTMwNkJcdTYzMDdcdTVCOUFcdTMwNTdcdTMwNUZWYXJpYWJsZVJlZmVyZW5jZVx1MzA0Q1x1MzBCM1x1MzBGM1x1MzBDNlx1MzBBRFx1MzBCOVx1MzBDOFx1N0JDNFx1NTZGMlx1NTkxNlx1MzA0Qlx1NUI5QVx1N0ZBOVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMlx1NTQwRFx1NTI0RD0gezB9In0sCi0KLSAgeyBFUl9BWEVTX05PVF9BTExPV0VELAotICAgICAgIlx1NEUwMFx1ODFGNFx1MzBEMVx1MzBCRlx1MzBGQ1x1MzBGM1x1MzA2N1x1MzA2Rlx1MzAwMWNoaWxkOjpcdThFRjhcdTMwNjhhdHRyaWJ1dGU6Olx1OEVGOFx1MzA2RVx1MzA3Rlx1MzA0Q1x1OEEzMVx1NTNFRlx1MzA1NVx1MzA4Q1x1MzA3RVx1MzA1OVx1MzAwMlx1NTU0Rlx1OTg0Q1x1MzA2OFx1MzA2QVx1MzA4Qlx1OEVGOD0gezB9In0sCi0KLSAgeyBFUl9LRVlfSEFTX1RPT19NQU5ZX0FSR1MsCi0gICAgICAia2V5KClcdTMwNENcdTYzMDFcdTMwNjRcdTVGMTVcdTY1NzBcdTMwNkVcdTY1NzBcdTMwNENcdTRFMERcdTZCNjNcdTMwNjdcdTMwNTlcdTMwMDIifSwKLQotICB7IEVSX0NPVU5UX1RBS0VTXzFfQVJHLAotICAgICAgIlx1MzBBQlx1MzBBNlx1MzBGM1x1MzBDOFx1OTVBMlx1NjU3MFx1MzA2Rlx1NUYxNVx1NjU3MFx1MzA5MjFcdTMwNjRcdTUzRDZcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIifSwKLQotICB7IEVSX0NPVUxETk9UX0ZJTkRfRlVOQ1RJT04sCi0gICAgICJcdTk1QTJcdTY1NzB7MH1cdTMwNENcdTg5OEJcdTMwNjRcdTMwNEJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwNjdcdTMwNTdcdTMwNUYifSwKLQotICB7IEVSX1VOU1VQUE9SVEVEX0VOQ09ESU5HLAotICAgICAiXHUzMEI1XHUzMEREXHUzMEZDXHUzMEM4XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDZBXHUzMDQ0XHUzMEE4XHUzMEYzXHUzMEIzXHUzMEZDXHUzMEM3XHUzMEEzXHUzMEYzXHUzMEIwXHUzMDY3XHUzMDU5OiB7MH0ifSwKLQotICB7IEVSX1BST0JMRU1fSU5fRFRNX05FWFRTSUJMSU5HLAotICAgICAgImdldE5leHRTaWJsaW5nXHUzMDZFRFRNXHUzMDY3XHU1NTRGXHU5ODRDXHUzMDRDXHU3NjdBXHU3NTFGXHUzMDU3XHUzMDdFXHUzMDU3XHUzMDVGLi4uXHU1RkE5XHU1MTQzXHUzMDZFXHU4QTY2XHU4ODRDXHU0RTJEXHUzMDY3XHUzMDU5In0sCi0KLSAgeyBFUl9DQU5OT1RfV1JJVEVfVE9fRU1QVFlOT0RFTElTVElNUEwsCi0gICAgICAiXHUzMEQ3XHUzMEVEXHUzMEIwXHUzMEU5XHUzMERFXHUzMEZCXHUzMEE4XHUzMEU5XHUzMEZDOiBFbXB0eU5vZGVMaXN0XHUzMDZCXHU2NkY4XHUzMDREXHU4RkJDXHUzMDgxXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyIn0sCi0KLSAgeyBFUl9TRVRET01GQUNUT1JZX05PVF9TVVBQT1JURUQsCi0gICAgICAic2V0RE9NRmFjdG9yeVx1MzA2RlhQYXRoQ29udGV4dFx1MzA2N1x1MzBCNVx1MzBERFx1MzBGQ1x1MzBDOFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMiJ9LAotCi0gIHsgRVJfUFJFRklYX01VU1RfUkVTT0xWRSwKLSAgICAgICJcdTYzQTVcdTk4MkRcdThGOUVcdTMwNkZcdTMwQ0RcdTMwRkNcdTMwRTBcdTMwQjlcdTMwREFcdTMwRkNcdTMwQjlcdTMwNkJcdTg5RTNcdTZDN0FcdTMwNTVcdTMwOENcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTk6IHswfSJ9LAotCi0gIHsgRVJfUEFSU0VfTk9UX1NVUFBPUlRFRCwKLSAgICAgICJcdTg5RTNcdTY3OTAoSW5wdXRTb3VyY2VcdTMwQkRcdTMwRkNcdTMwQjkpXHUzMDZGWFBhdGhDb250ZXh0XHUzMDY3XHUzMEI1XHUzMEREXHUzMEZDXHUzMEM4XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyezB9XHUzMDkyXHU5NThCXHUzMDUxXHUzMDdFXHUzMDVCXHUzMDkzIn0sCi0KLSAgeyBFUl9TQVhfQVBJX05PVF9IQU5ETEVELAotICAgICAgIlNBWCBBUEkgY2hhcmFjdGVycyhjaGFyIGNoW10uLi5cdTMwNkZEVE1cdTMwNkJcdTMwODhcdTMwNjNcdTMwNjZcdTUxRTZcdTc0MDZcdTMwNTVcdTMwOENcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIifSwKLQotICB7IEVSX0lHTk9SQUJMRV9XSElURVNQQUNFX05PVF9IQU5ETEVELAotICAgICAgImlnbm9yYWJsZVdoaXRlc3BhY2UoY2hhciBjaFtdLi4uXHUzMDZGRFRNXHUzMDZCXHUzMDg4XHUzMDYzXHUzMDY2XHU1MUU2XHU3NDA2XHUzMDU1XHUzMDhDXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyIn0sCi0KLSAgeyBFUl9EVE1fQ0FOTk9UX0hBTkRMRV9OT0RFUywKLSAgICAgICJEVE1MaWFpc29uXHUzMDZGXHUzMEJGXHUzMEE0XHUzMEQ3ezB9XHUzMDZFXHUzMENFXHUzMEZDXHUzMEM5XHUzMDkyXHU1MUU2XHU3NDA2XHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzIn0sCi0KLSAgeyBFUl9YRVJDRVNfQ0FOTk9UX0hBTkRMRV9OT0RFUywKLSAgICAgICJET00ySGVscGVyXHUzMDZGezB9XHUzMEJGXHUzMEE0XHUzMEQ3XHUzMDZFXHUzMENFXHUzMEZDXHUzMEM5XHUzMDkyXHU1MUU2XHU3NDA2XHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzIn0sCi0KLSAgeyBFUl9YRVJDRVNfUEFSU0VfRVJST1JfREVUQUlMUywKLSAgICAgICJET00ySGVscGVyLnBhcnNlXHUzMEE4XHUzMEU5XHUzMEZDOiBTeXN0ZW1JRCAtIHswfSBcdTg4NEMgLSB7MX0ifSwKLQotICB7IEVSX1hFUkNFU19QQVJTRV9FUlJPUiwKLSAgICAgIkRPTTJIZWxwZXIucGFyc2VcdTMwQThcdTMwRTlcdTMwRkMifSwKLQotICB7IEVSX0lOVkFMSURfVVRGMTZfU1VSUk9HQVRFLAotICAgICAgIlx1NzEyMVx1NTJCOVx1MzA2QVVURi0xNlx1MzBCNVx1MzBFRFx1MzBCMlx1MzBGQ1x1MzBDOFx1MzA0Q1x1NjkxQ1x1NTFGQVx1MzA1NVx1MzA4Q1x1MzA3RVx1MzA1N1x1MzA1RjogezB9XHUzMDAyIn0sCi0KLSAgeyBFUl9PSUVSUk9SLAotICAgICAiSU9cdTMwQThcdTMwRTlcdTMwRkMifSwKLQotICB7IEVSX0NBTk5PVF9DUkVBVEVfVVJMLAotICAgICAiezB9XHUzMDZFVVJMXHUzMDkyXHU0RjVDXHU2MjEwXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzIn0sCi0KLSAgeyBFUl9YUEFUSF9SRUFET0JKRUNULAotICAgICAiWFBhdGgucmVhZE9iamVjdFx1NTE4NTogezB9In0sCi0KLSAgeyBFUl9GVU5DVElPTl9UT0tFTl9OT1RfRk9VTkQsCi0gICAgICAiXHU5NUEyXHU2NTcwXHUzMEM4XHUzMEZDXHUzMEFGXHUzMEYzXHUzMDRDXHU4OThCXHUzMDY0XHUzMDRCXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyIn0sCi0KLSAgeyBFUl9DQU5OT1RfREVBTF9YUEFUSF9UWVBFLAotICAgICAgICJYUGF0aFx1MzBCRlx1MzBBNFx1MzBEN1x1MzA5Mlx1NTFFNlx1NzQwNlx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MzogezB9In0sCi0KLSAgeyBFUl9OT0RFU0VUX05PVF9NVVRBQkxFLAotICAgICAgICJcdTMwNTNcdTMwNkVOb2RlU2V0XHUzMDZGXHU1M0VGXHU1OTA5XHUzMDY3XHUzMDZGXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzIn0sCi0KLSAgeyBFUl9OT0RFU0VURFRNX05PVF9NVVRBQkxFLAotICAgICAgICJcdTMwNTNcdTMwNkVOb2RlU2V0RFRNXHUzMDZGXHU1M0VGXHU1OTA5XHUzMDY3XHUzMDZGXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzIn0sCi0KLSAgeyBFUl9WQVJfTk9UX1JFU09MVkFCTEUsCi0gICAgICAgICJcdTU5MDlcdTY1NzBcdTMwOTJcdTg5RTNcdTZDN0FcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTM6IHswfSJ9LAotCi0gIHsgRVJfTlVMTF9FUlJPUl9IQU5ETEVSLAotICAgICAgICAiTnVsbFx1MzA2RVx1MzBBOFx1MzBFOVx1MzBGQ1x1MzBGQlx1MzBDRlx1MzBGM1x1MzBDOVx1MzBFOSJ9LAotCi0gIHsgRVJfUFJPR19BU1NFUlRfVU5LTk9XTl9PUENPREUsCi0gICAgICAgIlx1MzBEN1x1MzBFRFx1MzBCMFx1MzBFOVx1MzBERVx1MzA2RVx1MzBBMlx1MzBCNVx1MzBGQ1x1MzBCN1x1MzBFN1x1MzBGMzogXHU0RTBEXHU2NjBFXHUzMDZBb3Bjb2RlOiB7MH0ifSwKLQotICB7IEVSX1pFUk9fT1JfT05FLAotICAgICAgICIwXHUzMDdFXHUzMDVGXHUzMDZGMSJ9LAotCi0gIHsgRVJfUlRGX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIsCi0gICAgICAgInJ0ZigpXHUzMDZGWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXJcdTMwNkJcdTMwODhcdTMwNjNcdTMwNjZcdTMwQjVcdTMwRERcdTMwRkNcdTMwQzhcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTMifSwKLQotICB7IEVSX1JURl9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSLAotICAgICAgICJhc05vZGVJdGVyYXRvcigpXHUzMDZGWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXJcdTMwNkJcdTMwODhcdTMwNjNcdTMwNjZcdTMwQjVcdTMwRERcdTMwRkNcdTMwQzhcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTMifSwKLQotICAgICAgICAvKiogIGRldGFjaCgpIG5vdCBzdXBwb3J0ZWQgYnkgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIgICAqLwotICAgeyBFUl9ERVRBQ0hfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiwKLSAgICAgICAgICAgICAgICAiZGV0YWNoKClcdTMwNkZYUlRyZWVGcmFnU2VsZWN0V3JhcHBlclx1MzA2Qlx1MzA4OFx1MzA2M1x1MzA2Nlx1MzBCNVx1MzBERFx1MzBGQ1x1MzBDOFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5MyJ9LAotCi0gICAgICAgIC8qKiAgbnVtKCkgbm90IHN1cHBvcnRlZCBieSBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciAgICovCi0gICB7IEVSX05VTV9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSLAotICAgICAgICAgICAgICAgICJudW0oKVx1MzA2RlhSVHJlZUZyYWdTZWxlY3RXcmFwcGVyXHUzMDZCXHUzMDg4XHUzMDYzXHUzMDY2XHUzMEI1XHUzMEREXHUzMEZDXHUzMEM4XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzIn0sCi0KLSAgICAgICAgLyoqICB4c3RyKCkgbm90IHN1cHBvcnRlZCBieSBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciAgICovCi0gICB7IEVSX1hTVFJfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiwKLSAgICAgICAgICAgICAgICAieHN0cigpXHUzMDZGWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXJcdTMwNkJcdTMwODhcdTMwNjNcdTMwNjZcdTMwQjVcdTMwRERcdTMwRkNcdTMwQzhcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTMifSwKLQotICAgICAgICAvKiogIHN0cigpIG5vdCBzdXBwb3J0ZWQgYnkgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIgICAqLwotICAgeyBFUl9TVFJfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiwKLSAgICAgICAgICAgICAgICAic3RyKClcdTMwNkZYUlRyZWVGcmFnU2VsZWN0V3JhcHBlclx1MzA2Qlx1MzA4OFx1MzA2M1x1MzA2Nlx1MzBCNVx1MzBERFx1MzBGQ1x1MzBDOFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5MyJ9LAotCi0gIHsgRVJfRlNCX05PVF9TVVBQT1JURURfWFNUUklOR0ZPUkNIQVJTLAotICAgICAgICJmc2IoKVx1MzA2RlhTdHJpbmdGb3JDaGFyc1x1NzUyOFx1MzA2Qlx1MzBCNVx1MzBERFx1MzBGQ1x1MzBDOFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5MyJ9LAotCi0gIHsgRVJfQ09VTERfTk9UX0ZJTkRfVkFSLAotICAgICAgIlx1NTQwRFx1NTI0RHswfVx1MzA2RVx1NTkwOVx1NjU3MFx1MzA0Q1x1ODk4Qlx1MzA2NFx1MzA0Qlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5M1x1MzA2N1x1MzA1N1x1MzA1RiJ9LAotCi0gIHsgRVJfWFNUUklOR0ZPUkNIQVJTX0NBTk5PVF9UQUtFX1NUUklORywKLSAgICAgICJYU3RyaW5nRm9yQ2hhcnNcdTMwNkZcdTVGMTVcdTY1NzBcdTMwNkJcdTMwNjRcdTMwNDRcdTMwNjZcdTY1ODdcdTVCNTdcdTUyMTdcdTMwOTJcdTUzRDZcdTMwOEJcdTMwNTNcdTMwNjhcdTMwNENcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTMifSwKLQotICB7IEVSX0ZBU1RTVFJJTkdCVUZGRVJfQ0FOTk9UX0JFX05VTEwsCi0gICAgICAiRmFzdFN0cmluZ0J1ZmZlclx1NUYxNVx1NjU3MFx1MzA2Rm51bGxcdTMwNkJcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTMifSwKLQotICB7IEVSX1RXT19PUl9USFJFRSwKLSAgICAgICAiMlx1MzA3RVx1MzA1Rlx1MzA2RjMifSwKLQotICB7IEVSX1ZBUklBQkxFX0FDQ0VTU0VEX0JFRk9SRV9CSU5ELAotICAgICAgICJcdTU5MDlcdTY1NzBcdTMwNENcdTMwRDBcdTMwQTRcdTMwRjNcdTMwQzlcdTMwNTVcdTMwOENcdTMwOEJcdTUyNERcdTMwNkJcdTMwQTJcdTMwQUZcdTMwQkJcdTMwQjlcdTMwNTVcdTMwOENcdTMwN0VcdTMwNTdcdTMwNUZcdTMwMDIifSwKLQotICB7IEVSX0ZTQl9DQU5OT1RfVEFLRV9TVFJJTkcsCi0gICAgICAgIlhTdHJpbmdGb3JGU0JcdTMwNkZcdTVGMTVcdTY1NzBcdTMwNkJcdTMwNjRcdTMwNDRcdTMwNjZcdTY1ODdcdTVCNTdcdTUyMTdcdTMwOTJcdTUzRDZcdTMwOEJcdTMwNTNcdTMwNjhcdTMwNENcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIifSwKLQotICB7IEVSX1NFVFRJTkdfV0FMS0VSX1JPT1RfVE9fTlVMTCwKLSAgICAgICAiXG4gXHUzMEE4XHUzMEU5XHUzMEZDXHUzMDAyXHUzMEE2XHUzMEE5XHUzMEZDXHUzMEFCXHUzMDZFXHUzMEVCXHUzMEZDXHUzMEM4XHUzMDkybnVsbFx1MzA2Qlx1OEEyRFx1NUI5QVx1MzA1N1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OVx1MzAwMiJ9LAotCi0gIHsgRVJfTk9ERVNFVERUTV9DQU5OT1RfSVRFUkFURSwKLSAgICAgICAiXHUzMDUzXHUzMDZFTm9kZVNldERUTVx1MzA2Rlx1NTI0RFx1MzA2RVx1MzBDRVx1MzBGQ1x1MzBDOVx1MzA5Mlx1NTNDRFx1NUZBOVx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMiJ9LAotCi0gIHsgRVJfTk9ERVNFVF9DQU5OT1RfSVRFUkFURSwKLSAgICAgICAiXHUzMDUzXHUzMDZFTm9kZVNldFx1MzA2Rlx1NTI0RFx1MzA2RVx1MzBDRVx1MzBGQ1x1MzBDOVx1MzA5Mlx1NTNDRFx1NUZBOVx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMiJ9LAotCi0gIHsgRVJfTk9ERVNFVERUTV9DQU5OT1RfSU5ERVgsCi0gICAgICAgIlx1MzA1M1x1MzA2RU5vZGVTZXREVE1cdTMwNkZcdTdEMjJcdTVGMTVcdTRFRDhcdTMwNTFcdTMwN0VcdTMwNUZcdTMwNkZcdTMwQUJcdTMwQTZcdTMwRjNcdTMwQzhcdTZBNUZcdTgwRkRcdTMwOTJcdTVCOUZcdTg4NENcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIifSwKLQotICB7IEVSX05PREVTRVRfQ0FOTk9UX0lOREVYLAotICAgICAgICJcdTMwNTNcdTMwNkVOb2RlU2V0XHUzMDZGXHU3RDIyXHU1RjE1XHU0RUQ4XHUzMDUxXHUzMDdFXHUzMDVGXHUzMDZGXHUzMEFCXHUzMEE2XHUzMEYzXHUzMEM4XHU2QTVGXHU4MEZEXHUzMDkyXHU1QjlGXHU4ODRDXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyIn0sCi0KLSAgeyBFUl9DQU5OT1RfQ0FMTF9TRVRTSE9VTERDQUNIRU5PREUsCi0gICAgICAgIm5leHROb2RlXHUzMDkyXHU1NDdDXHUzMDczXHU1MUZBXHUzMDU3XHUzMDVGXHU1RjhDXHUzMDZCc2V0U2hvdWxkQ2FjaGVOb2Rlc1x1MzA5Mlx1NTQ3Q1x1MzA3M1x1NTFGQVx1MzA1Qlx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMiJ9LAotCi0gIHsgRVJfT05MWV9BTExPV1MsCi0gICAgICAgInswfVx1MzA2RnsxfVx1NTAwQlx1MzA2RVx1NUYxNVx1NjU3MFx1MzA2RVx1MzA3Rlx1OEEzMVx1NTNFRlx1MzA1N1x1MzA3RVx1MzA1OSJ9LAotCi0gIHsgRVJfVU5LTk9XTl9TVEVQLAotICAgICAgICJnZXROZXh0U3RlcFBvc1x1MzA2N1x1MzA2RVx1MzBEN1x1MzBFRFx1MzBCMFx1MzBFOVx1MzBERVx1MzA2RVx1MzBBMlx1MzBCNVx1MzBGQ1x1MzBCN1x1MzBFN1x1MzBGMzogXHU0RTBEXHU2NjBFXHUzMDZBc3RlcFR5cGU6IHswfSJ9LAotCi0gIC8vTm90ZSB0byB0cmFuc2xhdG9yczogIEEgcmVsYXRpdmUgbG9jYXRpb24gcGF0aCBpcyBhIGZvcm0gb2YgWFBhdGggZXhwcmVzc2lvbi4KLSAgLy8gVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgc3VjaCBhbiBleHByZXNzaW9uIHdhcyBleHBlY3RlZCBmb2xsb3dpbmcgdGhlCi0gIC8vIGNoYXJhY3RlcnMgJy8nIG9yICcvLycsIGJ1dCB3YXMgbm90IGZvdW5kLgotICB7IEVSX0VYUEVDVEVEX1JFTF9MT0NfUEFUSCwKLSAgICAgICInLydcdTMwN0VcdTMwNUZcdTMwNkYnLy8nXHUzMEM4XHUzMEZDXHUzMEFGXHUzMEYzXHUzMDZFXHU1RjhDXHUzMDZCXHU3NkY4XHU1QkZFXHUzMEVEXHUzMEIxXHUzMEZDXHUzMEI3XHUzMEU3XHUzMEYzXHUzMEZCXHUzMEQxXHUzMEI5XHUzMDRDXHU1RkM1XHU4OTgxXHUzMDY3XHUzMDU5XHUzMDAyIn0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIEEgbG9jYXRpb24gcGF0aCBpcyBhIGZvcm0gb2YgWFBhdGggZXhwcmVzc2lvbi4KLSAgLy8gVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgc3ludGFjdGljYWxseSBzdWNoIGFuIGV4cHJlc3Npb24gd2FzIGV4cGVjdGVkLGJ1dAotICAvLyB0aGUgY2hhcmFjdGVycyBzcGVjaWZpZWQgYnkgdGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHdlcmUgZW5jb3VudGVyZWQgaW5zdGVhZC4KLSAgeyBFUl9FWFBFQ1RFRF9MT0NfUEFUSCwKLSAgICAgICAiXHUzMEVEXHUzMEIxXHUzMEZDXHUzMEI3XHUzMEU3XHUzMEYzXHUzMEZCXHUzMEQxXHUzMEI5XHUzMDRDXHU1RkM1XHU4OTgxXHUzMDY3XHUzMDU5XHUzMDRDXHUzMDAxXHU2QjIxXHUzMDZFXHUzMEM4XHUzMEZDXHUzMEFGXHUzMEYzXHUzMDRDXHU2OTFDXHU1MUZBXHUzMDU1XHUzMDhDXHUzMDdFXHUzMDU3XHUzMDVGOiAgezB9In0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIEEgbG9jYXRpb24gcGF0aCBpcyBhIGZvcm0gb2YgWFBhdGggZXhwcmVzc2lvbi4KLSAgLy8gVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgc3ludGFjdGljYWxseSBzdWNoIGEgc3ViZXhwcmVzc2lvbiB3YXMgZXhwZWN0ZWQsCi0gIC8vIGJ1dCBubyBtb3JlIGNoYXJhY3RlcnMgd2VyZSBmb3VuZCBpbiB0aGUgZXhwcmVzc2lvbi4KLSAgeyBFUl9FWFBFQ1RFRF9MT0NfUEFUSF9BVF9FTkRfRVhQUiwKLSAgICAgICAiXHUzMEVEXHUzMEIxXHUzMEZDXHUzMEI3XHUzMEU3XHUzMEYzXHUzMEZCXHUzMEQxXHUzMEI5XHUzMDRDXHU1RkM1XHU4OTgxXHUzMDY3XHUzMDU5XHUzMDRDXHUzMDAxXHUzMDRCXHUzMDhGXHUzMDhBXHUzMDZCWFBhdGhcdTVGMEZcdTMwNkVcdTdENDJcdTMwOEZcdTMwOEFcdTMwNENcdTY5MUNcdTUxRkFcdTMwNTVcdTMwOENcdTMwN0VcdTMwNTdcdTMwNUZcdTMwMDIifSwKLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQSBsb2NhdGlvbiBzdGVwIGlzIHBhcnQgb2YgYW4gWFBhdGggZXhwcmVzc2lvbi4KLSAgLy8gVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgc3ludGFjdGljYWxseSBzdWNoIGFuIGV4cHJlc3Npb24gd2FzIGV4cGVjdGVkCi0gIC8vIGZvbGxvd2luZyB0aGUgc3BlY2lmaWVkIGNoYXJhY3RlcnMuCi0gIHsgRVJfRVhQRUNURURfTE9DX1NURVAsCi0gICAgICAgIicvJ1x1MzA3RVx1MzA1Rlx1MzA2RicvLydcdTMwQzhcdTMwRkNcdTMwQUZcdTMwRjNcdTMwNkVcdTVGOENcdTMwNkJcdTMwRURcdTMwQjFcdTMwRkNcdTMwQjdcdTMwRTdcdTMwRjNcdTMwRkJcdTMwQjlcdTMwQzZcdTMwQzNcdTMwRDdcdTMwNENcdTVGQzVcdTg5ODFcdTMwNjdcdTMwNTlcdTMwMDIifSwKLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQSBub2RlIHRlc3QgaXMgcGFydCBvZiBhbiBYUGF0aCBleHByZXNzaW9uIHRoYXQgaXMKLSAgLy8gdXNlZCB0byB0ZXN0IGZvciBwYXJ0aWN1bGFyIGtpbmRzIG9mIG5vZGVzLiAgSW4gdGhpcyBjYXNlLCBhIG5vZGUgdGVzdCB0aGF0Ci0gIC8vIGNvbnNpc3RzIG9mIGFuIE5DTmFtZSBmb2xsb3dlZCBieSBhIGNvbG9uIGFuZCBhbiBhc3RlcmlzayBvciB0aGF0IGNvbnNpc3RzCi0gIC8vIG9mIGEgUU5hbWUgd2FzIGV4cGVjdGVkLCBidXQgd2FzIG5vdCBmb3VuZC4KLSAgeyBFUl9FWFBFQ1RFRF9OT0RFX1RFU1QsCi0gICAgICAgIk5DTmFtZToqXHUzMDdFXHUzMDVGXHUzMDZGUU5hbWVcdTMwNkJcdTRFMDBcdTgxRjRcdTMwNTlcdTMwOEJcdTMwQ0VcdTMwRkNcdTMwQzlcdTMwRkJcdTMwQzZcdTMwQjlcdTMwQzhcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIifSwKLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQSBzdGVwIHBhdHRlcm4gaXMgcGFydCBvZiBhbiBYUGF0aCBleHByZXNzaW9uLgotICAvLyBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCBzeW50YWN0aWNhbGx5IHN1Y2ggYW4gZXhwcmVzc2lvbiB3YXMgZXhwZWN0ZWQsCi0gIC8vIGJ1dCB0aGUgc3BlY2lmaWVkIGNoYXJhY3RlciB3YXMgZm91bmQgaW4gdGhlIGV4cHJlc3Npb24gaW5zdGVhZC4KLSAgeyBFUl9FWFBFQ1RFRF9TVEVQX1BBVFRFUk4sCi0gICAgICAgIlx1MzBCOVx1MzBDNlx1MzBDM1x1MzBEN1x1MzBGQlx1MzBEMVx1MzBCRlx1MzBGQ1x1MzBGM1x1MzA0Q1x1NUZDNVx1ODk4MVx1MzA2N1x1MzA1OVx1MzA0Q1x1MzAwMScvJ1x1MzA0Q1x1NjkxQ1x1NTFGQVx1MzA1NVx1MzA4Q1x1MzA3RVx1MzA1N1x1MzA1Rlx1MzAwMiJ9LAotCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6IEEgcmVsYXRpdmUgcGF0aCBwYXR0ZXJuIGlzIHBhcnQgb2YgYW4gWFBhdGggZXhwcmVzc2lvbi4KLSAgLy8gVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgc3ludGFjdGljYWxseSBzdWNoIGFuIGV4cHJlc3Npb24gd2FzIGV4cGVjdGVkLAotICAvLyBidXQgd2FzIG5vdCBmb3VuZC4KLSAgeyBFUl9FWFBFQ1RFRF9SRUxfUEFUSF9QQVRURVJOLAotICAgICAgICJcdTc2RjhcdTVCRkVcdTMwRDFcdTMwQjlcdTMwRkJcdTMwRDFcdTMwQkZcdTMwRkNcdTMwRjNcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIifSwKLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIGEgZGF0YSB0eXBlLiAgVGhlCi0gIC8vIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgYSB2YWx1ZSBvZiBhIHBhcnRpY3VsYXIgdHlwZSBjb3VsZCBub3QgYmUgY29udmVydGVkCi0gIC8vIHRvIGEgdmFsdWUgb2YgdHlwZSBib29sZWFuLgotICB7IEVSX0NBTlRfQ09OVkVSVF9UT19CT09MRUFOLAotICAgICAgICJYUGF0aFx1NUYwRicnezB9JydcdTMwNkVYUGF0aFJlc3VsdFx1MzA2Rlx1MzAwMWJvb2xlYW5cdTMwNkJcdTU5MDlcdTYzREJcdTMwNjdcdTMwNERcdTMwNkFcdTMwNDR7MX1cdTMwNkVYUGF0aFJlc3VsdFR5cGVcdTMwNjdcdTMwNTlcdTMwMDIifSwKLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiBEbyBub3QgdHJhbnNsYXRlIEFOWV9VTk9SREVSRURfTk9ERV9UWVBFIGFuZAotICAvLyBGSVJTVF9PUkRFUkVEX05PREVfVFlQRS4KLSAgeyBFUl9DQU5UX0NPTlZFUlRfVE9fU0lOR0xFTk9ERSwKLSAgICAgICAiWFBhdGhcdTVGMEYnJ3swfScnXHUzMDZFWFBhdGhSZXN1bHRcdTMwNkZcdTMwMDFcdTUzNThcdTRFMDBcdTMwQ0VcdTMwRkNcdTMwQzlcdTMwNkJcdTU5MDlcdTYzREJcdTMwNjdcdTMwNERcdTMwNkFcdTMwNDR7MX1cdTMwNkVYUGF0aFJlc3VsdFR5cGVcdTMwNjdcdTMwNTlcdTMwMDJcdTMwRTFcdTMwQkRcdTMwQzNcdTMwQzlnZXRTaW5nbGVOb2RlVmFsdWVcdTMwNkZcdTMwMDFBTllfVU5PUkRFUkVEX05PREVfVFlQRVx1MzBCRlx1MzBBNFx1MzBEN1x1MzA0QVx1MzA4OFx1MzA3M0ZJUlNUX09SREVSRURfTk9ERV9UWVBFXHUzMEJGXHUzMEE0XHUzMEQ3XHUzMDZCXHUzMDZFXHUzMDdGXHU5MDY5XHU3NTI4XHUzMDU1XHUzMDhDXHUzMDdFXHUzMDU5XHUzMDAyIn0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogRG8gbm90IHRyYW5zbGF0ZSBVTk9SREVSRURfTk9ERV9TTkFQU0hPVF9UWVBFIGFuZAotICAvLyBPUkRFUkVEX05PREVfU05BUFNIT1RfVFlQRS4KLSAgeyBFUl9DQU5UX0dFVF9TTkFQU0hPVF9MRU5HVEgsCi0gICAgICAgIlhQYXRoUmVzdWx0VHlwZVx1MzA0Q3sxfVx1MzA2RVx1MzA1Rlx1MzA4MVx1MzAwMVx1MzBFMVx1MzBCRFx1MzBDM1x1MzBDOWdldFNuYXBzaG90TGVuZ3RoXHUzMDZGWFBhdGhcdTVGMEYnJ3swfScnXHUzMDZFWFBhdGhSZXN1bHRcdTMwNjdcdTU0N0NcdTMwNzNcdTUxRkFcdTMwNTlcdTMwNTNcdTMwNjhcdTMwNENcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDJcdTMwNTNcdTMwNkVcdTMwRTFcdTMwQkRcdTMwQzNcdTMwQzlcdTMwNkZcdTMwMDFVTk9SREVSRURfTk9ERV9TTkFQU0hPVF9UWVBFXHUzMEJGXHUzMEE0XHUzMEQ3XHUzMDRBXHUzMDg4XHUzMDczT1JERVJFRF9OT0RFX1NOQVBTSE9UX1RZUEVcdTMwQkZcdTMwQTRcdTMwRDdcdTMwNkJcdTMwNkVcdTMwN0ZcdTkwNjlcdTc1MjhcdTMwNTVcdTMwOENcdTMwN0VcdTMwNTlcdTMwMDIifSwKLQotICB7IEVSX05PTl9JVEVSQVRPUl9UWVBFLAotICAgICAgICJYUGF0aFJlc3VsdFR5cGVcdTMwNEN7MX1cdTMwNkVcdTMwNUZcdTMwODFcdTMwMDFcdTMwRTFcdTMwQkRcdTMwQzNcdTMwQzlpdGVyYXRlTmV4dFx1MzA2RlhQYXRoXHU1RjBGJyd7MH0nJ1x1MzA2RVhQYXRoUmVzdWx0XHUzMDY3XHU1NDdDXHUzMDczXHU1MUZBXHUzMDU5XHUzMDUzXHUzMDY4XHUzMDRDXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyXHUzMDUzXHUzMDZFXHUzMEUxXHUzMEJEXHUzMEMzXHUzMEM5XHUzMDZGXHUzMDAxVU5PUkRFUkVEX05PREVfSVRFUkFUT1JfVFlQRVx1MzBCRlx1MzBBNFx1MzBEN1x1MzA0QVx1MzA4OFx1MzA3M09SREVSRURfTk9ERV9JVEVSQVRPUl9UWVBFXHUzMEJGXHUzMEE0XHUzMEQ3XHUzMDZCXHUzMDZFXHUzMDdGXHU5MDY5XHU3NTI4XHUzMDU1XHUzMDhDXHUzMDdFXHUzMDU5XHUzMDAyIn0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogVGhpcyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoZSBkb2N1bWVudCBiZWluZyBvcGVyYXRlZAotICAvLyB1cG9uIGNoYW5nZWQsIHNvIHRoZSBpdGVyYXRvciBvYmplY3QgdGhhdCB3YXMgYmVpbmcgdXNlZCB0byB0cmF2ZXJzZSB0aGUKLSAgLy8gZG9jdW1lbnQgaGFzIG5vdyBiZWNvbWUgaW52YWxpZC4KLSAgeyBFUl9ET0NfTVVUQVRFRCwKLSAgICAgICAiXHU3RDUwXHU2NzlDXHUzMDRDXHU4RkQ0XHUzMDU1XHUzMDhDXHUzMDVGXHU1RjhDXHUzMDZCXHUzMEM5XHUzMEFEXHUzMEU1XHUzMEUxXHUzMEYzXHUzMEM4XHUzMDRDXHU1OTA5XHU2NkY0XHUzMDU1XHUzMDhDXHUzMDdFXHUzMDU3XHUzMDVGXHUzMDAyXHUzMEE0XHUzMEM2XHUzMEVDXHUzMEZDXHUzMEJGXHUzMDRDXHU3MTIxXHU1MkI5XHUzMDY3XHUzMDU5XHUzMDAyIn0sCi0KLSAgeyBFUl9JTlZBTElEX1hQQVRIX1RZUEUsCi0gICAgICAgIlhQYXRoXHUzMEJGXHUzMEE0XHUzMEQ3XHUzMDZFXHU1RjE1XHU2NTcwezB9XHUzMDRDXHU3MTIxXHU1MkI5XHUzMDY3XHUzMDU5In0sCi0KLSAgeyBFUl9FTVBUWV9YUEFUSF9SRVNVTFQsCi0gICAgICAgIlhQYXRoXHU3RDUwXHU2NzlDXHUzMEFBXHUzMEQ2XHUzMEI4XHUzMEE3XHUzMEFGXHUzMEM4XHUzMDRDXHU3QTdBXHUzMDY3XHUzMDU5In0sCi0KLSAgeyBFUl9JTkNPTVBBVElCTEVfVFlQRVMsCi0gICAgICAgIlhQYXRoXHU1RjBGJyd7MH0nJ1x1MzA2RVhQYXRoUmVzdWx0XHUzMDZGXHUzMDAxezJ9XHUzMDZFXHU2MzA3XHU1QjlBXHUzMDU1XHUzMDhDXHUzMDVGWFBhdGhSZXN1bHRUeXBlXHUzMDZCXHU1RjM3XHU1MjM2XHU1OTA5XHU2M0RCXHUzMDY3XHUzMDREXHUzMDZBXHUzMDQ0ezF9XHUzMDZFWFBhdGhSZXN1bHRUeXBlXHUzMDkyXHU2MzAxXHUzMDYxXHUzMDdFXHUzMDU5XHUzMDAyIn0sCi0KLSAgeyBFUl9OVUxMX1JFU09MVkVSLAotICAgICAgICJudWxsXHU2M0E1XHU5ODJEXHU4RjlFXHUzMEVBXHUzMEJFXHUzMEVCXHUzMEQwXHUzMDY3XHU2M0E1XHU5ODJEXHU4RjlFXHUzMDkyXHU4OUUzXHU2QzdBXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyIn0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBhIGRhdGEgdHlwZS4gIFRoZQotICAvLyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IGEgdmFsdWUgb2YgYSBwYXJ0aWN1bGFyIHR5cGUgY291bGQgbm90IGJlIGNvbnZlcnRlZAotICAvLyB0byBhIHZhbHVlIG9mIHR5cGUgc3RyaW5nLgotICB7IEVSX0NBTlRfQ09OVkVSVF9UT19TVFJJTkcsCi0gICAgICAgIlhQYXRoXHU1RjBGJyd7MH0nJ1x1MzA2RVhQYXRoUmVzdWx0XHUzMDZGXHUzMDAxXHU2NTg3XHU1QjU3XHU1MjE3XHUzMDZCXHU1OTA5XHU2M0RCXHUzMDY3XHUzMDREXHUzMDZBXHUzMDQ0ezF9XHUzMDZFWFBhdGhSZXN1bHRUeXBlXHUzMDkyXHU2MzAxXHUzMDYxXHUzMDdFXHUzMDU5XHUzMDAyIn0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogRG8gbm90IHRyYW5zbGF0ZSBzbmFwc2hvdEl0ZW0sCi0gIC8vIFVOT1JERVJFRF9OT0RFX1NOQVBTSE9UX1RZUEUgYW5kIE9SREVSRURfTk9ERV9TTkFQU0hPVF9UWVBFLgotICB7IEVSX05PTl9TTkFQU0hPVF9UWVBFLAotICAgICAgICJYUGF0aFJlc3VsdFR5cGVcdTMwNEN7MX1cdTMwNkVcdTMwNUZcdTMwODFcdTMwMDFcdTMwRTFcdTMwQkRcdTMwQzNcdTMwQzlzbmFwc2hvdEl0ZW1cdTMwNkZYUGF0aFx1NUYwRicnezB9JydcdTMwNkVYUGF0aFJlc3VsdFx1MzA2N1x1NTQ3Q1x1MzA3M1x1NTFGQVx1MzA1OVx1MzA1M1x1MzA2OFx1MzA0Q1x1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMlx1MzA1M1x1MzA2RVx1MzBFMVx1MzBCRFx1MzBDM1x1MzBDOVx1MzA2Rlx1MzAwMVVOT1JERVJFRF9OT0RFX1NOQVBTSE9UX1RZUEVcdTMwQkZcdTMwQTRcdTMwRDdcdTMwNEFcdTMwODhcdTMwNzNPUkRFUkVEX05PREVfU05BUFNIT1RfVFlQRVx1MzBCRlx1MzBBNFx1MzBEN1x1MzA2Qlx1MzA2RVx1MzA3Rlx1OTA2OVx1NzUyOFx1MzA1NVx1MzA4Q1x1MzA3RVx1MzA1OVx1MzAwMiJ9LAotCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBYUGF0aEV2YWx1YXRvciBpcyBhIEphdmEgaW50ZXJmYWNlIG5hbWUuICBBbgotICAvLyBYUGF0aEV2YWx1YXRvciBpcyBjcmVhdGVkIHdpdGggcmVzcGVjdCB0byBhIHBhcnRpY3VsYXIgWE1MIGRvY3VtZW50LCBhbmQgaW4KLSAgLy8gdGhpcyBjYXNlIHRoZSBleHByZXNzaW9uIHJlcHJlc2VudGVkIGJ5IHRoaXMgb2JqZWN0IHdhcyBiZWluZyBldmFsdWF0ZWQgd2l0aAotICAvLyByZXNwZWN0IHRvIGEgY29udGV4dCBub2RlIGZyb20gYSBkaWZmZXJlbnQgZG9jdW1lbnQuCi0gIHsgRVJfV1JPTkdfRE9DVU1FTlQsCi0gICAgICAgIlx1MzBCM1x1MzBGM1x1MzBDNlx1MzBBRFx1MzBCOVx1MzBDOFx1MzBGQlx1MzBDRVx1MzBGQ1x1MzBDOVx1MzA2Rlx1MzAwMVx1MzA1M1x1MzA2RVhQYXRoRXZhbHVhdG9yXHUzMDZCXHUzMEQwXHUzMEE0XHUzMEYzXHUzMEM5XHUzMDU1XHUzMDhDXHUzMDVGXHUzMEM5XHUzMEFEXHUzMEU1XHUzMEUxXHUzMEYzXHUzMEM4XHUzMDZCXHU1QzVFXHUzMDU3XHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyIn0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBYUGF0aCBleHByZXNzaW9uIGNhbm5vdCBiZSBldmFsdWF0ZWQgd2l0aCByZXNwZWN0Ci0gIC8vIHRvIHRoaXMgdHlwZSBvZiBub2RlLgotICB7IEVSX1dST05HX05PREVUWVBFLAotICAgICAgICJcdTMwQjNcdTMwRjNcdTMwQzZcdTMwQURcdTMwQjlcdTMwQzhcdTMwRkJcdTMwQ0VcdTMwRkNcdTMwQzlcdTMwRkJcdTMwQkZcdTMwQTRcdTMwRDdcdTMwNkZcdTMwQjVcdTMwRERcdTMwRkNcdTMwQzhcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIifSwKLQotICB7IEVSX1hQQVRIX0VSUk9SLAotICAgICAgICJYUGF0aFx1MzA2Qlx1NEUwRFx1NjYwRVx1MzA2QVx1MzBBOFx1MzBFOVx1MzBGQ1x1MzA0Q1x1NzY3QVx1NzUxRlx1MzA1N1x1MzA3RVx1MzA1N1x1MzA1Rlx1MzAwMiJ9LAotCi0gIHsgRVJfQ0FOVF9DT05WRVJUX1hQQVRIUkVTVUxUVFlQRV9UT19OVU1CRVIsCi0gICAgICAgICJYUGF0aFx1NUYwRicnezB9JydcdTMwNkVYUGF0aFJlc3VsdFx1MzA2Rlx1MzAwMVx1NjU3MFx1NTAyNFx1MzA2Qlx1NTkwOVx1NjNEQlx1MzA2N1x1MzA0RFx1MzA2QVx1MzA0NHsxfVx1MzA2RVhQYXRoUmVzdWx0VHlwZVx1MzA5Mlx1NjMwMVx1MzA2MVx1MzA3RVx1MzA1OSJ9LAotCi0gIC8vQkVHSU46ICBEZWZpbml0aW9ucyBvZiBlcnJvciBrZXlzIHVzZWQgIGluIGV4Y2VwdGlvbiBtZXNzYWdlcyBvZiAgSkFYUCAxLjMgWFBhdGggQVBJIGltcGxlbWVudGF0aW9uCi0KLSAgLyoqIEZpZWxkIEVSX0VYVEVOU0lPTl9GVU5DVElPTl9DQU5OT1RfQkVfSU5WT0tFRCAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX0VYVEVOU0lPTl9GVU5DVElPTl9DQU5OT1RfQkVfSU5WT0tFRCwKLSAgICAgICAiXHU2MkUxXHU1RjM1XHU5NUEyXHU2NTcwOiBYTUxDb25zdGFudHMuRkVBVFVSRV9TRUNVUkVfUFJPQ0VTU0lOR1x1NkE1Rlx1ODBGRFx1MzA0Q3RydWVcdTMwNkJcdThBMkRcdTVCOUFcdTMwNTVcdTMwOENcdTMwOEJcdTMwNjgnJ3swfScnXHUzMDkyXHU4RDc3XHU1MkQ1XHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyIn0sCi0KLSAgLyoqIEZpZWxkIEVSX1JFU09MVkVfVkFSSUFCTEVfUkVUVVJOU19OVUxMICAgICAgICAgICAgICAgICAgICAgICAqLwotCi0gIHsgRVJfUkVTT0xWRV9WQVJJQUJMRV9SRVRVUk5TX05VTEwsCi0gICAgICAgIlx1NTkwOVx1NjU3MHswfVx1MzA2RXJlc29sdmVWYXJpYWJsZVx1MzA0Q251bGxcdTMwOTJcdThGRDRcdTMwNTdcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTkifSwKLQotICAvKiogRmllbGQgRVJfVU5TVVBQT1JURURfUkVUVVJOX1RZUEUgICAgICAgICAgICAgICAgICAgICAgICovCi0KLSAgeyBFUl9VTlNVUFBPUlRFRF9SRVRVUk5fVFlQRSwKLSAgICAgICAiXHUzMEI1XHUzMEREXHUzMEZDXHUzMEM4XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDZBXHUzMDQ0XHU2MjNCXHUzMDhBXHU1NzhCOiB7MH0ifSwKLQotICAvKiogRmllbGQgRVJfU09VUkNFX1JFVFVSTl9UWVBFX0NBTk5PVF9CRV9OVUxMICAgICAgICAgICAgICAgICAgICAgICAqLwotCi0gIHsgRVJfU09VUkNFX1JFVFVSTl9UWVBFX0NBTk5PVF9CRV9OVUxMLAotICAgICAgICJcdTMwQkRcdTMwRkNcdTMwQjlcdTMwRkJcdTMwQkZcdTMwQTRcdTMwRDdcdTMwN0VcdTMwNUZcdTMwNkZcdTYyM0JcdTMwOEFcdTU3OEJcdTMwNkZudWxsXHUzMDZCXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzIn0sCi0KLSAgLyoqIEZpZWxkIEVSX1NPVVJDRV9SRVRVUk5fVFlQRV9DQU5OT1RfQkVfTlVMTCAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX1NPVVJDRV9SRVRVUk5fVFlQRV9DQU5OT1RfQkVfTlVMTCwKLSAgICAgICAiXHUzMEJEXHUzMEZDXHUzMEI5XHUzMEZCXHUzMEJGXHUzMEE0XHUzMEQ3XHUzMDdFXHUzMDVGXHUzMDZGXHU2MjNCXHUzMDhBXHU1NzhCXHUzMDZGbnVsbFx1MzA2Qlx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MyJ9LAotCi0gIC8qKiBGaWVsZCBFUl9BUkdfQ0FOTk9UX0JFX05VTEwgICAgICAgICAgICAgICAgICAgICAgICovCi0KLSAgeyBFUl9BUkdfQ0FOTk9UX0JFX05VTEwsCi0gICAgICAgInswfVx1NUYxNVx1NjU3MFx1MzA2Rm51bGxcdTMwNkJcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTMifSwKLQotICAvKiogRmllbGQgRVJfT0JKRUNUX01PREVMX05VTEwgICAgICAgICAgICAgICAgICAgICAgICovCi0KLSAgeyBFUl9PQkpFQ1RfTU9ERUxfTlVMTCwKLSAgICAgICAiezB9I2lzT2JqZWN0TW9kZWxTdXBwb3J0ZWQoIFN0cmluZyBvYmplY3RNb2RlbCApXHUzMDZGb2JqZWN0TW9kZWwgPT0gbnVsbFx1MzA2N1x1NTQ3Q1x1MzA3M1x1NTFGQVx1MzA1Qlx1MzA3RVx1MzA1Qlx1MzA5MyJ9LAotCi0gIC8qKiBGaWVsZCBFUl9PQkpFQ1RfTU9ERUxfRU1QVFkgICAgICAgICAgICAgICAgICAgICAgICovCi0KLSAgeyBFUl9PQkpFQ1RfTU9ERUxfRU1QVFksCi0gICAgICAgInswfSNpc09iamVjdE1vZGVsU3VwcG9ydGVkKCBTdHJpbmcgb2JqZWN0TW9kZWwgKVx1MzA2Rm9iamVjdE1vZGVsID09IFwiXCJcdTMwNjdcdTU0N0NcdTMwNzNcdTUxRkFcdTMwNUJcdTMwN0VcdTMwNUJcdTMwOTMifSwKLQotICAvKiogRmllbGQgRVJfT0JKRUNUX01PREVMX0VNUFRZICAgICAgICAgICAgICAgICAgICAgICAqLwotCi0gIHsgRVJfRkVBVFVSRV9OQU1FX05VTEwsCi0gICAgICAgIlx1NkE1Rlx1ODBGRFx1MzA2Qm51bGxcdTMwNkVcdTU0MERcdTUyNERcdTMwOTJcdThBMkRcdTVCOUFcdTMwNTdcdTMwODhcdTMwNDZcdTMwNjhcdTMwNTdcdTMwN0VcdTMwNTdcdTMwNUY6IHswfSNzZXRGZWF0dXJlKCBudWxsLCB7MX0pIn0sCi0KLSAgLyoqIEZpZWxkIEVSX0ZFQVRVUkVfVU5LTk9XTiAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX0ZFQVRVUkVfVU5LTk9XTiwKLSAgICAgICAiXHU0RTBEXHU2NjBFXHUzMDZBXHU2QTVGXHU4MEZEXCJ7MH1cIlx1MzA5Mlx1OEEyRFx1NUI5QVx1MzA1N1x1MzA4OFx1MzA0Nlx1MzA2OFx1MzA1N1x1MzA3RVx1MzA1N1x1MzA1RjogezF9I3NldEZlYXR1cmUoezB9LHsyfSkifSwKLQotICAvKiogRmllbGQgRVJfR0VUVElOR19OVUxMX0ZFQVRVUkUgICAgICAgICAgICAgICAgICAgICAgICovCi0KLSAgeyBFUl9HRVRUSU5HX05VTExfRkVBVFVSRSwKLSAgICAgICAibnVsbFx1NTQwRFx1MzA2RVx1NkE1Rlx1ODBGRFx1MzA5Mlx1NTNENlx1NUY5N1x1MzA1N1x1MzA4OFx1MzA0Nlx1MzA2OFx1MzA1N1x1MzA3RVx1MzA1N1x1MzA1RjogezB9I2dldEZlYXR1cmUobnVsbCkifSwKLQotICAvKiogRmllbGQgRVJfR0VUVElOR19OVUxMX0ZFQVRVUkUgICAgICAgICAgICAgICAgICAgICAgICovCi0KLSAgeyBFUl9HRVRUSU5HX1VOS05PV05fRkVBVFVSRSwKLSAgICAgICAiXHU0RTBEXHU2NjBFXHUzMDZBXHU2QTVGXHU4MEZEXCJ7MH1cIlx1MzA5Mlx1NTNENlx1NUY5N1x1MzA1N1x1MzA4OFx1MzA0Nlx1MzA2OFx1MzA1N1x1MzA3RVx1MzA1N1x1MzA1RjogezF9I2dldEZlYXR1cmUoezB9KSJ9LAotCi0gIHtFUl9TRUNVUkVQUk9DRVNTSU5HX0ZFQVRVUkUsCi0gICAgICAgICJGRUFUVVJFX1NFQ1VSRV9QUk9DRVNTSU5HOiBcdTMwQkJcdTMwQURcdTMwRTVcdTMwRUFcdTMwQzZcdTMwQTNcdTMwRkJcdTMwREVcdTMwQ0RcdTMwRkNcdTMwQjhcdTMwRTNcdTMwNENcdTVCNThcdTU3MjhcdTMwNTlcdTMwOEJcdTMwNjhcdTMwNERcdTMwMDFcdTZBNUZcdTgwRkRcdTMwOTJmYWxzZVx1MzA2Qlx1OEEyRFx1NUI5QVx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MzogezF9I3NldEZlYXR1cmUoezB9LHsyfSkifSwKLQotICAvKiogRmllbGQgRVJfTlVMTF9YUEFUSF9GVU5DVElPTl9SRVNPTFZFUiAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX05VTExfWFBBVEhfRlVOQ1RJT05fUkVTT0xWRVIsCi0gICAgICAgIm51bGxcdTMwNkVYUGF0aEZ1bmN0aW9uUmVzb2x2ZXJcdTMwOTJcdThBMkRcdTVCOUFcdTMwNTdcdTMwODhcdTMwNDZcdTMwNjhcdTMwNTdcdTMwN0VcdTMwNTdcdTMwNUY6IHswfSNzZXRYUGF0aEZ1bmN0aW9uUmVzb2x2ZXIobnVsbCkifSwKLQotICAvKiogRmllbGQgRVJfTlVMTF9YUEFUSF9WQVJJQUJMRV9SRVNPTFZFUiAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX05VTExfWFBBVEhfVkFSSUFCTEVfUkVTT0xWRVIsCi0gICAgICAgIm51bGxcdTMwNkVYUGF0aFZhcmlhYmxlUmVzb2x2ZXJcdTMwOTJcdThBMkRcdTVCOUFcdTMwNTdcdTMwODhcdTMwNDZcdTMwNjhcdTMwNTdcdTMwN0VcdTMwNTdcdTMwNUY6IHswfSNzZXRYUGF0aFZhcmlhYmxlUmVzb2x2ZXIobnVsbCkifSwKLQotICAvL0VORDogIERlZmluaXRpb25zIG9mIGVycm9yIGtleXMgdXNlZCAgaW4gZXhjZXB0aW9uIG1lc3NhZ2VzIG9mICBKQVhQIDEuMyBYUGF0aCBBUEkgaW1wbGVtZW50YXRpb24KLQotICAvLyBXYXJuaW5ncy4uLgotCi0gIHsgV0dfTE9DQUxFX05BTUVfTk9UX0hBTkRMRUQsCi0gICAgICAiZm9ybWF0LW51bWJlclx1OTVBMlx1NjU3MFx1MzA2RVx1MzBFRFx1MzBCMVx1MzBGQ1x1MzBFQlx1NTQwRFx1MzA0Q1x1NjcyQVx1NTFFNlx1NzQwNlx1MzA2N1x1MzA1OVx1MzAwMiJ9LAotCi0gIHsgV0dfUFJPUEVSVFlfTk9UX1NVUFBPUlRFRCwKLSAgICAgICJYU0xcdTMwRDdcdTMwRURcdTMwRDFcdTMwQzZcdTMwQTNcdTMwNkZcdTMwQjVcdTMwRERcdTMwRkNcdTMwQzhcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTM6IHswfSJ9LAotCi0gIHsgV0dfRE9OVF9ET19BTllUSElOR19XSVRIX05TLAotICAgICAgIlx1MzBEN1x1MzBFRFx1MzBEMVx1MzBDNlx1MzBBM3sxfVx1NTE4NVx1MzA2RVx1MzBDRFx1MzBGQ1x1MzBFMFx1MzBCOVx1MzBEQVx1MzBGQ1x1MzBCOXswfVx1MzA2N1x1MzA2Rlx1NzNGRVx1NTcyOFx1NEY1NVx1MzA4Mlx1NUI5Rlx1ODg0Q1x1MzA1N1x1MzA2QVx1MzA0NFx1MzA2N1x1MzA0Rlx1MzA2MFx1MzA1NVx1MzA0NCJ9LAotCi0gIHsgV0dfU0VDVVJJVFlfRVhDRVBUSU9OLAotICAgICAgIlhTTFx1MzBCN1x1MzBCOVx1MzBDNlx1MzBFMFx1MzBGQlx1MzBEN1x1MzBFRFx1MzBEMVx1MzBDNlx1MzBBM3swfVx1MzA2Qlx1MzBBMlx1MzBBRlx1MzBCQlx1MzBCOVx1MzA1N1x1MzA4OFx1MzA0Nlx1MzA2OFx1MzA1N1x1MzA1Rlx1MzA2OFx1MzA0RFx1MzA2QlNlY3VyaXR5RXhjZXB0aW9uXHUzMDRDXHU3NjdBXHU3NTFGXHUzMDU3XHUzMDdFXHUzMDU3XHUzMDVGIn0sCi0KLSAgeyBXR19RVU9fTk9fTE9OR0VSX0RFRklORUQsCi0gICAgICAiXHU1M0U0XHUzMDQ0XHU2OUNCXHU2NTg3OiBxdW8oLi4uKVx1MzA2RlhQYXRoXHUzMDY3XHUzMDZGXHU3M0ZFXHU1NzI4XHU1QjlBXHU3RkE5XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyIn0sCi0KLSAgeyBXR19ORUVEX0RFUklWRURfT0JKRUNUX1RPX0lNUExFTUVOVF9OT0RFVEVTVCwKLSAgICAgICJYUGF0aFx1MzA2Qlx1MzA2Rm5vZGVUZXN0XHUzMDkyXHU1QjlGXHU4OEM1XHUzMDU5XHUzMDhCXHUzMDVGXHUzMDgxXHUzMDZFXHU1QzBFXHU1MUZBXHUzMEFBXHUzMEQ2XHUzMEI4XHUzMEE3XHUzMEFGXHUzMEM4XHUzMDRDXHU1RkM1XHU4OTgxXHUzMDY3XHUzMDU5XHUzMDAyIn0sCi0KLSAgeyBXR19GVU5DVElPTl9UT0tFTl9OT1RfRk9VTkQsCi0gICAgICAiXHU5NUEyXHU2NTcwXHUzMEM4XHUzMEZDXHUzMEFGXHUzMEYzXHUzMDRDXHU4OThCXHUzMDY0XHUzMDRCXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyIn0sCi0KLSAgeyBXR19DT1VMRE5PVF9GSU5EX0ZVTkNUSU9OLAotICAgICAgIlx1OTVBMlx1NjU3MHswfVx1MzA0Q1x1ODk4Qlx1MzA2NFx1MzA0Qlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5M1x1MzA2N1x1MzA1N1x1MzA1RiJ9LAotCi0gIHsgV0dfQ0FOTk9UX01BS0VfVVJMX0ZST00sCi0gICAgICAiezB9XHUzMDRCXHUzMDg5VVJMXHUzMDkyXHU0RjVDXHU2MjEwXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzIn0sCi0KLSAgeyBXR19FWFBBTkRfRU5USVRJRVNfTk9UX1NVUFBPUlRFRCwKLSAgICAgICItRVx1MzBBQVx1MzBEN1x1MzBCN1x1MzBFN1x1MzBGM1x1MzA2RkRUTVx1MzBEMVx1MzBGQ1x1MzBCNVx1MzBGQ1x1MzA2N1x1MzA2Rlx1MzBCNVx1MzBERFx1MzBGQ1x1MzBDOFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5MyJ9LAotCi0gIHsgV0dfSUxMRUdBTF9WQVJJQUJMRV9SRUZFUkVOQ0UsCi0gICAgICAiXHU1OTA5XHU2NTcwXHUzMDZCXHU2MzA3XHU1QjlBXHUzMDU3XHUzMDVGVmFyaWFibGVSZWZlcmVuY2VcdTMwNENcdTMwQjNcdTMwRjNcdTMwQzZcdTMwQURcdTMwQjlcdTMwQzhcdTdCQzRcdTU2RjJcdTU5MTZcdTMwNEJcdTVCOUFcdTdGQTlcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDJcdTU0MERcdTUyNEQ9IHswfSJ9LAotCi0gIHsgV0dfVU5TVVBQT1JURURfRU5DT0RJTkcsCi0gICAgICJcdTMwQjVcdTMwRERcdTMwRkNcdTMwQzhcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwNkFcdTMwNDRcdTMwQThcdTMwRjNcdTMwQjNcdTMwRkNcdTMwQzdcdTMwQTNcdTMwRjNcdTMwQjBcdTMwNjdcdTMwNTk6IHswfSJ9LAotCi0KLQotICAvLyBPdGhlciBtaXNjZWxsYW5lb3VzIHRleHQgdXNlZCBpbnNpZGUgdGhlIGNvZGUuLi4KLSAgeyAidWlfbGFuZ3VhZ2UiLCAiamEifSwKLSAgeyAiaGVscF9sYW5ndWFnZSIsICJqYSJ9LAotICB7ICJsYW5ndWFnZSIsICJqYSJ9LAotICB7ICJCQURfQ09ERSIsICJjcmVhdGVNZXNzYWdlXHUzMDZFXHUzMEQxXHUzMEU5XHUzMEUxXHUzMEZDXHUzMEJGXHUzMDRDXHU3QkM0XHU1NkYyXHU1OTE2XHUzMDY3XHUzMDU5In0sCi0gIHsgIkZPUk1BVF9GQUlMRUQiLCAibWVzc2FnZUZvcm1hdFx1MzA2RVx1NTQ3Q1x1NTFGQVx1MzA1N1x1NEUyRFx1MzA2Qlx1NEY4Qlx1NTkxNlx1MzA0Q1x1MzBCOVx1MzBFRFx1MzBGQ1x1MzA1NVx1MzA4Q1x1MzA3RVx1MzA1N1x1MzA1RiJ9LAotICB7ICJ2ZXJzaW9uIiwgIj4+Pj4+Pj4gWGFsYW5cdTMwRDBcdTMwRkNcdTMwQjhcdTMwRTdcdTMwRjMgIn0sCi0gIHsgInZlcnNpb24yIiwgIjw8PDw8PDwifSwKLSAgeyAieWVzIiwgInllcyJ9LAotICB7ICJsaW5lIiwgIlx1ODg0Q1x1NzU2QVx1NTNGNyJ9LAotICB7ICJjb2x1bW4iLCAiXHU1MjE3XHU3NTZBXHU1M0Y3In0sCi0gIHsgInhzbGRvbmUiLCAiWFNMUHJvY2Vzc29yOiBcdTVCOENcdTRFODZcdTMwNTdcdTMwN0VcdTMwNTdcdTMwNUYifSwKLSAgeyAieHBhdGhfb3B0aW9uIiwgInhwYXRoXHUzMEFBXHUzMEQ3XHUzMEI3XHUzMEU3XHUzMEYzOiAifSwKLSAgeyAib3B0aW9uSU4iLCAiICAgWy1pbiBpbnB1dFhNTFVSTF0ifSwKLSAgeyAib3B0aW9uU2VsZWN0IiwgIiAgIFstc2VsZWN0IHhwYXRoIGV4cHJlc3Npb25dIn0sCi0gIHsgIm9wdGlvbk1hdGNoIiwgIiAgIFstbWF0Y2ggbWF0Y2ggcGF0dGVybiAoXHU0RTAwXHU4MUY0XHU4QTNBXHU2NUFEXHU3NTI4KV0ifSwKLSAgeyAib3B0aW9uQW55RXhwciIsICJcdTMwN0VcdTMwNUZcdTMwNkZcdTMwMDF4cGF0aFx1NUYwRlx1MzA0Q1x1OEEzQVx1NjVBRFx1MzBDMFx1MzBGM1x1MzBEN1x1MzA5Mlx1NUI5Rlx1ODg0Q1x1MzA1N1x1MzA3RVx1MzA1OSJ9LAotICB7ICJub1BhcnNlcm1zZzEiLCAiWFNMXHUzMEQ3XHUzMEVEXHUzMEJCXHUzMEI5XHUzMDZGXHU2MjEwXHU1MjlGXHUzMDU3XHUzMDdFXHUzMDVCXHUzMDkzXHUzMDY3XHUzMDU3XHUzMDVGXHUzMDAyIn0sCi0gIHsgIm5vUGFyc2VybXNnMiIsICIqKiBcdTMwRDFcdTMwRkNcdTMwQjVcdTMwRkNcdTMwNENcdTg5OEJcdTMwNjRcdTMwNEJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwNjdcdTMwNTdcdTMwNUYgKioifSwKLSAgeyAibm9QYXJzZXJtc2czIiwgIlx1MzBBRlx1MzBFOVx1MzBCOVx1MzBEMVx1MzBCOVx1MzA5Mlx1NzhCQVx1OEE4RFx1MzA1N1x1MzA2Nlx1MzA0Rlx1MzA2MFx1MzA1NVx1MzA0NFx1MzAwMiJ9LAotICB7ICJub1BhcnNlcm1zZzQiLCAiSUJNXHUzMDZFSmF2YVx1NzUyOFhNTFx1MzBEMVx1MzBGQ1x1MzBCNVx1MzBGQ1x1MzA0Q1x1MzA2QVx1MzA0NFx1NTgzNFx1NTQwOFx1MzAwMVx1NkIyMVx1MzA2RVx1MzBCNVx1MzBBNFx1MzBDOFx1MzA0Qlx1MzA4OVx1MzBDMFx1MzBBNlx1MzBGM1x1MzBFRFx1MzBGQ1x1MzBDOVx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1OSJ9LAotICB7ICJub1BhcnNlcm1zZzUiLCAiSUJNXHUzMDZFQWxwaGFXb3JrczogaHR0cDovL3d3dy5hbHBoYXdvcmtzLmlibS5jb20vZm9ybXVsYS94bWwifSwKLSAgeyAiZ3RvbmUiLCAiPjEiIH0sCi0gIHsgInplcm8iLCAiMCIgfSwKLSAgeyAib25lIiwgIjEiIH0sCi0gIHsgInR3byIgLCAiMiIgfSwKLSAgeyAidGhyZWUiLCAiMyIgfQotCi0gIH07Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgYXNzb2NpYXRpb24gbGlzdC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgYXNzb2NpYXRpb24gbGlzdC4KLSAgICovCi0gIHB1YmxpYyBPYmplY3RbXVtdIGdldENvbnRlbnRzKCkKLSAgewotICAgICAgcmV0dXJuIF9jb250ZW50czsKLSAgfQotCi0KLSAgLy8gPT09PT09PT09PT09PT09PT0gSU5GUkFTVFJVQ1RVUkUgPT09PT09PT09PT09PT09PT09PT09PQotCi0gIC8qKiBGaWVsZCBCQURfQ09ERSAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBCQURfQ09ERSA9ICJCQURfQ09ERSI7Ci0KLSAgLyoqIEZpZWxkIEZPUk1BVF9GQUlMRUQgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRk9STUFUX0ZBSUxFRCA9ICJGT1JNQVRfRkFJTEVEIjsKLQotICAvKiogRmllbGQgRVJST1JfUkVTT1VSQ0VTICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUk9SX1JFU09VUkNFUyA9Ci0gICAgImNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5yZXMuWFBBVEhFcnJvclJlc291cmNlcyI7Ci0KLSAgLyoqIEZpZWxkIEVSUk9SX1NUUklORyAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJPUl9TVFJJTkcgPSAiI2Vycm9yIjsKLQotICAvKiogRmllbGQgRVJST1JfSEVBREVSICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUk9SX0hFQURFUiA9ICJFcnJvcjogIjsKLQotICAvKiogRmllbGQgV0FSTklOR19IRUFERVIgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0FSTklOR19IRUFERVIgPSAiV2FybmluZzogIjsKLQotICAvKiogRmllbGQgWFNMX0hFQURFUiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBYU0xfSEVBREVSID0gIlhTTCAiOwotCi0gIC8qKiBGaWVsZCBYTUxfSEVBREVSICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFhNTF9IRUFERVIgPSAiWE1MICI7Ci0KLSAgLyoqIEZpZWxkIFFVRVJZX0hFQURFUiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBRVUVSWV9IRUFERVIgPSAiUEFUVEVSTiAiOwotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL3Jlcy9YUEFUSEVycm9yUmVzb3VyY2VzX2tvLmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL3Jlcy9YUEFUSEVycm9yUmVzb3VyY2VzX2tvLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDljOGE3ZGYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9yZXMvWFBBVEhFcnJvclJlc291cmNlc19rby5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTM2ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLnJlczsKLQotaW1wb3J0IGphdmEudXRpbC5MaXN0UmVzb3VyY2VCdW5kbGU7Ci0KLS8qKgotICogU2V0IHVwIGVycm9yIG1lc3NhZ2VzLgotICogV2UgYnVpbGQgYSB0d28gZGltZW5zaW9uYWwgYXJyYXkgb2YgbWVzc2FnZSBrZXlzIGFuZAotICogbWVzc2FnZSBzdHJpbmdzLiBJbiBvcmRlciB0byBhZGQgYSBuZXcgbWVzc2FnZSBoZXJlLAotICogeW91IG5lZWQgdG8gZmlyc3QgYWRkIGEgU3RhdGljIHN0cmluZyBjb25zdGFudCBmb3IgdGhlCi0gKiBLZXkgYW5kIHVwZGF0ZSB0aGUgY29udGVudHMgYXJyYXkgd2l0aCBLZXksIFZhbHVlIHBhaXIKLSAgKiBBbHNvIHlvdSBuZWVkIHRvICB1cGRhdGUgdGhlIGNvdW50IG9mIG1lc3NhZ2VzKE1BWF9DT0RFKW9yCi0gKiB0aGUgY291bnQgb2Ygd2FybmluZ3MoTUFYX1dBUk5JTkcpIFsgSW5mb3JtYXRpb24gcHVycG9zZSBvbmx5XQotICogQHhzbC51c2FnZSBhZHZhbmNlZAotICovCi1wdWJsaWMgY2xhc3MgWFBBVEhFcnJvclJlc291cmNlc19rbyBleHRlbmRzIExpc3RSZXNvdXJjZUJ1bmRsZQotewotCi0vKgotICogR2VuZXJhbCBub3RlcyB0byB0cmFuc2xhdG9yczoKLSAqCi0gKiBUaGlzIGZpbGUgY29udGFpbnMgZXJyb3IgYW5kIHdhcm5pbmcgbWVzc2FnZXMgcmVsYXRlZCB0byBYUGF0aCBFcnJvcgotICogSGFuZGxpbmcuCi0gKgotICogIDEpIFhhbGFuIChvciBtb3JlIHByb3Blcmx5LCBYYWxhbi1pbnRlcnByZXRpdmUpIGFuZCBYU0xUQyBhcmUgbmFtZXMgb2YKLSAqICAgICBjb21wb25lbnRzLgotICogICAgIFhTTFQgaXMgYW4gYWNyb255bSBmb3IgIlhNTCBTdHlsZXNoZWV0IExhbmd1YWdlOiBUcmFuc2Zvcm1hdGlvbnMiLgotICogICAgIFhTTFRDIGlzIGFuIGFjcm9ueW0gZm9yIFhTTFQgQ29tcGlsZXIuCi0gKgotICogIDIpIEEgc3R5bGVzaGVldCBpcyBhIGRlc2NyaXB0aW9uIG9mIGhvdyB0byB0cmFuc2Zvcm0gYW4gaW5wdXQgWE1MIGRvY3VtZW50Ci0gKiAgICAgaW50byBhIHJlc3VsdGFudCBYTUwgZG9jdW1lbnQgKG9yIEhUTUwgZG9jdW1lbnQgb3IgdGV4dCkuICBUaGUKLSAqICAgICBzdHlsZXNoZWV0IGl0c2VsZiBpcyBkZXNjcmliZWQgaW4gdGhlIGZvcm0gb2YgYW4gWE1MIGRvY3VtZW50LgotICoKLSAqICAzKSBBIHRlbXBsYXRlIGlzIGEgY29tcG9uZW50IG9mIGEgc3R5bGVzaGVldCB0aGF0IGlzIHVzZWQgdG8gbWF0Y2ggYQotICogICAgIHBhcnRpY3VsYXIgcG9ydGlvbiBvZiBhbiBpbnB1dCBkb2N1bWVudCBhbmQgc3BlY2lmaWVzIHRoZSBmb3JtIG9mIHRoZQotICogICAgIGNvcnJlc3BvbmRpbmcgcG9ydGlvbiBvZiB0aGUgb3V0cHV0IGRvY3VtZW50LgotICoKLSAqICA0KSBBbiBlbGVtZW50IGlzIGEgbWFyay11cCB0YWcgaW4gYW4gWE1MIGRvY3VtZW50OyBhbiBhdHRyaWJ1dGUgaXMgYQotICogICAgIG1vZGlmaWVyIG9uIHRoZSB0YWcuICBGb3IgZXhhbXBsZSwgaW4gPGVsZW0gYXR0cj0ndmFsJyBhdHRyMj0ndmFsMic+Ci0gKiAgICAgImVsZW0iIGlzIGFuIGVsZW1lbnQgbmFtZSwgImF0dHIiIGFuZCAiYXR0cjIiIGFyZSBhdHRyaWJ1dGUgbmFtZXMgd2l0aAotICogICAgIHRoZSB2YWx1ZXMgInZhbCIgYW5kICJ2YWwyIiwgcmVzcGVjdGl2ZWx5LgotICoKLSAqICA1KSBBIG5hbWVzcGFjZSBkZWNsYXJhdGlvbiBpcyBhIHNwZWNpYWwgYXR0cmlidXRlIHRoYXQgaXMgdXNlZCB0byBhc3NvY2lhdGUKLSAqICAgICBhIHByZWZpeCB3aXRoIGEgVVJJICh0aGUgbmFtZXNwYWNlKS4gIFRoZSBtZWFuaW5ncyBvZiBlbGVtZW50IG5hbWVzIGFuZAotICogICAgIGF0dHJpYnV0ZSBuYW1lcyB0aGF0IHVzZSB0aGF0IHByZWZpeCBhcmUgZGVmaW5lZCB3aXRoIHJlc3BlY3QgdG8gdGhhdAotICogICAgIG5hbWVzcGFjZS4KLSAqCi0gKiAgNikgIlRyYW5zbGV0IiBpcyBhbiBpbnZlbnRlZCB0ZXJtIHRoYXQgZGVzY3JpYmVzIHRoZSBjbGFzcyBmaWxlIHRoYXQKLSAqICAgICByZXN1bHRzIGZyb20gY29tcGlsaW5nIGFuIFhNTCBzdHlsZXNoZWV0IGludG8gYSBKYXZhIGNsYXNzLgotICoKLSAqICA3KSBYUGF0aCBpcyBhIHNwZWNpZmljYXRpb24gdGhhdCBkZXNjcmliZXMgYSBub3RhdGlvbiBmb3IgaWRlbnRpZnlpbmcKLSAqICAgICBub2RlcyBpbiBhIHRyZWUtc3RydWN0dXJlZCByZXByZXNlbnRhdGlvbiBvZiBhbiBYTUwgZG9jdW1lbnQuICBBbgotICogICAgIGluc3RhbmNlIG9mIHRoYXQgbm90YXRpb24gaXMgcmVmZXJyZWQgdG8gYXMgYW4gWFBhdGggZXhwcmVzc2lvbi4KLSAqCi0gKiAgOCkgVGhlIGNvbnRleHQgbm9kZSBpcyB0aGUgbm9kZSBpbiB0aGUgZG9jdW1lbnQgd2l0aCByZXNwZWN0IHRvIHdoaWNoIGFuCi0gKiAgICAgWFBhdGggZXhwcmVzc2lvbiBpcyBiZWluZyBldmFsdWF0ZWQuCi0gKgotICogIDkpIEFuIGl0ZXJhdG9yIGlzIGFuIG9iamVjdCB0aGF0IHRyYXZlcnNlcyBub2RlcyBpbiB0aGUgdHJlZSwgb25lIGF0IGEgdGltZS4KLSAqCi0gKiAgMTApIE5DTmFtZSBpcyBhbiBYTUwgdGVybSB1c2VkIHRvIGRlc2NyaWJlIGEgbmFtZSB0aGF0IGRvZXMgbm90IGNvbnRhaW4gYQotICogICAgIGNvbG9uIChhICJuby1jb2xvbiBuYW1lIikuCi0gKgotICogIDExKSBRTmFtZSBpcyBhbiBYTUwgdGVybSBtZWFuaW5nICJxdWFsaWZpZWQgbmFtZSIuCi0gKi8KLQotICAvKgotICAgKiBzdGF0aWMgdmFyaWFibGVzCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJPUjAwMDAgPSAiRVJST1IwMDAwIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ1VSUkVOVF9OT1RfQUxMT1dFRF9JTl9NQVRDSCA9Ci0gICAgICAgICAiRVJfQ1VSUkVOVF9OT1RfQUxMT1dFRF9JTl9NQVRDSCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NVUlJFTlRfVEFLRVNfTk9fQVJHUyA9Ci0gICAgICAgICAiRVJfQ1VSUkVOVF9UQUtFU19OT19BUkdTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRE9DVU1FTlRfUkVQTEFDRUQgPSAiRVJfRE9DVU1FTlRfUkVQTEFDRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT05URVhUX0hBU19OT19PV05FUkRPQyA9Ci0gICAgICAgICAiRVJfQ09OVEVYVF9IQVNfTk9fT1dORVJET0MiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9MT0NBTE5BTUVfSEFTX1RPT19NQU5ZX0FSR1MgPQotICAgICAgICAgIkVSX0xPQ0FMTkFNRV9IQVNfVE9PX01BTllfQVJHUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05BTUVTUEFDRVVSSV9IQVNfVE9PX01BTllfQVJHUyA9Ci0gICAgICAgICAiRVJfTkFNRVNQQUNFVVJJX0hBU19UT09fTUFOWV9BUkdTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9STUFMSVpFU1BBQ0VfSEFTX1RPT19NQU5ZX0FSR1MgPQotICAgICAgICAgIkVSX05PUk1BTElaRVNQQUNFX0hBU19UT09fTUFOWV9BUkdTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTlVNQkVSX0hBU19UT09fTUFOWV9BUkdTID0KLSAgICAgICAgICJFUl9OVU1CRVJfSEFTX1RPT19NQU5ZX0FSR1MiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OQU1FX0hBU19UT09fTUFOWV9BUkdTID0KLSAgICAgICAgICJFUl9OQU1FX0hBU19UT09fTUFOWV9BUkdTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU1RSSU5HX0hBU19UT09fTUFOWV9BUkdTID0KLSAgICAgICAgICJFUl9TVFJJTkdfSEFTX1RPT19NQU5ZX0FSR1MiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TVFJJTkdMRU5HVEhfSEFTX1RPT19NQU5ZX0FSR1MgPQotICAgICAgICAgIkVSX1NUUklOR0xFTkdUSF9IQVNfVE9PX01BTllfQVJHUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1RSQU5TTEFURV9UQUtFU18zX0FSR1MgPQotICAgICAgICAgIkVSX1RSQU5TTEFURV9UQUtFU18zX0FSR1MiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTlBBUlNFREVOVElUWVVSSV9UQUtFU18xX0FSRyA9Ci0gICAgICAgICAiRVJfVU5QQVJTRURFTlRJVFlVUklfVEFLRVNfMV9BUkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OQU1FU1BBQ0VBWElTX05PVF9JTVBMRU1FTlRFRCA9Ci0gICAgICAgICAiRVJfTkFNRVNQQUNFQVhJU19OT1RfSU1QTEVNRU5URUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTktOT1dOX0FYSVMgPSAiRVJfVU5LTk9XTl9BWElTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5LTk9XTl9NQVRDSF9PUEVSQVRJT04gPQotICAgICAgICAgIkVSX1VOS05PV05fTUFUQ0hfT1BFUkFUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5DT1JSRUNUX0FSR19MRU5HVEggPSJFUl9JTkNPUlJFQ1RfQVJHX0xFTkdUSCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfQ09OVkVSVF9UT19OVU1CRVIgPQotICAgICAgICAgIkVSX0NBTlRfQ09OVkVSVF9UT19OVU1CRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX0NPTlZFUlRfWFBBVEhSRVNVTFRUWVBFX1RPX05VTUJFUiA9Ci0gICAgICAgICAgICJFUl9DQU5UX0NPTlZFUlRfWFBBVEhSRVNVTFRUWVBFX1RPX05VTUJFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfQ09OVkVSVF9UT19OT0RFTElTVCA9Ci0gICAgICAgICAiRVJfQ0FOVF9DT05WRVJUX1RPX05PREVMSVNUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9DT05WRVJUX1RPX01VVEFCTEVOT0RFTElTVCA9Ci0gICAgICAgICAiRVJfQ0FOVF9DT05WRVJUX1RPX01VVEFCTEVOT0RFTElTVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfQ09OVkVSVF9UT19UWVBFID0iRVJfQ0FOVF9DT05WRVJUX1RPX1RZUEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FWFBFQ1RFRF9NQVRDSF9QQVRURVJOID0KLSAgICAgICAgICJFUl9FWFBFQ1RFRF9NQVRDSF9QQVRURVJOIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTEROT1RfR0VUX1ZBUl9OQU1FRCA9Ci0gICAgICAgICAiRVJfQ09VTEROT1RfR0VUX1ZBUl9OQU1FRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1VOS05PV05fT1BDT0RFID0gIkVSX1VOS05PV05fT1BDT0RFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhUUkFfSUxMRUdBTF9UT0tFTlMgPSJFUl9FWFRSQV9JTExFR0FMX1RPS0VOUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYUEVDVEVEX0RPVUJMRV9RVU9URSA9Ci0gICAgICAgICAiRVJfRVhQRUNURURfRE9VQkxFX1FVT1RFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhQRUNURURfU0lOR0xFX1FVT1RFID0KLSAgICAgICAgICJFUl9FWFBFQ1RFRF9TSU5HTEVfUVVPVEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FTVBUWV9FWFBSRVNTSU9OID0gIkVSX0VNUFRZX0VYUFJFU1NJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FWFBFQ1RFRF9CVVRfRk9VTkQgPSAiRVJfRVhQRUNURURfQlVUX0ZPVU5EIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5DT1JSRUNUX1BST0dSQU1NRVJfQVNTRVJUSU9OID0KLSAgICAgICAgICJFUl9JTkNPUlJFQ1RfUFJPR1JBTU1FUl9BU1NFUlRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9CT09MRUFOX0FSR19OT19MT05HRVJfT1BUSU9OQUwgPQotICAgICAgICAgIkVSX0JPT0xFQU5fQVJHX05PX0xPTkdFUl9PUFRJT05BTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZPVU5EX0NPTU1BX0JVVF9OT19QUkVDRURJTkdfQVJHID0KLSAgICAgICAgICJFUl9GT1VORF9DT01NQV9CVVRfTk9fUFJFQ0VESU5HX0FSRyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZPVU5EX0NPTU1BX0JVVF9OT19GT0xMT1dJTkdfQVJHID0KLSAgICAgICAgICJFUl9GT1VORF9DT01NQV9CVVRfTk9fRk9MTE9XSU5HX0FSRyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BSRURJQ0FURV9JTExFR0FMX1NZTlRBWCA9Ci0gICAgICAgICAiRVJfUFJFRElDQVRFX0lMTEVHQUxfU1lOVEFYIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSUxMRUdBTF9BWElTX05BTUUgPSAiRVJfSUxMRUdBTF9BWElTX05BTUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTktOT1dOX05PREVUWVBFID0gIkVSX1VOS05PV05fTk9ERVRZUEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QQVRURVJOX0xJVEVSQUxfTkVFRFNfQkVfUVVPVEVEID0KLSAgICAgICAgICJFUl9QQVRURVJOX0xJVEVSQUxfTkVFRFNfQkVfUVVPVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTEROT1RfQkVfRk9STUFUVEVEX1RPX05VTUJFUiA9Ci0gICAgICAgICAiRVJfQ09VTEROT1RfQkVfRk9STUFUVEVEX1RPX05VTUJFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxETk9UX0NSRUFURV9YTUxQUk9DRVNTT1JMSUFJU09OID0KLSAgICAgICAgICJFUl9DT1VMRE5PVF9DUkVBVEVfWE1MUFJPQ0VTU09STElBSVNPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0RJRE5PVF9GSU5EX1hQQVRIX1NFTEVDVF9FWFAgPQotICAgICAgICAgIkVSX0RJRE5PVF9GSU5EX1hQQVRIX1NFTEVDVF9FWFAiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRE5PVF9GSU5EX0VORE9QX0FGVEVSX09QTE9DQVRJT05QQVRIID0KLSAgICAgICAgICJFUl9DT1VMRE5PVF9GSU5EX0VORE9QX0FGVEVSX09QTE9DQVRJT05QQVRIIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVJST1JfT0NDVVJFRCA9ICJFUl9FUlJPUl9PQ0NVUkVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSUxMRUdBTF9WQVJJQUJMRV9SRUZFUkVOQ0UgPQotICAgICAgICAgIkVSX0lMTEVHQUxfVkFSSUFCTEVfUkVGRVJFTkNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQVhFU19OT1RfQUxMT1dFRCA9ICJFUl9BWEVTX05PVF9BTExPV0VEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfS0VZX0hBU19UT09fTUFOWV9BUkdTID0KLSAgICAgICAgICJFUl9LRVlfSEFTX1RPT19NQU5ZX0FSR1MiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VOVF9UQUtFU18xX0FSRyA9ICJFUl9DT1VOVF9UQUtFU18xX0FSRyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxETk9UX0ZJTkRfRlVOQ1RJT04gPQotICAgICAgICAgIkVSX0NPVUxETk9UX0ZJTkRfRlVOQ1RJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTlNVUFBPUlRFRF9FTkNPRElORyA9IkVSX1VOU1VQUE9SVEVEX0VOQ09ESU5HIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJPQkxFTV9JTl9EVE1fTkVYVFNJQkxJTkcgPQotICAgICAgICAgIkVSX1BST0JMRU1fSU5fRFRNX05FWFRTSUJMSU5HIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX1dSSVRFX1RPX0VNUFRZTk9ERUxJU1RJTVBMID0KLSAgICAgICAgICJFUl9DQU5OT1RfV1JJVEVfVE9fRU1QVFlOT0RFTElTVElNUEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TRVRET01GQUNUT1JZX05PVF9TVVBQT1JURUQgPQotICAgICAgICAgIkVSX1NFVERPTUZBQ1RPUllfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BSRUZJWF9NVVNUX1JFU09MVkUgPSAiRVJfUFJFRklYX01VU1RfUkVTT0xWRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BBUlNFX05PVF9TVVBQT1JURUQgPSAiRVJfUEFSU0VfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NBWF9BUElfTk9UX0hBTkRMRUQgPSAiRVJfU0FYX0FQSV9OT1RfSEFORExFRCI7Ci1wdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JR05PUkFCTEVfV0hJVEVTUEFDRV9OT1RfSEFORExFRCA9Ci0gICAgICAgICAiRVJfSUdOT1JBQkxFX1dISVRFU1BBQ0VfTk9UX0hBTkRMRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9EVE1fQ0FOTk9UX0hBTkRMRV9OT0RFUyA9Ci0gICAgICAgICAiRVJfRFRNX0NBTk5PVF9IQU5ETEVfTk9ERVMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YRVJDRVNfQ0FOTk9UX0hBTkRMRV9OT0RFUyA9Ci0gICAgICAgICAiRVJfWEVSQ0VTX0NBTk5PVF9IQU5ETEVfTk9ERVMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YRVJDRVNfUEFSU0VfRVJST1JfREVUQUlMUyA9Ci0gICAgICAgICAiRVJfWEVSQ0VTX1BBUlNFX0VSUk9SX0RFVEFJTFMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YRVJDRVNfUEFSU0VfRVJST1IgPSAiRVJfWEVSQ0VTX1BBUlNFX0VSUk9SIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9VVEYxNl9TVVJST0dBVEUgPQotICAgICAgICAgIkVSX0lOVkFMSURfVVRGMTZfU1VSUk9HQVRFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfT0lFUlJPUiA9ICJFUl9PSUVSUk9SIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX0NSRUFURV9VUkwgPSAiRVJfQ0FOTk9UX0NSRUFURV9VUkwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YUEFUSF9SRUFET0JKRUNUID0gIkVSX1hQQVRIX1JFQURPQkpFQ1QiOwotIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZVTkNUSU9OX1RPS0VOX05PVF9GT1VORCA9Ci0gICAgICAgICAiRVJfRlVOQ1RJT05fVE9LRU5fTk9UX0ZPVU5EIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX0RFQUxfWFBBVEhfVFlQRSA9Ci0gICAgICAgICAiRVJfQ0FOTk9UX0RFQUxfWFBBVEhfVFlQRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PREVTRVRfTk9UX01VVEFCTEUgPSAiRVJfTk9ERVNFVF9OT1RfTVVUQUJMRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PREVTRVREVE1fTk9UX01VVEFCTEUgPQotICAgICAgICAgIkVSX05PREVTRVREVE1fTk9UX01VVEFCTEUiOwotICAgLyoqICBWYXJpYWJsZSBub3QgcmVzb2x2YWJsZTogICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9WQVJfTk9UX1JFU09MVkFCTEUgPSAiRVJfVkFSX05PVF9SRVNPTFZBQkxFIjsKLSAgIC8qKiBOdWxsIGVycm9yIGhhbmRsZXIgICovCi0gcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTlVMTF9FUlJPUl9IQU5ETEVSID0gIkVSX05VTExfRVJST1JfSEFORExFUiI7Ci0gICAvKiogIFByb2dyYW1tZXIncyBhc3NlcnRpb246IHVua25vd24gb3Bjb2RlICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUk9HX0FTU0VSVF9VTktOT1dOX09QQ09ERSA9Ci0gICAgICAgICAiRVJfUFJPR19BU1NFUlRfVU5LTk9XTl9PUENPREUiOwotICAgLyoqICAwIG9yIDEgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9aRVJPX09SX09ORSA9ICJFUl9aRVJPX09SX09ORSI7Ci0gICAvKiogIHJ0ZigpIG5vdCBzdXBwb3J0ZWQgYnkgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SVEZfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiA9Ci0gICAgICAgICAiRVJfUlRGX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIiOwotICAgLyoqICBhc05vZGVJdGVyYXRvcigpIG5vdCBzdXBwb3J0ZWQgYnkgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9BU05PREVJVEVSQVRPUl9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSID0gIkVSX0FTTk9ERUlURVJBVE9SX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIiOwotICAgLyoqICBmc2IoKSBub3Qgc3VwcG9ydGVkIGZvciBYU3RyaW5nRm9yQ2hhcnMgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GU0JfTk9UX1NVUFBPUlRFRF9YU1RSSU5HRk9SQ0hBUlMgPQotICAgICAgICAgIkVSX0ZTQl9OT1RfU1VQUE9SVEVEX1hTVFJJTkdGT1JDSEFSUyI7Ci0gICAvKiogIENvdWxkIG5vdCBmaW5kIHZhcmlhYmxlIHdpdGggdGhlIG5hbWUgb2YgICAqLwotIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxEX05PVF9GSU5EX1ZBUiA9ICJFUl9DT1VMRF9OT1RfRklORF9WQVIiOwotICAgLyoqICBYU3RyaW5nRm9yQ2hhcnMgY2FuIG5vdCB0YWtlIGEgc3RyaW5nIGZvciBhbiBhcmd1bWVudCAgICovCi0gcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWFNUUklOR0ZPUkNIQVJTX0NBTk5PVF9UQUtFX1NUUklORyA9Ci0gICAgICAgICAiRVJfWFNUUklOR0ZPUkNIQVJTX0NBTk5PVF9UQUtFX1NUUklORyI7Ci0gICAvKiogIFRoZSBGYXN0U3RyaW5nQnVmZmVyIGFyZ3VtZW50IGNhbiBub3QgYmUgbnVsbCAgICovCi0gcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRkFTVFNUUklOR0JVRkZFUl9DQU5OT1RfQkVfTlVMTCA9Ci0gICAgICAgICAiRVJfRkFTVFNUUklOR0JVRkZFUl9DQU5OT1RfQkVfTlVMTCI7Ci0gICAvKiogIDIgb3IgMyAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1RXT19PUl9USFJFRSA9ICJFUl9UV09fT1JfVEhSRUUiOwotICAgLyoqIFZhcmlhYmxlIGFjY2Vzc2VkIGJlZm9yZSBpdCBpcyBib3VuZCEgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVkFSSUFCTEVfQUNDRVNTRURfQkVGT1JFX0JJTkQgPQotICAgICAgICAgIkVSX1ZBUklBQkxFX0FDQ0VTU0VEX0JFRk9SRV9CSU5EIjsKLSAgIC8qKiBYU3RyaW5nRm9yRlNCIGNhbiBub3QgdGFrZSBhIHN0cmluZyBmb3IgYW4gYXJndW1lbnQhICovCi0gcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRlNCX0NBTk5PVF9UQUtFX1NUUklORyA9Ci0gICAgICAgICAiRVJfRlNCX0NBTk5PVF9UQUtFX1NUUklORyI7Ci0gICAvKiogRXJyb3IhIFNldHRpbmcgdGhlIHJvb3Qgb2YgYSB3YWxrZXIgdG8gbnVsbCEgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU0VUVElOR19XQUxLRVJfUk9PVF9UT19OVUxMID0KLSAgICAgICAgICJFUl9TRVRUSU5HX1dBTEtFUl9ST09UX1RPX05VTEwiOwotICAgLyoqIFRoaXMgTm9kZVNldERUTSBjYW4gbm90IGl0ZXJhdGUgdG8gYSBwcmV2aW91cyBub2RlISAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT0RFU0VURFRNX0NBTk5PVF9JVEVSQVRFID0KLSAgICAgICAgICJFUl9OT0RFU0VURFRNX0NBTk5PVF9JVEVSQVRFIjsKLSAgLyoqIFRoaXMgTm9kZVNldCBjYW4gbm90IGl0ZXJhdGUgdG8gYSBwcmV2aW91cyBub2RlISAqLwotIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PREVTRVRfQ0FOTk9UX0lURVJBVEUgPQotICAgICAgICAgIkVSX05PREVTRVRfQ0FOTk9UX0lURVJBVEUiOwotICAvKiogVGhpcyBOb2RlU2V0RFRNIGNhbiBub3QgZG8gaW5kZXhpbmcgb3IgY291bnRpbmcgZnVuY3Rpb25zISAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT0RFU0VURFRNX0NBTk5PVF9JTkRFWCA9Ci0gICAgICAgICAiRVJfTk9ERVNFVERUTV9DQU5OT1RfSU5ERVgiOwotICAvKiogVGhpcyBOb2RlU2V0IGNhbiBub3QgZG8gaW5kZXhpbmcgb3IgY291bnRpbmcgZnVuY3Rpb25zISAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT0RFU0VUX0NBTk5PVF9JTkRFWCA9Ci0gICAgICAgICAiRVJfTk9ERVNFVF9DQU5OT1RfSU5ERVgiOwotICAvKiogQ2FuIG5vdCBjYWxsIHNldFNob3VsZENhY2hlTm9kZXMgYWZ0ZXIgbmV4dE5vZGUgaGFzIGJlZW4gY2FsbGVkISAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfQ0FMTF9TRVRTSE9VTERDQUNIRU5PREUgPQotICAgICAgICAgIkVSX0NBTk5PVF9DQUxMX1NFVFNIT1VMRENBQ0hFTk9ERSI7Ci0gIC8qKiB7MH0gb25seSBhbGxvd3MgezF9IGFyZ3VtZW50cyAqLwotIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX09OTFlfQUxMT1dTID0gIkVSX09OTFlfQUxMT1dTIjsKLSAgLyoqIFByb2dyYW1tZXIncyBhc3NlcnRpb24gaW4gZ2V0TmV4dFN0ZXBQb3M6IHVua25vd24gc3RlcFR5cGU6IHswfSAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTktOT1dOX1NURVAgPSAiRVJfVU5LTk9XTl9TVEVQIjsKLSAgLyoqIFByb2JsZW0gd2l0aCBSZWxhdGl2ZUxvY2F0aW9uUGF0aCAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FWFBFQ1RFRF9SRUxfTE9DX1BBVEggPQotICAgICAgICAgIkVSX0VYUEVDVEVEX1JFTF9MT0NfUEFUSCI7Ci0gIC8qKiBQcm9ibGVtIHdpdGggTG9jYXRpb25QYXRoICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYUEVDVEVEX0xPQ19QQVRIID0gIkVSX0VYUEVDVEVEX0xPQ19QQVRIIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhQRUNURURfTE9DX1BBVEhfQVRfRU5EX0VYUFIgPQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJFUl9FWFBFQ1RFRF9MT0NfUEFUSF9BVF9FTkRfRVhQUiI7Ci0gIC8qKiBQcm9ibGVtIHdpdGggU3RlcCAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FWFBFQ1RFRF9MT0NfU1RFUCA9ICJFUl9FWFBFQ1RFRF9MT0NfU1RFUCI7Ci0gIC8qKiBQcm9ibGVtIHdpdGggTm9kZVRlc3QgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhQRUNURURfTk9ERV9URVNUID0gIkVSX0VYUEVDVEVEX05PREVfVEVTVCI7Ci0gIC8qKiBFeHBlY3RlZCBzdGVwIHBhdHRlcm4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhQRUNURURfU1RFUF9QQVRURVJOID0KLSAgICAgICAgIkVSX0VYUEVDVEVEX1NURVBfUEFUVEVSTiI7Ci0gIC8qKiBFeHBlY3RlZCByZWxhdGl2ZSBwYXRoIHBhdHRlcm4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhQRUNURURfUkVMX1BBVEhfUEFUVEVSTiA9Ci0gICAgICAgICAiRVJfRVhQRUNURURfUkVMX1BBVEhfUEFUVEVSTiI7Ci0gIC8qKiBFUl9DQU5UX0NPTlZFUlRfWFBBVEhSRVNVTFRUWVBFX1RPX0JPT0xFQU4gICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9DT05WRVJUX1RPX0JPT0xFQU4gPQotICAgICAgICAgIkVSX0NBTlRfQ09OVkVSVF9UT19CT09MRUFOIjsKLSAgLyoqIEZpZWxkIEVSX0NBTlRfQ09OVkVSVF9UT19TSU5HTEVOT0RFICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfQ09OVkVSVF9UT19TSU5HTEVOT0RFID0KLSAgICAgICAgICJFUl9DQU5UX0NPTlZFUlRfVE9fU0lOR0xFTk9ERSI7Ci0gIC8qKiBGaWVsZCBFUl9DQU5UX0dFVF9TTkFQU0hPVF9MRU5HVEggICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX0dFVF9TTkFQU0hPVF9MRU5HVEggPQotICAgICAgICAgIkVSX0NBTlRfR0VUX1NOQVBTSE9UX0xFTkdUSCI7Ci0gIC8qKiBGaWVsZCBFUl9OT05fSVRFUkFUT1JfVFlQRSAgICAgICAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT05fSVRFUkFUT1JfVFlQRSA9ICJFUl9OT05fSVRFUkFUT1JfVFlQRSI7Ci0gIC8qKiBGaWVsZCBFUl9ET0NfTVVUQVRFRCAgICAgICAgICAgICAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9ET0NfTVVUQVRFRCA9ICJFUl9ET0NfTVVUQVRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfWFBBVEhfVFlQRSA9ICJFUl9JTlZBTElEX1hQQVRIX1RZUEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FTVBUWV9YUEFUSF9SRVNVTFQgPSAiRVJfRU1QVFlfWFBBVEhfUkVTVUxUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5DT01QQVRJQkxFX1RZUEVTID0gIkVSX0lOQ09NUEFUSUJMRV9UWVBFUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05VTExfUkVTT0xWRVIgPSAiRVJfTlVMTF9SRVNPTFZFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfQ09OVkVSVF9UT19TVFJJTkcgPQotICAgICAgICAgIkVSX0NBTlRfQ09OVkVSVF9UT19TVFJJTkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT05fU05BUFNIT1RfVFlQRSA9ICJFUl9OT05fU05BUFNIT1RfVFlQRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1dST05HX0RPQ1VNRU5UID0gIkVSX1dST05HX0RPQ1VNRU5UIjsKLSAgLyogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBYUGF0aCBleHByZXNzaW9uIGNhbm5vdCBiZSBldmFsdWF0ZWQgd2l0aCByZXNwZWN0Ci0gICAqIHRvIHRoaXMgdHlwZSBvZiBub2RlLgotICAgKi8KLSAgLyoqIEZpZWxkIEVSX1dST05HX05PREVUWVBFICAgICAgICAgICAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9XUk9OR19OT0RFVFlQRSA9ICJFUl9XUk9OR19OT0RFVFlQRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hQQVRIX0VSUk9SID0gIkVSX1hQQVRIX0VSUk9SIjsKLQotICAvL0JFR0lOOiBLZXlzIG5lZWRlZCBmb3IgZXhjZXB0aW9uIG1lc3NhZ2VzIG9mICBKQVhQIDEuMyBYUGF0aCBBUEkgaW1wbGVtZW50YXRpb24KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhURU5TSU9OX0ZVTkNUSU9OX0NBTk5PVF9CRV9JTlZPS0VEID0gIkVSX0VYVEVOU0lPTl9GVU5DVElPTl9DQU5OT1RfQkVfSU5WT0tFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1JFU09MVkVfVkFSSUFCTEVfUkVUVVJOU19OVUxMID0gIkVSX1JFU09MVkVfVkFSSUFCTEVfUkVUVVJOU19OVUxMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5TVVBQT1JURURfUkVUVVJOX1RZUEUgPSAiRVJfVU5TVVBQT1JURURfUkVUVVJOX1RZUEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TT1VSQ0VfUkVUVVJOX1RZUEVfQ0FOTk9UX0JFX05VTEwgPSAiRVJfU09VUkNFX1JFVFVSTl9UWVBFX0NBTk5PVF9CRV9OVUxMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQVJHX0NBTk5PVF9CRV9OVUxMID0gIkVSX0FSR19DQU5OT1RfQkVfTlVMTCI7Ci0KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfT0JKRUNUX01PREVMX05VTEwgPSAiRVJfT0JKRUNUX01PREVMX05VTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9PQkpFQ1RfTU9ERUxfRU1QVFkgPSAiRVJfT0JKRUNUX01PREVMX0VNUFRZIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRkVBVFVSRV9OQU1FX05VTEwgPSAiRVJfRkVBVFVSRV9OQU1FX05VTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GRUFUVVJFX1VOS05PV04gPSAiRVJfRkVBVFVSRV9VTktOT1dOIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfR0VUVElOR19OVUxMX0ZFQVRVUkUgPSAiRVJfR0VUVElOR19OVUxMX0ZFQVRVUkUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9HRVRUSU5HX1VOS05PV05fRkVBVFVSRSA9ICJFUl9HRVRUSU5HX1VOS05PV05fRkVBVFVSRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NFQ1VSRVBST0NFU1NJTkdfRkVBVFVSRSA9ICJFUl9TRUNVUkVQUk9DRVNTSU5HX0ZFQVRVUkUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OVUxMX1hQQVRIX0ZVTkNUSU9OX1JFU09MVkVSID0gIkVSX05VTExfWFBBVEhfRlVOQ1RJT05fUkVTT0xWRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OVUxMX1hQQVRIX1ZBUklBQkxFX1JFU09MVkVSID0gIkVSX05VTExfWFBBVEhfVkFSSUFCTEVfUkVTT0xWRVIiOwotICAvL0VORDogS2V5cyBuZWVkZWQgZm9yIGV4Y2VwdGlvbiBtZXNzYWdlcyBvZiAgSkFYUCAxLjMgWFBhdGggQVBJIGltcGxlbWVudGF0aW9uCi0KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfTE9DQUxFX05BTUVfTk9UX0hBTkRMRUQgPQotICAgICAgICAgIldHX0xPQ0FMRV9OQU1FX05PVF9IQU5ETEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfUFJPUEVSVFlfTk9UX1NVUFBPUlRFRCA9Ci0gICAgICAgICAiV0dfUFJPUEVSVFlfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0RPTlRfRE9fQU5ZVEhJTkdfV0lUSF9OUyA9Ci0gICAgICAgICAiV0dfRE9OVF9ET19BTllUSElOR19XSVRIX05TIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfU0VDVVJJVFlfRVhDRVBUSU9OID0gIldHX1NFQ1VSSVRZX0VYQ0VQVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX1FVT19OT19MT05HRVJfREVGSU5FRCA9Ci0gICAgICAgICAiV0dfUVVPX05PX0xPTkdFUl9ERUZJTkVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfTkVFRF9ERVJJVkVEX09CSkVDVF9UT19JTVBMRU1FTlRfTk9ERVRFU1QgPQotICAgICAgICAgIldHX05FRURfREVSSVZFRF9PQkpFQ1RfVE9fSU1QTEVNRU5UX05PREVURVNUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfRlVOQ1RJT05fVE9LRU5fTk9UX0ZPVU5EID0KLSAgICAgICAgICJXR19GVU5DVElPTl9UT0tFTl9OT1RfRk9VTkQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19DT1VMRE5PVF9GSU5EX0ZVTkNUSU9OID0KLSAgICAgICAgICJXR19DT1VMRE5PVF9GSU5EX0ZVTkNUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfQ0FOTk9UX01BS0VfVVJMX0ZST00gPSJXR19DQU5OT1RfTUFLRV9VUkxfRlJPTSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0VYUEFORF9FTlRJVElFU19OT1RfU1VQUE9SVEVEID0KLSAgICAgICAgICJXR19FWFBBTkRfRU5USVRJRVNfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0lMTEVHQUxfVkFSSUFCTEVfUkVGRVJFTkNFID0KLSAgICAgICAgICJXR19JTExFR0FMX1ZBUklBQkxFX1JFRkVSRU5DRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX1VOU1VQUE9SVEVEX0VOQ09ESU5HID0iV0dfVU5TVVBQT1JURURfRU5DT0RJTkciOwotCi0gIC8qKiAgZGV0YWNoKCkgbm90IHN1cHBvcnRlZCBieSBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0RFVEFDSF9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSID0KLSAgICAgICAgICJFUl9ERVRBQ0hfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiI7Ci0gIC8qKiAgbnVtKCkgbm90IHN1cHBvcnRlZCBieSBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05VTV9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSID0KLSAgICAgICAgICJFUl9OVU1fTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiI7Ci0gIC8qKiAgeHN0cigpIG5vdCBzdXBwb3J0ZWQgYnkgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YU1RSX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIgPQotICAgICAgICAgIkVSX1hTVFJfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiI7Ci0gIC8qKiAgc3RyKCkgbm90IHN1cHBvcnRlZCBieSBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NUUl9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSID0KLSAgICAgICAgICJFUl9TVFJfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiI7Ci0KLSAgLy8gRXJyb3IgbWVzc2FnZXMuLi4KLQotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBPYmplY3RbXVtdIF9jb250ZW50cyA9IG5ldyBPYmplY3RbXVtdewotCi0gIHsgIkVSUk9SMDAwMCIgLCAiezB9IiB9LAotCi0gIHsgRVJfQ1VSUkVOVF9OT1RfQUxMT1dFRF9JTl9NQVRDSCwgIlx1Qzc3Q1x1Q0U1OCBcdUQzMjhcdUQxMzRcdUM1RDBcdUMxMUNcdUIyOTQgY3VycmVudCgpIFx1RDU2OFx1QzIxOFx1QUMwMCBcdUQ1QzhcdUM2QTlcdUI0MThcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0ISIgfSwKLQotICB7IEVSX0NVUlJFTlRfVEFLRVNfTk9fQVJHUywgImN1cnJlbnQoKSBcdUQ1NjhcdUMyMThcdUM1RDBcdUIyOTQgXHVDNzc4XHVDMjE4XHVCOTdDIFx1QzBBQ1x1QzZBOVx1RDU2MCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0ISIgfSwKLQotICB7IEVSX0RPQ1VNRU5UX1JFUExBQ0VELAotICAgICAgImRvY3VtZW50KCkgXHVENTY4XHVDMjE4IFx1QUQ2Q1x1RDYwNFx1Qzc3NCBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdC5GdW5jRG9jdW1lbnRcdUI4NUMgXHVCMzAwXHVDQ0I0XHVCNDE4XHVDNUM4XHVDMkI1XHVCMkM4XHVCMkU0ISJ9LAotCi0gIHsgRVJfQ09OVEVYVF9IQVNfTk9fT1dORVJET0MsCi0gICAgICAiXHVDRUU4XHVEMTREXHVDMkE0XHVEMkI4XHVDNUQwIFx1QzE4Q1x1QzcyMFx1Qzc5MCBcdUJCMzhcdUMxMUNcdUFDMDAgXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0ISJ9LAotCi0gIHsgRVJfTE9DQUxOQU1FX0hBU19UT09fTUFOWV9BUkdTLAotICAgICAgImxvY2FsLW5hbWUoKVx1QzVEMCBcdUM3NzhcdUMyMThcdUFDMDAgXHVCMTA4XHVCQjM0IFx1QjlDRVx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICB7IEVSX05BTUVTUEFDRVVSSV9IQVNfVE9PX01BTllfQVJHUywKLSAgICAgICJuYW1lc3BhY2UtdXJpKClcdUM1RDAgXHVDNzc4XHVDMjE4XHVBQzAwIFx1QjEwOFx1QkIzNCBcdUI5Q0VcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgeyBFUl9OT1JNQUxJWkVTUEFDRV9IQVNfVE9PX01BTllfQVJHUywKLSAgICAgICJub3JtYWxpemUtc3BhY2UoKVx1QzVEMCBcdUM3NzhcdUMyMThcdUFDMDAgXHVCMTA4XHVCQjM0IFx1QjlDRVx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICB7IEVSX05VTUJFUl9IQVNfVE9PX01BTllfQVJHUywKLSAgICAgICJudW1iZXIoKVx1QzVEMCBcdUM3NzhcdUMyMThcdUFDMDAgXHVCMTA4XHVCQjM0IFx1QjlDRVx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICB7IEVSX05BTUVfSEFTX1RPT19NQU5ZX0FSR1MsCi0gICAgICJuYW1lKClcdUM1RDAgXHVDNzc4XHVDMjE4XHVBQzAwIFx1QjEwOFx1QkIzNCBcdUI5Q0VcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgeyBFUl9TVFJJTkdfSEFTX1RPT19NQU5ZX0FSR1MsCi0gICAgICAic3RyaW5nKClcdUM1RDAgXHVDNzc4XHVDMjE4XHVBQzAwIFx1QjEwOFx1QkIzNCBcdUI5Q0VcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgeyBFUl9TVFJJTkdMRU5HVEhfSEFTX1RPT19NQU5ZX0FSR1MsCi0gICAgICAic3RyaW5nLWxlbmd0aCgpXHVDNUQwIFx1Qzc3OFx1QzIxOFx1QUMwMCBcdUIxMDhcdUJCMzQgXHVCOUNFXHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gIHsgRVJfVFJBTlNMQVRFX1RBS0VTXzNfQVJHUywKLSAgICAgICJ0cmFuc2xhdGUoKSBcdUQ1NjhcdUMyMThcdUM1RDAgXHVDMTM4IFx1QUMxQ1x1Qzc1OCBcdUM3NzhcdUMyMThcdUFDMDAgXHVDMEFDXHVDNkE5XHVCNDI5XHVCMkM4XHVCMkU0ISJ9LAotCi0gIHsgRVJfVU5QQVJTRURFTlRJVFlVUklfVEFLRVNfMV9BUkcsCi0gICAgICAidW5wYXJzZWQtZW50aXR5LXVyaSBcdUQ1NjhcdUMyMThcdUM1RDBcdUIyOTQgXHVENTVDIFx1QUMxQ1x1Qzc1OCBcdUM3NzhcdUMyMThcdUFDMDAgXHVDMEFDXHVDNkE5XHVCNDE4XHVDNUI0XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNCEifSwKLQotICB7IEVSX05BTUVTUEFDRUFYSVNfTk9UX0lNUExFTUVOVEVELAotICAgICAgIlx1QjEyNFx1Qzc4NFx1QzJBNFx1RDM5OFx1Qzc3NFx1QzJBNCBcdUNEOTVcdUM3NzQgXHVDNTQ0XHVDOUMxIFx1QUQ2Q1x1RDYwNFx1QjQxOFx1QzlDMCBcdUM1NEFcdUM1NThcdUMyQjVcdUIyQzhcdUIyRTQhIn0sCi0KLSAgeyBFUl9VTktOT1dOX0FYSVMsCi0gICAgICJcdUM1NEMgXHVDMjE4IFx1QzVDNlx1QjI5NCBcdUNEOTU6IHswfSJ9LAotCi0gIHsgRVJfVU5LTk9XTl9NQVRDSF9PUEVSQVRJT04sCi0gICAgICJcdUM1NEMgXHVDMjE4IFx1QzVDNlx1QjI5NCBcdUM3N0NcdUNFNTggXHVDNzkxXHVDNUM1XHVDNzg1XHVCMkM4XHVCMkU0ISJ9LAotCi0gIHsgRVJfSU5DT1JSRUNUX0FSR19MRU5HVEgsCi0gICAgICAicHJvY2Vzc2luZy1pbnN0cnVjdGlvbigpIFx1QjE3OFx1QjREQyBcdUQxNENcdUMyQTRcdUQyQjhcdUM3NTggXHVDNzc4XHVDMjE4IFx1QUUzOFx1Qzc3NFx1QUMwMCBcdUM2MkNcdUJDMTRcdUI5NzRcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0ISJ9LAotCi0gIHsgRVJfQ0FOVF9DT05WRVJUX1RPX05VTUJFUiwKLSAgICAgICJ7MH1cdUM3NDQoXHVCOTdDKSBcdUMyMkJcdUM3OTBcdUI4NUMgXHVCQ0MwXHVENjU4XHVENTYwIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgeyBFUl9DQU5UX0NPTlZFUlRfVE9fTk9ERUxJU1QsCi0gICAgICAiezB9XHVDNzQ0KFx1Qjk3QykgTm9kZUxpc3RcdUI4NUMgXHVCQ0MwXHVENjU4XHVENTYwIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQhIn0sCi0KLSAgeyBFUl9DQU5UX0NPTlZFUlRfVE9fTVVUQUJMRU5PREVMSVNULAotICAgICAgInswfVx1Qzc0NChcdUI5N0MpIE5vZGVTZXREVE1cdUM3M0NcdUI4NUMgXHVCQ0MwXHVENjU4XHVENTYwIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQhIn0sCi0KLSAgeyBFUl9DQU5UX0NPTlZFUlRfVE9fVFlQRSwKLSAgICAgICJ7MH1cdUM3NDQoXHVCOTdDKSB0eXBlI3sxfShcdUM3M0MpXHVCODVDIFx1QkNDMFx1RDY1OFx1RDU2MCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gIHsgRVJfRVhQRUNURURfTUFUQ0hfUEFUVEVSTiwKLSAgICAgICJnZXRNYXRjaFNjb3JlXHVDNUQwIFx1Qzc3Q1x1Q0U1OCBcdUQzMjhcdUQxMzRcdUM3NzQgXHVENTQ0XHVDNjk0XHVENTY5XHVCMkM4XHVCMkU0ISJ9LAotCi0gIHsgRVJfQ09VTEROT1RfR0VUX1ZBUl9OQU1FRCwKLSAgICAgICJcdUM3NzRcdUI5ODRcdUM3NzQgezB9XHVDNzc4IFx1QkNDMFx1QzIxOFx1Qjk3QyBcdUFDMDBcdUM4MzhcdUM2MkMgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICB7IEVSX1VOS05PV05fT1BDT0RFLAotICAgICAiXHVDNjI0XHVCOTU4ISBcdUM1NEMgXHVDMjE4IFx1QzVDNlx1QjI5NCBcdUM3OTFcdUM1QzUgXHVDRjU0XHVCNERDOiB7MH0ifSwKLQotICB7IEVSX0VYVFJBX0lMTEVHQUxfVE9LRU5TLAotICAgICAiXHVDNzk4XHVCQUJCXHVCNDFDIFx1Q0Q5NFx1QUMwMCBcdUQxQTBcdUQwNzA6IHswfSJ9LAotCi0gIHsgRVJfRVhQRUNURURfRE9VQkxFX1FVT1RFLAotICAgICAgIlx1QjlBQ1x1RDEzMFx1QjdGNFx1Qzc1OCBcdUI1MzBcdUM2MzRcdUQ0NUNcdUFDMDAgXHVDNzk4XHVCQUJCIFx1QzlDMFx1QzgxNVx1QjQxOFx1QzVDOFx1QzJCNVx1QjJDOFx1QjJFNC4gXHVEMDcwIFx1QjUzMFx1QzYzNFx1RDQ1Q1x1QUMwMCBcdUQ1NDRcdUM2OTRcdUQ1NjlcdUIyQzhcdUIyRTQhIn0sCi0KLSAgeyBFUl9FWFBFQ1RFRF9TSU5HTEVfUVVPVEUsCi0gICAgICAiXHVCOUFDXHVEMTMwXHVCN0Y0XHVDNzU4IFx1QjUzMFx1QzYzNFx1RDQ1Q1x1QUMwMCBcdUM3OThcdUJBQkIgXHVDOUMwXHVDODE1XHVCNDE4XHVDNUM4XHVDMkI1XHVCMkM4XHVCMkU0LiBcdUM3OTFcdUM3NDAgXHVCNTMwXHVDNjM0XHVENDVDXHVBQzAwIFx1RDU0NFx1QzY5NFx1RDU2OVx1QjJDOFx1QjJFNCEifSwKLQotICB7IEVSX0VNUFRZX0VYUFJFU1NJT04sCi0gICAgICJcdUQ0NUNcdUQ2MDRcdUMyRERcdUM3NzQgXHVCRTQ0XHVDNUI0IFx1Qzc4OFx1QzJCNVx1QjJDOFx1QjJFNCEifSwKLQotICB7IEVSX0VYUEVDVEVEX0JVVF9GT1VORCwKLSAgICAgInswfVx1Qzc3NChcdUFDMDApIFx1RDU0NFx1QzY5NFx1RDU1OFx1QzlDMFx1QjlDQyB7MX1cdUM3NzQoXHVBQzAwKSBcdUJDMUNcdUFDQUNcdUI0MThcdUM1QzhcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgeyBFUl9JTkNPUlJFQ1RfUFJPR1JBTU1FUl9BU1NFUlRJT04sCi0gICAgICAiXHVENTA0XHVCODVDXHVBREY4XHVCNzk4XHVCQTM4IFx1QUM4MFx1Qzk5RFx1Qzc3NCBcdUM2MkNcdUJDMTRcdUI5NzRcdUM5QzAgXHVDNTRBXHVDNzRDIC0gezB9In0sCi0KLSAgeyBFUl9CT09MRUFOX0FSR19OT19MT05HRVJfT1BUSU9OQUwsCi0gICAgICAiMTk5OTA3MDkgWFBhdGggXHVDRDA4XHVDNTQ4XHVDNUQwXHVDMTFDXHVCMjk0IGJvb2xlYW4oLi4uKSBcdUM3NzhcdUMyMThcdUFDMDAgXHVCMzU0IFx1Qzc3NFx1QzBDMSBcdUMxMjBcdUQwRERcdUM4MDEgXHVDNzc4XHVDMjE4XHVBQzAwIFx1QzU0NFx1QjJEOVx1QjJDOFx1QjJFNC4ifSwKLQotICB7IEVSX0ZPVU5EX0NPTU1BX0JVVF9OT19QUkVDRURJTkdfQVJHLAotICAgICAgIicsJ1x1Qjk3QyBcdUNDM0VcdUM1NThcdUM5QzBcdUI5Q0MgXHVDMTIwXHVENTg5IFx1Qzc3OFx1QzIxOFx1QUMwMCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQhIn0sCi0KLSAgeyBFUl9GT1VORF9DT01NQV9CVVRfTk9fRk9MTE9XSU5HX0FSRywKLSAgICAgICInLCdcdUI5N0MgXHVDQzNFXHVDNTU4XHVDOUMwXHVCOUNDIFx1RDZDNFx1RDU4OSBcdUM3NzhcdUMyMThcdUFDMDAgXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0ISJ9LAotCi0gIHsgRVJfUFJFRElDQVRFX0lMTEVHQUxfU1lOVEFYLAotICAgICAgIicuLltwcmVkaWNhdGVdJyBcdUI2MTBcdUIyOTQgJy5bcHJlZGljYXRlXSdcdUIyOTQgXHVDNzk4XHVCQUJCXHVCNDFDIFx1QUQ2Q1x1QkIzOFx1Qzc4NVx1QjJDOFx1QjJFNC4gXHVCMzAwXHVDMkUwICdzZWxmOjpub2RlKClbcHJlZGljYXRlXSdcdUI5N0MgXHVDMEFDXHVDNkE5XHVENTU4XHVDMkVEXHVDMkRDXHVDNjI0LiJ9LAotCi0gIHsgRVJfSUxMRUdBTF9BWElTX05BTUUsCi0gICAgICJcdUM3OThcdUJBQkJcdUI0MUMgXHVDRDk1IFx1Qzc3NFx1Qjk4NDogezB9In0sCi0KLSAgeyBFUl9VTktOT1dOX05PREVUWVBFLAotICAgICAiXHVDNTRDIFx1QzIxOCBcdUM1QzZcdUIyOTQgbm9kZXR5cGU6IHswfSJ9LAotCi0gIHsgRVJfUEFUVEVSTl9MSVRFUkFMX05FRURTX0JFX1FVT1RFRCwKLSAgICAgICJcdUQzMjhcdUQxMzQgXHVCOUFDXHVEMTMwXHVCN0Y0KHswfSlcdUM1RDAgXHVCNTMwXHVDNjM0XHVENDVDXHVCOTdDIFx1QzlDMFx1QzgxNVx1RDU3NFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTQhIn0sCi0KLSAgeyBFUl9DT1VMRE5PVF9CRV9GT1JNQVRURURfVE9fTlVNQkVSLAotICAgICAgInswfVx1Qzc1OCBcdUQ2MTVcdUMyRERcdUM3NDQgXHVDMjJCXHVDNzkwXHVCODVDIFx1QzlDMFx1QzgxNVx1RDU2MCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0ISJ9LAotCi0gIHsgRVJfQ09VTEROT1RfQ1JFQVRFX1hNTFBST0NFU1NPUkxJQUlTT04sCi0gICAgICAiWE1MIFRyYW5zZm9ybWVyRmFjdG9yeSBcdUM1RjBcdUFDQjBcdUM3NDQgXHVDMEREXHVDMTMxXHVENTYwIFx1QzIxOCBcdUM1QzZcdUM3NEM6IHswfSJ9LAotCi0gIHsgRVJfRElETk9UX0ZJTkRfWFBBVEhfU0VMRUNUX0VYUCwKLSAgICAgICJcdUM2MjRcdUI5NTg6IHhwYXRoIHNlbGVjdCBcdUQ0NUNcdUQ2MDRcdUMyREQoLXNlbGVjdClcdUM3NDQgXHVDQzNFXHVDNzQ0IFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgeyBFUl9DT1VMRE5PVF9GSU5EX0VORE9QX0FGVEVSX09QTE9DQVRJT05QQVRILAotICAgICAgIlx1QzYyNFx1Qjk1OCEgT1BfTE9DQVRJT05QQVRIIFx1QjRBNFx1QzVEMFx1QzExQyBFTkRPUFx1Qjk3QyBcdUNDM0VcdUM3NDQgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICB7IEVSX0VSUk9SX09DQ1VSRUQsCi0gICAgICJcdUM2MjRcdUI5NThcdUFDMDAgXHVCQzFDXHVDMEREXHVENTg4XHVDMkI1XHVCMkM4XHVCMkU0ISJ9LAotCi0gIHsgRVJfSUxMRUdBTF9WQVJJQUJMRV9SRUZFUkVOQ0UsCi0gICAgICAiXHVCQ0MwXHVDMjE4XHVDNUQwIFx1QjMwMFx1RDU3NCBcdUM4MUNcdUFDRjVcdUI0MUMgVmFyaWFibGVSZWZlcmVuY2VcdUFDMDAgXHVDRUU4XHVEMTREXHVDMkE0XHVEMkI4XHVDNUQwXHVDMTFDIFx1QkM5N1x1QzVCNFx1QjA5OFx1QUM3MFx1QjA5OCBcdUM4MTVcdUM3NThcdUI5N0MgXHVEM0VDXHVENTY4XHVENTU4XHVDOUMwIFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNCEgXHVDNzc0XHVCOTg0ID0gezB9In0sCi0KLSAgeyBFUl9BWEVTX05PVF9BTExPV0VELAotICAgICAgIlx1Qzc3Q1x1Q0U1OCBcdUQzMjhcdUQxMzRcdUM1RDBcdUMxMUNcdUIyOTQgY2hpbGQ6OiBcdUJDMEYgYXR0cmlidXRlOjogXHVDRDk1XHVCOUNDIFx1RDVDOFx1QzZBOVx1QjQyOVx1QjJDOFx1QjJFNCEgXHVDNzk4XHVCQUJCXHVCNDFDIFx1Q0Q5NSA9IHswfSJ9LAotCi0gIHsgRVJfS0VZX0hBU19UT09fTUFOWV9BUkdTLAotICAgICAgImtleSgpXHVDNUQwIFx1QzYyQ1x1QkMxNFx1Qjk3NFx1QzlDMCBcdUM1NEFcdUM3NDAgXHVDMjE4XHVDNzU4IFx1Qzc3OFx1QzIxOFx1QUMwMCBcdUM3ODhcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgeyBFUl9DT1VOVF9UQUtFU18xX0FSRywKLSAgICAgICJjb3VudCBcdUQ1NjhcdUMyMThcdUM1RDBcdUIyOTQgXHVENTVDIFx1QUMxQ1x1Qzc1OCBcdUM3NzhcdUMyMThcdUFDMDAgXHVDMEFDXHVDNkE5XHVCNDE4XHVDNUI0XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNCEifSwKLQotICB7IEVSX0NPVUxETk9UX0ZJTkRfRlVOQ1RJT04sCi0gICAgICJcdUQ1NjhcdUMyMThcdUI5N0MgXHVDQzNFXHVDNzQ0IFx1QzIxOCBcdUM1QzZcdUM3NEM6IHswfSJ9LAotCi0gIHsgRVJfVU5TVVBQT1JURURfRU5DT0RJTkcsCi0gICAgICJcdUM5QzBcdUM2RDBcdUI0MThcdUM5QzAgXHVDNTRBXHVCMjk0IFx1Qzc3OFx1Q0Y1NFx1QjUyOTogezB9In0sCi0KLSAgeyBFUl9QUk9CTEVNX0lOX0RUTV9ORVhUU0lCTElORywKLSAgICAgICJEVE1cdUM1RDBcdUMxMUMgZ2V0TmV4dFNpYmxpbmdcdUM1RDAgXHVCQjM4XHVDODFDXHVBQzAwIFx1QkMxQ1x1QzBERFx1RDU4OFx1QzJCNVx1QjJDOFx1QjJFNC4gXHVCQ0Y1XHVBRDZDXHVENTU4XHVCODI0XHVBQ0UwIFx1QzJEQ1x1QjNDNFx1RDU1OFx1QjI5NCBcdUM5MTEifSwKLQotICB7IEVSX0NBTk5PVF9XUklURV9UT19FTVBUWU5PREVMSVNUSU1QTCwKLSAgICAgICJcdUQ1MDRcdUI4NUNcdUFERjhcdUI3OThcdUJBMzggXHVDNjI0XHVCOTU4OiBFbXB0eU5vZGVMaXN0XHVDNUQwIFx1QzRGOCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gIHsgRVJfU0VURE9NRkFDVE9SWV9OT1RfU1VQUE9SVEVELAotICAgICAgIlhQYXRoQ29udGV4dFx1QzVEMFx1QzExQ1x1QjI5NCBzZXRET01GYWN0b3J5XHVBQzAwIFx1QzlDMFx1QzZEMFx1QjQxOFx1QzlDMCBcdUM1NEFcdUMyQjVcdUIyQzhcdUIyRTQhIn0sCi0KLSAgeyBFUl9QUkVGSVhfTVVTVF9SRVNPTFZFLAotICAgICAgIlx1QzgxMVx1QjQ1MFx1QzVCNFx1QjI5NCBcdUIxMjRcdUM3ODRcdUMyQTRcdUQzOThcdUM3NzRcdUMyQTRcdUI4NUMgXHVCRDg0XHVDMTFEXHVCNDE4XHVDNUI0XHVDNTdDIFx1RDU2ODogezB9In0sCi0KLSAgeyBFUl9QQVJTRV9OT1RfU1VQUE9SVEVELAotICAgICAgIlhQYXRoQ29udGV4dFx1QzVEMFx1QzExQ1x1QjI5NCBwYXJzZShJbnB1dFNvdXJjZSBcdUMxOENcdUMyQTQpXHVBQzAwIFx1QzlDMFx1QzZEMFx1QjQxOFx1QzlDMCBcdUM1NEFcdUMyQjVcdUIyQzhcdUIyRTQhIHswfVx1Qzc0NChcdUI5N0MpIFx1QzVGNCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gIHsgRVJfU0FYX0FQSV9OT1RfSEFORExFRCwKLSAgICAgICJEVE1cdUM3NzQgU0FYIEFQSSBcdUJCMzhcdUM3OTAoY2hhciBjaFtdLi4uXHVCOTdDIFx1Q0M5OFx1QjlBQ1x1RDU1OFx1QzlDMCBcdUM1NEFcdUM1NThcdUMyQjVcdUIyQzhcdUIyRTQhIn0sCi0KLSAgeyBFUl9JR05PUkFCTEVfV0hJVEVTUEFDRV9OT1RfSEFORExFRCwKLSAgICAgICJEVE1cdUM3NzQgaWdub3JhYmxlV2hpdGVzcGFjZShjaGFyIGNoW10uLi5cdUI5N0MgXHVDQzk4XHVCOUFDXHVENTU4XHVDOUMwIFx1QzU0QVx1QzU1OFx1QzJCNVx1QjJDOFx1QjJFNCEifSwKLQotICB7IEVSX0RUTV9DQU5OT1RfSEFORExFX05PREVTLAotICAgICAgIkRUTUxpYWlzb25cdUM3NDAgezB9IFx1QzcyMFx1RDYxNVx1Qzc1OCBcdUIxNzhcdUI0RENcdUI5N0MgXHVDQzk4XHVCOUFDXHVENTYwIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgeyBFUl9YRVJDRVNfQ0FOTk9UX0hBTkRMRV9OT0RFUywKLSAgICAgICJET00ySGVscGVyXHVCMjk0IHswfSBcdUM3MjBcdUQ2MTVcdUM3NTggXHVCMTc4XHVCNERDXHVCOTdDIFx1Q0M5OFx1QjlBQ1x1RDU2MCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gIHsgRVJfWEVSQ0VTX1BBUlNFX0VSUk9SX0RFVEFJTFMsCi0gICAgICAiRE9NMkhlbHBlci5wYXJzZSBcdUM2MjRcdUI5NTg6IFN5c3RlbUlEIC0gezB9IFx1RDU4OSAtIHsxfSJ9LAotCi0gIHsgRVJfWEVSQ0VTX1BBUlNFX0VSUk9SLAotICAgICAiRE9NMkhlbHBlci5wYXJzZSBcdUM2MjRcdUI5NTgifSwKLQotICB7IEVSX0lOVkFMSURfVVRGMTZfU1VSUk9HQVRFLAotICAgICAgIlx1QkQ4MFx1QzgwMVx1RDU2OVx1RDU1QyBVVEYtMTYgXHVCMzAwXHVCOUFDIFx1QzY5NFx1QzE4Q1x1QUMwMCBcdUFDMTBcdUM5QzBcdUI0Mjg6IHswfSJ9LAotCi0gIHsgRVJfT0lFUlJPUiwKLSAgICAgIklPIFx1QzYyNFx1Qjk1OCJ9LAotCi0gIHsgRVJfQ0FOTk9UX0NSRUFURV9VUkwsCi0gICAgICJ7MH1cdUM1RDAgXHVCMzAwXHVENTVDIFVSTFx1Qzc0NCBcdUMwRERcdUMxMzFcdUQ1NjAgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICB7IEVSX1hQQVRIX1JFQURPQkpFQ1QsCi0gICAgICJYUGF0aC5yZWFkT2JqZWN0XHVDNUQwIFx1QzYyNFx1Qjk1OCBcdUJDMUNcdUMwREQ6IHswfSJ9LAotCi0gIHsgRVJfRlVOQ1RJT05fVE9LRU5fTk9UX0ZPVU5ELAotICAgICAgIlx1RDU2OFx1QzIxOCBcdUQxQTBcdUQwNzBcdUM3NDQgXHVDQzNFXHVDNzQ0IFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgeyBFUl9DQU5OT1RfREVBTF9YUEFUSF9UWVBFLAotICAgICAgICJYUGF0aCBcdUM3MjBcdUQ2MTVcdUM3NDQgXHVDQzk4XHVCOUFDXHVENTYwIFx1QzIxOCBcdUM1QzZcdUM3NEM6IHswfSJ9LAotCi0gIHsgRVJfTk9ERVNFVF9OT1RfTVVUQUJMRSwKLSAgICAgICAiXHVDNzc0IE5vZGVTZXRcdUIyOTQgXHVCQ0MwXHVBQ0JEXHVENTYwIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgeyBFUl9OT0RFU0VURFRNX05PVF9NVVRBQkxFLAotICAgICAgICJcdUM3NzQgTm9kZVNldERUTVx1Qzc0MCBcdUJDQzBcdUFDQkRcdUQ1NjAgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICB7IEVSX1ZBUl9OT1RfUkVTT0xWQUJMRSwKLSAgICAgICAgIlx1QkNDMFx1QzIxOFx1Qjk3QyBcdUJEODRcdUMxMURcdUQ1NjAgXHVDMjE4IFx1QzVDNlx1Qzc0QzogezB9In0sCi0KLSAgeyBFUl9OVUxMX0VSUk9SX0hBTkRMRVIsCi0gICAgICAgICJcdUIxMTAgXHVDNjI0XHVCOTU4IFx1Q0M5OFx1QjlBQ1x1QUUzMCJ9LAotCi0gIHsgRVJfUFJPR19BU1NFUlRfVU5LTk9XTl9PUENPREUsCi0gICAgICAgIlx1RDUwNFx1Qjg1Q1x1QURGOFx1Qjc5OFx1QkEzOCBcdUFDODBcdUM5OUQ6IFx1QzU0QyBcdUMyMTggXHVDNUM2XHVCMjk0IG9wY29kZTogezB9In0sCi0KLSAgeyBFUl9aRVJPX09SX09ORSwKLSAgICAgICAiMCBcdUI2MTBcdUIyOTQgMSJ9LAotCi0gIHsgRVJfUlRGX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIsCi0gICAgICAgIlhSVHJlZUZyYWdTZWxlY3RXcmFwcGVyXHVCMjk0IHJ0ZigpXHVCOTdDIFx1QzlDMFx1QzZEMFx1RDU1OFx1QzlDMCBcdUM1NEFcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgeyBFUl9SVEZfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiwKLSAgICAgICAiWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXJcdUIyOTQgYXNOb2RlSXRlcmF0b3IoKVx1Qjk3QyBcdUM5QzBcdUM2RDBcdUQ1NThcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgICAgIC8qKiAgZGV0YWNoKCkgbm90IHN1cHBvcnRlZCBieSBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciAgICovCi0gICB7IEVSX0RFVEFDSF9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSLAotICAgICAgICAgICAgICAgICJYUlRyZWVGcmFnU2VsZWN0V3JhcHBlclx1QjI5NCBkZXRhY2goKVx1Qjk3QyBcdUM5QzBcdUM2RDBcdUQ1NThcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgICAgIC8qKiAgbnVtKCkgbm90IHN1cHBvcnRlZCBieSBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciAgICovCi0gICB7IEVSX05VTV9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSLAotICAgICAgICAgICAgICAgICJYUlRyZWVGcmFnU2VsZWN0V3JhcHBlclx1QjI5NCBudW0oKVx1Qzc0NCBcdUM5QzBcdUM2RDBcdUQ1NThcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgICAgIC8qKiAgeHN0cigpIG5vdCBzdXBwb3J0ZWQgYnkgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIgICAqLwotICAgeyBFUl9YU1RSX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIsCi0gICAgICAgICAgICAgICAgIlhSVHJlZUZyYWdTZWxlY3RXcmFwcGVyXHVCMjk0IHhzdHIoKVx1Qzc0NCBcdUM5QzBcdUM2RDBcdUQ1NThcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gICAgICAgIC8qKiAgc3RyKCkgbm90IHN1cHBvcnRlZCBieSBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciAgICovCi0gICB7IEVSX1NUUl9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSLAotICAgICAgICAgICAgICAgICJYUlRyZWVGcmFnU2VsZWN0V3JhcHBlclx1QjI5NCBzdHIoKVx1Qzc0NCBcdUM5QzBcdUM2RDBcdUQ1NThcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gIHsgRVJfRlNCX05PVF9TVVBQT1JURURfWFNUUklOR0ZPUkNIQVJTLAotICAgICAgICJmc2IoKVx1QjI5NCBYU3RyaW5nRm9yQ2hhcnNcdUM1RDAgXHVCMzAwXHVENTc0IFx1QzlDMFx1QzZEMFx1QjQxOFx1QzlDMCBcdUM1NEFcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgeyBFUl9DT1VMRF9OT1RfRklORF9WQVIsCi0gICAgICAiXHVDNzc0XHVCOTg0XHVDNzc0IHswfVx1Qzc3OCBcdUJDQzBcdUMyMThcdUI5N0MgXHVDQzNFXHVDNzQ0IFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgeyBFUl9YU1RSSU5HRk9SQ0hBUlNfQ0FOTk9UX1RBS0VfU1RSSU5HLAotICAgICAgIlhTdHJpbmdGb3JDaGFyc1x1QjI5NCBcdUM3NzhcdUMyMThcdUM1RDAgXHVCQjM4XHVDNzkwXHVDNUY0XHVDNzQ0IFx1QzBBQ1x1QzZBOVx1RDU2MCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gIHsgRVJfRkFTVFNUUklOR0JVRkZFUl9DQU5OT1RfQkVfTlVMTCwKLSAgICAgICJGYXN0U3RyaW5nQnVmZmVyIFx1Qzc3OFx1QzIxOFx1QjI5NCBcdUIxMTBcdUM3N0MgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICB7IEVSX1RXT19PUl9USFJFRSwKLSAgICAgICAiMiBcdUI2MTBcdUIyOTQgMyJ9LAotCi0gIHsgRVJfVkFSSUFCTEVfQUNDRVNTRURfQkVGT1JFX0JJTkQsCi0gICAgICAgIlx1QkNDMFx1QzIxOFx1QUMwMCBcdUJDMTRcdUM3NzhcdUI0RENcdUI0MThcdUFFMzAgXHVDODA0XHVDNUQwIFx1QkNDMFx1QzIxOFx1QzVEMCBcdUM1NjFcdUMxMzhcdUMyQTRcdUI0MThcdUM1QzhcdUMyQjVcdUIyQzhcdUIyRTQhIn0sCi0KLSAgeyBFUl9GU0JfQ0FOTk9UX1RBS0VfU1RSSU5HLAotICAgICAgICJYU3RyaW5nRm9yRlNCXHVCMjk0IFx1Qzc3OFx1QzIxOFx1QzVEMCBcdUJCMzhcdUM3OTBcdUM1RjRcdUM3NDQgXHVDMEFDXHVDNkE5XHVENTYwIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQhIn0sCi0KLSAgeyBFUl9TRVRUSU5HX1dBTEtFUl9ST09UX1RPX05VTEwsCi0gICAgICAgIlxuICEhISEgXHVDNjI0XHVCOTU4ISBcdUM2Q0NcdUNFRTRcdUM3NTggXHVCOEU4XHVEMkI4XHVCOTdDIG51bGxcdUI4NUMgXHVDMTI0XHVDODE1XHVENTU4XHVCMjk0IFx1QzkxMVx1Qzc4NVx1QjJDOFx1QjJFNCEifSwKLQotICB7IEVSX05PREVTRVREVE1fQ0FOTk9UX0lURVJBVEUsCi0gICAgICAgIlx1Qzc3NCBOb2RlU2V0RFRNXHVDNzQwIFx1Qzc3NFx1QzgwNCBcdUIxNzhcdUI0RENcdUI5N0MgXHVCQzE4XHVCQ0Y1XHVENTYwIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQhIn0sCi0KLSAgeyBFUl9OT0RFU0VUX0NBTk5PVF9JVEVSQVRFLAotICAgICAgICJcdUM3NzQgTm9kZVNldFx1QjI5NCBcdUM3NzRcdUM4MDQgXHVCMTc4XHVCNERDXHVCOTdDIFx1QkMxOFx1QkNGNVx1RDU2MCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0ISJ9LAotCi0gIHsgRVJfTk9ERVNFVERUTV9DQU5OT1RfSU5ERVgsCi0gICAgICAgIlx1Qzc3NCBOb2RlU2V0RFRNXHVDNzQwIFx1RDU2OFx1QzIxOFx1Qjk3QyBcdUM3NzhcdUIzNzFcdUMyQTRcdUQ2NTRcdUQ1NThcdUFDNzBcdUIwOTggXHVDOUQxXHVBQ0M0XHVENTYwIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQhIn0sCi0KLSAgeyBFUl9OT0RFU0VUX0NBTk5PVF9JTkRFWCwKLSAgICAgICAiXHVDNzc0IE5vZGVTZXRcdUIyOTQgXHVENTY4XHVDMjE4XHVCOTdDIFx1Qzc3OFx1QjM3MVx1QzJBNFx1RDY1NFx1RDU1OFx1QUM3MFx1QjA5OCBcdUM5RDFcdUFDQzRcdUQ1NjAgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNCEifSwKLQotICB7IEVSX0NBTk5PVF9DQUxMX1NFVFNIT1VMRENBQ0hFTk9ERSwKLSAgICAgICAibmV4dE5vZGVcdUFDMDAgXHVENjM4XHVDRDlDXHVCNDFDIFx1RDZDNFx1QzVEMFx1QjI5NCBzZXRTaG91bGRDYWNoZU5vZGVzXHVCOTdDIFx1RDYzOFx1Q0Q5Q1x1RDU2MCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0ISJ9LAotCi0gIHsgRVJfT05MWV9BTExPV1MsCi0gICAgICAgInswfVx1Qzc0MChcdUIyOTQpIHsxfVx1QUMxQ1x1Qzc1OCBcdUM3NzhcdUMyMThcdUI5Q0MgXHVENUM4XHVDNkE5XHVENTY5XHVCMkM4XHVCMkU0LiJ9LAotCi0gIHsgRVJfVU5LTk9XTl9TVEVQLAotICAgICAgICJnZXROZXh0U3RlcFBvc1x1QzVEMCBcdUQ1MDRcdUI4NUNcdUFERjhcdUI3OThcdUJBMzggXHVBQzgwXHVDOTlEXHVDNzc0IFx1Qzc4OFx1Qzc0QzogXHVDNTRDIFx1QzIxOCBcdUM1QzZcdUIyOTQgc3RlcFR5cGU6IHswfSJ9LAotCi0gIC8vTm90ZSB0byB0cmFuc2xhdG9yczogIEEgcmVsYXRpdmUgbG9jYXRpb24gcGF0aCBpcyBhIGZvcm0gb2YgWFBhdGggZXhwcmVzc2lvbi4KLSAgLy8gVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgc3VjaCBhbiBleHByZXNzaW9uIHdhcyBleHBlY3RlZCBmb2xsb3dpbmcgdGhlCi0gIC8vIGNoYXJhY3RlcnMgJy8nIG9yICcvLycsIGJ1dCB3YXMgbm90IGZvdW5kLgotICB7IEVSX0VYUEVDVEVEX1JFTF9MT0NfUEFUSCwKLSAgICAgICInLycgXHVCNjEwXHVCMjk0ICcvLycgXHVEMUEwXHVEMDcwIFx1QjRBNFx1QzVEMCBcdUMwQzFcdUIzMDAgXHVDNzA0XHVDRTU4IFx1QUNCRFx1Qjg1Q1x1QUMwMCBcdUQ1NDRcdUM2OTRcdUQ1NjlcdUIyQzhcdUIyRTQuIn0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIEEgbG9jYXRpb24gcGF0aCBpcyBhIGZvcm0gb2YgWFBhdGggZXhwcmVzc2lvbi4KLSAgLy8gVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgc3ludGFjdGljYWxseSBzdWNoIGFuIGV4cHJlc3Npb24gd2FzIGV4cGVjdGVkLGJ1dAotICAvLyB0aGUgY2hhcmFjdGVycyBzcGVjaWZpZWQgYnkgdGhlIHN1YnN0aXR1dGlvbiB0ZXh0IHdlcmUgZW5jb3VudGVyZWQgaW5zdGVhZC4KLSAgeyBFUl9FWFBFQ1RFRF9MT0NfUEFUSCwKLSAgICAgICAiXHVDNzA0XHVDRTU4IFx1QUNCRFx1Qjg1Q1x1QUMwMCBcdUQ1NDRcdUM2OTRcdUQ1NThcdUM5QzBcdUI5Q0MgezB9IFx1RDFBMFx1RDA3MFx1Qzc3NCBcdUJDMUNcdUFDQUNcdUI0MThcdUM1QzhcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIEEgbG9jYXRpb24gcGF0aCBpcyBhIGZvcm0gb2YgWFBhdGggZXhwcmVzc2lvbi4KLSAgLy8gVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgc3ludGFjdGljYWxseSBzdWNoIGEgc3ViZXhwcmVzc2lvbiB3YXMgZXhwZWN0ZWQsCi0gIC8vIGJ1dCBubyBtb3JlIGNoYXJhY3RlcnMgd2VyZSBmb3VuZCBpbiB0aGUgZXhwcmVzc2lvbi4KLSAgeyBFUl9FWFBFQ1RFRF9MT0NfUEFUSF9BVF9FTkRfRVhQUiwKLSAgICAgICAiXHVDNzA0XHVDRTU4IFx1QUNCRFx1Qjg1Q1x1QUMwMCBcdUQ1NDRcdUM2OTRcdUQ1NThcdUM5QzBcdUI5Q0MgWFBhdGggXHVENDVDXHVENjA0XHVDMkREIFx1QjA1RFx1Qzc3NCBcdUJDMUNcdUFDQUNcdUI0MThcdUM1QzhcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIEEgbG9jYXRpb24gc3RlcCBpcyBwYXJ0IG9mIGFuIFhQYXRoIGV4cHJlc3Npb24uCi0gIC8vIFRoZSBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHN5bnRhY3RpY2FsbHkgc3VjaCBhbiBleHByZXNzaW9uIHdhcyBleHBlY3RlZAotICAvLyBmb2xsb3dpbmcgdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXJzLgotICB7IEVSX0VYUEVDVEVEX0xPQ19TVEVQLAotICAgICAgICInLycgXHVCNjEwXHVCMjk0ICcvLycgXHVEMUEwXHVEMDcwIFx1QjRBNFx1QzVEMCBcdUM3MDRcdUNFNTggXHVCMkU4XHVBQ0M0XHVBQzAwIFx1RDU0NFx1QzY5NFx1RDU2OVx1QjJDOFx1QjJFNC4ifSwKLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQSBub2RlIHRlc3QgaXMgcGFydCBvZiBhbiBYUGF0aCBleHByZXNzaW9uIHRoYXQgaXMKLSAgLy8gdXNlZCB0byB0ZXN0IGZvciBwYXJ0aWN1bGFyIGtpbmRzIG9mIG5vZGVzLiAgSW4gdGhpcyBjYXNlLCBhIG5vZGUgdGVzdCB0aGF0Ci0gIC8vIGNvbnNpc3RzIG9mIGFuIE5DTmFtZSBmb2xsb3dlZCBieSBhIGNvbG9uIGFuZCBhbiBhc3RlcmlzayBvciB0aGF0IGNvbnNpc3RzCi0gIC8vIG9mIGEgUU5hbWUgd2FzIGV4cGVjdGVkLCBidXQgd2FzIG5vdCBmb3VuZC4KLSAgeyBFUl9FWFBFQ1RFRF9OT0RFX1RFU1QsCi0gICAgICAgIk5DTmFtZToqIFx1QjYxMFx1QjI5NCBRTmFtZVx1QUNGQyBcdUM3N0NcdUNFNThcdUQ1NThcdUIyOTQgXHVCMTc4XHVCNERDIFx1RDE0Q1x1QzJBNFx1RDJCOFx1QUMwMCBcdUQ1NDRcdUM2OTRcdUQ1NjlcdUIyQzhcdUIyRTQuIn0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIEEgc3RlcCBwYXR0ZXJuIGlzIHBhcnQgb2YgYW4gWFBhdGggZXhwcmVzc2lvbi4KLSAgLy8gVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgc3ludGFjdGljYWxseSBzdWNoIGFuIGV4cHJlc3Npb24gd2FzIGV4cGVjdGVkLAotICAvLyBidXQgdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXIgd2FzIGZvdW5kIGluIHRoZSBleHByZXNzaW9uIGluc3RlYWQuCi0gIHsgRVJfRVhQRUNURURfU1RFUF9QQVRURVJOLAotICAgICAgICJcdUIyRThcdUFDQzQgXHVEMzI4XHVEMTM0XHVDNzc0IFx1RDU0NFx1QzY5NFx1RDU1OFx1QzlDMFx1QjlDQyAnLydcdUFDMDAgXHVCQzFDXHVBQ0FDXHVCNDE4XHVDNUM4XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6IEEgcmVsYXRpdmUgcGF0aCBwYXR0ZXJuIGlzIHBhcnQgb2YgYW4gWFBhdGggZXhwcmVzc2lvbi4KLSAgLy8gVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgc3ludGFjdGljYWxseSBzdWNoIGFuIGV4cHJlc3Npb24gd2FzIGV4cGVjdGVkLAotICAvLyBidXQgd2FzIG5vdCBmb3VuZC4KLSAgeyBFUl9FWFBFQ1RFRF9SRUxfUEFUSF9QQVRURVJOLAotICAgICAgICJcdUMwQzFcdUIzMDAgXHVBQ0JEXHVCODVDIFx1RDMyOFx1RDEzNFx1Qzc3NCBcdUQ1NDRcdUM2OTRcdUQ1NjlcdUIyQzhcdUIyRTQuIn0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBhIGRhdGEgdHlwZS4gIFRoZQotICAvLyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IGEgdmFsdWUgb2YgYSBwYXJ0aWN1bGFyIHR5cGUgY291bGQgbm90IGJlIGNvbnZlcnRlZAotICAvLyB0byBhIHZhbHVlIG9mIHR5cGUgYm9vbGVhbi4KLSAgeyBFUl9DQU5UX0NPTlZFUlRfVE9fQk9PTEVBTiwKLSAgICAgICAiWFBhdGggXHVENDVDXHVENjA0XHVDMkREICcnezB9JydcdUM1RDAgXHVCMzAwXHVENTVDIFhQYXRoUmVzdWx0XHVDNzU4IFhQYXRoUmVzdWx0VHlwZVx1Qzc3NCBcdUJEODBcdUM2QjhcdUI4NUMgXHVCQ0MwXHVENjU4XHVCNDIwIFx1QzIxOCBcdUM1QzZcdUIyOTQgezF9XHVDNzg1XHVCMkM4XHVCMkU0LiJ9LAotCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6IERvIG5vdCB0cmFuc2xhdGUgQU5ZX1VOT1JERVJFRF9OT0RFX1RZUEUgYW5kCi0gIC8vIEZJUlNUX09SREVSRURfTk9ERV9UWVBFLgotICB7IEVSX0NBTlRfQ09OVkVSVF9UT19TSU5HTEVOT0RFLAotICAgICAgICJYUGF0aCBcdUQ0NUNcdUQ2MDRcdUMyREQgJyd7MH0nJ1x1QzVEMCBcdUIzMDBcdUQ1NUMgWFBhdGhSZXN1bHRcdUM3NTggWFBhdGhSZXN1bHRUeXBlXHVDNzc0IFx1QjJFOFx1Qzc3QyBcdUIxNzhcdUI0RENcdUI4NUMgXHVCQ0MwXHVENjU4XHVCNDIwIFx1QzIxOCBcdUM1QzZcdUIyOTQgezF9XHVDNzg1XHVCMkM4XHVCMkU0LiBnZXRTaW5nbGVOb2RlVmFsdWUgXHVCQTU0XHVDMThDXHVCNERDXHVCMjk0IEFOWV9VTk9SREVSRURfTk9ERV9UWVBFIFx1QkMwRiBGSVJTVF9PUkRFUkVEX05PREVfVFlQRSBcdUM3MjBcdUQ2MTVcdUM1RDBcdUI5Q0MgXHVDODAxXHVDNkE5XHVCNDI5XHVCMkM4XHVCMkU0LiJ9LAotCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6IERvIG5vdCB0cmFuc2xhdGUgVU5PUkRFUkVEX05PREVfU05BUFNIT1RfVFlQRSBhbmQKLSAgLy8gT1JERVJFRF9OT0RFX1NOQVBTSE9UX1RZUEUuCi0gIHsgRVJfQ0FOVF9HRVRfU05BUFNIT1RfTEVOR1RILAotICAgICAgICJYUGF0aFJlc3VsdFR5cGVcdUM3NzQgezF9XHVDNzc0XHVCQkMwXHVCODVDIGdldFNuYXBzaG90TGVuZ3RoIFx1QkE1NFx1QzE4Q1x1QjREQ1x1QjI5NCBYUGF0aCBcdUQ0NUNcdUQ2MDRcdUMyREQgJyd7MH0nJ1x1QzVEMCBcdUIzMDBcdUQ1NUMgWFBhdGhSZXN1bHRcdUM1RDBcdUMxMUMgXHVENjM4XHVDRDlDXHVCNDIwIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuIFx1Qzc3NCBcdUJBNTRcdUMxOENcdUI0RENcdUIyOTQgVU5PUkRFUkVEX05PREVfU05BUFNIT1RfVFlQRSBcdUJDMEYgT1JERVJFRF9OT0RFX1NOQVBTSE9UX1RZUEUgXHVDNzIwXHVENjE1XHVDNUQwXHVCOUNDIFx1QzgwMVx1QzZBOVx1QjQyOVx1QjJDOFx1QjJFNC4ifSwKLQotICB7IEVSX05PTl9JVEVSQVRPUl9UWVBFLAotICAgICAgICJYUGF0aFJlc3VsdFR5cGVcdUM3NzQgezF9XHVDNzc0XHVCQkMwXHVCODVDIGl0ZXJhdGVOZXh0IFx1QkE1NFx1QzE4Q1x1QjREQ1x1QjI5NCBYUGF0aCBcdUQ0NUNcdUQ2MDRcdUMyREQgJyd7MH0nJ1x1QzVEMCBcdUIzMDBcdUQ1NUMgWFBhdGhSZXN1bHRcdUM1RDBcdUMxMUMgXHVENjM4XHVDRDlDXHVCNDIwIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuIFx1Qzc3NCBcdUJBNTRcdUMxOENcdUI0RENcdUIyOTQgVU5PUkRFUkVEX05PREVfSVRFUkFUT1JfVFlQRSBcdUJDMEYgT1JERVJFRF9OT0RFX0lURVJBVE9SX1RZUEUgXHVDNzIwXHVENjE1XHVDNUQwXHVCOUNDIFx1QzgwMVx1QzZBOVx1QjQyOVx1QjJDOFx1QjJFNC4ifSwKLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiBUaGlzIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgdGhlIGRvY3VtZW50IGJlaW5nIG9wZXJhdGVkCi0gIC8vIHVwb24gY2hhbmdlZCwgc28gdGhlIGl0ZXJhdG9yIG9iamVjdCB0aGF0IHdhcyBiZWluZyB1c2VkIHRvIHRyYXZlcnNlIHRoZQotICAvLyBkb2N1bWVudCBoYXMgbm93IGJlY29tZSBpbnZhbGlkLgotICB7IEVSX0RPQ19NVVRBVEVELAotICAgICAgICJcdUFDQjBcdUFDRkNcdUFDMDAgXHVCQzE4XHVENjU4XHVCNDFDIFx1RDZDNCBcdUJCMzhcdUMxMUNcdUFDMDAgXHVCQ0MwXHVBQ0JEXHVCNDE4XHVDNUM4XHVDMkI1XHVCMkM4XHVCMkU0LiBcdUM3NzRcdUQxMzBcdUI4MDhcdUM3NzRcdUQxMzBcdUFDMDAgXHVCRDgwXHVDODAxXHVENTY5XHVENTY5XHVCMkM4XHVCMkU0LiJ9LAotCi0gIHsgRVJfSU5WQUxJRF9YUEFUSF9UWVBFLAotICAgICAgICJcdUJEODBcdUM4MDFcdUQ1NjlcdUQ1NUMgWFBhdGggXHVDNzIwXHVENjE1IFx1Qzc3OFx1QzIxODogezB9In0sCi0KLSAgeyBFUl9FTVBUWV9YUEFUSF9SRVNVTFQsCi0gICAgICAgIlhQYXRoIFx1QUNCMFx1QUNGQyBcdUFDMURcdUNDQjRcdUFDMDAgXHVCRTQ0XHVDNUI0IFx1Qzc4OFx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICB7IEVSX0lOQ09NUEFUSUJMRV9UWVBFUywKLSAgICAgICAiWFBhdGggXHVENDVDXHVENjA0XHVDMkREICcnezB9JydcdUM1RDAgXHVCMzAwXHVENTVDIFhQYXRoUmVzdWx0XHVDNzU4IFhQYXRoUmVzdWx0VHlwZVx1Qzc3NCBcdUM5QzBcdUM4MTVcdUI0MUMgWFBhdGhSZXN1bHRUeXBlIHsyfShcdUM3M0MpXHVCODVDIFx1QUMxNVx1QzgxQyBcdUJDQzBcdUQ2NThcdUI0MjAgXHVDMjE4IFx1QzVDNlx1QjI5NCB7MX1cdUM3ODVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgeyBFUl9OVUxMX1JFU09MVkVSLAotICAgICAgICJcdUIxMTAgXHVDODExXHVCNDUwXHVDNUI0IFx1QkQ4NFx1QzExRFx1QUUzMFx1Qjg1QyBcdUM4MTFcdUI0NTBcdUM1QjRcdUI5N0MgXHVCRDg0XHVDMTFEXHVENTYwIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBhIGRhdGEgdHlwZS4gIFRoZQotICAvLyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IGEgdmFsdWUgb2YgYSBwYXJ0aWN1bGFyIHR5cGUgY291bGQgbm90IGJlIGNvbnZlcnRlZAotICAvLyB0byBhIHZhbHVlIG9mIHR5cGUgc3RyaW5nLgotICB7IEVSX0NBTlRfQ09OVkVSVF9UT19TVFJJTkcsCi0gICAgICAgIlhQYXRoIFx1RDQ1Q1x1RDYwNFx1QzJERCAnJ3swfScnXHVDNUQwIFx1QjMwMFx1RDU1QyBYUGF0aFJlc3VsdFx1Qzc1OCBYUGF0aFJlc3VsdFR5cGVcdUM3NzQgXHVCQjM4XHVDNzkwXHVDNUY0XHVCODVDIFx1QkNDMFx1RDY1OFx1QjQyMCBcdUMyMTggXHVDNUM2XHVCMjk0IHsxfVx1Qzc4NVx1QjJDOFx1QjJFNC4ifSwKLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiBEbyBub3QgdHJhbnNsYXRlIHNuYXBzaG90SXRlbSwKLSAgLy8gVU5PUkRFUkVEX05PREVfU05BUFNIT1RfVFlQRSBhbmQgT1JERVJFRF9OT0RFX1NOQVBTSE9UX1RZUEUuCi0gIHsgRVJfTk9OX1NOQVBTSE9UX1RZUEUsCi0gICAgICAgIlhQYXRoUmVzdWx0VHlwZVx1Qzc3NCB7MX1cdUM3NzRcdUJCQzBcdUI4NUMgc25hcHNob3RJdGVtIFx1QkE1NFx1QzE4Q1x1QjREQ1x1QjI5NCBYUGF0aCBcdUQ0NUNcdUQ2MDRcdUMyREQgJyd7MH0nJ1x1QzVEMCBcdUIzMDBcdUQ1NUMgWFBhdGhSZXN1bHRcdUM1RDBcdUMxMUMgXHVENjM4XHVDRDlDXHVCNDIwIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuIFx1Qzc3NCBcdUJBNTRcdUMxOENcdUI0RENcdUIyOTQgVU5PUkRFUkVEX05PREVfU05BUFNIT1RfVFlQRSBcdUJDMEYgT1JERVJFRF9OT0RFX1NOQVBTSE9UX1RZUEUgXHVDNzIwXHVENjE1XHVDNUQwXHVCOUNDIFx1QzgwMVx1QzZBOVx1QjQyOVx1QjJDOFx1QjJFNC4ifSwKLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgWFBhdGhFdmFsdWF0b3IgaXMgYSBKYXZhIGludGVyZmFjZSBuYW1lLiAgQW4KLSAgLy8gWFBhdGhFdmFsdWF0b3IgaXMgY3JlYXRlZCB3aXRoIHJlc3BlY3QgdG8gYSBwYXJ0aWN1bGFyIFhNTCBkb2N1bWVudCwgYW5kIGluCi0gIC8vIHRoaXMgY2FzZSB0aGUgZXhwcmVzc2lvbiByZXByZXNlbnRlZCBieSB0aGlzIG9iamVjdCB3YXMgYmVpbmcgZXZhbHVhdGVkIHdpdGgKLSAgLy8gcmVzcGVjdCB0byBhIGNvbnRleHQgbm9kZSBmcm9tIGEgZGlmZmVyZW50IGRvY3VtZW50LgotICB7IEVSX1dST05HX0RPQ1VNRU5ULAotICAgICAgICJcdUNFRThcdUQxNERcdUMyQTRcdUQyQjggXHVCMTc4XHVCNERDXHVBQzAwIFx1Qzc3NCBYUGF0aEV2YWx1YXRvclx1QzVEMCBcdUJDMTRcdUM3NzhcdUI0RENcdUI0MUMgXHVCQjM4XHVDMTFDXHVDNUQwIFx1QzE4RFx1RDU1OFx1QzlDMCBcdUM1NEFcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBYUGF0aCBleHByZXNzaW9uIGNhbm5vdCBiZSBldmFsdWF0ZWQgd2l0aCByZXNwZWN0Ci0gIC8vIHRvIHRoaXMgdHlwZSBvZiBub2RlLgotICB7IEVSX1dST05HX05PREVUWVBFLAotICAgICAgICJcdUNFRThcdUQxNERcdUMyQTRcdUQyQjggXHVCMTc4XHVCNERDIFx1QzcyMFx1RDYxNVx1Qzc0MCBcdUM5QzBcdUM2RDBcdUI0MThcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gIHsgRVJfWFBBVEhfRVJST1IsCi0gICAgICAgIlhQYXRoXHVDNUQwIFx1QzU0QyBcdUMyMTggXHVDNUM2XHVCMjk0IFx1QzYyNFx1Qjk1OFx1QUMwMCBcdUJDMUNcdUMwRERcdUQ1ODhcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgeyBFUl9DQU5UX0NPTlZFUlRfWFBBVEhSRVNVTFRUWVBFX1RPX05VTUJFUiwKLSAgICAgICAgIlhQYXRoIFx1RDQ1Q1x1RDYwNFx1QzJERCAnJ3swfScnXHVDNUQwIFx1QjMwMFx1RDU1QyBYUGF0aFJlc3VsdFx1Qzc1OCBYUGF0aFJlc3VsdFR5cGVcdUM3NzQgXHVDMjJCXHVDNzkwXHVCODVDIFx1QkNDMFx1RDY1OFx1QjQyMCBcdUMyMTggXHVDNUM2XHVCMjk0IHsxfVx1Qzc4NVx1QjJDOFx1QjJFNC4ifSwKLQotICAvL0JFR0lOOiAgRGVmaW5pdGlvbnMgb2YgZXJyb3Iga2V5cyB1c2VkICBpbiBleGNlcHRpb24gbWVzc2FnZXMgb2YgIEpBWFAgMS4zIFhQYXRoIEFQSSBpbXBsZW1lbnRhdGlvbgotCi0gIC8qKiBGaWVsZCBFUl9FWFRFTlNJT05fRlVOQ1RJT05fQ0FOTk9UX0JFX0lOVk9LRUQgICAgICAgICAgICAgICAgICAgICAgICovCi0KLSAgeyBFUl9FWFRFTlNJT05fRlVOQ1RJT05fQ0FOTk9UX0JFX0lOVk9LRUQsCi0gICAgICAgIlhNTENvbnN0YW50cy5GRUFUVVJFX1NFQ1VSRV9QUk9DRVNTSU5HIFx1QUUzMFx1QjJBNVx1Qzc3NCB0cnVlXHVCODVDIFx1QzEyNFx1QzgxNVx1QjQxQyBcdUFDQkRcdUM2QjAgXHVENjU1XHVDN0E1IFx1RDU2OFx1QzIxOCAnJ3swfScnXHVDNzQ0KFx1Qjk3QykgXHVENjM4XHVDRDlDXHVENTYwIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgLyoqIEZpZWxkIEVSX1JFU09MVkVfVkFSSUFCTEVfUkVUVVJOU19OVUxMICAgICAgICAgICAgICAgICAgICAgICAqLwotCi0gIHsgRVJfUkVTT0xWRV9WQVJJQUJMRV9SRVRVUk5TX05VTEwsCi0gICAgICAgInswfSBcdUJDQzBcdUMyMThcdUM1RDAgXHVCMzAwXHVENTVDIHJlc29sdmVWYXJpYWJsZVx1Qzc3NCBcdUIxMTBcdUM3NDQgXHVCQzE4XHVENjU4XHVENTY5XHVCMkM4XHVCMkU0LiJ9LAotCi0gIC8qKiBGaWVsZCBFUl9VTlNVUFBPUlRFRF9SRVRVUk5fVFlQRSAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX1VOU1VQUE9SVEVEX1JFVFVSTl9UWVBFLAotICAgICAgICJcdUM5QzBcdUM2RDBcdUI0MThcdUM5QzAgXHVDNTRBXHVCMjk0IFx1QkMxOFx1RDY1OCBcdUM3MjBcdUQ2MTU6IHswfSJ9LAotCi0gIC8qKiBGaWVsZCBFUl9TT1VSQ0VfUkVUVVJOX1RZUEVfQ0FOTk9UX0JFX05VTEwgICAgICAgICAgICAgICAgICAgICAgICovCi0KLSAgeyBFUl9TT1VSQ0VfUkVUVVJOX1RZUEVfQ0FOTk9UX0JFX05VTEwsCi0gICAgICAgIlx1QzE4Q1x1QzJBNCBcdUJDMEYvXHVCNjEwXHVCMjk0IFx1QkMxOFx1RDY1OCBcdUM3MjBcdUQ2MTVcdUM3NDAgXHVCMTEwXHVDNzdDIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgLyoqIEZpZWxkIEVSX1NPVVJDRV9SRVRVUk5fVFlQRV9DQU5OT1RfQkVfTlVMTCAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX1NPVVJDRV9SRVRVUk5fVFlQRV9DQU5OT1RfQkVfTlVMTCwKLSAgICAgICAiXHVDMThDXHVDMkE0IFx1QkMwRi9cdUI2MTBcdUIyOTQgXHVCQzE4XHVENjU4IFx1QzcyMFx1RDYxNVx1Qzc0MCBcdUIxMTBcdUM3N0MgXHVDMjE4IFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLQotICAvKiogRmllbGQgRVJfQVJHX0NBTk5PVF9CRV9OVUxMICAgICAgICAgICAgICAgICAgICAgICAqLwotCi0gIHsgRVJfQVJHX0NBTk5PVF9CRV9OVUxMLAotICAgICAgICJ7MH0gXHVDNzc4XHVDMjE4XHVCMjk0IFx1QjExMFx1Qzc3QyBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gIC8qKiBGaWVsZCBFUl9PQkpFQ1RfTU9ERUxfTlVMTCAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX09CSkVDVF9NT0RFTF9OVUxMLAotICAgICAgICJvYmplY3RNb2RlbCA9PSBudWxsXHVCODVDIHswfSNpc09iamVjdE1vZGVsU3VwcG9ydGVkKFN0cmluZyBvYmplY3RNb2RlbClcdUI5N0MgXHVENjM4XHVDRDlDXHVENTYwIFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgLyoqIEZpZWxkIEVSX09CSkVDVF9NT0RFTF9FTVBUWSAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX09CSkVDVF9NT0RFTF9FTVBUWSwKLSAgICAgICAib2JqZWN0TW9kZWwgPT0gXCJcIlx1Qjg1QyB7MH0jaXNPYmplY3RNb2RlbFN1cHBvcnRlZChTdHJpbmcgb2JqZWN0TW9kZWwpXHVCOTdDIFx1RDYzOFx1Q0Q5Q1x1RDU2MCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gIC8qKiBGaWVsZCBFUl9PQkpFQ1RfTU9ERUxfRU1QVFkgICAgICAgICAgICAgICAgICAgICAgICovCi0KLSAgeyBFUl9GRUFUVVJFX05BTUVfTlVMTCwKLSAgICAgICAiXHVCMTEwIFx1Qzc3NFx1Qjk4NFx1QzczQ1x1Qjg1QyBcdUFFMzBcdUIyQTVcdUM3NDQgXHVDMTI0XHVDODE1XHVENTU4XHVCODI0XHVBQ0UwIFx1QzJEQ1x1QjNDNFx1RDU1OFx1QjI5NCBcdUM5MTE6IHswfSNzZXRGZWF0dXJlKG51bGwsIHsxfSkifSwKLQotICAvKiogRmllbGQgRVJfRkVBVFVSRV9VTktOT1dOICAgICAgICAgICAgICAgICAgICAgICAqLwotCi0gIHsgRVJfRkVBVFVSRV9VTktOT1dOLAotICAgICAgICJcdUM1NEMgXHVDMjE4IFx1QzVDNlx1QjI5NCBcdUFFMzBcdUIyQTUgXCJ7MH1cIlx1Qzc0NChcdUI5N0MpIFx1QzEyNFx1QzgxNVx1RDU1OFx1QjgyNFx1QUNFMCBcdUMyRENcdUIzQzRcdUQ1NThcdUIyOTQgXHVDOTExOiB7MX0jc2V0RmVhdHVyZSh7MH0sezJ9KSJ9LAotCi0gIC8qKiBGaWVsZCBFUl9HRVRUSU5HX05VTExfRkVBVFVSRSAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX0dFVFRJTkdfTlVMTF9GRUFUVVJFLAotICAgICAgICJcdUIxMTAgXHVDNzc0XHVCOTg0XHVDNzNDXHVCODVDIFx1QUUzMFx1QjJBNVx1Qzc0NCBcdUFDMDBcdUM4MzhcdUM2MjRcdUI4MjRcdUFDRTAgXHVDMkRDXHVCM0M0XHVENTU4XHVCMjk0IFx1QzkxMTogezB9I2dldEZlYXR1cmUobnVsbCkifSwKLQotICAvKiogRmllbGQgRVJfR0VUVElOR19OVUxMX0ZFQVRVUkUgICAgICAgICAgICAgICAgICAgICAgICovCi0KLSAgeyBFUl9HRVRUSU5HX1VOS05PV05fRkVBVFVSRSwKLSAgICAgICAiXHVDNTRDIFx1QzIxOCBcdUM1QzZcdUIyOTQgXHVBRTMwXHVCMkE1IFwiezB9XCJcdUM3NDQoXHVCOTdDKSBcdUFDMDBcdUM4MzhcdUM2MjRcdUI4MjRcdUFDRTAgXHVDMkRDXHVCM0M0XHVENTU4XHVCMjk0IFx1QzkxMTogezF9I2dldEZlYXR1cmUoezB9KSJ9LAotCi0gIHtFUl9TRUNVUkVQUk9DRVNTSU5HX0ZFQVRVUkUsCi0gICAgICAgICJGRUFUVVJFX1NFQ1VSRV9QUk9DRVNTSU5HOiBcdUJDRjRcdUM1NDggXHVBRDAwXHVCOUFDXHVDNzkwXHVBQzAwIFx1Qzc4OFx1Qzc0NCBcdUFDQkRcdUM2QjAgXHVBRTMwXHVCMkE1XHVDNzQ0IGZhbHNlXHVCODVDIFx1QzEyNFx1QzgxNVx1RDU2MCBcdUMyMTggXHVDNUM2XHVDNzRDOiB7MX0jc2V0RmVhdHVyZSh7MH0sezJ9KSJ9LAotCi0gIC8qKiBGaWVsZCBFUl9OVUxMX1hQQVRIX0ZVTkNUSU9OX1JFU09MVkVSICAgICAgICAgICAgICAgICAgICAgICAqLwotCi0gIHsgRVJfTlVMTF9YUEFUSF9GVU5DVElPTl9SRVNPTFZFUiwKLSAgICAgICAiXHVCMTEwIFhQYXRoRnVuY3Rpb25SZXNvbHZlclx1Qjk3QyBcdUMxMjRcdUM4MTVcdUQ1NThcdUI4MjRcdUFDRTAgXHVDMkRDXHVCM0M0XHVENTU4XHVCMjk0IFx1QzkxMTogezB9I3NldFhQYXRoRnVuY3Rpb25SZXNvbHZlcihudWxsKSJ9LAotCi0gIC8qKiBGaWVsZCBFUl9OVUxMX1hQQVRIX1ZBUklBQkxFX1JFU09MVkVSICAgICAgICAgICAgICAgICAgICAgICAqLwotCi0gIHsgRVJfTlVMTF9YUEFUSF9WQVJJQUJMRV9SRVNPTFZFUiwKLSAgICAgICAiXHVCMTEwIFhQYXRoVmFyaWFibGVSZXNvbHZlclx1Qjk3QyBcdUMxMjRcdUM4MTVcdUQ1NThcdUI4MjRcdUFDRTAgXHVDMkRDXHVCM0M0XHVENTU4XHVCMjk0IFx1QzkxMTogezB9I3NldFhQYXRoVmFyaWFibGVSZXNvbHZlcihudWxsKSJ9LAotCi0gIC8vRU5EOiAgRGVmaW5pdGlvbnMgb2YgZXJyb3Iga2V5cyB1c2VkICBpbiBleGNlcHRpb24gbWVzc2FnZXMgb2YgIEpBWFAgMS4zIFhQYXRoIEFQSSBpbXBsZW1lbnRhdGlvbgotCi0gIC8vIFdhcm5pbmdzLi4uCi0KLSAgeyBXR19MT0NBTEVfTkFNRV9OT1RfSEFORExFRCwKLSAgICAgICJmb3JtYXQtbnVtYmVyIFx1RDU2OFx1QzIxOFx1Qzc1OCBcdUI4NUNcdUNGMDBcdUM3N0MgXHVDNzc0XHVCOTg0XHVDNzc0IFx1QzU0NFx1QzlDMSBcdUNDOThcdUI5QUNcdUI0MThcdUM5QzAgXHVDNTRBXHVDNTU4XHVDMkI1XHVCMkM4XHVCMkU0ISJ9LAotCi0gIHsgV0dfUFJPUEVSVFlfTk9UX1NVUFBPUlRFRCwKLSAgICAgICJYU0wgXHVDMThEXHVDMTMxXHVDNzc0IFx1QzlDMFx1QzZEMFx1QjQxOFx1QzlDMCBcdUM1NEFcdUM3NEM6IHswfSJ9LAotCi0gIHsgV0dfRE9OVF9ET19BTllUSElOR19XSVRIX05TLAotICAgICAgIlx1QzE4RFx1QzEzMVx1Qzc1OCB7MH0gXHVCMTI0XHVDNzg0XHVDMkE0XHVEMzk4XHVDNzc0XHVDMkE0XHVDNUQwIFx1QjMwMFx1RDU3NCBcdUQ2MDRcdUM3QUMgXHVDNUI0XHVCNUE0IFx1Qzc5MVx1QzVDNVx1QjNDNCBcdUMyMThcdUQ1ODlcdUQ1NThcdUM5QzAgXHVDNTRBXHVDNTQ0XHVDNTdDIFx1RDU2ODogezF9In0sCi0KLSAgeyBXR19TRUNVUklUWV9FWENFUFRJT04sCi0gICAgICAiWFNMIFx1QzJEQ1x1QzJBNFx1RDE1QyBcdUMxOERcdUMxMzFcdUM1RDAgXHVDNTYxXHVDMTM4XHVDMkE0XHVENTU4XHVCODI0XHVBQ0UwIFx1QzJEQ1x1QjNDNFx1RDU1OFx1QjI5NCBcdUM5MTEgU2VjdXJpdHlFeGNlcHRpb24gXHVCQzFDXHVDMEREOiB7MH0ifSwKLQotICB7IFdHX1FVT19OT19MT05HRVJfREVGSU5FRCwKLSAgICAgICJcdUM3NzRcdUM4MDQgXHVBRDZDXHVCQjM4OiBxdW8oLi4uKVx1QUMwMCBYUGF0aFx1QzVEMCBcdUIzNTQgXHVDNzc0XHVDMEMxIFx1QzgxNVx1Qzc1OFx1QjQxOFx1QzVCNCBcdUM3ODhcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gIHsgV0dfTkVFRF9ERVJJVkVEX09CSkVDVF9UT19JTVBMRU1FTlRfTk9ERVRFU1QsCi0gICAgICAibm9kZVRlc3RcdUI5N0MgXHVBRDZDXHVENjA0XHVENTU4XHVCODI0XHVCQTc0IFhQYXRoXHVDNUQwIFx1RDMwQ1x1QzBERCBcdUFDMURcdUNDQjRcdUFDMDAgXHVENTQ0XHVDNjk0XHVENTY5XHVCMkM4XHVCMkU0ISJ9LAotCi0gIHsgV0dfRlVOQ1RJT05fVE9LRU5fTk9UX0ZPVU5ELAotICAgICAgIlx1RDU2OFx1QzIxOCBcdUQxQTBcdUQwNzBcdUM3NDQgXHVDQzNFXHVDNzQ0IFx1QzIxOCBcdUM1QzZcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0KLSAgeyBXR19DT1VMRE5PVF9GSU5EX0ZVTkNUSU9OLAotICAgICAgIlx1RDU2OFx1QzIxOFx1Qjk3QyBcdUNDM0VcdUM3NDQgXHVDMjE4IFx1QzVDNlx1Qzc0QzogezB9In0sCi0KLSAgeyBXR19DQU5OT1RfTUFLRV9VUkxfRlJPTSwKLSAgICAgICJ7MH1cdUM1RDBcdUMxMUMgVVJMXHVDNzQ0IFx1QzBERFx1QzEzMVx1RDU2MCBcdUMyMTggXHVDNUM2XHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gIHsgV0dfRVhQQU5EX0VOVElUSUVTX05PVF9TVVBQT1JURUQsCi0gICAgICAiRFRNIFx1QUQ2Q1x1QkIzOCBcdUJEODRcdUMxMURcdUFFMzBcdUM1RDAgXHVCMzAwXHVENTc0XHVDMTFDXHVCMjk0IC1FIFx1QzYzNVx1QzE1OFx1Qzc3NCBcdUM5QzBcdUM2RDBcdUI0MThcdUM5QzAgXHVDNTRBXHVDMkI1XHVCMkM4XHVCMkU0LiJ9LAotCi0gIHsgV0dfSUxMRUdBTF9WQVJJQUJMRV9SRUZFUkVOQ0UsCi0gICAgICAiXHVCQ0MwXHVDMjE4XHVDNUQwIFx1QjMwMFx1RDU3NCBcdUM4MUNcdUFDRjVcdUI0MUMgVmFyaWFibGVSZWZlcmVuY2VcdUFDMDAgXHVDRUU4XHVEMTREXHVDMkE0XHVEMkI4XHVDNUQwXHVDMTFDIFx1QkM5N1x1QzVCNFx1QjA5OFx1QUM3MFx1QjA5OCBcdUM4MTVcdUM3NThcdUI5N0MgXHVEM0VDXHVENTY4XHVENTU4XHVDOUMwIFx1QzVDNlx1QzJCNVx1QjJDOFx1QjJFNCEgXHVDNzc0XHVCOTg0ID0gezB9In0sCi0KLSAgeyBXR19VTlNVUFBPUlRFRF9FTkNPRElORywKLSAgICAgIlx1QzlDMFx1QzZEMFx1QjQxOFx1QzlDMCBcdUM1NEFcdUIyOTQgXHVDNzc4XHVDRjU0XHVCNTI5OiB7MH0ifSwKLQotCi0KLSAgLy8gT3RoZXIgbWlzY2VsbGFuZW91cyB0ZXh0IHVzZWQgaW5zaWRlIHRoZSBjb2RlLi4uCi0gIHsgInVpX2xhbmd1YWdlIiwgImtvIn0sCi0gIHsgImhlbHBfbGFuZ3VhZ2UiLCAia28ifSwKLSAgeyAibGFuZ3VhZ2UiLCAia28ifSwKLSAgeyAiQkFEX0NPREUiLCAiY3JlYXRlTWVzc2FnZVx1QzVEMCBcdUIzMDBcdUQ1NUMgXHVCOUU0XHVBQzFDXHVCQ0MwXHVDMjE4XHVBQzAwIFx1QkM5NFx1QzcwNFx1Qjk3QyBcdUJDOTdcdUM1QjRcdUIwQUNcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0gIHsgIkZPUk1BVF9GQUlMRUQiLCAibWVzc2FnZUZvcm1hdCBcdUQ2MzhcdUNEOUMgXHVDOTExIFx1QzYwOFx1QzY3OFx1QzBBQ1x1RDU2RFx1Qzc3NCBcdUJDMUNcdUMwRERcdUQ1ODhcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0gIHsgInZlcnNpb24iLCAiPj4+Pj4+PiBYYWxhbiBcdUJDODRcdUM4MDQgIn0sCi0gIHsgInZlcnNpb24yIiwgIjw8PDw8PDwifSwKLSAgeyAieWVzIiwgIlx1QzYwOCJ9LAotICB7ICJsaW5lIiwgIlx1RDU4OSBcdUJDODhcdUQ2MzgifSwKLSAgeyAiY29sdW1uIiwgIlx1QzVGNCBcdUJDODhcdUQ2MzgifSwKLSAgeyAieHNsZG9uZSIsICJYU0xQcm9jZXNzb3I6IFx1QzY0NFx1QjhDQyJ9LAotICB7ICJ4cGF0aF9vcHRpb24iLCAiWFBhdGggXHVDNjM1XHVDMTU4OiAifSwKLSAgeyAib3B0aW9uSU4iLCAiICAgWy1pbiBpbnB1dFhNTFVSTF0ifSwKLSAgeyAib3B0aW9uU2VsZWN0IiwgIiAgIFstc2VsZWN0IFhQYXRoIFx1RDQ1Q1x1RDYwNFx1QzJERF0ifSwKLSAgeyAib3B0aW9uTWF0Y2giLCAiICAgWy1tYXRjaCBcdUM3N0NcdUNFNTggXHVEMzI4XHVEMTM0KFx1Qzc3Q1x1Q0U1OCBcdUM5QzRcdUIyRThcdUM3NTggXHVBQ0JEXHVDNkIwKV0ifSwKLSAgeyAib3B0aW9uQW55RXhwciIsICJcdUI2MTBcdUIyOTQgWFBhdGggXHVENDVDXHVENjA0XHVDMkREXHVDNzc0IFx1QzlDNFx1QjJFOCBcdUIzNjRcdUQ1MDRcdUI5N0MgXHVDMjE4XHVENTg5XHVENTY5XHVCMkM4XHVCMkU0LiJ9LAotICB7ICJub1BhcnNlcm1zZzEiLCAiWFNMIFx1RDUwNFx1Qjg1Q1x1QzEzOFx1QzJBNFx1Qjk3QyBcdUMyRTRcdUQzMjhcdUQ1ODhcdUMyQjVcdUIyQzhcdUIyRTQuIn0sCi0gIHsgIm5vUGFyc2VybXNnMiIsICIqKiBcdUFENkNcdUJCMzggXHVCRDg0XHVDMTFEXHVBRTMwXHVCOTdDIFx1Q0MzRVx1Qzc0NCBcdUMyMTggXHVDNUM2XHVDNzRDICoqIn0sCi0gIHsgIm5vUGFyc2VybXNnMyIsICJcdUQwNzRcdUI3OThcdUMyQTQgXHVBQ0JEXHVCODVDXHVCOTdDIFx1RDY1NVx1Qzc3OFx1RDU1OFx1QzJFRFx1QzJEQ1x1QzYyNC4ifSwKLSAgeyAibm9QYXJzZXJtc2c0IiwgIklCTVx1Qzc1OCBKYXZhXHVDNkE5IFhNTCBcdUFENkNcdUJCMzggXHVCRDg0XHVDMTFEXHVBRTMwXHVBQzAwIFx1QzVDNlx1Qzc0NCBcdUFDQkRcdUM2QjAgXHVCMkU0XHVDNzRDIFx1QzcwNFx1Q0U1OFx1QzVEMFx1QzExQyBcdUIyRTRcdUM2QjRcdUI4NUNcdUI0RENcdUQ1NjAgXHVDMjE4IFx1Qzc4OFx1QzJCNVx1QjJDOFx1QjJFNC4ifSwKLSAgeyAibm9QYXJzZXJtc2c1IiwgIklCTSBBbHBoYVdvcmtzOiBodHRwOi8vd3d3LmFscGhhd29ya3MuaWJtLmNvbS9mb3JtdWxhL3htbCJ9LAotICB7ICJndG9uZSIsICI+MSIgfSwKLSAgeyAiemVybyIsICIwIiB9LAotICB7ICJvbmUiLCAiMSIgfSwKLSAgeyAidHdvIiAsICIyIiB9LAotICB7ICJ0aHJlZSIsICIzIiB9Ci0KLSAgfTsKLQotICAvKioKLSAgICogR2V0IHRoZSBhc3NvY2lhdGlvbiBsaXN0LgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBhc3NvY2lhdGlvbiBsaXN0LgotICAgKi8KLSAgcHVibGljIE9iamVjdFtdW10gZ2V0Q29udGVudHMoKQotICB7Ci0gICAgICByZXR1cm4gX2NvbnRlbnRzOwotICB9Ci0KLQotICAvLyA9PT09PT09PT09PT09PT09PSBJTkZSQVNUUlVDVFVSRSA9PT09PT09PT09PT09PT09PT09PT09Ci0KLSAgLyoqIEZpZWxkIEJBRF9DT0RFICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEJBRF9DT0RFID0gIkJBRF9DT0RFIjsKLQotICAvKiogRmllbGQgRk9STUFUX0ZBSUxFRCAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBGT1JNQVRfRkFJTEVEID0gIkZPUk1BVF9GQUlMRUQiOwotCi0gIC8qKiBGaWVsZCBFUlJPUl9SRVNPVVJDRVMgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJST1JfUkVTT1VSQ0VTID0KLSAgICAiY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLnJlcy5YUEFUSEVycm9yUmVzb3VyY2VzIjsKLQotICAvKiogRmllbGQgRVJST1JfU1RSSU5HICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUk9SX1NUUklORyA9ICIjZXJyb3IiOwotCi0gIC8qKiBGaWVsZCBFUlJPUl9IRUFERVIgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJST1JfSEVBREVSID0gIkVycm9yOiAiOwotCi0gIC8qKiBGaWVsZCBXQVJOSU5HX0hFQURFUiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXQVJOSU5HX0hFQURFUiA9ICJXYXJuaW5nOiAiOwotCi0gIC8qKiBGaWVsZCBYU0xfSEVBREVSICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFhTTF9IRUFERVIgPSAiWFNMICI7Ci0KLSAgLyoqIEZpZWxkIFhNTF9IRUFERVIgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MX0hFQURFUiA9ICJYTUwgIjsKLQotICAvKiogRmllbGQgUVVFUllfSEVBREVSICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFFVRVJZX0hFQURFUiA9ICJQQVRURVJOICI7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvcmVzL1hQQVRIRXJyb3JSZXNvdXJjZXNfcHRfQlIuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvcmVzL1hQQVRIRXJyb3JSZXNvdXJjZXNfcHRfQlIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNjU5ZTc4NC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL3Jlcy9YUEFUSEVycm9yUmVzb3VyY2VzX3B0X0JSLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5MzYgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucmVzOwotCi1pbXBvcnQgamF2YS51dGlsLkxpc3RSZXNvdXJjZUJ1bmRsZTsKLQotLyoqCi0gKiBTZXQgdXAgZXJyb3IgbWVzc2FnZXMuCi0gKiBXZSBidWlsZCBhIHR3byBkaW1lbnNpb25hbCBhcnJheSBvZiBtZXNzYWdlIGtleXMgYW5kCi0gKiBtZXNzYWdlIHN0cmluZ3MuIEluIG9yZGVyIHRvIGFkZCBhIG5ldyBtZXNzYWdlIGhlcmUsCi0gKiB5b3UgbmVlZCB0byBmaXJzdCBhZGQgYSBTdGF0aWMgc3RyaW5nIGNvbnN0YW50IGZvciB0aGUKLSAqIEtleSBhbmQgdXBkYXRlIHRoZSBjb250ZW50cyBhcnJheSB3aXRoIEtleSwgVmFsdWUgcGFpcgotICAqIEFsc28geW91IG5lZWQgdG8gIHVwZGF0ZSB0aGUgY291bnQgb2YgbWVzc2FnZXMoTUFYX0NPREUpb3IKLSAqIHRoZSBjb3VudCBvZiB3YXJuaW5ncyhNQVhfV0FSTklORykgWyBJbmZvcm1hdGlvbiBwdXJwb3NlIG9ubHldCi0gKiBAeHNsLnVzYWdlIGFkdmFuY2VkCi0gKi8KLXB1YmxpYyBjbGFzcyBYUEFUSEVycm9yUmVzb3VyY2VzX3B0X0JSIGV4dGVuZHMgTGlzdFJlc291cmNlQnVuZGxlCi17Ci0KLS8qCi0gKiBHZW5lcmFsIG5vdGVzIHRvIHRyYW5zbGF0b3JzOgotICoKLSAqIFRoaXMgZmlsZSBjb250YWlucyBlcnJvciBhbmQgd2FybmluZyBtZXNzYWdlcyByZWxhdGVkIHRvIFhQYXRoIEVycm9yCi0gKiBIYW5kbGluZy4KLSAqCi0gKiAgMSkgWGFsYW4gKG9yIG1vcmUgcHJvcGVybHksIFhhbGFuLWludGVycHJldGl2ZSkgYW5kIFhTTFRDIGFyZSBuYW1lcyBvZgotICogICAgIGNvbXBvbmVudHMuCi0gKiAgICAgWFNMVCBpcyBhbiBhY3JvbnltIGZvciAiWE1MIFN0eWxlc2hlZXQgTGFuZ3VhZ2U6IFRyYW5zZm9ybWF0aW9ucyIuCi0gKiAgICAgWFNMVEMgaXMgYW4gYWNyb255bSBmb3IgWFNMVCBDb21waWxlci4KLSAqCi0gKiAgMikgQSBzdHlsZXNoZWV0IGlzIGEgZGVzY3JpcHRpb24gb2YgaG93IHRvIHRyYW5zZm9ybSBhbiBpbnB1dCBYTUwgZG9jdW1lbnQKLSAqICAgICBpbnRvIGEgcmVzdWx0YW50IFhNTCBkb2N1bWVudCAob3IgSFRNTCBkb2N1bWVudCBvciB0ZXh0KS4gIFRoZQotICogICAgIHN0eWxlc2hlZXQgaXRzZWxmIGlzIGRlc2NyaWJlZCBpbiB0aGUgZm9ybSBvZiBhbiBYTUwgZG9jdW1lbnQuCi0gKgotICogIDMpIEEgdGVtcGxhdGUgaXMgYSBjb21wb25lbnQgb2YgYSBzdHlsZXNoZWV0IHRoYXQgaXMgdXNlZCB0byBtYXRjaCBhCi0gKiAgICAgcGFydGljdWxhciBwb3J0aW9uIG9mIGFuIGlucHV0IGRvY3VtZW50IGFuZCBzcGVjaWZpZXMgdGhlIGZvcm0gb2YgdGhlCi0gKiAgICAgY29ycmVzcG9uZGluZyBwb3J0aW9uIG9mIHRoZSBvdXRwdXQgZG9jdW1lbnQuCi0gKgotICogIDQpIEFuIGVsZW1lbnQgaXMgYSBtYXJrLXVwIHRhZyBpbiBhbiBYTUwgZG9jdW1lbnQ7IGFuIGF0dHJpYnV0ZSBpcyBhCi0gKiAgICAgbW9kaWZpZXIgb24gdGhlIHRhZy4gIEZvciBleGFtcGxlLCBpbiA8ZWxlbSBhdHRyPSd2YWwnIGF0dHIyPSd2YWwyJz4KLSAqICAgICAiZWxlbSIgaXMgYW4gZWxlbWVudCBuYW1lLCAiYXR0ciIgYW5kICJhdHRyMiIgYXJlIGF0dHJpYnV0ZSBuYW1lcyB3aXRoCi0gKiAgICAgdGhlIHZhbHVlcyAidmFsIiBhbmQgInZhbDIiLCByZXNwZWN0aXZlbHkuCi0gKgotICogIDUpIEEgbmFtZXNwYWNlIGRlY2xhcmF0aW9uIGlzIGEgc3BlY2lhbCBhdHRyaWJ1dGUgdGhhdCBpcyB1c2VkIHRvIGFzc29jaWF0ZQotICogICAgIGEgcHJlZml4IHdpdGggYSBVUkkgKHRoZSBuYW1lc3BhY2UpLiAgVGhlIG1lYW5pbmdzIG9mIGVsZW1lbnQgbmFtZXMgYW5kCi0gKiAgICAgYXR0cmlidXRlIG5hbWVzIHRoYXQgdXNlIHRoYXQgcHJlZml4IGFyZSBkZWZpbmVkIHdpdGggcmVzcGVjdCB0byB0aGF0Ci0gKiAgICAgbmFtZXNwYWNlLgotICoKLSAqICA2KSAiVHJhbnNsZXQiIGlzIGFuIGludmVudGVkIHRlcm0gdGhhdCBkZXNjcmliZXMgdGhlIGNsYXNzIGZpbGUgdGhhdAotICogICAgIHJlc3VsdHMgZnJvbSBjb21waWxpbmcgYW4gWE1MIHN0eWxlc2hlZXQgaW50byBhIEphdmEgY2xhc3MuCi0gKgotICogIDcpIFhQYXRoIGlzIGEgc3BlY2lmaWNhdGlvbiB0aGF0IGRlc2NyaWJlcyBhIG5vdGF0aW9uIGZvciBpZGVudGlmeWluZwotICogICAgIG5vZGVzIGluIGEgdHJlZS1zdHJ1Y3R1cmVkIHJlcHJlc2VudGF0aW9uIG9mIGFuIFhNTCBkb2N1bWVudC4gIEFuCi0gKiAgICAgaW5zdGFuY2Ugb2YgdGhhdCBub3RhdGlvbiBpcyByZWZlcnJlZCB0byBhcyBhbiBYUGF0aCBleHByZXNzaW9uLgotICoKLSAqICA4KSBUaGUgY29udGV4dCBub2RlIGlzIHRoZSBub2RlIGluIHRoZSBkb2N1bWVudCB3aXRoIHJlc3BlY3QgdG8gd2hpY2ggYW4KLSAqICAgICBYUGF0aCBleHByZXNzaW9uIGlzIGJlaW5nIGV2YWx1YXRlZC4KLSAqCi0gKiAgOSkgQW4gaXRlcmF0b3IgaXMgYW4gb2JqZWN0IHRoYXQgdHJhdmVyc2VzIG5vZGVzIGluIHRoZSB0cmVlLCBvbmUgYXQgYSB0aW1lLgotICoKLSAqICAxMCkgTkNOYW1lIGlzIGFuIFhNTCB0ZXJtIHVzZWQgdG8gZGVzY3JpYmUgYSBuYW1lIHRoYXQgZG9lcyBub3QgY29udGFpbiBhCi0gKiAgICAgY29sb24gKGEgIm5vLWNvbG9uIG5hbWUiKS4KLSAqCi0gKiAgMTEpIFFOYW1lIGlzIGFuIFhNTCB0ZXJtIG1lYW5pbmcgInF1YWxpZmllZCBuYW1lIi4KLSAqLwotCi0gIC8qCi0gICAqIHN0YXRpYyB2YXJpYWJsZXMKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUk9SMDAwMCA9ICJFUlJPUjAwMDAiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DVVJSRU5UX05PVF9BTExPV0VEX0lOX01BVENIID0KLSAgICAgICAgICJFUl9DVVJSRU5UX05PVF9BTExPV0VEX0lOX01BVENIIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ1VSUkVOVF9UQUtFU19OT19BUkdTID0KLSAgICAgICAgICJFUl9DVVJSRU5UX1RBS0VTX05PX0FSR1MiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9ET0NVTUVOVF9SRVBMQUNFRCA9ICJFUl9ET0NVTUVOVF9SRVBMQUNFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPTlRFWFRfSEFTX05PX09XTkVSRE9DID0KLSAgICAgICAgICJFUl9DT05URVhUX0hBU19OT19PV05FUkRPQyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0xPQ0FMTkFNRV9IQVNfVE9PX01BTllfQVJHUyA9Ci0gICAgICAgICAiRVJfTE9DQUxOQU1FX0hBU19UT09fTUFOWV9BUkdTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTkFNRVNQQUNFVVJJX0hBU19UT09fTUFOWV9BUkdTID0KLSAgICAgICAgICJFUl9OQU1FU1BBQ0VVUklfSEFTX1RPT19NQU5ZX0FSR1MiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT1JNQUxJWkVTUEFDRV9IQVNfVE9PX01BTllfQVJHUyA9Ci0gICAgICAgICAiRVJfTk9STUFMSVpFU1BBQ0VfSEFTX1RPT19NQU5ZX0FSR1MiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OVU1CRVJfSEFTX1RPT19NQU5ZX0FSR1MgPQotICAgICAgICAgIkVSX05VTUJFUl9IQVNfVE9PX01BTllfQVJHUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05BTUVfSEFTX1RPT19NQU5ZX0FSR1MgPQotICAgICAgICAgIkVSX05BTUVfSEFTX1RPT19NQU5ZX0FSR1MiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TVFJJTkdfSEFTX1RPT19NQU5ZX0FSR1MgPQotICAgICAgICAgIkVSX1NUUklOR19IQVNfVE9PX01BTllfQVJHUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NUUklOR0xFTkdUSF9IQVNfVE9PX01BTllfQVJHUyA9Ci0gICAgICAgICAiRVJfU1RSSU5HTEVOR1RIX0hBU19UT09fTUFOWV9BUkdTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVFJBTlNMQVRFX1RBS0VTXzNfQVJHUyA9Ci0gICAgICAgICAiRVJfVFJBTlNMQVRFX1RBS0VTXzNfQVJHUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1VOUEFSU0VERU5USVRZVVJJX1RBS0VTXzFfQVJHID0KLSAgICAgICAgICJFUl9VTlBBUlNFREVOVElUWVVSSV9UQUtFU18xX0FSRyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05BTUVTUEFDRUFYSVNfTk9UX0lNUExFTUVOVEVEID0KLSAgICAgICAgICJFUl9OQU1FU1BBQ0VBWElTX05PVF9JTVBMRU1FTlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1VOS05PV05fQVhJUyA9ICJFUl9VTktOT1dOX0FYSVMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTktOT1dOX01BVENIX09QRVJBVElPTiA9Ci0gICAgICAgICAiRVJfVU5LTk9XTl9NQVRDSF9PUEVSQVRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTkNPUlJFQ1RfQVJHX0xFTkdUSCA9IkVSX0lOQ09SUkVDVF9BUkdfTEVOR1RIIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9DT05WRVJUX1RPX05VTUJFUiA9Ci0gICAgICAgICAiRVJfQ0FOVF9DT05WRVJUX1RPX05VTUJFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfQ09OVkVSVF9YUEFUSFJFU1VMVFRZUEVfVE9fTlVNQkVSID0KLSAgICAgICAgICAgIkVSX0NBTlRfQ09OVkVSVF9YUEFUSFJFU1VMVFRZUEVfVE9fTlVNQkVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9DT05WRVJUX1RPX05PREVMSVNUID0KLSAgICAgICAgICJFUl9DQU5UX0NPTlZFUlRfVE9fTk9ERUxJU1QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX0NPTlZFUlRfVE9fTVVUQUJMRU5PREVMSVNUID0KLSAgICAgICAgICJFUl9DQU5UX0NPTlZFUlRfVE9fTVVUQUJMRU5PREVMSVNUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9DT05WRVJUX1RPX1RZUEUgPSJFUl9DQU5UX0NPTlZFUlRfVE9fVFlQRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYUEVDVEVEX01BVENIX1BBVFRFUk4gPQotICAgICAgICAgIkVSX0VYUEVDVEVEX01BVENIX1BBVFRFUk4iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRE5PVF9HRVRfVkFSX05BTUVEID0KLSAgICAgICAgICJFUl9DT1VMRE5PVF9HRVRfVkFSX05BTUVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5LTk9XTl9PUENPREUgPSAiRVJfVU5LTk9XTl9PUENPREUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FWFRSQV9JTExFR0FMX1RPS0VOUyA9IkVSX0VYVFJBX0lMTEVHQUxfVE9LRU5TIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhQRUNURURfRE9VQkxFX1FVT1RFID0KLSAgICAgICAgICJFUl9FWFBFQ1RFRF9ET1VCTEVfUVVPVEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FWFBFQ1RFRF9TSU5HTEVfUVVPVEUgPQotICAgICAgICAgIkVSX0VYUEVDVEVEX1NJTkdMRV9RVU9URSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VNUFRZX0VYUFJFU1NJT04gPSAiRVJfRU1QVFlfRVhQUkVTU0lPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYUEVDVEVEX0JVVF9GT1VORCA9ICJFUl9FWFBFQ1RFRF9CVVRfRk9VTkQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTkNPUlJFQ1RfUFJPR1JBTU1FUl9BU1NFUlRJT04gPQotICAgICAgICAgIkVSX0lOQ09SUkVDVF9QUk9HUkFNTUVSX0FTU0VSVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0JPT0xFQU5fQVJHX05PX0xPTkdFUl9PUFRJT05BTCA9Ci0gICAgICAgICAiRVJfQk9PTEVBTl9BUkdfTk9fTE9OR0VSX09QVElPTkFMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRk9VTkRfQ09NTUFfQlVUX05PX1BSRUNFRElOR19BUkcgPQotICAgICAgICAgIkVSX0ZPVU5EX0NPTU1BX0JVVF9OT19QUkVDRURJTkdfQVJHIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRk9VTkRfQ09NTUFfQlVUX05PX0ZPTExPV0lOR19BUkcgPQotICAgICAgICAgIkVSX0ZPVU5EX0NPTU1BX0JVVF9OT19GT0xMT1dJTkdfQVJHIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJFRElDQVRFX0lMTEVHQUxfU1lOVEFYID0KLSAgICAgICAgICJFUl9QUkVESUNBVEVfSUxMRUdBTF9TWU5UQVgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTExFR0FMX0FYSVNfTkFNRSA9ICJFUl9JTExFR0FMX0FYSVNfTkFNRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1VOS05PV05fTk9ERVRZUEUgPSAiRVJfVU5LTk9XTl9OT0RFVFlQRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BBVFRFUk5fTElURVJBTF9ORUVEU19CRV9RVU9URUQgPQotICAgICAgICAgIkVSX1BBVFRFUk5fTElURVJBTF9ORUVEU19CRV9RVU9URUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRE5PVF9CRV9GT1JNQVRURURfVE9fTlVNQkVSID0KLSAgICAgICAgICJFUl9DT1VMRE5PVF9CRV9GT1JNQVRURURfVE9fTlVNQkVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTEROT1RfQ1JFQVRFX1hNTFBST0NFU1NPUkxJQUlTT04gPQotICAgICAgICAgIkVSX0NPVUxETk9UX0NSRUFURV9YTUxQUk9DRVNTT1JMSUFJU09OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRElETk9UX0ZJTkRfWFBBVEhfU0VMRUNUX0VYUCA9Ci0gICAgICAgICAiRVJfRElETk9UX0ZJTkRfWFBBVEhfU0VMRUNUX0VYUCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxETk9UX0ZJTkRfRU5ET1BfQUZURVJfT1BMT0NBVElPTlBBVEggPQotICAgICAgICAgIkVSX0NPVUxETk9UX0ZJTkRfRU5ET1BfQUZURVJfT1BMT0NBVElPTlBBVEgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FUlJPUl9PQ0NVUkVEID0gIkVSX0VSUk9SX09DQ1VSRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTExFR0FMX1ZBUklBQkxFX1JFRkVSRU5DRSA9Ci0gICAgICAgICAiRVJfSUxMRUdBTF9WQVJJQUJMRV9SRUZFUkVOQ0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9BWEVTX05PVF9BTExPV0VEID0gIkVSX0FYRVNfTk9UX0FMTE9XRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9LRVlfSEFTX1RPT19NQU5ZX0FSR1MgPQotICAgICAgICAgIkVSX0tFWV9IQVNfVE9PX01BTllfQVJHUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVU5UX1RBS0VTXzFfQVJHID0gIkVSX0NPVU5UX1RBS0VTXzFfQVJHIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTEROT1RfRklORF9GVU5DVElPTiA9Ci0gICAgICAgICAiRVJfQ09VTEROT1RfRklORF9GVU5DVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1VOU1VQUE9SVEVEX0VOQ09ESU5HID0iRVJfVU5TVVBQT1JURURfRU5DT0RJTkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUk9CTEVNX0lOX0RUTV9ORVhUU0lCTElORyA9Ci0gICAgICAgICAiRVJfUFJPQkxFTV9JTl9EVE1fTkVYVFNJQkxJTkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfV1JJVEVfVE9fRU1QVFlOT0RFTElTVElNUEwgPQotICAgICAgICAgIkVSX0NBTk5PVF9XUklURV9UT19FTVBUWU5PREVMSVNUSU1QTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NFVERPTUZBQ1RPUllfTk9UX1NVUFBPUlRFRCA9Ci0gICAgICAgICAiRVJfU0VURE9NRkFDVE9SWV9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJFRklYX01VU1RfUkVTT0xWRSA9ICJFUl9QUkVGSVhfTVVTVF9SRVNPTFZFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUEFSU0VfTk9UX1NVUFBPUlRFRCA9ICJFUl9QQVJTRV9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU0FYX0FQSV9OT1RfSEFORExFRCA9ICJFUl9TQVhfQVBJX05PVF9IQU5ETEVEIjsKLXB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lHTk9SQUJMRV9XSElURVNQQUNFX05PVF9IQU5ETEVEID0KLSAgICAgICAgICJFUl9JR05PUkFCTEVfV0hJVEVTUEFDRV9OT1RfSEFORExFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0RUTV9DQU5OT1RfSEFORExFX05PREVTID0KLSAgICAgICAgICJFUl9EVE1fQ0FOTk9UX0hBTkRMRV9OT0RFUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hFUkNFU19DQU5OT1RfSEFORExFX05PREVTID0KLSAgICAgICAgICJFUl9YRVJDRVNfQ0FOTk9UX0hBTkRMRV9OT0RFUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hFUkNFU19QQVJTRV9FUlJPUl9ERVRBSUxTID0KLSAgICAgICAgICJFUl9YRVJDRVNfUEFSU0VfRVJST1JfREVUQUlMUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hFUkNFU19QQVJTRV9FUlJPUiA9ICJFUl9YRVJDRVNfUEFSU0VfRVJST1IiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX1VURjE2X1NVUlJPR0FURSA9Ci0gICAgICAgICAiRVJfSU5WQUxJRF9VVEYxNl9TVVJST0dBVEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9PSUVSUk9SID0gIkVSX09JRVJST1IiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfQ1JFQVRFX1VSTCA9ICJFUl9DQU5OT1RfQ1JFQVRFX1VSTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hQQVRIX1JFQURPQkpFQ1QgPSAiRVJfWFBBVEhfUkVBRE9CSkVDVCI7Ci0gcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRlVOQ1RJT05fVE9LRU5fTk9UX0ZPVU5EID0KLSAgICAgICAgICJFUl9GVU5DVElPTl9UT0tFTl9OT1RfRk9VTkQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfREVBTF9YUEFUSF9UWVBFID0KLSAgICAgICAgICJFUl9DQU5OT1RfREVBTF9YUEFUSF9UWVBFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9ERVNFVF9OT1RfTVVUQUJMRSA9ICJFUl9OT0RFU0VUX05PVF9NVVRBQkxFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9ERVNFVERUTV9OT1RfTVVUQUJMRSA9Ci0gICAgICAgICAiRVJfTk9ERVNFVERUTV9OT1RfTVVUQUJMRSI7Ci0gICAvKiogIFZhcmlhYmxlIG5vdCByZXNvbHZhYmxlOiAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1ZBUl9OT1RfUkVTT0xWQUJMRSA9ICJFUl9WQVJfTk9UX1JFU09MVkFCTEUiOwotICAgLyoqIE51bGwgZXJyb3IgaGFuZGxlciAgKi8KLSBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OVUxMX0VSUk9SX0hBTkRMRVIgPSAiRVJfTlVMTF9FUlJPUl9IQU5ETEVSIjsKLSAgIC8qKiAgUHJvZ3JhbW1lcidzIGFzc2VydGlvbjogdW5rbm93biBvcGNvZGUgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BST0dfQVNTRVJUX1VOS05PV05fT1BDT0RFID0KLSAgICAgICAgICJFUl9QUk9HX0FTU0VSVF9VTktOT1dOX09QQ09ERSI7Ci0gICAvKiogIDAgb3IgMSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1pFUk9fT1JfT05FID0gIkVSX1pFUk9fT1JfT05FIjsKLSAgIC8qKiAgcnRmKCkgbm90IHN1cHBvcnRlZCBieSBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1JURl9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSID0KLSAgICAgICAgICJFUl9SVEZfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiI7Ci0gICAvKiogIGFzTm9kZUl0ZXJhdG9yKCkgbm90IHN1cHBvcnRlZCBieSBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FTTk9ERUlURVJBVE9SX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIgPSAiRVJfQVNOT0RFSVRFUkFUT1JfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiI7Ci0gICAvKiogIGZzYigpIG5vdCBzdXBwb3J0ZWQgZm9yIFhTdHJpbmdGb3JDaGFycyAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZTQl9OT1RfU1VQUE9SVEVEX1hTVFJJTkdGT1JDSEFSUyA9Ci0gICAgICAgICAiRVJfRlNCX05PVF9TVVBQT1JURURfWFNUUklOR0ZPUkNIQVJTIjsKLSAgIC8qKiAgQ291bGQgbm90IGZpbmQgdmFyaWFibGUgd2l0aCB0aGUgbmFtZSBvZiAgICovCi0gcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTERfTk9UX0ZJTkRfVkFSID0gIkVSX0NPVUxEX05PVF9GSU5EX1ZBUiI7Ci0gICAvKiogIFhTdHJpbmdGb3JDaGFycyBjYW4gbm90IHRha2UgYSBzdHJpbmcgZm9yIGFuIGFyZ3VtZW50ICAgKi8KLSBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YU1RSSU5HRk9SQ0hBUlNfQ0FOTk9UX1RBS0VfU1RSSU5HID0KLSAgICAgICAgICJFUl9YU1RSSU5HRk9SQ0hBUlNfQ0FOTk9UX1RBS0VfU1RSSU5HIjsKLSAgIC8qKiAgVGhlIEZhc3RTdHJpbmdCdWZmZXIgYXJndW1lbnQgY2FuIG5vdCBiZSBudWxsICAgKi8KLSBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GQVNUU1RSSU5HQlVGRkVSX0NBTk5PVF9CRV9OVUxMID0KLSAgICAgICAgICJFUl9GQVNUU1RSSU5HQlVGRkVSX0NBTk5PVF9CRV9OVUxMIjsKLSAgIC8qKiAgMiBvciAzICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVFdPX09SX1RIUkVFID0gIkVSX1RXT19PUl9USFJFRSI7Ci0gICAvKiogVmFyaWFibGUgYWNjZXNzZWQgYmVmb3JlIGl0IGlzIGJvdW5kISAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9WQVJJQUJMRV9BQ0NFU1NFRF9CRUZPUkVfQklORCA9Ci0gICAgICAgICAiRVJfVkFSSUFCTEVfQUNDRVNTRURfQkVGT1JFX0JJTkQiOwotICAgLyoqIFhTdHJpbmdGb3JGU0IgY2FuIG5vdCB0YWtlIGEgc3RyaW5nIGZvciBhbiBhcmd1bWVudCEgKi8KLSBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GU0JfQ0FOTk9UX1RBS0VfU1RSSU5HID0KLSAgICAgICAgICJFUl9GU0JfQ0FOTk9UX1RBS0VfU1RSSU5HIjsKLSAgIC8qKiBFcnJvciEgU2V0dGluZyB0aGUgcm9vdCBvZiBhIHdhbGtlciB0byBudWxsISAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TRVRUSU5HX1dBTEtFUl9ST09UX1RPX05VTEwgPQotICAgICAgICAgIkVSX1NFVFRJTkdfV0FMS0VSX1JPT1RfVE9fTlVMTCI7Ci0gICAvKiogVGhpcyBOb2RlU2V0RFRNIGNhbiBub3QgaXRlcmF0ZSB0byBhIHByZXZpb3VzIG5vZGUhICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PREVTRVREVE1fQ0FOTk9UX0lURVJBVEUgPQotICAgICAgICAgIkVSX05PREVTRVREVE1fQ0FOTk9UX0lURVJBVEUiOwotICAvKiogVGhpcyBOb2RlU2V0IGNhbiBub3QgaXRlcmF0ZSB0byBhIHByZXZpb3VzIG5vZGUhICovCi0gcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9ERVNFVF9DQU5OT1RfSVRFUkFURSA9Ci0gICAgICAgICAiRVJfTk9ERVNFVF9DQU5OT1RfSVRFUkFURSI7Ci0gIC8qKiBUaGlzIE5vZGVTZXREVE0gY2FuIG5vdCBkbyBpbmRleGluZyBvciBjb3VudGluZyBmdW5jdGlvbnMhICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PREVTRVREVE1fQ0FOTk9UX0lOREVYID0KLSAgICAgICAgICJFUl9OT0RFU0VURFRNX0NBTk5PVF9JTkRFWCI7Ci0gIC8qKiBUaGlzIE5vZGVTZXQgY2FuIG5vdCBkbyBpbmRleGluZyBvciBjb3VudGluZyBmdW5jdGlvbnMhICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PREVTRVRfQ0FOTk9UX0lOREVYID0KLSAgICAgICAgICJFUl9OT0RFU0VUX0NBTk5PVF9JTkRFWCI7Ci0gIC8qKiBDYW4gbm90IGNhbGwgc2V0U2hvdWxkQ2FjaGVOb2RlcyBhZnRlciBuZXh0Tm9kZSBoYXMgYmVlbiBjYWxsZWQhICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9DQUxMX1NFVFNIT1VMRENBQ0hFTk9ERSA9Ci0gICAgICAgICAiRVJfQ0FOTk9UX0NBTExfU0VUU0hPVUxEQ0FDSEVOT0RFIjsKLSAgLyoqIHswfSBvbmx5IGFsbG93cyB7MX0gYXJndW1lbnRzICovCi0gcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfT05MWV9BTExPV1MgPSAiRVJfT05MWV9BTExPV1MiOwotICAvKiogUHJvZ3JhbW1lcidzIGFzc2VydGlvbiBpbiBnZXROZXh0U3RlcFBvczogdW5rbm93biBzdGVwVHlwZTogezB9ICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1VOS05PV05fU1RFUCA9ICJFUl9VTktOT1dOX1NURVAiOwotICAvKiogUHJvYmxlbSB3aXRoIFJlbGF0aXZlTG9jYXRpb25QYXRoICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYUEVDVEVEX1JFTF9MT0NfUEFUSCA9Ci0gICAgICAgICAiRVJfRVhQRUNURURfUkVMX0xPQ19QQVRIIjsKLSAgLyoqIFByb2JsZW0gd2l0aCBMb2NhdGlvblBhdGggKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhQRUNURURfTE9DX1BBVEggPSAiRVJfRVhQRUNURURfTE9DX1BBVEgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FWFBFQ1RFRF9MT0NfUEFUSF9BVF9FTkRfRVhQUiA9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkVSX0VYUEVDVEVEX0xPQ19QQVRIX0FUX0VORF9FWFBSIjsKLSAgLyoqIFByb2JsZW0gd2l0aCBTdGVwICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYUEVDVEVEX0xPQ19TVEVQID0gIkVSX0VYUEVDVEVEX0xPQ19TVEVQIjsKLSAgLyoqIFByb2JsZW0gd2l0aCBOb2RlVGVzdCAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FWFBFQ1RFRF9OT0RFX1RFU1QgPSAiRVJfRVhQRUNURURfTk9ERV9URVNUIjsKLSAgLyoqIEV4cGVjdGVkIHN0ZXAgcGF0dGVybiAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FWFBFQ1RFRF9TVEVQX1BBVFRFUk4gPQotICAgICAgICAiRVJfRVhQRUNURURfU1RFUF9QQVRURVJOIjsKLSAgLyoqIEV4cGVjdGVkIHJlbGF0aXZlIHBhdGggcGF0dGVybiAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FWFBFQ1RFRF9SRUxfUEFUSF9QQVRURVJOID0KLSAgICAgICAgICJFUl9FWFBFQ1RFRF9SRUxfUEFUSF9QQVRURVJOIjsKLSAgLyoqIEVSX0NBTlRfQ09OVkVSVF9YUEFUSFJFU1VMVFRZUEVfVE9fQk9PTEVBTiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX0NPTlZFUlRfVE9fQk9PTEVBTiA9Ci0gICAgICAgICAiRVJfQ0FOVF9DT05WRVJUX1RPX0JPT0xFQU4iOwotICAvKiogRmllbGQgRVJfQ0FOVF9DT05WRVJUX1RPX1NJTkdMRU5PREUgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9DT05WRVJUX1RPX1NJTkdMRU5PREUgPQotICAgICAgICAgIkVSX0NBTlRfQ09OVkVSVF9UT19TSU5HTEVOT0RFIjsKLSAgLyoqIEZpZWxkIEVSX0NBTlRfR0VUX1NOQVBTSE9UX0xFTkdUSCAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfR0VUX1NOQVBTSE9UX0xFTkdUSCA9Ci0gICAgICAgICAiRVJfQ0FOVF9HRVRfU05BUFNIT1RfTEVOR1RIIjsKLSAgLyoqIEZpZWxkIEVSX05PTl9JVEVSQVRPUl9UWVBFICAgICAgICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PTl9JVEVSQVRPUl9UWVBFID0gIkVSX05PTl9JVEVSQVRPUl9UWVBFIjsKLSAgLyoqIEZpZWxkIEVSX0RPQ19NVVRBVEVEICAgICAgICAgICAgICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0RPQ19NVVRBVEVEID0gIkVSX0RPQ19NVVRBVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9YUEFUSF9UWVBFID0gIkVSX0lOVkFMSURfWFBBVEhfVFlQRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VNUFRZX1hQQVRIX1JFU1VMVCA9ICJFUl9FTVBUWV9YUEFUSF9SRVNVTFQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTkNPTVBBVElCTEVfVFlQRVMgPSAiRVJfSU5DT01QQVRJQkxFX1RZUEVTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTlVMTF9SRVNPTFZFUiA9ICJFUl9OVUxMX1JFU09MVkVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9DT05WRVJUX1RPX1NUUklORyA9Ci0gICAgICAgICAiRVJfQ0FOVF9DT05WRVJUX1RPX1NUUklORyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PTl9TTkFQU0hPVF9UWVBFID0gIkVSX05PTl9TTkFQU0hPVF9UWVBFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfV1JPTkdfRE9DVU1FTlQgPSAiRVJfV1JPTkdfRE9DVU1FTlQiOwotICAvKiBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIFhQYXRoIGV4cHJlc3Npb24gY2Fubm90IGJlIGV2YWx1YXRlZCB3aXRoIHJlc3BlY3QKLSAgICogdG8gdGhpcyB0eXBlIG9mIG5vZGUuCi0gICAqLwotICAvKiogRmllbGQgRVJfV1JPTkdfTk9ERVRZUEUgICAgICAgICAgICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1dST05HX05PREVUWVBFID0gIkVSX1dST05HX05PREVUWVBFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWFBBVEhfRVJST1IgPSAiRVJfWFBBVEhfRVJST1IiOwotCi0gIC8vQkVHSU46IEtleXMgbmVlZGVkIGZvciBleGNlcHRpb24gbWVzc2FnZXMgb2YgIEpBWFAgMS4zIFhQYXRoIEFQSSBpbXBsZW1lbnRhdGlvbgotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FWFRFTlNJT05fRlVOQ1RJT05fQ0FOTk9UX0JFX0lOVk9LRUQgPSAiRVJfRVhURU5TSU9OX0ZVTkNUSU9OX0NBTk5PVF9CRV9JTlZPS0VEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUkVTT0xWRV9WQVJJQUJMRV9SRVRVUk5TX05VTEwgPSAiRVJfUkVTT0xWRV9WQVJJQUJMRV9SRVRVUk5TX05VTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTlNVUFBPUlRFRF9SRVRVUk5fVFlQRSA9ICJFUl9VTlNVUFBPUlRFRF9SRVRVUk5fVFlQRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NPVVJDRV9SRVRVUk5fVFlQRV9DQU5OT1RfQkVfTlVMTCA9ICJFUl9TT1VSQ0VfUkVUVVJOX1RZUEVfQ0FOTk9UX0JFX05VTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9BUkdfQ0FOTk9UX0JFX05VTEwgPSAiRVJfQVJHX0NBTk5PVF9CRV9OVUxMIjsKLQotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9PQkpFQ1RfTU9ERUxfTlVMTCA9ICJFUl9PQkpFQ1RfTU9ERUxfTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX09CSkVDVF9NT0RFTF9FTVBUWSA9ICJFUl9PQkpFQ1RfTU9ERUxfRU1QVFkiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GRUFUVVJFX05BTUVfTlVMTCA9ICJFUl9GRUFUVVJFX05BTUVfTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZFQVRVUkVfVU5LTk9XTiA9ICJFUl9GRUFUVVJFX1VOS05PV04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9HRVRUSU5HX05VTExfRkVBVFVSRSA9ICJFUl9HRVRUSU5HX05VTExfRkVBVFVSRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0dFVFRJTkdfVU5LTk9XTl9GRUFUVVJFID0gIkVSX0dFVFRJTkdfVU5LTk9XTl9GRUFUVVJFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU0VDVVJFUFJPQ0VTU0lOR19GRUFUVVJFID0gIkVSX1NFQ1VSRVBST0NFU1NJTkdfRkVBVFVSRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05VTExfWFBBVEhfRlVOQ1RJT05fUkVTT0xWRVIgPSAiRVJfTlVMTF9YUEFUSF9GVU5DVElPTl9SRVNPTFZFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05VTExfWFBBVEhfVkFSSUFCTEVfUkVTT0xWRVIgPSAiRVJfTlVMTF9YUEFUSF9WQVJJQUJMRV9SRVNPTFZFUiI7Ci0gIC8vRU5EOiBLZXlzIG5lZWRlZCBmb3IgZXhjZXB0aW9uIG1lc3NhZ2VzIG9mICBKQVhQIDEuMyBYUGF0aCBBUEkgaW1wbGVtZW50YXRpb24KLQotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19MT0NBTEVfTkFNRV9OT1RfSEFORExFRCA9Ci0gICAgICAgICAiV0dfTE9DQUxFX05BTUVfTk9UX0hBTkRMRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19QUk9QRVJUWV9OT1RfU1VQUE9SVEVEID0KLSAgICAgICAgICJXR19QUk9QRVJUWV9OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfRE9OVF9ET19BTllUSElOR19XSVRIX05TID0KLSAgICAgICAgICJXR19ET05UX0RPX0FOWVRISU5HX1dJVEhfTlMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19TRUNVUklUWV9FWENFUFRJT04gPSAiV0dfU0VDVVJJVFlfRVhDRVBUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfUVVPX05PX0xPTkdFUl9ERUZJTkVEID0KLSAgICAgICAgICJXR19RVU9fTk9fTE9OR0VSX0RFRklORUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19ORUVEX0RFUklWRURfT0JKRUNUX1RPX0lNUExFTUVOVF9OT0RFVEVTVCA9Ci0gICAgICAgICAiV0dfTkVFRF9ERVJJVkVEX09CSkVDVF9UT19JTVBMRU1FTlRfTk9ERVRFU1QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19GVU5DVElPTl9UT0tFTl9OT1RfRk9VTkQgPQotICAgICAgICAgIldHX0ZVTkNUSU9OX1RPS0VOX05PVF9GT1VORCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0NPVUxETk9UX0ZJTkRfRlVOQ1RJT04gPQotICAgICAgICAgIldHX0NPVUxETk9UX0ZJTkRfRlVOQ1RJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19DQU5OT1RfTUFLRV9VUkxfRlJPTSA9IldHX0NBTk5PVF9NQUtFX1VSTF9GUk9NIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfRVhQQU5EX0VOVElUSUVTX05PVF9TVVBQT1JURUQgPQotICAgICAgICAgIldHX0VYUEFORF9FTlRJVElFU19OT1RfU1VQUE9SVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfSUxMRUdBTF9WQVJJQUJMRV9SRUZFUkVOQ0UgPQotICAgICAgICAgIldHX0lMTEVHQUxfVkFSSUFCTEVfUkVGRVJFTkNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfVU5TVVBQT1JURURfRU5DT0RJTkcgPSJXR19VTlNVUFBPUlRFRF9FTkNPRElORyI7Ci0KLSAgLyoqICBkZXRhY2goKSBub3Qgc3VwcG9ydGVkIGJ5IFhSVHJlZUZyYWdTZWxlY3RXcmFwcGVyICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfREVUQUNIX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIgPQotICAgICAgICAgIkVSX0RFVEFDSF9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSIjsKLSAgLyoqICBudW0oKSBub3Qgc3VwcG9ydGVkIGJ5IFhSVHJlZUZyYWdTZWxlY3RXcmFwcGVyICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTlVNX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIgPQotICAgICAgICAgIkVSX05VTV9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSIjsKLSAgLyoqICB4c3RyKCkgbm90IHN1cHBvcnRlZCBieSBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hTVFJfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiA9Ci0gICAgICAgICAiRVJfWFNUUl9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSIjsKLSAgLyoqICBzdHIoKSBub3Qgc3VwcG9ydGVkIGJ5IFhSVHJlZUZyYWdTZWxlY3RXcmFwcGVyICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU1RSX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIgPQotICAgICAgICAgIkVSX1NUUl9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSIjsKLQotICAvLyBFcnJvciBtZXNzYWdlcy4uLgotCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIE9iamVjdFtdW10gX2NvbnRlbnRzID0gbmV3IE9iamVjdFtdW117Ci0KLSAgeyAiRVJST1IwMDAwIiAsICJ7MH0iIH0sCi0KLSAgeyBFUl9DVVJSRU5UX05PVF9BTExPV0VEX0lOX01BVENILCAiQSBmdW5cdTAwRTdcdTAwRTNvIGN1cnJlbnQoKSBuXHUwMEUzbyBcdTAwRTkgcGVybWl0aWRhIGVtIHVtIHBhZHJcdTAwRTNvIGRlIGNvcnJlc3BvbmRcdTAwRUFuY2lhISIgfSwKLQotICB7IEVSX0NVUlJFTlRfVEFLRVNfTk9fQVJHUywgIkEgZnVuXHUwMEU3XHUwMEUzbyBjdXJyZW50KCkgblx1MDBFM28gYWNlaXRhIGFyZ3VtZW50b3MhIiB9LAotCi0gIHsgRVJfRE9DVU1FTlRfUkVQTEFDRUQsCi0gICAgICAiYSBpbXBsZW1lbnRhXHUwMEU3XHUwMEUzbyBkYSBmdW5cdTAwRTdcdTAwRTNvIGRvY3VtZW50KCkgZm9pIHN1YnN0aXR1XHUwMEVEZGEgcG9yIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0LkZ1bmNEb2N1bWVudCEifSwKLQotICB7IEVSX0NPTlRFWFRfSEFTX05PX09XTkVSRE9DLAotICAgICAgIm8gY29udGV4dG8gblx1MDBFM28gdGVtIHVtIGRvY3VtZW50byBkZSBwcm9wcmlldFx1MDBFMXJpbyEifSwKLQotICB7IEVSX0xPQ0FMTkFNRV9IQVNfVE9PX01BTllfQVJHUywKLSAgICAgICJsb2NhbC1uYW1lKCkgdGVtIG11aXRvcyBhcmd1bWVudG9zLiJ9LAotCi0gIHsgRVJfTkFNRVNQQUNFVVJJX0hBU19UT09fTUFOWV9BUkdTLAotICAgICAgIm5hbWVzcGFjZS11cmkoKSB0ZW0gbXVpdG9zIGFyZ3VtZW50b3MuIn0sCi0KLSAgeyBFUl9OT1JNQUxJWkVTUEFDRV9IQVNfVE9PX01BTllfQVJHUywKLSAgICAgICJub3JtYWxpemUtc3BhY2UoKSB0ZW0gbXVpdG9zIGFyZ3VtZW50b3MuIn0sCi0KLSAgeyBFUl9OVU1CRVJfSEFTX1RPT19NQU5ZX0FSR1MsCi0gICAgICAibnVtYmVyKCkgdGVtIG11aXRvcyBhcmd1bWVudG9zLiJ9LAotCi0gIHsgRVJfTkFNRV9IQVNfVE9PX01BTllfQVJHUywKLSAgICAgIm5hbWUoKSB0ZW0gbXVpdG9zIGFyZ3VtZW50b3MuIn0sCi0KLSAgeyBFUl9TVFJJTkdfSEFTX1RPT19NQU5ZX0FSR1MsCi0gICAgICAic3RyaW5nKCkgdGVtIG11aXRvcyBhcmd1bWVudG9zLiJ9LAotCi0gIHsgRVJfU1RSSU5HTEVOR1RIX0hBU19UT09fTUFOWV9BUkdTLAotICAgICAgInN0cmluZy1sZW5ndGgoKSB0ZW0gbXVpdG9zIGFyZ3VtZW50b3MuIn0sCi0KLSAgeyBFUl9UUkFOU0xBVEVfVEFLRVNfM19BUkdTLAotICAgICAgIkEgZnVuXHUwMEU3XHUwMEUzbyB0cmFuc2xhdGUoKSB0ZW0gdHJcdTAwRUFzIGFyZ3VtZW50b3MhIn0sCi0KLSAgeyBFUl9VTlBBUlNFREVOVElUWVVSSV9UQUtFU18xX0FSRywKLSAgICAgICJBIGZ1blx1MDBFN1x1MDBFM28gdW5wYXJzZWQtZW50aXR5LXVyaSBkZXZlIHRlciB1bSBhcmd1bWVudG8hIn0sCi0KLSAgeyBFUl9OQU1FU1BBQ0VBWElTX05PVF9JTVBMRU1FTlRFRCwKLSAgICAgICJvIGVpeG8gZG8gbmFtZXNwYWNlIGFpbmRhIG5cdTAwRTNvIGZvaSBpbXBsZW1lbnRhZG8hIn0sCi0KLSAgeyBFUl9VTktOT1dOX0FYSVMsCi0gICAgICJlaXhvIGRlc2NvbmhlY2lkbzogezB9In0sCi0KLSAgeyBFUl9VTktOT1dOX01BVENIX09QRVJBVElPTiwKLSAgICAgIk9wZXJhXHUwMEU3XHUwMEUzbyBjb3JyZXNwb25kZW50ZSBkZXNjb25oZWNpZGEhIn0sCi0KLSAgeyBFUl9JTkNPUlJFQ1RfQVJHX0xFTkdUSCwKLSAgICAgICJPIHRhbWFuaG8gZG8gYXJndW1lbnRvIGRvIHRlc3RlIGRlIG5cdTAwRjMgZGUgcHJvY2Vzc2luZy1pbnN0cnVjdGlvbigpIGVzdFx1MDBFMSBpbmNvcnJldG8hIn0sCi0KLSAgeyBFUl9DQU5UX0NPTlZFUlRfVE9fTlVNQkVSLAotICAgICAgIk5cdTAwRTNvIFx1MDBFOSBwb3NzXHUwMEVEdmVsIGNvbnZlcnRlciB7MH0gZW0gdW0gblx1MDBGQW1lcm8ifSwKLQotICB7IEVSX0NBTlRfQ09OVkVSVF9UT19OT0RFTElTVCwKLSAgICAgICJOXHUwMEUzbyBcdTAwRTkgcG9zc1x1MDBFRHZlbCBjb252ZXJ0ZXIgezB9IGVtIHVtYSBOb2RlTGlzdCEifSwKLQotICB7IEVSX0NBTlRfQ09OVkVSVF9UT19NVVRBQkxFTk9ERUxJU1QsCi0gICAgICAiTlx1MDBFM28gXHUwMEU5IHBvc3NcdTAwRUR2ZWwgY29udmVydGVyIHswfSBlbSB1bSBOb2RlU2V0RFRNISJ9LAotCi0gIHsgRVJfQ0FOVF9DT05WRVJUX1RPX1RZUEUsCi0gICAgICAiTlx1MDBFM28gXHUwMEU5IHBvc3NcdTAwRUR2ZWwgY29udmVydGVyIHswfSBlbSB1bSB0aXBvIG5cdTAwQkF7MX0ifSwKLQotICB7IEVSX0VYUEVDVEVEX01BVENIX1BBVFRFUk4sCi0gICAgICAiUGFkclx1MDBFM28gZGUgY29ycmVzcG9uZFx1MDBFQW5jaWEgZXNwZXJhZG8gZW0gZ2V0TWF0Y2hTY29yZSEifSwKLQotICB7IEVSX0NPVUxETk9UX0dFVF9WQVJfTkFNRUQsCi0gICAgICAiTlx1MDBFM28gZm9pIHBvc3NcdTAwRUR2ZWwgb2J0ZXIgYSB2YXJpXHUwMEUxdmVsIGNvbSBvIG5vbWUgezB9In0sCi0KLSAgeyBFUl9VTktOT1dOX09QQ09ERSwKLSAgICAgIkVSUk8hIENcdTAwRjNkaWdvIGRhIG9wZXJhXHUwMEU3XHUwMEUzbyBkZXNjb25oZWNpZG86IHswfSJ9LAotCi0gIHsgRVJfRVhUUkFfSUxMRUdBTF9UT0tFTlMsCi0gICAgICJUb2tlbnMgaW52XHUwMEUxbGlkb3MgZXh0cmFzOiB7MH0ifSwKLQotICB7IEVSX0VYUEVDVEVEX0RPVUJMRV9RVU9URSwKLSAgICAgICJsaXRlcmFsIGNvbSBhc3BhcyBpbmNvcnJldGFzLi4uIGVzcGVyYXZhLXNlIGFzcGFzIGR1cGxhcyEifSwKLQotICB7IEVSX0VYUEVDVEVEX1NJTkdMRV9RVU9URSwKLSAgICAgICJsaXRlcmFsIGNvbSBhc3BhcyBpbmNvcnJldGFzLi4uIGVzcGVyYXZhLXNlIGFzcGFzIHNpbXBsZXMhIn0sCi0KLSAgeyBFUl9FTVBUWV9FWFBSRVNTSU9OLAotICAgICAiRXhwcmVzc1x1MDBFM28gdmF6aWEhIn0sCi0KLSAgeyBFUl9FWFBFQ1RFRF9CVVRfRk9VTkQsCi0gICAgICJFc3BlcmF2YSB7MH0sIG1hcyBlbmNvbnRyb3U6IHsxfSJ9LAotCi0gIHsgRVJfSU5DT1JSRUNUX1BST0dSQU1NRVJfQVNTRVJUSU9OLAotICAgICAgIkFzc2VyXHUwMEU3XHUwMEUzbyBkbyBwcm9ncmFtYWRvciBpbmNvcnJldGEhIC0gezB9In0sCi0KLSAgeyBFUl9CT09MRUFOX0FSR19OT19MT05HRVJfT1BUSU9OQUwsCi0gICAgICAiTyBhcmd1bWVudG8gYm9vbGVhbiguLi4pIG5cdTAwRTNvIFx1MDBFOSBtYWlzIG9wY2lvbmFsIGNvbSBvIHJhc2N1bmhvIFhQYXRoIDE5OTkwNzA5LiJ9LAotCi0gIHsgRVJfRk9VTkRfQ09NTUFfQlVUX05PX1BSRUNFRElOR19BUkcsCi0gICAgICAiRW5jb250cm91ICcsJyBtYXMgc2VtIHVtIGFyZ3VtZW50byBwcmVjZWRlbnRlISJ9LAotCi0gIHsgRVJfRk9VTkRfQ09NTUFfQlVUX05PX0ZPTExPV0lOR19BUkcsCi0gICAgICAiRW5jb250cm91ICcsJyBtYXMgc2VtIG8gYXJndW1lbnRvIGEgc2VndWlyISJ9LAotCi0gIHsgRVJfUFJFRElDQVRFX0lMTEVHQUxfU1lOVEFYLAotICAgICAgIicuLltwcmVkaWNhdGVdJyBvdSAnLltwcmVkaWNhdGVdJyBcdTAwRTkgdW1hIHNpbnRheGUgaW52XHUwMEUxbGlkYS4gVXNlICdzZWxmOjpub2RlKClbcHJlZGljYXRlXScuIn0sCi0KLSAgeyBFUl9JTExFR0FMX0FYSVNfTkFNRSwKLSAgICAgIm5vbWUgZG8gZWl4byBpbnZcdTAwRTFsaWRvOiB7MH0ifSwKLQotICB7IEVSX1VOS05PV05fTk9ERVRZUEUsCi0gICAgICJUaXBvIGRlIG5cdTAwRjMgZGVzY29uaGVjaWRvOiB7MH0ifSwKLQotICB7IEVSX1BBVFRFUk5fTElURVJBTF9ORUVEU19CRV9RVU9URUQsCi0gICAgICAiQSBsaXRlcmFsIHBhZHJcdTAwRTNvICh7MH0pIHByZWNpc2EgZXN0YXIgZW50cmUgYXNwYXMhIn0sCi0KLSAgeyBFUl9DT1VMRE5PVF9CRV9GT1JNQVRURURfVE9fTlVNQkVSLAotICAgICAgIm5cdTAwRTNvIGZvaSBwb3NzXHUwMEVEdmVsIGZvcm1hdGFyIHswfSBjb21vIHVtIG5cdTAwRkFtZXJvISJ9LAotCi0gIHsgRVJfQ09VTEROT1RfQ1JFQVRFX1hNTFBST0NFU1NPUkxJQUlTT04sCi0gICAgICAiTlx1MDBFM28gZm9pIHBvc3NcdTAwRUR2ZWwgY3JpYXIgYSBMaWdhXHUwMEU3XHUwMEUzbyBUcmFuc2Zvcm1lckZhY3RvcnkgWE1MOiB7MH0ifSwKLQotICB7IEVSX0RJRE5PVF9GSU5EX1hQQVRIX1NFTEVDVF9FWFAsCi0gICAgICAiRXJybyEgTlx1MDBFM28gZm9pIHBvc3NcdTAwRUR2ZWwgbG9jYWxpemFyIGEgZXhwcmVzc1x1MDBFM28gZGUgc2VsZVx1MDBFN1x1MDBFM28geHBhdGggKC1zZWxlY3QpLiJ9LAotCi0gIHsgRVJfQ09VTEROT1RfRklORF9FTkRPUF9BRlRFUl9PUExPQ0FUSU9OUEFUSCwKLSAgICAgICJFUlJPISBOXHUwMEUzbyBmb2kgcG9zc1x1MDBFRHZlbCBsb2NhbGl6YXIgRU5ET1AgYXBcdTAwRjNzIE9QX0xPQ0FUSU9OUEFUSCJ9LAotCi0gIHsgRVJfRVJST1JfT0NDVVJFRCwKLSAgICAgIk9jb3JyZXUgdW0gZXJybyEifSwKLQotICB7IEVSX0lMTEVHQUxfVkFSSUFCTEVfUkVGRVJFTkNFLAotICAgICAgIlZhcmlhYmxlUmVmZXJlbmNlIGZvcm5lY2lkYSBwYXJhIGEgdmFyaVx1MDBFMXZlbCBmb3JhIGRvIGNvbnRleHRvIG91IHNlbSBkZWZpbmlcdTAwRTdcdTAwRTNvISBOb21lID0gezB9In0sCi0KLSAgeyBFUl9BWEVTX05PVF9BTExPV0VELAotICAgICAgIlNvbWVudGUgZWl4b3MgZmlsaG86OiBlIGF0cmlidXRvOjogc1x1MDBFM28gcGVybWl0aWRvcyBub3MgcGFkclx1MDBGNWVzIGRlIGNvcnJlc3BvbmRcdTAwRUFuY2lhISBFaXhvcyBpbmNvcnJldG9zID0gezB9In0sCi0KLSAgeyBFUl9LRVlfSEFTX1RPT19NQU5ZX0FSR1MsCi0gICAgICAia2V5KCkgdGVtIHVtIG5cdTAwRkFtZXJvIGluY29ycmV0byBkZSBhcmd1bWVudG9zLiJ9LAotCi0gIHsgRVJfQ09VTlRfVEFLRVNfMV9BUkcsCi0gICAgICAiQSBmdW5cdTAwRTdcdTAwRTNvIGNvdW50IGRldmUgdGVyIHVtIGFyZ3VtZW50byEifSwKLQotICB7IEVSX0NPVUxETk9UX0ZJTkRfRlVOQ1RJT04sCi0gICAgICJOXHUwMEUzbyBmb2kgcG9zc1x1MDBFRHZlbCBsb2NhbGl6YXIgYSBmdW5cdTAwRTdcdTAwRTNvOiB7MH0ifSwKLQotICB7IEVSX1VOU1VQUE9SVEVEX0VOQ09ESU5HLAotICAgICAiQ29kaWZpY2FcdTAwRTdcdTAwRTNvIG5cdTAwRTNvIHN1cG9ydGFkYTogezB9In0sCi0KLSAgeyBFUl9QUk9CTEVNX0lOX0RUTV9ORVhUU0lCTElORywKLSAgICAgICJPY29ycmV1IHVtIHByb2JsZW1hIG5vIERUTSBlbSBnZXROZXh0U2libGluZy4uLiB0ZW50YW5kbyByZWN1cGVyYXIifSwKLQotICB7IEVSX0NBTk5PVF9XUklURV9UT19FTVBUWU5PREVMSVNUSU1QTCwKLSAgICAgICJFcnJvIGRvIHByb2dyYW1hZG9yOiBFbXB0eU5vZGVMaXN0IG5cdTAwRTNvIHBvZGUgc2VyIGdyYXZhZG8uIn0sCi0KLSAgeyBFUl9TRVRET01GQUNUT1JZX05PVF9TVVBQT1JURUQsCi0gICAgICAic2V0RE9NRmFjdG9yeSBuXHUwMEUzbyBzdXBvcnRhZG8gcG9yIFhQYXRoQ29udGV4dCEifSwKLQotICB7IEVSX1BSRUZJWF9NVVNUX1JFU09MVkUsCi0gICAgICAiTyBwcmVmaXhvIGRldmUgc2VyIHJlc29sdmlkbyBwYXJhIHVtIG5hbWVzcGFjZTogezB9In0sCi0KLSAgeyBFUl9QQVJTRV9OT1RfU1VQUE9SVEVELAotICAgICAgInBhcnNpbmcgKElucHV0U291cmNlIHNvdXJjZSkgblx1MDBFM28gc3Vwb3J0YWRvIGVtIFhQYXRoQ29udGV4dCEgTlx1MDBFM28gXHUwMEU5IHBvc3NcdTAwRUR2ZWwgYWJyaXIgezB9In0sCi0KLSAgeyBFUl9TQVhfQVBJX05PVF9IQU5ETEVELAotICAgICAgIkNhcmFjdGVyZXMgU0FYIEFQSShjaGFyIGNoW10uLi4gblx1MDBFM28gdHJhdGFkb3MgcG9yIERUTSEifSwKLQotICB7IEVSX0lHTk9SQUJMRV9XSElURVNQQUNFX05PVF9IQU5ETEVELAotICAgICAgImlnbm9yYWJsZVdoaXRlc3BhY2UoY2hhciBjaFtdLi4uIG5cdTAwRTNvIHRyYXRhZG8gcGVsbyBEVE0hIn0sCi0KLSAgeyBFUl9EVE1fQ0FOTk9UX0hBTkRMRV9OT0RFUywKLSAgICAgICJEVE1MaWFpc29uIG5cdTAwRTNvIHBvZGUgdHJhdGFyIG5cdTAwRjNzIGRvIHRpcG8gezB9In0sCi0KLSAgeyBFUl9YRVJDRVNfQ0FOTk9UX0hBTkRMRV9OT0RFUywKLSAgICAgICJET00ySGVscGVyIG5cdTAwRTNvIHBvZGUgdHJhdGFyIG5cdTAwRjNzIGRvIHRpcG8gezB9In0sCi0KLSAgeyBFUl9YRVJDRVNfUEFSU0VfRVJST1JfREVUQUlMUywKLSAgICAgICJFcnJvIGRlIERPTTJIZWxwZXIucGFyc2U6IFN5c3RlbUlEIC0gezB9IGxpbmhhIC0gezF9In0sCi0KLSAgeyBFUl9YRVJDRVNfUEFSU0VfRVJST1IsCi0gICAgICJFcnJvIGRlIERPTTJIZWxwZXIucGFyc2UifSwKLQotICB7IEVSX0lOVkFMSURfVVRGMTZfU1VSUk9HQVRFLAotICAgICAgIkZvaSBkZXRlY3RhZG8gdW0gc3Vic3RpdHV0byBkZSBVVEYtMTYgaW52XHUwMEUxbGlkbzogezB9ID8ifSwKLQotICB7IEVSX09JRVJST1IsCi0gICAgICJFcnJvIGRlIEUvUyJ9LAotCi0gIHsgRVJfQ0FOTk9UX0NSRUFURV9VUkwsCi0gICAgICJOXHUwMEUzbyBcdTAwRTkgcG9zc1x1MDBFRHZlbCBjcmlhciBvIHVybCBwYXJhOiB7MH0ifSwKLQotICB7IEVSX1hQQVRIX1JFQURPQkpFQ1QsCi0gICAgICJObyBYUGF0aC5yZWFkT2JqZWN0OiB7MH0ifSwKLQotICB7IEVSX0ZVTkNUSU9OX1RPS0VOX05PVF9GT1VORCwKLSAgICAgICJ0b2tlbiBkYSBmdW5cdTAwRTdcdTAwRTNvIG5cdTAwRTNvIGVuY29udHJhZG8uIn0sCi0KLSAgeyBFUl9DQU5OT1RfREVBTF9YUEFUSF9UWVBFLAotICAgICAgICJOXHUwMEUzbyBcdTAwRTkgcG9zc1x1MDBFRHZlbCBsaWRhciBjb20gbyB0aXBvIGRlIFhQYXRoOiB7MH0ifSwKLQotICB7IEVSX05PREVTRVRfTk9UX01VVEFCTEUsCi0gICAgICAgIkVzdGUgTm9kZVNldCBuXHUwMEUzbyBcdTAwRTkgbXV0XHUwMEUxdmVsIn0sCi0KLSAgeyBFUl9OT0RFU0VURFRNX05PVF9NVVRBQkxFLAotICAgICAgICJFc3RlIE5vZGVTZXREVE0gblx1MDBFM28gXHUwMEU5IG11dFx1MDBFMXZlbCJ9LAotCi0gIHsgRVJfVkFSX05PVF9SRVNPTFZBQkxFLAotICAgICAgICAiVmFyaVx1MDBFMXZlbCBuXHUwMEUzbyByZXNvbHZcdTAwRUR2ZWw6IHswfSJ9LAotCi0gIHsgRVJfTlVMTF9FUlJPUl9IQU5ETEVSLAotICAgICAgICAiSGFuZGxlciBkZSBlcnJvIG51bG8ifSwKLQotICB7IEVSX1BST0dfQVNTRVJUX1VOS05PV05fT1BDT0RFLAotICAgICAgICJBc3Nlclx1MDBFN1x1MDBFM28gZG8gcHJvZ3JhbWFkb3I6IG9wY29kZSBkZXNjb25oZWNpZG86IHswfSJ9LAotCi0gIHsgRVJfWkVST19PUl9PTkUsCi0gICAgICAgIjAgb3UgMSJ9LAotCi0gIHsgRVJfUlRGX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIsCi0gICAgICAgInJ0ZigpIG5cdTAwRTNvIHN1cG9ydGFkbyBwb3IgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIifSwKLQotICB7IEVSX1JURl9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSLAotICAgICAgICJhc05vZGVJdGVyYXRvcigpIG5cdTAwRTNvIHN1cG9ydGFkbyBwb3IgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIifSwKLQotICAgICAgICAvKiogIGRldGFjaCgpIG5vdCBzdXBwb3J0ZWQgYnkgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIgICAqLwotICAgeyBFUl9ERVRBQ0hfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiwKLSAgICAgICAgICAgICAgICAiZGV0YWNoKCkgblx1MDBFM28gc3Vwb3J0YWRvIHBvciBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciJ9LAotCi0gICAgICAgIC8qKiAgbnVtKCkgbm90IHN1cHBvcnRlZCBieSBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciAgICovCi0gICB7IEVSX05VTV9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSLAotICAgICAgICAgICAgICAgICJudW0oKSBuXHUwMEUzbyBzdXBvcnRhZG8gcG9yIFhSVHJlZUZyYWdTZWxlY3RXcmFwcGVyIn0sCi0KLSAgICAgICAgLyoqICB4c3RyKCkgbm90IHN1cHBvcnRlZCBieSBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciAgICovCi0gICB7IEVSX1hTVFJfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiwKLSAgICAgICAgICAgICAgICAieHN0cigpIG5cdTAwRTNvIHN1cG9ydGFkbyBwb3IgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIifSwKLQotICAgICAgICAvKiogIHN0cigpIG5vdCBzdXBwb3J0ZWQgYnkgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIgICAqLwotICAgeyBFUl9TVFJfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiwKLSAgICAgICAgICAgICAgICAic3RyKCkgblx1MDBFM28gc3Vwb3J0YWRvIHBvciBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciJ9LAotCi0gIHsgRVJfRlNCX05PVF9TVVBQT1JURURfWFNUUklOR0ZPUkNIQVJTLAotICAgICAgICJmc2IoKSBuXHUwMEUzbyBzdXBvcnRhZG8gcGFyYSBYU3RyaW5nRm9yQ2hhcnMifSwKLQotICB7IEVSX0NPVUxEX05PVF9GSU5EX1ZBUiwKLSAgICAgICJOXHUwMEUzbyBmb2kgcG9zc1x1MDBFRHZlbCBsb2NhbGl6YXIgYSB2YXJpXHUwMEUxdmVsIGNvbSBvIG5vbWUgezB9In0sCi0KLSAgeyBFUl9YU1RSSU5HRk9SQ0hBUlNfQ0FOTk9UX1RBS0VfU1RSSU5HLAotICAgICAgIlhTdHJpbmdGb3JDaGFycyBuXHUwMEUzbyBwb2RlIHRlciB1bWEgc3RyaW5nIHBhcmEgdW0gYXJndW1lbnRvIn0sCi0KLSAgeyBFUl9GQVNUU1RSSU5HQlVGRkVSX0NBTk5PVF9CRV9OVUxMLAotICAgICAgIk8gYXJndW1lbnRvIEZhc3RTdHJpbmdCdWZmZXIgblx1MDBFM28gcG9kZSBzZXIgbnVsbyJ9LAotCi0gIHsgRVJfVFdPX09SX1RIUkVFLAotICAgICAgICIyIG91IDMifSwKLQotICB7IEVSX1ZBUklBQkxFX0FDQ0VTU0VEX0JFRk9SRV9CSU5ELAotICAgICAgICJWYXJpXHUwMEUxdmVsIGFjZXNzYWRhIGFudGVzIGRlIHNlciBhc3NvY2lhZGEhIn0sCi0KLSAgeyBFUl9GU0JfQ0FOTk9UX1RBS0VfU1RSSU5HLAotICAgICAgICJYU3RyaW5nRm9yRlNCIG5cdTAwRTNvIHBvZGUgb2J0ZXIgdW1hIHN0cmluZyBwYXJhIHVtIGFyZ3VtZW50byEifSwKLQotICB7IEVSX1NFVFRJTkdfV0FMS0VSX1JPT1RfVE9fTlVMTCwKLSAgICAgICAiXG4gISEhISBFcnJvISBEZWZpbmluZG8gYSByYWl6IGRlIHVtIHdhbGtlciBjb21vIG51bGEhISEifSwKLQotICB7IEVSX05PREVTRVREVE1fQ0FOTk9UX0lURVJBVEUsCi0gICAgICAgIkVzdGUgTm9kZVNldERUTSBuXHUwMEUzbyBwb2RlIGZhemVyIGl0ZXJhXHUwMEU3XHUwMEY1ZXMgcGFyYSB1bSBuXHUwMEYzIGFudGVyaW9yISJ9LAotCi0gIHsgRVJfTk9ERVNFVF9DQU5OT1RfSVRFUkFURSwKLSAgICAgICAiRXN0ZSBOb2RlU2V0IG5cdTAwRTNvIHBvZGUgZmF6ZXIgaXRlcmFcdTAwRTdcdTAwRjVlcyBwYXJhIHVtIG5cdTAwRjMgYW50ZXJpb3IhIn0sCi0KLSAgeyBFUl9OT0RFU0VURFRNX0NBTk5PVF9JTkRFWCwKLSAgICAgICAiRXN0ZSBOb2RlU2V0RFRNIG5cdTAwRTNvIHBvZGUgZXhlY3V0YXIgYXMgZnVuXHUwMEU3XHUwMEY1ZXMgZGUgaW5kZXhhXHUwMEU3XHUwMEUzbyBvdSBkZSBjb250YWdlbSEifSwKLQotICB7IEVSX05PREVTRVRfQ0FOTk9UX0lOREVYLAotICAgICAgICJFc3RlIE5vZGVTZXQgblx1MDBFM28gcG9kZSBleGVjdXRhciBhcyBmdW5cdTAwRTdcdTAwRjVlcyBkZSBpbmRleGFcdTAwRTdcdTAwRTNvIG91IGRlIGNvbnRhZ2VtISJ9LAotCi0gIHsgRVJfQ0FOTk9UX0NBTExfU0VUU0hPVUxEQ0FDSEVOT0RFLAotICAgICAgICJOXHUwMEUzbyBcdTAwRTkgcG9zc1x1MDBFRHZlbCBjaGFtYXIgc2V0U2hvdWxkQ2FjaGVOb2RlcyBkZXBvaXMgZGUgbmV4dE5vZGUgdGVyIHNpZG8gY2hhbWFkbyEifSwKLQotICB7IEVSX09OTFlfQUxMT1dTLAotICAgICAgICJ7MH0gc1x1MDBGMyBwZXJtaXRlIHsxfSBhcmd1bWVudG9zIn0sCi0KLSAgeyBFUl9VTktOT1dOX1NURVAsCi0gICAgICAgIkFzc2VyXHUwMEU3XHUwMEUzbyBkbyBwcm9ncmFtYWRvciBlbSBnZXROZXh0U3RlcFBvczogc3RlcFR5cGUgZGVzY29uaGVjaWRvOiB7MH0ifSwKLQotICAvL05vdGUgdG8gdHJhbnNsYXRvcnM6ICBBIHJlbGF0aXZlIGxvY2F0aW9uIHBhdGggaXMgYSBmb3JtIG9mIFhQYXRoIGV4cHJlc3Npb24uCi0gIC8vIFRoZSBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHN1Y2ggYW4gZXhwcmVzc2lvbiB3YXMgZXhwZWN0ZWQgZm9sbG93aW5nIHRoZQotICAvLyBjaGFyYWN0ZXJzICcvJyBvciAnLy8nLCBidXQgd2FzIG5vdCBmb3VuZC4KLSAgeyBFUl9FWFBFQ1RFRF9SRUxfTE9DX1BBVEgsCi0gICAgICAiRXNwZXJhdmEtc2UgdW0gY2FtaW5obyBkZSBsb2NhbGl6YVx1MDBFN1x1MDBFM28gcmVsYXRpdm8sIG1hcyBvIHNlZ3VpbnRlIHRva2VuIGZvaSBlbmNvbnRyYWRvOiAnLycgb3UgJy8vJy4ifSwKLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQSBsb2NhdGlvbiBwYXRoIGlzIGEgZm9ybSBvZiBYUGF0aCBleHByZXNzaW9uLgotICAvLyBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCBzeW50YWN0aWNhbGx5IHN1Y2ggYW4gZXhwcmVzc2lvbiB3YXMgZXhwZWN0ZWQsYnV0Ci0gIC8vIHRoZSBjaGFyYWN0ZXJzIHNwZWNpZmllZCBieSB0aGUgc3Vic3RpdHV0aW9uIHRleHQgd2VyZSBlbmNvdW50ZXJlZCBpbnN0ZWFkLgotICB7IEVSX0VYUEVDVEVEX0xPQ19QQVRILAotICAgICAgICJFc3BlcmF2YS1zZSB1bSBjYW1pbmhvIGRlIGxvY2FsaXphXHUwMEU3XHUwMEUzbywgbWFzIG8gc2VndWludGUgdG9rZW4gZm9pIGVuY29udHJhZG86ICB7MH0ifSwKLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQSBsb2NhdGlvbiBwYXRoIGlzIGEgZm9ybSBvZiBYUGF0aCBleHByZXNzaW9uLgotICAvLyBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCBzeW50YWN0aWNhbGx5IHN1Y2ggYSBzdWJleHByZXNzaW9uIHdhcyBleHBlY3RlZCwKLSAgLy8gYnV0IG5vIG1vcmUgY2hhcmFjdGVycyB3ZXJlIGZvdW5kIGluIHRoZSBleHByZXNzaW9uLgotICB7IEVSX0VYUEVDVEVEX0xPQ19QQVRIX0FUX0VORF9FWFBSLAotICAgICAgICJFc3BlcmF2YS1zZSB1bSBjYW1pbmhvIGRlIGxvY2FsaXphXHUwMEU3XHUwMEUzbywgbWFzLCBlbSB2ZXogZGlzc28sIG8gZmltIGRhIGV4cHJlc3NcdTAwRTNvIFhQYXRoIGZvaSBlbmNvbnRyYWRvLiJ9LAotCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBIGxvY2F0aW9uIHN0ZXAgaXMgcGFydCBvZiBhbiBYUGF0aCBleHByZXNzaW9uLgotICAvLyBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCBzeW50YWN0aWNhbGx5IHN1Y2ggYW4gZXhwcmVzc2lvbiB3YXMgZXhwZWN0ZWQKLSAgLy8gZm9sbG93aW5nIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVycy4KLSAgeyBFUl9FWFBFQ1RFRF9MT0NfU1RFUCwKLSAgICAgICAiRXNwZXJhdmEtc2UgdW1hIGV0YXBhIGRlIGxvY2FsaXphXHUwMEU3XHUwMEUzbyBzZWd1aW50ZSBhbyB0b2tlbiAnLycgb3UgJy8vJy4ifSwKLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQSBub2RlIHRlc3QgaXMgcGFydCBvZiBhbiBYUGF0aCBleHByZXNzaW9uIHRoYXQgaXMKLSAgLy8gdXNlZCB0byB0ZXN0IGZvciBwYXJ0aWN1bGFyIGtpbmRzIG9mIG5vZGVzLiAgSW4gdGhpcyBjYXNlLCBhIG5vZGUgdGVzdCB0aGF0Ci0gIC8vIGNvbnNpc3RzIG9mIGFuIE5DTmFtZSBmb2xsb3dlZCBieSBhIGNvbG9uIGFuZCBhbiBhc3RlcmlzayBvciB0aGF0IGNvbnNpc3RzCi0gIC8vIG9mIGEgUU5hbWUgd2FzIGV4cGVjdGVkLCBidXQgd2FzIG5vdCBmb3VuZC4KLSAgeyBFUl9FWFBFQ1RFRF9OT0RFX1RFU1QsCi0gICAgICAgIkVzcGVyYXZhLXNlIHVtIHRlc3RlIGRlIG5cdTAwRjMgcXVlIGNvcnJlc3BvbmRlIGEgTkNOYW1lOiogb3UgUU5hbWUuIn0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIEEgc3RlcCBwYXR0ZXJuIGlzIHBhcnQgb2YgYW4gWFBhdGggZXhwcmVzc2lvbi4KLSAgLy8gVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgc3ludGFjdGljYWxseSBzdWNoIGFuIGV4cHJlc3Npb24gd2FzIGV4cGVjdGVkLAotICAvLyBidXQgdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXIgd2FzIGZvdW5kIGluIHRoZSBleHByZXNzaW9uIGluc3RlYWQuCi0gIHsgRVJfRVhQRUNURURfU1RFUF9QQVRURVJOLAotICAgICAgICJFc3BlcmF2YS1zZSB1bSBwYWRyXHUwMEUzbyBkYSBldGFwYSwgbWFzICcvJyBmb2kgZW5jb250cmFkby4ifSwKLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiBBIHJlbGF0aXZlIHBhdGggcGF0dGVybiBpcyBwYXJ0IG9mIGFuIFhQYXRoIGV4cHJlc3Npb24uCi0gIC8vIFRoZSBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHN5bnRhY3RpY2FsbHkgc3VjaCBhbiBleHByZXNzaW9uIHdhcyBleHBlY3RlZCwKLSAgLy8gYnV0IHdhcyBub3QgZm91bmQuCi0gIHsgRVJfRVhQRUNURURfUkVMX1BBVEhfUEFUVEVSTiwKLSAgICAgICAiRXNwZXJhdmEtc2UgdW0gcGFkclx1MDBFM28gZGUgY2FtaW5obyByZWxhdGl2by4ifSwKLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIGEgZGF0YSB0eXBlLiAgVGhlCi0gIC8vIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgYSB2YWx1ZSBvZiBhIHBhcnRpY3VsYXIgdHlwZSBjb3VsZCBub3QgYmUgY29udmVydGVkCi0gIC8vIHRvIGEgdmFsdWUgb2YgdHlwZSBib29sZWFuLgotICB7IEVSX0NBTlRfQ09OVkVSVF9UT19CT09MRUFOLAotICAgICAgICJPIFhQYXRoUmVzdWx0IGRhIGV4cHJlc3NcdTAwRTNvIGRlIFhQYXRoICcnezB9JycgdGVtIHVtIFhQYXRoUmVzdWx0VHlwZSBkZSB7MX0gcXVlIG5cdTAwRTNvIHBvZGUgc2VyIGNvbnZlcnRpZG8gZW0gdW0gYm9vbGlhbm8uIn0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogRG8gbm90IHRyYW5zbGF0ZSBBTllfVU5PUkRFUkVEX05PREVfVFlQRSBhbmQKLSAgLy8gRklSU1RfT1JERVJFRF9OT0RFX1RZUEUuCi0gIHsgRVJfQ0FOVF9DT05WRVJUX1RPX1NJTkdMRU5PREUsCi0gICAgICAgIk8gWFBhdGhSZXN1bHQgZGEgZXhwcmVzc1x1MDBFM28gZGUgWFBhdGggJyd7MH0nJyB0ZW0gdW0gWFBhdGhSZXN1bHRUeXBlIGRlIHsxfSBxdWUgblx1MDBFM28gcG9kZSBzZXIgY29udmVydGlkbyBlbSB1bSBuXHUwMEYzIHNpbXBsZXMuIE8gbVx1MDBFOXRvZG8gZ2V0U2luZ2xlTm9kZVZhbHVlIGFwbGljYS1zZSBzb21lbnRlIGFvcyB0aXBvcyBBTllfVU5PUkRFUkVEX05PREVfVFlQRSBlIEZJUlNUX09SREVSRURfTk9ERV9UWVBFLiJ9LAotCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6IERvIG5vdCB0cmFuc2xhdGUgVU5PUkRFUkVEX05PREVfU05BUFNIT1RfVFlQRSBhbmQKLSAgLy8gT1JERVJFRF9OT0RFX1NOQVBTSE9UX1RZUEUuCi0gIHsgRVJfQ0FOVF9HRVRfU05BUFNIT1RfTEVOR1RILAotICAgICAgICJPIG1cdTAwRTl0b2RvIGdldFNuYXBzaG90TGVuZ3RoIG5cdTAwRTNvIHBvZGUgc2VyIGNoYW1hZG8gbm8gWFBhdGhSZXN1bHQgZGEgZXhwcmVzc1x1MDBFM28gWFBhdGggJyd7MH0nJyBwb3JxdWUgc2V1IFhQYXRoUmVzdWx0VHlwZSBcdTAwRTkgezF9LiBFc3RlIG1cdTAwRTl0b2RvIHNlIGFwbGljYSBzb21lbnRlIGEgdGlwb3MgVU5PUkRFUkVEX05PREVfU05BUFNIT1RfVFlQRSBlIE9SREVSRURfTk9ERV9TTkFQU0hPVF9UWVBFLiJ9LAotCi0gIHsgRVJfTk9OX0lURVJBVE9SX1RZUEUsCi0gICAgICAgIk8gbVx1MDBFOXRvZG8gaXRlcmF0ZU5leHQgblx1MDBFM28gcG9kZSBzZXIgY2hhbWFkbyBubyBYUGF0aFJlc3VsdCBkYSBleHByZXNzXHUwMEUzbyBYUGF0aCAnJ3swfScnIHBvcnF1ZSBzZXUgWFBhdGhSZXN1bHRUeXBlIFx1MDBFOSB7MX0uIEVzdGUgbVx1MDBFOXRvZG8gc2UgYXBsaWNhIHNvbWVudGUgYSB0aXBvcyBVTk9SREVSRURfTk9ERV9JVEVSQVRPUl9UWVBFIGUgT1JERVJFRF9OT0RFX0lURVJBVE9SX1RZUEUuIn0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogVGhpcyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoZSBkb2N1bWVudCBiZWluZyBvcGVyYXRlZAotICAvLyB1cG9uIGNoYW5nZWQsIHNvIHRoZSBpdGVyYXRvciBvYmplY3QgdGhhdCB3YXMgYmVpbmcgdXNlZCB0byB0cmF2ZXJzZSB0aGUKLSAgLy8gZG9jdW1lbnQgaGFzIG5vdyBiZWNvbWUgaW52YWxpZC4KLSAgeyBFUl9ET0NfTVVUQVRFRCwKLSAgICAgICAiRG9jdW1lbnRvIGFsdGVyYWRvIGRlc2RlIHF1ZSBvIHJlc3VsdGFkbyBmb2kgZGV2b2x2aWRvLiBPIGl0ZXJhZG9yIFx1MDBFOSBpbnZcdTAwRTFsaWRvLiJ9LAotCi0gIHsgRVJfSU5WQUxJRF9YUEFUSF9UWVBFLAotICAgICAgICJBcmd1bWVudG8gZGUgdGlwbyBYUGF0aCBpbnZcdTAwRTFsaWRvOiB7MH0ifSwKLQotICB7IEVSX0VNUFRZX1hQQVRIX1JFU1VMVCwKLSAgICAgICAiT2JqZXRvIGRlIHJlc3VsdGFkbyBkZSBYUGF0aCB2YXppbyJ9LAotCi0gIHsgRVJfSU5DT01QQVRJQkxFX1RZUEVTLAotICAgICAgICJPIFhQYXRoUmVzdWx0IGRhIGV4cHJlc3NcdTAwRTNvIFhQYXRoICcnezB9JycgdGVtIHVtIFhQYXRoUmVzdWx0VHlwZSB7MX0gcXVlIG5cdTAwRTNvIHBvZGUgZXN0YXIgZGVsaW1pdGFkbyBubyBYUGF0aFJlc3VsdFR5cGUgZXNwZWNpZmljYWRvIHsyfS4ifSwKLQotICB7IEVSX05VTExfUkVTT0xWRVIsCi0gICAgICAgIk5cdTAwRTNvIFx1MDBFOSBwb3NzXHUwMEVEdmVsIHJlc29sdmVyIG8gcHJlZml4byBjb20gc29sdWNpb25hZG9yIGRlIHByZWZpeG8gbnVsby4ifSwKLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIGEgZGF0YSB0eXBlLiAgVGhlCi0gIC8vIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgYSB2YWx1ZSBvZiBhIHBhcnRpY3VsYXIgdHlwZSBjb3VsZCBub3QgYmUgY29udmVydGVkCi0gIC8vIHRvIGEgdmFsdWUgb2YgdHlwZSBzdHJpbmcuCi0gIHsgRVJfQ0FOVF9DT05WRVJUX1RPX1NUUklORywKLSAgICAgICAiTyBYUGF0aFJlc3VsdCBkYSBleHByZXNzXHUwMEUzbyBYUGF0aCAnJ3swfScnIHRlbSB1bSBYUGF0aFJlc3VsdFR5cGUgezF9IHF1ZSBuXHUwMEUzbyBwb2RlIHNlciBjb252ZXJ0aWRvIGVtIHN0cmluZy4ifSwKLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiBEbyBub3QgdHJhbnNsYXRlIHNuYXBzaG90SXRlbSwKLSAgLy8gVU5PUkRFUkVEX05PREVfU05BUFNIT1RfVFlQRSBhbmQgT1JERVJFRF9OT0RFX1NOQVBTSE9UX1RZUEUuCi0gIHsgRVJfTk9OX1NOQVBTSE9UX1RZUEUsCi0gICAgICAgIk8gbVx1MDBFOXRvZG8gc25hcHNob3RJdGVtIG5cdTAwRTNvIHBvZGUgc2VyIGNoYW1hZG8gbm8gWFBhdGhSZXN1bHQgZGEgZXhwcmVzc1x1MDBFM28gWFBhdGggJyd7MH0nJyBwb3JxdWUgc2V1IFhQYXRoUmVzdWx0VHlwZSBcdTAwRTkgezF9LiBFc3RlIG1cdTAwRTl0b2RvIHNlIGFwbGljYSBzb21lbnRlIGEgdGlwb3MgVU5PUkRFUkVEX05PREVfU05BUFNIT1RfVFlQRSBlIE9SREVSRURfTk9ERV9TTkFQU0hPVF9UWVBFLiJ9LAotCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBYUGF0aEV2YWx1YXRvciBpcyBhIEphdmEgaW50ZXJmYWNlIG5hbWUuICBBbgotICAvLyBYUGF0aEV2YWx1YXRvciBpcyBjcmVhdGVkIHdpdGggcmVzcGVjdCB0byBhIHBhcnRpY3VsYXIgWE1MIGRvY3VtZW50LCBhbmQgaW4KLSAgLy8gdGhpcyBjYXNlIHRoZSBleHByZXNzaW9uIHJlcHJlc2VudGVkIGJ5IHRoaXMgb2JqZWN0IHdhcyBiZWluZyBldmFsdWF0ZWQgd2l0aAotICAvLyByZXNwZWN0IHRvIGEgY29udGV4dCBub2RlIGZyb20gYSBkaWZmZXJlbnQgZG9jdW1lbnQuCi0gIHsgRVJfV1JPTkdfRE9DVU1FTlQsCi0gICAgICAgIk8gblx1MDBGMyBkZSBjb250ZXh0byBuXHUwMEUzbyBwZXJ0ZW5jZSBhbyBkb2N1bWVudG8gcXVlIGVzdFx1MDBFMSB2aW5jdWxhZG8gYSBlc3RlIFhQYXRoRXZhbHVhdG9yLiJ9LAotCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgWFBhdGggZXhwcmVzc2lvbiBjYW5ub3QgYmUgZXZhbHVhdGVkIHdpdGggcmVzcGVjdAotICAvLyB0byB0aGlzIHR5cGUgb2Ygbm9kZS4KLSAgeyBFUl9XUk9OR19OT0RFVFlQRSwKLSAgICAgICAiTyB0aXBvIGRvIG5cdTAwRjMgZGUgY29udGV4dG8gblx1MDBFM28gXHUwMEU5IHN1cG9ydGFkby4ifSwKLQotICB7IEVSX1hQQVRIX0VSUk9SLAotICAgICAgICJFcnJvIGRlc2NvbmhlY2lkbyBubyBYUGF0aC4ifSwKLQotICB7IEVSX0NBTlRfQ09OVkVSVF9YUEFUSFJFU1VMVFRZUEVfVE9fTlVNQkVSLAotICAgICAgICAiTyBYUGF0aFJlc3VsdCBkYSBleHByZXNzXHUwMEUzbyBYUGF0aCAnJ3swfScnIHRlbSB1bSBYUGF0aFJlc3VsdFR5cGUgezF9IHF1ZSBuXHUwMEUzbyBwb2RlIHNlciBjb252ZXJ0aWRvIGVtIG5cdTAwRkFtZXJvLiJ9LAotCi0gIC8vQkVHSU46ICBEZWZpbml0aW9ucyBvZiBlcnJvciBrZXlzIHVzZWQgIGluIGV4Y2VwdGlvbiBtZXNzYWdlcyBvZiAgSkFYUCAxLjMgWFBhdGggQVBJIGltcGxlbWVudGF0aW9uCi0KLSAgLyoqIEZpZWxkIEVSX0VYVEVOU0lPTl9GVU5DVElPTl9DQU5OT1RfQkVfSU5WT0tFRCAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX0VYVEVOU0lPTl9GVU5DVElPTl9DQU5OT1RfQkVfSU5WT0tFRCwKLSAgICAgICAiRnVuXHUwMEU3XHUwMEUzbyBkZSBleHRlbnNcdTAwRTNvOiAnJ3swfScnIG5cdTAwRTNvIHBvZGUgc2VyIGNoYW1hZG8gcXVhbmRvIG8gcmVjdXJzbyBYTUxDb25zdGFudHMuRkVBVFVSRV9TRUNVUkVfUFJPQ0VTU0lORyBlc3RpdmVyIGRlZmluaWRvIGNvbW8gdmVyZGFkZWlyby4ifSwKLQotICAvKiogRmllbGQgRVJfUkVTT0xWRV9WQVJJQUJMRV9SRVRVUk5TX05VTEwgICAgICAgICAgICAgICAgICAgICAgICovCi0KLSAgeyBFUl9SRVNPTFZFX1ZBUklBQkxFX1JFVFVSTlNfTlVMTCwKLSAgICAgICAicmVzb2x2ZVZhcmlhYmxlIGRhIHZhcmlcdTAwRTF2ZWwgezB9IHJldG9ybmFuZG8gbnVsbyJ9LAotCi0gIC8qKiBGaWVsZCBFUl9VTlNVUFBPUlRFRF9SRVRVUk5fVFlQRSAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX1VOU1VQUE9SVEVEX1JFVFVSTl9UWVBFLAotICAgICAgICJUaXBvIGRlIFJldG9ybm8gTlx1MDBFM28gU3Vwb3J0YWRvIDogezB9In0sCi0KLSAgLyoqIEZpZWxkIEVSX1NPVVJDRV9SRVRVUk5fVFlQRV9DQU5OT1RfQkVfTlVMTCAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX1NPVVJDRV9SRVRVUk5fVFlQRV9DQU5OT1RfQkVfTlVMTCwKLSAgICAgICAiTyBUaXBvIGRlIE9yaWdlbSBlL291IFJldG9ybm8gblx1MDBFM28gcG9kZSBzZXIgbnVsbyJ9LAotCi0gIC8qKiBGaWVsZCBFUl9TT1VSQ0VfUkVUVVJOX1RZUEVfQ0FOTk9UX0JFX05VTEwgICAgICAgICAgICAgICAgICAgICAgICovCi0KLSAgeyBFUl9TT1VSQ0VfUkVUVVJOX1RZUEVfQ0FOTk9UX0JFX05VTEwsCi0gICAgICAgIk8gVGlwbyBkZSBPcmlnZW0gZS9vdSBSZXRvcm5vIG5cdTAwRTNvIHBvZGUgc2VyIG51bG8ifSwKLQotICAvKiogRmllbGQgRVJfQVJHX0NBTk5PVF9CRV9OVUxMICAgICAgICAgICAgICAgICAgICAgICAqLwotCi0gIHsgRVJfQVJHX0NBTk5PVF9CRV9OVUxMLAotICAgICAgICJPIGFyZ3VtZW50byB7MH0gblx1MDBFM28gcG9kZSBzZXIgbnVsbyJ9LAotCi0gIC8qKiBGaWVsZCBFUl9PQkpFQ1RfTU9ERUxfTlVMTCAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX09CSkVDVF9NT0RFTF9OVUxMLAotICAgICAgICJ7MH0jaXNPYmplY3RNb2RlbFN1cHBvcnRlZCggU3RyaW5nIG9iamVjdE1vZGVsICkgblx1MDBFM28gcG9kZSBzZXIgY2hhbWFkbyBjb20gb2JqZWN0TW9kZWwgPT0gbnVsbCJ9LAotCi0gIC8qKiBGaWVsZCBFUl9PQkpFQ1RfTU9ERUxfRU1QVFkgICAgICAgICAgICAgICAgICAgICAgICovCi0KLSAgeyBFUl9PQkpFQ1RfTU9ERUxfRU1QVFksCi0gICAgICAgInswfSNpc09iamVjdE1vZGVsU3VwcG9ydGVkKCBTdHJpbmcgb2JqZWN0TW9kZWwgKSBuXHUwMEUzbyBwb2RlIHNlciBjaGFtYWRvIGNvbSBvYmplY3RNb2RlbCA9PSAgXCJcIiJ9LAotCi0gIC8qKiBGaWVsZCBFUl9PQkpFQ1RfTU9ERUxfRU1QVFkgICAgICAgICAgICAgICAgICAgICAgICovCi0KLSAgeyBFUl9GRUFUVVJFX05BTUVfTlVMTCwKLSAgICAgICAiVGVudGF0aXZhIGRlIGRlZmluaXIgdW0gcmVjdXJzbyBjb20gdW0gbm9tZSBudWxvOiB7MH0jc2V0RmVhdHVyZSggbnVsbCwgezF9KSJ9LAotCi0gIC8qKiBGaWVsZCBFUl9GRUFUVVJFX1VOS05PV04gICAgICAgICAgICAgICAgICAgICAgICovCi0KLSAgeyBFUl9GRUFUVVJFX1VOS05PV04sCi0gICAgICAgIlRlbnRhdGl2YSBkZSBkZWZpbmlyIG8gcmVjdXJzbyBkZXNjb25oZWNpZG8gXCJ7MH1cIjp7MX0jc2V0RmVhdHVyZSh7MH0sezJ9KSJ9LAotCi0gIC8qKiBGaWVsZCBFUl9HRVRUSU5HX05VTExfRkVBVFVSRSAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX0dFVFRJTkdfTlVMTF9GRUFUVVJFLAotICAgICAgICJUZW50YXRpdmEgZGUgb2J0ZXIgdW0gcmVjdXJzbyBjb20gdW0gbm9tZSBudWxvOiB7MH0jZ2V0RmVhdHVyZShudWxsKSJ9LAotCi0gIC8qKiBGaWVsZCBFUl9HRVRUSU5HX05VTExfRkVBVFVSRSAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX0dFVFRJTkdfVU5LTk9XTl9GRUFUVVJFLAotICAgICAgICJUZW50YXRpdmEgZGUgb2J0ZXIgbyByZWN1cnNvIGRlc2NvbmhlY2lkbyBcInswfVwiOnsxfSNnZXRGZWF0dXJlKHswfSkifSwKLQotICB7RVJfU0VDVVJFUFJPQ0VTU0lOR19GRUFUVVJFLAotICAgICAgICAiRkVBVFVSRV9TRUNVUkVfUFJPQ0VTU0lORzogTlx1MDBFM28gXHUwMEU5IHBvc3NcdTAwRUR2ZWwgZGVmaW5pciBvIHJlY3Vyc28gY29tbyBmYWxzbyBxdWFuZG8gbyBnZXJlbmNpYWRvciBkZSBzZWd1cmFuXHUwMEU3YSBlc3RcdTAwRTEgcHJlc2VudGU6IHsxfSNzZXRGZWF0dXJlKHswfSx7Mn0pIn0sCi0KLSAgLyoqIEZpZWxkIEVSX05VTExfWFBBVEhfRlVOQ1RJT05fUkVTT0xWRVIgICAgICAgICAgICAgICAgICAgICAgICovCi0KLSAgeyBFUl9OVUxMX1hQQVRIX0ZVTkNUSU9OX1JFU09MVkVSLAotICAgICAgICJUZW50YXRpdmEgZGUgZGVmaW5pciB1bSBYUGF0aEZ1bmN0aW9uUmVzb2x2ZXIgbnVsbzp7MH0jc2V0WFBhdGhGdW5jdGlvblJlc29sdmVyKG51bGwpIn0sCi0KLSAgLyoqIEZpZWxkIEVSX05VTExfWFBBVEhfVkFSSUFCTEVfUkVTT0xWRVIgICAgICAgICAgICAgICAgICAgICAgICovCi0KLSAgeyBFUl9OVUxMX1hQQVRIX1ZBUklBQkxFX1JFU09MVkVSLAotICAgICAgICJUZW50YXRpdmEgZGUgZGVmaW5pciB1bSBYUGF0aFZhcmlhYmxlUmVzb2x2ZXIgbnVsbzp7MH0jc2V0WFBhdGhWYXJpYWJsZVJlc29sdmVyKG51bGwpIn0sCi0KLSAgLy9FTkQ6ICBEZWZpbml0aW9ucyBvZiBlcnJvciBrZXlzIHVzZWQgIGluIGV4Y2VwdGlvbiBtZXNzYWdlcyBvZiAgSkFYUCAxLjMgWFBhdGggQVBJIGltcGxlbWVudGF0aW9uCi0KLSAgLy8gV2FybmluZ3MuLi4KLQotICB7IFdHX0xPQ0FMRV9OQU1FX05PVF9IQU5ETEVELAotICAgICAgIm5vbWUgZGFzIGNvbmZpZ3VyYVx1MDBFN1x1MDBGNWVzIHJlZ2lvbmFpcyBuYSBmdW5cdTAwRTdcdTAwRTNvIGZvcm1hdC1udW1iZXIgYWluZGEgblx1MDBFM28gdHJhdGFkbyEifSwKLQotICB7IFdHX1BST1BFUlRZX05PVF9TVVBQT1JURUQsCi0gICAgICAiUHJvcHJpZWRhZGUgWFNMIG5cdTAwRTNvIHN1cG9ydGFkYTogezB9In0sCi0KLSAgeyBXR19ET05UX0RPX0FOWVRISU5HX1dJVEhfTlMsCi0gICAgICAiTmVuaHVtYSBhXHUwMEU3XHUwMEUzbyBhIHNlciB0b21hZGEgY29tIG8gbmFtZXNwYWNlIHswfSBuYSBwcm9wcmllZGFkZTogezF9In0sCi0KLSAgeyBXR19TRUNVUklUWV9FWENFUFRJT04sCi0gICAgICAiU2VjdXJpdHlFeGNlcHRpb24gYW8gdGVudGFyIGFjZXNzYXIgYSBwcm9wcmllZGFkZSBkZSBzaXN0ZW1hIFhTTDogezB9In0sCi0KLSAgeyBXR19RVU9fTk9fTE9OR0VSX0RFRklORUQsCi0gICAgICAiU2ludGF4ZSBhbnRpZ2E6IHF1byguLi4pIG5cdTAwRTNvIGVzdFx1MDBFMSBtYWlzIGRlZmluaWRvIG5vIFhQYXRoLiJ9LAotCi0gIHsgV0dfTkVFRF9ERVJJVkVEX09CSkVDVF9UT19JTVBMRU1FTlRfTk9ERVRFU1QsCi0gICAgICAiWFBhdGggcmVxdWVyIHVtIG9iamV0byBkZXJpdmFkbyBwYXJhIGltcGxlbWVudGFyIG5vZGVUZXN0ISJ9LAotCi0gIHsgV0dfRlVOQ1RJT05fVE9LRU5fTk9UX0ZPVU5ELAotICAgICAgInRva2VuIGRhIGZ1blx1MDBFN1x1MDBFM28gblx1MDBFM28gZW5jb250cmFkby4ifSwKLQotICB7IFdHX0NPVUxETk9UX0ZJTkRfRlVOQ1RJT04sCi0gICAgICAiTlx1MDBFM28gZm9pIHBvc3NcdTAwRUR2ZWwgbG9jYWxpemFyIGEgZnVuXHUwMEU3XHUwMEUzbzogezB9In0sCi0KLSAgeyBXR19DQU5OT1RfTUFLRV9VUkxfRlJPTSwKLSAgICAgICJOXHUwMEUzbyBcdTAwRTkgcG9zc1x1MDBFRHZlbCBjcmlhciBvIFVSTCBkZTogezB9In0sCi0KLSAgeyBXR19FWFBBTkRfRU5USVRJRVNfTk9UX1NVUFBPUlRFRCwKLSAgICAgICJPcFx1MDBFN1x1MDBFM28gLUUgblx1MDBFM28gc3Vwb3J0YWRhIHBhcmEgbyBwYXJzZXIgRFRNIn0sCi0KLSAgeyBXR19JTExFR0FMX1ZBUklBQkxFX1JFRkVSRU5DRSwKLSAgICAgICJWYXJpYWJsZVJlZmVyZW5jZSBmb3JuZWNpZGEgcGFyYSBhIHZhcmlcdTAwRTF2ZWwgZm9yYSBkbyBjb250ZXh0byBvdSBzZW0gZGVmaW5pXHUwMEU3XHUwMEUzbyEgTm9tZSA9IHswfSJ9LAotCi0gIHsgV0dfVU5TVVBQT1JURURfRU5DT0RJTkcsCi0gICAgICJDb2RpZmljYVx1MDBFN1x1MDBFM28gblx1MDBFM28gc3Vwb3J0YWRhOiB7MH0ifSwKLQotCi0KLSAgLy8gT3RoZXIgbWlzY2VsbGFuZW91cyB0ZXh0IHVzZWQgaW5zaWRlIHRoZSBjb2RlLi4uCi0gIHsgInVpX2xhbmd1YWdlIiwgInB0LUJSIn0sCi0gIHsgImhlbHBfbGFuZ3VhZ2UiLCAicHQtQlIifSwKLSAgeyAibGFuZ3VhZ2UiLCAicHQtQlIifSwKLSAgeyAiQkFEX0NPREUiLCAiTyBwYXJcdTAwRTJtZXRybyBwYXJhIGNyZWF0ZU1lc3NhZ2UgZXN0YXZhIGZvcmEgZG9zIGxpbWl0ZXMifSwKLSAgeyAiRk9STUFUX0ZBSUxFRCIsICJFeGNlXHUwMEU3XHUwMEUzbyBnZXJhZGEgZHVyYW50ZSBhIGNoYW1hZGEgbWVzc2FnZUZvcm1hdCJ9LAotICB7ICJ2ZXJzaW9uIiwgIj4+Pj4+Pj4gVmVyc1x1MDBFM28gZG8gWGFsYW4gIn0sCi0gIHsgInZlcnNpb24yIiwgIjw8PDw8PDwifSwKLSAgeyAieWVzIiwgInNpbSJ9LAotICB7ICJsaW5lIiwgIk5cdTAwQjAgZGEgTGluaGEifSwKLSAgeyAiY29sdW1uIiwgIk5cdTAwQjAgZGEgQ29sdW5hIn0sCi0gIHsgInhzbGRvbmUiLCAiWFNMUHJvY2Vzc29yOiBjb25jbHVcdTAwRURkbyJ9LAotICB7ICJ4cGF0aF9vcHRpb24iLCAib3BcdTAwRTdcdTAwRjVlcyBkZSB4cGF0aDogIn0sCi0gIHsgIm9wdGlvbklOIiwgIiAgIFstaW4gaW5wdXRYTUxVUkxdIn0sCi0gIHsgIm9wdGlvblNlbGVjdCIsICIgICBbLXNlbGVjdCB4cGF0aCBleHByZXNzaW9uXSJ9LAotICB7ICJvcHRpb25NYXRjaCIsICIgICBbLW1hdGNoIG1hdGNoIHBhdHRlcm4gKHBhcmEgZGlhZ25cdTAwRjNzdGljb3MgY29ycmVzcG9uZGVudGVzKV0ifSwKLSAgeyAib3B0aW9uQW55RXhwciIsICJPdSBhcGVuYXMgdW1hIGV4cHJlc3NcdTAwRTNvIHhwYXRoIGZhclx1MDBFMSB1bWEgZWxpbWluYVx1MDBFN1x1MDBFM28gZGUgZGlhZ25cdTAwRjNzdGljb3MifSwKLSAgeyAibm9QYXJzZXJtc2cxIiwgIlByb2Nlc3NvIFhTTCBtYWxzdWNlZGlkby4ifSwKLSAgeyAibm9QYXJzZXJtc2cyIiwgIioqIE5cdTAwRTNvIGZvaSBwb3NzXHUwMEVEdmVsIGxvY2FsaXphciBvIHBhcnNlciAqKiJ9LAotICB7ICJub1BhcnNlcm1zZzMiLCAiVmVyaWZpcXVlIHNldSBjbGFzc3BhdGguIn0sCi0gIHsgIm5vUGFyc2VybXNnNCIsICJTZSB2b2NcdTAwRUEgblx1MDBFM28gdGl2ZXIgdW0gUGFyc2VyIFhNTCBkYSBJQk0gcGFyYSBKYXZhLCBwb2Rlclx1MDBFMSBmYXplciBkb3dubG9hZCBkZWxlIGVtIn0sCi0gIHsgIm5vUGFyc2VybXNnNSIsICJBbHBoYVdvcmtzIGRhIElCTTogaHR0cDovL3d3dy5hbHBoYXdvcmtzLmlibS5jb20vZm9ybXVsYS94bWwifSwKLSAgeyAiZ3RvbmUiLCAiPjEiIH0sCi0gIHsgInplcm8iLCAiMCIgfSwKLSAgeyAib25lIiwgIjEiIH0sCi0gIHsgInR3byIgLCAiMiIgfSwKLSAgeyAidGhyZWUiLCAiMyIgfQotCi0gIH07Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgYXNzb2NpYXRpb24gbGlzdC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgYXNzb2NpYXRpb24gbGlzdC4KLSAgICovCi0gIHB1YmxpYyBPYmplY3RbXVtdIGdldENvbnRlbnRzKCkKLSAgewotICAgICAgcmV0dXJuIF9jb250ZW50czsKLSAgfQotCi0KLSAgLy8gPT09PT09PT09PT09PT09PT0gSU5GUkFTVFJVQ1RVUkUgPT09PT09PT09PT09PT09PT09PT09PQotCi0gIC8qKiBGaWVsZCBCQURfQ09ERSAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBCQURfQ09ERSA9ICJCQURfQ09ERSI7Ci0KLSAgLyoqIEZpZWxkIEZPUk1BVF9GQUlMRUQgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRk9STUFUX0ZBSUxFRCA9ICJGT1JNQVRfRkFJTEVEIjsKLQotICAvKiogRmllbGQgRVJST1JfUkVTT1VSQ0VTICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUk9SX1JFU09VUkNFUyA9Ci0gICAgImNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5yZXMuWFBBVEhFcnJvclJlc291cmNlcyI7Ci0KLSAgLyoqIEZpZWxkIEVSUk9SX1NUUklORyAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJPUl9TVFJJTkcgPSAiI2Vycm9yIjsKLQotICAvKiogRmllbGQgRVJST1JfSEVBREVSICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUk9SX0hFQURFUiA9ICJFcnJvcjogIjsKLQotICAvKiogRmllbGQgV0FSTklOR19IRUFERVIgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0FSTklOR19IRUFERVIgPSAiV2FybmluZzogIjsKLQotICAvKiogRmllbGQgWFNMX0hFQURFUiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBYU0xfSEVBREVSID0gIlhTTCAiOwotCi0gIC8qKiBGaWVsZCBYTUxfSEVBREVSICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFhNTF9IRUFERVIgPSAiWE1MICI7Ci0KLSAgLyoqIEZpZWxkIFFVRVJZX0hFQURFUiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBRVUVSWV9IRUFERVIgPSAiUEFUVEVSTiAiOwotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL3Jlcy9YUEFUSEVycm9yUmVzb3VyY2VzX3N2LmphdmEgYi9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL3Jlcy9YUEFUSEVycm9yUmVzb3VyY2VzX3N2LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDM0YWQwZjEuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9yZXMvWFBBVEhFcnJvclJlc291cmNlc19zdi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTM2ICswLDAgQEAKLS8qCi0gKiByZXNlcnZlZCBjb21tZW50IGJsb2NrCi0gKiBETyBOT1QgUkVNT1ZFIE9SIEFMVEVSIQotICovCi0vKgotICogQ29weXJpZ2h0IDE5OTktMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLXBhY2thZ2UgY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLnJlczsKLQotaW1wb3J0IGphdmEudXRpbC5MaXN0UmVzb3VyY2VCdW5kbGU7Ci0KLS8qKgotICogU2V0IHVwIGVycm9yIG1lc3NhZ2VzLgotICogV2UgYnVpbGQgYSB0d28gZGltZW5zaW9uYWwgYXJyYXkgb2YgbWVzc2FnZSBrZXlzIGFuZAotICogbWVzc2FnZSBzdHJpbmdzLiBJbiBvcmRlciB0byBhZGQgYSBuZXcgbWVzc2FnZSBoZXJlLAotICogeW91IG5lZWQgdG8gZmlyc3QgYWRkIGEgU3RhdGljIHN0cmluZyBjb25zdGFudCBmb3IgdGhlCi0gKiBLZXkgYW5kIHVwZGF0ZSB0aGUgY29udGVudHMgYXJyYXkgd2l0aCBLZXksIFZhbHVlIHBhaXIKLSAgKiBBbHNvIHlvdSBuZWVkIHRvICB1cGRhdGUgdGhlIGNvdW50IG9mIG1lc3NhZ2VzKE1BWF9DT0RFKW9yCi0gKiB0aGUgY291bnQgb2Ygd2FybmluZ3MoTUFYX1dBUk5JTkcpIFsgSW5mb3JtYXRpb24gcHVycG9zZSBvbmx5XQotICogQHhzbC51c2FnZSBhZHZhbmNlZAotICovCi1wdWJsaWMgY2xhc3MgWFBBVEhFcnJvclJlc291cmNlc19zdiBleHRlbmRzIExpc3RSZXNvdXJjZUJ1bmRsZQotewotCi0vKgotICogR2VuZXJhbCBub3RlcyB0byB0cmFuc2xhdG9yczoKLSAqCi0gKiBUaGlzIGZpbGUgY29udGFpbnMgZXJyb3IgYW5kIHdhcm5pbmcgbWVzc2FnZXMgcmVsYXRlZCB0byBYUGF0aCBFcnJvcgotICogSGFuZGxpbmcuCi0gKgotICogIDEpIFhhbGFuIChvciBtb3JlIHByb3Blcmx5LCBYYWxhbi1pbnRlcnByZXRpdmUpIGFuZCBYU0xUQyBhcmUgbmFtZXMgb2YKLSAqICAgICBjb21wb25lbnRzLgotICogICAgIFhTTFQgaXMgYW4gYWNyb255bSBmb3IgIlhNTCBTdHlsZXNoZWV0IExhbmd1YWdlOiBUcmFuc2Zvcm1hdGlvbnMiLgotICogICAgIFhTTFRDIGlzIGFuIGFjcm9ueW0gZm9yIFhTTFQgQ29tcGlsZXIuCi0gKgotICogIDIpIEEgc3R5bGVzaGVldCBpcyBhIGRlc2NyaXB0aW9uIG9mIGhvdyB0byB0cmFuc2Zvcm0gYW4gaW5wdXQgWE1MIGRvY3VtZW50Ci0gKiAgICAgaW50byBhIHJlc3VsdGFudCBYTUwgZG9jdW1lbnQgKG9yIEhUTUwgZG9jdW1lbnQgb3IgdGV4dCkuICBUaGUKLSAqICAgICBzdHlsZXNoZWV0IGl0c2VsZiBpcyBkZXNjcmliZWQgaW4gdGhlIGZvcm0gb2YgYW4gWE1MIGRvY3VtZW50LgotICoKLSAqICAzKSBBIHRlbXBsYXRlIGlzIGEgY29tcG9uZW50IG9mIGEgc3R5bGVzaGVldCB0aGF0IGlzIHVzZWQgdG8gbWF0Y2ggYQotICogICAgIHBhcnRpY3VsYXIgcG9ydGlvbiBvZiBhbiBpbnB1dCBkb2N1bWVudCBhbmQgc3BlY2lmaWVzIHRoZSBmb3JtIG9mIHRoZQotICogICAgIGNvcnJlc3BvbmRpbmcgcG9ydGlvbiBvZiB0aGUgb3V0cHV0IGRvY3VtZW50LgotICoKLSAqICA0KSBBbiBlbGVtZW50IGlzIGEgbWFyay11cCB0YWcgaW4gYW4gWE1MIGRvY3VtZW50OyBhbiBhdHRyaWJ1dGUgaXMgYQotICogICAgIG1vZGlmaWVyIG9uIHRoZSB0YWcuICBGb3IgZXhhbXBsZSwgaW4gPGVsZW0gYXR0cj0ndmFsJyBhdHRyMj0ndmFsMic+Ci0gKiAgICAgImVsZW0iIGlzIGFuIGVsZW1lbnQgbmFtZSwgImF0dHIiIGFuZCAiYXR0cjIiIGFyZSBhdHRyaWJ1dGUgbmFtZXMgd2l0aAotICogICAgIHRoZSB2YWx1ZXMgInZhbCIgYW5kICJ2YWwyIiwgcmVzcGVjdGl2ZWx5LgotICoKLSAqICA1KSBBIG5hbWVzcGFjZSBkZWNsYXJhdGlvbiBpcyBhIHNwZWNpYWwgYXR0cmlidXRlIHRoYXQgaXMgdXNlZCB0byBhc3NvY2lhdGUKLSAqICAgICBhIHByZWZpeCB3aXRoIGEgVVJJICh0aGUgbmFtZXNwYWNlKS4gIFRoZSBtZWFuaW5ncyBvZiBlbGVtZW50IG5hbWVzIGFuZAotICogICAgIGF0dHJpYnV0ZSBuYW1lcyB0aGF0IHVzZSB0aGF0IHByZWZpeCBhcmUgZGVmaW5lZCB3aXRoIHJlc3BlY3QgdG8gdGhhdAotICogICAgIG5hbWVzcGFjZS4KLSAqCi0gKiAgNikgIlRyYW5zbGV0IiBpcyBhbiBpbnZlbnRlZCB0ZXJtIHRoYXQgZGVzY3JpYmVzIHRoZSBjbGFzcyBmaWxlIHRoYXQKLSAqICAgICByZXN1bHRzIGZyb20gY29tcGlsaW5nIGFuIFhNTCBzdHlsZXNoZWV0IGludG8gYSBKYXZhIGNsYXNzLgotICoKLSAqICA3KSBYUGF0aCBpcyBhIHNwZWNpZmljYXRpb24gdGhhdCBkZXNjcmliZXMgYSBub3RhdGlvbiBmb3IgaWRlbnRpZnlpbmcKLSAqICAgICBub2RlcyBpbiBhIHRyZWUtc3RydWN0dXJlZCByZXByZXNlbnRhdGlvbiBvZiBhbiBYTUwgZG9jdW1lbnQuICBBbgotICogICAgIGluc3RhbmNlIG9mIHRoYXQgbm90YXRpb24gaXMgcmVmZXJyZWQgdG8gYXMgYW4gWFBhdGggZXhwcmVzc2lvbi4KLSAqCi0gKiAgOCkgVGhlIGNvbnRleHQgbm9kZSBpcyB0aGUgbm9kZSBpbiB0aGUgZG9jdW1lbnQgd2l0aCByZXNwZWN0IHRvIHdoaWNoIGFuCi0gKiAgICAgWFBhdGggZXhwcmVzc2lvbiBpcyBiZWluZyBldmFsdWF0ZWQuCi0gKgotICogIDkpIEFuIGl0ZXJhdG9yIGlzIGFuIG9iamVjdCB0aGF0IHRyYXZlcnNlcyBub2RlcyBpbiB0aGUgdHJlZSwgb25lIGF0IGEgdGltZS4KLSAqCi0gKiAgMTApIE5DTmFtZSBpcyBhbiBYTUwgdGVybSB1c2VkIHRvIGRlc2NyaWJlIGEgbmFtZSB0aGF0IGRvZXMgbm90IGNvbnRhaW4gYQotICogICAgIGNvbG9uIChhICJuby1jb2xvbiBuYW1lIikuCi0gKgotICogIDExKSBRTmFtZSBpcyBhbiBYTUwgdGVybSBtZWFuaW5nICJxdWFsaWZpZWQgbmFtZSIuCi0gKi8KLQotICAvKgotICAgKiBzdGF0aWMgdmFyaWFibGVzCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJPUjAwMDAgPSAiRVJST1IwMDAwIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ1VSUkVOVF9OT1RfQUxMT1dFRF9JTl9NQVRDSCA9Ci0gICAgICAgICAiRVJfQ1VSUkVOVF9OT1RfQUxMT1dFRF9JTl9NQVRDSCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NVUlJFTlRfVEFLRVNfTk9fQVJHUyA9Ci0gICAgICAgICAiRVJfQ1VSUkVOVF9UQUtFU19OT19BUkdTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRE9DVU1FTlRfUkVQTEFDRUQgPSAiRVJfRE9DVU1FTlRfUkVQTEFDRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT05URVhUX0hBU19OT19PV05FUkRPQyA9Ci0gICAgICAgICAiRVJfQ09OVEVYVF9IQVNfTk9fT1dORVJET0MiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9MT0NBTE5BTUVfSEFTX1RPT19NQU5ZX0FSR1MgPQotICAgICAgICAgIkVSX0xPQ0FMTkFNRV9IQVNfVE9PX01BTllfQVJHUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05BTUVTUEFDRVVSSV9IQVNfVE9PX01BTllfQVJHUyA9Ci0gICAgICAgICAiRVJfTkFNRVNQQUNFVVJJX0hBU19UT09fTUFOWV9BUkdTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9STUFMSVpFU1BBQ0VfSEFTX1RPT19NQU5ZX0FSR1MgPQotICAgICAgICAgIkVSX05PUk1BTElaRVNQQUNFX0hBU19UT09fTUFOWV9BUkdTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTlVNQkVSX0hBU19UT09fTUFOWV9BUkdTID0KLSAgICAgICAgICJFUl9OVU1CRVJfSEFTX1RPT19NQU5ZX0FSR1MiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OQU1FX0hBU19UT09fTUFOWV9BUkdTID0KLSAgICAgICAgICJFUl9OQU1FX0hBU19UT09fTUFOWV9BUkdTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU1RSSU5HX0hBU19UT09fTUFOWV9BUkdTID0KLSAgICAgICAgICJFUl9TVFJJTkdfSEFTX1RPT19NQU5ZX0FSR1MiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TVFJJTkdMRU5HVEhfSEFTX1RPT19NQU5ZX0FSR1MgPQotICAgICAgICAgIkVSX1NUUklOR0xFTkdUSF9IQVNfVE9PX01BTllfQVJHUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1RSQU5TTEFURV9UQUtFU18zX0FSR1MgPQotICAgICAgICAgIkVSX1RSQU5TTEFURV9UQUtFU18zX0FSR1MiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTlBBUlNFREVOVElUWVVSSV9UQUtFU18xX0FSRyA9Ci0gICAgICAgICAiRVJfVU5QQVJTRURFTlRJVFlVUklfVEFLRVNfMV9BUkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OQU1FU1BBQ0VBWElTX05PVF9JTVBMRU1FTlRFRCA9Ci0gICAgICAgICAiRVJfTkFNRVNQQUNFQVhJU19OT1RfSU1QTEVNRU5URUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTktOT1dOX0FYSVMgPSAiRVJfVU5LTk9XTl9BWElTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5LTk9XTl9NQVRDSF9PUEVSQVRJT04gPQotICAgICAgICAgIkVSX1VOS05PV05fTUFUQ0hfT1BFUkFUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5DT1JSRUNUX0FSR19MRU5HVEggPSJFUl9JTkNPUlJFQ1RfQVJHX0xFTkdUSCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfQ09OVkVSVF9UT19OVU1CRVIgPQotICAgICAgICAgIkVSX0NBTlRfQ09OVkVSVF9UT19OVU1CRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX0NPTlZFUlRfWFBBVEhSRVNVTFRUWVBFX1RPX05VTUJFUiA9Ci0gICAgICAgICAgICJFUl9DQU5UX0NPTlZFUlRfWFBBVEhSRVNVTFRUWVBFX1RPX05VTUJFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfQ09OVkVSVF9UT19OT0RFTElTVCA9Ci0gICAgICAgICAiRVJfQ0FOVF9DT05WRVJUX1RPX05PREVMSVNUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9DT05WRVJUX1RPX01VVEFCTEVOT0RFTElTVCA9Ci0gICAgICAgICAiRVJfQ0FOVF9DT05WRVJUX1RPX01VVEFCTEVOT0RFTElTVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfQ09OVkVSVF9UT19UWVBFID0iRVJfQ0FOVF9DT05WRVJUX1RPX1RZUEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FWFBFQ1RFRF9NQVRDSF9QQVRURVJOID0KLSAgICAgICAgICJFUl9FWFBFQ1RFRF9NQVRDSF9QQVRURVJOIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTEROT1RfR0VUX1ZBUl9OQU1FRCA9Ci0gICAgICAgICAiRVJfQ09VTEROT1RfR0VUX1ZBUl9OQU1FRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1VOS05PV05fT1BDT0RFID0gIkVSX1VOS05PV05fT1BDT0RFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhUUkFfSUxMRUdBTF9UT0tFTlMgPSJFUl9FWFRSQV9JTExFR0FMX1RPS0VOUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYUEVDVEVEX0RPVUJMRV9RVU9URSA9Ci0gICAgICAgICAiRVJfRVhQRUNURURfRE9VQkxFX1FVT1RFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhQRUNURURfU0lOR0xFX1FVT1RFID0KLSAgICAgICAgICJFUl9FWFBFQ1RFRF9TSU5HTEVfUVVPVEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FTVBUWV9FWFBSRVNTSU9OID0gIkVSX0VNUFRZX0VYUFJFU1NJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FWFBFQ1RFRF9CVVRfRk9VTkQgPSAiRVJfRVhQRUNURURfQlVUX0ZPVU5EIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5DT1JSRUNUX1BST0dSQU1NRVJfQVNTRVJUSU9OID0KLSAgICAgICAgICJFUl9JTkNPUlJFQ1RfUFJPR1JBTU1FUl9BU1NFUlRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9CT09MRUFOX0FSR19OT19MT05HRVJfT1BUSU9OQUwgPQotICAgICAgICAgIkVSX0JPT0xFQU5fQVJHX05PX0xPTkdFUl9PUFRJT05BTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZPVU5EX0NPTU1BX0JVVF9OT19QUkVDRURJTkdfQVJHID0KLSAgICAgICAgICJFUl9GT1VORF9DT01NQV9CVVRfTk9fUFJFQ0VESU5HX0FSRyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZPVU5EX0NPTU1BX0JVVF9OT19GT0xMT1dJTkdfQVJHID0KLSAgICAgICAgICJFUl9GT1VORF9DT01NQV9CVVRfTk9fRk9MTE9XSU5HX0FSRyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BSRURJQ0FURV9JTExFR0FMX1NZTlRBWCA9Ci0gICAgICAgICAiRVJfUFJFRElDQVRFX0lMTEVHQUxfU1lOVEFYIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSUxMRUdBTF9BWElTX05BTUUgPSAiRVJfSUxMRUdBTF9BWElTX05BTUUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTktOT1dOX05PREVUWVBFID0gIkVSX1VOS05PV05fTk9ERVRZUEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QQVRURVJOX0xJVEVSQUxfTkVFRFNfQkVfUVVPVEVEID0KLSAgICAgICAgICJFUl9QQVRURVJOX0xJVEVSQUxfTkVFRFNfQkVfUVVPVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTEROT1RfQkVfRk9STUFUVEVEX1RPX05VTUJFUiA9Ci0gICAgICAgICAiRVJfQ09VTEROT1RfQkVfRk9STUFUVEVEX1RPX05VTUJFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxETk9UX0NSRUFURV9YTUxQUk9DRVNTT1JMSUFJU09OID0KLSAgICAgICAgICJFUl9DT1VMRE5PVF9DUkVBVEVfWE1MUFJPQ0VTU09STElBSVNPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0RJRE5PVF9GSU5EX1hQQVRIX1NFTEVDVF9FWFAgPQotICAgICAgICAgIkVSX0RJRE5PVF9GSU5EX1hQQVRIX1NFTEVDVF9FWFAiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRE5PVF9GSU5EX0VORE9QX0FGVEVSX09QTE9DQVRJT05QQVRIID0KLSAgICAgICAgICJFUl9DT1VMRE5PVF9GSU5EX0VORE9QX0FGVEVSX09QTE9DQVRJT05QQVRIIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVJST1JfT0NDVVJFRCA9ICJFUl9FUlJPUl9PQ0NVUkVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSUxMRUdBTF9WQVJJQUJMRV9SRUZFUkVOQ0UgPQotICAgICAgICAgIkVSX0lMTEVHQUxfVkFSSUFCTEVfUkVGRVJFTkNFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQVhFU19OT1RfQUxMT1dFRCA9ICJFUl9BWEVTX05PVF9BTExPV0VEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfS0VZX0hBU19UT09fTUFOWV9BUkdTID0KLSAgICAgICAgICJFUl9LRVlfSEFTX1RPT19NQU5ZX0FSR1MiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VOVF9UQUtFU18xX0FSRyA9ICJFUl9DT1VOVF9UQUtFU18xX0FSRyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxETk9UX0ZJTkRfRlVOQ1RJT04gPQotICAgICAgICAgIkVSX0NPVUxETk9UX0ZJTkRfRlVOQ1RJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTlNVUFBPUlRFRF9FTkNPRElORyA9IkVSX1VOU1VQUE9SVEVEX0VOQ09ESU5HIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJPQkxFTV9JTl9EVE1fTkVYVFNJQkxJTkcgPQotICAgICAgICAgIkVSX1BST0JMRU1fSU5fRFRNX05FWFRTSUJMSU5HIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX1dSSVRFX1RPX0VNUFRZTk9ERUxJU1RJTVBMID0KLSAgICAgICAgICJFUl9DQU5OT1RfV1JJVEVfVE9fRU1QVFlOT0RFTElTVElNUEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TRVRET01GQUNUT1JZX05PVF9TVVBQT1JURUQgPQotICAgICAgICAgIkVSX1NFVERPTUZBQ1RPUllfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BSRUZJWF9NVVNUX1JFU09MVkUgPSAiRVJfUFJFRklYX01VU1RfUkVTT0xWRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BBUlNFX05PVF9TVVBQT1JURUQgPSAiRVJfUEFSU0VfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NBWF9BUElfTk9UX0hBTkRMRUQgPSAiRVJfU0FYX0FQSV9OT1RfSEFORExFRCI7Ci1wdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JR05PUkFCTEVfV0hJVEVTUEFDRV9OT1RfSEFORExFRCA9Ci0gICAgICAgICAiRVJfSUdOT1JBQkxFX1dISVRFU1BBQ0VfTk9UX0hBTkRMRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9EVE1fQ0FOTk9UX0hBTkRMRV9OT0RFUyA9Ci0gICAgICAgICAiRVJfRFRNX0NBTk5PVF9IQU5ETEVfTk9ERVMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YRVJDRVNfQ0FOTk9UX0hBTkRMRV9OT0RFUyA9Ci0gICAgICAgICAiRVJfWEVSQ0VTX0NBTk5PVF9IQU5ETEVfTk9ERVMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YRVJDRVNfUEFSU0VfRVJST1JfREVUQUlMUyA9Ci0gICAgICAgICAiRVJfWEVSQ0VTX1BBUlNFX0VSUk9SX0RFVEFJTFMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YRVJDRVNfUEFSU0VfRVJST1IgPSAiRVJfWEVSQ0VTX1BBUlNFX0VSUk9SIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5WQUxJRF9VVEYxNl9TVVJST0dBVEUgPQotICAgICAgICAgIkVSX0lOVkFMSURfVVRGMTZfU1VSUk9HQVRFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfT0lFUlJPUiA9ICJFUl9PSUVSUk9SIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX0NSRUFURV9VUkwgPSAiRVJfQ0FOTk9UX0NSRUFURV9VUkwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YUEFUSF9SRUFET0JKRUNUID0gIkVSX1hQQVRIX1JFQURPQkpFQ1QiOwotIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZVTkNUSU9OX1RPS0VOX05PVF9GT1VORCA9Ci0gICAgICAgICAiRVJfRlVOQ1RJT05fVE9LRU5fTk9UX0ZPVU5EIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX0RFQUxfWFBBVEhfVFlQRSA9Ci0gICAgICAgICAiRVJfQ0FOTk9UX0RFQUxfWFBBVEhfVFlQRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PREVTRVRfTk9UX01VVEFCTEUgPSAiRVJfTk9ERVNFVF9OT1RfTVVUQUJMRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PREVTRVREVE1fTk9UX01VVEFCTEUgPQotICAgICAgICAgIkVSX05PREVTRVREVE1fTk9UX01VVEFCTEUiOwotICAgLyoqICBWYXJpYWJsZSBub3QgcmVzb2x2YWJsZTogICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9WQVJfTk9UX1JFU09MVkFCTEUgPSAiRVJfVkFSX05PVF9SRVNPTFZBQkxFIjsKLSAgIC8qKiBOdWxsIGVycm9yIGhhbmRsZXIgICovCi0gcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTlVMTF9FUlJPUl9IQU5ETEVSID0gIkVSX05VTExfRVJST1JfSEFORExFUiI7Ci0gICAvKiogIFByb2dyYW1tZXIncyBhc3NlcnRpb246IHVua25vd24gb3Bjb2RlICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUk9HX0FTU0VSVF9VTktOT1dOX09QQ09ERSA9Ci0gICAgICAgICAiRVJfUFJPR19BU1NFUlRfVU5LTk9XTl9PUENPREUiOwotICAgLyoqICAwIG9yIDEgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9aRVJPX09SX09ORSA9ICJFUl9aRVJPX09SX09ORSI7Ci0gICAvKiogIHJ0ZigpIG5vdCBzdXBwb3J0ZWQgYnkgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SVEZfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiA9Ci0gICAgICAgICAiRVJfUlRGX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIiOwotICAgLyoqICBhc05vZGVJdGVyYXRvcigpIG5vdCBzdXBwb3J0ZWQgYnkgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9BU05PREVJVEVSQVRPUl9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSID0gIkVSX0FTTk9ERUlURVJBVE9SX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIiOwotICAgLyoqICBmc2IoKSBub3Qgc3VwcG9ydGVkIGZvciBYU3RyaW5nRm9yQ2hhcnMgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GU0JfTk9UX1NVUFBPUlRFRF9YU1RSSU5HRk9SQ0hBUlMgPQotICAgICAgICAgIkVSX0ZTQl9OT1RfU1VQUE9SVEVEX1hTVFJJTkdGT1JDSEFSUyI7Ci0gICAvKiogIENvdWxkIG5vdCBmaW5kIHZhcmlhYmxlIHdpdGggdGhlIG5hbWUgb2YgICAqLwotIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxEX05PVF9GSU5EX1ZBUiA9ICJFUl9DT1VMRF9OT1RfRklORF9WQVIiOwotICAgLyoqICBYU3RyaW5nRm9yQ2hhcnMgY2FuIG5vdCB0YWtlIGEgc3RyaW5nIGZvciBhbiBhcmd1bWVudCAgICovCi0gcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWFNUUklOR0ZPUkNIQVJTX0NBTk5PVF9UQUtFX1NUUklORyA9Ci0gICAgICAgICAiRVJfWFNUUklOR0ZPUkNIQVJTX0NBTk5PVF9UQUtFX1NUUklORyI7Ci0gICAvKiogIFRoZSBGYXN0U3RyaW5nQnVmZmVyIGFyZ3VtZW50IGNhbiBub3QgYmUgbnVsbCAgICovCi0gcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRkFTVFNUUklOR0JVRkZFUl9DQU5OT1RfQkVfTlVMTCA9Ci0gICAgICAgICAiRVJfRkFTVFNUUklOR0JVRkZFUl9DQU5OT1RfQkVfTlVMTCI7Ci0gICAvKiogIDIgb3IgMyAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1RXT19PUl9USFJFRSA9ICJFUl9UV09fT1JfVEhSRUUiOwotICAgLyoqIFZhcmlhYmxlIGFjY2Vzc2VkIGJlZm9yZSBpdCBpcyBib3VuZCEgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVkFSSUFCTEVfQUNDRVNTRURfQkVGT1JFX0JJTkQgPQotICAgICAgICAgIkVSX1ZBUklBQkxFX0FDQ0VTU0VEX0JFRk9SRV9CSU5EIjsKLSAgIC8qKiBYU3RyaW5nRm9yRlNCIGNhbiBub3QgdGFrZSBhIHN0cmluZyBmb3IgYW4gYXJndW1lbnQhICovCi0gcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRlNCX0NBTk5PVF9UQUtFX1NUUklORyA9Ci0gICAgICAgICAiRVJfRlNCX0NBTk5PVF9UQUtFX1NUUklORyI7Ci0gICAvKiogRXJyb3IhIFNldHRpbmcgdGhlIHJvb3Qgb2YgYSB3YWxrZXIgdG8gbnVsbCEgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU0VUVElOR19XQUxLRVJfUk9PVF9UT19OVUxMID0KLSAgICAgICAgICJFUl9TRVRUSU5HX1dBTEtFUl9ST09UX1RPX05VTEwiOwotICAgLyoqIFRoaXMgTm9kZVNldERUTSBjYW4gbm90IGl0ZXJhdGUgdG8gYSBwcmV2aW91cyBub2RlISAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT0RFU0VURFRNX0NBTk5PVF9JVEVSQVRFID0KLSAgICAgICAgICJFUl9OT0RFU0VURFRNX0NBTk5PVF9JVEVSQVRFIjsKLSAgLyoqIFRoaXMgTm9kZVNldCBjYW4gbm90IGl0ZXJhdGUgdG8gYSBwcmV2aW91cyBub2RlISAqLwotIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PREVTRVRfQ0FOTk9UX0lURVJBVEUgPQotICAgICAgICAgIkVSX05PREVTRVRfQ0FOTk9UX0lURVJBVEUiOwotICAvKiogVGhpcyBOb2RlU2V0RFRNIGNhbiBub3QgZG8gaW5kZXhpbmcgb3IgY291bnRpbmcgZnVuY3Rpb25zISAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT0RFU0VURFRNX0NBTk5PVF9JTkRFWCA9Ci0gICAgICAgICAiRVJfTk9ERVNFVERUTV9DQU5OT1RfSU5ERVgiOwotICAvKiogVGhpcyBOb2RlU2V0IGNhbiBub3QgZG8gaW5kZXhpbmcgb3IgY291bnRpbmcgZnVuY3Rpb25zISAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT0RFU0VUX0NBTk5PVF9JTkRFWCA9Ci0gICAgICAgICAiRVJfTk9ERVNFVF9DQU5OT1RfSU5ERVgiOwotICAvKiogQ2FuIG5vdCBjYWxsIHNldFNob3VsZENhY2hlTm9kZXMgYWZ0ZXIgbmV4dE5vZGUgaGFzIGJlZW4gY2FsbGVkISAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5OT1RfQ0FMTF9TRVRTSE9VTERDQUNIRU5PREUgPQotICAgICAgICAgIkVSX0NBTk5PVF9DQUxMX1NFVFNIT1VMRENBQ0hFTk9ERSI7Ci0gIC8qKiB7MH0gb25seSBhbGxvd3MgezF9IGFyZ3VtZW50cyAqLwotIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX09OTFlfQUxMT1dTID0gIkVSX09OTFlfQUxMT1dTIjsKLSAgLyoqIFByb2dyYW1tZXIncyBhc3NlcnRpb24gaW4gZ2V0TmV4dFN0ZXBQb3M6IHVua25vd24gc3RlcFR5cGU6IHswfSAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTktOT1dOX1NURVAgPSAiRVJfVU5LTk9XTl9TVEVQIjsKLSAgLyoqIFByb2JsZW0gd2l0aCBSZWxhdGl2ZUxvY2F0aW9uUGF0aCAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FWFBFQ1RFRF9SRUxfTE9DX1BBVEggPQotICAgICAgICAgIkVSX0VYUEVDVEVEX1JFTF9MT0NfUEFUSCI7Ci0gIC8qKiBQcm9ibGVtIHdpdGggTG9jYXRpb25QYXRoICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYUEVDVEVEX0xPQ19QQVRIID0gIkVSX0VYUEVDVEVEX0xPQ19QQVRIIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhQRUNURURfTE9DX1BBVEhfQVRfRU5EX0VYUFIgPQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJFUl9FWFBFQ1RFRF9MT0NfUEFUSF9BVF9FTkRfRVhQUiI7Ci0gIC8qKiBQcm9ibGVtIHdpdGggU3RlcCAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FWFBFQ1RFRF9MT0NfU1RFUCA9ICJFUl9FWFBFQ1RFRF9MT0NfU1RFUCI7Ci0gIC8qKiBQcm9ibGVtIHdpdGggTm9kZVRlc3QgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhQRUNURURfTk9ERV9URVNUID0gIkVSX0VYUEVDVEVEX05PREVfVEVTVCI7Ci0gIC8qKiBFeHBlY3RlZCBzdGVwIHBhdHRlcm4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhQRUNURURfU1RFUF9QQVRURVJOID0KLSAgICAgICAgIkVSX0VYUEVDVEVEX1NURVBfUEFUVEVSTiI7Ci0gIC8qKiBFeHBlY3RlZCByZWxhdGl2ZSBwYXRoIHBhdHRlcm4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhQRUNURURfUkVMX1BBVEhfUEFUVEVSTiA9Ci0gICAgICAgICAiRVJfRVhQRUNURURfUkVMX1BBVEhfUEFUVEVSTiI7Ci0gIC8qKiBFUl9DQU5UX0NPTlZFUlRfWFBBVEhSRVNVTFRUWVBFX1RPX0JPT0xFQU4gICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9DT05WRVJUX1RPX0JPT0xFQU4gPQotICAgICAgICAgIkVSX0NBTlRfQ09OVkVSVF9UT19CT09MRUFOIjsKLSAgLyoqIEZpZWxkIEVSX0NBTlRfQ09OVkVSVF9UT19TSU5HTEVOT0RFICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfQ09OVkVSVF9UT19TSU5HTEVOT0RFID0KLSAgICAgICAgICJFUl9DQU5UX0NPTlZFUlRfVE9fU0lOR0xFTk9ERSI7Ci0gIC8qKiBGaWVsZCBFUl9DQU5UX0dFVF9TTkFQU0hPVF9MRU5HVEggICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX0dFVF9TTkFQU0hPVF9MRU5HVEggPQotICAgICAgICAgIkVSX0NBTlRfR0VUX1NOQVBTSE9UX0xFTkdUSCI7Ci0gIC8qKiBGaWVsZCBFUl9OT05fSVRFUkFUT1JfVFlQRSAgICAgICAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT05fSVRFUkFUT1JfVFlQRSA9ICJFUl9OT05fSVRFUkFUT1JfVFlQRSI7Ci0gIC8qKiBGaWVsZCBFUl9ET0NfTVVUQVRFRCAgICAgICAgICAgICAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9ET0NfTVVUQVRFRCA9ICJFUl9ET0NfTVVUQVRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfWFBBVEhfVFlQRSA9ICJFUl9JTlZBTElEX1hQQVRIX1RZUEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FTVBUWV9YUEFUSF9SRVNVTFQgPSAiRVJfRU1QVFlfWFBBVEhfUkVTVUxUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSU5DT01QQVRJQkxFX1RZUEVTID0gIkVSX0lOQ09NUEFUSUJMRV9UWVBFUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05VTExfUkVTT0xWRVIgPSAiRVJfTlVMTF9SRVNPTFZFUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfQ09OVkVSVF9UT19TVFJJTkcgPQotICAgICAgICAgIkVSX0NBTlRfQ09OVkVSVF9UT19TVFJJTkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT05fU05BUFNIT1RfVFlQRSA9ICJFUl9OT05fU05BUFNIT1RfVFlQRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1dST05HX0RPQ1VNRU5UID0gIkVSX1dST05HX0RPQ1VNRU5UIjsKLSAgLyogTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBYUGF0aCBleHByZXNzaW9uIGNhbm5vdCBiZSBldmFsdWF0ZWQgd2l0aCByZXNwZWN0Ci0gICAqIHRvIHRoaXMgdHlwZSBvZiBub2RlLgotICAgKi8KLSAgLyoqIEZpZWxkIEVSX1dST05HX05PREVUWVBFICAgICAgICAgICAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9XUk9OR19OT0RFVFlQRSA9ICJFUl9XUk9OR19OT0RFVFlQRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hQQVRIX0VSUk9SID0gIkVSX1hQQVRIX0VSUk9SIjsKLQotICAvL0JFR0lOOiBLZXlzIG5lZWRlZCBmb3IgZXhjZXB0aW9uIG1lc3NhZ2VzIG9mICBKQVhQIDEuMyBYUGF0aCBBUEkgaW1wbGVtZW50YXRpb24KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhURU5TSU9OX0ZVTkNUSU9OX0NBTk5PVF9CRV9JTlZPS0VEID0gIkVSX0VYVEVOU0lPTl9GVU5DVElPTl9DQU5OT1RfQkVfSU5WT0tFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1JFU09MVkVfVkFSSUFCTEVfUkVUVVJOU19OVUxMID0gIkVSX1JFU09MVkVfVkFSSUFCTEVfUkVUVVJOU19OVUxMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5TVVBQT1JURURfUkVUVVJOX1RZUEUgPSAiRVJfVU5TVVBQT1JURURfUkVUVVJOX1RZUEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TT1VSQ0VfUkVUVVJOX1RZUEVfQ0FOTk9UX0JFX05VTEwgPSAiRVJfU09VUkNFX1JFVFVSTl9UWVBFX0NBTk5PVF9CRV9OVUxMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQVJHX0NBTk5PVF9CRV9OVUxMID0gIkVSX0FSR19DQU5OT1RfQkVfTlVMTCI7Ci0KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfT0JKRUNUX01PREVMX05VTEwgPSAiRVJfT0JKRUNUX01PREVMX05VTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9PQkpFQ1RfTU9ERUxfRU1QVFkgPSAiRVJfT0JKRUNUX01PREVMX0VNUFRZIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRkVBVFVSRV9OQU1FX05VTEwgPSAiRVJfRkVBVFVSRV9OQU1FX05VTEwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GRUFUVVJFX1VOS05PV04gPSAiRVJfRkVBVFVSRV9VTktOT1dOIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfR0VUVElOR19OVUxMX0ZFQVRVUkUgPSAiRVJfR0VUVElOR19OVUxMX0ZFQVRVUkUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9HRVRUSU5HX1VOS05PV05fRkVBVFVSRSA9ICJFUl9HRVRUSU5HX1VOS05PV05fRkVBVFVSRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NFQ1VSRVBST0NFU1NJTkdfRkVBVFVSRSA9ICJFUl9TRUNVUkVQUk9DRVNTSU5HX0ZFQVRVUkUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OVUxMX1hQQVRIX0ZVTkNUSU9OX1JFU09MVkVSID0gIkVSX05VTExfWFBBVEhfRlVOQ1RJT05fUkVTT0xWRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OVUxMX1hQQVRIX1ZBUklBQkxFX1JFU09MVkVSID0gIkVSX05VTExfWFBBVEhfVkFSSUFCTEVfUkVTT0xWRVIiOwotICAvL0VORDogS2V5cyBuZWVkZWQgZm9yIGV4Y2VwdGlvbiBtZXNzYWdlcyBvZiAgSkFYUCAxLjMgWFBhdGggQVBJIGltcGxlbWVudGF0aW9uCi0KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfTE9DQUxFX05BTUVfTk9UX0hBTkRMRUQgPQotICAgICAgICAgIldHX0xPQ0FMRV9OQU1FX05PVF9IQU5ETEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfUFJPUEVSVFlfTk9UX1NVUFBPUlRFRCA9Ci0gICAgICAgICAiV0dfUFJPUEVSVFlfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0RPTlRfRE9fQU5ZVEhJTkdfV0lUSF9OUyA9Ci0gICAgICAgICAiV0dfRE9OVF9ET19BTllUSElOR19XSVRIX05TIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfU0VDVVJJVFlfRVhDRVBUSU9OID0gIldHX1NFQ1VSSVRZX0VYQ0VQVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX1FVT19OT19MT05HRVJfREVGSU5FRCA9Ci0gICAgICAgICAiV0dfUVVPX05PX0xPTkdFUl9ERUZJTkVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfTkVFRF9ERVJJVkVEX09CSkVDVF9UT19JTVBMRU1FTlRfTk9ERVRFU1QgPQotICAgICAgICAgIldHX05FRURfREVSSVZFRF9PQkpFQ1RfVE9fSU1QTEVNRU5UX05PREVURVNUIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfRlVOQ1RJT05fVE9LRU5fTk9UX0ZPVU5EID0KLSAgICAgICAgICJXR19GVU5DVElPTl9UT0tFTl9OT1RfRk9VTkQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19DT1VMRE5PVF9GSU5EX0ZVTkNUSU9OID0KLSAgICAgICAgICJXR19DT1VMRE5PVF9GSU5EX0ZVTkNUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfQ0FOTk9UX01BS0VfVVJMX0ZST00gPSJXR19DQU5OT1RfTUFLRV9VUkxfRlJPTSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0VYUEFORF9FTlRJVElFU19OT1RfU1VQUE9SVEVEID0KLSAgICAgICAgICJXR19FWFBBTkRfRU5USVRJRVNfTk9UX1NVUFBPUlRFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0lMTEVHQUxfVkFSSUFCTEVfUkVGRVJFTkNFID0KLSAgICAgICAgICJXR19JTExFR0FMX1ZBUklBQkxFX1JFRkVSRU5DRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX1VOU1VQUE9SVEVEX0VOQ09ESU5HID0iV0dfVU5TVVBQT1JURURfRU5DT0RJTkciOwotCi0gIC8qKiAgZGV0YWNoKCkgbm90IHN1cHBvcnRlZCBieSBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0RFVEFDSF9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSID0KLSAgICAgICAgICJFUl9ERVRBQ0hfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiI7Ci0gIC8qKiAgbnVtKCkgbm90IHN1cHBvcnRlZCBieSBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05VTV9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSID0KLSAgICAgICAgICJFUl9OVU1fTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiI7Ci0gIC8qKiAgeHN0cigpIG5vdCBzdXBwb3J0ZWQgYnkgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YU1RSX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIgPQotICAgICAgICAgIkVSX1hTVFJfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiI7Ci0gIC8qKiAgc3RyKCkgbm90IHN1cHBvcnRlZCBieSBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NUUl9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSID0KLSAgICAgICAgICJFUl9TVFJfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiI7Ci0KLSAgLy8gRXJyb3IgbWVzc2FnZXMuLi4KLQotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBPYmplY3RbXVtdIF9jb250ZW50cyA9IG5ldyBPYmplY3RbXVtdewotCi0gIHsgIkVSUk9SMDAwMCIgLCAiezB9IiB9LAotCi0gIHsgRVJfQ1VSUkVOVF9OT1RfQUxMT1dFRF9JTl9NQVRDSCwgIkZ1bmt0aW9uZW4gY3VycmVudCgpIFx1MDBFNHIgaW50ZSB0aWxsXHUwMEU1dGVuIGkgZXR0IG1hdGNobmluZ3NtXHUwMEY2bnN0ZXIhIiB9LAotCi0gIHsgRVJfQ1VSUkVOVF9UQUtFU19OT19BUkdTLCAiRnVua3Rpb25lbiBjdXJyZW50KCkgdGFyIGludGUgZW1vdCBhcmd1bWVudCEiIH0sCi0KLSAgeyBFUl9ET0NVTUVOVF9SRVBMQUNFRCwKLSAgICAgICJJbXBsZW1lbnRlcmluZ2VuIGF2IGZ1bmt0aW9uZW4gZG9jdW1lbnQoKSBoYXIgaW50ZSBlcnNhdHRzIGF2IGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0LkZ1bmNEb2N1bWVudCEifSwKLQotICB7IEVSX0NPTlRFWFRfSEFTX05PX09XTkVSRE9DLAotICAgICAgImNvbnRleHQgaGFyIGluZ2V0IFx1MDBFNGdhcmRva3VtZW50ISJ9LAotCi0gIHsgRVJfTE9DQUxOQU1FX0hBU19UT09fTUFOWV9BUkdTLAotICAgICAgImxvY2FsLW5hbWUoKSBoYXIgZlx1MDBGNnIgbVx1MDBFNW5nYSBhcmd1bWVudC4ifSwKLQotICB7IEVSX05BTUVTUEFDRVVSSV9IQVNfVE9PX01BTllfQVJHUywKLSAgICAgICJuYW1lc3BhY2UtdXJpKCkgaGFyIGZcdTAwRjZyIG1cdTAwRTVuZ2EgYXJndW1lbnQuIn0sCi0KLSAgeyBFUl9OT1JNQUxJWkVTUEFDRV9IQVNfVE9PX01BTllfQVJHUywKLSAgICAgICJub3JtYWxpemUtc3BhY2UoKSBoYXIgZlx1MDBGNnIgbVx1MDBFNW5nYSBhcmd1bWVudC4ifSwKLQotICB7IEVSX05VTUJFUl9IQVNfVE9PX01BTllfQVJHUywKLSAgICAgICJudW1iZXIoKSBoYXIgZlx1MDBGNnIgbVx1MDBFNW5nYSBhcmd1bWVudC4ifSwKLQotICB7IEVSX05BTUVfSEFTX1RPT19NQU5ZX0FSR1MsCi0gICAgICJuYW1lKCkgaGFyIGZcdTAwRjZyIG1cdTAwRTVuZ2EgYXJndW1lbnQuIn0sCi0KLSAgeyBFUl9TVFJJTkdfSEFTX1RPT19NQU5ZX0FSR1MsCi0gICAgICAic3RyaW5nKCkgaGFyIGZcdTAwRjZyIG1cdTAwRTVuZ2EgYXJndW1lbnQuIn0sCi0KLSAgeyBFUl9TVFJJTkdMRU5HVEhfSEFTX1RPT19NQU5ZX0FSR1MsCi0gICAgICAic3RyaW5nLWxlbmd0aCgpIGhhciBmXHUwMEY2ciBtXHUwMEU1bmdhIGFyZ3VtZW50LiJ9LAotCi0gIHsgRVJfVFJBTlNMQVRFX1RBS0VTXzNfQVJHUywKLSAgICAgICJGdW5rdGlvbmVuIHRyYW5zbGF0ZSgpIHRhciBlbW90IHRyZSBhcmd1bWVudCEifSwKLQotICB7IEVSX1VOUEFSU0VERU5USVRZVVJJX1RBS0VTXzFfQVJHLAotICAgICAgIkZ1bmt0aW9uZW4gdW5wYXJzZWQtZW50aXR5LXVyaSBib3JkZSB0YSBlbW90IGV0dCBhcmd1bWVudCEifSwKLQotICB7IEVSX05BTUVTUEFDRUFYSVNfTk9UX0lNUExFTUVOVEVELAotICAgICAgIm5hbW5yeW1kc2F4ZWxuIFx1MDBFNHIgaW50ZSBpbXBsZW1lbnRlcmFkIFx1MDBFNG4hIn0sCi0KLSAgeyBFUl9VTktOT1dOX0FYSVMsCi0gICAgICJva1x1MDBFNG5kIGF4ZWw6IHswfSJ9LAotCi0gIHsgRVJfVU5LTk9XTl9NQVRDSF9PUEVSQVRJT04sCi0gICAgICJva1x1MDBFNG5kIG1hdGNobmluZ3NcdTAwRTV0Z1x1MDBFNHJkISJ9LAotCi0gIHsgRVJfSU5DT1JSRUNUX0FSR19MRU5HVEgsCi0gICAgICAiRmVsYWt0aWcgYXJndW1lbnRsXHUwMEU0bmdkIHBcdTAwRTUgbm9kdGVzdCBmXHUwMEY2ciBwcm9jZXNzaW5nLWluc3RydWN0aW9uKCkhIn0sCi0KLSAgeyBFUl9DQU5UX0NPTlZFUlRfVE9fTlVNQkVSLAotICAgICAgIkthbiBpbnRlIGtvbnZlcnRlcmEgezB9IHRpbGwgZXR0IHRhbCJ9LAotCi0gIHsgRVJfQ0FOVF9DT05WRVJUX1RPX05PREVMSVNULAotICAgICAgIkthbiBpbnRlIGtvbnZlcnRlcmEgezB9IHRpbGwgTm9kZUxpc3QhIn0sCi0KLSAgeyBFUl9DQU5UX0NPTlZFUlRfVE9fTVVUQUJMRU5PREVMSVNULAotICAgICAgIkthbiBpbnRlIGtvbnZlcnRlcmEgezB9IHRpbGwgTm9kZVNldERUTSEifSwKLQotICB7IEVSX0NBTlRfQ09OVkVSVF9UT19UWVBFLAotICAgICAgIkthbiBpbnRlIGtvbnZlcnRlcmEgezB9IHRpbGwgdHlwZSN7MX0ifSwKLQotICB7IEVSX0VYUEVDVEVEX01BVENIX1BBVFRFUk4sCi0gICAgICAiRlx1MDBGNnJ2XHUwMEU0bnRhdCBtYXRjaG5pbmdzbVx1MDBGNm5zdGVyIGkgZ2V0TWF0Y2hTY29yZSEifSwKLQotICB7IEVSX0NPVUxETk9UX0dFVF9WQVJfTkFNRUQsCi0gICAgICAiS3VuZGUgaW50ZSBoXHUwMEU0bXRhIHZhcmlhYmVsbiB7MH0ifSwKLQotICB7IEVSX1VOS05PV05fT1BDT0RFLAotICAgICAiRkVMISBPa1x1MDBFNG5kIG9wLWtvZDogezB9In0sCi0KLSAgeyBFUl9FWFRSQV9JTExFR0FMX1RPS0VOUywKLSAgICAgIkV4dHJhIG90aWxsXHUwMEU1dG5hIHRlY2tlbjogezB9In0sCi0KLSAgeyBFUl9FWFBFQ1RFRF9ET1VCTEVfUVVPVEUsCi0gICAgICAiTGl0dGVyYWwgb21nZXMgYXYgZmVsIHNvcnRzIGNpdGF0dGVja2VuLi4uIGR1YmJsYSBjaXRhdHRlY2tlbiBmXHUwMEY2cnZcdTAwRTRudGFkZSEifSwKLQotICB7IEVSX0VYUEVDVEVEX1NJTkdMRV9RVU9URSwKLSAgICAgICJMaXR0ZXJhbCBvbWdlcyBhdiBmZWwgc29ydHMgY2l0YXR0ZWNrZW4uLi4gZW5rbGEgY2l0YXR0ZWNrZW4gZlx1MDBGNnJ2XHUwMEU0bnRhZGUhIn0sCi0KLSAgeyBFUl9FTVBUWV9FWFBSRVNTSU9OLAotICAgICAiVG9tdCB1dHRyeWNrISJ9LAotCi0gIHsgRVJfRVhQRUNURURfQlVUX0ZPVU5ELAotICAgICAiRlx1MDBGNnJ2XHUwMEU0bnRhZGUgezB9LCBtZW4gaGl0dGFkZTogezF9In0sCi0KLSAgeyBFUl9JTkNPUlJFQ1RfUFJPR1JBTU1FUl9BU1NFUlRJT04sCi0gICAgICAiUHJvZ3JhbW1lcmFyZW5zIHV0c2FnYSBcdTAwRTRyIGludGUga29ycmVrdCEgLSB7MH0ifSwKLQotICB7IEVSX0JPT0xFQU5fQVJHX05PX0xPTkdFUl9PUFRJT05BTCwKLSAgICAgICJBcmd1bWVudGV0IGJvb2xlYW4oLi4uKSBcdTAwRTRyIGludGUgbFx1MDBFNG5ncmUgdmFsZnJpdHQgbWVkIDE5OTkwNzA5IFhQYXRoLXV0a2FzdC4ifSwKLQotICB7IEVSX0ZPVU5EX0NPTU1BX0JVVF9OT19QUkVDRURJTkdfQVJHLAotICAgICAgIkhpdHRhZGUgJywnIHV0YW4gZlx1MDBGNnJlZ1x1MDBFNWVuZGUgYXJndW1lbnQhIn0sCi0KLSAgeyBFUl9GT1VORF9DT01NQV9CVVRfTk9fRk9MTE9XSU5HX0FSRywKLSAgICAgICJIaXR0YWRlICcsJyB1dGFuIGVmdGVyZlx1MDBGNmxqYW5kZSBhcmd1bWVudCEifSwKLQotICB7IEVSX1BSRURJQ0FURV9JTExFR0FMX1NZTlRBWCwKLSAgICAgICInLi5bcHJlZGlrYXRdJyBlbGxlciAnLltwcmVkaWthdF0nIFx1MDBFNHIgb3RpbGxcdTAwRTV0ZW4gc3ludGF4LiBBbnZcdTAwRTRuZCAnc2VsZjo6bm9kZSgpW3ByZWRpa2F0XScgaXN0XHUwMEU0bGxldC4ifSwKLQotICB7IEVSX0lMTEVHQUxfQVhJU19OQU1FLAotICAgICAib3RpbGxcdTAwRTV0ZXQgYXhlbG5hbW46IHswfSJ9LAotCi0gIHsgRVJfVU5LTk9XTl9OT0RFVFlQRSwKLSAgICAgIk9rXHUwMEU0bmQgbm9kdHlwOiB7MH0ifSwKLQotICB7IEVSX1BBVFRFUk5fTElURVJBTF9ORUVEU19CRV9RVU9URUQsCi0gICAgICAiTVx1MDBGNm5zdGVybGl0dGVyYWxlbiAoezB9KSBtXHUwMEU1c3RlIG9tZ2VzIGF2IGNpdGF0dGVja2VuISJ9LAotCi0gIHsgRVJfQ09VTEROT1RfQkVfRk9STUFUVEVEX1RPX05VTUJFUiwKLSAgICAgICJ7MH0ga3VuZGUgaW50ZSBmb3JtYXRlcmFzIHRpbGwgZXR0IHRhbCEifSwKLQotICB7IEVSX0NPVUxETk9UX0NSRUFURV9YTUxQUk9DRVNTT1JMSUFJU09OLAotICAgICAgIkt1bmRlIGludGUgc2thcGEgWE1MIFRyYW5zZm9ybWVyRmFjdG9yeSBMaWFpc29uOiB7MH0ifSwKLQotICB7IEVSX0RJRE5PVF9GSU5EX1hQQVRIX1NFTEVDVF9FWFAsCi0gICAgICAiRmVsISBIaXR0YWRlIGludGUgeHBhdGggc2VsZWN0LXV0dHJ5Y2sgKC1zZWxlY3QpLiJ9LAotCi0gIHsgRVJfQ09VTEROT1RfRklORF9FTkRPUF9BRlRFUl9PUExPQ0FUSU9OUEFUSCwKLSAgICAgICJGRUwhIEhpdHRhZGUgaW50ZSBFTkRPUCBlZnRlciBPUF9MT0NBVElPTlBBVEgifSwKLQotICB7IEVSX0VSUk9SX09DQ1VSRUQsCi0gICAgICJFdHQgZmVsIGhhciBpbnRyXHUwMEU0ZmZhdCEifSwKLQotICB7IEVSX0lMTEVHQUxfVkFSSUFCTEVfUkVGRVJFTkNFLAotICAgICAgIlZhcmlhYmxlUmVmZXJlbmNlIGFuZ2l2ZW4gZlx1MDBGNnIgdmFyaWFiZWwgc29tIFx1MDBFNHIgdXRhbmZcdTAwRjZyIGtvbnRleHQgZWxsZXIgc29tIHNha25hciBkZWZpbml0aW9uISBOYW1uID0gezB9In0sCi0KLSAgeyBFUl9BWEVTX05PVF9BTExPV0VELAotICAgICAgIkVuZGFzdCB1bmRlcm9yZG5hZGU6OiBvY2ggYXR0cmlidXQ6Oi1heGxhciBcdTAwRTRyIHRpbGxcdTAwRTV0bmEgaSBtYXRjaG5pbmdzbVx1MDBGNm5zdGVyISBSZWdlbHZpZHJpZ2EgYXhsYXIgPSB7MH0ifSwKLQotICB7IEVSX0tFWV9IQVNfVE9PX01BTllfQVJHUywKLSAgICAgICJrZXkoKSBoYXIgZmVsYWt0aWd0IGFudGFsIGFyZ3VtZW50LiJ9LAotCi0gIHsgRVJfQ09VTlRfVEFLRVNfMV9BUkcsCi0gICAgICAiRnVua3Rpb25lbiBjb3VudCBib3JkZSB0YSBlbW90IGV0dCBhcmd1bWVudCEifSwKLQotICB7IEVSX0NPVUxETk9UX0ZJTkRfRlVOQ1RJT04sCi0gICAgICJIaXR0YWRlIGludGUgZnVua3Rpb25lbjogezB9In0sCi0KLSAgeyBFUl9VTlNVUFBPUlRFRF9FTkNPRElORywKLSAgICAgIktvZG5pbmcgdXRhbiBzdFx1MDBGNmQ6IHswfSJ9LAotCi0gIHsgRVJfUFJPQkxFTV9JTl9EVE1fTkVYVFNJQkxJTkcsCi0gICAgICAiUHJvYmxlbSBpbnRyXHUwMEU0ZmZhZGUgaSBEVE0gaSBnZXROZXh0U2libGluZy4uLiBmXHUwMEY2cnNcdTAwRjZrZXIgXHUwMEU1dGVyc2thcGEifSwKLQotICB7IEVSX0NBTk5PVF9XUklURV9UT19FTVBUWU5PREVMSVNUSU1QTCwKLSAgICAgICJQcm9ncmFtbWVyYXJmZWw6IGthbiBpbnRlIHNrcml2YSB0aWxsIEVtcHR5Tm9kZUxpc3QuIn0sCi0KLSAgeyBFUl9TRVRET01GQUNUT1JZX05PVF9TVVBQT1JURUQsCi0gICAgICAic2V0RE9NRmFjdG9yeSBzdFx1MDBGNmRzIGludGUgaSBYUGF0aENvbnRleHQhIn0sCi0KLSAgeyBFUl9QUkVGSVhfTVVTVF9SRVNPTFZFLAotICAgICAgIlByZWZpeCBtXHUwMEU1c3RlIG1hdGNoYXMgdGlsbCBlbiBuYW1ucnltZDogezB9In0sCi0KLSAgeyBFUl9QQVJTRV9OT1RfU1VQUE9SVEVELAotICAgICAgInRvbGtuaW5nIChJbnB1dFNvdXJjZS1rXHUwMEU0bGxhKSBzdFx1MDBGNmRzIGludGUgaSBYUGF0aENvbnRleHQhIEthbiBpbnRlIFx1MDBGNnBwbmEgezB9In0sCi0KLSAgeyBFUl9TQVhfQVBJX05PVF9IQU5ETEVELAotICAgICAgIlNBWCBBUEktdGVja2VuKGNoYXIgY2hbXS4uLiBoYW50ZXJhcyBpbnRlIGF2IERUTSEifSwKLQotICB7IEVSX0lHTk9SQUJMRV9XSElURVNQQUNFX05PVF9IQU5ETEVELAotICAgICAgImlnbm9yYWJsZVdoaXRlc3BhY2UoY2hhciBjaFtdLi4uIGhhbnRlcmFzIGludGUgYXYgRFRNISJ9LAotCi0gIHsgRVJfRFRNX0NBTk5PVF9IQU5ETEVfTk9ERVMsCi0gICAgICAiRFRNTGlhaXNvbiBrYW4gaW50ZSBoYW50ZXJhIG5vZGVyIGF2IHR5cCB7MH0ifSwKLQotICB7IEVSX1hFUkNFU19DQU5OT1RfSEFORExFX05PREVTLAotICAgICAgIkRPTTJIZWxwZXIga2FuIGludGUgaGFudGVyYSBub2RlciBhdiB0eXAgezB9In0sCi0KLSAgeyBFUl9YRVJDRVNfUEFSU0VfRVJST1JfREVUQUlMUywKLSAgICAgICJGZWwgaSBET00ySGVscGVyLnBhcnNlOiBTeXN0ZW1JRCAtIHswfSByYWQgLSB7MX0ifSwKLQotICB7IEVSX1hFUkNFU19QQVJTRV9FUlJPUiwKLSAgICAgIkZlbCBpIERPTTJIZWxwZXIucGFyc2UifSwKLQotICB7IEVSX0lOVkFMSURfVVRGMTZfU1VSUk9HQVRFLAotICAgICAgIk9naWx0aWd0IFVURi0xNi1zdXJyb2dhdCB1cHB0XHUwMEU0Y2t0OiB7MH0gPyJ9LAotCi0gIHsgRVJfT0lFUlJPUiwKLSAgICAgIklPLWZlbCJ9LAotCi0gIHsgRVJfQ0FOTk9UX0NSRUFURV9VUkwsCi0gICAgICJLYW4gaW50ZSBza2FwYSBVUkwgZlx1MDBGNnI6IHswfSJ9LAotCi0gIHsgRVJfWFBBVEhfUkVBRE9CSkVDVCwKLSAgICAgIkkgWFBhdGgucmVhZE9iamVjdDogezB9In0sCi0KLSAgeyBFUl9GVU5DVElPTl9UT0tFTl9OT1RfRk9VTkQsCi0gICAgICAiZnVua3Rpb25zdGVja2VuIGhpdHRhZGVzIGludGUuIn0sCi0KLSAgeyBFUl9DQU5OT1RfREVBTF9YUEFUSF9UWVBFLAotICAgICAgICJLYW4gaW50ZSBoYW50ZXJhIFhQYXRoLXR5cDogezB9In0sCi0KLSAgeyBFUl9OT0RFU0VUX05PVF9NVVRBQkxFLAotICAgICAgICJEZXR0YSBOb2RlU2V0IFx1MDBFNHIgb2ZcdTAwRjZyXHUwMEU0bmRlcmxpZ3QifSwKLQotICB7IEVSX05PREVTRVREVE1fTk9UX01VVEFCTEUsCi0gICAgICAgIkRldHRhIE5vZGVTZXREVE0gXHUwMEU0ciBvZlx1MDBGNnJcdTAwRTRuZGVybGlndCJ9LAotCi0gIHsgRVJfVkFSX05PVF9SRVNPTFZBQkxFLAotICAgICAgICAiVmFyaWFiZWxuIGthbiBpbnRlIG1hdGNoYXM6IHswfSJ9LAotCi0gIHsgRVJfTlVMTF9FUlJPUl9IQU5ETEVSLAotICAgICAgICAiRmVsaGFudGVyYXJlIG1lZCB2XHUwMEU0cmRlIG51bGwifSwKLQotICB7IEVSX1BST0dfQVNTRVJUX1VOS05PV05fT1BDT0RFLAotICAgICAgICJQcm9ncmFtbWVyYXJlbnMgdXRzYWdhOiBva1x1MDBFNG5kIG9wLWtvZDogezB9In0sCi0KLSAgeyBFUl9aRVJPX09SX09ORSwKLSAgICAgICAiMCBlbGxlciAxIn0sCi0KLSAgeyBFUl9SVEZfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiwKLSAgICAgICAicnRmKCkgc3RcdTAwRjZkcyBpbnRlIGF2IFhSVHJlZUZyYWdTZWxlY3RXcmFwcGVyIn0sCi0KLSAgeyBFUl9SVEZfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiwKLSAgICAgICAiYXNOb2RlSXRlcmF0b3IoKSBzdFx1MDBGNmRzIGludGUgYXYgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIifSwKLQotICAgICAgICAvKiogIGRldGFjaCgpIG5vdCBzdXBwb3J0ZWQgYnkgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIgICAqLwotICAgeyBFUl9ERVRBQ0hfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiwKLSAgICAgICAgICAgICAgICAiZGV0YWNoKCkgc3RcdTAwRjZkcyBpbnRlIGF2IFhSVHJlZUZyYWdTZWxlY3RXcmFwcGVyIn0sCi0KLSAgICAgICAgLyoqICBudW0oKSBub3Qgc3VwcG9ydGVkIGJ5IFhSVHJlZUZyYWdTZWxlY3RXcmFwcGVyICAgKi8KLSAgIHsgRVJfTlVNX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIsCi0gICAgICAgICAgICAgICAgIm51bSgpIHN0XHUwMEY2ZHMgaW50ZSBhdiBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciJ9LAotCi0gICAgICAgIC8qKiAgeHN0cigpIG5vdCBzdXBwb3J0ZWQgYnkgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIgICAqLwotICAgeyBFUl9YU1RSX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIsCi0gICAgICAgICAgICAgICAgInhzdHIoKSBzdFx1MDBGNmRzIGludGUgYXYgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIifSwKLQotICAgICAgICAvKiogIHN0cigpIG5vdCBzdXBwb3J0ZWQgYnkgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIgICAqLwotICAgeyBFUl9TVFJfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiwKLSAgICAgICAgICAgICAgICAic3RyKCkgc3RcdTAwRjZkcyBpbnRlIGF2IFhSVHJlZUZyYWdTZWxlY3RXcmFwcGVyIn0sCi0KLSAgeyBFUl9GU0JfTk9UX1NVUFBPUlRFRF9YU1RSSU5HRk9SQ0hBUlMsCi0gICAgICAgImZzYigpIHN0XHUwMEY2ZHMgaW50ZSBmXHUwMEY2ciBYU3RyaW5nRm9yQ2hhcnMifSwKLQotICB7IEVSX0NPVUxEX05PVF9GSU5EX1ZBUiwKLSAgICAgICJIaXR0YWRlIGludGUgdmFyaWFiZWwgbWVkIG5hbW5ldCB7MH0ifSwKLQotICB7IEVSX1hTVFJJTkdGT1JDSEFSU19DQU5OT1RfVEFLRV9TVFJJTkcsCi0gICAgICAiWFN0cmluZ0ZvckNoYXJzIGthbiBpbnRlIHRhIGVtb3QgZW4gc3RyXHUwMEU0bmcgZlx1MDBGNnIgYXJndW1lbnQifSwKLQotICB7IEVSX0ZBU1RTVFJJTkdCVUZGRVJfQ0FOTk9UX0JFX05VTEwsCi0gICAgICAiRmFzdFN0cmluZ0J1ZmZlci1hcmd1bWVudGV0IGZcdTAwRTVyIGludGUgdmFyYSBudWxsIn0sCi0KLSAgeyBFUl9UV09fT1JfVEhSRUUsCi0gICAgICAgIjIgZWxsZXIgMyJ9LAotCi0gIHsgRVJfVkFSSUFCTEVfQUNDRVNTRURfQkVGT1JFX0JJTkQsCi0gICAgICAgIlx1MDBDNXRrb21zdCB0aWxsIHZhcmlhYmVsIGlubmFuIGRlbiBcdTAwRTRyIGJ1bmRlbiEifSwKLQotICB7IEVSX0ZTQl9DQU5OT1RfVEFLRV9TVFJJTkcsCi0gICAgICAgIlhTdHJpbmdGb3JGU0Iga2FuIGludGUgdGEgZW1vdCBlbiBzdHJcdTAwRTRuZyBmXHUwMEY2ciBhcmd1bWVudCEifSwKLQotICB7IEVSX1NFVFRJTkdfV0FMS0VSX1JPT1RfVE9fTlVMTCwKLSAgICAgICAiXG4gISEhISBGZWwhIEFuZ2VyIHJvdGVuIGZcdTAwRjZyIGVuICcnd2Fsa2VyJycgc29tIG51bGwhISEifSwKLQotICB7IEVSX05PREVTRVREVE1fQ0FOTk9UX0lURVJBVEUsCi0gICAgICAgIkRldHRhIE5vZGVTZXREVE0ga2FuIGludGUgaXRlcmVyYSB0aWxsIGVuIHRpZGlnYXJlIG5vZCEifSwKLQotICB7IEVSX05PREVTRVRfQ0FOTk9UX0lURVJBVEUsCi0gICAgICAgIkRldHRhIE5vZGVTZXQga2FuIGludGUgaXRlcmVyYSB0aWxsIGVuIHRpZGlnYXJlIG5vZCEifSwKLQotICB7IEVSX05PREVTRVREVE1fQ0FOTk9UX0lOREVYLAotICAgICAgICJEZXR0YSBOb2RlU2V0RFRNIGthbiBpbnRlIHV0Zlx1MDBGNnJhIGZ1bmt0aW9uZXIgc29tIGluZGV4ZXJhciBlbGxlciByXHUwMEU0a25hciEifSwKLQotICB7IEVSX05PREVTRVRfQ0FOTk9UX0lOREVYLAotICAgICAgICJEZXR0YSBOb2RlU2V0IGthbiBpbnRlIHV0Zlx1MDBGNnJhIGZ1bmt0aW9uZXIgc29tIGluZGV4ZXJhciBlbGxlciByXHUwMEU0a25hciEifSwKLQotICB7IEVSX0NBTk5PVF9DQUxMX1NFVFNIT1VMRENBQ0hFTk9ERSwKLSAgICAgICAiS2FuIGludGUgYW5yb3BhIHNldFNob3VsZENhY2hlTm9kZXMgZWZ0ZXIgYW5yb3BhdCBuZXh0Tm9kZSEifSwKLQotICB7IEVSX09OTFlfQUxMT1dTLAotICAgICAgICJ7MH0gdGlsbFx1MDBFNXRlciBlbmRhc3QgezF9IGFyZ3VtZW50In0sCi0KLSAgeyBFUl9VTktOT1dOX1NURVAsCi0gICAgICAgIlByb2dyYW1tZXJhcmVucyB1dHNhZ2EgaSBnZXROZXh0U3RlcFBvczogb2tcdTAwRTRudCBzdGVwVHlwZTogezB9In0sCi0KLSAgLy9Ob3RlIHRvIHRyYW5zbGF0b3JzOiAgQSByZWxhdGl2ZSBsb2NhdGlvbiBwYXRoIGlzIGEgZm9ybSBvZiBYUGF0aCBleHByZXNzaW9uLgotICAvLyBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCBzdWNoIGFuIGV4cHJlc3Npb24gd2FzIGV4cGVjdGVkIGZvbGxvd2luZyB0aGUKLSAgLy8gY2hhcmFjdGVycyAnLycgb3IgJy8vJywgYnV0IHdhcyBub3QgZm91bmQuCi0gIHsgRVJfRVhQRUNURURfUkVMX0xPQ19QQVRILAotICAgICAgIkVuIHJlbGF0aXYgc1x1MDBGNmt2XHUwMEU0ZyBmXHUwMEY2cnZcdTAwRTRudGFkZXMgZWZ0ZXIgdGVja25ldCAnLycgZWxsZXIgJy8vJy4ifSwKLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQSBsb2NhdGlvbiBwYXRoIGlzIGEgZm9ybSBvZiBYUGF0aCBleHByZXNzaW9uLgotICAvLyBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCBzeW50YWN0aWNhbGx5IHN1Y2ggYW4gZXhwcmVzc2lvbiB3YXMgZXhwZWN0ZWQsYnV0Ci0gIC8vIHRoZSBjaGFyYWN0ZXJzIHNwZWNpZmllZCBieSB0aGUgc3Vic3RpdHV0aW9uIHRleHQgd2VyZSBlbmNvdW50ZXJlZCBpbnN0ZWFkLgotICB7IEVSX0VYUEVDVEVEX0xPQ19QQVRILAotICAgICAgICJFbiBzXHUwMEY2a3ZcdTAwRTRnIGZcdTAwRjZydlx1MDBFNG50YWRlcywgbWVuIGZcdTAwRjZsamFuZGUgdGVja2VuIHBcdTAwRTV0clx1MDBFNGZmYWRlczogezB9In0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIEEgbG9jYXRpb24gcGF0aCBpcyBhIGZvcm0gb2YgWFBhdGggZXhwcmVzc2lvbi4KLSAgLy8gVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgc3ludGFjdGljYWxseSBzdWNoIGEgc3ViZXhwcmVzc2lvbiB3YXMgZXhwZWN0ZWQsCi0gIC8vIGJ1dCBubyBtb3JlIGNoYXJhY3RlcnMgd2VyZSBmb3VuZCBpbiB0aGUgZXhwcmVzc2lvbi4KLSAgeyBFUl9FWFBFQ1RFRF9MT0NfUEFUSF9BVF9FTkRfRVhQUiwKLSAgICAgICAiRW4gc1x1MDBGNmt2XHUwMEU0ZyBmXHUwMEY2cnZcdTAwRTRudGFkZXMsIG1lbiBzbHV0ZXQgYXYgWFBhdGgtdXR0cnlja2V0IGhpdHRhZGVzIGlzdFx1MDBFNGxsZXQuIn0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIEEgbG9jYXRpb24gc3RlcCBpcyBwYXJ0IG9mIGFuIFhQYXRoIGV4cHJlc3Npb24uCi0gIC8vIFRoZSBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHN5bnRhY3RpY2FsbHkgc3VjaCBhbiBleHByZXNzaW9uIHdhcyBleHBlY3RlZAotICAvLyBmb2xsb3dpbmcgdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXJzLgotICB7IEVSX0VYUEVDVEVEX0xPQ19TVEVQLAotICAgICAgICJFdHQgcGxhdHNzdGVnIGZcdTAwRjZydlx1MDBFNG50YWRlcyBlZnRlciB0ZWNrbmV0ICcvJyBlbGxlciAnLy8nLiJ9LAotCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBIG5vZGUgdGVzdCBpcyBwYXJ0IG9mIGFuIFhQYXRoIGV4cHJlc3Npb24gdGhhdCBpcwotICAvLyB1c2VkIHRvIHRlc3QgZm9yIHBhcnRpY3VsYXIga2luZHMgb2Ygbm9kZXMuICBJbiB0aGlzIGNhc2UsIGEgbm9kZSB0ZXN0IHRoYXQKLSAgLy8gY29uc2lzdHMgb2YgYW4gTkNOYW1lIGZvbGxvd2VkIGJ5IGEgY29sb24gYW5kIGFuIGFzdGVyaXNrIG9yIHRoYXQgY29uc2lzdHMKLSAgLy8gb2YgYSBRTmFtZSB3YXMgZXhwZWN0ZWQsIGJ1dCB3YXMgbm90IGZvdW5kLgotICB7IEVSX0VYUEVDVEVEX05PREVfVEVTVCwKLSAgICAgICAiRXR0IG5vZHRlc3Qgc29tIG1hdGNoYXIgYW50aW5nZW4gTkNOYW1lOiogZWxsZXIgUU5hbWUgZlx1MDBGNnJ2XHUwMEU0bnRhZGVzLiJ9LAotCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBIHN0ZXAgcGF0dGVybiBpcyBwYXJ0IG9mIGFuIFhQYXRoIGV4cHJlc3Npb24uCi0gIC8vIFRoZSBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHN5bnRhY3RpY2FsbHkgc3VjaCBhbiBleHByZXNzaW9uIHdhcyBleHBlY3RlZCwKLSAgLy8gYnV0IHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyIHdhcyBmb3VuZCBpbiB0aGUgZXhwcmVzc2lvbiBpbnN0ZWFkLgotICB7IEVSX0VYUEVDVEVEX1NURVBfUEFUVEVSTiwKLSAgICAgICAiRXR0IHN0ZWdtXHUwMEY2bnN0ZXIgZlx1MDBGNnJ2XHUwMEU0bnRhZGVzLCBtZW4gJy8nIHBcdTAwRTV0clx1MDBFNGZmYWRlcy4ifSwKLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiBBIHJlbGF0aXZlIHBhdGggcGF0dGVybiBpcyBwYXJ0IG9mIGFuIFhQYXRoIGV4cHJlc3Npb24uCi0gIC8vIFRoZSBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHN5bnRhY3RpY2FsbHkgc3VjaCBhbiBleHByZXNzaW9uIHdhcyBleHBlY3RlZCwKLSAgLy8gYnV0IHdhcyBub3QgZm91bmQuCi0gIHsgRVJfRVhQRUNURURfUkVMX1BBVEhfUEFUVEVSTiwKLSAgICAgICAiRXR0IG1cdTAwRjZuc3RlciBmXHUwMEY2ciByZWxhdGl2IHNcdTAwRjZrdlx1MDBFNGcgZlx1MDBGNnJ2XHUwMEU0bnRhZGVzLiJ9LAotCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYSBkYXRhIHR5cGUuICBUaGUKLSAgLy8gbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCBhIHZhbHVlIG9mIGEgcGFydGljdWxhciB0eXBlIGNvdWxkIG5vdCBiZSBjb252ZXJ0ZWQKLSAgLy8gdG8gYSB2YWx1ZSBvZiB0eXBlIGJvb2xlYW4uCi0gIHsgRVJfQ0FOVF9DT05WRVJUX1RPX0JPT0xFQU4sCi0gICAgICAgIlhQYXRoUmVzdWx0IGkgWFBhdGgtdXR0cnlja2V0ICcnezB9JycgaW5uZWhcdTAwRTVsbGVyIFhQYXRoUmVzdWx0VHlwZSB7MX0gc29tIGludGUga2FuIGtvbnZlcnRlcmFzIHRpbGwgYm9vbGVza3Qgdlx1MDBFNHJkZS4ifSwKLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiBEbyBub3QgdHJhbnNsYXRlIEFOWV9VTk9SREVSRURfTk9ERV9UWVBFIGFuZAotICAvLyBGSVJTVF9PUkRFUkVEX05PREVfVFlQRS4KLSAgeyBFUl9DQU5UX0NPTlZFUlRfVE9fU0lOR0xFTk9ERSwKLSAgICAgICAiWFBhdGhSZXN1bHQgaSBYUGF0aC11dHRyeWNrZXQgJyd7MH0nJyBpbm5laFx1MDBFNWxsZXIgWFBhdGhSZXN1bHRUeXBlIHsxfSBzb20gaW50ZSBrYW4ga29udmVydGVyYXMgdGlsbCBlbnNraWxkIG5vZC4gTWV0b2RlbiBnZXRTaW5nbGVOb2RlVmFsdWUgYW52XHUwMEU0bmRzIGVuZGFzdCB0aWxsIHR5cCBBTllfVU5PUkRFUkVEX05PREVfVFlQRSBvY2ggRklSU1RfT1JERVJFRF9OT0RFX1RZUEUuIn0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogRG8gbm90IHRyYW5zbGF0ZSBVTk9SREVSRURfTk9ERV9TTkFQU0hPVF9UWVBFIGFuZAotICAvLyBPUkRFUkVEX05PREVfU05BUFNIT1RfVFlQRS4KLSAgeyBFUl9DQU5UX0dFVF9TTkFQU0hPVF9MRU5HVEgsCi0gICAgICAgIk1ldG9kZW4gZ2V0U25hcHNob3RMZW5ndGgga2FuIGludGUgYW5yb3BhcyB2aWQgWFBhdGhSZXN1bHQgZnJcdTAwRTVuIFhQYXRoLXV0dHJ5Y2tldCAnJ3swfScnIGVmdGVyc29tIFhQYXRoUmVzdWx0VHlwZSBcdTAwRTRyIHsxfS4gTWV0b2RlbiBhbnZcdTAwRTRuZHMgZW5kYXN0IHRpbGwgdHlwIFVOT1JERVJFRF9OT0RFX1NOQVBTSE9UX1RZUEUgb2NoIE9SREVSRURfTk9ERV9TTkFQU0hPVF9UWVBFLiJ9LAotCi0gIHsgRVJfTk9OX0lURVJBVE9SX1RZUEUsCi0gICAgICAgIk1ldG9kZW4gaXRlcmF0ZU5leHQga2FuIGludGUgYW5yb3BhcyB2aWQgWFBhdGhSZXN1bHQgZnJcdTAwRTVuIFhQYXRoLXV0dHJ5Y2tldCAnJ3swfScnIGVmdGVyc29tIFhQYXRoUmVzdWx0VHlwZSBcdTAwRTRyIHsxfS4gTWV0b2RlbiBhbnZcdTAwRTRuZHMgZW5kYXN0IHRpbGwgdHlwIFVOT1JERVJFRF9OT0RFX0lURVJBVE9SX1RZUEUgb2NoIE9SREVSRURfTk9ERV9JVEVSQVRPUl9UWVBFLiJ9LAotCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6IFRoaXMgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUgZG9jdW1lbnQgYmVpbmcgb3BlcmF0ZWQKLSAgLy8gdXBvbiBjaGFuZ2VkLCBzbyB0aGUgaXRlcmF0b3Igb2JqZWN0IHRoYXQgd2FzIGJlaW5nIHVzZWQgdG8gdHJhdmVyc2UgdGhlCi0gIC8vIGRvY3VtZW50IGhhcyBub3cgYmVjb21lIGludmFsaWQuCi0gIHsgRVJfRE9DX01VVEFURUQsCi0gICAgICAgIkRva3VtZW50ZXQgaGFyIG11dGVyYXRzIHNlZGFuIHJlc3VsdGF0ZXQgZ2VuZXJlcmFkZXMuIEl0ZXJhdG9ybiBcdTAwRTRyIG9naWx0aWcuIn0sCi0KLSAgeyBFUl9JTlZBTElEX1hQQVRIX1RZUEUsCi0gICAgICAgIk9naWx0aWd0IFhQYXRoLXR5cGFyZ3VtZW50OiB7MH0ifSwKLQotICB7IEVSX0VNUFRZX1hQQVRIX1JFU1VMVCwKLSAgICAgICAiVG9tdCBYUGF0aC1yZXN1bHRhdG9iamVrdCJ9LAotCi0gIHsgRVJfSU5DT01QQVRJQkxFX1RZUEVTLAotICAgICAgICJYUGF0aFJlc3VsdCBpIFhQYXRoLXV0dHJ5Y2tldCAnJ3swfScnIGlubmVoXHUwMEU1bGxlciBYUGF0aFJlc3VsdFR5cGUgezF9IHNvbSBpbnRlIGthbiB0dmluZ2FzIHRpbGwgYW5naXZlbiBYUGF0aFJlc3VsdFR5cGUgezJ9LiJ9LAotCi0gIHsgRVJfTlVMTF9SRVNPTFZFUiwKLSAgICAgICAiS2FuIGludGUgbWF0Y2hhIHByZWZpeCBtZWQgcHJlZml4bWF0Y2huaW5nIHNvbSBcdTAwRTRyIG51bGwuIn0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBzdWJzdGl0dXRpb24gdGV4dCBpcyB0aGUgbmFtZSBvZiBhIGRhdGEgdHlwZS4gIFRoZQotICAvLyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IGEgdmFsdWUgb2YgYSBwYXJ0aWN1bGFyIHR5cGUgY291bGQgbm90IGJlIGNvbnZlcnRlZAotICAvLyB0byBhIHZhbHVlIG9mIHR5cGUgc3RyaW5nLgotICB7IEVSX0NBTlRfQ09OVkVSVF9UT19TVFJJTkcsCi0gICAgICAgIlhQYXRoUmVzdWx0IGkgWFBhdGgtdXR0cnlja2V0ICcnezB9JycgaW5uZWhcdTAwRTVsbGVyIFhQYXRoUmVzdWx0VHlwZSB7MX0gc29tIGludGUga2FuIGtvbnZlcnRlcmFzIHRpbGwgZW4gc3RyXHUwMEU0bmcuIn0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogRG8gbm90IHRyYW5zbGF0ZSBzbmFwc2hvdEl0ZW0sCi0gIC8vIFVOT1JERVJFRF9OT0RFX1NOQVBTSE9UX1RZUEUgYW5kIE9SREVSRURfTk9ERV9TTkFQU0hPVF9UWVBFLgotICB7IEVSX05PTl9TTkFQU0hPVF9UWVBFLAotICAgICAgICJNZXRvZGVuIHNuYXBzaG90SXRlbSBrYW4gaW50ZSBhbnJvcGFzIHZpZCBYUGF0aFJlc3VsdCBmclx1MDBFNW4gWFBhdGgtdXR0cnlja2V0ICcnezB9JycgZWZ0ZXJzb20gWFBhdGhSZXN1bHRUeXBlIFx1MDBFNHIgezF9LiBNZXRvZGVuIGFudlx1MDBFNG5kcyBlbmRhc3QgdGlsbCB0eXAgVU5PUkRFUkVEX05PREVfU05BUFNIT1RfVFlQRSBvY2ggT1JERVJFRF9OT0RFX1NOQVBTSE9UX1RZUEUuIn0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFhQYXRoRXZhbHVhdG9yIGlzIGEgSmF2YSBpbnRlcmZhY2UgbmFtZS4gIEFuCi0gIC8vIFhQYXRoRXZhbHVhdG9yIGlzIGNyZWF0ZWQgd2l0aCByZXNwZWN0IHRvIGEgcGFydGljdWxhciBYTUwgZG9jdW1lbnQsIGFuZCBpbgotICAvLyB0aGlzIGNhc2UgdGhlIGV4cHJlc3Npb24gcmVwcmVzZW50ZWQgYnkgdGhpcyBvYmplY3Qgd2FzIGJlaW5nIGV2YWx1YXRlZCB3aXRoCi0gIC8vIHJlc3BlY3QgdG8gYSBjb250ZXh0IG5vZGUgZnJvbSBhIGRpZmZlcmVudCBkb2N1bWVudC4KLSAgeyBFUl9XUk9OR19ET0NVTUVOVCwKLSAgICAgICAiS29udGV4dG5vZGVuIHRpbGxoXHUwMEY2ciBpbnRlIGRva3VtZW50ZXQgc29tIFx1MDBFNHIgYnVuZGV0IHRpbGwgZGVubmEgWFBhdGhFdmFsdWF0b3IuIn0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBYUGF0aCBleHByZXNzaW9uIGNhbm5vdCBiZSBldmFsdWF0ZWQgd2l0aCByZXNwZWN0Ci0gIC8vIHRvIHRoaXMgdHlwZSBvZiBub2RlLgotICB7IEVSX1dST05HX05PREVUWVBFLAotICAgICAgICJLb250ZXh0bm9kdHlwZW4gc3RcdTAwRjZkcyBpbnRlLiJ9LAotCi0gIHsgRVJfWFBBVEhfRVJST1IsCi0gICAgICAgIk9rXHUwMEU0bnQgZmVsIGkgWFBhdGguIn0sCi0KLSAgeyBFUl9DQU5UX0NPTlZFUlRfWFBBVEhSRVNVTFRUWVBFX1RPX05VTUJFUiwKLSAgICAgICAgIlhQYXRoUmVzdWx0IGkgWFBhdGgtdXR0cnlja2V0ICcnezB9JycgaW5uZWhcdTAwRTVsbGVyIFhQYXRoUmVzdWx0VHlwZSB7MX0gc29tIGludGUga2FuIGtvbnZlcnRlcmFzIHRpbGwgZXR0IHRhbC4ifSwKLQotICAvL0JFR0lOOiAgRGVmaW5pdGlvbnMgb2YgZXJyb3Iga2V5cyB1c2VkICBpbiBleGNlcHRpb24gbWVzc2FnZXMgb2YgIEpBWFAgMS4zIFhQYXRoIEFQSSBpbXBsZW1lbnRhdGlvbgotCi0gIC8qKiBGaWVsZCBFUl9FWFRFTlNJT05fRlVOQ1RJT05fQ0FOTk9UX0JFX0lOVk9LRUQgICAgICAgICAgICAgICAgICAgICAgICovCi0KLSAgeyBFUl9FWFRFTlNJT05fRlVOQ1RJT05fQ0FOTk9UX0JFX0lOVk9LRUQsCi0gICAgICAgIlRpbGxcdTAwRTRnZ3NmdW5rdGlvbjogJyd7MH0nJyBrYW4gaW50ZSBhbnJvcGFzIG9tIGZ1bmt0aW9uZW4gWE1MQ29uc3RhbnRzLkZFQVRVUkVfU0VDVVJFX1BST0NFU1NJTkcgYW5nZXMgc29tIHRydWUuIn0sCi0KLSAgLyoqIEZpZWxkIEVSX1JFU09MVkVfVkFSSUFCTEVfUkVUVVJOU19OVUxMICAgICAgICAgICAgICAgICAgICAgICAqLwotCi0gIHsgRVJfUkVTT0xWRV9WQVJJQUJMRV9SRVRVUk5TX05VTEwsCi0gICAgICAgInJlc29sdmVWYXJpYWJsZSBmXHUwMEY2ciB2YXJpYWJlbG4gezB9IHJldHVybmVyYXIgbnVsbCJ9LAotCi0gIC8qKiBGaWVsZCBFUl9VTlNVUFBPUlRFRF9SRVRVUk5fVFlQRSAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX1VOU1VQUE9SVEVEX1JFVFVSTl9UWVBFLAotICAgICAgICJEZXQgZmlubnMgaW5nZXQgc3RcdTAwRjZkIGZcdTAwRjZyIHJldHVydHlwZW46IHswfSJ9LAotCi0gIC8qKiBGaWVsZCBFUl9TT1VSQ0VfUkVUVVJOX1RZUEVfQ0FOTk9UX0JFX05VTEwgICAgICAgICAgICAgICAgICAgICAgICovCi0KLSAgeyBFUl9TT1VSQ0VfUkVUVVJOX1RZUEVfQ0FOTk9UX0JFX05VTEwsCi0gICAgICAgIktcdTAwRTRsbGEgb2NoL2VsbGVyIHJldHVydHlwIGZcdTAwRTVyIGludGUgdmFyYSBudWxsIn0sCi0KLSAgLyoqIEZpZWxkIEVSX1NPVVJDRV9SRVRVUk5fVFlQRV9DQU5OT1RfQkVfTlVMTCAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX1NPVVJDRV9SRVRVUk5fVFlQRV9DQU5OT1RfQkVfTlVMTCwKLSAgICAgICAiS1x1MDBFNGxsYSBvY2gvZWxsZXIgcmV0dXJ0eXAgZlx1MDBFNXIgaW50ZSB2YXJhIG51bGwifSwKLQotICAvKiogRmllbGQgRVJfQVJHX0NBTk5PVF9CRV9OVUxMICAgICAgICAgICAgICAgICAgICAgICAqLwotCi0gIHsgRVJfQVJHX0NBTk5PVF9CRV9OVUxMLAotICAgICAgICJBcmd1bWVudGV0IHswfSBrYW4gaW50ZSB2YXJhIG51bGwifSwKLQotICAvKiogRmllbGQgRVJfT0JKRUNUX01PREVMX05VTEwgICAgICAgICAgICAgICAgICAgICAgICovCi0KLSAgeyBFUl9PQkpFQ1RfTU9ERUxfTlVMTCwKLSAgICAgICAiezB9I2lzT2JqZWN0TW9kZWxTdXBwb3J0ZWQoIFN0cmluZyBvYmplY3RNb2RlbCApIGthbiBpbnRlIGFucm9wYXMgbWVkIG9iamVjdE1vZGVsID09IG51bGwifSwKLQotICAvKiogRmllbGQgRVJfT0JKRUNUX01PREVMX0VNUFRZICAgICAgICAgICAgICAgICAgICAgICAqLwotCi0gIHsgRVJfT0JKRUNUX01PREVMX0VNUFRZLAotICAgICAgICJ7MH0jaXNPYmplY3RNb2RlbFN1cHBvcnRlZCggU3RyaW5nIG9iamVjdE1vZGVsICkga2FuIGludGUgYW5yb3BhcyBtZWQgb2JqZWN0TW9kZWwgPT0gXCJcIiJ9LAotCi0gIC8qKiBGaWVsZCBFUl9PQkpFQ1RfTU9ERUxfRU1QVFkgICAgICAgICAgICAgICAgICAgICAgICovCi0KLSAgeyBFUl9GRUFUVVJFX05BTUVfTlVMTCwKLSAgICAgICAiRlx1MDBGNnJzXHUwMEY2a2VyIGFuZ2UgZW4gZnVua3Rpb24gbWVkIG51bGwtbmFtbjogezB9I3NldEZlYXR1cmUoIG51bGwsIHsxfSkifSwKLQotICAvKiogRmllbGQgRVJfRkVBVFVSRV9VTktOT1dOICAgICAgICAgICAgICAgICAgICAgICAqLwotCi0gIHsgRVJfRkVBVFVSRV9VTktOT1dOLAotICAgICAgICJGXHUwMEY2cnNcdTAwRjZrZXIgYW5nZSBlbiBva1x1MDBFNG5kIGZ1bmt0aW9uIFwiezB9XCI6ezF9I3NldEZlYXR1cmUoezB9LHsyfSkifSwKLQotICAvKiogRmllbGQgRVJfR0VUVElOR19OVUxMX0ZFQVRVUkUgICAgICAgICAgICAgICAgICAgICAgICovCi0KLSAgeyBFUl9HRVRUSU5HX05VTExfRkVBVFVSRSwKLSAgICAgICAiRlx1MDBGNnJzXHUwMEY2a2VyIGhcdTAwRTRtdGEgZW4gZnVua3Rpb24gbWVkIG51bGwtbmFtbjogezB9I2dldEZlYXR1cmUobnVsbCkifSwKLQotICAvKiogRmllbGQgRVJfR0VUVElOR19OVUxMX0ZFQVRVUkUgICAgICAgICAgICAgICAgICAgICAgICovCi0KLSAgeyBFUl9HRVRUSU5HX1VOS05PV05fRkVBVFVSRSwKLSAgICAgICAiRlx1MDBGNnJzXHUwMEY2a2VyIGhcdTAwRTRtdGEgZW4gb2tcdTAwRTRuZCBmdW5rdGlvbiBcInswfVwiOnsxfSNnZXRGZWF0dXJlKHswfSkifSwKLQotICB7RVJfU0VDVVJFUFJPQ0VTU0lOR19GRUFUVVJFLAotICAgICAgICAiRkVBVFVSRV9TRUNVUkVfUFJPQ0VTU0lORzogS2FuIGludGUgYW5nZSBmdW5rdGlvbmVuIHNvbSBmYWxzZSBvbSBzXHUwMEU0a2VyaGV0c2hhbnRlcmFyZW4gYW52XHUwMEU0bmRzOiB7MX0jc2V0RmVhdHVyZSh7MH0sezJ9KSJ9LAotCi0gIC8qKiBGaWVsZCBFUl9OVUxMX1hQQVRIX0ZVTkNUSU9OX1JFU09MVkVSICAgICAgICAgICAgICAgICAgICAgICAqLwotCi0gIHsgRVJfTlVMTF9YUEFUSF9GVU5DVElPTl9SRVNPTFZFUiwKLSAgICAgICAiRlx1MDBGNnJzXHUwMEY2a2VyIGFuZ2UgbnVsbHZcdTAwRTRyZGUgZlx1MDBGNnIgWFBhdGhGdW5jdGlvblJlc29sdmVyOnswfSNzZXRYUGF0aEZ1bmN0aW9uUmVzb2x2ZXIobnVsbCkifSwKLQotICAvKiogRmllbGQgRVJfTlVMTF9YUEFUSF9WQVJJQUJMRV9SRVNPTFZFUiAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX05VTExfWFBBVEhfVkFSSUFCTEVfUkVTT0xWRVIsCi0gICAgICAgIkZcdTAwRjZyc1x1MDBGNmtlciBhbmdlIG51bGx2XHUwMEU0cmRlIGZcdTAwRjZyIFhQYXRoVmFyaWFibGVSZXNvbHZlcjp7MH0jc2V0WFBhdGhWYXJpYWJsZVJlc29sdmVyKG51bGwpIn0sCi0KLSAgLy9FTkQ6ICBEZWZpbml0aW9ucyBvZiBlcnJvciBrZXlzIHVzZWQgIGluIGV4Y2VwdGlvbiBtZXNzYWdlcyBvZiAgSkFYUCAxLjMgWFBhdGggQVBJIGltcGxlbWVudGF0aW9uCi0KLSAgLy8gV2FybmluZ3MuLi4KLQotICB7IFdHX0xPQ0FMRV9OQU1FX05PVF9IQU5ETEVELAotICAgICAgInNwclx1MDBFNWtrb252ZW50aW9uc25hbW5ldCBpIGZ1bmt0aW9uZW4gZm9ybWF0LW51bWJlciBoYXIgXHUwMEU0bm51IGludGUgaGFudGVyYXRzISJ9LAotCi0gIHsgV0dfUFJPUEVSVFlfTk9UX1NVUFBPUlRFRCwKLSAgICAgICJYU0wtZWdlbnNrYXBlbiBzdFx1MDBGNmRzIGludGU6IHswfSJ9LAotCi0gIHsgV0dfRE9OVF9ET19BTllUSElOR19XSVRIX05TLAotICAgICAgIkdcdTAwRjZyIGZcdTAwRjZyIG5cdTAwRTRydmFyYW5kZSBpbnRlIG5cdTAwRTVnb250aW5nIG1lZCBuYW1ucnltZGVuIHswfSBpIGVnZW5za2FwOiB7MX0ifSwKLQotICB7IFdHX1NFQ1VSSVRZX0VYQ0VQVElPTiwKLSAgICAgICJTZWN1cml0eUV4Y2VwdGlvbiB2aWQgZlx1MDBGNnJzXHUwMEY2ayBhdHQgZlx1MDBFNSBcdTAwRTV0a29tc3QgdGlsbCBYU0wtc3lzdGVtZWdlbnNrYXA6IHswfSJ9LAotCi0gIHsgV0dfUVVPX05PX0xPTkdFUl9ERUZJTkVELAotICAgICAgIkdhbW1hbCBzeW50YXg6IHF1byguLi4pIGRlZmluaWVyYXMgaW50ZSBsXHUwMEU0bmdyZSBpIFhQYXRoLiJ9LAotCi0gIHsgV0dfTkVFRF9ERVJJVkVEX09CSkVDVF9UT19JTVBMRU1FTlRfTk9ERVRFU1QsCi0gICAgICAiWFBhdGggYmVoXHUwMEY2dmVyIGV0dCBoXHUwMEU0cmxlZG5pbmdzb2JqZWt0IGZcdTAwRjZyIGF0dCBpbXBsZW1lbnRlcmEgbm9kZVRlc3QhIn0sCi0KLSAgeyBXR19GVU5DVElPTl9UT0tFTl9OT1RfRk9VTkQsCi0gICAgICAiZnVua3Rpb25zdGVja2VuIGhpdHRhZGVzIGludGUuIn0sCi0KLSAgeyBXR19DT1VMRE5PVF9GSU5EX0ZVTkNUSU9OLAotICAgICAgIkhpdHRhZGUgaW50ZSBmdW5rdGlvbmVuOiB7MH0ifSwKLQotICB7IFdHX0NBTk5PVF9NQUtFX1VSTF9GUk9NLAotICAgICAgIkthbiBpbnRlIHNrYXBhIFVSTCBmclx1MDBFNW46IHswfSJ9LAotCi0gIHsgV0dfRVhQQU5EX0VOVElUSUVTX05PVF9TVVBQT1JURUQsCi0gICAgICAiQWx0ZXJuYXRpdmV0IC1FIHN0XHUwMEY2ZHMgaW50ZSBpIERUTS1wYXJzZXIifSwKLQotICB7IFdHX0lMTEVHQUxfVkFSSUFCTEVfUkVGRVJFTkNFLAotICAgICAgIlZhcmlhYmxlUmVmZXJlbmNlIGFuZ2l2ZW4gZlx1MDBGNnIgdmFyaWFiZWwgc29tIFx1MDBFNHIgdXRhbmZcdTAwRjZyIGtvbnRleHQgZWxsZXIgc29tIHNha25hciBkZWZpbml0aW9uISBOYW1uID0gezB9In0sCi0KLSAgeyBXR19VTlNVUFBPUlRFRF9FTkNPRElORywKLSAgICAgIktvZG5pbmcgdXRhbiBzdFx1MDBGNmQ6IHswfSJ9LAotCi0KLQotICAvLyBPdGhlciBtaXNjZWxsYW5lb3VzIHRleHQgdXNlZCBpbnNpZGUgdGhlIGNvZGUuLi4KLSAgeyAidWlfbGFuZ3VhZ2UiLCAiZW4ifSwKLSAgeyAiaGVscF9sYW5ndWFnZSIsICJlbiJ9LAotICB7ICJsYW5ndWFnZSIsICJlbiJ9LAotICB7ICJCQURfQ09ERSIsICJQYXJhbWV0ZXIgZlx1MDBGNnIgY3JlYXRlTWVzc2FnZSBsaWdnZXIgdXRhbmZcdTAwRjZyIGdyXHUwMEU0bnN2XHUwMEU0cmRldCJ9LAotICB7ICJGT1JNQVRfRkFJTEVEIiwgIlVuZGFudGFnIHV0bFx1MDBGNnN0IHZpZCBtZXNzYWdlRm9ybWF0LWFucm9wIn0sCi0gIHsgInZlcnNpb24iLCAiPj4+Pj4+PiBYYWxhbiB2ZXJzaW9uICJ9LAotICB7ICJ2ZXJzaW9uMiIsICI8PDw8PDw8In0sCi0gIHsgInllcyIsICJqYSJ9LAotICB7ICJsaW5lIiwgIlJhZCBuciJ9LAotICB7ICJjb2x1bW4iLCAiS29sdW1uIG5yIn0sCi0gIHsgInhzbGRvbmUiLCAiWFNMUHJvY2Vzc29yOiB1dGZcdTAwRjZyZCJ9LAotICB7ICJ4cGF0aF9vcHRpb24iLCAieHBhdGgtYWx0ZXJuYXRpdjogIn0sCi0gIHsgIm9wdGlvbklOIiwgIiAgIFstaW4gaW5wdXRYTUxVUkxdIn0sCi0gIHsgIm9wdGlvblNlbGVjdCIsICIgICBbLXNlbGVjdCB4cGF0aC11dHRyeWNrXSJ9LAotICB7ICJvcHRpb25NYXRjaCIsICIgICBbLW1hdGNoIG1hdGNobmluZ3NtXHUwMEY2bnN0ZXIgKGZcdTAwRjZyIG1hdGNobmluZ3NkaWFnbm9zdGlrKV0ifSwKLSAgeyAib3B0aW9uQW55RXhwciIsICJFbGxlciBiYXJhIGV0dCB4cGF0aC11dHRyeWNrIHNrYXBhciBlbiBkaWFnbm9zdGlrZHVtcCJ9LAotICB7ICJub1BhcnNlcm1zZzEiLCAiWFNMLXByb2Nlc3NlbiB1dGZcdTAwRjZyZGVzIGludGUuIn0sCi0gIHsgIm5vUGFyc2VybXNnMiIsICIqKiBIaXR0YWRlIGludGUgcGFyc2VyICoqIn0sCi0gIHsgIm5vUGFyc2VybXNnMyIsICJLb250cm9sbGVyYSBrbGFzc1x1MDBGNmt2XHUwMEU0Z2VuLiJ9LAotICB7ICJub1BhcnNlcm1zZzQiLCAiT20gZHUgaW50ZSBoYXIgSUJNcyBYTUwgUGFyc2VyIGZcdTAwRjZyIEphdmEga2FuIGR1IGxhZGRhIG5lZCBkZW4gZnJcdTAwRTVuIn0sCi0gIHsgIm5vUGFyc2VybXNnNSIsICJJQk1zIEFscGhhV29ya3M6IGh0dHA6Ly93d3cuYWxwaGF3b3Jrcy5pYm0uY29tL2Zvcm11bGEveG1sIn0sCi0gIHsgImd0b25lIiwgIj4xIiB9LAotICB7ICJ6ZXJvIiwgIjAiIH0sCi0gIHsgIm9uZSIsICIxIiB9LAotICB7ICJ0d28iICwgIjIiIH0sCi0gIHsgInRocmVlIiwgIjMiIH0KLQotICB9OwotCi0gIC8qKgotICAgKiBHZXQgdGhlIGFzc29jaWF0aW9uIGxpc3QuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGFzc29jaWF0aW9uIGxpc3QuCi0gICAqLwotICBwdWJsaWMgT2JqZWN0W11bXSBnZXRDb250ZW50cygpCi0gIHsKLSAgICAgIHJldHVybiBfY29udGVudHM7Ci0gIH0KLQotCi0gIC8vID09PT09PT09PT09PT09PT09IElORlJBU1RSVUNUVVJFID09PT09PT09PT09PT09PT09PT09PT0KLQotICAvKiogRmllbGQgQkFEX0NPREUgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQkFEX0NPREUgPSAiQkFEX0NPREUiOwotCi0gIC8qKiBGaWVsZCBGT1JNQVRfRkFJTEVEICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEZPUk1BVF9GQUlMRUQgPSAiRk9STUFUX0ZBSUxFRCI7Ci0KLSAgLyoqIEZpZWxkIEVSUk9SX1JFU09VUkNFUyAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJPUl9SRVNPVVJDRVMgPQotICAgICJjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucmVzLlhQQVRIRXJyb3JSZXNvdXJjZXMiOwotCi0gIC8qKiBGaWVsZCBFUlJPUl9TVFJJTkcgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJST1JfU1RSSU5HID0gIiNlcnJvciI7Ci0KLSAgLyoqIEZpZWxkIEVSUk9SX0hFQURFUiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJPUl9IRUFERVIgPSAiRXJyb3I6ICI7Ci0KLSAgLyoqIEZpZWxkIFdBUk5JTkdfSEVBREVSICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdBUk5JTkdfSEVBREVSID0gIldhcm5pbmc6ICI7Ci0KLSAgLyoqIEZpZWxkIFhTTF9IRUFERVIgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgWFNMX0hFQURFUiA9ICJYU0wgIjsKLQotICAvKiogRmllbGQgWE1MX0hFQURFUiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxfSEVBREVSID0gIlhNTCAiOwotCi0gIC8qKiBGaWVsZCBRVUVSWV9IRUFERVIgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgUVVFUllfSEVBREVSID0gIlBBVFRFUk4gIjsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9yZXMvWFBBVEhFcnJvclJlc291cmNlc196aF9DTi5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9yZXMvWFBBVEhFcnJvclJlc291cmNlc196aF9DTi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiMDIzM2IxLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvcmVzL1hQQVRIRXJyb3JSZXNvdXJjZXNfemhfQ04uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDkzNiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5yZXM7Ci0KLWltcG9ydCBqYXZhLnV0aWwuTGlzdFJlc291cmNlQnVuZGxlOwotCi0vKioKLSAqIFNldCB1cCBlcnJvciBtZXNzYWdlcy4KLSAqIFdlIGJ1aWxkIGEgdHdvIGRpbWVuc2lvbmFsIGFycmF5IG9mIG1lc3NhZ2Uga2V5cyBhbmQKLSAqIG1lc3NhZ2Ugc3RyaW5ncy4gSW4gb3JkZXIgdG8gYWRkIGEgbmV3IG1lc3NhZ2UgaGVyZSwKLSAqIHlvdSBuZWVkIHRvIGZpcnN0IGFkZCBhIFN0YXRpYyBzdHJpbmcgY29uc3RhbnQgZm9yIHRoZQotICogS2V5IGFuZCB1cGRhdGUgdGhlIGNvbnRlbnRzIGFycmF5IHdpdGggS2V5LCBWYWx1ZSBwYWlyCi0gICogQWxzbyB5b3UgbmVlZCB0byAgdXBkYXRlIHRoZSBjb3VudCBvZiBtZXNzYWdlcyhNQVhfQ09ERSlvcgotICogdGhlIGNvdW50IG9mIHdhcm5pbmdzKE1BWF9XQVJOSU5HKSBbIEluZm9ybWF0aW9uIHB1cnBvc2Ugb25seV0KLSAqIEB4c2wudXNhZ2UgYWR2YW5jZWQKLSAqLwotcHVibGljIGNsYXNzIFhQQVRIRXJyb3JSZXNvdXJjZXNfemhfQ04gZXh0ZW5kcyBMaXN0UmVzb3VyY2VCdW5kbGUKLXsKLQotLyoKLSAqIEdlbmVyYWwgbm90ZXMgdG8gdHJhbnNsYXRvcnM6Ci0gKgotICogVGhpcyBmaWxlIGNvbnRhaW5zIGVycm9yIGFuZCB3YXJuaW5nIG1lc3NhZ2VzIHJlbGF0ZWQgdG8gWFBhdGggRXJyb3IKLSAqIEhhbmRsaW5nLgotICoKLSAqICAxKSBYYWxhbiAob3IgbW9yZSBwcm9wZXJseSwgWGFsYW4taW50ZXJwcmV0aXZlKSBhbmQgWFNMVEMgYXJlIG5hbWVzIG9mCi0gKiAgICAgY29tcG9uZW50cy4KLSAqICAgICBYU0xUIGlzIGFuIGFjcm9ueW0gZm9yICJYTUwgU3R5bGVzaGVldCBMYW5ndWFnZTogVHJhbnNmb3JtYXRpb25zIi4KLSAqICAgICBYU0xUQyBpcyBhbiBhY3JvbnltIGZvciBYU0xUIENvbXBpbGVyLgotICoKLSAqICAyKSBBIHN0eWxlc2hlZXQgaXMgYSBkZXNjcmlwdGlvbiBvZiBob3cgdG8gdHJhbnNmb3JtIGFuIGlucHV0IFhNTCBkb2N1bWVudAotICogICAgIGludG8gYSByZXN1bHRhbnQgWE1MIGRvY3VtZW50IChvciBIVE1MIGRvY3VtZW50IG9yIHRleHQpLiAgVGhlCi0gKiAgICAgc3R5bGVzaGVldCBpdHNlbGYgaXMgZGVzY3JpYmVkIGluIHRoZSBmb3JtIG9mIGFuIFhNTCBkb2N1bWVudC4KLSAqCi0gKiAgMykgQSB0ZW1wbGF0ZSBpcyBhIGNvbXBvbmVudCBvZiBhIHN0eWxlc2hlZXQgdGhhdCBpcyB1c2VkIHRvIG1hdGNoIGEKLSAqICAgICBwYXJ0aWN1bGFyIHBvcnRpb24gb2YgYW4gaW5wdXQgZG9jdW1lbnQgYW5kIHNwZWNpZmllcyB0aGUgZm9ybSBvZiB0aGUKLSAqICAgICBjb3JyZXNwb25kaW5nIHBvcnRpb24gb2YgdGhlIG91dHB1dCBkb2N1bWVudC4KLSAqCi0gKiAgNCkgQW4gZWxlbWVudCBpcyBhIG1hcmstdXAgdGFnIGluIGFuIFhNTCBkb2N1bWVudDsgYW4gYXR0cmlidXRlIGlzIGEKLSAqICAgICBtb2RpZmllciBvbiB0aGUgdGFnLiAgRm9yIGV4YW1wbGUsIGluIDxlbGVtIGF0dHI9J3ZhbCcgYXR0cjI9J3ZhbDInPgotICogICAgICJlbGVtIiBpcyBhbiBlbGVtZW50IG5hbWUsICJhdHRyIiBhbmQgImF0dHIyIiBhcmUgYXR0cmlidXRlIG5hbWVzIHdpdGgKLSAqICAgICB0aGUgdmFsdWVzICJ2YWwiIGFuZCAidmFsMiIsIHJlc3BlY3RpdmVseS4KLSAqCi0gKiAgNSkgQSBuYW1lc3BhY2UgZGVjbGFyYXRpb24gaXMgYSBzcGVjaWFsIGF0dHJpYnV0ZSB0aGF0IGlzIHVzZWQgdG8gYXNzb2NpYXRlCi0gKiAgICAgYSBwcmVmaXggd2l0aCBhIFVSSSAodGhlIG5hbWVzcGFjZSkuICBUaGUgbWVhbmluZ3Mgb2YgZWxlbWVudCBuYW1lcyBhbmQKLSAqICAgICBhdHRyaWJ1dGUgbmFtZXMgdGhhdCB1c2UgdGhhdCBwcmVmaXggYXJlIGRlZmluZWQgd2l0aCByZXNwZWN0IHRvIHRoYXQKLSAqICAgICBuYW1lc3BhY2UuCi0gKgotICogIDYpICJUcmFuc2xldCIgaXMgYW4gaW52ZW50ZWQgdGVybSB0aGF0IGRlc2NyaWJlcyB0aGUgY2xhc3MgZmlsZSB0aGF0Ci0gKiAgICAgcmVzdWx0cyBmcm9tIGNvbXBpbGluZyBhbiBYTUwgc3R5bGVzaGVldCBpbnRvIGEgSmF2YSBjbGFzcy4KLSAqCi0gKiAgNykgWFBhdGggaXMgYSBzcGVjaWZpY2F0aW9uIHRoYXQgZGVzY3JpYmVzIGEgbm90YXRpb24gZm9yIGlkZW50aWZ5aW5nCi0gKiAgICAgbm9kZXMgaW4gYSB0cmVlLXN0cnVjdHVyZWQgcmVwcmVzZW50YXRpb24gb2YgYW4gWE1MIGRvY3VtZW50LiAgQW4KLSAqICAgICBpbnN0YW5jZSBvZiB0aGF0IG5vdGF0aW9uIGlzIHJlZmVycmVkIHRvIGFzIGFuIFhQYXRoIGV4cHJlc3Npb24uCi0gKgotICogIDgpIFRoZSBjb250ZXh0IG5vZGUgaXMgdGhlIG5vZGUgaW4gdGhlIGRvY3VtZW50IHdpdGggcmVzcGVjdCB0byB3aGljaCBhbgotICogICAgIFhQYXRoIGV4cHJlc3Npb24gaXMgYmVpbmcgZXZhbHVhdGVkLgotICoKLSAqICA5KSBBbiBpdGVyYXRvciBpcyBhbiBvYmplY3QgdGhhdCB0cmF2ZXJzZXMgbm9kZXMgaW4gdGhlIHRyZWUsIG9uZSBhdCBhIHRpbWUuCi0gKgotICogIDEwKSBOQ05hbWUgaXMgYW4gWE1MIHRlcm0gdXNlZCB0byBkZXNjcmliZSBhIG5hbWUgdGhhdCBkb2VzIG5vdCBjb250YWluIGEKLSAqICAgICBjb2xvbiAoYSAibm8tY29sb24gbmFtZSIpLgotICoKLSAqICAxMSkgUU5hbWUgaXMgYW4gWE1MIHRlcm0gbWVhbmluZyAicXVhbGlmaWVkIG5hbWUiLgotICovCi0KLSAgLyoKLSAgICogc3RhdGljIHZhcmlhYmxlcwotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJST1IwMDAwID0gIkVSUk9SMDAwMCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NVUlJFTlRfTk9UX0FMTE9XRURfSU5fTUFUQ0ggPQotICAgICAgICAgIkVSX0NVUlJFTlRfTk9UX0FMTE9XRURfSU5fTUFUQ0giOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DVVJSRU5UX1RBS0VTX05PX0FSR1MgPQotICAgICAgICAgIkVSX0NVUlJFTlRfVEFLRVNfTk9fQVJHUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0RPQ1VNRU5UX1JFUExBQ0VEID0gIkVSX0RPQ1VNRU5UX1JFUExBQ0VEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09OVEVYVF9IQVNfTk9fT1dORVJET0MgPQotICAgICAgICAgIkVSX0NPTlRFWFRfSEFTX05PX09XTkVSRE9DIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTE9DQUxOQU1FX0hBU19UT09fTUFOWV9BUkdTID0KLSAgICAgICAgICJFUl9MT0NBTE5BTUVfSEFTX1RPT19NQU5ZX0FSR1MiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OQU1FU1BBQ0VVUklfSEFTX1RPT19NQU5ZX0FSR1MgPQotICAgICAgICAgIkVSX05BTUVTUEFDRVVSSV9IQVNfVE9PX01BTllfQVJHUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PUk1BTElaRVNQQUNFX0hBU19UT09fTUFOWV9BUkdTID0KLSAgICAgICAgICJFUl9OT1JNQUxJWkVTUEFDRV9IQVNfVE9PX01BTllfQVJHUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05VTUJFUl9IQVNfVE9PX01BTllfQVJHUyA9Ci0gICAgICAgICAiRVJfTlVNQkVSX0hBU19UT09fTUFOWV9BUkdTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTkFNRV9IQVNfVE9PX01BTllfQVJHUyA9Ci0gICAgICAgICAiRVJfTkFNRV9IQVNfVE9PX01BTllfQVJHUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NUUklOR19IQVNfVE9PX01BTllfQVJHUyA9Ci0gICAgICAgICAiRVJfU1RSSU5HX0hBU19UT09fTUFOWV9BUkdTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU1RSSU5HTEVOR1RIX0hBU19UT09fTUFOWV9BUkdTID0KLSAgICAgICAgICJFUl9TVFJJTkdMRU5HVEhfSEFTX1RPT19NQU5ZX0FSR1MiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9UUkFOU0xBVEVfVEFLRVNfM19BUkdTID0KLSAgICAgICAgICJFUl9UUkFOU0xBVEVfVEFLRVNfM19BUkdTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5QQVJTRURFTlRJVFlVUklfVEFLRVNfMV9BUkcgPQotICAgICAgICAgIkVSX1VOUEFSU0VERU5USVRZVVJJX1RBS0VTXzFfQVJHIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTkFNRVNQQUNFQVhJU19OT1RfSU1QTEVNRU5URUQgPQotICAgICAgICAgIkVSX05BTUVTUEFDRUFYSVNfTk9UX0lNUExFTUVOVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5LTk9XTl9BWElTID0gIkVSX1VOS05PV05fQVhJUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1VOS05PV05fTUFUQ0hfT1BFUkFUSU9OID0KLSAgICAgICAgICJFUl9VTktOT1dOX01BVENIX09QRVJBVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOQ09SUkVDVF9BUkdfTEVOR1RIID0iRVJfSU5DT1JSRUNUX0FSR19MRU5HVEgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX0NPTlZFUlRfVE9fTlVNQkVSID0KLSAgICAgICAgICJFUl9DQU5UX0NPTlZFUlRfVE9fTlVNQkVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9DT05WRVJUX1hQQVRIUkVTVUxUVFlQRV9UT19OVU1CRVIgPQotICAgICAgICAgICAiRVJfQ0FOVF9DT05WRVJUX1hQQVRIUkVTVUxUVFlQRV9UT19OVU1CRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX0NPTlZFUlRfVE9fTk9ERUxJU1QgPQotICAgICAgICAgIkVSX0NBTlRfQ09OVkVSVF9UT19OT0RFTElTVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfQ09OVkVSVF9UT19NVVRBQkxFTk9ERUxJU1QgPQotICAgICAgICAgIkVSX0NBTlRfQ09OVkVSVF9UT19NVVRBQkxFTk9ERUxJU1QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX0NPTlZFUlRfVE9fVFlQRSA9IkVSX0NBTlRfQ09OVkVSVF9UT19UWVBFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhQRUNURURfTUFUQ0hfUEFUVEVSTiA9Ci0gICAgICAgICAiRVJfRVhQRUNURURfTUFUQ0hfUEFUVEVSTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxETk9UX0dFVF9WQVJfTkFNRUQgPQotICAgICAgICAgIkVSX0NPVUxETk9UX0dFVF9WQVJfTkFNRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTktOT1dOX09QQ09ERSA9ICJFUl9VTktOT1dOX09QQ09ERSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYVFJBX0lMTEVHQUxfVE9LRU5TID0iRVJfRVhUUkFfSUxMRUdBTF9UT0tFTlMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FWFBFQ1RFRF9ET1VCTEVfUVVPVEUgPQotICAgICAgICAgIkVSX0VYUEVDVEVEX0RPVUJMRV9RVU9URSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYUEVDVEVEX1NJTkdMRV9RVU9URSA9Ci0gICAgICAgICAiRVJfRVhQRUNURURfU0lOR0xFX1FVT1RFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRU1QVFlfRVhQUkVTU0lPTiA9ICJFUl9FTVBUWV9FWFBSRVNTSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhQRUNURURfQlVUX0ZPVU5EID0gIkVSX0VYUEVDVEVEX0JVVF9GT1VORCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOQ09SUkVDVF9QUk9HUkFNTUVSX0FTU0VSVElPTiA9Ci0gICAgICAgICAiRVJfSU5DT1JSRUNUX1BST0dSQU1NRVJfQVNTRVJUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQk9PTEVBTl9BUkdfTk9fTE9OR0VSX09QVElPTkFMID0KLSAgICAgICAgICJFUl9CT09MRUFOX0FSR19OT19MT05HRVJfT1BUSU9OQUwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GT1VORF9DT01NQV9CVVRfTk9fUFJFQ0VESU5HX0FSRyA9Ci0gICAgICAgICAiRVJfRk9VTkRfQ09NTUFfQlVUX05PX1BSRUNFRElOR19BUkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GT1VORF9DT01NQV9CVVRfTk9fRk9MTE9XSU5HX0FSRyA9Ci0gICAgICAgICAiRVJfRk9VTkRfQ09NTUFfQlVUX05PX0ZPTExPV0lOR19BUkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUkVESUNBVEVfSUxMRUdBTF9TWU5UQVggPQotICAgICAgICAgIkVSX1BSRURJQ0FURV9JTExFR0FMX1NZTlRBWCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lMTEVHQUxfQVhJU19OQU1FID0gIkVSX0lMTEVHQUxfQVhJU19OQU1FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5LTk9XTl9OT0RFVFlQRSA9ICJFUl9VTktOT1dOX05PREVUWVBFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUEFUVEVSTl9MSVRFUkFMX05FRURTX0JFX1FVT1RFRCA9Ci0gICAgICAgICAiRVJfUEFUVEVSTl9MSVRFUkFMX05FRURTX0JFX1FVT1RFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxETk9UX0JFX0ZPUk1BVFRFRF9UT19OVU1CRVIgPQotICAgICAgICAgIkVSX0NPVUxETk9UX0JFX0ZPUk1BVFRFRF9UT19OVU1CRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRE5PVF9DUkVBVEVfWE1MUFJPQ0VTU09STElBSVNPTiA9Ci0gICAgICAgICAiRVJfQ09VTEROT1RfQ1JFQVRFX1hNTFBST0NFU1NPUkxJQUlTT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9ESUROT1RfRklORF9YUEFUSF9TRUxFQ1RfRVhQID0KLSAgICAgICAgICJFUl9ESUROT1RfRklORF9YUEFUSF9TRUxFQ1RfRVhQIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTEROT1RfRklORF9FTkRPUF9BRlRFUl9PUExPQ0FUSU9OUEFUSCA9Ci0gICAgICAgICAiRVJfQ09VTEROT1RfRklORF9FTkRPUF9BRlRFUl9PUExPQ0FUSU9OUEFUSCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VSUk9SX09DQ1VSRUQgPSAiRVJfRVJST1JfT0NDVVJFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lMTEVHQUxfVkFSSUFCTEVfUkVGRVJFTkNFID0KLSAgICAgICAgICJFUl9JTExFR0FMX1ZBUklBQkxFX1JFRkVSRU5DRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FYRVNfTk9UX0FMTE9XRUQgPSAiRVJfQVhFU19OT1RfQUxMT1dFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0tFWV9IQVNfVE9PX01BTllfQVJHUyA9Ci0gICAgICAgICAiRVJfS0VZX0hBU19UT09fTUFOWV9BUkdTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTlRfVEFLRVNfMV9BUkcgPSAiRVJfQ09VTlRfVEFLRVNfMV9BUkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRE5PVF9GSU5EX0ZVTkNUSU9OID0KLSAgICAgICAgICJFUl9DT1VMRE5PVF9GSU5EX0ZVTkNUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5TVVBQT1JURURfRU5DT0RJTkcgPSJFUl9VTlNVUFBPUlRFRF9FTkNPRElORyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BST0JMRU1fSU5fRFRNX05FWFRTSUJMSU5HID0KLSAgICAgICAgICJFUl9QUk9CTEVNX0lOX0RUTV9ORVhUU0lCTElORyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9XUklURV9UT19FTVBUWU5PREVMSVNUSU1QTCA9Ci0gICAgICAgICAiRVJfQ0FOTk9UX1dSSVRFX1RPX0VNUFRZTk9ERUxJU1RJTVBMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU0VURE9NRkFDVE9SWV9OT1RfU1VQUE9SVEVEID0KLSAgICAgICAgICJFUl9TRVRET01GQUNUT1JZX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUkVGSVhfTVVTVF9SRVNPTFZFID0gIkVSX1BSRUZJWF9NVVNUX1JFU09MVkUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QQVJTRV9OT1RfU1VQUE9SVEVEID0gIkVSX1BBUlNFX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TQVhfQVBJX05PVF9IQU5ETEVEID0gIkVSX1NBWF9BUElfTk9UX0hBTkRMRUQiOwotcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSUdOT1JBQkxFX1dISVRFU1BBQ0VfTk9UX0hBTkRMRUQgPQotICAgICAgICAgIkVSX0lHTk9SQUJMRV9XSElURVNQQUNFX05PVF9IQU5ETEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRFRNX0NBTk5PVF9IQU5ETEVfTk9ERVMgPQotICAgICAgICAgIkVSX0RUTV9DQU5OT1RfSEFORExFX05PREVTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWEVSQ0VTX0NBTk5PVF9IQU5ETEVfTk9ERVMgPQotICAgICAgICAgIkVSX1hFUkNFU19DQU5OT1RfSEFORExFX05PREVTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWEVSQ0VTX1BBUlNFX0VSUk9SX0RFVEFJTFMgPQotICAgICAgICAgIkVSX1hFUkNFU19QQVJTRV9FUlJPUl9ERVRBSUxTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWEVSQ0VTX1BBUlNFX0VSUk9SID0gIkVSX1hFUkNFU19QQVJTRV9FUlJPUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfVVRGMTZfU1VSUk9HQVRFID0KLSAgICAgICAgICJFUl9JTlZBTElEX1VURjE2X1NVUlJPR0FURSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX09JRVJST1IgPSAiRVJfT0lFUlJPUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9DUkVBVEVfVVJMID0gIkVSX0NBTk5PVF9DUkVBVEVfVVJMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWFBBVEhfUkVBRE9CSkVDVCA9ICJFUl9YUEFUSF9SRUFET0JKRUNUIjsKLSBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GVU5DVElPTl9UT0tFTl9OT1RfRk9VTkQgPQotICAgICAgICAgIkVSX0ZVTkNUSU9OX1RPS0VOX05PVF9GT1VORCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9ERUFMX1hQQVRIX1RZUEUgPQotICAgICAgICAgIkVSX0NBTk5PVF9ERUFMX1hQQVRIX1RZUEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT0RFU0VUX05PVF9NVVRBQkxFID0gIkVSX05PREVTRVRfTk9UX01VVEFCTEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT0RFU0VURFRNX05PVF9NVVRBQkxFID0KLSAgICAgICAgICJFUl9OT0RFU0VURFRNX05PVF9NVVRBQkxFIjsKLSAgIC8qKiAgVmFyaWFibGUgbm90IHJlc29sdmFibGU6ICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVkFSX05PVF9SRVNPTFZBQkxFID0gIkVSX1ZBUl9OT1RfUkVTT0xWQUJMRSI7Ci0gICAvKiogTnVsbCBlcnJvciBoYW5kbGVyICAqLwotIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05VTExfRVJST1JfSEFORExFUiA9ICJFUl9OVUxMX0VSUk9SX0hBTkRMRVIiOwotICAgLyoqICBQcm9ncmFtbWVyJ3MgYXNzZXJ0aW9uOiB1bmtub3duIG9wY29kZSAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJPR19BU1NFUlRfVU5LTk9XTl9PUENPREUgPQotICAgICAgICAgIkVSX1BST0dfQVNTRVJUX1VOS05PV05fT1BDT0RFIjsKLSAgIC8qKiAgMCBvciAxICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWkVST19PUl9PTkUgPSAiRVJfWkVST19PUl9PTkUiOwotICAgLyoqICBydGYoKSBub3Qgc3VwcG9ydGVkIGJ5IFhSVHJlZUZyYWdTZWxlY3RXcmFwcGVyICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUlRGX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIgPQotICAgICAgICAgIkVSX1JURl9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSIjsKLSAgIC8qKiAgYXNOb2RlSXRlcmF0b3IoKSBub3Qgc3VwcG9ydGVkIGJ5IFhSVHJlZUZyYWdTZWxlY3RXcmFwcGVyICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQVNOT0RFSVRFUkFUT1JfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiA9ICJFUl9BU05PREVJVEVSQVRPUl9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSIjsKLSAgIC8qKiAgZnNiKCkgbm90IHN1cHBvcnRlZCBmb3IgWFN0cmluZ0ZvckNoYXJzICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRlNCX05PVF9TVVBQT1JURURfWFNUUklOR0ZPUkNIQVJTID0KLSAgICAgICAgICJFUl9GU0JfTk9UX1NVUFBPUlRFRF9YU1RSSU5HRk9SQ0hBUlMiOwotICAgLyoqICBDb3VsZCBub3QgZmluZCB2YXJpYWJsZSB3aXRoIHRoZSBuYW1lIG9mICAgKi8KLSBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRF9OT1RfRklORF9WQVIgPSAiRVJfQ09VTERfTk9UX0ZJTkRfVkFSIjsKLSAgIC8qKiAgWFN0cmluZ0ZvckNoYXJzIGNhbiBub3QgdGFrZSBhIHN0cmluZyBmb3IgYW4gYXJndW1lbnQgICAqLwotIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hTVFJJTkdGT1JDSEFSU19DQU5OT1RfVEFLRV9TVFJJTkcgPQotICAgICAgICAgIkVSX1hTVFJJTkdGT1JDSEFSU19DQU5OT1RfVEFLRV9TVFJJTkciOwotICAgLyoqICBUaGUgRmFzdFN0cmluZ0J1ZmZlciBhcmd1bWVudCBjYW4gbm90IGJlIG51bGwgICAqLwotIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZBU1RTVFJJTkdCVUZGRVJfQ0FOTk9UX0JFX05VTEwgPQotICAgICAgICAgIkVSX0ZBU1RTVFJJTkdCVUZGRVJfQ0FOTk9UX0JFX05VTEwiOwotICAgLyoqICAyIG9yIDMgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9UV09fT1JfVEhSRUUgPSAiRVJfVFdPX09SX1RIUkVFIjsKLSAgIC8qKiBWYXJpYWJsZSBhY2Nlc3NlZCBiZWZvcmUgaXQgaXMgYm91bmQhICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1ZBUklBQkxFX0FDQ0VTU0VEX0JFRk9SRV9CSU5EID0KLSAgICAgICAgICJFUl9WQVJJQUJMRV9BQ0NFU1NFRF9CRUZPUkVfQklORCI7Ci0gICAvKiogWFN0cmluZ0ZvckZTQiBjYW4gbm90IHRha2UgYSBzdHJpbmcgZm9yIGFuIGFyZ3VtZW50ISAqLwotIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZTQl9DQU5OT1RfVEFLRV9TVFJJTkcgPQotICAgICAgICAgIkVSX0ZTQl9DQU5OT1RfVEFLRV9TVFJJTkciOwotICAgLyoqIEVycm9yISBTZXR0aW5nIHRoZSByb290IG9mIGEgd2Fsa2VyIHRvIG51bGwhICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NFVFRJTkdfV0FMS0VSX1JPT1RfVE9fTlVMTCA9Ci0gICAgICAgICAiRVJfU0VUVElOR19XQUxLRVJfUk9PVF9UT19OVUxMIjsKLSAgIC8qKiBUaGlzIE5vZGVTZXREVE0gY2FuIG5vdCBpdGVyYXRlIHRvIGEgcHJldmlvdXMgbm9kZSEgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9ERVNFVERUTV9DQU5OT1RfSVRFUkFURSA9Ci0gICAgICAgICAiRVJfTk9ERVNFVERUTV9DQU5OT1RfSVRFUkFURSI7Ci0gIC8qKiBUaGlzIE5vZGVTZXQgY2FuIG5vdCBpdGVyYXRlIHRvIGEgcHJldmlvdXMgbm9kZSEgKi8KLSBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT0RFU0VUX0NBTk5PVF9JVEVSQVRFID0KLSAgICAgICAgICJFUl9OT0RFU0VUX0NBTk5PVF9JVEVSQVRFIjsKLSAgLyoqIFRoaXMgTm9kZVNldERUTSBjYW4gbm90IGRvIGluZGV4aW5nIG9yIGNvdW50aW5nIGZ1bmN0aW9ucyEgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9ERVNFVERUTV9DQU5OT1RfSU5ERVggPQotICAgICAgICAgIkVSX05PREVTRVREVE1fQ0FOTk9UX0lOREVYIjsKLSAgLyoqIFRoaXMgTm9kZVNldCBjYW4gbm90IGRvIGluZGV4aW5nIG9yIGNvdW50aW5nIGZ1bmN0aW9ucyEgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9ERVNFVF9DQU5OT1RfSU5ERVggPQotICAgICAgICAgIkVSX05PREVTRVRfQ0FOTk9UX0lOREVYIjsKLSAgLyoqIENhbiBub3QgY2FsbCBzZXRTaG91bGRDYWNoZU5vZGVzIGFmdGVyIG5leHROb2RlIGhhcyBiZWVuIGNhbGxlZCEgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX0NBTExfU0VUU0hPVUxEQ0FDSEVOT0RFID0KLSAgICAgICAgICJFUl9DQU5OT1RfQ0FMTF9TRVRTSE9VTERDQUNIRU5PREUiOwotICAvKiogezB9IG9ubHkgYWxsb3dzIHsxfSBhcmd1bWVudHMgKi8KLSBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9PTkxZX0FMTE9XUyA9ICJFUl9PTkxZX0FMTE9XUyI7Ci0gIC8qKiBQcm9ncmFtbWVyJ3MgYXNzZXJ0aW9uIGluIGdldE5leHRTdGVwUG9zOiB1bmtub3duIHN0ZXBUeXBlOiB7MH0gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5LTk9XTl9TVEVQID0gIkVSX1VOS05PV05fU1RFUCI7Ci0gIC8qKiBQcm9ibGVtIHdpdGggUmVsYXRpdmVMb2NhdGlvblBhdGggKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhQRUNURURfUkVMX0xPQ19QQVRIID0KLSAgICAgICAgICJFUl9FWFBFQ1RFRF9SRUxfTE9DX1BBVEgiOwotICAvKiogUHJvYmxlbSB3aXRoIExvY2F0aW9uUGF0aCAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FWFBFQ1RFRF9MT0NfUEFUSCA9ICJFUl9FWFBFQ1RFRF9MT0NfUEFUSCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYUEVDVEVEX0xPQ19QQVRIX0FUX0VORF9FWFBSID0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRVJfRVhQRUNURURfTE9DX1BBVEhfQVRfRU5EX0VYUFIiOwotICAvKiogUHJvYmxlbSB3aXRoIFN0ZXAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhQRUNURURfTE9DX1NURVAgPSAiRVJfRVhQRUNURURfTE9DX1NURVAiOwotICAvKiogUHJvYmxlbSB3aXRoIE5vZGVUZXN0ICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYUEVDVEVEX05PREVfVEVTVCA9ICJFUl9FWFBFQ1RFRF9OT0RFX1RFU1QiOwotICAvKiogRXhwZWN0ZWQgc3RlcCBwYXR0ZXJuICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYUEVDVEVEX1NURVBfUEFUVEVSTiA9Ci0gICAgICAgICJFUl9FWFBFQ1RFRF9TVEVQX1BBVFRFUk4iOwotICAvKiogRXhwZWN0ZWQgcmVsYXRpdmUgcGF0aCBwYXR0ZXJuICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYUEVDVEVEX1JFTF9QQVRIX1BBVFRFUk4gPQotICAgICAgICAgIkVSX0VYUEVDVEVEX1JFTF9QQVRIX1BBVFRFUk4iOwotICAvKiogRVJfQ0FOVF9DT05WRVJUX1hQQVRIUkVTVUxUVFlQRV9UT19CT09MRUFOICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfQ09OVkVSVF9UT19CT09MRUFOID0KLSAgICAgICAgICJFUl9DQU5UX0NPTlZFUlRfVE9fQk9PTEVBTiI7Ci0gIC8qKiBGaWVsZCBFUl9DQU5UX0NPTlZFUlRfVE9fU0lOR0xFTk9ERSAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX0NPTlZFUlRfVE9fU0lOR0xFTk9ERSA9Ci0gICAgICAgICAiRVJfQ0FOVF9DT05WRVJUX1RPX1NJTkdMRU5PREUiOwotICAvKiogRmllbGQgRVJfQ0FOVF9HRVRfU05BUFNIT1RfTEVOR1RIICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9HRVRfU05BUFNIT1RfTEVOR1RIID0KLSAgICAgICAgICJFUl9DQU5UX0dFVF9TTkFQU0hPVF9MRU5HVEgiOwotICAvKiogRmllbGQgRVJfTk9OX0lURVJBVE9SX1RZUEUgICAgICAgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9OX0lURVJBVE9SX1RZUEUgPSAiRVJfTk9OX0lURVJBVE9SX1RZUEUiOwotICAvKiogRmllbGQgRVJfRE9DX01VVEFURUQgICAgICAgICAgICAgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRE9DX01VVEFURUQgPSAiRVJfRE9DX01VVEFURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX1hQQVRIX1RZUEUgPSAiRVJfSU5WQUxJRF9YUEFUSF9UWVBFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRU1QVFlfWFBBVEhfUkVTVUxUID0gIkVSX0VNUFRZX1hQQVRIX1JFU1VMVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOQ09NUEFUSUJMRV9UWVBFUyA9ICJFUl9JTkNPTVBBVElCTEVfVFlQRVMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OVUxMX1JFU09MVkVSID0gIkVSX05VTExfUkVTT0xWRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX0NPTlZFUlRfVE9fU1RSSU5HID0KLSAgICAgICAgICJFUl9DQU5UX0NPTlZFUlRfVE9fU1RSSU5HIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9OX1NOQVBTSE9UX1RZUEUgPSAiRVJfTk9OX1NOQVBTSE9UX1RZUEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9XUk9OR19ET0NVTUVOVCA9ICJFUl9XUk9OR19ET0NVTUVOVCI7Ci0gIC8qIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgWFBhdGggZXhwcmVzc2lvbiBjYW5ub3QgYmUgZXZhbHVhdGVkIHdpdGggcmVzcGVjdAotICAgKiB0byB0aGlzIHR5cGUgb2Ygbm9kZS4KLSAgICovCi0gIC8qKiBGaWVsZCBFUl9XUk9OR19OT0RFVFlQRSAgICAgICAgICAgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfV1JPTkdfTk9ERVRZUEUgPSAiRVJfV1JPTkdfTk9ERVRZUEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YUEFUSF9FUlJPUiA9ICJFUl9YUEFUSF9FUlJPUiI7Ci0KLSAgLy9CRUdJTjogS2V5cyBuZWVkZWQgZm9yIGV4Y2VwdGlvbiBtZXNzYWdlcyBvZiAgSkFYUCAxLjMgWFBhdGggQVBJIGltcGxlbWVudGF0aW9uCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYVEVOU0lPTl9GVU5DVElPTl9DQU5OT1RfQkVfSU5WT0tFRCA9ICJFUl9FWFRFTlNJT05fRlVOQ1RJT05fQ0FOTk9UX0JFX0lOVk9LRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SRVNPTFZFX1ZBUklBQkxFX1JFVFVSTlNfTlVMTCA9ICJFUl9SRVNPTFZFX1ZBUklBQkxFX1JFVFVSTlNfTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1VOU1VQUE9SVEVEX1JFVFVSTl9UWVBFID0gIkVSX1VOU1VQUE9SVEVEX1JFVFVSTl9UWVBFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU09VUkNFX1JFVFVSTl9UWVBFX0NBTk5PVF9CRV9OVUxMID0gIkVSX1NPVVJDRV9SRVRVUk5fVFlQRV9DQU5OT1RfQkVfTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FSR19DQU5OT1RfQkVfTlVMTCA9ICJFUl9BUkdfQ0FOTk9UX0JFX05VTEwiOwotCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX09CSkVDVF9NT0RFTF9OVUxMID0gIkVSX09CSkVDVF9NT0RFTF9OVUxMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfT0JKRUNUX01PREVMX0VNUFRZID0gIkVSX09CSkVDVF9NT0RFTF9FTVBUWSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZFQVRVUkVfTkFNRV9OVUxMID0gIkVSX0ZFQVRVUkVfTkFNRV9OVUxMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRkVBVFVSRV9VTktOT1dOID0gIkVSX0ZFQVRVUkVfVU5LTk9XTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0dFVFRJTkdfTlVMTF9GRUFUVVJFID0gIkVSX0dFVFRJTkdfTlVMTF9GRUFUVVJFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfR0VUVElOR19VTktOT1dOX0ZFQVRVUkUgPSAiRVJfR0VUVElOR19VTktOT1dOX0ZFQVRVUkUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TRUNVUkVQUk9DRVNTSU5HX0ZFQVRVUkUgPSAiRVJfU0VDVVJFUFJPQ0VTU0lOR19GRUFUVVJFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTlVMTF9YUEFUSF9GVU5DVElPTl9SRVNPTFZFUiA9ICJFUl9OVUxMX1hQQVRIX0ZVTkNUSU9OX1JFU09MVkVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTlVMTF9YUEFUSF9WQVJJQUJMRV9SRVNPTFZFUiA9ICJFUl9OVUxMX1hQQVRIX1ZBUklBQkxFX1JFU09MVkVSIjsKLSAgLy9FTkQ6IEtleXMgbmVlZGVkIGZvciBleGNlcHRpb24gbWVzc2FnZXMgb2YgIEpBWFAgMS4zIFhQYXRoIEFQSSBpbXBsZW1lbnRhdGlvbgotCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0xPQ0FMRV9OQU1FX05PVF9IQU5ETEVEID0KLSAgICAgICAgICJXR19MT0NBTEVfTkFNRV9OT1RfSEFORExFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX1BST1BFUlRZX05PVF9TVVBQT1JURUQgPQotICAgICAgICAgIldHX1BST1BFUlRZX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19ET05UX0RPX0FOWVRISU5HX1dJVEhfTlMgPQotICAgICAgICAgIldHX0RPTlRfRE9fQU5ZVEhJTkdfV0lUSF9OUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX1NFQ1VSSVRZX0VYQ0VQVElPTiA9ICJXR19TRUNVUklUWV9FWENFUFRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19RVU9fTk9fTE9OR0VSX0RFRklORUQgPQotICAgICAgICAgIldHX1FVT19OT19MT05HRVJfREVGSU5FRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX05FRURfREVSSVZFRF9PQkpFQ1RfVE9fSU1QTEVNRU5UX05PREVURVNUID0KLSAgICAgICAgICJXR19ORUVEX0RFUklWRURfT0JKRUNUX1RPX0lNUExFTUVOVF9OT0RFVEVTVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0ZVTkNUSU9OX1RPS0VOX05PVF9GT1VORCA9Ci0gICAgICAgICAiV0dfRlVOQ1RJT05fVE9LRU5fTk9UX0ZPVU5EIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfQ09VTEROT1RfRklORF9GVU5DVElPTiA9Ci0gICAgICAgICAiV0dfQ09VTEROT1RfRklORF9GVU5DVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0NBTk5PVF9NQUtFX1VSTF9GUk9NID0iV0dfQ0FOTk9UX01BS0VfVVJMX0ZST00iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19FWFBBTkRfRU5USVRJRVNfTk9UX1NVUFBPUlRFRCA9Ci0gICAgICAgICAiV0dfRVhQQU5EX0VOVElUSUVTX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19JTExFR0FMX1ZBUklBQkxFX1JFRkVSRU5DRSA9Ci0gICAgICAgICAiV0dfSUxMRUdBTF9WQVJJQUJMRV9SRUZFUkVOQ0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19VTlNVUFBPUlRFRF9FTkNPRElORyA9IldHX1VOU1VQUE9SVEVEX0VOQ09ESU5HIjsKLQotICAvKiogIGRldGFjaCgpIG5vdCBzdXBwb3J0ZWQgYnkgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9ERVRBQ0hfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiA9Ci0gICAgICAgICAiRVJfREVUQUNIX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIiOwotICAvKiogIG51bSgpIG5vdCBzdXBwb3J0ZWQgYnkgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OVU1fTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiA9Ci0gICAgICAgICAiRVJfTlVNX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIiOwotICAvKiogIHhzdHIoKSBub3Qgc3VwcG9ydGVkIGJ5IFhSVHJlZUZyYWdTZWxlY3RXcmFwcGVyICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWFNUUl9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSID0KLSAgICAgICAgICJFUl9YU1RSX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIiOwotICAvKiogIHN0cigpIG5vdCBzdXBwb3J0ZWQgYnkgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TVFJfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiA9Ci0gICAgICAgICAiRVJfU1RSX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIiOwotCi0gIC8vIEVycm9yIG1lc3NhZ2VzLi4uCi0KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgT2JqZWN0W11bXSBfY29udGVudHMgPSBuZXcgT2JqZWN0W11bXXsKLQotICB7ICJFUlJPUjAwMDAiICwgInswfSIgfSwKLQotICB7IEVSX0NVUlJFTlRfTk9UX0FMTE9XRURfSU5fTUFUQ0gsICJcdTUzMzlcdTkxNERcdTZBMjFcdTVGMEZcdTRFMkRcdTRFMERcdTUxNDFcdThCQjhcdTRGN0ZcdTc1MjggY3VycmVudCgpIFx1NTFGRFx1NjU3MCEiIH0sCi0KLSAgeyBFUl9DVVJSRU5UX1RBS0VTX05PX0FSR1MsICJjdXJyZW50KCkgXHU1MUZEXHU2NTcwXHU0RTBEXHU2M0E1XHU1M0Q3XHU1M0MyXHU2NTcwISIgfSwKLQotICB7IEVSX0RPQ1VNRU5UX1JFUExBQ0VELAotICAgICAgImRvY3VtZW50KCkgXHU1MUZEXHU2NTcwXHU1QjlFXHU3M0IwXHU1REYyXHU2NkZGXHU2MzYyXHU0RTNBIGNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0LkZ1bmNEb2N1bWVudCEifSwKLQotICB7IEVSX0NPTlRFWFRfSEFTX05PX09XTkVSRE9DLAotICAgICAgIlx1NEUwQVx1NEUwQlx1NjU4N1x1NkNBMVx1NjcwOVx1NjI0MFx1NjcwOVx1ODAwNVx1NjU4N1x1Njg2MyEifSwKLQotICB7IEVSX0xPQ0FMTkFNRV9IQVNfVE9PX01BTllfQVJHUywKLSAgICAgICJsb2NhbC1uYW1lKCkgXHU1MTc3XHU2NzA5XHU1OTJBXHU1OTFBXHU1M0MyXHU2NTcwXHUzMDAyIn0sCi0KLSAgeyBFUl9OQU1FU1BBQ0VVUklfSEFTX1RPT19NQU5ZX0FSR1MsCi0gICAgICAibmFtZXNwYWNlLXVyaSgpIFx1NTE3N1x1NjcwOVx1NTkyQVx1NTkxQVx1NTNDMlx1NjU3MFx1MzAwMiJ9LAotCi0gIHsgRVJfTk9STUFMSVpFU1BBQ0VfSEFTX1RPT19NQU5ZX0FSR1MsCi0gICAgICAibm9ybWFsaXplLXNwYWNlKCkgXHU1MTc3XHU2NzA5XHU1OTJBXHU1OTFBXHU1M0MyXHU2NTcwXHUzMDAyIn0sCi0KLSAgeyBFUl9OVU1CRVJfSEFTX1RPT19NQU5ZX0FSR1MsCi0gICAgICAibnVtYmVyKCkgXHU1MTc3XHU2NzA5XHU1OTJBXHU1OTFBXHU1M0MyXHU2NTcwXHUzMDAyIn0sCi0KLSAgeyBFUl9OQU1FX0hBU19UT09fTUFOWV9BUkdTLAotICAgICAibmFtZSgpIFx1NTE3N1x1NjcwOVx1NTkyQVx1NTkxQVx1NTNDMlx1NjU3MFx1MzAwMiJ9LAotCi0gIHsgRVJfU1RSSU5HX0hBU19UT09fTUFOWV9BUkdTLAotICAgICAgInN0cmluZygpIFx1NTE3N1x1NjcwOVx1NTkyQVx1NTkxQVx1NTNDMlx1NjU3MFx1MzAwMiJ9LAotCi0gIHsgRVJfU1RSSU5HTEVOR1RIX0hBU19UT09fTUFOWV9BUkdTLAotICAgICAgInN0cmluZy1sZW5ndGgoKSBcdTUxNzdcdTY3MDlcdTU5MkFcdTU5MUFcdTUzQzJcdTY1NzBcdTMwMDIifSwKLQotICB7IEVSX1RSQU5TTEFURV9UQUtFU18zX0FSR1MsCi0gICAgICAidHJhbnNsYXRlKCkgXHU1MUZEXHU2NTcwXHU5MUM3XHU3NTI4XHU0RTA5XHU0RTJBXHU1M0MyXHU2NTcwISJ9LAotCi0gIHsgRVJfVU5QQVJTRURFTlRJVFlVUklfVEFLRVNfMV9BUkcsCi0gICAgICAidW5wYXJzZWQtZW50aXR5LXVyaSBcdTUxRkRcdTY1NzBcdTVFOTRcdTkxQzdcdTc1MjhcdTRFMDBcdTRFMkFcdTUzQzJcdTY1NzAhIn0sCi0KLSAgeyBFUl9OQU1FU1BBQ0VBWElTX05PVF9JTVBMRU1FTlRFRCwKLSAgICAgICJcdTVDMUFcdTY3MkFcdTVCOUVcdTczQjBcdTU0MERcdTc5RjBcdTdBN0FcdTk1RjRcdThGNzQhIn0sCi0KLSAgeyBFUl9VTktOT1dOX0FYSVMsCi0gICAgICJcdThGNzRcdTY3MkFcdTc3RTU6IHswfSJ9LAotCi0gIHsgRVJfVU5LTk9XTl9NQVRDSF9PUEVSQVRJT04sCi0gICAgICJcdTUzMzlcdTkxNERcdTY0Q0RcdTRGNUNcdTY3MkFcdTc3RTUhIn0sCi0KLSAgeyBFUl9JTkNPUlJFQ1RfQVJHX0xFTkdUSCwKLSAgICAgICJwcm9jZXNzaW5nLWluc3RydWN0aW9uKCkgXHU4MjgyXHU3MEI5XHU2RDRCXHU4QkQ1XHU3Njg0XHU1M0MyXHU2NTcwXHU5NTdGXHU1RUE2XHU0RTBEXHU2QjYzXHU3ODZFISJ9LAotCi0gIHsgRVJfQ0FOVF9DT05WRVJUX1RPX05VTUJFUiwKLSAgICAgICJcdTY1RTBcdTZDRDVcdTVDMDZ7MH1cdThGNkNcdTYzNjJcdTRFM0FcdTY1NzBcdTVCNTcifSwKLQotICB7IEVSX0NBTlRfQ09OVkVSVF9UT19OT0RFTElTVCwKLSAgICAgICJcdTY1RTBcdTZDRDVcdTVDMDZ7MH1cdThGNkNcdTYzNjJcdTRFM0EgTm9kZUxpc3QhIn0sCi0KLSAgeyBFUl9DQU5UX0NPTlZFUlRfVE9fTVVUQUJMRU5PREVMSVNULAotICAgICAgIlx1NjVFMFx1NkNENVx1NUMwNnswfVx1OEY2Q1x1NjM2Mlx1NEUzQSBOb2RlU2V0RFRNISJ9LAotCi0gIHsgRVJfQ0FOVF9DT05WRVJUX1RPX1RZUEUsCi0gICAgICAiXHU2NUUwXHU2Q0Q1XHU1QzA2ezB9XHU4RjZDXHU2MzYyXHU0RTNBIHR5cGUjezF9In0sCi0KLSAgeyBFUl9FWFBFQ1RFRF9NQVRDSF9QQVRURVJOLAotICAgICAgImdldE1hdGNoU2NvcmUgXHU0RTJEXHU5NzAwXHU4OTgxXHU1MzM5XHU5MTREXHU2QTIxXHU1RjBGISJ9LAotCi0gIHsgRVJfQ09VTEROT1RfR0VUX1ZBUl9OQU1FRCwKLSAgICAgICJcdTY1RTBcdTZDRDVcdTgzQjdcdTUzRDZcdTU0MERcdTRFM0F7MH1cdTc2ODRcdTUzRDhcdTkxQ0YifSwKLQotICB7IEVSX1VOS05PV05fT1BDT0RFLAotICAgICAiXHU5NTE5XHU4QkVGISBcdTY0Q0RcdTRGNUNcdTc4MDFcdTY3MkFcdTc3RTU6IHswfSJ9LAotCi0gIHsgRVJfRVhUUkFfSUxMRUdBTF9UT0tFTlMsCi0gICAgICJcdTk2NDRcdTUyQTBcdTk3NUVcdTZDRDVcdTY4MDdcdThCQjA6IHswfSJ9LAotCi0gIHsgRVJfRVhQRUNURURfRE9VQkxFX1FVT1RFLAotICAgICAgIlx1OTUxOVx1OEJFRlx1NUYxNVx1NzUyOFx1NzY4NFx1NjU4N1x1NUI1Ny4uLiBcdTk3MDBcdTg5ODFcdTUzQ0NcdTVGMTVcdTUzRjchIn0sCi0KLSAgeyBFUl9FWFBFQ1RFRF9TSU5HTEVfUVVPVEUsCi0gICAgICAiXHU5NTE5XHU4QkVGXHU1RjE1XHU3NTI4XHU3Njg0XHU2NTg3XHU1QjU3Li4uIFx1OTcwMFx1ODk4MVx1NTM1NVx1NUYxNVx1NTNGNyEifSwKLQotICB7IEVSX0VNUFRZX0VYUFJFU1NJT04sCi0gICAgICJcdTdBN0FcdTg4NjhcdThGQkVcdTVGMEYhIn0sCi0KLSAgeyBFUl9FWFBFQ1RFRF9CVVRfRk9VTkQsCi0gICAgICJcdTk3MDBcdTg5ODF7MH0sIFx1NEY0Nlx1NjI3RVx1NTIzMDogezF9In0sCi0KLSAgeyBFUl9JTkNPUlJFQ1RfUFJPR1JBTU1FUl9BU1NFUlRJT04sCi0gICAgICAiXHU3QTBCXHU1RThGXHU1NDU4XHU2NUFEXHU4QTAwXHU5NTE5XHU4QkVGISAtIHswfSJ9LAotCi0gIHsgRVJfQk9PTEVBTl9BUkdfTk9fTE9OR0VSX09QVElPTkFMLAotICAgICAgIlx1NTcyOCAxOTk5MDcwOSBYUGF0aCBcdTgzNDlcdTdBM0ZcdTRFMkQsIGJvb2xlYW4oLi4uKSBcdTUzQzJcdTY1NzBcdTRFMERcdTUxOERcdTY2MkZcdTUzRUZcdTkwMDlcdTc2ODRcdTMwMDIifSwKLQotICB7IEVSX0ZPVU5EX0NPTU1BX0JVVF9OT19QUkVDRURJTkdfQVJHLAotICAgICAgIlx1NURGMlx1NjI3RVx1NTIzMCAnLCcsIFx1NEY0Nlx1NTI0RFx1OTc2Mlx1NkNBMVx1NjcwOVx1NTNDMlx1NjU3MCEifSwKLQotICB7IEVSX0ZPVU5EX0NPTU1BX0JVVF9OT19GT0xMT1dJTkdfQVJHLAotICAgICAgIlx1NURGMlx1NjI3RVx1NTIzMCAnLCcsIFx1NEY0Nlx1NTQwRVx1OTc2Mlx1NkNBMVx1NjcwOVx1NTNDMlx1NjU3MCEifSwKLQotICB7IEVSX1BSRURJQ0FURV9JTExFR0FMX1NZTlRBWCwKLSAgICAgICInLi5bcHJlZGljYXRlXScgXHU2MjE2ICcuW3ByZWRpY2F0ZV0nIFx1NjYyRlx1OTc1RVx1NkNENVx1OEJFRFx1NkNENVx1MzAwMlx1OEJGN1x1NjUzOVx1NzUyOCAnc2VsZjo6bm9kZSgpW3ByZWRpY2F0ZV0nXHUzMDAyIn0sCi0KLSAgeyBFUl9JTExFR0FMX0FYSVNfTkFNRSwKLSAgICAgIlx1OTc1RVx1NkNENVx1OEY3NFx1NTQwRFx1NzlGMDogezB9In0sCi0KLSAgeyBFUl9VTktOT1dOX05PREVUWVBFLAotICAgICAiXHU2NzJBXHU3N0U1XHU4MjgyXHU3MEI5XHU3QzdCXHU1NzhCOiB7MH0ifSwKLQotICB7IEVSX1BBVFRFUk5fTElURVJBTF9ORUVEU19CRV9RVU9URUQsCi0gICAgICAiXHU5NzAwXHU4OTgxXHU3NTI4XHU1RjE1XHU1M0Y3XHU1QzA2XHU2QTIxXHU1RjBGXHU2NTg3XHU1QjU3ICh7MH0pIFx1NUYxNVx1OEQ3N1x1Njc2NSEifSwKLQotICB7IEVSX0NPVUxETk9UX0JFX0ZPUk1BVFRFRF9UT19OVU1CRVIsCi0gICAgICAiXHU2NUUwXHU2Q0Q1XHU1QzA2ezB9XHU3Njg0XHU2ODNDXHU1RjBGXHU4QkJFXHU3RjZFXHU0RTNBXHU2NTcwXHU1QjU3ISJ9LAotCi0gIHsgRVJfQ09VTEROT1RfQ1JFQVRFX1hNTFBST0NFU1NPUkxJQUlTT04sCi0gICAgICAiXHU2NUUwXHU2Q0Q1XHU1MjFCXHU1RUZBIFhNTCBUcmFuc2Zvcm1lckZhY3RvcnkgTGlhaXNvbjogezB9In0sCi0KLSAgeyBFUl9ESUROT1RfRklORF9YUEFUSF9TRUxFQ1RfRVhQLAotICAgICAgIlx1OTUxOVx1OEJFRiEgXHU2MjdFXHU0RTBEXHU1MjMwIHhwYXRoIFx1OTAwOVx1NjJFOVx1ODg2OFx1OEZCRVx1NUYwRiAoLXNlbGVjdClcdTMwMDIifSwKLQotICB7IEVSX0NPVUxETk9UX0ZJTkRfRU5ET1BfQUZURVJfT1BMT0NBVElPTlBBVEgsCi0gICAgICAiXHU5NTE5XHU4QkVGISBcdTU3MjggT1BfTE9DQVRJT05QQVRIIFx1NTQwRVx1NjI3RVx1NEUwRFx1NTIzMCBFTkRPUCJ9LAotCi0gIHsgRVJfRVJST1JfT0NDVVJFRCwKLSAgICAgIlx1NTFGQVx1NzNCMFx1OTUxOVx1OEJFRiEifSwKLQotICB7IEVSX0lMTEVHQUxfVkFSSUFCTEVfUkVGRVJFTkNFLAotICAgICAgIlx1NEUzQVx1NTNEOFx1OTFDRlx1N0VEOVx1NUI5QVx1NzY4NCBWYXJpYWJsZVJlZmVyZW5jZSBcdTgxMzFcdTc5QkJcdTRFMEFcdTRFMEJcdTY1ODdcdTYyMTZcdTZDQTFcdTY3MDlcdTVCOUFcdTRFNDkhIFx1NTQwRFx1NzlGMCA9IHswfSJ9LAotCi0gIHsgRVJfQVhFU19OT1RfQUxMT1dFRCwKLSAgICAgICJcdTUzMzlcdTkxNERcdTZBMjFcdTVGMEZcdTRFMkRcdTRFQzVcdTUxNDFcdThCQjhcdTRGN0ZcdTc1MjggY2hpbGQ6OiBcdTU0OEMgYXR0cmlidXRlOjogXHU4Rjc0XHUzMDAyXHU4RkREXHU4OUM0XHU4Rjc0ID0gezB9In0sCi0KLSAgeyBFUl9LRVlfSEFTX1RPT19NQU5ZX0FSR1MsCi0gICAgICAia2V5KCkgXHU3Njg0XHU1M0MyXHU2NTcwXHU2NTcwXHU3NkVFXHU0RTBEXHU2QjYzXHU3ODZFXHUzMDAyIn0sCi0KLSAgeyBFUl9DT1VOVF9UQUtFU18xX0FSRywKLSAgICAgICJjb3VudCBcdTUxRkRcdTY1NzBcdTVFOTRcdTkxQzdcdTc1MjhcdTRFMDBcdTRFMkFcdTUzQzJcdTY1NzAhIn0sCi0KLSAgeyBFUl9DT1VMRE5PVF9GSU5EX0ZVTkNUSU9OLAotICAgICAiXHU2MjdFXHU0RTBEXHU1MjMwXHU1MUZEXHU2NTcwOiB7MH0ifSwKLQotICB7IEVSX1VOU1VQUE9SVEVEX0VOQ09ESU5HLAotICAgICAiXHU0RTBEXHU2NTJGXHU2MzAxXHU3RjE2XHU3ODAxOiB7MH0ifSwKLQotICB7IEVSX1BST0JMRU1fSU5fRFRNX05FWFRTSUJMSU5HLAotICAgICAgImdldE5leHRTaWJsaW5nIFx1NjVGNiBEVE0gXHU0RTJEXHU1MUZBXHU3M0IwXHU5NUVFXHU5ODk4Li4uIFx1NkI2M1x1NTcyOFx1NUMxRFx1OEJENVx1NjA2Mlx1NTkwRCJ9LAotCi0gIHsgRVJfQ0FOTk9UX1dSSVRFX1RPX0VNUFRZTk9ERUxJU1RJTVBMLAotICAgICAgIlx1N0EwQlx1NUU4Rlx1NTQ1OFx1OTUxOVx1OEJFRjogXHU2NUUwXHU2Q0Q1XHU1MTk5XHU1MTY1IEVtcHR5Tm9kZUxpc3RcdTMwMDIifSwKLQotICB7IEVSX1NFVERPTUZBQ1RPUllfTk9UX1NVUFBPUlRFRCwKLSAgICAgICJYUGF0aENvbnRleHQgXHU0RTBEXHU2NTJGXHU2MzAxIHNldERPTUZhY3RvcnkhIn0sCi0KLSAgeyBFUl9QUkVGSVhfTVVTVF9SRVNPTFZFLAotICAgICAgIlx1NTI0RFx1N0YwMFx1NUZDNVx1OTg3Qlx1ODlFM1x1Njc5MFx1NEUzQVx1NTQwRFx1NzlGMFx1N0E3QVx1OTVGNDogezB9In0sCi0KLSAgeyBFUl9QQVJTRV9OT1RfU1VQUE9SVEVELAotICAgICAgIlhQYXRoQ29udGV4dCBcdTRFMkRcdTRFMERcdTY1MkZcdTYzMDEgcGFyc2UgKElucHV0U291cmNlIHNvdXJjZSkhIFx1NjVFMFx1NkNENVx1NjI1M1x1NUYwMHswfSJ9LAotCi0gIHsgRVJfU0FYX0FQSV9OT1RfSEFORExFRCwKLSAgICAgICJEVE0gXHU2NzJBXHU1OTA0XHU3NDA2IFNBWCBBUEkgY2hhcmFjdGVycyhjaGFyIGNoW10uLi4hIn0sCi0KLSAgeyBFUl9JR05PUkFCTEVfV0hJVEVTUEFDRV9OT1RfSEFORExFRCwKLSAgICAgICJEVE0gXHU2NzJBXHU1OTA0XHU3NDA2IGlnbm9yYWJsZVdoaXRlc3BhY2UoY2hhciBjaFtdLi4uISJ9LAotCi0gIHsgRVJfRFRNX0NBTk5PVF9IQU5ETEVfTk9ERVMsCi0gICAgICAiRFRNTGlhaXNvbiBcdTY1RTBcdTZDRDVcdTU5MDRcdTc0MDZ7MH1cdTdDN0JcdTU3OEJcdTc2ODRcdTgyODJcdTcwQjkifSwKLQotICB7IEVSX1hFUkNFU19DQU5OT1RfSEFORExFX05PREVTLAotICAgICAgIkRPTTJIZWxwZXIgXHU2NUUwXHU2Q0Q1XHU1OTA0XHU3NDA2ezB9XHU3QzdCXHU1NzhCXHU3Njg0XHU4MjgyXHU3MEI5In0sCi0KLSAgeyBFUl9YRVJDRVNfUEFSU0VfRVJST1JfREVUQUlMUywKLSAgICAgICJET00ySGVscGVyLnBhcnNlIFx1OTUxOVx1OEJFRjogU3lzdGVtSUQgLSBcdTdCMkMgezB9IFx1ODg0QyAtIHsxfSJ9LAotCi0gIHsgRVJfWEVSQ0VTX1BBUlNFX0VSUk9SLAotICAgICAiRE9NMkhlbHBlci5wYXJzZSBcdTk1MTlcdThCRUYifSwKLQotICB7IEVSX0lOVkFMSURfVVRGMTZfU1VSUk9HQVRFLAotICAgICAgIlx1NjhDMFx1NkQ0Qlx1NTIzMFx1NjVFMFx1NjU0OFx1NzY4NCBVVEYtMTYgXHU0RUUzXHU3NDA2OiB7MH0/In0sCi0KLSAgeyBFUl9PSUVSUk9SLAotICAgICAiSU8gXHU5NTE5XHU4QkVGIn0sCi0KLSAgeyBFUl9DQU5OT1RfQ1JFQVRFX1VSTCwKLSAgICAgIlx1NjVFMFx1NkNENVx1NEUzQXswfVx1NTIxQlx1NUVGQSB1cmwifSwKLQotICB7IEVSX1hQQVRIX1JFQURPQkpFQ1QsCi0gICAgICJcdTU3MjggWFBhdGgucmVhZE9iamVjdCBcdTRFMkQ6IHswfSJ9LAotCi0gIHsgRVJfRlVOQ1RJT05fVE9LRU5fTk9UX0ZPVU5ELAotICAgICAgIlx1NjI3RVx1NEUwRFx1NTIzMFx1NTFGRFx1NjU3MFx1NjgwN1x1OEJCMFx1MzAwMiJ9LAotCi0gIHsgRVJfQ0FOTk9UX0RFQUxfWFBBVEhfVFlQRSwKLSAgICAgICAiXHU2NUUwXHU2Q0Q1XHU1OTA0XHU3NDA2IFhQYXRoIFx1N0M3Qlx1NTc4QjogezB9In0sCi0KLSAgeyBFUl9OT0RFU0VUX05PVF9NVVRBQkxFLAotICAgICAgICJcdTZCNjQgTm9kZVNldCBcdTRFMERcdTUzRUZcdTUzRDgifSwKLQotICB7IEVSX05PREVTRVREVE1fTk9UX01VVEFCTEUsCi0gICAgICAgIlx1NkI2NCBOb2RlU2V0RFRNIFx1NEUwRFx1NTNFRlx1NTNEOCJ9LAotCi0gIHsgRVJfVkFSX05PVF9SRVNPTFZBQkxFLAotICAgICAgICAiXHU2NUUwXHU2Q0Q1XHU4OUUzXHU2NzkwXHU1M0Q4XHU5MUNGOiB7MH0ifSwKLQotICB7IEVSX05VTExfRVJST1JfSEFORExFUiwKLSAgICAgICAgIlx1N0E3QVx1OTUxOVx1OEJFRlx1NTkwNFx1NzQwNlx1N0EwQlx1NUU4RiJ9LAotCi0gIHsgRVJfUFJPR19BU1NFUlRfVU5LTk9XTl9PUENPREUsCi0gICAgICAgIlx1N0EwQlx1NUU4Rlx1NTQ1OFx1NjVBRFx1OEEwMDogXHU2NENEXHU0RjVDXHU3ODAxXHU2NzJBXHU3N0U1OiB7MH0ifSwKLQotICB7IEVSX1pFUk9fT1JfT05FLAotICAgICAgICIwIFx1NjIxNiAxIn0sCi0KLSAgeyBFUl9SVEZfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiwKLSAgICAgICAiWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIgXHU0RTBEXHU2NTJGXHU2MzAxIHJ0ZigpIn0sCi0KLSAgeyBFUl9SVEZfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiwKLSAgICAgICAiWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIgXHU0RTBEXHU2NTJGXHU2MzAxIGFzTm9kZUl0ZXJhdG9yKCkifSwKLQotICAgICAgICAvKiogIGRldGFjaCgpIG5vdCBzdXBwb3J0ZWQgYnkgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIgICAqLwotICAgeyBFUl9ERVRBQ0hfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiwKLSAgICAgICAgICAgICAgICAiWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIgXHU0RTBEXHU2NTJGXHU2MzAxIGRldGFjaCgpIn0sCi0KLSAgICAgICAgLyoqICBudW0oKSBub3Qgc3VwcG9ydGVkIGJ5IFhSVHJlZUZyYWdTZWxlY3RXcmFwcGVyICAgKi8KLSAgIHsgRVJfTlVNX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIsCi0gICAgICAgICAgICAgICAgIlhSVHJlZUZyYWdTZWxlY3RXcmFwcGVyIFx1NEUwRFx1NjUyRlx1NjMwMSBudW0oKSJ9LAotCi0gICAgICAgIC8qKiAgeHN0cigpIG5vdCBzdXBwb3J0ZWQgYnkgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIgICAqLwotICAgeyBFUl9YU1RSX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIsCi0gICAgICAgICAgICAgICAgIlhSVHJlZUZyYWdTZWxlY3RXcmFwcGVyIFx1NEUwRFx1NjUyRlx1NjMwMSB4c3RyKCkifSwKLQotICAgICAgICAvKiogIHN0cigpIG5vdCBzdXBwb3J0ZWQgYnkgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIgICAqLwotICAgeyBFUl9TVFJfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiwKLSAgICAgICAgICAgICAgICAiWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIgXHU0RTBEXHU2NTJGXHU2MzAxIHN0cigpIn0sCi0KLSAgeyBFUl9GU0JfTk9UX1NVUFBPUlRFRF9YU1RSSU5HRk9SQ0hBUlMsCi0gICAgICAgIlhTdHJpbmdGb3JDaGFycyBcdTRFMERcdTY1MkZcdTYzMDEgZnNiKCkifSwKLQotICB7IEVSX0NPVUxEX05PVF9GSU5EX1ZBUiwKLSAgICAgICJcdTYyN0VcdTRFMERcdTUyMzBcdTU0MERcdTRFM0F7MH1cdTc2ODRcdTUzRDhcdTkxQ0YifSwKLQotICB7IEVSX1hTVFJJTkdGT1JDSEFSU19DQU5OT1RfVEFLRV9TVFJJTkcsCi0gICAgICAiWFN0cmluZ0ZvckNoYXJzIFx1NjVFMFx1NkNENVx1OTFDN1x1NzUyOFx1NUI1N1x1N0IyNlx1NEUzMlx1NEY1Q1x1NEUzQVx1NTNDMlx1NjU3MCJ9LAotCi0gIHsgRVJfRkFTVFNUUklOR0JVRkZFUl9DQU5OT1RfQkVfTlVMTCwKLSAgICAgICJGYXN0U3RyaW5nQnVmZmVyIFx1NTNDMlx1NjU3MFx1NEUwRFx1ODBGRFx1NEUzQVx1N0E3QVx1NTAzQyJ9LAotCi0gIHsgRVJfVFdPX09SX1RIUkVFLAotICAgICAgICIyIFx1NjIxNiAzIn0sCi0KLSAgeyBFUl9WQVJJQUJMRV9BQ0NFU1NFRF9CRUZPUkVfQklORCwKLSAgICAgICAiXHU1REYyXHU1NzI4XHU3RUQxXHU1QjlBXHU1M0Q4XHU5MUNGXHU1MjREXHU4QkJGXHU5NUVFXHU2QjY0XHU1M0Q4XHU5MUNGISJ9LAotCi0gIHsgRVJfRlNCX0NBTk5PVF9UQUtFX1NUUklORywKLSAgICAgICAiWFN0cmluZ0ZvckZTQiBcdTY1RTBcdTZDRDVcdTkxQzdcdTc1MjhcdTVCNTdcdTdCMjZcdTRFMzJcdTRGNUNcdTRFM0FcdTUzQzJcdTY1NzAhIn0sCi0KLSAgeyBFUl9TRVRUSU5HX1dBTEtFUl9ST09UX1RPX05VTEwsCi0gICAgICAgIlxuICEhISEgXHU5NTE5XHU4QkVGISBcdTVDMDYgd2Fsa2VyIFx1NzY4NFx1NjgzOVx1OEJCRVx1N0Y2RVx1NEUzQVx1N0E3QVx1NTAzQyEhISJ9LAotCi0gIHsgRVJfTk9ERVNFVERUTV9DQU5OT1RfSVRFUkFURSwKLSAgICAgICAiXHU2QjY0IE5vZGVTZXREVE0gXHU2NUUwXHU2Q0Q1XHU4RkVEXHU0RUUzXHU1MjMwXHU0RTBBXHU0RTAwXHU0RTJBXHU4MjgyXHU3MEI5ISJ9LAotCi0gIHsgRVJfTk9ERVNFVF9DQU5OT1RfSVRFUkFURSwKLSAgICAgICAiXHU2QjY0IE5vZGVTZXQgXHU2NUUwXHU2Q0Q1XHU4RkVEXHU0RUUzXHU1MjMwXHU0RTBBXHU0RTAwXHU0RTJBXHU4MjgyXHU3MEI5ISJ9LAotCi0gIHsgRVJfTk9ERVNFVERUTV9DQU5OT1RfSU5ERVgsCi0gICAgICAgIlx1NkI2NCBOb2RlU2V0RFRNIFx1NjVFMFx1NkNENVx1NjI2N1x1ODg0QyBpbmRleGluZyBcdTYyMTYgY291bnRpbmcgXHU1MUZEXHU2NTcwISJ9LAotCi0gIHsgRVJfTk9ERVNFVF9DQU5OT1RfSU5ERVgsCi0gICAgICAgIlx1NkI2NCBOb2RlU2V0IFx1NjVFMFx1NkNENVx1NjI2N1x1ODg0QyBpbmRleGluZyBcdTYyMTYgY291bnRpbmcgXHU1MUZEXHU2NTcwISJ9LAotCi0gIHsgRVJfQ0FOTk9UX0NBTExfU0VUU0hPVUxEQ0FDSEVOT0RFLAotICAgICAgICJcdTY1RTBcdTZDRDVcdTU3MjhcdThDMDNcdTc1MjggbmV4dE5vZGUgXHU0RTRCXHU1NDBFXHU4QzAzXHU3NTI4IHNldFNob3VsZENhY2hlTm9kZXMhIn0sCi0KLSAgeyBFUl9PTkxZX0FMTE9XUywKLSAgICAgICAiezB9XHU0RUM1XHU1MTQxXHU4QkI4XHU0RjdGXHU3NTI4ezF9XHU1M0MyXHU2NTcwIn0sCi0KLSAgeyBFUl9VTktOT1dOX1NURVAsCi0gICAgICAgImdldE5leHRTdGVwUG9zIFx1NEUyRFx1NzY4NFx1N0EwQlx1NUU4Rlx1NTQ1OFx1NjVBRFx1OEEwMDogc3RlcFR5cGUgXHU2NzJBXHU3N0U1OiB7MH0ifSwKLQotICAvL05vdGUgdG8gdHJhbnNsYXRvcnM6ICBBIHJlbGF0aXZlIGxvY2F0aW9uIHBhdGggaXMgYSBmb3JtIG9mIFhQYXRoIGV4cHJlc3Npb24uCi0gIC8vIFRoZSBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHN1Y2ggYW4gZXhwcmVzc2lvbiB3YXMgZXhwZWN0ZWQgZm9sbG93aW5nIHRoZQotICAvLyBjaGFyYWN0ZXJzICcvJyBvciAnLy8nLCBidXQgd2FzIG5vdCBmb3VuZC4KLSAgeyBFUl9FWFBFQ1RFRF9SRUxfTE9DX1BBVEgsCi0gICAgICAiXHU3NkY4XHU1QkY5XHU0RjREXHU3RjZFXHU4REVGXHU1Rjg0XHU1RTk0XHU0RjREXHU0RThFICcvJyBcdTYyMTYgJy8vJyBcdTY4MDdcdThCQjBcdTRFNEJcdTU0MEVcdTMwMDIifSwKLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQSBsb2NhdGlvbiBwYXRoIGlzIGEgZm9ybSBvZiBYUGF0aCBleHByZXNzaW9uLgotICAvLyBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCBzeW50YWN0aWNhbGx5IHN1Y2ggYW4gZXhwcmVzc2lvbiB3YXMgZXhwZWN0ZWQsYnV0Ci0gIC8vIHRoZSBjaGFyYWN0ZXJzIHNwZWNpZmllZCBieSB0aGUgc3Vic3RpdHV0aW9uIHRleHQgd2VyZSBlbmNvdW50ZXJlZCBpbnN0ZWFkLgotICB7IEVSX0VYUEVDVEVEX0xPQ19QQVRILAotICAgICAgICJcdTk3MDBcdTg5ODFcdTRGNERcdTdGNkVcdThERUZcdTVGODQsIFx1NEY0Nlx1OTA0N1x1NTIzMFx1NEVFNVx1NEUwQlx1NjgwN1x1OEJCMDogezB9In0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIEEgbG9jYXRpb24gcGF0aCBpcyBhIGZvcm0gb2YgWFBhdGggZXhwcmVzc2lvbi4KLSAgLy8gVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgc3ludGFjdGljYWxseSBzdWNoIGEgc3ViZXhwcmVzc2lvbiB3YXMgZXhwZWN0ZWQsCi0gIC8vIGJ1dCBubyBtb3JlIGNoYXJhY3RlcnMgd2VyZSBmb3VuZCBpbiB0aGUgZXhwcmVzc2lvbi4KLSAgeyBFUl9FWFBFQ1RFRF9MT0NfUEFUSF9BVF9FTkRfRVhQUiwKLSAgICAgICAiXHU5NzAwXHU4OTgxXHU0RjREXHU3RjZFXHU4REVGXHU1Rjg0LCBcdTRGNDZcdTYyN0VcdTUyMzAgWFBhdGggXHU4ODY4XHU4RkJFXHU1RjBGXHU3Njg0XHU2NzJCXHU1QzNFXHUzMDAyIn0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIEEgbG9jYXRpb24gc3RlcCBpcyBwYXJ0IG9mIGFuIFhQYXRoIGV4cHJlc3Npb24uCi0gIC8vIFRoZSBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHN5bnRhY3RpY2FsbHkgc3VjaCBhbiBleHByZXNzaW9uIHdhcyBleHBlY3RlZAotICAvLyBmb2xsb3dpbmcgdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXJzLgotICB7IEVSX0VYUEVDVEVEX0xPQ19TVEVQLAotICAgICAgICJcdTRGNERcdTdGNkVcdTZCNjVcdTlBQTRcdTVFOTRcdTRGNERcdTRFOEUgJy8nIFx1NjIxNiAnLy8nIFx1NjgwN1x1OEJCMFx1NEU0Qlx1NTQwRVx1MzAwMiJ9LAotCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBIG5vZGUgdGVzdCBpcyBwYXJ0IG9mIGFuIFhQYXRoIGV4cHJlc3Npb24gdGhhdCBpcwotICAvLyB1c2VkIHRvIHRlc3QgZm9yIHBhcnRpY3VsYXIga2luZHMgb2Ygbm9kZXMuICBJbiB0aGlzIGNhc2UsIGEgbm9kZSB0ZXN0IHRoYXQKLSAgLy8gY29uc2lzdHMgb2YgYW4gTkNOYW1lIGZvbGxvd2VkIGJ5IGEgY29sb24gYW5kIGFuIGFzdGVyaXNrIG9yIHRoYXQgY29uc2lzdHMKLSAgLy8gb2YgYSBRTmFtZSB3YXMgZXhwZWN0ZWQsIGJ1dCB3YXMgbm90IGZvdW5kLgotICB7IEVSX0VYUEVDVEVEX05PREVfVEVTVCwKLSAgICAgICAiXHU5NzAwXHU4OTgxXHU0RTBFIE5DTmFtZToqIFx1NjIxNiBRTmFtZSBcdTUzMzlcdTkxNERcdTc2ODRcdTgyODJcdTcwQjlcdTZENEJcdThCRDVcdTMwMDIifSwKLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQSBzdGVwIHBhdHRlcm4gaXMgcGFydCBvZiBhbiBYUGF0aCBleHByZXNzaW9uLgotICAvLyBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCBzeW50YWN0aWNhbGx5IHN1Y2ggYW4gZXhwcmVzc2lvbiB3YXMgZXhwZWN0ZWQsCi0gIC8vIGJ1dCB0aGUgc3BlY2lmaWVkIGNoYXJhY3RlciB3YXMgZm91bmQgaW4gdGhlIGV4cHJlc3Npb24gaW5zdGVhZC4KLSAgeyBFUl9FWFBFQ1RFRF9TVEVQX1BBVFRFUk4sCi0gICAgICAgIlx1OTcwMFx1ODk4MVx1NkI2NVx1OUFBNFx1NkEyMVx1NUYwRiwgXHU0RjQ2XHU5MDQ3XHU1MjMwICcvJ1x1MzAwMiJ9LAotCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6IEEgcmVsYXRpdmUgcGF0aCBwYXR0ZXJuIGlzIHBhcnQgb2YgYW4gWFBhdGggZXhwcmVzc2lvbi4KLSAgLy8gVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgc3ludGFjdGljYWxseSBzdWNoIGFuIGV4cHJlc3Npb24gd2FzIGV4cGVjdGVkLAotICAvLyBidXQgd2FzIG5vdCBmb3VuZC4KLSAgeyBFUl9FWFBFQ1RFRF9SRUxfUEFUSF9QQVRURVJOLAotICAgICAgICJcdTk3MDBcdTg5ODFcdTc2RjhcdTVCRjlcdThERUZcdTVGODRcdTZBMjFcdTVGMEZcdTMwMDIifSwKLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIGEgZGF0YSB0eXBlLiAgVGhlCi0gIC8vIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgYSB2YWx1ZSBvZiBhIHBhcnRpY3VsYXIgdHlwZSBjb3VsZCBub3QgYmUgY29udmVydGVkCi0gIC8vIHRvIGEgdmFsdWUgb2YgdHlwZSBib29sZWFuLgotICB7IEVSX0NBTlRfQ09OVkVSVF9UT19CT09MRUFOLAotICAgICAgICJYUGF0aCBcdTg4NjhcdThGQkVcdTVGMEYgJyd7MH0nJyBcdTc2ODQgWFBhdGhSZXN1bHQgXHU1MTc3XHU2NzA5ezF9XHU3QzdCXHU1NzhCXHU3Njg0IFhQYXRoUmVzdWx0VHlwZSwgXHU2NUUwXHU2Q0Q1XHU1QzA2XHU2QjY0IFhQYXRoUmVzdWx0VHlwZSBcdThGNkNcdTYzNjJcdTRFM0EgYm9vbGVhblx1MzAwMiJ9LAotCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6IERvIG5vdCB0cmFuc2xhdGUgQU5ZX1VOT1JERVJFRF9OT0RFX1RZUEUgYW5kCi0gIC8vIEZJUlNUX09SREVSRURfTk9ERV9UWVBFLgotICB7IEVSX0NBTlRfQ09OVkVSVF9UT19TSU5HTEVOT0RFLAotICAgICAgICJYUGF0aCBcdTg4NjhcdThGQkVcdTVGMEYgJyd7MH0nJyBcdTc2ODQgWFBhdGhSZXN1bHQgXHU1MTc3XHU2NzA5ezF9XHU3QzdCXHU1NzhCXHU3Njg0IFhQYXRoUmVzdWx0VHlwZSwgXHU2NUUwXHU2Q0Q1XHU1QzA2XHU2QjY0IFhQYXRoUmVzdWx0VHlwZSBcdThGNkNcdTYzNjJcdTRFM0FcdTUzNTVcdTRFMDBcdTgyODJcdTcwQjlcdTMwMDJcdTY1QjlcdTZDRDUgZ2V0U2luZ2xlTm9kZVZhbHVlIFx1NEVDNVx1OTAwMlx1NzUyOFx1NEU4RVx1N0M3Qlx1NTc4QiBBTllfVU5PUkRFUkVEX05PREVfVFlQRSBcdTU0OEMgRklSU1RfT1JERVJFRF9OT0RFX1RZUEVcdTMwMDIifSwKLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiBEbyBub3QgdHJhbnNsYXRlIFVOT1JERVJFRF9OT0RFX1NOQVBTSE9UX1RZUEUgYW5kCi0gIC8vIE9SREVSRURfTk9ERV9TTkFQU0hPVF9UWVBFLgotICB7IEVSX0NBTlRfR0VUX1NOQVBTSE9UX0xFTkdUSCwKLSAgICAgICAiXHU2NUUwXHU2Q0Q1XHU1NzI4IFhQYXRoIFx1ODg2OFx1OEZCRVx1NUYwRiAnJ3swfScnIFx1NzY4NCBYUGF0aFJlc3VsdCBcdTRFMkRcdThDMDNcdTc1MjhcdTY1QjlcdTZDRDUgZ2V0U25hcHNob3RMZW5ndGgsIFx1OEZEOVx1NjYyRlx1NTZFMFx1NEUzQVx1NTE3NiBYUGF0aFJlc3VsdFR5cGUgXHU0RTNBezF9XHUzMDAyXHU2QjY0XHU2NUI5XHU2Q0Q1XHU0RUM1XHU5MDAyXHU3NTI4XHU0RThFXHU3QzdCXHU1NzhCIFVOT1JERVJFRF9OT0RFX1NOQVBTSE9UX1RZUEUgXHU1NDhDIE9SREVSRURfTk9ERV9TTkFQU0hPVF9UWVBFXHUzMDAyIn0sCi0KLSAgeyBFUl9OT05fSVRFUkFUT1JfVFlQRSwKLSAgICAgICAiXHU2NUUwXHU2Q0Q1XHU1NzI4IFhQYXRoIFx1ODg2OFx1OEZCRVx1NUYwRiAnJ3swfScnIFx1NzY4NCBYUGF0aFJlc3VsdCBcdTRFMkRcdThDMDNcdTc1MjhcdTY1QjlcdTZDRDUgaXRlcmF0ZU5leHQsIFx1OEZEOVx1NjYyRlx1NTZFMFx1NEUzQVx1NTE3NiBYUGF0aFJlc3VsdFR5cGUgXHU0RTNBezF9XHUzMDAyXHU2QjY0XHU2NUI5XHU2Q0Q1XHU0RUM1XHU5MDAyXHU3NTI4XHU0RThFXHU3QzdCXHU1NzhCIFVOT1JERVJFRF9OT0RFX0lURVJBVE9SX1RZUEUgXHU1NDhDIE9SREVSRURfTk9ERV9JVEVSQVRPUl9UWVBFXHUzMDAyIn0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogVGhpcyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoZSBkb2N1bWVudCBiZWluZyBvcGVyYXRlZAotICAvLyB1cG9uIGNoYW5nZWQsIHNvIHRoZSBpdGVyYXRvciBvYmplY3QgdGhhdCB3YXMgYmVpbmcgdXNlZCB0byB0cmF2ZXJzZSB0aGUKLSAgLy8gZG9jdW1lbnQgaGFzIG5vdyBiZWNvbWUgaW52YWxpZC4KLSAgeyBFUl9ET0NfTVVUQVRFRCwKLSAgICAgICAiXHU3NTMxXHU0RThFXHU1REYyXHU4RkQ0XHU1NkRFXHU3RUQzXHU2NzlDLCBcdTY1ODdcdTY4NjNcdTUzRDFcdTc1MUZcdTUzRDhcdTY2RjRcdTMwMDJcdThGRURcdTRFRTNcdTU2NjhcdTY1RTBcdTY1NDhcdTMwMDIifSwKLQotICB7IEVSX0lOVkFMSURfWFBBVEhfVFlQRSwKLSAgICAgICAiWFBhdGggXHU3QzdCXHU1NzhCXHU1M0MyXHU2NTcwXHU2NUUwXHU2NTQ4OiB7MH0ifSwKLQotICB7IEVSX0VNUFRZX1hQQVRIX1JFU1VMVCwKLSAgICAgICAiXHU3QTdBIFhQYXRoIFx1N0VEM1x1Njc5Q1x1NUJGOVx1OEM2MSJ9LAotCi0gIHsgRVJfSU5DT01QQVRJQkxFX1RZUEVTLAotICAgICAgICJYUGF0aCBcdTg4NjhcdThGQkVcdTVGMEYgJyd7MH0nJyBcdTc2ODQgWFBhdGhSZXN1bHQgXHU1MTc3XHU2NzA5ezF9XHU3QzdCXHU1NzhCXHU3Njg0IFhQYXRoUmVzdWx0VHlwZSwgXHU2NUUwXHU2Q0Q1XHU1QzA2XHU2QjY0IFhQYXRoUmVzdWx0VHlwZSBcdTVGM0FcdTUyMzZcdTRFM0F7Mn1cdTdDN0JcdTU3OEJcdTc2ODRcdTYzMDdcdTVCOUEgWFBhdGhSZXN1bHRUeXBlXHUzMDAyIn0sCi0KLSAgeyBFUl9OVUxMX1JFU09MVkVSLAotICAgICAgICJcdTY1RTBcdTZDRDVcdTRGN0ZcdTc1MjhcdTdBN0FcdTUyNERcdTdGMDBcdTg5RTNcdTY3OTBcdTU2NjhcdTg5RTNcdTY3OTBcdTUyNERcdTdGMDBcdTMwMDIifSwKLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgVGhlIHN1YnN0aXR1dGlvbiB0ZXh0IGlzIHRoZSBuYW1lIG9mIGEgZGF0YSB0eXBlLiAgVGhlCi0gIC8vIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgYSB2YWx1ZSBvZiBhIHBhcnRpY3VsYXIgdHlwZSBjb3VsZCBub3QgYmUgY29udmVydGVkCi0gIC8vIHRvIGEgdmFsdWUgb2YgdHlwZSBzdHJpbmcuCi0gIHsgRVJfQ0FOVF9DT05WRVJUX1RPX1NUUklORywKLSAgICAgICAiWFBhdGggXHU4ODY4XHU4RkJFXHU1RjBGICcnezB9JycgXHU3Njg0IFhQYXRoUmVzdWx0IFx1NTE3N1x1NjcwOXsxfVx1N0M3Qlx1NTc4Qlx1NzY4NCBYUGF0aFJlc3VsdFR5cGUsIFx1NjVFMFx1NkNENVx1NUMwNlx1NkI2NCBYUGF0aFJlc3VsdFR5cGUgXHU4RjZDXHU2MzYyXHU0RTNBXHU1QjU3XHU3QjI2XHU0RTMyXHUzMDAyIn0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogRG8gbm90IHRyYW5zbGF0ZSBzbmFwc2hvdEl0ZW0sCi0gIC8vIFVOT1JERVJFRF9OT0RFX1NOQVBTSE9UX1RZUEUgYW5kIE9SREVSRURfTk9ERV9TTkFQU0hPVF9UWVBFLgotICB7IEVSX05PTl9TTkFQU0hPVF9UWVBFLAotICAgICAgICJcdTY1RTBcdTZDRDVcdTU3MjggWFBhdGggXHU4ODY4XHU4RkJFXHU1RjBGICcnezB9JycgXHU3Njg0IFhQYXRoUmVzdWx0IFx1NEUyRFx1OEMwM1x1NzUyOFx1NjVCOVx1NkNENSBzbmFwc2hvdEl0ZW0sIFx1OEZEOVx1NjYyRlx1NTZFMFx1NEUzQVx1NTE3NiBYUGF0aFJlc3VsdFR5cGUgXHU0RTNBezF9XHUzMDAyXHU2QjY0XHU2NUI5XHU2Q0Q1XHU0RUM1XHU5MDAyXHU3NTI4XHU0RThFXHU3QzdCXHU1NzhCIFVOT1JERVJFRF9OT0RFX1NOQVBTSE9UX1RZUEUgXHU1NDhDIE9SREVSRURfTk9ERV9TTkFQU0hPVF9UWVBFXHUzMDAyIn0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFhQYXRoRXZhbHVhdG9yIGlzIGEgSmF2YSBpbnRlcmZhY2UgbmFtZS4gIEFuCi0gIC8vIFhQYXRoRXZhbHVhdG9yIGlzIGNyZWF0ZWQgd2l0aCByZXNwZWN0IHRvIGEgcGFydGljdWxhciBYTUwgZG9jdW1lbnQsIGFuZCBpbgotICAvLyB0aGlzIGNhc2UgdGhlIGV4cHJlc3Npb24gcmVwcmVzZW50ZWQgYnkgdGhpcyBvYmplY3Qgd2FzIGJlaW5nIGV2YWx1YXRlZCB3aXRoCi0gIC8vIHJlc3BlY3QgdG8gYSBjb250ZXh0IG5vZGUgZnJvbSBhIGRpZmZlcmVudCBkb2N1bWVudC4KLSAgeyBFUl9XUk9OR19ET0NVTUVOVCwKLSAgICAgICAiXHU0RTBBXHU0RTBCXHU2NTg3XHU4MjgyXHU3MEI5XHU0RTBEXHU1QzVFXHU0RThFXHU3RUQxXHU1QjlBXHU1MjMwXHU2QjY0IFhQYXRoRXZhbHVhdG9yIFx1NzY4NFx1NjU4N1x1Njg2M1x1MzAwMiJ9LAotCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgWFBhdGggZXhwcmVzc2lvbiBjYW5ub3QgYmUgZXZhbHVhdGVkIHdpdGggcmVzcGVjdAotICAvLyB0byB0aGlzIHR5cGUgb2Ygbm9kZS4KLSAgeyBFUl9XUk9OR19OT0RFVFlQRSwKLSAgICAgICAiXHU0RTBEXHU2NTJGXHU2MzAxXHU0RTBBXHU0RTBCXHU2NTg3XHU4MjgyXHU3MEI5XHU3QzdCXHU1NzhCXHUzMDAyIn0sCi0KLSAgeyBFUl9YUEFUSF9FUlJPUiwKLSAgICAgICAiWFBhdGggXHU0RTJEXHU1QjU4XHU1NzI4XHU2NzJBXHU3N0U1XHU5NTE5XHU4QkVGXHUzMDAyIn0sCi0KLSAgeyBFUl9DQU5UX0NPTlZFUlRfWFBBVEhSRVNVTFRUWVBFX1RPX05VTUJFUiwKLSAgICAgICAgIlhQYXRoIFx1ODg2OFx1OEZCRVx1NUYwRiAnJ3swfScnIFx1NzY4NCBYUGF0aFJlc3VsdCBcdTUxNzdcdTY3MDl7MX1cdTdDN0JcdTU3OEJcdTc2ODQgWFBhdGhSZXN1bHRUeXBlLCBcdTY1RTBcdTZDRDVcdTVDMDZcdTZCNjQgWFBhdGhSZXN1bHRUeXBlIFx1OEY2Q1x1NjM2Mlx1NEUzQVx1NjU3MFx1NUI1NyJ9LAotCi0gIC8vQkVHSU46ICBEZWZpbml0aW9ucyBvZiBlcnJvciBrZXlzIHVzZWQgIGluIGV4Y2VwdGlvbiBtZXNzYWdlcyBvZiAgSkFYUCAxLjMgWFBhdGggQVBJIGltcGxlbWVudGF0aW9uCi0KLSAgLyoqIEZpZWxkIEVSX0VYVEVOU0lPTl9GVU5DVElPTl9DQU5OT1RfQkVfSU5WT0tFRCAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX0VYVEVOU0lPTl9GVU5DVElPTl9DQU5OT1RfQkVfSU5WT0tFRCwKLSAgICAgICAiXHU1RjUzIFhNTENvbnN0YW50cy5GRUFUVVJFX1NFQ1VSRV9QUk9DRVNTSU5HIFx1NTI5Rlx1ODBGRFx1OEJCRVx1N0Y2RVx1NEUzQVx1MjAxQ1x1NzcxRlx1MjAxRFx1NjVGNiwgXHU0RTBEXHU4MEZEXHU4QzAzXHU3NTI4XHU2MjY5XHU1QzU1XHU1MUZEXHU2NTcwICcnezB9JydcdTMwMDIifSwKLQotICAvKiogRmllbGQgRVJfUkVTT0xWRV9WQVJJQUJMRV9SRVRVUk5TX05VTEwgICAgICAgICAgICAgICAgICAgICAgICovCi0KLSAgeyBFUl9SRVNPTFZFX1ZBUklBQkxFX1JFVFVSTlNfTlVMTCwKLSAgICAgICAiXHU1M0Q4XHU5MUNGezB9XHU3Njg0IHJlc29sdmVWYXJpYWJsZSBcdThGRDRcdTU2REVcdTdBN0FcdTUwM0MifSwKLQotICAvKiogRmllbGQgRVJfVU5TVVBQT1JURURfUkVUVVJOX1RZUEUgICAgICAgICAgICAgICAgICAgICAgICovCi0KLSAgeyBFUl9VTlNVUFBPUlRFRF9SRVRVUk5fVFlQRSwKLSAgICAgICAiXHU0RTBEXHU2NTJGXHU2MzAxXHU4QkU1XHU4RkQ0XHU1NkRFXHU3QzdCXHU1NzhCOiB7MH0ifSwKLQotICAvKiogRmllbGQgRVJfU09VUkNFX1JFVFVSTl9UWVBFX0NBTk5PVF9CRV9OVUxMICAgICAgICAgICAgICAgICAgICAgICAqLwotCi0gIHsgRVJfU09VUkNFX1JFVFVSTl9UWVBFX0NBTk5PVF9CRV9OVUxMLAotICAgICAgICJcdTZFOTBcdTU0OEMvXHU2MjE2XHU4RkQ0XHU1NkRFXHU3QzdCXHU1NzhCXHU0RTBEXHU4MEZEXHU0RTNBXHU3QTdBXHU1MDNDIn0sCi0KLSAgLyoqIEZpZWxkIEVSX1NPVVJDRV9SRVRVUk5fVFlQRV9DQU5OT1RfQkVfTlVMTCAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX1NPVVJDRV9SRVRVUk5fVFlQRV9DQU5OT1RfQkVfTlVMTCwKLSAgICAgICAiXHU2RTkwXHU1NDhDL1x1NjIxNlx1OEZENFx1NTZERVx1N0M3Qlx1NTc4Qlx1NEUwRFx1ODBGRFx1NEUzQVx1N0E3QVx1NTAzQyJ9LAotCi0gIC8qKiBGaWVsZCBFUl9BUkdfQ0FOTk9UX0JFX05VTEwgICAgICAgICAgICAgICAgICAgICAgICovCi0KLSAgeyBFUl9BUkdfQ0FOTk9UX0JFX05VTEwsCi0gICAgICAgInswfVx1NTNDMlx1NjU3MFx1NEUwRFx1ODBGRFx1NEUzQVx1N0E3QVx1NTAzQyJ9LAotCi0gIC8qKiBGaWVsZCBFUl9PQkpFQ1RfTU9ERUxfTlVMTCAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX09CSkVDVF9NT0RFTF9OVUxMLAotICAgICAgICJcdTRFMERcdTgwRkRcdTU3Mjggb2JqZWN0TW9kZWwgPT0gXHU3QTdBXHU1MDNDXHU3Njg0XHU2MEM1XHU1MUI1XHU0RTBCXHU4QzAzXHU3NTI4IHswfSNpc09iamVjdE1vZGVsU3VwcG9ydGVkKFN0cmluZyBvYmplY3RNb2RlbCkifSwKLQotICAvKiogRmllbGQgRVJfT0JKRUNUX01PREVMX0VNUFRZICAgICAgICAgICAgICAgICAgICAgICAqLwotCi0gIHsgRVJfT0JKRUNUX01PREVMX0VNUFRZLAotICAgICAgICJcdTRFMERcdTgwRkRcdTU3Mjggb2JqZWN0TW9kZWwgPT0gXCJcIiBcdTc2ODRcdTYwQzVcdTUxQjVcdTRFMEJcdThDMDNcdTc1MjggezB9I2lzT2JqZWN0TW9kZWxTdXBwb3J0ZWQoU3RyaW5nIG9iamVjdE1vZGVsKSJ9LAotCi0gIC8qKiBGaWVsZCBFUl9PQkpFQ1RfTU9ERUxfRU1QVFkgICAgICAgICAgICAgICAgICAgICAgICovCi0KLSAgeyBFUl9GRUFUVVJFX05BTUVfTlVMTCwKLSAgICAgICAiXHU1QzFEXHU4QkQ1XHU4QkJFXHU3RjZFXHU1MTc3XHU2NzA5XHU3QTdBXHU1NDBEXHU3OUYwXHU3Njg0XHU1MjlGXHU4MEZEOiB7MH0jc2V0RmVhdHVyZShudWxsLCB7MX0pIn0sCi0KLSAgLyoqIEZpZWxkIEVSX0ZFQVRVUkVfVU5LTk9XTiAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX0ZFQVRVUkVfVU5LTk9XTiwKLSAgICAgICAiXHU1QzFEXHU4QkQ1XHU4QkJFXHU3RjZFXHU2NzJBXHU3N0U1XHU1MjlGXHU4MEZEIFwiezB9XCI6ezF9I3NldEZlYXR1cmUoezB9LHsyfSkifSwKLQotICAvKiogRmllbGQgRVJfR0VUVElOR19OVUxMX0ZFQVRVUkUgICAgICAgICAgICAgICAgICAgICAgICovCi0KLSAgeyBFUl9HRVRUSU5HX05VTExfRkVBVFVSRSwKLSAgICAgICAiXHU1QzFEXHU4QkQ1XHU4M0I3XHU1M0Q2XHU1MTc3XHU2NzA5XHU3QTdBXHU1NDBEXHU3OUYwXHU3Njg0XHU1MjlGXHU4MEZEOiB7MH0jZ2V0RmVhdHVyZShudWxsKSJ9LAotCi0gIC8qKiBGaWVsZCBFUl9HRVRUSU5HX05VTExfRkVBVFVSRSAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX0dFVFRJTkdfVU5LTk9XTl9GRUFUVVJFLAotICAgICAgICJcdTVDMURcdThCRDVcdTgzQjdcdTUzRDZcdTY3MkFcdTc3RTVcdTUyOUZcdTgwRkQgXCJ7MH1cIjp7MX0jZ2V0RmVhdHVyZSh7MH0pIn0sCi0KLSAge0VSX1NFQ1VSRVBST0NFU1NJTkdfRkVBVFVSRSwKLSAgICAgICAgIkZFQVRVUkVfU0VDVVJFX1BST0NFU1NJTkc6IFx1NUI1OFx1NTcyOCBTZWN1cml0eSBNYW5hZ2VyIFx1NjVGNiwgXHU2NUUwXHU2Q0Q1XHU1QzA2XHU2QjY0XHU1MjlGXHU4MEZEXHU4QkJFXHU3RjZFXHU0RTNBXHUyMDFDXHU1MDQ3XHUyMDFEOiB7MX0jc2V0RmVhdHVyZSh7MH0sezJ9KSJ9LAotCi0gIC8qKiBGaWVsZCBFUl9OVUxMX1hQQVRIX0ZVTkNUSU9OX1JFU09MVkVSICAgICAgICAgICAgICAgICAgICAgICAqLwotCi0gIHsgRVJfTlVMTF9YUEFUSF9GVU5DVElPTl9SRVNPTFZFUiwKLSAgICAgICAiXHU1QzFEXHU4QkQ1XHU4QkJFXHU3RjZFXHU3QTdBIFhQYXRoRnVuY3Rpb25SZXNvbHZlcjp7MH0jc2V0WFBhdGhGdW5jdGlvblJlc29sdmVyKG51bGwpIn0sCi0KLSAgLyoqIEZpZWxkIEVSX05VTExfWFBBVEhfVkFSSUFCTEVfUkVTT0xWRVIgICAgICAgICAgICAgICAgICAgICAgICovCi0KLSAgeyBFUl9OVUxMX1hQQVRIX1ZBUklBQkxFX1JFU09MVkVSLAotICAgICAgICJcdTVDMURcdThCRDVcdThCQkVcdTdGNkVcdTdBN0EgWFBhdGhWYXJpYWJsZVJlc29sdmVyOnswfSNzZXRYUGF0aFZhcmlhYmxlUmVzb2x2ZXIobnVsbCkifSwKLQotICAvL0VORDogIERlZmluaXRpb25zIG9mIGVycm9yIGtleXMgdXNlZCAgaW4gZXhjZXB0aW9uIG1lc3NhZ2VzIG9mICBKQVhQIDEuMyBYUGF0aCBBUEkgaW1wbGVtZW50YXRpb24KLQotICAvLyBXYXJuaW5ncy4uLgotCi0gIHsgV0dfTE9DQUxFX05BTUVfTk9UX0hBTkRMRUQsCi0gICAgICAiXHU1QzFBXHU2NzJBXHU1OTA0XHU3NDA2IGZvcm1hdC1udW1iZXIgXHU1MUZEXHU2NTcwXHU0RTJEXHU3Njg0XHU1MzNBXHU1N0RGXHU4QkJFXHU3RjZFXHU1NDBEXHU3OUYwISJ9LAotCi0gIHsgV0dfUFJPUEVSVFlfTk9UX1NVUFBPUlRFRCwKLSAgICAgICJcdTRFMERcdTY1MkZcdTYzMDEgWFNMIFx1NUM1RVx1NjAyNzogezB9In0sCi0KLSAgeyBXR19ET05UX0RPX0FOWVRISU5HX1dJVEhfTlMsCi0gICAgICAiXHU3NkVFXHU1MjREXHU0RTBEXHU4OTgxXHU0RjdGXHU3NTI4XHU1QzVFXHU2MDI3ezF9XHU0RTJEXHU3Njg0XHU1NDBEXHU3OUYwXHU3QTdBXHU5NUY0ezB9XHU2MjY3XHU4ODRDXHU0RUZCXHU0RjU1XHU2NENEXHU0RjVDIn0sCi0KLSAgeyBXR19TRUNVUklUWV9FWENFUFRJT04sCi0gICAgICAiXHU1QzFEXHU4QkQ1XHU4QkJGXHU5NUVFIFhTTCBcdTdDRkJcdTdFREZcdTVDNUVcdTYwMjdcdTY1RjZcdTUxRkFcdTczQjAgU2VjdXJpdHlFeGNlcHRpb246IHswfSJ9LAotCi0gIHsgV0dfUVVPX05PX0xPTkdFUl9ERUZJTkVELAotICAgICAgIlx1NjVFN1x1OEJFRFx1NkNENTogWFBhdGggXHU0RTJEXHU0RTBEXHU1MThEXHU1QjlBXHU0RTQ5IHF1byguLi4pXHUzMDAyIn0sCi0KLSAgeyBXR19ORUVEX0RFUklWRURfT0JKRUNUX1RPX0lNUExFTUVOVF9OT0RFVEVTVCwKLSAgICAgICJYUGF0aCBcdTk3MDBcdTg5ODFcdTZEM0VcdTc1MUZcdTVCRjlcdThDNjFcdTYyNERcdTgwRkRcdTVCOUVcdTczQjAgbm9kZVRlc3QhIn0sCi0KLSAgeyBXR19GVU5DVElPTl9UT0tFTl9OT1RfRk9VTkQsCi0gICAgICAiXHU2MjdFXHU0RTBEXHU1MjMwXHU1MUZEXHU2NTcwXHU2ODA3XHU4QkIwXHUzMDAyIn0sCi0KLSAgeyBXR19DT1VMRE5PVF9GSU5EX0ZVTkNUSU9OLAotICAgICAgIlx1NjI3RVx1NEUwRFx1NTIzMFx1NTFGRFx1NjU3MDogezB9In0sCi0KLSAgeyBXR19DQU5OT1RfTUFLRV9VUkxfRlJPTSwKLSAgICAgICJcdTY1RTBcdTZDRDVcdTY4MzlcdTYzNkV7MH1cdTc1MUZcdTYyMTAgVVJMIn0sCi0KLSAgeyBXR19FWFBBTkRfRU5USVRJRVNfTk9UX1NVUFBPUlRFRCwKLSAgICAgICJEVE0gXHU4OUUzXHU2NzkwXHU1NjY4XHU0RTBEXHU2NTJGXHU2MzAxIC1FIFx1OTAwOVx1OTg3OSJ9LAotCi0gIHsgV0dfSUxMRUdBTF9WQVJJQUJMRV9SRUZFUkVOQ0UsCi0gICAgICAiXHU0RTNBXHU1M0Q4XHU5MUNGXHU3RUQ5XHU1QjlBXHU3Njg0IFZhcmlhYmxlUmVmZXJlbmNlIFx1ODEzMVx1NzlCQlx1NEUwQVx1NEUwQlx1NjU4N1x1NjIxNlx1NkNBMVx1NjcwOVx1NUI5QVx1NEU0OSEgXHU1NDBEXHU3OUYwID0gezB9In0sCi0KLSAgeyBXR19VTlNVUFBPUlRFRF9FTkNPRElORywKLSAgICAgIlx1NEUwRFx1NjUyRlx1NjMwMVx1N0YxNlx1NzgwMTogezB9In0sCi0KLQotCi0gIC8vIE90aGVyIG1pc2NlbGxhbmVvdXMgdGV4dCB1c2VkIGluc2lkZSB0aGUgY29kZS4uLgotICB7ICJ1aV9sYW5ndWFnZSIsICJlbiJ9LAotICB7ICJoZWxwX2xhbmd1YWdlIiwgImVuIn0sCi0gIHsgImxhbmd1YWdlIiwgImVuIn0sCi0gIHsgIkJBRF9DT0RFIiwgImNyZWF0ZU1lc3NhZ2UgXHU3Njg0XHU1M0MyXHU2NTcwXHU4RDg1XHU1MUZBXHU4MzAzXHU1NkY0In0sCi0gIHsgIkZPUk1BVF9GQUlMRUQiLCAiXHU4QzAzXHU3NTI4IG1lc3NhZ2VGb3JtYXQgXHU2NUY2XHU2MjlCXHU1MUZBXHU1RjAyXHU1RTM4XHU5NTE5XHU4QkVGIn0sCi0gIHsgInZlcnNpb24iLCAiPj4+Pj4+PiBYYWxhbiBcdTcyNDhcdTY3MkMgIn0sCi0gIHsgInZlcnNpb24yIiwgIjw8PDw8PDwifSwKLSAgeyAieWVzIiwgIlx1NjYyRiJ9LAotICB7ICJsaW5lIiwgIlx1ODg0Q1x1NTNGNyJ9LAotICB7ICJjb2x1bW4iLCAiXHU1MjE3XHU1M0Y3In0sCi0gIHsgInhzbGRvbmUiLCAiWFNMUHJvY2Vzc29yOiBcdTVCOENcdTYyMTAifSwKLSAgeyAieHBhdGhfb3B0aW9uIiwgInhwYXRoIFx1OTAwOVx1OTg3OTogIn0sCi0gIHsgIm9wdGlvbklOIiwgIiAgIFstaW4gaW5wdXRYTUxVUkxdIn0sCi0gIHsgIm9wdGlvblNlbGVjdCIsICIgICBbLXNlbGVjdCB4cGF0aCBleHByZXNzaW9uXSJ9LAotICB7ICJvcHRpb25NYXRjaCIsICIgICBbLW1hdGNoIG1hdGNoIHBhdHRlcm4gKGZvciBtYXRjaCBkaWFnbm9zdGljcyldIn0sCi0gIHsgIm9wdGlvbkFueUV4cHIiLCAiXHU2MjE2XHU4MDA1XHU0RUM1IHhwYXRoIFx1ODg2OFx1OEZCRVx1NUYwRlx1NjI2N1x1ODg0Q1x1OEJDQVx1NjVBRFx1OEY2Q1x1NTBBOCJ9LAotICB7ICJub1BhcnNlcm1zZzEiLCAiWFNMIFx1OEZEQlx1N0EwQlx1NjcyQVx1NjIxMFx1NTI5Rlx1MzAwMiJ9LAotICB7ICJub1BhcnNlcm1zZzIiLCAiKiogXHU2MjdFXHU0RTBEXHU1MjMwXHU4OUUzXHU2NzkwXHU1NjY4ICoqIn0sCi0gIHsgIm5vUGFyc2VybXNnMyIsICJcdThCRjdcdTY4QzBcdTY3RTVcdTYwQThcdTc2ODRcdTdDN0JcdThERUZcdTVGODRcdTMwMDIifSwKLSAgeyAibm9QYXJzZXJtc2c0IiwgIlx1NTk4Mlx1Njc5Q1x1NkNBMVx1NjcwOSBJQk0gXHU2M0QwXHU0RjlCXHU3Njg0IFhNTCBQYXJzZXIgZm9yIEphdmEsIFx1NTIxOVx1NTNFRlx1NEVFNVx1NEVDRSJ9LAotICB7ICJub1BhcnNlcm1zZzUiLCAiSUJNIEFscGhhV29ya3MgXHU4RkRCXHU4ODRDXHU0RTBCXHU4RjdELCBcdTdGNTFcdTU3NDBcdTRFM0E6IGh0dHA6Ly93d3cuYWxwaGF3b3Jrcy5pYm0uY29tL2Zvcm11bGEveG1sIn0sCi0gIHsgImd0b25lIiwgIj4xIiB9LAotICB7ICJ6ZXJvIiwgIjAiIH0sCi0gIHsgIm9uZSIsICIxIiB9LAotICB7ICJ0d28iICwgIjIiIH0sCi0gIHsgInRocmVlIiwgIjMiIH0KLQotICB9OwotCi0gIC8qKgotICAgKiBHZXQgdGhlIGFzc29jaWF0aW9uIGxpc3QuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGFzc29jaWF0aW9uIGxpc3QuCi0gICAqLwotICBwdWJsaWMgT2JqZWN0W11bXSBnZXRDb250ZW50cygpCi0gIHsKLSAgICAgIHJldHVybiBfY29udGVudHM7Ci0gIH0KLQotCi0gIC8vID09PT09PT09PT09PT09PT09IElORlJBU1RSVUNUVVJFID09PT09PT09PT09PT09PT09PT09PT0KLQotICAvKiogRmllbGQgQkFEX0NPREUgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQkFEX0NPREUgPSAiQkFEX0NPREUiOwotCi0gIC8qKiBGaWVsZCBGT1JNQVRfRkFJTEVEICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEZPUk1BVF9GQUlMRUQgPSAiRk9STUFUX0ZBSUxFRCI7Ci0KLSAgLyoqIEZpZWxkIEVSUk9SX1JFU09VUkNFUyAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJPUl9SRVNPVVJDRVMgPQotICAgICJjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucmVzLlhQQVRIRXJyb3JSZXNvdXJjZXMiOwotCi0gIC8qKiBGaWVsZCBFUlJPUl9TVFJJTkcgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJST1JfU1RSSU5HID0gIiNlcnJvciI7Ci0KLSAgLyoqIEZpZWxkIEVSUk9SX0hFQURFUiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJPUl9IRUFERVIgPSAiRXJyb3I6ICI7Ci0KLSAgLyoqIEZpZWxkIFdBUk5JTkdfSEVBREVSICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdBUk5JTkdfSEVBREVSID0gIldhcm5pbmc6ICI7Ci0KLSAgLyoqIEZpZWxkIFhTTF9IRUFERVIgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgWFNMX0hFQURFUiA9ICJYU0wgIjsKLQotICAvKiogRmllbGQgWE1MX0hFQURFUiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxfSEVBREVSID0gIlhNTCAiOwotCi0gIC8qKiBGaWVsZCBRVUVSWV9IRUFERVIgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgUVVFUllfSEVBREVSID0gIlBBVFRFUk4gIjsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9yZXMvWFBBVEhFcnJvclJlc291cmNlc196aF9UVy5qYXZhIGIvc3JjL2NvbS9zdW4vb3JnL2FwYWNoZS94cGF0aC9pbnRlcm5hbC9yZXMvWFBBVEhFcnJvclJlc291cmNlc196aF9UVy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiMWU0YThhLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvcmVzL1hQQVRIRXJyb3JSZXNvdXJjZXNfemhfVFcuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDkzNiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotLyoKLSAqIENvcHlyaWdodCAxOTk5LTIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi1wYWNrYWdlIGNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5yZXM7Ci0KLWltcG9ydCBqYXZhLnV0aWwuTGlzdFJlc291cmNlQnVuZGxlOwotCi0vKioKLSAqIFNldCB1cCBlcnJvciBtZXNzYWdlcy4KLSAqIFdlIGJ1aWxkIGEgdHdvIGRpbWVuc2lvbmFsIGFycmF5IG9mIG1lc3NhZ2Uga2V5cyBhbmQKLSAqIG1lc3NhZ2Ugc3RyaW5ncy4gSW4gb3JkZXIgdG8gYWRkIGEgbmV3IG1lc3NhZ2UgaGVyZSwKLSAqIHlvdSBuZWVkIHRvIGZpcnN0IGFkZCBhIFN0YXRpYyBzdHJpbmcgY29uc3RhbnQgZm9yIHRoZQotICogS2V5IGFuZCB1cGRhdGUgdGhlIGNvbnRlbnRzIGFycmF5IHdpdGggS2V5LCBWYWx1ZSBwYWlyCi0gICogQWxzbyB5b3UgbmVlZCB0byAgdXBkYXRlIHRoZSBjb3VudCBvZiBtZXNzYWdlcyhNQVhfQ09ERSlvcgotICogdGhlIGNvdW50IG9mIHdhcm5pbmdzKE1BWF9XQVJOSU5HKSBbIEluZm9ybWF0aW9uIHB1cnBvc2Ugb25seV0KLSAqIEB4c2wudXNhZ2UgYWR2YW5jZWQKLSAqLwotcHVibGljIGNsYXNzIFhQQVRIRXJyb3JSZXNvdXJjZXNfemhfVFcgZXh0ZW5kcyBMaXN0UmVzb3VyY2VCdW5kbGUKLXsKLQotLyoKLSAqIEdlbmVyYWwgbm90ZXMgdG8gdHJhbnNsYXRvcnM6Ci0gKgotICogVGhpcyBmaWxlIGNvbnRhaW5zIGVycm9yIGFuZCB3YXJuaW5nIG1lc3NhZ2VzIHJlbGF0ZWQgdG8gWFBhdGggRXJyb3IKLSAqIEhhbmRsaW5nLgotICoKLSAqICAxKSBYYWxhbiAob3IgbW9yZSBwcm9wZXJseSwgWGFsYW4taW50ZXJwcmV0aXZlKSBhbmQgWFNMVEMgYXJlIG5hbWVzIG9mCi0gKiAgICAgY29tcG9uZW50cy4KLSAqICAgICBYU0xUIGlzIGFuIGFjcm9ueW0gZm9yICJYTUwgU3R5bGVzaGVldCBMYW5ndWFnZTogVHJhbnNmb3JtYXRpb25zIi4KLSAqICAgICBYU0xUQyBpcyBhbiBhY3JvbnltIGZvciBYU0xUIENvbXBpbGVyLgotICoKLSAqICAyKSBBIHN0eWxlc2hlZXQgaXMgYSBkZXNjcmlwdGlvbiBvZiBob3cgdG8gdHJhbnNmb3JtIGFuIGlucHV0IFhNTCBkb2N1bWVudAotICogICAgIGludG8gYSByZXN1bHRhbnQgWE1MIGRvY3VtZW50IChvciBIVE1MIGRvY3VtZW50IG9yIHRleHQpLiAgVGhlCi0gKiAgICAgc3R5bGVzaGVldCBpdHNlbGYgaXMgZGVzY3JpYmVkIGluIHRoZSBmb3JtIG9mIGFuIFhNTCBkb2N1bWVudC4KLSAqCi0gKiAgMykgQSB0ZW1wbGF0ZSBpcyBhIGNvbXBvbmVudCBvZiBhIHN0eWxlc2hlZXQgdGhhdCBpcyB1c2VkIHRvIG1hdGNoIGEKLSAqICAgICBwYXJ0aWN1bGFyIHBvcnRpb24gb2YgYW4gaW5wdXQgZG9jdW1lbnQgYW5kIHNwZWNpZmllcyB0aGUgZm9ybSBvZiB0aGUKLSAqICAgICBjb3JyZXNwb25kaW5nIHBvcnRpb24gb2YgdGhlIG91dHB1dCBkb2N1bWVudC4KLSAqCi0gKiAgNCkgQW4gZWxlbWVudCBpcyBhIG1hcmstdXAgdGFnIGluIGFuIFhNTCBkb2N1bWVudDsgYW4gYXR0cmlidXRlIGlzIGEKLSAqICAgICBtb2RpZmllciBvbiB0aGUgdGFnLiAgRm9yIGV4YW1wbGUsIGluIDxlbGVtIGF0dHI9J3ZhbCcgYXR0cjI9J3ZhbDInPgotICogICAgICJlbGVtIiBpcyBhbiBlbGVtZW50IG5hbWUsICJhdHRyIiBhbmQgImF0dHIyIiBhcmUgYXR0cmlidXRlIG5hbWVzIHdpdGgKLSAqICAgICB0aGUgdmFsdWVzICJ2YWwiIGFuZCAidmFsMiIsIHJlc3BlY3RpdmVseS4KLSAqCi0gKiAgNSkgQSBuYW1lc3BhY2UgZGVjbGFyYXRpb24gaXMgYSBzcGVjaWFsIGF0dHJpYnV0ZSB0aGF0IGlzIHVzZWQgdG8gYXNzb2NpYXRlCi0gKiAgICAgYSBwcmVmaXggd2l0aCBhIFVSSSAodGhlIG5hbWVzcGFjZSkuICBUaGUgbWVhbmluZ3Mgb2YgZWxlbWVudCBuYW1lcyBhbmQKLSAqICAgICBhdHRyaWJ1dGUgbmFtZXMgdGhhdCB1c2UgdGhhdCBwcmVmaXggYXJlIGRlZmluZWQgd2l0aCByZXNwZWN0IHRvIHRoYXQKLSAqICAgICBuYW1lc3BhY2UuCi0gKgotICogIDYpICJUcmFuc2xldCIgaXMgYW4gaW52ZW50ZWQgdGVybSB0aGF0IGRlc2NyaWJlcyB0aGUgY2xhc3MgZmlsZSB0aGF0Ci0gKiAgICAgcmVzdWx0cyBmcm9tIGNvbXBpbGluZyBhbiBYTUwgc3R5bGVzaGVldCBpbnRvIGEgSmF2YSBjbGFzcy4KLSAqCi0gKiAgNykgWFBhdGggaXMgYSBzcGVjaWZpY2F0aW9uIHRoYXQgZGVzY3JpYmVzIGEgbm90YXRpb24gZm9yIGlkZW50aWZ5aW5nCi0gKiAgICAgbm9kZXMgaW4gYSB0cmVlLXN0cnVjdHVyZWQgcmVwcmVzZW50YXRpb24gb2YgYW4gWE1MIGRvY3VtZW50LiAgQW4KLSAqICAgICBpbnN0YW5jZSBvZiB0aGF0IG5vdGF0aW9uIGlzIHJlZmVycmVkIHRvIGFzIGFuIFhQYXRoIGV4cHJlc3Npb24uCi0gKgotICogIDgpIFRoZSBjb250ZXh0IG5vZGUgaXMgdGhlIG5vZGUgaW4gdGhlIGRvY3VtZW50IHdpdGggcmVzcGVjdCB0byB3aGljaCBhbgotICogICAgIFhQYXRoIGV4cHJlc3Npb24gaXMgYmVpbmcgZXZhbHVhdGVkLgotICoKLSAqICA5KSBBbiBpdGVyYXRvciBpcyBhbiBvYmplY3QgdGhhdCB0cmF2ZXJzZXMgbm9kZXMgaW4gdGhlIHRyZWUsIG9uZSBhdCBhIHRpbWUuCi0gKgotICogIDEwKSBOQ05hbWUgaXMgYW4gWE1MIHRlcm0gdXNlZCB0byBkZXNjcmliZSBhIG5hbWUgdGhhdCBkb2VzIG5vdCBjb250YWluIGEKLSAqICAgICBjb2xvbiAoYSAibm8tY29sb24gbmFtZSIpLgotICoKLSAqICAxMSkgUU5hbWUgaXMgYW4gWE1MIHRlcm0gbWVhbmluZyAicXVhbGlmaWVkIG5hbWUiLgotICovCi0KLSAgLyoKLSAgICogc3RhdGljIHZhcmlhYmxlcwotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJST1IwMDAwID0gIkVSUk9SMDAwMCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NVUlJFTlRfTk9UX0FMTE9XRURfSU5fTUFUQ0ggPQotICAgICAgICAgIkVSX0NVUlJFTlRfTk9UX0FMTE9XRURfSU5fTUFUQ0giOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DVVJSRU5UX1RBS0VTX05PX0FSR1MgPQotICAgICAgICAgIkVSX0NVUlJFTlRfVEFLRVNfTk9fQVJHUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0RPQ1VNRU5UX1JFUExBQ0VEID0gIkVSX0RPQ1VNRU5UX1JFUExBQ0VEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09OVEVYVF9IQVNfTk9fT1dORVJET0MgPQotICAgICAgICAgIkVSX0NPTlRFWFRfSEFTX05PX09XTkVSRE9DIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTE9DQUxOQU1FX0hBU19UT09fTUFOWV9BUkdTID0KLSAgICAgICAgICJFUl9MT0NBTE5BTUVfSEFTX1RPT19NQU5ZX0FSR1MiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OQU1FU1BBQ0VVUklfSEFTX1RPT19NQU5ZX0FSR1MgPQotICAgICAgICAgIkVSX05BTUVTUEFDRVVSSV9IQVNfVE9PX01BTllfQVJHUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05PUk1BTElaRVNQQUNFX0hBU19UT09fTUFOWV9BUkdTID0KLSAgICAgICAgICJFUl9OT1JNQUxJWkVTUEFDRV9IQVNfVE9PX01BTllfQVJHUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05VTUJFUl9IQVNfVE9PX01BTllfQVJHUyA9Ci0gICAgICAgICAiRVJfTlVNQkVSX0hBU19UT09fTUFOWV9BUkdTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTkFNRV9IQVNfVE9PX01BTllfQVJHUyA9Ci0gICAgICAgICAiRVJfTkFNRV9IQVNfVE9PX01BTllfQVJHUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NUUklOR19IQVNfVE9PX01BTllfQVJHUyA9Ci0gICAgICAgICAiRVJfU1RSSU5HX0hBU19UT09fTUFOWV9BUkdTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU1RSSU5HTEVOR1RIX0hBU19UT09fTUFOWV9BUkdTID0KLSAgICAgICAgICJFUl9TVFJJTkdMRU5HVEhfSEFTX1RPT19NQU5ZX0FSR1MiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9UUkFOU0xBVEVfVEFLRVNfM19BUkdTID0KLSAgICAgICAgICJFUl9UUkFOU0xBVEVfVEFLRVNfM19BUkdTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5QQVJTRURFTlRJVFlVUklfVEFLRVNfMV9BUkcgPQotICAgICAgICAgIkVSX1VOUEFSU0VERU5USVRZVVJJX1RBS0VTXzFfQVJHIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTkFNRVNQQUNFQVhJU19OT1RfSU1QTEVNRU5URUQgPQotICAgICAgICAgIkVSX05BTUVTUEFDRUFYSVNfTk9UX0lNUExFTUVOVEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5LTk9XTl9BWElTID0gIkVSX1VOS05PV05fQVhJUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1VOS05PV05fTUFUQ0hfT1BFUkFUSU9OID0KLSAgICAgICAgICJFUl9VTktOT1dOX01BVENIX09QRVJBVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOQ09SUkVDVF9BUkdfTEVOR1RIID0iRVJfSU5DT1JSRUNUX0FSR19MRU5HVEgiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX0NPTlZFUlRfVE9fTlVNQkVSID0KLSAgICAgICAgICJFUl9DQU5UX0NPTlZFUlRfVE9fTlVNQkVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9DT05WRVJUX1hQQVRIUkVTVUxUVFlQRV9UT19OVU1CRVIgPQotICAgICAgICAgICAiRVJfQ0FOVF9DT05WRVJUX1hQQVRIUkVTVUxUVFlQRV9UT19OVU1CRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX0NPTlZFUlRfVE9fTk9ERUxJU1QgPQotICAgICAgICAgIkVSX0NBTlRfQ09OVkVSVF9UT19OT0RFTElTVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfQ09OVkVSVF9UT19NVVRBQkxFTk9ERUxJU1QgPQotICAgICAgICAgIkVSX0NBTlRfQ09OVkVSVF9UT19NVVRBQkxFTk9ERUxJU1QiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX0NPTlZFUlRfVE9fVFlQRSA9IkVSX0NBTlRfQ09OVkVSVF9UT19UWVBFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhQRUNURURfTUFUQ0hfUEFUVEVSTiA9Ci0gICAgICAgICAiRVJfRVhQRUNURURfTUFUQ0hfUEFUVEVSTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxETk9UX0dFVF9WQVJfTkFNRUQgPQotICAgICAgICAgIkVSX0NPVUxETk9UX0dFVF9WQVJfTkFNRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9VTktOT1dOX09QQ09ERSA9ICJFUl9VTktOT1dOX09QQ09ERSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYVFJBX0lMTEVHQUxfVE9LRU5TID0iRVJfRVhUUkFfSUxMRUdBTF9UT0tFTlMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FWFBFQ1RFRF9ET1VCTEVfUVVPVEUgPQotICAgICAgICAgIkVSX0VYUEVDVEVEX0RPVUJMRV9RVU9URSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYUEVDVEVEX1NJTkdMRV9RVU9URSA9Ci0gICAgICAgICAiRVJfRVhQRUNURURfU0lOR0xFX1FVT1RFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRU1QVFlfRVhQUkVTU0lPTiA9ICJFUl9FTVBUWV9FWFBSRVNTSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhQRUNURURfQlVUX0ZPVU5EID0gIkVSX0VYUEVDVEVEX0JVVF9GT1VORCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOQ09SUkVDVF9QUk9HUkFNTUVSX0FTU0VSVElPTiA9Ci0gICAgICAgICAiRVJfSU5DT1JSRUNUX1BST0dSQU1NRVJfQVNTRVJUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQk9PTEVBTl9BUkdfTk9fTE9OR0VSX09QVElPTkFMID0KLSAgICAgICAgICJFUl9CT09MRUFOX0FSR19OT19MT05HRVJfT1BUSU9OQUwiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GT1VORF9DT01NQV9CVVRfTk9fUFJFQ0VESU5HX0FSRyA9Ci0gICAgICAgICAiRVJfRk9VTkRfQ09NTUFfQlVUX05PX1BSRUNFRElOR19BUkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GT1VORF9DT01NQV9CVVRfTk9fRk9MTE9XSU5HX0FSRyA9Ci0gICAgICAgICAiRVJfRk9VTkRfQ09NTUFfQlVUX05PX0ZPTExPV0lOR19BUkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUkVESUNBVEVfSUxMRUdBTF9TWU5UQVggPQotICAgICAgICAgIkVSX1BSRURJQ0FURV9JTExFR0FMX1NZTlRBWCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lMTEVHQUxfQVhJU19OQU1FID0gIkVSX0lMTEVHQUxfQVhJU19OQU1FIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5LTk9XTl9OT0RFVFlQRSA9ICJFUl9VTktOT1dOX05PREVUWVBFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUEFUVEVSTl9MSVRFUkFMX05FRURTX0JFX1FVT1RFRCA9Ci0gICAgICAgICAiRVJfUEFUVEVSTl9MSVRFUkFMX05FRURTX0JFX1FVT1RFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NPVUxETk9UX0JFX0ZPUk1BVFRFRF9UT19OVU1CRVIgPQotICAgICAgICAgIkVSX0NPVUxETk9UX0JFX0ZPUk1BVFRFRF9UT19OVU1CRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRE5PVF9DUkVBVEVfWE1MUFJPQ0VTU09STElBSVNPTiA9Ci0gICAgICAgICAiRVJfQ09VTEROT1RfQ1JFQVRFX1hNTFBST0NFU1NPUkxJQUlTT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9ESUROT1RfRklORF9YUEFUSF9TRUxFQ1RfRVhQID0KLSAgICAgICAgICJFUl9ESUROT1RfRklORF9YUEFUSF9TRUxFQ1RfRVhQIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTEROT1RfRklORF9FTkRPUF9BRlRFUl9PUExPQ0FUSU9OUEFUSCA9Ci0gICAgICAgICAiRVJfQ09VTEROT1RfRklORF9FTkRPUF9BRlRFUl9PUExPQ0FUSU9OUEFUSCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VSUk9SX09DQ1VSRUQgPSAiRVJfRVJST1JfT0NDVVJFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lMTEVHQUxfVkFSSUFCTEVfUkVGRVJFTkNFID0KLSAgICAgICAgICJFUl9JTExFR0FMX1ZBUklBQkxFX1JFRkVSRU5DRSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FYRVNfTk9UX0FMTE9XRUQgPSAiRVJfQVhFU19OT1RfQUxMT1dFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0tFWV9IQVNfVE9PX01BTllfQVJHUyA9Ci0gICAgICAgICAiRVJfS0VZX0hBU19UT09fTUFOWV9BUkdTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ09VTlRfVEFLRVNfMV9BUkcgPSAiRVJfQ09VTlRfVEFLRVNfMV9BUkciOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRE5PVF9GSU5EX0ZVTkNUSU9OID0KLSAgICAgICAgICJFUl9DT1VMRE5PVF9GSU5EX0ZVTkNUSU9OIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5TVVBQT1JURURfRU5DT0RJTkcgPSJFUl9VTlNVUFBPUlRFRF9FTkNPRElORyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1BST0JMRU1fSU5fRFRNX05FWFRTSUJMSU5HID0KLSAgICAgICAgICJFUl9QUk9CTEVNX0lOX0RUTV9ORVhUU0lCTElORyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9XUklURV9UT19FTVBUWU5PREVMSVNUSU1QTCA9Ci0gICAgICAgICAiRVJfQ0FOTk9UX1dSSVRFX1RPX0VNUFRZTk9ERUxJU1RJTVBMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU0VURE9NRkFDVE9SWV9OT1RfU1VQUE9SVEVEID0KLSAgICAgICAgICJFUl9TRVRET01GQUNUT1JZX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QUkVGSVhfTVVTVF9SRVNPTFZFID0gIkVSX1BSRUZJWF9NVVNUX1JFU09MVkUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9QQVJTRV9OT1RfU1VQUE9SVEVEID0gIkVSX1BBUlNFX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TQVhfQVBJX05PVF9IQU5ETEVEID0gIkVSX1NBWF9BUElfTk9UX0hBTkRMRUQiOwotcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfSUdOT1JBQkxFX1dISVRFU1BBQ0VfTk9UX0hBTkRMRUQgPQotICAgICAgICAgIkVSX0lHTk9SQUJMRV9XSElURVNQQUNFX05PVF9IQU5ETEVEIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRFRNX0NBTk5PVF9IQU5ETEVfTk9ERVMgPQotICAgICAgICAgIkVSX0RUTV9DQU5OT1RfSEFORExFX05PREVTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWEVSQ0VTX0NBTk5PVF9IQU5ETEVfTk9ERVMgPQotICAgICAgICAgIkVSX1hFUkNFU19DQU5OT1RfSEFORExFX05PREVTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWEVSQ0VTX1BBUlNFX0VSUk9SX0RFVEFJTFMgPQotICAgICAgICAgIkVSX1hFUkNFU19QQVJTRV9FUlJPUl9ERVRBSUxTIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWEVSQ0VTX1BBUlNFX0VSUk9SID0gIkVSX1hFUkNFU19QQVJTRV9FUlJPUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOVkFMSURfVVRGMTZfU1VSUk9HQVRFID0KLSAgICAgICAgICJFUl9JTlZBTElEX1VURjE2X1NVUlJPR0FURSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX09JRVJST1IgPSAiRVJfT0lFUlJPUiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9DUkVBVEVfVVJMID0gIkVSX0NBTk5PVF9DUkVBVEVfVVJMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWFBBVEhfUkVBRE9CSkVDVCA9ICJFUl9YUEFUSF9SRUFET0JKRUNUIjsKLSBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9GVU5DVElPTl9UT0tFTl9OT1RfRk9VTkQgPQotICAgICAgICAgIkVSX0ZVTkNUSU9OX1RPS0VOX05PVF9GT1VORCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTk5PVF9ERUFMX1hQQVRIX1RZUEUgPQotICAgICAgICAgIkVSX0NBTk5PVF9ERUFMX1hQQVRIX1RZUEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT0RFU0VUX05PVF9NVVRBQkxFID0gIkVSX05PREVTRVRfTk9UX01VVEFCTEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT0RFU0VURFRNX05PVF9NVVRBQkxFID0KLSAgICAgICAgICJFUl9OT0RFU0VURFRNX05PVF9NVVRBQkxFIjsKLSAgIC8qKiAgVmFyaWFibGUgbm90IHJlc29sdmFibGU6ICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVkFSX05PVF9SRVNPTFZBQkxFID0gIkVSX1ZBUl9OT1RfUkVTT0xWQUJMRSI7Ci0gICAvKiogTnVsbCBlcnJvciBoYW5kbGVyICAqLwotIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX05VTExfRVJST1JfSEFORExFUiA9ICJFUl9OVUxMX0VSUk9SX0hBTkRMRVIiOwotICAgLyoqICBQcm9ncmFtbWVyJ3MgYXNzZXJ0aW9uOiB1bmtub3duIG9wY29kZSAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUFJPR19BU1NFUlRfVU5LTk9XTl9PUENPREUgPQotICAgICAgICAgIkVSX1BST0dfQVNTRVJUX1VOS05PV05fT1BDT0RFIjsKLSAgIC8qKiAgMCBvciAxICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWkVST19PUl9PTkUgPSAiRVJfWkVST19PUl9PTkUiOwotICAgLyoqICBydGYoKSBub3Qgc3VwcG9ydGVkIGJ5IFhSVHJlZUZyYWdTZWxlY3RXcmFwcGVyICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfUlRGX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIgPQotICAgICAgICAgIkVSX1JURl9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSIjsKLSAgIC8qKiAgYXNOb2RlSXRlcmF0b3IoKSBub3Qgc3VwcG9ydGVkIGJ5IFhSVHJlZUZyYWdTZWxlY3RXcmFwcGVyICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQVNOT0RFSVRFUkFUT1JfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiA9ICJFUl9BU05PREVJVEVSQVRPUl9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSIjsKLSAgIC8qKiAgZnNiKCkgbm90IHN1cHBvcnRlZCBmb3IgWFN0cmluZ0ZvckNoYXJzICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRlNCX05PVF9TVVBQT1JURURfWFNUUklOR0ZPUkNIQVJTID0KLSAgICAgICAgICJFUl9GU0JfTk9UX1NVUFBPUlRFRF9YU1RSSU5HRk9SQ0hBUlMiOwotICAgLyoqICBDb3VsZCBub3QgZmluZCB2YXJpYWJsZSB3aXRoIHRoZSBuYW1lIG9mICAgKi8KLSBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DT1VMRF9OT1RfRklORF9WQVIgPSAiRVJfQ09VTERfTk9UX0ZJTkRfVkFSIjsKLSAgIC8qKiAgWFN0cmluZ0ZvckNoYXJzIGNhbiBub3QgdGFrZSBhIHN0cmluZyBmb3IgYW4gYXJndW1lbnQgICAqLwotIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1hTVFJJTkdGT1JDSEFSU19DQU5OT1RfVEFLRV9TVFJJTkcgPQotICAgICAgICAgIkVSX1hTVFJJTkdGT1JDSEFSU19DQU5OT1RfVEFLRV9TVFJJTkciOwotICAgLyoqICBUaGUgRmFzdFN0cmluZ0J1ZmZlciBhcmd1bWVudCBjYW4gbm90IGJlIG51bGwgICAqLwotIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZBU1RTVFJJTkdCVUZGRVJfQ0FOTk9UX0JFX05VTEwgPQotICAgICAgICAgIkVSX0ZBU1RTVFJJTkdCVUZGRVJfQ0FOTk9UX0JFX05VTEwiOwotICAgLyoqICAyIG9yIDMgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9UV09fT1JfVEhSRUUgPSAiRVJfVFdPX09SX1RIUkVFIjsKLSAgIC8qKiBWYXJpYWJsZSBhY2Nlc3NlZCBiZWZvcmUgaXQgaXMgYm91bmQhICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1ZBUklBQkxFX0FDQ0VTU0VEX0JFRk9SRV9CSU5EID0KLSAgICAgICAgICJFUl9WQVJJQUJMRV9BQ0NFU1NFRF9CRUZPUkVfQklORCI7Ci0gICAvKiogWFN0cmluZ0ZvckZTQiBjYW4gbm90IHRha2UgYSBzdHJpbmcgZm9yIGFuIGFyZ3VtZW50ISAqLwotIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZTQl9DQU5OT1RfVEFLRV9TVFJJTkcgPQotICAgICAgICAgIkVSX0ZTQl9DQU5OT1RfVEFLRV9TVFJJTkciOwotICAgLyoqIEVycm9yISBTZXR0aW5nIHRoZSByb290IG9mIGEgd2Fsa2VyIHRvIG51bGwhICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1NFVFRJTkdfV0FMS0VSX1JPT1RfVE9fTlVMTCA9Ci0gICAgICAgICAiRVJfU0VUVElOR19XQUxLRVJfUk9PVF9UT19OVUxMIjsKLSAgIC8qKiBUaGlzIE5vZGVTZXREVE0gY2FuIG5vdCBpdGVyYXRlIHRvIGEgcHJldmlvdXMgbm9kZSEgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9ERVNFVERUTV9DQU5OT1RfSVRFUkFURSA9Ci0gICAgICAgICAiRVJfTk9ERVNFVERUTV9DQU5OT1RfSVRFUkFURSI7Ci0gIC8qKiBUaGlzIE5vZGVTZXQgY2FuIG5vdCBpdGVyYXRlIHRvIGEgcHJldmlvdXMgbm9kZSEgKi8KLSBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OT0RFU0VUX0NBTk5PVF9JVEVSQVRFID0KLSAgICAgICAgICJFUl9OT0RFU0VUX0NBTk5PVF9JVEVSQVRFIjsKLSAgLyoqIFRoaXMgTm9kZVNldERUTSBjYW4gbm90IGRvIGluZGV4aW5nIG9yIGNvdW50aW5nIGZ1bmN0aW9ucyEgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9ERVNFVERUTV9DQU5OT1RfSU5ERVggPQotICAgICAgICAgIkVSX05PREVTRVREVE1fQ0FOTk9UX0lOREVYIjsKLSAgLyoqIFRoaXMgTm9kZVNldCBjYW4gbm90IGRvIGluZGV4aW5nIG9yIGNvdW50aW5nIGZ1bmN0aW9ucyEgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9ERVNFVF9DQU5OT1RfSU5ERVggPQotICAgICAgICAgIkVSX05PREVTRVRfQ0FOTk9UX0lOREVYIjsKLSAgLyoqIENhbiBub3QgY2FsbCBzZXRTaG91bGRDYWNoZU5vZGVzIGFmdGVyIG5leHROb2RlIGhhcyBiZWVuIGNhbGxlZCEgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOTk9UX0NBTExfU0VUU0hPVUxEQ0FDSEVOT0RFID0KLSAgICAgICAgICJFUl9DQU5OT1RfQ0FMTF9TRVRTSE9VTERDQUNIRU5PREUiOwotICAvKiogezB9IG9ubHkgYWxsb3dzIHsxfSBhcmd1bWVudHMgKi8KLSBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9PTkxZX0FMTE9XUyA9ICJFUl9PTkxZX0FMTE9XUyI7Ci0gIC8qKiBQcm9ncmFtbWVyJ3MgYXNzZXJ0aW9uIGluIGdldE5leHRTdGVwUG9zOiB1bmtub3duIHN0ZXBUeXBlOiB7MH0gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfVU5LTk9XTl9TVEVQID0gIkVSX1VOS05PV05fU1RFUCI7Ci0gIC8qKiBQcm9ibGVtIHdpdGggUmVsYXRpdmVMb2NhdGlvblBhdGggKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhQRUNURURfUkVMX0xPQ19QQVRIID0KLSAgICAgICAgICJFUl9FWFBFQ1RFRF9SRUxfTE9DX1BBVEgiOwotICAvKiogUHJvYmxlbSB3aXRoIExvY2F0aW9uUGF0aCAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9FWFBFQ1RFRF9MT0NfUEFUSCA9ICJFUl9FWFBFQ1RFRF9MT0NfUEFUSCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYUEVDVEVEX0xPQ19QQVRIX0FUX0VORF9FWFBSID0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRVJfRVhQRUNURURfTE9DX1BBVEhfQVRfRU5EX0VYUFIiOwotICAvKiogUHJvYmxlbSB3aXRoIFN0ZXAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRVhQRUNURURfTE9DX1NURVAgPSAiRVJfRVhQRUNURURfTE9DX1NURVAiOwotICAvKiogUHJvYmxlbSB3aXRoIE5vZGVUZXN0ICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYUEVDVEVEX05PREVfVEVTVCA9ICJFUl9FWFBFQ1RFRF9OT0RFX1RFU1QiOwotICAvKiogRXhwZWN0ZWQgc3RlcCBwYXR0ZXJuICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYUEVDVEVEX1NURVBfUEFUVEVSTiA9Ci0gICAgICAgICJFUl9FWFBFQ1RFRF9TVEVQX1BBVFRFUk4iOwotICAvKiogRXhwZWN0ZWQgcmVsYXRpdmUgcGF0aCBwYXR0ZXJuICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYUEVDVEVEX1JFTF9QQVRIX1BBVFRFUk4gPQotICAgICAgICAgIkVSX0VYUEVDVEVEX1JFTF9QQVRIX1BBVFRFUk4iOwotICAvKiogRVJfQ0FOVF9DT05WRVJUX1hQQVRIUkVTVUxUVFlQRV9UT19CT09MRUFOICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0NBTlRfQ09OVkVSVF9UT19CT09MRUFOID0KLSAgICAgICAgICJFUl9DQU5UX0NPTlZFUlRfVE9fQk9PTEVBTiI7Ci0gIC8qKiBGaWVsZCBFUl9DQU5UX0NPTlZFUlRfVE9fU0lOR0xFTk9ERSAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX0NPTlZFUlRfVE9fU0lOR0xFTk9ERSA9Ci0gICAgICAgICAiRVJfQ0FOVF9DT05WRVJUX1RPX1NJTkdMRU5PREUiOwotICAvKiogRmllbGQgRVJfQ0FOVF9HRVRfU05BUFNIT1RfTEVOR1RIICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfQ0FOVF9HRVRfU05BUFNIT1RfTEVOR1RIID0KLSAgICAgICAgICJFUl9DQU5UX0dFVF9TTkFQU0hPVF9MRU5HVEgiOwotICAvKiogRmllbGQgRVJfTk9OX0lURVJBVE9SX1RZUEUgICAgICAgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9OX0lURVJBVE9SX1RZUEUgPSAiRVJfTk9OX0lURVJBVE9SX1RZUEUiOwotICAvKiogRmllbGQgRVJfRE9DX01VVEFURUQgICAgICAgICAgICAgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRE9DX01VVEFURUQgPSAiRVJfRE9DX01VVEFURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9JTlZBTElEX1hQQVRIX1RZUEUgPSAiRVJfSU5WQUxJRF9YUEFUSF9UWVBFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRU1QVFlfWFBBVEhfUkVTVUxUID0gIkVSX0VNUFRZX1hQQVRIX1JFU1VMVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0lOQ09NUEFUSUJMRV9UWVBFUyA9ICJFUl9JTkNPTVBBVElCTEVfVFlQRVMiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OVUxMX1JFU09MVkVSID0gIkVSX05VTExfUkVTT0xWRVIiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9DQU5UX0NPTlZFUlRfVE9fU1RSSU5HID0KLSAgICAgICAgICJFUl9DQU5UX0NPTlZFUlRfVE9fU1RSSU5HIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTk9OX1NOQVBTSE9UX1RZUEUgPSAiRVJfTk9OX1NOQVBTSE9UX1RZUEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9XUk9OR19ET0NVTUVOVCA9ICJFUl9XUk9OR19ET0NVTUVOVCI7Ci0gIC8qIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgWFBhdGggZXhwcmVzc2lvbiBjYW5ub3QgYmUgZXZhbHVhdGVkIHdpdGggcmVzcGVjdAotICAgKiB0byB0aGlzIHR5cGUgb2Ygbm9kZS4KLSAgICovCi0gIC8qKiBGaWVsZCBFUl9XUk9OR19OT0RFVFlQRSAgICAgICAgICAgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfV1JPTkdfTk9ERVRZUEUgPSAiRVJfV1JPTkdfTk9ERVRZUEUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9YUEFUSF9FUlJPUiA9ICJFUl9YUEFUSF9FUlJPUiI7Ci0KLSAgLy9CRUdJTjogS2V5cyBuZWVkZWQgZm9yIGV4Y2VwdGlvbiBtZXNzYWdlcyBvZiAgSkFYUCAxLjMgWFBhdGggQVBJIGltcGxlbWVudGF0aW9uCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0VYVEVOU0lPTl9GVU5DVElPTl9DQU5OT1RfQkVfSU5WT0tFRCA9ICJFUl9FWFRFTlNJT05fRlVOQ1RJT05fQ0FOTk9UX0JFX0lOVk9LRUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9SRVNPTFZFX1ZBUklBQkxFX1JFVFVSTlNfTlVMTCA9ICJFUl9SRVNPTFZFX1ZBUklBQkxFX1JFVFVSTlNfTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX1VOU1VQUE9SVEVEX1JFVFVSTl9UWVBFID0gIkVSX1VOU1VQUE9SVEVEX1JFVFVSTl9UWVBFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfU09VUkNFX1JFVFVSTl9UWVBFX0NBTk5PVF9CRV9OVUxMID0gIkVSX1NPVVJDRV9SRVRVUk5fVFlQRV9DQU5OT1RfQkVfTlVMTCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0FSR19DQU5OT1RfQkVfTlVMTCA9ICJFUl9BUkdfQ0FOTk9UX0JFX05VTEwiOwotCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX09CSkVDVF9NT0RFTF9OVUxMID0gIkVSX09CSkVDVF9NT0RFTF9OVUxMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfT0JKRUNUX01PREVMX0VNUFRZID0gIkVSX09CSkVDVF9NT0RFTF9FTVBUWSI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0ZFQVRVUkVfTkFNRV9OVUxMID0gIkVSX0ZFQVRVUkVfTkFNRV9OVUxMIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfRkVBVFVSRV9VTktOT1dOID0gIkVSX0ZFQVRVUkVfVU5LTk9XTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSX0dFVFRJTkdfTlVMTF9GRUFUVVJFID0gIkVSX0dFVFRJTkdfTlVMTF9GRUFUVVJFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfR0VUVElOR19VTktOT1dOX0ZFQVRVUkUgPSAiRVJfR0VUVElOR19VTktOT1dOX0ZFQVRVUkUiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TRUNVUkVQUk9DRVNTSU5HX0ZFQVRVUkUgPSAiRVJfU0VDVVJFUFJPQ0VTU0lOR19GRUFUVVJFIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTlVMTF9YUEFUSF9GVU5DVElPTl9SRVNPTFZFUiA9ICJFUl9OVUxMX1hQQVRIX0ZVTkNUSU9OX1JFU09MVkVSIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfTlVMTF9YUEFUSF9WQVJJQUJMRV9SRVNPTFZFUiA9ICJFUl9OVUxMX1hQQVRIX1ZBUklBQkxFX1JFU09MVkVSIjsKLSAgLy9FTkQ6IEtleXMgbmVlZGVkIGZvciBleGNlcHRpb24gbWVzc2FnZXMgb2YgIEpBWFAgMS4zIFhQYXRoIEFQSSBpbXBsZW1lbnRhdGlvbgotCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0xPQ0FMRV9OQU1FX05PVF9IQU5ETEVEID0KLSAgICAgICAgICJXR19MT0NBTEVfTkFNRV9OT1RfSEFORExFRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX1BST1BFUlRZX05PVF9TVVBQT1JURUQgPQotICAgICAgICAgIldHX1BST1BFUlRZX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19ET05UX0RPX0FOWVRISU5HX1dJVEhfTlMgPQotICAgICAgICAgIldHX0RPTlRfRE9fQU5ZVEhJTkdfV0lUSF9OUyI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX1NFQ1VSSVRZX0VYQ0VQVElPTiA9ICJXR19TRUNVUklUWV9FWENFUFRJT04iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19RVU9fTk9fTE9OR0VSX0RFRklORUQgPQotICAgICAgICAgIldHX1FVT19OT19MT05HRVJfREVGSU5FRCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX05FRURfREVSSVZFRF9PQkpFQ1RfVE9fSU1QTEVNRU5UX05PREVURVNUID0KLSAgICAgICAgICJXR19ORUVEX0RFUklWRURfT0JKRUNUX1RPX0lNUExFTUVOVF9OT0RFVEVTVCI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0ZVTkNUSU9OX1RPS0VOX05PVF9GT1VORCA9Ci0gICAgICAgICAiV0dfRlVOQ1RJT05fVE9LRU5fTk9UX0ZPVU5EIjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0dfQ09VTEROT1RfRklORF9GVU5DVElPTiA9Ci0gICAgICAgICAiV0dfQ09VTEROT1RfRklORF9GVU5DVElPTiI7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdHX0NBTk5PVF9NQUtFX1VSTF9GUk9NID0iV0dfQ0FOTk9UX01BS0VfVVJMX0ZST00iOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19FWFBBTkRfRU5USVRJRVNfTk9UX1NVUFBPUlRFRCA9Ci0gICAgICAgICAiV0dfRVhQQU5EX0VOVElUSUVTX05PVF9TVVBQT1JURUQiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19JTExFR0FMX1ZBUklBQkxFX1JFRkVSRU5DRSA9Ci0gICAgICAgICAiV0dfSUxMRUdBTF9WQVJJQUJMRV9SRUZFUkVOQ0UiOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXR19VTlNVUFBPUlRFRF9FTkNPRElORyA9IldHX1VOU1VQUE9SVEVEX0VOQ09ESU5HIjsKLQotICAvKiogIGRldGFjaCgpIG5vdCBzdXBwb3J0ZWQgYnkgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9ERVRBQ0hfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiA9Ci0gICAgICAgICAiRVJfREVUQUNIX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIiOwotICAvKiogIG51bSgpIG5vdCBzdXBwb3J0ZWQgYnkgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9OVU1fTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiA9Ci0gICAgICAgICAiRVJfTlVNX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIiOwotICAvKiogIHhzdHIoKSBub3Qgc3VwcG9ydGVkIGJ5IFhSVHJlZUZyYWdTZWxlY3RXcmFwcGVyICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJfWFNUUl9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSID0KLSAgICAgICAgICJFUl9YU1RSX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIiOwotICAvKiogIHN0cigpIG5vdCBzdXBwb3J0ZWQgYnkgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUl9TVFJfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiA9Ci0gICAgICAgICAiRVJfU1RSX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIiOwotCi0gIC8vIEVycm9yIG1lc3NhZ2VzLi4uCi0KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgT2JqZWN0W11bXSBfY29udGVudHMgPSBuZXcgT2JqZWN0W11bXXsKLQotICB7ICJFUlJPUjAwMDAiICwgInswfSIgfSwKLQotICB7IEVSX0NVUlJFTlRfTk9UX0FMTE9XRURfSU5fTUFUQ0gsICJcdTkxNERcdTVDMERcdTZBMjNcdTVGMEZcdTRFMkRcdTRFMERcdTUxNDFcdThBMzEgY3VycmVudCgpIFx1NTFGRFx1NjU3OFx1RkYwMSIgfSwKLQotICB7IEVSX0NVUlJFTlRfVEFLRVNfTk9fQVJHUywgImN1cnJlbnQoKSBcdTUxRkRcdTY1NzhcdTRFMERcdTYzQTVcdTUzRDdcdTVGMTVcdTY1NzhcdUZGMDEiIH0sCi0KLSAgeyBFUl9ET0NVTUVOVF9SRVBMQUNFRCwKLSAgICAgICJkb2N1bWVudCgpIFx1NTFGRFx1NjU3OFx1NUJFNlx1ODg0Q1x1NURGMlx1NzUzMSBjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdC5GdW5jRG9jdW1lbnQgXHU1M0Q2XHU0RUUzXHUzMDAyIn0sCi0KLSAgeyBFUl9DT05URVhUX0hBU19OT19PV05FUkRPQywKLSAgICAgICJcdTc2RjhcdTk1RENcdThDQzdcdThBMEFcdTc0QjBcdTU4ODNcdTRFMERcdTUxNzdcdTY3MDlcdTY0QzFcdTY3MDlcdTgwMDVcdTY1ODdcdTRFRjZcdUZGMDEifSwKLQotICB7IEVSX0xPQ0FMTkFNRV9IQVNfVE9PX01BTllfQVJHUywKLSAgICAgICJsb2NhbC1uYW1lKCkgXHU1MTc3XHU2NzA5XHU5MDRFXHU1OTFBXHU3Njg0XHU1RjE1XHU2NTc4XHUzMDAyIn0sCi0KLSAgeyBFUl9OQU1FU1BBQ0VVUklfSEFTX1RPT19NQU5ZX0FSR1MsCi0gICAgICAibmFtZXNwYWNlLXVyaSgpIFx1NTE3N1x1NjcwOVx1OTA0RVx1NTkxQVx1NzY4NFx1NUYxNVx1NjU3OFx1MzAwMiJ9LAotCi0gIHsgRVJfTk9STUFMSVpFU1BBQ0VfSEFTX1RPT19NQU5ZX0FSR1MsCi0gICAgICAibm9ybWFsaXplLXNwYWNlKCkgXHU1MTc3XHU2NzA5XHU5MDRFXHU1OTFBXHU3Njg0XHU1RjE1XHU2NTc4XHUzMDAyIn0sCi0KLSAgeyBFUl9OVU1CRVJfSEFTX1RPT19NQU5ZX0FSR1MsCi0gICAgICAibnVtYmVyKCkgXHU1MTc3XHU2NzA5XHU5MDRFXHU1OTFBXHU3Njg0XHU1RjE1XHU2NTc4XHUzMDAyIn0sCi0KLSAgeyBFUl9OQU1FX0hBU19UT09fTUFOWV9BUkdTLAotICAgICAibmFtZSgpIFx1NTE3N1x1NjcwOVx1OTA0RVx1NTkxQVx1NzY4NFx1NUYxNVx1NjU3OFx1MzAwMiJ9LAotCi0gIHsgRVJfU1RSSU5HX0hBU19UT09fTUFOWV9BUkdTLAotICAgICAgInN0cmluZygpIFx1NTE3N1x1NjcwOVx1OTA0RVx1NTkxQVx1NzY4NFx1NUYxNVx1NjU3OFx1MzAwMiJ9LAotCi0gIHsgRVJfU1RSSU5HTEVOR1RIX0hBU19UT09fTUFOWV9BUkdTLAotICAgICAgInN0cmluZy1sZW5ndGgoKSBcdTUxNzdcdTY3MDlcdTkwNEVcdTU5MUFcdTc2ODRcdTVGMTVcdTY1NzhcdTMwMDIifSwKLQotICB7IEVSX1RSQU5TTEFURV9UQUtFU18zX0FSR1MsCi0gICAgICAidHJhbnNsYXRlKCkgXHU1MUZEXHU2NTc4XHU2M0E1XHU1M0Q3XHU0RTA5XHU1MDBCXHU1RjE1XHU2NTc4XHVGRjAxIn0sCi0KLSAgeyBFUl9VTlBBUlNFREVOVElUWVVSSV9UQUtFU18xX0FSRywKLSAgICAgICJ1bnBhcnNlZC1lbnRpdHktdXJpIFx1NTFGRFx1NjU3OFx1NjFDOVx1NjNBNVx1NTNEN1x1NEUwMFx1NTAwQlx1NUYxNVx1NjU3OFx1RkYwMSJ9LAotCi0gIHsgRVJfTkFNRVNQQUNFQVhJU19OT1RfSU1QTEVNRU5URUQsCi0gICAgICAiXHU1QzFBXHU2NzJBXHU1QkU2XHU4ODRDXHU1NDdEXHU1NDBEXHU3QTdBXHU5NTkzXHU4RUY4XHVGRjAxIn0sCi0KLSAgeyBFUl9VTktOT1dOX0FYSVMsCi0gICAgICJcdTRFMERcdTY2MEVcdTc2ODRcdThFRjg6IHswfSJ9LAotCi0gIHsgRVJfVU5LTk9XTl9NQVRDSF9PUEVSQVRJT04sCi0gICAgICJcdTRFMERcdTY2MEVcdTc2ODRcdTkxNERcdTVDMERcdTRGNUNcdTY5NkRcdUZGMDEifSwKLQotICB7IEVSX0lOQ09SUkVDVF9BUkdfTEVOR1RILAotICAgICAgInByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24oKSBcdTdCQzBcdTlFREVcdTc2ODRcdTVGMTVcdTY1NzhcdTk1NzdcdTVFQTZcdTRFMERcdTZCNjNcdTc4QkFcdUZGMDEifSwKLQotICB7IEVSX0NBTlRfQ09OVkVSVF9UT19OVU1CRVIsCi0gICAgICAiXHU3MTIxXHU2Q0Q1XHU4RjQ5XHU2M0RCIHswfSBcdTcwQkFcdTY1NzhcdTVCNTcifSwKLQotICB7IEVSX0NBTlRfQ09OVkVSVF9UT19OT0RFTElTVCwKLSAgICAgICJcdTcxMjFcdTZDRDVcdThGNDlcdTYzREIgezB9IFx1NzBCQSBOb2RlTGlzdFx1RkYwMSJ9LAotCi0gIHsgRVJfQ0FOVF9DT05WRVJUX1RPX01VVEFCTEVOT0RFTElTVCwKLSAgICAgICJcdTcxMjFcdTZDRDVcdThGNDlcdTYzREIgezB9IFx1NzBCQSBOb2RlU2V0RFRNXHVGRjAxIn0sCi0KLSAgeyBFUl9DQU5UX0NPTlZFUlRfVE9fVFlQRSwKLSAgICAgICJcdTcxMjFcdTZDRDVcdThGNDlcdTYzREIgezB9IFx1NzBCQSB0eXBlI3sxfSJ9LAotCi0gIHsgRVJfRVhQRUNURURfTUFUQ0hfUEFUVEVSTiwKLSAgICAgICJcdTU3MjggZ2V0TWF0Y2hTY29yZSBcdTRFMkRcdTk4MTBcdTY3MUZcdTkxNERcdTVDMERcdTZBMjNcdTVGMEYifSwKLQotICB7IEVSX0NPVUxETk9UX0dFVF9WQVJfTkFNRUQsCi0gICAgICAiXHU3MTIxXHU2Q0Q1XHU1M0Q2XHU1Rjk3XHU1NDBEXHU3QTMxXHU3MEJBIHswfSBcdTc2ODRcdThCOEFcdTY1NzgifSwKLQotICB7IEVSX1VOS05PV05fT1BDT0RFLAotICAgICAiXHU5MzJGXHU4QUE0XHVGRjAxXHU0RTBEXHU2NjBFXHU3Njg0XHU0RjVDXHU2OTZEXHU0RUUzXHU3OEJDOiB7MH0ifSwKLQotICB7IEVSX0VYVFJBX0lMTEVHQUxfVE9LRU5TLAotICAgICAiXHU5ODREXHU1OTE2XHU3Njg0XHU3MTIxXHU2NTQ4XHU4QTE4XHU4NjVGOiB7MH0ifSwKLQotICB7IEVSX0VYUEVDVEVEX0RPVUJMRV9RVU9URSwKLSAgICAgICJcdTVGMTVcdTg2NUZcdTkzMkZcdThBQTRcdTc2ODRcdTY1ODdcdTVCNTcuLi4gXHU5ODEwXHU2NzFGXHU5NkQ5XHU1RjE1XHU4NjVGXHVGRjAxIn0sCi0KLSAgeyBFUl9FWFBFQ1RFRF9TSU5HTEVfUVVPVEUsCi0gICAgICAiXHU1RjE1XHU4NjVGXHU5MzJGXHU4QUE0XHU3Njg0XHU2NTg3XHU1QjU3Li4uIFx1OTgxMFx1NjcxRlx1NTVBRVx1NUYxNVx1ODY1Rlx1RkYwMSJ9LAotCi0gIHsgRVJfRU1QVFlfRVhQUkVTU0lPTiwKLSAgICAgIlx1N0E3QVx1NzY3RFx1ODg2OFx1NzkzQVx1NUYwRlx1RkYwMSJ9LAotCi0gIHsgRVJfRVhQRUNURURfQlVUX0ZPVU5ELAotICAgICAiXHU5ODEwXHU2NzFGIHswfVx1RkYwQ1x1NEY0Nlx1NjI3RVx1NTIzMDogezF9In0sCi0KLSAgeyBFUl9JTkNPUlJFQ1RfUFJPR1JBTU1FUl9BU1NFUlRJT04sCi0gICAgICAiXHU3QTBCXHU1RjBGXHU4QTJEXHU4QTA4XHU0RUJBXHU1NEUxXHU1QkEzXHU1NDRBXHU0RTBEXHU2QjYzXHU3OEJBXHVGRjAxLSB7MH0ifSwKLQotICB7IEVSX0JPT0xFQU5fQVJHX05PX0xPTkdFUl9PUFRJT05BTCwKLSAgICAgICJcdTY4MzlcdTY0REEgMTk5OTA3MDkgWFBhdGggXHU4MzQ5XHU2ODQ4XHVGRjBDYm9vbGVhbiguLi4pIFx1NEUwRFx1NTE4RFx1NjYyRlx1OTA3OFx1NjRDN1x1NjAyN1x1NUYxNVx1NjU3OFx1MzAwMiJ9LAotCi0gIHsgRVJfRk9VTkRfQ09NTUFfQlVUX05PX1BSRUNFRElOR19BUkcsCi0gICAgICAiXHU2MjdFXHU1MjMwICcsJyBcdTRGNDZcdTZDOTJcdTY3MDlcdTUxNDhcdTUyNERcdTc2ODRcdTVGMTVcdTY1NzhcdUZGMDEifSwKLQotICB7IEVSX0ZPVU5EX0NPTU1BX0JVVF9OT19GT0xMT1dJTkdfQVJHLAotICAgICAgIlx1NjI3RVx1NTIzMCAnLCcgXHU0RjQ2XHU2QzkyXHU2NzA5XHU1RjhDXHU3RThDXHU3Njg0XHU1RjE1XHU2NTc4XHVGRjAxIn0sCi0KLSAgeyBFUl9QUkVESUNBVEVfSUxMRUdBTF9TWU5UQVgsCi0gICAgICAiJy4uW3ByZWRpY2F0ZV0nIFx1NjIxNiAnLltwcmVkaWNhdGVdJyBcdTY2MkZcdTcxMjFcdTY1NDhcdTc2ODRcdThBOUVcdTZDRDVcdTMwMDJcdThBQ0JcdTY1MzlcdTc1MjggJ3NlbGY6Om5vZGUoKVtwcmVkaWNhdGVdJ1x1MzAwMiJ9LAotCi0gIHsgRVJfSUxMRUdBTF9BWElTX05BTUUsCi0gICAgICJcdTcxMjFcdTY1NDhcdTc2ODRcdThFRjhcdTU0MERcdTdBMzE6IHswfSJ9LAotCi0gIHsgRVJfVU5LTk9XTl9OT0RFVFlQRSwKLSAgICAgIlx1NEUwRFx1NjYwRVx1NzY4NCBub2RldHlwZTogezB9In0sCi0KLSAgeyBFUl9QQVRURVJOX0xJVEVSQUxfTkVFRFNfQkVfUVVPVEVELAotICAgICAgIlx1NkEyM1x1NUYwRlx1NjU4N1x1NUI1NyAoezB9KSBcdTk3MDBcdTg5ODFcdTUyQTBcdTRFMEFcdTVGMTVcdTg2NUZcdUZGMDEifSwKLQotICB7IEVSX0NPVUxETk9UX0JFX0ZPUk1BVFRFRF9UT19OVU1CRVIsCi0gICAgICAiezB9IFx1NzEyMVx1NkNENVx1NjgzQ1x1NUYwRlx1NTMxNlx1NzBCQVx1NjU3OFx1NUI1N1x1RkYwMSJ9LAotCi0gIHsgRVJfQ09VTEROT1RfQ1JFQVRFX1hNTFBST0NFU1NPUkxJQUlTT04sCi0gICAgICAiXHU3MTIxXHU2Q0Q1XHU1RUZBXHU3QUNCIFhNTCBUcmFuc2Zvcm1lckZhY3RvcnkgTGlhaXNvbjogezB9In0sCi0KLSAgeyBFUl9ESUROT1RfRklORF9YUEFUSF9TRUxFQ1RfRVhQLAotICAgICAgIlx1OTMyRlx1OEFBNFx1RkYwMVx1NjI3RVx1NEUwRFx1NTIzMCB4cGF0aCBcdTkwNzhcdTUzRDZcdTg4NjhcdTc5M0FcdTVGMEYgKC1zZWxlY3QpXHUzMDAyIn0sCi0KLSAgeyBFUl9DT1VMRE5PVF9GSU5EX0VORE9QX0FGVEVSX09QTE9DQVRJT05QQVRILAotICAgICAgIlx1OTMyRlx1OEFBNFx1RkYwMVx1NTcyOCBPUF9MT0NBVElPTlBBVEggXHU0RTRCXHU1RjhDXHU2MjdFXHU0RTBEXHU1MjMwIEVORE9QIn0sCi0KLSAgeyBFUl9FUlJPUl9PQ0NVUkVELAotICAgICAiXHU3NjdDXHU3NTFGXHU5MzJGXHU4QUE0XHVGRjAxIn0sCi0KLSAgeyBFUl9JTExFR0FMX1ZBUklBQkxFX1JFRkVSRU5DRSwKLSAgICAgICJcdTcwQkFcdThCOEFcdTY1NzhcdTYzMDdcdTVCOUFcdTc2ODQgVmFyaWFibGVSZWZlcmVuY2UgXHU4RDg1XHU1MUZBXHU3NkY4XHU5NURDXHU4Q0M3XHU4QTBBXHU3NEIwXHU1ODgzXHU2MjE2XHU2QzkyXHU2NzA5XHU1QjlBXHU3RkE5XHVGRjAxXHU1NDBEXHU3QTMxID0gezB9In0sCi0KLSAgeyBFUl9BWEVTX05PVF9BTExPV0VELAotICAgICAgIlx1OTE0RFx1NUMwRFx1NkEyM1x1NUYwRlx1NEUyRFx1NTBDNVx1NTE0MVx1OEEzMSBjaGlsZDo6IFx1ODIwNyBhdHRyaWJ1dGU6OiBcdThFRjhcdUZGMDFcdTkwNTVcdTUzQ0RcdTc2ODRcdThFRjggPSB7MH0ifSwKLQotICB7IEVSX0tFWV9IQVNfVE9PX01BTllfQVJHUywKLSAgICAgICJrZXkoKSBcdTUxNzdcdTY3MDlcdTRFMERcdTZCNjNcdTc4QkFcdTc2ODRcdTVGMTVcdTY1NzhcdTY1NzhcdTc2RUVcdTMwMDIifSwKLQotICB7IEVSX0NPVU5UX1RBS0VTXzFfQVJHLAotICAgICAgImNvdW50IFx1NTFGRFx1NjU3OFx1NjFDOVx1NjNBNVx1NTNEN1x1NEUwMFx1NTAwQlx1NUYxNVx1NjU3OFx1RkYwMSJ9LAotCi0gIHsgRVJfQ09VTEROT1RfRklORF9GVU5DVElPTiwKLSAgICAgIlx1NjI3RVx1NEUwRFx1NTIzMFx1NTFGRFx1NjU3ODogezB9In0sCi0KLSAgeyBFUl9VTlNVUFBPUlRFRF9FTkNPRElORywKLSAgICAgIlx1NEUwRFx1NjUyRlx1NjNGNFx1NzY4NFx1N0RFOFx1NzhCQzogezB9In0sCi0KLSAgeyBFUl9QUk9CTEVNX0lOX0RUTV9ORVhUU0lCTElORywKLSAgICAgICJcdTU3MjggZ2V0TmV4dFNpYmxpbmcgXHU3Njg0IERUTSBcdTRFMkRcdTc2N0NcdTc1MUZcdTU1NEZcdTk4NEMuLi4gXHU2QjYzXHU1NzI4XHU1NjE3XHU4QTY2XHU1RkE5XHU1MzlGIn0sCi0KLSAgeyBFUl9DQU5OT1RfV1JJVEVfVE9fRU1QVFlOT0RFTElTVElNUEwsCi0gICAgICAiXHU3QTBCXHU1RjBGXHU4QTJEXHU4QTA4XHU0RUJBXHU1NEUxXHU5MzJGXHU4QUE0OiBcdTcxMjFcdTZDRDVcdTVCRUJcdTUxNjUgRW1wdHlOb2RlTGlzdFx1MzAwMiJ9LAotCi0gIHsgRVJfU0VURE9NRkFDVE9SWV9OT1RfU1VQUE9SVEVELAotICAgICAgIlhQYXRoQ29udGV4dCBcdTRFMERcdTY1MkZcdTYzRjQgc2V0RE9NRmFjdG9yeVx1RkYwMSJ9LAotCi0gIHsgRVJfUFJFRklYX01VU1RfUkVTT0xWRSwKLSAgICAgICJcdTUyNERcdTdGNkVcdTc4QkNcdTVGQzVcdTk4MDhcdTg5RTNcdTY3OTBcdTcwQkFcdTU0N0RcdTU0MERcdTdBN0FcdTk1OTM6IHswfSJ9LAotCi0gIHsgRVJfUEFSU0VfTk9UX1NVUFBPUlRFRCwKLSAgICAgICJYUGF0aENvbnRleHQgXHU0RTJEXHU0RTBEXHU2NTJGXHU2M0Y0IHBhcnNlIChJbnB1dFNvdXJjZSBcdTRGODZcdTZFOTApXHUzMDAyXHU3MTIxXHU2Q0Q1XHU5NThCXHU1NTVGIHswfSJ9LAotCi0gIHsgRVJfU0FYX0FQSV9OT1RfSEFORExFRCwKLSAgICAgICJTQVggQVBJIGNoYXJhY3RlcnMoY2hhciBjaFtdLi4uIFx1NEUyNlx1OTc1RVx1NzUzMSBEVE0gXHU4NjU1XHU3NDA2XHVGRjAxIn0sCi0KLSAgeyBFUl9JR05PUkFCTEVfV0hJVEVTUEFDRV9OT1RfSEFORExFRCwKLSAgICAgICJpZ25vcmFibGVXaGl0ZXNwYWNlKGNoYXIgY2hbXS4uLiBcdTRFMjZcdTk3NUVcdTc1MzEgRFRNIFx1ODY1NVx1NzQwNlx1RkYwMSJ9LAotCi0gIHsgRVJfRFRNX0NBTk5PVF9IQU5ETEVfTk9ERVMsCi0gICAgICAiRFRNTGlhaXNvbiBcdTcxMjFcdTZDRDVcdTg2NTVcdTc0MDZcdTk4NUVcdTU3OEIgezB9IFx1NzY4NFx1NjNBN1x1NTIzNlx1NEVFM1x1NzhCQ1x1N0JDMFx1OUVERSJ9LAotCi0gIHsgRVJfWEVSQ0VTX0NBTk5PVF9IQU5ETEVfTk9ERVMsCi0gICAgICAiRE9NMkhlbHBlciBcdTcxMjFcdTZDRDVcdTg2NTVcdTc0MDZcdTk4NUVcdTU3OEIgezB9IFx1NzY4NFx1NjNBN1x1NTIzNlx1NEVFM1x1NzhCQ1x1N0JDMFx1OUVERSJ9LAotCi0gIHsgRVJfWEVSQ0VTX1BBUlNFX0VSUk9SX0RFVEFJTFMsCi0gICAgICAiRE9NMkhlbHBlci5wYXJzZSBcdTkzMkZcdThBQTQ6IFN5c3RlbUlEIC0gezB9IFx1ODg0QyAtIHsxfSJ9LAotCi0gIHsgRVJfWEVSQ0VTX1BBUlNFX0VSUk9SLAotICAgICAiRE9NMkhlbHBlci5wYXJzZSBcdTkzMkZcdThBQTQifSwKLQotICB7IEVSX0lOVkFMSURfVVRGMTZfU1VSUk9HQVRFLAotICAgICAgIlx1NTA3NVx1NkUyQ1x1NTIzMFx1NzEyMVx1NjU0OFx1NzY4NCBVVEYtMTYgXHU0RUUzXHU3NDA2OiB7MH1cdUZGMUYifSwKLQotICB7IEVSX09JRVJST1IsCi0gICAgICJJTyBcdTkzMkZcdThBQTQifSwKLQotICB7IEVSX0NBTk5PVF9DUkVBVEVfVVJMLAotICAgICAiXHU3MTIxXHU2Q0Q1XHU3MEJBIHswfSBcdTVFRkFcdTdBQ0IgdXJsIn0sCi0KLSAgeyBFUl9YUEFUSF9SRUFET0JKRUNULAotICAgICAiXHU1NzI4IFhQYXRoLnJlYWRPYmplY3QgXHU0RTJEOiB7MH0ifSwKLQotICB7IEVSX0ZVTkNUSU9OX1RPS0VOX05PVF9GT1VORCwKLSAgICAgICJcdTYyN0VcdTRFMERcdTUyMzBcdTUxRkRcdTY1NzhcdThBMThcdTg2NUZcdTMwMDIifSwKLQotICB7IEVSX0NBTk5PVF9ERUFMX1hQQVRIX1RZUEUsCi0gICAgICAgIlx1NzEyMVx1NkNENVx1ODY1NVx1NzQwNiBYUGF0aCBcdTk4NUVcdTU3OEI6IHswfSJ9LAotCi0gIHsgRVJfTk9ERVNFVF9OT1RfTVVUQUJMRSwKLSAgICAgICAiXHU2QjY0IE5vZGVTZXQgXHU0RTBEXHU1M0VGXHU4QjhBXHU2NkY0In0sCi0KLSAgeyBFUl9OT0RFU0VURFRNX05PVF9NVVRBQkxFLAotICAgICAgICJcdTZCNjQgTm9kZVNldERUTSBcdTRFMERcdTUzRUZcdThCOEFcdTY2RjQifSwKLQotICB7IEVSX1ZBUl9OT1RfUkVTT0xWQUJMRSwKLSAgICAgICAgIlx1OEI4QVx1NjU3OFx1NzEyMVx1NkNENVx1ODlFM1x1Njc5MDogezB9In0sCi0KLSAgeyBFUl9OVUxMX0VSUk9SX0hBTkRMRVIsCi0gICAgICAgICJcdTdBN0FcdTUwM0NcdTkzMkZcdThBQTRcdTg2NTVcdTc0MDZcdTdBMEJcdTVGMEYifSwKLQotICB7IEVSX1BST0dfQVNTRVJUX1VOS05PV05fT1BDT0RFLAotICAgICAgICJcdTdBMEJcdTVGMEZcdThBMkRcdThBMDhcdTRFQkFcdTU0RTFcdTVCQTNcdTU0NEE6IFx1NEUwRFx1NjYwRVx1NzY4NCBvcGNvZGU6IHswfSJ9LAotCi0gIHsgRVJfWkVST19PUl9PTkUsCi0gICAgICAgIjAgXHU2MjE2IDEifSwKLQotICB7IEVSX1JURl9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSLAotICAgICAgICJYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciBcdTRFMERcdTY1MkZcdTYzRjQgcnRmKCkifSwKLQotICB7IEVSX1JURl9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSLAotICAgICAgICJYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciBcdTRFMERcdTY1MkZcdTYzRjQgYXNOb2RlSXRlcmF0b3IoKSJ9LAotCi0gICAgICAgIC8qKiAgZGV0YWNoKCkgbm90IHN1cHBvcnRlZCBieSBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciAgICovCi0gICB7IEVSX0RFVEFDSF9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSLAotICAgICAgICAgICAgICAgICJYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciBcdTRFMERcdTY1MkZcdTYzRjQgZGV0YWNoKCkifSwKLQotICAgICAgICAvKiogIG51bSgpIG5vdCBzdXBwb3J0ZWQgYnkgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIgICAqLwotICAgeyBFUl9OVU1fTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiwKLSAgICAgICAgICAgICAgICAiWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIgXHU0RTBEXHU2NTJGXHU2M0Y0IG51bSgpIn0sCi0KLSAgICAgICAgLyoqICB4c3RyKCkgbm90IHN1cHBvcnRlZCBieSBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciAgICovCi0gICB7IEVSX1hTVFJfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiwKLSAgICAgICAgICAgICAgICAiWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIgXHU0RTBEXHU2NTJGXHU2M0Y0IHhzdHIoKSJ9LAotCi0gICAgICAgIC8qKiAgc3RyKCkgbm90IHN1cHBvcnRlZCBieSBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciAgICovCi0gICB7IEVSX1NUUl9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSLAotICAgICAgICAgICAgICAgICJYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciBcdTRFMERcdTY1MkZcdTYzRjQgc3RyKCkifSwKLQotICB7IEVSX0ZTQl9OT1RfU1VQUE9SVEVEX1hTVFJJTkdGT1JDSEFSUywKLSAgICAgICAiWFN0cmluZ0ZvckNoYXJzIFx1NEUwRFx1NjUyRlx1NjNGNCBmc2IoKSJ9LAotCi0gIHsgRVJfQ09VTERfTk9UX0ZJTkRfVkFSLAotICAgICAgIlx1NjI3RVx1NEUwRFx1NTIzMFx1NTQwRFx1N0EzMVx1NzBCQSB7MH0gXHU3Njg0XHU4QjhBXHU2NTc4In0sCi0KLSAgeyBFUl9YU1RSSU5HRk9SQ0hBUlNfQ0FOTk9UX1RBS0VfU1RSSU5HLAotICAgICAgIlhTdHJpbmdGb3JDaGFycyBcdTcxMjFcdTZDRDVcdTYzQTVcdTUzRDdcdTVCNTdcdTRFMzJcdTRGNUNcdTcwQkFcdTVGMTVcdTY1NzgifSwKLQotICB7IEVSX0ZBU1RTVFJJTkdCVUZGRVJfQ0FOTk9UX0JFX05VTEwsCi0gICAgICAiRmFzdFN0cmluZ0J1ZmZlciBcdTVGMTVcdTY1NzhcdTRFMERcdTUzRUZcdTcwQkFcdTdBN0FcdTUwM0MifSwKLQotICB7IEVSX1RXT19PUl9USFJFRSwKLSAgICAgICAiMiBcdTYyMTYgMyJ9LAotCi0gIHsgRVJfVkFSSUFCTEVfQUNDRVNTRURfQkVGT1JFX0JJTkQsCi0gICAgICAgIlx1OEI4QVx1NjU3OFx1OTAyM1x1N0Q1MFx1NEU0Qlx1NTI0RFx1NEZCRlx1OTAzMlx1ODg0Q1x1NUI1OFx1NTNENlx1RkYwMSJ9LAotCi0gIHsgRVJfRlNCX0NBTk5PVF9UQUtFX1NUUklORywKLSAgICAgICAiWFN0cmluZ0ZvckZTQiBcdTcxMjFcdTZDRDVcdTYzQTVcdTUzRDdcdTVCNTdcdTRFMzJcdTRGNUNcdTcwQkFcdTVGMTVcdTY1NzhcdUZGMDEifSwKLQotICB7IEVSX1NFVFRJTkdfV0FMS0VSX1JPT1RfVE9fTlVMTCwKLSAgICAgICAiXG4gXHU5MzJGXHU4QUE0XHVGRjAxXHU1QzA3XHU4NDkwXHU5NkM2XHU3QTBCXHU1RjBGXHU3Njg0XHU2ODM5XHU4QTJEXHU1QjlBXHU3MEJBXHU3QTdBXHU1MDNDXHVGRjAxIn0sCi0KLSAgeyBFUl9OT0RFU0VURFRNX0NBTk5PVF9JVEVSQVRFLAotICAgICAgICJcdTZCNjQgTm9kZVNldERUTSBcdTcxMjFcdTZDRDVcdTkxQ0RcdTg5MDdcdTUxNDhcdTUyNERcdTc2ODRcdTdCQzBcdTlFREVcdUZGMDEifSwKLQotICB7IEVSX05PREVTRVRfQ0FOTk9UX0lURVJBVEUsCi0gICAgICAgIlx1NkI2NCBOb2RlU2V0IFx1NzEyMVx1NkNENVx1OTFDRFx1ODkwN1x1NTE0OFx1NTI0RFx1NzY4NFx1N0JDMFx1OUVERVx1RkYwMSJ9LAotCi0gIHsgRVJfTk9ERVNFVERUTV9DQU5OT1RfSU5ERVgsCi0gICAgICAgIlx1NkI2NCBOb2RlU2V0RFRNIFx1NzEyMVx1NkNENVx1NTdGN1x1ODg0Q1x1ODhGRFx1NEY1Q1x1N0QyMlx1NUYxNVx1NjIxNlx1OEEwOFx1NjU3OFx1NTI5Rlx1ODBGRFx1RkYwMSJ9LAotCi0gIHsgRVJfTk9ERVNFVF9DQU5OT1RfSU5ERVgsCi0gICAgICAgIlx1NkI2NCBOb2RlU2V0IFx1NzEyMVx1NkNENVx1NTdGN1x1ODg0Q1x1ODhGRFx1NEY1Q1x1N0QyMlx1NUYxNVx1NjIxNlx1OEEwOFx1NjU3OFx1NTI5Rlx1ODBGRFx1RkYwMSJ9LAotCi0gIHsgRVJfQ0FOTk9UX0NBTExfU0VUU0hPVUxEQ0FDSEVOT0RFLAotICAgICAgICJcdTU0N0NcdTUzRUIgbmV4dE5vZGUgXHU0RTRCXHU1RjhDXHVGRjBDXHU3MTIxXHU2Q0Q1XHU1NDdDXHU1M0VCIHNldFNob3VsZENhY2hlTm9kZXNcdUZGMDEifSwKLQotICB7IEVSX09OTFlfQUxMT1dTLAotICAgICAgICJ7MH0gXHU1MEM1XHU1MTQxXHU4QTMxIHsxfSBcdTUwMEJcdTVGMTVcdTY1NzgifSwKLQotICB7IEVSX1VOS05PV05fU1RFUCwKLSAgICAgICAiXHU1NzI4IGdldE5leHRTdGVwUG9zIFx1NEUyRFx1N0EwQlx1NUYwRlx1OEEyRFx1OEEwOFx1NEVCQVx1NTRFMVx1NzY4NFx1NUJBM1x1NTQ0QTogXHU0RTBEXHU2NjBFXHU3Njg0IHN0ZXBUeXBlOiB7MH0ifSwKLQotICAvL05vdGUgdG8gdHJhbnNsYXRvcnM6ICBBIHJlbGF0aXZlIGxvY2F0aW9uIHBhdGggaXMgYSBmb3JtIG9mIFhQYXRoIGV4cHJlc3Npb24uCi0gIC8vIFRoZSBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHN1Y2ggYW4gZXhwcmVzc2lvbiB3YXMgZXhwZWN0ZWQgZm9sbG93aW5nIHRoZQotICAvLyBjaGFyYWN0ZXJzICcvJyBvciAnLy8nLCBidXQgd2FzIG5vdCBmb3VuZC4KLSAgeyBFUl9FWFBFQ1RFRF9SRUxfTE9DX1BBVEgsCi0gICAgICAiJy8nIFx1NjIxNiAnLy8nIFx1OEExOFx1ODY1Rlx1NEU0Qlx1NUY4Q1x1RkYwQ1x1OTgxMFx1NjcxRlx1NzZGOFx1NUMwRFx1NEY0RFx1N0Y2RVx1OERFRlx1NUY5MVx1MzAwMiJ9LAotCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBIGxvY2F0aW9uIHBhdGggaXMgYSBmb3JtIG9mIFhQYXRoIGV4cHJlc3Npb24uCi0gIC8vIFRoZSBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHN5bnRhY3RpY2FsbHkgc3VjaCBhbiBleHByZXNzaW9uIHdhcyBleHBlY3RlZCxidXQKLSAgLy8gdGhlIGNoYXJhY3RlcnMgc3BlY2lmaWVkIGJ5IHRoZSBzdWJzdGl0dXRpb24gdGV4dCB3ZXJlIGVuY291bnRlcmVkIGluc3RlYWQuCi0gIHsgRVJfRVhQRUNURURfTE9DX1BBVEgsCi0gICAgICAgIlx1OTgxMFx1NjcxRlx1NEY0RFx1N0Y2RVx1OERFRlx1NUY5MVx1RkYwQ1x1NEY0Nlx1NTFGQVx1NzNGRVx1NEUwQlx1NTIxN1x1OEExOFx1ODY1RjogIHswfSJ9LAotCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBBIGxvY2F0aW9uIHBhdGggaXMgYSBmb3JtIG9mIFhQYXRoIGV4cHJlc3Npb24uCi0gIC8vIFRoZSBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHN5bnRhY3RpY2FsbHkgc3VjaCBhIHN1YmV4cHJlc3Npb24gd2FzIGV4cGVjdGVkLAotICAvLyBidXQgbm8gbW9yZSBjaGFyYWN0ZXJzIHdlcmUgZm91bmQgaW4gdGhlIGV4cHJlc3Npb24uCi0gIHsgRVJfRVhQRUNURURfTE9DX1BBVEhfQVRfRU5EX0VYUFIsCi0gICAgICAgIlx1OTgxMFx1NjcxRlx1NEY0RFx1N0Y2RVx1OERFRlx1NUY5MVx1RkYwQ1x1NEY0Nlx1NTFGQVx1NzNGRSBYUGF0aCBcdTg4NjhcdTc5M0FcdTVGMEZcdTc2ODRcdTdENTBcdTVDM0VcdTMwMDIifSwKLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQSBsb2NhdGlvbiBzdGVwIGlzIHBhcnQgb2YgYW4gWFBhdGggZXhwcmVzc2lvbi4KLSAgLy8gVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgc3ludGFjdGljYWxseSBzdWNoIGFuIGV4cHJlc3Npb24gd2FzIGV4cGVjdGVkCi0gIC8vIGZvbGxvd2luZyB0aGUgc3BlY2lmaWVkIGNoYXJhY3RlcnMuCi0gIHsgRVJfRVhQRUNURURfTE9DX1NURVAsCi0gICAgICAgIicvJyBcdTYyMTYgJy8vJyBcdThBMThcdTg2NUZcdTRFNEJcdTVGOENcdUZGMENcdTk4MTBcdTY3MUZcdTRGNERcdTdGNkVcdTZCNjVcdTlBNUZcdTMwMDIifSwKLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgQSBub2RlIHRlc3QgaXMgcGFydCBvZiBhbiBYUGF0aCBleHByZXNzaW9uIHRoYXQgaXMKLSAgLy8gdXNlZCB0byB0ZXN0IGZvciBwYXJ0aWN1bGFyIGtpbmRzIG9mIG5vZGVzLiAgSW4gdGhpcyBjYXNlLCBhIG5vZGUgdGVzdCB0aGF0Ci0gIC8vIGNvbnNpc3RzIG9mIGFuIE5DTmFtZSBmb2xsb3dlZCBieSBhIGNvbG9uIGFuZCBhbiBhc3RlcmlzayBvciB0aGF0IGNvbnNpc3RzCi0gIC8vIG9mIGEgUU5hbWUgd2FzIGV4cGVjdGVkLCBidXQgd2FzIG5vdCBmb3VuZC4KLSAgeyBFUl9FWFBFQ1RFRF9OT0RFX1RFU1QsCi0gICAgICAgIlx1OTgxMFx1NjcxRlx1N0IyNlx1NTQwOCBOQ05hbWU6KiBcdTYyMTYgUU5hbWUgXHU3Njg0XHU3QkMwXHU5RURFXHU2RTJDXHU4QTY2XHUzMDAyIn0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIEEgc3RlcCBwYXR0ZXJuIGlzIHBhcnQgb2YgYW4gWFBhdGggZXhwcmVzc2lvbi4KLSAgLy8gVGhlIG1lc3NhZ2UgaW5kaWNhdGVzIHRoYXQgc3ludGFjdGljYWxseSBzdWNoIGFuIGV4cHJlc3Npb24gd2FzIGV4cGVjdGVkLAotICAvLyBidXQgdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXIgd2FzIGZvdW5kIGluIHRoZSBleHByZXNzaW9uIGluc3RlYWQuCi0gIHsgRVJfRVhQRUNURURfU1RFUF9QQVRURVJOLAotICAgICAgICJcdTk4MTBcdTY3MUZcdTZCNjVcdTlBNUZcdTZBMjNcdTVGMEZcdUZGMENcdTRGNDZcdTUxRkFcdTczRkUgJy8nXHUzMDAyIn0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogQSByZWxhdGl2ZSBwYXRoIHBhdHRlcm4gaXMgcGFydCBvZiBhbiBYUGF0aCBleHByZXNzaW9uLgotICAvLyBUaGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCBzeW50YWN0aWNhbGx5IHN1Y2ggYW4gZXhwcmVzc2lvbiB3YXMgZXhwZWN0ZWQsCi0gIC8vIGJ1dCB3YXMgbm90IGZvdW5kLgotICB7IEVSX0VYUEVDVEVEX1JFTF9QQVRIX1BBVFRFUk4sCi0gICAgICAgIlx1OTgxMFx1NjcxRlx1NzZGOFx1NUMwRFx1OERFRlx1NUY5MVx1NkEyM1x1NUYwRlx1MzAwMiJ9LAotCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYSBkYXRhIHR5cGUuICBUaGUKLSAgLy8gbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCBhIHZhbHVlIG9mIGEgcGFydGljdWxhciB0eXBlIGNvdWxkIG5vdCBiZSBjb252ZXJ0ZWQKLSAgLy8gdG8gYSB2YWx1ZSBvZiB0eXBlIGJvb2xlYW4uCi0gIHsgRVJfQ0FOVF9DT05WRVJUX1RPX0JPT0xFQU4sCi0gICAgICAgIlhQYXRoIFx1ODg2OFx1NzkzQVx1NUYwRiAnJ3swfScnIFx1NzY4NCBYUGF0aFJlc3VsdCBcdTUxNzdcdTY3MDkgWFBhdGhSZXN1bHRUeXBlIFx1NzY4NCB7MX1cdUZGMENcdTVCODNcdTcxMjFcdTZDRDVcdThGNDlcdTYzREJcdTcwQkFcdTVFMDNcdTY3OTdcdTUwM0NcdTMwMDIifSwKLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiBEbyBub3QgdHJhbnNsYXRlIEFOWV9VTk9SREVSRURfTk9ERV9UWVBFIGFuZAotICAvLyBGSVJTVF9PUkRFUkVEX05PREVfVFlQRS4KLSAgeyBFUl9DQU5UX0NPTlZFUlRfVE9fU0lOR0xFTk9ERSwKLSAgICAgICAiWFBhdGggXHU4ODY4XHU3OTNBXHU1RjBGICcnezB9JycgXHU3Njg0IFhQYXRoUmVzdWx0IFx1NTE3N1x1NjcwOSBYUGF0aFJlc3VsdFR5cGUgXHU3Njg0IHsxfVx1RkYwQ1x1NUI4M1x1NzEyMVx1NkNENVx1OEY0OVx1NjNEQlx1NzBCQVx1NTVBRVx1NEUwMFx1N0JDMFx1OUVERVx1MzAwMlx1NjVCOVx1NkNENSBnZXRTaW5nbGVOb2RlVmFsdWUgXHU1MEM1XHU5MDY5XHU3NTI4XHU2NUJDXHU5ODVFXHU1NzhCIEFOWV9VTk9SREVSRURfTk9ERV9UWVBFIFx1ODIwNyBGSVJTVF9PUkRFUkVEX05PREVfVFlQRVx1MzAwMiJ9LAotCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6IERvIG5vdCB0cmFuc2xhdGUgVU5PUkRFUkVEX05PREVfU05BUFNIT1RfVFlQRSBhbmQKLSAgLy8gT1JERVJFRF9OT0RFX1NOQVBTSE9UX1RZUEUuCi0gIHsgRVJfQ0FOVF9HRVRfU05BUFNIT1RfTEVOR1RILAotICAgICAgICJcdTcxMjFcdTZDRDVcdTU3MjggWFBhdGggXHU4ODY4XHU3OTNBXHU1RjBGICcnezB9JycgXHU3Njg0IFhQYXRoUmVzdWx0IFx1NEUwQVx1NTQ3Q1x1NTNFQlx1NjVCOVx1NkNENSBnZXRTbmFwc2hvdExlbmd0aFx1RkYwQ1x1NTZFMFx1NzBCQVx1NUI4M1x1NzY4NCBYUGF0aFJlc3VsdFR5cGUgXHU2NjJGIHsxfVx1MzAwMlx1NkI2NFx1NjVCOVx1NkNENVx1NTBDNVx1OTA2OVx1NzUyOFx1NjVCQ1x1OTg1RVx1NTc4QiBVTk9SREVSRURfTk9ERV9TTkFQU0hPVF9UWVBFIFx1ODIwNyBPUkRFUkVEX05PREVfU05BUFNIT1RfVFlQRVx1MzAwMiJ9LAotCi0gIHsgRVJfTk9OX0lURVJBVE9SX1RZUEUsCi0gICAgICAgIlx1NzEyMVx1NkNENVx1NTcyOCBYUGF0aCBcdTg4NjhcdTc5M0FcdTVGMEYgJyd7MH0nJyBcdTc2ODQgWFBhdGhSZXN1bHQgXHU0RTBBXHU1NDdDXHU1M0VCXHU2NUI5XHU2Q0Q1IGl0ZXJhdGVOZXh0XHVGRjBDXHU1NkUwXHU3MEJBXHU1QjgzXHU3Njg0IFhQYXRoUmVzdWx0VHlwZSBcdTY2MkYgezF9XHUzMDAyXHU2QjY0XHU2NUI5XHU2Q0Q1XHU1MEM1XHU5MDY5XHU3NTI4XHU2NUJDXHU5ODVFXHU1NzhCIFVOT1JERVJFRF9OT0RFX0lURVJBVE9SX1RZUEUgXHU4MjA3IE9SREVSRURfTk9ERV9JVEVSQVRPUl9UWVBFXHUzMDAyIn0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogVGhpcyBtZXNzYWdlIGluZGljYXRlcyB0aGF0IHRoZSBkb2N1bWVudCBiZWluZyBvcGVyYXRlZAotICAvLyB1cG9uIGNoYW5nZWQsIHNvIHRoZSBpdGVyYXRvciBvYmplY3QgdGhhdCB3YXMgYmVpbmcgdXNlZCB0byB0cmF2ZXJzZSB0aGUKLSAgLy8gZG9jdW1lbnQgaGFzIG5vdyBiZWNvbWUgaW52YWxpZC4KLSAgeyBFUl9ET0NfTVVUQVRFRCwKLSAgICAgICAiXHU3RDUwXHU2NzlDXHU1MEIzXHU1NkRFXHU1RjhDXHU2NTg3XHU0RUY2XHU1REYyXHU4QjhBXHU2NkY0XHUzMDAyXHU5MUNEXHU4OTA3XHU3QTBCXHU1RjBGXHU3MTIxXHU2NTQ4XHUzMDAyIn0sCi0KLSAgeyBFUl9JTlZBTElEX1hQQVRIX1RZUEUsCi0gICAgICAgIlx1NzEyMVx1NjU0OFx1NzY4NCBYUGF0aCBcdTk4NUVcdTU3OEJcdTVGMTVcdTY1Nzg6IHswfSJ9LAotCi0gIHsgRVJfRU1QVFlfWFBBVEhfUkVTVUxULAotICAgICAgICJcdTdBN0FcdTc2N0RcdTc2ODQgWFBhdGggXHU3RDUwXHU2NzlDXHU3MjY5XHU0RUY2In0sCi0KLSAgeyBFUl9JTkNPTVBBVElCTEVfVFlQRVMsCi0gICAgICAgIlhQYXRoIFx1ODg2OFx1NzkzQVx1NUYwRiAnJ3swfScnIFx1NzY4NCBYUGF0aFJlc3VsdCBcdTUxNzdcdTY3MDkgWFBhdGhSZXN1bHRUeXBlIFx1NzY4NCB7MX1cdUZGMENcdTVCODNcdTcxMjFcdTZDRDVcdTVGMzdcdTUyMzZcdThGNDlcdTYyMTAgezJ9IFx1NjMwN1x1NUI5QVx1NzY4NCBYUGF0aFJlc3VsdFR5cGVcdTMwMDIifSwKLQotICB7IEVSX05VTExfUkVTT0xWRVIsCi0gICAgICAgIlx1NzEyMVx1NkNENVx1NEVFNVx1N0E3QVx1NTAzQ1x1NTI0RFx1N0Y2RVx1NzhCQ1x1ODlFM1x1Njc5MFx1NTY2OFx1NEY4Nlx1ODlFM1x1Njc5MFx1NTI0RFx1N0Y2RVx1NzhCQ1x1MzAwMiJ9LAotCi0gIC8vIE5vdGUgdG8gdHJhbnNsYXRvcnM6ICBUaGUgc3Vic3RpdHV0aW9uIHRleHQgaXMgdGhlIG5hbWUgb2YgYSBkYXRhIHR5cGUuICBUaGUKLSAgLy8gbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCBhIHZhbHVlIG9mIGEgcGFydGljdWxhciB0eXBlIGNvdWxkIG5vdCBiZSBjb252ZXJ0ZWQKLSAgLy8gdG8gYSB2YWx1ZSBvZiB0eXBlIHN0cmluZy4KLSAgeyBFUl9DQU5UX0NPTlZFUlRfVE9fU1RSSU5HLAotICAgICAgICJYUGF0aCBcdTg4NjhcdTc5M0FcdTVGMEYgJyd7MH0nJyBcdTc2ODQgWFBhdGhSZXN1bHQgXHU1MTc3XHU2NzA5IFhQYXRoUmVzdWx0VHlwZSBcdTc2ODQgezF9XHVGRjBDXHU1QjgzXHU3MTIxXHU2Q0Q1XHU4RjQ5XHU2M0RCXHU3MEJBXHU1QjU3XHU0RTMyXHUzMDAyIn0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogRG8gbm90IHRyYW5zbGF0ZSBzbmFwc2hvdEl0ZW0sCi0gIC8vIFVOT1JERVJFRF9OT0RFX1NOQVBTSE9UX1RZUEUgYW5kIE9SREVSRURfTk9ERV9TTkFQU0hPVF9UWVBFLgotICB7IEVSX05PTl9TTkFQU0hPVF9UWVBFLAotICAgICAgICJcdTcxMjFcdTZDRDVcdTU3MjggWFBhdGggXHU4ODY4XHU3OTNBXHU1RjBGICcnezB9JycgXHU3Njg0IFhQYXRoUmVzdWx0IFx1NEUwQVx1NTQ3Q1x1NTNFQlx1NjVCOVx1NkNENSBzbmFwc2hvdEl0ZW1cdUZGMENcdTU2RTBcdTcwQkFcdTVCODNcdTc2ODQgWFBhdGhSZXN1bHRUeXBlIFx1NjYyRiB7MX1cdTMwMDJcdTZCNjRcdTY1QjlcdTZDRDVcdTUwQzVcdTkwNjlcdTc1MjhcdTY1QkNcdTk4NUVcdTU3OEIgVU5PUkRFUkVEX05PREVfU05BUFNIT1RfVFlQRSBcdTgyMDcgT1JERVJFRF9OT0RFX1NOQVBTSE9UX1RZUEVcdTMwMDIifSwKLQotICAvLyBOb3RlIHRvIHRyYW5zbGF0b3JzOiAgWFBhdGhFdmFsdWF0b3IgaXMgYSBKYXZhIGludGVyZmFjZSBuYW1lLiAgQW4KLSAgLy8gWFBhdGhFdmFsdWF0b3IgaXMgY3JlYXRlZCB3aXRoIHJlc3BlY3QgdG8gYSBwYXJ0aWN1bGFyIFhNTCBkb2N1bWVudCwgYW5kIGluCi0gIC8vIHRoaXMgY2FzZSB0aGUgZXhwcmVzc2lvbiByZXByZXNlbnRlZCBieSB0aGlzIG9iamVjdCB3YXMgYmVpbmcgZXZhbHVhdGVkIHdpdGgKLSAgLy8gcmVzcGVjdCB0byBhIGNvbnRleHQgbm9kZSBmcm9tIGEgZGlmZmVyZW50IGRvY3VtZW50LgotICB7IEVSX1dST05HX0RPQ1VNRU5ULAotICAgICAgICJcdTc2RjhcdTk1RENcdThDQzdcdThBMEFcdTc0QjBcdTU4ODNcdTdCQzBcdTlFREVcdTRFMERcdTVDNkNcdTY1QkNcdTkwMjNcdTdENTBcdTgxRjNcdTZCNjQgWFBhdGhFdmFsdWF0b3IgXHU3Njg0XHU2NTg3XHU0RUY2XHUzMDAyIn0sCi0KLSAgLy8gTm90ZSB0byB0cmFuc2xhdG9yczogIFRoZSBYUGF0aCBleHByZXNzaW9uIGNhbm5vdCBiZSBldmFsdWF0ZWQgd2l0aCByZXNwZWN0Ci0gIC8vIHRvIHRoaXMgdHlwZSBvZiBub2RlLgotICB7IEVSX1dST05HX05PREVUWVBFLAotICAgICAgICJcdTRFMERcdTY1MkZcdTYzRjRcdTc2RjhcdTk1RENcdThDQzdcdThBMEFcdTc0QjBcdTU4ODNcdTdCQzBcdTlFREVcdTk4NUVcdTU3OEJcdTMwMDIifSwKLQotICB7IEVSX1hQQVRIX0VSUk9SLAotICAgICAgICJYUGF0aCBcdTc2N0NcdTc1MUZcdTRFMERcdTY2MEVcdTc2ODRcdTkzMkZcdThBQTRcdTMwMDIifSwKLQotICB7IEVSX0NBTlRfQ09OVkVSVF9YUEFUSFJFU1VMVFRZUEVfVE9fTlVNQkVSLAotICAgICAgICAiWFBhdGggXHU4ODY4XHU3OTNBXHU1RjBGICcnezB9JycgXHU3Njg0IFhQYXRoUmVzdWx0IFx1NTE3N1x1NjcwOSBYUGF0aFJlc3VsdFR5cGUgXHU3Njg0IHsxfVx1RkYwQ1x1NUI4M1x1NzEyMVx1NkNENVx1OEY0OVx1NjNEQlx1NzBCQVx1NjU3OFx1NUI1N1x1MzAwMiJ9LAotCi0gIC8vQkVHSU46ICBEZWZpbml0aW9ucyBvZiBlcnJvciBrZXlzIHVzZWQgIGluIGV4Y2VwdGlvbiBtZXNzYWdlcyBvZiAgSkFYUCAxLjMgWFBhdGggQVBJIGltcGxlbWVudGF0aW9uCi0KLSAgLyoqIEZpZWxkIEVSX0VYVEVOU0lPTl9GVU5DVElPTl9DQU5OT1RfQkVfSU5WT0tFRCAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX0VYVEVOU0lPTl9GVU5DVElPTl9DQU5OT1RfQkVfSU5WT0tFRCwKLSAgICAgICAiXHU3NTc2IFhNTENvbnN0YW50cy5GRUFUVVJFX1NFQ1VSRV9QUk9DRVNTSU5HIFx1NTI5Rlx1ODBGRFx1OEEyRFx1NzBCQVx1NzcxRlx1NjY0Mlx1RkYwQ1x1NzEyMVx1NkNENVx1NTQ3Q1x1NTNFQlx1NjRGNFx1NTE0NVx1NTFGRFx1NjU3ODogJyd7MH0nJ1x1MzAwMiJ9LAotCi0gIC8qKiBGaWVsZCBFUl9SRVNPTFZFX1ZBUklBQkxFX1JFVFVSTlNfTlVMTCAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX1JFU09MVkVfVkFSSUFCTEVfUkVUVVJOU19OVUxMLAotICAgICAgICJcdThCOEFcdTY1NzggezB9IFx1NzY4NCByZXNvbHZlVmFyaWFibGUgXHU1MEIzXHU1NkRFXHU3QTdBXHU1MDNDIn0sCi0KLSAgLyoqIEZpZWxkIEVSX1VOU1VQUE9SVEVEX1JFVFVSTl9UWVBFICAgICAgICAgICAgICAgICAgICAgICAqLwotCi0gIHsgRVJfVU5TVVBQT1JURURfUkVUVVJOX1RZUEUsCi0gICAgICAgIlx1NEUwRFx1NjUyRlx1NjNGNFx1NzY4NFx1NTBCM1x1NTZERVx1OTg1RVx1NTc4QjogezB9In0sCi0KLSAgLyoqIEZpZWxkIEVSX1NPVVJDRV9SRVRVUk5fVFlQRV9DQU5OT1RfQkVfTlVMTCAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX1NPVVJDRV9SRVRVUk5fVFlQRV9DQU5OT1RfQkVfTlVMTCwKLSAgICAgICAiXHU0Rjg2XHU2RTkwXHU1NDhDIChcdTYyMTYpIFx1NTBCM1x1NTZERVx1OTg1RVx1NTc4Qlx1NEUwRFx1NTNFRlx1NzBCQVx1N0E3QVx1NTAzQyJ9LAotCi0gIC8qKiBGaWVsZCBFUl9TT1VSQ0VfUkVUVVJOX1RZUEVfQ0FOTk9UX0JFX05VTEwgICAgICAgICAgICAgICAgICAgICAgICovCi0KLSAgeyBFUl9TT1VSQ0VfUkVUVVJOX1RZUEVfQ0FOTk9UX0JFX05VTEwsCi0gICAgICAgIlx1NEY4Nlx1NkU5MFx1NTQ4QyAoXHU2MjE2KSBcdTUwQjNcdTU2REVcdTk4NUVcdTU3OEJcdTRFMERcdTUzRUZcdTcwQkFcdTdBN0FcdTUwM0MifSwKLQotICAvKiogRmllbGQgRVJfQVJHX0NBTk5PVF9CRV9OVUxMICAgICAgICAgICAgICAgICAgICAgICAqLwotCi0gIHsgRVJfQVJHX0NBTk5PVF9CRV9OVUxMLAotICAgICAgICJ7MH0gXHU1RjE1XHU2NTc4XHU0RTBEXHU1M0VGXHU3MEJBXHU3QTdBXHU1MDNDIn0sCi0KLSAgLyoqIEZpZWxkIEVSX09CSkVDVF9NT0RFTF9OVUxMICAgICAgICAgICAgICAgICAgICAgICAqLwotCi0gIHsgRVJfT0JKRUNUX01PREVMX05VTEwsCi0gICAgICAgInswfSNpc09iamVjdE1vZGVsU3VwcG9ydGVkKCBTdHJpbmcgb2JqZWN0TW9kZWwgKSBcdTcxMjFcdTZDRDVcdTRGN0ZcdTc1Mjggb2JqZWN0TW9kZWwgPT0gbnVsbCBcdTRGODZcdTU0N0NcdTUzRUIifSwKLQotICAvKiogRmllbGQgRVJfT0JKRUNUX01PREVMX0VNUFRZICAgICAgICAgICAgICAgICAgICAgICAqLwotCi0gIHsgRVJfT0JKRUNUX01PREVMX0VNUFRZLAotICAgICAgICJ7MH0jaXNPYmplY3RNb2RlbFN1cHBvcnRlZCggU3RyaW5nIG9iamVjdE1vZGVsICkgXHU3MTIxXHU2Q0Q1XHU0RjdGXHU3NTI4IG9iamVjdE1vZGVsID09IFwiXCIgXHU0Rjg2XHU1NDdDXHU1M0VCIn0sCi0KLSAgLyoqIEZpZWxkIEVSX09CSkVDVF9NT0RFTF9FTVBUWSAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX0ZFQVRVUkVfTkFNRV9OVUxMLAotICAgICAgICJcdTU2MTdcdThBNjZcdTRFRTVcdTdBN0FcdTUwM0NcdTU0MERcdTdBMzFcdThBMkRcdTVCOUFcdTUyOUZcdTgwRkQ6IHswfSNzZXRGZWF0dXJlKCBudWxsLCB7MX0pIn0sCi0KLSAgLyoqIEZpZWxkIEVSX0ZFQVRVUkVfVU5LTk9XTiAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX0ZFQVRVUkVfVU5LTk9XTiwKLSAgICAgICAiXHU1NjE3XHU4QTY2XHU4QTJEXHU1QjlBXHU0RTBEXHU2NjBFXHU3Njg0XHU1MjlGXHU4MEZEIFwiezB9XCI6ezF9I3NldEZlYXR1cmUoezB9LHsyfSkifSwKLQotICAvKiogRmllbGQgRVJfR0VUVElOR19OVUxMX0ZFQVRVUkUgICAgICAgICAgICAgICAgICAgICAgICovCi0KLSAgeyBFUl9HRVRUSU5HX05VTExfRkVBVFVSRSwKLSAgICAgICAiXHU1NjE3XHU4QTY2XHU0RUU1XHU3QTdBXHU1MDNDXHU1NDBEXHU3QTMxXHU1M0Q2XHU1Rjk3XHU1MjlGXHU4MEZEOiB7MH0jZ2V0RmVhdHVyZShudWxsKSJ9LAotCi0gIC8qKiBGaWVsZCBFUl9HRVRUSU5HX05VTExfRkVBVFVSRSAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX0dFVFRJTkdfVU5LTk9XTl9GRUFUVVJFLAotICAgICAgICJcdTU2MTdcdThBNjZcdTUzRDZcdTVGOTdcdTRFMERcdTY2MEVcdTc2ODRcdTUyOUZcdTgwRkQgXCJ7MH1cIjp7MX0jZ2V0RmVhdHVyZSh7MH0pIn0sCi0KLSAge0VSX1NFQ1VSRVBST0NFU1NJTkdfRkVBVFVSRSwKLSAgICAgICAgIkZFQVRVUkVfU0VDVVJFX1BST0NFU1NJTkc6IFx1NUI4OVx1NTE2OFx1N0JBMVx1NzQwNlx1N0EwQlx1NUYwRlx1NUI1OFx1NTcyOFx1NjY0Mlx1RkYwQ1x1NzEyMVx1NkNENVx1NUMwN1x1NTI5Rlx1ODBGRFx1OEEyRFx1NzBCQVx1NTA3RDogezF9I3NldEZlYXR1cmUoezB9LHsyfSkifSwKLQotICAvKiogRmllbGQgRVJfTlVMTF9YUEFUSF9GVU5DVElPTl9SRVNPTFZFUiAgICAgICAgICAgICAgICAgICAgICAgKi8KLQotICB7IEVSX05VTExfWFBBVEhfRlVOQ1RJT05fUkVTT0xWRVIsCi0gICAgICAgIlx1NTYxN1x1OEE2Nlx1OEEyRFx1NUI5QVx1N0E3QVx1NTAzQyBYUGF0aEZ1bmN0aW9uUmVzb2x2ZXI6ezB9I3NldFhQYXRoRnVuY3Rpb25SZXNvbHZlcihudWxsKSJ9LAotCi0gIC8qKiBGaWVsZCBFUl9OVUxMX1hQQVRIX1ZBUklBQkxFX1JFU09MVkVSICAgICAgICAgICAgICAgICAgICAgICAqLwotCi0gIHsgRVJfTlVMTF9YUEFUSF9WQVJJQUJMRV9SRVNPTFZFUiwKLSAgICAgICAiXHU1NjE3XHU4QTY2XHU4QTJEXHU1QjlBXHU3QTdBXHU1MDNDIFhQYXRoVmFyaWFibGVSZXNvbHZlcjp7MH0jc2V0WFBhdGhWYXJpYWJsZVJlc29sdmVyKG51bGwpIn0sCi0KLSAgLy9FTkQ6ICBEZWZpbml0aW9ucyBvZiBlcnJvciBrZXlzIHVzZWQgIGluIGV4Y2VwdGlvbiBtZXNzYWdlcyBvZiAgSkFYUCAxLjMgWFBhdGggQVBJIGltcGxlbWVudGF0aW9uCi0KLSAgLy8gV2FybmluZ3MuLi4KLQotICB7IFdHX0xPQ0FMRV9OQU1FX05PVF9IQU5ETEVELAotICAgICAgIlx1NUMxQVx1NjcyQVx1ODY1NVx1NzQwNiBmb3JtYXQtbnVtYmVyIFx1NTFGRFx1NjU3OFx1NEUyRFx1NzY4NFx1NTczMFx1NTM0MFx1OEEyRFx1NUI5QVx1NTQwRFx1N0EzMVx1RkYwMSJ9LAotCi0gIHsgV0dfUFJPUEVSVFlfTk9UX1NVUFBPUlRFRCwKLSAgICAgICJcdTRFMERcdTY1MkZcdTYzRjQgWFNMIFx1NUM2Q1x1NjAyNzogezB9In0sCi0KLSAgeyBXR19ET05UX0RPX0FOWVRISU5HX1dJVEhfTlMsCi0gICAgICAiXHU3NkVFXHU1MjREXHU0RTBEXHU2NzAzXHU4NjU1XHU3NDA2XHU1QzZDXHU2MDI3XHU0RTJEXHU3Njg0XHU1NDdEXHU1NDBEXHU3QTdBXHU5NTkzIHswfTogezF9In0sCi0KLSAgeyBXR19TRUNVUklUWV9FWENFUFRJT04sCi0gICAgICAiXHU1NjE3XHU4QTY2XHU1QjU4XHU1M0Q2IFhTTCBcdTdDRkJcdTdENzFcdTVDNkNcdTYwMjdcdTY2NDJcdTc2N0NcdTc1MUYgU2VjdXJpdHlFeGNlcHRpb246IHswfSJ9LAotCi0gIHsgV0dfUVVPX05PX0xPTkdFUl9ERUZJTkVELAotICAgICAgIlx1ODIwQVx1OEE5RVx1NkNENTogWFBhdGggXHU0RTJEXHU0RTBEXHU1MThEXHU1QjlBXHU3RkE5IHF1byguLi4pXHUzMDAyIn0sCi0KLSAgeyBXR19ORUVEX0RFUklWRURfT0JKRUNUX1RPX0lNUExFTUVOVF9OT0RFVEVTVCwKLSAgICAgICJYUGF0aCBcdTk3MDBcdTg5ODFcdTg4NERcdTc1MUZcdTc2ODRcdTcyNjlcdTRFRjZcdTRGODZcdTVCRTZcdTg4NEMgbm9kZVRlc3RcdUZGMDEifSwKLQotICB7IFdHX0ZVTkNUSU9OX1RPS0VOX05PVF9GT1VORCwKLSAgICAgICJcdTYyN0VcdTRFMERcdTUyMzBcdTUxRkRcdTY1NzhcdThBMThcdTg2NUZcdTMwMDIifSwKLQotICB7IFdHX0NPVUxETk9UX0ZJTkRfRlVOQ1RJT04sCi0gICAgICAiXHU2MjdFXHU0RTBEXHU1MjMwXHU1MUZEXHU2NTc4OiB7MH0ifSwKLQotICB7IFdHX0NBTk5PVF9NQUtFX1VSTF9GUk9NLAotICAgICAgIlx1NzEyMVx1NkNENVx1NUY5RSB7MH0gXHU1RUZBXHU3QUNCIFVSTCJ9LAotCi0gIHsgV0dfRVhQQU5EX0VOVElUSUVTX05PVF9TVVBQT1JURUQsCi0gICAgICAiRFRNIFx1NTI1Nlx1Njc5MFx1NTY2OFx1NEUwRFx1NjUyRlx1NjNGNCAtRSBcdTkwNzhcdTk4MDUifSwKLQotICB7IFdHX0lMTEVHQUxfVkFSSUFCTEVfUkVGRVJFTkNFLAotICAgICAgIlx1NzBCQVx1OEI4QVx1NjU3OFx1NjMwN1x1NUI5QVx1NzY4NCBWYXJpYWJsZVJlZmVyZW5jZSBcdThEODVcdTUxRkFcdTc2RjhcdTk1RENcdThDQzdcdThBMEFcdTc0QjBcdTU4ODNcdTYyMTZcdTZDOTJcdTY3MDlcdTVCOUFcdTdGQTlcdUZGMDFcdTU0MERcdTdBMzEgPSB7MH0ifSwKLQotICB7IFdHX1VOU1VQUE9SVEVEX0VOQ09ESU5HLAotICAgICAiXHU0RTBEXHU2NTJGXHU2M0Y0XHU3Njg0XHU3REU4XHU3OEJDOiB7MH0ifSwKLQotCi0KLSAgLy8gT3RoZXIgbWlzY2VsbGFuZW91cyB0ZXh0IHVzZWQgaW5zaWRlIHRoZSBjb2RlLi4uCi0gIHsgInVpX2xhbmd1YWdlIiwgInR3In0sCi0gIHsgImhlbHBfbGFuZ3VhZ2UiLCAidHcifSwKLSAgeyAibGFuZ3VhZ2UiLCAidHcifSwKLSAgeyAiQkFEX0NPREUiLCAiY3JlYXRlTWVzc2FnZSBcdTc2ODRcdTUzQzNcdTY1NzhcdThEODVcdTUxRkFcdTdCQzRcdTU3MEQifSwKLSAgeyAiRk9STUFUX0ZBSUxFRCIsICJtZXNzYWdlRm9ybWF0IFx1NTQ3Q1x1NTNFQlx1NjcxRlx1OTU5M1x1NzY3Q1x1NzUxRlx1NzU3MFx1NUUzOFx1NzJDMFx1NkNDMSJ9LAotICB7ICJ2ZXJzaW9uIiwgIj4+Pj4+Pj4gWGFsYW4gXHU3MjQ4XHU2NzJDICJ9LAotICB7ICJ2ZXJzaW9uMiIsICI8PDw8PDw8In0sCi0gIHsgInllcyIsICJcdTY2MkYifSwKLSAgeyAibGluZSIsICJcdTg4NENcdTg2NUYifSwKLSAgeyAiY29sdW1uIiwgIlx1OENDN1x1NjU5OVx1NkIwNFx1N0RFOFx1ODY1RiJ9LAotICB7ICJ4c2xkb25lIiwgIlhTTFByb2Nlc3NvcjogXHU1QjhDXHU2MjEwIn0sCi0gIHsgInhwYXRoX29wdGlvbiIsICJ4cGF0aCBcdTkwNzhcdTk4MDU6ICJ9LAotICB7ICJvcHRpb25JTiIsICIgICBbLWluIGlucHV0WE1MVVJMXSJ9LAotICB7ICJvcHRpb25TZWxlY3QiLCAiICAgWy1zZWxlY3QgeHBhdGggXHU4ODY4XHU3OTNBXHU1RjBGXSJ9LAotICB7ICJvcHRpb25NYXRjaCIsICIgICBbLW1hdGNoIFx1OTE0RFx1NUMwRFx1NkEyM1x1NUYwRiAoXHU5MUREXHU1QzBEXHU5MTREXHU1QzBEXHU4QTNBXHU2NUI3KV0ifSwKLSAgeyAib3B0aW9uQW55RXhwciIsICJcdTYyMTZcdTgwMDVcdUZGMENcdTUzRUFcdTY3MDkgeHBhdGggXHU4ODY4XHU3OTNBXHU1RjBGXHU2NjQyXHU1QzA3XHU5MDMyXHU4ODRDXHU4QTNBXHU2NUI3XHU1MEJFXHU1MzcwIn0sCi0gIHsgIm5vUGFyc2VybXNnMSIsICJYU0wgXHU4NjU1XHU3NDA2XHU0RjVDXHU2OTZEXHU1OTMxXHU2NTU3XHUzMDAyIn0sCi0gIHsgIm5vUGFyc2VybXNnMiIsICIqKiBcdTYyN0VcdTRFMERcdTUyMzBcdTUyNTZcdTY3OTBcdTU2NjggKioifSwKLSAgeyAibm9QYXJzZXJtc2czIiwgIlx1OEFDQlx1NkFBMlx1NjdFNVx1OTg1RVx1NTIyNVx1OERFRlx1NUY5MVx1MzAwMiJ9LAotICB7ICJub1BhcnNlcm1zZzQiLCAiXHU4MkU1XHU3MTIxIElCTSBcdTc2ODQgWE1MIFBhcnNlciBmb3IgSmF2YVx1RkYwQ1x1NTNFRlx1NEUwQlx1OEYwOVx1ODFFQSJ9LAotICB7ICJub1BhcnNlcm1zZzUiLCAiSUJNIFx1NzY4NCBBbHBoYVdvcmtzOiBodHRwOi8vd3d3LmFscGhhd29ya3MuaWJtLmNvbS9mb3JtdWxhL3htbCJ9LAotICB7ICJndG9uZSIsICI+MSIgfSwKLSAgeyAiemVybyIsICIwIiB9LAotICB7ICJvbmUiLCAiMSIgfSwKLSAgeyAidHdvIiAsICIyIiB9LAotICB7ICJ0aHJlZSIsICIzIiB9Ci0KLSAgfTsKLQotICAvKioKLSAgICogR2V0IHRoZSBhc3NvY2lhdGlvbiBsaXN0LgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBhc3NvY2lhdGlvbiBsaXN0LgotICAgKi8KLSAgcHVibGljIE9iamVjdFtdW10gZ2V0Q29udGVudHMoKQotICB7Ci0gICAgICByZXR1cm4gX2NvbnRlbnRzOwotICB9Ci0KLQotICAvLyA9PT09PT09PT09PT09PT09PSBJTkZSQVNUUlVDVFVSRSA9PT09PT09PT09PT09PT09PT09PT09Ci0KLSAgLyoqIEZpZWxkIEJBRF9DT0RFICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEJBRF9DT0RFID0gIkJBRF9DT0RFIjsKLQotICAvKiogRmllbGQgRk9STUFUX0ZBSUxFRCAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBGT1JNQVRfRkFJTEVEID0gIkZPUk1BVF9GQUlMRUQiOwotCi0gIC8qKiBGaWVsZCBFUlJPUl9SRVNPVVJDRVMgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJST1JfUkVTT1VSQ0VTID0KLSAgICAiY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLnJlcy5YUEFUSEVycm9yUmVzb3VyY2VzIjsKLQotICAvKiogRmllbGQgRVJST1JfU1RSSU5HICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUk9SX1NUUklORyA9ICIjZXJyb3IiOwotCi0gIC8qKiBGaWVsZCBFUlJPUl9IRUFERVIgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJST1JfSEVBREVSID0gIkVycm9yOiAiOwotCi0gIC8qKiBGaWVsZCBXQVJOSU5HX0hFQURFUiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXQVJOSU5HX0hFQURFUiA9ICJXYXJuaW5nOiAiOwotCi0gIC8qKiBGaWVsZCBYU0xfSEVBREVSICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFhTTF9IRUFERVIgPSAiWFNMICI7Ci0KLSAgLyoqIEZpZWxkIFhNTF9IRUFERVIgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MX0hFQURFUiA9ICJYTUwgIjsKLQotICAvKiogRmllbGQgUVVFUllfSEVBREVSICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFFVRVJZX0hFQURFUiA9ICJQQVRURVJOICI7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvcmVzL1hQQVRITWVzc2FnZXMuamF2YSBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvcmVzL1hQQVRITWVzc2FnZXMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMWQwZmU2Zi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL3Jlcy9YUEFUSE1lc3NhZ2VzLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNDkgKzAsMCBAQAotLyoKLSAqIHJlc2VydmVkIGNvbW1lbnQgYmxvY2sKLSAqIERPIE5PVCBSRU1PVkUgT1IgQUxURVIhCi0gKi8KLS8qCi0gKiBDb3B5cmlnaHQgMTk5OS0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotLyoKLSAqICRJZDogWFBBVEhNZXNzYWdlcy5qYXZhLHYgMS4yLjQuMSAyMDA1LzA5LzAxIDE0OjU3OjM0IHB2ZWR1bGEgRXhwICQKLSAqLwotcGFja2FnZSBjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucmVzOwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwudXRpbC5TZWN1cml0eVN1cHBvcnQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXMuWE1MTWVzc2FnZXM7Ci1pbXBvcnQgamF2YS51dGlsLkxpc3RSZXNvdXJjZUJ1bmRsZTsKLQotLyoqCi0gKiBBIHV0aWxpdHkgY2xhc3MgZm9yIGlzc3VpbmcgWFBhdGggZXJyb3IgbWVzc2FnZXMuCi0gKgotICogQHhzbC51c2FnZSBpbnRlcm5hbAotICovCi1wdWJsaWMgY2xhc3MgWFBBVEhNZXNzYWdlcyBleHRlbmRzIFhNTE1lc3NhZ2VzIHsKLQotICAgIC8qKgotICAgICAqIFRoZSBsYW5ndWFnZSBzcGVjaWZpYyByZXNvdXJjZSBvYmplY3QgZm9yIFhQYXRoIG1lc3NhZ2VzLgotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIExpc3RSZXNvdXJjZUJ1bmRsZSBYUEFUSEJ1bmRsZSA9IG51bGw7Ci0gICAgLyoqCi0gICAgICogVGhlIGNsYXNzIG5hbWUgb2YgdGhlIFhQYXRoIGVycm9yIG1lc3NhZ2Ugc3RyaW5nIHRhYmxlLgotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBYUEFUSF9FUlJPUl9SRVNPVVJDRVMgPQotICAgICAgICAgICAgImNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5yZXMuWFBBVEhFcnJvclJlc291cmNlcyI7Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGVzIGEgbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQga2V5IGFuZCByZXBsYWNlbWVudCBhcmd1bWVudHMsCi0gICAgICogbG9jYWxpemVkIHRvIHRoZSBnaXZlbiBsb2NhbGUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbXNnS2V5IFRoZSBrZXkgZm9yIHRoZSBtZXNzYWdlIHRleHQuCi0gICAgICogQHBhcmFtIGFyZ3MgVGhlIGFyZ3VtZW50cyB0byBiZSB1c2VkIGFzIHJlcGxhY2VtZW50IHRleHQgaW4gdGhlIG1lc3NhZ2UKLSAgICAgKiBjcmVhdGVkLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgZm9ybWF0dGVkIG1lc3NhZ2Ugc3RyaW5nLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIGNyZWF0ZVhQQVRITWVzc2FnZShTdHJpbmcgbXNnS2V5LCBPYmplY3QgYXJnc1tdKSAvL3Rocm93cyBFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGlmIChYUEFUSEJ1bmRsZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBYUEFUSEJ1bmRsZSA9IFNlY3VyaXR5U3VwcG9ydC5nZXRSZXNvdXJjZUJ1bmRsZShYUEFUSF9FUlJPUl9SRVNPVVJDRVMpOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKFhQQVRIQnVuZGxlICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBjcmVhdGVYUEFUSE1zZyhYUEFUSEJ1bmRsZSwgbXNnS2V5LCBhcmdzKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiAiQ291bGQgbm90IGxvYWQgYW55IHJlc291cmNlIGJ1bmRsZXMuIjsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIENyZWF0ZXMgYSBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCBrZXkgYW5kIHJlcGxhY2VtZW50IGFyZ3VtZW50cywKLSAgICAgKiBsb2NhbGl6ZWQgdG8gdGhlIGdpdmVuIGxvY2FsZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBtc2dLZXkgVGhlIGtleSBmb3IgdGhlIG1lc3NhZ2UgdGV4dC4KLSAgICAgKiBAcGFyYW0gYXJncyBUaGUgYXJndW1lbnRzIHRvIGJlIHVzZWQgYXMgcmVwbGFjZW1lbnQgdGV4dCBpbiB0aGUgbWVzc2FnZQotICAgICAqIGNyZWF0ZWQuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBmb3JtYXR0ZWQgd2FybmluZyBzdHJpbmcuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgY3JlYXRlWFBBVEhXYXJuaW5nKFN0cmluZyBtc2dLZXksIE9iamVjdCBhcmdzW10pIC8vdGhyb3dzIEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaWYgKFhQQVRIQnVuZGxlID09IG51bGwpIHsKLSAgICAgICAgICAgIFhQQVRIQnVuZGxlID0gU2VjdXJpdHlTdXBwb3J0LmdldFJlc291cmNlQnVuZGxlKFhQQVRIX0VSUk9SX1JFU09VUkNFUyk7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoWFBBVEhCdW5kbGUgIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZVhQQVRITXNnKFhQQVRIQnVuZGxlLCBtc2dLZXksIGFyZ3MpOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgcmV0dXJuICJDb3VsZCBub3QgbG9hZCBhbnkgcmVzb3VyY2UgYnVuZGxlcy4iOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlcyBhIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIGtleSBhbmQgcmVwbGFjZW1lbnQgYXJndW1lbnRzLAotICAgICAqIGxvY2FsaXplZCB0byB0aGUgZ2l2ZW4gbG9jYWxlLgotICAgICAqCi0gICAgICogQHBhcmFtIGZSZXNvdXJjZUJ1bmRsZSBUaGUgcmVzb3VyY2UgYnVuZGxlIHRvIHVzZS4KLSAgICAgKiBAcGFyYW0gbXNnS2V5IFRoZSBtZXNzYWdlIGtleSB0byB1c2UuCi0gICAgICogQHBhcmFtIGFyZ3MgVGhlIGFyZ3VtZW50cyB0byBiZSB1c2VkIGFzIHJlcGxhY2VtZW50IHRleHQgaW4gdGhlIG1lc3NhZ2UKLSAgICAgKiBjcmVhdGVkLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgZm9ybWF0dGVkIG1lc3NhZ2Ugc3RyaW5nLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIGNyZWF0ZVhQQVRITXNnKExpc3RSZXNvdXJjZUJ1bmRsZSBmUmVzb3VyY2VCdW5kbGUsCi0gICAgICAgICAgICBTdHJpbmcgbXNnS2V5LCBPYmplY3QgYXJnc1tdKSAvL3Rocm93cyBFeGNlcHRpb24KLSAgICB7Ci0KLSAgICAgICAgU3RyaW5nIGZtc2cgPSBudWxsOwotICAgICAgICBib29sZWFuIHRocm93ZXggPSBmYWxzZTsKLSAgICAgICAgU3RyaW5nIG1zZyA9IG51bGw7Ci0KLSAgICAgICAgaWYgKG1zZ0tleSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBtc2cgPSBmUmVzb3VyY2VCdW5kbGUuZ2V0U3RyaW5nKG1zZ0tleSk7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAobXNnID09IG51bGwpIHsKLSAgICAgICAgICAgIG1zZyA9IGZSZXNvdXJjZUJ1bmRsZS5nZXRTdHJpbmcoWFBBVEhFcnJvclJlc291cmNlcy5CQURfQ09ERSk7Ci0gICAgICAgICAgICB0aHJvd2V4ID0gdHJ1ZTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChhcmdzICE9IG51bGwpIHsKLSAgICAgICAgICAgIHRyeSB7Ci0KLSAgICAgICAgICAgICAgICAvLyBEbyB0aGlzIHRvIGtlZXAgZm9ybWF0IGZyb20gY3J5aW5nLgotICAgICAgICAgICAgICAgIC8vIFRoaXMgaXMgYmV0dGVyIHRoYW4gbWFraW5nIGEgYnVuY2ggb2YgY29uZGl0aW9uYWwKLSAgICAgICAgICAgICAgICAvLyBjb2RlIGFsbCBvdmVyIHRoZSBwbGFjZS4KLSAgICAgICAgICAgICAgICBpbnQgbiA9IGFyZ3MubGVuZ3RoOwotCi0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKG51bGwgPT0gYXJnc1tpXSkgewotICAgICAgICAgICAgICAgICAgICAgICAgYXJnc1tpXSA9ICIiOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgZm1zZyA9IGphdmEudGV4dC5NZXNzYWdlRm9ybWF0LmZvcm1hdChtc2csIGFyZ3MpOwotICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICBmbXNnID0gZlJlc291cmNlQnVuZGxlLmdldFN0cmluZyhYUEFUSEVycm9yUmVzb3VyY2VzLkZPUk1BVF9GQUlMRUQpOwotICAgICAgICAgICAgICAgIGZtc2cgKz0gIiAiICsgbXNnOwotICAgICAgICAgICAgfQotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgZm1zZyA9IG1zZzsKLSAgICAgICAgfQotCi0gICAgICAgIGlmICh0aHJvd2V4KSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihmbXNnKTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBmbXNnOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvcmVzL3BhY2thZ2UuaHRtbCBiL3NyYy9jb20vc3VuL29yZy9hcGFjaGUveHBhdGgvaW50ZXJuYWwvcmVzL3BhY2thZ2UuaHRtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggY2IyMTkwNS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi9vcmcvYXBhY2hlL3hwYXRoL2ludGVybmFsL3Jlcy9wYWNrYWdlLmh0bWwKKysrIC9kZXYvbnVsbApAQCAtMSwzMiArMCwwIEBACi0vKgotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLSAqLwotPCEtLQotICogcmVzZXJ2ZWQgY29tbWVudCBibG9jawotICogRE8gTk9UIFJFTU9WRSBPUiBBTFRFUiEKLS0tPgotPCEtLQotICogQ29weXJpZ2h0IDIwMDAtMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0tLT4KLTwhLS0gJElkOiBwYWNrYWdlLmh0bWwsdiAxLjEuMi4xIDIwMDUvMDgvMDEgMDE6Mjk6NTEgamVmZnN1dHRvciBFeHAgJCAtLT4KLTxodG1sPgotICA8dGl0bGU+WFBhdGggcmVzb3VyY2VzLjwvdGl0bGU+Ci0gIDxib2R5PgotICAgIDxwPkNvbnRhaW5zIHN0cmluZ3MgZm9yIFhQYXRoIHN1cHBvcnQgdGhhdCByZXF1aXJlIGludGVybmF0aW9uYWxpemF0aW9uLjxwPgotIDwvYm9keT4KLTwvaHRtbD4KLQotCmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL0VudGl0eS5qYXZhIGIvc3JjL2NvbS9zdW4veG1sL2ludGVybmFsL3N0cmVhbS9FbnRpdHkuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOWMyYThhZC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL0VudGl0eS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDc1ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTMsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKi8KLQotLyoKLSAqIENvcHlyaWdodCAyMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLnhtbC5pbnRlcm5hbC5zdHJlYW07Ci0KLWltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uUmVhZGVyOwotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci0KLWltcG9ydCBjb20uc3VuLnhtbC5pbnRlcm5hbC5zdHJlYW0udXRpbC5CdWZmZXJBbGxvY2F0b3I7Ci1pbXBvcnQgY29tLnN1bi54bWwuaW50ZXJuYWwuc3RyZWFtLnV0aWwuVGhyZWFkTG9jYWxCdWZmZXJBbGxvY2F0b3I7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MUmVzb3VyY2VJZGVudGlmaWVyOwotCi0vKioKLSAqIEVudGl0eSBpbmZvcm1hdGlvbi4KLSAqCi0gKiBAYXV0aG9yCi0gKi8KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBFbnRpdHkgewotCi0gICAgLy8KLSAgICAvLyBEYXRhCi0gICAgLy8KLQotICAgIC8veHh4IHdoeSBkb250IHdlIGRlY2xhcmUgdGhlIHR5cGUgb2YgZW50aXRpZXMsIGxpa2UgYXNzaWduIGludGVnZXIgZm9yIGV4dGVybmFsLyBpbnRlcm5hbCBldGMuLgotCi0gICAgLyoqIEVudGl0eSBuYW1lLiAqLwotICAgIHB1YmxpYyBTdHJpbmcgbmFtZTsKLQotICAgIC8vIHdoZXRoZXIgdGhpcyBlbnRpdHkncyBkZWNsYXJhdGlvbiB3YXMgZm91bmQgaW4gdGhlIGludGVybmFsCi0gICAgLy8gb3IgZXh0ZXJuYWwgc3Vic2V0Ci0gICAgcHVibGljIGJvb2xlYW4gaW5FeHRlcm5hbFN1YnNldDsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RydWN0b3JzCi0gICAgLy8KLQotICAgIC8qKiBEZWZhdWx0IGNvbnN0cnVjdG9yLiAqLwotICAgIHB1YmxpYyBFbnRpdHkoKSB7Ci0gICAgICAgIGNsZWFyKCk7Ci0gICAgfSAvLyA8aW5pdD4oKQotCi0gICAgLyoqIENvbnN0cnVjdHMgYW4gZW50aXR5LiAqLwotICAgIHB1YmxpYyBFbnRpdHkoU3RyaW5nIG5hbWUsIGJvb2xlYW4gaW5FeHRlcm5hbFN1YnNldCkgewotICAgICAgICB0aGlzLm5hbWUgPSBuYW1lOwotICAgICAgICB0aGlzLmluRXh0ZXJuYWxTdWJzZXQgPSBpbkV4dGVybmFsU3Vic2V0OwotICAgIH0gLy8gPGluaXQ+KFN0cmluZykKLQotICAgIC8vCi0gICAgLy8gUHVibGljIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqIFJldHVybnMgdHJ1ZSBpZiB0aGlzIGVudGl0eSB3YXMgZGVjbGFyZWQgaW4gdGhlIGV4dGVybmFsIHN1YnNldC4gKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0VudGl0eURlY2xJbkV4dGVybmFsU3Vic2V0KCkgewotICAgICAgICByZXR1cm4gaW5FeHRlcm5hbFN1YnNldDsKLSAgICB9Ci0KLSAgICAvKiogUmV0dXJucyB0cnVlIGlmIHRoaXMgaXMgYW4gZXh0ZXJuYWwgZW50aXR5LiAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGlzRXh0ZXJuYWwoKTsKLQotICAgIC8qKiBSZXR1cm5zIHRydWUgaWYgdGhpcyBpcyBhbiB1bnBhcnNlZCBlbnRpdHkuICovCi0gICAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gaXNVbnBhcnNlZCgpOwotCi0gICAgLyoqIENsZWFycyB0aGUgZW50aXR5LiAqLwotICAgIHB1YmxpYyB2b2lkIGNsZWFyKCkgewotICAgICAgICBuYW1lID0gbnVsbDsKLSAgICAgICAgaW5FeHRlcm5hbFN1YnNldCA9IGZhbHNlOwotICAgIH0gLy8gY2xlYXIoKQotCi0gICAgLyoqIFNldHMgdGhlIHZhbHVlcyBvZiB0aGUgZW50aXR5LiAqLwotICAgIHB1YmxpYyB2b2lkIHNldFZhbHVlcyhFbnRpdHkgZW50aXR5KSB7Ci0gICAgICAgIG5hbWUgPSBlbnRpdHkubmFtZTsKLSAgICAgICAgaW5FeHRlcm5hbFN1YnNldCA9IGVudGl0eS5pbkV4dGVybmFsU3Vic2V0OwotICAgIH0gLy8gc2V0VmFsdWVzKEVudGl0eSkKLQotCi0gICAgLyoqCi0gICAgICogSW50ZXJuYWwgZW50aXR5LgotICAgICAqCi0gICAgICogQGF1dGhvciBuYjEzMTE2NQotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgSW50ZXJuYWxFbnRpdHkKLSAgICAgICAgICAgIGV4dGVuZHMgRW50aXR5IHsKLQotICAgICAgICAvLwotICAgICAgICAvLyBEYXRhCi0gICAgICAgIC8vCi0KLSAgICAgICAgLyoqIFRleHQgdmFsdWUgb2YgZW50aXR5LiAqLwotICAgICAgICBwdWJsaWMgU3RyaW5nIHRleHQ7Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gQ29uc3RydWN0b3JzCi0gICAgICAgIC8vCi0KLSAgICAgICAgLyoqIERlZmF1bHQgY29uc3RydWN0b3IuICovCi0gICAgICAgIHB1YmxpYyBJbnRlcm5hbEVudGl0eSgpIHsKLSAgICAgICAgICAgIGNsZWFyKCk7Ci0gICAgICAgIH0gLy8gPGluaXQ+KCkKLQotICAgICAgICAvKiogQ29uc3RydWN0cyBhbiBpbnRlcm5hbCBlbnRpdHkuICovCi0gICAgICAgIHB1YmxpYyBJbnRlcm5hbEVudGl0eShTdHJpbmcgbmFtZSwgU3RyaW5nIHRleHQsIGJvb2xlYW4gaW5FeHRlcm5hbFN1YnNldCkgewotICAgICAgICAgICAgc3VwZXIobmFtZSxpbkV4dGVybmFsU3Vic2V0KTsKLSAgICAgICAgICAgIHRoaXMudGV4dCA9IHRleHQ7Ci0gICAgICAgIH0gLy8gPGluaXQ+KFN0cmluZyxTdHJpbmcpCi0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gRW50aXR5IG1ldGhvZHMKLSAgICAgICAgLy8KLQotICAgICAgICAvKiogUmV0dXJucyB0cnVlIGlmIHRoaXMgaXMgYW4gZXh0ZXJuYWwgZW50aXR5LiAqLwotICAgICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0V4dGVybmFsKCkgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9IC8vIGlzRXh0ZXJuYWwoKTpib29sZWFuCi0KLSAgICAgICAgLyoqIFJldHVybnMgdHJ1ZSBpZiB0aGlzIGlzIGFuIHVucGFyc2VkIGVudGl0eS4gKi8KLSAgICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNVbnBhcnNlZCgpIHsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfSAvLyBpc1VucGFyc2VkKCk6Ym9vbGVhbgotCi0gICAgICAgIC8qKiBDbGVhcnMgdGhlIGVudGl0eS4gKi8KLSAgICAgICAgcHVibGljIHZvaWQgY2xlYXIoKSB7Ci0gICAgICAgICAgICBzdXBlci5jbGVhcigpOwotICAgICAgICAgICAgdGV4dCA9IG51bGw7Ci0gICAgICAgIH0gLy8gY2xlYXIoKQotCi0gICAgICAgIC8qKiBTZXRzIHRoZSB2YWx1ZXMgb2YgdGhlIGVudGl0eS4gKi8KLSAgICAgICAgcHVibGljIHZvaWQgc2V0VmFsdWVzKEVudGl0eSBlbnRpdHkpIHsKLSAgICAgICAgICAgIHN1cGVyLnNldFZhbHVlcyhlbnRpdHkpOwotICAgICAgICAgICAgdGV4dCA9IG51bGw7Ci0gICAgICAgIH0gLy8gc2V0VmFsdWVzKEVudGl0eSkKLQotICAgICAgICAvKiogU2V0cyB0aGUgdmFsdWVzIG9mIHRoZSBlbnRpdHkuICovCi0gICAgICAgIHB1YmxpYyB2b2lkIHNldFZhbHVlcyhJbnRlcm5hbEVudGl0eSBlbnRpdHkpIHsKLSAgICAgICAgICAgIHN1cGVyLnNldFZhbHVlcyhlbnRpdHkpOwotICAgICAgICAgICAgdGV4dCA9IGVudGl0eS50ZXh0OwotICAgICAgICB9IC8vIHNldFZhbHVlcyhJbnRlcm5hbEVudGl0eSkKLQotICAgIH0gLy8gY2xhc3MgSW50ZXJuYWxFbnRpdHkKLQotICAgIC8qKgotICAgICAqIEV4dGVybmFsIGVudGl0eS4KLSAgICAgKgotICAgICAqIEBhdXRob3IgbmIxMzExNjUKLSAgICAgKi8KLSAgICBwdWJsaWMgIHN0YXRpYyBjbGFzcyBFeHRlcm5hbEVudGl0eQotICAgICAgICAgICAgZXh0ZW5kcyBFbnRpdHkgewotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIERhdGEKLSAgICAgICAgLy8KLQotICAgICAgICAvKiogY29udGFpbmVyIGZvciBhbGwgcmVsZXZhbnQgZW50aXR5IGxvY2F0aW9uIGluZm9ybWF0aW9uLiAqLwotICAgICAgICBwdWJsaWMgWE1MUmVzb3VyY2VJZGVudGlmaWVyIGVudGl0eUxvY2F0aW9uOwotCi0gICAgICAgIC8qKiBOb3RhdGlvbiBuYW1lIGZvciB1bnBhcnNlZCBlbnRpdHkuICovCi0gICAgICAgIHB1YmxpYyBTdHJpbmcgbm90YXRpb247Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gQ29uc3RydWN0b3JzCi0gICAgICAgIC8vCi0KLSAgICAgICAgLyoqIERlZmF1bHQgY29uc3RydWN0b3IuICovCi0gICAgICAgIHB1YmxpYyBFeHRlcm5hbEVudGl0eSgpIHsKLSAgICAgICAgICAgIGNsZWFyKCk7Ci0gICAgICAgIH0gLy8gPGluaXQ+KCkKLQotICAgICAgICAvKiogQ29uc3RydWN0cyBhbiBpbnRlcm5hbCBlbnRpdHkuICovCi0gICAgICAgIHB1YmxpYyBFeHRlcm5hbEVudGl0eShTdHJpbmcgbmFtZSwgWE1MUmVzb3VyY2VJZGVudGlmaWVyIGVudGl0eUxvY2F0aW9uLAotICAgICAgICAgICAgICAgIFN0cmluZyBub3RhdGlvbiwgYm9vbGVhbiBpbkV4dGVybmFsU3Vic2V0KSB7Ci0gICAgICAgICAgICBzdXBlcihuYW1lLGluRXh0ZXJuYWxTdWJzZXQpOwotICAgICAgICAgICAgdGhpcy5lbnRpdHlMb2NhdGlvbiA9IGVudGl0eUxvY2F0aW9uOwotICAgICAgICAgICAgdGhpcy5ub3RhdGlvbiA9IG5vdGF0aW9uOwotICAgICAgICB9IC8vIDxpbml0PihTdHJpbmcsWE1MUmVzb3VyY2VJZGVudGlmaWVyLCBTdHJpbmcpCi0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gRW50aXR5IG1ldGhvZHMKLSAgICAgICAgLy8KLQotICAgICAgICAvKiogUmV0dXJucyB0cnVlIGlmIHRoaXMgaXMgYW4gZXh0ZXJuYWwgZW50aXR5LiAqLwotICAgICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0V4dGVybmFsKCkgewotICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgIH0gLy8gaXNFeHRlcm5hbCgpOmJvb2xlYW4KLQotICAgICAgICAvKiogUmV0dXJucyB0cnVlIGlmIHRoaXMgaXMgYW4gdW5wYXJzZWQgZW50aXR5LiAqLwotICAgICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc1VucGFyc2VkKCkgewotICAgICAgICAgICAgcmV0dXJuIG5vdGF0aW9uICE9IG51bGw7Ci0gICAgICAgIH0gLy8gaXNVbnBhcnNlZCgpOmJvb2xlYW4KLQotICAgICAgICAvKiogQ2xlYXJzIHRoZSBlbnRpdHkuICovCi0gICAgICAgIHB1YmxpYyB2b2lkIGNsZWFyKCkgewotICAgICAgICAgICAgc3VwZXIuY2xlYXIoKTsKLSAgICAgICAgICAgIGVudGl0eUxvY2F0aW9uID0gbnVsbDsKLSAgICAgICAgICAgIG5vdGF0aW9uID0gbnVsbDsKLSAgICAgICAgfSAvLyBjbGVhcigpCi0KLSAgICAgICAgLyoqIFNldHMgdGhlIHZhbHVlcyBvZiB0aGUgZW50aXR5LiAqLwotICAgICAgICBwdWJsaWMgdm9pZCBzZXRWYWx1ZXMoRW50aXR5IGVudGl0eSkgewotICAgICAgICAgICAgc3VwZXIuc2V0VmFsdWVzKGVudGl0eSk7Ci0gICAgICAgICAgICBlbnRpdHlMb2NhdGlvbiA9IG51bGw7Ci0gICAgICAgICAgICBub3RhdGlvbiA9IG51bGw7Ci0gICAgICAgIH0gLy8gc2V0VmFsdWVzKEVudGl0eSkKLQotICAgICAgICAvKiogU2V0cyB0aGUgdmFsdWVzIG9mIHRoZSBlbnRpdHkuICovCi0gICAgICAgIHB1YmxpYyB2b2lkIHNldFZhbHVlcyhFeHRlcm5hbEVudGl0eSBlbnRpdHkpIHsKLSAgICAgICAgICAgIHN1cGVyLnNldFZhbHVlcyhlbnRpdHkpOwotICAgICAgICAgICAgZW50aXR5TG9jYXRpb24gPSBlbnRpdHkuZW50aXR5TG9jYXRpb247Ci0gICAgICAgICAgICBub3RhdGlvbiA9IGVudGl0eS5ub3RhdGlvbjsKLSAgICAgICAgfSAvLyBzZXRWYWx1ZXMoRXh0ZXJuYWxFbnRpdHkpCi0KLSAgICB9IC8vIGNsYXNzIEV4dGVybmFsRW50aXR5Ci0KLSAgICAvKioKLSAgICAgKiBFbnRpdHkgc3RhdGUuCi0gICAgICoKLSAgICAgKiBAYXV0aG9yIG5iMTMxMTY1Ci0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBjbGFzcyBTY2FubmVkRW50aXR5Ci0gICAgICAgICAgICBleHRlbmRzIEVudGl0eSB7Ci0KLQotICAgICAgICAvKiogRGVmYXVsdCBidWZmZXIgc2l6ZSAoNDA5NikuICovCi0gICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFRkFVTFRfQlVGRkVSX1NJWkUgPSA4MTkyOwotICAgICAgICAvLzQwOTY7Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIEJ1ZmZlciBzaXplLiBXZSBnZXQgdGhpcyB2YWx1ZSBmcm9tIGEgcHJvcGVydHkuIFRoZSBkZWZhdWx0IHNpemUKLSAgICAgICAgICogaXMgdXNlZCBpZiB0aGUgaW5wdXQgYnVmZmVyIHNpemUgcHJvcGVydHkgaXMgbm90IHNwZWNpZmllZC4KLSAgICAgICAgICogUkVWSVNJVDogZG8gd2UgbmVlZCBhIHByb3BlcnR5IGZvciBpbnRlcm5hbCBlbnRpdHkgYnVmZmVyIHNpemU/Ci0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgaW50IGZCdWZmZXJTaXplID0gREVGQVVMVF9CVUZGRVJfU0laRTsKLQotICAgICAgICAvKiogRGVmYXVsdCBidWZmZXIgc2l6ZSBiZWZvcmUgd2UndmUgZmluaXNoZWQgd2l0aCB0aGUgWE1MRGVjbDogICovCi0gICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFRkFVTFRfWE1MREVDTF9CVUZGRVJfU0laRSA9IDI4OwotCi0gICAgICAgIC8qKiBEZWZhdWx0IGludGVybmFsIGVudGl0eSBidWZmZXIgc2l6ZSAoMTAyNCkuICovCi0gICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFRkFVTFRfSU5URVJOQUxfQlVGRkVSX1NJWkUgPSAxMDI0OwotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIERhdGEKLSAgICAgICAgLy8KLQotICAgICAgICAvLyBpL28KLQotICAgICAgICAvKiogWFhYIGxldCB0aGVzZSBmaWVsZCByZW1haW4gcHVibGljIHJpZ2h0IG5vdywgdGhvdWdoIHdlIGhhdmUgZGVmaW5lZCBtZXRob2RzIGZvciB0aGVtLgotICAgICAgICAgKiBJbnB1dCBzdHJlYW0uICovCi0gICAgICAgIHB1YmxpYyBJbnB1dFN0cmVhbSBzdHJlYW07Ci0KLSAgICAgICAgLyoqIFhYWCBsZXQgdGhlc2UgZmllbGQgcmVtYWluIHB1YmxpYyByaWdodCBub3csIHRob3VnaCB3ZSBoYXZlIGRlZmluZWQgbWV0aG9kcyBmb3IgdGhlbS4KLSAgICAgICAgICogUmVhZGVyLiAqLwotICAgICAgICBwdWJsaWMgUmVhZGVyIHJlYWRlcjsKLQotICAgICAgICAvLyBsb2NhdG9yIGluZm9ybWF0aW9uCi0KLSAgICAgICAgLyoqIGVudGl0eSBsb2NhdGlvbiBpbmZvcm1hdGlvbiAqLwotICAgICAgICBwdWJsaWMgWE1MUmVzb3VyY2VJZGVudGlmaWVyIGVudGl0eUxvY2F0aW9uOwotCi0gICAgICAgIC8vIGVuY29kaW5nCi0KLSAgICAgICAgLyoqIEF1dG8tZGV0ZWN0ZWQgZW5jb2RpbmcuICovCi0gICAgICAgIHB1YmxpYyBTdHJpbmcgZW5jb2Rpbmc7Ci0KLSAgICAgICAgLy8gc3RhdHVzCi0KLSAgICAgICAgLyoqIFRydWUgaWYgaW4gYSBsaXRlcmFsLiAgKi8KLSAgICAgICAgcHVibGljIGJvb2xlYW4gbGl0ZXJhbDsKLQotICAgICAgICAvLyB3aGV0aGVyIHRoaXMgaXMgYW4gZXh0ZXJuYWwgb3IgaW50ZXJuYWwgc2Nhbm5lZCBlbnRpdHkKLSAgICAgICAgcHVibGljIGJvb2xlYW4gaXNFeHRlcm5hbDsKLQotICAgICAgICAvL2VhY2ggJ2V4dGVybmFsJyBwYXJzZWQgZW50aXR5IG1heSBoYXZlIHhtbC90ZXh0IGRlY2xhcmF0aW9uIGNvbnRhaW5pbmcgdmVyc2lvbiBpbmZvcm1hdGlvbgotICAgICAgICBwdWJsaWMgU3RyaW5nICB2ZXJzaW9uIDsKLQotICAgICAgICAvLyBidWZmZXIKLQotICAgICAgICAvKiogQ2hhcmFjdGVyIGJ1ZmZlci4gKi8KLSAgICAgICAgcHVibGljIGNoYXJbXSBjaCA9IG51bGw7Ci0KLSAgICAgICAgLyoqIFBvc2l0aW9uIGluIGNoYXJhY3RlciBidWZmZXIgYXQgYW55IHBvaW50IG9mIHRpbWUuICovCi0gICAgICAgIHB1YmxpYyBpbnQgcG9zaXRpb247Ci0KLSAgICAgICAgLyoqIENvdW50IG9mIGNoYXJhY3RlcnMgcHJlc2VudCBpbiBidWZmZXIuICovCi0gICAgICAgIHB1YmxpYyBpbnQgY291bnQ7Ci0KLSAgICAgICAgLyoqIExpbmUgbnVtYmVyLiAqLwotICAgICAgICBwdWJsaWMgaW50IGxpbmVOdW1iZXIgPSAxOwotCi0gICAgICAgIC8qKiBDb2x1bW4gbnVtYmVyLiAqLwotICAgICAgICBwdWJsaWMgaW50IGNvbHVtbk51bWJlciA9IDE7Ci0KLSAgICAgICAgLyoqIEVuY29kaW5nIGhhcyBiZWVuIHNldCBleHRlcm5hbGx5IGZvciBlZzogdXNpbmcgRE9NSW5wdXQqLwotICAgICAgICBib29sZWFuIGRlY2xhcmVkRW5jb2RpbmcgPSBmYWxzZTsKLQotICAgICAgICAvLyBzdGF0dXMKLQotICAgICAgICAvKioKLSAgICAgICAgICogRW5jb2RpbmcgaGFzIGJlZW4gc2V0IGV4dGVybmFsbHksIGZvciBleGFtcGxlCi0gICAgICAgICAqIHVzaW5nIGEgU0FYIElucHV0U291cmNlIG9yIGEgRE9NIExTSW5wdXQuCi0gICAgICAgICAqLwotICAgICAgICBib29sZWFuIGV4dGVybmFsbHlTcGVjaWZpZWRFbmNvZGluZyA9IGZhbHNlOwotCi0gICAgICAgIC8qKiBYTUwgdmVyc2lvbi4gKiovCi0gICAgICAgIHB1YmxpYyBTdHJpbmcgeG1sVmVyc2lvbiA9ICIxLjAiOwotCi0gICAgICAgIC8qKiBUaGlzIHZhcmlhYmxlIGlzIHVzZWQgdG8gY2FsY3VsYXRlIHRoZSBjdXJyZW50IHBvc2l0aW9uIGluIHRoZSBYTUwgc3RyZWFtLgotICAgICAgICAgKiBOb3RlIHRoYXQgZkN1cnJlbnRFbnRpdHkucG9zaXRpb24gbWFpbnRhaW5zIHRoZSBwb3NpdGlvbiByZWxhdGl2ZSB0bwotICAgICAgICAgKiB0aGUgYnVmZmVyLgotICAgICAgICAgKiAgQXQgYW55IHBvaW50IG9mIHRpbWUgYWJzb2x1dGUgcG9zaXRpb24gaW4gdGhlIFhNTCBzdHJlYW0gY2FuIGJlIGNhbGN1bGF0ZWQKLSAgICAgICAgICogIGFzIGZUb3RhbENvdW50VGlsbExhc3RMb2FkICsgZkN1cnJlbnRFbnRpdHkucG9zaXRpb24KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBpbnQgZlRvdGFsQ291bnRUaWxsTGFzdExvYWQgOwotCi0gICAgICAgIC8qKiBUaGlzIHZhcmlhYmxlIHN0b3JlcyB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgcmVhZCBkdXJpbmcgdGhlIGxvYWQoKQotICAgICAgICAgKiBvcGVyYXRpb24uIEl0IGlzIHVzZWQgdG8gY2FsY3VsYXRlIGZUb3RhbENvdW50VGlsbExhc3RMb2FkCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgIGludCBmTGFzdENvdW50IDsKLQotICAgICAgICAvKiogQmFzZSBjaGFyYWN0ZXIgb2Zmc2V0IGZvciBjb21wdXRpbmcgYWJzb2x1dGUgY2hhcmFjdGVyIG9mZnNldC4gKi8KLSAgICAgICAgcHVibGljIGludCBiYXNlQ2hhck9mZnNldDsKLQotICAgICAgICAvKiogU3RhcnQgcG9zaXRpb24gaW4gY2hhcmFjdGVyIGJ1ZmZlci4gKi8KLSAgICAgICAgcHVibGljIGludCBzdGFydFBvc2l0aW9uOwotCi0gICAgICAgIC8vIHRvIGFsbG93IHRoZSByZWFkZXIvaW5wdXRTdHJlYW0gdG8gYmVoYXZlIGVmZmljaWVudGx5OgotICAgICAgICBwdWJsaWMgYm9vbGVhbiBtYXlSZWFkQ2h1bmtzOwotCi0gICAgICAgIC8vIHRvIGtub3cgdGhhdCBwcm9sb2cgaXMgcmVhZAotICAgICAgICBwdWJsaWMgYm9vbGVhbiB4bWxEZWNsQ2h1bmtSZWFkID0gZmFsc2U7Ci0KLSAgICAgICAgLy8gZmxhZyB0byBpbmRpY2F0ZSB3aGV0aGVyIHRoZSBFbnRpdHkgaXMgYSBHZW5lcmFsIEVudGl0eQotICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc0dFID0gZmFsc2U7Ci0KLSAgICAgICAgLyoqIHJldHVybnMgdGhlIG5hbWUgb2YgdGhlIGN1cnJlbnQgZW5jb2RpbmcKLSAgICAgICAgICogIEByZXR1cm4gY3VycmVudCBlbmNvZGluZyBuYW1lCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgU3RyaW5nIGdldEVuY29kaW5nTmFtZSgpewotICAgICAgICAgICAgcmV0dXJuIGVuY29kaW5nIDsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKmVhY2ggJ2V4dGVybmFsJyBwYXJzZWQgZW50aXR5IG1heSBoYXZlIHhtbC90ZXh0IGRlY2xhcmF0aW9uIGNvbnRhaW5pbmcgdmVyc2lvbiBpbmZvcm1hdGlvbgotICAgICAgICAgKiBAcmV0dXJuIFN0cmluZyB2ZXJzaW9uIG9mIHRoZSBlbml0eSwgZm9yIGFuIGludGVybmFsIGVudGl0eSB2ZXJzaW9uIHdvdWxkIGJlIG51bGwKLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0RW50aXR5VmVyc2lvbigpewotICAgICAgICAgICAgcmV0dXJuIHZlcnNpb24gOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqIGVhY2ggJ2V4dGVybmFsJyBwYXJzZWQgZW50aXR5IG1heSBoYXZlIHhtbC90ZXh0IGRlY2xhcmF0aW9uIGNvbnRhaW5pbmcgdmVyc2lvbiBpbmZvcm1hdGlvbgotICAgICAgICAgKiBAcGFyYW0gU3RyaW5nIHZlcnNpb24gb2YgdGhlIGV4dGVybmFsIHBhcnNlZCBlbnRpdHkKLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyB2b2lkIHNldEVudGl0eVZlcnNpb24oU3RyaW5nIHZlcnNpb24pewotICAgICAgICAgICAgdGhpcy52ZXJzaW9uID0gdmVyc2lvbiA7Ci0gICAgICAgIH0KLQotICAgICAgICAvKiogIFJldHVybnMgdGhlIGphdmEuaW8uUmVhZGVyIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGVudGl0eS5SZWFkZXJzIGFyZSB1c2VkCi0gICAgICAgICAqIHRvIHJlYWQgZnJvbSB0aGUgZmlsZS4gUmVhZGVycyB3cmFwIGFueSBwYXJ0aWN1bGFyICBJbnB1dFN0cmVhbSB0aGF0IHdhcwotICAgICAgICAgKiB1c2VkIHRvIG9wZW4gdGhlIGVudGl0eS4KLSAgICAgICAgICogQHJldHVybiBqYXZhLmlvLlJlYWRlciBSZWFkZXIgYXNzb2NpYXRlZCB3aXRoIHRoaXMgZW50aXR5Ci0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgUmVhZGVyIGdldEVudGl0eVJlYWRlcigpewotICAgICAgICAgICAgcmV0dXJuIHJlYWRlcjsKLSAgICAgICAgfQotCi0KLSAgICAgICAgLyoqIGlmIGVudGl0eSB3YXMgb3BlbmVkIHVzaW5nIHRoZSBzdHJlYW0sIHJldHVybiB0aGUgYXNzb2NpYXRlZCBpbnB1dHN0cmVhbQotICAgICAgICAgKiB3aXRoIHRoaXMgZW50aXR5Ci0gICAgICAgICAqQHJldHVybiBqYXZhLmlvLklucHV0U3RyZWFtIElucHV0U3RyZWFtIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGVudGl0eQotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIElucHV0U3RyZWFtIGdldEVudGl0eUlucHV0U3RyZWFtKCl7Ci0gICAgICAgICAgICByZXR1cm4gc3RyZWFtOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gQ29uc3RydWN0b3JzCi0gICAgICAgIC8vCi0KLSAgICAgICAgLyoqIENvbnN0cnVjdHMgYSBzY2FubmVkIGVudGl0eS4gKi8KLSAgICAgICAgcHVibGljIFNjYW5uZWRFbnRpdHkoYm9vbGVhbiBpc0dFLCBTdHJpbmcgbmFtZSwKLSAgICAgICAgICAgICAgICBYTUxSZXNvdXJjZUlkZW50aWZpZXIgZW50aXR5TG9jYXRpb24sCi0gICAgICAgICAgICAgICAgSW5wdXRTdHJlYW0gc3RyZWFtLCBSZWFkZXIgcmVhZGVyLAotICAgICAgICAgICAgICAgIFN0cmluZyBlbmNvZGluZywgYm9vbGVhbiBsaXRlcmFsLCBib29sZWFuIG1heVJlYWRDaHVua3MsIGJvb2xlYW4gaXNFeHRlcm5hbCkgewotICAgICAgICAgICAgdGhpcy5pc0dFID0gaXNHRTsKLSAgICAgICAgICAgIHRoaXMubmFtZSA9IG5hbWUgOwotICAgICAgICAgICAgdGhpcy5lbnRpdHlMb2NhdGlvbiA9IGVudGl0eUxvY2F0aW9uOwotICAgICAgICAgICAgdGhpcy5zdHJlYW0gPSBzdHJlYW07Ci0gICAgICAgICAgICB0aGlzLnJlYWRlciA9IHJlYWRlcjsKLSAgICAgICAgICAgIHRoaXMuZW5jb2RpbmcgPSBlbmNvZGluZzsKLSAgICAgICAgICAgIHRoaXMubGl0ZXJhbCA9IGxpdGVyYWw7Ci0gICAgICAgICAgICB0aGlzLm1heVJlYWRDaHVua3MgPSBtYXlSZWFkQ2h1bmtzOwotICAgICAgICAgICAgdGhpcy5pc0V4dGVybmFsID0gaXNFeHRlcm5hbDsKLSAgICAgICAgICAgIGZpbmFsIGludCBzaXplID0gaXNFeHRlcm5hbCA/IGZCdWZmZXJTaXplIDogREVGQVVMVF9JTlRFUk5BTF9CVUZGRVJfU0laRTsKLSAgICAgICAgICAgIEJ1ZmZlckFsbG9jYXRvciBiYSA9IFRocmVhZExvY2FsQnVmZmVyQWxsb2NhdG9yLmdldEJ1ZmZlckFsbG9jYXRvcigpOwotICAgICAgICAgICAgY2ggPSBiYS5nZXRDaGFyQnVmZmVyKHNpemUpOwotICAgICAgICAgICAgaWYgKGNoID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICB0aGlzLmNoID0gbmV3IGNoYXJbc2l6ZV07Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gLy8gPGluaXQ+KFN0cmluZ1hNTFJlc291cmNlSWRlbnRpZmllcixJbnB1dFN0cmVhbSxSZWFkZXIsU3RyaW5nLGJvb2xlYW4sIGJvb2xlYW4pCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFJlbGVhc2UgYW55IHJlc291cmNlcyBhc3NvY2lhdGVkIHdpdGggdGhpcyBlbnRpdHkuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgICAgICBCdWZmZXJBbGxvY2F0b3IgYmEgPSBUaHJlYWRMb2NhbEJ1ZmZlckFsbG9jYXRvci5nZXRCdWZmZXJBbGxvY2F0b3IoKTsKLSAgICAgICAgICAgIGJhLnJldHVybkNoYXJCdWZmZXIoY2gpOwotICAgICAgICAgICAgY2ggPSBudWxsOwotICAgICAgICAgICAgcmVhZGVyLmNsb3NlKCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLwotICAgICAgICAvLyBFbnRpdHkgbWV0aG9kcwotICAgICAgICAvLwotCi0gICAgICAgIC8qKiBSZXR1cm5zIHdoZXRoZXIgdGhlIGVuY29kaW5nIG9mIHRoaXMgZW50aXR5IHdhcyBleHRlcm5hbGx5IHNwZWNpZmllZC4gKiovCi0gICAgICAgIHB1YmxpYyBib29sZWFuIGlzRW5jb2RpbmdFeHRlcm5hbGx5U3BlY2lmaWVkKCkgewotICAgICAgICAgICAgcmV0dXJuIGV4dGVybmFsbHlTcGVjaWZpZWRFbmNvZGluZzsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKiBTZXRzIHdoZXRoZXIgdGhlIGVuY29kaW5nIG9mIHRoaXMgZW50aXR5IHdhcyBleHRlcm5hbGx5IHNwZWNpZmllZC4gKiovCi0gICAgICAgIHB1YmxpYyB2b2lkIHNldEVuY29kaW5nRXh0ZXJuYWxseVNwZWNpZmllZChib29sZWFuIHZhbHVlKSB7Ci0gICAgICAgICAgICBleHRlcm5hbGx5U3BlY2lmaWVkRW5jb2RpbmcgPSB2YWx1ZTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyBib29sZWFuIGlzRGVjbGFyZWRFbmNvZGluZygpIHsKLSAgICAgICAgICAgIHJldHVybiBkZWNsYXJlZEVuY29kaW5nOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIHZvaWQgc2V0RGVjbGFyZWRFbmNvZGluZyhib29sZWFuIHZhbHVlKSB7Ci0gICAgICAgICAgICBkZWNsYXJlZEVuY29kaW5nID0gdmFsdWU7Ci0gICAgICAgIH0KLQotICAgICAgICAvKiogUmV0dXJucyB0cnVlIGlmIHRoaXMgaXMgYW4gZXh0ZXJuYWwgZW50aXR5LiAqLwotICAgICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0V4dGVybmFsKCkgewotICAgICAgICAgICAgcmV0dXJuIGlzRXh0ZXJuYWw7Ci0gICAgICAgIH0gLy8gaXNFeHRlcm5hbCgpOmJvb2xlYW4KLQotICAgICAgICAvKiogUmV0dXJucyB0cnVlIGlmIHRoaXMgaXMgYW4gdW5wYXJzZWQgZW50aXR5LiAqLwotICAgICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc1VucGFyc2VkKCkgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9IC8vIGlzVW5wYXJzZWQoKTpib29sZWFuCi0KLSAgICAgICAgLy8KLSAgICAgICAgLy8gT2JqZWN0IG1ldGhvZHMKLSAgICAgICAgLy8KLQotICAgICAgICAvKiogUmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIG9iamVjdC4gKi8KLSAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKLQotICAgICAgICAgICAgU3RyaW5nQnVmZmVyIHN0ciA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLSAgICAgICAgICAgIHN0ci5hcHBlbmQoIm5hbWU9XCIiK25hbWUrJyInKTsKLSAgICAgICAgICAgIHN0ci5hcHBlbmQoIixjaD0iKyBuZXcgU3RyaW5nKGNoKSk7Ci0gICAgICAgICAgICBzdHIuYXBwZW5kKCIscG9zaXRpb249Iitwb3NpdGlvbik7Ci0gICAgICAgICAgICBzdHIuYXBwZW5kKCIsY291bnQ9Iitjb3VudCk7Ci0gICAgICAgICAgICByZXR1cm4gc3RyLnRvU3RyaW5nKCk7Ci0KLSAgICAgICAgfSAvLyB0b1N0cmluZygpOlN0cmluZwotCi0gICAgfSAvLyBjbGFzcyBTY2FubmVkRW50aXR5Ci0KLX0gLy8gY2xhc3MgRW50aXR5CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL0V2ZW50RmlsdGVyU3VwcG9ydC5qYXZhIGIvc3JjL2NvbS9zdW4veG1sL2ludGVybmFsL3N0cmVhbS9FdmVudEZpbHRlclN1cHBvcnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNmMzNTRhNS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL0V2ZW50RmlsdGVyU3VwcG9ydC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTExICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi54bWwuaW50ZXJuYWwuc3RyZWFtOwotCi1pbXBvcnQgamF2YS51dGlsLk5vU3VjaEVsZW1lbnRFeGNlcHRpb247Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5FdmVudEZpbHRlcjsKLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLlhNTEV2ZW50UmVhZGVyOwotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uWE1MU3RyZWFtRXhjZXB0aW9uOwotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uZXZlbnRzLlhNTEV2ZW50OwotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0udXRpbC5FdmVudFJlYWRlckRlbGVnYXRlOwotCi0vKioKLSAqCi0gKiBAYXV0aG9yICBOZWVyYWogQmFqYWosIFN1biBNaWNyb3N5c3RlbXMKLSAqCi0gKi8KLXB1YmxpYyBjbGFzcyBFdmVudEZpbHRlclN1cHBvcnQgZXh0ZW5kcyBFdmVudFJlYWRlckRlbGVnYXRlIHsKLQotICAgIC8vbWFpbnRhaW4gYSByZWZlcmVuY2UgdG8gRXZlbnRGaWx0ZXIKLSAgICBFdmVudEZpbHRlciBmRXZlbnRGaWx0ZXIgOwotICAgIC8qKiBDcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIEV2ZW50RmlsdGVyU3VwcG9ydCAqLwotICAgIHB1YmxpYyBFdmVudEZpbHRlclN1cHBvcnQoWE1MRXZlbnRSZWFkZXIgZXZlbnRSZWFkZXIsIEV2ZW50RmlsdGVyIGV2ZW50RmlsdGVyKSB7Ci0gICAgICAgIHNldFBhcmVudChldmVudFJlYWRlcik7Ci0gICAgICAgIGZFdmVudEZpbHRlciA9IGV2ZW50RmlsdGVyOwotICAgIH0KLQotICAgIHB1YmxpYyBPYmplY3QgbmV4dCgpewotICAgICAgICB0cnl7Ci0gICAgICAgICAgICByZXR1cm4gbmV4dEV2ZW50KCk7Ci0gICAgICAgIH1jYXRjaChYTUxTdHJlYW1FeGNlcHRpb24gZXgpewotICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGhhc05leHQoKXsKLSAgICAgICAgdHJ5ewotICAgICAgICAgICAgcmV0dXJuIHBlZWsoKSAhPSBudWxsID8gdHJ1ZSA6IGZhbHNlIDsKLSAgICAgICAgfWNhdGNoKFhNTFN0cmVhbUV4Y2VwdGlvbiBleCl7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgWE1MRXZlbnQgbmV4dEV2ZW50KCl0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uewotICAgICAgICBpZihzdXBlci5oYXNOZXh0KCkpewotICAgICAgICAgICAgLy9nZXQgdGhlIG5leHQgZXZlbnQgYnkgY2FsbGluZyBYTUxFdmVudFJlYWRlcgotICAgICAgICAgICAgWE1MRXZlbnQgZXZlbnQgPSBzdXBlci5uZXh0RXZlbnQoKTsKLQotICAgICAgICAgICAgLy9pZiB0aGlzIGZpbHRlciBhY2NlcHRzIHRoaXMgZXZlbnQgdGhlbiByZXR1cm4gdGhpcyBldmVudAotICAgICAgICAgICAgaWYoZkV2ZW50RmlsdGVyLmFjY2VwdChldmVudCkpewotICAgICAgICAgICAgICAgIHJldHVybiBldmVudDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2V7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIG5leHRFdmVudCgpOwotICAgICAgICAgICAgfQotICAgICAgICB9ZWxzZXsKLSAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uKCk7Ci0gICAgICAgIH0KLSAgICB9Ly9uZXh0RXZlbnQoKQotCi0gICAgIHB1YmxpYyBYTUxFdmVudCBuZXh0VGFnKCkgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbnsKLSAgICAgICAgIGlmKHN1cGVyLmhhc05leHQoKSl7Ci0gICAgICAgICAgICAgWE1MRXZlbnQgZXZlbnQgPSBzdXBlci5uZXh0VGFnKCk7Ci0gICAgICAgICAgICAgLy9pZiB0aGUgZmlsdGVyIGFjY2VwdHMgdGhpcyBldmVudCByZXR1cm4gdGhpcyBldmVudC4KLSAgICAgICAgICAgICBpZihmRXZlbnRGaWx0ZXIuYWNjZXB0KGV2ZW50KSl7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGV2ZW50OwotICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICBlbHNlewotICAgICAgICAgICAgICAgIHJldHVybiBuZXh0VGFnKCk7Ci0gICAgICAgICAgICAgfQotICAgICAgICAgfWVsc2V7Ci0gICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oKTsKLSAgICAgICAgIH0KLSAgICAgfQotCi0gICAgIHB1YmxpYyBYTUxFdmVudCBwZWVrKCkgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbnsKLSAgICAgICAgIHdoaWxlICh0cnVlKSB7Ci0gICAgICAgICAgICAgWE1MRXZlbnQgZXZlbnQgPSBzdXBlci5wZWVrKCk7Ci0gICAgICAgICAgICAgaWYoZXZlbnQgPT0gbnVsbClyZXR1cm4gbnVsbDsKLSAgICAgICAgICAgICAvL2lmIHRoZSBmaWx0ZXIgYWNjZXB0cyB0aGlzIGV2ZW50IHJldHVybiB0aGlzIGV2ZW50LgotICAgICAgICAgICAgIGlmKGZFdmVudEZpbHRlci5hY2NlcHQoZXZlbnQpKXsKLSAgICAgICAgICAgICAgICByZXR1cm4gZXZlbnQ7Ci0gICAgICAgICAgICAgfQotICAgICAgICAgICAgIC8vY2FsbCBzdXBlci5uZXh0KCksIGFuZCB0aGVuIHBlZWsgYWdhaW4uCi0gICAgICAgICAgICAgc3VwZXIubmV4dCgpOwotICAgICAgICAgfQotICAgICB9Ci0KLX0vL0V2ZW50RmlsdGVyU3VwcG9ydApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4veG1sL2ludGVybmFsL3N0cmVhbS9TdGF4RW50aXR5UmVzb2x2ZXJXcmFwcGVyLmphdmEgYi9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL1N0YXhFbnRpdHlSZXNvbHZlcldyYXBwZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDFjNWQyNS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL1N0YXhFbnRpdHlSZXNvbHZlcldyYXBwZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDg0ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi54bWwuaW50ZXJuYWwuc3RyZWFtOwotCi1pbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLlhNTEV2ZW50UmVhZGVyOwotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uWE1MUmVzb2x2ZXI7Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5YTUxTdHJlYW1FeGNlcHRpb247Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5YTUxTdHJlYW1SZWFkZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MUmVzb3VyY2VJZGVudGlmaWVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhOSUV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MSW5wdXRTb3VyY2U7Ci0KLS8qKgotICoKLSAqIEBhdXRob3IgIE5lZXJhaiBCYWphagotICovCi1wdWJsaWMgY2xhc3MgU3RheEVudGl0eVJlc29sdmVyV3JhcHBlciB7Ci0KLSAgICBYTUxSZXNvbHZlciBmU3RheFJlc29sdmVyIDsKLQotICAgIC8qKiBDcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIFN0YXhFbnRpdHlSZXNvbHZlcldyYXBwZXIgKi8KLSAgICBwdWJsaWMgU3RheEVudGl0eVJlc29sdmVyV3JhcHBlcihYTUxSZXNvbHZlciByZXNvbHZlcikgewotICAgICAgICBmU3RheFJlc29sdmVyID0gcmVzb2x2ZXIgOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldFN0YXhFbnRpdHlSZXNvbHZlcihYTUxSZXNvbHZlciByZXNvbHZlciApewotICAgICAgICBmU3RheFJlc29sdmVyID0gcmVzb2x2ZXIgOwotICAgIH0KLQotICAgIHB1YmxpYyBYTUxSZXNvbHZlciBnZXRTdGF4RW50aXR5UmVzb2x2ZXIoKXsKLSAgICAgICAgcmV0dXJuIGZTdGF4UmVzb2x2ZXIgOwotICAgIH0KLQotICAgIHB1YmxpYyBTdGF4WE1MSW5wdXRTb3VyY2UgcmVzb2x2ZUVudGl0eShYTUxSZXNvdXJjZUlkZW50aWZpZXIgcmVzb3VyY2VJZGVudGlmaWVyKQotICAgIHRocm93cyBYTklFeGNlcHRpb24sIGphdmEuaW8uSU9FeGNlcHRpb24gewotICAgICAgICBPYmplY3Qgb2JqZWN0ID0gbnVsbCA7Ci0gICAgICAgIHRyeXsKLSAgICAgICAgICAgIG9iamVjdCA9IGZTdGF4UmVzb2x2ZXIucmVzb2x2ZUVudGl0eShyZXNvdXJjZUlkZW50aWZpZXIuZ2V0UHVibGljSWQoKSwgcmVzb3VyY2VJZGVudGlmaWVyLmdldExpdGVyYWxTeXN0ZW1JZCgpLAotICAgICAgICAgICAgcmVzb3VyY2VJZGVudGlmaWVyLmdldEJhc2VTeXN0ZW1JZCgpLCBudWxsKTsKLSAgICAgICAgICAgIHJldHVybiBnZXRTdGF4SW5wdXRTb3VyY2Uob2JqZWN0KSA7Ci0gICAgICAgIH1jYXRjaChYTUxTdHJlYW1FeGNlcHRpb24gc3RyZWFtRXhjZXB0aW9uKXsKLSAgICAgICAgICAgIHRocm93IG5ldyBYTklFeGNlcHRpb24oc3RyZWFtRXhjZXB0aW9uKSA7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBTdGF4WE1MSW5wdXRTb3VyY2UgZ2V0U3RheElucHV0U291cmNlKE9iamVjdCBvYmplY3QpewotICAgICAgICBpZihvYmplY3QgPT0gbnVsbCkgcmV0dXJuIG51bGwgOwotCi0gICAgICAgIGlmKG9iamVjdCAgaW5zdGFuY2VvZiBqYXZhLmlvLklucHV0U3RyZWFtKXsKLSAgICAgICAgICAgIHJldHVybiBuZXcgU3RheFhNTElucHV0U291cmNlKG5ldyBYTUxJbnB1dFNvdXJjZShudWxsLCBudWxsLCBudWxsLCAoSW5wdXRTdHJlYW0pb2JqZWN0LCBudWxsKSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZihvYmplY3QgaW5zdGFuY2VvZiBYTUxTdHJlYW1SZWFkZXIpewotICAgICAgICAgICAgcmV0dXJuIG5ldyBTdGF4WE1MSW5wdXRTb3VyY2UoKFhNTFN0cmVhbVJlYWRlcilvYmplY3QpIDsKLSAgICAgICAgfWVsc2UgaWYob2JqZWN0IGluc3RhbmNlb2YgWE1MRXZlbnRSZWFkZXIpewotICAgICAgICAgICAgcmV0dXJuIG5ldyBTdGF4WE1MSW5wdXRTb3VyY2UoKFhNTEV2ZW50UmVhZGVyKW9iamVjdCkgOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIG51bGwgOwotICAgIH0KLX0vL2NsYXNzIFN0YXhFbnRpdHlSZXNvbHZlcldyYXBwZXIKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL3htbC9pbnRlcm5hbC9zdHJlYW0vU3RheEVycm9yUmVwb3J0ZXIuamF2YSBiL3NyYy9jb20vc3VuL3htbC9pbnRlcm5hbC9zdHJlYW0vU3RheEVycm9yUmVwb3J0ZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZTQ4YWU3Yi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL1N0YXhFcnJvclJlcG9ydGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxODcgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLnhtbC5pbnRlcm5hbC5zdHJlYW07Ci0KLQotCi1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5Mb2NhdGlvbjsKLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLlhNTElucHV0RmFjdG9yeTsKLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLlhNTFJlcG9ydGVyOwotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uWE1MU3RyZWFtRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5tc2cuWE1MTWVzc2FnZUZvcm1hdHRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuTWVzc2FnZUZvcm1hdHRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxMb2NhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhOSUV4Y2VwdGlvbjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5Qcm9wZXJ0eU1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLlhNTEVycm9yUmVwb3J0ZXI7Ci0KLS8qKgotICoKLSAqIEBhdXRob3IgIG5lZXJhagotICovCi0KLXB1YmxpYyBjbGFzcyBTdGF4RXJyb3JSZXBvcnRlciBleHRlbmRzIFhNTEVycm9yUmVwb3J0ZXIgewotCi0gICAgcHJvdGVjdGVkIFhNTFJlcG9ydGVyIGZYTUxSZXBvcnRlciA9IG51bGwgOwotCi0gICAgLyoqIENyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgU3RheEVycm9yUmVwb3J0ZXIgKi8KLSAgICBwdWJsaWMgU3RheEVycm9yUmVwb3J0ZXIoUHJvcGVydHlNYW5hZ2VyIHByb3BlcnR5TWFuYWdlcikgewotICAgICAgICBzdXBlcigpOwotICAgICAgICBwdXRNZXNzYWdlRm9ybWF0dGVyKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwgbmV3IFhNTE1lc3NhZ2VGb3JtYXR0ZXIoKSk7Ci0gICAgICAgIHJlc2V0KHByb3BlcnR5TWFuYWdlcik7Ci0gICAgfQotCi0gICAgLyoqIENyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgU3RheEVycm9yUmVwb3J0ZXIKLSAgICAgKiBJZiB0aGlzIGNvbnN0cnVjdG9yIGlzIHVzZWQgdG8gY3JlYXRlIHRoZSBvYmplY3QsIG9uZSBtdXN0IGludm9rZSByZXNldCgpIG9uIHRoaXMgb2JqZWN0LgotICAgICAqLwotICAgIHB1YmxpYyBTdGF4RXJyb3JSZXBvcnRlcigpIHsKLSAgICAgICAgc3VwZXIoKTsKLSAgICAgICAgcHV0TWVzc2FnZUZvcm1hdHRlcihYTUxNZXNzYWdlRm9ybWF0dGVyLlhNTF9ET01BSU4sIG5ldyBYTUxNZXNzYWdlRm9ybWF0dGVyKCkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqT25lIG11c3QgY2FsbCByZXNldCBiZWZvcmUgdXNpbmcgYW55IG9mIHRoZSBmdW5jdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCByZXNldChQcm9wZXJ0eU1hbmFnZXIgcHJvcGVydHlNYW5hZ2VyKXsKLSAgICAgICAgZlhNTFJlcG9ydGVyID0gKFhNTFJlcG9ydGVyKXByb3BlcnR5TWFuYWdlci5nZXRQcm9wZXJ0eShYTUxJbnB1dEZhY3RvcnkuUkVQT1JURVIpOwotICAgIH0KLSAgICAvKioKLSAgICAgKiBSZXBvcnRzIGFuIGVycm9yIGF0IGEgc3BlY2lmaWMgbG9jYXRpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbG9jYXRpb24gIFRoZSBlcnJvciBsb2NhdGlvbi4KLSAgICAgKiBAcGFyYW0gZG9tYWluICAgIFRoZSBlcnJvciBkb21haW4uCi0gICAgICogQHBhcmFtIGtleSAgICAgICBUaGUga2V5IG9mIHRoZSBlcnJvciBtZXNzYWdlLgotICAgICAqIEBwYXJhbSBhcmd1bWVudHMgVGhlIHJlcGxhY2VtZW50IGFyZ3VtZW50cyBmb3IgdGhlIGVycm9yIG1lc3NhZ2UsCi0gICAgICogICAgICAgICAgICAgICAgICBpZiBuZWVkZWQuCi0gICAgICogQHBhcmFtIHNldmVyaXR5ICBUaGUgc2V2ZXJpdHkgb2YgdGhlIGVycm9yLgotICAgICAqCi0gICAgICogQHNlZSAjU0VWRVJJVFlfV0FSTklORwotICAgICAqIEBzZWUgI1NFVkVSSVRZX0VSUk9SCi0gICAgICogQHNlZSAjU0VWRVJJVFlfRkFUQUxfRVJST1IKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIHJlcG9ydEVycm9yKFhNTExvY2F0b3IgbG9jYXRpb24sCi0gICAgU3RyaW5nIGRvbWFpbiwgU3RyaW5nIGtleSwgT2JqZWN0W10gYXJndW1lbnRzLAotICAgIHNob3J0IHNldmVyaXR5KSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgLy8gZm9ybWF0IGVycm9yIG1lc3NhZ2UgYW5kIGNyZWF0ZSBwYXJzZSBleGNlcHRpb24KLSAgICAgICAgTWVzc2FnZUZvcm1hdHRlciBtZXNzYWdlRm9ybWF0dGVyID0gZ2V0TWVzc2FnZUZvcm1hdHRlcihkb21haW4pOwotICAgICAgICBTdHJpbmcgbWVzc2FnZTsKLSAgICAgICAgaWYgKG1lc3NhZ2VGb3JtYXR0ZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgbWVzc2FnZSA9IG1lc3NhZ2VGb3JtYXR0ZXIuZm9ybWF0TWVzc2FnZShmTG9jYWxlLCBrZXksIGFyZ3VtZW50cyk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBTdHJpbmdCdWZmZXIgc3RyID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotICAgICAgICAgICAgc3RyLmFwcGVuZChkb21haW4pOwotICAgICAgICAgICAgc3RyLmFwcGVuZCgnIycpOwotICAgICAgICAgICAgc3RyLmFwcGVuZChrZXkpOwotICAgICAgICAgICAgaW50IGFyZ0NvdW50ID0gYXJndW1lbnRzICE9IG51bGwgPyBhcmd1bWVudHMubGVuZ3RoIDogMDsKLSAgICAgICAgICAgIGlmIChhcmdDb3VudCA+IDApIHsKLSAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKCc/Jyk7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhcmdDb3VudDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgICAgIHN0ci5hcHBlbmQoYXJndW1lbnRzW2ldKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGkgPCBhcmdDb3VudCAtMSkgewotICAgICAgICAgICAgICAgICAgICAgICAgc3RyLmFwcGVuZCgnJicpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgbWVzc2FnZSA9IHN0ci50b1N0cmluZygpOwotICAgICAgICB9Ci0KLQotCi0gICAgICAgIC8vbm8gcmVwb3J0ZXIgd2FzIHNwZWNpZmllZAotICAgICAgICAvKioKLSAgICAgICAgICogaWYgKHJlcG9ydGVyID09IG51bGwpIHsKLSAgICAgICAgICogcmVwb3J0ZXIgPSBuZXcgRGVmYXVsdFN0YXhFcnJvclJlcG9ydGVyKCk7Ci0gICAgICAgICAqIH0KLSAgICAgICAgICovCi0KLSAgICAgICAgLy8gY2FsbCBlcnJvciBoYW5kbGVyCi0gICAgICAgIHN3aXRjaCAoc2V2ZXJpdHkpIHsKLSAgICAgICAgICAgIGNhc2UgU0VWRVJJVFlfV0FSTklORzogewotICAgICAgICAgICAgICAgIHRyeXsKLSAgICAgICAgICAgICAgICAgICAgaWYoZlhNTFJlcG9ydGVyIT0gbnVsbCl7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmWE1MUmVwb3J0ZXIucmVwb3J0KG1lc3NhZ2UsICJXQVJOSU5HIiwgbnVsbCwgY29udmVydFRvU3RheExvY2F0aW9uKGxvY2F0aW9uKSApOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfWNhdGNoKFhNTFN0cmVhbUV4Y2VwdGlvbiBleCl7Ci0gICAgICAgICAgICAgICAgICAgIC8vd2hhdCB3ZSBzaG91bGQgYmUgZG9pbmcgPz8gaWYgdGhlIHVzZXIgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbgotICAgICAgICAgICAgICAgICAgICAvL1JFVklTSVQ6Ci0gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBYTklFeGNlcHRpb24oZXgpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhc2UgU0VWRVJJVFlfRVJST1I6IHsKLSAgICAgICAgICAgICAgICB0cnl7Ci0gICAgICAgICAgICAgICAgICAgIGlmKGZYTUxSZXBvcnRlciE9IG51bGwpewotICAgICAgICAgICAgICAgICAgICAgICAgZlhNTFJlcG9ydGVyLnJlcG9ydChtZXNzYWdlLCAiRVJST1IiLCBudWxsLCBjb252ZXJ0VG9TdGF4TG9jYXRpb24obG9jYXRpb24pICk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Y2F0Y2goWE1MU3RyZWFtRXhjZXB0aW9uIGV4KXsKLSAgICAgICAgICAgICAgICAgICAgLy93aGF0IHdlIHNob3VsZCBiZSBkb2luZyA/PyBpZiB0aGUgdXNlciB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uCi0gICAgICAgICAgICAgICAgICAgIC8vUkVWSVNJVDoKLSAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFhOSUV4Y2VwdGlvbihleCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2FzZSBTRVZFUklUWV9GQVRBTF9FUlJPUjogewotICAgICAgICAgICAgICAgIGlmICghZkNvbnRpbnVlQWZ0ZXJGYXRhbEVycm9yKSB7Ci0gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBYTklFeGNlcHRpb24obWVzc2FnZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBtZXNzYWdlOwotICAgIH0KLQotCi0gICAgTG9jYXRpb24gY29udmVydFRvU3RheExvY2F0aW9uKGZpbmFsIFhNTExvY2F0b3IgbG9jYXRpb24pewotICAgICAgICByZXR1cm4gbmV3IExvY2F0aW9uKCl7Ci0gICAgICAgICAgICBwdWJsaWMgaW50IGdldENvbHVtbk51bWJlcigpewotICAgICAgICAgICAgICAgIHJldHVybiBsb2NhdGlvbi5nZXRDb2x1bW5OdW1iZXIoKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgcHVibGljIGludCBnZXRMaW5lTnVtYmVyKCl7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGxvY2F0aW9uLmdldExpbmVOdW1iZXIoKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgcHVibGljIFN0cmluZyBnZXRQdWJsaWNJZCgpewotICAgICAgICAgICAgICAgIHJldHVybiBsb2NhdGlvbi5nZXRQdWJsaWNJZCgpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFN5c3RlbUlkKCl7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGxvY2F0aW9uLmdldExpdGVyYWxTeXN0ZW1JZCgpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBwdWJsaWMgaW50IGdldENoYXJhY3Rlck9mZnNldCgpewotICAgICAgICAgICAgICAgIHJldHVybiBsb2NhdGlvbi5nZXRDaGFyYWN0ZXJPZmZzZXQoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0TG9jYXRpb25VUkkoKXsKLSAgICAgICAgICAgICAgICByZXR1cm4gIiI7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgfTsKLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL3htbC9pbnRlcm5hbC9zdHJlYW0vU3RheFhNTElucHV0U291cmNlLmphdmEgYi9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL1N0YXhYTUxJbnB1dFNvdXJjZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2NWY4NTJjLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL3htbC9pbnRlcm5hbC9zdHJlYW0vU3RheFhNTElucHV0U291cmNlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4OCArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDEzLCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ueG1sLmludGVybmFsLnN0cmVhbTsKLQotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uWE1MRXZlbnRSZWFkZXI7Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5YTUxTdHJlYW1SZWFkZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTElucHV0U291cmNlOwotCi0vKioKLSAqCi0gKiBAYXV0aG9yICBOZWVyYWoKLSAqCi0gKiBUaGlzIGNsYXNzIHdyYXBzIFhNTElucHV0U291cmNlIGFuZCBpcyBhbHNvIGNhcGFibGUgb2YgdGVsbGluZyB3ZXRoZXIgYXBwbGljYXRpb24KLSAqIHJldHVybmVkIFhNTFN0cmVhbVJlYWRlciBvciBub3Qgd2hlbiBYTUxSZXNvbHZlci5yZXNvbHZlRW5pdHkKLSAqIHdhcyBjYWxsZWQuCi0gKi8KLXB1YmxpYyBjbGFzcyBTdGF4WE1MSW5wdXRTb3VyY2UgewotCi0gICAgWE1MU3RyZWFtUmVhZGVyIGZTdHJlYW1SZWFkZXIgOwotICAgIFhNTEV2ZW50UmVhZGVyIGZFdmVudFJlYWRlciA7Ci0gICAgWE1MSW5wdXRTb3VyY2UgZklucHV0U291cmNlIDsKLQotICAgIC8vaW5kaWNhdGUgaWYgdGhlIHNvdXJjZSBpcyByZXNvbHZlZCBieSBhIHJlc29sdmVyCi0gICAgYm9vbGVhbiBmSGFzUmVzb2x2ZXIgPSBmYWxzZTsKLQotICAgIC8qKiBDcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIFN0YXhYTUxJbnB1dFNvdXJjZSAqLwotICAgIHB1YmxpYyBTdGF4WE1MSW5wdXRTb3VyY2UoWE1MU3RyZWFtUmVhZGVyIHN0cmVhbVJlYWRlcikgewotICAgICAgICBmU3RyZWFtUmVhZGVyID0gc3RyZWFtUmVhZGVyIDsKLSAgICB9Ci0KLSAgICAvKiogQ3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiBTdGF4WE1MSW5wdXRTb3VyY2UgKi8KLSAgICBwdWJsaWMgU3RheFhNTElucHV0U291cmNlKFhNTEV2ZW50UmVhZGVyIGV2ZW50UmVhZGVyKSB7Ci0gICAgICAgIGZFdmVudFJlYWRlciA9IGV2ZW50UmVhZGVyIDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RheFhNTElucHV0U291cmNlKFhNTElucHV0U291cmNlIGlucHV0U291cmNlKXsKLSAgICAgICAgZklucHV0U291cmNlID0gaW5wdXRTb3VyY2UgOwotCi0gICAgfQotCi0gICAgcHVibGljIFN0YXhYTUxJbnB1dFNvdXJjZShYTUxJbnB1dFNvdXJjZSBpbnB1dFNvdXJjZSwgYm9vbGVhbiBoYXNSZXNvbHZlcil7Ci0gICAgICAgIGZJbnB1dFNvdXJjZSA9IGlucHV0U291cmNlIDsKLSAgICAgICAgZkhhc1Jlc29sdmVyID0gaGFzUmVzb2x2ZXI7Ci0gICAgfQotCi0gICAgcHVibGljIFhNTFN0cmVhbVJlYWRlciBnZXRYTUxTdHJlYW1SZWFkZXIoKXsKLSAgICAgICAgcmV0dXJuIGZTdHJlYW1SZWFkZXIgOwotICAgIH0KLQotICAgIHB1YmxpYyBYTUxFdmVudFJlYWRlciBnZXRYTUxFdmVudFJlYWRlcigpewotICAgICAgICByZXR1cm4gZkV2ZW50UmVhZGVyIDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgWE1MSW5wdXRTb3VyY2UgZ2V0WE1MSW5wdXRTb3VyY2UoKXsKLSAgICAgICAgcmV0dXJuIGZJbnB1dFNvdXJjZSA7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gaGFzWE1MU3RyZWFtT3JYTUxFdmVudFJlYWRlcigpewotICAgICAgICByZXR1cm4gKGZTdHJlYW1SZWFkZXIgPT0gbnVsbCkgJiYgKGZFdmVudFJlYWRlciA9PSBudWxsKSA/IGZhbHNlIDogdHJ1ZSA7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gaGFzUmVzb2x2ZXIoKSB7Ci0gICAgICAgIHJldHVybiBmSGFzUmVzb2x2ZXI7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4veG1sL2ludGVybmFsL3N0cmVhbS9YTUxCdWZmZXJMaXN0ZW5lci5qYXZhIGIvc3JjL2NvbS9zdW4veG1sL2ludGVybmFsL3N0cmVhbS9YTUxCdWZmZXJMaXN0ZW5lci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzM2M5ODEyLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL3htbC9pbnRlcm5hbC9zdHJlYW0vWE1MQnVmZmVyTGlzdGVuZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDUwICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi54bWwuaW50ZXJuYWwuc3RyZWFtOwotCi0vKioKLSAqIFhNTEJ1ZmZlckxpc3Rlcm5lciBzaG91bGQgYmUgaW1wbGVtZW50ZWQgYnkgY2xhc3NlcyB3aGljaCB3aXNoIHRvIHJlY2VpdmUKLSAqIGNhbGwgYmFja3MgZnJvbSBYTUxFbnRpdHlSZWFkZXIuCi0gKgotICogQGF1dGhvciBrLnZlbnVnb3BhbEBzdW4uY29tLAotICogQGF1dGhvciBOZWVyYWouYmFqYWpAc3VuLmNvbQotICovCi1wdWJsaWMgaW50ZXJmYWNlIFhNTEJ1ZmZlckxpc3RlbmVyIHsKLQotICAgIC8qKgotICAgICAqIFdpbGwgYmUgaW52b2tlZCBieSBYTUxFbnRpdHlSZWFkZXIgYmVmb3JlIGl0IHRyaWVzIHRvIHJlc2l6ZSxsb2FkIG5ldyBkYXRhCi0gICAgICogaW50byBjdXJyZW50IFNjYW5uZWRFbnRpdGllcyBidWZmZXIuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcmVmcmVzaCgpOwotCi0gICAgLyoqCi0gICAgICogcmVjZWl2ZXMgY2FsbGJhY2tzIGZyb20ge0BsaW5rIFhNTEVudGl0eVJlYWRlciB9IHdoZW4gYnVmZmVyCi0gICAgICogaXMgYmVpbmcgY2hhbmdlZC4KLSAgICAgKiBAcGFyYW0gcmVmcmVzaFBvc2l0aW9uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcmVmcmVzaChpbnQgbG9hZFBvc2l0aW9uKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4veG1sL2ludGVybmFsL3N0cmVhbS9YTUxFbnRpdHlSZWFkZXIuamF2YSBiL3NyYy9jb20vc3VuL3htbC9pbnRlcm5hbC9zdHJlYW0vWE1MRW50aXR5UmVhZGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDUyMWMwMDkuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4veG1sL2ludGVybmFsL3N0cmVhbS9YTUxFbnRpdHlSZWFkZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDMwMiArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDA1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICovCi0KLS8qCi0gKiBDb3B5cmlnaHQgMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi54bWwuaW50ZXJuYWwuc3RyZWFtOwotCi1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5YTUxTdHJpbmdCdWZmZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuKjsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGFsbG93cyB2YXJpb3VzIHBhcnNlciBzY2FubmVycyB0byBzY2FuIGJhc2ljIFhNTCBjb25zdHJ1Y3RzCi0gKiBmcm9tIGVudGl0aWVzLiBUaGlzIGNsYXNzIHdvcmtzIGRpcmVjdGx5IHdpdGggdGhlIGVudGl0eSBtYW5hZ2VyIHRvCi0gKiBwcm92aWRlIHRoaXMgZnVuY3Rpb25hbGl0eS4KLSAqIDxwPgotICogVGhlcmUgaXMgb25seSBvbmUgZW50aXR5IHNjYW5uZXIgYW5kIGVudGl0eSBtYW5hZ2VyIHBlciBwYXJzZXIuIFRoZQotICogZW50aXR5IG1hbmFnZXIgPGVtPmNvdWxkPC9lbT4gaW1wbGVtZW50IHRoZSBtZXRob2RzIHRvIHBlcmZvcm0gZW50aXR5Ci0gKiBzY2FubmluZywgYnV0IHRoZSBlbnRpdHkgc2Nhbm5lciBjbGFzcyBhbGxvd3MgYSBjbGVhbmVyIHNlcGFyYXRpb24KLSAqIGJldHdlZW4gZW50aXR5IG1hbmFnZW1lbnQgQVBJIGFuZCBlbnRpdHkgc2Nhbm5pbmcuCi0gKgotICogQGF1dGhvciBBbmR5IENsYXJrLCBJQk0KLSAqIEBhdXRob3IgTmVlcmFqIEJhamFqIFN1biBNaWNyb3N5c3RlbXMKLSAqIEBhdXRob3IgSy5WZW51Z29wYWwgU3VuIE1pY3Jvc3lzdGVtcwotICoKLSAqIEBzZWUgWE1MRW50aXR5SGFuZGxlcgotICogQHNlZSBYTUxFbnRpdHlNYW5hZ2VyCi0gKi8KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBYTUxFbnRpdHlSZWFkZXIgaW1wbGVtZW50cyBYTUxMb2NhdG9yIHsKLQotICAgIC8vCi0gICAgLy8gUHVibGljIG1ldGhvZHMKLSAgICAvLwotCi0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSBlbmNvZGluZyBvZiB0aGUgc2Nhbm5lci4gVGhpcyBtZXRob2QgaXMgdXNlZCBieSB0aGUKLSAgICAgKiBzY2FubmVycyBpZiB0aGUgWE1MRGVjbCBvciBUZXh0RGVjbCBsaW5lIGNvbnRhaW5zIGFuIGVuY29kaW5nCi0gICAgICogcHNldWRvLWF0dHJpYnV0ZS4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoZSB1bmRlcmx5aW5nIGNoYXJhY3RlciByZWFkZXIgb24gdGhlCi0gICAgICogY3VycmVudCBlbnRpdHkgd2lsbCBiZSBjaGFuZ2VkIHRvIGFjY29tb2RhdGUgdGhlIG5ldyBlbmNvZGluZy4KLSAgICAgKiBIb3dldmVyLCB0aGUgbmV3IGVuY29kaW5nIGlzIGlnbm9yZWQgaWYgdGhlIGN1cnJlbnQgcmVhZGVyIHdhcwotICAgICAqIG5vdCBjb25zdHJ1Y3RlZCBmcm9tIGFuIGlucHV0IHN0cmVhbSAoZS5nLiBhbiBleHRlcm5hbCBlbnRpdHkKLSAgICAgKiB0aGF0IGlzIHJlc29sdmVkIGRpcmVjdGx5IHRvIHRoZSBhcHByb3ByaWF0ZSBqYXZhLmlvLlJlYWRlcgotICAgICAqIG9iamVjdCkuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZW5jb2RpbmcgVGhlIElBTkEgZW5jb2RpbmcgbmFtZSBvZiB0aGUgbmV3IGVuY29kaW5nLgotICAgICAqCi0gICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiAgVGhyb3duIGlmIHRoZSBuZXcgZW5jb2RpbmcgaXMgbm90IHN1cHBvcnRlZC4KLSAgICAgKgotICAgICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLkVuY29kaW5nTWFwCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuWE1MQ2hhciNpc1ZhbGlkSUFOQUVuY29kaW5nCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuWE1MQ2hhciNpc1ZhbGlkSmF2YUVuY29kaW5nCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2V0RW5jb2RpbmcoU3RyaW5nIGVuY29kaW5nKQotICAgIHRocm93cyBJT0V4Y2VwdGlvbjsKLQotICAgIHB1YmxpYyBhYnN0cmFjdCBTdHJpbmcgZ2V0RW5jb2RpbmcoKSA7Ci0KLSAgICBwdWJsaWMgYWJzdHJhY3QgaW50IGdldENoYXJhY3Rlck9mZnNldCgpIDsKLQotICAgIC8qKiB0aGUgdmVyc2lvbiBvZiB0aGUgY3VycmVudCBlbnRpdHkgYmVpbmcgc2Nhbm5lZCBvciB0aGUgdmVyc2lvbiBvZiB0aGUgZW50aXR5IG9uIHdoaWNoIHJlYWRlciBpcyBvcGVyYXRpbmcgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRWZXJzaW9uKFN0cmluZyB2ZXJzaW9uKSA7Ci0KLSAgICAvKiogZ2V0IHRoZSB2ZXJzaW9uIG9mIHRoZSBlbnRpdHkgb24gd2hpY2ggcmVhZGVyIGlzIG9wZXJhdGluZyAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCBTdHJpbmcgZ2V0VmVyc2lvbigpIDsKLQotICAgIC8qKiBSZXR1cm5zIHRydWUgaWYgdGhlIGN1cnJlbnQgZW50aXR5IGJlaW5nIHNjYW5uZWQgaXMgZXh0ZXJuYWwuICovCi0gICAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gaXNFeHRlcm5hbCgpOwotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgbmV4dCBjaGFyYWN0ZXIgb24gdGhlIGlucHV0LgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gVGhlIGNoYXJhY3RlciBpcyA8ZW0+bm90PC9lbT4gY29uc3VtZWQuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uICBUaHJvd24gaWYgaS9vIGVycm9yIG9jY3Vycy4KLSAgICAgKiBAdGhyb3dzIEVPRkV4Y2VwdGlvbiBUaHJvd24gb24gZW5kIG9mIGZpbGUuCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IGludCBwZWVrQ2hhcigpIHRocm93cyBJT0V4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIG5leHQgY2hhcmFjdGVyIG9uIHRoZSBpbnB1dC4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoZSBjaGFyYWN0ZXIgaXMgY29uc3VtZWQuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uICBUaHJvd24gaWYgaS9vIGVycm9yIG9jY3Vycy4KLSAgICAgKiBAdGhyb3dzIEVPRkV4Y2VwdGlvbiBUaHJvd24gb24gZW5kIG9mIGZpbGUuCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IGludCBzY2FuQ2hhcigpIHRocm93cyBJT0V4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYSBzdHJpbmcgbWF0Y2hpbmcgdGhlIE5NVE9LRU4gcHJvZHVjdGlvbiBhcHBlYXJpbmcgaW1tZWRpYXRlbHkKLSAgICAgKiBvbiB0aGUgaW5wdXQgYXMgYSBzeW1ib2wsIG9yIG51bGwgaWYgTk1UT0tFTiBOYW1lIHN0cmluZyBpcyBwcmVzZW50LgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gVGhlIE5NVE9LRU4gY2hhcmFjdGVycyBhcmUgY29uc3VtZWQuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGUgc3RyaW5nIHJldHVybmVkIG11c3QgYmUgYSBzeW1ib2wuIFRoZQotICAgICAqIFN5bWJvbFRhYmxlIGNhbiBiZSB1c2VkIGZvciB0aGlzIHB1cnBvc2UuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uICBUaHJvd24gaWYgaS9vIGVycm9yIG9jY3Vycy4KLSAgICAgKiBAdGhyb3dzIEVPRkV4Y2VwdGlvbiBUaHJvd24gb24gZW5kIG9mIGZpbGUuCi0gICAgICoKLSAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5TeW1ib2xUYWJsZQotICAgICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlhNTENoYXIjaXNOYW1lCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IFN0cmluZyBzY2FuTm10b2tlbigpIHRocm93cyBJT0V4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYSBzdHJpbmcgbWF0Y2hpbmcgdGhlIE5hbWUgcHJvZHVjdGlvbiBhcHBlYXJpbmcgaW1tZWRpYXRlbHkKLSAgICAgKiBvbiB0aGUgaW5wdXQgYXMgYSBzeW1ib2wsIG9yIG51bGwgaWYgbm8gTmFtZSBzdHJpbmcgaXMgcHJlc2VudC4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoZSBOYW1lIGNoYXJhY3RlcnMgYXJlIGNvbnN1bWVkLgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gVGhlIHN0cmluZyByZXR1cm5lZCBtdXN0IGJlIGEgc3ltYm9sLiBUaGUKLSAgICAgKiBTeW1ib2xUYWJsZSBjYW4gYmUgdXNlZCBmb3IgdGhpcyBwdXJwb3NlLgotICAgICAqCi0gICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiAgVGhyb3duIGlmIGkvbyBlcnJvciBvY2N1cnMuCi0gICAgICogQHRocm93cyBFT0ZFeGNlcHRpb24gVGhyb3duIG9uIGVuZCBvZiBmaWxlLgotICAgICAqCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuU3ltYm9sVGFibGUKLSAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5YTUxDaGFyI2lzTmFtZQotICAgICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlhNTENoYXIjaXNOYW1lU3RhcnQKLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nIHNjYW5OYW1lKCkgdGhyb3dzIElPRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogU2NhbnMgYSBxdWFsaWZpZWQgbmFtZSBmcm9tIHRoZSBpbnB1dCwgc2V0dGluZyB0aGUgZmllbGRzIG9mIHRoZQotICAgICAqIFFOYW1lIHN0cnVjdHVyZSBhcHByb3ByaWF0ZWx5LgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gVGhlIHF1YWxpZmllZCBuYW1lIGNoYXJhY3RlcnMgYXJlIGNvbnN1bWVkLgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gVGhlIHN0cmluZ3MgdXNlZCB0byBzZXQgdGhlIHZhbHVlcyBvZiB0aGUKLSAgICAgKiBRTmFtZSBzdHJ1Y3R1cmUgbXVzdCBiZSBzeW1ib2xzLiBUaGUgU3ltYm9sVGFibGUgY2FuIGJlIHVzZWQgZm9yCi0gICAgICogdGhpcyBwdXJwb3NlLgotICAgICAqCi0gICAgICogQHBhcmFtIHFuYW1lIFRoZSBxdWFsaWZpZWQgbmFtZSBzdHJ1Y3R1cmUgdG8gZmlsbC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gUmV0dXJucyB0cnVlIGlmIGEgcXVhbGlmaWVkIG5hbWUgYXBwZWFyZWQgaW1tZWRpYXRlbHkgb24KLSAgICAgKiAgICAgICAgIHRoZSBpbnB1dCBhbmQgd2FzIHNjYW5uZWQsIGZhbHNlIG90aGVyd2lzZS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gIFRocm93biBpZiBpL28gZXJyb3Igb2NjdXJzLgotICAgICAqIEB0aHJvd3MgRU9GRXhjZXB0aW9uIFRocm93biBvbiBlbmQgb2YgZmlsZS4KLSAgICAgKgotICAgICAqIEBzZWUgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlN5bWJvbFRhYmxlCi0gICAgICogQHNlZSBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuWE1MQ2hhciNpc05hbWUKLSAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5YTUxDaGFyI2lzTmFtZVN0YXJ0Ci0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gc2NhblFOYW1lKFFOYW1lIHFuYW1lKSB0aHJvd3MgSU9FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBDSEFOR0VEOgotICAgICAqIFNjYW5zIGEgcmFuZ2Ugb2YgcGFyc2VkIGNoYXJhY3RlciBkYXRhLCBUaGlzIGZ1bmN0aW9uIGFwcGVuZHMgdGhlIGNoYXJhY3RlciBkYXRhIHRvCi0gICAgICogdGhlIHN1cHBsaWVkIGJ1ZmZlci4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoZSBjaGFyYWN0ZXJzIGFyZSBjb25zdW1lZC4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoaXMgbWV0aG9kIGRvZXMgbm90IGd1YXJhbnRlZSB0byByZXR1cm4KLSAgICAgKiB0aGUgbG9uZ2VzdCBydW4gb2YgcGFyc2VkIGNoYXJhY3RlciBkYXRhLiBUaGlzIG1ldGhvZCBtYXkgcmV0dXJuCi0gICAgICogYmVmb3JlIG1hcmt1cCBkdWUgdG8gcmVhY2hpbmcgdGhlIGVuZCBvZiB0aGUgaW5wdXQgYnVmZmVyIG9yIGFueQotICAgICAqIG90aGVyIHJlYXNvbi4KLSAgICAgKiA8cD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjb250ZW50IFRoZSBjb250ZW50IHN0cnVjdHVyZSB0byBmaWxsLgotICAgICAqCi0gICAgICogQHJldHVybiBSZXR1cm5zIHRoZSBuZXh0IGNoYXJhY3RlciBvbiB0aGUgaW5wdXQsIGlmIGtub3duLiBUaGlzCi0gICAgICogICAgICAgICB2YWx1ZSBtYXkgYmUgLTEgYnV0IHRoaXMgZG9lcyA8ZW0+bm90ZTwvZW0+IGRlc2lnbmF0ZQotICAgICAqICAgICAgICAgZW5kIG9mIGZpbGUuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uICBUaHJvd24gaWYgaS9vIGVycm9yIG9jY3Vycy4KLSAgICAgKiBAdGhyb3dzIEVPRkV4Y2VwdGlvbiBUaHJvd24gb24gZW5kIG9mIGZpbGUuCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IGludCBzY2FuQ29udGVudChYTUxTdHJpbmcgY29udGVudCkgdGhyb3dzIElPRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogU2NhbnMgYSByYW5nZSBvZiBhdHRyaWJ1dGUgdmFsdWUgZGF0YSwgc2V0dGluZyB0aGUgZmllbGRzIG9mIHRoZQotICAgICAqIFhNTFN0cmluZyBzdHJ1Y3R1cmUsIGFwcHJvcHJpYXRlbHkuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGUgY2hhcmFjdGVycyBhcmUgY29uc3VtZWQuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGlzIG1ldGhvZCBkb2VzIG5vdCBndWFyYW50ZWUgdG8gcmV0dXJuCi0gICAgICogdGhlIGxvbmdlc3QgcnVuIG9mIGF0dHJpYnV0ZSB2YWx1ZSBkYXRhLiBUaGlzIG1ldGhvZCBtYXkgcmV0dXJuCi0gICAgICogYmVmb3JlIHRoZSBxdW90ZSBjaGFyYWN0ZXIgZHVlIHRvIHJlYWNoaW5nIHRoZSBlbmQgb2YgdGhlIGlucHV0Ci0gICAgICogYnVmZmVyIG9yIGFueSBvdGhlciByZWFzb24uCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGUgZmllbGRzIGNvbnRhaW5lZCBpbiB0aGUgWE1MU3RyaW5nCi0gICAgICogc3RydWN0dXJlIGFyZSBub3QgZ3VhcmFudGVlZCB0byByZW1haW4gdmFsaWQgdXBvbiBzdWJzZXF1ZW50IGNhbGxzCi0gICAgICogdG8gdGhlIGVudGl0eSBzY2FubmVyLiBUaGVyZWZvcmUsIHRoZSBjYWxsZXIgaXMgcmVzcG9uc2libGUgZm9yCi0gICAgICogaW1tZWRpYXRlbHkgdXNpbmcgdGhlIHJldHVybmVkIGNoYXJhY3RlciBkYXRhIG9yIG1ha2luZyBhIGNvcHkgb2YKLSAgICAgKiB0aGUgY2hhcmFjdGVyIGRhdGEuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcXVvdGUgICBUaGUgcXVvdGUgY2hhcmFjdGVyIHRoYXQgc2lnbmlmaWVzIHRoZSBlbmQgb2YgdGhlCi0gICAgICogICAgICAgICAgICAgICAgYXR0cmlidXRlIHZhbHVlIGRhdGEuCi0gICAgICogQHBhcmFtIGNvbnRlbnQgVGhlIGNvbnRlbnQgc3RydWN0dXJlIHRvIGZpbGwuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFJldHVybnMgdGhlIG5leHQgY2hhcmFjdGVyIG9uIHRoZSBpbnB1dCwgaWYga25vd24uIFRoaXMKLSAgICAgKiAgICAgICAgIHZhbHVlIG1heSBiZSAtMSBidXQgdGhpcyBkb2VzIDxlbT5ub3RlPC9lbT4gZGVzaWduYXRlCi0gICAgICogICAgICAgICBlbmQgb2YgZmlsZS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gIFRocm93biBpZiBpL28gZXJyb3Igb2NjdXJzLgotICAgICAqIEB0aHJvd3MgRU9GRXhjZXB0aW9uIFRocm93biBvbiBlbmQgb2YgZmlsZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3QgaW50IHNjYW5MaXRlcmFsKGludCBxdW90ZSwgWE1MU3RyaW5nIGNvbnRlbnQpCi0gICAgdGhyb3dzIElPRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogU2NhbnMgYSByYW5nZSBvZiBjaGFyYWN0ZXIgZGF0YSB1cCB0byB0aGUgc3BlY2ljaWVkIGRlbGltaXRlciwKLSAgICAgKiBzZXR0aW5nIHRoZSBmaWVsZHMgb2YgdGhlIFhNTFN0cmluZyBzdHJ1Y3R1cmUsIGFwcHJvcHJpYXRlbHkuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGUgY2hhcmFjdGVycyBhcmUgY29uc3VtZWQuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGlzIGFzc3VtZXMgdGhhdCB0aGUgaW50ZXJuYWwgYnVmZmVyIGlzCi0gICAgICogYXQgbGVhc3QgdGhlIHNhbWUgc2l6ZSwgb3IgYmlnZ2VyLCB0aGFuIHRoZSBsZW5ndGggb2YgdGhlIGRlbGltaXRlcgotICAgICAqIGFuZCB0aGF0IHRoZSBkZWxpbWl0ZXIgY29udGFpbnMgYXQgbGVhc3Qgb25lIGNoYXJhY3Rlci4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoaXMgbWV0aG9kIGRvZXMgbm90IGd1YXJhbnRlZSB0byByZXR1cm4KLSAgICAgKiB0aGUgbG9uZ2VzdCBydW4gb2YgY2hhcmFjdGVyIGRhdGEuIFRoaXMgbWV0aG9kIG1heSByZXR1cm4gYmVmb3JlCi0gICAgICogdGhlIGRlbGltaXRlciBkdWUgdG8gcmVhY2hpbmcgdGhlIGVuZCBvZiB0aGUgaW5wdXQgYnVmZmVyIG9yIGFueQotICAgICAqIG90aGVyIHJlYXNvbi4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoZSBmaWVsZHMgY29udGFpbmVkIGluIHRoZSBYTUxTdHJpbmcKLSAgICAgKiBzdHJ1Y3R1cmUgYXJlIG5vdCBndWFyYW50ZWVkIHRvIHJlbWFpbiB2YWxpZCB1cG9uIHN1YnNlcXVlbnQgY2FsbHMKLSAgICAgKiB0byB0aGUgZW50aXR5IHNjYW5uZXIuIFRoZXJlZm9yZSwgdGhlIGNhbGxlciBpcyByZXNwb25zaWJsZSBmb3IKLSAgICAgKiBpbW1lZGlhdGVseSB1c2luZyB0aGUgcmV0dXJuZWQgY2hhcmFjdGVyIGRhdGEgb3IgbWFraW5nIGEgY29weSBvZgotICAgICAqIHRoZSBjaGFyYWN0ZXIgZGF0YS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBkZWxpbWl0ZXIgVGhlIHN0cmluZyB0aGF0IHNpZ25pZmllcyB0aGUgZW5kIG9mIHRoZSBjaGFyYWN0ZXIKLSAgICAgKiAgICAgICAgICAgICAgICAgIGRhdGEgdG8gYmUgc2Nhbm5lZC4KLSAgICAgKiBAcGFyYW0gZGF0YSAgICAgIFRoZSBkYXRhIHN0cnVjdHVyZSB0byBmaWxsLgotICAgICAqCi0gICAgICogQHJldHVybiBSZXR1cm5zIHRydWUgaWYgdGhlcmUgaXMgbW9yZSBkYXRhIHRvIHNjYW4sIGZhbHNlIG90aGVyd2lzZS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gIFRocm93biBpZiBpL28gZXJyb3Igb2NjdXJzLgotICAgICAqIEB0aHJvd3MgRU9GRXhjZXB0aW9uIFRocm93biBvbiBlbmQgb2YgZmlsZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBzY2FuRGF0YShTdHJpbmcgZGVsaW1pdGVyLCBYTUxTdHJpbmdCdWZmZXIgZGF0YSkKLSAgICB0aHJvd3MgSU9FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBTa2lwcyBhIGNoYXJhY3RlciBhcHBlYXJpbmcgaW1tZWRpYXRlbHkgb24gdGhlIGlucHV0LgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gVGhlIGNoYXJhY3RlciBpcyBjb25zdW1lZCBvbmx5IGlmIGl0IG1hdGNoZXMKLSAgICAgKiB0aGUgc3BlY2lmaWVkIGNoYXJhY3Rlci4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjIFRoZSBjaGFyYWN0ZXIgdG8gc2tpcC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gUmV0dXJucyB0cnVlIGlmIHRoZSBjaGFyYWN0ZXIgd2FzIHNraXBwZWQuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uICBUaHJvd24gaWYgaS9vIGVycm9yIG9jY3Vycy4KLSAgICAgKiBAdGhyb3dzIEVPRkV4Y2VwdGlvbiBUaHJvd24gb24gZW5kIG9mIGZpbGUuCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gc2tpcENoYXIoaW50IGMpIHRocm93cyBJT0V4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIFNraXBzIHNwYWNlIGNoYXJhY3RlcnMgYXBwZWFyaW5nIGltbWVkaWF0ZWx5IG9uIHRoZSBpbnB1dC4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoZSBjaGFyYWN0ZXJzIGFyZSBjb25zdW1lZCBvbmx5IGlmIHRoZXkgYXJlCi0gICAgICogc3BhY2UgY2hhcmFjdGVycy4KLSAgICAgKgotICAgICAqIEByZXR1cm4gUmV0dXJucyB0cnVlIGlmIGF0IGxlYXN0IG9uZSBzcGFjZSBjaGFyYWN0ZXIgd2FzIHNraXBwZWQuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uICBUaHJvd24gaWYgaS9vIGVycm9yIG9jY3Vycy4KLSAgICAgKiBAdGhyb3dzIEVPRkV4Y2VwdGlvbiBUaHJvd24gb24gZW5kIG9mIGZpbGUuCi0gICAgICoKLSAgICAgKiBAc2VlIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5YTUxDaGFyI2lzU3BhY2UKLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBza2lwU3BhY2VzKCkgdGhyb3dzIElPRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogU2tpcHMgdGhlIHNwZWNpZmllZCBzdHJpbmcgYXBwZWFyaW5nIGltbWVkaWF0ZWx5IG9uIHRoZSBpbnB1dC4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoZSBjaGFyYWN0ZXJzIGFyZSBjb25zdW1lZCBvbmx5IGlmIHRoZXkgYXJlCi0gICAgICogc3BhY2UgY2hhcmFjdGVycy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzIFRoZSBzdHJpbmcgdG8gc2tpcC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gUmV0dXJucyB0cnVlIGlmIHRoZSBzdHJpbmcgd2FzIHNraXBwZWQuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uICBUaHJvd24gaWYgaS9vIGVycm9yIG9jY3Vycy4KLSAgICAgKiBAdGhyb3dzIEVPRkV4Y2VwdGlvbiBUaHJvd24gb24gZW5kIG9mIGZpbGUuCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gc2tpcFN0cmluZyhTdHJpbmcgcykgdGhyb3dzIElPRXhjZXB0aW9uOwotCi0gICAgcHVibGljIGFic3RyYWN0IHZvaWQgcmVnaXN0ZXJMaXN0ZW5lcihYTUxCdWZmZXJMaXN0ZW5lciBsaXN0ZW5lcik7Ci0KLX0gLy8gY2xhc3MgWE1MRW50aXR5U2Nhbm5lcgpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4veG1sL2ludGVybmFsL3N0cmVhbS9YTUxFbnRpdHlTdG9yYWdlLmphdmEgYi9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL1hNTEVudGl0eVN0b3JhZ2UuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNjI1MmYyMi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL1hNTEVudGl0eVN0b3JhZ2UuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDYyNSArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDE1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ueG1sLmludGVybmFsLnN0cmVhbTsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5Db25zdGFudHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLlByb3BlcnR5TWFuYWdlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuWE1MRW50aXR5TWFuYWdlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuWE1MRXJyb3JSZXBvcnRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwubXNnLlhNTE1lc3NhZ2VGb3JtYXR0ZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlVSSTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuWE1MUmVzb3VyY2VJZGVudGlmaWVySW1wbDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWxzLlNlY3VyaXR5U3VwcG9ydDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MQ29tcG9uZW50TWFuYWdlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuWE1MQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7Ci1pbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOwotaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwotaW1wb3J0IGphdmEudXRpbC5NYXA7Ci0KLS8qKgotICoKLSAqIEBhdXRob3IgSy5WZW51Z29wYWwgU1VOIE1pY3Jvc3lzdGVtcwotICogQGF1dGhvciBOZWVyYWogQmFqYWogU1VOIE1pY3Jvc3lzdGVtcwotICogQGF1dGhvciBBbmR5IENsYXJrLCBJQk0KLSAqCi0gKi8KLXB1YmxpYyBjbGFzcyBYTUxFbnRpdHlTdG9yYWdlIHsKLQotICAgIC8qKiBQcm9wZXJ0eSBpZGVudGlmaWVyOiBlcnJvciByZXBvcnRlci4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJPUl9SRVBPUlRFUiA9Ci0gICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuRVJST1JfUkVQT1JURVJfUFJPUEVSVFk7Ci0KLSAgICAvKiogRmVhdHVyZSBpZGVudGlmaWVyOiB3YXJuIG9uIGR1cGxpY2F0ZSBFbnRpdHlEZWYgKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBXQVJOX09OX0RVUExJQ0FURV9FTlRJVFlERUYgPQotICAgIENvbnN0YW50cy5YRVJDRVNfRkVBVFVSRV9QUkVGSVggK0NvbnN0YW50cy5XQVJOX09OX0RVUExJQ0FURV9FTlRJVFlERUZfRkVBVFVSRTsKLQotICAgIC8qKiB3YXJuIG9uIGR1cGxpY2F0ZSBFbnRpdHkgZGVjbGFyYXRpb24uCi0gICAgICogIGh0dHA6Ly9hcGFjaGUub3JnL3htbC9mZWF0dXJlcy93YXJuLW9uLWR1cGxpY2F0ZS1lbnRpdHlkZWYKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBmV2FybkR1cGxpY2F0ZUVudGl0eURlZjsKLQotICAgIC8qKiBFbnRpdGllcy4gKi8KLSAgICBwcm90ZWN0ZWQgTWFwPFN0cmluZywgRW50aXR5PiBmRW50aXRpZXMgPSBuZXcgSGFzaE1hcDw+KCk7Ci0KLSAgICBwcm90ZWN0ZWQgRW50aXR5LlNjYW5uZWRFbnRpdHkgZkN1cnJlbnRFbnRpdHkgOwotCi0gICAgcHJpdmF0ZSBYTUxFbnRpdHlNYW5hZ2VyIGZFbnRpdHlNYW5hZ2VyOwotICAgIC8qKgotICAgICAqIEVycm9yIHJlcG9ydGVyLiBUaGlzIHByb3BlcnR5IGlkZW50aWZpZXIgaXM6Ci0gICAgICogaHR0cDovL2FwYWNoZS5vcmcveG1sL3Byb3BlcnRpZXMvaW50ZXJuYWwvZXJyb3ItcmVwb3J0ZXIKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgWE1MRXJyb3JSZXBvcnRlciBmRXJyb3JSZXBvcnRlcjsKLSAgICBwcm90ZWN0ZWQgUHJvcGVydHlNYW5hZ2VyIGZQcm9wZXJ0eU1hbmFnZXIgOwotCi0gICAgLyogVG8ga2VlcCB0cmFjayB3aGV0aGVyIGFuIGVudGl0eSBpcyBkZWNsYXJlZCBpbiBleHRlcm5hbCBvciBpbnRlcm5hbCBzdWJzZXQqLwotICAgIHByb3RlY3RlZCBib29sZWFuIGZJbkV4dGVybmFsU3Vic2V0ID0gZmFsc2U7Ci0KLSAgICAvKiogQ3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiBYTUxFbnRpdHlTdG9yYWdlICovCi0gICAgcHVibGljIFhNTEVudGl0eVN0b3JhZ2UoUHJvcGVydHlNYW5hZ2VyIHByb3BlcnR5TWFuYWdlcikgewotICAgICAgICBmUHJvcGVydHlNYW5hZ2VyID0gcHJvcGVydHlNYW5hZ2VyIDsKLSAgICB9Ci0KLSAgICAvKiogQ3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiBYTUxFbnRpdHlTdG9yYWdlICovCi0gICAgLypwdWJsaWMgWE1MRW50aXR5U3RvcmFnZShFbnRpdHkuU2Nhbm5lZEVudGl0eSBjdXJyZW50RW50aXR5KSB7Ci0gICAgICAgIGZDdXJyZW50RW50aXR5ID0gY3VycmVudEVudGl0eSA7Ki8KLSAgICBwdWJsaWMgWE1MRW50aXR5U3RvcmFnZShYTUxFbnRpdHlNYW5hZ2VyIGVudGl0eU1hbmFnZXIpIHsKLSAgICAgICAgZkVudGl0eU1hbmFnZXIgPSBlbnRpdHlNYW5hZ2VyOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHJlc2V0KFByb3BlcnR5TWFuYWdlciBwcm9wZXJ0eU1hbmFnZXIpewotCi0gICAgICAgIGZFcnJvclJlcG9ydGVyID0gKFhNTEVycm9yUmVwb3J0ZXIpcHJvcGVydHlNYW5hZ2VyLmdldFByb3BlcnR5KENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLkVSUk9SX1JFUE9SVEVSX1BST1BFUlRZKTsKLSAgICAgICAgZkVudGl0aWVzLmNsZWFyKCk7Ci0gICAgICAgIGZDdXJyZW50RW50aXR5ID0gbnVsbDsKLQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHJlc2V0KCl7Ci0gICAgICAgIGZFbnRpdGllcy5jbGVhcigpOwotICAgICAgICBmQ3VycmVudEVudGl0eSA9IG51bGw7Ci0gICAgfQotICAgIC8qKgotICAgICAqIFJlc2V0cyB0aGUgY29tcG9uZW50LiBUaGUgY29tcG9uZW50IGNhbiBxdWVyeSB0aGUgY29tcG9uZW50IG1hbmFnZXIKLSAgICAgKiBhYm91dCBhbnkgZmVhdHVyZXMgYW5kIHByb3BlcnRpZXMgdGhhdCBhZmZlY3QgdGhlIG9wZXJhdGlvbiBvZiB0aGUKLSAgICAgKiBjb21wb25lbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29tcG9uZW50TWFuYWdlciBUaGUgY29tcG9uZW50IG1hbmFnZXIuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBUaHJvd24gYnkgY29tcG9uZW50IG9uIGluaXRpYWxpemF0aW9uIGVycm9yLgotICAgICAqICAgICAgICAgICAgICAgICAgICAgIEZvciBleGFtcGxlLCBpZiBhIGZlYXR1cmUgb3IgcHJvcGVydHkgaXMKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICByZXF1aXJlZCBmb3IgdGhlIG9wZXJhdGlvbiBvZiB0aGUgY29tcG9uZW50LCB0aGUKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBjb21wb25lbnQgbWFuYWdlciBtYXkgdGhyb3cgYQotICAgICAqICAgICAgICAgICAgICAgICAgICAgIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24gb3IgYQotICAgICAqICAgICAgICAgICAgICAgICAgICAgIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCByZXNldChYTUxDb21wb25lbnRNYW5hZ2VyIGNvbXBvbmVudE1hbmFnZXIpCi0gICAgdGhyb3dzIFhNTENvbmZpZ3VyYXRpb25FeGNlcHRpb24gewotCi0KLSAgICAgICAgLy8geGVyY2VzIGZlYXR1cmVzCi0KLSAgICAgICAgZldhcm5EdXBsaWNhdGVFbnRpdHlEZWYgPSBjb21wb25lbnRNYW5hZ2VyLmdldEZlYXR1cmUoV0FSTl9PTl9EVVBMSUNBVEVfRU5USVRZREVGLCBmYWxzZSk7Ci0KLSAgICAgICAgZkVycm9yUmVwb3J0ZXIgPSAoWE1MRXJyb3JSZXBvcnRlciljb21wb25lbnRNYW5hZ2VyLmdldFByb3BlcnR5KEVSUk9SX1JFUE9SVEVSKTsKLQotICAgICAgICBmRW50aXRpZXMuY2xlYXIoKTsKLSAgICAgICAgZkN1cnJlbnRFbnRpdHkgPSBudWxsOwotCi0gICAgfSAvLyByZXNldChYTUxDb21wb25lbnRNYW5hZ2VyKQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBlbnRpdHkgZGVjbGFyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgZW50aXR5LgotICAgICAqCi0gICAgICogQHNlZSBTeW1ib2xUYWJsZQotICAgICAqLwotICAgIHB1YmxpYyBFbnRpdHkgZ2V0RW50aXR5KFN0cmluZyBuYW1lKSB7Ci0gICAgICAgIHJldHVybiBmRW50aXRpZXMuZ2V0KG5hbWUpOwotICAgIH0gLy8gZ2V0RW50aXR5KFN0cmluZykKLQotICAgIHB1YmxpYyBib29sZWFuIGhhc0VudGl0aWVzKCkgewotICAgICAgICAgICAgcmV0dXJuIChmRW50aXRpZXMhPW51bGwpOwotICAgIH0gLy8gZ2V0RW50aXR5KFN0cmluZykKLQotICAgIHB1YmxpYyBpbnQgZ2V0RW50aXR5U2l6ZSgpIHsKLSAgICAgICAgcmV0dXJuIGZFbnRpdGllcy5zaXplKCk7Ci0gICAgfSAvLyBnZXRFbnRpdHkoU3RyaW5nKQotCi0gICAgcHVibGljIEVudW1lcmF0aW9uIGdldEVudGl0eUtleXMoKSB7Ci0gICAgICAgIHJldHVybiBDb2xsZWN0aW9ucy5lbnVtZXJhdGlvbihmRW50aXRpZXMua2V5U2V0KCkpOwotICAgIH0KLSAgICAvKioKLSAgICAgKiBBZGRzIGFuIGludGVybmFsIGVudGl0eSBkZWNsYXJhdGlvbi4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoaXMgbWV0aG9kIGlnbm9yZXMgc3Vic2VxdWVudCBlbnRpdHkKLSAgICAgKiBkZWNsYXJhdGlvbnMuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGUgbmFtZSBzaG91bGQgYmUgYSB1bmlxdWUgc3ltYm9sLiBUaGUKLSAgICAgKiBTeW1ib2xUYWJsZSBjYW4gYmUgdXNlZCBmb3IgdGhpcyBwdXJwb3NlLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGVudGl0eS4KLSAgICAgKiBAcGFyYW0gdGV4dCBUaGUgdGV4dCBvZiB0aGUgZW50aXR5LgotICAgICAqCi0gICAgICogQHNlZSBTeW1ib2xUYWJsZQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGFkZEludGVybmFsRW50aXR5KFN0cmluZyBuYW1lLCBTdHJpbmcgdGV4dCkgewotICAgICAgaWYgKCFmRW50aXRpZXMuY29udGFpbnNLZXkobmFtZSkpIHsKLSAgICAgICAgICAgIEVudGl0eSBlbnRpdHkgPSBuZXcgRW50aXR5LkludGVybmFsRW50aXR5KG5hbWUsIHRleHQsIGZJbkV4dGVybmFsU3Vic2V0KTsKLSAgICAgICAgICAgIGZFbnRpdGllcy5wdXQobmFtZSwgZW50aXR5KTsKLSAgICAgICAgfQotICAgICAgICBlbHNlewotICAgICAgICAgICAgaWYoZldhcm5EdXBsaWNhdGVFbnRpdHlEZWYpewotICAgICAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAiTVNHX0RVUExJQ0FURV9FTlRJVFlfREVGSU5JVElPTiIsCi0gICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdeyBuYW1lIH0sCi0gICAgICAgICAgICAgICAgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9XQVJOSU5HICk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9IC8vIGFkZEludGVybmFsRW50aXR5KFN0cmluZyxTdHJpbmcpCi0KLSAgICAvKioKLSAgICAgKiBBZGRzIGFuIGV4dGVybmFsIGVudGl0eSBkZWNsYXJhdGlvbi4KLSAgICAgKiA8cD4KLSAgICAgKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IFRoaXMgbWV0aG9kIGlnbm9yZXMgc3Vic2VxdWVudCBlbnRpdHkKLSAgICAgKiBkZWNsYXJhdGlvbnMuCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGUgbmFtZSBzaG91bGQgYmUgYSB1bmlxdWUgc3ltYm9sLiBUaGUKLSAgICAgKiBTeW1ib2xUYWJsZSBjYW4gYmUgdXNlZCBmb3IgdGhpcyBwdXJwb3NlLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgICAgICAgICBUaGUgbmFtZSBvZiB0aGUgZW50aXR5LgotICAgICAqIEBwYXJhbSBwdWJsaWNJZCAgICAgVGhlIHB1YmxpYyBpZGVudGlmaWVyIG9mIHRoZSBlbnRpdHkuCi0gICAgICogQHBhcmFtIGxpdGVyYWxTeXN0ZW1JZCAgICAgVGhlIHN5c3RlbSBpZGVudGlmaWVyIG9mIHRoZSBlbnRpdHkuCi0gICAgICogQHBhcmFtIGJhc2VTeXN0ZW1JZCBUaGUgYmFzZSBzeXN0ZW0gaWRlbnRpZmllciBvZiB0aGUgZW50aXR5LgotICAgICAqICAgICAgICAgICAgICAgICAgICAgVGhpcyBpcyB0aGUgc3lzdGVtIGlkZW50aWZpZXIgb2YgdGhlIGVudGl0eQotICAgICAqICAgICAgICAgICAgICAgICAgICAgd2hlcmUgPGVtPnRoZSBlbnRpdHkgYmVpbmcgYWRkZWQ8L2VtPiBhbmQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgIGlzIHVzZWQgdG8gZXhwYW5kIHRoZSBzeXN0ZW0gaWRlbnRpZmllciB3aGVuCi0gICAgICogICAgICAgICAgICAgICAgICAgICB0aGUgc3lzdGVtIGlkZW50aWZpZXIgaXMgYSByZWxhdGl2ZSBVUkkuCi0gICAgICogICAgICAgICAgICAgICAgICAgICBXaGVuIG51bGwgdGhlIHN5c3RlbSBpZGVudGlmaWVyIG9mIHRoZSBmaXJzdAotICAgICAqICAgICAgICAgICAgICAgICAgICAgZXh0ZXJuYWwgZW50aXR5IG9uIHRoZSBzdGFjayBpcyB1c2VkIGluc3RlYWQuCi0gICAgICoKLSAgICAgKiBAc2VlIFN5bWJvbFRhYmxlCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgYWRkRXh0ZXJuYWxFbnRpdHkoU3RyaW5nIG5hbWUsCi0gICAgU3RyaW5nIHB1YmxpY0lkLCBTdHJpbmcgbGl0ZXJhbFN5c3RlbUlkLAotICAgIFN0cmluZyBiYXNlU3lzdGVtSWQpIHsKLSAgICAgICAgaWYgKCFmRW50aXRpZXMuY29udGFpbnNLZXkobmFtZSkpIHsKLSAgICAgICAgICAgIGlmIChiYXNlU3lzdGVtSWQgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIC8vIHNlYXJjaCBmb3IgdGhlIGZpcnN0IGV4dGVybmFsIGVudGl0eSBvbiB0aGUgc3RhY2sKLSAgICAgICAgICAgICAgICAvL3h4eCBjb21tZW50aW5nIHRoZSAnc2l6ZScgdmFyaWFibGUuLgotICAgICAgICAgICAgICAgIC8qKgotICAgICAgICAgICAgICAgICAqIGludCBzaXplID0gZkVudGl0eVN0YWNrLnNpemUoKTsKLSAgICAgICAgICAgICAgICAgKiBpZiAoc2l6ZSA9PSAwICYmIGZDdXJyZW50RW50aXR5ICE9IG51bGwgJiYgZkN1cnJlbnRFbnRpdHkuZW50aXR5TG9jYXRpb24gIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAqIGJhc2VTeXN0ZW1JZCA9IGZDdXJyZW50RW50aXR5LmVudGl0eUxvY2F0aW9uLmdldEV4cGFuZGVkU3lzdGVtSWQoKTsKLSAgICAgICAgICAgICAgICAgKiB9Ci0gICAgICAgICAgICAgICAgICovCi0KLSAgICAgICAgICAgICAgICAvL3h4eCB3ZSBuZWVkIHRvIGhhdmUgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGN1cnJlbnQgZW50aXR5LgotICAgICAgICAgICAgICAgIGlmIChmQ3VycmVudEVudGl0eSAhPSBudWxsICYmIGZDdXJyZW50RW50aXR5LmVudGl0eUxvY2F0aW9uICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgYmFzZVN5c3RlbUlkID0gZkN1cnJlbnRFbnRpdHkuZW50aXR5TG9jYXRpb24uZ2V0RXhwYW5kZWRTeXN0ZW1JZCgpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvKioKLSAgICAgICAgICAgICAgICAgKiBmb3IgKGludCBpID0gc2l6ZSAtIDE7IGkgPj0gMCA7IGktLSkgewotICAgICAgICAgICAgICAgICAqIFNjYW5uZWRFbnRpdHkgZXh0ZXJuYWxFbnRpdHkgPQotICAgICAgICAgICAgICAgICAqIChTY2FubmVkRW50aXR5KWZFbnRpdHlTdGFjay5lbGVtZW50QXQoaSk7Ci0gICAgICAgICAgICAgICAgICogaWYgKGV4dGVybmFsRW50aXR5LmVudGl0eUxvY2F0aW9uICE9IG51bGwgJiYgZXh0ZXJuYWxFbnRpdHkuZW50aXR5TG9jYXRpb24uZ2V0RXhwYW5kZWRTeXN0ZW1JZCgpICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgKiBiYXNlU3lzdGVtSWQgPSBleHRlcm5hbEVudGl0eS5lbnRpdHlMb2NhdGlvbi5nZXRFeHBhbmRlZFN5c3RlbUlkKCk7Ci0gICAgICAgICAgICAgICAgICogYnJlYWs7Ci0gICAgICAgICAgICAgICAgICogfQotICAgICAgICAgICAgICAgICAqIH0KLSAgICAgICAgICAgICAgICAgKi8KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgZkN1cnJlbnRFbnRpdHkgPSBmRW50aXR5TWFuYWdlci5nZXRDdXJyZW50RW50aXR5KCk7Ci0gICAgICAgICAgICBFbnRpdHkgZW50aXR5ID0gbmV3IEVudGl0eS5FeHRlcm5hbEVudGl0eShuYW1lLAotICAgICAgICAgICAgbmV3IFhNTFJlc291cmNlSWRlbnRpZmllckltcGwocHVibGljSWQsIGxpdGVyYWxTeXN0ZW1JZCwKLSAgICAgICAgICAgIGJhc2VTeXN0ZW1JZCwgZXhwYW5kU3lzdGVtSWQobGl0ZXJhbFN5c3RlbUlkLCBiYXNlU3lzdGVtSWQpKSwKLSAgICAgICAgICAgIG51bGwsIGZJbkV4dGVybmFsU3Vic2V0KTsKLSAgICAgICAgICAgIC8vVE9ETyA6OiBGb3JjZWQgdG8gcGFzcyB0cnVlIGFib3ZlIHJlbW92ZSBpdC4KLSAgICAgICAgICAgIC8vKGZDdXJyZW50RW50aXR5ID09IG51bGwpID8gZmFzbGUgOiBmQ3VycmVudEVudGl0eS5pc0VudGl0eURlY2xJbkV4dGVybmFsU3Vic2V0KCkpOwotICAgICAgICAgICAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwgZkN1cnJlbnRFbnRpdHkuaXNFbnRpdHlEZWNsSW5FeHRlcm5hbFN1YnNldCgpKTsKLSAgICAgICAgICAgIGZFbnRpdGllcy5wdXQobmFtZSwgZW50aXR5KTsKLSAgICAgICAgfQotICAgICAgICBlbHNlewotICAgICAgICAgICAgaWYoZldhcm5EdXBsaWNhdGVFbnRpdHlEZWYpewotICAgICAgICAgICAgICAgIGZFcnJvclJlcG9ydGVyLnJlcG9ydEVycm9yKFhNTE1lc3NhZ2VGb3JtYXR0ZXIuWE1MX0RPTUFJTiwKLSAgICAgICAgICAgICAgICAiTVNHX0RVUExJQ0FURV9FTlRJVFlfREVGSU5JVElPTiIsCi0gICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdeyBuYW1lIH0sCi0gICAgICAgICAgICAgICAgWE1MRXJyb3JSZXBvcnRlci5TRVZFUklUWV9XQVJOSU5HICk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgIH0gLy8gYWRkRXh0ZXJuYWxFbnRpdHkoU3RyaW5nLFN0cmluZyxTdHJpbmcsU3RyaW5nKQotCi0gICAgLyoqCi0gICAgICogQ2hlY2tzIHdoZXRoZXIgYW4gZW50aXR5IGdpdmVuIGJ5IG5hbWUgaXMgZXh0ZXJuYWwuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZW50aXR5TmFtZSBUaGUgbmFtZSBvZiB0aGUgZW50aXR5IHRvIGNoZWNrLgotICAgICAqIEByZXR1cm5zIFRydWUgaWYgdGhlIGVudGl0eSBpcyBleHRlcm5hbCwgZmFsc2Ugb3RoZXJ3aXNlCi0gICAgICogICAgICAgICAgIChpbmNsdWRpbmcgd2hlbiB0aGUgZW50aXR5IGlzIG5vdCBkZWNsYXJlZCkuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNFeHRlcm5hbEVudGl0eShTdHJpbmcgZW50aXR5TmFtZSkgewotCi0gICAgICAgIEVudGl0eSBlbnRpdHkgPSBmRW50aXRpZXMuZ2V0KGVudGl0eU5hbWUpOwotICAgICAgICBpZiAoZW50aXR5ID09IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZW50aXR5LmlzRXh0ZXJuYWwoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDaGVja3Mgd2hldGhlciB0aGUgZGVjbGFyYXRpb24gb2YgYW4gZW50aXR5IGdpdmVuIGJ5IG5hbWUgaXMKLSAgICAgKiAvLyBpbiB0aGUgZXh0ZXJuYWwgc3Vic2V0LgotICAgICAqCi0gICAgICogQHBhcmFtIGVudGl0eU5hbWUgVGhlIG5hbWUgb2YgdGhlIGVudGl0eSB0byBjaGVjay4KLSAgICAgKiBAcmV0dXJucyBUcnVlIGlmIHRoZSBlbnRpdHkgd2FzIGRlY2xhcmVkIGluIHRoZSBleHRlcm5hbCBzdWJzZXQsIGZhbHNlIG90aGVyd2lzZQotICAgICAqICAgICAgICAgICAoaW5jbHVkaW5nIHdoZW4gdGhlIGVudGl0eSBpcyBub3QgZGVjbGFyZWQpLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzRW50aXR5RGVjbEluRXh0ZXJuYWxTdWJzZXQoU3RyaW5nIGVudGl0eU5hbWUpIHsKLQotICAgICAgICBFbnRpdHkgZW50aXR5ID0gZkVudGl0aWVzLmdldChlbnRpdHlOYW1lKTsKLSAgICAgICAgaWYgKGVudGl0eSA9PSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGVudGl0eS5pc0VudGl0eURlY2xJbkV4dGVybmFsU3Vic2V0KCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQWRkcyBhbiB1bnBhcnNlZCBlbnRpdHkgZGVjbGFyYXRpb24uCi0gICAgICogPHA+Ci0gICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGlzIG1ldGhvZCBpZ25vcmVzIHN1YnNlcXVlbnQgZW50aXR5Ci0gICAgICogZGVjbGFyYXRpb25zLgotICAgICAqIDxwPgotICAgICAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gVGhlIG5hbWUgc2hvdWxkIGJlIGEgdW5pcXVlIHN5bWJvbC4gVGhlCi0gICAgICogU3ltYm9sVGFibGUgY2FuIGJlIHVzZWQgZm9yIHRoaXMgcHVycG9zZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lICAgICBUaGUgbmFtZSBvZiB0aGUgZW50aXR5LgotICAgICAqIEBwYXJhbSBwdWJsaWNJZCBUaGUgcHVibGljIGlkZW50aWZpZXIgb2YgdGhlIGVudGl0eS4KLSAgICAgKiBAcGFyYW0gc3lzdGVtSWQgVGhlIHN5c3RlbSBpZGVudGlmaWVyIG9mIHRoZSBlbnRpdHkuCi0gICAgICogQHBhcmFtIG5vdGF0aW9uIFRoZSBuYW1lIG9mIHRoZSBub3RhdGlvbi4KLSAgICAgKgotICAgICAqIEBzZWUgU3ltYm9sVGFibGUKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBhZGRVbnBhcnNlZEVudGl0eShTdHJpbmcgbmFtZSwKLSAgICBTdHJpbmcgcHVibGljSWQsIFN0cmluZyBzeXN0ZW1JZCwKLSAgICBTdHJpbmcgYmFzZVN5c3RlbUlkLCBTdHJpbmcgbm90YXRpb24pIHsKLQotICAgICAgICBmQ3VycmVudEVudGl0eSA9IGZFbnRpdHlNYW5hZ2VyLmdldEN1cnJlbnRFbnRpdHkoKTsKLSAgICAgICAgaWYgKCFmRW50aXRpZXMuY29udGFpbnNLZXkobmFtZSkpIHsKLSAgICAgICAgICAgIEVudGl0eSBlbnRpdHkgPSBuZXcgRW50aXR5LkV4dGVybmFsRW50aXR5KG5hbWUsIG5ldyBYTUxSZXNvdXJjZUlkZW50aWZpZXJJbXBsKHB1YmxpY0lkLCBzeXN0ZW1JZCwgYmFzZVN5c3RlbUlkLCBudWxsKSwgbm90YXRpb24sIGZJbkV4dGVybmFsU3Vic2V0KTsKLSAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgICAgKGZDdXJyZW50RW50aXR5ID09IG51bGwpID8gZmFzbGUgOiBmQ3VycmVudEVudGl0eS5pc0VudGl0eURlY2xJbkV4dGVybmFsU3Vic2V0KCkpOwotICAgICAgICAgICAgLy8gICAgICAgICAgICAgICAgICBmQ3VycmVudEVudGl0eS5pc0VudGl0eURlY2xJbkV4dGVybmFsU3Vic2V0KCkpOwotICAgICAgICAgICAgZkVudGl0aWVzLnB1dChuYW1lLCBlbnRpdHkpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2V7Ci0gICAgICAgICAgICBpZihmV2FybkR1cGxpY2F0ZUVudGl0eURlZil7Ci0gICAgICAgICAgICAgICAgZkVycm9yUmVwb3J0ZXIucmVwb3J0RXJyb3IoWE1MTWVzc2FnZUZvcm1hdHRlci5YTUxfRE9NQUlOLAotICAgICAgICAgICAgICAgICJNU0dfRFVQTElDQVRFX0VOVElUWV9ERUZJTklUSU9OIiwKLSAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117IG5hbWUgfSwKLSAgICAgICAgICAgICAgICBYTUxFcnJvclJlcG9ydGVyLlNFVkVSSVRZX1dBUk5JTkcgKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0gLy8gYWRkVW5wYXJzZWRFbnRpdHkoU3RyaW5nLFN0cmluZyxTdHJpbmcsU3RyaW5nKQotCi0gICAgLyoqCi0gICAgICogQ2hlY2tzIHdoZXRoZXIgYW4gZW50aXR5IGdpdmVuIGJ5IG5hbWUgaXMgdW5wYXJzZWQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZW50aXR5TmFtZSBUaGUgbmFtZSBvZiB0aGUgZW50aXR5IHRvIGNoZWNrLgotICAgICAqIEByZXR1cm5zIFRydWUgaWYgdGhlIGVudGl0eSBpcyB1bnBhcnNlZCwgZmFsc2Ugb3RoZXJ3aXNlCi0gICAgICogICAgICAgICAgKGluY2x1ZGluZyB3aGVuIHRoZSBlbnRpdHkgaXMgbm90IGRlY2xhcmVkKS4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc1VucGFyc2VkRW50aXR5KFN0cmluZyBlbnRpdHlOYW1lKSB7Ci0KLSAgICAgICAgRW50aXR5IGVudGl0eSA9IGZFbnRpdGllcy5nZXQoZW50aXR5TmFtZSk7Ci0gICAgICAgIGlmIChlbnRpdHkgPT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBlbnRpdHkuaXNVbnBhcnNlZCgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENoZWNrcyB3aGV0aGVyIGFuIGVudGl0eSBnaXZlbiBieSBuYW1lIGlzIGRlY2xhcmVkLgotICAgICAqCi0gICAgICogQHBhcmFtIGVudGl0eU5hbWUgVGhlIG5hbWUgb2YgdGhlIGVudGl0eSB0byBjaGVjay4KLSAgICAgKiBAcmV0dXJucyBUcnVlIGlmIHRoZSBlbnRpdHkgaXMgZGVjbGFyZWQsIGZhbHNlIG90aGVyd2lzZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0RlY2xhcmVkRW50aXR5KFN0cmluZyBlbnRpdHlOYW1lKSB7Ci0KLSAgICAgICAgRW50aXR5IGVudGl0eSA9IGZFbnRpdGllcy5nZXQoZW50aXR5TmFtZSk7Ci0gICAgICAgIHJldHVybiBlbnRpdHkgIT0gbnVsbDsKLSAgICB9Ci0gICAgLyoqCi0gICAgICogRXhwYW5kcyBhIHN5c3RlbSBpZCBhbmQgcmV0dXJucyB0aGUgc3lzdGVtIGlkIGFzIGEgVVJJLCBpZgotICAgICAqIGl0IGNhbiBiZSBleHBhbmRlZC4gQSByZXR1cm4gdmFsdWUgb2YgbnVsbCBtZWFucyB0aGF0IHRoZQotICAgICAqIGlkZW50aWZpZXIgaXMgYWxyZWFkeSBleHBhbmRlZC4gQW4gZXhjZXB0aW9uIHRocm93bgotICAgICAqIGluZGljYXRlcyBhIGZhaWx1cmUgdG8gZXhwYW5kIHRoZSBpZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzeXN0ZW1JZCBUaGUgc3lzdGVtSWQgdG8gYmUgZXhwYW5kZWQuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFJldHVybnMgdGhlIFVSSSBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBleHBhbmRlZCBzeXN0ZW0KLSAgICAgKiAgICAgICAgIGlkZW50aWZpZXIuIEEgbnVsbCB2YWx1ZSBpbmRpY2F0ZXMgdGhhdCB0aGUgZ2l2ZW4KLSAgICAgKiAgICAgICAgIHN5c3RlbSBpZGVudGlmaWVyIGlzIGFscmVhZHkgZXhwYW5kZWQuCi0gICAgICoKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBleHBhbmRTeXN0ZW1JZChTdHJpbmcgc3lzdGVtSWQpIHsKLSAgICAgICAgcmV0dXJuIGV4cGFuZFN5c3RlbUlkKHN5c3RlbUlkLCBudWxsKTsKLSAgICB9IC8vIGV4cGFuZFN5c3RlbUlkKFN0cmluZyk6U3RyaW5nCi0KLSAgICAvLyBjdXJyZW50IHZhbHVlIG9mIHRoZSAidXNlci5kaXIiIHByb3BlcnR5Ci0gICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGdVc2VyRGlyOwotICAgIC8vIGVzY2FwZWQgdmFsdWUgb2YgdGhlIGN1cnJlbnQgInVzZXIuZGlyIiBwcm9wZXJ0eQotICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBnRXNjYXBlZFVzZXJEaXI7Ci0gICAgLy8gd2hpY2ggQVNDSUkgY2hhcmFjdGVycyBuZWVkIHRvIGJlIGVzY2FwZWQKLSAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGdOZWVkRXNjYXBpbmdbXSA9IG5ldyBib29sZWFuWzEyOF07Ci0gICAgLy8gdGhlIGZpcnN0IGhleCBjaGFyYWN0ZXIgaWYgYSBjaGFyYWN0ZXIgbmVlZHMgdG8gYmUgZXNjYXBlZAotICAgIHByaXZhdGUgc3RhdGljIGNoYXIgZ0FmdGVyRXNjYXBpbmcxW10gPSBuZXcgY2hhclsxMjhdOwotICAgIC8vIHRoZSBzZWNvbmQgaGV4IGNoYXJhY3RlciBpZiBhIGNoYXJhY3RlciBuZWVkcyB0byBiZSBlc2NhcGVkCi0gICAgcHJpdmF0ZSBzdGF0aWMgY2hhciBnQWZ0ZXJFc2NhcGluZzJbXSA9IG5ldyBjaGFyWzEyOF07Ci0gICAgcHJpdmF0ZSBzdGF0aWMgY2hhcltdIGdIZXhDaHMgPSB7JzAnLCAnMScsICcyJywgJzMnLCAnNCcsICc1JywgJzYnLCAnNycsCi0gICAgJzgnLCAnOScsICdBJywgJ0InLCAnQycsICdEJywgJ0UnLCAnRid9OwotICAgIC8vIGluaXRpYWxpemUgdGhlIGFib3ZlIDMgYXJyYXlzCi0gICAgc3RhdGljIHsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPD0gMHgxZjsgaSsrKSB7Ci0gICAgICAgICAgICBnTmVlZEVzY2FwaW5nW2ldID0gdHJ1ZTsKLSAgICAgICAgICAgIGdBZnRlckVzY2FwaW5nMVtpXSA9IGdIZXhDaHNbaSA+PiA0XTsKLSAgICAgICAgICAgIGdBZnRlckVzY2FwaW5nMltpXSA9IGdIZXhDaHNbaSAmIDB4Zl07Ci0gICAgICAgIH0KLSAgICAgICAgZ05lZWRFc2NhcGluZ1sweDdmXSA9IHRydWU7Ci0gICAgICAgIGdBZnRlckVzY2FwaW5nMVsweDdmXSA9ICc3JzsKLSAgICAgICAgZ0FmdGVyRXNjYXBpbmcyWzB4N2ZdID0gJ0YnOwotICAgICAgICBjaGFyW10gZXNjQ2hzID0geycgJywgJzwnLCAnPicsICcjJywgJyUnLCAnIicsICd7JywgJ30nLAotICAgICAgICAnfCcsICdcXCcsICdeJywgJ34nLCAnWycsICddJywgJ2AnfTsKLSAgICAgICAgaW50IGxlbiA9IGVzY0Nocy5sZW5ndGg7Ci0gICAgICAgIGNoYXIgY2g7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKLSAgICAgICAgICAgIGNoID0gZXNjQ2hzW2ldOwotICAgICAgICAgICAgZ05lZWRFc2NhcGluZ1tjaF0gPSB0cnVlOwotICAgICAgICAgICAgZ0FmdGVyRXNjYXBpbmcxW2NoXSA9IGdIZXhDaHNbY2ggPj4gNF07Ci0gICAgICAgICAgICBnQWZ0ZXJFc2NhcGluZzJbY2hdID0gZ0hleENoc1tjaCAmIDB4Zl07Ci0gICAgICAgIH0KLSAgICB9Ci0gICAgLy8gVG8gZXNjYXBlIHRoZSAidXNlci5kaXIiIHN5c3RlbSBwcm9wZXJ0eSwgYnkgdXNpbmcgJUhIIHRvIHJlcHJlc2VudAotICAgIC8vIHNwZWNpYWwgQVNDSUkgY2hhcmFjdGVyczogMHgwMH4weDFGLCAweDdGLCAnICcsICc8JywgJz4nLCAnIycsICclJwotICAgIC8vIGFuZCAnIicuIEl0J3MgYSBzdGF0aWMgbWV0aG9kLCBzbyBuZWVkcyB0byBiZSBzeW5jaHJvbml6ZWQuCi0gICAgLy8gdGhpcyBtZXRob2QgbG9va3MgaGVhdnksIGJ1dCBzaW5jZSB0aGUgc3lzdGVtIHByb3BlcnR5IGlzbid0IGV4cGVjdGVkCi0gICAgLy8gdG8gY2hhbmdlIG9mdGVuLCBzbyBpbiBtb3N0IGNhc2VzLCB3ZSBvbmx5IG5lZWQgdG8gcmV0dXJuIHRoZSBzdHJpbmcKLSAgICAvLyB0aGF0IHdhcyBlc2NhcGVkIGJlZm9yZS4KLSAgICAvLyBBY2NvcmRpbmcgdG8gdGhlIFVSSSBzcGVjLCBub24tQVNDSUkgY2hhcmFjdGVycyAod2hvc2UgdmFsdWUgPj0gMTI4KQotICAgIC8vIG5lZWQgdG8gYmUgZXNjYXBlZCB0b28uCi0gICAgLy8gUkVWSVNJVDogZG9uJ3Qga25vdyBob3cgdG8gZXNjYXBlIG5vbi1BU0NJSSBjaGFyYWN0ZXJzLCBlc3BlY2lhbGx5Ci0gICAgLy8gd2hpY2ggZW5jb2RpbmcgdG8gdXNlLiBMZWF2ZSB0aGVtIGZvciBub3cuCi0gICAgcHJpdmF0ZSBzdGF0aWMgc3luY2hyb25pemVkIFN0cmluZyBnZXRVc2VyRGlyKCkgewotICAgICAgICAvLyBnZXQgdGhlIHVzZXIuZGlyIHByb3BlcnR5Ci0gICAgICAgIFN0cmluZyB1c2VyRGlyID0gIiI7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICB1c2VyRGlyID0gU2VjdXJpdHlTdXBwb3J0LmdldFN5c3RlbVByb3BlcnR5KCJ1c2VyLmRpciIpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBzZSkgewotICAgICAgICB9Ci0KLSAgICAgICAgLy8gcmV0dXJuIGVtcHR5IHN0cmluZyBpZiBwcm9wZXJ0eSB2YWx1ZSBpcyBlbXB0eSBzdHJpbmcuCi0gICAgICAgIGlmICh1c2VyRGlyLmxlbmd0aCgpID09IDApCi0gICAgICAgICAgICByZXR1cm4gIiI7Ci0KLSAgICAgICAgLy8gY29tcHV0ZSB0aGUgbmV3IGVzY2FwZWQgdmFsdWUgaWYgdGhlIG5ldyBwcm9wZXJ0eSB2YWx1ZSBkb2Vzbid0Ci0gICAgICAgIC8vIG1hdGNoIHRoZSBwcmV2aW91cyBvbmUKLSAgICAgICAgaWYgKHVzZXJEaXIuZXF1YWxzKGdVc2VyRGlyKSkgewotICAgICAgICAgICAgcmV0dXJuIGdFc2NhcGVkVXNlckRpcjsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIHJlY29yZCB0aGUgbmV3IHZhbHVlIGFzIHRoZSBnbG9iYWwgcHJvcGVydHkgdmFsdWUKLSAgICAgICAgZ1VzZXJEaXIgPSB1c2VyRGlyOwotCi0gICAgICAgIGNoYXIgc2VwYXJhdG9yID0gamF2YS5pby5GaWxlLnNlcGFyYXRvckNoYXI7Ci0gICAgICAgIHVzZXJEaXIgPSB1c2VyRGlyLnJlcGxhY2Uoc2VwYXJhdG9yLCAnLycpOwotCi0gICAgICAgIGludCBsZW4gPSB1c2VyRGlyLmxlbmd0aCgpLCBjaDsKLSAgICAgICAgU3RyaW5nQnVmZmVyIGJ1ZmZlciA9IG5ldyBTdHJpbmdCdWZmZXIobGVuKjMpOwotICAgICAgICAvLyBjaGFuZ2UgQzovYmxhaCB0byAvQzovYmxhaAotICAgICAgICBpZiAobGVuID49IDIgJiYgdXNlckRpci5jaGFyQXQoMSkgPT0gJzonKSB7Ci0gICAgICAgICAgICBjaCA9IENoYXJhY3Rlci50b1VwcGVyQ2FzZSh1c2VyRGlyLmNoYXJBdCgwKSk7Ci0gICAgICAgICAgICBpZiAoY2ggPj0gJ0EnICYmIGNoIDw9ICdaJykgewotICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoJy8nKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIGZvciBlYWNoIGNoYXJhY3RlciBpbiB0aGUgcGF0aAotICAgICAgICBpbnQgaSA9IDA7Ci0gICAgICAgIGZvciAoOyBpIDwgbGVuOyBpKyspIHsKLSAgICAgICAgICAgIGNoID0gdXNlckRpci5jaGFyQXQoaSk7Ci0gICAgICAgICAgICAvLyBpZiBpdCdzIG5vdCBhbiBBU0NJSSBjaGFyYWN0ZXIsIGJyZWFrIGhlcmUsIGFuZCB1c2UgVVRGLTggZW5jb2RpbmcKLSAgICAgICAgICAgIGlmIChjaCA+PSAxMjgpCi0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICBpZiAoZ05lZWRFc2NhcGluZ1tjaF0pIHsKLSAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCclJyk7Ci0gICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZChnQWZ0ZXJFc2NhcGluZzFbY2hdKTsKLSAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKGdBZnRlckVzY2FwaW5nMltjaF0pOwotICAgICAgICAgICAgICAgIC8vIHJlY29yZCB0aGUgZmFjdCB0aGF0IGl0J3MgZXNjYXBlZAotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgoY2hhciljaCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyB3ZSBzYXcgc29tZSBub24tYXNjaWkgY2hhcmFjdGVyCi0gICAgICAgIGlmIChpIDwgbGVuKSB7Ci0gICAgICAgICAgICAvLyBnZXQgVVRGLTggYnl0ZXMgZm9yIHRoZSByZW1haW5pbmcgc3ViLXN0cmluZwotICAgICAgICAgICAgYnl0ZVtdIGJ5dGVzID0gbnVsbDsKLSAgICAgICAgICAgIGJ5dGUgYjsKLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgYnl0ZXMgPSB1c2VyRGlyLnN1YnN0cmluZyhpKS5nZXRCeXRlcygiVVRGLTgiKTsKLSAgICAgICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgLy8gc2hvdWxkIG5ldmVyIGhhcHBlbgotICAgICAgICAgICAgICAgIHJldHVybiB1c2VyRGlyOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgbGVuID0gYnl0ZXMubGVuZ3RoOwotCi0gICAgICAgICAgICAvLyBmb3IgZWFjaCBieXRlCi0gICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKLSAgICAgICAgICAgICAgICBiID0gYnl0ZXNbaV07Ci0gICAgICAgICAgICAgICAgLy8gZm9yIG5vbi1hc2NpaSBjaGFyYWN0ZXI6IG1ha2UgaXQgcG9zaXRpdmUsIHRoZW4gZXNjYXBlCi0gICAgICAgICAgICAgICAgaWYgKGIgPCAwKSB7Ci0gICAgICAgICAgICAgICAgICAgIGNoID0gYiArIDI1NjsKLSAgICAgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgnJScpOwotICAgICAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKGdIZXhDaHNbY2ggPj4gNF0pOwotICAgICAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKGdIZXhDaHNbY2ggJiAweGZdKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSBpZiAoZ05lZWRFc2NhcGluZ1tiXSkgewotICAgICAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCclJyk7Ci0gICAgICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoZ0FmdGVyRXNjYXBpbmcxW2JdKTsKLSAgICAgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZChnQWZ0ZXJFc2NhcGluZzJbYl0pOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgoY2hhciliKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBjaGFuZ2UgYmxhaC9ibGFoIHRvIGJsYWgvYmxhaC8KLSAgICAgICAgaWYgKCF1c2VyRGlyLmVuZHNXaXRoKCIvIikpCi0gICAgICAgICAgICBidWZmZXIuYXBwZW5kKCcvJyk7Ci0KLSAgICAgICAgZ0VzY2FwZWRVc2VyRGlyID0gYnVmZmVyLnRvU3RyaW5nKCk7Ci0KLSAgICAgICAgcmV0dXJuIGdFc2NhcGVkVXNlckRpcjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBFeHBhbmRzIGEgc3lzdGVtIGlkIGFuZCByZXR1cm5zIHRoZSBzeXN0ZW0gaWQgYXMgYSBVUkksIGlmCi0gICAgICogaXQgY2FuIGJlIGV4cGFuZGVkLiBBIHJldHVybiB2YWx1ZSBvZiBudWxsIG1lYW5zIHRoYXQgdGhlCi0gICAgICogaWRlbnRpZmllciBpcyBhbHJlYWR5IGV4cGFuZGVkLiBBbiBleGNlcHRpb24gdGhyb3duCi0gICAgICogaW5kaWNhdGVzIGEgZmFpbHVyZSB0byBleHBhbmQgdGhlIGlkLgotICAgICAqCi0gICAgICogQHBhcmFtIHN5c3RlbUlkIFRoZSBzeXN0ZW1JZCB0byBiZSBleHBhbmRlZC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gUmV0dXJucyB0aGUgVVJJIHN0cmluZyByZXByZXNlbnRpbmcgdGhlIGV4cGFuZGVkIHN5c3RlbQotICAgICAqICAgICAgICAgaWRlbnRpZmllci4gQSBudWxsIHZhbHVlIGluZGljYXRlcyB0aGF0IHRoZSBnaXZlbgotICAgICAqICAgICAgICAgc3lzdGVtIGlkZW50aWZpZXIgaXMgYWxyZWFkeSBleHBhbmRlZC4KLSAgICAgKgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGV4cGFuZFN5c3RlbUlkKFN0cmluZyBzeXN0ZW1JZCwgU3RyaW5nIGJhc2VTeXN0ZW1JZCkgewotCi0gICAgICAgIC8vIGNoZWNrIGZvciBiYWQgcGFyYW1ldGVycyBpZAotICAgICAgICBpZiAoc3lzdGVtSWQgPT0gbnVsbCB8fCBzeXN0ZW1JZC5sZW5ndGgoKSA9PSAwKSB7Ci0gICAgICAgICAgICByZXR1cm4gc3lzdGVtSWQ7Ci0gICAgICAgIH0KLSAgICAgICAgLy8gaWYgaWQgYWxyZWFkeSBleHBhbmRlZCwgcmV0dXJuCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBuZXcgVVJJKHN5c3RlbUlkKTsKLSAgICAgICAgICAgIHJldHVybiBzeXN0ZW1JZDsKLSAgICAgICAgfSBjYXRjaCAoVVJJLk1hbGZvcm1lZFVSSUV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAvLyBjb250aW51ZSBvbi4uLgotICAgICAgICB9Ci0gICAgICAgIC8vIG5vcm1hbGl6ZSBpZAotICAgICAgICBTdHJpbmcgaWQgPSBmaXhVUkkoc3lzdGVtSWQpOwotCi0gICAgICAgIC8vIG5vcm1hbGl6ZSBiYXNlCi0gICAgICAgIFVSSSBiYXNlID0gbnVsbDsKLSAgICAgICAgVVJJIHVyaSA9IG51bGw7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBpZiAoYmFzZVN5c3RlbUlkID09IG51bGwgfHwgYmFzZVN5c3RlbUlkLmxlbmd0aCgpID09IDAgfHwKLSAgICAgICAgICAgIGJhc2VTeXN0ZW1JZC5lcXVhbHMoc3lzdGVtSWQpKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIGRpciA9IGdldFVzZXJEaXIoKTsKLSAgICAgICAgICAgICAgICBiYXNlID0gbmV3IFVSSSgiZmlsZSIsICIiLCBkaXIsIG51bGwsIG51bGwpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgYmFzZSA9IG5ldyBVUkkoZml4VVJJKGJhc2VTeXN0ZW1JZCkpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBjYXRjaCAoVVJJLk1hbGZvcm1lZFVSSUV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChiYXNlU3lzdGVtSWQuaW5kZXhPZignOicpICE9IC0xKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyBmb3IgeG1sIHNjaGVtYXMgd2UgbWlnaHQgaGF2ZSBiYXNlVVJJIHdpdGgKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGEgc3BlY2lmaWVkIGRyaXZlCi0gICAgICAgICAgICAgICAgICAgICAgICBiYXNlID0gbmV3IFVSSSgiZmlsZSIsICIiLCBmaXhVUkkoYmFzZVN5c3RlbUlkKSwgbnVsbCwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgZGlyID0gZ2V0VXNlckRpcigpOwotICAgICAgICAgICAgICAgICAgICAgICAgZGlyID0gZGlyICsgZml4VVJJKGJhc2VTeXN0ZW1JZCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBiYXNlID0gbmV3IFVSSSgiZmlsZSIsICIiLCBkaXIsIG51bGwsIG51bGwpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gZXhwYW5kIGlkCi0gICAgICAgICAgICB1cmkgPSBuZXcgVVJJKGJhc2UsIGlkKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIC8vIGxldCBpdCBnbyB0aHJvdWdoCi0KLSAgICAgICAgfQotCi0gICAgICAgIGlmICh1cmkgPT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIHN5c3RlbUlkOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiB1cmkudG9TdHJpbmcoKTsKLQotICAgIH0gLy8gZXhwYW5kU3lzdGVtSWQoU3RyaW5nLFN0cmluZyk6U3RyaW5nCi0gICAgLy8KLSAgICAvLyBQcm90ZWN0ZWQgc3RhdGljIG1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogRml4ZXMgYSBwbGF0Zm9ybSBkZXBlbmRlbnQgZmlsZW5hbWUgdG8gc3RhbmRhcmQgVVJJIGZvcm0uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc3RyIFRoZSBzdHJpbmcgdG8gZml4LgotICAgICAqCi0gICAgICogQHJldHVybiBSZXR1cm5zIHRoZSBmaXhlZCBVUkkgc3RyaW5nLgotICAgICAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgU3RyaW5nIGZpeFVSSShTdHJpbmcgc3RyKSB7Ci0KLSAgICAgICAgLy8gaGFuZGxlIHBsYXRmb3JtIGRlcGVuZGVudCBzdHJpbmdzCi0gICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKGphdmEuaW8uRmlsZS5zZXBhcmF0b3JDaGFyLCAnLycpOwotCi0gICAgICAgIC8vIFdpbmRvd3MgZml4Ci0gICAgICAgIGlmIChzdHIubGVuZ3RoKCkgPj0gMikgewotICAgICAgICAgICAgY2hhciBjaDEgPSBzdHIuY2hhckF0KDEpOwotICAgICAgICAgICAgLy8gY2hhbmdlICJDOmJsYWgiIHRvICIvQzpibGFoIgotICAgICAgICAgICAgaWYgKGNoMSA9PSAnOicpIHsKLSAgICAgICAgICAgICAgICBjaGFyIGNoMCA9IENoYXJhY3Rlci50b1VwcGVyQ2FzZShzdHIuY2hhckF0KDApKTsKLSAgICAgICAgICAgICAgICBpZiAoY2gwID49ICdBJyAmJiBjaDAgPD0gJ1onKSB7Ci0gICAgICAgICAgICAgICAgICAgIHN0ciA9ICIvIiArIHN0cjsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyBjaGFuZ2UgIi8vYmxhaCIgdG8gImZpbGU6Ly9ibGFoIgotICAgICAgICAgICAgZWxzZSBpZiAoY2gxID09ICcvJyAmJiBzdHIuY2hhckF0KDApID09ICcvJykgewotICAgICAgICAgICAgICAgIHN0ciA9ICJmaWxlOiIgKyBzdHI7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBkb25lCi0gICAgICAgIHJldHVybiBzdHI7Ci0KLSAgICB9IC8vIGZpeFVSSShTdHJpbmcpOlN0cmluZwotCi0gICAgLy8gaW5kaWNhdGUgc3RhcnQgb2YgZXh0ZXJuYWwgc3Vic2V0Ci0gICAgcHVibGljIHZvaWQgc3RhcnRFeHRlcm5hbFN1YnNldCgpIHsKLSAgICAgICAgZkluRXh0ZXJuYWxTdWJzZXQgPSB0cnVlOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGVuZEV4dGVybmFsU3Vic2V0KCkgewotICAgICAgICBmSW5FeHRlcm5hbFN1YnNldCA9IGZhbHNlOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL3htbC9pbnRlcm5hbC9zdHJlYW0vWE1MRXZlbnRSZWFkZXJJbXBsLmphdmEgYi9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL1hNTEV2ZW50UmVhZGVySW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlZTQxMDNhLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL3htbC9pbnRlcm5hbC9zdHJlYW0vWE1MRXZlbnRSZWFkZXJJbXBsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyODcgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLnhtbC5pbnRlcm5hbC5zdHJlYW07Ci0KLWltcG9ydCBjb20uc3VuLnhtbC5pbnRlcm5hbC5zdHJlYW0uZXZlbnRzLlhNTEV2ZW50QWxsb2NhdG9ySW1wbDsKLWltcG9ydCBqYXZhLnV0aWwuTm9TdWNoRWxlbWVudEV4Y2VwdGlvbjsKLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLlhNTElucHV0RmFjdG9yeTsKLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLlhNTFN0cmVhbUNvbnN0YW50czsKLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLlhNTFN0cmVhbUV4Y2VwdGlvbjsKLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLlhNTFN0cmVhbVJlYWRlcjsKLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLmV2ZW50cy5FbnRpdHlSZWZlcmVuY2U7Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5ldmVudHMuWE1MRXZlbnQ7Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS51dGlsLlhNTEV2ZW50QWxsb2NhdG9yOwotCi0vKioKLSAqIEBhdXRob3IgIEBhdXRob3IgIE5lZXJhaiBCYWphaiBTdW4gTWljcm9zeXN0ZW1zCi0gKgotICovCi0KLXB1YmxpYyBjbGFzcyBYTUxFdmVudFJlYWRlckltcGwgaW1wbGVtZW50cyBqYXZheC54bWwuc3RyZWFtLlhNTEV2ZW50UmVhZGVyewotCi0gICAgcHJvdGVjdGVkIFhNTFN0cmVhbVJlYWRlciBmWE1MUmVhZGVyIDsKLSAgICBwcm90ZWN0ZWQgWE1MRXZlbnRBbGxvY2F0b3IgZlhNTEV2ZW50QWxsb2NhdG9yOwotCi0gICAgLy9vbmx5IGNvbnN0cnVjdG9yIHdpbGwgZG8gYmVjYXVzZSB3ZSBkZWxlZ2F0ZSBldmVyeXRoaW5nIHRvIHVuZGVybHlpbmcgWE1MU3RyZWFtUmVhZGVyCi0gICAgcHVibGljIFhNTEV2ZW50UmVhZGVySW1wbChYTUxTdHJlYW1SZWFkZXIgcmVhZGVyKSB0aHJvd3MgIFhNTFN0cmVhbUV4Y2VwdGlvbiB7Ci0gICAgICAgIGZYTUxSZWFkZXIgPSByZWFkZXIgOwotICAgICAgICBmWE1MRXZlbnRBbGxvY2F0b3IgPSAoWE1MRXZlbnRBbGxvY2F0b3IpcmVhZGVyLmdldFByb3BlcnR5KFhNTElucHV0RmFjdG9yeS5BTExPQ0FUT1IpOwotICAgICAgICBpZihmWE1MRXZlbnRBbGxvY2F0b3IgPT0gbnVsbCl7Ci0gICAgICAgICAgICBmWE1MRXZlbnRBbGxvY2F0b3IgPSBuZXcgWE1MRXZlbnRBbGxvY2F0b3JJbXBsKCk7Ci0gICAgICAgIH0KLSAgICAgICAgZlBlZWtlZEV2ZW50ID0gZlhNTEV2ZW50QWxsb2NhdG9yLmFsbG9jYXRlKGZYTUxSZWFkZXIpOwotICAgIH0KLQotCi0gICAgcHVibGljIGJvb2xlYW4gaGFzTmV4dCgpIHsKLSAgICAgICAgLy9pZiB3ZSBoYXZlIHRoZSBwZWVrZWQgZXZlbnQgcmV0dXJuICd0cnVlJwotICAgICAgICBpZihmUGVla2VkRXZlbnQgIT0gbnVsbClyZXR1cm4gdHJ1ZTsKLSAgICAgICAgLy90aGlzIGlzIHN0cmFuZ2UgWE1MU3RyZWFtUmVhZGVyIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24KLSAgICAgICAgLy9YTUxFdmVudFJlYWRlciBkb2Vzbid0IHRocm93IFhNTFN0cmVhbUV4Y2VwdGlvbgotICAgICAgICBib29sZWFuIG5leHQgPSBmYWxzZSA7Ci0gICAgICAgIHRyeXsKLSAgICAgICAgICAgIG5leHQgPSBmWE1MUmVhZGVyLmhhc05leHQoKTsKLSAgICAgICAgfWNhdGNoKFhNTFN0cmVhbUV4Y2VwdGlvbiBleCl7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG5leHQgOwotICAgIH0KLQotCi0gICAgcHVibGljIFhNTEV2ZW50IG5leHRFdmVudCgpIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24gewotICAgICAgICAvL2lmIGFwcGxpY2F0aW9uIHBlZWtlZCByZXR1cm4gdGhlIHBlZWtlZCBldmVudAotICAgICAgICBpZihmUGVla2VkRXZlbnQgIT0gbnVsbCl7Ci0gICAgICAgICAgICBmTGFzdEV2ZW50ID0gZlBlZWtlZEV2ZW50IDsKLSAgICAgICAgICAgIGZQZWVrZWRFdmVudCA9IG51bGw7Ci0gICAgICAgICAgICByZXR1cm4gZkxhc3RFdmVudCA7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZihmWE1MUmVhZGVyLmhhc05leHQoKSl7Ci0gICAgICAgICAgICAvL2FkdmFuY2UgdGhlIHJlYWRlciB0byBuZXh0IHN0YXRlLgotICAgICAgICAgICAgZlhNTFJlYWRlci5uZXh0KCk7Ci0gICAgICAgICAgICByZXR1cm4gZkxhc3RFdmVudCA9IGZYTUxFdmVudEFsbG9jYXRvci5hbGxvY2F0ZShmWE1MUmVhZGVyKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlewotICAgICAgICAgICAgZkxhc3RFdmVudCA9IG51bGw7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbigpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgcmVtb3ZlKCl7Ci0gICAgICAgIC8vcmVtb3ZlIG9mIHRoZSBldmVudCBpcyBub3Qgc3VwcG9ydGVkLgotICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLlVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24gewotICAgICAgICBmWE1MUmVhZGVyLmNsb3NlKCk7Ci0gICAgfQotCi0gICAgLyoqIFJlYWRzIHRoZSBjb250ZW50IG9mIGEgdGV4dC1vbmx5IGVsZW1lbnQuIFByZWNvbmRpdGlvbjoKLSAgICAgKiB0aGUgY3VycmVudCBldmVudCBpcyBTVEFSVF9FTEVNRU5ULiBQb3N0Y29uZGl0aW9uOgotICAgICAqIFRoZSBjdXJyZW50IGV2ZW50IGlzIHRoZSBjb3JyZXNwb25kaW5nIEVORF9FTEVNRU5ULgotICAgICAqIEB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uIGlmIHRoZSBjdXJyZW50IGV2ZW50IGlzIG5vdCBhIFNUQVJUX0VMRU1FTlQKLSAgICAgKiBvciBpZiBhIG5vbiB0ZXh0IGVsZW1lbnQgaXMgZW5jb3VudGVyZWQKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEVsZW1lbnRUZXh0KCkgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbiB7Ci0gICAgICAgIC8vd2UgaGF2ZSB0byBrZWVwIHJlZmVyZW5jZSB0byB0aGUgJ2xhc3QgZXZlbnQnIG9mIHRoZSBzdHJlYW0gdG8gYmUgYWJsZQotICAgICAgICAvL3RvIG1ha2UgdGhpcyBjaGVjayAtIGlzIHRoZXJlIGFub3RoZXIgd2F5ID8gLSBuYi4KLSAgICAgICAgaWYoZkxhc3RFdmVudC5nZXRFdmVudFR5cGUoKSAhPSBYTUxFdmVudC5TVEFSVF9FTEVNRU5UKXsKLSAgICAgICAgICAgIHRocm93IG5ldyBYTUxTdHJlYW1FeGNlcHRpb24oCi0gICAgICAgICAgICAicGFyc2VyIG11c3QgYmUgb24gU1RBUlRfRUxFTUVOVCB0byByZWFkIG5leHQgdGV4dCIsIGZMYXN0RXZlbnQuZ2V0TG9jYXRpb24oKSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBTVGFnIGNvbnRlbnQgRVRhZwotICAgICAgICAvL1s0M10gICBjb250ZW50ICAgOjo9ICAgQ2hhckRhdGE/ICgoZWxlbWVudCB8IFJlZmVyZW5jZSB8IENEU2VjdCB8IFBJIHwgQ29tbWVudCkgQ2hhckRhdGE/KSoKLQotICAgICAgICAvLzxmb28+Li4uLnNvbWUgbG9uZyB0ZXh0IHNheSBpbiBLQiBhbmQgdW5kZXJseWluZyBwYXJzZXIgcmVwb3J0cyBtdWx0aXBsZSBjaGFyYWN0ZXIKLSAgICAgICAgLy8gYnV0IGdldEVsZW1lbnRUZXh0KCkgZXZlbnRzLi4uLjwvZm9vPgotCi0gICAgICAgIFN0cmluZyBkYXRhID0gbnVsbDsKLSAgICAgICAgLy9oYXZpbmcgYSBwZWVrZWQgZXZlbnQgbWFrZXMgdGhpbmdzIHJlYWxseSB3b3JzZSAtLSB3ZSBoYXZlIHRvIHRlc3QgdGhlIGZpcnN0IGV2ZW50Ci0gICAgICAgIGlmKGZQZWVrZWRFdmVudCAhPSBudWxsKXsKLSAgICAgICAgICAgIFhNTEV2ZW50IGV2ZW50ID0gZlBlZWtlZEV2ZW50IDsKLSAgICAgICAgICAgIGZQZWVrZWRFdmVudCA9IG51bGw7Ci0gICAgICAgICAgICBpbnQgdHlwZSA9IGV2ZW50LmdldEV2ZW50VHlwZSgpOwotCi0gICAgICAgICAgICBpZiggIHR5cGUgPT0gWE1MRXZlbnQuQ0hBUkFDVEVSUyB8fCB0eXBlID09IFhNTEV2ZW50LlNQQUNFIHx8Ci0gICAgICAgICAgICB0eXBlID09IFhNTEV2ZW50LkNEQVRBKXsKLSAgICAgICAgICAgICAgICBkYXRhID0gZXZlbnQuYXNDaGFyYWN0ZXJzKCkuZ2V0RGF0YSgpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZih0eXBlID09IFhNTEV2ZW50LkVOVElUWV9SRUZFUkVOQ0UpewotICAgICAgICAgICAgICAgIGRhdGEgPSAoKEVudGl0eVJlZmVyZW5jZSlldmVudCkuZ2V0RGVjbGFyYXRpb24oKS5nZXRSZXBsYWNlbWVudFRleHQoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYodHlwZSA9PSBYTUxFdmVudC5DT01NRU5UIHx8IHR5cGUgPT0gWE1MRXZlbnQuUFJPQ0VTU0lOR19JTlNUUlVDVElPTil7Ci0gICAgICAgICAgICAgICAgLy9pZ25vcmUKLSAgICAgICAgICAgIH0gZWxzZSBpZih0eXBlID09IFhNTEV2ZW50LlNUQVJUX0VMRU1FTlQpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWE1MU3RyZWFtRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICJlbGVtZW50R2V0VGV4dCgpIGZ1bmN0aW9uIGV4cGVjdHMgdGV4dCBvbmx5IGVsbWVudCBidXQgU1RBUlRfRUxFTUVOVCB3YXMgZW5jb3VudGVyZWQuIiwgZXZlbnQuZ2V0TG9jYXRpb24oKSk7Ci0gICAgICAgICAgICB9ZWxzZSBpZih0eXBlID09IFhNTEV2ZW50LkVORF9FTEVNRU5UKXsKLSAgICAgICAgICAgICAgICByZXR1cm4gIiI7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vY3JlYXRlIHRoZSBzdHJpbmcgYnVmZmVyIGFuZCBhZGQgaW5pdGlhbCBkYXRhCi0gICAgICAgICAgICBTdHJpbmdCdWZmZXIgYnVmZmVyID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotICAgICAgICAgICAgaWYoZGF0YSAhPSBudWxsICYmIGRhdGEubGVuZ3RoKCkgPiAwICkgewotICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoZGF0YSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvL2dldCB0aGUgbmV4dCBldmVudCAtLSB3ZSBzaG91bGQgc3RvcCBhdCBFTkRfRUxFTUVOVCBidXQgaXQgY2FuIGJlIGFueSB0aGluZwotICAgICAgICAgICAgLy90aGluZ3MgYXJlIHdvcnNlIHdoZW4gaW1wbGVtZW50aW5nIHRoaXMgZnVuY3Rpb24gaW4gWE1MRXZlbnRSZWFkZXIgYmVjYXVzZQotICAgICAgICAgICAgLy90aGVyZSBpc24ndCBhbnkgZnVuY3Rpb24gY2FsbGVkIGdldFRleHQoKSB3aGljaCBjYW4gZ2V0IHZhbHVlcyBmb3IKLSAgICAgICAgICAgIC8vc3BhY2UsIGNkYXRhLCBjaGFyYWN0ZXJzIGFuZCBlbnRpdHkgcmVmZXJlbmNlCi0gICAgICAgICAgICAvL25leHRFdmVudCgpIHdvdWxkIGFsc28gc2V0IHRoZSBsYXN0IGV2ZW50LgotICAgICAgICAgICAgZXZlbnQgPSBuZXh0RXZlbnQoKTsKLSAgICAgICAgICAgIHdoaWxlKGV2ZW50LmdldEV2ZW50VHlwZSgpICE9IFhNTEV2ZW50LkVORF9FTEVNRU5UKXsKLSAgICAgICAgICAgICAgICBpZiggIHR5cGUgPT0gWE1MRXZlbnQuQ0hBUkFDVEVSUyB8fCB0eXBlID09IFhNTEV2ZW50LlNQQUNFIHx8Ci0gICAgICAgICAgICAgICAgdHlwZSA9PSBYTUxFdmVudC5DREFUQSl7Ci0gICAgICAgICAgICAgICAgICAgIGRhdGEgPSBldmVudC5hc0NoYXJhY3RlcnMoKS5nZXREYXRhKCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgaWYodHlwZSA9PSBYTUxFdmVudC5FTlRJVFlfUkVGRVJFTkNFKXsKLSAgICAgICAgICAgICAgICAgICAgZGF0YSA9ICgoRW50aXR5UmVmZXJlbmNlKWV2ZW50KS5nZXREZWNsYXJhdGlvbigpLmdldFJlcGxhY2VtZW50VGV4dCgpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIGlmKHR5cGUgPT0gWE1MRXZlbnQuQ09NTUVOVCB8fCB0eXBlID09IFhNTEV2ZW50LlBST0NFU1NJTkdfSU5TVFJVQ1RJT04pewotICAgICAgICAgICAgICAgICAgICAvL2lnbm9yZQotICAgICAgICAgICAgICAgIH0gZWxzZSBpZih0eXBlID09IFhNTEV2ZW50LkVORF9ET0NVTUVOVCkgewotICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWE1MU3RyZWFtRXhjZXB0aW9uKCJ1bmV4cGVjdGVkIGVuZCBvZiBkb2N1bWVudCB3aGVuIHJlYWRpbmcgZWxlbWVudCB0ZXh0IGNvbnRlbnQiKTsKLSAgICAgICAgICAgICAgICB9IGVsc2UgaWYodHlwZSA9PSBYTUxFdmVudC5TVEFSVF9FTEVNRU5UKSB7Ci0gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBYTUxTdHJlYW1FeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgICJlbGVtZW50R2V0VGV4dCgpIGZ1bmN0aW9uIGV4cGVjdHMgdGV4dCBvbmx5IGVsbWVudCBidXQgU1RBUlRfRUxFTUVOVCB3YXMgZW5jb3VudGVyZWQuIiwgZXZlbnQuZ2V0TG9jYXRpb24oKSk7Ci0gICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFhNTFN0cmVhbUV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgIlVuZXhwZWN0ZWQgZXZlbnQgdHlwZSAiKyB0eXBlLCBldmVudC5nZXRMb2NhdGlvbigpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLy9hZGQgdGhlIGRhdGEgdG8gdGhlIGJ1ZmZlcgotICAgICAgICAgICAgICAgIGlmKGRhdGEgIT0gbnVsbCAmJiBkYXRhLmxlbmd0aCgpID4gMCApIHsKLSAgICAgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZChkYXRhKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZXZlbnQgPSBuZXh0RXZlbnQoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiBidWZmZXIudG9TdHJpbmcoKTsKLSAgICAgICAgfS8vaWYgKGZQZWVrZWRFdmVudCAhPSBudWxsKQotCi0gICAgICAgIC8vaWYgdGhlcmUgd2FzIG5vIHBlZWtlZCwgZGVsZWdhdGUgZXZlcnl0aGluZyB0byBmWE1MUmVhZGVyCi0gICAgICAgIC8vdXBkYXRlIHRoZSBsYXN0IGV2ZW50IGJlZm9yZSByZXR1cm5pbmcgdGhlIHRleHQKLSAgICAgICAgZGF0YSA9IGZYTUxSZWFkZXIuZ2V0RWxlbWVudFRleHQoKTsKLSAgICAgICAgZkxhc3RFdmVudCA9IGZYTUxFdmVudEFsbG9jYXRvci5hbGxvY2F0ZShmWE1MUmVhZGVyKTsKLSAgICAgICAgcmV0dXJuIGRhdGE7Ci0gICAgfQotCi0gICAgLyoqIEdldCB0aGUgdmFsdWUgb2YgYSBmZWF0dXJlL3Byb3BlcnR5IGZyb20gdGhlIHVuZGVybHlpbmcgaW1wbGVtZW50YXRpb24KLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgcHJvcGVydHkKLSAgICAgKiBAcmV0dXJuIFRoZSB2YWx1ZSBvZiB0aGUgcHJvcGVydHkKLSAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgcHJvcGVydHkgaXMgbm90IHN1cHBvcnRlZAotICAgICAqLwotICAgIHB1YmxpYyBPYmplY3QgZ2V0UHJvcGVydHkoamF2YS5sYW5nLlN0cmluZyBuYW1lKSB0aHJvd3MgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7Ci0gICAgICAgIHJldHVybiBmWE1MUmVhZGVyLmdldFByb3BlcnR5KG5hbWUpIDsKLSAgICB9Ci0KLSAgICAvKiogU2tpcHMgYW55IGluc2lnbmlmaWNhbnQgc3BhY2UgZXZlbnRzIHVudGlsIGEgU1RBUlRfRUxFTUVOVCBvcgotICAgICAqIEVORF9FTEVNRU5UIGlzIHJlYWNoZWQuIElmIGFueXRoaW5nIG90aGVyIHRoYW4gc3BhY2UgY2hhcmFjdGVycyBhcmUKLSAgICAgKiBlbmNvdW50ZXJlZCwgYW4gZXhjZXB0aW9uIGlzIHRocm93bi4gVGhpcyBtZXRob2Qgc2hvdWxkCi0gICAgICogYmUgdXNlZCB3aGVuIHByb2Nlc3NpbmcgZWxlbWVudC1vbmx5IGNvbnRlbnQgYmVjYXVzZQotICAgICAqIHRoZSBwYXJzZXIgaXMgbm90IGFibGUgdG8gcmVjb2duaXplIGlnbm9yYWJsZSB3aGl0ZXNwYWNlIGlmCi0gICAgICogdGhlIERURCBpcyBtaXNzaW5nIG9yIG5vdCBpbnRlcnByZXRlZC4KLSAgICAgKiBAdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbiBpZiBhbnl0aGluZyBvdGhlciB0aGFuIHNwYWNlIGNoYXJhY3RlcnMgYXJlIGVuY291bnRlcmVkCi0gICAgICovCi0gICAgcHVibGljIFhNTEV2ZW50IG5leHRUYWcoKSB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uIHsKLSAgICAgICAgLy9pdHMgcmVhbGx5IGEgcGFpbiBpZiB0aGVyZSBpcyBwZWVrZWQgZXZlbnQgYmVmb3JlIGNhbGxpbmcgbmV4dFRhZygpCi0gICAgICAgIGlmKGZQZWVrZWRFdmVudCAhPSBudWxsKXsKLSAgICAgICAgICAgIC8vY2hlY2sgdGhlIHBlZWtlZCBldmVudCBmaXJzdC4KLSAgICAgICAgICAgIFhNTEV2ZW50IGV2ZW50ID0gZlBlZWtlZEV2ZW50OwotICAgICAgICAgICAgZlBlZWtlZEV2ZW50ID0gbnVsbCA7Ci0gICAgICAgICAgICBpbnQgZXZlbnRUeXBlID0gZXZlbnQuZ2V0RXZlbnRUeXBlKCk7Ci0gICAgICAgICAgICAvL2lmIHBlZWtlZCBldmVudCBpcyB3aGl0ZXNwYWNlIG1vdmUgdG8gdGhlIG5leHQgZXZlbnQKLSAgICAgICAgICAgIC8vaWYgcGVla2VkIGV2ZW50IGlzIFBJIG9yIENPTU1FTlQgbW92ZSB0byB0aGUgbmV4dCBldmVudAotICAgICAgICAgICAgaWYoIChldmVudC5pc0NoYXJhY3RlcnMoKSAmJiBldmVudC5hc0NoYXJhY3RlcnMoKS5pc1doaXRlU3BhY2UoKSkKLSAgICAgICAgICAgIHx8IGV2ZW50VHlwZSA9PSBYTUxTdHJlYW1Db25zdGFudHMuUFJPQ0VTU0lOR19JTlNUUlVDVElPTgotICAgICAgICAgICAgfHwgZXZlbnRUeXBlID09IFhNTFN0cmVhbUNvbnN0YW50cy5DT01NRU5UCi0gICAgICAgICAgICB8fCBldmVudFR5cGUgPT0gWE1MU3RyZWFtQ29uc3RhbnRzLlNUQVJUX0RPQ1VNRU5UKXsKLSAgICAgICAgICAgICAgICBldmVudCA9IG5leHRFdmVudCgpOwotICAgICAgICAgICAgICAgIGV2ZW50VHlwZSA9IGV2ZW50LmdldEV2ZW50VHlwZSgpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvL3dlIGhhdmUgdG8gaGF2ZSB0aGUgd2hpbGUgbG9vcCBiZWNhdXNlIHRoZXJlIGNhbiBiZSBtYW55IFBJIG9yIGNvbW1lbnQgZXZlbnQgaW4gc3VjZXNzaW9uCi0gICAgICAgICAgICB3aGlsZSgoZXZlbnQuaXNDaGFyYWN0ZXJzKCkgJiYgZXZlbnQuYXNDaGFyYWN0ZXJzKCkuaXNXaGl0ZVNwYWNlKCkpCi0gICAgICAgICAgICB8fCBldmVudFR5cGUgPT0gWE1MU3RyZWFtQ29uc3RhbnRzLlBST0NFU1NJTkdfSU5TVFJVQ1RJT04KLSAgICAgICAgICAgIHx8IGV2ZW50VHlwZSA9PSBYTUxTdHJlYW1Db25zdGFudHMuQ09NTUVOVCl7Ci0KLSAgICAgICAgICAgICAgICBldmVudCA9IG5leHRFdmVudCgpOwotICAgICAgICAgICAgICAgIGV2ZW50VHlwZSA9IGV2ZW50LmdldEV2ZW50VHlwZSgpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAoZXZlbnRUeXBlICE9IFhNTFN0cmVhbUNvbnN0YW50cy5TVEFSVF9FTEVNRU5UICYmIGV2ZW50VHlwZSAhPSBYTUxTdHJlYW1Db25zdGFudHMuRU5EX0VMRU1FTlQpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWE1MU3RyZWFtRXhjZXB0aW9uKCJleHBlY3RlZCBzdGFydCBvciBlbmQgdGFnIiwgZXZlbnQuZ2V0TG9jYXRpb24oKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gZXZlbnQ7Ci0gICAgICAgIH0KLQotICAgICAgICAvL2lmIHRoZXJlIGlzIG5vIHBlZWtlZCBldmVudCAtLSBkZWxlZ2F0ZSB0aGUgd29yayBvZiBnZXR0aW5nIG5leHQgZXZlbnQgdG8gZlhNTFJlYWRlcgotICAgICAgICBmWE1MUmVhZGVyLm5leHRUYWcoKTsKLSAgICAgICAgcmV0dXJuIChmTGFzdEV2ZW50ID0gZlhNTEV2ZW50QWxsb2NhdG9yLmFsbG9jYXRlKGZYTUxSZWFkZXIpKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgT2JqZWN0IG5leHQoKSB7Ci0gICAgICAgIE9iamVjdCBvYmplY3QgPSBudWxsOwotICAgICAgICB0cnl7Ci0gICAgICAgICAgICBvYmplY3QgPSBuZXh0RXZlbnQoKTsKLSAgICAgICAgfWNhdGNoKFhNTFN0cmVhbUV4Y2VwdGlvbiBzdHJlYW1FeGNlcHRpb24pewotICAgICAgICAgICAgZkxhc3RFdmVudCA9IG51bGwgOwotICAgICAgICAgICAgLy9kb24ndCBzd2FsbG93IHRoZSBjYXVzZQotICAgICAgICAgICAgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbiBlID0gbmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oc3RyZWFtRXhjZXB0aW9uLmdldE1lc3NhZ2UoKSk7Ci0gICAgICAgICAgICBlLmluaXRDYXVzZShzdHJlYW1FeGNlcHRpb24uZ2V0Q2F1c2UoKSk7Ci0gICAgICAgICAgICB0aHJvdyBlOwotCi0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG9iamVjdDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgWE1MRXZlbnQgcGVlaygpIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb257Ci0gICAgICAgIC8vaWYgc29tZW9uZSBjYWxsIHBlZWsoKSB0d28gdGltZXMgd2Ugc2hvdWxkIGp1c3QgcmV0dXJuIHRoZSBwZWVrZWQgZXZlbnQKLSAgICAgICAgLy90aGlzIGlzIHJlc2V0IGlmIHdlIGNhbGwgbmV4dCgpIG9yIG5leHRFdmVudCgpCi0gICAgICAgIGlmKGZQZWVrZWRFdmVudCAhPSBudWxsKSByZXR1cm4gZlBlZWtlZEV2ZW50OwotCi0gICAgICAgIGlmKGhhc05leHQoKSl7Ci0gICAgICAgICAgICAvL3JldmlzaXQ6IHdlIGNhbiBpbXBsZW1lbnQgcGVlaygpIGJ5IGNhbGxpbmcgdW5kZXJseWluZyByZWFkZXIgdG8gYWR2YW5jZQotICAgICAgICAgICAgLy8gdGhlIHN0cmVhbSBhbmQgcmV0dXJuaW5nIHRoZSBldmVudCB3aXRob3V0IHRoZSBrbm93bGVkZ2Ugb2YgdGhlIHVzZXIKLSAgICAgICAgICAgIC8vIHRoYXQgdGhlIHN0cmVhbSB3YXMgYWR2YW5jZWQgYnV0IHRoZSBwb2ludCBpcyB3ZSBhcmUgYWR2YW5jaW5nIHRoZSBzdHJlYW0KLSAgICAgICAgICAgIC8vaGVyZS4gLS0gbmIuCi0KLSAgICAgICAgICAgIC8vIElzIHRoZXJlIGFueSBhcHBsaWNhdGlvbiB0aGF0IHJlbGllcyBvbiB0aGlzIGJlaGF2aW9yID8KLSAgICAgICAgICAgIC8vQ2FuIGl0IGJlIGFuIGFwcGxpY2F0aW9uIGtub3dzIHRoYXQgdGhlcmUgaXMgcGFydGljdWxhcmx5IHZlcnkgbGFyZ2UgJ2NvbW1lbnQnIHNlY3Rpb24KLSAgICAgICAgICAgIC8vb3IgY2hhcmFjdGVyIGRhdGEgd2hpY2ggaXQgZG9lc24ndCB3YW50IHRvIHJlYWQgb3IgdG8gYmUgcmV0dXJuZWQgYXMgZXZlbnQKLSAgICAgICAgICAgIC8vQnV0IGFzIG9mIG5vdyB3ZSBhcmUgY3JlYXRpbmcgZXZlcnkgZXZlbnQgYnV0IGl0IGNhbiBiZSBvcHRpbWl6ZWQgbm90IHRvIGNyZWF0ZQotICAgICAgICAgICAgLy8gdGhlIGV2ZW50LgotICAgICAgICAgICAgZlhNTFJlYWRlci5uZXh0KCk7Ci0gICAgICAgICAgICBmUGVla2VkRXZlbnQgPSBmWE1MRXZlbnRBbGxvY2F0b3IuYWxsb2NhdGUoZlhNTFJlYWRlcik7Ci0gICAgICAgICAgICByZXR1cm4gZlBlZWtlZEV2ZW50OwotICAgICAgICB9ZWxzZXsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgfS8vcGVlaygpCi0KLSAgICBwcml2YXRlIFhNTEV2ZW50IGZQZWVrZWRFdmVudDsKLSAgICBwcml2YXRlIFhNTEV2ZW50IGZMYXN0RXZlbnQ7Ci0KLX0vL1hNTEV2ZW50UmVhZGVySW1wbApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4veG1sL2ludGVybmFsL3N0cmVhbS9YTUxJbnB1dEZhY3RvcnlJbXBsLmphdmEgYi9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL1hNTElucHV0RmFjdG9yeUltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNmYwOWUwZi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL1hNTElucHV0RmFjdG9yeUltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDMwNSArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDA2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ueG1sLmludGVybmFsLnN0cmVhbTsKLQotaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5pby5SZWFkZXI7Ci0KLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLio7Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS51dGlsLlhNTEV2ZW50QWxsb2NhdG9yIDsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlNvdXJjZTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbS5TdHJlYW1Tb3VyY2U7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTElucHV0U291cmNlOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5YTUxTdHJlYW1SZWFkZXJJbXBsOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5Qcm9wZXJ0eU1hbmFnZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLlhNTFN0cmVhbUZpbHRlckltcGw7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLkNvbnN0YW50czsKLQotLyoqIEZhY3RvcnkgSW1wbGVtZW50YXRpb24gZm9yIFhNTElucHV0RmFjdG9yeS4KLSAqIEBhdXRob3IgTmVlcmFqIEJhamFqIFN1biBNaWNyb3N5c3RlbXMKLSAqIEBhdXRob3IgSy5WZW51Z29wYWwgU3VuIE1pY3Jvc3lzdGVtcwotICovCi0KLS8veHh4OiBTaG91bGQgd2UgYmUgcmV1c2luZyB0aGUgWE1MSW5wdXRTb3VyY2Ugb2JqZWN0Ci1wdWJsaWMgY2xhc3MgWE1MSW5wdXRGYWN0b3J5SW1wbCBleHRlbmRzIGphdmF4LnhtbC5zdHJlYW0uWE1MSW5wdXRGYWN0b3J5IHsKLQotCi0gICAgLy9MaXN0IG9mIHN1cHBvcnRlZCBwcm9wZXJ0aWVzIGFuZCBkZWZhdWx0IHZhbHVlcy4KLSAgICBwcml2YXRlIFByb3BlcnR5TWFuYWdlciBmUHJvcGVydHlNYW5hZ2VyID0gbmV3IFByb3BlcnR5TWFuYWdlcihQcm9wZXJ0eU1hbmFnZXIuQ09OVEVYVF9SRUFERVIpIDsKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIERFQlVHID0gZmFsc2U7Ci0KLSAgICAvL01haW50YWluIGEgcmVmZXJlbmNlIHRvIGxhc3QgcmVhZGVyIGluc3RhbnRpYXRlZC4KLSAgICBwcml2YXRlIFhNTFN0cmVhbVJlYWRlckltcGwgZlRlbXBSZWFkZXIgPSBudWxsIDsKLQotICAgIGJvb2xlYW4gZlByb3BlcnR5Q2hhbmdlZCA9IGZhbHNlOwotICAgIC8vbm8gcmVhZGVyIHJldXNlIGJ5IGRlZmF1bHQKLSAgICBib29sZWFuIGZSZXVzZUluc3RhbmNlID0gZmFsc2U7Ci0KLSAgICAvKiogQ3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiBaZXBocnlQYXJzZXJGYWN0b3J5ICovCi0gICAgcHVibGljIFhNTElucHV0RmFjdG9yeUltcGwoKSB7Ci0KLSAgICB9Ci0KLSAgICB2b2lkIGluaXRFdmVudFJlYWRlcigpewotICAgICAgICBmUHJvcGVydHlDaGFuZ2VkID0gdHJ1ZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAcGFyYW0gaW5wdXRzdHJlYW0KLSAgICAgKiBAdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbgotICAgICAqIEByZXR1cm4KLSAgICAgKi8KLSAgICBwdWJsaWMgWE1MRXZlbnRSZWFkZXIgY3JlYXRlWE1MRXZlbnRSZWFkZXIoSW5wdXRTdHJlYW0gaW5wdXRzdHJlYW0pIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24gewotICAgICAgICBpbml0RXZlbnRSZWFkZXIoKTsKLSAgICAgICAgLy9kZWxlZ2F0ZSBldmVyeXRoaW5nIHRvIFhNTFN0cmVhbVJlYWRlcgotICAgICAgICByZXR1cm4gbmV3IFhNTEV2ZW50UmVhZGVySW1wbChjcmVhdGVYTUxTdHJlYW1SZWFkZXIoaW5wdXRzdHJlYW0pKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgWE1MRXZlbnRSZWFkZXIgY3JlYXRlWE1MRXZlbnRSZWFkZXIoUmVhZGVyIHJlYWRlcikgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbiB7Ci0gICAgICAgIGluaXRFdmVudFJlYWRlcigpOwotICAgICAgICAvL2RlbGVnYXRlIGV2ZXJ5dGhpbmcgdG8gWE1MU3RyZWFtUmVhZGVyCi0gICAgICAgIHJldHVybiBuZXcgWE1MRXZlbnRSZWFkZXJJbXBsKGNyZWF0ZVhNTFN0cmVhbVJlYWRlcihyZWFkZXIpKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgWE1MRXZlbnRSZWFkZXIgY3JlYXRlWE1MRXZlbnRSZWFkZXIoU291cmNlIHNvdXJjZSkgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbiB7Ci0gICAgICAgIGluaXRFdmVudFJlYWRlcigpOwotICAgICAgICAvL2RlbGVnYXRlIGV2ZXJ5dGhpbmcgdG8gWE1MU3RyZWFtUmVhZGVyCi0gICAgICAgIHJldHVybiBuZXcgWE1MRXZlbnRSZWFkZXJJbXBsKGNyZWF0ZVhNTFN0cmVhbVJlYWRlcihzb3VyY2UpKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgWE1MRXZlbnRSZWFkZXIgY3JlYXRlWE1MRXZlbnRSZWFkZXIoU3RyaW5nIHN5c3RlbUlkLCBJbnB1dFN0cmVhbSBpbnB1dHN0cmVhbSkgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbiB7Ci0gICAgICAgIGluaXRFdmVudFJlYWRlcigpOwotICAgICAgICAvL2RlbGVnYXRlIGV2ZXJ5dGhpbmcgdG8gWE1MU3RyZWFtUmVhZGVyCi0gICAgICAgIHJldHVybiBuZXcgWE1MRXZlbnRSZWFkZXJJbXBsKGNyZWF0ZVhNTFN0cmVhbVJlYWRlcihzeXN0ZW1JZCwgaW5wdXRzdHJlYW0pKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgWE1MRXZlbnRSZWFkZXIgY3JlYXRlWE1MRXZlbnRSZWFkZXIoamF2YS5pby5JbnB1dFN0cmVhbSBzdHJlYW0sIFN0cmluZyBlbmNvZGluZykgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbiB7Ci0gICAgICAgIGluaXRFdmVudFJlYWRlcigpOwotICAgICAgICAvL2RlbGVnYXRlIGV2ZXJ5dGhpbmcgdG8gWE1MU3RyZWFtUmVhZGVyCi0gICAgICAgIHJldHVybiBuZXcgWE1MRXZlbnRSZWFkZXJJbXBsKGNyZWF0ZVhNTFN0cmVhbVJlYWRlcihzdHJlYW0sIGVuY29kaW5nKSk7Ci0gICAgfQotCi0gICAgcHVibGljIFhNTEV2ZW50UmVhZGVyIGNyZWF0ZVhNTEV2ZW50UmVhZGVyKFN0cmluZyBzeXN0ZW1JZCwgUmVhZGVyIHJlYWRlcikgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbiB7Ci0gICAgICAgIGluaXRFdmVudFJlYWRlcigpOwotICAgICAgICAvL2RlbGVnYXRlIGV2ZXJ5dGhpbmcgdG8gWE1MU3RyZWFtUmVhZGVyCi0gICAgICAgIHJldHVybiBuZXcgWE1MRXZlbnRSZWFkZXJJbXBsKGNyZWF0ZVhNTFN0cmVhbVJlYWRlcihzeXN0ZW1JZCwgcmVhZGVyKSk7Ci0gICAgfQotCi0gICAgLyoqIENyZWF0ZSBhIG5ldyBYTUxFdmVudFJlYWRlciBmcm9tIGFuIFhNTFN0cmVhbVJlYWRlci4gIEFmdGVyIGJlaW5nIHVzZWQKLSAgICAgKiB0byBjb25zdHJ1Y3QgdGhlIFhNTEV2ZW50UmVhZGVyIGluc3RhbmNlIHJldHVybmVkIGZyb20gdGhpcyBtZXRob2QKLSAgICAgKiB0aGUgWE1MU3RyZWFtUmVhZGVyIG11c3Qgbm90IGJlIHVzZWQuCi0gICAgICogQHBhcmFtIHJlYWRlciB0aGUgWE1MU3RyZWFtUmVhZGVyIHRvIHJlYWQgZnJvbSAobWF5IG5vdCBiZSBtb2RpZmllZCkKLSAgICAgKiBAcmV0dXJuIGEgbmV3IFhNTEV2ZW50UmVhZGVyCi0gICAgICogQHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgWE1MRXZlbnRSZWFkZXIgY3JlYXRlWE1MRXZlbnRSZWFkZXIoWE1MU3RyZWFtUmVhZGVyIHJlYWRlcikgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy94eHg6IHdoYXQgZG8gd2UgZG8gbm93IC0tIGluc3RhbmNlIGlzIHBhc3NlZCBmcm9tIHRoZSBhcHBsaWNhdGlvbgotICAgICAgICAvL3Byb2JhYmx5IHdlIHNob3VsZCBjaGVjayBpZiB0aGUgc3RhdGUgaXMgYXQgdGhlIHN0YXJ0IGRvY3VtZW50LAotICAgICAgICAvL2V2ZW50cmVhZGVyIGNhbGwgdG8gbmV4dCgpIHNob3VsZCByZXR1cm4gU1RBUlRfRE9DVU1FTlQgYW5kCi0gICAgICAgIC8vdGhlbiBkZWxlZ2F0ZSBldmVyeSBjYWxsIHRvIHVuZGVybHlpbmcgc3RyZWFtUmVhZGVyCi0gICAgICAgIHJldHVybiBuZXcgWE1MRXZlbnRSZWFkZXJJbXBsKHJlYWRlcikgOwotICAgIH0KLQotICAgIHB1YmxpYyBYTUxTdHJlYW1SZWFkZXIgY3JlYXRlWE1MU3RyZWFtUmVhZGVyKElucHV0U3RyZWFtIGlucHV0c3RyZWFtKSB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uIHsKLSAgICAgICAgWE1MSW5wdXRTb3VyY2UgaW5wdXRTb3VyY2UgPSBuZXcgWE1MSW5wdXRTb3VyY2UobnVsbCwgbnVsbCwgbnVsbCwgaW5wdXRzdHJlYW0sIG51bGwpOwotICAgICAgICByZXR1cm4gZ2V0WE1MU3RyZWFtUmVhZGVySW1wbChpbnB1dFNvdXJjZSk7Ci0gICAgfQotCi0gICAgcHVibGljIFhNTFN0cmVhbVJlYWRlciBjcmVhdGVYTUxTdHJlYW1SZWFkZXIoUmVhZGVyIHJlYWRlcikgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbiB7Ci0gICAgICAgIFhNTElucHV0U291cmNlIGlucHV0U291cmNlID0gbmV3IFhNTElucHV0U291cmNlKG51bGwsIG51bGwsIG51bGwsIHJlYWRlciwgbnVsbCk7Ci0gICAgICAgIHJldHVybiBnZXRYTUxTdHJlYW1SZWFkZXJJbXBsKGlucHV0U291cmNlKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgWE1MU3RyZWFtUmVhZGVyIGNyZWF0ZVhNTFN0cmVhbVJlYWRlcihTdHJpbmcgc3lzdGVtSWQsIFJlYWRlciByZWFkZXIpIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24gewotICAgICAgICBYTUxJbnB1dFNvdXJjZSBpbnB1dFNvdXJjZSA9IG5ldyBYTUxJbnB1dFNvdXJjZShudWxsLHN5c3RlbUlkLG51bGwscmVhZGVyLG51bGwpOwotICAgICAgICByZXR1cm4gZ2V0WE1MU3RyZWFtUmVhZGVySW1wbChpbnB1dFNvdXJjZSk7Ci0gICAgfQotCi0gICAgcHVibGljIFhNTFN0cmVhbVJlYWRlciBjcmVhdGVYTUxTdHJlYW1SZWFkZXIoU291cmNlIHNvdXJjZSkgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbiB7Ci0gICAgICAgIHJldHVybiBuZXcgWE1MU3RyZWFtUmVhZGVySW1wbChqYXhwU291cmNldG9YTUxJbnB1dFNvdXJjZShzb3VyY2UpLAotICAgICAgICAgICAgICAgIG5ldyBQcm9wZXJ0eU1hbmFnZXIoZlByb3BlcnR5TWFuYWdlcikpOwotICAgIH0KLQotICAgIHB1YmxpYyBYTUxTdHJlYW1SZWFkZXIgY3JlYXRlWE1MU3RyZWFtUmVhZGVyKFN0cmluZyBzeXN0ZW1JZCwgSW5wdXRTdHJlYW0gaW5wdXRzdHJlYW0pIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24gewotICAgICAgICBYTUxJbnB1dFNvdXJjZSBpbnB1dFNvdXJjZSA9IG5ldyBYTUxJbnB1dFNvdXJjZShudWxsLHN5c3RlbUlkLG51bGwsaW5wdXRzdHJlYW0sbnVsbCk7Ci0gICAgICAgIHJldHVybiBnZXRYTUxTdHJlYW1SZWFkZXJJbXBsKGlucHV0U291cmNlKTsKLSAgICB9Ci0KLQotICAgIHB1YmxpYyBYTUxTdHJlYW1SZWFkZXIgY3JlYXRlWE1MU3RyZWFtUmVhZGVyKElucHV0U3RyZWFtIGlucHV0c3RyZWFtLCBTdHJpbmcgZW5jb2RpbmcpIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24gewotICAgICAgICBYTUxJbnB1dFNvdXJjZSBpbnB1dFNvdXJjZSA9IG5ldyBYTUxJbnB1dFNvdXJjZShudWxsLG51bGwsbnVsbCxpbnB1dHN0cmVhbSxlbmNvZGluZyk7Ci0gICAgICAgIHJldHVybiBnZXRYTUxTdHJlYW1SZWFkZXJJbXBsKGlucHV0U291cmNlKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgWE1MRXZlbnRBbGxvY2F0b3IgZ2V0RXZlbnRBbGxvY2F0b3IoKSB7Ci0gICAgICAgIHJldHVybiAoWE1MRXZlbnRBbGxvY2F0b3IpZ2V0UHJvcGVydHkoWE1MSW5wdXRGYWN0b3J5LkFMTE9DQVRPUik7Ci0gICAgfQotCi0gICAgcHVibGljIFhNTFJlcG9ydGVyIGdldFhNTFJlcG9ydGVyKCkgewotICAgICAgICByZXR1cm4gKFhNTFJlcG9ydGVyKWZQcm9wZXJ0eU1hbmFnZXIuZ2V0UHJvcGVydHkoWE1MSW5wdXRGYWN0b3J5LlJFUE9SVEVSKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgWE1MUmVzb2x2ZXIgZ2V0WE1MUmVzb2x2ZXIoKSB7Ci0gICAgICAgIE9iamVjdCBvYmplY3QgPSBmUHJvcGVydHlNYW5hZ2VyLmdldFByb3BlcnR5KFhNTElucHV0RmFjdG9yeS5SRVNPTFZFUik7Ci0gICAgICAgIHJldHVybiAoWE1MUmVzb2x2ZXIpb2JqZWN0OwotICAgICAgICAvL3JldHVybiAoWE1MUmVzb2x2ZXIpZlByb3BlcnR5TWFuYWdlci5nZXRQcm9wZXJ0eShYTUxJbnB1dEZhY3RvcnkuUkVTT0xWRVIpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldFhNTFJlcG9ydGVyKFhNTFJlcG9ydGVyIHhtbHJlcG9ydGVyKSB7Ci0gICAgICAgIGZQcm9wZXJ0eU1hbmFnZXIuc2V0UHJvcGVydHkoWE1MSW5wdXRGYWN0b3J5LlJFUE9SVEVSLCB4bWxyZXBvcnRlcik7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0WE1MUmVzb2x2ZXIoWE1MUmVzb2x2ZXIgeG1scmVzb2x2ZXIpIHsKLSAgICAgICAgZlByb3BlcnR5TWFuYWdlci5zZXRQcm9wZXJ0eShYTUxJbnB1dEZhY3RvcnkuUkVTT0xWRVIsIHhtbHJlc29sdmVyKTsKLSAgICB9Ci0KLSAgICAvKiogQ3JlYXRlIGEgZmlsdGVyZWQgZXZlbnQgcmVhZGVyIHRoYXQgd3JhcHMgdGhlIGZpbHRlciBhcm91bmQgdGhlIGV2ZW50IHJlYWRlcgotICAgICAqIEBwYXJhbSByZWFkZXIgdGhlIGV2ZW50IHJlYWRlciB0byB3cmFwCi0gICAgICogQHBhcmFtIGZpbHRlciB0aGUgZmlsdGVyIHRvIGFwcGx5IHRvIHRoZSBldmVudCByZWFkZXIKLSAgICAgKiBAdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbgotICAgICAqLwotICAgIHB1YmxpYyBYTUxFdmVudFJlYWRlciBjcmVhdGVGaWx0ZXJlZFJlYWRlcihYTUxFdmVudFJlYWRlciByZWFkZXIsIEV2ZW50RmlsdGVyIGZpbHRlcikgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbiB7Ci0gICAgICAgIHJldHVybiBuZXcgRXZlbnRGaWx0ZXJTdXBwb3J0KHJlYWRlciwgZmlsdGVyKTsKLSAgICB9Ci0KLSAgICAvKiogQ3JlYXRlIGEgZmlsdGVyZWQgcmVhZGVyIHRoYXQgd3JhcHMgdGhlIGZpbHRlciBhcm91bmQgdGhlIHJlYWRlcgotICAgICAqIEBwYXJhbSByZWFkZXIgdGhlIHJlYWRlciB0byBmaWx0ZXIKLSAgICAgKiBAcGFyYW0gZmlsdGVyIHRoZSBmaWx0ZXIgdG8gYXBwbHkgdG8gdGhlIHJlYWRlcgotICAgICAqIEB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uCi0gICAgICovCi0gICAgcHVibGljIFhNTFN0cmVhbVJlYWRlciBjcmVhdGVGaWx0ZXJlZFJlYWRlcihYTUxTdHJlYW1SZWFkZXIgcmVhZGVyLCBTdHJlYW1GaWx0ZXIgZmlsdGVyKSB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uIHsKLSAgICAgICAgaWYoIHJlYWRlciAhPSBudWxsICYmIGZpbHRlciAhPSBudWxsICkKLSAgICAgICAgICAgIHJldHVybiBuZXcgWE1MU3RyZWFtRmlsdGVySW1wbChyZWFkZXIsZmlsdGVyKTsKLQotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLQotCi0gICAgLyoqIEdldCB0aGUgdmFsdWUgb2YgYSBmZWF0dXJlL3Byb3BlcnR5IGZyb20gdGhlIHVuZGVybHlpbmcgaW1wbGVtZW50YXRpb24KLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgcHJvcGVydHkgKG1heSBub3QgYmUgbnVsbCkKLSAgICAgKiBAcmV0dXJuIFRoZSB2YWx1ZSBvZiB0aGUgcHJvcGVydHkKLSAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgcHJvcGVydHkgaXMgbm90IHN1cHBvcnRlZAotICAgICAqLwotICAgIHB1YmxpYyBPYmplY3QgZ2V0UHJvcGVydHkoamF2YS5sYW5nLlN0cmluZyBuYW1lKSB0aHJvd3MgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmKG5hbWUgPT0gbnVsbCl7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJQcm9wZXJ0eSBub3Qgc3VwcG9ydGVkIik7Ci0gICAgICAgIH0KLSAgICAgICAgaWYoZlByb3BlcnR5TWFuYWdlci5jb250YWluc1Byb3BlcnR5KG5hbWUpKQotICAgICAgICAgICAgcmV0dXJuIGZQcm9wZXJ0eU1hbmFnZXIuZ2V0UHJvcGVydHkobmFtZSk7Ci0gICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIlByb3BlcnR5IG5vdCBzdXBwb3J0ZWQiKTsKLSAgICB9Ci0KLSAgICAvKiogUXVlcnkgdGhlIHNldCBvZiBmUHJvcGVydGllcyB0aGF0IHRoaXMgZmFjdG9yeSBzdXBwb3J0cy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBwcm9wZXJ0eSAobWF5IG5vdCBiZSBudWxsKQotICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgcHJvcGVydHkgaXMgc3VwcG9ydGVkIGFuZCBmYWxzZSBvdGhlcndpc2UKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc1Byb3BlcnR5U3VwcG9ydGVkKFN0cmluZyBuYW1lKSB7Ci0gICAgICAgIGlmKG5hbWUgPT0gbnVsbCkKLSAgICAgICAgICAgIHJldHVybiBmYWxzZSA7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICAgIHJldHVybiBmUHJvcGVydHlNYW5hZ2VyLmNvbnRhaW5zUHJvcGVydHkobmFtZSk7Ci0gICAgfQotCi0gICAgLyoqIFNldCBhIHVzZXIgZGVmaW5lZCBldmVudCBhbGxvY2F0b3IgZm9yIGV2ZW50cwotICAgICAqIEBwYXJhbSBhbGxvY2F0b3IgdGhlIHVzZXIgZGVmaW5lZCBhbGxvY2F0b3IKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRFdmVudEFsbG9jYXRvcihYTUxFdmVudEFsbG9jYXRvciBhbGxvY2F0b3IpIHsKLSAgICAgICAgZlByb3BlcnR5TWFuYWdlci5zZXRQcm9wZXJ0eShYTUxJbnB1dEZhY3RvcnkuQUxMT0NBVE9SLCBhbGxvY2F0b3IpOwotICAgIH0KLQotICAgIC8qKiBBbGxvd3MgdGhlIHVzZXIgdG8gc2V0IHNwZWNpZmljIGZlYXR1cmUvcHJvcGVydHkgb24gdGhlIHVuZGVybHlpbmcgaW1wbGVtZW50YXRpb24uIFRoZSB1bmRlcmx5aW5nIGltcGxlbWVudGF0aW9uCi0gICAgICogaXMgbm90IHJlcXVpcmVkIHRvIHN1cHBvcnQgZXZlcnkgc2V0dGluZyBvZiBldmVyeSBwcm9wZXJ0eSBpbiB0aGUgc3BlY2lmaWNhdGlvbiBhbmQgbWF5IHVzZSBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KLSAgICAgKiB0byBzaWduYWwgdGhhdCBhbiB1bnN1cHBvcnRlZCBwcm9wZXJ0eSBtYXkgbm90IGJlIHNldCB3aXRoIHRoZSBzcGVjaWZpZWQgdmFsdWUuCi0gICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIHByb3BlcnR5IChtYXkgbm90IGJlIG51bGwpCi0gICAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZSBvZiB0aGUgcHJvcGVydHkKLSAgICAgKiBAdGhyb3dzIGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgdGhlIHByb3BlcnR5IGlzIG5vdCBzdXBwb3J0ZWQKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRQcm9wZXJ0eShqYXZhLmxhbmcuU3RyaW5nIG5hbWUsIE9iamVjdCB2YWx1ZSkgdGhyb3dzIGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gewotCi0gICAgICAgIGlmKG5hbWUgPT0gbnVsbCB8fCB2YWx1ZSA9PSBudWxsIHx8ICFmUHJvcGVydHlNYW5hZ2VyLmNvbnRhaW5zUHJvcGVydHkobmFtZSkgKXsKLSAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIlByb3BlcnR5ICIrbmFtZSsiIGlzIG5vdCBzdXBwb3J0ZWQiKTsKLSAgICAgICAgfQotICAgICAgICBpZihuYW1lID09IENvbnN0YW50cy5SRVVTRV9JTlNUQU5DRSB8fCBuYW1lLmVxdWFscyhDb25zdGFudHMuUkVVU0VfSU5TVEFOQ0UpKXsKLSAgICAgICAgICAgIGZSZXVzZUluc3RhbmNlID0gKChCb29sZWFuKXZhbHVlKS5ib29sZWFuVmFsdWUoKTsKLSAgICAgICAgICAgIGlmKERFQlVHKVN5c3RlbS5vdXQucHJpbnRsbigiZlJldXNlSW5zdGFuY2UgaXMgc2V0IHRvICIgKyBmUmV1c2VJbnN0YW5jZSk7Ci0gICAgICAgIH1lbHNley8vZm9yIGFueSBvdGhlciBwcm9wZXJ0eSBzZXQgdGhlIGZsYWcKLSAgICAgICAgICAgIC8vUkVWSVNJVDogRXZlbiBpbiB0aGlzIGNhc2UgaW5zdGFuY2UgY2FuIGJlIHJldXNlZCwgYnkgcGFzc2luZyBQcm9wZXJ0eU1hbmFnZXIKLSAgICAgICAgICAgIGZQcm9wZXJ0eUNoYW5nZWQgPSB0cnVlOwotICAgICAgICB9Ci0gICAgICAgIGZQcm9wZXJ0eU1hbmFnZXIuc2V0UHJvcGVydHkobmFtZSx2YWx1ZSk7Ci0gICAgfQotCi0gICAgWE1MU3RyZWFtUmVhZGVyIGdldFhNTFN0cmVhbVJlYWRlckltcGwoWE1MSW5wdXRTb3VyY2UgaW5wdXRTb3VyY2UpIHRocm93cyBqYXZheC54bWwuc3RyZWFtLlhNTFN0cmVhbUV4Y2VwdGlvbnsKLSAgICAgICAgLy8xLiBpZiB0aGUgdGVtcCByZWFkZXIgaXMgbnVsbCAtLSBjcmVhdGUgdGhlIGluc3RhbmNlIGFuZCByZXR1cm4KLSAgICAgICAgaWYoZlRlbXBSZWFkZXIgPT0gbnVsbCl7Ci0gICAgICAgICAgICBmUHJvcGVydHlDaGFuZ2VkID0gZmFsc2U7Ci0gICAgICAgICAgICByZXR1cm4gZlRlbXBSZWFkZXIgPSBuZXcgWE1MU3RyZWFtUmVhZGVySW1wbChpbnB1dFNvdXJjZSwKLSAgICAgICAgICAgICAgICAgICAgbmV3IFByb3BlcnR5TWFuYWdlcihmUHJvcGVydHlNYW5hZ2VyKSk7Ci0gICAgICAgIH0KLSAgICAgICAgLy9pZiBmYWN0b3J5IGlzIGNvbmZpZ3VyZWQgdG8gcmV1c2UgdGhlIGluc3RhbmNlICYgdGhpcyBpbnN0YW5jZSBjYW4gYmUgcmV1c2VkCi0gICAgICAgIC8vJiB0aGUgc2V0UHJvcGVydHkoKSBoYXNuJ3QgYmVlbiBjYWxsZWQKLSAgICAgICAgaWYoZlJldXNlSW5zdGFuY2UgJiYgZlRlbXBSZWFkZXIuY2FuUmV1c2UoKSAmJiAhZlByb3BlcnR5Q2hhbmdlZCl7Ci0gICAgICAgICAgICBpZihERUJVRylTeXN0ZW0ub3V0LnByaW50bG4oIlJldXNpbmcgdGhlIGluc3RhbmNlIik7Ci0gICAgICAgICAgICAvL3dlIGNhbiBtYWtlIHNldElucHV0U291cmNlKCkgY2FsbCByZXNldCgpIGFuZCB0aGlzIHdheSB0aGVyZSB3b250IGJlIHR3byBmdW5jdGlvbiBjYWxscwotICAgICAgICAgICAgZlRlbXBSZWFkZXIucmVzZXQoKTsKLSAgICAgICAgICAgIGZUZW1wUmVhZGVyLnNldElucHV0U291cmNlKGlucHV0U291cmNlKTsKLSAgICAgICAgICAgIGZQcm9wZXJ0eUNoYW5nZWQgPSBmYWxzZTsKLSAgICAgICAgICAgIHJldHVybiBmVGVtcFJlYWRlcjsKLSAgICAgICAgfWVsc2V7Ci0gICAgICAgICAgICBmUHJvcGVydHlDaGFuZ2VkID0gZmFsc2U7Ci0gICAgICAgICAgICAvL2p1c3QgcmV0dXJuIHRoZSBuZXcgaW5zdGFuY2UuLiBub3RlIHRoYXQgd2UgYXJlIG5vdCBzZXR0aW5nICBmVGVtcFJlYWRlciB0byB0aGUgbmV3bHkgY3JlYXRlZCBpbnN0YW5jZQotICAgICAgICAgICAgcmV0dXJuIGZUZW1wUmVhZGVyID0gbmV3IFhNTFN0cmVhbVJlYWRlckltcGwoaW5wdXRTb3VyY2UsCi0gICAgICAgICAgICAgICAgICAgIG5ldyBQcm9wZXJ0eU1hbmFnZXIoZlByb3BlcnR5TWFuYWdlcikpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgWE1MSW5wdXRTb3VyY2UgamF4cFNvdXJjZXRvWE1MSW5wdXRTb3VyY2UoU291cmNlIHNvdXJjZSl7Ci0gICAgICAgICBpZihzb3VyY2UgaW5zdGFuY2VvZiBTdHJlYW1Tb3VyY2UpewotICAgICAgICAgICAgIFN0cmVhbVNvdXJjZSBzdFNvdXJjZSA9IChTdHJlYW1Tb3VyY2Upc291cmNlOwotICAgICAgICAgICAgIFN0cmluZyBzeXN0ZW1JZCA9IHN0U291cmNlLmdldFN5c3RlbUlkKCk7Ci0gICAgICAgICAgICAgU3RyaW5nIHB1YmxpY0lkID0gc3RTb3VyY2UuZ2V0UHVibGljSWQoKTsKLSAgICAgICAgICAgICBJbnB1dFN0cmVhbSBpc3RyZWFtID0gc3RTb3VyY2UuZ2V0SW5wdXRTdHJlYW0oKTsKLSAgICAgICAgICAgICBSZWFkZXIgcmVhZGVyID0gc3RTb3VyY2UuZ2V0UmVhZGVyKCk7Ci0KLSAgICAgICAgICAgICBpZihpc3RyZWFtICE9IG51bGwpewotICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFhNTElucHV0U291cmNlKHB1YmxpY0lkLCBzeXN0ZW1JZCwgbnVsbCwgaXN0cmVhbSwgbnVsbCk7Ci0gICAgICAgICAgICAgfQotICAgICAgICAgICAgIGVsc2UgaWYocmVhZGVyICE9IG51bGwpewotICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFhNTElucHV0U291cmNlKHB1YmxpY0lkLCBzeXN0ZW1JZCxudWxsLCByZWFkZXIsIG51bGwpOwotICAgICAgICAgICAgIH1lbHNlewotICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFhNTElucHV0U291cmNlKHB1YmxpY0lkLCBzeXN0ZW1JZCwgbnVsbCk7Ci0gICAgICAgICAgICAgfQotICAgICAgICAgfQotCi0gICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIkNhbm5vdCBjcmVhdGUgIiArCi0gICAgICAgICAgICAgICAgIlhNTFN0cmVhbVJlYWRlciBvciBYTUxFdmVudFJlYWRlciBmcm9tIGEgIiArCi0gICAgICAgICAgICAgICAgc291cmNlLmdldENsYXNzKCkuZ2V0TmFtZSgpKTsKLSAgICB9Ci0KLX0vL1hNTElucHV0RmFjdG9yeUltcGwKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL3htbC9pbnRlcm5hbC9zdHJlYW0vWE1MT3V0cHV0RmFjdG9yeUltcGwuamF2YSBiL3NyYy9jb20vc3VuL3htbC9pbnRlcm5hbC9zdHJlYW0vWE1MT3V0cHV0RmFjdG9yeUltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOWUyNjYzOC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL1hNTE91dHB1dEZhY3RvcnlJbXBsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxOTkgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAwNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLnhtbC5pbnRlcm5hbC5zdHJlYW07Ci0KLWltcG9ydCBqYXZhLmlvLkZpbGU7Ci1pbXBvcnQgamF2YS5pby5GaWxlV3JpdGVyOwotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci1pbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5pby5Xcml0ZXI7Ci0KLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLlhNTE91dHB1dEZhY3RvcnkgOwotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uWE1MU3RyZWFtRXhjZXB0aW9uOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uUmVzdWx0OwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uZG9tLkRPTVJlc3VsdDsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbS5TdHJlYW1SZXN1bHQ7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zdGF4LlN0QVhSZXN1bHQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLkNvbnN0YW50czsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuUHJvcGVydHlNYW5hZ2VyOwotCi1pbXBvcnQgY29tLnN1bi54bWwuaW50ZXJuYWwuc3RyZWFtLndyaXRlcnMuWE1MRE9NV3JpdGVySW1wbDsKLWltcG9ydCBjb20uc3VuLnhtbC5pbnRlcm5hbC5zdHJlYW0ud3JpdGVycy5YTUxFdmVudFdyaXRlckltcGw7Ci1pbXBvcnQgY29tLnN1bi54bWwuaW50ZXJuYWwuc3RyZWFtLndyaXRlcnMuWE1MU3RyZWFtV3JpdGVySW1wbDsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIHByb3ZpZGVzIHRoZSBpbXBsZW1lbnRhdGlvbiBvZiBYTUxPdXRwdXRGYWN0b3J5LgotICoKLSAqIEBhdXRob3IgIE5lZXJhaiBCYWphaiwKLSAqIEBhdXRob3Igay52ZW51Z29wYWxAc3VuLmNvbQotICovCi1wdWJsaWMgY2xhc3MgWE1MT3V0cHV0RmFjdG9yeUltcGwgZXh0ZW5kcyBYTUxPdXRwdXRGYWN0b3J5IHsKLQotICAgIC8vTGlzdCBvZiBzdXBwb3J0ZWQgcHJvcGVydGllcyBhbmQgZGVmYXVsdCB2YWx1ZXMuCi0gICAgcHJpdmF0ZSBQcm9wZXJ0eU1hbmFnZXIgZlByb3BlcnR5TWFuYWdlciA9IG5ldyBQcm9wZXJ0eU1hbmFnZXIoUHJvcGVydHlNYW5hZ2VyLkNPTlRFWFRfV1JJVEVSKTsKLQotICAgIC8vY2FjaGUgdGhlIGluc3RhbmNlIG9mIFhNTFN0cmVhbVdyaXRlckltcGwKLSAgICBwcml2YXRlIFhNTFN0cmVhbVdyaXRlckltcGwgZlN0cmVhbVdyaXRlciA9IG51bGw7Ci0KLSAgICAvKioKLSAgICAgKiBUT0RPOiBhdCB0aGUgY3VycmVudCB0aW1lLCBYTUxTdHJlYW1Xcml0ZXJzIGFyZSBub3QgVGhyZWFkIHNhZmUuCi0gICAgICovCi0gICAgYm9vbGVhbiBmUmV1c2VJbnN0YW5jZSA9IGZhbHNlOwotCi0gICAgLyoqIENyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgWE1MT3V0cHV0RmFjdG9yeSAqLwotICAgIHB1YmxpYyBYTUxPdXRwdXRGYWN0b3J5SW1wbCgpIHsKLSAgICB9Ci0KLSAgICBwdWJsaWMgamF2YXgueG1sLnN0cmVhbS5YTUxFdmVudFdyaXRlciBjcmVhdGVYTUxFdmVudFdyaXRlcihqYXZhLmlvLk91dHB1dFN0cmVhbSBvdXRwdXRTdHJlYW0pIHRocm93cyBqYXZheC54bWwuc3RyZWFtLlhNTFN0cmVhbUV4Y2VwdGlvbiB7Ci0gICAgICAgIHJldHVybiBjcmVhdGVYTUxFdmVudFdyaXRlcihvdXRwdXRTdHJlYW0sICBudWxsKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgamF2YXgueG1sLnN0cmVhbS5YTUxFdmVudFdyaXRlciBjcmVhdGVYTUxFdmVudFdyaXRlcihqYXZhLmlvLk91dHB1dFN0cmVhbSBvdXRwdXRTdHJlYW0sIFN0cmluZyBlbmNvZGluZykgdGhyb3dzIGphdmF4LnhtbC5zdHJlYW0uWE1MU3RyZWFtRXhjZXB0aW9uIHsKLSAgICAgICAgcmV0dXJuIG5ldyBYTUxFdmVudFdyaXRlckltcGwoY3JlYXRlWE1MU3RyZWFtV3JpdGVyKG91dHB1dFN0cmVhbSwgZW5jb2RpbmcpKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgamF2YXgueG1sLnN0cmVhbS5YTUxFdmVudFdyaXRlciBjcmVhdGVYTUxFdmVudFdyaXRlcihqYXZheC54bWwudHJhbnNmb3JtLlJlc3VsdCByZXN1bHQpIHRocm93cyBqYXZheC54bWwuc3RyZWFtLlhNTFN0cmVhbUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIFN0QVhSZXN1bHQgJiYgKChTdEFYUmVzdWx0KXJlc3VsdCkuZ2V0WE1MRXZlbnRXcml0ZXIoKSAhPSBudWxsKQotICAgICAgICAgICAgcmV0dXJuICgoU3RBWFJlc3VsdClyZXN1bHQpLmdldFhNTEV2ZW50V3JpdGVyKCk7Ci0KLSAgICAgICAgcmV0dXJuIG5ldyBYTUxFdmVudFdyaXRlckltcGwoY3JlYXRlWE1MU3RyZWFtV3JpdGVyKHJlc3VsdCkpOwotICAgIH0KLQotICAgIHB1YmxpYyBqYXZheC54bWwuc3RyZWFtLlhNTEV2ZW50V3JpdGVyIGNyZWF0ZVhNTEV2ZW50V3JpdGVyKGphdmEuaW8uV3JpdGVyIHdyaXRlcikgdGhyb3dzIGphdmF4LnhtbC5zdHJlYW0uWE1MU3RyZWFtRXhjZXB0aW9uIHsKLSAgICAgICAgcmV0dXJuIG5ldyBYTUxFdmVudFdyaXRlckltcGwoY3JlYXRlWE1MU3RyZWFtV3JpdGVyKHdyaXRlcikpOwotICAgIH0KLQotICAgIHB1YmxpYyBqYXZheC54bWwuc3RyZWFtLlhNTFN0cmVhbVdyaXRlciBjcmVhdGVYTUxTdHJlYW1Xcml0ZXIoamF2YXgueG1sLnRyYW5zZm9ybS5SZXN1bHQgcmVzdWx0KSB0aHJvd3MgamF2YXgueG1sLnN0cmVhbS5YTUxTdHJlYW1FeGNlcHRpb24gewotCi0gICAgICAgIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBTdHJlYW1SZXN1bHQpIHsKLSAgICAgICAgICAgIHJldHVybiBjcmVhdGVYTUxTdHJlYW1Xcml0ZXIoKFN0cmVhbVJlc3VsdCkgcmVzdWx0LCBudWxsKTsKLSAgICAgICAgfSBlbHNlIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBET01SZXN1bHQpIHsKLSAgICAgICAgICAgIHJldHVybiBuZXcgWE1MRE9NV3JpdGVySW1wbCgoRE9NUmVzdWx0KSByZXN1bHQpOwotICAgICAgICB9IGVsc2UgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIFN0QVhSZXN1bHQpIHsKLSAgICAgICAgICAgIGlmICgoKFN0QVhSZXN1bHQpIHJlc3VsdCkuZ2V0WE1MU3RyZWFtV3JpdGVyKCkgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJldHVybiAoKFN0QVhSZXN1bHQpIHJlc3VsdCkuZ2V0WE1MU3RyZWFtV3JpdGVyKCk7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIlJlc3VsdCBvZiB0eXBlICIgKyByZXN1bHQgKyAiIGlzIG5vdCBzdXBwb3J0ZWQiKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIGlmIChyZXN1bHQuZ2V0U3lzdGVtSWQoKSAhPW51bGwpIHsKLSAgICAgICAgICAgICAgICAvL3RoaXMgaXMgbm90IGNvcnJlY3QgaW1wbCBvZiBTQVhSZXN1bHQuIEtlZXAgaXQgZm9yIG5vdyBmb3IgY29tcGF0aWJpbGl0eQotICAgICAgICAgICAgICAgIHJldHVybiBjcmVhdGVYTUxTdHJlYW1Xcml0ZXIobmV3IFN0cmVhbVJlc3VsdChyZXN1bHQuZ2V0U3lzdGVtSWQoKSkpOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLlVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJSZXN1bHQgb2YgdHlwZSAiICsgcmVzdWx0ICsgIiBpcyBub3Qgc3VwcG9ydGVkLiAiICsKLSAgICAgICAgICAgICAgICAgICAgICAgICJTdXBwb3J0ZWQgcmVzdWx0IHR5cGVzIGFyZTogRE9NUmVzdWx0LCBTdEFYUmVzdWx0IGFuZCBTdHJlYW1SZXN1bHQuIik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgIH0KLQotICAgIHB1YmxpYyBqYXZheC54bWwuc3RyZWFtLlhNTFN0cmVhbVdyaXRlciBjcmVhdGVYTUxTdHJlYW1Xcml0ZXIoamF2YS5pby5Xcml0ZXIgd3JpdGVyKSB0aHJvd3MgamF2YXgueG1sLnN0cmVhbS5YTUxTdHJlYW1FeGNlcHRpb24gewotICAgICAgICByZXR1cm4gY3JlYXRlWE1MU3RyZWFtV3JpdGVyKHRvU3RyZWFtUmVzdWx0KG51bGwsIHdyaXRlciwgbnVsbCkgLCBudWxsKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgamF2YXgueG1sLnN0cmVhbS5YTUxTdHJlYW1Xcml0ZXIgY3JlYXRlWE1MU3RyZWFtV3JpdGVyKGphdmEuaW8uT3V0cHV0U3RyZWFtIG91dHB1dFN0cmVhbSkgdGhyb3dzIGphdmF4LnhtbC5zdHJlYW0uWE1MU3RyZWFtRXhjZXB0aW9uIHsKLSAgICAgICAgcmV0dXJuIGNyZWF0ZVhNTFN0cmVhbVdyaXRlcihvdXRwdXRTdHJlYW0sIG51bGwpOwotICAgIH0KLQotICAgIHB1YmxpYyBqYXZheC54bWwuc3RyZWFtLlhNTFN0cmVhbVdyaXRlciBjcmVhdGVYTUxTdHJlYW1Xcml0ZXIoamF2YS5pby5PdXRwdXRTdHJlYW0gb3V0cHV0U3RyZWFtLCBTdHJpbmcgZW5jb2RpbmcpIHRocm93cyBqYXZheC54bWwuc3RyZWFtLlhNTFN0cmVhbUV4Y2VwdGlvbiB7Ci0gICAgICAgIHJldHVybiBjcmVhdGVYTUxTdHJlYW1Xcml0ZXIodG9TdHJlYW1SZXN1bHQob3V0cHV0U3RyZWFtLCBudWxsLCBudWxsKSAsIGVuY29kaW5nKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgT2JqZWN0IGdldFByb3BlcnR5KFN0cmluZyBuYW1lKSB0aHJvd3MgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmKG5hbWUgPT0gbnVsbCl7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJQcm9wZXJ0eSBub3Qgc3VwcG9ydGVkIik7Ci0gICAgICAgIH0KLSAgICAgICAgaWYoZlByb3BlcnR5TWFuYWdlci5jb250YWluc1Byb3BlcnR5KG5hbWUpKQotICAgICAgICAgICAgcmV0dXJuIGZQcm9wZXJ0eU1hbmFnZXIuZ2V0UHJvcGVydHkobmFtZSk7Ci0gICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIlByb3BlcnR5IG5vdCBzdXBwb3J0ZWQiKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBpc1Byb3BlcnR5U3VwcG9ydGVkKFN0cmluZyBuYW1lKSB7Ci0gICAgICAgIGlmKG5hbWUgPT0gbnVsbCl7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2UgOwotICAgICAgICB9Ci0gICAgICAgIGVsc2V7Ci0gICAgICAgICAgICByZXR1cm4gZlByb3BlcnR5TWFuYWdlci5jb250YWluc1Byb3BlcnR5KG5hbWUpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0UHJvcGVydHkoU3RyaW5nIG5hbWUsIE9iamVjdCB2YWx1ZSkgdGhyb3dzIGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gewotICAgICAgICBpZihuYW1lID09IG51bGwgfHwgdmFsdWUgPT0gbnVsbCB8fCAhZlByb3BlcnR5TWFuYWdlci5jb250YWluc1Byb3BlcnR5KG5hbWUpICl7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJQcm9wZXJ0eSAiK25hbWUrImlzIG5vdCBzdXBwb3J0ZWQiKTsKLSAgICAgICAgfQotICAgICAgICBpZihuYW1lID09IENvbnN0YW50cy5SRVVTRV9JTlNUQU5DRSB8fCBuYW1lLmVxdWFscyhDb25zdGFudHMuUkVVU0VfSU5TVEFOQ0UpKXsKLSAgICAgICAgICAgIGZSZXVzZUluc3RhbmNlID0gKChCb29sZWFuKXZhbHVlKS5ib29sZWFuVmFsdWUoKTsKLSAgICAgICAgICAgIGlmKERFQlVHKVN5c3RlbS5vdXQucHJpbnRsbigiZlJldXNlSW5zdGFuY2UgaXMgc2V0IHRvICIgKyBmUmV1c2VJbnN0YW5jZSk7Ci0KLSAgICAgICAgICAgIC8vIFRPRE86IFhNTFN0cmVhbVdyaXRlcnMgYXJlIG5vdCBUaHJlYWQgc2FmZSwKLSAgICAgICAgICAgIC8vIGRvbid0IGxldCBhcHBsaWNhdGlvbiB0aGluayBpdCBpcyBvcHRpbWl6aW5nCi0gICAgICAgICAgICBpZiAoZlJldXNlSW5zdGFuY2UpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICAgICAgIlByb3BlcnR5ICIKLSAgICAgICAgICAgICAgICAgICAgICAgICsgbmFtZQotICAgICAgICAgICAgICAgICAgICAgICAgKyAiIGlzIG5vdCBzdXBwb3J0ZWQ6IFhNTFN0cmVhbVdyaXRlcnMgYXJlIG5vdCBUaHJlYWQgc2FmZSIpOwotICAgICAgICAgICAgfQotICAgICAgICB9ZWxzZXsvL2ZvciBhbnkgb3RoZXIgcHJvcGVydHkgc2V0IHRoZSBmbGFnCi0gICAgICAgICAgICAvL1JFVklTSVQ6IEV2ZW4gaW4gdGhpcyBjYXNlIGluc3RhbmNlIGNhbiBiZSByZXVzZWQsIGJ5IHBhc3NpbmcgUHJvcGVydHlNYW5hZ2VyCi0gICAgICAgICAgICBmUHJvcGVydHlDaGFuZ2VkID0gdHJ1ZTsKLSAgICAgICAgfQotICAgICAgICBmUHJvcGVydHlNYW5hZ2VyLnNldFByb3BlcnR5KG5hbWUsdmFsdWUpOwotICAgIH0KLQotICAgIC8qKiBTdHJlYW1SZXN1bHQgb2JqZWN0IGlzIHJlLXVzZWQgYW5kIHRoZSB2YWx1ZXMgYXJlIHNldCBhcHByb3ByaWF0ZWx5LgotICAgICAqLwotICAgIFN0cmVhbVJlc3VsdCB0b1N0cmVhbVJlc3VsdChPdXRwdXRTdHJlYW0gb3MsIFdyaXRlciB3cml0ZXIsIFN0cmluZyBzeXN0ZW1JZCl7Ci0gICAgICAgIFN0cmVhbVJlc3VsdCBzciA9IG5ldyBTdHJlYW1SZXN1bHQoKTsKLSAgICAgICAgc3Iuc2V0T3V0cHV0U3RyZWFtKG9zKTsKLSAgICAgICAgc3Iuc2V0V3JpdGVyKHdyaXRlcik7Ci0gICAgICAgIHNyLnNldFN5c3RlbUlkKHN5c3RlbUlkKTsKLSAgICAgICAgcmV0dXJuIHNyOwotICAgIH0KLQotICAgIGphdmF4LnhtbC5zdHJlYW0uWE1MU3RyZWFtV3JpdGVyIGNyZWF0ZVhNTFN0cmVhbVdyaXRlcihqYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbS5TdHJlYW1SZXN1bHQgc3IsIFN0cmluZyBlbmNvZGluZykgdGhyb3dzIGphdmF4LnhtbC5zdHJlYW0uWE1MU3RyZWFtRXhjZXB0aW9uIHsKLSAgICAgICAgLy9pZiBmYWN0b3J5IGlzIGNvbmZpZ3VyZWQgdG8gcmV1c2UgdGhlIGluc3RhbmNlICYgdGhpcyBpbnN0YW5jZSBjYW4gYmUgcmV1c2VkCi0gICAgICAgIC8vJiB0aGUgc2V0UHJvcGVydHkoKSBoYXNuJ3QgYmVlbiBjYWxsZWQKLSAgICAgICAgdHJ5ewotICAgICAgICAgICAgaWYoZlJldXNlSW5zdGFuY2UgJiYgZlN0cmVhbVdyaXRlciAhPSBudWxsICYmIGZTdHJlYW1Xcml0ZXIuY2FuUmV1c2UoKSAmJiAhZlByb3BlcnR5Q2hhbmdlZCl7Ci0gICAgICAgICAgICAgICAgZlN0cmVhbVdyaXRlci5yZXNldCgpOwotICAgICAgICAgICAgICAgIGZTdHJlYW1Xcml0ZXIuc2V0T3V0cHV0KHNyLCBlbmNvZGluZyk7Ci0gICAgICAgICAgICAgICAgaWYoREVCVUcpU3lzdGVtLm91dC5wcmludGxuKCJyZXVzaW5nIGluc3RhbmNlLCBvYmplY3QgaWQgOiAiICsgZlN0cmVhbVdyaXRlcik7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGZTdHJlYW1Xcml0ZXI7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gZlN0cmVhbVdyaXRlciA9IG5ldyBYTUxTdHJlYW1Xcml0ZXJJbXBsKHNyLCBlbmNvZGluZywgbmV3IFByb3BlcnR5TWFuYWdlcihmUHJvcGVydHlNYW5hZ2VyKSk7Ci0gICAgICAgIH1jYXRjaChqYXZhLmlvLklPRXhjZXB0aW9uIGlvKXsKLSAgICAgICAgICAgIHRocm93IG5ldyBYTUxTdHJlYW1FeGNlcHRpb24oaW8pOwotICAgICAgICB9Ci0gICAgfS8vY3JlYXRlWE1MU3RyZWFtV3JpdGVyKFN0cmVhbVJlc3VsdCxTdHJpbmcpCi0KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIERFQlVHID0gZmFsc2U7Ci0KLSAgICAvKiogVGhpcyBmbGFnIGluZGljYXRlcyB0aGUgY2hhbmdlIG9mIHByb3BlcnR5LiBJZiB0cnVlLAotICAgICAqIDxjb2RlPlByb3BlcnR5TWFuYWdlcjwvY29kZT4gc2hvdWxkIGJlIHBhc3NlZCB3aGVuIGNyZWF0aW5nCi0gICAgICogPGNvZGU+WE1MU3RyZWFtV3JpdGVySW1wbDwvY29kZT4gKi8KLSAgICBwcml2YXRlIGJvb2xlYW4gZlByb3BlcnR5Q2hhbmdlZCA7Ci19Ly9YTUxPdXRwdXRGYWN0b3J5CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL2R0ZC9EVERHcmFtbWFyVXRpbC5qYXZhIGIvc3JjL2NvbS9zdW4veG1sL2ludGVybmFsL3N0cmVhbS9kdGQvRFRER3JhbW1hclV0aWwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYjEzMzFiNS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL2R0ZC9EVERHcmFtbWFyVXRpbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDk4ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMDYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKi8KLQotLyoKLSAqIENvcHlyaWdodCAyMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLnhtbC5pbnRlcm5hbC5zdHJlYW0uZHRkOwotaW1wb3J0IGNvbS5zdW4ueG1sLmludGVybmFsLnN0cmVhbS5kdGQubm9udmFsaWRhdGluZy5EVERHcmFtbWFyOwotaW1wb3J0IGNvbS5zdW4ueG1sLmludGVybmFsLnN0cmVhbS5kdGQubm9udmFsaWRhdGluZy5YTUxBdHRyaWJ1dGVEZWNsOwotaW1wb3J0IGNvbS5zdW4ueG1sLmludGVybmFsLnN0cmVhbS5kdGQubm9udmFsaWRhdGluZy5YTUxFbGVtZW50RGVjbDsKLWltcG9ydCBjb20uc3VuLnhtbC5pbnRlcm5hbC5zdHJlYW0uZHRkLm5vbnZhbGlkYXRpbmcuWE1MU2ltcGxlVHlwZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuQ29uc3RhbnRzOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5YTUxFbnRpdHlNYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5YTUxFcnJvclJlcG9ydGVyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5TeW1ib2xUYWJsZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuWE1MQ2hhcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuWE1MU3ltYm9sczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5BdWdtZW50YXRpb25zOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlFOYW1lOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLk5hbWVzcGFjZUNvbnRleHQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MQXR0cmlidXRlczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxEb2N1bWVudEhhbmRsZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MTG9jYXRvcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxTdHJpbmc7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE5JRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxDb21wb25lbnRNYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxEb2N1bWVudFNvdXJjZTsKLWltcG9ydCBqYXZheC54bWwuWE1MQ29uc3RhbnRzOwotCi0gLyoKLSAgKiBAYXV0aG9yIEVyaWMgWWUsIElCTQotICAqIEBhdXRob3IgQW5keSBDbGFyaywgSUJNCi0gICogQGF1dGhvciBKZWZmcmV5IFJvZHJpZ3VleiBJQk0KLSAgKiBAYXV0aG9yIE5laWwgR3JhaGFtLCBJQk0KLSAgKiBAYXV0aG9yIFN1bml0aGEgUmVkZHksIFN1biBNaWNyb3N5c3RlbXMKLSAgKi8KLQotcHVibGljIGNsYXNzIERUREdyYW1tYXJVdGlsIHsKLQotCi0gICAgLyoqIFByb3BlcnR5IGlkZW50aWZpZXI6IHN5bWJvbCB0YWJsZS4gKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBTWU1CT0xfVEFCTEUgPQotICAgIENvbnN0YW50cy5YRVJDRVNfUFJPUEVSVFlfUFJFRklYICsgQ29uc3RhbnRzLlNZTUJPTF9UQUJMRV9QUk9QRVJUWTsKLQotICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIE5BTUVTUEFDRVMgPQotICAgIENvbnN0YW50cy5TQVhfRkVBVFVSRV9QUkVGSVggKyBDb25zdGFudHMuTkFNRVNQQUNFU19GRUFUVVJFOwotCi0KLSAgICAvKiogQ29tcGlsZSB0byB0cnVlIHRvIGRlYnVnIGF0dHJpYnV0ZXMuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbiBERUJVR19BVFRSSUJVVEVTID0gZmFsc2U7Ci0KLSAgICAvKiogQ29tcGlsZSB0byB0cnVlIHRvIGRlYnVnIGVsZW1lbnQgY2hpbGRyZW4uICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbiBERUJVR19FTEVNRU5UX0NISUxEUkVOID0gZmFsc2U7Ci0KLSAgICBwcm90ZWN0ZWQgRFRER3JhbW1hciBmRFRER3JhbW1hciA9IG51bGw7Ci0gICAgLyoqIE5hbWVzcGFjZXMuICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gZk5hbWVzcGFjZXM7Ci0KLSAgICAvKiogU3ltYm9sIHRhYmxlLiAqLwotICAgIHByb3RlY3RlZCBTeW1ib2xUYWJsZSBmU3ltYm9sVGFibGUgPSBudWxsOwotCi0gICAgLyoqIEN1cnJlbnQgZWxlbWVudCBpbmRleC4gKi8KLSAgICBwcml2YXRlIGludCBmQ3VycmVudEVsZW1lbnRJbmRleCA9IC0xOwotCi0gICAgLyoqIEN1cnJlbnQgY29udGVudCBzcGVjIHR5cGUuICovCi0gICAgcHJpdmF0ZSBpbnQgZkN1cnJlbnRDb250ZW50U3BlY1R5cGUgPSAtMTsKLQotICAgIC8qKiBDb250ZW50IHNwZWMgdHlwZSBzdGFjay4gKi8KLSAgICBwcml2YXRlIGJvb2xlYW5bXSBmRWxlbWVudENvbnRlbnRTdGF0ZSA9IG5ldyBib29sZWFuWzhdOwotCi0gICAgLyoqIEVsZW1lbnQgZGVwdGguICovCi0gICAgcHJpdmF0ZSBpbnQgZkVsZW1lbnREZXB0aCA9IC0xOwotCi0gICAgLyoqIFRydWUgaWYgaW5zaWRlIG9mIGVsZW1lbnQgY29udGVudC4gKi8KLSAgICBwcml2YXRlIGJvb2xlYW4gZkluRWxlbWVudENvbnRlbnQgPSBmYWxzZTsKLQotICAgIC8qKiBUZW1wb3JhcnkgYXRyaWJ1dGUgZGVjbGFyYXRpb24uICovCi0gICAgcHJpdmF0ZSBYTUxBdHRyaWJ1dGVEZWNsIGZUZW1wQXR0RGVjbCA9IG5ldyBYTUxBdHRyaWJ1dGVEZWNsKCk7Ci0KLSAgICAvKiogVGVtcG9yYXJ5IHF1YWxpZmllZCBuYW1lLiAqLwotICAgIHByaXZhdGUgUU5hbWUgZlRlbXBRTmFtZSA9IG5ldyBRTmFtZSgpOwotCi0gICAgLyoqIFRlbXBvcmFyeSBzdHJpbmcgYnVmZmVycy4gKi8KLSAgICBwcml2YXRlIFN0cmluZ0J1ZmZlciBmQnVmZmVyID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotCi0gICAgcHJpdmF0ZSBOYW1lc3BhY2VDb250ZXh0IGZOYW1lc3BhY2VDb250ZXh0ID0gbnVsbDsKLQotICAgIC8qKiBEZWZhdWx0IGNvbnN0cnVjdG9yLiAqLwotICAgIHB1YmxpYyBEVERHcmFtbWFyVXRpbChTeW1ib2xUYWJsZSBzeW1ib2xUYWJsZSkgewotICAgICAgICBmU3ltYm9sVGFibGUgPSBzeW1ib2xUYWJsZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgRFRER3JhbW1hclV0aWwoRFRER3JhbW1hciBncmFtbWFyLCBTeW1ib2xUYWJsZSBzeW1ib2xUYWJsZSkgewotICAgICAgICBmRFRER3JhbW1hciA9IGdyYW1tYXI7Ci0gICAgICAgIGZTeW1ib2xUYWJsZSA9IHN5bWJvbFRhYmxlOwotICAgIH0KLQotICAgIHB1YmxpYyBEVERHcmFtbWFyVXRpbChEVERHcmFtbWFyIGdyYW1tYXIsIFN5bWJvbFRhYmxlIHN5bWJvbFRhYmxlLAotICAgICAgICAgICAgTmFtZXNwYWNlQ29udGV4dCBuYW1lc3BhY2VDb250ZXh0KSB7Ci0gICAgICAgIGZEVERHcmFtbWFyID0gZ3JhbW1hcjsKLSAgICAgICAgZlN5bWJvbFRhYmxlID0gc3ltYm9sVGFibGU7Ci0gICAgICAgIGZOYW1lc3BhY2VDb250ZXh0ID0gbmFtZXNwYWNlQ29udGV4dDsKLSAgICB9Ci0KLSAgICAvKgotICAgICAqIFJlc2V0cyB0aGUgY29tcG9uZW50LiBUaGUgY29tcG9uZW50IGNhbiBxdWVyeSB0aGUgY29tcG9uZW50IG1hbmFnZXIKLSAgICAgKiBhYm91dCBhbnkgZmVhdHVyZXMgYW5kIHByb3BlcnRpZXMgdGhhdCBhZmZlY3QgdGhlIG9wZXJhdGlvbiBvZiB0aGUKLSAgICAgKiBjb21wb25lbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29tcG9uZW50TWFuYWdlciBUaGUgY29tcG9uZW50IG1hbmFnZXIuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBUaHJvd24gYnkgY29tcG9uZW50IG9uIGZpbml0aWFsaXphdGlvbiBlcnJvci4KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBGb3IgZXhhbXBsZSwgaWYgYSBmZWF0dXJlIG9yIHByb3BlcnR5IGlzCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgcmVxdWlyZWQgZm9yIHRoZSBvcGVyYXRpb24gb2YgdGhlIGNvbXBvbmVudCwgdGhlCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgY29tcG9uZW50IG1hbmFnZXIgbWF5IHRocm93IGEKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIG9yIGEKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcmVzZXQoWE1MQ29tcG9uZW50TWFuYWdlciBjb21wb25lbnRNYW5hZ2VyKQotICAgIHRocm93cyBYTUxDb25maWd1cmF0aW9uRXhjZXB0aW9uIHsKLQotICAgICAgICBmRFRER3JhbW1hciA9IG51bGw7Ci0gICAgICAgIGZJbkVsZW1lbnRDb250ZW50ID0gZmFsc2U7Ci0gICAgICAgIGZDdXJyZW50RWxlbWVudEluZGV4ID0gLTE7Ci0gICAgICAgIGZDdXJyZW50Q29udGVudFNwZWNUeXBlID0gLTE7Ci0gICAgICAgIGZOYW1lc3BhY2VzID0gY29tcG9uZW50TWFuYWdlci5nZXRGZWF0dXJlKE5BTUVTUEFDRVMsIHRydWUpOwotICAgICAgICBmU3ltYm9sVGFibGUgPSAoU3ltYm9sVGFibGUpIGNvbXBvbmVudE1hbmFnZXIuZ2V0UHJvcGVydHkoCi0gICAgICAgICAgICAgICAgQ29uc3RhbnRzLlhFUkNFU19QUk9QRVJUWV9QUkVGSVggKyBDb25zdGFudHMuU1lNQk9MX1RBQkxFX1BST1BFUlRZKTsKLSAgICAgICAgZkVsZW1lbnREZXB0aCA9IC0xOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogVGhlIHN0YXJ0IG9mIGFuIGVsZW1lbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZWxlbWVudCAgICBUaGUgbmFtZSBvZiB0aGUgZWxlbWVudC4KLSAgICAgKiBAcGFyYW0gYXR0cmlidXRlcyBUaGUgZWxlbWVudCBhdHRyaWJ1dGVzLgotICAgICAqIEBwYXJhbSBhdWdzICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudChRTmFtZSBlbGVtZW50LCBYTUxBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMpICB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICAgICAgaGFuZGxlU3RhcnRFbGVtZW50KGVsZW1lbnQsIGF0dHJpYnV0ZXMpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoZSBlbmQgb2YgYW4gZWxlbWVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlbGVtZW50IFRoZSBuYW1lIG9mIHRoZSBlbGVtZW50LgotICAgICAqIEBwYXJhbSBhdWdzICAgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQgYXVnbWVudGF0aW9ucwotICAgICAqCi0gICAgICogQHRocm93cyBYTklFeGNlcHRpb24gVGhyb3duIGJ5IGhhbmRsZXIgdG8gc2lnbmFsIGFuIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZEVsZW1lbnQoUU5hbWUgZWxlbWVudCkgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIGhhbmRsZUVuZEVsZW1lbnQoZWxlbWVudCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhlIHN0YXJ0IG9mIGEgQ0RBVEEgc2VjdGlvbi4KLSAgICAgKiBAcGFyYW0gYXVncyAgIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0IGF1Z21lbnRhdGlvbnMKLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydENEQVRBKEF1Z21lbnRhdGlvbnMgYXVncykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhlIGVuZCBvZiBhIENEQVRBIHNlY3Rpb24uCi0gICAgICogQHBhcmFtIGF1Z3MgICBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgbWF5IGluY2x1ZGUgaW5mb3NldCBhdWdtZW50YXRpb25zCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kQ0RBVEEoQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLSAgICB9Ci0KLQotCi0gICAgLyoqIEFkZCBkZWZhdWx0IGF0dHJpYnV0ZXMgYW5kIHZhbGlkYXRlLiAqLwotICAgIHB1YmxpYyB2b2lkIGFkZERURERlZmF1bHRBdHRycyhRTmFtZSBlbGVtZW50TmFtZSwgWE1MQXR0cmlidXRlcyBhdHRyaWJ1dGVzKQotICAgIHRocm93cyBYTklFeGNlcHRpb24gewotCi0gICAgICAgIGludCBlbGVtZW50SW5kZXg7Ci0gICAgICAgIGVsZW1lbnRJbmRleCA9IGZEVERHcmFtbWFyLmdldEVsZW1lbnREZWNsSW5kZXgoZWxlbWVudE5hbWUpOwotICAgICAgICAvLyBpcyB0aGVyZSBhbnl0aGluZyB0byBkbz8KLSAgICAgICAgaWYgKGVsZW1lbnRJbmRleCA9PSAtMSB8fCBmRFRER3JhbW1hciA9PSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLQotICAgICAgICAvLwotICAgICAgICAvLyBDaGVjayBhZnRlciBhbGwgc3BlY2lmaWVkIGF0dHJzIGFyZSBzY2FubmVkCi0gICAgICAgIC8vICgxKSByZXBvcnQgZXJyb3IgZm9yIFJFUVVJUkVEIGF0dHJzIHRoYXQgYXJlIG1pc3NpbmcgKFZfVEFHYykKLSAgICAgICAgLy8gKDIpIGFkZCBkZWZhdWx0IGF0dHJzIChGSVhFRCBhbmQgTk9UX0ZJWEVEKQotICAgICAgICAvLwotICAgICAgICBpbnQgYXR0bGlzdEluZGV4ID0gZkRUREdyYW1tYXIuZ2V0Rmlyc3RBdHRyaWJ1dGVEZWNsSW5kZXgoZWxlbWVudEluZGV4KTsKLQotICAgICAgICB3aGlsZSAoYXR0bGlzdEluZGV4ICE9IC0xKSB7Ci0KLSAgICAgICAgICAgIGZEVERHcmFtbWFyLmdldEF0dHJpYnV0ZURlY2woYXR0bGlzdEluZGV4LCBmVGVtcEF0dERlY2wpOwotCi0gICAgICAgICAgICBpZiAoREVCVUdfQVRUUklCVVRFUykgewotICAgICAgICAgICAgICAgIGlmIChmVGVtcEF0dERlY2wgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBYTUxFbGVtZW50RGVjbCBlbGVtZW50RGVjbCA9IG5ldyBYTUxFbGVtZW50RGVjbCgpOwotICAgICAgICAgICAgICAgICAgICBmRFRER3JhbW1hci5nZXRFbGVtZW50RGVjbChlbGVtZW50SW5kZXgsIGVsZW1lbnREZWNsKTsKLSAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJlbGVtZW50OiAiICsgKGVsZW1lbnREZWNsLm5hbWUubG9jYWxwYXJ0KSk7Ci0gICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiYXR0bGlzdEluZGV4ICIgKyBhdHRsaXN0SW5kZXggKyAiXG4iICsKLSAgICAgICAgICAgICAgICAgICAgImF0dE5hbWUgOiAnIiArIChmVGVtcEF0dERlY2wubmFtZS5sb2NhbHBhcnQpICsgIidcbiIKLSAgICAgICAgICAgICAgICAgICAgKyAiYXR0VHlwZSA6ICIgKyBmVGVtcEF0dERlY2wuc2ltcGxlVHlwZS50eXBlICsgIlxuIgotICAgICAgICAgICAgICAgICAgICArICJhdHREZWZhdWx0VHlwZSA6ICIgKyBmVGVtcEF0dERlY2wuc2ltcGxlVHlwZS5kZWZhdWx0VHlwZSArICJcbiIKLSAgICAgICAgICAgICAgICAgICAgKyAiYXR0RGVmYXVsdFZhbHVlIDogJyIgKyBmVGVtcEF0dERlY2wuc2ltcGxlVHlwZS5kZWZhdWx0VmFsdWUgKyAiJ1xuIgotICAgICAgICAgICAgICAgICAgICArIGF0dHJpYnV0ZXMuZ2V0TGVuZ3RoKCkgKyAiXG4iCi0gICAgICAgICAgICAgICAgICAgICk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgU3RyaW5nIGF0dFByZWZpeCA9IGZUZW1wQXR0RGVjbC5uYW1lLnByZWZpeDsKLSAgICAgICAgICAgIFN0cmluZyBhdHRMb2NhbHBhcnQgPSBmVGVtcEF0dERlY2wubmFtZS5sb2NhbHBhcnQ7Ci0gICAgICAgICAgICBTdHJpbmcgYXR0UmF3TmFtZSA9IGZUZW1wQXR0RGVjbC5uYW1lLnJhd25hbWU7Ci0gICAgICAgICAgICBTdHJpbmcgYXR0VHlwZSA9IGdldEF0dHJpYnV0ZVR5cGVOYW1lKGZUZW1wQXR0RGVjbCk7Ci0gICAgICAgICAgICBpbnQgYXR0RGVmYXVsdFR5cGUgPSBmVGVtcEF0dERlY2wuc2ltcGxlVHlwZS5kZWZhdWx0VHlwZTsKLSAgICAgICAgICAgIFN0cmluZyBhdHRWYWx1ZSA9IG51bGw7Ci0KLSAgICAgICAgICAgIGlmIChmVGVtcEF0dERlY2wuc2ltcGxlVHlwZS5kZWZhdWx0VmFsdWUgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGF0dFZhbHVlID0gZlRlbXBBdHREZWNsLnNpbXBsZVR5cGUuZGVmYXVsdFZhbHVlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgYm9vbGVhbiBzcGVjaWZpZWQgPSBmYWxzZTsKLSAgICAgICAgICAgIGJvb2xlYW4gcmVxdWlyZWQgPSBhdHREZWZhdWx0VHlwZSA9PSBYTUxTaW1wbGVUeXBlLkRFRkFVTFRfVFlQRV9SRVFVSVJFRDsKLSAgICAgICAgICAgIGJvb2xlYW4gY2RhdGEgPSBhdHRUeXBlID09IFhNTFN5bWJvbHMuZkNEQVRBU3ltYm9sOwotCi0gICAgICAgICAgICBpZiAoIWNkYXRhIHx8IHJlcXVpcmVkIHx8IGF0dFZhbHVlICE9IG51bGwpIHsKLQotICAgICAgICAgICAgICAgIC8vY2hlY2sgd2hldGhlciBhdHRyaWJ1dGUgaXMgYSBuYW1lc3BhY2UgZGVjbGFyYXRpb24KLSAgICAgICAgICAgICAgICBpZiAoZk5hbWVzcGFjZUNvbnRleHQgIT0gbnVsbCAmJiBhdHRSYXdOYW1lLnN0YXJ0c1dpdGgoWE1MQ29uc3RhbnRzLlhNTE5TX0FUVFJJQlVURSkpIHsKLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHByZWZpeCA9ICIiOwotICAgICAgICAgICAgICAgICAgICBpbnQgcG9zID0gYXR0UmF3TmFtZS5pbmRleE9mKCc6Jyk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChwb3MgIT0gLTEpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHByZWZpeCA9IGF0dFJhd05hbWUuc3Vic3RyaW5nKDAsIHBvcyk7Ci0gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBwcmVmaXggPSBhdHRSYXdOYW1lOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIHByZWZpeCA9IGZTeW1ib2xUYWJsZS5hZGRTeW1ib2wocHJlZml4KTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKCEoKGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC4KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBOYW1lc3BhY2VTdXBwb3J0KSBmTmFtZXNwYWNlQ29udGV4dCkuCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGFpbnNQcmVmaXhJbkN1cnJlbnRDb250ZXh0KHByZWZpeCkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZOYW1lc3BhY2VDb250ZXh0LmRlY2xhcmVQcmVmaXgocHJlZml4LCBhdHRWYWx1ZSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgc3BlY2lmaWVkID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICB9IGVsc2UgewotCi0gICAgICAgICAgICAgICAgICAgIGludCBhdHRyQ291bnQgPSBhdHRyaWJ1dGVzLmdldExlbmd0aCgpOwotICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGF0dHJDb3VudDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXR0cmlidXRlcy5nZXRRTmFtZShpKSA9PSBhdHRSYXdOYW1lKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BlY2lmaWVkID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmICghc3BlY2lmaWVkKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGF0dFZhbHVlICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGZOYW1lc3BhY2VzKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpbnQgaW5kZXggPSBhdHRSYXdOYW1lLmluZGV4T2YoJzonKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbmRleCAhPSAtMSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dFByZWZpeCA9IGF0dFJhd05hbWUuc3Vic3RyaW5nKDAsIGluZGV4KTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRQcmVmaXggPSBmU3ltYm9sVGFibGUuYWRkU3ltYm9sKGF0dFByZWZpeCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0TG9jYWxwYXJ0ID0gYXR0UmF3TmFtZS5zdWJzdHJpbmcoaW5kZXggKyAxKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRMb2NhbHBhcnQgPSBmU3ltYm9sVGFibGUuYWRkU3ltYm9sKGF0dExvY2FscGFydCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZlRlbXBRTmFtZS5zZXRWYWx1ZXMoYXR0UHJlZml4LCBhdHRMb2NhbHBhcnQsIGF0dFJhd05hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZlRlbXBBdHREZWNsLm5hbWUudXJpKTsKLSAgICAgICAgICAgICAgICAgICAgaW50IG5ld0F0dHIgPSBhdHRyaWJ1dGVzLmFkZEF0dHJpYnV0ZShmVGVtcFFOYW1lLCBhdHRUeXBlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dFZhbHVlKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBhdHRsaXN0SW5kZXggPSBmRFRER3JhbW1hci5nZXROZXh0QXR0cmlidXRlRGVjbEluZGV4KGF0dGxpc3RJbmRleCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBub3cgaXRlcmF0ZSB0aHJvdWdoIHRoZSBleHBhbmRlZCBhdHRyaWJ1dGVzIGZvcgotICAgICAgICAvLyAxLiBpZiBldmVyeSBhdHRyaWJ1dGUgc2VlbiBpcyBkZWNsYXJlZCBpbiB0aGUgRFRECi0gICAgICAgIC8vIDIuIGNoZWNrIGlmIHRoZSBWQzogZGVmYXVsdF9maXhlZCBob2xkcwotICAgICAgICAvLyAzLiB2YWxpZGF0ZSBldmVyeSBhdHRyaWJ1dGUuCi0gICAgICAgIGludCBhdHRyQ291bnQgPSBhdHRyaWJ1dGVzLmdldExlbmd0aCgpOwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGF0dHJDb3VudDsgaSsrKSB7Ci0gICAgICAgICAgICBTdHJpbmcgYXR0clJhd05hbWUgPSBhdHRyaWJ1dGVzLmdldFFOYW1lKGkpOwotICAgICAgICAgICAgYm9vbGVhbiBkZWNsYXJlZCA9IGZhbHNlOwotICAgICAgICAgICAgaW50IHBvc2l0aW9uID0KLSAgICAgICAgICAgIGZEVERHcmFtbWFyLmdldEZpcnN0QXR0cmlidXRlRGVjbEluZGV4KGVsZW1lbnRJbmRleCk7Ci0gICAgICAgICAgICB3aGlsZSAocG9zaXRpb24gIT0gLTEpIHsKLSAgICAgICAgICAgICAgICBmRFRER3JhbW1hci5nZXRBdHRyaWJ1dGVEZWNsKHBvc2l0aW9uLCBmVGVtcEF0dERlY2wpOwotICAgICAgICAgICAgICAgIGlmIChmVGVtcEF0dERlY2wubmFtZS5yYXduYW1lID09IGF0dHJSYXdOYW1lKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIGZvdW5kIHRoZSBtYXRjaCBhdHQgZGVjbCwKLSAgICAgICAgICAgICAgICAgICAgZGVjbGFyZWQgPSB0cnVlOwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgcG9zaXRpb24gPSBmRFRER3JhbW1hci5nZXROZXh0QXR0cmlidXRlRGVjbEluZGV4KHBvc2l0aW9uKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmICghZGVjbGFyZWQpIHsKLSAgICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgU3RyaW5nIHR5cGUgPSBnZXRBdHRyaWJ1dGVUeXBlTmFtZShmVGVtcEF0dERlY2wpOwotICAgICAgICAgICAgYXR0cmlidXRlcy5zZXRUeXBlKGksIHR5cGUpOwotCi0gICAgICAgICAgICBib29sZWFuIGNoYW5nZWRCeU5vcm1hbGl6YXRpb24gPSBmYWxzZTsKLSAgICAgICAgICAgIGlmIChhdHRyaWJ1dGVzLmlzU3BlY2lmaWVkKGkpICYmIHR5cGUgIT0gWE1MU3ltYm9scy5mQ0RBVEFTeW1ib2wpIHsKLSAgICAgICAgICAgICAgICBjaGFuZ2VkQnlOb3JtYWxpemF0aW9uID0gbm9ybWFsaXplQXR0clZhbHVlKGF0dHJpYnV0ZXMsIGkpOwotICAgICAgICAgICAgfQotICAgICAgICB9IC8vIGZvciBhbGwgYXR0cmlidXRlcwotCi0gICAgfSAvLyBhZGREVEREZWZhdWx0QXR0cnNBbmRWYWxpZGF0ZShpbnQsWE1MQXR0ckxpc3QpCi0KLQotICAgIC8qKgotICAgICAqIE5vcm1hbGl6ZSB0aGUgYXR0cmlidXRlIHZhbHVlIG9mIGEgbm9uIENEQVRBIGF0dHJpYnV0ZXMgY29sbGFwc2luZwotICAgICAqIHNlcXVlbmNlcyBvZiBzcGFjZSBjaGFyYWN0ZXJzICh4MjApCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYXR0cmlidXRlcyBUaGUgbGlzdCBvZiBhdHRyaWJ1dGVzCi0gICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgYXR0cmlidXRlIHRvIG5vcm1hbGl6ZQotICAgICAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBub3JtYWxpemVBdHRyVmFsdWUoWE1MQXR0cmlidXRlcyBhdHRyaWJ1dGVzLCBpbnQgaW5kZXgpIHsKLSAgICAgICAgLy8gdmFycwotICAgICAgICBib29sZWFuIGxlYWRpbmdTcGFjZSA9IHRydWU7Ci0gICAgICAgIGJvb2xlYW4gc3BhY2VTdGFydCA9IGZhbHNlOwotICAgICAgICBib29sZWFuIHJlYWRpbmdOb25TcGFjZSA9IGZhbHNlOwotICAgICAgICBpbnQgY291bnQgPSAwOwotICAgICAgICBpbnQgZWF0ZW4gPSAwOwotICAgICAgICBTdHJpbmcgYXR0clZhbHVlID0gYXR0cmlidXRlcy5nZXRWYWx1ZShpbmRleCk7Ci0gICAgICAgIGNoYXJbXSBhdHRWYWx1ZSA9IG5ldyBjaGFyW2F0dHJWYWx1ZS5sZW5ndGgoKV07Ci0KLSAgICAgICAgZkJ1ZmZlci5zZXRMZW5ndGgoMCk7Ci0gICAgICAgIGF0dHJWYWx1ZS5nZXRDaGFycygwLCBhdHRyVmFsdWUubGVuZ3RoKCksIGF0dFZhbHVlLCAwKTsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhdHRWYWx1ZS5sZW5ndGg7IGkrKykgewotCi0gICAgICAgICAgICBpZiAoYXR0VmFsdWVbaV0gPT0gJyAnKSB7Ci0KLSAgICAgICAgICAgICAgICAvLyBub3cgdGhlIHRyaWNreSBwYXJ0Ci0gICAgICAgICAgICAgICAgaWYgKHJlYWRpbmdOb25TcGFjZSkgewotICAgICAgICAgICAgICAgICAgICBzcGFjZVN0YXJ0ID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgcmVhZGluZ05vblNwYWNlID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgaWYgKHNwYWNlU3RhcnQgJiYgIWxlYWRpbmdTcGFjZSkgewotICAgICAgICAgICAgICAgICAgICBzcGFjZVN0YXJ0ID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgICAgIGZCdWZmZXIuYXBwZW5kKGF0dFZhbHVlW2ldKTsKLSAgICAgICAgICAgICAgICAgICAgY291bnQrKzsKLSAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICBpZiAobGVhZGluZ1NwYWNlIHx8ICFzcGFjZVN0YXJ0KSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBlYXRlbisrOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIHJlYWRpbmdOb25TcGFjZSA9IHRydWU7Ci0gICAgICAgICAgICAgICAgc3BhY2VTdGFydCA9IGZhbHNlOwotICAgICAgICAgICAgICAgIGxlYWRpbmdTcGFjZSA9IGZhbHNlOwotICAgICAgICAgICAgICAgIGZCdWZmZXIuYXBwZW5kKGF0dFZhbHVlW2ldKTsKLSAgICAgICAgICAgICAgICBjb3VudCsrOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gY2hlY2sgaWYgdGhlIGxhc3QgYXBwZW5kZWQgY2hhcmFjdGVyIGlzIGEgc3BhY2UuCi0gICAgICAgIGlmIChjb3VudCA+IDAgJiYgZkJ1ZmZlci5jaGFyQXQoY291bnQgLSAxKSA9PSAnICcpIHsKLSAgICAgICAgICAgIGZCdWZmZXIuc2V0TGVuZ3RoKGNvdW50IC0gMSk7Ci0KLSAgICAgICAgfQotICAgICAgICBTdHJpbmcgbmV3VmFsdWUgPSBmQnVmZmVyLnRvU3RyaW5nKCk7Ci0gICAgICAgIGF0dHJpYnV0ZXMuc2V0VmFsdWUoaW5kZXgsIG5ld1ZhbHVlKTsKLSAgICAgICAgcmV0dXJuICFhdHRyVmFsdWUuZXF1YWxzKG5ld1ZhbHVlKTsKLSAgICB9Ci0KLQotCi0gICAgLyoqIGNvbnZlcnQgYXR0cmlidXRlIHR5cGUgZnJvbSBpbnRzIHRvIHN0cmluZ3MgKi8KLSAgICBwcml2YXRlIFN0cmluZyBnZXRBdHRyaWJ1dGVUeXBlTmFtZShYTUxBdHRyaWJ1dGVEZWNsIGF0dHJEZWNsKSB7Ci0KLSAgICAgICAgc3dpdGNoIChhdHRyRGVjbC5zaW1wbGVUeXBlLnR5cGUpIHsKLSAgICAgICAgICAgIGNhc2UgWE1MU2ltcGxlVHlwZS5UWVBFX0VOVElUWTogewotICAgICAgICAgICAgICAgIHJldHVybiBhdHRyRGVjbC5zaW1wbGVUeXBlLmxpc3QgPyBYTUxTeW1ib2xzLmZFTlRJVElFU1N5bWJvbCA6Ci0gICAgICAgICAgICAgICAgICAgIFhNTFN5bWJvbHMuZkVOVElUWVN5bWJvbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhc2UgWE1MU2ltcGxlVHlwZS5UWVBFX0VOVU1FUkFUSU9OOiB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nQnVmZmVyIGJ1ZmZlciA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLSAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCcoJyk7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhdHRyRGVjbC5zaW1wbGVUeXBlLmVudW1lcmF0aW9uLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChpID4gMCkgewotICAgICAgICAgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgifCIpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoYXR0ckRlY2wuc2ltcGxlVHlwZS5lbnVtZXJhdGlvbltpXSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoJyknKTsKLSAgICAgICAgICAgICAgICByZXR1cm4gZlN5bWJvbFRhYmxlLmFkZFN5bWJvbChidWZmZXIudG9TdHJpbmcoKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXNlIFhNTFNpbXBsZVR5cGUuVFlQRV9JRDogewotICAgICAgICAgICAgICAgIHJldHVybiBYTUxTeW1ib2xzLmZJRFN5bWJvbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhc2UgWE1MU2ltcGxlVHlwZS5UWVBFX0lEUkVGOiB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGF0dHJEZWNsLnNpbXBsZVR5cGUubGlzdCA/IFhNTFN5bWJvbHMuZklEUkVGU1N5bWJvbCA6Ci0gICAgICAgICAgICAgICAgICAgIFhNTFN5bWJvbHMuZklEUkVGU3ltYm9sOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2FzZSBYTUxTaW1wbGVUeXBlLlRZUEVfTk1UT0tFTjogewotICAgICAgICAgICAgICAgIHJldHVybiBhdHRyRGVjbC5zaW1wbGVUeXBlLmxpc3QgPyBYTUxTeW1ib2xzLmZOTVRPS0VOU1N5bWJvbCA6Ci0gICAgICAgICAgICAgICAgICAgIFhNTFN5bWJvbHMuZk5NVE9LRU5TeW1ib2w7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXNlIFhNTFNpbXBsZVR5cGUuVFlQRV9OT1RBVElPTjogewotICAgICAgICAgICAgICAgIHJldHVybiBYTUxTeW1ib2xzLmZOT1RBVElPTlN5bWJvbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gWE1MU3ltYm9scy5mQ0RBVEFTeW1ib2w7Ci0KLSAgICB9Ci0KLQotICAgIC8qKiBlbnN1cmUgZWxlbWVudCBzdGFjayBjYXBhY2l0eSAqLwotICAgIHByaXZhdGUgdm9pZCBlbnN1cmVTdGFja0NhcGFjaXR5KGludCBuZXdFbGVtZW50RGVwdGgpIHsKLSAgICAgICAgaWYgKG5ld0VsZW1lbnREZXB0aCA9PSBmRWxlbWVudENvbnRlbnRTdGF0ZS5sZW5ndGgpIHsKLSAgICAgICAgICAgIGJvb2xlYW5bXSBuZXdTdGFjayA9IG5ldyBib29sZWFuW25ld0VsZW1lbnREZXB0aCAqIDJdOwotICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weSh0aGlzLmZFbGVtZW50Q29udGVudFN0YXRlLCAwLCBuZXdTdGFjaywgMCwKLSAgICAgICAgICAgICAgICAgICAgbmV3RWxlbWVudERlcHRoKTsKLSAgICAgICAgICAgIGZFbGVtZW50Q29udGVudFN0YXRlID0gbmV3U3RhY2s7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotCi0gICAgLyoqIEhhbmRsZSBlbGVtZW50Ci0gICAgICogQHJldHVybiB0cnVlIGlmIHZhbGlkYXRvciBpcyByZW1vdmVkIGZyb20gdGhlIHBpcGVsaW5lCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgaGFuZGxlU3RhcnRFbGVtZW50KFFOYW1lIGVsZW1lbnQsIFhNTEF0dHJpYnV0ZXMgYXR0cmlidXRlcykgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgaWYgKGZEVERHcmFtbWFyID09IG51bGwpIHsKLSAgICAgICAgICAgIGZDdXJyZW50RWxlbWVudEluZGV4ID0gLTE7Ci0gICAgICAgICAgICBmQ3VycmVudENvbnRlbnRTcGVjVHlwZSA9IC0xOwotICAgICAgICAgICAgZkluRWxlbWVudENvbnRlbnQgPSBmYWxzZTsKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIGZDdXJyZW50RWxlbWVudEluZGV4ID0gZkRUREdyYW1tYXIuZ2V0RWxlbWVudERlY2xJbmRleChlbGVtZW50KTsKLSAgICAgICAgICAgIGZDdXJyZW50Q29udGVudFNwZWNUeXBlID0gZkRUREdyYW1tYXIuZ2V0Q29udGVudFNwZWNUeXBlKAotICAgICAgICAgICAgICAgICAgICBmQ3VycmVudEVsZW1lbnRJbmRleCk7Ci0gICAgICAgICAgICAvL2hhbmRsZURURERlZmF1bHRBdHRycyhlbGVtZW50LGF0dHJpYnV0ZXMpOwotICAgICAgICAgICAgYWRkRFRERGVmYXVsdEF0dHJzKGVsZW1lbnQsIGF0dHJpYnV0ZXMpOwotICAgICAgICB9Ci0KLSAgICAgICAgZkluRWxlbWVudENvbnRlbnQgPSBmQ3VycmVudENvbnRlbnRTcGVjVHlwZSA9PSBYTUxFbGVtZW50RGVjbC5UWVBFX0NISUxEUkVOOwotICAgICAgICBmRWxlbWVudERlcHRoKys7Ci0gICAgICAgIGVuc3VyZVN0YWNrQ2FwYWNpdHkoZkVsZW1lbnREZXB0aCk7Ci0gICAgICAgIGZFbGVtZW50Q29udGVudFN0YXRlW2ZFbGVtZW50RGVwdGhdID0gZkluRWxlbWVudENvbnRlbnQ7Ci0gICAgfQotCi0KLSAgICAvKiogSGFuZGxlIGVuZCBlbGVtZW50LiAqLwotICAgIHByb3RlY3RlZCB2b2lkIGhhbmRsZUVuZEVsZW1lbnQoUU5hbWUgZWxlbWVudCkgdGhyb3dzIFhOSUV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChmRFRER3JhbW1hciA9PSBudWxsKSByZXR1cm47Ci0gICAgICAgIGZFbGVtZW50RGVwdGgtLTsKLSAgICAgICAgaWYgKGZFbGVtZW50RGVwdGggPCAtMSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIkZXSzAwOCBFbGVtZW50IHN0YWNrIHVuZGVyZmxvdyIpOwotICAgICAgICB9Ci0gICAgICAgIGlmIChmRWxlbWVudERlcHRoIDwgMCkgewotICAgICAgICAgICAgZkN1cnJlbnRFbGVtZW50SW5kZXggPSAtMTsKLSAgICAgICAgICAgIGZDdXJyZW50Q29udGVudFNwZWNUeXBlID0gLTE7Ci0gICAgICAgICAgICBmSW5FbGVtZW50Q29udGVudCA9IGZhbHNlOwotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0gICAgICAgIGZJbkVsZW1lbnRDb250ZW50ID0gIGZFbGVtZW50Q29udGVudFN0YXRlW2ZFbGVtZW50RGVwdGhdOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGlzSW5FbGVtZW50Q29udGVudCgpIHsKLSAgICAgICAgcmV0dXJuIGZJbkVsZW1lbnRDb250ZW50OwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGlzSWdub3JhYmxlV2hpdGVTcGFjZShYTUxTdHJpbmcgdGV4dCkgewotICAgICAgICBpZiAoaXNJbkVsZW1lbnRDb250ZW50KCkpIHsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSB0ZXh0Lm9mZnNldDsgaSA8IHRleHQub2Zmc2V0ICsgdGV4dC5sZW5ndGg7IGkrKykgewotICAgICAgICAgICAgICAgIGlmICghWE1MQ2hhci5pc1NwYWNlKHRleHQuY2hbaV0pKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4veG1sL2ludGVybmFsL3N0cmVhbS9kdGQvbm9udmFsaWRhdGluZy9EVERHcmFtbWFyLmphdmEgYi9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL2R0ZC9ub252YWxpZGF0aW5nL0RUREdyYW1tYXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYTM4OTczNS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL2R0ZC9ub252YWxpZGF0aW5nL0RUREdyYW1tYXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDg3OCArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDE1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICovCi0vKgotICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCi0gKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKLSAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KLSAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCi0gKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAotICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLnhtbC5pbnRlcm5hbC5zdHJlYW0uZHRkLm5vbnZhbGlkYXRpbmc7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuU3ltYm9sVGFibGU7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLlhNTFN5bWJvbHM7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuQXVnbWVudGF0aW9uczsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5RTmFtZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxMb2NhdG9yOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlhNTFJlc291cmNlSWRlbnRpZmllcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5YTUxTdHJpbmc7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE5JRXhjZXB0aW9uOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLnBhcnNlci5YTUxEVERDb250ZW50TW9kZWxTb3VyY2U7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTERURFNvdXJjZTsKLWltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwotaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwotaW1wb3J0IGphdmEudXRpbC5MaXN0OwotaW1wb3J0IGphdmEudXRpbC5NYXA7Ci0KLS8qKgotICogQSBEVEQgZ3JhbW1hci4gVGhpcyBjbGFzcyBpbXBsZW1lbnRzIHRoZSBYTkkgaGFuZGxlciBpbnRlcmZhY2VzCi0gKiBmb3IgRFREIGluZm9ybWF0aW9uIHNvIHRoYXQgaXQgY2FuIGJ1aWxkIHRoZSBhcHByb3ByYXRlIHZhbGlkYXRpb24KLSAqIHN0cnVjdHVyZXMgYXV0b21hdGljYWxseSBmcm9tIHRoZSBjYWxsYmFja3MuCi0gKgotICogQGF1dGhvciBFcmljIFllLCBJQk0KLSAqIEBhdXRob3IgSmVmZnJleSBSb2RyaWd1ZXosIElCTQotICogQGF1dGhvciBBbmR5IENsYXJrLCBJQk0KLSAqIEBhdXRob3IgTmVpbCBHcmFoYW0sIElCTQotICoKLSAqLwotcHVibGljIGNsYXNzIERUREdyYW1tYXIgewotCi0KLSAgICAvKiogVG9wIGxldmVsIHNjb3BlICgtMSkuICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVE9QX0xFVkVMX1NDT1BFID0gLTE7Ci0KLSAgICAvLyBwcml2YXRlCi0KLSAgICAvKiogQ2h1bmsgc2hpZnQgKDgpLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBDSFVOS19TSElGVCA9IDg7IC8vIDJeOCA9IDI1NgotCi0gICAgLyoqIENodW5rIHNpemUgKDEgPDwgQ0hVTktfU0hJRlQpLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBDSFVOS19TSVpFID0gKDEgPDwgQ0hVTktfU0hJRlQpOwotCi0gICAgLyoqIENodW5rIG1hc2sgKENIVU5LX1NJWkUgLSAxKS4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQ0hVTktfTUFTSyA9IENIVU5LX1NJWkUgLSAxOwotCi0gICAgLyoqIEluaXRpYWwgY2h1bmsgY291bnQgKDEgPDwgKDEwIC0gQ0hVTktfU0hJRlQpKS4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgSU5JVElBTF9DSFVOS19DT1VOVCA9ICgxIDw8ICgxMCAtIENIVU5LX1NISUZUKSk7IC8vIDJeMTAgPSAxawotCi0gICAgLyoqIExpc3QgZmxhZyAoMHg4MCkuICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgc2hvcnQgTElTVF9GTEFHID0gMHg4MDsKLQotICAgIC8qKiBMaXN0IG1hc2sgKH5MSVNUX0ZMQUcpLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHNob3J0IExJU1RfTUFTSyA9IH5MSVNUX0ZMQUc7Ci0KLSAgICAvLyBkZWJ1Z2dpbmcKLQotICAgIC8qKiBEZWJ1ZyBEVERHcmFtbWFyLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW4gREVCVUcgPSBmYWxzZTsKLQotICAgIC8vCi0gICAgLy8gRGF0YQotICAgIC8vCi0KLSAgICBwcm90ZWN0ZWQgWE1MRFREU291cmNlIGZEVERTb3VyY2UgPSBudWxsOwotICAgIHByb3RlY3RlZCBYTUxEVERDb250ZW50TW9kZWxTb3VyY2UgZkRURENvbnRlbnRNb2RlbFNvdXJjZSA9IG51bGw7Ci0KLSAgICAvKiogQ3VycmVudCBlbGVtZW50IGluZGV4LiAqLwotICAgIHByb3RlY3RlZCBpbnQgZkN1cnJlbnRFbGVtZW50SW5kZXg7Ci0KLSAgICAvKiogQ3VycmVudCBhdHRyaWJ1dGUgaW5kZXguICovCi0gICAgcHJvdGVjdGVkIGludCBmQ3VycmVudEF0dHJpYnV0ZUluZGV4OwotCi0gICAgLyoqIGZSZWFkaW5nRXh0ZXJuYWxEVEQgKi8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBmUmVhZGluZ0V4dGVybmFsRFREID0gZmFsc2U7Ci0KLSAgICAvKiogU3ltYm9sIHRhYmxlLiAqLwotICAgIHByaXZhdGUgU3ltYm9sVGFibGUgZlN5bWJvbFRhYmxlOwotICAgIHByaXZhdGUgQXJyYXlMaXN0IG5vdGF0aW9uRGVjbHMgPSBuZXcgQXJyYXlMaXN0KCk7Ci0KLSAgICAvLyBlbGVtZW50IGRlY2xhcmF0aW9ucwotCi0gICAgLyoqIE51bWJlciBvZiBlbGVtZW50IGRlY2xhcmF0aW9ucy4gKi8KLSAgICBwcml2YXRlIGludCBmRWxlbWVudERlY2xDb3VudCA9IDA7Ci0KLSAgICAvKiogRWxlbWVudCBkZWNsYXJhdGlvbiBuYW1lLiAqLwotICAgIHByaXZhdGUgUU5hbWUgZkVsZW1lbnREZWNsTmFtZVtdW10gPSBuZXcgUU5hbWVbSU5JVElBTF9DSFVOS19DT1VOVF1bXTsKLQotICAgIC8qKgotICAgICAqIEVsZW1lbnQgZGVjbGFyYXRpb24gdHlwZS4KLSAgICAgKiBAc2VlIFhNTEVsZW1lbnREZWNsCi0gICAgICovCi0gICAgcHJpdmF0ZSBzaG9ydCBmRWxlbWVudERlY2xUeXBlW11bXSA9IG5ldyBzaG9ydFtJTklUSUFMX0NIVU5LX0NPVU5UXVtdOwotCi0KLSAgICAvKiogRmlyc3QgYXR0cmlidXRlIGRlY2xhcmF0aW9uIG9mIGFuIGVsZW1lbnQgZGVjbGFyYXRpb24uICovCi0gICAgcHJpdmF0ZSBpbnQgZkVsZW1lbnREZWNsRmlyc3RBdHRyaWJ1dGVEZWNsSW5kZXhbXVtdID0gbmV3IGludFtJTklUSUFMX0NIVU5LX0NPVU5UXVtdOwotCi0gICAgLyoqIExhc3QgYXR0cmlidXRlIGRlY2xhcmF0aW9uIG9mIGFuIGVsZW1lbnQgZGVjbGFyYXRpb24uICovCi0gICAgcHJpdmF0ZSBpbnQgZkVsZW1lbnREZWNsTGFzdEF0dHJpYnV0ZURlY2xJbmRleFtdW10gPSBuZXcgaW50W0lOSVRJQUxfQ0hVTktfQ09VTlRdW107Ci0KLSAgICAvLyBhdHRyaWJ1dGUgZGVjbGFyYXRpb25zCi0KLSAgICAvKiogTnVtYmVyIG9mIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbnMuICovCi0gICAgcHJpdmF0ZSBpbnQgZkF0dHJpYnV0ZURlY2xDb3VudCA9IDAgOwotCi0gICAgLyoqIEF0dHJpYnV0ZSBkZWNsYXJhdGlvbiBuYW1lLiAqLwotICAgIHByaXZhdGUgUU5hbWUgZkF0dHJpYnV0ZURlY2xOYW1lW11bXSA9IG5ldyBRTmFtZVtJTklUSUFMX0NIVU5LX0NPVU5UXVtdOwotCi0gICAgLyoqCi0gICAgICogQXR0cmlidXRlIGRlY2xhcmF0aW9uIHR5cGUuCi0gICAgICogQHNlZSBYTUxBdHRyaWJ1dGVEZWNsCi0gICAgICovCi0gICAgcHJpdmF0ZSBzaG9ydCBmQXR0cmlidXRlRGVjbFR5cGVbXVtdID0gbmV3IHNob3J0W0lOSVRJQUxfQ0hVTktfQ09VTlRdW107Ci0KLSAgICAvKiogQXR0cmlidXRlIGRlY2xhcmF0aW9uIGVudW1lcmF0aW9uIHZhbHVlcy4gKi8KLSAgICBwcml2YXRlIFN0cmluZ1tdIGZBdHRyaWJ1dGVEZWNsRW51bWVyYXRpb25bXVtdID0gbmV3IFN0cmluZ1tJTklUSUFMX0NIVU5LX0NPVU5UXVtdW107Ci0gICAgcHJpdmF0ZSBzaG9ydCBmQXR0cmlidXRlRGVjbERlZmF1bHRUeXBlW11bXSA9IG5ldyBzaG9ydFtJTklUSUFMX0NIVU5LX0NPVU5UXVtdOwotICAgIHByaXZhdGUgU3RyaW5nIGZBdHRyaWJ1dGVEZWNsRGVmYXVsdFZhbHVlW11bXSA9IG5ldyBTdHJpbmdbSU5JVElBTF9DSFVOS19DT1VOVF1bXTsKLSAgICBwcml2YXRlIFN0cmluZyBmQXR0cmlidXRlRGVjbE5vbk5vcm1hbGl6ZWREZWZhdWx0VmFsdWVbXVtdID0gbmV3IFN0cmluZ1tJTklUSUFMX0NIVU5LX0NPVU5UXVtdOwotICAgIHByaXZhdGUgaW50IGZBdHRyaWJ1dGVEZWNsTmV4dEF0dHJpYnV0ZURlY2xJbmRleFtdW10gPSBuZXcgaW50W0lOSVRJQUxfQ0hVTktfQ09VTlRdW107Ci0KLSAgICAvKiogRWxlbWVudCBpbmRleCBtYXBwaW5nIHRhYmxlLiAqLwotICAgIHByaXZhdGUgZmluYWwgTWFwPFN0cmluZywgSW50ZWdlcj4gZkVsZW1lbnRJbmRleE1hcCA9IG5ldyBIYXNoTWFwPD4oKTsKLQotICAgIC8qKiBUZW1wb3JhcnkgcXVhbGlmaWVkIG5hbWUuICovCi0gICAgcHJpdmF0ZSBmaW5hbCBRTmFtZSBmUU5hbWUgPSBuZXcgUU5hbWUoKTsKLQotICAgIC8qKiBUZW1wb3JhcnkgQXR0cmlidXRlIGRlY2wuICovCi0gICAgcHJvdGVjdGVkIFhNTEF0dHJpYnV0ZURlY2wgZkF0dHJpYnV0ZURlY2wgPSBuZXcgWE1MQXR0cmlidXRlRGVjbCgpOwotCi0gICAgLyoqIEVsZW1lbnQgZGVjbGFyYXRpb24uICovCi0gICAgcHJpdmF0ZSBYTUxFbGVtZW50RGVjbCBmRWxlbWVudERlY2wgPSBuZXcgWE1MRWxlbWVudERlY2woKTsKLQotICAgIC8qKiBTaW1wbGUgdHlwZS4gKi8KLSAgICBwcml2YXRlIFhNTFNpbXBsZVR5cGUgZlNpbXBsZVR5cGUgPSBuZXcgWE1MU2ltcGxlVHlwZSgpOwotCi0KLSAgICAvKiogdGFibGUgb2YgWE1MRWxlbWVudERlY2wgICAqLwotICAgIE1hcDxTdHJpbmcsIFhNTEVsZW1lbnREZWNsPiBmRWxlbWVudERlY2xUYWIgPSBuZXcgSGFzaE1hcDw+KCk7Ci0KLSAgICAvKiogRGVmYXVsdCBjb25zdHJ1Y3Rvci4gKi8KLSAgICBwdWJsaWMgRFRER3JhbW1hcihTeW1ib2xUYWJsZSBzeW1ib2xUYWJsZSkgewotICAgICAgICBmU3ltYm9sVGFibGUgPSBzeW1ib2xUYWJsZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldEF0dHJpYnV0ZURlY2xJbmRleChpbnQgZWxlbWVudERlY2xJbmRleCwgU3RyaW5nIGF0dHJpYnV0ZURlY2xOYW1lKSB7Ci0gICAgICAgIGlmIChlbGVtZW50RGVjbEluZGV4ID09IC0xKSB7Ci0gICAgICAgICAgICByZXR1cm4gLTE7Ci0gICAgICAgIH0KLSAgICAgICAgaW50IGF0dERlZkluZGV4ID0gZ2V0Rmlyc3RBdHRyaWJ1dGVEZWNsSW5kZXgoZWxlbWVudERlY2xJbmRleCk7Ci0gICAgICAgIHdoaWxlIChhdHREZWZJbmRleCAhPSAtMSkgewotICAgICAgICAgICAgZ2V0QXR0cmlidXRlRGVjbChhdHREZWZJbmRleCwgZkF0dHJpYnV0ZURlY2wpOwotCi0gICAgICAgICAgICBpZiAoZkF0dHJpYnV0ZURlY2wubmFtZS5yYXduYW1lID09IGF0dHJpYnV0ZURlY2xOYW1lCi0gICAgICAgICAgICB8fCBhdHRyaWJ1dGVEZWNsTmFtZS5lcXVhbHMoZkF0dHJpYnV0ZURlY2wubmFtZS5yYXduYW1lKSApIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gYXR0RGVmSW5kZXg7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBhdHREZWZJbmRleCA9IGdldE5leHRBdHRyaWJ1dGVEZWNsSW5kZXgoYXR0RGVmSW5kZXgpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiAtMTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgc3RhcnQgb2YgdGhlIERURC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBsb2NhdG9yICBUaGUgZG9jdW1lbnQgbG9jYXRvciwgb3IgbnVsbCBpZiB0aGUgZG9jdW1lbnQKLSAgICAgKiAgICAgICAgICAgICAgICAgbG9jYXRpb24gY2Fubm90IGJlIHJlcG9ydGVkIGR1cmluZyB0aGUgcGFyc2luZyBvZgotICAgICAqICAgICAgICAgICAgICAgICB0aGUgZG9jdW1lbnQgRFRELiBIb3dldmVyLCBpdCBpcyA8ZW0+c3Ryb25nbHk8L2VtPgotICAgICAqICAgICAgICAgICAgICAgICByZWNvbW1lbmRlZCB0aGF0IGEgbG9jYXRvciBiZSBzdXBwbGllZCB0aGF0IGNhbgotICAgICAqICAgICAgICAgICAgICAgICBhdCBsZWFzdCByZXBvcnQgdGhlIGJhc2Ugc3lzdGVtIGlkZW50aWZpZXIgb2YgdGhlCi0gICAgICogICAgICAgICAgICAgICAgIERURC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBhdWdzIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGhhdCBtYXkgaW5jbHVkZSBpbmZvc2V0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXVnbWVudGF0aW9ucy4KLSAgICAgKiBAdGhyb3dzIFhOSUV4Y2VwdGlvbiBUaHJvd24gYnkgaGFuZGxlciB0byBzaWduYWwgYW4gZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnREVEQoWE1MTG9jYXRvciBsb2NhdG9yLCBBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotICAgIH0gLy8gc3RhcnREVEQoWE1MTG9jYXRvcikKLQotICAgIC8vIHN0YXJ0RXh0ZXJuYWxTdWJzZXQoQXVnbWVudGF0aW9ucykKLQotICAgIC8vIGVuZEV4dGVybmFsU3Vic2V0KEF1Z21lbnRhdGlvbnMpCi0KLSAgICAvKioKLSAgICAgKiBBbiBlbGVtZW50IGRlY2xhcmF0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgICAgICAgICBUaGUgbmFtZSBvZiB0aGUgZWxlbWVudC4KLSAgICAgKiBAcGFyYW0gY29udGVudE1vZGVsIFRoZSBlbGVtZW50IGNvbnRlbnQgbW9kZWwuCi0gICAgICogQHBhcmFtIGF1Z3MgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbGVtZW50RGVjbChTdHJpbmcgbmFtZSwgU3RyaW5nIGNvbnRlbnRNb2RlbCwgQXVnbWVudGF0aW9ucyBhdWdzKQotICAgIHRocm93cyBYTklFeGNlcHRpb24gewotCi0gICAgICAgIFhNTEVsZW1lbnREZWNsIHRtcEVsZW1lbnREZWNsID0gZkVsZW1lbnREZWNsVGFiLmdldChuYW1lKSA7Ci0gICAgICAgIGlmICggdG1wRWxlbWVudERlY2wgIT0gbnVsbCApIHsKLSAgICAgICAgICAgIGlmICh0bXBFbGVtZW50RGVjbC50eXBlID09IC0xKSB7Ci0gICAgICAgICAgICAgICAgZkN1cnJlbnRFbGVtZW50SW5kZXggPSBnZXRFbGVtZW50RGVjbEluZGV4KG5hbWUpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgLy8gZHVwbGljYXRlIGVsZW1lbnQsIGlnbm9yZWQuCi0gICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgZkN1cnJlbnRFbGVtZW50SW5kZXggPSBjcmVhdGVFbGVtZW50RGVjbCgpOy8vY3JlYXRlIGVsZW1lbnQgZGVjbAotICAgICAgICB9Ci0KLSAgICAgICAgWE1MRWxlbWVudERlY2wgZWxlbWVudERlY2wgICAgICAgPSBuZXcgWE1MRWxlbWVudERlY2woKTsKLSAgICAgICAgUU5hbWUgICAgICAgICAgZWxlbWVudE5hbWUgICAgICAgPSBuZXcgUU5hbWUobnVsbCwgbmFtZSwgbmFtZSwgbnVsbCk7Ci0KLSAgICAgICAgZWxlbWVudERlY2wubmFtZS5zZXRWYWx1ZXMoZWxlbWVudE5hbWUpOwotICAgICAgICBlbGVtZW50RGVjbC5zY29wZT0gLTE7Ci0gICAgICAgIGlmIChjb250ZW50TW9kZWwuZXF1YWxzKCJFTVBUWSIpKSB7Ci0gICAgICAgICAgICBlbGVtZW50RGVjbC50eXBlID0gWE1MRWxlbWVudERlY2wuVFlQRV9FTVBUWTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChjb250ZW50TW9kZWwuZXF1YWxzKCJBTlkiKSkgewotICAgICAgICAgICAgZWxlbWVudERlY2wudHlwZSA9IFhNTEVsZW1lbnREZWNsLlRZUEVfQU5ZOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKGNvbnRlbnRNb2RlbC5zdGFydHNXaXRoKCIoIikgKSB7Ci0gICAgICAgICAgICBpZiAoY29udGVudE1vZGVsLmluZGV4T2YoIiNQQ0RBVEEiKSA+IDAgKSB7Ci0gICAgICAgICAgICAgICAgZWxlbWVudERlY2wudHlwZSA9IFhNTEVsZW1lbnREZWNsLlRZUEVfTUlYRUQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBlbGVtZW50RGVjbC50eXBlID0gWE1MRWxlbWVudERlY2wuVFlQRV9DSElMRFJFTjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0KLSAgICAgICAgLy9hZGQob3Igc2V0KSB0aGlzIGVsZW1lbnREZWNsIHRvIHRoZSBsb2NhbCBjYWNoZQotICAgICAgICB0aGlzLmZFbGVtZW50RGVjbFRhYi5wdXQobmFtZSwgZWxlbWVudERlY2wgKTsKLQotICAgICAgICBmRWxlbWVudERlY2wgPSBlbGVtZW50RGVjbDsKLQotCi0gICAgICAgIGlmICggREVCVUcgKSB7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oICAibmFtZSA9ICIgKyBmRWxlbWVudERlY2wubmFtZS5sb2NhbHBhcnQgKTsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbiggICJUeXBlID0gIiArIGZFbGVtZW50RGVjbC50eXBlICk7Ci0gICAgICAgIH0KLQotICAgICAgICBzZXRFbGVtZW50RGVjbChmQ3VycmVudEVsZW1lbnRJbmRleCwgZkVsZW1lbnREZWNsICk7Ly9zZXQgaW50ZXJuYWwgc3RydWN0dXJlCi0KLSAgICAgICAgaW50IGNodW5rID0gZkN1cnJlbnRFbGVtZW50SW5kZXggPj4gQ0hVTktfU0hJRlQ7Ci0gICAgICAgIGVuc3VyZUVsZW1lbnREZWNsQ2FwYWNpdHkoY2h1bmspOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEFuIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlbGVtZW50TmFtZSAgIFRoZSBuYW1lIG9mIHRoZSBlbGVtZW50IHRoYXQgdGhpcyBhdHRyaWJ1dGUKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBpcyBhc3NvY2lhdGVkIHdpdGguCi0gICAgICogQHBhcmFtIGF0dHJpYnV0ZU5hbWUgVGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgKiBAcGFyYW0gdHlwZSAgICAgICAgICBUaGUgYXR0cmlidXRlIHR5cGUuIFRoaXMgdmFsdWUgd2lsbCBiZSBvbmUgb2YKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICB0aGUgZm9sbG93aW5nOiAiQ0RBVEEiLCAiRU5USVRZIiwgIkVOVElUSUVTIiwKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAiRU5VTUVSQVRJT04iLCAiSUQiLCAiSURSRUYiLCAiSURSRUZTIiwKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAiTk1UT0tFTiIsICJOTVRPS0VOUyIsIG9yICJOT1RBVElPTiIuCi0gICAgICogQHBhcmFtIGVudW1lcmF0aW9uICAgSWYgdGhlIHR5cGUgaGFzIHRoZSB2YWx1ZSAiRU5VTUVSQVRJT04iLCB0aGlzCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgYXJyYXkgaG9sZHMgdGhlIGFsbG93ZWQgYXR0cmlidXRlIHZhbHVlczsKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBvdGhlcndpc2UsIHRoaXMgYXJyYXkgaXMgbnVsbC4KLSAgICAgKiBAcGFyYW0gZGVmYXVsdFR5cGUgICBUaGUgYXR0cmlidXRlIGRlZmF1bHQgdHlwZS4gVGhpcyB2YWx1ZSB3aWxsIGJlCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgb25lIG9mIHRoZSBmb2xsb3dpbmc6ICIjRklYRUQiLCAiI0lNUExJRUQiLAotICAgICAqICAgICAgICAgICAgICAgICAgICAgICIjUkVRVUlSRUQiLCBvciBudWxsLgotICAgICAqIEBwYXJhbSBkZWZhdWx0VmFsdWUgIFRoZSBhdHRyaWJ1dGUgZGVmYXVsdCB2YWx1ZSwgb3IgbnVsbCBpZiBubwotICAgICAqICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQgdmFsdWUgaXMgc3BlY2lmaWVkLgotICAgICAqIEBwYXJhbSBub25Ob3JtYWxpemVkRGVmYXVsdFZhbHVlICBUaGUgYXR0cmlidXRlIGRlZmF1bHQgdmFsdWUgd2l0aCBubyBub3JtYWxpemF0aW9uCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgcGVyZm9ybWVkLCBvciBudWxsIGlmIG5vIGRlZmF1bHQgdmFsdWUgaXMgc3BlY2lmaWVkLgotICAgICAqCi0gICAgICogQHBhcmFtIGF1Z3MgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0aGF0IG1heSBpbmNsdWRlIGluZm9zZXQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhdWdtZW50YXRpb25zLgotICAgICAqIEB0aHJvd3MgWE5JRXhjZXB0aW9uIFRocm93biBieSBoYW5kbGVyIHRvIHNpZ25hbCBhbiBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBhdHRyaWJ1dGVEZWNsKFN0cmluZyBlbGVtZW50TmFtZSwgU3RyaW5nIGF0dHJpYnV0ZU5hbWUsCi0gICAgU3RyaW5nIHR5cGUsIFN0cmluZ1tdIGVudW1lcmF0aW9uLAotICAgIFN0cmluZyBkZWZhdWx0VHlwZSwgWE1MU3RyaW5nIGRlZmF1bHRWYWx1ZSwKLSAgICBYTUxTdHJpbmcgbm9uTm9ybWFsaXplZERlZmF1bHRWYWx1ZSwgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLQotICAgICAgICBpZiAodHlwZSAhPSBYTUxTeW1ib2xzLmZDREFUQVN5bWJvbCAmJiBkZWZhdWx0VmFsdWUgIT0gbnVsbCkgewotICAgICAgICAgICAgbm9ybWFsaXplRGVmYXVsdEF0dHJWYWx1ZShkZWZhdWx0VmFsdWUpOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKCB0aGlzLmZFbGVtZW50RGVjbFRhYi5jb250YWluc0tleShlbGVtZW50TmFtZSkpIHsKLSAgICAgICAgICAgIC8vaWYgRWxlbWVudERlY2wgaGFzIGFscmVhZHkgYmVpbmcgY3JlYXRlZCBpbiB0aGUgR3JhbW1hciB0aGVuIHJlbW92ZSBmcm9tIHRhYmxlLAotICAgICAgICAgICAgLy90aGlzLmZFbGVtZW50RGVjbFRhYi5yZW1vdmUoIChTdHJpbmcpIGVsZW1lbnROYW1lICk7Ci0gICAgICAgIH0KLSAgICAgICAgLy8gdGhlbiBpdCBpcyBmb3J3YXJkIHJlZmVyZW5jZSB0byBhIGVsZW1lbnQgZGVjbCwgY3JlYXRlIHRoZSBlbGVtZW50RGVjbCBmaXJzdC4KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICBmQ3VycmVudEVsZW1lbnRJbmRleCA9IGNyZWF0ZUVsZW1lbnREZWNsKCk7Ly9jcmVhdGUgZWxlbWVudCBkZWNsCi0KLSAgICAgICAgICAgIFhNTEVsZW1lbnREZWNsIGVsZW1lbnREZWNsICAgICAgID0gbmV3IFhNTEVsZW1lbnREZWNsKCk7Ci0gICAgICAgICAgICBlbGVtZW50RGVjbC5uYW1lLnNldFZhbHVlcyhudWxsLCBlbGVtZW50TmFtZSwgZWxlbWVudE5hbWUsIG51bGwpOwotCi0gICAgICAgICAgICBlbGVtZW50RGVjbC5zY29wZT0gLTE7Ci0KLSAgICAgICAgICAgIC8vYWRkKG9yIHNldCkgdGhpcyBlbGVtZW50RGVjbCB0byB0aGUgbG9jYWwgY2FjaGUKLSAgICAgICAgICAgIHRoaXMuZkVsZW1lbnREZWNsVGFiLnB1dChlbGVtZW50TmFtZSwgZWxlbWVudERlY2wgKTsKLQotICAgICAgICAgICAgLy9zZXQgaW50ZXJuYWwgc3RydWN0dXJlCi0gICAgICAgICAgICBzZXRFbGVtZW50RGVjbChmQ3VycmVudEVsZW1lbnRJbmRleCwgZWxlbWVudERlY2wgKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vR2V0IEdyYW1tYXIgaW5kZXggdG8gZ3JhbW1hciBhcnJheQotICAgICAgICBpbnQgZWxlbWVudEluZGV4ICAgICAgID0gZ2V0RWxlbWVudERlY2xJbmRleChlbGVtZW50TmFtZSk7Ci0KLSAgICAgICAgLy9yZXR1cm4sIHdoZW4gbW9yZSB0aGFuIG9uZSBkZWZpbml0aW9uIGlzIHByb3ZpZGVkIGZvciB0aGUgc2FtZSBhdHRyaWJ1dGUgb2YgZ2l2ZW4gZWxlbWVudCB0eXBlCi0gICAgICAgIC8vb25seSB0aGUgZmlyc3QgZGVjbGFyYXRpb24gaXMgYmluZGluZyBhbmQgbGF0ZXIgZGVjbGFyYXRpb25zIGFyZSBpZ25vcmVkCi0gICAgICAgIGlmIChnZXRBdHRyaWJ1dGVEZWNsSW5kZXgoZWxlbWVudEluZGV4LCBhdHRyaWJ1dGVOYW1lKSAhPSAtMSkgewotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0KLSAgICAgICAgZkN1cnJlbnRBdHRyaWJ1dGVJbmRleCA9IGNyZWF0ZUF0dHJpYnV0ZURlY2woKTsvLyBDcmVhdGUgY3VycmVudCBBdHRyaWJ1dGUgRGVjbAotCi0gICAgICAgIGZTaW1wbGVUeXBlLmNsZWFyKCk7Ci0gICAgICAgIGlmICggZGVmYXVsdFR5cGUgIT0gbnVsbCApIHsKLSAgICAgICAgICAgIGlmICggZGVmYXVsdFR5cGUuZXF1YWxzKCAiI0ZJWEVEIikgKSB7Ci0gICAgICAgICAgICAgICAgZlNpbXBsZVR5cGUuZGVmYXVsdFR5cGUgPSBmU2ltcGxlVHlwZS5ERUZBVUxUX1RZUEVfRklYRUQ7Ci0gICAgICAgICAgICB9IGVsc2UgaWYgKCBkZWZhdWx0VHlwZS5lcXVhbHMoICIjSU1QTElFRCIpICkgewotICAgICAgICAgICAgICAgIGZTaW1wbGVUeXBlLmRlZmF1bHRUeXBlID0gZlNpbXBsZVR5cGUuREVGQVVMVF9UWVBFX0lNUExJRUQ7Ci0gICAgICAgICAgICB9IGVsc2UgaWYgKCBkZWZhdWx0VHlwZS5lcXVhbHMoICIjUkVRVUlSRUQiKSApIHsKLSAgICAgICAgICAgICAgICBmU2ltcGxlVHlwZS5kZWZhdWx0VHlwZSA9IGZTaW1wbGVUeXBlLkRFRkFVTFRfVFlQRV9SRVFVSVJFRDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBpZiAoIERFQlVHICkgewotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJkZWZhdWx0dmFsdWUgPSAiICsgZGVmYXVsdFZhbHVlLnRvU3RyaW5nKCkgKTsKLSAgICAgICAgfQotICAgICAgICBmU2ltcGxlVHlwZS5kZWZhdWx0VmFsdWUgICAgICA9IGRlZmF1bHRWYWx1ZSE9bnVsbCA/ICBkZWZhdWx0VmFsdWUudG9TdHJpbmcoKSA6IG51bGw7Ci0gICAgICAgIGZTaW1wbGVUeXBlLm5vbk5vcm1hbGl6ZWREZWZhdWx0VmFsdWUgICAgICA9IG5vbk5vcm1hbGl6ZWREZWZhdWx0VmFsdWUhPW51bGwgPyAgbm9uTm9ybWFsaXplZERlZmF1bHRWYWx1ZS50b1N0cmluZygpIDogbnVsbDsKLSAgICAgICAgZlNpbXBsZVR5cGUuZW51bWVyYXRpb24gICAgICAgPSBlbnVtZXJhdGlvbjsKLQotICAgICAgICBpZiAodHlwZS5lcXVhbHMoIkNEQVRBIikpIHsKLSAgICAgICAgICAgIGZTaW1wbGVUeXBlLnR5cGUgPSBYTUxTaW1wbGVUeXBlLlRZUEVfQ0RBVEE7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoIHR5cGUuZXF1YWxzKCJJRCIpICkgewotICAgICAgICAgICAgZlNpbXBsZVR5cGUudHlwZSA9IFhNTFNpbXBsZVR5cGUuVFlQRV9JRDsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICggdHlwZS5zdGFydHNXaXRoKCJJRFJFRiIpICkgewotICAgICAgICAgICAgZlNpbXBsZVR5cGUudHlwZSA9IFhNTFNpbXBsZVR5cGUuVFlQRV9JRFJFRjsKLSAgICAgICAgICAgIGlmICh0eXBlLmluZGV4T2YoIlMiKSA+IDApIHsKLSAgICAgICAgICAgICAgICBmU2ltcGxlVHlwZS5saXN0ID0gdHJ1ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICh0eXBlLmVxdWFscygiRU5USVRJRVMiKSkgewotICAgICAgICAgICAgZlNpbXBsZVR5cGUudHlwZSA9IFhNTFNpbXBsZVR5cGUuVFlQRV9FTlRJVFk7Ci0gICAgICAgICAgICBmU2ltcGxlVHlwZS5saXN0ID0gdHJ1ZTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICh0eXBlLmVxdWFscygiRU5USVRZIikpIHsKLSAgICAgICAgICAgIGZTaW1wbGVUeXBlLnR5cGUgPSBYTUxTaW1wbGVUeXBlLlRZUEVfRU5USVRZOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKHR5cGUuZXF1YWxzKCJOTVRPS0VOUyIpKSB7Ci0gICAgICAgICAgICBmU2ltcGxlVHlwZS50eXBlID0gWE1MU2ltcGxlVHlwZS5UWVBFX05NVE9LRU47Ci0gICAgICAgICAgICBmU2ltcGxlVHlwZS5saXN0ID0gdHJ1ZTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICh0eXBlLmVxdWFscygiTk1UT0tFTiIpKSB7Ci0gICAgICAgICAgICBmU2ltcGxlVHlwZS50eXBlID0gWE1MU2ltcGxlVHlwZS5UWVBFX05NVE9LRU47Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAodHlwZS5zdGFydHNXaXRoKCJOT1RBVElPTiIpICkgewotICAgICAgICAgICAgZlNpbXBsZVR5cGUudHlwZSA9IFhNTFNpbXBsZVR5cGUuVFlQRV9OT1RBVElPTjsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICh0eXBlLnN0YXJ0c1dpdGgoIkVOVU1FUkFUSU9OIikgKSB7Ci0gICAgICAgICAgICBmU2ltcGxlVHlwZS50eXBlID0gWE1MU2ltcGxlVHlwZS5UWVBFX0VOVU1FUkFUSU9OOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgLy8gUkVWSVNJVDogUmVwb3J0IGVycm9yIG1lc3NhZ2UuIC1BYwotICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCIhISEgdW5rbm93biBhdHRyaWJ1dGUgdHlwZSAiK3R5cGUpOwotICAgICAgICB9Ci0gICAgICAgIC8vIFJFVklTSVQ6IFRoZSBkYXRhdHlwZSBzaG91bGQgYmUgc3RvcmVkIHdpdGggdGhlIGF0dHJpYnV0ZSB2YWx1ZQotICAgICAgICAvLyAgICAgICAgICBhbmQgbm90IHNwZWNpYWwtY2FzZWQgaW4gdGhlIFhNTFZhbGlkYXRvci4gLUFjCi0gICAgICAgIC8vZlNpbXBsZVR5cGUuZGF0YXR5cGVWYWxpZGF0b3IgPSBmRGF0YXR5cGVWYWxpZGF0b3JGYWN0b3J5LmNyZWF0ZURhdGF0eXBlVmFsaWRhdG9yKHR5cGUsIG51bGwsIGZhY2V0cywgZlNpbXBsZVR5cGUubGlzdCk7Ci0KLSAgICAgICAgZlFOYW1lLnNldFZhbHVlcyhudWxsLCBhdHRyaWJ1dGVOYW1lLCBhdHRyaWJ1dGVOYW1lLCBudWxsKTsKLSAgICAgICAgZkF0dHJpYnV0ZURlY2wuc2V0VmFsdWVzKCBmUU5hbWUsIGZTaW1wbGVUeXBlLCBmYWxzZSApOwotCi0gICAgICAgIHNldEF0dHJpYnV0ZURlY2woZWxlbWVudEluZGV4LCBmQ3VycmVudEF0dHJpYnV0ZUluZGV4LCBmQXR0cmlidXRlRGVjbCk7Ci0KLSAgICAgICAgaW50IGNodW5rID0gZkN1cnJlbnRBdHRyaWJ1dGVJbmRleCA+PiBDSFVOS19TSElGVDsKLSAgICAgICAgZW5zdXJlQXR0cmlidXRlRGVjbENhcGFjaXR5KGNodW5rKTsKLSAgICB9IC8vIGF0dHJpYnV0ZURlY2woU3RyaW5nLFN0cmluZyxTdHJpbmcsU3RyaW5nW10sU3RyaW5nLFhNTFN0cmluZyxYTUxTdHJpbmcsIEF1Z21lbnRhdGlvbnMpCi0KLSAgICAvKiogUmV0dXJucyB0aGUgc3ltYm9sIHRhYmxlLiAqLwotICAgIHB1YmxpYyBTeW1ib2xUYWJsZSBnZXRTeW1ib2xUYWJsZSgpIHsKLSAgICAgICAgcmV0dXJuIGZTeW1ib2xUYWJsZTsKLSAgICB9IC8vIGdldFN5bWJvbFRhYmxlKCk6U3ltYm9sVGFibGUKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBlbGVtZW50IGRlY2xhcmF0aW9uLiBUaGlzIGluZGV4Ci0gICAgICogaXMgdGhlbiB1c2VkIHRvIHF1ZXJ5IG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGVsZW1lbnQgZGVjbGFyYXRpb24uCi0gICAgICoKLSAgICAgKiBAc2VlICNnZXROZXh0RWxlbWVudERlY2xJbmRleAotICAgICAqIEBzZWUgI2dldEVsZW1lbnREZWNsCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRGaXJzdEVsZW1lbnREZWNsSW5kZXgoKSB7Ci0gICAgICAgIHJldHVybiBmRWxlbWVudERlY2xDb3VudCA+PSAwID8gMCA6IC0xOwotICAgIH0gLy8gZ2V0Rmlyc3RFbGVtZW50RGVjbEluZGV4KCk6aW50Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBuZXh0IGluZGV4IG9mIHRoZSBlbGVtZW50IGRlY2xhcmF0aW9uIGZvbGxvd2luZyB0aGUKLSAgICAgKiBzcGVjaWZpZWQgZWxlbWVudCBkZWNsYXJhdGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlbGVtZW50RGVjbEluZGV4IFRoZSBlbGVtZW50IGRlY2xhcmF0aW9uIGluZGV4LgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0TmV4dEVsZW1lbnREZWNsSW5kZXgoaW50IGVsZW1lbnREZWNsSW5kZXgpIHsKLSAgICAgICAgcmV0dXJuIGVsZW1lbnREZWNsSW5kZXggPCBmRWxlbWVudERlY2xDb3VudCAtIDEKLSAgICAgICAgPyBlbGVtZW50RGVjbEluZGV4ICsgMSA6IC0xOwotICAgIH0gLy8gZ2V0TmV4dEVsZW1lbnREZWNsSW5kZXgoaW50KTppbnQKLQotICAgIC8qKgotICAgICAqIGdldEVsZW1lbnREZWNsSW5kZXgKLSAgICAgKgotICAgICAqIEBwYXJhbSBlbGVtZW50RGVjbE5hbWUKLSAgICAgKgotICAgICAqIEByZXR1cm4gaW5kZXggb2YgdGhlIGVsZW1lbnREZWNsTmFtZSBpbiBzY29wZQotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0RWxlbWVudERlY2xJbmRleChTdHJpbmcgZWxlbWVudERlY2xOYW1lKSB7Ci0gICAgICAgIEludGVnZXIgbWFwcGluZyA9IGZFbGVtZW50SW5kZXhNYXAuZ2V0KGVsZW1lbnREZWNsTmFtZSk7Ci0gICAgICAgIGlmIChtYXBwaW5nID09IG51bGwpIHsKLSAgICAgICAgICAgIG1hcHBpbmcgPSAtMTsKLSAgICAgICAgfQotICAgICAgICAvL1N5c3RlbS5vdXQucHJpbnRsbigiZ2V0RWxlbWVudERlY2xJbmRleCgiK2VsZW1lbnREZWNsTmFtZSsiKSAtPiAiK21hcHBpbmcpOwotICAgICAgICByZXR1cm4gbWFwcGluZzsKLSAgICB9IC8vIGdldEVsZW1lbnREZWNsSW5kZXgoU3RyaW5nKTppbnQKLQotICAgIC8qKiBSZXR1cm5zIHRoZSBlbGVtZW50IGRlY2wgaW5kZXguCi0gICAgICogQHBhcmFtIGVsZW1lbnREZWNsUU5hbWUgcXVhbGlsZmllZCBuYW1lIG9mIHRoZSBlbGVtZW50Ci0gICAgICovCi0gICAgcHVibGljIGludCBnZXRFbGVtZW50RGVjbEluZGV4KFFOYW1lIGVsZW1lbnREZWNsUU5hbWUpIHsKLSAgICAgICAgcmV0dXJuIGdldEVsZW1lbnREZWNsSW5kZXgoZWxlbWVudERlY2xRTmFtZS5yYXduYW1lKTsKLSAgICB9IC8vIGdldEVsZW1lbnREZWNsSW5kZXgoUU5hbWUpOmludAotCi0gICAgLyoqIG1ha2Ugc2VwYXJhdGUgZnVuY3Rpb24gZm9yIGdldHRpbmcgY29udGVudFNwZWNUeXBlIG9mIGVsZW1lbnQuCi0gICAgICogd2UgY2FuIGF2b2lkIHNldHRpbmcgb2YgdGhlIGVsZW1lbnQgdmFsdWVzLgotICAgICAqLwotCi0gICAgcHVibGljIHNob3J0IGdldENvbnRlbnRTcGVjVHlwZShpbnQgZWxlbWVudEluZGV4KXsKLSAgICAgICAgaWYgKGVsZW1lbnRJbmRleCA8IDAgfHwgZWxlbWVudEluZGV4ID49IGZFbGVtZW50RGVjbENvdW50KSB7Ci0gICAgICAgICAgICByZXR1cm4gLTEgOwotICAgICAgICB9Ci0KLSAgICAgICAgaW50IGNodW5rID0gZWxlbWVudEluZGV4ID4+IENIVU5LX1NISUZUOwotICAgICAgICBpbnQgaW5kZXggPSBlbGVtZW50SW5kZXggJiAgQ0hVTktfTUFTSzsKLQotICAgICAgICBpZihmRWxlbWVudERlY2xUeXBlW2NodW5rXVtpbmRleF0gPT0gLTEpewotICAgICAgICAgICAgcmV0dXJuIC0xIDsKLSAgICAgICAgfQotICAgICAgICBlbHNlewotICAgICAgICAgICAgcmV0dXJuIChzaG9ydCkgKGZFbGVtZW50RGVjbFR5cGVbY2h1bmtdW2luZGV4XSAmIExJU1RfTUFTSyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBnZXRFbGVtZW50RGVjbAotICAgICAqCi0gICAgICogQHBhcmFtIGVsZW1lbnREZWNsSW5kZXgKLSAgICAgKiBAcGFyYW0gZWxlbWVudERlY2wgVGhlIHZhbHVlcyBvZiB0aGlzIHN0cnVjdHVyZSBhcmUgc2V0IGJ5IHRoaXMgY2FsbC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVHJ1ZSBpZiBmaW5kIHRoZSBlbGVtZW50LCBGYWxzZSBvdGhlcndpc2UuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0RWxlbWVudERlY2woaW50IGVsZW1lbnREZWNsSW5kZXgsCi0gICAgWE1MRWxlbWVudERlY2wgZWxlbWVudERlY2wpIHsKLQotICAgICAgICBpZiAoZWxlbWVudERlY2xJbmRleCA8IDAgfHwgZWxlbWVudERlY2xJbmRleCA+PSBmRWxlbWVudERlY2xDb3VudCkgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0KLSAgICAgICAgaW50IGNodW5rID0gZWxlbWVudERlY2xJbmRleCA+PiBDSFVOS19TSElGVDsKLSAgICAgICAgaW50IGluZGV4ID0gZWxlbWVudERlY2xJbmRleCAmICBDSFVOS19NQVNLOwotCi0gICAgICAgIGVsZW1lbnREZWNsLm5hbWUuc2V0VmFsdWVzKGZFbGVtZW50RGVjbE5hbWVbY2h1bmtdW2luZGV4XSk7Ci0KLSAgICAgICAgaWYgKGZFbGVtZW50RGVjbFR5cGVbY2h1bmtdW2luZGV4XSA9PSAtMSkgewotICAgICAgICAgICAgZWxlbWVudERlY2wudHlwZSAgICAgICAgICAgICAgICAgICAgPSAtMTsKLSAgICAgICAgICAgIGVsZW1lbnREZWNsLnNpbXBsZVR5cGUubGlzdCA9IGZhbHNlOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgZWxlbWVudERlY2wudHlwZSAgICAgICAgICAgID0gKHNob3J0KSAoZkVsZW1lbnREZWNsVHlwZVtjaHVua11baW5kZXhdICYgTElTVF9NQVNLKTsKLSAgICAgICAgICAgIGVsZW1lbnREZWNsLnNpbXBsZVR5cGUubGlzdCA9IChmRWxlbWVudERlY2xUeXBlW2NodW5rXVtpbmRleF0gJiBMSVNUX0ZMQUcpICE9IDA7Ci0gICAgICAgIH0KLQotICAgICAgICBlbGVtZW50RGVjbC5zaW1wbGVUeXBlLmRlZmF1bHRUeXBlICAgICAgID0gLTE7Ci0gICAgICAgIGVsZW1lbnREZWNsLnNpbXBsZVR5cGUuZGVmYXVsdFZhbHVlICAgICAgPSBudWxsOwotICAgICAgICByZXR1cm4gdHJ1ZTsKLQotICAgIH0KLQotICAgIC8vIFJFVklTSVQ6IE1ha2UgdGhpcyBnZXRBdHRyaWJ1dGVEZWNsQ291bnQvZ2V0QXR0cmlidXRlRGVjbEF0LiAtQWMKLQotICAgIC8qKgotICAgICAqIGdldEZpcnN0QXR0cmlidXRlRGVjbEluZGV4Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gZWxlbWVudERlY2xJbmRleAotICAgICAqCi0gICAgICogQHJldHVybiBpbmRleCBvZiB0aGUgZmlyc3QgYXR0cmlidXRlIGZvciBlbGVtZW50IGRlY2xhcmF0aW9uIGVsZW1lbnREZWNsSW5kZXgKLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldEZpcnN0QXR0cmlidXRlRGVjbEluZGV4KGludCBlbGVtZW50RGVjbEluZGV4KSB7Ci0gICAgICAgIGludCBjaHVuayA9IGVsZW1lbnREZWNsSW5kZXggPj4gQ0hVTktfU0hJRlQ7Ci0gICAgICAgIGludCBpbmRleCA9IGVsZW1lbnREZWNsSW5kZXggJiAgQ0hVTktfTUFTSzsKLQotICAgICAgICByZXR1cm4gIGZFbGVtZW50RGVjbEZpcnN0QXR0cmlidXRlRGVjbEluZGV4W2NodW5rXVtpbmRleF07Ci0gICAgfSAvLyBnZXRGaXJzdEF0dHJpYnV0ZURlY2xJbmRleAotCi0gICAgLyoqCi0gICAgICogZ2V0TmV4dEF0dHJpYnV0ZURlY2xJbmRleAotICAgICAqCi0gICAgICogQHBhcmFtIGF0dHJpYnV0ZURlY2xJbmRleAotICAgICAqCi0gICAgICogQHJldHVybiBpbmRleCBvZiB0aGUgbmV4dCBhdHRyaWJ1dGUgb2YgdGhlIGF0dHJpYnV0ZSBhdCBhdHRyaWJ1dGVEZWNsSW5kZXgKLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldE5leHRBdHRyaWJ1dGVEZWNsSW5kZXgoaW50IGF0dHJpYnV0ZURlY2xJbmRleCkgewotICAgICAgICBpbnQgY2h1bmsgPSBhdHRyaWJ1dGVEZWNsSW5kZXggPj4gQ0hVTktfU0hJRlQ7Ci0gICAgICAgIGludCBpbmRleCA9IGF0dHJpYnV0ZURlY2xJbmRleCAmICBDSFVOS19NQVNLOwotCi0gICAgICAgIHJldHVybiBmQXR0cmlidXRlRGVjbE5leHRBdHRyaWJ1dGVEZWNsSW5kZXhbY2h1bmtdW2luZGV4XTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBnZXRBdHRyaWJ1dGVEZWNsCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYXR0cmlidXRlRGVjbEluZGV4Ci0gICAgICogQHBhcmFtIGF0dHJpYnV0ZURlY2wgVGhlIHZhbHVlcyBvZiB0aGlzIHN0cnVjdHVyZSBhcmUgc2V0IGJ5IHRoaXMgY2FsbC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBnZXRBdHRyaWJ1dGVEZWNsIHdhcyBhYmxlIHRvIGZpbGwgaW4gdGhlIHZhbHVlIG9mIGF0dHJpYnV0ZURlY2wKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXRBdHRyaWJ1dGVEZWNsKGludCBhdHRyaWJ1dGVEZWNsSW5kZXgsIFhNTEF0dHJpYnV0ZURlY2wgYXR0cmlidXRlRGVjbCkgewotICAgICAgICBpZiAoYXR0cmlidXRlRGVjbEluZGV4IDwgMCB8fCBhdHRyaWJ1dGVEZWNsSW5kZXggPj0gZkF0dHJpYnV0ZURlY2xDb3VudCkgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0gICAgICAgIGludCBjaHVuayA9IGF0dHJpYnV0ZURlY2xJbmRleCA+PiBDSFVOS19TSElGVDsKLSAgICAgICAgaW50IGluZGV4ID0gYXR0cmlidXRlRGVjbEluZGV4ICYgQ0hVTktfTUFTSzsKLQotICAgICAgICBhdHRyaWJ1dGVEZWNsLm5hbWUuc2V0VmFsdWVzKGZBdHRyaWJ1dGVEZWNsTmFtZVtjaHVua11baW5kZXhdKTsKLQotICAgICAgICBzaG9ydCBhdHRyaWJ1dGVUeXBlOwotICAgICAgICBib29sZWFuIGlzTGlzdDsKLQotICAgICAgICBpZiAoZkF0dHJpYnV0ZURlY2xUeXBlW2NodW5rXVtpbmRleF0gPT0gLTEpIHsKLQotICAgICAgICAgICAgYXR0cmlidXRlVHlwZSA9IC0xOwotICAgICAgICAgICAgaXNMaXN0ID0gZmFsc2U7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBhdHRyaWJ1dGVUeXBlID0gKHNob3J0KSAoZkF0dHJpYnV0ZURlY2xUeXBlW2NodW5rXVtpbmRleF0gJiBMSVNUX01BU0spOwotICAgICAgICAgICAgaXNMaXN0ID0gKGZBdHRyaWJ1dGVEZWNsVHlwZVtjaHVua11baW5kZXhdICYgTElTVF9GTEFHKSAhPSAwOwotICAgICAgICB9Ci0gICAgICAgIGF0dHJpYnV0ZURlY2wuc2ltcGxlVHlwZS5zZXRWYWx1ZXMoYXR0cmlidXRlVHlwZSxmQXR0cmlidXRlRGVjbE5hbWVbY2h1bmtdW2luZGV4XS5sb2NhbHBhcnQsCi0gICAgICAgIGZBdHRyaWJ1dGVEZWNsRW51bWVyYXRpb25bY2h1bmtdW2luZGV4XSwKLSAgICAgICAgaXNMaXN0LCBmQXR0cmlidXRlRGVjbERlZmF1bHRUeXBlW2NodW5rXVtpbmRleF0sCi0gICAgICAgIGZBdHRyaWJ1dGVEZWNsRGVmYXVsdFZhbHVlW2NodW5rXVtpbmRleF0sCi0gICAgICAgIGZBdHRyaWJ1dGVEZWNsTm9uTm9ybWFsaXplZERlZmF1bHRWYWx1ZVtjaHVua11baW5kZXhdKTsKLSAgICAgICAgcmV0dXJuIHRydWU7Ci0KLSAgICB9IC8vIGdldEF0dHJpYnV0ZURlY2wKLQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB3aGV0aGVyIHRoZSBnaXZlbiBhdHRyaWJ1dGUgaXMgb2YgdHlwZSBDREFUQSBvciBub3QKLSAgICAgKgotICAgICAqIEBwYXJhbSBlbE5hbWUgVGhlIGVsZW1lbnQgbmFtZS4KLSAgICAgKiBAcGFyYW0gYXROYW1lIFRoZSBhdHRyaWJ1dGUgbmFtZS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgYXR0cmlidXRlIGlzIG9mIHR5cGUgQ0RBVEEKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0NEQVRBQXR0cmlidXRlKFFOYW1lIGVsTmFtZSwgUU5hbWUgYXROYW1lKSB7Ci0gICAgICAgIGludCBlbERlY2xJZHggPSBnZXRFbGVtZW50RGVjbEluZGV4KGVsTmFtZSk7Ci0gICAgICAgIGlmIChnZXRBdHRyaWJ1dGVEZWNsKGVsRGVjbElkeCwgZkF0dHJpYnV0ZURlY2wpCi0gICAgICAgICYmIGZBdHRyaWJ1dGVEZWNsLnNpbXBsZVR5cGUudHlwZSAhPSBYTUxTaW1wbGVUeXBlLlRZUEVfQ0RBVEEpewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotCi0KLSAgICBwdWJsaWMgdm9pZCBwcmludEVsZW1lbnRzKCAgKSB7Ci0gICAgICAgIGludCBlbGVtZW50RGVjbEluZGV4ID0gMDsKLSAgICAgICAgWE1MRWxlbWVudERlY2wgZWxlbWVudERlY2wgPSBuZXcgWE1MRWxlbWVudERlY2woKTsKLSAgICAgICAgd2hpbGUgKGdldEVsZW1lbnREZWNsKGVsZW1lbnREZWNsSW5kZXgrKywgZWxlbWVudERlY2wpKSB7Ci0KLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiZWxlbWVudCBkZWNsOiAiK2VsZW1lbnREZWNsLm5hbWUrCi0gICAgICAgICAgICAiLCAiKyBlbGVtZW50RGVjbC5uYW1lLnJhd25hbWUgICk7Ci0KLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHByaW50QXR0cmlidXRlcyhpbnQgZWxlbWVudERlY2xJbmRleCkgewotICAgICAgICBpbnQgYXR0cmlidXRlRGVjbEluZGV4ID0gZ2V0Rmlyc3RBdHRyaWJ1dGVEZWNsSW5kZXgoZWxlbWVudERlY2xJbmRleCk7Ci0gICAgICAgIFN5c3RlbS5vdXQucHJpbnQoZWxlbWVudERlY2xJbmRleCk7Ci0gICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIiBbIik7Ci0gICAgICAgIHdoaWxlIChhdHRyaWJ1dGVEZWNsSW5kZXggIT0gLTEpIHsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoJyAnKTsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoYXR0cmlidXRlRGVjbEluZGV4KTsKLSAgICAgICAgICAgIHByaW50QXR0cmlidXRlKGF0dHJpYnV0ZURlY2xJbmRleCk7Ci0gICAgICAgICAgICBhdHRyaWJ1dGVEZWNsSW5kZXggPSBnZXROZXh0QXR0cmlidXRlRGVjbEluZGV4KGF0dHJpYnV0ZURlY2xJbmRleCk7Ci0gICAgICAgICAgICBpZiAoYXR0cmlidXRlRGVjbEluZGV4ICE9IC0xKSB7Ci0gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiLCIpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiIF0iKTsKLSAgICB9Ci0KLQotICAgIHByb3RlY3RlZCBpbnQgY3JlYXRlRWxlbWVudERlY2woKSB7Ci0gICAgICAgIGludCBjaHVuayA9IGZFbGVtZW50RGVjbENvdW50ID4+IENIVU5LX1NISUZUOwotICAgICAgICBpbnQgaW5kZXggPSBmRWxlbWVudERlY2xDb3VudCAmIENIVU5LX01BU0s7Ci0gICAgICAgIGVuc3VyZUVsZW1lbnREZWNsQ2FwYWNpdHkoY2h1bmspOwotICAgICAgICBmRWxlbWVudERlY2xOYW1lW2NodW5rXVtpbmRleF0gICAgICAgICAgICAgICAgICAgID0gbmV3IFFOYW1lKCk7Ci0gICAgICAgIGZFbGVtZW50RGVjbFR5cGVbY2h1bmtdW2luZGV4XSAgICAgICAgICAgICAgICAgICAgPSAtMTsKLSAgICAgICAgZkVsZW1lbnREZWNsRmlyc3RBdHRyaWJ1dGVEZWNsSW5kZXhbY2h1bmtdW2luZGV4XSA9IC0xOwotICAgICAgICBmRWxlbWVudERlY2xMYXN0QXR0cmlidXRlRGVjbEluZGV4W2NodW5rXVtpbmRleF0gID0gLTE7Ci0gICAgICAgIHJldHVybiBmRWxlbWVudERlY2xDb3VudCsrOwotICAgIH0KLQotICAgIHByb3RlY3RlZCB2b2lkIHNldEVsZW1lbnREZWNsKGludCBlbGVtZW50RGVjbEluZGV4LCBYTUxFbGVtZW50RGVjbCBlbGVtZW50RGVjbCkgewotICAgICAgICBpZiAoZWxlbWVudERlY2xJbmRleCA8IDAgfHwgZWxlbWVudERlY2xJbmRleCA+PSBmRWxlbWVudERlY2xDb3VudCkgewotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0gICAgICAgIGludCAgICAgY2h1bmsgICAgICAgPSBlbGVtZW50RGVjbEluZGV4ID4+IENIVU5LX1NISUZUOwotICAgICAgICBpbnQgICAgIGluZGV4ICAgICAgID0gZWxlbWVudERlY2xJbmRleCAmICBDSFVOS19NQVNLOwotCi0gICAgICAgIGludCAgICAgc2NvcGUgICAgICAgPSBlbGVtZW50RGVjbC5zY29wZTsKLQotCi0gICAgICAgIGZFbGVtZW50RGVjbE5hbWVbY2h1bmtdW2luZGV4XS5zZXRWYWx1ZXMoZWxlbWVudERlY2wubmFtZSk7Ci0gICAgICAgIGZFbGVtZW50RGVjbFR5cGVbY2h1bmtdW2luZGV4XSAgICAgICAgICAgICAgICAgID0gZWxlbWVudERlY2wudHlwZTsKLQotCi0KLSAgICAgICAgaWYgKGVsZW1lbnREZWNsLnNpbXBsZVR5cGUubGlzdCAgPT0gdHJ1ZSApIHsKLSAgICAgICAgICAgIGZFbGVtZW50RGVjbFR5cGVbY2h1bmtdW2luZGV4XSB8PSBMSVNUX0ZMQUc7Ci0gICAgICAgIH0KLQotICAgICAgICBmRWxlbWVudEluZGV4TWFwLnB1dChlbGVtZW50RGVjbC5uYW1lLnJhd25hbWUsIGVsZW1lbnREZWNsSW5kZXgpOwotICAgIH0KLQotCi0KLQotICAgIHByb3RlY3RlZCB2b2lkIHNldEZpcnN0QXR0cmlidXRlRGVjbEluZGV4KGludCBlbGVtZW50RGVjbEluZGV4LCBpbnQgbmV3Rmlyc3RBdHRySW5kZXgpewotCi0gICAgICAgIGlmIChlbGVtZW50RGVjbEluZGV4IDwgMCB8fCBlbGVtZW50RGVjbEluZGV4ID49IGZFbGVtZW50RGVjbENvdW50KSB7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLQotICAgICAgICBpbnQgY2h1bmsgPSBlbGVtZW50RGVjbEluZGV4ID4+IENIVU5LX1NISUZUOwotICAgICAgICBpbnQgaW5kZXggPSBlbGVtZW50RGVjbEluZGV4ICYgIENIVU5LX01BU0s7Ci0KLSAgICAgICAgZkVsZW1lbnREZWNsRmlyc3RBdHRyaWJ1dGVEZWNsSW5kZXhbY2h1bmtdW2luZGV4XSA9IG5ld0ZpcnN0QXR0ckluZGV4OwotICAgIH0KLQotCi0gICAgcHJvdGVjdGVkIGludCBjcmVhdGVBdHRyaWJ1dGVEZWNsKCkgewotICAgICAgICBpbnQgY2h1bmsgPSBmQXR0cmlidXRlRGVjbENvdW50ID4+IENIVU5LX1NISUZUOwotICAgICAgICBpbnQgaW5kZXggPSBmQXR0cmlidXRlRGVjbENvdW50ICYgQ0hVTktfTUFTSzsKLQotICAgICAgICBlbnN1cmVBdHRyaWJ1dGVEZWNsQ2FwYWNpdHkoY2h1bmspOwotICAgICAgICBmQXR0cmlidXRlRGVjbE5hbWVbY2h1bmtdW2luZGV4XSAgICAgICAgICAgICAgICAgICAgPSBuZXcgUU5hbWUoKTsKLSAgICAgICAgZkF0dHJpYnV0ZURlY2xUeXBlW2NodW5rXVtpbmRleF0gICAgICAgICAgICAgICAgICAgID0gLTE7Ci0gICAgICAgIGZBdHRyaWJ1dGVEZWNsRW51bWVyYXRpb25bY2h1bmtdW2luZGV4XSAgICAgICAgICAgICA9IG51bGw7Ci0gICAgICAgIGZBdHRyaWJ1dGVEZWNsRGVmYXVsdFR5cGVbY2h1bmtdW2luZGV4XSAgICAgICAgICAgICA9IFhNTFNpbXBsZVR5cGUuREVGQVVMVF9UWVBFX0lNUExJRUQ7Ci0gICAgICAgIGZBdHRyaWJ1dGVEZWNsRGVmYXVsdFZhbHVlW2NodW5rXVtpbmRleF0gICAgICAgICAgICA9IG51bGw7Ci0gICAgICAgIGZBdHRyaWJ1dGVEZWNsTm9uTm9ybWFsaXplZERlZmF1bHRWYWx1ZVtjaHVua11baW5kZXhdICAgICAgICAgICAgPSBudWxsOwotICAgICAgICBmQXR0cmlidXRlRGVjbE5leHRBdHRyaWJ1dGVEZWNsSW5kZXhbY2h1bmtdW2luZGV4XSAgPSAtMTsKLSAgICAgICAgcmV0dXJuIGZBdHRyaWJ1dGVEZWNsQ291bnQrKzsKLSAgICB9Ci0KLQotICAgIHByb3RlY3RlZCB2b2lkIHNldEF0dHJpYnV0ZURlY2woaW50IGVsZW1lbnREZWNsSW5kZXgsIGludCBhdHRyaWJ1dGVEZWNsSW5kZXgsCi0gICAgWE1MQXR0cmlidXRlRGVjbCBhdHRyaWJ1dGVEZWNsKSB7Ci0gICAgICAgIGludCBhdHRyQ2h1bmsgPSBhdHRyaWJ1dGVEZWNsSW5kZXggPj4gQ0hVTktfU0hJRlQ7Ci0gICAgICAgIGludCBhdHRySW5kZXggPSBhdHRyaWJ1dGVEZWNsSW5kZXggJiAgQ0hVTktfTUFTSzsKLSAgICAgICAgZkF0dHJpYnV0ZURlY2xOYW1lW2F0dHJDaHVua11bYXR0ckluZGV4XS5zZXRWYWx1ZXMoYXR0cmlidXRlRGVjbC5uYW1lKTsKLSAgICAgICAgZkF0dHJpYnV0ZURlY2xUeXBlW2F0dHJDaHVua11bYXR0ckluZGV4XSAgPSAgYXR0cmlidXRlRGVjbC5zaW1wbGVUeXBlLnR5cGU7Ci0KLSAgICAgICAgaWYgKGF0dHJpYnV0ZURlY2wuc2ltcGxlVHlwZS5saXN0KSB7Ci0gICAgICAgICAgICBmQXR0cmlidXRlRGVjbFR5cGVbYXR0ckNodW5rXVthdHRySW5kZXhdIHw9IExJU1RfRkxBRzsKLSAgICAgICAgfQotICAgICAgICBmQXR0cmlidXRlRGVjbEVudW1lcmF0aW9uW2F0dHJDaHVua11bYXR0ckluZGV4XSAgPSAgYXR0cmlidXRlRGVjbC5zaW1wbGVUeXBlLmVudW1lcmF0aW9uOwotICAgICAgICBmQXR0cmlidXRlRGVjbERlZmF1bHRUeXBlW2F0dHJDaHVua11bYXR0ckluZGV4XSAgPSAgYXR0cmlidXRlRGVjbC5zaW1wbGVUeXBlLmRlZmF1bHRUeXBlOwotCi0gICAgICAgIGZBdHRyaWJ1dGVEZWNsRGVmYXVsdFZhbHVlW2F0dHJDaHVua11bYXR0ckluZGV4XSA9IGF0dHJpYnV0ZURlY2wuc2ltcGxlVHlwZS5kZWZhdWx0VmFsdWU7Ci0gICAgICAgIGZBdHRyaWJ1dGVEZWNsTm9uTm9ybWFsaXplZERlZmF1bHRWYWx1ZVthdHRyQ2h1bmtdW2F0dHJJbmRleF0gPSBhdHRyaWJ1dGVEZWNsLnNpbXBsZVR5cGUubm9uTm9ybWFsaXplZERlZmF1bHRWYWx1ZTsKLQotICAgICAgICBpbnQgZWxlbUNodW5rICAgICA9IGVsZW1lbnREZWNsSW5kZXggPj4gQ0hVTktfU0hJRlQ7Ci0gICAgICAgIGludCBlbGVtSW5kZXggICAgID0gZWxlbWVudERlY2xJbmRleCAmICBDSFVOS19NQVNLOwotICAgICAgICBpbnQgaW5kZXggICAgICAgICA9IGZFbGVtZW50RGVjbEZpcnN0QXR0cmlidXRlRGVjbEluZGV4W2VsZW1DaHVua11bZWxlbUluZGV4XTsKLSAgICAgICAgd2hpbGUgKGluZGV4ICE9IC0xKSB7Ci0gICAgICAgICAgICBpZiAoaW5kZXggPT0gYXR0cmlidXRlRGVjbEluZGV4KSB7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBhdHRyQ2h1bmsgPSBpbmRleCA+PiBDSFVOS19TSElGVDsKLSAgICAgICAgICAgIGF0dHJJbmRleCA9IGluZGV4ICYgQ0hVTktfTUFTSzsKLSAgICAgICAgICAgIGluZGV4ID0gZkF0dHJpYnV0ZURlY2xOZXh0QXR0cmlidXRlRGVjbEluZGV4W2F0dHJDaHVua11bYXR0ckluZGV4XTsKLSAgICAgICAgfQotICAgICAgICBpZiAoaW5kZXggPT0gLTEpIHsKLSAgICAgICAgICAgIGlmIChmRWxlbWVudERlY2xGaXJzdEF0dHJpYnV0ZURlY2xJbmRleFtlbGVtQ2h1bmtdW2VsZW1JbmRleF0gPT0gLTEpIHsKLSAgICAgICAgICAgICAgICBmRWxlbWVudERlY2xGaXJzdEF0dHJpYnV0ZURlY2xJbmRleFtlbGVtQ2h1bmtdW2VsZW1JbmRleF0gPSBhdHRyaWJ1dGVEZWNsSW5kZXg7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIGluZGV4ID0gZkVsZW1lbnREZWNsTGFzdEF0dHJpYnV0ZURlY2xJbmRleFtlbGVtQ2h1bmtdW2VsZW1JbmRleF07Ci0gICAgICAgICAgICAgICAgYXR0ckNodW5rID0gaW5kZXggPj4gQ0hVTktfU0hJRlQ7Ci0gICAgICAgICAgICAgICAgYXR0ckluZGV4ID0gaW5kZXggJiBDSFVOS19NQVNLOwotICAgICAgICAgICAgICAgIGZBdHRyaWJ1dGVEZWNsTmV4dEF0dHJpYnV0ZURlY2xJbmRleFthdHRyQ2h1bmtdW2F0dHJJbmRleF0gPSBhdHRyaWJ1dGVEZWNsSW5kZXg7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmRWxlbWVudERlY2xMYXN0QXR0cmlidXRlRGVjbEluZGV4W2VsZW1DaHVua11bZWxlbUluZGV4XSA9IGF0dHJpYnV0ZURlY2xJbmRleDsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIG5vdGF0aW9uRGVjbChTdHJpbmcgbmFtZSwgWE1MUmVzb3VyY2VJZGVudGlmaWVyIGlkZW50aWZpZXIsCi0gICAgQXVnbWVudGF0aW9ucyBhdWdzKSB0aHJvd3MgWE5JRXhjZXB0aW9uIHsKLQotCi0gICAgICAgIFhNTE5vdGF0aW9uRGVjbCAgbm90YXRpb25EZWNsID0gbmV3IFhNTE5vdGF0aW9uRGVjbCgpOwotICAgICAgICBub3RhdGlvbkRlY2wuc2V0VmFsdWVzKG5hbWUsaWRlbnRpZmllci5nZXRQdWJsaWNJZCgpLGlkZW50aWZpZXIuZ2V0TGl0ZXJhbFN5c3RlbUlkKCksCi0gICAgICAgIGlkZW50aWZpZXIuZ2V0QmFzZVN5c3RlbUlkKCkpOwotICAgICAgICBub3RhdGlvbkRlY2xzLmFkZChub3RhdGlvbkRlY2wpOwotICAgIH0KLQotICAgIHB1YmxpYyBMaXN0IGdldE5vdGF0aW9uRGVjbHMoKXsKLSAgICAgICAgcmV0dXJuIG5vdGF0aW9uRGVjbHM7Ci0gICAgfQotCi0gICAgLy8KLSAgICAvLyBQcml2YXRlIG1ldGhvZHMKLSAgICAvLwotICAgIHByaXZhdGUgdm9pZCBwcmludEF0dHJpYnV0ZShpbnQgYXR0cmlidXRlRGVjbEluZGV4KSB7Ci0KLSAgICAgICAgWE1MQXR0cmlidXRlRGVjbCBhdHRyaWJ1dGVEZWNsID0gbmV3IFhNTEF0dHJpYnV0ZURlY2woKTsKLSAgICAgICAgaWYgKGdldEF0dHJpYnV0ZURlY2woYXR0cmlidXRlRGVjbEluZGV4LCBhdHRyaWJ1dGVEZWNsKSkgewotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiIHsgIik7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KGF0dHJpYnV0ZURlY2wubmFtZS5sb2NhbHBhcnQpOwotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiIH0iKTsKLSAgICAgICAgfQotCi0gICAgfSAvLyBwcmludEF0dHJpYnV0ZShpbnQpCi0KLQotCi0gICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUVsZW1lbnREZWNsQ2FwYWNpdHkoaW50IGNodW5rKSB7Ci0gICAgICAgIGlmIChjaHVuayA+PSBmRWxlbWVudERlY2xOYW1lLmxlbmd0aCkgewotCi0gICAgICAgICAgICBmRWxlbWVudERlY2xOYW1lID0gcmVzaXplKGZFbGVtZW50RGVjbE5hbWUsIGZFbGVtZW50RGVjbE5hbWUubGVuZ3RoICogMik7Ci0gICAgICAgICAgICBmRWxlbWVudERlY2xUeXBlID0gcmVzaXplKGZFbGVtZW50RGVjbFR5cGUsIGZFbGVtZW50RGVjbFR5cGUubGVuZ3RoICogMik7Ci0gICAgICAgICAgICBmRWxlbWVudERlY2xGaXJzdEF0dHJpYnV0ZURlY2xJbmRleCA9IHJlc2l6ZShmRWxlbWVudERlY2xGaXJzdEF0dHJpYnV0ZURlY2xJbmRleCwgZkVsZW1lbnREZWNsRmlyc3RBdHRyaWJ1dGVEZWNsSW5kZXgubGVuZ3RoICogMik7Ci0gICAgICAgICAgICBmRWxlbWVudERlY2xMYXN0QXR0cmlidXRlRGVjbEluZGV4ID0gcmVzaXplKGZFbGVtZW50RGVjbExhc3RBdHRyaWJ1dGVEZWNsSW5kZXgsIGZFbGVtZW50RGVjbExhc3RBdHRyaWJ1dGVEZWNsSW5kZXgubGVuZ3RoICogMik7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoZkVsZW1lbnREZWNsTmFtZVtjaHVua10gIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0KLSAgICAgICAgZkVsZW1lbnREZWNsTmFtZVtjaHVua10gPSBuZXcgUU5hbWVbQ0hVTktfU0laRV07Ci0gICAgICAgIGZFbGVtZW50RGVjbFR5cGVbY2h1bmtdID0gbmV3IHNob3J0W0NIVU5LX1NJWkVdOwotICAgICAgICBmRWxlbWVudERlY2xGaXJzdEF0dHJpYnV0ZURlY2xJbmRleFtjaHVua10gPSBuZXcgaW50W0NIVU5LX1NJWkVdOwotICAgICAgICBmRWxlbWVudERlY2xMYXN0QXR0cmlidXRlRGVjbEluZGV4W2NodW5rXSA9IG5ldyBpbnRbQ0hVTktfU0laRV07Ci0gICAgICAgIHJldHVybjsKLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgZW5zdXJlQXR0cmlidXRlRGVjbENhcGFjaXR5KGludCBjaHVuaykgewotCi0gICAgICAgIGlmIChjaHVuayA+PSBmQXR0cmlidXRlRGVjbE5hbWUubGVuZ3RoKSB7Ci0gICAgICAgICAgICBmQXR0cmlidXRlRGVjbE5hbWUgPSByZXNpemUoZkF0dHJpYnV0ZURlY2xOYW1lLCBmQXR0cmlidXRlRGVjbE5hbWUubGVuZ3RoICogMik7Ci0gICAgICAgICAgICBmQXR0cmlidXRlRGVjbFR5cGUgPSByZXNpemUoZkF0dHJpYnV0ZURlY2xUeXBlLCBmQXR0cmlidXRlRGVjbFR5cGUubGVuZ3RoICogMik7Ci0gICAgICAgICAgICBmQXR0cmlidXRlRGVjbEVudW1lcmF0aW9uID0gcmVzaXplKGZBdHRyaWJ1dGVEZWNsRW51bWVyYXRpb24sIGZBdHRyaWJ1dGVEZWNsRW51bWVyYXRpb24ubGVuZ3RoICogMik7Ci0gICAgICAgICAgICBmQXR0cmlidXRlRGVjbERlZmF1bHRUeXBlID0gcmVzaXplKGZBdHRyaWJ1dGVEZWNsRGVmYXVsdFR5cGUsIGZBdHRyaWJ1dGVEZWNsRGVmYXVsdFR5cGUubGVuZ3RoICogMik7Ci0gICAgICAgICAgICBmQXR0cmlidXRlRGVjbERlZmF1bHRWYWx1ZSA9IHJlc2l6ZShmQXR0cmlidXRlRGVjbERlZmF1bHRWYWx1ZSwgZkF0dHJpYnV0ZURlY2xEZWZhdWx0VmFsdWUubGVuZ3RoICogMik7Ci0gICAgICAgICAgICBmQXR0cmlidXRlRGVjbE5vbk5vcm1hbGl6ZWREZWZhdWx0VmFsdWUgPSByZXNpemUoZkF0dHJpYnV0ZURlY2xOb25Ob3JtYWxpemVkRGVmYXVsdFZhbHVlLCBmQXR0cmlidXRlRGVjbE5vbk5vcm1hbGl6ZWREZWZhdWx0VmFsdWUubGVuZ3RoICogMik7Ci0gICAgICAgICAgICBmQXR0cmlidXRlRGVjbE5leHRBdHRyaWJ1dGVEZWNsSW5kZXggPSByZXNpemUoZkF0dHJpYnV0ZURlY2xOZXh0QXR0cmlidXRlRGVjbEluZGV4LCBmQXR0cmlidXRlRGVjbE5leHRBdHRyaWJ1dGVEZWNsSW5kZXgubGVuZ3RoICogMik7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoZkF0dHJpYnV0ZURlY2xOYW1lW2NodW5rXSAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLQotICAgICAgICBmQXR0cmlidXRlRGVjbE5hbWVbY2h1bmtdID0gbmV3IFFOYW1lW0NIVU5LX1NJWkVdOwotICAgICAgICBmQXR0cmlidXRlRGVjbFR5cGVbY2h1bmtdID0gbmV3IHNob3J0W0NIVU5LX1NJWkVdOwotICAgICAgICBmQXR0cmlidXRlRGVjbEVudW1lcmF0aW9uW2NodW5rXSA9IG5ldyBTdHJpbmdbQ0hVTktfU0laRV1bXTsKLSAgICAgICAgZkF0dHJpYnV0ZURlY2xEZWZhdWx0VHlwZVtjaHVua10gPSBuZXcgc2hvcnRbQ0hVTktfU0laRV07Ci0gICAgICAgIGZBdHRyaWJ1dGVEZWNsRGVmYXVsdFZhbHVlW2NodW5rXSA9IG5ldyBTdHJpbmdbQ0hVTktfU0laRV07Ci0gICAgICAgIGZBdHRyaWJ1dGVEZWNsTm9uTm9ybWFsaXplZERlZmF1bHRWYWx1ZVtjaHVua10gPSBuZXcgU3RyaW5nW0NIVU5LX1NJWkVdOwotICAgICAgICBmQXR0cmlidXRlRGVjbE5leHRBdHRyaWJ1dGVEZWNsSW5kZXhbY2h1bmtdID0gbmV3IGludFtDSFVOS19TSVpFXTsKLSAgICAgICAgcmV0dXJuOwotICAgIH0KLQotCi0gICAgLy8gcmVzaXplIGNodW5rcwotCi0gICAgcHJpdmF0ZSBzdGF0aWMgc2hvcnRbXVtdIHJlc2l6ZShzaG9ydCBhcnJheVtdW10sIGludCBuZXdzaXplKSB7Ci0gICAgICAgIHNob3J0IG5ld2FycmF5W11bXSA9IG5ldyBzaG9ydFtuZXdzaXplXVtdOwotICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGFycmF5LCAwLCBuZXdhcnJheSwgMCwgYXJyYXkubGVuZ3RoKTsKLSAgICAgICAgcmV0dXJuIG5ld2FycmF5OwotICAgIH0KLQotICAgIHByaXZhdGUgc3RhdGljIGludFtdW10gcmVzaXplKGludCBhcnJheVtdW10sIGludCBuZXdzaXplKSB7Ci0gICAgICAgIGludCBuZXdhcnJheVtdW10gPSBuZXcgaW50W25ld3NpemVdW107Ci0gICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYXJyYXksIDAsIG5ld2FycmF5LCAwLCBhcnJheS5sZW5ndGgpOwotICAgICAgICByZXR1cm4gbmV3YXJyYXk7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBzdGF0aWMgUU5hbWVbXVtdIHJlc2l6ZShRTmFtZSBhcnJheVtdW10sIGludCBuZXdzaXplKSB7Ci0gICAgICAgIFFOYW1lIG5ld2FycmF5W11bXSA9IG5ldyBRTmFtZVtuZXdzaXplXVtdOwotICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGFycmF5LCAwLCBuZXdhcnJheSwgMCwgYXJyYXkubGVuZ3RoKTsKLSAgICAgICAgcmV0dXJuIG5ld2FycmF5OwotICAgIH0KLQotICAgIHByaXZhdGUgc3RhdGljIFN0cmluZ1tdW10gcmVzaXplKFN0cmluZyBhcnJheVtdW10sIGludCBuZXdzaXplKSB7Ci0gICAgICAgIFN0cmluZyBuZXdhcnJheVtdW10gPSBuZXcgU3RyaW5nW25ld3NpemVdW107Ci0gICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYXJyYXksIDAsIG5ld2FycmF5LCAwLCBhcnJheS5sZW5ndGgpOwotICAgICAgICByZXR1cm4gbmV3YXJyYXk7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nW11bXVtdIHJlc2l6ZShTdHJpbmcgYXJyYXlbXVtdW10sIGludCBuZXdzaXplKSB7Ci0gICAgICAgIFN0cmluZyBuZXdhcnJheVtdW11bXSA9IG5ldyBTdHJpbmdbbmV3c2l6ZV0gW11bXTsKLSAgICAgICAgU3lzdGVtLmFycmF5Y29weShhcnJheSwgMCwgbmV3YXJyYXksIDAsIGFycmF5Lmxlbmd0aCk7Ci0gICAgICAgIHJldHVybiBuZXdhcnJheTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBOb3JtYWxpemUgdGhlIGF0dHJpYnV0ZSB2YWx1ZSBvZiBhIG5vbiBDREFUQSBkZWZhdWx0IGF0dHJpYnV0ZQotICAgICAqIGNvbGxhcHNpbmcgc2VxdWVuY2VzIG9mIHNwYWNlIGNoYXJhY3RlcnMgKHgyMCkKLSAgICAgKgotICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUgdG8gbm9ybWFsaXplCi0gICAgICogQHJldHVybiBXaGV0aGVyIHRoZSB2YWx1ZSB3YXMgY2hhbmdlZCBvciBub3QuCi0gICAgICovCi0gICAgcHJpdmF0ZSBib29sZWFuIG5vcm1hbGl6ZURlZmF1bHRBdHRyVmFsdWUoWE1MU3RyaW5nIHZhbHVlKSB7Ci0KLSAgICAgICAgaW50IG9sZExlbmd0aCA9IHZhbHVlLmxlbmd0aDsKLQotICAgICAgICBib29sZWFuIHNraXBTcGFjZSA9IHRydWU7IC8vIHNraXAgbGVhZGluZyBzcGFjZXMKLSAgICAgICAgaW50IGN1cnJlbnQgPSB2YWx1ZS5vZmZzZXQ7Ci0gICAgICAgIGludCBlbmQgPSB2YWx1ZS5vZmZzZXQgKyB2YWx1ZS5sZW5ndGg7Ci0gICAgICAgIGZvciAoaW50IGkgPSB2YWx1ZS5vZmZzZXQ7IGkgPCBlbmQ7IGkrKykgewotICAgICAgICAgICAgaWYgKHZhbHVlLmNoW2ldID09ICcgJykgewotICAgICAgICAgICAgICAgIGlmICghc2tpcFNwYWNlKSB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIHRha2UgdGhlIGZpcnN0IHdoaXRlc3BhY2UgYXMgYSBzcGFjZSBhbmQgc2tpcCB0aGUgb3RoZXJzCi0gICAgICAgICAgICAgICAgICAgIHZhbHVlLmNoW2N1cnJlbnQrK10gPSAnICc7Ci0gICAgICAgICAgICAgICAgICAgIHNraXBTcGFjZSA9IHRydWU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAvLyBqdXN0IHNraXAgaXQuCi0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgLy8gc2ltcGx5IHNoaWZ0IG5vbiBzcGFjZSBjaGFycyBpZiBuZWVkZWQKLSAgICAgICAgICAgICAgICBpZiAoY3VycmVudCAhPSBpKSB7Ci0gICAgICAgICAgICAgICAgICAgIHZhbHVlLmNoW2N1cnJlbnRdID0gdmFsdWUuY2hbaV07Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGN1cnJlbnQrKzsKLSAgICAgICAgICAgICAgICBza2lwU3BhY2UgPSBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBpZiAoY3VycmVudCAhPSBlbmQpIHsKLSAgICAgICAgICAgIGlmIChza2lwU3BhY2UpIHsKLSAgICAgICAgICAgICAgICAvLyBpZiB3ZSBmaW5pc2hlZCBvbiBhIHNwYWNlIHRyaW0gaXQKLSAgICAgICAgICAgICAgICBjdXJyZW50LS07Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyBzZXQgdGhlIG5ldyB2YWx1ZSBsZW5ndGgKLSAgICAgICAgICAgIHZhbHVlLmxlbmd0aCA9IGN1cnJlbnQgLSB2YWx1ZS5vZmZzZXQ7Ci0gICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotICAgIHB1YmxpYyB2b2lkIGVuZERURChBdWdtZW50YXRpb25zIGF1Z3MpIHRocm93cyBYTklFeGNlcHRpb24gewotCi0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4veG1sL2ludGVybmFsL3N0cmVhbS9kdGQvbm9udmFsaWRhdGluZy9YTUxBdHRyaWJ1dGVEZWNsLmphdmEgYi9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL2R0ZC9ub252YWxpZGF0aW5nL1hNTEF0dHJpYnV0ZURlY2wuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYjNlOGY1YS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL2R0ZC9ub252YWxpZGF0aW5nL1hNTEF0dHJpYnV0ZURlY2wuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDYyICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKi8KLQotLyoKLSAqIENvcHlyaWdodCAyMDA1IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLSAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KLSAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAotICoKLSAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCi0gKgotICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQotICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKLSAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgotICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAotICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLnhtbC5pbnRlcm5hbC5zdHJlYW0uZHRkLm5vbnZhbGlkYXRpbmc7Ci0KLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5RTmFtZTsKLQotLyoqCi0gKi8KLXB1YmxpYyBjbGFzcyBYTUxBdHRyaWJ1dGVEZWNsIHsKLQotCi0gICAgLyoqIG5hbWUgKi8KLSAgICBwdWJsaWMgZmluYWwgUU5hbWUgbmFtZSA9IG5ldyBRTmFtZSgpOwotCi0gICAgLyoqIHNpbXBsZVR5cGUgKi8KLSAgICBwdWJsaWMgZmluYWwgWE1MU2ltcGxlVHlwZSBzaW1wbGVUeXBlID0gbmV3IFhNTFNpbXBsZVR5cGUoKTsKLQotICAgIC8qKiBvcHRpb25hbCAqLwotICAgIHB1YmxpYyBib29sZWFuIG9wdGlvbmFsOwotCi0KLSAgICAvKioKLSAgICAgKiBzZXRWYWx1ZXMKLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lCi0gICAgICogQHBhcmFtIHNpbXBsZVR5cGUKLSAgICAgKiBAcGFyYW0gb3B0aW9uYWwKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRWYWx1ZXMoUU5hbWUgbmFtZSwgWE1MU2ltcGxlVHlwZSBzaW1wbGVUeXBlLCBib29sZWFuIG9wdGlvbmFsKSB7Ci0gICAgICAgIHRoaXMubmFtZS5zZXRWYWx1ZXMobmFtZSk7Ci0gICAgICAgIHRoaXMuc2ltcGxlVHlwZS5zZXRWYWx1ZXMoc2ltcGxlVHlwZSk7Ci0gICAgICAgIHRoaXMub3B0aW9uYWwgICA9IG9wdGlvbmFsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIGNsZWFyCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY2xlYXIoKSB7Ci0gICAgICAgIHRoaXMubmFtZS5jbGVhcigpOwotICAgICAgICB0aGlzLnNpbXBsZVR5cGUuY2xlYXIoKTsKLSAgICAgICAgdGhpcy5vcHRpb25hbCAgID0gZmFsc2U7Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL2R0ZC9ub252YWxpZGF0aW5nL1hNTEVsZW1lbnREZWNsLmphdmEgYi9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL2R0ZC9ub252YWxpZGF0aW5nL1hNTEVsZW1lbnREZWNsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGQwZDk1MGYuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4veG1sL2ludGVybmFsL3N0cmVhbS9kdGQvbm9udmFsaWRhdGluZy9YTUxFbGVtZW50RGVjbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsODMgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqLwotCi0vKgotICogQ29weXJpZ2h0IDIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwotICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgotICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi0gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAotICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCi0gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi0gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ueG1sLmludGVybmFsLnN0cmVhbS5kdGQubm9udmFsaWRhdGluZzsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueG5pLlFOYW1lOwotLyoqCi0gKi8KLXB1YmxpYyBjbGFzcyBYTUxFbGVtZW50RGVjbCB7Ci0KLSAgICAvKiogVFlQRV9BTlkgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFRZUEVfQU5ZID0gMDsKLQotICAgIC8qKiBUWVBFX0VNUFRZICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBUWVBFX0VNUFRZID0gMTsKLQotICAgIC8qKiBUWVBFX01JWEVEICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBUWVBFX01JWEVEID0gMjsKLQotICAgIC8qKiBUWVBFX0NISUxEUkVOICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBUWVBFX0NISUxEUkVOID0gMzsKLQotICAgIC8qKiBUWVBFX1NJTVBMRSAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgVFlQRV9TSU1QTEUgPSA0OwotCi0KLSAgICAvKiogbmFtZSAqLwotICAgIHB1YmxpYyBmaW5hbCBRTmFtZSBuYW1lID0gbmV3IFFOYW1lKCk7Ci0KLSAgICAvKiogc2NvcGUgKi8KLSAgICBwdWJsaWMgaW50IHNjb3BlID0gLTE7Ci0KLSAgICAvKiogdHlwZSAqLwotICAgIHB1YmxpYyBzaG9ydCB0eXBlID0gLTE7Ci0KLQotICAgIC8qKiBzaW1wbGVUeXBlICovCi0gICAgcHVibGljIGZpbmFsIFhNTFNpbXBsZVR5cGUgc2ltcGxlVHlwZSA9IG5ldyBYTUxTaW1wbGVUeXBlKCk7Ci0KLSAgICAvKioKLSAgICAgKiBzZXRWYWx1ZXMKLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lCi0gICAgICogQHBhcmFtIHNjb3BlCi0gICAgICogQHBhcmFtIHR5cGUKLSAgICAgKiBAcGFyYW0gY29udGVudE1vZGVsVmFsaWRhdG9yCi0gICAgICogQHBhcmFtIHNpbXBsZVR5cGUKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRWYWx1ZXMoUU5hbWUgbmFtZSwgaW50IHNjb3BlLCBzaG9ydCB0eXBlLCBYTUxTaW1wbGVUeXBlIHNpbXBsZVR5cGUpIHsKLSAgICAgICAgdGhpcy5uYW1lLnNldFZhbHVlcyhuYW1lKTsKLSAgICAgICAgdGhpcy5zY29wZSAgICAgICAgICAgICAgICAgPSBzY29wZTsKLSAgICAgICAgdGhpcy50eXBlICAgICAgICAgICAgICAgICAgPSB0eXBlOwotICAgICAgICB0aGlzLnNpbXBsZVR5cGUuc2V0VmFsdWVzKHNpbXBsZVR5cGUpOwotICAgIH0gLy8gc2V0VmFsdWVzCi0KLSAgICAvKioKLSAgICAgKiBjbGVhcgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGNsZWFyKCkgewotICAgICAgICB0aGlzLm5hbWUuY2xlYXIoKTsKLSAgICAgICAgdGhpcy50eXBlICAgICAgICAgID0gLTE7Ci0gICAgICAgIHRoaXMuc2NvcGUgICAgICAgICA9IC0xOwotICAgICAgICB0aGlzLnNpbXBsZVR5cGUuY2xlYXIoKTsKLSAgICB9IC8vIGNsZWFyCi0KLX0gLy8gY2xhc3MgWE1MRWxlbWVudERlY2wKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL3htbC9pbnRlcm5hbC9zdHJlYW0vZHRkL25vbnZhbGlkYXRpbmcvWE1MTm90YXRpb25EZWNsLmphdmEgYi9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL2R0ZC9ub252YWxpZGF0aW5nL1hNTE5vdGF0aW9uRGVjbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhMTY0NTgzLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL3htbC9pbnRlcm5hbC9zdHJlYW0vZHRkL25vbnZhbGlkYXRpbmcvWE1MTm90YXRpb25EZWNsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3MSArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDA1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICovCi0KLS8qCi0gKiBDb3B5cmlnaHQgMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7Ci0gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCi0gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKLSAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi0gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLSAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKLSAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi54bWwuaW50ZXJuYWwuc3RyZWFtLmR0ZC5ub252YWxpZGF0aW5nOwotCi0vKioKLSAqLwotcHVibGljIGNsYXNzIFhNTE5vdGF0aW9uRGVjbCB7Ci0KLSAgICAvLwotICAgIC8vIERhdGEKLSAgICAvLwotCi0gICAgLyoqIG5hbWUgKi8KLSAgICBwdWJsaWMgU3RyaW5nIG5hbWU7Ci0KLSAgICAvKiogcHVibGljSWQgKi8KLSAgICBwdWJsaWMgU3RyaW5nIHB1YmxpY0lkOwotCi0gICAgLyoqIHN5c3RlbUlkICovCi0gICAgcHVibGljIFN0cmluZyBzeXN0ZW1JZDsKLQotICAgIC8qKiBiYXNlIHN5c3RlbUlkICovCi0gICAgcHVibGljIFN0cmluZyBiYXNlU3lzdGVtSWQ7Ci0KLSAgICAvLwotICAgIC8vIE1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogc2V0VmFsdWVzCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZQotICAgICAqIEBwYXJhbSBwdWJsaWNJZAotICAgICAqIEBwYXJhbSBzeXN0ZW1JZAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFZhbHVlcyhTdHJpbmcgbmFtZSwgU3RyaW5nIHB1YmxpY0lkLCBTdHJpbmcgc3lzdGVtSWQsIFN0cmluZyBiYXNlU3lzdGVtSWQpIHsKLSAgICAgICAgdGhpcy5uYW1lICAgICA9ICAgbmFtZTsKLSAgICAgICAgdGhpcy5wdWJsaWNJZCA9IHB1YmxpY0lkOwotICAgICAgICB0aGlzLnN5c3RlbUlkID0gc3lzdGVtSWQ7Ci0gICAgICAgIHRoaXMuYmFzZVN5c3RlbUlkID0gYmFzZVN5c3RlbUlkOwotICAgIH0gLy8gc2V0VmFsdWVzCi0KLSAgICAvKioKLSAgICAgKiBjbGVhcgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGNsZWFyKCkgewotICAgICAgICB0aGlzLm5hbWUgICAgID0gbnVsbDsKLSAgICAgICAgdGhpcy5wdWJsaWNJZCA9IG51bGw7Ci0gICAgICAgIHRoaXMuc3lzdGVtSWQgPSBudWxsOwotICAgICAgICB0aGlzLmJhc2VTeXN0ZW1JZCA9IG51bGw7Ci0gICAgfSAvLyBjbGVhcgotCi19IC8vIGNsYXNzIFhNTE5vdGF0aW9uRGVjbApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4veG1sL2ludGVybmFsL3N0cmVhbS9kdGQvbm9udmFsaWRhdGluZy9YTUxTaW1wbGVUeXBlLmphdmEgYi9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL2R0ZC9ub252YWxpZGF0aW5nL1hNTFNpbXBsZVR5cGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMzFhZTUzNC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL2R0ZC9ub252YWxpZGF0aW5nL1hNTFNpbXBsZVR5cGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE3MyArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDA1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqCi0gKiBUSElTIEZJTEUgV0FTIE1PRElGSUVEIEJZIFNVTiBNSUNST1NZU1RFTVMsIElOQy4KLSAqLwotCi0vKgotICogQ29weXJpZ2h0IDIwMDUgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi54bWwuaW50ZXJuYWwuc3RyZWFtLmR0ZC5ub252YWxpZGF0aW5nOwotLyoqCi0gKi8KLXB1YmxpYyBjbGFzcyBYTUxTaW1wbGVUeXBlIHsKLQotICAgIC8vCi0gICAgLy8gQ29uc3RhbnRzCi0gICAgLy8KLQotICAgIC8qKiBUWVBFX0NEQVRBICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBUWVBFX0NEQVRBID0gMDsKLQotICAgIC8qKiBUWVBFX0VOVElUWSAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgVFlQRV9FTlRJVFkgPSAxOwotCi0gICAgLyoqIFRZUEVfRU5VTUVSQVRJT04gKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFRZUEVfRU5VTUVSQVRJT04gPSAyOwotCi0gICAgLyoqIFRZUEVfSUQgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFRZUEVfSUQgPSAzOwotCi0gICAgLyoqIFRZUEVfSURSRUYgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFRZUEVfSURSRUYgPSA0OwotCi0gICAgLyoqIFRZUEVfTk1UT0tFTiAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgVFlQRV9OTVRPS0VOID0gNTsKLQotICAgIC8qKiBUWVBFX05PVEFUSU9OICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBUWVBFX05PVEFUSU9OID0gNjsKLQotICAgIC8qKiBUWVBFX05BTUVEICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBUWVBFX05BTUVEID0gNzsKLQotICAgIC8qKiBERUZBVUxUX1RZUEVfREVGQVVMVCAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgREVGQVVMVF9UWVBFX0RFRkFVTFQgPSAzOwotCi0gICAgLyoqIERFRkFVTFRfVFlQRV9GSVhFRCAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgREVGQVVMVF9UWVBFX0ZJWEVEID0gMTsKLQotICAgIC8qKiBERUZBVUxUX1RZUEVfSU1QTElFRCAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgREVGQVVMVF9UWVBFX0lNUExJRUQgPSAwOwotCi0gICAgLyoqIERFRkFVTFRfVFlQRV9SRVFVSVJFRCAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgREVGQVVMVF9UWVBFX1JFUVVJUkVEID0gMjsKLQotICAgIC8vCi0gICAgLy8gRGF0YQotICAgIC8vCi0KLSAgICAvKiogdHlwZSAqLwotICAgIHB1YmxpYyBzaG9ydCB0eXBlOwotCi0gICAgLyoqIG5hbWUgKi8KLSAgICBwdWJsaWMgU3RyaW5nIG5hbWU7Ci0KLSAgICAvKiogZW51bWVyYXRpb24gKi8KLSAgICBwdWJsaWMgU3RyaW5nW10gZW51bWVyYXRpb247Ci0KLSAgICAvKiogbGlzdCAqLwotICAgIHB1YmxpYyBib29sZWFuIGxpc3Q7Ci0KLSAgICAvKiogZGVmYXVsdFR5cGUgKi8KLSAgICBwdWJsaWMgc2hvcnQgZGVmYXVsdFR5cGU7Ci0KLSAgICAvKiogZGVmYXVsdFZhbHVlICovCi0gICAgcHVibGljIFN0cmluZyBkZWZhdWx0VmFsdWU7Ci0KLSAgICAvKiogbm9uLW5vcm1hbGl6ZWQgZGVmYXVsdFZhbHVlICovCi0gICAgcHVibGljIFN0cmluZyBub25Ob3JtYWxpemVkRGVmYXVsdFZhbHVlOwotCi0KLSAgICAvLwotICAgIC8vIE1ldGhvZHMKLSAgICAvLwotCi0gICAgLyoqCi0gICAgICogc2V0VmFsdWVzCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdHlwZQotICAgICAqIEBwYXJhbSBuYW1lCi0gICAgICogQHBhcmFtIGVudW1lcmF0aW9uCi0gICAgICogQHBhcmFtIGxpc3QKLSAgICAgKiBAcGFyYW0gZGVmYXVsdFR5cGUKLSAgICAgKiBAcGFyYW0gZGVmYXVsdFZhbHVlCi0gICAgICogQHBhcmFtIG5vbk5vcm1hbGl6ZWREZWZhdWx0VmFsdWUKLSAgICAgKiBAcGFyYW0gZGF0YXR5cGVWYWxpZGF0b3IKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRWYWx1ZXMoc2hvcnQgdHlwZSwgU3RyaW5nIG5hbWUsIFN0cmluZ1tdIGVudW1lcmF0aW9uLAotICAgIGJvb2xlYW4gbGlzdCwgc2hvcnQgZGVmYXVsdFR5cGUsCi0gICAgU3RyaW5nIGRlZmF1bHRWYWx1ZSwgU3RyaW5nIG5vbk5vcm1hbGl6ZWREZWZhdWx0VmFsdWUpewotCi0gICAgICAgIHRoaXMudHlwZSAgICAgICAgICAgICAgPSB0eXBlOwotICAgICAgICB0aGlzLm5hbWUgICAgICAgICAgICAgID0gbmFtZTsKLSAgICAgICAgLy8gUkVWSVNJVDogU2hvdWxkIHRoaXMgYmUgYSBjb3B5PyAtQWMKLSAgICAgICAgaWYgKGVudW1lcmF0aW9uICE9IG51bGwgJiYgZW51bWVyYXRpb24ubGVuZ3RoID4gMCkgewotICAgICAgICAgICAgdGhpcy5lbnVtZXJhdGlvbiA9IG5ldyBTdHJpbmdbZW51bWVyYXRpb24ubGVuZ3RoXTsKLSAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZW51bWVyYXRpb24sIDAsIHRoaXMuZW51bWVyYXRpb24sIDAsIHRoaXMuZW51bWVyYXRpb24ubGVuZ3RoKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIHRoaXMuZW51bWVyYXRpb24gPSBudWxsOwotICAgICAgICB9Ci0gICAgICAgIHRoaXMubGlzdCAgICAgICAgICAgICAgPSBsaXN0OwotICAgICAgICB0aGlzLmRlZmF1bHRUeXBlICAgICAgID0gZGVmYXVsdFR5cGU7Ci0gICAgICAgIHRoaXMuZGVmYXVsdFZhbHVlICAgICAgPSBkZWZhdWx0VmFsdWU7Ci0gICAgICAgIHRoaXMubm9uTm9ybWFsaXplZERlZmF1bHRWYWx1ZSAgICAgID0gbm9uTm9ybWFsaXplZERlZmF1bHRWYWx1ZTsKLQotICAgIH0gLy8gc2V0VmFsdWVzKHNob3J0LFN0cmluZyxTdHJpbmdbXSxib29sZWFuLHNob3J0LFN0cmluZyxTdHJpbmcsRGF0YXR5cGVWYWxpZGF0b3IpCi0KLSAgICAvKiogU2V0IHZhbHVlcy4gKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRWYWx1ZXMoWE1MU2ltcGxlVHlwZSBzaW1wbGVUeXBlKSB7Ci0KLSAgICAgICAgdHlwZSA9IHNpbXBsZVR5cGUudHlwZTsKLSAgICAgICAgbmFtZSA9IHNpbXBsZVR5cGUubmFtZTsKLSAgICAgICAgLy8gUkVWSVNJVDogU2hvdWxkIHRoaXMgYmUgYSBjb3B5PyAtQWMKLSAgICAgICAgaWYgKHNpbXBsZVR5cGUuZW51bWVyYXRpb24gIT0gbnVsbCAmJiBzaW1wbGVUeXBlLmVudW1lcmF0aW9uLmxlbmd0aCA+IDApIHsKLSAgICAgICAgICAgIGVudW1lcmF0aW9uID0gbmV3IFN0cmluZ1tzaW1wbGVUeXBlLmVudW1lcmF0aW9uLmxlbmd0aF07Ci0gICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHNpbXBsZVR5cGUuZW51bWVyYXRpb24sIDAsIGVudW1lcmF0aW9uLCAwLCBlbnVtZXJhdGlvbi5sZW5ndGgpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgZW51bWVyYXRpb24gPSBudWxsOwotICAgICAgICB9Ci0gICAgICAgIGxpc3QgPSBzaW1wbGVUeXBlLmxpc3Q7Ci0gICAgICAgIGRlZmF1bHRUeXBlID0gc2ltcGxlVHlwZS5kZWZhdWx0VHlwZTsKLSAgICAgICAgZGVmYXVsdFZhbHVlID0gc2ltcGxlVHlwZS5kZWZhdWx0VmFsdWU7Ci0gICAgICAgIG5vbk5vcm1hbGl6ZWREZWZhdWx0VmFsdWUgPSBzaW1wbGVUeXBlLm5vbk5vcm1hbGl6ZWREZWZhdWx0VmFsdWU7Ci0KLSAgICB9IC8vIHNldFZhbHVlcyhYTUxTaW1wbGVUeXBlKQotCi0gICAgLyoqCi0gICAgICogY2xlYXIKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBjbGVhcigpIHsKLSAgICAgICAgdGhpcy50eXBlICAgICAgICAgICAgICA9IC0xOwotICAgICAgICB0aGlzLm5hbWUgICAgICAgICAgICAgID0gbnVsbDsKLSAgICAgICAgdGhpcy5lbnVtZXJhdGlvbiAgICAgICA9IG51bGw7Ci0gICAgICAgIHRoaXMubGlzdCAgICAgICAgICAgICAgPSBmYWxzZTsKLSAgICAgICAgdGhpcy5kZWZhdWx0VHlwZSAgICAgICA9IC0xOwotICAgICAgICB0aGlzLmRlZmF1bHRWYWx1ZSAgICAgID0gbnVsbDsKLSAgICAgICAgdGhpcy5ub25Ob3JtYWxpemVkRGVmYXVsdFZhbHVlID0gbnVsbDsKLSAgICB9Ci0KLX0gLy8gY2xhc3MgWE1MU2ltcGxlVHlwZQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4veG1sL2ludGVybmFsL3N0cmVhbS9ldmVudHMvQXR0cmlidXRlSW1wbC5qYXZhIGIvc3JjL2NvbS9zdW4veG1sL2ludGVybmFsL3N0cmVhbS9ldmVudHMvQXR0cmlidXRlSW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzNzJiMmNlLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL3htbC9pbnRlcm5hbC9zdHJlYW0vZXZlbnRzL0F0dHJpYnV0ZUltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE2MSArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDA1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ueG1sLmludGVybmFsLnN0cmVhbS5ldmVudHM7Ci0KLWltcG9ydCBqYXZheC54bWwubmFtZXNwYWNlLlFOYW1lOwotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uZXZlbnRzLkF0dHJpYnV0ZTsKLWltcG9ydCBqYXZhLmlvLldyaXRlcjsKLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLmV2ZW50cy5YTUxFdmVudDsKLQotCi0vL3h4eDogQXR0cmlidXRlRXZlbnQgaXMgbm90IHJlYWxseSBhIGZpcnN0IG9yZGVyIGV2ZW50LiBTaG91bGQgd2UgYmUgcmVuYW1pbmcgdGhlIGNsYXNzIHRvIEF0dHJpYnV0ZUltcGwgZm9yIGNvbnNpc3RlbnQKLS8vbmFtaW5nIGNvbnZlbnRpb24uCi0KLS8qKgotICogSW1wbGVtZW50YXRpb24gb2YgQXR0cmlidXRlIEV2ZW50LgotICoKLSAqQGF1dGhvciBOZWVyYWogQmFqYWosIFN1biBNaWNyb3N5c3RlbXMKLSAqQGF1dGhvciBLLlZlbnVnb3BhbCwgU3VuIE1pY3Jvc3lzdGVtcwotICoKLSAqLwotCi1wdWJsaWMgY2xhc3MgQXR0cmlidXRlSW1wbCBleHRlbmRzIER1bW15RXZlbnQgaW1wbGVtZW50cyBBdHRyaWJ1dGUKLQotewotICAgIC8vYXR0cmlidXRlIHZhbHVlCi0gICAgcHJpdmF0ZSBTdHJpbmcgZlZhbHVlOwotICAgIHByaXZhdGUgU3RyaW5nIGZOb25Ob3JtYWxpemVkdmFsdWU7Ci0KLSAgICAvL25hbWUgb2YgdGhlIGF0dHJpYnV0ZQotICAgIHByaXZhdGUgUU5hbWUgZlFOYW1lOwotICAgIC8vYXR0cmlidXRlIHR5cGUKLSAgICBwcml2YXRlIFN0cmluZyBmQXR0cmlidXRlVHlwZSA9ICJDREFUQSI7Ci0KLQotICAgIC8vQSBmbGFnIGluZGljYXRpbmcgd2hldGhlciB0aGlzIGF0dHJpYnV0ZSB3YXMgYWN0dWFsbHkgc3BlY2lmaWVkIGluIHRoZSBzdGFydC10YWcKLSAgICAvL29mIGl0cyBlbGVtZW50IG9yIHdhcyBkZWZhdWx0ZWQgZnJvbSB0aGUgc2NoZW1hLgotICAgIHByaXZhdGUgYm9vbGVhbiBmSXNTcGVjaWZpZWQ7Ci0KLSAgICBwdWJsaWMgQXR0cmlidXRlSW1wbCgpewotICAgICAgICBpbml0KCk7Ci0gICAgfQotICAgIHB1YmxpYyBBdHRyaWJ1dGVJbXBsKFN0cmluZyBuYW1lLCBTdHJpbmcgdmFsdWUpIHsKLSAgICAgICAgaW5pdCgpOwotICAgICAgICBmUU5hbWUgPSBuZXcgUU5hbWUobmFtZSk7Ci0gICAgICAgIGZWYWx1ZSA9IHZhbHVlOwotICAgIH0KLQotICAgIHB1YmxpYyBBdHRyaWJ1dGVJbXBsKFN0cmluZyBwcmVmaXgsIFN0cmluZyBuYW1lLCBTdHJpbmcgdmFsdWUpIHsKLSAgICAgICAgdGhpcyhwcmVmaXgsIG51bGwsbmFtZSwgdmFsdWUsIG51bGwsbnVsbCxmYWxzZSApOwotICAgIH0KLQotICAgIHB1YmxpYyBBdHRyaWJ1dGVJbXBsKFN0cmluZyBwcmVmaXgsIFN0cmluZyB1cmksIFN0cmluZyBsb2NhbFBhcnQsIFN0cmluZyB2YWx1ZSwgU3RyaW5nIHR5cGUpIHsKLSAgICAgICAgdGhpcyhwcmVmaXgsIHVyaSwgbG9jYWxQYXJ0LCB2YWx1ZSwgbnVsbCwgdHlwZSwgZmFsc2UpOwotICAgIH0KLQotICAgIHB1YmxpYyBBdHRyaWJ1dGVJbXBsKFN0cmluZyBwcmVmaXgsIFN0cmluZyB1cmksIFN0cmluZyBsb2NhbFBhcnQsIFN0cmluZyB2YWx1ZSwgU3RyaW5nIG5vbk5vcm1hbGl6ZWR2YWx1ZSwgU3RyaW5nIHR5cGUsIGJvb2xlYW4gaXNTcGVjaWZpZWQpIHsKLSAgICAgICAgdGhpcyhuZXcgUU5hbWUodXJpLCBsb2NhbFBhcnQsIHByZWZpeCksIHZhbHVlLCBub25Ob3JtYWxpemVkdmFsdWUsIHR5cGUsIGlzU3BlY2lmaWVkKTsKLSAgICB9Ci0KLQotICAgIHB1YmxpYyBBdHRyaWJ1dGVJbXBsKFFOYW1lIHFuYW1lLCBTdHJpbmcgdmFsdWUsIFN0cmluZyBub25Ob3JtYWxpemVkdmFsdWUsIFN0cmluZyB0eXBlLCBib29sZWFuIGlzU3BlY2lmaWVkKSB7Ci0gICAgICAgIGluaXQoKTsKLSAgICAgICAgZlFOYW1lID0gcW5hbWUgOwotICAgICAgICBmVmFsdWUgPSB2YWx1ZSA7Ci0gICAgICAgIGlmKHR5cGUgIT0gbnVsbCAmJiAhdHlwZS5lcXVhbHMoIiIpKQotICAgICAgICAgICAgZkF0dHJpYnV0ZVR5cGUgPSB0eXBlOwotCi0gICAgICAgIGZOb25Ob3JtYWxpemVkdmFsdWUgPSBub25Ob3JtYWxpemVkdmFsdWU7Ci0gICAgICAgIGZJc1NwZWNpZmllZCA9IGlzU3BlY2lmaWVkIDsKLQotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0gICAgICAgIGlmKCBmUU5hbWUuZ2V0UHJlZml4KCkgIT0gbnVsbCAmJiBmUU5hbWUuZ2V0UHJlZml4KCkubGVuZ3RoKCkgPiAwICkKLSAgICAgICAgICAgIHJldHVybiBmUU5hbWUuZ2V0UHJlZml4KCkgKyAiOiIgKyBmUU5hbWUuZ2V0TG9jYWxQYXJ0KCkgKyAiPSciICsgZlZhbHVlICsgIiciOwotICAgICAgICBlbHNlCi0gICAgICAgICAgICByZXR1cm4gZlFOYW1lLmdldExvY2FsUGFydCgpICsgIj0nIiArIGZWYWx1ZSArICInIjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXROYW1lKFFOYW1lIG5hbWUpewotICAgICAgICBmUU5hbWUgPSBuYW1lIDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgUU5hbWUgZ2V0TmFtZSgpIHsKLSAgICAgICAgcmV0dXJuIGZRTmFtZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRWYWx1ZShTdHJpbmcgdmFsdWUpewotICAgICAgICBmVmFsdWUgPSB2YWx1ZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldFZhbHVlKCkgewotICAgICAgICByZXR1cm4gZlZhbHVlOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldE5vbk5vcm1hbGl6ZWRWYWx1ZShTdHJpbmcgbm9uTm9ybWFsaXplZHZhbHVlKXsKLSAgICAgICAgZk5vbk5vcm1hbGl6ZWR2YWx1ZSA9IG5vbk5vcm1hbGl6ZWR2YWx1ZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldE5vbk5vcm1hbGl6ZWRWYWx1ZSgpewotICAgICAgICByZXR1cm4gZk5vbk5vcm1hbGl6ZWR2YWx1ZSA7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0QXR0cmlidXRlVHlwZShTdHJpbmcgYXR0cmlidXRlVHlwZSl7Ci0gICAgICAgIGZBdHRyaWJ1dGVUeXBlID0gYXR0cmlidXRlVHlwZSA7Ci0gICAgfQotCi0gICAgLyoqIEdldHMgdGhlIHR5cGUgb2YgdGhpcyBhdHRyaWJ1dGUsIGRlZmF1bHQgaXMgIkNEQVRBICAgKi8KLSAgICAvLyBXZSBkb250IG5lZWQgdG8gdGFrZSBjYXJlIG9mIGRlZmF1bHQgdmFsdWUuLiBpbXBsZW1lbnRhdGlvbiB0YWtlcyBjYXJlIG9mIGl0LgotICAgIHB1YmxpYyBTdHJpbmcgZ2V0RFREVHlwZSgpIHsKLSAgICAgICAgcmV0dXJuIGZBdHRyaWJ1dGVUeXBlOwotICAgIH0KLQotICAgIC8qKiBpcyB0aGlzIGF0dHJpYnV0ZSBpcyBzcGVjaWZpZWQgaW4gdGhlIGluc3RhbmNlIGRvY3VtZW50ICovCi0KLSAgICBwdWJsaWMgdm9pZCBzZXRTcGVjaWZpZWQoYm9vbGVhbiBpc1NwZWNpZmllZCl7Ci0gICAgICAgIGZJc1NwZWNpZmllZCA9IGlzU3BlY2lmaWVkIDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBpc1NwZWNpZmllZCgpIHsKLSAgICAgICAgcmV0dXJuIGZJc1NwZWNpZmllZCA7Ci0gICAgfQotCi0gICAgcHJvdGVjdGVkIHZvaWQgd3JpdGVBc0VuY29kZWRVbmljb2RlRXgoamF2YS5pby5Xcml0ZXIgd3JpdGVyKQotICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uCi0gICAgewotICAgICAgICB3cml0ZXIud3JpdGUodG9TdHJpbmcoKSk7Ci0gICAgIH0KLQotCi0gICAgcHJvdGVjdGVkIHZvaWQgaW5pdCgpewotICAgICAgICBzZXRFdmVudFR5cGUoWE1MRXZlbnQuQVRUUklCVVRFKTsKLSAgICB9Ci0KLQotCi0KLX0vL0F0dHJpYnV0ZUltcGwKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL3htbC9pbnRlcm5hbC9zdHJlYW0vZXZlbnRzL0NoYXJhY3RlckV2ZW50LmphdmEgYi9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL2V2ZW50cy9DaGFyYWN0ZXJFdmVudC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyMTdkOTBlLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL3htbC9pbnRlcm5hbC9zdHJlYW0vZXZlbnRzL0NoYXJhY3RlckV2ZW50LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxOTYgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLnhtbC5pbnRlcm5hbC5zdHJlYW0uZXZlbnRzIDsKLQotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uZXZlbnRzLkNoYXJhY3RlcnM7Ci1pbXBvcnQgamF2YS5pby5Xcml0ZXI7Ci1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLmV2ZW50cy5YTUxFdmVudDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuWE1MQ2hhcjsKLQotLyoqIEltcGxlbWVudGF0aW9uIG9mIENoYXJhY3RlciBldmVudC4KLSAqCi0gKkBhdXRob3IgTmVlcmFqIEJhamFqLCBTdW4gTWljcm9zeXN0ZW1zCi0gKkBhdXRob3IgSy5WZW51Z29wYWwsIFN1biBNaWNyb3N5c3RlbXMKLSAqCi0gKi8KLQotcHVibGljIGNsYXNzIENoYXJhY3RlckV2ZW50IGV4dGVuZHMgRHVtbXlFdmVudAotaW1wbGVtZW50cyBDaGFyYWN0ZXJzIHsKLSAgICAvKiBkYXRhICovCi0gICAgcHJpdmF0ZSBTdHJpbmcgZkRhdGE7Ci0gICAgLyp0cnVlIGlmIGZEYXRhIGlzIENEYXRhICovCi0gICAgcHJpdmF0ZSBib29sZWFuIGZJc0NEYXRhOwotICAgIC8qIHRydWUgaWYgZkRhdGEgaXMgaWdub3JhYmxlV2hpdGVzcGFjZSovCi0gICAgcHJpdmF0ZSBib29sZWFuIGZJc0lnbm9yYWJsZVdoaXRlc3BhY2U7Ci0gICAgLyogdHJ1ZSBpZiBmRGF0YSBjb250ZXQgaXMgd2hpdGVzcGFjZSovCi0gICAgcHJpdmF0ZSBib29sZWFuIGZJc1NwYWNlID0gZmFsc2U7Ci0gICAgLyp1c2VkIHRvIHByZXZlbnQgc2Nhbm5pbmcgb2YgIGRhdGEgbXVsdGlwbGUgdGltZXMgKi8KLSAgICBwcml2YXRlIGJvb2xlYW4gZkNoZWNrSWZTcGFjZU5lZWRlZCA9IHRydWU7Ci0KLSAgICBwdWJsaWMgQ2hhcmFjdGVyRXZlbnQoKSB7Ci0gICAgICAgIGZJc0NEYXRhID0gZmFsc2U7Ci0gICAgICAgIGluaXQoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKgotICAgICAqIEBwYXJhbSBkYXRhIENoYXJhY3RlciBEYXRhLgotICAgICAqLwotICAgIHB1YmxpYyBDaGFyYWN0ZXJFdmVudChTdHJpbmcgZGF0YSkgewotICAgICAgICBmSXNDRGF0YSA9IGZhbHNlOwotICAgICAgICBpbml0KCk7Ci0gICAgICAgIGZEYXRhID0gZGF0YTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKgotICAgICAqIEBwYXJhbSBkYXRhIENoYXJhY3RlciBEYXRhLgotICAgICAqIEBwYXJhbSBmbGFnIHRydWUgaWYgQ0RhdGEKLSAgICAgKi8KLSAgICBwdWJsaWMgQ2hhcmFjdGVyRXZlbnQoU3RyaW5nIGRhdGEsIGJvb2xlYW4gZmxhZykgewotICAgICAgICBpbml0KCk7Ci0gICAgICAgIGZEYXRhID0gZGF0YTsKLSAgICAgICAgZklzQ0RhdGEgPSBmbGFnOwotICAgIH0KLQotICAgIC8qKgotICAgICAqCi0gICAgICogQHBhcmFtIGRhdGEgQ2hhcmFjdGVyIERhdGEuCi0gICAgICogQHBhcmFtIGZsYWcgdHJ1ZSBpZiBDRGF0YQotICAgICAqIEBwYXJhbSBpc0lnbm9yYWJsZVdoaXRlU3BhY2UgdHJ1ZSBpZiBkYXRhIGlzIGlnbm9yYWJsZSB3aGl0ZXNwYWNlLgotICAgICAqLwotICAgIHB1YmxpYyBDaGFyYWN0ZXJFdmVudChTdHJpbmcgZGF0YSwgYm9vbGVhbiBmbGFnLCBib29sZWFuIGlzSWdub3JhYmxlV2hpdGVTcGFjZSkgewotICAgICAgICBpbml0KCk7Ci0gICAgICAgIGZEYXRhID0gZGF0YTsKLSAgICAgICAgZklzQ0RhdGEgPSBmbGFnOwotICAgICAgICBmSXNJZ25vcmFibGVXaGl0ZXNwYWNlID0gaXNJZ25vcmFibGVXaGl0ZVNwYWNlIDsKLSAgICB9Ci0KLSAgICBwcm90ZWN0ZWQgdm9pZCBpbml0KCkgewotICAgICAgICBzZXRFdmVudFR5cGUoWE1MRXZlbnQuQ0hBUkFDVEVSUyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHJldHVybiBkYXRhLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0RGF0YSgpIHsKLSAgICAgICAgcmV0dXJuIGZEYXRhOwotICAgIH0KLQotICAgIC8qKgotICAgICAqCi0gICAgICogQHBhcmFtIFN0cmluZyBkYXRhCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RGF0YShTdHJpbmcgZGF0YSl7Ci0gICAgICAgIGZEYXRhID0gZGF0YTsKLSAgICAgICAgZkNoZWNrSWZTcGFjZU5lZWRlZCA9IHRydWU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIGJvb2xlYW4gcmV0dXJucyB0cnVlIGlmIHRoZSBkYXRhIGlzIENEYXRhCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNDRGF0YSgpIHsKLSAgICAgICAgcmV0dXJuIGZJc0NEYXRhOwotICAgIH0KLQotICAgIC8qKgotICAgICAqCi0gICAgICogQHJldHVybiBTdHJpbmcgcmV0dXJuIHRoZSBTdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBldmVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgICAgICBpZihmSXNDRGF0YSkKLSAgICAgICAgICAgIHJldHVybiAiPCFbQ0RBVEFbIiArIGdldERhdGEoKSArICJdXT4iOwotICAgICAgICBlbHNlCi0gICAgICAgICAgICByZXR1cm4gZkRhdGE7Ci0gICAgfQotCi0gICAgLyoqIFRoaXMgbWV0aG9kIHdpbGwgd3JpdGUgdGhlIFhNTEV2ZW50IGFzIHBlciB0aGUgWE1MIDEuMCBzcGVjaWZpY2F0aW9uIGFzIFVuaWNvZGUgY2hhcmFjdGVycy4KLSAgICAgKiBObyBpbmRlbnRhdGlvbiBvciB3aGl0ZXNwYWNlIHNob3VsZCBiZSBvdXRwdXR0ZWQuCi0gICAgICoKLSAgICAgKiBBbnkgdXNlciBkZWZpbmVkIGV2ZW50IHR5cGUgU0hBTEwgaGF2ZSB0aGlzIG1ldGhvZAotICAgICAqIGNhbGxlZCB3aGVuIGJlaW5nIHdyaXR0ZW4gdG8gb24gYW4gb3V0cHV0IHN0cmVhbS4KLSAgICAgKiBCdWlsdCBpbiBFdmVudCB0eXBlcyBNVVNUIGltcGxlbWVudCB0aGlzIG1ldGhvZCwKLSAgICAgKiBidXQgaW1wbGVtZW50YXRpb25zIE1BWSBjaG9vc2Ugbm90IGNhbGwgdGhlc2UgbWV0aG9kcwotICAgICAqIGZvciBvcHRpbWl6YXRpb25zIHJlYXNvbnMgd2hlbiB3cml0aW5nIG91dCBidWlsdCBpbgotICAgICAqIEV2ZW50cyB0byBhbiBvdXRwdXQgc3RyZWFtLgotICAgICAqIFRoZSBvdXRwdXQgZ2VuZXJhdGVkIE1VU1QgYmUgZXF1aXZhbGVudCBpbiB0ZXJtcyBvZiB0aGUKLSAgICAgKiBpbmZvc2V0IGV4cHJlc3NlZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSB3cml0ZXIgVGhlIHdyaXRlciB0aGF0IHdpbGwgb3V0cHV0IHRoZSBkYXRhCi0gICAgICogQHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24gaWYgdGhlcmUgaXMgYSBmYXRhbCBlcnJvciB3cml0aW5nIHRoZSBldmVudAotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIHdyaXRlQXNFbmNvZGVkVW5pY29kZUV4KFdyaXRlciB3cml0ZXIpIHRocm93cyBJT0V4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaWYgKGZJc0NEYXRhKSB7Ci0gICAgICAgICAgICB3cml0ZXIud3JpdGUoIjwhW0NEQVRBWyIgKyBnZXREYXRhKCkgKyAiXV0+Iik7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBjaGFyRW5jb2RlKHdyaXRlciwgZkRhdGEpOwotICAgICAgICB9Ci0gICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybiB0cnVlIGlmIHRoaXMgaXMgaWdub3JhYmxlV2hpdGVTcGFjZS4gIElmCi0gICAgICogdGhpcyBldmVudCBpcyBpZ25vcmFibGVXaGl0ZVNwYWNlIGl0cyBldmVudCB0eXBlIHdpbGwKLSAgICAgKiBiZSBTUEFDRS4KLSAgICAgKiBAcmV0dXJuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNJZ25vcmFibGVXaGl0ZVNwYWNlKCkgewotICAgICAgICByZXR1cm4gZklzSWdub3JhYmxlV2hpdGVzcGFjZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhpcyBzZXQgb2YgQ2hhcmFjdGVycwotICAgICAqIGlzIGFsbCB3aGl0ZXNwYWNlLiAgV2hpdHNwYWNlIGluc2lkZSBhIGRvY3VtZW50Ci0gICAgICogaXMgcmVwb3J0ZWQgYXMgQ0hBUkFDVEVSUy4gIFRoaXMgbWV0aG9kIGFsbG93cwotICAgICAqIGNoZWNraW5nIG9mIENIQVJBQ1RFUlMgZXZlbnRzIHRvIHNlZSBpZiB0aGV5Ci0gICAgICogYXJlIGNvbXBvc2VkIG9mIG9ubHkgd2hpdGVzcGFjZSBjaGFyYWN0ZXJzCi0gICAgICogQHJldHVybgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzV2hpdGVTcGFjZSgpIHsKLSAgICAgICAgLy9ubyBzeW5jaHJvbml6YXRpb24gY2hlY2tzIG1hZGUuCi0gICAgICAgIGlmKGZDaGVja0lmU3BhY2VOZWVkZWQpewotICAgICAgICAgICAgY2hlY2tXaGl0ZVNwYWNlKCk7Ci0gICAgICAgICAgICBmQ2hlY2tJZlNwYWNlTmVlZGVkID0gZmFsc2U7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGZJc1NwYWNlOwotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBjaGVja1doaXRlU3BhY2UoKXsKLSAgICAgICAgLy9mb3Igbm93IC0gcmVtb3ZlIGRlcGVuZGFuY3kgb2YgWE1MQ2hhcgotICAgICAgICBpZihmRGF0YSAhPSBudWxsICYmIGZEYXRhLmxlbmd0aCgpID4wICl7Ci0gICAgICAgICAgICBmSXNTcGFjZSA9IHRydWU7Ci0gICAgICAgICAgICBmb3IoaW50IGk9MDtpPGZEYXRhLmxlbmd0aCgpO2krKyl7Ci0gICAgICAgICAgICAgICAgaWYoIVhNTENoYXIuaXNTcGFjZShmRGF0YS5jaGFyQXQoaSkpKXsKLSAgICAgICAgICAgICAgICAgICAgZklzU3BhY2UgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4veG1sL2ludGVybmFsL3N0cmVhbS9ldmVudHMvQ29tbWVudEV2ZW50LmphdmEgYi9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL2V2ZW50cy9Db21tZW50RXZlbnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNjE3YjNkMi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL2V2ZW50cy9Db21tZW50RXZlbnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDc2ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi54bWwuaW50ZXJuYWwuc3RyZWFtLmV2ZW50cyA7Ci0KLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLmV2ZW50cy5Db21tZW50OwotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uZXZlbnRzLlhNTEV2ZW50OwotCi0vKioKLSAqIFRoaXMgY2xhc3MgY29udGFpbnMgaW5mb3JtYXRpb24gYWJvdXQgQ29tbWVudCBldmVudC4KLSAqCi0gKiBAYXV0aG9yIE5lZXJhaiBCYWphaiwgU3VuIE1pY3Jvc3lzdGVtcy4KLSAqLwotcHVibGljIGNsYXNzIENvbW1lbnRFdmVudCBleHRlbmRzIER1bW15RXZlbnQgaW1wbGVtZW50cyBDb21tZW50IHsKLQotICAgIC8qIFN0cmluZyBkYXRhIGZvciB0aGlzIGV2ZW50ICovCi0gICAgcHJpdmF0ZSBTdHJpbmcgZlRleHQgOwotCi0gICAgcHVibGljIENvbW1lbnRFdmVudCgpIHsKLSAgICAgICAgaW5pdCgpOwotICAgIH0KLQotICAgIHB1YmxpYyBDb21tZW50RXZlbnQoU3RyaW5nIHRleHQpIHsKLSAgICAgICAgaW5pdCgpOwotICAgICAgICBmVGV4dCA9IHRleHQ7Ci0gICAgfQotCi0gICAgcHJvdGVjdGVkIHZvaWQgaW5pdCgpIHsKLSAgICAgICAgc2V0RXZlbnRUeXBlKFhNTEV2ZW50LkNPTU1FTlQpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEByZXR1cm4gU3RyaW5nIFN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIGV2ZW50Ci0gICAgICovCi0gICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKLSAgICAgICAgcmV0dXJuICI8IS0tIiArIGdldFRleHQoKSArICItLT4iOwotICAgIH0KLQotCi0gICAgLyoqIFJldHVybiB0aGUgc3RyaW5nIGRhdGEgb2YgdGhlIGNvbW1lbnQsIHJldHVybnMgZW1wdHkgc3RyaW5nIGlmIGl0Ci0gICAgICogZG9lcyBub3QgZXhpc3QKLSAgICAgKiBAcmV0dXJuIFN0cmluZwotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VGV4dCgpIHsKLSAgICAgICAgcmV0dXJuIGZUZXh0IDsKLSAgICB9Ci0KLSAgICBwcm90ZWN0ZWQgdm9pZCB3cml0ZUFzRW5jb2RlZFVuaWNvZGVFeChqYXZhLmlvLldyaXRlciB3cml0ZXIpCi0gICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIHdyaXRlci53cml0ZSgiPCEtLSIgKyBnZXRUZXh0KCkgKyAiLS0+Iik7Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL2V2ZW50cy9EVERFdmVudC5qYXZhIGIvc3JjL2NvbS9zdW4veG1sL2ludGVybmFsL3N0cmVhbS9ldmVudHMvRFRERXZlbnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOWI4MTUyMC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL2V2ZW50cy9EVERFdmVudC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTA0ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi54bWwuaW50ZXJuYWwuc3RyZWFtLmV2ZW50czsKLQotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uZXZlbnRzLkRURDsKLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLmV2ZW50cy5YTUxFdmVudDsKLQotLyoqCi0gKgotICogQGF1dGhvciAgTmVlcmFqIEJhamFqLCBTdW4gTWljcm9zeXN0ZXNtLgotICoKLSAqLwotcHVibGljIGNsYXNzIERUREV2ZW50IGV4dGVuZHMgRHVtbXlFdmVudCBpbXBsZW1lbnRzIERURHsKLQotICAgIHByaXZhdGUgU3RyaW5nIGZEb2N0eXBlRGVjbGFyYXRpb247Ci0gICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdCBmTm90YXRpb25zOwotICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3QgZkVudGl0aWVzOwotCi0gICAgLyoqIENyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgRFRERXZlbnQgKi8KLSAgICBwdWJsaWMgRFRERXZlbnQoKSB7Ci0gICAgICAgIGluaXQoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgRFRERXZlbnQoU3RyaW5nIGRvY3R5cGVEZWNsYXJhdGlvbil7Ci0gICAgICAgIGluaXQoKTsKLSAgICAgICAgZkRvY3R5cGVEZWNsYXJhdGlvbiA9IGRvY3R5cGVEZWNsYXJhdGlvbjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXREb2N1bWVudFR5cGVEZWNsYXJhdGlvbihTdHJpbmcgZG9jdHlwZURlY2xhcmF0aW9uKXsKLSAgICAgICAgZkRvY3R5cGVEZWNsYXJhdGlvbiA9IGRvY3R5cGVEZWNsYXJhdGlvbjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldERvY3VtZW50VHlwZURlY2xhcmF0aW9uKCkgewotICAgICAgICByZXR1cm4gZkRvY3R5cGVEZWNsYXJhdGlvbjsKLSAgICB9Ci0KLSAgICAvL3h4eDogd2UgY2FuIGNoYW5nZSB0aGUgc2lnbmF0dXJlIGlmIHRoZSBpbXBsZW1lbnRhdGlvbiBkb2Vzbid0IHN0b3JlIHRoZSBlbnRpdGllcyBpbiBMaXN0IERhdGF0eXBlLgotICAgIC8vYW5kIHRoZW4gY29udmVydCB0aGF0IERUIHRvIGxpc3QgZm9ybWF0IGhlcmUuIFRoYXQgd2F5IGNhbGxlZSBkb250IG5lZWQgdG8gYm90aGVyIGFib3V0IGNvbnZlcnNpb24KLQotICAgIHB1YmxpYyB2b2lkIHNldEVudGl0aWVzKGphdmEudXRpbC5MaXN0IGVudGl0ZXMpewotICAgICAgICBmRW50aXRpZXMgPSBlbnRpdGVzOwotICAgIH0KLQotICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdCBnZXRFbnRpdGllcygpIHsKLSAgICAgICAgcmV0dXJuIGZFbnRpdGllczsKLSAgICB9Ci0KLSAgICAvL3h4eDogd2UgY2FuIGNoYW5nZSB0aGUgc2lnbmF0dXJlIGlmIHRoZSBpbXBsZW1lbnRhdGlvbiBkb2Vzbid0IHN0b3JlIHRoZSBlbnRpdGllcyBpbiBMaXN0IERhdGF0eXBlLgotICAgIC8vYW5kIHRoZW4gY29udmVydCB0aGF0IERUIHRvIGxpc3QgZm9ybWF0IGhlcmUuIFRoYXQgd2F5IGNhbGxlZSBkb250IG5lZWQgdG8gYm90aGVyIGFib3V0IGNvbnZlcnNpb24KLQotICAgIHB1YmxpYyB2b2lkIHNldE5vdGF0aW9ucyhqYXZhLnV0aWwuTGlzdCBub3RhdGlvbnMpewotICAgICAgICBmTm90YXRpb25zID0gbm90YXRpb25zOwotICAgIH0KLQotICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdCBnZXROb3RhdGlvbnMoKSB7Ci0gICAgICAgIHJldHVybiBmTm90YXRpb25zOwotICAgIH0KLQotICAgIC8qKgotICAgICAqUmV0dXJucyBhbiBpbXBsZW1lbnRhdGlvbiBkZWZpbmVkIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBEVEQuCi0gICAgICogVGhpcyBtZXRob2QgbWF5IHJldHVybiBudWxsIGlmIG5vIHJlcHJlc2VudGF0aW9uIGlzIGF2YWlsYWJsZS4KLSAgICAgKgotICAgICAqLwotICAgIHB1YmxpYyBPYmplY3QgZ2V0UHJvY2Vzc2VkRFREKCkgewotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICBwcm90ZWN0ZWQgdm9pZCBpbml0KCl7Ci0gICAgICAgIHNldEV2ZW50VHlwZShYTUxFdmVudC5EVEQpOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKXsKLSAgICAgICAgcmV0dXJuIGZEb2N0eXBlRGVjbGFyYXRpb24gOwotICAgIH0KLQotICAgIHByb3RlY3RlZCB2b2lkIHdyaXRlQXNFbmNvZGVkVW5pY29kZUV4KGphdmEuaW8uV3JpdGVyIHdyaXRlcikKLSAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgd3JpdGVyLndyaXRlKGZEb2N0eXBlRGVjbGFyYXRpb24pOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL3htbC9pbnRlcm5hbC9zdHJlYW0vZXZlbnRzL0R1bW15RXZlbnQuamF2YSBiL3NyYy9jb20vc3VuL3htbC9pbnRlcm5hbC9zdHJlYW0vZXZlbnRzL0R1bW15RXZlbnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYTkxOGE5Yy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL2V2ZW50cy9EdW1teUV2ZW50LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyNTggKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLnhtbC5pbnRlcm5hbC5zdHJlYW0uZXZlbnRzIDsKLQotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci1pbXBvcnQgamF2YS5pby5Xcml0ZXI7Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5ldmVudHMuWE1MRXZlbnQ7Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5ldmVudHMuQ2hhcmFjdGVyczsKLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLmV2ZW50cy5FbmRFbGVtZW50OwotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uZXZlbnRzLlN0YXJ0RWxlbWVudDsKLWltcG9ydCBqYXZheC54bWwubmFtZXNwYWNlLlFOYW1lOwotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uTG9jYXRpb247Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5YTUxTdHJlYW1FeGNlcHRpb247Ci0KLS8qKiBEdW1teUV2ZW50IGlzIGFuIGFic3RyYWN0IGNsYXNzLiBJdCBwcm92aWRlcyBmdW5jdGlvbmFsaXR5IGZvciBtb3N0IG9mIHRoZQotICogZnVuY3Rpb24gb2YgWE1MRXZlbnQuCi0gKgotICogQGF1dGhvciBOZWVyYWogQmFqYWogU3VuIE1pY3Jvc3lzdGVtcyxJbmMuCi0gKiBAYXV0aG9yIEsuVmVudWdvcGFsIFN1biBNaWNyb3N5c3RlbXMsSW5jLgotICoKLSAqLwotCi1wdWJsaWMgYWJzdHJhY3QgY2xhc3MgRHVtbXlFdmVudCBpbXBsZW1lbnRzIFhNTEV2ZW50IHsKLSAgICAvLyBNYWtlIHN1cmUgdGhhdCBnZXRMb2NhdGlvbigpIG5ldmVyIHJldHVybnMgbnVsbC4gSW5zdGVhZCwgcmV0dXJuIHRoaXMgZHVtbXkgbG9jYXRpb24KLSAgICAvLyB0aGF0IGluZGljYXRlcyAibm93aGVyZSIgYXMgZWZmZWN0aXZlbHkgYXMgcG9zc2libGUuCi0gICAgcHJpdmF0ZSBzdGF0aWMgRHVtbXlMb2NhdGlvbiBub3doZXJlID0gbmV3IER1bW15TG9jYXRpb24oKTsKLQotICAgIC8qIEV2ZW50IHR5cGUgdGhpcyBldmVudCBjb3JyZXNwb25kcyB0byAqLwotICAgIHByaXZhdGUgaW50IGZFdmVudFR5cGU7Ci0gICAgcHJvdGVjdGVkIExvY2F0aW9uIGZMb2NhdGlvbiA9IChMb2NhdGlvbikgbm93aGVyZTsKLQotICAgIHB1YmxpYyBEdW1teUV2ZW50KCkgewotICAgIH0KLQotICAgIHB1YmxpYyBEdW1teUV2ZW50KGludCBpKSB7Ci0gICAgICAgIGZFdmVudFR5cGUgPSBpOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgZ2V0RXZlbnRUeXBlKCkgewotICAgICAgICByZXR1cm4gZkV2ZW50VHlwZTsKLSAgICB9Ci0KLSAgICBwcm90ZWN0ZWQgdm9pZCBzZXRFdmVudFR5cGUoaW50IGV2ZW50VHlwZSl7Ci0gICAgICAgIGZFdmVudFR5cGUgPSBldmVudFR5cGU7Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgYm9vbGVhbiBpc1N0YXJ0RWxlbWVudCgpIHsKLSAgICAgICAgcmV0dXJuIGZFdmVudFR5cGUgPT0gWE1MRXZlbnQuU1RBUlRfRUxFTUVOVDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0VuZEVsZW1lbnQoKSB7Ci0gICAgICAgIHJldHVybiBmRXZlbnRUeXBlID09IFhNTEV2ZW50LkVORF9FTEVNRU5UOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGlzRW50aXR5UmVmZXJlbmNlKCkgewotICAgICAgICByZXR1cm4gZkV2ZW50VHlwZSA9PSBYTUxFdmVudC5FTlRJVFlfUkVGRVJFTkNFOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGlzUHJvY2Vzc2luZ0luc3RydWN0aW9uKCkgewotICAgICAgICByZXR1cm4gZkV2ZW50VHlwZSA9PSBYTUxFdmVudC5QUk9DRVNTSU5HX0lOU1RSVUNUSU9OOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGlzQ2hhcmFjdGVyRGF0YSgpIHsKLSAgICAgICAgcmV0dXJuIGZFdmVudFR5cGUgPT0gWE1MRXZlbnQuQ0hBUkFDVEVSUzsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBpc1N0YXJ0RG9jdW1lbnQoKSB7Ci0gICAgICAgIHJldHVybiBmRXZlbnRUeXBlID09IFhNTEV2ZW50LlNUQVJUX0RPQ1VNRU5UOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGlzRW5kRG9jdW1lbnQoKSB7Ci0gICAgICAgIHJldHVybiBmRXZlbnRUeXBlID09IFhNTEV2ZW50LkVORF9ET0NVTUVOVDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgTG9jYXRpb24gZ2V0TG9jYXRpb24oKXsKLSAgICAgICAgcmV0dXJuIGZMb2NhdGlvbjsKLSAgICB9Ci0KLSAgICB2b2lkIHNldExvY2F0aW9uKExvY2F0aW9uIGxvYyl7Ci0gICAgICAgIGlmIChsb2MgPT0gbnVsbCkgewotICAgICAgICAgICAgZkxvY2F0aW9uID0gbm93aGVyZTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIGZMb2NhdGlvbiA9IGxvYzsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKiBSZXR1cm5zIHRoaXMgZXZlbnQgYXMgQ2hhcmFjdGVycywgbWF5IHJlc3VsdCBpbgotICAgICAqIGEgY2xhc3MgY2FzdCBleGNlcHRpb24gaWYgdGhpcyBldmVudCBpcyBub3QgQ2hhcmFjdGVycy4KLSAgICAgKi8KLSAgICBwdWJsaWMgQ2hhcmFjdGVycyBhc0NoYXJhY3RlcnMoKSB7Ci0gICAgICAgIHJldHVybiAoQ2hhcmFjdGVycyl0aGlzOwotICAgIH0KLQotICAgIC8qKiBSZXR1cm5zIHRoaXMgZXZlbnQgYXMgYW4gZW5kICBlbGVtZW50IGV2ZW50LCBtYXkgcmVzdWx0IGluCi0gICAgICogYSBjbGFzcyBjYXN0IGV4Y2VwdGlvbiBpZiB0aGlzIGV2ZW50IGlzIG5vdCBhIGVuZCBlbGVtZW50LgotICAgICAqLwotICAgIHB1YmxpYyBFbmRFbGVtZW50IGFzRW5kRWxlbWVudCgpIHsKLSAgICAgICAgcmV0dXJuIChFbmRFbGVtZW50KXRoaXM7Ci0gICAgfQotCi0gICAgLyoqIFJldHVybnMgdGhpcyBldmVudCBhcyBhIHN0YXJ0IGVsZW1lbnQgZXZlbnQsIG1heSByZXN1bHQgaW4KLSAgICAgKiBhIGNsYXNzIGNhc3QgZXhjZXB0aW9uIGlmIHRoaXMgZXZlbnQgaXMgbm90IGEgc3RhcnQgZWxlbWVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RhcnRFbGVtZW50IGFzU3RhcnRFbGVtZW50KCkgewotICAgICAgICByZXR1cm4gKFN0YXJ0RWxlbWVudCl0aGlzOwotICAgIH0KLQotICAgIC8qKiBUaGlzIG1ldGhvZCBpcyBwcm92aWRlZCBmb3IgaW1wbGVtZW50YXRpb25zIHRvIHByb3ZpZGUKLSAgICAgKiBvcHRpb25hbCB0eXBlIGluZm9ybWF0aW9uIGFib3V0IHRoZSBhc3NvY2lhdGVkIGV2ZW50LgotICAgICAqIEl0IGlzIG9wdGlvbmFsIGFuZCB3aWxsIHJldHVybiBudWxsIGlmIG5vIGluZm9ybWF0aW9uCi0gICAgICogaXMgYXZhaWxhYmxlLgotICAgICAqLwotICAgIHB1YmxpYyBRTmFtZSBnZXRTY2hlbWFUeXBlKCkgewotICAgICAgICAvL0Jhc2UgY2xhc3Mgd2lsbCB0YWtlIGNhcmUgb2YgcHJvdmlkaW5nIGV4dHJhIGluZm9ybWF0aW9uIGFib3V0IHRoaXMgZXZlbnQuCi0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKiBBIHV0aWxpdHkgZnVuY3Rpb24gdG8gY2hlY2sgaWYgdGhpcyBldmVudCBpcyBhbiBBdHRyaWJ1dGUuCi0gICAgICogQHNlZSBBdHRyaWJ1dGUKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0F0dHJpYnV0ZSgpIHsKLSAgICAgICAgcmV0dXJuIGZFdmVudFR5cGUgPT0gWE1MRXZlbnQuQVRUUklCVVRFOwotICAgIH0KLQotICAgIC8qKiBBIHV0aWxpdHkgZnVuY3Rpb24gdG8gY2hlY2sgaWYgdGhpcyBldmVudCBpcyBDaGFyYWN0ZXJzLgotICAgICAqIEBzZWUgQ2hhcmFjdGVycwotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzQ2hhcmFjdGVycygpIHsKLSAgICAgICAgcmV0dXJuIGZFdmVudFR5cGUgPT0gWE1MRXZlbnQuQ0hBUkFDVEVSUzsKLSAgICB9Ci0KLSAgICAvKiogQSB1dGlsaXR5IGZ1bmN0aW9uIHRvIGNoZWNrIGlmIHRoaXMgZXZlbnQgaXMgYSBOYW1lc3BhY2UuCi0gICAgICogQHNlZSBOYW1lc3BhY2UKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc05hbWVzcGFjZSgpIHsKLSAgICAgICAgcmV0dXJuIGZFdmVudFR5cGUgPT0gWE1MRXZlbnQuTkFNRVNQQUNFOwotICAgIH0KLQotICAgIC8qKiBUaGlzIG1ldGhvZCB3aWxsIHdyaXRlIHRoZSBYTUxFdmVudCBhcyBwZXIgdGhlIFhNTCAxLjAgc3BlY2lmaWNhdGlvbiBhcyBVbmljb2RlIGNoYXJhY3RlcnMuCi0gICAgICogTm8gaW5kZW50YXRpb24gb3Igd2hpdGVzcGFjZSBzaG91bGQgYmUgb3V0cHV0dGVkLgotICAgICAqCi0gICAgICogQW55IHVzZXIgZGVmaW5lZCBldmVudCB0eXBlIFNIQUxMIGhhdmUgdGhpcyBtZXRob2QKLSAgICAgKiBjYWxsZWQgd2hlbiBiZWluZyB3cml0dGVuIHRvIG9uIGFuIG91dHB1dCBzdHJlYW0uCi0gICAgICogQnVpbHQgaW4gRXZlbnQgdHlwZXMgTVVTVCBpbXBsZW1lbnQgdGhpcyBtZXRob2QsCi0gICAgICogYnV0IGltcGxlbWVudGF0aW9ucyBNQVkgY2hvb3NlIG5vdCBjYWxsIHRoZXNlIG1ldGhvZHMKLSAgICAgKiBmb3Igb3B0aW1pemF0aW9ucyByZWFzb25zIHdoZW4gd3JpdGluZyBvdXQgYnVpbHQgaW4KLSAgICAgKiBFdmVudHMgdG8gYW4gb3V0cHV0IHN0cmVhbS4KLSAgICAgKiBUaGUgb3V0cHV0IGdlbmVyYXRlZCBNVVNUIGJlIGVxdWl2YWxlbnQgaW4gdGVybXMgb2YgdGhlCi0gICAgICogaW5mb3NldCBleHByZXNzZWQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gd3JpdGVyIFRoZSB3cml0ZXIgdGhhdCB3aWxsIG91dHB1dCB0aGUgZGF0YQotICAgICAqIEB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uIGlmIHRoZXJlIGlzIGEgZmF0YWwgZXJyb3Igd3JpdGluZyB0aGUgZXZlbnQKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB3cml0ZUFzRW5jb2RlZFVuaWNvZGUoV3JpdGVyIHdyaXRlcikgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbiB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICB3cml0ZUFzRW5jb2RlZFVuaWNvZGVFeCh3cml0ZXIpOwotICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWE1MU3RyZWFtRXhjZXB0aW9uKGUpOwotICAgICAgICB9Ci0gICAgfQotICAgIC8qKiBIZWxwZXIgbWV0aG9kIGluIG9yZGVyIHRvIGV4cG9zZSBJT0V4Y2VwdGlvbi4KLSAgICAgKiBAcGFyYW0gd3JpdGVyIFRoZSB3cml0ZXIgdGhhdCB3aWxsIG91dHB1dCB0aGUgZGF0YQotICAgICAqIEB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uIGlmIHRoZXJlIGlzIGEgZmF0YWwgZXJyb3Igd3JpdGluZyB0aGUgZXZlbnQKLSAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHRoZXJlIGlzIGFuIElPIGVycm9yCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGFic3RyYWN0IHZvaWQgd3JpdGVBc0VuY29kZWRVbmljb2RlRXgoV3JpdGVyIHdyaXRlcikKLSAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBYTUxTdHJlYW1FeGNlcHRpb247Ci0KLSAgICAvKiogSGVscGVyIG1ldGhvZCB0byBlc2NhcGUgPCA+ICYgZm9yIGNoYXJhY3RlcnMgZXZlbnQgYW5kCi0gICAgICogIHF1b3RlcywgbHQgYW5kIGFtcHMgZm9yIEVudGl0eQotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIGNoYXJFbmNvZGUoV3JpdGVyIHdyaXRlciwgU3RyaW5nIGRhdGEpCi0gICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaWYgKGRhdGEgPT0gbnVsbCB8fCBkYXRhID09ICIiKSByZXR1cm47Ci0gICAgICAgIGludCBpID0gMCwgc3RhcnQgPSAwOwotICAgICAgICBpbnQgbGVuID0gZGF0YS5sZW5ndGgoKTsKLQotICAgICAgICBsb29wOgotICAgICAgICBmb3IgKDsgaSA8IGxlbjsgKytpKSB7Ci0gICAgICAgICAgICBzd2l0Y2ggKGRhdGEuY2hhckF0KGkpKSB7Ci0gICAgICAgICAgICBjYXNlICc8JzoKLSAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoZGF0YSwgc3RhcnQsIGkgLSBzdGFydCk7Ci0gICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKCImbHQ7Iik7Ci0gICAgICAgICAgICAgICAgc3RhcnQgPSBpICsgMTsKLSAgICAgICAgICAgICAgICBicmVhazsKLQotICAgICAgICAgICAgY2FzZSAnJic6Ci0gICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKGRhdGEsIHN0YXJ0LCBpIC0gc3RhcnQpOwotICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZSgiJmFtcDsiKTsKLSAgICAgICAgICAgICAgICBzdGFydCA9IGkgKyAxOwotICAgICAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgICAgICBjYXNlICc+JzoKLSAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoZGF0YSwgc3RhcnQsIGkgLSBzdGFydCk7Ci0gICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKCImZ3Q7Iik7Ci0gICAgICAgICAgICAgICAgc3RhcnQgPSBpICsgMTsKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIGNhc2UgJyInOgotICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZShkYXRhLCBzdGFydCwgaSAtIHN0YXJ0KTsKLSAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoIiZxdW90OyIpOwotICAgICAgICAgICAgICAgIHN0YXJ0ID0gaSArIDE7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgLy8gV3JpdGUgYW55IHBlbmRpbmcgZGF0YQotICAgICAgICB3cml0ZXIud3JpdGUoZGF0YSwgc3RhcnQsIGxlbiAtIHN0YXJ0KTsKLSAgICB9Ci0KLSAgICBzdGF0aWMgY2xhc3MgRHVtbXlMb2NhdGlvbiBpbXBsZW1lbnRzIExvY2F0aW9uIHsKLSAgICAgICAgcHVibGljIER1bW15TG9jYXRpb24oKSB7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgaW50IGdldENoYXJhY3Rlck9mZnNldCgpIHsKLSAgICAgICAgICAgIHJldHVybiAtMTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyBpbnQgZ2V0Q29sdW1uTnVtYmVyKCkgewotICAgICAgICAgICAgcmV0dXJuIC0xOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIGludCBnZXRMaW5lTnVtYmVyKCkgewotICAgICAgICAgICAgcmV0dXJuIC0xOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIFN0cmluZyBnZXRQdWJsaWNJZCgpIHsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIFN0cmluZyBnZXRTeXN0ZW1JZCgpIHsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4veG1sL2ludGVybmFsL3N0cmVhbS9ldmVudHMvRW5kRG9jdW1lbnRFdmVudC5qYXZhIGIvc3JjL2NvbS9zdW4veG1sL2ludGVybmFsL3N0cmVhbS9ldmVudHMvRW5kRG9jdW1lbnRFdmVudC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxMmE5MWMyLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL3htbC9pbnRlcm5hbC9zdHJlYW0vZXZlbnRzL0VuZERvY3VtZW50RXZlbnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDYxICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi54bWwuaW50ZXJuYWwuc3RyZWFtLmV2ZW50cyA7Ci0KLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLmV2ZW50cy5FbmREb2N1bWVudDsKLWltcG9ydCBqYXZhLmlvLldyaXRlcjsKLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLlhNTFN0cmVhbUNvbnN0YW50czsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGNvbnRhaW5zIGluZm9ybWF0aW9uIGFib3V0IEVuZERvY3VtZW50IGV2ZW50LgotICoKLSAqIEBhdXRob3IgTmVlcmFqIEJhamFqLCBTdW4gTWljcm9zeXN0ZW1zLgotICovCi0KLQotcHVibGljIGNsYXNzIEVuZERvY3VtZW50RXZlbnQgZXh0ZW5kcyBEdW1teUV2ZW50Ci1pbXBsZW1lbnRzIEVuZERvY3VtZW50IHsKLQotICAgIHB1YmxpYyBFbmREb2N1bWVudEV2ZW50KCkgewotICAgICAgICBpbml0KCk7Ci0gICAgfQotCi0gICAgcHJvdGVjdGVkIHZvaWQgaW5pdCgpIHsKLSAgICAgICAgc2V0RXZlbnRUeXBlKFhNTFN0cmVhbUNvbnN0YW50cy5FTkRfRE9DVU1FTlQpOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0gICAgICAgIHJldHVybiAiRU5ERE9DVU1FTlQiOwotICAgIH0KLQotICAgIHByb3RlY3RlZCB2b2lkIHdyaXRlQXNFbmNvZGVkVW5pY29kZUV4KGphdmEuaW8uV3JpdGVyIHdyaXRlcikKLSAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgLy9lbmQgZG9jdW1lbnQKLSAgICB9Ci0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4veG1sL2ludGVybmFsL3N0cmVhbS9ldmVudHMvRW5kRWxlbWVudEV2ZW50LmphdmEgYi9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL2V2ZW50cy9FbmRFbGVtZW50RXZlbnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYzQ0MWQ0Mi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL2V2ZW50cy9FbmRFbGVtZW50RXZlbnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEyNCArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDA1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ueG1sLmludGVybmFsLnN0cmVhbS5ldmVudHMgOwotCi1pbXBvcnQgamF2YS51dGlsLkxpc3Q7Ci1pbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKLQotaW1wb3J0IGphdmF4LnhtbC5uYW1lc3BhY2UuUU5hbWU7Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5ldmVudHMuRW5kRWxlbWVudDsKLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLmV2ZW50cy5OYW1lc3BhY2U7Ci1pbXBvcnQgamF2YS5pby5Xcml0ZXI7Ci1pbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOwotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uZXZlbnRzLlhNTEV2ZW50OwotaW1wb3J0IGNvbS5zdW4ueG1sLmludGVybmFsLnN0cmVhbS51dGlsLlJlYWRPbmx5SXRlcmF0b3I7Ci0KLS8qKiBJbXBsZW1lbnRhdGlvbiBvZiBFbmRFbGVtZW50IGV2ZW50LgotICoKLSAqIEBhdXRob3IgTmVlcmFqIEJhamFqIFN1biBNaWNyb3N5c3RlbXMsSW5jLgotICogQGF1dGhvciBLLlZlbnVnb3BhbCBTdW4gTWljcm9zeXN0ZW1zLEluYy4KLSAqLwotCi1wdWJsaWMgY2xhc3MgRW5kRWxlbWVudEV2ZW50IGV4dGVuZHMgRHVtbXlFdmVudAotaW1wbGVtZW50cyBFbmRFbGVtZW50IHsKLQotICAgIExpc3QgZk5hbWVzcGFjZXMgPSBudWxsOwotICAgIFFOYW1lIGZRTmFtZSA7Ci0KLSAgICBwdWJsaWMgRW5kRWxlbWVudEV2ZW50KCkgewotICAgICAgICBpbml0KCk7Ci0gICAgfQotCi0gICAgcHJvdGVjdGVkIHZvaWQgaW5pdCgpIHsKLSAgICAgICAgc2V0RXZlbnRUeXBlKFhNTEV2ZW50LkVORF9FTEVNRU5UKTsKLSAgICAgICAgZk5hbWVzcGFjZXMgPSBuZXcgQXJyYXlMaXN0KCk7Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgRW5kRWxlbWVudEV2ZW50KFN0cmluZyBwcmVmaXgsICBTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxwYXJ0KSB7Ci0gICAgICAgIHRoaXMobmV3IFFOYW1lKHVyaSxsb2NhbHBhcnQscHJlZml4KSk7Ci0gICAgfQotCi0gICAgcHVibGljIEVuZEVsZW1lbnRFdmVudChRTmFtZSBxbmFtZSkgewotICAgICAgICB0aGlzLmZRTmFtZSA9IHFuYW1lOwotICAgICAgICBpbml0KCk7Ci0gICAgfQotCi0gICAgcHVibGljIFFOYW1lIGdldE5hbWUoKSB7Ci0gICAgICAgIHJldHVybiBmUU5hbWU7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0TmFtZShRTmFtZSBxbmFtZSkgewotICAgICAgICB0aGlzLmZRTmFtZSA9IHFuYW1lOwotICAgIH0KLQotICAgIHByb3RlY3RlZCB2b2lkIHdyaXRlQXNFbmNvZGVkVW5pY29kZUV4KGphdmEuaW8uV3JpdGVyIHdyaXRlcikKLSAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgd3JpdGVyLndyaXRlKCI8LyIpOwotICAgICAgICBTdHJpbmcgcHJlZml4ID0gZlFOYW1lLmdldFByZWZpeCgpOwotICAgICAgICBpZiAocHJlZml4ICE9IG51bGwgJiYgcHJlZml4Lmxlbmd0aCgpID4gMCkgewotICAgICAgICAgICAgd3JpdGVyLndyaXRlKHByZWZpeCk7Ci0gICAgICAgICAgICB3cml0ZXIud3JpdGUoJzonKTsKLSAgICAgfQotICAgICAgICB3cml0ZXIud3JpdGUoZlFOYW1lLmdldExvY2FsUGFydCgpKTsKLSAgICAgICAgd3JpdGVyLndyaXRlKCc+Jyk7Ci0gICAgfQotCi0gICAgLyoqIFJldHVybnMgYW4gSXRlcmF0b3Igb2YgbmFtZXNwYWNlcyB0aGF0IGhhdmUgZ29uZSBvdXQKLSAgICAgKiBvZiBzY29wZS4gIFJldHVybnMgYW4gZW1wdHkgaXRlcmF0b3IgaWYgbm8gbmFtZXNwYWNlcyBoYXZlIGdvbmUKLSAgICAgKiBvdXQgb2Ygc2NvcGUuCi0gICAgICogQHJldHVybiBhbiBJdGVyYXRvciBvdmVyIE5hbWVzcGFjZSBpbnRlcmZhY2VzLCBvciBhbgotICAgICAqIGVtcHR5IGl0ZXJhdG9yCi0gICAgICovCi0gICAgcHVibGljIEl0ZXJhdG9yIGdldE5hbWVzcGFjZXMoKSB7Ci0gICAgICAgIGlmKGZOYW1lc3BhY2VzICE9IG51bGwpCi0gICAgICAgICAgICBmTmFtZXNwYWNlcy5pdGVyYXRvcigpOwotICAgICAgICByZXR1cm4gbmV3IFJlYWRPbmx5SXRlcmF0b3IoKTsKLSAgICB9Ci0KLSAgICB2b2lkIGFkZE5hbWVzcGFjZShOYW1lc3BhY2UgYXR0cil7Ci0gICAgICAgIGlmKGF0dHIgIT0gbnVsbCl7Ci0gICAgICAgICAgICBmTmFtZXNwYWNlcy5hZGQoYXR0cik7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgICAgICBTdHJpbmcgcyA9ICI8LyIgKyBuYW1lQXNTdHJpbmcoKTsKLSAgICAgICAgcyA9IHMgKyAiPiI7Ci0gICAgICAgIHJldHVybiBzOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgbmFtZUFzU3RyaW5nKCkgewotICAgICAgICBpZigiIi5lcXVhbHMoZlFOYW1lLmdldE5hbWVzcGFjZVVSSSgpKSkKLSAgICAgICAgICAgIHJldHVybiBmUU5hbWUuZ2V0TG9jYWxQYXJ0KCk7Ci0gICAgICAgIGlmKGZRTmFtZS5nZXRQcmVmaXgoKSAhPSBudWxsKQotICAgICAgICAgICAgcmV0dXJuICJbJyIgKyBmUU5hbWUuZ2V0TmFtZXNwYWNlVVJJKCkgKyAiJ106IiArIGZRTmFtZS5nZXRQcmVmaXgoKSArICI6IiArIGZRTmFtZS5nZXRMb2NhbFBhcnQoKTsKLSAgICAgICAgZWxzZQotICAgICAgICAgICAgcmV0dXJuICJbJyIgKyBmUU5hbWUuZ2V0TmFtZXNwYWNlVVJJKCkgKyAiJ106IiArIGZRTmFtZS5nZXRMb2NhbFBhcnQoKTsKLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL3htbC9pbnRlcm5hbC9zdHJlYW0vZXZlbnRzL0VudGl0eURlY2xhcmF0aW9uSW1wbC5qYXZhIGIvc3JjL2NvbS9zdW4veG1sL2ludGVybmFsL3N0cmVhbS9ldmVudHMvRW50aXR5RGVjbGFyYXRpb25JbXBsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGU0YjM2ZWMuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4veG1sL2ludGVybmFsL3N0cmVhbS9ldmVudHMvRW50aXR5RGVjbGFyYXRpb25JbXBsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNTAgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLnhtbC5pbnRlcm5hbC5zdHJlYW0uZXZlbnRzOwotCi1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5ldmVudHMuRW50aXR5RGVjbGFyYXRpb247Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5ldmVudHMuWE1MRXZlbnQ7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuWE1MUmVzb3VyY2VJZGVudGlmaWVyOwotCi0vKioKLSAqCi0gKiBUaGlzIGNsYXNzIHN0b3JlIGFsbCB0aGUgaW5mb3JtYXRpb24gZm9yIGEgcGFydGljdWxhciBFbnRpdHlEZWNsYXJhdGlvbi4gRW50aXR5RGVjbGFyYXRpb24gaW50ZXJmYWNlCi0gKiBoYXMgdmFyaW91cyBnZXQqIGZ1bmN0aW9zbiB0byByZXRpcnZlIGluZm9ybWF0aW9uIGFib3V0IGEgcGFydGljdWxhciBFbnRpdHlEZWNsYXJhdGlvbi4KLSAqCi0gKiBAYXV0aG9yICBOZWVyYWogQmFqYWosIFN1biBNaWNyb3N5c3RlbXMuCi0gKi8KLXB1YmxpYyBjbGFzcyBFbnRpdHlEZWNsYXJhdGlvbkltcGwgZXh0ZW5kcyBEdW1teUV2ZW50IGltcGxlbWVudHMgRW50aXR5RGVjbGFyYXRpb24gewotCi0gICAgcHJpdmF0ZSBYTUxSZXNvdXJjZUlkZW50aWZpZXIgZlhNTFJlc291cmNlSWRlbnRpZmllciA7Ci0gICAgcHJpdmF0ZSBTdHJpbmcgZkVudGl0eU5hbWU7Ci0gICAgcHJpdmF0ZSBTdHJpbmcgZlJlcGxhY2VtZW50VGV4dDsKLSAgICBwcml2YXRlIFN0cmluZyBmTm90YXRpb25OYW1lOwotCi0gICAgLyoqIENyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgRW50aXR5RGVjbGFyYXRpb25JbXBsICovCi0gICAgcHVibGljIEVudGl0eURlY2xhcmF0aW9uSW1wbCgpIHsKLSAgICAgICAgaW5pdCgpOwotICAgIH0KLQotICAgIHB1YmxpYyBFbnRpdHlEZWNsYXJhdGlvbkltcGwoU3RyaW5nIGVudGl0eU5hbWUgLCBTdHJpbmcgcmVwbGFjZW1lbnRUZXh0KXsKLSAgICAgICAgdGhpcyhlbnRpdHlOYW1lLHJlcGxhY2VtZW50VGV4dCxudWxsKTsKLQotICAgIH0KLQotICAgIHB1YmxpYyBFbnRpdHlEZWNsYXJhdGlvbkltcGwoU3RyaW5nIGVudGl0eU5hbWUsIFN0cmluZyByZXBsYWNlbWVudFRleHQsIFhNTFJlc291cmNlSWRlbnRpZmllciByZXNvdXJjZUlkZW50aWZpZXIpewotICAgICAgICBpbml0KCk7Ci0gICAgICAgIGZFbnRpdHlOYW1lID0gZW50aXR5TmFtZTsKLSAgICAgICAgZlJlcGxhY2VtZW50VGV4dCA9IHJlcGxhY2VtZW50VGV4dDsKLSAgICAgICAgZlhNTFJlc291cmNlSWRlbnRpZmllciA9IHJlc291cmNlSWRlbnRpZmllcjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRFbnRpdHlOYW1lKFN0cmluZyBlbnRpdHlOYW1lKXsKLSAgICAgICAgZkVudGl0eU5hbWUgPSBlbnRpdHlOYW1lOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0RW50aXR5TmFtZSgpewotICAgICAgICByZXR1cm4gZkVudGl0eU5hbWU7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0RW50aXR5UmVwbGFjZW1lbnRUZXh0KFN0cmluZyByZXBsYWNlbWVudFRleHQpewotICAgICAgICBmUmVwbGFjZW1lbnRUZXh0ID0gcmVwbGFjZW1lbnRUZXh0OwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldFhNTFJlc291cmNlSWRlbnRpZmllcihYTUxSZXNvdXJjZUlkZW50aWZpZXIgcmVzb3VyY2VJZGVudGlmaWVyKXsKLSAgICAgICAgZlhNTFJlc291cmNlSWRlbnRpZmllciA9IHJlc291cmNlSWRlbnRpZmllciA7Ci0gICAgfQotCi0gICAgcHVibGljIFhNTFJlc291cmNlSWRlbnRpZmllciBnZXRYTUxSZXNvdXJjZUlkZW50aWZpZXIoKXsKLSAgICAgICAgcmV0dXJuIGZYTUxSZXNvdXJjZUlkZW50aWZpZXI7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRTeXN0ZW1JZCgpewotICAgICAgICBpZihmWE1MUmVzb3VyY2VJZGVudGlmaWVyICE9IG51bGwpCi0gICAgICAgICAgICByZXR1cm4gZlhNTFJlc291cmNlSWRlbnRpZmllci5nZXRMaXRlcmFsU3lzdGVtSWQoKTsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRQdWJsaWNJZCgpewotICAgICAgICBpZihmWE1MUmVzb3VyY2VJZGVudGlmaWVyICE9IG51bGwpCi0gICAgICAgICAgICByZXR1cm4gZlhNTFJlc291cmNlSWRlbnRpZmllci5nZXRQdWJsaWNJZCgpOwotCi0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0QmFzZVVSSSgpIHsKLSAgICAgICAgaWYoZlhNTFJlc291cmNlSWRlbnRpZmllciAhPSBudWxsKQotICAgICAgICAgICAgcmV0dXJuIGZYTUxSZXNvdXJjZUlkZW50aWZpZXIuZ2V0QmFzZVN5c3RlbUlkKCk7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpewotICAgICAgICByZXR1cm4gZkVudGl0eU5hbWU7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXROb3RhdGlvbk5hbWUoKSB7Ci0gICAgICAgIHJldHVybiBmTm90YXRpb25OYW1lOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldE5vdGF0aW9uTmFtZShTdHJpbmcgbm90YXRpb25OYW1lKXsKLSAgICAgICAgZk5vdGF0aW9uTmFtZSA9IG5vdGF0aW9uTmFtZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldFJlcGxhY2VtZW50VGV4dCgpIHsKLSAgICAgICAgcmV0dXJuIGZSZXBsYWNlbWVudFRleHQ7Ci0gICAgfQotCi0gICAgcHJvdGVjdGVkIHZvaWQgaW5pdCgpewotICAgICAgICBzZXRFdmVudFR5cGUoWE1MRXZlbnQuRU5USVRZX0RFQ0xBUkFUSU9OKTsKLSAgICB9Ci0KLSAgICBwcm90ZWN0ZWQgdm9pZCB3cml0ZUFzRW5jb2RlZFVuaWNvZGVFeChqYXZhLmlvLldyaXRlciB3cml0ZXIpCi0gICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIHdyaXRlci53cml0ZSgiPCFFTlRJVFkgIik7Ci0gICAgICAgIHdyaXRlci53cml0ZShmRW50aXR5TmFtZSk7Ci0gICAgICAgIGlmIChmUmVwbGFjZW1lbnRUZXh0ICE9IG51bGwpIHsKLSAgICAgICAgICAgIC8vaW50ZXJuYWwgZW50aXR5Ci0gICAgICAgICAgICAvL2VzY2FwZSBxdW90ZXMsIGx0IGFuZCBhbXBzCi0gICAgICAgICAgICB3cml0ZXIud3JpdGUoIiBcIiIpOwotICAgICAgICAgICAgY2hhckVuY29kZSh3cml0ZXIsIGZSZXBsYWNlbWVudFRleHQpOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgLy9leHRlcm5hbCBlbnRpdHkKLSAgICAgICAgICAgIFN0cmluZyBwdWJJZCA9IGdldFB1YmxpY0lkKCk7Ci0gICAgICAgICAgICBpZiAocHViSWQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZSgiIFBVQkxJQyBcIiIpOwotICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZShwdWJJZCk7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZSgiIFNZU1RFTSBcIiIpOwotICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZShnZXRTeXN0ZW1JZCgpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICB3cml0ZXIud3JpdGUoIlwiIik7Ci0gICAgICAgIGlmIChmTm90YXRpb25OYW1lICE9IG51bGwpIHsKLSAgICAgICAgICAgIHdyaXRlci53cml0ZSgiIE5EQVRBICIpOwotICAgICAgICAgICAgd3JpdGVyLndyaXRlKGZOb3RhdGlvbk5hbWUpOwotICAgICAgICB9Ci0gICAgICAgIHdyaXRlci53cml0ZSgiPiIpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL3htbC9pbnRlcm5hbC9zdHJlYW0vZXZlbnRzL0VudGl0eVJlZmVyZW5jZUV2ZW50LmphdmEgYi9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL2V2ZW50cy9FbnRpdHlSZWZlcmVuY2VFdmVudC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhYzZhYmQ2Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL3htbC9pbnRlcm5hbC9zdHJlYW0vZXZlbnRzL0VudGl0eVJlZmVyZW5jZUV2ZW50LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4MCArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDA1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ueG1sLmludGVybmFsLnN0cmVhbS5ldmVudHMgOwotCi1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5ldmVudHMuRW50aXR5UmVmZXJlbmNlOwotaW1wb3J0IGphdmEuaW8uV3JpdGVyOwotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uZXZlbnRzLkVudGl0eURlY2xhcmF0aW9uOwotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uZXZlbnRzLlhNTEV2ZW50OwotCi0vKiogSW1wbGVtZW50cyBFbnRpdHlSZWZlcmVuY2UgZXZlbnQuCi0gKgotICpAYXV0aG9yIE5lZXJhaiBCYWphaiwgU3VuIE1pY3Jvc3lzdGVtcywKLSAqLwotcHVibGljIGNsYXNzIEVudGl0eVJlZmVyZW5jZUV2ZW50IGV4dGVuZHMgRHVtbXlFdmVudAotaW1wbGVtZW50cyBFbnRpdHlSZWZlcmVuY2UgewotICAgIHByaXZhdGUgRW50aXR5RGVjbGFyYXRpb24gZkVudGl0eURlY2xhcmF0aW9uIDsKLSAgICBwcml2YXRlIFN0cmluZyBmRW50aXR5TmFtZTsKLQotICAgIHB1YmxpYyBFbnRpdHlSZWZlcmVuY2VFdmVudCgpIHsKLSAgICAgICAgaW5pdCgpOwotICAgIH0KLQotICAgIHB1YmxpYyBFbnRpdHlSZWZlcmVuY2VFdmVudChTdHJpbmcgZW50aXR5TmFtZSAsIEVudGl0eURlY2xhcmF0aW9uIGVudGl0eURlY2xhcmF0aW9uKSB7Ci0gICAgICAgIGluaXQoKTsKLSAgICAgICAgZkVudGl0eU5hbWUgPSBlbnRpdHlOYW1lOwotICAgICAgICBmRW50aXR5RGVjbGFyYXRpb24gPSBlbnRpdHlEZWNsYXJhdGlvbiA7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXROYW1lKCkgewotICAgICAgICByZXR1cm4gZkVudGl0eU5hbWU7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKLSAgICAgICAgU3RyaW5nIHRleHQgPSBmRW50aXR5RGVjbGFyYXRpb24uZ2V0UmVwbGFjZW1lbnRUZXh0KCk7Ci0gICAgICAgIGlmKHRleHQgPT0gbnVsbCkKLSAgICAgICAgICAgIHRleHQgPSAiIjsKLSAgICAgICAgcmV0dXJuICImIiArIGdldE5hbWUoKSArICI7PSciICsgdGV4dCArICInIjsKLSAgICB9Ci0KLSAgICBwcm90ZWN0ZWQgdm9pZCB3cml0ZUFzRW5jb2RlZFVuaWNvZGVFeChqYXZhLmlvLldyaXRlciB3cml0ZXIpCi0gICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIHdyaXRlci53cml0ZSgnJicpOwotICAgICAgICB3cml0ZXIud3JpdGUoZ2V0TmFtZSgpKTsKLSAgICAgICAgd3JpdGVyLndyaXRlKCc7Jyk7Ci0gICAgfQotCi0gICAgcHVibGljIEVudGl0eURlY2xhcmF0aW9uIGdldERlY2xhcmF0aW9uKCl7Ci0gICAgICAgIHJldHVybiBmRW50aXR5RGVjbGFyYXRpb24gOwotICAgIH0KLQotICAgIHByb3RlY3RlZCB2b2lkIGluaXQoKSB7Ci0gICAgICAgIHNldEV2ZW50VHlwZShYTUxFdmVudC5FTlRJVFlfUkVGRVJFTkNFKTsKLSAgICB9Ci0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4veG1sL2ludGVybmFsL3N0cmVhbS9ldmVudHMvTG9jYXRpb25JbXBsLmphdmEgYi9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL2V2ZW50cy9Mb2NhdGlvbkltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYTRiOWIzMi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL2V2ZW50cy9Mb2NhdGlvbkltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDg0ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi54bWwuaW50ZXJuYWwuc3RyZWFtLmV2ZW50czsKLQotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uTG9jYXRpb247Ci0KLS8qKgotICpJbXBsZW1lbnRhdGlvbiBvZiBMb2NhdGlvbiBpbnRlcmZhY2UgdG8gYmUgdXNlZCBieQotICpldmVudCByZWFkZXJzLgotICpAYXV0aG9yIE5lZXJhai5iYWphakBzdW4uY29tLGsudmVudWdvcGFsQHN1bi5jb20KLSAqLwotcHVibGljIGNsYXNzIExvY2F0aW9uSW1wbCBpbXBsZW1lbnRzIExvY2F0aW9uewotICAgIFN0cmluZyBzeXN0ZW1JZDsKLSAgICBTdHJpbmcgcHVibGljSWQ7Ci0gICAgaW50IGNvbE5vOwotICAgIGludCBsaW5lTm87Ci0gICAgaW50IGNoYXJPZmZzZXQ7Ci0gICAgTG9jYXRpb25JbXBsKExvY2F0aW9uIGxvYyl7Ci0gICAgICAgIHN5c3RlbUlkID0gbG9jLmdldFN5c3RlbUlkKCk7Ci0gICAgICAgIHB1YmxpY0lkID0gbG9jLmdldFB1YmxpY0lkKCk7Ci0gICAgICAgIGxpbmVObyA9IGxvYy5nZXRMaW5lTnVtYmVyKCk7Ci0gICAgICAgIGNvbE5vID0gbG9jLmdldENvbHVtbk51bWJlcigpOwotICAgICAgICBjaGFyT2Zmc2V0ID0gbG9jLmdldENoYXJhY3Rlck9mZnNldCgpOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgZ2V0Q2hhcmFjdGVyT2Zmc2V0KCl7Ci0gICAgICAgIHJldHVybiBjaGFyT2Zmc2V0OwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgZ2V0Q29sdW1uTnVtYmVyKCkgewotICAgICAgICByZXR1cm4gY29sTm87Ci0gICAgfQotCi0gICAgcHVibGljIGludCBnZXRMaW5lTnVtYmVyKCl7Ci0gICAgICAgIHJldHVybiBsaW5lTm87Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRQdWJsaWNJZCgpewotICAgICAgICByZXR1cm4gcHVibGljSWQ7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRTeXN0ZW1JZCgpewotICAgICAgICByZXR1cm4gc3lzdGVtSWQ7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpewotICAgICAgICBTdHJpbmdCdWZmZXIgc2J1ZmZlciA9IG5ldyBTdHJpbmdCdWZmZXIoKSA7Ci0gICAgICAgIHNidWZmZXIuYXBwZW5kKCJMaW5lIG51bWJlciA9ICIgKyBnZXRMaW5lTnVtYmVyKCkpOwotICAgICAgICBzYnVmZmVyLmFwcGVuZCgiXG4iKSA7Ci0gICAgICAgIHNidWZmZXIuYXBwZW5kKCJDb2x1bW4gbnVtYmVyID0gIiArIGdldENvbHVtbk51bWJlcigpKTsKLSAgICAgICAgc2J1ZmZlci5hcHBlbmQoIlxuIikgOwotICAgICAgICBzYnVmZmVyLmFwcGVuZCgiU3lzdGVtIElkID0gIiArIGdldFN5c3RlbUlkKCkpOwotICAgICAgICBzYnVmZmVyLmFwcGVuZCgiXG4iKSA7Ci0gICAgICAgIHNidWZmZXIuYXBwZW5kKCJQdWJsaWMgSWQgPSAiICsgZ2V0UHVibGljSWQoKSk7Ci0gICAgICAgIHNidWZmZXIuYXBwZW5kKCJcbiIpIDsKLSAgICAgICAgc2J1ZmZlci5hcHBlbmQoIkNoYXJhY3Rlck9mZnNldCA9ICIgKyBnZXRDaGFyYWN0ZXJPZmZzZXQoKSk7Ci0gICAgICAgIHNidWZmZXIuYXBwZW5kKCJcbiIpIDsKLSAgICAgICAgcmV0dXJuIHNidWZmZXIudG9TdHJpbmcoKTsKLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL3htbC9pbnRlcm5hbC9zdHJlYW0vZXZlbnRzL05hbWVkRXZlbnQuamF2YSBiL3NyYy9jb20vc3VuL3htbC9pbnRlcm5hbC9zdHJlYW0vZXZlbnRzL05hbWVkRXZlbnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZjE0ODhhOS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL2V2ZW50cy9OYW1lZEV2ZW50LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4MyArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDA1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ueG1sLmludGVybmFsLnN0cmVhbS5ldmVudHMgOwotCi1pbXBvcnQgamF2YXgueG1sLm5hbWVzcGFjZS5RTmFtZTsKLS8qKgotICoKLSAqQGF1dGhvciBOZWVyYWogQmFqYWosIFN1biBNaWNyb3N5c3RlbXMKLSAqCi0gKi8KLXB1YmxpYyBjbGFzcyBOYW1lZEV2ZW50IGV4dGVuZHMgRHVtbXlFdmVudCB7Ci0KLSAgICBwcml2YXRlIFFOYW1lIG5hbWU7Ci0KLSAgICBwdWJsaWMgTmFtZWRFdmVudCgpIHsKLSAgICB9Ci0KLQotICAgIHB1YmxpYyBOYW1lZEV2ZW50KFFOYW1lIHFuYW1lKSB7Ci0gICAgICAgIHRoaXMubmFtZSA9IHFuYW1lOwotICAgIH0KLQotCi0gICAgcHVibGljIE5hbWVkRXZlbnQoU3RyaW5nIHByZWZpeCwgU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FscGFydCkgewotICAgICAgICB0aGlzLm5hbWUgPSBuZXcgUU5hbWUodXJpLCBsb2NhbHBhcnQsIHByZWZpeCk7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRQcmVmaXgoKSB7Ci0gICAgICAgIHJldHVybiB0aGlzLm5hbWUuZ2V0UHJlZml4KCk7Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgUU5hbWUgZ2V0TmFtZSgpIHsKLSAgICAgICAgcmV0dXJuIG5hbWU7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0TmFtZShRTmFtZSBxbmFtZSkgewotICAgICAgICB0aGlzLm5hbWUgPSBxbmFtZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIG5hbWVBc1N0cmluZygpIHsKLSAgICAgICAgaWYoIiIuZXF1YWxzKG5hbWUuZ2V0TmFtZXNwYWNlVVJJKCkpKQotICAgICAgICAgICAgcmV0dXJuIG5hbWUuZ2V0TG9jYWxQYXJ0KCk7Ci0gICAgICAgIGlmKG5hbWUuZ2V0UHJlZml4KCkgIT0gbnVsbCkKLSAgICAgICAgICAgIHJldHVybiAiWyciICsgbmFtZS5nZXROYW1lc3BhY2VVUkkoKSArICInXToiICsgZ2V0UHJlZml4KCkgKyAiOiIgKyBuYW1lLmdldExvY2FsUGFydCgpOwotICAgICAgICBlbHNlCi0gICAgICAgICAgICByZXR1cm4gIlsnIiArIG5hbWUuZ2V0TmFtZXNwYWNlVVJJKCkgKyAiJ106IiArIG5hbWUuZ2V0TG9jYWxQYXJ0KCk7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXROYW1lc3BhY2UoKXsKLSAgICAgICAgcmV0dXJuIG5hbWUuZ2V0TmFtZXNwYWNlVVJJKCk7Ci0gICAgfQotCi0gICAgcHJvdGVjdGVkIHZvaWQgd3JpdGVBc0VuY29kZWRVbmljb2RlRXgoamF2YS5pby5Xcml0ZXIgd3JpdGVyKQotICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uCi0gICAgewotICAgICAgICB3cml0ZXIud3JpdGUobmFtZUFzU3RyaW5nKCkpOwotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4veG1sL2ludGVybmFsL3N0cmVhbS9ldmVudHMvTmFtZXNwYWNlSW1wbC5qYXZhIGIvc3JjL2NvbS9zdW4veG1sL2ludGVybmFsL3N0cmVhbS9ldmVudHMvTmFtZXNwYWNlSW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4MTRiZWExLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL3htbC9pbnRlcm5hbC9zdHJlYW0vZXZlbnRzL05hbWVzcGFjZUltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEwMSArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDA1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ueG1sLmludGVybmFsLnN0cmVhbS5ldmVudHM7Ci0KLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLmV2ZW50cy5OYW1lc3BhY2U7Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5ldmVudHMuWE1MRXZlbnQ7Ci1pbXBvcnQgamF2YXgueG1sLm5hbWVzcGFjZS5RTmFtZTsKLQotaW1wb3J0IGphdmF4LnhtbC5YTUxDb25zdGFudHM7Ci0vKioKLSAqCi0gKiBAYXV0aG9yICBOZWVyYWogQmFqYWosSy5WZW51Z29wYWxAc3VuLmNvbSAgU3VuIE1pY3Jvc3lzdGVtcy4KLSAqLwotcHVibGljIGNsYXNzIE5hbWVzcGFjZUltcGwgZXh0ZW5kcyBBdHRyaWJ1dGVJbXBsIGltcGxlbWVudHMgTmFtZXNwYWNlewotCi0gICAgcHVibGljIE5hbWVzcGFjZUltcGwoICkgewotICAgICAgICBpbml0KCk7Ci0gICAgfQotCi0gICAgLyoqIENyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgTmFtZXNwYWNlSW1wbCAqLwotICAgIHB1YmxpYyBOYW1lc3BhY2VJbXBsKFN0cmluZyBuYW1lc3BhY2VVUkkpIHsKLSAgICAgICAgc3VwZXIoWE1MQ29uc3RhbnRzLlhNTE5TX0FUVFJJQlVURSxYTUxDb25zdGFudHMuWE1MTlNfQVRUUklCVVRFX05TX1VSSSxYTUxDb25zdGFudHMuREVGQVVMVF9OU19QUkVGSVgsbmFtZXNwYWNlVVJJLG51bGwpOwotICAgICAgICBpbml0KCk7Ci0gICAgfQotCi0gICAgcHVibGljIE5hbWVzcGFjZUltcGwoU3RyaW5nIHByZWZpeCwgU3RyaW5nIG5hbWVzcGFjZVVSSSl7Ci0gICAgICAgIHN1cGVyKFhNTENvbnN0YW50cy5YTUxOU19BVFRSSUJVVEUsWE1MQ29uc3RhbnRzLlhNTE5TX0FUVFJJQlVURV9OU19VUkkscHJlZml4LG5hbWVzcGFjZVVSSSxudWxsKTsKLSAgICAgICAgaW5pdCgpOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGlzRGVmYXVsdE5hbWVzcGFjZURlY2xhcmF0aW9uKCkgewotICAgICAgICBRTmFtZSBuYW1lID0gdGhpcy5nZXROYW1lKCk7Ci0KLSAgICAgICAgaWYobmFtZSAhPSBudWxsICYmIChuYW1lLmdldExvY2FsUGFydCgpLmVxdWFscyhYTUxDb25zdGFudHMuREVGQVVMVF9OU19QUkVGSVgpKSkKLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgdm9pZCBzZXRQcmVmaXgoU3RyaW5nIHByZWZpeCl7Ci0gICAgICAgIGlmKHByZWZpeCA9PSBudWxsKQotICAgICAgICAgICAgc2V0TmFtZShuZXcgUU5hbWUoWE1MQ29uc3RhbnRzLlhNTE5TX0FUVFJJQlVURV9OU19VUkksWE1MQ29uc3RhbnRzLkRFRkFVTFRfTlNfUFJFRklYLFhNTENvbnN0YW50cy5YTUxOU19BVFRSSUJVVEUpKTsKLSAgICAgICAgZWxzZS8vIG5ldyBRTmFtZSh1cmksIGxvY2FscGFydCwgcHJlZml4KQotICAgICAgICAgICAgc2V0TmFtZShuZXcgUU5hbWUoWE1MQ29uc3RhbnRzLlhNTE5TX0FUVFJJQlVURV9OU19VUkkscHJlZml4LFhNTENvbnN0YW50cy5YTUxOU19BVFRSSUJVVEUpKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldFByZWZpeCgpIHsKLSAgICAgICAgLy9mb3IgYSBuYW1lc3BhY2UgZGVjbGFyYXRpb24geG1sbnM6cHJlZml4PSJ1cmkiIHRvIGdldCB0aGUgcHJlZml4IHdlIGhhdmUgdG8gZ2V0IHRoZQotICAgICAgICAvL2xvY2FsIG5hbWUgaWYgdGhpcyBkZWNsYXJhdGlvbiBpcyBzdG9yZWQgYXMgUU5hbWUuCi0gICAgICAgIFFOYW1lIG5hbWUgPSB0aGlzLmdldE5hbWUoKTsKLSAgICAgICAgaWYobmFtZSAhPSBudWxsKQotICAgICAgICAgICAgcmV0dXJuIG5hbWUuZ2V0TG9jYWxQYXJ0KCk7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZXNwYWNlVVJJKCkgewotICAgICAgICAvL3dlIGFyZSB0cmVhdGluZyBuYW1lc3BhY2UgZGVjbGFyYXRpb24gYXMgYXR0cmlidXRlIC0tIHNvIFVSSSBpcyBzdG9yZWQgYXMgdmFsdWUKLSAgICAgICAgLy94bWxuczpwcmVmaXg9IlZhbHVlIgotICAgICAgICByZXR1cm4gdGhpcy5nZXRWYWx1ZSgpOwotICAgIH0KLQotICAgIHZvaWQgc2V0TmFtZXNwYWNlVVJJKFN0cmluZyB1cmkpIHsKLSAgICAgICAgLy93ZSBhcmUgdHJlYXRpbmcgbmFtZXNwYWNlIGRlY2xhcmF0aW9uIGFzIGF0dHJpYnV0ZSAtLSBzbyBVUkkgaXMgc3RvcmVkIGFzIHZhbHVlCi0gICAgICAgIC8veG1sbnM6cHJlZml4PSJWYWx1ZSIKLSAgICAgICAgdGhpcy5zZXRWYWx1ZSh1cmkpOwotICAgIH0KLQotICAgIHByb3RlY3RlZCB2b2lkIGluaXQoKXsKLSAgICAgICAgc2V0RXZlbnRUeXBlKFhNTEV2ZW50Lk5BTUVTUEFDRSk7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBnZXRFdmVudFR5cGUoKXsKLSAgICAgICAgcmV0dXJuIFhNTEV2ZW50Lk5BTUVTUEFDRTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBpc05hbWVzcGFjZSgpewotICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL2V2ZW50cy9Ob3RhdGlvbkRlY2xhcmF0aW9uSW1wbC5qYXZhIGIvc3JjL2NvbS9zdW4veG1sL2ludGVybmFsL3N0cmVhbS9ldmVudHMvTm90YXRpb25EZWNsYXJhdGlvbkltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYWYzZDk0OS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL2V2ZW50cy9Ob3RhdGlvbkRlY2xhcmF0aW9uSW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTAzICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi54bWwuaW50ZXJuYWwuc3RyZWFtLmV2ZW50czsKLQotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uZXZlbnRzLk5vdGF0aW9uRGVjbGFyYXRpb247Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5ldmVudHMuWE1MRXZlbnQ7Ci1pbXBvcnQgY29tLnN1bi54bWwuaW50ZXJuYWwuc3RyZWFtLmR0ZC5ub252YWxpZGF0aW5nLlhNTE5vdGF0aW9uRGVjbDsKLQotLyoqCi0gKiBJbXBsZW1lbnRhdGlvbiBvZiBOb3RhdGlvbkRlY2xhcmF0aW9uIGV2ZW50LgotICoKLSAqIEBhdXRob3Igay52ZW51Z29wYWxAc3VuLmNvbQotICovCi1wdWJsaWMgY2xhc3MgTm90YXRpb25EZWNsYXJhdGlvbkltcGwgZXh0ZW5kcyBEdW1teUV2ZW50IGltcGxlbWVudHMgTm90YXRpb25EZWNsYXJhdGlvbiB7Ci0KLSAgICBTdHJpbmcgZk5hbWUgPSBudWxsOwotICAgIFN0cmluZyBmUHVibGljSWQgPSBudWxsOwotICAgIFN0cmluZyBmU3lzdGVtSWQgPSBudWxsOwotCi0gICAgLyoqIENyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgTm90YXRpb25EZWNsYXJhdGlvbkltcGwgKi8KLSAgICBwdWJsaWMgTm90YXRpb25EZWNsYXJhdGlvbkltcGwoKSB7Ci0gICAgICAgIHNldEV2ZW50VHlwZShYTUxFdmVudC5OT1RBVElPTl9ERUNMQVJBVElPTik7Ci0gICAgfQotCi0gICAgcHVibGljIE5vdGF0aW9uRGVjbGFyYXRpb25JbXBsKFN0cmluZyBuYW1lLFN0cmluZyBwdWJsaWNJZCxTdHJpbmcgc3lzdGVtSWQpewotICAgICAgICB0aGlzLmZOYW1lID0gbmFtZTsKLSAgICAgICAgdGhpcy5mUHVibGljSWQgPSBwdWJsaWNJZDsKLSAgICAgICAgdGhpcy5mU3lzdGVtSWQgPSBzeXN0ZW1JZDsKLSAgICAgICAgc2V0RXZlbnRUeXBlKFhNTEV2ZW50Lk5PVEFUSU9OX0RFQ0xBUkFUSU9OKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgTm90YXRpb25EZWNsYXJhdGlvbkltcGwoWE1MTm90YXRpb25EZWNsIG5vdGF0aW9uKXsKLSAgICAgICAgdGhpcy5mTmFtZSA9IG5vdGF0aW9uLm5hbWU7Ci0gICAgICAgIHRoaXMuZlB1YmxpY0lkID0gbm90YXRpb24ucHVibGljSWQ7Ci0gICAgICAgIHRoaXMuZlN5c3RlbUlkID0gbm90YXRpb24uc3lzdGVtSWQ7Ci0gICAgICAgIHNldEV2ZW50VHlwZShYTUxFdmVudC5OT1RBVElPTl9ERUNMQVJBVElPTik7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXROYW1lKCkgewotICAgICAgICByZXR1cm4gZk5hbWU7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRQdWJsaWNJZCgpIHsKLSAgICAgICAgcmV0dXJuIGZQdWJsaWNJZDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldFN5c3RlbUlkKCkgewotICAgICAgICByZXR1cm4gZlN5c3RlbUlkOwotICAgIH0KLQotICAgIHZvaWQgc2V0UHVibGljSWQoU3RyaW5nIHB1YmxpY0lkKXsKLSAgICAgICAgdGhpcy5mUHVibGljSWQgPSBwdWJsaWNJZDsKLSAgICB9Ci0KLSAgICB2b2lkIHNldFN5c3RlbUlkKFN0cmluZyBzeXN0ZW1JZCl7Ci0gICAgICAgIHRoaXMuZlN5c3RlbUlkID0gc3lzdGVtSWQ7Ci0gICAgfQotCi0gICAgdm9pZCBzZXROYW1lKFN0cmluZyBuYW1lKXsKLSAgICAgICAgdGhpcy5mTmFtZSA9IG5hbWU7Ci0gICAgfQotCi0gICAgcHJvdGVjdGVkIHZvaWQgd3JpdGVBc0VuY29kZWRVbmljb2RlRXgoamF2YS5pby5Xcml0ZXIgd3JpdGVyKQotICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uCi0gICAgewotICAgICAgICB3cml0ZXIud3JpdGUoIjwhTk9UQVRJT04gIik7Ci0gICAgICAgIHdyaXRlci53cml0ZShnZXROYW1lKCkpOwotICAgICAgICBpZiAoZlB1YmxpY0lkICE9IG51bGwpIHsKLSAgICAgICAgICAgIHdyaXRlci53cml0ZSgiIFBVQkxJQyBcIiIpOwotICAgICAgICAgICAgd3JpdGVyLndyaXRlKGZQdWJsaWNJZCk7Ci0gICAgICAgICAgICB3cml0ZXIud3JpdGUoIlwiIik7Ci0gICAgICAgIH0gZWxzZSBpZiAoZlN5c3RlbUlkICE9IG51bGwpIHsKLSAgICAgICAgICAgIHdyaXRlci53cml0ZSgiIFNZU1RFTSIpOwotICAgICAgICAgICAgd3JpdGVyLndyaXRlKCIgXCIiKTsKLSAgICAgICAgICAgIHdyaXRlci53cml0ZShmU3lzdGVtSWQpOwotICAgICAgICAgICAgd3JpdGVyLndyaXRlKCJcIiIpOwotICAgICAgICB9Ci0gICAgICAgIHdyaXRlci53cml0ZSgnPicpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL3htbC9pbnRlcm5hbC9zdHJlYW0vZXZlbnRzL1Byb2Nlc3NpbmdJbnN0cnVjdGlvbkV2ZW50LmphdmEgYi9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL2V2ZW50cy9Qcm9jZXNzaW5nSW5zdHJ1Y3Rpb25FdmVudC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlMTk1MmIyLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL3htbC9pbnRlcm5hbC9zdHJlYW0vZXZlbnRzL1Byb2Nlc3NpbmdJbnN0cnVjdGlvbkV2ZW50LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMDEgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLnhtbC5pbnRlcm5hbC5zdHJlYW0uZXZlbnRzIDsKLQotaW1wb3J0IGphdmEuaW8uV3JpdGVyOwotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uTG9jYXRpb247Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5YTUxTdHJlYW1Db25zdGFudHM7Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5YTUxTdHJlYW1FeGNlcHRpb247Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5ldmVudHMuUHJvY2Vzc2luZ0luc3RydWN0aW9uOwotCi0vKiogSW1wbGVtZW50cyBQcm9jZXNzaW5nIEluc3RydWN0aW9uIEV2ZW50Ci0gKgotICpAYXV0aG9yIE5lZXJhaiBCYWphaiwgU3VuIE1pY3Jvc3lzdGVtcy4KLSAqCi0gKi8KLQotCi1wdWJsaWMgY2xhc3MgUHJvY2Vzc2luZ0luc3RydWN0aW9uRXZlbnQgZXh0ZW5kcyBEdW1teUV2ZW50Ci1pbXBsZW1lbnRzIFByb2Nlc3NpbmdJbnN0cnVjdGlvbiB7Ci0KLSAgICAvKiogUHJvY2Vzc2luZyBJbnN0cnVjdGlvbiBOYW1lICovCi0gICAgcHJpdmF0ZSBTdHJpbmcgZk5hbWU7Ci0gICAgLyoqIFByb2Nlc3NzaW5nIGluc3RydWN0aW9uIGNvbnRlbnQgKi8KLSAgICBwcml2YXRlIFN0cmluZyBmQ29udGVudDsKLQotICAgIHB1YmxpYyBQcm9jZXNzaW5nSW5zdHJ1Y3Rpb25FdmVudCgpIHsKLSAgICAgICAgaW5pdCgpOwotICAgIH0KLQotICAgIHB1YmxpYyBQcm9jZXNzaW5nSW5zdHJ1Y3Rpb25FdmVudChTdHJpbmcgdGFyZ2V0TmFtZSwgU3RyaW5nIGRhdGEpIHsKLSAgICAgICAgdGhpcyh0YXJnZXROYW1lLGRhdGEsbnVsbCk7Ci0gICAgfQotCi0gICAgcHVibGljIFByb2Nlc3NpbmdJbnN0cnVjdGlvbkV2ZW50KFN0cmluZyB0YXJnZXROYW1lLCBTdHJpbmcgZGF0YSxMb2NhdGlvbiBsb2MpIHsKLSAgICAgICAgaW5pdCgpOwotICAgICAgICB0aGlzLmZOYW1lID0gdGFyZ2V0TmFtZTsKLSAgICAgICAgZkNvbnRlbnQgPSBkYXRhOwotICAgICAgICBzZXRMb2NhdGlvbihsb2MpOwotICAgIH0KLQotICAgIHByb3RlY3RlZCB2b2lkIGluaXQoKSB7Ci0gICAgICAgIHNldEV2ZW50VHlwZShYTUxTdHJlYW1Db25zdGFudHMuUFJPQ0VTU0lOR19JTlNUUlVDVElPTik7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXQoKSB7Ci0gICAgICAgIHJldHVybiBmTmFtZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRUYXJnZXQoU3RyaW5nIHRhcmdldE5hbWUpIHsKLSAgICAgICAgZk5hbWUgPSB0YXJnZXROYW1lOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldERhdGEoU3RyaW5nIGRhdGEpIHsKLSAgICAgICAgZkNvbnRlbnQgPSBkYXRhOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0RGF0YSgpIHsKLSAgICAgICAgcmV0dXJuIGZDb250ZW50OwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0gICAgICAgIGlmKGZDb250ZW50ICE9IG51bGwgJiYgZk5hbWUgIT0gbnVsbCkKLSAgICAgICAgICAgIHJldHVybiAiPD8iICsgZk5hbWUgKyAiICIgKyBmQ29udGVudCArICI/PiI7Ci0gICAgICAgIGlmKGZOYW1lICE9IG51bGwpCi0gICAgICAgICAgICByZXR1cm4gIjw/IiArIGZOYW1lICsgIj8+IjsKLSAgICAgICAgaWYoZkNvbnRlbnQgIT0gbnVsbCkKLSAgICAgICAgICAgIHJldHVybiAiPD8iICsgZkNvbnRlbnQgKyAiPz4iOwotICAgICAgICBlbHNlCi0gICAgICAgICAgICByZXR1cm4gIjw/Pz4iOwotICAgIH0KLQotICAgIHByb3RlY3RlZCB2b2lkIHdyaXRlQXNFbmNvZGVkVW5pY29kZUV4KGphdmEuaW8uV3JpdGVyIHdyaXRlcikKLSAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgd3JpdGVyLndyaXRlKHRvU3RyaW5nKCkpOwotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4veG1sL2ludGVybmFsL3N0cmVhbS9ldmVudHMvU3RhcnREb2N1bWVudEV2ZW50LmphdmEgYi9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL2V2ZW50cy9TdGFydERvY3VtZW50RXZlbnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMGZkMTZiMy4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL2V2ZW50cy9TdGFydERvY3VtZW50RXZlbnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE3MyArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDA1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ueG1sLmludGVybmFsLnN0cmVhbS5ldmVudHMgOwotCi1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5ldmVudHMuU3RhcnREb2N1bWVudDsKLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLkxvY2F0aW9uOwotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uWE1MU3RyZWFtQ29uc3RhbnRzOwotCi0vKiogSW1wbGVtZW50YXRpb24gb2YgU3RhcnREb2N1bWVudEV2ZW50LgotICoKLSAqIEBhdXRob3IgTmVlcmFqIEJhamFqIFN1biBNaWNyb3N5c3RlbXMsSW5jLgotICogQGF1dGhvciBLLlZlbnVnb3BhbCBTdW4gTWljcm9zeXN0ZW1zLEluYy4KLSAqCi0gKi8KLQotcHVibGljIGNsYXNzIFN0YXJ0RG9jdW1lbnRFdmVudCBleHRlbmRzIER1bW15RXZlbnQKLWltcGxlbWVudHMgU3RhcnREb2N1bWVudCB7Ci0KLSAgICBwcm90ZWN0ZWQgU3RyaW5nIGZTeXN0ZW1JZDsKLSAgICBwcm90ZWN0ZWQgU3RyaW5nIGZFbmNvZGluZ1NjaGVhbTsKLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBmU3RhbmRhbG9uZTsKLSAgICBwcm90ZWN0ZWQgU3RyaW5nIGZWZXJzaW9uOwotICAgIHByaXZhdGUgYm9vbGVhbiBmRW5jb2RpbmdTY2hlbWVTZXQgPSBmYWxzZTsKLSAgICBwcml2YXRlIGJvb2xlYW4gZlN0YW5kYWxvbmVTZXQgPSBmYWxzZTsKLSAgICBwcml2YXRlIGJvb2xlYW4gbmVzdGVkQ2FsbCA9IGZhbHNlOwotCi0gICAgcHVibGljIFN0YXJ0RG9jdW1lbnRFdmVudCgpIHsKLSAgICAgICAgaW5pdCgiVVRGLTgiLCIxLjAiLHRydWUsbnVsbCk7Ci0gICAgfQotCi0gICAgcHVibGljIFN0YXJ0RG9jdW1lbnRFdmVudChTdHJpbmcgZW5jb2RpbmcpewotICAgICAgICBpbml0KGVuY29kaW5nLCIxLjAiLHRydWUsbnVsbCk7Ci0gICAgfQotCi0gICAgcHVibGljIFN0YXJ0RG9jdW1lbnRFdmVudChTdHJpbmcgZW5jb2RpbmcsIFN0cmluZyB2ZXJzaW9uKXsKLSAgICAgICAgaW5pdChlbmNvZGluZyx2ZXJzaW9uLHRydWUsbnVsbCk7Ci0gICAgfQotCi0gICAgcHVibGljIFN0YXJ0RG9jdW1lbnRFdmVudChTdHJpbmcgZW5jb2RpbmcsIFN0cmluZyB2ZXJzaW9uLCBib29sZWFuIHN0YW5kYWxvbmUpewotICAgICAgICB0aGlzLmZTdGFuZGFsb25lU2V0ID0gdHJ1ZTsKLSAgICAgICAgaW5pdChlbmNvZGluZyx2ZXJzaW9uLHN0YW5kYWxvbmUsbnVsbCk7Ci0gICAgfQotCi0gICAgcHVibGljIFN0YXJ0RG9jdW1lbnRFdmVudChTdHJpbmcgZW5jb2RpbmcsIFN0cmluZyB2ZXJzaW9uLCBib29sZWFuIHN0YW5kYWxvbmUsTG9jYXRpb24gbG9jKXsKLSAgICAgICAgdGhpcy5mU3RhbmRhbG9uZVNldCA9IHRydWU7Ci0gICAgICAgIGluaXQoZW5jb2RpbmcsIHZlcnNpb24sIHN0YW5kYWxvbmUsIGxvYyk7Ci0gICAgfQotICAgIHByb3RlY3RlZCB2b2lkIGluaXQoU3RyaW5nIGVuY29kaW5nLCBTdHJpbmcgdmVyc2lvbiwgYm9vbGVhbiBzdGFuZGFsb25lLExvY2F0aW9uIGxvYykgewotICAgICAgICBzZXRFdmVudFR5cGUoWE1MU3RyZWFtQ29uc3RhbnRzLlNUQVJUX0RPQ1VNRU5UKTsKLSAgICAgICAgdGhpcy5mRW5jb2RpbmdTY2hlYW0gPSBlbmNvZGluZzsKLSAgICAgICAgdGhpcy5mVmVyc2lvbiA9IHZlcnNpb247Ci0gICAgICAgIHRoaXMuZlN0YW5kYWxvbmUgPSBzdGFuZGFsb25lOwotICAgICAgICBpZiAoZW5jb2RpbmcgIT0gbnVsbCAmJiAhZW5jb2RpbmcuZXF1YWxzKCIiKSkKLSAgICAgICAgICAgIHRoaXMuZkVuY29kaW5nU2NoZW1lU2V0ID0gdHJ1ZTsKLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICB0aGlzLmZFbmNvZGluZ1NjaGVtZVNldCA9IGZhbHNlOwotICAgICAgICAgICAgdGhpcy5mRW5jb2RpbmdTY2hlYW0gPSAiVVRGLTgiOwotICAgICAgICB9Ci0gICAgICAgIHRoaXMuZkxvY2F0aW9uID0gbG9jOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3lzdGVtSWQoKSB7Ci0gICAgICAgIGlmKGZMb2NhdGlvbiA9PSBudWxsICkKLSAgICAgICAgICAgIHJldHVybiAiIjsKLSAgICAgICAgZWxzZQotICAgICAgICAgICAgcmV0dXJuIGZMb2NhdGlvbi5nZXRTeXN0ZW1JZCgpOwotICAgIH0KLQotCi0gICAgcHVibGljIFN0cmluZyBnZXRDaGFyYWN0ZXJFbmNvZGluZ1NjaGVtZSgpIHsKLSAgICAgICAgcmV0dXJuIGZFbmNvZGluZ1NjaGVhbTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBpc1N0YW5kYWxvbmUoKSB7Ci0gICAgICAgIHJldHVybiBmU3RhbmRhbG9uZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldFZlcnNpb24oKSB7Ci0gICAgICAgIHJldHVybiBmVmVyc2lvbjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRTdGFuZGFsb25lKGJvb2xlYW4gZmxhZykgewotICAgICAgICBmU3RhbmRhbG9uZVNldCA9IHRydWU7Ci0gICAgICAgIGZTdGFuZGFsb25lID0gZmxhZzsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRTdGFuZGFsb25lKFN0cmluZyBzKSB7Ci0gICAgICAgIGZTdGFuZGFsb25lU2V0ID0gdHJ1ZTsKLSAgICAgICAgaWYocyA9PSBudWxsKSB7Ci0gICAgICAgICAgICBmU3RhbmRhbG9uZSA9IHRydWU7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLSAgICAgICAgaWYocy5lcXVhbHMoInllcyIpKQotICAgICAgICAgICAgZlN0YW5kYWxvbmUgPSB0cnVlOwotICAgICAgICBlbHNlCi0gICAgICAgICAgICBmU3RhbmRhbG9uZSA9IGZhbHNlOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGVuY29kaW5nU2V0KCkgewotICAgICAgICByZXR1cm4gZkVuY29kaW5nU2NoZW1lU2V0OwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIHN0YW5kYWxvbmVTZXQoKSB7Ci0gICAgICAgIHJldHVybiBmU3RhbmRhbG9uZVNldDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRFbmNvZGluZyhTdHJpbmcgZW5jb2RpbmcpIHsKLSAgICAgICAgZkVuY29kaW5nU2NoZWFtID0gZW5jb2Rpbmc7Ci0gICAgfQotCi0gICAgdm9pZCBzZXREZWNsYXJlZEVuY29kaW5nKGJvb2xlYW4gdmFsdWUpewotICAgICAgICBmRW5jb2RpbmdTY2hlbWVTZXQgPSB2YWx1ZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRWZXJzaW9uKFN0cmluZyBzKSB7Ci0gICAgICAgIGZWZXJzaW9uID0gczsKLSAgICB9Ci0KLSAgICB2b2lkIGNsZWFyKCkgewotICAgICAgICBmRW5jb2RpbmdTY2hlYW0gPSAiVVRGLTgiOwotICAgICAgICBmU3RhbmRhbG9uZSA9IHRydWU7Ci0gICAgICAgIGZWZXJzaW9uID0gIjEuMCI7Ci0gICAgICAgIGZFbmNvZGluZ1NjaGVtZVNldCA9IGZhbHNlOwotICAgICAgICBmU3RhbmRhbG9uZVNldCA9IGZhbHNlOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0gICAgICAgIFN0cmluZyBzID0gIjw/eG1sIHZlcnNpb249XCIiICsgZlZlcnNpb24gKyAiXCIiOwotICAgICAgICBzID0gcyArICIgZW5jb2Rpbmc9JyIgKyBmRW5jb2RpbmdTY2hlYW0gKyAiJyI7Ci0gICAgICAgIGlmKGZTdGFuZGFsb25lU2V0KSB7Ci0gICAgICAgICAgICBpZihmU3RhbmRhbG9uZSkKLSAgICAgICAgICAgICAgICBzID0gcyArICIgc3RhbmRhbG9uZT0neWVzJz8+IjsKLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICBzID0gcyArICIgc3RhbmRhbG9uZT0nbm8nPz4iOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgcyA9IHMgKyAiPz4iOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBzOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGlzU3RhcnREb2N1bWVudCgpIHsKLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotCi0gICAgcHJvdGVjdGVkIHZvaWQgd3JpdGVBc0VuY29kZWRVbmljb2RlRXgoamF2YS5pby5Xcml0ZXIgd3JpdGVyKQotICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uCi0gICAgewotICAgICAgICB3cml0ZXIud3JpdGUodG9TdHJpbmcoKSk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4veG1sL2ludGVybmFsL3N0cmVhbS9ldmVudHMvU3RhcnRFbGVtZW50RXZlbnQuamF2YSBiL3NyYy9jb20vc3VuL3htbC9pbnRlcm5hbC9zdHJlYW0vZXZlbnRzL1N0YXJ0RWxlbWVudEV2ZW50LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDcxZjY5ODkuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4veG1sL2ludGVybmFsL3N0cmVhbS9ldmVudHMvU3RhcnRFbGVtZW50RXZlbnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIzMSArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDA1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ueG1sLmludGVybmFsLnN0cmVhbS5ldmVudHMgOwotCi1pbXBvcnQgamF2YS51dGlsLkxpc3Q7Ci1pbXBvcnQgamF2YS51dGlsLk1hcDsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKLWltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7Ci1pbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKLWltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsKLQotaW1wb3J0IGphdmF4LnhtbC5uYW1lc3BhY2UuUU5hbWU7Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5ldmVudHMuU3RhcnRFbGVtZW50OwotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uZXZlbnRzLkF0dHJpYnV0ZTsKLWltcG9ydCBqYXZheC54bWwubmFtZXNwYWNlLk5hbWVzcGFjZUNvbnRleHQ7Ci1pbXBvcnQgamF2YS5pby5Xcml0ZXI7Ci1pbXBvcnQgY29tLnN1bi54bWwuaW50ZXJuYWwuc3RyZWFtLnV0aWwuUmVhZE9ubHlJdGVyYXRvcjsKLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLlhNTFN0cmVhbUNvbnN0YW50czsKLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLmV2ZW50cy5OYW1lc3BhY2U7Ci0KLS8qKiBJbXBsZW1lbnRhdGlvbiBvZiBTdGFydEVsZW1lbnRFdmVudC4KLSAqCi0gKiBAYXV0aG9yIE5lZXJhaiBCYWphaiBTdW4gTWljcm9zeXN0ZW1zLEluYy4KLSAqIEBhdXRob3IgSy5WZW51Z29wYWwgU3VuIE1pY3Jvc3lzdGVtcyxJbmMuCi0gKi8KLQotcHVibGljIGNsYXNzIFN0YXJ0RWxlbWVudEV2ZW50IGV4dGVuZHMgRHVtbXlFdmVudAotaW1wbGVtZW50cyBTdGFydEVsZW1lbnQgewotCi0gICAgcHJpdmF0ZSBNYXAgZkF0dHJpYnV0ZXM7Ci0gICAgcHJpdmF0ZSBMaXN0IGZOYW1lc3BhY2VzOwotICAgIHByaXZhdGUgTmFtZXNwYWNlQ29udGV4dCBmTmFtZXNwYWNlQ29udGV4dCA9IG51bGw7Ci0gICAgcHJpdmF0ZSBRTmFtZSBmUU5hbWU7Ci0KLSAgICBwdWJsaWMgU3RhcnRFbGVtZW50RXZlbnQoU3RyaW5nIHByZWZpeCwgU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FscGFydCkgewotICAgICAgICB0aGlzKG5ldyBRTmFtZSh1cmksIGxvY2FscGFydCwgcHJlZml4KSk7Ci0gICAgfQotCi0gICAgcHVibGljIFN0YXJ0RWxlbWVudEV2ZW50KFFOYW1lIHFuYW1lKSB7Ci0gICAgICAgIGZRTmFtZSA9IHFuYW1lOwotICAgICAgICBpbml0KCk7Ci0gICAgfQotCi0gICAgcHVibGljIFN0YXJ0RWxlbWVudEV2ZW50KFN0YXJ0RWxlbWVudCBzdGFydGVsZW1lbnQpIHsKLSAgICAgICAgdGhpcyhzdGFydGVsZW1lbnQuZ2V0TmFtZSgpKTsKLSAgICAgICAgYWRkQXR0cmlidXRlcyhzdGFydGVsZW1lbnQuZ2V0QXR0cmlidXRlcygpKTsKLSAgICAgICAgYWRkTmFtZXNwYWNlQXR0cmlidXRlcyhzdGFydGVsZW1lbnQuZ2V0TmFtZXNwYWNlcygpKTsKLSAgICB9Ci0KLSAgICBwcm90ZWN0ZWQgdm9pZCBpbml0KCkgewotICAgICAgICBzZXRFdmVudFR5cGUoWE1MU3RyZWFtQ29uc3RhbnRzLlNUQVJUX0VMRU1FTlQpOwotICAgICAgICBmQXR0cmlidXRlcyA9IG5ldyBIYXNoTWFwKCk7Ci0gICAgICAgIGZOYW1lc3BhY2VzID0gbmV3IEFycmF5TGlzdCgpOwotICAgIH0KLQotICAgIHB1YmxpYyBRTmFtZSBnZXROYW1lKCkgewotICAgICAgICByZXR1cm4gZlFOYW1lOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldE5hbWUoUU5hbWUgcW5hbWUpIHsKLSAgICAgICAgdGhpcy5mUU5hbWUgPSBxbmFtZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgSXRlcmF0b3IgZ2V0QXR0cmlidXRlcygpIHsKLSAgICAgICAgaWYoZkF0dHJpYnV0ZXMgIT0gbnVsbCl7Ci0gICAgICAgICAgICBDb2xsZWN0aW9uIGNvbGwgPSBmQXR0cmlidXRlcy52YWx1ZXMoKTsKLSAgICAgICAgICAgIHJldHVybiBuZXcgUmVhZE9ubHlJdGVyYXRvcihjb2xsLml0ZXJhdG9yKCkpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBuZXcgUmVhZE9ubHlJdGVyYXRvcigpOwotICAgIH0KLQotICAgIHB1YmxpYyBJdGVyYXRvciBnZXROYW1lc3BhY2VzKCkgewotICAgICAgICBpZihmTmFtZXNwYWNlcyAhPSBudWxsKXsKLSAgICAgICAgICAgIHJldHVybiBuZXcgUmVhZE9ubHlJdGVyYXRvcihmTmFtZXNwYWNlcy5pdGVyYXRvcigpKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbmV3IFJlYWRPbmx5SXRlcmF0b3IoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgQXR0cmlidXRlIGdldEF0dHJpYnV0ZUJ5TmFtZShRTmFtZSBxbmFtZSkgewotICAgICAgICBpZihxbmFtZSA9PSBudWxsKQotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIHJldHVybiAoQXR0cmlidXRlKWZBdHRyaWJ1dGVzLmdldChxbmFtZSk7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXROYW1lc3BhY2UoKXsKLSAgICAgICAgcmV0dXJuIGZRTmFtZS5nZXROYW1lc3BhY2VVUkkoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWVzcGFjZVVSSShTdHJpbmcgcHJlZml4KSB7Ci0gICAgICAgIC8vY2hlY2sgdGhhdCBVUkkgd2FzIHN1cHBsaWVkIHdoZW4gY3JlYXRpbmcgdGhpcyBzdGFydEVsZW1lbnQgZXZlbnQgYW5kIHByZWZpeCBtYXRjaGVzCi0gICAgICAgIGlmKCBnZXROYW1lc3BhY2UoKSAhPSBudWxsICYmIGZRTmFtZS5nZXRQcmVmaXgoKS5lcXVhbHMocHJlZml4KSkgcmV0dXJuIGdldE5hbWVzcGFjZSgpOwotICAgICAgICAvL2Vsc2UgY2hlY2sgdGhlIG5hbWVzcGFjZSBjb250ZXh0Ci0gICAgICAgIGlmKGZOYW1lc3BhY2VDb250ZXh0ICE9IG51bGwpCi0gICAgICAgICAgICByZXR1cm4gZk5hbWVzcGFjZUNvbnRleHQuZ2V0TmFtZXNwYWNlVVJJKHByZWZpeCk7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPlJldHVybiBhIDxjb2RlPlN0cmluZzwvY29kZT4gcmVwcmVzZW50YXRpb24gb2YgdGhpcwotICAgICAqIDxjb2RlPlN0YXJ0RWxlbWVudDwvY29kZT4gZm9ybWF0dGVkIGFzIFhNTC48L3A+Ci0gICAgICoKLSAgICAgKiBAcmV0dXJuIDxjb2RlPlN0cmluZzwvY29kZT4gcmVwcmVzZW50YXRpb24gb2YgdGhpcwotICAgICAqICAgPGNvZGU+U3RhcnRFbGVtZW50PC9jb2RlPiBmb3JtYXR0ZWQgYXMgWE1MLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0KLSAgICAgICAgU3RyaW5nQnVmZmVyIHN0YXJ0RWxlbWVudCA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLQotICAgICAgICAvLyBvcGVuIGVsZW1lbnQKLSAgICAgICAgc3RhcnRFbGVtZW50LmFwcGVuZCgiPCIpOwotICAgICAgICBzdGFydEVsZW1lbnQuYXBwZW5kKG5hbWVBc1N0cmluZygpKTsKLQotICAgICAgICAvLyBhZGQgYW55IGF0dHJpYnV0ZXMKLSAgICAgICAgaWYgKGZBdHRyaWJ1dGVzICE9IG51bGwpIHsKLSAgICAgICAgICAgIEl0ZXJhdG9yIGl0ID0gdGhpcy5nZXRBdHRyaWJ1dGVzKCk7Ci0gICAgICAgICAgICBBdHRyaWJ1dGUgYXR0ciA9IG51bGw7Ci0gICAgICAgICAgICB3aGlsZSAoaXQuaGFzTmV4dCgpKSB7Ci0gICAgICAgICAgICAgICAgYXR0ciA9IChBdHRyaWJ1dGUpIGl0Lm5leHQoKTsKLSAgICAgICAgICAgICAgICBzdGFydEVsZW1lbnQuYXBwZW5kKCIgIik7Ci0gICAgICAgICAgICAgICAgc3RhcnRFbGVtZW50LmFwcGVuZChhdHRyLnRvU3RyaW5nKCkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gYWRkIGFueSBuYW1lc3BhY2VzCi0gICAgICAgIGlmIChmTmFtZXNwYWNlcyAhPSBudWxsKSB7Ci0gICAgICAgICAgICBJdGVyYXRvciBpdCA9IGZOYW1lc3BhY2VzLml0ZXJhdG9yKCk7Ci0gICAgICAgICAgICBOYW1lc3BhY2UgYXR0ciA9IG51bGw7Ci0gICAgICAgICAgICB3aGlsZSAoaXQuaGFzTmV4dCgpKSB7Ci0gICAgICAgICAgICAgICAgYXR0ciA9IChOYW1lc3BhY2UpIGl0Lm5leHQoKTsKLSAgICAgICAgICAgICAgICBzdGFydEVsZW1lbnQuYXBwZW5kKCIgIik7Ci0gICAgICAgICAgICAgICAgc3RhcnRFbGVtZW50LmFwcGVuZChhdHRyLnRvU3RyaW5nKCkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gY2xvc2Ugc3RhcnQgdGFnCi0gICAgICAgIHN0YXJ0RWxlbWVudC5hcHBlbmQoIj4iKTsKLQotICAgICAgICAvLyByZXR1cm4gU3RhcnRFbGVtZW50IGFzIGEgU3RyaW5nCi0gICAgICAgIHJldHVybiBzdGFydEVsZW1lbnQudG9TdHJpbmcoKTsKLSAgICB9Ci0KLSAgICAvKiogUmV0dXJuIHRoaXMgZXZlbnQgYXMgU3RyaW5nCi0gICAgICogQHJldHVybiBTdHJpbmcgRXZlbnQgcmV0dXJuZWQgYXMgc3RyaW5nLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgbmFtZUFzU3RyaW5nKCkgewotICAgICAgICBpZigiIi5lcXVhbHMoZlFOYW1lLmdldE5hbWVzcGFjZVVSSSgpKSkKLSAgICAgICAgICAgIHJldHVybiBmUU5hbWUuZ2V0TG9jYWxQYXJ0KCk7Ci0gICAgICAgIGlmKGZRTmFtZS5nZXRQcmVmaXgoKSAhPSBudWxsKQotICAgICAgICAgICAgcmV0dXJuICJbJyIgKyBmUU5hbWUuZ2V0TmFtZXNwYWNlVVJJKCkgKyAiJ106IiArIGZRTmFtZS5nZXRQcmVmaXgoKSArICI6IiArIGZRTmFtZS5nZXRMb2NhbFBhcnQoKTsKLSAgICAgICAgZWxzZQotICAgICAgICAgICAgcmV0dXJuICJbJyIgKyBmUU5hbWUuZ2V0TmFtZXNwYWNlVVJJKCkgKyAiJ106IiArIGZRTmFtZS5nZXRMb2NhbFBhcnQoKTsKLSAgICB9Ci0KLQotICAgIC8qKiBHZXRzIGEgcmVhZC1vbmx5IG5hbWVzcGFjZSBjb250ZXh0LiBJZiBubyBjb250ZXh0IGlzCi0gICAgICogYXZhaWxhYmxlIHRoaXMgbWV0aG9kIHdpbGwgcmV0dXJuIGFuIGVtcHR5IG5hbWVzcGFjZSBjb250ZXh0LgotICAgICAqIFRoZSBOYW1lc3BhY2VDb250ZXh0IGNvbnRhaW5zIGluZm9ybWF0aW9uIGFib3V0IGFsbCBuYW1lc3BhY2VzCi0gICAgICogaW4gc2NvcGUgZm9yIHRoaXMgU3RhcnRFbGVtZW50LgotICAgICAqCi0gICAgICogQHJldHVybiB0aGUgY3VycmVudCBuYW1lc3BhY2UgY29udGV4dAotICAgICAqLwotICAgIHB1YmxpYyBOYW1lc3BhY2VDb250ZXh0IGdldE5hbWVzcGFjZUNvbnRleHQoKSB7Ci0gICAgICAgIHJldHVybiBmTmFtZXNwYWNlQ29udGV4dDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXROYW1lc3BhY2VDb250ZXh0KE5hbWVzcGFjZUNvbnRleHQgbmMpIHsKLSAgICAgICAgZk5hbWVzcGFjZUNvbnRleHQgPSBuYzsKLSAgICB9Ci0KLSAgICBwcm90ZWN0ZWQgdm9pZCB3cml0ZUFzRW5jb2RlZFVuaWNvZGVFeChqYXZhLmlvLldyaXRlciB3cml0ZXIpCi0gICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIHdyaXRlci53cml0ZSh0b1N0cmluZygpKTsKLSAgICB9Ci0KLSAgICB2b2lkIGFkZEF0dHJpYnV0ZShBdHRyaWJ1dGUgYXR0cil7Ci0gICAgICAgIGlmKGF0dHIuaXNOYW1lc3BhY2UoKSl7Ci0gICAgICAgICAgICBmTmFtZXNwYWNlcy5hZGQoYXR0cik7Ci0gICAgICAgIH1lbHNlewotICAgICAgICAgICAgZkF0dHJpYnV0ZXMucHV0KGF0dHIuZ2V0TmFtZSgpLGF0dHIpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgdm9pZCBhZGRBdHRyaWJ1dGVzKEl0ZXJhdG9yIGF0dHJzKXsKLSAgICAgICAgaWYoYXR0cnMgPT0gbnVsbCkKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgd2hpbGUoYXR0cnMuaGFzTmV4dCgpKXsKLSAgICAgICAgICAgIEF0dHJpYnV0ZSBhdHRyID0gKEF0dHJpYnV0ZSlhdHRycy5uZXh0KCk7Ci0gICAgICAgICAgICBmQXR0cmlidXRlcy5wdXQoYXR0ci5nZXROYW1lKCksYXR0cik7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICB2b2lkIGFkZE5hbWVzcGFjZUF0dHJpYnV0ZShOYW1lc3BhY2UgYXR0cil7Ci0gICAgICAgIGlmKGF0dHIgPT0gbnVsbCkKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgZk5hbWVzcGFjZXMuYWRkKGF0dHIpOwotICAgIH0KLQotICAgIHZvaWQgYWRkTmFtZXNwYWNlQXR0cmlidXRlcyhJdGVyYXRvciBhdHRycyl7Ci0gICAgICAgIGlmKGF0dHJzID09IG51bGwpCi0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIHdoaWxlKGF0dHJzLmhhc05leHQoKSl7Ci0gICAgICAgICAgICBOYW1lc3BhY2UgYXR0ciA9IChOYW1lc3BhY2UpYXR0cnMubmV4dCgpOwotICAgICAgICAgICAgZk5hbWVzcGFjZXMuYWRkKGF0dHIpOwotICAgICAgICB9Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL2V2ZW50cy9YTUxFdmVudEFsbG9jYXRvckltcGwuamF2YSBiL3NyYy9jb20vc3VuL3htbC9pbnRlcm5hbC9zdHJlYW0vZXZlbnRzL1hNTEV2ZW50QWxsb2NhdG9ySW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwNjVhN2NkLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL3htbC9pbnRlcm5hbC9zdHJlYW0vZXZlbnRzL1hNTEV2ZW50QWxsb2NhdG9ySW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjU3ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMDYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi54bWwuaW50ZXJuYWwuc3RyZWFtLmV2ZW50czsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5Qcm9wZXJ0eU1hbmFnZXI7Ci1pbXBvcnQgamF2YS51dGlsLkxpc3Q7Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS51dGlsLlhNTEV2ZW50QWxsb2NhdG9yOwotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uKjsKLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLmV2ZW50cy4qOwotaW1wb3J0IGphdmF4LnhtbC5YTUxDb25zdGFudHM7Ci1pbXBvcnQgamF2YXgueG1sLm5hbWVzcGFjZS5RTmFtZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuTmFtZXNwYWNlQ29udGV4dFdyYXBwZXI7Ci1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsLk5hbWVzcGFjZVN1cHBvcnQ7Ci0KLS8qKgotICogSW1wbGVtZW50YXRpb24gb2YgWE1MRXZlbnQgQWxsb2NhdG9yLgotICogQGF1dGhvciBOZWVyYWouYmFqYWpAc3VuLmNvbSwgay52ZW51Z29wYWxAc3VuLmNvbQotICovCi1wdWJsaWMgY2xhc3MgWE1MRXZlbnRBbGxvY2F0b3JJbXBsIGltcGxlbWVudHMgWE1MRXZlbnRBbGxvY2F0b3IgewotCi0gICAgLyoqIENyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgWE1MRXZlbnRBbGxvY2F0b3IgKi8KLSAgICBwdWJsaWMgWE1MRXZlbnRBbGxvY2F0b3JJbXBsKCkgewotICAgIH0KLQotICAgIHB1YmxpYyBqYXZheC54bWwuc3RyZWFtLmV2ZW50cy5YTUxFdmVudCBhbGxvY2F0ZShqYXZheC54bWwuc3RyZWFtLlhNTFN0cmVhbVJlYWRlciB4TUxTdHJlYW1SZWFkZXIpIHRocm93cyBqYXZheC54bWwuc3RyZWFtLlhNTFN0cmVhbUV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmKHhNTFN0cmVhbVJlYWRlciA9PSBudWxsICkKLSAgICAgICAgICAgIHRocm93IG5ldyBYTUxTdHJlYW1FeGNlcHRpb24oIlJlYWRlciBjYW5ub3QgYmUgbnVsbCIpOwotICAgICAgICAvLyAgICAgICAgYWxsb2NhdGUgaXMgbm90IHN1cHBvc2VkIHRvIGNoYW5nZSB0aGUgc3RhdGUgb2YgdGhlIHJlYWRlciBzbyB3ZSBzaG91bGRuJ3QgYmUgY2FsbGluZyBuZXh0LgotICAgICAgICAvLyAgICAgICAgcmV0dXJuIGdldE5leHRFdmVudCh4TUxTdHJlYW1SZWFkZXIpOwotICAgICAgICByZXR1cm4gZ2V0WE1MRXZlbnQoeE1MU3RyZWFtUmVhZGVyKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBhbGxvY2F0ZShqYXZheC54bWwuc3RyZWFtLlhNTFN0cmVhbVJlYWRlciB4TUxTdHJlYW1SZWFkZXIsIGphdmF4LnhtbC5zdHJlYW0udXRpbC5YTUxFdmVudENvbnN1bWVyIHhNTEV2ZW50Q29uc3VtZXIpIHRocm93cyBqYXZheC54bWwuc3RyZWFtLlhNTFN0cmVhbUV4Y2VwdGlvbiB7Ci0gICAgICAgIFhNTEV2ZW50IGN1cnJlbnRFdmVudCA9IGdldFhNTEV2ZW50KHhNTFN0cmVhbVJlYWRlcik7Ci0gICAgICAgIGlmKGN1cnJlbnRFdmVudCAhPSBudWxsICkKLSAgICAgICAgICAgIHhNTEV2ZW50Q29uc3VtZXIuYWRkKGN1cnJlbnRFdmVudCk7Ci0KLSAgICAgICAgcmV0dXJuOwotICAgIH0KLQotICAgIHB1YmxpYyBqYXZheC54bWwuc3RyZWFtLnV0aWwuWE1MRXZlbnRBbGxvY2F0b3IgbmV3SW5zdGFuY2UoKSB7Ci0gICAgICAgIHJldHVybiBuZXcgWE1MRXZlbnRBbGxvY2F0b3JJbXBsKCk7Ci0gICAgfQotCi0gICAgLy9SRVZJU0lUOiBzaG91bGRuJ3Qgd2UgYmUgdXNpbmcgWE1MRXZlbnRGYWN0b3J5IHRvIGNyZWF0ZSBldmVudHMuCi0gICAgWE1MRXZlbnQgZ2V0WE1MRXZlbnQoWE1MU3RyZWFtUmVhZGVyIHN0cmVhbVJlYWRlcil7Ci0gICAgICAgIFhNTEV2ZW50IGV2ZW50ID0gbnVsbDsKLSAgICAgICAgLy9yZXR1cm5zIHRoZSBjdXJyZW50IGV2ZW50Ci0gICAgICAgIGludCBldmVudFR5cGUgPSBzdHJlYW1SZWFkZXIuZ2V0RXZlbnRUeXBlKCk7Ci0gICAgICAgIHN3aXRjaChldmVudFR5cGUpewotCi0gICAgICAgICAgICBjYXNlIFhNTEV2ZW50LlNUQVJUX0VMRU1FTlQ6ewotICAgICAgICAgICAgICAgIFN0YXJ0RWxlbWVudEV2ZW50IHN0YXJ0RWxlbWVudEV2ZW50ID0gbmV3IFN0YXJ0RWxlbWVudEV2ZW50KGdldFFOYW1lKHN0cmVhbVJlYWRlcikpOwotICAgICAgICAgICAgICAgIGZpbGxBdHRyaWJ1dGVzKHN0YXJ0RWxlbWVudEV2ZW50LHN0cmVhbVJlYWRlcik7Ci0gICAgICAgICAgICAgICAgLy93ZSBtaWdodCBoYXZlIGRpZmZlcmVudCBYTUxTdHJlYW1SZWFkZXIgc28gY2hlY2sgZXZlcnkgdGltZSBmb3IgdGhlIG5hbWVzcGFjZSBhd2FyZSBwcm9wZXJ0eQotICAgICAgICAgICAgICAgIC8vd2Ugc2hvdWxkIGJlIHNldHRpbmcgbmFtZXNwYWNlIHJlbGF0ZWQgdmFsdWVzIG9ubHkgd2hlbiBpc05hbWVzcGFjZUF3YXJlIGlzICd0cnVlJwotICAgICAgICAgICAgICAgIGlmKCAoKEJvb2xlYW4pc3RyZWFtUmVhZGVyLmdldFByb3BlcnR5KFhNTElucHV0RmFjdG9yeS5JU19OQU1FU1BBQ0VfQVdBUkUpKS5ib29sZWFuVmFsdWUoKSApewotICAgICAgICAgICAgICAgICAgICBmaWxsTmFtZXNwYWNlQXR0cmlidXRlcyhzdGFydEVsZW1lbnRFdmVudCwgc3RyZWFtUmVhZGVyKTsKLSAgICAgICAgICAgICAgICAgICAgc2V0TmFtZXNwYWNlQ29udGV4dChzdGFydEVsZW1lbnRFdmVudCxzdHJlYW1SZWFkZXIpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIHN0YXJ0RWxlbWVudEV2ZW50LnNldExvY2F0aW9uKHN0cmVhbVJlYWRlci5nZXRMb2NhdGlvbigpKTsKLSAgICAgICAgICAgICAgICBldmVudCA9IHN0YXJ0RWxlbWVudEV2ZW50IDsKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhc2UgWE1MRXZlbnQuRU5EX0VMRU1FTlQ6ewotICAgICAgICAgICAgICAgIEVuZEVsZW1lbnRFdmVudCBlbmRFbGVtZW50RXZlbnQgPSBuZXcgRW5kRWxlbWVudEV2ZW50KGdldFFOYW1lKHN0cmVhbVJlYWRlcikpOwotICAgICAgICAgICAgICAgIGVuZEVsZW1lbnRFdmVudC5zZXRMb2NhdGlvbihzdHJlYW1SZWFkZXIuZ2V0TG9jYXRpb24oKSk7Ci0KLSAgICAgICAgICAgICAgICBpZiggKChCb29sZWFuKXN0cmVhbVJlYWRlci5nZXRQcm9wZXJ0eShYTUxJbnB1dEZhY3RvcnkuSVNfTkFNRVNQQUNFX0FXQVJFKSkuYm9vbGVhblZhbHVlKCkgKXsKLSAgICAgICAgICAgICAgICAgICAgZmlsbE5hbWVzcGFjZUF0dHJpYnV0ZXMoZW5kRWxlbWVudEV2ZW50LHN0cmVhbVJlYWRlcik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGV2ZW50ID0gZW5kRWxlbWVudEV2ZW50IDsKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhc2UgWE1MRXZlbnQuUFJPQ0VTU0lOR19JTlNUUlVDVElPTjp7Ci0gICAgICAgICAgICAgICAgUHJvY2Vzc2luZ0luc3RydWN0aW9uRXZlbnQgcGlFdmVudCA9IG5ldyBQcm9jZXNzaW5nSW5zdHJ1Y3Rpb25FdmVudChzdHJlYW1SZWFkZXIuZ2V0UElUYXJnZXQoKSxzdHJlYW1SZWFkZXIuZ2V0UElEYXRhKCkpOwotICAgICAgICAgICAgICAgIHBpRXZlbnQuc2V0TG9jYXRpb24oc3RyZWFtUmVhZGVyLmdldExvY2F0aW9uKCkpOwotICAgICAgICAgICAgICAgIGV2ZW50ID0gcGlFdmVudCA7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXNlIFhNTEV2ZW50LkNIQVJBQ1RFUlM6ewotICAgICAgICAgICAgICAgIENoYXJhY3RlckV2ZW50IGNEYXRhRXZlbnQgPSBuZXcgQ2hhcmFjdGVyRXZlbnQoc3RyZWFtUmVhZGVyLmdldFRleHQoKSk7Ci0gICAgICAgICAgICAgICAgY0RhdGFFdmVudC5zZXRMb2NhdGlvbihzdHJlYW1SZWFkZXIuZ2V0TG9jYXRpb24oKSk7Ci0gICAgICAgICAgICAgICAgZXZlbnQgPSBjRGF0YUV2ZW50IDsKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhc2UgWE1MRXZlbnQuQ09NTUVOVDp7Ci0gICAgICAgICAgICAgICAgQ29tbWVudEV2ZW50IGNvbW1lbnRFdmVudCA9IG5ldyBDb21tZW50RXZlbnQoc3RyZWFtUmVhZGVyLmdldFRleHQoKSk7Ci0gICAgICAgICAgICAgICAgY29tbWVudEV2ZW50LnNldExvY2F0aW9uKHN0cmVhbVJlYWRlci5nZXRMb2NhdGlvbigpKTsKLSAgICAgICAgICAgICAgICBldmVudCA9IGNvbW1lbnRFdmVudCA7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXNlIFhNTEV2ZW50LlNUQVJUX0RPQ1VNRU5UOnsKLSAgICAgICAgICAgICAgICBTdGFydERvY3VtZW50RXZlbnQgc2RFdmVudCA9IG5ldyBTdGFydERvY3VtZW50RXZlbnQoKTsKLSAgICAgICAgICAgICAgICBzZEV2ZW50LnNldFZlcnNpb24oc3RyZWFtUmVhZGVyLmdldFZlcnNpb24oKSk7Ci0gICAgICAgICAgICAgICAgc2RFdmVudC5zZXRFbmNvZGluZyhzdHJlYW1SZWFkZXIuZ2V0RW5jb2RpbmcoKSk7Ci0gICAgICAgICAgICAgICAgaWYoc3RyZWFtUmVhZGVyLmdldENoYXJhY3RlckVuY29kaW5nU2NoZW1lKCkgIT0gbnVsbCl7Ci0gICAgICAgICAgICAgICAgICAgIHNkRXZlbnQuc2V0RGVjbGFyZWRFbmNvZGluZyh0cnVlKTsKLSAgICAgICAgICAgICAgICB9ZWxzZXsKLSAgICAgICAgICAgICAgICAgICAgc2RFdmVudC5zZXREZWNsYXJlZEVuY29kaW5nKGZhbHNlKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgc2RFdmVudC5zZXRTdGFuZGFsb25lKHN0cmVhbVJlYWRlci5pc1N0YW5kYWxvbmUoKSk7Ci0gICAgICAgICAgICAgICAgc2RFdmVudC5zZXRMb2NhdGlvbihzdHJlYW1SZWFkZXIuZ2V0TG9jYXRpb24oKSk7Ci0gICAgICAgICAgICAgICAgZXZlbnQgPSBzZEV2ZW50IDsKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhc2UgWE1MRXZlbnQuRU5EX0RPQ1VNRU5UOnsKLSAgICAgICAgICAgICAgICBFbmREb2N1bWVudEV2ZW50IGVuZERvY3VtZW50RXZlbnQgPSBuZXcgRW5kRG9jdW1lbnRFdmVudCgpIDsKLSAgICAgICAgICAgICAgICBlbmREb2N1bWVudEV2ZW50LnNldExvY2F0aW9uKHN0cmVhbVJlYWRlci5nZXRMb2NhdGlvbigpKTsKLSAgICAgICAgICAgICAgICBldmVudCA9IGVuZERvY3VtZW50RXZlbnQgOwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2FzZSBYTUxFdmVudC5FTlRJVFlfUkVGRVJFTkNFOnsKLSAgICAgICAgICAgICAgICBFbnRpdHlSZWZlcmVuY2VFdmVudCBlbnRpdHlFdmVudCA9ICBuZXcgRW50aXR5UmVmZXJlbmNlRXZlbnQoc3RyZWFtUmVhZGVyLmdldExvY2FsTmFtZSgpLCBuZXcgRW50aXR5RGVjbGFyYXRpb25JbXBsKHN0cmVhbVJlYWRlci5nZXRMb2NhbE5hbWUoKSxzdHJlYW1SZWFkZXIuZ2V0VGV4dCgpKSk7Ci0gICAgICAgICAgICAgICAgZW50aXR5RXZlbnQuc2V0TG9jYXRpb24oc3RyZWFtUmVhZGVyLmdldExvY2F0aW9uKCkpOwotICAgICAgICAgICAgICAgIGV2ZW50ID0gZW50aXR5RXZlbnQ7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhc2UgWE1MRXZlbnQuQVRUUklCVVRFOnsKLSAgICAgICAgICAgICAgICBldmVudCA9IG51bGwgOwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2FzZSBYTUxFdmVudC5EVEQ6ewotICAgICAgICAgICAgICAgIERUREV2ZW50IGR0ZEV2ZW50ID0gbmV3IERUREV2ZW50KHN0cmVhbVJlYWRlci5nZXRUZXh0KCkpOwotICAgICAgICAgICAgICAgIGR0ZEV2ZW50LnNldExvY2F0aW9uKHN0cmVhbVJlYWRlci5nZXRMb2NhdGlvbigpKTsKLSAgICAgICAgICAgICAgICBMaXN0IGVudGl0aWVzID0gKExpc3Qpc3RyZWFtUmVhZGVyLmdldFByb3BlcnR5KFByb3BlcnR5TWFuYWdlci5TVEFYX0VOVElUSUVTKTsKLSAgICAgICAgICAgICAgICBpZiAoZW50aXRpZXMgIT0gbnVsbCAmJiBlbnRpdGllcy5zaXplKCkgIT0gMCkgZHRkRXZlbnQuc2V0RW50aXRpZXMoZW50aXRpZXMpOwotICAgICAgICAgICAgICAgIExpc3Qgbm90YXRpb25zID0gKExpc3Qpc3RyZWFtUmVhZGVyLmdldFByb3BlcnR5KFByb3BlcnR5TWFuYWdlci5TVEFYX05PVEFUSU9OUyk7Ci0gICAgICAgICAgICAgICAgaWYgKG5vdGF0aW9ucyAhPSBudWxsICYmIG5vdGF0aW9ucy5zaXplKCkgIT0gMCkgZHRkRXZlbnQuc2V0Tm90YXRpb25zKG5vdGF0aW9ucyk7Ci0gICAgICAgICAgICAgICAgZXZlbnQgPSBkdGRFdmVudDsKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhc2UgWE1MRXZlbnQuQ0RBVEE6ewotICAgICAgICAgICAgICAgIENoYXJhY3RlckV2ZW50IGNEYXRhRXZlbnQgPSBuZXcgQ2hhcmFjdGVyRXZlbnQoc3RyZWFtUmVhZGVyLmdldFRleHQoKSx0cnVlKTsKLSAgICAgICAgICAgICAgICBjRGF0YUV2ZW50LnNldExvY2F0aW9uKHN0cmVhbVJlYWRlci5nZXRMb2NhdGlvbigpKTsKLSAgICAgICAgICAgICAgICBldmVudCA9IGNEYXRhRXZlbnQgOwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2FzZSBYTUxFdmVudC5TUEFDRTp7Ci0gICAgICAgICAgICAgICAgQ2hhcmFjdGVyRXZlbnQgc3BhY2VFdmVudCA9IG5ldyBDaGFyYWN0ZXJFdmVudChzdHJlYW1SZWFkZXIuZ2V0VGV4dCgpLGZhbHNlLHRydWUpOwotICAgICAgICAgICAgICAgIHNwYWNlRXZlbnQuc2V0TG9jYXRpb24oc3RyZWFtUmVhZGVyLmdldExvY2F0aW9uKCkpOwotICAgICAgICAgICAgICAgIGV2ZW50ID0gc3BhY2VFdmVudCA7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGV2ZW50IDsKLSAgICB9Ci0KLSAgICAvL3RoaXMgZnVuY3Rpb24gaXMgbm90IHVzZWQuLgotICAgIHByb3RlY3RlZCBYTUxFdmVudCBnZXROZXh0RXZlbnQoWE1MU3RyZWFtUmVhZGVyIHN0cmVhbVJlYWRlcikgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbnsKLSAgICAgICAgLy9hZHZhbmNlIHRoZSByZWFkZXIgdG8gbmV4dCBldmVudC4KLSAgICAgICAgc3RyZWFtUmVhZGVyLm5leHQoKTsKLSAgICAgICAgcmV0dXJuIGdldFhNTEV2ZW50KHN0cmVhbVJlYWRlcik7Ci0gICAgfQotCi0gICAgcHJvdGVjdGVkIHZvaWQgZmlsbEF0dHJpYnV0ZXMoU3RhcnRFbGVtZW50RXZlbnQgZXZlbnQsWE1MU3RyZWFtUmVhZGVyIHhtbHIpewotCi0gICAgICAgIGludCBsZW4gPSB4bWxyLmdldEF0dHJpYnV0ZUNvdW50KCk7Ci0gICAgICAgIFFOYW1lIHFuYW1lID0gbnVsbDsKLSAgICAgICAgQXR0cmlidXRlSW1wbCBhdHRyID0gbnVsbDsKLSAgICAgICAgTmFtZXNwYWNlSW1wbCBuYXR0ciA9IG51bGw7Ci0gICAgICAgIGZvcihpbnQgaT0wOyBpPGxlbiA7aSsrKXsKLSAgICAgICAgICAgIHFuYW1lID0geG1sci5nZXRBdHRyaWJ1dGVOYW1lKGkpOwotICAgICAgICAgICAgLy90aGlzIG1ldGhvZCBkb2Vzbid0IGluY2x1ZGUgbmFtZXNwYWNlIGRlY2xhcmF0aW9ucwotICAgICAgICAgICAgLy9zbyB3ZSBjYW4gYmUgc3VyZSB0aGF0IHRoZXJlIHdvbnQgYmUgYW55IG5hbWVzcGFjZSBkZWNsYXJhdGlvbiBhcyBwYXJ0IG9mIHRoaXMgZnVuY3Rpb24gY2FsbAotICAgICAgICAgICAgLy93ZSBjYW4gYXZvaWQgdGhpcyBjaGVjayAtIG5iLgotICAgICAgICAgICAgLyoqCi0gICAgICAgICAgICAgKiBwcmVmaXggPSBxbmFtZS5nZXRQcmVmaXgoKTsKLSAgICAgICAgICAgICAqIGxvY2FscGFydCA9IHFuYW1lLmdldExvY2FsUGFydCgpOwotICAgICAgICAgICAgICogaWYgKHByZWZpeC5lcXVhbHMoWE1MQ29uc3RhbnRzLlhNTE5TX0FUVFJJQlVURSkgKSB7Ci0gICAgICAgICAgICAgKiBhdHRyID0gbmV3IE5hbWVzcGFjZUltcGwobG9jYWxwYXJ0LHhtbHIuZ2V0QXR0cmlidXRlVmFsdWUoaSkpOwotICAgICAgICAgICAgICogfWVsc2UgaWYgKHByZWZpeC5lcXVhbHMoWE1MQ29uc3RhbnRzLkRFRkFVTFRfTlNfUFJFRklYKSl7Ci0gICAgICAgICAgICAgKiBhdHRyID0gbmV3IE5hbWVzcGFjZUltcGwoeG1sci5nZXRBdHRyaWJ1dGVWYWx1ZShpKSk7Ci0gICAgICAgICAgICAgKiB9ZWxzZXsKLSAgICAgICAgICAgICAqIGF0dHIgPSBuZXcgQXR0cmlidXRlSW1wbCgpOwotICAgICAgICAgICAgICogYXR0ci5zZXROYW1lKHFuYW1lKTsKLSAgICAgICAgICAgICAqIH0KLSAgICAgICAgICAgICAqKi8KLSAgICAgICAgICAgIGF0dHIgPSBuZXcgQXR0cmlidXRlSW1wbCgpOwotICAgICAgICAgICAgYXR0ci5zZXROYW1lKHFuYW1lKTsKLSAgICAgICAgICAgIGF0dHIuc2V0QXR0cmlidXRlVHlwZSh4bWxyLmdldEF0dHJpYnV0ZVR5cGUoaSkpOwotICAgICAgICAgICAgYXR0ci5zZXRTcGVjaWZpZWQoeG1sci5pc0F0dHJpYnV0ZVNwZWNpZmllZChpKSk7Ci0gICAgICAgICAgICBhdHRyLnNldFZhbHVlKHhtbHIuZ2V0QXR0cmlidXRlVmFsdWUoaSkpOwotICAgICAgICAgICAgZXZlbnQuYWRkQXR0cmlidXRlKGF0dHIpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHJvdGVjdGVkIHZvaWQgZmlsbE5hbWVzcGFjZUF0dHJpYnV0ZXMoU3RhcnRFbGVtZW50RXZlbnQgZXZlbnQsWE1MU3RyZWFtUmVhZGVyIHhtbHIpewotICAgICAgICBpbnQgY291bnQgPSB4bWxyLmdldE5hbWVzcGFjZUNvdW50KCk7Ci0gICAgICAgIFN0cmluZyB1cmkgPSBudWxsOwotICAgICAgICBTdHJpbmcgcHJlZml4ID0gbnVsbDsKLSAgICAgICAgTmFtZXNwYWNlSW1wbCBhdHRyID0gbnVsbDsKLSAgICAgICAgZm9yKGludCBpPTA7aTwgY291bnQ7aSsrKXsKLSAgICAgICAgICAgIHVyaSA9IHhtbHIuZ2V0TmFtZXNwYWNlVVJJKGkpOwotICAgICAgICAgICAgcHJlZml4ID0geG1sci5nZXROYW1lc3BhY2VQcmVmaXgoaSk7Ci0gICAgICAgICAgICBpZihwcmVmaXggPT0gbnVsbCl7Ci0gICAgICAgICAgICAgICAgcHJlZml4ID0gWE1MQ29uc3RhbnRzLkRFRkFVTFRfTlNfUFJFRklYOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgYXR0ciA9IG5ldyBOYW1lc3BhY2VJbXBsKHByZWZpeCx1cmkpOwotICAgICAgICAgICAgZXZlbnQuYWRkTmFtZXNwYWNlQXR0cmlidXRlKGF0dHIpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHJvdGVjdGVkIHZvaWQgZmlsbE5hbWVzcGFjZUF0dHJpYnV0ZXMoRW5kRWxlbWVudEV2ZW50IGV2ZW50LFhNTFN0cmVhbVJlYWRlciB4bWxyKXsKLSAgICAgICAgaW50IGNvdW50ID0geG1sci5nZXROYW1lc3BhY2VDb3VudCgpOwotICAgICAgICBTdHJpbmcgdXJpID0gbnVsbDsKLSAgICAgICAgU3RyaW5nIHByZWZpeCA9IG51bGw7Ci0gICAgICAgIE5hbWVzcGFjZUltcGwgYXR0ciA9IG51bGw7Ci0gICAgICAgIGZvcihpbnQgaT0wO2k8IGNvdW50O2krKyl7Ci0gICAgICAgICAgICB1cmkgPSB4bWxyLmdldE5hbWVzcGFjZVVSSShpKTsKLSAgICAgICAgICAgIHByZWZpeCA9IHhtbHIuZ2V0TmFtZXNwYWNlUHJlZml4KGkpOwotICAgICAgICAgICAgaWYocHJlZml4ID09IG51bGwpewotICAgICAgICAgICAgICAgIHByZWZpeCA9IFhNTENvbnN0YW50cy5ERUZBVUxUX05TX1BSRUZJWDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGF0dHIgPSBuZXcgTmFtZXNwYWNlSW1wbChwcmVmaXgsdXJpKTsKLSAgICAgICAgICAgIGV2ZW50LmFkZE5hbWVzcGFjZShhdHRyKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8vUmV2aXNpdCA6IENyZWF0aW5nIGEgbmV3IE5hbWVzcGFjZWNvbnRleHQgZm9yIG5vdy4KLSAgICAvL3NlZSBpZiB3ZSBjYW4gZG8gYmV0dGVyIGpvYi4KLSAgICBwcml2YXRlIHZvaWQgc2V0TmFtZXNwYWNlQ29udGV4dChTdGFydEVsZW1lbnRFdmVudCBldmVudCAsIFhNTFN0cmVhbVJlYWRlciB4bWxyKXsKLSAgICAgICAgTmFtZXNwYWNlQ29udGV4dFdyYXBwZXIgY29udGV4dFdyYXBwZXIgPShOYW1lc3BhY2VDb250ZXh0V3JhcHBlcikgeG1sci5nZXROYW1lc3BhY2VDb250ZXh0KCk7Ci0gICAgICAgIE5hbWVzcGFjZVN1cHBvcnQgbnMgPSBuZXcgTmFtZXNwYWNlU3VwcG9ydChjb250ZXh0V3JhcHBlci5nZXROYW1lc3BhY2VDb250ZXh0KCkpOwotICAgICAgICBldmVudC5zZXROYW1lc3BhY2VDb250ZXh0KG5ldyBOYW1lc3BhY2VDb250ZXh0V3JhcHBlcihucykpOwotICAgIH0KLQotICAgIHByaXZhdGUgUU5hbWUgZ2V0UU5hbWUoWE1MU3RyZWFtUmVhZGVyIHhtbHIpIHsKLSAgICAgICAgcmV0dXJuIG5ldyBRTmFtZSh4bWxyLmdldE5hbWVzcGFjZVVSSSgpLCB4bWxyLmdldExvY2FsTmFtZSgpLAotICAgICAgICAgICAgICAgIHhtbHIuZ2V0UHJlZml4KCkpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL3htbC9pbnRlcm5hbC9zdHJlYW0vZXZlbnRzL1hNTEV2ZW50RmFjdG9yeUltcGwuamF2YSBiL3NyYy9jb20vc3VuL3htbC9pbnRlcm5hbC9zdHJlYW0vZXZlbnRzL1hNTEV2ZW50RmFjdG9yeUltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNjY5NTQ2Yi4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL2V2ZW50cy9YTUxFdmVudEZhY3RvcnlJbXBsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMDEgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLnhtbC5pbnRlcm5hbC5zdHJlYW0uZXZlbnRzOwotCi1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5YTUxFdmVudEZhY3Rvcnk7Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5Mb2NhdGlvbjsKLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLmV2ZW50cy5OYW1lc3BhY2U7Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5ldmVudHMuRW50aXR5RGVjbGFyYXRpb247Ci0KLQotLyoqCi0gKgotICogQGF1dGhvciAgTmVlcmFqIEJhamFqLCBrLnZlbnVnb3BhbEBzdW4uY29tCi0gKi8KLXB1YmxpYyBjbGFzcyBYTUxFdmVudEZhY3RvcnlJbXBsIGV4dGVuZHMgWE1MRXZlbnRGYWN0b3J5IHsKLQotICAgIExvY2F0aW9uIGxvY2F0aW9uID0gbnVsbDsKLSAgICAvKiogQ3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiBYTUxFdmVudEZhY3RvcnkgKi8KLSAgICBwdWJsaWMgWE1MRXZlbnRGYWN0b3J5SW1wbCgpIHsKLSAgICB9Ci0KLSAgICBwdWJsaWMgamF2YXgueG1sLnN0cmVhbS5ldmVudHMuQXR0cmlidXRlIGNyZWF0ZUF0dHJpYnV0ZShTdHJpbmcgbG9jYWxOYW1lLCBTdHJpbmcgdmFsdWUpIHsKLSAgICAgICAgQXR0cmlidXRlSW1wbCBhdHRyID0gIG5ldyBBdHRyaWJ1dGVJbXBsKGxvY2FsTmFtZSwgdmFsdWUpOwotICAgICAgICBpZihsb2NhdGlvbiAhPSBudWxsKWF0dHIuc2V0TG9jYXRpb24obG9jYXRpb24pOwotICAgICAgICByZXR1cm4gYXR0cjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgamF2YXgueG1sLnN0cmVhbS5ldmVudHMuQXR0cmlidXRlIGNyZWF0ZUF0dHJpYnV0ZShqYXZheC54bWwubmFtZXNwYWNlLlFOYW1lIG5hbWUsIFN0cmluZyB2YWx1ZSkgewotICAgICAgICByZXR1cm4gY3JlYXRlQXR0cmlidXRlKG5hbWUuZ2V0UHJlZml4KCksIG5hbWUuZ2V0TmFtZXNwYWNlVVJJKCksIG5hbWUuZ2V0TG9jYWxQYXJ0KCksIHZhbHVlKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgamF2YXgueG1sLnN0cmVhbS5ldmVudHMuQXR0cmlidXRlIGNyZWF0ZUF0dHJpYnV0ZShTdHJpbmcgcHJlZml4LCBTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgbG9jYWxOYW1lLCBTdHJpbmcgdmFsdWUpIHsKLSAgICAgICAgQXR0cmlidXRlSW1wbCBhdHRyID0gIG5ldyBBdHRyaWJ1dGVJbXBsKHByZWZpeCwgbmFtZXNwYWNlVVJJLCBsb2NhbE5hbWUsIHZhbHVlLCBudWxsKTsKLSAgICAgICAgaWYobG9jYXRpb24gIT0gbnVsbClhdHRyLnNldExvY2F0aW9uKGxvY2F0aW9uKTsKLSAgICAgICAgcmV0dXJuIGF0dHI7Ci0gICAgfQotCi0gICAgcHVibGljIGphdmF4LnhtbC5zdHJlYW0uZXZlbnRzLkNoYXJhY3RlcnMgY3JlYXRlQ0RhdGEoU3RyaW5nIGNvbnRlbnQpIHsKLSAgICAgICAgLy9zdGF4IGRvZXNuJ3QgaGF2ZSBzZXBhcmF0ZSBDREFUQSBldmVudC4gVGhpcyBpcyB0YWtlbiBjYXJlIGJ5Ci0gICAgICAgIC8vQ0hSQUNURVJTIGV2ZW50IHNldHRpbmcgdGhlIGNkYXRhIGZsYWcgdG8gdHJ1ZS4KLSAgICAgICAgQ2hhcmFjdGVyRXZlbnQgY2hhckV2ZW50ID0gIG5ldyBDaGFyYWN0ZXJFdmVudChjb250ZW50LCB0cnVlKTsKLSAgICAgICAgaWYobG9jYXRpb24gIT0gbnVsbCljaGFyRXZlbnQuc2V0TG9jYXRpb24obG9jYXRpb24pOwotICAgICAgICByZXR1cm4gY2hhckV2ZW50OwotICAgIH0KLQotICAgIHB1YmxpYyBqYXZheC54bWwuc3RyZWFtLmV2ZW50cy5DaGFyYWN0ZXJzIGNyZWF0ZUNoYXJhY3RlcnMoU3RyaW5nIGNvbnRlbnQpIHsKLSAgICAgICAgQ2hhcmFjdGVyRXZlbnQgY2hhckV2ZW50ID0gIG5ldyBDaGFyYWN0ZXJFdmVudChjb250ZW50KTsKLSAgICAgICAgaWYobG9jYXRpb24gIT0gbnVsbCljaGFyRXZlbnQuc2V0TG9jYXRpb24obG9jYXRpb24pOwotICAgICAgICByZXR1cm4gY2hhckV2ZW50OwotICAgIH0KLQotICAgIHB1YmxpYyBqYXZheC54bWwuc3RyZWFtLmV2ZW50cy5Db21tZW50IGNyZWF0ZUNvbW1lbnQoU3RyaW5nIHRleHQpIHsKLSAgICAgICAgQ29tbWVudEV2ZW50IGNoYXJFdmVudCA9ICBuZXcgQ29tbWVudEV2ZW50KHRleHQpOwotICAgICAgICBpZihsb2NhdGlvbiAhPSBudWxsKWNoYXJFdmVudC5zZXRMb2NhdGlvbihsb2NhdGlvbik7Ci0gICAgICAgIHJldHVybiBjaGFyRXZlbnQ7Ci0gICAgfQotCi0gICAgcHVibGljIGphdmF4LnhtbC5zdHJlYW0uZXZlbnRzLkRURCBjcmVhdGVEVEQoU3RyaW5nIGR0ZCkgewotICAgICAgICBEVERFdmVudCBkdGRFdmVudCA9IG5ldyBEVERFdmVudChkdGQpOwotICAgICAgICBpZihsb2NhdGlvbiAhPSBudWxsKWR0ZEV2ZW50LnNldExvY2F0aW9uKGxvY2F0aW9uKTsKLSAgICAgICAgcmV0dXJuIGR0ZEV2ZW50OwotICAgIH0KLQotICAgIHB1YmxpYyBqYXZheC54bWwuc3RyZWFtLmV2ZW50cy5FbmREb2N1bWVudCBjcmVhdGVFbmREb2N1bWVudCgpIHsKLSAgICAgICAgRW5kRG9jdW1lbnRFdmVudCBldmVudCA9bmV3IEVuZERvY3VtZW50RXZlbnQoKTsKLSAgICAgICAgaWYobG9jYXRpb24gIT0gbnVsbClldmVudC5zZXRMb2NhdGlvbihsb2NhdGlvbik7Ci0gICAgICAgIHJldHVybiBldmVudDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgamF2YXgueG1sLnN0cmVhbS5ldmVudHMuRW5kRWxlbWVudCBjcmVhdGVFbmRFbGVtZW50KGphdmF4LnhtbC5uYW1lc3BhY2UuUU5hbWUgbmFtZSwgamF2YS51dGlsLkl0ZXJhdG9yIG5hbWVzcGFjZXMpIHsKLSAgICAgICAgcmV0dXJuIGNyZWF0ZUVuZEVsZW1lbnQobmFtZS5nZXRQcmVmaXgoKSwgbmFtZS5nZXROYW1lc3BhY2VVUkkoKSwgbmFtZS5nZXRMb2NhbFBhcnQoKSk7Ci0gICAgfQotCi0gICAgcHVibGljIGphdmF4LnhtbC5zdHJlYW0uZXZlbnRzLkVuZEVsZW1lbnQgY3JlYXRlRW5kRWxlbWVudChTdHJpbmcgcHJlZml4LCBTdHJpbmcgbmFtZXNwYWNlVXJpLCBTdHJpbmcgbG9jYWxOYW1lKSB7Ci0gICAgICAgIEVuZEVsZW1lbnRFdmVudCBldmVudCA9ICBuZXcgRW5kRWxlbWVudEV2ZW50KHByZWZpeCwgbmFtZXNwYWNlVXJpLCBsb2NhbE5hbWUpOwotICAgICAgICBpZihsb2NhdGlvbiAhPSBudWxsKWV2ZW50LnNldExvY2F0aW9uKGxvY2F0aW9uKTsKLSAgICAgICAgcmV0dXJuIGV2ZW50OwotICAgIH0KLQotICAgIHB1YmxpYyBqYXZheC54bWwuc3RyZWFtLmV2ZW50cy5FbmRFbGVtZW50IGNyZWF0ZUVuZEVsZW1lbnQoU3RyaW5nIHByZWZpeCwgU3RyaW5nIG5hbWVzcGFjZVVyaSwgU3RyaW5nIGxvY2FsTmFtZSwgamF2YS51dGlsLkl0ZXJhdG9yIG5hbWVzcGFjZXMpIHsKLQotICAgICAgICBFbmRFbGVtZW50RXZlbnQgZXZlbnQgPSAgbmV3IEVuZEVsZW1lbnRFdmVudChwcmVmaXgsIG5hbWVzcGFjZVVyaSwgbG9jYWxOYW1lKTsKLSAgICAgICAgaWYobmFtZXNwYWNlcyE9bnVsbCl7Ci0gICAgICAgICAgICB3aGlsZShuYW1lc3BhY2VzLmhhc05leHQoKSkKLSAgICAgICAgICAgICAgICBldmVudC5hZGROYW1lc3BhY2UoKE5hbWVzcGFjZSluYW1lc3BhY2VzLm5leHQoKSk7Ci0gICAgICAgIH0KLSAgICAgICAgaWYobG9jYXRpb24gIT0gbnVsbClldmVudC5zZXRMb2NhdGlvbihsb2NhdGlvbik7Ci0gICAgICAgIHJldHVybiBldmVudDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgamF2YXgueG1sLnN0cmVhbS5ldmVudHMuRW50aXR5UmVmZXJlbmNlIGNyZWF0ZUVudGl0eVJlZmVyZW5jZShTdHJpbmcgbmFtZSwgRW50aXR5RGVjbGFyYXRpb24gZW50aXR5RGVjbGFyYXRpb24pIHsKLSAgICAgICAgRW50aXR5UmVmZXJlbmNlRXZlbnQgZXZlbnQgPSAgbmV3IEVudGl0eVJlZmVyZW5jZUV2ZW50KG5hbWUsIGVudGl0eURlY2xhcmF0aW9uKTsKLSAgICAgICAgaWYobG9jYXRpb24gIT0gbnVsbClldmVudC5zZXRMb2NhdGlvbihsb2NhdGlvbik7Ci0gICAgICAgIHJldHVybiBldmVudDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgamF2YXgueG1sLnN0cmVhbS5ldmVudHMuQ2hhcmFjdGVycyBjcmVhdGVJZ25vcmFibGVTcGFjZShTdHJpbmcgY29udGVudCkgewotICAgICAgICBDaGFyYWN0ZXJFdmVudCBldmVudCA9ICBuZXcgQ2hhcmFjdGVyRXZlbnQoY29udGVudCwgZmFsc2UsIHRydWUpOwotICAgICAgICBpZihsb2NhdGlvbiAhPSBudWxsKWV2ZW50LnNldExvY2F0aW9uKGxvY2F0aW9uKTsKLSAgICAgICAgcmV0dXJuIGV2ZW50OwotICAgIH0KLQotICAgIHB1YmxpYyBqYXZheC54bWwuc3RyZWFtLmV2ZW50cy5OYW1lc3BhY2UgY3JlYXRlTmFtZXNwYWNlKFN0cmluZyBuYW1lc3BhY2VVUkkpIHsKLSAgICAgICAgTmFtZXNwYWNlSW1wbCBldmVudCA9ICBuZXcgTmFtZXNwYWNlSW1wbChuYW1lc3BhY2VVUkkpOwotICAgICAgICBpZihsb2NhdGlvbiAhPSBudWxsKWV2ZW50LnNldExvY2F0aW9uKGxvY2F0aW9uKTsKLSAgICAgICAgcmV0dXJuIGV2ZW50OwotICAgIH0KLQotICAgIHB1YmxpYyBqYXZheC54bWwuc3RyZWFtLmV2ZW50cy5OYW1lc3BhY2UgY3JlYXRlTmFtZXNwYWNlKFN0cmluZyBwcmVmaXgsIFN0cmluZyBuYW1lc3BhY2VVUkkpIHsKLSAgICAgICAgTmFtZXNwYWNlSW1wbCBldmVudCA9ICBuZXcgTmFtZXNwYWNlSW1wbChwcmVmaXgsIG5hbWVzcGFjZVVSSSk7Ci0gICAgICAgIGlmKGxvY2F0aW9uICE9IG51bGwpZXZlbnQuc2V0TG9jYXRpb24obG9jYXRpb24pOwotICAgICAgICByZXR1cm4gZXZlbnQ7Ci0gICAgfQotCi0gICAgcHVibGljIGphdmF4LnhtbC5zdHJlYW0uZXZlbnRzLlByb2Nlc3NpbmdJbnN0cnVjdGlvbiBjcmVhdGVQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oU3RyaW5nIHRhcmdldCwgU3RyaW5nIGRhdGEpIHsKLSAgICAgICAgUHJvY2Vzc2luZ0luc3RydWN0aW9uRXZlbnQgZXZlbnQgPSAgbmV3IFByb2Nlc3NpbmdJbnN0cnVjdGlvbkV2ZW50KHRhcmdldCwgZGF0YSk7Ci0gICAgICAgIGlmKGxvY2F0aW9uICE9IG51bGwpZXZlbnQuc2V0TG9jYXRpb24obG9jYXRpb24pOwotICAgICAgICByZXR1cm4gZXZlbnQ7Ci0gICAgfQotCi0gICAgcHVibGljIGphdmF4LnhtbC5zdHJlYW0uZXZlbnRzLkNoYXJhY3RlcnMgY3JlYXRlU3BhY2UoU3RyaW5nIGNvbnRlbnQpIHsKLSAgICAgICAgQ2hhcmFjdGVyRXZlbnQgZXZlbnQgPSAgbmV3IENoYXJhY3RlckV2ZW50KGNvbnRlbnQpOwotICAgICAgICBpZihsb2NhdGlvbiAhPSBudWxsKWV2ZW50LnNldExvY2F0aW9uKGxvY2F0aW9uKTsKLSAgICAgICAgcmV0dXJuIGV2ZW50OwotICAgIH0KLQotICAgIHB1YmxpYyBqYXZheC54bWwuc3RyZWFtLmV2ZW50cy5TdGFydERvY3VtZW50IGNyZWF0ZVN0YXJ0RG9jdW1lbnQoKSB7Ci0gICAgICAgIFN0YXJ0RG9jdW1lbnRFdmVudCBldmVudCA9IG5ldyBTdGFydERvY3VtZW50RXZlbnQoKTsKLSAgICAgICAgaWYobG9jYXRpb24gIT0gbnVsbClldmVudC5zZXRMb2NhdGlvbihsb2NhdGlvbik7Ci0gICAgICAgIHJldHVybiBldmVudDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgamF2YXgueG1sLnN0cmVhbS5ldmVudHMuU3RhcnREb2N1bWVudCBjcmVhdGVTdGFydERvY3VtZW50KFN0cmluZyBlbmNvZGluZykgewotICAgICAgICBTdGFydERvY3VtZW50RXZlbnQgZXZlbnQgPSAgbmV3IFN0YXJ0RG9jdW1lbnRFdmVudChlbmNvZGluZyk7Ci0gICAgICAgIGlmKGxvY2F0aW9uICE9IG51bGwpZXZlbnQuc2V0TG9jYXRpb24obG9jYXRpb24pOwotICAgICAgICByZXR1cm4gZXZlbnQ7Ci0gICAgfQotCi0gICAgcHVibGljIGphdmF4LnhtbC5zdHJlYW0uZXZlbnRzLlN0YXJ0RG9jdW1lbnQgY3JlYXRlU3RhcnREb2N1bWVudChTdHJpbmcgZW5jb2RpbmcsIFN0cmluZyB2ZXJzaW9uKSB7Ci0gICAgICAgIFN0YXJ0RG9jdW1lbnRFdmVudCBldmVudCA9ICBuZXcgU3RhcnREb2N1bWVudEV2ZW50KGVuY29kaW5nLCB2ZXJzaW9uKTsKLSAgICAgICAgaWYobG9jYXRpb24gIT0gbnVsbClldmVudC5zZXRMb2NhdGlvbihsb2NhdGlvbik7Ci0gICAgICAgIHJldHVybiBldmVudDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgamF2YXgueG1sLnN0cmVhbS5ldmVudHMuU3RhcnREb2N1bWVudCBjcmVhdGVTdGFydERvY3VtZW50KFN0cmluZyBlbmNvZGluZywgU3RyaW5nIHZlcnNpb24sIGJvb2xlYW4gc3RhbmRhbG9uZSkgewotICAgICAgICBTdGFydERvY3VtZW50RXZlbnQgZXZlbnQgPSAgbmV3IFN0YXJ0RG9jdW1lbnRFdmVudChlbmNvZGluZywgdmVyc2lvbiwgc3RhbmRhbG9uZSk7Ci0gICAgICAgIGlmKGxvY2F0aW9uICE9IG51bGwpZXZlbnQuc2V0TG9jYXRpb24obG9jYXRpb24pOwotICAgICAgICByZXR1cm4gZXZlbnQ7Ci0gICAgfQotCi0gICAgcHVibGljIGphdmF4LnhtbC5zdHJlYW0uZXZlbnRzLlN0YXJ0RWxlbWVudCBjcmVhdGVTdGFydEVsZW1lbnQoamF2YXgueG1sLm5hbWVzcGFjZS5RTmFtZSBuYW1lLCBqYXZhLnV0aWwuSXRlcmF0b3IgYXR0cmlidXRlcywgamF2YS51dGlsLkl0ZXJhdG9yIG5hbWVzcGFjZXMpIHsKLSAgICAgICAgcmV0dXJuIGNyZWF0ZVN0YXJ0RWxlbWVudChuYW1lLmdldFByZWZpeCgpLCBuYW1lLmdldE5hbWVzcGFjZVVSSSgpLCBuYW1lLmdldExvY2FsUGFydCgpLCBhdHRyaWJ1dGVzLCBuYW1lc3BhY2VzKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgamF2YXgueG1sLnN0cmVhbS5ldmVudHMuU3RhcnRFbGVtZW50IGNyZWF0ZVN0YXJ0RWxlbWVudChTdHJpbmcgcHJlZml4LCBTdHJpbmcgbmFtZXNwYWNlVXJpLCBTdHJpbmcgbG9jYWxOYW1lKSB7Ci0gICAgICAgIFN0YXJ0RWxlbWVudEV2ZW50IGV2ZW50ID0gIG5ldyBTdGFydEVsZW1lbnRFdmVudChwcmVmaXgsIG5hbWVzcGFjZVVyaSwgbG9jYWxOYW1lKTsKLSAgICAgICAgaWYobG9jYXRpb24gIT0gbnVsbClldmVudC5zZXRMb2NhdGlvbihsb2NhdGlvbik7Ci0gICAgICAgIHJldHVybiBldmVudDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgamF2YXgueG1sLnN0cmVhbS5ldmVudHMuU3RhcnRFbGVtZW50IGNyZWF0ZVN0YXJ0RWxlbWVudChTdHJpbmcgcHJlZml4LCBTdHJpbmcgbmFtZXNwYWNlVXJpLCBTdHJpbmcgbG9jYWxOYW1lLCBqYXZhLnV0aWwuSXRlcmF0b3IgYXR0cmlidXRlcywgamF2YS51dGlsLkl0ZXJhdG9yIG5hbWVzcGFjZXMpIHsKLSAgICAgICAgcmV0dXJuIGNyZWF0ZVN0YXJ0RWxlbWVudChwcmVmaXgsIG5hbWVzcGFjZVVyaSwgbG9jYWxOYW1lLCBhdHRyaWJ1dGVzLCBuYW1lc3BhY2VzLCBudWxsKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgamF2YXgueG1sLnN0cmVhbS5ldmVudHMuU3RhcnRFbGVtZW50IGNyZWF0ZVN0YXJ0RWxlbWVudChTdHJpbmcgcHJlZml4LCBTdHJpbmcgbmFtZXNwYWNlVXJpLCBTdHJpbmcgbG9jYWxOYW1lLCBqYXZhLnV0aWwuSXRlcmF0b3IgYXR0cmlidXRlcywgamF2YS51dGlsLkl0ZXJhdG9yIG5hbWVzcGFjZXMsIGphdmF4LnhtbC5uYW1lc3BhY2UuTmFtZXNwYWNlQ29udGV4dCBjb250ZXh0KSB7Ci0gICAgICAgIFN0YXJ0RWxlbWVudEV2ZW50IGVsZW0gPSAgbmV3IFN0YXJ0RWxlbWVudEV2ZW50KHByZWZpeCwgbmFtZXNwYWNlVXJpLCBsb2NhbE5hbWUpOwotICAgICAgICBlbGVtLmFkZEF0dHJpYnV0ZXMoYXR0cmlidXRlcyk7Ci0gICAgICAgIGVsZW0uYWRkTmFtZXNwYWNlQXR0cmlidXRlcyhuYW1lc3BhY2VzKTsKLSAgICAgICAgZWxlbS5zZXROYW1lc3BhY2VDb250ZXh0KGNvbnRleHQpOwotICAgICAgICBpZihsb2NhdGlvbiAhPSBudWxsKWVsZW0uc2V0TG9jYXRpb24obG9jYXRpb24pOwotICAgICAgICByZXR1cm4gZWxlbTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRMb2NhdGlvbihqYXZheC54bWwuc3RyZWFtLkxvY2F0aW9uIGxvY2F0aW9uKSB7Ci0gICAgICAgIHRoaXMubG9jYXRpb24gPSBsb2NhdGlvbjsKLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL3htbC9pbnRlcm5hbC9zdHJlYW0vamF2YXgueG1sLnN0cmVhbS5YTUxFdmVudEZhY3RvcnkgYi9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL2phdmF4LnhtbC5zdHJlYW0uWE1MRXZlbnRGYWN0b3J5CmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhZGMyNmIzLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL3htbC9pbnRlcm5hbC9zdHJlYW0vamF2YXgueG1sLnN0cmVhbS5YTUxFdmVudEZhY3RvcnkKKysrIC9kZXYvbnVsbApAQCAtMSArMCwwIEBACi1jb20uc3VuLnhtbC5pbnRlcm5hbC5zdHJlYW0uZXZlbnRzLlhNTEV2ZW50RmFjdG9yeUltcGwKZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL3htbC9pbnRlcm5hbC9zdHJlYW0vamF2YXgueG1sLnN0cmVhbS5YTUxJbnB1dEZhY3RvcnkgYi9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL2phdmF4LnhtbC5zdHJlYW0uWE1MSW5wdXRGYWN0b3J5CmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0NTY4ODJjLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL3htbC9pbnRlcm5hbC9zdHJlYW0vamF2YXgueG1sLnN0cmVhbS5YTUxJbnB1dEZhY3RvcnkKKysrIC9kZXYvbnVsbApAQCAtMSArMCwwIEBACi1jb20uc3VuLnhtbC5pbnRlcm5hbC5zdHJlYW0uWE1MSW5wdXRGYWN0b3J5SW1wbApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4veG1sL2ludGVybmFsL3N0cmVhbS9qYXZheC54bWwuc3RyZWFtLlhNTE91dHB1dEZhY3RvcnkgYi9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL2phdmF4LnhtbC5zdHJlYW0uWE1MT3V0cHV0RmFjdG9yeQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggM2RlNTE5MC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL2phdmF4LnhtbC5zdHJlYW0uWE1MT3V0cHV0RmFjdG9yeQorKysgL2Rldi9udWxsCkBAIC0xICswLDAgQEAKLWNvbS5zdW4ueG1sLmludGVybmFsLnN0cmVhbS5YTUxPdXRwdXRGYWN0b3J5SW1wbApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4veG1sL2ludGVybmFsL3N0cmVhbS91dGlsL0J1ZmZlckFsbG9jYXRvci5qYXZhIGIvc3JjL2NvbS9zdW4veG1sL2ludGVybmFsL3N0cmVhbS91dGlsL0J1ZmZlckFsbG9jYXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxMzYyNjkyLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL3htbC9pbnRlcm5hbC9zdHJlYW0vdXRpbC9CdWZmZXJBbGxvY2F0b3IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEyMSArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDA1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ueG1sLmludGVybmFsLnN0cmVhbS51dGlsOwotCi1pbXBvcnQgamF2YS5sYW5nLnJlZi4qOwotCi0vKioKLSAqIEJ1ZmZlciBhbGxvY2F0b3IgZm9yIGJ1ZmZlcnMgb2Ygc2l6ZXMgMTI4IEIsIDIgS0IgYW5kIDggS0IuIEluY2x1ZGVzCi0gKiBtZXRob2RzIGZvciBhbGxvY2F0aW5nIGFuZCBmcmVlaW5nIGJ1ZmZlcnMuCi0gKgotICogQGF1dGhvciBCaW51LkpvaG5Ac3VuLmNvbQotICogQGF1dGhvciBTYW50aWFnby5QZXJpY2FzR2VlcnRzZW5Ac3VuLmNvbQotICovCi1wdWJsaWMgY2xhc3MgQnVmZmVyQWxsb2NhdG9yIHsKLSAgICBwdWJsaWMgc3RhdGljIGludCBTTUFMTF9TSVpFX0xJTUlUID0gMTI4OwotICAgIHB1YmxpYyBzdGF0aWMgaW50IE1FRElVTV9TSVpFX0xJTUlUID0gMjA0ODsKLSAgICBwdWJsaWMgc3RhdGljIGludCBMQVJHRV9TSVpFX0xJTUlUID0gODE5MjsKLQotICAgIGNoYXJbXSBzbWFsbENoYXJCdWZmZXI7Ci0gICAgY2hhcltdIG1lZGl1bUNoYXJCdWZmZXI7Ci0gICAgY2hhcltdIGxhcmdlQ2hhckJ1ZmZlcjsKLQotICAgIGJ5dGVbXSBzbWFsbEJ5dGVCdWZmZXI7Ci0gICAgYnl0ZVtdIG1lZGl1bUJ5dGVCdWZmZXI7Ci0gICAgYnl0ZVtdIGxhcmdlQnl0ZUJ1ZmZlcjsKLQotICAgIHB1YmxpYyBCdWZmZXJBbGxvY2F0b3IoKSB7Ci0gICAgfQotCi0gICAgcHVibGljIGNoYXJbXSBnZXRDaGFyQnVmZmVyKGludCBzaXplKSB7Ci0gICAgICAgIGlmIChzaXplIDw9IFNNQUxMX1NJWkVfTElNSVQpIHsKLSAgICAgICAgICAgIGNoYXJbXSBidWZmZXIgPSBzbWFsbENoYXJCdWZmZXI7Ci0gICAgICAgICAgICBzbWFsbENoYXJCdWZmZXIgPSBudWxsOwotICAgICAgICAgICAgcmV0dXJuIGJ1ZmZlcjsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChzaXplIDw9IE1FRElVTV9TSVpFX0xJTUlUKSB7Ci0gICAgICAgICAgICBjaGFyW10gYnVmZmVyID0gbWVkaXVtQ2hhckJ1ZmZlcjsKLSAgICAgICAgICAgIG1lZGl1bUNoYXJCdWZmZXIgPSBudWxsOwotICAgICAgICAgICAgcmV0dXJuIGJ1ZmZlcjsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChzaXplIDw9IExBUkdFX1NJWkVfTElNSVQpIHsKLSAgICAgICAgICAgIGNoYXJbXSBidWZmZXIgPSBsYXJnZUNoYXJCdWZmZXI7Ci0gICAgICAgICAgICBsYXJnZUNoYXJCdWZmZXIgPSBudWxsOwotICAgICAgICAgICAgcmV0dXJuIGJ1ZmZlcjsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCByZXR1cm5DaGFyQnVmZmVyKGNoYXJbXSBjKSB7Ci0gICAgICAgIGlmIChjID09IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotICAgICAgICBpZiAoYy5sZW5ndGggPD0gU01BTExfU0laRV9MSU1JVCkgewotICAgICAgICAgICAgc21hbGxDaGFyQnVmZmVyID0gYzsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChjLmxlbmd0aCA8PSBNRURJVU1fU0laRV9MSU1JVCkgewotICAgICAgICAgICAgbWVkaXVtQ2hhckJ1ZmZlciA9IGM7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoYy5sZW5ndGggPD0gTEFSR0VfU0laRV9MSU1JVCkgewotICAgICAgICAgICAgbGFyZ2VDaGFyQnVmZmVyID0gYzsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyBieXRlW10gZ2V0Qnl0ZUJ1ZmZlcihpbnQgc2l6ZSkgewotICAgICAgICBpZiAoc2l6ZSA8PSBTTUFMTF9TSVpFX0xJTUlUKSB7Ci0gICAgICAgICAgICBieXRlW10gYnVmZmVyID0gc21hbGxCeXRlQnVmZmVyOwotICAgICAgICAgICAgc21hbGxCeXRlQnVmZmVyID0gbnVsbDsKLSAgICAgICAgICAgIHJldHVybiBidWZmZXI7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoc2l6ZSA8PSBNRURJVU1fU0laRV9MSU1JVCkgewotICAgICAgICAgICAgYnl0ZVtdIGJ1ZmZlciA9IG1lZGl1bUJ5dGVCdWZmZXI7Ci0gICAgICAgICAgICBtZWRpdW1CeXRlQnVmZmVyID0gbnVsbDsKLSAgICAgICAgICAgIHJldHVybiBidWZmZXI7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoc2l6ZSA8PSBMQVJHRV9TSVpFX0xJTUlUKSB7Ci0gICAgICAgICAgICBieXRlW10gYnVmZmVyID0gbGFyZ2VCeXRlQnVmZmVyOwotICAgICAgICAgICAgbGFyZ2VCeXRlQnVmZmVyID0gbnVsbDsKLSAgICAgICAgICAgIHJldHVybiBidWZmZXI7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgcmV0dXJuQnl0ZUJ1ZmZlcihieXRlW10gYikgewotICAgICAgICBpZiAoYiA9PSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGIubGVuZ3RoIDw9IFNNQUxMX1NJWkVfTElNSVQpIHsKLSAgICAgICAgICAgIHNtYWxsQnl0ZUJ1ZmZlciA9IGI7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoYi5sZW5ndGggPD0gTUVESVVNX1NJWkVfTElNSVQpIHsKLSAgICAgICAgICAgIG1lZGl1bUJ5dGVCdWZmZXIgPSBiOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKGIubGVuZ3RoIDw9IExBUkdFX1NJWkVfTElNSVQpIHsKLSAgICAgICAgICAgIGxhcmdlQnl0ZUJ1ZmZlciA9IGI7Ci0gICAgICAgIH0KLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9jb20vc3VuL3htbC9pbnRlcm5hbC9zdHJlYW0vdXRpbC9SZWFkT25seUl0ZXJhdG9yLmphdmEgYi9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL3V0aWwvUmVhZE9ubHlJdGVyYXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjMWZkM2M3Li4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL3htbC9pbnRlcm5hbC9zdHJlYW0vdXRpbC9SZWFkT25seUl0ZXJhdG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw2NyArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDA1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ueG1sLmludGVybmFsLnN0cmVhbS51dGlsOwotLyoqCi0gKgotICogQGF1dGhvciBLLlZlbnVnb3BhbCAsTmVlcmFqIEJhamFqIFN1biBNaWNyb3N5c3RlbXMuCi0gKi8KLQotaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKLQotcHVibGljIGNsYXNzIFJlYWRPbmx5SXRlcmF0b3IgaW1wbGVtZW50cyBJdGVyYXRvciB7Ci0KLSAgICBJdGVyYXRvciBpdGVyYXRvciA9IG51bGw7Ci0KLSAgICBwdWJsaWMgUmVhZE9ubHlJdGVyYXRvcigpewotICAgIH0KLQotICAgIHB1YmxpYyBSZWFkT25seUl0ZXJhdG9yKEl0ZXJhdG9yIGl0cil7Ci0gICAgICAgIGl0ZXJhdG9yID0gaXRyOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEByZXR1cm4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBoYXNOZXh0KCkgewotICAgICAgICBpZihpdGVyYXRvciAgIT0gbnVsbCkKLSAgICAgICAgICAgIHJldHVybiBpdGVyYXRvci5oYXNOZXh0KCk7Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAcmV0dXJuCi0gICAgICovCi0gICAgcHVibGljIE9iamVjdCBuZXh0KCkgewotICAgICAgICBpZihpdGVyYXRvciAgIT0gbnVsbCkKLSAgICAgICAgICAgIHJldHVybiBpdGVyYXRvci5uZXh0KCk7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHJlbW92ZSgpIHsKLSAgICAgICAgdGhyb3cgbmV3ICBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiUmVtb3ZlIG9wZXJhdGlvbiBpcyBub3Qgc3VwcG9ydGVkIik7Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL3V0aWwvVGhyZWFkTG9jYWxCdWZmZXJBbGxvY2F0b3IuamF2YSBiL3NyYy9jb20vc3VuL3htbC9pbnRlcm5hbC9zdHJlYW0vdXRpbC9UaHJlYWRMb2NhbEJ1ZmZlckFsbG9jYXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyNWJkZjZiLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL3htbC9pbnRlcm5hbC9zdHJlYW0vdXRpbC9UaHJlYWRMb2NhbEJ1ZmZlckFsbG9jYXRvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTMgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLnhtbC5pbnRlcm5hbC5zdHJlYW0udXRpbDsKLQotaW1wb3J0IGphdmEubGFuZy5yZWYuKjsKLQotLyoqCi0gKiBUaGlzIGlzIGEgU2luZ2xldG9uIGNsYXNzIHRoYXQgYWxsb3dzIHlvdSB0byBhbGxvY2F0ZSBidWZmZXIgdGhhdAotICogYXJlIHN0b3JlZCBpbiBUaHJlYWRMb2NhbC4gVGhpcyBjbGFzcyBzdG9yZXMgMyB0eXBlcyBvZiBjaGFyCi0gKiBidWZmZXJzIC0gc21hbGwgKDwgMTI4IGJ5dGVzKSwgbWVkaXVtICg8MkspIGFuZCBsYXJnZSAoPiAySykgYXMKLSAqIHdlbGwgYXMgdGhyZWUgYnl0ZSBidWZmZXJzIC0gc21hbGwsIG1lZGl1bSBhbmQgbGFyZ2UuCi0gKiBUaGUgbG9jYWwgc3RvcmFnZSBpcyBhY3RpdmF0ZWQgb24gdGhlIHJldHVybiBvZiB0aGUgYnVmZmVyLgotICogVGhlIGJ1ZmZlciByZXR1cm5zIG51bGwgaWYgaXQgaXMgYWxyZWFkeSBhbGxvY2F0ZWQuCi0gKgotICogQGF1dGhvciBCaW51LkpvaG5Ac3VuLmNvbQotICogQGF1dGhvciBTYW50aWFnby5QZXJpY2FzR2VlcnRzZW5Ac3VuLmNvbQotICovCi1wdWJsaWMgY2xhc3MgVGhyZWFkTG9jYWxCdWZmZXJBbGxvY2F0b3IgewotICAgcHJpdmF0ZSBzdGF0aWMgVGhyZWFkTG9jYWwgdGxiYSA9IG5ldyBUaHJlYWRMb2NhbCgpOwotCi0gICBwdWJsaWMgc3RhdGljIEJ1ZmZlckFsbG9jYXRvciBnZXRCdWZmZXJBbGxvY2F0b3IoKSB7Ci0gICAgICAgIFNvZnRSZWZlcmVuY2UgYkFsbG9jYXRvclJlZiA9IChTb2Z0UmVmZXJlbmNlKSB0bGJhLmdldCgpOwotICAgICAgICBpZiAoYkFsbG9jYXRvclJlZiA9PSBudWxsIHx8IGJBbGxvY2F0b3JSZWYuZ2V0KCkgPT0gbnVsbCkgewotICAgICAgICAgICAgYkFsbG9jYXRvclJlZiA9IG5ldyBTb2Z0UmVmZXJlbmNlKG5ldyBCdWZmZXJBbGxvY2F0b3IoKSk7Ci0gICAgICAgICAgICB0bGJhLnNldChiQWxsb2NhdG9yUmVmKTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiAoQnVmZmVyQWxsb2NhdG9yKSBiQWxsb2NhdG9yUmVmLmdldCgpOwotICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4veG1sL2ludGVybmFsL3N0cmVhbS93cml0ZXJzL1VURjhPdXRwdXRTdHJlYW1Xcml0ZXIuamF2YSBiL3NyYy9jb20vc3VuL3htbC9pbnRlcm5hbC9zdHJlYW0vd3JpdGVycy9VVEY4T3V0cHV0U3RyZWFtV3JpdGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDU1MmUwMzAuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4veG1sL2ludGVybmFsL3N0cmVhbS93cml0ZXJzL1VURjhPdXRwdXRTdHJlYW1Xcml0ZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE0OSArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDA2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ueG1sLmludGVybmFsLnN0cmVhbS53cml0ZXJzOwotCi1pbXBvcnQgamF2YS5pby5Xcml0ZXI7Ci1pbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLQotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5YTUxDaGFyOwotCi0vKioKLSAqIDxwPlRoaXMgY2xhc3MgaXMgdXNlZCB0byB3cml0ZSBhIHN0cmVhbSBvZiBjaGFycyBhcyBhIHN0cmVhbSBvZgotICogYnl0ZXMgdXNpbmcgdGhlIFVURjggZW5jb2RpbmcuIEl0IGFzc3VtZXMgdGhhdCB0aGUgdW5kZXJseWluZwotICogb3V0cHV0IHN0cmVhbSBpcyBidWZmZXJlZCBvciBkb2VzIG5vdCBuZWVkIGFkZGl0aW9uYWwgYnVmZmVyaW5nLjwvcD4KLSAqCi0gKiA8cD5JdCBpcyBtb3JlIGVmZmljaWVudCB0aGFuIHVzaW5nIGEgPGNvZGU+amF2YS5pby5PdXRwdXRTdHJlYW1Xcml0ZXI8L2NvZGU+Ci0gKiBiZWNhdXNlIGl0IGRvZXMgbm90IG5lZWQgdG8gYmUgd3JhcHBlZCBpbiBhCi0gKiA8Y29kZT5qYXZhLmlvLkJ1ZmZlcmVkV3JpdGVyPC9jb2RlPi4gQ3JlYXRpbmcgbXVsdGlwbGUgaW5zdGFuY2VzCi0gKiBvZiA8Y29kZT5qYXZhLmlvLkJ1ZmZlcmVkV3JpdGVyPC9jb2RlPiBoYXMgYmVlbiBzaG93biB0byBiZSB2ZXJ5Ci0gKiBleHBlbnNpdmUgaW4gSkFYLVdTLjwvcD4KLSAqCi0gKiBAYXV0aG9yIFNhbnRpYWdvLlBlcmljYXNHZWVydHNlbkBzdW4uY29tCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBVVEY4T3V0cHV0U3RyZWFtV3JpdGVyIGV4dGVuZHMgV3JpdGVyIHsKLQotICAgIC8qKgotICAgICAqIFVuZGVseWluZyBvdXRwdXQgc3RyZWFtLiBUaGlzIGNsYXNzIGFzc3VtZXMgdGhhdCB0aGlzCi0gICAgICogb3V0cHV0IHN0cmVhbSBkb2VzIG5vdCBuZWVkIGJ1ZmZlcmluZy4KLSAgICAgKi8KLSAgICBPdXRwdXRTdHJlYW0gb3V0OwotCi0gICAgLyoqCi0gICAgICogSmF2YSByZXByZXNlbnRzIGNoYXJzIHRoYXQgYXJlIG5vdCBpbiB0aGUgQmFzaWMgTXVsdGlsaW5ndWFsCi0gICAgICogUGxhbmUgKEJNUCkgaW4gVVRGLTE2LiBUaGlzIGludCBzdG9yZXMgdGhlIGZpcnN0IGNvZGUgdW5pdAotICAgICAqIGZvciBhIGNvZGUgcG9pbnQgZW5jb2RlZCBpbiB0d28gVVRGLTE2IGNvZGUgdW5pdHMuCi0gICAgICovCi0gICAgaW50IGxhc3RVVEYxNkNvZGVQb2ludCA9IDA7Ci0KLSAgICBwdWJsaWMgVVRGOE91dHB1dFN0cmVhbVdyaXRlcihPdXRwdXRTdHJlYW0gb3V0KSB7Ci0gICAgICAgIHRoaXMub3V0ID0gb3V0OwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0RW5jb2RpbmcoKSB7Ci0gICAgICAgIHJldHVybiAiVVRGLTgiOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHdyaXRlKGludCBjKSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgICAgICAvLyBDaGVjayBpbiB3ZSBhcmUgZW5jb2RpbmcgYXQgaGlnaCBhbmQgbG93IHN1cnJvZ2F0ZXMKLSAgICAgICAgaWYgKGxhc3RVVEYxNkNvZGVQb2ludCAhPSAwKSB7Ci0gICAgICAgICAgICBmaW5hbCBpbnQgdWMgPQotICAgICAgICAgICAgICAgICgoKGxhc3RVVEYxNkNvZGVQb2ludCAmIDB4M2ZmKSA8PCAxMCkgfCAoYyAmIDB4M2ZmKSkgKyAweDEwMDAwOwotCi0gICAgICAgICAgICBpZiAodWMgPCAwIHx8IHVjID49IDB4MjAwMDAwKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJBdHR0ZW1wdGluZyB0byB3cml0ZSBpbnZhbGlkIFVuaWNvZGUgY29kZSBwb2ludCAnIiArIHVjICsgIiciKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgb3V0LndyaXRlKDB4RjAgfCAodWMgPj4gMTgpKTsKLSAgICAgICAgICAgIG91dC53cml0ZSgweDgwIHwgKCh1YyA+PiAxMikgJiAweDNGKSk7Ci0gICAgICAgICAgICBvdXQud3JpdGUoMHg4MCB8ICgodWMgPj4gNikgJiAweDNGKSk7Ci0gICAgICAgICAgICBvdXQud3JpdGUoMHg4MCB8ICh1YyAmIDB4M0YpKTsKLQotICAgICAgICAgICAgbGFzdFVURjE2Q29kZVBvaW50ID0gMDsKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIE90aGVyd2lzZSwgZW5jb2RlIGNoYXIgYXMgZGVmaW5lZCBpbiBVVEYtOAotICAgICAgICBpZiAoYyA8IDB4ODApIHsKLSAgICAgICAgICAgIC8vIDEgYnl0ZSwgNyBiaXRzCi0gICAgICAgICAgICBvdXQud3JpdGUoKGludCkgYyk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoYyA8IDB4ODAwKSB7Ci0gICAgICAgICAgICAvLyAyIGJ5dGVzLCAxMSBiaXRzCi0gICAgICAgICAgICBvdXQud3JpdGUoMHhDMCB8IChjID4+IDYpKTsgICAgLy8gZmlyc3QgNQotICAgICAgICAgICAgb3V0LndyaXRlKDB4ODAgfCAoYyAmIDB4M0YpKTsgIC8vIHNlY29uZCA2Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoYyA8PSAnXHVGRkZGJykgewotICAgICAgICAgICAgaWYgKCFYTUxDaGFyLmlzSGlnaFN1cnJvZ2F0ZShjKSAmJiAhWE1MQ2hhci5pc0xvd1N1cnJvZ2F0ZShjKSkgewotICAgICAgICAgICAgICAgIC8vIDMgYnl0ZXMsIDE2IGJpdHMKLSAgICAgICAgICAgICAgICBvdXQud3JpdGUoMHhFMCB8IChjID4+IDEyKSk7ICAgLy8gZmlyc3QgNAotICAgICAgICAgICAgICAgIG91dC53cml0ZSgweDgwIHwgKChjID4+IDYpICYgMHgzRikpOyAgLy8gc2Vjb25kIDYKLSAgICAgICAgICAgICAgICBvdXQud3JpdGUoMHg4MCB8IChjICYgMHgzRikpOyAgLy8gdGhpcmQgNgotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgbGFzdFVURjE2Q29kZVBvaW50ID0gYzsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHdyaXRlKGNoYXIgY2J1ZltdKSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNidWYubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgIHdyaXRlKGNidWZbaV0pOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgd3JpdGUoY2hhciBjYnVmW10sIGludCBvZmYsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKLSAgICAgICAgICAgIHdyaXRlKGNidWZbb2ZmICsgaV0pOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgd3JpdGUoU3RyaW5nIHN0cikgdGhyb3dzIElPRXhjZXB0aW9uIHsKLSAgICAgICAgZmluYWwgaW50IGxlbiA9IHN0ci5sZW5ndGgoKTsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW47IGkrKykgewotICAgICAgICAgICAgd3JpdGUoc3RyLmNoYXJBdChpKSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCB3cml0ZShTdHJpbmcgc3RyLCBpbnQgb2ZmLCBpbnQgbGVuKSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbjsgaSsrKSB7Ci0gICAgICAgICAgICB3cml0ZShzdHIuY2hhckF0KG9mZiArIGkpKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGZsdXNoKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLSAgICAgICAgb3V0LmZsdXNoKCk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgICAgICBpZiAobGFzdFVURjE2Q29kZVBvaW50ICE9IDApIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oIkF0dGVtcHRpbmcgdG8gY2xvc2UgYSBVVEY4T3V0cHV0U3RyZWFtV3JpdGVyIgotICAgICAgICAgICAgICAgICsgIiB3aGlsZSBhd2FpdGluZyBmb3IgYSBVVEYtMTYgY29kZSB1bml0Iik7Ci0gICAgICAgIH0KLSAgICAgICAgb3V0LmNsb3NlKCk7Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL3dyaXRlcnMvV3JpdGVyVXRpbGl0eS5qYXZhIGIvc3JjL2NvbS9zdW4veG1sL2ludGVybmFsL3N0cmVhbS93cml0ZXJzL1dyaXRlclV0aWxpdHkuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNzAxN2VkNS4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL3dyaXRlcnMvV3JpdGVyVXRpbGl0eS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjU0ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTMsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi54bWwuaW50ZXJuYWwuc3RyZWFtLndyaXRlcnM7Ci0KLWltcG9ydCBqYXZhLmlvLkZpbGVXcml0ZXI7Ci1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbVdyaXRlcjsKLWltcG9ydCBqYXZhLmlvLldyaXRlcjsKLWltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXQ7Ci1pbXBvcnQgamF2YS5uaW8uY2hhcnNldC5DaGFyc2V0RW5jb2RlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuWE1MQ2hhcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWxzLlNlY3VyaXR5U3VwcG9ydDsKLQotLyoqCi0gKiBJbXBsZW1lbnRzIGNvbW1vbiB4bWwgd3JpdGVyIGZ1bmN0aW9ucy4KLSAqCi0gKiBAYXV0aG9yIE5lZXJhaiBCYWphaixLLlZlbnVnb3BhbCBTdW4gTWljcm9zeXN0ZW1zLgotICovCi0KLXB1YmxpYyBjbGFzcyBXcml0ZXJVdGlsaXR5IHsKLQotCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1RBUlRfQ09NTUVOVCA9ICI8IS0tIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFTkRfQ09NTUVOVCA9ICItLT4iOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIERFRkFVTFRfRU5DT0RJTkcgPSAiIGVuY29kaW5nPVwidXRmLThcIiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgREVGQVVMVF9YTUxERUNMID0iPD94bWwgdmVyc2lvbj1cIjEuMFwiID8+IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBERUZBVUxUX1hNTF9WRVJTSU9OID0iMS4wIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNoYXIgQ0xPU0VfU1RBUlRfVEFHID0gJz4nOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2hhciBPUEVOX1NUQVJUX1RBRyA9ICc8JzsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBPUEVOX0VORF9UQUcgPSI8LyI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBjaGFyIENMT1NFX0VORF9UQUcgPSAnPic7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1RBUlRfQ0RBVEEgPSAiPCFbQ0RBVEFbIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFTkRfQ0RBVEEgPSAiXV0+IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBDTE9TRV9FTVBUWV9FTEVNRU5UID0gIi8+IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBTUEFDRSA9ICIgIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBVVEZfOCA9ICJ1dGYtOCI7Ci0KLSAgICBzdGF0aWMgZmluYWwgYm9vbGVhbiBERUJVR19YTUxfQ09OVEVOVCA9IGZhbHNlOwotCi0gICAgLyoqWFhYOiBUaGlzIGZlYXR1cmUgaXMgb25seSB1c2VkIHdoZW4gd3JpdGluZyBlbGVtZW50IGNvbnRlbnQgdmFsdWVzLgotICAgICAqIGRlZmF1bHQgdmFsdWUgaXMgJ3RydWUnIGhvd2V2ZXIsIGlmIHRoZSBmZWF0dXJlIGlzIHNldCB0byBmYWxzZQotICAgICAqIGNoYXJhY3RlcnMgd29udCBiZSBlc2NhcGVkLgotICAgICAqIFRoaXMgZmVhdHVyZSBoYXMgbm8gZWZmZWN0IHdoZW4gd3JpdGluZyBBdHRyaWJ1dGUgdmFsdWVzLCBjaGFyYWN0ZXIgd291bGQgc3RpbGwgYmUgZXNjYXBlZC4KLSAgICAgKiBJIGNhbid0IHRoaW5rIG9mIGFueSByZWFzb24gd2h5IHRoaXMgd291bGQgYmUgdXNlZnVsIHdoZW4gd3JpdGluZyBhdHRyaWJ1dGUgdmFsdWVzLgotICAgICAqIEhvd2V2ZXIsIHRoaXMgY2FuIGJlIHJlY29uc2lkZXJlZCBpZiB0aGVyZSBpcyBhbnkgdXNlY2FzZS4KLSAgICAgKi8KLSAgICBib29sZWFuIGZFc2NhcGVDaGFyYWN0ZXJzID0gdHJ1ZSA7Ci0KLSAgICAvKiogV3JpdGVyIG9iamVjdCovCi0gICAgV3JpdGVyIGZXcml0ZXIgPSBudWxsOwotCi0gICAgLy9DaGFyc2V0RW5jb2RlcgotICAgIENoYXJzZXRFbmNvZGVyIGZFbmNvZGVyIDsKLQotICAgIHB1YmxpYyBXcml0ZXJVdGlsaXR5KCl7Ci0gICAgICAgIGZFbmNvZGVyID0gZ2V0RGVmYXVsdEVuY29kZXIoKTsKLSAgICB9Ci0KLQotICAgIC8qKiBDcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIFdyaXRlclV0aWxpdHkgKi8KLSAgICBwdWJsaWMgV3JpdGVyVXRpbGl0eShXcml0ZXIgd3JpdGVyKSB7Ci0gICAgICAgIGZXcml0ZXIgPSB3cml0ZXI7Ci0gICAgICAgIGlmKHdyaXRlciBpbnN0YW5jZW9mIE91dHB1dFN0cmVhbVdyaXRlcil7Ci0gICAgICAgICAgICBTdHJpbmcgY2hhcnNldCA9ICgoT3V0cHV0U3RyZWFtV3JpdGVyKXdyaXRlcikuZ2V0RW5jb2RpbmcoKTsKLSAgICAgICAgICAgIGlmKGNoYXJzZXQgIT0gbnVsbCl7Ci0gICAgICAgICAgICAgICAgZkVuY29kZXIgPSBDaGFyc2V0LmZvck5hbWUoY2hhcnNldCkubmV3RW5jb2RlcigpOwotICAgICAgICAgICAgfQotICAgICAgICB9ZWxzZSBpZih3cml0ZXIgaW5zdGFuY2VvZiBGaWxlV3JpdGVyKXsKLSAgICAgICAgICAgIFN0cmluZyBjaGFyc2V0ID0gKChGaWxlV3JpdGVyKXdyaXRlcikuZ2V0RW5jb2RpbmcoKTsKLSAgICAgICAgICAgIGlmKGNoYXJzZXQgIT0gbnVsbCl7Ci0gICAgICAgICAgICAgICAgZkVuY29kZXIgPSBDaGFyc2V0LmZvck5hbWUoY2hhcnNldCkubmV3RW5jb2RlcigpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2V7Ci0gICAgICAgICAgICAvL2F0dGVtcHQgdG8gcmV0cmVpdmUgZGVmYXVsdCBmRW5jb2Rlcm9kZXIKLSAgICAgICAgICAgIGZFbmNvZGVyID0gZ2V0RGVmYXVsdEVuY29kZXIoKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIHNldHMgdGhlIHdyaXRlciBvYmplY3QKLSAgICAgKiBAcGFyYW0gd3JpdGVyIGZpbGUgdG8gd3JpdGUgaW50bwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkICBzZXRXcml0ZXIoV3JpdGVyIHdyaXRlcil7Ci0gICAgICAgIGZXcml0ZXIgPSB3cml0ZXI7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0RXNjYXBlQ2hhcmFjdGVycyhib29sZWFuIGVzY2FwZSl7Ci0gICAgICAgIGZFc2NhcGVDaGFyYWN0ZXJzID0gZXNjYXBlIDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXRFc2NhcGVDaGFyYWN0ZXJzKCl7Ci0gICAgICAgIHJldHVybiBmRXNjYXBlQ2hhcmFjdGVyczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiB3cml0ZXMgeG1sIGNvbnRlbnQgKGNoYXJhY3RlcnMgYW5kIGVsZW1lbnQgY29udGVudAotICAgICAqIEBwYXJhbSBjb250ZW50Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgd3JpdGVYTUxDb250ZW50KGNoYXJbXSBjb250ZW50LCBpbnQgc3RhcnQsIGludCBsZW5ndGgpIHRocm93cyBJT0V4Y2VwdGlvbnsKLSAgICAgICAgd3JpdGVYTUxDb250ZW50KGNvbnRlbnQsIHN0YXJ0LCBsZW5ndGgsIGdldEVzY2FwZUNoYXJhY3RlcnMoKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogd3JpdGVzIHhtbCBjb250ZW50IChjaGFyYWN0ZXJzIGFuZCBlbGVtZW50IGNvbnRlbnQKLSAgICAgKiBAcGFyYW0gY29udGVudAotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCB3cml0ZVhNTENvbnRlbnQoY2hhcltdIGNvbnRlbnQsIGludCBzdGFydCwgaW50IGxlbmd0aCwgYm9vbGVhbiBlc2NhcGVDaGFyYWN0ZXIpIHRocm93cyBJT0V4Y2VwdGlvbnsKLSAgICAgICAgaWYoREVCVUdfWE1MX0NPTlRFTlQpewotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJjb250ZW50IHRvIHdyaXRlIGlzICIgKyBuZXcgU3RyaW5nKGNvbnRlbnQsIHN0YXJ0LCBsZW5ndGgpKTsKLSAgICAgICAgfQotICAgICAgICBpbnQgaW5kZXg7Ci0gICAgICAgIGNoYXIgY2g7Ci0gICAgICAgIGludCBzYzsKLSAgICAgICAgZmluYWwgaW50IGVuZCA9IHN0YXJ0ICsgbGVuZ3RoIDsKLSAgICAgICAgLy9kZWZpbmUgc3RhcnRXcml0ZVBvcyB0byB0cmFjayB0aGUgcG9zaXRpb24gZnJvbSB3aGVyZSB0aGUgY2hhcmFjdGVyIGFycmF5IGRhdGEgbmVlZHMgdG8gYmUgd3JpdHRlbgotICAgICAgICAvL2luaXRpYWxpemUgdGhpcyB2YXJpYWJsZSB0byBzdGFydCBwb3MuIGluZGljYXRpbmcgdGhhdCBubyBkYXRhIGhhcyBiZWVuIHdyaXR0ZW4KLSAgICAgICAgaW50IHN0YXJ0V3JpdGVQb3MgPSBzdGFydDsKLQotICAgICAgICBmb3IgKCBpbmRleCA9IHN0YXJ0IDsgaW5kZXggPCBlbmQgOyBpbmRleCsrICkgewotICAgICAgICAgICAgY2ggPSBjb250ZW50WyBpbmRleCBdOwotCi0gICAgICAgICAgICBpZihmRW5jb2RlciAhPSBudWxsICYmICFmRW5jb2Rlci5jYW5FbmNvZGUoY2gpKXsKLSAgICAgICAgICAgICAgICAvLy0gd3JpdGUgdGhlIGRhdGEgdG8gdGhlIHBvaW50IHdlIGdldCB0aGlzIGNoYXJhY3RlcgotICAgICAgICAgICAgICAgIGZXcml0ZXIud3JpdGUoY29udGVudCwgc3RhcnRXcml0ZVBvcywgaW5kZXggLSBzdGFydFdyaXRlUG9zICk7Ci0KLSAgICAgICAgICAgICAgICAvL2VzY2FwZSB0aGlzIGNoYXJhY3RlcgotICAgICAgICAgICAgICAgIGZXcml0ZXIud3JpdGUoICImI3giICk7Ci0gICAgICAgICAgICAgICAgZldyaXRlci53cml0ZShJbnRlZ2VyLnRvSGV4U3RyaW5nKGNoKSk7Ci0gICAgICAgICAgICAgICAgZldyaXRlci53cml0ZSggJzsnICk7Ci0gICAgICAgICAgICAgICAgLy9pbmNyZWFzZSB0aGUgc3RhcnRXcml0ZVBvcyBieSAxIGluZGljYXRpbmcgdGhhdCBuZXh0IHdyaXRlIHNob3VsZCBzdGFydCBmcm9tCi0gICAgICAgICAgICAgICAgLy9vbmUgcG9zaXRpb24gYWhlYWQKLSAgICAgICAgICAgICAgICBzdGFydFdyaXRlUG9zID0gaW5kZXggKyAxOwotCi0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZihERUJVR19YTUxfQ09OVEVOVCl7Ci0gICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJzdGFydFdyaXRlUG9zID0gIiArIHN0YXJ0V3JpdGVQb3MpOwotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiaW5kZXggPSAiICsgaW5kZXgpOwotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigic3RhcnQgPSAiICsgc3RhcnQpOwotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiZW5kID0gIiArIGVuZCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIHN3aXRjaChjaCl7Ci0gICAgICAgICAgICAgICAgY2FzZSAnPCcgOnsKLSAgICAgICAgICAgICAgICAgICAgaWYoZXNjYXBlQ2hhcmFjdGVyKXsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vdGhpcyBjaGFyYWN0ZXIgbmVlZHMgdG8gYmUgZXNjYXBlZCwgd3JpdGUgdGhlIGRhdGEgZnJvbSB0aGUgbGFzdCB3cml0ZSBwb3MKLSAgICAgICAgICAgICAgICAgICAgICAgIGZXcml0ZXIud3JpdGUoY29udGVudCwgc3RhcnRXcml0ZVBvcywgaW5kZXggLSBzdGFydFdyaXRlUG9zKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZXcml0ZXIud3JpdGUoIiZsdDsiKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmKERFQlVHX1hNTF9DT05URU5UKXsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KG5ldyBTdHJpbmcoY29udGVudCwgc3RhcnRXcml0ZVBvcywgaW5kZXggLSBzdGFydFdyaXRlUG9zKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCImbHQ7Iik7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAvL2luY3JlYXNlIHRoZSBzdGFydFdyaXRlUG9zIGJ5IDEgaW5kaWNhdGluZyB0aGF0IG5leHQgd3JpdGUgc2hvdWxkIHN0YXJ0IGZyb20KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vb25lIHBvc2l0aW9uIGFoZWFkCi0gICAgICAgICAgICAgICAgICAgICAgICBzdGFydFdyaXRlUG9zID0gaW5kZXggKyAxOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBjYXNlICcmJyA6ewotICAgICAgICAgICAgICAgICAgICBpZihlc2NhcGVDaGFyYWN0ZXIpewotICAgICAgICAgICAgICAgICAgICAgICAgLy90aGlzIGNoYXJhY3RlciBuZWVkcyB0byBiZSBlc2NhcGVkLCB3cml0ZSB0aGUgZGF0YSBmcm9tIHRoZSBsYXN0IHdyaXRlIHBvcwotICAgICAgICAgICAgICAgICAgICAgICAgZldyaXRlci53cml0ZShjb250ZW50LCBzdGFydFdyaXRlUG9zLCBpbmRleCAtIHN0YXJ0V3JpdGVQb3MpOwotICAgICAgICAgICAgICAgICAgICAgICAgZldyaXRlci53cml0ZSgiJmFtcDsiKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmKERFQlVHX1hNTF9DT05URU5UKXsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KG5ldyBTdHJpbmcoY29udGVudCxzdGFydFdyaXRlUG9zLCBpbmRleCAtIHN0YXJ0V3JpdGVQb3MpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIiZhbXA7Iik7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAvL2luY3JlYXNlIHRoZSBzdGFydFdyaXRlUG9zIGJ5IDEgaW5kaWNhdGluZyB0aGF0IG5leHQgd3JpdGUgc2hvdWxkIHN0YXJ0IGZyb20KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vb25lIHBvc2l0aW9uIGFoZWFkCi0gICAgICAgICAgICAgICAgICAgICAgICBzdGFydFdyaXRlUG9zID0gaW5kZXggKyAxOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIGNhc2UgJz4nOiB7Ci0gICAgICAgICAgICAgICAgICAgIGlmKGVzY2FwZUNoYXJhY3Rlcil7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvL3RoaXMgY2hhcmFjdGVyIG5lZWRzIHRvIGJlIGVzY2FwZWQsIHdyaXRlIHRoZSBkYXRhIGZyb20gdGhlIGxhc3Qgd3JpdGUgcG9zCi0gICAgICAgICAgICAgICAgICAgICAgICBmV3JpdGVyLndyaXRlKGNvbnRlbnQsIHN0YXJ0V3JpdGVQb3MsIGluZGV4IC0gc3RhcnRXcml0ZVBvcyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmV3JpdGVyLndyaXRlKCImZ3Q7Iik7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZihERUJVR19YTUxfQ09OVEVOVCl7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludChuZXcgU3RyaW5nKGNvbnRlbnQsc3RhcnRXcml0ZVBvcywgaW5kZXggLSBzdGFydFdyaXRlUG9zKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCImZ3Q7Iik7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAvL2luY3JlYXNlIHRoZSBzdGFydFdyaXRlUG9zIGJ5IDEgaW5kaWNhdGluZyB0aGF0IG5leHQgd3JpdGUgc2hvdWxkIHN0YXJ0IGZyb20KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vb25lIHBvc2l0aW9uIGFoZWFkCi0gICAgICAgICAgICAgICAgICAgICAgICBzdGFydFdyaXRlUG9zID0gaW5kZXggKyAxOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBpZihERUJVR19YTUxfQ09OVEVOVCl7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIm91dCBvZiB0aGUgbG9vcCwgd3JpdGluZyAiICsgbmV3IFN0cmluZyhjb250ZW50LCBzdGFydFdyaXRlUG9zLCBlbmQgLSBzdGFydFdyaXRlUG9zKSk7Ci0gICAgICAgIH0KLSAgICAgICAgLy93cml0ZSBhbnkgcGVuZGluZyBkYXRhCi0gICAgICAgIGZXcml0ZXIud3JpdGUoY29udGVudCwgc3RhcnRXcml0ZVBvcywgZW5kIC0gc3RhcnRXcml0ZVBvcyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogd3JpdGVzIHhtbCBjb250ZW50IChjaGFyYWN0ZXJzIGFuZCBlbGVtZW50IGNvbnRlbnQKLSAgICAgKiBAcGFyYW0gY29udGVudAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHdyaXRlWE1MQ29udGVudChTdHJpbmcgY29udGVudCkgdGhyb3dzIElPRXhjZXB0aW9uewotICAgICAgICBpZihjb250ZW50ID09IG51bGwgfHwgY29udGVudC5sZW5ndGgoKSA9PSAwKSByZXR1cm4gOwotICAgICAgICB3cml0ZVhNTENvbnRlbnQoY29udGVudC50b0NoYXJBcnJheSgpLCAwLCBjb250ZW50Lmxlbmd0aCgpKTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFdyaXRlIEF0dHJpYnV0ZSB2YWx1ZSB0byB0aGUgdW5kZXJseWluZyBzdHJlYW0uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdmFsdWUKLSAgICAgKi8KLQotICAgIHB1YmxpYyB2b2lkICB3cml0ZVhNTEF0dHJpYnV0ZVZhbHVlKFN0cmluZyB2YWx1ZSl0aHJvd3MgSU9FeGNlcHRpb257Ci0gICAgICAgIHdyaXRlWE1MQ29udGVudCh2YWx1ZS50b0NoYXJBcnJheSgpLCAwLCB2YWx1ZS5sZW5ndGgoKSwgdHJ1ZSk7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBDaGFyc2V0RW5jb2RlciBnZXREZWZhdWx0RW5jb2RlcigpewotICAgICAgICB0cnl7Ci0gICAgICAgICAgICBTdHJpbmcgZW5jb2RpbmcgPSBTZWN1cml0eVN1cHBvcnQuZ2V0U3lzdGVtUHJvcGVydHkoImZpbGUuZW5jb2RpbmciKTsKLSAgICAgICAgICAgIGlmKGVuY29kaW5nICE9IG51bGwpewotICAgICAgICAgICAgICAgIHJldHVybiBDaGFyc2V0LmZvck5hbWUoZW5jb2RpbmcpLm5ld0VuY29kZXIoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBjYXRjaChFeGNlcHRpb24gZXgpewotICAgICAgICAgICAgLy9mb3IgYW55IGV4Y2VwdGlvbiB0aHJvd24gLCBjYXRjaCBhbmQgY29udGludWUKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL3dyaXRlcnMvWE1MRE9NV3JpdGVySW1wbC5qYXZhIGIvc3JjL2NvbS9zdW4veG1sL2ludGVybmFsL3N0cmVhbS93cml0ZXJzL1hNTERPTVdyaXRlckltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNmFiNThkNC4uMDAwMDAwMAotLS0gYS9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL3dyaXRlcnMvWE1MRE9NV3JpdGVySW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNzQyICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMDYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi54bWwuaW50ZXJuYWwuc3RyZWFtLndyaXRlcnM7Ci0KLWltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5JbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uOwotaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lk1ldGhvZDsKLWltcG9ydCBqYXZheC54bWwuWE1MQ29uc3RhbnRzOwotaW1wb3J0IGphdmF4LnhtbC5uYW1lc3BhY2UuTmFtZXNwYWNlQ29udGV4dDsKLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLlhNTFN0cmVhbUV4Y2VwdGlvbjsKLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLlhNTFN0cmVhbVdyaXRlcjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLmRvbS5ET01SZXN1bHQ7Ci1pbXBvcnQgb3JnLnczYy5kb20uQXR0cjsKLWltcG9ydCBvcmcudzNjLmRvbS5DREFUQVNlY3Rpb247Ci1pbXBvcnQgb3JnLnczYy5kb20uQ29tbWVudDsKLWltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKLWltcG9ydCBvcmcudzNjLmRvbS5FbGVtZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLkVudGl0eVJlZmVyZW5jZTsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotaW1wb3J0IG9yZy53M2MuZG9tLlByb2Nlc3NpbmdJbnN0cnVjdGlvbjsKLWltcG9ydCBvcmcudzNjLmRvbS5UZXh0OwotaW1wb3J0IG9yZy54bWwuc2F4LmhlbHBlcnMuTmFtZXNwYWNlU3VwcG9ydDsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIHByb3ZpZGVzIHN1cHBvcnQgdG8gYnVpbGQgYSBET00gdHJlZSB1c2luZyBYTUxTdHJlYW1Xcml0ZXIgQVBJJ3MuCi0gKiBAYXV0aG9yIEsuVmVudWdvcGFsQHN1bi5jb20KLSAqLwotCi0vKgotICogVE9ETyA6IC1WZW51Ci0gKiBJbnRlcm5hbCBOYW1lc3BhY2VNYW5hZ2VtZW50Ci0gKiBzZXRQcmVmaXgKLSAqIHN1cHBvcnQgZm9yIGlzUmVwYWlyTmFtZXNwYWNlIHByb3BlcnR5LgotICogU29tZSBVbnN1cHBvcnRlZCBNZXRob2RzLgotICogQ2hhbmdlIFN0cmluZ0J1ZmZlciB0byBTdHJpbmdCdWlsZGVyLCB3aGVuIEpESyAxLjUgd2lsbCBiZSBtaW5pbXVtIHJlcXVpcmVtZW50IGZvciBTSlNYUC4KLSAqLwotCi1wdWJsaWMgY2xhc3MgWE1MRE9NV3JpdGVySW1wbCBpbXBsZW1lbnRzIFhNTFN0cmVhbVdyaXRlciAgewotCi0KLSAgICBwcml2YXRlIERvY3VtZW50IG93bmVyRG9jID0gbnVsbDsKLSAgICBwcml2YXRlIE5vZGUgY3VycmVudE5vZGUgPSBudWxsOwotICAgIHByaXZhdGUgTm9kZSBub2RlID0gbnVsbDsKLSAgICBwcml2YXRlIE5hbWVzcGFjZVN1cHBvcnQgbmFtZXNwYWNlQ29udGV4dCA9IG51bGw7Ci0gICAgcHJpdmF0ZSBNZXRob2QgIG1YbWxWZXJzaW9uID0gbnVsbDsKLSAgICBwcml2YXRlIGJvb2xlYW4gW10gbmVlZENvbnRleHRQb3AgPSBudWxsOwotICAgIHByaXZhdGUgU3RyaW5nQnVmZmVyIHN0cmluZ0J1ZmZlciA9IG51bGw7Ci0gICAgcHJpdmF0ZSBpbnQgcmVzaXplVmFsdWUgPSAyMDsKLSAgICBwcml2YXRlIGludCBkZXB0aCA9IDA7Ci0gICAgLyoqCi0gICAgICogQ3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiBYTUxET013cml0ZXJJbXBsCi0gICAgICogQHBhcmFtIHJlc3VsdCBET01SZXN1bHQgb2JqZWN0IEBqYXZheC54bWwudHJhbnNmb3JtLmRvbS5ET01SZXN1bHQKLSAgICAgKi8KLSAgICBwdWJsaWMgWE1MRE9NV3JpdGVySW1wbChET01SZXN1bHQgcmVzdWx0KSB7Ci0KLSAgICAgICAgbm9kZSA9IHJlc3VsdC5nZXROb2RlKCk7Ci0gICAgICAgIGlmKCBub2RlLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5ET0NVTUVOVF9OT0RFKXsKLSAgICAgICAgICAgIG93bmVyRG9jID0gKERvY3VtZW50KW5vZGU7Ci0gICAgICAgICAgICBjdXJyZW50Tm9kZSA9IG93bmVyRG9jOwotICAgICAgICB9ZWxzZXsKLSAgICAgICAgICAgIG93bmVyRG9jID0gbm9kZS5nZXRPd25lckRvY3VtZW50KCk7Ci0gICAgICAgICAgICBjdXJyZW50Tm9kZSA9IG5vZGU7Ci0gICAgICAgIH0KLSAgICAgICAgZ2V0RExUaHJlZU1ldGhvZHMoKTsKLSAgICAgICAgc3RyaW5nQnVmZmVyID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotICAgICAgICBuZWVkQ29udGV4dFBvcCA9IG5ldyBib29sZWFuW3Jlc2l6ZVZhbHVlXTsKLSAgICAgICAgbmFtZXNwYWNlQ29udGV4dCA9IG5ldyBOYW1lc3BhY2VTdXBwb3J0KCk7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIGdldERMVGhyZWVNZXRob2RzKCl7Ci0gICAgICAgIHRyeXsKLSAgICAgICAgICAgIG1YbWxWZXJzaW9uID0gIG93bmVyRG9jLmdldENsYXNzKCkuZ2V0TWV0aG9kKCJzZXRYbWxWZXJzaW9uIixuZXcgQ2xhc3NbXSB7U3RyaW5nLmNsYXNzfSk7Ci0gICAgICAgIH1jYXRjaChOb1N1Y2hNZXRob2RFeGNlcHRpb24gbWV4KXsKLSAgICAgICAgICAgIC8vbG9nIHRoZXNlIGVycm9ycyBhdCBmaW5lIGxldmVsLgotICAgICAgICAgICAgbVhtbFZlcnNpb24gPSBudWxsOwotICAgICAgICB9Y2F0Y2goU2VjdXJpdHlFeGNlcHRpb24gc2UpewotICAgICAgICAgICAgLy9sb2cgdGhlc2UgZXJyb3JzIGF0IGZpbmUgbGV2ZWwuCi0gICAgICAgICAgICBtWG1sVmVyc2lvbiA9IG51bGw7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIGhhcyBubyBlZmZlY3Qgd2hlbiBjYWxsZWQuCi0gICAgICogQHRocm93cyBqYXZheC54bWwuc3RyZWFtLlhNTFN0cmVhbUV4Y2VwdGlvbiB7QGluaGVyaXREb2N9Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uIHsKLSAgICAgICAgLy9uby1vcAotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIGhhcyBubyBlZmZlY3Qgd2hlbiBjYWxsZWQuCi0gICAgICogQHRocm93cyBqYXZheC54bWwuc3RyZWFtLlhNTFN0cmVhbUV4Y2VwdGlvbiB7QGluaGVyaXREb2N9Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgZmx1c2goKSB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uIHsKLSAgICAgICAgLy9uby1vcAotICAgIH0KLQotICAgIC8qKgotICAgICAqIHtAaW5oZXJpdERvY30KLSAgICAgKiBAcmV0dXJuIHtAaW5oZXJpdERvY30KLSAgICAgKi8KLSAgICBwdWJsaWMgamF2YXgueG1sLm5hbWVzcGFjZS5OYW1lc3BhY2VDb250ZXh0IGdldE5hbWVzcGFjZUNvbnRleHQoKSB7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIHtAaW5oZXJpdERvY30KLSAgICAgKiBAcGFyYW0gbmFtZXNwYWNlVVJJIHtAaW5oZXJpdERvY30KLSAgICAgKiBAdGhyb3dzIGphdmF4LnhtbC5zdHJlYW0uWE1MU3RyZWFtRXhjZXB0aW9uIHtAaW5oZXJpdERvY30KLSAgICAgKiBAcmV0dXJuIHtAaW5oZXJpdERvY30KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFByZWZpeChTdHJpbmcgbmFtZXNwYWNlVVJJKSB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uIHsKLSAgICAgICAgU3RyaW5nIHByZWZpeCA9IG51bGw7Ci0gICAgICAgIGlmKHRoaXMubmFtZXNwYWNlQ29udGV4dCAhPSBudWxsKXsKLSAgICAgICAgICAgIHByZWZpeCA9IG5hbWVzcGFjZUNvbnRleHQuZ2V0UHJlZml4KG5hbWVzcGFjZVVSSSk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIHByZWZpeDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJcyBub3Qgc3VwcG9ydGVkIGluIHRoaXMgaW1wbGVtZW50YXRpb24uCi0gICAgICogQHBhcmFtIHN0ciB7QGluaGVyaXREb2N9Ci0gICAgICogQHRocm93cyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHtAaW5oZXJpdERvY30KLSAgICAgKiBAcmV0dXJuIHtAaW5oZXJpdERvY30KLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0IGdldFByb3BlcnR5KFN0cmluZyBzdHIpIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gewotICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJcyBub3Qgc3VwcG9ydGVkIGluIHRoaXMgdmVyc2lvbiBvZiB0aGUgaW1wbGVtZW50YXRpb24uCi0gICAgICogQHBhcmFtIHVyaSB7QGluaGVyaXREb2N9Ci0gICAgICogQHRocm93cyBqYXZheC54bWwuc3RyZWFtLlhNTFN0cmVhbUV4Y2VwdGlvbiB7QGluaGVyaXREb2N9Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RGVmYXVsdE5hbWVzcGFjZShTdHJpbmcgdXJpKSB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uIHsKLSAgICAgICAgbmFtZXNwYWNlQ29udGV4dC5kZWNsYXJlUHJlZml4KFhNTENvbnN0YW50cy5ERUZBVUxUX05TX1BSRUZJWCwgdXJpKTsKLSAgICAgICAgaWYoIW5lZWRDb250ZXh0UG9wW2RlcHRoXSl7Ci0gICAgICAgICAgICBuZWVkQ29udGV4dFBvcFtkZXB0aF0gPSB0cnVlOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICoge0Bpbmhlcml0RG9jfQotICAgICAqIEBwYXJhbSBuYW1lc3BhY2VDb250ZXh0IHtAaW5oZXJpdERvY30KLSAgICAgKiBAdGhyb3dzIGphdmF4LnhtbC5zdHJlYW0uWE1MU3RyZWFtRXhjZXB0aW9uIHtAaW5oZXJpdERvY30KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXROYW1lc3BhY2VDb250ZXh0KGphdmF4LnhtbC5uYW1lc3BhY2UuTmFtZXNwYWNlQ29udGV4dCBuYW1lc3BhY2VDb250ZXh0KSB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uIHsKLSAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSXMgbm90IHN1cHBvcnRlZCBpbiB0aGlzIHZlcnNpb24gb2YgdGhlIGltcGxlbWVudGF0aW9uLgotICAgICAqIEBwYXJhbSBwcmVmaXgge0Bpbmhlcml0RG9jfQotICAgICAqIEBwYXJhbSB1cmkge0Bpbmhlcml0RG9jfQotICAgICAqIEB0aHJvd3MgamF2YXgueG1sLnN0cmVhbS5YTUxTdHJlYW1FeGNlcHRpb24ge0Bpbmhlcml0RG9jfQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFByZWZpeChTdHJpbmcgcHJlZml4LCBTdHJpbmcgdXJpKSB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uIHsKLSAgICAgICAgaWYocHJlZml4ID09IG51bGwpewotICAgICAgICAgICAgdGhyb3cgbmV3IFhNTFN0cmVhbUV4Y2VwdGlvbigiUHJlZml4IGNhbm5vdCBiZSBudWxsIik7Ci0gICAgICAgIH0KLSAgICAgICAgbmFtZXNwYWNlQ29udGV4dC5kZWNsYXJlUHJlZml4KHByZWZpeCwgdXJpKTsKLSAgICAgICAgaWYoIW5lZWRDb250ZXh0UG9wW2RlcHRoXSl7Ci0gICAgICAgICAgICBuZWVkQ29udGV4dFBvcFtkZXB0aF0gPSB0cnVlOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlcyBhIERPTSBBdHJyaWJ1dGUgQHNlZSBvcmcudzNjLmRvbS5Ob2RlIGFuZCBhc3NvY2lhdGVzIGl0IHdpdGggdGhlIGN1cnJlbnQgRE9NIGVsZW1lbnQgQHNlZSBvcmcudzNjLmRvbS5Ob2RlLgotICAgICAqIEBwYXJhbSBsb2NhbE5hbWUge0Bpbmhlcml0RG9jfQotICAgICAqIEBwYXJhbSB2YWx1ZSB7QGluaGVyaXREb2N9Ci0gICAgICogQHRocm93cyBqYXZheC54bWwuc3RyZWFtLlhNTFN0cmVhbUV4Y2VwdGlvbiB7QGluaGVyaXREb2N9Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgd3JpdGVBdHRyaWJ1dGUoU3RyaW5nIGxvY2FsTmFtZSwgU3RyaW5nIHZhbHVlKSB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uIHsKLQotICAgICAgICBpZihjdXJyZW50Tm9kZS5nZXROb2RlVHlwZSgpID09IE5vZGUuRUxFTUVOVF9OT0RFKXsKLSAgICAgICAgICAgIEF0dHIgYXR0ciA9IG93bmVyRG9jLmNyZWF0ZUF0dHJpYnV0ZShsb2NhbE5hbWUpOwotICAgICAgICAgICAgYXR0ci5zZXRWYWx1ZSh2YWx1ZSk7Ci0gICAgICAgICAgICAoKEVsZW1lbnQpY3VycmVudE5vZGUpLnNldEF0dHJpYnV0ZU5vZGUoYXR0cik7Ci0gICAgICAgIH1lbHNlewotICAgICAgICAgICAgLy9Db252ZXJ0IG5vZGUgdHlwZSB0byBTdHJpbmcKLSAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oIkN1cnJlbnQgRE9NIE5vZGUgdHlwZSAgaXMgIisgY3VycmVudE5vZGUuZ2V0Tm9kZVR5cGUoKSArCi0gICAgICAgICAgICAgICAgICAgICJhbmQgZG9lcyBub3QgYWxsb3cgYXR0cmlidXRlcyB0byBiZSBzZXQgIik7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGVzIGEgRE9NIEF0cnJpYnV0ZSBAc2VlIG9yZy53M2MuZG9tLk5vZGUgYW5kIGFzc29jaWF0ZXMgaXQgd2l0aCB0aGUgY3VycmVudCBET00gZWxlbWVudCBAc2VlIG9yZy53M2MuZG9tLk5vZGUuCi0gICAgICogQHBhcmFtIG5hbWVzcGFjZVVSSSB7QGluaGVyaXREb2N9Ci0gICAgICogQHBhcmFtIGxvY2FsTmFtZSB7QGluaGVyaXREb2N9Ci0gICAgICogQHBhcmFtIHZhbHVlIHtAaW5oZXJpdERvY30KLSAgICAgKiBAdGhyb3dzIGphdmF4LnhtbC5zdHJlYW0uWE1MU3RyZWFtRXhjZXB0aW9uIHtAaW5oZXJpdERvY30KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB3cml0ZUF0dHJpYnV0ZShTdHJpbmcgbmFtZXNwYWNlVVJJLFN0cmluZyBsb2NhbE5hbWUsU3RyaW5nIHZhbHVlKXRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24gewotICAgICAgICBpZihjdXJyZW50Tm9kZS5nZXROb2RlVHlwZSgpID09IE5vZGUuRUxFTUVOVF9OT0RFKXsKLSAgICAgICAgICAgIFN0cmluZyBwcmVmaXggPSBudWxsOwotICAgICAgICAgICAgaWYobmFtZXNwYWNlVVJJID09IG51bGwgKXsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWE1MU3RyZWFtRXhjZXB0aW9uKCJOYW1lc3BhY2VVUkkgY2Fubm90IGJlIG51bGwiKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmKGxvY2FsTmFtZSA9PSBudWxsKXsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWE1MU3RyZWFtRXhjZXB0aW9uKCJMb2NhbCBuYW1lIGNhbm5vdCBiZSBudWxsIik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZihuYW1lc3BhY2VDb250ZXh0ICE9IG51bGwpewotICAgICAgICAgICAgICAgIHByZWZpeCA9IG5hbWVzcGFjZUNvbnRleHQuZ2V0UHJlZml4KG5hbWVzcGFjZVVSSSk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmKHByZWZpeCA9PSBudWxsKXsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWE1MU3RyZWFtRXhjZXB0aW9uKCJOYW1lc3BhY2UgVVJJICIrbmFtZXNwYWNlVVJJICsKLSAgICAgICAgICAgICAgICAgICAgICAgICJpcyBub3QgYm91bmQgdG8gYW55IHByZWZpeCIgKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgU3RyaW5nIHF1YWxpZmllZE5hbWUgPSBudWxsOwotICAgICAgICAgICAgaWYocHJlZml4LmVxdWFscygiIikpewotICAgICAgICAgICAgICAgIHF1YWxpZmllZE5hbWUgPSBsb2NhbE5hbWU7Ci0gICAgICAgICAgICB9ZWxzZXsKLSAgICAgICAgICAgICAgICBxdWFsaWZpZWROYW1lID0gZ2V0UU5hbWUocHJlZml4LGxvY2FsTmFtZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBBdHRyIGF0dHIgPSBvd25lckRvYy5jcmVhdGVBdHRyaWJ1dGVOUyhuYW1lc3BhY2VVUkksIHF1YWxpZmllZE5hbWUpOwotICAgICAgICAgICAgYXR0ci5zZXRWYWx1ZSh2YWx1ZSk7Ci0gICAgICAgICAgICAoKEVsZW1lbnQpY3VycmVudE5vZGUpLnNldEF0dHJpYnV0ZU5vZGUoYXR0cik7Ci0gICAgICAgIH1lbHNlewotICAgICAgICAgICAgLy9Db252ZXJ0IG5vZGUgdHlwZSB0byBTdHJpbmcKLSAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oIkN1cnJlbnQgRE9NIE5vZGUgdHlwZSAgaXMgIisgY3VycmVudE5vZGUuZ2V0Tm9kZVR5cGUoKSArCi0gICAgICAgICAgICAgICAgICAgICJhbmQgZG9lcyBub3QgYWxsb3cgYXR0cmlidXRlcyB0byBiZSBzZXQgIik7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGVzIGEgRE9NIEF0cnJpYnV0ZSBAc2VlIG9yZy53M2MuZG9tLk5vZGUgYW5kIGFzc29jaWF0ZXMgaXQgd2l0aCB0aGUgY3VycmVudCBET00gZWxlbWVudCBAc2VlIG9yZy53M2MuZG9tLk5vZGUuCi0gICAgICogQHBhcmFtIHByZWZpeCB7QGluaGVyaXREb2N9Ci0gICAgICogQHBhcmFtIG5hbWVzcGFjZVVSSSB7QGluaGVyaXREb2N9Ci0gICAgICogQHBhcmFtIGxvY2FsTmFtZSB7QGluaGVyaXREb2N9Ci0gICAgICogQHBhcmFtIHZhbHVlIHtAaW5oZXJpdERvY30KLSAgICAgKiBAdGhyb3dzIGphdmF4LnhtbC5zdHJlYW0uWE1MU3RyZWFtRXhjZXB0aW9uIHtAaW5oZXJpdERvY30KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB3cml0ZUF0dHJpYnV0ZShTdHJpbmcgcHJlZml4LFN0cmluZyBuYW1lc3BhY2VVUkksU3RyaW5nIGxvY2FsTmFtZSxTdHJpbmcgdmFsdWUpdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmKGN1cnJlbnROb2RlLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5FTEVNRU5UX05PREUpewotICAgICAgICAgICAgaWYobmFtZXNwYWNlVVJJID09IG51bGwgKXsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWE1MU3RyZWFtRXhjZXB0aW9uKCJOYW1lc3BhY2VVUkkgY2Fubm90IGJlIG51bGwiKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmKGxvY2FsTmFtZSA9PSBudWxsKXsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWE1MU3RyZWFtRXhjZXB0aW9uKCJMb2NhbCBuYW1lIGNhbm5vdCBiZSBudWxsIik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZihwcmVmaXggPT0gbnVsbCl7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFhNTFN0cmVhbUV4Y2VwdGlvbigicHJlZml4IGNhbm5vdCBiZSBudWxsIik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBTdHJpbmcgcXVhbGlmaWVkTmFtZSA9IG51bGw7Ci0gICAgICAgICAgICBpZihwcmVmaXguZXF1YWxzKCIiKSl7Ci0gICAgICAgICAgICAgICAgcXVhbGlmaWVkTmFtZSA9IGxvY2FsTmFtZTsKLSAgICAgICAgICAgIH1lbHNlewotCi0gICAgICAgICAgICAgICAgcXVhbGlmaWVkTmFtZSA9IGdldFFOYW1lKHByZWZpeCxsb2NhbE5hbWUpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgQXR0ciBhdHRyID0gb3duZXJEb2MuY3JlYXRlQXR0cmlidXRlTlMobmFtZXNwYWNlVVJJLCBxdWFsaWZpZWROYW1lKTsKLSAgICAgICAgICAgIGF0dHIuc2V0VmFsdWUodmFsdWUpOwotICAgICAgICAgICAgKChFbGVtZW50KWN1cnJlbnROb2RlKS5zZXRBdHRyaWJ1dGVOb2RlTlMoYXR0cik7Ci0gICAgICAgIH1lbHNlewotICAgICAgICAgICAgLy9Db252ZXJ0IG5vZGUgdHlwZSB0byBTdHJpbmcKLSAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oIkN1cnJlbnQgRE9NIE5vZGUgdHlwZSAgaXMgIisgY3VycmVudE5vZGUuZ2V0Tm9kZVR5cGUoKSArCi0gICAgICAgICAgICAgICAgICAgICJhbmQgZG9lcyBub3QgYWxsb3cgYXR0cmlidXRlcyB0byBiZSBzZXQgIik7Ci0gICAgICAgIH0KLQotICAgIH0KLQotICAgIC8qKgotICAgICAqIENyZWF0ZXMgYSBDREFUQSBvYmplY3QgQHNlZSBvcmcudzNjLmRvbS5DREFUQVNlY3Rpb24uCi0gICAgICogQHBhcmFtIGRhdGEge0Bpbmhlcml0RG9jfQotICAgICAqIEB0aHJvd3MgamF2YXgueG1sLnN0cmVhbS5YTUxTdHJlYW1FeGNlcHRpb24ge0Bpbmhlcml0RG9jfQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHdyaXRlQ0RhdGEoU3RyaW5nIGRhdGEpIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24gewotICAgICAgICBpZihkYXRhID09IG51bGwpewotICAgICAgICAgICAgdGhyb3cgbmV3IFhNTFN0cmVhbUV4Y2VwdGlvbigiQ0RBVEEgY2Fubm90IGJlIG51bGwiKTsKLSAgICAgICAgfQotCi0gICAgICAgIENEQVRBU2VjdGlvbiBjZGF0YSA9IG93bmVyRG9jLmNyZWF0ZUNEQVRBU2VjdGlvbihkYXRhKTsKLSAgICAgICAgZ2V0Tm9kZSgpLmFwcGVuZENoaWxkKGNkYXRhKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGVzIGEgY2hhcmFjdGVyIG9iamVjdCBAc2VlIG9yZy53M2MuZG9tLlRleHQgYW5kIGFwcGVuZHMgaXQgdG8gdGhlIGN1cnJlbnQKLSAgICAgKiBlbGVtZW50IGluIHRoZSBET00gdHJlZS4KLSAgICAgKiBAcGFyYW0gY2hhckRhdGEge0Bpbmhlcml0RG9jfQotICAgICAqIEB0aHJvd3MgamF2YXgueG1sLnN0cmVhbS5YTUxTdHJlYW1FeGNlcHRpb24ge0Bpbmhlcml0RG9jfQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHdyaXRlQ2hhcmFjdGVycyhTdHJpbmcgY2hhckRhdGEpIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24gewotICAgICAgICBUZXh0IHRleHQgPSBvd25lckRvYy5jcmVhdGVUZXh0Tm9kZShjaGFyRGF0YSk7Ci0gICAgICAgIGN1cnJlbnROb2RlLmFwcGVuZENoaWxkKHRleHQpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENyZWF0ZXMgYSBjaGFyYWN0ZXIgb2JqZWN0IEBzZWUgb3JnLnczYy5kb20uVGV4dCBhbmQgYXBwZW5kcyBpdCB0byB0aGUgY3VycmVudAotICAgICAqIGVsZW1lbnQgaW4gdGhlIERPTSB0cmVlLgotICAgICAqIEBwYXJhbSB2YWx1ZXMge0Bpbmhlcml0RG9jfQotICAgICAqIEBwYXJhbSBwYXJhbSB7QGluaGVyaXREb2N9Ci0gICAgICogQHBhcmFtIHBhcmFtMiB7QGluaGVyaXREb2N9Ci0gICAgICogQHRocm93cyBqYXZheC54bWwuc3RyZWFtLlhNTFN0cmVhbUV4Y2VwdGlvbiB7QGluaGVyaXREb2N9Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgd3JpdGVDaGFyYWN0ZXJzKGNoYXJbXSB2YWx1ZXMsIGludCBwYXJhbSwgaW50IHBhcmFtMikgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgVGV4dCB0ZXh0ID0gb3duZXJEb2MuY3JlYXRlVGV4dE5vZGUobmV3IFN0cmluZyh2YWx1ZXMscGFyYW0scGFyYW0yKSk7Ci0gICAgICAgIGN1cnJlbnROb2RlLmFwcGVuZENoaWxkKHRleHQpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENyZWF0ZXMgYSBDb21tZW50IG9iamVjdCBAc2VlIG9yZy53M2MuZG9tLkNvbW1lbnQgYW5kIGFwcGVuZHMgaXQgdG8gdGhlIGN1cnJlbnQKLSAgICAgKiBlbGVtZW50IGluIHRoZSBET00gdHJlZS4KLSAgICAgKiBAcGFyYW0gc3RyIHtAaW5oZXJpdERvY30KLSAgICAgKiBAdGhyb3dzIGphdmF4LnhtbC5zdHJlYW0uWE1MU3RyZWFtRXhjZXB0aW9uIHtAaW5oZXJpdERvY30KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB3cml0ZUNvbW1lbnQoU3RyaW5nIHN0cikgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbiB7Ci0gICAgICAgIENvbW1lbnQgY29tbWVudCA9IG93bmVyRG9jLmNyZWF0ZUNvbW1lbnQoc3RyKTsKLSAgICAgICAgZ2V0Tm9kZSgpLmFwcGVuZENoaWxkKGNvbW1lbnQpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIGlzIG5vdCBzdXBwb3J0ZWQgaW4gdGhpcyBpbXBsZW1lbnRhdGlvbi4KLSAgICAgKiBAcGFyYW0gc3RyIHtAaW5oZXJpdERvY30KLSAgICAgKiBAdGhyb3dzIGphdmF4LnhtbC5zdHJlYW0uWE1MU3RyZWFtRXhjZXB0aW9uIHtAaW5oZXJpdERvY30KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB3cml0ZURURChTdHJpbmcgc3RyKSB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uIHsKLSAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlcyBhIERPTSBhdHRyaWJ1dGUgYW5kIGFkZHMgaXQgdG8gdGhlIGN1cnJlbnQgZWxlbWVudCBpbiB0aGUgRE9NIHRyZWUuCi0gICAgICogQHBhcmFtIG5hbWVzcGFjZVVSSSB7QGluaGVyaXREb2N9Ci0gICAgICogQHRocm93cyBqYXZheC54bWwuc3RyZWFtLlhNTFN0cmVhbUV4Y2VwdGlvbiB7QGluaGVyaXREb2N9Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgd3JpdGVEZWZhdWx0TmFtZXNwYWNlKFN0cmluZyBuYW1lc3BhY2VVUkkpIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24gewotICAgICAgICBpZihjdXJyZW50Tm9kZS5nZXROb2RlVHlwZSgpID09IE5vZGUuRUxFTUVOVF9OT0RFKXsKLSAgICAgICAgICAgIFN0cmluZyBxbmFtZSA9IFhNTENvbnN0YW50cy5YTUxOU19BVFRSSUJVVEU7Ci0gICAgICAgICAgICAoKEVsZW1lbnQpY3VycmVudE5vZGUpLnNldEF0dHJpYnV0ZU5TKFhNTENvbnN0YW50cy5YTUxOU19BVFRSSUJVVEVfTlNfVVJJLHFuYW1lLCBuYW1lc3BhY2VVUkkpOwotICAgICAgICB9ZWxzZXsKLSAgICAgICAgICAgIC8vQ29udmVydCBub2RlIHR5cGUgdG8gU3RyaW5nCi0gICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJDdXJyZW50IERPTSBOb2RlIHR5cGUgIGlzICIrIGN1cnJlbnROb2RlLmdldE5vZGVUeXBlKCkgKwotICAgICAgICAgICAgICAgICAgICAiYW5kIGRvZXMgbm90IGFsbG93IGF0dHJpYnV0ZXMgdG8gYmUgc2V0ICIpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogY3JlYXRlcyBhIERPTSBFbGVtZW50IGFuZCBhcHBlbmRzIGl0IHRvIHRoZSBjdXJyZW50IGVsZW1lbnQgaW4gdGhlIHRyZWUuCi0gICAgICogQHBhcmFtIGxvY2FsTmFtZSB7QGluaGVyaXREb2N9Ci0gICAgICogQHRocm93cyBqYXZheC54bWwuc3RyZWFtLlhNTFN0cmVhbUV4Y2VwdGlvbiB7QGluaGVyaXREb2N9Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgd3JpdGVFbXB0eUVsZW1lbnQoU3RyaW5nIGxvY2FsTmFtZSkgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmKG93bmVyRG9jICE9IG51bGwpewotICAgICAgICAgICAgRWxlbWVudCBlbGVtZW50ID0gb3duZXJEb2MuY3JlYXRlRWxlbWVudChsb2NhbE5hbWUpOwotICAgICAgICAgICAgaWYoY3VycmVudE5vZGUhPW51bGwpewotICAgICAgICAgICAgICAgIGN1cnJlbnROb2RlLmFwcGVuZENoaWxkKGVsZW1lbnQpOwotICAgICAgICAgICAgfWVsc2V7Ci0gICAgICAgICAgICAgICAgb3duZXJEb2MuYXBwZW5kQ2hpbGQoZWxlbWVudCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgIH0KLQotICAgIC8qKgotICAgICAqIGNyZWF0ZXMgYSBET00gRWxlbWVudCBhbmQgYXBwZW5kcyBpdCB0byB0aGUgY3VycmVudCBlbGVtZW50IGluIHRoZSB0cmVlLgotICAgICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkge0Bpbmhlcml0RG9jfQotICAgICAqIEBwYXJhbSBsb2NhbE5hbWUge0Bpbmhlcml0RG9jfQotICAgICAqIEB0aHJvd3MgamF2YXgueG1sLnN0cmVhbS5YTUxTdHJlYW1FeGNlcHRpb24ge0Bpbmhlcml0RG9jfQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHdyaXRlRW1wdHlFbGVtZW50KFN0cmluZyBuYW1lc3BhY2VVUkksIFN0cmluZyBsb2NhbE5hbWUpIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24gewotICAgICAgICBpZihvd25lckRvYyAhPSBudWxsKXsKLSAgICAgICAgICAgIFN0cmluZyBxdWFsaWZpZWROYW1lID0gbnVsbDsKLSAgICAgICAgICAgIFN0cmluZyBwcmVmaXggPSBudWxsOwotICAgICAgICAgICAgaWYobmFtZXNwYWNlVVJJID09IG51bGwgKXsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWE1MU3RyZWFtRXhjZXB0aW9uKCJOYW1lc3BhY2VVUkkgY2Fubm90IGJlIG51bGwiKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmKGxvY2FsTmFtZSA9PSBudWxsKXsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWE1MU3RyZWFtRXhjZXB0aW9uKCJMb2NhbCBuYW1lIGNhbm5vdCBiZSBudWxsIik7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmKG5hbWVzcGFjZUNvbnRleHQgIT0gbnVsbCl7Ci0gICAgICAgICAgICAgICAgcHJlZml4ID0gbmFtZXNwYWNlQ29udGV4dC5nZXRQcmVmaXgobmFtZXNwYWNlVVJJKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmKHByZWZpeCA9PSBudWxsKXsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWE1MU3RyZWFtRXhjZXB0aW9uKCJOYW1lc3BhY2UgVVJJICIrbmFtZXNwYWNlVVJJICsKLSAgICAgICAgICAgICAgICAgICAgICAgICJpcyBub3QgYm91bmQgdG8gYW55IHByZWZpeCIgKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmKCIiLmVxdWFscyhwcmVmaXgpKXsKLSAgICAgICAgICAgICAgICBxdWFsaWZpZWROYW1lID0gbG9jYWxOYW1lOwotICAgICAgICAgICAgfWVsc2V7Ci0KLSAgICAgICAgICAgICAgICBxdWFsaWZpZWROYW1lID0gZ2V0UU5hbWUocHJlZml4LGxvY2FsTmFtZSk7Ci0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIEVsZW1lbnQgZWxlbWVudCA9IG93bmVyRG9jLmNyZWF0ZUVsZW1lbnROUyhuYW1lc3BhY2VVUkksIHF1YWxpZmllZE5hbWUpOwotICAgICAgICAgICAgaWYoY3VycmVudE5vZGUhPW51bGwpewotICAgICAgICAgICAgICAgIGN1cnJlbnROb2RlLmFwcGVuZENoaWxkKGVsZW1lbnQpOwotICAgICAgICAgICAgfWVsc2V7Ci0gICAgICAgICAgICAgICAgb3duZXJEb2MuYXBwZW5kQ2hpbGQoZWxlbWVudCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvL2N1cnJlbnROb2RlID0gZWxlbWVudDsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIGNyZWF0ZXMgYSBET00gRWxlbWVudCBhbmQgYXBwZW5kcyBpdCB0byB0aGUgY3VycmVudCBlbGVtZW50IGluIHRoZSB0cmVlLgotICAgICAqIEBwYXJhbSBwcmVmaXgge0Bpbmhlcml0RG9jfQotICAgICAqIEBwYXJhbSBsb2NhbE5hbWUge0Bpbmhlcml0RG9jfQotICAgICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkge0Bpbmhlcml0RG9jfQotICAgICAqIEB0aHJvd3MgamF2YXgueG1sLnN0cmVhbS5YTUxTdHJlYW1FeGNlcHRpb24ge0Bpbmhlcml0RG9jfQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHdyaXRlRW1wdHlFbGVtZW50KFN0cmluZyBwcmVmaXgsIFN0cmluZyBsb2NhbE5hbWUsIFN0cmluZyBuYW1lc3BhY2VVUkkpIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24gewotICAgICAgICBpZihvd25lckRvYyAhPSBudWxsKXsKLSAgICAgICAgICAgIGlmKG5hbWVzcGFjZVVSSSA9PSBudWxsICl7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFhNTFN0cmVhbUV4Y2VwdGlvbigiTmFtZXNwYWNlVVJJIGNhbm5vdCBiZSBudWxsIik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZihsb2NhbE5hbWUgPT0gbnVsbCl7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFhNTFN0cmVhbUV4Y2VwdGlvbigiTG9jYWwgbmFtZSBjYW5ub3QgYmUgbnVsbCIpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYocHJlZml4ID09IG51bGwpewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBYTUxTdHJlYW1FeGNlcHRpb24oIlByZWZpeCBjYW5ub3QgYmUgbnVsbCIpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgU3RyaW5nIHF1YWxpZmllZE5hbWUgPSBudWxsOwotICAgICAgICAgICAgaWYoIiIuZXF1YWxzKHByZWZpeCkpewotICAgICAgICAgICAgICAgIHF1YWxpZmllZE5hbWUgPSBsb2NhbE5hbWU7Ci0gICAgICAgICAgICB9ZWxzZXsKLSAgICAgICAgICAgICAgICBxdWFsaWZpZWROYW1lID0gZ2V0UU5hbWUocHJlZml4LGxvY2FsTmFtZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBFbGVtZW50IGVsICA9IG93bmVyRG9jLmNyZWF0ZUVsZW1lbnROUyhuYW1lc3BhY2VVUkkscXVhbGlmaWVkTmFtZSk7Ci0gICAgICAgICAgICBpZihjdXJyZW50Tm9kZSE9bnVsbCl7Ci0gICAgICAgICAgICAgICAgY3VycmVudE5vZGUuYXBwZW5kQ2hpbGQoZWwpOwotICAgICAgICAgICAgfWVsc2V7Ci0gICAgICAgICAgICAgICAgb3duZXJEb2MuYXBwZW5kQ2hpbGQoZWwpOwotICAgICAgICAgICAgfQotCi0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBXaWxsIHJlc2V0IGN1cnJlbnQgTm9kZSBwb2ludGVyIG1haW50YWluZWQgYnkgdGhlIGltcGxlbWVudGF0aW9uLgotICAgICAqIEB0aHJvd3MgamF2YXgueG1sLnN0cmVhbS5YTUxTdHJlYW1FeGNlcHRpb24ge0Bpbmhlcml0RG9jfQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHdyaXRlRW5kRG9jdW1lbnQoKSB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uIHsKLSAgICAgICAgLy9XaGF0IGRvIHlvdSB3YW50IG1lIHRvIGRvIGVoISA6KQotICAgICAgICBjdXJyZW50Tm9kZSA9IG51bGw7Ci0gICAgICAgIGZvcihpbnQgaT0wOyBpPCBkZXB0aDtpKyspewotICAgICAgICAgICAgaWYobmVlZENvbnRleHRQb3BbZGVwdGhdKXsKLSAgICAgICAgICAgICAgICBuZWVkQ29udGV4dFBvcFtkZXB0aF0gPSBmYWxzZTsKLSAgICAgICAgICAgICAgICBuYW1lc3BhY2VDb250ZXh0LnBvcENvbnRleHQoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGRlcHRoLS07Ci0gICAgICAgIH0KLSAgICAgICAgZGVwdGggPTA7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSW50ZXJuYWwgY3VycmVudCBOb2RlIHBvaW50ZXIgd2lsbCBwb2ludCB0byB0aGUgcGFyZW50IG9mIHRoZSBjdXJyZW50IE5vZGUuCi0gICAgICogQHRocm93cyBqYXZheC54bWwuc3RyZWFtLlhNTFN0cmVhbUV4Y2VwdGlvbiB7QGluaGVyaXREb2N9Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgd3JpdGVFbmRFbGVtZW50KCkgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbiB7Ci0gICAgICAgIE5vZGUgbm9kZT0gY3VycmVudE5vZGUuZ2V0UGFyZW50Tm9kZSgpOwotICAgICAgICBpZihjdXJyZW50Tm9kZS5nZXROb2RlVHlwZSgpID09IE5vZGUuRE9DVU1FTlRfTk9ERSl7Ci0gICAgICAgICAgICBjdXJyZW50Tm9kZSA9IG51bGw7Ci0gICAgICAgIH1lbHNlewotICAgICAgICAgICAgY3VycmVudE5vZGUgPSBub2RlOwotICAgICAgICB9Ci0gICAgICAgIGlmKG5lZWRDb250ZXh0UG9wW2RlcHRoXSl7Ci0gICAgICAgICAgICBuZWVkQ29udGV4dFBvcFtkZXB0aF0gPSBmYWxzZTsKLSAgICAgICAgICAgIG5hbWVzcGFjZUNvbnRleHQucG9wQ29udGV4dCgpOwotICAgICAgICB9Ci0gICAgICAgIGRlcHRoLS07Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSXMgbm90IHN1cHBvcnRlZCBpbiB0aGlzIGltcGxlbWVudGF0aW9uLgotICAgICAqIEBwYXJhbSBuYW1lIHtAaW5oZXJpdERvY30KLSAgICAgKiBAdGhyb3dzIGphdmF4LnhtbC5zdHJlYW0uWE1MU3RyZWFtRXhjZXB0aW9uIHtAaW5oZXJpdERvY30KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB3cml0ZUVudGl0eVJlZihTdHJpbmcgbmFtZSkgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbiB7Ci0gICAgICAgIEVudGl0eVJlZmVyZW5jZSBlciA9IG93bmVyRG9jLmNyZWF0ZUVudGl0eVJlZmVyZW5jZShuYW1lKTsKLSAgICAgICAgY3VycmVudE5vZGUuYXBwZW5kQ2hpbGQoZXIpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIGNyZWF0ZXMgYSBuYW1lc3BhY2UgYXR0cmlidXRlIGFuZCB3aWxsIGFzc29jaWF0ZSBpdCB3aXRoIHRoZSBjdXJyZW50IGVsZW1lbnQgaW4KLSAgICAgKiB0aGUgRE9NIHRyZWUuCi0gICAgICogQHBhcmFtIHByZWZpeCB7QGluaGVyaXREb2N9Ci0gICAgICogQHBhcmFtIG5hbWVzcGFjZVVSSSB7QGluaGVyaXREb2N9Ci0gICAgICogQHRocm93cyBqYXZheC54bWwuc3RyZWFtLlhNTFN0cmVhbUV4Y2VwdGlvbiB7QGluaGVyaXREb2N9Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgd3JpdGVOYW1lc3BhY2UoU3RyaW5nIHByZWZpeCwgU3RyaW5nIG5hbWVzcGFjZVVSSSkgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgaWYgKHByZWZpeCA9PSBudWxsKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWE1MU3RyZWFtRXhjZXB0aW9uKCJwcmVmaXggY2Fubm90IGJlIG51bGwiKTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChuYW1lc3BhY2VVUkkgPT0gbnVsbCkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFhNTFN0cmVhbUV4Y2VwdGlvbigiTmFtZXNwYWNlVVJJIGNhbm5vdCBiZSBudWxsIik7Ci0gICAgICAgIH0KLQotICAgICAgICBTdHJpbmcgcW5hbWUgPSBudWxsOwotCi0gICAgICAgIGlmIChwcmVmaXguZXF1YWxzKCIiKSkgewotICAgICAgICAgICAgcW5hbWUgPSBYTUxDb25zdGFudHMuWE1MTlNfQVRUUklCVVRFOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgcW5hbWUgPSBnZXRRTmFtZShYTUxDb25zdGFudHMuWE1MTlNfQVRUUklCVVRFLHByZWZpeCk7Ci0gICAgICAgIH0KLQotICAgICAgICAoKEVsZW1lbnQpY3VycmVudE5vZGUpLnNldEF0dHJpYnV0ZU5TKFhNTENvbnN0YW50cy5YTUxOU19BVFRSSUJVVEVfTlNfVVJJLHFuYW1lLCBuYW1lc3BhY2VVUkkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIGlzIG5vdCBzdXBwb3J0ZWQgaW4gdGhpcyByZWxlYXNlLgotICAgICAqIEBwYXJhbSB0YXJnZXQge0Bpbmhlcml0RG9jfQotICAgICAqIEB0aHJvd3MgamF2YXgueG1sLnN0cmVhbS5YTUxTdHJlYW1FeGNlcHRpb24ge0Bpbmhlcml0RG9jfQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHdyaXRlUHJvY2Vzc2luZ0luc3RydWN0aW9uKFN0cmluZyB0YXJnZXQpIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24gewotICAgICAgICBpZih0YXJnZXQgPT0gbnVsbCl7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWE1MU3RyZWFtRXhjZXB0aW9uKCJUYXJnZXQgY2Fubm90IGJlIG51bGwiKTsKLSAgICAgICAgfQotICAgICAgICBQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24gcGkgPSBvd25lckRvYy5jcmVhdGVQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24odGFyZ2V0LCAiIik7Ci0gICAgICAgIGN1cnJlbnROb2RlLmFwcGVuZENoaWxkKHBpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBpcyBub3Qgc3VwcG9ydGVkIGluIHRoaXMgcmVsZWFzZS4KLSAgICAgKiBAcGFyYW0gdGFyZ2V0IHtAaW5oZXJpdERvY30KLSAgICAgKiBAcGFyYW0gZGF0YSB7QGluaGVyaXREb2N9Ci0gICAgICogQHRocm93cyBqYXZheC54bWwuc3RyZWFtLlhNTFN0cmVhbUV4Y2VwdGlvbiB7QGluaGVyaXREb2N9Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgd3JpdGVQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oU3RyaW5nIHRhcmdldCwgU3RyaW5nIGRhdGEpIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24gewotICAgICAgICBpZih0YXJnZXQgPT0gbnVsbCl7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWE1MU3RyZWFtRXhjZXB0aW9uKCJUYXJnZXQgY2Fubm90IGJlIG51bGwiKTsKLSAgICAgICAgfQotICAgICAgICBQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24gcGkgID0gb3duZXJEb2MuY3JlYXRlUHJvY2Vzc2luZ0luc3RydWN0aW9uKHRhcmdldCwgZGF0YSk7Ci0gICAgICAgIGN1cnJlbnROb2RlLmFwcGVuZENoaWxkKHBpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiB3aWxsIHNldCB2ZXJzaW9uIG9uIHRoZSBEb2N1bWVudCBvYmplY3Qgd2hlbiB0aGUgRE9NIE5vZGUgcGFzc2VkIHRvIHRoaXMgaW1wbGVtZW50YXRpb24KLSAgICAgKiBzdXBwb3J0cyBET00gTGV2ZWwzIEFQSSdzLgotICAgICAqIEB0aHJvd3MgamF2YXgueG1sLnN0cmVhbS5YTUxTdHJlYW1FeGNlcHRpb24ge0Bpbmhlcml0RG9jfQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHdyaXRlU3RhcnREb2N1bWVudCgpIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24gewotICAgICAgICB0cnl7Ci0gICAgICAgICAgICBpZihtWG1sVmVyc2lvbiAhPSBudWxsKXsKLSAgICAgICAgICAgICAgICBtWG1sVmVyc2lvbi5pbnZva2Uob3duZXJEb2MsIG5ldyBPYmplY3RbXSB7IjEuMCJ9KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfWNhdGNoKElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gaWFlKXsKLSAgICAgICAgICAgIHRocm93IG5ldyBYTUxTdHJlYW1FeGNlcHRpb24oaWFlKTsKLSAgICAgICAgfWNhdGNoKEludm9jYXRpb25UYXJnZXRFeGNlcHRpb24gaXRlKXsKLSAgICAgICAgICAgIHRocm93IG5ldyBYTUxTdHJlYW1FeGNlcHRpb24oaXRlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIHdpbGwgc2V0IHZlcnNpb24gb24gdGhlIERvY3VtZW50IG9iamVjdCB3aGVuIHRoZSBET00gTm9kZSBwYXNzZWQgdG8gdGhpcyBpbXBsZW1lbnRhdGlvbgotICAgICAqIHN1cHBvcnRzIERPTSBMZXZlbDMgQVBJJ3MuCi0gICAgICogQHBhcmFtIHZlcnNpb24ge0Bpbmhlcml0RG9jfQotICAgICAqIEB0aHJvd3MgamF2YXgueG1sLnN0cmVhbS5YTUxTdHJlYW1FeGNlcHRpb24ge0Bpbmhlcml0RG9jfQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHdyaXRlU3RhcnREb2N1bWVudChTdHJpbmcgdmVyc2lvbikgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbiB7Ci0gICAgICAgIHRyeXsKLSAgICAgICAgICAgIGlmKG1YbWxWZXJzaW9uICE9IG51bGwpewotICAgICAgICAgICAgICAgIG1YbWxWZXJzaW9uLmludm9rZShvd25lckRvYywgbmV3IE9iamVjdFtdIHt2ZXJzaW9ufSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH1jYXRjaChJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIGlhZSl7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWE1MU3RyZWFtRXhjZXB0aW9uKGlhZSk7Ci0gICAgICAgIH1jYXRjaChJbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uIGl0ZSl7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWE1MU3RyZWFtRXhjZXB0aW9uKGl0ZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiB3aWxsIHNldCB2ZXJzaW9uIG9uIHRoZSBEb2N1bWVudCBvYmplY3Qgd2hlbiB0aGUgRE9NIE5vZGUgcGFzc2VkIHRvIHRoaXMgaW1wbGVtZW50YXRpb24KLSAgICAgKiBzdXBwb3J0cyBET00gTGV2ZWwzIEFQSSdzLgotICAgICAqIEBwYXJhbSBlbmNvZGluZyB7QGluaGVyaXREb2N9Ci0gICAgICogQHBhcmFtIHZlcnNpb24ge0Bpbmhlcml0RG9jfQotICAgICAqIEB0aHJvd3MgamF2YXgueG1sLnN0cmVhbS5YTUxTdHJlYW1FeGNlcHRpb24ge0Bpbmhlcml0RG9jfQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHdyaXRlU3RhcnREb2N1bWVudChTdHJpbmcgZW5jb2RpbmcsIFN0cmluZyB2ZXJzaW9uKSB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uIHsKLSAgICAgICAgdHJ5ewotICAgICAgICAgICAgaWYobVhtbFZlcnNpb24gIT0gbnVsbCl7Ci0gICAgICAgICAgICAgICAgbVhtbFZlcnNpb24uaW52b2tlKG93bmVyRG9jLCBuZXcgT2JqZWN0W10ge3ZlcnNpb259KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfWNhdGNoKElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gaWFlKXsKLSAgICAgICAgICAgIHRocm93IG5ldyBYTUxTdHJlYW1FeGNlcHRpb24oaWFlKTsKLSAgICAgICAgfWNhdGNoKEludm9jYXRpb25UYXJnZXRFeGNlcHRpb24gaXRlKXsKLSAgICAgICAgICAgIHRocm93IG5ldyBYTUxTdHJlYW1FeGNlcHRpb24oaXRlKTsKLSAgICAgICAgfQotICAgICAgICAvL1RPRE86IFdoYXQgdG8gZG8gd2l0aCBlbmNvZGluZy4tVmVudQotICAgIH0KLQotICAgIC8qKgotICAgICAqIGNyZWF0ZXMgYSBET00gRWxlbWVudCBhbmQgYXBwZW5kcyBpdCB0byB0aGUgY3VycmVudCBlbGVtZW50IGluIHRoZSB0cmVlLgotICAgICAqIEBwYXJhbSBsb2NhbE5hbWUge0Bpbmhlcml0RG9jfQotICAgICAqIEB0aHJvd3MgamF2YXgueG1sLnN0cmVhbS5YTUxTdHJlYW1FeGNlcHRpb24ge0Bpbmhlcml0RG9jfQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHdyaXRlU3RhcnRFbGVtZW50KFN0cmluZyBsb2NhbE5hbWUpIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24gewotICAgICAgICBpZihvd25lckRvYyAhPSBudWxsKXsKLSAgICAgICAgICAgIEVsZW1lbnQgZWxlbWVudCA9IG93bmVyRG9jLmNyZWF0ZUVsZW1lbnQobG9jYWxOYW1lKTsKLSAgICAgICAgICAgIGlmKGN1cnJlbnROb2RlIT1udWxsKXsKLSAgICAgICAgICAgICAgICBjdXJyZW50Tm9kZS5hcHBlbmRDaGlsZChlbGVtZW50KTsKLSAgICAgICAgICAgIH1lbHNlewotICAgICAgICAgICAgICAgIG93bmVyRG9jLmFwcGVuZENoaWxkKGVsZW1lbnQpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY3VycmVudE5vZGUgPSBlbGVtZW50OwotICAgICAgICB9Ci0gICAgICAgIGlmKG5lZWRDb250ZXh0UG9wW2RlcHRoXSl7Ci0gICAgICAgICAgICBuYW1lc3BhY2VDb250ZXh0LnB1c2hDb250ZXh0KCk7Ci0gICAgICAgIH0KLSAgICAgICAgaW5jRGVwdGgoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBjcmVhdGVzIGEgRE9NIEVsZW1lbnQgYW5kIGFwcGVuZHMgaXQgdG8gdGhlIGN1cnJlbnQgZWxlbWVudCBpbiB0aGUgdHJlZS4KLSAgICAgKiBAcGFyYW0gbmFtZXNwYWNlVVJJIHtAaW5oZXJpdERvY30KLSAgICAgKiBAcGFyYW0gbG9jYWxOYW1lIHtAaW5oZXJpdERvY30KLSAgICAgKiBAdGhyb3dzIGphdmF4LnhtbC5zdHJlYW0uWE1MU3RyZWFtRXhjZXB0aW9uIHtAaW5oZXJpdERvY30KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB3cml0ZVN0YXJ0RWxlbWVudChTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgbG9jYWxOYW1lKSB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uIHsKLSAgICAgICAgaWYob3duZXJEb2MgIT0gbnVsbCl7Ci0gICAgICAgICAgICBTdHJpbmcgcXVhbGlmaWVkTmFtZSA9IG51bGw7Ci0gICAgICAgICAgICBTdHJpbmcgcHJlZml4ID0gbnVsbDsKLQotICAgICAgICAgICAgaWYobmFtZXNwYWNlVVJJID09IG51bGwgKXsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWE1MU3RyZWFtRXhjZXB0aW9uKCJOYW1lc3BhY2VVUkkgY2Fubm90IGJlIG51bGwiKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmKGxvY2FsTmFtZSA9PSBudWxsKXsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWE1MU3RyZWFtRXhjZXB0aW9uKCJMb2NhbCBuYW1lIGNhbm5vdCBiZSBudWxsIik7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmKG5hbWVzcGFjZUNvbnRleHQgIT0gbnVsbCl7Ci0gICAgICAgICAgICAgICAgcHJlZml4ID0gbmFtZXNwYWNlQ29udGV4dC5nZXRQcmVmaXgobmFtZXNwYWNlVVJJKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmKHByZWZpeCA9PSBudWxsKXsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWE1MU3RyZWFtRXhjZXB0aW9uKCJOYW1lc3BhY2UgVVJJICIrbmFtZXNwYWNlVVJJICsKLSAgICAgICAgICAgICAgICAgICAgICAgICJpcyBub3QgYm91bmQgdG8gYW55IHByZWZpeCIgKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmKCIiLmVxdWFscyhwcmVmaXgpKXsKLSAgICAgICAgICAgICAgICBxdWFsaWZpZWROYW1lID0gbG9jYWxOYW1lOwotICAgICAgICAgICAgfWVsc2V7Ci0gICAgICAgICAgICAgICAgcXVhbGlmaWVkTmFtZSA9ICBnZXRRTmFtZShwcmVmaXgsbG9jYWxOYW1lKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgRWxlbWVudCBlbGVtZW50ID0gb3duZXJEb2MuY3JlYXRlRWxlbWVudE5TKG5hbWVzcGFjZVVSSSwgcXVhbGlmaWVkTmFtZSk7Ci0KLSAgICAgICAgICAgIGlmKGN1cnJlbnROb2RlIT1udWxsKXsKLSAgICAgICAgICAgICAgICBjdXJyZW50Tm9kZS5hcHBlbmRDaGlsZChlbGVtZW50KTsKLSAgICAgICAgICAgIH1lbHNlewotICAgICAgICAgICAgICAgIG93bmVyRG9jLmFwcGVuZENoaWxkKGVsZW1lbnQpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY3VycmVudE5vZGUgPSBlbGVtZW50OwotICAgICAgICB9Ci0gICAgICAgIGlmKG5lZWRDb250ZXh0UG9wW2RlcHRoXSl7Ci0gICAgICAgICAgICBuYW1lc3BhY2VDb250ZXh0LnB1c2hDb250ZXh0KCk7Ci0gICAgICAgIH0KLSAgICAgICAgaW5jRGVwdGgoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBjcmVhdGVzIGEgRE9NIEVsZW1lbnQgYW5kIGFwcGVuZHMgaXQgdG8gdGhlIGN1cnJlbnQgZWxlbWVudCBpbiB0aGUgdHJlZS4KLSAgICAgKiBAcGFyYW0gcHJlZml4IHtAaW5oZXJpdERvY30KLSAgICAgKiBAcGFyYW0gbG9jYWxOYW1lIHtAaW5oZXJpdERvY30KLSAgICAgKiBAcGFyYW0gbmFtZXNwYWNlVVJJIHtAaW5oZXJpdERvY30KLSAgICAgKiBAdGhyb3dzIGphdmF4LnhtbC5zdHJlYW0uWE1MU3RyZWFtRXhjZXB0aW9uIHtAaW5oZXJpdERvY30KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB3cml0ZVN0YXJ0RWxlbWVudChTdHJpbmcgcHJlZml4LCBTdHJpbmcgbG9jYWxOYW1lLCBTdHJpbmcgbmFtZXNwYWNlVVJJKSB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uIHsKLQotICAgICAgICBpZihvd25lckRvYyAhPSBudWxsKXsKLSAgICAgICAgICAgIFN0cmluZyBxbmFtZSA9IG51bGw7Ci0gICAgICAgICAgICBpZihuYW1lc3BhY2VVUkkgPT0gbnVsbCApewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBYTUxTdHJlYW1FeGNlcHRpb24oIk5hbWVzcGFjZVVSSSBjYW5ub3QgYmUgbnVsbCIpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYobG9jYWxOYW1lID09IG51bGwpewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBYTUxTdHJlYW1FeGNlcHRpb24oIkxvY2FsIG5hbWUgY2Fubm90IGJlIG51bGwiKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmKHByZWZpeCA9PSBudWxsKXsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWE1MU3RyZWFtRXhjZXB0aW9uKCJQcmVmaXggY2Fubm90IGJlIG51bGwiKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYocHJlZml4LmVxdWFscygiIikpewotICAgICAgICAgICAgICAgIHFuYW1lID0gbG9jYWxOYW1lOwotICAgICAgICAgICAgfWVsc2V7Ci0gICAgICAgICAgICAgICAgcW5hbWUgPSBnZXRRTmFtZShwcmVmaXgsbG9jYWxOYW1lKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgRWxlbWVudCBlbCA9IG93bmVyRG9jLmNyZWF0ZUVsZW1lbnROUyhuYW1lc3BhY2VVUkkscW5hbWUpOwotCi0gICAgICAgICAgICBpZihjdXJyZW50Tm9kZSE9bnVsbCl7Ci0gICAgICAgICAgICAgICAgY3VycmVudE5vZGUuYXBwZW5kQ2hpbGQoZWwpOwotICAgICAgICAgICAgfWVsc2V7Ci0gICAgICAgICAgICAgICAgb3duZXJEb2MuYXBwZW5kQ2hpbGQoZWwpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY3VycmVudE5vZGUgPSBlbDsKLSAgICAgICAgICAgIGlmKG5lZWRDb250ZXh0UG9wW2RlcHRoXSl7Ci0gICAgICAgICAgICAgICAgbmFtZXNwYWNlQ29udGV4dC5wdXNoQ29udGV4dCgpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaW5jRGVwdGgoKTsKLQotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBTdHJpbmcgZ2V0UU5hbWUoU3RyaW5nIHByZWZpeCAsIFN0cmluZyBsb2NhbE5hbWUpewotICAgICAgICBzdHJpbmdCdWZmZXIuc2V0TGVuZ3RoKDApOwotICAgICAgICBzdHJpbmdCdWZmZXIuYXBwZW5kKHByZWZpeCk7Ci0gICAgICAgIHN0cmluZ0J1ZmZlci5hcHBlbmQoIjoiKTsKLSAgICAgICAgc3RyaW5nQnVmZmVyLmFwcGVuZChsb2NhbE5hbWUpOwotICAgICAgICByZXR1cm4gc3RyaW5nQnVmZmVyLnRvU3RyaW5nKCk7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBOb2RlIGdldE5vZGUoKXsKLSAgICAgICAgaWYoY3VycmVudE5vZGUgPT0gbnVsbCl7Ci0gICAgICAgICAgICByZXR1cm4gb3duZXJEb2M7Ci0gICAgICAgIH0gZWxzZXsKLSAgICAgICAgICAgIHJldHVybiBjdXJyZW50Tm9kZTsKLSAgICAgICAgfQotICAgIH0KLSAgICBwcml2YXRlIHZvaWQgaW5jRGVwdGgoKSB7Ci0gICAgICAgIGRlcHRoKys7Ci0gICAgICAgIGlmIChkZXB0aCA9PSBuZWVkQ29udGV4dFBvcC5sZW5ndGgpIHsKLSAgICAgICAgICAgIGJvb2xlYW5bXSBhcnJheSA9IG5ldyBib29sZWFuW2RlcHRoICsgcmVzaXplVmFsdWVdOwotICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShuZWVkQ29udGV4dFBvcCwgMCwgYXJyYXksIDAsIGRlcHRoKTsKLSAgICAgICAgICAgIG5lZWRDb250ZXh0UG9wID0gYXJyYXk7Ci0gICAgICAgIH0KLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL3dyaXRlcnMvWE1MRXZlbnRXcml0ZXJJbXBsLmphdmEgYi9zcmMvY29tL3N1bi94bWwvaW50ZXJuYWwvc3RyZWFtL3dyaXRlcnMvWE1MRXZlbnRXcml0ZXJJbXBsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDhhY2JkMzIuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4veG1sL2ludGVybmFsL3N0cmVhbS93cml0ZXJzL1hNTEV2ZW50V3JpdGVySW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjYxICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMDYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi54bWwuaW50ZXJuYWwuc3RyZWFtLndyaXRlcnM7Ci0KLWltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7Ci1pbXBvcnQgamF2YXgueG1sLm5hbWVzcGFjZS5RTmFtZTsKLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLlhNTEV2ZW50V3JpdGVyOwotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uWE1MU3RyZWFtRXhjZXB0aW9uOwotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uZXZlbnRzLkF0dHJpYnV0ZTsKLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLmV2ZW50cy5DaGFyYWN0ZXJzOwotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uZXZlbnRzLkNvbW1lbnQ7Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5ldmVudHMuRFREOwotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uZXZlbnRzLkVudGl0eVJlZmVyZW5jZTsKLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLmV2ZW50cy5OYW1lc3BhY2U7Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5ldmVudHMuUHJvY2Vzc2luZ0luc3RydWN0aW9uOwotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uZXZlbnRzLlN0YXJ0RG9jdW1lbnQ7Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5ldmVudHMuU3RhcnRFbGVtZW50OwotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uZXZlbnRzLlhNTEV2ZW50OwotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uWE1MU3RyZWFtV3JpdGVyOwotCi0vKioKLSAqCi0gKiBAYXV0aG9yICBOZWVyYWogQmFqYWosIFN1biBNaWNyb3N5c3RlbXMuCi0gKgotICovCi1wdWJsaWMgY2xhc3MgWE1MRXZlbnRXcml0ZXJJbXBsIGltcGxlbWVudHMgWE1MRXZlbnRXcml0ZXJ7Ci0KLSAgICAvL2RlbGVnYXRlIGV2ZXJ5dGhpbmcgdG8gWE1MU3RyZWFtV3JpdGVyLi4KLSAgICBwcml2YXRlIFhNTFN0cmVhbVdyaXRlciBmU3RyZWFtV3JpdGVyIDsKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIERFQlVHID0gZmFsc2U7Ci0gICAgLyoqCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc3RyZWFtV3JpdGVyCi0gICAgICovCi0gICAgcHVibGljIFhNTEV2ZW50V3JpdGVySW1wbChYTUxTdHJlYW1Xcml0ZXIgc3RyZWFtV3JpdGVyKXsKLSAgICAgICAgZlN0cmVhbVdyaXRlciA9IHN0cmVhbVdyaXRlcjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKgotICAgICAqIEBwYXJhbSB4TUxFdmVudFJlYWRlcgotICAgICAqIEB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgYWRkKGphdmF4LnhtbC5zdHJlYW0uWE1MRXZlbnRSZWFkZXIgeE1MRXZlbnRSZWFkZXIpIHRocm93cyBqYXZheC54bWwuc3RyZWFtLlhNTFN0cmVhbUV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmKHhNTEV2ZW50UmVhZGVyID09IG51bGwpIHRocm93IG5ldyBYTUxTdHJlYW1FeGNlcHRpb24oIkV2ZW50IHJlYWRlciBzaG91bGRuJ3QgYmUgbnVsbCIpOwotICAgICAgICB3aGlsZSh4TUxFdmVudFJlYWRlci5oYXNOZXh0KCkpewotICAgICAgICAgICAgYWRkKHhNTEV2ZW50UmVhZGVyLm5leHRFdmVudCgpKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqCi0gICAgICogQHBhcmFtIHhNTEV2ZW50Ci0gICAgICogQHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBhZGQoamF2YXgueG1sLnN0cmVhbS5ldmVudHMuWE1MRXZlbnQgeE1MRXZlbnQpIHRocm93cyBqYXZheC54bWwuc3RyZWFtLlhNTFN0cmVhbUV4Y2VwdGlvbiB7Ci0gICAgICAgIGludCB0eXBlID0geE1MRXZlbnQuZ2V0RXZlbnRUeXBlKCk7Ci0gICAgICAgIHN3aXRjaCh0eXBlKXsKLSAgICAgICAgICAgIGNhc2UgWE1MRXZlbnQuRFREOnsKLSAgICAgICAgICAgICAgICBEVEQgZHRkID0gKERURCl4TUxFdmVudCA7Ci0gICAgICAgICAgICAgICAgaWYgKERFQlVHKVN5c3RlbS5vdXQucHJpbnRsbigiQWRkaW5nIERURCA9ICIgKyBkdGQudG9TdHJpbmcoKSk7Ci0gICAgICAgICAgICAgICAgZlN0cmVhbVdyaXRlci53cml0ZURURChkdGQuZ2V0RG9jdW1lbnRUeXBlRGVjbGFyYXRpb24oKSk7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXNlIFhNTEV2ZW50LlNUQVJUX0RPQ1VNRU5UIDp7Ci0gICAgICAgICAgICAgICAgU3RhcnREb2N1bWVudCBzdGFydERvY3VtZW50ID0gKFN0YXJ0RG9jdW1lbnQpeE1MRXZlbnQgOwotICAgICAgICAgICAgICAgIGlmIChERUJVRylTeXN0ZW0ub3V0LnByaW50bG4oIkFkZGluZyBTdGFydERvY3VtZW50ID0gIiArIHN0YXJ0RG9jdW1lbnQudG9TdHJpbmcoKSk7Ci0gICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICBmU3RyZWFtV3JpdGVyLndyaXRlU3RhcnREb2N1bWVudChzdGFydERvY3VtZW50LmdldENoYXJhY3RlckVuY29kaW5nU2NoZW1lKCksIHN0YXJ0RG9jdW1lbnQuZ2V0VmVyc2lvbigpKTsKLSAgICAgICAgICAgICAgICB9Y2F0Y2goWE1MU3RyZWFtRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICAgICAgZlN0cmVhbVdyaXRlci53cml0ZVN0YXJ0RG9jdW1lbnQoc3RhcnREb2N1bWVudC5nZXRWZXJzaW9uKCkpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhc2UgWE1MRXZlbnQuU1RBUlRfRUxFTUVOVCA6ewotICAgICAgICAgICAgICAgIFN0YXJ0RWxlbWVudCBzdGFydEVsZW1lbnQgPSB4TUxFdmVudC5hc1N0YXJ0RWxlbWVudCgpIDsKLSAgICAgICAgICAgICAgICBpZiAoREVCVUcpU3lzdGVtLm91dC5wcmludGxuKCJBZGRpbmcgc3RhcnRlbGVtZW50ID0gIiArIHN0YXJ0RWxlbWVudC50b1N0cmluZygpKTsKLSAgICAgICAgICAgICAgICBRTmFtZSBxbmFtZSA9IHN0YXJ0RWxlbWVudC5nZXROYW1lKCk7Ci0gICAgICAgICAgICAgICAgZlN0cmVhbVdyaXRlci53cml0ZVN0YXJ0RWxlbWVudChxbmFtZS5nZXRQcmVmaXgoKSwgcW5hbWUuZ2V0TG9jYWxQYXJ0KCksIHFuYW1lLmdldE5hbWVzcGFjZVVSSSgpKTsKLQotICAgICAgICAgICAgICAgIC8vZ2V0TmFtZXNwYWNlcygpIFJldHVybnMgYW4gSXRlcmF0b3Igb2YgbmFtZXNwYWNlcyBkZWNsYXJlZCBvbiB0aGlzIGVsZW1lbnQuIFRoaXMgSXRlcmF0b3IgZG9lcyBub3QgY29udGFpbgotICAgICAgICAgICAgICAgIC8vcHJldmlvdXNseSBkZWNsYXJlZCBuYW1lc3BhY2VzIHVubGVzcyB0aGV5IGFwcGVhciBvbiB0aGUgY3VycmVudCBTVEFSVF9FTEVNRU5ULiBUaGVyZWZvcmUKLSAgICAgICAgICAgICAgICAvL3RoaXMgbGlzdCBtYXkgY29udGFpbiByZWRlY2xhcmVkIG5hbWVzcGFjZXMgYW5kIGR1cGxpY2F0ZSBuYW1lc3BhY2UgZGVjbGFyYXRpb25zLiBVc2UgdGhlCi0gICAgICAgICAgICAgICAgLy9nZXROYW1lc3BhY2VDb250ZXh0KCkgbWV0aG9kIHRvIGdldCB0aGUgY3VycmVudCBjb250ZXh0IG9mIG5hbWVzcGFjZSBkZWNsYXJhdGlvbnMuCi0KLSAgICAgICAgICAgICAgICAvL3NvIHdlIHNob3VsZCBiZSB1c2luZyBnZXROYW1lc3BhY2VzKCkgdG8gd3JpdGUgbmFtZXNwYWNlIGRlY2xhcmF0aW9ucyBmb3IgdGhpcyBTVEFSVF9FTEVNRU5UCi0gICAgICAgICAgICAgICAgSXRlcmF0b3IgaXRlcmF0b3IgPSBzdGFydEVsZW1lbnQuZ2V0TmFtZXNwYWNlcygpOwotICAgICAgICAgICAgICAgIHdoaWxlKGl0ZXJhdG9yLmhhc05leHQoKSl7Ci0gICAgICAgICAgICAgICAgICAgIE5hbWVzcGFjZSBuYW1lc3BhY2UgPSAoTmFtZXNwYWNlKWl0ZXJhdG9yLm5leHQoKTsKLSAgICAgICAgICAgICAgICAgICAgZlN0cmVhbVdyaXRlci53cml0ZU5hbWVzcGFjZShuYW1lc3BhY2UuZ2V0UHJlZml4KCksIG5hbWVzcGFjZS5nZXROYW1lc3BhY2VVUkkoKSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIC8vUkVWSVNJVDogV2hhdCBhYm91dCB3cml0aW5nIGF0dHJpYnV0ZXMgPwotICAgICAgICAgICAgICAgIEl0ZXJhdG9yIGF0dHJpYnV0ZXMgPSBzdGFydEVsZW1lbnQuZ2V0QXR0cmlidXRlcygpOwotICAgICAgICAgICAgICAgIHdoaWxlKGF0dHJpYnV0ZXMuaGFzTmV4dCgpKXsKLSAgICAgICAgICAgICAgICAgICAgQXR0cmlidXRlIGF0dHJpYnV0ZSA9IChBdHRyaWJ1dGUpYXR0cmlidXRlcy5uZXh0KCk7Ci0gICAgICAgICAgICAgICAgICAgIFFOYW1lIGFxbmFtZSA9IGF0dHJpYnV0ZS5nZXROYW1lKCk7Ci0gICAgICAgICAgICAgICAgICAgIGZTdHJlYW1Xcml0ZXIud3JpdGVBdHRyaWJ1dGUoYXFuYW1lLmdldFByZWZpeCgpLCBhcW5hbWUuZ2V0TmFtZXNwYWNlVVJJKCksIGFxbmFtZS5nZXRMb2NhbFBhcnQoKSxhdHRyaWJ1dGUuZ2V0VmFsdWUoKSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2FzZSBYTUxFdmVudC5OQU1FU1BBQ0U6ewotICAgICAgICAgICAgICAgIE5hbWVzcGFjZSBuYW1lc3BhY2UgPSAoTmFtZXNwYWNlKXhNTEV2ZW50OwotICAgICAgICAgICAgICAgIGlmIChERUJVRylTeXN0ZW0ub3V0LnByaW50bG4oIkFkZGluZyBuYW1lc3BhY2UgPSAiICsgbmFtZXNwYWNlLnRvU3RyaW5nKCkpOwotICAgICAgICAgICAgICAgIGZTdHJlYW1Xcml0ZXIud3JpdGVOYW1lc3BhY2UobmFtZXNwYWNlLmdldFByZWZpeCgpLCBuYW1lc3BhY2UuZ2V0TmFtZXNwYWNlVVJJKCkpOwotICAgICAgICAgICAgICAgIGJyZWFrIDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhc2UgWE1MRXZlbnQuQ09NTUVOVDogewotICAgICAgICAgICAgICAgIENvbW1lbnQgY29tbWVudCA9IChDb21tZW50KXhNTEV2ZW50IDsKLSAgICAgICAgICAgICAgICBpZiAoREVCVUcpU3lzdGVtLm91dC5wcmludGxuKCJBZGRpbmcgY29tbWVudCA9ICIgKyBjb21tZW50LnRvU3RyaW5nKCkpOwotICAgICAgICAgICAgICAgIGZTdHJlYW1Xcml0ZXIud3JpdGVDb21tZW50KGNvbW1lbnQuZ2V0VGV4dCgpKTsKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhc2UgWE1MRXZlbnQuUFJPQ0VTU0lOR19JTlNUUlVDVElPTjp7Ci0gICAgICAgICAgICAgICAgUHJvY2Vzc2luZ0luc3RydWN0aW9uIHByb2Nlc3NpbmdJbnN0cnVjdGlvbiA9IChQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24peE1MRXZlbnQgOwotICAgICAgICAgICAgICAgIGlmIChERUJVRylTeXN0ZW0ub3V0LnByaW50bG4oIkFkZGluZyBwcm9jZXNzaW5nIGluc3RydWN0aW9uID0gIiArIHByb2Nlc3NpbmdJbnN0cnVjdGlvbi50b1N0cmluZygpKTsKLSAgICAgICAgICAgICAgICBmU3RyZWFtV3JpdGVyLndyaXRlUHJvY2Vzc2luZ0luc3RydWN0aW9uKHByb2Nlc3NpbmdJbnN0cnVjdGlvbi5nZXRUYXJnZXQoKSwgcHJvY2Vzc2luZ0luc3RydWN0aW9uLmdldERhdGEoKSk7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXNlIFhNTEV2ZW50LkNIQVJBQ1RFUlM6ewotICAgICAgICAgICAgICAgIENoYXJhY3RlcnMgY2hhcmFjdGVycyA9IHhNTEV2ZW50LmFzQ2hhcmFjdGVycygpOwotICAgICAgICAgICAgICAgIGlmIChERUJVRylTeXN0ZW0ub3V0LnByaW50bG4oIkFkZGluZyBjaGFyYWN0ZXJzID0gIiArIGNoYXJhY3RlcnMudG9TdHJpbmcoKSk7Ci0gICAgICAgICAgICAgICAgLy9jaGVjayBpZiB0aGUgQ0hBUkFDVEVSUyBhcmUgQ0RBVEEKLSAgICAgICAgICAgICAgICBpZihjaGFyYWN0ZXJzLmlzQ0RhdGEoKSl7Ci0gICAgICAgICAgICAgICAgICAgIGZTdHJlYW1Xcml0ZXIud3JpdGVDRGF0YShjaGFyYWN0ZXJzLmdldERhdGEoKSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2V7Ci0gICAgICAgICAgICAgICAgICAgIGZTdHJlYW1Xcml0ZXIud3JpdGVDaGFyYWN0ZXJzKGNoYXJhY3RlcnMuZ2V0RGF0YSgpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXNlIFhNTEV2ZW50LkVOVElUWV9SRUZFUkVOQ0U6ewotICAgICAgICAgICAgICAgIEVudGl0eVJlZmVyZW5jZSBlbnRpdHlSZWZlcmVuY2UgPSAoRW50aXR5UmVmZXJlbmNlKXhNTEV2ZW50IDsKLSAgICAgICAgICAgICAgICBpZiAoREVCVUcpU3lzdGVtLm91dC5wcmludGxuKCJBZGRpbmcgRW50aXR5IFJlZmVyZW5jZSA9ICIrIGVudGl0eVJlZmVyZW5jZS50b1N0cmluZygpKTsKLSAgICAgICAgICAgICAgICBmU3RyZWFtV3JpdGVyLndyaXRlRW50aXR5UmVmKGVudGl0eVJlZmVyZW5jZS5nZXROYW1lKCkpOwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2FzZSBYTUxFdmVudC5BVFRSSUJVVEU6ewotICAgICAgICAgICAgICAgIEF0dHJpYnV0ZSBhdHRyaWJ1dGUgPSAoQXR0cmlidXRlKXhNTEV2ZW50OwotICAgICAgICAgICAgICAgIGlmIChERUJVRylTeXN0ZW0ub3V0LnByaW50bG4oIkFkZGluZyBBdHRyaWJ1dGUgPSAiICsgYXR0cmlidXRlLnRvU3RyaW5nKCkpOwotICAgICAgICAgICAgICAgIFFOYW1lIHFuYW1lID0gYXR0cmlidXRlLmdldE5hbWUoKTsKLSAgICAgICAgICAgICAgICBmU3RyZWFtV3JpdGVyLndyaXRlQXR0cmlidXRlKHFuYW1lLmdldFByZWZpeCgpLCBxbmFtZS5nZXROYW1lc3BhY2VVUkkoKSwgcW5hbWUuZ2V0TG9jYWxQYXJ0KCksYXR0cmlidXRlLmdldFZhbHVlKCkpOwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2FzZSBYTUxFdmVudC5DREFUQTp7Ci0gICAgICAgICAgICAgICAgLy90aGVyZSBpcyBubyBzZXBhcmF0ZSBDREFUQSBkYXRhdHlwZSBidXQgQ0RBVEEgZXZlbnQgY2FuIGJlIHJlcG9ydGVkCi0gICAgICAgICAgICAgICAgLy9ieSB1c2luZyB2ZW5kb3Igc3BlY2lmaWMgQ0RBVEEgcHJvcGVydHkuCi0gICAgICAgICAgICAgICAgQ2hhcmFjdGVycyBjaGFyYWN0ZXJzID0gKENoYXJhY3RlcnMpeE1MRXZlbnQ7Ci0gICAgICAgICAgICAgICAgaWYgKERFQlVHKVN5c3RlbS5vdXQucHJpbnRsbigiQWRkaW5nIGNoYXJhY3RlcnMgPSAiICsgY2hhcmFjdGVycy50b1N0cmluZygpKTsKLSAgICAgICAgICAgICAgICBpZihjaGFyYWN0ZXJzLmlzQ0RhdGEoKSl7Ci0gICAgICAgICAgICAgICAgICAgIGZTdHJlYW1Xcml0ZXIud3JpdGVDRGF0YShjaGFyYWN0ZXJzLmdldERhdGEoKSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy94eHg6IFdoeSB0aGVyZSBpc24ndCBhbnkgZXZlbnQgY2FsbGVkIE5vdGF0aW9uLgotICAgICAgICAgICAgLy9jYXNlIFhNTEV2ZW50Lk5PVEFUSU9OX0RFQ0xBUkFUSU9OOnsKLSAgICAgICAgICAgIC8vfQotCi0gICAgICAgICAgICBjYXNlIFhNTEV2ZW50LkVORF9FTEVNRU5UOnsKLSAgICAgICAgICAgICAgICAvL3dlIGRvbnQgbmVlZCB0byB0eXBlY2FzdCBpdC4uIGp1c3QgY2FsbCB3cml0ZUVuZEVsZW1lbnQoKSBhbmQgZlN0cmVhbVdyaXRlciB3aWxsIHRha2UgY2FyZSBvZiBpdC4KLSAgICAgICAgICAgICAgICAvL0VuZEVsZW1lbnQgZW5kRWxlbWVudCA9IChFbmRFbGVtZW50KXhNTEV2ZW50OwotICAgICAgICAgICAgICAgIGZTdHJlYW1Xcml0ZXIud3JpdGVFbmRFbGVtZW50KCk7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXNlIFhNTEV2ZW50LkVORF9ET0NVTUVOVDp7Ci0gICAgICAgICAgICAgICAgLy93ZSBkb250IG5lZWQgdG8gdHlwZWNhc3QganVzdCBjYWxsIHdyaXRlRW5kRG9jdW1lbnQoKSBhbmQgZlN0cmVhbVdyaXRlciB3aWxsIHRha2UgY2FyZSByZXN0LgotICAgICAgICAgICAgICAgIC8vRW5kRG9jdW1lbnQgZW5kRG9jdW1lbnQgPSAoRW5kRG9jdW1lbnQpeE1MRXZlbnQ7Ci0gICAgICAgICAgICAgICAgZlN0cmVhbVdyaXRlci53cml0ZUVuZERvY3VtZW50KCk7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvL3Rocm93IG5ldyBYTUxTdHJlYW1FeGNlcHRpb24oIlVua25vd24gRXZlbnQgdHlwZSA9ICIgKyB0eXBlKTsKLSAgICAgICAgfTsKLQotICAgIH0KLQotICAgIC8qKgotICAgICAqCi0gICAgICogQHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBqYXZheC54bWwuc3RyZWFtLlhNTFN0cmVhbUV4Y2VwdGlvbiB7Ci0gICAgICAgIGZTdHJlYW1Xcml0ZXIuY2xvc2UoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uIHdpbGwgaW50dXJuIGNhbGwgZmx1c2ggb24gdGhlIHN0cmVhbSB0byB3aGljaCBkYXRhIGlzIGJlaW5nCi0gICAgICogd3JpdHRlbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBmbHVzaCgpIHRocm93cyBqYXZheC54bWwuc3RyZWFtLlhNTFN0cmVhbUV4Y2VwdGlvbiB7Ci0gICAgICAgIGZTdHJlYW1Xcml0ZXIuZmx1c2goKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKgotICAgICAqIEByZXR1cm4KLSAgICAgKi8KLSAgICBwdWJsaWMgamF2YXgueG1sLm5hbWVzcGFjZS5OYW1lc3BhY2VDb250ZXh0IGdldE5hbWVzcGFjZUNvbnRleHQoKSB7Ci0gICAgICAgIHJldHVybiBmU3RyZWFtV3JpdGVyLmdldE5hbWVzcGFjZUNvbnRleHQoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkgTmFtZXNwYWNlIFVSSQotICAgICAqIEB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uCi0gICAgICogQHJldHVybiBwcmVmaXggYXNzb2NpYXRlZCB3aXRoIHRoZSBVUkkuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRQcmVmaXgoU3RyaW5nIG5hbWVzcGFjZVVSSSkgdGhyb3dzIGphdmF4LnhtbC5zdHJlYW0uWE1MU3RyZWFtRXhjZXB0aW9uIHsKLSAgICAgICAgcmV0dXJuIGZTdHJlYW1Xcml0ZXIuZ2V0UHJlZml4KG5hbWVzcGFjZVVSSSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdXJpIE5hbWVzcGFjZSBVUkkKLSAgICAgKiBAdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldERlZmF1bHROYW1lc3BhY2UoU3RyaW5nIHVyaSkgdGhyb3dzIGphdmF4LnhtbC5zdHJlYW0uWE1MU3RyZWFtRXhjZXB0aW9uIHsKLSAgICAgICAgZlN0cmVhbVdyaXRlci5zZXREZWZhdWx0TmFtZXNwYWNlKHVyaSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZXNwYWNlQ29udGV4dCBOYW1lc3BhY2UgQ29udGV4dAotICAgICAqIEB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0TmFtZXNwYWNlQ29udGV4dChqYXZheC54bWwubmFtZXNwYWNlLk5hbWVzcGFjZUNvbnRleHQgbmFtZXNwYWNlQ29udGV4dCkgdGhyb3dzIGphdmF4LnhtbC5zdHJlYW0uWE1MU3RyZWFtRXhjZXB0aW9uIHsKLSAgICAgICAgZlN0cmVhbVdyaXRlci5zZXROYW1lc3BhY2VDb250ZXh0KG5hbWVzcGFjZUNvbnRleHQpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqCi0gICAgICogQHBhcmFtIHByZWZpeCBuYW1lc3BhY2UgcHJlZml4IGFzc29jaWF0ZWQgd2l0aCB0aGUgdXJpLgotICAgICAqIEBwYXJhbSB1cmkgTmFtZXNwYWNlIFVSSQotICAgICAqIEB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0UHJlZml4KFN0cmluZyBwcmVmaXgsIFN0cmluZyB1cmkpIHRocm93cyBqYXZheC54bWwuc3RyZWFtLlhNTFN0cmVhbUV4Y2VwdGlvbiB7Ci0gICAgICAgIGZTdHJlYW1Xcml0ZXIuc2V0UHJlZml4KHByZWZpeCwgdXJpKTsKLSAgICB9Ci0KLX0vL1hNTEV2ZW50V3JpdGVySW1wbApkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4veG1sL2ludGVybmFsL3N0cmVhbS93cml0ZXJzL1hNTE91dHB1dFNvdXJjZS5qYXZhIGIvc3JjL2NvbS9zdW4veG1sL2ludGVybmFsL3N0cmVhbS93cml0ZXJzL1hNTE91dHB1dFNvdXJjZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1YTJjNTVhLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL3htbC9pbnRlcm5hbC9zdHJlYW0vd3JpdGVycy9YTUxPdXRwdXRTb3VyY2UuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQ1ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLXBhY2thZ2UgY29tLnN1bi54bWwuaW50ZXJuYWwuc3RyZWFtLndyaXRlcnM7Ci0KLWltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKLWltcG9ydCBqYXZhLmlvLldyaXRlcjsKLQotLyoqCi0gKiBYTUxPdXRwdXRTb3VyY2UuCi0gKgotICogRW5jYXB1c2xhdGVzIHRoZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgc291cmNlIHdoZXJlCi0gKiBYTUwgb3V0cHV0IG5lZWRzIHRvIGJlIHdyaXR0ZW4uCi0gKgotICogQGF1dGhvciBOZWVyYWogQmFqYWoKLSAqLwotcHVibGljIGNsYXNzIFhNTE91dHB1dFNvdXJjZSB7Ci0KLSAgICAvKiogQ3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiBYTUxPdXRwdXRTb3VyY2UgKi8KLSAgICBwdWJsaWMgWE1MT3V0cHV0U291cmNlKCkgewotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4veG1sL2ludGVybmFsL3N0cmVhbS93cml0ZXJzL1hNTFN0cmVhbVdyaXRlckltcGwuamF2YSBiL3NyYy9jb20vc3VuL3htbC9pbnRlcm5hbC9zdHJlYW0vd3JpdGVycy9YTUxTdHJlYW1Xcml0ZXJJbXBsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGYzYjliNTAuLjAwMDAwMDAKLS0tIGEvc3JjL2NvbS9zdW4veG1sL2ludGVybmFsL3N0cmVhbS93cml0ZXJzL1hNTFN0cmVhbVdyaXRlckltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIyMDYgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLnhtbC5pbnRlcm5hbC5zdHJlYW0ud3JpdGVyczsKLQotaW1wb3J0IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbTsKLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtV3JpdGVyOwotaW1wb3J0IGphdmEuaW8uV3JpdGVyOwotaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuQ2hhcnNldDsKLWltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXRFbmNvZGVyOwotaW1wb3J0IGphdmEudXRpbC5BYnN0cmFjdE1hcDsKLWltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwotaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwotaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKLWltcG9ydCBqYXZhLnV0aWwuUmFuZG9tOwotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci1pbXBvcnQgamF2YS51dGlsLlNldDsKLWltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7Ci0KLWltcG9ydCBqYXZheC54bWwuWE1MQ29uc3RhbnRzOwotaW1wb3J0IGphdmF4LnhtbC5uYW1lc3BhY2UuTmFtZXNwYWNlQ29udGV4dDsKLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLlhNTE91dHB1dEZhY3Rvcnk7Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5YTUxTdHJlYW1Db25zdGFudHM7Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5YTUxTdHJlYW1FeGNlcHRpb247Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5YTUxTdHJlYW1Xcml0ZXI7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zdHJlYW0uU3RyZWFtUmVzdWx0OwotCi1pbXBvcnQgY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLkNvbnN0YW50czsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuUHJvcGVydHlNYW5hZ2VyOwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5OYW1lc3BhY2VTdXBwb3J0OwotaW1wb3J0IGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwudXRpbC5TeW1ib2xUYWJsZTsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWxzLlNlY3VyaXR5U3VwcG9ydDsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5RTmFtZTsKLQotaW1wb3J0IGNvbS5zdW4ueG1sLmludGVybmFsLnN0cmVhbS51dGlsLlJlYWRPbmx5SXRlcmF0b3I7Ci0KLS8qKgotICogVGhpcyBjbGFzcyBpbXBsZW1lbnRzIGEgU3RBWCBYTUxTdHJlYW1Xcml0ZXIuIEl0IGV4dGVuZHMKLSAqIDxjb2RlPkFic3RyYWN0TWFwPC9jb2RlPiBpbiBvcmRlciB0byBzdXBwb3J0IGEgZ2V0dGVyIGZvcgotICogaW1wbGVtZW50YXRpb24tc3BlY2lmaWMgcHJvcGVydGllcy4gRm9yIGV4YW1wbGUsIHlvdSBjYW4gZ2V0Ci0gKiB0aGUgdW5kZXJseWluZyA8Y29kZT5PdXRwdXRTdHJlYW08L2NvZGU+IGJ5IGNhc3RpbmcgYW4gaW5zdGFuY2UKLSAqIG9mIHRoaXMgY2xhc3MgdG8gPGNvZGU+TWFwPC9jb2RlPiBhbmQgY2FsbGluZwotICogPGNvZGU+Z2V0UHJvcGVydHkoT1VUUFVUU1RSRUFNX1BST1BFUlRZKTwvY29kZT4uCi0gKgotICogQGF1dGhvciBOZWVyYWogQmFqYWoKLSAqIEBhdXRob3IgSy5WZW51Z29wYWwKLSAqIEBhdXRob3IgU2FudGlhZ28uUGVyaWNhcy1HZWVydHNlbkBzdW4uY29tCi0gKiBAYXV0aG9yIFN1bml0aGEuUmVkZHlAc3VuLmNvbQotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgWE1MU3RyZWFtV3JpdGVySW1wbCBleHRlbmRzIEFic3RyYWN0TWFwIGltcGxlbWVudHMgWE1MU3RyZWFtV3JpdGVyIHsKLQotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFNUQVJUX0NPTU1FTlQgPSAiPCEtLSI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRU5EX0NPTU1FTlQgPSAiLS0+IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBERUZBVUxUX0VOQ09ESU5HID0gIiBlbmNvZGluZz1cInV0Zi04XCIiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIERFRkFVTFRfWE1MREVDTCA9ICI8P3htbCB2ZXJzaW9uPVwiMS4wXCIgPz4iOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIERFRkFVTFRfWE1MX1ZFUlNJT04gPSAiMS4wIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNoYXIgQ0xPU0VfU1RBUlRfVEFHID0gJz4nOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2hhciBPUEVOX1NUQVJUX1RBRyA9ICc8JzsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBPUEVOX0VORF9UQUcgPSAiPC8iOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2hhciBDTE9TRV9FTkRfVEFHID0gJz4nOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFNUQVJUX0NEQVRBID0gIjwhW0NEQVRBWyI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRU5EX0NEQVRBID0gIl1dPiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ0xPU0VfRU1QVFlfRUxFTUVOVCA9ICIvPiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1BBQ0UgPSAiICI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgVVRGXzggPSAiVVRGLTgiOwotCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgT1VUUFVUU1RSRUFNX1BST1BFUlRZID0gInNqc3hwLW91dHB1dHN0cmVhbSI7Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIGZsYWcgY2FuIGJlIHVzZWQgdG8gdHVybiBlc2NhcGluZyBvZmYgZm9yIGNvbnRlbnQuIEl0IGRvZXMKLSAgICAgKiBub3QgYXBwbHkgdG8gYXR0cmlidXRlIGNvbnRlbnQuCi0gICAgICovCi0gICAgYm9vbGVhbiBmRXNjYXBlQ2hhcmFjdGVycyA9IHRydWU7Ci0KLSAgICAvKioKLSAgICAgKiBGbGFnIGZvciB0aGUgdmFsdWUgb2YgcmVwYWlyTmFtZXNwYWNlIHByb3BlcnR5Ci0gICAgICovCi0gICAgcHJpdmF0ZSBib29sZWFuIGZJc1JlcGFpcmluZ05hbWVzcGFjZSA9IGZhbHNlOwotCi0gICAgLyoqCi0gICAgICogVW5kZXJseWluZyBXcml0ZXIgdG8gd2hpY2ggY2hhcmFjdGVycyBhcmUgd3JpdHRlbi4KLSAgICAgKi8KLSAgICBwcml2YXRlIFdyaXRlciBmV3JpdGVyOwotCi0gICAgLyoqCi0gICAgICogVW5kZXJseWluZyBPdXRwdXRTdHJlYW0gdG8gd2hpY2ggPGNvZGU+ZldyaXRlcjwvY29kZT4KLSAgICAgKiB3cml0ZXMgdG8uIE1heSBiZSBudWxsIGlmIHVua25vd24uCi0gICAgICovCi0gICAgcHJpdmF0ZSBPdXRwdXRTdHJlYW0gZk91dHB1dFN0cmVhbSA9IG51bGw7Ci0KLSAgICAvKioKLSAgICAgKiBDb2xsZWN0cyBhdHRyaWJ1dGVzIHdoZW4gdGhlIHdyaXRlciBpcyBpbiByZXBhcmluZyBtb2RlLgotICAgICAqLwotICAgIHByaXZhdGUgQXJyYXlMaXN0IGZBdHRyaWJ1dGVDYWNoZTsKLQotICAgIC8qKgotICAgICAqIENvbGxlY3RzIG5hbWVzcGFjZSBkZWNsYXJhdGlvbnMgd2hlbiB0aGUgd3JpdGVyIGlzIGluIHJlcGFyaW5nIG1vZGUuCi0gICAgICovCi0gICAgcHJpdmF0ZSBBcnJheUxpc3QgZk5hbWVzcGFjZURlY2xzOwotCi0gICAgLyoqCi0gICAgICogTmFtZXNwYWNlIGNvbnRleHQgZW5jYXBzdWxhdGluZyB1c2VyIHNwZWNpZmllZCBjb250ZXh0Ci0gICAgICogYW5kIGNvbnRleHQgYnVpbHQgYnkgdGhlIHdyaXRlcgotICAgICAqLwotICAgIHByaXZhdGUgTmFtZXNwYWNlQ29udGV4dEltcGwgZk5hbWVzcGFjZUNvbnRleHQgPSBudWxsOwotCi0gICAgcHJpdmF0ZSBOYW1lc3BhY2VTdXBwb3J0IGZJbnRlcm5hbE5hbWVzcGFjZUNvbnRleHQgPSBudWxsOwotCi0gICAgcHJpdmF0ZSBSYW5kb20gZlByZWZpeEdlbiA9IG51bGw7Ci0KLSAgICAvKioKLSAgICAgKiBSZWZlcmVuY2UgdG8gUHJvcGVydHlNYW5hZ2VyCi0gICAgICovCi0gICAgcHJpdmF0ZSBQcm9wZXJ0eU1hbmFnZXIgZlByb3BlcnR5TWFuYWdlciA9IG51bGw7Ci0KLSAgICAvKioKLSAgICAgKiBGbGFnIHRvIHRyYWNrIGlmIHN0YXJ0IHRhZyBpcyBvcGVuZWQKLSAgICAgKi8KLSAgICBwcml2YXRlIGJvb2xlYW4gZlN0YXJ0VGFnT3BlbmVkID0gZmFsc2U7Ci0KLSAgICAvKioKLSAgICAgKiBCb29sZWFuIGZsYWcgIHRvIGluZGljYXRlLCBpZiBpbnN0YW5jZSBjYW4gYmUgcmV1c2VkCi0gICAgICovCi0gICAgcHJpdmF0ZSBib29sZWFuIGZSZXVzZTsKLQotICAgIHByaXZhdGUgU3ltYm9sVGFibGUgZlN5bWJvbFRhYmxlID0gbmV3IFN5bWJvbFRhYmxlKCk7Ci0KLSAgICBwcml2YXRlIEVsZW1lbnRTdGFjayBmRWxlbWVudFN0YWNrID0gbmV3IEVsZW1lbnRTdGFjaygpOyAvL0NoYW5nZSB0aGlzIC4tVmVudQotCi0gICAgZmluYWwgcHJpdmF0ZSBTdHJpbmcgREVGQVVMVF9QUkVGSVggPSBmU3ltYm9sVGFibGUuYWRkU3ltYm9sKCIiKTsKLQotICAgIHByaXZhdGUgZmluYWwgUmVhZE9ubHlJdGVyYXRvciBmUmVhZE9ubHlJdGVyYXRvciA9IG5ldyBSZWFkT25seUl0ZXJhdG9yKCk7Ci0KLSAgICAvKioKLSAgICAgKiBJbiBzb21lIGNhc2VzLCB0aGlzIGNoYXJzZXQgZW5jb2RlciBpcyB1c2VkIHRvIGRldGVybWluZSBpZiBhIGNoYXIgaXMKLSAgICAgKiBlbmNvZGFibGUgYnkgdW5kZXJseWluZyB3cml0ZXIuIEZvciBleGFtcGxlLCBhbiA4LWJpdCBjaGFyIGZyb20gdGhlCi0gICAgICogZXh0ZW5kZWQgQVNDSUkgc2V0IGlzIG5vdCBlbmNvZGFibGUgYnkgNy1iaXQgQVNDSUkgZW5jb2Rlci4gVW5lbmNvZGFibGUKLSAgICAgKiBjaGFycyBhcmUgZXNjYXBlZCB1c2luZyBYTUwgbnVtZXJpYyBlbnRpdGllcy4KLSAgICAgKi8KLSAgICBwcml2YXRlIENoYXJzZXRFbmNvZGVyIGZFbmNvZGVyID0gbnVsbDsKLQotICAgICAvKioKLSAgICAgKiBUaGlzIGlzIHVzZWQgdG8gaG9sZCB0aGUgbmFtZXNwYWNlIGZvciBhdHRyaWJ1dGVzIHdoaWNoIGhhcHBlbiB0byBoYXZlCi0gICAgICogdGhlIHNhbWUgdXJpIGFzIHRoZSBkZWZhdWx0IG5hbWVzcGFjZTsgSXQncyBhZGRlZCB0byBhdm9pZCBjaGFuZ2luZyB0aGUKLSAgICAgKiBjdXJyZW50IGltcGwuIHdoaWNoIGhhcyBtYW55IHJlZHVuZGFudCBjb2RlIGZvciB0aGUgcmVwYWlyIG1vZGUKLSAgICAgKi8KLSAgICBIYXNoTWFwIGZBdHRyTmFtZXNwYWNlID0gbnVsbDsKLQotICAgIC8qKgotICAgICAqIENyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgWE1MU3RyZWFtV3JpdGVySW1wbC4gVXNlcyBwbGF0Zm9ybSdzIGRlZmF1bHQKLSAgICAgKiBlbmNvZGluZy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBvdXRwdXRTdHJlYW0gVW5kZXJseWluZyBzdHJlYW0gdG8gd3JpdGUgdGhlIGJ5dGVzIHRvCi0gICAgICogQHBhcmFtIHByb3BzICAgICAgICBQcm9wZXJ0aWVzIHVzZWQgYnkgdGhpcyB3cml0ZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgWE1MU3RyZWFtV3JpdGVySW1wbChPdXRwdXRTdHJlYW0gb3V0cHV0U3RyZWFtLCBQcm9wZXJ0eU1hbmFnZXIgcHJvcHMpCi0gICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0KLSAgICAgICAgLy8gY2Fubm90IGNhbGwgdGhpcyhvdXRwdXRTdHJlYW0sIG51bGwsIHByb3BzKTsgZm9yIGNvbnN0cnVjdG9yLAotICAgICAgICAvLyBPdXRwdXRTdHJlYW1Xcml0ZXIgY2hhcnNldE5hbWUgY2Fubm90IGJlIG51bGwKLQotICAgICAgICAvLyB1c2UgZGVmYXVsdCBlbmNvZGluZwotICAgICAgICB0aGlzKG5ldyBPdXRwdXRTdHJlYW1Xcml0ZXIob3V0cHV0U3RyZWFtKSwgcHJvcHMpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgWE1MU3RyZWFtV3JpdGVySW1wbC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBvdXRwdXRTdHJlYW0gVW5kZXJseWluZyBzdHJlYW0gdG8gd3JpdGUgdGhlIGJ5dGVzCi0gICAgICogQHBhcmFtIGVuY29kaW5nICAgICBFbmNvZGluZyB1c2VkIHRvIGNvbnZlcnQgY2hhcnMgaW50byBieXRlcwotICAgICAqIEBwYXJhbSBwcm9wcyAgICAgICAgUHJvcGVydGllcyB1c2VkIGJ5IHRoaXMgd3JpdGVyCi0gICAgICovCi0gICAgcHVibGljIFhNTFN0cmVhbVdyaXRlckltcGwoT3V0cHV0U3RyZWFtIG91dHB1dFN0cmVhbSwgU3RyaW5nIGVuY29kaW5nLAotICAgICAgICBQcm9wZXJ0eU1hbmFnZXIgcHJvcHMpIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKLSAgICAgICAgdGhpcyhuZXcgU3RyZWFtUmVzdWx0KG91dHB1dFN0cmVhbSksIGVuY29kaW5nLCBwcm9wcyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiBYTUxTdHJlYW1Xcml0ZXJJbXBsIHVzaW5nIGEgV3JpdGVyLgotICAgICAqCi0gICAgICogQHBhcmFtIHdyaXRlciAgVW5kZXJseWluZyB3cml0ZXIgdG8gd2hpY2ggY2hhcnMgYXJlIHdyaXR0ZW4KLSAgICAgKiBAcGFyYW0gcHJvcHMgICBQcm9wZXJ0aWVzIHVzZWQgYnkgdGhpcyB3cml0ZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgWE1MU3RyZWFtV3JpdGVySW1wbChXcml0ZXIgd3JpdGVyLCBQcm9wZXJ0eU1hbmFnZXIgcHJvcHMpCi0gICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKLSAgICAgICAgdGhpcyhuZXcgU3RyZWFtUmVzdWx0KHdyaXRlciksIG51bGwsIHByb3BzKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIFhNTFN0cmVhbVdyaXRlckltcGwgdXNpbmcgYSBTdHJlYW1SZXN1bHQuCi0gICAgICogQSBTdHJlYW1SZXN1bHQgZW5jYXN1cGF0ZXMgYW4gT3V0cHV0U3RyZWFtLCBhIFdyaXRlciBvciBhIFN5c3RlbUlkLgotICAgICAqCi0gICAgICogQHBhcmFtIHdyaXRlciAgVW5kZXJseWluZyB3cml0ZXIgdG8gd2hpY2ggY2hhcnMgYXJlIHdyaXR0ZW4KLSAgICAgKiBAcGFyYW0gcHJvcHMgICBQcm9wZXJ0aWVzIHVzZWQgYnkgdGhpcyB3cml0ZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgWE1MU3RyZWFtV3JpdGVySW1wbChTdHJlYW1SZXN1bHQgc3IsIFN0cmluZyBlbmNvZGluZywKLSAgICAgICAgUHJvcGVydHlNYW5hZ2VyIHByb3BzKSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7Ci0gICAgICAgIHNldE91dHB1dChzciwgZW5jb2RpbmcpOwotICAgICAgICBmUHJvcGVydHlNYW5hZ2VyID0gcHJvcHM7Ci0gICAgICAgIGluaXQoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJbml0aWFsaXplIGFuIGluc3RhbmNlIG9mIHRoaXMgWE1MU3RyZWFtV3JpdGVyLiBBbGxvY2F0ZSBuZXcgaW5zdGFuY2VzCi0gICAgICogZm9yIGFsbCB0aGUgZGF0YSBzdHJ1Y3R1cmVzLiBTZXQgaW50ZXJuYWwgZmxhZ3MgYmFzZWQgb24gcHJvcGVydHkgdmFsdWVzLgotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCBpbml0KCkgewotICAgICAgICBmUmV1c2UgPSBmYWxzZTsKLSAgICAgICAgZk5hbWVzcGFjZURlY2xzID0gbmV3IEFycmF5TGlzdCgpOwotICAgICAgICBmUHJlZml4R2VuID0gbmV3IFJhbmRvbSgpOwotICAgICAgICBmQXR0cmlidXRlQ2FjaGUgPSBuZXcgQXJyYXlMaXN0KCk7Ci0gICAgICAgIGZJbnRlcm5hbE5hbWVzcGFjZUNvbnRleHQgPSBuZXcgTmFtZXNwYWNlU3VwcG9ydCgpOwotICAgICAgICBmSW50ZXJuYWxOYW1lc3BhY2VDb250ZXh0LnJlc2V0KCk7Ci0gICAgICAgIGZOYW1lc3BhY2VDb250ZXh0ID0gbmV3IE5hbWVzcGFjZUNvbnRleHRJbXBsKCk7Ci0gICAgICAgIGZOYW1lc3BhY2VDb250ZXh0LmludGVybmFsQ29udGV4dCA9IGZJbnRlcm5hbE5hbWVzcGFjZUNvbnRleHQ7Ci0KLSAgICAgICAgLy8gU2V0IGludGVybmFsIHN0YXRlIGJhc2VkIG9uIHByb3BlcnR5IHZhbHVlcwotICAgICAgICBCb29sZWFuIG9iID0gKEJvb2xlYW4pIGZQcm9wZXJ0eU1hbmFnZXIuZ2V0UHJvcGVydHkoWE1MT3V0cHV0RmFjdG9yeS5JU19SRVBBSVJJTkdfTkFNRVNQQUNFUyk7Ci0gICAgICAgIGZJc1JlcGFpcmluZ05hbWVzcGFjZSA9IG9iLmJvb2xlYW5WYWx1ZSgpOwotICAgICAgICBvYiA9IChCb29sZWFuKSBmUHJvcGVydHlNYW5hZ2VyLmdldFByb3BlcnR5KENvbnN0YW50cy5FU0NBUEVfQ0hBUkFDVEVSUyk7Ci0gICAgICAgIHNldEVzY2FwZUNoYXJhY3RlcnMob2IuYm9vbGVhblZhbHVlKCkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJlc2V0IHRoaXMgaW5zdGFuY2Ugc28gdGhhdCBpdCBjYW4gYmUgcmUtdXNlZC4gRG8gbm90IHJlYWQgcHJvcGVydGllcwotICAgICAqIGFnYWluLiBUaGUgbWV0aG9kIDxjb2RlPnNldE91dHB1dChTdHJlYW1SZXN1bHQsIGVuY29kaW5nKTwvY29kZT4gbXVzdAotICAgICAqIGJlIGNhbGxlZCBhZnRlciB0aGlzIG9uZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCByZXNldCgpIHsKLSAgICAgICAgcmVzZXQoZmFsc2UpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJlc2V0IHRoaXMgaW5zdGFuY2Ugc28gdGhhdCBpdCBjYW4gYmUgcmUtdXNlZC4gQ2xlYXJzIGJ1dCBkb2VzIG5vdAotICAgICAqIHJlLWFsbG9jYXRlIGludGVybmFsIGRhdGEgc3RydWN0dXJlcy4KLSAgICAgKgotICAgICAqIEBwYXJhbSByZXNldFByb3BlcnRpZXMgSW5kaWNhdGVzIGlmIHByb3BlcnRpZXMgc2hvdWxkIGJlIHJlYWQgYWdhaW4KLSAgICAgKi8KLSAgICB2b2lkIHJlc2V0KGJvb2xlYW4gcmVzZXRQcm9wZXJ0aWVzKSB7Ci0gICAgICAgIGlmICghZlJldXNlKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxTdGF0ZUV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAiY2xvc2UoKSBNdXN0IGJlIGNhbGxlZCBiZWZvcmUgY2FsbGluZyByZXNldCgpIik7Ci0gICAgICAgIH0KLQotICAgICAgICBmUmV1c2UgPSBmYWxzZTsKLSAgICAgICAgZk5hbWVzcGFjZURlY2xzLmNsZWFyKCk7Ci0gICAgICAgIGZBdHRyaWJ1dGVDYWNoZS5jbGVhcigpOwotCi0gICAgICAgIC8vIHJlc2V0IEVsZW1lbnQvTmFtZXNwYWNlQ29udGV4dCBzdGFja3MKLSAgICAgICAgZkVsZW1lbnRTdGFjay5jbGVhcigpOwotICAgICAgICBmSW50ZXJuYWxOYW1lc3BhY2VDb250ZXh0LnJlc2V0KCk7Ci0KLSAgICAgICAgZlN0YXJ0VGFnT3BlbmVkID0gZmFsc2U7Ci0gICAgICAgIGZOYW1lc3BhY2VDb250ZXh0LnVzZXJDb250ZXh0ID0gbnVsbDsKLQotICAgICAgICBpZiAocmVzZXRQcm9wZXJ0aWVzKSB7Ci0gICAgICAgICAgICBCb29sZWFuIG9iID0gKEJvb2xlYW4pIGZQcm9wZXJ0eU1hbmFnZXIuZ2V0UHJvcGVydHkoWE1MT3V0cHV0RmFjdG9yeS5JU19SRVBBSVJJTkdfTkFNRVNQQUNFUyk7Ci0gICAgICAgICAgICBmSXNSZXBhaXJpbmdOYW1lc3BhY2UgPSBvYi5ib29sZWFuVmFsdWUoKTsKLSAgICAgICAgICAgIG9iID0gKEJvb2xlYW4pIGZQcm9wZXJ0eU1hbmFnZXIuZ2V0UHJvcGVydHkoQ29uc3RhbnRzLkVTQ0FQRV9DSEFSQUNURVJTKTsKLSAgICAgICAgICAgIHNldEVzY2FwZUNoYXJhY3RlcnMob2IuYm9vbGVhblZhbHVlKCkpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVXNlIGEgU3RyZWFtUmVzdWx0IHRvIGluaXRpYWxpemUgdGhlIG91dHB1dCBmb3IgdGhpcyBYTUxTdHJlYW1Xcml0ZXIuIENoZWNrCi0gICAgICogZm9yIE91dHB1dFN0cmVhbSwgV3JpdGVyIGFuZCB0aGVuIHN5c3RlbUlkLCBpbiB0aGF0IG9yZGVyLgotICAgICAqCi0gICAgICogQHBhcmFtIHNyICAgICAgICBTdHJlYW1SZXN1bHQgZW5jYXBzdWxhdGluZyBvdXRwdXQgaW5mb3JtYXRpb24KLSAgICAgKiBAcGFyYW0gZW5jb2RpbmcgIEVuY29kaW5nIHRvIGJlIHVzZWQgZXhjZXB0IHdoZW4gYSBXcml0ZXIgaXMgYXZhaWxhYmxlCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0T3V0cHV0KFN0cmVhbVJlc3VsdCBzciwgU3RyaW5nIGVuY29kaW5nKQotICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24gewotCi0gICAgICAgIGlmIChzci5nZXRPdXRwdXRTdHJlYW0oKSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBzZXRPdXRwdXRVc2luZ1N0cmVhbShzci5nZXRPdXRwdXRTdHJlYW0oKSwgZW5jb2RpbmcpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKHNyLmdldFdyaXRlcigpICE9IG51bGwpIHsKLSAgICAgICAgICAgIHNldE91dHB1dFVzaW5nV3JpdGVyKHNyLmdldFdyaXRlcigpKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChzci5nZXRTeXN0ZW1JZCgpICE9IG51bGwpIHsKLSAgICAgICAgICAgIHNldE91dHB1dFVzaW5nU3RyZWFtKG5ldyBGaWxlT3V0cHV0U3RyZWFtKHNyLmdldFN5c3RlbUlkKCkpLAotICAgICAgICAgICAgICAgIGVuY29kaW5nKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgICBwcml2YXRlIHZvaWQgc2V0T3V0cHV0VXNpbmdXcml0ZXIoV3JpdGVyIHdyaXRlcikKLSAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uCi0gICAgIHsKLSAgICAgICAgIGZXcml0ZXIgPSB3cml0ZXI7Ci0KLSAgICAgICAgIGlmICh3cml0ZXIgaW5zdGFuY2VvZiBPdXRwdXRTdHJlYW1Xcml0ZXIpIHsKLSAgICAgICAgICAgICBTdHJpbmcgY2hhcnNldCA9ICgoT3V0cHV0U3RyZWFtV3JpdGVyKSB3cml0ZXIpLmdldEVuY29kaW5nKCk7Ci0gICAgICAgICAgICAgaWYgKGNoYXJzZXQgIT0gbnVsbCAmJiAhY2hhcnNldC5lcXVhbHNJZ25vcmVDYXNlKCJ1dGYtOCIpKSB7Ci0gICAgICAgICAgICAgICAgIGZFbmNvZGVyID0gQ2hhcnNldC5mb3JOYW1lKGNoYXJzZXQpLm5ld0VuY29kZXIoKTsKLSAgICAgICAgICAgICB9Ci0gICAgICAgICB9Ci0gICAgIH0KLQotICAgIC8qKgotICAgICAqIFV0aWxpdHkgbWV0aG9kIHRvIGNyZWF0ZSBhIHdyaXRlciB3aGVuIHBhc3NlZCBhbiBPdXRwdXRTdHJlYW0uIE1ha2UKLSAgICAgKiBzdXJlIHRvIHdyYXAgYW4gPGNvZGU+T3V0cHV0U3RyZWFtV3JpdGVyPC9jb2RlPiB1c2luZyBhbgotICAgICAqIDxjb2RlPlhNTFdyaXRlcjwvY29kZT4gZm9yIHBlcmZvcm1hbmNlIHJlYXNvbnMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gb3MgICAgICAgIFVuZGVybHlpbmcgT3V0cHV0U3RyZWFtCi0gICAgICogQHBhcmFtIGVuY29kaW5nICBFbmNvZGluZyB1c2VkIHRvIGNvbnZlcnQgY2hhcnMgaW50byBieXRlcwotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCBzZXRPdXRwdXRVc2luZ1N0cmVhbShPdXRwdXRTdHJlYW0gb3MsIFN0cmluZyBlbmNvZGluZykKLSAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKLSAgICAgICAgZk91dHB1dFN0cmVhbSA9IG9zOwotCi0gICAgICAgIGlmIChlbmNvZGluZyAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAoZW5jb2RpbmcuZXF1YWxzSWdub3JlQ2FzZSgidXRmLTgiKSkgewotICAgICAgICAgICAgICAgIGZXcml0ZXIgPSBuZXcgVVRGOE91dHB1dFN0cmVhbVdyaXRlcihvcyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBmV3JpdGVyID0gbmV3IFhNTFdyaXRlcihuZXcgT3V0cHV0U3RyZWFtV3JpdGVyKG9zLCBlbmNvZGluZykpOwotICAgICAgICAgICAgICAgIGZFbmNvZGVyID0gQ2hhcnNldC5mb3JOYW1lKGVuY29kaW5nKS5uZXdFbmNvZGVyKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBlbmNvZGluZyA9IFNlY3VyaXR5U3VwcG9ydC5nZXRTeXN0ZW1Qcm9wZXJ0eSgiZmlsZS5lbmNvZGluZyIpOwotICAgICAgICAgICAgaWYgKGVuY29kaW5nICE9IG51bGwgJiYgZW5jb2RpbmcuZXF1YWxzSWdub3JlQ2FzZSgidXRmLTgiKSkgewotICAgICAgICAgICAgICAgIGZXcml0ZXIgPSBuZXcgVVRGOE91dHB1dFN0cmVhbVdyaXRlcihvcyk7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIGZXcml0ZXIgPSBuZXcgWE1MV3JpdGVyKG5ldyBPdXRwdXRTdHJlYW1Xcml0ZXIob3MpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKiBDYW4gdGhpcyBpbnN0YW5jZSBiZSByZXVzZWQKLSAgICAgKgotICAgICAqIEByZXR1cm4gYm9vbGVhbiBib29sZWFuIHZhbHVlIHRvIGluZGljYXRlIGlmIHRoaXMgaW5zdGFuY2UgY2FuIGJlIHJldXNlZCBvciBub3QKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBjYW5SZXVzZSgpIHsKLSAgICAgICAgcmV0dXJuIGZSZXVzZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRFc2NhcGVDaGFyYWN0ZXJzKGJvb2xlYW4gZXNjYXBlKSB7Ci0gICAgICAgIGZFc2NhcGVDaGFyYWN0ZXJzID0gZXNjYXBlOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGdldEVzY2FwZUNoYXJhY3RlcnMoKSB7Ci0gICAgICAgIHJldHVybiBmRXNjYXBlQ2hhcmFjdGVyczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDbG9zZSB0aGlzIFhNTFN0cmVhbVdyaXRlciBieSBjbG9zaW5nIHVuZGVybHlpbmcgd3JpdGVyLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChmV3JpdGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgLy9mV3JpdGVyLmNsb3NlKCk7Ci0gICAgICAgICAgICAgICAgZldyaXRlci5mbHVzaCgpOwotICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBYTUxTdHJlYW1FeGNlcHRpb24oZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZldyaXRlciA9IG51bGw7Ci0gICAgICAgIGZPdXRwdXRTdHJlYW0gPSBudWxsOwotICAgICAgICBmTmFtZXNwYWNlRGVjbHMuY2xlYXIoKTsKLSAgICAgICAgZkF0dHJpYnV0ZUNhY2hlLmNsZWFyKCk7Ci0gICAgICAgIGZFbGVtZW50U3RhY2suY2xlYXIoKTsKLSAgICAgICAgZkludGVybmFsTmFtZXNwYWNlQ29udGV4dC5yZXNldCgpOwotICAgICAgICBmUmV1c2UgPSB0cnVlOwotICAgICAgICBmU3RhcnRUYWdPcGVuZWQgPSBmYWxzZTsKLSAgICAgICAgZk5hbWVzcGFjZUNvbnRleHQudXNlckNvbnRleHQgPSBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEZsdXNoIHRoaXMgWE1MU3RyZWFtV3JpdGVyIGJ5IGZsdXNoaW4gdW5kZXJseWluZyB3cml0ZXIuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZmx1c2goKSB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGZXcml0ZXIuZmx1c2goKTsKLSAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFhNTFN0cmVhbUV4Y2VwdGlvbihlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybiA8Y29kZT5OYW1lc3BhY2VDb250ZXh0PC9jb2RlPiBiZWluZyB1c2VkIGJ5IHRoZSB3cml0ZXIuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIE5hbWVzcGFjZUNvbnRleHQKLSAgICAgKi8KLSAgICBwdWJsaWMgTmFtZXNwYWNlQ29udGV4dCBnZXROYW1lc3BhY2VDb250ZXh0KCkgewotICAgICAgICByZXR1cm4gZk5hbWVzcGFjZUNvbnRleHQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIGEgcHJlZml4IGFzc29jaWF0ZWQgd2l0aCBzcGVjaWZpZWQgdXJpLCBvciBudWxsIGlmIHRoZQotICAgICAqIHVyaSBpcyB1bmtub3duLgotICAgICAqCi0gICAgICogQHBhcmFtICB1cmkgVGhlIG5hbWVzcGFjZSB1cmkKLSAgICAgKiBAdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbiBpZiB1cmkgc3BlY2lmaWVkIGlzICIiIG9yIG51bGwKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFByZWZpeChTdHJpbmcgdXJpKSB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uIHsKLSAgICAgICAgcmV0dXJuIGZOYW1lc3BhY2VDb250ZXh0LmdldFByZWZpeCh1cmkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdmFsdWUgYXNzb2NpYXRlZCB3aXRoIHRoZSBzcGVjaWZpZWQgcHJvcGVydHkgbmFtZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSAgc3RyIFByb3BlcnR5IG5hbWUKLSAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIHByb3BlcnR5IGlzIG5vdCBzdXBwb3J0ZWQKLSAgICAgKiBAcmV0dXJuIHZhbHVlIGFzc29jaWF0ZWQgd2l0aCB0aGUgc3BlY2lmaWVkIHByb3BlcnR5LgotICAgICAqLwotICAgIHB1YmxpYyBPYmplY3QgZ2V0UHJvcGVydHkoU3RyaW5nIHN0cikKLSAgICAgICAgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChzdHIgPT0gbnVsbCkgewotICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoIWZQcm9wZXJ0eU1hbmFnZXIuY29udGFpbnNQcm9wZXJ0eShzdHIpKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJQcm9wZXJ0eSAnIiArIHN0ciArCi0gICAgICAgICAgICAgICAgIicgaXMgbm90IHN1cHBvcnRlZCIpOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIGZQcm9wZXJ0eU1hbmFnZXIuZ2V0UHJvcGVydHkoc3RyKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIHNwZWNpZmllZCBVUkkgYXMgZGVmYXVsdCBuYW1lc3BhY2UgaW4gdGhlIGN1cnJlbnQgbmFtZXNwYWNlIGNvbnRleHQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdXJpIE5hbWVzcGFjZSBVUkkKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXREZWZhdWx0TmFtZXNwYWNlKFN0cmluZyB1cmkpIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24gewotICAgICAgICBpZiAodXJpICE9IG51bGwpIHsKLSAgICAgICAgICAgIHVyaSA9IGZTeW1ib2xUYWJsZS5hZGRTeW1ib2wodXJpKTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChmSXNSZXBhaXJpbmdOYW1lc3BhY2UpIHsKLSAgICAgICAgICAgIGlmIChpc0RlZmF1bHROYW1lc3BhY2UodXJpKSkgewotICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgUU5hbWUgcW5hbWUgPSBuZXcgUU5hbWUoKTsKLSAgICAgICAgICAgIHFuYW1lLnNldFZhbHVlcyhERUZBVUxUX1BSRUZJWCwgInhtbG5zIiwgbnVsbCwgdXJpKTsKLSAgICAgICAgICAgIGZOYW1lc3BhY2VEZWNscy5hZGQocW5hbWUpOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgZkludGVybmFsTmFtZXNwYWNlQ29udGV4dC5kZWNsYXJlUHJlZml4KERFRkFVTFRfUFJFRklYLCB1cmkpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0cyB0aGUgY3VycmVudCA8Y29kZT5OYW1lc3BhY2VDb250ZXh0PC9jb2RlPiBmb3IgcHJlZml4IGFuZCB1cmkgYmluZGluZ3MuCi0gICAgICogVGhpcyBjb250ZXh0IGJlY29tZXMgdGhlIHJvb3QgbmFtZXNwYWNlIGNvbnRleHQgZm9yIHdyaXRpbmcgYW5kCi0gICAgICogd2lsbCByZXBsYWNlIHRoZSBjdXJyZW50IHJvb3QgbmFtZXNwYWNlIGNvbnRleHQuIFN1YnNlcXVlbnQgY2FsbHMKLSAgICAgKiB0byBzZXRQcmVmaXggYW5kIHNldERlZmF1bHROYW1lc3BhY2Ugd2lsbCBiaW5kIG5hbWVzcGFjZXMgdXNpbmcKLSAgICAgKiB0aGUgY29udGV4dCBwYXNzZWQgdG8gdGhlIG1ldGhvZCBhcyB0aGUgcm9vdCBjb250ZXh0IGZvciByZXNvbHZpbmcKLSAgICAgKiBuYW1lc3BhY2VzLiBUaGlzIG1ldGhvZCBtYXkgb25seSBiZSBjYWxsZWQgb25jZSBhdCB0aGUgc3RhcnQgb2YgdGhlCi0gICAgICogZG9jdW1lbnQuIEl0IGRvZXMgbm90IGNhdXNlIHRoZSBuYW1lc3BhY2VzIHRvIGJlIGRlY2xhcmVkLiBJZiBhCi0gICAgICogbmFtZXNwYWNlIFVSSSB0byBwcmVmaXggbWFwcGluZyBpcyBmb3VuZCBpbiB0aGUgbmFtZXNwYWNlIGNvbnRleHQKLSAgICAgKiBpdCBpcyB0cmVhdGVkIGFzIGRlY2xhcmVkIGFuZCB0aGUgcHJlZml4IG1heSBiZSB1c2VkIGJ5IHRoZQotICAgICAqIDxjb2RlPlhNTFN0cmVhbVdyaXRlcjwvY29kZT4uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZXNwYWNlQ29udGV4dCB0aGUgbmFtZXNwYWNlIGNvbnRleHQgdG8gdXNlIGZvciB0aGlzIHdyaXRlciwgbWF5IG5vdCBiZSBudWxsCi0gICAgICogQHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXROYW1lc3BhY2VDb250ZXh0KE5hbWVzcGFjZUNvbnRleHQgbmFtZXNwYWNlQ29udGV4dCkKLSAgICAgICAgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbiB7Ci0gICAgICAgIGZOYW1lc3BhY2VDb250ZXh0LnVzZXJDb250ZXh0ID0gbmFtZXNwYWNlQ29udGV4dDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSBwcmVmaXggdGhlIHVyaSBpcyBib3VuZCB0by4gVGhpcyBwcmVmaXggaXMgYm91bmQgaW4gdGhlIHNjb3BlIG9mCi0gICAgICogdGhlIGN1cnJlbnQgU1RBUlRfRUxFTUVOVCAvIEVORF9FTEVNRU5UIHBhaXIuIElmIHRoaXMgbWV0aG9kIGlzIGNhbGxlZCBiZWZvcmUKLSAgICAgKiBhIFNUQVJUX0VMRU1FTlQgaGFzIGJlZW4gd3JpdHRlbiB0aGUgcHJlZml4IGlzIGJvdW5kIGluIHRoZSByb290IHNjb3BlLgotICAgICAqCi0gICAgICogQHBhcmFtIHByZWZpeAotICAgICAqIEBwYXJhbSB1cmkKLSAgICAgKiBAdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFByZWZpeChTdHJpbmcgcHJlZml4LCBTdHJpbmcgdXJpKSB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uIHsKLQotICAgICAgICBpZiAocHJlZml4ID09IG51bGwpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBYTUxTdHJlYW1FeGNlcHRpb24oIlByZWZpeCBjYW5ub3QgYmUgbnVsbCIpOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKHVyaSA9PSBudWxsKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWE1MU3RyZWFtRXhjZXB0aW9uKCJVUkkgY2Fubm90IGJlIG51bGwiKTsKLSAgICAgICAgfQotCi0gICAgICAgIHByZWZpeCA9IGZTeW1ib2xUYWJsZS5hZGRTeW1ib2wocHJlZml4KTsKLSAgICAgICAgdXJpID0gZlN5bWJvbFRhYmxlLmFkZFN5bWJvbCh1cmkpOwotCi0gICAgICAgIGlmIChmSXNSZXBhaXJpbmdOYW1lc3BhY2UpIHsKLSAgICAgICAgICAgIFN0cmluZyB0bXBVUkkgPSBmSW50ZXJuYWxOYW1lc3BhY2VDb250ZXh0LmdldFVSSShwcmVmaXgpOwotCi0gICAgICAgICAgICBpZiAoKHRtcFVSSSAhPSBudWxsKSAmJiAodG1wVVJJID09IHVyaSkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmKGNoZWNrVXNlck5hbWVzcGFjZUNvbnRleHQocHJlZml4LHVyaSkpCi0gICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgUU5hbWUgcW5hbWUgPSBuZXcgUU5hbWUoKTsKLSAgICAgICAgICAgIHFuYW1lLnNldFZhbHVlcyhwcmVmaXgsWE1MQ29uc3RhbnRzLlhNTE5TX0FUVFJJQlVURSwgbnVsbCx1cmkpOwotICAgICAgICAgICAgZk5hbWVzcGFjZURlY2xzLmFkZChxbmFtZSk7Ci0KLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotCi0gICAgICAgIGZJbnRlcm5hbE5hbWVzcGFjZUNvbnRleHQuZGVjbGFyZVByZWZpeChwcmVmaXgsIHVyaSk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgd3JpdGVBdHRyaWJ1dGUoU3RyaW5nIGxvY2FsTmFtZSwgU3RyaW5nIHZhbHVlKQotICAgICAgICB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGlmICghZlN0YXJ0VGFnT3BlbmVkKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFhNTFN0cmVhbUV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgIkF0dHJpYnV0ZSBub3QgYXNzb2NpYXRlZCB3aXRoIGFueSBlbGVtZW50Iik7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmIChmSXNSZXBhaXJpbmdOYW1lc3BhY2UpIHsKLSAgICAgICAgICAgICAgICBBdHRyaWJ1dGUgYXR0ciA9IG5ldyBBdHRyaWJ1dGUodmFsdWUpOyAvLyBSZXZpc2l0OkRvbnQgY3JlYXRlIG5ldyBvbmUncy4gUmV1c2UuLVZlbnUKLSAgICAgICAgICAgICAgICBhdHRyLnNldFZhbHVlcyhudWxsLCBsb2NhbE5hbWUsIG51bGwsIG51bGwpOwotICAgICAgICAgICAgICAgIGZBdHRyaWJ1dGVDYWNoZS5hZGQoYXR0cik7Ci0KLSAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGZXcml0ZXIud3JpdGUoIiAiKTsKLSAgICAgICAgICAgIGZXcml0ZXIud3JpdGUobG9jYWxOYW1lKTsKLSAgICAgICAgICAgIGZXcml0ZXIud3JpdGUoIj1cIiIpOwotICAgICAgICAgICAgd3JpdGVYTUxDb250ZW50KAotICAgICAgICAgICAgICAgICAgICB2YWx1ZSwKLSAgICAgICAgICAgICAgICAgICAgdHJ1ZSwgICAvLyB0cnVlID0gZXNjYXBlQ2hhcnMKLSAgICAgICAgICAgICAgICAgICAgdHJ1ZSk7ICAvLyB0cnVlID0gZXNjYXBlRG91YmxlUXVvdGVzCi0gICAgICAgICAgICBmV3JpdGVyLndyaXRlKCJcIiIpOwotICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWE1MU3RyZWFtRXhjZXB0aW9uKGUpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgd3JpdGVBdHRyaWJ1dGUoU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIGxvY2FsTmFtZSwKLSAgICAgICAgU3RyaW5nIHZhbHVlKSB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGlmICghZlN0YXJ0VGFnT3BlbmVkKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFhNTFN0cmVhbUV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgIkF0dHJpYnV0ZSBub3QgYXNzb2NpYXRlZCB3aXRoIGFueSBlbGVtZW50Iik7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmIChuYW1lc3BhY2VVUkkgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBYTUxTdHJlYW1FeGNlcHRpb24oIk5hbWVzcGFjZVVSSSBjYW5ub3QgYmUgbnVsbCIpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBuYW1lc3BhY2VVUkkgPSBmU3ltYm9sVGFibGUuYWRkU3ltYm9sKG5hbWVzcGFjZVVSSSk7Ci0KLSAgICAgICAgICAgIFN0cmluZyBwcmVmaXggPSBmSW50ZXJuYWxOYW1lc3BhY2VDb250ZXh0LmdldFByZWZpeChuYW1lc3BhY2VVUkkpOwotCi0gICAgICAgICAgICBpZiAoIWZJc1JlcGFpcmluZ05hbWVzcGFjZSkgewotICAgICAgICAgICAgICAgIGlmIChwcmVmaXggPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWE1MU3RyZWFtRXhjZXB0aW9uKCJQcmVmaXggY2Fubm90IGJlIG51bGwiKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICB3cml0ZUF0dHJpYnV0ZVdpdGhQcmVmaXgocHJlZml4LCBsb2NhbE5hbWUsIHZhbHVlKTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgQXR0cmlidXRlIGF0dHIgPSBuZXcgQXR0cmlidXRlKHZhbHVlKTsKLSAgICAgICAgICAgICAgICBhdHRyLnNldFZhbHVlcyhudWxsLCBsb2NhbE5hbWUsIG51bGwsIG5hbWVzcGFjZVVSSSk7Ci0gICAgICAgICAgICAgICAgZkF0dHJpYnV0ZUNhY2hlLmFkZChhdHRyKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFhNTFN0cmVhbUV4Y2VwdGlvbihlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCB3cml0ZUF0dHJpYnV0ZVdpdGhQcmVmaXgoU3RyaW5nIHByZWZpeCwgU3RyaW5nIGxvY2FsTmFtZSwKLSAgICAgICAgU3RyaW5nIHZhbHVlKSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgICAgICBmV3JpdGVyLndyaXRlKFNQQUNFKTsKLQotICAgICAgICBpZiAoKHByZWZpeCAhPSBudWxsKSAmJiAocHJlZml4ICE9IFhNTENvbnN0YW50cy5ERUZBVUxUX05TX1BSRUZJWCkpIHsKLSAgICAgICAgICAgIGZXcml0ZXIud3JpdGUocHJlZml4KTsKLSAgICAgICAgICAgIGZXcml0ZXIud3JpdGUoIjoiKTsKLSAgICAgICAgfQotCi0gICAgICAgIGZXcml0ZXIud3JpdGUobG9jYWxOYW1lKTsKLSAgICAgICAgZldyaXRlci53cml0ZSgiPVwiIik7Ci0gICAgICAgIHdyaXRlWE1MQ29udGVudCh2YWx1ZSwKLSAgICAgICAgICAgICAgICB0cnVlLCAgIC8vIHRydWUgPSBlc2NhcGVDaGFycwotICAgICAgICAgICAgICAgIHRydWUpOyAgLy8gdHJ1ZSA9IGVzY2FwZURvdWJsZVF1b3RlcwotICAgICAgICBmV3JpdGVyLndyaXRlKCJcIiIpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHdyaXRlQXR0cmlidXRlKFN0cmluZyBwcmVmaXgsIFN0cmluZyBuYW1lc3BhY2VVUkksCi0gICAgICAgIFN0cmluZyBsb2NhbE5hbWUsIFN0cmluZyB2YWx1ZSkgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbiB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBpZiAoIWZTdGFydFRhZ09wZW5lZCkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBYTUxTdHJlYW1FeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgICJBdHRyaWJ1dGUgbm90IGFzc29jaWF0ZWQgd2l0aCBhbnkgZWxlbWVudCIpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAobmFtZXNwYWNlVVJJID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWE1MU3RyZWFtRXhjZXB0aW9uKCJOYW1lc3BhY2VVUkkgY2Fubm90IGJlIG51bGwiKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKGxvY2FsTmFtZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFhNTFN0cmVhbUV4Y2VwdGlvbigiTG9jYWwgbmFtZSBjYW5ub3QgYmUgbnVsbCIpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAoIWZJc1JlcGFpcmluZ05hbWVzcGFjZSkgewotICAgICAgICAgICAgICAgIGlmIChwcmVmaXggPT0gbnVsbCB8fCBwcmVmaXguZXF1YWxzKCIiKSl7Ci0gICAgICAgICAgICAgICAgICAgIGlmICghbmFtZXNwYWNlVVJJLmVxdWFscygiIikpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBYTUxTdHJlYW1FeGNlcHRpb24oInByZWZpeCBjYW5ub3QgYmUgbnVsbCBvciBlbXB0eSIpOwotICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVBdHRyaWJ1dGVXaXRoUHJlZml4KG51bGwsIGxvY2FsTmFtZSwgdmFsdWUpOwotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgaWYgKCFwcmVmaXguZXF1YWxzKFhNTENvbnN0YW50cy5YTUxfTlNfUFJFRklYKSB8fCAhbmFtZXNwYWNlVVJJLmVxdWFscyhYTUxDb25zdGFudHMuWE1MX05TX1VSSSkpIHsKLQotICAgICAgICAgICAgICAgICAgICBwcmVmaXggPSBmU3ltYm9sVGFibGUuYWRkU3ltYm9sKHByZWZpeCk7Ci0gICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZVVSSSA9IGZTeW1ib2xUYWJsZS5hZGRTeW1ib2wobmFtZXNwYWNlVVJJKTsKLQotICAgICAgICAgICAgICAgICAgICBpZiAoZkludGVybmFsTmFtZXNwYWNlQ29udGV4dC5jb250YWluc1ByZWZpeEluQ3VycmVudENvbnRleHQocHJlZml4KSl7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyB0bXBVUkkgPSBmSW50ZXJuYWxOYW1lc3BhY2VDb250ZXh0LmdldFVSSShwcmVmaXgpOwotCi0gICAgICAgICAgICAgICAgICAgICAgICBpZiAodG1wVVJJICE9IG51bGwgJiYgdG1wVVJJICE9IG5hbWVzcGFjZVVSSSl7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFhNTFN0cmVhbUV4Y2VwdGlvbigiUHJlZml4ICIrcHJlZml4KyIgaXMgIiArCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYWxyZWFkeSBib3VuZCB0byAiK3RtcFVSSSsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIuIFRyeWluZyB0byByZWJpbmQgaXQgdG8gIituYW1lc3BhY2VVUkkrIiBpcyBhbiBlcnJvci4iKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBmSW50ZXJuYWxOYW1lc3BhY2VDb250ZXh0LmRlY2xhcmVQcmVmaXgocHJlZml4LCBuYW1lc3BhY2VVUkkpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB3cml0ZUF0dHJpYnV0ZVdpdGhQcmVmaXgocHJlZml4LCBsb2NhbE5hbWUsIHZhbHVlKTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgaWYgKHByZWZpeCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIHByZWZpeCA9IGZTeW1ib2xUYWJsZS5hZGRTeW1ib2wocHJlZml4KTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBuYW1lc3BhY2VVUkkgPSBmU3ltYm9sVGFibGUuYWRkU3ltYm9sKG5hbWVzcGFjZVVSSSk7Ci0KLSAgICAgICAgICAgICAgICBBdHRyaWJ1dGUgYXR0ciA9IG5ldyBBdHRyaWJ1dGUodmFsdWUpOwotICAgICAgICAgICAgICAgIGF0dHIuc2V0VmFsdWVzKHByZWZpeCwgbG9jYWxOYW1lLCBudWxsLCBuYW1lc3BhY2VVUkkpOwotICAgICAgICAgICAgICAgIGZBdHRyaWJ1dGVDYWNoZS5hZGQoYXR0cik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBYTUxTdHJlYW1FeGNlcHRpb24oZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCB3cml0ZUNEYXRhKFN0cmluZyBjZGF0YSkgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbiB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBpZiAoY2RhdGEgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBYTUxTdHJlYW1FeGNlcHRpb24oImNkYXRhIGNhbm5vdCBiZSBudWxsIik7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmIChmU3RhcnRUYWdPcGVuZWQpIHsKLSAgICAgICAgICAgICAgICBjbG9zZVN0YXJ0VGFnKCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGZXcml0ZXIud3JpdGUoU1RBUlRfQ0RBVEEpOwotICAgICAgICAgICAgZldyaXRlci53cml0ZShjZGF0YSk7Ci0gICAgICAgICAgICBmV3JpdGVyLndyaXRlKEVORF9DREFUQSk7Ci0gICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBYTUxTdHJlYW1FeGNlcHRpb24oZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCB3cml0ZUNoYXJhY3RlcnMoU3RyaW5nIGRhdGEpIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24gewotICAgICAgICB0cnkgewotICAgICAgICAgICAgaWYgKGZTdGFydFRhZ09wZW5lZCkgewotICAgICAgICAgICAgICAgIGNsb3NlU3RhcnRUYWcoKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgd3JpdGVYTUxDb250ZW50KGRhdGEpOwotICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWE1MU3RyZWFtRXhjZXB0aW9uKGUpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgd3JpdGVDaGFyYWN0ZXJzKGNoYXJbXSBkYXRhLCBpbnQgc3RhcnQsIGludCBsZW4pCi0gICAgICAgIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24gewotICAgICAgICB0cnkgewotICAgICAgICAgICAgaWYgKGZTdGFydFRhZ09wZW5lZCkgewotICAgICAgICAgICAgICAgIGNsb3NlU3RhcnRUYWcoKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgd3JpdGVYTUxDb250ZW50KGRhdGEsIHN0YXJ0LCBsZW4sIGZFc2NhcGVDaGFyYWN0ZXJzKTsKLSAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFhNTFN0cmVhbUV4Y2VwdGlvbihlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHdyaXRlQ29tbWVudChTdHJpbmcgY29tbWVudCkgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbiB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBpZiAoZlN0YXJ0VGFnT3BlbmVkKSB7Ci0gICAgICAgICAgICAgICAgY2xvc2VTdGFydFRhZygpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBmV3JpdGVyLndyaXRlKFNUQVJUX0NPTU1FTlQpOwotCi0gICAgICAgICAgICBpZiAoY29tbWVudCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZldyaXRlci53cml0ZShjb21tZW50KTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgZldyaXRlci53cml0ZShFTkRfQ09NTUVOVCk7Ci0gICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBYTUxTdHJlYW1FeGNlcHRpb24oZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCB3cml0ZURURChTdHJpbmcgZHRkKSB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGlmIChmU3RhcnRUYWdPcGVuZWQpIHsKLSAgICAgICAgICAgICAgICBjbG9zZVN0YXJ0VGFnKCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGZXcml0ZXIud3JpdGUoZHRkKTsKLSAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFhNTFN0cmVhbUV4Y2VwdGlvbihlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qCi0gICAgICogV3JpdGUgZGVmYXVsdCBOYW1lc3BhY2UuCi0gICAgICoKLSAgICAgKiBJZiBuYW1lc3BhY2VVUkkgPT0gbnVsbCwKLSAgICAgKiB0aGVuIGl0IGlzIGFzc3VtZWQgdG8gYmUgZXF1aXZpbGVudCB0byB7QGxpbmsgWE1MQ29uc3RhbnRzLk5VTExfTlNfVVJJfSwKLSAgICAgKiBpLmUuIHRoZXJlIGlzIG5vIE5hbWVzcGFjZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkgTmFtZXNwYWNlVVJJIHRvIGRlY2xhcmUuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbgotICAgICAqCi0gICAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMteG1sLW5hbWVzLyNkZWZhdWx0aW5nIj4KLSAgICAgKiAgIE5hbWVzcGFjZXMgaW4gWE1MLCA1LjIgTmFtZXNwYWNlIERlZmF1bHRpbmc8L2E+Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgd3JpdGVEZWZhdWx0TmFtZXNwYWNlKFN0cmluZyBuYW1lc3BhY2VVUkkpCi0gICAgICAgIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24gewotCi0gICAgICAgIC8vIG5vcm1hbGl6ZSBuYW1lc3BhY2VVUkkKLSAgICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSU5vcm1hbGl6ZWQgPSBudWxsOwotICAgICAgICBpZiAobmFtZXNwYWNlVVJJID09IG51bGwpIHsKLSAgICAgICAgICAgIG5hbWVzcGFjZVVSSU5vcm1hbGl6ZWQgPSAiIjsgLy8gWE1MQ29uc3RhbnRzLk5VTExfTlNfVVJJCi0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBuYW1lc3BhY2VVUklOb3JtYWxpemVkID0gbmFtZXNwYWNlVVJJOwotICAgICAgICB9Ci0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGlmICghZlN0YXJ0VGFnT3BlbmVkKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgIk5hbWVzcGFjZSBBdHRyaWJ1dGUgbm90IGFzc29jaWF0ZWQgd2l0aCBhbnkgZWxlbWVudCIpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAoZklzUmVwYWlyaW5nTmFtZXNwYWNlKSB7Ci0gICAgICAgICAgICAgICAgUU5hbWUgcW5hbWUgPSBuZXcgUU5hbWUoKTsKLSAgICAgICAgICAgICAgICBxbmFtZS5zZXRWYWx1ZXMoWE1MQ29uc3RhbnRzLkRFRkFVTFRfTlNfUFJFRklYLAotICAgICAgICAgICAgICAgICAgICBYTUxDb25zdGFudHMuWE1MTlNfQVRUUklCVVRFLCBudWxsLCBuYW1lc3BhY2VVUklOb3JtYWxpemVkKTsKLSAgICAgICAgICAgICAgICBmTmFtZXNwYWNlRGVjbHMuYWRkKHFuYW1lKTsKLQotICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgbmFtZXNwYWNlVVJJTm9ybWFsaXplZCA9IGZTeW1ib2xUYWJsZS5hZGRTeW1ib2wobmFtZXNwYWNlVVJJTm9ybWFsaXplZCk7Ci0KLSAgICAgICAgICAgIGlmIChmSW50ZXJuYWxOYW1lc3BhY2VDb250ZXh0LmNvbnRhaW5zUHJlZml4SW5DdXJyZW50Q29udGV4dCgiIikpewotCi0gICAgICAgICAgICAgICAgU3RyaW5nIHRtcCA9IGZJbnRlcm5hbE5hbWVzcGFjZUNvbnRleHQuZ2V0VVJJKCIiKTsKLQotICAgICAgICAgICAgICAgIGlmICh0bXAgIT0gbnVsbCAmJiB0bXAgIT0gbmFtZXNwYWNlVVJJTm9ybWFsaXplZCkgewotICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFhNTFN0cmVhbUV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInhtbG5zIGhhcyBiZWVuIGFscmVhZHkgYm91bmQgdG8gIiArdG1wICsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIi4gUmViaW5kaW5nIGl0IHRvICIrIG5hbWVzcGFjZVVSSU5vcm1hbGl6ZWQgKwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIGlzIGFuIGVycm9yIik7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGZJbnRlcm5hbE5hbWVzcGFjZUNvbnRleHQuZGVjbGFyZVByZWZpeCgiIiwgbmFtZXNwYWNlVVJJTm9ybWFsaXplZCk7Ci0KLSAgICAgICAgICAgIC8vIHVzZSBjb21tb24gbmFtZXNwYWNlIGNvZGUgd2l0aCBhIHByZWZpeCA9PSBudWxsIGZvciB4bWxucz0iLi4uIgotICAgICAgICAgICAgd3JpdGVuYW1lc3BhY2UobnVsbCwgbmFtZXNwYWNlVVJJTm9ybWFsaXplZCk7Ci0gICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBYTUxTdHJlYW1FeGNlcHRpb24oZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCB3cml0ZUVtcHR5RWxlbWVudChTdHJpbmcgbG9jYWxOYW1lKSB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGlmIChmU3RhcnRUYWdPcGVuZWQpIHsKLSAgICAgICAgICAgICAgICBjbG9zZVN0YXJ0VGFnKCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIG9wZW5TdGFydFRhZygpOwotICAgICAgICAgICAgZkVsZW1lbnRTdGFjay5wdXNoKG51bGwsIGxvY2FsTmFtZSwgbnVsbCwgbnVsbCwgdHJ1ZSk7Ci0gICAgICAgICAgICBmSW50ZXJuYWxOYW1lc3BhY2VDb250ZXh0LnB1c2hDb250ZXh0KCk7Ci0KLSAgICAgICAgICAgIGlmICghZklzUmVwYWlyaW5nTmFtZXNwYWNlKSB7Ci0gICAgICAgICAgICAgICAgZldyaXRlci53cml0ZShsb2NhbE5hbWUpOwotICAgICAgICAgICAgfQotICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWE1MU3RyZWFtRXhjZXB0aW9uKGUpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgd3JpdGVFbXB0eUVsZW1lbnQoU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIGxvY2FsTmFtZSkKLSAgICAgICAgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChuYW1lc3BhY2VVUkkgPT0gbnVsbCkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFhNTFN0cmVhbUV4Y2VwdGlvbigiTmFtZXNwYWNlVVJJIGNhbm5vdCBiZSBudWxsIik7Ci0gICAgICAgIH0KLQotICAgICAgICBuYW1lc3BhY2VVUkkgPSBmU3ltYm9sVGFibGUuYWRkU3ltYm9sKG5hbWVzcGFjZVVSSSk7Ci0KLSAgICAgICAgU3RyaW5nIHByZWZpeCA9IGZOYW1lc3BhY2VDb250ZXh0LmdldFByZWZpeChuYW1lc3BhY2VVUkkpOwotICAgICAgICB3cml0ZUVtcHR5RWxlbWVudChwcmVmaXgsIGxvY2FsTmFtZSwgbmFtZXNwYWNlVVJJKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCB3cml0ZUVtcHR5RWxlbWVudChTdHJpbmcgcHJlZml4LCBTdHJpbmcgbG9jYWxOYW1lLAotICAgICAgICBTdHJpbmcgbmFtZXNwYWNlVVJJKSB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGlmIChsb2NhbE5hbWUgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBYTUxTdHJlYW1FeGNlcHRpb24oIkxvY2FsIE5hbWUgY2Fubm90IGJlIG51bGwiKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKG5hbWVzcGFjZVVSSSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFhNTFN0cmVhbUV4Y2VwdGlvbigiTmFtZXNwYWNlVVJJIGNhbm5vdCBiZSBudWxsIik7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmIChwcmVmaXggIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHByZWZpeCA9IGZTeW1ib2xUYWJsZS5hZGRTeW1ib2wocHJlZml4KTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgbmFtZXNwYWNlVVJJID0gZlN5bWJvbFRhYmxlLmFkZFN5bWJvbChuYW1lc3BhY2VVUkkpOwotCi0gICAgICAgICAgICBpZiAoZlN0YXJ0VGFnT3BlbmVkKSB7Ci0gICAgICAgICAgICAgICAgY2xvc2VTdGFydFRhZygpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBvcGVuU3RhcnRUYWcoKTsKLQotICAgICAgICAgICAgZkVsZW1lbnRTdGFjay5wdXNoKHByZWZpeCwgbG9jYWxOYW1lLCBudWxsLCBuYW1lc3BhY2VVUkksIHRydWUpOwotICAgICAgICAgICAgZkludGVybmFsTmFtZXNwYWNlQ29udGV4dC5wdXNoQ29udGV4dCgpOwotCi0gICAgICAgICAgICBpZiAoIWZJc1JlcGFpcmluZ05hbWVzcGFjZSkgewotICAgICAgICAgICAgICAgIGlmIChwcmVmaXggPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWE1MU3RyZWFtRXhjZXB0aW9uKCJOYW1lc3BhY2VVUkkgIiArCi0gICAgICAgICAgICAgICAgICAgICAgICBuYW1lc3BhY2VVUkkgKyAiIGhhcyBub3QgYmVlbiBib3VuZCB0byBhbnkgcHJlZml4Iik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmICgocHJlZml4ICE9IG51bGwpICYmIChwcmVmaXggIT0gWE1MQ29uc3RhbnRzLkRFRkFVTFRfTlNfUFJFRklYKSkgewotICAgICAgICAgICAgICAgIGZXcml0ZXIud3JpdGUocHJlZml4KTsKLSAgICAgICAgICAgICAgICBmV3JpdGVyLndyaXRlKCI6Iik7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGZXcml0ZXIud3JpdGUobG9jYWxOYW1lKTsKLSAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFhNTFN0cmVhbUV4Y2VwdGlvbihlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHdyaXRlRW5kRG9jdW1lbnQoKSB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGlmIChmU3RhcnRUYWdPcGVuZWQpIHsKLSAgICAgICAgICAgICAgICBjbG9zZVN0YXJ0VGFnKCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIEVsZW1lbnRTdGF0ZSBlbGVtID0gbnVsbDsKLQotICAgICAgICAgICAgd2hpbGUgKCFmRWxlbWVudFN0YWNrLmVtcHR5KCkpIHsKLSAgICAgICAgICAgICAgICBlbGVtID0gKEVsZW1lbnRTdGF0ZSkgZkVsZW1lbnRTdGFjay5wb3AoKTsKLSAgICAgICAgICAgICAgICBmSW50ZXJuYWxOYW1lc3BhY2VDb250ZXh0LnBvcENvbnRleHQoKTsKLQotICAgICAgICAgICAgICAgIGlmIChlbGVtLmlzRW1wdHkpIHsKLSAgICAgICAgICAgICAgICAgICAgLy9mV3JpdGVyLndyaXRlKENMT1NFX0VNUFRZX0VMRU1FTlQpOwotICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIGZXcml0ZXIud3JpdGUoT1BFTl9FTkRfVEFHKTsKLQotICAgICAgICAgICAgICAgICAgICBpZiAoKGVsZW0ucHJlZml4ICE9IG51bGwpICYmICEoZWxlbS5wcmVmaXgpLmVxdWFscygiIikpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZXcml0ZXIud3JpdGUoZWxlbS5wcmVmaXgpOwotICAgICAgICAgICAgICAgICAgICAgICAgZldyaXRlci53cml0ZSgiOiIpOwotICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgZldyaXRlci53cml0ZShlbGVtLmxvY2FscGFydCk7Ci0gICAgICAgICAgICAgICAgICAgIGZXcml0ZXIud3JpdGUoQ0xPU0VfRU5EX1RBRyk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWE1MU3RyZWFtRXhjZXB0aW9uKGUpOwotICAgICAgICB9IGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFhNTFN0cmVhbUV4Y2VwdGlvbigiTm8gbW9yZSBlbGVtZW50cyB0byB3cml0ZSIpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgd3JpdGVFbmRFbGVtZW50KCkgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbiB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBpZiAoZlN0YXJ0VGFnT3BlbmVkKSB7Ci0gICAgICAgICAgICAgICAgY2xvc2VTdGFydFRhZygpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBFbGVtZW50U3RhdGUgY3VycmVudEVsZW1lbnQgPSAoRWxlbWVudFN0YXRlKSBmRWxlbWVudFN0YWNrLnBvcCgpOwotCi0gICAgICAgICAgICBpZiAoY3VycmVudEVsZW1lbnQgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBYTUxTdHJlYW1FeGNlcHRpb24oIk5vIGVsZW1lbnQgd2FzIGZvdW5kIHRvIHdyaXRlIik7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmIChjdXJyZW50RWxlbWVudC5pc0VtcHR5KSB7Ci0gICAgICAgICAgICAgICAgLy9mV3JpdGVyLndyaXRlKENMT1NFX0VNUFRZX0VMRU1FTlQpOwotICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgZldyaXRlci53cml0ZShPUEVOX0VORF9UQUcpOwotCi0gICAgICAgICAgICBpZiAoKGN1cnJlbnRFbGVtZW50LnByZWZpeCAhPSBudWxsKSAmJgotICAgICAgICAgICAgICAgICAgICAhKGN1cnJlbnRFbGVtZW50LnByZWZpeCkuZXF1YWxzKCIiKSkgewotICAgICAgICAgICAgICAgIGZXcml0ZXIud3JpdGUoY3VycmVudEVsZW1lbnQucHJlZml4KTsKLSAgICAgICAgICAgICAgICBmV3JpdGVyLndyaXRlKCI6Iik7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGZXcml0ZXIud3JpdGUoY3VycmVudEVsZW1lbnQubG9jYWxwYXJ0KTsKLSAgICAgICAgICAgIGZXcml0ZXIud3JpdGUoQ0xPU0VfRU5EX1RBRyk7Ci0gICAgICAgICAgICBmSW50ZXJuYWxOYW1lc3BhY2VDb250ZXh0LnBvcENvbnRleHQoKTsKLSAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFhNTFN0cmVhbUV4Y2VwdGlvbihlKTsKLSAgICAgICAgfSBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBYTUxTdHJlYW1FeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgICJObyBlbGVtZW50IHdhcyBmb3VuZCB0byB3cml0ZTogIgotICAgICAgICAgICAgICAgICAgICArIGUudG9TdHJpbmcoKSwgZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCB3cml0ZUVudGl0eVJlZihTdHJpbmcgcmVmTmFtZSkgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbiB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBpZiAoZlN0YXJ0VGFnT3BlbmVkKSB7Ci0gICAgICAgICAgICAgICAgY2xvc2VTdGFydFRhZygpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBmV3JpdGVyLndyaXRlKCcmJyk7Ci0gICAgICAgICAgICBmV3JpdGVyLndyaXRlKHJlZk5hbWUpOwotICAgICAgICAgICAgZldyaXRlci53cml0ZSgnOycpOwotICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWE1MU3RyZWFtRXhjZXB0aW9uKGUpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogV3JpdGUgYSBOYW1lc3BhY2UgZGVjbGFyYXRpb24uCi0gICAgICoKLSAgICAgKiBJZiBuYW1lc3BhY2VVUkkgPT0gbnVsbCwKLSAgICAgKiB0aGVuIGl0IGlzIGFzc3VtZWQgdG8gYmUgZXF1aXZpbGVudCB0byB7QGxpbmsgWE1MQ29uc3RhbnRzLk5VTExfTlNfVVJJfSwKLSAgICAgKiBpLmUuIHRoZXJlIGlzIG5vIE5hbWVzcGFjZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBwcmVmaXggUHJlZml4IHRvIGJpbmQuCi0gICAgICogQHBhcmFtIG5hbWVzcGFjZVVSSSBOYW1lc3BhY2VVUkkgdG8gZGVjbGFyZS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uCi0gICAgICoKLSAgICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy14bWwtbmFtZXMvI2RlZmF1bHRpbmciPgotICAgICAqICAgTmFtZXNwYWNlcyBpbiBYTUwsIDUuMiBOYW1lc3BhY2UgRGVmYXVsdGluZzwvYT4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB3cml0ZU5hbWVzcGFjZShTdHJpbmcgcHJlZml4LCBTdHJpbmcgbmFtZXNwYWNlVVJJKQotICAgICAgICB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uIHsKLQotICAgICAgICAvLyBub3JtYWxpemUgbmFtZXNwYWNlVVJJCi0gICAgICAgIFN0cmluZyBuYW1lc3BhY2VVUklOb3JtYWxpemVkID0gbnVsbDsKLSAgICAgICAgaWYgKG5hbWVzcGFjZVVSSSA9PSBudWxsKSB7Ci0gICAgICAgICAgICBuYW1lc3BhY2VVUklOb3JtYWxpemVkID0gIiI7IC8vIFhNTENvbnN0YW50cy5OVUxMX05TX1VSSQotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgbmFtZXNwYWNlVVJJTm9ybWFsaXplZCA9IG5hbWVzcGFjZVVSSTsKLSAgICAgICAgfQotCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBRTmFtZSBxbmFtZSA9IG51bGw7Ci0KLSAgICAgICAgICAgIGlmICghZlN0YXJ0VGFnT3BlbmVkKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgICAgICJJbnZhbGlkIHN0YXRlOiBzdGFydCB0YWcgaXMgbm90IG9wZW5lZCBhdCB3cml0ZU5hbWVzcGFjZSgiCi0gICAgICAgICAgICAgICAgICAgICAgICArIHByZWZpeAotICAgICAgICAgICAgICAgICAgICAgICAgKyAiLCAiCi0gICAgICAgICAgICAgICAgICAgICAgICArIG5hbWVzcGFjZVVSSU5vcm1hbGl6ZWQKLSAgICAgICAgICAgICAgICAgICAgICAgICsgIikiKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gaXMgdGhpcyB0aGUgZGVmYXVsdCBOYW1lc3BhY2U/Ci0gICAgICAgICAgICBpZiAocHJlZml4ID09IG51bGwKLSAgICAgICAgICAgICAgICAgICAgfHwgcHJlZml4LmVxdWFscyhYTUxDb25zdGFudHMuREVGQVVMVF9OU19QUkVGSVgpCi0gICAgICAgICAgICAgICAgICAgIHx8IHByZWZpeC5lcXVhbHMoWE1MQ29uc3RhbnRzLlhNTE5TX0FUVFJJQlVURSkpIHsKLSAgICAgICAgICAgICAgICB3cml0ZURlZmF1bHROYW1lc3BhY2UobmFtZXNwYWNlVVJJTm9ybWFsaXplZCk7Ci0gICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAocHJlZml4LmVxdWFscyhYTUxDb25zdGFudHMuWE1MX05TX1BSRUZJWCkgJiYgbmFtZXNwYWNlVVJJTm9ybWFsaXplZC5lcXVhbHMoWE1MQ29uc3RhbnRzLlhNTF9OU19VUkkpKQotICAgICAgICAgICAgICAgIHJldHVybjsKLQotICAgICAgICAgICAgcHJlZml4ID0gZlN5bWJvbFRhYmxlLmFkZFN5bWJvbChwcmVmaXgpOwotICAgICAgICAgICAgbmFtZXNwYWNlVVJJTm9ybWFsaXplZCA9IGZTeW1ib2xUYWJsZS5hZGRTeW1ib2wobmFtZXNwYWNlVVJJTm9ybWFsaXplZCk7Ci0KLSAgICAgICAgICAgIGlmIChmSXNSZXBhaXJpbmdOYW1lc3BhY2UpIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgdG1wVVJJID0gZkludGVybmFsTmFtZXNwYWNlQ29udGV4dC5nZXRVUkkocHJlZml4KTsKLQotICAgICAgICAgICAgICAgIGlmICgodG1wVVJJICE9IG51bGwpICYmICh0bXBVUkkgPT0gbmFtZXNwYWNlVVJJTm9ybWFsaXplZCkpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIHFuYW1lID0gbmV3IFFOYW1lKCk7Ci0gICAgICAgICAgICAgICAgcW5hbWUuc2V0VmFsdWVzKHByZWZpeCwgWE1MQ29uc3RhbnRzLlhNTE5TX0FUVFJJQlVURSwgbnVsbCwKLSAgICAgICAgICAgICAgICAgICAgbmFtZXNwYWNlVVJJTm9ybWFsaXplZCk7Ci0gICAgICAgICAgICAgICAgZk5hbWVzcGFjZURlY2xzLmFkZChxbmFtZSk7Ci0KLSAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICB9Ci0KLQotICAgICAgICAgICAgaWYgKGZJbnRlcm5hbE5hbWVzcGFjZUNvbnRleHQuY29udGFpbnNQcmVmaXhJbkN1cnJlbnRDb250ZXh0KHByZWZpeCkpewotCi0gICAgICAgICAgICAgICAgU3RyaW5nIHRtcCA9IGZJbnRlcm5hbE5hbWVzcGFjZUNvbnRleHQuZ2V0VVJJKHByZWZpeCk7Ci0KLSAgICAgICAgICAgICAgICBpZiAodG1wICE9IG51bGwgJiYgdG1wICE9IG5hbWVzcGFjZVVSSU5vcm1hbGl6ZWQpIHsKLQotICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWE1MU3RyZWFtRXhjZXB0aW9uKCJwcmVmaXggIitwcmVmaXgrCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIiBoYXMgYmVlbiBhbHJlYWR5IGJvdW5kIHRvICIgK3RtcCArCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIi4gUmViaW5kaW5nIGl0IHRvICIrIG5hbWVzcGFjZVVSSU5vcm1hbGl6ZWQrCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIiBpcyBhbiBlcnJvciIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgZkludGVybmFsTmFtZXNwYWNlQ29udGV4dC5kZWNsYXJlUHJlZml4KHByZWZpeCwgbmFtZXNwYWNlVVJJTm9ybWFsaXplZCk7Ci0gICAgICAgICAgICB3cml0ZW5hbWVzcGFjZShwcmVmaXgsIG5hbWVzcGFjZVVSSU5vcm1hbGl6ZWQpOwotCi0gICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBYTUxTdHJlYW1FeGNlcHRpb24oZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgd3JpdGVuYW1lc3BhY2UoU3RyaW5nIHByZWZpeCwgU3RyaW5nIG5hbWVzcGFjZVVSSSkKLSAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKLSAgICAgICAgZldyaXRlci53cml0ZSgiIHhtbG5zIik7Ci0KLSAgICAgICAgaWYgKChwcmVmaXggIT0gbnVsbCkgJiYgKHByZWZpeCAhPSBYTUxDb25zdGFudHMuREVGQVVMVF9OU19QUkVGSVgpKSB7Ci0gICAgICAgICAgICBmV3JpdGVyLndyaXRlKCI6Iik7Ci0gICAgICAgICAgICBmV3JpdGVyLndyaXRlKHByZWZpeCk7Ci0gICAgICAgIH0KLQotICAgICAgICBmV3JpdGVyLndyaXRlKCI9XCIiKTsKLSAgICAgICAgd3JpdGVYTUxDb250ZW50KAotICAgICAgICAgICAgICAgIG5hbWVzcGFjZVVSSSwKLSAgICAgICAgICAgICAgICB0cnVlLCAgIC8vIHRydWUgPSBlc2NhcGVDaGFycwotICAgICAgICAgICAgICAgIHRydWUpOyAgLy8gdHJ1ZSA9IGVzY2FwZURvdWJsZVF1b3RlcwotICAgICAgICBmV3JpdGVyLndyaXRlKCJcIiIpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHdyaXRlUHJvY2Vzc2luZ0luc3RydWN0aW9uKFN0cmluZyB0YXJnZXQpCi0gICAgICAgIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24gewotICAgICAgICB0cnkgewotICAgICAgICAgICAgaWYgKGZTdGFydFRhZ09wZW5lZCkgewotICAgICAgICAgICAgICAgIGNsb3NlU3RhcnRUYWcoKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKHRhcmdldCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZldyaXRlci53cml0ZSgiPD8iKTsKLSAgICAgICAgICAgICAgICBmV3JpdGVyLndyaXRlKHRhcmdldCk7Ci0gICAgICAgICAgICAgICAgZldyaXRlci53cml0ZSgiPz4iKTsKLQotICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFhNTFN0cmVhbUV4Y2VwdGlvbihlKTsKLSAgICAgICAgfQotCi0gICAgICAgIHRocm93IG5ldyBYTUxTdHJlYW1FeGNlcHRpb24oIlBJIHRhcmdldCBjYW5ub3QgYmUgbnVsbCIpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBwYXJhbSB0YXJnZXQKLSAgICAgKiBAcGFyYW0gZGF0YQotICAgICAqIEB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgd3JpdGVQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oU3RyaW5nIHRhcmdldCwgU3RyaW5nIGRhdGEpCi0gICAgICAgIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24gewotICAgICAgICB0cnkgewotICAgICAgICAgICAgaWYgKGZTdGFydFRhZ09wZW5lZCkgewotICAgICAgICAgICAgICAgIGNsb3NlU3RhcnRUYWcoKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKCh0YXJnZXQgPT0gbnVsbCkgfHwgKGRhdGEgPT0gbnVsbCkpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWE1MU3RyZWFtRXhjZXB0aW9uKCJQSSB0YXJnZXQgY2Fubm90IGJlIG51bGwiKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgZldyaXRlci53cml0ZSgiPD8iKTsKLSAgICAgICAgICAgIGZXcml0ZXIud3JpdGUodGFyZ2V0KTsKLSAgICAgICAgICAgIGZXcml0ZXIud3JpdGUoU1BBQ0UpOwotICAgICAgICAgICAgZldyaXRlci53cml0ZShkYXRhKTsKLSAgICAgICAgICAgIGZXcml0ZXIud3JpdGUoIj8+Iik7Ci0gICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBYTUxTdHJlYW1FeGNlcHRpb24oZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHdyaXRlU3RhcnREb2N1bWVudCgpIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24gewotICAgICAgICB0cnkgewotICAgICAgICAgICAgZldyaXRlci53cml0ZShERUZBVUxUX1hNTERFQ0wpOwotICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFhNTFN0cmVhbUV4Y2VwdGlvbihleCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBAcGFyYW0gdmVyc2lvbgotICAgICAqIEB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgd3JpdGVTdGFydERvY3VtZW50KFN0cmluZyB2ZXJzaW9uKSB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGlmICgodmVyc2lvbiA9PSBudWxsKSB8fCB2ZXJzaW9uLmVxdWFscygiIikpIHsKLSAgICAgICAgICAgICAgICB3cml0ZVN0YXJ0RG9jdW1lbnQoKTsKLQotICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgZldyaXRlci53cml0ZSgiPD94bWwgdmVyc2lvbj1cIiIpOwotICAgICAgICAgICAgZldyaXRlci53cml0ZSh2ZXJzaW9uKTsKLSAgICAgICAgICAgIGZXcml0ZXIud3JpdGUoIlwiIik7Ci0KLSAgICAgICAgICAgIC8vZldyaXRlci53cml0ZShERUZBVUxUX0VOQ09ESU5HKTsKLSAgICAgICAgICAgIGZXcml0ZXIud3JpdGUoIj8+Iik7Ci0gICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWE1MU3RyZWFtRXhjZXB0aW9uKGV4KTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBwYXJhbSBlbmNvZGluZwotICAgICAqIEBwYXJhbSB2ZXJzaW9uCi0gICAgICogQHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB3cml0ZVN0YXJ0RG9jdW1lbnQoU3RyaW5nIGVuY29kaW5nLCBTdHJpbmcgdmVyc2lvbikKLSAgICAgICAgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbiB7Ci0gICAgICAgIC8vUmV2aXNpdCA6IFdoYXQgYWJvdXQgc3RhbmRhbG9uZSA/Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBpZiAoKGVuY29kaW5nID09IG51bGwpICYmICh2ZXJzaW9uID09IG51bGwpKSB7Ci0gICAgICAgICAgICAgICAgd3JpdGVTdGFydERvY3VtZW50KCk7Ci0KLSAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmIChlbmNvZGluZyA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgd3JpdGVTdGFydERvY3VtZW50KHZlcnNpb24pOwotCi0gICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBTdHJpbmcgc3RyZWFtRW5jb2RpbmcgPSBudWxsOwotICAgICAgICAgICAgaWYgKGZXcml0ZXIgaW5zdGFuY2VvZiBPdXRwdXRTdHJlYW1Xcml0ZXIpIHsKLSAgICAgICAgICAgICAgICBzdHJlYW1FbmNvZGluZyA9ICgoT3V0cHV0U3RyZWFtV3JpdGVyKSBmV3JpdGVyKS5nZXRFbmNvZGluZygpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoZldyaXRlciBpbnN0YW5jZW9mIFVURjhPdXRwdXRTdHJlYW1Xcml0ZXIpIHsKLSAgICAgICAgICAgICAgICBzdHJlYW1FbmNvZGluZyA9ICgoVVRGOE91dHB1dFN0cmVhbVdyaXRlcikgZldyaXRlcikuZ2V0RW5jb2RpbmcoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKGZXcml0ZXIgaW5zdGFuY2VvZiBYTUxXcml0ZXIpIHsKLSAgICAgICAgICAgICAgICBzdHJlYW1FbmNvZGluZyA9ICgoT3V0cHV0U3RyZWFtV3JpdGVyKSAoKFhNTFdyaXRlcilmV3JpdGVyKS5nZXRXcml0ZXIoKSkuZ2V0RW5jb2RpbmcoKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKHN0cmVhbUVuY29kaW5nICE9IG51bGwgJiYgIXN0cmVhbUVuY29kaW5nLmVxdWFsc0lnbm9yZUNhc2UoZW5jb2RpbmcpKSB7Ci0gICAgICAgICAgICAgICAgLy8gSWYgdGhlIGVxdWFsaXR5IGNoZWNrIGZhaWxlZCwgY2hlY2sgZm9yIGNoYXJzZXQgZW5jb2RpbmcgYWxpYXNlcwotICAgICAgICAgICAgICAgIGJvb2xlYW4gZm91bmRBbGlhcyA9IGZhbHNlOwotICAgICAgICAgICAgICAgIFNldCBhbGlhc2VzID0gQ2hhcnNldC5mb3JOYW1lKGVuY29kaW5nKS5hbGlhc2VzKCk7Ci0gICAgICAgICAgICAgICAgZm9yIChJdGVyYXRvciBpdCA9IGFsaWFzZXMuaXRlcmF0b3IoKTsgIWZvdW5kQWxpYXMgJiYgaXQuaGFzTmV4dCgpOyApIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKHN0cmVhbUVuY29kaW5nLmVxdWFsc0lnbm9yZUNhc2UoKFN0cmluZykgaXQubmV4dCgpKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgZm91bmRBbGlhcyA9IHRydWU7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLy8gSWYgbm8gYWxpYXMgbWF0Y2hlcyB0aGUgZW5jb2RpbmcgbmFtZSwgdGhlbiByZXBvcnQgZXJyb3IKLSAgICAgICAgICAgICAgICBpZiAoIWZvdW5kQWxpYXMpIHsKLSAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFhNTFN0cmVhbUV4Y2VwdGlvbigiVW5kZXJseWluZyBzdHJlYW0gZW5jb2RpbmcgJyIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICArIHN0cmVhbUVuY29kaW5nCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiJyBhbmQgaW5wdXQgcGFyYW10ZXIgZm9yIHdyaXRlU3RhcnREb2N1bWVudCgpIG1ldGhvZCAnIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgZW5jb2RpbmcgKyAiJyBkbyBub3QgbWF0Y2guIik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0KLSAgICAgICAgICAgIGZXcml0ZXIud3JpdGUoIjw/eG1sIHZlcnNpb249XCIiKTsKLQotICAgICAgICAgICAgaWYgKCh2ZXJzaW9uID09IG51bGwpIHx8IHZlcnNpb24uZXF1YWxzKCIiKSkgewotICAgICAgICAgICAgICAgIGZXcml0ZXIud3JpdGUoREVGQVVMVF9YTUxfVkVSU0lPTik7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIGZXcml0ZXIud3JpdGUodmVyc2lvbik7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmICghZW5jb2RpbmcuZXF1YWxzKCIiKSkgewotICAgICAgICAgICAgICAgIGZXcml0ZXIud3JpdGUoIlwiIGVuY29kaW5nPVwiIik7Ci0gICAgICAgICAgICAgICAgZldyaXRlci53cml0ZShlbmNvZGluZyk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGZXcml0ZXIud3JpdGUoIlwiPz4iKTsKLSAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBYTUxTdHJlYW1FeGNlcHRpb24oZXgpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHBhcmFtIGxvY2FsTmFtZQotICAgICAqIEB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgd3JpdGVTdGFydEVsZW1lbnQoU3RyaW5nIGxvY2FsTmFtZSkgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbiB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBpZiAobG9jYWxOYW1lID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWE1MU3RyZWFtRXhjZXB0aW9uKCJMb2NhbCBOYW1lIGNhbm5vdCBiZSBudWxsIik7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmIChmU3RhcnRUYWdPcGVuZWQpIHsKLSAgICAgICAgICAgICAgICBjbG9zZVN0YXJ0VGFnKCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIG9wZW5TdGFydFRhZygpOwotICAgICAgICAgICAgZkVsZW1lbnRTdGFjay5wdXNoKG51bGwsIGxvY2FsTmFtZSwgbnVsbCwgbnVsbCwgZmFsc2UpOwotICAgICAgICAgICAgZkludGVybmFsTmFtZXNwYWNlQ29udGV4dC5wdXNoQ29udGV4dCgpOwotCi0gICAgICAgICAgICBpZiAoZklzUmVwYWlyaW5nTmFtZXNwYWNlKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBmV3JpdGVyLndyaXRlKGxvY2FsTmFtZSk7Ci0gICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWE1MU3RyZWFtRXhjZXB0aW9uKGV4KTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkKLSAgICAgKiBAcGFyYW0gbG9jYWxOYW1lCi0gICAgICogQHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB3cml0ZVN0YXJ0RWxlbWVudChTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgbG9jYWxOYW1lKQotICAgICAgICB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKGxvY2FsTmFtZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWE1MU3RyZWFtRXhjZXB0aW9uKCJMb2NhbCBOYW1lIGNhbm5vdCBiZSBudWxsIik7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAobmFtZXNwYWNlVVJJID09IG51bGwpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBYTUxTdHJlYW1FeGNlcHRpb24oIk5hbWVzcGFjZVVSSSBjYW5ub3QgYmUgbnVsbCIpOwotICAgICAgICB9Ci0KLSAgICAgICAgbmFtZXNwYWNlVVJJID0gZlN5bWJvbFRhYmxlLmFkZFN5bWJvbChuYW1lc3BhY2VVUkkpOwotCi0gICAgICAgIFN0cmluZyBwcmVmaXggPSBudWxsOwotCi0gICAgICAgIGlmICghZklzUmVwYWlyaW5nTmFtZXNwYWNlKSB7Ci0gICAgICAgICAgICBwcmVmaXggPSBmTmFtZXNwYWNlQ29udGV4dC5nZXRQcmVmaXgobmFtZXNwYWNlVVJJKTsKLQotICAgICAgICAgICAgaWYgKHByZWZpeCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgcHJlZml4ID0gZlN5bWJvbFRhYmxlLmFkZFN5bWJvbChwcmVmaXgpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgd3JpdGVTdGFydEVsZW1lbnQocHJlZml4LCBsb2NhbE5hbWUsIG5hbWVzcGFjZVVSSSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHBhcmFtIHByZWZpeAotICAgICAqIEBwYXJhbSBsb2NhbE5hbWUKLSAgICAgKiBAcGFyYW0gbmFtZXNwYWNlVVJJCi0gICAgICogQHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB3cml0ZVN0YXJ0RWxlbWVudChTdHJpbmcgcHJlZml4LCBTdHJpbmcgbG9jYWxOYW1lLAotICAgICAgICBTdHJpbmcgbmFtZXNwYWNlVVJJKSB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGlmIChsb2NhbE5hbWUgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBYTUxTdHJlYW1FeGNlcHRpb24oIkxvY2FsIE5hbWUgY2Fubm90IGJlIG51bGwiKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKG5hbWVzcGFjZVVSSSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFhNTFN0cmVhbUV4Y2VwdGlvbigiTmFtZXNwYWNlVVJJIGNhbm5vdCBiZSBudWxsIik7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmICghZklzUmVwYWlyaW5nTmFtZXNwYWNlKSB7Ci0gICAgICAgICAgICAgICAgaWYgKHByZWZpeCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBYTUxTdHJlYW1FeGNlcHRpb24oIlByZWZpeCBjYW5ub3QgYmUgbnVsbCIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKGZTdGFydFRhZ09wZW5lZCkgewotICAgICAgICAgICAgICAgIGNsb3NlU3RhcnRUYWcoKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgb3BlblN0YXJ0VGFnKCk7Ci0gICAgICAgICAgICBuYW1lc3BhY2VVUkkgPSBmU3ltYm9sVGFibGUuYWRkU3ltYm9sKG5hbWVzcGFjZVVSSSk7Ci0KLSAgICAgICAgICAgIGlmIChwcmVmaXggIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHByZWZpeCA9IGZTeW1ib2xUYWJsZS5hZGRTeW1ib2wocHJlZml4KTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgZkVsZW1lbnRTdGFjay5wdXNoKHByZWZpeCwgbG9jYWxOYW1lLCBudWxsLCBuYW1lc3BhY2VVUkksIGZhbHNlKTsKLSAgICAgICAgICAgIGZJbnRlcm5hbE5hbWVzcGFjZUNvbnRleHQucHVzaENvbnRleHQoKTsKLQotICAgICAgICAgICAgU3RyaW5nIHRtcFByZWZpeCA9IGZOYW1lc3BhY2VDb250ZXh0LmdldFByZWZpeChuYW1lc3BhY2VVUkkpOwotCi0KLSAgICAgICAgICAgIGlmICgocHJlZml4ICE9IG51bGwpICYmCi0gICAgICAgICAgICAgICAgICAgICgodG1wUHJlZml4ID09IG51bGwpIHx8ICFwcmVmaXguZXF1YWxzKHRtcFByZWZpeCkpKSB7Ci0gICAgICAgICAgICAgICAgZkludGVybmFsTmFtZXNwYWNlQ29udGV4dC5kZWNsYXJlUHJlZml4KHByZWZpeCwgbmFtZXNwYWNlVVJJKTsKLQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAoZklzUmVwYWlyaW5nTmFtZXNwYWNlKSB7Ci0gICAgICAgICAgICAgICAgaWYgKChwcmVmaXggPT0gbnVsbCkgfHwKLSAgICAgICAgICAgICAgICAgICAgICAgICgodG1wUHJlZml4ICE9IG51bGwpICYmIHByZWZpeC5lcXVhbHModG1wUHJlZml4KSkpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIFFOYW1lIHFuYW1lID0gbmV3IFFOYW1lKCk7Ci0gICAgICAgICAgICAgICAgcW5hbWUuc2V0VmFsdWVzKHByZWZpeCwgWE1MQ29uc3RhbnRzLlhNTE5TX0FUVFJJQlVURSwgbnVsbCwKLSAgICAgICAgICAgICAgICAgICAgbmFtZXNwYWNlVVJJKTsKLSAgICAgICAgICAgICAgICBmTmFtZXNwYWNlRGVjbHMuYWRkKHFuYW1lKTsKLQotICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKChwcmVmaXggIT0gbnVsbCkgJiYgKHByZWZpeCAhPSBYTUxDb25zdGFudHMuREVGQVVMVF9OU19QUkVGSVgpKSB7Ci0gICAgICAgICAgICAgICAgZldyaXRlci53cml0ZShwcmVmaXgpOwotICAgICAgICAgICAgICAgIGZXcml0ZXIud3JpdGUoIjoiKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgZldyaXRlci53cml0ZShsb2NhbE5hbWUpOwotCi0gICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWE1MU3RyZWFtRXhjZXB0aW9uKGV4KTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFdyaXRlcyBjaGFyYWN0ZXIgcmVmZXJlbmNlIGluIGhleCBmb3JtYXQuCi0gICAgICovCi0gICAgcHJpdmF0ZSB2b2lkIHdyaXRlQ2hhclJlZihpbnQgY29kZVBvaW50KSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgICAgICBmV3JpdGVyLndyaXRlKCAiJiN4IiApOwotICAgICAgICBmV3JpdGVyLndyaXRlKCBJbnRlZ2VyLnRvSGV4U3RyaW5nKGNvZGVQb2ludCkgKTsKLSAgICAgICAgZldyaXRlci53cml0ZSggJzsnICk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogV3JpdGVzIFhNTCBjb250ZW50IHRvIHVuZGVybHlpbmcgd3JpdGVyLiBFc2NhcGVzIGNoYXJhY3RlcnMgdW5sZXNzCi0gICAgICogZXNjYXBpbmcgY2hhcmFjdGVyIGZlYXR1cmUgaXMgdHVybmVkIG9mZi4KLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgd3JpdGVYTUxDb250ZW50KGNoYXJbXSBjb250ZW50LCBpbnQgc3RhcnQsIGludCBsZW5ndGgsCi0gICAgICAgIGJvb2xlYW4gZXNjYXBlQ2hhcnMpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgIGlmICghZXNjYXBlQ2hhcnMpIHsKLSAgICAgICAgICAgIGZXcml0ZXIud3JpdGUoY29udGVudCwgc3RhcnQsIGxlbmd0aCk7Ci0KLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIEluZGV4IG9mIHRoZSBuZXh0IGNoYXIgdG8gYmUgd3JpdHRlbgotICAgICAgICBpbnQgc3RhcnRXcml0ZVBvcyA9IHN0YXJ0OwotCi0gICAgICAgIGZpbmFsIGludCBlbmQgPSBzdGFydCArIGxlbmd0aDsKLQotICAgICAgICBmb3IgKGludCBpbmRleCA9IHN0YXJ0OyBpbmRleCA8IGVuZDsgaW5kZXgrKykgewotICAgICAgICAgICAgY2hhciBjaCA9IGNvbnRlbnRbaW5kZXhdOwotCi0gICAgICAgICAgICBpZiAoZkVuY29kZXIgIT0gbnVsbCAmJiAhZkVuY29kZXIuY2FuRW5jb2RlKGNoKSl7Ci0gICAgICAgICAgICAgICAgZldyaXRlci53cml0ZShjb250ZW50LCBzdGFydFdyaXRlUG9zLCBpbmRleCAtIHN0YXJ0V3JpdGVQb3MgKTsKLQotICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIGN1cnJlbnQgYW5kIG5leHQgY2hhcmFjdGVycyBmb3JtcyBhIHN1cnJvZ2F0ZSBwYWlyCi0gICAgICAgICAgICAgICAgLy8gYW5kIGVzY2FwZSBpdCB0byBhdm9pZCBnZW5lcmF0aW9uIG9mIGludmFsaWQgeG1sIGNvbnRlbnQKLSAgICAgICAgICAgICAgICBpZiAoIGluZGV4ICE9IGVuZCAtIDEgJiYgQ2hhcmFjdGVyLmlzU3Vycm9nYXRlUGFpcihjaCwgY29udGVudFtpbmRleCsxXSkpIHsKLSAgICAgICAgICAgICAgICAgICAgd3JpdGVDaGFyUmVmKENoYXJhY3Rlci50b0NvZGVQb2ludChjaCwgY29udGVudFtpbmRleCsxXSkpOwotICAgICAgICAgICAgICAgICAgICBpbmRleCsrOwotICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIHdyaXRlQ2hhclJlZihjaCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHN0YXJ0V3JpdGVQb3MgPSBpbmRleCArIDE7Ci0gICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIHN3aXRjaCAoY2gpIHsKLSAgICAgICAgICAgIGNhc2UgJzwnOgotICAgICAgICAgICAgICAgIGZXcml0ZXIud3JpdGUoY29udGVudCwgc3RhcnRXcml0ZVBvcywgaW5kZXggLSBzdGFydFdyaXRlUG9zKTsKLSAgICAgICAgICAgICAgICBmV3JpdGVyLndyaXRlKCImbHQ7Iik7Ci0gICAgICAgICAgICAgICAgc3RhcnRXcml0ZVBvcyA9IGluZGV4ICsgMTsKLQotICAgICAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgICAgICBjYXNlICcmJzoKLSAgICAgICAgICAgICAgICBmV3JpdGVyLndyaXRlKGNvbnRlbnQsIHN0YXJ0V3JpdGVQb3MsIGluZGV4IC0gc3RhcnRXcml0ZVBvcyk7Ci0gICAgICAgICAgICAgICAgZldyaXRlci53cml0ZSgiJmFtcDsiKTsKLSAgICAgICAgICAgICAgICBzdGFydFdyaXRlUG9zID0gaW5kZXggKyAxOwotCi0gICAgICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgICAgIGNhc2UgJz4nOgotICAgICAgICAgICAgICAgIGZXcml0ZXIud3JpdGUoY29udGVudCwgc3RhcnRXcml0ZVBvcywgaW5kZXggLSBzdGFydFdyaXRlUG9zKTsKLSAgICAgICAgICAgICAgICBmV3JpdGVyLndyaXRlKCImZ3Q7Iik7Ci0gICAgICAgICAgICAgICAgc3RhcnRXcml0ZVBvcyA9IGluZGV4ICsgMTsKLQotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gV3JpdGUgYW55IHBlbmRpbmcgZGF0YQotICAgICAgICBmV3JpdGVyLndyaXRlKGNvbnRlbnQsIHN0YXJ0V3JpdGVQb3MsIGVuZCAtIHN0YXJ0V3JpdGVQb3MpOwotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCB3cml0ZVhNTENvbnRlbnQoU3RyaW5nIGNvbnRlbnQpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgIGlmICgoY29udGVudCAhPSBudWxsKSAmJiAoY29udGVudC5sZW5ndGgoKSA+IDApKSB7Ci0gICAgICAgICAgICB3cml0ZVhNTENvbnRlbnQoY29udGVudCwKLSAgICAgICAgICAgICAgICAgICAgZkVzY2FwZUNoYXJhY3RlcnMsICAvLyBib29sZWFuID0gZXNjYXBlQ2hhcnMKLSAgICAgICAgICAgICAgICAgICAgZmFsc2UpOyAgICAgICAgICAgICAvLyBmYWxzZSA9IGVzY2FwZURvdWJsZVF1b3RlcwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogV3JpdGVzIFhNTCBjb250ZW50IHRvIHVuZGVybHlpbmcgd3JpdGVyLiBFc2NhcGVzIGNoYXJhY3RlcnMgdW5sZXNzCi0gICAgICogZXNjYXBpbmcgY2hhcmFjdGVyIGZlYXR1cmUgaXMgdHVybmVkIG9mZi4KLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgd3JpdGVYTUxDb250ZW50KAotICAgICAgICAgICAgU3RyaW5nIGNvbnRlbnQsCi0gICAgICAgICAgICBib29sZWFuIGVzY2FwZUNoYXJzLAotICAgICAgICAgICAgYm9vbGVhbiBlc2NhcGVEb3VibGVRdW90ZXMpCi0gICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0KLSAgICAgICAgaWYgKCFlc2NhcGVDaGFycykgewotICAgICAgICAgICAgZldyaXRlci53cml0ZShjb250ZW50KTsKLQotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gSW5kZXggb2YgdGhlIG5leHQgY2hhciB0byBiZSB3cml0dGVuCi0gICAgICAgIGludCBzdGFydFdyaXRlUG9zID0gMDsKLQotICAgICAgICBmaW5hbCBpbnQgZW5kID0gY29udGVudC5sZW5ndGgoKTsKLQotICAgICAgICBmb3IgKGludCBpbmRleCA9IDA7IGluZGV4IDwgZW5kOyBpbmRleCsrKSB7Ci0gICAgICAgICAgICBjaGFyIGNoID0gY29udGVudC5jaGFyQXQoaW5kZXgpOwotCi0gICAgICAgICAgICBpZiAoZkVuY29kZXIgIT0gbnVsbCAmJiAhZkVuY29kZXIuY2FuRW5jb2RlKGNoKSl7Ci0gICAgICAgICAgICAgICAgZldyaXRlci53cml0ZShjb250ZW50LCBzdGFydFdyaXRlUG9zLCBpbmRleCAtIHN0YXJ0V3JpdGVQb3MgKTsKLQotICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIGN1cnJlbnQgYW5kIG5leHQgY2hhcmFjdGVycyBmb3JtcyBhIHN1cnJvZ2F0ZSBwYWlyCi0gICAgICAgICAgICAgICAgLy8gYW5kIGVzY2FwZSBpdCB0byBhdm9pZCBnZW5lcmF0aW9uIG9mIGludmFsaWQgeG1sIGNvbnRlbnQKLSAgICAgICAgICAgICAgICBpZiAoIGluZGV4ICE9IGVuZCAtIDEgJiYgQ2hhcmFjdGVyLmlzU3Vycm9nYXRlUGFpcihjaCwgY29udGVudC5jaGFyQXQoaW5kZXgrMSkpKSB7Ci0gICAgICAgICAgICAgICAgICAgIHdyaXRlQ2hhclJlZihDaGFyYWN0ZXIudG9Db2RlUG9pbnQoY2gsIGNvbnRlbnQuY2hhckF0KGluZGV4KzEpKSk7Ci0gICAgICAgICAgICAgICAgICAgIGluZGV4Kys7Ci0gICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgd3JpdGVDaGFyUmVmKGNoKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBzdGFydFdyaXRlUG9zID0gaW5kZXggKyAxOwotICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBzd2l0Y2ggKGNoKSB7Ci0gICAgICAgICAgICBjYXNlICc8JzoKLSAgICAgICAgICAgICAgICBmV3JpdGVyLndyaXRlKGNvbnRlbnQsIHN0YXJ0V3JpdGVQb3MsIGluZGV4IC0gc3RhcnRXcml0ZVBvcyk7Ci0gICAgICAgICAgICAgICAgZldyaXRlci53cml0ZSgiJmx0OyIpOwotICAgICAgICAgICAgICAgIHN0YXJ0V3JpdGVQb3MgPSBpbmRleCArIDE7Ci0KLSAgICAgICAgICAgICAgICBicmVhazsKLQotICAgICAgICAgICAgY2FzZSAnJic6Ci0gICAgICAgICAgICAgICAgZldyaXRlci53cml0ZShjb250ZW50LCBzdGFydFdyaXRlUG9zLCBpbmRleCAtIHN0YXJ0V3JpdGVQb3MpOwotICAgICAgICAgICAgICAgIGZXcml0ZXIud3JpdGUoIiZhbXA7Iik7Ci0gICAgICAgICAgICAgICAgc3RhcnRXcml0ZVBvcyA9IGluZGV4ICsgMTsKLQotICAgICAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgICAgICBjYXNlICc+JzoKLSAgICAgICAgICAgICAgICBmV3JpdGVyLndyaXRlKGNvbnRlbnQsIHN0YXJ0V3JpdGVQb3MsIGluZGV4IC0gc3RhcnRXcml0ZVBvcyk7Ci0gICAgICAgICAgICAgICAgZldyaXRlci53cml0ZSgiJmd0OyIpOwotICAgICAgICAgICAgICAgIHN0YXJ0V3JpdGVQb3MgPSBpbmRleCArIDE7Ci0KLSAgICAgICAgICAgICAgICBicmVhazsKLQotICAgICAgICAgICAgY2FzZSAnIic6Ci0gICAgICAgICAgICAgICAgZldyaXRlci53cml0ZShjb250ZW50LCBzdGFydFdyaXRlUG9zLCBpbmRleCAtIHN0YXJ0V3JpdGVQb3MpOwotICAgICAgICAgICAgICAgIGlmIChlc2NhcGVEb3VibGVRdW90ZXMpIHsKLSAgICAgICAgICAgICAgICAgICAgZldyaXRlci53cml0ZSgiJnF1b3Q7Iik7Ci0gICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgZldyaXRlci53cml0ZSgnIicpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBzdGFydFdyaXRlUG9zID0gaW5kZXggKyAxOwotCi0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBXcml0ZSBhbnkgcGVuZGluZyBkYXRhCi0gICAgICAgIGZXcml0ZXIud3JpdGUoY29udGVudCwgc3RhcnRXcml0ZVBvcywgZW5kIC0gc3RhcnRXcml0ZVBvcyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogbWFya3MgY2xvc2Ugb2Ygc3RhcnQgdGFnIGFuZCB3cml0ZXMgdGhlIHNhbWUgaW50byB0aGUgd3JpdGVyLgotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCBjbG9zZVN0YXJ0VGFnKCkgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbiB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBFbGVtZW50U3RhdGUgY3VycmVudEVsZW1lbnQgPSBmRWxlbWVudFN0YWNrLnBlZWsoKTsKLQotICAgICAgICAgICAgaWYgKGZJc1JlcGFpcmluZ05hbWVzcGFjZSkgewotICAgICAgICAgICAgICAgIHJlcGFpcigpOwotICAgICAgICAgICAgICAgIGNvcnJlY3RQcmVmaXgoY3VycmVudEVsZW1lbnQsIFhNTFN0cmVhbUNvbnN0YW50cy5TVEFSVF9FTEVNRU5UKTsKLQotICAgICAgICAgICAgICAgIGlmICgoY3VycmVudEVsZW1lbnQucHJlZml4ICE9IG51bGwpICYmCi0gICAgICAgICAgICAgICAgICAgICAgICAoY3VycmVudEVsZW1lbnQucHJlZml4ICE9IFhNTENvbnN0YW50cy5ERUZBVUxUX05TX1BSRUZJWCkpIHsKLSAgICAgICAgICAgICAgICAgICAgZldyaXRlci53cml0ZShjdXJyZW50RWxlbWVudC5wcmVmaXgpOwotICAgICAgICAgICAgICAgICAgICBmV3JpdGVyLndyaXRlKCI6Iik7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgZldyaXRlci53cml0ZShjdXJyZW50RWxlbWVudC5sb2NhbHBhcnQpOwotCi0gICAgICAgICAgICAgICAgaW50IGxlbiA9IGZOYW1lc3BhY2VEZWNscy5zaXplKCk7Ci0gICAgICAgICAgICAgICAgUU5hbWUgcW5hbWUgPSBudWxsOwotCi0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW47IGkrKykgewotICAgICAgICAgICAgICAgICAgICBxbmFtZSA9IChRTmFtZSkgZk5hbWVzcGFjZURlY2xzLmdldChpKTsKLQotICAgICAgICAgICAgICAgICAgICBpZiAocW5hbWUgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZJbnRlcm5hbE5hbWVzcGFjZUNvbnRleHQuZGVjbGFyZVByZWZpeChxbmFtZS5wcmVmaXgsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcW5hbWUudXJpKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlbmFtZXNwYWNlKHFuYW1lLnByZWZpeCwgcW5hbWUudXJpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIGZOYW1lc3BhY2VEZWNscy5jbGVhcigpOwotCi0gICAgICAgICAgICAgICAgQXR0cmlidXRlIGF0dHIgPSBudWxsOwotCi0gICAgICAgICAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBmQXR0cmlidXRlQ2FjaGUuc2l6ZSgpOyBqKyspIHsKLSAgICAgICAgICAgICAgICAgICAgYXR0ciA9IChBdHRyaWJ1dGUpIGZBdHRyaWJ1dGVDYWNoZS5nZXQoaik7Ci0KLSAgICAgICAgICAgICAgICAgICAgaWYgKChhdHRyLnByZWZpeCAhPSBudWxsKSAmJiAoYXR0ci51cmkgIT0gbnVsbCkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmICghYXR0ci5wcmVmaXguZXF1YWxzKCIiKSAmJiAhYXR0ci51cmkuZXF1YWxzKCIiKSApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdG1wID0gZkludGVybmFsTmFtZXNwYWNlQ29udGV4dC5nZXRQcmVmaXgoYXR0ci51cmkpOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCh0bXAgPT0gbnVsbCkgfHwgKHRtcCAhPSBhdHRyLnByZWZpeCkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG1wID0gZ2V0QXR0clByZWZpeChhdHRyLnVyaSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0bXAgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZJbnRlcm5hbE5hbWVzcGFjZUNvbnRleHQuZGVjbGFyZVByZWZpeChhdHRyLnByZWZpeCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyLnVyaSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cml0ZW5hbWVzcGFjZShhdHRyLnByZWZpeCwgYXR0ci51cmkpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVuYW1lc3BhY2UoYXR0ci5wcmVmaXgsIGF0dHIudXJpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgIHdyaXRlQXR0cmlidXRlV2l0aFByZWZpeChhdHRyLnByZWZpeCwgYXR0ci5sb2NhbHBhcnQsCi0gICAgICAgICAgICAgICAgICAgICAgICBhdHRyLnZhbHVlKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZkF0dHJOYW1lc3BhY2UgPSBudWxsOwotICAgICAgICAgICAgICAgIGZBdHRyaWJ1dGVDYWNoZS5jbGVhcigpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAoY3VycmVudEVsZW1lbnQuaXNFbXB0eSkgewotICAgICAgICAgICAgICAgIGZFbGVtZW50U3RhY2sucG9wKCk7Ci0gICAgICAgICAgICAgICAgZkludGVybmFsTmFtZXNwYWNlQ29udGV4dC5wb3BDb250ZXh0KCk7Ci0gICAgICAgICAgICAgICAgZldyaXRlci53cml0ZShDTE9TRV9FTVBUWV9FTEVNRU5UKTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgZldyaXRlci53cml0ZShDTE9TRV9TVEFSVF9UQUcpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBmU3RhcnRUYWdPcGVuZWQgPSBmYWxzZTsKLSAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKLSAgICAgICAgICAgIGZTdGFydFRhZ09wZW5lZCA9IGZhbHNlOwotICAgICAgICAgICAgdGhyb3cgbmV3IFhNTFN0cmVhbUV4Y2VwdGlvbihleCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBtYXJrcyBvcGVuIG9mIHN0YXJ0IHRhZyBhbmQgd3JpdGVzIHRoZSBzYW1lIGludG8gdGhlIHdyaXRlci4KLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgb3BlblN0YXJ0VGFnKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLSAgICAgICAgZlN0YXJ0VGFnT3BlbmVkID0gdHJ1ZTsKLSAgICAgICAgZldyaXRlci53cml0ZShPUEVOX1NUQVJUX1RBRyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdXJpCi0gICAgICogQHJldHVybgotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCBjb3JyZWN0UHJlZml4KFFOYW1lIGF0dHIsIGludCB0eXBlKSB7Ci0gICAgICAgIFN0cmluZyB0bXBQcmVmaXggPSBudWxsOwotICAgICAgICBTdHJpbmcgcHJlZml4OwotICAgICAgICBTdHJpbmcgdXJpOwotICAgICAgICBwcmVmaXggPSBhdHRyLnByZWZpeDsKLSAgICAgICAgdXJpID0gYXR0ci51cmk7Ci0gICAgICAgIGJvb2xlYW4gaXNTcGVjaWFsQ2FzZVVSSSA9IGZhbHNlOwotCi0gICAgICAgIGlmIChwcmVmaXggPT0gbnVsbCB8fCBwcmVmaXguZXF1YWxzKCIiKSkgewotICAgICAgICAgICAgaWYgKHVyaSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAocHJlZml4ID09IFhNTENvbnN0YW50cy5ERUZBVUxUX05TX1BSRUZJWCAmJiB1cmkgPT0gWE1MQ29uc3RhbnRzLkRFRkFVTFRfTlNfUFJFRklYKQotICAgICAgICAgICAgICAgIHJldHVybjsKLQotICAgICAgICAgICAgdXJpID0gZlN5bWJvbFRhYmxlLmFkZFN5bWJvbCh1cmkpOwotCi0gICAgICAgICAgICBRTmFtZSBkZWNsID0gbnVsbDsKLQotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmTmFtZXNwYWNlRGVjbHMuc2l6ZSgpOyBpKyspIHsKLSAgICAgICAgICAgICAgICBkZWNsID0gKFFOYW1lKSBmTmFtZXNwYWNlRGVjbHMuZ2V0KGkpOwotCi0gICAgICAgICAgICAgICAgaWYgKChkZWNsICE9IG51bGwpICYmIChkZWNsLnVyaSA9PSBhdHRyLnVyaSkpIHsKLSAgICAgICAgICAgICAgICAgICAgYXR0ci5wcmVmaXggPSBkZWNsLnByZWZpeDsKLQotICAgICAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICB0bXBQcmVmaXggPSBmTmFtZXNwYWNlQ29udGV4dC5nZXRQcmVmaXgodXJpKTsKLQotICAgICAgICAgICAgaWYgKHRtcFByZWZpeCA9PSBYTUxDb25zdGFudHMuREVGQVVMVF9OU19QUkVGSVgpIHsKLSAgICAgICAgICAgICAgICBpZiAodHlwZSA9PSBYTUxTdHJlYW1Db25zdGFudHMuU1RBUlRfRUxFTUVOVCkgewotICAgICAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGUgPT0gWE1MU3RyZWFtQ29uc3RhbnRzLkFUVFJJQlVURSkgewotICAgICAgICAgICAgICAgICAgICAvL3RoZSB1cmkgaGFwcGVucyB0byBiZSB0aGUgc2FtZSBhcyB0aGF0IG9mIHRoZSBkZWZhdWx0IG5hbWVzcGFjZQotICAgICAgICAgICAgICAgICAgICB0bXBQcmVmaXggPSBnZXRBdHRyUHJlZml4KHVyaSk7Ci0gICAgICAgICAgICAgICAgICAgIGlzU3BlY2lhbENhc2VVUkkgPSB0cnVlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKHRtcFByZWZpeCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nQnVmZmVyIGdlblByZWZpeCA9IG5ldyBTdHJpbmdCdWZmZXIoInpkZWYiKTsKLQotICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMTsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgICAgIGdlblByZWZpeC5hcHBlbmQoZlByZWZpeEdlbi5uZXh0SW50KCkpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIHByZWZpeCA9IGdlblByZWZpeC50b1N0cmluZygpOwotICAgICAgICAgICAgICAgIHByZWZpeCA9IGZTeW1ib2xUYWJsZS5hZGRTeW1ib2wocHJlZml4KTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgcHJlZml4ID0gZlN5bWJvbFRhYmxlLmFkZFN5bWJvbCh0bXBQcmVmaXgpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAodG1wUHJlZml4ID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBpZiAoaXNTcGVjaWFsQ2FzZVVSSSkgewotICAgICAgICAgICAgICAgICAgICBhZGRBdHRyTmFtZXNwYWNlKHByZWZpeCwgdXJpKTsKLSAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICBRTmFtZSBxbmFtZSA9IG5ldyBRTmFtZSgpOwotICAgICAgICAgICAgICAgICAgICBxbmFtZS5zZXRWYWx1ZXMocHJlZml4LCBYTUxDb25zdGFudHMuWE1MTlNfQVRUUklCVVRFLCBudWxsLCB1cmkpOwotICAgICAgICAgICAgICAgICAgICBmTmFtZXNwYWNlRGVjbHMuYWRkKHFuYW1lKTsKLSAgICAgICAgICAgICAgICAgICAgZkludGVybmFsTmFtZXNwYWNlQ29udGV4dC5kZWNsYXJlUHJlZml4KGZTeW1ib2xUYWJsZS5hZGRTeW1ib2woCi0gICAgICAgICAgICAgICAgICAgICAgICBwcmVmaXgpLCB1cmkpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGF0dHIucHJlZml4ID0gcHJlZml4OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIHJldHVybiB0aGUgcHJlZml4IGlmIHRoZSBhdHRyaWJ1dGUgaGFzIGFuIHVyaSB0aGUgc2FtZSBhcyB0aGF0IG9mIHRoZSBkZWZhdWx0IG5hbWVzcGFjZQotICAgICAqLwotICAgIHByaXZhdGUgU3RyaW5nIGdldEF0dHJQcmVmaXgoU3RyaW5nIHVyaSkgewotICAgICAgICBpZiAoZkF0dHJOYW1lc3BhY2UgIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIChTdHJpbmcpZkF0dHJOYW1lc3BhY2UuZ2V0KHVyaSk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotICAgIHByaXZhdGUgdm9pZCBhZGRBdHRyTmFtZXNwYWNlKFN0cmluZyBwcmVmaXgsIFN0cmluZyB1cmkpIHsKLSAgICAgICAgaWYgKGZBdHRyTmFtZXNwYWNlID09IG51bGwpIHsKLSAgICAgICAgICAgIGZBdHRyTmFtZXNwYWNlID0gbmV3IEhhc2hNYXAoKTsKLSAgICAgICAgfQotICAgICAgICBmQXR0ck5hbWVzcGFjZS5wdXQocHJlZml4LCB1cmkpOwotICAgIH0KLSAgICAvKioKLSAgICAgKiBAcGFyYW0gdXJpCi0gICAgICogQHJldHVybgotICAgICAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBpc0RlZmF1bHROYW1lc3BhY2UoU3RyaW5nIHVyaSkgewotICAgICAgICBTdHJpbmcgZGVmYXVsdE5hbWVzcGFjZSA9IGZJbnRlcm5hbE5hbWVzcGFjZUNvbnRleHQuZ2V0VVJJKERFRkFVTFRfUFJFRklYKTsKLQotICAgICAgICBpZiAodXJpID09IGRlZmF1bHROYW1lc3BhY2UpIHsKLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEBwYXJhbSBwcmVmaXgKLSAgICAgKiBAcGFyYW0gdXJpCi0gICAgICogQHJldHVybgotICAgICAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBjaGVja1VzZXJOYW1lc3BhY2VDb250ZXh0KFN0cmluZyBwcmVmaXgsIFN0cmluZyB1cmkpIHsKLSAgICAgICAgaWYgKGZOYW1lc3BhY2VDb250ZXh0LnVzZXJDb250ZXh0ICE9IG51bGwpIHsKLSAgICAgICAgICAgIFN0cmluZyB0bXBVUkkgPSBmTmFtZXNwYWNlQ29udGV4dC51c2VyQ29udGV4dC5nZXROYW1lc3BhY2VVUkkocHJlZml4KTsKLQotICAgICAgICAgICAgaWYgKCh0bXBVUkkgIT0gbnVsbCkgJiYgdG1wVVJJLmVxdWFscyh1cmkpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29ycmVjdCdzIG5hbWVzcGFjZXMgIGFzIHBlciByZXF1aXJlbWVudHMgb2YgaXNSZXBhcmlzaW5nTmFtZXNwYWNlIHByb3BlcnR5LgotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIHJlcGFpcigpIHsKLSAgICAgICAgQXR0cmlidXRlIGF0dHIgPSBudWxsOwotICAgICAgICBBdHRyaWJ1dGUgYXR0cjIgPSBudWxsOwotICAgICAgICBFbGVtZW50U3RhdGUgY3VycmVudEVsZW1lbnQgPSBmRWxlbWVudFN0YWNrLnBlZWsoKTsKLSAgICAgICAgcmVtb3ZlRHVwbGljYXRlRGVjbHMoKTsKLQotICAgICAgICBmb3IoaW50IGk9MCA7IGk8IGZBdHRyaWJ1dGVDYWNoZS5zaXplKCk7aSsrKXsKLSAgICAgICAgICAgIGF0dHIgPSAoQXR0cmlidXRlKWZBdHRyaWJ1dGVDYWNoZS5nZXQoaSk7Ci0gICAgICAgICAgICBpZigoYXR0ci5wcmVmaXggIT0gbnVsbCAmJiAhYXR0ci5wcmVmaXguZXF1YWxzKCIiKSkgfHwgKGF0dHIudXJpICE9IG51bGwgJiYgIWF0dHIudXJpLmVxdWFscygiIikpKSB7Ci0gICAgICAgICAgICAgICAgY29ycmVjdFByZWZpeChjdXJyZW50RWxlbWVudCxhdHRyKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGlmICghaXNEZWNsYXJlZChjdXJyZW50RWxlbWVudCkpIHsKLSAgICAgICAgICAgIGlmICgoY3VycmVudEVsZW1lbnQucHJlZml4ICE9IG51bGwpICYmCi0gICAgICAgICAgICAgICAgICAgIChjdXJyZW50RWxlbWVudC51cmkgIT0gbnVsbCkpIHsKLSAgICAgICAgICAgICAgICBpZiAoKCFjdXJyZW50RWxlbWVudC5wcmVmaXguZXF1YWxzKCIiKSkgJiYgKCFjdXJyZW50RWxlbWVudC51cmkuZXF1YWxzKCIiKSkpIHsKLSAgICAgICAgICAgICAgICAgICAgZk5hbWVzcGFjZURlY2xzLmFkZChjdXJyZW50RWxlbWVudCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgZm9yKGludCBpPTAgOyBpPCBmQXR0cmlidXRlQ2FjaGUuc2l6ZSgpO2krKyl7Ci0gICAgICAgICAgICBhdHRyID0gKEF0dHJpYnV0ZSlmQXR0cmlidXRlQ2FjaGUuZ2V0KGkpOwotICAgICAgICAgICAgZm9yKGludCBqPWkrMTtqPGZBdHRyaWJ1dGVDYWNoZS5zaXplKCk7aisrKXsKLSAgICAgICAgICAgICAgICBhdHRyMiA9IChBdHRyaWJ1dGUpZkF0dHJpYnV0ZUNhY2hlLmdldChqKTsKLSAgICAgICAgICAgICAgICBpZighIiIuZXF1YWxzKGF0dHIucHJlZml4KSYmICEiIi5lcXVhbHMoYXR0cjIucHJlZml4KSl7Ci0gICAgICAgICAgICAgICAgICAgIGNvcnJlY3RQcmVmaXgoYXR0cixhdHRyMik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgcmVwYWlyTmFtZXNwYWNlRGVjbChjdXJyZW50RWxlbWVudCk7Ci0KLSAgICAgICAgaW50IGkgPSAwOwotCi0gICAgICAgIGZvciAoaSA9IDA7IGkgPCBmQXR0cmlidXRlQ2FjaGUuc2l6ZSgpOyBpKyspIHsKLSAgICAgICAgICAgIGF0dHIgPSAoQXR0cmlidXRlKSBmQXR0cmlidXRlQ2FjaGUuZ2V0KGkpOwotICAgICAgICAgICAgLyogSWYgJ2F0dHInIGlzIGFuIGF0dHJpYnV0ZSBhbmQgaXQgaXMgaW4gbm8gbmFtZXNwYWNlKHdoaWNoIG1lYW5zIHRoYXQgcHJlZml4PSIiLCB1cmk9IiIpLCBhdHRyJ3MKLSAgICAgICAgICAgICAgIG5hbWVzcGFjZSBzaG91bGQgbm90IGJlIHJlZGluZGVkLiBTZWUgW2h0dHA6Ly93d3cudzMub3JnL1RSL1JFQy14bWwtbmFtZXMvI2RlZmF1bHRpbmddLgotICAgICAgICAgICAgICovCi0gICAgICAgICAgICBpZiAoYXR0ci5wcmVmaXggIT0gbnVsbCAmJiBhdHRyLnByZWZpeC5lcXVhbHMoIiIpICYmIGF0dHIudXJpICE9IG51bGwgJiYgYXR0ci51cmkuZXF1YWxzKCIiKSl7Ci0gICAgICAgICAgICAgICAgcmVwYWlyTmFtZXNwYWNlRGVjbChhdHRyKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIFFOYW1lIHFuYW1lID0gbnVsbDsKLQotICAgICAgICBmb3IgKGkgPSAwOyBpIDwgZk5hbWVzcGFjZURlY2xzLnNpemUoKTsgaSsrKSB7Ci0gICAgICAgICAgICBxbmFtZSA9IChRTmFtZSkgZk5hbWVzcGFjZURlY2xzLmdldChpKTsKLQotICAgICAgICAgICAgaWYgKHFuYW1lICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmSW50ZXJuYWxOYW1lc3BhY2VDb250ZXh0LmRlY2xhcmVQcmVmaXgocW5hbWUucHJlZml4LCBxbmFtZS51cmkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgZm9yIChpID0gMDsgaSA8IGZBdHRyaWJ1dGVDYWNoZS5zaXplKCk7IGkrKykgewotICAgICAgICAgICAgYXR0ciA9IChBdHRyaWJ1dGUpIGZBdHRyaWJ1dGVDYWNoZS5nZXQoaSk7Ci0gICAgICAgICAgICBjb3JyZWN0UHJlZml4KGF0dHIsIFhNTFN0cmVhbUNvbnN0YW50cy5BVFRSSUJVVEUpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoKLSAgICAgKklmIGVsZW1lbnQgYW5kL29yIGF0dHJpYnV0ZSBuYW1lcyBpbiB0aGUgc2FtZSBzdGFydCBvciBlbXB0eS1lbGVtZW50IHRhZwotICAgICAqYXJlIGJvdW5kIHRvIGRpZmZlcmVudCBuYW1lc3BhY2UgVVJJcyBhbmQgYXJlIHVzaW5nIHRoZSBzYW1lIHByZWZpeCB0aGVuCi0gICAgICp0aGUgZWxlbWVudCBvciB0aGUgZmlyc3Qgb2NjdXJyaW5nIGF0dHJpYnV0ZSByZXRhaW5zIHRoZSBvcmlnaW5hbCBwcmVmaXgKLSAgICAgKmFuZCB0aGUgZm9sbG93aW5nIGF0dHJpYnV0ZXMgaGF2ZSB0aGVpciBwcmVmaXhlcyByZXBsYWNlZCB3aXRoIGEgbmV3IHByZWZpeAotICAgICAqdGhhdCBpcyBib3VuZCB0byB0aGUgbmFtZXNwYWNlIFVSSXMgb2YgdGhvc2UgYXR0cmlidXRlcy4KLSAgICAgKi8KLSAgICB2b2lkIGNvcnJlY3RQcmVmaXgoUU5hbWUgYXR0cjEsIFFOYW1lIGF0dHIyKSB7Ci0gICAgICAgIFN0cmluZyB0bXBQcmVmaXggPSBudWxsOwotICAgICAgICBRTmFtZSBkZWNsID0gbnVsbDsKLSAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7Ci0KLSAgICAgICAgY2hlY2tGb3JOdWxsKGF0dHIxKTsKLSAgICAgICAgY2hlY2tGb3JOdWxsKGF0dHIyKTsKLQotICAgICAgICBpZihhdHRyMS5wcmVmaXguZXF1YWxzKGF0dHIyLnByZWZpeCkgJiYgIShhdHRyMS51cmkuZXF1YWxzKGF0dHIyLnVyaSkpKXsKLQotICAgICAgICAgICAgdG1wUHJlZml4ID0gZk5hbWVzcGFjZUNvbnRleHQuZ2V0UHJlZml4KGF0dHIyLnVyaSk7Ci0KLSAgICAgICAgICAgIGlmICh0bXBQcmVmaXggIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGF0dHIyLnByZWZpeCA9IGZTeW1ib2xUYWJsZS5hZGRTeW1ib2wodG1wUHJlZml4KTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgZGVjbCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgZm9yKGludCBuPTA7bjxmTmFtZXNwYWNlRGVjbHMuc2l6ZSgpO24rKyl7Ci0gICAgICAgICAgICAgICAgICAgIGRlY2wgPSAoUU5hbWUpZk5hbWVzcGFjZURlY2xzLmdldChuKTsKLSAgICAgICAgICAgICAgICAgICAgaWYoZGVjbCAhPSBudWxsICYmIChkZWNsLnVyaSA9PSBhdHRyMi51cmkpKXsKLSAgICAgICAgICAgICAgICAgICAgICAgIGF0dHIyLnByZWZpeCA9IGRlY2wucHJlZml4OwotCi0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAvL05vIG5hbWVzcGFjZSBtYXBwaW5nIGZvdW5kICwgc28gZGVjbGFyZSBwcmVmaXguCi0gICAgICAgICAgICAgICAgU3RyaW5nQnVmZmVyIGdlblByZWZpeCA9IG5ldyBTdHJpbmdCdWZmZXIoInpkZWYiKTsKLQotICAgICAgICAgICAgICAgIGZvciAoaW50IGsgPSAwOyBrIDwgMTsgaysrKSB7Ci0gICAgICAgICAgICAgICAgICAgIGdlblByZWZpeC5hcHBlbmQoZlByZWZpeEdlbi5uZXh0SW50KCkpOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIHRtcFByZWZpeCA9IGdlblByZWZpeC50b1N0cmluZygpOwotICAgICAgICAgICAgICAgIHRtcFByZWZpeCA9IGZTeW1ib2xUYWJsZS5hZGRTeW1ib2wodG1wUHJlZml4KTsKLSAgICAgICAgICAgICAgICBhdHRyMi5wcmVmaXggPSB0bXBQcmVmaXg7Ci0KLSAgICAgICAgICAgICAgICBRTmFtZSBxbmFtZSA9IG5ldyBRTmFtZSgpOwotICAgICAgICAgICAgICAgIHFuYW1lLnNldFZhbHVlcyh0bXBQcmVmaXgsIFhNTENvbnN0YW50cy5YTUxOU19BVFRSSUJVVEUsIG51bGwsCi0gICAgICAgICAgICAgICAgICAgIGF0dHIyLnVyaSk7Ci0gICAgICAgICAgICAgICAgZk5hbWVzcGFjZURlY2xzLmFkZChxbmFtZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICB2b2lkIGNoZWNrRm9yTnVsbChRTmFtZSBhdHRyKSB7Ci0gICAgICAgIGlmIChhdHRyLnByZWZpeCA9PSBudWxsKSBhdHRyLnByZWZpeCA9IFhNTENvbnN0YW50cy5ERUZBVUxUX05TX1BSRUZJWDsKLSAgICAgICAgaWYgKGF0dHIudXJpID09IG51bGwpIGF0dHIudXJpID0gWE1MQ29uc3RhbnRzLkRFRkFVTFRfTlNfUFJFRklYOwotICAgIH0KLQotICAgIHZvaWQgcmVtb3ZlRHVwbGljYXRlRGVjbHMoKXsKLSAgICAgICAgUU5hbWUgZGVjbDEsZGVjbDI7Ci0gICAgICAgIGZvcihpbnQgaSA9MDtpPGZOYW1lc3BhY2VEZWNscy5zaXplKCk7aSsrKXsKLSAgICAgICAgICAgIGRlY2wxID0gKFFOYW1lKWZOYW1lc3BhY2VEZWNscy5nZXQoaSk7Ci0gICAgICAgICAgICBpZihkZWNsMSE9bnVsbCkgewotICAgICAgICAgICAgICAgIGZvcihpbnQgaj1pKzE7ajxmTmFtZXNwYWNlRGVjbHMuc2l6ZSgpO2orKyl7Ci0gICAgICAgICAgICAgICAgICAgIGRlY2wyID0gKFFOYW1lKWZOYW1lc3BhY2VEZWNscy5nZXQoaik7Ci0gICAgICAgICAgICAgICAgICAgIC8vIFFOYW1lLmVxdWFscyByZWxpZXMgb24gaWRlbnRpdHkgZXF1YWxpdHksIHNvIHdlIGNhbid0IHVzZSBpdCwKLSAgICAgICAgICAgICAgICAgICAgLy8gYmVjYXVzZSBwcmVmaXhlcyBhcmVuJ3QgaW50ZXJuZWQKLSAgICAgICAgICAgICAgICAgICAgaWYoZGVjbDIhPW51bGwgJiYgZGVjbDEucHJlZml4LmVxdWFscyhkZWNsMi5wcmVmaXgpICYmIGRlY2wxLnVyaS5lcXVhbHMoZGVjbDIudXJpKSkKLSAgICAgICAgICAgICAgICAgICAgICAgIGZOYW1lc3BhY2VEZWNscy5yZW1vdmUoaik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoKLSAgICAgKklmIGFuIGVsZW1lbnQgb3IgYXR0cmlidXRlIG5hbWUgaXMgYm91bmQgdG8gYSBwcmVmaXggYW5kIHRoZXJlIGlzIGEgbmFtZXNwYWNlCi0gICAgICpkZWNsYXJhdGlvbiB0aGF0IGJpbmRzIHRoYXQgcHJlZml4IHRvIGEgZGlmZmVyZW50IFVSSSB0aGVuIHRoYXQgbmFtZXNwYWNlIGRlY2xhcmF0aW9uCi0gICAgICppcyBlaXRoZXIgcmVtb3ZlZCBpZiB0aGUgY29ycmVjdCBtYXBwaW5nIGlzIGluaGVyaXRlZCBmcm9tIHRoZSBwYXJlbnQgY29udGV4dCBvZiB0aGF0IGVsZW1lbnQsCi0gICAgICpvciBjaGFuZ2VkIHRvIHRoZSBuYW1lc3BhY2UgVVJJIG9mIHRoZSBlbGVtZW50IG9yIGF0dHJpYnV0ZSB1c2luZyB0aGF0IHByZWZpeC4KLSAgICAgKgotICAgICAqLwotICAgIHZvaWQgcmVwYWlyTmFtZXNwYWNlRGVjbChRTmFtZSBhdHRyKSB7Ci0gICAgICAgIFFOYW1lIGRlY2wgPSBudWxsOwotICAgICAgICBTdHJpbmcgdG1wVVJJOwotCi0gICAgICAgIC8vY2hlY2sgZm9yIG51bGwgcHJlZml4LgotICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IGZOYW1lc3BhY2VEZWNscy5zaXplKCk7IGorKykgewotICAgICAgICAgICAgZGVjbCA9IChRTmFtZSkgZk5hbWVzcGFjZURlY2xzLmdldChqKTsKLQotICAgICAgICAgICAgaWYgKGRlY2wgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGlmICgoYXR0ci5wcmVmaXggIT0gbnVsbCkgJiYKLSAgICAgICAgICAgICAgICAgICAgICAgIChhdHRyLnByZWZpeC5lcXVhbHMoZGVjbC5wcmVmaXgpICYmCi0gICAgICAgICAgICAgICAgICAgICAgICAhKGF0dHIudXJpLmVxdWFscyhkZWNsLnVyaSkpKSkgewotICAgICAgICAgICAgICAgICAgICB0bXBVUkkgPSBmTmFtZXNwYWNlQ29udGV4dC5nZXROYW1lc3BhY2VVUkkoYXR0ci5wcmVmaXgpOwotCi0gICAgICAgICAgICAgICAgICAgIC8vc2VlIGlmIHlvdSBuZWVkIHRvIGFkZCB0byBzeW1ib2xlIHRhYmxlLgotICAgICAgICAgICAgICAgICAgICBpZiAodG1wVVJJICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0bXBVUkkuZXF1YWxzKGF0dHIudXJpKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZOYW1lc3BhY2VEZWNscy5zZXQoaiwgbnVsbCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlY2wudXJpID0gYXR0ci51cmk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBib29sZWFuIGlzRGVjbGFyZWQoUU5hbWUgYXR0cikgewotICAgICAgICBRTmFtZSBkZWNsID0gbnVsbDsKLQotICAgICAgICBmb3IgKGludCBuID0gMDsgbiA8IGZOYW1lc3BhY2VEZWNscy5zaXplKCk7IG4rKykgewotICAgICAgICAgICAgZGVjbCA9IChRTmFtZSkgZk5hbWVzcGFjZURlY2xzLmdldChuKTsKLQotICAgICAgICAgICAgaWYgKChhdHRyLnByZWZpeCAhPSBudWxsKSAmJgotICAgICAgICAgICAgICAgICAgICAoKGF0dHIucHJlZml4ID09IGRlY2wucHJlZml4KSAmJiAoZGVjbC51cmkgPT0gYXR0ci51cmkpKSkgewotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKGF0dHIudXJpICE9IG51bGwpIHsKLSAgICAgICAgICAgIGlmIChmTmFtZXNwYWNlQ29udGV4dC5nZXRQcmVmaXgoYXR0ci51cmkpICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICAvKgotICAgICAqIFN0YXJ0IG9mIEludGVybmFsIGNsYXNzZXMuCi0gICAgICoKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgY2xhc3MgRWxlbWVudFN0YWNrIHsKLSAgICAgICAgLyoqIFRoZSBzdGFjayBkYXRhLiAqLwotICAgICAgICBwcm90ZWN0ZWQgRWxlbWVudFN0YXRlW10gZkVsZW1lbnRzOwotCi0gICAgICAgIC8qKiBUaGUgc2l6ZSBvZiB0aGUgc3RhY2suICovCi0gICAgICAgIHByb3RlY3RlZCBzaG9ydCBmRGVwdGg7Ci0KLSAgICAgICAgLyoqIERlZmF1bHQgY29uc3RydWN0b3IuICovCi0gICAgICAgIHB1YmxpYyBFbGVtZW50U3RhY2soKSB7Ci0gICAgICAgICAgICBmRWxlbWVudHMgPSBuZXcgRWxlbWVudFN0YXRlWzEwXTsKLQotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmRWxlbWVudHMubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgICAgICBmRWxlbWVudHNbaV0gPSBuZXcgRWxlbWVudFN0YXRlKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogUHVzaGVzIGFuIGVsZW1lbnQgb24gdGhlIHN0YWNrLgotICAgICAgICAgKiA8cD4KLSAgICAgICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGUgUU5hbWUgdmFsdWVzIGFyZSBjb3BpZWQgaW50byB0aGUKLSAgICAgICAgICogc3RhY2suIEluIG90aGVyIHdvcmRzLCB0aGUgY2FsbGVyIGRvZXMgPGVtPm5vdDwvZW0+IG9ycGhhbgotICAgICAgICAgKiB0aGUgZWxlbWVudCB0byB0aGUgc3RhY2suIEFsc28sIHRoZSBRTmFtZSBvYmplY3QgcmV0dXJuZWQKLSAgICAgICAgICogaXMgPGVtPm5vdDwvZW0+IG9ycGhhbmVkIHRvIHRoZSBjYWxsZXIuIEl0IHNob3VsZCBiZQotICAgICAgICAgKiBjb25zaWRlcmVkIHJlYWQtb25seS4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIGVsZW1lbnQgVGhlIGVsZW1lbnQgdG8gcHVzaCBvbnRvIHRoZSBzdGFjay4KLSAgICAgICAgICoKLSAgICAgICAgICogQHJldHVybiBSZXR1cm5zIHRoZSBhY3R1YWwgUU5hbWUgb2JqZWN0IHRoYXQgc3RvcmVzIHRoZQotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIEVsZW1lbnRTdGF0ZSBwdXNoKEVsZW1lbnRTdGF0ZSBlbGVtZW50KSB7Ci0gICAgICAgICAgICBpZiAoZkRlcHRoID09IGZFbGVtZW50cy5sZW5ndGgpIHsKLSAgICAgICAgICAgICAgICBFbGVtZW50U3RhdGVbXSBhcnJheSA9IG5ldyBFbGVtZW50U3RhdGVbZkVsZW1lbnRzLmxlbmd0aCAqIDJdOwotICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZkVsZW1lbnRzLCAwLCBhcnJheSwgMCwgZkRlcHRoKTsKLSAgICAgICAgICAgICAgICBmRWxlbWVudHMgPSBhcnJheTsKLQotICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSBmRGVwdGg7IGkgPCBmRWxlbWVudHMubGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgZkVsZW1lbnRzW2ldID0gbmV3IEVsZW1lbnRTdGF0ZSgpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgZkVsZW1lbnRzW2ZEZXB0aF0uc2V0VmFsdWVzKGVsZW1lbnQpOwotCi0gICAgICAgICAgICByZXR1cm4gZkVsZW1lbnRzW2ZEZXB0aCsrXTsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gcHJlZml4Ci0gICAgICAgICAqIEBwYXJhbSBsb2NhbHBhcnQKLSAgICAgICAgICogQHBhcmFtIHJhd25hbWUKLSAgICAgICAgICogQHBhcmFtIHVyaQotICAgICAgICAgKiBAcGFyYW0gaXNFbXB0eQotICAgICAgICAgKiBAcmV0dXJuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgRWxlbWVudFN0YXRlIHB1c2goU3RyaW5nIHByZWZpeCwgU3RyaW5nIGxvY2FscGFydCwKLSAgICAgICAgICAgIFN0cmluZyByYXduYW1lLCBTdHJpbmcgdXJpLCBib29sZWFuIGlzRW1wdHkpIHsKLSAgICAgICAgICAgIGlmIChmRGVwdGggPT0gZkVsZW1lbnRzLmxlbmd0aCkgewotICAgICAgICAgICAgICAgIEVsZW1lbnRTdGF0ZVtdIGFycmF5ID0gbmV3IEVsZW1lbnRTdGF0ZVtmRWxlbWVudHMubGVuZ3RoICogMl07Ci0gICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShmRWxlbWVudHMsIDAsIGFycmF5LCAwLCBmRGVwdGgpOwotICAgICAgICAgICAgICAgIGZFbGVtZW50cyA9IGFycmF5OwotCi0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IGZEZXB0aDsgaSA8IGZFbGVtZW50cy5sZW5ndGg7IGkrKykgewotICAgICAgICAgICAgICAgICAgICBmRWxlbWVudHNbaV0gPSBuZXcgRWxlbWVudFN0YXRlKCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBmRWxlbWVudHNbZkRlcHRoXS5zZXRWYWx1ZXMocHJlZml4LCBsb2NhbHBhcnQsIHJhd25hbWUsIHVyaSwgaXNFbXB0eSk7Ci0KLSAgICAgICAgICAgIHJldHVybiBmRWxlbWVudHNbZkRlcHRoKytdOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFBvcHMgYW4gZWxlbWVudCBvZmYgb2YgdGhlIHN0YWNrIGJ5IHNldHRpbmcgdGhlIHZhbHVlcyBvZgotICAgICAgICAgKiB0aGUgc3BlY2lmaWVkIFFOYW1lLgotICAgICAgICAgKiA8cD4KLSAgICAgICAgICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGUgb2JqZWN0IHJldHVybmVkIGlzIDxlbT5ub3Q8L2VtPgotICAgICAgICAgKiBvcnBoYW5lZCB0byB0aGUgY2FsbGVyLiBUaGVyZWZvcmUsIHRoZSBjYWxsZXIgc2hvdWxkIGNvbnNpZGVyCi0gICAgICAgICAqIHRoZSBvYmplY3QgdG8gYmUgcmVhZC1vbmx5LgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIEVsZW1lbnRTdGF0ZSBwb3AoKSB7Ci0gICAgICAgICAgICByZXR1cm4gZkVsZW1lbnRzWy0tZkRlcHRoXTsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKiBDbGVhcnMgdGhlIHN0YWNrIHdpdGhvdXQgdGhyb3dpbmcgYXdheSBleGlzdGluZyBRTmFtZSBvYmplY3RzLiAqLwotICAgICAgICBwdWJsaWMgdm9pZCBjbGVhcigpIHsKLSAgICAgICAgICAgIGZEZXB0aCA9IDA7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogVGhpcyBmdW5jdGlvbiBpcyBhcyBhIHJlc3VsdCBvZiBvcHRpbWl6YXRpb24gZG9uZSBmb3IgZW5kRWxlbWVudCAtLQotICAgICAgICAgKiB3ZSBkb250IG5lZWQgdG8gc2V0IHRoZSB2YWx1ZSBmb3IgZXZlcnkgZW5kIGVsZW1lbnQgd2UgZW5jb3V0ZXIuCi0gICAgICAgICAqIEZvciBXZWxsIGZvcm1lZG5lc3MgY2hlY2tzIHdlIGNhbiBoYXZlIHRoZSBzYW1lIFFOYW1lIG9iamVjdCB0aGF0IHdhcyBwdXNoZWQuCi0gICAgICAgICAqIHRoZSB2YWx1ZXMgd2lsbCBiZSBzZXQgb25seSBpZiBhcHBsaWNhdGlvbiBuZWVkIHRvIGtub3cgYWJvdXQgdGhlIGVuZEVsZW1lbnQKLSAgICAgICAgICogLS0gbmVlcmFqLmJhamFqQHN1bi5jb20KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBFbGVtZW50U3RhdGUgcGVlaygpIHsKLSAgICAgICAgICAgIHJldHVybiBmRWxlbWVudHNbZkRlcHRoIC0gMV07Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICoKLSAgICAgICAgICogQHJldHVybgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIGJvb2xlYW4gZW1wdHkoKSB7Ci0gICAgICAgICAgICByZXR1cm4gKGZEZXB0aCA+IDApID8gZmFsc2UgOiB0cnVlOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogTWFpbnRhaW5zIGVsZW1lbnQgc3RhdGUgLiBsb2NhbE5hbWUgZm9yIG5vdy4KLSAgICAgKi8KLSAgICBjbGFzcyBFbGVtZW50U3RhdGUgZXh0ZW5kcyBRTmFtZSB7Ci0gICAgICAgIHB1YmxpYyBib29sZWFuIGlzRW1wdHkgPSBmYWxzZTsKLQotICAgICAgICBwdWJsaWMgRWxlbWVudFN0YXRlKCkge30KLQotICAgICAgICBwdWJsaWMgRWxlbWVudFN0YXRlKFN0cmluZyBwcmVmaXgsIFN0cmluZyBsb2NhbHBhcnQsIFN0cmluZyByYXduYW1lLAotICAgICAgICAgICAgU3RyaW5nIHVyaSkgewotICAgICAgICAgICAgc3VwZXIocHJlZml4LCBsb2NhbHBhcnQsIHJhd25hbWUsIHVyaSk7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCBzZXRWYWx1ZXMoU3RyaW5nIHByZWZpeCwgU3RyaW5nIGxvY2FscGFydCwgU3RyaW5nIHJhd25hbWUsCi0gICAgICAgICAgICBTdHJpbmcgdXJpLCBib29sZWFuIGlzRW1wdHkpIHsKLSAgICAgICAgICAgIHN1cGVyLnNldFZhbHVlcyhwcmVmaXgsIGxvY2FscGFydCwgcmF3bmFtZSwgdXJpKTsKLSAgICAgICAgICAgIHRoaXMuaXNFbXB0eSA9IGlzRW1wdHk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBdHRyaWJ1dGVzCi0gICAgICovCi0gICAgY2xhc3MgQXR0cmlidXRlIGV4dGVuZHMgUU5hbWUgewotICAgICAgICBTdHJpbmcgdmFsdWU7Ci0KLSAgICAgICAgQXR0cmlidXRlKFN0cmluZyB2YWx1ZSkgewotICAgICAgICAgICAgc3VwZXIoKTsKLSAgICAgICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEltcGxlbWVudGF0aW9uIG9mIE5hbWVzcGFjZUNvbnRleHQgLgotICAgICAqCi0gICAgICovCi0gICAgY2xhc3MgTmFtZXNwYWNlQ29udGV4dEltcGwgaW1wbGVtZW50cyBOYW1lc3BhY2VDb250ZXh0IHsKLSAgICAgICAgLy9yb290IG5hbWVzcGFjZSBjb250ZXh0IHNldCBieSB1c2VyLgotICAgICAgICBOYW1lc3BhY2VDb250ZXh0IHVzZXJDb250ZXh0ID0gbnVsbDsKLQotICAgICAgICAvL2NvbnRleHQgYnVpbHQgYnkgdGhlIHdyaXRlci4KLSAgICAgICAgTmFtZXNwYWNlU3VwcG9ydCBpbnRlcm5hbENvbnRleHQgPSBudWxsOwotCi0gICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZXNwYWNlVVJJKFN0cmluZyBwcmVmaXgpIHsKLSAgICAgICAgICAgIFN0cmluZyB1cmkgPSBudWxsOwotCi0gICAgICAgICAgICBpZiAocHJlZml4ICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBwcmVmaXggPSBmU3ltYm9sVGFibGUuYWRkU3ltYm9sKHByZWZpeCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmIChpbnRlcm5hbENvbnRleHQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHVyaSA9IGludGVybmFsQ29udGV4dC5nZXRVUkkocHJlZml4KTsKLQotICAgICAgICAgICAgICAgIGlmICh1cmkgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gdXJpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKHVzZXJDb250ZXh0ICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICB1cmkgPSB1c2VyQ29udGV4dC5nZXROYW1lc3BhY2VVUkkocHJlZml4KTsKLQotICAgICAgICAgICAgICAgIHJldHVybiB1cmk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIFN0cmluZyBnZXRQcmVmaXgoU3RyaW5nIHVyaSkgewotICAgICAgICAgICAgU3RyaW5nIHByZWZpeCA9IG51bGw7Ci0KLSAgICAgICAgICAgIGlmICh1cmkgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHVyaSA9IGZTeW1ib2xUYWJsZS5hZGRTeW1ib2wodXJpKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKGludGVybmFsQ29udGV4dCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgcHJlZml4ID0gaW50ZXJuYWxDb250ZXh0LmdldFByZWZpeCh1cmkpOwotCi0gICAgICAgICAgICAgICAgaWYgKHByZWZpeCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBwcmVmaXg7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAodXNlckNvbnRleHQgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJldHVybiB1c2VyQ29udGV4dC5nZXRQcmVmaXgodXJpKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgamF2YS51dGlsLkl0ZXJhdG9yIGdldFByZWZpeGVzKFN0cmluZyB1cmkpIHsKLSAgICAgICAgICAgIFZlY3RvciBwcmVmaXhlcyA9IG51bGw7Ci0gICAgICAgICAgICBJdGVyYXRvciBpdHIgPSBudWxsOwotCi0gICAgICAgICAgICBpZiAodXJpICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICB1cmkgPSBmU3ltYm9sVGFibGUuYWRkU3ltYm9sKHVyaSk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmICh1c2VyQ29udGV4dCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgaXRyID0gdXNlckNvbnRleHQuZ2V0UHJlZml4ZXModXJpKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKGludGVybmFsQ29udGV4dCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgcHJlZml4ZXMgPSBpbnRlcm5hbENvbnRleHQuZ2V0UHJlZml4ZXModXJpKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKChwcmVmaXhlcyA9PSBudWxsKSAmJiAoaXRyICE9IG51bGwpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGl0cjsKLSAgICAgICAgICAgIH0gZWxzZSBpZiAoKHByZWZpeGVzICE9IG51bGwpICYmIChpdHIgPT0gbnVsbCkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFJlYWRPbmx5SXRlcmF0b3IocHJlZml4ZXMuaXRlcmF0b3IoKSk7Ci0gICAgICAgICAgICB9IGVsc2UgaWYgKChwcmVmaXhlcyAhPSBudWxsKSAmJiAoaXRyICE9IG51bGwpKSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIG9iID0gbnVsbDsKLQotICAgICAgICAgICAgICAgIHdoaWxlIChpdHIuaGFzTmV4dCgpKSB7Ci0gICAgICAgICAgICAgICAgICAgIG9iID0gKFN0cmluZykgaXRyLm5leHQoKTsKLQotICAgICAgICAgICAgICAgICAgICBpZiAob2IgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgb2IgPSBmU3ltYm9sVGFibGUuYWRkU3ltYm9sKG9iKTsKLSAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgIGlmICghcHJlZml4ZXMuY29udGFpbnMob2IpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBwcmVmaXhlcy5hZGQob2IpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBSZWFkT25seUl0ZXJhdG9yKHByZWZpeGVzLml0ZXJhdG9yKCkpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICByZXR1cm4gZlJlYWRPbmx5SXRlcmF0b3I7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvLyAtLSBNYXAgSW50ZXJmYWNlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0KLSAgICBwdWJsaWMgaW50IHNpemUoKSB7Ci0gICAgICAgIHJldHVybiAxOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGlzRW1wdHkoKSB7Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0tleShPYmplY3Qga2V5KSB7Ci0gICAgICAgIHJldHVybiBrZXkuZXF1YWxzKE9VVFBVVFNUUkVBTV9QUk9QRVJUWSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgdmFsdWUgYXNzb2NpYXRlZCB0byBhbiBpbXBsZW1lbnRhdGlvbi1zcGVjaWZpYwotICAgICAqIHByb3BlcnR5LgotICAgICAqLwotICAgIHB1YmxpYyBPYmplY3QgZ2V0KE9iamVjdCBrZXkpIHsKLSAgICAgICAgaWYgKGtleS5lcXVhbHMoT1VUUFVUU1RSRUFNX1BST1BFUlRZKSkgewotICAgICAgICAgICAgcmV0dXJuIGZPdXRwdXRTdHJlYW07Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgcHVibGljIGphdmEudXRpbC5TZXQgZW50cnlTZXQoKSB7Ci0gICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIE92ZXJyaWRlcyB0aGUgbWV0aG9kIGRlZmluZWQgaW4gQWJzdHJhY3RNYXAgd2hpY2ggaXMKLSAgICAgKiBub3QgY29tcGxldGVseSBpbXBsZW1lbnRlZC4gQ2FsbGluZyB0b1N0cmluZygpIGluCi0gICAgICogQWJzdHJhY3RNYXAgd291bGQgY2F1c2UgYW4gdW5zdXBwb3J0ZWQgZXhlY3Rpb24gdG8KLSAgICAgKiBiZSB0aHJvd24uCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKLSAgICAgICAgcmV0dXJuIGdldENsYXNzKCkuZ2V0TmFtZSgpICsgIkAiICsgSW50ZWdlci50b0hleFN0cmluZyhoYXNoQ29kZSgpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBPdmVycmlkZXMgdGhlIG1ldGhvZCBkZWZpbmVkIGluIEFic3RyYWN0TWFwCi0gICAgICogVGhpcyBpcyByZXF1aXJlZCBieSB0aGUgdG9TdHJpbmcoKSBtZXRob2QKLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewotICAgICAgICByZXR1cm4gZkVsZW1lbnRTdGFjay5oYXNoQ29kZSgpOwotICAgIH0KLSAgICAvKioKLSAgICAgKiBPdmVycmlkZXMgdGhlIG1ldGhvZCBkZWZpbmVkIGluIEFic3RyYWN0TWFwCi0gICAgICogVGhpcyBpcyByZXF1aXJlZCB0byBzYXRpc2Z5IHRoZSBjb250cmFjdCBmb3IgaGFzaENvZGUuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmopIHsKLSAgICAgICAgcmV0dXJuICh0aGlzID09IG9iaik7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2NvbS9zdW4veG1sL2ludGVybmFsL3N0cmVhbS93cml0ZXJzL1hNTFdyaXRlci5qYXZhIGIvc3JjL2NvbS9zdW4veG1sL2ludGVybmFsL3N0cmVhbS93cml0ZXJzL1hNTFdyaXRlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhZGU0ZWFmLi4wMDAwMDAwCi0tLSBhL3NyYy9jb20vc3VuL3htbC9pbnRlcm5hbC9zdHJlYW0vd3JpdGVycy9YTUxXcml0ZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI2MCArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDA2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi1wYWNrYWdlIGNvbS5zdW4ueG1sLmludGVybmFsLnN0cmVhbS53cml0ZXJzOwotCi1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLldyaXRlcjsKLWltcG9ydCBjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuWE1MU3RyaW5nQnVmZmVyOwotCi0vKioKLSAqIFhNTFdyaXRlcgotICoKLSAqIDxjb2RlPlhNTFdyaXRlcjwvY29kZT4gaXMgbm90IHRocmVhZCBzYWZlLgotICoKLSAqIEZvciBlZmZpY2llbmN5IHRoaXMgd3JpdGVyIGJ1ZmZlcnMgdGhlIGlucHV0LiBVc2UgPGNvZGU+Zmx1c2goKTwvY29kZT4gZnVuY3Rpb24KLSAqIHRvIGV4cGxpY2l0bHkgd3JpdGUgdGhlIGRhdGEgdG8gdW5kZXJseWluZyBzdHJlYW0uCi0gKgotICogVGhpcyB3cml0ZXIgaXMgZGVzaWduZWQgaW4gc3VjaCBhIHdheSB0aGF0IGl0IGF0bGVhc3QgYnVmZmVycyB0aGUgaW5wdXQgdG8gdGhlCi0gKiA8Y29kZT5zaXplPC9jb2RlPiBzcGVjaWZpZWQuIFVubGVzcyA8Y29kZT5mbHVzaDwvY29kZT4gaXMgY2FsbGVkLCBpdCBndWFyYW50ZWVzIHRoYXQKLSAqIGRhdGEgaW4gY2h1bmtzIG9mIHNpemUgZXF1YWwgdG8gb3IgbW9yZSB0aGFuIDxjb2RlPnNpemU8L2NvZGU+IHNwZWNpZmllZCB3aWxsIGJlIHdyaXR0ZW4uCi0gKgotICoKLSAqIDxjb2RlPlhNTFdyaXRlcjwvY29kZT4gaW5zdGFuY2UgY2FuIGJlIHJldXNlZC4gPGNvZGU+c2V0V3JpdGVyKCk8L2NvZGU+IGludGVybmFsbHkgY2xlYXJzIHRoZQotICogYnVmZmVyIGFuZCBzdG9yZXMgdGhlIHJlZmVyZW5jZSB0byBuZXdseSBzdXBwbGllZCA8Y29kZT5Xcml0ZXI8L2NvZGU+IGluc3RhbmNlLgotICoKLSAqIEBhdXRob3IgTmVlcmFqIEJhamFqIFN1biBNaWNyb3N5c3RlbXMsIGluYy4KLSAqLwotcHVibGljIGNsYXNzIFhNTFdyaXRlciBleHRlbmRzIFdyaXRlciB7Ci0KLSAgICBwcml2YXRlIFdyaXRlciB3cml0ZXIgOwotICAgIHByaXZhdGUgaW50IHNpemUgOwotICAgIC8va2VlcCB0aGUgc2l6ZSBvZiBpbnRlcm5hbCBidWZmZXIgbW9yZSB0aGFuICdzaXplJyByZXF1aXJlZCB0byBhdm9pZCByZXNpemluZwotICAgIHByaXZhdGUgWE1MU3RyaW5nQnVmZmVyIGJ1ZmZlciA9IG5ldyBYTUxTdHJpbmdCdWZmZXIoNiAqICgxIDw8IDExKSApOyAvLyA2IEtCCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFRIUkVTSEhPTERfTEVOR1RIID0gMSA8PCAxMiA7IC8vIDQgS0IKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIERFQlVHID0gZmFsc2U7Ci0KLSAgICAvKiogQ3JlYXRlcyB0aGUgaW5zdGFuY2Ugb2YgPGNvZGU+WE1MV3JpdGVyPC9jb2RlPgotICAgICAqLwotCi0gICAgIHB1YmxpYyBYTUxXcml0ZXIoV3JpdGVyIHdyaXRlcil7Ci0gICAgICAgICB0aGlzKHdyaXRlciwgVEhSRVNISE9MRF9MRU5HVEgpOwotICAgICB9Ci0KLSAgICAgLyoqCi0gICAgICAqIENyZWF0ZXMgdGhlIGluc3RuYWNlIG9mIDxjb2RlPlhNTFdyaXRlcjwvY29kZT4uCi0gICAgICAqCi0gICAgICAqIGF0bGVhc3QgYnVmZmVycyB0aGUgaW5wdXQgdG8gdGhlCi0gICAgICAqIDxjb2RlPnNpemU8L2NvZGU+IHNwZWNpZmllZC4KLSAgICAgICovCi0gICAgIHB1YmxpYyBYTUxXcml0ZXIoV3JpdGVyIHdyaXRlciwgaW50IHNpemUpewotICAgICAgICAgdGhpcy53cml0ZXIgPSB3cml0ZXIgOwotICAgICAgICAgdGhpcy5zaXplID0gc2l6ZTsKLSAgICAgfQotCi0gICAgIC8qKgotICAgICAqIFdyaXRlIGEgc2luZ2xlIGNoYXJhY3Rlci4gIFRoZSBjaGFyYWN0ZXIgdG8gYmUgd3JpdHRlbiBpcyBjb250YWluZWQgaW4KLSAgICAgKiB0aGUgMTYgbG93LW9yZGVyIGJpdHMgb2YgdGhlIGdpdmVuIGludGVnZXIgdmFsdWU7IHRoZSAxNiBoaWdoLW9yZGVyIGJpdHMKLSAgICAgKiBhcmUgaWdub3JlZC4KLSAgICAgKgotICAgICAqIDxwPiBTdWJjbGFzc2VzIHRoYXQgaW50ZW5kIHRvIHN1cHBvcnQgZWZmaWNpZW50IHNpbmdsZS1jaGFyYWN0ZXIgb3V0cHV0Ci0gICAgICogc2hvdWxkIG92ZXJyaWRlIHRoaXMgbWV0aG9kLgotICAgICAqCi0gICAgICogQHBhcmFtIGMgIGludCBzcGVjaWZ5aW5nIGEgY2hhcmFjdGVyIHRvIGJlIHdyaXR0ZW4uCi0gICAgICogQGV4Y2VwdGlvbiAgSU9FeGNlcHRpb24gIElmIGFuIEkvTyBlcnJvciBvY2N1cnMKLSAgICAgKi8KLQotICAgIHB1YmxpYyB2b2lkIHdyaXRlKGludCBjKSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgICAgICBlbnN1cmVPcGVuKCk7Ci0gICAgICAgIGJ1ZmZlci5hcHBlbmQoKGNoYXIpYyk7Ci0gICAgICAgIGNvbmRpdGlvbmFsV3JpdGUoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBXcml0ZSBhbiBhcnJheSBvZiBjaGFyYWN0ZXJzLgotICAgICAqCi0gICAgICogQHBhcmFtICBjYnVmICBBcnJheSBvZiBjaGFyYWN0ZXJzIHRvIGJlIHdyaXR0ZW4KLSAgICAgKgotICAgICAqIEBleGNlcHRpb24gIElPRXhjZXB0aW9uICBJZiBhbiBJL08gZXJyb3Igb2NjdXJzCi0gICAgICovCi0KLSAgICBwdWJsaWMgdm9pZCB3cml0ZShjaGFyIGNidWZbXSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLSAgICAgICAgd3JpdGUoY2J1ZiwgMCwgY2J1Zi5sZW5ndGgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFdyaXRlIGEgcG9ydGlvbiBvZiBhbiBhcnJheSBvZiBjaGFyYWN0ZXJzLgotICAgICAqCi0gICAgICogQHBhcmFtICBjYnVmICBBcnJheSBvZiBjaGFyYWN0ZXJzCi0gICAgICogQHBhcmFtICBvZmYgICBPZmZzZXQgZnJvbSB3aGljaCB0byBzdGFydCB3cml0aW5nIGNoYXJhY3RlcnMKLSAgICAgKiBAcGFyYW0gIGxlbiAgIE51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHdyaXRlCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uICBJT0V4Y2VwdGlvbiAgSWYgYW4gSS9PIGVycm9yIG9jY3VycwotICAgICAqLwotCi0gICAgcHVibGljIHZvaWQgd3JpdGUoY2hhciBjYnVmW10sIGludCBvZmYsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbnsKLSAgICAgICAgZW5zdXJlT3BlbigpOwotICAgICAgICAvL29wdGltaXphdGlvbjogaWYgZGF0YSBzaXplIHRvIGJlIHdyaXR0ZW4gaXMgbW9yZSB0aGFuIHRoZSAnc2l6ZScgc3BlY2lmaWVkLAotICAgICAgICAvL2RvIG5vdCBidWZmZXIgdGhlIGRhdGEgYnV0IHdyaXRlIHRoZSBkYXRhIHN0cmFpZ2h0IHRvIHRoZSB1bmRlcmx5aW5nIHN0cmVhbQotICAgICAgICBpZihsZW4gPiBzaXplKXsKLSAgICAgICAgICAgIC8vZmlyc3Qgd3JpdGUgdGhlIGRhdGEgdGhhdCBtYXkgYmUgcHJlc2VudCBpbiB0aGUgYnVmZmVyCi0gICAgICAgICAgICB3cml0ZUJ1ZmZlcmVkRGF0YSgpOwotICAgICAgICAgICAgLy93cml0ZSBkaXJlY3RseSB0byBzdHJlYW0KLSAgICAgICAgICAgIHdyaXRlci53cml0ZShjYnVmLCBvZmYsIGxlbik7Ci0gICAgICAgIH1lbHNlewotICAgICAgICAgICAgYnVmZmVyLmFwcGVuZChjYnVmLCBvZmYsIGxlbik7Ci0gICAgICAgICAgICBjb25kaXRpb25hbFdyaXRlKCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBXcml0ZSBhIHBvcnRpb24gb2YgYSBzdHJpbmcuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gIHN0ciAgQSBTdHJpbmcKLSAgICAgKiBAcGFyYW0gIG9mZiAgT2Zmc2V0IGZyb20gd2hpY2ggdG8gc3RhcnQgd3JpdGluZyBjaGFyYWN0ZXJzCi0gICAgICogQHBhcmFtICBsZW4gIE51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHdyaXRlCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uICBJT0V4Y2VwdGlvbiAgSWYgYW4gSS9PIGVycm9yIG9jY3VycwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHdyaXRlKFN0cmluZyBzdHIsIGludCBvZmYsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgIHdyaXRlKHN0ci50b0NoYXJBcnJheSgpLCBvZmYsIGxlbik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogV3JpdGUgYSBzdHJpbmcuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gIHN0ciAgU3RyaW5nIHRvIGJlIHdyaXR0ZW4KLSAgICAgKgotICAgICAqIEBleGNlcHRpb24gIElPRXhjZXB0aW9uICBJZiBhbiBJL08gZXJyb3Igb2NjdXJzCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgd3JpdGUoU3RyaW5nIHN0cikgdGhyb3dzIElPRXhjZXB0aW9uIHsKLSAgICAgICAgLy9vcHRpbWl6YXRpb246IGlmIGRhdGEgc2l6ZSB0byBiZSB3cml0dGVuIGlzIG1vcmUgdGhhbiB0aGUgJ3NpemUnIHNwZWNpZmllZCwKLSAgICAgICAgLy9kbyBub3QgYnVmZmVyIHRoZSBkYXRhIGJ1dCB3cml0ZSB0aGUgZGF0YSBzdHJhaWdodCB0byB0aGUgdW5kZXJseWluZyBzdHJlYW0gLSBuYi4KLSAgICAgICAgaWYoc3RyLmxlbmd0aCgpID4gc2l6ZSl7Ci0gICAgICAgICAgICAvL2ZpcnN0IHdyaXRlIHRoZSBkYXRhIHRoYXQgbWF5IGJlIHByZXNlbnQgaW4gdGhlIGJ1ZmZlcgotICAgICAgICAgICAgd3JpdGVCdWZmZXJlZERhdGEoKTsKLSAgICAgICAgICAgIC8vd3JpdGUgZGlyZWN0bHkgdG8gc3RyZWFtCi0gICAgICAgICAgICB3cml0ZXIud3JpdGUoc3RyKTsKLSAgICAgICAgfWVsc2V7Ci0gICAgICAgICAgICBidWZmZXIuYXBwZW5kKHN0cik7Ci0gICAgICAgICAgICBjb25kaXRpb25hbFdyaXRlKCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDbG9zZSB0aGUgc3RyZWFtLCBmbHVzaGluZyBpdCBmaXJzdC4gIE9uY2UgYSBzdHJlYW0gaGFzIGJlZW4gY2xvc2VkLAotICAgICAqIGZ1cnRoZXIgd3JpdGUoKSBvciBmbHVzaCgpIGludm9jYXRpb25zIHdpbGwgY2F1c2UgYW4gSU9FeGNlcHRpb24gdG8gYmUKLSAgICAgKiB0aHJvd24uICBDbG9zaW5nIGEgcHJldmlvdXNseS1jbG9zZWQgc3RyZWFtLCBob3dldmVyLCBoYXMgbm8gZWZmZWN0LgotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiAgSU9FeGNlcHRpb24gIElmIGFuIEkvTyBlcnJvciBvY2N1cnMKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgIGlmKHdyaXRlciA9PSBudWxsKSByZXR1cm47Ci0gICAgICAgIC8vZmx1c2ggaXQgZmlyc3QKLSAgICAgICAgZmx1c2goKTsKLSAgICAgICAgd3JpdGVyLmNsb3NlKCk7Ci0gICAgICAgIHdyaXRlciA9IG51bGwgOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEZsdXNoIHRoZSBzdHJlYW0uICBJZiB0aGUgc3RyZWFtIGhhcyBzYXZlZCBhbnkgY2hhcmFjdGVycyBmcm9tIHRoZQotICAgICAqIHZhcmlvdXMgd3JpdGUoKSBtZXRob2RzIGluIGEgYnVmZmVyLCB3cml0ZSB0aGVtIGltbWVkaWF0ZWx5IHRvIHRoZWlyCi0gICAgICogaW50ZW5kZWQgZGVzdGluYXRpb24uICBUaGVuLCBpZiB0aGF0IGRlc3RpbmF0aW9uIGlzIGFub3RoZXIgY2hhcmFjdGVyIG9yCi0gICAgICogYnl0ZSBzdHJlYW0sIGZsdXNoIGl0LiAgVGh1cyBvbmUgZmx1c2goKSBpbnZvY2F0aW9uIHdpbGwgZmx1c2ggYWxsIHRoZQotICAgICAqIGJ1ZmZlcnMgaW4gYSBjaGFpbiBvZiBXcml0ZXJzIGFuZCBPdXRwdXRTdHJlYW1zLgotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiAgSU9FeGNlcHRpb24gIElmIGFuIEkvTyBlcnJvciBvY2N1cnMKLSAgICAgKi8KLQotICAgIHB1YmxpYyB2b2lkIGZsdXNoKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLSAgICAgICAgZW5zdXJlT3BlbigpOwotICAgICAgICAvL3dyaXRlIGN1cnJlbnQgZGF0YSBwcmVzZW50IGluIHRoZSBidWZmZXIKLSAgICAgICAgd3JpdGVCdWZmZXJlZERhdGEoKTsKLSAgICAgICAgd3JpdGVyLmZsdXNoKCk7Ci0gICAgfQotCi0gICAgLyoqIFJlc2V0IHRoaXMgV3JpdGVyLgotICAgICAqCi0gICAgICogc2VlIEBzZXRXcml0ZXIoKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHJlc2V0KCl7Ci0gICAgICAgIHRoaXMud3JpdGVyID0gbnVsbDsKLSAgICAgICAgYnVmZmVyLmNsZWFyKCk7Ci0gICAgICAgIHRoaXMuc2l6ZSA9IFRIUkVTSEhPTERfTEVOR1RIOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldCB0aGUgZ2l2ZW4gPGNvZGU+V3JpdGVyPC9jb2RlPi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBXcml0ZXIgV3JpdGVyLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFdyaXRlcihXcml0ZXIgd3JpdGVyKXsKLSAgICAgICAgdGhpcy53cml0ZXIgPSB3cml0ZXI7Ci0gICAgICAgIGJ1ZmZlci5jbGVhcigpOwotICAgICAgICB0aGlzLnNpemUgPSBUSFJFU0hIT0xEX0xFTkdUSDsKLSAgICB9Ci0KLSAgICAvKiogU2V0IHRoZSBnaXZlbiA8Y29kZT5Xcml0ZXI8L2NvZGU+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gV3JpdGVyIFdyaXRlci4KLSAgICAgKiBAcGFyYW0gaW50ICAgIFdyaXRlciB3aWxsIGJ1ZmZlciB0aGUgY2hhcmFjdGVyIGRhdGEgc2l6ZSwgYWZ0ZXIgdGhhdCBkYXRhIGlzIHdyaXR0ZW4gdG8gc3RyZWFtLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFdyaXRlcihXcml0ZXIgd3JpdGVyLCBpbnQgc2l6ZSl7Ci0gICAgICAgIHRoaXMud3JpdGVyID0gd3JpdGVyOwotICAgICAgICB0aGlzLnNpemUgPSBzaXplOwotICAgIH0KLQotICAgLyoqCi0gICAgICogUmV0dXJucyB1bmRlcmx5aW5nIDxjb2RlPldyaXRlcjwvY29kZT4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgV3JpdGVyIGdldFdyaXRlcigpIHsKLSAgICAgICAgcmV0dXJuIHdyaXRlcjsKLSAgICB9Ci0KLSAgICAvKiogd3JpdGUgdGhlIGJ1ZmZlciBkYXRhLCBpZiB0aGUgYnVmZmVyIHNpemUgaGFzIGluY3JlYXNlZCB0aGUgc2l6ZSBzcGVjaWZpZWQKLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgY29uZGl0aW9uYWxXcml0ZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgIGlmKGJ1ZmZlci5sZW5ndGggPiBzaXplKXsKLSAgICAgICAgICAgIGlmKERFQlVHKXsKLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oImludGVybmFsIGJ1ZmZlciBsZW5ndGggIiArIGJ1ZmZlci5sZW5ndGggKyAiIGluY3JlYXNlZCBzaXplIGxpbWl0IDogIiArIHNpemUpOwotICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiRGF0YTogKCciICsgbmV3IFN0cmluZyhidWZmZXIuY2gsIGJ1ZmZlci5vZmZzZXQsIGJ1ZmZlci5sZW5ndGgpICsgIicpIik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICB3cml0ZUJ1ZmZlcmVkRGF0YSgpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqIFdyaXRlIHRoZSBkYXRhIHByZXNlbnQgaW4gdGhlIGJ1ZmZlciB0byB0aGUgd3JpdGVyLgotICAgICAqICBidWZmZXIgaXMgY2xlYXJlZCBhZnRlciB3cml0ZSBvcGVyYXRpb24uCi0gICAgICovCi0gICAgcHJpdmF0ZSB2b2lkIHdyaXRlQnVmZmVyZWREYXRhKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLSAgICAgICAgd3JpdGVyLndyaXRlKGJ1ZmZlci5jaCwgYnVmZmVyLm9mZnNldCwgYnVmZmVyLmxlbmd0aCk7Ci0gICAgICAgIGJ1ZmZlci5jbGVhcigpOwotICAgIH0KLQotICAgIC8qKiBDaGVjayB0byBtYWtlIHN1cmUgdGhhdCB0aGUgc3RyZWFtIGhhcyBub3QgYmVlbiBjbG9zZWQgKi8KLSAgICBwcml2YXRlIHZvaWQgZW5zdXJlT3BlbigpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgIGlmICh3cml0ZXIgPT0gbnVsbCl0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlN0cmVhbSBjbG9zZWQiKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvamF2YXgveG1sL1hNTENvbnN0YW50cy5qYXZhIGIvc3JjL2phdmF4L3htbC9YTUxDb25zdGFudHMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOGU4MDVlYy4uMDAwMDAwMAotLS0gYS9zcmMvamF2YXgveG1sL1hNTENvbnN0YW50cy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzkyICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDMsIDIwMTMsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLXBhY2thZ2UgamF2YXgueG1sOwotCi0vKioKLSAqIDxwPlV0aWxpdHkgY2xhc3MgdG8gY29udGFpbiBiYXNpYyBYTUwgdmFsdWVzIGFzIGNvbnN0YW50cy48L3A+Ci0gKgotICogQGF1dGhvciA8YSBocmVmPSJtYWlsdG86SmVmZi5TdXR0b3JAU3VuLmNvbSI+SmVmZiBTdXR0b3I8L2E+Ci0gKiBAdmVyc2lvbiAkUmV2aXNpb246IDEuOCAkLCAkRGF0ZTogMjAxMC8wNS8yNSAxNjoxOTo0NSAkCi0gKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3htbDExLyI+RXh0ZW5zaWJsZSBNYXJrdXAgTGFuZ3VhZ2UgKFhNTCkgMS4xPC9hPgotICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMteG1sIj5FeHRlbnNpYmxlIE1hcmt1cCBMYW5ndWFnZSAoWE1MKSAxLjAgKFNlY29uZCBFZGl0aW9uKTwvYT4KLSAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvWE1ML3htbC1WMTAtMmUtZXJyYXRhIj5YTUwgMS4wIFNlY29uZCBFZGl0aW9uIFNwZWNpZmljYXRpb24gRXJyYXRhPC9hPgotICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94bWwtbmFtZXMxMS8iPk5hbWVzcGFjZXMgaW4gWE1MIDEuMTwvYT4KLSAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLXhtbC1uYW1lcyI+TmFtZXNwYWNlcyBpbiBYTUw8L2E+Ci0gKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1hNTC94bWwtbmFtZXMtMTk5OTAxMTQtZXJyYXRhIj5OYW1lc3BhY2VzIGluIFhNTCBFcnJhdGE8L2E+Ci0gKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3htbHNjaGVtYS0xLyI+WE1MIFNjaGVtYSBQYXJ0IDE6IFN0cnVjdHVyZXM8L2E+Ci0gKiBAc2luY2UgMS41Ci0gKiovCi0KLXB1YmxpYyBmaW5hbCBjbGFzcyBYTUxDb25zdGFudHMgewotCi0gICAgLyoqCi0gICAgICogPHA+UHJpdmF0ZSBjb25zdHJ1Y3RvciB0byBwcmV2ZW50IGluc3RhbnRpYXRpb24uPC9wPgotICAgICAqLwotICAgICAgICBwcml2YXRlIFhNTENvbnN0YW50cygpIHsKLSAgICAgICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+TmFtZXNwYWNlIFVSSSB0byB1c2UgdG8gcmVwcmVzZW50IHRoYXQgdGhlcmUgaXMgbm8gTmFtZXNwYWNlLjwvcD4KLSAgICAgKgotICAgICAqIDxwPkRlZmluZWQgYnkgdGhlIE5hbWVzcGFjZSBzcGVjaWZpY2F0aW9uIHRvIGJlICIiLjwvcD4KLSAgICAgKgotICAgICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLXhtbC1uYW1lcy8jZGVmYXVsdGluZyI+Ci0gICAgICogTmFtZXNwYWNlcyBpbiBYTUwsIDUuMiBOYW1lc3BhY2UgRGVmYXVsdGluZzwvYT4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBOVUxMX05TX1VSSSA9ICIiOwotCi0gICAgLyoqCi0gICAgICogPHA+UHJlZml4IHRvIHVzZSB0byByZXByZXNlbnQgdGhlIGRlZmF1bHQgWE1MIE5hbWVzcGFjZS48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5EZWZpbmVkIGJ5IHRoZSBYTUwgc3BlY2lmaWNhdGlvbiB0byBiZSAiIi48L3A+Ci0gICAgICoKLSAgICAgKiBAc2VlIDxhCi0gICAgICogaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLXhtbC1uYW1lcy8jbnMtcXVhbG5hbWVzIj4KLSAgICAgKiBOYW1lc3BhY2VzIGluIFhNTCwgMy4gUXVhbGlmaWVkIE5hbWVzPC9hPgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIERFRkFVTFRfTlNfUFJFRklYID0gIiI7Ci0KLSAgICAvKioKLSAgICAgKiA8cD5UaGUgb2ZmaWNpYWwgWE1MIE5hbWVzcGFjZSBuYW1lIFVSSS48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5EZWZpbmVkIGJ5IHRoZSBYTUwgc3BlY2lmaWNhdGlvbiB0byBiZQotICAgICAqICJ7QGNvZGUgaHR0cDovL3d3dy53My5vcmcvWE1MLzE5OTgvbmFtZXNwYWNlfSIuPC9wPgotICAgICAqCi0gICAgICogQHNlZSA8YQotICAgICAqIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy14bWwtbmFtZXMvI25zLXF1YWxuYW1lcyI+Ci0gICAgICogTmFtZXNwYWNlcyBpbiBYTUwsIDMuIFF1YWxpZmllZCBOYW1lczwvYT4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxfTlNfVVJJID0KLSAgICAgICAgImh0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZSI7Ci0KLSAgICAvKioKLSAgICAgKiA8cD5UaGUgb2ZmaWNpYWwgWE1MIE5hbWVzcGFjZSBwcmVmaXguPC9wPgotICAgICAqCi0gICAgICogPHA+RGVmaW5lZCBieSB0aGUgWE1MIHNwZWNpZmljYXRpb24gdG8gYmUgIntAY29kZSB4bWx9Ii48L3A+Ci0gICAgICoKLSAgICAgKiBAc2VlIDxhCi0gICAgICogaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLXhtbC1uYW1lcy8jbnMtcXVhbG5hbWVzIj4KLSAgICAgKiBOYW1lc3BhY2VzIGluIFhNTCwgMy4gUXVhbGlmaWVkIE5hbWVzPDwvYT4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxfTlNfUFJFRklYID0gInhtbCI7Ci0KLSAgICAvKioKLSAgICAgKiA8cD5UaGUgb2ZmaWNpYWwgWE1MIGF0dHJpYnV0ZSB1c2VkIGZvciBzcGVjaWZ5aW5nIFhNTCBOYW1lc3BhY2UKLSAgICAgKiBkZWNsYXJhdGlvbnMsIHtAbGluayAjWE1MTlNfQVRUUklCVVRFCi0gICAgICogWE1MQ29uc3RhbnRzLlhNTE5TX0FUVFJJQlVURX0sIE5hbWVzcGFjZSBuYW1lIFVSSS48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5EZWZpbmVkIGJ5IHRoZSBYTUwgc3BlY2lmaWNhdGlvbiB0byBiZQotICAgICAqICJ7QGNvZGUgaHR0cDovL3d3dy53My5vcmcvMjAwMC94bWxucy99Ii48L3A+Ci0gICAgICoKLSAgICAgKiBAc2VlIDxhCi0gICAgICogaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLXhtbC1uYW1lcy8jbnMtcXVhbG5hbWVzIj4KLSAgICAgKiBOYW1lc3BhY2VzIGluIFhNTCwgMy4gUXVhbGlmaWVkIE5hbWVzPC9hPgotICAgICAqIEBzZWUgPGEKLSAgICAgKiBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9YTUwveG1sLW5hbWVzLTE5OTkwMTE0LWVycmF0YSI+Ci0gICAgICogTmFtZXNwYWNlcyBpbiBYTUwgRXJyYXRhPC9hPgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFhNTE5TX0FUVFJJQlVURV9OU19VUkkgPQotICAgICAgICAiaHR0cDovL3d3dy53My5vcmcvMjAwMC94bWxucy8iOwotCi0gICAgLyoqCi0gICAgICogPHA+VGhlIG9mZmljaWFsIFhNTCBhdHRyaWJ1dGUgdXNlZCBmb3Igc3BlY2lmeWluZyBYTUwgTmFtZXNwYWNlCi0gICAgICogZGVjbGFyYXRpb25zLjwvcD4KLSAgICAgKgotICAgICAqIDxwPkl0IGlzIDxzdHJvbmc+PGVtPk5PVDwvZW0+PC9zdHJvbmc+IHZhbGlkIHRvIHVzZSBhcyBhCi0gICAgICogcHJlZml4LiAgRGVmaW5lZCBieSB0aGUgWE1MIHNwZWNpZmljYXRpb24gdG8gYmUKLSAgICAgKiAie0Bjb2RlIHhtbG5zfSIuPC9wPgotICAgICAqCi0gICAgICogQHNlZSA8YQotICAgICAqIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy14bWwtbmFtZXMvI25zLXF1YWxuYW1lcyI+Ci0gICAgICogTmFtZXNwYWNlcyBpbiBYTUwsIDMuIFF1YWxpZmllZCBOYW1lczwvYT4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxOU19BVFRSSUJVVEUgPSAieG1sbnMiOwotCi0gICAgLyoqCi0gICAgICogPHA+VzNDIFhNTCBTY2hlbWEgTmFtZXNwYWNlIFVSSS48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5EZWZpbmVkIHRvIGJlICJ7QGNvZGUgaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWF9Ii4KLSAgICAgKgotICAgICAqIEBzZWUgPGEgaHJlZj0KLSAgICAgKiAgImh0dHA6Ly93d3cudzMub3JnL1RSL3htbHNjaGVtYS0xLyNJbnN0YW5jZV9Eb2N1bWVudF9Db25zdHJ1Y3Rpb25zIj4KLSAgICAgKiAgWE1MIFNjaGVtYSBQYXJ0IDE6Ci0gICAgICogIFN0cnVjdHVyZXMsIDIuNiBTY2hlbWEtUmVsYXRlZCBNYXJrdXAgaW4gRG9jdW1lbnRzIEJlaW5nIFZhbGlkYXRlZDwvYT4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXM0NfWE1MX1NDSEVNQV9OU19VUkkgPQotICAgICAgICAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiOwotCi0gICAgLyoqCi0gICAgICogPHA+VzNDIFhNTCBTY2hlbWEgSW5zdGFuY2UgTmFtZXNwYWNlIFVSSS48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5EZWZpbmVkIHRvIGJlICJ7QGNvZGUgaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2V9Ii48L3A+Ci0gICAgICoKLSAgICAgKiBAc2VlIDxhIGhyZWY9Ci0gICAgICogICJodHRwOi8vd3d3LnczLm9yZy9UUi94bWxzY2hlbWEtMS8jSW5zdGFuY2VfRG9jdW1lbnRfQ29uc3RydWN0aW9ucyI+Ci0gICAgICogIFhNTCBTY2hlbWEgUGFydCAxOgotICAgICAqICBTdHJ1Y3R1cmVzLCAyLjYgU2NoZW1hLVJlbGF0ZWQgTWFya3VwIGluIERvY3VtZW50cyBCZWluZyBWYWxpZGF0ZWQ8L2E+Ci0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgVzNDX1hNTF9TQ0hFTUFfSU5TVEFOQ0VfTlNfVVJJID0KLSAgICAgICAgImh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIjsKLQotICAgICAgICAvKioKLSAgICAgICAgICogPHA+VzNDIFhQYXRoIERhdGF0eXBlIE5hbWVzcGFjZSBVUkkuPC9wPgotICAgICAgICAgKgotICAgICAgICAgKiA8cD5EZWZpbmVkIHRvIGJlICJ7QGNvZGUgaHR0cDovL3d3dy53My5vcmcvMjAwMy8xMS94cGF0aC1kYXRhdHlwZXN9Ii48L3A+Ci0gICAgICAgICAqCi0gICAgICAgICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGgtZGF0YW1vZGVsIj5YUXVlcnkgMS4wIGFuZCBYUGF0aCAyLjAgRGF0YSBNb2RlbDwvYT4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFczQ19YUEFUSF9EQVRBVFlQRV9OU19VUkkgPSAiaHR0cDovL3d3dy53My5vcmcvMjAwMy8xMS94cGF0aC1kYXRhdHlwZXMiOwotCi0gICAgLyoqCi0gICAgICogPHA+WE1MIERvY3VtZW50IFR5cGUgRGVjbGFyYXRpb24gTmFtZXNwYWNlIFVSSSBhcyBhbiBhcmJpdHJhcnkgdmFsdWUuPC9wPgotICAgICAqCi0gICAgICogPHA+U2luY2Ugbm90IGZvcm1hbGx5IGRlZmluZWQgYnkgYW55IGV4aXN0aW5nIHN0YW5kYXJkLCBhcmJpdHJhcmlseSBkZWZpbmUgdG8gYmUgIntAY29kZSBodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMteG1sfSIuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MX0RURF9OU19VUkkgPSAiaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLXhtbCI7Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIDxwPlJFTEFYIE5HIE5hbWVzcGFjZSBVUkkuPC9wPgotICAgICAgICAgKgotICAgICAgICAgKiA8cD5EZWZpbmVkIHRvIGJlICJ7QGNvZGUgaHR0cDovL3JlbGF4bmcub3JnL25zL3N0cnVjdHVyZS8xLjB9Ii48L3A+Ci0gICAgICAgICAqCi0gICAgICAgICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3JlbGF4bmcub3JnL3NwZWMtMjAwMTEyMDMuaHRtbCI+UkVMQVggTkcgU3BlY2lmaWNhdGlvbjwvYT4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFJFTEFYTkdfTlNfVVJJID0gImh0dHA6Ly9yZWxheG5nLm9yZy9ucy9zdHJ1Y3R1cmUvMS4wIjsKLQotICAgICAgICAvKioKLSAgICAgICAgICogPHA+RmVhdHVyZSBmb3Igc2VjdXJlIHByb2Nlc3NpbmcuPC9wPgotICAgICAgICAgKgotICAgICAgICAgKiA8dWw+Ci0gICAgICAgICAqICAgPGxpPgotICAgICAgICAgKiAgICAge0Bjb2RlIHRydWV9IGluc3RydWN0cyB0aGUgaW1wbGVtZW50YXRpb24gdG8gcHJvY2VzcyBYTUwgc2VjdXJlbHkuCi0gICAgICAgICAqICAgICBUaGlzIG1heSBzZXQgbGltaXRzIG9uIFhNTCBjb25zdHJ1Y3RzIHRvIGF2b2lkIGNvbmRpdGlvbnMgc3VjaCBhcyBkZW5pYWwgb2Ygc2VydmljZSBhdHRhY2tzLgotICAgICAgICAgKiAgIDwvbGk+Ci0gICAgICAgICAqICAgPGxpPgotICAgICAgICAgKiAgICAge0Bjb2RlIGZhbHNlfSBpbnN0cnVjdHMgdGhlIGltcGxlbWVudGF0aW9uIHRvIHByb2Nlc3MgWE1MIGluIGFjY29yZGFuY2Ugd2l0aCB0aGUgWE1MIHNwZWNpZmljYXRpb25zCi0gICAgICAgICAqICAgICBpZ25vcmluZyBzZWN1cml0eSBpc3N1ZXMgc3VjaCBhcyBsaW1pdHMgb24gWE1MIGNvbnN0cnVjdHMgdG8gYXZvaWQgY29uZGl0aW9ucyBzdWNoIGFzIGRlbmlhbCBvZiBzZXJ2aWNlIGF0dGFja3MuCi0gICAgICAgICAqICAgPC9saT4KLSAgICAgICAgICogPC91bD4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEZFQVRVUkVfU0VDVVJFX1BST0NFU1NJTkcgPSAiaHR0cDovL2phdmF4LnhtbC5YTUxDb25zdGFudHMvZmVhdHVyZS9zZWN1cmUtcHJvY2Vzc2luZyI7Ci0KLQotICAgICAgICAvKioKLSAgICAgICAgICogPHA+UHJvcGVydHk6IGFjY2Vzc0V4dGVybmFsRFREPC9wPgotICAgICAgICAgKgotICAgICAgICAgKiA8cD4KLSAgICAgICAgICogUmVzdHJpY3QgYWNjZXNzIHRvIGV4dGVybmFsIERURHMgYW5kIGV4dGVybmFsIEVudGl0eSBSZWZlcmVuY2VzIHRvIHRoZSBwcm90b2NvbHMgc3BlY2lmaWVkLgotICAgICAgICAgKiBJZiBhY2Nlc3MgaXMgZGVuaWVkIGR1ZSB0byB0aGUgcmVzdHJpY3Rpb24gb2YgdGhpcyBwcm9wZXJ0eSwgYSBydW50aW1lIGV4Y2VwdGlvbiB0aGF0Ci0gICAgICAgICAqIGlzIHNwZWNpZmljIHRvIHRoZSBjb250ZXh0IGlzIHRocm93bi4gSW4gdGhlIGNhc2Ugb2Yge0BsaW5rIGphdmF4LnhtbC5wYXJzZXJzLlNBWFBhcnNlcn0KLSAgICAgICAgICogZm9yIGV4YW1wbGUsIHtAbGluayBvcmcueG1sLnNheC5TQVhFeGNlcHRpb259IGlzIHRocm93bi4KLSAgICAgICAgICogPC9wPgotICAgICAgICAgKgotICAgICAgICAgKiA8cD4KLSAgICAgICAgICogPGI+VmFsdWU6IDwvYj4gYSBsaXN0IG9mIHByb3RvY29scyBzZXBhcmF0ZWQgYnkgY29tbWEuIEEgcHJvdG9jb2wgaXMgdGhlIHNjaGVtZSBwb3J0aW9uIG9mIGEKLSAgICAgICAgICoge0BsaW5rIGphdmEubmV0LlVSSX0sIG9yIGluIHRoZSBjYXNlIG9mIHRoZSBKQVIgcHJvdG9jb2wsICJqYXIiIHBsdXMgdGhlIHNjaGVtZSBwb3J0aW9uCi0gICAgICAgICAqIHNlcGFyYXRlZCBieSBjb2xvbi4KLSAgICAgICAgICogQSBzY2hlbWUgaXMgZGVmaW5lZCBhczoKLSAgICAgICAgICoKLSAgICAgICAgICogPGJsb2NrcXVvdGU+Ci0gICAgICAgICAqIHNjaGVtZSA9IGFscGhhICooIGFscGhhIHwgZGlnaXQgfCAiKyIgfCAiLSIgfCAiLiIgKTxicj4KLSAgICAgICAgICogd2hlcmUgYWxwaGEgPSBhLXogYW5kIEEtWi48YnI+PGJyPgotICAgICAgICAgKgotICAgICAgICAgKiBBbmQgdGhlIEpBUiBwcm90b2NvbDo8YnI+Ci0gICAgICAgICAqCi0gICAgICAgICAqIGphcls6c2NoZW1lXTxicj48YnI+Ci0gICAgICAgICAqCi0gICAgICAgICAqIFByb3RvY29scyBpbmNsdWRpbmcgdGhlIGtleXdvcmQgImphciIgYXJlIGNhc2UtaW5zZW5zaXRpdmUuIEFueSB3aGl0ZXNwYWNlcyBhcyBkZWZpbmVkIGJ5Ci0gICAgICAgICAqIHtAbGluayBqYXZhLmxhbmcuQ2hhcmFjdGVyI2lzU3BhY2VDaGFyIH0gaW4gdGhlIHZhbHVlIHdpbGwgYmUgaWdub3JlZC4KLSAgICAgICAgICogRXhhbXBsZXMgb2YgcHJvdG9jb2xzIGFyZSBmaWxlLCBodHRwLCBqYXI6ZmlsZS4KLSAgICAgICAgICoKLSAgICAgICAgICogPC9ibG9ja3F1b3RlPgotICAgICAgICAgKjwvcD4KLSAgICAgICAgICoKLSAgICAgICAgICo8cD4KLSAgICAgICAgICogPGI+RGVmYXVsdCB2YWx1ZTo8L2I+IFRoZSBkZWZhdWx0IHZhbHVlIGlzIGltcGxlbWVudGF0aW9uIHNwZWNpZmljIGFuZCB0aGVyZWZvcmUgbm90IHNwZWNpZmllZC4KLSAgICAgICAgICogVGhlIGZvbGxvd2luZyBvcHRpb25zIGFyZSBwcm92aWRlZCBmb3IgY29uc2lkZXJhdGlvbjoKLSAgICAgICAgICogPGJsb2NrcXVvdGU+Ci0gICAgICAgICAqIDxVTD4KLSAgICAgICAgICogICAgIDxMST5hbiBlbXB0eSBzdHJpbmcgdG8gZGVueSBhbGwgYWNjZXNzIHRvIGV4dGVybmFsIHJlZmVyZW5jZXM7PC9MST4KLSAgICAgICAgICogICAgIDxMST5hIHNwZWNpZmljIHByb3RvY29sLCBzdWNoIGFzIGZpbGUsIHRvIGdpdmUgcGVybWlzc2lvbiB0byBvbmx5IHRoZSBwcm90b2NvbDs8L0xJPgotICAgICAgICAgKiAgICAgPExJPnRoZSBrZXl3b3JkICJhbGwiIHRvIGdyYW50ICBwZXJtaXNzaW9uIHRvIGFsbCBwcm90b2NvbHMuPC9MST4KLSAgICAgICAgICo8L1VMPjxicj4KLSAgICAgICAgICogICAgICBXaGVuIEZFQVRVUkVfU0VDVVJFX1BST0NFU1NJTkcgaXMgZW5hYmxlZCwgIGl0IGlzIHJlY29tbWVuZGVkIHRoYXQgaW1wbGVtZW50YXRpb25zCi0gICAgICAgICAqICAgICAgcmVzdHJpY3QgZXh0ZXJuYWwgY29ubmVjdGlvbnMgYnkgZGVmYXVsdCwgdGhvdWdoIHRoaXMgbWF5IGNhdXNlIHByb2JsZW1zIGZvciBhcHBsaWNhdGlvbnMKLSAgICAgICAgICogICAgICB0aGF0IHByb2Nlc3MgWE1ML1hTRC9YU0wgd2l0aCBleHRlcm5hbCByZWZlcmVuY2VzLgotICAgICAgICAgKiA8L2Jsb2NrcXVvdGU+Ci0gICAgICAgICAqIDwvcD4KLSAgICAgICAgICoKLSAgICAgICAgICogPHA+Ci0gICAgICAgICAqIDxiPkdyYW50aW5nIGFsbCBhY2Nlc3M6PC9iPiAgdGhlIGtleXdvcmQgImFsbCIgZ3JhbnRzIHBlcm1pc3Npb24gdG8gYWxsIHByb3RvY29scy4KLSAgICAgICAgICogPC9wPgotICAgICAgICAgKiA8cD4KLSAgICAgICAgICogPGI+U3lzdGVtIFByb3BlcnR5OjwvYj4gVGhlIHZhbHVlIG9mIHRoaXMgcHJvcGVydHkgY2FuIGJlIHNldCBvciBvdmVycmlkZGVuIGJ5Ci0gICAgICAgICAqIHN5c3RlbSBwcm9wZXJ0eSB7QGNvZGUgamF2YXgueG1sLmFjY2Vzc0V4dGVybmFsRFREfS4KLSAgICAgICAgICogPC9wPgotICAgICAgICAgKgotICAgICAgICAgKiA8cD4KLSAgICAgICAgICogPGI+JHtKQVZBX0hPTUV9L2xpYi9qYXhwLnByb3BlcnRpZXM6PC9iPiBUaGlzIGNvbmZpZ3VyYXRpb24gZmlsZSBpcyBpbiBzdGFuZGFyZAotICAgICAgICAgKiB7QGxpbmsgamF2YS51dGlsLlByb3BlcnRpZXN9IGZvcm1hdC4gSWYgdGhlIGZpbGUgZXhpc3RzIGFuZCB0aGUgc3lzdGVtIHByb3BlcnR5IGlzIHNwZWNpZmllZCwKLSAgICAgICAgICogaXRzIHZhbHVlIHdpbGwgYmUgdXNlZCB0byBvdmVycmlkZSB0aGUgZGVmYXVsdCBvZiB0aGUgcHJvcGVydHkuCi0gICAgICAgICAqIDwvcD4KLSAgICAgICAgICoKLSAgICAgICAgICogPHA+Ci0gICAgICAgICAqCi0gICAgICAgICAqIDwvcD4KLSAgICAgICAgICogQHNpbmNlIDEuNwotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQUNDRVNTX0VYVEVSTkFMX0RURCA9ICJodHRwOi8vamF2YXgueG1sLlhNTENvbnN0YW50cy9wcm9wZXJ0eS9hY2Nlc3NFeHRlcm5hbERURCI7Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIDxwPlByb3BlcnR5OiBhY2Nlc3NFeHRlcm5hbFNjaGVtYTwvcD4KLSAgICAgICAgICoKLSAgICAgICAgICogPHA+Ci0gICAgICAgICAqIFJlc3RyaWN0IGFjY2VzcyB0byB0aGUgcHJvdG9jb2xzIHNwZWNpZmllZCBmb3IgZXh0ZXJuYWwgcmVmZXJlbmNlIHNldCBieSB0aGUKLSAgICAgICAgICogc2NoZW1hTG9jYXRpb24gYXR0cmlidXRlLCBJbXBvcnQgYW5kIEluY2x1ZGUgZWxlbWVudC4gSWYgYWNjZXNzIGlzIGRlbmllZAotICAgICAgICAgKiBkdWUgdG8gdGhlIHJlc3RyaWN0aW9uIG9mIHRoaXMgcHJvcGVydHksIGEgcnVudGltZSBleGNlcHRpb24gdGhhdCBpcyBzcGVjaWZpYwotICAgICAgICAgKiB0byB0aGUgY29udGV4dCBpcyB0aHJvd24uIEluIHRoZSBjYXNlIG9mIHtAbGluayBqYXZheC54bWwudmFsaWRhdGlvbi5TY2hlbWFGYWN0b3J5fQotICAgICAgICAgKiBmb3IgZXhhbXBsZSwgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIGlzIHRocm93bi4KLSAgICAgICAgICogPC9wPgotICAgICAgICAgKiA8cD4KLSAgICAgICAgICogPGI+VmFsdWU6PC9iPiBhIGxpc3Qgb2YgcHJvdG9jb2xzIHNlcGFyYXRlZCBieSBjb21tYS4gQSBwcm90b2NvbCBpcyB0aGUgc2NoZW1lIHBvcnRpb24gb2YgYQotICAgICAgICAgKiB7QGxpbmsgamF2YS5uZXQuVVJJfSwgb3IgaW4gdGhlIGNhc2Ugb2YgdGhlIEpBUiBwcm90b2NvbCwgImphciIgcGx1cyB0aGUgc2NoZW1lIHBvcnRpb24KLSAgICAgICAgICogc2VwYXJhdGVkIGJ5IGNvbG9uLgotICAgICAgICAgKiBBIHNjaGVtZSBpcyBkZWZpbmVkIGFzOgotICAgICAgICAgKgotICAgICAgICAgKiA8YmxvY2txdW90ZT4KLSAgICAgICAgICogc2NoZW1lID0gYWxwaGEgKiggYWxwaGEgfCBkaWdpdCB8ICIrIiB8ICItIiB8ICIuIiApPGJyPgotICAgICAgICAgKiB3aGVyZSBhbHBoYSA9IGEteiBhbmQgQS1aLjxicj48YnI+Ci0gICAgICAgICAqCi0gICAgICAgICAqIEFuZCB0aGUgSkFSIHByb3RvY29sOjxicj4KLSAgICAgICAgICoKLSAgICAgICAgICogamFyWzpzY2hlbWVdPGJyPjxicj4KLSAgICAgICAgICoKLSAgICAgICAgICogUHJvdG9jb2xzIGluY2x1ZGluZyB0aGUga2V5d29yZCAiamFyIiBhcmUgY2FzZS1pbnNlbnNpdGl2ZS4gQW55IHdoaXRlc3BhY2VzIGFzIGRlZmluZWQgYnkKLSAgICAgICAgICoge0BsaW5rIGphdmEubGFuZy5DaGFyYWN0ZXIjaXNTcGFjZUNoYXIgfSBpbiB0aGUgdmFsdWUgd2lsbCBiZSBpZ25vcmVkLgotICAgICAgICAgKiBFeGFtcGxlcyBvZiBwcm90b2NvbHMgYXJlIGZpbGUsIGh0dHAsIGphcjpmaWxlLgotICAgICAgICAgKgotICAgICAgICAgKiA8L2Jsb2NrcXVvdGU+Ci0gICAgICAgICAqPC9wPgotICAgICAgICAgKgotICAgICAgICAgKjxwPgotICAgICAgICAgKiA8Yj5EZWZhdWx0IHZhbHVlOjwvYj4gVGhlIGRlZmF1bHQgdmFsdWUgaXMgaW1wbGVtZW50YXRpb24gc3BlY2lmaWMgYW5kIHRoZXJlZm9yZSBub3Qgc3BlY2lmaWVkLgotICAgICAgICAgKiBUaGUgZm9sbG93aW5nIG9wdGlvbnMgYXJlIHByb3ZpZGVkIGZvciBjb25zaWRlcmF0aW9uOgotICAgICAgICAgKiA8YmxvY2txdW90ZT4KLSAgICAgICAgICogPFVMPgotICAgICAgICAgKiAgICAgPExJPmFuIGVtcHR5IHN0cmluZyB0byBkZW55IGFsbCBhY2Nlc3MgdG8gZXh0ZXJuYWwgcmVmZXJlbmNlczs8L0xJPgotICAgICAgICAgKiAgICAgPExJPmEgc3BlY2lmaWMgcHJvdG9jb2wsIHN1Y2ggYXMgZmlsZSwgdG8gZ2l2ZSBwZXJtaXNzaW9uIHRvIG9ubHkgdGhlIHByb3RvY29sOzwvTEk+Ci0gICAgICAgICAqICAgICA8TEk+dGhlIGtleXdvcmQgImFsbCIgdG8gZ3JhbnQgIHBlcm1pc3Npb24gdG8gYWxsIHByb3RvY29scy48L0xJPgotICAgICAgICAgKjwvVUw+PGJyPgotICAgICAgICAgKiAgICAgIFdoZW4gRkVBVFVSRV9TRUNVUkVfUFJPQ0VTU0lORyBpcyBlbmFibGVkLCAgaXQgaXMgcmVjb21tZW5kZWQgdGhhdCBpbXBsZW1lbnRhdGlvbnMKLSAgICAgICAgICogICAgICByZXN0cmljdCBleHRlcm5hbCBjb25uZWN0aW9ucyBieSBkZWZhdWx0LCB0aG91Z2ggdGhpcyBtYXkgY2F1c2UgcHJvYmxlbXMgZm9yIGFwcGxpY2F0aW9ucwotICAgICAgICAgKiAgICAgIHRoYXQgcHJvY2VzcyBYTUwvWFNEL1hTTCB3aXRoIGV4dGVybmFsIHJlZmVyZW5jZXMuCi0gICAgICAgICAqIDwvYmxvY2txdW90ZT4KLSAgICAgICAgICogPC9wPgotICAgICAgICAgKiA8cD4KLSAgICAgICAgICogPGI+R3JhbnRpbmcgYWxsIGFjY2Vzczo8L2I+ICB0aGUga2V5d29yZCAiYWxsIiBncmFudHMgcGVybWlzc2lvbiB0byBhbGwgcHJvdG9jb2xzLgotICAgICAgICAgKiA8L3A+Ci0gICAgICAgICAqCi0gICAgICAgICAqIDxwPgotICAgICAgICAgKiA8Yj5TeXN0ZW0gUHJvcGVydHk6PC9iPiBUaGUgdmFsdWUgb2YgdGhpcyBwcm9wZXJ0eSBjYW4gYmUgc2V0IG9yIG92ZXJyaWRkZW4gYnkKLSAgICAgICAgICogc3lzdGVtIHByb3BlcnR5IHtAY29kZSBqYXZheC54bWwuYWNjZXNzRXh0ZXJuYWxTY2hlbWF9Ci0gICAgICAgICAqIDwvcD4KLSAgICAgICAgICoKLSAgICAgICAgICogPHA+Ci0gICAgICAgICAqIDxiPiR7SkFWQV9IT01FfS9saWIvamF4cC5wcm9wZXJ0aWVzOjwvYj4gVGhpcyBjb25maWd1cmF0aW9uIGZpbGUgaXMgaW4gc3RhbmRhcmQKLSAgICAgICAgICogamF2YS51dGlsLlByb3BlcnRpZXMgZm9ybWF0LiBJZiB0aGUgZmlsZSBleGlzdHMgYW5kIHRoZSBzeXN0ZW0gcHJvcGVydHkgaXMgc3BlY2lmaWVkLAotICAgICAgICAgKiBpdHMgdmFsdWUgd2lsbCBiZSB1c2VkIHRvIG92ZXJyaWRlIHRoZSBkZWZhdWx0IG9mIHRoZSBwcm9wZXJ0eS4KLSAgICAgICAgICoKLSAgICAgICAgICogQHNpbmNlIDEuNwotICAgICAgICAgKiA8L3A+Ci0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBQ0NFU1NfRVhURVJOQUxfU0NIRU1BID0gImh0dHA6Ly9qYXZheC54bWwuWE1MQ29uc3RhbnRzL3Byb3BlcnR5L2FjY2Vzc0V4dGVybmFsU2NoZW1hIjsKLQotICAgICAgICAvKioKLSAgICAgICAgICogPHA+UHJvcGVydHk6IGFjY2Vzc0V4dGVybmFsU3R5bGVzaGVldDwvcD4KLSAgICAgICAgICoKLSAgICAgICAgICogPHA+Ci0gICAgICAgICAqIFJlc3RyaWN0IGFjY2VzcyB0byB0aGUgcHJvdG9jb2xzIHNwZWNpZmllZCBmb3IgZXh0ZXJuYWwgcmVmZXJlbmNlcyBzZXQgYnkgdGhlCi0gICAgICAgICAqIHN0eWxlc2hlZXQgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiwgSW1wb3J0IGFuZCBJbmNsdWRlIGVsZW1lbnQsIGFuZCBkb2N1bWVudCBmdW5jdGlvbi4KLSAgICAgICAgICogSWYgYWNjZXNzIGlzIGRlbmllZCBkdWUgdG8gdGhlIHJlc3RyaWN0aW9uIG9mIHRoaXMgcHJvcGVydHksIGEgcnVudGltZSBleGNlcHRpb24KLSAgICAgICAgICogdGhhdCBpcyBzcGVjaWZpYyB0byB0aGUgY29udGV4dCBpcyB0aHJvd24uIEluIHRoZSBjYXNlIG9mIGNvbnN0cnVjdGluZyBuZXcKLSAgICAgICAgICoge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJ9IGZvciBleGFtcGxlLAotICAgICAgICAgKiB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb259Ci0gICAgICAgICAqIHdpbGwgYmUgdGhyb3duIGJ5IHRoZSB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckZhY3Rvcnl9LgotICAgICAgICAgKiA8L3A+Ci0gICAgICAgICAqIDxwPgotICAgICAgICAgKiA8Yj5WYWx1ZTo8L2I+IGEgbGlzdCBvZiBwcm90b2NvbHMgc2VwYXJhdGVkIGJ5IGNvbW1hLiBBIHByb3RvY29sIGlzIHRoZSBzY2hlbWUgcG9ydGlvbiBvZiBhCi0gICAgICAgICAqIHtAbGluayBqYXZhLm5ldC5VUkl9LCBvciBpbiB0aGUgY2FzZSBvZiB0aGUgSkFSIHByb3RvY29sLCAiamFyIiBwbHVzIHRoZSBzY2hlbWUgcG9ydGlvbgotICAgICAgICAgKiBzZXBhcmF0ZWQgYnkgY29sb24uCi0gICAgICAgICAqIEEgc2NoZW1lIGlzIGRlZmluZWQgYXM6Ci0gICAgICAgICAqCi0gICAgICAgICAqIDxibG9ja3F1b3RlPgotICAgICAgICAgKiBzY2hlbWUgPSBhbHBoYSAqKCBhbHBoYSB8IGRpZ2l0IHwgIisiIHwgIi0iIHwgIi4iICk8YnI+Ci0gICAgICAgICAqIHdoZXJlIGFscGhhID0gYS16IGFuZCBBLVouPGJyPjxicj4KLSAgICAgICAgICoKLSAgICAgICAgICogQW5kIHRoZSBKQVIgcHJvdG9jb2w6PGJyPgotICAgICAgICAgKgotICAgICAgICAgKiBqYXJbOnNjaGVtZV08YnI+PGJyPgotICAgICAgICAgKgotICAgICAgICAgKiBQcm90b2NvbHMgaW5jbHVkaW5nIHRoZSBrZXl3b3JkICJqYXIiIGFyZSBjYXNlLWluc2Vuc2l0aXZlLiBBbnkgd2hpdGVzcGFjZXMgYXMgZGVmaW5lZCBieQotICAgICAgICAgKiB7QGxpbmsgamF2YS5sYW5nLkNoYXJhY3RlciNpc1NwYWNlQ2hhciB9IGluIHRoZSB2YWx1ZSB3aWxsIGJlIGlnbm9yZWQuCi0gICAgICAgICAqIEV4YW1wbGVzIG9mIHByb3RvY29scyBhcmUgZmlsZSwgaHR0cCwgamFyOmZpbGUuCi0gICAgICAgICAqCi0gICAgICAgICAqIDwvYmxvY2txdW90ZT4KLSAgICAgICAgICo8L3A+Ci0gICAgICAgICAqCi0gICAgICAgICAqPHA+Ci0gICAgICAgICAqIDxiPkRlZmF1bHQgdmFsdWU6PC9iPiBUaGUgZGVmYXVsdCB2YWx1ZSBpcyBpbXBsZW1lbnRhdGlvbiBzcGVjaWZpYyBhbmQgdGhlcmVmb3JlIG5vdCBzcGVjaWZpZWQuCi0gICAgICAgICAqIFRoZSBmb2xsb3dpbmcgb3B0aW9ucyBhcmUgcHJvdmlkZWQgZm9yIGNvbnNpZGVyYXRpb246Ci0gICAgICAgICAqIDxibG9ja3F1b3RlPgotICAgICAgICAgKiA8VUw+Ci0gICAgICAgICAqICAgICA8TEk+YW4gZW1wdHkgc3RyaW5nIHRvIGRlbnkgYWxsIGFjY2VzcyB0byBleHRlcm5hbCByZWZlcmVuY2VzOzwvTEk+Ci0gICAgICAgICAqICAgICA8TEk+YSBzcGVjaWZpYyBwcm90b2NvbCwgc3VjaCBhcyBmaWxlLCB0byBnaXZlIHBlcm1pc3Npb24gdG8gb25seSB0aGUgcHJvdG9jb2w7PC9MST4KLSAgICAgICAgICogICAgIDxMST50aGUga2V5d29yZCAiYWxsIiB0byBncmFudCAgcGVybWlzc2lvbiB0byBhbGwgcHJvdG9jb2xzLjwvTEk+Ci0gICAgICAgICAqPC9VTD48YnI+Ci0gICAgICAgICAqICAgICAgV2hlbiBGRUFUVVJFX1NFQ1VSRV9QUk9DRVNTSU5HIGlzIGVuYWJsZWQsICBpdCBpcyByZWNvbW1lbmRlZCB0aGF0IGltcGxlbWVudGF0aW9ucwotICAgICAgICAgKiAgICAgIHJlc3RyaWN0IGV4dGVybmFsIGNvbm5lY3Rpb25zIGJ5IGRlZmF1bHQsIHRob3VnaCB0aGlzIG1heSBjYXVzZSBwcm9ibGVtcyBmb3IgYXBwbGljYXRpb25zCi0gICAgICAgICAqICAgICAgdGhhdCBwcm9jZXNzIFhNTC9YU0QvWFNMIHdpdGggZXh0ZXJuYWwgcmVmZXJlbmNlcy4KLSAgICAgICAgICogPC9ibG9ja3F1b3RlPgotICAgICAgICAgKiA8L3A+Ci0gICAgICAgICAqIDxwPgotICAgICAgICAgKiA8Yj5HcmFudGluZyBhbGwgYWNjZXNzOjwvYj4gIHRoZSBrZXl3b3JkICJhbGwiIGdyYW50cyBwZXJtaXNzaW9uIHRvIGFsbCBwcm90b2NvbHMuCi0gICAgICAgICAqIDwvcD4KLSAgICAgICAgICoKLSAgICAgICAgICogPHA+Ci0gICAgICAgICAqIDxiPlN5c3RlbSBQcm9wZXJ0eTo8L2I+IFRoZSB2YWx1ZSBvZiB0aGlzIHByb3BlcnR5IGNhbiBiZSBzZXQgb3Igb3ZlcnJpZGRlbiBieQotICAgICAgICAgKiBzeXN0ZW0gcHJvcGVydHkge0Bjb2RlIGphdmF4LnhtbC5hY2Nlc3NFeHRlcm5hbFN0eWxlc2hlZXR9Ci0gICAgICAgICAqIDwvcD4KLSAgICAgICAgICoKLSAgICAgICAgICogPHA+Ci0gICAgICAgICAqIDxiPiR7SkFWQV9IT01FfS9saWIvamF4cC5wcm9wZXJ0aWVzOiA8L2I+IFRoaXMgY29uZmlndXJhdGlvbiBmaWxlIGlzIGluIHN0YW5kYXJkCi0gICAgICAgICAqIGphdmEudXRpbC5Qcm9wZXJ0aWVzIGZvcm1hdC4gSWYgdGhlIGZpbGUgZXhpc3RzIGFuZCB0aGUgc3lzdGVtIHByb3BlcnR5IGlzIHNwZWNpZmllZCwKLSAgICAgICAgICogaXRzIHZhbHVlIHdpbGwgYmUgdXNlZCB0byBvdmVycmlkZSB0aGUgZGVmYXVsdCBvZiB0aGUgcHJvcGVydHkuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBzaW5jZSAxLjcKLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEFDQ0VTU19FWFRFUk5BTF9TVFlMRVNIRUVUID0gImh0dHA6Ly9qYXZheC54bWwuWE1MQ29uc3RhbnRzL3Byb3BlcnR5L2FjY2Vzc0V4dGVybmFsU3R5bGVzaGVldCI7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9qYXZheC94bWwvZGF0YXR5cGUvRGF0YXR5cGVDb25maWd1cmF0aW9uRXhjZXB0aW9uLmphdmEgYi9zcmMvamF2YXgveG1sL2RhdGF0eXBlL0RhdGF0eXBlQ29uZmlndXJhdGlvbkV4Y2VwdGlvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3Zjk2Y2U5Li4wMDAwMDAwCi0tLSBhL3NyYy9qYXZheC94bWwvZGF0YXR5cGUvRGF0YXR5cGVDb25maWd1cmF0aW9uRXhjZXB0aW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3OSArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDA0LCAyMDA1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi1wYWNrYWdlIGphdmF4LnhtbC5kYXRhdHlwZTsKLQotLyoqCi0gKiA8cD5JbmRpY2F0ZXMgYSBzZXJpb3VzIGNvbmZpZ3VyYXRpb24gZXJyb3IuPC9wPgotICoKLSAqIEBhdXRob3IgPGEgaHJlZj0ibWFpbHRvOkplZmYuU3V0dG9yQFN1bi5jb20iPkplZmYgU3V0dG9yPC9hPgotICogQHNpbmNlIDEuNQotICovCi0KLXB1YmxpYyBjbGFzcyBEYXRhdHlwZUNvbmZpZ3VyYXRpb25FeGNlcHRpb24gZXh0ZW5kcyBFeGNlcHRpb24gewotCi0gICAgLyoqCi0gICAgICogPHA+Q3JlYXRlIGEgbmV3IDxjb2RlPkRhdGF0eXBlQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjwvY29kZT4gd2l0aAotICAgICAqIG5vIHNwZWNpZmllZCBkZXRhaWwgbWVzYWdlIGFuZCBjYXVzZS48L3A+Ci0gICAgICovCi0KLSAgICBwdWJsaWMgRGF0YXR5cGVDb25maWd1cmF0aW9uRXhjZXB0aW9uKCkgewotICAgICAgICBzdXBlcigpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPkNyZWF0ZSBhIG5ldyA8Y29kZT5EYXRhdHlwZUNvbmZpZ3VyYXRpb25FeGNlcHRpb248L2NvZGU+IHdpdGgKLSAgICAgICAgICogdGhlIHNwZWNpZmllZCBkZXRhaWwgbWVzc2FnZS48L3A+Ci0gICAgICoKLSAgICAgICAgICogQHBhcmFtIG1lc3NhZ2UgVGhlIGRldGFpbCBtZXNzYWdlLgotICAgICAqLwotCi0gICAgcHVibGljIERhdGF0eXBlQ29uZmlndXJhdGlvbkV4Y2VwdGlvbihTdHJpbmcgbWVzc2FnZSkgewotICAgICAgICBzdXBlcihtZXNzYWdlKTsKLSAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIDxwPkNyZWF0ZSBhIG5ldyA8Y29kZT5EYXRhdHlwZUNvbmZpZ3VyYXRpb25FeGNlcHRpb248L2NvZGU+IHdpdGgKLSAgICAgICAgICogdGhlIHNwZWNpZmllZCBkZXRhaWwgbWVzc2FnZSBhbmQgY2F1c2UuPC9wPgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gbWVzc2FnZSBUaGUgZGV0YWlsIG1lc3NhZ2UuCi0gICAgICAgICAqIEBwYXJhbSBjYXVzZSBUaGUgY2F1c2UuICBBIDxjb2RlPm51bGw8L2NvZGU+IHZhbHVlIGlzIHBlcm1pdHRlZCwgYW5kIGluZGljYXRlcyB0aGF0IHRoZSBjYXVzZSBpcyBub25leGlzdGVudCBvciB1bmtub3duLgotICAgICAgICAgKi8KLQotICAgICAgICBwdWJsaWMgRGF0YXR5cGVDb25maWd1cmF0aW9uRXhjZXB0aW9uKFN0cmluZyBtZXNzYWdlLCBUaHJvd2FibGUgY2F1c2UpIHsKLSAgICAgICAgICAgICAgICBzdXBlcihtZXNzYWdlLCBjYXVzZSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogPHA+Q3JlYXRlIGEgbmV3IDxjb2RlPkRhdGF0eXBlQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjwvY29kZT4gd2l0aAotICAgICAgICAgKiB0aGUgc3BlY2lmaWVkIGNhdXNlLjwvcD4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIGNhdXNlIFRoZSBjYXVzZS4gIEEgPGNvZGU+bnVsbDwvY29kZT4gdmFsdWUgaXMgcGVybWl0dGVkLCBhbmQgaW5kaWNhdGVzIHRoYXQgdGhlIGNhdXNlIGlzIG5vbmV4aXN0ZW50IG9yIHVua25vd24uCi0gICAgICAgICAqLwotCi0gICAgICAgIHB1YmxpYyBEYXRhdHlwZUNvbmZpZ3VyYXRpb25FeGNlcHRpb24oVGhyb3dhYmxlIGNhdXNlKSB7Ci0gICAgICAgICAgICAgICAgc3VwZXIoY2F1c2UpOwotICAgICAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvamF2YXgveG1sL2RhdGF0eXBlL0RhdGF0eXBlQ29uc3RhbnRzLmphdmEgYi9zcmMvamF2YXgveG1sL2RhdGF0eXBlL0RhdGF0eXBlQ29uc3RhbnRzLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDUxOWQ4MWQuLjAwMDAwMDAKLS0tIGEvc3JjL2phdmF4L3htbC9kYXRhdHlwZS9EYXRhdHlwZUNvbnN0YW50cy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjc0ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDQsIDIwMDYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLXBhY2thZ2UgamF2YXgueG1sLmRhdGF0eXBlOwotCi1pbXBvcnQgamF2YXgueG1sLlhNTENvbnN0YW50czsKLWltcG9ydCBqYXZheC54bWwubmFtZXNwYWNlLlFOYW1lOwotCi0vKioKLSAqIDxwPlV0aWxpdHkgY2xhc3MgdG8gY29udGFpbiBiYXNpYyBEYXRhdHlwZSB2YWx1ZXMgYXMgY29uc3RhbnRzLjwvcD4KLSAqCi0gKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzpKZWZmLlN1dHRvckBTdW4uY29tIj5KZWZmIFN1dHRvcjwvYT4KLSAqIEBzaW5jZSAxLjUKLSAqLwotCi1wdWJsaWMgZmluYWwgY2xhc3MgRGF0YXR5cGVDb25zdGFudHMgewotCi0gICAgLyoqCi0gICAgICogPHA+UHJpdmF0ZSBjb25zdHJ1Y3RvciB0byBwcmV2ZW50IGluc3RhbnRpYXRpb24uPC9wPgotICAgICAqLwotICAgICAgICBwcml2YXRlIERhdGF0eXBlQ29uc3RhbnRzKCkgewotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFZhbHVlIGZvciBmaXJzdCBtb250aCBvZiB5ZWFyLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSkFOVUFSWSAgPSAxOwotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBWYWx1ZSBmb3Igc2Vjb25kIG1vbnRoIG9mIHllYXIuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGRUJSVUFSWSA9IDI7Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFZhbHVlIGZvciB0aGlyZCBtb250aCBvZiB5ZWFyLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFSQ0ggICAgPSAzOwotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBWYWx1ZSBmb3IgZm91cnRoIG1vbnRoIG9mIHllYXIuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBUFJJTCAgICA9IDQ7Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFZhbHVlIGZvciBmaWZ0aCBtb250aCBvZiB5ZWFyLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFZICAgICAgPSA1OwotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBWYWx1ZSBmb3Igc2l4dGggbW9udGggb2YgeWVhci4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEpVTkUgICAgID0gNjsKLQotICAgICAgICAvKioKLSAgICAgICAgICogVmFsdWUgZm9yIHNldmVudGggbW9udGggb2YgeWVhci4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEpVTFkgICAgID0gNzsKLQotICAgICAgICAvKioKLSAgICAgICAgICogVmFsdWUgZm9yIGVpZ2h0aCBtb250aCBvZiB5ZWFyLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQVVHVVNUICAgPSA4OwotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBWYWx1ZSBmb3IgbmludGggbW9udGggb2YgeWVhci4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNFUFRFTUJFUiA9IDk7Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFZhbHVlIGZvciB0ZW50aCBtb250aCBvZiB5ZWFyLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT0NUT0JFUiA9IDEwOwotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBWYWx1ZSBmb3IgZWxldmVuIG1vbnRoIG9mIHllYXIuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBOT1ZFTUJFUiA9IDExOwotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBWYWx1ZSBmb3IgdHdlbHZlIG1vbnRoIG9mIHllYXIuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBERUNFTUJFUiA9IDEyOwotCi0gICAgICAgIC8qKgotICAgICAgICAgKiA8cD5Db21wYXJpc29uIHJlc3VsdC48L3A+Ci0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMRVNTRVIgPSAtMTsKLQotICAgICAgICAvKioKLSAgICAgICAgICogPHA+Q29tcGFyaXNvbiByZXN1bHQuPC9wPgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVFVQUwgPSAgMDsKLQotICAgICAgICAvKioKLSAgICAgICAgICogPHA+Q29tcGFyaXNvbiByZXN1bHQuPC9wPgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgR1JFQVRFUiA9ICAxOwotCi0gICAgICAgIC8qKgotICAgICAgICAgKiA8cD5Db21wYXJpc29uIHJlc3VsdC48L3A+Ci0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJTkRFVEVSTUlOQVRFID0gIDI7Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIERlc2lnbmF0aW9uIHRoYXQgYW4gImludCIgZmllbGQgaXMgbm90IHNldC4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX1VOREVGSU5FRCA9IEludGVnZXIuTUlOX1ZBTFVFOwotCi0gICAgICAgIC8qKgotICAgICAgICAgKiA8cD5BIGNvbnN0YW50IHRoYXQgcmVwcmVzZW50cyB0aGUgeWVhcnMgZmllbGQuPC9wPgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBGaWVsZCBZRUFSUyA9IG5ldyBGaWVsZCgiWUVBUlMiLCAwKTsKLQotICAgICAgICAvKioKLSAgICAgICAgICogPHA+QSBjb25zdGFudCB0aGF0IHJlcHJlc2VudHMgdGhlIG1vbnRocyBmaWVsZC48L3A+Ci0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEZpZWxkIE1PTlRIUyA9IG5ldyBGaWVsZCgiTU9OVEhTIiwgMSk7Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIDxwPkEgY29uc3RhbnQgdGhhdCByZXByZXNlbnRzIHRoZSBkYXlzIGZpZWxkLjwvcD4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgRmllbGQgREFZUyA9IG5ldyBGaWVsZCgiREFZUyIsIDIpOwotCi0gICAgICAgIC8qKgotICAgICAgICAgKiA8cD5BIGNvbnN0YW50IHRoYXQgcmVwcmVzZW50cyB0aGUgaG91cnMgZmllbGQuPC9wPgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBGaWVsZCBIT1VSUyA9IG5ldyBGaWVsZCgiSE9VUlMiLCAzKTsKLQotICAgICAgICAvKioKLSAgICAgICAgICogPHA+QSBjb25zdGFudCB0aGF0IHJlcHJlc2VudHMgdGhlIG1pbnV0ZXMgZmllbGQuPC9wPgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBGaWVsZCBNSU5VVEVTID0gbmV3IEZpZWxkKCJNSU5VVEVTIiwgNCk7Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIDxwPkEgY29uc3RhbnQgdGhhdCByZXByZXNlbnRzIHRoZSBzZWNvbmRzIGZpZWxkLjwvcD4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgRmllbGQgU0VDT05EUyA9IG5ldyBGaWVsZCgiU0VDT05EUyIsIDUpOwotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBUeXBlLXNhZmUgZW51bSBjbGFzcyB0aGF0IHJlcHJlc2VudHMgc2l4IGZpZWxkcwotICAgICAgICAgKiBvZiB0aGUge0BsaW5rIER1cmF0aW9ufSBjbGFzcy4KLSAgICAgICAgICogQHNpbmNlIDEuNQotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZCB7Ci0KLSAgICAgICAgICAgICAgICAvKioKLSAgICAgICAgICAgICAgICAgKiA8cD48Y29kZT5TdHJpbmc8L2NvZGU+IHJlcHJlc2VudGF0aW9uIG9mIDxjb2RlPkZpZWxkPC9jb2RlPi48L3A+Ci0gICAgICAgICAgICAgICAgICovCi0gICAgICAgICAgICAgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgc3RyOwotICAgICAgICAgICAgICAgIC8qKgotICAgICAgICAgICAgICAgICAqIDxwPlVuaXF1ZSBpZCBvZiB0aGUgZmllbGQuPC9wPgotICAgICAgICAgICAgICAgICAqCi0gICAgICAgICAgICAgICAgICogPHA+VGhpcyB2YWx1ZSBhbGxvd3MgdGhlIHtAbGluayBEdXJhdGlvbn0gY2xhc3MgdG8gdXNlIHN3aXRjaAotICAgICAgICAgICAgICAgICAqIHN0YXRlbWVudHMgdG8gcHJvY2VzcyBmaWVsZHMuPC9wPgotICAgICAgICAgICAgICAgICAqLwotICAgICAgICAgICAgICAgIHByaXZhdGUgZmluYWwgaW50IGlkOwotCi0gICAgICAgICAgICAgICAgLyoqCi0gICAgICAgICAgICAgICAgICogPHA+Q29uc3RydWN0IGEgPGNvZGU+RmllbGQ8L2NvZGU+IHdpdGggc3BlY2lmaWVkIHZhbHVlcy48L3A+Ci0gICAgICAgICAgICAgICAgICogQHBhcmFtIHN0ciA8Y29kZT5TdHJpbmc8L2NvZGU+IHJlcHJlc2VudGF0aW9uIG9mIDxjb2RlPkZpZWxkPC9jb2RlPgotICAgICAgICAgICAgICAgICAqIEBwYXJhbSBpZCAgPGNvZGU+aW50PC9jb2RlPiByZXByZXNlbnRhdGlvbiBvZiA8Y29kZT5GaWVsZDwvY29kZT4KLSAgICAgICAgICAgICAgICAgKi8KLSAgICAgICAgICAgICAgICBwcml2YXRlIEZpZWxkKGZpbmFsIFN0cmluZyBzdHIsIGZpbmFsIGludCBpZCkgewotICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHIgPSBzdHI7Ci0gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlkID0gaWQ7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIC8qKgotICAgICAgICAgICAgICAgICAqIFJldHVybnMgYSBmaWVsZCBuYW1lIGluIEVuZ2xpc2guIFRoaXMgbWV0aG9kCi0gICAgICAgICAgICAgICAgICogaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBmb3IgZGVidWdnaW5nL2RpYWdub3NpcwotICAgICAgICAgICAgICAgICAqIGFuZCBub3QgZm9yIGRpc3BsYXkgdG8gZW5kLXVzZXJzLgotICAgICAgICAgICAgICAgICAqCi0gICAgICAgICAgICAgICAgICogQHJldHVybgotICAgICAgICAgICAgICAgICAqICAgICAgYSBub24tbnVsbCB2YWxpZCBTdHJpbmcgY29uc3RhbnQuCi0gICAgICAgICAgICAgICAgICovCi0gICAgICAgICAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsgcmV0dXJuIHN0cjsgfQotCi0gICAgICAgICAgICAgICAgLyoqCi0gICAgICAgICAgICAgICAgICogPHA+R2V0IGlkIG9mIHRoaXMgRmllbGQuPC9wPgotICAgICAgICAgICAgICAgICAqCi0gICAgICAgICAgICAgICAgICogQHJldHVybiBJZCBvZiBmaWVsZC4KLSAgICAgICAgICAgICAgICAgKi8KLSAgICAgICAgICAgICAgICBwdWJsaWMgaW50IGdldElkKCkgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGlkOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiA8cD5GdWxseSBxdWFsaWZpZWQgbmFtZSBmb3IgVzNDIFhNTCBTY2hlbWEgMS4wIGRhdGF0eXBlIDxjb2RlPmRhdGVUaW1lPC9jb2RlPi48L3A+Ci0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFFOYW1lIERBVEVUSU1FID0gbmV3IFFOYW1lKFhNTENvbnN0YW50cy5XM0NfWE1MX1NDSEVNQV9OU19VUkksICJkYXRlVGltZSIpOwotCi0gICAgICAgIC8qKgotICAgICAgICAgKiA8cD5GdWxseSBxdWFsaWZpZWQgbmFtZSBmb3IgVzNDIFhNTCBTY2hlbWEgMS4wIGRhdGF0eXBlIDxjb2RlPnRpbWU8L2NvZGU+LjwvcD4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgUU5hbWUgVElNRSA9IG5ldyBRTmFtZShYTUxDb25zdGFudHMuVzNDX1hNTF9TQ0hFTUFfTlNfVVJJLCAidGltZSIpOwotCi0gICAgICAgIC8qKgotICAgICAgICAgKiA8cD5GdWxseSBxdWFsaWZpZWQgbmFtZSBmb3IgVzNDIFhNTCBTY2hlbWEgMS4wIGRhdGF0eXBlIDxjb2RlPmRhdGU8L2NvZGU+LjwvcD4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgUU5hbWUgREFURSA9IG5ldyBRTmFtZShYTUxDb25zdGFudHMuVzNDX1hNTF9TQ0hFTUFfTlNfVVJJLCAiZGF0ZSIpOwotCi0gICAgICAgIC8qKgotICAgICAgICAgKiA8cD5GdWxseSBxdWFsaWZpZWQgbmFtZSBmb3IgVzNDIFhNTCBTY2hlbWEgMS4wIGRhdGF0eXBlIDxjb2RlPmdZZWFyTW9udGg8L2NvZGU+LjwvcD4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgUU5hbWUgR1lFQVJNT05USCA9IG5ldyBRTmFtZShYTUxDb25zdGFudHMuVzNDX1hNTF9TQ0hFTUFfTlNfVVJJLCAiZ1llYXJNb250aCIpOwotCi0gICAgICAgIC8qKgotICAgICAgICAgKiA8cD5GdWxseSBxdWFsaWZpZWQgbmFtZSBmb3IgVzNDIFhNTCBTY2hlbWEgMS4wIGRhdGF0eXBlIDxjb2RlPmdNb250aERheTwvY29kZT4uPC9wPgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBRTmFtZSBHTU9OVEhEQVkgPSBuZXcgUU5hbWUoWE1MQ29uc3RhbnRzLlczQ19YTUxfU0NIRU1BX05TX1VSSSwgImdNb250aERheSIpOwotCi0gICAgICAgIC8qKgotICAgICAgICAgKiA8cD5GdWxseSBxdWFsaWZpZWQgbmFtZSBmb3IgVzNDIFhNTCBTY2hlbWEgMS4wIGRhdGF0eXBlIDxjb2RlPmdZZWFyPC9jb2RlPi48L3A+Ci0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFFOYW1lIEdZRUFSID0gbmV3IFFOYW1lKFhNTENvbnN0YW50cy5XM0NfWE1MX1NDSEVNQV9OU19VUkksICJnWWVhciIpOwotCi0gICAgICAgIC8qKgotICAgICAgICAgKiA8cD5GdWxseSBxdWFsaWZpZWQgbmFtZSBmb3IgVzNDIFhNTCBTY2hlbWEgMS4wIGRhdGF0eXBlIDxjb2RlPmdNb250aDwvY29kZT4uPC9wPgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBRTmFtZSBHTU9OVEggPSBuZXcgUU5hbWUoWE1MQ29uc3RhbnRzLlczQ19YTUxfU0NIRU1BX05TX1VSSSwgImdNb250aCIpOwotCi0gICAgICAgIC8qKgotICAgICAgICAgKiA8cD5GdWxseSBxdWFsaWZpZWQgbmFtZSBmb3IgVzNDIFhNTCBTY2hlbWEgMS4wIGRhdGF0eXBlIDxjb2RlPmdEYXk8L2NvZGU+LjwvcD4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgUU5hbWUgR0RBWSA9IG5ldyBRTmFtZShYTUxDb25zdGFudHMuVzNDX1hNTF9TQ0hFTUFfTlNfVVJJLCAiZ0RheSIpOwotCi0gICAgICAgIC8qKgotICAgICAgICAgKiA8cD5GdWxseSBxdWFsaWZpZWQgbmFtZSBmb3IgVzNDIFhNTCBTY2hlbWEgZGF0YXR5cGUgPGNvZGU+ZHVyYXRpb248L2NvZGU+LjwvcD4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgUU5hbWUgRFVSQVRJT04gPSBuZXcgUU5hbWUoWE1MQ29uc3RhbnRzLlczQ19YTUxfU0NIRU1BX05TX1VSSSwgImR1cmF0aW9uIik7Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIDxwPkZ1bGx5IHF1YWxpZmllZCBuYW1lIGZvciBYUXVlcnkgMS4wIGFuZCBYUGF0aCAyLjAgZGF0YXR5cGUgPGNvZGU+ZGF5VGltZUR1cmF0aW9uPC9jb2RlPi48L3A+Ci0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFFOYW1lIERVUkFUSU9OX0RBWVRJTUUgPSBuZXcgUU5hbWUoWE1MQ29uc3RhbnRzLlczQ19YUEFUSF9EQVRBVFlQRV9OU19VUkksICJkYXlUaW1lRHVyYXRpb24iKTsKLQotICAgICAgICAvKioKLSAgICAgICAgICogPHA+RnVsbHkgcXVhbGlmaWVkIG5hbWUgZm9yIFhRdWVyeSAxLjAgYW5kIFhQYXRoIDIuMCBkYXRhdHlwZSA8Y29kZT55ZWFyTW9udGhEdXJhdGlvbjwvY29kZT4uPC9wPgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBRTmFtZSBEVVJBVElPTl9ZRUFSTU9OVEggPSBuZXcgUU5hbWUoWE1MQ29uc3RhbnRzLlczQ19YUEFUSF9EQVRBVFlQRV9OU19VUkksICJ5ZWFyTW9udGhEdXJhdGlvbiIpOwotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBXM0MgWE1MIFNjaGVtYSBtYXggdGltZXpvbmUgb2Zmc2V0IGlzIC0xNDowMC4gWm9uZSBvZmZzZXQgaXMgaW4gbWludXRlcy4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BWF9USU1FWk9ORV9PRkZTRVQgPSAtMTQgKiA2MDsKLQotICAgICAgICAvKioKLSAgICAgICAgICogVzNDIFhNTCBTY2hlbWEgbWluIHRpbWV6b25lIG9mZnNldCBpcyArMTQ6MDAuIFpvbmUgb2Zmc2V0IGlzIGluIG1pbnV0ZXMuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNSU5fVElNRVpPTkVfT0ZGU0VUID0gMTQgKiA2MDsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmF4L3htbC9kYXRhdHlwZS9EYXRhdHlwZUZhY3RvcnkuamF2YSBiL3NyYy9qYXZheC94bWwvZGF0YXR5cGUvRGF0YXR5cGVGYWN0b3J5LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDU2Yzc5NmIuLjAwMDAwMDAKLS0tIGEvc3JjL2phdmF4L3htbC9kYXRhdHlwZS9EYXRhdHlwZUZhY3RvcnkuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEwNzQgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwNCwgMjAxMywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotcGFja2FnZSBqYXZheC54bWwuZGF0YXR5cGU7Ci0KLWltcG9ydCBqYXZhLm1hdGguQmlnRGVjaW1hbDsKLWltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKLWltcG9ydCBqYXZhLnV0aWwuR3JlZ29yaWFuQ2FsZW5kYXI7Ci1pbXBvcnQgamF2YS51dGlsLnJlZ2V4Lk1hdGNoZXI7Ci1pbXBvcnQgamF2YS51dGlsLnJlZ2V4LlBhdHRlcm47Ci0KLS8qKgotICogPHA+RmFjdG9yeSB0aGF0IGNyZWF0ZXMgbmV3IDxjb2RlPmphdmF4LnhtbC5kYXRhdHlwZTwvY29kZT4gPGNvZGU+T2JqZWN0PC9jb2RlPnMgdGhhdCBtYXAgWE1MIHRvL2Zyb20gSmF2YSA8Y29kZT5PYmplY3Q8L2NvZGU+cy48L3A+Ci0gKgotICogPHA+QSBuZXcgaW5zdGFuY2Ugb2YgdGhlIDxjb2RlPkRhdGF0eXBlRmFjdG9yeTwvY29kZT4gaXMgY3JlYXRlZCB0aHJvdWdoIHRoZSB7QGxpbmsgI25ld0luc3RhbmNlKCl9IG1ldGhvZAotICogdGhhdCB1c2VzIHRoZSBmb2xsb3dpbmcgaW1wbGVtZW50YXRpb24gcmVzb2x1dGlvbiBtZWNoYW5pc21zIHRvIGRldGVybWluZSBhbiBpbXBsZW1lbnRhdGlvbjo8L3A+Ci0gKiA8b2w+Ci0gKiAgICA8bGk+Ci0gKiAgICAgIElmIHRoZSBzeXN0ZW0gcHJvcGVydHkgc3BlY2lmaWVkIGJ5IHtAbGluayAjREFUQVRZUEVGQUNUT1JZX1BST1BFUlRZfSwgIjxjb2RlPmphdmF4LnhtbC5kYXRhdHlwZS5EYXRhdHlwZUZhY3Rvcnk8L2NvZGU+IiwKLSAqICAgICAgZXhpc3RzLCBhIGNsYXNzIHdpdGggdGhlIG5hbWUgb2YgdGhlIHByb3BlcnR5IHZhbHVlIGlzIGluc3RhbnRpYXRlZC4KLSAqICAgICAgQW55IEV4Y2VwdGlvbiB0aHJvd24gZHVyaW5nIHRoZSBpbnN0YW50aWF0aW9uIHByb2Nlc3MgaXMgd3JhcHBlZCBhcyBhIHtAbGluayBEYXRhdHlwZUNvbmZpZ3VyYXRpb25FeGNlcHRpb259LgotICogICAgPC9saT4KLSAqICAgIDxsaT4KLSAqICAgICAgSWYgdGhlIGZpbGUgJHtKQVZBX0hPTUV9L2xpYi9qYXhwLnByb3BlcnRpZXMgZXhpc3RzLCBpdCBpcyBsb2FkZWQgaW4gYSB7QGxpbmsgamF2YS51dGlsLlByb3BlcnRpZXN9IDxjb2RlPk9iamVjdDwvY29kZT4uCi0gKiAgICAgIFRoZSA8Y29kZT5Qcm9wZXJ0aWVzPC9jb2RlPiA8Y29kZT5PYmplY3QgPC9jb2RlPiBpcyB0aGVuIHF1ZXJpZWQgZm9yIHRoZSBwcm9wZXJ0eSBhcyBkb2N1bWVudGVkIGluIHRoZSBwcmlvciBzdGVwCi0gKiAgICAgIGFuZCBwcm9jZXNzZWQgYXMgZG9jdW1lbnRlZCBpbiB0aGUgcHJpb3Igc3RlcC4KLSAqICAgIDwvbGk+Ci0gKiAgICA8bGk+Ci0gKiAgICAgVXNlcyB0aGUgc2VydmljZS1wcm92aWRlciBsb2FkaW5nIGZhY2lsaXRpZXMsIGRlZmluZWQgYnkgdGhlIHtAbGluayBqYXZhLnV0aWwuU2VydmljZUxvYWRlcn0gY2xhc3MsIHRvIGF0dGVtcHQKLSAqICAgICB0byBsb2NhdGUgYW5kIGxvYWQgYW4gaW1wbGVtZW50YXRpb24gb2YgdGhlIHNlcnZpY2UgdXNpbmcgdGhlIHtAbGlua3BsYWluCi0gKiAgICAgamF2YS51dGlsLlNlcnZpY2VMb2FkZXIjbG9hZChqYXZhLmxhbmcuQ2xhc3MpIGRlZmF1bHQgbG9hZGluZyBtZWNoYW5pc219OgotICogICAgIHRoZSBzZXJ2aWNlLXByb3ZpZGVyIGxvYWRpbmcgZmFjaWxpdHkgd2lsbCB1c2UgdGhlIHtAbGlua3BsYWluCi0gKiAgICAgamF2YS5sYW5nLlRocmVhZCNnZXRDb250ZXh0Q2xhc3NMb2FkZXIoKSBjdXJyZW50IHRocmVhZCdzIGNvbnRleHQgY2xhc3MgbG9hZGVyfQotICogICAgIHRvIGF0dGVtcHQgdG8gbG9hZCB0aGUgc2VydmljZS4gSWYgdGhlIGNvbnRleHQgY2xhc3MKLSAqICAgICBsb2FkZXIgaXMgbnVsbCwgdGhlIHtAbGlua3BsYWluCi0gKiAgICAgQ2xhc3NMb2FkZXIjZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKSBzeXN0ZW0gY2xhc3MgbG9hZGVyfSB3aWxsIGJlIHVzZWQuCi0gKiAgICAgPGJyPgotICogICAgIEluIGNhc2Ugb2Yge0BsaW5rIGphdmEudXRpbC5TZXJ2aWNlQ29uZmlndXJhdGlvbkVycm9yIHNlcnZpY2UKLSAqICAgICBjb25maWd1cmF0aW9uIGVycm9yfSBhIHtAbGluayBqYXZheC54bWwuZGF0YXR5cGUuRGF0YXR5cGVDb25maWd1cmF0aW9uRXhjZXB0aW9ufQotICogICAgIHdpbGwgYmUgdGhyb3duLgotICogICAgPC9saT4KLSAqICAgIDxsaT4KLSAqICAgICAgVGhlIGZpbmFsIG1lY2hhbmlzbSBpcyB0byBhdHRlbXB0IHRvIGluc3RhbnRpYXRlIHRoZSA8Y29kZT5DbGFzczwvY29kZT4gc3BlY2lmaWVkIGJ5Ci0gKiAgICAgIHtAbGluayAjREFUQVRZUEVGQUNUT1JZX0lNUExFTUVOVEFUSU9OX0NMQVNTfS4KLSAqICAgICAgQW55IEV4Y2VwdGlvbiB0aHJvd24gZHVyaW5nIHRoZSBpbnN0YW50aWF0aW9uIHByb2Nlc3MgaXMgd3JhcHBlZCBhcyBhIHtAbGluayBEYXRhdHlwZUNvbmZpZ3VyYXRpb25FeGNlcHRpb259LgotICogICAgPC9saT4KLSAqIDwvb2w+Ci0gKgotICogQGF1dGhvciA8YSBocmVmPSJtYWlsdG86Sm9zZXBoLkZpYWxsaUBTdW4uQ09NIj5Kb3NlcGggRmlhbGxpPC9hPgotICogQGF1dGhvciA8YSBocmVmPSJtYWlsdG86SmVmZi5TdXR0b3JAU3VuLmNvbSI+SmVmZiBTdXR0b3I8L2E+Ci0gKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzpOZWVyYWouQmFqYWpAc3VuLmNvbSI+TmVlcmFqIEJhamFqPC9hPgotICoKLSAqIEB2ZXJzaW9uICRSZXZpc2lvbjogMS4xMyAkLCAkRGF0ZTogMjAxMC8wMy8xMSAyMzoxMDo1MyAkCi0gKiBAc2luY2UgMS41Ci0gKi8KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBEYXRhdHlwZUZhY3RvcnkgewotCi0gICAgLyoqCi0gICAgICogPHA+RGVmYXVsdCBwcm9wZXJ0eSBuYW1lIGFzIGRlZmluZWQgaW4gSlNSIDIwNjogSmF2YShUTSkgQVBJIGZvciBYTUwgUHJvY2Vzc2luZyAoSkFYUCkgMS4zLjwvcD4KLSAgICAgKgotICAgICAqIDxwPkRlZmF1bHQgdmFsdWUgaXMgPGNvZGU+amF2YXgueG1sLmRhdGF0eXBlLkRhdGF0eXBlRmFjdG9yeTwvY29kZT4uPC9wPgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIERBVEFUWVBFRkFDVE9SWV9QUk9QRVJUWSA9Ci0gICAgICAgICAgICAvLyBXZSB1c2UgYSBTdHJpbmcgY29uc3RhbnQgaGVyZSwgcmF0aGVyIHRoYW4gY2FsbGluZwotICAgICAgICAgICAgLy8gRGF0YXR5cGVGYWN0b3J5LmNsYXNzLmdldE5hbWUoKSAtIGluIG9yZGVyIHRvIG1ha2UgamF2YWRvYwotICAgICAgICAgICAgLy8gZ2VuZXJhdGUgYSBTZWUgQWxzbzogQ29uc3RhbnQgRmllbGQgVmFsdWUgbGluay4KLSAgICAgICAgICAgICJqYXZheC54bWwuZGF0YXR5cGUuRGF0YXR5cGVGYWN0b3J5IjsKLQotICAgIC8qKgotICAgICAqIDxwPkRlZmF1bHQgaW1wbGVtZW50YXRpb24gY2xhc3MgbmFtZSBhcyBkZWZpbmVkIGluCi0gICAgICogPGVtPkpTUiAyMDY6IEphdmEoVE0pIEFQSSBmb3IgWE1MIFByb2Nlc3NpbmcgKEpBWFApIDEuMzwvZW0+LjwvcD4KLSAgICAgKgotICAgICAqIDxwPkltcGxlbWVudGVycyBzaG91bGQgc3BlY2lmeSB0aGUgbmFtZSBvZiBhbiBhcHByb3ByaWF0ZSBjbGFzcwotICAgICAqIHRvIGJlIGluc3RhbnRpYXRlZCBpZiBubyBvdGhlciBpbXBsZW1lbnRhdGlvbiByZXNvbHV0aW9uIG1lY2hhbmlzbQotICAgICAqIHN1Y2NlZWRzLjwvcD4KLSAgICAgKgotICAgICAqIDxwPlVzZXJzIHNob3VsZCBub3QgcmVmZXIgdG8gdGhpcyBmaWVsZDsgaXQgaXMgaW50ZW5kZWQgb25seSB0bwotICAgICAqIGRvY3VtZW50IGEgZmFjdG9yeSBpbXBsZW1lbnRhdGlvbiBkZXRhaWwuCi0gICAgICogPC9wPgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIERBVEFUWVBFRkFDVE9SWV9JTVBMRU1FTlRBVElPTl9DTEFTUyA9Ci0gICAgICAgIC8vIFdlIHVzZSBuZXcgU3RyaW5nKCkgaGVyZSB0byBwcmV2ZW50IGphdmFkb2MgZnJvbSBnZW5lcmF0aW5nCi0gICAgICAgIC8vIGEgU2VlIEFsc286IENvbnN0YW50IEZpZWxkIFZhbHVlIGxpbmsuCi0gICAgICAgIG5ldyBTdHJpbmcoImNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuamF4cC5kYXRhdHlwZS5EYXRhdHlwZUZhY3RvcnlJbXBsIik7Ci0KLSAgICAvKioKLSAgICAgKiBodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aC1kYXRhbW9kZWwvI3hkdHNjaGVtYSBkZWZpbmVzIHR3byByZWdleHBzCi0gICAgICogdG8gY29uc3RyYWluIHRoZSB2YWx1ZSBzcGFjZSBvZiBkYXlUaW1lRHVyYXRpb24gKFteWU1dKltEVF0uKikKLSAgICAgKiBhbmQgeWVhck1vbnRoRHVyYXRpb24gKFteRFRdKikuIE5vdGUgdGhhdCB0aGVzZSBleHByZXNzaW9ucyByZWx5IG9uCi0gICAgICogdGhlIGZhY3QgdGhhdCB0aGUgdmFsdWUgbXVzdCBiZSBhbiB4czpEdXJhdGlvbiwgdGhleSBzaW1wbHkgZXhjbHVkZQotICAgICAqIHNvbWUgRHVyYXRpb25zLgotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFBhdHRlcm4gWERUU0NIRU1BX1lNRCA9Ci0gICAgICAgIFBhdHRlcm4uY29tcGlsZSgiW15EVF0qIik7Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBQYXR0ZXJuIFhEVFNDSEVNQV9EVEQgPQotICAgICAgICBQYXR0ZXJuLmNvbXBpbGUoIlteWU1dKltEVF0uKiIpOwotCi0gICAgLyoqCi0gICAgICogPHA+UHJvdGVjdGVkIGNvbnN0cnVjdG9yIHRvIHByZXZlbnQgaW5zdGFuaWF0aW9uIG91dHNpZGUgb2YgcGFja2FnZS48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5Vc2Uge0BsaW5rICNuZXdJbnN0YW5jZSgpfSB0byBjcmVhdGUgYSA8Y29kZT5EYXRhdHlwZUZhY3Rvcnk8L2NvZGU+LjwvcD4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgRGF0YXR5cGVGYWN0b3J5KCkgewotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPk9idGFpbiBhIG5ldyBpbnN0YW5jZSBvZiBhIDxjb2RlPkRhdGF0eXBlRmFjdG9yeTwvY29kZT4uPC9wPgotICAgICAqCi0gICAgICogPHA+VGhlIGltcGxlbWVudGF0aW9uIHJlc29sdXRpb24gbWVjaGFuaXNtcyBhcmUgPGEgaHJlZj0iI0RhdGF0eXBlRmFjdG9yeS5uZXdJbnN0YW5jZSI+ZGVmaW5lZDwvYT4gaW4gdGhpcwotICAgICAqIDxjb2RlPkNsYXNzPC9jb2RlPidzIGRvY3VtZW50YXRpb24uPC9wPgotICAgICAqCi0gICAgICogQHJldHVybiBOZXcgaW5zdGFuY2Ugb2YgYSA8Y29kZT5EYXRhdHlwZUZhY3Rvcnk8L2NvZGU+Ci0gICAgICoKLSAgICAgKiBAdGhyb3dzIERhdGF0eXBlQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBJZiB0aGUgaW1wbGVtZW50YXRpb24gaXMgbm90Ci0gICAgICogICBhdmFpbGFibGUgb3IgY2Fubm90IGJlIGluc3RhbnRpYXRlZC4KLSAgICAgKgotICAgICAqIEBzZWUgI25ld0luc3RhbmNlKFN0cmluZyBmYWN0b3J5Q2xhc3NOYW1lLCBDbGFzc0xvYWRlciBjbGFzc0xvYWRlcikKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIERhdGF0eXBlRmFjdG9yeSBuZXdJbnN0YW5jZSgpCi0gICAgICAgICAgICB0aHJvd3MgRGF0YXR5cGVDb25maWd1cmF0aW9uRXhjZXB0aW9uIHsKLQotICAgICAgICAgICAgcmV0dXJuIEZhY3RvcnlGaW5kZXIuZmluZCgKLSAgICAgICAgICAgICAgICAgICAgLyogVGhlIGRlZmF1bHQgcHJvcGVydHkgbmFtZSBhY2NvcmRpbmcgdG8gdGhlIEpBWFAgc3BlYyAqLwotICAgICAgICAgICAgICAgICAgICBEYXRhdHlwZUZhY3RvcnkuY2xhc3MsCi0gICAgICAgICAgICAgICAgICAgIC8qIFRoZSBmYWxsYmFjayBpbXBsZW1lbnRhdGlvbiBjbGFzcyBuYW1lICovCi0gICAgICAgICAgICAgICAgICAgIERBVEFUWVBFRkFDVE9SWV9JTVBMRU1FTlRBVElPTl9DTEFTUyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+T2J0YWluIGEgbmV3IGluc3RhbmNlIG9mIGEgPGNvZGU+RGF0YXR5cGVGYWN0b3J5PC9jb2RlPiBmcm9tIGNsYXNzIG5hbWUuCi0gICAgICogVGhpcyBmdW5jdGlvbiBpcyB1c2VmdWwgd2hlbiB0aGVyZSBhcmUgbXVsdGlwbGUgcHJvdmlkZXJzIGluIHRoZSBjbGFzc3BhdGguCi0gICAgICogSXQgZ2l2ZXMgbW9yZSBjb250cm9sIHRvIHRoZSBhcHBsaWNhdGlvbiBhcyBpdCBjYW4gc3BlY2lmeSB3aGljaCBwcm92aWRlcgotICAgICAqIHNob3VsZCBiZSBsb2FkZWQuPC9wPgotICAgICAqCi0gICAgICogPHA+T25jZSBhbiBhcHBsaWNhdGlvbiBoYXMgb2J0YWluZWQgYSByZWZlcmVuY2UgdG8gYSA8Y29kZT5EYXRhdHlwZUZhY3Rvcnk8L2NvZGU+Ci0gICAgICogaXQgY2FuIHVzZSB0aGUgZmFjdG9yeSB0byBjb25maWd1cmUgYW5kIG9idGFpbiBkYXRhdHlwZSBpbnN0YW5jZXMuPC9QPgotICAgICAqCi0gICAgICoKLSAgICAgKiA8aDI+VGlwIGZvciBUcm91YmxlLXNob290aW5nPC9oMj4KLSAgICAgKiA8cD5TZXR0aW5nIHRoZSA8Y29kZT5qYXhwLmRlYnVnPC9jb2RlPiBzeXN0ZW0gcHJvcGVydHkgd2lsbCBjYXVzZQotICAgICAqIHRoaXMgbWV0aG9kIHRvIHByaW50IGEgbG90IG9mIGRlYnVnIG1lc3NhZ2VzCi0gICAgICogdG8gPGNvZGU+U3lzdGVtLmVycjwvY29kZT4gYWJvdXQgd2hhdCBpdCBpcyBkb2luZyBhbmQgd2hlcmUgaXQgaXMgbG9va2luZyBhdC48L3A+Ci0gICAgICoKLSAgICAgKiA8cD4gSWYgeW91IGhhdmUgcHJvYmxlbXMgdHJ5OjwvcD4KLSAgICAgKiA8cHJlPgotICAgICAqIGphdmEgLURqYXhwLmRlYnVnPTEgWW91clByb2dyYW0gLi4uLgotICAgICAqIDwvcHJlPgotICAgICAqCi0gICAgICogQHBhcmFtIGZhY3RvcnlDbGFzc05hbWUgZnVsbHkgcXVhbGlmaWVkIGZhY3RvcnkgY2xhc3MgbmFtZSB0aGF0IHByb3ZpZGVzIGltcGxlbWVudGF0aW9uIG9mIDxjb2RlPmphdmF4LnhtbC5kYXRhdHlwZS5EYXRhdHlwZUZhY3Rvcnk8L2NvZGU+LgotICAgICAqCi0gICAgICogQHBhcmFtIGNsYXNzTG9hZGVyIDxjb2RlPkNsYXNzTG9hZGVyPC9jb2RlPiB1c2VkIHRvIGxvYWQgdGhlIGZhY3RvcnkgY2xhc3MuIElmIDxjb2RlPm51bGw8L2NvZGU+Ci0gICAgICogICAgICAgICAgICAgICAgICAgICBjdXJyZW50IDxjb2RlPlRocmVhZDwvY29kZT4ncyBjb250ZXh0IGNsYXNzTG9hZGVyIGlzIHVzZWQgdG8gbG9hZCB0aGUgZmFjdG9yeSBjbGFzcy4KLSAgICAgKgotICAgICAqIEByZXR1cm4gTmV3IGluc3RhbmNlIG9mIGEgPGNvZGU+RGF0YXR5cGVGYWN0b3J5PC9jb2RlPgotICAgICAqCi0gICAgICogQHRocm93cyBEYXRhdHlwZUNvbmZpZ3VyYXRpb25FeGNlcHRpb24gaWYgPGNvZGU+ZmFjdG9yeUNsYXNzTmFtZTwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4sIG9yCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSBmYWN0b3J5IGNsYXNzIGNhbm5vdCBiZSBsb2FkZWQsIGluc3RhbnRpYXRlZC4KLSAgICAgKgotICAgICAqIEBzZWUgI25ld0luc3RhbmNlKCkKLSAgICAgKgotICAgICAqIEBzaW5jZSAxLjYKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIERhdGF0eXBlRmFjdG9yeSBuZXdJbnN0YW5jZShTdHJpbmcgZmFjdG9yeUNsYXNzTmFtZSwgQ2xhc3NMb2FkZXIgY2xhc3NMb2FkZXIpCi0gICAgICAgIHRocm93cyBEYXRhdHlwZUNvbmZpZ3VyYXRpb25FeGNlcHRpb24gewotICAgICAgICByZXR1cm4gRmFjdG9yeUZpbmRlci5uZXdJbnN0YW5jZShEYXRhdHlwZUZhY3RvcnkuY2xhc3MsCi0gICAgICAgICAgICAgICAgICAgIGZhY3RvcnlDbGFzc05hbWUsIGNsYXNzTG9hZGVyLCBmYWxzZSk7Ci0gICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPk9idGFpbiBhIG5ldyBpbnN0YW5jZSBvZiBhIDxjb2RlPkR1cmF0aW9uPC9jb2RlPgotICAgICAqIHNwZWNpZnlpbmcgdGhlIDxjb2RlPkR1cmF0aW9uPC9jb2RlPiBhcyBpdHMgc3RyaW5nIHJlcHJlc2VudGF0aW9uLCAiUG5Zbk1uRFRuSG5NblMiLAotICAgICAqIGFzIGRlZmluZWQgaW4gWE1MIFNjaGVtYSAxLjAgc2VjdGlvbiAzLjIuNi4xLjwvcD4KLSAgICAgKgotICAgICAqIDxwPlhNTCBTY2hlbWEgUGFydCAyOiBEYXRhdHlwZXMsIDMuMi42IGR1cmF0aW9uLCBkZWZpbmVzIDxjb2RlPmR1cmF0aW9uPC9jb2RlPiBhczo8L3A+Ci0gICAgICogPGJsb2NrcXVvdGU+Ci0gICAgICogZHVyYXRpb24gcmVwcmVzZW50cyBhIGR1cmF0aW9uIG9mIHRpbWUuCi0gICAgICogVGhlIHZhbHVlIHNwYWNlIG9mIGR1cmF0aW9uIGlzIGEgc2l4LWRpbWVuc2lvbmFsIHNwYWNlIHdoZXJlIHRoZSBjb29yZGluYXRlcyBkZXNpZ25hdGUgdGhlCi0gICAgICogR3JlZ29yaWFuIHllYXIsIG1vbnRoLCBkYXksIGhvdXIsIG1pbnV0ZSwgYW5kIHNlY29uZCBjb21wb25lbnRzIGRlZmluZWQgaW4gU2VjdGlvbiA1LjUuMy4yIG9mIFtJU08gODYwMV0sIHJlc3BlY3RpdmVseS4KLSAgICAgKiBUaGVzZSBjb21wb25lbnRzIGFyZSBvcmRlcmVkIGluIHRoZWlyIHNpZ25pZmljYW5jZSBieSB0aGVpciBvcmRlciBvZiBhcHBlYXJhbmNlIGkuZS4gYXMKLSAgICAgKiB5ZWFyLCBtb250aCwgZGF5LCBob3VyLCBtaW51dGUsIGFuZCBzZWNvbmQuCi0gICAgICogPC9ibG9ja3F1b3RlPgotICAgICAqIDxwPkFsbCBzaXggdmFsdWVzIGFyZSBzZXQgYW5kIGF2YWlsYWJsZSBmcm9tIHRoZSBjcmVhdGVkIHtAbGluayBEdXJhdGlvbn08L3A+Ci0gICAgICoKLSAgICAgKiA8cD5UaGUgWE1MIFNjaGVtYSBzcGVjaWZpY2F0aW9uIHN0YXRlcyB0aGF0IHZhbHVlcyBjYW4gYmUgb2YgYW4gYXJiaXRyYXJ5IHNpemUuCi0gICAgICogSW1wbGVtZW50YXRpb25zIG1heSBjaG9zZSBub3QgdG8gb3IgYmUgaW5jYXBhYmxlIG9mIHN1cHBvcnRpbmcgYXJiaXRyYXJpbHkgbGFyZ2UgYW5kL29yIHNtYWxsIHZhbHVlcy4KLSAgICAgKiBBbiB7QGxpbmsgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb259IHdpbGwgYmUgdGhyb3duIHdpdGggYSBtZXNzYWdlIGluZGljYXRpbmcgaW1wbGVtZW50YXRpb24gbGltaXRzCi0gICAgICogaWYgaW1wbGVtZW50YXRpb24gY2FwYWNpdGllcyBhcmUgZXhjZWVkZWQuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGxleGljYWxSZXByZXNlbnRhdGlvbiA8Y29kZT5TdHJpbmc8L2NvZGU+IHJlcHJlc2VudGF0aW9uIG9mIGEgPGNvZGU+RHVyYXRpb248L2NvZGU+LgotICAgICAqCi0gICAgICogQHJldHVybiBOZXcgPGNvZGU+RHVyYXRpb248L2NvZGU+IGNyZWF0ZWQgZnJvbSBwYXJzaW5nIHRoZSA8Y29kZT5sZXhpY2FsUmVwcmVzZW50YXRpb248L2NvZGU+LgotICAgICAqCi0gICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gSWYgPGNvZGU+bGV4aWNhbFJlcHJlc2VudGF0aW9uPC9jb2RlPiBpcyBub3QgYSB2YWxpZCByZXByZXNlbnRhdGlvbiBvZiBhIDxjb2RlPkR1cmF0aW9uPC9jb2RlPi4KLSAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIElmIGltcGxlbWVudGF0aW9uIGNhbm5vdCBzdXBwb3J0IHJlcXVlc3RlZCB2YWx1ZXMuCi0gICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiA8Y29kZT5sZXhpY2FsUmVwcmVzZW50YXRpb248L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCBEdXJhdGlvbiBuZXdEdXJhdGlvbihmaW5hbCBTdHJpbmcgbGV4aWNhbFJlcHJlc2VudGF0aW9uKTsKLQotICAgIC8qKgotICAgICAqIDxwPk9idGFpbiBhIG5ldyBpbnN0YW5jZSBvZiBhIDxjb2RlPkR1cmF0aW9uPC9jb2RlPgotICAgICAqIHNwZWNpZnlpbmcgdGhlIDxjb2RlPkR1cmF0aW9uPC9jb2RlPiBhcyBtaWxsaXNlY29uZHMuPC9wPgotICAgICAqCi0gICAgICogPHA+WE1MIFNjaGVtYSBQYXJ0IDI6IERhdGF0eXBlcywgMy4yLjYgZHVyYXRpb24sIGRlZmluZXMgPGNvZGU+ZHVyYXRpb248L2NvZGU+IGFzOjwvcD4KLSAgICAgKiA8YmxvY2txdW90ZT4KLSAgICAgKiBkdXJhdGlvbiByZXByZXNlbnRzIGEgZHVyYXRpb24gb2YgdGltZS4KLSAgICAgKiBUaGUgdmFsdWUgc3BhY2Ugb2YgZHVyYXRpb24gaXMgYSBzaXgtZGltZW5zaW9uYWwgc3BhY2Ugd2hlcmUgdGhlIGNvb3JkaW5hdGVzIGRlc2lnbmF0ZSB0aGUKLSAgICAgKiBHcmVnb3JpYW4geWVhciwgbW9udGgsIGRheSwgaG91ciwgbWludXRlLCBhbmQgc2Vjb25kIGNvbXBvbmVudHMgZGVmaW5lZCBpbiBTZWN0aW9uIDUuNS4zLjIgb2YgW0lTTyA4NjAxXSwgcmVzcGVjdGl2ZWx5LgotICAgICAqIFRoZXNlIGNvbXBvbmVudHMgYXJlIG9yZGVyZWQgaW4gdGhlaXIgc2lnbmlmaWNhbmNlIGJ5IHRoZWlyIG9yZGVyIG9mIGFwcGVhcmFuY2UgaS5lLiBhcwotICAgICAqIHllYXIsIG1vbnRoLCBkYXksIGhvdXIsIG1pbnV0ZSwgYW5kIHNlY29uZC4KLSAgICAgKiA8L2Jsb2NrcXVvdGU+Ci0gICAgICogPHA+QWxsIHNpeCB2YWx1ZXMgYXJlIHNldCBieSBjb21wdXRpbmcgdGhlaXIgdmFsdWVzIGZyb20gdGhlIHNwZWNpZmllZCBtaWxsaXNlY29uZHMKLSAgICAgKiBhbmQgYXJlIGF2YWlsYWJsZSB1c2luZyB0aGUgPGNvZGU+Z2V0PC9jb2RlPiBtZXRob2RzIG9mICB0aGUgY3JlYXRlZCB7QGxpbmsgRHVyYXRpb259LgotICAgICAqIFRoZSB2YWx1ZXMgY29uZm9ybSB0byBhbmQgYXJlIGRlZmluZWQgYnk6PC9wPgotICAgICAqIDx1bD4KLSAgICAgKiAgIDxsaT5JU08gODYwMToyMDAwKEUpIFNlY3Rpb24gNS41LjMuMiBBbHRlcm5hdGl2ZSBmb3JtYXQ8L2xpPgotICAgICAqICAgPGxpPjxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3htbHNjaGVtYS0yLyNpc29mb3JtYXRzIj4KLSAgICAgKiAgICAgVzNDIFhNTCBTY2hlbWEgMS4wIFBhcnQgMiwgQXBwZW5kaXggRCwgSVNPIDg2MDEgRGF0ZSBhbmQgVGltZSBGb3JtYXRzPC9hPgotICAgICAqICAgPC9saT4KLSAgICAgKiAgIDxsaT57QGxpbmsgWE1MR3JlZ29yaWFuQ2FsZW5kYXJ9ICBEYXRlL1RpbWUgRGF0YXR5cGUgRmllbGQgTWFwcGluZyBCZXR3ZWVuIFhNTCBTY2hlbWEgMS4wIGFuZCBKYXZhIFJlcHJlc2VudGF0aW9uPC9saT4KLSAgICAgKiA8L3VsPgotICAgICAqCi0gICAgICogPHA+VGhlIGRlZmF1bHQgc3RhcnQgaW5zdGFuY2UgaXMgZGVmaW5lZCBieSB7QGxpbmsgR3JlZ29yaWFuQ2FsZW5kYXJ9J3MgdXNlIG9mIHRoZSBzdGFydCBvZiB0aGUgZXBvY2g6IGkuZS4sCi0gICAgICoge0BsaW5rIGphdmEudXRpbC5DYWxlbmRhciNZRUFSfSA9IDE5NzAsCi0gICAgICoge0BsaW5rIGphdmEudXRpbC5DYWxlbmRhciNNT05USH0gPSB7QGxpbmsgamF2YS51dGlsLkNhbGVuZGFyI0pBTlVBUll9LAotICAgICAqIHtAbGluayBqYXZhLnV0aWwuQ2FsZW5kYXIjREFURX0gPSAxLCBldGMuCi0gICAgICogVGhpcyBpcyBpbXBvcnRhbnQgYXMgdGhlcmUgYXJlIHZhcmlhdGlvbnMgaW4gdGhlIEdyZWdvcmlhbiBDYWxlbmRhciwKLSAgICAgKiBlLmcuIGxlYXAgeWVhcnMgaGF2ZSBkaWZmZXJlbnQgZGF5cyBpbiB0aGUgbW9udGggPSB7QGxpbmsgamF2YS51dGlsLkNhbGVuZGFyI0ZFQlJVQVJZfQotICAgICAqIHNvIHRoZSByZXN1bHQgb2Yge0BsaW5rIER1cmF0aW9uI2dldE1vbnRocygpfSBhbmQge0BsaW5rIER1cmF0aW9uI2dldERheXMoKX0gY2FuIGJlIGluZmx1ZW5jZWQuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGR1cmF0aW9uSW5NaWxsaVNlY29uZHMgRHVyYXRpb24gaW4gbWlsbGlzZWNvbmRzIHRvIGNyZWF0ZS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gTmV3IDxjb2RlPkR1cmF0aW9uPC9jb2RlPiByZXByZXNlbnRpbmcgPGNvZGU+ZHVyYXRpb25Jbk1pbGxpU2Vjb25kczwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IER1cmF0aW9uIG5ld0R1cmF0aW9uKGZpbmFsIGxvbmcgZHVyYXRpb25Jbk1pbGxpU2Vjb25kcyk7Ci0KLSAgICAvKioKLSAgICAgKiA8cD5PYnRhaW4gYSBuZXcgaW5zdGFuY2Ugb2YgYSA8Y29kZT5EdXJhdGlvbjwvY29kZT4KLSAgICAgKiBzcGVjaWZ5aW5nIHRoZSA8Y29kZT5EdXJhdGlvbjwvY29kZT4gYXMgaXNQb3NpdGl2ZSwgeWVhcnMsIG1vbnRocywgZGF5cywgaG91cnMsIG1pbnV0ZXMsIHNlY29uZHMuPC9wPgotICAgICAqCi0gICAgICogPHA+VGhlIFhNTCBTY2hlbWEgc3BlY2lmaWNhdGlvbiBzdGF0ZXMgdGhhdCB2YWx1ZXMgY2FuIGJlIG9mIGFuIGFyYml0cmFyeSBzaXplLgotICAgICAqIEltcGxlbWVudGF0aW9ucyBtYXkgY2hvc2Ugbm90IHRvIG9yIGJlIGluY2FwYWJsZSBvZiBzdXBwb3J0aW5nIGFyYml0cmFyaWx5IGxhcmdlIGFuZC9vciBzbWFsbCB2YWx1ZXMuCi0gICAgICogQW4ge0BsaW5rIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9ufSB3aWxsIGJlIHRocm93biB3aXRoIGEgbWVzc2FnZSBpbmRpY2F0aW5nIGltcGxlbWVudGF0aW9uIGxpbWl0cwotICAgICAqIGlmIGltcGxlbWVudGF0aW9uIGNhcGFjaXRpZXMgYXJlIGV4Y2VlZGVkLjwvcD4KLSAgICAgKgotICAgICAqIDxwPkEgPGNvZGU+bnVsbDwvY29kZT4gdmFsdWUgaW5kaWNhdGVzIHRoYXQgZmllbGQgaXMgbm90IHNldC48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gaXNQb3NpdGl2ZSBTZXQgdG8gPGNvZGU+ZmFsc2U8L2NvZGU+IHRvIGNyZWF0ZSBhIG5lZ2F0aXZlIGR1cmF0aW9uLiBXaGVuIHRoZSBsZW5ndGgKLSAgICAgKiAgIG9mIHRoZSBkdXJhdGlvbiBpcyB6ZXJvLCB0aGlzIHBhcmFtZXRlciB3aWxsIGJlIGlnbm9yZWQuCi0gICAgICogQHBhcmFtIHllYXJzIG9mIHRoaXMgPGNvZGU+RHVyYXRpb248L2NvZGU+Ci0gICAgICogQHBhcmFtIG1vbnRocyBvZiB0aGlzIDxjb2RlPkR1cmF0aW9uPC9jb2RlPgotICAgICAqIEBwYXJhbSBkYXlzIG9mIHRoaXMgPGNvZGU+RHVyYXRpb248L2NvZGU+Ci0gICAgICogQHBhcmFtIGhvdXJzIG9mIHRoaXMgPGNvZGU+RHVyYXRpb248L2NvZGU+Ci0gICAgICogQHBhcmFtIG1pbnV0ZXMgb2YgdGhpcyA8Y29kZT5EdXJhdGlvbjwvY29kZT4KLSAgICAgKiBAcGFyYW0gc2Vjb25kcyBvZiB0aGlzIDxjb2RlPkR1cmF0aW9uPC9jb2RlPgotICAgICAqCi0gICAgICogQHJldHVybiBOZXcgPGNvZGU+RHVyYXRpb248L2NvZGU+IGNyZWF0ZWQgZnJvbSB0aGUgc3BlY2lmaWVkIHZhbHVlcy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIElmIHRoZSB2YWx1ZXMgYXJlIG5vdCBhIHZhbGlkIHJlcHJlc2VudGF0aW9uIG9mIGEKLSAgICAgKiA8Y29kZT5EdXJhdGlvbjwvY29kZT46IGlmIGFsbCB0aGUgZmllbGRzICh5ZWFycywgbW9udGhzLCAuLi4pIGFyZSBudWxsIG9yCi0gICAgICogaWYgYW55IG9mIHRoZSBmaWVsZHMgaXMgbmVnYXRpdmUuCi0gICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBJZiBpbXBsZW1lbnRhdGlvbiBjYW5ub3Qgc3VwcG9ydCByZXF1ZXN0ZWQgdmFsdWVzLgotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCBEdXJhdGlvbiBuZXdEdXJhdGlvbigKLSAgICAgICAgICAgIGZpbmFsIGJvb2xlYW4gaXNQb3NpdGl2ZSwKLSAgICAgICAgICAgIGZpbmFsIEJpZ0ludGVnZXIgeWVhcnMsCi0gICAgICAgICAgICBmaW5hbCBCaWdJbnRlZ2VyIG1vbnRocywKLSAgICAgICAgICAgIGZpbmFsIEJpZ0ludGVnZXIgZGF5cywKLSAgICAgICAgICAgIGZpbmFsIEJpZ0ludGVnZXIgaG91cnMsCi0gICAgICAgICAgICBmaW5hbCBCaWdJbnRlZ2VyIG1pbnV0ZXMsCi0gICAgICAgICAgICBmaW5hbCBCaWdEZWNpbWFsIHNlY29uZHMpOwotCi0gICAgLyoqCi0gICAgICogPHA+T2J0YWluIGEgbmV3IGluc3RhbmNlIG9mIGEgPGNvZGU+RHVyYXRpb248L2NvZGU+Ci0gICAgICogc3BlY2lmeWluZyB0aGUgPGNvZGU+RHVyYXRpb248L2NvZGU+IGFzIGlzUG9zaXRpdmUsIHllYXJzLCBtb250aHMsIGRheXMsIGhvdXJzLCBtaW51dGVzLCBzZWNvbmRzLjwvcD4KLSAgICAgKgotICAgICAqIDxwPkEge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0ZJRUxEX1VOREVGSU5FRH0gdmFsdWUgaW5kaWNhdGVzIHRoYXQgZmllbGQgaXMgbm90IHNldC48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gaXNQb3NpdGl2ZSBTZXQgdG8gPGNvZGU+ZmFsc2U8L2NvZGU+IHRvIGNyZWF0ZSBhIG5lZ2F0aXZlIGR1cmF0aW9uLiBXaGVuIHRoZSBsZW5ndGgKLSAgICAgKiAgIG9mIHRoZSBkdXJhdGlvbiBpcyB6ZXJvLCB0aGlzIHBhcmFtZXRlciB3aWxsIGJlIGlnbm9yZWQuCi0gICAgICogQHBhcmFtIHllYXJzIG9mIHRoaXMgPGNvZGU+RHVyYXRpb248L2NvZGU+Ci0gICAgICogQHBhcmFtIG1vbnRocyBvZiB0aGlzIDxjb2RlPkR1cmF0aW9uPC9jb2RlPgotICAgICAqIEBwYXJhbSBkYXlzIG9mIHRoaXMgPGNvZGU+RHVyYXRpb248L2NvZGU+Ci0gICAgICogQHBhcmFtIGhvdXJzIG9mIHRoaXMgPGNvZGU+RHVyYXRpb248L2NvZGU+Ci0gICAgICogQHBhcmFtIG1pbnV0ZXMgb2YgdGhpcyA8Y29kZT5EdXJhdGlvbjwvY29kZT4KLSAgICAgKiBAcGFyYW0gc2Vjb25kcyBvZiB0aGlzIDxjb2RlPkR1cmF0aW9uPC9jb2RlPgotICAgICAqCi0gICAgICogQHJldHVybiBOZXcgPGNvZGU+RHVyYXRpb248L2NvZGU+IGNyZWF0ZWQgZnJvbSB0aGUgc3BlY2lmaWVkIHZhbHVlcy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIElmIHRoZSB2YWx1ZXMgYXJlIG5vdCBhIHZhbGlkIHJlcHJlc2VudGF0aW9uIG9mIGEKLSAgICAgKiA8Y29kZT5EdXJhdGlvbjwvY29kZT46IGlmIGFueSBvZiB0aGUgZmllbGRzIGlzIG5lZ2F0aXZlLgotICAgICAqCi0gICAgICogQHNlZSAjbmV3RHVyYXRpb24oCi0gICAgICogICBib29sZWFuIGlzUG9zaXRpdmUsCi0gICAgICogICBCaWdJbnRlZ2VyIHllYXJzLAotICAgICAqICAgQmlnSW50ZWdlciBtb250aHMsCi0gICAgICogICBCaWdJbnRlZ2VyIGRheXMsCi0gICAgICogICBCaWdJbnRlZ2VyIGhvdXJzLAotICAgICAqICAgQmlnSW50ZWdlciBtaW51dGVzLAotICAgICAqICAgQmlnRGVjaW1hbCBzZWNvbmRzKQotICAgICAqLwotICAgIHB1YmxpYyBEdXJhdGlvbiBuZXdEdXJhdGlvbigKLSAgICAgICAgICAgIGZpbmFsIGJvb2xlYW4gaXNQb3NpdGl2ZSwKLSAgICAgICAgICAgIGZpbmFsIGludCB5ZWFycywKLSAgICAgICAgICAgIGZpbmFsIGludCBtb250aHMsCi0gICAgICAgICAgICBmaW5hbCBpbnQgZGF5cywKLSAgICAgICAgICAgIGZpbmFsIGludCBob3VycywKLSAgICAgICAgICAgIGZpbmFsIGludCBtaW51dGVzLAotICAgICAgICAgICAgZmluYWwgaW50IHNlY29uZHMpIHsKLQotICAgICAgICAgICAgLy8geWVhcnMgbWF5IG5vdCBiZSBzZXQKLSAgICAgICAgICAgIEJpZ0ludGVnZXIgcmVhbFllYXJzID0gKHllYXJzICE9IERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCkgPyBCaWdJbnRlZ2VyLnZhbHVlT2YoKGxvbmcpIHllYXJzKSA6IG51bGw7Ci0KLSAgICAgICAgICAgIC8vIG1vbnRocyBtYXkgbm90IGJlIHNldAotICAgICAgICAgICAgQmlnSW50ZWdlciByZWFsTW9udGhzID0gKG1vbnRocyAhPSBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQpID8gQmlnSW50ZWdlci52YWx1ZU9mKChsb25nKSBtb250aHMpIDogbnVsbDsKLQotICAgICAgICAgICAgLy8gZGF5cyBtYXkgbm90IGJlIHNldAotICAgICAgICAgICAgQmlnSW50ZWdlciByZWFsRGF5cyA9IChkYXlzICE9IERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCkgPyBCaWdJbnRlZ2VyLnZhbHVlT2YoKGxvbmcpIGRheXMpIDogbnVsbDsKLQotICAgICAgICAgICAgLy8gaG91cnMgbWF5IG5vdCBiZSBzZXQKLSAgICAgICAgICAgIEJpZ0ludGVnZXIgcmVhbEhvdXJzID0gKGhvdXJzICE9IERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCkgPyBCaWdJbnRlZ2VyLnZhbHVlT2YoKGxvbmcpIGhvdXJzKSA6IG51bGw7Ci0KLSAgICAgICAgICAgIC8vIG1pbnV0ZXMgbWF5IG5vdCBiZSBzZXQKLSAgICAgICAgICAgIEJpZ0ludGVnZXIgcmVhbE1pbnV0ZXMgPSAobWludXRlcyAhPSBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQpID8gQmlnSW50ZWdlci52YWx1ZU9mKChsb25nKSBtaW51dGVzKSA6IG51bGw7Ci0KLSAgICAgICAgICAgIC8vIHNlY29uZHMgbWF5IG5vdCBiZSBzZXQKLSAgICAgICAgICAgIEJpZ0RlY2ltYWwgcmVhbFNlY29uZHMgPSAoc2Vjb25kcyAhPSBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQpID8gQmlnRGVjaW1hbC52YWx1ZU9mKChsb25nKSBzZWNvbmRzKSA6IG51bGw7Ci0KLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ld0R1cmF0aW9uKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzUG9zaXRpdmUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhbFllYXJzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlYWxNb250aHMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhbERheXMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhbEhvdXJzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlYWxNaW51dGVzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlYWxTZWNvbmRzCi0gICAgICAgICAgICAgICAgICAgICk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5DcmVhdGUgYSA8Y29kZT5EdXJhdGlvbjwvY29kZT4gb2YgdHlwZSA8Y29kZT54ZHQ6ZGF5VGltZUR1cmF0aW9uPC9jb2RlPiBieSBwYXJzaW5nIGl0cyA8Y29kZT5TdHJpbmc8L2NvZGU+IHJlcHJlc2VudGF0aW9uLAotICAgICAqICI8ZW0+UG5EVG5Ibk1uUzwvZW0+IiwgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGgtZGF0YW1vZGVsI2RheVRpbWVEdXJhdGlvbiI+Ci0gICAgICogICBYUXVlcnkgMS4wIGFuZCBYUGF0aCAyLjAgRGF0YSBNb2RlbCwgeGR0OmRheVRpbWVEdXJhdGlvbjwvYT4uPC9wPgotICAgICAqCi0gICAgICogPHA+VGhlIGRhdGF0eXBlIDxjb2RlPnhkdDpkYXlUaW1lRHVyYXRpb248L2NvZGU+IGlzIGEgc3VidHlwZSBvZiA8Y29kZT54czpkdXJhdGlvbjwvY29kZT4KLSAgICAgKiB3aG9zZSBsZXhpY2FsIHJlcHJlc2VudGF0aW9uIGNvbnRhaW5zIG9ubHkgZGF5LCBob3VyLCBtaW51dGUsIGFuZCBzZWNvbmQgY29tcG9uZW50cy4KLSAgICAgKiBUaGlzIGRhdGF0eXBlIHJlc2lkZXMgaW4gdGhlIG5hbWVzcGFjZSA8Y29kZT5odHRwOi8vd3d3LnczLm9yZy8yMDAzLzExL3hwYXRoLWRhdGF0eXBlczwvY29kZT4uPC9wPgotICAgICAqCi0gICAgICogPHA+QWxsIGZvdXIgdmFsdWVzIGFyZSBzZXQgYW5kIGF2YWlsYWJsZSBmcm9tIHRoZSBjcmVhdGVkIHtAbGluayBEdXJhdGlvbn08L3A+Ci0gICAgICoKLSAgICAgKiA8cD5UaGUgWE1MIFNjaGVtYSBzcGVjaWZpY2F0aW9uIHN0YXRlcyB0aGF0IHZhbHVlcyBjYW4gYmUgb2YgYW4gYXJiaXRyYXJ5IHNpemUuCi0gICAgICogSW1wbGVtZW50YXRpb25zIG1heSBjaG9zZSBub3QgdG8gb3IgYmUgaW5jYXBhYmxlIG9mIHN1cHBvcnRpbmcgYXJiaXRyYXJpbHkgbGFyZ2UgYW5kL29yIHNtYWxsIHZhbHVlcy4KLSAgICAgKiBBbiB7QGxpbmsgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb259IHdpbGwgYmUgdGhyb3duIHdpdGggYSBtZXNzYWdlIGluZGljYXRpbmcgaW1wbGVtZW50YXRpb24gbGltaXRzCi0gICAgICogaWYgaW1wbGVtZW50YXRpb24gY2FwYWNpdGllcyBhcmUgZXhjZWVkZWQuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGxleGljYWxSZXByZXNlbnRhdGlvbiBMZXhpY2FsIHJlcHJlc2VudGF0aW9uIG9mIGEgZHVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIE5ldyA8Y29kZT5EdXJhdGlvbjwvY29kZT4gY3JlYXRlZCB1c2luZyB0aGUgc3BlY2lmaWVkIDxjb2RlPmxleGljYWxSZXByZXNlbnRhdGlvbjwvY29kZT4uCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBJZiA8Y29kZT5sZXhpY2FsUmVwcmVzZW50YXRpb248L2NvZGU+IGlzIG5vdCBhIHZhbGlkIHJlcHJlc2VudGF0aW9uIG9mIGEgPGNvZGU+RHVyYXRpb248L2NvZGU+IGV4cHJlc3NlZCBvbmx5IGluIHRlcm1zIG9mIGRheXMgYW5kIHRpbWUuCi0gICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBJZiBpbXBsZW1lbnRhdGlvbiBjYW5ub3Qgc3VwcG9ydCByZXF1ZXN0ZWQgdmFsdWVzLgotICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gSWYgPGNvZGU+bGV4aWNhbFJlcHJlc2VudGF0aW9uPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgRHVyYXRpb24gbmV3RHVyYXRpb25EYXlUaW1lKGZpbmFsIFN0cmluZyBsZXhpY2FsUmVwcmVzZW50YXRpb24pIHsKLSAgICAgICAgLy8gbGV4aWNhbFJlcHJlc2VudGF0aW9uIG11c3QgYmUgbm9uLW51bGwKLSAgICAgICAgaWYgKGxleGljYWxSZXByZXNlbnRhdGlvbiA9PSBudWxsKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgIlRyeWluZyB0byBjcmVhdGUgYW4geGR0OmRheVRpbWVEdXJhdGlvbiB3aXRoIGFuIGludmFsaWQiCi0gICAgICAgICAgICAgICAgKyAiIGxleGljYWwgcmVwcmVzZW50YXRpb24gb2YgXCJudWxsXCIiKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIHRlc3QgbGV4aWNhbFJlcHJlc2VudGF0aW9uIGFnYWluc3Qgc3BlYyByZWdleAotICAgICAgICBNYXRjaGVyIG1hdGNoZXIgPSBYRFRTQ0hFTUFfRFRELm1hdGNoZXIobGV4aWNhbFJlcHJlc2VudGF0aW9uKTsKLSAgICAgICAgaWYgKCFtYXRjaGVyLm1hdGNoZXMoKSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAiVHJ5aW5nIHRvIGNyZWF0ZSBhbiB4ZHQ6ZGF5VGltZUR1cmF0aW9uIHdpdGggYW4gaW52YWxpZCIKLSAgICAgICAgICAgICAgICArICIgbGV4aWNhbCByZXByZXNlbnRhdGlvbiBvZiBcIiIgKyBsZXhpY2FsUmVwcmVzZW50YXRpb24KLSAgICAgICAgICAgICAgICArICJcIiwgZGF0YSBtb2RlbCByZXF1aXJlcyB5ZWFycyBhbmQgbW9udGhzIG9ubHkuIik7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gbmV3RHVyYXRpb24obGV4aWNhbFJlcHJlc2VudGF0aW9uKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5DcmVhdGUgYSA8Y29kZT5EdXJhdGlvbjwvY29kZT4gb2YgdHlwZSA8Y29kZT54ZHQ6ZGF5VGltZUR1cmF0aW9uPC9jb2RlPiB1c2luZyB0aGUgc3BlY2lmaWVkIG1pbGxpc2Vjb25kcyBhcyBkZWZpbmVkIGluCi0gICAgICogPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGgtZGF0YW1vZGVsI2RheVRpbWVEdXJhdGlvbiI+Ci0gICAgICogICBYUXVlcnkgMS4wIGFuZCBYUGF0aCAyLjAgRGF0YSBNb2RlbCwgeGR0OmRheVRpbWVEdXJhdGlvbjwvYT4uPC9wPgotICAgICAqCi0gICAgICogPHA+VGhlIGRhdGF0eXBlIDxjb2RlPnhkdDpkYXlUaW1lRHVyYXRpb248L2NvZGU+IGlzIGEgc3VidHlwZSBvZiA8Y29kZT54czpkdXJhdGlvbjwvY29kZT4KLSAgICAgKiB3aG9zZSBsZXhpY2FsIHJlcHJlc2VudGF0aW9uIGNvbnRhaW5zIG9ubHkgZGF5LCBob3VyLCBtaW51dGUsIGFuZCBzZWNvbmQgY29tcG9uZW50cy4KLSAgICAgKiBUaGlzIGRhdGF0eXBlIHJlc2lkZXMgaW4gdGhlIG5hbWVzcGFjZSA8Y29kZT5odHRwOi8vd3d3LnczLm9yZy8yMDAzLzExL3hwYXRoLWRhdGF0eXBlczwvY29kZT4uPC9wPgotICAgICAqCi0gICAgICogPHA+QWxsIGZvdXIgdmFsdWVzIGFyZSBzZXQgYnkgY29tcHV0aW5nIHRoZWlyIHZhbHVlcyBmcm9tIHRoZSBzcGVjaWZpZWQgbWlsbGlzZWNvbmRzCi0gICAgICogYW5kIGFyZSBhdmFpbGFibGUgdXNpbmcgdGhlIDxjb2RlPmdldDwvY29kZT4gbWV0aG9kcyBvZiAgdGhlIGNyZWF0ZWQge0BsaW5rIER1cmF0aW9ufS4KLSAgICAgKiBUaGUgdmFsdWVzIGNvbmZvcm0gdG8gYW5kIGFyZSBkZWZpbmVkIGJ5OjwvcD4KLSAgICAgKiA8dWw+Ci0gICAgICogICA8bGk+SVNPIDg2MDE6MjAwMChFKSBTZWN0aW9uIDUuNS4zLjIgQWx0ZXJuYXRpdmUgZm9ybWF0PC9saT4KLSAgICAgKiAgIDxsaT48YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94bWxzY2hlbWEtMi8jaXNvZm9ybWF0cyI+Ci0gICAgICogICAgIFczQyBYTUwgU2NoZW1hIDEuMCBQYXJ0IDIsIEFwcGVuZGl4IEQsIElTTyA4NjAxIERhdGUgYW5kIFRpbWUgRm9ybWF0czwvYT4KLSAgICAgKiAgIDwvbGk+Ci0gICAgICogICA8bGk+e0BsaW5rIFhNTEdyZWdvcmlhbkNhbGVuZGFyfSAgRGF0ZS9UaW1lIERhdGF0eXBlIEZpZWxkIE1hcHBpbmcgQmV0d2VlbiBYTUwgU2NoZW1hIDEuMCBhbmQgSmF2YSBSZXByZXNlbnRhdGlvbjwvbGk+Ci0gICAgICogPC91bD4KLSAgICAgKgotICAgICAqIDxwPlRoZSBkZWZhdWx0IHN0YXJ0IGluc3RhbmNlIGlzIGRlZmluZWQgYnkge0BsaW5rIEdyZWdvcmlhbkNhbGVuZGFyfSdzIHVzZSBvZiB0aGUgc3RhcnQgb2YgdGhlIGVwb2NoOiBpLmUuLAotICAgICAqIHtAbGluayBqYXZhLnV0aWwuQ2FsZW5kYXIjWUVBUn0gPSAxOTcwLAotICAgICAqIHtAbGluayBqYXZhLnV0aWwuQ2FsZW5kYXIjTU9OVEh9ID0ge0BsaW5rIGphdmEudXRpbC5DYWxlbmRhciNKQU5VQVJZfSwKLSAgICAgKiB7QGxpbmsgamF2YS51dGlsLkNhbGVuZGFyI0RBVEV9ID0gMSwgZXRjLgotICAgICAqIFRoaXMgaXMgaW1wb3J0YW50IGFzIHRoZXJlIGFyZSB2YXJpYXRpb25zIGluIHRoZSBHcmVnb3JpYW4gQ2FsZW5kYXIsCi0gICAgICogZS5nLiBsZWFwIHllYXJzIGhhdmUgZGlmZmVyZW50IGRheXMgaW4gdGhlIG1vbnRoID0ge0BsaW5rIGphdmEudXRpbC5DYWxlbmRhciNGRUJSVUFSWX0KLSAgICAgKiBzbyB0aGUgcmVzdWx0IG9mIHtAbGluayBEdXJhdGlvbiNnZXREYXlzKCl9IGNhbiBiZSBpbmZsdWVuY2VkLjwvcD4KLSAgICAgKgotICAgICAqIDxwPkFueSByZW1haW5pbmcgbWlsbGlzZWNvbmRzIGFmdGVyIGRldGVybWluaW5nIHRoZSBkYXksIGhvdXIsIG1pbnV0ZSBhbmQgc2Vjb25kIGFyZSBkaXNjYXJkZWQuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGR1cmF0aW9uSW5NaWxsaXNlY29uZHMgTWlsbGlzZWNvbmRzIG9mIDxjb2RlPkR1cmF0aW9uPC9jb2RlPiB0byBjcmVhdGUuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIE5ldyA8Y29kZT5EdXJhdGlvbjwvY29kZT4gY3JlYXRlZCB3aXRoIHRoZSBzcGVjaWZpZWQgPGNvZGU+ZHVyYXRpb25Jbk1pbGxpc2Vjb25kczwvY29kZT4uCi0gICAgICoKLSAgICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hwYXRoLWRhdGFtb2RlbCNkYXlUaW1lRHVyYXRpb24iPgotICAgICAqICAgWFF1ZXJ5IDEuMCBhbmQgWFBhdGggMi4wIERhdGEgTW9kZWwsIHhkdDpkYXlUaW1lRHVyYXRpb248L2E+Ci0gICAgICovCi0gICAgcHVibGljIER1cmF0aW9uIG5ld0R1cmF0aW9uRGF5VGltZShmaW5hbCBsb25nIGR1cmF0aW9uSW5NaWxsaXNlY29uZHMpIHsKLQotICAgICAgICAgICAgcmV0dXJuIG5ld0R1cmF0aW9uKGR1cmF0aW9uSW5NaWxsaXNlY29uZHMpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPkNyZWF0ZSBhIDxjb2RlPkR1cmF0aW9uPC9jb2RlPiBvZiB0eXBlIDxjb2RlPnhkdDpkYXlUaW1lRHVyYXRpb248L2NvZGU+IHVzaW5nIHRoZSBzcGVjaWZpZWQKLSAgICAgKiA8Y29kZT5kYXk8L2NvZGU+LCA8Y29kZT5ob3VyPC9jb2RlPiwgPGNvZGU+bWludXRlPC9jb2RlPiBhbmQgPGNvZGU+c2Vjb25kPC9jb2RlPiBhcyBkZWZpbmVkIGluCi0gICAgICogPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGgtZGF0YW1vZGVsI2RheVRpbWVEdXJhdGlvbiI+Ci0gICAgICogICBYUXVlcnkgMS4wIGFuZCBYUGF0aCAyLjAgRGF0YSBNb2RlbCwgeGR0OmRheVRpbWVEdXJhdGlvbjwvYT4uPC9wPgotICAgICAqCi0gICAgICogPHA+VGhlIGRhdGF0eXBlIDxjb2RlPnhkdDpkYXlUaW1lRHVyYXRpb248L2NvZGU+IGlzIGEgc3VidHlwZSBvZiA8Y29kZT54czpkdXJhdGlvbjwvY29kZT4KLSAgICAgKiB3aG9zZSBsZXhpY2FsIHJlcHJlc2VudGF0aW9uIGNvbnRhaW5zIG9ubHkgZGF5LCBob3VyLCBtaW51dGUsIGFuZCBzZWNvbmQgY29tcG9uZW50cy4KLSAgICAgKiBUaGlzIGRhdGF0eXBlIHJlc2lkZXMgaW4gdGhlIG5hbWVzcGFjZSA8Y29kZT5odHRwOi8vd3d3LnczLm9yZy8yMDAzLzExL3hwYXRoLWRhdGF0eXBlczwvY29kZT4uPC9wPgotICAgICAqCi0gICAgICogPHA+VGhlIFhNTCBTY2hlbWEgc3BlY2lmaWNhdGlvbiBzdGF0ZXMgdGhhdCB2YWx1ZXMgY2FuIGJlIG9mIGFuIGFyYml0cmFyeSBzaXplLgotICAgICAqIEltcGxlbWVudGF0aW9ucyBtYXkgY2hvc2Ugbm90IHRvIG9yIGJlIGluY2FwYWJsZSBvZiBzdXBwb3J0aW5nIGFyYml0cmFyaWx5IGxhcmdlIGFuZC9vciBzbWFsbCB2YWx1ZXMuCi0gICAgICogQW4ge0BsaW5rIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9ufSB3aWxsIGJlIHRocm93biB3aXRoIGEgbWVzc2FnZSBpbmRpY2F0aW5nIGltcGxlbWVudGF0aW9uIGxpbWl0cwotICAgICAqIGlmIGltcGxlbWVudGF0aW9uIGNhcGFjaXRpZXMgYXJlIGV4Y2VlZGVkLjwvcD4KLSAgICAgKgotICAgICAqIDxwPkEgPGNvZGU+bnVsbDwvY29kZT4gdmFsdWUgaW5kaWNhdGVzIHRoYXQgZmllbGQgaXMgbm90IHNldC48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gaXNQb3NpdGl2ZSBTZXQgdG8gPGNvZGU+ZmFsc2U8L2NvZGU+IHRvIGNyZWF0ZSBhIG5lZ2F0aXZlIGR1cmF0aW9uLiBXaGVuIHRoZSBsZW5ndGgKLSAgICAgKiAgIG9mIHRoZSBkdXJhdGlvbiBpcyB6ZXJvLCB0aGlzIHBhcmFtZXRlciB3aWxsIGJlIGlnbm9yZWQuCi0gICAgICogQHBhcmFtIGRheSBEYXkgb2YgPGNvZGU+RHVyYXRpb248L2NvZGU+LgotICAgICAqIEBwYXJhbSBob3VyIEhvdXIgb2YgPGNvZGU+RHVyYXRpb248L2NvZGU+LgotICAgICAqIEBwYXJhbSBtaW51dGUgTWludXRlIG9mIDxjb2RlPkR1cmF0aW9uPC9jb2RlPi4KLSAgICAgKiBAcGFyYW0gc2Vjb25kIFNlY29uZCBvZiA8Y29kZT5EdXJhdGlvbjwvY29kZT4uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIE5ldyA8Y29kZT5EdXJhdGlvbjwvY29kZT4gY3JlYXRlZCB3aXRoIHRoZSBzcGVjaWZpZWQgPGNvZGU+ZGF5PC9jb2RlPiwgPGNvZGU+aG91cjwvY29kZT4sIDxjb2RlPm1pbnV0ZTwvY29kZT4KLSAgICAgKiBhbmQgPGNvZGU+c2Vjb25kPC9jb2RlPi4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIElmIHRoZSB2YWx1ZXMgYXJlIG5vdCBhIHZhbGlkIHJlcHJlc2VudGF0aW9uIG9mIGEKLSAgICAgKiA8Y29kZT5EdXJhdGlvbjwvY29kZT46IGlmIGFsbCB0aGUgZmllbGRzIChkYXksIGhvdXIsIC4uLikgYXJlIG51bGwgb3IKLSAgICAgKiBpZiBhbnkgb2YgdGhlIGZpZWxkcyBpcyBuZWdhdGl2ZS4KLSAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIElmIGltcGxlbWVudGF0aW9uIGNhbm5vdCBzdXBwb3J0IHJlcXVlc3RlZCB2YWx1ZXMuCi0gICAgICovCi0gICAgcHVibGljIER1cmF0aW9uIG5ld0R1cmF0aW9uRGF5VGltZSgKLSAgICAgICAgICAgIGZpbmFsIGJvb2xlYW4gaXNQb3NpdGl2ZSwKLSAgICAgICAgICAgIGZpbmFsIEJpZ0ludGVnZXIgZGF5LAotICAgICAgICAgICAgZmluYWwgQmlnSW50ZWdlciBob3VyLAotICAgICAgICAgICAgZmluYWwgQmlnSW50ZWdlciBtaW51dGUsCi0gICAgICAgICAgICBmaW5hbCBCaWdJbnRlZ2VyIHNlY29uZCkgewotCi0gICAgICAgICAgICByZXR1cm4gbmV3RHVyYXRpb24oCi0gICAgICAgICAgICAgICAgICAgIGlzUG9zaXRpdmUsCi0gICAgICAgICAgICAgICAgICAgIG51bGwsICAvLyB5ZWFycwotICAgICAgICAgICAgICAgICAgICBudWxsLCAvLyBtb250aHMKLSAgICAgICAgICAgICAgICAgICAgZGF5LAotICAgICAgICAgICAgICAgICAgICBob3VyLAotICAgICAgICAgICAgICAgICAgICBtaW51dGUsCi0gICAgICAgICAgICAgICAgICAgIChzZWNvbmQgIT0gbnVsbCk/IG5ldyBCaWdEZWNpbWFsKHNlY29uZCk6bnVsbAotICAgICAgICAgICAgKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5DcmVhdGUgYSA8Y29kZT5EdXJhdGlvbjwvY29kZT4gb2YgdHlwZSA8Y29kZT54ZHQ6ZGF5VGltZUR1cmF0aW9uPC9jb2RlPiB1c2luZyB0aGUgc3BlY2lmaWVkCi0gICAgICogPGNvZGU+ZGF5PC9jb2RlPiwgPGNvZGU+aG91cjwvY29kZT4sIDxjb2RlPm1pbnV0ZTwvY29kZT4gYW5kIDxjb2RlPnNlY29uZDwvY29kZT4gYXMgZGVmaW5lZCBpbgotICAgICAqIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hwYXRoLWRhdGFtb2RlbCNkYXlUaW1lRHVyYXRpb24iPgotICAgICAqICAgWFF1ZXJ5IDEuMCBhbmQgWFBhdGggMi4wIERhdGEgTW9kZWwsIHhkdDpkYXlUaW1lRHVyYXRpb248L2E+LjwvcD4KLSAgICAgKgotICAgICAqIDxwPlRoZSBkYXRhdHlwZSA8Y29kZT54ZHQ6ZGF5VGltZUR1cmF0aW9uPC9jb2RlPiBpcyBhIHN1YnR5cGUgb2YgPGNvZGU+eHM6ZHVyYXRpb248L2NvZGU+Ci0gICAgICogd2hvc2UgbGV4aWNhbCByZXByZXNlbnRhdGlvbiBjb250YWlucyBvbmx5IGRheSwgaG91ciwgbWludXRlLCBhbmQgc2Vjb25kIGNvbXBvbmVudHMuCi0gICAgICogVGhpcyBkYXRhdHlwZSByZXNpZGVzIGluIHRoZSBuYW1lc3BhY2UgPGNvZGU+aHR0cDovL3d3dy53My5vcmcvMjAwMy8xMS94cGF0aC1kYXRhdHlwZXM8L2NvZGU+LjwvcD4KLSAgICAgKgotICAgICAqIDxwPkEge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0ZJRUxEX1VOREVGSU5FRH0gdmFsdWUgaW5kaWNhdGVzIHRoYXQgZmllbGQgaXMgbm90IHNldC48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gaXNQb3NpdGl2ZSBTZXQgdG8gPGNvZGU+ZmFsc2U8L2NvZGU+IHRvIGNyZWF0ZSBhIG5lZ2F0aXZlIGR1cmF0aW9uLiBXaGVuIHRoZSBsZW5ndGgKLSAgICAgKiAgIG9mIHRoZSBkdXJhdGlvbiBpcyB6ZXJvLCB0aGlzIHBhcmFtZXRlciB3aWxsIGJlIGlnbm9yZWQuCi0gICAgICogQHBhcmFtIGRheSBEYXkgb2YgPGNvZGU+RHVyYXRpb248L2NvZGU+LgotICAgICAqIEBwYXJhbSBob3VyIEhvdXIgb2YgPGNvZGU+RHVyYXRpb248L2NvZGU+LgotICAgICAqIEBwYXJhbSBtaW51dGUgTWludXRlIG9mIDxjb2RlPkR1cmF0aW9uPC9jb2RlPi4KLSAgICAgKiBAcGFyYW0gc2Vjb25kIFNlY29uZCBvZiA8Y29kZT5EdXJhdGlvbjwvY29kZT4uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIE5ldyA8Y29kZT5EdXJhdGlvbjwvY29kZT4gY3JlYXRlZCB3aXRoIHRoZSBzcGVjaWZpZWQgPGNvZGU+ZGF5PC9jb2RlPiwgPGNvZGU+aG91cjwvY29kZT4sIDxjb2RlPm1pbnV0ZTwvY29kZT4KLSAgICAgKiBhbmQgPGNvZGU+c2Vjb25kPC9jb2RlPi4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIElmIHRoZSB2YWx1ZXMgYXJlIG5vdCBhIHZhbGlkIHJlcHJlc2VudGF0aW9uIG9mIGEKLSAgICAgKiA8Y29kZT5EdXJhdGlvbjwvY29kZT46IGlmIGFueSBvZiB0aGUgZmllbGRzIChkYXksIGhvdXIsIC4uLikgaXMgbmVnYXRpdmUuCi0gICAgICovCi0gICAgcHVibGljIER1cmF0aW9uIG5ld0R1cmF0aW9uRGF5VGltZSgKLSAgICAgICAgICAgIGZpbmFsIGJvb2xlYW4gaXNQb3NpdGl2ZSwKLSAgICAgICAgICAgIGZpbmFsIGludCBkYXksCi0gICAgICAgICAgICBmaW5hbCBpbnQgaG91ciwKLSAgICAgICAgICAgIGZpbmFsIGludCBtaW51dGUsCi0gICAgICAgICAgICBmaW5hbCBpbnQgc2Vjb25kKSB7Ci0KLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ld0R1cmF0aW9uRGF5VGltZSgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc1Bvc2l0aXZlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIudmFsdWVPZigobG9uZykgZGF5KSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLnZhbHVlT2YoKGxvbmcpIGhvdXIpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJpZ0ludGVnZXIudmFsdWVPZigobG9uZykgbWludXRlKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLnZhbHVlT2YoKGxvbmcpIHNlY29uZCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICApOwotICAgICAgICAgICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+Q3JlYXRlIGEgPGNvZGU+RHVyYXRpb248L2NvZGU+IG9mIHR5cGUgPGNvZGU+eGR0OnllYXJNb250aER1cmF0aW9uPC9jb2RlPiBieSBwYXJzaW5nIGl0cyA8Y29kZT5TdHJpbmc8L2NvZGU+IHJlcHJlc2VudGF0aW9uLAotICAgICAqICI8ZW0+UG5Zbk08L2VtPiIsIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hwYXRoLWRhdGFtb2RlbCN5ZWFyTW9udGhEdXJhdGlvbiI+Ci0gICAgICogICBYUXVlcnkgMS4wIGFuZCBYUGF0aCAyLjAgRGF0YSBNb2RlbCwgeGR0OnllYXJNb250aER1cmF0aW9uPC9hPi48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5UaGUgZGF0YXR5cGUgPGNvZGU+eGR0OnllYXJNb250aER1cmF0aW9uPC9jb2RlPiBpcyBhIHN1YnR5cGUgb2YgPGNvZGU+eHM6ZHVyYXRpb248L2NvZGU+Ci0gICAgICogd2hvc2UgbGV4aWNhbCByZXByZXNlbnRhdGlvbiBjb250YWlucyBvbmx5IHllYXIgYW5kIG1vbnRoIGNvbXBvbmVudHMuCi0gICAgICogVGhpcyBkYXRhdHlwZSByZXNpZGVzIGluIHRoZSBuYW1lc3BhY2Uge0BsaW5rIGphdmF4LnhtbC5YTUxDb25zdGFudHMjVzNDX1hQQVRIX0RBVEFUWVBFX05TX1VSSX0uPC9wPgotICAgICAqCi0gICAgICogPHA+Qm90aCB2YWx1ZXMgYXJlIHNldCBhbmQgYXZhaWxhYmxlIGZyb20gdGhlIGNyZWF0ZWQge0BsaW5rIER1cmF0aW9ufTwvcD4KLSAgICAgKgotICAgICAqIDxwPlRoZSBYTUwgU2NoZW1hIHNwZWNpZmljYXRpb24gc3RhdGVzIHRoYXQgdmFsdWVzIGNhbiBiZSBvZiBhbiBhcmJpdHJhcnkgc2l6ZS4KLSAgICAgKiBJbXBsZW1lbnRhdGlvbnMgbWF5IGNob3NlIG5vdCB0byBvciBiZSBpbmNhcGFibGUgb2Ygc3VwcG9ydGluZyBhcmJpdHJhcmlseSBsYXJnZSBhbmQvb3Igc21hbGwgdmFsdWVzLgotICAgICAqIEFuIHtAbGluayBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbn0gd2lsbCBiZSB0aHJvd24gd2l0aCBhIG1lc3NhZ2UgaW5kaWNhdGluZyBpbXBsZW1lbnRhdGlvbiBsaW1pdHMKLSAgICAgKiBpZiBpbXBsZW1lbnRhdGlvbiBjYXBhY2l0aWVzIGFyZSBleGNlZWRlZC48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gbGV4aWNhbFJlcHJlc2VudGF0aW9uIExleGljYWwgcmVwcmVzZW50YXRpb24gb2YgYSBkdXJhdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gTmV3IDxjb2RlPkR1cmF0aW9uPC9jb2RlPiBjcmVhdGVkIHVzaW5nIHRoZSBzcGVjaWZpZWQgPGNvZGU+bGV4aWNhbFJlcHJlc2VudGF0aW9uPC9jb2RlPi4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIElmIDxjb2RlPmxleGljYWxSZXByZXNlbnRhdGlvbjwvY29kZT4gaXMgbm90IGEgdmFsaWQgcmVwcmVzZW50YXRpb24gb2YgYSA8Y29kZT5EdXJhdGlvbjwvY29kZT4gZXhwcmVzc2VkIG9ubHkgaW4gdGVybXMgb2YgeWVhcnMgYW5kIG1vbnRocy4KLSAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIElmIGltcGxlbWVudGF0aW9uIGNhbm5vdCBzdXBwb3J0IHJlcXVlc3RlZCB2YWx1ZXMuCi0gICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBJZiA8Y29kZT5sZXhpY2FsUmVwcmVzZW50YXRpb248L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBEdXJhdGlvbiBuZXdEdXJhdGlvblllYXJNb250aCgKLSAgICAgICAgICAgIGZpbmFsIFN0cmluZyBsZXhpY2FsUmVwcmVzZW50YXRpb24pIHsKLQotICAgICAgICAvLyBsZXhpY2FsUmVwcmVzZW50YXRpb24gbXVzdCBiZSBub24tbnVsbAotICAgICAgICBpZiAobGV4aWNhbFJlcHJlc2VudGF0aW9uID09IG51bGwpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgIlRyeWluZyB0byBjcmVhdGUgYW4geGR0OnllYXJNb250aER1cmF0aW9uIHdpdGggYW4gaW52YWxpZCIKLSAgICAgICAgICAgICAgICAgICAgKyAiIGxleGljYWwgcmVwcmVzZW50YXRpb24gb2YgXCJudWxsXCIiKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIHRlc3QgbGV4aWNhbFJlcHJlc2VudGF0aW9uIGFnYWluc3Qgc3BlYyByZWdleAotICAgICAgICBNYXRjaGVyIG1hdGNoZXIgPSBYRFRTQ0hFTUFfWU1ELm1hdGNoZXIobGV4aWNhbFJlcHJlc2VudGF0aW9uKTsKLSAgICAgICAgaWYgKCFtYXRjaGVyLm1hdGNoZXMoKSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgIlRyeWluZyB0byBjcmVhdGUgYW4geGR0OnllYXJNb250aER1cmF0aW9uIHdpdGggYW4gaW52YWxpZCIKLSAgICAgICAgICAgICAgICAgICAgKyAiIGxleGljYWwgcmVwcmVzZW50YXRpb24gb2YgXCIiICsgbGV4aWNhbFJlcHJlc2VudGF0aW9uCi0gICAgICAgICAgICAgICAgICAgICsgIlwiLCBkYXRhIG1vZGVsIHJlcXVpcmVzIGRheXMgYW5kIHRpbWVzIG9ubHkuIik7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gbmV3RHVyYXRpb24obGV4aWNhbFJlcHJlc2VudGF0aW9uKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5DcmVhdGUgYSA8Y29kZT5EdXJhdGlvbjwvY29kZT4gb2YgdHlwZSA8Y29kZT54ZHQ6eWVhck1vbnRoRHVyYXRpb248L2NvZGU+IHVzaW5nIHRoZSBzcGVjaWZpZWQgbWlsbGlzZWNvbmRzIGFzIGRlZmluZWQgaW4KLSAgICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aC1kYXRhbW9kZWwjeWVhck1vbnRoRHVyYXRpb24iPgotICAgICAqICAgWFF1ZXJ5IDEuMCBhbmQgWFBhdGggMi4wIERhdGEgTW9kZWwsIHhkdDp5ZWFyTW9udGhEdXJhdGlvbjwvYT4uPC9wPgotICAgICAqCi0gICAgICogPHA+VGhlIGRhdGF0eXBlIDxjb2RlPnhkdDp5ZWFyTW9udGhEdXJhdGlvbjwvY29kZT4gaXMgYSBzdWJ0eXBlIG9mIDxjb2RlPnhzOmR1cmF0aW9uPC9jb2RlPgotICAgICAqIHdob3NlIGxleGljYWwgcmVwcmVzZW50YXRpb24gY29udGFpbnMgb25seSB5ZWFyIGFuZCBtb250aCBjb21wb25lbnRzLgotICAgICAqIFRoaXMgZGF0YXR5cGUgcmVzaWRlcyBpbiB0aGUgbmFtZXNwYWNlIHtAbGluayBqYXZheC54bWwuWE1MQ29uc3RhbnRzI1czQ19YUEFUSF9EQVRBVFlQRV9OU19VUkl9LjwvcD4KLSAgICAgKgotICAgICAqIDxwPkJvdGggdmFsdWVzIGFyZSBzZXQgYnkgY29tcHV0aW5nIHRoZWlyIHZhbHVlcyBmcm9tIHRoZSBzcGVjaWZpZWQgbWlsbGlzZWNvbmRzCi0gICAgICogYW5kIGFyZSBhdmFpbGFibGUgdXNpbmcgdGhlIDxjb2RlPmdldDwvY29kZT4gbWV0aG9kcyBvZiAgdGhlIGNyZWF0ZWQge0BsaW5rIER1cmF0aW9ufS4KLSAgICAgKiBUaGUgdmFsdWVzIGNvbmZvcm0gdG8gYW5kIGFyZSBkZWZpbmVkIGJ5OjwvcD4KLSAgICAgKiA8dWw+Ci0gICAgICogICA8bGk+SVNPIDg2MDE6MjAwMChFKSBTZWN0aW9uIDUuNS4zLjIgQWx0ZXJuYXRpdmUgZm9ybWF0PC9saT4KLSAgICAgKiAgIDxsaT48YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94bWxzY2hlbWEtMi8jaXNvZm9ybWF0cyI+Ci0gICAgICogICAgIFczQyBYTUwgU2NoZW1hIDEuMCBQYXJ0IDIsIEFwcGVuZGl4IEQsIElTTyA4NjAxIERhdGUgYW5kIFRpbWUgRm9ybWF0czwvYT4KLSAgICAgKiAgIDwvbGk+Ci0gICAgICogICA8bGk+e0BsaW5rIFhNTEdyZWdvcmlhbkNhbGVuZGFyfSAgRGF0ZS9UaW1lIERhdGF0eXBlIEZpZWxkIE1hcHBpbmcgQmV0d2VlbiBYTUwgU2NoZW1hIDEuMCBhbmQgSmF2YSBSZXByZXNlbnRhdGlvbjwvbGk+Ci0gICAgICogPC91bD4KLSAgICAgKgotICAgICAqIDxwPlRoZSBkZWZhdWx0IHN0YXJ0IGluc3RhbmNlIGlzIGRlZmluZWQgYnkge0BsaW5rIEdyZWdvcmlhbkNhbGVuZGFyfSdzIHVzZSBvZiB0aGUgc3RhcnQgb2YgdGhlIGVwb2NoOiBpLmUuLAotICAgICAqIHtAbGluayBqYXZhLnV0aWwuQ2FsZW5kYXIjWUVBUn0gPSAxOTcwLAotICAgICAqIHtAbGluayBqYXZhLnV0aWwuQ2FsZW5kYXIjTU9OVEh9ID0ge0BsaW5rIGphdmEudXRpbC5DYWxlbmRhciNKQU5VQVJZfSwKLSAgICAgKiB7QGxpbmsgamF2YS51dGlsLkNhbGVuZGFyI0RBVEV9ID0gMSwgZXRjLgotICAgICAqIFRoaXMgaXMgaW1wb3J0YW50IGFzIHRoZXJlIGFyZSB2YXJpYXRpb25zIGluIHRoZSBHcmVnb3JpYW4gQ2FsZW5kYXIsCi0gICAgICogZS5nLiBsZWFwIHllYXJzIGhhdmUgZGlmZmVyZW50IGRheXMgaW4gdGhlIG1vbnRoID0ge0BsaW5rIGphdmEudXRpbC5DYWxlbmRhciNGRUJSVUFSWX0KLSAgICAgKiBzbyB0aGUgcmVzdWx0IG9mIHtAbGluayBEdXJhdGlvbiNnZXRNb250aHMoKX0gY2FuIGJlIGluZmx1ZW5jZWQuPC9wPgotICAgICAqCi0gICAgICogPHA+QW55IHJlbWFpbmluZyBtaWxsaXNlY29uZHMgYWZ0ZXIgZGV0ZXJtaW5pbmcgdGhlIHllYXIgYW5kIG1vbnRoIGFyZSBkaXNjYXJkZWQuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGR1cmF0aW9uSW5NaWxsaXNlY29uZHMgTWlsbGlzZWNvbmRzIG9mIDxjb2RlPkR1cmF0aW9uPC9jb2RlPiB0byBjcmVhdGUuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIE5ldyA8Y29kZT5EdXJhdGlvbjwvY29kZT4gY3JlYXRlZCB1c2luZyB0aGUgc3BlY2lmaWVkIDxjb2RlPmR1cmF0aW9uSW5NaWxsaXNlY29uZHM8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBEdXJhdGlvbiBuZXdEdXJhdGlvblllYXJNb250aCgKLSAgICAgICAgICAgIGZpbmFsIGxvbmcgZHVyYXRpb25Jbk1pbGxpc2Vjb25kcykgewotCi0gICAgICAgIC8vIGNyZWF0ZSBhIER1cmF0aW9uIHRoYXQgb25seSBoYXMgc2lnbiwgeWVhciAmIG1vbnRoCi0gICAgICAgIC8vIER1cmF0aW9uIGlzIGltbXV0YWJsZSwgc28gbmVlZCB0byBjcmVhdGUgYSBuZXcgRHVyYXRpb24KLSAgICAgICAgLy8gaW1wbGVtZW50YXRpb25zIG1heSBvdmVycmlkZSB0aGlzIG1ldGhvZCBpbiBhIG1vcmUgZWZmaWNpZW50IHdheQotICAgICAgICBEdXJhdGlvbiBmdWxsRHVyYXRpb24gPSBuZXdEdXJhdGlvbihkdXJhdGlvbkluTWlsbGlzZWNvbmRzKTsKLSAgICAgICAgYm9vbGVhbiBpc1Bvc2l0aXZlID0gKGZ1bGxEdXJhdGlvbi5nZXRTaWduKCkgPT0gLTEpID8gZmFsc2UgOiB0cnVlOwotICAgICAgICBCaWdJbnRlZ2VyIHllYXJzID0KLSAgICAgICAgICAgIChCaWdJbnRlZ2VyKSBmdWxsRHVyYXRpb24uZ2V0RmllbGQoRGF0YXR5cGVDb25zdGFudHMuWUVBUlMpOwotICAgICAgICBpZiAoeWVhcnMgPT0gbnVsbCkgeyB5ZWFycyA9IEJpZ0ludGVnZXIuWkVSTzsgfQotICAgICAgICBCaWdJbnRlZ2VyIG1vbnRocyA9Ci0gICAgICAgICAgICAoQmlnSW50ZWdlcikgZnVsbER1cmF0aW9uLmdldEZpZWxkKERhdGF0eXBlQ29uc3RhbnRzLk1PTlRIUyk7Ci0gICAgICAgIGlmIChtb250aHMgPT0gbnVsbCkgeyBtb250aHMgPSBCaWdJbnRlZ2VyLlpFUk87IH0KLQotICAgICAgICByZXR1cm4gbmV3RHVyYXRpb25ZZWFyTW9udGgoaXNQb3NpdGl2ZSwgeWVhcnMsIG1vbnRocyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+Q3JlYXRlIGEgPGNvZGU+RHVyYXRpb248L2NvZGU+IG9mIHR5cGUgPGNvZGU+eGR0OnllYXJNb250aER1cmF0aW9uPC9jb2RlPiB1c2luZyB0aGUgc3BlY2lmaWVkCi0gICAgICogPGNvZGU+eWVhcjwvY29kZT4gYW5kIDxjb2RlPm1vbnRoPC9jb2RlPiBhcyBkZWZpbmVkIGluCi0gICAgICogPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGgtZGF0YW1vZGVsI3llYXJNb250aER1cmF0aW9uIj4KLSAgICAgKiAgIFhRdWVyeSAxLjAgYW5kIFhQYXRoIDIuMCBEYXRhIE1vZGVsLCB4ZHQ6eWVhck1vbnRoRHVyYXRpb248L2E+LjwvcD4KLSAgICAgKgotICAgICAqIDxwPlRoZSBYTUwgU2NoZW1hIHNwZWNpZmljYXRpb24gc3RhdGVzIHRoYXQgdmFsdWVzIGNhbiBiZSBvZiBhbiBhcmJpdHJhcnkgc2l6ZS4KLSAgICAgKiBJbXBsZW1lbnRhdGlvbnMgbWF5IGNob3NlIG5vdCB0byBvciBiZSBpbmNhcGFibGUgb2Ygc3VwcG9ydGluZyBhcmJpdHJhcmlseSBsYXJnZSBhbmQvb3Igc21hbGwgdmFsdWVzLgotICAgICAqIEFuIHtAbGluayBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbn0gd2lsbCBiZSB0aHJvd24gd2l0aCBhIG1lc3NhZ2UgaW5kaWNhdGluZyBpbXBsZW1lbnRhdGlvbiBsaW1pdHMKLSAgICAgKiBpZiBpbXBsZW1lbnRhdGlvbiBjYXBhY2l0aWVzIGFyZSBleGNlZWRlZC48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5BIDxjb2RlPm51bGw8L2NvZGU+IHZhbHVlIGluZGljYXRlcyB0aGF0IGZpZWxkIGlzIG5vdCBzZXQuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGlzUG9zaXRpdmUgU2V0IHRvIDxjb2RlPmZhbHNlPC9jb2RlPiB0byBjcmVhdGUgYSBuZWdhdGl2ZSBkdXJhdGlvbi4gV2hlbiB0aGUgbGVuZ3RoCi0gICAgICogICBvZiB0aGUgZHVyYXRpb24gaXMgemVybywgdGhpcyBwYXJhbWV0ZXIgd2lsbCBiZSBpZ25vcmVkLgotICAgICAqIEBwYXJhbSB5ZWFyIFllYXIgb2YgPGNvZGU+RHVyYXRpb248L2NvZGU+LgotICAgICAqIEBwYXJhbSBtb250aCBNb250aCBvZiA8Y29kZT5EdXJhdGlvbjwvY29kZT4uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIE5ldyA8Y29kZT5EdXJhdGlvbjwvY29kZT4gY3JlYXRlZCB1c2luZyB0aGUgc3BlY2lmaWVkIDxjb2RlPnllYXI8L2NvZGU+IGFuZCA8Y29kZT5tb250aDwvY29kZT4uCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBJZiB0aGUgdmFsdWVzIGFyZSBub3QgYSB2YWxpZCByZXByZXNlbnRhdGlvbiBvZiBhCi0gICAgICogPGNvZGU+RHVyYXRpb248L2NvZGU+OiBpZiBhbGwgb2YgdGhlIGZpZWxkcyAoeWVhciwgbW9udGgpIGFyZSBudWxsIG9yCi0gICAgICogaWYgYW55IG9mIHRoZSBmaWVsZHMgaXMgbmVnYXRpdmUuCi0gICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBJZiBpbXBsZW1lbnRhdGlvbiBjYW5ub3Qgc3VwcG9ydCByZXF1ZXN0ZWQgdmFsdWVzLgotICAgICAqLwotICAgIHB1YmxpYyBEdXJhdGlvbiBuZXdEdXJhdGlvblllYXJNb250aCgKLSAgICAgICAgICAgIGZpbmFsIGJvb2xlYW4gaXNQb3NpdGl2ZSwKLSAgICAgICAgICAgIGZpbmFsIEJpZ0ludGVnZXIgeWVhciwKLSAgICAgICAgICAgIGZpbmFsIEJpZ0ludGVnZXIgbW9udGgpIHsKLQotICAgICAgICAgICAgcmV0dXJuIG5ld0R1cmF0aW9uKAotICAgICAgICAgICAgICAgICAgICBpc1Bvc2l0aXZlLAotICAgICAgICAgICAgICAgICAgICB5ZWFyLAotICAgICAgICAgICAgICAgICAgICBtb250aCwKLSAgICAgICAgICAgICAgICAgICAgbnVsbCwgLy8gZGF5cwotICAgICAgICAgICAgICAgICAgICBudWxsLCAvLyBob3VycwotICAgICAgICAgICAgICAgICAgICBudWxsLCAvLyBtaW51dGVzCi0gICAgICAgICAgICAgICAgICAgIG51bGwgIC8vIHNlY29uZHMKLSAgICAgICAgICAgICk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+Q3JlYXRlIGEgPGNvZGU+RHVyYXRpb248L2NvZGU+IG9mIHR5cGUgPGNvZGU+eGR0OnllYXJNb250aER1cmF0aW9uPC9jb2RlPiB1c2luZyB0aGUgc3BlY2lmaWVkCi0gICAgICogPGNvZGU+eWVhcjwvY29kZT4gYW5kIDxjb2RlPm1vbnRoPC9jb2RlPiBhcyBkZWZpbmVkIGluCi0gICAgICogPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGgtZGF0YW1vZGVsI3llYXJNb250aER1cmF0aW9uIj4KLSAgICAgKiAgIFhRdWVyeSAxLjAgYW5kIFhQYXRoIDIuMCBEYXRhIE1vZGVsLCB4ZHQ6eWVhck1vbnRoRHVyYXRpb248L2E+LjwvcD4KLSAgICAgKgotICAgICAqIDxwPkEge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0ZJRUxEX1VOREVGSU5FRH0gdmFsdWUgaW5kaWNhdGVzIHRoYXQgZmllbGQgaXMgbm90IHNldC48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gaXNQb3NpdGl2ZSBTZXQgdG8gPGNvZGU+ZmFsc2U8L2NvZGU+IHRvIGNyZWF0ZSBhIG5lZ2F0aXZlIGR1cmF0aW9uLiBXaGVuIHRoZSBsZW5ndGgKLSAgICAgKiAgIG9mIHRoZSBkdXJhdGlvbiBpcyB6ZXJvLCB0aGlzIHBhcmFtZXRlciB3aWxsIGJlIGlnbm9yZWQuCi0gICAgICogQHBhcmFtIHllYXIgWWVhciBvZiA8Y29kZT5EdXJhdGlvbjwvY29kZT4uCi0gICAgICogQHBhcmFtIG1vbnRoIE1vbnRoIG9mIDxjb2RlPkR1cmF0aW9uPC9jb2RlPi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gTmV3IDxjb2RlPkR1cmF0aW9uPC9jb2RlPiBjcmVhdGVkIHVzaW5nIHRoZSBzcGVjaWZpZWQgPGNvZGU+eWVhcjwvY29kZT4gYW5kIDxjb2RlPm1vbnRoPC9jb2RlPi4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIElmIHRoZSB2YWx1ZXMgYXJlIG5vdCBhIHZhbGlkIHJlcHJlc2VudGF0aW9uIG9mIGEKLSAgICAgKiA8Y29kZT5EdXJhdGlvbjwvY29kZT46IGlmIGFueSBvZiB0aGUgZmllbGRzICh5ZWFyLCBtb250aCkgaXMgbmVnYXRpdmUuCi0gICAgICovCi0gICAgcHVibGljIER1cmF0aW9uIG5ld0R1cmF0aW9uWWVhck1vbnRoKAotICAgICAgICAgICAgZmluYWwgYm9vbGVhbiBpc1Bvc2l0aXZlLAotICAgICAgICAgICAgZmluYWwgaW50IHllYXIsCi0gICAgICAgICAgICBmaW5hbCBpbnQgbW9udGgpIHsKLQotICAgICAgICAgICAgcmV0dXJuIG5ld0R1cmF0aW9uWWVhck1vbnRoKAotICAgICAgICAgICAgICAgICAgICBpc1Bvc2l0aXZlLAotICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLnZhbHVlT2YoKGxvbmcpIHllYXIpLAotICAgICAgICAgICAgICAgICAgICBCaWdJbnRlZ2VyLnZhbHVlT2YoKGxvbmcpIG1vbnRoKSk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5DcmVhdGUgYSBuZXcgaW5zdGFuY2Ugb2YgYW4gPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+LjwvcD4KLSAgICAgKgotICAgICAqIDxwPkFsbCBkYXRlL3RpbWUgZGF0YXR5cGUgZmllbGRzIHNldCB0byB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjRklFTERfVU5ERUZJTkVEfSBvciBudWxsLjwvcD4KLSAgICAgKgotICAgICAqIEByZXR1cm4gTmV3IDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiB3aXRoIGFsbCBkYXRlL3RpbWUgZGF0YXR5cGUgZmllbGRzIHNldCB0bwotICAgICAqICAge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0ZJRUxEX1VOREVGSU5FRH0gb3IgbnVsbC4KLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3QgWE1MR3JlZ29yaWFuQ2FsZW5kYXIgbmV3WE1MR3JlZ29yaWFuQ2FsZW5kYXIoKTsKLQotICAgIC8qKgotICAgICAqIDxwPkNyZWF0ZSBhIG5ldyBYTUxHcmVnb3JpYW5DYWxlbmRhciBieSBwYXJzaW5nIHRoZSBTdHJpbmcgYXMgYSBsZXhpY2FsIHJlcHJlc2VudGF0aW9uLjwvcD4KLSAgICAgKgotICAgICAqIDxwPlBhcnNpbmcgdGhlIGxleGljYWwgc3RyaW5nIHJlcHJlc2VudGF0aW9uIGlzIGRlZmluZWQgaW4KLSAgICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94bWxzY2hlbWEtMi8jZGF0ZVRpbWUtb3JkZXIiPlhNTCBTY2hlbWEgMS4wIFBhcnQgMiwgU2VjdGlvbiAzLjIuWzctMTRdLjEsCi0gICAgICogPGVtPkxleGljYWwgUmVwcmVzZW50YXRpb248L2VtPi48L2E+PC9wPgotICAgICAqCi0gICAgICogPHA+VGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBtYXkgbm90IGhhdmUgYW55IGxlYWRpbmcgYW5kIHRyYWlsaW5nIHdoaXRlc3BhY2VzLjwvcD4KLSAgICAgKgotICAgICAqIDxwPlRoZSBwYXJzaW5nIGlzIGRvbmUgZmllbGQgYnkgZmllbGQgc28gdGhhdAotICAgICAqIHRoZSBmb2xsb3dpbmcgaG9sZHMgZm9yIGFueSBsZXhpY2FsbHkgY29ycmVjdCBTdHJpbmcgeDo8L3A+Ci0gICAgICogPHByZT4KLSAgICAgKiBuZXdYTUxHcmVnb3JpYW5DYWxlbmRhcih4KS50b1hNTEZvcm1hdCgpLmVxdWFscyh4KQotICAgICAqIDwvcHJlPgotICAgICAqIDxwPkV4Y2VwdCBmb3IgdGhlIG5vdGVkIGxleGljYWwvY2Fub25pY2FsIHJlcHJlc2VudGF0aW9uIG1pc21hdGNoZXMKLSAgICAgKiBsaXN0ZWQgaW4gPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8wNS94bWxzY2hlbWEtZXJyYXRhI2UyLTQ1Ij4KLSAgICAgKiBYTUwgU2NoZW1hIDEuMCBlcnJhdGEsIFNlY3Rpb24gMy4yLjcuMjwvYT4uPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGxleGljYWxSZXByZXNlbnRhdGlvbiBMZXhpY2FsIHJlcHJlc2VudGF0aW9uIG9mIG9uZSB0aGUgZWlnaHQgWE1MIFNjaGVtYSBkYXRlL3RpbWUgZGF0YXR5cGVzLgotICAgICAqCi0gICAgICogQHJldHVybiA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gY3JlYXRlZCBmcm9tIHRoZSA8Y29kZT5sZXhpY2FsUmVwcmVzZW50YXRpb248L2NvZGU+LgotICAgICAqCi0gICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gSWYgdGhlIDxjb2RlPmxleGljYWxSZXByZXNlbnRhdGlvbjwvY29kZT4gaXMgbm90IGEgdmFsaWQgPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+LgotICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gSWYgPGNvZGU+bGV4aWNhbFJlcHJlc2VudGF0aW9uPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3QgWE1MR3JlZ29yaWFuQ2FsZW5kYXIgbmV3WE1MR3JlZ29yaWFuQ2FsZW5kYXIoZmluYWwgU3RyaW5nIGxleGljYWxSZXByZXNlbnRhdGlvbik7Ci0KLSAgICAvKioKLSAgICAgKiA8cD5DcmVhdGUgYW4gPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IGZyb20gYSB7QGxpbmsgR3JlZ29yaWFuQ2FsZW5kYXJ9LjwvcD4KLSAgICAgKgotICAgICAqIDx0YWJsZSBib3JkZXI9IjIiIHJ1bGVzPSJhbGwiIGNlbGxwYWRkaW5nPSIyIj4KLSAgICAgKiAgIDx0aGVhZD4KLSAgICAgKiAgICAgPHRyPgotICAgICAqICAgICAgIDx0aCBhbGlnbj0iY2VudGVyIiBjb2xzcGFuPSIyIj4KLSAgICAgKiAgICAgICAgICBGaWVsZCBieSBGaWVsZCBDb252ZXJzaW9uIGZyb20KLSAgICAgKiAgICAgICAgICB7QGxpbmsgR3JlZ29yaWFuQ2FsZW5kYXJ9IHRvIGFuIHtAbGluayBYTUxHcmVnb3JpYW5DYWxlbmRhcn0KLSAgICAgKiAgICAgICA8L3RoPgotICAgICAqICAgICA8L3RyPgotICAgICAqICAgICA8dHI+Ci0gICAgICogICAgICAgIDx0aD48Y29kZT5qYXZhLnV0aWwuR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IGZpZWxkPC90aD4KLSAgICAgKiAgICAgICAgPHRoPjxjb2RlPmphdmF4LnhtbC5kYXRhdHlwZS5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gZmllbGQ8L3RoPgotICAgICAqICAgICA8L3RyPgotICAgICAqICAgPC90aGVhZD4KLSAgICAgKiAgIDx0Ym9keT4KLSAgICAgKiAgICAgPHRyPgotICAgICAqICAgICAgIDx0ZD48Y29kZT5FUkEgPT0gR3JlZ29yaWFuQ2FsZW5kYXIuQkMgPyAtWUVBUiA6IFlFQVI8L2NvZGU+PC90ZD4KLSAgICAgKiAgICAgICA8dGQ+e0BsaW5rIFhNTEdyZWdvcmlhbkNhbGVuZGFyI3NldFllYXIoaW50IHllYXIpfTwvdGQ+Ci0gICAgICogICAgIDwvdHI+Ci0gICAgICogICAgIDx0cj4KLSAgICAgKiAgICAgICA8dGQ+PGNvZGU+TU9OVEggKyAxPC9jb2RlPjwvdGQ+Ci0gICAgICogICAgICAgPHRkPntAbGluayBYTUxHcmVnb3JpYW5DYWxlbmRhciNzZXRNb250aChpbnQgbW9udGgpfTwvdGQ+Ci0gICAgICogICAgIDwvdHI+Ci0gICAgICogICAgIDx0cj4KLSAgICAgKiAgICAgICA8dGQ+PGNvZGU+REFZX09GX01PTlRIPC9jb2RlPjwvdGQ+Ci0gICAgICogICAgICAgPHRkPntAbGluayBYTUxHcmVnb3JpYW5DYWxlbmRhciNzZXREYXkoaW50IGRheSl9PC90ZD4KLSAgICAgKiAgICAgPC90cj4KLSAgICAgKiAgICAgPHRyPgotICAgICAqICAgICAgIDx0ZD48Y29kZT5IT1VSX09GX0RBWSwgTUlOVVRFLCBTRUNPTkQsIE1JTExJU0VDT05EPC9jb2RlPjwvdGQ+Ci0gICAgICogICAgICAgPHRkPntAbGluayBYTUxHcmVnb3JpYW5DYWxlbmRhciNzZXRUaW1lKGludCBob3VyLCBpbnQgbWludXRlLCBpbnQgc2Vjb25kLCBCaWdEZWNpbWFsIGZyYWN0aW9uYWwpfTwvdGQ+Ci0gICAgICogICAgIDwvdHI+Ci0gICAgICogICAgIDx0cj4KLSAgICAgKiAgICAgICA8dGQ+Ci0gICAgICogICAgICAgICA8Y29kZT4oWk9ORV9PRkZTRVQgKyBEU1RfT0ZGU0VUKSAvICg2MCoxMDAwKTwvY29kZT48YnIvPgotICAgICAqICAgICAgICAgPGVtPihpbiBtaW51dGVzKTwvZW0+Ci0gICAgICogICAgICAgPC90ZD4KLSAgICAgKiAgICAgICA8dGQ+e0BsaW5rIFhNTEdyZWdvcmlhbkNhbGVuZGFyI3NldFRpbWV6b25lKGludCBvZmZzZXQpfTxzdXA+PGVtPio8L2VtPjwvc3VwPgotICAgICAqICAgICAgIDwvdGQ+Ci0gICAgICogICAgIDwvdHI+Ci0gICAgICogICA8L3Rib2R5PgotICAgICAqIDwvdGFibGU+Ci0gICAgICogPHA+PGVtPio8L2VtPmNvbnZlcnNpb24gbG9zcyBvZiBpbmZvcm1hdGlvbi4gSXQgaXMgbm90IHBvc3NpYmxlIHRvIHJlcHJlc2VudAotICAgICAqIGEgPGNvZGU+amF2YS51dGlsLkdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiBkYXlsaWdodCBzYXZpbmdzIHRpbWV6b25lIGlkIGluIHRoZQotICAgICAqIFhNTCBTY2hlbWEgMS4wIGRhdGUvdGltZSBkYXRhdHlwZSByZXByZXNlbnRhdGlvbi48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5UbyBjb21wdXRlIHRoZSByZXR1cm4gdmFsdWUncyA8Y29kZT5UaW1lWm9uZTwvY29kZT4gZmllbGQsCi0gICAgICogPHVsPgotICAgICAqIDxsaT53aGVuIDxjb2RlPnRoaXMuZ2V0VGltZXpvbmUoKSAhPSBGSUVMRF9VTkRFRklORUQ8L2NvZGU+LAotICAgICAqIGNyZWF0ZSBhIDxjb2RlPmphdmEudXRpbC5UaW1lWm9uZTwvY29kZT4gd2l0aCBhIGN1c3RvbSB0aW1lem9uZSBpZAotICAgICAqIHVzaW5nIHRoZSA8Y29kZT50aGlzLmdldFRpbWV6b25lKCk8L2NvZGU+LjwvbGk+Ci0gICAgICogPGxpPmVsc2UgdXNlIHRoZSA8Y29kZT5HcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gZGVmYXVsdCB0aW1lem9uZSB2YWx1ZQotICAgICAqIGZvciB0aGUgaG9zdCBpcyBkZWZpbmVkIGFzIHNwZWNpZmllZCBieQotICAgICAqIDxjb2RlPmphdmEudXRpbC5UaW1lWm9uZS5nZXREZWZhdWx0KCk8L2NvZGU+LjwvbGk+PC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGNhbCA8Y29kZT5qYXZhLnV0aWwuR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IHVzZWQgdG8gY3JlYXRlIDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPgotICAgICAqCi0gICAgICogQHJldHVybiA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gY3JlYXRlZCBmcm9tIDxjb2RlPmphdmEudXRpbC5HcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gSWYgPGNvZGU+Y2FsPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3QgWE1MR3JlZ29yaWFuQ2FsZW5kYXIgbmV3WE1MR3JlZ29yaWFuQ2FsZW5kYXIoZmluYWwgR3JlZ29yaWFuQ2FsZW5kYXIgY2FsKTsKLQotICAgIC8qKgotICAgICAqIDxwPkNvbnN0cnVjdG9yIGFsbG93aW5nIGZvciBjb21wbGV0ZSB2YWx1ZSBzcGFjZXMgYWxsb3dlZCBieQotICAgICAqIFczQyBYTUwgU2NoZW1hIDEuMCByZWNvbW1lbmRhdGlvbiBmb3IgeHNkOmRhdGVUaW1lIGFuZCByZWxhdGVkCi0gICAgICogYnVpbHRpbiBkYXRhdHlwZXMuIE5vdGUgdGhhdCA8Y29kZT55ZWFyPC9jb2RlPiBwYXJhbWV0ZXIgc3VwcG9ydHMKLSAgICAgKiBhcmJpdHJhcmlseSBsYXJnZSBudW1iZXJzIGFuZCBmcmFjdGlvbmFsU2Vjb25kIGhhcyBpbmZpbml0ZQotICAgICAqIHByZWNpc2lvbi48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5BIDxjb2RlPm51bGw8L2NvZGU+IHZhbHVlIGluZGljYXRlcyB0aGF0IGZpZWxkIGlzIG5vdCBzZXQuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIHllYXIgb2YgPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IHRvIGJlIGNyZWF0ZWQuCi0gICAgICogQHBhcmFtIG1vbnRoIG9mIDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiB0byBiZSBjcmVhdGVkLgotICAgICAqIEBwYXJhbSBkYXkgb2YgPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IHRvIGJlIGNyZWF0ZWQuCi0gICAgICogQHBhcmFtIGhvdXIgb2YgPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IHRvIGJlIGNyZWF0ZWQuCi0gICAgICogQHBhcmFtIG1pbnV0ZSBvZiA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gdG8gYmUgY3JlYXRlZC4KLSAgICAgKiBAcGFyYW0gc2Vjb25kIG9mIDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiB0byBiZSBjcmVhdGVkLgotICAgICAqIEBwYXJhbSBmcmFjdGlvbmFsU2Vjb25kIG9mIDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiB0byBiZSBjcmVhdGVkLgotICAgICAqIEBwYXJhbSB0aW1lem9uZSBvZiA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gdG8gYmUgY3JlYXRlZC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IGNyZWF0ZWQgZnJvbSBzcGVjaWZpZWQgdmFsdWVzLgotICAgICAqCi0gICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gSWYgYW55IGluZGl2aWR1YWwgcGFyYW1ldGVyJ3MgdmFsdWUgaXMgb3V0c2lkZSB0aGUgbWF4aW11bSB2YWx1ZSBjb25zdHJhaW50IGZvciB0aGUgZmllbGQKLSAgICAgKiAgIGFzIGRldGVybWluZWQgYnkgdGhlIERhdGUvVGltZSBEYXRhIE1hcHBpbmcgdGFibGUgaW4ge0BsaW5rIFhNTEdyZWdvcmlhbkNhbGVuZGFyfQotICAgICAqICAgb3IgaWYgdGhlIGNvbXBvc2l0ZSB2YWx1ZXMgY29uc3RpdHV0ZSBhbiBpbnZhbGlkIDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiBpbnN0YW5jZQotICAgICAqICAgYXMgZGV0ZXJtaW5lZCBieSB7QGxpbmsgWE1MR3JlZ29yaWFuQ2FsZW5kYXIjaXNWYWxpZCgpfS4KLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3QgWE1MR3JlZ29yaWFuQ2FsZW5kYXIgbmV3WE1MR3JlZ29yaWFuQ2FsZW5kYXIoCi0gICAgICAgICAgICBmaW5hbCBCaWdJbnRlZ2VyIHllYXIsCi0gICAgICAgICAgICBmaW5hbCBpbnQgbW9udGgsCi0gICAgICAgICAgICBmaW5hbCBpbnQgZGF5LAotICAgICAgICAgICAgZmluYWwgaW50IGhvdXIsCi0gICAgICAgICAgICBmaW5hbCBpbnQgbWludXRlLAotICAgICAgICAgICAgZmluYWwgaW50IHNlY29uZCwKLSAgICAgICAgICAgIGZpbmFsIEJpZ0RlY2ltYWwgZnJhY3Rpb25hbFNlY29uZCwKLSAgICAgICAgICAgIGZpbmFsIGludCB0aW1lem9uZSk7Ci0KLSAgICAvKioKLSAgICAgKiA8cD5Db25zdHJ1Y3RvciBvZiB2YWx1ZSBzcGFjZXMgdGhhdCBhCi0gICAgICogPGNvZGU+amF2YS51dGlsLkdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiBpbnN0YW5jZSB3b3VsZCBuZWVkIHRvIGNvbnZlcnQgdG8gYW4KLSAgICAgKiA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gaW5zdGFuY2UuPC9wPgotICAgICAqCi0gICAgICogPHA+PGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXIgZW9uPC9jb2RlPiBhbmQKLSAgICAgKiA8Y29kZT5mcmFjdGlvbmFsU2Vjb25kPC9jb2RlPiBhcmUgc2V0IHRvIDxjb2RlPm51bGw8L2NvZGU+PC9wPgotICAgICAqCi0gICAgICogPHA+QSB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjRklFTERfVU5ERUZJTkVEfSB2YWx1ZSBpbmRpY2F0ZXMgdGhhdCBmaWVsZCBpcyBub3Qgc2V0LjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSB5ZWFyIG9mIDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiB0byBiZSBjcmVhdGVkLgotICAgICAqIEBwYXJhbSBtb250aCBvZiA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gdG8gYmUgY3JlYXRlZC4KLSAgICAgKiBAcGFyYW0gZGF5IG9mIDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiB0byBiZSBjcmVhdGVkLgotICAgICAqIEBwYXJhbSBob3VyIG9mIDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiB0byBiZSBjcmVhdGVkLgotICAgICAqIEBwYXJhbSBtaW51dGUgb2YgPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IHRvIGJlIGNyZWF0ZWQuCi0gICAgICogQHBhcmFtIHNlY29uZCBvZiA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gdG8gYmUgY3JlYXRlZC4KLSAgICAgKiBAcGFyYW0gbWlsbGlzZWNvbmQgb2YgPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IHRvIGJlIGNyZWF0ZWQuCi0gICAgICogQHBhcmFtIHRpbWV6b25lIG9mIDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiB0byBiZSBjcmVhdGVkLgotICAgICAqCi0gICAgICogQHJldHVybiA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gY3JlYXRlZCBmcm9tIHNwZWNpZmllZCB2YWx1ZXMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBJZiBhbnkgaW5kaXZpZHVhbCBwYXJhbWV0ZXIncyB2YWx1ZSBpcyBvdXRzaWRlIHRoZSBtYXhpbXVtIHZhbHVlIGNvbnN0cmFpbnQgZm9yIHRoZSBmaWVsZAotICAgICAqICAgYXMgZGV0ZXJtaW5lZCBieSB0aGUgRGF0ZS9UaW1lIERhdGEgTWFwcGluZyB0YWJsZSBpbiB7QGxpbmsgWE1MR3JlZ29yaWFuQ2FsZW5kYXJ9Ci0gICAgICogICBvciBpZiB0aGUgY29tcG9zaXRlIHZhbHVlcyBjb25zdGl0dXRlIGFuIGludmFsaWQgPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IGluc3RhbmNlCi0gICAgICogICBhcyBkZXRlcm1pbmVkIGJ5IHtAbGluayBYTUxHcmVnb3JpYW5DYWxlbmRhciNpc1ZhbGlkKCl9LgotICAgICAqLwotICAgIHB1YmxpYyBYTUxHcmVnb3JpYW5DYWxlbmRhciBuZXdYTUxHcmVnb3JpYW5DYWxlbmRhcigKLSAgICAgICAgICAgIGZpbmFsIGludCB5ZWFyLAotICAgICAgICAgICAgZmluYWwgaW50IG1vbnRoLAotICAgICAgICAgICAgZmluYWwgaW50IGRheSwKLSAgICAgICAgICAgIGZpbmFsIGludCBob3VyLAotICAgICAgICAgICAgZmluYWwgaW50IG1pbnV0ZSwKLSAgICAgICAgICAgIGZpbmFsIGludCBzZWNvbmQsCi0gICAgICAgICAgICBmaW5hbCBpbnQgbWlsbGlzZWNvbmQsCi0gICAgICAgICAgICBmaW5hbCBpbnQgdGltZXpvbmUpIHsKLQotICAgICAgICAgICAgLy8geWVhciBtYXkgYmUgdW5kZWZpbmVkCi0gICAgICAgICAgICBCaWdJbnRlZ2VyIHJlYWxZZWFyID0gKHllYXIgIT0gRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVEKSA/IEJpZ0ludGVnZXIudmFsdWVPZigobG9uZykgeWVhcikgOiBudWxsOwotCi0gICAgICAgICAgICAvLyBtaWxsaXNlY29uZCBtYXkgYmUgdW5kZWZpbmVkCi0gICAgICAgICAgICAvLyBtaWxsaXNlY29uZCBtdXN0IGJlID49IDAgbWlsbGlzZWNvbmQgPD0gMTAwMAotICAgICAgICAgICAgQmlnRGVjaW1hbCByZWFsTWlsbGlzZWNvbmQgPSBudWxsOyAvLyB1bmRlZmluZWQgdmFsdWUKLSAgICAgICAgICAgIGlmIChtaWxsaXNlY29uZCAhPSBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQpIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKG1pbGxpc2Vjb25kIDwgMCB8fCBtaWxsaXNlY29uZCA+IDEwMDApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJqYXZheC54bWwuZGF0YXR5cGUuRGF0YXR5cGVGYWN0b3J5I25ld1hNTEdyZWdvcmlhbkNhbGVuZGFyKCIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICJpbnQgeWVhciwgaW50IG1vbnRoLCBpbnQgZGF5LCBpbnQgaG91ciwgaW50IG1pbnV0ZSwgaW50IHNlY29uZCwgaW50IG1pbGxpc2Vjb25kLCBpbnQgdGltZXpvbmUpIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIndpdGggaW52YWxpZCBtaWxsaXNlY29uZDogIiArIG1pbGxpc2Vjb25kCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTsKLSAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgIHJlYWxNaWxsaXNlY29uZCA9IEJpZ0RlY2ltYWwudmFsdWVPZigobG9uZykgbWlsbGlzZWNvbmQpLm1vdmVQb2ludExlZnQoMyk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIHJldHVybiBuZXdYTUxHcmVnb3JpYW5DYWxlbmRhcigKLSAgICAgICAgICAgICAgICAgICAgcmVhbFllYXIsCi0gICAgICAgICAgICAgICAgICAgIG1vbnRoLAotICAgICAgICAgICAgICAgICAgICBkYXksCi0gICAgICAgICAgICAgICAgICAgIGhvdXIsCi0gICAgICAgICAgICAgICAgICAgIG1pbnV0ZSwKLSAgICAgICAgICAgICAgICAgICAgc2Vjb25kLAotICAgICAgICAgICAgICAgICAgICByZWFsTWlsbGlzZWNvbmQsCi0gICAgICAgICAgICAgICAgICAgIHRpbWV6b25lCi0gICAgICAgICAgICApOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPkNyZWF0ZSBhIEphdmEgcmVwcmVzZW50YXRpb24gb2YgWE1MIFNjaGVtYSBidWlsdGluIGRhdGF0eXBlIDxjb2RlPmRhdGU8L2NvZGU+IG9yIDxjb2RlPmcqPC9jb2RlPi48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5Gb3IgZXhhbXBsZSwgYW4gaW5zdGFuY2Ugb2YgPGNvZGU+Z1llYXI8L2NvZGU+IGNhbiBiZSBjcmVhdGVkIGludm9raW5nIHRoaXMgZmFjdG9yeQotICAgICAqIHdpdGggPGNvZGU+bW9udGg8L2NvZGU+IGFuZCA8Y29kZT5kYXk8L2NvZGU+IHBhcmFtZXRlcnMgc2V0IHRvCi0gICAgICoge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0ZJRUxEX1VOREVGSU5FRH0uPC9wPgotICAgICAqCi0gICAgICogPHA+QSB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjRklFTERfVU5ERUZJTkVEfSB2YWx1ZSBpbmRpY2F0ZXMgdGhhdCBmaWVsZCBpcyBub3Qgc2V0LjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSB5ZWFyIG9mIDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiB0byBiZSBjcmVhdGVkLgotICAgICAqIEBwYXJhbSBtb250aCBvZiA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gdG8gYmUgY3JlYXRlZC4KLSAgICAgKiBAcGFyYW0gZGF5IG9mIDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiB0byBiZSBjcmVhdGVkLgotICAgICAqIEBwYXJhbSB0aW1lem9uZSBvZmZzZXQgaW4gbWludXRlcy4ge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0ZJRUxEX1VOREVGSU5FRH0gaW5kaWNhdGVzIG9wdGlvbmFsIGZpZWxkIGlzIG5vdCBzZXQuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiBjcmVhdGVkIGZyb20gcGFyYW1ldGVyIHZhbHVlcy4KLSAgICAgKgotICAgICAqIEBzZWUgRGF0YXR5cGVDb25zdGFudHMjRklFTERfVU5ERUZJTkVECi0gICAgICoKLSAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBJZiBhbnkgaW5kaXZpZHVhbCBwYXJhbWV0ZXIncyB2YWx1ZSBpcyBvdXRzaWRlIHRoZSBtYXhpbXVtIHZhbHVlIGNvbnN0cmFpbnQgZm9yIHRoZSBmaWVsZAotICAgICAqICAgYXMgZGV0ZXJtaW5lZCBieSB0aGUgRGF0ZS9UaW1lIERhdGEgTWFwcGluZyB0YWJsZSBpbiB7QGxpbmsgWE1MR3JlZ29yaWFuQ2FsZW5kYXJ9Ci0gICAgICogICBvciBpZiB0aGUgY29tcG9zaXRlIHZhbHVlcyBjb25zdGl0dXRlIGFuIGludmFsaWQgPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IGluc3RhbmNlCi0gICAgICogICBhcyBkZXRlcm1pbmVkIGJ5IHtAbGluayBYTUxHcmVnb3JpYW5DYWxlbmRhciNpc1ZhbGlkKCl9LgotICAgICAqLwotICAgIHB1YmxpYyBYTUxHcmVnb3JpYW5DYWxlbmRhciBuZXdYTUxHcmVnb3JpYW5DYWxlbmRhckRhdGUoCi0gICAgICAgICAgICBmaW5hbCBpbnQgeWVhciwKLSAgICAgICAgICAgIGZpbmFsIGludCBtb250aCwKLSAgICAgICAgICAgIGZpbmFsIGludCBkYXksCi0gICAgICAgICAgICBmaW5hbCBpbnQgdGltZXpvbmUpIHsKLQotICAgICAgICAgICAgcmV0dXJuIG5ld1hNTEdyZWdvcmlhbkNhbGVuZGFyKAotICAgICAgICAgICAgICAgICAgICB5ZWFyLAotICAgICAgICAgICAgICAgICAgICBtb250aCwKLSAgICAgICAgICAgICAgICAgICAgZGF5LAotICAgICAgICAgICAgICAgICAgICBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQsIC8vIGhvdXIKLSAgICAgICAgICAgICAgICAgICAgRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVELCAvLyBtaW51dGUKLSAgICAgICAgICAgICAgICAgICAgRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVELCAvLyBzZWNvbmQKLSAgICAgICAgICAgICAgICAgICAgRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVELCAvLyBtaWxsaXNlY29uZAotICAgICAgICAgICAgICAgICAgICB0aW1lem9uZSk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5DcmVhdGUgYSBKYXZhIGluc3RhbmNlIG9mIFhNTCBTY2hlbWEgYnVpbHRpbiBkYXRhdHlwZSA8Y29kZT50aW1lPC9jb2RlPi48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5BIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNGSUVMRF9VTkRFRklORUR9IHZhbHVlIGluZGljYXRlcyB0aGF0IGZpZWxkIGlzIG5vdCBzZXQuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGhvdXJzIG51bWJlciBvZiBob3VycwotICAgICAqIEBwYXJhbSBtaW51dGVzIG51bWJlciBvZiBtaW51dGVzCi0gICAgICogQHBhcmFtIHNlY29uZHMgbnVtYmVyIG9mIHNlY29uZHMKLSAgICAgKiBAcGFyYW0gdGltZXpvbmUgb2Zmc2V0IGluIG1pbnV0ZXMuIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNGSUVMRF9VTkRFRklORUR9IGluZGljYXRlcyBvcHRpb25hbCBmaWVsZCBpcyBub3Qgc2V0LgotICAgICAqCi0gICAgICogQHJldHVybiA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gY3JlYXRlZCBmcm9tIHBhcmFtZXRlciB2YWx1ZXMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBJZiBhbnkgaW5kaXZpZHVhbCBwYXJhbWV0ZXIncyB2YWx1ZSBpcyBvdXRzaWRlIHRoZSBtYXhpbXVtIHZhbHVlIGNvbnN0cmFpbnQgZm9yIHRoZSBmaWVsZAotICAgICAqICAgYXMgZGV0ZXJtaW5lZCBieSB0aGUgRGF0ZS9UaW1lIERhdGEgTWFwcGluZyB0YWJsZSBpbiB7QGxpbmsgWE1MR3JlZ29yaWFuQ2FsZW5kYXJ9Ci0gICAgICogICBvciBpZiB0aGUgY29tcG9zaXRlIHZhbHVlcyBjb25zdGl0dXRlIGFuIGludmFsaWQgPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IGluc3RhbmNlCi0gICAgICogICBhcyBkZXRlcm1pbmVkIGJ5IHtAbGluayBYTUxHcmVnb3JpYW5DYWxlbmRhciNpc1ZhbGlkKCl9LgotICAgICAqCi0gICAgICogQHNlZSBEYXRhdHlwZUNvbnN0YW50cyNGSUVMRF9VTkRFRklORUQKLSAgICAgKi8KLSAgICBwdWJsaWMgWE1MR3JlZ29yaWFuQ2FsZW5kYXIgbmV3WE1MR3JlZ29yaWFuQ2FsZW5kYXJUaW1lKAotICAgICAgICAgICAgZmluYWwgaW50IGhvdXJzLAotICAgICAgICAgICAgZmluYWwgaW50IG1pbnV0ZXMsCi0gICAgICAgICAgICBmaW5hbCBpbnQgc2Vjb25kcywKLSAgICAgICAgICAgIGZpbmFsIGludCB0aW1lem9uZSkgewotCi0gICAgICAgICAgICByZXR1cm4gbmV3WE1MR3JlZ29yaWFuQ2FsZW5kYXIoCi0gICAgICAgICAgICAgICAgICAgIERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCwgLy8gWWVhcgotICAgICAgICAgICAgICAgICAgICBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQsIC8vIE1vbnRoCi0gICAgICAgICAgICAgICAgICAgIERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCwgLy8gRGF5Ci0gICAgICAgICAgICAgICAgICAgIGhvdXJzLAotICAgICAgICAgICAgICAgICAgICBtaW51dGVzLAotICAgICAgICAgICAgICAgICAgICBzZWNvbmRzLAotICAgICAgICAgICAgICAgICAgICBEYXRhdHlwZUNvbnN0YW50cy5GSUVMRF9VTkRFRklORUQsIC8vTWlsbGlzZWNvbmQKLSAgICAgICAgICAgICAgICAgICAgdGltZXpvbmUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPkNyZWF0ZSBhIEphdmEgaW5zdGFuY2Ugb2YgWE1MIFNjaGVtYSBidWlsdGluIGRhdGF0eXBlIHRpbWUuPC9wPgotICAgICAqCi0gICAgICogPHA+QSA8Y29kZT5udWxsPC9jb2RlPiB2YWx1ZSBpbmRpY2F0ZXMgdGhhdCBmaWVsZCBpcyBub3Qgc2V0LjwvcD4KLSAgICAgKiA8cD5BIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNGSUVMRF9VTkRFRklORUR9IHZhbHVlIGluZGljYXRlcyB0aGF0IGZpZWxkIGlzIG5vdCBzZXQuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGhvdXJzIG51bWJlciBvZiBob3VycwotICAgICAqIEBwYXJhbSBtaW51dGVzIG51bWJlciBvZiBtaW51dGVzCi0gICAgICogQHBhcmFtIHNlY29uZHMgbnVtYmVyIG9mIHNlY29uZHMKLSAgICAgKiBAcGFyYW0gZnJhY3Rpb25hbFNlY29uZCB2YWx1ZSBvZiA8Y29kZT5udWxsPC9jb2RlPiBpbmRpY2F0ZXMgdGhhdCB0aGlzIG9wdGlvbmFsIGZpZWxkIGlzIG5vdCBzZXQuCi0gICAgICogQHBhcmFtIHRpbWV6b25lIG9mZnNldCBpbiBtaW51dGVzLiB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjRklFTERfVU5ERUZJTkVEfSBpbmRpY2F0ZXMgb3B0aW9uYWwgZmllbGQgaXMgbm90IHNldC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IGNyZWF0ZWQgZnJvbSBwYXJhbWV0ZXIgdmFsdWVzLgotICAgICAqCi0gICAgICogQHNlZSBEYXRhdHlwZUNvbnN0YW50cyNGSUVMRF9VTkRFRklORUQKLSAgICAgKgotICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIElmIGFueSBpbmRpdmlkdWFsIHBhcmFtZXRlcidzIHZhbHVlIGlzIG91dHNpZGUgdGhlIG1heGltdW0gdmFsdWUgY29uc3RyYWludCBmb3IgdGhlIGZpZWxkCi0gICAgICogICBhcyBkZXRlcm1pbmVkIGJ5IHRoZSBEYXRlL1RpbWUgRGF0YSBNYXBwaW5nIHRhYmxlIGluIHtAbGluayBYTUxHcmVnb3JpYW5DYWxlbmRhcn0KLSAgICAgKiAgIG9yIGlmIHRoZSBjb21wb3NpdGUgdmFsdWVzIGNvbnN0aXR1dGUgYW4gaW52YWxpZCA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gaW5zdGFuY2UKLSAgICAgKiAgIGFzIGRldGVybWluZWQgYnkge0BsaW5rIFhNTEdyZWdvcmlhbkNhbGVuZGFyI2lzVmFsaWQoKX0uCi0gICAgICovCi0gICAgcHVibGljIFhNTEdyZWdvcmlhbkNhbGVuZGFyIG5ld1hNTEdyZWdvcmlhbkNhbGVuZGFyVGltZSgKLSAgICAgICAgICAgIGZpbmFsIGludCBob3VycywKLSAgICAgICAgICAgIGZpbmFsIGludCBtaW51dGVzLAotICAgICAgICAgICAgZmluYWwgaW50IHNlY29uZHMsCi0gICAgICAgICAgICBmaW5hbCBCaWdEZWNpbWFsIGZyYWN0aW9uYWxTZWNvbmQsCi0gICAgICAgICAgICBmaW5hbCBpbnQgdGltZXpvbmUpIHsKLQotICAgICAgICAgICAgcmV0dXJuIG5ld1hNTEdyZWdvcmlhbkNhbGVuZGFyKAotICAgICAgICAgICAgICAgICAgICBudWxsLCAvLyB5ZWFyCi0gICAgICAgICAgICAgICAgICAgIERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCwgLy8gbW9udGgKLSAgICAgICAgICAgICAgICAgICAgRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVELCAvLyBkYXkKLSAgICAgICAgICAgICAgICAgICAgaG91cnMsCi0gICAgICAgICAgICAgICAgICAgIG1pbnV0ZXMsCi0gICAgICAgICAgICAgICAgICAgIHNlY29uZHMsCi0gICAgICAgICAgICAgICAgICAgIGZyYWN0aW9uYWxTZWNvbmQsCi0gICAgICAgICAgICAgICAgICAgIHRpbWV6b25lKTsKLSAgICAgICAgICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPkNyZWF0ZSBhIEphdmEgaW5zdGFuY2Ugb2YgWE1MIFNjaGVtYSBidWlsdGluIGRhdGF0eXBlIHRpbWUuPC9wPgotICAgICAqCi0gICAgICogPHA+QSB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjRklFTERfVU5ERUZJTkVEfSB2YWx1ZSBpbmRpY2F0ZXMgdGhhdCBmaWVsZCBpcyBub3Qgc2V0LjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBob3VycyBudW1iZXIgb2YgaG91cnMKLSAgICAgKiBAcGFyYW0gbWludXRlcyBudW1iZXIgb2YgbWludXRlcwotICAgICAqIEBwYXJhbSBzZWNvbmRzIG51bWJlciBvZiBzZWNvbmRzCi0gICAgICogQHBhcmFtIG1pbGxpc2Vjb25kcyBudW1iZXIgb2YgbWlsbGlzZWNvbmRzCi0gICAgICogQHBhcmFtIHRpbWV6b25lIG9mZnNldCBpbiBtaW51dGVzLiB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjRklFTERfVU5ERUZJTkVEfSBpbmRpY2F0ZXMgb3B0aW9uYWwgZmllbGQgaXMgbm90IHNldC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IGNyZWF0ZWQgZnJvbSBwYXJhbWV0ZXIgdmFsdWVzLgotICAgICAqCi0gICAgICogQHNlZSBEYXRhdHlwZUNvbnN0YW50cyNGSUVMRF9VTkRFRklORUQKLSAgICAgKgotICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIElmIGFueSBpbmRpdmlkdWFsIHBhcmFtZXRlcidzIHZhbHVlIGlzIG91dHNpZGUgdGhlIG1heGltdW0gdmFsdWUgY29uc3RyYWludCBmb3IgdGhlIGZpZWxkCi0gICAgICogICBhcyBkZXRlcm1pbmVkIGJ5IHRoZSBEYXRlL1RpbWUgRGF0YSBNYXBwaW5nIHRhYmxlIGluIHtAbGluayBYTUxHcmVnb3JpYW5DYWxlbmRhcn0KLSAgICAgKiAgIG9yIGlmIHRoZSBjb21wb3NpdGUgdmFsdWVzIGNvbnN0aXR1dGUgYW4gaW52YWxpZCA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gaW5zdGFuY2UKLSAgICAgKiAgIGFzIGRldGVybWluZWQgYnkge0BsaW5rIFhNTEdyZWdvcmlhbkNhbGVuZGFyI2lzVmFsaWQoKX0uCi0gICAgICovCi0gICAgcHVibGljIFhNTEdyZWdvcmlhbkNhbGVuZGFyIG5ld1hNTEdyZWdvcmlhbkNhbGVuZGFyVGltZSgKLSAgICAgICAgICAgIGZpbmFsIGludCBob3VycywKLSAgICAgICAgICAgIGZpbmFsIGludCBtaW51dGVzLAotICAgICAgICAgICAgZmluYWwgaW50IHNlY29uZHMsCi0gICAgICAgICAgICBmaW5hbCBpbnQgbWlsbGlzZWNvbmRzLAotICAgICAgICAgICAgZmluYWwgaW50IHRpbWV6b25lKSB7Ci0KLSAgICAgICAgICAgIC8vIG1pbGxpc2Vjb25kIG1heSBiZSB1bmRlZmluZWQKLSAgICAgICAgICAgIC8vIG1pbGxpc2Vjb25kIG11c3QgYmUgPj0gMCBtaWxsaXNlY29uZCA8PSAxMDAwCi0gICAgICAgICAgICBCaWdEZWNpbWFsIHJlYWxNaWxsaXNlY29uZHMgPSBudWxsOyAvLyB1bmRlZmluZWQgdmFsdWUKLSAgICAgICAgICAgIGlmIChtaWxsaXNlY29uZHMgIT0gRGF0YXR5cGVDb25zdGFudHMuRklFTERfVU5ERUZJTkVEKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChtaWxsaXNlY29uZHMgPCAwIHx8IG1pbGxpc2Vjb25kcyA+IDEwMDApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJqYXZheC54bWwuZGF0YXR5cGUuRGF0YXR5cGVGYWN0b3J5I25ld1hNTEdyZWdvcmlhbkNhbGVuZGFyVGltZSgiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiaW50IGhvdXJzLCBpbnQgbWludXRlcywgaW50IHNlY29uZHMsIGludCBtaWxsaXNlY29uZHMsIGludCB0aW1lem9uZSkiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAid2l0aCBpbnZhbGlkIG1pbGxpc2Vjb25kczogIiArIG1pbGxpc2Vjb25kcwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICByZWFsTWlsbGlzZWNvbmRzID0gQmlnRGVjaW1hbC52YWx1ZU9mKChsb25nKSBtaWxsaXNlY29uZHMpLm1vdmVQb2ludExlZnQoMyk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIHJldHVybiBuZXdYTUxHcmVnb3JpYW5DYWxlbmRhclRpbWUoCi0gICAgICAgICAgICAgICAgICAgIGhvdXJzLAotICAgICAgICAgICAgICAgICAgICBtaW51dGVzLAotICAgICAgICAgICAgICAgICAgICBzZWNvbmRzLAotICAgICAgICAgICAgICAgICAgICByZWFsTWlsbGlzZWNvbmRzLAotICAgICAgICAgICAgICAgICAgICB0aW1lem9uZQotICAgICAgICAgICAgKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvamF2YXgveG1sL2RhdGF0eXBlL0R1cmF0aW9uLmphdmEgYi9zcmMvamF2YXgveG1sL2RhdGF0eXBlL0R1cmF0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDM1MGY0YWYuLjAwMDAwMDAKLS0tIGEvc3JjL2phdmF4L3htbC9kYXRhdHlwZS9EdXJhdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTg4ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDMsIDIwMDYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLXBhY2thZ2UgamF2YXgueG1sLmRhdGF0eXBlOwotCi1pbXBvcnQgamF2YS5tYXRoLkJpZ0RlY2ltYWw7Ci1pbXBvcnQgamF2YS5tYXRoLkJpZ0ludGVnZXI7Ci1pbXBvcnQgamF2YS51dGlsLkNhbGVuZGFyOwotaW1wb3J0IGphdmEudXRpbC5EYXRlOwotaW1wb3J0IGphdmEudXRpbC5HcmVnb3JpYW5DYWxlbmRhcjsKLQotaW1wb3J0IGphdmF4LnhtbC5uYW1lc3BhY2UuUU5hbWU7Ci0KLS8qKgotICogPHA+SW1tdXRhYmxlIHJlcHJlc2VudGF0aW9uIG9mIGEgdGltZSBzcGFuIGFzIGRlZmluZWQgaW4KLSAqIHRoZSBXM0MgWE1MIFNjaGVtYSAxLjAgc3BlY2lmaWNhdGlvbi48L3A+Ci0gKgotICogPHA+QSBEdXJhdGlvbiBvYmplY3QgcmVwcmVzZW50cyBhIHBlcmlvZCBvZiBHcmVnb3JpYW4gdGltZSwKLSAqIHdoaWNoIGNvbnNpc3RzIG9mIHNpeCBmaWVsZHMgKHllYXJzLCBtb250aHMsIGRheXMsIGhvdXJzLAotICogbWludXRlcywgYW5kIHNlY29uZHMpIHBsdXMgYSBzaWduICgrLy0pIGZpZWxkLjwvcD4KLSAqCi0gKiA8cD5UaGUgZmlyc3QgZml2ZSBmaWVsZHMgaGF2ZSBub24tbmVnYXRpdmUgKD49MCkgaW50ZWdlcnMgb3IgbnVsbAotICogKHdoaWNoIHJlcHJlc2VudHMgdGhhdCB0aGUgZmllbGQgaXMgbm90IHNldCksCi0gKiBhbmQgdGhlIHNlY29uZHMgZmllbGQgaGFzIGEgbm9uLW5lZ2F0aXZlIGRlY2ltYWwgb3IgbnVsbC4KLSAqIEEgbmVnYXRpdmUgc2lnbiBpbmRpY2F0ZXMgYSBuZWdhdGl2ZSBkdXJhdGlvbi48L3A+Ci0gKgotICogPHA+VGhpcyBjbGFzcyBwcm92aWRlcyBhIG51bWJlciBvZiBtZXRob2RzIHRoYXQgbWFrZSBpdCBlYXN5Ci0gKiB0byB1c2UgZm9yIHRoZSBkdXJhdGlvbiBkYXRhdHlwZSBvZiBYTUwgU2NoZW1hIDEuMCB3aXRoCi0gKiB0aGUgZXJyYXRhLjwvcD4KLSAqCi0gKiA8aDI+T3JkZXIgcmVsYXRpb25zaGlwPC9oMj4KLSAqIDxwPkR1cmF0aW9uIG9iamVjdHMgb25seSBoYXZlIHBhcnRpYWwgb3JkZXIsIHdoZXJlIHR3byB2YWx1ZXMgQSBhbmQgQgotICogbWF5YmUgZWl0aGVyOjwvcD4KLSAqIDxvbD4KLSAqICA8bGk+QSZsdDtCIChBIGlzIHNob3J0ZXIgdGhhbiBCKQotICogIDxsaT5BJmd0O0IgKEEgaXMgbG9uZ2VyIHRoYW4gQikKLSAqICA8bGk+QT09QiAgIChBIGFuZCBCIGFyZSBvZiB0aGUgc2FtZSBkdXJhdGlvbikKLSAqICA8bGk+QSZsdDs+QiAoQ29tcGFyaXNvbiBiZXR3ZWVuIEEgYW5kIEIgaXMgaW5kZXRlcm1pbmF0ZSkKLSAqIDwvb2w+Ci0gKgotICogPHA+Rm9yIGV4YW1wbGUsIDMwIGRheXMgY2Fubm90IGJlIG1lYW5pbmdmdWxseSBjb21wYXJlZCB0byBvbmUgbW9udGguCi0gKiBUaGUge0BsaW5rICNjb21wYXJlKER1cmF0aW9uIGR1cmF0aW9uKX0gbWV0aG9kIGltcGxlbWVudHMgdGhpcwotICogcmVsYXRpb25zaGlwLjwvcD4KLSAqCi0gKiA8cD5TZWUgdGhlIHtAbGluayAjaXNMb25nZXJUaGFuKER1cmF0aW9uKX0gbWV0aG9kIGZvciBkZXRhaWxzIGFib3V0Ci0gKiB0aGUgb3JkZXIgcmVsYXRpb25zaGlwIGFtb25nIDxjb2RlPkR1cmF0aW9uPC9jb2RlPiBvYmplY3RzLjwvcD4KLSAqCi0gKiA8aDI+T3BlcmF0aW9ucyBvdmVyIER1cmF0aW9uPC9oMj4KLSAqIDxwPlRoaXMgY2xhc3MgcHJvdmlkZXMgYSBzZXQgb2YgYmFzaWMgYXJpdGhtZXRpYyBvcGVyYXRpb25zLCBzdWNoCi0gKiBhcyBhZGRpdGlvbiwgc3VidHJhY3Rpb24gYW5kIG11bHRpcGxpY2F0aW9uLgotICogQmVjYXVzZSBkdXJhdGlvbnMgZG9uJ3QgaGF2ZSB0b3RhbCBvcmRlciwgYW4gb3BlcmF0aW9uIGNvdWxkCi0gKiBmYWlsIGZvciBzb21lIGNvbWJpbmF0aW9ucyBvZiBvcGVyYXRpb25zLiBGb3IgZXhhbXBsZSwgeW91IGNhbm5vdAotICogc3VidHJhY3QgMTUgZGF5cyBmcm9tIDEgbW9udGguIFNlZSB0aGUgamF2YWRvYyBvZiB0aG9zZSBtZXRob2RzCi0gKiBmb3IgZGV0YWlsZWQgY29uZGl0aW9ucyB3aGVyZSB0aGlzIGNvdWxkIGhhcHBlbi48L3A+Ci0gKgotICogPHA+QWxzbywgZGl2aXNpb24gb2YgYSBkdXJhdGlvbiBieSBhIG51bWJlciBpcyBub3QgcHJvdmlkZWQgYmVjYXVzZQotICogdGhlIDxjb2RlPkR1cmF0aW9uPC9jb2RlPiBjbGFzcyBjYW4gb25seSBkZWFsIHdpdGggZmluaXRlIHByZWNpc2lvbgotICogZGVjaW1hbCBudW1iZXJzLiBGb3IgZXhhbXBsZSwgb25lIGNhbm5vdCByZXByZXNlbnQgMSBzZWMgZGl2aWRlZCBieSAzLjwvcD4KLSAqCi0gKiA8cD5Ib3dldmVyLCB5b3UgY291bGQgc3Vic3RpdHV0ZSBhIGRpdmlzaW9uIGJ5IDMgd2l0aCBtdWx0aXBseWluZwotICogYnkgbnVtYmVycyBzdWNoIGFzIDAuMyBvciAwLjMzMy48L3A+Ci0gKgotICogPGgyPlJhbmdlIG9mIGFsbG93ZWQgdmFsdWVzPC9oMj4KLSAqIDxwPgotICogQmVjYXVzZSBzb21lIG9wZXJhdGlvbnMgb2YgPGNvZGU+RHVyYXRpb248L2NvZGU+IHJlbHkgb24ge0BsaW5rIENhbGVuZGFyfQotICogZXZlbiB0aG91Z2gge0BsaW5rIER1cmF0aW9ufSBjYW4gaG9sZCB2ZXJ5IGxhcmdlIG9yIHZlcnkgc21hbGwgdmFsdWVzLAotICogc29tZSBvZiB0aGUgbWV0aG9kcyBtYXkgbm90IHdvcmsgY29ycmVjdGx5IG9uIHN1Y2ggPGNvZGU+RHVyYXRpb248L2NvZGU+cy4KLSAqIFRoZSBpbXBhY3RlZCBtZXRob2RzIGRvY3VtZW50IHRoZWlyIGRlcGVuZGVuY3kgb24ge0BsaW5rIENhbGVuZGFyfS4KLSAqCi0gKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzpKb3NlcGguRmlhbGxpQFN1bi5DT00iPkpvc2VwaCBGaWFsbGk8L2E+Ci0gKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzpLb2hzdWtlLkthd2FndWNoaUBTdW4uY29tIj5Lb2hzdWtlIEthd2FndWNoaTwvYT4KLSAqIEBhdXRob3IgPGEgaHJlZj0ibWFpbHRvOkplZmYuU3V0dG9yQFN1bi5jb20iPkplZmYgU3V0dG9yPC9hPgotICogQGF1dGhvciA8YSBocmVmPSJtYWlsdG86U3VuaXRoYS5SZWRkeUBTdW4uY29tIj5TdW5pdGhhIFJlZGR5PC9hPgotICogQHNlZSBYTUxHcmVnb3JpYW5DYWxlbmRhciNhZGQoRHVyYXRpb24pCi0gKiBAc2luY2UgMS41Ci0gKi8KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBEdXJhdGlvbiB7Ci0KLSAgICAvKioKLSAgICAgKiA8cD5EZWJ1Z2dpbmcgPGNvZGU+dHJ1ZTwvY29kZT4gb3IgPGNvZGU+ZmFsc2U8L2NvZGU+LjwvcD4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIERFQlVHID0gdHJ1ZTsKLQotICAgIC8qKgotICAgICAqIERlZmF1bHQgbm8tYXJnIGNvbnN0cnVjdG9yLgotICAgICAqCi0gICAgICogPHA+Tm90ZTogQWx3YXlzIHVzZSB0aGUge0BsaW5rIERhdGF0eXBlRmFjdG9yeX0gdG8KLSAgICAgKiBjb25zdHJ1Y3QgYW4gaW5zdGFuY2Ugb2YgPGNvZGU+RHVyYXRpb248L2NvZGU+LgotICAgICAqIFRoZSBjb25zdHJ1Y3RvciBvbiB0aGlzIGNsYXNzIGNhbm5vdCBiZSBndWFyYW50ZWVkIHRvCi0gICAgICogcHJvZHVjZSBhbiBvYmplY3Qgd2l0aCBhIGNvbnNpc3RlbnQgc3RhdGUgYW5kIG1heSBiZQotICAgICAqIHJlbW92ZWQgaW4gdGhlIGZ1dHVyZS48L3A+Ci0gICAgICovCi0gICAgcHVibGljIER1cmF0aW9uKCkgewotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPlJldHVybiB0aGUgbmFtZSBvZiB0aGUgWE1MIFNjaGVtYSBkYXRlL3RpbWUgdHlwZSB0aGF0IHRoaXMgaW5zdGFuY2UKLSAgICAgKiBtYXBzIHRvLiBUeXBlIGlzIGNvbXB1dGVkIGJhc2VkIG9uIGZpZWxkcyB0aGF0IGFyZSBzZXQsCi0gICAgICogaS5lLiB7QGxpbmsgI2lzU2V0KERhdGF0eXBlQ29uc3RhbnRzLkZpZWxkIGZpZWxkKX0gPT0gPGNvZGU+dHJ1ZTwvY29kZT4uPC9wPgotICAgICAqCi0gICAgICogPHRhYmxlIGJvcmRlcj0iMiIgcnVsZXM9ImFsbCIgY2VsbHBhZGRpbmc9IjIiPgotICAgICAqICAgPHRoZWFkPgotICAgICAqICAgICA8dHI+Ci0gICAgICogICAgICAgPHRoIGFsaWduPSJjZW50ZXIiIGNvbHNwYW49IjciPgotICAgICAqICAgICAgICAgUmVxdWlyZWQgZmllbGRzIGZvciBYTUwgU2NoZW1hIDEuMCBEYXRlL1RpbWUgRGF0YXR5cGVzLjxici8+Ci0gICAgICogICAgICAgICA8aT4odGltZXpvbmUgaXMgb3B0aW9uYWwgZm9yIGFsbCBkYXRlL3RpbWUgZGF0YXR5cGVzKTwvaT4KLSAgICAgKiAgICAgICA8L3RoPgotICAgICAqICAgICA8L3RyPgotICAgICAqICAgPC90aGVhZD4KLSAgICAgKiAgIDx0Ym9keT4KLSAgICAgKiAgICAgPHRyPgotICAgICAqICAgICAgIDx0ZD5EYXRhdHlwZTwvdGQ+Ci0gICAgICogICAgICAgPHRkPnllYXI8L3RkPgotICAgICAqICAgICAgIDx0ZD5tb250aDwvdGQ+Ci0gICAgICogICAgICAgPHRkPmRheTwvdGQ+Ci0gICAgICogICAgICAgPHRkPmhvdXI8L3RkPgotICAgICAqICAgICAgIDx0ZD5taW51dGU8L3RkPgotICAgICAqICAgICAgIDx0ZD5zZWNvbmQ8L3RkPgotICAgICAqICAgICA8L3RyPgotICAgICAqICAgICA8dHI+Ci0gICAgICogICAgICAgPHRkPntAbGluayBEYXRhdHlwZUNvbnN0YW50cyNEVVJBVElPTn08L3RkPgotICAgICAqICAgICAgIDx0ZD5YPC90ZD4KLSAgICAgKiAgICAgICA8dGQ+WDwvdGQ+Ci0gICAgICogICAgICAgPHRkPlg8L3RkPgotICAgICAqICAgICAgIDx0ZD5YPC90ZD4KLSAgICAgKiAgICAgICA8dGQ+WDwvdGQ+Ci0gICAgICogICAgICAgPHRkPlg8L3RkPgotICAgICAqICAgICA8L3RyPgotICAgICAqICAgICA8dHI+Ci0gICAgICogICAgICAgPHRkPntAbGluayBEYXRhdHlwZUNvbnN0YW50cyNEVVJBVElPTl9EQVlUSU1FfTwvdGQ+Ci0gICAgICogICAgICAgPHRkPjwvdGQ+Ci0gICAgICogICAgICAgPHRkPjwvdGQ+Ci0gICAgICogICAgICAgPHRkPlg8L3RkPgotICAgICAqICAgICAgIDx0ZD5YPC90ZD4KLSAgICAgKiAgICAgICA8dGQ+WDwvdGQ+Ci0gICAgICogICAgICAgPHRkPlg8L3RkPgotICAgICAqICAgICA8L3RyPgotICAgICAqICAgICA8dHI+Ci0gICAgICogICAgICAgPHRkPntAbGluayBEYXRhdHlwZUNvbnN0YW50cyNEVVJBVElPTl9ZRUFSTU9OVEh9PC90ZD4KLSAgICAgKiAgICAgICA8dGQ+WDwvdGQ+Ci0gICAgICogICAgICAgPHRkPlg8L3RkPgotICAgICAqICAgICAgIDx0ZD48L3RkPgotICAgICAqICAgICAgIDx0ZD48L3RkPgotICAgICAqICAgICAgIDx0ZD48L3RkPgotICAgICAqICAgICAgIDx0ZD48L3RkPgotICAgICAqICAgICA8L3RyPgotICAgICAqICAgPC90Ym9keT4KLSAgICAgKiA8L3RhYmxlPgotICAgICAqCi0gICAgICogQHJldHVybiBvbmUgb2YgdGhlIGZvbGxvd2luZyBjb25zdGFudHM6Ci0gICAgICogICB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjRFVSQVRJT059LAotICAgICAqICAge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0RVUkFUSU9OX0RBWVRJTUV9IG9yCi0gICAgICogICB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjRFVSQVRJT05fWUVBUk1PTlRIfS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIElmIHRoZSBjb21iaW5hdGlvbiBvZiBzZXQgZmllbGRzIGRvZXMgbm90IG1hdGNoIG9uZSBvZiB0aGUgWE1MIFNjaGVtYSBkYXRlL3RpbWUgZGF0YXR5cGVzLgotICAgICAqLwotICAgIHB1YmxpYyBRTmFtZSBnZXRYTUxTY2hlbWFUeXBlKCkgewotCi0gICAgICAgIGJvb2xlYW4geWVhclNldCA9IGlzU2V0KERhdGF0eXBlQ29uc3RhbnRzLllFQVJTKTsKLSAgICAgICAgYm9vbGVhbiBtb250aFNldCA9IGlzU2V0KERhdGF0eXBlQ29uc3RhbnRzLk1PTlRIUyk7Ci0gICAgICAgIGJvb2xlYW4gZGF5U2V0ID0gaXNTZXQoRGF0YXR5cGVDb25zdGFudHMuREFZUyk7Ci0gICAgICAgIGJvb2xlYW4gaG91clNldCA9IGlzU2V0KERhdGF0eXBlQ29uc3RhbnRzLkhPVVJTKTsKLSAgICAgICAgYm9vbGVhbiBtaW51dGVTZXQgPSBpc1NldChEYXRhdHlwZUNvbnN0YW50cy5NSU5VVEVTKTsKLSAgICAgICAgYm9vbGVhbiBzZWNvbmRTZXQgPSBpc1NldChEYXRhdHlwZUNvbnN0YW50cy5TRUNPTkRTKTsKLQotICAgICAgICAvLyBEVVJBVElPTgotICAgICAgICBpZiAoeWVhclNldAotICAgICAgICAgICAgJiYgbW9udGhTZXQKLSAgICAgICAgICAgICYmIGRheVNldAotICAgICAgICAgICAgJiYgaG91clNldAotICAgICAgICAgICAgJiYgbWludXRlU2V0Ci0gICAgICAgICAgICAmJiBzZWNvbmRTZXQpIHsKLSAgICAgICAgICAgIHJldHVybiBEYXRhdHlwZUNvbnN0YW50cy5EVVJBVElPTjsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIERVUkFUSU9OX0RBWVRJTUUKLSAgICAgICAgaWYgKCF5ZWFyU2V0Ci0gICAgICAgICAgICAmJiAhbW9udGhTZXQKLSAgICAgICAgICAgICYmIGRheVNldAotICAgICAgICAgICAgJiYgaG91clNldAotICAgICAgICAgICAgJiYgbWludXRlU2V0Ci0gICAgICAgICAgICAmJiBzZWNvbmRTZXQpIHsKLSAgICAgICAgICAgIHJldHVybiBEYXRhdHlwZUNvbnN0YW50cy5EVVJBVElPTl9EQVlUSU1FOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gRFVSQVRJT05fWUVBUk1PTlRICi0gICAgICAgIGlmICh5ZWFyU2V0Ci0gICAgICAgICAgICAmJiBtb250aFNldAotICAgICAgICAgICAgJiYgIWRheVNldAotICAgICAgICAgICAgJiYgIWhvdXJTZXQKLSAgICAgICAgICAgICYmICFtaW51dGVTZXQKLSAgICAgICAgICAgICYmICFzZWNvbmRTZXQpIHsKLSAgICAgICAgICAgIHJldHVybiBEYXRhdHlwZUNvbnN0YW50cy5EVVJBVElPTl9ZRUFSTU9OVEg7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBub3RoaW5nIG1hdGNoZXMKLSAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAiamF2YXgueG1sLmRhdGF0eXBlLkR1cmF0aW9uI2dldFhNTFNjaGVtYVR5cGUoKToiCi0gICAgICAgICAgICAgICAgKyAiIHRoaXMgRHVyYXRpb24gZG9lcyBub3QgbWF0Y2ggb25lIG9mIHRoZSBYTUwgU2NoZW1hIGRhdGUvdGltZSBkYXRhdHlwZXM6IgotICAgICAgICAgICAgICAgICsgIiB5ZWFyIHNldCA9ICIgKyB5ZWFyU2V0Ci0gICAgICAgICAgICAgICAgKyAiIG1vbnRoIHNldCA9ICIgKyBtb250aFNldAotICAgICAgICAgICAgICAgICsgIiBkYXkgc2V0ID0gIiArIGRheVNldAotICAgICAgICAgICAgICAgICsgIiBob3VyIHNldCA9ICIgKyBob3VyU2V0Ci0gICAgICAgICAgICAgICAgKyAiIG1pbnV0ZSBzZXQgPSAiICsgbWludXRlU2V0Ci0gICAgICAgICAgICAgICAgKyAiIHNlY29uZCBzZXQgPSAiICsgc2Vjb25kU2V0Ci0gICAgICAgICk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgc2lnbiBvZiB0aGlzIGR1cmF0aW9uIGluIC0xLDAsIG9yIDEuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuCi0gICAgICogICAgICAtMSBpZiB0aGlzIGR1cmF0aW9uIGlzIG5lZ2F0aXZlLCAwIGlmIHRoZSBkdXJhdGlvbiBpcyB6ZXJvLAotICAgICAqICAgICAgYW5kIDEgaWYgdGhlIGR1cmF0aW9uIGlzIHBvc2l0aXZlLgotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCBpbnQgZ2V0U2lnbigpOwotCi0gICAgLyoqCi0gICAgICogPHA+R2V0IHRoZSB5ZWFycyB2YWx1ZSBvZiB0aGlzIDxjb2RlPkR1cmF0aW9uPC9jb2RlPiBhcyBhbiA8Y29kZT5pbnQ8L2NvZGU+IG9yIDxjb2RlPjA8L2NvZGU+IGlmIG5vdCBwcmVzZW50LjwvcD4KLSAgICAgKgotICAgICAqIDxwPjxjb2RlPmdldFllYXJzKCk8L2NvZGU+IGlzIGEgY29udmVuaWVuY2UgbWV0aG9kIGZvcgotICAgICAqIHtAbGluayAjZ2V0RmllbGQoRGF0YXR5cGVDb25zdGFudHMuRmllbGQgZmllbGQpIGdldEZpZWxkKERhdGF0eXBlQ29uc3RhbnRzLllFQVJTKX0uPC9wPgotICAgICAqCi0gICAgICogPHA+QXMgdGhlIHJldHVybiB2YWx1ZSBpcyBhbiA8Y29kZT5pbnQ8L2NvZGU+LCBhbiBpbmNvcnJlY3QgdmFsdWUgd2lsbCBiZSByZXR1cm5lZCBmb3IgPGNvZGU+RHVyYXRpb248L2NvZGU+cwotICAgICAqIHdpdGggeWVhcnMgdGhhdCBnbyBiZXlvbmQgdGhlIHJhbmdlIG9mIGFuIDxjb2RlPmludDwvY29kZT4uCi0gICAgICogVXNlIHtAbGluayAjZ2V0RmllbGQoRGF0YXR5cGVDb25zdGFudHMuRmllbGQgZmllbGQpIGdldEZpZWxkKERhdGF0eXBlQ29uc3RhbnRzLllFQVJTKX0gdG8gYXZvaWQgcG9zc2libGUgbG9zcyBvZiBwcmVjaXNpb24uPC9wPgotICAgICAqCi0gICAgICogQHJldHVybiBJZiB0aGUgeWVhcnMgZmllbGQgaXMgcHJlc2VudCwgcmV0dXJuIGl0cyB2YWx1ZSBhcyBhbiA8Y29kZT5pbnQ8L2NvZGU+LCBlbHNlIHJldHVybiA8Y29kZT4wPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldFllYXJzKCkgewotICAgICAgICByZXR1cm4gZ2V0RmllbGQoRGF0YXR5cGVDb25zdGFudHMuWUVBUlMpLmludFZhbHVlKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogT2J0YWlucyB0aGUgdmFsdWUgb2YgdGhlIE1PTlRIUyBmaWVsZCBhcyBhbiBpbnRlZ2VyIHZhbHVlLAotICAgICAqIG9yIDAgaWYgbm90IHByZXNlbnQuCi0gICAgICoKLSAgICAgKiBUaGlzIG1ldGhvZCB3b3JrcyBqdXN0IGxpa2Uge0BsaW5rICNnZXRZZWFycygpfSBleGNlcHQKLSAgICAgKiB0aGF0IHRoaXMgbWV0aG9kIHdvcmtzIG9uIHRoZSBNT05USFMgZmllbGQuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIE1vbnRocyBvZiB0aGlzIDxjb2RlPkR1cmF0aW9uPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldE1vbnRocygpIHsKLSAgICAgICAgcmV0dXJuIGdldEZpZWxkKERhdGF0eXBlQ29uc3RhbnRzLk1PTlRIUykuaW50VmFsdWUoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBPYnRhaW5zIHRoZSB2YWx1ZSBvZiB0aGUgREFZUyBmaWVsZCBhcyBhbiBpbnRlZ2VyIHZhbHVlLAotICAgICAqIG9yIDAgaWYgbm90IHByZXNlbnQuCi0gICAgICoKLSAgICAgKiBUaGlzIG1ldGhvZCB3b3JrcyBqdXN0IGxpa2Uge0BsaW5rICNnZXRZZWFycygpfSBleGNlcHQKLSAgICAgKiB0aGF0IHRoaXMgbWV0aG9kIHdvcmtzIG9uIHRoZSBEQVlTIGZpZWxkLgotICAgICAqCi0gICAgICogQHJldHVybiBEYXlzIG9mIHRoaXMgPGNvZGU+RHVyYXRpb248L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0RGF5cygpIHsKLSAgICAgICAgcmV0dXJuIGdldEZpZWxkKERhdGF0eXBlQ29uc3RhbnRzLkRBWVMpLmludFZhbHVlKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogT2J0YWlucyB0aGUgdmFsdWUgb2YgdGhlIEhPVVJTIGZpZWxkIGFzIGFuIGludGVnZXIgdmFsdWUsCi0gICAgICogb3IgMCBpZiBub3QgcHJlc2VudC4KLSAgICAgKgotICAgICAqIFRoaXMgbWV0aG9kIHdvcmtzIGp1c3QgbGlrZSB7QGxpbmsgI2dldFllYXJzKCl9IGV4Y2VwdAotICAgICAqIHRoYXQgdGhpcyBtZXRob2Qgd29ya3Mgb24gdGhlIEhPVVJTIGZpZWxkLgotICAgICAqCi0gICAgICogQHJldHVybiBIb3VycyBvZiB0aGlzIDxjb2RlPkR1cmF0aW9uPC9jb2RlPi4KLSAgICAgKgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0SG91cnMoKSB7Ci0gICAgICAgIHJldHVybiBnZXRGaWVsZChEYXRhdHlwZUNvbnN0YW50cy5IT1VSUykuaW50VmFsdWUoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBPYnRhaW5zIHRoZSB2YWx1ZSBvZiB0aGUgTUlOVVRFUyBmaWVsZCBhcyBhbiBpbnRlZ2VyIHZhbHVlLAotICAgICAqIG9yIDAgaWYgbm90IHByZXNlbnQuCi0gICAgICoKLSAgICAgKiBUaGlzIG1ldGhvZCB3b3JrcyBqdXN0IGxpa2Uge0BsaW5rICNnZXRZZWFycygpfSBleGNlcHQKLSAgICAgKiB0aGF0IHRoaXMgbWV0aG9kIHdvcmtzIG9uIHRoZSBNSU5VVEVTIGZpZWxkLgotICAgICAqCi0gICAgICogQHJldHVybiBNaW51dGVzIG9mIHRoaXMgPGNvZGU+RHVyYXRpb248L2NvZGU+LgotICAgICAqCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRNaW51dGVzKCkgewotICAgICAgICByZXR1cm4gZ2V0RmllbGQoRGF0YXR5cGVDb25zdGFudHMuTUlOVVRFUykuaW50VmFsdWUoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBPYnRhaW5zIHRoZSB2YWx1ZSBvZiB0aGUgU0VDT05EUyBmaWVsZCBhcyBhbiBpbnRlZ2VyIHZhbHVlLAotICAgICAqIG9yIDAgaWYgbm90IHByZXNlbnQuCi0gICAgICoKLSAgICAgKiBUaGlzIG1ldGhvZCB3b3JrcyBqdXN0IGxpa2Uge0BsaW5rICNnZXRZZWFycygpfSBleGNlcHQKLSAgICAgKiB0aGF0IHRoaXMgbWV0aG9kIHdvcmtzIG9uIHRoZSBTRUNPTkRTIGZpZWxkLgotICAgICAqCi0gICAgICogQHJldHVybiBzZWNvbmRzIGluIHRoZSBpbnRlZ2VyIHZhbHVlLiBUaGUgZnJhY3Rpb24gb2Ygc2Vjb25kcwotICAgICAqICAgd2lsbCBiZSBkaXNjYXJkZWQgKGZvciBleGFtcGxlLCBpZiB0aGUgYWN0dWFsIHZhbHVlIGlzIDIuNSwKLSAgICAgKiAgIHRoaXMgbWV0aG9kIHJldHVybnMgMikKLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldFNlY29uZHMoKSB7Ci0gICAgICAgIHJldHVybiBnZXRGaWVsZChEYXRhdHlwZUNvbnN0YW50cy5TRUNPTkRTKS5pbnRWYWx1ZSgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPlJldHVybnMgdGhlIGxlbmd0aCBvZiB0aGUgZHVyYXRpb24gaW4gbWlsbGktc2Vjb25kcy48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5JZiB0aGUgc2Vjb25kcyBmaWVsZCBjYXJyaWVzIG1vcmUgZGlnaXRzIHRoYW4gbWlsbGktc2Vjb25kIG9yZGVyLAotICAgICAqIHRob3NlIHdpbGwgYmUgc2ltcGx5IGRpc2NhcmRlZCAob3IgaW4gb3RoZXIgd29yZHMsIHJvdW5kZWQgdG8gemVyby4pCi0gICAgICogRm9yIGV4YW1wbGUsIGZvciBhbnkgQ2FsZW5kYXIgdmFsdWUgPGNvZGU+eDwvY29kZT4sPC9wPgotICAgICAqIDxwcmU+Ci0gICAgICogPGNvZGU+bmV3IER1cmF0aW9uKCJQVDEwLjAwMDk5UyIpLmdldFRpbWVJbk1pbGxzKHgpID09IDEwMDAwPC9jb2RlPi4KLSAgICAgKiA8Y29kZT5uZXcgRHVyYXRpb24oIi1QVDEwLjAwMDk5UyIpLmdldFRpbWVJbk1pbGxzKHgpID09IC0xMDAwMDwvY29kZT4uCi0gICAgICogPC9wcmU+Ci0gICAgICoKLSAgICAgKiA8cD4KLSAgICAgKiBOb3RlIHRoYXQgdGhpcyBtZXRob2QgdXNlcyB0aGUge0BsaW5rICNhZGRUbyhDYWxlbmRhcil9IG1ldGhvZCwKLSAgICAgKiB3aGljaCBtYXkgd29yayBpbmNvcnJlY3RseSB3aXRoIDxjb2RlPkR1cmF0aW9uPC9jb2RlPiBvYmplY3RzIHdpdGgKLSAgICAgKiB2ZXJ5IGxhcmdlIHZhbHVlcyBpbiBpdHMgZmllbGRzLiBTZWUgdGhlIHtAbGluayAjYWRkVG8oQ2FsZW5kYXIpfQotICAgICAqIG1ldGhvZCBmb3IgZGV0YWlscy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzdGFydEluc3RhbnQKLSAgICAgKiAgICAgIFRoZSBsZW5ndGggb2YgYSBtb250aC95ZWFyIHZhcmllcy4gVGhlIDxjb2RlPnN0YXJ0SW5zdGFudDwvY29kZT4gaXMKLSAgICAgKiAgICAgIHVzZWQgdG8gZGlzYW1iaWd1YXRlIHRoaXMgdmFyaWFuY2UuIFNwZWNpZmljYWxseSwgdGhpcyBtZXRob2QKLSAgICAgKiAgICAgIHJldHVybnMgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiA8Y29kZT5zdGFydEluc3RhbnQ8L2NvZGU+IGFuZAotICAgICAqICAgICAgPGNvZGU+c3RhcnRJbnN0YW50K2R1cmF0aW9uPC9jb2RlPgotICAgICAqCi0gICAgICogQHJldHVybiBtaWxsaXNlY29uZHMgYmV0d2VlbiA8Y29kZT5zdGFydEluc3RhbnQ8L2NvZGU+IGFuZAotICAgICAqICAgPGNvZGU+c3RhcnRJbnN0YW50PC9jb2RlPiBwbHVzIHRoaXMgPGNvZGU+RHVyYXRpb248L2NvZGU+Ci0gICAgICoKLSAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIDxjb2RlPnN0YXJ0SW5zdGFudDwvY29kZT4gcGFyYW1ldGVyCi0gICAgICogaXMgbnVsbC4KLSAgICAgKgotICAgICAqLwotICAgIHB1YmxpYyBsb25nIGdldFRpbWVJbk1pbGxpcyhmaW5hbCBDYWxlbmRhciBzdGFydEluc3RhbnQpIHsKLSAgICAgICAgQ2FsZW5kYXIgY2FsID0gKENhbGVuZGFyKSBzdGFydEluc3RhbnQuY2xvbmUoKTsKLSAgICAgICAgYWRkVG8oY2FsKTsKLSAgICAgICAgcmV0dXJuIGdldENhbGVuZGFyVGltZUluTWlsbGlzKGNhbCkKLSAgICAgICAgICAgICAgICAgICAgLSBnZXRDYWxlbmRhclRpbWVJbk1pbGxpcyhzdGFydEluc3RhbnQpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPlJldHVybnMgdGhlIGxlbmd0aCBvZiB0aGUgZHVyYXRpb24gaW4gbWlsbGktc2Vjb25kcy48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5JZiB0aGUgc2Vjb25kcyBmaWVsZCBjYXJyaWVzIG1vcmUgZGlnaXRzIHRoYW4gbWlsbGktc2Vjb25kIG9yZGVyLAotICAgICAqIHRob3NlIHdpbGwgYmUgc2ltcGx5IGRpc2NhcmRlZCAob3IgaW4gb3RoZXIgd29yZHMsIHJvdW5kZWQgdG8gemVyby4pCi0gICAgICogRm9yIGV4YW1wbGUsIGZvciBhbnkgPGNvZGU+RGF0ZTwvY29kZT4gdmFsdWUgPGNvZGU+eDwvY29kZT4sPC9wPgotICAgICAqIDxwcmU+Ci0gICAgICogPGNvZGU+bmV3IER1cmF0aW9uKCJQVDEwLjAwMDk5UyIpLmdldFRpbWVJbk1pbGxzKHgpID09IDEwMDAwPC9jb2RlPi4KLSAgICAgKiA8Y29kZT5uZXcgRHVyYXRpb24oIi1QVDEwLjAwMDk5UyIpLmdldFRpbWVJbk1pbGxzKHgpID09IC0xMDAwMDwvY29kZT4uCi0gICAgICogPC9wcmU+Ci0gICAgICoKLSAgICAgKiA8cD4KLSAgICAgKiBOb3RlIHRoYXQgdGhpcyBtZXRob2QgdXNlcyB0aGUge0BsaW5rICNhZGRUbyhEYXRlKX0gbWV0aG9kLAotICAgICAqIHdoaWNoIG1heSB3b3JrIGluY29ycmVjdGx5IHdpdGggPGNvZGU+RHVyYXRpb248L2NvZGU+IG9iamVjdHMgd2l0aAotICAgICAqIHZlcnkgbGFyZ2UgdmFsdWVzIGluIGl0cyBmaWVsZHMuIFNlZSB0aGUge0BsaW5rICNhZGRUbyhEYXRlKX0KLSAgICAgKiBtZXRob2QgZm9yIGRldGFpbHMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc3RhcnRJbnN0YW50Ci0gICAgICogICAgICBUaGUgbGVuZ3RoIG9mIGEgbW9udGgveWVhciB2YXJpZXMuIFRoZSA8Y29kZT5zdGFydEluc3RhbnQ8L2NvZGU+IGlzCi0gICAgICogICAgICB1c2VkIHRvIGRpc2FtYmlndWF0ZSB0aGlzIHZhcmlhbmNlLiBTcGVjaWZpY2FsbHksIHRoaXMgbWV0aG9kCi0gICAgICogICAgICByZXR1cm5zIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gPGNvZGU+c3RhcnRJbnN0YW50PC9jb2RlPiBhbmQKLSAgICAgKiAgICAgIDxjb2RlPnN0YXJ0SW5zdGFudCtkdXJhdGlvbjwvY29kZT4uCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCi0gICAgICogICAgICBJZiB0aGUgc3RhcnRJbnN0YW50IHBhcmFtZXRlciBpcyBudWxsLgotICAgICAqCi0gICAgICogQHJldHVybiBtaWxsaXNlY29uZHMgYmV0d2VlbiA8Y29kZT5zdGFydEluc3RhbnQ8L2NvZGU+IGFuZAotICAgICAqICAgPGNvZGU+c3RhcnRJbnN0YW50PC9jb2RlPiBwbHVzIHRoaXMgPGNvZGU+RHVyYXRpb248L2NvZGU+Ci0gICAgICoKLSAgICAgKiBAc2VlICNnZXRUaW1lSW5NaWxsaXMoQ2FsZW5kYXIpCi0gICAgICovCi0gICAgcHVibGljIGxvbmcgZ2V0VGltZUluTWlsbGlzKGZpbmFsIERhdGUgc3RhcnRJbnN0YW50KSB7Ci0gICAgICAgIENhbGVuZGFyIGNhbCA9IG5ldyBHcmVnb3JpYW5DYWxlbmRhcigpOwotICAgICAgICBjYWwuc2V0VGltZShzdGFydEluc3RhbnQpOwotICAgICAgICB0aGlzLmFkZFRvKGNhbCk7Ci0gICAgICAgIHJldHVybiBnZXRDYWxlbmRhclRpbWVJbk1pbGxpcyhjYWwpIC0gc3RhcnRJbnN0YW50LmdldFRpbWUoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXRzIHRoZSB2YWx1ZSBvZiBhIGZpZWxkLgotICAgICAqCi0gICAgICogRmllbGRzIG9mIGEgZHVyYXRpb24gb2JqZWN0IG1heSBjb250YWluIGFyYml0cmFyeSBsYXJnZSB2YWx1ZS4KLSAgICAgKiBUaGVyZWZvcmUgdGhpcyBtZXRob2QgaXMgZGVzaWduZWQgdG8gcmV0dXJuIGEge0BsaW5rIE51bWJlcn0gb2JqZWN0LgotICAgICAqCi0gICAgICogSW4gY2FzZSBvZiBZRUFSUywgTU9OVEhTLCBEQVlTLCBIT1VSUywgYW5kIE1JTlVURVMsIHRoZSByZXR1cm5lZAotICAgICAqIG51bWJlciB3aWxsIGJlIGEgbm9uLW5lZ2F0aXZlIGludGVnZXIuIEluIGNhc2Ugb2Ygc2Vjb25kcywKLSAgICAgKiB0aGUgcmV0dXJuZWQgbnVtYmVyIG1heSBiZSBhIG5vbi1uZWdhdGl2ZSBkZWNpbWFsIHZhbHVlLgotICAgICAqCi0gICAgICogQHBhcmFtIGZpZWxkCi0gICAgICogICAgICBvbmUgb2YgdGhlIHNpeCBGaWVsZCBjb25zdGFudHMgKFlFQVJTLE1PTlRIUyxEQVlTLEhPVVJTLAotICAgICAqICAgICAgTUlOVVRFUywgb3IgU0VDT05EUy4pCi0gICAgICogQHJldHVybgotICAgICAqICAgICAgSWYgdGhlIHNwZWNpZmllZCBmaWVsZCBpcyBwcmVzZW50LCB0aGlzIG1ldGhvZCByZXR1cm5zCi0gICAgICogICAgICBhIG5vbi1udWxsIG5vbi1uZWdhdGl2ZSB7QGxpbmsgTnVtYmVyfSBvYmplY3QgdGhhdAotICAgICAqICAgICAgcmVwcmVzZW50cyBpdHMgdmFsdWUuIElmIGl0IGlzIG5vdCBwcmVzZW50LCByZXR1cm4gbnVsbC4KLSAgICAgKiAgICAgIEZvciBZRUFSUywgTU9OVEhTLCBEQVlTLCBIT1VSUywgYW5kIE1JTlVURVMsIHRoaXMgbWV0aG9kCi0gICAgICogICAgICByZXR1cm5zIGEge0BsaW5rIGphdmEubWF0aC5CaWdJbnRlZ2VyfSBvYmplY3QuIEZvciBTRUNPTkRTLCB0aGlzCi0gICAgICogICAgICBtZXRob2QgcmV0dXJucyBhIHtAbGluayBqYXZhLm1hdGguQmlnRGVjaW1hbH0uCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIElmIHRoZSA8Y29kZT5maWVsZDwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IE51bWJlciBnZXRGaWVsZChmaW5hbCBEYXRhdHlwZUNvbnN0YW50cy5GaWVsZCBmaWVsZCk7Ci0KLSAgICAvKioKLSAgICAgKiBDaGVja3MgaWYgYSBmaWVsZCBpcyBzZXQuCi0gICAgICoKLSAgICAgKiBBIGZpZWxkIG9mIGEgZHVyYXRpb24gb2JqZWN0IG1heSBvciBtYXkgbm90IGJlIHByZXNlbnQuCi0gICAgICogVGhpcyBtZXRob2QgY2FuIGJlIHVzZWQgdG8gdGVzdCBpZiBhIGZpZWxkIGlzIHByZXNlbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZmllbGQKLSAgICAgKiAgICAgIG9uZSBvZiB0aGUgc2l4IEZpZWxkIGNvbnN0YW50cyAoWUVBUlMsTU9OVEhTLERBWVMsSE9VUlMsCi0gICAgICogICAgICBNSU5VVEVTLCBvciBTRUNPTkRTLikKLSAgICAgKiBAcmV0dXJuCi0gICAgICogICAgICB0cnVlIGlmIHRoZSBmaWVsZCBpcyBwcmVzZW50LiBmYWxzZSBpZiBub3QuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCi0gICAgICogICAgICBJZiB0aGUgZmllbGQgcGFyYW1ldGVyIGlzIG51bGwuCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gaXNTZXQoZmluYWwgRGF0YXR5cGVDb25zdGFudHMuRmllbGQgZmllbGQpOwotCi0gICAgLyoqCi0gICAgICogPHA+Q29tcHV0ZXMgYSBuZXcgZHVyYXRpb24gd2hvc2UgdmFsdWUgaXMgPGNvZGU+dGhpcytyaHM8L2NvZGU+LjwvcD4KLSAgICAgKgotICAgICAqIDxwPkZvciBleGFtcGxlLDwvcD4KLSAgICAgKiA8cHJlPgotICAgICAqICIxIGRheSIgKyAiLTMgZGF5cyIgPSAiLTIgZGF5cyIKLSAgICAgKiAiMSB5ZWFyIiArICIxIGRheSIgPSAiMSB5ZWFyIGFuZCAxIGRheSIKLSAgICAgKiAiLSgxIGhvdXIsNTAgbWludXRlcykiICsgIi0yMCBtaW51dGVzIiA9ICItKDEgaG91cnMsNzAgbWludXRlcykiCi0gICAgICogIjE1IGhvdXJzIiArICItMyBkYXlzIiA9ICItKDIgZGF5cyw5IGhvdXJzKSIKLSAgICAgKiAiMSB5ZWFyIiArICItMSBkYXkiID0gSWxsZWdhbFN0YXRlRXhjZXB0aW9uCi0gICAgICogPC9wcmU+Ci0gICAgICoKLSAgICAgKiA8cD5TaW5jZSB0aGVyZSdzIG5vIHdheSB0byBtZWFuaW5nZnVsbHkgc3VidHJhY3QgMSBkYXkgZnJvbSAxIG1vbnRoLAotICAgICAqIHRoZXJlIGFyZSBjYXNlcyB3aGVyZSB0aGUgb3BlcmF0aW9uIGZhaWxzIGluCi0gICAgICoge0BsaW5rIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbn0uPC9wPgotICAgICAqCi0gICAgICogPHA+Ci0gICAgICogRm9ybWFsbHksIHRoZSBjb21wdXRhdGlvbiBpcyBkZWZpbmVkIGFzIGZvbGxvd3MuPC9wPgotICAgICAqIDxwPgotICAgICAqIEZpcnN0bHksIHdlIGNhbiBhc3N1bWUgdGhhdCB0d28gPGNvZGU+RHVyYXRpb248L2NvZGU+cyB0byBiZSBhZGRlZAotICAgICAqIGFyZSBib3RoIHBvc2l0aXZlIHdpdGhvdXQgbG9zaW5nIGdlbmVyYWxpdHkgKGkuZS4sCi0gICAgICogPGNvZGU+KC1YKStZPVktWDwvY29kZT4sIDxjb2RlPlgrKC1ZKT1YLVk8L2NvZGU+LAotICAgICAqIDxjb2RlPigtWCkrKC1ZKT0tKFgrWSk8L2NvZGU+KQotICAgICAqCi0gICAgICogPHA+Ci0gICAgICogQWRkaXRpb24gb2YgdHdvIHBvc2l0aXZlIDxjb2RlPkR1cmF0aW9uPC9jb2RlPnMgYXJlIHNpbXBseSBkZWZpbmVkIGFzCi0gICAgICogZmllbGQgYnkgZmllbGQgYWRkaXRpb24gd2hlcmUgbWlzc2luZyBmaWVsZHMgYXJlIHRyZWF0ZWQgYXMgMC4KLSAgICAgKiA8cD4KLSAgICAgKiBBIGZpZWxkIG9mIHRoZSByZXN1bHRpbmcgPGNvZGU+RHVyYXRpb248L2NvZGU+IHdpbGwgYmUgdW5zZXQgaWYgYW5kCi0gICAgICogb25seSBpZiByZXNwZWN0aXZlIGZpZWxkcyBvZiB0d28gaW5wdXQgPGNvZGU+RHVyYXRpb248L2NvZGU+cyBhcmUgdW5zZXQuCi0gICAgICogPHA+Ci0gICAgICogTm90ZSB0aGF0IDxjb2RlPmxocy5hZGQocmhzKTwvY29kZT4gd2lsbCBiZSBhbHdheXMgc3VjY2Vzc2Z1bCBpZgotICAgICAqIDxjb2RlPmxocy5zaWdudW0oKSpyaHMuc2lnbnVtKCkhPS0xPC9jb2RlPiBvciBib3RoIG9mIHRoZW0gYXJlCi0gICAgICogbm9ybWFsaXplZC48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gcmhzIDxjb2RlPkR1cmF0aW9uPC9jb2RlPiB0byBhZGQgdG8gdGhpcyA8Y29kZT5EdXJhdGlvbjwvY29kZT4KLSAgICAgKgotICAgICAqIEByZXR1cm4KLSAgICAgKiAgICAgIG5vbi1udWxsIHZhbGlkIER1cmF0aW9uIG9iamVjdC4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KLSAgICAgKiAgICAgIElmIHRoZSByaHMgcGFyYW1ldGVyIGlzIG51bGwuCi0gICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KLSAgICAgKiAgICAgIElmIHR3byBkdXJhdGlvbnMgY2Fubm90IGJlIG1lYW5pbmdmdWxseSBhZGRlZC4gRm9yCi0gICAgICogICAgICBleGFtcGxlLCBhZGRpbmcgbmVnYXRpdmUgb25lIGRheSB0byBvbmUgbW9udGggY2F1c2VzCi0gICAgICogICAgICB0aGlzIGV4Y2VwdGlvbi4KLSAgICAgKgotICAgICAqCi0gICAgICogQHNlZSAjc3VidHJhY3QoRHVyYXRpb24pCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IER1cmF0aW9uIGFkZChmaW5hbCBEdXJhdGlvbiByaHMpOwotCi0gICAgLyoqCi0gICAgICogQWRkcyB0aGlzIGR1cmF0aW9uIHRvIGEge0BsaW5rIENhbGVuZGFyfSBvYmplY3QuCi0gICAgICoKLSAgICAgKiA8cD4KLSAgICAgKiBDYWxscyB7QGxpbmsgamF2YS51dGlsLkNhbGVuZGFyI2FkZChpbnQsaW50KX0gaW4gdGhlCi0gICAgICogb3JkZXIgb2YgWUVBUlMsIE1PTlRIUywgREFZUywgSE9VUlMsIE1JTlVURVMsIFNFQ09ORFMsIGFuZCBNSUxMSVNFQ09ORFMKLSAgICAgKiBpZiB0aG9zZSBmaWVsZHMgYXJlIHByZXNlbnQuIEJlY2F1c2UgdGhlIHtAbGluayBDYWxlbmRhcn0gY2xhc3MKLSAgICAgKiB1c2VzIGludCB0byBob2xkIHZhbHVlcywgdGhlcmUgYXJlIGNhc2VzIHdoZXJlIHRoaXMgbWV0aG9kCi0gICAgICogd29uJ3Qgd29yayBjb3JyZWN0bHkgKGZvciBleGFtcGxlIGlmIHZhbHVlcyBvZiBmaWVsZHMKLSAgICAgKiBleGNlZWQgdGhlIHJhbmdlIG9mIGludC4pCi0gICAgICogPC9wPgotICAgICAqCi0gICAgICogPHA+Ci0gICAgICogQWxzbywgc2luY2UgdGhpcyBkdXJhdGlvbiBjbGFzcyBpcyBhIEdyZWdvcmlhbiBkdXJhdGlvbiwgdGhpcwotICAgICAqIG1ldGhvZCB3aWxsIG5vdCB3b3JrIGNvcnJlY3RseSBpZiB0aGUgZ2l2ZW4ge0BsaW5rIENhbGVuZGFyfQotICAgICAqIG9iamVjdCBpcyBiYXNlZCBvbiBzb21lIG90aGVyIGNhbGVuZGFyIHN5c3RlbXMuCi0gICAgICogPC9wPgotICAgICAqCi0gICAgICogPHA+Ci0gICAgICogQW55IGZyYWN0aW9uYWwgcGFydHMgb2YgdGhpcyA8Y29kZT5EdXJhdGlvbjwvY29kZT4gb2JqZWN0Ci0gICAgICogYmV5b25kIG1pbGxpc2Vjb25kcyB3aWxsIGJlIHNpbXBseSBpZ25vcmVkLiBGb3IgZXhhbXBsZSwgaWYKLSAgICAgKiB0aGlzIGR1cmF0aW9uIGlzICJQMS4yMzQ1NlMiLCB0aGVuIDEgaXMgYWRkZWQgdG8gU0VDT05EUywKLSAgICAgKiAyMzQgaXMgYWRkZWQgdG8gTUlMTElTRUNPTkRTLCBhbmQgdGhlIHJlc3Qgd2lsbCBiZSB1bnVzZWQuCi0gICAgICogPC9wPgotICAgICAqCi0gICAgICogPHA+Ci0gICAgICogTm90ZSB0aGF0IGJlY2F1c2Uge0BsaW5rIENhbGVuZGFyI2FkZChpbnQsIGludCl9IGlzIHVzaW5nCi0gICAgICogPGNvZGU+aW50PC9jb2RlPiwgPGNvZGU+RHVyYXRpb248L2NvZGU+IHdpdGggdmFsdWVzIGJleW9uZCB0aGUKLSAgICAgKiByYW5nZSBvZiA8Y29kZT5pbnQ8L2NvZGU+IGluIGl0cyBmaWVsZHMKLSAgICAgKiB3aWxsIGNhdXNlIG92ZXJmbG93L3VuZGVyZmxvdyB0byB0aGUgZ2l2ZW4ge0BsaW5rIENhbGVuZGFyfS4KLSAgICAgKiB7QGxpbmsgWE1MR3JlZ29yaWFuQ2FsZW5kYXIjYWRkKER1cmF0aW9uKX0gcHJvdmlkZXMgdGhlIHNhbWUKLSAgICAgKiBiYXNpYyBvcGVyYXRpb24gYXMgdGhpcyBtZXRob2Qgd2hpbGUgYXZvaWRpbmcKLSAgICAgKiB0aGUgb3ZlcmZsb3cvdW5kZXJmbG93IGlzc3Vlcy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjYWxlbmRhcgotICAgICAqICAgICAgQSBjYWxlbmRhciBvYmplY3Qgd2hvc2UgdmFsdWUgd2lsbCBiZSBtb2RpZmllZC4KLSAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCi0gICAgICogICAgICBpZiB0aGUgY2FsZW5kYXIgcGFyYW1ldGVyIGlzIG51bGwuCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IHZvaWQgYWRkVG8oQ2FsZW5kYXIgY2FsZW5kYXIpOwotCi0gICAgLyoqCi0gICAgICogQWRkcyB0aGlzIGR1cmF0aW9uIHRvIGEge0BsaW5rIERhdGV9IG9iamVjdC4KLSAgICAgKgotICAgICAqIDxwPgotICAgICAqIFRoZSBnaXZlbiBkYXRlIGlzIGZpcnN0IGNvbnZlcnRlZCBpbnRvCi0gICAgICogYSB7QGxpbmsgamF2YS51dGlsLkdyZWdvcmlhbkNhbGVuZGFyfSwgdGhlbiB0aGUgZHVyYXRpb24KLSAgICAgKiBpcyBhZGRlZCBleGFjdGx5IGxpa2UgdGhlIHtAbGluayAjYWRkVG8oQ2FsZW5kYXIpfSBtZXRob2QuCi0gICAgICoKLSAgICAgKiA8cD4KLSAgICAgKiBUaGUgdXBkYXRlZCB0aW1lIGluc3RhbnQgaXMgdGhlbiBjb252ZXJ0ZWQgYmFjayBpbnRvIGEKLSAgICAgKiB7QGxpbmsgRGF0ZX0gb2JqZWN0IGFuZCB1c2VkIHRvIHVwZGF0ZSB0aGUgZ2l2ZW4ge0BsaW5rIERhdGV9IG9iamVjdC4KLSAgICAgKgotICAgICAqIDxwPgotICAgICAqIFRoaXMgc29tZXdoYXQgcmVkdW5kYW50IGNvbXB1dGF0aW9uIGlzIG5lY2Vzc2FyeSB0byB1bmFtYmlndW91c2x5Ci0gICAgICogZGV0ZXJtaW5lIHRoZSBkdXJhdGlvbiBvZiBtb250aHMgYW5kIHllYXJzLgotICAgICAqCi0gICAgICogQHBhcmFtIGRhdGUKLSAgICAgKiAgICAgIEEgZGF0ZSBvYmplY3Qgd2hvc2UgdmFsdWUgd2lsbCBiZSBtb2RpZmllZC4KLSAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCi0gICAgICogICAgICBpZiB0aGUgZGF0ZSBwYXJhbWV0ZXIgaXMgbnVsbC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBhZGRUbyhEYXRlIGRhdGUpIHsKLQotICAgICAgICAvLyBjaGVjayBkYXRhIHBhcmFtZXRlcgotICAgICAgICBpZiAoZGF0ZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgIkNhbm5vdCBjYWxsICIKLSAgICAgICAgICAgICAgICArIHRoaXMuZ2V0Q2xhc3MoKS5nZXROYW1lKCkKLSAgICAgICAgICAgICAgICArICIjYWRkVG8oRGF0ZSBkYXRlKSB3aXRoIGRhdGUgPT0gbnVsbC4iCi0gICAgICAgICAgICApOwotICAgICAgICB9Ci0KLSAgICAgICAgQ2FsZW5kYXIgY2FsID0gbmV3IEdyZWdvcmlhbkNhbGVuZGFyKCk7Ci0gICAgICAgIGNhbC5zZXRUaW1lKGRhdGUpOwotICAgICAgICB0aGlzLmFkZFRvKGNhbCk7Ci0gICAgICAgIGRhdGUuc2V0VGltZShnZXRDYWxlbmRhclRpbWVJbk1pbGxpcyhjYWwpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5Db21wdXRlcyBhIG5ldyBkdXJhdGlvbiB3aG9zZSB2YWx1ZSBpcyA8Y29kZT50aGlzLXJoczwvY29kZT4uPC9wPgotICAgICAqCi0gICAgICogPHA+Rm9yIGV4YW1wbGU6PC9wPgotICAgICAqIDxwcmU+Ci0gICAgICogIjEgZGF5IiAtICItMyBkYXlzIiA9ICI0IGRheXMiCi0gICAgICogIjEgeWVhciIgLSAiMSBkYXkiID0gSWxsZWdhbFN0YXRlRXhjZXB0aW9uCi0gICAgICogIi0oMSBob3VyLDUwIG1pbnV0ZXMpIiAtICItMjAgbWludXRlcyIgPSAiLSgxaG91cnMsMzAgbWludXRlcykiCi0gICAgICogIjE1IGhvdXJzIiAtICItMyBkYXlzIiA9ICIzIGRheXMgYW5kIDE1IGhvdXJzIgotICAgICAqICIxIHllYXIiIC0gIi0xIGRheSIgPSAiMSB5ZWFyIGFuZCAxIGRheSIKLSAgICAgKiA8L3ByZT4KLSAgICAgKgotICAgICAqIDxwPlNpbmNlIHRoZXJlJ3Mgbm8gd2F5IHRvIG1lYW5pbmdmdWxseSBzdWJ0cmFjdCAxIGRheSBmcm9tIDEgbW9udGgsCi0gICAgICogdGhlcmUgYXJlIGNhc2VzIHdoZXJlIHRoZSBvcGVyYXRpb24gZmFpbHMgaW4ge0BsaW5rIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbn0uPC9wPgotICAgICAqCi0gICAgICogPHA+Rm9ybWFsbHkgdGhlIGNvbXB1dGF0aW9uIGlzIGRlZmluZWQgYXMgZm9sbG93cy4KLSAgICAgKiBGaXJzdCwgd2UgY2FuIGFzc3VtZSB0aGF0IHR3byA8Y29kZT5EdXJhdGlvbjwvY29kZT5zIGFyZSBib3RoIHBvc2l0aXZlCi0gICAgICogd2l0aG91dCBsb3NpbmcgZ2VuZXJhbGl0eS4gIChpLmUuLAotICAgICAqIDxjb2RlPigtWCktWT0tKFgrWSk8L2NvZGU+LCA8Y29kZT5YLSgtWSk9WCtZPC9jb2RlPiwKLSAgICAgKiA8Y29kZT4oLVgpLSgtWSk9LShYLVkpPC9jb2RlPik8L3A+Ci0gICAgICoKLSAgICAgKiA8cD5UaGVuIHR3byBkdXJhdGlvbnMgYXJlIHN1YnRyYWN0ZWQgZmllbGQgYnkgZmllbGQuCi0gICAgICogSWYgdGhlIHNpZ24gb2YgYW55IG5vbi16ZXJvIGZpZWxkIDxjb2RlPkY8L2NvZGU+IGlzIGRpZmZlcmVudCBmcm9tCi0gICAgICogdGhlIHNpZ24gb2YgdGhlIG1vc3Qgc2lnbmlmaWNhbnQgZmllbGQsCi0gICAgICogMSAoaWYgPGNvZGU+RjwvY29kZT4gaXMgbmVnYXRpdmUpIG9yIC0xIChvdGhlcndpc2UpCi0gICAgICogd2lsbCBiZSBib3Jyb3dlZCBmcm9tIHRoZSBuZXh0IGJpZ2dlciB1bml0IG9mIDxjb2RlPkY8L2NvZGU+LjwvcD4KLSAgICAgKgotICAgICAqIDxwPlRoaXMgcHJvY2VzcyBpcyByZXBlYXRlZCB1bnRpbCBhbGwgdGhlIG5vbi16ZXJvIGZpZWxkcyBoYXZlCi0gICAgICogdGhlIHNhbWUgc2lnbi48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5JZiBhIGJvcnJvdyBvY2N1cnMgaW4gdGhlIGRheXMgZmllbGQgKGluIG90aGVyIHdvcmRzLCBpZgotICAgICAqIHRoZSBjb21wdXRhdGlvbiBuZWVkcyB0byBib3Jyb3cgMSBvciAtMSBtb250aCB0byBjb21wZW5zYXRlCi0gICAgICogZGF5cyksIHRoZW4gdGhlIGNvbXB1dGF0aW9uIGZhaWxzIGJ5IHRocm93aW5nIGFuCi0gICAgICoge0BsaW5rIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbn0uPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIHJocyA8Y29kZT5EdXJhdGlvbjwvY29kZT4gdG8gc3VidHJhY3QgZnJvbSB0aGlzIDxjb2RlPkR1cmF0aW9uPC9jb2RlPi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gTmV3IDxjb2RlPkR1cmF0aW9uPC9jb2RlPiBjcmVhdGVkIGZyb20gc3VidHJhY3RpbmcgPGNvZGU+cmhzPC9jb2RlPiBmcm9tIHRoaXMgPGNvZGU+RHVyYXRpb248L2NvZGU+LgotICAgICAqCi0gICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KLSAgICAgKiAgICAgIElmIHR3byBkdXJhdGlvbnMgY2Fubm90IGJlIG1lYW5pbmdmdWxseSBzdWJ0cmFjdGVkLiBGb3IKLSAgICAgKiAgICAgIGV4YW1wbGUsIHN1YnRyYWN0aW5nIG9uZSBkYXkgZnJvbSBvbmUgbW9udGggY2F1c2VzCi0gICAgICogICAgICB0aGlzIGV4Y2VwdGlvbi4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KLSAgICAgKiAgICAgIElmIHRoZSByaHMgcGFyYW1ldGVyIGlzIG51bGwuCi0gICAgICoKLSAgICAgKiBAc2VlICNhZGQoRHVyYXRpb24pCi0gICAgICovCi0gICAgcHVibGljIER1cmF0aW9uIHN1YnRyYWN0KGZpbmFsIER1cmF0aW9uIHJocykgewotICAgICAgICByZXR1cm4gYWRkKHJocy5uZWdhdGUoKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+Q29tcHV0ZXMgYSBuZXcgZHVyYXRpb24gd2hvc2UgdmFsdWUgaXMgPGNvZGU+ZmFjdG9yPC9jb2RlPiB0aW1lcwotICAgICAqIGxvbmdlciB0aGFuIHRoZSB2YWx1ZSBvZiB0aGlzIGR1cmF0aW9uLjwvcD4KLSAgICAgKgotICAgICAqIDxwPlRoaXMgbWV0aG9kIGlzIHByb3ZpZGVkIGZvciB0aGUgY29udmVuaWVuY2UuCi0gICAgICogSXQgaXMgZnVuY3Rpb25hbGx5IGVxdWl2YWxlbnQgdG8gdGhlIGZvbGxvd2luZyBjb2RlOjwvcD4KLSAgICAgKiA8cHJlPgotICAgICAqIG11bHRpcGx5KG5ldyBCaWdEZWNpbWFsKFN0cmluZy52YWx1ZU9mKGZhY3RvcikpKQotICAgICAqIDwvcHJlPgotICAgICAqCi0gICAgICogQHBhcmFtIGZhY3RvciBGYWN0b3IgdGltZXMgbG9uZ2VyIG9mIG5ldyA8Y29kZT5EdXJhdGlvbjwvY29kZT4gdG8gY3JlYXRlLgotICAgICAqCi0gICAgICogQHJldHVybiBOZXcgPGNvZGU+RHVyYXRpb248L2NvZGU+IHRoYXQgaXMgPGNvZGU+ZmFjdG9yPC9jb2RlPnRpbWVzIGxvbmdlciB0aGFuIHRoaXMgPGNvZGU+RHVyYXRpb248L2NvZGU+LgotICAgICAqCi0gICAgICogQHNlZSAjbXVsdGlwbHkoQmlnRGVjaW1hbCkKLSAgICAgKi8KLSAgICBwdWJsaWMgRHVyYXRpb24gbXVsdGlwbHkoaW50IGZhY3RvcikgewotICAgICAgICByZXR1cm4gbXVsdGlwbHkobmV3IEJpZ0RlY2ltYWwoU3RyaW5nLnZhbHVlT2YoZmFjdG9yKSkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbXB1dGVzIGEgbmV3IGR1cmF0aW9uIHdob3NlIHZhbHVlIGlzIDxjb2RlPmZhY3RvcjwvY29kZT4gdGltZXMKLSAgICAgKiBsb25nZXIgdGhhbiB0aGUgdmFsdWUgb2YgdGhpcyBkdXJhdGlvbi4KLSAgICAgKgotICAgICAqIDxwPgotICAgICAqIEZvciBleGFtcGxlLAotICAgICAqIDxwcmU+Ci0gICAgICogIlAxTSIgKDEgbW9udGgpICogIjEyIiA9ICJQMTJNIiAoMTIgbW9udGhzKQotICAgICAqICJQVDFNIiAoMSBtaW4pICogIjAuMyIgPSAiUFQxOFMiICgxOCBzZWNvbmRzKQotICAgICAqICJQMU0iICgxIG1vbnRoKSAqICIxLjUiID0gSWxsZWdhbFN0YXRlRXhjZXB0aW9uCi0gICAgICogPC9wcmU+Ci0gICAgICoKLSAgICAgKiA8cD4KLSAgICAgKiBTaW5jZSB0aGUgPGNvZGU+RHVyYXRpb248L2NvZGU+IGNsYXNzIGlzIGltbXV0YWJsZSwgdGhpcyBtZXRob2QKLSAgICAgKiBkb2Vzbid0IGNoYW5nZSB0aGUgdmFsdWUgb2YgdGhpcyBvYmplY3QuIEl0IHNpbXBseSBjb21wdXRlcwotICAgICAqIGEgbmV3IER1cmF0aW9uIG9iamVjdCBhbmQgcmV0dXJucyBpdC4KLSAgICAgKgotICAgICAqIDxwPgotICAgICAqIFRoZSBvcGVyYXRpb24gd2lsbCBiZSBwZXJmb3JtZWQgZmllbGQgYnkgZmllbGQgd2l0aCB0aGUgcHJlY2lzaW9uCi0gICAgICogb2Yge0BsaW5rIEJpZ0RlY2ltYWx9LiBTaW5jZSBhbGwgdGhlIGZpZWxkcyBleGNlcHQgc2Vjb25kcyBhcmUKLSAgICAgKiByZXN0cmljdGVkIHRvIGhvbGQgaW50ZWdlcnMsCi0gICAgICogYW55IGZyYWN0aW9uIHByb2R1Y2VkIGJ5IHRoZSBjb21wdXRhdGlvbiB3aWxsIGJlCi0gICAgICogY2FycmllZCBkb3duIHRvd2FyZCB0aGUgbmV4dCBsb3dlciB1bml0LiBGb3IgZXhhbXBsZSwKLSAgICAgKiBpZiB5b3UgbXVsdGlwbHkgIlAxRCIgKDEgZGF5KSB3aXRoICIwLjUiLCB0aGVuIGl0IHdpbGwgYmUgMC41IGRheSwKLSAgICAgKiB3aGljaCB3aWxsIGJlIGNhcnJpZWQgZG93biB0byAiUFQxMkgiICgxMiBob3VycykuCi0gICAgICogV2hlbiBmcmFjdGlvbnMgb2YgbW9udGggY2Fubm90IGJlIG1lYW5pbmdmdWxseSBjYXJyaWVkIGRvd24KLSAgICAgKiB0byBkYXlzLCBvciB5ZWFyIHRvIG1vbnRocywgdGhpcyB3aWxsIGNhdXNlIGFuCi0gICAgICoge0BsaW5rIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbn0gdG8gYmUgdGhyb3duLgotICAgICAqIEZvciBleGFtcGxlIGlmIHlvdSBtdWx0aXBsZSBvbmUgbW9udGggYnkgMC41LjwvcD4KLSAgICAgKgotICAgICAqIDxwPgotICAgICAqIFRvIGF2b2lkIHtAbGluayBJbGxlZ2FsU3RhdGVFeGNlcHRpb259LCB1c2UKLSAgICAgKiB0aGUge0BsaW5rICNub3JtYWxpemVXaXRoKENhbGVuZGFyKX0gbWV0aG9kIHRvIHJlbW92ZSB0aGUgeWVhcnMKLSAgICAgKiBhbmQgbW9udGhzIGZpZWxkcy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBmYWN0b3IgdG8gbXVsdGlwbHkgYnkKLSAgICAgKgotICAgICAqIEByZXR1cm4KLSAgICAgKiAgICAgIHJldHVybnMgYSBub24tbnVsbCB2YWxpZCA8Y29kZT5EdXJhdGlvbjwvY29kZT4gb2JqZWN0Ci0gICAgICoKLSAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiBvcGVyYXRpb24gcHJvZHVjZXMgZnJhY3Rpb24gaW4KLSAgICAgKiB0aGUgbW9udGhzIGZpZWxkLgotICAgICAqCi0gICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgPGNvZGU+ZmFjdG9yPC9jb2RlPiBwYXJhbWV0ZXIgaXMKLSAgICAgKiA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICAgKgotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCBEdXJhdGlvbiBtdWx0aXBseShmaW5hbCBCaWdEZWNpbWFsIGZhY3Rvcik7Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGEgbmV3IDxjb2RlPkR1cmF0aW9uPC9jb2RlPiBvYmplY3Qgd2hvc2UKLSAgICAgKiB2YWx1ZSBpcyA8Y29kZT4tdGhpczwvY29kZT4uCi0gICAgICoKLSAgICAgKiA8cD4KLSAgICAgKiBTaW5jZSB0aGUgPGNvZGU+RHVyYXRpb248L2NvZGU+IGNsYXNzIGlzIGltbXV0YWJsZSwgdGhpcyBtZXRob2QKLSAgICAgKiBkb2Vzbid0IGNoYW5nZSB0aGUgdmFsdWUgb2YgdGhpcyBvYmplY3QuIEl0IHNpbXBseSBjb21wdXRlcwotICAgICAqIGEgbmV3IER1cmF0aW9uIG9iamVjdCBhbmQgcmV0dXJucyBpdC4KLSAgICAgKgotICAgICAqIEByZXR1cm4KLSAgICAgKiAgICAgIGFsd2F5cyByZXR1cm4gYSBub24tbnVsbCB2YWxpZCA8Y29kZT5EdXJhdGlvbjwvY29kZT4gb2JqZWN0LgotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCBEdXJhdGlvbiBuZWdhdGUoKTsKLQotICAgIC8qKgotICAgICAqIDxwPkNvbnZlcnRzIHRoZSB5ZWFycyBhbmQgbW9udGhzIGZpZWxkcyBpbnRvIHRoZSBkYXlzIGZpZWxkCi0gICAgICogYnkgdXNpbmcgYSBzcGVjaWZpYyB0aW1lIGluc3RhbnQgYXMgdGhlIHJlZmVyZW5jZSBwb2ludC48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5Gb3IgZXhhbXBsZSwgZHVyYXRpb24gb2Ygb25lIG1vbnRoIG5vcm1hbGl6ZXMgdG8gMzEgZGF5cwotICAgICAqIGdpdmVuIHRoZSBzdGFydCB0aW1lIGluc3RhbmNlICJKdWx5IDh0aCAyMDAzLCAxNzo0MDozMiIuPC9wPgotICAgICAqCi0gICAgICogPHA+Rm9ybWFsbHksIHRoZSBjb21wdXRhdGlvbiBpcyBkb25lIGFzIGZvbGxvd3M6PC9wPgotICAgICAqIDxvbD4KLSAgICAgKiAgPGxpPnRoZSBnaXZlbiBDYWxlbmRhciBvYmplY3QgaXMgY2xvbmVkPC9saT4KLSAgICAgKiAgPGxpPnRoZSB5ZWFycywgbW9udGhzIGFuZCBkYXlzIGZpZWxkcyB3aWxsIGJlIGFkZGVkIHRvIHRoZSB7QGxpbmsgQ2FsZW5kYXJ9IG9iamVjdAotICAgICAqICAgICAgYnkgdXNpbmcgdGhlIHtAbGluayBDYWxlbmRhciNhZGQoaW50LGludCl9IG1ldGhvZDwvbGk+Ci0gICAgICogIDxsaT50aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSB0d28gQ2FsZW5kYXJzIGluIGNvbXB1dGVkIGluIG1pbGxpc2Vjb25kcyBhbmQgY29udmVydGVkIHRvIGRheXMsCi0gICAgICogICAgIGlmIGEgcmVtYWluZGVyIG9jY3VycyBkdWUgdG8gRGF5bGlnaHQgU2F2aW5ncyBUaW1lLCBpdCBpcyBkaXNjYXJkZWQ8L2xpPgotICAgICAqICA8bGk+dGhlIGNvbXB1dGVkIGRheXMsIGFsb25nIHdpdGggdGhlIGhvdXJzLCBtaW51dGVzIGFuZCBzZWNvbmRzCi0gICAgICogICAgICBmaWVsZHMgb2YgdGhpcyBkdXJhdGlvbiBvYmplY3QgaXMgdXNlZCB0byBjb25zdHJ1Y3QgYSBuZXcKLSAgICAgKiAgICAgIER1cmF0aW9uIG9iamVjdC48L2xpPgotICAgICAqIDwvb2w+Ci0gICAgICoKLSAgICAgKiA8cD5Ob3RlIHRoYXQgc2luY2UgdGhlIENhbGVuZGFyIGNsYXNzIHVzZXMgPGNvZGU+aW50PC9jb2RlPiB0bwotICAgICAqIGhvbGQgdGhlIHZhbHVlIG9mIHllYXIgYW5kIG1vbnRoLCB0aGlzIG1ldGhvZCBtYXkgcHJvZHVjZQotICAgICAqIGFuIHVuZXhwZWN0ZWQgcmVzdWx0IGlmIHRoaXMgZHVyYXRpb24gb2JqZWN0IGhvbGRzCi0gICAgICogYSB2ZXJ5IGxhcmdlIHZhbHVlIGluIHRoZSB5ZWFycyBvciBtb250aHMgZmllbGRzLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzdGFydFRpbWVJbnN0YW50IDxjb2RlPkNhbGVuZGFyPC9jb2RlPiByZWZlcmVuY2UgcG9pbnQuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIDxjb2RlPkR1cmF0aW9uPC9jb2RlPiBvZiB5ZWFycyBhbmQgbW9udGhzIG9mIHRoaXMgPGNvZGU+RHVyYXRpb248L2NvZGU+IGFzIGRheXMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIElmIHRoZSBzdGFydFRpbWVJbnN0YW50IHBhcmFtZXRlciBpcyBudWxsLgotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCBEdXJhdGlvbiBub3JtYWxpemVXaXRoKGZpbmFsIENhbGVuZGFyIHN0YXJ0VGltZUluc3RhbnQpOwotCi0gICAgLyoqCi0gICAgICogPHA+UGFydGlhbCBvcmRlciByZWxhdGlvbiBjb21wYXJpc29uIHdpdGggdGhpcyA8Y29kZT5EdXJhdGlvbjwvY29kZT4gaW5zdGFuY2UuPC9wPgotICAgICAqCi0gICAgICogPHA+Q29tcGFyaXNvbiByZXN1bHQgbXVzdCBiZSBpbiBhY2NvcmRhbmNlIHdpdGgKLSAgICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94bWxzY2hlbWEtMi8jZHVyYXRpb24tb3JkZXIiPlczQyBYTUwgU2NoZW1hIDEuMCBQYXJ0IDIsIFNlY3Rpb24gMy4yLjcuNi4yLAotICAgICAqIDxpPk9yZGVyIHJlbGF0aW9uIG9uIGR1cmF0aW9uPC9pPjwvYT4uPC9wPgotICAgICAqCi0gICAgICogPHA+UmV0dXJuOjwvcD4KLSAgICAgKiA8dWw+Ci0gICAgICogICA8bGk+e0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0xFU1NFUn0gaWYgdGhpcyA8Y29kZT5EdXJhdGlvbjwvY29kZT4gaXMgc2hvcnRlciB0aGFuIDxjb2RlPmR1cmF0aW9uPC9jb2RlPiBwYXJhbWV0ZXI8L2xpPgotICAgICAqICAgPGxpPntAbGluayBEYXRhdHlwZUNvbnN0YW50cyNFUVVBTH0gaWYgdGhpcyA8Y29kZT5EdXJhdGlvbjwvY29kZT4gaXMgZXF1YWwgdG8gPGNvZGU+ZHVyYXRpb248L2NvZGU+IHBhcmFtZXRlcjwvbGk+Ci0gICAgICogICA8bGk+e0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0dSRUFURVJ9IGlmIHRoaXMgPGNvZGU+RHVyYXRpb248L2NvZGU+IGlzIGxvbmdlciB0aGFuIDxjb2RlPmR1cmF0aW9uPC9jb2RlPiBwYXJhbWV0ZXI8L2xpPgotICAgICAqICAgPGxpPntAbGluayBEYXRhdHlwZUNvbnN0YW50cyNJTkRFVEVSTUlOQVRFfSBpZiBhIGNvbmNsdXNpdmUgcGFydGlhbCBvcmRlciByZWxhdGlvbiBjYW5ub3QgYmUgZGV0ZXJtaW5lZDwvbGk+Ci0gICAgICogPC91bD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBkdXJhdGlvbiB0byBjb21wYXJlCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiA8Y29kZT50aGlzPC9jb2RlPiA8Y29kZT5EdXJhdGlvbjwvY29kZT5hbmQgPGNvZGU+ZHVyYXRpb248L2NvZGU+IHBhcmFtZXRlciBhcwotICAgICAqICAge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0xFU1NFUn0sIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNFUVVBTH0sIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNHUkVBVEVSfQotICAgICAqICAgb3Ige0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0lOREVURVJNSU5BVEV9LgotICAgICAqCi0gICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBJZiB0aGUgdW5kZXJseWluZyBpbXBsZW1lbnRhdGlvbgotICAgICAqICAgY2Fubm90IHJlYXNvbmFibHkgcHJvY2VzcyB0aGUgcmVxdWVzdCwgZS5nLiBXM0MgWE1MIFNjaGVtYSBhbGxvd3MgZm9yCi0gICAgICogICBhcmJpdHJhcmlseSBsYXJnZS9zbWFsbC9wcmVjaXNlIHZhbHVlcywgdGhlIHJlcXVlc3QgbWF5IGJlIGJleW9uZCB0aGUKLSAgICAgKiAgIGltcGxlbWVudGF0aW9ucyBjYXBhYmlsaXR5LgotICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgPGNvZGU+ZHVyYXRpb248L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAqCi0gICAgICogQHNlZSAjaXNTaG9ydGVyVGhhbihEdXJhdGlvbikKLSAgICAgKiBAc2VlICNpc0xvbmdlclRoYW4oRHVyYXRpb24pCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IGludCBjb21wYXJlKGZpbmFsIER1cmF0aW9uIGR1cmF0aW9uKTsKLQotICAgIC8qKgotICAgICAqIDxwPkNoZWNrcyBpZiB0aGlzIGR1cmF0aW9uIG9iamVjdCBpcyBzdHJpY3RseSBsb25nZXIgdGhhbgotICAgICAqIGFub3RoZXIgPGNvZGU+RHVyYXRpb248L2NvZGU+IG9iamVjdC48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5EdXJhdGlvbiBYIGlzICJsb25nZXIiIHRoYW4gWSBpZiBhbmQgb25seSBpZiBYPlkKLSAgICAgKiBhcyBkZWZpbmVkIGluIHRoZSBzZWN0aW9uIDMuMi42LjIgb2YgdGhlIFhNTCBTY2hlbWEgMS4wCi0gICAgICogc3BlY2lmaWNhdGlvbi48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5Gb3IgZXhhbXBsZSwgIlAxRCIgKG9uZSBkYXkpID4gIlBUMTJIIiAoMTIgaG91cnMpIGFuZAotICAgICAqICJQMlkiICh0d28geWVhcnMpID4gIlAyM00iICgyMyBtb250aHMpLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBkdXJhdGlvbiA8Y29kZT5EdXJhdGlvbjwvY29kZT4gdG8gdGVzdCB0aGlzIDxjb2RlPkR1cmF0aW9uPC9jb2RlPiBhZ2FpbnN0LgotICAgICAqCi0gICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBJZiB0aGUgdW5kZXJseWluZyBpbXBsZW1lbnRhdGlvbgotICAgICAqICAgY2Fubm90IHJlYXNvbmFibHkgcHJvY2VzcyB0aGUgcmVxdWVzdCwgZS5nLiBXM0MgWE1MIFNjaGVtYSBhbGxvd3MgZm9yCi0gICAgICogICBhcmJpdHJhcmlseSBsYXJnZS9zbWFsbC9wcmVjaXNlIHZhbHVlcywgdGhlIHJlcXVlc3QgbWF5IGJlIGJleW9uZCB0aGUKLSAgICAgKiAgIGltcGxlbWVudGF0aW9ucyBjYXBhYmlsaXR5LgotICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gSWYgPGNvZGU+ZHVyYXRpb248L2NvZGU+IGlzIG51bGwuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuCi0gICAgICogICAgICB0cnVlIGlmIHRoZSBkdXJhdGlvbiByZXByZXNlbnRlZCBieSB0aGlzIG9iamVjdAotICAgICAqICAgICAgaXMgbG9uZ2VyIHRoYW4gdGhlIGdpdmVuIGR1cmF0aW9uLiBmYWxzZSBvdGhlcndpc2UuCi0gICAgICoKLSAgICAgKiBAc2VlICNpc1Nob3J0ZXJUaGFuKER1cmF0aW9uKQotICAgICAqIEBzZWUgI2NvbXBhcmUoRHVyYXRpb24gZHVyYXRpb24pCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNMb25nZXJUaGFuKGZpbmFsIER1cmF0aW9uIGR1cmF0aW9uKSB7Ci0gICAgICAgIHJldHVybiBjb21wYXJlKGR1cmF0aW9uKSA9PSBEYXRhdHlwZUNvbnN0YW50cy5HUkVBVEVSOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPkNoZWNrcyBpZiB0aGlzIGR1cmF0aW9uIG9iamVjdCBpcyBzdHJpY3RseSBzaG9ydGVyIHRoYW4KLSAgICAgKiBhbm90aGVyIDxjb2RlPkR1cmF0aW9uPC9jb2RlPiBvYmplY3QuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGR1cmF0aW9uIDxjb2RlPkR1cmF0aW9uPC9jb2RlPiB0byB0ZXN0IHRoaXMgPGNvZGU+RHVyYXRpb248L2NvZGU+IGFnYWluc3QuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIDxjb2RlPnRydWU8L2NvZGU+IGlmIDxjb2RlPmR1cmF0aW9uPC9jb2RlPiBwYXJhbWV0ZXIgaXMgc2hvcnRlciB0aGFuIHRoaXMgPGNvZGU+RHVyYXRpb248L2NvZGU+LAotICAgICAqICAgZWxzZSA8Y29kZT5mYWxzZTwvY29kZT4uCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIElmIHRoZSB1bmRlcmx5aW5nIGltcGxlbWVudGF0aW9uCi0gICAgICogICBjYW5ub3QgcmVhc29uYWJseSBwcm9jZXNzIHRoZSByZXF1ZXN0LCBlLmcuIFczQyBYTUwgU2NoZW1hIGFsbG93cyBmb3IKLSAgICAgKiAgIGFyYml0cmFyaWx5IGxhcmdlL3NtYWxsL3ByZWNpc2UgdmFsdWVzLCB0aGUgcmVxdWVzdCBtYXkgYmUgYmV5b25kIHRoZQotICAgICAqICAgaW1wbGVtZW50YXRpb25zIGNhcGFiaWxpdHkuCi0gICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiA8Y29kZT5kdXJhdGlvbjwvY29kZT4gaXMgbnVsbC4KLSAgICAgKgotICAgICAqIEBzZWUgI2lzTG9uZ2VyVGhhbihEdXJhdGlvbiBkdXJhdGlvbikKLSAgICAgKiBAc2VlICNjb21wYXJlKER1cmF0aW9uIGR1cmF0aW9uKQotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzU2hvcnRlclRoYW4oZmluYWwgRHVyYXRpb24gZHVyYXRpb24pIHsKLSAgICAgICAgcmV0dXJuIGNvbXBhcmUoZHVyYXRpb24pID09IERhdGF0eXBlQ29uc3RhbnRzLkxFU1NFUjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5DaGVja3MgaWYgdGhpcyBkdXJhdGlvbiBvYmplY3QgaGFzIHRoZSBzYW1lIGR1cmF0aW9uCi0gICAgICogYXMgYW5vdGhlciA8Y29kZT5EdXJhdGlvbjwvY29kZT4gb2JqZWN0LjwvcD4KLSAgICAgKgotICAgICAqIDxwPkZvciBleGFtcGxlLCAiUDFEIiAoMSBkYXkpIGlzIGVxdWFsIHRvICJQVDI0SCIgKDI0IGhvdXJzKS48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5EdXJhdGlvbiBYIGlzIGVxdWFsIHRvIFkgaWYgYW5kIG9ubHkgaWYgdGltZSBpbnN0YW50Ci0gICAgICogdCtYIGFuZCB0K1kgYXJlIHRoZSBzYW1lIGZvciBhbGwgdGhlIHRlc3QgdGltZSBpbnN0YW50cwotICAgICAqIHNwZWNpZmllZCBpbiB0aGUgc2VjdGlvbiAzLjIuNi4yIG9mIHRoZSBYTUwgU2NoZW1hIDEuMAotICAgICAqIHNwZWNpZmljYXRpb24uPC9wPgotICAgICAqCi0gICAgICogPHA+Tm90ZSB0aGF0IHRoZXJlIGFyZSBjYXNlcyB3aGVyZSB0d28gPGNvZGU+RHVyYXRpb248L2NvZGU+cyBhcmUKLSAgICAgKiAiaW5jb21wYXJhYmxlIiB0byBlYWNoIG90aGVyLCBsaWtlIG9uZSBtb250aCBhbmQgMzAgZGF5cy4KLSAgICAgKiBGb3IgZXhhbXBsZSw8L3A+Ci0gICAgICogPHByZT4KLSAgICAgKiAhbmV3IER1cmF0aW9uKCJQMU0iKS5pc1Nob3J0ZXJUaGFuKG5ldyBEdXJhdGlvbigiUDMwRCIpKQotICAgICAqICFuZXcgRHVyYXRpb24oIlAxTSIpLmlzTG9uZ2VyVGhhbihuZXcgRHVyYXRpb24oIlAzMEQiKSkKLSAgICAgKiAhbmV3IER1cmF0aW9uKCJQMU0iKS5lcXVhbHMobmV3IER1cmF0aW9uKCJQMzBEIikpCi0gICAgICogPC9wcmU+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gZHVyYXRpb24KLSAgICAgKiAgICAgIFRoZSBvYmplY3QgdG8gY29tcGFyZSB0aGlzIDxjb2RlPkR1cmF0aW9uPC9jb2RlPiBhZ2FpbnN0LgotICAgICAqCi0gICAgICogQHJldHVybgotICAgICAqICAgICAgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhpcyBkdXJhdGlvbiBpcyB0aGUgc2FtZSBsZW5ndGggYXMKLSAgICAgKiAgICAgICAgIDxjb2RlPmR1cmF0aW9uPC9jb2RlPi4KLSAgICAgKiAgICAgIDxjb2RlPmZhbHNlPC9jb2RlPiBpZiA8Y29kZT5kdXJhdGlvbjwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4sCi0gICAgICogICAgICAgICBpcyBub3QgYQotICAgICAqICAgICAgICAgPGNvZGU+RHVyYXRpb248L2NvZGU+IG9iamVjdCwKLSAgICAgKiAgICAgICAgIG9yIGl0cyBsZW5ndGggaXMgZGlmZmVyZW50IGZyb20gdGhpcyBkdXJhdGlvbi4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gSWYgdGhlIHVuZGVybHlpbmcgaW1wbGVtZW50YXRpb24KLSAgICAgKiAgIGNhbm5vdCByZWFzb25hYmx5IHByb2Nlc3MgdGhlIHJlcXVlc3QsIGUuZy4gVzNDIFhNTCBTY2hlbWEgYWxsb3dzIGZvcgotICAgICAqICAgYXJiaXRyYXJpbHkgbGFyZ2Uvc21hbGwvcHJlY2lzZSB2YWx1ZXMsIHRoZSByZXF1ZXN0IG1heSBiZSBiZXlvbmQgdGhlCi0gICAgICogICBpbXBsZW1lbnRhdGlvbnMgY2FwYWJpbGl0eS4KLSAgICAgKgotICAgICAqIEBzZWUgI2NvbXBhcmUoRHVyYXRpb24gZHVyYXRpb24pCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIE9iamVjdCBkdXJhdGlvbikgewotCi0gICAgICAgIGlmIChkdXJhdGlvbiA9PSBudWxsIHx8ICEoZHVyYXRpb24gaW5zdGFuY2VvZiBEdXJhdGlvbikpIHsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBjb21wYXJlKChEdXJhdGlvbikgZHVyYXRpb24pID09IERhdGF0eXBlQ29uc3RhbnRzLkVRVUFMOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYSBoYXNoIGNvZGUgY29uc2lzdGVudCB3aXRoIHRoZSBkZWZpbml0aW9uIG9mIHRoZSBlcXVhbHMgbWV0aG9kLgotICAgICAqCi0gICAgICogQHNlZSBPYmplY3QjaGFzaENvZGUoKQotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCBpbnQgaGFzaENvZGUoKTsKLQotICAgIC8qKgotICAgICAqIDxwPlJldHVybnMgYSA8Y29kZT5TdHJpbmc8L2NvZGU+IHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgPGNvZGU+RHVyYXRpb248L2NvZGU+IDxjb2RlPk9iamVjdDwvY29kZT4uPC9wPgotICAgICAqCi0gICAgICogPHA+VGhlIHJlc3VsdCBpcyBmb3JtYXR0ZWQgYWNjb3JkaW5nIHRvIHRoZSBYTUwgU2NoZW1hIDEuMCBzcGVjIGFuZCBjYW4gYmUgYWx3YXlzIHBhcnNlZCBiYWNrIGxhdGVyIGludG8gdGhlCi0gICAgICogZXF1aXZhbGVudCA8Y29kZT5EdXJhdGlvbjwvY29kZT4gPGNvZGU+T2JqZWN0PC9jb2RlPiBieSB7QGxpbmsgRGF0YXR5cGVGYWN0b3J5I25ld0R1cmF0aW9uKFN0cmluZyAgbGV4aWNhbFJlcHJlc2VudGF0aW9uKX0uPC9wPgotICAgICAqCi0gICAgICogPHA+Rm9ybWFsbHksIHRoZSBmb2xsb3dpbmcgaG9sZHMgZm9yIGFueSA8Y29kZT5EdXJhdGlvbjwvY29kZT4KLSAgICAgKiA8Y29kZT5PYmplY3Q8L2NvZGU+IHg6PC9wPgotICAgICAqIDxwcmU+Ci0gICAgICogbmV3IER1cmF0aW9uKHgudG9TdHJpbmcoKSkuZXF1YWxzKHgpCi0gICAgICogPC9wcmU+Ci0gICAgICoKLSAgICAgKiBAcmV0dXJuIEEgbm9uLTxjb2RlPm51bGw8L2NvZGU+IHZhbGlkIDxjb2RlPlN0cmluZzwvY29kZT4gcmVwcmVzZW50YXRpb24gb2YgdGhpcyA8Y29kZT5EdXJhdGlvbjwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKLQotICAgICAgICBTdHJpbmdCdWZmZXIgYnVmID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotCi0gICAgICAgIGlmIChnZXRTaWduKCkgPCAwKSB7Ci0gICAgICAgICAgICBidWYuYXBwZW5kKCctJyk7Ci0gICAgICAgIH0KLSAgICAgICAgYnVmLmFwcGVuZCgnUCcpOwotCi0gICAgICAgIEJpZ0ludGVnZXIgeWVhcnMgPSAoQmlnSW50ZWdlcikgZ2V0RmllbGQoRGF0YXR5cGVDb25zdGFudHMuWUVBUlMpOwotICAgICAgICBpZiAoeWVhcnMgIT0gbnVsbCkgewotICAgICAgICAgICAgYnVmLmFwcGVuZCh5ZWFycyArICJZIik7Ci0gICAgICAgIH0KLQotICAgICAgICBCaWdJbnRlZ2VyIG1vbnRocyA9IChCaWdJbnRlZ2VyKSBnZXRGaWVsZChEYXRhdHlwZUNvbnN0YW50cy5NT05USFMpOwotICAgICAgICBpZiAobW9udGhzICE9IG51bGwpIHsKLSAgICAgICAgICAgIGJ1Zi5hcHBlbmQobW9udGhzICsgIk0iKTsKLSAgICAgICAgfQotCi0gICAgICAgIEJpZ0ludGVnZXIgZGF5cyA9IChCaWdJbnRlZ2VyKSBnZXRGaWVsZChEYXRhdHlwZUNvbnN0YW50cy5EQVlTKTsKLSAgICAgICAgaWYgKGRheXMgIT0gbnVsbCkgewotICAgICAgICAgICAgYnVmLmFwcGVuZChkYXlzICsgIkQiKTsKLSAgICAgICAgfQotCi0gICAgICAgIEJpZ0ludGVnZXIgaG91cnMgPSAoQmlnSW50ZWdlcikgZ2V0RmllbGQoRGF0YXR5cGVDb25zdGFudHMuSE9VUlMpOwotICAgICAgICBCaWdJbnRlZ2VyIG1pbnV0ZXMgPSAoQmlnSW50ZWdlcikgZ2V0RmllbGQoRGF0YXR5cGVDb25zdGFudHMuTUlOVVRFUyk7Ci0gICAgICAgIEJpZ0RlY2ltYWwgc2Vjb25kcyA9IChCaWdEZWNpbWFsKSBnZXRGaWVsZChEYXRhdHlwZUNvbnN0YW50cy5TRUNPTkRTKTsKLSAgICAgICAgaWYgKGhvdXJzICE9IG51bGwgfHwgbWludXRlcyAhPSBudWxsIHx8IHNlY29uZHMgIT0gbnVsbCkgewotICAgICAgICAgICAgYnVmLmFwcGVuZCgnVCcpOwotICAgICAgICAgICAgaWYgKGhvdXJzICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBidWYuYXBwZW5kKGhvdXJzICsgIkgiKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChtaW51dGVzICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBidWYuYXBwZW5kKG1pbnV0ZXMgKyAiTSIpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKHNlY29uZHMgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQodG9TdHJpbmcoc2Vjb25kcykgKyAiUyIpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIGJ1Zi50b1N0cmluZygpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPlR1cm5zIHtAbGluayBCaWdEZWNpbWFsfSB0byBhIHN0cmluZyByZXByZXNlbnRhdGlvbi48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5EdWUgdG8gYSBiZWhhdmlvciBjaGFuZ2UgaW4gdGhlIHtAbGluayBCaWdEZWNpbWFsI3RvU3RyaW5nKCl9Ci0gICAgICogbWV0aG9kIGluIEpESzEuNSwgdGhpcyBoYWQgdG8gYmUgaW1wbGVtZW50ZWQgaGVyZS48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gYmQgPGNvZGU+QmlnRGVjaW1hbDwvY29kZT4gdG8gZm9ybWF0IGFzIGEgPGNvZGU+U3RyaW5nPC9jb2RlPgotICAgICAqCi0gICAgICogQHJldHVybiAgPGNvZGU+U3RyaW5nPC9jb2RlPiByZXByZXNlbnRhdGlvbiBvZiA8Y29kZT5CaWdEZWNpbWFsPC9jb2RlPgotICAgICAqLwotICAgIHByaXZhdGUgU3RyaW5nIHRvU3RyaW5nKEJpZ0RlY2ltYWwgYmQpIHsKLSAgICAgICAgU3RyaW5nIGludFN0cmluZyA9IGJkLnVuc2NhbGVkVmFsdWUoKS50b1N0cmluZygpOwotICAgICAgICBpbnQgc2NhbGUgPSBiZC5zY2FsZSgpOwotCi0gICAgICAgIGlmIChzY2FsZSA9PSAwKSB7Ci0gICAgICAgICAgICByZXR1cm4gaW50U3RyaW5nOwotICAgICAgICB9Ci0KLSAgICAgICAgLyogSW5zZXJ0IGRlY2ltYWwgcG9pbnQgKi8KLSAgICAgICAgU3RyaW5nQnVmZmVyIGJ1ZjsKLSAgICAgICAgaW50IGluc2VydGlvblBvaW50ID0gaW50U3RyaW5nLmxlbmd0aCgpIC0gc2NhbGU7Ci0gICAgICAgIGlmIChpbnNlcnRpb25Qb2ludCA9PSAwKSB7IC8qIFBvaW50IGdvZXMgcmlnaHQgYmVmb3JlIGludFZhbCAqLwotICAgICAgICAgICAgcmV0dXJuICIwLiIgKyBpbnRTdHJpbmc7Ci0gICAgICAgIH0gZWxzZSBpZiAoaW5zZXJ0aW9uUG9pbnQgPiAwKSB7IC8qIFBvaW50IGdvZXMgaW5zaWRlIGludFZhbCAqLwotICAgICAgICAgICAgYnVmID0gbmV3IFN0cmluZ0J1ZmZlcihpbnRTdHJpbmcpOwotICAgICAgICAgICAgYnVmLmluc2VydChpbnNlcnRpb25Qb2ludCwgJy4nKTsKLSAgICAgICAgfSBlbHNlIHsgLyogV2UgbXVzdCBpbnNlcnQgemVyb3MgYmV0d2VlbiBwb2ludCBhbmQgaW50VmFsICovCi0gICAgICAgICAgICBidWYgPSBuZXcgU3RyaW5nQnVmZmVyKDMgLSBpbnNlcnRpb25Qb2ludCArIGludFN0cmluZy5sZW5ndGgoKSk7Ci0gICAgICAgICAgICBidWYuYXBwZW5kKCIwLiIpOwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAtaW5zZXJ0aW9uUG9pbnQ7IGkrKykgewotICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoJzAnKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGJ1Zi5hcHBlbmQoaW50U3RyaW5nKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gYnVmLnRvU3RyaW5nKCk7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiA8cD5DYWxscyB0aGUge0BsaW5rIENhbGVuZGFyI2dldFRpbWVJbk1pbGxpc30gbWV0aG9kLgotICAgICAqIFByaW9yIHRvIEpESzEuNCwgdGhpcyBtZXRob2Qgd2FzIHByb3RlY3RlZCBhbmQgdGhlcmVmb3JlCi0gICAgICogY2Fubm90IGJlIGludm9rZWQgZGlyZWN0bHkuPC9wPgotICAgICAqCi0gICAgICogPHA+VE9ETzogSW4gZnV0dXJlLCB0aGlzIHNob3VsZCBiZSByZXBsYWNlZCBieSA8Y29kZT5jYWwuZ2V0VGltZUluTWlsbGlzKCk8L2NvZGU+LjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjYWwgPGNvZGU+Q2FsZW5kYXI8L2NvZGU+IHRvIGdldCB0aW1lIGluIG1pbGxpc2Vjb25kcy4KLSAgICAgKgotICAgICAqIEByZXR1cm4gTWlsbGlzZWNvbmRzIG9mIDxjb2RlPmNhbDwvY29kZT4uCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgbG9uZyBnZXRDYWxlbmRhclRpbWVJbk1pbGxpcyhmaW5hbCBDYWxlbmRhciBjYWwpIHsKLSAgICAgICAgcmV0dXJuIGNhbC5nZXRUaW1lKCkuZ2V0VGltZSgpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9qYXZheC94bWwvZGF0YXR5cGUvRmFjdG9yeUZpbmRlci5qYXZhIGIvc3JjL2phdmF4L3htbC9kYXRhdHlwZS9GYWN0b3J5RmluZGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGNlOTgyMTUuLjAwMDAwMDAKLS0tIGEvc3JjL2phdmF4L3htbC9kYXRhdHlwZS9GYWN0b3J5RmluZGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzMTEgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwNCwgMjAxMywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotcGFja2FnZSBqYXZheC54bWwuZGF0YXR5cGU7Ci0KLWltcG9ydCBqYXZhLmlvLkZpbGU7Ci1pbXBvcnQgamF2YS5zZWN1cml0eS5BY2Nlc3NDb250cm9sbGVyOwotaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpdmlsZWdlZEFjdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7Ci1pbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7Ci1pbXBvcnQgamF2YS51dGlsLlNlcnZpY2VDb25maWd1cmF0aW9uRXJyb3I7Ci1pbXBvcnQgamF2YS51dGlsLlNlcnZpY2VMb2FkZXI7Ci0KLS8qKgotICogPHA+SW1wbGVtZW50cyBwbHVnZ2FibGUgRGF0YXR5cGVzLjwvcD4KLSAqCi0gKiA8cD5UaGlzIGNsYXNzIGlzIGR1cGxpY2F0ZWQgZm9yIGVhY2ggSkFYUCBzdWJwYWNrYWdlIHNvIGtlZXAgaXQgaW4KLSAqIHN5bmMuICBJdCBpcyBwYWNrYWdlIHByaXZhdGUgZm9yIHNlY3VyZSBjbGFzcyBsb2FkaW5nLjwvcD4KLSAqCi0gKiBAYXV0aG9yIFNhbnRpYWdvLlBlcmljYXNHZWVydHNlbkBzdW4uY29tCi0gKi8KLWNsYXNzIEZhY3RvcnlGaW5kZXIgewotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBERUZBVUxUX1BBQ0tBR0UgPSAiY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbCI7Ci0KLSAgICAvKioKLSAgICAgKiBJbnRlcm5hbCBkZWJ1ZyBmbGFnLgotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gZGVidWcgPSBmYWxzZTsKLQotICAgIC8qKgotICAgICAqIENhY2hlIGZvciBwcm9wZXJ0aWVzIGluIGphdmEuaG9tZS9saWIvamF4cC5wcm9wZXJ0aWVzCi0gICAgICovCi0gICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgUHJvcGVydGllcyBjYWNoZVByb3BzID0gbmV3IFByb3BlcnRpZXMoKTsKLQotICAgIC8qKgotICAgICAqIEZsYWcgaW5kaWNhdGluZyBpZiBwcm9wZXJ0aWVzIGZyb20gamF2YS5ob21lL2xpYi9qYXhwLnByb3BlcnRpZXMKLSAgICAgKiBoYXZlIGJlZW4gY2FjaGVkLgotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIHZvbGF0aWxlIGJvb2xlYW4gZmlyc3RUaW1lID0gdHJ1ZTsKLQotICAgIC8qKgotICAgICAqIFNlY3VyaXR5IHN1cHBvcnQgY2xhc3MgdXNlIHRvIGNoZWNrIGFjY2VzcyBjb250cm9sIGJlZm9yZQotICAgICAqIGdldHRpbmcgY2VydGFpbiBzeXN0ZW0gcmVzb3VyY2VzLgotICAgICAqLwotICAgIHByaXZhdGUgZmluYWwgc3RhdGljIFNlY3VyaXR5U3VwcG9ydCBzcyA9IG5ldyBTZWN1cml0eVN1cHBvcnQoKTsKLQotICAgIC8vIERlZmluZSBzeXN0ZW0gcHJvcGVydHkgImpheHAuZGVidWciIHRvIGdldCBvdXRwdXQKLSAgICBzdGF0aWMgewotICAgICAgICAvLyBVc2UgdHJ5L2NhdGNoIGJsb2NrIHRvIHN1cHBvcnQgYXBwbGV0cywgd2hpY2ggdGhyb3dzCi0gICAgICAgIC8vIFNlY3VyaXR5RXhjZXB0aW9uIG91dCBvZiB0aGlzIGNvZGUuCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBTdHJpbmcgdmFsID0gc3MuZ2V0U3lzdGVtUHJvcGVydHkoImpheHAuZGVidWciKTsKLSAgICAgICAgICAgIC8vIEFsbG93IHNpbXBseSBzZXR0aW5nIHRoZSBwcm9wIHRvIHR1cm4gb24gZGVidWcKLSAgICAgICAgICAgIGRlYnVnID0gdmFsICE9IG51bGwgJiYgISJmYWxzZSIuZXF1YWxzKHZhbCk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIHNlKSB7Ci0gICAgICAgICAgICBkZWJ1ZyA9IGZhbHNlOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBkUHJpbnQoU3RyaW5nIG1zZykgewotICAgICAgICBpZiAoZGVidWcpIHsKLSAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiSkFYUDogIiArIG1zZyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBdHRlbXB0IHRvIGxvYWQgYSBjbGFzcyB1c2luZyB0aGUgY2xhc3MgbG9hZGVyIHN1cHBsaWVkLiBJZiB0aGF0IGZhaWxzCi0gICAgICogYW5kIGZhbGwgYmFjayBpcyBlbmFibGVkLCB0aGUgY3VycmVudCAoaS5lLiBib290c3RyYXApIGNsYXNzIGxvYWRlciBpcwotICAgICAqIHRyaWVkLgotICAgICAqCi0gICAgICogSWYgdGhlIGNsYXNzIGxvYWRlciBzdXBwbGllZCBpcyA8Y29kZT5udWxsPC9jb2RlPiwgZmlyc3QgdHJ5IHVzaW5nIHRoZQotICAgICAqIGNvbnRleHQgY2xhc3MgbG9hZGVyIGZvbGxvd2VkIGJ5IHRoZSBjdXJyZW50IChpLmUuIGJvb3RzdHJhcCkgY2xhc3MKLSAgICAgKiBsb2FkZXIuCi0gICAgICoKLSAgICAgKiBVc2UgYm9vdHN0cmFwIGNsYXNzTG9hZGVyIGlmIGNsID0gbnVsbCBhbmQgdXNlQlNDbHNMb2FkZXIgaXMgdHJ1ZQotICAgICAqLwotICAgIHN0YXRpYyBwcml2YXRlIENsYXNzPD8+IGdldFByb3ZpZGVyQ2xhc3MoU3RyaW5nIGNsYXNzTmFtZSwgQ2xhc3NMb2FkZXIgY2wsCi0gICAgICAgICAgICBib29sZWFuIGRvRmFsbGJhY2ssIGJvb2xlYW4gdXNlQlNDbHNMb2FkZXIpIHRocm93cyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uCi0gICAgewotICAgICAgICB0cnkgewotICAgICAgICAgICAgaWYgKGNsID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBpZiAodXNlQlNDbHNMb2FkZXIpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIENsYXNzLmZvck5hbWUoY2xhc3NOYW1lLCBmYWxzZSwgRmFjdG9yeUZpbmRlci5jbGFzcy5nZXRDbGFzc0xvYWRlcigpKTsKLSAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICBjbCA9IHNzLmdldENvbnRleHRDbGFzc0xvYWRlcigpOwotICAgICAgICAgICAgICAgICAgICBpZiAoY2wgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IENsYXNzTm90Rm91bmRFeGNlcHRpb24oKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBDbGFzcy5mb3JOYW1lKGNsYXNzTmFtZSwgZmFsc2UsIGNsKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIHJldHVybiBDbGFzcy5mb3JOYW1lKGNsYXNzTmFtZSwgZmFsc2UsIGNsKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBlMSkgewotICAgICAgICAgICAgaWYgKGRvRmFsbGJhY2spIHsKLSAgICAgICAgICAgICAgICAvLyBVc2UgY3VycmVudCBjbGFzcyBsb2FkZXIgLSBzaG91bGQgYWx3YXlzIGJlIGJvb3RzdHJhcCBDTAotICAgICAgICAgICAgICAgIHJldHVybiBDbGFzcy5mb3JOYW1lKGNsYXNzTmFtZSwgZmFsc2UsIEZhY3RvcnlGaW5kZXIuY2xhc3MuZ2V0Q2xhc3NMb2FkZXIoKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBlMTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIENyZWF0ZSBhbiBpbnN0YW5jZSBvZiBhIGNsYXNzLiBEZWxlZ2F0ZXMgdG8gbWV0aG9kCi0gICAgICogPGNvZGU+Z2V0UHJvdmlkZXJDbGFzcygpPC9jb2RlPiBpbiBvcmRlciB0byBsb2FkIHRoZSBjbGFzcy4KLSAgICAgKgotICAgICAqIEBwYXJhbSB0eXBlIEJhc2UgY2xhc3MgLyBTZXJ2aWNlIGludGVyZmFjZSAgb2YgdGhlIGZhY3RvcnkgdG8KLSAgICAgKiAgICAgICAgICAgICBpbnN0YW50aWF0ZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjbGFzc05hbWUgTmFtZSBvZiB0aGUgY29uY3JldGUgY2xhc3MgY29ycmVzcG9uZGluZyB0byB0aGUKLSAgICAgKiBzZXJ2aWNlIHByb3ZpZGVyCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY2wgPGNvZGU+Q2xhc3NMb2FkZXI8L2NvZGU+IHVzZWQgdG8gbG9hZCB0aGUgZmFjdG9yeSBjbGFzcy4gSWYgPGNvZGU+bnVsbDwvY29kZT4KLSAgICAgKiBjdXJyZW50IDxjb2RlPlRocmVhZDwvY29kZT4ncyBjb250ZXh0IGNsYXNzTG9hZGVyIGlzIHVzZWQgdG8gbG9hZCB0aGUgZmFjdG9yeSBjbGFzcy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBkb0ZhbGxiYWNrIFRydWUgaWYgdGhlIGN1cnJlbnQgQ2xhc3NMb2FkZXIgc2hvdWxkIGJlIHRyaWVkIGFzCi0gICAgICogYSBmYWxsYmFjayBpZiB0aGUgY2xhc3MgaXMgbm90IGZvdW5kIHVzaW5nIGNsCi0gICAgICovCi0gICAgc3RhdGljIDxUPiBUIG5ld0luc3RhbmNlKENsYXNzPFQ+IHR5cGUsIFN0cmluZyBjbGFzc05hbWUsIENsYXNzTG9hZGVyIGNsLCBib29sZWFuIGRvRmFsbGJhY2spCi0gICAgICAgIHRocm93cyAgRGF0YXR5cGVDb25maWd1cmF0aW9uRXhjZXB0aW9uCi0gICAgewotICAgICAgICByZXR1cm4gbmV3SW5zdGFuY2UodHlwZSwgY2xhc3NOYW1lLCBjbCwgZG9GYWxsYmFjaywgZmFsc2UpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENyZWF0ZSBhbiBpbnN0YW5jZSBvZiBhIGNsYXNzLiBEZWxlZ2F0ZXMgdG8gbWV0aG9kCi0gICAgICogPGNvZGU+Z2V0UHJvdmlkZXJDbGFzcygpPC9jb2RlPiBpbiBvcmRlciB0byBsb2FkIHRoZSBjbGFzcy4KLSAgICAgKgotICAgICAqIEBwYXJhbSB0eXBlIEJhc2UgY2xhc3MgLyBTZXJ2aWNlIGludGVyZmFjZSAgb2YgdGhlIGZhY3RvcnkgdG8KLSAgICAgKiAgICAgICAgICAgICBpbnN0YW50aWF0ZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjbGFzc05hbWUgTmFtZSBvZiB0aGUgY29uY3JldGUgY2xhc3MgY29ycmVzcG9uZGluZyB0byB0aGUKLSAgICAgKiBzZXJ2aWNlIHByb3ZpZGVyCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY2wgQ2xhc3NMb2FkZXIgdG8gdXNlIHRvIGxvYWQgdGhlIGNsYXNzLCBudWxsIG1lYW5zIHRvIHVzZQotICAgICAqIHRoZSBib290c3RyYXAgQ2xhc3NMb2FkZXIKLSAgICAgKgotICAgICAqIEBwYXJhbSBkb0ZhbGxiYWNrIFRydWUgaWYgdGhlIGN1cnJlbnQgQ2xhc3NMb2FkZXIgc2hvdWxkIGJlIHRyaWVkIGFzCi0gICAgICogYSBmYWxsYmFjayBpZiB0aGUgY2xhc3MgaXMgbm90IGZvdW5kIHVzaW5nIGNsCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdXNlQlNDbHNMb2FkZXIgVHJ1ZSBpZiBjbD1udWxsIGFjdHVhbGx5IG1lYW50IGJvb3RzdHJhcCBjbGFzc0xvYWRlci4gVGhpcyBwYXJhbWV0ZXIKLSAgICAgKiBpcyBuZWVkZWQgc2luY2UgRG9jdW1lbnRCdWlsZGVyRmFjdG9yeS9TQVhQYXJzZXJGYWN0b3J5IGRlZmluZWQgbnVsbCBhcyBjb250ZXh0IGNsYXNzTG9hZGVyLgotICAgICAqLwotICAgIHN0YXRpYyA8VD4gVCBuZXdJbnN0YW5jZShDbGFzczxUPiB0eXBlLCBTdHJpbmcgY2xhc3NOYW1lLCBDbGFzc0xvYWRlciBjbCwKLSAgICAgICAgICAgIGJvb2xlYW4gZG9GYWxsYmFjaywgYm9vbGVhbiB1c2VCU0Nsc0xvYWRlcikKLSAgICAgICAgdGhyb3dzIERhdGF0eXBlQ29uZmlndXJhdGlvbkV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgYXNzZXJ0IHR5cGUgIT0gbnVsbDsKLQotICAgICAgICAvLyBtYWtlIHN1cmUgd2UgaGF2ZSBhY2Nlc3MgdG8gcmVzdHJpY3RlZCBwYWNrYWdlcwotICAgICAgICBpZiAoU3lzdGVtLmdldFNlY3VyaXR5TWFuYWdlcigpICE9IG51bGwpIHsKLSAgICAgICAgICAgIGlmIChjbGFzc05hbWUgIT0gbnVsbCAmJiBjbGFzc05hbWUuc3RhcnRzV2l0aChERUZBVUxUX1BBQ0tBR0UpKSB7Ci0gICAgICAgICAgICAgICAgY2wgPSBudWxsOwotICAgICAgICAgICAgICAgIHVzZUJTQ2xzTG9hZGVyID0gdHJ1ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBDbGFzczw/PiBwcm92aWRlckNsYXNzID0gZ2V0UHJvdmlkZXJDbGFzcyhjbGFzc05hbWUsIGNsLCBkb0ZhbGxiYWNrLCB1c2VCU0Nsc0xvYWRlcik7Ci0gICAgICAgICAgICBpZiAoIXR5cGUuaXNBc3NpZ25hYmxlRnJvbShwcm92aWRlckNsYXNzKSkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBDbGFzc0Nhc3RFeGNlcHRpb24oY2xhc3NOYW1lICsgIiBjYW5ub3QgYmUgY2FzdCB0byAiICsgdHlwZS5nZXROYW1lKCkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgT2JqZWN0IGluc3RhbmNlID0gcHJvdmlkZXJDbGFzcy5uZXdJbnN0YW5jZSgpOwotICAgICAgICAgICAgaWYgKGRlYnVnKSB7ICAgIC8vIEV4dHJhIGNoZWNrIHRvIGF2b2lkIGNvbXB1dGluZyBjbCBzdHJpbmdzCi0gICAgICAgICAgICAgICAgZFByaW50KCJjcmVhdGVkIG5ldyBpbnN0YW5jZSBvZiAiICsgcHJvdmlkZXJDbGFzcyArCi0gICAgICAgICAgICAgICAgICAgICAgICIgdXNpbmcgQ2xhc3NMb2FkZXI6ICIgKyBjbCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gdHlwZS5jYXN0KGluc3RhbmNlKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB4KSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgRGF0YXR5cGVDb25maWd1cmF0aW9uRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICJQcm92aWRlciAiICsgY2xhc3NOYW1lICsgIiBub3QgZm91bmQiLCB4KTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIHgpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBEYXRhdHlwZUNvbmZpZ3VyYXRpb25FeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgIlByb3ZpZGVyICIgKyBjbGFzc05hbWUgKyAiIGNvdWxkIG5vdCBiZSBpbnN0YW50aWF0ZWQ6ICIgKyB4LAotICAgICAgICAgICAgICAgIHgpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRmluZHMgdGhlIGltcGxlbWVudGF0aW9uIENsYXNzIG9iamVjdCBpbiB0aGUgc3BlY2lmaWVkIG9yZGVyLiAgTWFpbgotICAgICAqIGVudHJ5IHBvaW50LgotICAgICAqIEByZXR1cm4gQ2xhc3Mgb2JqZWN0IG9mIGZhY3RvcnksIG5ldmVyIG51bGwKLSAgICAgKgotICAgICAqIEBwYXJhbSB0eXBlICAgICAgICAgICAgICAgICAgQmFzZSBjbGFzcyAvIFNlcnZpY2UgaW50ZXJmYWNlICBvZiB0aGUKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhY3RvcnkgdG8gZmluZC4KLSAgICAgKiBAcGFyYW0gZmFsbGJhY2tDbGFzc05hbWUgICAgIEltcGxlbWVudGF0aW9uIGNsYXNzIG5hbWUsIGlmIG5vdGhpbmcgZWxzZQotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXMgZm91bmQuICBVc2UgbnVsbCB0byBtZWFuIG5vIGZhbGxiYWNrLgotICAgICAqCi0gICAgICogUGFja2FnZSBwcml2YXRlIHNvIHRoaXMgY29kZSBjYW4gYmUgc2hhcmVkLgotICAgICAqLwotICAgIHN0YXRpYyA8VD4gVCBmaW5kKENsYXNzPFQ+IHR5cGUsIFN0cmluZyBmYWxsYmFja0NsYXNzTmFtZSkKLSAgICAgICAgdGhyb3dzIERhdGF0eXBlQ29uZmlndXJhdGlvbkV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgZmluYWwgU3RyaW5nIGZhY3RvcnlJZCA9IHR5cGUuZ2V0TmFtZSgpOwotICAgICAgICBkUHJpbnQoImZpbmQgZmFjdG9yeUlkID0iICsgZmFjdG9yeUlkKTsKLQotICAgICAgICAvLyBVc2UgdGhlIHN5c3RlbSBwcm9wZXJ0eSBmaXJzdAotICAgICAgICB0cnkgewotICAgICAgICAgICAgU3RyaW5nIHN5c3RlbVByb3AgPSBzcy5nZXRTeXN0ZW1Qcm9wZXJ0eShmYWN0b3J5SWQpOwotICAgICAgICAgICAgaWYgKHN5c3RlbVByb3AgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGRQcmludCgiZm91bmQgc3lzdGVtIHByb3BlcnR5LCB2YWx1ZT0iICsgc3lzdGVtUHJvcCk7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIG5ld0luc3RhbmNlKHR5cGUsIHN5c3RlbVByb3AsIG51bGwsIHRydWUpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBzZSkgewotICAgICAgICAgICAgaWYgKGRlYnVnKSBzZS5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIHRyeSB0byByZWFkIGZyb20gJGphdmEuaG9tZS9saWIvamF4cC5wcm9wZXJ0aWVzCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBpZiAoZmlyc3RUaW1lKSB7Ci0gICAgICAgICAgICAgICAgc3luY2hyb25pemVkIChjYWNoZVByb3BzKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChmaXJzdFRpbWUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBjb25maWdGaWxlID0gc3MuZ2V0U3lzdGVtUHJvcGVydHkoImphdmEuaG9tZSIpICsgRmlsZS5zZXBhcmF0b3IgKwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICJsaWIiICsgRmlsZS5zZXBhcmF0b3IgKyAiamF4cC5wcm9wZXJ0aWVzIjsKLSAgICAgICAgICAgICAgICAgICAgICAgIEZpbGUgZiA9IG5ldyBGaWxlKGNvbmZpZ0ZpbGUpOwotICAgICAgICAgICAgICAgICAgICAgICAgZmlyc3RUaW1lID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3MuZG9lc0ZpbGVFeGlzdChmKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRQcmludCgiUmVhZCBwcm9wZXJ0aWVzIGZpbGUgIitmKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWNoZVByb3BzLmxvYWQoc3MuZ2V0RmlsZUlucHV0U3RyZWFtKGYpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGZpbmFsIFN0cmluZyBmYWN0b3J5Q2xhc3NOYW1lID0gY2FjaGVQcm9wcy5nZXRQcm9wZXJ0eShmYWN0b3J5SWQpOwotCi0gICAgICAgICAgICBpZiAoZmFjdG9yeUNsYXNzTmFtZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZFByaW50KCJmb3VuZCBpbiAkamF2YS5ob21lL2pheHAucHJvcGVydGllcywgdmFsdWU9IiArIGZhY3RvcnlDbGFzc05hbWUpOwotICAgICAgICAgICAgICAgIHJldHVybiBuZXdJbnN0YW5jZSh0eXBlLCBmYWN0b3J5Q2xhc3NOYW1lLCBudWxsLCB0cnVlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7Ci0gICAgICAgICAgICBpZiAoZGVidWcpIGV4LnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gVHJ5IEphciBTZXJ2aWNlIFByb3ZpZGVyIE1lY2hhbmlzbQotICAgICAgICBmaW5hbCBUIHByb3ZpZGVyID0gZmluZFNlcnZpY2VQcm92aWRlcih0eXBlKTsKLSAgICAgICAgaWYgKHByb3ZpZGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBwcm92aWRlcjsKLSAgICAgICAgfQotICAgICAgICBpZiAoZmFsbGJhY2tDbGFzc05hbWUgPT0gbnVsbCkgewotICAgICAgICAgICAgdGhyb3cgbmV3IERhdGF0eXBlQ29uZmlndXJhdGlvbkV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAiUHJvdmlkZXIgZm9yICIgKyBmYWN0b3J5SWQgKyAiIGNhbm5vdCBiZSBmb3VuZCIpOwotICAgICAgICB9Ci0KLSAgICAgICAgZFByaW50KCJsb2FkZWQgZnJvbSBmYWxsYmFjayB2YWx1ZTogIiArIGZhbGxiYWNrQ2xhc3NOYW1lKTsKLSAgICAgICAgcmV0dXJuIG5ld0luc3RhbmNlKHR5cGUsIGZhbGxiYWNrQ2xhc3NOYW1lLCBudWxsLCB0cnVlKTsKLSAgICB9Ci0KLSAgICAvKgotICAgICAqIFRyeSB0byBmaW5kIHByb3ZpZGVyIHVzaW5nIHRoZSBTZXJ2aWNlTG9hZGVyIEFQSQotICAgICAqCi0gICAgICogQHBhcmFtIHR5cGUgQmFzZSBjbGFzcyAvIFNlcnZpY2UgaW50ZXJmYWNlICBvZiB0aGUgZmFjdG9yeSB0byBmaW5kLgotICAgICAqCi0gICAgICogQHJldHVybiBpbnN0YW5jZSBvZiBwcm92aWRlciBjbGFzcyBpZiBmb3VuZCBvciBudWxsCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgPFQ+IFQgZmluZFNlcnZpY2VQcm92aWRlcihmaW5hbCBDbGFzczxUPiB0eXBlKQotICAgICAgICAgICAgdGhyb3dzIERhdGF0eXBlQ29uZmlndXJhdGlvbkV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIHJldHVybiBBY2Nlc3NDb250cm9sbGVyLmRvUHJpdmlsZWdlZChuZXcgUHJpdmlsZWdlZEFjdGlvbjxUPigpIHsKLSAgICAgICAgICAgICAgICBwdWJsaWMgVCBydW4oKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZpbmFsIFNlcnZpY2VMb2FkZXI8VD4gc2VydmljZUxvYWRlciA9IFNlcnZpY2VMb2FkZXIubG9hZCh0eXBlKTsKLSAgICAgICAgICAgICAgICAgICAgZmluYWwgSXRlcmF0b3I8VD4gaXRlcmF0b3IgPSBzZXJ2aWNlTG9hZGVyLml0ZXJhdG9yKCk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChpdGVyYXRvci5oYXNOZXh0KCkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpdGVyYXRvci5uZXh0KCk7Ci0gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0pOwotICAgICAgICB9IGNhdGNoKFNlcnZpY2VDb25maWd1cmF0aW9uRXJyb3IgZSkgewotICAgICAgICAgICAgZmluYWwgRGF0YXR5cGVDb25maWd1cmF0aW9uRXhjZXB0aW9uIGVycm9yID0KLSAgICAgICAgICAgICAgICAgICAgbmV3IERhdGF0eXBlQ29uZmlndXJhdGlvbkV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgICAgICJQcm92aWRlciBmb3IgIiArIHR5cGUgKyAiIGNhbm5vdCBiZSBmb3VuZCIsIGUpOwotICAgICAgICAgICAgdGhyb3cgZXJyb3I7Ci0gICAgICAgIH0KLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9qYXZheC94bWwvZGF0YXR5cGUvU2VjdXJpdHlTdXBwb3J0LmphdmEgYi9zcmMvamF2YXgveG1sL2RhdGF0eXBlL1NlY3VyaXR5U3VwcG9ydC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxMjdkYjIyLi4wMDAwMDAwCi0tLSBhL3NyYy9qYXZheC94bWwvZGF0YXR5cGUvU2VjdXJpdHlTdXBwb3J0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMDYgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotcGFja2FnZSBqYXZheC54bWwuZGF0YXR5cGU7Ci0KLWltcG9ydCBqYXZhLnNlY3VyaXR5Lio7Ci1pbXBvcnQgamF2YS5uZXQuKjsKLWltcG9ydCBqYXZhLmlvLio7Ci1pbXBvcnQgamF2YS51dGlsLio7Ci0KLS8qKgotICogVGhpcyBjbGFzcyBpcyBkdXBsaWNhdGVkIGZvciBlYWNoIEpBWFAgc3VicGFja2FnZSBzbyBrZWVwIGl0IGluIHN5bmMuCi0gKiBJdCBpcyBwYWNrYWdlIHByaXZhdGUgYW5kIHRoZXJlZm9yZSBpcyBub3QgZXhwb3NlZCBhcyBwYXJ0IG9mIHRoZSBKQVhQCi0gKiBBUEkuCi0gKgotICogU2VjdXJpdHkgcmVsYXRlZCBtZXRob2RzIHRoYXQgb25seSB3b3JrIG9uIEoyU0UgMS4yIGFuZCBuZXdlci4KLSAqLwotY2xhc3MgU2VjdXJpdHlTdXBwb3J0ICB7Ci0KLQotICAgIENsYXNzTG9hZGVyIGdldENvbnRleHRDbGFzc0xvYWRlcigpIHsKLSAgICAgICAgcmV0dXJuIChDbGFzc0xvYWRlcikKLSAgICAgICAgICAgICAgICBBY2Nlc3NDb250cm9sbGVyLmRvUHJpdmlsZWdlZChuZXcgUHJpdmlsZWdlZEFjdGlvbigpIHsKLSAgICAgICAgICAgIHB1YmxpYyBPYmplY3QgcnVuKCkgewotICAgICAgICAgICAgICAgIENsYXNzTG9hZGVyIGNsID0gbnVsbDsKLSAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICBjbCA9IFRocmVhZC5jdXJyZW50VGhyZWFkKCkuZ2V0Q29udGV4dENsYXNzTG9hZGVyKCk7Ci0gICAgICAgICAgICAgICAgfSBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gZXgpIHsgfQotICAgICAgICAgICAgICAgIHJldHVybiBjbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSk7Ci0gICAgfQotCi0gICAgU3RyaW5nIGdldFN5c3RlbVByb3BlcnR5KGZpbmFsIFN0cmluZyBwcm9wTmFtZSkgewotICAgICAgICByZXR1cm4gKFN0cmluZykKLSAgICAgICAgICAgIEFjY2Vzc0NvbnRyb2xsZXIuZG9Qcml2aWxlZ2VkKG5ldyBQcml2aWxlZ2VkQWN0aW9uKCkgewotICAgICAgICAgICAgICAgIHB1YmxpYyBPYmplY3QgcnVuKCkgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gU3lzdGVtLmdldFByb3BlcnR5KHByb3BOYW1lKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9KTsKLSAgICB9Ci0KLSAgICBGaWxlSW5wdXRTdHJlYW0gZ2V0RmlsZUlucHV0U3RyZWFtKGZpbmFsIEZpbGUgZmlsZSkKLSAgICAgICAgdGhyb3dzIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIHJldHVybiAoRmlsZUlucHV0U3RyZWFtKQotICAgICAgICAgICAgICAgIEFjY2Vzc0NvbnRyb2xsZXIuZG9Qcml2aWxlZ2VkKG5ldyBQcml2aWxlZ2VkRXhjZXB0aW9uQWN0aW9uKCkgewotICAgICAgICAgICAgICAgICAgICBwdWJsaWMgT2JqZWN0IHJ1bigpIHRocm93cyBGaWxlTm90Rm91bmRFeGNlcHRpb24gewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBGaWxlSW5wdXRTdHJlYW0oZmlsZSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9KTsKLSAgICAgICAgfSBjYXRjaCAoUHJpdmlsZWdlZEFjdGlvbkV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICB0aHJvdyAoRmlsZU5vdEZvdW5kRXhjZXB0aW9uKWUuZ2V0RXhjZXB0aW9uKCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBJbnB1dFN0cmVhbSBnZXRSZXNvdXJjZUFzU3RyZWFtKGZpbmFsIENsYXNzTG9hZGVyIGNsLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBuYW1lKQotICAgIHsKLSAgICAgICAgcmV0dXJuIChJbnB1dFN0cmVhbSkKLSAgICAgICAgICAgIEFjY2Vzc0NvbnRyb2xsZXIuZG9Qcml2aWxlZ2VkKG5ldyBQcml2aWxlZ2VkQWN0aW9uKCkgewotICAgICAgICAgICAgICAgIHB1YmxpYyBPYmplY3QgcnVuKCkgewotICAgICAgICAgICAgICAgICAgICBJbnB1dFN0cmVhbSByaXM7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChjbCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByaXMgPSBPYmplY3QuY2xhc3MuZ2V0UmVzb3VyY2VBc1N0cmVhbShuYW1lKTsKLSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJpcyA9IGNsLmdldFJlc291cmNlQXNTdHJlYW0obmFtZSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJpczsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9KTsKLSAgICB9Ci0KLSAgICBib29sZWFuIGRvZXNGaWxlRXhpc3QoZmluYWwgRmlsZSBmKSB7Ci0gICAgcmV0dXJuICgoQm9vbGVhbikKLSAgICAgICAgICAgIEFjY2Vzc0NvbnRyb2xsZXIuZG9Qcml2aWxlZ2VkKG5ldyBQcml2aWxlZ2VkQWN0aW9uKCkgewotICAgICAgICAgICAgICAgIHB1YmxpYyBPYmplY3QgcnVuKCkgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEJvb2xlYW4oZi5leGlzdHMoKSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfSkpLmJvb2xlYW5WYWx1ZSgpOwotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmF4L3htbC9kYXRhdHlwZS9YTUxHcmVnb3JpYW5DYWxlbmRhci5qYXZhIGIvc3JjL2phdmF4L3htbC9kYXRhdHlwZS9YTUxHcmVnb3JpYW5DYWxlbmRhci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjZTE2YjljLi4wMDAwMDAwCi0tLSBhL3NyYy9qYXZheC94bWwvZGF0YXR5cGUvWE1MR3JlZ29yaWFuQ2FsZW5kYXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEwNjIgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwMywgMjAwNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotcGFja2FnZSBqYXZheC54bWwuZGF0YXR5cGU7Ci0KLWltcG9ydCBqYXZheC54bWwubmFtZXNwYWNlLlFOYW1lOwotaW1wb3J0IGphdmEubWF0aC5CaWdEZWNpbWFsOwotaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOwotaW1wb3J0IGphdmEudXRpbC5UaW1lWm9uZTsKLWltcG9ydCBqYXZhLnV0aWwuR3JlZ29yaWFuQ2FsZW5kYXI7Ci0KLS8qKgotICogPHA+UmVwcmVzZW50YXRpb24gZm9yIFczQyBYTUwgU2NoZW1hIDEuMCBkYXRlL3RpbWUgZGF0YXR5cGVzLgotICogU3BlY2lmaWNhbGx5LCB0aGVzZSBkYXRlL3RpbWUgZGF0YXR5cGVzIGFyZQotICoge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0RBVEVUSU1FfSwKLSAqIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNUSU1FfSwKLSAqIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNEQVRFfSwKLSAqIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNHWUVBUk1PTlRIfSwKLSAqIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNHTU9OVEhEQVl9LAotICoge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0dZRUFSfSwKLSAqIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNHTU9OVEh9LCBhbmQKLSAqIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNHREFZfQotICogZGVmaW5lZCBpbiB0aGUgWE1MIE5hbWVzcGFjZQotICogPGNvZGU+Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hIjwvY29kZT4uCi0gKiBUaGVzZSBkYXRhdHlwZXMgYXJlIG5vcm1hdGl2ZWx5IGRlZmluZWQgaW4KLSAqIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3htbHNjaGVtYS0yLyNkYXRlVGltZSI+VzNDIFhNTCBTY2hlbWEgMS4wIFBhcnQgMiwgU2VjdGlvbiAzLjIuNy0xNDwvYT4uPC9wPgotICoKLSAqIDxwPlRoZSB0YWJsZSBiZWxvdyBkZWZpbmVzIHRoZSBtYXBwaW5nIGJldHdlZW4gWE1MIFNjaGVtYSAxLjAKLSAqIGRhdGUvdGltZSBkYXRhdHlwZSBmaWVsZHMgYW5kIHRoaXMgY2xhc3MnIGZpZWxkcy4gSXQgYWxzbyBzdW1tYXJpemVzCi0gKiB0aGUgdmFsdWUgY29uc3RyYWludHMgZm9yIHRoZSBkYXRlIGFuZCB0aW1lIGZpZWxkcyBkZWZpbmVkIGluCi0gKiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94bWxzY2hlbWEtMi8jaXNvZm9ybWF0cyI+VzNDIFhNTCBTY2hlbWEgMS4wIFBhcnQgMiwgQXBwZW5kaXggRCwKLSAqIDxpPklTTyA4NjAxIERhdGUgYW5kIFRpbWUgRm9ybWF0czwvaT48L2E+LjwvcD4KLSAqCi0gKiA8YSBuYW1lPSJkYXRldGltZWZpZWxkbWFwcGluZyIvPgotICogPHRhYmxlIGJvcmRlcj0iMiIgcnVsZXM9ImFsbCIgY2VsbHBhZGRpbmc9IjIiPgotICogICA8dGhlYWQ+Ci0gKiAgICAgPHRyPgotICogICAgICAgPHRoIGFsaWduPSJjZW50ZXIiIGNvbHNwYW49IjMiPgotICogICAgICAgICBEYXRlL1RpbWUgRGF0YXR5cGUgRmllbGQgTWFwcGluZyBCZXR3ZWVuIFhNTCBTY2hlbWEgMS4wIGFuZCBKYXZhIFJlcHJlc2VudGF0aW9uCi0gKiAgICAgICA8L3RoPgotICogICAgIDwvdHI+Ci0gKiAgIDwvdGhlYWQ+Ci0gKiAgIDx0Ym9keT4KLSAqICAgICA8dHI+Ci0gKiAgICAgICA8dGg+WE1MIFNjaGVtYSAxLjA8YnIvPgotICogICAgICAgICAgIGRhdGF0eXBlPGJyLz4KLSAqICAgICAgICAgICAgZmllbGQ8L3RoPgotICogICAgICAgPHRoPlJlbGF0ZWQ8YnIvPlhNTEdyZWdvcmlhbkNhbGVuZGFyPGJyLz5BY2Nlc3NvcihzKTwvdGg+Ci0gKiAgICAgICA8dGg+VmFsdWUgUmFuZ2U8L3RoPgotICogICAgIDwvdHI+Ci0gKiAgICAgPHRyPgotICogICAgICAgPHRkPjxhIG5hbWU9ImRhdGV0aW1lZmllbGQteWVhciIvPnllYXI8L3RkPgotICogICAgICAgPHRkPiB7QGxpbmsgI2dldFllYXIoKX0gKyB7QGxpbmsgI2dldEVvbigpfSBvcjxici8+Ci0gKiAgICAgICAgICAgIHtAbGluayAjZ2V0RW9uQW5kWWVhcn0KLSAqICAgICAgIDwvdGQ+Ci0gKiAgICAgICA8dGQ+IDxjb2RlPmdldFllYXIoKTwvY29kZT4gaXMgYSB2YWx1ZSBiZXR3ZWVuIC0oMTBeOS0xKSB0byAoMTBeOSktMQotICogICAgICAgICAgICBvciB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjRklFTERfVU5ERUZJTkVEfS48YnIvPgotICogICAgICAgICAgICB7QGxpbmsgI2dldEVvbigpfSBpcyBoaWdoIG9yZGVyIHllYXIgdmFsdWUgaW4gYmlsbGlvbiBvZiB5ZWFycy48YnIvPgotICogICAgICAgICAgICA8Y29kZT5nZXRFb24oKTwvY29kZT4gaGFzIHZhbHVlcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gKDEwXjkpIG9yIGxlc3MgdGhhbiBvciBlcXVhbCB0byAtKDEwXjkpLgotICogICAgICAgICAgICBBIHZhbHVlIG9mIG51bGwgaW5kaWNhdGVzIGZpZWxkIGlzIHVuZGVmaW5lZC48L2JyPgotICogICAgICAgICAgICBHaXZlbiB0aGF0IDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMDUveG1sc2NoZW1hLWVycmF0YSNlMi02MyI+WE1MIFNjaGVtYSAxLjAgZXJyYXRhPC9hPiBzdGF0ZXMgdGhhdCB0aGUgeWVhciB6ZXJvCi0gKiAgICAgICAgICAgIHdpbGwgYmUgYSB2YWxpZCBsZXhpY2FsIHZhbHVlIGluIGEgZnV0dXJlIHZlcnNpb24gb2YgWE1MIFNjaGVtYSwKLSAqICAgICAgICAgICAgdGhpcyBjbGFzcyBhbGxvd3MgdGhlIHllYXIgZmllbGQgdG8gYmUgc2V0IHRvIHplcm8uIE90aGVyd2lzZSwKLSAqICAgICAgICAgICAgdGhlIHllYXIgZmllbGQgdmFsdWUgaXMgaGFuZGxlZCBleGFjdGx5IGFzIGRlc2NyaWJlZAotICogICAgICAgICAgICBpbiB0aGUgZXJyYXRhIGFuZCBbSVNPLTg2MDEtMTk4OF0uIE5vdGUgdGhhdCBXM0MgWE1MIFNjaGVtYSAxLjAKLSAqICAgICAgICAgICAgdmFsaWRhdGlvbiBkb2VzIG5vdCBhbGxvdyBmb3IgdGhlIHllYXIgZmllbGQgdG8gaGF2ZSBhIHZhbHVlIG9mIHplcm8uCi0gKiAgICAgICAgICAgIDwvdGQ+Ci0gKiAgICAgPC90cj4KLSAqICAgICA8dHI+Ci0gKiAgICAgICA8dGQ+PGEgbmFtZT0iZGF0ZXRpbWVmaWVsZC1tb250aCIvPm1vbnRoPC90ZD4KLSAqICAgICAgIDx0ZD4ge0BsaW5rICNnZXRNb250aCgpfSA8L3RkPgotICogICAgICAgPHRkPiAxIHRvIDEyIG9yIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNGSUVMRF9VTkRFRklORUR9IDwvdGQ+Ci0gKiAgICAgPC90cj4KLSAqICAgICA8dHI+Ci0gKiAgICAgICA8dGQ+PGEgbmFtZT0iZGF0ZXRpbWVmaWVsZC1kYXkiLz5kYXk8L3RkPgotICogICAgICAgPHRkPiB7QGxpbmsgI2dldERheSgpfSA8L3RkPgotICogICAgICAgPHRkPiBJbmRlcGVuZGVudCBvZiBtb250aCwgbWF4IHJhbmdlIGlzIDEgdG8gMzEgb3Ige0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0ZJRUxEX1VOREVGSU5FRH0uPGJyLz4KLSAqICAgICAgICAgICAgVGhlIG5vcm1hdGl2ZSB2YWx1ZSBjb25zdHJhaW50IHN0YXRlZCByZWxhdGl2ZSB0byBtb250aAotICogICAgICAgICAgICBmaWVsZCdzIHZhbHVlIGlzIGluIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3htbHNjaGVtYS0yLyNpc29mb3JtYXRzIj5XM0MgWE1MIFNjaGVtYSAxLjAgUGFydCAyLCBBcHBlbmRpeCBEPC9hPi4KLSAqICAgICAgIDwvdGQ+Ci0gKiAgICAgPC90cj4KLSAqICAgICA8dHI+Ci0gKiAgICAgICA8dGQ+PGEgbmFtZT0iZGF0ZXRpbWVmaWVsZC1ob3VyIi8+aG91cjwvdGQ+Ci0gKiAgICAgICA8dGQ+e0BsaW5rICNnZXRIb3VyKCl9PC90ZD4KLSAqICAgICAgIDx0ZD4KLSAqICAgICAgICAgMCB0byAyMyBvciB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjRklFTERfVU5ERUZJTkVEfS4KLSAqICAgICAgICAgQW4gaG91ciB2YWx1ZSBvZiAyNCBpcyBhbGxvd2VkIHRvIGJlIHNldCBpbiB0aGUgbGV4aWNhbCBzcGFjZSBwcm92aWRlZCB0aGUgbWludXRlIGFuZCBzZWNvbmQKLSAqICAgICAgICAgZmllbGQgdmFsdWVzIGFyZSB6ZXJvLiBIb3dldmVyLCBhbiBob3VyIHZhbHVlIG9mIDI0IGlzIG5vdCBhbGxvd2VkIGluIHZhbHVlIHNwYWNlIGFuZCB3aWxsIGJlCi0gKiAgICAgICAgIHRyYW5zZm9ybWVkIHRvIHJlcHJlc2VudCB0aGUgdmFsdWUgb2YgdGhlIGZpcnN0IGluc3RhbmNlIG9mIHRoZSBmb2xsb3dpbmcgZGF5IGFzIHBlcgotICogICAgICAgICA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94bWxzY2hlbWEtMi8jYnVpbHQtaW4tcHJpbWl0aXZlLWRhdGF0eXBlcyI+Ci0gKiAgICAgICAgIFhNTCBTY2hlbWEgUGFydCAyOiBEYXRhdHlwZXMgU2Vjb25kIEVkaXRpb24sIDMuMiBQcmltaXRpdmUgZGF0YXR5cGVzPC9hPi4KLSAqICAgICAgIDwvdGQ+Ci0gKiAgICAgPC90cj4KLSAqICAgICA8dHI+Ci0gKiAgICAgICA8dGQ+PGEgbmFtZT0iZGF0ZXRpbWVmaWVsZC1taW51dGUiLz5taW51dGU8L3RkPgotICogICAgICAgPHRkPiB7QGxpbmsgI2dldE1pbnV0ZSgpfSA8L3RkPgotICogICAgICAgPHRkPiAwIHRvIDU5IG9yIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNGSUVMRF9VTkRFRklORUR9IDwvdGQ+Ci0gKiAgICAgPC90cj4KLSAqICAgICA8dHI+Ci0gKiAgICAgICA8dGQ+PGEgbmFtZT0iZGF0ZXRpbWVmaWVsZC1zZWNvbmQiLz5zZWNvbmQ8L3RkPgotICogICAgICAgPHRkPgotICogICAgICAgICB7QGxpbmsgI2dldFNlY29uZCgpfSArIHtAbGluayAjZ2V0TWlsbGlzZWNvbmQoKX0vMTAwMCBvcjxici8+Ci0gKiAgICAgICAgIHtAbGluayAjZ2V0U2Vjb25kKCl9ICsge0BsaW5rICNnZXRGcmFjdGlvbmFsU2Vjb25kKCl9Ci0gKiAgICAgICA8L3RkPgotICogICAgICAgPHRkPgotICogICAgICAgICB7QGxpbmsgI2dldFNlY29uZCgpfSBmcm9tIDAgdG8gNjAgb3Ige0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0ZJRUxEX1VOREVGSU5FRH0uPGJyLz4KLSAqICAgICAgICAgPGk+KE5vdGU6IDYwIG9ubHkgYWxsb3dhYmxlIGZvciBsZWFwIHNlY29uZC4pPC9pPjxici8+Ci0gKiAgICAgICAgIHtAbGluayAjZ2V0RnJhY3Rpb25hbFNlY29uZCgpfSBhbGxvd3MgZm9yIGluZmluaXRlIHByZWNpc2lvbiBvdmVyIHRoZSByYW5nZSBmcm9tIDAuMCB0byAxLjAgd2hlbgotICogICAgICAgICB0aGUge0BsaW5rICNnZXRTZWNvbmQoKX0gaXMgZGVmaW5lZC48YnIvPgotICogICAgICAgICA8Y29kZT5GcmFjdGlvbmFsU2Vjb25kPC9jb2RlPiBpcyBvcHRpb25hbCBhbmQgaGFzIGEgdmFsdWUgb2YgPGNvZGU+bnVsbDwvY29kZT4gd2hlbiBpdCBpcyB1bmRlZmluZWQuPGJyIC8+Ci0gKiAgICAgICAgICAgIHtAbGluayAjZ2V0TWlsbGlzZWNvbmQoKX0gaXMgdGhlIGNvbnZlbmllbmNlCi0gKiAgICAgICAgICAgIG1pbGxpc2Vjb25kIHByZWNpc2lvbiBvZiB2YWx1ZSBvZiB7QGxpbmsgI2dldEZyYWN0aW9uYWxTZWNvbmQoKX0uCi0gKiAgICAgICA8L3RkPgotICogICAgIDwvdHI+Ci0gKiAgICAgPHRyPgotICogICAgICAgPHRkPjxhIG5hbWU9ImRhdGV0aW1lZmllbGQtdGltZXpvbmUiLz50aW1lem9uZTwvdGQ+Ci0gKiAgICAgICA8dGQ+IHtAbGluayAjZ2V0VGltZXpvbmUoKX0gPC90ZD4KLSAqICAgICAgIDx0ZD4gTnVtYmVyIG9mIG1pbnV0ZXMgb3Ige0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0ZJRUxEX1VOREVGSU5FRH0uCi0gKiAgICAgICAgIFZhbHVlIHJhbmdlIGZyb20gLTE0IGhvdXJzICgtMTQgKiA2MCBtaW51dGVzKSB0byAxNCBob3VycyAoMTQgKiA2MCBtaW51dGVzKS4KLSAqICAgICAgIDwvdGQ+Ci0gKiAgICAgPC90cj4KLSAqICAgPC90Ym9keT4KLSAqICA8L3RhYmxlPgotICoKLSAqIDxwPkFsbCBtYXhpbXVtIHZhbHVlIHNwYWNlIGNvbnN0cmFpbnRzIGxpc3RlZCBmb3IgdGhlIGZpZWxkcyBpbiB0aGUgdGFibGUKLSAqIGFib3ZlIGFyZSBjaGVja2VkIGJ5IGZhY3RvcnkgbWV0aG9kcywgQHtsaW5rIERhdGF0eXBlRmFjdG9yeX0sCi0gKiBzZXR0ZXIgbWV0aG9kcyBhbmQgcGFyc2UgbWV0aG9kcyBvZgotICogdGhpcyBjbGFzcy4gPGNvZGU+SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uPC9jb2RlPiBpcyB0aHJvd24gd2hlbiBhCi0gKiBwYXJhbWV0ZXIncyB2YWx1ZSBpcyBvdXRzaWRlIHRoZSB2YWx1ZSBjb25zdHJhaW50IGZvciB0aGUgZmllbGQgb3IKLSAqIGlmIHRoZSBjb21wb3NpdGUKLSAqIHZhbHVlcyBjb25zdGl0dXRlIGFuIGludmFsaWQgWE1MR3JlZ29yaWFuQ2FsZW5kYXIgaW5zdGFuY2UgKGZvciBleGFtcGxlLCBpZgotICogdGhlIDMxc3Qgb2YgSnVuZSBpcyBzcGVjaWZpZWQpLgotICogPC9wPgotICoKLSAqIDxwPlRoZSBmb2xsb3dpbmcgb3BlcmF0aW9ucyBhcmUgZGVmaW5lZCBmb3IgdGhpcyBjbGFzczoKLSAqIDx1bD4KLSAqICAgPGxpPmFjY2Vzc29ycy9tdXRhdG9ycyBmb3IgaW5kZXBlbmRlbnQgZGF0ZS90aW1lIGZpZWxkczwvbGk+Ci0gKiAgIDxsaT5jb252ZXJzaW9uIGJldHdlZW4gdGhpcyBjbGFzcyBhbmQgVzNDIFhNTCBTY2hlbWEgMS4wIGxleGljYWwgcmVwcmVzZW50YXRpb24sCi0gKiAgICAge0BsaW5rICN0b1N0cmluZygpfSwge0BsaW5rIERhdGF0eXBlRmFjdG9yeSNuZXdYTUxHcmVnb3JpYW5DYWxlbmRhcihTdHJpbmcgbGV4aWNhbFJlcHJlc2VudGF0aW9uKX08L2xpPgotICogICA8bGk+Y29udmVyc2lvbiBiZXR3ZWVuIHRoaXMgY2xhc3MgYW5kIHtAbGluayBHcmVnb3JpYW5DYWxlbmRhcn0sCi0gKiAgICAge0BsaW5rICN0b0dyZWdvcmlhbkNhbGVuZGFyKGphdmEudXRpbC5UaW1lWm9uZSB0aW1lem9uZSwgamF2YS51dGlsLkxvY2FsZSBhTG9jYWxlLCBYTUxHcmVnb3JpYW5DYWxlbmRhciBkZWZhdWx0cyl9LAotICogICAgIHtAbGluayBEYXRhdHlwZUZhY3Rvcnl9PC9saT4KLSAqICAgPGxpPnBhcnRpYWwgb3JkZXIgcmVsYXRpb24gY29tcGFyYXRvciBtZXRob2QsIHtAbGluayAjY29tcGFyZShYTUxHcmVnb3JpYW5DYWxlbmRhciB4bWxHcmVnb3JpYW5DYWxlbmRhcil9PC9saT4KLSAqICAgPGxpPntAbGluayAjZXF1YWxzKE9iamVjdCl9IGRlZmluZWQgcmVsYXRpdmUgdG8ge0BsaW5rICNjb21wYXJlKFhNTEdyZWdvcmlhbkNhbGVuZGFyIHhtbEdyZWdvcmlhbkNhbGVuZGFyKX0uPC9saT4KLSAqICAgPGxpPmFkZGl0aW9uIG9wZXJhdGlvbiB3aXRoIHtAbGluayBEdXJhdGlvbn0KLSAqICAgICAgaW5zdGFuY2UgYXMgZGVmaW5lZCBpbiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94bWxzY2hlbWEtMi8jYWRkaW5nLWR1cmF0aW9ucy10by1kYXRlVGltZXMiPgotICogICAgICBXM0MgWE1MIFNjaGVtYSAxLjAgUGFydCAyLCBBcHBlbmRpeCBFLCA8aT5BZGRpbmcgZHVyYXRpb25zIHRvIGRhdGVUaW1lczwvaT48L2E+LgotICogICA8L2xpPgotICogPC91bD4KLSAqIDwvcD4KLSAqCi0gKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzpKb3NlcGguRmlhbGxpQFN1bi5jb20iPkpvc2VwaCBGaWFsbGk8L2E+Ci0gKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzpLb2hzdWtlLkthd2FndWNoaUBTdW4uY29tIj5Lb2hzdWtlIEthd2FndWNoaTwvYT4KLSAqIEBhdXRob3IgPGEgaHJlZj0ibWFpbHRvOkplZmYuU3V0dG9yQFN1bi5jb20iPkplZmYgU3V0dG9yPC9hPgotICogQGF1dGhvciA8YSBocmVmPSJtYWlsdG86U3VuaXRoYS5SZWRkeUBTdW4uY29tIj5TdW5pdGhhIFJlZGR5PC9hPgotICogQHNlZSBEdXJhdGlvbgotICogQHNlZSBEYXRhdHlwZUZhY3RvcnkKLSAqIEBzaW5jZSAxLjUKLSAqLwotCi1wdWJsaWMgYWJzdHJhY3QgY2xhc3MgWE1MR3JlZ29yaWFuQ2FsZW5kYXIKLSAgICAgICAgaW1wbGVtZW50cyBDbG9uZWFibGUgewotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBEZWZhdWx0IG5vLWFyZyBjb25zdHJ1Y3Rvci4KLSAgICAgICAgICoKLSAgICAgICAgICogPHA+Tm90ZTogQWx3YXlzIHVzZSB0aGUge0BsaW5rIERhdGF0eXBlRmFjdG9yeX0gdG8KLSAgICAgICAgICogY29uc3RydWN0IGFuIGluc3RhbmNlIG9mIDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPi4KLSAgICAgICAgICogVGhlIGNvbnN0cnVjdG9yIG9uIHRoaXMgY2xhc3MgY2Fubm90IGJlIGd1YXJhbnRlZWQgdG8KLSAgICAgICAgICogcHJvZHVjZSBhbiBvYmplY3Qgd2l0aCBhIGNvbnNpc3RlbnQgc3RhdGUgYW5kIG1heSBiZQotICAgICAgICAgKiByZW1vdmVkIGluIHRoZSBmdXR1cmUuPC9wPgotICAgICAgICAgKi8KLSAgICAgICAgIHB1YmxpYyBYTUxHcmVnb3JpYW5DYWxlbmRhcigpIHsKLSAgICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogPHA+VW5zZXQgYWxsIGZpZWxkcyB0byB1bmRlZmluZWQuPC9wPgotICAgICAgICAgKgotICAgICAgICAgKiA8cD5TZXQgYWxsIGludCBmaWVsZHMgdG8ge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0ZJRUxEX1VOREVGSU5FRH0gYW5kIHJlZmVyZW5jZSBmaWVsZHMKLSAgICAgICAgICogdG8gbnVsbC48L3A+Ci0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBjbGVhcigpOwotCi0gICAgICAgIC8qKgotICAgICAgICAgKiA8cD5SZXNldCB0aGlzIDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiB0byBpdHMgb3JpZ2luYWwgdmFsdWVzLjwvcD4KLSAgICAgICAgICoKLSAgICAgICAgICogPHA+PGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IGlzIHJlc2V0IHRvIHRoZSBzYW1lIHZhbHVlcyBhcyB3aGVuIGl0IHdhcyBjcmVhdGVkIHdpdGgKLSAgICAgICAgICoge0BsaW5rIERhdGF0eXBlRmFjdG9yeSNuZXdYTUxHcmVnb3JpYW5DYWxlbmRhcigpfSwKLSAgICAgICAgICoge0BsaW5rIERhdGF0eXBlRmFjdG9yeSNuZXdYTUxHcmVnb3JpYW5DYWxlbmRhcihTdHJpbmcgbGV4aWNhbFJlcHJlc2VudGF0aW9uKX0sCi0gICAgICAgICAqIHtAbGluayBEYXRhdHlwZUZhY3RvcnkjbmV3WE1MR3JlZ29yaWFuQ2FsZW5kYXIoCi0gICAgICAgICAqICAgQmlnSW50ZWdlciB5ZWFyLAotICAgICAgICAgKiAgIGludCBtb250aCwKLSAgICAgICAgICogICBpbnQgZGF5LAotICAgICAgICAgKiAgIGludCBob3VyLAotICAgICAgICAgKiAgIGludCBtaW51dGUsCi0gICAgICAgICAqICAgaW50IHNlY29uZCwKLSAgICAgICAgICogICBCaWdEZWNpbWFsIGZyYWN0aW9uYWxTZWNvbmQsCi0gICAgICAgICAqICAgaW50IHRpbWV6b25lKX0sCi0gICAgICAgICAqIHtAbGluayBEYXRhdHlwZUZhY3RvcnkjbmV3WE1MR3JlZ29yaWFuQ2FsZW5kYXIoCi0gICAgICAgICAqICAgaW50IHllYXIsCi0gICAgICAgICAqICAgaW50IG1vbnRoLAotICAgICAgICAgKiAgIGludCBkYXksCi0gICAgICAgICAqICAgaW50IGhvdXIsCi0gICAgICAgICAqICAgaW50IG1pbnV0ZSwKLSAgICAgICAgICogICBpbnQgc2Vjb25kLAotICAgICAgICAgKiAgIGludCBtaWxsaXNlY29uZCwKLSAgICAgICAgICogICBpbnQgdGltZXpvbmUpfSwKLSAgICAgICAgICoge0BsaW5rIERhdGF0eXBlRmFjdG9yeSNuZXdYTUxHcmVnb3JpYW5DYWxlbmRhcihHcmVnb3JpYW5DYWxlbmRhciBjYWwpfSwKLSAgICAgICAgICoge0BsaW5rIERhdGF0eXBlRmFjdG9yeSNuZXdYTUxHcmVnb3JpYW5DYWxlbmRhckRhdGUoCi0gICAgICAgICAqICAgaW50IHllYXIsCi0gICAgICAgICAqICAgaW50IG1vbnRoLAotICAgICAgICAgKiAgIGludCBkYXksCi0gICAgICAgICAqICAgaW50IHRpbWV6b25lKX0sCi0gICAgICAgICAqIHtAbGluayBEYXRhdHlwZUZhY3RvcnkjbmV3WE1MR3JlZ29yaWFuQ2FsZW5kYXJUaW1lKAotICAgICAgICAgKiAgIGludCBob3VycywKLSAgICAgICAgICogICBpbnQgbWludXRlcywKLSAgICAgICAgICogICBpbnQgc2Vjb25kcywKLSAgICAgICAgICogICBpbnQgdGltZXpvbmUpfSwKLSAgICAgICAgICoge0BsaW5rIERhdGF0eXBlRmFjdG9yeSNuZXdYTUxHcmVnb3JpYW5DYWxlbmRhclRpbWUoCi0gICAgICAgICAqICAgaW50IGhvdXJzLAotICAgICAgICAgKiAgIGludCBtaW51dGVzLAotICAgICAgICAgKiAgIGludCBzZWNvbmRzLAotICAgICAgICAgKiAgIEJpZ0RlY2ltYWwgZnJhY3Rpb25hbFNlY29uZCwKLSAgICAgICAgICogICBpbnQgdGltZXpvbmUpfSBvcgotICAgICAgICAgKiB7QGxpbmsgRGF0YXR5cGVGYWN0b3J5I25ld1hNTEdyZWdvcmlhbkNhbGVuZGFyVGltZSgKLSAgICAgICAgICogICBpbnQgaG91cnMsCi0gICAgICAgICAqICAgaW50IG1pbnV0ZXMsCi0gICAgICAgICAqICAgaW50IHNlY29uZHMsCi0gICAgICAgICAqICAgaW50IG1pbGxpc2Vjb25kcywKLSAgICAgICAgICogICBpbnQgdGltZXpvbmUpfS4KLSAgICAgICAgICogPC9wPgotICAgICAgICAgKgotICAgICAgICAgKiA8cD48Y29kZT5yZXNldCgpPC9jb2RlPiBpcyBkZXNpZ25lZCB0byBhbGxvdyB0aGUgcmV1c2Ugb2YgZXhpc3RpbmcgPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+cwotICAgICAgICAgKiB0aHVzIHNhdmluZyByZXNvdXJjZXMgYXNzb2NpYXRlZCB3aXRoIHRoZSBjcmVhdGlvbiBvZiBuZXcgPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+cy48L3A+Ci0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCByZXNldCgpOwotCi0gICAgLyoqCi0gICAgICogPHA+U2V0IGxvdyBhbmQgaGlnaCBvcmRlciBjb21wb25lbnQgb2YgWFNEIDxjb2RlPmRhdGVUaW1lPC9jb2RlPiB5ZWFyIGZpZWxkLjwvcD4KLSAgICAgKgotICAgICAqIDxwPlVuc2V0IHRoaXMgZmllbGQgYnkgaW52b2tpbmcgdGhlIHNldHRlciB3aXRoIGEgcGFyYW1ldGVyIHZhbHVlIG9mIDxjb2RlPm51bGw8L2NvZGU+LjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSB5ZWFyIHZhbHVlIGNvbnN0cmFpbnRzIHN1bW1hcml6ZWQgaW4gPGEgaHJlZj0iI2RhdGV0aW1lZmllbGQteWVhciI+eWVhciBmaWVsZCBvZiBkYXRlL3RpbWUgZmllbGQgbWFwcGluZyB0YWJsZTwvYT4uCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiA8Y29kZT55ZWFyPC9jb2RlPiBwYXJhbWV0ZXIgaXMKLSAgICAgKiBvdXRzaWRlIHZhbHVlIGNvbnN0cmFpbnRzIGZvciB0aGUgZmllbGQgYXMgc3BlY2lmaWVkIGluCi0gICAgICogPGEgaHJlZj0iI2RhdGV0aW1lZmllbGRtYXBwaW5nIj5kYXRlL3RpbWUgZmllbGQgbWFwcGluZyB0YWJsZTwvYT4uCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2V0WWVhcihCaWdJbnRlZ2VyIHllYXIpOwotCi0gICAgLyoqCi0gICAgICogPHA+U2V0IHllYXIgb2YgWFNEIDxjb2RlPmRhdGVUaW1lPC9jb2RlPiB5ZWFyIGZpZWxkLjwvcD4KLSAgICAgKgotICAgICAqIDxwPlVuc2V0IHRoaXMgZmllbGQgYnkgaW52b2tpbmcgdGhlIHNldHRlciB3aXRoIGEgcGFyYW1ldGVyIHZhbHVlIG9mCi0gICAgICoge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0ZJRUxEX1VOREVGSU5FRH0uPC9wPgotICAgICAqCi0gICAgICogPHA+Tm90ZTogaWYgdGhlIGFic29sdXRlIHZhbHVlIG9mIHRoZSA8Y29kZT55ZWFyPC9jb2RlPiBwYXJhbWV0ZXIKLSAgICAgKiBpcyBsZXNzIHRoYW4gMTBeOSwgdGhlIGVvbiBjb21wb25lbnQgb2YgdGhlIFhTRCB5ZWFyIGZpZWxkIGlzIHNldCB0bwotICAgICAqIDxjb2RlPm51bGw8L2NvZGU+IGJ5IHRoaXMgbWV0aG9kLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSB5ZWFyIHZhbHVlIGNvbnN0cmFpbnRzIGFyZSBzdW1tYXJpemVkIGluIDxhIGhyZWY9IiNkYXRldGltZWZpZWxkLXllYXIiPnllYXIgZmllbGQgb2YgZGF0ZS90aW1lIGZpZWxkIG1hcHBpbmcgdGFibGU8L2E+LgotICAgICAqICAgSWYgeWVhciBpcyB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjRklFTERfVU5ERUZJTkVEfSwgdGhlbiBlb24gaXMgc2V0IHRvIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHNldFllYXIoaW50IHllYXIpOwotCi0gICAgLyoqCi0gICAgICogPHA+U2V0IG1vbnRoLjwvcD4KLSAgICAgKgotICAgICAqIDxwPlVuc2V0IHRoaXMgZmllbGQgYnkgaW52b2tpbmcgdGhlIHNldHRlciB3aXRoIGEgcGFyYW1ldGVyIHZhbHVlIG9mIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNGSUVMRF9VTkRFRklORUR9LjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBtb250aCB2YWx1ZSBjb25zdHJhaW50cyBzdW1tYXJpemVkIGluIDxhIGhyZWY9IiNkYXRldGltZWZpZWxkLW1vbnRoIj5tb250aCBmaWVsZCBvZiBkYXRlL3RpbWUgZmllbGQgbWFwcGluZyB0YWJsZTwvYT4uCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiA8Y29kZT5tb250aDwvY29kZT4gcGFyYW1ldGVyIGlzCi0gICAgICogb3V0c2lkZSB2YWx1ZSBjb25zdHJhaW50cyBmb3IgdGhlIGZpZWxkIGFzIHNwZWNpZmllZCBpbgotICAgICAqIDxhIGhyZWY9IiNkYXRldGltZWZpZWxkbWFwcGluZyI+ZGF0ZS90aW1lIGZpZWxkIG1hcHBpbmcgdGFibGU8L2E+LgotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHNldE1vbnRoKGludCBtb250aCk7Ci0KLSAgICAvKioKLSAgICAgKiA8cD5TZXQgZGF5cyBpbiBtb250aC48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5VbnNldCB0aGlzIGZpZWxkIGJ5IGludm9raW5nIHRoZSBzZXR0ZXIgd2l0aCBhIHBhcmFtZXRlciB2YWx1ZSBvZiB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjRklFTERfVU5ERUZJTkVEfS48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gZGF5IHZhbHVlIGNvbnN0cmFpbnRzIHN1bW1hcml6ZWQgaW4gPGEgaHJlZj0iI2RhdGV0aW1lZmllbGQtZGF5Ij5kYXkgZmllbGQgb2YgZGF0ZS90aW1lIGZpZWxkIG1hcHBpbmcgdGFibGU8L2E+LgotICAgICAqCi0gICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgPGNvZGU+ZGF5PC9jb2RlPiBwYXJhbWV0ZXIgaXMKLSAgICAgKiBvdXRzaWRlIHZhbHVlIGNvbnN0cmFpbnRzIGZvciB0aGUgZmllbGQgYXMgc3BlY2lmaWVkIGluCi0gICAgICogPGEgaHJlZj0iI2RhdGV0aW1lZmllbGRtYXBwaW5nIj5kYXRlL3RpbWUgZmllbGQgbWFwcGluZyB0YWJsZTwvYT4uCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2V0RGF5KGludCBkYXkpOwotCi0gICAgLyoqCi0gICAgICogPHA+U2V0IHRoZSBudW1iZXIgb2YgbWludXRlcyBpbiB0aGUgdGltZXpvbmUgb2Zmc2V0LjwvcD4KLSAgICAgKgotICAgICAqIDxwPlVuc2V0IHRoaXMgZmllbGQgYnkgaW52b2tpbmcgdGhlIHNldHRlciB3aXRoIGEgcGFyYW1ldGVyIHZhbHVlIG9mIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNGSUVMRF9VTkRFRklORUR9LjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBvZmZzZXQgdmFsdWUgY29uc3RyYWludHMgc3VtbWFyaXplZCBpbiA8YSBocmVmPSIjZGF0ZXRpbWVmaWVsZC10aW1lem9uZSI+Ci0gICAgICogICB0aW1lem9uZSBmaWVsZCBvZiBkYXRlL3RpbWUgZmllbGQgbWFwcGluZyB0YWJsZTwvYT4uCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiA8Y29kZT5vZmZzZXQ8L2NvZGU+IHBhcmFtZXRlciBpcwotICAgICAqIG91dHNpZGUgdmFsdWUgY29uc3RyYWludHMgZm9yIHRoZSBmaWVsZCBhcyBzcGVjaWZpZWQgaW4KLSAgICAgKiA8YSBocmVmPSIjZGF0ZXRpbWVmaWVsZG1hcHBpbmciPmRhdGUvdGltZSBmaWVsZCBtYXBwaW5nIHRhYmxlPC9hPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRUaW1lem9uZShpbnQgb2Zmc2V0KTsKLQotICAgIC8qKgotICAgICAqIDxwPlNldCB0aW1lIGFzIG9uZSB1bml0LjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBob3VyIHZhbHVlIGNvbnN0cmFpbnRzIGFyZSBzdW1tYXJpemVkIGluCi0gICAgICogPGEgaHJlZj0iI2RhdGV0aW1lZmllbGQtaG91ciI+aG91ciBmaWVsZCBvZiBkYXRlL3RpbWUgZmllbGQgbWFwcGluZyB0YWJsZTwvYT4uCi0gICAgICogQHBhcmFtIG1pbnV0ZSB2YWx1ZSBjb25zdHJhaW50cyBhcmUgc3VtbWFyaXplZCBpbgotICAgICAqIDxhIGhyZWY9IiNkYXRldGltZWZpZWxkLW1pbnV0ZSI+bWludXRlIGZpZWxkIG9mIGRhdGUvdGltZSBmaWVsZCBtYXBwaW5nIHRhYmxlPC9hPi4KLSAgICAgKiBAcGFyYW0gc2Vjb25kIHZhbHVlIGNvbnN0cmFpbnRzIGFyZSBzdW1tYXJpemVkIGluCi0gICAgICogPGEgaHJlZj0iI2RhdGV0aW1lZmllbGQtc2Vjb25kIj5zZWNvbmQgZmllbGQgb2YgZGF0ZS90aW1lIGZpZWxkIG1hcHBpbmcgdGFibGU8L2E+LgotICAgICAqCi0gICAgICogQHNlZSAjc2V0VGltZShpbnQsIGludCwgaW50LCBCaWdEZWNpbWFsKQotICAgICAqCi0gICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgYW55IHBhcmFtZXRlciBpcwotICAgICAqIG91dHNpZGUgdmFsdWUgY29uc3RyYWludHMgZm9yIHRoZSBmaWVsZCBhcyBzcGVjaWZpZWQgaW4KLSAgICAgKiA8YSBocmVmPSIjZGF0ZXRpbWVmaWVsZG1hcHBpbmciPmRhdGUvdGltZSBmaWVsZCBtYXBwaW5nIHRhYmxlPC9hPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRUaW1lKGludCBob3VyLCBpbnQgbWludXRlLCBpbnQgc2Vjb25kKSB7Ci0KLSAgICAgICAgICAgICAgICBzZXRUaW1lKAotICAgICAgICAgICAgICAgICAgICAgICAgaG91ciwKLSAgICAgICAgICAgICAgICAgICAgICAgIG1pbnV0ZSwKLSAgICAgICAgICAgICAgICAgICAgICAgIHNlY29uZCwKLSAgICAgICAgICAgICAgICAgICAgICAgIG51bGwgLy8gZnJhY3Rpb25hbAotICAgICAgICAgICAgICAgICk7Ci0gICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiA8cD5TZXQgaG91cnMuPC9wPgotICAgICAgICAgKgotICAgICAgICAgKiA8cD5VbnNldCB0aGlzIGZpZWxkIGJ5IGludm9raW5nIHRoZSBzZXR0ZXIgd2l0aCBhIHBhcmFtZXRlciB2YWx1ZSBvZiB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjRklFTERfVU5ERUZJTkVEfS48L3A+Ci0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBob3VyIHZhbHVlIGNvbnN0cmFpbnRzIHN1bW1hcml6ZWQgaW4gPGEgaHJlZj0iI2RhdGV0aW1lZmllbGQtaG91ciI+aG91ciBmaWVsZCBvZiBkYXRlL3RpbWUgZmllbGQgbWFwcGluZyB0YWJsZTwvYT4uCi0gICAgICAgICAqCi0gICAgICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIDxjb2RlPmhvdXI8L2NvZGU+IHBhcmFtZXRlciBpcyBvdXRzaWRlIHZhbHVlIGNvbnN0cmFpbnRzIGZvciB0aGUgZmllbGQgYXMgc3BlY2lmaWVkIGluCi0gICAgICAgICAqICAgPGEgaHJlZj0iI2RhdGV0aW1lZmllbGRtYXBwaW5nIj5kYXRlL3RpbWUgZmllbGQgbWFwcGluZyB0YWJsZTwvYT4uCi0gICAgICAgICovCi0gICAgICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHNldEhvdXIoaW50IGhvdXIpOwotCi0gICAgICAgIC8qKgotICAgICAgICAgKiA8cD5TZXQgbWludXRlcy48L3A+Ci0gICAgICAgICAqCi0gICAgICAgICAqIDxwPlVuc2V0IHRoaXMgZmllbGQgYnkgaW52b2tpbmcgdGhlIHNldHRlciB3aXRoIGEgcGFyYW1ldGVyIHZhbHVlIG9mIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNGSUVMRF9VTkRFRklORUR9LjwvcD4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIG1pbnV0ZSB2YWx1ZSBjb25zdHJhaW50cyBzdW1tYXJpemVkIGluIDxhIGhyZWY9IiNkYXRldGltZWZpZWxkLW1pbnV0ZSI+bWludXRlIGZpZWxkIG9mIGRhdGUvdGltZSBmaWVsZCBtYXBwaW5nIHRhYmxlPC9hPi4KLSAgICAgICAgICoKLSAgICAgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgPGNvZGU+bWludXRlPC9jb2RlPiBwYXJhbWV0ZXIgaXMgb3V0c2lkZSB2YWx1ZSBjb25zdHJhaW50cyBmb3IgdGhlIGZpZWxkIGFzIHNwZWNpZmllZCBpbgotICAgICAgICAgKiAgIDxhIGhyZWY9IiNkYXRldGltZWZpZWxkbWFwcGluZyI+ZGF0ZS90aW1lIGZpZWxkIG1hcHBpbmcgdGFibGU8L2E+LgotICAgICAgICAqLwotICAgICAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRNaW51dGUoaW50IG1pbnV0ZSk7Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIDxwPlNldCBzZWNvbmRzLjwvcD4KLSAgICAgICAgICoKLSAgICAgICAgICogPHA+VW5zZXQgdGhpcyBmaWVsZCBieSBpbnZva2luZyB0aGUgc2V0dGVyIHdpdGggYSBwYXJhbWV0ZXIgdmFsdWUgb2Yge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0ZJRUxEX1VOREVGSU5FRH0uPC9wPgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gc2Vjb25kIHZhbHVlIGNvbnN0cmFpbnRzIHN1bW1hcml6ZWQgaW4gPGEgaHJlZj0iI2RhdGV0aW1lZmllbGQtc2Vjb25kIj5zZWNvbmQgZmllbGQgb2YgZGF0ZS90aW1lIGZpZWxkIG1hcHBpbmcgdGFibGU8L2E+LgotICAgICAgICAgKgotICAgICAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiA8Y29kZT5zZWNvbmQ8L2NvZGU+IHBhcmFtZXRlciBpcyBvdXRzaWRlIHZhbHVlIGNvbnN0cmFpbnRzIGZvciB0aGUgZmllbGQgYXMgc3BlY2lmaWVkIGluCi0gICAgICAgICAqICAgPGEgaHJlZj0iI2RhdGV0aW1lZmllbGRtYXBwaW5nIj5kYXRlL3RpbWUgZmllbGQgbWFwcGluZyB0YWJsZTwvYT4uCi0gICAgICAgICovCi0gICAgICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHNldFNlY29uZChpbnQgc2Vjb25kKTsKLQotICAgICAgICAvKioKLSAgICAgICAgICogPHA+U2V0IG1pbGxpc2Vjb25kcy48L3A+Ci0gICAgICAgICAqCi0gICAgICAgICAqIDxwPlVuc2V0IHRoaXMgZmllbGQgYnkgaW52b2tpbmcgdGhlIHNldHRlciB3aXRoIGEgcGFyYW1ldGVyIHZhbHVlIG9mIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNGSUVMRF9VTkRFRklORUR9LjwvcD4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIG1pbGxpc2Vjb25kIHZhbHVlIGNvbnN0cmFpbnRzIHN1bW1hcml6ZWQgaW4KLSAgICAgICAgICogICA8YSBocmVmPSIjZGF0ZXRpbWVmaWVsZC1zZWNvbmQiPnNlY29uZCBmaWVsZCBvZiBkYXRlL3RpbWUgZmllbGQgbWFwcGluZyB0YWJsZTwvYT4uCi0gICAgICAgICAqCi0gICAgICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIDxjb2RlPm1pbGxpc2Vjb25kPC9jb2RlPiBwYXJhbWV0ZXIgaXMgb3V0c2lkZSB2YWx1ZSBjb25zdHJhaW50cyBmb3IgdGhlIGZpZWxkIGFzIHNwZWNpZmllZAotICAgICAgICAgKiAgIGluIDxhIGhyZWY9IiNkYXRldGltZWZpZWxkbWFwcGluZyI+ZGF0ZS90aW1lIGZpZWxkIG1hcHBpbmcgdGFibGU8L2E+LgotICAgICAgICAqLwotICAgICAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRNaWxsaXNlY29uZChpbnQgbWlsbGlzZWNvbmQpOwotCi0gICAgICAgIC8qKgotICAgICAgICAgKiA8cD5TZXQgZnJhY3Rpb25hbCBzZWNvbmRzLjwvcD4KLSAgICAgICAgICoKLSAgICAgICAgICogPHA+VW5zZXQgdGhpcyBmaWVsZCBieSBpbnZva2luZyB0aGUgc2V0dGVyIHdpdGggYSBwYXJhbWV0ZXIgdmFsdWUgb2YgPGNvZGU+bnVsbDwvY29kZT4uPC9wPgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gZnJhY3Rpb25hbCB2YWx1ZSBjb25zdHJhaW50cyBzdW1tYXJpemVkIGluCi0gICAgICAgICAqICAgPGEgaHJlZj0iI2RhdGV0aW1lZmllbGQtc2Vjb25kIj5zZWNvbmQgZmllbGQgb2YgZGF0ZS90aW1lIGZpZWxkIG1hcHBpbmcgdGFibGU8L2E+LgotICAgICAgICAgKgotICAgICAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiA8Y29kZT5mcmFjdGlvbmFsPC9jb2RlPiBwYXJhbWV0ZXIgaXMgb3V0c2lkZSB2YWx1ZSBjb25zdHJhaW50cyBmb3IgdGhlIGZpZWxkIGFzIHNwZWNpZmllZAotICAgICAgICAgKiAgIGluIDxhIGhyZWY9IiNkYXRldGltZWZpZWxkbWFwcGluZyI+ZGF0ZS90aW1lIGZpZWxkIG1hcHBpbmcgdGFibGU8L2E+LgotICAgICAgICAqLwotICAgICAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRGcmFjdGlvbmFsU2Vjb25kKEJpZ0RlY2ltYWwgZnJhY3Rpb25hbCk7Ci0KLQotICAgIC8qKgotICAgICAqIDxwPlNldCB0aW1lIGFzIG9uZSB1bml0LCBpbmNsdWRpbmcgdGhlIG9wdGlvbmFsIGluZmluaXRlIHByZWNpc2lvbgotICAgICAqIGZyYWN0aW9uYWwgc2Vjb25kcy48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gaG91ciB2YWx1ZSBjb25zdHJhaW50cyBhcmUgc3VtbWFyaXplZCBpbgotICAgICAqIDxhIGhyZWY9IiNkYXRldGltZWZpZWxkLWhvdXIiPmhvdXIgZmllbGQgb2YgZGF0ZS90aW1lIGZpZWxkIG1hcHBpbmcgdGFibGU8L2E+LgotICAgICAqIEBwYXJhbSBtaW51dGUgdmFsdWUgY29uc3RyYWludHMgYXJlIHN1bW1hcml6ZWQgaW4KLSAgICAgKiA8YSBocmVmPSIjZGF0ZXRpbWVmaWVsZC1taW51dGUiPm1pbnV0ZSBmaWVsZCBvZiBkYXRlL3RpbWUgZmllbGQgbWFwcGluZyB0YWJsZTwvYT4uCi0gICAgICogQHBhcmFtIHNlY29uZCB2YWx1ZSBjb25zdHJhaW50cyBhcmUgc3VtbWFyaXplZCBpbgotICAgICAqIDxhIGhyZWY9IiNkYXRldGltZWZpZWxkLXNlY29uZCI+c2Vjb25kIGZpZWxkIG9mIGRhdGUvdGltZSBmaWVsZCBtYXBwaW5nIHRhYmxlPC9hPi4KLSAgICAgKiBAcGFyYW0gZnJhY3Rpb25hbCB2YWx1ZSBvZiA8Y29kZT5udWxsPC9jb2RlPiBpbmRpY2F0ZXMgdGhpcyBvcHRpb25hbAotICAgICAqICAgZmllbGQgaXMgbm90IHNldC4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIGFueSBwYXJhbWV0ZXIgaXMKLSAgICAgKiBvdXRzaWRlIHZhbHVlIGNvbnN0cmFpbnRzIGZvciB0aGUgZmllbGQgYXMgc3BlY2lmaWVkIGluCi0gICAgICogPGEgaHJlZj0iI2RhdGV0aW1lZmllbGRtYXBwaW5nIj5kYXRlL3RpbWUgZmllbGQgbWFwcGluZyB0YWJsZTwvYT4uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0VGltZSgKLSAgICAgICAgaW50IGhvdXIsCi0gICAgICAgIGludCBtaW51dGUsCi0gICAgICAgIGludCBzZWNvbmQsCi0gICAgICAgIEJpZ0RlY2ltYWwgZnJhY3Rpb25hbCkgewotCi0gICAgICAgICAgICAgICAgc2V0SG91cihob3VyKTsKLSAgICAgICAgc2V0TWludXRlKG1pbnV0ZSk7Ci0gICAgICAgIHNldFNlY29uZChzZWNvbmQpOwotICAgICAgICBzZXRGcmFjdGlvbmFsU2Vjb25kKGZyYWN0aW9uYWwpOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogPHA+U2V0IHRpbWUgYXMgb25lIHVuaXQsIGluY2x1ZGluZyBvcHRpb25hbCBtaWxsaXNlY29uZHMuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGhvdXIgdmFsdWUgY29uc3RyYWludHMgYXJlIHN1bW1hcml6ZWQgaW4KLSAgICAgKiA8YSBocmVmPSIjZGF0ZXRpbWVmaWVsZC1ob3VyIj5ob3VyIGZpZWxkIG9mIGRhdGUvdGltZSBmaWVsZCBtYXBwaW5nIHRhYmxlPC9hPi4KLSAgICAgKiBAcGFyYW0gbWludXRlIHZhbHVlIGNvbnN0cmFpbnRzIGFyZSBzdW1tYXJpemVkIGluCi0gICAgICogPGEgaHJlZj0iI2RhdGV0aW1lZmllbGQtbWludXRlIj5taW51dGUgZmllbGQgb2YgZGF0ZS90aW1lIGZpZWxkIG1hcHBpbmcgdGFibGU8L2E+LgotICAgICAqIEBwYXJhbSBzZWNvbmQgdmFsdWUgY29uc3RyYWludHMgYXJlIHN1bW1hcml6ZWQgaW4KLSAgICAgKiA8YSBocmVmPSIjZGF0ZXRpbWVmaWVsZC1zZWNvbmQiPnNlY29uZCBmaWVsZCBvZiBkYXRlL3RpbWUgZmllbGQgbWFwcGluZyB0YWJsZTwvYT4uCi0gICAgICogQHBhcmFtIG1pbGxpc2Vjb25kIHZhbHVlIG9mIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNGSUVMRF9VTkRFRklORUR9IGluZGljYXRlcyB0aGlzCi0gICAgICogICAgICAgICAgICAgICAgICAgIG9wdGlvbmFsIGZpZWxkIGlzIG5vdCBzZXQuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiBhbnkgcGFyYW1ldGVyIGlzCi0gICAgICogb3V0c2lkZSB2YWx1ZSBjb25zdHJhaW50cyBmb3IgdGhlIGZpZWxkIGFzIHNwZWNpZmllZCBpbgotICAgICAqIDxhIGhyZWY9IiNkYXRldGltZWZpZWxkbWFwcGluZyI+ZGF0ZS90aW1lIGZpZWxkIG1hcHBpbmcgdGFibGU8L2E+LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFRpbWUoaW50IGhvdXIsIGludCBtaW51dGUsIGludCBzZWNvbmQsIGludCBtaWxsaXNlY29uZCkgewotCi0gICAgICAgIHNldEhvdXIoaG91cik7Ci0gICAgICAgIHNldE1pbnV0ZShtaW51dGUpOwotICAgICAgICBzZXRTZWNvbmQoc2Vjb25kKTsKLSAgICAgICAgc2V0TWlsbGlzZWNvbmQobWlsbGlzZWNvbmQpOwotICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogPHA+UmV0dXJuIGhpZ2ggb3JkZXIgY29tcG9uZW50IGZvciBYTUwgU2NoZW1hIDEuMCBkYXRlVGltZSBkYXRhdHlwZSBmaWVsZCBmb3IKLSAgICAgICAgICogPGNvZGU+eWVhcjwvY29kZT4uCi0gICAgICAgICAqIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoaXMgb3B0aW9uYWwgcGFydCBvZiB0aGUgeWVhciBmaWVsZCBpcyBub3QgZGVmaW5lZC48L3A+Ci0gICAgICAgICAqCi0gICAgICAgICAqIDxwPlZhbHVlIGNvbnN0cmFpbnRzIGZvciB0aGlzIHZhbHVlIGFyZSBzdW1tYXJpemVkIGluCi0gICAgICAgICAqIDxhIGhyZWY9IiNkYXRldGltZWZpZWxkLXllYXIiPnllYXIgZmllbGQgb2YgZGF0ZS90aW1lIGZpZWxkIG1hcHBpbmcgdGFibGU8L2E+LjwvcD4KLSAgICAgICAgICogQHJldHVybiBlb24gb2YgdGhpcyA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4uIFRoZSB2YWx1ZQotICAgICAgICAgKiByZXR1cm5lZCBpcyBhbiBpbnRlZ2VyIG11bHRpcGxlIG9mIDEwXjkuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBzZWUgI2dldFllYXIoKQotICAgICAgICAgKiBAc2VlICNnZXRFb25BbmRZZWFyKCkKLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBhYnN0cmFjdCBCaWdJbnRlZ2VyIGdldEVvbigpOwotCi0gICAgICAgIC8qKgotICAgICAgICAgKiA8cD5SZXR1cm4gbG93IG9yZGVyIGNvbXBvbmVudCBmb3IgWE1MIFNjaGVtYSAxLjAgZGF0ZVRpbWUgZGF0YXR5cGUgZmllbGQgZm9yCi0gICAgICAgICAqIDxjb2RlPnllYXI8L2NvZGU+IG9yIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNGSUVMRF9VTkRFRklORUR9LjwvcD4KLSAgICAgICAgICoKLSAgICAgICAgICogPHA+VmFsdWUgY29uc3RyYWludHMgZm9yIHRoaXMgdmFsdWUgYXJlIHN1bW1hcml6ZWQgaW4KLSAgICAgICAgICogPGEgaHJlZj0iI2RhdGV0aW1lZmllbGQteWVhciI+eWVhciBmaWVsZCBvZiBkYXRlL3RpbWUgZmllbGQgbWFwcGluZyB0YWJsZTwvYT4uPC9wPgotICAgICAgICAgKgotICAgICAgICAgKiBAcmV0dXJuIHllYXIgIG9mIHRoaXMgPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+LgotICAgICAgICAgKgotICAgICAgICAgKiBAc2VlICNnZXRFb24oKQotICAgICAgICAgKiBAc2VlICNnZXRFb25BbmRZZWFyKCkKLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBhYnN0cmFjdCBpbnQgZ2V0WWVhcigpOwotCi0gICAgICAgIC8qKgotICAgICAgICAgKiA8cD5SZXR1cm4gWE1MIFNjaGVtYSAxLjAgZGF0ZVRpbWUgZGF0YXR5cGUgZmllbGQgZm9yCi0gICAgICAgICAqIDxjb2RlPnllYXI8L2NvZGU+LjwvcD4KLSAgICAgICAgICoKLSAgICAgICAgICogPHA+VmFsdWUgY29uc3RyYWludHMgZm9yIHRoaXMgdmFsdWUgYXJlIHN1bW1hcml6ZWQgaW4KLSAgICAgICAgICogPGEgaHJlZj0iI2RhdGV0aW1lZmllbGQteWVhciI+eWVhciBmaWVsZCBvZiBkYXRlL3RpbWUgZmllbGQgbWFwcGluZyB0YWJsZTwvYT4uPC9wPgotICAgICAgICAgKgotICAgICAgICAgKiBAcmV0dXJuIHN1bSBvZiA8Y29kZT5lb248L2NvZGU+IGFuZCA8Y29kZT5CaWdJbnRlZ2VyLnZhbHVlT2YoeWVhcik8L2NvZGU+Ci0gICAgICAgICAqIHdoZW4gYm90aCBmaWVsZHMgYXJlIGRlZmluZWQuIFdoZW4gb25seSA8Y29kZT55ZWFyPC9jb2RlPiBpcyBkZWZpbmVkLAotICAgICAgICAgKiByZXR1cm4gaXQuIFdoZW4gYm90aCA8Y29kZT5lb248L2NvZGU+IGFuZCA8Y29kZT55ZWFyPC9jb2RlPiBhcmUgbm90Ci0gICAgICAgICAqIGRlZmluZWQsIHJldHVybiA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICAgICAgICoKLSAgICAgICAgICogQHNlZSAjZ2V0RW9uKCkKLSAgICAgICAgICogQHNlZSAjZ2V0WWVhcigpCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgYWJzdHJhY3QgQmlnSW50ZWdlciBnZXRFb25BbmRZZWFyKCk7Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIDxwPlJldHVybiBudW1iZXIgb2YgbW9udGggb3Ige0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0ZJRUxEX1VOREVGSU5FRH0uPC9wPgotICAgICAgICAgKgotICAgICAgICAgKiA8cD5WYWx1ZSBjb25zdHJhaW50cyBmb3IgdGhpcyB2YWx1ZSBhcmUgc3VtbWFyaXplZCBpbgotICAgICAgICAgKiA8YSBocmVmPSIjZGF0ZXRpbWVmaWVsZC1tb250aCI+bW9udGggZmllbGQgb2YgZGF0ZS90aW1lIGZpZWxkIG1hcHBpbmcgdGFibGU8L2E+LjwvcD4KLSAgICAgICAgICoKLSAgICAgICAgICogQHJldHVybiB5ZWFyICBvZiB0aGlzIDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPi4KLSAgICAgICAgICoKLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBhYnN0cmFjdCBpbnQgZ2V0TW9udGgoKTsKLQotICAgICAgICAvKioKLSAgICAgICAgICogUmV0dXJuIGRheSBpbiBtb250aCBvciB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjRklFTERfVU5ERUZJTkVEfS48L3A+Ci0gICAgICAgICAqCi0gICAgICAgICAqIDxwPlZhbHVlIGNvbnN0cmFpbnRzIGZvciB0aGlzIHZhbHVlIGFyZSBzdW1tYXJpemVkIGluCi0gICAgICAgICAqIDxhIGhyZWY9IiNkYXRldGltZWZpZWxkLWRheSI+ZGF5IGZpZWxkIG9mIGRhdGUvdGltZSBmaWVsZCBtYXBwaW5nIHRhYmxlPC9hPi48L3A+Ci0gICAgICAgICAqCi0gICAgICAgICAqIEBzZWUgI3NldERheShpbnQpCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgYWJzdHJhY3QgaW50IGdldERheSgpOwotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBSZXR1cm4gdGltZXpvbmUgb2Zmc2V0IGluIG1pbnV0ZXMgb3IKLSAgICAgICAgICoge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0ZJRUxEX1VOREVGSU5FRH0gaWYgdGhpcyBvcHRpb25hbCBmaWVsZCBpcyBub3QgZGVmaW5lZC4KLSAgICAgICAgICoKLSAgICAgICAgICogPHA+VmFsdWUgY29uc3RyYWludHMgZm9yIHRoaXMgdmFsdWUgYXJlIHN1bW1hcml6ZWQgaW4KLSAgICAgICAgICogPGEgaHJlZj0iI2RhdGV0aW1lZmllbGQtdGltZXpvbmUiPnRpbWV6b25lIGZpZWxkIG9mIGRhdGUvdGltZSBmaWVsZCBtYXBwaW5nIHRhYmxlPC9hPi48L3A+Ci0gICAgICAgICAqCi0gICAgICAgICAqIEBzZWUgI3NldFRpbWV6b25lKGludCkKLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBhYnN0cmFjdCBpbnQgZ2V0VGltZXpvbmUoKTsKLQotICAgICAgICAvKioKLSAgICAgICAgICogUmV0dXJuIGhvdXJzIG9yIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNGSUVMRF9VTkRFRklORUR9LgotICAgICAgICAgKiBSZXR1cm5zIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNGSUVMRF9VTkRFRklORUR9IGlmIHRoaXMgZmllbGQgaXMgbm90IGRlZmluZWQuCi0gICAgICAgICAqCi0gICAgICAgICAqIDxwPlZhbHVlIGNvbnN0cmFpbnRzIGZvciB0aGlzIHZhbHVlIGFyZSBzdW1tYXJpemVkIGluCi0gICAgICAgICAqIDxhIGhyZWY9IiNkYXRldGltZWZpZWxkLWhvdXIiPmhvdXIgZmllbGQgb2YgZGF0ZS90aW1lIGZpZWxkIG1hcHBpbmcgdGFibGU8L2E+LjwvcD4KLSAgICAgICAgICogQHNlZSAjc2V0VGltZShpbnQsIGludCwgaW50KQotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIGFic3RyYWN0IGludCBnZXRIb3VyKCk7Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFJldHVybiBtaW51dGVzIG9yIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNGSUVMRF9VTkRFRklORUR9LjwvcD4KLSAgICAgICAgICogUmV0dXJucyB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjRklFTERfVU5ERUZJTkVEfSBpZiB0aGlzIGZpZWxkIGlzIG5vdCBkZWZpbmVkLgotICAgICAgICAgKgotICAgICAgICAgKiA8cD5WYWx1ZSBjb25zdHJhaW50cyBmb3IgdGhpcyB2YWx1ZSBhcmUgc3VtbWFyaXplZCBpbgotICAgICAgICAgKiA8YSBocmVmPSIjZGF0ZXRpbWVmaWVsZC1taW51dGUiPm1pbnV0ZSBmaWVsZCBvZiBkYXRlL3RpbWUgZmllbGQgbWFwcGluZyB0YWJsZTwvYT4uPC9wPgotICAgICAgICAgKiBAc2VlICNzZXRUaW1lKGludCwgaW50LCBpbnQpCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgYWJzdHJhY3QgaW50IGdldE1pbnV0ZSgpOwotCi0gICAgICAgIC8qKgotICAgICAgICAgKiA8cD5SZXR1cm4gc2Vjb25kcyBvciB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjRklFTERfVU5ERUZJTkVEfS48L3A+Ci0gICAgICAgICAqCi0gICAgICAgICAqIDxwPlJldHVybnMge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0ZJRUxEX1VOREVGSU5FRH0gaWYgdGhpcyBmaWVsZCBpcyBub3QgZGVmaW5lZC4KLSAgICAgICAgICogV2hlbiB0aGlzIGZpZWxkIGlzIG5vdCBkZWZpbmVkLCB0aGUgb3B0aW9uYWwgeHM6ZGF0ZVRpbWUKLSAgICAgICAgICogZnJhY3Rpb25hbCBzZWNvbmRzIGZpZWxkLCByZXByZXNlbnRlZCBieQotICAgICAgICAgKiB7QGxpbmsgI2dldEZyYWN0aW9uYWxTZWNvbmQoKX0gYW5kIHtAbGluayAjZ2V0TWlsbGlzZWNvbmQoKX0sCi0gICAgICAgICAqIG11c3Qgbm90IGJlIGRlZmluZWQuPC9wPgotICAgICAgICAgKgotICAgICAgICAgKiA8cD5WYWx1ZSBjb25zdHJhaW50cyBmb3IgdGhpcyB2YWx1ZSBhcmUgc3VtbWFyaXplZCBpbgotICAgICAgICAgKiA8YSBocmVmPSIjZGF0ZXRpbWVmaWVsZC1zZWNvbmQiPnNlY29uZCBmaWVsZCBvZiBkYXRlL3RpbWUgZmllbGQgbWFwcGluZyB0YWJsZTwvYT4uPC9wPgotICAgICAgICAgKgotICAgICAgICAgKiBAcmV0dXJuIFNlY29uZCAgb2YgdGhpcyA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4uCi0gICAgICAgICAqCi0gICAgICAgICAqIEBzZWUgI2dldEZyYWN0aW9uYWxTZWNvbmQoKQotICAgICAgICAgKiBAc2VlICNnZXRNaWxsaXNlY29uZCgpCi0gICAgICAgICAqIEBzZWUgI3NldFRpbWUoaW50LCBpbnQsIGludCkKLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBhYnN0cmFjdCBpbnQgZ2V0U2Vjb25kKCk7Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIDxwPlJldHVybiBtaWxsaXNlY29uZCBwcmVjaXNpb24gb2Yge0BsaW5rICNnZXRGcmFjdGlvbmFsU2Vjb25kKCl9LjwvcD4KLSAgICAgICAgICoKLSAgICAgICAgICogPHA+VGhpcyBtZXRob2QgcmVwcmVzZW50cyBhIGNvbnZlbmllbmNlIGFjY2Vzc29yIHRvIGluZmluaXRlCi0gICAgICAgICAqIHByZWNpc2lvbiBmcmFjdGlvbmFsIHNlY29uZCB2YWx1ZSByZXR1cm5lZCBieQotICAgICAgICAgKiB7QGxpbmsgI2dldEZyYWN0aW9uYWxTZWNvbmQoKX0uIFRoZSByZXR1cm5lZCB2YWx1ZSBpcyB0aGUgcm91bmRlZAotICAgICAgICAgKiBkb3duIHRvIG1pbGxpc2Vjb25kcyB2YWx1ZSBvZgotICAgICAgICAgKiB7QGxpbmsgI2dldEZyYWN0aW9uYWxTZWNvbmQoKX0uIFdoZW4ge0BsaW5rICNnZXRGcmFjdGlvbmFsU2Vjb25kKCl9Ci0gICAgICAgICAqIHJldHVybnMgPGNvZGU+bnVsbDwvY29kZT4sIHRoaXMgbWV0aG9kIG11c3QgcmV0dXJuCi0gICAgICAgICAqIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNGSUVMRF9VTkRFRklORUR9LjwvcD4KLSAgICAgICAgICoKLSAgICAgICAgICogPHA+VmFsdWUgY29uc3RyYWludHMgZm9yIHRoaXMgdmFsdWUgYXJlIHN1bW1hcml6ZWQgaW4KLSAgICAgICAgICogPGEgaHJlZj0iI2RhdGV0aW1lZmllbGQtc2Vjb25kIj5zZWNvbmQgZmllbGQgb2YgZGF0ZS90aW1lIGZpZWxkIG1hcHBpbmcgdGFibGU8L2E+LjwvcD4KLSAgICAgICAgICoKLSAgICAgICAgICogQHJldHVybiBNaWxsaXNlY29uZCAgb2YgdGhpcyA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4uCi0gICAgICAgICAqCi0gICAgICAgICAqIEBzZWUgI2dldEZyYWN0aW9uYWxTZWNvbmQoKQotICAgICAgICAgKiBAc2VlICNzZXRUaW1lKGludCwgaW50LCBpbnQpCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgaW50IGdldE1pbGxpc2Vjb25kKCkgewotCi0gICAgICAgICAgICAgICAgQmlnRGVjaW1hbCBmcmFjdGlvbmFsU2Vjb25kcyA9IGdldEZyYWN0aW9uYWxTZWNvbmQoKTsKLQotICAgICAgICAgICAgICAgIC8vIGlzIGZpZWxkIHVuZGVmaW5lZD8KLSAgICAgICAgICAgICAgICBpZiAoZnJhY3Rpb25hbFNlY29uZHMgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRDsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICByZXR1cm4gZ2V0RnJhY3Rpb25hbFNlY29uZCgpLm1vdmVQb2ludFJpZ2h0KDMpLmludFZhbHVlKCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogPHA+UmV0dXJuIGZyYWN0aW9uYWwgc2Vjb25kcy48L3A+Ci0gICAgICAgICAqCi0gICAgICAgICAqIDxwPjxjb2RlPm51bGw8L2NvZGU+IGlzIHJldHVybmVkIHdoZW4gdGhpcyBvcHRpb25hbCBmaWVsZCBpcyBub3QgZGVmaW5lZC48L3A+Ci0gICAgICAgICAqCi0gICAgICAgICAqIDxwPlZhbHVlIGNvbnN0cmFpbnRzIGFyZSBkZXRhaWxlZCBpbgotICAgICAgICAgKiA8YSBocmVmPSIjZGF0ZXRpbWVmaWVsZC1zZWNvbmQiPnNlY29uZCBmaWVsZCBvZiBkYXRlL3RpbWUgZmllbGQgbWFwcGluZyB0YWJsZTwvYT4uPC9wPgotICAgICAgICAgKgotICAgICAgICAgKiA8cD5UaGlzIG9wdGlvbmFsIGZpZWxkIGNhbiBvbmx5IGhhdmUgYSBkZWZpbmVkIHZhbHVlIHdoZW4gdGhlCi0gICAgICAgICAqIHhzOmRhdGVUaW1lIHNlY29uZCBmaWVsZCwgcmVwcmVzZW50ZWQgYnkge0BsaW5rICNnZXRTZWNvbmQoKX0sCi0gICAgICAgICAqIGRvZXMgbm90IHJldHVybiB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjRklFTERfVU5ERUZJTkVEfS48L3A+Ci0gICAgICAgICAqCi0gICAgICAgICAqIEByZXR1cm4gZnJhY3Rpb25hbCBzZWNvbmRzICBvZiB0aGlzIDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPi4KLSAgICAgICAgICoKLSAgICAgICAgICogQHNlZSAjZ2V0U2Vjb25kKCkKLSAgICAgICAgICogQHNlZSAjc2V0VGltZShpbnQsIGludCwgaW50LCBCaWdEZWNpbWFsKQotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIGFic3RyYWN0IEJpZ0RlY2ltYWwgZ2V0RnJhY3Rpb25hbFNlY29uZCgpOwotCi0gICAgLy8gY29tcGFyaXNvbnMKLSAgICAvKioKLSAgICAgKiA8cD5Db21wYXJlIHR3byBpbnN0YW5jZXMgb2YgVzNDIFhNTCBTY2hlbWEgMS4wIGRhdGUvdGltZSBkYXRhdHlwZXMKLSAgICAgKiBhY2NvcmRpbmcgdG8gcGFydGlhbCBvcmRlciByZWxhdGlvbiBkZWZpbmVkIGluCi0gICAgICogPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveG1sc2NoZW1hLTIvI2RhdGVUaW1lLW9yZGVyIj5XM0MgWE1MIFNjaGVtYSAxLjAgUGFydCAyLCBTZWN0aW9uIDMuMi43LjMsCi0gICAgICogPGk+T3JkZXIgcmVsYXRpb24gb24gZGF0ZVRpbWU8L2k+PC9hPi48L3A+Ci0gICAgICoKLSAgICAgKiA8cD48Y29kZT54c2Q6ZGF0ZVRpbWU8L2NvZGU+IGRhdGF0eXBlIGZpZWxkIG1hcHBpbmcgdG8gYWNjZXNzb3JzIG9mCi0gICAgICogdGhpcyBjbGFzcyBhcmUgZGVmaW5lZCBpbgotICAgICAqIDxhIGhyZWY9IiNkYXRldGltZWZpZWxkbWFwcGluZyI+ZGF0ZS90aW1lIGZpZWxkIG1hcHBpbmcgdGFibGU8L2E+LjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSB4bWxHcmVnb3JpYW5DYWxlbmRhciBJbnN0YW5jZSBvZiA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gdG8gY29tcGFyZQotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgcmVsYXRpb25zaGlwIGJldHdlZW4gPGNvZGU+dGhpczwvY29kZT4gPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IGFuZAotICAgICAqICAgdGhlIHNwZWNpZmllZCA8Y29kZT54bWxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gYXMKLSAgICAgKiAgIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNMRVNTRVJ9LAotICAgICAqICAge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0VRVUFMfSwKLSAgICAgKiAgIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNHUkVBVEVSfSBvcgotICAgICAqICAge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0lOREVURVJNSU5BVEV9LgotICAgICAqCi0gICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiA8Y29kZT54bWxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gaXMgbnVsbC4KLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3QgaW50IGNvbXBhcmUoWE1MR3JlZ29yaWFuQ2FsZW5kYXIgeG1sR3JlZ29yaWFuQ2FsZW5kYXIpOwotCi0gICAgLyoqCi0gICAgICogPHA+Tm9ybWFsaXplIHRoaXMgaW5zdGFuY2UgdG8gVVRDLjwvcD4KLSAgICAgKgotICAgICAqIDxwPjIwMDAtMDMtMDRUMjM6MDA6MDArMDM6MDAgbm9ybWFsaXplcyB0byAyMDAwLTAzLTA0VDIwOjAwOjAwWjwvcD4KLSAgICAgKiA8cD5JbXBsZW1lbnRzIFczQyBYTUwgU2NoZW1hIFBhcnQgMiwgU2VjdGlvbiAzLjIuNy4zIChBKS48L3A+Ci0gICAgICoKLSAgICAgKiBAcmV0dXJuIDxjb2RlPnRoaXM8L2NvZGU+IDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiBub3JtYWxpemVkIHRvIFVUQy4KLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3QgWE1MR3JlZ29yaWFuQ2FsZW5kYXIgbm9ybWFsaXplKCk7Ci0KLSAgICAvKioKLSAgICAgKiA8cD5Db21wYXJlcyB0aGlzIGNhbGVuZGFyIHRvIHRoZSBzcGVjaWZpZWQgb2JqZWN0LiBUaGUgcmVzdWx0IGlzCi0gICAgICogPGNvZGU+dHJ1ZTwvY29kZT4gaWYgYW5kIG9ubHkgaWYgdGhlIGFyZ3VtZW50IGlzIG5vdCBudWxsIGFuZCBpcyBhbgotICAgICAqIDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiBvYmplY3QgdGhhdCByZXByZXNlbnRzIHRoZSBzYW1lCi0gICAgICogaW5zdGFudCBpbiB0aW1lIGFzIHRoaXMgb2JqZWN0LjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBvYmogdG8gY29tcGFyZS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gPGNvZGU+dHJ1ZTwvY29kZT4gd2hlbiA8Y29kZT5vYmo8L2NvZGU+IGlzIGFuIGluc3RhbmNlIG9mCi0gICAgICogPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IGFuZAotICAgICAqIHtAbGluayAjY29tcGFyZShYTUxHcmVnb3JpYW5DYWxlbmRhciBvYmopfQotICAgICAqIHJldHVybnMge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0VRVUFMfSwKLSAgICAgKiBvdGhlcndpc2UgPGNvZGU+ZmFsc2U8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqKSB7Ci0KLSAgICAgICAgaWYgKG9iaiA9PSBudWxsIHx8ICEob2JqIGluc3RhbmNlb2YgWE1MR3JlZ29yaWFuQ2FsZW5kYXIpKSB7Ci0gICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGNvbXBhcmUoKFhNTEdyZWdvcmlhbkNhbGVuZGFyKSBvYmopID09IERhdGF0eXBlQ29uc3RhbnRzLkVRVUFMOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPlJldHVybnMgYSBoYXNoIGNvZGUgY29uc2lzdGVudCB3aXRoIHRoZSBkZWZpbml0aW9uIG9mIHRoZSBlcXVhbHMgbWV0aG9kLjwvcD4KLSAgICAgKgotICAgICAqIEByZXR1cm4gaGFzaCBjb2RlIG9mIHRoaXMgb2JqZWN0LgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7Ci0KLSAgICAgICAgLy8gRm9sbG93aW5nIHR3byBkYXRlcyBjb21wYXJlIHRvIEVRVUFMUyBzaW5jZSBpbiBkaWZmZXJlbnQgdGltZXpvbmVzLgotICAgICAgICAvLyAyMDAwLTAxLTE1VDEyOjAwOjAwLTA1OjAwID09IDIwMDAtMDEtMTVUMTM6MDA6MDAtMDQ6MDAKLSAgICAgICAgLy8KLSAgICAgICAgLy8gTXVzdCBlbnN1cmUgYm90aCBpbnN0YW5jZXMgZ2VuZXJhdGUgc2FtZSBoYXNoY29kZSBieSBub3JtYWxpemluZwotICAgICAgICAvLyB0aGlzIHRvIFVUQyB0aW1lem9uZS4KLSAgICAgICAgaW50IHRpbWV6b25lID0gZ2V0VGltZXpvbmUoKTsKLSAgICAgICAgaWYgKHRpbWV6b25lID09IERhdGF0eXBlQ29uc3RhbnRzLkZJRUxEX1VOREVGSU5FRCkgewotICAgICAgICAgICAgdGltZXpvbmUgPSAwOwotICAgICAgICB9Ci0gICAgICAgIFhNTEdyZWdvcmlhbkNhbGVuZGFyIGdjID0gdGhpczsKLSAgICAgICAgaWYgKHRpbWV6b25lICE9IDApIHsKLSAgICAgICAgICAgIGdjID0gdGhpcy5ub3JtYWxpemUoKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZ2MuZ2V0WWVhcigpCi0gICAgICAgICAgICAgICAgKyBnYy5nZXRNb250aCgpCi0gICAgICAgICAgICAgICAgKyBnYy5nZXREYXkoKQotICAgICAgICAgICAgICAgICsgZ2MuZ2V0SG91cigpCi0gICAgICAgICAgICAgICAgKyBnYy5nZXRNaW51dGUoKQotICAgICAgICAgICAgICAgICsgZ2MuZ2V0U2Vjb25kKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+UmV0dXJuIHRoZSBsZXhpY2FsIHJlcHJlc2VudGF0aW9uIG9mIDxjb2RlPnRoaXM8L2NvZGU+IGluc3RhbmNlLgotICAgICAqIFRoZSBmb3JtYXQgaXMgc3BlY2lmaWVkIGluCi0gICAgICogPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveG1sc2NoZW1hLTIvI2RhdGVUaW1lLW9yZGVyIj5YTUwgU2NoZW1hIDEuMCBQYXJ0IDIsIFNlY3Rpb24gMy4yLls3LTE0XS4xLAotICAgICAqIDxpPkxleGljYWwgUmVwcmVzZW50YXRpb248L2k+Ii48L2E+PC9wPgotICAgICAqCi0gICAgICogPHA+U3BlY2lmaWMgdGFyZ2V0IGxleGljYWwgcmVwcmVzZW50YXRpb24gZm9ybWF0IGlzIGRldGVybWluZWQgYnkKLSAgICAgKiB7QGxpbmsgI2dldFhNTFNjaGVtYVR5cGUoKX0uPC9wPgotICAgICAqCi0gICAgICogQHJldHVybiBYTUwsIGFzIDxjb2RlPlN0cmluZzwvY29kZT4sIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+Ci0gICAgICoKLSAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGUgY29tYmluYXRpb24gb2Ygc2V0IGZpZWxkcwotICAgICAqICAgIGRvZXMgbm90IG1hdGNoIG9uZSBvZiB0aGUgZWlnaHQgZGVmaW5lZCBYTUwgU2NoZW1hIGJ1aWx0aW4gZGF0ZS90aW1lIGRhdGF0eXBlcy4KLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nIHRvWE1MRm9ybWF0KCk7Ci0KLSAgICAvKioKLSAgICAgKiA8cD5SZXR1cm4gdGhlIG5hbWUgb2YgdGhlIFhNTCBTY2hlbWEgZGF0ZS90aW1lIHR5cGUgdGhhdCB0aGlzIGluc3RhbmNlCi0gICAgICogbWFwcyB0by4gVHlwZSBpcyBjb21wdXRlZCBiYXNlZCBvbiBmaWVsZHMgdGhhdCBhcmUgc2V0LjwvcD4KLSAgICAgKgotICAgICAqIDx0YWJsZSBib3JkZXI9IjIiIHJ1bGVzPSJhbGwiIGNlbGxwYWRkaW5nPSIyIj4KLSAgICAgKiAgIDx0aGVhZD4KLSAgICAgKiAgICAgPHRyPgotICAgICAqICAgICAgIDx0aCBhbGlnbj0iY2VudGVyIiBjb2xzcGFuPSI3Ij4KLSAgICAgKiAgICAgICAgIFJlcXVpcmVkIGZpZWxkcyBmb3IgWE1MIFNjaGVtYSAxLjAgRGF0ZS9UaW1lIERhdGF0eXBlcy48YnIvPgotICAgICAqICAgICAgICAgPGk+KHRpbWV6b25lIGlzIG9wdGlvbmFsIGZvciBhbGwgZGF0ZS90aW1lIGRhdGF0eXBlcyk8L2k+Ci0gICAgICogICAgICAgPC90aD4KLSAgICAgKiAgICAgPC90cj4KLSAgICAgKiAgIDwvdGhlYWQ+Ci0gICAgICogICA8dGJvZHk+Ci0gICAgICogICAgIDx0cj4KLSAgICAgKiAgICAgICA8dGQ+RGF0YXR5cGU8L3RkPgotICAgICAqICAgICAgIDx0ZD55ZWFyPC90ZD4KLSAgICAgKiAgICAgICA8dGQ+bW9udGg8L3RkPgotICAgICAqICAgICAgIDx0ZD5kYXk8L3RkPgotICAgICAqICAgICAgIDx0ZD5ob3VyPC90ZD4KLSAgICAgKiAgICAgICA8dGQ+bWludXRlPC90ZD4KLSAgICAgKiAgICAgICA8dGQ+c2Vjb25kPC90ZD4KLSAgICAgKiAgICAgPC90cj4KLSAgICAgKiAgICAgPHRyPgotICAgICAqICAgICAgIDx0ZD57QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjREFURVRJTUV9PC90ZD4KLSAgICAgKiAgICAgICA8dGQ+WDwvdGQ+Ci0gICAgICogICAgICAgPHRkPlg8L3RkPgotICAgICAqICAgICAgIDx0ZD5YPC90ZD4KLSAgICAgKiAgICAgICA8dGQ+WDwvdGQ+Ci0gICAgICogICAgICAgPHRkPlg8L3RkPgotICAgICAqICAgICAgIDx0ZD5YPC90ZD4KLSAgICAgKiAgICAgPC90cj4KLSAgICAgKiAgICAgPHRyPgotICAgICAqICAgICAgIDx0ZD57QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjREFURX08L3RkPgotICAgICAqICAgICAgIDx0ZD5YPC90ZD4KLSAgICAgKiAgICAgICA8dGQ+WDwvdGQ+Ci0gICAgICogICAgICAgPHRkPlg8L3RkPgotICAgICAqICAgICAgIDx0ZD48L3RkPgotICAgICAqICAgICAgIDx0ZD48L3RkPgotICAgICAqICAgICAgIDx0ZD48L3RkPgotICAgICAqICAgICA8L3RyPgotICAgICAqICAgICA8dHI+Ci0gICAgICogICAgICAgPHRkPntAbGluayBEYXRhdHlwZUNvbnN0YW50cyNUSU1FfTwvdGQ+Ci0gICAgICogICAgICAgPHRkPjwvdGQ+Ci0gICAgICogICAgICAgPHRkPjwvdGQ+Ci0gICAgICogICAgICAgPHRkPjwvdGQ+Ci0gICAgICogICAgICAgPHRkPlg8L3RkPgotICAgICAqICAgICAgIDx0ZD5YPC90ZD4KLSAgICAgKiAgICAgICA8dGQ+WDwvdGQ+Ci0gICAgICogICAgIDwvdHI+Ci0gICAgICogICAgIDx0cj4KLSAgICAgKiAgICAgICA8dGQ+e0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0dZRUFSTU9OVEh9PC90ZD4KLSAgICAgKiAgICAgICA8dGQ+WDwvdGQ+Ci0gICAgICogICAgICAgPHRkPlg8L3RkPgotICAgICAqICAgICAgIDx0ZD48L3RkPgotICAgICAqICAgICAgIDx0ZD48L3RkPgotICAgICAqICAgICAgIDx0ZD48L3RkPgotICAgICAqICAgICAgIDx0ZD48L3RkPgotICAgICAqICAgICA8L3RyPgotICAgICAqICAgICA8dHI+Ci0gICAgICogICAgICAgPHRkPntAbGluayBEYXRhdHlwZUNvbnN0YW50cyNHTU9OVEhEQVl9PC90ZD4KLSAgICAgKiAgICAgICA8dGQ+PC90ZD4KLSAgICAgKiAgICAgICA8dGQ+WDwvdGQ+Ci0gICAgICogICAgICAgPHRkPlg8L3RkPgotICAgICAqICAgICAgIDx0ZD48L3RkPgotICAgICAqICAgICAgIDx0ZD48L3RkPgotICAgICAqICAgICAgIDx0ZD48L3RkPgotICAgICAqICAgICA8L3RyPgotICAgICAqICAgICA8dHI+Ci0gICAgICogICAgICAgPHRkPntAbGluayBEYXRhdHlwZUNvbnN0YW50cyNHWUVBUn08L3RkPgotICAgICAqICAgICAgIDx0ZD5YPC90ZD4KLSAgICAgKiAgICAgICA8dGQ+PC90ZD4KLSAgICAgKiAgICAgICA8dGQ+PC90ZD4KLSAgICAgKiAgICAgICA8dGQ+PC90ZD4KLSAgICAgKiAgICAgICA8dGQ+PC90ZD4KLSAgICAgKiAgICAgICA8dGQ+PC90ZD4KLSAgICAgKiAgICAgPC90cj4KLSAgICAgKiAgICAgPHRyPgotICAgICAqICAgICAgIDx0ZD57QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjR01PTlRIfTwvdGQ+Ci0gICAgICogICAgICAgPHRkPjwvdGQ+Ci0gICAgICogICAgICAgPHRkPlg8L3RkPgotICAgICAqICAgICAgIDx0ZD48L3RkPgotICAgICAqICAgICAgIDx0ZD48L3RkPgotICAgICAqICAgICAgIDx0ZD48L3RkPgotICAgICAqICAgICAgIDx0ZD48L3RkPgotICAgICAqICAgICA8L3RyPgotICAgICAqICAgICA8dHI+Ci0gICAgICogICAgICAgPHRkPntAbGluayBEYXRhdHlwZUNvbnN0YW50cyNHREFZfTwvdGQ+Ci0gICAgICogICAgICAgPHRkPjwvdGQ+Ci0gICAgICogICAgICAgPHRkPjwvdGQ+Ci0gICAgICogICAgICAgPHRkPlg8L3RkPgotICAgICAqICAgICAgIDx0ZD48L3RkPgotICAgICAqICAgICAgIDx0ZD48L3RkPgotICAgICAqICAgICAgIDx0ZD48L3RkPgotICAgICAqICAgICA8L3RyPgotICAgICAqICAgPC90Ym9keT4KLSAgICAgKiA8L3RhYmxlPgotICAgICAqCi0gICAgICogQHRocm93cyBqYXZhLmxhbmcuSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoZSBjb21iaW5hdGlvbiBvZiBzZXQgZmllbGRzCi0gICAgICogICAgZG9lcyBub3QgbWF0Y2ggb25lIG9mIHRoZSBlaWdodCBkZWZpbmVkIFhNTCBTY2hlbWEgYnVpbHRpbgotICAgICAqICAgIGRhdGUvdGltZSBkYXRhdHlwZXMuCi0gICAgICogQHJldHVybiBPbmUgb2YgdGhlIGZvbGxvd2luZyBjbGFzcyBjb25zdGFudHM6Ci0gICAgICogICB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjREFURVRJTUV9LAotICAgICAqICAge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI1RJTUV9LAotICAgICAqICAge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0RBVEV9LAotICAgICAqICAge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0dZRUFSTU9OVEh9LAotICAgICAqICAge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0dNT05USERBWX0sCi0gICAgICogICB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjR1lFQVJ9LAotICAgICAqICAge0BsaW5rIERhdGF0eXBlQ29uc3RhbnRzI0dNT05USH0gb3IKLSAgICAgKiAgIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNHREFZfS4KLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3QgUU5hbWUgZ2V0WE1MU2NoZW1hVHlwZSgpOwotCi0gICAgICAgIC8qKgotICAgICAgICAgKiA8cD5SZXR1cm5zIGEgPGNvZGU+U3RyaW5nPC9jb2RlPiByZXByZXNlbnRhdGlvbiBvZiB0aGlzIDxjb2RlPlhNTEdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiA8Y29kZT5PYmplY3Q8L2NvZGU+LjwvcD4KLSAgICAgICAgICoKLSAgICAgICAgICogPHA+VGhlIHJlc3VsdCBpcyBhIGxleGljYWwgcmVwcmVzZW50YXRpb24gZ2VuZXJhdGVkIGJ5IHtAbGluayAjdG9YTUxGb3JtYXQoKX0uPC9wPgotICAgICAgICAgKgotICAgICAgICAgKiBAcmV0dXJuIEEgbm9uLTxjb2RlPm51bGw8L2NvZGU+IHZhbGlkIDxjb2RlPlN0cmluZzwvY29kZT4gcmVwcmVzZW50YXRpb24gb2YgdGhpcyA8Y29kZT5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4uCi0gICAgICAgICAqCi0gICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhlIGNvbWJpbmF0aW9uIG9mIHNldCBmaWVsZHMKLSAgICAgKiAgICBkb2VzIG5vdCBtYXRjaCBvbmUgb2YgdGhlIGVpZ2h0IGRlZmluZWQgWE1MIFNjaGVtYSBidWlsdGluIGRhdGUvdGltZSBkYXRhdHlwZXMuCi0gICAgICoKLSAgICAgKiBAc2VlICN0b1hNTEZvcm1hdCgpCi0gICAgICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0KLSAgICAgICAgcmV0dXJuIHRvWE1MRm9ybWF0KCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVmFsaWRhdGUgaW5zdGFuY2UgYnkgPGNvZGU+Z2V0WE1MU2NoZW1hVHlwZSgpPC9jb2RlPiBjb25zdHJhaW50cy4KLSAgICAgKiBAcmV0dXJuIHRydWUgaWYgZGF0YSB2YWx1ZXMgYXJlIHZhbGlkLgotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGlzVmFsaWQoKTsKLQotICAgIC8qKgotICAgICAqIDxwPkFkZCA8Y29kZT5kdXJhdGlvbjwvY29kZT4gdG8gdGhpcyBpbnN0YW5jZS48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5UaGUgY29tcHV0YXRpb24gaXMgc3BlY2lmaWVkIGluCi0gICAgICogPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveG1sc2NoZW1hLTIvI2FkZGluZy1kdXJhdGlvbnMtdG8tZGF0ZVRpbWVzIj5YTUwgU2NoZW1hIDEuMCBQYXJ0IDIsIEFwcGVuZGl4IEUsCi0gICAgICogPGk+QWRkaW5nIGR1cmF0aW9ucyB0byBkYXRlVGltZXM8L2k+PjwvYT4uCi0gICAgICogPGEgaHJlZj0iI2RhdGV0aW1lZmllbGRtYXBwaW5nIj5kYXRlL3RpbWUgZmllbGQgbWFwcGluZyB0YWJsZTwvYT4KLSAgICAgKiBkZWZpbmVzIHRoZSBtYXBwaW5nIGZyb20gWE1MIFNjaGVtYSAxLjAgPGNvZGU+ZGF0ZVRpbWU8L2NvZGU+IGZpZWxkcwotICAgICAqIHRvIHRoaXMgY2xhc3MnIHJlcHJlc2VudGF0aW9uIG9mIHRob3NlIGZpZWxkcy48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gZHVyYXRpb24gRHVyYXRpb24gdG8gYWRkIHRvIHRoaXMgPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+LgotICAgICAqCi0gICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiAgd2hlbiA8Y29kZT5kdXJhdGlvbjwvY29kZT4gcGFyYW1ldGVyIGlzIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIGFkZChEdXJhdGlvbiBkdXJhdGlvbik7Ci0KLSAgICAvKioKLSAgICAgKiA8cD5Db252ZXJ0IHRoaXMgPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IHRvIGEge0BsaW5rIEdyZWdvcmlhbkNhbGVuZGFyfS48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5XaGVuIDxjb2RlPnRoaXM8L2NvZGU+IGluc3RhbmNlIGhhcyBhbiB1bmRlZmluZWQgZmllbGQsIHRoaXMKLSAgICAgKiBjb252ZXJzaW9uIHJlbGllcyBvbiB0aGUgPGNvZGU+amF2YS51dGlsLkdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiBkZWZhdWx0Ci0gICAgICogZm9yIGl0cyBjb3JyZXNwb25kaW5nIGZpZWxkLiBBIG5vdGFibGUgZGlmZmVyZW5jZSBiZXR3ZWVuCi0gICAgICogWE1MIFNjaGVtYSAxLjAgZGF0ZS90aW1lIGRhdGF0eXBlcyBhbmQgPGNvZGU+amF2YS51dGlsLkdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPgotICAgICAqIGlzIHRoYXQgVGltZXpvbmUgdmFsdWUgaXMgb3B0aW9uYWwgZm9yIGRhdGUvdGltZSBkYXRhdHlwZXMgYW5kIGl0IGlzCi0gICAgICogYSByZXF1aXJlZCBmaWVsZCBmb3IgPGNvZGU+amF2YS51dGlsLkdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPi4gU2VlIGphdmFkb2MKLSAgICAgKiBmb3IgPGNvZGU+amF2YS51dGlsLlRpbWVab25lLmdldERlZmF1bHQoKTwvY29kZT4gb24gaG93IHRoZSBkZWZhdWx0Ci0gICAgICogaXMgZGV0ZXJtaW5lZC4gVG8gZXhwbGljaXRseSBzcGVjaWZ5IHRoZSA8Y29kZT5UaW1lWm9uZTwvY29kZT4KLSAgICAgKiBpbnN0YW5jZSwgc2VlCi0gICAgICoge0BsaW5rICN0b0dyZWdvcmlhbkNhbGVuZGFyKFRpbWVab25lLCBMb2NhbGUsIFhNTEdyZWdvcmlhbkNhbGVuZGFyKX0uPC9wPgotICAgICAqCi0gICAgICogPHRhYmxlIGJvcmRlcj0iMiIgcnVsZXM9ImFsbCIgY2VsbHBhZGRpbmc9IjIiPgotICAgICAqICAgPHRoZWFkPgotICAgICAqICAgICA8dHI+Ci0gICAgICogICAgICAgPHRoIGFsaWduPSJjZW50ZXIiIGNvbHNwYW49IjIiPgotICAgICAqICAgICAgICAgIEZpZWxkIGJ5IEZpZWxkIENvbnZlcnNpb24gZnJvbSB0aGlzIGNsYXNzIHRvCi0gICAgICogICAgICAgICAgPGNvZGU+amF2YS51dGlsLkdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPgotICAgICAqICAgICAgIDwvdGg+Ci0gICAgICogICAgIDwvdHI+Ci0gICAgICogICA8L3RoZWFkPgotICAgICAqICAgPHRib2R5PgotICAgICAqICAgICA8dHI+Ci0gICAgICogICAgICAgIDx0ZD48Y29kZT5qYXZhLnV0aWwuR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IGZpZWxkPC90ZD4KLSAgICAgKiAgICAgICAgPHRkPjxjb2RlPmphdmF4LnhtbC5kYXRhdHlwZS5YTUxHcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gZmllbGQ8L3RkPgotICAgICAqICAgICA8L3RyPgotICAgICAqICAgICA8dHI+Ci0gICAgICogICAgICAgPHRkPjxjb2RlPkVSQTwvY29kZT48L3RkPgotICAgICAqICAgICAgIDx0ZD57QGxpbmsgI2dldEVvbkFuZFllYXIoKX08Y29kZT4uc2lnbnVtKCkgPCAwID8gR3JlZ29yaWFuQ2FsZW5kYXIuQkMgOiBHcmVnb3JpYW5DYWxlbmRhci5BRDwvY29kZT48L3RkPgotICAgICAqICAgICA8L3RyPgotICAgICAqICAgICA8dHI+Ci0gICAgICogICAgICAgPHRkPjxjb2RlPllFQVI8L2NvZGU+PC90ZD4KLSAgICAgKiAgICAgICA8dGQ+e0BsaW5rICNnZXRFb25BbmRZZWFyKCl9PGNvZGU+LmFicygpLmludFZhbHVlKCk8L2NvZGU+PGk+KjwvaT48L3RkPgotICAgICAqICAgICA8L3RyPgotICAgICAqICAgICA8dHI+Ci0gICAgICogICAgICAgPHRkPjxjb2RlPk1PTlRIPC9jb2RlPjwvdGQ+Ci0gICAgICogICAgICAgPHRkPntAbGluayAjZ2V0TW9udGgoKX0gLSB7QGxpbmsgRGF0YXR5cGVDb25zdGFudHMjSkFOVUFSWX0gKyB7QGxpbmsgR3JlZ29yaWFuQ2FsZW5kYXIjSkFOVUFSWX08L3RkPgotICAgICAqICAgICA8L3RyPgotICAgICAqICAgICA8dHI+Ci0gICAgICogICAgICAgPHRkPjxjb2RlPkRBWV9PRl9NT05USDwvY29kZT48L3RkPgotICAgICAqICAgICAgIDx0ZD57QGxpbmsgI2dldERheSgpfTwvdGQ+Ci0gICAgICogICAgIDwvdHI+Ci0gICAgICogICAgIDx0cj4KLSAgICAgKiAgICAgICA8dGQ+PGNvZGU+SE9VUl9PRl9EQVk8L2NvZGU+PC90ZD4KLSAgICAgKiAgICAgICA8dGQ+e0BsaW5rICNnZXRIb3VyKCl9PC90ZD4KLSAgICAgKiAgICAgPC90cj4KLSAgICAgKiAgICAgPHRyPgotICAgICAqICAgICAgIDx0ZD48Y29kZT5NSU5VVEU8L2NvZGU+PC90ZD4KLSAgICAgKiAgICAgICA8dGQ+e0BsaW5rICNnZXRNaW51dGUoKX08L3RkPgotICAgICAqICAgICA8L3RyPgotICAgICAqICAgICA8dHI+Ci0gICAgICogICAgICAgPHRkPjxjb2RlPlNFQ09ORDwvY29kZT48L3RkPgotICAgICAqICAgICAgIDx0ZD57QGxpbmsgI2dldFNlY29uZCgpfTwvdGQ+Ci0gICAgICogICAgIDwvdHI+Ci0gICAgICogICAgIDx0cj4KLSAgICAgKiAgICAgICA8dGQ+PGNvZGU+TUlMTElTRUNPTkQ8L2NvZGU+PC90ZD4KLSAgICAgKiAgICAgICA8dGQ+Z2V0IG1pbGxpc2Vjb25kIG9yZGVyIGZyb20ge0BsaW5rICNnZXRGcmFjdGlvbmFsU2Vjb25kKCl9PGk+KjwvaT4gPC90ZD4KLSAgICAgKiAgICAgPC90cj4KLSAgICAgKiAgICAgPHRyPgotICAgICAqICAgICAgIDx0ZD48Y29kZT5HcmVnb3JpYW5DYWxlbmRhci5zZXRUaW1lWm9uZShUaW1lWm9uZSk8L2NvZGU+PC90ZD4KLSAgICAgKiAgICAgICA8dGQ+e0BsaW5rICNnZXRUaW1lem9uZSgpfSBmb3JtYXR0ZWQgaW50byBDdXN0b20gdGltZXpvbmUgaWQ8L3RkPgotICAgICAqICAgICA8L3RyPgotICAgICAqICAgPC90Ym9keT4KLSAgICAgKiA8L3RhYmxlPgotICAgICAqIDxpPio8L2k+IGRlc2lnbmF0ZXMgcG9zc2libGUgbG9zcyBvZiBwcmVjaXNpb24gZHVyaW5nIHRoZSBjb252ZXJzaW9uIGR1ZQotICAgICAqIHRvIHNvdXJjZSBkYXRhdHlwZSBoYXZpbmcgaGlnaGVyIHByZWNpc2lvbiB0aGFuIHRhcmdldCBkYXRhdHlwZS4KLSAgICAgKgotICAgICAqIDxwPlRvIGVuc3VyZSBjb25zaXN0ZW5jeSBpbiBjb252ZXJzaW9uIGltcGxlbWVudGF0aW9ucywgdGhlIG5ldwotICAgICAqIDxjb2RlPkdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiBzaG91bGQgYmUgaW5zdGFudGlhdGVkIGluIGZvbGxvd2luZwotICAgICAqIG1hbm5lci4KLSAgICAgKiA8dWw+Ci0gICAgICogICA8bGk+VXNpbmcgPGNvZGU+dGltZVpvbmU8L2NvZGU+IHZhbHVlIGFzIGRlZmluZWQgYWJvdmUsIGNyZWF0ZSBhIG5ldwotICAgICAqIDxjb2RlPmphdmEudXRpbC5HcmVnb3JpYW5DYWxlbmRhcih0aW1lWm9uZSxMb2NhbGUuZ2V0RGVmYXVsdCgpKTwvY29kZT4uCi0gICAgICogICA8L2xpPgotICAgICAqICAgPGxpPkluaXRpYWxpemUgYWxsIEdyZWdvcmlhbkNhbGVuZGFyIGZpZWxkcyBieSBjYWxsaW5nIHtAbGluayBqYXZhLnV0aWwuR3JlZ29yaWFuQ2FsZW5kYXIjY2xlYXIoKX0uPC9saT4KLSAgICAgKiAgIDxsaT5PYnRhaW4gYSBwdXJlIEdyZWdvcmlhbiBDYWxlbmRhciBieSBpbnZva2luZwotICAgICAqICAgPGNvZGU+R3JlZ29yaWFuQ2FsZW5kYXIuc2V0R3JlZ29yaWFuQ2hhbmdlKAotICAgICAqICAgbmV3IERhdGUoTG9uZy5NSU5fVkFMVUUpKTwvY29kZT4uPC9saT4KLSAgICAgKiAgIDxsaT5JdHMgZmllbGRzIEVSQSwgWUVBUiwgTU9OVEgsIERBWV9PRl9NT05USCwgSE9VUl9PRl9EQVksCi0gICAgICogICAgICAgTUlOVVRFLCBTRUNPTkQgYW5kIE1JTExJU0VDT05EIGFyZSBzZXQgdXNpbmcgdGhlIG1ldGhvZAotICAgICAqICAgICAgIDxjb2RlPkNhbGVuZGFyLnNldChpbnQsaW50KTwvY29kZT48L2xpPgotICAgICAqIDwvdWw+Ci0gICAgICogPC9wPgotICAgICAqCi0gICAgICogQHNlZSAjdG9HcmVnb3JpYW5DYWxlbmRhcihqYXZhLnV0aWwuVGltZVpvbmUsIGphdmEudXRpbC5Mb2NhbGUsIFhNTEdyZWdvcmlhbkNhbGVuZGFyKQotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCBHcmVnb3JpYW5DYWxlbmRhciB0b0dyZWdvcmlhbkNhbGVuZGFyKCk7Ci0KLSAgICAvKioKLSAgICAgKiA8cD5Db252ZXJ0IHRoaXMgPGNvZGU+WE1MR3JlZ29yaWFuQ2FsZW5kYXI8L2NvZGU+IGFsb25nIHdpdGggcHJvdmlkZWQgcGFyYW1ldGVycwotICAgICAqIHRvIGEge0BsaW5rIEdyZWdvcmlhbkNhbGVuZGFyfSBpbnN0YW5jZS48L3A+Ci0gICAgICoKLSAgICAgKiA8cD4gU2luY2UgWE1MIFNjaGVtYSAxLjAgZGF0ZS90aW1lIGRhdGV0eXBlcyBoYXMgbm8gY29uY2VwdCBvZgotICAgICAqIHRpbWV6b25lIGlkcyBvciBkYXlsaWdodCBzYXZpbmdzIHRpbWV6b25lIGlkcywgdGhpcyBjb252ZXJzaW9uIG9wZXJhdGlvbgotICAgICAqIGFsbG93cyB0aGUgdXNlciB0byBleHBsaWNpdGx5IHNwZWNpZnkgb25lIHdpdGgKLSAgICAgKiA8Y29kZT50aW1lem9uZTwvY29kZT4gcGFyYW1ldGVyLjwvcD4KLSAgICAgKgotICAgICAqIDxwPlRvIGNvbXB1dGUgdGhlIHJldHVybiB2YWx1ZSdzIDxjb2RlPlRpbWVab25lPC9jb2RlPiBmaWVsZCwKLSAgICAgKiA8dWw+Ci0gICAgICogPGxpPndoZW4gcGFyYW1ldGVyIDxjb2RlPnRpbWVab25lPC9jb2RlPiBpcyBub24tbnVsbCwKLSAgICAgKiBpdCBpcyB0aGUgdGltZXpvbmUgZmllbGQuPC9saT4KLSAgICAgKiA8bGk+ZWxzZSB3aGVuIDxjb2RlPnRoaXMuZ2V0VGltZXpvbmUoKSAhPSBGSUVMRF9VTkRFRklORUQ8L2NvZGU+LAotICAgICAqIGNyZWF0ZSBhIDxjb2RlPmphdmEudXRpbC5UaW1lWm9uZTwvY29kZT4gd2l0aCBhIGN1c3RvbSB0aW1lem9uZSBpZAotICAgICAqIHVzaW5nIHRoZSA8Y29kZT50aGlzLmdldFRpbWV6b25lKCk8L2NvZGU+LjwvbGk+Ci0gICAgICogPGxpPmVsc2Ugd2hlbiA8Y29kZT5kZWZhdWx0cy5nZXRUaW1lem9uZSgpICE9IEZJRUxEX1VOREVGSU5FRDwvY29kZT4sCi0gICAgICogY3JlYXRlIGEgPGNvZGU+amF2YS51dGlsLlRpbWVab25lPC9jb2RlPiB3aXRoIGEgY3VzdG9tIHRpbWV6b25lIGlkCi0gICAgICogdXNpbmcgPGNvZGU+ZGVmYXVsdHMuZ2V0VGltZXpvbmUoKTwvY29kZT4uPC9saT4KLSAgICAgKiA8bGk+ZWxzZSB1c2UgdGhlIDxjb2RlPkdyZWdvcmlhbkNhbGVuZGFyPC9jb2RlPiBkZWZhdWx0IHRpbWV6b25lIHZhbHVlCi0gICAgICogZm9yIHRoZSBob3N0IGlzIGRlZmluZWQgYXMgc3BlY2lmaWVkIGJ5Ci0gICAgICogPGNvZGU+amF2YS51dGlsLlRpbWVab25lLmdldERlZmF1bHQoKTwvY29kZT4uPC9saT48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5UbyBlbnN1cmUgY29uc2lzdGVuY3kgaW4gY29udmVyc2lvbiBpbXBsZW1lbnRhdGlvbnMsIHRoZSBuZXcKLSAgICAgKiA8Y29kZT5HcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gc2hvdWxkIGJlIGluc3RhbnRpYXRlZCBpbiBmb2xsb3dpbmcKLSAgICAgKiBtYW5uZXIuCi0gICAgICogPHVsPgotICAgICAqICAgPGxpPkNyZWF0ZSBhIG5ldyA8Y29kZT5qYXZhLnV0aWwuR3JlZ29yaWFuQ2FsZW5kYXIoVGltZVpvbmUsCi0gICAgICogICAgICAgTG9jYWxlKTwvY29kZT4gd2l0aCBUaW1lWm9uZSBzZXQgYXMgc3BlY2lmaWVkIGFib3ZlIGFuZCB0aGUKLSAgICAgKiAgICAgICA8Y29kZT5Mb2NhbGU8L2NvZGU+IHBhcmFtZXRlci4KLSAgICAgKiAgIDwvbGk+Ci0gICAgICogICA8bGk+SW5pdGlhbGl6ZSBhbGwgR3JlZ29yaWFuQ2FsZW5kYXIgZmllbGRzIGJ5IGNhbGxpbmcge0BsaW5rIEdyZWdvcmlhbkNhbGVuZGFyI2NsZWFyKCl9PC9saT4KLSAgICAgKiAgIDxsaT5PYnRhaW4gYSBwdXJlIEdyZWdvcmlhbiBDYWxlbmRhciBieSBpbnZva2luZwotICAgICAqICAgPGNvZGU+R3JlZ29yaWFuQ2FsZW5kYXIuc2V0R3JlZ29yaWFuQ2hhbmdlKAotICAgICAqICAgbmV3IERhdGUoTG9uZy5NSU5fVkFMVUUpKTwvY29kZT4uPC9saT4KLSAgICAgKiAgIDxsaT5JdHMgZmllbGRzIEVSQSwgWUVBUiwgTU9OVEgsIERBWV9PRl9NT05USCwgSE9VUl9PRl9EQVksCi0gICAgICogICAgICAgTUlOVVRFLCBTRUNPTkQgYW5kIE1JTExJU0VDT05EIGFyZSBzZXQgdXNpbmcgdGhlIG1ldGhvZAotICAgICAqICAgICAgIDxjb2RlPkNhbGVuZGFyLnNldChpbnQsaW50KTwvY29kZT48L2xpPgotICAgICAqIDwvdWw+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gdGltZXpvbmUgcHJvdmlkZSBUaW1lem9uZS4gPGNvZGU+bnVsbDwvY29kZT4gaXMgYSBsZWdhbCB2YWx1ZS4KLSAgICAgKiBAcGFyYW0gYUxvY2FsZSAgcHJvdmlkZSBleHBsaWNpdCBMb2NhbGUuIFVzZSBkZWZhdWx0IEdyZWdvcmlhbkNhbGVuZGFyIGxvY2FsZSBpZgotICAgICAqICAgICAgICAgICAgICAgICB2YWx1ZSBpcyA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICAgKiBAcGFyYW0gZGVmYXVsdHMgcHJvdmlkZSBkZWZhdWx0IGZpZWxkIHZhbHVlcyB0byB1c2Ugd2hlbiBjb3JyZXNwb25kaW5nCi0gICAgICogICAgICAgICAgICAgICAgIGZpZWxkIGZvciB0aGlzIGluc3RhbmNlIGlzIEZJRUxEX1VOREVGSU5FRCBvciBudWxsLgotICAgICAqICAgICAgICAgICAgICAgICBJZiA8Y29kZT5kZWZhdWx0czwvY29kZT5pcyA8Y29kZT5udWxsPC9jb2RlPiBvciBhIGZpZWxkCi0gICAgICogICAgICAgICAgICAgICAgIHdpdGhpbiB0aGUgc3BlY2lmaWVkIDxjb2RlPmRlZmF1bHRzPC9jb2RlPiBpcyB1bmRlZmluZWQsCi0gICAgICogICAgICAgICAgICAgICAgIGp1c3QgdXNlIDxjb2RlPmphdmEudXRpbC5HcmVnb3JpYW5DYWxlbmRhcjwvY29kZT4gZGVmYXVsdHMuCi0gICAgICogQHJldHVybiBhIGphdmEudXRpbC5HcmVnb3JpYW5DYWxlbmRhciBjb252ZXJzaW9uIG9mIHRoaXMgaW5zdGFuY2UuCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IEdyZWdvcmlhbkNhbGVuZGFyIHRvR3JlZ29yaWFuQ2FsZW5kYXIoCi0gICAgICAgIGphdmEudXRpbC5UaW1lWm9uZSB0aW1lem9uZSwKLSAgICAgICAgICAgICAgICBqYXZhLnV0aWwuTG9jYWxlIGFMb2NhbGUsCi0gICAgICAgICAgICAgICAgWE1MR3JlZ29yaWFuQ2FsZW5kYXIgZGVmYXVsdHMpOwotCi0gICAgLyoqCi0gICAgICogPHA+UmV0dXJucyBhIDxjb2RlPmphdmEudXRpbC5UaW1lWm9uZTwvY29kZT4gZm9yIHRoaXMgY2xhc3MuPC9wPgotICAgICAqCi0gICAgICogPHA+SWYgdGltZXpvbmUgZmllbGQgaXMgZGVmaW5lZCBmb3IgdGhpcyBpbnN0YW5jZSwKLSAgICAgKiByZXR1cm5zIFRpbWVab25lIGluaXRpYWxpemVkIHdpdGggY3VzdG9tIHRpbWV6b25lIGlkCi0gICAgICogb2Ygem9uZW9mZnNldC4gSWYgdGltZXpvbmUgZmllbGQgaXMgdW5kZWZpbmVkLAotICAgICAqIHRyeSB0aGUgZGVmYXVsdFpvbmVvZmZzZXQgdGhhdCB3YXMgcGFzc2VkIGluLgotICAgICAqIElmIGRlZmF1bHRab25lb2Zmc2V0IGlzIEZJRUxEX1VOREVGSU5FRCwgcmV0dXJuCi0gICAgICogZGVmYXVsdCB0aW1lem9uZSBmb3IgdGhpcyBob3N0LgotICAgICAqIChTYW1lIGRlZmF1bHQgYXMgamF2YS51dGlsLkdyZWdvcmlhbkNhbGVuZGFyKS48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gZGVmYXVsdFpvbmVvZmZzZXQgZGVmYXVsdCB6b25lb2Zmc2V0IGlmIHRoaXMgem9uZW9mZnNldCBpcwotICAgICAqIHtAbGluayBEYXRhdHlwZUNvbnN0YW50cyNGSUVMRF9VTkRFRklORUR9LgotICAgICAqCi0gICAgICogQHJldHVybiBUaW1lWm9uZSBmb3IgdGhpcy4KLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3QgVGltZVpvbmUgZ2V0VGltZVpvbmUoaW50IGRlZmF1bHRab25lb2Zmc2V0KTsKLQotCi0KLSAgICAvKioKLSAgICAgKiA8cD5DcmVhdGVzIGFuZCByZXR1cm5zIGEgY29weSBvZiB0aGlzIG9iamVjdC48L3A+Ci0gICAgICoKLSAgICAgKiBAcmV0dXJuIGNvcHkgb2YgdGhpcyA8Y29kZT5PYmplY3Q8L2NvZGU+Ci0gICAgICovCi0gICBwdWJsaWMgYWJzdHJhY3QgT2JqZWN0IGNsb25lKCk7Ci19CmRpZmYgLS1naXQgYS9zcmMvamF2YXgveG1sL2RhdGF0eXBlL3BhY2thZ2UuaHRtbCBiL3NyYy9qYXZheC94bWwvZGF0YXR5cGUvcGFja2FnZS5odG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhZjgxNDU0Li4wMDAwMDAwCi0tLSBhL3NyYy9qYXZheC94bWwvZGF0YXR5cGUvcGFja2FnZS5odG1sCisrKyAvZGV2L251bGwKQEAgLTEsMTcwICswLDAgQEAKLTw/eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04Ij8+Ci08IS0tCi1Db3B5cmlnaHQgKGMpIDIwMDQsIDIwMDUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi1ETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0KLVRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci11bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi1wYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi1ieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLQotVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi1BTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLUZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLWFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0KLVlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLTIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLUluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLQotUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLW9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLXF1ZXN0aW9ucy4gCi0tLT4KLQotPCFET0NUWVBFIGh0bWwgUFVCTElDICItLy9XM0MvL0RURCBYSFRNTCAxLjAgU3RyaWN0Ly9FTiIgImh0dHA6Ly93d3cudzMub3JnL1RSL3hodG1sMS9EVEQveGh0bWwxLXN0cmljdC5kdGQiPgotPGh0bWwgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwiPgotCi0JPGhlYWQ+Ci0JCTx0aXRsZT5qYXZheC54bWwueHBhdGg8L3RpdGxlPgotCi0JCTxtZXRhIG5hbWU9IkBhdXRob3IiIGNvbnRlbnQ9Im1haWx0bzpKZWZmLlN1dHRvckBTdW4uY29tIiAvPgotCQk8bWV0YSBuYW1lPSJAdmVyc2lvbiIgY29udGVudD0iJFJldmlzaW9uOiAxLjIgJCwgJERhdGU6IDIwMDUvMDYvMTAgMDM6NTA6MjcgJCIgLz4KLQkJPG1ldGEgbmFtZT0iQHNlZSIgY29udGVudD0nPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveG1sc2NoZW1hLTIvI2RhdGVUaW1lIj5XM0MgWE1MIFNjaGVtYSAxLjAgUGFydCAyLCBTZWN0aW9uIDMuMi43LTE0PC9hPicgLz4KLQkJPG1ldGEgbmFtZT0iQHNlZSIgY29udGVudD0nPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGgtZGF0YW1vZGVsI2R0LWRheVRpbWVEdXJhdGlvbiI+WFF1ZXJ5IDEuMCBhbmQgWFBhdGggMi4wIERhdGEgTW9kZWwsIHhkdDpkYXlUaW1lRHVyYXRpb248L2E+JyAvPgotCQk8bWV0YSBuYW1lPSJAc2VlIiBjb250ZW50PSc8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aC1kYXRhbW9kZWwjZHQteWVhck1vbnRoRHVyYXRpb24iPlhRdWVyeSAxLjAgYW5kIFhQYXRoIDIuMCBEYXRhIE1vZGVsLCB4ZHQ6eWVhck1vbnRoRHVyYXRpb248L2E+JyAvPgotCQk8bWV0YSBuYW1lPSJAc2luY2UiIGNvbnRlbnQ9IjEuNSIgLz4KLQk8L2hlYWQ+Ci0KLQk8Ym9keT4KLQotCQk8cD5YTUwvSmF2YSBUeXBlIE1hcHBpbmdzLjwvcD4KLQkJCi0JCTxwPjxjb2RlPmphdmF4LnhtbC5kYXRhdHlwZTwvY29kZT5BUEkgcHJvdmlkZXMgWE1ML0phdmEgdHlwZSBtYXBwaW5ncy48L3A+Ci0JCQotCQk8cD5UaGUgZm9sbG93aW5nIFhNTCBzdGFuZGFyZHMgYXBwbHk6PC9wPgotCQk8dWw+Ci0JCQk8bGk+PGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveG1sc2NoZW1hLTIvI2RhdGVUaW1lIj5XM0MgWE1MIFNjaGVtYSAxLjAgUGFydCAyLCBTZWN0aW9uIDMuMi43LTE0PC9hPjwvbGk+Ci0JCQk8bGk+PGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGgtZGF0YW1vZGVsI2R0LWRheVRpbWVEdXJhdGlvbiI+WFF1ZXJ5IDEuMCBhbmQgWFBhdGggMi4wIERhdGEgTW9kZWwsIHhkdDpkYXlUaW1lRHVyYXRpb248L2E+PC9saT4KLQkJCTxsaT48YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aC1kYXRhbW9kZWwjZHQteWVhck1vbnRoRHVyYXRpb24iPlhRdWVyeSAxLjAgYW5kIFhQYXRoIDIuMCBEYXRhIE1vZGVsLCB4ZHQ6eWVhck1vbnRoRHVyYXRpb248L2E+PC9saT4KLQkJPC91bD4KLQotCQk8aHIgLz4KLQkJCi0JCTx0YWJsZSBib3JkZXI9IjEiIGNlbGxwYWRkaW5nPSIyIj4KLQkJCTx0aGVhZD4KLQkJCQk8dHI+Ci0JCQkJCTx0aD5XM0MgWE1MIFNjaGVtYSBEYXRhIFR5cGU8L3RoPgotCQkJCQk8dGg+SmF2YSBEYXRhIFR5cGU8L3RoPgotCQkJCTwvdHI+Ci0JCQk8L3RoZWFkPgotCQkJCi0JCQk8dGJvZHk+Ci0JCQkJPHRyPgotCQkJCQk8dGQ+eHM6ZGF0ZTwvdGQ+Ci0JCQkJCTx0ZD57QGxpbmsgamF2YXgueG1sLmRhdGF0eXBlLlhNTEdyZWdvcmlhbkNhbGVuZGFyfTwvdGQ+Ci0JCQkJPC90cj4KLQkJCQk8dHI+Ci0JCQkJCTx0ZD54czpkYXRlVGltZTwvdGQ+Ci0JCQkJCTx0ZD57QGxpbmsgamF2YXgueG1sLmRhdGF0eXBlLlhNTEdyZWdvcmlhbkNhbGVuZGFyfTwvdGQ+Ci0JCQkJPC90cj4KLQkJCQk8dHI+Ci0JCQkJCTx0ZD54czpkdXJhdGlvbjwvdGQ+Ci0JCQkJCTx0ZD57QGxpbmsgamF2YXgueG1sLmRhdGF0eXBlLkR1cmF0aW9ufTwvdGQ+Ci0JCQkJPC90cj4KLQkJCQk8dHI+Ci0JCQkJCTx0ZD54czpnRGF5PC90ZD4KLQkJCQkJPHRkPntAbGluayBqYXZheC54bWwuZGF0YXR5cGUuWE1MR3JlZ29yaWFuQ2FsZW5kYXJ9PC90ZD4KLQkJCQk8L3RyPgotCQkJCTx0cj4KLQkJCQkJPHRkPnhzOmdNb250aCA8L3RkPgotCQkJCQk8dGQ+e0BsaW5rIGphdmF4LnhtbC5kYXRhdHlwZS5YTUxHcmVnb3JpYW5DYWxlbmRhcn08L3RkPgotCQkJCTwvdHI+Ci0JCQkJPHRyPgotCQkJCQk8dGQ+eHM6Z01vbnRoRGF5PC90ZD4KLQkJCQkJPHRkPntAbGluayBqYXZheC54bWwuZGF0YXR5cGUuWE1MR3JlZ29yaWFuQ2FsZW5kYXJ9PC90ZD4KLQkJCQk8L3RyPgotCQkJCTx0cj4KLQkJCQkJPHRkPnhzOmdZZWFyPC90ZD4KLQkJCQkJPHRkPntAbGluayBqYXZheC54bWwuZGF0YXR5cGUuWE1MR3JlZ29yaWFuQ2FsZW5kYXJ9PC90ZD4KLQkJCQk8L3RyPgotCQkJCTx0cj4KLQkJCQkJPHRkPnhzOmdZZWFyTW9udGg8L3RkPgotCQkJCQk8dGQ+e0BsaW5rIGphdmF4LnhtbC5kYXRhdHlwZS5YTUxHcmVnb3JpYW5DYWxlbmRhcn08L3RkPgotCQkJCTwvdHI+Ci0JCQkJPHRyPgotCQkJCQk8dGQ+eHM6dGltZTwvdGQ+Ci0JCQkJCTx0ZD57QGxpbmsgamF2YXgueG1sLmRhdGF0eXBlLlhNTEdyZWdvcmlhbkNhbGVuZGFyfTwvdGQ+Ci0JCQkJPC90cj4KLQkJCQkKLQkJCTwvdGJvZHk+Ci0JCTwvdGFibGU+Ci0JCQotCQk8aHIgLz4KLQkJCi0JCQotCQk8dGFibGUgYm9yZGVyPSIxIiBjZWxscGFkZGluZz0iMiI+Ci0JCQk8dGhlYWQ+Ci0JCQkJPHRyPgotCQkJCQk8dGg+WFF1ZXJ5IDEuMCBhbmQgWFBhdGggMi4wIERhdGEgTW9kZWw8L3RoPgotCQkJCQk8dGg+SmF2YSBEYXRhIFR5cGU8L3RoPgotCQkJCTwvdHI+Ci0JCQk8L3RoZWFkPgotCQkJCi0JCQk8dGJvZHk+Ci0JCQkJPHRyPgotCQkJCQk8dGQ+eGR0OmRheVRpbWVEdXJhdGlvbjwvdGQ+Ci0JCQkJCTx0ZD57QGxpbmsgamF2YXgueG1sLmRhdGF0eXBlLkR1cmF0aW9ufTwvdGQ+Ci0JCQkJPC90cj4KLQkJCQk8dHI+Ci0JCQkJCTx0ZD54ZHQ6eWVhck1vbnRoRHVyYXRpb248L3RkPgotCQkJCQk8dGQ+e0BsaW5rIGphdmF4LnhtbC5kYXRhdHlwZS5EdXJhdGlvbn08L3RkPgotCQkJCTwvdHI+Ci0JCQk8L3Rib2R5PgotCQk8L3RhYmxlPgotCQkKLQkJPGhyIC8+Ci0JCQotCQk8cD4KLQkJCVczQyBYTUwgU2NoZW1hIGRhdGEgdHlwZXMgdGhhdCBoYXZlIGEgIjxlbT5uYXR1cmFsPC9lbT4iIG1hcHBpbmcgdG8gSmF2YSB0eXBlcyBhcmUgZGVmaW5lZCBieQotCQkJSlNSIDMxOiBKYXZhJnRyYWRlOyBBcmNoaXRlY3R1cmUgZm9yIFhNTCBCaW5kaW5nIChKQVhCKSBTcGVjaWZpY2F0aW9uLCBCaW5kaW5nIFhNTCBTY2hlbWEgdG8gSmF2YSBSZXByZXNlbnRhdGlvbnMuCi0JCQlKQVhCIGRlZmluZWQgbWFwcGluZ3MgZm9yIFhNTCBTY2hlbWEgYnVpbHQtaW4gZGF0YSB0eXBlcyBpbmNsdWRlOgotCQk8L3A+Ci0JCTx1bD4KLQkJCTxsaT54czphbnlTaW1wbGVUeXBlPC9saT4KLQkJCTxsaT54czpiYXNlNjRCaW5hcnk8L2xpPgotCQkJPGxpPnhzOmJvb2xlYW48L2xpPgotCQkJPGxpPnhzOmJ5dGU8L2xpPgotCQkJPGxpPnhzOmRlY2ltYWw8L2xpPgotCQkJPGxpPnhzOmRvdWJsZTwvbGk+Ci0JCQk8bGk+eHM6ZmxvYXQ8L2xpPgotCQkJPGxpPnhzOmhleEJpbmFyeTwvbGk+Ci0JCQk8bGk+eHM6aW50PC9saT4KLQkJCTxsaT54czppbnRlZ2VyPC9saT4KLQkJCTxsaT54czpsb25nPC9saT4KLQkJCTxsaT54czpRTmFtZTwvbGk+Ci0JCQk8bGk+eHM6c2hvcnQ8L2xpPgotCQkJPGxpPnhzOnN0cmluZzwvbGk+Ci0JCQk8bGk+eHM6dW5zaWduZWRCeXRlPC9saT4KLQkJCTxsaT54czp1bnNpZ25lZEludDwvbGk+Ci0JCQk8bGk+eHM6dW5zaWduZWRTaG9ydDwvbGk+Ci0JCTwvdWw+Ci0JCQotCQk8aHIgLz4KLQkJCi0KLQkJPHVsPgotCQkJPGxpPkF1dGhvciA8YSBocmVmPSJtYWlsdG86SmVmZi5TdXR0b3JAU3VuLmNvbSI+SmVmZiBTdXR0b3I8L2E+PC9saT4KLQkJCTxsaT5TZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveG1sc2NoZW1hLTIvI2RhdGVUaW1lIj5XM0MgWE1MIFNjaGVtYSAxLjAgUGFydCAyLCBTZWN0aW9uIDMuMi43LTE0PC9hPjwvbGk+Ci0JCQk8bGk+U2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hwYXRoLWRhdGFtb2RlbCNkdC1kYXlUaW1lRHVyYXRpb24iPlhRdWVyeSAxLjAgYW5kIFhQYXRoIDIuMCBEYXRhIE1vZGVsLCB4ZHQ6ZGF5VGltZUR1cmF0aW9uPC9hPjwvbGk+Ci0JCQk8bGk+U2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hwYXRoLWRhdGFtb2RlbCNkdC15ZWFyTW9udGhEdXJhdGlvbiI+WFF1ZXJ5IDEuMCBhbmQgWFBhdGggMi4wIERhdGEgTW9kZWwsIHhkdDp5ZWFyTW9udGhEdXJhdGlvbjwvYT48L2xpPgotCQkJPGxpPlNpbmNlIDEuNTwvbGk+Ci0JCTwvdWw+Ci0JCQotCQk8aHIgLz4KLQkJCi0KLQk8L2JvZHk+Ci08L2h0bWw+CmRpZmYgLS1naXQgYS9zcmMvamF2YXgveG1sL25hbWVzcGFjZS9OYW1lc3BhY2VDb250ZXh0LmphdmEgYi9zcmMvamF2YXgveG1sL25hbWVzcGFjZS9OYW1lc3BhY2VDb250ZXh0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGYxY2U2OTMuLjAwMDAwMDAKLS0tIGEvc3JjL2phdmF4L3htbC9uYW1lc3BhY2UvTmFtZXNwYWNlQ29udGV4dC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjg4ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDMsIDIwMDUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLXBhY2thZ2UgamF2YXgueG1sLm5hbWVzcGFjZTsKLQotaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKLQotLyoqCi0gKiA8cD5JbnRlcmZhY2UgZm9yIHJlYWQgb25seSBYTUwgTmFtZXNwYWNlIGNvbnRleHQgcHJvY2Vzc2luZy48L3A+Ci0gKgotICogPHA+QW4gWE1MIE5hbWVzcGFjZSBoYXMgdGhlIHByb3BlcnRpZXM6PC9wPgotICogPHVsPgotICogICA8bGk+TmFtZXNwYWNlIFVSSToKLSAqICAgICAgIE5hbWVzcGFjZSBuYW1lIGV4cHJlc3NlZCBhcyBhIFVSSSB0byB3aGljaCB0aGUgcHJlZml4IGlzIGJvdW5kPC9saT4KLSAqICAgPGxpPnByZWZpeDogc3ludGFjdGljYWxseSwgdGhpcyBpcyB0aGUgcGFydCBvZiB0aGUgYXR0cmlidXRlIG5hbWUKLSAqICAgICAgIGZvbGxvd2luZyB0aGUgPGNvZGU+WE1MQ29uc3RhbnRzLlhNTE5TX0FUVFJJQlVURTwvY29kZT4KLSAqICAgICAgICgieG1sbnMiKSBpbiB0aGUgTmFtZXNwYWNlIGRlY2xhcmF0aW9uPC9saT4KLSAqIDwvdWw+Ci0gKiA8cD5leGFtcGxlOgotICogPGNvZGU+Jmx0O2VsZW1lbnQgeG1sbnM6cHJlZml4PSJodHRwOi8vTmFtZXNwYWNlLW5hbWUtVVJJIiZndDs8L2NvZGU+PC9wPgotICoKLSAqIDxwPkFsbCA8Y29kZT5nZXQqKCopPC9jb2RlPiBtZXRob2RzIG9wZXJhdGUgaW4gdGhlIGN1cnJlbnQgc2NvcGUKLSAqIGZvciBOYW1lc3BhY2UgVVJJIGFuZCBwcmVmaXggcmVzb2x1dGlvbi48L3A+Ci0gKgotICogPHA+Tm90ZSB0aGF0IGEgTmFtZXNwYWNlIFVSSSBjYW4gYmUgYm91bmQgdG8KLSAqIDxzdHJvbmc+bXVsdGlwbGU8L3N0cm9uZz4gcHJlZml4ZXMgaW4gdGhlIGN1cnJlbnQgc2NvcGUuICBUaGlzIGNhbgotICogb2NjdXIgd2hlbiBtdWx0aXBsZSA8Y29kZT5YTUxDb25zdGFudHMuWE1MTlNfQVRUUklCVVRFPC9jb2RlPgotICogKCJ4bWxucyIpIE5hbWVzcGFjZSBkZWNsYXJhdGlvbnMgb2NjdXIgaW4gdGhlIHNhbWUgU3RhcnQtVGFnIGFuZAotICogcmVmZXIgdG8gdGhlIHNhbWUgTmFtZXNwYWNlIFVSSS4gZS5nLjxiciAvPgotICogPHByZT4KLSAqICZsdDtlbGVtZW50IHhtbG5zOnByZWZpeDE9Imh0dHA6Ly9OYW1lc3BhY2UtbmFtZS1VUkkiCi0gKiAgICAgICAgICB4bWxuczpwcmVmaXgyPSJodHRwOi8vTmFtZXNwYWNlLW5hbWUtVVJJIiZndDsKLSAqIDwvcHJlPgotICogVGhpcyBjYW4gYWxzbyBvY2N1ciB3aGVuIHRoZSBzYW1lIE5hbWVzcGFjZSBVUkkgaXMgdXNlZCBpbiBtdWx0aXBsZQotICogPGNvZGU+WE1MQ29uc3RhbnRzLlhNTE5TX0FUVFJJQlVURTwvY29kZT4gKCJ4bWxucyIpIE5hbWVzcGFjZQotICogZGVjbGFyYXRpb25zIGluIHRoZSBsb2dpY2FsIHBhcmVudCBlbGVtZW50IGhpZXJhcmNoeS4gIGUuZy48YnIgLz4KLSAqIDxwcmU+Ci0gKiAmbHQ7cGFyZW50IHhtbG5zOnByZWZpeDE9Imh0dHA6Ly9OYW1lc3BhY2UtbmFtZS1VUkkiPgotICogICAmbHQ7Y2hpbGQgeG1sbnM6cHJlZml4Mj0iaHR0cDovL05hbWVzcGFjZS1uYW1lLVVSSSImZ3Q7Ci0gKiAgICAgLi4uCi0gKiAgICZsdDsvY2hpbGQmZ3Q7Ci0gKiAmbHQ7L3BhcmVudCZndDsKLSAqIDwvcHJlPjwvcD4KLSAqCi0gKiA8cD5BIHByZWZpeCBjYW4gb25seSBiZSBib3VuZCB0byBhIDxzdHJvbmc+c2luZ2xlPC9zdHJvbmc+Ci0gKiBOYW1lc3BhY2UgVVJJIGluIHRoZSBjdXJyZW50IHNjb3BlLjwvcD4KLSAqCi0gKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzpKZWZmLlN1dHRvckBTdW4uY29tIj5KZWZmIFN1dHRvcjwvYT4KLSAqIEBzZWUgamF2YXgueG1sLlhNTENvbnN0YW50cwotICogICBqYXZheC54bWwuWE1MQ29uc3RhbnRzIGZvciBkZWNsYXJhdGlvbnMgb2YgY29tbW9uIFhNTCB2YWx1ZXMKLSAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveG1sc2NoZW1hLTIvI1FOYW1lIj4KLSAqICAgWE1MIFNjaGVtYSBQYXJ0MjogRGF0YXR5cGVzPC9hPgotICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMteG1sLW5hbWVzLyNucy1xdWFsbmFtZXMiPgotICogICBOYW1lc3BhY2VzIGluIFhNTDwvYT4KLSAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvWE1ML3htbC1uYW1lcy0xOTk5MDExNC1lcnJhdGEiPgotICogICBOYW1lc3BhY2VzIGluIFhNTCBFcnJhdGE8L2E+Ci0gKiBAc2luY2UgMS41Ci0gKi8KLQotcHVibGljIGludGVyZmFjZSBOYW1lc3BhY2VDb250ZXh0IHsKLQotICAgIC8qKgotICAgICAqIDxwPkdldCBOYW1lc3BhY2UgVVJJIGJvdW5kIHRvIGEgcHJlZml4IGluIHRoZSBjdXJyZW50IHNjb3BlLjwvcD4KLSAgICAgKgotICAgICAqIDxwPldoZW4gcmVxdWVzdGluZyBhIE5hbWVzcGFjZSBVUkkgYnkgcHJlZml4LCB0aGUgZm9sbG93aW5nCi0gICAgICogdGFibGUgZGVzY3JpYmVzIHRoZSByZXR1cm5lZCBOYW1lc3BhY2UgVVJJIHZhbHVlIGZvciBhbGwKLSAgICAgKiBwb3NzaWJsZSBwcmVmaXggdmFsdWVzOjwvcD4KLSAgICAgKgotICAgICAqIDx0YWJsZSBib3JkZXI9IjIiIHJ1bGVzPSJhbGwiIGNlbGxwYWRkaW5nPSI0Ij4KLSAgICAgKiAgIDx0aGVhZD4KLSAgICAgKiAgICAgPHRyPgotICAgICAqICAgICAgIDx0ZCBhbGlnbj0iY2VudGVyIiBjb2xzcGFuPSIyIj4KLSAgICAgKiAgICAgICAgIDxjb2RlPmdldE5hbWVzcGFjZVVSSShwcmVmaXgpPC9jb2RlPgotICAgICAqICAgICAgICAgcmV0dXJuIHZhbHVlIGZvciBzcGVjaWZpZWQgcHJlZml4ZXMKLSAgICAgKiAgICAgICA8L3RkPgotICAgICAqICAgICA8L3RyPgotICAgICAqICAgICA8dHI+Ci0gICAgICogICAgICAgPHRkPnByZWZpeCBwYXJhbWV0ZXI8L3RkPgotICAgICAqICAgICAgIDx0ZD5OYW1lc3BhY2UgVVJJIHJldHVybiB2YWx1ZTwvdGQ+Ci0gICAgICogICAgIDwvdHI+Ci0gICAgICogICA8L3RoZWFkPgotICAgICAqICAgPHRib2R5PgotICAgICAqICAgICA8dHI+Ci0gICAgICogICAgICAgPHRkPjxjb2RlPkRFRkFVTFRfTlNfUFJFRklYPC9jb2RlPiAoIiIpPC90ZD4KLSAgICAgKiAgICAgICA8dGQ+ZGVmYXVsdCBOYW1lc3BhY2UgVVJJIGluIHRoZSBjdXJyZW50IHNjb3BlIG9yCi0gICAgICogICAgICAgICA8Y29kZT57QGxpbmsKLSAgICAgKiAgICAgICAgIGphdmF4LnhtbC5YTUxDb25zdGFudHMjTlVMTF9OU19VUkkgWE1MQ29uc3RhbnRzLk5VTExfTlNfVVJJKCIiKX0KLSAgICAgKiAgICAgICAgIDwvY29kZT4KLSAgICAgKiAgICAgICAgIHdoZW4gdGhlcmUgaXMgbm8gZGVmYXVsdCBOYW1lc3BhY2UgVVJJIGluIHRoZSBjdXJyZW50IHNjb3BlPC90ZD4KLSAgICAgKiAgICAgPC90cj4KLSAgICAgKiAgICAgPHRyPgotICAgICAqICAgICAgIDx0ZD5ib3VuZCBwcmVmaXg8L3RkPgotICAgICAqICAgICAgIDx0ZD5OYW1lc3BhY2UgVVJJIGJvdW5kIHRvIHByZWZpeCBpbiBjdXJyZW50IHNjb3BlPC90ZD4KLSAgICAgKiAgICAgPC90cj4KLSAgICAgKiAgICAgPHRyPgotICAgICAqICAgICAgIDx0ZD51bmJvdW5kIHByZWZpeDwvdGQ+Ci0gICAgICogICAgICAgPHRkPgotICAgICAqICAgICAgICAgPGNvZGU+e0BsaW5rCi0gICAgICogICAgICAgICBqYXZheC54bWwuWE1MQ29uc3RhbnRzI05VTExfTlNfVVJJIFhNTENvbnN0YW50cy5OVUxMX05TX1VSSSgiIil9Ci0gICAgICogICAgICAgICA8L2NvZGU+Ci0gICAgICogICAgICAgPC90ZD4KLSAgICAgKiAgICAgPC90cj4KLSAgICAgKiAgICAgPHRyPgotICAgICAqICAgICAgIDx0ZD48Y29kZT5YTUxDb25zdGFudHMuWE1MX05TX1BSRUZJWDwvY29kZT4gKCJ4bWwiKTwvdGQ+Ci0gICAgICogICAgICAgPHRkPjxjb2RlPlhNTENvbnN0YW50cy5YTUxfTlNfVVJJPC9jb2RlPgotICAgICAqICAgICAgICAgICAoImh0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZSIpPC90ZD4KLSAgICAgKiAgICAgPC90cj4KLSAgICAgKiAgICAgPHRyPgotICAgICAqICAgICAgIDx0ZD48Y29kZT5YTUxDb25zdGFudHMuWE1MTlNfQVRUUklCVVRFPC9jb2RlPiAoInhtbG5zIik8L3RkPgotICAgICAqICAgICAgIDx0ZD48Y29kZT5YTUxDb25zdGFudHMuWE1MTlNfQVRUUklCVVRFX05TX1VSSTwvY29kZT4KLSAgICAgKiAgICAgICAgICgiaHR0cDovL3d3dy53My5vcmcvMjAwMC94bWxucy8iKTwvdGQ+Ci0gICAgICogICAgIDwvdHI+Ci0gICAgICogICAgIDx0cj4KLSAgICAgKiAgICAgICA8dGQ+PGNvZGU+bnVsbDwvY29kZT48L3RkPgotICAgICAqICAgICAgIDx0ZD48Y29kZT5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb248L2NvZGU+IGlzIHRocm93bjwvdGQ+Ci0gICAgICogICAgIDwvdHI+Ci0gICAgICogICAgPC90Ym9keT4KLSAgICAgKiA8L3RhYmxlPgotICAgICAqCi0gICAgICogQHBhcmFtIHByZWZpeCBwcmVmaXggdG8gbG9vayB1cAotICAgICAqCi0gICAgICogQHJldHVybiBOYW1lc3BhY2UgVVJJIGJvdW5kIHRvIHByZWZpeCBpbiB0aGUgY3VycmVudCBzY29wZQotICAgICAqCi0gICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gV2hlbiA8Y29kZT5wcmVmaXg8L2NvZGU+IGlzCi0gICAgICogICA8Y29kZT5udWxsPC9jb2RlPgotICAgICAqLwotICAgIFN0cmluZyBnZXROYW1lc3BhY2VVUkkoU3RyaW5nIHByZWZpeCk7Ci0KLSAgICAvKioKLSAgICAgKiA8cD5HZXQgcHJlZml4IGJvdW5kIHRvIE5hbWVzcGFjZSBVUkkgaW4gdGhlIGN1cnJlbnQgc2NvcGUuPC9wPgotICAgICAqCi0gICAgICogPHA+VG8gZ2V0IGFsbCBwcmVmaXhlcyBib3VuZCB0byBhIE5hbWVzcGFjZSBVUkkgaW4gdGhlIGN1cnJlbnQKLSAgICAgKiBzY29wZSwgdXNlIHtAbGluayAjZ2V0UHJlZml4ZXMoU3RyaW5nIG5hbWVzcGFjZVVSSSl9LjwvcD4KLSAgICAgKgotICAgICAqIDxwPldoZW4gcmVxdWVzdGluZyBhIHByZWZpeCBieSBOYW1lc3BhY2UgVVJJLCB0aGUgZm9sbG93aW5nCi0gICAgICogdGFibGUgZGVzY3JpYmVzIHRoZSByZXR1cm5lZCBwcmVmaXggdmFsdWUgZm9yIGFsbCBOYW1lc3BhY2UgVVJJCi0gICAgICogdmFsdWVzOjwvcD4KLSAgICAgKgotICAgICAqIDx0YWJsZSBib3JkZXI9IjIiIHJ1bGVzPSJhbGwiIGNlbGxwYWRkaW5nPSI0Ij4KLSAgICAgKiAgIDx0aGVhZD4KLSAgICAgKiAgICAgPHRyPgotICAgICAqICAgICAgIDx0aCBhbGlnbj0iY2VudGVyIiBjb2xzcGFuPSIyIj4KLSAgICAgKiAgICAgICAgIDxjb2RlPmdldFByZWZpeChuYW1lc3BhY2VVUkkpPC9jb2RlPiByZXR1cm4gdmFsdWUgZm9yCi0gICAgICogICAgICAgICBzcGVjaWZpZWQgTmFtZXNwYWNlIFVSSXMKLSAgICAgKiAgICAgICA8L3RoPgotICAgICAqICAgICA8L3RyPgotICAgICAqICAgICA8dHI+Ci0gICAgICogICAgICAgPHRoPk5hbWVzcGFjZSBVUkkgcGFyYW1ldGVyPC90aD4KLSAgICAgKiAgICAgICA8dGg+cHJlZml4IHZhbHVlIHJldHVybmVkPC90aD4KLSAgICAgKiAgICAgPC90cj4KLSAgICAgKiAgIDwvdGhlYWQ+Ci0gICAgICogICA8dGJvZHk+Ci0gICAgICogICAgIDx0cj4KLSAgICAgKiAgICAgICA8dGQ+Jmx0O2RlZmF1bHQgTmFtZXNwYWNlIFVSSSZndDs8L3RkPgotICAgICAqICAgICAgIDx0ZD48Y29kZT5YTUxDb25zdGFudHMuREVGQVVMVF9OU19QUkVGSVg8L2NvZGU+ICgiIikKLSAgICAgKiAgICAgICA8L3RkPgotICAgICAqICAgICA8L3RyPgotICAgICAqICAgICA8dHI+Ci0gICAgICogICAgICAgPHRkPmJvdW5kIE5hbWVzcGFjZSBVUkk8L3RkPgotICAgICAqICAgICAgIDx0ZD5wcmVmaXggYm91bmQgdG8gTmFtZXNwYWNlIFVSSSBpbiB0aGUgY3VycmVudCBzY29wZSwKLSAgICAgKiAgICAgICAgICAgaWYgbXVsdGlwbGUgcHJlZml4ZXMgYXJlIGJvdW5kIHRvIHRoZSBOYW1lc3BhY2UgVVJJIGluCi0gICAgICogICAgICAgICAgIHRoZSBjdXJyZW50IHNjb3BlLCBhIHNpbmdsZSBhcmJpdHJhcnkgcHJlZml4LCB3aG9zZQotICAgICAqICAgICAgICAgICBjaG9pY2UgaXMgaW1wbGVtZW50YXRpb24gZGVwZW5kZW50LCBpcyByZXR1cm5lZDwvdGQ+Ci0gICAgICogICAgIDwvdHI+Ci0gICAgICogICAgIDx0cj4KLSAgICAgKiAgICAgICA8dGQ+dW5ib3VuZCBOYW1lc3BhY2UgVVJJPC90ZD4KLSAgICAgKiAgICAgICA8dGQ+PGNvZGU+bnVsbDwvY29kZT48L3RkPgotICAgICAqICAgICA8L3RyPgotICAgICAqICAgICA8dHI+Ci0gICAgICogICAgICAgPHRkPjxjb2RlPlhNTENvbnN0YW50cy5YTUxfTlNfVVJJPC9jb2RlPgotICAgICAqICAgICAgICAgICAoImh0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZSIpPC90ZD4KLSAgICAgKiAgICAgICA8dGQ+PGNvZGU+WE1MQ29uc3RhbnRzLlhNTF9OU19QUkVGSVg8L2NvZGU+ICgieG1sIik8L3RkPgotICAgICAqICAgICA8L3RyPgotICAgICAqICAgICA8dHI+Ci0gICAgICogICAgICAgPHRkPjxjb2RlPlhNTENvbnN0YW50cy5YTUxOU19BVFRSSUJVVEVfTlNfVVJJPC9jb2RlPgotICAgICAqICAgICAgICAgICAoImh0dHA6Ly93d3cudzMub3JnLzIwMDAveG1sbnMvIik8L3RkPgotICAgICAqICAgICAgIDx0ZD48Y29kZT5YTUxDb25zdGFudHMuWE1MTlNfQVRUUklCVVRFPC9jb2RlPiAoInhtbG5zIik8L3RkPgotICAgICAqICAgICA8L3RyPgotICAgICAqICAgICA8dHI+Ci0gICAgICogICAgICAgPHRkPjxjb2RlPm51bGw8L2NvZGU+PC90ZD4KLSAgICAgKiAgICAgICA8dGQ+PGNvZGU+SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uPC9jb2RlPiBpcyB0aHJvd248L3RkPgotICAgICAqICAgICA8L3RyPgotICAgICAqICAgPC90Ym9keT4KLSAgICAgKiA8L3RhYmxlPgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWVzcGFjZVVSSSBVUkkgb2YgTmFtZXNwYWNlIHRvIGxvb2t1cAotICAgICAqCi0gICAgICogQHJldHVybiBwcmVmaXggYm91bmQgdG8gTmFtZXNwYWNlIFVSSSBpbiBjdXJyZW50IGNvbnRleHQKLSAgICAgKgotICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIFdoZW4gPGNvZGU+bmFtZXNwYWNlVVJJPC9jb2RlPiBpcwotICAgICAqICAgPGNvZGU+bnVsbDwvY29kZT4KLSAgICAgKi8KLSAgICBTdHJpbmcgZ2V0UHJlZml4KFN0cmluZyBuYW1lc3BhY2VVUkkpOwotCi0gICAgLyoqCi0gICAgICogPHA+R2V0IGFsbCBwcmVmaXhlcyBib3VuZCB0byBhIE5hbWVzcGFjZSBVUkkgaW4gdGhlIGN1cnJlbnQKLSAgICAgKiBzY29wZS48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5BbiBJdGVyYXRvciBvdmVyIFN0cmluZyBlbGVtZW50cyBpcyByZXR1cm5lZCBpbiBhbiBhcmJpdHJhcnksCi0gICAgICogPHN0cm9uZz5pbXBsZW1lbnRhdGlvbiBkZXBlbmRlbnQ8L3N0cm9uZz4sIG9yZGVyLjwvcD4KLSAgICAgKgotICAgICAqIDxwPjxzdHJvbmc+VGhlIDxjb2RlPkl0ZXJhdG9yPC9jb2RlPiBpcwotICAgICAqIDxlbT5ub3Q8L2VtPiBtb2RpZmlhYmxlLiAgZS5nLiB0aGUKLSAgICAgKiA8Y29kZT5yZW1vdmUoKTwvY29kZT4gbWV0aG9kIHdpbGwgdGhyb3cKLSAgICAgKiA8Y29kZT5VbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbjwvY29kZT4uPC9zdHJvbmc+PC9wPgotICAgICAqCi0gICAgICogPHA+V2hlbiByZXF1ZXN0aW5nIHByZWZpeGVzIGJ5IE5hbWVzcGFjZSBVUkksIHRoZSBmb2xsb3dpbmcKLSAgICAgKiB0YWJsZSBkZXNjcmliZXMgdGhlIHJldHVybmVkIHByZWZpeGVzIHZhbHVlIGZvciBhbGwgTmFtZXNwYWNlCi0gICAgICogVVJJIHZhbHVlczo8L3A+Ci0gICAgICoKLSAgICAgKiA8dGFibGUgYm9yZGVyPSIyIiBydWxlcz0iYWxsIiBjZWxscGFkZGluZz0iNCI+Ci0gICAgICogICA8dGhlYWQ+Ci0gICAgICogICAgIDx0cj4KLSAgICAgKiAgICAgICA8dGggYWxpZ249ImNlbnRlciIgY29sc3Bhbj0iMiI+PGNvZGU+Ci0gICAgICogICAgICAgICBnZXRQcmVmaXhlcyhuYW1lc3BhY2VVUkkpPC9jb2RlPiByZXR1cm4gdmFsdWUgZm9yCi0gICAgICogICAgICAgICBzcGVjaWZpZWQgTmFtZXNwYWNlIFVSSXM8L3RoPgotICAgICAqICAgICA8L3RyPgotICAgICAqICAgICA8dHI+Ci0gICAgICogICAgICAgPHRoPk5hbWVzcGFjZSBVUkkgcGFyYW1ldGVyPC90aD4KLSAgICAgKiAgICAgICA8dGg+cHJlZml4ZXMgdmFsdWUgcmV0dXJuZWQ8L3RoPgotICAgICAqICAgICA8L3RyPgotICAgICAqICAgPC90aGVhZD4KLSAgICAgKiAgIDx0Ym9keT4KLSAgICAgKiAgICAgPHRyPgotICAgICAqICAgICAgIDx0ZD5ib3VuZCBOYW1lc3BhY2UgVVJJLAotICAgICAqICAgICAgICAgaW5jbHVkaW5nIHRoZSAmbHQ7ZGVmYXVsdCBOYW1lc3BhY2UgVVJJJmd0OzwvdGQ+Ci0gICAgICogICAgICAgPHRkPgotICAgICAqICAgICAgICAgPGNvZGU+SXRlcmF0b3I8L2NvZGU+IG92ZXIgcHJlZml4ZXMgYm91bmQgdG8gTmFtZXNwYWNlIFVSSSBpbgotICAgICAqICAgICAgICAgdGhlIGN1cnJlbnQgc2NvcGUgaW4gYW4gYXJiaXRyYXJ5LAotICAgICAqICAgICAgICAgPHN0cm9uZz5pbXBsZW1lbnRhdGlvbiBkZXBlbmRlbnQ8L3N0cm9uZz4sCi0gICAgICogICAgICAgICBvcmRlcgotICAgICAqICAgICAgIDwvdGQ+Ci0gICAgICogICAgIDwvdHI+Ci0gICAgICogICAgIDx0cj4KLSAgICAgKiAgICAgICA8dGQ+dW5ib3VuZCBOYW1lc3BhY2UgVVJJPC90ZD4KLSAgICAgKiAgICAgICA8dGQ+ZW1wdHkgPGNvZGU+SXRlcmF0b3I8L2NvZGU+PC90ZD4KLSAgICAgKiAgICAgPC90cj4KLSAgICAgKiAgICAgPHRyPgotICAgICAqICAgICAgIDx0ZD48Y29kZT5YTUxDb25zdGFudHMuWE1MX05TX1VSSTwvY29kZT4KLSAgICAgKiAgICAgICAgICAgKCJodHRwOi8vd3d3LnczLm9yZy9YTUwvMTk5OC9uYW1lc3BhY2UiKTwvdGQ+Ci0gICAgICogICAgICAgPHRkPjxjb2RlPkl0ZXJhdG9yPC9jb2RlPiB3aXRoIG9uZSBlbGVtZW50IHNldCB0bwotICAgICAqICAgICAgICAgPGNvZGU+WE1MQ29uc3RhbnRzLlhNTF9OU19QUkVGSVg8L2NvZGU+ICgieG1sIik8L3RkPgotICAgICAqICAgICA8L3RyPgotICAgICAqICAgICA8dHI+Ci0gICAgICogICAgICAgPHRkPjxjb2RlPlhNTENvbnN0YW50cy5YTUxOU19BVFRSSUJVVEVfTlNfVVJJPC9jb2RlPgotICAgICAqICAgICAgICAgICAoImh0dHA6Ly93d3cudzMub3JnLzIwMDAveG1sbnMvIik8L3RkPgotICAgICAqICAgICAgIDx0ZD48Y29kZT5JdGVyYXRvcjwvY29kZT4gd2l0aCBvbmUgZWxlbWVudCBzZXQgdG8KLSAgICAgKiAgICAgICAgIDxjb2RlPlhNTENvbnN0YW50cy5YTUxOU19BVFRSSUJVVEU8L2NvZGU+ICgieG1sbnMiKTwvdGQ+Ci0gICAgICogICAgIDwvdHI+Ci0gICAgICogICAgIDx0cj4KLSAgICAgKiAgICAgICA8dGQ+PGNvZGU+bnVsbDwvY29kZT48L3RkPgotICAgICAqICAgICAgIDx0ZD48Y29kZT5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb248L2NvZGU+IGlzIHRocm93bjwvdGQ+Ci0gICAgICogICAgIDwvdHI+Ci0gICAgICogICA8L3Rib2R5PgotICAgICAqIDwvdGFibGU+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZXNwYWNlVVJJIFVSSSBvZiBOYW1lc3BhY2UgdG8gbG9va3VwCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIDxjb2RlPkl0ZXJhdG9yPC9jb2RlPiBmb3IgYWxsIHByZWZpeGVzIGJvdW5kIHRvIHRoZQotICAgICAqICAgTmFtZXNwYWNlIFVSSSBpbiB0aGUgY3VycmVudCBzY29wZQotICAgICAqCi0gICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gV2hlbiA8Y29kZT5uYW1lc3BhY2VVUkk8L2NvZGU+IGlzCi0gICAgICogICA8Y29kZT5udWxsPC9jb2RlPgotICAgICAqLwotICAgIEl0ZXJhdG9yIGdldFByZWZpeGVzKFN0cmluZyBuYW1lc3BhY2VVUkkpOwotfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmF4L3htbC9uYW1lc3BhY2UvUU5hbWUuamF2YSBiL3NyYy9qYXZheC94bWwvbmFtZXNwYWNlL1FOYW1lLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDk4MWE4YjIuLjAwMDAwMDAKLS0tIGEvc3JjL2phdmF4L3htbC9uYW1lc3BhY2UvUU5hbWUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDUxNiArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDA2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi1wYWNrYWdlIGphdmF4LnhtbC5uYW1lc3BhY2U7Ci0KLWltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKLWltcG9ydCBqYXZhLnNlY3VyaXR5LkFjY2Vzc0NvbnRyb2xsZXI7Ci1pbXBvcnQgamF2YS5zZWN1cml0eS5Qcml2aWxlZ2VkQWN0aW9uOwotCi1pbXBvcnQgamF2YXgueG1sLlhNTENvbnN0YW50czsKLQotLyoqCi0gKiA8cD48Y29kZT5RTmFtZTwvY29kZT4gcmVwcmVzZW50cyBhIDxzdHJvbmc+cXVhbGlmaWVkIG5hbWU8L3N0cm9uZz4KLSAqIGFzIGRlZmluZWQgaW4gdGhlIFhNTCBzcGVjaWZpY2F0aW9uczogPGEKLSAqIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3htbHNjaGVtYS0yLyNRTmFtZSI+WE1MIFNjaGVtYSBQYXJ0MjoKLSAqIERhdGF0eXBlcyBzcGVjaWZpY2F0aW9uPC9hPiwgPGEKLSAqIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy14bWwtbmFtZXMvI25zLXF1YWxuYW1lcyI+TmFtZXNwYWNlcwotICogaW4gWE1MPC9hPiwgPGEKLSAqIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1hNTC94bWwtbmFtZXMtMTk5OTAxMTQtZXJyYXRhIj5OYW1lc3BhY2VzCi0gKiBpbiBYTUwgRXJyYXRhPC9hPi48L3A+Ci0gKgotICogPHA+VGhlIHZhbHVlIG9mIGEgPGNvZGU+UU5hbWU8L2NvZGU+IGNvbnRhaW5zIGEgPHN0cm9uZz5OYW1lc3BhY2UKLSAqIFVSSTwvc3Ryb25nPiwgPHN0cm9uZz5sb2NhbCBwYXJ0PC9zdHJvbmc+IGFuZAotICogPHN0cm9uZz5wcmVmaXg8L3N0cm9uZz4uPC9wPgotICoKLSAqIDxwPlRoZSBwcmVmaXggaXMgaW5jbHVkZWQgaW4gPGNvZGU+UU5hbWU8L2NvZGU+IHRvIHJldGFpbiBsZXhpY2FsCi0gKiBpbmZvcm1hdGlvbiA8c3Ryb25nPjxlbT53aGVuIHByZXNlbnQ8L2VtPjwvc3Ryb25nPiBpbiBhbiB7QGxpbmsKLSAqIGphdmF4LnhtbC50cmFuc2Zvcm0uU291cmNlIFhNTCBpbnB1dCBzb3VyY2V9LiBUaGUgcHJlZml4IGlzCi0gKiA8c3Ryb25nPjxlbT5OT1Q8L2VtPjwvc3Ryb25nPiB1c2VkIGluIHtAbGluayAjZXF1YWxzKE9iamVjdCkKLSAqIFFOYW1lLmVxdWFscyhPYmplY3QpfSBvciB0byBjb21wdXRlIHRoZSB7QGxpbmsgI2hhc2hDb2RlKCkKLSAqIFFOYW1lLmhhc2hDb2RlKCl9LiAgRXF1YWxpdHkgYW5kIHRoZSBoYXNoIGNvZGUgYXJlIGRlZmluZWQgdXNpbmcKLSAqIDxzdHJvbmc+PGVtPm9ubHk8L2VtPjwvc3Ryb25nPiB0aGUgTmFtZXNwYWNlIFVSSSBhbmQgbG9jYWwgcGFydC48L3A+Ci0gKgotICogPHA+SWYgbm90IHNwZWNpZmllZCwgdGhlIE5hbWVzcGFjZSBVUkkgaXMgc2V0IHRvIHtAbGluawotICogamF2YXgueG1sLlhNTENvbnN0YW50cyNOVUxMX05TX1VSSSBYTUxDb25zdGFudHMuTlVMTF9OU19VUkl9LgotICogSWYgbm90IHNwZWNpZmllZCwgdGhlIHByZWZpeCBpcyBzZXQgdG8ge0BsaW5rCi0gKiBqYXZheC54bWwuWE1MQ29uc3RhbnRzI0RFRkFVTFRfTlNfUFJFRklYCi0gKiBYTUxDb25zdGFudHMuREVGQVVMVF9OU19QUkVGSVh9LjwvcD4KLSAqCi0gKiA8cD48Y29kZT5RTmFtZTwvY29kZT4gaXMgaW1tdXRhYmxlLjwvcD4KLSAqCi0gKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzpKZWZmLlN1dHRvckBTdW4uY29tIj5KZWZmIFN1dHRvcjwvYT4KLSAqIEB2ZXJzaW9uICRSZXZpc2lvbjogMS44ICQsICREYXRlOiAyMDEwLzAzLzE4IDAzOjA2OjE3ICQKLSAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveG1sc2NoZW1hLTIvI1FOYW1lIj4KLSAqICAgWE1MIFNjaGVtYSBQYXJ0MjogRGF0YXR5cGVzIHNwZWNpZmljYXRpb248L2E+Ci0gKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy14bWwtbmFtZXMvI25zLXF1YWxuYW1lcyI+Ci0gKiAgIE5hbWVzcGFjZXMgaW4gWE1MPC9hPgotICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9YTUwveG1sLW5hbWVzLTE5OTkwMTE0LWVycmF0YSI+Ci0gKiAgIE5hbWVzcGFjZXMgaW4gWE1MIEVycmF0YTwvYT4KLSAqIEBzaW5jZSAxLjUKLSAqLwotCi1wdWJsaWMgY2xhc3MgUU5hbWUgaW1wbGVtZW50cyBTZXJpYWxpemFibGUgewotCi0gICAgLyoqCi0gICAgICogPHA+U3RyZWFtIFVuaXF1ZSBJZGVudGlmaWVyLjwvcD4KLSAgICAgKgotICAgICAqIDxwPkR1ZSB0byBhIGhpc3RvcmljYWwgZGVmZWN0LCBRTmFtZSB3YXMgcmVsZWFzZWQgd2l0aCBtdWx0aXBsZQotICAgICAqIHNlcmlhbFZlcnNpb25VSUQgdmFsdWVzIGV2ZW4gdGhvdWdoIGl0cyBzZXJpYWxpemF0aW9uIHdhcyB0aGUKLSAgICAgKiBzYW1lLjwvcD4KLSAgICAgKgotICAgICAqIDxwPlRvIHdvcmthcm91bmQgdGhpcyBpc3N1ZSwgc2VyaWFsVmVyc2lvblVJRCBpcyBzZXQgd2l0aCBlaXRoZXIKLSAgICAgKiBhIGRlZmF1bHQgdmFsdWUgb3IgYSBjb21wYXRpYmlsaXR5IHZhbHVlLiAgVG8gdXNlIHRoZQotICAgICAqIGNvbXBhdGlibGl0eSB2YWx1ZSwgc2V0IHRoZSBzeXN0ZW0gcHJvcGVydHk6PC9wPgotICAgICAqCi0gICAgICogPGNvZGU+Y29tLnN1bi54bWwubmFtZXNwYWNlLlFOYW1lLnVzZUNvbXBhdGlibGVTZXJpYWxWZXJzaW9uVUlEPTEuMDwvY29kZT4KLSAgICAgKgotICAgICAqIDxwPlRoaXMgd29ya2Fyb3VuZCB3YXMgaW5zcGlyZWQgYnkgY2xhc3NlcyBpbiB0aGUgamF2YXgubWFuYWdlbWVudAotICAgICAqIHBhY2thZ2UsIGUuZy4gT2JqZWN0TmFtZSwgZXRjLgotICAgICAqIFNlZSBDUjYyNjcyMjQgZm9yIG9yaWdpbmFsIGRlZmVjdCByZXBvcnQuPC9wPgotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRDsKLSAgICAvKioKLSAgICAgKiA8cD5EZWZhdWx0IDxjb2RlPnNlcmlhbFZlcnNpb25VSUQ8L2NvZGU+IHZhbHVlLjwvcD4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIGRlZmF1bHRTZXJpYWxWZXJzaW9uVUlEID0gLTkxMjA0NDg3NTQ4OTY2MDk5NDBMOwotICAgIC8qKgotICAgICAqIDxwPkNvbXBhdGliaWxpdHkgPGNvZGU+c2VyaWFsVmVyc2lvblVJRDwvY29kZT4gdmFsdWUuPC9wPgotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgY29tcGF0aWJsZVNlcmlhbFZlcnNpb25VSUQgPSA0NDE4NjIyOTgxMDI2NTQ1MTUxTDsKLSAgICAvKioKLSAgICAgKiA8cD5GbGFnIHRvIHVzZSBkZWZhdWx0IG9yIGNhbXBhdGlibGUgc2VyaWFsVmVyc2lvblVJRC48L3A+Ci0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiB1c2VEZWZhdWx0U2VyaWFsVmVyc2lvblVJRCA9IHRydWU7Ci0gICAgc3RhdGljIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIC8vIHVzZSBhIHByaXZpbGVnZWQgYmxvY2sgYXMgcmVhZGluZyBhIHN5c3RlbSBwcm9wZXJ0eQotICAgICAgICAgICAgU3RyaW5nIHZhbHVlVXNlQ29tcGF0aWJsZVNlcmlhbFZlcnNpb25VSUQgPSAoU3RyaW5nKSBBY2Nlc3NDb250cm9sbGVyLmRvUHJpdmlsZWdlZCgKLSAgICAgICAgICAgICAgICAgICAgbmV3IFByaXZpbGVnZWRBY3Rpb24oKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBwdWJsaWMgT2JqZWN0IHJ1bigpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gU3lzdGVtLmdldFByb3BlcnR5KCJjb20uc3VuLnhtbC5uYW1lc3BhY2UuUU5hbWUudXNlQ29tcGF0aWJsZVNlcmlhbFZlcnNpb25VSUQiKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgKTsKLSAgICAgICAgICAgIHVzZURlZmF1bHRTZXJpYWxWZXJzaW9uVUlEID0gKHZhbHVlVXNlQ29tcGF0aWJsZVNlcmlhbFZlcnNpb25VSUQgIT0gbnVsbCAmJiB2YWx1ZVVzZUNvbXBhdGlibGVTZXJpYWxWZXJzaW9uVUlELmVxdWFscygiMS4wIikpID8gZmFsc2UgOiB0cnVlOwotICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXhjZXB0aW9uKSB7Ci0gICAgICAgICAgICAvLyB1c2UgZGVmYXVsdCBpZiBhbnkgRXhjZXB0aW9ucwotICAgICAgICAgICAgdXNlRGVmYXVsdFNlcmlhbFZlcnNpb25VSUQgPSB0cnVlOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gc2V0IHNlcmlhbFZlcnNpb25VSUQgdG8gZGVzaXJlZCB2YWx1ZQotICAgICAgICBpZiAodXNlRGVmYXVsdFNlcmlhbFZlcnNpb25VSUQpIHsKLSAgICAgICAgICAgIHNlcmlhbFZlcnNpb25VSUQgPSBkZWZhdWx0U2VyaWFsVmVyc2lvblVJRDsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIHNlcmlhbFZlcnNpb25VSUQgPSBjb21wYXRpYmxlU2VyaWFsVmVyc2lvblVJRDsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPk5hbWVzcGFjZSBVUkkgb2YgdGhpcyA8Y29kZT5RTmFtZTwvY29kZT4uPC9wPgotICAgICAqLwotICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIG5hbWVzcGFjZVVSSTsKLQotICAgIC8qKgotICAgICAqIDxwPmxvY2FsIHBhcnQgb2YgdGhpcyA8Y29kZT5RTmFtZTwvY29kZT4uPC9wPgotICAgICAqLwotICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIGxvY2FsUGFydDsKLQotICAgIC8qKgotICAgICAqIDxwPnByZWZpeCBvZiB0aGlzIDxjb2RlPlFOYW1lPC9jb2RlPi48L3A+Ci0gICAgICovCi0gICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgcHJlZml4OwotCi0gICAgLyoqCi0gICAgICogPHA+PGNvZGU+UU5hbWU8L2NvZGU+IGNvbnN0cnVjdG9yIHNwZWNpZnlpbmcgdGhlIE5hbWVzcGFjZSBVUkkKLSAgICAgKiBhbmQgbG9jYWwgcGFydC48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5JZiB0aGUgTmFtZXNwYWNlIFVSSSBpcyA8Y29kZT5udWxsPC9jb2RlPiwgaXQgaXMgc2V0IHRvCi0gICAgICoge0BsaW5rIGphdmF4LnhtbC5YTUxDb25zdGFudHMjTlVMTF9OU19VUkkKLSAgICAgKiBYTUxDb25zdGFudHMuTlVMTF9OU19VUkl9LiAgVGhpcyB2YWx1ZSByZXByZXNlbnRzIG5vCi0gICAgICogZXhwbGljaXRseSBkZWZpbmVkIE5hbWVzcGFjZSBhcyBkZWZpbmVkIGJ5IHRoZSA8YQotICAgICAqIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy14bWwtbmFtZXMvI25zLXF1YWxuYW1lcyI+TmFtZXNwYWNlcwotICAgICAqIGluIFhNTDwvYT4gc3BlY2lmaWNhdGlvbi4gIFRoaXMgYWN0aW9uIHByZXNlcnZlcyBjb21wYXRpYmxlCi0gICAgICogYmVoYXZpb3Igd2l0aCBRTmFtZSAxLjAuICBFeHBsaWNpdGx5IHByb3ZpZGluZyB0aGUge0BsaW5rCi0gICAgICogamF2YXgueG1sLlhNTENvbnN0YW50cyNOVUxMX05TX1VSSQotICAgICAqIFhNTENvbnN0YW50cy5OVUxMX05TX1VSSX0gdmFsdWUgaXMgdGhlIHByZWZlcnJlZCBjb2RpbmcKLSAgICAgKiBzdHlsZS48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5JZiB0aGUgbG9jYWwgcGFydCBpcyA8Y29kZT5udWxsPC9jb2RlPiBhbgotICAgICAqIDxjb2RlPklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbjwvY29kZT4gaXMgdGhyb3duLgotICAgICAqIEEgbG9jYWwgcGFydCBvZiAiIiBpcyBhbGxvd2VkIHRvIHByZXNlcnZlCi0gICAgICogY29tcGF0aWJsZSBiZWhhdmlvciB3aXRoIFFOYW1lIDEuMC4gPC9wPgotICAgICAqCi0gICAgICogPHA+V2hlbiB1c2luZyB0aGlzIGNvbnN0cnVjdG9yLCB0aGUgcHJlZml4IGlzIHNldCB0byB7QGxpbmsKLSAgICAgKiBqYXZheC54bWwuWE1MQ29uc3RhbnRzI0RFRkFVTFRfTlNfUFJFRklYCi0gICAgICogWE1MQ29uc3RhbnRzLkRFRkFVTFRfTlNfUFJFRklYfS48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5UaGUgTmFtZXNwYWNlIFVSSSBpcyBub3QgdmFsaWRhdGVkIGFzIGEKLSAgICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyMzk2LnR4dCI+VVJJIHJlZmVyZW5jZTwvYT4uCi0gICAgICogVGhlIGxvY2FsIHBhcnQgaXMgbm90IHZhbGlkYXRlZCBhcyBhCi0gICAgICogPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLXhtbC1uYW1lcy8jTlQtTkNOYW1lIj5OQ05hbWU8L2E+Ci0gICAgICogYXMgc3BlY2lmaWVkIGluIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy14bWwtbmFtZXMvIj5OYW1lc3BhY2VzCi0gICAgICogaW4gWE1MPC9hPi48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZXNwYWNlVVJJIE5hbWVzcGFjZSBVUkkgb2YgdGhlIDxjb2RlPlFOYW1lPC9jb2RlPgotICAgICAqIEBwYXJhbSBsb2NhbFBhcnQgICAgbG9jYWwgcGFydCBvZiB0aGUgPGNvZGU+UU5hbWU8L2NvZGU+Ci0gICAgICoKLSAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBXaGVuIDxjb2RlPmxvY2FsUGFydDwvY29kZT4gaXMKLSAgICAgKiAgIDxjb2RlPm51bGw8L2NvZGU+Ci0gICAgICoKLSAgICAgKiBAc2VlICNRTmFtZShTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgbG9jYWxQYXJ0LCBTdHJpbmcKLSAgICAgKiBwcmVmaXgpIFFOYW1lKFN0cmluZyBuYW1lc3BhY2VVUkksIFN0cmluZyBsb2NhbFBhcnQsIFN0cmluZwotICAgICAqIHByZWZpeCkKLSAgICAgKi8KLSAgICBwdWJsaWMgUU5hbWUoZmluYWwgU3RyaW5nIG5hbWVzcGFjZVVSSSwgZmluYWwgU3RyaW5nIGxvY2FsUGFydCkgewotICAgICAgICB0aGlzKG5hbWVzcGFjZVVSSSwgbG9jYWxQYXJ0LCBYTUxDb25zdGFudHMuREVGQVVMVF9OU19QUkVGSVgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPjxjb2RlPlFOYW1lPC9jb2RlPiBjb25zdHJ1Y3RvciBzcGVjaWZ5aW5nIHRoZSBOYW1lc3BhY2UgVVJJLAotICAgICAqIGxvY2FsIHBhcnQgYW5kIHByZWZpeC48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5JZiB0aGUgTmFtZXNwYWNlIFVSSSBpcyA8Y29kZT5udWxsPC9jb2RlPiwgaXQgaXMgc2V0IHRvCi0gICAgICoge0BsaW5rIGphdmF4LnhtbC5YTUxDb25zdGFudHMjTlVMTF9OU19VUkkKLSAgICAgKiBYTUxDb25zdGFudHMuTlVMTF9OU19VUkl9LiAgVGhpcyB2YWx1ZSByZXByZXNlbnRzIG5vCi0gICAgICogZXhwbGljaXRseSBkZWZpbmVkIE5hbWVzcGFjZSBhcyBkZWZpbmVkIGJ5IHRoZSA8YQotICAgICAqIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy14bWwtbmFtZXMvI25zLXF1YWxuYW1lcyI+TmFtZXNwYWNlcwotICAgICAqIGluIFhNTDwvYT4gc3BlY2lmaWNhdGlvbi4gIFRoaXMgYWN0aW9uIHByZXNlcnZlcyBjb21wYXRpYmxlCi0gICAgICogYmVoYXZpb3Igd2l0aCBRTmFtZSAxLjAuICBFeHBsaWNpdGx5IHByb3ZpZGluZyB0aGUge0BsaW5rCi0gICAgICogamF2YXgueG1sLlhNTENvbnN0YW50cyNOVUxMX05TX1VSSQotICAgICAqIFhNTENvbnN0YW50cy5OVUxMX05TX1VSSX0gdmFsdWUgaXMgdGhlIHByZWZlcnJlZCBjb2RpbmcKLSAgICAgKiBzdHlsZS48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5JZiB0aGUgbG9jYWwgcGFydCBpcyA8Y29kZT5udWxsPC9jb2RlPiBhbgotICAgICAqIDxjb2RlPklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbjwvY29kZT4gaXMgdGhyb3duLgotICAgICAqIEEgbG9jYWwgcGFydCBvZiAiIiBpcyBhbGxvd2VkIHRvIHByZXNlcnZlCi0gICAgICogY29tcGF0aWJsZSBiZWhhdmlvciB3aXRoIFFOYW1lIDEuMC4gPC9wPgotICAgICAqCi0gICAgICogPHA+SWYgdGhlIHByZWZpeCBpcyA8Y29kZT5udWxsPC9jb2RlPiwgYW4KLSAgICAgKiA8Y29kZT5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb248L2NvZGU+IGlzIHRocm93bi4gIFVzZSB7QGxpbmsKLSAgICAgKiBqYXZheC54bWwuWE1MQ29uc3RhbnRzI0RFRkFVTFRfTlNfUFJFRklYCi0gICAgICogWE1MQ29uc3RhbnRzLkRFRkFVTFRfTlNfUFJFRklYfSB0byBleHBsaWNpdGx5IGluZGljYXRlIHRoYXQgbm8KLSAgICAgKiBwcmVmaXggaXMgcHJlc2VudCBvciB0aGUgcHJlZml4IGlzIG5vdCByZWxldmFudC48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5UaGUgTmFtZXNwYWNlIFVSSSBpcyBub3QgdmFsaWRhdGVkIGFzIGEKLSAgICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyMzk2LnR4dCI+VVJJIHJlZmVyZW5jZTwvYT4uCi0gICAgICogVGhlIGxvY2FsIHBhcnQgYW5kIHByZWZpeCBhcmUgbm90IHZhbGlkYXRlZCBhcyBhCi0gICAgICogPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLXhtbC1uYW1lcy8jTlQtTkNOYW1lIj5OQ05hbWU8L2E+Ci0gICAgICogYXMgc3BlY2lmaWVkIGluIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy14bWwtbmFtZXMvIj5OYW1lc3BhY2VzCi0gICAgICogaW4gWE1MPC9hPi48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZXNwYWNlVVJJIE5hbWVzcGFjZSBVUkkgb2YgdGhlIDxjb2RlPlFOYW1lPC9jb2RlPgotICAgICAqIEBwYXJhbSBsb2NhbFBhcnQgICAgbG9jYWwgcGFydCBvZiB0aGUgPGNvZGU+UU5hbWU8L2NvZGU+Ci0gICAgICogQHBhcmFtIHByZWZpeCAgICAgICBwcmVmaXggb2YgdGhlIDxjb2RlPlFOYW1lPC9jb2RlPgotICAgICAqCi0gICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gV2hlbiA8Y29kZT5sb2NhbFBhcnQ8L2NvZGU+Ci0gICAgICogICBvciA8Y29kZT5wcmVmaXg8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+Ci0gICAgICovCi0gICAgcHVibGljIFFOYW1lKFN0cmluZyBuYW1lc3BhY2VVUkksIFN0cmluZyBsb2NhbFBhcnQsIFN0cmluZyBwcmVmaXgpIHsKLQotICAgICAgICAvLyBtYXAgbnVsbCBOYW1lc3BhY2UgVVJJIHRvIGRlZmF1bHQKLSAgICAgICAgLy8gdG8gcHJlc2VydmUgY29tcGF0aWJpbGl0eSB3aXRoIFFOYW1lIDEuMAotICAgICAgICBpZiAobmFtZXNwYWNlVVJJID09IG51bGwpIHsKLSAgICAgICAgICAgIHRoaXMubmFtZXNwYWNlVVJJID0gWE1MQ29uc3RhbnRzLk5VTExfTlNfVVJJOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgdGhpcy5uYW1lc3BhY2VVUkkgPSBuYW1lc3BhY2VVUkk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBsb2NhbCBwYXJ0IGlzIHJlcXVpcmVkLgotICAgICAgICAvLyAiIiBpcyBhbGxvd2VkIHRvIHByZXNlcnZlIGNvbXBhdGliaWxpdHkgd2l0aCBRTmFtZSAxLjAKLSAgICAgICAgaWYgKGxvY2FsUGFydCA9PSBudWxsKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICAibG9jYWwgcGFydCBjYW5ub3QgYmUgXCJudWxsXCIgd2hlbiBjcmVhdGluZyBhIFFOYW1lIik7Ci0gICAgICAgIH0KLSAgICAgICAgdGhpcy5sb2NhbFBhcnQgPSBsb2NhbFBhcnQ7Ci0KLSAgICAgICAgLy8gcHJlZml4IGlzIHJlcXVpcmVkCi0gICAgICAgIGlmIChwcmVmaXggPT0gbnVsbCkgewotICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgInByZWZpeCBjYW5ub3QgYmUgXCJudWxsXCIgd2hlbiBjcmVhdGluZyBhIFFOYW1lIik7Ci0gICAgICAgIH0KLSAgICAgICAgdGhpcy5wcmVmaXggPSBwcmVmaXg7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+PGNvZGU+UU5hbWU8L2NvZGU+IGNvbnN0cnVjdG9yIHNwZWNpZnlpbmcgdGhlIGxvY2FsIHBhcnQuPC9wPgotICAgICAqCi0gICAgICogPHA+SWYgdGhlIGxvY2FsIHBhcnQgaXMgPGNvZGU+bnVsbDwvY29kZT4gYW4KLSAgICAgKiA8Y29kZT5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb248L2NvZGU+IGlzIHRocm93bi4KLSAgICAgKiBBIGxvY2FsIHBhcnQgb2YgIiIgaXMgYWxsb3dlZCB0byBwcmVzZXJ2ZQotICAgICAqIGNvbXBhdGlibGUgYmVoYXZpb3Igd2l0aCBRTmFtZSAxLjAuIDwvcD4KLSAgICAgKgotICAgICAqIDxwPldoZW4gdXNpbmcgdGhpcyBjb25zdHJ1Y3RvciwgdGhlIE5hbWVzcGFjZSBVUkkgaXMgc2V0IHRvCi0gICAgICoge0BsaW5rIGphdmF4LnhtbC5YTUxDb25zdGFudHMjTlVMTF9OU19VUkkKLSAgICAgKiBYTUxDb25zdGFudHMuTlVMTF9OU19VUkl9IGFuZCB0aGUgcHJlZml4IGlzIHNldCB0byB7QGxpbmsKLSAgICAgKiBqYXZheC54bWwuWE1MQ29uc3RhbnRzI0RFRkFVTFRfTlNfUFJFRklYCi0gICAgICogWE1MQ29uc3RhbnRzLkRFRkFVTFRfTlNfUFJFRklYfS48L3A+Ci0gICAgICoKLSAgICAgKiA8cD48ZW0+SW4gYW4gWE1MIGNvbnRleHQsIGFsbCBFbGVtZW50IGFuZCBBdHRyaWJ1dGUgbmFtZXMgZXhpc3QKLSAgICAgKiBpbiB0aGUgY29udGV4dCBvZiBhIE5hbWVzcGFjZS4gIE1ha2luZyB0aGlzIGV4cGxpY2l0IGR1cmluZyB0aGUKLSAgICAgKiBjb25zdHJ1Y3Rpb24gb2YgYSA8Y29kZT5RTmFtZTwvY29kZT4gaGVscHMgcHJldmVudCBoYXJkIHRvCi0gICAgICogZGlhZ25vc2lzIFhNTCB2YWxpZGl0eSBlcnJvcnMuICBUaGUgY29uc3RydWN0b3JzIHtAbGluawotICAgICAqICNRTmFtZShTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgbG9jYWxQYXJ0KSBRTmFtZShTdHJpbmcKLSAgICAgKiBuYW1lc3BhY2VVUkksIFN0cmluZyBsb2NhbFBhcnQpfSBhbmQKLSAgICAgKiB7QGxpbmsgI1FOYW1lKFN0cmluZyBuYW1lc3BhY2VVUkksIFN0cmluZyBsb2NhbFBhcnQsIFN0cmluZyBwcmVmaXgpfQotICAgICAqIGFyZSBwcmVmZXJyZWQuPC9lbT48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5UaGUgbG9jYWwgcGFydCBpcyBub3QgdmFsaWRhdGVkIGFzIGEKLSAgICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMteG1sLW5hbWVzLyNOVC1OQ05hbWUiPk5DTmFtZTwvYT4KLSAgICAgKiBhcyBzcGVjaWZpZWQgaW4gPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLXhtbC1uYW1lcy8iPk5hbWVzcGFjZXMKLSAgICAgKiBpbiBYTUw8L2E+LjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBsb2NhbFBhcnQgbG9jYWwgcGFydCBvZiB0aGUgPGNvZGU+UU5hbWU8L2NvZGU+Ci0gICAgICoKLSAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBXaGVuIDxjb2RlPmxvY2FsUGFydDwvY29kZT4gaXMKLSAgICAgKiAgIDxjb2RlPm51bGw8L2NvZGU+Ci0gICAgICoKLSAgICAgKiBAc2VlICNRTmFtZShTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgbG9jYWxQYXJ0KSBRTmFtZShTdHJpbmcKLSAgICAgKiBuYW1lc3BhY2VVUkksIFN0cmluZyBsb2NhbFBhcnQpCi0gICAgICogQHNlZSAjUU5hbWUoU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIGxvY2FsUGFydCwgU3RyaW5nCi0gICAgICogcHJlZml4KSBRTmFtZShTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgbG9jYWxQYXJ0LCBTdHJpbmcKLSAgICAgKiBwcmVmaXgpCi0gICAgICovCi0gICAgcHVibGljIFFOYW1lKFN0cmluZyBsb2NhbFBhcnQpIHsKLSAgICAgICAgdGhpcygKLSAgICAgICAgICAgIFhNTENvbnN0YW50cy5OVUxMX05TX1VSSSwKLSAgICAgICAgICAgIGxvY2FsUGFydCwKLSAgICAgICAgICAgIFhNTENvbnN0YW50cy5ERUZBVUxUX05TX1BSRUZJWCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+R2V0IHRoZSBOYW1lc3BhY2UgVVJJIG9mIHRoaXMgPGNvZGU+UU5hbWU8L2NvZGU+LjwvcD4KLSAgICAgKgotICAgICAqIEByZXR1cm4gTmFtZXNwYWNlIFVSSSBvZiB0aGlzIDxjb2RlPlFOYW1lPC9jb2RlPgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZXNwYWNlVVJJKCkgewotICAgICAgICByZXR1cm4gbmFtZXNwYWNlVVJJOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPkdldCB0aGUgbG9jYWwgcGFydCBvZiB0aGlzIDxjb2RlPlFOYW1lPC9jb2RlPi48L3A+Ci0gICAgICoKLSAgICAgKiAgQHJldHVybiBsb2NhbCBwYXJ0IG9mIHRoaXMgPGNvZGU+UU5hbWU8L2NvZGU+Ci0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRMb2NhbFBhcnQoKSB7Ci0gICAgICAgIHJldHVybiBsb2NhbFBhcnQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+R2V0IHRoZSBwcmVmaXggb2YgdGhpcyA8Y29kZT5RTmFtZTwvY29kZT4uPC9wPgotICAgICAqCi0gICAgICogPHA+VGhlIHByZWZpeCBhc3NpZ25lZCB0byBhIDxjb2RlPlFOYW1lPC9jb2RlPiBtaWdodAotICAgICAqIDxzdHJvbmc+PGVtPk5PVDwvZW0+PC9zdHJvbmc+IGJlIHZhbGlkIGluIGEgZGlmZmVyZW50Ci0gICAgICogY29udGV4dC4gRm9yIGV4YW1wbGUsIGEgPGNvZGU+UU5hbWU8L2NvZGU+IG1heSBiZSBhc3NpZ25lZCBhCi0gICAgICogcHJlZml4IGluIHRoZSBjb250ZXh0IG9mIHBhcnNpbmcgYSBkb2N1bWVudCBidXQgdGhhdCBwcmVmaXggbWF5Ci0gICAgICogYmUgaW52YWxpZCBpbiB0aGUgY29udGV4dCBvZiBhIGRpZmZlcmVudCBkb2N1bWVudC48L3A+Ci0gICAgICoKLSAgICAgKiAgQHJldHVybiBwcmVmaXggb2YgdGhpcyA8Y29kZT5RTmFtZTwvY29kZT4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFByZWZpeCgpIHsKLSAgICAgICAgcmV0dXJuIHByZWZpeDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5UZXN0IHRoaXMgPGNvZGU+UU5hbWU8L2NvZGU+IGZvciBlcXVhbGl0eSB3aXRoIGFub3RoZXIKLSAgICAgKiA8Y29kZT5PYmplY3Q8L2NvZGU+LjwvcD4KLSAgICAgKgotICAgICAqIDxwPklmIHRoZSA8Y29kZT5PYmplY3Q8L2NvZGU+IHRvIGJlIHRlc3RlZCBpcyBub3QgYQotICAgICAqIDxjb2RlPlFOYW1lPC9jb2RlPiBvciBpcyA8Y29kZT5udWxsPC9jb2RlPiwgdGhlbiB0aGlzIG1ldGhvZAotICAgICAqIHJldHVybnMgPGNvZGU+ZmFsc2U8L2NvZGU+LjwvcD4KLSAgICAgKgotICAgICAqIDxwPlR3byA8Y29kZT5RTmFtZTwvY29kZT5zIGFyZSBjb25zaWRlcmVkIGVxdWFsIGlmIGFuZCBvbmx5IGlmCi0gICAgICogYm90aCB0aGUgTmFtZXNwYWNlIFVSSSBhbmQgbG9jYWwgcGFydCBhcmUgZXF1YWwuIFRoaXMgbWV0aG9kCi0gICAgICogdXNlcyA8Y29kZT5TdHJpbmcuZXF1YWxzKCk8L2NvZGU+IHRvIGNoZWNrIGVxdWFsaXR5IG9mIHRoZQotICAgICAqIE5hbWVzcGFjZSBVUkkgYW5kIGxvY2FsIHBhcnQuIFRoZSBwcmVmaXggaXMKLSAgICAgKiA8c3Ryb25nPjxlbT5OT1Q8L2VtPjwvc3Ryb25nPiB1c2VkIHRvIGRldGVybWluZSBlcXVhbGl0eS48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5UaGlzIG1ldGhvZCBzYXRpc2ZpZXMgdGhlIGdlbmVyYWwgY29udHJhY3Qgb2Yge0BsaW5rCi0gICAgICogamF2YS5sYW5nLk9iamVjdCNlcXVhbHMoT2JqZWN0KSBPYmplY3QuZXF1YWxzKE9iamVjdCl9PC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIG9iamVjdFRvVGVzdCB0aGUgPGNvZGU+T2JqZWN0PC9jb2RlPiB0byB0ZXN0IGZvcgotICAgICAqIGVxdWFsaXR5IHdpdGggdGhpcyA8Y29kZT5RTmFtZTwvY29kZT4KLSAgICAgKiBAcmV0dXJuIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBnaXZlbiA8Y29kZT5PYmplY3Q8L2NvZGU+IGlzCi0gICAgICogZXF1YWwgdG8gdGhpcyA8Y29kZT5RTmFtZTwvY29kZT4gZWxzZSA8Y29kZT5mYWxzZTwvY29kZT4KLSAgICAgKi8KLSAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iamVjdFRvVGVzdCkgewotICAgICAgICBpZiAob2JqZWN0VG9UZXN0ID09IHRoaXMpIHsKLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKG9iamVjdFRvVGVzdCA9PSBudWxsIHx8ICEob2JqZWN0VG9UZXN0IGluc3RhbmNlb2YgUU5hbWUpKSB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLQotICAgICAgICBRTmFtZSBxTmFtZSA9IChRTmFtZSkgb2JqZWN0VG9UZXN0OwotCi0gICAgICAgIHJldHVybiBsb2NhbFBhcnQuZXF1YWxzKHFOYW1lLmxvY2FsUGFydCkKLSAgICAgICAgICAgICYmIG5hbWVzcGFjZVVSSS5lcXVhbHMocU5hbWUubmFtZXNwYWNlVVJJKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5HZW5lcmF0ZSB0aGUgaGFzaCBjb2RlIGZvciB0aGlzIDxjb2RlPlFOYW1lPC9jb2RlPi48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5UaGUgaGFzaCBjb2RlIGlzIGNhbGN1bGF0ZWQgdXNpbmcgYm90aCB0aGUgTmFtZXNwYWNlIFVSSSBhbmQKLSAgICAgKiB0aGUgbG9jYWwgcGFydCBvZiB0aGUgPGNvZGU+UU5hbWU8L2NvZGU+LiAgVGhlIHByZWZpeCBpcwotICAgICAqIDxzdHJvbmc+PGVtPk5PVDwvZW0+PC9zdHJvbmc+IHVzZWQgdG8gY2FsY3VsYXRlIHRoZSBoYXNoCi0gICAgICogY29kZS48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5UaGlzIG1ldGhvZCBzYXRpc2ZpZXMgdGhlIGdlbmVyYWwgY29udHJhY3Qgb2Yge0BsaW5rCi0gICAgICogamF2YS5sYW5nLk9iamVjdCNoYXNoQ29kZSgpIE9iamVjdC5oYXNoQ29kZSgpfS48L3A+Ci0gICAgICoKLSAgICAgKiBAcmV0dXJuIGhhc2ggY29kZSBmb3IgdGhpcyA8Y29kZT5RTmFtZTwvY29kZT4gPGNvZGU+T2JqZWN0PC9jb2RlPgotICAgICAqLwotICAgIHB1YmxpYyBmaW5hbCBpbnQgaGFzaENvZGUoKSB7Ci0gICAgICAgIHJldHVybiBuYW1lc3BhY2VVUkkuaGFzaENvZGUoKSBeIGxvY2FsUGFydC5oYXNoQ29kZSgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPjxjb2RlPlN0cmluZzwvY29kZT4gcmVwcmVzZW50YXRpb24gb2YgdGhpcwotICAgICAqIDxjb2RlPlFOYW1lPC9jb2RlPi48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5UaGUgY29tbW9ubHkgYWNjZXB0ZWQgd2F5IG9mIHJlcHJlc2VudGluZyBhIDxjb2RlPlFOYW1lPC9jb2RlPgotICAgICAqIGFzIGEgPGNvZGU+U3RyaW5nPC9jb2RlPiB3YXMKLSAgICAgKiA8YSBocmVmPSJodHRwOi8vamNsYXJrLmNvbS94bWwveG1sbnMuaHRtIj5kZWZpbmVkPC9hPgotICAgICAqIGJ5IEphbWVzIENsYXJrLiAgQWx0aG91Z2ggdGhpcyBpcyBub3QgYSA8ZW0+c3RhbmRhcmQ8L2VtPgotICAgICAqIHNwZWNpZmljYXRpb24sIGl0IGlzIGluIGNvbW1vbiB1c2UsIGUuZy4ge0BsaW5rCi0gICAgICogamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lciNzZXRQYXJhbWV0ZXIoU3RyaW5nIG5hbWUsIE9iamVjdCB2YWx1ZSl9LgotICAgICAqIFRoaXMgaW1wbGVtZW50YXRpb24gcmVwcmVzZW50cyBhIDxjb2RlPlFOYW1lPC9jb2RlPiBhczoKLSAgICAgKiAieyIgKyBOYW1lc3BhY2UgVVJJICsgIn0iICsgbG9jYWwgcGFydC4gIElmIHRoZSBOYW1lc3BhY2UgVVJJCi0gICAgICogPGNvZGU+LmVxdWFscyhYTUxDb25zdGFudHMuTlVMTF9OU19VUkkpPC9jb2RlPiwgb25seSB0aGUKLSAgICAgKiBsb2NhbCBwYXJ0IGlzIHJldHVybmVkLiAgQW4gYXBwcm9wcmlhdGUgdXNlIG9mIHRoaXMgbWV0aG9kIGlzCi0gICAgICogZm9yIGRlYnVnZ2luZyBvciBsb2dnaW5nIGZvciBodW1hbiBjb25zdW1wdGlvbi48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5Ob3RlIHRoZSBwcmVmaXggdmFsdWUgaXMgPHN0cm9uZz48ZW0+Tk9UPC9lbT48L3N0cm9uZz4KLSAgICAgKiByZXR1cm5lZCBhcyBwYXJ0IG9mIHRoZSA8Y29kZT5TdHJpbmc8L2NvZGU+IHJlcHJlc2VudGF0aW9uLjwvcD4KLSAgICAgKgotICAgICAqIDxwPlRoaXMgbWV0aG9kIHNhdGlzZmllcyB0aGUgZ2VuZXJhbCBjb250cmFjdCBvZiB7QGxpbmsKLSAgICAgKiBqYXZhLmxhbmcuT2JqZWN0I3RvU3RyaW5nKCkgT2JqZWN0LnRvU3RyaW5nKCl9LjwvcD4KLSAgICAgKgotICAgICAqICBAcmV0dXJuIDxjb2RlPlN0cmluZzwvY29kZT4gcmVwcmVzZW50YXRpb24gb2YgdGhpcyA8Y29kZT5RTmFtZTwvY29kZT4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotICAgICAgICBpZiAobmFtZXNwYWNlVVJJLmVxdWFscyhYTUxDb25zdGFudHMuTlVMTF9OU19VUkkpKSB7Ci0gICAgICAgICAgICByZXR1cm4gbG9jYWxQYXJ0OwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgcmV0dXJuICJ7IiArIG5hbWVzcGFjZVVSSSArICJ9IiArIGxvY2FsUGFydDsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPjxjb2RlPlFOYW1lPC9jb2RlPiBkZXJpdmVkIGZyb20gcGFyc2luZyB0aGUgZm9ybWF0dGVkCi0gICAgICogPGNvZGU+U3RyaW5nPC9jb2RlPi48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5JZiB0aGUgPGNvZGU+U3RyaW5nPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPiBvciBkb2VzIG5vdCBjb25mb3JtIHRvCi0gICAgICoge0BsaW5rICN0b1N0cmluZygpIFFOYW1lLnRvU3RyaW5nKCl9IGZvcm1hdHRpbmcsIGFuCi0gICAgICogPGNvZGU+SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uPC9jb2RlPiBpcyB0aHJvd24uPC9wPgotICAgICAqCi0gICAgICogPHA+PGVtPlRoZSA8Y29kZT5TdHJpbmc8L2NvZGU+IDxzdHJvbmc+TVVTVDwvc3Ryb25nPiBiZSBpbiB0aGUKLSAgICAgKiBmb3JtIHJldHVybmVkIGJ5IHtAbGluayAjdG9TdHJpbmcoKSBRTmFtZS50b1N0cmluZygpfS48L2VtPjwvcD4KLSAgICAgKgotICAgICAqIDxwPlRoZSBjb21tb25seSBhY2NlcHRlZCB3YXkgb2YgcmVwcmVzZW50aW5nIGEgPGNvZGU+UU5hbWU8L2NvZGU+Ci0gICAgICogYXMgYSA8Y29kZT5TdHJpbmc8L2NvZGU+IHdhcwotICAgICAqIDxhIGhyZWY9Imh0dHA6Ly9qY2xhcmsuY29tL3htbC94bWxucy5odG0iPmRlZmluZWQ8L2E+Ci0gICAgICogYnkgSmFtZXMgQ2xhcmsuICBBbHRob3VnaCB0aGlzIGlzIG5vdCBhIDxlbT5zdGFuZGFyZDwvZW0+Ci0gICAgICogc3BlY2lmaWNhdGlvbiwgaXQgaXMgaW4gY29tbW9uIHVzZSwgZS5nLiB7QGxpbmsKLSAgICAgKiBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyI3NldFBhcmFtZXRlcihTdHJpbmcgbmFtZSwgT2JqZWN0IHZhbHVlKX0uCi0gICAgICogVGhpcyBpbXBsZW1lbnRhdGlvbiBwYXJzZXMgYSA8Y29kZT5TdHJpbmc8L2NvZGU+IGZvcm1hdHRlZAotICAgICAqIGFzOiAieyIgKyBOYW1lc3BhY2UgVVJJICsgIn0iICsgbG9jYWwgcGFydC4gIElmIHRoZSBOYW1lc3BhY2UKLSAgICAgKiBVUkkgPGNvZGU+LmVxdWFscyhYTUxDb25zdGFudHMuTlVMTF9OU19VUkkpPC9jb2RlPiwgb25seSB0aGUKLSAgICAgKiBsb2NhbCBwYXJ0IHNob3VsZCBiZSBwcm92aWRlZC48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5UaGUgcHJlZml4IHZhbHVlIDxzdHJvbmc+PGVtPkNBTk5PVDwvZW0+PC9zdHJvbmc+IGJlCi0gICAgICogcmVwcmVzZW50ZWQgaW4gdGhlIDxjb2RlPlN0cmluZzwvY29kZT4gYW5kIHdpbGwgYmUgc2V0IHRvCi0gICAgICoge0BsaW5rIGphdmF4LnhtbC5YTUxDb25zdGFudHMjREVGQVVMVF9OU19QUkVGSVgKLSAgICAgKiBYTUxDb25zdGFudHMuREVGQVVMVF9OU19QUkVGSVh9LjwvcD4KLSAgICAgKgotICAgICAqIDxwPlRoaXMgbWV0aG9kIGRvZXMgbm90IGRvIGZ1bGwgdmFsaWRhdGlvbiBvZiB0aGUgcmVzdWx0aW5nCi0gICAgICogPGNvZGU+UU5hbWU8L2NvZGU+LgotICAgICAqIDxwPlRoZSBOYW1lc3BhY2UgVVJJIGlzIG5vdCB2YWxpZGF0ZWQgYXMgYQotICAgICAqIDxhIGhyZWY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzIzOTYudHh0Ij5VUkkgcmVmZXJlbmNlPC9hPi4KLSAgICAgKiBUaGUgbG9jYWwgcGFydCBpcyBub3QgdmFsaWRhdGVkIGFzIGEKLSAgICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMteG1sLW5hbWVzLyNOVC1OQ05hbWUiPk5DTmFtZTwvYT4KLSAgICAgKiBhcyBzcGVjaWZpZWQgaW4KLSAgICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMteG1sLW5hbWVzLyI+TmFtZXNwYWNlcyBpbiBYTUw8L2E+LjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBxTmFtZUFzU3RyaW5nIDxjb2RlPlN0cmluZzwvY29kZT4gcmVwcmVzZW50YXRpb24KLSAgICAgKiBvZiB0aGUgPGNvZGU+UU5hbWU8L2NvZGU+Ci0gICAgICoKLSAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBXaGVuIDxjb2RlPnFOYW1lQXNTdHJpbmc8L2NvZGU+IGlzCi0gICAgICogICA8Y29kZT5udWxsPC9jb2RlPiBvciBtYWxmb3JtZWQKLSAgICAgKgotICAgICAqIEByZXR1cm4gPGNvZGU+UU5hbWU8L2NvZGU+IGNvcnJlc3BvbmRpbmcgdG8gdGhlIGdpdmVuIDxjb2RlPlN0cmluZzwvY29kZT4KLSAgICAgKiBAc2VlICN0b1N0cmluZygpIFFOYW1lLnRvU3RyaW5nKCkKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFFOYW1lIHZhbHVlT2YoU3RyaW5nIHFOYW1lQXNTdHJpbmcpIHsKLQotICAgICAgICAvLyBudWxsIGlzIG5vdCB2YWxpZAotICAgICAgICBpZiAocU5hbWVBc1N0cmluZyA9PSBudWxsKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICAiY2Fubm90IGNyZWF0ZSBRTmFtZSBmcm9tIFwibnVsbFwiIG9yIFwiXCIgU3RyaW5nIik7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyAiIiBsb2NhbCBwYXJ0IGlzIHZhbGlkIHRvIHByZXNlcnZlIGNvbXBhdGlibGUgYmVoYXZpb3Igd2l0aCBRTmFtZSAxLjAKLSAgICAgICAgaWYgKHFOYW1lQXNTdHJpbmcubGVuZ3RoKCkgPT0gMCkgewotICAgICAgICAgICAgcmV0dXJuIG5ldyBRTmFtZSgKLSAgICAgICAgICAgICAgICBYTUxDb25zdGFudHMuTlVMTF9OU19VUkksCi0gICAgICAgICAgICAgICAgcU5hbWVBc1N0cmluZywKLSAgICAgICAgICAgICAgICBYTUxDb25zdGFudHMuREVGQVVMVF9OU19QUkVGSVgpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gbG9jYWwgcGFydCBvbmx5PwotICAgICAgICBpZiAocU5hbWVBc1N0cmluZy5jaGFyQXQoMCkgIT0gJ3snKSB7Ci0gICAgICAgICAgICByZXR1cm4gbmV3IFFOYW1lKAotICAgICAgICAgICAgICAgIFhNTENvbnN0YW50cy5OVUxMX05TX1VSSSwKLSAgICAgICAgICAgICAgICBxTmFtZUFzU3RyaW5nLAotICAgICAgICAgICAgICAgIFhNTENvbnN0YW50cy5ERUZBVUxUX05TX1BSRUZJWCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBOYW1lc3BhY2UgVVJJIGltcHJvcGVybHkgc3BlY2lmaWVkPwotICAgICAgICBpZiAocU5hbWVBc1N0cmluZy5zdGFydHNXaXRoKCJ7IiArIFhNTENvbnN0YW50cy5OVUxMX05TX1VSSSArICJ9IikpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgIk5hbWVzcGFjZSBVUkkgLmVxdWFscyhYTUxDb25zdGFudHMuTlVMTF9OU19VUkkpLCAiCi0gICAgICAgICAgICAgICAgKyAiLmVxdWFscyhcIiIgKyBYTUxDb25zdGFudHMuTlVMTF9OU19VUkkgKyAiXCIpLCAiCi0gICAgICAgICAgICAgICAgKyAib25seSB0aGUgbG9jYWwgcGFydCwgIgotICAgICAgICAgICAgICAgICsgIlwiIgotICAgICAgICAgICAgICAgICsgcU5hbWVBc1N0cmluZy5zdWJzdHJpbmcoMiArIFhNTENvbnN0YW50cy5OVUxMX05TX1VSSS5sZW5ndGgoKSkKLSAgICAgICAgICAgICAgICArICJcIiwgIgotICAgICAgICAgICAgICAgICsgInNob3VsZCBiZSBwcm92aWRlZC4iKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIE5hbWVzcGFjZSBVUkkgYW5kIGxvY2FsIHBhcnQgc3BlY2lmaWVkCi0gICAgICAgIGludCBlbmRPZk5hbWVzcGFjZVVSSSA9IHFOYW1lQXNTdHJpbmcuaW5kZXhPZignfScpOwotICAgICAgICBpZiAoZW5kT2ZOYW1lc3BhY2VVUkkgPT0gLTEpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgImNhbm5vdCBjcmVhdGUgUU5hbWUgZnJvbSBcIiIKLSAgICAgICAgICAgICAgICAgICAgKyBxTmFtZUFzU3RyaW5nCi0gICAgICAgICAgICAgICAgICAgICsgIlwiLCBtaXNzaW5nIGNsb3NpbmcgXCJ9XCIiKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbmV3IFFOYW1lKAotICAgICAgICAgICAgcU5hbWVBc1N0cmluZy5zdWJzdHJpbmcoMSwgZW5kT2ZOYW1lc3BhY2VVUkkpLAotICAgICAgICAgICAgcU5hbWVBc1N0cmluZy5zdWJzdHJpbmcoZW5kT2ZOYW1lc3BhY2VVUkkgKyAxKSwKLSAgICAgICAgICAgIFhNTENvbnN0YW50cy5ERUZBVUxUX05TX1BSRUZJWCk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmF4L3htbC9uYW1lc3BhY2UvcGFja2FnZS5odG1sIGIvc3JjL2phdmF4L3htbC9uYW1lc3BhY2UvcGFja2FnZS5odG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiNWIwMmVkLi4wMDAwMDAwCi0tLSBhL3NyYy9qYXZheC94bWwvbmFtZXNwYWNlL3BhY2thZ2UuaHRtbAorKysgL2Rldi9udWxsCkBAIC0xLDU0ICswLDAgQEAKLTw/eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04Ij8+Ci08IS0tCi1Db3B5cmlnaHQgKGMpIDIwMDMsIDIwMDUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi1ETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0KLVRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci11bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi1wYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi1ieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLQotVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi1BTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLUZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLWFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0KLVlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLTIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLUluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLQotUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLW9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLXF1ZXN0aW9ucy4gCi0tLT4KLQotPCFET0NUWVBFIGh0bWwKLSAgICAgUFVCTElDICItLy9XM0MvL0RURCBYSFRNTCAxLjAgU3RyaWN0Ly9FTiIKLSAgICAgImh0dHA6Ly93d3cudzMub3JnL1RSL3hodG1sMS9EVEQveGh0bWwxLXN0cmljdC5kdGQiPgotCi08aHRtbCB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCI+Ci0KLTxoZWFkPgotICA8dGl0bGU+amF2YXgueG1sLm5hbWVzcGFjZTwvdGl0bGU+Ci0KLSAgPG1ldGEgbmFtZT0iQ1ZTIgotICAgICAgICBjb250ZW50PSIkSWQ6IHBhY2thZ2UuaHRtbCx2IDEuMiAyMDA1LzA2LzEwIDAzOjUwOjI4IGplZmZzdXR0b3IgRXhwICQiIC8+Ci0gIDxtZXRhIG5hbWU9IkFVVEhPUiIKLSAgICAgICAgY29udGVudD0iSmVmZi5TdXR0b3JAU3VuLmNvbSIgLz4KLTwvaGVhZD4KLQotPGJvZHk+Ci0KLTxwPlhNTCBOYW1lc3BhY2UgcHJvY2Vzc2luZy48L3A+Ci0KLTxwPlRoZSBmb2xsb3dpbmcgWE1MIHN0YW5kYXJkcyBhcHBseTo8L3A+Ci08dWw+Ci0gIDxsaT48YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94bWxzY2hlbWEtMi8jUU5hbWUiPlhNTCBTY2hlbWEgUGFydDI6IERhdGF0eXBlcyBzcGVjaWZpY2F0aW9uPC9hPjwvbGk+Ci0gIDxsaT48YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMteG1sLW5hbWVzLyNucy1xdWFsbmFtZXMiPk5hbWVzcGFjZXMgaW4gWE1MPC9hPjwvbGk+Ci0gIDxsaT48YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9YTUwveG1sLW5hbWVzLTE5OTkwMTE0LWVycmF0YSI+TmFtZXNwYWNlcyBpbiBYTUwgRXJyYXRhPC9hPjwvbGk+Ci08L3VsPgotCi08L2JvZHk+Ci08L2h0bWw+CmRpZmYgLS1naXQgYS9zcmMvamF2YXgveG1sL3BhcnNlcnMvRG9jdW1lbnRCdWlsZGVyLmphdmEgYi9zcmMvamF2YXgveG1sL3BhcnNlcnMvRG9jdW1lbnRCdWlsZGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDMzYzMyNWQuLjAwMDAwMDAKLS0tIGEvc3JjL2phdmF4L3htbC9wYXJzZXJzL0RvY3VtZW50QnVpbGRlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzQ4ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDAsIDIwMDYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLXBhY2thZ2UgamF2YXgueG1sLnBhcnNlcnM7Ci0KLWltcG9ydCBqYXZhLmlvLkZpbGU7Ci1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOwotCi1pbXBvcnQgamF2YXgueG1sLnZhbGlkYXRpb24uU2NoZW1hOwotCi1pbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7Ci1pbXBvcnQgb3JnLnczYy5kb20uRE9NSW1wbGVtZW50YXRpb247Ci0KLWltcG9ydCBvcmcueG1sLnNheC5FbnRpdHlSZXNvbHZlcjsKLWltcG9ydCBvcmcueG1sLnNheC5FcnJvckhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguSW5wdXRTb3VyY2U7Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotCi0vKioKLSAqIERlZmluZXMgdGhlIEFQSSB0byBvYnRhaW4gRE9NIERvY3VtZW50IGluc3RhbmNlcyBmcm9tIGFuIFhNTAotICogZG9jdW1lbnQuIFVzaW5nIHRoaXMgY2xhc3MsIGFuIGFwcGxpY2F0aW9uIHByb2dyYW1tZXIgY2FuIG9idGFpbiBhCi0gKiB7QGxpbmsgRG9jdW1lbnR9IGZyb20gWE1MLjxwPgotICoKLSAqIEFuIGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgY2FuIGJlIG9idGFpbmVkIGZyb20gdGhlCi0gKiB7QGxpbmsgRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSNuZXdEb2N1bWVudEJ1aWxkZXIoKX0gbWV0aG9kLiBPbmNlCi0gKiBhbiBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIGlzIG9idGFpbmVkLCBYTUwgY2FuIGJlIHBhcnNlZCBmcm9tIGEKLSAqIHZhcmlldHkgb2YgaW5wdXQgc291cmNlcy4gVGhlc2UgaW5wdXQgc291cmNlcyBhcmUgSW5wdXRTdHJlYW1zLAotICogRmlsZXMsIFVSTHMsIGFuZCBTQVggSW5wdXRTb3VyY2VzLjxwPgotICoKLSAqIE5vdGUgdGhhdCB0aGlzIGNsYXNzIHJldXNlcyBzZXZlcmFsIGNsYXNzZXMgZnJvbSB0aGUgU0FYIEFQSS4gVGhpcwotICogZG9lcyBub3QgcmVxdWlyZSB0aGF0IHRoZSBpbXBsZW1lbnRvciBvZiB0aGUgdW5kZXJseWluZyBET00KLSAqIGltcGxlbWVudGF0aW9uIHVzZSBhIFNBWCBwYXJzZXIgdG8gcGFyc2UgWE1MIGRvY3VtZW50IGludG8gYQotICogPGNvZGU+RG9jdW1lbnQ8L2NvZGU+LiBJdCBtZXJlbHkgcmVxdWlyZXMgdGhhdCB0aGUgaW1wbGVtZW50YXRpb24KLSAqIGNvbW11bmljYXRlIHdpdGggdGhlIGFwcGxpY2F0aW9uIHVzaW5nIHRoZXNlIGV4aXN0aW5nIEFQSXMuCi0gKgotICogQGF1dGhvciA8YSBocmVmPSJtYWlsdG86SmVmZi5TdXR0b3JAU3VuLmNvbSI+SmVmZiBTdXR0b3I8L2E+Ci0gKi8KLQotcHVibGljIGFic3RyYWN0IGNsYXNzIERvY3VtZW50QnVpbGRlciB7Ci0KLQotICAgIC8qKiBQcm90ZWN0ZWQgY29uc3RydWN0b3IgKi8KLSAgICBwcm90ZWN0ZWQgRG9jdW1lbnRCdWlsZGVyICgpIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5SZXNldCB0aGlzIDxjb2RlPkRvY3VtZW50QnVpbGRlcjwvY29kZT4gdG8gaXRzIG9yaWdpbmFsIGNvbmZpZ3VyYXRpb24uPC9wPgotICAgICAqCi0gICAgICogPHA+PGNvZGU+RG9jdW1lbnRCdWlsZGVyPC9jb2RlPiBpcyByZXNldCB0byB0aGUgc2FtZSBzdGF0ZSBhcyB3aGVuIGl0IHdhcyBjcmVhdGVkIHdpdGgKLSAgICAgKiB7QGxpbmsgRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSNuZXdEb2N1bWVudEJ1aWxkZXIoKX0uCi0gICAgICogPGNvZGU+cmVzZXQoKTwvY29kZT4gaXMgZGVzaWduZWQgdG8gYWxsb3cgdGhlIHJldXNlIG9mIGV4aXN0aW5nIDxjb2RlPkRvY3VtZW50QnVpbGRlcjwvY29kZT5zCi0gICAgICogdGh1cyBzYXZpbmcgcmVzb3VyY2VzIGFzc29jaWF0ZWQgd2l0aCB0aGUgY3JlYXRpb24gb2YgbmV3IDxjb2RlPkRvY3VtZW50QnVpbGRlcjwvY29kZT5zLjwvcD4KLSAgICAgKgotICAgICAqIDxwPlRoZSByZXNldCA8Y29kZT5Eb2N1bWVudEJ1aWxkZXI8L2NvZGU+IGlzIG5vdCBndWFyYW50ZWVkIHRvIGhhdmUgdGhlIHNhbWUge0BsaW5rIEVudGl0eVJlc29sdmVyfSBvciB7QGxpbmsgRXJyb3JIYW5kbGVyfQotICAgICAqIDxjb2RlPk9iamVjdDwvY29kZT5zLCBlLmcuIHtAbGluayBPYmplY3QjZXF1YWxzKE9iamVjdCBvYmopfS4gIEl0IGlzIGd1YXJhbnRlZWQgdG8gaGF2ZSBhIGZ1bmN0aW9uYWxseSBlcXVhbAotICAgICAqIDxjb2RlPkVudGl0eVJlc29sdmVyPC9jb2RlPiBhbmQgPGNvZGU+RXJyb3JIYW5kbGVyPC9jb2RlPi48L3A+Ci0gICAgICoKLSAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIFdoZW4gaW1wbGVtZW50YXRpb24gZG9lcyBub3QKLSAgICAgKiAgIG92ZXJyaWRlIHRoaXMgbWV0aG9kLgotICAgICAqCi0gICAgICogQHNpbmNlIDEuNQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHJlc2V0KCkgewotCi0gICAgICAgIC8vIGltcGxlbWVudG9ycyBzaG91bGQgb3ZlcnJpZGUgdGhpcyBtZXRob2QKLSAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICJUaGlzIERvY3VtZW50QnVpbGRlciwgXCIiICsgdGhpcy5nZXRDbGFzcygpLmdldE5hbWUoKSArICJcIiwgZG9lcyBub3Qgc3VwcG9ydCB0aGUgcmVzZXQgZnVuY3Rpb25hbGl0eS4iCi0gICAgICAgICAgICAgICAgKyAiICBTcGVjaWZpY2F0aW9uIFwiIiArIHRoaXMuZ2V0Q2xhc3MoKS5nZXRQYWNrYWdlKCkuZ2V0U3BlY2lmaWNhdGlvblRpdGxlKCkgKyAiXCIiCi0gICAgICAgICAgICAgICAgKyAiIHZlcnNpb24gXCIiICsgdGhpcy5nZXRDbGFzcygpLmdldFBhY2thZ2UoKS5nZXRTcGVjaWZpY2F0aW9uVmVyc2lvbigpICsgIlwiIgotICAgICAgICAgICAgICAgICk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUGFyc2UgdGhlIGNvbnRlbnQgb2YgdGhlIGdpdmVuIDxjb2RlPklucHV0U3RyZWFtPC9jb2RlPiBhcyBhbiBYTUwKLSAgICAgKiBkb2N1bWVudCBhbmQgcmV0dXJuIGEgbmV3IERPTSB7QGxpbmsgRG9jdW1lbnR9IG9iamVjdC4KLSAgICAgKiBBbiA8Y29kZT5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb248L2NvZGU+IGlzIHRocm93biBpZiB0aGUKLSAgICAgKiA8Y29kZT5JbnB1dFN0cmVhbTwvY29kZT4gaXMgbnVsbC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBpcyBJbnB1dFN0cmVhbSBjb250YWluaW5nIHRoZSBjb250ZW50IHRvIGJlIHBhcnNlZC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gPGNvZGU+RG9jdW1lbnQ8L2NvZGU+IHJlc3VsdCBvZiBwYXJzaW5nIHRoZQotICAgICAqICA8Y29kZT5JbnB1dFN0cmVhbTwvY29kZT4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gSWYgYW55IElPIGVycm9ycyBvY2N1ci4KLSAgICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBJZiBhbnkgcGFyc2UgZXJyb3JzIG9jY3VyLgotICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIFdoZW4gPGNvZGU+aXM8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+Ci0gICAgICoKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkRvY3VtZW50SGFuZGxlcgotICAgICAqLwotCi0gICAgcHVibGljIERvY3VtZW50IHBhcnNlKElucHV0U3RyZWFtIGlzKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChpcyA9PSBudWxsKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJJbnB1dFN0cmVhbSBjYW5ub3QgYmUgbnVsbCIpOwotICAgICAgICB9Ci0KLSAgICAgICAgSW5wdXRTb3VyY2UgaW4gPSBuZXcgSW5wdXRTb3VyY2UoaXMpOwotICAgICAgICByZXR1cm4gcGFyc2UoaW4pOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFBhcnNlIHRoZSBjb250ZW50IG9mIHRoZSBnaXZlbiA8Y29kZT5JbnB1dFN0cmVhbTwvY29kZT4gYXMgYW4KLSAgICAgKiBYTUwgZG9jdW1lbnQgYW5kIHJldHVybiBhIG5ldyBET00ge0BsaW5rIERvY3VtZW50fSBvYmplY3QuCi0gICAgICogQW4gPGNvZGU+SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uPC9jb2RlPiBpcyB0aHJvd24gaWYgdGhlCi0gICAgICogPGNvZGU+SW5wdXRTdHJlYW08L2NvZGU+IGlzIG51bGwuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaXMgSW5wdXRTdHJlYW0gY29udGFpbmluZyB0aGUgY29udGVudCB0byBiZSBwYXJzZWQuCi0gICAgICogQHBhcmFtIHN5c3RlbUlkIFByb3ZpZGUgYSBiYXNlIGZvciByZXNvbHZpbmcgcmVsYXRpdmUgVVJJcy4KLSAgICAgKgotICAgICAqIEByZXR1cm4gQSBuZXcgRE9NIERvY3VtZW50IG9iamVjdC4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gSWYgYW55IElPIGVycm9ycyBvY2N1ci4KLSAgICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBJZiBhbnkgcGFyc2UgZXJyb3JzIG9jY3VyLgotICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIFdoZW4gPGNvZGU+aXM8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+Ci0gICAgICoKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkRvY3VtZW50SGFuZGxlcgotICAgICAqLwotCi0gICAgcHVibGljIERvY3VtZW50IHBhcnNlKElucHV0U3RyZWFtIGlzLCBTdHJpbmcgc3lzdGVtSWQpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKGlzID09IG51bGwpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIklucHV0U3RyZWFtIGNhbm5vdCBiZSBudWxsIik7Ci0gICAgICAgIH0KLQotICAgICAgICBJbnB1dFNvdXJjZSBpbiA9IG5ldyBJbnB1dFNvdXJjZShpcyk7Ci0gICAgICAgIGluLnNldFN5c3RlbUlkKHN5c3RlbUlkKTsKLSAgICAgICAgcmV0dXJuIHBhcnNlKGluKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBQYXJzZSB0aGUgY29udGVudCBvZiB0aGUgZ2l2ZW4gVVJJIGFzIGFuIFhNTCBkb2N1bWVudAotICAgICAqIGFuZCByZXR1cm4gYSBuZXcgRE9NIHtAbGluayBEb2N1bWVudH0gb2JqZWN0LgotICAgICAqIEFuIDxjb2RlPklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbjwvY29kZT4gaXMgdGhyb3duIGlmIHRoZQotICAgICAqIFVSSSBpcyA8Y29kZT5udWxsPC9jb2RlPiBudWxsLgotICAgICAqCi0gICAgICogQHBhcmFtIHVyaSBUaGUgbG9jYXRpb24gb2YgdGhlIGNvbnRlbnQgdG8gYmUgcGFyc2VkLgotICAgICAqCi0gICAgICogQHJldHVybiBBIG5ldyBET00gRG9jdW1lbnQgb2JqZWN0LgotICAgICAqCi0gICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBJZiBhbnkgSU8gZXJyb3JzIG9jY3VyLgotICAgICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uIElmIGFueSBwYXJzZSBlcnJvcnMgb2NjdXIuCi0gICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gV2hlbiA8Y29kZT51cmk8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+Ci0gICAgICoKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkRvY3VtZW50SGFuZGxlcgotICAgICAqLwotCi0gICAgcHVibGljIERvY3VtZW50IHBhcnNlKFN0cmluZyB1cmkpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKHVyaSA9PSBudWxsKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJVUkkgY2Fubm90IGJlIG51bGwiKTsKLSAgICAgICAgfQotCi0gICAgICAgIElucHV0U291cmNlIGluID0gbmV3IElucHV0U291cmNlKHVyaSk7Ci0gICAgICAgIHJldHVybiBwYXJzZShpbik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUGFyc2UgdGhlIGNvbnRlbnQgb2YgdGhlIGdpdmVuIGZpbGUgYXMgYW4gWE1MIGRvY3VtZW50Ci0gICAgICogYW5kIHJldHVybiBhIG5ldyBET00ge0BsaW5rIERvY3VtZW50fSBvYmplY3QuCi0gICAgICogQW4gPGNvZGU+SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uPC9jb2RlPiBpcyB0aHJvd24gaWYgdGhlCi0gICAgICogPGNvZGU+RmlsZTwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4gbnVsbC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBmIFRoZSBmaWxlIGNvbnRhaW5pbmcgdGhlIFhNTCB0byBwYXJzZS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gSWYgYW55IElPIGVycm9ycyBvY2N1ci4KLSAgICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBJZiBhbnkgcGFyc2UgZXJyb3JzIG9jY3VyLgotICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIFdoZW4gPGNvZGU+ZjwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4KLSAgICAgKgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguRG9jdW1lbnRIYW5kbGVyCi0gICAgICogQHJldHVybiBBIG5ldyBET00gRG9jdW1lbnQgb2JqZWN0LgotICAgICAqLwotCi0gICAgcHVibGljIERvY3VtZW50IHBhcnNlKEZpbGUgZikgdGhyb3dzIFNBWEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewotICAgICAgICBpZiAoZiA9PSBudWxsKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWxlIGNhbm5vdCBiZSBudWxsIik7Ci0gICAgICAgIH0KLQotICAgICAgICAvL2NvbnZlcnQgZmlsZSB0byBhcHByb3ByaWF0ZSBVUkksIGYudG9VUkkoKS50b0FTQ0lJU3RyaW5nKCkKLSAgICAgICAgLy9jb252ZXJ0cyB0aGUgVVJJIHRvIHN0cmluZyBhcyBwZXIgcnVsZSBzcGVjaWZpZWQgaW4KLSAgICAgICAgLy9SRkMgMjM5NiwKLSAgICAgICAgSW5wdXRTb3VyY2UgaW4gPSBuZXcgSW5wdXRTb3VyY2UoZi50b1VSSSgpLnRvQVNDSUlTdHJpbmcoKSk7Ci0gICAgICAgIHJldHVybiBwYXJzZShpbik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUGFyc2UgdGhlIGNvbnRlbnQgb2YgdGhlIGdpdmVuIGlucHV0IHNvdXJjZSBhcyBhbiBYTUwgZG9jdW1lbnQKLSAgICAgKiBhbmQgcmV0dXJuIGEgbmV3IERPTSB7QGxpbmsgRG9jdW1lbnR9IG9iamVjdC4KLSAgICAgKiBBbiA8Y29kZT5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb248L2NvZGU+IGlzIHRocm93biBpZiB0aGUKLSAgICAgKiA8Y29kZT5JbnB1dFNvdXJjZTwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4gbnVsbC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBpcyBJbnB1dFNvdXJjZSBjb250YWluaW5nIHRoZSBjb250ZW50IHRvIGJlIHBhcnNlZC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gQSBuZXcgRE9NIERvY3VtZW50IG9iamVjdC4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gSWYgYW55IElPIGVycm9ycyBvY2N1ci4KLSAgICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBJZiBhbnkgcGFyc2UgZXJyb3JzIG9jY3VyLgotICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIFdoZW4gPGNvZGU+aXM8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+Ci0gICAgICoKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkRvY3VtZW50SGFuZGxlcgotICAgICAqLwotCi0gICAgcHVibGljIGFic3RyYWN0IERvY3VtZW50IHBhcnNlKElucHV0U291cmNlIGlzKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbjsKLQotCi0gICAgLyoqCi0gICAgICogSW5kaWNhdGVzIHdoZXRoZXIgb3Igbm90IHRoaXMgcGFyc2VyIGlzIGNvbmZpZ3VyZWQgdG8KLSAgICAgKiB1bmRlcnN0YW5kIG5hbWVzcGFjZXMuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhpcyBwYXJzZXIgaXMgY29uZmlndXJlZCB0byB1bmRlcnN0YW5kCi0gICAgICogICAgICAgICBuYW1lc3BhY2VzOyBmYWxzZSBvdGhlcndpc2UuCi0gICAgICovCi0KLSAgICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBpc05hbWVzcGFjZUF3YXJlKCk7Ci0KLSAgICAvKioKLSAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciBvciBub3QgdGhpcyBwYXJzZXIgaXMgY29uZmlndXJlZCB0bwotICAgICAqIHZhbGlkYXRlIFhNTCBkb2N1bWVudHMuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhpcyBwYXJzZXIgaXMgY29uZmlndXJlZCB0byB2YWxpZGF0ZQotICAgICAqICAgICAgICAgWE1MIGRvY3VtZW50czsgZmFsc2Ugb3RoZXJ3aXNlLgotICAgICAqLwotCi0gICAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gaXNWYWxpZGF0aW5nKCk7Ci0KLSAgICAvKioKLSAgICAgKiBTcGVjaWZ5IHRoZSB7QGxpbmsgRW50aXR5UmVzb2x2ZXJ9IHRvIGJlIHVzZWQgdG8gcmVzb2x2ZQotICAgICAqIGVudGl0aWVzIHByZXNlbnQgaW4gdGhlIFhNTCBkb2N1bWVudCB0byBiZSBwYXJzZWQuIFNldHRpbmcKLSAgICAgKiB0aGlzIHRvIDxjb2RlPm51bGw8L2NvZGU+IHdpbGwgcmVzdWx0IGluIHRoZSB1bmRlcmx5aW5nCi0gICAgICogaW1wbGVtZW50YXRpb24gdXNpbmcgaXQncyBvd24gZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBhbmQKLSAgICAgKiBiZWhhdmlvci4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlciBUaGUgPGNvZGU+RW50aXR5UmVzb2x2ZXI8L2NvZGU+IHRvIGJlIHVzZWQgdG8gcmVzb2x2ZSBlbnRpdGllcwotICAgICAqICAgICAgICAgICBwcmVzZW50IGluIHRoZSBYTUwgZG9jdW1lbnQgdG8gYmUgcGFyc2VkLgotICAgICAqLwotCi0gICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2V0RW50aXR5UmVzb2x2ZXIoRW50aXR5UmVzb2x2ZXIgZXIpOwotCi0gICAgLyoqCi0gICAgICogU3BlY2lmeSB0aGUge0BsaW5rIEVycm9ySGFuZGxlcn0gdG8gYmUgdXNlZCBieSB0aGUgcGFyc2VyLgotICAgICAqIFNldHRpbmcgdGhpcyB0byA8Y29kZT5udWxsPC9jb2RlPiB3aWxsIHJlc3VsdCBpbiB0aGUgdW5kZXJseWluZwotICAgICAqIGltcGxlbWVudGF0aW9uIHVzaW5nIGl0J3Mgb3duIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gYW5kCi0gICAgICogYmVoYXZpb3IuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZWggVGhlIDxjb2RlPkVycm9ySGFuZGxlcjwvY29kZT4gdG8gYmUgdXNlZCBieSB0aGUgcGFyc2VyLgotICAgICAqLwotCi0gICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2V0RXJyb3JIYW5kbGVyKEVycm9ySGFuZGxlciBlaCk7Ci0KLSAgICAvKioKLSAgICAgKiBPYnRhaW4gYSBuZXcgaW5zdGFuY2Ugb2YgYSBET00ge0BsaW5rIERvY3VtZW50fSBvYmplY3QKLSAgICAgKiB0byBidWlsZCBhIERPTSB0cmVlIHdpdGguCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIEEgbmV3IGluc3RhbmNlIG9mIGEgRE9NIERvY3VtZW50IG9iamVjdC4KLSAgICAgKi8KLQotICAgIHB1YmxpYyBhYnN0cmFjdCBEb2N1bWVudCBuZXdEb2N1bWVudCgpOwotCi0gICAgLyoqCi0gICAgICogT2J0YWluIGFuIGluc3RhbmNlIG9mIGEge0BsaW5rIERPTUltcGxlbWVudGF0aW9ufSBvYmplY3QuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIEEgbmV3IGluc3RhbmNlIG9mIGEgPGNvZGU+RE9NSW1wbGVtZW50YXRpb248L2NvZGU+LgotICAgICAqLwotCi0gICAgcHVibGljIGFic3RyYWN0IERPTUltcGxlbWVudGF0aW9uIGdldERPTUltcGxlbWVudGF0aW9uKCk7Ci0KLSAgICAvKiogPHA+R2V0IGN1cnJlbnQgc3RhdGUgb2YgY2Fub25pY2FsaXphdGlvbi48L3A+Ci0gICAgICoKLSAgICAgKiBAcmV0dXJuIGN1cnJlbnQgc3RhdGUgY2Fub25pY2FsaXphdGlvbiBjb250cm9sCi0gICAgICovCi0gICAgLyoKLSAgICBwdWJsaWMgYm9vbGVhbiBnZXRDYW5vbmljYWxpemF0aW9uKCkgewotICAgICAgICByZXR1cm4gY2Fub25pY2FsU3RhdGU7Ci0gICAgfQotICAgICovCi0KLSAgICAvKiogPHA+R2V0IGEgcmVmZXJlbmNlIHRvIHRoZSB0aGUge0BsaW5rIFNjaGVtYX0gYmVpbmcgdXNlZCBieQotICAgICAqIHRoZSBYTUwgcHJvY2Vzc29yLjwvcD4KLSAgICAgKgotICAgICAqIDxwPklmIG5vIHNjaGVtYSBpcyBiZWluZyB1c2VkLCA8Y29kZT5udWxsPC9jb2RlPiBpcyByZXR1cm5lZC48L3A+Ci0gICAgICoKLSAgICAgKiBAcmV0dXJuIHtAbGluayBTY2hlbWF9IGJlaW5nIHVzZWQgb3IgPGNvZGU+bnVsbDwvY29kZT4KLSAgICAgKiAgaWYgbm9uZSBpbiB1c2UKLSAgICAgKgotICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gV2hlbiBpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdAotICAgICAqICAgb3ZlcnJpZGUgdGhpcyBtZXRob2QKLSAgICAgKgotICAgICAqIEBzaW5jZSAxLjUKLSAgICAgKi8KLSAgICBwdWJsaWMgU2NoZW1hIGdldFNjaGVtYSgpIHsKLSAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKAotICAgICAgICAgICAgIlRoaXMgcGFyc2VyIGRvZXMgbm90IHN1cHBvcnQgc3BlY2lmaWNhdGlvbiBcIiIKLSAgICAgICAgICAgICsgdGhpcy5nZXRDbGFzcygpLmdldFBhY2thZ2UoKS5nZXRTcGVjaWZpY2F0aW9uVGl0bGUoKQotICAgICAgICAgICAgKyAiXCIgdmVyc2lvbiBcIiIKLSAgICAgICAgICAgICsgdGhpcy5nZXRDbGFzcygpLmdldFBhY2thZ2UoKS5nZXRTcGVjaWZpY2F0aW9uVmVyc2lvbigpCi0gICAgICAgICAgICArICJcIiIKLSAgICAgICAgICAgICk7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiA8cD5HZXQgdGhlIFhJbmNsdWRlIHByb2Nlc3NpbmcgbW9kZSBmb3IgdGhpcyBwYXJzZXIuPC9wPgotICAgICAqCi0gICAgICogQHJldHVybgotICAgICAqICAgICAgdGhlIHJldHVybiB2YWx1ZSBvZgotICAgICAqICAgICAgdGhlIHtAbGluayBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5I2lzWEluY2x1ZGVBd2FyZSgpfQotICAgICAqICAgICAgd2hlbiB0aGlzIHBhcnNlciB3YXMgY3JlYXRlZCBmcm9tIGZhY3RvcnkuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIFdoZW4gaW1wbGVtZW50YXRpb24gZG9lcyBub3QKLSAgICAgKiAgIG92ZXJyaWRlIHRoaXMgbWV0aG9kCi0gICAgICoKLSAgICAgKiBAc2luY2UgMS41Ci0gICAgICoKLSAgICAgKiBAc2VlIERvY3VtZW50QnVpbGRlckZhY3Rvcnkjc2V0WEluY2x1ZGVBd2FyZShib29sZWFuKQotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzWEluY2x1ZGVBd2FyZSgpIHsKLSAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKAotICAgICAgICAgICAgIlRoaXMgcGFyc2VyIGRvZXMgbm90IHN1cHBvcnQgc3BlY2lmaWNhdGlvbiBcIiIKLSAgICAgICAgICAgICsgdGhpcy5nZXRDbGFzcygpLmdldFBhY2thZ2UoKS5nZXRTcGVjaWZpY2F0aW9uVGl0bGUoKQotICAgICAgICAgICAgKyAiXCIgdmVyc2lvbiBcIiIKLSAgICAgICAgICAgICsgdGhpcy5nZXRDbGFzcygpLmdldFBhY2thZ2UoKS5nZXRTcGVjaWZpY2F0aW9uVmVyc2lvbigpCi0gICAgICAgICAgICArICJcIiIKLSAgICAgICAgICAgICk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmF4L3htbC9wYXJzZXJzL0RvY3VtZW50QnVpbGRlckZhY3RvcnkuamF2YSBiL3NyYy9qYXZheC94bWwvcGFyc2Vycy9Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDA0MjY1ZjYuLjAwMDAwMDAKLS0tIGEvc3JjL2phdmF4L3htbC9wYXJzZXJzL0RvY3VtZW50QnVpbGRlckZhY3RvcnkuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDYwNyArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDAwLCAyMDEzLCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi1wYWNrYWdlIGphdmF4LnhtbC5wYXJzZXJzOwotCi1pbXBvcnQgamF2YXgueG1sLnZhbGlkYXRpb24uU2NoZW1hOwotCi0vKioKLSAqIERlZmluZXMgYSBmYWN0b3J5IEFQSSB0aGF0IGVuYWJsZXMgYXBwbGljYXRpb25zIHRvIG9idGFpbiBhCi0gKiBwYXJzZXIgdGhhdCBwcm9kdWNlcyBET00gb2JqZWN0IHRyZWVzIGZyb20gWE1MIGRvY3VtZW50cy4KLSAqCi0gKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzpKZWZmLlN1dHRvckBTdW4uY29tIj5KZWZmIFN1dHRvcjwvYT4KLSAqIEBhdXRob3IgPGEgaHJlZj0ibWFpbHRvOk5lZXJhai5CYWphakBzdW4uY29tIj5OZWVyYWogQmFqYWo8L2E+Ci0gKgotICogQHZlcnNpb24gJFJldmlzaW9uOiAxLjkgJCwgJERhdGU6IDIwMTAvMDUvMjUgMTY6MTk6NDQgJAotCi0gKi8KLQotcHVibGljIGFic3RyYWN0IGNsYXNzIERvY3VtZW50QnVpbGRlckZhY3RvcnkgewotCi0gICAgcHJpdmF0ZSBib29sZWFuIHZhbGlkYXRpbmcgPSBmYWxzZTsKLSAgICBwcml2YXRlIGJvb2xlYW4gbmFtZXNwYWNlQXdhcmUgPSBmYWxzZTsKLSAgICBwcml2YXRlIGJvb2xlYW4gd2hpdGVzcGFjZSA9IGZhbHNlOwotICAgIHByaXZhdGUgYm9vbGVhbiBleHBhbmRFbnRpdHlSZWYgPSB0cnVlOwotICAgIHByaXZhdGUgYm9vbGVhbiBpZ25vcmVDb21tZW50cyA9IGZhbHNlOwotICAgIHByaXZhdGUgYm9vbGVhbiBjb2FsZXNjaW5nID0gZmFsc2U7Ci0KLSAgICAvKioKLSAgICAgKiA8cD5Qcm90ZWN0ZWQgY29uc3RydWN0b3IgdG8gcHJldmVudCBpbnN0YW50aWF0aW9uLgotICAgICAqIFVzZSB7QGxpbmsgI25ld0luc3RhbmNlKCl9LjwvcD4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSAoKSB7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogT2J0YWluIGEgbmV3IGluc3RhbmNlIG9mIGEKLSAgICAgKiA8Y29kZT5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5PC9jb2RlPi4gVGhpcyBzdGF0aWMgbWV0aG9kIGNyZWF0ZXMKLSAgICAgKiBhIG5ldyBmYWN0b3J5IGluc3RhbmNlLgotICAgICAqIFRoaXMgbWV0aG9kIHVzZXMgdGhlIGZvbGxvd2luZyBvcmRlcmVkIGxvb2t1cCBwcm9jZWR1cmUgdG8gZGV0ZXJtaW5lCi0gICAgICogdGhlIDxjb2RlPkRvY3VtZW50QnVpbGRlckZhY3Rvcnk8L2NvZGU+IGltcGxlbWVudGF0aW9uIGNsYXNzIHRvCi0gICAgICogbG9hZDoKLSAgICAgKiA8dWw+Ci0gICAgICogPGxpPgotICAgICAqIFVzZSB0aGUgPGNvZGU+amF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyRmFjdG9yeTwvY29kZT4gc3lzdGVtCi0gICAgICogcHJvcGVydHkuCi0gICAgICogPC9saT4KLSAgICAgKiA8bGk+Ci0gICAgICogVXNlIHRoZSBwcm9wZXJ0aWVzIGZpbGUgImxpYi9qYXhwLnByb3BlcnRpZXMiIGluIHRoZSBKUkUgZGlyZWN0b3J5LgotICAgICAqIFRoaXMgY29uZmlndXJhdGlvbiBmaWxlIGlzIGluIHN0YW5kYXJkIDxjb2RlPmphdmEudXRpbC5Qcm9wZXJ0aWVzCi0gICAgICogPC9jb2RlPiBmb3JtYXQgYW5kIGNvbnRhaW5zIHRoZSBmdWxseSBxdWFsaWZpZWQgbmFtZSBvZiB0aGUKLSAgICAgKiBpbXBsZW1lbnRhdGlvbiBjbGFzcyB3aXRoIHRoZSBrZXkgYmVpbmcgdGhlIHN5c3RlbSBwcm9wZXJ0eSBkZWZpbmVkCi0gICAgICogYWJvdmUuCi0gICAgICoKLSAgICAgKiBUaGUgamF4cC5wcm9wZXJ0aWVzIGZpbGUgaXMgcmVhZCBvbmx5IG9uY2UgYnkgdGhlIEpBWFAgaW1wbGVtZW50YXRpb24KLSAgICAgKiBhbmQgaXQncyB2YWx1ZXMgYXJlIHRoZW4gY2FjaGVkIGZvciBmdXR1cmUgdXNlLiAgSWYgdGhlIGZpbGUgZG9lcyBub3QgZXhpc3QKLSAgICAgKiB3aGVuIHRoZSBmaXJzdCBhdHRlbXB0IGlzIG1hZGUgdG8gcmVhZCBmcm9tIGl0LCBubyBmdXJ0aGVyIGF0dGVtcHRzIGFyZQotICAgICAqIG1hZGUgdG8gY2hlY2sgZm9yIGl0cyBleGlzdGVuY2UuICBJdCBpcyBub3QgcG9zc2libGUgdG8gY2hhbmdlIHRoZSB2YWx1ZQotICAgICAqIG9mIGFueSBwcm9wZXJ0eSBpbiBqYXhwLnByb3BlcnRpZXMgYWZ0ZXIgaXQgaGFzIGJlZW4gcmVhZCBmb3IgdGhlIGZpcnN0IHRpbWUuCi0gICAgICogPC9saT4KLSAgICAgKiA8bGk+Ci0gICAgICogVXNlcyB0aGUgc2VydmljZS1wcm92aWRlciBsb2FkaW5nIGZhY2lsaXRpZXMsIGRlZmluZWQgYnkgdGhlCi0gICAgICoge0BsaW5rIGphdmEudXRpbC5TZXJ2aWNlTG9hZGVyfSBjbGFzcywgdG8gYXR0ZW1wdCB0byBsb2NhdGUgYW5kIGxvYWQgYW4KLSAgICAgKiBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgc2VydmljZSB1c2luZyB0aGUge0BsaW5rcGxhaW4KLSAgICAgKiBqYXZhLnV0aWwuU2VydmljZUxvYWRlciNsb2FkKGphdmEubGFuZy5DbGFzcykgZGVmYXVsdCBsb2FkaW5nIG1lY2hhbmlzbX06Ci0gICAgICogdGhlIHNlcnZpY2UtcHJvdmlkZXIgbG9hZGluZyBmYWNpbGl0eSB3aWxsIHVzZSB0aGUge0BsaW5rcGxhaW4KLSAgICAgKiBqYXZhLmxhbmcuVGhyZWFkI2dldENvbnRleHRDbGFzc0xvYWRlcigpIGN1cnJlbnQgdGhyZWFkJ3MgY29udGV4dCBjbGFzcyBsb2FkZXJ9Ci0gICAgICogdG8gYXR0ZW1wdCB0byBsb2FkIHRoZSBzZXJ2aWNlLiBJZiB0aGUgY29udGV4dCBjbGFzcwotICAgICAqIGxvYWRlciBpcyBudWxsLCB0aGUge0BsaW5rcGxhaW4KLSAgICAgKiBDbGFzc0xvYWRlciNnZXRTeXN0ZW1DbGFzc0xvYWRlcigpIHN5c3RlbSBjbGFzcyBsb2FkZXJ9IHdpbGwgYmUgdXNlZC4KLSAgICAgKiA8L2xpPgotICAgICAqIDxsaT4KLSAgICAgKiBPdGhlcndpc2UsIHRoZSBzeXN0ZW0tZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBpcyByZXR1cm5lZC4KLSAgICAgKiA8L2xpPgotICAgICAqIDwvdWw+Ci0gICAgICoKLSAgICAgKiBPbmNlIGFuIGFwcGxpY2F0aW9uIGhhcyBvYnRhaW5lZCBhIHJlZmVyZW5jZSB0byBhCi0gICAgICogPGNvZGU+RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTwvY29kZT4gaXQgY2FuIHVzZSB0aGUgZmFjdG9yeSB0bwotICAgICAqIGNvbmZpZ3VyZSBhbmQgb2J0YWluIHBhcnNlciBpbnN0YW5jZXMuCi0gICAgICoKLSAgICAgKgotICAgICAqIDxoMj5UaXAgZm9yIFRyb3VibGUtc2hvb3Rpbmc8L2gyPgotICAgICAqIDxwPlNldHRpbmcgdGhlIDxjb2RlPmpheHAuZGVidWc8L2NvZGU+IHN5c3RlbSBwcm9wZXJ0eSB3aWxsIGNhdXNlCi0gICAgICogdGhpcyBtZXRob2QgdG8gcHJpbnQgYSBsb3Qgb2YgZGVidWcgbWVzc2FnZXMKLSAgICAgKiB0byA8Y29kZT5TeXN0ZW0uZXJyPC9jb2RlPiBhYm91dCB3aGF0IGl0IGlzIGRvaW5nIGFuZCB3aGVyZSBpdCBpcyBsb29raW5nIGF0LjwvcD4KLSAgICAgKgotICAgICAqIDxwPiBJZiB5b3UgaGF2ZSBwcm9ibGVtcyBsb2FkaW5nIHtAbGluayBEb2N1bWVudEJ1aWxkZXJ9cywgdHJ5OjwvcD4KLSAgICAgKiA8cHJlPgotICAgICAqIGphdmEgLURqYXhwLmRlYnVnPTEgWW91clByb2dyYW0gLi4uLgotICAgICAqIDwvcHJlPgotICAgICAqCi0gICAgICogQHJldHVybiBOZXcgaW5zdGFuY2Ugb2YgYSA8Y29kZT5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5PC9jb2RlPgotICAgICAqCi0gICAgICogQHRocm93cyBGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yIGluIGNhc2Ugb2Yge0BsaW5rcGxhaW4KLSAgICAgKiBqYXZhLnV0aWwuU2VydmljZUNvbmZpZ3VyYXRpb25FcnJvciBzZXJ2aWNlIGNvbmZpZ3VyYXRpb24gZXJyb3J9IG9yIGlmCi0gICAgICogdGhlIGltcGxlbWVudGF0aW9uIGlzIG5vdCBhdmFpbGFibGUgb3IgY2Fubm90IGJlIGluc3RhbnRpYXRlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIERvY3VtZW50QnVpbGRlckZhY3RvcnkgbmV3SW5zdGFuY2UoKSB7Ci0gICAgICAgIHJldHVybiBGYWN0b3J5RmluZGVyLmZpbmQoCi0gICAgICAgICAgICAgICAgLyogVGhlIGRlZmF1bHQgcHJvcGVydHkgbmFtZSBhY2NvcmRpbmcgdG8gdGhlIEpBWFAgc3BlYyAqLwotICAgICAgICAgICAgICAgIERvY3VtZW50QnVpbGRlckZhY3RvcnkuY2xhc3MsIC8vICJqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5IgotICAgICAgICAgICAgICAgIC8qIFRoZSBmYWxsYmFjayBpbXBsZW1lbnRhdGlvbiBjbGFzcyBuYW1lICovCi0gICAgICAgICAgICAgICAgImNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuamF4cC5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5SW1wbCIpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPk9idGFpbiBhIG5ldyBpbnN0YW5jZSBvZiBhIDxjb2RlPkRvY3VtZW50QnVpbGRlckZhY3Rvcnk8L2NvZGU+IGZyb20gY2xhc3MgbmFtZS4KLSAgICAgKiBUaGlzIGZ1bmN0aW9uIGlzIHVzZWZ1bCB3aGVuIHRoZXJlIGFyZSBtdWx0aXBsZSBwcm92aWRlcnMgaW4gdGhlIGNsYXNzcGF0aC4KLSAgICAgKiBJdCBnaXZlcyBtb3JlIGNvbnRyb2wgdG8gdGhlIGFwcGxpY2F0aW9uIGFzIGl0IGNhbiBzcGVjaWZ5IHdoaWNoIHByb3ZpZGVyCi0gICAgICogc2hvdWxkIGJlIGxvYWRlZC48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5PbmNlIGFuIGFwcGxpY2F0aW9uIGhhcyBvYnRhaW5lZCBhIHJlZmVyZW5jZSB0byBhIDxjb2RlPkRvY3VtZW50QnVpbGRlckZhY3Rvcnk8L2NvZGU+Ci0gICAgICogaXQgY2FuIHVzZSB0aGUgZmFjdG9yeSB0byBjb25maWd1cmUgYW5kIG9idGFpbiBwYXJzZXIgaW5zdGFuY2VzLjwvcD4KLSAgICAgKgotICAgICAqCi0gICAgICogPGgyPlRpcCBmb3IgVHJvdWJsZS1zaG9vdGluZzwvaDI+Ci0gICAgICogPHA+U2V0dGluZyB0aGUgPGNvZGU+amF4cC5kZWJ1ZzwvY29kZT4gc3lzdGVtIHByb3BlcnR5IHdpbGwgY2F1c2UKLSAgICAgKiB0aGlzIG1ldGhvZCB0byBwcmludCBhIGxvdCBvZiBkZWJ1ZyBtZXNzYWdlcwotICAgICAqIHRvIDxjb2RlPlN5c3RlbS5lcnI8L2NvZGU+IGFib3V0IHdoYXQgaXQgaXMgZG9pbmcgYW5kIHdoZXJlIGl0IGlzIGxvb2tpbmcgYXQuPC9wPgotICAgICAqCi0gICAgICogPHA+IElmIHlvdSBoYXZlIHByb2JsZW1zIHRyeTo8L3A+Ci0gICAgICogPHByZT4KLSAgICAgKiBqYXZhIC1EamF4cC5kZWJ1Zz0xIFlvdXJQcm9ncmFtIC4uLi4KLSAgICAgKiA8L3ByZT4KLSAgICAgKgotICAgICAqIEBwYXJhbSBmYWN0b3J5Q2xhc3NOYW1lIGZ1bGx5IHF1YWxpZmllZCBmYWN0b3J5IGNsYXNzIG5hbWUgdGhhdCBwcm92aWRlcyBpbXBsZW1lbnRhdGlvbiBvZiA8Y29kZT5qYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5PC9jb2RlPi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjbGFzc0xvYWRlciA8Y29kZT5DbGFzc0xvYWRlcjwvY29kZT4gdXNlZCB0byBsb2FkIHRoZSBmYWN0b3J5IGNsYXNzLiBJZiA8Y29kZT5udWxsPC9jb2RlPgotICAgICAqICAgICAgICAgICAgICAgICAgICAgY3VycmVudCA8Y29kZT5UaHJlYWQ8L2NvZGU+J3MgY29udGV4dCBjbGFzc0xvYWRlciBpcyB1c2VkIHRvIGxvYWQgdGhlIGZhY3RvcnkgY2xhc3MuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIE5ldyBpbnN0YW5jZSBvZiBhIDxjb2RlPkRvY3VtZW50QnVpbGRlckZhY3Rvcnk8L2NvZGU+Ci0gICAgICoKLSAgICAgKiBAdGhyb3dzIEZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IgaWYgPGNvZGU+ZmFjdG9yeUNsYXNzTmFtZTwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4sIG9yCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSBmYWN0b3J5IGNsYXNzIGNhbm5vdCBiZSBsb2FkZWQsIGluc3RhbnRpYXRlZC4KLSAgICAgKgotICAgICAqIEBzZWUgI25ld0luc3RhbmNlKCkKLSAgICAgKgotICAgICAqIEBzaW5jZSAxLjYKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIERvY3VtZW50QnVpbGRlckZhY3RvcnkgbmV3SW5zdGFuY2UoU3RyaW5nIGZhY3RvcnlDbGFzc05hbWUsIENsYXNzTG9hZGVyIGNsYXNzTG9hZGVyKXsKLSAgICAgICAgICAgIC8vZG8gbm90IGZhbGxiYWNrIGlmIGdpdmVuIGNsYXNzbG9hZGVyIGNhbid0IGZpbmQgdGhlIGNsYXNzLCB0aHJvdyBleGNlcHRpb24KLSAgICAgICAgICAgIHJldHVybiBGYWN0b3J5RmluZGVyLm5ld0luc3RhbmNlKERvY3VtZW50QnVpbGRlckZhY3RvcnkuY2xhc3MsCi0gICAgICAgICAgICAgICAgICAgICAgICBmYWN0b3J5Q2xhc3NOYW1lLCBjbGFzc0xvYWRlciwgZmFsc2UpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgYSB7QGxpbmsgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyfQotICAgICAqIHVzaW5nIHRoZSBjdXJyZW50bHkgY29uZmlndXJlZCBwYXJhbWV0ZXJzLgotICAgICAqCi0gICAgICogQHJldHVybiBBIG5ldyBpbnN0YW5jZSBvZiBhIERvY3VtZW50QnVpbGRlci4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBpZiBhIERvY3VtZW50QnVpbGRlcgotICAgICAqICAgY2Fubm90IGJlIGNyZWF0ZWQgd2hpY2ggc2F0aXNmaWVzIHRoZSBjb25maWd1cmF0aW9uIHJlcXVlc3RlZC4KLSAgICAgKi8KLQotICAgIHB1YmxpYyBhYnN0cmFjdCBEb2N1bWVudEJ1aWxkZXIgbmV3RG9jdW1lbnRCdWlsZGVyKCkKLSAgICAgICAgdGhyb3dzIFBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci0KLQotICAgIC8qKgotICAgICAqIFNwZWNpZmllcyB0aGF0IHRoZSBwYXJzZXIgcHJvZHVjZWQgYnkgdGhpcyBjb2RlIHdpbGwKLSAgICAgKiBwcm92aWRlIHN1cHBvcnQgZm9yIFhNTCBuYW1lc3BhY2VzLiBCeSBkZWZhdWx0IHRoZSB2YWx1ZSBvZiB0aGlzIGlzIHNldAotICAgICAqIHRvIDxjb2RlPmZhbHNlPC9jb2RlPgotICAgICAqCi0gICAgICogQHBhcmFtIGF3YXJlbmVzcyB0cnVlIGlmIHRoZSBwYXJzZXIgcHJvZHVjZWQgd2lsbCBwcm92aWRlIHN1cHBvcnQKLSAgICAgKiAgICAgICAgICAgICAgICAgIGZvciBYTUwgbmFtZXNwYWNlczsgZmFsc2Ugb3RoZXJ3aXNlLgotICAgICAqLwotCi0gICAgcHVibGljIHZvaWQgc2V0TmFtZXNwYWNlQXdhcmUoYm9vbGVhbiBhd2FyZW5lc3MpIHsKLSAgICAgICAgdGhpcy5uYW1lc3BhY2VBd2FyZSA9IGF3YXJlbmVzczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTcGVjaWZpZXMgdGhhdCB0aGUgcGFyc2VyIHByb2R1Y2VkIGJ5IHRoaXMgY29kZSB3aWxsCi0gICAgICogdmFsaWRhdGUgZG9jdW1lbnRzIGFzIHRoZXkgYXJlIHBhcnNlZC4gQnkgZGVmYXVsdCB0aGUgdmFsdWUgb2YgdGhpcwotICAgICAqIGlzIHNldCB0byA8Y29kZT5mYWxzZTwvY29kZT4uCi0gICAgICoKLSAgICAgKiA8cD4KLSAgICAgKiBOb3RlIHRoYXQgInRoZSB2YWxpZGF0aW9uIiBoZXJlIG1lYW5zCi0gICAgICogPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLXhtbCNwcm9jLXR5cGVzIj5hIHZhbGlkYXRpbmcKLSAgICAgKiBwYXJzZXI8L2E+IGFzIGRlZmluZWQgaW4gdGhlIFhNTCByZWNvbW1lbmRhdGlvbi4KLSAgICAgKiBJbiBvdGhlciB3b3JkcywgaXQgZXNzZW50aWFsbHkganVzdCBjb250cm9scyB0aGUgRFREIHZhbGlkYXRpb24uCi0gICAgICogKGV4Y2VwdCB0aGUgbGVnYWN5IHR3byBwcm9wZXJ0aWVzIGRlZmluZWQgaW4gSkFYUCAxLjIuKQotICAgICAqIDwvcD4KLSAgICAgKgotICAgICAqIDxwPgotICAgICAqIFRvIHVzZSBtb2Rlcm4gc2NoZW1hIGxhbmd1YWdlcyBzdWNoIGFzIFczQyBYTUwgU2NoZW1hIG9yCi0gICAgICogUkVMQVggTkcgaW5zdGVhZCBvZiBEVEQsIHlvdSBjYW4gY29uZmlndXJlIHlvdXIgcGFyc2VyIHRvIGJlCi0gICAgICogYSBub24tdmFsaWRhdGluZyBwYXJzZXIgYnkgbGVhdmluZyB0aGUge0BsaW5rICNzZXRWYWxpZGF0aW5nKGJvb2xlYW4pfQotICAgICAqIG1ldGhvZCA8Y29kZT5mYWxzZTwvY29kZT4sIHRoZW4gdXNlIHRoZSB7QGxpbmsgI3NldFNjaGVtYShTY2hlbWEpfQotICAgICAqIG1ldGhvZCB0byBhc3NvY2lhdGUgYSBzY2hlbWEgdG8gYSBwYXJzZXIuCi0gICAgICogPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIHZhbGlkYXRpbmcgdHJ1ZSBpZiB0aGUgcGFyc2VyIHByb2R1Y2VkIHdpbGwgdmFsaWRhdGUgZG9jdW1lbnRzCi0gICAgICogICAgICAgICAgICAgICAgICAgYXMgdGhleSBhcmUgcGFyc2VkOyBmYWxzZSBvdGhlcndpc2UuCi0gICAgICovCi0KLSAgICBwdWJsaWMgdm9pZCBzZXRWYWxpZGF0aW5nKGJvb2xlYW4gdmFsaWRhdGluZykgewotICAgICAgICB0aGlzLnZhbGlkYXRpbmcgPSB2YWxpZGF0aW5nOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNwZWNpZmllcyB0aGF0IHRoZSBwYXJzZXJzIGNyZWF0ZWQgYnkgdGhpcyAgZmFjdG9yeSBtdXN0IGVsaW1pbmF0ZQotICAgICAqIHdoaXRlc3BhY2UgaW4gZWxlbWVudCBjb250ZW50IChzb21ldGltZXMga25vd24gbG9vc2VseSBhcwotICAgICAqICdpZ25vcmFibGUgd2hpdGVzcGFjZScpIHdoZW4gcGFyc2luZyBYTUwgZG9jdW1lbnRzIChzZWUgWE1MIFJlYwotICAgICAqIDIuMTApLiBOb3RlIHRoYXQgb25seSB3aGl0ZXNwYWNlIHdoaWNoIGlzIGRpcmVjdGx5IGNvbnRhaW5lZCB3aXRoaW4KLSAgICAgKiBlbGVtZW50IGNvbnRlbnQgdGhhdCBoYXMgYW4gZWxlbWVudCBvbmx5IGNvbnRlbnQgbW9kZWwgKHNlZSBYTUwKLSAgICAgKiBSZWMgMy4yLjEpIHdpbGwgYmUgZWxpbWluYXRlZC4gRHVlIHRvIHJlbGlhbmNlIG9uIHRoZSBjb250ZW50IG1vZGVsCi0gICAgICogdGhpcyBzZXR0aW5nIHJlcXVpcmVzIHRoZSBwYXJzZXIgdG8gYmUgaW4gdmFsaWRhdGluZyBtb2RlLiBCeSBkZWZhdWx0Ci0gICAgICogdGhlIHZhbHVlIG9mIHRoaXMgaXMgc2V0IHRvIDxjb2RlPmZhbHNlPC9jb2RlPi4KLSAgICAgKgotICAgICAqIEBwYXJhbSB3aGl0ZXNwYWNlIHRydWUgaWYgdGhlIHBhcnNlciBjcmVhdGVkIG11c3QgZWxpbWluYXRlIHdoaXRlc3BhY2UKLSAgICAgKiAgICAgICAgICAgICAgICAgICBpbiB0aGUgZWxlbWVudCBjb250ZW50IHdoZW4gcGFyc2luZyBYTUwgZG9jdW1lbnRzOwotICAgICAqICAgICAgICAgICAgICAgICAgIGZhbHNlIG90aGVyd2lzZS4KLSAgICAgKi8KLQotICAgIHB1YmxpYyB2b2lkIHNldElnbm9yaW5nRWxlbWVudENvbnRlbnRXaGl0ZXNwYWNlKGJvb2xlYW4gd2hpdGVzcGFjZSkgewotICAgICAgICB0aGlzLndoaXRlc3BhY2UgPSB3aGl0ZXNwYWNlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNwZWNpZmllcyB0aGF0IHRoZSBwYXJzZXIgcHJvZHVjZWQgYnkgdGhpcyBjb2RlIHdpbGwKLSAgICAgKiBleHBhbmQgZW50aXR5IHJlZmVyZW5jZSBub2Rlcy4gQnkgZGVmYXVsdCB0aGUgdmFsdWUgb2YgdGhpcyBpcyBzZXQgdG8KLSAgICAgKiA8Y29kZT50cnVlPC9jb2RlPgotICAgICAqCi0gICAgICogQHBhcmFtIGV4cGFuZEVudGl0eVJlZiB0cnVlIGlmIHRoZSBwYXJzZXIgcHJvZHVjZWQgd2lsbCBleHBhbmQgZW50aXR5Ci0gICAgICogICAgICAgICAgICAgICAgICAgICAgICByZWZlcmVuY2Ugbm9kZXM7IGZhbHNlIG90aGVyd2lzZS4KLSAgICAgKi8KLQotICAgIHB1YmxpYyB2b2lkIHNldEV4cGFuZEVudGl0eVJlZmVyZW5jZXMoYm9vbGVhbiBleHBhbmRFbnRpdHlSZWYpIHsKLSAgICAgICAgdGhpcy5leHBhbmRFbnRpdHlSZWYgPSBleHBhbmRFbnRpdHlSZWY7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+U3BlY2lmaWVzIHRoYXQgdGhlIHBhcnNlciBwcm9kdWNlZCBieSB0aGlzIGNvZGUgd2lsbAotICAgICAqIGlnbm9yZSBjb21tZW50cy4gQnkgZGVmYXVsdCB0aGUgdmFsdWUgb2YgdGhpcyBpcyBzZXQgdG8gPGNvZGU+ZmFsc2UKLSAgICAgKiA8L2NvZGU+LjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBpZ25vcmVDb21tZW50cyA8Y29kZT5ib29sZWFuPC9jb2RlPiB2YWx1ZSB0byBpZ25vcmUgY29tbWVudHMgZHVyaW5nIHByb2Nlc3NpbmcKLSAgICAgKi8KLQotICAgIHB1YmxpYyB2b2lkIHNldElnbm9yaW5nQ29tbWVudHMoYm9vbGVhbiBpZ25vcmVDb21tZW50cykgewotICAgICAgICB0aGlzLmlnbm9yZUNvbW1lbnRzID0gaWdub3JlQ29tbWVudHM7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU3BlY2lmaWVzIHRoYXQgdGhlIHBhcnNlciBwcm9kdWNlZCBieSB0aGlzIGNvZGUgd2lsbAotICAgICAqIGNvbnZlcnQgQ0RBVEEgbm9kZXMgdG8gVGV4dCBub2RlcyBhbmQgYXBwZW5kIGl0IHRvIHRoZQotICAgICAqIGFkamFjZW50IChpZiBhbnkpIHRleHQgbm9kZS4gQnkgZGVmYXVsdCB0aGUgdmFsdWUgb2YgdGhpcyBpcyBzZXQgdG8KLSAgICAgKiA8Y29kZT5mYWxzZTwvY29kZT4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjb2FsZXNjaW5nICB0cnVlIGlmIHRoZSBwYXJzZXIgcHJvZHVjZWQgd2lsbCBjb252ZXJ0IENEQVRBIG5vZGVzCi0gICAgICogICAgICAgICAgICAgICAgICAgIHRvIFRleHQgbm9kZXMgYW5kIGFwcGVuZCBpdCB0byB0aGUgYWRqYWNlbnQgKGlmIGFueSkKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgdGV4dCBub2RlOyBmYWxzZSBvdGhlcndpc2UuCi0gICAgICovCi0KLSAgICBwdWJsaWMgdm9pZCBzZXRDb2FsZXNjaW5nKGJvb2xlYW4gY29hbGVzY2luZykgewotICAgICAgICB0aGlzLmNvYWxlc2NpbmcgPSBjb2FsZXNjaW5nOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEluZGljYXRlcyB3aGV0aGVyIG9yIG5vdCB0aGUgZmFjdG9yeSBpcyBjb25maWd1cmVkIHRvIHByb2R1Y2UKLSAgICAgKiBwYXJzZXJzIHdoaWNoIGFyZSBuYW1lc3BhY2UgYXdhcmUuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuICB0cnVlIGlmIHRoZSBmYWN0b3J5IGlzIGNvbmZpZ3VyZWQgdG8gcHJvZHVjZSBwYXJzZXJzIHdoaWNoCi0gICAgICogICAgICAgICAgYXJlIG5hbWVzcGFjZSBhd2FyZTsgZmFsc2Ugb3RoZXJ3aXNlLgotICAgICAqLwotCi0gICAgcHVibGljIGJvb2xlYW4gaXNOYW1lc3BhY2VBd2FyZSgpIHsKLSAgICAgICAgcmV0dXJuIG5hbWVzcGFjZUF3YXJlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEluZGljYXRlcyB3aGV0aGVyIG9yIG5vdCB0aGUgZmFjdG9yeSBpcyBjb25maWd1cmVkIHRvIHByb2R1Y2UKLSAgICAgKiBwYXJzZXJzIHdoaWNoIHZhbGlkYXRlIHRoZSBYTUwgY29udGVudCBkdXJpbmcgcGFyc2UuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuICB0cnVlIGlmIHRoZSBmYWN0b3J5IGlzIGNvbmZpZ3VyZWQgdG8gcHJvZHVjZSBwYXJzZXJzCi0gICAgICogICAgICAgICAgd2hpY2ggdmFsaWRhdGUgdGhlIFhNTCBjb250ZW50IGR1cmluZyBwYXJzZTsgZmFsc2Ugb3RoZXJ3aXNlLgotICAgICAqLwotCi0gICAgcHVibGljIGJvb2xlYW4gaXNWYWxpZGF0aW5nKCkgewotICAgICAgICByZXR1cm4gdmFsaWRhdGluZzsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciBvciBub3QgdGhlIGZhY3RvcnkgaXMgY29uZmlndXJlZCB0byBwcm9kdWNlCi0gICAgICogcGFyc2VycyB3aGljaCBpZ25vcmUgaWdub3JhYmxlIHdoaXRlc3BhY2UgaW4gZWxlbWVudCBjb250ZW50LgotICAgICAqCi0gICAgICogQHJldHVybiAgdHJ1ZSBpZiB0aGUgZmFjdG9yeSBpcyBjb25maWd1cmVkIHRvIHByb2R1Y2UgcGFyc2VycwotICAgICAqICAgICAgICAgIHdoaWNoIGlnbm9yZSBpZ25vcmFibGUgd2hpdGVzcGFjZSBpbiBlbGVtZW50IGNvbnRlbnQ7Ci0gICAgICogICAgICAgICAgZmFsc2Ugb3RoZXJ3aXNlLgotICAgICAqLwotCi0gICAgcHVibGljIGJvb2xlYW4gaXNJZ25vcmluZ0VsZW1lbnRDb250ZW50V2hpdGVzcGFjZSgpIHsKLSAgICAgICAgcmV0dXJuIHdoaXRlc3BhY2U7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSW5kaWNhdGVzIHdoZXRoZXIgb3Igbm90IHRoZSBmYWN0b3J5IGlzIGNvbmZpZ3VyZWQgdG8gcHJvZHVjZQotICAgICAqIHBhcnNlcnMgd2hpY2ggZXhwYW5kIGVudGl0eSByZWZlcmVuY2Ugbm9kZXMuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuICB0cnVlIGlmIHRoZSBmYWN0b3J5IGlzIGNvbmZpZ3VyZWQgdG8gcHJvZHVjZSBwYXJzZXJzCi0gICAgICogICAgICAgICAgd2hpY2ggZXhwYW5kIGVudGl0eSByZWZlcmVuY2Ugbm9kZXM7IGZhbHNlIG90aGVyd2lzZS4KLSAgICAgKi8KLQotICAgIHB1YmxpYyBib29sZWFuIGlzRXhwYW5kRW50aXR5UmVmZXJlbmNlcygpIHsKLSAgICAgICAgcmV0dXJuIGV4cGFuZEVudGl0eVJlZjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciBvciBub3QgdGhlIGZhY3RvcnkgaXMgY29uZmlndXJlZCB0byBwcm9kdWNlCi0gICAgICogcGFyc2VycyB3aGljaCBpZ25vcmVzIGNvbW1lbnRzLgotICAgICAqCi0gICAgICogQHJldHVybiAgdHJ1ZSBpZiB0aGUgZmFjdG9yeSBpcyBjb25maWd1cmVkIHRvIHByb2R1Y2UgcGFyc2VycwotICAgICAqICAgICAgICAgIHdoaWNoIGlnbm9yZXMgY29tbWVudHM7IGZhbHNlIG90aGVyd2lzZS4KLSAgICAgKi8KLQotICAgIHB1YmxpYyBib29sZWFuIGlzSWdub3JpbmdDb21tZW50cygpIHsKLSAgICAgICAgcmV0dXJuIGlnbm9yZUNvbW1lbnRzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEluZGljYXRlcyB3aGV0aGVyIG9yIG5vdCB0aGUgZmFjdG9yeSBpcyBjb25maWd1cmVkIHRvIHByb2R1Y2UKLSAgICAgKiBwYXJzZXJzIHdoaWNoIGNvbnZlcnRzIENEQVRBIG5vZGVzIHRvIFRleHQgbm9kZXMgYW5kIGFwcGVuZHMgaXQgdG8KLSAgICAgKiB0aGUgYWRqYWNlbnQgKGlmIGFueSkgVGV4dCBub2RlLgotICAgICAqCi0gICAgICogQHJldHVybiAgdHJ1ZSBpZiB0aGUgZmFjdG9yeSBpcyBjb25maWd1cmVkIHRvIHByb2R1Y2UgcGFyc2VycwotICAgICAqICAgICAgICAgIHdoaWNoIGNvbnZlcnRzIENEQVRBIG5vZGVzIHRvIFRleHQgbm9kZXMgYW5kIGFwcGVuZHMgaXQgdG8KLSAgICAgKiAgICAgICAgICB0aGUgYWRqYWNlbnQgKGlmIGFueSkgVGV4dCBub2RlOyBmYWxzZSBvdGhlcndpc2UuCi0gICAgICovCi0KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0NvYWxlc2NpbmcoKSB7Ci0gICAgICAgIHJldHVybiBjb2FsZXNjaW5nOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEFsbG93cyB0aGUgdXNlciB0byBzZXQgc3BlY2lmaWMgYXR0cmlidXRlcyBvbiB0aGUgdW5kZXJseWluZwotICAgICAqIGltcGxlbWVudGF0aW9uLgotICAgICAqIDxwPgotICAgICAqIEFsbCBpbXBsZW1lbnRhdGlvbnMgdGhhdCBpbXBsZW1lbnQgSkFYUCAxLjUgb3IgbmV3ZXIgYXJlIHJlcXVpcmVkIHRvCi0gICAgICogc3VwcG9ydCB0aGUge0BsaW5rIGphdmF4LnhtbC5YTUxDb25zdGFudHMjQUNDRVNTX0VYVEVSTkFMX0RURH0gYW5kCi0gICAgICoge0BsaW5rIGphdmF4LnhtbC5YTUxDb25zdGFudHMjQUNDRVNTX0VYVEVSTkFMX1NDSEVNQX0gcHJvcGVydGllcy4KLSAgICAgKiA8L3A+Ci0gICAgICogPHVsPgotICAgICAqICAgPGxpPgotICAgICAqICAgICAgPHA+Ci0gICAgICogICAgICBTZXR0aW5nIHRoZSB7QGxpbmsgamF2YXgueG1sLlhNTENvbnN0YW50cyNBQ0NFU1NfRVhURVJOQUxfRFREfSBwcm9wZXJ0eQotICAgICAqICAgICAgcmVzdHJpY3RzIHRoZSBhY2Nlc3MgdG8gZXh0ZXJuYWwgRFREcywgZXh0ZXJuYWwgRW50aXR5IFJlZmVyZW5jZXMgdG8gdGhlCi0gICAgICogICAgICBwcm90b2NvbHMgc3BlY2lmaWVkIGJ5IHRoZSBwcm9wZXJ0eS4KLSAgICAgKiAgICAgIElmIGFjY2VzcyBpcyBkZW5pZWQgZHVyaW5nIHBhcnNpbmcgZHVlIHRvIHRoZSByZXN0cmljdGlvbiBvZiB0aGlzIHByb3BlcnR5LAotICAgICAqICAgICAge0BsaW5rIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbn0gd2lsbCBiZSB0aHJvd24gYnkgdGhlIHBhcnNlIG1ldGhvZHMgZGVmaW5lZCBieQotICAgICAqICAgICAge0BsaW5rIGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlcn0uCi0gICAgICogICAgICA8L3A+Ci0gICAgICogICAgICA8cD4KLSAgICAgKiAgICAgIFNldHRpbmcgdGhlIHtAbGluayBqYXZheC54bWwuWE1MQ29uc3RhbnRzI0FDQ0VTU19FWFRFUk5BTF9TQ0hFTUF9IHByb3BlcnR5Ci0gICAgICogICAgICByZXN0cmljdHMgdGhlIGFjY2VzcyB0byBleHRlcm5hbCBTY2hlbWEgc2V0IGJ5IHRoZSBzY2hlbWFMb2NhdGlvbiBhdHRyaWJ1dGUgdG8KLSAgICAgKiAgICAgIHRoZSBwcm90b2NvbHMgc3BlY2lmaWVkIGJ5IHRoZSBwcm9wZXJ0eS4gIElmIGFjY2VzcyBpcyBkZW5pZWQgZHVyaW5nIHBhcnNpbmcKLSAgICAgKiAgICAgIGR1ZSB0byB0aGUgcmVzdHJpY3Rpb24gb2YgdGhpcyBwcm9wZXJ0eSwge0BsaW5rIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbn0KLSAgICAgKiAgICAgIHdpbGwgYmUgdGhyb3duIGJ5IHRoZSBwYXJzZSBtZXRob2RzIGRlZmluZWQgYnkKLSAgICAgKiAgICAgIHtAbGluayBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXJ9LgotICAgICAqICAgICAgPC9wPgotICAgICAqICAgPC9saT4KLSAgICAgKiA8L3VsPgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB0aHJvd24gaWYgdGhlIHVuZGVybHlpbmcKLSAgICAgKiAgIGltcGxlbWVudGF0aW9uIGRvZXNuJ3QgcmVjb2duaXplIHRoZSBhdHRyaWJ1dGUuCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2V0QXR0cmlidXRlKFN0cmluZyBuYW1lLCBPYmplY3QgdmFsdWUpCi0gICAgICAgICAgICAgICAgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIEFsbG93cyB0aGUgdXNlciB0byByZXRyaWV2ZSBzcGVjaWZpYyBhdHRyaWJ1dGVzIG9uIHRoZSB1bmRlcmx5aW5nCi0gICAgICogaW1wbGVtZW50YXRpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlLgotICAgICAqCi0gICAgICogQHJldHVybiB2YWx1ZSBUaGUgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHRocm93biBpZiB0aGUgdW5kZXJseWluZwotICAgICAqICAgaW1wbGVtZW50YXRpb24gZG9lc24ndCByZWNvZ25pemUgdGhlIGF0dHJpYnV0ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3QgT2JqZWN0IGdldEF0dHJpYnV0ZShTdHJpbmcgbmFtZSkKLSAgICAgICAgICAgICAgICB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogPHA+U2V0IGEgZmVhdHVyZSBmb3IgdGhpcyA8Y29kZT5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5PC9jb2RlPiBhbmQgPGNvZGU+RG9jdW1lbnRCdWlsZGVyPC9jb2RlPnMgY3JlYXRlZCBieSB0aGlzIGZhY3RvcnkuPC9wPgotICAgICAqCi0gICAgICogPHA+Ci0gICAgICogRmVhdHVyZSBuYW1lcyBhcmUgZnVsbHkgcXVhbGlmaWVkIHtAbGluayBqYXZhLm5ldC5VUkl9cy4KLSAgICAgKiBJbXBsZW1lbnRhdGlvbnMgbWF5IGRlZmluZSB0aGVpciBvd24gZmVhdHVyZXMuCi0gICAgICogQSB7QGxpbmsgUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbn0gaXMgdGhyb3duIGlmIHRoaXMgPGNvZGU+RG9jdW1lbnRCdWlsZGVyRmFjdG9yeTwvY29kZT4gb3IgdGhlCi0gICAgICogPGNvZGU+RG9jdW1lbnRCdWlsZGVyPC9jb2RlPnMgaXQgY3JlYXRlcyBjYW5ub3Qgc3VwcG9ydCB0aGUgZmVhdHVyZS4KLSAgICAgKiBJdCBpcyBwb3NzaWJsZSBmb3IgYSA8Y29kZT5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5PC9jb2RlPiB0byBleHBvc2UgYSBmZWF0dXJlIHZhbHVlIGJ1dCBiZSB1bmFibGUgdG8gY2hhbmdlIGl0cyBzdGF0ZS4KLSAgICAgKiA8L3A+Ci0gICAgICoKLSAgICAgKiA8cD4KLSAgICAgKiBBbGwgaW1wbGVtZW50YXRpb25zIGFyZSByZXF1aXJlZCB0byBzdXBwb3J0IHRoZSB7QGxpbmsgamF2YXgueG1sLlhNTENvbnN0YW50cyNGRUFUVVJFX1NFQ1VSRV9QUk9DRVNTSU5HfSBmZWF0dXJlLgotICAgICAqIFdoZW4gdGhlIGZlYXR1cmUgaXM6PC9wPgotICAgICAqIDx1bD4KLSAgICAgKiAgIDxsaT4KLSAgICAgKiAgICAgPGNvZGU+dHJ1ZTwvY29kZT46IHRoZSBpbXBsZW1lbnRhdGlvbiB3aWxsIGxpbWl0IFhNTCBwcm9jZXNzaW5nIHRvIGNvbmZvcm0gdG8gaW1wbGVtZW50YXRpb24gbGltaXRzLgotICAgICAqICAgICBFeGFtcGxlcyBpbmNsdWRlIGVuaXR5IGV4cGFuc2lvbiBsaW1pdHMgYW5kIFhNTCBTY2hlbWEgY29uc3RydWN0cyB0aGF0IHdvdWxkIGNvbnN1bWUgbGFyZ2UgYW1vdW50cyBvZiByZXNvdXJjZXMuCi0gICAgICogICAgIElmIFhNTCBwcm9jZXNzaW5nIGlzIGxpbWl0ZWQgZm9yIHNlY3VyaXR5IHJlYXNvbnMsIGl0IHdpbGwgYmUgcmVwb3J0ZWQgdmlhIGEgY2FsbCB0byB0aGUgcmVnaXN0ZXJlZAotICAgICAqICAgIHtAbGluayBvcmcueG1sLnNheC5FcnJvckhhbmRsZXIjZmF0YWxFcnJvcihTQVhQYXJzZUV4Y2VwdGlvbiBleGNlcHRpb24pfS4KLSAgICAgKiAgICAgU2VlIHtAbGluayAgRG9jdW1lbnRCdWlsZGVyI3NldEVycm9ySGFuZGxlcihvcmcueG1sLnNheC5FcnJvckhhbmRsZXIgZXJyb3JIYW5kbGVyKX0uCi0gICAgICogICA8L2xpPgotICAgICAqICAgPGxpPgotICAgICAqICAgICA8Y29kZT5mYWxzZTwvY29kZT46IHRoZSBpbXBsZW1lbnRhdGlvbiB3aWxsIHByb2Nlc3NpbmcgWE1MIGFjY29yZGluZyB0byB0aGUgWE1MIHNwZWNpZmljYXRpb25zIHdpdGhvdXQKLSAgICAgKiAgICAgcmVnYXJkIHRvIHBvc3NpYmxlIGltcGxlbWVudGF0aW9uIGxpbWl0cy4KLSAgICAgKiAgIDwvbGk+Ci0gICAgICogPC91bD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lIEZlYXR1cmUgbmFtZS4KLSAgICAgKiBAcGFyYW0gdmFsdWUgSXMgZmVhdHVyZSBzdGF0ZSA8Y29kZT50cnVlPC9jb2RlPiBvciA8Y29kZT5mYWxzZTwvY29kZT4uCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gaWYgdGhpcyA8Y29kZT5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5PC9jb2RlPiBvciB0aGUgPGNvZGU+RG9jdW1lbnRCdWlsZGVyPC9jb2RlPnMKLSAgICAgKiAgIGl0IGNyZWF0ZXMgY2Fubm90IHN1cHBvcnQgdGhpcyBmZWF0dXJlLgotICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gSWYgdGhlIDxjb2RlPm5hbWU8L2NvZGU+IHBhcmFtZXRlciBpcyBudWxsLgotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHNldEZlYXR1cmUoU3RyaW5nIG5hbWUsIGJvb2xlYW4gdmFsdWUpCi0gICAgICAgICAgICB0aHJvd3MgUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIDxwPkdldCB0aGUgc3RhdGUgb2YgdGhlIG5hbWVkIGZlYXR1cmUuPC9wPgotICAgICAqCi0gICAgICogPHA+Ci0gICAgICogRmVhdHVyZSBuYW1lcyBhcmUgZnVsbHkgcXVhbGlmaWVkIHtAbGluayBqYXZhLm5ldC5VUkl9cy4KLSAgICAgKiBJbXBsZW1lbnRhdGlvbnMgbWF5IGRlZmluZSB0aGVpciBvd24gZmVhdHVyZXMuCi0gICAgICogQW4ge0BsaW5rIFBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb259IGlzIHRocm93biBpZiB0aGlzIDxjb2RlPkRvY3VtZW50QnVpbGRlckZhY3Rvcnk8L2NvZGU+IG9yIHRoZQotICAgICAqIDxjb2RlPkRvY3VtZW50QnVpbGRlcjwvY29kZT5zIGl0IGNyZWF0ZXMgY2Fubm90IHN1cHBvcnQgdGhlIGZlYXR1cmUuCi0gICAgICogSXQgaXMgcG9zc2libGUgZm9yIGFuIDxjb2RlPkRvY3VtZW50QnVpbGRlckZhY3Rvcnk8L2NvZGU+IHRvIGV4cG9zZSBhIGZlYXR1cmUgdmFsdWUgYnV0IGJlIHVuYWJsZSB0byBjaGFuZ2UgaXRzIHN0YXRlLgotICAgICAqIDwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lIEZlYXR1cmUgbmFtZS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gU3RhdGUgb2YgdGhlIG5hbWVkIGZlYXR1cmUuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gaWYgdGhpcyA8Y29kZT5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5PC9jb2RlPgotICAgICAqICAgb3IgdGhlIDxjb2RlPkRvY3VtZW50QnVpbGRlcjwvY29kZT5zIGl0IGNyZWF0ZXMgY2Fubm90IHN1cHBvcnQgdGhpcyBmZWF0dXJlLgotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGdldEZlYXR1cmUoU3RyaW5nIG5hbWUpCi0gICAgICAgICAgICB0aHJvd3MgUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKLQotCi0gICAgLyoqCi0gICAgICogR2V0cyB0aGUge0BsaW5rIFNjaGVtYX0gb2JqZWN0IHNwZWNpZmllZCB0aHJvdWdoCi0gICAgICogdGhlIHtAbGluayAjc2V0U2NoZW1hKFNjaGVtYSBzY2hlbWEpfSBtZXRob2QuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuCi0gICAgICogICAgICB0aGUge0BsaW5rIFNjaGVtYX0gb2JqZWN0IHRoYXQgd2FzIGxhc3Qgc2V0IHRocm91Z2gKLSAgICAgKiAgICAgIHRoZSB7QGxpbmsgI3NldFNjaGVtYShTY2hlbWEpfSBtZXRob2QsIG9yIG51bGwKLSAgICAgKiAgICAgIGlmIHRoZSBtZXRob2Qgd2FzIG5vdCBpbnZva2VkIHNpbmNlIGEge0BsaW5rIERvY3VtZW50QnVpbGRlckZhY3Rvcnl9Ci0gICAgICogICAgICBpcyBjcmVhdGVkLgotICAgICAqCi0gICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBXaGVuIGltcGxlbWVudGF0aW9uIGRvZXMgbm90Ci0gICAgICogICBvdmVycmlkZSB0aGlzIG1ldGhvZC4KLSAgICAgKgotICAgICAqIEBzaW5jZSAxLjUKLSAgICAgKi8KLSAgICBwdWJsaWMgU2NoZW1hIGdldFNjaGVtYSgpIHsKLSAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKAotICAgICAgICAgICAgIlRoaXMgcGFyc2VyIGRvZXMgbm90IHN1cHBvcnQgc3BlY2lmaWNhdGlvbiBcIiIKLSAgICAgICAgICAgICsgdGhpcy5nZXRDbGFzcygpLmdldFBhY2thZ2UoKS5nZXRTcGVjaWZpY2F0aW9uVGl0bGUoKQotICAgICAgICAgICAgKyAiXCIgdmVyc2lvbiBcIiIKLSAgICAgICAgICAgICsgdGhpcy5nZXRDbGFzcygpLmdldFBhY2thZ2UoKS5nZXRTcGVjaWZpY2F0aW9uVmVyc2lvbigpCi0gICAgICAgICAgICArICJcIiIKLSAgICAgICAgICAgICk7Ci0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5TZXQgdGhlIHtAbGluayBTY2hlbWF9IHRvIGJlIHVzZWQgYnkgcGFyc2VycyBjcmVhdGVkCi0gICAgICogZnJvbSB0aGlzIGZhY3RvcnkuCi0gICAgICoKLSAgICAgKiA8cD4KLSAgICAgKiBXaGVuIGEge0BsaW5rIFNjaGVtYX0gaXMgbm9uLW51bGwsIGEgcGFyc2VyIHdpbGwgdXNlIGEgdmFsaWRhdG9yCi0gICAgICogY3JlYXRlZCBmcm9tIGl0IHRvIHZhbGlkYXRlIGRvY3VtZW50cyBiZWZvcmUgaXQgcGFzc2VzIGluZm9ybWF0aW9uCi0gICAgICogZG93biB0byB0aGUgYXBwbGljYXRpb24uCi0gICAgICoKLSAgICAgKiA8cD5XaGVuIGVycm9ycyBhcmUgZm91bmQgYnkgdGhlIHZhbGlkYXRvciwgdGhlIHBhcnNlciBpcyByZXNwb25zaWJsZQotICAgICAqIHRvIHJlcG9ydCB0aGVtIHRvIHRoZSB1c2VyLXNwZWNpZmllZCB7QGxpbmsgb3JnLnhtbC5zYXguRXJyb3JIYW5kbGVyfQotICAgICAqIChvciBpZiB0aGUgZXJyb3IgaGFuZGxlciBpcyBub3Qgc2V0LCBpZ25vcmUgdGhlbSBvciB0aHJvdyB0aGVtKSwganVzdAotICAgICAqIGxpa2UgYW55IG90aGVyIGVycm9ycyBmb3VuZCBieSB0aGUgcGFyc2VyIGl0c2VsZi4KLSAgICAgKiBJbiBvdGhlciB3b3JkcywgaWYgdGhlIHVzZXItc3BlY2lmaWVkIHtAbGluayBvcmcueG1sLnNheC5FcnJvckhhbmRsZXJ9Ci0gICAgICogaXMgc2V0LCBpdCBtdXN0IHJlY2VpdmUgdGhvc2UgZXJyb3JzLCBhbmQgaWYgbm90LCB0aGV5IG11c3QgYmUKLSAgICAgKiB0cmVhdGVkIGFjY29yZGluZyB0byB0aGUgaW1wbGVtZW50YXRpb24gc3BlY2lmaWMKLSAgICAgKiBkZWZhdWx0IGVycm9yIGhhbmRsaW5nIHJ1bGVzLgotICAgICAqCi0gICAgICogPHA+Ci0gICAgICogQSB2YWxpZGF0b3IgbWF5IG1vZGlmeSB0aGUgb3V0Y29tZSBvZiBhIHBhcnNlIChmb3IgZXhhbXBsZSBieQotICAgICAqIGFkZGluZyBkZWZhdWx0IHZhbHVlcyB0aGF0IHdlcmUgbWlzc2luZyBpbiBkb2N1bWVudHMpLCBhbmQgYSBwYXJzZXIKLSAgICAgKiBpcyByZXNwb25zaWJsZSB0byBtYWtlIHN1cmUgdGhhdCB0aGUgYXBwbGljYXRpb24gd2lsbCByZWNlaXZlCi0gICAgICogbW9kaWZpZWQgRE9NIHRyZWVzLgotICAgICAqCi0gICAgICogPHA+Ci0gICAgICogSW5pdGlhbHksIG51bGwgaXMgc2V0IGFzIHRoZSB7QGxpbmsgU2NoZW1hfS4KLSAgICAgKgotICAgICAqIDxwPgotICAgICAqIFRoaXMgcHJvY2Vzc2luZyB3aWxsIHRha2UgZWZmZWN0IGV2ZW4gaWYKLSAgICAgKiB0aGUge0BsaW5rICNpc1ZhbGlkYXRpbmcoKX0gbWV0aG9kIHJldHVybnMgPGNvZGU+ZmFsc2U8L2NvZGU+LgotICAgICAqCi0gICAgICogPHA+SXQgaXMgYW4gZXJyb3IgdG8gdXNlCi0gICAgICogdGhlIDxjb2RlPmh0dHA6Ly9qYXZhLnN1bi5jb20veG1sL2pheHAvcHJvcGVydGllcy9zY2hlbWFTb3VyY2U8L2NvZGU+Ci0gICAgICogcHJvcGVydHkgYW5kL29yIHRoZSA8Y29kZT5odHRwOi8vamF2YS5zdW4uY29tL3htbC9qYXhwL3Byb3BlcnRpZXMvc2NoZW1hTGFuZ3VhZ2U8L2NvZGU+Ci0gICAgICogcHJvcGVydHkgaW4gY29uanVuY3Rpb24gd2l0aCBhIHtAbGluayBTY2hlbWF9IG9iamVjdC4KLSAgICAgKiBTdWNoIGNvbmZpZ3VyYXRpb24gd2lsbCBjYXVzZSBhIHtAbGluayBQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9ufQotICAgICAqIGV4Y2VwdGlvbiB3aGVuIHRoZSB7QGxpbmsgI25ld0RvY3VtZW50QnVpbGRlcigpfSBpcyBpbnZva2VkLjwvcD4KLSAgICAgKgotICAgICAqCi0gICAgICogPGg0Pk5vdGUgZm9yIGltcGxtZW50b3JzPC9oND4KLSAgICAgKgotICAgICAqIDxwPgotICAgICAqIEEgcGFyc2VyIG11c3QgYmUgYWJsZSB0byB3b3JrIHdpdGggYW55IHtAbGluayBTY2hlbWF9Ci0gICAgICogaW1wbGVtZW50YXRpb24uIEhvd2V2ZXIsIHBhcnNlcnMgYW5kIHNjaGVtYXMgYXJlIGFsbG93ZWQKLSAgICAgKiB0byB1c2UgaW1wbGVtZW50YXRpb24tc3BlY2lmaWMgY3VzdG9tIG1lY2hhbmlzbXMKLSAgICAgKiBhcyBsb25nIGFzIHRoZXkgeWllbGQgdGhlIHJlc3VsdCBkZXNjcmliZWQgaW4gdGhlIHNwZWNpZmljYXRpb24uCi0gICAgICogPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIHNjaGVtYSA8Y29kZT5TY2hlbWE8L2NvZGU+IHRvIHVzZSBvciA8Y29kZT5udWxsPC9jb2RlPgotICAgICAqICAgdG8gcmVtb3ZlIGEgc2NoZW1hLgotICAgICAqCi0gICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBXaGVuIGltcGxlbWVudGF0aW9uIGRvZXMgbm90Ci0gICAgICogICBvdmVycmlkZSB0aGlzIG1ldGhvZC4KLSAgICAgKgotICAgICAqIEBzaW5jZSAxLjUKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRTY2hlbWEoU2NoZW1hIHNjaGVtYSkgewotICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oCi0gICAgICAgICAgICAiVGhpcyBwYXJzZXIgZG9lcyBub3Qgc3VwcG9ydCBzcGVjaWZpY2F0aW9uIFwiIgotICAgICAgICAgICAgKyB0aGlzLmdldENsYXNzKCkuZ2V0UGFja2FnZSgpLmdldFNwZWNpZmljYXRpb25UaXRsZSgpCi0gICAgICAgICAgICArICJcIiB2ZXJzaW9uIFwiIgotICAgICAgICAgICAgKyB0aGlzLmdldENsYXNzKCkuZ2V0UGFja2FnZSgpLmdldFNwZWNpZmljYXRpb25WZXJzaW9uKCkKLSAgICAgICAgICAgICsgIlwiIgotICAgICAgICAgICAgKTsKLSAgICB9Ci0KLQotCi0gICAgLyoqCi0gICAgICogPHA+U2V0IHN0YXRlIG9mIFhJbmNsdWRlIHByb2Nlc3NpbmcuPC9wPgotICAgICAqCi0gICAgICogPHA+SWYgWEluY2x1ZGUgbWFya3VwIGlzIGZvdW5kIGluIHRoZSBkb2N1bWVudCBpbnN0YW5jZSwgc2hvdWxkIGl0IGJlCi0gICAgICogcHJvY2Vzc2VkIGFzIHNwZWNpZmllZCBpbiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94aW5jbHVkZS8iPgotICAgICAqIFhNTCBJbmNsdXNpb25zIChYSW5jbHVkZSkgVmVyc2lvbiAxLjA8L2E+LjwvcD4KLSAgICAgKgotICAgICAqIDxwPlhJbmNsdWRlIHByb2Nlc3NpbmcgZGVmYXVsdHMgdG8gPGNvZGU+ZmFsc2U8L2NvZGU+LjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzdGF0ZSBTZXQgWEluY2x1ZGUgcHJvY2Vzc2luZyB0byA8Y29kZT50cnVlPC9jb2RlPiBvcgotICAgICAqICAgPGNvZGU+ZmFsc2U8L2NvZGU+Ci0gICAgICoKLSAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIFdoZW4gaW1wbGVtZW50YXRpb24gZG9lcyBub3QKLSAgICAgKiAgIG92ZXJyaWRlIHRoaXMgbWV0aG9kLgotICAgICAqCi0gICAgICogQHNpbmNlIDEuNQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFhJbmNsdWRlQXdhcmUoZmluYWwgYm9vbGVhbiBzdGF0ZSkgewotICAgICAgICBpZiAoc3RhdGUpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiIHNldFhJbmNsdWRlQXdhcmUgIiArCi0gICAgICAgICAgICAgICAgImlzIG5vdCBzdXBwb3J0ZWQgb24gdGhpcyBKQVhQIiArCi0gICAgICAgICAgICAgICAgIiBpbXBsZW1lbnRhdGlvbiBvciBlYXJsaWVyOiAiICsgdGhpcy5nZXRDbGFzcygpKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPkdldCBzdGF0ZSBvZiBYSW5jbHVkZSBwcm9jZXNzaW5nLjwvcD4KLSAgICAgKgotICAgICAqIEByZXR1cm4gY3VycmVudCBzdGF0ZSBvZiBYSW5jbHVkZSBwcm9jZXNzaW5nCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIFdoZW4gaW1wbGVtZW50YXRpb24gZG9lcyBub3QKLSAgICAgKiAgIG92ZXJyaWRlIHRoaXMgbWV0aG9kLgotICAgICAqCi0gICAgICogQHNpbmNlIDEuNQotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzWEluY2x1ZGVBd2FyZSgpIHsKLSAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKAotICAgICAgICAgICAgIlRoaXMgcGFyc2VyIGRvZXMgbm90IHN1cHBvcnQgc3BlY2lmaWNhdGlvbiBcIiIKLSAgICAgICAgICAgICsgdGhpcy5nZXRDbGFzcygpLmdldFBhY2thZ2UoKS5nZXRTcGVjaWZpY2F0aW9uVGl0bGUoKQotICAgICAgICAgICAgKyAiXCIgdmVyc2lvbiBcIiIKLSAgICAgICAgICAgICsgdGhpcy5nZXRDbGFzcygpLmdldFBhY2thZ2UoKS5nZXRTcGVjaWZpY2F0aW9uVmVyc2lvbigpCi0gICAgICAgICAgICArICJcIiIKLSAgICAgICAgICAgICk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmF4L3htbC9wYXJzZXJzL0ZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IuamF2YSBiL3NyYy9qYXZheC94bWwvcGFyc2Vycy9GYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGM3MGU0YWUuLjAwMDAwMDAKLS0tIGEvc3JjL2phdmF4L3htbC9wYXJzZXJzL0ZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEzNSArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDAwLCAyMDA1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi1wYWNrYWdlIGphdmF4LnhtbC5wYXJzZXJzOwotCi0vKioKLSAqIFRocm93biB3aGVuIGEgcHJvYmxlbSB3aXRoIGNvbmZpZ3VyYXRpb24gd2l0aCB0aGUgUGFyc2VyIEZhY3RvcmllcwotICogZXhpc3RzLiBUaGlzIGVycm9yIHdpbGwgdHlwaWNhbGx5IGJlIHRocm93biB3aGVuIHRoZSBjbGFzcyBvZiBhCi0gKiBwYXJzZXIgZmFjdG9yeSBzcGVjaWZpZWQgaW4gdGhlIHN5c3RlbSBwcm9wZXJ0aWVzIGNhbm5vdCBiZSBmb3VuZAotICogb3IgaW5zdGFudGlhdGVkLgotICoKLSAqIEBhdXRob3IgPGEgaHJlZj0ibWFpbHRvOkplZmYuU3V0dG9yQFN1bi5jb20iPkplZmYgU3V0dG9yPC9hPgotICogQHZlcnNpb24gJFJldmlzaW9uOiAxLjcgJCwgJERhdGU6IDIwMTAtMTEtMDEgMDQ6MzY6MDkgJAotICovCi0KLXB1YmxpYyBjbGFzcyBGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yIGV4dGVuZHMgRXJyb3IgewotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC04MjcxMDg2ODI0NzIyNjMzNTVMOwotCi0gICAgLyoqCi0gICAgICo8Y29kZT5FeGNlcHRpb248L2NvZGU+IHRoYXQgcmVwcmVzZW50cyB0aGUgZXJyb3IuCi0gICAgICovCi0gICAgcHJpdmF0ZSBFeGNlcHRpb24gZXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlIGEgbmV3IDxjb2RlPkZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3I8L2NvZGU+IHdpdGggbm8KLSAgICAgKiBkZXRhaWwgbWVzYWdlLgotICAgICAqLwotCi0gICAgcHVibGljIEZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IoKSB7Ci0gICAgICAgIHN1cGVyKCk7Ci0gICAgICAgIHRoaXMuZXhjZXB0aW9uID0gbnVsbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGUgYSBuZXcgPGNvZGU+RmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvcjwvY29kZT4gd2l0aAotICAgICAqIHRoZSA8Y29kZT5TdHJpbmcgPC9jb2RlPiBzcGVjaWZpZWQgYXMgYW4gZXJyb3IgbWVzc2FnZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBtc2cgVGhlIGVycm9yIG1lc3NhZ2UgZm9yIHRoZSBleGNlcHRpb24uCi0gICAgICovCi0KLSAgICBwdWJsaWMgRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvcihTdHJpbmcgbXNnKSB7Ci0gICAgICAgIHN1cGVyKG1zZyk7Ci0gICAgICAgIHRoaXMuZXhjZXB0aW9uID0gbnVsbDsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIENyZWF0ZSBhIG5ldyA8Y29kZT5GYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yPC9jb2RlPiB3aXRoIGEKLSAgICAgKiBnaXZlbiA8Y29kZT5FeGNlcHRpb248L2NvZGU+IGJhc2UgY2F1c2Ugb2YgdGhlIGVycm9yLgotICAgICAqCi0gICAgICogQHBhcmFtIGUgVGhlIGV4Y2VwdGlvbiB0byBiZSBlbmNhcHN1bGF0ZWQgaW4gYQotICAgICAqIEZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IuCi0gICAgICovCi0KLSAgICBwdWJsaWMgRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvcihFeGNlcHRpb24gZSkgewotICAgICAgICBzdXBlcihlLnRvU3RyaW5nKCkpOwotICAgICAgICB0aGlzLmV4Y2VwdGlvbiA9IGU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlIGEgbmV3IDxjb2RlPkZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3I8L2NvZGU+IHdpdGggdGhlCi0gICAgICogZ2l2ZW4gPGNvZGU+RXhjZXB0aW9uPC9jb2RlPiBiYXNlIGNhdXNlIGFuZCBkZXRhaWwgbWVzc2FnZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlIFRoZSBleGNlcHRpb24gdG8gYmUgZW5jYXBzdWxhdGVkIGluIGEKLSAgICAgKiBGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yCi0gICAgICogQHBhcmFtIG1zZyBUaGUgZGV0YWlsIG1lc3NhZ2UuCi0gICAgICovCi0KLSAgICBwdWJsaWMgRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvcihFeGNlcHRpb24gZSwgU3RyaW5nIG1zZykgewotICAgICAgICBzdXBlcihtc2cpOwotICAgICAgICB0aGlzLmV4Y2VwdGlvbiA9IGU7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIG1lc3NhZ2UgKGlmIGFueSkgZm9yIHRoaXMgZXJyb3IgLiBJZiB0aGVyZSBpcyBubwotICAgICAqIG1lc3NhZ2UgZm9yIHRoZSBleGNlcHRpb24gYW5kIHRoZXJlIGlzIGFuIGVuY2Fwc3VsYXRlZAotICAgICAqIGV4Y2VwdGlvbiB0aGVuIHRoZSBtZXNzYWdlIG9mIHRoYXQgZXhjZXB0aW9uLCBpZiBpdCBleGlzdHMgd2lsbCBiZQotICAgICAqIHJldHVybmVkLiBFbHNlIHRoZSBuYW1lIG9mIHRoZSBlbmNhcHN1bGF0ZWQgZXhjZXB0aW9uIHdpbGwgYmUKLSAgICAgKiByZXR1cm5lZC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIGVycm9yIG1lc3NhZ2UuCi0gICAgICovCi0KLSAgICBwdWJsaWMgU3RyaW5nIGdldE1lc3NhZ2UgKCkgewotICAgICAgICBTdHJpbmcgbWVzc2FnZSA9IHN1cGVyLmdldE1lc3NhZ2UgKCk7Ci0KLSAgICAgICAgaWYgKG1lc3NhZ2UgPT0gbnVsbCAmJiBleGNlcHRpb24gIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIGV4Y2VwdGlvbi5nZXRNZXNzYWdlKCk7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gbWVzc2FnZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIGFjdHVhbCBleGNlcHRpb24gKGlmIGFueSkgdGhhdCBjYXVzZWQgdGhpcyBleGNlcHRpb24gdG8KLSAgICAgKiBiZSByYWlzZWQuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBlbmNhcHN1bGF0ZWQgZXhjZXB0aW9uLCBvciBudWxsIGlmIHRoZXJlIGlzIG5vbmUuCi0gICAgICovCi0KLSAgICBwdWJsaWMgRXhjZXB0aW9uIGdldEV4Y2VwdGlvbiAoKSB7Ci0gICAgICAgIHJldHVybiBleGNlcHRpb247Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogdXNlIHRoZSBleGNlcHRpb24gY2hhaW5pbmcgbWVjaGFuaXNtIG9mIEpESzEuNAotICAgICovCi0gICAgQE92ZXJyaWRlCi0gICAgcHVibGljIFRocm93YWJsZSBnZXRDYXVzZSgpIHsKLSAgICAgICAgcmV0dXJuIGV4Y2VwdGlvbjsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvamF2YXgveG1sL3BhcnNlcnMvRmFjdG9yeUZpbmRlci5qYXZhIGIvc3JjL2phdmF4L3htbC9wYXJzZXJzL0ZhY3RvcnlGaW5kZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOWUxODZmNS4uMDAwMDAwMAotLS0gYS9zcmMvamF2YXgveG1sL3BhcnNlcnMvRmFjdG9yeUZpbmRlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzE2ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDMsIDIwMTMsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLXBhY2thZ2UgamF2YXgueG1sLnBhcnNlcnM7Ci0KLWltcG9ydCBqYXZhLmlvLkZpbGU7Ci1pbXBvcnQgamF2YS5zZWN1cml0eS5BY2Nlc3NDb250cm9sbGVyOwotaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpdmlsZWdlZEFjdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7Ci1pbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7Ci1pbXBvcnQgamF2YS51dGlsLlNlcnZpY2VDb25maWd1cmF0aW9uRXJyb3I7Ci1pbXBvcnQgamF2YS51dGlsLlNlcnZpY2VMb2FkZXI7Ci0KLS8qKgotICogPHA+SW1wbGVtZW50cyBwbHVnZ2FibGUgUGFyc2Vycy48L3A+Ci0gKgotICogPHA+VGhpcyBjbGFzcyBpcyBkdXBsaWNhdGVkIGZvciBlYWNoIEpBWFAgc3VicGFja2FnZSBzbyBrZWVwIGl0IGluCi0gKiBzeW5jLiAgSXQgaXMgcGFja2FnZSBwcml2YXRlIGZvciBzZWN1cmUgY2xhc3MgbG9hZGluZy48L3A+Ci0gKgotICogQGF1dGhvciBTYW50aWFnby5QZXJpY2FzR2VlcnRzZW5Ac3VuLmNvbQotICogQGF1dGhvciBIdWl6aGUuV2FuZ0BvcmFjbGUuY29tCi0gKi8KLWNsYXNzIEZhY3RvcnlGaW5kZXIgewotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBERUZBVUxUX1BBQ0tBR0UgPSAiY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbCI7Ci0gICAgLyoqCi0gICAgICogSW50ZXJuYWwgZGVidWcgZmxhZy4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGRlYnVnID0gZmFsc2U7Ci0KLSAgICAvKioKLSAgICAgKiBDYWNoZSBmb3IgcHJvcGVydGllcyBpbiBqYXZhLmhvbWUvbGliL2pheHAucHJvcGVydGllcwotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFByb3BlcnRpZXMgY2FjaGVQcm9wcyA9IG5ldyBQcm9wZXJ0aWVzKCk7Ci0KLSAgICAvKioKLSAgICAgKiBGbGFnIGluZGljYXRpbmcgaWYgcHJvcGVydGllcyBmcm9tIGphdmEuaG9tZS9saWIvamF4cC5wcm9wZXJ0aWVzCi0gICAgICogaGF2ZSBiZWVuIGNhY2hlZC4KLSAgICAgKi8KLSAgICBzdGF0aWMgdm9sYXRpbGUgYm9vbGVhbiBmaXJzdFRpbWUgPSB0cnVlOwotCi0gICAgLyoqCi0gICAgICogU2VjdXJpdHkgc3VwcG9ydCBjbGFzcyB1c2UgdG8gY2hlY2sgYWNjZXNzIGNvbnRyb2wgYmVmb3JlCi0gICAgICogZ2V0dGluZyBjZXJ0YWluIHN5c3RlbSByZXNvdXJjZXMuCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU2VjdXJpdHlTdXBwb3J0IHNzID0gbmV3IFNlY3VyaXR5U3VwcG9ydCgpOwotCi0gICAgLy8gRGVmaW5lIHN5c3RlbSBwcm9wZXJ0eSAiamF4cC5kZWJ1ZyIgdG8gZ2V0IG91dHB1dAotICAgIHN0YXRpYyB7Ci0gICAgICAgIC8vIFVzZSB0cnkvY2F0Y2ggYmxvY2sgdG8gc3VwcG9ydCBhcHBsZXRzLCB3aGljaCB0aHJvd3MKLSAgICAgICAgLy8gU2VjdXJpdHlFeGNlcHRpb24gb3V0IG9mIHRoaXMgY29kZS4KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIFN0cmluZyB2YWwgPSBzcy5nZXRTeXN0ZW1Qcm9wZXJ0eSgiamF4cC5kZWJ1ZyIpOwotICAgICAgICAgICAgLy8gQWxsb3cgc2ltcGx5IHNldHRpbmcgdGhlIHByb3AgdG8gdHVybiBvbiBkZWJ1ZwotICAgICAgICAgICAgZGVidWcgPSB2YWwgIT0gbnVsbCAmJiAhImZhbHNlIi5lcXVhbHModmFsKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gc2UpIHsKLSAgICAgICAgICAgIGRlYnVnID0gZmFsc2U7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGRQcmludChTdHJpbmcgbXNnKSB7Ci0gICAgICAgIGlmIChkZWJ1ZykgewotICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJKQVhQOiAiICsgbXNnKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEF0dGVtcHQgdG8gbG9hZCBhIGNsYXNzIHVzaW5nIHRoZSBjbGFzcyBsb2FkZXIgc3VwcGxpZWQuIElmIHRoYXQgZmFpbHMKLSAgICAgKiBhbmQgZmFsbCBiYWNrIGlzIGVuYWJsZWQsIHRoZSBjdXJyZW50IChpLmUuIGJvb3RzdHJhcCkgY2xhc3MgbG9hZGVyIGlzCi0gICAgICogdHJpZWQuCi0gICAgICoKLSAgICAgKiBJZiB0aGUgY2xhc3MgbG9hZGVyIHN1cHBsaWVkIGlzIDxjb2RlPm51bGw8L2NvZGU+LCBmaXJzdCB0cnkgdXNpbmcgdGhlCi0gICAgICogY29udGV4dCBjbGFzcyBsb2FkZXIgZm9sbG93ZWQgYnkgdGhlIGN1cnJlbnQgKGkuZS4gYm9vdHN0cmFwKSBjbGFzcwotICAgICAqIGxvYWRlci4KLSAgICAgKgotICAgICAqIFVzZSBib290c3RyYXAgY2xhc3NMb2FkZXIgaWYgY2wgPSBudWxsIGFuZCB1c2VCU0Nsc0xvYWRlciBpcyB0cnVlCi0gICAgICovCi0gICAgc3RhdGljIHByaXZhdGUgQ2xhc3M8Pz4gZ2V0UHJvdmlkZXJDbGFzcyhTdHJpbmcgY2xhc3NOYW1lLCBDbGFzc0xvYWRlciBjbCwKLSAgICAgICAgICAgIGJvb2xlYW4gZG9GYWxsYmFjaywgYm9vbGVhbiB1c2VCU0Nsc0xvYWRlcikgdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBpZiAoY2wgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGlmICh1c2VCU0Nsc0xvYWRlcikgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gQ2xhc3MuZm9yTmFtZShjbGFzc05hbWUsIGZhbHNlLCBGYWN0b3J5RmluZGVyLmNsYXNzLmdldENsYXNzTG9hZGVyKCkpOwotICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIGNsID0gc3MuZ2V0Q29udGV4dENsYXNzTG9hZGVyKCk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChjbCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbigpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIENsYXNzLmZvck5hbWUoY2xhc3NOYW1lLCBmYWxzZSwgY2wpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIENsYXNzLmZvck5hbWUoY2xhc3NOYW1lLCBmYWxzZSwgY2wpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGUxKSB7Ci0gICAgICAgICAgICBpZiAoZG9GYWxsYmFjaykgewotICAgICAgICAgICAgICAgIC8vIFVzZSBjdXJyZW50IGNsYXNzIGxvYWRlciAtIHNob3VsZCBhbHdheXMgYmUgYm9vdHN0cmFwIENMCi0gICAgICAgICAgICAgICAgcmV0dXJuIENsYXNzLmZvck5hbWUoY2xhc3NOYW1lLCBmYWxzZSwgRmFjdG9yeUZpbmRlci5jbGFzcy5nZXRDbGFzc0xvYWRlcigpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIHRocm93IGUxOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlIGFuIGluc3RhbmNlIG9mIGEgY2xhc3MuIERlbGVnYXRlcyB0byBtZXRob2QKLSAgICAgKiA8Y29kZT5nZXRQcm92aWRlckNsYXNzKCk8L2NvZGU+IGluIG9yZGVyIHRvIGxvYWQgdGhlIGNsYXNzLgotICAgICAqCi0gICAgICogQHBhcmFtIHR5cGUgQmFzZSBjbGFzcyAvIFNlcnZpY2UgaW50ZXJmYWNlICBvZiB0aGUgZmFjdG9yeSB0bwotICAgICAqICAgICAgICAgICAgIGluc3RhbnRpYXRlLgotICAgICAqCi0gICAgICogQHBhcmFtIGNsYXNzTmFtZSBOYW1lIG9mIHRoZSBjb25jcmV0ZSBjbGFzcyBjb3JyZXNwb25kaW5nIHRvIHRoZQotICAgICAqIHNlcnZpY2UgcHJvdmlkZXIKLSAgICAgKgotICAgICAqIEBwYXJhbSBjbCA8Y29kZT5DbGFzc0xvYWRlcjwvY29kZT4gdXNlZCB0byBsb2FkIHRoZSBmYWN0b3J5IGNsYXNzLiBJZiA8Y29kZT5udWxsPC9jb2RlPgotICAgICAqIGN1cnJlbnQgPGNvZGU+VGhyZWFkPC9jb2RlPidzIGNvbnRleHQgY2xhc3NMb2FkZXIgaXMgdXNlZCB0byBsb2FkIHRoZSBmYWN0b3J5IGNsYXNzLgotICAgICAqCi0gICAgICogQHBhcmFtIGRvRmFsbGJhY2sgVHJ1ZSBpZiB0aGUgY3VycmVudCBDbGFzc0xvYWRlciBzaG91bGQgYmUgdHJpZWQgYXMKLSAgICAgKiBhIGZhbGxiYWNrIGlmIHRoZSBjbGFzcyBpcyBub3QgZm91bmQgdXNpbmcgY2wKLSAgICAgKi8KLSAgICBzdGF0aWMgPFQ+IFQgbmV3SW5zdGFuY2UoQ2xhc3M8VD4gdHlwZSwgU3RyaW5nIGNsYXNzTmFtZSwgQ2xhc3NMb2FkZXIgY2wsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gZG9GYWxsYmFjaykKLSAgICAgICAgdGhyb3dzIEZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IKLSAgICB7Ci0gICAgICAgIHJldHVybiBuZXdJbnN0YW5jZSh0eXBlLCBjbGFzc05hbWUsIGNsLCBkb0ZhbGxiYWNrLCBmYWxzZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlIGFuIGluc3RhbmNlIG9mIGEgY2xhc3MuIERlbGVnYXRlcyB0byBtZXRob2QKLSAgICAgKiA8Y29kZT5nZXRQcm92aWRlckNsYXNzKCk8L2NvZGU+IGluIG9yZGVyIHRvIGxvYWQgdGhlIGNsYXNzLgotICAgICAqCi0gICAgICogQHBhcmFtIHR5cGUgQmFzZSBjbGFzcyAvIFNlcnZpY2UgaW50ZXJmYWNlICBvZiB0aGUgZmFjdG9yeSB0bwotICAgICAqICAgICAgICAgICAgIGluc3RhbnRpYXRlLgotICAgICAqCi0gICAgICogQHBhcmFtIGNsYXNzTmFtZSBOYW1lIG9mIHRoZSBjb25jcmV0ZSBjbGFzcyBjb3JyZXNwb25kaW5nIHRvIHRoZQotICAgICAqIHNlcnZpY2UgcHJvdmlkZXIKLSAgICAgKgotICAgICAqIEBwYXJhbSBjbCA8Y29kZT5DbGFzc0xvYWRlcjwvY29kZT4gdXNlZCB0byBsb2FkIHRoZSBmYWN0b3J5IGNsYXNzLiBJZiA8Y29kZT5udWxsPC9jb2RlPgotICAgICAqIGN1cnJlbnQgPGNvZGU+VGhyZWFkPC9jb2RlPidzIGNvbnRleHQgY2xhc3NMb2FkZXIgaXMgdXNlZCB0byBsb2FkIHRoZSBmYWN0b3J5IGNsYXNzLgotICAgICAqCi0gICAgICogQHBhcmFtIGRvRmFsbGJhY2sgVHJ1ZSBpZiB0aGUgY3VycmVudCBDbGFzc0xvYWRlciBzaG91bGQgYmUgdHJpZWQgYXMKLSAgICAgKiBhIGZhbGxiYWNrIGlmIHRoZSBjbGFzcyBpcyBub3QgZm91bmQgdXNpbmcgY2wKLSAgICAgKgotICAgICAqIEBwYXJhbSB1c2VCU0Nsc0xvYWRlciBUcnVlIGlmIGNsPW51bGwgYWN0dWFsbHkgbWVhbnQgYm9vdHN0cmFwIGNsYXNzTG9hZGVyLiBUaGlzIHBhcmFtZXRlcgotICAgICAqIGlzIG5lZWRlZCBzaW5jZSBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5L1NBWFBhcnNlckZhY3RvcnkgZGVmaW5lZCBudWxsIGFzIGNvbnRleHQgY2xhc3NMb2FkZXIuCi0gICAgICovCi0gICAgc3RhdGljIDxUPiBUIG5ld0luc3RhbmNlKENsYXNzPFQ+IHR5cGUsIFN0cmluZyBjbGFzc05hbWUsIENsYXNzTG9hZGVyIGNsLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGRvRmFsbGJhY2ssIGJvb2xlYW4gdXNlQlNDbHNMb2FkZXIpCi0gICAgICAgIHRocm93cyBGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yCi0gICAgewotICAgICAgICBhc3NlcnQgdHlwZSAhPSBudWxsOwotICAgICAgICAvLyBtYWtlIHN1cmUgd2UgaGF2ZSBhY2Nlc3MgdG8gcmVzdHJpY3RlZCBwYWNrYWdlcwotICAgICAgICBpZiAoU3lzdGVtLmdldFNlY3VyaXR5TWFuYWdlcigpICE9IG51bGwpIHsKLSAgICAgICAgICAgIGlmIChjbGFzc05hbWUgIT0gbnVsbCAmJiBjbGFzc05hbWUuc3RhcnRzV2l0aChERUZBVUxUX1BBQ0tBR0UpKSB7Ci0gICAgICAgICAgICAgICAgY2wgPSBudWxsOwotICAgICAgICAgICAgICAgIHVzZUJTQ2xzTG9hZGVyID0gdHJ1ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBDbGFzczw/PiBwcm92aWRlckNsYXNzID0gZ2V0UHJvdmlkZXJDbGFzcyhjbGFzc05hbWUsIGNsLCBkb0ZhbGxiYWNrLCB1c2VCU0Nsc0xvYWRlcik7Ci0gICAgICAgICAgICBpZiAoIXR5cGUuaXNBc3NpZ25hYmxlRnJvbShwcm92aWRlckNsYXNzKSkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBDbGFzc0Nhc3RFeGNlcHRpb24oY2xhc3NOYW1lICsgIiBjYW5ub3QgYmUgY2FzdCB0byAiICsgdHlwZS5nZXROYW1lKCkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgT2JqZWN0IGluc3RhbmNlID0gcHJvdmlkZXJDbGFzcy5uZXdJbnN0YW5jZSgpOwotICAgICAgICAgICAgaWYgKGRlYnVnKSB7ICAgIC8vIEV4dHJhIGNoZWNrIHRvIGF2b2lkIGNvbXB1dGluZyBjbCBzdHJpbmdzCi0gICAgICAgICAgICAgICAgZFByaW50KCJjcmVhdGVkIG5ldyBpbnN0YW5jZSBvZiAiICsgcHJvdmlkZXJDbGFzcyArCi0gICAgICAgICAgICAgICAgICAgICAgICIgdXNpbmcgQ2xhc3NMb2FkZXI6ICIgKyBjbCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gdHlwZS5jYXN0KGluc3RhbmNlKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB4KSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvcih4LAotICAgICAgICAgICAgICAgICJQcm92aWRlciAiICsgY2xhc3NOYW1lICsgIiBub3QgZm91bmQiKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIHgpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yKHgsCi0gICAgICAgICAgICAgICAgIlByb3ZpZGVyICIgKyBjbGFzc05hbWUgKyAiIGNvdWxkIG5vdCBiZSBpbnN0YW50aWF0ZWQ6ICIgKyB4KTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEZpbmRzIHRoZSBpbXBsZW1lbnRhdGlvbiBDbGFzcyBvYmplY3QgaW4gdGhlIHNwZWNpZmllZCBvcmRlci4gIE1haW4KLSAgICAgKiBlbnRyeSBwb2ludC4KLSAgICAgKiBAcmV0dXJuIENsYXNzIG9iamVjdCBvZiBmYWN0b3J5LCBuZXZlciBudWxsCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdHlwZSAgICAgICAgICAgICAgICAgIEJhc2UgY2xhc3MgLyBTZXJ2aWNlIGludGVyZmFjZSAgb2YgdGhlCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWN0b3J5IHRvIGZpbmQuCi0gICAgICogQHBhcmFtIGZhbGxiYWNrQ2xhc3NOYW1lICAgICBJbXBsZW1lbnRhdGlvbiBjbGFzcyBuYW1lLCBpZiBub3RoaW5nIGVsc2UKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzIGZvdW5kLiAgVXNlIG51bGwgdG8gbWVhbiBubyBmYWxsYmFjay4KLSAgICAgKgotICAgICAqIFBhY2thZ2UgcHJpdmF0ZSBzbyB0aGlzIGNvZGUgY2FuIGJlIHNoYXJlZC4KLSAgICAgKi8KLSAgICBzdGF0aWMgPFQ+IFQgZmluZChDbGFzczxUPiB0eXBlLCBTdHJpbmcgZmFsbGJhY2tDbGFzc05hbWUpCi0gICAgICAgIHRocm93cyBGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yCi0gICAgewotICAgICAgICBmaW5hbCBTdHJpbmcgZmFjdG9yeUlkID0gdHlwZS5nZXROYW1lKCk7Ci0gICAgICAgIGRQcmludCgiZmluZCBmYWN0b3J5SWQgPSIgKyBmYWN0b3J5SWQpOwotCi0gICAgICAgIC8vIFVzZSB0aGUgc3lzdGVtIHByb3BlcnR5IGZpcnN0Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBTdHJpbmcgc3lzdGVtUHJvcCA9IHNzLmdldFN5c3RlbVByb3BlcnR5KGZhY3RvcnlJZCk7Ci0gICAgICAgICAgICBpZiAoc3lzdGVtUHJvcCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZFByaW50KCJmb3VuZCBzeXN0ZW0gcHJvcGVydHksIHZhbHVlPSIgKyBzeXN0ZW1Qcm9wKTsKLSAgICAgICAgICAgICAgICByZXR1cm4gbmV3SW5zdGFuY2UodHlwZSwgc3lzdGVtUHJvcCwgbnVsbCwgdHJ1ZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIHNlKSB7Ci0gICAgICAgICAgICBpZiAoZGVidWcpIHNlLnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gdHJ5IHRvIHJlYWQgZnJvbSAkamF2YS5ob21lL2xpYi9qYXhwLnByb3BlcnRpZXMKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGlmIChmaXJzdFRpbWUpIHsKLSAgICAgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKGNhY2hlUHJvcHMpIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGZpcnN0VGltZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGNvbmZpZ0ZpbGUgPSBzcy5nZXRTeXN0ZW1Qcm9wZXJ0eSgiamF2YS5ob21lIikgKyBGaWxlLnNlcGFyYXRvciArCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgImxpYiIgKyBGaWxlLnNlcGFyYXRvciArICJqYXhwLnByb3BlcnRpZXMiOwotICAgICAgICAgICAgICAgICAgICAgICAgRmlsZSBmID0gbmV3IEZpbGUoY29uZmlnRmlsZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmaXJzdFRpbWUgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzcy5kb2VzRmlsZUV4aXN0KGYpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZFByaW50KCJSZWFkIHByb3BlcnRpZXMgZmlsZSAiK2YpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhY2hlUHJvcHMubG9hZChzcy5nZXRGaWxlSW5wdXRTdHJlYW0oZikpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZmluYWwgU3RyaW5nIGZhY3RvcnlDbGFzc05hbWUgPSBjYWNoZVByb3BzLmdldFByb3BlcnR5KGZhY3RvcnlJZCk7Ci0KLSAgICAgICAgICAgIGlmIChmYWN0b3J5Q2xhc3NOYW1lICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBkUHJpbnQoImZvdW5kIGluICRqYXZhLmhvbWUvamF4cC5wcm9wZXJ0aWVzLCB2YWx1ZT0iICsgZmFjdG9yeUNsYXNzTmFtZSk7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIG5ld0luc3RhbmNlKHR5cGUsIGZhY3RvcnlDbGFzc05hbWUsIG51bGwsIHRydWUpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpIHsKLSAgICAgICAgICAgIGlmIChkZWJ1ZykgZXgucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBUcnkgSmFyIFNlcnZpY2UgUHJvdmlkZXIgTWVjaGFuaXNtCi0gICAgICAgIFQgcHJvdmlkZXIgPSBmaW5kU2VydmljZVByb3ZpZGVyKHR5cGUpOwotICAgICAgICBpZiAocHJvdmlkZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIHByb3ZpZGVyOwotICAgICAgICB9Ci0gICAgICAgIGlmIChmYWxsYmFja0NsYXNzTmFtZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvcigKLSAgICAgICAgICAgICAgICAiUHJvdmlkZXIgZm9yICIgKyBmYWN0b3J5SWQgKyAiIGNhbm5vdCBiZSBmb3VuZCIpOwotICAgICAgICB9Ci0KLSAgICAgICAgZFByaW50KCJsb2FkZWQgZnJvbSBmYWxsYmFjayB2YWx1ZTogIiArIGZhbGxiYWNrQ2xhc3NOYW1lKTsKLSAgICAgICAgcmV0dXJuIG5ld0luc3RhbmNlKHR5cGUsIGZhbGxiYWNrQ2xhc3NOYW1lLCBudWxsLCB0cnVlKTsKLSAgICB9Ci0KLSAgICAvKgotICAgICAqIFRyeSB0byBmaW5kIHByb3ZpZGVyIHVzaW5nIHRoZSBTZXJ2aWNlTG9hZGVyIEFQSQotICAgICAqCi0gICAgICogQHBhcmFtIHR5cGUgQmFzZSBjbGFzcyAvIFNlcnZpY2UgaW50ZXJmYWNlICBvZiB0aGUgZmFjdG9yeSB0byBmaW5kLgotICAgICAqCi0gICAgICogQHJldHVybiBpbnN0YW5jZSBvZiBwcm92aWRlciBjbGFzcyBpZiBmb3VuZCBvciBudWxsCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgPFQ+IFQgZmluZFNlcnZpY2VQcm92aWRlcihmaW5hbCBDbGFzczxUPiB0eXBlKSB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICByZXR1cm4gQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQobmV3IFByaXZpbGVnZWRBY3Rpb248VD4oKSB7Ci0gICAgICAgICAgICAgICAgcHVibGljIFQgcnVuKCkgewotICAgICAgICAgICAgICAgICAgICBmaW5hbCBTZXJ2aWNlTG9hZGVyPFQ+IHNlcnZpY2VMb2FkZXIgPSBTZXJ2aWNlTG9hZGVyLmxvYWQodHlwZSk7Ci0gICAgICAgICAgICAgICAgICAgIGZpbmFsIEl0ZXJhdG9yPFQ+IGl0ZXJhdG9yID0gc2VydmljZUxvYWRlci5pdGVyYXRvcigpOwotICAgICAgICAgICAgICAgICAgICBpZiAoaXRlcmF0b3IuaGFzTmV4dCgpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaXRlcmF0b3IubmV4dCgpOwotICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfSk7Ci0gICAgICAgIH0gY2F0Y2goU2VydmljZUNvbmZpZ3VyYXRpb25FcnJvciBlKSB7Ci0gICAgICAgICAgICAvLyBJdCBpcyBub3QgcG9zc2libGUgdG8gd3JhcCBhbiBlcnJvciBkaXJlY3RseSBpbgotICAgICAgICAgICAgLy8gRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvciAtIHNvIHdlIG5lZWQgdG8gd3JhcCB0aGUKLSAgICAgICAgICAgIC8vIFNlcnZpY2VDb25maWd1cmF0aW9uRXJyb3IgaW4gYSBSdW50aW1lRXhjZXB0aW9uLgotICAgICAgICAgICAgLy8gVGhlIGFsdGVybmF0aXZlIHdvdWxkIGJlIHRvIG1vZGlmeSB0aGUgbG9naWMgaW4KLSAgICAgICAgICAgIC8vIEZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IgdG8gYWxsb3cgc2V0dGluZyBhCi0gICAgICAgICAgICAvLyBUaHJvd2FibGUgYXMgdGhlIGNhdXNlLCBidXQgdGhhdCBjb3VsZCBjYXVzZQotICAgICAgICAgICAgLy8gY29tcGF0aWJpbGl0eSBpc3N1ZXMgZG93biB0aGUgcm9hZC4KLSAgICAgICAgICAgIGZpbmFsIFJ1bnRpbWVFeGNlcHRpb24geCA9IG5ldyBSdW50aW1lRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICAiUHJvdmlkZXIgZm9yICIgKyB0eXBlICsgIiBjYW5ub3QgYmUgY3JlYXRlZCIsIGUpOwotICAgICAgICAgICAgZmluYWwgRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvciBlcnJvciA9Ci0gICAgICAgICAgICAgICAgICAgIG5ldyBGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yKHgsIHguZ2V0TWVzc2FnZSgpKTsKLSAgICAgICAgICAgIHRocm93IGVycm9yOwotICAgICAgICB9Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvamF2YXgveG1sL3BhcnNlcnMvUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbi5qYXZhIGIvc3JjL2phdmF4L3htbC9wYXJzZXJzL1BhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDQ2N2NhMC4uMDAwMDAwMAotLS0gYS9zcmMvamF2YXgveG1sL3BhcnNlcnMvUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTYgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwMCwgMjAwNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotcGFja2FnZSBqYXZheC54bWwucGFyc2VyczsKLQotLyoqCi0gKiBJbmRpY2F0ZXMgYSBzZXJpb3VzIGNvbmZpZ3VyYXRpb24gZXJyb3IuCi0gKgotICogQGF1dGhvciA8YSBocmVmPSJtYWlsdG86SmVmZi5TdXR0b3JAU3VuLmNvbSI+SmVmZiBTdXR0b3I8L2E+Ci0gKi8KLQotcHVibGljIGNsYXNzIFBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gZXh0ZW5kcyBFeGNlcHRpb24gewotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlIGEgbmV3IDxjb2RlPlBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb248L2NvZGU+IHdpdGggbm8KLSAgICAgKiBkZXRhaWwgbWVzYWdlLgotICAgICAqLwotCi0gICAgcHVibGljIFBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24oKSB7Ci0gICAgICAgIHN1cGVyKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlIGEgbmV3IDxjb2RlPlBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb248L2NvZGU+IHdpdGgKLSAgICAgKiB0aGUgPGNvZGU+U3RyaW5nPC9jb2RlPiBzcGVjaWZpZWQgYXMgYW4gZXJyb3IgbWVzc2FnZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBtc2cgVGhlIGVycm9yIG1lc3NhZ2UgZm9yIHRoZSBleGNlcHRpb24uCi0gICAgICovCi0KLSAgICBwdWJsaWMgUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbihTdHJpbmcgbXNnKSB7Ci0gICAgICAgIHN1cGVyKG1zZyk7Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvamF2YXgveG1sL3BhcnNlcnMvU0FYUGFyc2VyLmphdmEgYi9zcmMvamF2YXgveG1sL3BhcnNlcnMvU0FYUGFyc2VyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDVhY2NkMTIuLjAwMDAwMDAKLS0tIGEvc3JjL2phdmF4L3htbC9wYXJzZXJzL1NBWFBhcnNlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTU1ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDAsIDIwMTMsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLXBhY2thZ2UgamF2YXgueG1sLnBhcnNlcnM7Ci0KLWltcG9ydCBqYXZhLmlvLkZpbGU7Ci1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOwotCi1pbXBvcnQgamF2YXgueG1sLnZhbGlkYXRpb24uU2NoZW1hOwotCi1pbXBvcnQgb3JnLnhtbC5zYXguSGFuZGxlckJhc2U7Ci1pbXBvcnQgb3JnLnhtbC5zYXguSW5wdXRTb3VyY2U7Ci1pbXBvcnQgb3JnLnhtbC5zYXguUGFyc2VyOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5YTUxSZWFkZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguaGVscGVycy5EZWZhdWx0SGFuZGxlcjsKLQotCi0vKioKLSAqIERlZmluZXMgdGhlIEFQSSB0aGF0IHdyYXBzIGFuIHtAbGluayBvcmcueG1sLnNheC5YTUxSZWFkZXJ9Ci0gKiBpbXBsZW1lbnRhdGlvbiBjbGFzcy4gSW4gSkFYUCAxLjAsIHRoaXMgY2xhc3Mgd3JhcHBlZCB0aGUKLSAqIHtAbGluayBvcmcueG1sLnNheC5QYXJzZXJ9IGludGVyZmFjZSwgaG93ZXZlciB0aGlzIGludGVyZmFjZSB3YXMKLSAqIHJlcGxhY2VkIGJ5IHRoZSB7QGxpbmsgb3JnLnhtbC5zYXguWE1MUmVhZGVyfS4gRm9yIGVhc2UKLSAqIG9mIHRyYW5zaXRpb24sIHRoaXMgY2xhc3MgY29udGludWVzIHRvIHN1cHBvcnQgdGhlIHNhbWUgbmFtZQotICogYW5kIGludGVyZmFjZSBhcyB3ZWxsIGFzIHN1cHBvcnRpbmcgbmV3IG1ldGhvZHMuCi0gKgotICogQW4gaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcyBjYW4gYmUgb2J0YWluZWQgZnJvbSB0aGUKLSAqIHtAbGluayBqYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXJGYWN0b3J5I25ld1NBWFBhcnNlcigpfSBtZXRob2QuCi0gKiBPbmNlIGFuIGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgaXMgb2J0YWluZWQsIFhNTCBjYW4gYmUgcGFyc2VkIGZyb20KLSAqIGEgdmFyaWV0eSBvZiBpbnB1dCBzb3VyY2VzLiBUaGVzZSBpbnB1dCBzb3VyY2VzIGFyZSBJbnB1dFN0cmVhbXMsCi0gKiBGaWxlcywgVVJMcywgYW5kIFNBWCBJbnB1dFNvdXJjZXMuPHA+Ci0gKgotICogVGhpcyBzdGF0aWMgbWV0aG9kIGNyZWF0ZXMgYSBuZXcgZmFjdG9yeSBpbnN0YW5jZSBiYXNlZAotICogb24gYSBzeXN0ZW0gcHJvcGVydHkgc2V0dGluZyBvciB1c2VzIHRoZSBwbGF0Zm9ybSBkZWZhdWx0Ci0gKiBpZiBubyBwcm9wZXJ0eSBoYXMgYmVlbiBkZWZpbmVkLjxwPgotICoKLSAqIFRoZSBzeXN0ZW0gcHJvcGVydHkgdGhhdCBjb250cm9scyB3aGljaCBGYWN0b3J5IGltcGxlbWVudGF0aW9uCi0gKiB0byBjcmVhdGUgaXMgbmFtZWQgPGNvZGU+JnF1b3Q7amF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyRmFjdG9yeSZxdW90OzwvY29kZT4uCi0gKiBUaGlzIHByb3BlcnR5IG5hbWVzIGEgY2xhc3MgdGhhdCBpcyBhIGNvbmNyZXRlIHN1YmNsYXNzIG9mIHRoaXMKLSAqIGFic3RyYWN0IGNsYXNzLiBJZiBubyBwcm9wZXJ0eSBpcyBkZWZpbmVkLCBhIHBsYXRmb3JtIGRlZmF1bHQKLSAqIHdpbGwgYmUgdXNlZC48L3A+Ci0gKgotICogQXMgdGhlIGNvbnRlbnQgaXMgcGFyc2VkIGJ5IHRoZSB1bmRlcmx5aW5nIHBhcnNlciwgbWV0aG9kcyBvZiB0aGUKLSAqIGdpdmVuIHtAbGluayBvcmcueG1sLnNheC5IYW5kbGVyQmFzZX0gb3IgdGhlCi0gKiB7QGxpbmsgb3JnLnhtbC5zYXguaGVscGVycy5EZWZhdWx0SGFuZGxlcn0gYXJlIGNhbGxlZC48cD4KLSAqCi0gKiBJbXBsZW1lbnRvcnMgb2YgdGhpcyBjbGFzcyB3aGljaCB3cmFwIGFuIHVuZGVybGF5aW5nIGltcGxlbWVudGF0aW9uCi0gKiBjYW4gY29uc2lkZXIgdXNpbmcgdGhlIHtAbGluayBvcmcueG1sLnNheC5oZWxwZXJzLlBhcnNlckFkYXB0ZXJ9Ci0gKiBjbGFzcyB0byBpbml0aWFsbHkgYWRhcHQgdGhlaXIgU0FYMSBpbXBsZW1lbnRhdGlvbiB0byB3b3JrIHVuZGVyCi0gKiB0aGlzIHJldmlzZWQgY2xhc3MuCi0gKgotICogQGF1dGhvciA8YSBocmVmPSJtYWlsdG86SmVmZi5TdXR0b3JAU3VuLmNvbSI+SmVmZiBTdXR0b3I8L2E+Ci0gKi8KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBTQVhQYXJzZXIgewotCi0gICAgLyoqCi0gICAgICogPHA+UHJvdGVjdGVkIGNvbnN0cnVjdG9yIHRvIHByZXZlbnQgaW5zdGFuaWF0aW9uLgotICAgICAqIFVzZSB7QGxpbmsgamF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyRmFjdG9yeSNuZXdTQVhQYXJzZXIoKX0uPC9wPgotICAgICAqLwotICAgIHByb3RlY3RlZCBTQVhQYXJzZXIgKCkgewotCi0gICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiA8cD5SZXNldCB0aGlzIDxjb2RlPlNBWFBhcnNlcjwvY29kZT4gdG8gaXRzIG9yaWdpbmFsIGNvbmZpZ3VyYXRpb24uPC9wPgotICAgICAgICAgKgotICAgICAgICAgKiA8cD48Y29kZT5TQVhQYXJzZXI8L2NvZGU+IGlzIHJlc2V0IHRvIHRoZSBzYW1lIHN0YXRlIGFzIHdoZW4gaXQgd2FzIGNyZWF0ZWQgd2l0aAotICAgICAgICAgKiB7QGxpbmsgU0FYUGFyc2VyRmFjdG9yeSNuZXdTQVhQYXJzZXIoKX0uCi0gICAgICAgICAqIDxjb2RlPnJlc2V0KCk8L2NvZGU+IGlzIGRlc2lnbmVkIHRvIGFsbG93IHRoZSByZXVzZSBvZiBleGlzdGluZyA8Y29kZT5TQVhQYXJzZXI8L2NvZGU+cwotICAgICAgICAgKiB0aHVzIHNhdmluZyByZXNvdXJjZXMgYXNzb2NpYXRlZCB3aXRoIHRoZSBjcmVhdGlvbiBvZiBuZXcgPGNvZGU+U0FYUGFyc2VyPC9jb2RlPnMuPC9wPgotICAgICAgICAgKgotICAgICAgICAgKiA8cD5UaGUgcmVzZXQgPGNvZGU+U0FYUGFyc2VyPC9jb2RlPiBpcyBub3QgZ3VhcmFudGVlZCB0byBoYXZlIHRoZSBzYW1lIHtAbGluayBTY2hlbWF9Ci0gICAgICAgICAqIDxjb2RlPk9iamVjdDwvY29kZT4sIGUuZy4ge0BsaW5rIE9iamVjdCNlcXVhbHMoT2JqZWN0IG9iail9LiAgSXQgaXMgZ3VhcmFudGVlZCB0byBoYXZlIGEgZnVuY3Rpb25hbGx5IGVxdWFsCi0gICAgICAgICAqIDxjb2RlPlNjaGVtYTwvY29kZT4uPC9wPgotICAgICAqCi0gICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBXaGVuIEltcGxlbWVudGF0aW9ucyBkbyBub3QKLSAgICAgKiAgIG92ZXJyaWRlIHRoaXMgbWV0aG9kCi0gICAgICAgICAqCi0gICAgICAgICAqIEBzaW5jZSAxLjUKLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyB2b2lkIHJlc2V0KCkgewotCi0gICAgICAgICAgICAgICAgLy8gaW1wbGVtZW50b3JzIHNob3VsZCBvdmVycmlkZSB0aGlzIG1ldGhvZAotICAgICAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgICAgICJUaGlzIFNBWFBhcnNlciwgXCIiICsgdGhpcy5nZXRDbGFzcygpLmdldE5hbWUoKSArICJcIiwgZG9lcyBub3Qgc3VwcG9ydCB0aGUgcmVzZXQgZnVuY3Rpb25hbGl0eS4iCi0gICAgICAgICAgICAgICAgICAgICAgICArICIgIFNwZWNpZmljYXRpb24gXCIiICsgdGhpcy5nZXRDbGFzcygpLmdldFBhY2thZ2UoKS5nZXRTcGVjaWZpY2F0aW9uVGl0bGUoKSArICJcIiIKLSAgICAgICAgICAgICAgICAgICAgICAgICsgIiB2ZXJzaW9uIFwiIiArIHRoaXMuZ2V0Q2xhc3MoKS5nZXRQYWNrYWdlKCkuZ2V0U3BlY2lmaWNhdGlvblZlcnNpb24oKSArICJcIiIKLSAgICAgICAgICAgICAgICAgICAgICAgICk7Ci0gICAgICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPlBhcnNlIHRoZSBjb250ZW50IG9mIHRoZSBnaXZlbiB7QGxpbmsgamF2YS5pby5JbnB1dFN0cmVhbX0KLSAgICAgKiBpbnN0YW5jZSBhcyBYTUwgdXNpbmcgdGhlIHNwZWNpZmllZCB7QGxpbmsgb3JnLnhtbC5zYXguSGFuZGxlckJhc2V9LgotICAgICAqIDxpPiBVc2Ugb2YgdGhlIERlZmF1bHRIYW5kbGVyIHZlcnNpb24gb2YgdGhpcyBtZXRob2QgaXMgcmVjb21tZW5kZWQgYXMKLSAgICAgKiB0aGUgSGFuZGxlckJhc2UgY2xhc3MgaGFzIGJlZW4gZGVwcmVjYXRlZCBpbiBTQVggMi4wPC9pPi48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gaXMgSW5wdXRTdHJlYW0gY29udGFpbmluZyB0aGUgY29udGVudCB0byBiZSBwYXJzZWQuCi0gICAgICogQHBhcmFtIGhiIFRoZSBTQVggSGFuZGxlckJhc2UgdG8gdXNlLgotICAgICAqCi0gICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gSWYgdGhlIGdpdmVuIElucHV0U3RyZWFtIGlzIG51bGwuCi0gICAgICogQHRocm93cyBTQVhFeGNlcHRpb24gSWYgcGFyc2UgcHJvZHVjZXMgYSBTQVggZXJyb3IuCi0gICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBJZiBhbiBJTyBlcnJvciBvY2N1cnMgaW50ZXJhY3Rpbmcgd2l0aCB0aGUKLSAgICAgKiAgIDxjb2RlPklucHV0U3RyZWFtPC9jb2RlPi4KLSAgICAgKgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguRG9jdW1lbnRIYW5kbGVyCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcGFyc2UoSW5wdXRTdHJlYW0gaXMsIEhhbmRsZXJCYXNlIGhiKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChpcyA9PSBudWxsKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJJbnB1dFN0cmVhbSBjYW5ub3QgYmUgbnVsbCIpOwotICAgICAgICB9Ci0KLSAgICAgICAgSW5wdXRTb3VyY2UgaW5wdXQgPSBuZXcgSW5wdXRTb3VyY2UoaXMpOwotICAgICAgICB0aGlzLnBhcnNlKGlucHV0LCBoYik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+UGFyc2UgdGhlIGNvbnRlbnQgb2YgdGhlIGdpdmVuIHtAbGluayBqYXZhLmlvLklucHV0U3RyZWFtfQotICAgICAqIGluc3RhbmNlIGFzIFhNTCB1c2luZyB0aGUgc3BlY2lmaWVkIHtAbGluayBvcmcueG1sLnNheC5IYW5kbGVyQmFzZX0uCi0gICAgICogPGk+IFVzZSBvZiB0aGUgRGVmYXVsdEhhbmRsZXIgdmVyc2lvbiBvZiB0aGlzIG1ldGhvZCBpcyByZWNvbW1lbmRlZCBhcwotICAgICAqIHRoZSBIYW5kbGVyQmFzZSBjbGFzcyBoYXMgYmVlbiBkZXByZWNhdGVkIGluIFNBWCAyLjA8L2k+LjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBpcyBJbnB1dFN0cmVhbSBjb250YWluaW5nIHRoZSBjb250ZW50IHRvIGJlIHBhcnNlZC4KLSAgICAgKiBAcGFyYW0gaGIgVGhlIFNBWCBIYW5kbGVyQmFzZSB0byB1c2UuCi0gICAgICogQHBhcmFtIHN5c3RlbUlkIFRoZSBzeXN0ZW1JZCB3aGljaCBpcyBuZWVkZWQgZm9yIHJlc29sdmluZyByZWxhdGl2ZSBVUklzLgotICAgICAqCi0gICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gSWYgdGhlIGdpdmVuIDxjb2RlPklucHV0U3RyZWFtPC9jb2RlPiBpcwotICAgICAqICAgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBJZiBhbnkgSU8gZXJyb3Igb2NjdXJzIGludGVyYWN0aW5nIHdpdGggdGhlCi0gICAgICogICA8Y29kZT5JbnB1dFN0cmVhbTwvY29kZT4uCi0gICAgICogQHRocm93cyBTQVhFeGNlcHRpb24gSWYgYW55IFNBWCBlcnJvcnMgb2NjdXIgZHVyaW5nIHByb2Nlc3NpbmcuCi0gICAgICoKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkRvY3VtZW50SGFuZGxlciB2ZXJzaW9uIG9mIHRoaXMgbWV0aG9kIGluc3RlYWQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcGFyc2UoCi0gICAgICAgIElucHV0U3RyZWFtIGlzLAotICAgICAgICBIYW5kbGVyQmFzZSBoYiwKLSAgICAgICAgU3RyaW5nIHN5c3RlbUlkKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChpcyA9PSBudWxsKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJJbnB1dFN0cmVhbSBjYW5ub3QgYmUgbnVsbCIpOwotICAgICAgICB9Ci0KLSAgICAgICAgSW5wdXRTb3VyY2UgaW5wdXQgPSBuZXcgSW5wdXRTb3VyY2UoaXMpOwotICAgICAgICBpbnB1dC5zZXRTeXN0ZW1JZChzeXN0ZW1JZCk7Ci0gICAgICAgIHRoaXMucGFyc2UoaW5wdXQsIGhiKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBQYXJzZSB0aGUgY29udGVudCBvZiB0aGUgZ2l2ZW4ge0BsaW5rIGphdmEuaW8uSW5wdXRTdHJlYW19Ci0gICAgICogaW5zdGFuY2UgYXMgWE1MIHVzaW5nIHRoZSBzcGVjaWZpZWQKLSAgICAgKiB7QGxpbmsgb3JnLnhtbC5zYXguaGVscGVycy5EZWZhdWx0SGFuZGxlcn0uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaXMgSW5wdXRTdHJlYW0gY29udGFpbmluZyB0aGUgY29udGVudCB0byBiZSBwYXJzZWQuCi0gICAgICogQHBhcmFtIGRoIFRoZSBTQVggRGVmYXVsdEhhbmRsZXIgdG8gdXNlLgotICAgICAqCi0gICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gSWYgdGhlIGdpdmVuIElucHV0U3RyZWFtIGlzIG51bGwuCi0gICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBJZiBhbnkgSU8gZXJyb3JzIG9jY3VyLgotICAgICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uIElmIGFueSBTQVggZXJyb3JzIG9jY3VyIGR1cmluZyBwcm9jZXNzaW5nLgotICAgICAqCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5Eb2N1bWVudEhhbmRsZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBwYXJzZShJbnB1dFN0cmVhbSBpcywgRGVmYXVsdEhhbmRsZXIgZGgpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKGlzID09IG51bGwpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIklucHV0U3RyZWFtIGNhbm5vdCBiZSBudWxsIik7Ci0gICAgICAgIH0KLQotICAgICAgICBJbnB1dFNvdXJjZSBpbnB1dCA9IG5ldyBJbnB1dFNvdXJjZShpcyk7Ci0gICAgICAgIHRoaXMucGFyc2UoaW5wdXQsIGRoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBQYXJzZSB0aGUgY29udGVudCBvZiB0aGUgZ2l2ZW4ge0BsaW5rIGphdmEuaW8uSW5wdXRTdHJlYW19Ci0gICAgICogaW5zdGFuY2UgYXMgWE1MIHVzaW5nIHRoZSBzcGVjaWZpZWQKLSAgICAgKiB7QGxpbmsgb3JnLnhtbC5zYXguaGVscGVycy5EZWZhdWx0SGFuZGxlcn0uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaXMgSW5wdXRTdHJlYW0gY29udGFpbmluZyB0aGUgY29udGVudCB0byBiZSBwYXJzZWQuCi0gICAgICogQHBhcmFtIGRoIFRoZSBTQVggRGVmYXVsdEhhbmRsZXIgdG8gdXNlLgotICAgICAqIEBwYXJhbSBzeXN0ZW1JZCBUaGUgc3lzdGVtSWQgd2hpY2ggaXMgbmVlZGVkIGZvciByZXNvbHZpbmcgcmVsYXRpdmUgVVJJcy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIElmIHRoZSBnaXZlbiBJbnB1dFN0cmVhbSBpcyBudWxsLgotICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gSWYgYW55IElPIGVycm9ycyBvY2N1ci4KLSAgICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBJZiBhbnkgU0FYIGVycm9ycyBvY2N1ciBkdXJpbmcgcHJvY2Vzc2luZy4KLSAgICAgKgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguRG9jdW1lbnRIYW5kbGVyIHZlcnNpb24gb2YgdGhpcyBtZXRob2QgaW5zdGVhZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBwYXJzZSgKLSAgICAgICAgSW5wdXRTdHJlYW0gaXMsCi0gICAgICAgIERlZmF1bHRIYW5kbGVyIGRoLAotICAgICAgICBTdHJpbmcgc3lzdGVtSWQpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKGlzID09IG51bGwpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIklucHV0U3RyZWFtIGNhbm5vdCBiZSBudWxsIik7Ci0gICAgICAgIH0KLQotICAgICAgICBJbnB1dFNvdXJjZSBpbnB1dCA9IG5ldyBJbnB1dFNvdXJjZShpcyk7Ci0gICAgICAgIGlucHV0LnNldFN5c3RlbUlkKHN5c3RlbUlkKTsKLSAgICAgICAgdGhpcy5wYXJzZShpbnB1dCwgZGgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFBhcnNlIHRoZSBjb250ZW50IGRlc2NyaWJlZCBieSB0aGUgZ2l2aW5nIFVuaWZvcm0gUmVzb3VyY2UKLSAgICAgKiBJZGVudGlmaWVyIChVUkkpIGFzIFhNTCB1c2luZyB0aGUgc3BlY2lmaWVkCi0gICAgICoge0BsaW5rIG9yZy54bWwuc2F4LkhhbmRsZXJCYXNlfS4KLSAgICAgKiA8aT4gVXNlIG9mIHRoZSBEZWZhdWx0SGFuZGxlciB2ZXJzaW9uIG9mIHRoaXMgbWV0aG9kIGlzIHJlY29tbWVuZGVkIGFzCi0gICAgICogdGhlIDxjb2RlPkhhbmRsZXJCYXNlPC9jb2RlPiBjbGFzcyBoYXMgYmVlbiBkZXByZWNhdGVkIGluIFNBWCAyLjA8L2k+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gdXJpIFRoZSBsb2NhdGlvbiBvZiB0aGUgY29udGVudCB0byBiZSBwYXJzZWQuCi0gICAgICogQHBhcmFtIGhiIFRoZSBTQVggSGFuZGxlckJhc2UgdG8gdXNlLgotICAgICAqCi0gICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gSWYgdGhlIHVyaSBpcyBudWxsLgotICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gSWYgYW55IElPIGVycm9ycyBvY2N1ci4KLSAgICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBJZiBhbnkgU0FYIGVycm9ycyBvY2N1ciBkdXJpbmcgcHJvY2Vzc2luZy4KLSAgICAgKgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguRG9jdW1lbnRIYW5kbGVyCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcGFyc2UoU3RyaW5nIHVyaSwgSGFuZGxlckJhc2UgaGIpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKHVyaSA9PSBudWxsKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJ1cmkgY2Fubm90IGJlIG51bGwiKTsKLSAgICAgICAgfQotCi0gICAgICAgIElucHV0U291cmNlIGlucHV0ID0gbmV3IElucHV0U291cmNlKHVyaSk7Ci0gICAgICAgIHRoaXMucGFyc2UoaW5wdXQsIGhiKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBQYXJzZSB0aGUgY29udGVudCBkZXNjcmliZWQgYnkgdGhlIGdpdmluZyBVbmlmb3JtIFJlc291cmNlCi0gICAgICogSWRlbnRpZmllciAoVVJJKSBhcyBYTUwgdXNpbmcgdGhlIHNwZWNpZmllZAotICAgICAqIHtAbGluayBvcmcueG1sLnNheC5oZWxwZXJzLkRlZmF1bHRIYW5kbGVyfS4KLSAgICAgKgotICAgICAqIEBwYXJhbSB1cmkgVGhlIGxvY2F0aW9uIG9mIHRoZSBjb250ZW50IHRvIGJlIHBhcnNlZC4KLSAgICAgKiBAcGFyYW0gZGggVGhlIFNBWCBEZWZhdWx0SGFuZGxlciB0byB1c2UuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBJZiB0aGUgdXJpIGlzIG51bGwuCi0gICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBJZiBhbnkgSU8gZXJyb3JzIG9jY3VyLgotICAgICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uIElmIGFueSBTQVggZXJyb3JzIG9jY3VyIGR1cmluZyBwcm9jZXNzaW5nLgotICAgICAqCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5Eb2N1bWVudEhhbmRsZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBwYXJzZShTdHJpbmcgdXJpLCBEZWZhdWx0SGFuZGxlciBkaCkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewotICAgICAgICBpZiAodXJpID09IG51bGwpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInVyaSBjYW5ub3QgYmUgbnVsbCIpOwotICAgICAgICB9Ci0KLSAgICAgICAgSW5wdXRTb3VyY2UgaW5wdXQgPSBuZXcgSW5wdXRTb3VyY2UodXJpKTsKLSAgICAgICAgdGhpcy5wYXJzZShpbnB1dCwgZGgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFBhcnNlIHRoZSBjb250ZW50IG9mIHRoZSBmaWxlIHNwZWNpZmllZCBhcyBYTUwgdXNpbmcgdGhlCi0gICAgICogc3BlY2lmaWVkIHtAbGluayBvcmcueG1sLnNheC5IYW5kbGVyQmFzZX0uCi0gICAgICogPGk+IFVzZSBvZiB0aGUgRGVmYXVsdEhhbmRsZXIgdmVyc2lvbiBvZiB0aGlzIG1ldGhvZCBpcyByZWNvbW1lbmRlZCBhcwotICAgICAqIHRoZSBIYW5kbGVyQmFzZSBjbGFzcyBoYXMgYmVlbiBkZXByZWNhdGVkIGluIFNBWCAyLjA8L2k+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gZiBUaGUgZmlsZSBjb250YWluaW5nIHRoZSBYTUwgdG8gcGFyc2UKLSAgICAgKiBAcGFyYW0gaGIgVGhlIFNBWCBIYW5kbGVyQmFzZSB0byB1c2UuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBJZiB0aGUgRmlsZSBvYmplY3QgaXMgbnVsbC4KLSAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIElmIGFueSBJTyBlcnJvcnMgb2NjdXIuCi0gICAgICogQHRocm93cyBTQVhFeGNlcHRpb24gSWYgYW55IFNBWCBlcnJvcnMgb2NjdXIgZHVyaW5nIHByb2Nlc3NpbmcuCi0gICAgICoKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkRvY3VtZW50SGFuZGxlcgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHBhcnNlKEZpbGUgZiwgSGFuZGxlckJhc2UgaGIpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKGYgPT0gbnVsbCkgewotICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmlsZSBjYW5ub3QgYmUgbnVsbCIpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy9jb252ZXJ0IGZpbGUgdG8gYXBwcm9wcmlhdGUgVVJJLCBmLnRvVVJJKCkudG9BU0NJSVN0cmluZygpCi0gICAgICAgIC8vY29udmVydHMgdGhlIFVSSSB0byBzdHJpbmcgYXMgcGVyIHJ1bGUgc3BlY2lmaWVkIGluCi0gICAgICAgIC8vUkZDIDIzOTYsCi0gICAgICAgIElucHV0U291cmNlIGlucHV0ID0gbmV3IElucHV0U291cmNlKGYudG9VUkkoKS50b0FTQ0lJU3RyaW5nKCkpOwotICAgICAgICB0aGlzLnBhcnNlKGlucHV0LCBoYik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUGFyc2UgdGhlIGNvbnRlbnQgb2YgdGhlIGZpbGUgc3BlY2lmaWVkIGFzIFhNTCB1c2luZyB0aGUKLSAgICAgKiBzcGVjaWZpZWQge0BsaW5rIG9yZy54bWwuc2F4LmhlbHBlcnMuRGVmYXVsdEhhbmRsZXJ9LgotICAgICAqCi0gICAgICogQHBhcmFtIGYgVGhlIGZpbGUgY29udGFpbmluZyB0aGUgWE1MIHRvIHBhcnNlCi0gICAgICogQHBhcmFtIGRoIFRoZSBTQVggRGVmYXVsdEhhbmRsZXIgdG8gdXNlLgotICAgICAqCi0gICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gSWYgdGhlIEZpbGUgb2JqZWN0IGlzIG51bGwuCi0gICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBJZiBhbnkgSU8gZXJyb3JzIG9jY3VyLgotICAgICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uIElmIGFueSBTQVggZXJyb3JzIG9jY3VyIGR1cmluZyBwcm9jZXNzaW5nLgotICAgICAqCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5Eb2N1bWVudEhhbmRsZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBwYXJzZShGaWxlIGYsIERlZmF1bHRIYW5kbGVyIGRoKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChmID09IG51bGwpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpbGUgY2Fubm90IGJlIG51bGwiKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vY29udmVydCBmaWxlIHRvIGFwcHJvcHJpYXRlIFVSSSwgZi50b1VSSSgpLnRvQVNDSUlTdHJpbmcoKQotICAgICAgICAvL2NvbnZlcnRzIHRoZSBVUkkgdG8gc3RyaW5nIGFzIHBlciBydWxlIHNwZWNpZmllZCBpbgotICAgICAgICAvL1JGQyAyMzk2LAotICAgICAgICBJbnB1dFNvdXJjZSBpbnB1dCA9IG5ldyBJbnB1dFNvdXJjZShmLnRvVVJJKCkudG9BU0NJSVN0cmluZygpKTsKLSAgICAgICAgdGhpcy5wYXJzZShpbnB1dCwgZGgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFBhcnNlIHRoZSBjb250ZW50IGdpdmVuIHtAbGluayBvcmcueG1sLnNheC5JbnB1dFNvdXJjZX0KLSAgICAgKiBhcyBYTUwgdXNpbmcgdGhlIHNwZWNpZmllZAotICAgICAqIHtAbGluayBvcmcueG1sLnNheC5IYW5kbGVyQmFzZX0uCi0gICAgICogPGk+IFVzZSBvZiB0aGUgRGVmYXVsdEhhbmRsZXIgdmVyc2lvbiBvZiB0aGlzIG1ldGhvZCBpcyByZWNvbW1lbmRlZCBhcwotICAgICAqIHRoZSBIYW5kbGVyQmFzZSBjbGFzcyBoYXMgYmVlbiBkZXByZWNhdGVkIGluIFNBWCAyLjA8L2k+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gaXMgVGhlIElucHV0U291cmNlIGNvbnRhaW5pbmcgdGhlIGNvbnRlbnQgdG8gYmUgcGFyc2VkLgotICAgICAqIEBwYXJhbSBoYiBUaGUgU0FYIEhhbmRsZXJCYXNlIHRvIHVzZS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIElmIHRoZSA8Y29kZT5JbnB1dFNvdXJjZTwvY29kZT4gb2JqZWN0Ci0gICAgICogICBpcyA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIElmIGFueSBJTyBlcnJvcnMgb2NjdXIuCi0gICAgICogQHRocm93cyBTQVhFeGNlcHRpb24gSWYgYW55IFNBWCBlcnJvcnMgb2NjdXIgZHVyaW5nIHByb2Nlc3NpbmcuCi0gICAgICoKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkRvY3VtZW50SGFuZGxlcgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHBhcnNlKElucHV0U291cmNlIGlzLCBIYW5kbGVyQmFzZSBoYikKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewotICAgICAgICBpZiAoaXMgPT0gbnVsbCkgewotICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiSW5wdXRTb3VyY2UgY2Fubm90IGJlIG51bGwiKTsKLSAgICAgICAgfQotCi0gICAgICAgIFBhcnNlciBwYXJzZXIgPSB0aGlzLmdldFBhcnNlcigpOwotICAgICAgICBpZiAoaGIgIT0gbnVsbCkgewotICAgICAgICAgICAgcGFyc2VyLnNldERvY3VtZW50SGFuZGxlcihoYik7Ci0gICAgICAgICAgICBwYXJzZXIuc2V0RW50aXR5UmVzb2x2ZXIoaGIpOwotICAgICAgICAgICAgcGFyc2VyLnNldEVycm9ySGFuZGxlcihoYik7Ci0gICAgICAgICAgICBwYXJzZXIuc2V0RFRESGFuZGxlcihoYik7Ci0gICAgICAgIH0KLSAgICAgICAgcGFyc2VyLnBhcnNlKGlzKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBQYXJzZSB0aGUgY29udGVudCBnaXZlbiB7QGxpbmsgb3JnLnhtbC5zYXguSW5wdXRTb3VyY2V9Ci0gICAgICogYXMgWE1MIHVzaW5nIHRoZSBzcGVjaWZpZWQKLSAgICAgKiB7QGxpbmsgb3JnLnhtbC5zYXguaGVscGVycy5EZWZhdWx0SGFuZGxlcn0uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaXMgVGhlIElucHV0U291cmNlIGNvbnRhaW5pbmcgdGhlIGNvbnRlbnQgdG8gYmUgcGFyc2VkLgotICAgICAqIEBwYXJhbSBkaCBUaGUgU0FYIERlZmF1bHRIYW5kbGVyIHRvIHVzZS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIElmIHRoZSA8Y29kZT5JbnB1dFNvdXJjZTwvY29kZT4gb2JqZWN0Ci0gICAgICogICBpcyA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIElmIGFueSBJTyBlcnJvcnMgb2NjdXIuCi0gICAgICogQHRocm93cyBTQVhFeGNlcHRpb24gSWYgYW55IFNBWCBlcnJvcnMgb2NjdXIgZHVyaW5nIHByb2Nlc3NpbmcuCi0gICAgICoKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkRvY3VtZW50SGFuZGxlcgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHBhcnNlKElucHV0U291cmNlIGlzLCBEZWZhdWx0SGFuZGxlciBkaCkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewotICAgICAgICBpZiAoaXMgPT0gbnVsbCkgewotICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiSW5wdXRTb3VyY2UgY2Fubm90IGJlIG51bGwiKTsKLSAgICAgICAgfQotCi0gICAgICAgIFhNTFJlYWRlciByZWFkZXIgPSB0aGlzLmdldFhNTFJlYWRlcigpOwotICAgICAgICBpZiAoZGggIT0gbnVsbCkgewotICAgICAgICAgICAgcmVhZGVyLnNldENvbnRlbnRIYW5kbGVyKGRoKTsKLSAgICAgICAgICAgIHJlYWRlci5zZXRFbnRpdHlSZXNvbHZlcihkaCk7Ci0gICAgICAgICAgICByZWFkZXIuc2V0RXJyb3JIYW5kbGVyKGRoKTsKLSAgICAgICAgICAgIHJlYWRlci5zZXREVERIYW5kbGVyKGRoKTsKLSAgICAgICAgfQotICAgICAgICByZWFkZXIucGFyc2UoaXMpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIFNBWCBwYXJzZXIgdGhhdCBpcyBlbmNhcHN1bHRhdGVkIGJ5IHRoZQotICAgICAqIGltcGxlbWVudGF0aW9uIG9mIHRoaXMgY2xhc3MuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBTQVggcGFyc2VyIHRoYXQgaXMgZW5jYXBzdWx0YXRlZCBieSB0aGUKLSAgICAgKiAgICAgICAgIGltcGxlbWVudGF0aW9uIG9mIHRoaXMgY2xhc3MuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBJZiBhbnkgU0FYIGVycm9ycyBvY2N1ciBkdXJpbmcgcHJvY2Vzc2luZy4KLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3Qgb3JnLnhtbC5zYXguUGFyc2VyIGdldFBhcnNlcigpIHRocm93cyBTQVhFeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSB7QGxpbmsgb3JnLnhtbC5zYXguWE1MUmVhZGVyfSB0aGF0IGlzIGVuY2Fwc3VsYXRlZCBieSB0aGUKLSAgICAgKiBpbXBsZW1lbnRhdGlvbiBvZiB0aGlzIGNsYXNzLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgWE1MUmVhZGVyIHRoYXQgaXMgZW5jYXBzdWxhdGVkIGJ5IHRoZQotICAgICAqICAgICAgICAgaW1wbGVtZW50YXRpb24gb2YgdGhpcyBjbGFzcy4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uIElmIGFueSBTQVggZXJyb3JzIG9jY3VyIGR1cmluZyBwcm9jZXNzaW5nLgotICAgICAqLwotCi0gICAgcHVibGljIGFic3RyYWN0IG9yZy54bWwuc2F4LlhNTFJlYWRlciBnZXRYTUxSZWFkZXIoKSB0aHJvd3MgU0FYRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogSW5kaWNhdGVzIHdoZXRoZXIgb3Igbm90IHRoaXMgcGFyc2VyIGlzIGNvbmZpZ3VyZWQgdG8KLSAgICAgKiB1bmRlcnN0YW5kIG5hbWVzcGFjZXMuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhpcyBwYXJzZXIgaXMgY29uZmlndXJlZCB0bwotICAgICAqICAgICAgICAgdW5kZXJzdGFuZCBuYW1lc3BhY2VzOyBmYWxzZSBvdGhlcndpc2UuCi0gICAgICovCi0KLSAgICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBpc05hbWVzcGFjZUF3YXJlKCk7Ci0KLSAgICAvKioKLSAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciBvciBub3QgdGhpcyBwYXJzZXIgaXMgY29uZmlndXJlZCB0bwotICAgICAqIHZhbGlkYXRlIFhNTCBkb2N1bWVudHMuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhpcyBwYXJzZXIgaXMgY29uZmlndXJlZCB0bwotICAgICAqICAgICAgICAgdmFsaWRhdGUgWE1MIGRvY3VtZW50czsgZmFsc2Ugb3RoZXJ3aXNlLgotICAgICAqLwotCi0gICAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gaXNWYWxpZGF0aW5nKCk7Ci0KLSAgICAvKioKLSAgICAgKiA8cD5TZXRzIHRoZSBwYXJ0aWN1bGFyIHByb3BlcnR5IGluIHRoZSB1bmRlcmx5aW5nIGltcGxlbWVudGF0aW9uIG9mCi0gICAgICoge0BsaW5rIG9yZy54bWwuc2F4LlhNTFJlYWRlcn0uCi0gICAgICogQSBsaXN0IG9mIHRoZSBjb3JlIGZlYXR1cmVzIGFuZCBwcm9wZXJ0aWVzIGNhbiBiZSBmb3VuZCBhdAotICAgICAqIDxhIGhyZWY9Imh0dHA6Ly9zYXguc291cmNlZm9yZ2UubmV0Lz9zZWxlY3RlZD1nZXQtc2V0Ij4KLSAgICAgKiBodHRwOi8vc2F4LnNvdXJjZWZvcmdlLm5ldC8/c2VsZWN0ZWQ9Z2V0LXNldDwvYT4uPC9wPgotICAgICAqIDxwPgotICAgICAqIEFsbCBpbXBsZW1lbnRhdGlvbnMgdGhhdCBpbXBsZW1lbnQgSkFYUCAxLjUgb3IgbmV3ZXIgYXJlIHJlcXVpcmVkIHRvCi0gICAgICogc3VwcG9ydCB0aGUge0BsaW5rIGphdmF4LnhtbC5YTUxDb25zdGFudHMjQUNDRVNTX0VYVEVSTkFMX0RURH0gYW5kCi0gICAgICoge0BsaW5rIGphdmF4LnhtbC5YTUxDb25zdGFudHMjQUNDRVNTX0VYVEVSTkFMX1NDSEVNQX0gcHJvcGVydGllcy4KLSAgICAgKiA8L3A+Ci0gICAgICogPHVsPgotICAgICAqICAgPGxpPgotICAgICAqICAgICAgPHA+Ci0gICAgICogICAgICBTZXR0aW5nIHRoZSB7QGxpbmsgamF2YXgueG1sLlhNTENvbnN0YW50cyNBQ0NFU1NfRVhURVJOQUxfRFREfSBwcm9wZXJ0eQotICAgICAqICAgICAgcmVzdHJpY3RzIHRoZSBhY2Nlc3MgdG8gZXh0ZXJuYWwgRFREcywgZXh0ZXJuYWwgRW50aXR5IFJlZmVyZW5jZXMgdG8KLSAgICAgKiAgICAgIHRoZSBwcm90b2NvbHMgc3BlY2lmaWVkIGJ5IHRoZSBwcm9wZXJ0eS4gIElmIGFjY2VzcyBpcyBkZW5pZWQgZHVyaW5nIHBhcnNpbmcKLSAgICAgKiAgICAgIGR1ZSB0byB0aGUgcmVzdHJpY3Rpb24gb2YgdGhpcyBwcm9wZXJ0eSwge0BsaW5rIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbn0KLSAgICAgKiAgICAgIHdpbGwgYmUgdGhyb3duIGJ5IHRoZSBwYXJzZSBtZXRob2RzIGRlZmluZWQgYnkge0BsaW5rIGphdmF4LnhtbC5wYXJzZXJzLlNBWFBhcnNlcn0uCi0gICAgICogICAgICA8L3A+Ci0gICAgICogICAgICA8cD4KLSAgICAgKiAgICAgIFNldHRpbmcgdGhlIHtAbGluayBqYXZheC54bWwuWE1MQ29uc3RhbnRzI0FDQ0VTU19FWFRFUk5BTF9TQ0hFTUF9IHByb3BlcnR5Ci0gICAgICogICAgICByZXN0cmljdHMgdGhlIGFjY2VzcyB0byBleHRlcm5hbCBTY2hlbWEgc2V0IGJ5IHRoZSBzY2hlbWFMb2NhdGlvbiBhdHRyaWJ1dGUgdG8KLSAgICAgKiAgICAgIHRoZSBwcm90b2NvbHMgc3BlY2lmaWVkIGJ5IHRoZSBwcm9wZXJ0eS4gIElmIGFjY2VzcyBpcyBkZW5pZWQgZHVyaW5nIHBhcnNpbmcKLSAgICAgKiAgICAgIGR1ZSB0byB0aGUgcmVzdHJpY3Rpb24gb2YgdGhpcyBwcm9wZXJ0eSwge0BsaW5rIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbn0KLSAgICAgKiAgICAgIHdpbGwgYmUgdGhyb3duIGJ5IHRoZSBwYXJzZSBtZXRob2RzIGRlZmluZWQgYnkgdGhlIHtAbGluayBqYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXJ9LgotICAgICAqICAgICAgPC9wPgotICAgICAqICAgPC9saT4KLSAgICAgKiA8L3VsPgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIHByb3BlcnR5IHRvIGJlIHNldC4KLSAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlIG9mIHRoZSBwcm9wZXJ0eSB0byBiZSBzZXQuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24gV2hlbiB0aGUgdW5kZXJseWluZyBYTUxSZWFkZXIgZG9lcwotICAgICAqICAgbm90IHJlY29nbml6ZSB0aGUgcHJvcGVydHkgbmFtZS4KLSAgICAgKiBAdGhyb3dzIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBXaGVuIHRoZSB1bmRlcmx5aW5nIFhNTFJlYWRlcgotICAgICAqICByZWNvZ25pemVzIHRoZSBwcm9wZXJ0eSBuYW1lIGJ1dCBkb2Vzbid0IHN1cHBvcnQgdGhlIHByb3BlcnR5LgotICAgICAqCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5YTUxSZWFkZXIjc2V0UHJvcGVydHkKLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRQcm9wZXJ0eShTdHJpbmcgbmFtZSwgT2JqZWN0IHZhbHVlKQotICAgICAgICB0aHJvd3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiwgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogPHA+UmV0dXJucyB0aGUgcGFydGljdWxhciBwcm9wZXJ0eSByZXF1ZXN0ZWQgZm9yIGluIHRoZSB1bmRlcmx5aW5nCi0gICAgICogaW1wbGVtZW50YXRpb24gb2Yge0BsaW5rIG9yZy54bWwuc2F4LlhNTFJlYWRlcn0uPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIHByb3BlcnR5IHRvIGJlIHJldHJpZXZlZC4KLSAgICAgKiBAcmV0dXJuIFZhbHVlIG9mIHRoZSByZXF1ZXN0ZWQgcHJvcGVydHkuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24gV2hlbiB0aGUgdW5kZXJseWluZyBYTUxSZWFkZXIgZG9lcwotICAgICAqICAgIG5vdCByZWNvZ25pemUgdGhlIHByb3BlcnR5IG5hbWUuCi0gICAgICogQHRocm93cyBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gV2hlbiB0aGUgdW5kZXJseWluZyBYTUxSZWFkZXIKLSAgICAgKiAgcmVjb2duaXplcyB0aGUgcHJvcGVydHkgbmFtZSBidXQgZG9lc24ndCBzdXBwb3J0IHRoZSBwcm9wZXJ0eS4KLSAgICAgKgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguWE1MUmVhZGVyI2dldFByb3BlcnR5Ci0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IE9iamVjdCBnZXRQcm9wZXJ0eShTdHJpbmcgbmFtZSkKLSAgICAgICAgdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbjsKLQotICAgIC8qKiA8cD5HZXQgY3VycmVudCBzdGF0ZSBvZiBjYW5vbmljYWxpemF0aW9uLjwvcD4KLSAgICAgKgotICAgICAqIEByZXR1cm4gY3VycmVudCBzdGF0ZSBjYW5vbmljYWxpemF0aW9uIGNvbnRyb2wKLSAgICAgKi8KLSAgICAvKgotICAgIHB1YmxpYyBib29sZWFuIGdldENhbm9uaWNhbGl6YXRpb24oKSB7Ci0gICAgICAgIHJldHVybiBjYW5vbmljYWxTdGF0ZTsKLSAgICB9Ci0gICAgKi8KLQotICAgIC8qKiA8cD5HZXQgYSByZWZlcmVuY2UgdG8gdGhlIHRoZSB7QGxpbmsgU2NoZW1hfSBiZWluZyB1c2VkIGJ5Ci0gICAgICogdGhlIFhNTCBwcm9jZXNzb3IuPC9wPgotICAgICAqCi0gICAgICogPHA+SWYgbm8gc2NoZW1hIGlzIGJlaW5nIHVzZWQsIDxjb2RlPm51bGw8L2NvZGU+IGlzIHJldHVybmVkLjwvcD4KLSAgICAgKgotICAgICAqIEByZXR1cm4ge0BsaW5rIFNjaGVtYX0gYmVpbmcgdXNlZCBvciA8Y29kZT5udWxsPC9jb2RlPgotICAgICAqICBpZiBub25lIGluIHVzZQotICAgICAqCi0gICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBXaGVuIGltcGxlbWVudGF0aW9uIGRvZXMgbm90Ci0gICAgICogICBvdmVycmlkZSB0aGlzIG1ldGhvZAotICAgICAqCi0gICAgICogQHNpbmNlIDEuNQotICAgICAqLwotICAgIHB1YmxpYyBTY2hlbWEgZ2V0U2NoZW1hKCkgewotICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oCi0gICAgICAgICAgICAiVGhpcyBwYXJzZXIgZG9lcyBub3Qgc3VwcG9ydCBzcGVjaWZpY2F0aW9uIFwiIgotICAgICAgICAgICAgKyB0aGlzLmdldENsYXNzKCkuZ2V0UGFja2FnZSgpLmdldFNwZWNpZmljYXRpb25UaXRsZSgpCi0gICAgICAgICAgICArICJcIiB2ZXJzaW9uIFwiIgotICAgICAgICAgICAgKyB0aGlzLmdldENsYXNzKCkuZ2V0UGFja2FnZSgpLmdldFNwZWNpZmljYXRpb25WZXJzaW9uKCkKLSAgICAgICAgICAgICsgIlwiIgotICAgICAgICAgICAgKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5HZXQgdGhlIFhJbmNsdWRlIHByb2Nlc3NpbmcgbW9kZSBmb3IgdGhpcyBwYXJzZXIuPC9wPgotICAgICAqCi0gICAgICogQHJldHVybgotICAgICAqICAgICAgdGhlIHJldHVybiB2YWx1ZSBvZgotICAgICAqICAgICAgdGhlIHtAbGluayBTQVhQYXJzZXJGYWN0b3J5I2lzWEluY2x1ZGVBd2FyZSgpfQotICAgICAqICAgICAgd2hlbiB0aGlzIHBhcnNlciB3YXMgY3JlYXRlZCBmcm9tIGZhY3RvcnkuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIFdoZW4gaW1wbGVtZW50YXRpb24gZG9lcyBub3QKLSAgICAgKiAgIG92ZXJyaWRlIHRoaXMgbWV0aG9kCi0gICAgICoKLSAgICAgKiBAc2luY2UgMS41Ci0gICAgICoKLSAgICAgKiBAc2VlIFNBWFBhcnNlckZhY3Rvcnkjc2V0WEluY2x1ZGVBd2FyZShib29sZWFuKQotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzWEluY2x1ZGVBd2FyZSgpIHsKLSAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKAotICAgICAgICAgICAgIlRoaXMgcGFyc2VyIGRvZXMgbm90IHN1cHBvcnQgc3BlY2lmaWNhdGlvbiBcIiIKLSAgICAgICAgICAgICsgdGhpcy5nZXRDbGFzcygpLmdldFBhY2thZ2UoKS5nZXRTcGVjaWZpY2F0aW9uVGl0bGUoKQotICAgICAgICAgICAgKyAiXCIgdmVyc2lvbiBcIiIKLSAgICAgICAgICAgICsgdGhpcy5nZXRDbGFzcygpLmdldFBhY2thZ2UoKS5nZXRTcGVjaWZpY2F0aW9uVmVyc2lvbigpCi0gICAgICAgICAgICArICJcIiIKLSAgICAgICAgICAgICk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmF4L3htbC9wYXJzZXJzL1NBWFBhcnNlckZhY3RvcnkuamF2YSBiL3NyYy9qYXZheC94bWwvcGFyc2Vycy9TQVhQYXJzZXJGYWN0b3J5LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDcxNjM0NTYuLjAwMDAwMDAKLS0tIGEvc3JjL2phdmF4L3htbC9wYXJzZXJzL1NBWFBhcnNlckZhY3RvcnkuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQ0MyArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDAwLCAyMDEzLCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi1wYWNrYWdlIGphdmF4LnhtbC5wYXJzZXJzOwotCi1pbXBvcnQgamF2YXgueG1sLnZhbGlkYXRpb24uU2NoZW1hOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbjsKLQotLyoqCi0gKiBEZWZpbmVzIGEgZmFjdG9yeSBBUEkgdGhhdCBlbmFibGVzIGFwcGxpY2F0aW9ucyB0byBjb25maWd1cmUgYW5kCi0gKiBvYnRhaW4gYSBTQVggYmFzZWQgcGFyc2VyIHRvIHBhcnNlIFhNTCBkb2N1bWVudHMuCi0gKgotICogQGF1dGhvciA8YSBocmVmPSJtYWlsdG86SmVmZi5TdXR0b3JAU3VuLmNvbSI+SmVmZiBTdXR0b3I8L2E+Ci0gKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzpOZWVyYWouQmFqYWpAc3VuLmNvbSI+TmVlcmFqIEJhamFqPC9hPgotICoKLSAqIEB2ZXJzaW9uICRSZXZpc2lvbjogMS45ICQsICREYXRlOiAyMDEwLzA1LzI1IDE2OjE5OjQ0ICQKLSAqCi0gKi8KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBTQVhQYXJzZXJGYWN0b3J5IHsKLQotICAgIC8qKgotICAgICAqIDxwPlNob3VsZCBQYXJzZXJzIGJlIHZhbGlkYXRpbmc/PC9wPgotICAgICAqLwotICAgIHByaXZhdGUgYm9vbGVhbiB2YWxpZGF0aW5nID0gZmFsc2U7Ci0KLSAgICAvKioKLSAgICAgKiA8cD5TaG91bGQgUGFyc2VycyBiZSBuYW1lc3BhY2UgYXdhcmU/PC9wPgotICAgICAqLwotICAgIHByaXZhdGUgYm9vbGVhbiBuYW1lc3BhY2VBd2FyZSA9IGZhbHNlOwotCi0gICAgLyoqCi0gICAgICogPHA+UHJvdGVjdGVkIGNvbnN0cnVjdG9yIHRvIGZvcmNlIHVzZSBvZiB7QGxpbmsgI25ld0luc3RhbmNlKCl9LjwvcD4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgU0FYUGFyc2VyRmFjdG9yeSAoKSB7Ci0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBPYnRhaW4gYSBuZXcgaW5zdGFuY2Ugb2YgYSA8Y29kZT5TQVhQYXJzZXJGYWN0b3J5PC9jb2RlPi4gVGhpcwotICAgICAqIHN0YXRpYyBtZXRob2QgY3JlYXRlcyBhIG5ldyBmYWN0b3J5IGluc3RhbmNlCi0gICAgICogVGhpcyBtZXRob2QgdXNlcyB0aGUgZm9sbG93aW5nIG9yZGVyZWQgbG9va3VwIHByb2NlZHVyZSB0byBkZXRlcm1pbmUKLSAgICAgKiB0aGUgPGNvZGU+U0FYUGFyc2VyRmFjdG9yeTwvY29kZT4gaW1wbGVtZW50YXRpb24gY2xhc3MgdG8KLSAgICAgKiBsb2FkOgotICAgICAqIDx1bD4KLSAgICAgKiA8bGk+Ci0gICAgICogVXNlIHRoZSA8Y29kZT5qYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXJGYWN0b3J5PC9jb2RlPiBzeXN0ZW0KLSAgICAgKiBwcm9wZXJ0eS4KLSAgICAgKiA8L2xpPgotICAgICAqIDxsaT4KLSAgICAgKiBVc2UgdGhlIHByb3BlcnRpZXMgZmlsZSAibGliL2pheHAucHJvcGVydGllcyIgaW4gdGhlIEpSRSBkaXJlY3RvcnkuCi0gICAgICogVGhpcyBjb25maWd1cmF0aW9uIGZpbGUgaXMgaW4gc3RhbmRhcmQgPGNvZGU+amF2YS51dGlsLlByb3BlcnRpZXMKLSAgICAgKiA8L2NvZGU+IGZvcm1hdCBhbmQgY29udGFpbnMgdGhlIGZ1bGx5IHF1YWxpZmllZCBuYW1lIG9mIHRoZQotICAgICAqIGltcGxlbWVudGF0aW9uIGNsYXNzIHdpdGggdGhlIGtleSBiZWluZyB0aGUgc3lzdGVtIHByb3BlcnR5IGRlZmluZWQKLSAgICAgKiBhYm92ZS4KLSAgICAgKgotICAgICAqIFRoZSBqYXhwLnByb3BlcnRpZXMgZmlsZSBpcyByZWFkIG9ubHkgb25jZSBieSB0aGUgSkFYUCBpbXBsZW1lbnRhdGlvbgotICAgICAqIGFuZCBpdCdzIHZhbHVlcyBhcmUgdGhlbiBjYWNoZWQgZm9yIGZ1dHVyZSB1c2UuICBJZiB0aGUgZmlsZSBkb2VzIG5vdCBleGlzdAotICAgICAqIHdoZW4gdGhlIGZpcnN0IGF0dGVtcHQgaXMgbWFkZSB0byByZWFkIGZyb20gaXQsIG5vIGZ1cnRoZXIgYXR0ZW1wdHMgYXJlCi0gICAgICogbWFkZSB0byBjaGVjayBmb3IgaXRzIGV4aXN0ZW5jZS4gIEl0IGlzIG5vdCBwb3NzaWJsZSB0byBjaGFuZ2UgdGhlIHZhbHVlCi0gICAgICogb2YgYW55IHByb3BlcnR5IGluIGpheHAucHJvcGVydGllcyBhZnRlciBpdCBoYXMgYmVlbiByZWFkIGZvciB0aGUgZmlyc3QgdGltZS4KLSAgICAgKiA8L2xpPgotICAgICAqIDxsaT4KLSAgICAgKiBVc2UgdGhlIHNlcnZpY2UtcHJvdmlkZXIgbG9hZGluZyBmYWNpbGl0aWVzLCBkZWZpbmVkIGJ5IHRoZQotICAgICAqIHtAbGluayBqYXZhLnV0aWwuU2VydmljZUxvYWRlcn0gY2xhc3MsIHRvIGF0dGVtcHQgdG8gbG9jYXRlIGFuZCBsb2FkIGFuCi0gICAgICogaW1wbGVtZW50YXRpb24gb2YgdGhlIHNlcnZpY2UgdXNpbmcgdGhlIHtAbGlua3BsYWluCi0gICAgICogamF2YS51dGlsLlNlcnZpY2VMb2FkZXIjbG9hZChqYXZhLmxhbmcuQ2xhc3MpIGRlZmF1bHQgbG9hZGluZyBtZWNoYW5pc219OgotICAgICAqIHRoZSBzZXJ2aWNlLXByb3ZpZGVyIGxvYWRpbmcgZmFjaWxpdHkgd2lsbCB1c2UgdGhlIHtAbGlua3BsYWluCi0gICAgICogamF2YS5sYW5nLlRocmVhZCNnZXRDb250ZXh0Q2xhc3NMb2FkZXIoKSBjdXJyZW50IHRocmVhZCdzIGNvbnRleHQgY2xhc3MgbG9hZGVyfQotICAgICAqIHRvIGF0dGVtcHQgdG8gbG9hZCB0aGUgc2VydmljZS4gSWYgdGhlIGNvbnRleHQgY2xhc3MKLSAgICAgKiBsb2FkZXIgaXMgbnVsbCwgdGhlIHtAbGlua3BsYWluCi0gICAgICogQ2xhc3NMb2FkZXIjZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKSBzeXN0ZW0gY2xhc3MgbG9hZGVyfSB3aWxsIGJlIHVzZWQuCi0gICAgICogPC9saT4KLSAgICAgKiA8bGk+Ci0gICAgICogT3RoZXJ3aXNlIHRoZSBzeXN0ZW0tZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBpcyByZXR1cm5lZC4KLSAgICAgKiA8L2xpPgotICAgICAqIDwvdWw+Ci0gICAgICoKLSAgICAgKiBPbmNlIGFuIGFwcGxpY2F0aW9uIGhhcyBvYnRhaW5lZCBhIHJlZmVyZW5jZSB0byBhCi0gICAgICogPGNvZGU+U0FYUGFyc2VyRmFjdG9yeTwvY29kZT4gaXQgY2FuIHVzZSB0aGUgZmFjdG9yeSB0bwotICAgICAqIGNvbmZpZ3VyZSBhbmQgb2J0YWluIHBhcnNlciBpbnN0YW5jZXMuCi0gICAgICoKLSAgICAgKgotICAgICAqCi0gICAgICogPGgyPlRpcCBmb3IgVHJvdWJsZS1zaG9vdGluZzwvaDI+Ci0gICAgICogPHA+U2V0dGluZyB0aGUgPGNvZGU+amF4cC5kZWJ1ZzwvY29kZT4gc3lzdGVtIHByb3BlcnR5IHdpbGwgY2F1c2UKLSAgICAgKiB0aGlzIG1ldGhvZCB0byBwcmludCBhIGxvdCBvZiBkZWJ1ZyBtZXNzYWdlcwotICAgICAqIHRvIDxjb2RlPlN5c3RlbS5lcnI8L2NvZGU+IGFib3V0IHdoYXQgaXQgaXMgZG9pbmcgYW5kIHdoZXJlIGl0IGlzIGxvb2tpbmcgYXQuPC9wPgotICAgICAqCi0gICAgICogPHA+IElmIHlvdSBoYXZlIHByb2JsZW1zIGxvYWRpbmcge0BsaW5rIFNBWFBhcnNlcn1zLCB0cnk6PC9wPgotICAgICAqIDxwcmU+Ci0gICAgICogamF2YSAtRGpheHAuZGVidWc9MSBZb3VyUHJvZ3JhbSAuLi4uCi0gICAgICogPC9wcmU+Ci0gICAgICoKLSAgICAgKgotICAgICAqIEByZXR1cm4gQSBuZXcgaW5zdGFuY2Ugb2YgYSBTQVhQYXJzZXJGYWN0b3J5LgotICAgICAqCi0gICAgICogQHRocm93cyBGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yIGluIGNhc2Ugb2Yge0BsaW5rcGxhaW4KLSAgICAgKiBqYXZhLnV0aWwuU2VydmljZUNvbmZpZ3VyYXRpb25FcnJvciBzZXJ2aWNlIGNvbmZpZ3VyYXRpb24gZXJyb3J9IG9yIGlmCi0gICAgICogdGhlIGltcGxlbWVudGF0aW9uIGlzIG5vdCBhdmFpbGFibGUgb3IgY2Fubm90IGJlIGluc3RhbnRpYXRlZC4KLSAgICAgKi8KLQotICAgIHB1YmxpYyBzdGF0aWMgU0FYUGFyc2VyRmFjdG9yeSBuZXdJbnN0YW5jZSgpIHsKLSAgICAgICAgcmV0dXJuIEZhY3RvcnlGaW5kZXIuZmluZCgKLSAgICAgICAgICAgICAgICAvKiBUaGUgZGVmYXVsdCBwcm9wZXJ0eSBuYW1lIGFjY29yZGluZyB0byB0aGUgSkFYUCBzcGVjICovCi0gICAgICAgICAgICAgICAgU0FYUGFyc2VyRmFjdG9yeS5jbGFzcywKLSAgICAgICAgICAgICAgICAvKiBUaGUgZmFsbGJhY2sgaW1wbGVtZW50YXRpb24gY2xhc3MgbmFtZSAqLwotICAgICAgICAgICAgICAgICJjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmpheHAuU0FYUGFyc2VyRmFjdG9yeUltcGwiKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5PYnRhaW4gYSBuZXcgaW5zdGFuY2Ugb2YgYSA8Y29kZT5TQVhQYXJzZXJGYWN0b3J5PC9jb2RlPiBmcm9tIGNsYXNzIG5hbWUuCi0gICAgICogVGhpcyBmdW5jdGlvbiBpcyB1c2VmdWwgd2hlbiB0aGVyZSBhcmUgbXVsdGlwbGUgcHJvdmlkZXJzIGluIHRoZSBjbGFzc3BhdGguCi0gICAgICogSXQgZ2l2ZXMgbW9yZSBjb250cm9sIHRvIHRoZSBhcHBsaWNhdGlvbiBhcyBpdCBjYW4gc3BlY2lmeSB3aGljaCBwcm92aWRlcgotICAgICAqIHNob3VsZCBiZSBsb2FkZWQuPC9wPgotICAgICAqCi0gICAgICogPHA+T25jZSBhbiBhcHBsaWNhdGlvbiBoYXMgb2J0YWluZWQgYSByZWZlcmVuY2UgdG8gYSA8Y29kZT5TQVhQYXJzZXJGYWN0b3J5PC9jb2RlPgotICAgICAqIGl0IGNhbiB1c2UgdGhlIGZhY3RvcnkgdG8gY29uZmlndXJlIGFuZCBvYnRhaW4gcGFyc2VyIGluc3RhbmNlcy48L3A+Ci0gICAgICoKLSAgICAgKgotICAgICAqIDxoMj5UaXAgZm9yIFRyb3VibGUtc2hvb3Rpbmc8L2gyPgotICAgICAqIDxwPlNldHRpbmcgdGhlIDxjb2RlPmpheHAuZGVidWc8L2NvZGU+IHN5c3RlbSBwcm9wZXJ0eSB3aWxsIGNhdXNlCi0gICAgICogdGhpcyBtZXRob2QgdG8gcHJpbnQgYSBsb3Qgb2YgZGVidWcgbWVzc2FnZXMKLSAgICAgKiB0byA8Y29kZT5TeXN0ZW0uZXJyPC9jb2RlPiBhYm91dCB3aGF0IGl0IGlzIGRvaW5nIGFuZCB3aGVyZSBpdCBpcyBsb29raW5nIGF0LjwvcD4KLSAgICAgKgotICAgICAqIDxwPiBJZiB5b3UgaGF2ZSBwcm9ibGVtcywgdHJ5OjwvcD4KLSAgICAgKiA8cHJlPgotICAgICAqIGphdmEgLURqYXhwLmRlYnVnPTEgWW91clByb2dyYW0gLi4uLgotICAgICAqIDwvcHJlPgotICAgICAqCi0gICAgICogQHBhcmFtIGZhY3RvcnlDbGFzc05hbWUgZnVsbHkgcXVhbGlmaWVkIGZhY3RvcnkgY2xhc3MgbmFtZSB0aGF0IHByb3ZpZGVzIGltcGxlbWVudGF0aW9uIG9mIDxjb2RlPmphdmF4LnhtbC5wYXJzZXJzLlNBWFBhcnNlckZhY3Rvcnk8L2NvZGU+LgotICAgICAqCi0gICAgICogQHBhcmFtIGNsYXNzTG9hZGVyIDxjb2RlPkNsYXNzTG9hZGVyPC9jb2RlPiB1c2VkIHRvIGxvYWQgdGhlIGZhY3RvcnkgY2xhc3MuIElmIDxjb2RlPm51bGw8L2NvZGU+Ci0gICAgICogICAgICAgICAgICAgICAgICAgICBjdXJyZW50IDxjb2RlPlRocmVhZDwvY29kZT4ncyBjb250ZXh0IGNsYXNzTG9hZGVyIGlzIHVzZWQgdG8gbG9hZCB0aGUgZmFjdG9yeSBjbGFzcy4KLSAgICAgKgotICAgICAqIEByZXR1cm4gTmV3IGluc3RhbmNlIG9mIGEgPGNvZGU+U0FYUGFyc2VyRmFjdG9yeTwvY29kZT4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvciBpZiA8Y29kZT5mYWN0b3J5Q2xhc3NOYW1lPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPiwgb3IKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlIGZhY3RvcnkgY2xhc3MgY2Fubm90IGJlIGxvYWRlZCwgaW5zdGFudGlhdGVkLgotICAgICAqCi0gICAgICogQHNlZSAjbmV3SW5zdGFuY2UoKQotICAgICAqCi0gICAgICogQHNpbmNlIDEuNgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgU0FYUGFyc2VyRmFjdG9yeSBuZXdJbnN0YW5jZShTdHJpbmcgZmFjdG9yeUNsYXNzTmFtZSwgQ2xhc3NMb2FkZXIgY2xhc3NMb2FkZXIpewotICAgICAgICAgICAgLy9kbyBub3QgZmFsbGJhY2sgaWYgZ2l2ZW4gY2xhc3Nsb2FkZXIgY2FuJ3QgZmluZCB0aGUgY2xhc3MsIHRocm93IGV4Y2VwdGlvbgotICAgICAgICAgICAgcmV0dXJuIEZhY3RvcnlGaW5kZXIubmV3SW5zdGFuY2UoU0FYUGFyc2VyRmFjdG9yeS5jbGFzcywKLSAgICAgICAgICAgICAgICAgICAgZmFjdG9yeUNsYXNzTmFtZSwgY2xhc3NMb2FkZXIsIGZhbHNlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5DcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIGEgU0FYUGFyc2VyIHVzaW5nIHRoZSBjdXJyZW50bHkKLSAgICAgKiBjb25maWd1cmVkIGZhY3RvcnkgcGFyYW1ldGVycy48L3A+Ci0gICAgICoKLSAgICAgKiBAcmV0dXJuIEEgbmV3IGluc3RhbmNlIG9mIGEgU0FYUGFyc2VyLgotICAgICAqCi0gICAgICogQHRocm93cyBQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIGlmIGEgcGFyc2VyIGNhbm5vdAotICAgICAqICAgYmUgY3JlYXRlZCB3aGljaCBzYXRpc2ZpZXMgdGhlIHJlcXVlc3RlZCBjb25maWd1cmF0aW9uLgotICAgICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uIGZvciBTQVggZXJyb3JzLgotICAgICAqLwotCi0gICAgcHVibGljIGFic3RyYWN0IFNBWFBhcnNlciBuZXdTQVhQYXJzZXIoKQotICAgICAgICB0aHJvd3MgUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiwgU0FYRXhjZXB0aW9uOwotCi0KLSAgICAvKioKLSAgICAgKiBTcGVjaWZpZXMgdGhhdCB0aGUgcGFyc2VyIHByb2R1Y2VkIGJ5IHRoaXMgY29kZSB3aWxsCi0gICAgICogcHJvdmlkZSBzdXBwb3J0IGZvciBYTUwgbmFtZXNwYWNlcy4gQnkgZGVmYXVsdCB0aGUgdmFsdWUgb2YgdGhpcyBpcyBzZXQKLSAgICAgKiB0byA8Y29kZT5mYWxzZTwvY29kZT4uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYXdhcmVuZXNzIHRydWUgaWYgdGhlIHBhcnNlciBwcm9kdWNlZCBieSB0aGlzIGNvZGUgd2lsbAotICAgICAqICAgICAgICAgICAgICAgICAgcHJvdmlkZSBzdXBwb3J0IGZvciBYTUwgbmFtZXNwYWNlczsgZmFsc2Ugb3RoZXJ3aXNlLgotICAgICAqLwotCi0gICAgcHVibGljIHZvaWQgc2V0TmFtZXNwYWNlQXdhcmUoYm9vbGVhbiBhd2FyZW5lc3MpIHsKLSAgICAgICAgdGhpcy5uYW1lc3BhY2VBd2FyZSA9IGF3YXJlbmVzczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTcGVjaWZpZXMgdGhhdCB0aGUgcGFyc2VyIHByb2R1Y2VkIGJ5IHRoaXMgY29kZSB3aWxsCi0gICAgICogdmFsaWRhdGUgZG9jdW1lbnRzIGFzIHRoZXkgYXJlIHBhcnNlZC4gQnkgZGVmYXVsdCB0aGUgdmFsdWUgb2YgdGhpcyBpcwotICAgICAqIHNldCB0byA8Y29kZT5mYWxzZTwvY29kZT4uCi0gICAgICoKLSAgICAgKiA8cD4KLSAgICAgKiBOb3RlIHRoYXQgInRoZSB2YWxpZGF0aW9uIiBoZXJlIG1lYW5zCi0gICAgICogPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLXhtbCNwcm9jLXR5cGVzIj5hIHZhbGlkYXRpbmcKLSAgICAgKiBwYXJzZXI8L2E+IGFzIGRlZmluZWQgaW4gdGhlIFhNTCByZWNvbW1lbmRhdGlvbi4KLSAgICAgKiBJbiBvdGhlciB3b3JkcywgaXQgZXNzZW50aWFsbHkganVzdCBjb250cm9scyB0aGUgRFREIHZhbGlkYXRpb24uCi0gICAgICogKGV4Y2VwdCB0aGUgbGVnYWN5IHR3byBwcm9wZXJ0aWVzIGRlZmluZWQgaW4gSkFYUCAxLjIuKQotICAgICAqIDwvcD4KLSAgICAgKgotICAgICAqIDxwPgotICAgICAqIFRvIHVzZSBtb2Rlcm4gc2NoZW1hIGxhbmd1YWdlcyBzdWNoIGFzIFczQyBYTUwgU2NoZW1hIG9yCi0gICAgICogUkVMQVggTkcgaW5zdGVhZCBvZiBEVEQsIHlvdSBjYW4gY29uZmlndXJlIHlvdXIgcGFyc2VyIHRvIGJlCi0gICAgICogYSBub24tdmFsaWRhdGluZyBwYXJzZXIgYnkgbGVhdmluZyB0aGUge0BsaW5rICNzZXRWYWxpZGF0aW5nKGJvb2xlYW4pfQotICAgICAqIG1ldGhvZCA8Y29kZT5mYWxzZTwvY29kZT4sIHRoZW4gdXNlIHRoZSB7QGxpbmsgI3NldFNjaGVtYShTY2hlbWEpfQotICAgICAqIG1ldGhvZCB0byBhc3NvY2lhdGUgYSBzY2hlbWEgdG8gYSBwYXJzZXIuCi0gICAgICogPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIHZhbGlkYXRpbmcgdHJ1ZSBpZiB0aGUgcGFyc2VyIHByb2R1Y2VkIGJ5IHRoaXMgY29kZSB3aWxsCi0gICAgICogICAgICAgICAgICAgICAgICAgdmFsaWRhdGUgZG9jdW1lbnRzIGFzIHRoZXkgYXJlIHBhcnNlZDsgZmFsc2Ugb3RoZXJ3aXNlLgotICAgICAqLwotCi0gICAgcHVibGljIHZvaWQgc2V0VmFsaWRhdGluZyhib29sZWFuIHZhbGlkYXRpbmcpIHsKLSAgICAgICAgdGhpcy52YWxpZGF0aW5nID0gdmFsaWRhdGluZzsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciBvciBub3QgdGhlIGZhY3RvcnkgaXMgY29uZmlndXJlZCB0byBwcm9kdWNlCi0gICAgICogcGFyc2VycyB3aGljaCBhcmUgbmFtZXNwYWNlIGF3YXJlLgotICAgICAqCi0gICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBmYWN0b3J5IGlzIGNvbmZpZ3VyZWQgdG8gcHJvZHVjZQotICAgICAqICAgICAgICAgcGFyc2VycyB3aGljaCBhcmUgbmFtZXNwYWNlIGF3YXJlOyBmYWxzZSBvdGhlcndpc2UuCi0gICAgICovCi0KLSAgICBwdWJsaWMgYm9vbGVhbiBpc05hbWVzcGFjZUF3YXJlKCkgewotICAgICAgICByZXR1cm4gbmFtZXNwYWNlQXdhcmU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSW5kaWNhdGVzIHdoZXRoZXIgb3Igbm90IHRoZSBmYWN0b3J5IGlzIGNvbmZpZ3VyZWQgdG8gcHJvZHVjZQotICAgICAqIHBhcnNlcnMgd2hpY2ggdmFsaWRhdGUgdGhlIFhNTCBjb250ZW50IGR1cmluZyBwYXJzZS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgZmFjdG9yeSBpcyBjb25maWd1cmVkIHRvIHByb2R1Y2UgcGFyc2VycyB3aGljaCB2YWxpZGF0ZQotICAgICAqICAgICAgICAgdGhlIFhNTCBjb250ZW50IGR1cmluZyBwYXJzZTsgZmFsc2Ugb3RoZXJ3aXNlLgotICAgICAqLwotCi0gICAgcHVibGljIGJvb2xlYW4gaXNWYWxpZGF0aW5nKCkgewotICAgICAgICByZXR1cm4gdmFsaWRhdGluZzsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKgotICAgICAqIDxwPlNldHMgdGhlIHBhcnRpY3VsYXIgZmVhdHVyZSBpbiB0aGUgdW5kZXJseWluZyBpbXBsZW1lbnRhdGlvbiBvZgotICAgICAqIG9yZy54bWwuc2F4LlhNTFJlYWRlci4KLSAgICAgKiBBIGxpc3Qgb2YgdGhlIGNvcmUgZmVhdHVyZXMgYW5kIHByb3BlcnRpZXMgY2FuIGJlIGZvdW5kIGF0Ci0gICAgICogPGEgaHJlZj0iaHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZy8iPmh0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmcvPC9hPjwvcD4KLSAgICAgKgotICAgICAqIDxwPkFsbCBpbXBsZW1lbnRhdGlvbnMgYXJlIHJlcXVpcmVkIHRvIHN1cHBvcnQgdGhlIHtAbGluayBqYXZheC54bWwuWE1MQ29uc3RhbnRzI0ZFQVRVUkVfU0VDVVJFX1BST0NFU1NJTkd9IGZlYXR1cmUuCi0gICAgICogV2hlbiB0aGUgZmVhdHVyZSBpczwvcD4KLSAgICAgKiA8dWw+Ci0gICAgICogICA8bGk+Ci0gICAgICogICAgIDxjb2RlPnRydWU8L2NvZGU+OiB0aGUgaW1wbGVtZW50YXRpb24gd2lsbCBsaW1pdCBYTUwgcHJvY2Vzc2luZyB0byBjb25mb3JtIHRvIGltcGxlbWVudGF0aW9uIGxpbWl0cy4KLSAgICAgKiAgICAgRXhhbXBsZXMgaW5jbHVkZSBlbnRpdHkgZXhwYW5zaW9uIGxpbWl0cyBhbmQgWE1MIFNjaGVtYSBjb25zdHJ1Y3RzIHRoYXQgd291bGQgY29uc3VtZSBsYXJnZSBhbW91bnRzIG9mIHJlc291cmNlcy4KLSAgICAgKiAgICAgSWYgWE1MIHByb2Nlc3NpbmcgaXMgbGltaXRlZCBmb3Igc2VjdXJpdHkgcmVhc29ucywgaXQgd2lsbCBiZSByZXBvcnRlZCB2aWEgYSBjYWxsIHRvIHRoZSByZWdpc3RlcmVkCi0gICAgICogICAgIHtAbGluayBvcmcueG1sLnNheC5FcnJvckhhbmRsZXIjZmF0YWxFcnJvcihTQVhQYXJzZUV4Y2VwdGlvbiBleGNlcHRpb24pfS4KLSAgICAgKiAgICAgU2VlIHtAbGluayBTQVhQYXJzZXJ9IDxjb2RlPnBhcnNlPC9jb2RlPiBtZXRob2RzIGZvciBoYW5kbGVyIHNwZWNpZmljYXRpb24uCi0gICAgICogICA8L2xpPgotICAgICAqICAgPGxpPgotICAgICAqICAgICBXaGVuIHRoZSBmZWF0dXJlIGlzIDxjb2RlPmZhbHNlPC9jb2RlPiwgdGhlIGltcGxlbWVudGF0aW9uIHdpbGwgcHJvY2Vzc2luZyBYTUwgYWNjb3JkaW5nIHRvIHRoZSBYTUwgc3BlY2lmaWNhdGlvbnMgd2l0aG91dAotICAgICAqICAgICByZWdhcmQgdG8gcG9zc2libGUgaW1wbGVtZW50YXRpb24gbGltaXRzLgotICAgICAqICAgPC9saT4KLSAgICAgKiA8L3VsPgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGZlYXR1cmUgdG8gYmUgc2V0LgotICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUgb2YgdGhlIGZlYXR1cmUgdG8gYmUgc2V0LgotICAgICAqCi0gICAgICogQHRocm93cyBQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIGlmIGEgcGFyc2VyIGNhbm5vdAotICAgICAqICAgICBiZSBjcmVhdGVkIHdoaWNoIHNhdGlzZmllcyB0aGUgcmVxdWVzdGVkIGNvbmZpZ3VyYXRpb24uCi0gICAgICogQHRocm93cyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIFdoZW4gdGhlIHVuZGVybHlpbmcgWE1MUmVhZGVyIGRvZXMKLSAgICAgKiAgICAgICAgICAgIG5vdCByZWNvZ25pemUgdGhlIHByb3BlcnR5IG5hbWUuCi0gICAgICogQHRocm93cyBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gV2hlbiB0aGUgdW5kZXJseWluZyBYTUxSZWFkZXIKLSAgICAgKiAgICAgICAgICAgIHJlY29nbml6ZXMgdGhlIHByb3BlcnR5IG5hbWUgYnV0IGRvZXNuJ3Qgc3VwcG9ydCB0aGUKLSAgICAgKiAgICAgICAgICAgIHByb3BlcnR5LgotICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gSWYgdGhlIDxjb2RlPm5hbWU8L2NvZGU+IHBhcmFtZXRlciBpcyBudWxsLgotICAgICAqCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5YTUxSZWFkZXIjc2V0RmVhdHVyZQotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHNldEZlYXR1cmUoU3RyaW5nIG5hbWUsIGJvb2xlYW4gdmFsdWUpCi0gICAgICAgIHRocm93cyBQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uLCBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uLAotICAgICAgICAgICAgICAgIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqCi0gICAgICogPHA+UmV0dXJucyB0aGUgcGFydGljdWxhciBwcm9wZXJ0eSByZXF1ZXN0ZWQgZm9yIGluIHRoZSB1bmRlcmx5aW5nCi0gICAgICogaW1wbGVtZW50YXRpb24gb2Ygb3JnLnhtbC5zYXguWE1MUmVhZGVyLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBwcm9wZXJ0eSB0byBiZSByZXRyaWV2ZWQuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFZhbHVlIG9mIHRoZSByZXF1ZXN0ZWQgcHJvcGVydHkuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gaWYgYSBwYXJzZXIgY2Fubm90IGJlIGNyZWF0ZWQgd2hpY2ggc2F0aXNmaWVzIHRoZSByZXF1ZXN0ZWQgY29uZmlndXJhdGlvbi4KLSAgICAgKiBAdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24gV2hlbiB0aGUgdW5kZXJseWluZyBYTUxSZWFkZXIgZG9lcyBub3QgcmVjb2duaXplIHRoZSBwcm9wZXJ0eSBuYW1lLgotICAgICAqIEB0aHJvd3MgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIFdoZW4gdGhlIHVuZGVybHlpbmcgWE1MUmVhZGVyIHJlY29nbml6ZXMgdGhlIHByb3BlcnR5IG5hbWUgYnV0IGRvZXNuJ3Qgc3VwcG9ydCB0aGUgcHJvcGVydHkuCi0gICAgICoKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LlhNTFJlYWRlciNnZXRQcm9wZXJ0eQotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGdldEZlYXR1cmUoU3RyaW5nIG5hbWUpCi0gICAgICAgIHRocm93cyBQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uLCBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uLAotICAgICAgICAgICAgICAgIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbjsKLQotCi0gICAgLyoqCi0gICAgICogR2V0cyB0aGUge0BsaW5rIFNjaGVtYX0gb2JqZWN0IHNwZWNpZmllZCB0aHJvdWdoCi0gICAgICogdGhlIHtAbGluayAjc2V0U2NoZW1hKFNjaGVtYSBzY2hlbWEpfSBtZXRob2QuCi0gICAgICoKLSAgICAgKgotICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gV2hlbiBpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdAotICAgICAqICAgb3ZlcnJpZGUgdGhpcyBtZXRob2QKLSAgICAgKgotICAgICAqIEByZXR1cm4KLSAgICAgKiAgICAgIHRoZSB7QGxpbmsgU2NoZW1hfSBvYmplY3QgdGhhdCB3YXMgbGFzdCBzZXQgdGhyb3VnaAotICAgICAqICAgICAgdGhlIHtAbGluayAjc2V0U2NoZW1hKFNjaGVtYSl9IG1ldGhvZCwgb3IgbnVsbAotICAgICAqICAgICAgaWYgdGhlIG1ldGhvZCB3YXMgbm90IGludm9rZWQgc2luY2UgYSB7QGxpbmsgU0FYUGFyc2VyRmFjdG9yeX0KLSAgICAgKiAgICAgIGlzIGNyZWF0ZWQuCi0gICAgICoKLSAgICAgKiBAc2luY2UgMS41Ci0gICAgICovCi0gICAgcHVibGljIFNjaGVtYSBnZXRTY2hlbWEoKSB7Ci0gICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigKLSAgICAgICAgICAgICJUaGlzIHBhcnNlciBkb2VzIG5vdCBzdXBwb3J0IHNwZWNpZmljYXRpb24gXCIiCi0gICAgICAgICAgICArIHRoaXMuZ2V0Q2xhc3MoKS5nZXRQYWNrYWdlKCkuZ2V0U3BlY2lmaWNhdGlvblRpdGxlKCkKLSAgICAgICAgICAgICsgIlwiIHZlcnNpb24gXCIiCi0gICAgICAgICAgICArIHRoaXMuZ2V0Q2xhc3MoKS5nZXRQYWNrYWdlKCkuZ2V0U3BlY2lmaWNhdGlvblZlcnNpb24oKQotICAgICAgICAgICAgKyAiXCIiCi0gICAgICAgICAgICApOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPlNldCB0aGUge0BsaW5rIFNjaGVtYX0gdG8gYmUgdXNlZCBieSBwYXJzZXJzIGNyZWF0ZWQKLSAgICAgKiBmcm9tIHRoaXMgZmFjdG9yeS48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5XaGVuIGEge0BsaW5rIFNjaGVtYX0gaXMgbm9uLW51bGwsIGEgcGFyc2VyIHdpbGwgdXNlIGEgdmFsaWRhdG9yCi0gICAgICogY3JlYXRlZCBmcm9tIGl0IHRvIHZhbGlkYXRlIGRvY3VtZW50cyBiZWZvcmUgaXQgcGFzc2VzIGluZm9ybWF0aW9uCi0gICAgICogZG93biB0byB0aGUgYXBwbGljYXRpb24uPC9wPgotICAgICAqCi0gICAgICogPHA+V2hlbiB3YXJuaW5ncy9lcnJvcnMvZmF0YWwgZXJyb3JzIGFyZSBmb3VuZCBieSB0aGUgdmFsaWRhdG9yLCB0aGUgcGFyc2VyIG11c3QKLSAgICAgKiBoYW5kbGUgdGhlbSBhcyBpZiB0aG9zZSBlcnJvcnMgd2VyZSBmb3VuZCBieSB0aGUgcGFyc2VyIGl0c2VsZi4KLSAgICAgKiBJbiBvdGhlciB3b3JkcywgaWYgdGhlIHVzZXItc3BlY2lmaWVkIHtAbGluayBvcmcueG1sLnNheC5FcnJvckhhbmRsZXJ9Ci0gICAgICogaXMgc2V0LCBpdCBtdXN0IHJlY2VpdmUgdGhvc2UgZXJyb3JzLCBhbmQgaWYgbm90LCB0aGV5IG11c3QgYmUKLSAgICAgKiB0cmVhdGVkIGFjY29yZGluZyB0byB0aGUgaW1wbGVtZW50YXRpb24gc3BlY2lmaWMKLSAgICAgKiBkZWZhdWx0IGVycm9yIGhhbmRsaW5nIHJ1bGVzLgotICAgICAqCi0gICAgICogPHA+QSB2YWxpZGF0b3IgbWF5IG1vZGlmeSB0aGUgU0FYIGV2ZW50IHN0cmVhbSAoZm9yIGV4YW1wbGUgYnkKLSAgICAgKiBhZGRpbmcgZGVmYXVsdCB2YWx1ZXMgdGhhdCB3ZXJlIG1pc3NpbmcgaW4gZG9jdW1lbnRzKSwgYW5kIGEgcGFyc2VyCi0gICAgICogaXMgcmVzcG9uc2libGUgdG8gbWFrZSBzdXJlIHRoYXQgdGhlIGFwcGxpY2F0aW9uIHdpbGwgcmVjZWl2ZQotICAgICAqIHRob3NlIG1vZGlmaWVkIGV2ZW50IHN0cmVhbS48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5Jbml0aWFseSwgPGNvZGU+bnVsbDwvY29kZT4gaXMgc2V0IGFzIHRoZSB7QGxpbmsgU2NoZW1hfS48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5UaGlzIHByb2Nlc3Npbmcgd2lsbCB0YWtlIGVmZmVjdCBldmVuIGlmCi0gICAgICogdGhlIHtAbGluayAjaXNWYWxpZGF0aW5nKCl9IG1ldGhvZCByZXR1cm5zIDxjb2RlPmZhbHNlPC9jb2RlPi4KLSAgICAgKgotICAgICAqIDxwPkl0IGlzIGFuIGVycm9yIHRvIHVzZQotICAgICAqIHRoZSA8Y29kZT5odHRwOi8vamF2YS5zdW4uY29tL3htbC9qYXhwL3Byb3BlcnRpZXMvc2NoZW1hU291cmNlPC9jb2RlPgotICAgICAqIHByb3BlcnR5IGFuZC9vciB0aGUgPGNvZGU+aHR0cDovL2phdmEuc3VuLmNvbS94bWwvamF4cC9wcm9wZXJ0aWVzL3NjaGVtYUxhbmd1YWdlPC9jb2RlPgotICAgICAqIHByb3BlcnR5IGluIGNvbmp1bmN0aW9uIHdpdGggYSBub24tbnVsbCB7QGxpbmsgU2NoZW1hfSBvYmplY3QuCi0gICAgICogU3VjaCBjb25maWd1cmF0aW9uIHdpbGwgY2F1c2UgYSB7QGxpbmsgU0FYRXhjZXB0aW9ufQotICAgICAqIGV4Y2VwdGlvbiB3aGVuIHRob3NlIHByb3BlcnRpZXMgYXJlIHNldCBvbiBhIHtAbGluayBTQVhQYXJzZXJ9LjwvcD4KLSAgICAgKgotICAgICAqIDxoND5Ob3RlIGZvciBpbXBsZW1lbnRvcnM8L2g0PgotICAgICAqIDxwPgotICAgICAqIEEgcGFyc2VyIG11c3QgYmUgYWJsZSB0byB3b3JrIHdpdGggYW55IHtAbGluayBTY2hlbWF9Ci0gICAgICogaW1wbGVtZW50YXRpb24uIEhvd2V2ZXIsIHBhcnNlcnMgYW5kIHNjaGVtYXMgYXJlIGFsbG93ZWQKLSAgICAgKiB0byB1c2UgaW1wbGVtZW50YXRpb24tc3BlY2lmaWMgY3VzdG9tIG1lY2hhbmlzbXMKLSAgICAgKiBhcyBsb25nIGFzIHRoZXkgeWllbGQgdGhlIHJlc3VsdCBkZXNjcmliZWQgaW4gdGhlIHNwZWNpZmljYXRpb24uCi0gICAgICogPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIHNjaGVtYSA8Y29kZT5TY2hlbWE8L2NvZGU+IHRvIHVzZSwgPGNvZGU+bnVsbDwvY29kZT4gdG8gcmVtb3ZlIGEgc2NoZW1hLgotICAgICAqCi0gICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBXaGVuIGltcGxlbWVudGF0aW9uIGRvZXMgbm90Ci0gICAgICogICBvdmVycmlkZSB0aGlzIG1ldGhvZAotICAgICAqCi0gICAgICogQHNpbmNlIDEuNQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFNjaGVtYShTY2hlbWEgc2NoZW1hKSB7Ci0gICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigKLSAgICAgICAgICAgICJUaGlzIHBhcnNlciBkb2VzIG5vdCBzdXBwb3J0IHNwZWNpZmljYXRpb24gXCIiCi0gICAgICAgICAgICArIHRoaXMuZ2V0Q2xhc3MoKS5nZXRQYWNrYWdlKCkuZ2V0U3BlY2lmaWNhdGlvblRpdGxlKCkKLSAgICAgICAgICAgICsgIlwiIHZlcnNpb24gXCIiCi0gICAgICAgICAgICArIHRoaXMuZ2V0Q2xhc3MoKS5nZXRQYWNrYWdlKCkuZ2V0U3BlY2lmaWNhdGlvblZlcnNpb24oKQotICAgICAgICAgICAgKyAiXCIiCi0gICAgICAgICAgICApOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPlNldCBzdGF0ZSBvZiBYSW5jbHVkZSBwcm9jZXNzaW5nLjwvcD4KLSAgICAgKgotICAgICAqIDxwPklmIFhJbmNsdWRlIG1hcmt1cCBpcyBmb3VuZCBpbiB0aGUgZG9jdW1lbnQgaW5zdGFuY2UsIHNob3VsZCBpdCBiZQotICAgICAqIHByb2Nlc3NlZCBhcyBzcGVjaWZpZWQgaW4gPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveGluY2x1ZGUvIj4KLSAgICAgKiBYTUwgSW5jbHVzaW9ucyAoWEluY2x1ZGUpIFZlcnNpb24gMS4wPC9hPi48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5YSW5jbHVkZSBwcm9jZXNzaW5nIGRlZmF1bHRzIHRvIDxjb2RlPmZhbHNlPC9jb2RlPi48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gc3RhdGUgU2V0IFhJbmNsdWRlIHByb2Nlc3NpbmcgdG8gPGNvZGU+dHJ1ZTwvY29kZT4gb3IKLSAgICAgKiAgIDxjb2RlPmZhbHNlPC9jb2RlPgotICAgICAqCi0gICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBXaGVuIGltcGxlbWVudGF0aW9uIGRvZXMgbm90Ci0gICAgICogICBvdmVycmlkZSB0aGlzIG1ldGhvZAotICAgICAqCi0gICAgICogQHNpbmNlIDEuNQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFhJbmNsdWRlQXdhcmUoZmluYWwgYm9vbGVhbiBzdGF0ZSkgewotICAgICAgICBpZiAoc3RhdGUpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiIHNldFhJbmNsdWRlQXdhcmUgIiArCi0gICAgICAgICAgICAgICAgImlzIG5vdCBzdXBwb3J0ZWQgb24gdGhpcyBKQVhQIiAgKwotICAgICAgICAgICAgICAgICIgaW1wbGVtZW50YXRpb24gb3IgZWFybGllcjogIiArIHRoaXMuZ2V0Q2xhc3MoKSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5HZXQgc3RhdGUgb2YgWEluY2x1ZGUgcHJvY2Vzc2luZy48L3A+Ci0gICAgICoKLSAgICAgKiBAcmV0dXJuIGN1cnJlbnQgc3RhdGUgb2YgWEluY2x1ZGUgcHJvY2Vzc2luZwotICAgICAqCi0gICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBXaGVuIGltcGxlbWVudGF0aW9uIGRvZXMgbm90Ci0gICAgICogICBvdmVycmlkZSB0aGlzIG1ldGhvZAotICAgICAqCi0gICAgICogQHNpbmNlIDEuNQotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzWEluY2x1ZGVBd2FyZSgpIHsKLSAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKAotICAgICAgICAgICAgIlRoaXMgcGFyc2VyIGRvZXMgbm90IHN1cHBvcnQgc3BlY2lmaWNhdGlvbiBcIiIKLSAgICAgICAgICAgICsgdGhpcy5nZXRDbGFzcygpLmdldFBhY2thZ2UoKS5nZXRTcGVjaWZpY2F0aW9uVGl0bGUoKQotICAgICAgICAgICAgKyAiXCIgdmVyc2lvbiBcIiIKLSAgICAgICAgICAgICsgdGhpcy5nZXRDbGFzcygpLmdldFBhY2thZ2UoKS5nZXRTcGVjaWZpY2F0aW9uVmVyc2lvbigpCi0gICAgICAgICAgICArICJcIiIKLSAgICAgICAgICAgICk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmF4L3htbC9wYXJzZXJzL1NlY3VyaXR5U3VwcG9ydC5qYXZhIGIvc3JjL2phdmF4L3htbC9wYXJzZXJzL1NlY3VyaXR5U3VwcG9ydC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhMjg3OGNhLi4wMDAwMDAwCi0tLSBhL3NyYy9qYXZheC94bWwvcGFyc2Vycy9TZWN1cml0eVN1cHBvcnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExMCArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDA0LCAyMDA2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi1wYWNrYWdlIGphdmF4LnhtbC5wYXJzZXJzOwotCi1pbXBvcnQgamF2YS5zZWN1cml0eS4qOwotaW1wb3J0IGphdmEubmV0Lio7Ci1pbXBvcnQgamF2YS5pby4qOwotaW1wb3J0IGphdmEudXRpbC4qOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgaXMgZHVwbGljYXRlZCBmb3IgZWFjaCBKQVhQIHN1YnBhY2thZ2Ugc28ga2VlcCBpdCBpbiBzeW5jLgotICogSXQgaXMgcGFja2FnZSBwcml2YXRlIGFuZCB0aGVyZWZvcmUgaXMgbm90IGV4cG9zZWQgYXMgcGFydCBvZiB0aGUgSkFYUAotICogQVBJLgotICoKLSAqIFNlY3VyaXR5IHJlbGF0ZWQgbWV0aG9kcyB0aGF0IG9ubHkgd29yayBvbiBKMlNFIDEuMiBhbmQgbmV3ZXIuCi0gKi8KLWNsYXNzIFNlY3VyaXR5U3VwcG9ydCAgewotCi0KLSAgICBDbGFzc0xvYWRlciBnZXRDb250ZXh0Q2xhc3NMb2FkZXIoKSB0aHJvd3MgU2VjdXJpdHlFeGNlcHRpb257Ci0gICAgICAgIHJldHVybiAoQ2xhc3NMb2FkZXIpCi0gICAgICAgICAgICAgICAgQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQobmV3IFByaXZpbGVnZWRBY3Rpb24oKSB7Ci0gICAgICAgICAgICBwdWJsaWMgT2JqZWN0IHJ1bigpIHsKLSAgICAgICAgICAgICAgICBDbGFzc0xvYWRlciBjbCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgLy90cnkgewotICAgICAgICAgICAgICAgIGNsID0gVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5nZXRDb250ZXh0Q2xhc3NMb2FkZXIoKTsKLSAgICAgICAgICAgICAgICAvL30gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIGV4KSB7IH0KLQotICAgICAgICAgICAgICAgIGlmIChjbCA9PSBudWxsKQotICAgICAgICAgICAgICAgICAgICBjbCA9IENsYXNzTG9hZGVyLmdldFN5c3RlbUNsYXNzTG9hZGVyKCk7Ci0KLSAgICAgICAgICAgICAgICByZXR1cm4gY2w7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0pOwotICAgIH0KLQotICAgIFN0cmluZyBnZXRTeXN0ZW1Qcm9wZXJ0eShmaW5hbCBTdHJpbmcgcHJvcE5hbWUpIHsKLSAgICAgICAgcmV0dXJuIChTdHJpbmcpCi0gICAgICAgICAgICBBY2Nlc3NDb250cm9sbGVyLmRvUHJpdmlsZWdlZChuZXcgUHJpdmlsZWdlZEFjdGlvbigpIHsKLSAgICAgICAgICAgICAgICBwdWJsaWMgT2JqZWN0IHJ1bigpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFN5c3RlbS5nZXRQcm9wZXJ0eShwcm9wTmFtZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfSk7Ci0gICAgfQotCi0gICAgRmlsZUlucHV0U3RyZWFtIGdldEZpbGVJbnB1dFN0cmVhbShmaW5hbCBGaWxlIGZpbGUpCi0gICAgICAgIHRocm93cyBGaWxlTm90Rm91bmRFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICByZXR1cm4gKEZpbGVJbnB1dFN0cmVhbSkKLSAgICAgICAgICAgICAgICBBY2Nlc3NDb250cm9sbGVyLmRvUHJpdmlsZWdlZChuZXcgUHJpdmlsZWdlZEV4Y2VwdGlvbkFjdGlvbigpIHsKLSAgICAgICAgICAgICAgICAgICAgcHVibGljIE9iamVjdCBydW4oKSB0aHJvd3MgRmlsZU5vdEZvdW5kRXhjZXB0aW9uIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgRmlsZUlucHV0U3RyZWFtKGZpbGUpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfSk7Ci0gICAgICAgIH0gY2F0Y2ggKFByaXZpbGVnZWRBY3Rpb25FeGNlcHRpb24gZSkgewotICAgICAgICAgICAgdGhyb3cgKEZpbGVOb3RGb3VuZEV4Y2VwdGlvbillLmdldEV4Y2VwdGlvbigpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgSW5wdXRTdHJlYW0gZ2V0UmVzb3VyY2VBc1N0cmVhbShmaW5hbCBDbGFzc0xvYWRlciBjbCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgbmFtZSkKLSAgICB7Ci0gICAgICAgIHJldHVybiAoSW5wdXRTdHJlYW0pCi0gICAgICAgICAgICBBY2Nlc3NDb250cm9sbGVyLmRvUHJpdmlsZWdlZChuZXcgUHJpdmlsZWdlZEFjdGlvbigpIHsKLSAgICAgICAgICAgICAgICBwdWJsaWMgT2JqZWN0IHJ1bigpIHsKLSAgICAgICAgICAgICAgICAgICAgSW5wdXRTdHJlYW0gcmlzOwotICAgICAgICAgICAgICAgICAgICBpZiAoY2wgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgcmlzID0gT2JqZWN0LmNsYXNzLmdldFJlc291cmNlQXNTdHJlYW0obmFtZSk7Ci0gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByaXMgPSBjbC5nZXRSZXNvdXJjZUFzU3RyZWFtKG5hbWUpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiByaXM7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfSk7Ci0gICAgfQotCi0gICAgYm9vbGVhbiBkb2VzRmlsZUV4aXN0KGZpbmFsIEZpbGUgZikgewotICAgIHJldHVybiAoKEJvb2xlYW4pCi0gICAgICAgICAgICBBY2Nlc3NDb250cm9sbGVyLmRvUHJpdmlsZWdlZChuZXcgUHJpdmlsZWdlZEFjdGlvbigpIHsKLSAgICAgICAgICAgICAgICBwdWJsaWMgT2JqZWN0IHJ1bigpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBCb29sZWFuKGYuZXhpc3RzKCkpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0pKS5ib29sZWFuVmFsdWUoKTsKLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9qYXZheC94bWwvcGFyc2Vycy9wYWNrYWdlLmh0bWwgYi9zcmMvamF2YXgveG1sL3BhcnNlcnMvcGFja2FnZS5odG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1MjA5MjExLi4wMDAwMDAwCi0tLSBhL3NyYy9qYXZheC94bWwvcGFyc2Vycy9wYWNrYWdlLmh0bWwKKysrIC9kZXYvbnVsbApAQCAtMSw1MSArMCwwIEBACi08P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJVVEYtOCI/PgotPCEtLQotQ29weXJpZ2h0IChjKSAyMDAwLCAyMDA1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotCi1UaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLXB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0KLVRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi1GSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLXZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci1hY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotCi1Zb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0yIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi1JbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0KLVBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi1vciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci1xdWVzdGlvbnMuIAotLS0+Ci0KLTwhRE9DVFlQRSBodG1sCi0gICAgIFBVQkxJQyAiLS8vVzNDLy9EVEQgWEhUTUwgMS4wIFN0cmljdC8vRU4iCi0gICAgICJodHRwOi8vd3d3LnczLm9yZy9UUi94aHRtbDEvRFREL3hodG1sMS1zdHJpY3QuZHRkIj4KLQotPGh0bWwgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwiPgotCi08aGVhZD4KLSAgPHRpdGxlPmphdmF4LnhtbC5wYXJzZXJzPC90aXRsZT4KLQotICA8bWV0YSBuYW1lPSJDVlMiCi0gICAgICAgIGNvbnRlbnQ9IiRJZDogcGFja2FnZS5odG1sLHYgMS4yIDIwMDUvMDYvMTAgMDM6NTA6MjkgamVmZnN1dHRvciBFeHAgJCIgLz4KLSAgPG1ldGEgbmFtZT0iQVVUSE9SIgotICAgICAgICBjb250ZW50PSJKZWZmLlN1dHRvckBTdW4uY29tIiAvPgotPC9oZWFkPgotPGJvZHk+Ci0JPHA+Ci0JCVByb3ZpZGVzIGNsYXNzZXMgYWxsb3dpbmcgdGhlIHByb2Nlc3Npbmcgb2YgWE1MIGRvY3VtZW50cy4gVHdvIHR5cGVzCi0JCW9mIHBsdWdhYmxlIHBhcnNlcnMgYXJlIHN1cHBvcnRlZDoKLQk8L3A+Ci0JPHVsPgotCQk8bGk+U0FYIChTaW1wbGUgQVBJIGZvciBYTUwpPC9saT4KLQkJPGxpPkRPTSAoRG9jdW1lbnQgT2JqZWN0IE1vZGVsKTwvbGk+Ci0JPC91bD4KLTwvYm9keT4KLTwvaHRtbD4KZGlmZiAtLWdpdCBhL3NyYy9qYXZheC94bWwvc3RyZWFtL0V2ZW50RmlsdGVyLmphdmEgYi9zcmMvamF2YXgveG1sL3N0cmVhbS9FdmVudEZpbHRlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2MWZlZWNiLi4wMDAwMDAwCi0tLSBhL3NyYy9qYXZheC94bWwvc3RyZWFtL0V2ZW50RmlsdGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw1MCArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogQ29weXJpZ2h0IChjKSAyMDA5IGJ5IE9yYWNsZSBDb3Jwb3JhdGlvbi4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KLSAqLwotCi1wYWNrYWdlIGphdmF4LnhtbC5zdHJlYW07Ci0KLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLmV2ZW50cy5YTUxFdmVudDsKLQotLyoqCi0gKiBUaGlzIGludGVyZmFjZSBkZWNsYXJlcyBhIHNpbXBsZSBmaWx0ZXIgaW50ZXJmYWNlIHRoYXQgb25lIGNhbgotICogY3JlYXRlIHRvIGZpbHRlciBYTUxFdmVudFJlYWRlcnMKLSAqIEB2ZXJzaW9uIDEuMAotICogQGF1dGhvciBDb3B5cmlnaHQgKGMpIDIwMDkgYnkgT3JhY2xlIENvcnBvcmF0aW9uLiBBbGwgUmlnaHRzIFJlc2VydmVkLgotICogQHNpbmNlIDEuNgotICovCi1wdWJsaWMgaW50ZXJmYWNlIEV2ZW50RmlsdGVyIHsKLSAgLyoqCi0gICAqIFRlc3RzIHdoZXRoZXIgdGhpcyBldmVudCBpcyBwYXJ0IG9mIHRoaXMgc3RyZWFtLiAgVGhpcyBtZXRob2QKLSAgICogd2lsbCByZXR1cm4gdHJ1ZSBpZiB0aGlzIGZpbHRlciBhY2NlcHRzIHRoaXMgZXZlbnQgYW5kIGZhbHNlCi0gICAqIG90aGVyd2lzZS4KLSAgICoKLSAgICogQHBhcmFtIGV2ZW50IHRoZSBldmVudCB0byB0ZXN0Ci0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGlzIGZpbHRlciBhY2NlcHRzIHRoaXMgZXZlbnQsIGZhbHNlIG90aGVyd2lzZQotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gYWNjZXB0KFhNTEV2ZW50IGV2ZW50KTsKLX0KZGlmZiAtLWdpdCBhL3NyYy9qYXZheC94bWwvc3RyZWFtL0ZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IuamF2YSBiL3NyYy9qYXZheC94bWwvc3RyZWFtL0ZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNjE5MmYzZC4uMDAwMDAwMAotLS0gYS9zcmMvamF2YXgveG1sL3N0cmVhbS9GYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMjUgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwOSBieSBPcmFjbGUgQ29ycG9yYXRpb24uIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCi0gKi8KLQotcGFja2FnZSBqYXZheC54bWwuc3RyZWFtOwotCi0vKioKLSAqIEFuIGVycm9yIGNsYXNzIGZvciByZXBvcnRpbmcgZmFjdG9yeSBjb25maWd1cmF0aW9uIGVycm9ycy4KLSAqCi0gKiBAdmVyc2lvbiAxLjAKLSAqIEBhdXRob3IgQ29weXJpZ2h0IChjKSAyMDA5IGJ5IE9yYWNsZSBDb3Jwb3JhdGlvbi4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KLSAqIEBzaW5jZSAxLjYKLSAqLwotcHVibGljIGNsYXNzIEZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IgZXh0ZW5kcyBFcnJvciB7Ci0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTI5OTQ0MTI1ODQ1ODk5NzU3NDRMOwotCi0gIEV4Y2VwdGlvbiBuZXN0ZWQ7Ci0KLSAgLyoqCi0gICAqIERlZmF1bHQgY29uc3RydWN0b3IKLSAgICovCi0gIHB1YmxpYyBGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yKCl7fQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYW4gZXhjZXB0aW9uIHdpdGggYSBuZXN0ZWQgaW5uZXIgZXhjZXB0aW9uCi0gICAqCi0gICAqIEBwYXJhbSBlIHRoZSBleGNlcHRpb24gdG8gbmVzdAotICAgKi8KLSAgcHVibGljIEZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IoamF2YS5sYW5nLkV4Y2VwdGlvbiBlKXsKLSAgICBuZXN0ZWQgPSBlOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhbiBleGNlcHRpb24gd2l0aCBhIG5lc3RlZCBpbm5lciBleGNlcHRpb24KLSAgICogYW5kIGEgbWVzc2FnZQotICAgKgotICAgKiBAcGFyYW0gZSB0aGUgZXhjZXB0aW9uIHRvIG5lc3QKLSAgICogQHBhcmFtIG1zZyB0aGUgbWVzc2FnZSB0byByZXBvcnQKLSAgICovCi0gIHB1YmxpYyBGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yKGphdmEubGFuZy5FeGNlcHRpb24gZSwgamF2YS5sYW5nLlN0cmluZyBtc2cpewotICAgIHN1cGVyKG1zZyk7Ci0gICAgbmVzdGVkID0gZTsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYW4gZXhjZXB0aW9uIHdpdGggYSBuZXN0ZWQgaW5uZXIgZXhjZXB0aW9uCi0gICAqIGFuZCBhIG1lc3NhZ2UKLSAgICoKLSAgICogQHBhcmFtIG1zZyB0aGUgbWVzc2FnZSB0byByZXBvcnQKLSAgICogQHBhcmFtIGUgdGhlIGV4Y2VwdGlvbiB0byBuZXN0Ci0gICAqLwotICBwdWJsaWMgRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvcihqYXZhLmxhbmcuU3RyaW5nIG1zZywgamF2YS5sYW5nLkV4Y2VwdGlvbiBlKXsKLSAgICBzdXBlcihtc2cpOwotICAgIG5lc3RlZCA9IGU7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IGFuIGV4Y2VwdGlvbiB3aXRoIGFzc29jaWF0ZWQgbWVzc2FnZQotICAgKgotICAgKiBAcGFyYW0gbXNnIHRoZSBtZXNzYWdlIHRvIHJlcG9ydAotICAgKi8KLSAgcHVibGljIEZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IoamF2YS5sYW5nLlN0cmluZyBtc2cpIHsKLSAgICBzdXBlcihtc2cpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgbmVzdGVkIGV4Y2VwdGlvbiAoaWYgYW55KQotICAgKgotICAgKiBAcmV0dXJuIHRoZSBuZXN0ZWQgZXhjZXB0aW9uIG9yIG51bGwKLSAgICovCi0gIHB1YmxpYyBFeGNlcHRpb24gZ2V0RXhjZXB0aW9uKCkgewotICAgIHJldHVybiBuZXN0ZWQ7Ci0gIH0KLSAgICAvKioKLSAgICAgKiB1c2UgdGhlIGV4Y2VwdGlvbiBjaGFpbmluZyBtZWNoYW5pc20gb2YgSkRLMS40Ci0gICAgKi8KLSAgICBAT3ZlcnJpZGUKLSAgICBwdWJsaWMgVGhyb3dhYmxlIGdldENhdXNlKCkgewotICAgICAgICByZXR1cm4gbmVzdGVkOwotICAgIH0KLQotICAvKioKLSAgICogUmVwb3J0IHRoZSBtZXNzYWdlIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGVycm9yCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIHN0cmluZyB2YWx1ZSBvZiB0aGUgbWVzc2FnZQotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRNZXNzYWdlKCkgewotICAgIFN0cmluZyBtc2cgPSBzdXBlci5nZXRNZXNzYWdlKCk7Ci0gICAgaWYobXNnICE9IG51bGwpCi0gICAgICByZXR1cm4gbXNnOwotICAgIGlmKG5lc3RlZCAhPSBudWxsKXsKLSAgICAgIG1zZyA9IG5lc3RlZC5nZXRNZXNzYWdlKCk7Ci0gICAgICBpZihtc2cgPT0gbnVsbCkKLSAgICAgICAgbXNnID0gbmVzdGVkLmdldENsYXNzKCkudG9TdHJpbmcoKTsKLSAgICB9Ci0gICAgcmV0dXJuIG1zZzsKLSAgfQotCi0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmF4L3htbC9zdHJlYW0vRmFjdG9yeUZpbmRlci5qYXZhIGIvc3JjL2phdmF4L3htbC9zdHJlYW0vRmFjdG9yeUZpbmRlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmMzRkMGY4Li4wMDAwMDAwCi0tLSBhL3NyYy9qYXZheC94bWwvc3RyZWFtL0ZhY3RvcnlGaW5kZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDM3NSArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDEzLCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi1wYWNrYWdlIGphdmF4LnhtbC5zdHJlYW07Ci0KLWltcG9ydCBqYXZhLmlvLkZpbGU7Ci1pbXBvcnQgamF2YS5zZWN1cml0eS5BY2Nlc3NDb250cm9sbGVyOwotaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpdmlsZWdlZEFjdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7Ci1pbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7Ci1pbXBvcnQgamF2YS51dGlsLlNlcnZpY2VDb25maWd1cmF0aW9uRXJyb3I7Ci1pbXBvcnQgamF2YS51dGlsLlNlcnZpY2VMb2FkZXI7Ci0KLS8qKgotICogPHA+SW1wbGVtZW50cyBwbHVnZ2FibGUgc3RyZWFtcy48L3A+Ci0gKgotICogPHA+VGhpcyBjbGFzcyBpcyBkdXBsaWNhdGVkIGZvciBlYWNoIEpBWFAgc3VicGFja2FnZSBzbyBrZWVwIGl0IGluCi0gKiBzeW5jLiAgSXQgaXMgcGFja2FnZSBwcml2YXRlIGZvciBzZWN1cmUgY2xhc3MgbG9hZGluZy48L3A+Ci0gKgotICogQGF1dGhvciBTYW50aWFnby5QZXJpY2FzR2VlcnRzZW5Ac3VuLmNvbQotICovCi1jbGFzcyBGYWN0b3J5RmluZGVyIHsKLSAgICAvLyBDaGVjayB3ZSBoYXZlIGFjY2VzcyB0byBwYWNrYWdlLgotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBERUZBVUxUX1BBQ0tBR0UgPSAiY29tLnN1bi54bWwuaW50ZXJuYWwuIjsKLQotICAgIC8qKgotICAgICAqIEludGVybmFsIGRlYnVnIGZsYWcuCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBkZWJ1ZyA9IGZhbHNlOwotCi0gICAgLyoqCi0gICAgICogQ2FjaGUgZm9yIHByb3BlcnRpZXMgaW4gamF2YS5ob21lL2xpYi9qYXhwLnByb3BlcnRpZXMKLSAgICAgKi8KLSAgICBmaW5hbCBwcml2YXRlIHN0YXRpYyBQcm9wZXJ0aWVzIGNhY2hlUHJvcHMgPSBuZXcgUHJvcGVydGllcygpOwotCi0gICAgLyoqCi0gICAgICogRmxhZyBpbmRpY2F0aW5nIGlmIHByb3BlcnRpZXMgZnJvbSBqYXZhLmhvbWUvbGliL2pheHAucHJvcGVydGllcwotICAgICAqIGhhdmUgYmVlbiBjYWNoZWQuCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgdm9sYXRpbGUgYm9vbGVhbiBmaXJzdFRpbWUgPSB0cnVlOwotCi0gICAgLyoqCi0gICAgICogU2VjdXJpdHkgc3VwcG9ydCBjbGFzcyB1c2UgdG8gY2hlY2sgYWNjZXNzIGNvbnRyb2wgYmVmb3JlCi0gICAgICogZ2V0dGluZyBjZXJ0YWluIHN5c3RlbSByZXNvdXJjZXMuCi0gICAgICovCi0gICAgZmluYWwgcHJpdmF0ZSBzdGF0aWMgU2VjdXJpdHlTdXBwb3J0IHNzID0gbmV3IFNlY3VyaXR5U3VwcG9ydCgpOwotCi0gICAgLy8gRGVmaW5lIHN5c3RlbSBwcm9wZXJ0eSAiamF4cC5kZWJ1ZyIgdG8gZ2V0IG91dHB1dAotICAgIHN0YXRpYyB7Ci0gICAgICAgIC8vIFVzZSB0cnkvY2F0Y2ggYmxvY2sgdG8gc3VwcG9ydCBhcHBsZXRzLCB3aGljaCB0aHJvd3MKLSAgICAgICAgLy8gU2VjdXJpdHlFeGNlcHRpb24gb3V0IG9mIHRoaXMgY29kZS4KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIFN0cmluZyB2YWwgPSBzcy5nZXRTeXN0ZW1Qcm9wZXJ0eSgiamF4cC5kZWJ1ZyIpOwotICAgICAgICAgICAgLy8gQWxsb3cgc2ltcGx5IHNldHRpbmcgdGhlIHByb3AgdG8gdHVybiBvbiBkZWJ1ZwotICAgICAgICAgICAgZGVidWcgPSB2YWwgIT0gbnVsbCAmJiAhImZhbHNlIi5lcXVhbHModmFsKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gc2UpIHsKLSAgICAgICAgICAgIGRlYnVnID0gZmFsc2U7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGRQcmludChTdHJpbmcgbXNnKSB7Ci0gICAgICAgIGlmIChkZWJ1ZykgewotICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJKQVhQOiAiICsgbXNnKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEF0dGVtcHQgdG8gbG9hZCBhIGNsYXNzIHVzaW5nIHRoZSBjbGFzcyBsb2FkZXIgc3VwcGxpZWQuIElmIHRoYXQgZmFpbHMKLSAgICAgKiBhbmQgZmFsbCBiYWNrIGlzIGVuYWJsZWQsIHRoZSBjdXJyZW50IChpLmUuIGJvb3RzdHJhcCkgY2xhc3MgbG9hZGVyIGlzCi0gICAgICogdHJpZWQuCi0gICAgICoKLSAgICAgKiBJZiB0aGUgY2xhc3MgbG9hZGVyIHN1cHBsaWVkIGlzIDxjb2RlPm51bGw8L2NvZGU+LCBmaXJzdCB0cnkgdXNpbmcgdGhlCi0gICAgICogY29udGV4dCBjbGFzcyBsb2FkZXIgZm9sbG93ZWQgYnkgdGhlIGN1cnJlbnQgKGkuZS4gYm9vdHN0cmFwKSBjbGFzcwotICAgICAqIGxvYWRlci4KLSAgICAgKgotICAgICAqIFVzZSBib290c3RyYXAgY2xhc3NMb2FkZXIgaWYgY2wgPSBudWxsIGFuZCB1c2VCU0Nsc0xvYWRlciBpcyB0cnVlCi0gICAgICovCi0gICAgc3RhdGljIHByaXZhdGUgQ2xhc3MgZ2V0UHJvdmlkZXJDbGFzcyhTdHJpbmcgY2xhc3NOYW1lLCBDbGFzc0xvYWRlciBjbCwKLSAgICAgICAgICAgIGJvb2xlYW4gZG9GYWxsYmFjaywgYm9vbGVhbiB1c2VCU0Nsc0xvYWRlcikgdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBpZiAoY2wgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGlmICh1c2VCU0Nsc0xvYWRlcikgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gQ2xhc3MuZm9yTmFtZShjbGFzc05hbWUsIGZhbHNlLCBGYWN0b3J5RmluZGVyLmNsYXNzLmdldENsYXNzTG9hZGVyKCkpOwotICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIGNsID0gc3MuZ2V0Q29udGV4dENsYXNzTG9hZGVyKCk7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChjbCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbigpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIENsYXNzLmZvck5hbWUoY2xhc3NOYW1lLCBmYWxzZSwgY2wpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIENsYXNzLmZvck5hbWUoY2xhc3NOYW1lLCBmYWxzZSwgY2wpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGUxKSB7Ci0gICAgICAgICAgICBpZiAoZG9GYWxsYmFjaykgewotICAgICAgICAgICAgICAgIC8vIFVzZSBjdXJyZW50IGNsYXNzIGxvYWRlciAtIHNob3VsZCBhbHdheXMgYmUgYm9vdHN0cmFwIENMCi0gICAgICAgICAgICAgICAgcmV0dXJuIENsYXNzLmZvck5hbWUoY2xhc3NOYW1lLCBmYWxzZSwgRmFjdG9yeUZpbmRlci5jbGFzcy5nZXRDbGFzc0xvYWRlcigpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgICAgIHRocm93IGUxOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlIGFuIGluc3RhbmNlIG9mIGEgY2xhc3MuIERlbGVnYXRlcyB0byBtZXRob2QKLSAgICAgKiA8Y29kZT5nZXRQcm92aWRlckNsYXNzKCk8L2NvZGU+IGluIG9yZGVyIHRvIGxvYWQgdGhlIGNsYXNzLgotICAgICAqCi0gICAgICogQHBhcmFtIHR5cGUgQmFzZSBjbGFzcyAvIFNlcnZpY2UgaW50ZXJmYWNlICBvZiB0aGUgZmFjdG9yeSB0bwotICAgICAqICAgICAgICAgICAgIGluc3RhbnRpYXRlLgotICAgICAqCi0gICAgICogQHBhcmFtIGNsYXNzTmFtZSBOYW1lIG9mIHRoZSBjb25jcmV0ZSBjbGFzcyBjb3JyZXNwb25kaW5nIHRvIHRoZQotICAgICAqIHNlcnZpY2UgcHJvdmlkZXIKLSAgICAgKgotICAgICAqIEBwYXJhbSBjbCA8Y29kZT5DbGFzc0xvYWRlcjwvY29kZT4gdXNlZCB0byBsb2FkIHRoZSBmYWN0b3J5IGNsYXNzLiBJZiA8Y29kZT5udWxsPC9jb2RlPgotICAgICAqIGN1cnJlbnQgPGNvZGU+VGhyZWFkPC9jb2RlPidzIGNvbnRleHQgY2xhc3NMb2FkZXIgaXMgdXNlZCB0byBsb2FkIHRoZSBmYWN0b3J5IGNsYXNzLgotICAgICAqCi0gICAgICogQHBhcmFtIGRvRmFsbGJhY2sgVHJ1ZSBpZiB0aGUgY3VycmVudCBDbGFzc0xvYWRlciBzaG91bGQgYmUgdHJpZWQgYXMKLSAgICAgKiBhIGZhbGxiYWNrIGlmIHRoZSBjbGFzcyBpcyBub3QgZm91bmQgdXNpbmcgY2wKLSAgICAgKi8KLSAgICBzdGF0aWMgPFQ+IFQgbmV3SW5zdGFuY2UoQ2xhc3M8VD4gdHlwZSwgU3RyaW5nIGNsYXNzTmFtZSwgQ2xhc3NMb2FkZXIgY2wsIGJvb2xlYW4gZG9GYWxsYmFjaykKLSAgICAgICAgdGhyb3dzIEZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IKLSAgICB7Ci0gICAgICAgIHJldHVybiBuZXdJbnN0YW5jZSh0eXBlLCBjbGFzc05hbWUsIGNsLCBkb0ZhbGxiYWNrLCBmYWxzZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlIGFuIGluc3RhbmNlIG9mIGEgY2xhc3MuIERlbGVnYXRlcyB0byBtZXRob2QKLSAgICAgKiA8Y29kZT5nZXRQcm92aWRlckNsYXNzKCk8L2NvZGU+IGluIG9yZGVyIHRvIGxvYWQgdGhlIGNsYXNzLgotICAgICAqCi0gICAgICogQHBhcmFtIHR5cGUgQmFzZSBjbGFzcyAvIFNlcnZpY2UgaW50ZXJmYWNlICBvZiB0aGUgZmFjdG9yeSB0bwotICAgICAqICAgICAgICAgICAgIGluc3RhbnRpYXRlLgotICAgICAqCi0gICAgICogQHBhcmFtIGNsYXNzTmFtZSBOYW1lIG9mIHRoZSBjb25jcmV0ZSBjbGFzcyBjb3JyZXNwb25kaW5nIHRvIHRoZQotICAgICAqIHNlcnZpY2UgcHJvdmlkZXIKLSAgICAgKgotICAgICAqIEBwYXJhbSBjbCA8Y29kZT5DbGFzc0xvYWRlcjwvY29kZT4gdXNlZCB0byBsb2FkIHRoZSBmYWN0b3J5IGNsYXNzLiBJZiA8Y29kZT5udWxsPC9jb2RlPgotICAgICAqIGN1cnJlbnQgPGNvZGU+VGhyZWFkPC9jb2RlPidzIGNvbnRleHQgY2xhc3NMb2FkZXIgaXMgdXNlZCB0byBsb2FkIHRoZSBmYWN0b3J5IGNsYXNzLgotICAgICAqCi0gICAgICogQHBhcmFtIGRvRmFsbGJhY2sgVHJ1ZSBpZiB0aGUgY3VycmVudCBDbGFzc0xvYWRlciBzaG91bGQgYmUgdHJpZWQgYXMKLSAgICAgKiBhIGZhbGxiYWNrIGlmIHRoZSBjbGFzcyBpcyBub3QgZm91bmQgdXNpbmcgY2wKLSAgICAgKgotICAgICAqIEBwYXJhbSB1c2VCU0Nsc0xvYWRlciBUcnVlIGlmIGNsPW51bGwgYWN0dWFsbHkgbWVhbnQgYm9vdHN0cmFwIGNsYXNzTG9hZGVyLiBUaGlzIHBhcmFtZXRlcgotICAgICAqIGlzIG5lZWRlZCBzaW5jZSBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5L1NBWFBhcnNlckZhY3RvcnkgZGVmaW5lZCBudWxsIGFzIGNvbnRleHQgY2xhc3NMb2FkZXIuCi0gICAgICovCi0gICAgc3RhdGljIDxUPiBUIG5ld0luc3RhbmNlKENsYXNzPFQ+IHR5cGUsIFN0cmluZyBjbGFzc05hbWUsIENsYXNzTG9hZGVyIGNsLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBkb0ZhbGxiYWNrLCBib29sZWFuIHVzZUJTQ2xzTG9hZGVyKQotICAgICAgICB0aHJvd3MgRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvcgotICAgIHsKLSAgICAgICAgYXNzZXJ0IHR5cGUgIT0gbnVsbDsKLQotICAgICAgICAvLyBtYWtlIHN1cmUgd2UgaGF2ZSBhY2Nlc3MgdG8gcmVzdHJpY3RlZCBwYWNrYWdlcwotICAgICAgICBpZiAoU3lzdGVtLmdldFNlY3VyaXR5TWFuYWdlcigpICE9IG51bGwpIHsKLSAgICAgICAgICAgIGlmIChjbGFzc05hbWUgIT0gbnVsbCAmJiBjbGFzc05hbWUuc3RhcnRzV2l0aChERUZBVUxUX1BBQ0tBR0UpKSB7Ci0gICAgICAgICAgICAgICAgY2wgPSBudWxsOwotICAgICAgICAgICAgICAgIHVzZUJTQ2xzTG9hZGVyID0gdHJ1ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBDbGFzczw/PiBwcm92aWRlckNsYXNzID0gZ2V0UHJvdmlkZXJDbGFzcyhjbGFzc05hbWUsIGNsLCBkb0ZhbGxiYWNrLCB1c2VCU0Nsc0xvYWRlcik7Ci0gICAgICAgICAgICBpZiAoIXR5cGUuaXNBc3NpZ25hYmxlRnJvbShwcm92aWRlckNsYXNzKSkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBDbGFzc0Nhc3RFeGNlcHRpb24oY2xhc3NOYW1lICsgIiBjYW5ub3QgYmUgY2FzdCB0byAiICsgdHlwZS5nZXROYW1lKCkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgT2JqZWN0IGluc3RhbmNlID0gcHJvdmlkZXJDbGFzcy5uZXdJbnN0YW5jZSgpOwotICAgICAgICAgICAgaWYgKGRlYnVnKSB7ICAgIC8vIEV4dHJhIGNoZWNrIHRvIGF2b2lkIGNvbXB1dGluZyBjbCBzdHJpbmdzCi0gICAgICAgICAgICAgICAgZFByaW50KCJjcmVhdGVkIG5ldyBpbnN0YW5jZSBvZiAiICsgcHJvdmlkZXJDbGFzcyArCi0gICAgICAgICAgICAgICAgICAgICAgICIgdXNpbmcgQ2xhc3NMb2FkZXI6ICIgKyBjbCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gdHlwZS5jYXN0KGluc3RhbmNlKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB4KSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvcigKLSAgICAgICAgICAgICAgICAiUHJvdmlkZXIgIiArIGNsYXNzTmFtZSArICIgbm90IGZvdW5kIiwgeCk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiB4KSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvcigKLSAgICAgICAgICAgICAgICAiUHJvdmlkZXIgIiArIGNsYXNzTmFtZSArICIgY291bGQgbm90IGJlIGluc3RhbnRpYXRlZDogIiArIHgsCi0gICAgICAgICAgICAgICAgeCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBGaW5kcyB0aGUgaW1wbGVtZW50YXRpb24gQ2xhc3Mgb2JqZWN0IGluIHRoZSBzcGVjaWZpZWQgb3JkZXIuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIENsYXNzIG9iamVjdCBvZiBmYWN0b3J5LCBuZXZlciBudWxsCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdHlwZSAgICAgICAgICAgICAgICAgIEJhc2UgY2xhc3MgLyBTZXJ2aWNlIGludGVyZmFjZSAgb2YgdGhlCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWN0b3J5IHRvIGZpbmQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZmFsbGJhY2tDbGFzc05hbWUgICAgIEltcGxlbWVudGF0aW9uIGNsYXNzIG5hbWUsIGlmIG5vdGhpbmcgZWxzZQotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXMgZm91bmQuICBVc2UgbnVsbCB0byBtZWFuIG5vIGZhbGxiYWNrLgotICAgICAqCi0gICAgICogUGFja2FnZSBwcml2YXRlIHNvIHRoaXMgY29kZSBjYW4gYmUgc2hhcmVkLgotICAgICAqLwotICAgIHN0YXRpYyA8VD4gVCBmaW5kKENsYXNzPFQ+IHR5cGUsIFN0cmluZyBmYWxsYmFja0NsYXNzTmFtZSkKLSAgICAgICAgdGhyb3dzIEZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IKLSAgICB7Ci0gICAgICAgIHJldHVybiBmaW5kKHR5cGUsIHR5cGUuZ2V0TmFtZSgpLCBudWxsLCBmYWxsYmFja0NsYXNzTmFtZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRmluZHMgdGhlIGltcGxlbWVudGF0aW9uIENsYXNzIG9iamVjdCBpbiB0aGUgc3BlY2lmaWVkIG9yZGVyLiAgTWFpbgotICAgICAqIGVudHJ5IHBvaW50LgotICAgICAqIEByZXR1cm4gQ2xhc3Mgb2JqZWN0IG9mIGZhY3RvcnksIG5ldmVyIG51bGwKLSAgICAgKgotICAgICAqIEBwYXJhbSB0eXBlICAgICAgICAgICAgICAgICAgQmFzZSBjbGFzcyAvIFNlcnZpY2UgaW50ZXJmYWNlICBvZiB0aGUKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhY3RvcnkgdG8gZmluZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBmYWN0b3J5SWQgICAgICAgICAgICAgTmFtZSBvZiB0aGUgZmFjdG9yeSB0byBmaW5kLCBzYW1lIGFzCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhIHByb3BlcnR5IG5hbWUKLSAgICAgKgotICAgICAqIEBwYXJhbSBjbCAgICAgICAgICAgICAgICAgICAgQ2xhc3NMb2FkZXIgdG8gYmUgdXNlZCB0byBsb2FkIHRoZSBjbGFzcywgbnVsbCBtZWFucyB0byB1c2UKLSAgICAgKiB0aGUgYm9vdHN0cmFwIENsYXNzTG9hZGVyCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZmFsbGJhY2tDbGFzc05hbWUgICAgIEltcGxlbWVudGF0aW9uIGNsYXNzIG5hbWUsIGlmIG5vdGhpbmcgZWxzZQotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXMgZm91bmQuICBVc2UgbnVsbCB0byBtZWFuIG5vIGZhbGxiYWNrLgotICAgICAqCi0gICAgICogUGFja2FnZSBwcml2YXRlIHNvIHRoaXMgY29kZSBjYW4gYmUgc2hhcmVkLgotICAgICAqLwotICAgIHN0YXRpYyA8VD4gVCBmaW5kKENsYXNzPFQ+IHR5cGUsIFN0cmluZyBmYWN0b3J5SWQsIENsYXNzTG9hZGVyIGNsLCBTdHJpbmcgZmFsbGJhY2tDbGFzc05hbWUpCi0gICAgICAgIHRocm93cyBGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yCi0gICAgewotICAgICAgICBkUHJpbnQoImZpbmQgZmFjdG9yeUlkID0iICsgZmFjdG9yeUlkKTsKLQotICAgICAgICAvLyBVc2UgdGhlIHN5c3RlbSBwcm9wZXJ0eSBmaXJzdAotICAgICAgICB0cnkgewotCi0gICAgICAgICAgICBmaW5hbCBTdHJpbmcgc3lzdGVtUHJvcDsKLSAgICAgICAgICAgIGlmICh0eXBlLmdldE5hbWUoKS5lcXVhbHMoZmFjdG9yeUlkKSkgewotICAgICAgICAgICAgICAgIHN5c3RlbVByb3AgPSBzcy5nZXRTeXN0ZW1Qcm9wZXJ0eShmYWN0b3J5SWQpOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBzeXN0ZW1Qcm9wID0gU3lzdGVtLmdldFByb3BlcnR5KGZhY3RvcnlJZCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoc3lzdGVtUHJvcCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZFByaW50KCJmb3VuZCBzeXN0ZW0gcHJvcGVydHksIHZhbHVlPSIgKyBzeXN0ZW1Qcm9wKTsKLSAgICAgICAgICAgICAgICByZXR1cm4gbmV3SW5zdGFuY2UodHlwZSwgc3lzdGVtUHJvcCwgY2wsIHRydWUpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBzZSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IEZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IoCi0gICAgICAgICAgICAgICAgICAgICJGYWlsZWQgdG8gcmVhZCBmYWN0b3J5SWQgJyIgKyBmYWN0b3J5SWQgKyAiJyIsIHNlKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIFRyeSByZWFkICRqYXZhLmhvbWUvbGliL3N0YXgucHJvcGVydGllcyBmb2xsb3dlZCBieQotICAgICAgICAvLyAkamF2YS5ob21lL2xpYi9qYXhwLnByb3BlcnRpZXMgaWYgZm9ybWVyIG5vdCBwcmVzZW50Ci0gICAgICAgIFN0cmluZyBjb25maWdGaWxlID0gbnVsbDsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGlmIChmaXJzdFRpbWUpIHsKLSAgICAgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKGNhY2hlUHJvcHMpIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGZpcnN0VGltZSkgewotICAgICAgICAgICAgICAgICAgICAgICAgY29uZmlnRmlsZSA9IHNzLmdldFN5c3RlbVByb3BlcnR5KCJqYXZhLmhvbWUiKSArIEZpbGUuc2VwYXJhdG9yICsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAibGliIiArIEZpbGUuc2VwYXJhdG9yICsgInN0YXgucHJvcGVydGllcyI7Ci0gICAgICAgICAgICAgICAgICAgICAgICBGaWxlIGYgPSBuZXcgRmlsZShjb25maWdGaWxlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZpcnN0VGltZSA9IGZhbHNlOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNzLmRvZXNGaWxlRXhpc3QoZikpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBkUHJpbnQoIlJlYWQgcHJvcGVydGllcyBmaWxlICIrZik7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FjaGVQcm9wcy5sb2FkKHNzLmdldEZpbGVJbnB1dFN0cmVhbShmKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25maWdGaWxlID0gc3MuZ2V0U3lzdGVtUHJvcGVydHkoImphdmEuaG9tZSIpICsgRmlsZS5zZXBhcmF0b3IgKwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibGliIiArIEZpbGUuc2VwYXJhdG9yICsgImpheHAucHJvcGVydGllcyI7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZiA9IG5ldyBGaWxlKGNvbmZpZ0ZpbGUpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzcy5kb2VzRmlsZUV4aXN0KGYpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRQcmludCgiUmVhZCBwcm9wZXJ0aWVzIGZpbGUgIitmKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FjaGVQcm9wcy5sb2FkKHNzLmdldEZpbGVJbnB1dFN0cmVhbShmKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZmluYWwgU3RyaW5nIGZhY3RvcnlDbGFzc05hbWUgPSBjYWNoZVByb3BzLmdldFByb3BlcnR5KGZhY3RvcnlJZCk7Ci0KLSAgICAgICAgICAgIGlmIChmYWN0b3J5Q2xhc3NOYW1lICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBkUHJpbnQoImZvdW5kIGluICIgKyBjb25maWdGaWxlICsgIiB2YWx1ZT0iICsgZmFjdG9yeUNsYXNzTmFtZSk7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIG5ld0luc3RhbmNlKHR5cGUsIGZhY3RvcnlDbGFzc05hbWUsIGNsLCB0cnVlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7Ci0gICAgICAgICAgICBpZiAoZGVidWcpIGV4LnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKHR5cGUuZ2V0TmFtZSgpLmVxdWFscyhmYWN0b3J5SWQpKSB7Ci0gICAgICAgICAgICAvLyBUcnkgSmFyIFNlcnZpY2UgUHJvdmlkZXIgTWVjaGFuaXNtCi0gICAgICAgICAgICBmaW5hbCBUIHByb3ZpZGVyID0gZmluZFNlcnZpY2VQcm92aWRlcih0eXBlLCBjbCk7Ci0gICAgICAgICAgICBpZiAocHJvdmlkZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJldHVybiBwcm92aWRlcjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIC8vIFdlJ3JlIGluIHRoZSBjYXNlIHdoZXJlIGEgJ2N1c3RvbScgZmFjdG9yeUlkIHdhcyBwcm92aWRlZCwKLSAgICAgICAgICAgIC8vIGFuZCBpbiBldmVyeSBjYXNlIHdoZXJlIHRoYXQgaGFwcGVucywgd2UgZXhwZWN0IHRoYXQKLSAgICAgICAgICAgIC8vIGZhbGxiYWNrQ2xhc3NOYW1lIHdpbGwgYmUgbnVsbC4KLSAgICAgICAgICAgIGFzc2VydCBmYWxsYmFja0NsYXNzTmFtZSA9PSBudWxsOwotICAgICAgICB9Ci0gICAgICAgIGlmIChmYWxsYmFja0NsYXNzTmFtZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvcigKLSAgICAgICAgICAgICAgICAiUHJvdmlkZXIgZm9yICIgKyBmYWN0b3J5SWQgKyAiIGNhbm5vdCBiZSBmb3VuZCIsIG51bGwpOwotICAgICAgICB9Ci0KLSAgICAgICAgZFByaW50KCJsb2FkZWQgZnJvbSBmYWxsYmFjayB2YWx1ZTogIiArIGZhbGxiYWNrQ2xhc3NOYW1lKTsKLSAgICAgICAgcmV0dXJuIG5ld0luc3RhbmNlKHR5cGUsIGZhbGxiYWNrQ2xhc3NOYW1lLCBjbCwgdHJ1ZSk7Ci0gICAgfQotCi0gICAgLyoKLSAgICAgKiBUcnkgdG8gZmluZCBwcm92aWRlciB1c2luZyB0aGUgU2VydmljZUxvYWRlciBBUEkKLSAgICAgKgotICAgICAqIEBwYXJhbSB0eXBlIEJhc2UgY2xhc3MgLyBTZXJ2aWNlIGludGVyZmFjZSAgb2YgdGhlIGZhY3RvcnkgdG8gZmluZC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gaW5zdGFuY2Ugb2YgcHJvdmlkZXIgY2xhc3MgaWYgZm91bmQgb3IgbnVsbAotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIDxUPiBUIGZpbmRTZXJ2aWNlUHJvdmlkZXIoZmluYWwgQ2xhc3M8VD4gdHlwZSwgZmluYWwgQ2xhc3NMb2FkZXIgY2wpIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIHJldHVybiBBY2Nlc3NDb250cm9sbGVyLmRvUHJpdmlsZWdlZChuZXcgUHJpdmlsZWdlZEFjdGlvbjxUPigpIHsKLSAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKLSAgICAgICAgICAgICAgICBwdWJsaWMgVCBydW4oKSB7Ci0gICAgICAgICAgICAgICAgICAgIGZpbmFsIFNlcnZpY2VMb2FkZXI8VD4gc2VydmljZUxvYWRlcjsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGNsID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vdGhlIGN1cnJlbnQgdGhyZWFkJ3MgY29udGV4dCBjbGFzcyBsb2FkZXIKLSAgICAgICAgICAgICAgICAgICAgICAgIHNlcnZpY2VMb2FkZXIgPSBTZXJ2aWNlTG9hZGVyLmxvYWQodHlwZSk7Ci0gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzZXJ2aWNlTG9hZGVyID0gU2VydmljZUxvYWRlci5sb2FkKHR5cGUsIGNsKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBmaW5hbCBJdGVyYXRvcjxUPiBpdGVyYXRvciA9IHNlcnZpY2VMb2FkZXIuaXRlcmF0b3IoKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGl0ZXJhdG9yLmhhc05leHQoKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGl0ZXJhdG9yLm5leHQoKTsKLSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfSk7Ci0gICAgICAgIH0gY2F0Y2goU2VydmljZUNvbmZpZ3VyYXRpb25FcnJvciBlKSB7Ci0gICAgICAgICAgICAvLyBJdCBpcyBub3QgcG9zc2libGUgdG8gd3JhcCBhbiBlcnJvciBkaXJlY3RseSBpbgotICAgICAgICAgICAgLy8gRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvciAtIHNvIHdlIG5lZWQgdG8gd3JhcCB0aGUKLSAgICAgICAgICAgIC8vIFNlcnZpY2VDb25maWd1cmF0aW9uRXJyb3IgaW4gYSBSdW50aW1lRXhjZXB0aW9uLgotICAgICAgICAgICAgLy8gVGhlIGFsdGVybmF0aXZlIHdvdWxkIGJlIHRvIG1vZGlmeSB0aGUgbG9naWMgaW4KLSAgICAgICAgICAgIC8vIEZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IgdG8gYWxsb3cgc2V0dGluZyBhCi0gICAgICAgICAgICAvLyBUaHJvd2FibGUgYXMgdGhlIGNhdXNlLCBidXQgdGhhdCBjb3VsZCBjYXVzZQotICAgICAgICAgICAgLy8gY29tcGF0aWJpbGl0eSBpc3N1ZXMgZG93biB0aGUgcm9hZC4KLSAgICAgICAgICAgIGZpbmFsIFJ1bnRpbWVFeGNlcHRpb24geCA9IG5ldyBSdW50aW1lRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICAiUHJvdmlkZXIgZm9yICIgKyB0eXBlICsgIiBjYW5ub3QgYmUgY3JlYXRlZCIsIGUpOwotICAgICAgICAgICAgZmluYWwgRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvciBlcnJvciA9Ci0gICAgICAgICAgICAgICAgICAgIG5ldyBGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yKHgsIHguZ2V0TWVzc2FnZSgpKTsKLSAgICAgICAgICAgIHRocm93IGVycm9yOwotICAgICAgICAgIH0KLSAgICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmF4L3htbC9zdHJlYW0vTG9jYXRpb24uamF2YSBiL3NyYy9qYXZheC94bWwvc3RyZWFtL0xvY2F0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDc0YTI1ZjMuLjAwMDAwMDAKLS0tIGEvc3JjL2phdmF4L3htbC9zdHJlYW0vTG9jYXRpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDc3ICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDkgYnkgT3JhY2xlIENvcnBvcmF0aW9uLiBBbGwgUmlnaHRzIFJlc2VydmVkLgotICovCi0KLXBhY2thZ2UgamF2YXgueG1sLnN0cmVhbTsKLQotLyoqCi0gKiBQcm92aWRlcyBpbmZvcm1hdGlvbiBvbiB0aGUgbG9jYXRpb24gb2YgYW4gZXZlbnQuCi0gKgotICogQWxsIHRoZSBpbmZvcm1hdGlvbiBwcm92aWRlZCBieSBhIExvY2F0aW9uIGlzIG9wdGlvbmFsLiAgRm9yIGV4YW1wbGUKLSAqIGFuIGFwcGxpY2F0aW9uIG1heSBvbmx5IHJlcG9ydCBsaW5lIG51bWJlcnMuCi0gKgotICogQHZlcnNpb24gMS4wCi0gKiBAYXV0aG9yIENvcHlyaWdodCAoYykgMjAwOSBieSBPcmFjbGUgQ29ycG9yYXRpb24uIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCi0gKiBAc2luY2UgMS42Ci0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgTG9jYXRpb24gewotICAvKioKLSAgICogUmV0dXJuIHRoZSBsaW5lIG51bWJlciB3aGVyZSB0aGUgY3VycmVudCBldmVudCBlbmRzLAotICAgKiByZXR1cm5zIC0xIGlmIG5vbmUgaXMgYXZhaWxhYmxlLgotICAgKiBAcmV0dXJuIHRoZSBjdXJyZW50IGxpbmUgbnVtYmVyCi0gICAqLwotICBpbnQgZ2V0TGluZU51bWJlcigpOwotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIGNvbHVtbiBudW1iZXIgd2hlcmUgdGhlIGN1cnJlbnQgZXZlbnQgZW5kcywKLSAgICogcmV0dXJucyAtMSBpZiBub25lIGlzIGF2YWlsYWJsZS4KLSAgICogQHJldHVybiB0aGUgY3VycmVudCBjb2x1bW4gbnVtYmVyCi0gICAqLwotICBpbnQgZ2V0Q29sdW1uTnVtYmVyKCk7Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgYnl0ZSBvciBjaGFyYWN0ZXIgb2Zmc2V0IGludG8gdGhlIGlucHV0IHNvdXJjZSB0aGlzIGxvY2F0aW9uCi0gICAqIGlzIHBvaW50aW5nIHRvLiBJZiB0aGUgaW5wdXQgc291cmNlIGlzIGEgZmlsZSBvciBhIGJ5dGUgc3RyZWFtIHRoZW4KLSAgICogdGhpcyBpcyB0aGUgYnl0ZSBvZmZzZXQgaW50byB0aGF0IHN0cmVhbSwgYnV0IGlmIHRoZSBpbnB1dCBzb3VyY2UgaXMKLSAgICogYSBjaGFyYWN0ZXIgbWVkaWEgdGhlbiB0aGUgb2Zmc2V0IGlzIHRoZSBjaGFyYWN0ZXIgb2Zmc2V0LgotICAgKiBSZXR1cm5zIC0xIGlmIHRoZXJlIGlzIG5vIG9mZnNldCBhdmFpbGFibGUuCi0gICAqIEByZXR1cm4gdGhlIGN1cnJlbnQgb2Zmc2V0Ci0gICAqLwotICBpbnQgZ2V0Q2hhcmFjdGVyT2Zmc2V0KCk7Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIHB1YmxpYyBJRCBvZiB0aGUgWE1MCi0gICAqIEByZXR1cm4gdGhlIHB1YmxpYyBJRCwgb3IgbnVsbCBpZiBub3QgYXZhaWxhYmxlCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFB1YmxpY0lkKCk7Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIHN5c3RlbSBJRCBvZiB0aGUgWE1MCi0gICAqIEByZXR1cm4gdGhlIHN5c3RlbSBJRCwgb3IgbnVsbCBpZiBub3QgYXZhaWxhYmxlCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFN5c3RlbUlkKCk7Ci19CmRpZmYgLS1naXQgYS9zcmMvamF2YXgveG1sL3N0cmVhbS9TZWN1cml0eVN1cHBvcnQuamF2YSBiL3NyYy9qYXZheC94bWwvc3RyZWFtL1NlY3VyaXR5U3VwcG9ydC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1MDBhYTlhLi4wMDAwMDAwCi0tLSBhL3NyYy9qYXZheC94bWwvc3RyZWFtL1NlY3VyaXR5U3VwcG9ydC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTEwICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLXBhY2thZ2UgamF2YXgueG1sLnN0cmVhbTsKLQotaW1wb3J0IGphdmEuc2VjdXJpdHkuKjsKLWltcG9ydCBqYXZhLm5ldC4qOwotaW1wb3J0IGphdmEuaW8uKjsKLWltcG9ydCBqYXZhLnV0aWwuKjsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGlzIGR1cGxpY2F0ZWQgZm9yIGVhY2ggSkFYUCBzdWJwYWNrYWdlIHNvIGtlZXAgaXQgaW4gc3luYy4KLSAqIEl0IGlzIHBhY2thZ2UgcHJpdmF0ZSBhbmQgdGhlcmVmb3JlIGlzIG5vdCBleHBvc2VkIGFzIHBhcnQgb2YgdGhlIEpBWFAKLSAqIEFQSS4KLSAqCi0gKiBTZWN1cml0eSByZWxhdGVkIG1ldGhvZHMgdGhhdCBvbmx5IHdvcmsgb24gSjJTRSAxLjIgYW5kIG5ld2VyLgotICovCi1jbGFzcyBTZWN1cml0eVN1cHBvcnQgIHsKLQotCi0gICAgQ2xhc3NMb2FkZXIgZ2V0Q29udGV4dENsYXNzTG9hZGVyKCkgdGhyb3dzIFNlY3VyaXR5RXhjZXB0aW9uewotICAgICAgICByZXR1cm4gKENsYXNzTG9hZGVyKQotICAgICAgICAgICAgICAgIEFjY2Vzc0NvbnRyb2xsZXIuZG9Qcml2aWxlZ2VkKG5ldyBQcml2aWxlZ2VkQWN0aW9uKCkgewotICAgICAgICAgICAgcHVibGljIE9iamVjdCBydW4oKSB7Ci0gICAgICAgICAgICAgICAgQ2xhc3NMb2FkZXIgY2wgPSBudWxsOwotICAgICAgICAgICAgICAgIC8vdHJ5IHsKLSAgICAgICAgICAgICAgICBjbCA9IFRocmVhZC5jdXJyZW50VGhyZWFkKCkuZ2V0Q29udGV4dENsYXNzTG9hZGVyKCk7Ci0gICAgICAgICAgICAgICAgLy99IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBleCkgeyB9Ci0KLSAgICAgICAgICAgICAgICBpZiAoY2wgPT0gbnVsbCkKLSAgICAgICAgICAgICAgICAgICAgY2wgPSBDbGFzc0xvYWRlci5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpOwotCi0gICAgICAgICAgICAgICAgcmV0dXJuIGNsOwotICAgICAgICAgICAgfQotICAgICAgICB9KTsKLSAgICB9Ci0KLSAgICBTdHJpbmcgZ2V0U3lzdGVtUHJvcGVydHkoZmluYWwgU3RyaW5nIHByb3BOYW1lKSB7Ci0gICAgICAgIHJldHVybiAoU3RyaW5nKQotICAgICAgICAgICAgQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQobmV3IFByaXZpbGVnZWRBY3Rpb24oKSB7Ci0gICAgICAgICAgICAgICAgcHVibGljIE9iamVjdCBydW4oKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBTeXN0ZW0uZ2V0UHJvcGVydHkocHJvcE5hbWUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0pOwotICAgIH0KLQotICAgIEZpbGVJbnB1dFN0cmVhbSBnZXRGaWxlSW5wdXRTdHJlYW0oZmluYWwgRmlsZSBmaWxlKQotICAgICAgICB0aHJvd3MgRmlsZU5vdEZvdW5kRXhjZXB0aW9uCi0gICAgewotICAgICAgICB0cnkgewotICAgICAgICAgICAgcmV0dXJuIChGaWxlSW5wdXRTdHJlYW0pCi0gICAgICAgICAgICAgICAgQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQobmV3IFByaXZpbGVnZWRFeGNlcHRpb25BY3Rpb24oKSB7Ci0gICAgICAgICAgICAgICAgICAgIHB1YmxpYyBPYmplY3QgcnVuKCkgdGhyb3dzIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEZpbGVJbnB1dFN0cmVhbShmaWxlKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0pOwotICAgICAgICB9IGNhdGNoIChQcml2aWxlZ2VkQWN0aW9uRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIHRocm93IChGaWxlTm90Rm91bmRFeGNlcHRpb24pZS5nZXRFeGNlcHRpb24oKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIElucHV0U3RyZWFtIGdldFJlc291cmNlQXNTdHJlYW0oZmluYWwgQ2xhc3NMb2FkZXIgY2wsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIG5hbWUpCi0gICAgewotICAgICAgICByZXR1cm4gKElucHV0U3RyZWFtKQotICAgICAgICAgICAgQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQobmV3IFByaXZpbGVnZWRBY3Rpb24oKSB7Ci0gICAgICAgICAgICAgICAgcHVibGljIE9iamVjdCBydW4oKSB7Ci0gICAgICAgICAgICAgICAgICAgIElucHV0U3RyZWFtIHJpczsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGNsID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJpcyA9IE9iamVjdC5jbGFzcy5nZXRSZXNvdXJjZUFzU3RyZWFtKG5hbWUpOwotICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgcmlzID0gY2wuZ2V0UmVzb3VyY2VBc1N0cmVhbShuYW1lKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmlzOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0pOwotICAgIH0KLQotICAgIGJvb2xlYW4gZG9lc0ZpbGVFeGlzdChmaW5hbCBGaWxlIGYpIHsKLSAgICByZXR1cm4gKChCb29sZWFuKQotICAgICAgICAgICAgQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQobmV3IFByaXZpbGVnZWRBY3Rpb24oKSB7Ci0gICAgICAgICAgICAgICAgcHVibGljIE9iamVjdCBydW4oKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQm9vbGVhbihmLmV4aXN0cygpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9KSkuYm9vbGVhblZhbHVlKCk7Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvamF2YXgveG1sL3N0cmVhbS9TdHJlYW1GaWx0ZXIuamF2YSBiL3NyYy9qYXZheC94bWwvc3RyZWFtL1N0cmVhbUZpbHRlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkMjQ4ZDZkLi4wMDAwMDAwCi0tLSBhL3NyYy9qYXZheC94bWwvc3RyZWFtL1N0cmVhbUZpbHRlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTEgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwOSBieSBPcmFjbGUgQ29ycG9yYXRpb24uIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCi0gKi8KLQotcGFja2FnZSBqYXZheC54bWwuc3RyZWFtOwotCi0vKioKLSAqIFRoaXMgaW50ZXJmYWNlIGRlY2xhcmVzIGEgc2ltcGxlIGZpbHRlciBpbnRlcmZhY2UgdGhhdCBvbmUgY2FuCi0gKiBjcmVhdGUgdG8gZmlsdGVyIFhNTFN0cmVhbVJlYWRlcnMKLSAqIEB2ZXJzaW9uIDEuMAotICogQGF1dGhvciBDb3B5cmlnaHQgKGMpIDIwMDkgYnkgT3JhY2xlIENvcnBvcmF0aW9uLiBBbGwgUmlnaHRzIFJlc2VydmVkLgotICogQHNpbmNlIDEuNgotICovCi1wdWJsaWMgaW50ZXJmYWNlIFN0cmVhbUZpbHRlciB7Ci0KLSAgLyoqCi0gICAqIFRlc3RzIHdoZXRoZXIgdGhlIGN1cnJlbnQgc3RhdGUgaXMgcGFydCBvZiB0aGlzIHN0cmVhbS4gIFRoaXMgbWV0aG9kCi0gICAqIHdpbGwgcmV0dXJuIHRydWUgaWYgdGhpcyBmaWx0ZXIgYWNjZXB0cyB0aGlzIGV2ZW50IGFuZCBmYWxzZSBvdGhlcndpc2UuCi0gICAqCi0gICAqIFRoZSBtZXRob2Qgc2hvdWxkIG5vdCBjaGFuZ2UgdGhlIHN0YXRlIG9mIHRoZSByZWFkZXIgd2hlbiBhY2NlcHRpbmcKLSAgICogYSBzdGF0ZS4KLSAgICoKLSAgICogQHBhcmFtIHJlYWRlciB0aGUgZXZlbnQgdG8gdGVzdAotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhpcyBmaWx0ZXIgYWNjZXB0cyB0aGlzIGV2ZW50LCBmYWxzZSBvdGhlcndpc2UKLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGFjY2VwdChYTUxTdHJlYW1SZWFkZXIgcmVhZGVyKTsKLX0KZGlmZiAtLWdpdCBhL3NyYy9qYXZheC94bWwvc3RyZWFtL1hNTEV2ZW50RmFjdG9yeS5qYXZhIGIvc3JjL2phdmF4L3htbC9zdHJlYW0vWE1MRXZlbnRGYWN0b3J5LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDU0OGZlZWIuLjAwMDAwMDAKLS0tIGEvc3JjL2phdmF4L3htbC9zdHJlYW0vWE1MRXZlbnRGYWN0b3J5LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0NjQgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwOSwgMjAxMywgYnkgT3JhY2xlIENvcnBvcmF0aW9uLiBBbGwgUmlnaHRzIFJlc2VydmVkLgotICovCi0KLXBhY2thZ2UgamF2YXgueG1sLnN0cmVhbTsKLWltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7Ci1pbXBvcnQgamF2YXgueG1sLm5hbWVzcGFjZS5OYW1lc3BhY2VDb250ZXh0OwotaW1wb3J0IGphdmF4LnhtbC5uYW1lc3BhY2UuUU5hbWU7Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5ldmVudHMuKjsKLS8qKgotICogVGhpcyBpbnRlcmZhY2UgZGVmaW5lcyBhIHV0aWxpdHkgY2xhc3MgZm9yIGNyZWF0aW5nIGluc3RhbmNlcyBvZgotICogWE1MRXZlbnRzCi0gKiBAdmVyc2lvbiAxLjIKLSAqIEBhdXRob3IgQ29weXJpZ2h0IChjKSAyMDA5IGJ5IE9yYWNsZSBDb3Jwb3JhdGlvbi4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KLSAqIEBzZWUgamF2YXgueG1sLnN0cmVhbS5ldmVudHMuU3RhcnRFbGVtZW50Ci0gKiBAc2VlIGphdmF4LnhtbC5zdHJlYW0uZXZlbnRzLkVuZEVsZW1lbnQKLSAqIEBzZWUgamF2YXgueG1sLnN0cmVhbS5ldmVudHMuUHJvY2Vzc2luZ0luc3RydWN0aW9uCi0gKiBAc2VlIGphdmF4LnhtbC5zdHJlYW0uZXZlbnRzLkNvbW1lbnQKLSAqIEBzZWUgamF2YXgueG1sLnN0cmVhbS5ldmVudHMuQ2hhcmFjdGVycwotICogQHNlZSBqYXZheC54bWwuc3RyZWFtLmV2ZW50cy5TdGFydERvY3VtZW50Ci0gKiBAc2VlIGphdmF4LnhtbC5zdHJlYW0uZXZlbnRzLkVuZERvY3VtZW50Ci0gKiBAc2VlIGphdmF4LnhtbC5zdHJlYW0uZXZlbnRzLkRURAotICogQHNpbmNlIDEuNgotICovCi1wdWJsaWMgYWJzdHJhY3QgY2xhc3MgWE1MRXZlbnRGYWN0b3J5IHsKLSAgcHJvdGVjdGVkIFhNTEV2ZW50RmFjdG9yeSgpe30KLQotICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgSkFYUEZBQ1RPUllJRCA9ICJqYXZheC54bWwuc3RyZWFtLlhNTEV2ZW50RmFjdG9yeSI7Ci0gICAgc3RhdGljIGZpbmFsIFN0cmluZyBERUZBVUxJTVBMID0gImNvbS5zdW4ueG1sLmludGVybmFsLnN0cmVhbS5ldmVudHMuWE1MRXZlbnRGYWN0b3J5SW1wbCI7Ci0KLQotICAvKioKLSAgICogQ3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiB0aGUgZmFjdG9yeSBpbiBleGFjdGx5IHRoZSBzYW1lIG1hbm5lciBhcyB0aGUKLSAgICoge0BsaW5rICNuZXdGYWN0b3J5KCl9IG1ldGhvZC4KLSAgICogQHRocm93cyBGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yIGlmIGFuIGluc3RhbmNlIG9mIHRoaXMgZmFjdG9yeSBjYW5ub3QgYmUgbG9hZGVkCi0gICAqLwotICBwdWJsaWMgc3RhdGljIFhNTEV2ZW50RmFjdG9yeSBuZXdJbnN0YW5jZSgpCi0gICAgdGhyb3dzIEZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IKLSAgewotICAgIHJldHVybiBGYWN0b3J5RmluZGVyLmZpbmQoWE1MRXZlbnRGYWN0b3J5LmNsYXNzLCBERUZBVUxJTVBMKTsKLSAgfQotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBuZXcgaW5zdGFuY2Ugb2YgdGhlIGZhY3RvcnkuCi0gICAqIDxwPgotICAgKiBUaGlzIHN0YXRpYyBtZXRob2QgY3JlYXRlcyBhIG5ldyBmYWN0b3J5IGluc3RhbmNlLgotICAgKiBUaGlzIG1ldGhvZCB1c2VzIHRoZSBmb2xsb3dpbmcgb3JkZXJlZCBsb29rdXAgcHJvY2VkdXJlIHRvIGRldGVybWluZQotICAgKiB0aGUgWE1MRXZlbnRGYWN0b3J5IGltcGxlbWVudGF0aW9uIGNsYXNzIHRvIGxvYWQ6Ci0gICAqIDwvcD4KLSAgICogPHVsPgotICAgKiA8bGk+Ci0gICAqICAgVXNlIHRoZSBqYXZheC54bWwuc3RyZWFtLlhNTEV2ZW50RmFjdG9yeSBzeXN0ZW0gcHJvcGVydHkuCi0gICAqIDwvbGk+Ci0gICAqIDxsaT4KLSAgICogICBVc2UgdGhlIHByb3BlcnRpZXMgZmlsZSAibGliL3N0YXgucHJvcGVydGllcyIgaW4gdGhlIEpSRSBkaXJlY3RvcnkuCi0gICAqICAgICBUaGlzIGNvbmZpZ3VyYXRpb24gZmlsZSBpcyBpbiBzdGFuZGFyZCBqYXZhLnV0aWwuUHJvcGVydGllcyBmb3JtYXQKLSAgICogICAgIGFuZCBjb250YWlucyB0aGUgZnVsbHkgcXVhbGlmaWVkIG5hbWUgb2YgdGhlIGltcGxlbWVudGF0aW9uIGNsYXNzCi0gICAqICAgICB3aXRoIHRoZSBrZXkgYmVpbmcgdGhlIHN5c3RlbSBwcm9wZXJ0eSBkZWZpbmVkIGFib3ZlLgotICAgKiA8L2xpPgotICAgKiA8bGk+Ci0gICAqICAgVXNlIHRoZSBzZXJ2aWNlLXByb3ZpZGVyIGxvYWRpbmcgZmFjaWxpdGllcywgZGVmaW5lZCBieSB0aGUKLSAgICogICB7QGxpbmsgamF2YS51dGlsLlNlcnZpY2VMb2FkZXJ9IGNsYXNzLCB0byBhdHRlbXB0IHRvIGxvY2F0ZSBhbmQgbG9hZCBhbgotICAgKiAgIGltcGxlbWVudGF0aW9uIG9mIHRoZSBzZXJ2aWNlIHVzaW5nIHRoZSB7QGxpbmtwbGFpbgotICAgKiAgIGphdmEudXRpbC5TZXJ2aWNlTG9hZGVyI2xvYWQoamF2YS5sYW5nLkNsYXNzKSBkZWZhdWx0IGxvYWRpbmcgbWVjaGFuaXNtfToKLSAgICogICB0aGUgc2VydmljZS1wcm92aWRlciBsb2FkaW5nIGZhY2lsaXR5IHdpbGwgdXNlIHRoZSB7QGxpbmtwbGFpbgotICAgKiAgIGphdmEubGFuZy5UaHJlYWQjZ2V0Q29udGV4dENsYXNzTG9hZGVyKCkgY3VycmVudCB0aHJlYWQncyBjb250ZXh0IGNsYXNzIGxvYWRlcn0KLSAgICogICB0byBhdHRlbXB0IHRvIGxvYWQgdGhlIHNlcnZpY2UuIElmIHRoZSBjb250ZXh0IGNsYXNzCi0gICAqICAgbG9hZGVyIGlzIG51bGwsIHRoZSB7QGxpbmtwbGFpbgotICAgKiAgIENsYXNzTG9hZGVyI2dldFN5c3RlbUNsYXNzTG9hZGVyKCkgc3lzdGVtIGNsYXNzIGxvYWRlcn0gd2lsbCBiZSB1c2VkLgotICAgKiA8L2xpPgotICAgKiA8bGk+Ci0gICAqICAgT3RoZXJ3aXNlLCB0aGUgc3lzdGVtLWRlZmF1bHQgaW1wbGVtZW50YXRpb24gaXMgcmV0dXJuZWQuCi0gICAqIDwvbGk+Ci0gICAqIDwvdWw+Ci0gICAqIDxwPgotICAgKiAgIE9uY2UgYW4gYXBwbGljYXRpb24gaGFzIG9idGFpbmVkIGEgcmVmZXJlbmNlIHRvIGEgWE1MRXZlbnRGYWN0b3J5IGl0Ci0gICAqICAgY2FuIHVzZSB0aGUgZmFjdG9yeSB0byBjb25maWd1cmUgYW5kIG9idGFpbiBzdHJlYW0gaW5zdGFuY2VzLgotICAgKiA8L3A+Ci0gICAqIDxwPgotICAgKiAgIE5vdGUgdGhhdCB0aGlzIGlzIGEgbmV3IG1ldGhvZCB0aGF0IHJlcGxhY2VzIHRoZSBkZXByZWNhdGVkIG5ld0luc3RhbmNlKCkgbWV0aG9kLgotICAgKiAgICAgTm8gY2hhbmdlcyBpbiBiZWhhdmlvciBhcmUgZGVmaW5lZCBieSB0aGlzIHJlcGxhY2VtZW50IG1ldGhvZCByZWxhdGl2ZSB0bwotICAgKiAgICAgdGhlIGRlcHJlY2F0ZWQgbWV0aG9kLgotICAgKiA8L3A+Ci0gICAqIEB0aHJvd3MgRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvciBpbiBjYXNlIG9mIHtAbGlua3BsYWluCi0gICAqICAgamF2YS51dGlsLlNlcnZpY2VDb25maWd1cmF0aW9uRXJyb3Igc2VydmljZSBjb25maWd1cmF0aW9uIGVycm9yfSBvciBpZgotICAgKiAgIHRoZSBpbXBsZW1lbnRhdGlvbiBpcyBub3QgYXZhaWxhYmxlIG9yIGNhbm5vdCBiZSBpbnN0YW50aWF0ZWQuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIFhNTEV2ZW50RmFjdG9yeSBuZXdGYWN0b3J5KCkKLSAgICB0aHJvd3MgRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvcgotICB7Ci0gICAgcmV0dXJuIEZhY3RvcnlGaW5kZXIuZmluZChYTUxFdmVudEZhY3RvcnkuY2xhc3MsIERFRkFVTElNUEwpOwotICB9Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIG5ldyBpbnN0YW5jZSBvZiB0aGUgZmFjdG9yeQotICAgKgotICAgKiBAcGFyYW0gZmFjdG9yeUlkICAgICAgICAgICAgIE5hbWUgb2YgdGhlIGZhY3RvcnkgdG8gZmluZCwgc2FtZSBhcwotICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGEgcHJvcGVydHkgbmFtZQotICAgKiBAcGFyYW0gY2xhc3NMb2FkZXIgICAgICAgICAgIGNsYXNzTG9hZGVyIHRvIHVzZQotICAgKiBAcmV0dXJuIHRoZSBmYWN0b3J5IGltcGxlbWVudGF0aW9uCi0gICAqIEB0aHJvd3MgRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvciBpZiBhbiBpbnN0YW5jZSBvZiB0aGlzIGZhY3RvcnkgY2Fubm90IGJlIGxvYWRlZAotICAgKgotICAgKiBAZGVwcmVjYXRlZCAgVGhpcyBtZXRob2QgaGFzIGJlZW4gZGVwcmVjYXRlZCB0byBtYWludGFpbiBBUEkgY29uc2lzdGVuY3kuCi0gICAqICAgICAgICAgICAgICBBbGwgbmV3SW5zdGFuY2UgbWV0aG9kcyBoYXZlIGJlZW4gcmVwbGFjZWQgd2l0aCBjb3JyZXNwb25kaW5nCi0gICAqICAgICAgICAgICAgICBuZXdGYWN0b3J5IG1ldGhvZHMuIFRoZSByZXBsYWNlbWVudCB7QGxpbmsKLSAgICogICAgICAgICAgICAgICNuZXdGYWN0b3J5KGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5DbGFzc0xvYWRlcil9Ci0gICAqICAgICAgICAgICAgICBtZXRob2QgZGVmaW5lcyBubyBjaGFuZ2VzIGluIGJlaGF2aW9yLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBYTUxFdmVudEZhY3RvcnkgbmV3SW5zdGFuY2UoU3RyaW5nIGZhY3RvcnlJZCwKLSAgICAgICAgICBDbGFzc0xvYWRlciBjbGFzc0xvYWRlcikKLSAgICAgICAgICB0aHJvd3MgRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvciB7Ci0gICAgICAvL2RvIG5vdCBmYWxsYmFjayBpZiBnaXZlbiBjbGFzc2xvYWRlciBjYW4ndCBmaW5kIHRoZSBjbGFzcywgdGhyb3cgZXhjZXB0aW9uCi0gICAgICByZXR1cm4gRmFjdG9yeUZpbmRlci5maW5kKFhNTEV2ZW50RmFjdG9yeS5jbGFzcywgZmFjdG9yeUlkLCBjbGFzc0xvYWRlciwgbnVsbCk7Ci0gIH0KLQotICAvKioKLSAgICogQ3JlYXRlIGEgbmV3IGluc3RhbmNlIG9mIHRoZSBmYWN0b3J5LgotICAgKiBJZiB0aGUgY2xhc3NMb2FkZXIgYXJndW1lbnQgaXMgbnVsbCwgdGhlbiB0aGUgQ29udGV4dENsYXNzTG9hZGVyIGlzIHVzZWQuCi0gICAqIDxwPgotICAgKiBUaGlzIG1ldGhvZCB1c2VzIHRoZSBmb2xsb3dpbmcgb3JkZXJlZCBsb29rdXAgcHJvY2VkdXJlIHRvIGRldGVybWluZQotICAgKiB0aGUgWE1MRXZlbnRGYWN0b3J5IGltcGxlbWVudGF0aW9uIGNsYXNzIHRvIGxvYWQ6Ci0gICAqIDwvcD4KLSAgICogPHVsPgotICAgKiA8bGk+Ci0gICAqICAgVXNlIHRoZSB2YWx1ZSBvZiB0aGUgc3lzdGVtIHByb3BlcnR5IGlkZW50aWZpZWQgYnkge0Bjb2RlIGZhY3RvcnlJZH0uCi0gICAqIDwvbGk+Ci0gICAqIDxsaT4KLSAgICogICBVc2UgdGhlIHByb3BlcnRpZXMgZmlsZSAibGliL3N0YXgucHJvcGVydGllcyIgaW4gdGhlIEpSRSBkaXJlY3RvcnkuCi0gICAqICAgICBUaGlzIGNvbmZpZ3VyYXRpb24gZmlsZSBpcyBpbiBzdGFuZGFyZCBqYXZhLnV0aWwuUHJvcGVydGllcyBmb3JtYXQKLSAgICogICAgIGFuZCBjb250YWlucyB0aGUgZnVsbHkgcXVhbGlmaWVkIG5hbWUgb2YgdGhlIGltcGxlbWVudGF0aW9uIGNsYXNzCi0gICAqICAgICB3aXRoIHRoZSBrZXkgYmVpbmcgdGhlIGdpdmVuIHtAY29kZSBmYWN0b3J5SWR9LgotICAgKiA8L2xpPgotICAgKiA8bGk+Ci0gICAqICAgSWYge0Bjb2RlIGZhY3RvcnlJZH0gaXMgImphdmF4LnhtbC5zdHJlYW0uWE1MRXZlbnRGYWN0b3J5IiwKLSAgICogICB1c2UgdGhlIHNlcnZpY2UtcHJvdmlkZXIgbG9hZGluZyBmYWNpbGl0aWVzLCBkZWZpbmVkIGJ5IHRoZQotICAgKiAgIHtAbGluayBqYXZhLnV0aWwuU2VydmljZUxvYWRlcn0gY2xhc3MsIHRvIGF0dGVtcHQgdG8ge0BsaW5rcGxhaW4KLSAgICogICBqYXZhLnV0aWwuU2VydmljZUxvYWRlciNsb2FkKGphdmEubGFuZy5DbGFzcywgamF2YS5sYW5nLkNsYXNzTG9hZGVyKSBsb2NhdGUgYW5kIGxvYWR9Ci0gICAqICAgYW4gaW1wbGVtZW50YXRpb24gb2YgdGhlIHNlcnZpY2UgdXNpbmcgdGhlIHNwZWNpZmllZCB7QGNvZGUgQ2xhc3NMb2FkZXJ9LgotICAgKiAgIElmIHtAY29kZSBjbGFzc0xvYWRlcn0gaXMgbnVsbCwgdGhlIHtAbGlua3BsYWluCi0gICAqICAgamF2YS51dGlsLlNlcnZpY2VMb2FkZXIjbG9hZChqYXZhLmxhbmcuQ2xhc3MpIGRlZmF1bHQgbG9hZGluZyBtZWNoYW5pc219IHdpbGwgYXBwbHk6Ci0gICAqICAgVGhhdCBpcywgdGhlIHNlcnZpY2UtcHJvdmlkZXIgbG9hZGluZyBmYWNpbGl0eSB3aWxsIHVzZSB0aGUge0BsaW5rcGxhaW4KLSAgICogICBqYXZhLmxhbmcuVGhyZWFkI2dldENvbnRleHRDbGFzc0xvYWRlcigpIGN1cnJlbnQgdGhyZWFkJ3MgY29udGV4dCBjbGFzcyBsb2FkZXJ9Ci0gICAqICAgdG8gYXR0ZW1wdCB0byBsb2FkIHRoZSBzZXJ2aWNlLiBJZiB0aGUgY29udGV4dCBjbGFzcwotICAgKiAgIGxvYWRlciBpcyBudWxsLCB0aGUge0BsaW5rcGxhaW4KLSAgICogICBDbGFzc0xvYWRlciNnZXRTeXN0ZW1DbGFzc0xvYWRlcigpIHN5c3RlbSBjbGFzcyBsb2FkZXJ9IHdpbGwgYmUgdXNlZC4KLSAgICogPC9saT4KLSAgICogPGxpPgotICAgKiAgIE90aGVyd2lzZSwgdGhyb3dzIGEge0BsaW5rIEZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3J9LgotICAgKiA8L2xpPgotICAgKiA8L3VsPgotICAgKgotICAgKiA8cD4KLSAgICogTm90ZSB0aGF0IHRoaXMgaXMgYSBuZXcgbWV0aG9kIHRoYXQgcmVwbGFjZXMgdGhlIGRlcHJlY2F0ZWQKLSAgICogICB7QGxpbmsgI25ld0luc3RhbmNlKGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5DbGFzc0xvYWRlcikKLSAgICogICBuZXdJbnN0YW5jZShTdHJpbmcgZmFjdG9yeUlkLCBDbGFzc0xvYWRlciBjbGFzc0xvYWRlcil9IG1ldGhvZC4KLSAgICogTm8gY2hhbmdlcyBpbiBiZWhhdmlvciBhcmUgZGVmaW5lZCBieSB0aGlzIHJlcGxhY2VtZW50IG1ldGhvZCByZWxhdGl2ZQotICAgKiB0byB0aGUgZGVwcmVjYXRlZCBtZXRob2QuCi0gICAqIDwvcD4KLSAgICoKLSAgICogQGFwaU5vdGUgVGhlIHBhcmFtZXRlciBmYWN0b3J5SWQgZGVmaW5lZCBoZXJlIGlzIGluY29uc2lzdGVudCB3aXRoIHRoYXQKLSAgICogb2Ygb3RoZXIgSkFYUCBmYWN0b3JpZXMgd2hlcmUgdGhlIGZpcnN0IHBhcmFtZXRlciBpcyBmdWxseSBxdWFsaWZpZWQKLSAgICogZmFjdG9yeSBjbGFzcyBuYW1lIHRoYXQgcHJvdmlkZXMgaW1wbGVtZW50YXRpb24gb2YgdGhlIGZhY3RvcnkuCi0gICAqCi0gICAqIEBwYXJhbSBmYWN0b3J5SWQgICAgICAgICAgICAgTmFtZSBvZiB0aGUgZmFjdG9yeSB0byBmaW5kLCBzYW1lIGFzCi0gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYSBwcm9wZXJ0eSBuYW1lCi0gICAqIEBwYXJhbSBjbGFzc0xvYWRlciAgICAgICAgICAgY2xhc3NMb2FkZXIgdG8gdXNlCi0gICAqIEByZXR1cm4gdGhlIGZhY3RvcnkgaW1wbGVtZW50YXRpb24KLSAgICogQHRocm93cyBGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yIGluIGNhc2Ugb2Yge0BsaW5rcGxhaW4KLSAgICogICBqYXZhLnV0aWwuU2VydmljZUNvbmZpZ3VyYXRpb25FcnJvciBzZXJ2aWNlIGNvbmZpZ3VyYXRpb24gZXJyb3J9IG9yIGlmCi0gICAqICAgdGhlIGltcGxlbWVudGF0aW9uIGlzIG5vdCBhdmFpbGFibGUgb3IgY2Fubm90IGJlIGluc3RhbnRpYXRlZC4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgWE1MRXZlbnRGYWN0b3J5IG5ld0ZhY3RvcnkoU3RyaW5nIGZhY3RvcnlJZCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDbGFzc0xvYWRlciBjbGFzc0xvYWRlcikKLSAgICAgICAgICB0aHJvd3MgRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvciB7Ci0gICAgICAvL2RvIG5vdCBmYWxsYmFjayBpZiBnaXZlbiBjbGFzc2xvYWRlciBjYW4ndCBmaW5kIHRoZSBjbGFzcywgdGhyb3cgZXhjZXB0aW9uCi0gICAgICByZXR1cm4gRmFjdG9yeUZpbmRlci5maW5kKFhNTEV2ZW50RmFjdG9yeS5jbGFzcywgZmFjdG9yeUlkLCBjbGFzc0xvYWRlciwgbnVsbCk7Ci0gIH0KLQotIC8qKgotICAgKiBUaGlzIG1ldGhvZCBhbGxvd3Mgc2V0dGluZyBvZiB0aGUgTG9jYXRpb24gb24gZWFjaCBldmVudCB0aGF0Ci0gICAqIGlzIGNyZWF0ZWQgYnkgdGhpcyBmYWN0b3J5LiAgVGhlIHZhbHVlcyBhcmUgY29waWVkIGJ5IHZhbHVlIGludG8KLSAgICogdGhlIGV2ZW50cyBjcmVhdGVkIGJ5IHRoaXMgZmFjdG9yeS4gIFRvIHJlc2V0IHRoZSBsb2NhdGlvbgotICAgKiBpbmZvcm1hdGlvbiBzZXQgdGhlIGxvY2F0aW9uIHRvIG51bGwuCi0gICAqIEBwYXJhbSBsb2NhdGlvbiB0aGUgbG9jYXRpb24gdG8gc2V0IG9uIGVhY2ggZXZlbnQgY3JlYXRlZAotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IHZvaWQgc2V0TG9jYXRpb24oTG9jYXRpb24gbG9jYXRpb24pOwotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBuZXcgQXR0cmlidXRlCi0gICAqIEBwYXJhbSBwcmVmaXggdGhlIHByZWZpeCBvZiB0aGlzIGF0dHJpYnV0ZSwgbWF5IG5vdCBiZSBudWxsCi0gICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkgdGhlIGF0dHJpYnV0ZSB2YWx1ZSBpcyBzZXQgdG8gdGhpcyB2YWx1ZSwgbWF5IG5vdCBiZSBudWxsCi0gICAqIEBwYXJhbSBsb2NhbE5hbWUgdGhlIGxvY2FsIG5hbWUgb2YgdGhlIFhNTCBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUsIGxvY2FsTmFtZSBjYW5ub3QgYmUgbnVsbAotICAgKiBAcGFyYW0gdmFsdWUgdGhlIGF0dHJpYnV0ZSB2YWx1ZSB0byBzZXQsIG1heSBub3QgYmUgbnVsbAotICAgKiBAcmV0dXJuIHRoZSBBdHRyaWJ1dGUgd2l0aCBzcGVjaWZpZWQgdmFsdWVzCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgQXR0cmlidXRlIGNyZWF0ZUF0dHJpYnV0ZShTdHJpbmcgcHJlZml4LCBTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgbG9jYWxOYW1lLCBTdHJpbmcgdmFsdWUpOwotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBuZXcgQXR0cmlidXRlCi0gICAqIEBwYXJhbSBsb2NhbE5hbWUgdGhlIGxvY2FsIG5hbWUgb2YgdGhlIFhNTCBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUsIGxvY2FsTmFtZSBjYW5ub3QgYmUgbnVsbAotICAgKiBAcGFyYW0gdmFsdWUgdGhlIGF0dHJpYnV0ZSB2YWx1ZSB0byBzZXQsIG1heSBub3QgYmUgbnVsbAotICAgKiBAcmV0dXJuIHRoZSBBdHRyaWJ1dGUgd2l0aCBzcGVjaWZpZWQgdmFsdWVzCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgQXR0cmlidXRlIGNyZWF0ZUF0dHJpYnV0ZShTdHJpbmcgbG9jYWxOYW1lLCBTdHJpbmcgdmFsdWUpOwotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBuZXcgQXR0cmlidXRlCi0gICAqIEBwYXJhbSBuYW1lIHRoZSBxdWFsaWZpZWQgbmFtZSBvZiB0aGUgYXR0cmlidXRlLCBtYXkgbm90IGJlIG51bGwKLSAgICogQHBhcmFtIHZhbHVlIHRoZSBhdHRyaWJ1dGUgdmFsdWUgdG8gc2V0LCBtYXkgbm90IGJlIG51bGwKLSAgICogQHJldHVybiB0aGUgQXR0cmlidXRlIHdpdGggc3BlY2lmaWVkIHZhbHVlcwotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IEF0dHJpYnV0ZSBjcmVhdGVBdHRyaWJ1dGUoUU5hbWUgbmFtZSwgU3RyaW5nIHZhbHVlKTsKLQotICAvKioKLSAgICogQ3JlYXRlIGEgbmV3IGRlZmF1bHQgTmFtZXNwYWNlCi0gICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkgdGhlIGRlZmF1bHQgbmFtZXNwYWNlIHVyaQotICAgKiBAcmV0dXJuIHRoZSBOYW1lc3BhY2Ugd2l0aCB0aGUgc3BlY2lmaWVkIHZhbHVlCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgTmFtZXNwYWNlIGNyZWF0ZU5hbWVzcGFjZShTdHJpbmcgbmFtZXNwYWNlVVJJKTsKLQotICAvKioKLSAgICogQ3JlYXRlIGEgbmV3IE5hbWVzcGFjZQotICAgKiBAcGFyYW0gcHJlZml4IHRoZSBwcmVmaXggb2YgdGhpcyBuYW1lc3BhY2UsIG1heSBub3QgYmUgbnVsbAotICAgKiBAcGFyYW0gbmFtZXNwYWNlVXJpIHRoZSBhdHRyaWJ1dGUgdmFsdWUgaXMgc2V0IHRvIHRoaXMgdmFsdWUsIG1heSBub3QgYmUgbnVsbAotICAgKiBAcmV0dXJuIHRoZSBOYW1lc3BhY2Ugd2l0aCB0aGUgc3BlY2lmaWVkIHZhbHVlcwotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IE5hbWVzcGFjZSBjcmVhdGVOYW1lc3BhY2UoU3RyaW5nIHByZWZpeCwgU3RyaW5nIG5hbWVzcGFjZVVyaSk7Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIG5ldyBTdGFydEVsZW1lbnQuICBOYW1lc3BhY2VzIGNhbiBiZSBhZGRlZCB0byB0aGlzIFN0YXJ0RWxlbWVudAotICAgKiBieSBwYXNzaW5nIGluIGFuIEl0ZXJhdG9yIHRoYXQgd2Fsa3Mgb3ZlciBhIHNldCBvZiBOYW1lc3BhY2UgaW50ZXJmYWNlcy4KLSAgICogQXR0cmlidXRlcyBjYW4gYmUgYWRkZWQgdG8gdGhpcyBTdGFydEVsZW1lbnQgYnkgcGFzc2luZyBhbiBpdGVyYXRvcgotICAgKiB0aGF0IHdhbGtzIG92ZXIgYSBzZXQgb2YgQXR0cmlidXRlIGludGVyZmFjZXMuCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lIHRoZSBxdWFsaWZpZWQgbmFtZSBvZiB0aGUgYXR0cmlidXRlLCBtYXkgbm90IGJlIG51bGwKLSAgICogQHBhcmFtIGF0dHJpYnV0ZXMgYW4gb3B0aW9uYWwgdW5vcmRlcmVkIHNldCBvZiBvYmplY3RzIHRoYXQKLSAgICogaW1wbGVtZW50IEF0dHJpYnV0ZSB0byBhZGQgdG8gdGhlIG5ldyBTdGFydEVsZW1lbnQsIG1heSBiZSBudWxsCi0gICAqIEBwYXJhbSBuYW1lc3BhY2VzIGFuIG9wdGlvbmFsIHVub3JkZXJlZCBzZXQgb2Ygb2JqZWN0cyB0aGF0Ci0gICAqIGltcGxlbWVudCBOYW1lc3BhY2UgdG8gYWRkIHRvIHRoZSBuZXcgU3RhcnRFbGVtZW50LCBtYXkgYmUgbnVsbAotICAgKiBAcmV0dXJuIGFuIGluc3RhbmNlIG9mIHRoZSByZXF1ZXN0ZWQgU3RhcnRFbGVtZW50Ci0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgU3RhcnRFbGVtZW50IGNyZWF0ZVN0YXJ0RWxlbWVudChRTmFtZSBuYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJdGVyYXRvciBhdHRyaWJ1dGVzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJdGVyYXRvciBuYW1lc3BhY2VzKTsKLQotICAvKioKLSAgICogQ3JlYXRlIGEgbmV3IFN0YXJ0RWxlbWVudC4gIFRoaXMgZGVmYXVsdHMgdGhlIE5hbWVzcGFjZUNvbnRleHQgdG8KLSAgICogYW4gZW1wdHkgTmFtZXNwYWNlQ29udGV4dC4gIFF1ZXJ5aW5nIHRoaXMgZXZlbnQgZm9yIGl0cyBuYW1lc3BhY2VzIG9yCi0gICAqIGF0dHJpYnV0ZXMgd2lsbCByZXN1bHQgaW4gYW4gZW1wdHkgaXRlcmF0b3IgYmVpbmcgcmV0dXJuZWQuCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lc3BhY2VVcmkgdGhlIHVyaSBvZiB0aGUgUU5hbWUgb2YgdGhlIG5ldyBTdGFydEVsZW1lbnQKLSAgICogQHBhcmFtIGxvY2FsTmFtZSB0aGUgbG9jYWwgbmFtZSBvZiB0aGUgUU5hbWUgb2YgdGhlIG5ldyBTdGFydEVsZW1lbnQKLSAgICogQHBhcmFtIHByZWZpeCB0aGUgcHJlZml4IG9mIHRoZSBRTmFtZSBvZiB0aGUgbmV3IFN0YXJ0RWxlbWVudAotICAgKiBAcmV0dXJuIGFuIGluc3RhbmNlIG9mIHRoZSByZXF1ZXN0ZWQgU3RhcnRFbGVtZW50Ci0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgU3RhcnRFbGVtZW50IGNyZWF0ZVN0YXJ0RWxlbWVudChTdHJpbmcgcHJlZml4LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbmFtZXNwYWNlVXJpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbG9jYWxOYW1lKTsKLSAgLyoqCi0gICAqIENyZWF0ZSBhIG5ldyBTdGFydEVsZW1lbnQuICBOYW1lc3BhY2VzIGNhbiBiZSBhZGRlZCB0byB0aGlzIFN0YXJ0RWxlbWVudAotICAgKiBieSBwYXNzaW5nIGluIGFuIEl0ZXJhdG9yIHRoYXQgd2Fsa3Mgb3ZlciBhIHNldCBvZiBOYW1lc3BhY2UgaW50ZXJmYWNlcy4KLSAgICogQXR0cmlidXRlcyBjYW4gYmUgYWRkZWQgdG8gdGhpcyBTdGFydEVsZW1lbnQgYnkgcGFzc2luZyBhbiBpdGVyYXRvcgotICAgKiB0aGF0IHdhbGtzIG92ZXIgYSBzZXQgb2YgQXR0cmlidXRlIGludGVyZmFjZXMuCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lc3BhY2VVcmkgdGhlIHVyaSBvZiB0aGUgUU5hbWUgb2YgdGhlIG5ldyBTdGFydEVsZW1lbnQKLSAgICogQHBhcmFtIGxvY2FsTmFtZSB0aGUgbG9jYWwgbmFtZSBvZiB0aGUgUU5hbWUgb2YgdGhlIG5ldyBTdGFydEVsZW1lbnQKLSAgICogQHBhcmFtIHByZWZpeCB0aGUgcHJlZml4IG9mIHRoZSBRTmFtZSBvZiB0aGUgbmV3IFN0YXJ0RWxlbWVudAotICAgKiBAcGFyYW0gYXR0cmlidXRlcyBhbiB1bm9yZGVyZWQgc2V0IG9mIG9iamVjdHMgdGhhdCBpbXBsZW1lbnQKLSAgICogQXR0cmlidXRlIHRvIGFkZCB0byB0aGUgbmV3IFN0YXJ0RWxlbWVudAotICAgKiBAcGFyYW0gbmFtZXNwYWNlcyBhbiB1bm9yZGVyZWQgc2V0IG9mIG9iamVjdHMgdGhhdCBpbXBsZW1lbnQKLSAgICogTmFtZXNwYWNlIHRvIGFkZCB0byB0aGUgbmV3IFN0YXJ0RWxlbWVudAotICAgKiBAcmV0dXJuIGFuIGluc3RhbmNlIG9mIHRoZSByZXF1ZXN0ZWQgU3RhcnRFbGVtZW50Ci0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgU3RhcnRFbGVtZW50IGNyZWF0ZVN0YXJ0RWxlbWVudChTdHJpbmcgcHJlZml4LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbmFtZXNwYWNlVXJpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbG9jYWxOYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJdGVyYXRvciBhdHRyaWJ1dGVzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJdGVyYXRvciBuYW1lc3BhY2VzCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7Ci0gIC8qKgotICAgKiBDcmVhdGUgYSBuZXcgU3RhcnRFbGVtZW50LiAgTmFtZXNwYWNlcyBjYW4gYmUgYWRkZWQgdG8gdGhpcyBTdGFydEVsZW1lbnQKLSAgICogYnkgcGFzc2luZyBpbiBhbiBJdGVyYXRvciB0aGF0IHdhbGtzIG92ZXIgYSBzZXQgb2YgTmFtZXNwYWNlIGludGVyZmFjZXMuCi0gICAqIEF0dHJpYnV0ZXMgY2FuIGJlIGFkZGVkIHRvIHRoaXMgU3RhcnRFbGVtZW50IGJ5IHBhc3NpbmcgYW4gaXRlcmF0b3IKLSAgICogdGhhdCB3YWxrcyBvdmVyIGEgc2V0IG9mIEF0dHJpYnV0ZSBpbnRlcmZhY2VzLgotICAgKgotICAgKiBAcGFyYW0gbmFtZXNwYWNlVXJpIHRoZSB1cmkgb2YgdGhlIFFOYW1lIG9mIHRoZSBuZXcgU3RhcnRFbGVtZW50Ci0gICAqIEBwYXJhbSBsb2NhbE5hbWUgdGhlIGxvY2FsIG5hbWUgb2YgdGhlIFFOYW1lIG9mIHRoZSBuZXcgU3RhcnRFbGVtZW50Ci0gICAqIEBwYXJhbSBwcmVmaXggdGhlIHByZWZpeCBvZiB0aGUgUU5hbWUgb2YgdGhlIG5ldyBTdGFydEVsZW1lbnQKLSAgICogQHBhcmFtIGF0dHJpYnV0ZXMgYW4gdW5vcmRlcmVkIHNldCBvZiBvYmplY3RzIHRoYXQgaW1wbGVtZW50Ci0gICAqIEF0dHJpYnV0ZSB0byBhZGQgdG8gdGhlIG5ldyBTdGFydEVsZW1lbnQsIG1heSBiZSBudWxsCi0gICAqIEBwYXJhbSBuYW1lc3BhY2VzIGFuIHVub3JkZXJlZCBzZXQgb2Ygb2JqZWN0cyB0aGF0IGltcGxlbWVudAotICAgKiBOYW1lc3BhY2UgdG8gYWRkIHRvIHRoZSBuZXcgU3RhcnRFbGVtZW50LCBtYXkgYmUgbnVsbAotICAgKiBAcGFyYW0gY29udGV4dCB0aGUgbmFtZXNwYWNlIGNvbnRleHQgb2YgdGhpcyBlbGVtZW50Ci0gICAqIEByZXR1cm4gYW4gaW5zdGFuY2Ugb2YgdGhlIHJlcXVlc3RlZCBTdGFydEVsZW1lbnQKLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBTdGFydEVsZW1lbnQgY3JlYXRlU3RhcnRFbGVtZW50KFN0cmluZyBwcmVmaXgsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBuYW1lc3BhY2VVcmksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBsb2NhbE5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEl0ZXJhdG9yIGF0dHJpYnV0ZXMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEl0ZXJhdG9yIG5hbWVzcGFjZXMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5hbWVzcGFjZUNvbnRleHQgY29udGV4dAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApOwotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBuZXcgRW5kRWxlbWVudAotICAgKiBAcGFyYW0gbmFtZSB0aGUgcXVhbGlmaWVkIG5hbWUgb2YgdGhlIEVuZEVsZW1lbnQKLSAgICogQHBhcmFtIG5hbWVzcGFjZXMgYW4gb3B0aW9uYWwgdW5vcmRlcmVkIHNldCBvZiBvYmplY3RzIHRoYXQKLSAgICogaW1wbGVtZW50IE5hbWVzcGFjZSB0aGF0IGhhdmUgZ29uZSBvdXQgb2Ygc2NvcGUsIG1heSBiZSBudWxsCi0gICAqIEByZXR1cm4gYW4gaW5zdGFuY2Ugb2YgdGhlIHJlcXVlc3RlZCBFbmRFbGVtZW50Ci0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgRW5kRWxlbWVudCBjcmVhdGVFbmRFbGVtZW50KFFOYW1lIG5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSXRlcmF0b3IgbmFtZXNwYWNlcyk7Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIG5ldyBFbmRFbGVtZW50Ci0gICAqIEBwYXJhbSBuYW1lc3BhY2VVcmkgdGhlIHVyaSBvZiB0aGUgUU5hbWUgb2YgdGhlIG5ldyBTdGFydEVsZW1lbnQKLSAgICogQHBhcmFtIGxvY2FsTmFtZSB0aGUgbG9jYWwgbmFtZSBvZiB0aGUgUU5hbWUgb2YgdGhlIG5ldyBTdGFydEVsZW1lbnQKLSAgICogQHBhcmFtIHByZWZpeCB0aGUgcHJlZml4IG9mIHRoZSBRTmFtZSBvZiB0aGUgbmV3IFN0YXJ0RWxlbWVudAotICAgKiBAcmV0dXJuIGFuIGluc3RhbmNlIG9mIHRoZSByZXF1ZXN0ZWQgRW5kRWxlbWVudAotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IEVuZEVsZW1lbnQgY3JlYXRlRW5kRWxlbWVudChTdHJpbmcgcHJlZml4LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBuYW1lc3BhY2VVcmksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGxvY2FsTmFtZSk7Ci0gIC8qKgotICAgKiBDcmVhdGUgYSBuZXcgRW5kRWxlbWVudAotICAgKiBAcGFyYW0gbmFtZXNwYWNlVXJpIHRoZSB1cmkgb2YgdGhlIFFOYW1lIG9mIHRoZSBuZXcgU3RhcnRFbGVtZW50Ci0gICAqIEBwYXJhbSBsb2NhbE5hbWUgdGhlIGxvY2FsIG5hbWUgb2YgdGhlIFFOYW1lIG9mIHRoZSBuZXcgU3RhcnRFbGVtZW50Ci0gICAqIEBwYXJhbSBwcmVmaXggdGhlIHByZWZpeCBvZiB0aGUgUU5hbWUgb2YgdGhlIG5ldyBTdGFydEVsZW1lbnQKLSAgICogQHBhcmFtIG5hbWVzcGFjZXMgYW4gdW5vcmRlcmVkIHNldCBvZiBvYmplY3RzIHRoYXQgaW1wbGVtZW50Ci0gICAqIE5hbWVzcGFjZSB0aGF0IGhhdmUgZ29uZSBvdXQgb2Ygc2NvcGUsIG1heSBiZSBudWxsCi0gICAqIEByZXR1cm4gYW4gaW5zdGFuY2Ugb2YgdGhlIHJlcXVlc3RlZCBFbmRFbGVtZW50Ci0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgRW5kRWxlbWVudCBjcmVhdGVFbmRFbGVtZW50KFN0cmluZyBwcmVmaXgsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG5hbWVzcGFjZVVyaSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbG9jYWxOYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEl0ZXJhdG9yIG5hbWVzcGFjZXMpOwotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBDaGFyYWN0ZXJzIGV2ZW50LCB0aGlzIG1ldGhvZCBkb2VzIG5vdCBjaGVjayBpZiB0aGUgY29udGVudAotICAgKiBpcyBhbGwgd2hpdGVzcGFjZS4gIFRvIGNyZWF0ZSBhIHNwYWNlIGV2ZW50IHVzZSAjY3JlYXRlU3BhY2UoU3RyaW5nKQotICAgKiBAcGFyYW0gY29udGVudCB0aGUgc3RyaW5nIHRvIGNyZWF0ZQotICAgKiBAcmV0dXJuIGEgQ2hhcmFjdGVycyBldmVudAotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IENoYXJhY3RlcnMgY3JlYXRlQ2hhcmFjdGVycyhTdHJpbmcgY29udGVudCk7Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIENoYXJhY3RlcnMgZXZlbnQgd2l0aCB0aGUgQ0RhdGEgZmxhZyBzZXQgdG8gdHJ1ZQotICAgKiBAcGFyYW0gY29udGVudCB0aGUgc3RyaW5nIHRvIGNyZWF0ZQotICAgKiBAcmV0dXJuIGEgQ2hhcmFjdGVycyBldmVudAotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IENoYXJhY3RlcnMgY3JlYXRlQ0RhdGEoU3RyaW5nIGNvbnRlbnQpOwotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBDaGFyYWN0ZXJzIGV2ZW50IHdpdGggdGhlIGlzU3BhY2UgZmxhZyBzZXQgdG8gdHJ1ZQotICAgKiBAcGFyYW0gY29udGVudCB0aGUgY29udGVudCBvZiB0aGUgc3BhY2UgdG8gY3JlYXRlCi0gICAqIEByZXR1cm4gYSBDaGFyYWN0ZXJzIGV2ZW50Ci0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgQ2hhcmFjdGVycyBjcmVhdGVTcGFjZShTdHJpbmcgY29udGVudCk7Ci0gIC8qKgotICAgKiBDcmVhdGUgYW4gaWdub3JhYmxlIHNwYWNlCi0gICAqIEBwYXJhbSBjb250ZW50IHRoZSBzcGFjZSB0byBjcmVhdGUKLSAgICogQHJldHVybiBhIENoYXJhY3RlcnMgZXZlbnQKLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBDaGFyYWN0ZXJzIGNyZWF0ZUlnbm9yYWJsZVNwYWNlKFN0cmluZyBjb250ZW50KTsKLQotICAvKioKLSAgICogQ3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiBhIFN0YXJ0RG9jdW1lbnQgZXZlbnQKLSAgICogQHJldHVybiBhIFN0YXJ0RG9jdW1lbnQgZXZlbnQKLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBTdGFydERvY3VtZW50IGNyZWF0ZVN0YXJ0RG9jdW1lbnQoKTsKLQotICAvKioKLSAgICogQ3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiBhIFN0YXJ0RG9jdW1lbnQgZXZlbnQKLSAgICoKLSAgICogQHBhcmFtIGVuY29kaW5nIHRoZSBlbmNvZGluZyBzdHlsZQotICAgKiBAcGFyYW0gdmVyc2lvbiB0aGUgWE1MIHZlcnNpb24KLSAgICogQHBhcmFtIHN0YW5kYWxvbmUgdGhlIHN0YXR1cyBvZiBzdGFuZGFsb25lIG1heSBiZSBzZXQgdG8gInRydWUiIG9yICJmYWxzZSIKLSAgICogQHJldHVybiBhIFN0YXJ0RG9jdW1lbnQgZXZlbnQKLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBTdGFydERvY3VtZW50IGNyZWF0ZVN0YXJ0RG9jdW1lbnQoU3RyaW5nIGVuY29kaW5nLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdmVyc2lvbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBzdGFuZGFsb25lKTsKLQotICAvKioKLSAgICogQ3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiBhIFN0YXJ0RG9jdW1lbnQgZXZlbnQKLSAgICoKLSAgICogQHBhcmFtIGVuY29kaW5nIHRoZSBlbmNvZGluZyBzdHlsZQotICAgKiBAcGFyYW0gdmVyc2lvbiB0aGUgWE1MIHZlcnNpb24KLSAgICogQHJldHVybiBhIFN0YXJ0RG9jdW1lbnQgZXZlbnQKLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBTdGFydERvY3VtZW50IGNyZWF0ZVN0YXJ0RG9jdW1lbnQoU3RyaW5nIGVuY29kaW5nLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdmVyc2lvbik7Ci0KLSAgLyoqCi0gICAqIENyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgYSBTdGFydERvY3VtZW50IGV2ZW50Ci0gICAqCi0gICAqIEBwYXJhbSBlbmNvZGluZyB0aGUgZW5jb2Rpbmcgc3R5bGUKLSAgICogQHJldHVybiBhIFN0YXJ0RG9jdW1lbnQgZXZlbnQKLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBTdGFydERvY3VtZW50IGNyZWF0ZVN0YXJ0RG9jdW1lbnQoU3RyaW5nIGVuY29kaW5nKTsKLQotICAvKioKLSAgICogQ3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiBhbiBFbmREb2N1bWVudCBldmVudAotICAgKiBAcmV0dXJuIGFuIEVuZERvY3VtZW50IGV2ZW50Ci0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgRW5kRG9jdW1lbnQgY3JlYXRlRW5kRG9jdW1lbnQoKTsKLQotICAvKiogQ3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiBhIEVudGl0eVJlZmVyZW5jZSBldmVudAotICAgKgotICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgcmVmZXJlbmNlCi0gICAqIEBwYXJhbSBkZWNsYXJhdGlvbiB0aGUgZGVjbGFyYXRpb24gZm9yIHRoZSBldmVudAotICAgKiBAcmV0dXJuIGFuIEVudGl0eVJlZmVyZW5jZSBldmVudAotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IEVudGl0eVJlZmVyZW5jZSBjcmVhdGVFbnRpdHlSZWZlcmVuY2UoU3RyaW5nIG5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVudGl0eURlY2xhcmF0aW9uIGRlY2xhcmF0aW9uKTsKLSAgLyoqCi0gICAqIENyZWF0ZSBhIGNvbW1lbnQKLSAgICogQHBhcmFtIHRleHQgVGhlIHRleHQgb2YgdGhlIGNvbW1lbnQKLSAgICogYSBDb21tZW50IGV2ZW50Ci0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgQ29tbWVudCBjcmVhdGVDb21tZW50KFN0cmluZyB0ZXh0KTsKLQotICAvKioKLSAgICogQ3JlYXRlIGEgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbgotICAgKiBAcGFyYW0gdGFyZ2V0IFRoZSB0YXJnZXQgb2YgdGhlIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24KLSAgICogQHBhcmFtIGRhdGEgVGhlIHRleHQgb2YgdGhlIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24KLSAgICogQHJldHVybiBhIFByb2Nlc3NpbmdJbnN0cnVjdGlvbiBldmVudAotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IFByb2Nlc3NpbmdJbnN0cnVjdGlvbiBjcmVhdGVQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oU3RyaW5nIHRhcmdldCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgZGF0YSk7Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIGRvY3VtZW50IHR5cGUgZGVmaW5pdGlvbiBldmVudAotICAgKiBUaGlzIHN0cmluZyBjb250YWlucyB0aGUgZW50aXJlIGRvY3VtZW50IHR5cGUgZGVjbGFyYXRpb24gdGhhdCBtYXRjaGVzCi0gICAqIHRoZSBkb2N0eXBlZGVjbCBpbiB0aGUgWE1MIDEuMCBzcGVjaWZpY2F0aW9uCi0gICAqIEBwYXJhbSBkdGQgdGhlIHRleHQgb2YgdGhlIGRvY3VtZW50IHR5cGUgZGVmaW5pdGlvbgotICAgKiBAcmV0dXJuIGEgRFREIGV2ZW50Ci0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgRFREIGNyZWF0ZURURChTdHJpbmcgZHRkKTsKLX0KZGlmZiAtLWdpdCBhL3NyYy9qYXZheC94bWwvc3RyZWFtL1hNTEV2ZW50UmVhZGVyLmphdmEgYi9zcmMvamF2YXgveG1sL3N0cmVhbS9YTUxFdmVudFJlYWRlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA5N2QyMDc2Li4wMDAwMDAwCi0tLSBhL3NyYy9qYXZheC94bWwvc3RyZWFtL1hNTEV2ZW50UmVhZGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMDYgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwOSBieSBPcmFjbGUgQ29ycG9yYXRpb24uIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCi0gKi8KLQotcGFja2FnZSBqYXZheC54bWwuc3RyZWFtOwotCi1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5ldmVudHMuWE1MRXZlbnQ7Ci0KLWltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7Ci0KLS8qKgotICoKLSAqIFRoaXMgaXMgdGhlIHRvcCBsZXZlbCBpbnRlcmZhY2UgZm9yIHBhcnNpbmcgWE1MIEV2ZW50cy4gIEl0IHByb3ZpZGVzCi0gKiB0aGUgYWJpbGl0eSB0byBwZWVrIGF0IHRoZSBuZXh0IGV2ZW50IGFuZCByZXR1cm5zIGNvbmZpZ3VyYXRpb24KLSAqIGluZm9ybWF0aW9uIHRocm91Z2ggdGhlIHByb3BlcnR5IGludGVyZmFjZS4KLSAqCi0gKiBAdmVyc2lvbiAxLjAKLSAqIEBhdXRob3IgQ29weXJpZ2h0IChjKSAyMDA5IGJ5IE9yYWNsZSBDb3Jwb3JhdGlvbi4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KLSAqIEBzZWUgWE1MSW5wdXRGYWN0b3J5Ci0gKiBAc2VlIFhNTEV2ZW50V3JpdGVyCi0gKiBAc2luY2UgMS42Ci0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgWE1MRXZlbnRSZWFkZXIgZXh0ZW5kcyBJdGVyYXRvciB7Ci0gIC8qKgotICAgKiBHZXQgdGhlIG5leHQgWE1MRXZlbnQKLSAgICogQHNlZSBYTUxFdmVudAotICAgKiBAdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbiBpZiB0aGVyZSBpcyBhbiBlcnJvciB3aXRoIHRoZSB1bmRlcmx5aW5nIFhNTC4KLSAgICogQHRocm93cyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uIGl0ZXJhdGlvbiBoYXMgbm8gbW9yZSBlbGVtZW50cy4KLSAgICovCi0gIHB1YmxpYyBYTUxFdmVudCBuZXh0RXZlbnQoKSB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uOwotCi0gIC8qKgotICAgKiBDaGVjayBpZiB0aGVyZSBhcmUgbW9yZSBldmVudHMuCi0gICAqIFJldHVybnMgdHJ1ZSBpZiB0aGVyZSBhcmUgbW9yZSBldmVudHMgYW5kIGZhbHNlIG90aGVyd2lzZS4KLSAgICogQHJldHVybiB0cnVlIGlmIHRoZSBldmVudCByZWFkZXIgaGFzIG1vcmUgZXZlbnRzLCBmYWxzZSBvdGhlcndpc2UKLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGhhc05leHQoKTsKLQotICAvKioKLSAgICogQ2hlY2sgdGhlIG5leHQgWE1MRXZlbnQgd2l0aG91dCByZWFkaW5nIGl0IGZyb20gdGhlIHN0cmVhbS4KLSAgICogUmV0dXJucyBudWxsIGlmIHRoZSBzdHJlYW0gaXMgYXQgRU9GIG9yIGhhcyBubyBtb3JlIFhNTEV2ZW50cy4KLSAgICogQSBjYWxsIHRvIHBlZWsoKSB3aWxsIGJlIGVxdWFsIHRvIHRoZSBuZXh0IHJldHVybiBvZiBuZXh0KCkuCi0gICAqIEBzZWUgWE1MRXZlbnQKLSAgICogQHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYTUxFdmVudCBwZWVrKCkgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbjsKLQotICAvKioKLSAgICogUmVhZHMgdGhlIGNvbnRlbnQgb2YgYSB0ZXh0LW9ubHkgZWxlbWVudC4gUHJlY29uZGl0aW9uOgotICAgKiB0aGUgY3VycmVudCBldmVudCBpcyBTVEFSVF9FTEVNRU5ULiBQb3N0Y29uZGl0aW9uOgotICAgKiBUaGUgY3VycmVudCBldmVudCBpcyB0aGUgY29ycmVzcG9uZGluZyBFTkRfRUxFTUVOVC4KLSAgICogQHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24gaWYgdGhlIGN1cnJlbnQgZXZlbnQgaXMgbm90IGEgU1RBUlRfRUxFTUVOVAotICAgKiBvciBpZiBhIG5vbiB0ZXh0IGVsZW1lbnQgaXMgZW5jb3VudGVyZWQKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0RWxlbWVudFRleHQoKSB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uOwotCi0gIC8qKgotICAgKiBTa2lwcyBhbnkgaW5zaWduaWZpY2FudCBzcGFjZSBldmVudHMgdW50aWwgYSBTVEFSVF9FTEVNRU5UIG9yCi0gICAqIEVORF9FTEVNRU5UIGlzIHJlYWNoZWQuIElmIGFueXRoaW5nIG90aGVyIHRoYW4gc3BhY2UgY2hhcmFjdGVycyBhcmUKLSAgICogZW5jb3VudGVyZWQsIGFuIGV4Y2VwdGlvbiBpcyB0aHJvd24uIFRoaXMgbWV0aG9kIHNob3VsZAotICAgKiBiZSB1c2VkIHdoZW4gcHJvY2Vzc2luZyBlbGVtZW50LW9ubHkgY29udGVudCBiZWNhdXNlCi0gICAqIHRoZSBwYXJzZXIgaXMgbm90IGFibGUgdG8gcmVjb2duaXplIGlnbm9yYWJsZSB3aGl0ZXNwYWNlIGlmCi0gICAqIHRoZSBEVEQgaXMgbWlzc2luZyBvciBub3QgaW50ZXJwcmV0ZWQuCi0gICAqIEB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uIGlmIGFueXRoaW5nIG90aGVyIHRoYW4gc3BhY2UgY2hhcmFjdGVycyBhcmUgZW5jb3VudGVyZWQKLSAgICovCi0gIHB1YmxpYyBYTUxFdmVudCBuZXh0VGFnKCkgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbjsKLQotICAvKioKLSAgICogR2V0IHRoZSB2YWx1ZSBvZiBhIGZlYXR1cmUvcHJvcGVydHkgZnJvbSB0aGUgdW5kZXJseWluZyBpbXBsZW1lbnRhdGlvbgotICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgcHJvcGVydHkKLSAgICogQHJldHVybiBUaGUgdmFsdWUgb2YgdGhlIHByb3BlcnR5Ci0gICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSBwcm9wZXJ0eSBpcyBub3Qgc3VwcG9ydGVkCi0gICAqLwotICBwdWJsaWMgT2JqZWN0IGdldFByb3BlcnR5KGphdmEubGFuZy5TdHJpbmcgbmFtZSkgdGhyb3dzIGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb247Ci0KLSAgLyoqCi0gICAqIEZyZWVzIGFueSByZXNvdXJjZXMgYXNzb2NpYXRlZCB3aXRoIHRoaXMgUmVhZGVyLiAgVGhpcyBtZXRob2QgZG9lcyBub3QgY2xvc2UgdGhlCi0gICAqIHVuZGVybHlpbmcgaW5wdXQgc291cmNlLgotICAgKiBAdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbiBpZiB0aGVyZSBhcmUgZXJyb3JzIGZyZWVpbmcgYXNzb2NpYXRlZCByZXNvdXJjZXMKLSAgICovCi0gIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbjsKLX0KZGlmZiAtLWdpdCBhL3NyYy9qYXZheC94bWwvc3RyZWFtL1hNTEV2ZW50V3JpdGVyLmphdmEgYi9zcmMvamF2YXgveG1sL3N0cmVhbS9YTUxFdmVudFdyaXRlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmMzg5ZGE2Li4wMDAwMDAwCi0tLSBhL3NyYy9qYXZheC94bWwvc3RyZWFtL1hNTEV2ZW50V3JpdGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyNTYgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwOSBieSBPcmFjbGUgQ29ycG9yYXRpb24uIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCi0gKi8KLQotcGFja2FnZSBqYXZheC54bWwuc3RyZWFtOwotCi1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5ldmVudHMuKjsKLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLnV0aWwuWE1MRXZlbnRDb25zdW1lcjsKLWltcG9ydCBqYXZheC54bWwubmFtZXNwYWNlLk5hbWVzcGFjZUNvbnRleHQ7Ci0KLS8qKgotICoKLSAqIFRoaXMgaXMgdGhlIHRvcCBsZXZlbCBpbnRlcmZhY2UgZm9yIHdyaXRpbmcgWE1MIGRvY3VtZW50cy4KLSAqCi0gKiBJbnN0YW5jZXMgb2YgdGhpcyBpbnRlcmZhY2UgYXJlIG5vdCByZXF1aXJlZCB0byB2YWxpZGF0ZSB0aGUKLSAqIGZvcm0gb2YgdGhlIFhNTC4KLSAqCi0gKiBAdmVyc2lvbiAxLjAKLSAqIEBhdXRob3IgQ29weXJpZ2h0IChjKSAyMDA5IGJ5IE9yYWNsZSBDb3Jwb3JhdGlvbi4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KLSAqIEBzZWUgWE1MRXZlbnRSZWFkZXIKLSAqIEBzZWUgamF2YXgueG1sLnN0cmVhbS5ldmVudHMuWE1MRXZlbnQKLSAqIEBzZWUgamF2YXgueG1sLnN0cmVhbS5ldmVudHMuQ2hhcmFjdGVycwotICogQHNlZSBqYXZheC54bWwuc3RyZWFtLmV2ZW50cy5Qcm9jZXNzaW5nSW5zdHJ1Y3Rpb24KLSAqIEBzZWUgamF2YXgueG1sLnN0cmVhbS5ldmVudHMuU3RhcnRFbGVtZW50Ci0gKiBAc2VlIGphdmF4LnhtbC5zdHJlYW0uZXZlbnRzLkVuZEVsZW1lbnQKLSAqIEBzaW5jZSAxLjYKLSAqLwotcHVibGljIGludGVyZmFjZSBYTUxFdmVudFdyaXRlciBleHRlbmRzIFhNTEV2ZW50Q29uc3VtZXIgewotCi0gIC8qKgotICAgKiBXcml0ZXMgYW55IGNhY2hlZCBldmVudHMgdG8gdGhlIHVuZGVybHlpbmcgb3V0cHV0IG1lY2hhbmlzbQotICAgKiBAdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgZmx1c2goKSB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uOwotCi0gIC8qKgotICAgKiBGcmVlcyBhbnkgcmVzb3VyY2VzIGFzc29jaWF0ZWQgd2l0aCB0aGlzIHN0cmVhbQotICAgKiBAdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uOwotCi0gIC8qKgotICAgKiBBZGQgYW4gZXZlbnQgdG8gdGhlIG91dHB1dCBzdHJlYW0KLSAgICogQWRkaW5nIGEgU1RBUlRfRUxFTUVOVCB3aWxsIG9wZW4gYSBuZXcgbmFtZXNwYWNlIHNjb3BlIHRoYXQKLSAgICogd2lsbCBiZSBjbG9zZWQgd2hlbiB0aGUgY29ycmVzcG9uZGluZyBFTkRfRUxFTUVOVCBpcyB3cml0dGVuLgotICAgKiA8dGFibGUgYm9yZGVyPSIyIiBydWxlcz0iYWxsIiBjZWxscGFkZGluZz0iNCI+Ci0gICAqICAgPHRoZWFkPgotICAgKiAgICAgPHRyPgotICAgKiAgICAgICA8dGggYWxpZ249ImNlbnRlciIgY29sc3Bhbj0iMiI+Ci0gICAqICAgICAgICAgUmVxdWlyZWQgYW5kIG9wdGlvbmFsIGZpZWxkcyBmb3IgZXZlbnRzIGFkZGVkIHRvIHRoZSB3cml0ZXIKLSAgICogICAgICAgPC90aD4KLSAgICogICAgIDwvdHI+Ci0gICAqICAgPC90aGVhZD4KLSAgICogICA8dGJvZHk+Ci0gICAqICAgICA8dHI+Ci0gICAqICAgICAgIDx0aD5FdmVudCBUeXBlPC90aD4KLSAgICogICAgICAgPHRoPlJlcXVpcmVkIEZpZWxkczwvdGg+Ci0gICAqICAgICAgIDx0aD5PcHRpb25hbCBGaWVsZHM8L3RoPgotICAgKiAgICAgICA8dGg+UmVxdWlyZWQgQmVoYXZpb3I8L3RoPgotICAgKiAgICAgPC90cj4KLSAgICogICAgIDx0cj4KLSAgICogICAgICAgPHRkPiBTVEFSVF9FTEVNRU5UICA8L3RkPgotICAgKiAgICAgICA8dGQ+IFFOYW1lIG5hbWUgPC90ZD4KLSAgICogICAgICAgPHRkPiBuYW1lc3BhY2VzICwgYXR0cmlidXRlcyA8L3RkPgotICAgKiAgICAgICA8dGQ+IEEgU1RBUlRfRUxFTUVOVCB3aWxsIGJlIHdyaXR0ZW4gYnkgd3JpdGluZyB0aGUgbmFtZSwKLSAgICogICAgICAgbmFtZXNwYWNlcywgYW5kIGF0dHJpYnV0ZXMgb2YgdGhlIGV2ZW50IGluIFhNTCAxLjAgdmFsaWQKLSAgICogICAgICAgc3ludGF4IGZvciBTVEFSVF9FTEVNRU5Ucy4KLSAgICogICAgICAgVGhlIG5hbWUgaXMgd3JpdHRlbiBieSBsb29raW5nIHVwIHRoZSBwcmVmaXggZm9yCi0gICAqICAgICAgIHRoZSBuYW1lc3BhY2UgdXJpLiAgVGhlIHdyaXRlciBjYW4gYmUgY29uZmlndXJlZCB0bwotICAgKiAgICAgICByZXNwZWN0IHByZWZpeGVzIG9mIFFOYW1lcy4gIElmIHRoZSB3cml0ZXIgaXMgcmVzcGVjdGluZwotICAgKiAgICAgICBwcmVmaXhlcyBpdCBtdXN0IHVzZSB0aGUgcHJlZml4IHNldCBvbiB0aGUgUU5hbWUuICBUaGUKLSAgICogICAgICAgZGVmYXVsdCBiZWhhdmlvciBpcyB0byBsb29rdXAgdGhlIHZhbHVlIGZvciB0aGUgcHJlZml4Ci0gICAqICAgICAgIG9uIHRoZSBFdmVudFdyaXRlcidzIGludGVybmFsIG5hbWVzcGFjZSBjb250ZXh0LgotICAgKiAgICAgICBFYWNoIGF0dHJpYnV0ZSAoaWYgYW55KQotICAgKiAgICAgICBpcyB3cml0dGVuIHVzaW5nIHRoZSBiZWhhdmlvciBzcGVjaWZpZWQgaW4gdGhlIGF0dHJpYnV0ZQotICAgKiAgICAgICBzZWN0aW9uIG9mIHRoaXMgdGFibGUuICBFYWNoIG5hbWVzcGFjZSAoaWYgYW55KSBpcyB3cml0dGVuCi0gICAqICAgICAgIHVzaW5nIHRoZSBiZWhhdmlvciBzcGVjaWZpZWQgaW4gdGhlIG5hbWVzcGFjZSBzZWN0aW9uIG9mIHRoaXMKLSAgICogICAgICAgdGFibGUuCi0gICAqICAgICAgIDwvdGQ+Ci0gICAqICAgICA8L3RyPgotICAgKiAgICAgPHRyPgotICAgKiAgICAgICA8dGQ+IEVORF9FTEVNRU5UICA8L3RkPgotICAgKiAgICAgICA8dGQ+IFFuYW1lIG5hbWUgIDwvdGQ+Ci0gICAqICAgICAgIDx0ZD4gTm9uZSA8L3RkPgotICAgKiAgICAgICA8dGQ+IEEgd2VsbCBmb3JtZWQgRU5EX0VMRU1FTlQgdGFnIGlzIHdyaXR0ZW4uCi0gICAqICAgICAgIFRoZSBuYW1lIGlzIHdyaXR0ZW4gYnkgbG9va2luZyB1cCB0aGUgcHJlZml4IGZvcgotICAgKiAgICAgICB0aGUgbmFtZXNwYWNlIHVyaS4gIFRoZSB3cml0ZXIgY2FuIGJlIGNvbmZpZ3VyZWQgdG8KLSAgICogICAgICAgcmVzcGVjdCBwcmVmaXhlcyBvZiBRTmFtZXMuICBJZiB0aGUgd3JpdGVyIGlzIHJlc3BlY3RpbmcKLSAgICogICAgICAgcHJlZml4ZXMgaXQgbXVzdCB1c2UgdGhlIHByZWZpeCBzZXQgb24gdGhlIFFOYW1lLiAgVGhlCi0gICAqICAgICAgIGRlZmF1bHQgYmVoYXZpb3IgaXMgdG8gbG9va3VwIHRoZSB2YWx1ZSBmb3IgdGhlIHByZWZpeAotICAgKiAgICAgICBvbiB0aGUgRXZlbnRXcml0ZXIncyBpbnRlcm5hbCBuYW1lc3BhY2UgY29udGV4dC4KLSAgICogICAgICAgSWYgdGhlIEVORF9FTEVNRU5UIG5hbWUgZG9lcyBub3QgbWF0Y2ggdGhlIFNUQVJUX0VMRU1FTlQKLSAgICogICAgICAgbmFtZSBhbiBYTUxTdHJlYW1FeGNlcHRpb24gaXMgdGhyb3duLgotICAgKiAgICAgICA8L3RkPgotICAgKiAgICAgPC90cj4KLSAgICogICAgIDx0cj4KLSAgICogICAgICAgPHRkPiBBVFRSSUJVVEUgIDwvdGQ+Ci0gICAqICAgICAgIDx0ZD4gUU5hbWUgbmFtZSAsIFN0cmluZyB2YWx1ZSA8L3RkPgotICAgKiAgICAgICA8dGQ+IFFOYW1lIHR5cGUgPC90ZD4KLSAgICogICAgICAgPHRkPiBBbiBhdHRyaWJ1dGUgaXMgd3JpdHRlbiB1c2luZyB0aGUgc2FtZSBhbGdvcml0aG0KLSAgICogICAgICAgICAgICB0byBmaW5kIHRoZSBsZXhpY2FsIGZvcm0gYXMgdXNlZCBpbiBTVEFSVF9FTEVNRU5ULgotICAgKiAgICAgICAgICAgIFRoZSBkZWZhdWx0IGlzIHRvIHVzZSBkb3VibGUgcXVvdGVzIHRvIHdyYXAgYXR0cmlidXRlCi0gICAqICAgICAgICAgICAgdmFsdWVzIGFuZCB0byBlc2NhcGUgYW55IGRvdWJsZSBxdW90ZXMgZm91bmQgaW4gdGhlCi0gICAqICAgICAgICAgICAgdmFsdWUuICBUaGUgdHlwZSB2YWx1ZSBpcyBpZ25vcmVkLgotICAgKiAgICAgICA8L3RkPgotICAgKiAgICAgPC90cj4KLSAgICogICAgIDx0cj4KLSAgICogICAgICAgPHRkPiBOQU1FU1BBQ0UgIDwvdGQ+Ci0gICAqICAgICAgIDx0ZD4gU3RyaW5nIHByZWZpeCwgU3RyaW5nIG5hbWVzcGFjZVVSSSwKLSAgICogICAgICAgICAgICBib29sZWFuIGlzRGVmYXVsdE5hbWVzcGFjZURlY2xhcmF0aW9uCi0gICAqICAgICAgPC90ZD4KLSAgICogICAgICAgPHRkPiBOb25lICA8L3RkPgotICAgKiAgICAgICA8dGQ+IEEgbmFtZXNwYWNlIGRlY2xhcmF0aW9uIGlzIHdyaXR0ZW4uICBJZiB0aGUKLSAgICogICAgICAgICAgICBuYW1lc3BhY2UgaXMgYSBkZWZhdWx0IG5hbWVzcGFjZSBkZWNsYXJhdGlvbgotICAgKiAgICAgICAgICAgIChpc0RlZmF1bHQgaXMgdHJ1ZSkgdGhlbiB4bWxucz0iJG5hbWVzcGFjZVVSSSIKLSAgICogICAgICAgICAgICBpcyB3cml0dGVuIGFuZCB0aGUgcHJlZml4IGlzIG9wdGlvbmFsLiAgSWYKLSAgICogICAgICAgICAgICBpc0RlZmF1bHQgaXMgZmFsc2UsIHRoZSBwcmVmaXggbXVzdCBiZSBkZWNsYXJlZAotICAgKiAgICAgICAgICAgIGFuZCB0aGUgd3JpdGVyIG11c3QgcHJlcGVuZCB4bWxucyB0byB0aGUgcHJlZml4Ci0gICAqICAgICAgICAgICAgYW5kIHdyaXRlIG91dCBhIHN0YW5kYXJkIHByZWZpeCBkZWNsYXJhdGlvbi4KLSAgICogICAgICA8L3RkPgotICAgKiAgICAgPC90cj4KLSAgICogICAgIDx0cj4KLSAgICogICAgICAgPHRkPiBQUk9DRVNTSU5HX0lOU1RSVUNUSU9OICA8L3RkPgotICAgKiAgICAgICA8dGQ+ICAgTm9uZTwvdGQ+Ci0gICAqICAgICAgIDx0ZD4gICBTdHJpbmcgdGFyZ2V0LCBTdHJpbmcgZGF0YTwvdGQ+Ci0gICAqICAgICAgIDx0ZD4gICBUaGUgZGF0YSBkb2VzIG5vdCBuZWVkIHRvIGJlIHByZXNlbnQgYW5kIG1heSBiZQotICAgKiAgICAgICAgICAgICAgbnVsbC4gIFRhcmdldCBpcyByZXF1aXJlZCBhbmQgbWFueSBub3QgYmUgbnVsbC4KLSAgICogICAgICAgICAgICAgIFRoZSB3cml0ZXIKLSAgICogICAgICAgICAgICAgIHdpbGwgd3JpdGUgZGF0YSBzZWN0aW9uCi0gICAqICAgICAgICAgICAgICBkaXJlY3RseSBhZnRlciB0aGUgdGFyZ2V0LAotICAgKiAgICAgICAgICAgICAgZW5jbG9zZWQgaW4gYXBwcm9wcmlhdGUgWE1MIDEuMCBzeW50YXgKLSAgICogICAgICA8L3RkPgotICAgKiAgICAgPC90cj4KLSAgICogICAgIDx0cj4KLSAgICogICAgICAgPHRkPiBDT01NRU5UICA8L3RkPgotICAgKiAgICAgICA8dGQ+IE5vbmUgIDwvdGQ+Ci0gICAqICAgICAgIDx0ZD4gU3RyaW5nIGNvbW1lbnQgIDwvdGQ+Ci0gICAqICAgICAgIDx0ZD4gSWYgdGhlIGNvbW1lbnQgaXMgcHJlc2VudCAobm90IG51bGwpIGl0IGlzIHdyaXR0ZW4sIG90aGVyd2lzZSBhbgotICAgKiAgICAgICAgICAgIGFuIGVtcHR5IGNvbW1lbnQgaXMgd3JpdHRlbgotICAgKiAgICAgIDwvdGQ+Ci0gICAqICAgICA8L3RyPgotICAgKiAgICAgPHRyPgotICAgKiAgICAgICA8dGQ+IFNUQVJUX0RPQ1VNRU5UICA8L3RkPgotICAgKiAgICAgICA8dGQ+IE5vbmUgIDwvdGQ+Ci0gICAqICAgICAgIDx0ZD4gU3RyaW5nIGVuY29kaW5nICwgYm9vbGVhbiBzdGFuZGFsb25lLCBTdHJpbmcgdmVyc2lvbiAgPC90ZD4KLSAgICogICAgICAgPHRkPiBBIFNUQVJUX0RPQ1VNRU5UIGV2ZW50IGlzIG5vdCByZXF1aXJlZCB0byBiZSB3cml0dGVuIHRvIHRoZQotICAgKiAgICAgICAgICAgICBzdHJlYW0uICBJZiBwcmVzZW50IHRoZSBhdHRyaWJ1dGVzIGFyZSB3cml0dGVuIGluc2lkZQotICAgKiAgICAgICAgICAgICB0aGUgYXBwcm9wcmlhdGUgWE1MIGRlY2xhcmF0aW9uIHN5bnRheAotICAgKiAgICAgIDwvdGQ+Ci0gICAqICAgICA8L3RyPgotICAgKiAgICAgPHRyPgotICAgKiAgICAgICA8dGQ+IEVORF9ET0NVTUVOVCAgPC90ZD4KLSAgICogICAgICAgPHRkPiBOb25lIDwvdGQ+Ci0gICAqICAgICAgIDx0ZD4gTm9uZSAgPC90ZD4KLSAgICogICAgICAgPHRkPiBOb3RoaW5nIGlzIHdyaXR0ZW4gdG8gdGhlIG91dHB1dCAgPC90ZD4KLSAgICogICAgIDwvdHI+Ci0gICAqICAgICA8dHI+Ci0gICAqICAgICAgIDx0ZD4gRFREICA8L3RkPgotICAgKiAgICAgICA8dGQ+IFN0cmluZyBEb2N1bWVudFR5cGVEZWZpbml0aW9uICA8L3RkPgotICAgKiAgICAgICA8dGQ+IE5vbmUgIDwvdGQ+Ci0gICAqICAgICAgIDx0ZD4gVGhlIERvY3VtZW50VHlwZURlZmluaXRpb24gaXMgd3JpdHRlbiB0byB0aGUgb3V0cHV0ICA8L3RkPgotICAgKiAgICAgPC90cj4KLSAgICogICA8L3Rib2R5PgotICAgKiA8L3RhYmxlPgotICAgKiBAcGFyYW0gZXZlbnQgdGhlIGV2ZW50IHRvIGJlIGFkZGVkCi0gICAqIEB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBhZGQoWE1MRXZlbnQgZXZlbnQpIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb247Ci0KLSAgLyoqCi0gICAqIEFkZHMgYW4gZW50aXJlIHN0cmVhbSB0byBhbiBvdXRwdXQgc3RyZWFtLAotICAgKiBjYWxscyBuZXh0KCkgb24gdGhlIGlucHV0U3RyZWFtIGFyZ3VtZW50IHVudGlsIGhhc05leHQoKSByZXR1cm5zIGZhbHNlCi0gICAqIFRoaXMgc2hvdWxkIGJlIHRyZWF0ZWQgYXMgYSBjb252ZW5pZW5jZSBtZXRob2QgdGhhdCB3aWxsCi0gICAqIHBlcmZvcm0gdGhlIGZvbGxvd2luZyBsb29wIG92ZXIgYWxsIHRoZSBldmVudHMgaW4gYW4KLSAgICogZXZlbnQgcmVhZGVyIGFuZCBjYWxsIGFkZCBvbiBlYWNoIGV2ZW50LgotICAgKgotICAgKiBAcGFyYW0gcmVhZGVyIHRoZSBldmVudCBzdHJlYW0gdG8gYWRkIHRvIHRoZSBvdXRwdXQKLSAgICogQHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24KLSAgICovCi0KLSAgcHVibGljIHZvaWQgYWRkKFhNTEV2ZW50UmVhZGVyIHJlYWRlcikgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbjsKLQotICAvKioKLSAgICogR2V0cyB0aGUgcHJlZml4IHRoZSB1cmkgaXMgYm91bmQgdG8KLSAgICogQHBhcmFtIHVyaSB0aGUgdXJpIHRvIGxvb2sgdXAKLSAgICogQHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0UHJlZml4KFN0cmluZyB1cmkpIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb247Ci0KLSAgLyoqCi0gICAqIFNldHMgdGhlIHByZWZpeCB0aGUgdXJpIGlzIGJvdW5kIHRvLiAgVGhpcyBwcmVmaXggaXMgYm91bmQKLSAgICogaW4gdGhlIHNjb3BlIG9mIHRoZSBjdXJyZW50IFNUQVJUX0VMRU1FTlQgLyBFTkRfRUxFTUVOVCBwYWlyLgotICAgKiBJZiB0aGlzIG1ldGhvZCBpcyBjYWxsZWQgYmVmb3JlIGEgU1RBUlRfRUxFTUVOVCBoYXMgYmVlbiB3cml0dGVuCi0gICAqIHRoZSBwcmVmaXggaXMgYm91bmQgaW4gdGhlIHJvb3Qgc2NvcGUuCi0gICAqIEBwYXJhbSBwcmVmaXggdGhlIHByZWZpeCB0byBiaW5kIHRvIHRoZSB1cmkKLSAgICogQHBhcmFtIHVyaSB0aGUgdXJpIHRvIGJpbmQgdG8gdGhlIHByZWZpeAotICAgKiBAdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0UHJlZml4KFN0cmluZyBwcmVmaXgsIFN0cmluZyB1cmkpIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb247Ci0KLSAgLyoqCi0gICAqIEJpbmRzIGEgVVJJIHRvIHRoZSBkZWZhdWx0IG5hbWVzcGFjZQotICAgKiBUaGlzIFVSSSBpcyBib3VuZAotICAgKiBpbiB0aGUgc2NvcGUgb2YgdGhlIGN1cnJlbnQgU1RBUlRfRUxFTUVOVCAvIEVORF9FTEVNRU5UIHBhaXIuCi0gICAqIElmIHRoaXMgbWV0aG9kIGlzIGNhbGxlZCBiZWZvcmUgYSBTVEFSVF9FTEVNRU5UIGhhcyBiZWVuIHdyaXR0ZW4KLSAgICogdGhlIHVyaSBpcyBib3VuZCBpbiB0aGUgcm9vdCBzY29wZS4KLSAgICogQHBhcmFtIHVyaSB0aGUgdXJpIHRvIGJpbmQgdG8gdGhlIGRlZmF1bHQgbmFtZXNwYWNlCi0gICAqIEB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXREZWZhdWx0TmFtZXNwYWNlKFN0cmluZyB1cmkpIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb247Ci0KLSAgLyoqCi0gICAqIFNldHMgdGhlIGN1cnJlbnQgbmFtZXNwYWNlIGNvbnRleHQgZm9yIHByZWZpeCBhbmQgdXJpIGJpbmRpbmdzLgotICAgKiBUaGlzIGNvbnRleHQgYmVjb21lcyB0aGUgcm9vdCBuYW1lc3BhY2UgY29udGV4dCBmb3Igd3JpdGluZyBhbmQKLSAgICogd2lsbCByZXBsYWNlIHRoZSBjdXJyZW50IHJvb3QgbmFtZXNwYWNlIGNvbnRleHQuICBTdWJzZXF1ZW50IGNhbGxzCi0gICAqIHRvIHNldFByZWZpeCBhbmQgc2V0RGVmYXVsdE5hbWVzcGFjZSB3aWxsIGJpbmQgbmFtZXNwYWNlcyB1c2luZwotICAgKiB0aGUgY29udGV4dCBwYXNzZWQgdG8gdGhlIG1ldGhvZCBhcyB0aGUgcm9vdCBjb250ZXh0IGZvciByZXNvbHZpbmcKLSAgICogbmFtZXNwYWNlcy4KLSAgICogQHBhcmFtIGNvbnRleHQgdGhlIG5hbWVzcGFjZSBjb250ZXh0IHRvIHVzZSBmb3IgdGhpcyB3cml0ZXIKLSAgICogQHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldE5hbWVzcGFjZUNvbnRleHQoTmFtZXNwYWNlQ29udGV4dCBjb250ZXh0KQotICAgIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb247Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIGN1cnJlbnQgbmFtZXNwYWNlIGNvbnRleHQuCi0gICAqIEByZXR1cm4gdGhlIGN1cnJlbnQgbmFtZXNwYWNlIGNvbnRleHQKLSAgICovCi0gIHB1YmxpYyBOYW1lc3BhY2VDb250ZXh0IGdldE5hbWVzcGFjZUNvbnRleHQoKTsKLQotCi19CmRpZmYgLS1naXQgYS9zcmMvamF2YXgveG1sL3N0cmVhbS9YTUxJbnB1dEZhY3RvcnkuamF2YSBiL3NyYy9qYXZheC94bWwvc3RyZWFtL1hNTElucHV0RmFjdG9yeS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyMGFmN2EwLi4wMDAwMDAwCi0tLSBhL3NyYy9qYXZheC94bWwvc3RyZWFtL1hNTElucHV0RmFjdG9yeS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTEwICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDksIDIwMTMsIGJ5IE9yYWNsZSBDb3Jwb3JhdGlvbi4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KLSAqLwotCi1wYWNrYWdlIGphdmF4LnhtbC5zdHJlYW07Ci0KLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLnV0aWwuWE1MRXZlbnRBbGxvY2F0b3I7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2U7Ci0KLS8qKgotICogRGVmaW5lcyBhbiBhYnN0cmFjdCBpbXBsZW1lbnRhdGlvbiBvZiBhIGZhY3RvcnkgZm9yIGdldHRpbmcgc3RyZWFtcy4KLSAqCi0gKiBUaGUgZm9sbG93aW5nIHRhYmxlIGRlZmluZXMgdGhlIHN0YW5kYXJkIHByb3BlcnRpZXMgb2YgdGhpcyBzcGVjaWZpY2F0aW9uLgotICogRWFjaCBwcm9wZXJ0eSB2YXJpZXMgaW4gdGhlIGxldmVsIG9mIHN1cHBvcnQgcmVxdWlyZWQgYnkgZWFjaCBpbXBsZW1lbnRhdGlvbi4KLSAqIFRoZSBsZXZlbCBvZiBzdXBwb3J0IHJlcXVpcmVkIGlzIGRlc2NyaWJlZCBpbiB0aGUgJ1JlcXVpcmVkJyBjb2x1bW4uCi0gKgotICogICA8dGFibGUgYm9yZGVyPSIyIiBydWxlcz0iYWxsIiBjZWxscGFkZGluZz0iNCI+Ci0gKiAgICA8dGhlYWQ+Ci0gKiAgICAgIDx0cj4KLSAqICAgICAgICA8dGggYWxpZ249ImNlbnRlciIgY29sc3Bhbj0iNSI+Ci0gKiAgICAgICAgICBDb25maWd1cmF0aW9uIHBhcmFtZXRlcnMKLSAqICAgICAgICA8L3RoPgotICogICAgICA8L3RyPgotICogICAgPC90aGVhZD4KLSAqICAgIDx0Ym9keT4KLSAqICAgICAgPHRyPgotICogICAgICAgIDx0aD5Qcm9wZXJ0eSBOYW1lPC90aD4KLSAqICAgICAgICA8dGg+QmVoYXZpb3I8L3RoPgotICogICAgICAgIDx0aD5SZXR1cm4gdHlwZTwvdGg+Ci0gKiAgICAgICAgPHRoPkRlZmF1bHQgVmFsdWU8L3RoPgotICogICAgICAgIDx0aD5SZXF1aXJlZDwvdGg+Ci0gKiAgICAgIDwvdHI+Ci0gKiA8dHI+PHRkPmphdmF4LnhtbC5zdHJlYW0uaXNWYWxpZGF0aW5nPC90ZD48dGQ+VHVybnMgb24vb2ZmIGltcGxlbWVudGF0aW9uIHNwZWNpZmljIERURCB2YWxpZGF0aW9uPC90ZD48dGQ+Qm9vbGVhbjwvdGQ+PHRkPkZhbHNlPC90ZD48dGQ+Tm88L3RkPjwvdHI+Ci0gKiA8dHI+PHRkPmphdmF4LnhtbC5zdHJlYW0uaXNOYW1lc3BhY2VBd2FyZTwvdGQ+PHRkPlR1cm5zIG9uL29mZiBuYW1lc3BhY2UgcHJvY2Vzc2luZyBmb3IgWE1MIDEuMCBzdXBwb3J0PC90ZD48dGQ+Qm9vbGVhbjwvdGQ+PHRkPlRydWU8L3RkPjx0ZD5UcnVlIChyZXF1aXJlZCkgLyBGYWxzZSAob3B0aW9uYWwpPC90ZD48L3RyPgotICogPHRyPjx0ZD5qYXZheC54bWwuc3RyZWFtLmlzQ29hbGVzY2luZzwvdGQ+PHRkPlJlcXVpcmVzIHRoZSBwcm9jZXNzb3IgdG8gY29hbGVzY2UgYWRqYWNlbnQgY2hhcmFjdGVyIGRhdGE8L3RkPjx0ZD5Cb29sZWFuPC90ZD48dGQ+RmFsc2U8L3RkPjx0ZD5ZZXM8L3RkPjwvdHI+Ci0gKiA8dHI+PHRkPmphdmF4LnhtbC5zdHJlYW0uaXNSZXBsYWNpbmdFbnRpdHlSZWZlcmVuY2VzPC90ZD48dGQ+cmVwbGFjZSBpbnRlcm5hbCBlbnRpdHkgcmVmZXJlbmNlcyB3aXRoIHRoZWlyIHJlcGxhY2VtZW50IHRleHQgYW5kIHJlcG9ydCB0aGVtIGFzIGNoYXJhY3RlcnM8L3RkPjx0ZD5Cb29sZWFuPC90ZD48dGQ+VHJ1ZTwvdGQ+PHRkPlllczwvdGQ+PC90cj4KLSAqPHRyPjx0ZD5qYXZheC54bWwuc3RyZWFtLmlzU3VwcG9ydGluZ0V4dGVybmFsRW50aXRpZXM8L3RkPjx0ZD5SZXNvbHZlIGV4dGVybmFsIHBhcnNlZCBlbnRpdGllczwvdGQ+PHRkPkJvb2xlYW48L3RkPjx0ZD5VbnNwZWNpZmllZDwvdGQ+PHRkPlllczwvdGQ+PC90cj4KLSAqPHRyPjx0ZD5qYXZheC54bWwuc3RyZWFtLnN1cHBvcnREVEQ8L3RkPjx0ZD5Vc2UgdGhpcyBwcm9wZXJ0eSB0byByZXF1ZXN0IHByb2Nlc3NvcnMgdGhhdCBkbyBub3Qgc3VwcG9ydCBEVERzPC90ZD48dGQ+Qm9vbGVhbjwvdGQ+PHRkPlRydWU8L3RkPjx0ZD5ZZXM8L3RkPjwvdHI+Ci0gKjx0cj48dGQ+amF2YXgueG1sLnN0cmVhbS5yZXBvcnRlcjwvdGQ+PHRkPnNldHMvZ2V0cyB0aGUgaW1wbCBvZiB0aGUgWE1MUmVwb3J0ZXIgPC90ZD48dGQ+amF2YXgueG1sLnN0cmVhbS5YTUxSZXBvcnRlcjwvdGQ+PHRkPk51bGw8L3RkPjx0ZD5ZZXM8L3RkPjwvdHI+Ci0gKjx0cj48dGQ+amF2YXgueG1sLnN0cmVhbS5yZXNvbHZlcjwvdGQ+PHRkPnNldHMvZ2V0cyB0aGUgaW1wbCBvZiB0aGUgWE1MUmVzb2x2ZXIgaW50ZXJmYWNlPC90ZD48dGQ+amF2YXgueG1sLnN0cmVhbS5YTUxSZXNvbHZlcjwvdGQ+PHRkPk51bGw8L3RkPjx0ZD5ZZXM8L3RkPjwvdHI+Ci0gKjx0cj48dGQ+amF2YXgueG1sLnN0cmVhbS5hbGxvY2F0b3I8L3RkPjx0ZD5zZXRzL2dldHMgdGhlIGltcGwgb2YgdGhlIFhNTEV2ZW50QWxsb2NhdG9yIGludGVyZmFjZTwvdGQ+PHRkPmphdmF4LnhtbC5zdHJlYW0udXRpbC5YTUxFdmVudEFsbG9jYXRvcjwvdGQ+PHRkPk51bGw8L3RkPjx0ZD5ZZXM8L3RkPjwvdHI+Ci0gKiAgICA8L3Rib2R5PgotICogIDwvdGFibGU+Ci0gKgotICoKLSAqIEB2ZXJzaW9uIDEuMgotICogQGF1dGhvciBDb3B5cmlnaHQgKGMpIDIwMDkgYnkgT3JhY2xlIENvcnBvcmF0aW9uLiBBbGwgUmlnaHRzIFJlc2VydmVkLgotICogQHNlZSBYTUxPdXRwdXRGYWN0b3J5Ci0gKiBAc2VlIFhNTEV2ZW50UmVhZGVyCi0gKiBAc2VlIFhNTFN0cmVhbVJlYWRlcgotICogQHNlZSBFdmVudEZpbHRlcgotICogQHNlZSBYTUxSZXBvcnRlcgotICogQHNlZSBYTUxSZXNvbHZlcgotICogQHNlZSBqYXZheC54bWwuc3RyZWFtLnV0aWwuWE1MRXZlbnRBbGxvY2F0b3IKLSAqIEBzaW5jZSAxLjYKLSAqLwotCi1wdWJsaWMgYWJzdHJhY3QgY2xhc3MgWE1MSW5wdXRGYWN0b3J5IHsKLSAgLyoqCi0gICAqIFRoZSBwcm9wZXJ0eSB1c2VkIHRvIHR1cm4gb24vb2ZmIG5hbWVzcGFjZSBzdXBwb3J0LAotICAgKiB0aGlzIGlzIHRvIHN1cHBvcnQgWE1MIDEuMCBkb2N1bWVudHMsCi0gICAqIG9ubHkgdGhlIHRydWUgc2V0dGluZyBtdXN0IGJlIHN1cHBvcnRlZAotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSVNfTkFNRVNQQUNFX0FXQVJFPQotICAgICJqYXZheC54bWwuc3RyZWFtLmlzTmFtZXNwYWNlQXdhcmUiOwotCi0gIC8qKgotICAgKiBUaGUgcHJvcGVydHkgdXNlZCB0byB0dXJuIG9uL29mZiBpbXBsZW1lbnRhdGlvbiBzcGVjaWZpYyB2YWxpZGF0aW9uCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBJU19WQUxJREFUSU5HPQotICAgICJqYXZheC54bWwuc3RyZWFtLmlzVmFsaWRhdGluZyI7Ci0KLSAgLyoqCi0gICAqIFRoZSBwcm9wZXJ0eSB0aGF0IHJlcXVpcmVzIHRoZSBwYXJzZXIgdG8gY29hbGVzY2UgYWRqYWNlbnQgY2hhcmFjdGVyIGRhdGEgc2VjdGlvbnMKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIElTX0NPQUxFU0NJTkc9Ci0gICAgImphdmF4LnhtbC5zdHJlYW0uaXNDb2FsZXNjaW5nIjsKLQotICAvKioKLSAgICogUmVxdWlyZXMgdGhlIHBhcnNlciB0byByZXBsYWNlIGludGVybmFsCi0gICAqIGVudGl0eSByZWZlcmVuY2VzIHdpdGggdGhlaXIgcmVwbGFjZW1lbnQKLSAgICogdGV4dCBhbmQgcmVwb3J0IHRoZW0gYXMgY2hhcmFjdGVycwotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSVNfUkVQTEFDSU5HX0VOVElUWV9SRUZFUkVOQ0VTPQotICAgICJqYXZheC54bWwuc3RyZWFtLmlzUmVwbGFjaW5nRW50aXR5UmVmZXJlbmNlcyI7Ci0KLSAgLyoqCi0gICAqICBUaGUgcHJvcGVydHkgdGhhdCByZXF1aXJlcyB0aGUgcGFyc2VyIHRvIHJlc29sdmUgZXh0ZXJuYWwgcGFyc2VkIGVudGl0aWVzCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBJU19TVVBQT1JUSU5HX0VYVEVSTkFMX0VOVElUSUVTPQotICAgICJqYXZheC54bWwuc3RyZWFtLmlzU3VwcG9ydGluZ0V4dGVybmFsRW50aXRpZXMiOwotCi0gIC8qKgotICAgKiAgVGhlIHByb3BlcnR5IHRoYXQgcmVxdWlyZXMgdGhlIHBhcnNlciB0byBzdXBwb3J0IERURHMKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFNVUFBPUlRfRFREPQotICAgICJqYXZheC54bWwuc3RyZWFtLnN1cHBvcnREVEQiOwotCi0gIC8qKgotICAgKiBUaGUgcHJvcGVydHkgdXNlZCB0bwotICAgKiBzZXQvZ2V0IHRoZSBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgWE1MUmVwb3J0ZXIgaW50ZXJmYWNlCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBSRVBPUlRFUj0KLSAgICAiamF2YXgueG1sLnN0cmVhbS5yZXBvcnRlciI7Ci0KLSAgLyoqCi0gICAqIFRoZSBwcm9wZXJ0eSB1c2VkIHRvIHNldC9nZXQgdGhlIGltcGxlbWVudGF0aW9uIG9mIHRoZSBYTUxSZXNvbHZlcgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgUkVTT0xWRVI9Ci0gICAgImphdmF4LnhtbC5zdHJlYW0ucmVzb2x2ZXIiOwotCi0gIC8qKgotICAgKiBUaGUgcHJvcGVydHkgdXNlZCB0byBzZXQvZ2V0IHRoZSBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgYWxsb2NhdG9yCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBTExPQ0FUT1I9Ci0gICAgImphdmF4LnhtbC5zdHJlYW0uYWxsb2NhdG9yIjsKLQotICBzdGF0aWMgZmluYWwgU3RyaW5nIERFRkFVTElNUEwgPSAiY29tLnN1bi54bWwuaW50ZXJuYWwuc3RyZWFtLlhNTElucHV0RmFjdG9yeUltcGwiOwotCi0gIHByb3RlY3RlZCBYTUxJbnB1dEZhY3RvcnkoKXt9Ci0KLSAgLyoqCi0gICAqIENyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhlIGZhY3RvcnkgaW4gZXhhY3RseSB0aGUgc2FtZSBtYW5uZXIgYXMgdGhlCi0gICAqIHtAbGluayAjbmV3RmFjdG9yeSgpfSBtZXRob2QuCi0gICAqIEB0aHJvd3MgRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvciBpZiBhbiBpbnN0YW5jZSBvZiB0aGlzIGZhY3RvcnkgY2Fubm90IGJlIGxvYWRlZAotICAgKi8KLSAgcHVibGljIHN0YXRpYyBYTUxJbnB1dEZhY3RvcnkgbmV3SW5zdGFuY2UoKQotICAgIHRocm93cyBGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yCi0gIHsKLSAgICByZXR1cm4gRmFjdG9yeUZpbmRlci5maW5kKFhNTElucHV0RmFjdG9yeS5jbGFzcywgREVGQVVMSU1QTCk7Ci0gIH0KLQotICAvKioKLSAgICogQ3JlYXRlIGEgbmV3IGluc3RhbmNlIG9mIHRoZSBmYWN0b3J5LgotICAgKiA8cD4KLSAgICogVGhpcyBzdGF0aWMgbWV0aG9kIGNyZWF0ZXMgYSBuZXcgZmFjdG9yeSBpbnN0YW5jZS4KLSAgICogVGhpcyBtZXRob2QgdXNlcyB0aGUgZm9sbG93aW5nIG9yZGVyZWQgbG9va3VwIHByb2NlZHVyZSB0byBkZXRlcm1pbmUKLSAgICogdGhlIFhNTElucHV0RmFjdG9yeSBpbXBsZW1lbnRhdGlvbiBjbGFzcyB0byBsb2FkOgotICAgKiA8L3A+Ci0gICAqIDx1bD4KLSAgICogPGxpPgotICAgKiAgIFVzZSB0aGUgamF2YXgueG1sLnN0cmVhbS5YTUxJbnB1dEZhY3Rvcnkgc3lzdGVtIHByb3BlcnR5LgotICAgKiA8L2xpPgotICAgKiA8bGk+Ci0gICAqICAgVXNlIHRoZSBwcm9wZXJ0aWVzIGZpbGUgImxpYi9zdGF4LnByb3BlcnRpZXMiIGluIHRoZSBKUkUgZGlyZWN0b3J5LgotICAgKiAgICAgVGhpcyBjb25maWd1cmF0aW9uIGZpbGUgaXMgaW4gc3RhbmRhcmQgamF2YS51dGlsLlByb3BlcnRpZXMgZm9ybWF0Ci0gICAqICAgICBhbmQgY29udGFpbnMgdGhlIGZ1bGx5IHF1YWxpZmllZCBuYW1lIG9mIHRoZSBpbXBsZW1lbnRhdGlvbiBjbGFzcwotICAgKiAgICAgd2l0aCB0aGUga2V5IGJlaW5nIHRoZSBzeXN0ZW0gcHJvcGVydHkgZGVmaW5lZCBhYm92ZS4KLSAgICogPC9saT4KLSAgICogPGxpPgotICAgKiAgIFVzZSB0aGUgc2VydmljZS1wcm92aWRlciBsb2FkaW5nIGZhY2lsaXRpZXMsIGRlZmluZWQgYnkgdGhlCi0gICAqICAge0BsaW5rIGphdmEudXRpbC5TZXJ2aWNlTG9hZGVyfSBjbGFzcywgdG8gYXR0ZW1wdCB0byBsb2NhdGUgYW5kIGxvYWQgYW4KLSAgICogICBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgc2VydmljZSB1c2luZyB0aGUge0BsaW5rcGxhaW4KLSAgICogICBqYXZhLnV0aWwuU2VydmljZUxvYWRlciNsb2FkKGphdmEubGFuZy5DbGFzcykgZGVmYXVsdCBsb2FkaW5nIG1lY2hhbmlzbX06Ci0gICAqICAgdGhlIHNlcnZpY2UtcHJvdmlkZXIgbG9hZGluZyBmYWNpbGl0eSB3aWxsIHVzZSB0aGUge0BsaW5rcGxhaW4KLSAgICogICBqYXZhLmxhbmcuVGhyZWFkI2dldENvbnRleHRDbGFzc0xvYWRlcigpIGN1cnJlbnQgdGhyZWFkJ3MgY29udGV4dCBjbGFzcyBsb2FkZXJ9Ci0gICAqICAgdG8gYXR0ZW1wdCB0byBsb2FkIHRoZSBzZXJ2aWNlLiBJZiB0aGUgY29udGV4dCBjbGFzcwotICAgKiAgIGxvYWRlciBpcyBudWxsLCB0aGUge0BsaW5rcGxhaW4KLSAgICogICBDbGFzc0xvYWRlciNnZXRTeXN0ZW1DbGFzc0xvYWRlcigpIHN5c3RlbSBjbGFzcyBsb2FkZXJ9IHdpbGwgYmUgdXNlZC4KLSAgICogPC9saT4KLSAgICogPGxpPgotICAgKiBPdGhlcndpc2UsIHRoZSBzeXN0ZW0tZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBpcyByZXR1cm5lZC4KLSAgICogPC9saT4KLSAgICogPC91bD4KLSAgICogPHA+Ci0gICAqICAgT25jZSBhbiBhcHBsaWNhdGlvbiBoYXMgb2J0YWluZWQgYSByZWZlcmVuY2UgdG8gYSBYTUxJbnB1dEZhY3RvcnkgaXQKLSAgICogICBjYW4gdXNlIHRoZSBmYWN0b3J5IHRvIGNvbmZpZ3VyZSBhbmQgb2J0YWluIHN0cmVhbSBpbnN0YW5jZXMuCi0gICAqIDwvcD4KLSAgICogPHA+Ci0gICAqICAgTm90ZSB0aGF0IHRoaXMgaXMgYSBuZXcgbWV0aG9kIHRoYXQgcmVwbGFjZXMgdGhlIGRlcHJlY2F0ZWQgbmV3SW5zdGFuY2UoKSBtZXRob2QuCi0gICAqICAgICBObyBjaGFuZ2VzIGluIGJlaGF2aW9yIGFyZSBkZWZpbmVkIGJ5IHRoaXMgcmVwbGFjZW1lbnQgbWV0aG9kIHJlbGF0aXZlIHRvCi0gICAqICAgICB0aGUgZGVwcmVjYXRlZCBtZXRob2QuCi0gICAqIDwvcD4KLSAgICogQHRocm93cyBGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yIGluIGNhc2Ugb2Yge0BsaW5rcGxhaW4KLSAgICogICBqYXZhLnV0aWwuU2VydmljZUNvbmZpZ3VyYXRpb25FcnJvciBzZXJ2aWNlIGNvbmZpZ3VyYXRpb24gZXJyb3J9IG9yIGlmCi0gICAqICAgdGhlIGltcGxlbWVudGF0aW9uIGlzIG5vdCBhdmFpbGFibGUgb3IgY2Fubm90IGJlIGluc3RhbnRpYXRlZC4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgWE1MSW5wdXRGYWN0b3J5IG5ld0ZhY3RvcnkoKQotICAgIHRocm93cyBGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yCi0gIHsKLSAgICByZXR1cm4gRmFjdG9yeUZpbmRlci5maW5kKFhNTElucHV0RmFjdG9yeS5jbGFzcywgREVGQVVMSU1QTCk7Ci0gIH0KLQotICAvKioKLSAgICogQ3JlYXRlIGEgbmV3IGluc3RhbmNlIG9mIHRoZSBmYWN0b3J5Ci0gICAqCi0gICAqIEBwYXJhbSBmYWN0b3J5SWQgICAgICAgICAgICAgTmFtZSBvZiB0aGUgZmFjdG9yeSB0byBmaW5kLCBzYW1lIGFzCi0gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYSBwcm9wZXJ0eSBuYW1lCi0gICAqIEBwYXJhbSBjbGFzc0xvYWRlciAgICAgICAgICAgY2xhc3NMb2FkZXIgdG8gdXNlCi0gICAqIEByZXR1cm4gdGhlIGZhY3RvcnkgaW1wbGVtZW50YXRpb24KLSAgICogQHRocm93cyBGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yIGlmIGFuIGluc3RhbmNlIG9mIHRoaXMgZmFjdG9yeSBjYW5ub3QgYmUgbG9hZGVkCi0gICAqCi0gICAqIEBkZXByZWNhdGVkICBUaGlzIG1ldGhvZCBoYXMgYmVlbiBkZXByZWNhdGVkIHRvIG1haW50YWluIEFQSSBjb25zaXN0ZW5jeS4KLSAgICogICAgICAgICAgICAgIEFsbCBuZXdJbnN0YW5jZSBtZXRob2RzIGhhdmUgYmVlbiByZXBsYWNlZCB3aXRoIGNvcnJlc3BvbmRpbmcKLSAgICogICAgICAgICAgICAgIG5ld0ZhY3RvcnkgbWV0aG9kcy4gVGhlIHJlcGxhY2VtZW50IHtAbGluawotICAgKiAgICAgICAgICAgICAgI25ld0ZhY3RvcnkoamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkNsYXNzTG9hZGVyKX0gbWV0aG9kCi0gICAqICAgICAgICAgICAgICBkZWZpbmVzIG5vIGNoYW5nZXMgaW4gYmVoYXZpb3IuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIFhNTElucHV0RmFjdG9yeSBuZXdJbnN0YW5jZShTdHJpbmcgZmFjdG9yeUlkLAotICAgICAgICAgIENsYXNzTG9hZGVyIGNsYXNzTG9hZGVyKQotICAgICAgICAgIHRocm93cyBGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yIHsKLSAgICAgIC8vZG8gbm90IGZhbGxiYWNrIGlmIGdpdmVuIGNsYXNzbG9hZGVyIGNhbid0IGZpbmQgdGhlIGNsYXNzLCB0aHJvdyBleGNlcHRpb24KLSAgICAgIHJldHVybiBGYWN0b3J5RmluZGVyLmZpbmQoWE1MSW5wdXRGYWN0b3J5LmNsYXNzLCBmYWN0b3J5SWQsIGNsYXNzTG9hZGVyLCBudWxsKTsKLSAgfQotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBuZXcgaW5zdGFuY2Ugb2YgdGhlIGZhY3RvcnkuCi0gICAqIElmIHRoZSBjbGFzc0xvYWRlciBhcmd1bWVudCBpcyBudWxsLCB0aGVuIHRoZSBDb250ZXh0Q2xhc3NMb2FkZXIgaXMgdXNlZC4KLSAgICogPHA+Ci0gICAqIFRoaXMgbWV0aG9kIHVzZXMgdGhlIGZvbGxvd2luZyBvcmRlcmVkIGxvb2t1cCBwcm9jZWR1cmUgdG8gZGV0ZXJtaW5lCi0gICAqIHRoZSBYTUxJbnB1dEZhY3RvcnkgaW1wbGVtZW50YXRpb24gY2xhc3MgdG8gbG9hZDoKLSAgICogPC9wPgotICAgKiA8dWw+Ci0gICAqIDxsaT4KLSAgICogICBVc2UgdGhlIHZhbHVlIG9mIHRoZSBzeXN0ZW0gcHJvcGVydHkgaWRlbnRpZmllZCBieSB7QGNvZGUgZmFjdG9yeUlkfS4KLSAgICogPC9saT4KLSAgICogPGxpPgotICAgKiAgIFVzZSB0aGUgcHJvcGVydGllcyBmaWxlICJsaWIvc3RheC5wcm9wZXJ0aWVzIiBpbiB0aGUgSlJFIGRpcmVjdG9yeS4KLSAgICogICAgIFRoaXMgY29uZmlndXJhdGlvbiBmaWxlIGlzIGluIHN0YW5kYXJkIGphdmEudXRpbC5Qcm9wZXJ0aWVzIGZvcm1hdAotICAgKiAgICAgYW5kIGNvbnRhaW5zIHRoZSBmdWxseSBxdWFsaWZpZWQgbmFtZSBvZiB0aGUgaW1wbGVtZW50YXRpb24gY2xhc3MKLSAgICogICAgIHdpdGggdGhlIGtleSBiZWluZyB0aGUgZ2l2ZW4ge0Bjb2RlIGZhY3RvcnlJZH0uCi0gICAqIDwvbGk+Ci0gICAqIDxsaT4KLSAgICogICBJZiB7QGNvZGUgZmFjdG9yeUlkfSBpcyAiamF2YXgueG1sLnN0cmVhbS5YTUxJbnB1dEZhY3RvcnkiLAotICAgKiAgIHVzZSB0aGUgc2VydmljZS1wcm92aWRlciBsb2FkaW5nIGZhY2lsaXRpZXMsIGRlZmluZWQgYnkgdGhlCi0gICAqICAge0BsaW5rIGphdmEudXRpbC5TZXJ2aWNlTG9hZGVyfSBjbGFzcywgdG8gYXR0ZW1wdCB0byB7QGxpbmtwbGFpbgotICAgKiAgIGphdmEudXRpbC5TZXJ2aWNlTG9hZGVyI2xvYWQoamF2YS5sYW5nLkNsYXNzLCBqYXZhLmxhbmcuQ2xhc3NMb2FkZXIpIGxvY2F0ZSBhbmQgbG9hZH0KLSAgICogICBhbiBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgc2VydmljZSB1c2luZyB0aGUgc3BlY2lmaWVkIHtAY29kZSBDbGFzc0xvYWRlcn0uCi0gICAqICAgSWYge0Bjb2RlIGNsYXNzTG9hZGVyfSBpcyBudWxsLCB0aGUge0BsaW5rcGxhaW4KLSAgICogICBqYXZhLnV0aWwuU2VydmljZUxvYWRlciNsb2FkKGphdmEubGFuZy5DbGFzcykgZGVmYXVsdCBsb2FkaW5nIG1lY2hhbmlzbX0gd2lsbCBhcHBseToKLSAgICogICBUaGF0IGlzLCB0aGUgc2VydmljZS1wcm92aWRlciBsb2FkaW5nIGZhY2lsaXR5IHdpbGwgdXNlIHRoZSB7QGxpbmtwbGFpbgotICAgKiAgIGphdmEubGFuZy5UaHJlYWQjZ2V0Q29udGV4dENsYXNzTG9hZGVyKCkgY3VycmVudCB0aHJlYWQncyBjb250ZXh0IGNsYXNzIGxvYWRlcn0KLSAgICogICB0byBhdHRlbXB0IHRvIGxvYWQgdGhlIHNlcnZpY2UuIElmIHRoZSBjb250ZXh0IGNsYXNzCi0gICAqICAgbG9hZGVyIGlzIG51bGwsIHRoZSB7QGxpbmtwbGFpbgotICAgKiAgIENsYXNzTG9hZGVyI2dldFN5c3RlbUNsYXNzTG9hZGVyKCkgc3lzdGVtIGNsYXNzIGxvYWRlcn0gd2lsbCBiZSB1c2VkLgotICAgKiA8L2xpPgotICAgKiA8bGk+Ci0gICAqICAgT3RoZXJ3aXNlLCB0aHJvd3MgYSB7QGxpbmsgRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvcn0uCi0gICAqIDwvbGk+Ci0gICAqIDwvdWw+Ci0gICAqCi0gICAqIDxwPgotICAgKiBOb3RlIHRoYXQgdGhpcyBpcyBhIG5ldyBtZXRob2QgdGhhdCByZXBsYWNlcyB0aGUgZGVwcmVjYXRlZAotICAgKiAgIHtAbGluayAjbmV3SW5zdGFuY2UoamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkNsYXNzTG9hZGVyKQotICAgKiAgIG5ld0luc3RhbmNlKFN0cmluZyBmYWN0b3J5SWQsIENsYXNzTG9hZGVyIGNsYXNzTG9hZGVyKX0gbWV0aG9kLgotICAgKiBObyBjaGFuZ2VzIGluIGJlaGF2aW9yIGFyZSBkZWZpbmVkIGJ5IHRoaXMgcmVwbGFjZW1lbnQgbWV0aG9kIHJlbGF0aXZlCi0gICAqIHRvIHRoZSBkZXByZWNhdGVkIG1ldGhvZC4KLSAgICogPC9wPgotICAgKgotICAgKiBAYXBpTm90ZSBUaGUgcGFyYW1ldGVyIGZhY3RvcnlJZCBkZWZpbmVkIGhlcmUgaXMgaW5jb25zaXN0ZW50IHdpdGggdGhhdAotICAgKiBvZiBvdGhlciBKQVhQIGZhY3RvcmllcyB3aGVyZSB0aGUgZmlyc3QgcGFyYW1ldGVyIGlzIGZ1bGx5IHF1YWxpZmllZAotICAgKiBmYWN0b3J5IGNsYXNzIG5hbWUgdGhhdCBwcm92aWRlcyBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgZmFjdG9yeS4KLSAgICoKLSAgICogQHBhcmFtIGZhY3RvcnlJZCAgICAgICAgICAgICBOYW1lIG9mIHRoZSBmYWN0b3J5IHRvIGZpbmQsIHNhbWUgYXMKLSAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhIHByb3BlcnR5IG5hbWUKLSAgICogQHBhcmFtIGNsYXNzTG9hZGVyICAgICAgICAgICBjbGFzc0xvYWRlciB0byB1c2UKLSAgICogQHJldHVybiB0aGUgZmFjdG9yeSBpbXBsZW1lbnRhdGlvbgotICAgKiBAdGhyb3dzIEZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IgaW4gY2FzZSBvZiB7QGxpbmtwbGFpbgotICAgKiAgIGphdmEudXRpbC5TZXJ2aWNlQ29uZmlndXJhdGlvbkVycm9yIHNlcnZpY2UgY29uZmlndXJhdGlvbiBlcnJvcn0gb3IgaWYKLSAgICogICB0aGUgaW1wbGVtZW50YXRpb24gaXMgbm90IGF2YWlsYWJsZSBvciBjYW5ub3QgYmUgaW5zdGFudGlhdGVkLgotICAgKiBAdGhyb3dzIEZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IgaWYgYW4gaW5zdGFuY2Ugb2YgdGhpcyBmYWN0b3J5IGNhbm5vdCBiZSBsb2FkZWQKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgWE1MSW5wdXRGYWN0b3J5IG5ld0ZhY3RvcnkoU3RyaW5nIGZhY3RvcnlJZCwKLSAgICAgICAgICBDbGFzc0xvYWRlciBjbGFzc0xvYWRlcikKLSAgICAgICAgICB0aHJvd3MgRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvciB7Ci0gICAgICAvL2RvIG5vdCBmYWxsYmFjayBpZiBnaXZlbiBjbGFzc2xvYWRlciBjYW4ndCBmaW5kIHRoZSBjbGFzcywgdGhyb3cgZXhjZXB0aW9uCi0gICAgICByZXR1cm4gRmFjdG9yeUZpbmRlci5maW5kKFhNTElucHV0RmFjdG9yeS5jbGFzcywgZmFjdG9yeUlkLCBjbGFzc0xvYWRlciwgbnVsbCk7Ci0gIH0KLQotICAvKioKLSAgICogQ3JlYXRlIGEgbmV3IFhNTFN0cmVhbVJlYWRlciBmcm9tIGEgcmVhZGVyCi0gICAqIEBwYXJhbSByZWFkZXIgdGhlIFhNTCBkYXRhIHRvIHJlYWQgZnJvbQotICAgKiBAdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IFhNTFN0cmVhbVJlYWRlciBjcmVhdGVYTUxTdHJlYW1SZWFkZXIoamF2YS5pby5SZWFkZXIgcmVhZGVyKQotICAgIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb247Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIG5ldyBYTUxTdHJlYW1SZWFkZXIgZnJvbSBhIEpBWFAgc291cmNlLiAgVGhpcyBtZXRob2QgaXMgb3B0aW9uYWwuCi0gICAqIEBwYXJhbSBzb3VyY2UgdGhlIHNvdXJjZSB0byByZWFkIGZyb20KLSAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBpZiB0aGlzIG1ldGhvZCBpcyBub3QKLSAgICogc3VwcG9ydGVkIGJ5IHRoaXMgWE1MSW5wdXRGYWN0b3J5Ci0gICAqIEB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgWE1MU3RyZWFtUmVhZGVyIGNyZWF0ZVhNTFN0cmVhbVJlYWRlcihTb3VyY2Ugc291cmNlKQotICAgIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb247Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIG5ldyBYTUxTdHJlYW1SZWFkZXIgZnJvbSBhIGphdmEuaW8uSW5wdXRTdHJlYW0KLSAgICogQHBhcmFtIHN0cmVhbSB0aGUgSW5wdXRTdHJlYW0gdG8gcmVhZCBmcm9tCi0gICAqIEB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgWE1MU3RyZWFtUmVhZGVyIGNyZWF0ZVhNTFN0cmVhbVJlYWRlcihqYXZhLmlvLklucHV0U3RyZWFtIHN0cmVhbSkKLSAgICB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uOwotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBuZXcgWE1MU3RyZWFtUmVhZGVyIGZyb20gYSBqYXZhLmlvLklucHV0U3RyZWFtCi0gICAqIEBwYXJhbSBzdHJlYW0gdGhlIElucHV0U3RyZWFtIHRvIHJlYWQgZnJvbQotICAgKiBAcGFyYW0gZW5jb2RpbmcgdGhlIGNoYXJhY3RlciBlbmNvZGluZyBvZiB0aGUgc3RyZWFtCi0gICAqIEB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgWE1MU3RyZWFtUmVhZGVyIGNyZWF0ZVhNTFN0cmVhbVJlYWRlcihqYXZhLmlvLklucHV0U3RyZWFtIHN0cmVhbSwgU3RyaW5nIGVuY29kaW5nKQotICAgIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb247Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIG5ldyBYTUxTdHJlYW1SZWFkZXIgZnJvbSBhIGphdmEuaW8uSW5wdXRTdHJlYW0KLSAgICogQHBhcmFtIHN5c3RlbUlkIHRoZSBzeXN0ZW0gSUQgb2YgdGhlIHN0cmVhbQotICAgKiBAcGFyYW0gc3RyZWFtIHRoZSBJbnB1dFN0cmVhbSB0byByZWFkIGZyb20KLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBYTUxTdHJlYW1SZWFkZXIgY3JlYXRlWE1MU3RyZWFtUmVhZGVyKFN0cmluZyBzeXN0ZW1JZCwgamF2YS5pby5JbnB1dFN0cmVhbSBzdHJlYW0pCi0gICAgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbjsKLQotICAvKioKLSAgICogQ3JlYXRlIGEgbmV3IFhNTFN0cmVhbVJlYWRlciBmcm9tIGEgamF2YS5pby5JbnB1dFN0cmVhbQotICAgKiBAcGFyYW0gc3lzdGVtSWQgdGhlIHN5c3RlbSBJRCBvZiB0aGUgc3RyZWFtCi0gICAqIEBwYXJhbSByZWFkZXIgdGhlIElucHV0U3RyZWFtIHRvIHJlYWQgZnJvbQotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IFhNTFN0cmVhbVJlYWRlciBjcmVhdGVYTUxTdHJlYW1SZWFkZXIoU3RyaW5nIHN5c3RlbUlkLCBqYXZhLmlvLlJlYWRlciByZWFkZXIpCi0gICAgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbjsKLQotICAvKioKLSAgICogQ3JlYXRlIGEgbmV3IFhNTEV2ZW50UmVhZGVyIGZyb20gYSByZWFkZXIKLSAgICogQHBhcmFtIHJlYWRlciB0aGUgWE1MIGRhdGEgdG8gcmVhZCBmcm9tCi0gICAqIEB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgWE1MRXZlbnRSZWFkZXIgY3JlYXRlWE1MRXZlbnRSZWFkZXIoamF2YS5pby5SZWFkZXIgcmVhZGVyKQotICAgIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb247Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIG5ldyBYTUxFdmVudFJlYWRlciBmcm9tIGEgcmVhZGVyCi0gICAqIEBwYXJhbSBzeXN0ZW1JZCB0aGUgc3lzdGVtIElEIG9mIHRoZSBpbnB1dAotICAgKiBAcGFyYW0gcmVhZGVyIHRoZSBYTUwgZGF0YSB0byByZWFkIGZyb20KLSAgICogQHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBYTUxFdmVudFJlYWRlciBjcmVhdGVYTUxFdmVudFJlYWRlcihTdHJpbmcgc3lzdGVtSWQsIGphdmEuaW8uUmVhZGVyIHJlYWRlcikKLSAgICB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uOwotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBuZXcgWE1MRXZlbnRSZWFkZXIgZnJvbSBhbiBYTUxTdHJlYW1SZWFkZXIuICBBZnRlciBiZWluZyB1c2VkCi0gICAqIHRvIGNvbnN0cnVjdCB0aGUgWE1MRXZlbnRSZWFkZXIgaW5zdGFuY2UgcmV0dXJuZWQgZnJvbSB0aGlzIG1ldGhvZAotICAgKiB0aGUgWE1MU3RyZWFtUmVhZGVyIG11c3Qgbm90IGJlIHVzZWQuCi0gICAqIEBwYXJhbSByZWFkZXIgdGhlIFhNTFN0cmVhbVJlYWRlciB0byByZWFkIGZyb20gKG1heSBub3QgYmUgbW9kaWZpZWQpCi0gICAqIEByZXR1cm4gYSBuZXcgWE1MRXZlbnRSZWFkZXIKLSAgICogQHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBYTUxFdmVudFJlYWRlciBjcmVhdGVYTUxFdmVudFJlYWRlcihYTUxTdHJlYW1SZWFkZXIgcmVhZGVyKQotICAgIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb247Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIG5ldyBYTUxFdmVudFJlYWRlciBmcm9tIGEgSkFYUCBzb3VyY2UuCi0gICAqIFN1cHBvcnQgb2YgdGhpcyBtZXRob2QgaXMgb3B0aW9uYWwuCi0gICAqIEBwYXJhbSBzb3VyY2UgdGhlIHNvdXJjZSB0byByZWFkIGZyb20KLSAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBpZiB0aGlzIG1ldGhvZCBpcyBub3QKLSAgICogc3VwcG9ydGVkIGJ5IHRoaXMgWE1MSW5wdXRGYWN0b3J5Ci0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgWE1MRXZlbnRSZWFkZXIgY3JlYXRlWE1MRXZlbnRSZWFkZXIoU291cmNlIHNvdXJjZSkKLSAgICB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uOwotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBuZXcgWE1MRXZlbnRSZWFkZXIgZnJvbSBhIGphdmEuaW8uSW5wdXRTdHJlYW0KLSAgICogQHBhcmFtIHN0cmVhbSB0aGUgSW5wdXRTdHJlYW0gdG8gcmVhZCBmcm9tCi0gICAqIEB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgWE1MRXZlbnRSZWFkZXIgY3JlYXRlWE1MRXZlbnRSZWFkZXIoamF2YS5pby5JbnB1dFN0cmVhbSBzdHJlYW0pCi0gICAgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbjsKLQotICAvKioKLSAgICogQ3JlYXRlIGEgbmV3IFhNTEV2ZW50UmVhZGVyIGZyb20gYSBqYXZhLmlvLklucHV0U3RyZWFtCi0gICAqIEBwYXJhbSBzdHJlYW0gdGhlIElucHV0U3RyZWFtIHRvIHJlYWQgZnJvbQotICAgKiBAcGFyYW0gZW5jb2RpbmcgdGhlIGNoYXJhY3RlciBlbmNvZGluZyBvZiB0aGUgc3RyZWFtCi0gICAqIEB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgWE1MRXZlbnRSZWFkZXIgY3JlYXRlWE1MRXZlbnRSZWFkZXIoamF2YS5pby5JbnB1dFN0cmVhbSBzdHJlYW0sIFN0cmluZyBlbmNvZGluZykKLSAgICB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uOwotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBuZXcgWE1MRXZlbnRSZWFkZXIgZnJvbSBhIGphdmEuaW8uSW5wdXRTdHJlYW0KLSAgICogQHBhcmFtIHN5c3RlbUlkIHRoZSBzeXN0ZW0gSUQgb2YgdGhlIHN0cmVhbQotICAgKiBAcGFyYW0gc3RyZWFtIHRoZSBJbnB1dFN0cmVhbSB0byByZWFkIGZyb20KLSAgICogQHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBYTUxFdmVudFJlYWRlciBjcmVhdGVYTUxFdmVudFJlYWRlcihTdHJpbmcgc3lzdGVtSWQsIGphdmEuaW8uSW5wdXRTdHJlYW0gc3RyZWFtKQotICAgIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb247Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIGZpbHRlcmVkIHJlYWRlciB0aGF0IHdyYXBzIHRoZSBmaWx0ZXIgYXJvdW5kIHRoZSByZWFkZXIKLSAgICogQHBhcmFtIHJlYWRlciB0aGUgcmVhZGVyIHRvIGZpbHRlcgotICAgKiBAcGFyYW0gZmlsdGVyIHRoZSBmaWx0ZXIgdG8gYXBwbHkgdG8gdGhlIHJlYWRlcgotICAgKiBAdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IFhNTFN0cmVhbVJlYWRlciBjcmVhdGVGaWx0ZXJlZFJlYWRlcihYTUxTdHJlYW1SZWFkZXIgcmVhZGVyLCBTdHJlYW1GaWx0ZXIgZmlsdGVyKQotICAgIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb247Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIGZpbHRlcmVkIGV2ZW50IHJlYWRlciB0aGF0IHdyYXBzIHRoZSBmaWx0ZXIgYXJvdW5kIHRoZSBldmVudCByZWFkZXIKLSAgICogQHBhcmFtIHJlYWRlciB0aGUgZXZlbnQgcmVhZGVyIHRvIHdyYXAKLSAgICogQHBhcmFtIGZpbHRlciB0aGUgZmlsdGVyIHRvIGFwcGx5IHRvIHRoZSBldmVudCByZWFkZXIKLSAgICogQHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBYTUxFdmVudFJlYWRlciBjcmVhdGVGaWx0ZXJlZFJlYWRlcihYTUxFdmVudFJlYWRlciByZWFkZXIsIEV2ZW50RmlsdGVyIGZpbHRlcikKLSAgICB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uOwotCi0gIC8qKgotICAgKiBUaGUgcmVzb2x2ZXIgdGhhdCB3aWxsIGJlIHNldCBvbiBhbnkgWE1MU3RyZWFtUmVhZGVyIG9yIFhNTEV2ZW50UmVhZGVyIGNyZWF0ZWQKLSAgICogYnkgdGhpcyBmYWN0b3J5IGluc3RhbmNlLgotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IFhNTFJlc29sdmVyIGdldFhNTFJlc29sdmVyKCk7Ci0KLSAgLyoqCi0gICAqIFRoZSByZXNvbHZlciB0aGF0IHdpbGwgYmUgc2V0IG9uIGFueSBYTUxTdHJlYW1SZWFkZXIgb3IgWE1MRXZlbnRSZWFkZXIgY3JlYXRlZAotICAgKiBieSB0aGlzIGZhY3RvcnkgaW5zdGFuY2UuCi0gICAqIEBwYXJhbSByZXNvbHZlciB0aGUgcmVzb2x2ZXIgdG8gdXNlIHRvIHJlc29sdmUgcmVmZXJlbmNlcwotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IHZvaWQgIHNldFhNTFJlc29sdmVyKFhNTFJlc29sdmVyIHJlc29sdmVyKTsKLQotICAvKioKLSAgICogVGhlIHJlcG9ydGVyIHRoYXQgd2lsbCBiZSBzZXQgb24gYW55IFhNTFN0cmVhbVJlYWRlciBvciBYTUxFdmVudFJlYWRlciBjcmVhdGVkCi0gICAqIGJ5IHRoaXMgZmFjdG9yeSBpbnN0YW5jZS4KLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBYTUxSZXBvcnRlciBnZXRYTUxSZXBvcnRlcigpOwotCi0gIC8qKgotICAgKiBUaGUgcmVwb3J0ZXIgdGhhdCB3aWxsIGJlIHNldCBvbiBhbnkgWE1MU3RyZWFtUmVhZGVyIG9yIFhNTEV2ZW50UmVhZGVyIGNyZWF0ZWQKLSAgICogYnkgdGhpcyBmYWN0b3J5IGluc3RhbmNlLgotICAgKiBAcGFyYW0gcmVwb3J0ZXIgdGhlIHJlc29sdmVyIHRvIHVzZSB0byByZXBvcnQgbm9uIGZhdGFsIGVycm9ycwotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IHZvaWQgc2V0WE1MUmVwb3J0ZXIoWE1MUmVwb3J0ZXIgcmVwb3J0ZXIpOwotCi0gIC8qKgotICAgKiBBbGxvd3MgdGhlIHVzZXIgdG8gc2V0IHNwZWNpZmljIGZlYXR1cmUvcHJvcGVydHkgb24gdGhlIHVuZGVybHlpbmcKLSAgICogaW1wbGVtZW50YXRpb24uIFRoZSB1bmRlcmx5aW5nIGltcGxlbWVudGF0aW9uIGlzIG5vdCByZXF1aXJlZCB0byBzdXBwb3J0Ci0gICAqIGV2ZXJ5IHNldHRpbmcgb2YgZXZlcnkgcHJvcGVydHkgaW4gdGhlIHNwZWNpZmljYXRpb24gYW5kIG1heSB1c2UKLSAgICogSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHRvIHNpZ25hbCB0aGF0IGFuIHVuc3VwcG9ydGVkIHByb3BlcnR5IG1heSBub3QgYmUKLSAgICogc2V0IHdpdGggdGhlIHNwZWNpZmllZCB2YWx1ZS4KLSAgICogPHA+Ci0gICAqIEFsbCBpbXBsZW1lbnRhdGlvbnMgdGhhdCBpbXBsZW1lbnQgSkFYUCAxLjUgb3IgbmV3ZXIgYXJlIHJlcXVpcmVkIHRvCi0gICAqIHN1cHBvcnQgdGhlIHtAbGluayBqYXZheC54bWwuWE1MQ29uc3RhbnRzI0FDQ0VTU19FWFRFUk5BTF9EVER9IHByb3BlcnR5LgotICAgKiA8L3A+Ci0gICAqIDx1bD4KLSAgICogICA8bGk+Ci0gICAqICAgICAgICA8cD4KLSAgICogICAgICAgIEFjY2VzcyB0byBleHRlcm5hbCBEVERzLCBleHRlcm5hbCBFbnRpdHkgUmVmZXJlbmNlcyBpcyByZXN0cmljdGVkIHRvIHRoZQotICAgKiAgICAgICAgcHJvdG9jb2xzIHNwZWNpZmllZCBieSB0aGUgcHJvcGVydHkuIElmIGFjY2VzcyBpcyBkZW5pZWQgZHVyaW5nIHBhcnNpbmcKLSAgICogICAgICAgIGR1ZSB0byB0aGUgcmVzdHJpY3Rpb24gb2YgdGhpcyBwcm9wZXJ0eSwge0BsaW5rIGphdmF4LnhtbC5zdHJlYW0uWE1MU3RyZWFtRXhjZXB0aW9ufQotICAgKiAgICAgICAgd2lsbCBiZSB0aHJvd24gYnkgdGhlIHtAbGluayBqYXZheC54bWwuc3RyZWFtLlhNTFN0cmVhbVJlYWRlciNuZXh0KCl9IG9yCi0gICAqICAgICAgICB7QGxpbmsgamF2YXgueG1sLnN0cmVhbS5YTUxFdmVudFJlYWRlciNuZXh0RXZlbnQoKX0gbWV0aG9kLgotICAgKiAgICAgICAgPC9wPgotICAgKiAgIDwvbGk+Ci0gICAqIDwvdWw+Ci0gICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBwcm9wZXJ0eSAobWF5IG5vdCBiZSBudWxsKQotICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlIG9mIHRoZSBwcm9wZXJ0eQotICAgKiBAdGhyb3dzIGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgdGhlIHByb3BlcnR5IGlzIG5vdCBzdXBwb3J0ZWQKLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHNldFByb3BlcnR5KGphdmEubGFuZy5TdHJpbmcgbmFtZSwgT2JqZWN0IHZhbHVlKQotICAgIHRocm93cyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uOwotCi0gIC8qKgotICAgKiBHZXQgdGhlIHZhbHVlIG9mIGEgZmVhdHVyZS9wcm9wZXJ0eSBmcm9tIHRoZSB1bmRlcmx5aW5nIGltcGxlbWVudGF0aW9uCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBwcm9wZXJ0eSAobWF5IG5vdCBiZSBudWxsKQotICAgKiBAcmV0dXJuIFRoZSB2YWx1ZSBvZiB0aGUgcHJvcGVydHkKLSAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgdGhlIHByb3BlcnR5IGlzIG5vdCBzdXBwb3J0ZWQKLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBPYmplY3QgZ2V0UHJvcGVydHkoamF2YS5sYW5nLlN0cmluZyBuYW1lKQotICAgIHRocm93cyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uOwotCi0KLSAgLyoqCi0gICAqIFF1ZXJ5IHRoZSBzZXQgb2YgcHJvcGVydGllcyB0aGF0IHRoaXMgZmFjdG9yeSBzdXBwb3J0cy4KLSAgICoKLSAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIHByb3BlcnR5IChtYXkgbm90IGJlIG51bGwpCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgcHJvcGVydHkgaXMgc3VwcG9ydGVkIGFuZCBmYWxzZSBvdGhlcndpc2UKLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGlzUHJvcGVydHlTdXBwb3J0ZWQoU3RyaW5nIG5hbWUpOwotCi0gIC8qKgotICAgKiBTZXQgYSB1c2VyIGRlZmluZWQgZXZlbnQgYWxsb2NhdG9yIGZvciBldmVudHMKLSAgICogQHBhcmFtIGFsbG9jYXRvciB0aGUgdXNlciBkZWZpbmVkIGFsbG9jYXRvcgotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IHZvaWQgc2V0RXZlbnRBbGxvY2F0b3IoWE1MRXZlbnRBbGxvY2F0b3IgYWxsb2NhdG9yKTsKLQotICAvKioKLSAgICogR2V0cyB0aGUgYWxsb2NhdG9yIHVzZWQgYnkgc3RyZWFtcyBjcmVhdGVkIHdpdGggdGhpcyBmYWN0b3J5Ci0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgWE1MRXZlbnRBbGxvY2F0b3IgZ2V0RXZlbnRBbGxvY2F0b3IoKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmF4L3htbC9zdHJlYW0vWE1MT3V0cHV0RmFjdG9yeS5qYXZhIGIvc3JjL2phdmF4L3htbC9zdHJlYW0vWE1MT3V0cHV0RmFjdG9yeS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlODc1YWMyLi4wMDAwMDAwCi0tLSBhL3NyYy9qYXZheC94bWwvc3RyZWFtL1hNTE91dHB1dEZhY3RvcnkuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDM1OSArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogQ29weXJpZ2h0IChjKSAyMDA5LCAyMDEzLCBieSBPcmFjbGUgQ29ycG9yYXRpb24uIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCi0gKi8KLQotcGFja2FnZSBqYXZheC54bWwuc3RyZWFtOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5SZXN1bHQ7Ci0KLS8qKgotICogRGVmaW5lcyBhbiBhYnN0cmFjdCBpbXBsZW1lbnRhdGlvbiBvZiBhIGZhY3RvcnkgZm9yCi0gKiBnZXR0aW5nIFhNTEV2ZW50V3JpdGVycyBhbmQgWE1MU3RyZWFtV3JpdGVycy4KLSAqCi0gKiBUaGUgZm9sbG93aW5nIHRhYmxlIGRlZmluZXMgdGhlIHN0YW5kYXJkIHByb3BlcnRpZXMgb2YgdGhpcyBzcGVjaWZpY2F0aW9uLgotICogRWFjaCBwcm9wZXJ0eSB2YXJpZXMgaW4gdGhlIGxldmVsIG9mIHN1cHBvcnQgcmVxdWlyZWQgYnkgZWFjaCBpbXBsZW1lbnRhdGlvbi4KLSAqIFRoZSBsZXZlbCBvZiBzdXBwb3J0IHJlcXVpcmVkIGlzIGRlc2NyaWJlZCBpbiB0aGUgJ1JlcXVpcmVkJyBjb2x1bW4uCi0gKgotICogICAgIDx0YWJsZSBib3JkZXI9IjIiIHJ1bGVzPSJhbGwiIGNlbGxwYWRkaW5nPSI0Ij4KLSAqICAgICA8dGhlYWQ+Ci0gKiAgICAgIDx0cj4KLSAqICAgICAgICA8dGggYWxpZ249ImNlbnRlciIgY29sc3Bhbj0iMiI+Ci0gKiAgICAgICAgICBDb25maWd1cmF0aW9uIHBhcmFtZXRlcnMKLSAqICAgICAgICA8L3RoPgotICogICAgICA8L3RyPgotICogICAgPC90aGVhZD4KLSAqICAgIDx0Ym9keT4KLSAqICAgICAgPHRyPgotICogICAgICAgIDx0aD5Qcm9wZXJ0eSBOYW1lPC90aD4KLSAqICAgICAgICA8dGg+QmVoYXZpb3I8L3RoPgotICogICAgICAgIDx0aD5SZXR1cm4gdHlwZTwvdGg+Ci0gKiAgICAgICAgPHRoPkRlZmF1bHQgVmFsdWU8L3RoPgotICogICAgICAgIDx0aD5SZXF1aXJlZDwvdGg+Ci0gKiAgICAgICAgICAgICAgPC90cj4KLSAqICAgICAgICAgPHRyPjx0ZD5qYXZheC54bWwuc3RyZWFtLmlzUmVwYWlyaW5nTmFtZXNwYWNlczwvdGQ+PHRkPmRlZmF1bHRzIHByZWZpeGVzIG9uIHRoZSBvdXRwdXQgc2lkZTwvdGQ+PHRkPkJvb2xlYW48L3RkPjx0ZD5GYWxzZTwvdGQ+PHRkPlllczwvdGQ+PC90cj4KLSAqICAgICAgPC90Ym9keT4KLSAqICAgPC90YWJsZT4KLSAqCi0gKiA8cD5UaGUgZm9sbG93aW5nIHBhcmFncmFwaHMgZGVzY3JpYmUgdGhlIG5hbWVzcGFjZSBhbmQgcHJlZml4IHJlcGFpciBhbGdvcml0aG06PC9wPgotICoKLSAqIDxwPlRoZSBwcm9wZXJ0eSBjYW4gYmUgc2V0IHdpdGggdGhlIGZvbGxvd2luZyBjb2RlIGxpbmU6Ci0gKiA8Y29kZT5zZXRQcm9wZXJ0eSgiamF2YXgueG1sLnN0cmVhbS5pc1JlcGFpcmluZ05hbWVzcGFjZXMiLG5ldyBCb29sZWFuKHRydWV8ZmFsc2UpKTs8L2NvZGU+PC9wPgotICoKLSAqIDxwPlRoaXMgcHJvcGVydHkgc3BlY2lmaWVzIHRoYXQgdGhlIHdyaXRlciBkZWZhdWx0IG5hbWVzcGFjZSBwcmVmaXggZGVjbGFyYXRpb25zLgotICogVGhlIGRlZmF1bHQgdmFsdWUgaXMgZmFsc2UuIDwvcD4KLSAqCi0gKiA8cD5JZiBhIHdyaXRlciBpc1JlcGFpcmluZ05hbWVzcGFjZXMgaXQgd2lsbCBjcmVhdGUgYSBuYW1lc3BhY2UgZGVjbGFyYXRpb24KLSAqIG9uIHRoZSBjdXJyZW50IFN0YXJ0RWxlbWVudCBmb3IKLSAqIGFueSBhdHRyaWJ1dGUgdGhhdCBkb2VzIG5vdAotICogY3VycmVudGx5IGhhdmUgYSBuYW1lc3BhY2UgZGVjbGFyYXRpb24gaW4gc2NvcGUuICBJZiB0aGUgU3RhcnRFbGVtZW50Ci0gKiBoYXMgYSB1cmkgYnV0IG5vIHByZWZpeCBzcGVjaWZpZWQgYSBwcmVmaXggd2lsbCBiZSBhc3NpZ25lZCwgaWYgdGhlIHByZWZpeAotICogaGFzIG5vdCBiZWVuIGRlY2xhcmVkIGluIGEgcGFyZW50IG9mIHRoZSBjdXJyZW50IFN0YXJ0RWxlbWVudCBpdCB3aWxsIGJlIGRlY2xhcmVkCi0gKiBvbiB0aGUgY3VycmVudCBTdGFydEVsZW1lbnQuICBJZiB0aGUgZGVmYXVsdE5hbWVzcGFjZSBpcyBib3VuZCBhbmQgaW4gc2NvcGUKLSAqIGFuZCB0aGUgZGVmYXVsdCBuYW1lc3BhY2UgbWF0Y2hlcyB0aGUgVVJJIG9mIHRoZSBhdHRyaWJ1dGUgb3IgU3RhcnRFbGVtZW50Ci0gKiBRTmFtZSBubyBwcmVmaXggd2lsbCBiZSBhc3NpZ25lZC48L3A+Ci0gKgotICogPHA+SWYgYW4gZWxlbWVudCBvciBhdHRyaWJ1dGUgbmFtZSBoYXMgYSBwcmVmaXgsIGJ1dCBpcyBub3QKLSAqIGJvdW5kIHRvIGFueSBuYW1lc3BhY2UgVVJJLCB0aGVuIHRoZSBwcmVmaXggd2lsbCBiZSByZW1vdmVkCi0gKiBkdXJpbmcgc2VyaWFsaXphdGlvbi48L3A+Ci0gKgotICogPHA+SWYgZWxlbWVudCBhbmQvb3IgYXR0cmlidXRlIG5hbWVzIGluIHRoZSBzYW1lIHN0YXJ0IG9yCi0gKiBlbXB0eS1lbGVtZW50IHRhZyBhcmUgYm91bmQgdG8gZGlmZmVyZW50IG5hbWVzcGFjZSBVUklzIGFuZAotICogYXJlIHVzaW5nIHRoZSBzYW1lIHByZWZpeCB0aGVuIHRoZSBlbGVtZW50IG9yIHRoZSBmaXJzdAotICogb2NjdXJyaW5nIGF0dHJpYnV0ZSByZXRhaW5zIHRoZSBvcmlnaW5hbCBwcmVmaXggYW5kIHRoZQotICogZm9sbG93aW5nIGF0dHJpYnV0ZXMgaGF2ZSB0aGVpciBwcmVmaXhlcyByZXBsYWNlZCB3aXRoIGEKLSAqIG5ldyBwcmVmaXggdGhhdCBpcyBib3VuZCB0byB0aGUgbmFtZXNwYWNlIFVSSXMgb2YgdGhvc2UKLSAqIGF0dHJpYnV0ZXMuIDwvcD4KLSAqCi0gKiA8cD5JZiBhbiBlbGVtZW50IG9yIGF0dHJpYnV0ZSBuYW1lIHVzZXMgYSBwcmVmaXggdGhhdCBpcwotICogYm91bmQgdG8gYSBkaWZmZXJlbnQgVVJJIHRoYW4gdGhhdCBpbmhlcml0ZWQgZnJvbSB0aGUKLSAqIG5hbWVzcGFjZSBjb250ZXh0IG9mIHRoZSBwYXJlbnQgb2YgdGhhdCBlbGVtZW50IGFuZCB0aGVyZQotICogaXMgbm8gbmFtZXNwYWNlIGRlY2xhcmF0aW9uIGluIHRoZSBjb250ZXh0IG9mIHRoZSBjdXJyZW50Ci0gKiBlbGVtZW50IHRoZW4gc3VjaCBhIG5hbWVzcGFjZSBkZWNsYXJhdGlvbiBpcyBhZGRlZC4gPC9wPgotICoKLSAqIDxwPklmIGFuIGVsZW1lbnQgb3IgYXR0cmlidXRlIG5hbWUgaXMgYm91bmQgdG8gYSBwcmVmaXggYW5kCi0gKiB0aGVyZSBpcyBhIG5hbWVzcGFjZSBkZWNsYXJhdGlvbiB0aGF0IGJpbmRzIHRoYXQgcHJlZml4Ci0gKiB0byBhIGRpZmZlcmVudCBVUkkgdGhlbiB0aGF0IG5hbWVzcGFjZSBkZWNsYXJhdGlvbiBpcwotICogZWl0aGVyIHJlbW92ZWQgaWYgdGhlIGNvcnJlY3QgbWFwcGluZyBpcyBpbmhlcml0ZWQgZnJvbQotICogdGhlIHBhcmVudCBjb250ZXh0IG9mIHRoYXQgZWxlbWVudCwgb3IgY2hhbmdlZCB0byB0aGUKLSAqIG5hbWVzcGFjZSBVUkkgb2YgdGhlIGVsZW1lbnQgb3IgYXR0cmlidXRlIHVzaW5nIHRoYXQgcHJlZml4LjwvcD4KLSAqCi0gKiBAdmVyc2lvbiAxLjIKLSAqIEBhdXRob3IgQ29weXJpZ2h0IChjKSAyMDA5IGJ5IE9yYWNsZSBDb3Jwb3JhdGlvbi4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KLSAqIEBzZWUgWE1MSW5wdXRGYWN0b3J5Ci0gKiBAc2VlIFhNTEV2ZW50V3JpdGVyCi0gKiBAc2VlIFhNTFN0cmVhbVdyaXRlcgotICogQHNpbmNlIDEuNgotICovCi1wdWJsaWMgYWJzdHJhY3QgY2xhc3MgWE1MT3V0cHV0RmFjdG9yeSB7Ci0gIC8qKgotICAgKiBQcm9wZXJ0eSB1c2VkIHRvIHNldCBwcmVmaXggZGVmYXVsdGluZyBvbiB0aGUgb3V0cHV0IHNpZGUKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIElTX1JFUEFJUklOR19OQU1FU1BBQ0VTPQotICAgICJqYXZheC54bWwuc3RyZWFtLmlzUmVwYWlyaW5nTmFtZXNwYWNlcyI7Ci0KLSAgc3RhdGljIGZpbmFsIFN0cmluZyBERUZBVUxJTVBMID0gImNvbS5zdW4ueG1sLmludGVybmFsLnN0cmVhbS5YTUxPdXRwdXRGYWN0b3J5SW1wbCI7Ci0KLSAgcHJvdGVjdGVkIFhNTE91dHB1dEZhY3RvcnkoKXt9Ci0KLSAgLyoqCi0gICAqIENyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhlIGZhY3RvcnkgaW4gZXhhY3RseSB0aGUgc2FtZSBtYW5uZXIgYXMgdGhlCi0gICAqIHtAbGluayAjbmV3RmFjdG9yeSgpfSBtZXRob2QuCi0gICAqIEB0aHJvd3MgRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvciBpZiBhbiBpbnN0YW5jZSBvZiB0aGlzIGZhY3RvcnkgY2Fubm90IGJlIGxvYWRlZAotICAgKi8KLSAgcHVibGljIHN0YXRpYyBYTUxPdXRwdXRGYWN0b3J5IG5ld0luc3RhbmNlKCkKLSAgICB0aHJvd3MgRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvcgotICB7Ci0gICAgcmV0dXJuIEZhY3RvcnlGaW5kZXIuZmluZChYTUxPdXRwdXRGYWN0b3J5LmNsYXNzLCBERUZBVUxJTVBMKTsKLSAgfQotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBuZXcgaW5zdGFuY2Ugb2YgdGhlIGZhY3RvcnkuCi0gICAqIDxwPgotICAgKiBUaGlzIHN0YXRpYyBtZXRob2QgY3JlYXRlcyBhIG5ldyBmYWN0b3J5IGluc3RhbmNlLiBUaGlzIG1ldGhvZCB1c2VzIHRoZQotICAgKiBmb2xsb3dpbmcgb3JkZXJlZCBsb29rdXAgcHJvY2VkdXJlIHRvIGRldGVybWluZSB0aGUgWE1MT3V0cHV0RmFjdG9yeQotICAgKiBpbXBsZW1lbnRhdGlvbiBjbGFzcyB0byBsb2FkOgotICAgKiA8L3A+Ci0gICAqIDx1bD4KLSAgICogPGxpPgotICAgKiAgIFVzZSB0aGUgamF2YXgueG1sLnN0cmVhbS5YTUxPdXRwdXRGYWN0b3J5IHN5c3RlbSBwcm9wZXJ0eS4KLSAgICogPC9saT4KLSAgICogPGxpPgotICAgKiAgIFVzZSB0aGUgcHJvcGVydGllcyBmaWxlICJsaWIvc3RheC5wcm9wZXJ0aWVzIiBpbiB0aGUgSlJFIGRpcmVjdG9yeS4KLSAgICogICAgIFRoaXMgY29uZmlndXJhdGlvbiBmaWxlIGlzIGluIHN0YW5kYXJkIGphdmEudXRpbC5Qcm9wZXJ0aWVzIGZvcm1hdAotICAgKiAgICAgYW5kIGNvbnRhaW5zIHRoZSBmdWxseSBxdWFsaWZpZWQgbmFtZSBvZiB0aGUgaW1wbGVtZW50YXRpb24gY2xhc3MKLSAgICogICAgIHdpdGggdGhlIGtleSBiZWluZyB0aGUgc3lzdGVtIHByb3BlcnR5IGRlZmluZWQgYWJvdmUuCi0gICAqIDwvbGk+Ci0gICAqIDxsaT4KLSAgICogICBVc2UgdGhlIHNlcnZpY2UtcHJvdmlkZXIgbG9hZGluZyBmYWNpbGl0aWVzLCBkZWZpbmVkIGJ5IHRoZQotICAgKiAgIHtAbGluayBqYXZhLnV0aWwuU2VydmljZUxvYWRlcn0gY2xhc3MsIHRvIGF0dGVtcHQgdG8gbG9jYXRlIGFuZCBsb2FkIGFuCi0gICAqICAgaW1wbGVtZW50YXRpb24gb2YgdGhlIHNlcnZpY2UgdXNpbmcgdGhlIHtAbGlua3BsYWluCi0gICAqICAgamF2YS51dGlsLlNlcnZpY2VMb2FkZXIjbG9hZChqYXZhLmxhbmcuQ2xhc3MpIGRlZmF1bHQgbG9hZGluZyBtZWNoYW5pc219OgotICAgKiAgIHRoZSBzZXJ2aWNlLXByb3ZpZGVyIGxvYWRpbmcgZmFjaWxpdHkgd2lsbCB1c2UgdGhlIHtAbGlua3BsYWluCi0gICAqICAgamF2YS5sYW5nLlRocmVhZCNnZXRDb250ZXh0Q2xhc3NMb2FkZXIoKSBjdXJyZW50IHRocmVhZCdzIGNvbnRleHQgY2xhc3MgbG9hZGVyfQotICAgKiAgIHRvIGF0dGVtcHQgdG8gbG9hZCB0aGUgc2VydmljZS4gSWYgdGhlIGNvbnRleHQgY2xhc3MKLSAgICogICBsb2FkZXIgaXMgbnVsbCwgdGhlIHtAbGlua3BsYWluCi0gICAqICAgQ2xhc3NMb2FkZXIjZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKSBzeXN0ZW0gY2xhc3MgbG9hZGVyfSB3aWxsIGJlIHVzZWQuCi0gICAqIDwvbGk+Ci0gICAqIDxsaT4KLSAgICogICBPdGhlcndpc2UsIHRoZSBzeXN0ZW0tZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBpcyByZXR1cm5lZC4KLSAgICogPC9saT4KLSAgICogPHA+Ci0gICAqIE9uY2UgYW4gYXBwbGljYXRpb24gaGFzIG9idGFpbmVkIGEgcmVmZXJlbmNlIHRvIGEgWE1MT3V0cHV0RmFjdG9yeSBpdAotICAgKiBjYW4gdXNlIHRoZSBmYWN0b3J5IHRvIGNvbmZpZ3VyZSBhbmQgb2J0YWluIHN0cmVhbSBpbnN0YW5jZXMuCi0gICAqIDwvcD4KLSAgICogPHA+Ci0gICAqIE5vdGUgdGhhdCB0aGlzIGlzIGEgbmV3IG1ldGhvZCB0aGF0IHJlcGxhY2VzIHRoZSBkZXByZWNhdGVkIG5ld0luc3RhbmNlKCkgbWV0aG9kLgotICAgKiAgIE5vIGNoYW5nZXMgaW4gYmVoYXZpb3IgYXJlIGRlZmluZWQgYnkgdGhpcyByZXBsYWNlbWVudCBtZXRob2QgcmVsYXRpdmUgdG8gdGhlCi0gICAqICAgZGVwcmVjYXRlZCBtZXRob2QuCi0gICAqIDwvcD4KLSAgICogQHRocm93cyBGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yIGluIGNhc2Ugb2Yge0BsaW5rcGxhaW4KLSAgICogICBqYXZhLnV0aWwuU2VydmljZUNvbmZpZ3VyYXRpb25FcnJvciBzZXJ2aWNlIGNvbmZpZ3VyYXRpb24gZXJyb3J9IG9yIGlmCi0gICAqICAgdGhlIGltcGxlbWVudGF0aW9uIGlzIG5vdCBhdmFpbGFibGUgb3IgY2Fubm90IGJlIGluc3RhbnRpYXRlZC4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgWE1MT3V0cHV0RmFjdG9yeSBuZXdGYWN0b3J5KCkKLSAgICB0aHJvd3MgRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvcgotICB7Ci0gICAgcmV0dXJuIEZhY3RvcnlGaW5kZXIuZmluZChYTUxPdXRwdXRGYWN0b3J5LmNsYXNzLCBERUZBVUxJTVBMKTsKLSAgfQotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBuZXcgaW5zdGFuY2Ugb2YgdGhlIGZhY3RvcnkuCi0gICAqCi0gICAqIEBwYXJhbSBmYWN0b3J5SWQgICAgICAgICAgICAgTmFtZSBvZiB0aGUgZmFjdG9yeSB0byBmaW5kLCBzYW1lIGFzCi0gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYSBwcm9wZXJ0eSBuYW1lCi0gICAqIEBwYXJhbSBjbGFzc0xvYWRlciAgICAgICAgICAgY2xhc3NMb2FkZXIgdG8gdXNlCi0gICAqIEByZXR1cm4gdGhlIGZhY3RvcnkgaW1wbGVtZW50YXRpb24KLSAgICogQHRocm93cyBGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yIGlmIGFuIGluc3RhbmNlIG9mIHRoaXMgZmFjdG9yeSBjYW5ub3QgYmUgbG9hZGVkCi0gICAqCi0gICAqIEBkZXByZWNhdGVkICBUaGlzIG1ldGhvZCBoYXMgYmVlbiBkZXByZWNhdGVkIGJlY2F1c2UgaXQgcmV0dXJucyBhbgotICAgKiAgICAgICAgICAgICAgaW5zdGFuY2Ugb2YgWE1MSW5wdXRGYWN0b3J5LCB3aGljaCBpcyBvZiB0aGUgd3JvbmcgY2xhc3MuCi0gICAqICAgICAgICAgICAgICBVc2UgdGhlIG5ldyBtZXRob2Qge0BsaW5rICNuZXdGYWN0b3J5KGphdmEubGFuZy5TdHJpbmcsCi0gICAqICAgICAgICAgICAgICBqYXZhLmxhbmcuQ2xhc3NMb2FkZXIpfSBpbnN0ZWFkLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBYTUxJbnB1dEZhY3RvcnkgbmV3SW5zdGFuY2UoU3RyaW5nIGZhY3RvcnlJZCwKLSAgICAgICAgICBDbGFzc0xvYWRlciBjbGFzc0xvYWRlcikKLSAgICAgICAgICB0aHJvd3MgRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvciB7Ci0gICAgICAvL2RvIG5vdCBmYWxsYmFjayBpZiBnaXZlbiBjbGFzc2xvYWRlciBjYW4ndCBmaW5kIHRoZSBjbGFzcywgdGhyb3cgZXhjZXB0aW9uCi0gICAgICByZXR1cm4gRmFjdG9yeUZpbmRlci5maW5kKFhNTElucHV0RmFjdG9yeS5jbGFzcywgZmFjdG9yeUlkLCBjbGFzc0xvYWRlciwgbnVsbCk7Ci0gIH0KLQotICAvKioKLSAgICogQ3JlYXRlIGEgbmV3IGluc3RhbmNlIG9mIHRoZSBmYWN0b3J5LgotICAgKiBJZiB0aGUgY2xhc3NMb2FkZXIgYXJndW1lbnQgaXMgbnVsbCwgdGhlbiB0aGUgQ29udGV4dENsYXNzTG9hZGVyIGlzIHVzZWQuCi0gICAqIDxwPgotICAgKiBUaGlzIG1ldGhvZCB1c2VzIHRoZSBmb2xsb3dpbmcgb3JkZXJlZCBsb29rdXAgcHJvY2VkdXJlIHRvIGRldGVybWluZQotICAgKiB0aGUgWE1MT3V0cHV0RmFjdG9yeSBpbXBsZW1lbnRhdGlvbiBjbGFzcyB0byBsb2FkOgotICAgKiA8L3A+Ci0gICAqIDx1bD4KLSAgICogPGxpPgotICAgKiAgIFVzZSB0aGUgdmFsdWUgb2YgdGhlIHN5c3RlbSBwcm9wZXJ0eSBpZGVudGlmaWVkIGJ5IHtAY29kZSBmYWN0b3J5SWR9LgotICAgKiA8L2xpPgotICAgKiA8bGk+Ci0gICAqICAgVXNlIHRoZSBwcm9wZXJ0aWVzIGZpbGUgImxpYi9zdGF4LnByb3BlcnRpZXMiIGluIHRoZSBKUkUgZGlyZWN0b3J5LgotICAgKiAgICAgVGhpcyBjb25maWd1cmF0aW9uIGZpbGUgaXMgaW4gc3RhbmRhcmQgamF2YS51dGlsLlByb3BlcnRpZXMgZm9ybWF0Ci0gICAqICAgICBhbmQgY29udGFpbnMgdGhlIGZ1bGx5IHF1YWxpZmllZCBuYW1lIG9mIHRoZSBpbXBsZW1lbnRhdGlvbiBjbGFzcwotICAgKiAgICAgd2l0aCB0aGUga2V5IGJlaW5nIHRoZSBnaXZlbiB7QGNvZGUgZmFjdG9yeUlkfS4KLSAgICogPC9saT4KLSAgICogPGxpPgotICAgKiAgIElmIHtAY29kZSBmYWN0b3J5SWR9IGlzICJqYXZheC54bWwuc3RyZWFtLlhNTE91dHB1dEZhY3RvcnkiLAotICAgKiAgIHVzZSB0aGUgc2VydmljZS1wcm92aWRlciBsb2FkaW5nIGZhY2lsaXRpZXMsIGRlZmluZWQgYnkgdGhlCi0gICAqICAge0BsaW5rIGphdmEudXRpbC5TZXJ2aWNlTG9hZGVyfSBjbGFzcywgdG8gYXR0ZW1wdCB0byB7QGxpbmtwbGFpbgotICAgKiAgIGphdmEudXRpbC5TZXJ2aWNlTG9hZGVyI2xvYWQoamF2YS5sYW5nLkNsYXNzLCBqYXZhLmxhbmcuQ2xhc3NMb2FkZXIpIGxvY2F0ZSBhbmQgbG9hZH0KLSAgICogICBhbiBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgc2VydmljZSB1c2luZyB0aGUgc3BlY2lmaWVkIHtAY29kZSBDbGFzc0xvYWRlcn0uCi0gICAqICAgSWYge0Bjb2RlIGNsYXNzTG9hZGVyfSBpcyBudWxsLCB0aGUge0BsaW5rcGxhaW4KLSAgICogICBqYXZhLnV0aWwuU2VydmljZUxvYWRlciNsb2FkKGphdmEubGFuZy5DbGFzcykgZGVmYXVsdCBsb2FkaW5nIG1lY2hhbmlzbX0gd2lsbCBhcHBseToKLSAgICogICBUaGF0IGlzLCB0aGUgc2VydmljZS1wcm92aWRlciBsb2FkaW5nIGZhY2lsaXR5IHdpbGwgdXNlIHRoZSB7QGxpbmtwbGFpbgotICAgKiAgIGphdmEubGFuZy5UaHJlYWQjZ2V0Q29udGV4dENsYXNzTG9hZGVyKCkgY3VycmVudCB0aHJlYWQncyBjb250ZXh0IGNsYXNzIGxvYWRlcn0KLSAgICogICB0byBhdHRlbXB0IHRvIGxvYWQgdGhlIHNlcnZpY2UuIElmIHRoZSBjb250ZXh0IGNsYXNzCi0gICAqICAgbG9hZGVyIGlzIG51bGwsIHRoZSB7QGxpbmtwbGFpbgotICAgKiAgIENsYXNzTG9hZGVyI2dldFN5c3RlbUNsYXNzTG9hZGVyKCkgc3lzdGVtIGNsYXNzIGxvYWRlcn0gd2lsbCBiZSB1c2VkLgotICAgKiA8L2xpPgotICAgKiA8bGk+Ci0gICAqICAgT3RoZXJ3aXNlLCB0aHJvd3MgYSB7QGxpbmsgRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvcn0uCi0gICAqIDwvbGk+Ci0gICAqIDwvdWw+Ci0gICAqCi0gICAqIEBhcGlOb3RlIFRoZSBwYXJhbWV0ZXIgZmFjdG9yeUlkIGRlZmluZWQgaGVyZSBpcyBpbmNvbnNpc3RlbnQgd2l0aCB0aGF0Ci0gICAqIG9mIG90aGVyIEpBWFAgZmFjdG9yaWVzIHdoZXJlIHRoZSBmaXJzdCBwYXJhbWV0ZXIgaXMgZnVsbHkgcXVhbGlmaWVkCi0gICAqIGZhY3RvcnkgY2xhc3MgbmFtZSB0aGF0IHByb3ZpZGVzIGltcGxlbWVudGF0aW9uIG9mIHRoZSBmYWN0b3J5LgotICAgKgotICAgKiA8cD4KLSAgICogICBOb3RlIHRoYXQgdGhpcyBpcyBhIG5ldyBtZXRob2QgdGhhdCByZXBsYWNlcyB0aGUgZGVwcmVjYXRlZAotICAgKiAgIHtAbGluayAjbmV3SW5zdGFuY2UoamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkNsYXNzTG9hZGVyKQotICAgKiAgIG5ld0luc3RhbmNlKFN0cmluZyBmYWN0b3J5SWQsIENsYXNzTG9hZGVyIGNsYXNzTG9hZGVyKX0gbWV0aG9kLgotICAgKiAgIFRoZSBvcmlnaW5hbCBtZXRob2Qgd2FzIGluY29ycmVjdGx5IGRlZmluZWQgdG8gcmV0dXJuIFhNTElucHV0RmFjdG9yeS4KLSAgICogPC9wPgotICAgKgotICAgKiBAcGFyYW0gZmFjdG9yeUlkICAgICAgICAgICAgIE5hbWUgb2YgdGhlIGZhY3RvcnkgdG8gZmluZCwgc2FtZSBhcwotICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGEgcHJvcGVydHkgbmFtZQotICAgKiBAcGFyYW0gY2xhc3NMb2FkZXIgICAgICAgICAgIGNsYXNzTG9hZGVyIHRvIHVzZQotICAgKiBAcmV0dXJuIHRoZSBmYWN0b3J5IGltcGxlbWVudGF0aW9uCi0gICAqIEB0aHJvd3MgRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvciBpbiBjYXNlIG9mIHtAbGlua3BsYWluCi0gICAqICAgamF2YS51dGlsLlNlcnZpY2VDb25maWd1cmF0aW9uRXJyb3Igc2VydmljZSBjb25maWd1cmF0aW9uIGVycm9yfSBvciBpZgotICAgKiAgIHRoZSBpbXBsZW1lbnRhdGlvbiBpcyBub3QgYXZhaWxhYmxlIG9yIGNhbm5vdCBiZSBpbnN0YW50aWF0ZWQuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIFhNTE91dHB1dEZhY3RvcnkgbmV3RmFjdG9yeShTdHJpbmcgZmFjdG9yeUlkLAotICAgICAgICAgIENsYXNzTG9hZGVyIGNsYXNzTG9hZGVyKQotICAgICAgICAgIHRocm93cyBGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yIHsKLSAgICAgIC8vZG8gbm90IGZhbGxiYWNrIGlmIGdpdmVuIGNsYXNzbG9hZGVyIGNhbid0IGZpbmQgdGhlIGNsYXNzLCB0aHJvdyBleGNlcHRpb24KLSAgICAgIHJldHVybiBGYWN0b3J5RmluZGVyLmZpbmQoWE1MT3V0cHV0RmFjdG9yeS5jbGFzcywgZmFjdG9yeUlkLCBjbGFzc0xvYWRlciwgbnVsbCk7Ci0gIH0KLQotICAvKioKLSAgICogQ3JlYXRlIGEgbmV3IFhNTFN0cmVhbVdyaXRlciB0aGF0IHdyaXRlcyB0byBhIHdyaXRlcgotICAgKiBAcGFyYW0gc3RyZWFtIHRoZSB3cml0ZXIgdG8gd3JpdGUgdG8KLSAgICogQHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBYTUxTdHJlYW1Xcml0ZXIgY3JlYXRlWE1MU3RyZWFtV3JpdGVyKGphdmEuaW8uV3JpdGVyIHN0cmVhbSkgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbjsKLQotICAvKioKLSAgICogQ3JlYXRlIGEgbmV3IFhNTFN0cmVhbVdyaXRlciB0aGF0IHdyaXRlcyB0byBhIHN0cmVhbQotICAgKiBAcGFyYW0gc3RyZWFtIHRoZSBzdHJlYW0gdG8gd3JpdGUgdG8KLSAgICogQHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBYTUxTdHJlYW1Xcml0ZXIgY3JlYXRlWE1MU3RyZWFtV3JpdGVyKGphdmEuaW8uT3V0cHV0U3RyZWFtIHN0cmVhbSkgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbjsKLQotICAvKioKLSAgICogQ3JlYXRlIGEgbmV3IFhNTFN0cmVhbVdyaXRlciB0aGF0IHdyaXRlcyB0byBhIHN0cmVhbQotICAgKiBAcGFyYW0gc3RyZWFtIHRoZSBzdHJlYW0gdG8gd3JpdGUgdG8KLSAgICogQHBhcmFtIGVuY29kaW5nIHRoZSBlbmNvZGluZyB0byB1c2UKLSAgICogQHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBYTUxTdHJlYW1Xcml0ZXIgY3JlYXRlWE1MU3RyZWFtV3JpdGVyKGphdmEuaW8uT3V0cHV0U3RyZWFtIHN0cmVhbSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGVuY29kaW5nKSB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uOwotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBuZXcgWE1MU3RyZWFtV3JpdGVyIHRoYXQgd3JpdGVzIHRvIGEgSkFYUCByZXN1bHQuICBUaGlzIG1ldGhvZCBpcyBvcHRpb25hbC4KLSAgICogQHBhcmFtIHJlc3VsdCB0aGUgcmVzdWx0IHRvIHdyaXRlIHRvCi0gICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gaWYgdGhpcyBtZXRob2QgaXMgbm90Ci0gICAqIHN1cHBvcnRlZCBieSB0aGlzIFhNTE91dHB1dEZhY3RvcnkKLSAgICogQHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBYTUxTdHJlYW1Xcml0ZXIgY3JlYXRlWE1MU3RyZWFtV3JpdGVyKFJlc3VsdCByZXN1bHQpIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb247Ci0KLQotICAvKioKLSAgICogQ3JlYXRlIGEgbmV3IFhNTEV2ZW50V3JpdGVyIHRoYXQgd3JpdGVzIHRvIGEgSkFYUCByZXN1bHQuICBUaGlzIG1ldGhvZCBpcyBvcHRpb25hbC4KLSAgICogQHBhcmFtIHJlc3VsdCB0aGUgcmVzdWx0IHRvIHdyaXRlIHRvCi0gICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gaWYgdGhpcyBtZXRob2QgaXMgbm90Ci0gICAqIHN1cHBvcnRlZCBieSB0aGlzIFhNTE91dHB1dEZhY3RvcnkKLSAgICogQHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBYTUxFdmVudFdyaXRlciBjcmVhdGVYTUxFdmVudFdyaXRlcihSZXN1bHQgcmVzdWx0KSB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uOwotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBuZXcgWE1MRXZlbnRXcml0ZXIgdGhhdCB3cml0ZXMgdG8gYSBzdHJlYW0KLSAgICogQHBhcmFtIHN0cmVhbSB0aGUgc3RyZWFtIHRvIHdyaXRlIHRvCi0gICAqIEB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgWE1MRXZlbnRXcml0ZXIgY3JlYXRlWE1MRXZlbnRXcml0ZXIoamF2YS5pby5PdXRwdXRTdHJlYW0gc3RyZWFtKSB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uOwotCi0KLQotICAvKioKLSAgICogQ3JlYXRlIGEgbmV3IFhNTEV2ZW50V3JpdGVyIHRoYXQgd3JpdGVzIHRvIGEgc3RyZWFtCi0gICAqIEBwYXJhbSBzdHJlYW0gdGhlIHN0cmVhbSB0byB3cml0ZSB0bwotICAgKiBAcGFyYW0gZW5jb2RpbmcgdGhlIGVuY29kaW5nIHRvIHVzZQotICAgKiBAdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IFhNTEV2ZW50V3JpdGVyIGNyZWF0ZVhNTEV2ZW50V3JpdGVyKGphdmEuaW8uT3V0cHV0U3RyZWFtIHN0cmVhbSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGVuY29kaW5nKSB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uOwotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBuZXcgWE1MRXZlbnRXcml0ZXIgdGhhdCB3cml0ZXMgdG8gYSB3cml0ZXIKLSAgICogQHBhcmFtIHN0cmVhbSB0aGUgc3RyZWFtIHRvIHdyaXRlIHRvCi0gICAqIEB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgWE1MRXZlbnRXcml0ZXIgY3JlYXRlWE1MRXZlbnRXcml0ZXIoamF2YS5pby5Xcml0ZXIgc3RyZWFtKSB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uOwotCi0gIC8qKgotICAgKiBBbGxvd3MgdGhlIHVzZXIgdG8gc2V0IHNwZWNpZmljIGZlYXR1cmVzL3Byb3BlcnRpZXMgb24gdGhlIHVuZGVybHlpbmcgaW1wbGVtZW50YXRpb24uCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBwcm9wZXJ0eQotICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlIG9mIHRoZSBwcm9wZXJ0eQotICAgKiBAdGhyb3dzIGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgdGhlIHByb3BlcnR5IGlzIG5vdCBzdXBwb3J0ZWQKLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHNldFByb3BlcnR5KGphdmEubGFuZy5TdHJpbmcgbmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9iamVjdCB2YWx1ZSkKLSAgICB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uOwotCi0gIC8qKgotICAgKiBHZXQgYSBmZWF0dXJlL3Byb3BlcnR5IG9uIHRoZSB1bmRlcmx5aW5nIGltcGxlbWVudGF0aW9uCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBwcm9wZXJ0eQotICAgKiBAcmV0dXJuIFRoZSB2YWx1ZSBvZiB0aGUgcHJvcGVydHkKLSAgICogQHRocm93cyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSBwcm9wZXJ0eSBpcyBub3Qgc3VwcG9ydGVkCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgT2JqZWN0IGdldFByb3BlcnR5KGphdmEubGFuZy5TdHJpbmcgbmFtZSkKLSAgICB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uOwotCi0gIC8qKgotICAgKiBRdWVyeSB0aGUgc2V0IG9mIHByb3BlcnRpZXMgdGhhdCB0aGlzIGZhY3Rvcnkgc3VwcG9ydHMuCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBwcm9wZXJ0eSAobWF5IG5vdCBiZSBudWxsKQotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHByb3BlcnR5IGlzIHN1cHBvcnRlZCBhbmQgZmFsc2Ugb3RoZXJ3aXNlCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBpc1Byb3BlcnR5U3VwcG9ydGVkKFN0cmluZyBuYW1lKTsKLX0KZGlmZiAtLWdpdCBhL3NyYy9qYXZheC94bWwvc3RyZWFtL1hNTFJlcG9ydGVyLmphdmEgYi9zcmMvamF2YXgveG1sL3N0cmVhbS9YTUxSZXBvcnRlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmNzg2NDhlLi4wMDAwMDAwCi0tLSBhL3NyYy9qYXZheC94bWwvc3RyZWFtL1hNTFJlcG9ydGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw2NSArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogQ29weXJpZ2h0IChjKSAyMDA5IGJ5IE9yYWNsZSBDb3Jwb3JhdGlvbi4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KLSAqLwotCi1wYWNrYWdlIGphdmF4LnhtbC5zdHJlYW07Ci0KLS8qKgotICogVGhpcyBpbnRlcmZhY2UgaXMgdXNlZCB0byByZXBvcnQgbm9uLWZhdGFsIGVycm9ycy4KLSAqIE9ubHkgd2FybmluZ3Mgc2hvdWxkIGJlIGVjaG9lZCB0aHJvdWdoIHRoaXMgaW50ZXJmYWNlLgotICogQHZlcnNpb24gMS4wCi0gKiBAYXV0aG9yIENvcHlyaWdodCAoYykgMjAwOSBieSBPcmFjbGUgQ29ycG9yYXRpb24uIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCi0gKiBAc2luY2UgMS42Ci0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgWE1MUmVwb3J0ZXIgewotCi0gICAgLyoqCi0KLSAgICAgKiBSZXBvcnQgdGhlIGRlc2lyZWQgbWVzc2FnZSBpbiBhbiBhcHBsaWNhdGlvbiBzcGVjaWZpYyBmb3JtYXQuCi0KLSAgICAgKiBPbmx5IHdhcm5pbmdzIGFuZCBub24tZmF0YWwgZXJyb3JzIHNob3VsZCBiZSByZXBvcnRlZCB0aHJvdWdoCi0KLSAgICAgKiB0aGlzIGludGVyZmFjZS4KLQotICAgICAqIEZhdGFsIGVycm9ycyBzaG91bGQgYmUgdGhyb3duIGFzIFhNTFN0cmVhbUV4Y2VwdGlvbi4KLQotICAgICAqCi0KLSAgICAgKiBAcGFyYW0gbWVzc2FnZSB0aGUgZXJyb3IgbWVzc2FnZQotCi0gICAgICogQHBhcmFtIGVycm9yVHlwZSBhbiBpbXBsZW1lbnRhdGlvbiBkZWZpbmVkIGVycm9yIHR5cGUKLQotICAgICAqIEBwYXJhbSByZWxhdGVkSW5mb3JtYXRpb24gaW5mb3JtYXRpb24gcmVsYXRlZCB0byB0aGUgZXJyb3IsIGlmIGF2YWlsYWJsZQotCi0gICAgICogQHBhcmFtIGxvY2F0aW9uIHRoZSBsb2NhdGlvbiBvZiB0aGUgZXJyb3IsIGlmIGF2YWlsYWJsZQotCi0gICAgICogQHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24KLQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHJlcG9ydChTdHJpbmcgbWVzc2FnZSwgU3RyaW5nIGVycm9yVHlwZSwgT2JqZWN0IHJlbGF0ZWRJbmZvcm1hdGlvbiwgTG9jYXRpb24gbG9jYXRpb24pCi0gICAgICAgICAgICB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uOwotfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmF4L3htbC9zdHJlYW0vWE1MUmVzb2x2ZXIuamF2YSBiL3NyYy9qYXZheC94bWwvc3RyZWFtL1hNTFJlc29sdmVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGRiYjE3N2IuLjAwMDAwMDAKLS0tIGEvc3JjL2phdmF4L3htbC9zdHJlYW0vWE1MUmVzb2x2ZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDYwICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDkgYnkgT3JhY2xlIENvcnBvcmF0aW9uLiBBbGwgUmlnaHRzIFJlc2VydmVkLgotICovCi0KLXBhY2thZ2UgamF2YXgueG1sLnN0cmVhbTsKLQotLyoqCi0gKiBUaGlzIGludGVyZmFjZSBpcyB1c2VkIHRvIHJlc29sdmUgcmVzb3VyY2VzIGR1cmluZyBhbiBYTUwgcGFyc2UuICBJZiBhbiBhcHBsaWNhdGlvbiB3aXNoZXMgdG8KLSAqIHBlcmZvcm0gY3VzdG9tIGVudGl0eSByZXNvbHV0aW9uIGl0IG11c3QgcmVnaXN0ZXIgYW4gaW5zdGFuY2Ugb2YgdGhpcyBpbnRlcmZhY2Ugd2l0aAotICogdGhlIFhNTElucHV0RmFjdG9yeSB1c2luZyB0aGUgc2V0WE1MUmVzb2x2ZXIgbWV0aG9kLgotICoKLSAqIEB2ZXJzaW9uIDEuMAotICogQGF1dGhvciBDb3B5cmlnaHQgKGMpIDIwMDkgYnkgT3JhY2xlIENvcnBvcmF0aW9uLiBBbGwgUmlnaHRzIFJlc2VydmVkLgotICogQHNpbmNlIDEuNgotICovCi1wdWJsaWMgaW50ZXJmYWNlIFhNTFJlc29sdmVyIHsKLQotICAvKioKLSAgICogUmV0cmlldmVzIGEgcmVzb3VyY2UuICBUaGlzIHJlc291cmNlIGNhbiBiZSBvZiB0aGUgZm9sbG93aW5nIHRocmVlIHJldHVybiB0eXBlczoKLSAgICogKDEpIGphdmEuaW8uSW5wdXRTdHJlYW0gKDIpIGphdmF4LnhtbC5zdHJlYW0uWE1MU3RyZWFtUmVhZGVyICgzKSBqYXZhLnhtbC5zdHJlYW0uWE1MRXZlbnRSZWFkZXIuCi0gICAqIElmIHRoaXMgbWV0aG9kIHJldHVybnMgbnVsbCB0aGUgcHJvY2Vzc29yIHdpbGwgYXR0ZW1wdCB0byByZXNvbHZlIHRoZSBlbnRpdHkgdXNpbmcgaXRzCi0gICAqIGRlZmF1bHQgbWVjaGFuaXNtLgotICAgKgotICAgKiBAcGFyYW0gcHVibGljSUQgVGhlIHB1YmxpYyBpZGVudGlmaWVyIG9mIHRoZSBleHRlcm5hbCBlbnRpdHkgYmVpbmcgcmVmZXJlbmNlZCwgb3IgbnVsbCBpZiBub25lIHdhcyBzdXBwbGllZC4KLSAgICogQHBhcmFtIHN5c3RlbUlEIFRoZSBzeXN0ZW0gaWRlbnRpZmllciBvZiB0aGUgZXh0ZXJuYWwgZW50aXR5IGJlaW5nIHJlZmVyZW5jZWQuCi0gICAqIEBwYXJhbSBiYXNlVVJJICBBYnNvbHV0ZSBiYXNlIFVSSSBhc3NvY2lhdGVkIHdpdGggc3lzdGVtSWQuCi0gICAqIEBwYXJhbSBuYW1lc3BhY2UgVGhlIG5hbWVzcGFjZSBvZiB0aGUgZW50aXR5IHRvIHJlc29sdmUuCi0gICAqIEByZXR1cm4gVGhlIHJlc291cmNlIHJlcXVlc3RlZCBvciBudWxsLgotICAgKiBAdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbiBpZiB0aGVyZSB3YXMgYSBmYWlsdXJlIGF0dGVtcHRpbmcgdG8gcmVzb2x2ZSB0aGUgcmVzb3VyY2UuCi0gICAqLwotICBwdWJsaWMgT2JqZWN0IHJlc29sdmVFbnRpdHkoU3RyaW5nIHB1YmxpY0lELAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHN5c3RlbUlELAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGJhc2VVUkksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbmFtZXNwYWNlKQotICAgIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb247Ci19CmRpZmYgLS1naXQgYS9zcmMvamF2YXgveG1sL3N0cmVhbS9YTUxTdHJlYW1Db25zdGFudHMuamF2YSBiL3NyYy9qYXZheC94bWwvc3RyZWFtL1hNTFN0cmVhbUNvbnN0YW50cy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2Y2ViMWM2Li4wMDAwMDAwCi0tLSBhL3NyYy9qYXZheC94bWwvc3RyZWFtL1hNTFN0cmVhbUNvbnN0YW50cy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTI3ICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLXBhY2thZ2UgamF2YXgueG1sLnN0cmVhbTsKLQotLyoqCi0gKiBUaGlzIGludGVyZmFjZSBkZWNsYXJlcyB0aGUgY29uc3RhbnRzIHVzZWQgaW4gdGhpcyBBUEkuCi0gKiBOdW1iZXJzIGluIHRoZSByYW5nZSAwIHRvIDI1NiBhcmUgcmVzZXJ2ZWQgZm9yIHRoZSBzcGVjaWZpY2F0aW9uLAotICogdXNlciBkZWZpbmVkIGV2ZW50cyBtdXN0IHVzZSBldmVudCBjb2RlcyBvdXRzaWRlIHRoYXQgcmFuZ2UuCi0gKgotICogQHNpbmNlIDEuNgotICovCi0KLXB1YmxpYyBpbnRlcmZhY2UgWE1MU3RyZWFtQ29uc3RhbnRzIHsKLSAgLyoqCi0gICAqIEluZGljYXRlcyBhbiBldmVudCBpcyBhIHN0YXJ0IGVsZW1lbnQKLSAgICogQHNlZSBqYXZheC54bWwuc3RyZWFtLmV2ZW50cy5TdGFydEVsZW1lbnQKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNUQVJUX0VMRU1FTlQ9MTsKLSAgLyoqCi0gICAqIEluZGljYXRlcyBhbiBldmVudCBpcyBhbiBlbmQgZWxlbWVudAotICAgKiBAc2VlIGphdmF4LnhtbC5zdHJlYW0uZXZlbnRzLkVuZEVsZW1lbnQKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVORF9FTEVNRU5UPTI7Ci0gIC8qKgotICAgKiBJbmRpY2F0ZXMgYW4gZXZlbnQgaXMgYSBwcm9jZXNzaW5nIGluc3RydWN0aW9uCi0gICAqIEBzZWUgamF2YXgueG1sLnN0cmVhbS5ldmVudHMuUHJvY2Vzc2luZ0luc3RydWN0aW9uCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQUk9DRVNTSU5HX0lOU1RSVUNUSU9OPTM7Ci0KLSAgLyoqCi0gICAqIEluZGljYXRlcyBhbiBldmVudCBpcyBjaGFyYWN0ZXJzCi0gICAqIEBzZWUgamF2YXgueG1sLnN0cmVhbS5ldmVudHMuQ2hhcmFjdGVycwotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ0hBUkFDVEVSUz00OwotCi0gIC8qKgotICAgKiBJbmRpY2F0ZXMgYW4gZXZlbnQgaXMgYSBjb21tZW50Ci0gICAqIEBzZWUgamF2YXgueG1sLnN0cmVhbS5ldmVudHMuQ29tbWVudAotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ09NTUVOVD01OwotCi0gIC8qKgotICAgKiBUaGUgY2hhcmFjdGVycyBhcmUgd2hpdGUgc3BhY2UKLSAgICogKHNlZSBbWE1MXSwgMi4xMCAiV2hpdGUgU3BhY2UgSGFuZGxpbmciKS4KLSAgICogRXZlbnRzIGFyZSBvbmx5IHJlcG9ydGVkIGFzIFNQQUNFIGlmIHRoZXkgYXJlIGlnbm9yYWJsZSB3aGl0ZQotICAgKiBzcGFjZS4gIE90aGVyd2lzZSB0aGV5IGFyZSByZXBvcnRlZCBhcyBDSEFSQUNURVJTLgotICAgKiBAc2VlIGphdmF4LnhtbC5zdHJlYW0uZXZlbnRzLkNoYXJhY3RlcnMKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNQQUNFPTY7Ci0KLSAgLyoqCi0gICAqIEluZGljYXRlcyBhbiBldmVudCBpcyBhIHN0YXJ0IGRvY3VtZW50Ci0gICAqIEBzZWUgamF2YXgueG1sLnN0cmVhbS5ldmVudHMuU3RhcnREb2N1bWVudAotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1RBUlRfRE9DVU1FTlQ9NzsKLQotICAvKioKLSAgICogSW5kaWNhdGVzIGFuIGV2ZW50IGlzIGFuIGVuZCBkb2N1bWVudAotICAgKiBAc2VlIGphdmF4LnhtbC5zdHJlYW0uZXZlbnRzLkVuZERvY3VtZW50Ci0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTkRfRE9DVU1FTlQ9ODsKLQotICAvKioKLSAgICogSW5kaWNhdGVzIGFuIGV2ZW50IGlzIGFuIGVudGl0eSByZWZlcmVuY2UKLSAgICogQHNlZSBqYXZheC54bWwuc3RyZWFtLmV2ZW50cy5FbnRpdHlSZWZlcmVuY2UKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVOVElUWV9SRUZFUkVOQ0U9OTsKLQotICAvKioKLSAgICogSW5kaWNhdGVzIGFuIGV2ZW50IGlzIGFuIGF0dHJpYnV0ZQotICAgKiBAc2VlIGphdmF4LnhtbC5zdHJlYW0uZXZlbnRzLkF0dHJpYnV0ZQotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQVRUUklCVVRFPTEwOwotCi0gIC8qKgotICAgKiBJbmRpY2F0ZXMgYW4gZXZlbnQgaXMgYSBEVEQKLSAgICogQHNlZSBqYXZheC54bWwuc3RyZWFtLmV2ZW50cy5EVEQKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERURD0xMTsKLQotICAvKioKLSAgICogSW5kaWNhdGVzIGFuIGV2ZW50IGlzIGEgQ0RBVEEgc2VjdGlvbgotICAgKiBAc2VlIGphdmF4LnhtbC5zdHJlYW0uZXZlbnRzLkNoYXJhY3RlcnMKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENEQVRBPTEyOwotCi0gIC8qKgotICAgKiBJbmRpY2F0ZXMgdGhlIGV2ZW50IGlzIGEgbmFtZXNwYWNlIGRlY2xhcmF0aW9uCi0gICAqCi0gICAqIEBzZWUgamF2YXgueG1sLnN0cmVhbS5ldmVudHMuTmFtZXNwYWNlCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBOQU1FU1BBQ0U9MTM7Ci0KLSAgLyoqCi0gICAqIEluZGljYXRlcyBhIE5vdGF0aW9uCi0gICAqIEBzZWUgamF2YXgueG1sLnN0cmVhbS5ldmVudHMuTm90YXRpb25EZWNsYXJhdGlvbgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTk9UQVRJT05fREVDTEFSQVRJT049MTQ7Ci0KLSAgLyoqCi0gICAqIEluZGljYXRlcyBhIEVudGl0eSBEZWNsYXJhdGlvbgotICAgKiBAc2VlIGphdmF4LnhtbC5zdHJlYW0uZXZlbnRzLk5vdGF0aW9uRGVjbGFyYXRpb24KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVOVElUWV9ERUNMQVJBVElPTj0xNTsKLX0KZGlmZiAtLWdpdCBhL3NyYy9qYXZheC94bWwvc3RyZWFtL1hNTFN0cmVhbUV4Y2VwdGlvbi5qYXZhIGIvc3JjL2phdmF4L3htbC9zdHJlYW0vWE1MU3RyZWFtRXhjZXB0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDQ4ZTUxMGMuLjAwMDAwMDAKLS0tIGEvc3JjL2phdmF4L3htbC9zdHJlYW0vWE1MU3RyZWFtRXhjZXB0aW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMzAgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwOSBieSBPcmFjbGUgQ29ycG9yYXRpb24uIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCi0gKi8KLQotcGFja2FnZSBqYXZheC54bWwuc3RyZWFtOwotCi0vKioKLSAqIFRoZSBiYXNlIGV4Y2VwdGlvbiBmb3IgdW5leHBlY3RlZCBwcm9jZXNzaW5nIGVycm9ycy4gIFRoaXMgRXhjZXB0aW9uCi0gKiBjbGFzcyBpcyB1c2VkIHRvIHJlcG9ydCB3ZWxsLWZvcm1lZG5lc3MgZXJyb3JzIGFzIHdlbGwgYXMgdW5leHBlY3RlZAotICogcHJvY2Vzc2luZyBjb25kaXRpb25zLgotICogQHZlcnNpb24gMS4wCi0gKiBAYXV0aG9yIENvcHlyaWdodCAoYykgMjAwOSBieSBPcmFjbGUgQ29ycG9yYXRpb24uIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCi0gKiBAc2luY2UgMS42Ci0gKi8KLQotcHVibGljIGNsYXNzIFhNTFN0cmVhbUV4Y2VwdGlvbiBleHRlbmRzIEV4Y2VwdGlvbiB7Ci0KLSAgcHJvdGVjdGVkIFRocm93YWJsZSBuZXN0ZWQ7Ci0gIHByb3RlY3RlZCBMb2NhdGlvbiBsb2NhdGlvbjsKLQotICAvKioKLSAgICogRGVmYXVsdCBjb25zdHJ1Y3RvcgotICAgKi8KLSAgcHVibGljIFhNTFN0cmVhbUV4Y2VwdGlvbigpewotICAgIHN1cGVyKCk7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IGFuIGV4Y2VwdGlvbiB3aXRoIHRoZSBhc3NvY2F0ZWQgbWVzc2FnZS4KLSAgICoKLSAgICogQHBhcmFtIG1zZyB0aGUgbWVzc2FnZSB0byByZXBvcnQKLSAgICovCi0gIHB1YmxpYyBYTUxTdHJlYW1FeGNlcHRpb24oU3RyaW5nIG1zZykgewotICAgIHN1cGVyKG1zZyk7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IGFuIGV4Y2VwdGlvbiB3aXRoIHRoZSBhc3NvY2F0ZWQgZXhjZXB0aW9uCi0gICAqCi0gICAqIEBwYXJhbSB0aCBhIG5lc3RlZCBleGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYTUxTdHJlYW1FeGNlcHRpb24oVGhyb3dhYmxlIHRoKSB7Ci0gICAgICBzdXBlcih0aCk7Ci0gICAgbmVzdGVkID0gdGg7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IGFuIGV4Y2VwdGlvbiB3aXRoIHRoZSBhc3NvY2F0ZWQgbWVzc2FnZSBhbmQgZXhjZXB0aW9uCi0gICAqCi0gICAqIEBwYXJhbSB0aCBhIG5lc3RlZCBleGNlcHRpb24KLSAgICogQHBhcmFtIG1zZyB0aGUgbWVzc2FnZSB0byByZXBvcnQKLSAgICovCi0gIHB1YmxpYyBYTUxTdHJlYW1FeGNlcHRpb24oU3RyaW5nIG1zZywgVGhyb3dhYmxlIHRoKSB7Ci0gICAgc3VwZXIobXNnLCB0aCk7Ci0gICAgbmVzdGVkID0gdGg7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IGFuIGV4Y2VwdGlvbiB3aXRoIHRoZSBhc3NvY2F0ZWQgbWVzc2FnZSwgZXhjZXB0aW9uIGFuZCBsb2NhdGlvbi4KLSAgICoKLSAgICogQHBhcmFtIHRoIGEgbmVzdGVkIGV4Y2VwdGlvbgotICAgKiBAcGFyYW0gbXNnIHRoZSBtZXNzYWdlIHRvIHJlcG9ydAotICAgKiBAcGFyYW0gbG9jYXRpb24gdGhlIGxvY2F0aW9uIG9mIHRoZSBlcnJvcgotICAgKi8KLSAgcHVibGljIFhNTFN0cmVhbUV4Y2VwdGlvbihTdHJpbmcgbXNnLCBMb2NhdGlvbiBsb2NhdGlvbiwgVGhyb3dhYmxlIHRoKSB7Ci0gICAgc3VwZXIoIlBhcnNlRXJyb3IgYXQgW3Jvdyxjb2xdOlsiK2xvY2F0aW9uLmdldExpbmVOdW1iZXIoKSsiLCIrCi0gICAgICAgICAgbG9jYXRpb24uZ2V0Q29sdW1uTnVtYmVyKCkrIl1cbiIrCi0gICAgICAgICAgIk1lc3NhZ2U6ICIrbXNnKTsKLSAgICBuZXN0ZWQgPSB0aDsKLSAgICB0aGlzLmxvY2F0aW9uID0gbG9jYXRpb247Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IGFuIGV4Y2VwdGlvbiB3aXRoIHRoZSBhc3NvY2F0ZWQgbWVzc2FnZSwgZXhjZXB0aW9uIGFuZCBsb2NhdGlvbi4KLSAgICoKLSAgICogQHBhcmFtIG1zZyB0aGUgbWVzc2FnZSB0byByZXBvcnQKLSAgICogQHBhcmFtIGxvY2F0aW9uIHRoZSBsb2NhdGlvbiBvZiB0aGUgZXJyb3IKLSAgICovCi0gIHB1YmxpYyBYTUxTdHJlYW1FeGNlcHRpb24oU3RyaW5nIG1zZywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBMb2NhdGlvbiBsb2NhdGlvbikgewotICAgIHN1cGVyKCJQYXJzZUVycm9yIGF0IFtyb3csY29sXTpbIitsb2NhdGlvbi5nZXRMaW5lTnVtYmVyKCkrIiwiKwotICAgICAgICAgIGxvY2F0aW9uLmdldENvbHVtbk51bWJlcigpKyJdXG4iKwotICAgICAgICAgICJNZXNzYWdlOiAiK21zZyk7Ci0gICAgdGhpcy5sb2NhdGlvbiA9IGxvY2F0aW9uOwotICB9Ci0KLQotICAvKioKLSAgICogR2V0cyB0aGUgbmVzdGVkIGV4Y2VwdGlvbi4KLSAgICoKLSAgICogQHJldHVybiBOZXN0ZWQgZXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgVGhyb3dhYmxlIGdldE5lc3RlZEV4Y2VwdGlvbigpIHsKLSAgICByZXR1cm4gbmVzdGVkOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldHMgdGhlIGxvY2F0aW9uIG9mIHRoZSBleGNlcHRpb24KLSAgICoKLSAgICogQHJldHVybiB0aGUgbG9jYXRpb24gb2YgdGhlIGV4Y2VwdGlvbiwgbWF5IGJlIG51bGwgaWYgbm9uZSBpcyBhdmFpbGFibGUKLSAgICovCi0gIHB1YmxpYyBMb2NhdGlvbiBnZXRMb2NhdGlvbigpIHsKLSAgICByZXR1cm4gbG9jYXRpb247Ci0gIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmF4L3htbC9zdHJlYW0vWE1MU3RyZWFtUmVhZGVyLmphdmEgYi9zcmMvamF2YXgveG1sL3N0cmVhbS9YTUxTdHJlYW1SZWFkZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZmQxNTgxOS4uMDAwMDAwMAotLS0gYS9zcmMvamF2YXgveG1sL3N0cmVhbS9YTUxTdHJlYW1SZWFkZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDcwNCArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogQ29weXJpZ2h0IChjKSAyMDA5IGJ5IE9yYWNsZSBDb3Jwb3JhdGlvbi4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KLSAqLwotCi1wYWNrYWdlIGphdmF4LnhtbC5zdHJlYW07Ci0KLWltcG9ydCBqYXZhLmlvLlJlYWRlcjsKLWltcG9ydCBqYXZheC54bWwubmFtZXNwYWNlLk5hbWVzcGFjZUNvbnRleHQ7Ci1pbXBvcnQgamF2YXgueG1sLm5hbWVzcGFjZS5RTmFtZTsKLQotLyoqCi0gKiAgVGhlIFhNTFN0cmVhbVJlYWRlciBpbnRlcmZhY2UgYWxsb3dzIGZvcndhcmQsIHJlYWQtb25seSBhY2Nlc3MgdG8gWE1MLgotICogIEl0IGlzIGRlc2lnbmVkIHRvIGJlIHRoZSBsb3dlc3QgbGV2ZWwgYW5kIG1vc3QgZWZmaWNpZW50IHdheSB0bwotICogIHJlYWQgWE1MIGRhdGEuCi0gKgotICogPHA+IFRoZSBYTUxTdHJlYW1SZWFkZXIgaXMgZGVzaWduZWQgdG8gaXRlcmF0ZSBvdmVyIFhNTCB1c2luZwotICogbmV4dCgpIGFuZCBoYXNOZXh0KCkuICBUaGUgZGF0YSBjYW4gYmUgYWNjZXNzZWQgdXNpbmcgbWV0aG9kcyBzdWNoIGFzIGdldEV2ZW50VHlwZSgpLAotICogZ2V0TmFtZXNwYWNlVVJJKCksIGdldExvY2FsTmFtZSgpIGFuZCBnZXRUZXh0KCk7Ci0gKgotICogPHA+IFRoZSA8YSBocmVmPSIjbmV4dCgpIj5uZXh0KCk8L2E+IG1ldGhvZCBjYXVzZXMgdGhlIHJlYWRlciB0byByZWFkIHRoZSBuZXh0IHBhcnNlIGV2ZW50LgotICogVGhlIG5leHQoKSBtZXRob2QgcmV0dXJucyBhbiBpbnRlZ2VyIHdoaWNoIGlkZW50aWZpZXMgdGhlIHR5cGUgb2YgZXZlbnQganVzdCByZWFkLgotICogPHA+IFRoZSBldmVudCB0eXBlIGNhbiBiZSBkZXRlcm1pbmVkIHVzaW5nIDxhIGhyZWY9IiNnZXRFdmVudFR5cGUoKSI+Z2V0RXZlbnRUeXBlKCk8L2E+LgotICogPHA+IFBhcnNpbmcgZXZlbnRzIGFyZSBkZWZpbmVkIGFzIHRoZSBYTUwgRGVjbGFyYXRpb24sIGEgRFRELAotICogc3RhcnQgdGFnLCBjaGFyYWN0ZXIgZGF0YSwgd2hpdGUgc3BhY2UsIGVuZCB0YWcsIGNvbW1lbnQsCi0gKiBvciBwcm9jZXNzaW5nIGluc3RydWN0aW9uLiAgQW4gYXR0cmlidXRlIG9yIG5hbWVzcGFjZSBldmVudCBtYXkgYmUgZW5jb3VudGVyZWQKLSAqIGF0IHRoZSByb290IGxldmVsIG9mIGEgZG9jdW1lbnQgYXMgdGhlIHJlc3VsdCBvZiBhIHF1ZXJ5IG9wZXJhdGlvbi4KLSAqCi0gKiA8cD5Gb3IgWE1MIDEuMCBjb21wbGlhbmNlIGFuIFhNTCBwcm9jZXNzb3IgbXVzdCBwYXNzIHRoZQotICogaWRlbnRpZmllcnMgb2YgZGVjbGFyZWQgdW5wYXJzZWQgZW50aXRpZXMsIG5vdGF0aW9uIGRlY2xhcmF0aW9ucyBhbmQgdGhlaXIKLSAqIGFzc29jaWF0ZWQgaWRlbnRpZmllcnMgdG8gdGhlIGFwcGxpY2F0aW9uLiAgVGhpcyBpbmZvcm1hdGlvbiBpcwotICogcHJvdmlkZWQgdGhyb3VnaCB0aGUgcHJvcGVydHkgQVBJIG9uIHRoaXMgaW50ZXJmYWNlLgotICogVGhlIGZvbGxvd2luZyB0d28gcHJvcGVydGllcyBhbGxvdyBhY2Nlc3MgdG8gdGhpcyBpbmZvcm1hdGlvbjoKLSAqIGphdmF4LnhtbC5zdHJlYW0ubm90YXRpb25zIGFuZCBqYXZheC54bWwuc3RyZWFtLmVudGl0aWVzLgotICogV2hlbiB0aGUgY3VycmVudCBldmVudCBpcyBhIERURCB0aGUgZm9sbG93aW5nIGNhbGwgd2lsbCByZXR1cm4gYQotICogbGlzdCBvZiBOb3RhdGlvbnMKLSAqICA8Y29kZT5MaXN0IGwgPSAoTGlzdCkgZ2V0UHJvcGVydHkoImphdmF4LnhtbC5zdHJlYW0ubm90YXRpb25zIik7PC9jb2RlPgotICogVGhlIGZvbGxvd2luZyBjYWxsIHdpbGwgcmV0dXJuIGEgbGlzdCBvZiBlbnRpdHkgZGVjbGFyYXRpb25zOgotICogPGNvZGU+TGlzdCBsID0gKExpc3QpIGdldFByb3BlcnR5KCJqYXZheC54bWwuc3RyZWFtLmVudGl0aWVzIik7PC9jb2RlPgotICogVGhlc2UgcHJvcGVydGllcyBjYW4gb25seSBiZSBhY2Nlc3NlZCBkdXJpbmcgYSBEVEQgZXZlbnQgYW5kCi0gKiBhcmUgZGVmaW5lZCB0byByZXR1cm4gbnVsbCBpZiB0aGUgaW5mb3JtYXRpb24gaXMgbm90IGF2YWlsYWJsZS4KLSAqCi0gKiA8cD5UaGUgZm9sbG93aW5nIHRhYmxlIGRlc2NyaWJlcyB3aGljaCBtZXRob2RzIGFyZSB2YWxpZCBpbiB3aGF0IHN0YXRlLgotICogSWYgYSBtZXRob2QgaXMgY2FsbGVkIGluIGFuIGludmFsaWQgc3RhdGUgdGhlIG1ldGhvZCB3aWxsIHRocm93IGEKLSAqIGphdmEubGFuZy5JbGxlZ2FsU3RhdGVFeGNlcHRpb24uCi0gKgotICogPHRhYmxlIGJvcmRlcj0iMiIgcnVsZXM9ImFsbCIgY2VsbHBhZGRpbmc9IjQiPgotICogICA8dGhlYWQ+Ci0gKiAgICAgPHRyPgotICogICAgICAgPHRoIGFsaWduPSJjZW50ZXIiIGNvbHNwYW49IjIiPgotICogICAgICAgICBWYWxpZCBtZXRob2RzIGZvciBlYWNoIHN0YXRlCi0gKiAgICAgICA8L3RoPgotICogICAgIDwvdHI+Ci0gKiAgIDwvdGhlYWQ+Ci0gKiAgIDx0Ym9keT4KLSAqICAgICA8dHI+Ci0gKiAgICAgICA8dGg+RXZlbnQgVHlwZTwvdGg+Ci0gKiAgICAgICA8dGg+VmFsaWQgTWV0aG9kczwvdGg+Ci0gKiAgICAgPC90cj4KLSAqICAgICA8dHI+Ci0gKiAgICAgICA8dGQ+IEFsbCBTdGF0ZXMgIDwvdGQ+Ci0gKiAgICAgICA8dGQ+IGdldFByb3BlcnR5KCksIGhhc05leHQoKSwgcmVxdWlyZSgpLCBjbG9zZSgpLAotICogICAgICAgICAgICBnZXROYW1lc3BhY2VVUkkoKSwgaXNTdGFydEVsZW1lbnQoKSwKLSAqICAgICAgICAgICAgaXNFbmRFbGVtZW50KCksIGlzQ2hhcmFjdGVycygpLCBpc1doaXRlU3BhY2UoKSwKLSAqICAgICAgICAgICAgZ2V0TmFtZXNwYWNlQ29udGV4dCgpLCBnZXRFdmVudFR5cGUoKSxnZXRMb2NhdGlvbigpLAotICogICAgICAgICAgICBoYXNUZXh0KCksIGhhc05hbWUoKQotICogICAgICAgPC90ZD4KLSAqICAgICA8L3RyPgotICogICAgIDx0cj4KLSAqICAgICAgIDx0ZD4gU1RBUlRfRUxFTUVOVCAgPC90ZD4KLSAqICAgICAgIDx0ZD4gbmV4dCgpLCBnZXROYW1lKCksIGdldExvY2FsTmFtZSgpLCBoYXNOYW1lKCksIGdldFByZWZpeCgpLAotICogICAgICAgICAgICBnZXRBdHRyaWJ1dGVYWFgoKSwgaXNBdHRyaWJ1dGVTcGVjaWZpZWQoKSwKLSAqICAgICAgICAgICAgZ2V0TmFtZXNwYWNlWFhYKCksCi0gKiAgICAgICAgICAgIGdldEVsZW1lbnRUZXh0KCksIG5leHRUYWcoKQotICogICAgICAgPC90ZD4KLSAqICAgICA8L3RyPgotICogICAgICAgPHRkPiBBVFRSSUJVVEUgIDwvdGQ+Ci0gKiAgICAgICA8dGQ+IG5leHQoKSwgbmV4dFRhZygpCi0gKiAgICAgICAgICAgIGdldEF0dHJpYnV0ZVhYWCgpLCBpc0F0dHJpYnV0ZVNwZWNpZmllZCgpLAotICogICAgICAgPC90ZD4KLSAqICAgICA8L3RyPgotICogICAgIDwvdHI+Ci0gKiAgICAgICA8dGQ+IE5BTUVTUEFDRSAgPC90ZD4KLSAqICAgICAgIDx0ZD4gbmV4dCgpLCBuZXh0VGFnKCkKLSAqICAgICAgICAgICAgZ2V0TmFtZXNwYWNlWFhYKCkKLSAqICAgICAgIDwvdGQ+Ci0gKiAgICAgPC90cj4KLSAqICAgICA8dHI+Ci0gKiAgICAgICA8dGQ+IEVORF9FTEVNRU5UICA8L3RkPgotICogICAgICAgPHRkPiBuZXh0KCksIGdldE5hbWUoKSwgZ2V0TG9jYWxOYW1lKCksIGhhc05hbWUoKSwgZ2V0UHJlZml4KCksCi0gKiAgICAgICAgICAgIGdldE5hbWVzcGFjZVhYWCgpLCBuZXh0VGFnKCkKLSAqICAgICAgPC90ZD4KLSAqICAgICA8L3RyPgotICogICAgIDx0cj4KLSAqICAgICAgIDx0ZD4gQ0hBUkFDVEVSUyAgPC90ZD4KLSAqICAgICAgIDx0ZD4gbmV4dCgpLCBnZXRUZXh0WFhYKCksIG5leHRUYWcoKSA8L3RkPgotICogICAgIDwvdHI+Ci0gKiAgICAgPHRyPgotICogICAgICAgPHRkPiBDREFUQSAgPC90ZD4KLSAqICAgICAgIDx0ZD4gbmV4dCgpLCBnZXRUZXh0WFhYKCksIG5leHRUYWcoKSA8L3RkPgotICogICAgIDwvdHI+Ci0gKiAgICAgPHRyPgotICogICAgICAgPHRkPiBDT01NRU5UICA8L3RkPgotICogICAgICAgPHRkPiBuZXh0KCksIGdldFRleHRYWFgoKSwgbmV4dFRhZygpIDwvdGQ+Ci0gKiAgICAgPC90cj4KLSAqICAgICA8dHI+Ci0gKiAgICAgICA8dGQ+IFNQQUNFICA8L3RkPgotICogICAgICAgPHRkPiBuZXh0KCksIGdldFRleHRYWFgoKSwgbmV4dFRhZygpIDwvdGQ+Ci0gKiAgICAgPC90cj4KLSAqICAgICA8dHI+Ci0gKiAgICAgICA8dGQ+IFNUQVJUX0RPQ1VNRU5UICA8L3RkPgotICogICAgICAgPHRkPiBuZXh0KCksIGdldEVuY29kaW5nKCksIGdldFZlcnNpb24oKSwgaXNTdGFuZGFsb25lKCksIHN0YW5kYWxvbmVTZXQoKSwKLSAqICAgICAgICAgICAgZ2V0Q2hhcmFjdGVyRW5jb2RpbmdTY2hlbWUoKSwgbmV4dFRhZygpPC90ZD4KLSAqICAgICA8L3RyPgotICogICAgIDx0cj4KLSAqICAgICAgIDx0ZD4gRU5EX0RPQ1VNRU5UICA8L3RkPgotICogICAgICAgPHRkPiBjbG9zZSgpPC90ZD4KLSAqICAgICA8L3RyPgotICogICAgIDx0cj4KLSAqICAgICAgIDx0ZD4gUFJPQ0VTU0lOR19JTlNUUlVDVElPTiAgPC90ZD4KLSAqICAgICAgIDx0ZD4gbmV4dCgpLCBnZXRQSVRhcmdldCgpLCBnZXRQSURhdGEoKSwgbmV4dFRhZygpIDwvdGQ+Ci0gKiAgICAgPC90cj4KLSAqICAgICA8dHI+Ci0gKiAgICAgICA8dGQ+IEVOVElUWV9SRUZFUkVOQ0UgIDwvdGQ+Ci0gKiAgICAgICA8dGQ+IG5leHQoKSwgZ2V0TG9jYWxOYW1lKCksIGdldFRleHQoKSwgbmV4dFRhZygpIDwvdGQ+Ci0gKiAgICAgPC90cj4KLSAqICAgICA8dHI+Ci0gKiAgICAgICA8dGQ+IERURCAgPC90ZD4KLSAqICAgICAgIDx0ZD4gbmV4dCgpLCBnZXRUZXh0KCksIG5leHRUYWcoKSA8L3RkPgotICogICAgIDwvdHI+Ci0gKiAgIDwvdGJvZHk+Ci0gKiAgPC90YWJsZT4KLSAqCi0gKiBAdmVyc2lvbiAxLjAKLSAqIEBhdXRob3IgQ29weXJpZ2h0IChjKSAyMDA5IGJ5IE9yYWNsZSBDb3Jwb3JhdGlvbi4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KLSAqIEBzZWUgamF2YXgueG1sLnN0cmVhbS5ldmVudHMuWE1MRXZlbnQKLSAqIEBzZWUgWE1MSW5wdXRGYWN0b3J5Ci0gKiBAc2VlIFhNTFN0cmVhbVdyaXRlcgotICogQHNpbmNlIDEuNgotICovCi1wdWJsaWMgaW50ZXJmYWNlIFhNTFN0cmVhbVJlYWRlciBleHRlbmRzIFhNTFN0cmVhbUNvbnN0YW50cyB7Ci0gIC8qKgotICAgKiBHZXQgdGhlIHZhbHVlIG9mIGEgZmVhdHVyZS9wcm9wZXJ0eSBmcm9tIHRoZSB1bmRlcmx5aW5nIGltcGxlbWVudGF0aW9uCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBwcm9wZXJ0eSwgbWF5IG5vdCBiZSBudWxsCi0gICAqIEByZXR1cm4gVGhlIHZhbHVlIG9mIHRoZSBwcm9wZXJ0eQotICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiBuYW1lIGlzIG51bGwKLSAgICovCi0gIHB1YmxpYyBPYmplY3QgZ2V0UHJvcGVydHkoamF2YS5sYW5nLlN0cmluZyBuYW1lKSB0aHJvd3MgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbjsKLQotICAvKioKLSAgICogR2V0IG5leHQgcGFyc2luZyBldmVudCAtIGEgcHJvY2Vzc29yIG1heSByZXR1cm4gYWxsIGNvbnRpZ3VvdXMKLSAgICogY2hhcmFjdGVyIGRhdGEgaW4gYSBzaW5nbGUgY2h1bmssIG9yIGl0IG1heSBzcGxpdCBpdCBpbnRvIHNldmVyYWwgY2h1bmtzLgotICAgKiBJZiB0aGUgcHJvcGVydHkgamF2YXgueG1sLnN0cmVhbS5pc0NvYWxlc2NpbmcgaXMgc2V0IHRvIHRydWUKLSAgICogZWxlbWVudCBjb250ZW50IG11c3QgYmUgY29hbGVzY2VkIGFuZCBvbmx5IG9uZSBDSEFSQUNURVJTIGV2ZW50Ci0gICAqIG11c3QgYmUgcmV0dXJuZWQgZm9yIGNvbnRpZ3VvdXMgZWxlbWVudCBjb250ZW50IG9yCi0gICAqIENEQVRBIFNlY3Rpb25zLgotICAgKgotICAgKiBCeSBkZWZhdWx0IGVudGl0eSByZWZlcmVuY2VzIG11c3QgYmUKLSAgICogZXhwYW5kZWQgYW5kIHJlcG9ydGVkIHRyYW5zcGFyZW50bHkgdG8gdGhlIGFwcGxpY2F0aW9uLgotICAgKiBBbiBleGNlcHRpb24gd2lsbCBiZSB0aHJvd24gaWYgYW4gZW50aXR5IHJlZmVyZW5jZSBjYW5ub3QgYmUgZXhwYW5kZWQuCi0gICAqIElmIGVsZW1lbnQgY29udGVudCBpcyBlbXB0eSAoaS5lLiBjb250ZW50IGlzICIiKSB0aGVuIG5vIENIQVJBQ1RFUlMgZXZlbnQgd2lsbCBiZSByZXBvcnRlZC4KLSAgICoKLSAgICogPHA+R2l2ZW4gdGhlIGZvbGxvd2luZyBYTUw6PGJyPgotICAgKiAmbHQ7Zm9vPiZsdDshLS1kZXNjcmlwdGlvbi0tPmNvbnRlbnQgdGV4dCZsdDshW0NEQVRBWyZsdDtncmVldGluZz5IZWxsbyZsdDsvZ3JlZXRpbmc+XV0+b3RoZXIgY29udGVudCZsdDsvZm9vPjxicj4KLSAgICogVGhlIGJlaGF2aW9yIG9mIGNhbGxpbmcgbmV4dCgpIHdoZW4gYmVpbmcgb24gZm9vIHdpbGwgYmU6PGJyPgotICAgKiAxLSB0aGUgY29tbWVudCAoQ09NTUVOVCk8YnI+Ci0gICAqIDItIHRoZW4gdGhlIGNoYXJhY3RlcnMgc2VjdGlvbiAoQ0hBUkFDVEVSUyk8YnI+Ci0gICAqIDMtIHRoZW4gdGhlIENEQVRBIHNlY3Rpb24gKGFub3RoZXIgQ0hBUkFDVEVSUyk8YnI+Ci0gICAqIDQtIHRoZW4gdGhlIG5leHQgY2hhcmFjdGVycyBzZWN0aW9uIChhbm90aGVyIENIQVJBQ1RFUlMpPGJyPgotICAgKiA1LSB0aGVuIHRoZSBFTkRfRUxFTUVOVDxicj4KLSAgICoKLSAgICogPHA+PGI+Tk9URTo8L2I+IGVtcHR5IGVsZW1lbnQgKHN1Y2ggYXMgJmx0O3RhZy8+KSB3aWxsIGJlIHJlcG9ydGVkCi0gICAqICB3aXRoICB0d28gc2VwYXJhdGUgZXZlbnRzOiBTVEFSVF9FTEVNRU5ULCBFTkRfRUxFTUVOVCAtIFRoaXMgcHJlc2VydmVzCi0gICAqICAgcGFyc2luZyBlcXVpdmFsZW5jeSBvZiBlbXB0eSBlbGVtZW50IHRvICZsdDt0YWc+Jmx0Oy90YWc+LgotICAgKgotICAgKiBUaGlzIG1ldGhvZCB3aWxsIHRocm93IGFuIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiBpdCBpcyBjYWxsZWQgYWZ0ZXIgaGFzTmV4dCgpIHJldHVybnMgZmFsc2UuCi0gICAqIEBzZWUgamF2YXgueG1sLnN0cmVhbS5ldmVudHMuWE1MRXZlbnQKLSAgICogQHJldHVybiB0aGUgaW50ZWdlciBjb2RlIGNvcnJlc3BvbmRpbmcgdG8gdGhlIGN1cnJlbnQgcGFyc2UgZXZlbnQKLSAgICogQHRocm93cyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uIGlmIHRoaXMgaXMgY2FsbGVkIHdoZW4gaGFzTmV4dCgpIHJldHVybnMgZmFsc2UKLSAgICogQHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24gIGlmIHRoZXJlIGlzIGFuIGVycm9yIHByb2Nlc3NpbmcgdGhlIHVuZGVybHlpbmcgWE1MIHNvdXJjZQotICAgKi8KLSAgcHVibGljIGludCBuZXh0KCkgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbjsKLQotICAvKioKLSAgICogVGVzdCBpZiB0aGUgY3VycmVudCBldmVudCBpcyBvZiB0aGUgZ2l2ZW4gdHlwZSBhbmQgaWYgdGhlIG5hbWVzcGFjZSBhbmQgbmFtZSBtYXRjaCB0aGUgY3VycmVudAotICAgKiBuYW1lc3BhY2UgYW5kIG5hbWUgb2YgdGhlIGN1cnJlbnQgZXZlbnQuICBJZiB0aGUgbmFtZXNwYWNlVVJJIGlzIG51bGwgaXQgaXMgbm90IGNoZWNrZWQgZm9yIGVxdWFsaXR5LAotICAgKiBpZiB0aGUgbG9jYWxOYW1lIGlzIG51bGwgaXQgaXMgbm90IGNoZWNrZWQgZm9yIGVxdWFsaXR5LgotICAgKiBAcGFyYW0gdHlwZSB0aGUgZXZlbnQgdHlwZQotICAgKiBAcGFyYW0gbmFtZXNwYWNlVVJJIHRoZSB1cmkgb2YgdGhlIGV2ZW50LCBtYXkgYmUgbnVsbAotICAgKiBAcGFyYW0gbG9jYWxOYW1lIHRoZSBsb2NhbE5hbWUgb2YgdGhlIGV2ZW50LCBtYXkgYmUgbnVsbAotICAgKiBAdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbiBpZiB0aGUgcmVxdWlyZWQgdmFsdWVzIGFyZSBub3QgbWF0Y2hlZC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHJlcXVpcmUoaW50IHR5cGUsIFN0cmluZyBuYW1lc3BhY2VVUkksIFN0cmluZyBsb2NhbE5hbWUpIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb247Ci0KLSAgLyoqCi0gICAqIFJlYWRzIHRoZSBjb250ZW50IG9mIGEgdGV4dC1vbmx5IGVsZW1lbnQsIGFuIGV4Y2VwdGlvbiBpcyB0aHJvd24gaWYgdGhpcyBpcwotICAgKiBub3QgYSB0ZXh0LW9ubHkgZWxlbWVudC4KLSAgICogUmVnYXJkbGVzcyBvZiB2YWx1ZSBvZiBqYXZheC54bWwuc3RyZWFtLmlzQ29hbGVzY2luZyB0aGlzIG1ldGhvZCBhbHdheXMgcmV0dXJucyBjb2FsZXNjZWQgY29udGVudC4KLSAgICogPGJyIC8+IFByZWNvbmRpdGlvbjogdGhlIGN1cnJlbnQgZXZlbnQgaXMgU1RBUlRfRUxFTUVOVC4KLSAgICogPGJyIC8+IFBvc3Rjb25kaXRpb246IHRoZSBjdXJyZW50IGV2ZW50IGlzIHRoZSBjb3JyZXNwb25kaW5nIEVORF9FTEVNRU5ULgotICAgKgotICAgKiA8YnIgLz5UaGUgbWV0aG9kIGRvZXMgdGhlIGZvbGxvd2luZyAoaW1wbGVtZW50YXRpb25zIGFyZSBmcmVlIHRvIG9wdGltaXplZAotICAgKiBidXQgbXVzdCBkbyBlcXVpdmFsZW50IHByb2Nlc3NpbmcpOgotICAgKiA8cHJlPgotICAgKiBpZihnZXRFdmVudFR5cGUoKSAhPSBYTUxTdHJlYW1Db25zdGFudHMuU1RBUlRfRUxFTUVOVCkgewotICAgKiB0aHJvdyBuZXcgWE1MU3RyZWFtRXhjZXB0aW9uKAotICAgKiAicGFyc2VyIG11c3QgYmUgb24gU1RBUlRfRUxFTUVOVCB0byByZWFkIG5leHQgdGV4dCIsIGdldExvY2F0aW9uKCkpOwotICAgKiB9Ci0gICAqIGludCBldmVudFR5cGUgPSBuZXh0KCk7Ci0gICAqIFN0cmluZ0J1ZmZlciBjb250ZW50ID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotICAgKiB3aGlsZShldmVudFR5cGUgIT0gWE1MU3RyZWFtQ29uc3RhbnRzLkVORF9FTEVNRU5UICkgewotICAgKiBpZihldmVudFR5cGUgPT0gWE1MU3RyZWFtQ29uc3RhbnRzLkNIQVJBQ1RFUlMKLSAgICogfHwgZXZlbnRUeXBlID09IFhNTFN0cmVhbUNvbnN0YW50cy5DREFUQQotICAgKiB8fCBldmVudFR5cGUgPT0gWE1MU3RyZWFtQ29uc3RhbnRzLlNQQUNFCi0gICAqIHx8IGV2ZW50VHlwZSA9PSBYTUxTdHJlYW1Db25zdGFudHMuRU5USVRZX1JFRkVSRU5DRSkgewotICAgKiBidWYuYXBwZW5kKGdldFRleHQoKSk7Ci0gICAqIH0gZWxzZSBpZihldmVudFR5cGUgPT0gWE1MU3RyZWFtQ29uc3RhbnRzLlBST0NFU1NJTkdfSU5TVFJVQ1RJT04KLSAgICogfHwgZXZlbnRUeXBlID09IFhNTFN0cmVhbUNvbnN0YW50cy5DT01NRU5UKSB7Ci0gICAqIC8vIHNraXBwaW5nCi0gICAqIH0gZWxzZSBpZihldmVudFR5cGUgPT0gWE1MU3RyZWFtQ29uc3RhbnRzLkVORF9ET0NVTUVOVCkgewotICAgKiB0aHJvdyBuZXcgWE1MU3RyZWFtRXhjZXB0aW9uKAotICAgKiAidW5leHBlY3RlZCBlbmQgb2YgZG9jdW1lbnQgd2hlbiByZWFkaW5nIGVsZW1lbnQgdGV4dCBjb250ZW50IiwgdGhpcyk7Ci0gICAqIH0gZWxzZSBpZihldmVudFR5cGUgPT0gWE1MU3RyZWFtQ29uc3RhbnRzLlNUQVJUX0VMRU1FTlQpIHsKLSAgICogdGhyb3cgbmV3IFhNTFN0cmVhbUV4Y2VwdGlvbigKLSAgICogImVsZW1lbnQgdGV4dCBjb250ZW50IG1heSBub3QgY29udGFpbiBTVEFSVF9FTEVNRU5UIiwgZ2V0TG9jYXRpb24oKSk7Ci0gICAqIH0gZWxzZSB7Ci0gICAqIHRocm93IG5ldyBYTUxTdHJlYW1FeGNlcHRpb24oCi0gICAqICJVbmV4cGVjdGVkIGV2ZW50IHR5cGUgIitldmVudFR5cGUsIGdldExvY2F0aW9uKCkpOwotICAgKiB9Ci0gICAqIGV2ZW50VHlwZSA9IG5leHQoKTsKLSAgICogfQotICAgKiByZXR1cm4gYnVmLnRvU3RyaW5nKCk7Ci0gICAqIDwvcHJlPgotICAgKgotICAgKiBAdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbiBpZiB0aGUgY3VycmVudCBldmVudCBpcyBub3QgYSBTVEFSVF9FTEVNRU5UCi0gICAqIG9yIGlmIGEgbm9uIHRleHQgZWxlbWVudCBpcyBlbmNvdW50ZXJlZAotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRFbGVtZW50VGV4dCgpIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb247Ci0KLSAgLyoqCi0gICAqIFNraXBzIGFueSB3aGl0ZSBzcGFjZSAoaXNXaGl0ZVNwYWNlKCkgcmV0dXJucyB0cnVlKSwgQ09NTUVOVCwKLSAgICogb3IgUFJPQ0VTU0lOR19JTlNUUlVDVElPTiwKLSAgICogdW50aWwgYSBTVEFSVF9FTEVNRU5UIG9yIEVORF9FTEVNRU5UIGlzIHJlYWNoZWQuCi0gICAqIElmIG90aGVyIHRoYW4gd2hpdGUgc3BhY2UgY2hhcmFjdGVycywgQ09NTUVOVCwgUFJPQ0VTU0lOR19JTlNUUlVDVElPTiwgU1RBUlRfRUxFTUVOVCwgRU5EX0VMRU1FTlQKLSAgICogYXJlIGVuY291bnRlcmVkLCBhbiBleGNlcHRpb24gaXMgdGhyb3duLiBUaGlzIG1ldGhvZCBzaG91bGQKLSAgICogYmUgdXNlZCB3aGVuIHByb2Nlc3NpbmcgZWxlbWVudC1vbmx5IGNvbnRlbnQgc2VwZXJhdGVkIGJ5IHdoaXRlIHNwYWNlLgotICAgKgotICAgKiA8YnIgLz4gUHJlY29uZGl0aW9uOiBub25lCi0gICAqIDxiciAvPiBQb3N0Y29uZGl0aW9uOiB0aGUgY3VycmVudCBldmVudCBpcyBTVEFSVF9FTEVNRU5UIG9yIEVORF9FTEVNRU5UCi0gICAqIGFuZCBjdXJzb3IgbWF5IGhhdmUgbW92ZWQgb3ZlciBhbnkgd2hpdGVzcGFjZSBldmVudC4KLSAgICoKLSAgICogPGJyIC8+RXNzZW50aWFsbHkgaXQgZG9lcyB0aGUgZm9sbG93aW5nIChpbXBsZW1lbnRhdGlvbnMgYXJlIGZyZWUgdG8gb3B0aW1pemVkCi0gICAqIGJ1dCBtdXN0IGRvIGVxdWl2YWxlbnQgcHJvY2Vzc2luZyk6Ci0gICAqIDxwcmU+Ci0gICAqIGludCBldmVudFR5cGUgPSBuZXh0KCk7Ci0gICAqIHdoaWxlKChldmVudFR5cGUgPT0gWE1MU3RyZWFtQ29uc3RhbnRzLkNIQVJBQ1RFUlMgJmFtcDsmYW1wOyBpc1doaXRlU3BhY2UoKSkgLy8gc2tpcCB3aGl0ZXNwYWNlCi0gICAqIHx8IChldmVudFR5cGUgPT0gWE1MU3RyZWFtQ29uc3RhbnRzLkNEQVRBICZhbXA7JmFtcDsgaXNXaGl0ZVNwYWNlKCkpCi0gICAqIC8vIHNraXAgd2hpdGVzcGFjZQotICAgKiB8fCBldmVudFR5cGUgPT0gWE1MU3RyZWFtQ29uc3RhbnRzLlNQQUNFCi0gICAqIHx8IGV2ZW50VHlwZSA9PSBYTUxTdHJlYW1Db25zdGFudHMuUFJPQ0VTU0lOR19JTlNUUlVDVElPTgotICAgKiB8fCBldmVudFR5cGUgPT0gWE1MU3RyZWFtQ29uc3RhbnRzLkNPTU1FTlQKLSAgICogKSB7Ci0gICAqIGV2ZW50VHlwZSA9IG5leHQoKTsKLSAgICogfQotICAgKiBpZiAoZXZlbnRUeXBlICE9IFhNTFN0cmVhbUNvbnN0YW50cy5TVEFSVF9FTEVNRU5UICZhbXA7JmFtcDsgZXZlbnRUeXBlICE9IFhNTFN0cmVhbUNvbnN0YW50cy5FTkRfRUxFTUVOVCkgewotICAgKiB0aHJvdyBuZXcgU3RyaW5nIFhNTFN0cmVhbUV4Y2VwdGlvbigiZXhwZWN0ZWQgc3RhcnQgb3IgZW5kIHRhZyIsIGdldExvY2F0aW9uKCkpOwotICAgKiB9Ci0gICAqIHJldHVybiBldmVudFR5cGU7Ci0gICAqIDwvcHJlPgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBldmVudCB0eXBlIG9mIHRoZSBlbGVtZW50IHJlYWQgKFNUQVJUX0VMRU1FTlQgb3IgRU5EX0VMRU1FTlQpCi0gICAqIEB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uIGlmIHRoZSBjdXJyZW50IGV2ZW50IGlzIG5vdCB3aGl0ZSBzcGFjZSwgUFJPQ0VTU0lOR19JTlNUUlVDVElPTiwKLSAgICogU1RBUlRfRUxFTUVOVCBvciBFTkRfRUxFTUVOVAotICAgKiBAdGhyb3dzIE5vU3VjaEVsZW1lbnRFeGNlcHRpb24gaWYgdGhpcyBpcyBjYWxsZWQgd2hlbiBoYXNOZXh0KCkgcmV0dXJucyBmYWxzZQotICAgKi8KLSAgcHVibGljIGludCBuZXh0VGFnKCkgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbjsKLQotICAvKioKLSAgICogUmV0dXJucyB0cnVlIGlmIHRoZXJlIGFyZSBtb3JlIHBhcnNpbmcgZXZlbnRzIGFuZCBmYWxzZQotICAgKiBpZiB0aGVyZSBhcmUgbm8gbW9yZSBldmVudHMuICBUaGlzIG1ldGhvZCB3aWxsIHJldHVybgotICAgKiBmYWxzZSBpZiB0aGUgY3VycmVudCBzdGF0ZSBvZiB0aGUgWE1MU3RyZWFtUmVhZGVyIGlzCi0gICAqIEVORF9ET0NVTUVOVAotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlcmUgYXJlIG1vcmUgZXZlbnRzLCBmYWxzZSBvdGhlcndpc2UKLSAgICogQHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24gaWYgdGhlcmUgaXMgYSBmYXRhbCBlcnJvciBkZXRlY3RpbmcgdGhlIG5leHQgc3RhdGUKLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGhhc05leHQoKSB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uOwotCi0gIC8qKgotICAgKiBGcmVlcyBhbnkgcmVzb3VyY2VzIGFzc29jaWF0ZWQgd2l0aCB0aGlzIFJlYWRlci4gIFRoaXMgbWV0aG9kIGRvZXMgbm90IGNsb3NlIHRoZQotICAgKiB1bmRlcmx5aW5nIGlucHV0IHNvdXJjZS4KLSAgICogQHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24gaWYgdGhlcmUgYXJlIGVycm9ycyBmcmVlaW5nIGFzc29jaWF0ZWQgcmVzb3VyY2VzCi0gICAqLwotICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb247Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgdXJpIGZvciB0aGUgZ2l2ZW4gcHJlZml4LgotICAgKiBUaGUgdXJpIHJldHVybmVkIGRlcGVuZHMgb24gdGhlIGN1cnJlbnQgc3RhdGUgb2YgdGhlIHByb2Nlc3Nvci4KLSAgICoKLSAgICogPHA+PHN0cm9uZz5OT1RFOjwvc3Ryb25nPlRoZSAneG1sJyBwcmVmaXggaXMgYm91bmQgYXMgZGVmaW5lZCBpbgotICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMteG1sLW5hbWVzLyNucy11c2luZyI+TmFtZXNwYWNlcyBpbiBYTUw8L2E+Ci0gICAqIHNwZWNpZmljYXRpb24gdG8gImh0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZSIuCi0gICAqCi0gICAqIDxwPjxzdHJvbmc+Tk9URTo8L3N0cm9uZz4gVGhlICd4bWxucycgcHJlZml4IG11c3QgYmUgcmVzb2x2ZWQgdG8gZm9sbG93aW5nIG5hbWVzcGFjZQotICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3htbG5zLyI+aHR0cDovL3d3dy53My5vcmcvMjAwMC94bWxucy88L2E+Ci0gICAqIEBwYXJhbSBwcmVmaXggVGhlIHByZWZpeCB0byBsb29rdXAsIG1heSBub3QgYmUgbnVsbAotICAgKiBAcmV0dXJuIHRoZSB1cmkgYm91bmQgdG8gdGhlIGdpdmVuIHByZWZpeCBvciBudWxsIGlmIGl0IGlzIG5vdCBib3VuZAotICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgcHJlZml4IGlzIG51bGwKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZXNwYWNlVVJJKFN0cmluZyBwcmVmaXgpOwotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIGN1cnNvciBwb2ludHMgdG8gYSBzdGFydCB0YWcgKG90aGVyd2lzZSBmYWxzZSkKLSAgICogQHJldHVybiB0cnVlIGlmIHRoZSBjdXJzb3IgcG9pbnRzIHRvIGEgc3RhcnQgdGFnLCBmYWxzZSBvdGhlcndpc2UKLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzU3RhcnRFbGVtZW50KCk7Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgY3Vyc29yIHBvaW50cyB0byBhbiBlbmQgdGFnIChvdGhlcndpc2UgZmFsc2UpCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgY3Vyc29yIHBvaW50cyB0byBhbiBlbmQgdGFnLCBmYWxzZSBvdGhlcndpc2UKLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzRW5kRWxlbWVudCgpOwotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIGN1cnNvciBwb2ludHMgdG8gYSBjaGFyYWN0ZXIgZGF0YSBldmVudAotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGN1cnNvciBwb2ludHMgdG8gY2hhcmFjdGVyIGRhdGEsIGZhbHNlIG90aGVyd2lzZQotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNDaGFyYWN0ZXJzKCk7Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgY3Vyc29yIHBvaW50cyB0byBhIGNoYXJhY3RlciBkYXRhIGV2ZW50Ci0gICAqIHRoYXQgY29uc2lzdHMgb2YgYWxsIHdoaXRlc3BhY2UKLSAgICogQHJldHVybiB0cnVlIGlmIHRoZSBjdXJzb3IgcG9pbnRzIHRvIGFsbCB3aGl0ZXNwYWNlLCBmYWxzZSBvdGhlcndpc2UKLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzV2hpdGVTcGFjZSgpOwotCi0KLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIG5vcm1hbGl6ZWQgYXR0cmlidXRlIHZhbHVlIG9mIHRoZQotICAgKiBhdHRyaWJ1dGUgd2l0aCB0aGUgbmFtZXNwYWNlIGFuZCBsb2NhbE5hbWUKLSAgICogSWYgdGhlIG5hbWVzcGFjZVVSSSBpcyBudWxsIHRoZSBuYW1lc3BhY2UKLSAgICogaXMgbm90IGNoZWNrZWQgZm9yIGVxdWFsaXR5Ci0gICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkgdGhlIG5hbWVzcGFjZSBvZiB0aGUgYXR0cmlidXRlCi0gICAqIEBwYXJhbSBsb2NhbE5hbWUgdGhlIGxvY2FsIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZSwgY2Fubm90IGJlIG51bGwKLSAgICogQHJldHVybiByZXR1cm5zIHRoZSB2YWx1ZSBvZiB0aGUgYXR0cmlidXRlICwgcmV0dXJucyBudWxsIGlmIG5vdCBmb3VuZAotICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGlzIGlzIG5vdCBhIFNUQVJUX0VMRU1FTlQgb3IgQVRUUklCVVRFCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldEF0dHJpYnV0ZVZhbHVlKFN0cmluZyBuYW1lc3BhY2VVUkksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGxvY2FsTmFtZSk7Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIGNvdW50IG9mIGF0dHJpYnV0ZXMgb24gdGhpcyBTVEFSVF9FTEVNRU5ULAotICAgKiB0aGlzIG1ldGhvZCBpcyBvbmx5IHZhbGlkIG9uIGEgU1RBUlRfRUxFTUVOVCBvciBBVFRSSUJVVEUuICBUaGlzCi0gICAqIGNvdW50IGV4Y2x1ZGVzIG5hbWVzcGFjZSBkZWZpbml0aW9ucy4gIEF0dHJpYnV0ZSBpbmRpY2VzIGFyZQotICAgKiB6ZXJvLWJhc2VkLgotICAgKiBAcmV0dXJuIHJldHVybnMgdGhlIG51bWJlciBvZiBhdHRyaWJ1dGVzCi0gICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgaXMgbm90IGEgU1RBUlRfRUxFTUVOVCBvciBBVFRSSUJVVEUKLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0QXR0cmlidXRlQ291bnQoKTsKLQotICAvKiogUmV0dXJucyB0aGUgcW5hbWUgb2YgdGhlIGF0dHJpYnV0ZSBhdCB0aGUgcHJvdmlkZWQgaW5kZXgKLSAgICoKLSAgICogQHBhcmFtIGluZGV4IHRoZSBwb3NpdGlvbiBvZiB0aGUgYXR0cmlidXRlCi0gICAqIEByZXR1cm4gdGhlIFFOYW1lIG9mIHRoZSBhdHRyaWJ1dGUKLSAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBpcyBub3QgYSBTVEFSVF9FTEVNRU5UIG9yIEFUVFJJQlVURQotICAgKi8KLSAgcHVibGljIFFOYW1lIGdldEF0dHJpYnV0ZU5hbWUoaW50IGluZGV4KTsKLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgbmFtZXNwYWNlIG9mIHRoZSBhdHRyaWJ1dGUgYXQgdGhlIHByb3ZpZGVkCi0gICAqIGluZGV4Ci0gICAqIEBwYXJhbSBpbmRleCB0aGUgcG9zaXRpb24gb2YgdGhlIGF0dHJpYnV0ZQotICAgKiBAcmV0dXJuIHRoZSBuYW1lc3BhY2UgVVJJIChjYW4gYmUgbnVsbCkKLSAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBpcyBub3QgYSBTVEFSVF9FTEVNRU5UIG9yIEFUVFJJQlVURQotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRBdHRyaWJ1dGVOYW1lc3BhY2UoaW50IGluZGV4KTsKLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgbG9jYWxOYW1lIG9mIHRoZSBhdHRyaWJ1dGUgYXQgdGhlIHByb3ZpZGVkCi0gICAqIGluZGV4Ci0gICAqIEBwYXJhbSBpbmRleCB0aGUgcG9zaXRpb24gb2YgdGhlIGF0dHJpYnV0ZQotICAgKiBAcmV0dXJuIHRoZSBsb2NhbE5hbWUgb2YgdGhlIGF0dHJpYnV0ZQotICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGlzIGlzIG5vdCBhIFNUQVJUX0VMRU1FTlQgb3IgQVRUUklCVVRFCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldEF0dHJpYnV0ZUxvY2FsTmFtZShpbnQgaW5kZXgpOwotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBwcmVmaXggb2YgdGhpcyBhdHRyaWJ1dGUgYXQgdGhlCi0gICAqIHByb3ZpZGVkIGluZGV4Ci0gICAqIEBwYXJhbSBpbmRleCB0aGUgcG9zaXRpb24gb2YgdGhlIGF0dHJpYnV0ZQotICAgKiBAcmV0dXJuIHRoZSBwcmVmaXggb2YgdGhlIGF0dHJpYnV0ZQotICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGlzIGlzIG5vdCBhIFNUQVJUX0VMRU1FTlQgb3IgQVRUUklCVVRFCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldEF0dHJpYnV0ZVByZWZpeChpbnQgaW5kZXgpOwotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBYTUwgdHlwZSBvZiB0aGUgYXR0cmlidXRlIGF0IHRoZSBwcm92aWRlZAotICAgKiBpbmRleAotICAgKiBAcGFyYW0gaW5kZXggdGhlIHBvc2l0aW9uIG9mIHRoZSBhdHRyaWJ1dGUKLSAgICogQHJldHVybiB0aGUgWE1MIHR5cGUgb2YgdGhlIGF0dHJpYnV0ZQotICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGlzIGlzIG5vdCBhIFNUQVJUX0VMRU1FTlQgb3IgQVRUUklCVVRFCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldEF0dHJpYnV0ZVR5cGUoaW50IGluZGV4KTsKLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZSBhdCB0aGUKLSAgICogaW5kZXgKLSAgICogQHBhcmFtIGluZGV4IHRoZSBwb3NpdGlvbiBvZiB0aGUgYXR0cmlidXRlCi0gICAqIEByZXR1cm4gdGhlIGF0dHJpYnV0ZSB2YWx1ZQotICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGlzIGlzIG5vdCBhIFNUQVJUX0VMRU1FTlQgb3IgQVRUUklCVVRFCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldEF0dHJpYnV0ZVZhbHVlKGludCBpbmRleCk7Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgYSBib29sZWFuIHdoaWNoIGluZGljYXRlcyBpZiB0aGlzCi0gICAqIGF0dHJpYnV0ZSB3YXMgY3JlYXRlZCBieSBkZWZhdWx0Ci0gICAqIEBwYXJhbSBpbmRleCB0aGUgcG9zaXRpb24gb2YgdGhlIGF0dHJpYnV0ZQotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhpcyBpcyBhIGRlZmF1bHQgYXR0cmlidXRlCi0gICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgaXMgbm90IGEgU1RBUlRfRUxFTUVOVCBvciBBVFRSSUJVVEUKLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzQXR0cmlidXRlU3BlY2lmaWVkKGludCBpbmRleCk7Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIGNvdW50IG9mIG5hbWVzcGFjZXMgZGVjbGFyZWQgb24gdGhpcyBTVEFSVF9FTEVNRU5UIG9yIEVORF9FTEVNRU5ULAotICAgKiB0aGlzIG1ldGhvZCBpcyBvbmx5IHZhbGlkIG9uIGEgU1RBUlRfRUxFTUVOVCwgRU5EX0VMRU1FTlQgb3IgTkFNRVNQQUNFLiBPbgotICAgKiBhbiBFTkRfRUxFTUVOVCB0aGUgY291bnQgaXMgb2YgdGhlIG5hbWVzcGFjZXMgdGhhdCBhcmUgYWJvdXQgdG8gZ28KLSAgICogb3V0IG9mIHNjb3BlLiAgVGhpcyBpcyB0aGUgZXF1aXZhbGVudCBvZiB0aGUgaW5mb3JtYXRpb24gcmVwb3J0ZWQKLSAgICogYnkgU0FYIGNhbGxiYWNrIGZvciBhbiBlbmQgZWxlbWVudCBldmVudC4KLSAgICogQHJldHVybiByZXR1cm5zIHRoZSBudW1iZXIgb2YgbmFtZXNwYWNlIGRlY2xhcmF0aW9ucyBvbiB0aGlzIHNwZWNpZmljIGVsZW1lbnQKLSAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBpcyBub3QgYSBTVEFSVF9FTEVNRU5ULCBFTkRfRUxFTUVOVCBvciBOQU1FU1BBQ0UKLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0TmFtZXNwYWNlQ291bnQoKTsKLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgcHJlZml4IGZvciB0aGUgbmFtZXNwYWNlIGRlY2xhcmVkIGF0IHRoZQotICAgKiBpbmRleC4gIFJldHVybnMgbnVsbCBpZiB0aGlzIGlzIHRoZSBkZWZhdWx0IG5hbWVzcGFjZQotICAgKiBkZWNsYXJhdGlvbgotICAgKgotICAgKiBAcGFyYW0gaW5kZXggdGhlIHBvc2l0aW9uIG9mIHRoZSBuYW1lc3BhY2UgZGVjbGFyYXRpb24KLSAgICogQHJldHVybiByZXR1cm5zIHRoZSBuYW1lc3BhY2UgcHJlZml4Ci0gICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgaXMgbm90IGEgU1RBUlRfRUxFTUVOVCwgRU5EX0VMRU1FTlQgb3IgTkFNRVNQQUNFCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldE5hbWVzcGFjZVByZWZpeChpbnQgaW5kZXgpOwotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSB1cmkgZm9yIHRoZSBuYW1lc3BhY2UgZGVjbGFyZWQgYXQgdGhlCi0gICAqIGluZGV4LgotICAgKgotICAgKiBAcGFyYW0gaW5kZXggdGhlIHBvc2l0aW9uIG9mIHRoZSBuYW1lc3BhY2UgZGVjbGFyYXRpb24KLSAgICogQHJldHVybiByZXR1cm5zIHRoZSBuYW1lc3BhY2UgdXJpCi0gICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgaXMgbm90IGEgU1RBUlRfRUxFTUVOVCwgRU5EX0VMRU1FTlQgb3IgTkFNRVNQQUNFCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldE5hbWVzcGFjZVVSSShpbnQgaW5kZXgpOwotCi0gIC8qKgotICAgKiBSZXR1cm5zIGEgcmVhZCBvbmx5IG5hbWVzcGFjZSBjb250ZXh0IGZvciB0aGUgY3VycmVudAotICAgKiBwb3NpdGlvbi4gIFRoZSBjb250ZXh0IGlzIHRyYW5zaWVudCBhbmQgb25seSB2YWxpZCB1bnRpbAotICAgKiBhIGNhbGwgdG8gbmV4dCgpIGNoYW5nZXMgdGhlIHN0YXRlIG9mIHRoZSByZWFkZXIuCi0gICAqIEByZXR1cm4gcmV0dXJuIGEgbmFtZXNwYWNlIGNvbnRleHQKLSAgICovCi0gIHB1YmxpYyBOYW1lc3BhY2VDb250ZXh0IGdldE5hbWVzcGFjZUNvbnRleHQoKTsKLQotICAvKioKLSAgICogUmV0dXJucyBhIHJlYWRlciB0aGF0IHBvaW50cyB0byB0aGUgY3VycmVudCBzdGFydCBlbGVtZW50Ci0gICAqIGFuZCBhbGwgb2YgaXRzIGNvbnRlbnRzLiAgVGhyb3dzIGFuIFhNTFN0cmVhbUV4Y2VwdGlvbiBpZiB0aGUKLSAgICogY3Vyc29yIGRvZXMgbm90IHBvaW50IHRvIGEgU1RBUlRfRUxFTUVOVC48cD4KLSAgICogVGhlIHN1YiBzdHJlYW0gaXMgcmVhZCBmcm9tIGl0IE1VU1QgYmUgcmVhZCBiZWZvcmUgdGhlIHBhcmVudCBzdHJlYW0gaXMKLSAgICogbW92ZWQgb24sIGlmIG5vdCBhbnkgY2FsbCBvbiB0aGUgc3ViIHN0cmVhbSB3aWxsIGNhdXNlIGFuIFhNTFN0cmVhbUV4Y2VwdGlvbiB0byBiZQotICAgKiB0aHJvd24uICAgVGhlIHBhcmVudCBzdHJlYW0gd2lsbCBhbHdheXMgcmV0dXJuIHRoZSBzYW1lIHJlc3VsdCBmcm9tIG5leHQoKQotICAgKiB3aGF0ZXZlciBpcyBkb25lIHRvIHRoZSBzdWIgc3RyZWFtLgotICAgKiBAcmV0dXJuIGFuIFhNTFN0cmVhbVJlYWRlciB3aGljaCBwb2ludHMgdG8gdGhlIG5leHQgZWxlbWVudAotICAgKi8KLSAgLy8gIHB1YmxpYyBYTUxTdHJlYW1SZWFkZXIgc3ViUmVhZGVyKCkgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbjsKLQotICAvKioKLSAgICogQWxsb3dzIHRoZSBpbXBsZW1lbnRhdGlvbiB0byByZXNldCBhbmQgcmV1c2UgYW55IHVuZGVybHlpbmcgdGFibGVzCi0gICAqLwotICAvLyAgcHVibGljIHZvaWQgcmVjeWNsZSgpIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb247Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgYW4gaW50ZWdlciBjb2RlIHRoYXQgaW5kaWNhdGVzIHRoZSB0eXBlCi0gICAqIG9mIHRoZSBldmVudCB0aGUgY3Vyc29yIGlzIHBvaW50aW5nIHRvLgotICAgKi8KLSAgcHVibGljIGludCBnZXRFdmVudFR5cGUoKTsKLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgcGFyc2UgZXZlbnQgYXMgYSBzdHJpbmcsCi0gICAqIHRoaXMgcmV0dXJucyB0aGUgc3RyaW5nIHZhbHVlIG9mIGEgQ0hBUkFDVEVSUyBldmVudCwKLSAgICogcmV0dXJucyB0aGUgdmFsdWUgb2YgYSBDT01NRU5ULCB0aGUgcmVwbGFjZW1lbnQgdmFsdWUKLSAgICogZm9yIGFuIEVOVElUWV9SRUZFUkVOQ0UsIHRoZSBzdHJpbmcgdmFsdWUgb2YgYSBDREFUQSBzZWN0aW9uLAotICAgKiB0aGUgc3RyaW5nIHZhbHVlIGZvciBhIFNQQUNFIGV2ZW50LAotICAgKiBvciB0aGUgU3RyaW5nIHZhbHVlIG9mIHRoZSBpbnRlcm5hbCBzdWJzZXQgb2YgdGhlIERURC4KLSAgICogSWYgYW4gRU5USVRZX1JFRkVSRU5DRSBoYXMgYmVlbiByZXNvbHZlZCwgYW55IGNoYXJhY3RlciBkYXRhCi0gICAqIHdpbGwgYmUgcmVwb3J0ZWQgYXMgQ0hBUkFDVEVSUyBldmVudHMuCi0gICAqIEByZXR1cm4gdGhlIGN1cnJlbnQgdGV4dCBvciBudWxsCi0gICAqIEB0aHJvd3MgamF2YS5sYW5nLklsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGlzIHN0YXRlIGlzIG5vdAotICAgKiBhIHZhbGlkIHRleHQgc3RhdGUuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFRleHQoKTsKLQotICAvKioKLSAgICogUmV0dXJucyBhbiBhcnJheSB3aGljaCBjb250YWlucyB0aGUgY2hhcmFjdGVycyBmcm9tIHRoaXMgZXZlbnQuCi0gICAqIFRoaXMgYXJyYXkgc2hvdWxkIGJlIHRyZWF0ZWQgYXMgcmVhZC1vbmx5IGFuZCB0cmFuc2llbnQuIEkuZS4gdGhlIGFycmF5IHdpbGwKLSAgICogY29udGFpbiB0aGUgdGV4dCBjaGFyYWN0ZXJzIHVudGlsIHRoZSBYTUxTdHJlYW1SZWFkZXIgbW92ZXMgb24gdG8gdGhlIG5leHQgZXZlbnQuCi0gICAqIEF0dGVtcHRzIHRvIGhvbGQgb250byB0aGUgY2hhcmFjdGVyIGFycmF5IGJleW9uZCB0aGF0IHRpbWUgb3IgbW9kaWZ5IHRoZQotICAgKiBjb250ZW50cyBvZiB0aGUgYXJyYXkgYXJlIGJyZWFjaGVzIG9mIHRoZSBjb250cmFjdCBmb3IgdGhpcyBpbnRlcmZhY2UuCi0gICAqIEByZXR1cm4gdGhlIGN1cnJlbnQgdGV4dCBvciBhbiBlbXB0eSBhcnJheQotICAgKiBAdGhyb3dzIGphdmEubGFuZy5JbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBzdGF0ZSBpcyBub3QKLSAgICogYSB2YWxpZCB0ZXh0IHN0YXRlLgotICAgKi8KLSAgcHVibGljIGNoYXJbXSBnZXRUZXh0Q2hhcmFjdGVycygpOwotCi0gIC8qKgotICAgKiBHZXRzIHRoZSB0aGUgdGV4dCBhc3NvY2lhdGVkIHdpdGggYSBDSEFSQUNURVJTLCBTUEFDRSBvciBDREFUQSBldmVudC4KLSAgICogVGV4dCBzdGFydGluZyBhICJzb3VyY2VTdGFydCIgaXMgY29waWVkIGludG8gInRhcmdldCIgc3RhcnRpbmcgYXQgInRhcmdldFN0YXJ0Ii4KLSAgICogVXAgdG8gImxlbmd0aCIgY2hhcmFjdGVycyBhcmUgY29waWVkLiAgVGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIGFjdHVhbGx5IGNvcGllZCBpcyByZXR1cm5lZC4KLSAgICoKLSAgICogVGhlICJzb3VyY2VTdGFydCIgYXJndW1lbnQgbXVzdCBiZSBncmVhdGVyIG9yIGVxdWFsIHRvIDAgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0bwotICAgKiB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgYXNzb2NpYXRlZCB3aXRoIHRoZSBldmVudC4gIFVzdWFsbHksIG9uZSByZXF1ZXN0cyB0ZXh0IHN0YXJ0aW5nIGF0IGEgInNvdXJjZVN0YXJ0IiBvZiAwLgotICAgKiBJZiB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgYWN0dWFsbHkgY29waWVkIGlzIGxlc3MgdGhhbiB0aGUgImxlbmd0aCIsIHRoZW4gdGhlcmUgaXMgbm8gbW9yZSB0ZXh0LgotICAgKiBPdGhlcndpc2UsIHN1YnNlcXVlbnQgY2FsbHMgbmVlZCB0byBiZSBtYWRlIHVudGlsIGFsbCB0ZXh0IGhhcyBiZWVuIHJldHJpZXZlZC4gRm9yIGV4YW1wbGU6Ci0gICAqCi0gICAqPGNvZGU+Ci0gICAqIGludCBsZW5ndGggPSAxMDI0OwotICAgKiBjaGFyW10gbXlCdWZmZXIgPSBuZXcgY2hhclsgbGVuZ3RoIF07Ci0gICAqCi0gICAqIGZvciAoIGludCBzb3VyY2VTdGFydCA9IDAgOyA7IHNvdXJjZVN0YXJ0ICs9IGxlbmd0aCApCi0gICAqIHsKLSAgICogICAgaW50IG5Db3BpZWQgPSBzdHJlYW0uZ2V0VGV4dENoYXJhY3RlcnMoIHNvdXJjZVN0YXJ0LCBteUJ1ZmZlciwgMCwgbGVuZ3RoICk7Ci0gICAqCi0gICAqICAgaWYgKG5Db3BpZWQgPCBsZW5ndGgpCi0gICAqICAgICAgIGJyZWFrOwotICAgKiB9Ci0gICAqIDwvY29kZT4KLSAgICogWE1MU3RyZWFtRXhjZXB0aW9uIG1heSBiZSB0aHJvd24gaWYgdGhlcmUgYXJlIGFueSBYTUwgZXJyb3JzIGluIHRoZSB1bmRlcmx5aW5nIHNvdXJjZS4KLSAgICogVGhlICJ0YXJnZXRTdGFydCIgYXJndW1lbnQgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gMCBhbmQgbGVzcyB0aGFuIHRoZSBsZW5ndGggb2YgInRhcmdldCIsCi0gICAqIExlbmd0aCBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAwIGFuZCAidGFyZ2V0U3RhcnQgKyBsZW5ndGgiIG11c3QgYmUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIGxlbmd0aCBvZiAidGFyZ2V0Ii4KLSAgICoKLSAgICogQHBhcmFtIHNvdXJjZVN0YXJ0IHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgY2hhcmFjdGVyIGluIHRoZSBzb3VyY2UgYXJyYXkgdG8gY29weQotICAgKiBAcGFyYW0gdGFyZ2V0IHRoZSBkZXN0aW5hdGlvbiBhcnJheQotICAgKiBAcGFyYW0gdGFyZ2V0U3RhcnQgdGhlIHN0YXJ0IG9mZnNldCBpbiB0aGUgdGFyZ2V0IGFycmF5Ci0gICAqIEBwYXJhbSBsZW5ndGggdGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIGNvcHkKLSAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgYWN0dWFsbHkgY29waWVkCi0gICAqIEB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uIGlmIHRoZSB1bmRlcmx5aW5nIFhNTCBzb3VyY2UgaXMgbm90IHdlbGwtZm9ybWVkCi0gICAqIEB0aHJvd3MgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpZiB0YXJnZXRTdGFydCA8IDAgb3IgPiB0aGFuIHRoZSBsZW5ndGggb2YgdGFyZ2V0Ci0gICAqIEB0aHJvd3MgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpZiBsZW5ndGggPCAwIG9yIHRhcmdldFN0YXJ0ICsgbGVuZ3RoID4gbGVuZ3RoIG9mIHRhcmdldAotICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGlmIHRoaXMgbWV0aG9kIGlzIG5vdCBzdXBwb3J0ZWQKLSAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpcyBpZiB0YXJnZXQgaXMgbnVsbAotICAgKi8KLSAgIHB1YmxpYyBpbnQgZ2V0VGV4dENoYXJhY3RlcnMoaW50IHNvdXJjZVN0YXJ0LCBjaGFyW10gdGFyZ2V0LCBpbnQgdGFyZ2V0U3RhcnQsIGludCBsZW5ndGgpCi0gICAgIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb247Ci0KLSAgLyoqCi0gICAqIEdldHMgdGhlIHRleHQgYXNzb2NpYXRlZCB3aXRoIGEgQ0hBUkFDVEVSUywgU1BBQ0Ugb3IgQ0RBVEEgZXZlbnQuICBBbGxvd3MgdGhlIHVuZGVybHlpbmcKLSAgICogaW1wbGVtZW50YXRpb24gdG8gcmV0dXJuIHRoZSB0ZXh0IGFzIGEgc3RyZWFtIG9mIGNoYXJhY3RlcnMuICBUaGUgcmVmZXJlbmNlIHRvIHRoZQotICAgKiBSZWFkZXIgcmV0dXJuZWQgYnkgdGhpcyBtZXRob2QgaXMgb25seSB2YWxpZCB1bnRpbCBuZXh0KCkgaXMgY2FsbGVkLgotICAgKgotICAgKiBBbGwgY2hhcmFjdGVycyBtdXN0IGhhdmUgYmVlbiBjaGVja2VkIGZvciB3ZWxsLWZvcm1lZG5lc3MuCi0gICAqCi0gICAqIDxwPiBUaGlzIG1ldGhvZCBpcyBvcHRpb25hbCBhbmQgd2lsbCB0aHJvdyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBpZiBpdCBpcyBub3Qgc3VwcG9ydGVkLgotICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGlmIHRoaXMgbWV0aG9kIGlzIG5vdCBzdXBwb3J0ZWQKLSAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBpcyBub3QgYSB2YWxpZCB0ZXh0IHN0YXRlCi0gICAqLwotICAvL3B1YmxpYyBSZWFkZXIgZ2V0VGV4dFN0cmVhbSgpOwotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBvZmZzZXQgaW50byB0aGUgdGV4dCBjaGFyYWN0ZXIgYXJyYXkgd2hlcmUgdGhlIGZpcnN0Ci0gICAqIGNoYXJhY3RlciAob2YgdGhpcyB0ZXh0IGV2ZW50KSBpcyBzdG9yZWQuCi0gICAqIEB0aHJvd3MgamF2YS5sYW5nLklsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGlzIHN0YXRlIGlzIG5vdAotICAgKiBhIHZhbGlkIHRleHQgc3RhdGUuCi0gICAqLwotICBwdWJsaWMgaW50IGdldFRleHRTdGFydCgpOwotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBsZW5ndGggb2YgdGhlIHNlcXVlbmNlIG9mIGNoYXJhY3RlcnMgZm9yIHRoaXMKLSAgICogVGV4dCBldmVudCB3aXRoaW4gdGhlIHRleHQgY2hhcmFjdGVyIGFycmF5LgotICAgKiBAdGhyb3dzIGphdmEubGFuZy5JbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBzdGF0ZSBpcyBub3QKLSAgICogYSB2YWxpZCB0ZXh0IHN0YXRlLgotICAgKi8KLSAgcHVibGljIGludCBnZXRUZXh0TGVuZ3RoKCk7Ci0KLSAgLyoqCi0gICAqIFJldHVybiBpbnB1dCBlbmNvZGluZyBpZiBrbm93biBvciBudWxsIGlmIHVua25vd24uCi0gICAqIEByZXR1cm4gdGhlIGVuY29kaW5nIG9mIHRoaXMgaW5zdGFuY2Ugb3IgbnVsbAotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRFbmNvZGluZygpOwotCi0gIC8qKgotICAgKiBSZXR1cm4gdHJ1ZSBpZiB0aGUgY3VycmVudCBldmVudCBoYXMgdGV4dCwgZmFsc2Ugb3RoZXJ3aXNlCi0gICAqIFRoZSBmb2xsb3dpbmcgZXZlbnRzIGhhdmUgdGV4dDoKLSAgICogQ0hBUkFDVEVSUyxEVEQgLEVOVElUWV9SRUZFUkVOQ0UsIENPTU1FTlQsIFNQQUNFCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBoYXNUZXh0KCk7Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgY3VycmVudCBsb2NhdGlvbiBvZiB0aGUgcHJvY2Vzc29yLgotICAgKiBJZiB0aGUgTG9jYXRpb24gaXMgdW5rbm93biB0aGUgcHJvY2Vzc29yIHNob3VsZCByZXR1cm4KLSAgICogYW4gaW1wbGVtZW50YXRpb24gb2YgTG9jYXRpb24gdGhhdCByZXR1cm5zIC0xIGZvciB0aGUKLSAgICogbG9jYXRpb24gYW5kIG51bGwgZm9yIHRoZSBwdWJsaWNJZCBhbmQgc3lzdGVtSWQuCi0gICAqIFRoZSBsb2NhdGlvbiBpbmZvcm1hdGlvbiBpcyBvbmx5IHZhbGlkIHVudGlsIG5leHQoKSBpcwotICAgKiBjYWxsZWQuCi0gICAqLwotICBwdWJsaWMgTG9jYXRpb24gZ2V0TG9jYXRpb24oKTsKLQotICAvKioKLSAgICogUmV0dXJucyBhIFFOYW1lIGZvciB0aGUgY3VycmVudCBTVEFSVF9FTEVNRU5UIG9yIEVORF9FTEVNRU5UIGV2ZW50Ci0gICAqIEByZXR1cm4gdGhlIFFOYW1lIGZvciB0aGUgY3VycmVudCBTVEFSVF9FTEVNRU5UIG9yIEVORF9FTEVNRU5UIGV2ZW50Ci0gICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgaXMgbm90IGEgU1RBUlRfRUxFTUVOVCBvcgotICAgKiBFTkRfRUxFTUVOVAotICAgKi8KLSAgcHVibGljIFFOYW1lIGdldE5hbWUoKTsKLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgKGxvY2FsKSBuYW1lIG9mIHRoZSBjdXJyZW50IGV2ZW50LgotICAgKiBGb3IgU1RBUlRfRUxFTUVOVCBvciBFTkRfRUxFTUVOVCByZXR1cm5zIHRoZSAobG9jYWwpIG5hbWUgb2YgdGhlIGN1cnJlbnQgZWxlbWVudC4KLSAgICogRm9yIEVOVElUWV9SRUZFUkVOQ0UgaXQgcmV0dXJucyBlbnRpdHkgbmFtZS4KLSAgICogVGhlIGN1cnJlbnQgZXZlbnQgbXVzdCBiZSBTVEFSVF9FTEVNRU5UIG9yIEVORF9FTEVNRU5ULAotICAgKiBvciBFTlRJVFlfUkVGRVJFTkNFCi0gICAqIEByZXR1cm4gdGhlIGxvY2FsTmFtZQotICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGlzIG5vdCBhIFNUQVJUX0VMRU1FTlQsCi0gICAqIEVORF9FTEVNRU5UIG9yIEVOVElUWV9SRUZFUkVOQ0UKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0TG9jYWxOYW1lKCk7Ci0KLSAgLyoqCi0gICAqIHJldHVybnMgdHJ1ZSBpZiB0aGUgY3VycmVudCBldmVudCBoYXMgYSBuYW1lIChpcyBhIFNUQVJUX0VMRU1FTlQgb3IgRU5EX0VMRU1FTlQpCi0gICAqIHJldHVybnMgZmFsc2Ugb3RoZXJ3aXNlCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBoYXNOYW1lKCk7Ci0KLSAgLyoqCi0gICAqIElmIHRoZSBjdXJyZW50IGV2ZW50IGlzIGEgU1RBUlRfRUxFTUVOVCBvciBFTkRfRUxFTUVOVCAgdGhpcyBtZXRob2QKLSAgICogcmV0dXJucyB0aGUgVVJJIG9mIHRoZSBwcmVmaXggb3IgdGhlIGRlZmF1bHQgbmFtZXNwYWNlLgotICAgKiBSZXR1cm5zIG51bGwgaWYgdGhlIGV2ZW50IGRvZXMgbm90IGhhdmUgYSBwcmVmaXguCi0gICAqIEByZXR1cm4gdGhlIFVSSSBib3VuZCB0byB0aGlzIGVsZW1lbnRzIHByZWZpeCwgdGhlIGRlZmF1bHQgbmFtZXNwYWNlLCBvciBudWxsCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldE5hbWVzcGFjZVVSSSgpOwotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBwcmVmaXggb2YgdGhlIGN1cnJlbnQgZXZlbnQgb3IgbnVsbCBpZiB0aGUgZXZlbnQgZG9lcyBub3QgaGF2ZSBhIHByZWZpeAotICAgKiBAcmV0dXJuIHRoZSBwcmVmaXggb3IgbnVsbAotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRQcmVmaXgoKTsKLQotICAvKioKLSAgICogR2V0IHRoZSB4bWwgdmVyc2lvbiBkZWNsYXJlZCBvbiB0aGUgeG1sIGRlY2xhcmF0aW9uCi0gICAqIFJldHVybnMgbnVsbCBpZiBub25lIHdhcyBkZWNsYXJlZAotICAgKiBAcmV0dXJuIHRoZSBYTUwgdmVyc2lvbiBvciBudWxsCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFZlcnNpb24oKTsKLQotICAvKioKLSAgICogR2V0IHRoZSBzdGFuZGFsb25lIGRlY2xhcmF0aW9uIGZyb20gdGhlIHhtbCBkZWNsYXJhdGlvbgotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhpcyBpcyBzdGFuZGFsb25lLCBvciBmYWxzZSBvdGhlcndpc2UKLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzU3RhbmRhbG9uZSgpOwotCi0gIC8qKgotICAgKiBDaGVja3MgaWYgc3RhbmRhbG9uZSB3YXMgc2V0IGluIHRoZSBkb2N1bWVudAotICAgKiBAcmV0dXJuIHRydWUgaWYgc3RhbmRhbG9uZSB3YXMgc2V0IGluIHRoZSBkb2N1bWVudCwgb3IgZmFsc2Ugb3RoZXJ3aXNlCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBzdGFuZGFsb25lU2V0KCk7Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIGNoYXJhY3RlciBlbmNvZGluZyBkZWNsYXJlZCBvbiB0aGUgeG1sIGRlY2xhcmF0aW9uCi0gICAqIFJldHVybnMgbnVsbCBpZiBub25lIHdhcyBkZWNsYXJlZAotICAgKiBAcmV0dXJuIHRoZSBlbmNvZGluZyBkZWNsYXJlZCBpbiB0aGUgZG9jdW1lbnQgb3IgbnVsbAotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRDaGFyYWN0ZXJFbmNvZGluZ1NjaGVtZSgpOwotCi0gIC8qKgotICAgKiBHZXQgdGhlIHRhcmdldCBvZiBhIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24KLSAgICogQHJldHVybiB0aGUgdGFyZ2V0IG9yIG51bGwKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0UElUYXJnZXQoKTsKLQotICAvKioKLSAgICogR2V0IHRoZSBkYXRhIHNlY3Rpb24gb2YgYSBwcm9jZXNzaW5nIGluc3RydWN0aW9uCi0gICAqIEByZXR1cm4gdGhlIGRhdGEgb3IgbnVsbAotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRQSURhdGEoKTsKLX0KZGlmZiAtLWdpdCBhL3NyYy9qYXZheC94bWwvc3RyZWFtL1hNTFN0cmVhbVdyaXRlci5qYXZhIGIvc3JjL2phdmF4L3htbC9zdHJlYW0vWE1MU3RyZWFtV3JpdGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGYzNjE1ODkuLjAwMDAwMDAKLS0tIGEvc3JjL2phdmF4L3htbC9zdHJlYW0vWE1MU3RyZWFtV3JpdGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw1MjggKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwOSBieSBPcmFjbGUgQ29ycG9yYXRpb24uIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCi0gKi8KLQotcGFja2FnZSBqYXZheC54bWwuc3RyZWFtOwotCi1pbXBvcnQgamF2YXgueG1sLm5hbWVzcGFjZS5OYW1lc3BhY2VDb250ZXh0OwotCi0vKioKLSAqIFRoZSBYTUxTdHJlYW1Xcml0ZXIgaW50ZXJmYWNlIHNwZWNpZmllcyBob3cgdG8gd3JpdGUgWE1MLiAgVGhlIFhNTFN0cmVhbVdyaXRlciAgZG9lcwotICogbm90IHBlcmZvcm0gd2VsbCBmb3JtZWRuZXNzIGNoZWNraW5nIG9uIGl0cyBpbnB1dC4gIEhvd2V2ZXIKLSAqIHRoZSB3cml0ZUNoYXJhY3RlcnMgbWV0aG9kIGlzIHJlcXVpcmVkIHRvIGVzY2FwZSAmYW1wOyAsICZsdDsgYW5kICZndDsKLSAqIEZvciBhdHRyaWJ1dGUgdmFsdWVzIHRoZSB3cml0ZUF0dHJpYnV0ZSBtZXRob2Qgd2lsbCBlc2NhcGUgdGhlCi0gKiBhYm92ZSBjaGFyYWN0ZXJzIHBsdXMgJnF1b3Q7IHRvIGVuc3VyZSB0aGF0IGFsbCBjaGFyYWN0ZXIgY29udGVudAotICogYW5kIGF0dHJpYnV0ZSB2YWx1ZXMgYXJlIHdlbGwgZm9ybWVkLgotICoKLSAqIEVhY2ggTkFNRVNQQUNFCi0gKiBhbmQgQVRUUklCVVRFIG11c3QgYmUgaW5kaXZpZHVhbGx5IHdyaXR0ZW4uCi0gKgotICogPHRhYmxlIGJvcmRlcj0iMSIgY2VsbHBhZGRpbmc9IjIiIGNlbGxzcGFjaW5nPSIwIj4KLSAqICAgICA8dGhlYWQ+Ci0gKiAgICAgICAgIDx0cj4KLSAqICAgICAgICAgICAgIDx0aCBjb2xzcGFuPSI1Ij5YTUwgTmFtZXNwYWNlcywgPGNvZGU+amF2YXgueG1sLnN0cmVhbS5pc1JlcGFpcmluZ05hbWVzcGFjZXM8L2NvZGU+IGFuZCB3cml0ZSBtZXRob2QgYmVoYXZpb3VyPC90aD4KLSAqICAgICAgICAgPC90cj4KLSAqICAgICAgICAgPHRyPgotICogICAgICAgICAgICAgPHRoPk1ldGhvZDwvdGg+IDwhLS0gbWV0aG9kIC0tPgotICogICAgICAgICAgICAgPHRoIGNvbHNwYW49IjIiPjxjb2RlPmlzUmVwYWlyaW5nTmFtZXNwYWNlczwvY29kZT4gPT0gdHJ1ZTwvdGg+Ci0gKiAgICAgICAgICAgICA8dGggY29sc3Bhbj0iMiI+PGNvZGU+aXNSZXBhaXJpbmdOYW1lc3BhY2VzPC9jb2RlPiA9PSBmYWxzZTwvdGg+Ci0gKiAgICAgICAgIDwvdHI+Ci0gKiAgICAgICAgIDx0cj4KLSAqICAgICAgICAgICAgIDx0aD48L3RoPiA8IS0tIG1ldGhvZCAtLT4KLSAqICAgICAgICAgICAgIDx0aD5uYW1lc3BhY2VVUkkgYm91bmQ8L3RoPgotICogICAgICAgICAgICAgPHRoPm5hbWVzcGFjZVVSSSB1bmJvdW5kPC90aD4KLSAqICAgICAgICAgICAgIDx0aD5uYW1lc3BhY2VVUkkgYm91bmQ8L3RoPgotICogICAgICAgICAgICAgPHRoPm5hbWVzcGFjZVVSSSB1bmJvdW5kPC90aD4KLSAqICAgICAgICAgPC90cj4KLSAqICAgICA8L3RoZWFkPgotICoKLSAqICAgICA8dGJvZHk+Ci0gKiAgICAgICAgIDx0cj4KLSAqICAgICAgICAgICAgIDx0aD48Y29kZT53cml0ZUF0dHJpYnV0ZShuYW1lc3BhY2VVUkksIGxvY2FsTmFtZSwgdmFsdWUpPC9jb2RlPjwvdGg+Ci0gKiAgICAgICAgICAgICA8IS0tIGlzUmVwYWlyaW5nTmFtZXNwYWNlcyA9PSB0cnVlIC0tPgotICogICAgICAgICAgICAgPHRkPgotICogICAgICAgICAgICAgICAgIDwhLS0gbmFtZXNwYWNlVVJJIGJvdW5kIC0tPgotICogICAgICAgICAgICAgICAgIHByZWZpeDpsb2NhbE5hbWU9InZhbHVlIiZuYnNwOzxzdXA+WzFdPC9zdXA+Ci0gKiAgICAgICAgICAgICA8L3RkPgotICogICAgICAgICAgICAgPHRkPgotICogICAgICAgICAgICAgICAgIDwhLS0gbmFtZXNwYWNlVVJJIHVuYm91bmQgLS0+Ci0gKiAgICAgICAgICAgICAgICAgeG1sbnM6e2dlbmVyYXRlZH09Im5hbWVzcGFjZVVSSSIge2dlbmVyYXRlZH06bG9jYWxOYW1lPSJ2YWx1ZSIKLSAqICAgICAgICAgICAgIDwvdGQ+Ci0gKiAgICAgICAgICAgICA8IS0tIGlzUmVwYWlyaW5nTmFtZXNwYWNlcyA9PSBmYWxzZSAtLT4KLSAqICAgICAgICAgICAgIDx0ZD4KLSAqICAgICAgICAgICAgICAgICA8IS0tIG5hbWVzcGFjZVVSSSBib3VuZCAtLT4KLSAqICAgICAgICAgICAgICAgICBwcmVmaXg6bG9jYWxOYW1lPSJ2YWx1ZSImbmJzcDs8c3VwPlsxXTwvc3VwPgotICogICAgICAgICAgICAgPC90ZD4KLSAqICAgICAgICAgICAgIDx0ZD4KLSAqICAgICAgICAgICAgICAgICA8IS0tIG5hbWVzcGFjZVVSSSB1bmJvdW5kIC0tPgotICogICAgICAgICAgICAgICAgIDxjb2RlPlhNTFN0cmVhbUV4Y2VwdGlvbjwvY29kZT4KLSAqICAgICAgICAgICAgIDwvdGQ+Ci0gKiAgICAgICAgIDwvdHI+Ci0gKgotICogICAgICAgICA8dHI+Ci0gKiAgICAgICAgICAgICA8dGg+PGNvZGU+d3JpdGVBdHRyaWJ1dGUocHJlZml4LCBuYW1lc3BhY2VVUkksIGxvY2FsTmFtZSwgdmFsdWUpPC9jb2RlPjwvdGg+Ci0gKiAgICAgICAgICAgICA8IS0tIGlzUmVwYWlyaW5nTmFtZXNwYWNlcyA9PSB0cnVlIC0tPgotICogICAgICAgICAgICAgPHRkPgotICogICAgICAgICAgICAgICAgIDwhLS0gbmFtZXNwYWNlVVJJIGJvdW5kIC0tPgotICogICAgICAgICAgICAgICAgIGJvdW5kIHRvIHNhbWUgcHJlZml4OjxiciAvPgotICogICAgICAgICAgICAgICAgIHByZWZpeDpsb2NhbE5hbWU9InZhbHVlIiZuYnNwOzxzdXA+WzFdPC9zdXA+PGJyIC8+Ci0gKiAgICAgICAgICAgICAgICAgPGJyIC8+Ci0gKiAgICAgICAgICAgICAgICAgYm91bmQgdG8gZGlmZmVyZW50IHByZWZpeDo8YnIgLz4KLSAqICAgICAgICAgICAgICAgICB4bWxuczp7Z2VuZXJhdGVkfT0ibmFtZXNwYWNlVVJJIiB7Z2VuZXJhdGVkfTpsb2NhbE5hbWU9InZhbHVlIgotICogICAgICAgICAgICAgPC90ZD4KLSAqICAgICAgICAgICAgIDx0ZD4KLSAqICAgICAgICAgICAgICAgICA8IS0tIG5hbWVzcGFjZVVSSSB1bmJvdW5kIC0tPgotICogICAgICAgICAgICAgICAgIHhtbG5zOnByZWZpeD0ibmFtZXNwYWNlVVJJIiBwcmVmaXg6bG9jYWxOYW1lPSJ2YWx1ZSImbmJzcDs8c3VwPlszXTwvc3VwPgotICogICAgICAgICAgICAgPC90ZD4KLSAqICAgICAgICAgICAgIDwhLS0gaXNSZXBhaXJpbmdOYW1lc3BhY2VzID09IGZhbHNlIC0tPgotICogICAgICAgICAgICAgPHRkPgotICogICAgICAgICAgICAgICAgIDwhLS0gbmFtZXNwYWNlVVJJIGJvdW5kIC0tPgotICogICAgICAgICAgICAgICAgIGJvdW5kIHRvIHNhbWUgcHJlZml4OjxiciAvPgotICogICAgICAgICAgICAgICAgIHByZWZpeDpsb2NhbE5hbWU9InZhbHVlIiZuYnNwOzxzdXA+WzFdWzJdPC9zdXA+PGJyIC8+Ci0gKiAgICAgICAgICAgICAgICAgPGJyIC8+Ci0gKiAgICAgICAgICAgICAgICAgYm91bmQgdG8gZGlmZmVyZW50IHByZWZpeDo8YnIgLz4KLSAqICAgICAgICAgICAgICAgICA8Y29kZT5YTUxTdHJlYW1FeGNlcHRpb248L2NvZGU+PHN1cD5bMl08L3N1cD4KLSAqICAgICAgICAgICAgIDwvdGQ+Ci0gKiAgICAgICAgICAgICA8dGQ+Ci0gKiAgICAgICAgICAgICAgICAgPCEtLSBuYW1lc3BhY2VVUkkgdW5ib3VuZCAtLT4KLSAqICAgICAgICAgICAgICAgICB4bWxuczpwcmVmaXg9Im5hbWVzcGFjZVVSSSIgcHJlZml4OmxvY2FsTmFtZT0idmFsdWUiJm5ic3A7PHN1cD5bMl1bNV08L3N1cD4KLSAqICAgICAgICAgICAgIDwvdGQ+Ci0gKiAgICAgICAgIDwvdHI+Ci0gKgotICogICAgICAgICA8dHI+Ci0gKiAgICAgICAgICAgICA8dGg+PGNvZGU+d3JpdGVTdGFydEVsZW1lbnQobmFtZXNwYWNlVVJJLCBsb2NhbE5hbWUpPC9jb2RlPjxiciAvPgotICogICAgICAgICAgICAgICAgIDxiciAvPgotICogICAgICAgICAgICAgICAgIDxjb2RlPndyaXRlRW1wdHlFbGVtZW50KG5hbWVzcGFjZVVSSSwgbG9jYWxOYW1lKTwvY29kZT48L3RoPgotICogICAgICAgICAgICAgPCEtLSBpc1JlcGFpcmluZ05hbWVzcGFjZXMgPT0gdHJ1ZSAtLT4KLSAqICAgICAgICAgICAgIDx0ZCA+Ci0gKiAgICAgICAgICAgICAgICAgPCEtLSBuYW1lc3BhY2VVUkkgYm91bmQgLS0+Ci0gKiAgICAgICAgICAgICAgICAgJmx0O3ByZWZpeDpsb2NhbE5hbWUmZ3Q7Jm5ic3A7PHN1cD5bMV08L3N1cD4KLSAqICAgICAgICAgICAgIDwvdGQ+Ci0gKiAgICAgICAgICAgICA8dGQ+Ci0gKiAgICAgICAgICAgICAgICAgPCEtLSBuYW1lc3BhY2VVUkkgdW5ib3VuZCAtLT4KLSAqICAgICAgICAgICAgICAgICAmbHQ7e2dlbmVyYXRlZH06bG9jYWxOYW1lIHhtbG5zOntnZW5lcmF0ZWR9PSJuYW1lc3BhY2VVUkkiJmd0OwotICogICAgICAgICAgICAgPC90ZD4KLSAqICAgICAgICAgICAgIDwhLS0gaXNSZXBhaXJpbmdOYW1lc3BhY2VzID09IGZhbHNlIC0tPgotICogICAgICAgICAgICAgPHRkPgotICogICAgICAgICAgICAgICAgIDwhLS0gbmFtZXNwYWNlVVJJIGJvdW5kIC0tPgotICogICAgICAgICAgICAgICAgICZsdDtwcmVmaXg6bG9jYWxOYW1lJmd0OyZuYnNwOzxzdXA+WzFdPC9zdXA+Ci0gKiAgICAgICAgICAgICA8L3RkPgotICogICAgICAgICAgICAgPHRkPgotICogICAgICAgICAgICAgICAgIDwhLS0gbmFtZXNwYWNlVVJJIHVuYm91bmQgLS0+Ci0gKiAgICAgICAgICAgICAgICAgPGNvZGU+WE1MU3RyZWFtRXhjZXB0aW9uPC9jb2RlPgotICogICAgICAgICAgICAgPC90ZD4KLSAqICAgICAgICAgPC90cj4KLSAqCi0gKiAgICAgICAgIDx0cj4KLSAqICAgICAgICAgICAgIDx0aD48Y29kZT53cml0ZVN0YXJ0RWxlbWVudChwcmVmaXgsIGxvY2FsTmFtZSwgbmFtZXNwYWNlVVJJKTwvY29kZT48YnIgLz4KLSAqICAgICAgICAgICAgICAgICA8YnIgLz4KLSAqICAgICAgICAgICAgICAgICA8Y29kZT53cml0ZUVtcHR5RWxlbWVudChwcmVmaXgsIGxvY2FsTmFtZSwgbmFtZXNwYWNlVVJJKTwvY29kZT48L3RoPgotICogICAgICAgICAgICAgPCEtLSBpc1JlcGFpcmluZ05hbWVzcGFjZXMgPT0gdHJ1ZSAtLT4KLSAqICAgICAgICAgICAgIDx0ZD4KLSAqICAgICAgICAgICAgICAgICA8IS0tIG5hbWVzcGFjZVVSSSBib3VuZCAtLT4KLSAqICAgICAgICAgICAgICAgICBib3VuZCB0byBzYW1lIHByZWZpeDo8YnIgLz4KLSAqICAgICAgICAgICAgICAgICAmbHQ7cHJlZml4OmxvY2FsTmFtZSZndDsmbmJzcDs8c3VwPlsxXTwvc3VwPjxiciAvPgotICogICAgICAgICAgICAgICAgIDxiciAvPgotICogICAgICAgICAgICAgICAgIGJvdW5kIHRvIGRpZmZlcmVudCBwcmVmaXg6PGJyIC8+Ci0gKiAgICAgICAgICAgICAgICAgJmx0O3tnZW5lcmF0ZWR9OmxvY2FsTmFtZSB4bWxuczp7Z2VuZXJhdGVkfT0ibmFtZXNwYWNlVVJJIiZndDsKLSAqICAgICAgICAgICAgIDwvdGQ+Ci0gKiAgICAgICAgICAgICA8dGQ+Ci0gKiAgICAgICAgICAgICAgICAgPCEtLSBuYW1lc3BhY2VVUkkgdW5ib3VuZCAtLT4KLSAqICAgICAgICAgICAgICAgICAmbHQ7cHJlZml4OmxvY2FsTmFtZSB4bWxuczpwcmVmaXg9Im5hbWVzcGFjZVVSSSImZ3Q7Jm5ic3A7PHN1cD5bNF08L3N1cD4KLSAqICAgICAgICAgICAgIDwvdGQ+Ci0gKiAgICAgICAgICAgICA8IS0tIGlzUmVwYWlyaW5nTmFtZXNwYWNlcyA9PSBmYWxzZSAtLT4KLSAqICAgICAgICAgICAgIDx0ZD4KLSAqICAgICAgICAgICAgICAgICA8IS0tIG5hbWVzcGFjZVVSSSBib3VuZCAtLT4KLSAqICAgICAgICAgICAgICAgICBib3VuZCB0byBzYW1lIHByZWZpeDo8YnIgLz4KLSAqICAgICAgICAgICAgICAgICAmbHQ7cHJlZml4OmxvY2FsTmFtZSZndDsmbmJzcDs8c3VwPlsxXTwvc3VwPjxiciAvPgotICogICAgICAgICAgICAgICAgIDxiciAvPgotICogICAgICAgICAgICAgICAgIGJvdW5kIHRvIGRpZmZlcmVudCBwcmVmaXg6PGJyIC8+Ci0gKiAgICAgICAgICAgICAgICAgPGNvZGU+WE1MU3RyZWFtRXhjZXB0aW9uPC9jb2RlPgotICogICAgICAgICAgICAgPC90ZD4KLSAqICAgICAgICAgICAgIDx0ZD4KLSAqICAgICAgICAgICAgICAgICA8IS0tIG5hbWVzcGFjZVVSSSB1bmJvdW5kIC0tPgotICogICAgICAgICAgICAgICAgICZsdDtwcmVmaXg6bG9jYWxOYW1lJmd0OyZuYnNwOwotICogICAgICAgICAgICAgPC90ZD4KLSAqICAgICAgICAgPC90cj4KLSAqICAgICA8L3Rib2R5PgotICogICAgIDx0Zm9vdD4KLSAqICAgICAgICAgPHRyPgotICogICAgICAgICAgICAgPHRkIGNvbHNwYW49IjUiPgotICogICAgICAgICAgICAgICAgIE5vdGVzOgotICogICAgICAgICAgICAgICAgIDx1bD4KLSAqICAgICAgICAgICAgICAgICAgICAgPGxpPlsxXSBpZiBuYW1lc3BhY2VVUkkgPT0gZGVmYXVsdCBOYW1lc3BhY2UgVVJJLCB0aGVuIG5vIHByZWZpeCBpcyB3cml0dGVuPC9saT4KLSAqICAgICAgICAgICAgICAgICAgICAgPGxpPlsyXSBpZiBwcmVmaXggPT0gIiIgfHwgbnVsbCAmJiBuYW1lc3BhY2VVUkkgPT0gIiIsIHRoZW4gbm8gcHJlZml4IG9yIE5hbWVzcGFjZSBkZWNsYXJhdGlvbiBpcyBnZW5lcmF0ZWQgb3Igd3JpdHRlbjwvbGk+Ci0gKiAgICAgICAgICAgICAgICAgICAgIDxsaT5bM10gaWYgcHJlZml4ID09ICIiIHx8IG51bGwsIHRoZW4gYSBwcmVmaXggaXMgcmFuZG9tbHkgZ2VuZXJhdGVkPC9saT4KLSAqICAgICAgICAgICAgICAgICAgICAgPGxpPls0XSBpZiBwcmVmaXggPT0gIiIgfHwgbnVsbCwgdGhlbiBpdCBpcyB0cmVhdGVkIGFzIHRoZSBkZWZhdWx0IE5hbWVzcGFjZSBhbmQgbm8gcHJlZml4IGlzIGdlbmVyYXRlZCBvciB3cml0dGVuLCBhbiB4bWxucyBkZWNsYXJhdGlvbiBpcyBnZW5lcmF0ZWQgYW5kIHdyaXR0ZW4gaWYgdGhlIG5hbWVzcGFjZVVSSSBpcyB1bmJvdW5kPC9saT4KLSAqICAgICAgICAgICAgICAgICAgICAgPGxpPls1XSBpZiBwcmVmaXggPT0gIiIgfHwgbnVsbCwgdGhlbiBpdCBpcyB0cmVhdGVkIGFzIGFuIGludmFsaWQgYXR0ZW1wdCB0byBkZWZpbmUgdGhlIGRlZmF1bHQgTmFtZXNwYWNlIGFuZCBhbiBYTUxTdHJlYW1FeGNlcHRpb24gaXMgdGhyb3duPC9saT4KLSAqICAgICAgICAgICAgICAgICA8L3VsPgotICogICAgICAgICAgICAgPC90ZD4KLSAqICAgICAgICAgPC90cj4KLSAqICAgICA8L3Rmb290PgotICogPC90YWJsZT4KLSAqCi0gKiBAdmVyc2lvbiAxLjAKLSAqIEBhdXRob3IgQ29weXJpZ2h0IChjKSAyMDA5IGJ5IE9yYWNsZSBDb3Jwb3JhdGlvbi4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KLSAqIEBzZWUgWE1MT3V0cHV0RmFjdG9yeQotICogQHNlZSBYTUxTdHJlYW1SZWFkZXIKLSAqIEBzaW5jZSAxLjYKLSAqLwotcHVibGljIGludGVyZmFjZSBYTUxTdHJlYW1Xcml0ZXIgewotCi0gIC8qKgotICAgKiBXcml0ZXMgYSBzdGFydCB0YWcgdG8gdGhlIG91dHB1dC4gIEFsbCB3cml0ZVN0YXJ0RWxlbWVudCBtZXRob2RzCi0gICAqIG9wZW4gYSBuZXcgc2NvcGUgaW4gdGhlIGludGVybmFsIG5hbWVzcGFjZSBjb250ZXh0LiAgV3JpdGluZyB0aGUKLSAgICogY29ycmVzcG9uZGluZyBFbmRFbGVtZW50IGNhdXNlcyB0aGUgc2NvcGUgdG8gYmUgY2xvc2VkLgotICAgKiBAcGFyYW0gbG9jYWxOYW1lIGxvY2FsIG5hbWUgb2YgdGhlIHRhZywgbWF5IG5vdCBiZSBudWxsCi0gICAqIEB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCB3cml0ZVN0YXJ0RWxlbWVudChTdHJpbmcgbG9jYWxOYW1lKQotICAgIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb247Ci0KLSAgLyoqCi0gICAqIFdyaXRlcyBhIHN0YXJ0IHRhZyB0byB0aGUgb3V0cHV0Ci0gICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkgdGhlIG5hbWVzcGFjZVVSSSBvZiB0aGUgcHJlZml4IHRvIHVzZSwgbWF5IG5vdCBiZSBudWxsCi0gICAqIEBwYXJhbSBsb2NhbE5hbWUgbG9jYWwgbmFtZSBvZiB0aGUgdGFnLCBtYXkgbm90IGJlIG51bGwKLSAgICogQHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24gaWYgdGhlIG5hbWVzcGFjZSBVUkkgaGFzIG5vdCBiZWVuIGJvdW5kIHRvIGEgcHJlZml4IGFuZAotICAgKiBqYXZheC54bWwuc3RyZWFtLmlzUmVwYWlyaW5nTmFtZXNwYWNlcyBoYXMgbm90IGJlZW4gc2V0IHRvIHRydWUKLSAgICovCi0gIHB1YmxpYyB2b2lkIHdyaXRlU3RhcnRFbGVtZW50KFN0cmluZyBuYW1lc3BhY2VVUkksIFN0cmluZyBsb2NhbE5hbWUpCi0gICAgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbjsKLQotICAvKioKLSAgICogV3JpdGVzIGEgc3RhcnQgdGFnIHRvIHRoZSBvdXRwdXQKLSAgICogQHBhcmFtIGxvY2FsTmFtZSBsb2NhbCBuYW1lIG9mIHRoZSB0YWcsIG1heSBub3QgYmUgbnVsbAotICAgKiBAcGFyYW0gcHJlZml4IHRoZSBwcmVmaXggb2YgdGhlIHRhZywgbWF5IG5vdCBiZSBudWxsCi0gICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkgdGhlIHVyaSB0byBiaW5kIHRoZSBwcmVmaXggdG8sIG1heSBub3QgYmUgbnVsbAotICAgKiBAdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgd3JpdGVTdGFydEVsZW1lbnQoU3RyaW5nIHByZWZpeCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGxvY2FsTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSkKLSAgICB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uOwotCi0gIC8qKgotICAgKiBXcml0ZXMgYW4gZW1wdHkgZWxlbWVudCB0YWcgdG8gdGhlIG91dHB1dAotICAgKiBAcGFyYW0gbmFtZXNwYWNlVVJJIHRoZSB1cmkgdG8gYmluZCB0aGUgdGFnIHRvLCBtYXkgbm90IGJlIG51bGwKLSAgICogQHBhcmFtIGxvY2FsTmFtZSBsb2NhbCBuYW1lIG9mIHRoZSB0YWcsIG1heSBub3QgYmUgbnVsbAotICAgKiBAdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbiBpZiB0aGUgbmFtZXNwYWNlIFVSSSBoYXMgbm90IGJlZW4gYm91bmQgdG8gYSBwcmVmaXggYW5kCi0gICAqIGphdmF4LnhtbC5zdHJlYW0uaXNSZXBhaXJpbmdOYW1lc3BhY2VzIGhhcyBub3QgYmVlbiBzZXQgdG8gdHJ1ZQotICAgKi8KLSAgcHVibGljIHZvaWQgd3JpdGVFbXB0eUVsZW1lbnQoU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIGxvY2FsTmFtZSkKLSAgICB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uOwotCi0gIC8qKgotICAgKiBXcml0ZXMgYW4gZW1wdHkgZWxlbWVudCB0YWcgdG8gdGhlIG91dHB1dAotICAgKiBAcGFyYW0gcHJlZml4IHRoZSBwcmVmaXggb2YgdGhlIHRhZywgbWF5IG5vdCBiZSBudWxsCi0gICAqIEBwYXJhbSBsb2NhbE5hbWUgbG9jYWwgbmFtZSBvZiB0aGUgdGFnLCBtYXkgbm90IGJlIG51bGwKLSAgICogQHBhcmFtIG5hbWVzcGFjZVVSSSB0aGUgdXJpIHRvIGJpbmQgdGhlIHRhZyB0bywgbWF5IG5vdCBiZSBudWxsCi0gICAqIEB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCB3cml0ZUVtcHR5RWxlbWVudChTdHJpbmcgcHJlZml4LCBTdHJpbmcgbG9jYWxOYW1lLCBTdHJpbmcgbmFtZXNwYWNlVVJJKQotICAgIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb247Ci0KLSAgLyoqCi0gICAqIFdyaXRlcyBhbiBlbXB0eSBlbGVtZW50IHRhZyB0byB0aGUgb3V0cHV0Ci0gICAqIEBwYXJhbSBsb2NhbE5hbWUgbG9jYWwgbmFtZSBvZiB0aGUgdGFnLCBtYXkgbm90IGJlIG51bGwKLSAgICogQHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHdyaXRlRW1wdHlFbGVtZW50KFN0cmluZyBsb2NhbE5hbWUpCi0gICAgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbjsKLQotICAvKioKLSAgICogV3JpdGVzIHN0cmluZyBkYXRhIHRvIHRoZSBvdXRwdXQgd2l0aG91dCBjaGVja2luZyBmb3Igd2VsbCBmb3JtZWRuZXNzLgotICAgKiBUaGUgZGF0YSBpcyBvcGFxdWUgdG8gdGhlIFhNTFN0cmVhbVdyaXRlciwgaS5lLiB0aGUgY2hhcmFjdGVycyBhcmUgd3JpdHRlbgotICAgKiBibGluZGx5IHRvIHRoZSB1bmRlcmx5aW5nIG91dHB1dC4gIElmIHRoZSBtZXRob2QgY2Fubm90IGJlIHN1cHBvcnRlZAotICAgKiBpbiB0aGUgY3VycnJlbnQgd3JpdGluZyBjb250ZXh0IHRoZSBpbXBsZW1lbnRhdGlvbiBtYXkgdGhyb3cgYQotICAgKiBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbi4gIEZvciBleGFtcGxlIG5vdGUgdGhhdCBhbnkKLSAgICogbmFtZXNwYWNlIGRlY2xhcmF0aW9ucywgZW5kIHRhZ3MsIGV0Yy4gd2lsbCBiZSBpZ25vcmVkIGFuZCBjb3VsZAotICAgKiBpbnRlcmZlcmUgd2l0aCBwcm9wZXIgbWFpbnRhbmVuY2Ugb2YgdGhlIHdyaXRlcnMgaW50ZXJuYWwgc3RhdGUuCi0gICAqCi0gICAqIEBwYXJhbSBkYXRhIHRoZSBkYXRhIHRvIHdyaXRlCi0gICAqLwotICAvLyAgcHVibGljIHZvaWQgd3JpdGVSYXcoU3RyaW5nIGRhdGEpIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb247Ci0KLSAgLyoqCi0gICAqIFdyaXRlcyBhbiBlbmQgdGFnIHRvIHRoZSBvdXRwdXQgcmVseWluZyBvbiB0aGUgaW50ZXJuYWwKLSAgICogc3RhdGUgb2YgdGhlIHdyaXRlciB0byBkZXRlcm1pbmUgdGhlIHByZWZpeCBhbmQgbG9jYWwgbmFtZQotICAgKiBvZiB0aGUgZXZlbnQuCi0gICAqIEB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCB3cml0ZUVuZEVsZW1lbnQoKQotICAgIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb247Ci0KLSAgLyoqCi0gICAqIENsb3NlcyBhbnkgc3RhcnQgdGFncyBhbmQgd3JpdGVzIGNvcnJlc3BvbmRpbmcgZW5kIHRhZ3MuCi0gICAqIEB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCB3cml0ZUVuZERvY3VtZW50KCkKLSAgICB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uOwotCi0gIC8qKgotICAgKiBDbG9zZSB0aGlzIHdyaXRlciBhbmQgZnJlZSBhbnkgcmVzb3VyY2VzIGFzc29jaWF0ZWQgd2l0aCB0aGUKLSAgICogd3JpdGVyLiAgVGhpcyBtdXN0IG5vdCBjbG9zZSB0aGUgdW5kZXJseWluZyBvdXRwdXQgc3RyZWFtLgotICAgKiBAdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgY2xvc2UoKQotICAgIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb247Ci0KLSAgLyoqCi0gICAqIFdyaXRlIGFueSBjYWNoZWQgZGF0YSB0byB0aGUgdW5kZXJseWluZyBvdXRwdXQgbWVjaGFuaXNtLgotICAgKiBAdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgZmx1c2goKQotICAgIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb247Ci0KLSAgLyoqCi0gICAqIFdyaXRlcyBhbiBhdHRyaWJ1dGUgdG8gdGhlIG91dHB1dCBzdHJlYW0gd2l0aG91dAotICAgKiBhIHByZWZpeC4KLSAgICogQHBhcmFtIGxvY2FsTmFtZSB0aGUgbG9jYWwgbmFtZSBvZiB0aGUgYXR0cmlidXRlCi0gICAqIEBwYXJhbSB2YWx1ZSB0aGUgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZQotICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGUgY3VycmVudCBzdGF0ZSBkb2VzIG5vdCBhbGxvdyBBdHRyaWJ1dGUgd3JpdGluZwotICAgKiBAdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgd3JpdGVBdHRyaWJ1dGUoU3RyaW5nIGxvY2FsTmFtZSwgU3RyaW5nIHZhbHVlKQotICAgIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb247Ci0KLSAgLyoqCi0gICAqIFdyaXRlcyBhbiBhdHRyaWJ1dGUgdG8gdGhlIG91dHB1dCBzdHJlYW0KLSAgICogQHBhcmFtIHByZWZpeCB0aGUgcHJlZml4IGZvciB0aGlzIGF0dHJpYnV0ZQotICAgKiBAcGFyYW0gbmFtZXNwYWNlVVJJIHRoZSB1cmkgb2YgdGhlIHByZWZpeCBmb3IgdGhpcyBhdHRyaWJ1dGUKLSAgICogQHBhcmFtIGxvY2FsTmFtZSB0aGUgbG9jYWwgbmFtZSBvZiB0aGUgYXR0cmlidXRlCi0gICAqIEBwYXJhbSB2YWx1ZSB0aGUgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZQotICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGUgY3VycmVudCBzdGF0ZSBkb2VzIG5vdCBhbGxvdyBBdHRyaWJ1dGUgd3JpdGluZwotICAgKiBAdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbiBpZiB0aGUgbmFtZXNwYWNlIFVSSSBoYXMgbm90IGJlZW4gYm91bmQgdG8gYSBwcmVmaXggYW5kCi0gICAqIGphdmF4LnhtbC5zdHJlYW0uaXNSZXBhaXJpbmdOYW1lc3BhY2VzIGhhcyBub3QgYmVlbiBzZXQgdG8gdHJ1ZQotICAgKi8KLQotICBwdWJsaWMgdm9pZCB3cml0ZUF0dHJpYnV0ZShTdHJpbmcgcHJlZml4LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbmFtZXNwYWNlVVJJLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbG9jYWxOYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdmFsdWUpCi0gICAgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbjsKLQotICAvKioKLSAgICogV3JpdGVzIGFuIGF0dHJpYnV0ZSB0byB0aGUgb3V0cHV0IHN0cmVhbQotICAgKiBAcGFyYW0gbmFtZXNwYWNlVVJJIHRoZSB1cmkgb2YgdGhlIHByZWZpeCBmb3IgdGhpcyBhdHRyaWJ1dGUKLSAgICogQHBhcmFtIGxvY2FsTmFtZSB0aGUgbG9jYWwgbmFtZSBvZiB0aGUgYXR0cmlidXRlCi0gICAqIEBwYXJhbSB2YWx1ZSB0aGUgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZQotICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGUgY3VycmVudCBzdGF0ZSBkb2VzIG5vdCBhbGxvdyBBdHRyaWJ1dGUgd3JpdGluZwotICAgKiBAdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbiBpZiB0aGUgbmFtZXNwYWNlIFVSSSBoYXMgbm90IGJlZW4gYm91bmQgdG8gYSBwcmVmaXggYW5kCi0gICAqIGphdmF4LnhtbC5zdHJlYW0uaXNSZXBhaXJpbmdOYW1lc3BhY2VzIGhhcyBub3QgYmVlbiBzZXQgdG8gdHJ1ZQotICAgKi8KLSAgcHVibGljIHZvaWQgd3JpdGVBdHRyaWJ1dGUoU3RyaW5nIG5hbWVzcGFjZVVSSSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGxvY2FsTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHZhbHVlKQotICAgIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb247Ci0KLSAgLyoqCi0gICAqIFdyaXRlcyBhIG5hbWVzcGFjZSB0byB0aGUgb3V0cHV0IHN0cmVhbQotICAgKiBJZiB0aGUgcHJlZml4IGFyZ3VtZW50IHRvIHRoaXMgbWV0aG9kIGlzIHRoZSBlbXB0eSBzdHJpbmcsCi0gICAqICJ4bWxucyIsIG9yIG51bGwgdGhpcyBtZXRob2Qgd2lsbCBkZWxlZ2F0ZSB0byB3cml0ZURlZmF1bHROYW1lc3BhY2UKLSAgICoKLSAgICogQHBhcmFtIHByZWZpeCB0aGUgcHJlZml4IHRvIGJpbmQgdGhpcyBuYW1lc3BhY2UgdG8KLSAgICogQHBhcmFtIG5hbWVzcGFjZVVSSSB0aGUgdXJpIHRvIGJpbmQgdGhlIHByZWZpeCB0bwotICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGUgY3VycmVudCBzdGF0ZSBkb2VzIG5vdCBhbGxvdyBOYW1lc3BhY2Ugd3JpdGluZwotICAgKiBAdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgd3JpdGVOYW1lc3BhY2UoU3RyaW5nIHByZWZpeCwgU3RyaW5nIG5hbWVzcGFjZVVSSSkKLSAgICB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uOwotCi0gIC8qKgotICAgKiBXcml0ZXMgdGhlIGRlZmF1bHQgbmFtZXNwYWNlIHRvIHRoZSBzdHJlYW0KLSAgICogQHBhcmFtIG5hbWVzcGFjZVVSSSB0aGUgdXJpIHRvIGJpbmQgdGhlIGRlZmF1bHQgbmFtZXNwYWNlIHRvCi0gICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoZSBjdXJyZW50IHN0YXRlIGRvZXMgbm90IGFsbG93IE5hbWVzcGFjZSB3cml0aW5nCi0gICAqIEB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCB3cml0ZURlZmF1bHROYW1lc3BhY2UoU3RyaW5nIG5hbWVzcGFjZVVSSSkKLSAgICB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uOwotCi0gIC8qKgotICAgKiBXcml0ZXMgYW4geG1sIGNvbW1lbnQgd2l0aCB0aGUgZGF0YSBlbmNsb3NlZAotICAgKiBAcGFyYW0gZGF0YSB0aGUgZGF0YSBjb250YWluZWQgaW4gdGhlIGNvbW1lbnQsIG1heSBiZSBudWxsCi0gICAqIEB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCB3cml0ZUNvbW1lbnQoU3RyaW5nIGRhdGEpCi0gICAgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbjsKLQotICAvKioKLSAgICogV3JpdGVzIGEgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbgotICAgKiBAcGFyYW0gdGFyZ2V0IHRoZSB0YXJnZXQgb2YgdGhlIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24sIG1heSBub3QgYmUgbnVsbAotICAgKiBAdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgd3JpdGVQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oU3RyaW5nIHRhcmdldCkKLSAgICB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uOwotCi0gIC8qKgotICAgKiBXcml0ZXMgYSBwcm9jZXNzaW5nIGluc3RydWN0aW9uCi0gICAqIEBwYXJhbSB0YXJnZXQgdGhlIHRhcmdldCBvZiB0aGUgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiwgbWF5IG5vdCBiZSBudWxsCi0gICAqIEBwYXJhbSBkYXRhIHRoZSBkYXRhIGNvbnRhaW5lZCBpbiB0aGUgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiwgbWF5IG5vdCBiZSBudWxsCi0gICAqIEB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCB3cml0ZVByb2Nlc3NpbmdJbnN0cnVjdGlvbihTdHJpbmcgdGFyZ2V0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgZGF0YSkKLSAgICB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uOwotCi0gIC8qKgotICAgKiBXcml0ZXMgYSBDRGF0YSBzZWN0aW9uCi0gICAqIEBwYXJhbSBkYXRhIHRoZSBkYXRhIGNvbnRhaW5lZCBpbiB0aGUgQ0RhdGEgU2VjdGlvbiwgbWF5IG5vdCBiZSBudWxsCi0gICAqIEB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCB3cml0ZUNEYXRhKFN0cmluZyBkYXRhKQotICAgIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb247Ci0KLSAgLyoqCi0gICAqIFdyaXRlIGEgRFREIHNlY3Rpb24uICBUaGlzIHN0cmluZyByZXByZXNlbnRzIHRoZSBlbnRpcmUgZG9jdHlwZWRlY2wgcHJvZHVjdGlvbgotICAgKiBmcm9tIHRoZSBYTUwgMS4wIHNwZWNpZmljYXRpb24uCi0gICAqCi0gICAqIEBwYXJhbSBkdGQgdGhlIERURCB0byBiZSB3cml0dGVuCi0gICAqIEB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCB3cml0ZURURChTdHJpbmcgZHRkKQotICAgIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb247Ci0KLSAgLyoqCi0gICAqIFdyaXRlcyBhbiBlbnRpdHkgcmVmZXJlbmNlCi0gICAqIEBwYXJhbSBuYW1lIHRoZSBuYW1lIG9mIHRoZSBlbnRpdHkKLSAgICogQHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHdyaXRlRW50aXR5UmVmKFN0cmluZyBuYW1lKQotICAgIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb247Ci0KLSAgLyoqCi0gICAqIFdyaXRlIHRoZSBYTUwgRGVjbGFyYXRpb24uIERlZmF1bHRzIHRoZSBYTUwgdmVyc2lvbiB0byAxLjAsIGFuZCB0aGUgZW5jb2RpbmcgdG8gdXRmLTgKLSAgICogQHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHdyaXRlU3RhcnREb2N1bWVudCgpCi0gICAgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbjsKLQotICAvKioKLSAgICogV3JpdGUgdGhlIFhNTCBEZWNsYXJhdGlvbi4gRGVmYXVsdHMgdGhlIFhNTCB2ZXJzaW9uIHRvIDEuMAotICAgKiBAcGFyYW0gdmVyc2lvbiB2ZXJzaW9uIG9mIHRoZSB4bWwgZG9jdW1lbnQKLSAgICogQHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHdyaXRlU3RhcnREb2N1bWVudChTdHJpbmcgdmVyc2lvbikKLSAgICB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uOwotCi0gIC8qKgotICAgKiBXcml0ZSB0aGUgWE1MIERlY2xhcmF0aW9uLiAgTm90ZSB0aGF0IHRoZSBlbmNvZGluZyBwYXJhbWV0ZXIgZG9lcwotICAgKiBub3Qgc2V0IHRoZSBhY3R1YWwgZW5jb2Rpbmcgb2YgdGhlIHVuZGVybHlpbmcgb3V0cHV0LiAgVGhhdCBtdXN0Ci0gICAqIGJlIHNldCB3aGVuIHRoZSBpbnN0YW5jZSBvZiB0aGUgWE1MU3RyZWFtV3JpdGVyIGlzIGNyZWF0ZWQgdXNpbmcgdGhlCi0gICAqIFhNTE91dHB1dEZhY3RvcnkKLSAgICogQHBhcmFtIGVuY29kaW5nIGVuY29kaW5nIG9mIHRoZSB4bWwgZGVjbGFyYXRpb24KLSAgICogQHBhcmFtIHZlcnNpb24gdmVyc2lvbiBvZiB0aGUgeG1sIGRvY3VtZW50Ci0gICAqIEB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uIElmIGdpdmVuIGVuY29kaW5nIGRvZXMgbm90IG1hdGNoIGVuY29kaW5nCi0gICAqIG9mIHRoZSB1bmRlcmx5aW5nIHN0cmVhbQotICAgKi8KLSAgcHVibGljIHZvaWQgd3JpdGVTdGFydERvY3VtZW50KFN0cmluZyBlbmNvZGluZywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyB2ZXJzaW9uKQotICAgIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb247Ci0KLSAgLyoqCi0gICAqIFdyaXRlIHRleHQgdG8gdGhlIG91dHB1dAotICAgKiBAcGFyYW0gdGV4dCB0aGUgdmFsdWUgdG8gd3JpdGUKLSAgICogQHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHdyaXRlQ2hhcmFjdGVycyhTdHJpbmcgdGV4dCkKLSAgICB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uOwotCi0gIC8qKgotICAgKiBXcml0ZSB0ZXh0IHRvIHRoZSBvdXRwdXQKLSAgICogQHBhcmFtIHRleHQgdGhlIHZhbHVlIHRvIHdyaXRlCi0gICAqIEBwYXJhbSBzdGFydCB0aGUgc3RhcnRpbmcgcG9zaXRpb24gaW4gdGhlIGFycmF5Ci0gICAqIEBwYXJhbSBsZW4gdGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHdyaXRlCi0gICAqIEB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCB3cml0ZUNoYXJhY3RlcnMoY2hhcltdIHRleHQsIGludCBzdGFydCwgaW50IGxlbikKLSAgICB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uOwotCi0gIC8qKgotICAgKiBHZXRzIHRoZSBwcmVmaXggdGhlIHVyaSBpcyBib3VuZCB0bwotICAgKiBAcmV0dXJuIHRoZSBwcmVmaXggb3IgbnVsbAotICAgKiBAdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRQcmVmaXgoU3RyaW5nIHVyaSkKLSAgICB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uOwotCi0gIC8qKgotICAgKiBTZXRzIHRoZSBwcmVmaXggdGhlIHVyaSBpcyBib3VuZCB0by4gIFRoaXMgcHJlZml4IGlzIGJvdW5kCi0gICAqIGluIHRoZSBzY29wZSBvZiB0aGUgY3VycmVudCBTVEFSVF9FTEVNRU5UIC8gRU5EX0VMRU1FTlQgcGFpci4KLSAgICogSWYgdGhpcyBtZXRob2QgaXMgY2FsbGVkIGJlZm9yZSBhIFNUQVJUX0VMRU1FTlQgaGFzIGJlZW4gd3JpdHRlbgotICAgKiB0aGUgcHJlZml4IGlzIGJvdW5kIGluIHRoZSByb290IHNjb3BlLgotICAgKiBAcGFyYW0gcHJlZml4IHRoZSBwcmVmaXggdG8gYmluZCB0byB0aGUgdXJpLCBtYXkgbm90IGJlIG51bGwKLSAgICogQHBhcmFtIHVyaSB0aGUgdXJpIHRvIGJpbmQgdG8gdGhlIHByZWZpeCwgbWF5IGJlIG51bGwKLSAgICogQHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFByZWZpeChTdHJpbmcgcHJlZml4LCBTdHJpbmcgdXJpKQotICAgIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb247Ci0KLQotICAvKioKLSAgICogQmluZHMgYSBVUkkgdG8gdGhlIGRlZmF1bHQgbmFtZXNwYWNlCi0gICAqIFRoaXMgVVJJIGlzIGJvdW5kCi0gICAqIGluIHRoZSBzY29wZSBvZiB0aGUgY3VycmVudCBTVEFSVF9FTEVNRU5UIC8gRU5EX0VMRU1FTlQgcGFpci4KLSAgICogSWYgdGhpcyBtZXRob2QgaXMgY2FsbGVkIGJlZm9yZSBhIFNUQVJUX0VMRU1FTlQgaGFzIGJlZW4gd3JpdHRlbgotICAgKiB0aGUgdXJpIGlzIGJvdW5kIGluIHRoZSByb290IHNjb3BlLgotICAgKiBAcGFyYW0gdXJpIHRoZSB1cmkgdG8gYmluZCB0byB0aGUgZGVmYXVsdCBuYW1lc3BhY2UsIG1heSBiZSBudWxsCi0gICAqIEB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXREZWZhdWx0TmFtZXNwYWNlKFN0cmluZyB1cmkpCi0gICAgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbjsKLQotICAvKioKLSAgICogU2V0cyB0aGUgY3VycmVudCBuYW1lc3BhY2UgY29udGV4dCBmb3IgcHJlZml4IGFuZCB1cmkgYmluZGluZ3MuCi0gICAqIFRoaXMgY29udGV4dCBiZWNvbWVzIHRoZSByb290IG5hbWVzcGFjZSBjb250ZXh0IGZvciB3cml0aW5nIGFuZAotICAgKiB3aWxsIHJlcGxhY2UgdGhlIGN1cnJlbnQgcm9vdCBuYW1lc3BhY2UgY29udGV4dC4gIFN1YnNlcXVlbnQgY2FsbHMKLSAgICogdG8gc2V0UHJlZml4IGFuZCBzZXREZWZhdWx0TmFtZXNwYWNlIHdpbGwgYmluZCBuYW1lc3BhY2VzIHVzaW5nCi0gICAqIHRoZSBjb250ZXh0IHBhc3NlZCB0byB0aGUgbWV0aG9kIGFzIHRoZSByb290IGNvbnRleHQgZm9yIHJlc29sdmluZwotICAgKiBuYW1lc3BhY2VzLiAgVGhpcyBtZXRob2QgbWF5IG9ubHkgYmUgY2FsbGVkIG9uY2UgYXQgdGhlIHN0YXJ0IG9mCi0gICAqIHRoZSBkb2N1bWVudC4gIEl0IGRvZXMgbm90IGNhdXNlIHRoZSBuYW1lc3BhY2VzIHRvIGJlIGRlY2xhcmVkLgotICAgKiBJZiBhIG5hbWVzcGFjZSBVUkkgdG8gcHJlZml4IG1hcHBpbmcgaXMgZm91bmQgaW4gdGhlIG5hbWVzcGFjZQotICAgKiBjb250ZXh0IGl0IGlzIHRyZWF0ZWQgYXMgZGVjbGFyZWQgYW5kIHRoZSBwcmVmaXggbWF5IGJlIHVzZWQKLSAgICogYnkgdGhlIFN0cmVhbVdyaXRlci4KLSAgICogQHBhcmFtIGNvbnRleHQgdGhlIG5hbWVzcGFjZSBjb250ZXh0IHRvIHVzZSBmb3IgdGhpcyB3cml0ZXIsIG1heSBub3QgYmUgbnVsbAotICAgKiBAdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0TmFtZXNwYWNlQ29udGV4dChOYW1lc3BhY2VDb250ZXh0IGNvbnRleHQpCi0gICAgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbjsKLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgY3VycmVudCBuYW1lc3BhY2UgY29udGV4dC4KLSAgICogQHJldHVybiB0aGUgY3VycmVudCBOYW1lc3BhY2VDb250ZXh0Ci0gICAqLwotICBwdWJsaWMgTmFtZXNwYWNlQ29udGV4dCBnZXROYW1lc3BhY2VDb250ZXh0KCk7Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgdmFsdWUgb2YgYSBmZWF0dXJlL3Byb3BlcnR5IGZyb20gdGhlIHVuZGVybHlpbmcgaW1wbGVtZW50YXRpb24KLSAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIHByb3BlcnR5LCBtYXkgbm90IGJlIG51bGwKLSAgICogQHJldHVybiBUaGUgdmFsdWUgb2YgdGhlIHByb3BlcnR5Ci0gICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSBwcm9wZXJ0eSBpcyBub3Qgc3VwcG9ydGVkCi0gICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIG5hbWUgaXMgbnVsbAotICAgKi8KLSAgcHVibGljIE9iamVjdCBnZXRQcm9wZXJ0eShqYXZhLmxhbmcuU3RyaW5nIG5hbWUpIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb247Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9qYXZheC94bWwvc3RyZWFtL2V2ZW50cy9BdHRyaWJ1dGUuamF2YSBiL3NyYy9qYXZheC94bWwvc3RyZWFtL2V2ZW50cy9BdHRyaWJ1dGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMjQ4ZDA2MC4uMDAwMDAwMAotLS0gYS9zcmMvamF2YXgveG1sL3N0cmVhbS9ldmVudHMvQXR0cmlidXRlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw2OSArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogQ29weXJpZ2h0IChjKSAyMDA5IGJ5IE9yYWNsZSBDb3Jwb3JhdGlvbi4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KLSAqLwotCi1wYWNrYWdlIGphdmF4LnhtbC5zdHJlYW0uZXZlbnRzOwotCi1pbXBvcnQgamF2YXgueG1sLm5hbWVzcGFjZS5RTmFtZTsKLQotLyoqCi0gKiBBbiBpbnRlcmZhY2UgdGhhdCBjb250YWlucyBpbmZvcm1hdGlvbiBhYm91dCBhbiBhdHRyaWJ1dGUuICBBdHRyaWJ1dGVzIGFyZSByZXBvcnRlZAotICogYXMgYSBzZXQgb2YgZXZlbnRzIGFjY2Vzc2libGUgZnJvbSBhIFN0YXJ0RWxlbWVudC4gIE90aGVyIGFwcGxpY2F0aW9ucyBtYXkgcmVwb3J0Ci0gKiBBdHRyaWJ1dGVzIGFzIGZpcnN0LW9yZGVyIGV2ZW50cywgZm9yIGV4YW1wbGUgYXMgdGhlIHJlc3VsdHMgb2YgYW4gWFBhdGggZXhwcmVzc2lvbi4KLSAqCi0gKiBAdmVyc2lvbiAxLjAKLSAqIEBhdXRob3IgQ29weXJpZ2h0IChjKSAyMDA5IGJ5IE9yYWNsZSBDb3Jwb3JhdGlvbi4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KLSAqIEBzZWUgU3RhcnRFbGVtZW50Ci0gKiBAc2luY2UgMS42Ci0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgQXR0cmlidXRlIGV4dGVuZHMgWE1MRXZlbnQgewotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBRTmFtZSBmb3IgdGhpcyBhdHRyaWJ1dGUKLSAgICovCi0gIFFOYW1lIGdldE5hbWUoKTsKLQotICAvKioKLSAgICogR2V0cyB0aGUgbm9ybWFsaXplZCB2YWx1ZSBvZiB0aGlzIGF0dHJpYnV0ZQotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRWYWx1ZSgpOwotCi0gIC8qKgotICAgKiBHZXRzIHRoZSB0eXBlIG9mIHRoaXMgYXR0cmlidXRlLCBkZWZhdWx0IGlzCi0gICAqIHRoZSBTdHJpbmcgIkNEQVRBIgotICAgKiBAcmV0dXJuIHRoZSB0eXBlIGFzIGEgU3RyaW5nLCBkZWZhdWx0IGlzICJDREFUQSIKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0RFREVHlwZSgpOwotCi0gIC8qKgotICAgKiBBIGZsYWcgaW5kaWNhdGluZyB3aGV0aGVyIHRoaXMgYXR0cmlidXRlIHdhcyBhY3R1YWxseQotICAgKiBzcGVjaWZpZWQgaW4gdGhlIHN0YXJ0LXRhZyBvZiBpdHMgZWxlbWVudCwgb3Igd2FzIGRlZmF1bHRlZCBmcm9tIHRoZSBzY2hlbWEuCi0gICAqIEByZXR1cm4gcmV0dXJucyB0cnVlIGlmIHRoaXMgd2FzIHNwZWNpZmllZCBpbiB0aGUgc3RhcnQgZWxlbWVudAotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNTcGVjaWZpZWQoKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmF4L3htbC9zdHJlYW0vZXZlbnRzL0NoYXJhY3RlcnMuamF2YSBiL3NyYy9qYXZheC94bWwvc3RyZWFtL2V2ZW50cy9DaGFyYWN0ZXJzLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDc2ZGFiN2YuLjAwMDAwMDAKLS0tIGEvc3JjL2phdmF4L3htbC9zdHJlYW0vZXZlbnRzL0NoYXJhY3RlcnMuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDc2ICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDkgYnkgT3JhY2xlIENvcnBvcmF0aW9uLiBBbGwgUmlnaHRzIFJlc2VydmVkLgotICovCi0KLXBhY2thZ2UgamF2YXgueG1sLnN0cmVhbS5ldmVudHM7Ci0KLS8qKgotICogVGhpcyBkZXNjcmliZXMgdGhlIGludGVyZmFjZSB0byBDaGFyYWN0ZXJzIGV2ZW50cy4KLSAqIEFsbCB0ZXh0IGV2ZW50cyBnZXQgcmVwb3J0ZWQgYXMgQ2hhcmFjdGVycyBldmVudHMuCi0gKiBDb250ZW50LCBDRGF0YSBhbmQgd2hpdGVzcGFjZSBhcmUgYWxsIHJlcG9ydGVkIGFzCi0gKiBDaGFyYWN0ZXJzIGV2ZW50cy4gIElnbm9yYWJsZVdoaXRlc3BhY2UsIGluIG1vc3QgY2FzZXMsCi0gKiB3aWxsIGJlIHNldCB0byBmYWxzZSB1bmxlc3MgYW4gZWxlbWVudCBkZWNsYXJhdGlvbiBvZiBlbGVtZW50Ci0gKiBjb250ZW50IGlzIHByZXNlbnQgZm9yIHRoZSBjdXJyZW50IGVsZW1lbnQuCi0gKgotICogQHZlcnNpb24gMS4wCi0gKiBAYXV0aG9yIENvcHlyaWdodCAoYykgMjAwOSBieSBPcmFjbGUgQ29ycG9yYXRpb24uIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCi0gKiBAc2luY2UgMS42Ci0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgQ2hhcmFjdGVycyBleHRlbmRzIFhNTEV2ZW50IHsKLSAgLyoqCi0gICAqIEdldCB0aGUgY2hhcmFjdGVyIGRhdGEgb2YgdGhpcyBldmVudAotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXREYXRhKCk7Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdHJ1ZSBpZiB0aGlzIHNldCBvZiBDaGFyYWN0ZXJzCi0gICAqIGlzIGFsbCB3aGl0ZXNwYWNlLiAgV2hpdGVzcGFjZSBpbnNpZGUgYSBkb2N1bWVudAotICAgKiBpcyByZXBvcnRlZCBhcyBDSEFSQUNURVJTLiAgVGhpcyBtZXRob2QgYWxsb3dzCi0gICAqIGNoZWNraW5nIG9mIENIQVJBQ1RFUlMgZXZlbnRzIHRvIHNlZSBpZiB0aGV5Ci0gICAqIGFyZSBjb21wb3NlZCBvZiBvbmx5IHdoaXRlc3BhY2UgY2hhcmFjdGVycwotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNXaGl0ZVNwYWNlKCk7Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdHJ1ZSBpZiB0aGlzIGlzIGEgQ0RhdGEgc2VjdGlvbi4gIElmIHRoaXMKLSAgICogZXZlbnQgaXMgQ0RhdGEgaXRzIGV2ZW50IHR5cGUgd2lsbCBiZSBDREFUQQotICAgKgotICAgKiBJZiBqYXZheC54bWwuc3RyZWFtLmlzQ29hbGVzY2luZyBpcyBzZXQgdG8gdHJ1ZSBDREFUQSBTZWN0aW9ucwotICAgKiB0aGF0IGFyZSBzdXJyb3VuZGVkIGJ5IG5vbiBDREFUQSBjaGFyYWN0ZXJzIHdpbGwgYmUgcmVwb3J0ZWQKLSAgICogYXMgYSBzaW5nbGUgQ2hhcmFjdGVycyBldmVudC4gVGhpcyBtZXRob2Qgd2lsbCByZXR1cm4gZmFsc2UKLSAgICogaW4gdGhpcyBjYXNlLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNDRGF0YSgpOwotCi0gIC8qKgotICAgKiBSZXR1cm4gdHJ1ZSBpZiB0aGlzIGlzIGlnbm9yYWJsZVdoaXRlU3BhY2UuICBJZgotICAgKiB0aGlzIGV2ZW50IGlzIGlnbm9yYWJsZVdoaXRlU3BhY2UgaXRzIGV2ZW50IHR5cGUgd2lsbAotICAgKiBiZSBTUEFDRS4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzSWdub3JhYmxlV2hpdGVTcGFjZSgpOwotCi19CmRpZmYgLS1naXQgYS9zcmMvamF2YXgveG1sL3N0cmVhbS9ldmVudHMvQ29tbWVudC5qYXZhIGIvc3JjL2phdmF4L3htbC9zdHJlYW0vZXZlbnRzL0NvbW1lbnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOGVkMDkyOS4uMDAwMDAwMAotLS0gYS9zcmMvamF2YXgveG1sL3N0cmVhbS9ldmVudHMvQ29tbWVudC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDUgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwOSBieSBPcmFjbGUgQ29ycG9yYXRpb24uIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCi0gKi8KLQotcGFja2FnZSBqYXZheC54bWwuc3RyZWFtLmV2ZW50czsKLQotLyoqCi0gKiBBbiBpbnRlcmZhY2UgZm9yIGNvbW1lbnQgZXZlbnRzCi0gKgotICogQHZlcnNpb24gMS4wCi0gKiBAYXV0aG9yIENvcHlyaWdodCAoYykgMjAwOSBieSBPcmFjbGUgQ29ycG9yYXRpb24uIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCi0gKiBAc2luY2UgMS42Ci0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgQ29tbWVudCBleHRlbmRzIFhNTEV2ZW50IHsKLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBzdHJpbmcgZGF0YSBvZiB0aGUgY29tbWVudCwgcmV0dXJucyBlbXB0eSBzdHJpbmcgaWYgaXQKLSAgICogZG9lcyBub3QgZXhpc3QKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0VGV4dCgpOwotfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmF4L3htbC9zdHJlYW0vZXZlbnRzL0RURC5qYXZhIGIvc3JjL2phdmF4L3htbC9zdHJlYW0vZXZlbnRzL0RURC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzYjBiYjlmLi4wMDAwMDAwCi0tLSBhL3NyYy9qYXZheC94bWwvc3RyZWFtL2V2ZW50cy9EVEQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDc0ICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDkgYnkgT3JhY2xlIENvcnBvcmF0aW9uLiBBbGwgUmlnaHRzIFJlc2VydmVkLgotICovCi0KLXBhY2thZ2UgamF2YXgueG1sLnN0cmVhbS5ldmVudHM7Ci0KLWltcG9ydCBqYXZhLnV0aWwuTGlzdDsKLQotLyoqCi0gKiBUaGlzIGlzIHRoZSB0b3AgbGV2ZWwgaW50ZXJmYWNlIGZvciBldmVudHMgZGVhbGluZyB3aXRoIERURHMKLSAqCi0gKiBAdmVyc2lvbiAxLjAKLSAqIEBhdXRob3IgQ29weXJpZ2h0IChjKSAyMDA5IGJ5IE9yYWNsZSBDb3Jwb3JhdGlvbi4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KLSAqIEBzaW5jZSAxLjYKLSAqLwotcHVibGljIGludGVyZmFjZSBEVEQgZXh0ZW5kcyBYTUxFdmVudCB7Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIGVudGlyZSBEb2N1bWVudCBUeXBlIERlY2xhcmF0aW9uIGFzIGEgc3RyaW5nLCBpbmNsdWRpbmcKLSAgICogdGhlIGludGVybmFsIERURCBzdWJzZXQuCi0gICAqIFRoaXMgbWF5IGJlIG51bGwgaWYgdGhlcmUgaXMgbm90IGFuIGludGVybmFsIHN1YnNldC4KLSAgICogSWYgaXQgaXMgbm90IG51bGwgaXQgbXVzdCByZXR1cm4gdGhlIGVudGlyZQotICAgKiBEb2N1bWVudCBUeXBlIERlY2xhcmF0aW9uIHdoaWNoIG1hdGNoZXMgdGhlIGRvY3R5cGVkZWNsCi0gICAqIHByb2R1Y3Rpb24gaW4gdGhlIFhNTCAxLjAgc3BlY2lmaWNhdGlvbgotICAgKi8KLSAgU3RyaW5nIGdldERvY3VtZW50VHlwZURlY2xhcmF0aW9uKCk7Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgYW4gaW1wbGVtZW50YXRpb24gZGVmaW5lZCByZXByZXNlbnRhdGlvbiBvZiB0aGUgRFRELgotICAgKiBUaGlzIG1ldGhvZCBtYXkgcmV0dXJuIG51bGwgaWYgbm8gcmVwcmVzZW50YXRpb24gaXMgYXZhaWxhYmxlLgotICAgKi8KLSAgT2JqZWN0IGdldFByb2Nlc3NlZERURCgpOwotCi0gIC8qKgotICAgKiBSZXR1cm4gYSBMaXN0IGNvbnRhaW5pbmcgdGhlIG5vdGF0aW9ucyBkZWNsYXJlZCBpbiB0aGUgRFRELgotICAgKiBUaGlzIGxpc3QgbXVzdCBjb250YWluIE5vdGF0aW9uRGVjbGFyYXRpb24gZXZlbnRzLgotICAgKiBAc2VlIE5vdGF0aW9uRGVjbGFyYXRpb24KLSAgICogQHJldHVybiBhbiB1bm9yZGVyZWQgbGlzdCBvZiBOb3RhdGlvbkRlY2xhcmF0aW9uIGV2ZW50cwotICAgKi8KLSAgTGlzdCBnZXROb3RhdGlvbnMoKTsKLQotICAvKioKLSAgICogUmV0dXJuIGEgTGlzdCBjb250YWluaW5nIHRoZSBnZW5lcmFsIGVudGl0aWVzLAotICAgKiBib3RoIGV4dGVybmFsIGFuZCBpbnRlcm5hbCwgZGVjbGFyZWQgaW4gdGhlIERURC4KLSAgICogVGhpcyBsaXN0IG11c3QgY29udGFpbiBFbnRpdHlEZWNsYXJhdGlvbiBldmVudHMuCi0gICAqIEBzZWUgRW50aXR5RGVjbGFyYXRpb24KLSAgICogQHJldHVybiBhbiB1bm9yZGVyZWQgbGlzdCBvZiBFbnRpdHlEZWNsYXJhdGlvbiBldmVudHMKLSAgICovCi0gIExpc3QgZ2V0RW50aXRpZXMoKTsKLX0KZGlmZiAtLWdpdCBhL3NyYy9qYXZheC94bWwvc3RyZWFtL2V2ZW50cy9FbmREb2N1bWVudC5qYXZhIGIvc3JjL2phdmF4L3htbC9zdHJlYW0vZXZlbnRzL0VuZERvY3VtZW50LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDBlN2FiMzEuLjAwMDAwMDAKLS0tIGEvc3JjL2phdmF4L3htbC9zdHJlYW0vZXZlbnRzL0VuZERvY3VtZW50LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0MiArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogQ29weXJpZ2h0IChjKSAyMDA5IGJ5IE9yYWNsZSBDb3Jwb3JhdGlvbi4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KLSAqLwotCi1wYWNrYWdlIGphdmF4LnhtbC5zdHJlYW0uZXZlbnRzOwotCi0vKioKLSAqIEEgbWFya2VyIGludGVyZmFjZSBmb3IgdGhlIGVuZCBvZiB0aGUgZG9jdW1lbnQKLSAqCi0gKiBAdmVyc2lvbiAxLjAKLSAqIEBhdXRob3IgQ29weXJpZ2h0IChjKSAyMDA5IGJ5IE9yYWNsZSBDb3Jwb3JhdGlvbi4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KLSAqIEBzaW5jZSAxLjYKLSAqLwotcHVibGljIGludGVyZmFjZSBFbmREb2N1bWVudCBleHRlbmRzIFhNTEV2ZW50IHsKLSAgLyoqCi0gICAqIE5vIG1ldGhvZHMgYXJlIGRlZmluZWQgaW4gdGhpcyBpbnRlcmZhY2UuCi0gICAqLwotfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmF4L3htbC9zdHJlYW0vZXZlbnRzL0VuZEVsZW1lbnQuamF2YSBiL3NyYy9qYXZheC94bWwvc3RyZWFtL2V2ZW50cy9FbmRFbGVtZW50LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGZkNmQ1ZjIuLjAwMDAwMDAKLS0tIGEvc3JjL2phdmF4L3htbC9zdHJlYW0vZXZlbnRzL0VuZEVsZW1lbnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDU5ICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDkgYnkgT3JhY2xlIENvcnBvcmF0aW9uLiBBbGwgUmlnaHRzIFJlc2VydmVkLgotICovCi0KLXBhY2thZ2UgamF2YXgueG1sLnN0cmVhbS5ldmVudHM7Ci0KLWltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7Ci1pbXBvcnQgamF2YXgueG1sLm5hbWVzcGFjZS5RTmFtZTsKLS8qKgotICogQW4gaW50ZXJmYWNlIGZvciB0aGUgZW5kIGVsZW1lbnQgZXZlbnQuICBBbiBFbmRFbGVtZW50IGlzIHJlcG9ydGVkCi0gKiBmb3IgZWFjaCBFbmQgVGFnIGluIHRoZSBkb2N1bWVudC4KLSAqCi0gKiBAdmVyc2lvbiAxLjAKLSAqIEBhdXRob3IgQ29weXJpZ2h0IChjKSAyMDA5IGJ5IE9yYWNsZSBDb3Jwb3JhdGlvbi4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KLSAqIEBzZWUgWE1MRXZlbnQKLSAqIEBzaW5jZSAxLjYKLSAqLwotcHVibGljIGludGVyZmFjZSBFbmRFbGVtZW50IGV4dGVuZHMgWE1MRXZlbnQgewotCi0gIC8qKgotICAgKiBHZXQgdGhlIG5hbWUgb2YgdGhpcyBldmVudAotICAgKiBAcmV0dXJuIHRoZSBxdWFsaWZpZWQgbmFtZSBvZiB0aGlzIGV2ZW50Ci0gICAqLwotICBwdWJsaWMgUU5hbWUgZ2V0TmFtZSgpOwotCi0gIC8qKgotICAgKiBSZXR1cm5zIGFuIEl0ZXJhdG9yIG9mIG5hbWVzcGFjZXMgdGhhdCBoYXZlIGdvbmUgb3V0Ci0gICAqIG9mIHNjb3BlLiAgUmV0dXJucyBhbiBlbXB0eSBpdGVyYXRvciBpZiBubyBuYW1lc3BhY2VzIGhhdmUgZ29uZQotICAgKiBvdXQgb2Ygc2NvcGUuCi0gICAqIEByZXR1cm4gYW4gSXRlcmF0b3Igb3ZlciBOYW1lc3BhY2UgaW50ZXJmYWNlcywgb3IgYW4KLSAgICogZW1wdHkgaXRlcmF0b3IKLSAgICovCi0gIHB1YmxpYyBJdGVyYXRvciBnZXROYW1lc3BhY2VzKCk7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9qYXZheC94bWwvc3RyZWFtL2V2ZW50cy9FbnRpdHlEZWNsYXJhdGlvbi5qYXZhIGIvc3JjL2phdmF4L3htbC9zdHJlYW0vZXZlbnRzL0VudGl0eURlY2xhcmF0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDc0NjEwZGEuLjAwMDAwMDAKLS0tIGEvc3JjL2phdmF4L3htbC9zdHJlYW0vZXZlbnRzL0VudGl0eURlY2xhcmF0aW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4MCArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogQ29weXJpZ2h0IChjKSAyMDA5IGJ5IE9yYWNsZSBDb3Jwb3JhdGlvbi4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KLSAqLwotCi1wYWNrYWdlIGphdmF4LnhtbC5zdHJlYW0uZXZlbnRzOwotLyoqCi0gKiBBbiBpbnRlcmZhY2UgZm9yIGhhbmRsaW5nIEVudGl0eSBEZWNsYXJhdGlvbnMKLSAqCi0gKiBUaGlzIGludGVyZmFjZSBpcyB1c2VkIHRvIHJlY29yZCBhbmQgcmVwb3J0IHVucGFyc2VkIGVudGl0eSBkZWNsYXJhdGlvbnMuCi0gKgotICogQHZlcnNpb24gMS4wCi0gKiBAYXV0aG9yIENvcHlyaWdodCAoYykgMjAwOSBieSBPcmFjbGUgQ29ycG9yYXRpb24uIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCi0gKiBAc2luY2UgMS42Ci0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgRW50aXR5RGVjbGFyYXRpb24gZXh0ZW5kcyBYTUxFdmVudCB7Ci0KLSAgLyoqCi0gICAqIFRoZSBlbnRpdHkncyBwdWJsaWMgaWRlbnRpZmllciwgb3IgbnVsbCBpZiBub25lIHdhcyBnaXZlbgotICAgKiBAcmV0dXJuIHRoZSBwdWJsaWMgSUQgZm9yIHRoaXMgZGVjbGFyYXRpb24gb3IgbnVsbAotICAgKi8KLSAgU3RyaW5nIGdldFB1YmxpY0lkKCk7Ci0KLSAgLyoqCi0gICAqIFRoZSBlbnRpdHkncyBzeXN0ZW0gaWRlbnRpZmllci4KLSAgICogQHJldHVybiB0aGUgc3lzdGVtIElEIGZvciB0aGlzIGRlY2xhcmF0aW9uIG9yIG51bGwKLSAgICovCi0gIFN0cmluZyBnZXRTeXN0ZW1JZCgpOwotCi0gIC8qKgotICAgKiBUaGUgZW50aXR5J3MgbmFtZQotICAgKiBAcmV0dXJuIHRoZSBuYW1lLCBtYXkgbm90IGJlIG51bGwKLSAgICovCi0gIFN0cmluZyBnZXROYW1lKCk7Ci0KLSAgLyoqCi0gICAqIFRoZSBuYW1lIG9mIHRoZSBhc3NvY2lhdGVkIG5vdGF0aW9uLgotICAgKiBAcmV0dXJuIHRoZSBub3RhdGlvbiBuYW1lCi0gICAqLwotICBTdHJpbmcgZ2V0Tm90YXRpb25OYW1lKCk7Ci0KLSAgLyoqCi0gICAqIFRoZSByZXBsYWNlbWVudCB0ZXh0IG9mIHRoZSBlbnRpdHkuCi0gICAqIFRoaXMgbWV0aG9kIHdpbGwgb25seSByZXR1cm4gbm9uLW51bGwKLSAgICogaWYgdGhpcyBpcyBhbiBpbnRlcm5hbCBlbnRpdHkuCi0gICAqIEByZXR1cm4gbnVsbCBvciB0aGUgcmVwbGFjbWVudCB0ZXh0Ci0gICAqLwotICBTdHJpbmcgZ2V0UmVwbGFjZW1lbnRUZXh0KCk7Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgYmFzZSBVUkkgZm9yIHRoaXMgcmVmZXJlbmNlCi0gICAqIG9yIG51bGwgaWYgdGhpcyBpbmZvcm1hdGlvbiBpcyBub3QgYXZhaWxhYmxlCi0gICAqIEByZXR1cm4gdGhlIGJhc2UgVVJJIG9yIG51bGwKLSAgICovCi0gIFN0cmluZyBnZXRCYXNlVVJJKCk7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9qYXZheC94bWwvc3RyZWFtL2V2ZW50cy9FbnRpdHlSZWZlcmVuY2UuamF2YSBiL3NyYy9qYXZheC94bWwvc3RyZWFtL2V2ZW50cy9FbnRpdHlSZWZlcmVuY2UuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggODg3MTQ2MC4uMDAwMDAwMAotLS0gYS9zcmMvamF2YXgveG1sL3N0cmVhbS9ldmVudHMvRW50aXR5UmVmZXJlbmNlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw2MiArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogQ29weXJpZ2h0IChjKSAyMDA5IGJ5IE9yYWNsZSBDb3Jwb3JhdGlvbi4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KLSAqLwotCi1wYWNrYWdlIGphdmF4LnhtbC5zdHJlYW0uZXZlbnRzOwotLyoqCi0gKiBBbiBpbnRlcmZhY2UgZm9yIGhhbmRsaW5nIEVudGl0eSBldmVudHMuCi0gKgotICogVGhpcyBldmVudCByZXBvcnRzIGVudGl0aWVzIHRoYXQgaGF2ZSBub3QgYmVlbiByZXNvbHZlZAotICogYW5kIHJlcG9ydHMgdGhlaXIgcmVwbGFjZW1lbnQgdGV4dCB1bnByb2Nlc3NlZCAoaWYKLSAqIGF2YWlsYWJsZSkuICBUaGlzIGV2ZW50IHdpbGwgYmUgcmVwb3J0ZWQgaWYgamF2YXgueG1sLnN0cmVhbS5pc1JlcGxhY2luZ0VudGl0eVJlZmVyZW5jZXMKLSAqIGlzIHNldCB0byBmYWxzZS4gIElmIGphdmF4LnhtbC5zdHJlYW0uaXNSZXBsYWNpbmdFbnRpdHlSZWZlcmVuY2VzIGlzIHNldCB0byB0cnVlCi0gKiBlbnRpdHkgcmVmZXJlbmNlcyB3aWxsIGJlIHJlc29sdmVkIHRyYW5zcGFyZW50bHkuCi0gKgotICogRW50aXRpZXMgYXJlIGhhbmRsZWQgaW4gdHdvIHBvc3NpYmxlIHdheXM6Ci0gKgotICogKDEpIElmIGphdmF4LnhtbC5zdHJlYW0uaXNSZXBsYWNpbmdFbnRpdHlSZWZlcmVuY2VzIGlzIHNldCB0byB0cnVlCi0gKiBhbGwgZW50aXR5IHJlZmVyZW5jZXMgYXJlIHJlc29sdmVkIGFuZCByZXBvcnRlZCBhcyBtYXJrdXAgdHJhbnNwYXJlbnRseS4KLSAqICgyKSBJZiBqYXZheC54bWwuc3RyZWFtLmlzUmVwbGFjaW5nRW50aXR5UmVmZXJlbmNlcyBpcyBzZXQgdG8gZmFsc2UKLSAqIEVudGl0eSByZWZlcmVuY2VzIGFyZSByZXBvcnRlZCBhcyBhbiBFbnRpdHlSZWZlcmVuY2UgRXZlbnQuCi0gKgotICogQHZlcnNpb24gMS4wCi0gKiBAYXV0aG9yIENvcHlyaWdodCAoYykgMjAwOSBieSBPcmFjbGUgQ29ycG9yYXRpb24uIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCi0gKiBAc2luY2UgMS42Ci0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgRW50aXR5UmVmZXJlbmNlIGV4dGVuZHMgWE1MRXZlbnQgewotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIGRlY2xhcmF0aW9uIG9mIHRoaXMgZW50aXR5LgotICAgKi8KLSAgRW50aXR5RGVjbGFyYXRpb24gZ2V0RGVjbGFyYXRpb24oKTsKLQotICAvKioKLSAgICogVGhlIG5hbWUgb2YgdGhlIGVudGl0eQotICAgKiBAcmV0dXJuIHRoZSBlbnRpdHkncyBuYW1lLCBtYXkgbm90IGJlIG51bGwKLSAgICovCi0gIFN0cmluZyBnZXROYW1lKCk7Ci19CmRpZmYgLS1naXQgYS9zcmMvamF2YXgveG1sL3N0cmVhbS9ldmVudHMvTmFtZXNwYWNlLmphdmEgYi9zcmMvamF2YXgveG1sL3N0cmVhbS9ldmVudHMvTmFtZXNwYWNlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGRmNWU2YmQuLjAwMDAwMDAKLS0tIGEvc3JjL2phdmF4L3htbC9zdHJlYW0vZXZlbnRzL05hbWVzcGFjZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTkgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwOSBieSBPcmFjbGUgQ29ycG9yYXRpb24uIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCi0gKi8KLQotcGFja2FnZSBqYXZheC54bWwuc3RyZWFtLmV2ZW50czsKLQotaW1wb3J0IGphdmF4LnhtbC5uYW1lc3BhY2UuUU5hbWU7Ci0KLS8qKgotICogQW4gaW50ZXJmYWNlIHRoYXQgY29udGFpbnMgaW5mb3JtYXRpb24gYWJvdXQgYSBuYW1lc3BhY2UuCi0gKiBOYW1lc3BhY2VzIGFyZSBhY2Nlc3NlZCBmcm9tIGEgU3RhcnRFbGVtZW50LgotICoKLSAqIEB2ZXJzaW9uIDEuMAotICogQGF1dGhvciBDb3B5cmlnaHQgKGMpIDIwMDkgYnkgT3JhY2xlIENvcnBvcmF0aW9uLiBBbGwgUmlnaHRzIFJlc2VydmVkLgotICogQHNlZSBTdGFydEVsZW1lbnQKLSAqIEBzaW5jZSAxLjYKLSAqLwotcHVibGljIGludGVyZmFjZSBOYW1lc3BhY2UgZXh0ZW5kcyBBdHRyaWJ1dGUgewotCi0gIC8qKgotICAgKiBHZXRzIHRoZSBwcmVmaXgsIHJldHVybnMgIiIgaWYgdGhpcyBpcyBhIGRlZmF1bHQKLSAgICogbmFtZXNwYWNlIGRlY2xhcmF0aW9uLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRQcmVmaXgoKTsKLQotICAvKioKLSAgICogR2V0cyB0aGUgdXJpIGJvdW5kIHRvIHRoZSBwcmVmaXggb2YgdGhpcyBuYW1lc3BhY2UKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZXNwYWNlVVJJKCk7Ci0KLSAgLyoqCi0gICAqIHJldHVybnMgdHJ1ZSBpZiB0aGlzIGF0dHJpYnV0ZSBkZWNsYXJlcyB0aGUgZGVmYXVsdCBuYW1lc3BhY2UKLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzRGVmYXVsdE5hbWVzcGFjZURlY2xhcmF0aW9uKCk7Ci19CmRpZmYgLS1naXQgYS9zcmMvamF2YXgveG1sL3N0cmVhbS9ldmVudHMvTm90YXRpb25EZWNsYXJhdGlvbi5qYXZhIGIvc3JjL2phdmF4L3htbC9zdHJlYW0vZXZlbnRzL05vdGF0aW9uRGVjbGFyYXRpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZmM1Zjc5MC4uMDAwMDAwMAotLS0gYS9zcmMvamF2YXgveG1sL3N0cmVhbS9ldmVudHMvTm90YXRpb25EZWNsYXJhdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTggKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwOSBieSBPcmFjbGUgQ29ycG9yYXRpb24uIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCi0gKi8KLQotcGFja2FnZSBqYXZheC54bWwuc3RyZWFtLmV2ZW50czsKLS8qKgotICogQW4gaW50ZXJmYWNlIGZvciBoYW5kbGluZyBOb3RhdGlvbiBEZWNsYXJhdGlvbnMKLSAqCi0gKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBhIG5vdGF0aW9uIGRlY2xhcmF0aW9uIGV2ZW50LgotICogSXQgaXMgdXAgdG8gdGhlIGFwcGxpY2F0aW9uIHRvIHJlY29yZCB0aGUgbm90YXRpb24gZm9yIGxhdGVyIHJlZmVyZW5jZSwKLSAqIEF0IGxlYXN0IG9uZSBvZiBwdWJsaWNJZCBhbmQgc3lzdGVtSWQgbXVzdCBiZSBub24tbnVsbC4KLSAqIFRoZXJlIGlzIG5vIGd1YXJhbnRlZSB0aGF0IHRoZSBub3RhdGlvbiBkZWNsYXJhdGlvbgotICogd2lsbCBiZSByZXBvcnRlZCBiZWZvcmUgYW55IHVucGFyc2VkIGVudGl0aWVzIHRoYXQgdXNlIGl0LgotICoKLSAqIEB2ZXJzaW9uIDEuMAotICogQGF1dGhvciBDb3B5cmlnaHQgKGMpIDIwMDkgYnkgT3JhY2xlIENvcnBvcmF0aW9uLiBBbGwgUmlnaHRzIFJlc2VydmVkLgotICogQHNpbmNlIDEuNgotICovCi1wdWJsaWMgaW50ZXJmYWNlIE5vdGF0aW9uRGVjbGFyYXRpb24gZXh0ZW5kcyBYTUxFdmVudCB7Ci0gIC8qKgotICAgKiBUaGUgbm90YXRpb24gbmFtZS4KLSAgICovCi0gIFN0cmluZyBnZXROYW1lKCk7Ci0KLSAgLyoqCi0gICAqIFRoZSBub3RhdGlvbidzIHB1YmxpYyBpZGVudGlmaWVyLCBvciBudWxsIGlmIG5vbmUgd2FzIGdpdmVuLgotICAgKi8KLSAgU3RyaW5nIGdldFB1YmxpY0lkKCk7Ci0KLSAgLyoqCi0gICAqIFRoZSBub3RhdGlvbidzIHN5c3RlbSBpZGVudGlmaWVyLCBvciBudWxsIGlmIG5vbmUgd2FzIGdpdmVuLgotICAgKi8KLSAgU3RyaW5nIGdldFN5c3RlbUlkKCk7Ci19CmRpZmYgLS1naXQgYS9zcmMvamF2YXgveG1sL3N0cmVhbS9ldmVudHMvUHJvY2Vzc2luZ0luc3RydWN0aW9uLmphdmEgYi9zcmMvamF2YXgveG1sL3N0cmVhbS9ldmVudHMvUHJvY2Vzc2luZ0luc3RydWN0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDllZTc3ZDguLjAwMDAwMDAKLS0tIGEvc3JjL2phdmF4L3htbC9zdHJlYW0vZXZlbnRzL1Byb2Nlc3NpbmdJbnN0cnVjdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTIgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwOSBieSBPcmFjbGUgQ29ycG9yYXRpb24uIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCi0gKi8KLQotcGFja2FnZSBqYXZheC54bWwuc3RyZWFtLmV2ZW50czsKLS8qKgotICogQW4gaW50ZXJmYWNlIHRoYXQgZGVzY3JpYmVzIHRoZSBkYXRhIGZvdW5kIGluIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb25zCi0gKgotICogQHZlcnNpb24gMS4wCi0gKiBAYXV0aG9yIENvcHlyaWdodCAoYykgMjAwOSBieSBPcmFjbGUgQ29ycG9yYXRpb24uIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCi0gKiBAc2luY2UgMS42Ci0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgUHJvY2Vzc2luZ0luc3RydWN0aW9uIGV4dGVuZHMgWE1MRXZlbnQgewotCi0gIC8qKgotICAgKiBUaGUgdGFyZ2V0IHNlY3Rpb24gb2YgdGhlIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24KLSAgICoKLSAgICogQHJldHVybiB0aGUgU3RyaW5nIHZhbHVlIG9mIHRoZSBQSSBvciBudWxsCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldCgpOwotCi0gIC8qKgotICAgKiBUaGUgZGF0YSBzZWN0aW9uIG9mIHRoZSBwcm9jZXNzaW5nIGluc3RydWN0aW9uCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIFN0cmluZyB2YWx1ZSBvZiB0aGUgUEkncyBkYXRhIG9yIG51bGwKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0RGF0YSgpOwotfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmF4L3htbC9zdHJlYW0vZXZlbnRzL1N0YXJ0RG9jdW1lbnQuamF2YSBiL3NyYy9qYXZheC94bWwvc3RyZWFtL2V2ZW50cy9TdGFydERvY3VtZW50LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGQ0NmMwNzAuLjAwMDAwMDAKLS0tIGEvc3JjL2phdmF4L3htbC9zdHJlYW0vZXZlbnRzL1N0YXJ0RG9jdW1lbnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDc0ICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDkgYnkgT3JhY2xlIENvcnBvcmF0aW9uLiBBbGwgUmlnaHRzIFJlc2VydmVkLgotICovCi0KLXBhY2thZ2UgamF2YXgueG1sLnN0cmVhbS5ldmVudHM7Ci0vKioKLSAqIEFuIGludGVyZmFjZSBmb3IgdGhlIHN0YXJ0IGRvY3VtZW50IGV2ZW50Ci0gKgotICogQHZlcnNpb24gMS4wCi0gKiBAYXV0aG9yIENvcHlyaWdodCAoYykgMjAwOSBieSBPcmFjbGUgQ29ycG9yYXRpb24uIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCi0gKiBAc2luY2UgMS42Ci0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgU3RhcnREb2N1bWVudCBleHRlbmRzIFhNTEV2ZW50IHsKLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgc3lzdGVtIElEIG9mIHRoZSBYTUwgZGF0YQotICAgKiBAcmV0dXJuIHRoZSBzeXN0ZW0gSUQsIGRlZmF1bHRzIHRvICIiCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFN5c3RlbUlkKCk7Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIGVuY29kaW5nIHN0eWxlIG9mIHRoZSBYTUwgZGF0YQotICAgKiBAcmV0dXJuIHRoZSBjaGFyYWN0ZXIgZW5jb2RpbmcsIGRlZmF1bHRzIHRvICJVVEYtOCIKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0Q2hhcmFjdGVyRW5jb2RpbmdTY2hlbWUoKTsKLQotICAvKioKLSAgICogUmV0dXJucyB0cnVlIGlmIENoYXJhY3RlckVuY29kaW5nU2NoZW1lIHdhcyBzZXQgaW4KLSAgICogdGhlIGVuY29kaW5nIGRlY2xhcmF0aW9uIG9mIHRoZSBkb2N1bWVudAotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZW5jb2RpbmdTZXQoKTsKLQotICAvKioKLSAgICogUmV0dXJucyBpZiB0aGlzIFhNTCBpcyBzdGFuZGFsb25lCi0gICAqIEByZXR1cm4gdGhlIHN0YW5kYWxvbmUgc3RhdGUgb2YgWE1MLCBkZWZhdWx0cyB0byAibm8iCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBpc1N0YW5kYWxvbmUoKTsKLQotICAvKioKLSAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBzdGFuZGFsb25lIGF0dHJpYnV0ZSB3YXMgc2V0IGluCi0gICAqIHRoZSBlbmNvZGluZyBkZWNsYXJhdGlvbiBvZiB0aGUgZG9jdW1lbnQuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBzdGFuZGFsb25lU2V0KCk7Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIHZlcnNpb24gb2YgWE1MIG9mIHRoaXMgWE1MIHN0cmVhbQotICAgKiBAcmV0dXJuIHRoZSB2ZXJzaW9uIG9mIFhNTCwgZGVmYXVsdHMgdG8gIjEuMCIKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0VmVyc2lvbigpOwotfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmF4L3htbC9zdHJlYW0vZXZlbnRzL1N0YXJ0RWxlbWVudC5qYXZhIGIvc3JjL2phdmF4L3htbC9zdHJlYW0vZXZlbnRzL1N0YXJ0RWxlbWVudC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA5YjI4NmE2Li4wMDAwMDAwCi0tLSBhL3NyYy9qYXZheC94bWwvc3RyZWFtL2V2ZW50cy9TdGFydEVsZW1lbnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExNyArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogQ29weXJpZ2h0IChjKSAyMDA5IGJ5IE9yYWNsZSBDb3Jwb3JhdGlvbi4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KLSAqLwotCi1wYWNrYWdlIGphdmF4LnhtbC5zdHJlYW0uZXZlbnRzOwotCi1pbXBvcnQgamF2YXgueG1sLm5hbWVzcGFjZS5RTmFtZTsKLWltcG9ydCBqYXZheC54bWwubmFtZXNwYWNlLk5hbWVzcGFjZUNvbnRleHQ7Ci0KLWltcG9ydCBqYXZhLnV0aWwuTWFwOwotaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKLQotLyoqCi0gKiBUaGUgU3RhcnRFbGVtZW50IGludGVyZmFjZSBwcm92aWRlcyBhY2Nlc3MgdG8gaW5mb3JtYXRpb24gYWJvdXQKLSAqIHN0YXJ0IGVsZW1lbnRzLiAgQSBTdGFydEVsZW1lbnQgaXMgcmVwb3J0ZWQgZm9yIGVhY2ggU3RhcnQgVGFnCi0gKiBpbiB0aGUgZG9jdW1lbnQuCi0gKgotICogQHZlcnNpb24gMS4wCi0gKiBAYXV0aG9yIENvcHlyaWdodCAoYykgMjAwOSBieSBPcmFjbGUgQ29ycG9yYXRpb24uIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCi0gKiBAc2luY2UgMS42Ci0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgU3RhcnRFbGVtZW50IGV4dGVuZHMgWE1MRXZlbnQgewotCi0gIC8qKgotICAgKiBHZXQgdGhlIG5hbWUgb2YgdGhpcyBldmVudAotICAgKiBAcmV0dXJuIHRoZSBxdWFsaWZpZWQgbmFtZSBvZiB0aGlzIGV2ZW50Ci0gICAqLwotICBwdWJsaWMgUU5hbWUgZ2V0TmFtZSgpOwotCi0gIC8qKgotICAgKiBSZXR1cm5zIGFuIEl0ZXJhdG9yIG9mIG5vbi1uYW1lc3BhY2UgZGVjbGFyZWQgYXR0cmlidXRlcyBkZWNsYXJlZCBvbgotICAgKiB0aGlzIFNUQVJUX0VMRU1FTlQsCi0gICAqIHJldHVybnMgYW4gZW1wdHkgaXRlcmF0b3IgaWYgdGhlcmUgYXJlIG5vIGF0dHJpYnV0ZXMuICBUaGUKLSAgICogaXRlcmF0b3IgbXVzdCBjb250YWluIG9ubHkgaW1wbGVtZW50YXRpb25zIG9mIHRoZSBqYXZheC54bWwuc3RyZWFtLkF0dHJpYnV0ZQotICAgKiBpbnRlcmZhY2UuICAgQXR0cmlidXRlcyBhcmUgZnVuZGFtZW50YWxseSB1bm9yZGVyZWQgYW5kIG1heSBub3QgYmUgcmVwb3J0ZWQKLSAgICogaW4gYW55IG9yZGVyLgotICAgKgotICAgKiBAcmV0dXJuIGEgcmVhZG9ubHkgSXRlcmF0b3Igb3ZlciBBdHRyaWJ1dGUgaW50ZXJmYWNlcywgb3IgYW4KLSAgICogZW1wdHkgaXRlcmF0b3IKLSAgICovCi0gIHB1YmxpYyBJdGVyYXRvciBnZXRBdHRyaWJ1dGVzKCk7Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgYW4gSXRlcmF0b3Igb2YgbmFtZXNwYWNlcyBkZWNsYXJlZCBvbiB0aGlzIGVsZW1lbnQuCi0gICAqIFRoaXMgSXRlcmF0b3IgZG9lcyBub3QgY29udGFpbiBwcmV2aW91c2x5IGRlY2xhcmVkIG5hbWVzcGFjZXMKLSAgICogdW5sZXNzIHRoZXkgYXBwZWFyIG9uIHRoZSBjdXJyZW50IFNUQVJUX0VMRU1FTlQuCi0gICAqIFRoZXJlZm9yZSB0aGlzIGxpc3QgbWF5IGNvbnRhaW4gcmVkZWNsYXJlZCBuYW1lc3BhY2VzIGFuZCBkdXBsaWNhdGUgbmFtZXNwYWNlCi0gICAqIGRlY2xhcmF0aW9ucy4gVXNlIHRoZSBnZXROYW1lc3BhY2VDb250ZXh0KCkgbWV0aG9kIHRvIGdldCB0aGUKLSAgICogY3VycmVudCBjb250ZXh0IG9mIG5hbWVzcGFjZSBkZWNsYXJhdGlvbnMuCi0gICAqCi0gICAqIDxwPlRoZSBpdGVyYXRvciBtdXN0IGNvbnRhaW4gb25seSBpbXBsZW1lbnRhdGlvbnMgb2YgdGhlCi0gICAqIGphdmF4LnhtbC5zdHJlYW0uTmFtZXNwYWNlIGludGVyZmFjZS4KLSAgICoKLSAgICogPHA+QSBOYW1lc3BhY2UgaXNBIEF0dHJpYnV0ZS4gIE9uZQotICAgKiBjYW4gaXRlcmF0ZSBvdmVyIGEgbGlzdCBvZiBuYW1lc3BhY2VzIGFzIGEgbGlzdCBvZiBhdHRyaWJ1dGVzLgotICAgKiBIb3dldmVyIHRoaXMgbWV0aG9kIHJldHVybnMgb25seSB0aGUgbGlzdCBvZiBuYW1lc3BhY2VzCi0gICAqIGRlY2xhcmVkIG9uIHRoaXMgU1RBUlRfRUxFTUVOVCBhbmQgZG9lcyBub3QKLSAgICogaW5jbHVkZSB0aGUgYXR0cmlidXRlcyBkZWNsYXJlZCBvbiB0aGlzIFNUQVJUX0VMRU1FTlQuCi0gICAqCi0gICAqIFJldHVybnMgYW4gZW1wdHkgaXRlcmF0b3IgaWYgdGhlcmUgYXJlIG5vIG5hbWVzcGFjZXMuCi0gICAqCi0gICAqIEByZXR1cm4gYSByZWFkb25seSBJdGVyYXRvciBvdmVyIE5hbWVzcGFjZSBpbnRlcmZhY2VzLCBvciBhbgotICAgKiBlbXB0eSBpdGVyYXRvcgotICAgKgotICAgKi8KLSAgcHVibGljIEl0ZXJhdG9yIGdldE5hbWVzcGFjZXMoKTsKLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgYXR0cmlidXRlIHJlZmVycmVkIHRvIGJ5IHRoaXMgbmFtZQotICAgKiBAcGFyYW0gbmFtZSB0aGUgcW5hbWUgb2YgdGhlIGRlc2lyZWQgbmFtZQotICAgKiBAcmV0dXJuIHRoZSBhdHRyaWJ1dGUgY29ycmVzcG9uZGluZyB0byB0aGUgbmFtZSB2YWx1ZSBvciBudWxsCi0gICAqLwotICBwdWJsaWMgQXR0cmlidXRlIGdldEF0dHJpYnV0ZUJ5TmFtZShRTmFtZSBuYW1lKTsKLQotICAvKioKLSAgICogR2V0cyBhIHJlYWQtb25seSBuYW1lc3BhY2UgY29udGV4dC4gSWYgbm8gY29udGV4dCBpcwotICAgKiBhdmFpbGFibGUgdGhpcyBtZXRob2Qgd2lsbCByZXR1cm4gYW4gZW1wdHkgbmFtZXNwYWNlIGNvbnRleHQuCi0gICAqIFRoZSBOYW1lc3BhY2VDb250ZXh0IGNvbnRhaW5zIGluZm9ybWF0aW9uIGFib3V0IGFsbCBuYW1lc3BhY2VzCi0gICAqIGluIHNjb3BlIGZvciB0aGlzIFN0YXJ0RWxlbWVudC4KLSAgICoKLSAgICogQHJldHVybiB0aGUgY3VycmVudCBuYW1lc3BhY2UgY29udGV4dAotICAgKi8KLSAgcHVibGljIE5hbWVzcGFjZUNvbnRleHQgZ2V0TmFtZXNwYWNlQ29udGV4dCgpOwotCi0gIC8qKgotICAgKiBHZXRzIHRoZSB2YWx1ZSB0aGF0IHRoZSBwcmVmaXggaXMgYm91bmQgdG8gaW4gdGhlCi0gICAqIGNvbnRleHQgb2YgdGhpcyBlbGVtZW50LiAgUmV0dXJucyBudWxsIGlmCi0gICAqIHRoZSBwcmVmaXggaXMgbm90IGJvdW5kIGluIHRoaXMgY29udGV4dAotICAgKiBAcGFyYW0gcHJlZml4IHRoZSBwcmVmaXggdG8gbG9va3VwCi0gICAqIEByZXR1cm4gdGhlIHVyaSBib3VuZCB0byB0aGUgcHJlZml4IG9yIG51bGwKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZXNwYWNlVVJJKFN0cmluZyBwcmVmaXgpOwotfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmF4L3htbC9zdHJlYW0vZXZlbnRzL1hNTEV2ZW50LmphdmEgYi9zcmMvamF2YXgveG1sL3N0cmVhbS9ldmVudHMvWE1MRXZlbnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNGY5ODAxMi4uMDAwMDAwMAotLS0gYS9zcmMvamF2YXgveG1sL3N0cmVhbS9ldmVudHMvWE1MRXZlbnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE3OCArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogQ29weXJpZ2h0IChjKSAyMDA5IGJ5IE9yYWNsZSBDb3Jwb3JhdGlvbi4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KLSAqLwotCi1wYWNrYWdlIGphdmF4LnhtbC5zdHJlYW0uZXZlbnRzOwotCi1pbXBvcnQgamF2YS5pby5Xcml0ZXI7Ci1pbXBvcnQgamF2YXgueG1sLm5hbWVzcGFjZS5RTmFtZTsKLS8qKgotICogVGhpcyBpcyB0aGUgYmFzZSBldmVudCBpbnRlcmZhY2UgZm9yIGhhbmRsaW5nIG1hcmt1cCBldmVudHMuCi0gKiBFdmVudHMgYXJlIHZhbHVlIG9iamVjdHMgdGhhdCBhcmUgdXNlZCB0byBjb21tdW5pY2F0ZSB0aGUKLSAqIFhNTCAxLjAgSW5mb1NldCB0byB0aGUgQXBwbGljYXRpb24uICBFdmVudHMgbWF5IGJlIGNhY2hlZAotICogYW5kIHJlZmVyZW5jZWQgYWZ0ZXIgdGhlIHBhcnNlIGhhcyBjb21wbGV0ZWQuCi0gKgotICogQHZlcnNpb24gMS4wCi0gKiBAYXV0aG9yIENvcHlyaWdodCAoYykgMjAwOSBieSBPcmFjbGUgQ29ycG9yYXRpb24uIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCi0gKiBAc2VlIGphdmF4LnhtbC5zdHJlYW0uWE1MRXZlbnRSZWFkZXIKLSAqIEBzZWUgQ2hhcmFjdGVycwotICogQHNlZSBQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24KLSAqIEBzZWUgU3RhcnRFbGVtZW50Ci0gKiBAc2VlIEVuZEVsZW1lbnQKLSAqIEBzZWUgU3RhcnREb2N1bWVudAotICogQHNlZSBFbmREb2N1bWVudAotICogQHNlZSBFbnRpdHlSZWZlcmVuY2UKLSAqIEBzZWUgRW50aXR5RGVjbGFyYXRpb24KLSAqIEBzZWUgTm90YXRpb25EZWNsYXJhdGlvbgotICogQHNpbmNlIDEuNgotICovCi1wdWJsaWMgaW50ZXJmYWNlIFhNTEV2ZW50IGV4dGVuZHMgamF2YXgueG1sLnN0cmVhbS5YTUxTdHJlYW1Db25zdGFudHMgewotCi0gIC8qKgotICAgKiBSZXR1cm5zIGFuIGludGVnZXIgY29kZSBmb3IgdGhpcyBldmVudC4KLSAgICogQHNlZSAjU1RBUlRfRUxFTUVOVAotICAgKiBAc2VlICNFTkRfRUxFTUVOVAotICAgKiBAc2VlICNDSEFSQUNURVJTCi0gICAqIEBzZWUgI0FUVFJJQlVURQotICAgKiBAc2VlICNOQU1FU1BBQ0UKLSAgICogQHNlZSAjUFJPQ0VTU0lOR19JTlNUUlVDVElPTgotICAgKiBAc2VlICNDT01NRU5UCi0gICAqIEBzZWUgI1NUQVJUX0RPQ1VNRU5UCi0gICAqIEBzZWUgI0VORF9ET0NVTUVOVAotICAgKiBAc2VlICNEVEQKLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0RXZlbnRUeXBlKCk7Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgbG9jYXRpb24gb2YgdGhpcyBldmVudC4gIFRoZSBMb2NhdGlvbgotICAgKiByZXR1cm5lZCBmcm9tIHRoaXMgbWV0aG9kIGlzIG5vbi12b2xhdGlsZSBhbmQKLSAgICogd2lsbCByZXRhaW4gaXRzIGluZm9ybWF0aW9uLgotICAgKiBAc2VlIGphdmF4LnhtbC5zdHJlYW0uTG9jYXRpb24KLSAgICovCi0gIGphdmF4LnhtbC5zdHJlYW0uTG9jYXRpb24gZ2V0TG9jYXRpb24oKTsKLQotICAvKioKLSAgICogQSB1dGlsaXR5IGZ1bmN0aW9uIHRvIGNoZWNrIGlmIHRoaXMgZXZlbnQgaXMgYSBTdGFydEVsZW1lbnQuCi0gICAqIEBzZWUgU3RhcnRFbGVtZW50Ci0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBpc1N0YXJ0RWxlbWVudCgpOwotCi0gIC8qKgotICAgKiBBIHV0aWxpdHkgZnVuY3Rpb24gdG8gY2hlY2sgaWYgdGhpcyBldmVudCBpcyBhbiBBdHRyaWJ1dGUuCi0gICAqIEBzZWUgQXR0cmlidXRlCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBpc0F0dHJpYnV0ZSgpOwotCi0gIC8qKgotICAgKiBBIHV0aWxpdHkgZnVuY3Rpb24gdG8gY2hlY2sgaWYgdGhpcyBldmVudCBpcyBhIE5hbWVzcGFjZS4KLSAgICogQHNlZSBOYW1lc3BhY2UKLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzTmFtZXNwYWNlKCk7Ci0KLQotICAvKioKLSAgICogQSB1dGlsaXR5IGZ1bmN0aW9uIHRvIGNoZWNrIGlmIHRoaXMgZXZlbnQgaXMgYSBFbmRFbGVtZW50LgotICAgKiBAc2VlIEVuZEVsZW1lbnQKLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzRW5kRWxlbWVudCgpOwotCi0gIC8qKgotICAgKiBBIHV0aWxpdHkgZnVuY3Rpb24gdG8gY2hlY2sgaWYgdGhpcyBldmVudCBpcyBhbiBFbnRpdHlSZWZlcmVuY2UuCi0gICAqIEBzZWUgRW50aXR5UmVmZXJlbmNlCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBpc0VudGl0eVJlZmVyZW5jZSgpOwotCi0gIC8qKgotICAgKiBBIHV0aWxpdHkgZnVuY3Rpb24gdG8gY2hlY2sgaWYgdGhpcyBldmVudCBpcyBhIFByb2Nlc3NpbmdJbnN0cnVjdGlvbi4KLSAgICogQHNlZSBQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzUHJvY2Vzc2luZ0luc3RydWN0aW9uKCk7Ci0KLSAgLyoqCi0gICAqIEEgdXRpbGl0eSBmdW5jdGlvbiB0byBjaGVjayBpZiB0aGlzIGV2ZW50IGlzIENoYXJhY3RlcnMuCi0gICAqIEBzZWUgQ2hhcmFjdGVycwotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNDaGFyYWN0ZXJzKCk7Ci0KLSAgLyoqCi0gICAqIEEgdXRpbGl0eSBmdW5jdGlvbiB0byBjaGVjayBpZiB0aGlzIGV2ZW50IGlzIGEgU3RhcnREb2N1bWVudC4KLSAgICogQHNlZSBTdGFydERvY3VtZW50Ci0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBpc1N0YXJ0RG9jdW1lbnQoKTsKLQotICAvKioKLSAgICogQSB1dGlsaXR5IGZ1bmN0aW9uIHRvIGNoZWNrIGlmIHRoaXMgZXZlbnQgaXMgYW4gRW5kRG9jdW1lbnQuCi0gICAqIEBzZWUgRW5kRG9jdW1lbnQKLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzRW5kRG9jdW1lbnQoKTsKLQotICAvKioKLSAgICogUmV0dXJucyB0aGlzIGV2ZW50IGFzIGEgc3RhcnQgZWxlbWVudCBldmVudCwgbWF5IHJlc3VsdCBpbgotICAgKiBhIGNsYXNzIGNhc3QgZXhjZXB0aW9uIGlmIHRoaXMgZXZlbnQgaXMgbm90IGEgc3RhcnQgZWxlbWVudC4KLSAgICovCi0gIHB1YmxpYyBTdGFydEVsZW1lbnQgYXNTdGFydEVsZW1lbnQoKTsKLQotICAvKioKLSAgICogUmV0dXJucyB0aGlzIGV2ZW50IGFzIGFuIGVuZCAgZWxlbWVudCBldmVudCwgbWF5IHJlc3VsdCBpbgotICAgKiBhIGNsYXNzIGNhc3QgZXhjZXB0aW9uIGlmIHRoaXMgZXZlbnQgaXMgbm90IGEgZW5kIGVsZW1lbnQuCi0gICAqLwotICBwdWJsaWMgRW5kRWxlbWVudCBhc0VuZEVsZW1lbnQoKTsKLQotICAvKioKLSAgICogUmV0dXJucyB0aGlzIGV2ZW50IGFzIENoYXJhY3RlcnMsIG1heSByZXN1bHQgaW4KLSAgICogYSBjbGFzcyBjYXN0IGV4Y2VwdGlvbiBpZiB0aGlzIGV2ZW50IGlzIG5vdCBDaGFyYWN0ZXJzLgotICAgKi8KLSAgcHVibGljIENoYXJhY3RlcnMgYXNDaGFyYWN0ZXJzKCk7Ci0KLSAgLyoqCi0gICAqIFRoaXMgbWV0aG9kIGlzIHByb3ZpZGVkIGZvciBpbXBsZW1lbnRhdGlvbnMgdG8gcHJvdmlkZQotICAgKiBvcHRpb25hbCB0eXBlIGluZm9ybWF0aW9uIGFib3V0IHRoZSBhc3NvY2lhdGVkIGV2ZW50LgotICAgKiBJdCBpcyBvcHRpb25hbCBhbmQgd2lsbCByZXR1cm4gbnVsbCBpZiBubyBpbmZvcm1hdGlvbgotICAgKiBpcyBhdmFpbGFibGUuCi0gICAqLwotICBwdWJsaWMgUU5hbWUgZ2V0U2NoZW1hVHlwZSgpOwotCi0gIC8qKgotICAgKiBUaGlzIG1ldGhvZCB3aWxsIHdyaXRlIHRoZSBYTUxFdmVudCBhcyBwZXIgdGhlIFhNTCAxLjAgc3BlY2lmaWNhdGlvbiBhcyBVbmljb2RlIGNoYXJhY3RlcnMuCi0gICAqIE5vIGluZGVudGF0aW9uIG9yIHdoaXRlc3BhY2Ugc2hvdWxkIGJlIG91dHB1dHRlZC4KLSAgICoKLSAgICogQW55IHVzZXIgZGVmaW5lZCBldmVudCB0eXBlIFNIQUxMIGhhdmUgdGhpcyBtZXRob2QKLSAgICogY2FsbGVkIHdoZW4gYmVpbmcgd3JpdHRlbiB0byBvbiBhbiBvdXRwdXQgc3RyZWFtLgotICAgKiBCdWlsdCBpbiBFdmVudCB0eXBlcyBNVVNUIGltcGxlbWVudCB0aGlzIG1ldGhvZCwKLSAgICogYnV0IGltcGxlbWVudGF0aW9ucyBNQVkgY2hvb3NlIG5vdCBjYWxsIHRoZXNlIG1ldGhvZHMKLSAgICogZm9yIG9wdGltaXphdGlvbnMgcmVhc29ucyB3aGVuIHdyaXRpbmcgb3V0IGJ1aWx0IGluCi0gICAqIEV2ZW50cyB0byBhbiBvdXRwdXQgc3RyZWFtLgotICAgKiBUaGUgb3V0cHV0IGdlbmVyYXRlZCBNVVNUIGJlIGVxdWl2YWxlbnQgaW4gdGVybXMgb2YgdGhlCi0gICAqIGluZm9zZXQgZXhwcmVzc2VkLgotICAgKgotICAgKiBAcGFyYW0gd3JpdGVyIFRoZSB3cml0ZXIgdGhhdCB3aWxsIG91dHB1dCB0aGUgZGF0YQotICAgKiBAdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbiBpZiB0aGVyZSBpcyBhIGZhdGFsIGVycm9yIHdyaXRpbmcgdGhlIGV2ZW50Ci0gICAqLwotICBwdWJsaWMgdm9pZCB3cml0ZUFzRW5jb2RlZFVuaWNvZGUoV3JpdGVyIHdyaXRlcikKLSAgICB0aHJvd3MgamF2YXgueG1sLnN0cmVhbS5YTUxTdHJlYW1FeGNlcHRpb247Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9qYXZheC94bWwvc3RyZWFtL3V0aWwvRXZlbnRSZWFkZXJEZWxlZ2F0ZS5qYXZhIGIvc3JjL2phdmF4L3htbC9zdHJlYW0vdXRpbC9FdmVudFJlYWRlckRlbGVnYXRlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDllMmZiZDMuLjAwMDAwMDAKLS0tIGEvc3JjL2phdmF4L3htbC9zdHJlYW0vdXRpbC9FdmVudFJlYWRlckRlbGVnYXRlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMzQgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwOSBieSBPcmFjbGUgQ29ycG9yYXRpb24uIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCi0gKi8KLQotcGFja2FnZSBqYXZheC54bWwuc3RyZWFtLnV0aWw7Ci0KLWltcG9ydCBqYXZheC54bWwubmFtZXNwYWNlLlFOYW1lOwotaW1wb3J0IGphdmF4LnhtbC5uYW1lc3BhY2UuTmFtZXNwYWNlQ29udGV4dDsKLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLlhNTEV2ZW50UmVhZGVyOwotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uZXZlbnRzLlhNTEV2ZW50OwotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uTG9jYXRpb247Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5YTUxTdHJlYW1FeGNlcHRpb247Ci0KLS8qKgotICogVGhpcyBpcyB0aGUgYmFzZSBjbGFzcyBmb3IgZGVyaXZpbmcgYW4gWE1MRXZlbnRSZWFkZXIKLSAqIGZpbHRlci4KLSAqCi0gKiBUaGlzIGNsYXNzIGlzIGRlc2lnbmVkIHRvIHNpdCBiZXR3ZWVuIGFuIFhNTEV2ZW50UmVhZGVyIGFuZCBhbgotICogYXBwbGljYXRpb24ncyBYTUxFdmVudFJlYWRlci4gIEJ5IGRlZmF1bHQgZWFjaCBtZXRob2QKLSAqIGRvZXMgbm90aGluZyBidXQgY2FsbCB0aGUgY29ycmVzcG9uZGluZyBtZXRob2Qgb24gdGhlCi0gKiBwYXJlbnQgaW50ZXJmYWNlLgotICoKLSAqIEB2ZXJzaW9uIDEuMAotICogQGF1dGhvciBDb3B5cmlnaHQgKGMpIDIwMDkgYnkgT3JhY2xlIENvcnBvcmF0aW9uLiBBbGwgUmlnaHRzIFJlc2VydmVkLgotICogQHNlZSBqYXZheC54bWwuc3RyZWFtLlhNTEV2ZW50UmVhZGVyCi0gKiBAc2VlIFN0cmVhbVJlYWRlckRlbGVnYXRlCi0gKiBAc2luY2UgMS42Ci0gKi8KLQotcHVibGljIGNsYXNzIEV2ZW50UmVhZGVyRGVsZWdhdGUgaW1wbGVtZW50cyBYTUxFdmVudFJlYWRlciB7Ci0gIHByaXZhdGUgWE1MRXZlbnRSZWFkZXIgcmVhZGVyOwotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYW4gZW1wdHkgZmlsdGVyIHdpdGggbm8gcGFyZW50LgotICAgKi8KLSAgcHVibGljIEV2ZW50UmVhZGVyRGVsZWdhdGUoKXt9Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhbiBmaWx0ZXIgd2l0aCB0aGUgc3BlY2lmaWVkIHBhcmVudC4KLSAgICogQHBhcmFtIHJlYWRlciB0aGUgcGFyZW50Ci0gICAqLwotICBwdWJsaWMgRXZlbnRSZWFkZXJEZWxlZ2F0ZShYTUxFdmVudFJlYWRlciByZWFkZXIpIHsKLSAgICB0aGlzLnJlYWRlciA9IHJlYWRlcjsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIHBhcmVudCBvZiB0aGlzIGluc3RhbmNlLgotICAgKiBAcGFyYW0gcmVhZGVyIHRoZSBuZXcgcGFyZW50Ci0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRQYXJlbnQoWE1MRXZlbnRSZWFkZXIgcmVhZGVyKSB7Ci0gICAgdGhpcy5yZWFkZXIgPSByZWFkZXI7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBwYXJlbnQgb2YgdGhpcyBpbnN0YW5jZS4KLSAgICogQHJldHVybiB0aGUgcGFyZW50IG9yIG51bGwgaWYgbm9uZSBpcyBzZXQKLSAgICovCi0gIHB1YmxpYyBYTUxFdmVudFJlYWRlciBnZXRQYXJlbnQoKSB7Ci0gICAgcmV0dXJuIHJlYWRlcjsKLSAgfQotCi0gIHB1YmxpYyBYTUxFdmVudCBuZXh0RXZlbnQoKQotICAgIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24KLSAgewotICAgIHJldHVybiByZWFkZXIubmV4dEV2ZW50KCk7Ci0gIH0KLQotICBwdWJsaWMgT2JqZWN0IG5leHQoKSB7Ci0gICAgcmV0dXJuIHJlYWRlci5uZXh0KCk7Ci0gIH0KLQotICBwdWJsaWMgYm9vbGVhbiBoYXNOZXh0KCkKLSAgewotICAgIHJldHVybiByZWFkZXIuaGFzTmV4dCgpOwotICB9Ci0KLSAgcHVibGljIFhNTEV2ZW50IHBlZWsoKQotICAgIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24KLSAgewotICAgIHJldHVybiByZWFkZXIucGVlaygpOwotICB9Ci0KLSAgcHVibGljIHZvaWQgY2xvc2UoKQotICAgIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24KLSAgewotICAgIHJlYWRlci5jbG9zZSgpOwotICB9Ci0KLSAgcHVibGljIFN0cmluZyBnZXRFbGVtZW50VGV4dCgpCi0gICAgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIHJlYWRlci5nZXRFbGVtZW50VGV4dCgpOwotICB9Ci0KLSAgcHVibGljIFhNTEV2ZW50IG5leHRUYWcoKQotICAgIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24KLSAgewotICAgIHJldHVybiByZWFkZXIubmV4dFRhZygpOwotICB9Ci0KLSAgcHVibGljIE9iamVjdCBnZXRQcm9wZXJ0eShqYXZhLmxhbmcuU3RyaW5nIG5hbWUpCi0gICAgdGhyb3dzIGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KLSAgewotICAgIHJldHVybiByZWFkZXIuZ2V0UHJvcGVydHkobmFtZSk7Ci0gIH0KLQotICBwdWJsaWMgdm9pZCByZW1vdmUoKSB7Ci0gICAgcmVhZGVyLnJlbW92ZSgpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvamF2YXgveG1sL3N0cmVhbS91dGlsL1N0cmVhbVJlYWRlckRlbGVnYXRlLmphdmEgYi9zcmMvamF2YXgveG1sL3N0cmVhbS91dGlsL1N0cmVhbVJlYWRlckRlbGVnYXRlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGYwNGE5ODUuLjAwMDAwMDAKLS0tIGEvc3JjL2phdmF4L3htbC9zdHJlYW0vdXRpbC9TdHJlYW1SZWFkZXJEZWxlZ2F0ZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjg3ICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDkgYnkgT3JhY2xlIENvcnBvcmF0aW9uLiBBbGwgUmlnaHRzIFJlc2VydmVkLgotICovCi0KLXBhY2thZ2UgamF2YXgueG1sLnN0cmVhbS51dGlsOwotCi1pbXBvcnQgamF2YS5pby5SZWFkZXI7Ci1pbXBvcnQgamF2YXgueG1sLm5hbWVzcGFjZS5RTmFtZTsKLWltcG9ydCBqYXZheC54bWwubmFtZXNwYWNlLk5hbWVzcGFjZUNvbnRleHQ7Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5YTUxTdHJlYW1SZWFkZXI7Ci1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5Mb2NhdGlvbjsKLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLlhNTFN0cmVhbUV4Y2VwdGlvbjsKLQotLyoqCi0gKiBUaGlzIGlzIHRoZSBiYXNlIGNsYXNzIGZvciBkZXJpdmluZyBhbiBYTUxTdHJlYW1SZWFkZXIgZmlsdGVyCi0gKgotICogVGhpcyBjbGFzcyBpcyBkZXNpZ25lZCB0byBzaXQgYmV0d2VlbiBhbiBYTUxTdHJlYW1SZWFkZXIgYW5kIGFuCi0gKiBhcHBsaWNhdGlvbidzIFhNTFN0cmVhbVJlYWRlci4gICBCeSBkZWZhdWx0IGVhY2ggbWV0aG9kCi0gKiBkb2VzIG5vdGhpbmcgYnV0IGNhbGwgdGhlIGNvcnJlc3BvbmRpbmcgbWV0aG9kIG9uIHRoZQotICogcGFyZW50IGludGVyZmFjZS4KLSAqCi0gKiBAdmVyc2lvbiAxLjAKLSAqIEBhdXRob3IgQ29weXJpZ2h0IChjKSAyMDA5IGJ5IE9yYWNsZSBDb3Jwb3JhdGlvbi4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KLSAqIEBzZWUgamF2YXgueG1sLnN0cmVhbS5YTUxTdHJlYW1SZWFkZXIKLSAqIEBzZWUgRXZlbnRSZWFkZXJEZWxlZ2F0ZQotICogQHNpbmNlIDEuNgotICovCi0KLXB1YmxpYyBjbGFzcyBTdHJlYW1SZWFkZXJEZWxlZ2F0ZSBpbXBsZW1lbnRzIFhNTFN0cmVhbVJlYWRlciB7Ci0gIHByaXZhdGUgWE1MU3RyZWFtUmVhZGVyIHJlYWRlcjsKLQotICAvKioKLSAgICogQ29uc3RydWN0IGFuIGVtcHR5IGZpbHRlciB3aXRoIG5vIHBhcmVudC4KLSAgICovCi0gIHB1YmxpYyBTdHJlYW1SZWFkZXJEZWxlZ2F0ZSgpe30KLQotICAvKioKLSAgICogQ29uc3RydWN0IGFuIGZpbHRlciB3aXRoIHRoZSBzcGVjaWZpZWQgcGFyZW50LgotICAgKiBAcGFyYW0gcmVhZGVyIHRoZSBwYXJlbnQKLSAgICovCi0gIHB1YmxpYyBTdHJlYW1SZWFkZXJEZWxlZ2F0ZShYTUxTdHJlYW1SZWFkZXIgcmVhZGVyKSB7Ci0gICAgdGhpcy5yZWFkZXIgPSByZWFkZXI7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBwYXJlbnQgb2YgdGhpcyBpbnN0YW5jZS4KLSAgICogQHBhcmFtIHJlYWRlciB0aGUgbmV3IHBhcmVudAotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0UGFyZW50KFhNTFN0cmVhbVJlYWRlciByZWFkZXIpIHsKLSAgICB0aGlzLnJlYWRlciA9IHJlYWRlcjsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIHBhcmVudCBvZiB0aGlzIGluc3RhbmNlLgotICAgKiBAcmV0dXJuIHRoZSBwYXJlbnQgb3IgbnVsbCBpZiBub25lIGlzIHNldAotICAgKi8KLSAgcHVibGljIFhNTFN0cmVhbVJlYWRlciBnZXRQYXJlbnQoKSB7Ci0gICAgcmV0dXJuIHJlYWRlcjsKLSAgfQotCi0gIHB1YmxpYyBpbnQgbmV4dCgpCi0gICAgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIHJlYWRlci5uZXh0KCk7Ci0gIH0KLQotICBwdWJsaWMgaW50IG5leHRUYWcoKQotICAgIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb24KLSAgewotICAgIHJldHVybiByZWFkZXIubmV4dFRhZygpOwotICB9Ci0KLSAgcHVibGljIFN0cmluZyBnZXRFbGVtZW50VGV4dCgpCi0gICAgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIHJlYWRlci5nZXRFbGVtZW50VGV4dCgpOwotICB9Ci0KLSAgcHVibGljIHZvaWQgcmVxdWlyZShpbnQgdHlwZSwgU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIGxvY2FsTmFtZSkKLSAgICB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uCi0gIHsKLSAgICByZWFkZXIucmVxdWlyZSh0eXBlLG5hbWVzcGFjZVVSSSxsb2NhbE5hbWUpOwotICB9Ci0KLSAgcHVibGljIGJvb2xlYW4gaGFzTmV4dCgpCi0gICAgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIHJlYWRlci5oYXNOZXh0KCk7Ci0gIH0KLQotICBwdWJsaWMgdm9pZCBjbG9zZSgpCi0gICAgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbgotICB7Ci0gICAgcmVhZGVyLmNsb3NlKCk7Ci0gIH0KLQotICBwdWJsaWMgU3RyaW5nIGdldE5hbWVzcGFjZVVSSShTdHJpbmcgcHJlZml4KQotICB7Ci0gICAgcmV0dXJuIHJlYWRlci5nZXROYW1lc3BhY2VVUkkocHJlZml4KTsKLSAgfQotCi0gIHB1YmxpYyBOYW1lc3BhY2VDb250ZXh0IGdldE5hbWVzcGFjZUNvbnRleHQoKSB7Ci0gICAgcmV0dXJuIHJlYWRlci5nZXROYW1lc3BhY2VDb250ZXh0KCk7Ci0gIH0KLQotICBwdWJsaWMgYm9vbGVhbiBpc1N0YXJ0RWxlbWVudCgpIHsKLSAgICByZXR1cm4gcmVhZGVyLmlzU3RhcnRFbGVtZW50KCk7Ci0gIH0KLQotICBwdWJsaWMgYm9vbGVhbiBpc0VuZEVsZW1lbnQoKSB7Ci0gICAgcmV0dXJuIHJlYWRlci5pc0VuZEVsZW1lbnQoKTsKLSAgfQotCi0gIHB1YmxpYyBib29sZWFuIGlzQ2hhcmFjdGVycygpIHsKLSAgICByZXR1cm4gcmVhZGVyLmlzQ2hhcmFjdGVycygpOwotICB9Ci0KLSAgcHVibGljIGJvb2xlYW4gaXNXaGl0ZVNwYWNlKCkgewotICAgIHJldHVybiByZWFkZXIuaXNXaGl0ZVNwYWNlKCk7Ci0gIH0KLQotICBwdWJsaWMgU3RyaW5nIGdldEF0dHJpYnV0ZVZhbHVlKFN0cmluZyBuYW1lc3BhY2VVcmksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGxvY2FsTmFtZSkKLSAgewotICAgIHJldHVybiByZWFkZXIuZ2V0QXR0cmlidXRlVmFsdWUobmFtZXNwYWNlVXJpLGxvY2FsTmFtZSk7Ci0gIH0KLQotICBwdWJsaWMgaW50IGdldEF0dHJpYnV0ZUNvdW50KCkgewotICAgIHJldHVybiByZWFkZXIuZ2V0QXR0cmlidXRlQ291bnQoKTsKLSAgfQotCi0gIHB1YmxpYyBRTmFtZSBnZXRBdHRyaWJ1dGVOYW1lKGludCBpbmRleCkgewotICAgIHJldHVybiByZWFkZXIuZ2V0QXR0cmlidXRlTmFtZShpbmRleCk7Ci0gIH0KLQotICBwdWJsaWMgU3RyaW5nIGdldEF0dHJpYnV0ZVByZWZpeChpbnQgaW5kZXgpIHsKLSAgICByZXR1cm4gcmVhZGVyLmdldEF0dHJpYnV0ZVByZWZpeChpbmRleCk7Ci0gIH0KLQotICBwdWJsaWMgU3RyaW5nIGdldEF0dHJpYnV0ZU5hbWVzcGFjZShpbnQgaW5kZXgpIHsKLSAgICByZXR1cm4gcmVhZGVyLmdldEF0dHJpYnV0ZU5hbWVzcGFjZShpbmRleCk7Ci0gIH0KLQotICBwdWJsaWMgU3RyaW5nIGdldEF0dHJpYnV0ZUxvY2FsTmFtZShpbnQgaW5kZXgpIHsKLSAgICByZXR1cm4gcmVhZGVyLmdldEF0dHJpYnV0ZUxvY2FsTmFtZShpbmRleCk7Ci0gIH0KLQotICBwdWJsaWMgU3RyaW5nIGdldEF0dHJpYnV0ZVR5cGUoaW50IGluZGV4KSB7Ci0gICAgcmV0dXJuIHJlYWRlci5nZXRBdHRyaWJ1dGVUeXBlKGluZGV4KTsKLSAgfQotCi0gIHB1YmxpYyBTdHJpbmcgZ2V0QXR0cmlidXRlVmFsdWUoaW50IGluZGV4KSB7Ci0gICAgcmV0dXJuIHJlYWRlci5nZXRBdHRyaWJ1dGVWYWx1ZShpbmRleCk7Ci0gIH0KLQotICBwdWJsaWMgYm9vbGVhbiBpc0F0dHJpYnV0ZVNwZWNpZmllZChpbnQgaW5kZXgpIHsKLSAgICByZXR1cm4gcmVhZGVyLmlzQXR0cmlidXRlU3BlY2lmaWVkKGluZGV4KTsKLSAgfQotCi0gIHB1YmxpYyBpbnQgZ2V0TmFtZXNwYWNlQ291bnQoKSB7Ci0gICAgcmV0dXJuIHJlYWRlci5nZXROYW1lc3BhY2VDb3VudCgpOwotICB9Ci0KLSAgcHVibGljIFN0cmluZyBnZXROYW1lc3BhY2VQcmVmaXgoaW50IGluZGV4KSB7Ci0gICAgcmV0dXJuIHJlYWRlci5nZXROYW1lc3BhY2VQcmVmaXgoaW5kZXgpOwotICB9Ci0KLSAgcHVibGljIFN0cmluZyBnZXROYW1lc3BhY2VVUkkoaW50IGluZGV4KSB7Ci0gICAgcmV0dXJuIHJlYWRlci5nZXROYW1lc3BhY2VVUkkoaW5kZXgpOwotICB9Ci0KLSAgcHVibGljIGludCBnZXRFdmVudFR5cGUoKSB7Ci0gICAgcmV0dXJuIHJlYWRlci5nZXRFdmVudFR5cGUoKTsKLSAgfQotCi0gIHB1YmxpYyBTdHJpbmcgZ2V0VGV4dCgpIHsKLSAgICByZXR1cm4gcmVhZGVyLmdldFRleHQoKTsKLSAgfQotCi0gIHB1YmxpYyBpbnQgZ2V0VGV4dENoYXJhY3RlcnMoaW50IHNvdXJjZVN0YXJ0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYXJbXSB0YXJnZXQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHRhcmdldFN0YXJ0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBsZW5ndGgpCi0gICAgdGhyb3dzIFhNTFN0cmVhbUV4Y2VwdGlvbiB7Ci0gICAgcmV0dXJuIHJlYWRlci5nZXRUZXh0Q2hhcmFjdGVycyhzb3VyY2VTdGFydCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldFN0YXJ0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVuZ3RoKTsKLSAgfQotCi0KLSAgcHVibGljIGNoYXJbXSBnZXRUZXh0Q2hhcmFjdGVycygpIHsKLSAgICByZXR1cm4gcmVhZGVyLmdldFRleHRDaGFyYWN0ZXJzKCk7Ci0gIH0KLQotICBwdWJsaWMgaW50IGdldFRleHRTdGFydCgpIHsKLSAgICByZXR1cm4gcmVhZGVyLmdldFRleHRTdGFydCgpOwotICB9Ci0KLSAgcHVibGljIGludCBnZXRUZXh0TGVuZ3RoKCkgewotICAgIHJldHVybiByZWFkZXIuZ2V0VGV4dExlbmd0aCgpOwotICB9Ci0KLSAgcHVibGljIFN0cmluZyBnZXRFbmNvZGluZygpIHsKLSAgICByZXR1cm4gcmVhZGVyLmdldEVuY29kaW5nKCk7Ci0gIH0KLQotICBwdWJsaWMgYm9vbGVhbiBoYXNUZXh0KCkgewotICAgIHJldHVybiByZWFkZXIuaGFzVGV4dCgpOwotICB9Ci0KLSAgcHVibGljIExvY2F0aW9uIGdldExvY2F0aW9uKCkgewotICAgIHJldHVybiByZWFkZXIuZ2V0TG9jYXRpb24oKTsKLSAgfQotCi0gIHB1YmxpYyBRTmFtZSBnZXROYW1lKCkgewotICAgIHJldHVybiByZWFkZXIuZ2V0TmFtZSgpOwotICB9Ci0KLSAgcHVibGljIFN0cmluZyBnZXRMb2NhbE5hbWUoKSB7Ci0gICAgcmV0dXJuIHJlYWRlci5nZXRMb2NhbE5hbWUoKTsKLSAgfQotCi0gIHB1YmxpYyBib29sZWFuIGhhc05hbWUoKSB7Ci0gICAgcmV0dXJuIHJlYWRlci5oYXNOYW1lKCk7Ci0gIH0KLQotICBwdWJsaWMgU3RyaW5nIGdldE5hbWVzcGFjZVVSSSgpIHsKLSAgICByZXR1cm4gcmVhZGVyLmdldE5hbWVzcGFjZVVSSSgpOwotICB9Ci0KLSAgcHVibGljIFN0cmluZyBnZXRQcmVmaXgoKSB7Ci0gICAgcmV0dXJuIHJlYWRlci5nZXRQcmVmaXgoKTsKLSAgfQotCi0gIHB1YmxpYyBTdHJpbmcgZ2V0VmVyc2lvbigpIHsKLSAgICByZXR1cm4gcmVhZGVyLmdldFZlcnNpb24oKTsKLSAgfQotCi0gIHB1YmxpYyBib29sZWFuIGlzU3RhbmRhbG9uZSgpIHsKLSAgICByZXR1cm4gcmVhZGVyLmlzU3RhbmRhbG9uZSgpOwotICB9Ci0KLSAgcHVibGljIGJvb2xlYW4gc3RhbmRhbG9uZVNldCgpIHsKLSAgICByZXR1cm4gcmVhZGVyLnN0YW5kYWxvbmVTZXQoKTsKLSAgfQotCi0gIHB1YmxpYyBTdHJpbmcgZ2V0Q2hhcmFjdGVyRW5jb2RpbmdTY2hlbWUoKSB7Ci0gICAgcmV0dXJuIHJlYWRlci5nZXRDaGFyYWN0ZXJFbmNvZGluZ1NjaGVtZSgpOwotICB9Ci0KLSAgcHVibGljIFN0cmluZyBnZXRQSVRhcmdldCgpIHsKLSAgICByZXR1cm4gcmVhZGVyLmdldFBJVGFyZ2V0KCk7Ci0gIH0KLQotICBwdWJsaWMgU3RyaW5nIGdldFBJRGF0YSgpIHsKLSAgICByZXR1cm4gcmVhZGVyLmdldFBJRGF0YSgpOwotICB9Ci0KLSAgcHVibGljIE9iamVjdCBnZXRQcm9wZXJ0eShTdHJpbmcgbmFtZSkgewotICAgIHJldHVybiByZWFkZXIuZ2V0UHJvcGVydHkobmFtZSk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9qYXZheC94bWwvc3RyZWFtL3V0aWwvWE1MRXZlbnRBbGxvY2F0b3IuamF2YSBiL3NyYy9qYXZheC94bWwvc3RyZWFtL3V0aWwvWE1MRXZlbnRBbGxvY2F0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMTFlNmU3Yy4uMDAwMDAwMAotLS0gYS9zcmMvamF2YXgveG1sL3N0cmVhbS91dGlsL1hNTEV2ZW50QWxsb2NhdG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4MiArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogQ29weXJpZ2h0IChjKSAyMDA5IGJ5IE9yYWNsZSBDb3Jwb3JhdGlvbi4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KLSAqLwotCi1wYWNrYWdlIGphdmF4LnhtbC5zdHJlYW0udXRpbDsKLQotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uZXZlbnRzLlhNTEV2ZW50OwotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uWE1MU3RyZWFtUmVhZGVyOwotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uWE1MU3RyZWFtRXhjZXB0aW9uOwotCi0vKioKLSAqIFRoaXMgaW50ZXJmYWNlIGRlZmluZXMgYSBjbGFzcyB0aGF0IGFsbG93cyBhIHVzZXIgdG8gcmVnaXN0ZXIKLSAqIGEgd2F5IHRvIGFsbG9jYXRlIGV2ZW50cyBnaXZlbiBhbiBYTUxTdHJlYW1SZWFkZXIuICBBbiBpbXBsZW1lbnRhdGlvbgotICogaXMgbm90IHJlcXVpcmVkIHRvIHVzZSB0aGUgWE1MRXZlbnRGYWN0b3J5IGltcGxlbWVudGF0aW9uIGJ1dCB0aGlzCi0gKiBpcyByZWNvbW1lbmRlZC4gIFRoZSBYTUxFdmVudEFsbG9jYXRvciBjYW4gYmUgc2V0IG9uIGFuIFhNTElucHV0RmFjdG9yeQotICogdXNpbmcgdGhlIHByb3BlcnR5ICJqYXZheC54bWwuc3RyZWFtLmFsbG9jYXRvciIKLSAqCi0gKiBAdmVyc2lvbiAxLjAKLSAqIEBhdXRob3IgQ29weXJpZ2h0IChjKSAyMDA5IGJ5IE9yYWNsZSBDb3Jwb3JhdGlvbi4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KLSAqIEBzZWUgamF2YXgueG1sLnN0cmVhbS5YTUxJbnB1dEZhY3RvcnkKLSAqIEBzZWUgamF2YXgueG1sLnN0cmVhbS5YTUxFdmVudEZhY3RvcnkKLSAqIEBzaW5jZSAxLjYKLSAqLwotcHVibGljIGludGVyZmFjZSBYTUxFdmVudEFsbG9jYXRvciB7Ci0KLSAgLyoqCi0gICAqIFRoaXMgbWV0aG9kIGNyZWF0ZXMgYW4gaW5zdGFuY2Ugb2YgdGhlIFhNTEV2ZW50QWxsb2NhdG9yLiBUaGlzCi0gICAqIGFsbG93cyB0aGUgWE1MSW5wdXRGYWN0b3J5IHRvIGFsbG9jYXRlIGEgbmV3IGluc3RhbmNlIHBlciByZWFkZXIuCi0gICAqLwotICBwdWJsaWMgWE1MRXZlbnRBbGxvY2F0b3IgbmV3SW5zdGFuY2UoKTsKLQotICAvKioKLSAgICogVGhpcyBtZXRob2QgYWxsb2NhdGVzIGFuIGV2ZW50IGdpdmVuIHRoZSBjdXJyZW50Ci0gICAqIHN0YXRlIG9mIHRoZSBYTUxTdHJlYW1SZWFkZXIuICBJZiB0aGlzIFhNTEV2ZW50QWxsb2NhdG9yCi0gICAqIGRvZXMgbm90IGhhdmUgYSBvbmUtdG8tb25lIG1hcHBpbmcgYmV0d2VlbiByZWFkZXIgc3RhdGVzCi0gICAqIGFuZCBldmVudHMgdGhpcyBtZXRob2Qgd2lsbCByZXR1cm4gbnVsbC4gIFRoaXMgbWV0aG9kCi0gICAqIG11c3Qgbm90IG1vZGlmeSB0aGUgc3RhdGUgb2YgdGhlIFhNTFN0cmVhbVJlYWRlci4KLSAgICogQHBhcmFtIHJlYWRlciBUaGUgWE1MU3RyZWFtUmVhZGVyIHRvIGFsbG9jYXRlIGZyb20KLSAgICogQHJldHVybiB0aGUgZXZlbnQgY29ycmVzcG9uZGluZyB0byB0aGUgY3VycmVudCByZWFkZXIgc3RhdGUKLSAgICovCi0gIHB1YmxpYyBYTUxFdmVudCBhbGxvY2F0ZShYTUxTdHJlYW1SZWFkZXIgcmVhZGVyKQotICAgIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb247Ci0KLSAgLyoqCi0gICAqIFRoaXMgbWV0aG9kIGFsbG9jYXRlcyBhbiBldmVudCBvciBzZXQgb2YgZXZlbnRzCi0gICAqIGdpdmVuIHRoZSBjdXJyZW50Ci0gICAqIHN0YXRlIG9mIHRoZSBYTUxTdHJlYW1SZWFkZXIgYW5kIGFkZHMgdGhlIGV2ZW50Ci0gICAqIG9yIHNldCBvZiBldmVudHMgdG8gdGhlCi0gICAqIGNvbnN1bWVyIHRoYXQgd2FzIHBhc3NlZCBpbi4gIFRoaXMgbWV0aG9kIGNhbiBiZSB1c2VkCi0gICAqIHRvIGV4cGFuZCBvciBjb250cmFjdCByZWFkZXIgc3RhdGVzIGludG8gZXZlbnQgc3RhdGVzLgotICAgKiBUaGlzIG1ldGhvZCBtYXkgbW9kaWZ5IHRoZSBzdGF0ZSBvZiB0aGUgWE1MU3RyZWFtUmVhZGVyLgotICAgKiBAcGFyYW0gcmVhZGVyIFRoZSBYTUxTdHJlYW1SZWFkZXIgdG8gYWxsb2NhdGUgZnJvbQotICAgKiBAcGFyYW0gY29uc3VtZXIgVGhlIFhNTEV2ZW50Q29uc3VtZXIgdG8gYWRkIHRvLgotICAgKi8KLSAgcHVibGljIHZvaWQgYWxsb2NhdGUoWE1MU3RyZWFtUmVhZGVyIHJlYWRlciwgWE1MRXZlbnRDb25zdW1lciBjb25zdW1lcikKLSAgICB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uOwotCi19CmRpZmYgLS1naXQgYS9zcmMvamF2YXgveG1sL3N0cmVhbS91dGlsL1hNTEV2ZW50Q29uc3VtZXIuamF2YSBiL3NyYy9qYXZheC94bWwvc3RyZWFtL3V0aWwvWE1MRXZlbnRDb25zdW1lci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwNjJmNzA2Li4wMDAwMDAwCi0tLSBhL3NyYy9qYXZheC94bWwvc3RyZWFtL3V0aWwvWE1MRXZlbnRDb25zdW1lci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTggKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwOSBieSBPcmFjbGUgQ29ycG9yYXRpb24uIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCi0gKi8KLQotcGFja2FnZSBqYXZheC54bWwuc3RyZWFtLnV0aWw7Ci0KLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLmV2ZW50cy5YTUxFdmVudDsKLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLlhNTFN0cmVhbUV4Y2VwdGlvbjsKLQotLyoqCi0gKiBUaGlzIGludGVyZmFjZSBkZWZpbmVzIGFuIGV2ZW50IGNvbnN1bWVyIGludGVyZmFjZS4gIFRoZSBjb250cmFjdCBvZiB0aGUKLSAqIG9mIGEgY29uc3VtZXIgaXMgdG8gYWNjZXB0IHRoZSBldmVudC4gIFRoaXMgaW50ZXJmYWNlIGNhbiBiZSB1c2VkIHRvCi0gKiBtYXJrIGFuIG9iamVjdCBhcyBhYmxlIHRvIHJlY2VpdmUgZXZlbnRzLiAgQWRkIG1heSBiZSBjYWxsZWQgc2V2ZXJhbAotICogdGltZXMgaW4gaW1tZWRpYXRlIHN1Y2Nlc3Npb24gc28gYSBjb25zdW1lciBtdXN0IGJlIGFibGUgdG8gY2FjaGUKLSAqIGV2ZW50cyBpdCBoYXNuJ3QgcHJvY2Vzc2VkIHlldC4KLSAqCi0gKiBAdmVyc2lvbiAxLjAKLSAqIEBhdXRob3IgQ29weXJpZ2h0IChjKSAyMDA5IGJ5IE9yYWNsZSBDb3Jwb3JhdGlvbi4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KLSAqIEBzaW5jZSAxLjYKLSAqLwotcHVibGljIGludGVyZmFjZSBYTUxFdmVudENvbnN1bWVyIHsKLQotICAvKioKLSAgICogVGhpcyBtZXRob2QgYWRkcyBhbiBldmVudCB0byB0aGUgY29uc3VtZXIuIENhbGxpbmcgdGhpcyBtZXRob2QKLSAgICogaW52YWxpZGF0ZXMgdGhlIGV2ZW50IHBhcmFtZXRlci4gVGhlIGNsaWVudCBhcHBsaWNhdGlvbiBzaG91bGQKLSAgICogZGlzY2FyZCBhbGwgcmVmZXJlbmNlcyB0byB0aGlzIGV2ZW50IHVwb24gY2FsbGluZyBhZGQuCi0gICAqIFRoZSBiZWhhdmlvciBvZiBhbiBhcHBsaWNhdGlvbiB0aGF0IGNvbnRpbnVlcyB0byB1c2Ugc3VjaCByZWZlcmVuY2VzCi0gICAqIGlzIHVuZGVmaW5lZC4KLSAgICoKLSAgICogQHBhcmFtIGV2ZW50IHRoZSBldmVudCB0byBhZGQsIG1heSBub3QgYmUgbnVsbAotICAgKi8KLSAgcHVibGljIHZvaWQgYWRkKFhNTEV2ZW50IGV2ZW50KQotICAgIHRocm93cyBYTUxTdHJlYW1FeGNlcHRpb247Ci19CmRpZmYgLS1naXQgYS9zcmMvamF2YXgveG1sL3RyYW5zZm9ybS9FcnJvckxpc3RlbmVyLmphdmEgYi9zcmMvamF2YXgveG1sL3RyYW5zZm9ybS9FcnJvckxpc3RlbmVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGJjMjg4MjMuLjAwMDAwMDAKLS0tIGEvc3JjL2phdmF4L3htbC90cmFuc2Zvcm0vRXJyb3JMaXN0ZW5lci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTE3ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDAsIDIwMDUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLXBhY2thZ2UgamF2YXgueG1sLnRyYW5zZm9ybTsKLQotLyoqCi0gKiA8cD5UbyBwcm92aWRlIGN1c3RvbWl6ZWQgZXJyb3IgaGFuZGxpbmcsIGltcGxlbWVudCB0aGlzIGludGVyZmFjZSBhbmQKLSAqIHVzZSB0aGUgPGNvZGU+c2V0RXJyb3JMaXN0ZW5lcjwvY29kZT4gbWV0aG9kIHRvIHJlZ2lzdGVyIGFuIGluc3RhbmNlIG9mIHRoZQotICogaW1wbG1lbnRhdGlvbiB3aXRoIHRoZSB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lcn0uICBUaGUKLSAqIDxjb2RlPlRyYW5zZm9ybWVyPC9jb2RlPiB0aGVuIHJlcG9ydHMgYWxsIGVycm9ycyBhbmQgd2FybmluZ3MgdGhyb3VnaCB0aGlzCi0gKiBpbnRlcmZhY2UuPC9wPgotICoKLSAqIDxwPklmIGFuIGFwcGxpY2F0aW9uIGRvZXMgPGVtPm5vdDwvZW0+IHJlZ2lzdGVyIGl0cyBvd24gY3VzdG9tCi0gKiA8Y29kZT5FcnJvckxpc3RlbmVyPC9jb2RlPiwgdGhlIGRlZmF1bHQgPGNvZGU+RXJyb3JMaXN0ZW5lcjwvY29kZT4KLSAqIGlzIHVzZWQgd2hpY2ggcmVwb3J0cyBhbGwgd2FybmluZ3MgYW5kIGVycm9ycyB0byA8Y29kZT5TeXN0ZW0uZXJyPC9jb2RlPgotICogYW5kIGRvZXMgbm90IHRocm93IGFueSA8Y29kZT5FeGNlcHRpb248L2NvZGU+cy4KLSAqIEFwcGxpY2F0aW9ucyBhcmUgPGVtPnN0cm9uZ2x5PC9lbT4gZW5jb3VyYWdlZCB0byByZWdpc3RlciBhbmQgdXNlCi0gKiA8Y29kZT5FcnJvckxpc3RlbmVyPC9jb2RlPnMgdGhhdCBpbnN1cmUgcHJvcGVyIGJlaGF2aW9yIGZvciB3YXJuaW5ncyBhbmQKLSAqIGVycm9ycy48L3A+Ci0gKgotICogPHA+Rm9yIHRyYW5zZm9ybWF0aW9uIGVycm9ycywgYSA8Y29kZT5UcmFuc2Zvcm1lcjwvY29kZT4gbXVzdCB1c2UgdGhpcwotICogaW50ZXJmYWNlIGluc3RlYWQgb2YgdGhyb3dpbmcgYW4gPGNvZGU+RXhjZXB0aW9uPC9jb2RlPjogaXQgaXMgdXAgdG8gdGhlCi0gKiBhcHBsaWNhdGlvbiB0byBkZWNpZGUgd2hldGhlciB0byB0aHJvdyBhbiA8Y29kZT5FeGNlcHRpb248L2NvZGU+IGZvcgotICogZGlmZmVyZW50IHR5cGVzIG9mIGVycm9ycyBhbmQgd2FybmluZ3MuICBOb3RlIGhvd2V2ZXIgdGhhdCB0aGUKLSAqIDxjb2RlPlRyYW5zZm9ybWVyPC9jb2RlPiBpcyBub3QgcmVxdWlyZWQgdG8gY29udGludWUgd2l0aCB0aGUgdHJhbnNmb3JtYXRpb24KLSAqIGFmdGVyIGEgY2FsbCB0byB7QGxpbmsgI2ZhdGFsRXJyb3IoVHJhbnNmb3JtZXJFeGNlcHRpb24gZXhjZXB0aW9uKX0uPC9wPgotICoKLSAqIDxwPjxjb2RlPlRyYW5zZm9ybWVyPC9jb2RlPnMgbWF5IHVzZSB0aGlzIG1lY2hhbmlzbSB0byByZXBvcnQgWE1MIHBhcnNpbmcKLSAqIGVycm9ycyBhcyB3ZWxsIGFzIHRyYW5zZm9ybWF0aW9uIGVycm9ycy48L3A+Ci0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgRXJyb3JMaXN0ZW5lciB7Ci0KLSAgICAvKioKLSAgICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBhIHdhcm5pbmcuCi0gICAgICoKLSAgICAgKiA8cD57QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lcn0gY2FuIHVzZSB0aGlzIG1ldGhvZCB0byByZXBvcnQKLSAgICAgKiBjb25kaXRpb25zIHRoYXQgYXJlIG5vdCBlcnJvcnMgb3IgZmF0YWwgZXJyb3JzLiAgVGhlIGRlZmF1bHQgYmVoYXZpb3VyCi0gICAgICogaXMgdG8gdGFrZSBubyBhY3Rpb24uPC9wPgotICAgICAqCi0gICAgICogPHA+QWZ0ZXIgaW52b2tpbmcgdGhpcyBtZXRob2QsIHRoZSBUcmFuc2Zvcm1lciBtdXN0IGNvbnRpbnVlIHdpdGgKLSAgICAgKiB0aGUgdHJhbnNmb3JtYXRpb24uIEl0IHNob3VsZCBzdGlsbCBiZSBwb3NzaWJsZSBmb3IgdGhlCi0gICAgICogYXBwbGljYXRpb24gdG8gcHJvY2VzcyB0aGUgZG9jdW1lbnQgdGhyb3VnaCB0byB0aGUgZW5kLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBleGNlcHRpb24gVGhlIHdhcm5pbmcgaW5mb3JtYXRpb24gZW5jYXBzdWxhdGVkIGluIGEKLSAgICAgKiAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybWVyIGV4Y2VwdGlvbi4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbiBpZiB0aGUgYXBwbGljYXRpb24KLSAgICAgKiBjaG9vc2VzIHRvIGRpc2NvbnRpbnVlIHRoZSB0cmFuc2Zvcm1hdGlvbi4KLSAgICAgKgotICAgICAqIEBzZWUgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHdhcm5pbmcoVHJhbnNmb3JtZXJFeGNlcHRpb24gZXhjZXB0aW9uKQotICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBhIHJlY292ZXJhYmxlIGVycm9yLgotICAgICAqCi0gICAgICogPHA+VGhlIHRyYW5zZm9ybWVyIG11c3QgY29udGludWUgdG8gdHJ5IGFuZCBwcm92aWRlIG5vcm1hbCB0cmFuc2Zvcm1hdGlvbgotICAgICAqIGFmdGVyIGludm9raW5nIHRoaXMgbWV0aG9kLiAgSXQgc2hvdWxkIHN0aWxsIGJlIHBvc3NpYmxlIGZvciB0aGUKLSAgICAgKiBhcHBsaWNhdGlvbiB0byBwcm9jZXNzIHRoZSBkb2N1bWVudCB0aHJvdWdoIHRvIHRoZSBlbmQgaWYgbm8gb3RoZXIgZXJyb3JzCi0gICAgICogYXJlIGVuY291bnRlcmVkLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBleGNlcHRpb24gVGhlIGVycm9yIGluZm9ybWF0aW9uIGVuY2Fwc3VsYXRlZCBpbiBhCi0gICAgICogICAgICAgICAgICAgICAgICB0cmFuc2Zvcm1lciBleGNlcHRpb24uCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24gaWYgdGhlIGFwcGxpY2F0aW9uCi0gICAgICogY2hvb3NlcyB0byBkaXNjb250aW51ZSB0aGUgdHJhbnNmb3JtYXRpb24uCi0gICAgICoKLSAgICAgKiBAc2VlIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBlcnJvcihUcmFuc2Zvcm1lckV4Y2VwdGlvbiBleGNlcHRpb24pCi0gICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIDxwPlJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGEgbm9uLXJlY292ZXJhYmxlIGVycm9yLjwvcD4KLSAgICAgKgotICAgICAqIDxwPlRoZSBwcm9jZXNzb3IgbWF5IGNob29zZSB0byBjb250aW51ZSwgYnV0IHdpbGwgbm90IG5vcm1hbGx5Ci0gICAgICogcHJvY2VlZCB0byBhIHN1Y2Nlc3NmdWwgY29tcGxldGlvbi48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5UaGUgbWV0aG9kIHNob3VsZCB0aHJvdyBhbiBleGNlcHRpb24gaWYgaXQgaXMgdW5hYmxlIHRvCi0gICAgICogcHJvY2VzcyB0aGUgZXJyb3IsIG9yIGlmIGl0IHdpc2hlcyBleGVjdXRpb24gdG8gdGVybWluYXRlCi0gICAgICogaW1tZWRpYXRlbHkuIFRoZSBwcm9jZXNzb3Igd2lsbCBub3QgbmVjZXNzYXJpbHkgaG9ub3IgdGhpcwotICAgICAqIHJlcXVlc3QuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGV4Y2VwdGlvbiBUaGUgZXJyb3IgaW5mb3JtYXRpb24gZW5jYXBzdWxhdGVkIGluIGEKLSAgICAgKiAgICA8Y29kZT5UcmFuc2Zvcm1lckV4Y2VwdGlvbjwvY29kZT4uCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24gaWYgdGhlIGFwcGxpY2F0aW9uCi0gICAgICogY2hvb3NlcyB0byBkaXNjb250aW51ZSB0aGUgdHJhbnNmb3JtYXRpb24uCi0gICAgICoKLSAgICAgKiBAc2VlIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBmYXRhbEVycm9yKFRyYW5zZm9ybWVyRXhjZXB0aW9uIGV4Y2VwdGlvbikKLSAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uOwotfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmF4L3htbC90cmFuc2Zvcm0vRmFjdG9yeUZpbmRlci5qYXZhIGIvc3JjL2phdmF4L3htbC90cmFuc2Zvcm0vRmFjdG9yeUZpbmRlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0YWU2NTY4Li4wMDAwMDAwCi0tLSBhL3NyYy9qYXZheC94bWwvdHJhbnNmb3JtL0ZhY3RvcnlGaW5kZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDM0OSArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDEzLCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi1wYWNrYWdlIGphdmF4LnhtbC50cmFuc2Zvcm07Ci0KLWltcG9ydCBqYXZhLmlvLkZpbGU7Ci1pbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kOwotaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lk1vZGlmaWVyOwotaW1wb3J0IGphdmEuc2VjdXJpdHkuQWNjZXNzQ29udHJvbGxlcjsKLWltcG9ydCBqYXZhLnNlY3VyaXR5LlByaXZpbGVnZWRBY3Rpb247Ci1pbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOwotaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0aWVzOwotaW1wb3J0IGphdmEudXRpbC5TZXJ2aWNlQ29uZmlndXJhdGlvbkVycm9yOwotaW1wb3J0IGphdmEudXRpbC5TZXJ2aWNlTG9hZGVyOwotCi0vKioKLSAqIDxwPkltcGxlbWVudHMgcGx1Z2dhYmxlIERhdGF0eXBlcy48L3A+Ci0gKgotICogPHA+VGhpcyBjbGFzcyBpcyBkdXBsaWNhdGVkIGZvciBlYWNoIEpBWFAgc3VicGFja2FnZSBzbyBrZWVwIGl0IGluCi0gKiBzeW5jLiAgSXQgaXMgcGFja2FnZSBwcml2YXRlIGZvciBzZWN1cmUgY2xhc3MgbG9hZGluZy48L3A+Ci0gKgotICogQGF1dGhvciBTYW50aWFnby5QZXJpY2FzR2VlcnRzZW5Ac3VuLmNvbQotICogQGF1dGhvciBIdWl6aGUuV2FuZ0BvcmFjbGUuY29tCi0gKi8KLWNsYXNzIEZhY3RvcnlGaW5kZXIgewotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBERUZBVUxUX1BBQ0tBR0UgPSAiY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLiI7Ci0KLSAgICAvKioKLSAgICAgKiBJbnRlcm5hbCBkZWJ1ZyBmbGFnLgotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gZGVidWcgPSBmYWxzZTsKLQotICAgIC8qKgotICAgICAqIENhY2hlIGZvciBwcm9wZXJ0aWVzIGluIGphdmEuaG9tZS9saWIvamF4cC5wcm9wZXJ0aWVzCi0gICAgICovCi0gICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgUHJvcGVydGllcyBjYWNoZVByb3BzID0gbmV3IFByb3BlcnRpZXMoKTsKLQotICAgIC8qKgotICAgICAqIEZsYWcgaW5kaWNhdGluZyBpZiBwcm9wZXJ0aWVzIGZyb20gamF2YS5ob21lL2xpYi9qYXhwLnByb3BlcnRpZXMKLSAgICAgKiBoYXZlIGJlZW4gY2FjaGVkLgotICAgICAqLwotICAgIHN0YXRpYyB2b2xhdGlsZSBib29sZWFuIGZpcnN0VGltZSA9IHRydWU7Ci0KLSAgICAvKioKLSAgICAgKiBTZWN1cml0eSBzdXBwb3J0IGNsYXNzIHVzZSB0byBjaGVjayBhY2Nlc3MgY29udHJvbCBiZWZvcmUKLSAgICAgKiBnZXR0aW5nIGNlcnRhaW4gc3lzdGVtIHJlc291cmNlcy4KLSAgICAgKi8KLSAgICBwcml2YXRlIGZpbmFsIHN0YXRpYyBTZWN1cml0eVN1cHBvcnQgc3MgPSBuZXcgU2VjdXJpdHlTdXBwb3J0KCk7Ci0KLSAgICAvLyBEZWZpbmUgc3lzdGVtIHByb3BlcnR5ICJqYXhwLmRlYnVnIiB0byBnZXQgb3V0cHV0Ci0gICAgc3RhdGljIHsKLSAgICAgICAgLy8gVXNlIHRyeS9jYXRjaCBibG9jayB0byBzdXBwb3J0IGFwcGxldHMsIHdoaWNoIHRocm93cwotICAgICAgICAvLyBTZWN1cml0eUV4Y2VwdGlvbiBvdXQgb2YgdGhpcyBjb2RlLgotICAgICAgICB0cnkgewotICAgICAgICAgICAgU3RyaW5nIHZhbCA9IHNzLmdldFN5c3RlbVByb3BlcnR5KCJqYXhwLmRlYnVnIik7Ci0gICAgICAgICAgICAvLyBBbGxvdyBzaW1wbHkgc2V0dGluZyB0aGUgcHJvcCB0byB0dXJuIG9uIGRlYnVnCi0gICAgICAgICAgICBkZWJ1ZyA9IHZhbCAhPSBudWxsICYmICEiZmFsc2UiLmVxdWFscyh2YWwpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBzZSkgewotICAgICAgICAgICAgZGVidWcgPSBmYWxzZTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHByaXZhdGUgc3RhdGljIHZvaWQgZFByaW50KFN0cmluZyBtc2cpIHsKLSAgICAgICAgaWYgKGRlYnVnKSB7Ci0gICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIkpBWFA6ICIgKyBtc2cpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQXR0ZW1wdCB0byBsb2FkIGEgY2xhc3MgdXNpbmcgdGhlIGNsYXNzIGxvYWRlciBzdXBwbGllZC4gSWYgdGhhdCBmYWlscwotICAgICAqIGFuZCBmYWxsIGJhY2sgaXMgZW5hYmxlZCwgdGhlIGN1cnJlbnQgKGkuZS4gYm9vdHN0cmFwKSBjbGFzcyBsb2FkZXIgaXMKLSAgICAgKiB0cmllZC4KLSAgICAgKgotICAgICAqIElmIHRoZSBjbGFzcyBsb2FkZXIgc3VwcGxpZWQgaXMgPGNvZGU+bnVsbDwvY29kZT4sIGZpcnN0IHRyeSB1c2luZyB0aGUKLSAgICAgKiBjb250ZXh0IGNsYXNzIGxvYWRlciBmb2xsb3dlZCBieSB0aGUgY3VycmVudCAoaS5lLiBib290c3RyYXApIGNsYXNzCi0gICAgICogbG9hZGVyLgotICAgICAqCi0gICAgICogVXNlIGJvb3RzdHJhcCBjbGFzc0xvYWRlciBpZiBjbCA9IG51bGwgYW5kIHVzZUJTQ2xzTG9hZGVyIGlzIHRydWUKLSAgICAgKi8KLSAgICBzdGF0aWMgcHJpdmF0ZSBDbGFzczw/PiBnZXRQcm92aWRlckNsYXNzKFN0cmluZyBjbGFzc05hbWUsIENsYXNzTG9hZGVyIGNsLAotICAgICAgICAgICAgYm9vbGVhbiBkb0ZhbGxiYWNrLCBib29sZWFuIHVzZUJTQ2xzTG9hZGVyKSB0aHJvd3MgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGlmIChjbCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgaWYgKHVzZUJTQ2xzTG9hZGVyKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBDbGFzcy5mb3JOYW1lKGNsYXNzTmFtZSwgZmFsc2UsIEZhY3RvcnlGaW5kZXIuY2xhc3MuZ2V0Q2xhc3NMb2FkZXIoKSk7Ci0gICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgY2wgPSBzcy5nZXRDb250ZXh0Q2xhc3NMb2FkZXIoKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGNsID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uKCk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gQ2xhc3MuZm9yTmFtZShjbGFzc05hbWUsIGZhbHNlLCBjbCk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gQ2xhc3MuZm9yTmFtZShjbGFzc05hbWUsIGZhbHNlLCBjbCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gZTEpIHsKLSAgICAgICAgICAgIGlmIChkb0ZhbGxiYWNrKSB7Ci0gICAgICAgICAgICAgICAgLy8gVXNlIGN1cnJlbnQgY2xhc3MgbG9hZGVyIC0gc2hvdWxkIGFsd2F5cyBiZSBib290c3RyYXAgQ0wKLSAgICAgICAgICAgICAgICByZXR1cm4gQ2xhc3MuZm9yTmFtZShjbGFzc05hbWUsIGZhbHNlLCBGYWN0b3J5RmluZGVyLmNsYXNzLmdldENsYXNzTG9hZGVyKCkpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgZTE7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGUgYW4gaW5zdGFuY2Ugb2YgYSBjbGFzcy4gRGVsZWdhdGVzIHRvIG1ldGhvZAotICAgICAqIDxjb2RlPmdldFByb3ZpZGVyQ2xhc3MoKTwvY29kZT4gaW4gb3JkZXIgdG8gbG9hZCB0aGUgY2xhc3MuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdHlwZSBCYXNlIGNsYXNzIC8gU2VydmljZSBpbnRlcmZhY2UgIG9mIHRoZSBmYWN0b3J5IHRvCi0gICAgICogICAgICAgICAgICAgaW5zdGFudGlhdGUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY2xhc3NOYW1lIE5hbWUgb2YgdGhlIGNvbmNyZXRlIGNsYXNzIGNvcnJlc3BvbmRpbmcgdG8gdGhlCi0gICAgICogc2VydmljZSBwcm92aWRlcgotICAgICAqCi0gICAgICogQHBhcmFtIGNsIDxjb2RlPkNsYXNzTG9hZGVyPC9jb2RlPiB1c2VkIHRvIGxvYWQgdGhlIGZhY3RvcnkgY2xhc3MuIElmIDxjb2RlPm51bGw8L2NvZGU+Ci0gICAgICogY3VycmVudCA8Y29kZT5UaHJlYWQ8L2NvZGU+J3MgY29udGV4dCBjbGFzc0xvYWRlciBpcyB1c2VkIHRvIGxvYWQgdGhlIGZhY3RvcnkgY2xhc3MuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZG9GYWxsYmFjayBUcnVlIGlmIHRoZSBjdXJyZW50IENsYXNzTG9hZGVyIHNob3VsZCBiZSB0cmllZCBhcwotICAgICAqIGEgZmFsbGJhY2sgaWYgdGhlIGNsYXNzIGlzIG5vdCBmb3VuZCB1c2luZyBjbAotICAgICAqCi0gICAgICogQHBhcmFtIHVzZVNlcnZpY2VzTWVjaGFuaXNtIFRydWUgdXNlIHNlcnZpY2VzIG1lY2hhbmlzbQotICAgICAqLwotICAgIHN0YXRpYyA8VD4gVCBuZXdJbnN0YW5jZShDbGFzczxUPiB0eXBlLCBTdHJpbmcgY2xhc3NOYW1lLCBDbGFzc0xvYWRlciBjbCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBkb0ZhbGxiYWNrLCBib29sZWFuIHVzZVNlcnZpY2VzTWVjaGFuaXNtKQotICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yCi0gICAgewotICAgICAgICBhc3NlcnQgdHlwZSAhPSBudWxsOwotCi0gICAgICAgIGJvb2xlYW4gdXNlQlNDbHNMb2FkZXIgPSBmYWxzZTsKLSAgICAgICAgLy8gbWFrZSBzdXJlIHdlIGhhdmUgYWNjZXNzIHRvIHJlc3RyaWN0ZWQgcGFja2FnZXMKLSAgICAgICAgaWYgKFN5c3RlbS5nZXRTZWN1cml0eU1hbmFnZXIoKSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAoY2xhc3NOYW1lICE9IG51bGwgJiYgY2xhc3NOYW1lLnN0YXJ0c1dpdGgoREVGQVVMVF9QQUNLQUdFKSkgewotICAgICAgICAgICAgICAgIGNsID0gbnVsbDsKLSAgICAgICAgICAgICAgICB1c2VCU0Nsc0xvYWRlciA9IHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICB0cnkgewotICAgICAgICAgICAgQ2xhc3M8Pz4gcHJvdmlkZXJDbGFzcyA9IGdldFByb3ZpZGVyQ2xhc3MoY2xhc3NOYW1lLCBjbCwgZG9GYWxsYmFjaywgdXNlQlNDbHNMb2FkZXIpOwotICAgICAgICAgICAgaWYgKCF0eXBlLmlzQXNzaWduYWJsZUZyb20ocHJvdmlkZXJDbGFzcykpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2xhc3NDYXN0RXhjZXB0aW9uKGNsYXNzTmFtZSArICIgY2Fubm90IGJlIGNhc3QgdG8gIiArIHR5cGUuZ2V0TmFtZSgpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIE9iamVjdCBpbnN0YW5jZSA9IG51bGw7Ci0gICAgICAgICAgICBpZiAoIXVzZVNlcnZpY2VzTWVjaGFuaXNtKSB7Ci0gICAgICAgICAgICAgICAgaW5zdGFuY2UgPSBuZXdJbnN0YW5jZU5vU2VydmljZUxvYWRlcih0eXBlLCBwcm92aWRlckNsYXNzKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChpbnN0YW5jZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgaW5zdGFuY2UgPSBwcm92aWRlckNsYXNzLm5ld0luc3RhbmNlKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoZGVidWcpIHsgICAgLy8gRXh0cmEgY2hlY2sgdG8gYXZvaWQgY29tcHV0aW5nIGNsIHN0cmluZ3MKLSAgICAgICAgICAgICAgICBkUHJpbnQoImNyZWF0ZWQgbmV3IGluc3RhbmNlIG9mICIgKyBwcm92aWRlckNsYXNzICsKLSAgICAgICAgICAgICAgICAgICAgICAgIiB1c2luZyBDbGFzc0xvYWRlcjogIiArIGNsKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiB0eXBlLmNhc3QoaW5zdGFuY2UpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHgpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IoeCwKLSAgICAgICAgICAgICAgICAiUHJvdmlkZXIgIiArIGNsYXNzTmFtZSArICIgbm90IGZvdW5kIik7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiB4KSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yKHgsCi0gICAgICAgICAgICAgICAgIlByb3ZpZGVyICIgKyBjbGFzc05hbWUgKyAiIGNvdWxkIG5vdCBiZSBpbnN0YW50aWF0ZWQ6ICIgKyB4KTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyeSB0byBjb25zdHJ1Y3QgdXNpbmcgbmV3VHJhbnNmb3JtZXJGYWN0b3J5Tm9TZXJ2aWNlTG9hZGVyCi0gICAgICogICBtZXRob2QgaWYgYXZhaWxhYmxlLgotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIDxUPiBUIG5ld0luc3RhbmNlTm9TZXJ2aWNlTG9hZGVyKENsYXNzPFQ+IHR5cGUsIENsYXNzPD8+IHByb3ZpZGVyQ2xhc3MpIHsKLSAgICAgICAgLy8gUmV0YWluIG1heGltdW0gY29tcGF0aWJpbGl0eSBpZiBubyBzZWN1cml0eSBtYW5hZ2VyLgotICAgICAgICBpZiAoU3lzdGVtLmdldFNlY3VyaXR5TWFuYWdlcigpID09IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBmaW5hbCBNZXRob2QgY3JlYXRpb25NZXRob2QgPQotICAgICAgICAgICAgICAgICAgICBwcm92aWRlckNsYXNzLmdldERlY2xhcmVkTWV0aG9kKAotICAgICAgICAgICAgICAgICAgICAgICAgIm5ld1RyYW5zZm9ybWVyRmFjdG9yeU5vU2VydmljZUxvYWRlciIKLSAgICAgICAgICAgICAgICAgICAgKTsKLSAgICAgICAgICAgIGZpbmFsIGludCBtb2RpZmllcnMgPSBjcmVhdGlvbk1ldGhvZC5nZXRNb2RpZmllcnMoKTsKLQotICAgICAgICAgICAgLy8gRG8gbm90IGNhbGwgdGhlIG1ldGhvZCBpZiBpdCdzIG5vdCBwdWJsaWMgc3RhdGljLgotICAgICAgICAgICAgaWYgKCFNb2RpZmllci5pc1B1YmxpYyhtb2RpZmllcnMpIHx8ICFNb2RpZmllci5pc1N0YXRpYyhtb2RpZmllcnMpKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIE9ubHkgY2FsbCB0aGUgbWV0aG9kIGlmIGl0J3MgZGVjbGFyZWQgdG8gcmV0dXJuIGFuIGluc3RhbmNlIG9mCi0gICAgICAgICAgICAvLyBUcmFuc2Zvcm1lckZhY3RvcnkKLSAgICAgICAgICAgIGZpbmFsIENsYXNzPD8+IHJldHVyblR5cGUgPSBjcmVhdGlvbk1ldGhvZC5nZXRSZXR1cm5UeXBlKCk7Ci0gICAgICAgICAgICBpZiAodHlwZS5pc0Fzc2lnbmFibGVGcm9tKHJldHVyblR5cGUpKSB7Ci0gICAgICAgICAgICAgICAgZmluYWwgT2JqZWN0IHJlc3VsdCA9IGNyZWF0aW9uTWV0aG9kLmludm9rZShudWxsLCAoT2JqZWN0W10pbnVsbCk7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHR5cGUuY2FzdChyZXN1bHQpOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAvLyBUaGlzIHNob3VsZCBub3QgaGFwcGVuLCBhcwotICAgICAgICAgICAgICAgIC8vIFRyYW5zZm9ybWVyRmFjdG9yeUltcGwubmV3VHJhbnNmb3JtZXJGYWN0b3J5Tm9TZXJ2aWNlTG9hZGVyIGlzCi0gICAgICAgICAgICAgICAgLy8gZGVjbGFyZWQgdG8gcmV0dXJuIFRyYW5zZm9ybWVyRmFjdG9yeS4KLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2xhc3NDYXN0RXhjZXB0aW9uKHJldHVyblR5cGUgKyAiIGNhbm5vdCBiZSBjYXN0IHRvICIgKyB0eXBlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IoZSwgZS5nZXRNZXNzYWdlKCkpOwotICAgICAgICB9IGNhdGNoIChOb1N1Y2hNZXRob2RFeGNlcHRpb24gZXhjKSB7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4YykgewotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBGaW5kcyB0aGUgaW1wbGVtZW50YXRpb24gQ2xhc3Mgb2JqZWN0IGluIHRoZSBzcGVjaWZpZWQgb3JkZXIuICBNYWluCi0gICAgICogZW50cnkgcG9pbnQuCi0gICAgICogQHJldHVybiBDbGFzcyBvYmplY3Qgb2YgZmFjdG9yeSwgbmV2ZXIgbnVsbAotICAgICAqCi0gICAgICogQHBhcmFtIHR5cGUgICAgICAgICAgICAgICAgICBCYXNlIGNsYXNzIC8gU2VydmljZSBpbnRlcmZhY2UgIG9mIHRoZQotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFjdG9yeSB0byBmaW5kLgotICAgICAqCi0gICAgICogQHBhcmFtIGZhbGxiYWNrQ2xhc3NOYW1lICAgICBJbXBsZW1lbnRhdGlvbiBjbGFzcyBuYW1lLCBpZiBub3RoaW5nIGVsc2UKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzIGZvdW5kLiAgVXNlIG51bGwgdG8gbWVhbiBubyBmYWxsYmFjay4KLSAgICAgKgotICAgICAqIFBhY2thZ2UgcHJpdmF0ZSBzbyB0aGlzIGNvZGUgY2FuIGJlIHNoYXJlZC4KLSAgICAgKi8KLSAgICBzdGF0aWMgPFQ+IFQgZmluZChDbGFzczxUPiB0eXBlLCBTdHJpbmcgZmFsbGJhY2tDbGFzc05hbWUpCi0gICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IKLSAgICB7Ci0gICAgICAgIGFzc2VydCB0eXBlICE9IG51bGw7Ci0KLSAgICAgICAgZmluYWwgU3RyaW5nIGZhY3RvcnlJZCA9IHR5cGUuZ2V0TmFtZSgpOwotCi0gICAgICAgIGRQcmludCgiZmluZCBmYWN0b3J5SWQgPSIgKyBmYWN0b3J5SWQpOwotICAgICAgICAvLyBVc2UgdGhlIHN5c3RlbSBwcm9wZXJ0eSBmaXJzdAotICAgICAgICB0cnkgewotICAgICAgICAgICAgU3RyaW5nIHN5c3RlbVByb3AgPSBzcy5nZXRTeXN0ZW1Qcm9wZXJ0eShmYWN0b3J5SWQpOwotICAgICAgICAgICAgaWYgKHN5c3RlbVByb3AgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGRQcmludCgiZm91bmQgc3lzdGVtIHByb3BlcnR5LCB2YWx1ZT0iICsgc3lzdGVtUHJvcCk7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIG5ld0luc3RhbmNlKHR5cGUsIHN5c3RlbVByb3AsIG51bGwsIHRydWUsIHRydWUpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBzZSkgewotICAgICAgICAgICAgaWYgKGRlYnVnKSBzZS5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIHRyeSB0byByZWFkIGZyb20gJGphdmEuaG9tZS9saWIvamF4cC5wcm9wZXJ0aWVzCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBpZiAoZmlyc3RUaW1lKSB7Ci0gICAgICAgICAgICAgICAgc3luY2hyb25pemVkIChjYWNoZVByb3BzKSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChmaXJzdFRpbWUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBjb25maWdGaWxlID0gc3MuZ2V0U3lzdGVtUHJvcGVydHkoImphdmEuaG9tZSIpICsgRmlsZS5zZXBhcmF0b3IgKwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICJsaWIiICsgRmlsZS5zZXBhcmF0b3IgKyAiamF4cC5wcm9wZXJ0aWVzIjsKLSAgICAgICAgICAgICAgICAgICAgICAgIEZpbGUgZiA9IG5ldyBGaWxlKGNvbmZpZ0ZpbGUpOwotICAgICAgICAgICAgICAgICAgICAgICAgZmlyc3RUaW1lID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3MuZG9lc0ZpbGVFeGlzdChmKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRQcmludCgiUmVhZCBwcm9wZXJ0aWVzIGZpbGUgIitmKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWNoZVByb3BzLmxvYWQoc3MuZ2V0RmlsZUlucHV0U3RyZWFtKGYpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGZpbmFsIFN0cmluZyBmYWN0b3J5Q2xhc3NOYW1lID0gY2FjaGVQcm9wcy5nZXRQcm9wZXJ0eShmYWN0b3J5SWQpOwotCi0gICAgICAgICAgICBpZiAoZmFjdG9yeUNsYXNzTmFtZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgZFByaW50KCJmb3VuZCBpbiAkamF2YS5ob21lL2pheHAucHJvcGVydGllcywgdmFsdWU9IiArIGZhY3RvcnlDbGFzc05hbWUpOwotICAgICAgICAgICAgICAgIHJldHVybiBuZXdJbnN0YW5jZSh0eXBlLCBmYWN0b3J5Q2xhc3NOYW1lLCBudWxsLCB0cnVlLCB0cnVlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7Ci0gICAgICAgICAgICBpZiAoZGVidWcpIGV4LnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gVHJ5IEphciBTZXJ2aWNlIFByb3ZpZGVyIE1lY2hhbmlzbQotICAgICAgICBUIHByb3ZpZGVyID0gZmluZFNlcnZpY2VQcm92aWRlcih0eXBlKTsKLSAgICAgICAgaWYgKHByb3ZpZGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBwcm92aWRlcjsKLSAgICAgICAgfQotICAgICAgICBpZiAoZmFsbGJhY2tDbGFzc05hbWUgPT0gbnVsbCkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvcihudWxsLAotICAgICAgICAgICAgICAgICJQcm92aWRlciBmb3IgIiArIGZhY3RvcnlJZCArICIgY2Fubm90IGJlIGZvdW5kIik7Ci0gICAgICAgIH0KLQotICAgICAgICBkUHJpbnQoImxvYWRlZCBmcm9tIGZhbGxiYWNrIHZhbHVlOiAiICsgZmFsbGJhY2tDbGFzc05hbWUpOwotICAgICAgICByZXR1cm4gbmV3SW5zdGFuY2UodHlwZSwgZmFsbGJhY2tDbGFzc05hbWUsIG51bGwsIHRydWUsIHRydWUpOwotICAgIH0KLQotICAgIC8qCi0gICAgICogVHJ5IHRvIGZpbmQgcHJvdmlkZXIgdXNpbmcgdGhlIFNlcnZpY2VMb2FkZXIuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdHlwZSBCYXNlIGNsYXNzIC8gU2VydmljZSBpbnRlcmZhY2UgIG9mIHRoZSBmYWN0b3J5IHRvIGZpbmQuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIGluc3RhbmNlIG9mIHByb3ZpZGVyIGNsYXNzIGlmIGZvdW5kIG9yIG51bGwKLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyA8VD4gVCBmaW5kU2VydmljZVByb3ZpZGVyKGZpbmFsIENsYXNzPFQ+IHR5cGUpCi0gICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IKLSAgICB7Ci0gICAgICB0cnkgewotICAgICAgICAgICAgcmV0dXJuIEFjY2Vzc0NvbnRyb2xsZXIuZG9Qcml2aWxlZ2VkKG5ldyBQcml2aWxlZ2VkQWN0aW9uPFQ+KCkgewotICAgICAgICAgICAgICAgIHB1YmxpYyBUIHJ1bigpIHsKLSAgICAgICAgICAgICAgICAgICAgZmluYWwgU2VydmljZUxvYWRlcjxUPiBzZXJ2aWNlTG9hZGVyID0gU2VydmljZUxvYWRlci5sb2FkKHR5cGUpOwotICAgICAgICAgICAgICAgICAgICBmaW5hbCBJdGVyYXRvcjxUPiBpdGVyYXRvciA9IHNlcnZpY2VMb2FkZXIuaXRlcmF0b3IoKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGl0ZXJhdG9yLmhhc05leHQoKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGl0ZXJhdG9yLm5leHQoKTsKLSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0pOwotICAgICAgICB9IGNhdGNoKFNlcnZpY2VDb25maWd1cmF0aW9uRXJyb3IgZSkgewotICAgICAgICAgICAgLy8gSXQgaXMgbm90IHBvc3NpYmxlIHRvIHdyYXAgYW4gZXJyb3IgZGlyZWN0bHkgaW4KLSAgICAgICAgICAgIC8vIEZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IgLSBzbyB3ZSBuZWVkIHRvIHdyYXAgdGhlCi0gICAgICAgICAgICAvLyBTZXJ2aWNlQ29uZmlndXJhdGlvbkVycm9yIGluIGEgUnVudGltZUV4Y2VwdGlvbi4KLSAgICAgICAgICAgIC8vIFRoZSBhbHRlcm5hdGl2ZSB3b3VsZCBiZSB0byBtb2RpZnkgdGhlIGxvZ2ljIGluCi0gICAgICAgICAgICAvLyBGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yIHRvIGFsbG93IHNldHRpbmcgYQotICAgICAgICAgICAgLy8gVGhyb3dhYmxlIGFzIHRoZSBjYXVzZSwgYnV0IHRoYXQgY291bGQgY2F1c2UKLSAgICAgICAgICAgIC8vIGNvbXBhdGliaWxpdHkgaXNzdWVzIGRvd24gdGhlIHJvYWQuCi0gICAgICAgICAgICBmaW5hbCBSdW50aW1lRXhjZXB0aW9uIHggPSBuZXcgUnVudGltZUV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgIlByb3ZpZGVyIGZvciAiICsgdHlwZSArICIgY2Fubm90IGJlIGNyZWF0ZWQiLCBlKTsKLSAgICAgICAgICAgIGZpbmFsIFRyYW5zZm9ybWVyRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvciBlcnJvciA9Ci0gICAgICAgICAgICAgICAgICAgIG5ldyBUcmFuc2Zvcm1lckZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IoeCwgeC5nZXRNZXNzYWdlKCkpOwotICAgICAgICAgICAgdGhyb3cgZXJyb3I7Ci0gICAgICAgIH0KLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvamF2YXgveG1sL3RyYW5zZm9ybS9PdXRwdXRLZXlzLmphdmEgYi9zcmMvamF2YXgveG1sL3RyYW5zZm9ybS9PdXRwdXRLZXlzLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDNjMGZjMzUuLjAwMDAwMDAKLS0tIGEvc3JjL2phdmF4L3htbC90cmFuc2Zvcm0vT3V0cHV0S2V5cy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjAwICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDAsIDIwMDUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLXBhY2thZ2UgamF2YXgueG1sLnRyYW5zZm9ybTsKLQotLyoqCi0gKiBQcm92aWRlcyBzdHJpbmcgY29uc3RhbnRzIHRoYXQgY2FuIGJlIHVzZWQgdG8gc2V0Ci0gKiBvdXRwdXQgcHJvcGVydGllcyBmb3IgYSBUcmFuc2Zvcm1lciwgb3IgdG8gcmV0cmlldmUKLSAqIG91dHB1dCBwcm9wZXJ0aWVzIGZyb20gYSBUcmFuc2Zvcm1lciBvciBUZW1wbGF0ZXMgb2JqZWN0LgotICogPHA+QWxsIHRoZSBmaWVsZHMgaW4gdGhpcyBjbGFzcyBhcmUgcmVhZC1vbmx5LjwvcD4KLSAqCi0gKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjb3V0cHV0Ij4KLSAqICBzZWN0aW9uIDE2IG9mIHRoZSBYU0wgVHJhbnNmb3JtYXRpb25zIChYU0xUKSBXM0MgUmVjb21tZW5kYXRpb248L2E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBPdXRwdXRLZXlzIHsKLQotICAgIC8qKgotICAgICAqIERlZmF1bHQgY29uc3RydWN0b3IgaXMgcHJpdmF0ZSBvbiBwdXJwb3NlLiAgVGhpcyBjbGFzcyBpcwotICAgICAqIG9ubHkgZm9yIHN0YXRpYyB2YXJpYWJsZSBhY2Nlc3MsIGFuZCBzaG91bGQgbmV2ZXIgYmUgY29uc3RydWN0ZWQuCi0gICAgICovCi0gICAgcHJpdmF0ZSBPdXRwdXRLZXlzKCkgeyB9Ci0KLSAgICAvKioKLSAgICAgKiBtZXRob2QgPSAieG1sIiB8ICJodG1sIiB8ICJ0ZXh0IiB8IDx2YXI+ZXhwYW5kZWQgbmFtZTwvdmFyPi4KLSAgICAgKgotICAgICAqIDxwPlRoZSB2YWx1ZSBvZiB0aGUgbWV0aG9kIHByb3BlcnR5IGlkZW50aWZpZXMgdGhlIG92ZXJhbGwgbWV0aG9kIHRoYXQKLSAgICAgKiBzaG91bGQgYmUgdXNlZCBmb3Igb3V0cHV0dGluZyB0aGUgcmVzdWx0IHRyZWUuICBPdGhlciBub24tbmFtZXNwYWNlZAotICAgICAqIHZhbHVlcyBtYXkgYmUgdXNlZCwgc3VjaCBhcyAieGh0bWwiLCBidXQsIGlmIGFjY2VwdGVkLCB0aGUgaGFuZGxpbmcKLSAgICAgKiBvZiBzdWNoIHZhbHVlcyBpcyBpbXBsZW1lbnRhdGlvbiBkZWZpbmVkLiAgSWYgYW55IG9mIHRoZSBtZXRob2QgdmFsdWVzCi0gICAgICogYXJlIG5vdCBhY2NlcHRlZCBhbmQgYXJlIG5vdCBuYW1lc3BhY2UgcXVhbGlmaWVkLAotICAgICAqIHRoZW4ge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXIjc2V0T3V0cHV0UHJvcGVydHl9Ci0gICAgICogb3Ige0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXIjc2V0T3V0cHV0UHJvcGVydGllc30gd2lsbAotICAgICAqIHRocm93IGEge0BsaW5rIGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb259LjwvcD4KLSAgICAgKgotICAgICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNvdXRwdXQiPgotICAgICAqICBzZWN0aW9uIDE2IG9mIHRoZSBYU0wgVHJhbnNmb3JtYXRpb25zIChYU0xUKSBXM0MgUmVjb21tZW5kYXRpb248L2E+Ci0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTUVUSE9EID0gIm1ldGhvZCI7Ci0KLSAgICAvKioKLSAgICAgKiB2ZXJzaW9uID0gPHZhcj5ubXRva2VuPC92YXI+LgotICAgICAqCi0gICAgICogPHA+PGNvZGU+dmVyc2lvbjwvY29kZT4gc3BlY2lmaWVzIHRoZSB2ZXJzaW9uIG9mIHRoZSBvdXRwdXQKLSAgICAgKiBtZXRob2QuPC9wPgotICAgICAqIDxwPldoZW4gdGhlIG91dHB1dCBtZXRob2QgaXMgInhtbCIsIHRoZSB2ZXJzaW9uIHZhbHVlIHNwZWNpZmllcyB0aGUKLSAgICAgKiB2ZXJzaW9uIG9mIFhNTCB0byBiZSB1c2VkIGZvciBvdXRwdXR0aW5nIHRoZSByZXN1bHQgdHJlZS4gVGhlIGRlZmF1bHQKLSAgICAgKiB2YWx1ZSBmb3IgdGhlIHhtbCBvdXRwdXQgbWV0aG9kIGlzIDEuMC4gV2hlbiB0aGUgb3V0cHV0IG1ldGhvZCBpcwotICAgICAqICJodG1sIiwgdGhlIHZlcnNpb24gdmFsdWUgaW5kaWNhdGVzIHRoZSB2ZXJzaW9uIG9mIHRoZSBIVE1MLgotICAgICAqIFRoZSBkZWZhdWx0IHZhbHVlIGZvciB0aGUgeG1sIG91dHB1dCBtZXRob2QgaXMgNC4wLCB3aGljaCBzcGVjaWZpZXMKLSAgICAgKiB0aGF0IHRoZSByZXN1bHQgc2hvdWxkIGJlIG91dHB1dCBhcyBIVE1MIGNvbmZvcm1pbmcgdG8gdGhlIEhUTUwgNC4wCi0gICAgICogUmVjb21tZW5kYXRpb24gW0hUTUxdLiAgSWYgdGhlIG91dHB1dCBtZXRob2QgaXMgInRleHQiLCB0aGUgdmVyc2lvbgotICAgICAqIHByb3BlcnR5IGlzIGlnbm9yZWQuPC9wPgotICAgICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNvdXRwdXQiPgotICAgICAqICBzZWN0aW9uIDE2IG9mIHRoZSBYU0wgVHJhbnNmb3JtYXRpb25zIChYU0xUKSBXM0MgUmVjb21tZW5kYXRpb248L2E+Ci0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgVkVSU0lPTiA9ICJ2ZXJzaW9uIjsKLQotICAgIC8qKgotICAgICAqIGVuY29kaW5nID0gPHZhcj5zdHJpbmc8L3Zhcj4uCi0gICAgICoKLSAgICAgKiA8cD48Y29kZT5lbmNvZGluZzwvY29kZT4gc3BlY2lmaWVzIHRoZSBwcmVmZXJyZWQgY2hhcmFjdGVyCi0gICAgICogZW5jb2RpbmcgdGhhdCB0aGUgVHJhbnNmb3JtZXIgc2hvdWxkIHVzZSB0byBlbmNvZGUgc2VxdWVuY2VzIG9mCi0gICAgICogY2hhcmFjdGVycyBhcyBzZXF1ZW5jZXMgb2YgYnl0ZXMuIFRoZSB2YWx1ZSBvZiB0aGUgZW5jb2RpbmcgcHJvcGVydHkgc2hvdWxkIGJlCi0gICAgICogdHJlYXRlZCBjYXNlLWluc2Vuc2l0aXZlbHkuIFRoZSB2YWx1ZSBtdXN0IG9ubHkgY29udGFpbiBjaGFyYWN0ZXJzIGluCi0gICAgICogdGhlIHJhbmdlICN4MjEgdG8gI3g3RSAoaS5lLiwgcHJpbnRhYmxlIEFTQ0lJIGNoYXJhY3RlcnMpLiBUaGUgdmFsdWUKLSAgICAgKiBzaG91bGQgZWl0aGVyIGJlIGEgPGNvZGU+Y2hhcnNldDwvY29kZT4gcmVnaXN0ZXJlZCB3aXRoIHRoZSBJbnRlcm5ldAotICAgICAqIEFzc2lnbmVkIE51bWJlcnMgQXV0aG9yaXR5IDxhIGhyZWY9Imh0dHA6Ly93d3cuaWFuYS5vcmcvIj5bSUFOQV08L2E+LAotICAgICAqIDxhIGhyZWY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzIyNzgudHh0Ij5bUkZDMjI3OF08L2E+Ci0gICAgICogb3Igc3RhcnQgd2l0aCA8Y29kZT5YLTwvY29kZT4uPC9wPgotICAgICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNvdXRwdXQiPgotICAgICAqIHNlY3Rpb24gMTYgb2YgdGhlIFhTTCBUcmFuc2Zvcm1hdGlvbnMgKFhTTFQpIFczQyBSZWNvbW1lbmRhdGlvbjwvYT4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFTkNPRElORyA9ICJlbmNvZGluZyI7Ci0KLSAgICAvKioKLSAgICAgKiBvbWl0LXhtbC1kZWNsYXJhdGlvbiA9ICJ5ZXMiIHwgIm5vIi4KLSAgICAgKgotICAgICAqIDxwPjxjb2RlPm9taXQteG1sLWRlY2xhcmF0aW9uPC9jb2RlPiBzcGVjaWZpZXMgd2hldGhlciB0aGUgWFNMVAotICAgICAqIHByb2Nlc3NvciBzaG91bGQgb3V0cHV0IGFuIFhNTCBkZWNsYXJhdGlvbjsgdGhlIHZhbHVlIG11c3QgYmUKLSAgICAgKiA8Y29kZT55ZXM8L2NvZGU+IG9yIDxjb2RlPm5vPC9jb2RlPi48L3A+Ci0gICAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I291dHB1dCI+Ci0gICAgICogIHNlY3Rpb24gMTYgb2YgdGhlIFhTTCBUcmFuc2Zvcm1hdGlvbnMgKFhTTFQpIFczQyBSZWNvbW1lbmRhdGlvbjwvYT4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBPTUlUX1hNTF9ERUNMQVJBVElPTiA9ICJvbWl0LXhtbC1kZWNsYXJhdGlvbiI7Ci0KLSAgICAvKioKLSAgICAgKiBzdGFuZGFsb25lID0gInllcyIgfCAibm8iLgotICAgICAqCi0gICAgICogPHA+PGNvZGU+c3RhbmRhbG9uZTwvY29kZT4gc3BlY2lmaWVzIHdoZXRoZXIgdGhlIFRyYW5zZm9ybWVyCi0gICAgICogc2hvdWxkIG91dHB1dCBhIHN0YW5kYWxvbmUgZG9jdW1lbnQgZGVjbGFyYXRpb247IHRoZSB2YWx1ZSBtdXN0IGJlCi0gICAgICogPGNvZGU+eWVzPC9jb2RlPiBvciA8Y29kZT5ubzwvY29kZT4uPC9wPgotICAgICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNvdXRwdXQiPgotICAgICAqICBzZWN0aW9uIDE2IG9mIHRoZSBYU0wgVHJhbnNmb3JtYXRpb25zIChYU0xUKSBXM0MgUmVjb21tZW5kYXRpb248L2E+Ci0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1RBTkRBTE9ORSA9ICJzdGFuZGFsb25lIjsKLQotICAgIC8qKgotICAgICAqIGRvY3R5cGUtcHVibGljID0gPHZhcj5zdHJpbmc8L3Zhcj4uCi0gICAgICogPHA+U2VlIHRoZSBkb2N1bWVudGF0aW9uIGZvciB0aGUge0BsaW5rICNET0NUWVBFX1NZU1RFTX0gcHJvcGVydHkKLSAgICAgKiBmb3IgYSBkZXNjcmlwdGlvbiBvZiB3aGF0IHRoZSB2YWx1ZSBvZiB0aGUga2V5IHNob3VsZCBiZS48L3A+Ci0gICAgICoKLSAgICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjb3V0cHV0Ij4KLSAgICAgKiAgc2VjdGlvbiAxNiBvZiB0aGUgWFNMIFRyYW5zZm9ybWF0aW9ucyAoWFNMVCkgVzNDIFJlY29tbWVuZGF0aW9uPC9hPgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIERPQ1RZUEVfUFVCTElDID0gImRvY3R5cGUtcHVibGljIjsKLQotICAgIC8qKgotICAgICAqIGRvY3R5cGUtc3lzdGVtID0gPHZhcj5zdHJpbmc8L3Zhcj4uCi0gICAgICogPHA+PGNvZGU+ZG9jdHlwZS1zeXN0ZW08L2NvZGU+IHNwZWNpZmllcyB0aGUgc3lzdGVtIGlkZW50aWZpZXIKLSAgICAgKiB0byBiZSB1c2VkIGluIHRoZSBkb2N1bWVudCB0eXBlIGRlY2xhcmF0aW9uLjwvcD4KLSAgICAgKiA8cD5JZiB0aGUgZG9jdHlwZS1zeXN0ZW0gcHJvcGVydHkgaXMgc3BlY2lmaWVkLCB0aGUgeG1sIG91dHB1dCBtZXRob2QKLSAgICAgKiBzaG91bGQgb3V0cHV0IGEgZG9jdW1lbnQgdHlwZSBkZWNsYXJhdGlvbiBpbW1lZGlhdGVseSBiZWZvcmUgdGhlIGZpcnN0Ci0gICAgICogZWxlbWVudC4gVGhlIG5hbWUgZm9sbG93aW5nICZsdDshRE9DVFlQRSBzaG91bGQgYmUgdGhlIG5hbWUgb2YgdGhlIGZpcnN0Ci0gICAgICogZWxlbWVudC4gSWYgZG9jdHlwZS1wdWJsaWMgcHJvcGVydHkgaXMgYWxzbyBzcGVjaWZpZWQsIHRoZW4gdGhlIHhtbAotICAgICAqIG91dHB1dCBtZXRob2Qgc2hvdWxkIG91dHB1dCBQVUJMSUMgZm9sbG93ZWQgYnkgdGhlIHB1YmxpYyBpZGVudGlmaWVyCi0gICAgICogYW5kIHRoZW4gdGhlIHN5c3RlbSBpZGVudGlmaWVyOyBvdGhlcndpc2UsIGl0IHNob3VsZCBvdXRwdXQgU1lTVEVNCi0gICAgICogZm9sbG93ZWQgYnkgdGhlIHN5c3RlbSBpZGVudGlmaWVyLiBUaGUgaW50ZXJuYWwgc3Vic2V0IHNob3VsZCBiZSBlbXB0eS4KLSAgICAgKiBUaGUgdmFsdWUgb2YgdGhlIGRvY3R5cGUtcHVibGljIHByb3BlcnR5IHNob3VsZCBiZSBpZ25vcmVkIHVubGVzcyB0aGUgZG9jdHlwZS1zeXN0ZW0KLSAgICAgKiBwcm9wZXJ0eSBpcyBzcGVjaWZpZWQuPC9wPgotICAgICAqIDxwPklmIHRoZSBkb2N0eXBlLXB1YmxpYyBvciBkb2N0eXBlLXN5c3RlbSBwcm9wZXJ0aWVzIGFyZSBzcGVjaWZpZWQsCi0gICAgICogdGhlbiB0aGUgaHRtbCBvdXRwdXQgbWV0aG9kIHNob3VsZCBvdXRwdXQgYSBkb2N1bWVudCB0eXBlIGRlY2xhcmF0aW9uCi0gICAgICogaW1tZWRpYXRlbHkgYmVmb3JlIHRoZSBmaXJzdCBlbGVtZW50LiBUaGUgbmFtZSBmb2xsb3dpbmcgJmx0OyFET0NUWVBFCi0gICAgICogc2hvdWxkIGJlIEhUTUwgb3IgaHRtbC4gSWYgdGhlIGRvY3R5cGUtcHVibGljIHByb3BlcnR5IGlzIHNwZWNpZmllZCwKLSAgICAgKiB0aGVuIHRoZSBvdXRwdXQgbWV0aG9kIHNob3VsZCBvdXRwdXQgUFVCTElDIGZvbGxvd2VkIGJ5IHRoZSBzcGVjaWZpZWQKLSAgICAgKiBwdWJsaWMgaWRlbnRpZmllcjsgaWYgdGhlIGRvY3R5cGUtc3lzdGVtIHByb3BlcnR5IGlzIGFsc28gc3BlY2lmaWVkLAotICAgICAqIGl0IHNob3VsZCBhbHNvIG91dHB1dCB0aGUgc3BlY2lmaWVkIHN5c3RlbSBpZGVudGlmaWVyIGZvbGxvd2luZyB0aGUKLSAgICAgKiBwdWJsaWMgaWRlbnRpZmllci4gSWYgdGhlIGRvY3R5cGUtc3lzdGVtIHByb3BlcnR5IGlzIHNwZWNpZmllZCBidXQKLSAgICAgKiB0aGUgZG9jdHlwZS1wdWJsaWMgcHJvcGVydHkgaXMgbm90IHNwZWNpZmllZCwgdGhlbiB0aGUgb3V0cHV0IG1ldGhvZAotICAgICAqIHNob3VsZCBvdXRwdXQgU1lTVEVNIGZvbGxvd2VkIGJ5IHRoZSBzcGVjaWZpZWQgc3lzdGVtIGlkZW50aWZpZXIuPC9wPgotICAgICAqCi0gICAgICogPHA+PGNvZGU+ZG9jdHlwZS1zeXN0ZW08L2NvZGU+IHNwZWNpZmllcyB0aGUgc3lzdGVtIGlkZW50aWZpZXIKLSAgICAgKiB0byBiZSB1c2VkIGluIHRoZSBkb2N1bWVudCB0eXBlIGRlY2xhcmF0aW9uLjwvcD4KLSAgICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjb3V0cHV0Ij4KLSAgICAgKiAgc2VjdGlvbiAxNiBvZiB0aGUgWFNMIFRyYW5zZm9ybWF0aW9ucyAoWFNMVCkgVzNDIFJlY29tbWVuZGF0aW9uPC9hPgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIERPQ1RZUEVfU1lTVEVNID0gImRvY3R5cGUtc3lzdGVtIjsKLQotICAgIC8qKgotICAgICAqIGNkYXRhLXNlY3Rpb24tZWxlbWVudHMgPSA8dmFyPmV4cGFuZGVkIG5hbWVzPC92YXI+LgotICAgICAqCi0gICAgICogPHA+PGNvZGU+Y2RhdGEtc2VjdGlvbi1lbGVtZW50czwvY29kZT4gc3BlY2lmaWVzIGEgd2hpdGVzcGFjZSBkZWxpbWl0ZWQKLSAgICAgKiBsaXN0IG9mIHRoZSBuYW1lcyBvZiBlbGVtZW50cyB3aG9zZSB0ZXh0IG5vZGUgY2hpbGRyZW4gc2hvdWxkIGJlIG91dHB1dAotICAgICAqIHVzaW5nIENEQVRBIHNlY3Rpb25zLiBOb3RlIHRoYXQgdGhlc2UgbmFtZXMgbXVzdCB1c2UgdGhlIGZvcm1hdAotICAgICAqIGRlc2NyaWJlZCBpbiB0aGUgc2VjdGlvbiBRdWFsZmllZCBOYW1lIFJlcHJlc2VudGF0aW9uIGluCi0gICAgICoge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm19LjwvcD4KLSAgICAgKgotICAgICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNvdXRwdXQiPgotICAgICAqICBzZWN0aW9uIDE2IG9mIHRoZSBYU0wgVHJhbnNmb3JtYXRpb25zIChYU0xUKSBXM0MgUmVjb21tZW5kYXRpb24uPC9hPgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIENEQVRBX1NFQ1RJT05fRUxFTUVOVFMgPQotICAgICAgICAiY2RhdGEtc2VjdGlvbi1lbGVtZW50cyI7Ci0KLSAgICAvKioKLSAgICAgKiBpbmRlbnQgPSAieWVzIiB8ICJubyIuCi0gICAgICoKLSAgICAgKiA8cD48Y29kZT5pbmRlbnQ8L2NvZGU+IHNwZWNpZmllcyB3aGV0aGVyIHRoZSBUcmFuc2Zvcm1lciBtYXkKLSAgICAgKiBhZGQgYWRkaXRpb25hbCB3aGl0ZXNwYWNlIHdoZW4gb3V0cHV0dGluZyB0aGUgcmVzdWx0IHRyZWU7IHRoZSB2YWx1ZQotICAgICAqIG11c3QgYmUgPGNvZGU+eWVzPC9jb2RlPiBvciA8Y29kZT5ubzwvY29kZT4uICA8L3A+Ci0gICAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I291dHB1dCI+Ci0gICAgICogIHNlY3Rpb24gMTYgb2YgdGhlIFhTTCBUcmFuc2Zvcm1hdGlvbnMgKFhTTFQpIFczQyBSZWNvbW1lbmRhdGlvbjwvYT4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBJTkRFTlQgPSAiaW5kZW50IjsKLQotICAgIC8qKgotICAgICAqIG1lZGlhLXR5cGUgPSA8dmFyPnN0cmluZzwvdmFyPi4KLSAgICAgKgotICAgICAqIDxwPjxjb2RlPm1lZGlhLXR5cGU8L2NvZGU+IHNwZWNpZmllcyB0aGUgbWVkaWEgdHlwZSAoTUlNRQotICAgICAqIGNvbnRlbnQgdHlwZSkgb2YgdGhlIGRhdGEgdGhhdCByZXN1bHRzIGZyb20gb3V0cHV0dGluZyB0aGUgcmVzdWx0Ci0gICAgICogdHJlZS4gVGhlIDxjb2RlPmNoYXJzZXQ8L2NvZGU+IHBhcmFtZXRlciBzaG91bGQgbm90IGJlIHNwZWNpZmllZAotICAgICAqIGV4cGxpY2l0bHk7IGluc3RlYWQsIHdoZW4gdGhlIHRvcC1sZXZlbCBtZWRpYSB0eXBlIGlzCi0gICAgICogPGNvZGU+dGV4dDwvY29kZT4sIGEgPGNvZGU+Y2hhcnNldDwvY29kZT4gcGFyYW1ldGVyIHNob3VsZCBiZSBhZGRlZAotICAgICAqIGFjY29yZGluZyB0byB0aGUgY2hhcmFjdGVyIGVuY29kaW5nIGFjdHVhbGx5IHVzZWQgYnkgdGhlIG91dHB1dAotICAgICAqIG1ldGhvZC4gIDwvcD4KLSAgICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjb3V0cHV0Ij5zCi0gICAgICogZWN0aW9uIDE2IG9mIHRoZSBYU0wgVHJhbnNmb3JtYXRpb25zIChYU0xUKSBXM0MgUmVjb21tZW5kYXRpb248L2E+Ci0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTUVESUFfVFlQRSA9ICJtZWRpYS10eXBlIjsKLX0KZGlmZiAtLWdpdCBhL3NyYy9qYXZheC94bWwvdHJhbnNmb3JtL1Jlc3VsdC5qYXZhIGIvc3JjL2phdmF4L3htbC90cmFuc2Zvcm0vUmVzdWx0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDQ3NDcyODUuLjAwMDAwMDAKLS0tIGEvc3JjL2phdmF4L3htbC90cmFuc2Zvcm0vUmVzdWx0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4NiArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDAwLCAyMDA1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi1wYWNrYWdlIGphdmF4LnhtbC50cmFuc2Zvcm07Ci0KLS8qKgotICogPHA+QW4gb2JqZWN0IHRoYXQgaW1wbGVtZW50cyB0aGlzIGludGVyZmFjZSBjb250YWlucyB0aGUgaW5mb3JtYXRpb24KLSAqIG5lZWRlZCB0byBidWlsZCBhIHRyYW5zZm9ybWF0aW9uIHJlc3VsdCB0cmVlLjwvcD4KLSAqCi0gKiBAYXV0aG9yIDxhIGhyZWY9IkplZmYuU3V0dG9yQFN1bi5jb20iPkplZmYgU3V0dG9yPC9hPgotICovCi1wdWJsaWMgaW50ZXJmYWNlIFJlc3VsdCB7Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgbmFtZSBvZiB0aGUgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiB0aGF0IGlzIHNlbnQgaWYgdGhlCi0gICAgICogcmVzdWx0IHRyZWUgZGlzYWJsZXMgb3V0cHV0IGVzY2FwaW5nLgotICAgICAqCi0gICAgICogPHA+Tm9ybWFsbHksIHJlc3VsdCB0cmVlIHNlcmlhbGl6YXRpb24gZXNjYXBlcyAmIGFuZCA8IChhbmQKLSAgICAgKiBwb3NzaWJseSBvdGhlciBjaGFyYWN0ZXJzKSB3aGVuIG91dHB1dHRpbmcgdGV4dCBub2Rlcy4KLSAgICAgKiBUaGlzIGVuc3VyZXMgdGhhdCB0aGUgb3V0cHV0IGlzIHdlbGwtZm9ybWVkIFhNTC4gSG93ZXZlciwKLSAgICAgKiBpdCBpcyBzb21ldGltZXMgY29udmVuaWVudCB0byBiZSBhYmxlIHRvIHByb2R1Y2Ugb3V0cHV0IHRoYXQgaXMKLSAgICAgKiBhbG1vc3QsIGJ1dCBub3QgcXVpdGUgd2VsbC1mb3JtZWQgWE1MOyBmb3IgZXhhbXBsZSwKLSAgICAgKiB0aGUgb3V0cHV0IG1heSBpbmNsdWRlIGlsbC1mb3JtZWQgc2VjdGlvbnMgdGhhdCB3aWxsCi0gICAgICogYmUgdHJhbnNmb3JtZWQgaW50byB3ZWxsLWZvcm1lZCBYTUwgYnkgYSBzdWJzZXF1ZW50IG5vbi1YTUwgYXdhcmUKLSAgICAgKiBwcm9jZXNzLiBJZiBhIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gaXMgc2VudCB3aXRoIHRoaXMgbmFtZSwKLSAgICAgKiBzZXJpYWxpemF0aW9uIHNob3VsZCBiZSBvdXRwdXQgd2l0aG91dCBhbnkgZXNjYXBpbmcuIDwvcD4KLSAgICAgKgotICAgICAqIDxwPlJlc3VsdCBET00gdHJlZXMgbWF5IGFsc28gaGF2ZSBQSV9ESVNBQkxFX09VVFBVVF9FU0NBUElORyBhbmQKLSAgICAgKiBQSV9FTkFCTEVfT1VUUFVUX0VTQ0FQSU5HIGluc2VydGVkIGludG8gdGhlIHRyZWUuPC9wPgotICAgICAqCi0gICAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2Rpc2FibGUtb3V0cHV0LWVzY2FwaW5nIj5kaXNhYmxlLW91dHB1dC1lc2NhcGluZyBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgUElfRElTQUJMRV9PVVRQVVRfRVNDQVBJTkcgPQotICAgICAgICAiamF2YXgueG1sLnRyYW5zZm9ybS5kaXNhYmxlLW91dHB1dC1lc2NhcGluZyI7Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgbmFtZSBvZiB0aGUgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiB0aGF0IGlzIHNlbnQKLSAgICAgKiBpZiB0aGUgcmVzdWx0IHRyZWUgZW5hYmxlcyBvdXRwdXQgZXNjYXBpbmcgYXQgc29tZSBwb2ludCBhZnRlciBoYXZpbmcKLSAgICAgKiByZWNlaXZlZCBhIFBJX0RJU0FCTEVfT1VUUFVUX0VTQ0FQSU5HIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24uCi0gICAgICoKLSAgICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjZGlzYWJsZS1vdXRwdXQtZXNjYXBpbmciPmRpc2FibGUtb3V0cHV0LWVzY2FwaW5nIGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBQSV9FTkFCTEVfT1VUUFVUX0VTQ0FQSU5HID0KLSAgICAgICAgImphdmF4LnhtbC50cmFuc2Zvcm0uZW5hYmxlLW91dHB1dC1lc2NhcGluZyI7Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIHN5c3RlbSBpZGVudGlmaWVyIGZvciB0aGlzIFJlc3VsdC4KLSAgICAgKgotICAgICAqIDxwPklmIHRoZSBSZXN1bHQgaXMgbm90IHRvIGJlIHdyaXR0ZW4gdG8gYSBmaWxlLCB0aGUgc3lzdGVtIGlkZW50aWZpZXIgaXMgb3B0aW9uYWwuCi0gICAgICogVGhlIGFwcGxpY2F0aW9uIG1heSBzdGlsbCB3YW50IHRvIHByb3ZpZGUgb25lLCBob3dldmVyLCBmb3IgdXNlIGluIGVycm9yIG1lc3NhZ2VzCi0gICAgICogYW5kIHdhcm5pbmdzLCBvciB0byByZXNvbHZlIHJlbGF0aXZlIG91dHB1dCBpZGVudGlmaWVycy48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gc3lzdGVtSWQgVGhlIHN5c3RlbSBpZGVudGlmaWVyIGFzIGEgVVJJIHN0cmluZy4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRTeXN0ZW1JZChTdHJpbmcgc3lzdGVtSWQpOwotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBzeXN0ZW0gaWRlbnRpZmllciB0aGF0IHdhcyBzZXQgd2l0aCBzZXRTeXN0ZW1JZC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIHN5c3RlbSBpZGVudGlmaWVyIHRoYXQgd2FzIHNldCB3aXRoIHNldFN5c3RlbUlkLAotICAgICAqIG9yIG51bGwgaWYgc2V0U3lzdGVtSWQgd2FzIG5vdCBjYWxsZWQuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRTeXN0ZW1JZCgpOwotfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmF4L3htbC90cmFuc2Zvcm0vU2VjdXJpdHlTdXBwb3J0LmphdmEgYi9zcmMvamF2YXgveG1sL3RyYW5zZm9ybS9TZWN1cml0eVN1cHBvcnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZTVmMWJiMC4uMDAwMDAwMAotLS0gYS9zcmMvamF2YXgveG1sL3RyYW5zZm9ybS9TZWN1cml0eVN1cHBvcnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEwOCArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDA0LCAyMDA2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi1wYWNrYWdlIGphdmF4LnhtbC50cmFuc2Zvcm07Ci0KLWltcG9ydCBqYXZhLnNlY3VyaXR5Lio7Ci1pbXBvcnQgamF2YS5uZXQuKjsKLWltcG9ydCBqYXZhLmlvLio7Ci1pbXBvcnQgamF2YS51dGlsLio7Ci0KLS8qKgotICogVGhpcyBjbGFzcyBpcyBkdXBsaWNhdGVkIGZvciBlYWNoIEpBWFAgc3VicGFja2FnZSBzbyBrZWVwIGl0IGluIHN5bmMuCi0gKiBJdCBpcyBwYWNrYWdlIHByaXZhdGUgYW5kIHRoZXJlZm9yZSBpcyBub3QgZXhwb3NlZCBhcyBwYXJ0IG9mIHRoZSBKQVhQCi0gKiBBUEkuCi0gKgotICogU2VjdXJpdHkgcmVsYXRlZCBtZXRob2RzIHRoYXQgb25seSB3b3JrIG9uIEoyU0UgMS4yIGFuZCBuZXdlci4KLSAqLwotY2xhc3MgU2VjdXJpdHlTdXBwb3J0ICB7Ci0KLQotICAgIENsYXNzTG9hZGVyIGdldENvbnRleHRDbGFzc0xvYWRlcigpIHRocm93cyBTZWN1cml0eUV4Y2VwdGlvbnsKLSAgICAgICAgcmV0dXJuIChDbGFzc0xvYWRlcikKLSAgICAgICAgQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQobmV3IFByaXZpbGVnZWRBY3Rpb24oKSB7Ci0gICAgICAgICAgICBwdWJsaWMgT2JqZWN0IHJ1bigpIHsKLSAgICAgICAgICAgICAgICBDbGFzc0xvYWRlciBjbCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgLy90cnkgewotICAgICAgICAgICAgICAgIGNsID0gVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5nZXRDb250ZXh0Q2xhc3NMb2FkZXIoKTsKLSAgICAgICAgICAgICAgICAvL30gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIGV4KSB7IH0KLSAgICAgICAgICAgICAgICBpZiAoY2wgPT0gbnVsbCkKLSAgICAgICAgICAgICAgICAgICAgY2wgPSBDbGFzc0xvYWRlci5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpOwotICAgICAgICAgICAgICAgIHJldHVybiBjbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSk7Ci0gICAgfQotCi0gICAgU3RyaW5nIGdldFN5c3RlbVByb3BlcnR5KGZpbmFsIFN0cmluZyBwcm9wTmFtZSkgewotICAgICAgICByZXR1cm4gKFN0cmluZykKLSAgICAgICAgICAgIEFjY2Vzc0NvbnRyb2xsZXIuZG9Qcml2aWxlZ2VkKG5ldyBQcml2aWxlZ2VkQWN0aW9uKCkgewotICAgICAgICAgICAgICAgIHB1YmxpYyBPYmplY3QgcnVuKCkgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gU3lzdGVtLmdldFByb3BlcnR5KHByb3BOYW1lKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9KTsKLSAgICB9Ci0KLSAgICBGaWxlSW5wdXRTdHJlYW0gZ2V0RmlsZUlucHV0U3RyZWFtKGZpbmFsIEZpbGUgZmlsZSkKLSAgICAgICAgdGhyb3dzIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIHJldHVybiAoRmlsZUlucHV0U3RyZWFtKQotICAgICAgICAgICAgICAgIEFjY2Vzc0NvbnRyb2xsZXIuZG9Qcml2aWxlZ2VkKG5ldyBQcml2aWxlZ2VkRXhjZXB0aW9uQWN0aW9uKCkgewotICAgICAgICAgICAgICAgICAgICBwdWJsaWMgT2JqZWN0IHJ1bigpIHRocm93cyBGaWxlTm90Rm91bmRFeGNlcHRpb24gewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBGaWxlSW5wdXRTdHJlYW0oZmlsZSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9KTsKLSAgICAgICAgfSBjYXRjaCAoUHJpdmlsZWdlZEFjdGlvbkV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICB0aHJvdyAoRmlsZU5vdEZvdW5kRXhjZXB0aW9uKWUuZ2V0RXhjZXB0aW9uKCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBJbnB1dFN0cmVhbSBnZXRSZXNvdXJjZUFzU3RyZWFtKGZpbmFsIENsYXNzTG9hZGVyIGNsLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBuYW1lKQotICAgIHsKLSAgICAgICAgcmV0dXJuIChJbnB1dFN0cmVhbSkKLSAgICAgICAgICAgIEFjY2Vzc0NvbnRyb2xsZXIuZG9Qcml2aWxlZ2VkKG5ldyBQcml2aWxlZ2VkQWN0aW9uKCkgewotICAgICAgICAgICAgICAgIHB1YmxpYyBPYmplY3QgcnVuKCkgewotICAgICAgICAgICAgICAgICAgICBJbnB1dFN0cmVhbSByaXM7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChjbCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByaXMgPSBPYmplY3QuY2xhc3MuZ2V0UmVzb3VyY2VBc1N0cmVhbShuYW1lKTsKLSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJpcyA9IGNsLmdldFJlc291cmNlQXNTdHJlYW0obmFtZSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJpczsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9KTsKLSAgICB9Ci0KLSAgICBib29sZWFuIGRvZXNGaWxlRXhpc3QoZmluYWwgRmlsZSBmKSB7Ci0gICAgcmV0dXJuICgoQm9vbGVhbikKLSAgICAgICAgICAgIEFjY2Vzc0NvbnRyb2xsZXIuZG9Qcml2aWxlZ2VkKG5ldyBQcml2aWxlZ2VkQWN0aW9uKCkgewotICAgICAgICAgICAgICAgIHB1YmxpYyBPYmplY3QgcnVuKCkgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEJvb2xlYW4oZi5leGlzdHMoKSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfSkpLmJvb2xlYW5WYWx1ZSgpOwotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmF4L3htbC90cmFuc2Zvcm0vU291cmNlLmphdmEgYi9zcmMvamF2YXgveG1sL3RyYW5zZm9ybS9Tb3VyY2UuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggM2FmNjk2OS4uMDAwMDAwMAotLS0gYS9zcmMvamF2YXgveG1sL3RyYW5zZm9ybS9Tb3VyY2UuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDUzICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDAsIDIwMDUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLXBhY2thZ2UgamF2YXgueG1sLnRyYW5zZm9ybTsKLQotLyoqCi0gKiBBbiBvYmplY3QgdGhhdCBpbXBsZW1lbnRzIHRoaXMgaW50ZXJmYWNlIGNvbnRhaW5zIHRoZSBpbmZvcm1hdGlvbgotICogbmVlZGVkIHRvIGFjdCBhcyBzb3VyY2UgaW5wdXQgKFhNTCBzb3VyY2Ugb3IgdHJhbnNmb3JtYXRpb24gaW5zdHJ1Y3Rpb25zKS4KLSAqLwotcHVibGljIGludGVyZmFjZSBTb3VyY2UgewotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSBzeXN0ZW0gaWRlbnRpZmllciBmb3IgdGhpcyBTb3VyY2UuCi0gICAgICoKLSAgICAgKiA8cD5UaGUgc3lzdGVtIGlkZW50aWZpZXIgaXMgb3B0aW9uYWwgaWYgdGhlIHNvdXJjZSBkb2VzIG5vdAotICAgICAqIGdldCBpdHMgZGF0YSBmcm9tIGEgVVJMLCBidXQgaXQgbWF5IHN0aWxsIGJlIHVzZWZ1bCB0byBwcm92aWRlIG9uZS4KLSAgICAgKiBUaGUgYXBwbGljYXRpb24gY2FuIHVzZSBhIHN5c3RlbSBpZGVudGlmaWVyLCBmb3IgZXhhbXBsZSwgdG8gcmVzb2x2ZQotICAgICAqIHJlbGF0aXZlIFVSSXMgYW5kIHRvIGluY2x1ZGUgaW4gZXJyb3IgbWVzc2FnZXMgYW5kIHdhcm5pbmdzLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzeXN0ZW1JZCBUaGUgc3lzdGVtIGlkZW50aWZpZXIgYXMgYSBVUkwgc3RyaW5nLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFN5c3RlbUlkKFN0cmluZyBzeXN0ZW1JZCk7Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIHN5c3RlbSBpZGVudGlmaWVyIHRoYXQgd2FzIHNldCB3aXRoIHNldFN5c3RlbUlkLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgc3lzdGVtIGlkZW50aWZpZXIgdGhhdCB3YXMgc2V0IHdpdGggc2V0U3lzdGVtSWQsIG9yIG51bGwKLSAgICAgKiBpZiBzZXRTeXN0ZW1JZCB3YXMgbm90IGNhbGxlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFN5c3RlbUlkKCk7Ci19CmRpZmYgLS1naXQgYS9zcmMvamF2YXgveG1sL3RyYW5zZm9ybS9Tb3VyY2VMb2NhdG9yLmphdmEgYi9zcmMvamF2YXgveG1sL3RyYW5zZm9ybS9Tb3VyY2VMb2NhdG9yLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDQ3NWU2NTQuLjAwMDAwMDAKLS0tIGEvc3JjL2phdmF4L3htbC90cmFuc2Zvcm0vU291cmNlTG9jYXRvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTYgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwMCwgMjAwNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotcGFja2FnZSBqYXZheC54bWwudHJhbnNmb3JtOwotCi0vKioKLSAqIFRoaXMgaW50ZXJmYWNlIGlzIHByaW1hcmlseSBmb3IgdGhlIHB1cnBvc2VzIG9mIHJlcG9ydGluZyB3aGVyZQotICogYW4gZXJyb3Igb2NjdXJyZWQgaW4gdGhlIFhNTCBzb3VyY2Ugb3IgdHJhbnNmb3JtYXRpb24gaW5zdHJ1Y3Rpb25zLgotICovCi1wdWJsaWMgaW50ZXJmYWNlIFNvdXJjZUxvY2F0b3IgewotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSBwdWJsaWMgaWRlbnRpZmllciBmb3IgdGhlIGN1cnJlbnQgZG9jdW1lbnQgZXZlbnQuCi0gICAgICoKLSAgICAgKiA8cD5UaGUgcmV0dXJuIHZhbHVlIGlzIHRoZSBwdWJsaWMgaWRlbnRpZmllciBvZiB0aGUgZG9jdW1lbnQKLSAgICAgKiBlbnRpdHkgb3Igb2YgdGhlIGV4dGVybmFsIHBhcnNlZCBlbnRpdHkgaW4gd2hpY2ggdGhlIG1hcmt1cCB0aGF0Ci0gICAgICogdHJpZ2dlcmVkIHRoZSBldmVudCBhcHBlYXJzLjwvcD4KLSAgICAgKgotICAgICAqIEByZXR1cm4gQSBzdHJpbmcgY29udGFpbmluZyB0aGUgcHVibGljIGlkZW50aWZpZXIsIG9yCi0gICAgICogICAgICAgICBudWxsIGlmIG5vbmUgaXMgYXZhaWxhYmxlLgotICAgICAqIEBzZWUgI2dldFN5c3RlbUlkCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRQdWJsaWNJZCgpOwotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSBzeXN0ZW0gaWRlbnRpZmllciBmb3IgdGhlIGN1cnJlbnQgZG9jdW1lbnQgZXZlbnQuCi0gICAgICoKLSAgICAgKiA8cD5UaGUgcmV0dXJuIHZhbHVlIGlzIHRoZSBzeXN0ZW0gaWRlbnRpZmllciBvZiB0aGUgZG9jdW1lbnQKLSAgICAgKiBlbnRpdHkgb3Igb2YgdGhlIGV4dGVybmFsIHBhcnNlZCBlbnRpdHkgaW4gd2hpY2ggdGhlIG1hcmt1cCB0aGF0Ci0gICAgICogdHJpZ2dlcmVkIHRoZSBldmVudCBhcHBlYXJzLjwvcD4KLSAgICAgKgotICAgICAqIDxwPklmIHRoZSBzeXN0ZW0gaWRlbnRpZmllciBpcyBhIFVSTCwgdGhlIHBhcnNlciBtdXN0IHJlc29sdmUgaXQKLSAgICAgKiBmdWxseSBiZWZvcmUgcGFzc2luZyBpdCB0byB0aGUgYXBwbGljYXRpb24uPC9wPgotICAgICAqCi0gICAgICogQHJldHVybiBBIHN0cmluZyBjb250YWluaW5nIHRoZSBzeXN0ZW0gaWRlbnRpZmllciwgb3IgbnVsbAotICAgICAqICAgICAgICAgaWYgbm9uZSBpcyBhdmFpbGFibGUuCi0gICAgICogQHNlZSAjZ2V0UHVibGljSWQKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFN5c3RlbUlkKCk7Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIGxpbmUgbnVtYmVyIHdoZXJlIHRoZSBjdXJyZW50IGRvY3VtZW50IGV2ZW50IGVuZHMuCi0gICAgICoKLSAgICAgKiA8cD48c3Ryb25nPldhcm5pbmc6PC9zdHJvbmc+IFRoZSByZXR1cm4gdmFsdWUgZnJvbSB0aGUgbWV0aG9kCi0gICAgICogaXMgaW50ZW5kZWQgb25seSBhcyBhbiBhcHByb3hpbWF0aW9uIGZvciB0aGUgc2FrZSBvZiBlcnJvcgotICAgICAqIHJlcG9ydGluZzsgaXQgaXMgbm90IGludGVuZGVkIHRvIHByb3ZpZGUgc3VmZmljaWVudCBpbmZvcm1hdGlvbgotICAgICAqIHRvIGVkaXQgdGhlIGNoYXJhY3RlciBjb250ZW50IG9mIHRoZSBvcmlnaW5hbCBYTUwgZG9jdW1lbnQuPC9wPgotICAgICAqCi0gICAgICogPHA+VGhlIHJldHVybiB2YWx1ZSBpcyBhbiBhcHByb3hpbWF0aW9uIG9mIHRoZSBsaW5lIG51bWJlcgotICAgICAqIGluIHRoZSBkb2N1bWVudCBlbnRpdHkgb3IgZXh0ZXJuYWwgcGFyc2VkIGVudGl0eSB3aGVyZSB0aGUKLSAgICAgKiBtYXJrdXAgdGhhdCB0cmlnZ2VyZWQgdGhlIGV2ZW50IGFwcGVhcnMuPC9wPgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgbGluZSBudW1iZXIsIG9yIC0xIGlmIG5vbmUgaXMgYXZhaWxhYmxlLgotICAgICAqIEBzZWUgI2dldENvbHVtbk51bWJlcgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0TGluZU51bWJlcigpOwotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSBjaGFyYWN0ZXIgcG9zaXRpb24gd2hlcmUgdGhlIGN1cnJlbnQgZG9jdW1lbnQgZXZlbnQgZW5kcy4KLSAgICAgKgotICAgICAqIDxwPjxzdHJvbmc+V2FybmluZzo8L3N0cm9uZz4gVGhlIHJldHVybiB2YWx1ZSBmcm9tIHRoZSBtZXRob2QKLSAgICAgKiBpcyBpbnRlbmRlZCBvbmx5IGFzIGFuIGFwcHJveGltYXRpb24gZm9yIHRoZSBzYWtlIG9mIGVycm9yCi0gICAgICogcmVwb3J0aW5nOyBpdCBpcyBub3QgaW50ZW5kZWQgdG8gcHJvdmlkZSBzdWZmaWNpZW50IGluZm9ybWF0aW9uCi0gICAgICogdG8gZWRpdCB0aGUgY2hhcmFjdGVyIGNvbnRlbnQgb2YgdGhlIG9yaWdpbmFsIFhNTCBkb2N1bWVudC48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5UaGUgcmV0dXJuIHZhbHVlIGlzIGFuIGFwcHJveGltYXRpb24gb2YgdGhlIGNvbHVtbiBudW1iZXIKLSAgICAgKiBpbiB0aGUgZG9jdW1lbnQgZW50aXR5IG9yIGV4dGVybmFsIHBhcnNlZCBlbnRpdHkgd2hlcmUgdGhlCi0gICAgICogbWFya3VwIHRoYXQgdHJpZ2dlcmVkIHRoZSBldmVudCBhcHBlYXJzLjwvcD4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIGNvbHVtbiBudW1iZXIsIG9yIC0xIGlmIG5vbmUgaXMgYXZhaWxhYmxlLgotICAgICAqIEBzZWUgI2dldExpbmVOdW1iZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldENvbHVtbk51bWJlcigpOwotfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmF4L3htbC90cmFuc2Zvcm0vVGVtcGxhdGVzLmphdmEgYi9zcmMvamF2YXgveG1sL3RyYW5zZm9ybS9UZW1wbGF0ZXMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOTk1MjM2OC4uMDAwMDAwMAotLS0gYS9zcmMvamF2YXgveG1sL3RyYW5zZm9ybS9UZW1wbGF0ZXMuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDgyICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDAsIDIwMDUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLXBhY2thZ2UgamF2YXgueG1sLnRyYW5zZm9ybTsKLQotaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0aWVzOwotCi0KLQotCi0vKioKLSAqIEFuIG9iamVjdCB0aGF0IGltcGxlbWVudHMgdGhpcyBpbnRlcmZhY2UgaXMgdGhlIHJ1bnRpbWUgcmVwcmVzZW50YXRpb24gb2YgcHJvY2Vzc2VkCi0gKiB0cmFuc2Zvcm1hdGlvbiBpbnN0cnVjdGlvbnMuCi0gKgotICogPHA+VGVtcGxhdGVzIG11c3QgYmUgdGhyZWFkc2FmZSBmb3IgYSBnaXZlbiBpbnN0YW5jZQotICogb3ZlciBtdWx0aXBsZSB0aHJlYWRzIHJ1bm5pbmcgY29uY3VycmVudGx5LCBhbmQgbWF5Ci0gKiBiZSB1c2VkIG11bHRpcGxlIHRpbWVzIGluIGEgZ2l2ZW4gc2Vzc2lvbi48L3A+Ci0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgVGVtcGxhdGVzIHsKLQotICAgIC8qKgotICAgICAqIENyZWF0ZSBhIG5ldyB0cmFuc2Zvcm1hdGlvbiBjb250ZXh0IGZvciB0aGlzIFRlbXBsYXRlcyBvYmplY3QuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIEEgdmFsaWQgbm9uLW51bGwgaW5zdGFuY2Ugb2YgYSBUcmFuc2Zvcm1lci4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIGlmIGEgVHJhbnNmb3JtZXIgY2FuIG5vdCBiZSBjcmVhdGVkLgotICAgICAqLwotICAgIFRyYW5zZm9ybWVyIG5ld1RyYW5zZm9ybWVyKCkgdGhyb3dzIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgcHJvcGVydGllcyBjb3JyZXNwb25kaW5nIHRvIHRoZSBlZmZlY3RpdmUgeHNsOm91dHB1dCBlbGVtZW50LgotICAgICAqIFRoZSBvYmplY3QgcmV0dXJuZWQgd2lsbAotICAgICAqIGJlIGEgY2xvbmUgb2YgdGhlIGludGVybmFsIHZhbHVlcy4gQWNjb3JkaW5nbHksIGl0IGNhbiBiZSBtdXRhdGVkCi0gICAgICogd2l0aG91dCBtdXRhdGluZyB0aGUgVGVtcGxhdGVzIG9iamVjdCwgYW5kIHRoZW4gaGFuZGVkIGluIHRvCi0gICAgICoge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXIjc2V0T3V0cHV0UHJvcGVydGllc30uCi0gICAgICoKLSAgICAgKiA8cD5UaGUgcHJvcGVydGllcyByZXR1cm5lZCBzaG91bGQgY29udGFpbiBwcm9wZXJ0aWVzIHNldCBieSB0aGUgc3R5bGVzaGVldCwKLSAgICAgKiBhbmQgdGhlc2UgcHJvcGVydGllcyBhcmUgImRlZmF1bHRlZCIgYnkgZGVmYXVsdCBwcm9wZXJ0aWVzIHNwZWNpZmllZCBieQotICAgICAqIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjb3V0cHV0Ij5zZWN0aW9uIDE2IG9mIHRoZQotICAgICAqIFhTTCBUcmFuc2Zvcm1hdGlvbnMgKFhTTFQpIFczQyBSZWNvbW1lbmRhdGlvbjwvYT4uICBUaGUgcHJvcGVydGllcyB0aGF0Ci0gICAgICogd2VyZSBzcGVjaWZpY2FsbHkgc2V0IGJ5IHRoZSBzdHlsZXNoZWV0IHNob3VsZCBiZSBpbiB0aGUgYmFzZQotICAgICAqIFByb3BlcnRpZXMgbGlzdCwgd2hpbGUgdGhlIFhTTFQgZGVmYXVsdCBwcm9wZXJ0aWVzIHRoYXQgd2VyZSBub3QKLSAgICAgKiBzcGVjaWZpY2FsbHkgc2V0IHNob3VsZCBiZSBpbiB0aGUgImRlZmF1bHQiIFByb3BlcnRpZXMgbGlzdC4gIFRodXMsCi0gICAgICogZ2V0T3V0cHV0UHJvcGVydGllcygpLmdldFByb3BlcnR5KFN0cmluZyBrZXkpIHdpbGwgb2J0YWluIGFueQotICAgICAqIHByb3BlcnR5IGluIHRoYXQgd2FzIHNldCBieSB0aGUgc3R5bGVzaGVldCwgPGVtPm9yPC9lbT4gdGhlIGRlZmF1bHQKLSAgICAgKiBwcm9wZXJ0aWVzLCB3aGlsZQotICAgICAqIGdldE91dHB1dFByb3BlcnRpZXMoKS5nZXQoU3RyaW5nIGtleSkgd2lsbCBvbmx5IHJldHJpZXZlIHByb3BlcnRpZXMKLSAgICAgKiB0aGF0IHdlcmUgZXhwbGljaXRseSBzZXQgaW4gdGhlIHN0eWxlc2hlZXQuPC9wPgotICAgICAqCi0gICAgICogPHA+Rm9yIFhTTFQsCi0gICAgICogPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNhdHRyaWJ1dGUtdmFsdWUtdGVtcGxhdGVzIj5BdHRyaWJ1dGUKLSAgICAgKiBWYWx1ZSBUZW1wbGF0ZXM8L2E+IGF0dHJpYnV0ZSB2YWx1ZXMgd2lsbAotICAgICAqIGJlIHJldHVybmVkIHVuZXhwYW5kZWQgKHNpbmNlIHRoZXJlIGlzIG5vIGNvbnRleHQgYXQgdGhpcyBwb2ludCkuICBUaGUKLSAgICAgKiBuYW1lc3BhY2UgcHJlZml4ZXMgaW5zaWRlIEF0dHJpYnV0ZSBWYWx1ZSBUZW1wbGF0ZXMgd2lsbCBiZSB1bmV4cGFuZGVkLAotICAgICAqIHNvIHRoYXQgdGhleSByZW1haW4gdmFsaWQgWFBhdGggdmFsdWVzLjwvcD4KLSAgICAgKgotICAgICAqIEByZXR1cm4gQSBQcm9wZXJ0aWVzIG9iamVjdCwgbmV2ZXIgbnVsbC4KLSAgICAgKi8KLSAgICBQcm9wZXJ0aWVzIGdldE91dHB1dFByb3BlcnRpZXMoKTsKLX0KZGlmZiAtLWdpdCBhL3NyYy9qYXZheC94bWwvdHJhbnNmb3JtL1RyYW5zZm9ybWVyLmphdmEgYi9zcmMvamF2YXgveG1sL3RyYW5zZm9ybS9UcmFuc2Zvcm1lci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3ODNlODdhLi4wMDAwMDAwCi0tLSBhL3NyYy9qYXZheC94bWwvdHJhbnNmb3JtL1RyYW5zZm9ybWVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzMzkgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwMCwgMjAwNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotcGFja2FnZSBqYXZheC54bWwudHJhbnNmb3JtOwotCi1pbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7Ci0KLS8qKgotICogQW4gaW5zdGFuY2Ugb2YgdGhpcyBhYnN0cmFjdCBjbGFzcyBjYW4gdHJhbnNmb3JtIGEKLSAqIHNvdXJjZSB0cmVlIGludG8gYSByZXN1bHQgdHJlZS4KLSAqCi0gKiA8cD5BbiBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIGNhbiBiZSBvYnRhaW5lZCB3aXRoIHRoZQotICoge0BsaW5rIFRyYW5zZm9ybWVyRmFjdG9yeSNuZXdUcmFuc2Zvcm1lciBUcmFuc2Zvcm1lckZhY3RvcnkubmV3VHJhbnNmb3JtZXJ9Ci0gKiBtZXRob2QuIFRoaXMgaW5zdGFuY2UgbWF5IHRoZW4gYmUgdXNlZCB0byBwcm9jZXNzIFhNTCBmcm9tIGEKLSAqIHZhcmlldHkgb2Ygc291cmNlcyBhbmQgd3JpdGUgdGhlIHRyYW5zZm9ybWF0aW9uIG91dHB1dCB0byBhCi0gKiB2YXJpZXR5IG9mIHNpbmtzLjwvcD4KLSAqCi0gKiA8cD5BbiBvYmplY3Qgb2YgdGhpcyBjbGFzcyBtYXkgbm90IGJlIHVzZWQgaW4gbXVsdGlwbGUgdGhyZWFkcwotICogcnVubmluZyBjb25jdXJyZW50bHkuICBEaWZmZXJlbnQgVHJhbnNmb3JtZXJzIG1heSBiZSB1c2VkCi0gKiBjb25jdXJyZW50bHkgYnkgZGlmZmVyZW50IHRocmVhZHMuPC9wPgotICoKLSAqIDxwPkEgPGNvZGU+VHJhbnNmb3JtZXI8L2NvZGU+IG1heSBiZSB1c2VkIG11bHRpcGxlIHRpbWVzLiAgUGFyYW1ldGVycyBhbmQKLSAqIG91dHB1dCBwcm9wZXJ0aWVzIGFyZSBwcmVzZXJ2ZWQgYWNyb3NzIHRyYW5zZm9ybWF0aW9ucy48L3A+Ci0gKgotICogQGF1dGhvciA8YSBocmVmPSJKZWZmLlN1dHRvckBTdW4uY29tIj5KZWZmIFN1dHRvcjwvYT4KLSAqLwotcHVibGljIGFic3RyYWN0IGNsYXNzIFRyYW5zZm9ybWVyIHsKLQotICAgIC8qKgotICAgICAqIERlZmF1bHQgY29uc3RydWN0b3IgaXMgcHJvdGVjdGVkIG9uIHB1cnBvc2UuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIFRyYW5zZm9ybWVyKCkgeyB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIDxwPlJlc2V0IHRoaXMgPGNvZGU+VHJhbnNmb3JtZXI8L2NvZGU+IHRvIGl0cyBvcmlnaW5hbCBjb25maWd1cmF0aW9uLjwvcD4KLSAgICAgICAgICoKLSAgICAgICAgICogPHA+PGNvZGU+VHJhbnNmb3JtZXI8L2NvZGU+IGlzIHJlc2V0IHRvIHRoZSBzYW1lIHN0YXRlIGFzIHdoZW4gaXQgd2FzIGNyZWF0ZWQgd2l0aAotICAgICAgICAgKiB7QGxpbmsgVHJhbnNmb3JtZXJGYWN0b3J5I25ld1RyYW5zZm9ybWVyKCl9LAotICAgICAgICAgKiB7QGxpbmsgVHJhbnNmb3JtZXJGYWN0b3J5I25ld1RyYW5zZm9ybWVyKFNvdXJjZSBzb3VyY2UpfSBvcgotICAgICAgICAgKiB7QGxpbmsgVGVtcGxhdGVzI25ld1RyYW5zZm9ybWVyKCl9LgotICAgICAgICAgKiA8Y29kZT5yZXNldCgpPC9jb2RlPiBpcyBkZXNpZ25lZCB0byBhbGxvdyB0aGUgcmV1c2Ugb2YgZXhpc3RpbmcgPGNvZGU+VHJhbnNmb3JtZXI8L2NvZGU+cwotICAgICAgICAgKiB0aHVzIHNhdmluZyByZXNvdXJjZXMgYXNzb2NpYXRlZCB3aXRoIHRoZSBjcmVhdGlvbiBvZiBuZXcgPGNvZGU+VHJhbnNmb3JtZXI8L2NvZGU+cy48L3A+Ci0gICAgICAgICAqCi0gICAgICAgICAqIDxwPlRoZSByZXNldCA8Y29kZT5UcmFuc2Zvcm1lcjwvY29kZT4gaXMgbm90IGd1YXJhbnRlZWQgdG8gaGF2ZSB0aGUgc2FtZSB7QGxpbmsgVVJJUmVzb2x2ZXJ9Ci0gICAgICAgICAqIG9yIHtAbGluayBFcnJvckxpc3RlbmVyfSA8Y29kZT5PYmplY3Q8L2NvZGU+cywgZS5nLiB7QGxpbmsgT2JqZWN0I2VxdWFscyhPYmplY3Qgb2JqKX0uCi0gICAgICAgICAqIEl0IGlzIGd1YXJhbnRlZWQgdG8gaGF2ZSBhIGZ1bmN0aW9uYWxseSBlcXVhbCA8Y29kZT5VUklSZXNvbHZlcjwvY29kZT4KLSAgICAgICAgICogYW5kIDxjb2RlPkVycm9yTGlzdGVuZXI8L2NvZGU+LjwvcD4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gV2hlbiBpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdAotICAgICAqICAgb3ZlcnJpZGUgdGhpcyBtZXRob2QuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBzaW5jZSAxLjUKLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyB2b2lkIHJlc2V0KCkgewotCi0gICAgICAgICAgICAgICAgLy8gaW1wbGVtZW50b3JzIHNob3VsZCBvdmVycmlkZSB0aGlzIG1ldGhvZAotICAgICAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgICAgICJUaGlzIFRyYW5zZm9ybWVyLCBcIiIgKyB0aGlzLmdldENsYXNzKCkuZ2V0TmFtZSgpICsgIlwiLCBkb2VzIG5vdCBzdXBwb3J0IHRoZSByZXNldCBmdW5jdGlvbmFsaXR5LiIKLSAgICAgICAgICAgICAgICAgICAgICAgICsgIiAgU3BlY2lmaWNhdGlvbiBcIiIgKyB0aGlzLmdldENsYXNzKCkuZ2V0UGFja2FnZSgpLmdldFNwZWNpZmljYXRpb25UaXRsZSgpICsgIlwiIgotICAgICAgICAgICAgICAgICAgICAgICAgKyAiIHZlcnNpb24gXCIiICsgdGhpcy5nZXRDbGFzcygpLmdldFBhY2thZ2UoKS5nZXRTcGVjaWZpY2F0aW9uVmVyc2lvbigpICsgIlwiIgotICAgICAgICAgICAgICAgICAgICAgICAgKTsKLSAgICAgICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+VHJhbnNmb3JtIHRoZSBYTUwgPGNvZGU+U291cmNlPC9jb2RlPiB0byBhIDxjb2RlPlJlc3VsdDwvY29kZT4uCi0gICAgICogU3BlY2lmaWMgdHJhbnNmb3JtYXRpb24gYmVoYXZpb3IgaXMgZGV0ZXJtaW5lZCBieSB0aGUgc2V0dGluZ3Mgb2YgdGhlCi0gICAgICogPGNvZGU+VHJhbnNmb3JtZXJGYWN0b3J5PC9jb2RlPiBpbiBlZmZlY3Qgd2hlbiB0aGUKLSAgICAgKiA8Y29kZT5UcmFuc2Zvcm1lcjwvY29kZT4gd2FzIGluc3RhbnRpYXRlZCBhbmQgYW55IG1vZGlmaWNhdGlvbnMgbWFkZSB0bwotICAgICAqIHRoZSA8Y29kZT5UcmFuc2Zvcm1lcjwvY29kZT4gaW5zdGFuY2UuPC9wPgotICAgICAqCi0gICAgICogPHA+QW4gZW1wdHkgPGNvZGU+U291cmNlPC9jb2RlPiBpcyByZXByZXNlbnRlZCBhcyBhbiBlbXB0eSBkb2N1bWVudAotICAgICAqIGFzIGNvbnN0cnVjdGVkIGJ5IHtAbGluayBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXIjbmV3RG9jdW1lbnQoKX0uCi0gICAgICogVGhlIHJlc3VsdCBvZiB0cmFuc2Zvcm1pbmcgYW4gZW1wdHkgPGNvZGU+U291cmNlPC9jb2RlPiBkZXBlbmRzIG9uCi0gICAgICogdGhlIHRyYW5zZm9ybWF0aW9uIGJlaGF2aW9yOyBpdCBpcyBub3QgYWx3YXlzIGFuIGVtcHR5Ci0gICAgICogPGNvZGU+UmVzdWx0PC9jb2RlPi48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0geG1sU291cmNlIFRoZSBYTUwgaW5wdXQgdG8gdHJhbnNmb3JtLgotICAgICAqIEBwYXJhbSBvdXRwdXRUYXJnZXQgVGhlIDxjb2RlPlJlc3VsdDwvY29kZT4gb2YgdHJhbnNmb3JtaW5nIHRoZQotICAgICAqICAgPGNvZGU+eG1sU291cmNlPC9jb2RlPi4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24gSWYgYW4gdW5yZWNvdmVyYWJsZSBlcnJvciBvY2N1cnMKLSAgICAgKiAgIGR1cmluZyB0aGUgY291cnNlIG9mIHRoZSB0cmFuc2Zvcm1hdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCB0cmFuc2Zvcm0oU291cmNlIHhtbFNvdXJjZSwgUmVzdWx0IG91dHB1dFRhcmdldCkKLSAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogQWRkIGEgcGFyYW1ldGVyIGZvciB0aGUgdHJhbnNmb3JtYXRpb24uCi0gICAgICoKLSAgICAgKiA8cD5QYXNzIGEgcXVhbGlmaWVkIG5hbWUgYXMgYSB0d28tcGFydCBzdHJpbmcsIHRoZSBuYW1lc3BhY2UgVVJJCi0gICAgICogZW5jbG9zZWQgaW4gY3VybHkgYnJhY2VzICh7fSksIGZvbGxvd2VkIGJ5IHRoZSBsb2NhbCBuYW1lLiBJZiB0aGUKLSAgICAgKiBuYW1lIGhhcyBhIG51bGwgVVJMLCB0aGUgU3RyaW5nIG9ubHkgY29udGFpbiB0aGUgbG9jYWwgbmFtZS4gQW4KLSAgICAgKiBhcHBsaWNhdGlvbiBjYW4gc2FmZWx5IGNoZWNrIGZvciBhIG5vbi1udWxsIFVSSSBieSB0ZXN0aW5nIHRvIHNlZSBpZiB0aGUKLSAgICAgKiBmaXJzdCBjaGFyYWN0ZXIgb2YgdGhlIG5hbWUgaXMgYSAneycgY2hhcmFjdGVyLjwvcD4KLSAgICAgKiA8cD5Gb3IgZXhhbXBsZSwgaWYgYSBVUkkgYW5kIGxvY2FsIG5hbWUgd2VyZSBvYnRhaW5lZCBmcm9tIGFuIGVsZW1lbnQKLSAgICAgKiBkZWZpbmVkIHdpdGggJmx0O3h5ejpmb28KLSAgICAgKiB4bWxuczp4eXo9Imh0dHA6Ly94eXouZm9vLmNvbS95YWRhL2Jhei5odG1sIi8mZ3Q7LAotICAgICAqIHRoZW4gdGhlIHF1YWxpZmllZCBuYW1lIHdvdWxkIGJlICJ7aHR0cDovL3h5ei5mb28uY29tL3lhZGEvYmF6Lmh0bWx9Zm9vIi4KLSAgICAgKiBOb3RlIHRoYXQgbm8gcHJlZml4IGlzIHVzZWQuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIHBhcmFtZXRlciwgd2hpY2ggbWF5IGJlZ2luIHdpdGggYQotICAgICAqIG5hbWVzcGFjZSBVUkkgaW4gY3VybHkgYnJhY2VzICh7fSkuCi0gICAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZSBvYmplY3QuICBUaGlzIGNhbiBiZSBhbnkgdmFsaWQgSmF2YSBvYmplY3QuIEl0IGlzCi0gICAgICogdXAgdG8gdGhlIHByb2Nlc3NvciB0byBwcm92aWRlIHRoZSBwcm9wZXIgb2JqZWN0IGNvZXJzaW9uIG9yIHRvIHNpbXBseQotICAgICAqIHBhc3MgdGhlIG9iamVjdCBvbiBmb3IgdXNlIGluIGFuIGV4dGVuc2lvbi4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gSWYgdmFsdWUgaXMgbnVsbC4KLSAgICAgKi8KLSAgICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2V0UGFyYW1ldGVyKFN0cmluZyBuYW1lLCBPYmplY3QgdmFsdWUpOwotCi0gICAgLyoqCi0gICAgICogR2V0IGEgcGFyYW1ldGVyIHRoYXQgd2FzIGV4cGxpY2l0bHkgc2V0IHdpdGggc2V0UGFyYW1ldGVyLgotICAgICAqCi0gICAgICogPHA+VGhpcyBtZXRob2QgZG9lcyBub3QgcmV0dXJuIGEgZGVmYXVsdCBwYXJhbWV0ZXIgdmFsdWUsIHdoaWNoCi0gICAgICogY2Fubm90IGJlIGRldGVybWluZWQgdW50aWwgdGhlIG5vZGUgY29udGV4dCBpcyBldmFsdWF0ZWQgZHVyaW5nCi0gICAgICogdGhlIHRyYW5zZm9ybWF0aW9uIHByb2Nlc3MuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSBvZiA8Y29kZT5PYmplY3Q8L2NvZGU+IHRvIGdldAotICAgICAqCi0gICAgICogQHJldHVybiBBIHBhcmFtZXRlciB0aGF0IGhhcyBiZWVuIHNldCB3aXRoIHNldFBhcmFtZXRlci4KLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3QgT2JqZWN0IGdldFBhcmFtZXRlcihTdHJpbmcgbmFtZSk7Ci0KLSAgICAvKioKLSAgICAgKiA8cD5TZXQgYSBsaXN0IG9mIHBhcmFtZXRlcnMuPC9wPgotICAgICAqCi0gICAgICogPHA+Tm90ZSB0aGF0IHRoZSBsaXN0IG9mIHBhcmFtZXRlcnMgaXMgc3BlY2lmaWVkIGFzIGEKLSAgICAgKiA8Y29kZT5Qcm9wZXJ0aWVzPC9jb2RlPiA8Y29kZT5PYmplY3Q8L2NvZGU+IHdoaWNoIGxpbWl0cyB0aGUgcGFyYW1ldGVyCi0gICAgICogdmFsdWVzIHRvIDxjb2RlPlN0cmluZzwvY29kZT5zLiAgTXVsdGlwbGUgY2FsbHMgdG8KLSAgICAgKiB7QGxpbmsgI3NldFBhcmFtZXRlcihTdHJpbmcgbmFtZSwgT2JqZWN0IHZhbHVlKX0gc2hvdWxkIGJlIHVzZWQgd2hlbiB0aGUKLSAgICAgKiBkZXNpcmVkIHZhbHVlcyBhcmUgbm9uLTxjb2RlPlN0cmluZzwvY29kZT4gPGNvZGU+T2JqZWN0PC9jb2RlPnMuCi0gICAgICogVGhlIHBhcmFtZXRlciBuYW1lcyBzaG91bGQgY29uZm9ybSBhcyBzcGVjaWZpZWQgaW4KLSAgICAgKiB7QGxpbmsgI3NldFBhcmFtZXRlcihTdHJpbmcgbmFtZSwgT2JqZWN0IHZhbHVlKX0uCi0gICAgICogQW4gPGNvZGU+SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uPC9jb2RlPiBpcyB0aHJvd24gaWYgYW55IG5hbWVzIGRvIG5vdAotICAgICAqIGNvbmZvcm0uPC9wPgotICAgICAqCi0gICAgICogPHA+TmV3IHBhcmFtZXRlcnMgaW4gdGhlIGxpc3QgYXJlIGFkZGVkIHRvIGFueSBleGlzdGluZyBwYXJhbWV0ZXJzLgotICAgICAqIElmIHRoZSBuYW1lIG9mIGEgbmV3IHBhcmFtZXRlciBpcyBlcXVhbCB0byB0aGUgbmFtZSBvZiBhbiBleGlzdGluZwotICAgICAqIHBhcmFtZXRlciBhcyBkZXRlcm1pbmVkIGJ5IHtAbGluayBqYXZhLmxhbmcuT2JqZWN0I2VxdWFscyhPYmplY3Qgb2JqKX0sCi0gICAgICogIHRoZSBleGlzdGluZyBwYXJhbWV0ZXIgaXMgc2V0IHRvIHRoZSBuZXcgdmFsdWUuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIHBhcmFtcyBQYXJhbWV0ZXJzIHRvIHNldC4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIElmIGFueSBwYXJhbWV0ZXIgbmFtZXMgZG8gbm90IGNvbmZvcm0KLSAgICAgKiAgIHRvIHRoZSBuYW1pbmcgcnVsZXMuCi0gICAgICovCi0KLSAgICAvKioKLSAgICAgKiBDbGVhciBhbGwgcGFyYW1ldGVycyBzZXQgd2l0aCBzZXRQYXJhbWV0ZXIuCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IHZvaWQgY2xlYXJQYXJhbWV0ZXJzKCk7Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgYW4gb2JqZWN0IHRoYXQgd2lsbCBiZSB1c2VkIHRvIHJlc29sdmUgVVJJcyB1c2VkIGluCi0gICAgICogZG9jdW1lbnQoKS4KLSAgICAgKgotICAgICAqIDxwPklmIHRoZSByZXNvbHZlciBhcmd1bWVudCBpcyBudWxsLCB0aGUgVVJJUmVzb2x2ZXIgdmFsdWUgd2lsbAotICAgICAqIGJlIGNsZWFyZWQgYW5kIHRoZSB0cmFuc2Zvcm1lciB3aWxsIG5vIGxvbmdlciBoYXZlIGEgcmVzb2x2ZXIuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIHJlc29sdmVyIEFuIG9iamVjdCB0aGF0IGltcGxlbWVudHMgdGhlIFVSSVJlc29sdmVyIGludGVyZmFjZSwKLSAgICAgKiBvciBudWxsLgotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHNldFVSSVJlc29sdmVyKFVSSVJlc29sdmVyIHJlc29sdmVyKTsKLQotICAgIC8qKgotICAgICAqIEdldCBhbiBvYmplY3QgdGhhdCB3aWxsIGJlIHVzZWQgdG8gcmVzb2x2ZSBVUklzIHVzZWQgaW4KLSAgICAgKiBkb2N1bWVudCgpLgotICAgICAqCi0gICAgICogQHJldHVybiBBbiBvYmplY3QgdGhhdCBpbXBsZW1lbnRzIHRoZSBVUklSZXNvbHZlciBpbnRlcmZhY2UsCi0gICAgICogb3IgbnVsbC4KLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3QgVVJJUmVzb2x2ZXIgZ2V0VVJJUmVzb2x2ZXIoKTsKLQotICAgIC8qKgotICAgICAqIFNldCB0aGUgb3V0cHV0IHByb3BlcnRpZXMgZm9yIHRoZSB0cmFuc2Zvcm1hdGlvbi4gIFRoZXNlCi0gICAgICogcHJvcGVydGllcyB3aWxsIG92ZXJyaWRlIHByb3BlcnRpZXMgc2V0IGluIHRoZSBUZW1wbGF0ZXMKLSAgICAgKiB3aXRoIHhzbDpvdXRwdXQuCi0gICAgICoKLSAgICAgKiA8cD5JZiBhcmd1bWVudCB0byB0aGlzIGZ1bmN0aW9uIGlzIG51bGwsIGFueSBwcm9wZXJ0aWVzCi0gICAgICogcHJldmlvdXNseSBzZXQgYXJlIHJlbW92ZWQsIGFuZCB0aGUgdmFsdWUgd2lsbCByZXZlcnQgdG8gdGhlIHZhbHVlCi0gICAgICogZGVmaW5lZCBpbiB0aGUgdGVtcGxhdGVzIG9iamVjdC48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5QYXNzIGEgcXVhbGlmaWVkIHByb3BlcnR5IGtleSBuYW1lIGFzIGEgdHdvLXBhcnQgc3RyaW5nLCB0aGUgbmFtZXNwYWNlCi0gICAgICogVVJJIGVuY2xvc2VkIGluIGN1cmx5IGJyYWNlcyAoe30pLCBmb2xsb3dlZCBieSB0aGUgbG9jYWwgbmFtZS4gSWYgdGhlCi0gICAgICogbmFtZSBoYXMgYSBudWxsIFVSTCwgdGhlIFN0cmluZyBvbmx5IGNvbnRhaW4gdGhlIGxvY2FsIG5hbWUuIEFuCi0gICAgICogYXBwbGljYXRpb24gY2FuIHNhZmVseSBjaGVjayBmb3IgYSBub24tbnVsbCBVUkkgYnkgdGVzdGluZyB0byBzZWUgaWYgdGhlCi0gICAgICogZmlyc3QgY2hhcmFjdGVyIG9mIHRoZSBuYW1lIGlzIGEgJ3snIGNoYXJhY3Rlci48L3A+Ci0gICAgICogPHA+Rm9yIGV4YW1wbGUsIGlmIGEgVVJJIGFuZCBsb2NhbCBuYW1lIHdlcmUgb2J0YWluZWQgZnJvbSBhbiBlbGVtZW50Ci0gICAgICogZGVmaW5lZCB3aXRoICZsdDt4eXo6Zm9vCi0gICAgICogeG1sbnM6eHl6PSJodHRwOi8veHl6LmZvby5jb20veWFkYS9iYXouaHRtbCIvJmd0OywKLSAgICAgKiB0aGVuIHRoZSBxdWFsaWZpZWQgbmFtZSB3b3VsZCBiZSAie2h0dHA6Ly94eXouZm9vLmNvbS95YWRhL2Jhei5odG1sfWZvbyIuCi0gICAgICogTm90ZSB0aGF0IG5vIHByZWZpeCBpcyB1c2VkLjwvcD4KLSAgICAgKiBBbiA8Y29kZT5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb248L2NvZGU+IGlzIHRocm93biAgaWYgYW55IG9mIHRoZQotICAgICAqIGFyZ3VtZW50IGtleXMgYXJlIG5vdCByZWNvZ25pemVkIGFuZCBhcmUgbm90IG5hbWVzcGFjZSBxdWFsaWZpZWQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gb2Zvcm1hdCBBIHNldCBvZiBvdXRwdXQgcHJvcGVydGllcyB0aGF0IHdpbGwgYmUKLSAgICAgKiAgIHVzZWQgdG8gb3ZlcnJpZGUgYW55IG9mIHRoZSBzYW1lIHByb3BlcnRpZXMgaW4gYWZmZWN0Ci0gICAgICogICBmb3IgdGhlIHRyYW5zZm9ybWF0aW9uLgotICAgICAqCi0gICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gV2hlbiBrZXlzIGFyZSBub3QgcmVjb2duaXplZCBhbmQKLSAgICAgKiAgIGFyZSBub3QgbmFtZXNwYWNlIHF1YWxpZmllZC4KLSAgICAgKgotICAgICAqIEBzZWUgamF2YXgueG1sLnRyYW5zZm9ybS5PdXRwdXRLZXlzCi0gICAgICogQHNlZSBqYXZhLnV0aWwuUHJvcGVydGllcwotICAgICAqCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2V0T3V0cHV0UHJvcGVydGllcyhQcm9wZXJ0aWVzIG9mb3JtYXQpOwotCi0gICAgLyoqCi0gICAgICogPHA+R2V0IGEgY29weSBvZiB0aGUgb3V0cHV0IHByb3BlcnRpZXMgZm9yIHRoZSB0cmFuc2Zvcm1hdGlvbi48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5UaGUgcHJvcGVydGllcyByZXR1cm5lZCBzaG91bGQgY29udGFpbiBwcm9wZXJ0aWVzIHNldCBieSB0aGUgdXNlciwKLSAgICAgKiBhbmQgcHJvcGVydGllcyBzZXQgYnkgdGhlIHN0eWxlc2hlZXQsIGFuZCB0aGVzZSBwcm9wZXJ0aWVzCi0gICAgICogYXJlICJkZWZhdWx0ZWQiIGJ5IGRlZmF1bHQgcHJvcGVydGllcyBzcGVjaWZpZWQgYnkKLSAgICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I291dHB1dCI+c2VjdGlvbiAxNiBvZiB0aGUKLSAgICAgKiBYU0wgVHJhbnNmb3JtYXRpb25zIChYU0xUKSBXM0MgUmVjb21tZW5kYXRpb248L2E+LiAgVGhlIHByb3BlcnRpZXMgdGhhdAotICAgICAqIHdlcmUgc3BlY2lmaWNhbGx5IHNldCBieSB0aGUgdXNlciBvciB0aGUgc3R5bGVzaGVldCBzaG91bGQgYmUgaW4gdGhlIGJhc2UKLSAgICAgKiBQcm9wZXJ0aWVzIGxpc3QsIHdoaWxlIHRoZSBYU0xUIGRlZmF1bHQgcHJvcGVydGllcyB0aGF0IHdlcmUgbm90Ci0gICAgICogc3BlY2lmaWNhbGx5IHNldCBzaG91bGQgYmUgdGhlIGRlZmF1bHQgUHJvcGVydGllcyBsaXN0LiAgVGh1cywKLSAgICAgKiBnZXRPdXRwdXRQcm9wZXJ0aWVzKCkuZ2V0UHJvcGVydHkoU3RyaW5nIGtleSkgd2lsbCBvYnRhaW4gYW55Ci0gICAgICogcHJvcGVydHkgaW4gdGhhdCB3YXMgc2V0IGJ5IHtAbGluayAjc2V0T3V0cHV0UHJvcGVydHl9LAotICAgICAqIHtAbGluayAjc2V0T3V0cHV0UHJvcGVydGllc30sIGluIHRoZSBzdHlsZXNoZWV0LCA8ZW0+b3I8L2VtPiB0aGUgZGVmYXVsdAotICAgICAqIHByb3BlcnRpZXMsIHdoaWxlCi0gICAgICogZ2V0T3V0cHV0UHJvcGVydGllcygpLmdldChTdHJpbmcga2V5KSB3aWxsIG9ubHkgcmV0cmlldmUgcHJvcGVydGllcwotICAgICAqIHRoYXQgd2VyZSBleHBsaWNpdGx5IHNldCBieSB7QGxpbmsgI3NldE91dHB1dFByb3BlcnR5fSwKLSAgICAgKiB7QGxpbmsgI3NldE91dHB1dFByb3BlcnRpZXN9LCBvciBpbiB0aGUgc3R5bGVzaGVldC48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5Ob3RlIHRoYXQgbXV0YXRpb24gb2YgdGhlIFByb3BlcnRpZXMgb2JqZWN0IHJldHVybmVkIHdpbGwgbm90Ci0gICAgICogZWZmZWN0IHRoZSBwcm9wZXJ0aWVzIHRoYXQgdGhlIHRyYW5zZm9ybWVyIGNvbnRhaW5zLjwvcD4KLSAgICAgKgotICAgICAqIDxwPklmIGFueSBvZiB0aGUgYXJndW1lbnQga2V5cyBhcmUgbm90IHJlY29nbml6ZWQgYW5kIGFyZSBub3QKLSAgICAgKiBuYW1lc3BhY2UgcXVhbGlmaWVkLCB0aGUgcHJvcGVydHkgd2lsbCBiZSBpZ25vcmVkIGFuZCBub3QgcmV0dXJuZWQuCi0gICAgICogSW4gb3RoZXIgd29yZHMgdGhlIGJlaGF2aW91ciBpcyBub3Qgb3J0aG9nb25hbCB3aXRoCi0gICAgICoge0BsaW5rICNzZXRPdXRwdXRQcm9wZXJ0aWVzIHNldE91dHB1dFByb3BlcnRpZXN9LjwvcD4KLSAgICAgKgotICAgICAqIEByZXR1cm4gQSBjb3B5IG9mIHRoZSBzZXQgb2Ygb3V0cHV0IHByb3BlcnRpZXMgaW4gZWZmZWN0IGZvcgotICAgICAqICAgdGhlIG5leHQgdHJhbnNmb3JtYXRpb24uCi0gICAgICoKLSAgICAgKiBAc2VlIGphdmF4LnhtbC50cmFuc2Zvcm0uT3V0cHV0S2V5cwotICAgICAqIEBzZWUgamF2YS51dGlsLlByb3BlcnRpZXMKLSAgICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjb3V0cHV0Ij4KLSAgICAgKiAgIFhTTCBUcmFuc2Zvcm1hdGlvbnMgKFhTTFQpIFZlcnNpb24gMS4wPC9hPgotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCBQcm9wZXJ0aWVzIGdldE91dHB1dFByb3BlcnRpZXMoKTsKLQotICAgIC8qKgotICAgICAqIFNldCBhbiBvdXRwdXQgcHJvcGVydHkgdGhhdCB3aWxsIGJlIGluIGVmZmVjdCBmb3IgdGhlCi0gICAgICogdHJhbnNmb3JtYXRpb24uCi0gICAgICoKLSAgICAgKiA8cD5QYXNzIGEgcXVhbGlmaWVkIHByb3BlcnR5IG5hbWUgYXMgYSB0d28tcGFydCBzdHJpbmcsIHRoZSBuYW1lc3BhY2UgVVJJCi0gICAgICogZW5jbG9zZWQgaW4gY3VybHkgYnJhY2VzICh7fSksIGZvbGxvd2VkIGJ5IHRoZSBsb2NhbCBuYW1lLiBJZiB0aGUKLSAgICAgKiBuYW1lIGhhcyBhIG51bGwgVVJMLCB0aGUgU3RyaW5nIG9ubHkgY29udGFpbiB0aGUgbG9jYWwgbmFtZS4gQW4KLSAgICAgKiBhcHBsaWNhdGlvbiBjYW4gc2FmZWx5IGNoZWNrIGZvciBhIG5vbi1udWxsIFVSSSBieSB0ZXN0aW5nIHRvIHNlZSBpZiB0aGUKLSAgICAgKiBmaXJzdCBjaGFyYWN0ZXIgb2YgdGhlIG5hbWUgaXMgYSAneycgY2hhcmFjdGVyLjwvcD4KLSAgICAgKiA8cD5Gb3IgZXhhbXBsZSwgaWYgYSBVUkkgYW5kIGxvY2FsIG5hbWUgd2VyZSBvYnRhaW5lZCBmcm9tIGFuIGVsZW1lbnQKLSAgICAgKiBkZWZpbmVkIHdpdGggJmx0O3h5ejpmb28KLSAgICAgKiB4bWxuczp4eXo9Imh0dHA6Ly94eXouZm9vLmNvbS95YWRhL2Jhei5odG1sIi8mZ3Q7LAotICAgICAqIHRoZW4gdGhlIHF1YWxpZmllZCBuYW1lIHdvdWxkIGJlICJ7aHR0cDovL3h5ei5mb28uY29tL3lhZGEvYmF6Lmh0bWx9Zm9vIi4KLSAgICAgKiBOb3RlIHRoYXQgbm8gcHJlZml4IGlzIHVzZWQuPC9wPgotICAgICAqCi0gICAgICogPHA+VGhlIFByb3BlcnRpZXMgb2JqZWN0IHRoYXQgd2FzIHBhc3NlZCB0byB7QGxpbmsgI3NldE91dHB1dFByb3BlcnRpZXN9Ci0gICAgICogd29uJ3QgYmUgZWZmZWN0ZWQgYnkgY2FsbGluZyB0aGlzIG1ldGhvZC48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSBBIG5vbi1udWxsIFN0cmluZyB0aGF0IHNwZWNpZmllcyBhbiBvdXRwdXQKLSAgICAgKiBwcm9wZXJ0eSBuYW1lLCB3aGljaCBtYXkgYmUgbmFtZXNwYWNlIHF1YWxpZmllZC4KLSAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG5vbi1udWxsIHN0cmluZyB2YWx1ZSBvZiB0aGUgb3V0cHV0IHByb3BlcnR5LgotICAgICAqCi0gICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gSWYgdGhlIHByb3BlcnR5IGlzIG5vdCBzdXBwb3J0ZWQsIGFuZCBpcwotICAgICAqIG5vdCBxdWFsaWZpZWQgd2l0aCBhIG5hbWVzcGFjZS4KLSAgICAgKgotICAgICAqIEBzZWUgamF2YXgueG1sLnRyYW5zZm9ybS5PdXRwdXRLZXlzCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2V0T3V0cHV0UHJvcGVydHkoU3RyaW5nIG5hbWUsIFN0cmluZyB2YWx1ZSkKLSAgICAgICAgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIDxwPkdldCBhbiBvdXRwdXQgcHJvcGVydHkgdGhhdCBpcyBpbiBlZmZlY3QgZm9yIHRoZSB0cmFuc2Zvcm1lci48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5JZiBhIHByb3BlcnR5IGhhcyBiZWVuIHNldCB1c2luZyB7QGxpbmsgI3NldE91dHB1dFByb3BlcnR5fSwKLSAgICAgKiB0aGF0IHZhbHVlIHdpbGwgYmUgcmV0dXJuZWQuIE90aGVyd2lzZSwgaWYgYSBwcm9wZXJ0eSBpcyBleHBsaWNpdGx5Ci0gICAgICogc3BlY2lmaWVkIGluIHRoZSBzdHlsZXNoZWV0LCB0aGF0IHZhbHVlIHdpbGwgYmUgcmV0dXJuZWQuIElmCi0gICAgICogdGhlIHZhbHVlIG9mIHRoZSBwcm9wZXJ0eSBoYXMgYmVlbiBkZWZhdWx0ZWQsIHRoYXQgaXMsIGlmIG5vCi0gICAgICogdmFsdWUgaGFzIGJlZW4gc2V0IGV4cGxpY2l0bHkgZWl0aGVyIHdpdGgge0BsaW5rICNzZXRPdXRwdXRQcm9wZXJ0eX0gb3IKLSAgICAgKiBpbiB0aGUgc3R5bGVzaGVldCwgdGhlIHJlc3VsdCBtYXkgdmFyeSBkZXBlbmRpbmcgb24KLSAgICAgKiBpbXBsZW1lbnRhdGlvbiBhbmQgaW5wdXQgc3R5bGVzaGVldC48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSBBIG5vbi1udWxsIFN0cmluZyB0aGF0IHNwZWNpZmllcyBhbiBvdXRwdXQKLSAgICAgKiBwcm9wZXJ0eSBuYW1lLCB3aGljaCBtYXkgYmUgbmFtZXNwYWNlIHF1YWxpZmllZC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIHN0cmluZyB2YWx1ZSBvZiB0aGUgb3V0cHV0IHByb3BlcnR5LCBvciBudWxsCi0gICAgICogaWYgbm8gcHJvcGVydHkgd2FzIGZvdW5kLgotICAgICAqCi0gICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gSWYgdGhlIHByb3BlcnR5IGlzIG5vdCBzdXBwb3J0ZWQuCi0gICAgICoKLSAgICAgKiBAc2VlIGphdmF4LnhtbC50cmFuc2Zvcm0uT3V0cHV0S2V5cwotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCBTdHJpbmcgZ2V0T3V0cHV0UHJvcGVydHkoU3RyaW5nIG5hbWUpCi0gICAgICAgIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIGVycm9yIGV2ZW50IGxpc3RlbmVyIGluIGVmZmVjdCBmb3IgdGhlIHRyYW5zZm9ybWF0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIGxpc3RlbmVyIFRoZSBuZXcgZXJyb3IgbGlzdGVuZXIuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiBsaXN0ZW5lciBpcyBudWxsLgotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHNldEVycm9yTGlzdGVuZXIoRXJyb3JMaXN0ZW5lciBsaXN0ZW5lcikKLSAgICAgICAgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgZXJyb3IgZXZlbnQgaGFuZGxlciBpbiBlZmZlY3QgZm9yIHRoZSB0cmFuc2Zvcm1hdGlvbi4KLSAgICAgKiBJbXBsZW1lbnRhdGlvbnMgbXVzdCBwcm92aWRlIGEgZGVmYXVsdCBlcnJvciBsaXN0ZW5lci4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIGN1cnJlbnQgZXJyb3IgaGFuZGxlciwgd2hpY2ggc2hvdWxkIG5ldmVyIGJlIG51bGwuCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IEVycm9yTGlzdGVuZXIgZ2V0RXJyb3JMaXN0ZW5lcigpOwotfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmF4L3htbC90cmFuc2Zvcm0vVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uLmphdmEgYi9zcmMvamF2YXgveG1sL3RyYW5zZm9ybS9UcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOWUyZjNhZi4uMDAwMDAwMAotLS0gYS9zcmMvamF2YXgveG1sL3RyYW5zZm9ybS9UcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEwMiArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDAwLCAyMDA1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi1wYWNrYWdlIGphdmF4LnhtbC50cmFuc2Zvcm07Ci0KLS8qKgotICogSW5kaWNhdGVzIGEgc2VyaW91cyBjb25maWd1cmF0aW9uIGVycm9yLgotICovCi1wdWJsaWMgY2xhc3MgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIGV4dGVuZHMgVHJhbnNmb3JtZXJFeGNlcHRpb24gewotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlIGEgbmV3IDxjb2RlPlRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjwvY29kZT4gd2l0aCBubwotICAgICAqIGRldGFpbCBtZXNhZ2UuCi0gICAgICovCi0gICAgcHVibGljIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbigpIHsKLSAgICAgICAgc3VwZXIoIkNvbmZpZ3VyYXRpb24gRXJyb3IiKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGUgYSBuZXcgPGNvZGU+VHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uPC9jb2RlPiB3aXRoCi0gICAgICogdGhlIDxjb2RlPlN0cmluZyA8L2NvZGU+IHNwZWNpZmllZCBhcyBhbiBlcnJvciBtZXNzYWdlLgotICAgICAqCi0gICAgICogQHBhcmFtIG1zZyBUaGUgZXJyb3IgbWVzc2FnZSBmb3IgdGhlIGV4Y2VwdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uKFN0cmluZyBtc2cpIHsKLSAgICAgICAgc3VwZXIobXNnKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGUgYSBuZXcgPGNvZGU+VHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uPC9jb2RlPiB3aXRoIGEKLSAgICAgKiBnaXZlbiA8Y29kZT5FeGNlcHRpb248L2NvZGU+IGJhc2UgY2F1c2Ugb2YgdGhlIGVycm9yLgotICAgICAqCi0gICAgICogQHBhcmFtIGUgVGhlIGV4Y2VwdGlvbiB0byBiZSBlbmNhcHN1bGF0ZWQgaW4gYQotICAgICAqIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uKFRocm93YWJsZSBlKSB7Ci0gICAgICAgIHN1cGVyKGUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENyZWF0ZSBhIG5ldyA8Y29kZT5UcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb248L2NvZGU+IHdpdGggdGhlCi0gICAgICogZ2l2ZW4gPGNvZGU+RXhjZXB0aW9uPC9jb2RlPiBiYXNlIGNhdXNlIGFuZCBkZXRhaWwgbWVzc2FnZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlIFRoZSBleGNlcHRpb24gdG8gYmUgZW5jYXBzdWxhdGVkIGluIGEKLSAgICAgKiAgICAgIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbgotICAgICAqIEBwYXJhbSBtc2cgVGhlIGRldGFpbCBtZXNzYWdlLgotICAgICAqLwotICAgIHB1YmxpYyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24oU3RyaW5nIG1zZywgVGhyb3dhYmxlIGUpIHsKLSAgICAgICAgc3VwZXIobXNnLCBlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGUgYSBuZXcgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIGZyb20gYSBtZXNzYWdlIGFuZCBhIExvY2F0b3IuCi0gICAgICoKLSAgICAgKiA8cD5UaGlzIGNvbnN0cnVjdG9yIGlzIGVzcGVjaWFsbHkgdXNlZnVsIHdoZW4gYW4gYXBwbGljYXRpb24gaXMKLSAgICAgKiBjcmVhdGluZyBpdHMgb3duIGV4Y2VwdGlvbiBmcm9tIHdpdGhpbiBhIERvY3VtZW50SGFuZGxlcgotICAgICAqIGNhbGxiYWNrLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBtZXNzYWdlIFRoZSBlcnJvciBvciB3YXJuaW5nIG1lc3NhZ2UuCi0gICAgICogQHBhcmFtIGxvY2F0b3IgVGhlIGxvY2F0b3Igb2JqZWN0IGZvciB0aGUgZXJyb3Igb3Igd2FybmluZy4KLSAgICAgKi8KLSAgICBwdWJsaWMgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uKFN0cmluZyBtZXNzYWdlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU291cmNlTG9jYXRvciBsb2NhdG9yKSB7Ci0gICAgICAgIHN1cGVyKG1lc3NhZ2UsIGxvY2F0b3IpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFdyYXAgYW4gZXhpc3RpbmcgZXhjZXB0aW9uIGluIGEgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIG1lc3NhZ2UgVGhlIGVycm9yIG9yIHdhcm5pbmcgbWVzc2FnZSwgb3IgbnVsbCB0bwotICAgICAqICAgICAgICAgICAgICAgIHVzZSB0aGUgbWVzc2FnZSBmcm9tIHRoZSBlbWJlZGRlZCBleGNlcHRpb24uCi0gICAgICogQHBhcmFtIGxvY2F0b3IgVGhlIGxvY2F0b3Igb2JqZWN0IGZvciB0aGUgZXJyb3Igb3Igd2FybmluZy4KLSAgICAgKiBAcGFyYW0gZSBBbnkgZXhjZXB0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24oU3RyaW5nIG1lc3NhZ2UsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTb3VyY2VMb2NhdG9yIGxvY2F0b3IsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaHJvd2FibGUgZSkgewotICAgICAgICBzdXBlcihtZXNzYWdlLCBsb2NhdG9yLCBlKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvamF2YXgveG1sL3RyYW5zZm9ybS9UcmFuc2Zvcm1lckV4Y2VwdGlvbi5qYXZhIGIvc3JjL2phdmF4L3htbC90cmFuc2Zvcm0vVHJhbnNmb3JtZXJFeGNlcHRpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDk4NWViYi4uMDAwMDAwMAotLS0gYS9zcmMvamF2YXgveG1sL3RyYW5zZm9ybS9UcmFuc2Zvcm1lckV4Y2VwdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzcwICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDAsIDIwMDYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLXBhY2thZ2UgamF2YXgueG1sLnRyYW5zZm9ybTsKLQotaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lk1ldGhvZDsKLWltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5JbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uOwotCi0vKioKLSAqIFRoaXMgY2xhc3Mgc3BlY2lmaWVzIGFuIGV4Y2VwdGlvbmFsIGNvbmRpdGlvbiB0aGF0IG9jY3VyZWQKLSAqIGR1cmluZyB0aGUgdHJhbnNmb3JtYXRpb24gcHJvY2Vzcy4KLSAqLwotcHVibGljIGNsYXNzIFRyYW5zZm9ybWVyRXhjZXB0aW9uIGV4dGVuZHMgRXhjZXB0aW9uIHsKLQotICAgIC8qKiBGaWVsZCBsb2NhdG9yIHNwZWNpZmllcyB3aGVyZSB0aGUgZXJyb3Igb2NjdXJlZCAqLwotICAgIFNvdXJjZUxvY2F0b3IgbG9jYXRvcjsKLQotICAgIC8qKgotICAgICAqIE1ldGhvZCBnZXRMb2NhdG9yIHJldHJpZXZlcyBhbiBpbnN0YW5jZSBvZiBhIFNvdXJjZUxvY2F0b3IKLSAgICAgKiBvYmplY3QgdGhhdCBzcGVjaWZpZXMgd2hlcmUgYW4gZXJyb3Igb2NjdXJlZC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gQSBTb3VyY2VMb2NhdG9yIG9iamVjdCwgb3IgbnVsbCBpZiBub25lIHdhcyBzcGVjaWZpZWQuCi0gICAgICovCi0gICAgcHVibGljIFNvdXJjZUxvY2F0b3IgZ2V0TG9jYXRvcigpIHsKLSAgICAgICAgcmV0dXJuIGxvY2F0b3I7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogTWV0aG9kIHNldExvY2F0b3Igc2V0cyBhbiBpbnN0YW5jZSBvZiBhIFNvdXJjZUxvY2F0b3IKLSAgICAgKiBvYmplY3QgdGhhdCBzcGVjaWZpZXMgd2hlcmUgYW4gZXJyb3Igb2NjdXJlZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBsb2NhdGlvbiBBIFNvdXJjZUxvY2F0b3Igb2JqZWN0LCBvciBudWxsIHRvIGNsZWFyIHRoZSBsb2NhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRMb2NhdG9yKFNvdXJjZUxvY2F0b3IgbG9jYXRpb24pIHsKLSAgICAgICAgbG9jYXRvciA9IGxvY2F0aW9uOwotICAgIH0KLQotICAgIC8qKiBGaWVsZCBjb250YWluZWRFeGNlcHRpb24gc3BlY2lmaWVzIGEgd3JhcHBlZCBleGNlcHRpb24uICBNYXkgYmUgbnVsbC4gKi8KLSAgICBUaHJvd2FibGUgY29udGFpbmVkRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgcmV0cmlldmVzIGFuIGV4Y2VwdGlvbiB0aGF0IHRoaXMgZXhjZXB0aW9uIHdyYXBzLgotICAgICAqCi0gICAgICogQHJldHVybiBBbiBUaHJvd2FibGUgb2JqZWN0LCBvciBudWxsLgotICAgICAqIEBzZWUgI2dldENhdXNlCi0gICAgICovCi0gICAgcHVibGljIFRocm93YWJsZSBnZXRFeGNlcHRpb24oKSB7Ci0gICAgICAgIHJldHVybiBjb250YWluZWRFeGNlcHRpb247Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgY2F1c2Ugb2YgdGhpcyB0aHJvd2FibGUgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlCi0gICAgICogY2F1c2UgaXMgbm9uZXhpc3RlbnQgb3IgdW5rbm93bi4gIChUaGUgY2F1c2UgaXMgdGhlIHRocm93YWJsZSB0aGF0Ci0gICAgICogY2F1c2VkIHRoaXMgdGhyb3dhYmxlIHRvIGdldCB0aHJvd24uKQotICAgICAqLwotICAgIHB1YmxpYyBUaHJvd2FibGUgZ2V0Q2F1c2UoKSB7Ci0KLSAgICAgICAgcmV0dXJuICgoY29udGFpbmVkRXhjZXB0aW9uID09IHRoaXMpCi0gICAgICAgICAgICAgICAgPyBudWxsCi0gICAgICAgICAgICAgICAgOiBjb250YWluZWRFeGNlcHRpb24pOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEluaXRpYWxpemVzIHRoZSA8aT5jYXVzZTwvaT4gb2YgdGhpcyB0aHJvd2FibGUgdG8gdGhlIHNwZWNpZmllZCB2YWx1ZS4KLSAgICAgKiAoVGhlIGNhdXNlIGlzIHRoZSB0aHJvd2FibGUgdGhhdCBjYXVzZWQgdGhpcyB0aHJvd2FibGUgdG8gZ2V0IHRocm93bi4pCi0gICAgICoKLSAgICAgKiA8cD5UaGlzIG1ldGhvZCBjYW4gYmUgY2FsbGVkIGF0IG1vc3Qgb25jZS4gIEl0IGlzIGdlbmVyYWxseSBjYWxsZWQgZnJvbQotICAgICAqIHdpdGhpbiB0aGUgY29uc3RydWN0b3IsIG9yIGltbWVkaWF0ZWx5IGFmdGVyIGNyZWF0aW5nIHRoZQotICAgICAqIHRocm93YWJsZS4gIElmIHRoaXMgdGhyb3dhYmxlIHdhcyBjcmVhdGVkCi0gICAgICogd2l0aCB7QGxpbmsgI1RyYW5zZm9ybWVyRXhjZXB0aW9uKFRocm93YWJsZSl9IG9yCi0gICAgICoge0BsaW5rICNUcmFuc2Zvcm1lckV4Y2VwdGlvbihTdHJpbmcsVGhyb3dhYmxlKX0sIHRoaXMgbWV0aG9kIGNhbm5vdCBiZSBjYWxsZWQKLSAgICAgKiBldmVuIG9uY2UuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gIGNhdXNlIHRoZSBjYXVzZSAod2hpY2ggaXMgc2F2ZWQgZm9yIGxhdGVyIHJldHJpZXZhbCBieSB0aGUKLSAgICAgKiAgICAgICAgIHtAbGluayAjZ2V0Q2F1c2UoKX0gbWV0aG9kKS4gIChBIDxjb2RlPm51bGw8L2NvZGU+IHZhbHVlIGlzCi0gICAgICogICAgICAgICBwZXJtaXR0ZWQsIGFuZCBpbmRpY2F0ZXMgdGhhdCB0aGUgY2F1c2UgaXMgbm9uZXhpc3RlbnQgb3IKLSAgICAgKiAgICAgICAgIHVua25vd24uKQotICAgICAqIEByZXR1cm4gIGEgcmVmZXJlbmNlIHRvIHRoaXMgPGNvZGU+VGhyb3dhYmxlPC9jb2RlPiBpbnN0YW5jZS4KLSAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiA8Y29kZT5jYXVzZTwvY29kZT4gaXMgdGhpcwotICAgICAqICAgICAgICAgdGhyb3dhYmxlLiAgKEEgdGhyb3dhYmxlIGNhbm5vdAotICAgICAqICAgICAgICAgYmUgaXRzIG93biBjYXVzZS4pCi0gICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyB0aHJvd2FibGUgd2FzCi0gICAgICogICAgICAgICBjcmVhdGVkIHdpdGgge0BsaW5rICNUcmFuc2Zvcm1lckV4Y2VwdGlvbihUaHJvd2FibGUpfSBvcgotICAgICAqICAgICAgICAge0BsaW5rICNUcmFuc2Zvcm1lckV4Y2VwdGlvbihTdHJpbmcsVGhyb3dhYmxlKX0sIG9yIHRoaXMgbWV0aG9kIGhhcyBhbHJlYWR5Ci0gICAgICogICAgICAgICBiZWVuIGNhbGxlZCBvbiB0aGlzIHRocm93YWJsZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3luY2hyb25pemVkIFRocm93YWJsZSBpbml0Q2F1c2UoVGhyb3dhYmxlIGNhdXNlKSB7Ci0KLSAgICAgICAgaWYgKHRoaXMuY29udGFpbmVkRXhjZXB0aW9uICE9IG51bGwpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oIkNhbid0IG92ZXJ3cml0ZSBjYXVzZSIpOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKGNhdXNlID09IHRoaXMpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgIlNlbGYtY2F1c2F0aW9uIG5vdCBwZXJtaXR0ZWQiKTsKLSAgICAgICAgfQotCi0gICAgICAgIHRoaXMuY29udGFpbmVkRXhjZXB0aW9uID0gY2F1c2U7Ci0KLSAgICAgICAgcmV0dXJuIHRoaXM7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlIGEgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIG1lc3NhZ2UgVGhlIGVycm9yIG9yIHdhcm5pbmcgbWVzc2FnZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgVHJhbnNmb3JtZXJFeGNlcHRpb24oU3RyaW5nIG1lc3NhZ2UpIHsKLQotICAgICAgICBzdXBlcihtZXNzYWdlKTsKLQotICAgICAgICB0aGlzLmNvbnRhaW5lZEV4Y2VwdGlvbiA9IG51bGw7Ci0gICAgICAgIHRoaXMubG9jYXRvciAgICAgICAgICAgID0gbnVsbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGUgYSBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24gd3JhcHBpbmcgYW4gZXhpc3RpbmcgZXhjZXB0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIGUgVGhlIGV4Y2VwdGlvbiB0byBiZSB3cmFwcGVkLgotICAgICAqLwotICAgIHB1YmxpYyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihUaHJvd2FibGUgZSkgewotCi0gICAgICAgIHN1cGVyKGUudG9TdHJpbmcoKSk7Ci0KLSAgICAgICAgdGhpcy5jb250YWluZWRFeGNlcHRpb24gPSBlOwotICAgICAgICB0aGlzLmxvY2F0b3IgICAgICAgICAgICA9IG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogV3JhcCBhbiBleGlzdGluZyBleGNlcHRpb24gaW4gYSBUcmFuc2Zvcm1lckV4Y2VwdGlvbi4KLSAgICAgKgotICAgICAqIDxwPlRoaXMgaXMgdXNlZCBmb3IgdGhyb3dpbmcgcHJvY2Vzc29yIGV4Y2VwdGlvbnMgYmVmb3JlCi0gICAgICogdGhlIHByb2Nlc3NpbmcgaGFzIHN0YXJ0ZWQuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIG1lc3NhZ2UgVGhlIGVycm9yIG9yIHdhcm5pbmcgbWVzc2FnZSwgb3IgbnVsbCB0bwotICAgICAqICAgICAgICAgICAgICAgIHVzZSB0aGUgbWVzc2FnZSBmcm9tIHRoZSBlbWJlZGRlZCBleGNlcHRpb24uCi0gICAgICogQHBhcmFtIGUgQW55IGV4Y2VwdGlvbgotICAgICAqLwotICAgIHB1YmxpYyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihTdHJpbmcgbWVzc2FnZSwgVGhyb3dhYmxlIGUpIHsKLQotICAgICAgICBzdXBlcigoKG1lc3NhZ2UgPT0gbnVsbCkgfHwgKG1lc3NhZ2UubGVuZ3RoKCkgPT0gMCkpCi0gICAgICAgICAgICAgID8gZS50b1N0cmluZygpCi0gICAgICAgICAgICAgIDogbWVzc2FnZSk7Ci0KLSAgICAgICAgdGhpcy5jb250YWluZWRFeGNlcHRpb24gPSBlOwotICAgICAgICB0aGlzLmxvY2F0b3IgICAgICAgICAgICA9IG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlIGEgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uIGZyb20gYSBtZXNzYWdlIGFuZCBhIExvY2F0b3IuCi0gICAgICoKLSAgICAgKiA8cD5UaGlzIGNvbnN0cnVjdG9yIGlzIGVzcGVjaWFsbHkgdXNlZnVsIHdoZW4gYW4gYXBwbGljYXRpb24gaXMKLSAgICAgKiBjcmVhdGluZyBpdHMgb3duIGV4Y2VwdGlvbiBmcm9tIHdpdGhpbiBhIERvY3VtZW50SGFuZGxlcgotICAgICAqIGNhbGxiYWNrLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBtZXNzYWdlIFRoZSBlcnJvciBvciB3YXJuaW5nIG1lc3NhZ2UuCi0gICAgICogQHBhcmFtIGxvY2F0b3IgVGhlIGxvY2F0b3Igb2JqZWN0IGZvciB0aGUgZXJyb3Igb3Igd2FybmluZy4KLSAgICAgKi8KLSAgICBwdWJsaWMgVHJhbnNmb3JtZXJFeGNlcHRpb24oU3RyaW5nIG1lc3NhZ2UsIFNvdXJjZUxvY2F0b3IgbG9jYXRvcikgewotCi0gICAgICAgIHN1cGVyKG1lc3NhZ2UpOwotCi0gICAgICAgIHRoaXMuY29udGFpbmVkRXhjZXB0aW9uID0gbnVsbDsKLSAgICAgICAgdGhpcy5sb2NhdG9yICAgICAgICAgICAgPSBsb2NhdG9yOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFdyYXAgYW4gZXhpc3RpbmcgZXhjZXB0aW9uIGluIGEgVHJhbnNmb3JtZXJFeGNlcHRpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbWVzc2FnZSBUaGUgZXJyb3Igb3Igd2FybmluZyBtZXNzYWdlLCBvciBudWxsIHRvCi0gICAgICogICAgICAgICAgICAgICAgdXNlIHRoZSBtZXNzYWdlIGZyb20gdGhlIGVtYmVkZGVkIGV4Y2VwdGlvbi4KLSAgICAgKiBAcGFyYW0gbG9jYXRvciBUaGUgbG9jYXRvciBvYmplY3QgZm9yIHRoZSBlcnJvciBvciB3YXJuaW5nLgotICAgICAqIEBwYXJhbSBlIEFueSBleGNlcHRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgVHJhbnNmb3JtZXJFeGNlcHRpb24oU3RyaW5nIG1lc3NhZ2UsIFNvdXJjZUxvY2F0b3IgbG9jYXRvciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhyb3dhYmxlIGUpIHsKLQotICAgICAgICBzdXBlcihtZXNzYWdlKTsKLQotICAgICAgICB0aGlzLmNvbnRhaW5lZEV4Y2VwdGlvbiA9IGU7Ci0gICAgICAgIHRoaXMubG9jYXRvciAgICAgICAgICAgID0gbG9jYXRvcjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIGVycm9yIG1lc3NhZ2Ugd2l0aCBsb2NhdGlvbiBpbmZvcm1hdGlvbgotICAgICAqIGFwcGVuZGVkLgotICAgICAqCi0gICAgICogQHJldHVybiBBIDxjb2RlPlN0cmluZzwvY29kZT4gcmVwcmVzZW50aW5nIHRoZSBlcnJvciBtZXNzYWdlIHdpdGgKLSAgICAgKiAgICAgICAgIGxvY2F0aW9uIGluZm9ybWF0aW9uIGFwcGVuZGVkLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TWVzc2FnZUFuZExvY2F0aW9uKCkgewotCi0gICAgICAgIFN0cmluZ0J1ZmZlciBzYnVmZmVyID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotICAgICAgICBTdHJpbmcgICAgICAgbWVzc2FnZSA9IHN1cGVyLmdldE1lc3NhZ2UoKTsKLQotICAgICAgICBpZiAobnVsbCAhPSBtZXNzYWdlKSB7Ci0gICAgICAgICAgICBzYnVmZmVyLmFwcGVuZChtZXNzYWdlKTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChudWxsICE9IGxvY2F0b3IpIHsKLSAgICAgICAgICAgIFN0cmluZyBzeXN0ZW1JRCA9IGxvY2F0b3IuZ2V0U3lzdGVtSWQoKTsKLSAgICAgICAgICAgIGludCAgICBsaW5lICAgICA9IGxvY2F0b3IuZ2V0TGluZU51bWJlcigpOwotICAgICAgICAgICAgaW50ICAgIGNvbHVtbiAgID0gbG9jYXRvci5nZXRDb2x1bW5OdW1iZXIoKTsKLQotICAgICAgICAgICAgaWYgKG51bGwgIT0gc3lzdGVtSUQpIHsKLSAgICAgICAgICAgICAgICBzYnVmZmVyLmFwcGVuZCgiOyBTeXN0ZW1JRDogIik7Ci0gICAgICAgICAgICAgICAgc2J1ZmZlci5hcHBlbmQoc3lzdGVtSUQpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAoMCAhPSBsaW5lKSB7Ci0gICAgICAgICAgICAgICAgc2J1ZmZlci5hcHBlbmQoIjsgTGluZSM6ICIpOwotICAgICAgICAgICAgICAgIHNidWZmZXIuYXBwZW5kKGxpbmUpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAoMCAhPSBjb2x1bW4pIHsKLSAgICAgICAgICAgICAgICBzYnVmZmVyLmFwcGVuZCgiOyBDb2x1bW4jOiAiKTsKLSAgICAgICAgICAgICAgICBzYnVmZmVyLmFwcGVuZChjb2x1bW4pOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIHNidWZmZXIudG9TdHJpbmcoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIGxvY2F0aW9uIGluZm9ybWF0aW9uIGFzIGEgc3RyaW5nLgotICAgICAqCi0gICAgICogQHJldHVybiBBIHN0cmluZyB3aXRoIGxvY2F0aW9uIGluZm8sIG9yIG51bGwKLSAgICAgKiBpZiB0aGVyZSBpcyBubyBsb2NhdGlvbiBpbmZvcm1hdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldExvY2F0aW9uQXNTdHJpbmcoKSB7Ci0KLSAgICAgICAgaWYgKG51bGwgIT0gbG9jYXRvcikgewotICAgICAgICAgICAgU3RyaW5nQnVmZmVyIHNidWZmZXIgID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotICAgICAgICAgICAgU3RyaW5nICAgICAgIHN5c3RlbUlEID0gbG9jYXRvci5nZXRTeXN0ZW1JZCgpOwotICAgICAgICAgICAgaW50ICAgICAgICAgIGxpbmUgICAgID0gbG9jYXRvci5nZXRMaW5lTnVtYmVyKCk7Ci0gICAgICAgICAgICBpbnQgICAgICAgICAgY29sdW1uICAgPSBsb2NhdG9yLmdldENvbHVtbk51bWJlcigpOwotCi0gICAgICAgICAgICBpZiAobnVsbCAhPSBzeXN0ZW1JRCkgewotICAgICAgICAgICAgICAgIHNidWZmZXIuYXBwZW5kKCI7IFN5c3RlbUlEOiAiKTsKLSAgICAgICAgICAgICAgICBzYnVmZmVyLmFwcGVuZChzeXN0ZW1JRCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmICgwICE9IGxpbmUpIHsKLSAgICAgICAgICAgICAgICBzYnVmZmVyLmFwcGVuZCgiOyBMaW5lIzogIik7Ci0gICAgICAgICAgICAgICAgc2J1ZmZlci5hcHBlbmQobGluZSk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmICgwICE9IGNvbHVtbikgewotICAgICAgICAgICAgICAgIHNidWZmZXIuYXBwZW5kKCI7IENvbHVtbiM6ICIpOwotICAgICAgICAgICAgICAgIHNidWZmZXIuYXBwZW5kKGNvbHVtbik7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIHJldHVybiBzYnVmZmVyLnRvU3RyaW5nKCk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFByaW50IHRoZSB0aGUgdHJhY2Ugb2YgbWV0aG9kcyBmcm9tIHdoZXJlIHRoZSBlcnJvcgotICAgICAqIG9yaWdpbmF0ZWQuICBUaGlzIHdpbGwgdHJhY2UgYWxsIG5lc3RlZCBleGNlcHRpb24KLSAgICAgKiBvYmplY3RzLCBhcyB3ZWxsIGFzIHRoaXMgb2JqZWN0LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHByaW50U3RhY2tUcmFjZSgpIHsKLSAgICAgICAgcHJpbnRTdGFja1RyYWNlKG5ldyBqYXZhLmlvLlByaW50V3JpdGVyKFN5c3RlbS5lcnIsIHRydWUpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBQcmludCB0aGUgdGhlIHRyYWNlIG9mIG1ldGhvZHMgZnJvbSB3aGVyZSB0aGUgZXJyb3IKLSAgICAgKiBvcmlnaW5hdGVkLiAgVGhpcyB3aWxsIHRyYWNlIGFsbCBuZXN0ZWQgZXhjZXB0aW9uCi0gICAgICogb2JqZWN0cywgYXMgd2VsbCBhcyB0aGlzIG9iamVjdC4KLSAgICAgKiBAcGFyYW0gcyBUaGUgc3RyZWFtIHdoZXJlIHRoZSBkdW1wIHdpbGwgYmUgc2VudCB0by4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBwcmludFN0YWNrVHJhY2UoamF2YS5pby5QcmludFN0cmVhbSBzKSB7Ci0gICAgICAgIHByaW50U3RhY2tUcmFjZShuZXcgamF2YS5pby5QcmludFdyaXRlcihzKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUHJpbnQgdGhlIHRoZSB0cmFjZSBvZiBtZXRob2RzIGZyb20gd2hlcmUgdGhlIGVycm9yCi0gICAgICogb3JpZ2luYXRlZC4gIFRoaXMgd2lsbCB0cmFjZSBhbGwgbmVzdGVkIGV4Y2VwdGlvbgotICAgICAqIG9iamVjdHMsIGFzIHdlbGwgYXMgdGhpcyBvYmplY3QuCi0gICAgICogQHBhcmFtIHMgVGhlIHdyaXRlciB3aGVyZSB0aGUgZHVtcCB3aWxsIGJlIHNlbnQgdG8uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcHJpbnRTdGFja1RyYWNlKGphdmEuaW8uUHJpbnRXcml0ZXIgcykgewotCi0gICAgICAgIGlmIChzID09IG51bGwpIHsKLSAgICAgICAgICAgIHMgPSBuZXcgamF2YS5pby5QcmludFdyaXRlcihTeXN0ZW0uZXJyLCB0cnVlKTsKLSAgICAgICAgfQotCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBTdHJpbmcgbG9jSW5mbyA9IGdldExvY2F0aW9uQXNTdHJpbmcoKTsKLQotICAgICAgICAgICAgaWYgKG51bGwgIT0gbG9jSW5mbykgewotICAgICAgICAgICAgICAgIHMucHJpbnRsbihsb2NJbmZvKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgc3VwZXIucHJpbnRTdGFja1RyYWNlKHMpOwotICAgICAgICB9IGNhdGNoIChUaHJvd2FibGUgZSkge30KLQotICAgICAgICBUaHJvd2FibGUgZXhjZXB0aW9uID0gZ2V0RXhjZXB0aW9uKCk7Ci0KLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IChpIDwgMTApICYmIChudWxsICE9IGV4Y2VwdGlvbik7IGkrKykgewotICAgICAgICAgICAgcy5wcmludGxuKCItLS0tLS0tLS0iKTsKLQotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICBpZiAoZXhjZXB0aW9uIGluc3RhbmNlb2YgVHJhbnNmb3JtZXJFeGNlcHRpb24pIHsKLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGxvY0luZm8gPQotICAgICAgICAgICAgICAgICAgICAgICAgKChUcmFuc2Zvcm1lckV4Y2VwdGlvbikgZXhjZXB0aW9uKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRMb2NhdGlvbkFzU3RyaW5nKCk7Ci0KLSAgICAgICAgICAgICAgICAgICAgaWYgKG51bGwgIT0gbG9jSW5mbykgewotICAgICAgICAgICAgICAgICAgICAgICAgcy5wcmludGxuKGxvY0luZm8pOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgZXhjZXB0aW9uLnByaW50U3RhY2tUcmFjZShzKTsKLSAgICAgICAgICAgIH0gY2F0Y2ggKFRocm93YWJsZSBlKSB7Ci0gICAgICAgICAgICAgICAgcy5wcmludGxuKCJDb3VsZCBub3QgcHJpbnQgc3RhY2sgdHJhY2UuLi4iKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICBNZXRob2QgbWV0aCA9Ci0gICAgICAgICAgICAgICAgICAgICgoT2JqZWN0KSBleGNlcHRpb24pLmdldENsYXNzKCkuZ2V0TWV0aG9kKCJnZXRFeGNlcHRpb24iLAotICAgICAgICAgICAgICAgICAgICAgICAgKENsYXNzW10pIG51bGwpOwotCi0gICAgICAgICAgICAgICAgaWYgKG51bGwgIT0gbWV0aCkgewotICAgICAgICAgICAgICAgICAgICBUaHJvd2FibGUgcHJldiA9IGV4Y2VwdGlvbjsKLQotICAgICAgICAgICAgICAgICAgICBleGNlcHRpb24gPSAoVGhyb3dhYmxlKSBtZXRoLmludm9rZShleGNlcHRpb24sIChPYmplY3RbXSkgbnVsbCk7Ci0KLSAgICAgICAgICAgICAgICAgICAgaWYgKHByZXYgPT0gZXhjZXB0aW9uKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIGV4Y2VwdGlvbiA9IG51bGw7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfSBjYXRjaCAoSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbiBpdGUpIHsKLSAgICAgICAgICAgICAgICBleGNlcHRpb24gPSBudWxsOwotICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBpYWUpIHsKLSAgICAgICAgICAgICAgICBleGNlcHRpb24gPSBudWxsOwotICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoTWV0aG9kRXhjZXB0aW9uIG5zbWUpIHsKLSAgICAgICAgICAgICAgICBleGNlcHRpb24gPSBudWxsOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIC8vIGluc3VyZSBvdXRwdXQgaXMgd3JpdHRlbgotICAgICAgICBzLmZsdXNoKCk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmF4L3htbC90cmFuc2Zvcm0vVHJhbnNmb3JtZXJGYWN0b3J5LmphdmEgYi9zcmMvamF2YXgveG1sL3RyYW5zZm9ybS9UcmFuc2Zvcm1lckZhY3RvcnkuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggY2RlNjZkZS4uMDAwMDAwMAotLS0gYS9zcmMvamF2YXgveG1sL3RyYW5zZm9ybS9UcmFuc2Zvcm1lckZhY3RvcnkuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQxOSArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDAwLCAyMDEzLCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi1wYWNrYWdlIGphdmF4LnhtbC50cmFuc2Zvcm07Ci0KLS8qKgotICogPHA+QSBUcmFuc2Zvcm1lckZhY3RvcnkgaW5zdGFuY2UgY2FuIGJlIHVzZWQgdG8gY3JlYXRlCi0gKiB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lcn0gYW5kCi0gKiB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5UZW1wbGF0ZXN9IG9iamVjdHMuPC9wPgotICoKLSAqIDxwPlRoZSBzeXN0ZW0gcHJvcGVydHkgdGhhdCBkZXRlcm1pbmVzIHdoaWNoIEZhY3RvcnkgaW1wbGVtZW50YXRpb24KLSAqIHRvIGNyZWF0ZSBpcyBuYW1lZCA8Y29kZT4iamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckZhY3RvcnkiPC9jb2RlPi4KLSAqIFRoaXMgcHJvcGVydHkgbmFtZXMgYSBjb25jcmV0ZSBzdWJjbGFzcyBvZiB0aGUKLSAqIDxjb2RlPlRyYW5zZm9ybWVyRmFjdG9yeTwvY29kZT4gYWJzdHJhY3QgY2xhc3MuIElmIHRoZSBwcm9wZXJ0eSBpcyBub3QKLSAqIGRlZmluZWQsIGEgcGxhdGZvcm0gZGVmYXVsdCBpcyBiZSB1c2VkLjwvcD4KLSAqCi0gKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzpKZWZmLlN1dHRvckBTdW4uY29tIj5KZWZmIFN1dHRvcjwvYT4KLSAqIEBhdXRob3IgPGEgaHJlZj0ibWFpbHRvOk5lZXJhai5CYWphakBzdW4uY29tIj5OZWVyYWogQmFqYWo8L2E+Ci0gKgotICogQHNpbmNlIDEuNQotICovCi1wdWJsaWMgYWJzdHJhY3QgY2xhc3MgVHJhbnNmb3JtZXJGYWN0b3J5IHsKLQotICAgIC8qKgotICAgICAqIERlZmF1bHQgY29uc3RydWN0b3IgaXMgcHJvdGVjdGVkIG9uIHB1cnBvc2UuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIFRyYW5zZm9ybWVyRmFjdG9yeSgpIHsgfQotCi0KLQotICAgIC8qKgotICAgICAqIDxwPk9idGFpbiBhIG5ldyBpbnN0YW5jZSBvZiBhIDxjb2RlPlRyYW5zZm9ybWVyRmFjdG9yeTwvY29kZT4uCi0gICAgICogVGhpcyBzdGF0aWMgbWV0aG9kIGNyZWF0ZXMgYSBuZXcgZmFjdG9yeSBpbnN0YW5jZS48L3A+Ci0gICAgICogPHA+VGhpcyBtZXRob2QgdXNlcyB0aGUgZm9sbG93aW5nIG9yZGVyZWQgbG9va3VwIHByb2NlZHVyZSB0byBkZXRlcm1pbmUKLSAgICAgKiB0aGUgPGNvZGU+VHJhbnNmb3JtZXJGYWN0b3J5PC9jb2RlPiBpbXBsZW1lbnRhdGlvbiBjbGFzcyB0bwotICAgICAqIGxvYWQ6PC9wPgotICAgICAqIDx1bD4KLSAgICAgKiA8bGk+Ci0gICAgICogVXNlIHRoZSA8Y29kZT5qYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRmFjdG9yeTwvY29kZT4gc3lzdGVtCi0gICAgICogcHJvcGVydHkuCi0gICAgICogPC9saT4KLSAgICAgKiA8bGk+Ci0gICAgICogVXNlIHRoZSBwcm9wZXJ0aWVzIGZpbGUgImxpYi9qYXhwLnByb3BlcnRpZXMiIGluIHRoZSBKUkUgZGlyZWN0b3J5LgotICAgICAqIFRoaXMgY29uZmlndXJhdGlvbiBmaWxlIGlzIGluIHN0YW5kYXJkIDxjb2RlPmphdmEudXRpbC5Qcm9wZXJ0aWVzCi0gICAgICogPC9jb2RlPiBmb3JtYXQgYW5kIGNvbnRhaW5zIHRoZSBmdWxseSBxdWFsaWZpZWQgbmFtZSBvZiB0aGUKLSAgICAgKiBpbXBsZW1lbnRhdGlvbiBjbGFzcyB3aXRoIHRoZSBrZXkgYmVpbmcgdGhlIHN5c3RlbSBwcm9wZXJ0eSBkZWZpbmVkCi0gICAgICogYWJvdmUuCi0gICAgICogPGJyPgotICAgICAqIFRoZSBqYXhwLnByb3BlcnRpZXMgZmlsZSBpcyByZWFkIG9ubHkgb25jZSBieSB0aGUgSkFYUCBpbXBsZW1lbnRhdGlvbgotICAgICAqIGFuZCBpdCdzIHZhbHVlcyBhcmUgdGhlbiBjYWNoZWQgZm9yIGZ1dHVyZSB1c2UuICBJZiB0aGUgZmlsZSBkb2VzIG5vdCBleGlzdAotICAgICAqIHdoZW4gdGhlIGZpcnN0IGF0dGVtcHQgaXMgbWFkZSB0byByZWFkIGZyb20gaXQsIG5vIGZ1cnRoZXIgYXR0ZW1wdHMgYXJlCi0gICAgICogbWFkZSB0byBjaGVjayBmb3IgaXRzIGV4aXN0ZW5jZS4gIEl0IGlzIG5vdCBwb3NzaWJsZSB0byBjaGFuZ2UgdGhlIHZhbHVlCi0gICAgICogb2YgYW55IHByb3BlcnR5IGluIGpheHAucHJvcGVydGllcyBhZnRlciBpdCBoYXMgYmVlbiByZWFkIGZvciB0aGUgZmlyc3QgdGltZS4KLSAgICAgKiA8L2xpPgotICAgICAqIDxsaT4KLSAgICAgKiAgIFVzZSB0aGUgc2VydmljZS1wcm92aWRlciBsb2FkaW5nIGZhY2lsaXRpZXMsIGRlZmluZWQgYnkgdGhlCi0gICAgICogICB7QGxpbmsgamF2YS51dGlsLlNlcnZpY2VMb2FkZXJ9IGNsYXNzLCB0byBhdHRlbXB0IHRvIGxvY2F0ZSBhbmQgbG9hZCBhbgotICAgICAqICAgaW1wbGVtZW50YXRpb24gb2YgdGhlIHNlcnZpY2UgdXNpbmcgdGhlIHtAbGlua3BsYWluCi0gICAgICogICBqYXZhLnV0aWwuU2VydmljZUxvYWRlciNsb2FkKGphdmEubGFuZy5DbGFzcykgZGVmYXVsdCBsb2FkaW5nIG1lY2hhbmlzbX06Ci0gICAgICogICB0aGUgc2VydmljZS1wcm92aWRlciBsb2FkaW5nIGZhY2lsaXR5IHdpbGwgdXNlIHRoZSB7QGxpbmtwbGFpbgotICAgICAqICAgamF2YS5sYW5nLlRocmVhZCNnZXRDb250ZXh0Q2xhc3NMb2FkZXIoKSBjdXJyZW50IHRocmVhZCdzIGNvbnRleHQgY2xhc3MgbG9hZGVyfQotICAgICAqICAgdG8gYXR0ZW1wdCB0byBsb2FkIHRoZSBzZXJ2aWNlLiBJZiB0aGUgY29udGV4dCBjbGFzcwotICAgICAqICAgbG9hZGVyIGlzIG51bGwsIHRoZSB7QGxpbmtwbGFpbgotICAgICAqICAgQ2xhc3NMb2FkZXIjZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKSBzeXN0ZW0gY2xhc3MgbG9hZGVyfSB3aWxsIGJlIHVzZWQuCi0gICAgICogPC9saT4KLSAgICAgKiA8bGk+Ci0gICAgICogICBPdGhlcndpc2UsIHRoZSBzeXN0ZW0tZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBpcyByZXR1cm5lZC4KLSAgICAgKiA8L2xpPgotICAgICAqIDwvdWw+Ci0gICAgICoKLSAgICAgKiA8cD5PbmNlIGFuIGFwcGxpY2F0aW9uIGhhcyBvYnRhaW5lZCBhIHJlZmVyZW5jZSB0byBhIDxjb2RlPgotICAgICAqIFRyYW5zZm9ybWVyRmFjdG9yeTwvY29kZT4gaXQgY2FuIHVzZSB0aGUgZmFjdG9yeSB0byBjb25maWd1cmUKLSAgICAgKiBhbmQgb2J0YWluIHRyYW5zZm9ybWVyIGluc3RhbmNlcy48L3A+Ci0gICAgICoKLSAgICAgKiBAcmV0dXJuIG5ldyBUcmFuc2Zvcm1lckZhY3RvcnkgaW5zdGFuY2UsIG5ldmVyIG51bGwuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvciBUaHJvd24gaW4gY2FzZSBvZiB7QGxpbmtwbGFpbgotICAgICAqIGphdmEudXRpbC5TZXJ2aWNlQ29uZmlndXJhdGlvbkVycm9yIHNlcnZpY2UgY29uZmlndXJhdGlvbiBlcnJvcn0gb3IgaWYKLSAgICAgKiB0aGUgaW1wbGVtZW50YXRpb24gaXMgbm90IGF2YWlsYWJsZSBvciBjYW5ub3QgYmUgaW5zdGFudGlhdGVkLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgVHJhbnNmb3JtZXJGYWN0b3J5IG5ld0luc3RhbmNlKCkKLSAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvciB7Ci0KLSAgICAgICAgcmV0dXJuIEZhY3RvcnlGaW5kZXIuZmluZCgKLSAgICAgICAgICAgIC8qIFRoZSBkZWZhdWx0IHByb3BlcnR5IG5hbWUgYWNjb3JkaW5nIHRvIHRoZSBKQVhQIHNwZWMgKi8KLSAgICAgICAgICAgIFRyYW5zZm9ybWVyRmFjdG9yeS5jbGFzcywKLSAgICAgICAgICAgIC8qIFRoZSBmYWxsYmFjayBpbXBsZW1lbnRhdGlvbiBjbGFzcyBuYW1lLCBYU0xUQyAqLwotICAgICAgICAgICAgImNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy50cmF4LlRyYW5zZm9ybWVyRmFjdG9yeUltcGwiKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5PYnRhaW4gYSBuZXcgaW5zdGFuY2Ugb2YgYSA8Y29kZT5UcmFuc2Zvcm1lckZhY3Rvcnk8L2NvZGU+IGZyb20gZmFjdG9yeSBjbGFzcyBuYW1lLgotICAgICAqIFRoaXMgZnVuY3Rpb24gaXMgdXNlZnVsIHdoZW4gdGhlcmUgYXJlIG11bHRpcGxlIHByb3ZpZGVycyBpbiB0aGUgY2xhc3NwYXRoLgotICAgICAqIEl0IGdpdmVzIG1vcmUgY29udHJvbCB0byB0aGUgYXBwbGljYXRpb24gYXMgaXQgY2FuIHNwZWNpZnkgd2hpY2ggcHJvdmlkZXIKLSAgICAgKiBzaG91bGQgYmUgbG9hZGVkLjwvcD4KLSAgICAgKgotICAgICAqIDxwPk9uY2UgYW4gYXBwbGljYXRpb24gaGFzIG9idGFpbmVkIGEgcmVmZXJlbmNlIHRvIGEgPGNvZGU+Ci0gICAgICogVHJhbnNmb3JtZXJGYWN0b3J5PC9jb2RlPiBpdCBjYW4gdXNlIHRoZSBmYWN0b3J5IHRvIGNvbmZpZ3VyZQotICAgICAqIGFuZCBvYnRhaW4gdHJhbnNmb3JtZXIgaW5zdGFuY2VzLjwvcD4KLSAgICAgKgotICAgICAqIDxoMj5UaXAgZm9yIFRyb3VibGUtc2hvb3Rpbmc8L2gyPgotICAgICAqIDxwPlNldHRpbmcgdGhlIDxjb2RlPmpheHAuZGVidWc8L2NvZGU+IHN5c3RlbSBwcm9wZXJ0eSB3aWxsIGNhdXNlCi0gICAgICogdGhpcyBtZXRob2QgdG8gcHJpbnQgYSBsb3Qgb2YgZGVidWcgbWVzc2FnZXMKLSAgICAgKiB0byA8Y29kZT5TeXN0ZW0uZXJyPC9jb2RlPiBhYm91dCB3aGF0IGl0IGlzIGRvaW5nIGFuZCB3aGVyZSBpdCBpcyBsb29raW5nIGF0LjwvcD4KLSAgICAgKgotICAgICAqIDxwPiBJZiB5b3UgaGF2ZSBwcm9ibGVtcyB0cnk6PC9wPgotICAgICAqIDxwcmU+Ci0gICAgICogamF2YSAtRGpheHAuZGVidWc9MSBZb3VyUHJvZ3JhbSAuLi4uCi0gICAgICogPC9wcmU+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gZmFjdG9yeUNsYXNzTmFtZSBmdWxseSBxdWFsaWZpZWQgZmFjdG9yeSBjbGFzcyBuYW1lIHRoYXQgcHJvdmlkZXMgaW1wbGVtZW50YXRpb24gb2YgPGNvZGU+amF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckZhY3Rvcnk8L2NvZGU+LgotICAgICAqCi0gICAgICogQHBhcmFtIGNsYXNzTG9hZGVyIDxjb2RlPkNsYXNzTG9hZGVyPC9jb2RlPiB1c2VkIHRvIGxvYWQgdGhlIGZhY3RvcnkgY2xhc3MuIElmIDxjb2RlPm51bGw8L2NvZGU+Ci0gICAgICogICAgICAgICAgICAgICAgICAgICBjdXJyZW50IDxjb2RlPlRocmVhZDwvY29kZT4ncyBjb250ZXh0IGNsYXNzTG9hZGVyIGlzIHVzZWQgdG8gbG9hZCB0aGUgZmFjdG9yeSBjbGFzcy4KLSAgICAgKgotICAgICAqIEByZXR1cm4gbmV3IFRyYW5zZm9ybWVyRmFjdG9yeSBpbnN0YW5jZSwgbmV2ZXIgbnVsbC4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yCi0gICAgICogICAgICAgICAgICAgICAgICAgIGlmIDxjb2RlPmZhY3RvcnlDbGFzc05hbWU8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LCBvcgotICAgICAqICAgICAgICAgICAgICAgICAgIHRoZSBmYWN0b3J5IGNsYXNzIGNhbm5vdCBiZSBsb2FkZWQsIGluc3RhbnRpYXRlZC4KLSAgICAgKgotICAgICAqIEBzZWUgI25ld0luc3RhbmNlKCkKLSAgICAgKgotICAgICAqIEBzaW5jZSAxLjYKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFRyYW5zZm9ybWVyRmFjdG9yeSBuZXdJbnN0YW5jZShTdHJpbmcgZmFjdG9yeUNsYXNzTmFtZSwgQ2xhc3NMb2FkZXIgY2xhc3NMb2FkZXIpCi0gICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3J7Ci0KLSAgICAgICAgLy9kbyBub3QgZmFsbGJhY2sgaWYgZ2l2ZW4gY2xhc3Nsb2FkZXIgY2FuJ3QgZmluZCB0aGUgY2xhc3MsIHRocm93IGV4Y2VwdGlvbgotICAgICAgICByZXR1cm4gIEZhY3RvcnlGaW5kZXIubmV3SW5zdGFuY2UoVHJhbnNmb3JtZXJGYWN0b3J5LmNsYXNzLAotICAgICAgICAgICAgICAgICAgICBmYWN0b3J5Q2xhc3NOYW1lLCBjbGFzc0xvYWRlciwgZmFsc2UsIGZhbHNlKTsKLSAgICB9Ci0gICAgLyoqCi0gICAgICogPHA+UHJvY2VzcyB0aGUgPGNvZGU+U291cmNlPC9jb2RlPiBpbnRvIGEgPGNvZGU+VHJhbnNmb3JtZXI8L2NvZGU+Ci0gICAgICogPGNvZGU+T2JqZWN0PC9jb2RlPi4gIFRoZSA8Y29kZT5Tb3VyY2U8L2NvZGU+IGlzIGFuIFhTTFQgZG9jdW1lbnQgdGhhdAotICAgICAqIGNvbmZvcm1zIHRvIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQiPgotICAgICAqIFhTTCBUcmFuc2Zvcm1hdGlvbnMgKFhTTFQpIFZlcnNpb24gMS4wPC9hPi4gIENhcmUgbXVzdAotICAgICAqIGJlIHRha2VuIG5vdCB0byB1c2UgdGhpcyA8Y29kZT5UcmFuc2Zvcm1lcjwvY29kZT4gaW4gbXVsdGlwbGUKLSAgICAgKiA8Y29kZT5UaHJlYWQ8L2NvZGU+cyBydW5uaW5nIGNvbmN1cnJlbnRseS4KLSAgICAgKiBEaWZmZXJlbnQgPGNvZGU+VHJhbnNmb3JtZXJGYWN0b3JpZXM8L2NvZGU+IGNhbiBiZSB1c2VkIGNvbmN1cnJlbnRseSBieQotICAgICAqIGRpZmZlcmVudCA8Y29kZT5UaHJlYWQ8L2NvZGU+cy48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gc291cmNlIDxjb2RlPlNvdXJjZSA8L2NvZGU+IG9mIFhTTFQgZG9jdW1lbnQgdXNlZCB0byBjcmVhdGUKLSAgICAgKiAgIDxjb2RlPlRyYW5zZm9ybWVyPC9jb2RlPi4KLSAgICAgKiAgIEV4YW1wbGVzIG9mIFhNTCA8Y29kZT5Tb3VyY2U8L2NvZGU+cyBpbmNsdWRlCi0gICAgICogICB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5kb20uRE9NU291cmNlIERPTVNvdXJjZX0sCi0gICAgICogICB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5zYXguU0FYU291cmNlIFNBWFNvdXJjZX0sIGFuZAotICAgICAqICAge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uc3RyZWFtLlN0cmVhbVNvdXJjZSBTdHJlYW1Tb3VyY2V9LgotICAgICAqCi0gICAgICogQHJldHVybiBBIDxjb2RlPlRyYW5zZm9ybWVyPC9jb2RlPiBvYmplY3QgdGhhdCBtYXkgYmUgdXNlZCB0byBwZXJmb3JtCi0gICAgICogICBhIHRyYW5zZm9ybWF0aW9uIGluIGEgc2luZ2xlIDxjb2RlPlRocmVhZDwvY29kZT4sIG5ldmVyCi0gICAgICogICA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIFRocm93biBpZiB0aGVyZSBhcmUgZXJyb3JzIHdoZW4KLSAgICAgKiAgICBwYXJzaW5nIHRoZSA8Y29kZT5Tb3VyY2U8L2NvZGU+IG9yIGl0IGlzIG5vdCBwb3NzaWJsZSB0byBjcmVhdGUgYQotICAgICAqICAgPGNvZGU+VHJhbnNmb3JtZXI8L2NvZGU+IGluc3RhbmNlLgotICAgICAqCi0gICAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0Ij4KLSAgICAgKiAgIFhTTCBUcmFuc2Zvcm1hdGlvbnMgKFhTTFQpIFZlcnNpb24gMS4wPC9hPgotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCBUcmFuc2Zvcm1lciBuZXdUcmFuc2Zvcm1lcihTb3VyY2Ugc291cmNlKQotICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogPHA+Q3JlYXRlIGEgbmV3IDxjb2RlPlRyYW5zZm9ybWVyPC9jb2RlPiB0aGF0IHBlcmZvcm1zIGEgY29weQotICAgICAqIG9mIHRoZSA8Y29kZT5Tb3VyY2U8L2NvZGU+IHRvIHRoZSA8Y29kZT5SZXN1bHQ8L2NvZGU+LgotICAgICAqIGkuZS4gdGhlICI8ZW0+aWRlbnRpdHkgdHJhbnNmb3JtPC9lbT4iLjwvcD4KLSAgICAgKgotICAgICAqIEByZXR1cm4gQSBUcmFuc2Zvcm1lciBvYmplY3QgdGhhdCBtYXkgYmUgdXNlZCB0byBwZXJmb3JtIGEgdHJhbnNmb3JtYXRpb24KLSAgICAgKiBpbiBhIHNpbmdsZSB0aHJlYWQsIG5ldmVyIG51bGwuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBXaGVuIGl0IGlzIG5vdAotICAgICAqICAgcG9zc2libGUgdG8gY3JlYXRlIGEgPGNvZGU+VHJhbnNmb3JtZXI8L2NvZGU+IGluc3RhbmNlLgotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCBUcmFuc2Zvcm1lciBuZXdUcmFuc2Zvcm1lcigpCi0gICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBQcm9jZXNzIHRoZSBTb3VyY2UgaW50byBhIFRlbXBsYXRlcyBvYmplY3QsIHdoaWNoIGlzIGEKLSAgICAgKiBhIGNvbXBpbGVkIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBzb3VyY2UuIFRoaXMgVGVtcGxhdGVzIG9iamVjdAotICAgICAqIG1heSB0aGVuIGJlIHVzZWQgY29uY3VycmVudGx5IGFjcm9zcyBtdWx0aXBsZSB0aHJlYWRzLiAgQ3JlYXRpbmcKLSAgICAgKiBhIFRlbXBsYXRlcyBvYmplY3QgYWxsb3dzIHRoZSBUcmFuc2Zvcm1lckZhY3RvcnkgdG8gZG8gZGV0YWlsZWQKLSAgICAgKiBwZXJmb3JtYW5jZSBvcHRpbWl6YXRpb24gb2YgdHJhbnNmb3JtYXRpb24gaW5zdHJ1Y3Rpb25zLCB3aXRob3V0Ci0gICAgICogcGVuYWxpemluZyBydW50aW1lIHRyYW5zZm9ybWF0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIHNvdXJjZSBBbiBvYmplY3QgdGhhdCBob2xkcyBhIFVSTCwgaW5wdXQgc3RyZWFtLCBldGMuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIEEgVGVtcGxhdGVzIG9iamVjdCBjYXBhYmxlIG9mIGJlaW5nIHVzZWQgZm9yIHRyYW5zZm9ybWF0aW9uCi0gICAgICogICBwdXJwb3NlcywgbmV2ZXIgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBXaGVuIHBhcnNpbmcgdG8KLSAgICAgKiAgIGNvbnN0cnVjdCB0aGUgVGVtcGxhdGVzIG9iamVjdCBmYWlscy4KLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3QgVGVtcGxhdGVzIG5ld1RlbXBsYXRlcyhTb3VyY2Ugc291cmNlKQotICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogPHA+R2V0IHRoZSBzdHlsZXNoZWV0IHNwZWNpZmljYXRpb24ocykgYXNzb2NpYXRlZCB3aXRoIHRoZQotICAgICAqIFhNTCA8Y29kZT5Tb3VyY2U8L2NvZGU+IGRvY3VtZW50IHZpYSB0aGUKLSAgICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94bWwtc3R5bGVzaGVldC8iPgotICAgICAqIHhtbC1zdHlsZXNoZWV0IHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb248L2E+IHRoYXQgbWF0Y2ggdGhlIGdpdmVuIGNyaXRlcmlhLgotICAgICAqIE5vdGUgdGhhdCBpdCBpcyBwb3NzaWJsZSB0byByZXR1cm4gc2V2ZXJhbCBzdHlsZXNoZWV0cywgaW4gd2hpY2ggY2FzZQotICAgICAqIHRoZXkgYXJlIGFwcGxpZWQgYXMgaWYgdGhleSB3ZXJlIGEgbGlzdCBvZiBpbXBvcnRzIG9yIGNhc2NhZGVzIGluIGEKLSAgICAgKiBzaW5nbGUgc3R5bGVzaGVldC48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gc291cmNlIFRoZSBYTUwgc291cmNlIGRvY3VtZW50LgotICAgICAqIEBwYXJhbSBtZWRpYSBUaGUgbWVkaWEgYXR0cmlidXRlIHRvIGJlIG1hdGNoZWQuICBNYXkgYmUgbnVsbCwgaW4gd2hpY2gKLSAgICAgKiAgICAgIGNhc2UgdGhlIHByZWZlcmVkIHRlbXBsYXRlcyB3aWxsIGJlIHVzZWQgKGkuZS4gYWx0ZXJuYXRlID0gbm8pLgotICAgICAqIEBwYXJhbSB0aXRsZSBUaGUgdmFsdWUgb2YgdGhlIHRpdGxlIGF0dHJpYnV0ZSB0byBtYXRjaC4gIE1heSBiZSBudWxsLgotICAgICAqIEBwYXJhbSBjaGFyc2V0IFRoZSB2YWx1ZSBvZiB0aGUgY2hhcnNldCBhdHRyaWJ1dGUgdG8gbWF0Y2guICBNYXkgYmUgbnVsbC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gQSA8Y29kZT5Tb3VyY2U8L2NvZGU+IDxjb2RlPk9iamVjdDwvY29kZT4gc3VpdGFibGUgZm9yIHBhc3NpbmcKLSAgICAgKiAgIHRvIHRoZSA8Y29kZT5UcmFuc2Zvcm1lckZhY3Rvcnk8L2NvZGU+LgotICAgICAqCi0gICAgICogQHRocm93cyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gQW4gPGNvZGU+RXhjZXB0aW9uPC9jb2RlPgotICAgICAqICAgaXMgdGhyb3duIGlmIGFuIGVycm9yIG9jY3VyaW5ncyBkdXJpbmcgcGFyc2luZyBvZiB0aGUKLSAgICAgKiAgIDxjb2RlPnNvdXJjZTwvY29kZT4uCi0gICAgICoKLSAgICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3htbC1zdHlsZXNoZWV0LyI+Ci0gICAgICogICBBc3NvY2lhdGluZyBTdHlsZSBTaGVldHMgd2l0aCBYTUwgZG9jdW1lbnRzIFZlcnNpb24gMS4wPC9hPgotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCBTb3VyY2UgZ2V0QXNzb2NpYXRlZFN0eWxlc2hlZXQoCi0gICAgICAgIFNvdXJjZSBzb3VyY2UsCi0gICAgICAgIFN0cmluZyBtZWRpYSwKLSAgICAgICAgU3RyaW5nIHRpdGxlLAotICAgICAgICBTdHJpbmcgY2hhcnNldCkKLSAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIFNldCBhbiBvYmplY3QgdGhhdCBpcyB1c2VkIGJ5IGRlZmF1bHQgZHVyaW5nIHRoZSB0cmFuc2Zvcm1hdGlvbgotICAgICAqIHRvIHJlc29sdmUgVVJJcyB1c2VkIGluIGRvY3VtZW50KCksIHhzbDppbXBvcnQsIG9yIHhzbDppbmNsdWRlLgotICAgICAqCi0gICAgICogQHBhcmFtIHJlc29sdmVyIEFuIG9iamVjdCB0aGF0IGltcGxlbWVudHMgdGhlIFVSSVJlc29sdmVyIGludGVyZmFjZSwKLSAgICAgKiBvciBudWxsLgotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHNldFVSSVJlc29sdmVyKFVSSVJlc29sdmVyIHJlc29sdmVyKTsKLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgb2JqZWN0IHRoYXQgaXMgdXNlZCBieSBkZWZhdWx0IGR1cmluZyB0aGUgdHJhbnNmb3JtYXRpb24KLSAgICAgKiB0byByZXNvbHZlIFVSSXMgdXNlZCBpbiBkb2N1bWVudCgpLCB4c2w6aW1wb3J0LCBvciB4c2w6aW5jbHVkZS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIFVSSVJlc29sdmVyIHRoYXQgd2FzIHNldCB3aXRoIHNldFVSSVJlc29sdmVyLgotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCBVUklSZXNvbHZlciBnZXRVUklSZXNvbHZlcigpOwotCi0gICAgLy89PT09PT09IENPTkZJR1VSQVRJT04gTUVUSE9EUyA9PT09PT09Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIDxwPlNldCBhIGZlYXR1cmUgZm9yIHRoaXMgPGNvZGU+VHJhbnNmb3JtZXJGYWN0b3J5PC9jb2RlPiBhbmQgPGNvZGU+VHJhbnNmb3JtZXI8L2NvZGU+cwotICAgICAgICAgKiBvciA8Y29kZT5UZW1wbGF0ZTwvY29kZT5zIGNyZWF0ZWQgYnkgdGhpcyBmYWN0b3J5LjwvcD4KLSAgICAgICAgICoKLSAgICAgICAgICogPHA+Ci0gICAgICAgICAqIEZlYXR1cmUgbmFtZXMgYXJlIGZ1bGx5IHF1YWxpZmllZCB7QGxpbmsgamF2YS5uZXQuVVJJfXMuCi0gICAgICAgICAqIEltcGxlbWVudGF0aW9ucyBtYXkgZGVmaW5lIHRoZWlyIG93biBmZWF0dXJlcy4KLSAgICAgICAgICogQW4ge0BsaW5rIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbn0gaXMgdGhyb3duIGlmIHRoaXMgPGNvZGU+VHJhbnNmb3JtZXJGYWN0b3J5PC9jb2RlPiBvciB0aGUKLSAgICAgICAgICogPGNvZGU+VHJhbnNmb3JtZXI8L2NvZGU+cyBvciA8Y29kZT5UZW1wbGF0ZTwvY29kZT5zIGl0IGNyZWF0ZXMgY2Fubm90IHN1cHBvcnQgdGhlIGZlYXR1cmUuCi0gICAgICAgICAqIEl0IGlzIHBvc3NpYmxlIGZvciBhbiA8Y29kZT5UcmFuc2Zvcm1lckZhY3Rvcnk8L2NvZGU+IHRvIGV4cG9zZSBhIGZlYXR1cmUgdmFsdWUgYnV0IGJlIHVuYWJsZSB0byBjaGFuZ2UgaXRzIHN0YXRlLgotICAgICAgICAgKiA8L3A+Ci0gICAgICAgICAqCi0gICAgICAgICAqIDxwPkFsbCBpbXBsZW1lbnRhdGlvbnMgYXJlIHJlcXVpcmVkIHRvIHN1cHBvcnQgdGhlIHtAbGluayBqYXZheC54bWwuWE1MQ29uc3RhbnRzI0ZFQVRVUkVfU0VDVVJFX1BST0NFU1NJTkd9IGZlYXR1cmUuCi0gICAgICAgICAqIFdoZW4gdGhlIGZlYXR1cmUgaXM6PC9wPgotICAgICAgICAgKiA8dWw+Ci0gICAgICAgICAqICAgPGxpPgotICAgICAgICAgKiAgICAgPGNvZGU+dHJ1ZTwvY29kZT46IHRoZSBpbXBsZW1lbnRhdGlvbiB3aWxsIGxpbWl0IFhNTCBwcm9jZXNzaW5nIHRvIGNvbmZvcm0gdG8gaW1wbGVtZW50YXRpb24gbGltaXRzCi0gICAgICAgICAqICAgICBhbmQgYmVoYXZlIGluIGEgc2VjdXJlIGZhc2hpb24gYXMgZGVmaW5lZCBieSB0aGUgaW1wbGVtZW50YXRpb24uCi0gICAgICAgICAqICAgICBFeGFtcGxlcyBpbmNsdWRlIHJlc29sdmluZyB1c2VyIGRlZmluZWQgc3R5bGUgc2hlZXRzIGFuZCBmdW5jdGlvbnMuCi0gICAgICAgICAqICAgICBJZiBYTUwgcHJvY2Vzc2luZyBpcyBsaW1pdGVkIGZvciBzZWN1cml0eSByZWFzb25zLCBpdCB3aWxsIGJlIHJlcG9ydGVkIHZpYSBhIGNhbGwgdG8gdGhlIHJlZ2lzdGVyZWQKLSAgICAgICAgICogICAgIHtAbGluayBFcnJvckxpc3RlbmVyI2ZhdGFsRXJyb3IoVHJhbnNmb3JtZXJFeGNlcHRpb24gZXhjZXB0aW9uKX0uCi0gICAgICAgICAqICAgICBTZWUge0BsaW5rICAjc2V0RXJyb3JMaXN0ZW5lcihFcnJvckxpc3RlbmVyIGxpc3RlbmVyKX0uCi0gICAgICAgICAqICAgPC9saT4KLSAgICAgICAgICogICA8bGk+Ci0gICAgICAgICAqICAgICA8Y29kZT5mYWxzZTwvY29kZT46IHRoZSBpbXBsZW1lbnRhdGlvbiB3aWxsIHByb2Nlc3NpbmcgWE1MIGFjY29yZGluZyB0byB0aGUgWE1MIHNwZWNpZmljYXRpb25zIHdpdGhvdXQKLSAgICAgICAgICogICAgIHJlZ2FyZCB0byBwb3NzaWJsZSBpbXBsZW1lbnRhdGlvbiBsaW1pdHMuCi0gICAgICAgICAqICAgPC9saT4KLSAgICAgICAgICogPC91bD4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIG5hbWUgRmVhdHVyZSBuYW1lLgotICAgICAgICAgKiBAcGFyYW0gdmFsdWUgSXMgZmVhdHVyZSBzdGF0ZSA8Y29kZT50cnVlPC9jb2RlPiBvciA8Y29kZT5mYWxzZTwvY29kZT4uCi0gICAgICAgICAqCi0gICAgICAgICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIGlmIHRoaXMgPGNvZGU+VHJhbnNmb3JtZXJGYWN0b3J5PC9jb2RlPgotICAgICAgICAgKiAgIG9yIHRoZSA8Y29kZT5UcmFuc2Zvcm1lcjwvY29kZT5zIG9yIDxjb2RlPlRlbXBsYXRlPC9jb2RlPnMgaXQgY3JlYXRlcyBjYW5ub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCi0gICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBJZiB0aGUgPGNvZGU+bmFtZTwvY29kZT4gcGFyYW1ldGVyIGlzIG51bGwuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRGZWF0dXJlKFN0cmluZyBuYW1lLCBib29sZWFuIHZhbHVlKQotICAgICAgICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBMb29rIHVwIHRoZSB2YWx1ZSBvZiBhIGZlYXR1cmUuCi0gICAgICoKLSAgICAgICAgICogPHA+Ci0gICAgICAgICAqIEZlYXR1cmUgbmFtZXMgYXJlIGZ1bGx5IHF1YWxpZmllZCB7QGxpbmsgamF2YS5uZXQuVVJJfXMuCi0gICAgICAgICAqIEltcGxlbWVudGF0aW9ucyBtYXkgZGVmaW5lIHRoZWlyIG93biBmZWF0dXJlcy4KLSAgICAgICAgICogPGNvZGU+ZmFsc2U8L2NvZGU+IGlzIHJldHVybmVkIGlmIHRoaXMgPGNvZGU+VHJhbnNmb3JtZXJGYWN0b3J5PC9jb2RlPiBvciB0aGUKLSAgICAgICAgICogPGNvZGU+VHJhbnNmb3JtZXI8L2NvZGU+cyBvciA8Y29kZT5UZW1wbGF0ZTwvY29kZT5zIGl0IGNyZWF0ZXMgY2Fubm90IHN1cHBvcnQgdGhlIGZlYXR1cmUuCi0gICAgICAgICAqIEl0IGlzIHBvc3NpYmxlIGZvciBhbiA8Y29kZT5UcmFuc2Zvcm1lckZhY3Rvcnk8L2NvZGU+IHRvIGV4cG9zZSBhIGZlYXR1cmUgdmFsdWUgYnV0IGJlIHVuYWJsZSB0byBjaGFuZ2UgaXRzIHN0YXRlLgotICAgICAgICAgKiA8L3A+Ci0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBuYW1lIEZlYXR1cmUgbmFtZS4KLSAgICAgICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBjdXJyZW50IHN0YXRlIG9mIHRoZSBmZWF0dXJlLCA8Y29kZT50cnVlPC9jb2RlPiBvciA8Y29kZT5mYWxzZTwvY29kZT4uCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIElmIHRoZSA8Y29kZT5uYW1lPC9jb2RlPiBwYXJhbWV0ZXIgaXMgbnVsbC4KLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBnZXRGZWF0dXJlKFN0cmluZyBuYW1lKTsKLQotICAgIC8qKgotICAgICAqIEFsbG93cyB0aGUgdXNlciB0byBzZXQgc3BlY2lmaWMgYXR0cmlidXRlcyBvbiB0aGUgdW5kZXJseWluZwotICAgICAqIGltcGxlbWVudGF0aW9uLiAgQW4gYXR0cmlidXRlIGluIHRoaXMgY29udGV4dCBpcyBkZWZpbmVkIHRvCi0gICAgICogYmUgYW4gb3B0aW9uIHRoYXQgdGhlIGltcGxlbWVudGF0aW9uIHByb3ZpZGVzLgotICAgICAqIEFuIDxjb2RlPklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbjwvY29kZT4gaXMgdGhyb3duIGlmIHRoZSB1bmRlcmx5aW5nCi0gICAgICogaW1wbGVtZW50YXRpb24gZG9lc24ndCByZWNvZ25pemUgdGhlIGF0dHJpYnV0ZS4KLSAgICAgKiA8cD4KLSAgICAgKiBBbGwgaW1wbGVtZW50YXRpb25zIHRoYXQgaW1wbGVtZW50IEpBWFAgMS41IG9yIG5ld2VyIGFyZSByZXF1aXJlZCB0bwotICAgICAqIHN1cHBvcnQgdGhlIHtAbGluayBqYXZheC54bWwuWE1MQ29uc3RhbnRzI0FDQ0VTU19FWFRFUk5BTF9EVER9ICBhbmQKLSAgICAgKiB7QGxpbmsgamF2YXgueG1sLlhNTENvbnN0YW50cyNBQ0NFU1NfRVhURVJOQUxfU1RZTEVTSEVFVH0gcHJvcGVydGllcy4KLSAgICAgKiA8L3A+Ci0gICAgICogPHVsPgotICAgICAqICAgPGxpPgotICAgICAqICAgICAgPHA+Ci0gICAgICogICAgICBBY2Nlc3MgdG8gZXh0ZXJuYWwgRFREcyBpbiB0aGUgc291cmNlIGZpbGUgaXMgcmVzdHJpY3RlZCB0byB0aGUgcHJvdG9jb2xzCi0gICAgICogICAgICBzcGVjaWZpZWQgYnkgdGhlIHtAbGluayBqYXZheC54bWwuWE1MQ29uc3RhbnRzI0FDQ0VTU19FWFRFUk5BTF9EVER9IHByb3BlcnR5LgotICAgICAqICAgICAgSWYgYWNjZXNzIGlzIGRlbmllZCBkdXJpbmcgdHJhbnNmb3JtYXRpb24gZHVlIHRvIHRoZSByZXN0cmljdGlvbiBvZiB0aGlzIHByb3BlcnR5LAotICAgICAqICAgICAge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb259IHdpbGwgYmUgdGhyb3duIGJ5Ci0gICAgICogICAgICB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lciN0cmFuc2Zvcm0oU291cmNlLCBSZXN1bHQpfS4KLSAgICAgKiAgICAgIDwvcD4KLSAgICAgKiAgICAgIDxwPgotICAgICAqICAgICAgQWNjZXNzIHRvIGV4dGVybmFsIERURHMgaW4gdGhlIHN0eWxlc2hlZXQgaXMgcmVzdHJpY3RlZCB0byB0aGUgcHJvdG9jb2xzCi0gICAgICogICAgICBzcGVjaWZpZWQgYnkgdGhlIHtAbGluayBqYXZheC54bWwuWE1MQ29uc3RhbnRzI0FDQ0VTU19FWFRFUk5BTF9EVER9IHByb3BlcnR5LgotICAgICAqICAgICAgSWYgYWNjZXNzIGlzIGRlbmllZCBkdXJpbmcgdGhlIGNyZWF0aW9uIG9mIGEgbmV3IHRyYW5zZm9ybWVyIGR1ZSB0byB0aGUKLSAgICAgKiAgICAgIHJlc3RyaWN0aW9uIG9mIHRoaXMgcHJvcGVydHksCi0gICAgICogICAgICB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb259IHdpbGwgYmUgdGhyb3duCi0gICAgICogICAgICBieSB0aGUge0BsaW5rICNuZXdUcmFuc2Zvcm1lcihTb3VyY2UpfSBtZXRob2QuCi0gICAgICogICAgICA8L3A+Ci0gICAgICogICAgICA8cD4KLSAgICAgKiAgICAgIEFjY2VzcyB0byBleHRlcm5hbCByZWZlcmVuY2Ugc2V0IGJ5IHRoZSBzdHlsZXNoZWV0IHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24sCi0gICAgICogICAgICBJbXBvcnQgYW5kIEluY2x1ZGUgZWxlbWVudCBpcyByZXN0cmljdGVkIHRvIHRoZSBwcm90b2NvbHMgc3BlY2lmaWVkIGJ5IHRoZQotICAgICAqICAgICAge0BsaW5rIGphdmF4LnhtbC5YTUxDb25zdGFudHMjQUNDRVNTX0VYVEVSTkFMX1NUWUxFU0hFRVR9IHByb3BlcnR5LgotICAgICAqICAgICAgSWYgYWNjZXNzIGlzIGRlbmllZCBkdXJpbmcgdGhlIGNyZWF0aW9uIG9mIGEgbmV3IHRyYW5zZm9ybWVyIGR1ZSB0byB0aGUKLSAgICAgKiAgICAgIHJlc3RyaWN0aW9uIG9mIHRoaXMgcHJvcGVydHksCi0gICAgICogICAgICB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb259IHdpbGwgYmUgdGhyb3duCi0gICAgICogICAgICBieSB0aGUge0BsaW5rICNuZXdUcmFuc2Zvcm1lcihTb3VyY2UpfSBtZXRob2QuCi0gICAgICogICAgICA8L3A+Ci0gICAgICogICAgICA8cD4KLSAgICAgKiAgICAgIEFjY2VzcyB0byBleHRlcm5hbCBkb2N1bWVudCB0aHJvdWdoIFhTTFQgZG9jdW1lbnQgZnVuY3Rpb24gaXMgcmVzdHJpY3RlZAotICAgICAqICAgICAgdG8gdGhlIHByb3RvY29scyBzcGVjaWZpZWQgYnkgdGhlIHByb3BlcnR5LiBJZiBhY2Nlc3MgaXMgZGVuaWVkIGR1cmluZwotICAgICAqICAgICAgdGhlIHRyYW5zZm9ybWF0aW9uIGR1ZSB0byB0aGUgcmVzdHJpY3Rpb24gb2YgdGhpcyBwcm9wZXJ0eSwKLSAgICAgKiAgICAgIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9ufSB3aWxsIGJlIHRocm93biBieSB0aGUKLSAgICAgKiAgICAgIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyI3RyYW5zZm9ybShTb3VyY2UsIFJlc3VsdCl9IG1ldGhvZC4KLSAgICAgKiAgICAgIDwvcD4KLSAgICAgKiAgIDwvbGk+Ci0gICAgICogPC91bD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUuCi0gICAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZSBvZiB0aGUgYXR0cmlidXRlLgotICAgICAqCi0gICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gV2hlbiBpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdAotICAgICAqICAgcmVjb2duaXplIHRoZSBhdHRyaWJ1dGUuCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2V0QXR0cmlidXRlKFN0cmluZyBuYW1lLCBPYmplY3QgdmFsdWUpOwotCi0gICAgLyoqCi0gICAgICogQWxsb3dzIHRoZSB1c2VyIHRvIHJldHJpZXZlIHNwZWNpZmljIGF0dHJpYnV0ZXMgb24gdGhlIHVuZGVybHlpbmcKLSAgICAgKiBpbXBsZW1lbnRhdGlvbi4KLSAgICAgKiBBbiA8Y29kZT5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb248L2NvZGU+IGlzIHRocm93biBpZiB0aGUgdW5kZXJseWluZwotICAgICAqIGltcGxlbWVudGF0aW9uIGRvZXNuJ3QgcmVjb2duaXplIHRoZSBhdHRyaWJ1dGUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlLgotICAgICAqCi0gICAgICogQHJldHVybiB2YWx1ZSBUaGUgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIFdoZW4gaW1wbGVtZW50YXRpb24gZG9lcyBub3QKLSAgICAgKiAgIHJlY29nbml6ZSB0aGUgYXR0cmlidXRlLgotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCBPYmplY3QgZ2V0QXR0cmlidXRlKFN0cmluZyBuYW1lKTsKLQotICAgIC8qKgotICAgICAqIFNldCB0aGUgZXJyb3IgZXZlbnQgbGlzdGVuZXIgZm9yIHRoZSBUcmFuc2Zvcm1lckZhY3RvcnksIHdoaWNoCi0gICAgICogaXMgdXNlZCBmb3IgdGhlIHByb2Nlc3Npbmcgb2YgdHJhbnNmb3JtYXRpb24gaW5zdHJ1Y3Rpb25zLAotICAgICAqIGFuZCBub3QgZm9yIHRoZSB0cmFuc2Zvcm1hdGlvbiBpdHNlbGYuCi0gICAgICogQW4gPGNvZGU+SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uPC9jb2RlPiBpcyB0aHJvd24gaWYgdGhlCi0gICAgICogPGNvZGU+RXJyb3JMaXN0ZW5lcjwvY29kZT4gbGlzdGVuZXIgaXMgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbGlzdGVuZXIgVGhlIG5ldyBlcnJvciBsaXN0ZW5lci4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIFdoZW4gPGNvZGU+bGlzdGVuZXI8L2NvZGU+IGlzCi0gICAgICogICA8Y29kZT5udWxsPC9jb2RlPgotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHNldEVycm9yTGlzdGVuZXIoRXJyb3JMaXN0ZW5lciBsaXN0ZW5lcik7Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIGVycm9yIGV2ZW50IGhhbmRsZXIgZm9yIHRoZSBUcmFuc2Zvcm1lckZhY3RvcnkuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBjdXJyZW50IGVycm9yIGhhbmRsZXIsIHdoaWNoIHNob3VsZCBuZXZlciBiZSBudWxsLgotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCBFcnJvckxpc3RlbmVyIGdldEVycm9yTGlzdGVuZXIoKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmF4L3htbC90cmFuc2Zvcm0vVHJhbnNmb3JtZXJGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yLmphdmEgYi9zcmMvamF2YXgveG1sL3RyYW5zZm9ybS9UcmFuc2Zvcm1lckZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZmIwNjBiMC4uMDAwMDAwMAotLS0gYS9zcmMvamF2YXgveG1sL3RyYW5zZm9ybS9UcmFuc2Zvcm1lckZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEzMCArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDAwLCAyMDA1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi1wYWNrYWdlIGphdmF4LnhtbC50cmFuc2Zvcm07Ci0KLS8qKgotICogVGhyb3duIHdoZW4gYSBwcm9ibGVtIHdpdGggY29uZmlndXJhdGlvbiB3aXRoIHRoZSBUcmFuc2Zvcm1lciBGYWN0b3JpZXMKLSAqIGV4aXN0cy4gVGhpcyBlcnJvciB3aWxsIHR5cGljYWxseSBiZSB0aHJvd24gd2hlbiB0aGUgY2xhc3Mgb2YgYQotICogdHJhbnNmb3JtYXRpb24gZmFjdG9yeSBzcGVjaWZpZWQgaW4gdGhlIHN5c3RlbSBwcm9wZXJ0aWVzIGNhbm5vdCBiZSBmb3VuZAotICogb3IgaW5zdGFudGlhdGVkLgotICovCi1wdWJsaWMgY2xhc3MgVHJhbnNmb3JtZXJGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yIGV4dGVuZHMgRXJyb3IgewotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC02NTI3NzE4NzIwNjc2MjgxNTE2TDsKLQotICAgIC8qKgotICAgICAqIDxjb2RlPkV4Y2VwdGlvbjwvY29kZT4gZm9yIHRoZQotICAgICAqICA8Y29kZT5UcmFuc2Zvcm1lckZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3I8L2NvZGU+LgotICAgICAqLwotICAgIHByaXZhdGUgRXhjZXB0aW9uIGV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIENyZWF0ZSBhIG5ldyA8Y29kZT5UcmFuc2Zvcm1lckZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3I8L2NvZGU+IHdpdGggbm8KLSAgICAgKiBkZXRhaWwgbWVzYWdlLgotICAgICAqLwotICAgIHB1YmxpYyBUcmFuc2Zvcm1lckZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IoKSB7Ci0KLSAgICAgICAgc3VwZXIoKTsKLQotICAgICAgICB0aGlzLmV4Y2VwdGlvbiA9IG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlIGEgbmV3IDxjb2RlPlRyYW5zZm9ybWVyRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvcjwvY29kZT4gd2l0aAotICAgICAqIHRoZSA8Y29kZT5TdHJpbmc8L2NvZGU+IHNwZWNpZmllZCBhcyBhbiBlcnJvciBtZXNzYWdlLgotICAgICAqCi0gICAgICogQHBhcmFtIG1zZyBUaGUgZXJyb3IgbWVzc2FnZSBmb3IgdGhlIGV4Y2VwdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgVHJhbnNmb3JtZXJGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yKFN0cmluZyBtc2cpIHsKLQotICAgICAgICBzdXBlcihtc2cpOwotCi0gICAgICAgIHRoaXMuZXhjZXB0aW9uID0gbnVsbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGUgYSBuZXcgPGNvZGU+VHJhbnNmb3JtZXJGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yPC9jb2RlPiB3aXRoIGEKLSAgICAgKiBnaXZlbiA8Y29kZT5FeGNlcHRpb248L2NvZGU+IGJhc2UgY2F1c2Ugb2YgdGhlIGVycm9yLgotICAgICAqCi0gICAgICogQHBhcmFtIGUgVGhlIGV4Y2VwdGlvbiB0byBiZSBlbmNhcHN1bGF0ZWQgaW4gYQotICAgICAqIFRyYW5zZm9ybWVyRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgVHJhbnNmb3JtZXJGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yKEV4Y2VwdGlvbiBlKSB7Ci0KLSAgICAgICAgc3VwZXIoZS50b1N0cmluZygpKTsKLQotICAgICAgICB0aGlzLmV4Y2VwdGlvbiA9IGU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlIGEgbmV3IDxjb2RlPlRyYW5zZm9ybWVyRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvcjwvY29kZT4gd2l0aCB0aGUKLSAgICAgKiBnaXZlbiA8Y29kZT5FeGNlcHRpb248L2NvZGU+IGJhc2UgY2F1c2UgYW5kIGRldGFpbCBtZXNzYWdlLgotICAgICAqCi0gICAgICogQHBhcmFtIGUgVGhlIGV4Y2VwdGlvbiB0byBiZSBlbmNhcHN1bGF0ZWQgaW4gYQotICAgICAqIFRyYW5zZm9ybWVyRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvcgotICAgICAqIEBwYXJhbSBtc2cgVGhlIGRldGFpbCBtZXNzYWdlLgotICAgICAqLwotICAgIHB1YmxpYyBUcmFuc2Zvcm1lckZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IoRXhjZXB0aW9uIGUsIFN0cmluZyBtc2cpIHsKLQotICAgICAgICBzdXBlcihtc2cpOwotCi0gICAgICAgIHRoaXMuZXhjZXB0aW9uID0gZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIG1lc3NhZ2UgKGlmIGFueSkgZm9yIHRoaXMgZXJyb3IgLiBJZiB0aGVyZSBpcyBubwotICAgICAqIG1lc3NhZ2UgZm9yIHRoZSBleGNlcHRpb24gYW5kIHRoZXJlIGlzIGFuIGVuY2Fwc3VsYXRlZAotICAgICAqIGV4Y2VwdGlvbiB0aGVuIHRoZSBtZXNzYWdlIG9mIHRoYXQgZXhjZXB0aW9uIHdpbGwgYmUgcmV0dXJuZWQuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBlcnJvciBtZXNzYWdlLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TWVzc2FnZSgpIHsKLQotICAgICAgICBTdHJpbmcgbWVzc2FnZSA9IHN1cGVyLmdldE1lc3NhZ2UoKTsKLQotICAgICAgICBpZiAoKG1lc3NhZ2UgPT0gbnVsbCkgJiYgKGV4Y2VwdGlvbiAhPSBudWxsKSkgewotICAgICAgICAgICAgcmV0dXJuIGV4Y2VwdGlvbi5nZXRNZXNzYWdlKCk7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gbWVzc2FnZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIGFjdHVhbCBleGNlcHRpb24gKGlmIGFueSkgdGhhdCBjYXVzZWQgdGhpcyBleGNlcHRpb24gdG8KLSAgICAgKiBiZSByYWlzZWQuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBlbmNhcHN1bGF0ZWQgZXhjZXB0aW9uLCBvciBudWxsIGlmIHRoZXJlIGlzIG5vbmUuCi0gICAgICovCi0gICAgcHVibGljIEV4Y2VwdGlvbiBnZXRFeGNlcHRpb24oKSB7Ci0gICAgICAgIHJldHVybiBleGNlcHRpb247Ci0gICAgfQotICAgIC8qKgotICAgICAqIHVzZSB0aGUgZXhjZXB0aW9uIGNoYWluaW5nIG1lY2hhbmlzbSBvZiBKREsxLjQKLSAgICAqLwotICAgIEBPdmVycmlkZQotICAgIHB1YmxpYyBUaHJvd2FibGUgZ2V0Q2F1c2UoKSB7Ci0gICAgICAgIHJldHVybiBleGNlcHRpb247Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmF4L3htbC90cmFuc2Zvcm0vVVJJUmVzb2x2ZXIuamF2YSBiL3NyYy9qYXZheC94bWwvdHJhbnNmb3JtL1VSSVJlc29sdmVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGE0ZWE0YzAuLjAwMDAwMDAKLS0tIGEvc3JjL2phdmF4L3htbC90cmFuc2Zvcm0vVVJJUmVzb2x2ZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDUwICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDAsIDIwMDUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLXBhY2thZ2UgamF2YXgueG1sLnRyYW5zZm9ybTsKLQotLyoqCi0gKiA8cD5BbiBvYmplY3QgdGhhdCBpbXBsZW1lbnRzIHRoaXMgaW50ZXJmYWNlIHRoYXQgY2FuIGJlIGNhbGxlZCBieSB0aGUgcHJvY2Vzc29yCi0gKiB0byB0dXJuIGEgVVJJIHVzZWQgaW4gZG9jdW1lbnQoKSwgeHNsOmltcG9ydCwgb3IgeHNsOmluY2x1ZGUgaW50byBhIFNvdXJjZSBvYmplY3QuCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgVVJJUmVzb2x2ZXIgewotCi0gICAgLyoqCi0gICAgICogQ2FsbGVkIGJ5IHRoZSBwcm9jZXNzb3Igd2hlbiBpdCBlbmNvdW50ZXJzCi0gICAgICogYW4geHNsOmluY2x1ZGUsIHhzbDppbXBvcnQsIG9yIGRvY3VtZW50KCkgZnVuY3Rpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaHJlZiBBbiBocmVmIGF0dHJpYnV0ZSwgd2hpY2ggbWF5IGJlIHJlbGF0aXZlIG9yIGFic29sdXRlLgotICAgICAqIEBwYXJhbSBiYXNlIFRoZSBiYXNlIFVSSSBhZ2FpbnN0IHdoaWNoIHRoZSBmaXJzdCBhcmd1bWVudCB3aWxsIGJlIG1hZGUKLSAgICAgKiBhYnNvbHV0ZSBpZiB0aGUgYWJzb2x1dGUgVVJJIGlzIHJlcXVpcmVkLgotICAgICAqCi0gICAgICogQHJldHVybiBBIFNvdXJjZSBvYmplY3QsIG9yIG51bGwgaWYgdGhlIGhyZWYgY2Fubm90IGJlIHJlc29sdmVkLAotICAgICAqIGFuZCB0aGUgcHJvY2Vzc29yIHNob3VsZCB0cnkgdG8gcmVzb2x2ZSB0aGUgVVJJIGl0c2VsZi4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24gaWYgYW4gZXJyb3Igb2NjdXJzIHdoZW4gdHJ5aW5nIHRvCi0gICAgICogcmVzb2x2ZSB0aGUgVVJJLgotICAgICAqLwotICAgIHB1YmxpYyBTb3VyY2UgcmVzb2x2ZShTdHJpbmcgaHJlZiwgU3RyaW5nIGJhc2UpCi0gICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLX0KZGlmZiAtLWdpdCBhL3NyYy9qYXZheC94bWwvdHJhbnNmb3JtL2RvbS9ET01Mb2NhdG9yLmphdmEgYi9zcmMvamF2YXgveG1sL3RyYW5zZm9ybS9kb20vRE9NTG9jYXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxM2E3NDQ2Li4wMDAwMDAwCi0tLSBhL3NyYy9qYXZheC94bWwvdHJhbnNmb3JtL2RvbS9ET01Mb2NhdG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0OSArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDAwLCAyMDA1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi1wYWNrYWdlIGphdmF4LnhtbC50cmFuc2Zvcm0uZG9tOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2VMb2NhdG9yOwotCi1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLQotCi0vKioKLSAqIEluZGljYXRlcyB0aGUgcG9zaXRpb24gb2YgYSBub2RlIGluIGEgc291cmNlIERPTSwgaW50ZW5kZWQKLSAqIHByaW1hcmlseSBmb3IgZXJyb3IgcmVwb3J0aW5nLiAgVG8gdXNlIGEgRE9NTG9jYXRvciwgdGhlIHJlY2VpdmVyIG9mIGFuCi0gKiBlcnJvciBtdXN0IGRvd25jYXN0IHRoZSB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2VMb2NhdG9yfQotICogb2JqZWN0IHJldHVybmVkIGJ5IGFuIGV4Y2VwdGlvbi4gQSB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lcn0KLSAqIG1heSB1c2UgdGhpcyBvYmplY3QgZm9yIHB1cnBvc2VzIG90aGVyIHRoYW4gZXJyb3IgcmVwb3J0aW5nLCBmb3IgaW5zdGFuY2UsCi0gKiB0byBpbmRpY2F0ZSB0aGUgc291cmNlIG5vZGUgdGhhdCBvcmlnaW5hdGVkIGEgcmVzdWx0IG5vZGUuCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgRE9NTG9jYXRvciBleHRlbmRzIFNvdXJjZUxvY2F0b3IgewotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSBub2RlIHdoZXJlIHRoZSBldmVudCBvY2N1cnJlZC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIG5vZGUgdGhhdCBpcyB0aGUgbG9jYXRpb24gZm9yIHRoZSBldmVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgTm9kZSBnZXRPcmlnaW5hdGluZ05vZGUoKTsKLX0KZGlmZiAtLWdpdCBhL3NyYy9qYXZheC94bWwvdHJhbnNmb3JtL2RvbS9ET01SZXN1bHQuamF2YSBiL3NyYy9qYXZheC94bWwvdHJhbnNmb3JtL2RvbS9ET01SZXN1bHQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYzdhZGZjNC4uMDAwMDAwMAotLS0gYS9zcmMvamF2YXgveG1sL3RyYW5zZm9ybS9kb20vRE9NUmVzdWx0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzNjIgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwMCwgMjAwNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotcGFja2FnZSBqYXZheC54bWwudHJhbnNmb3JtLmRvbTsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uUmVzdWx0OwotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci0KLS8qKgotICogPHA+QWN0cyBhcyBhIGhvbGRlciBmb3IgYSB0cmFuc2Zvcm1hdGlvbiByZXN1bHQgdHJlZSBpbiB0aGUgZm9ybSBvZiBhIERvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSB0cmVlLjwvcD4KLSAqCi0gKiA8cD5JZiBubyBvdXRwdXQgRE9NIHNvdXJjZSBpcyBzZXQsIHRoZSB0cmFuc2Zvcm1hdGlvbiB3aWxsIGNyZWF0ZSBhIERvY3VtZW50IG5vZGUgYXMgdGhlIGhvbGRlciBmb3IgdGhlIHJlc3VsdCBvZiB0aGUgdHJhbnNmb3JtYXRpb24sCi0gKiB3aGljaCBtYXkgYmUgcmV0cmlldmVkIHdpdGgge0BsaW5rICNnZXROb2RlKCl9LjwvcD4KLSAqCi0gKiBAYXV0aG9yIDxhIGhyZWY9IkplZmYuU3V0dG9yQFN1bi5jb20iPkplZmYgU3V0dG9yPC9hPgotICovCi1wdWJsaWMgY2xhc3MgRE9NUmVzdWx0IGltcGxlbWVudHMgUmVzdWx0IHsKLQotICAgIC8qKiA8cD5JZiB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckZhY3RvcnkjZ2V0RmVhdHVyZX0KLSAgICAgKiByZXR1cm5zIDxjb2RlPnRydWU8L2NvZGU+IHdoZW4gcGFzc2VkIHRoaXMgdmFsdWUgYXMgYW4gYXJndW1lbnQsCi0gICAgICogdGhlIDxjb2RlPlRyYW5zZm9ybWVyPC9jb2RlPiBzdXBwb3J0cyA8Y29kZT5SZXN1bHQ8L2NvZGU+IG91dHB1dCBvZiB0aGlzIHR5cGUuPC9wPgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEZFQVRVUkUgPSAiaHR0cDovL2phdmF4LnhtbC50cmFuc2Zvcm0uZG9tLkRPTVJlc3VsdC9mZWF0dXJlIjsKLQotICAgIC8qKgotICAgICAqIDxwPlplcm8tYXJndW1lbnQgZGVmYXVsdCBjb25zdHJ1Y3Rvci48L3A+Ci0gICAgICoKLSAgICAgKiA8cD48Y29kZT5ub2RlPC9jb2RlPiwKLSAgICAgKiA8Y29kZT5zaWJsaW5nTm9kZTwvY29kZT4gYW5kCi0gICAgICogPGNvZGU+c3lzdGVtSWQ8L2NvZGU+Ci0gICAgICogd2lsbCBiZSBzZXQgdG8gPGNvZGU+bnVsbDwvY29kZT4uPC9wPgotICAgICAqLwotICAgIHB1YmxpYyBET01SZXN1bHQoKSB7Ci0gICAgICAgIHNldE5vZGUobnVsbCk7Ci0gICAgICAgIHNldE5leHRTaWJsaW5nKG51bGwpOwotICAgICAgICBzZXRTeXN0ZW1JZChudWxsKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5Vc2UgYSBET00gbm9kZSB0byBjcmVhdGUgYSBuZXcgb3V0cHV0IHRhcmdldC48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5JbiBwcmFjdGljZSwgdGhlIG5vZGUgc2hvdWxkIGJlCi0gICAgICogYSB7QGxpbmsgb3JnLnczYy5kb20uRG9jdW1lbnR9IG5vZGUsCi0gICAgICogYSB7QGxpbmsgb3JnLnczYy5kb20uRG9jdW1lbnRGcmFnbWVudH0gbm9kZSwgb3IKLSAgICAgKiBhIHtAbGluayBvcmcudzNjLmRvbS5FbGVtZW50fSBub2RlLgotICAgICAqIEluIG90aGVyIHdvcmRzLCBhIG5vZGUgdGhhdCBhY2NlcHRzIGNoaWxkcmVuLjwvcD4KLSAgICAgKgotICAgICAqIDxwPjxjb2RlPnNpYmxpbmdOb2RlPC9jb2RlPiBhbmQKLSAgICAgKiA8Y29kZT5zeXN0ZW1JZDwvY29kZT4KLSAgICAgKiB3aWxsIGJlIHNldCB0byA8Y29kZT5udWxsPC9jb2RlPi48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gbm9kZSBUaGUgRE9NIG5vZGUgdGhhdCB3aWxsIGNvbnRhaW4gdGhlIHJlc3VsdCB0cmVlLgotICAgICAqLwotICAgIHB1YmxpYyBET01SZXN1bHQoTm9kZSBub2RlKSB7Ci0gICAgICAgIHNldE5vZGUobm9kZSk7Ci0gICAgICAgIHNldE5leHRTaWJsaW5nKG51bGwpOwotICAgICAgICBzZXRTeXN0ZW1JZChudWxsKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5Vc2UgYSBET00gbm9kZSB0byBjcmVhdGUgYSBuZXcgb3V0cHV0IHRhcmdldCB3aXRoIHRoZSBzcGVjaWZpZWQgU3lzdGVtIElELjxwPgotICAgICAqCi0gICAgICogPHA+SW4gcHJhY3RpY2UsIHRoZSBub2RlIHNob3VsZCBiZQotICAgICAqIGEge0BsaW5rIG9yZy53M2MuZG9tLkRvY3VtZW50fSBub2RlLAotICAgICAqIGEge0BsaW5rIG9yZy53M2MuZG9tLkRvY3VtZW50RnJhZ21lbnR9IG5vZGUsIG9yCi0gICAgICogYSB7QGxpbmsgb3JnLnczYy5kb20uRWxlbWVudH0gbm9kZS4KLSAgICAgKiBJbiBvdGhlciB3b3JkcywgYSBub2RlIHRoYXQgYWNjZXB0cyBjaGlsZHJlbi48L3A+Ci0gICAgICoKLSAgICAgKiA8cD48Y29kZT5zaWJsaW5nTm9kZTwvY29kZT4gd2lsbCBiZSBzZXQgdG8gPGNvZGU+bnVsbDwvY29kZT4uPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIG5vZGUgVGhlIERPTSBub2RlIHRoYXQgd2lsbCBjb250YWluIHRoZSByZXN1bHQgdHJlZS4KLSAgICAgKiBAcGFyYW0gc3lzdGVtSWQgVGhlIHN5c3RlbSBpZGVudGlmaWVyIHdoaWNoIG1heSBiZSB1c2VkIGluIGFzc29jaWF0aW9uIHdpdGggdGhpcyBub2RlLgotICAgICAqLwotICAgIHB1YmxpYyBET01SZXN1bHQoTm9kZSBub2RlLCBTdHJpbmcgc3lzdGVtSWQpIHsKLSAgICAgICAgc2V0Tm9kZShub2RlKTsKLSAgICAgICAgc2V0TmV4dFNpYmxpbmcobnVsbCk7Ci0gICAgICAgIHNldFN5c3RlbUlkKHN5c3RlbUlkKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5Vc2UgYSBET00gbm9kZSB0byBjcmVhdGUgYSBuZXcgb3V0cHV0IHRhcmdldCBzcGVjaWZ5aW5nIHRoZSBjaGlsZCBub2RlIHdoZXJlIHRoZSByZXN1bHQgbm9kZXMgc2hvdWxkIGJlIGluc2VydGVkIGJlZm9yZS48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5JbiBwcmFjdGljZSwgPGNvZGU+bm9kZTwvY29kZT4gYW5kIDxjb2RlPm5leHRTaWJsaW5nPC9jb2RlPiBzaG91bGQgYmUKLSAgICAgKiBhIHtAbGluayBvcmcudzNjLmRvbS5Eb2N1bWVudH0gbm9kZSwKLSAgICAgKiBhIHtAbGluayBvcmcudzNjLmRvbS5Eb2N1bWVudEZyYWdtZW50fSBub2RlLCBvcgotICAgICAqIGEge0BsaW5rIG9yZy53M2MuZG9tLkVsZW1lbnR9IG5vZGUuCi0gICAgICogSW4gb3RoZXIgd29yZHMsIGEgbm9kZSB0aGF0IGFjY2VwdHMgY2hpbGRyZW4uPC9wPgotICAgICAqCi0gICAgICogPHA+VXNlIDxjb2RlPm5leHRTaWJsaW5nPC9jb2RlPiB0byBzcGVjaWZ5IHRoZSBjaGlsZCBub2RlCi0gICAgICogd2hlcmUgdGhlIHJlc3VsdCBub2RlcyBzaG91bGQgYmUgaW5zZXJ0ZWQgYmVmb3JlLgotICAgICAqIElmIDxjb2RlPm5leHRTaWJsaW5nPC9jb2RlPiBpcyBub3QgYSBzaWJsaW5nIG9mIDxjb2RlPm5vZGU8L2NvZGU+LAotICAgICAqIHRoZW4gYW4gPGNvZGU+SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uPC9jb2RlPiBpcyB0aHJvd24uCi0gICAgICogSWYgPGNvZGU+bm9kZTwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4gYW5kIDxjb2RlPm5leHRTaWJsaW5nPC9jb2RlPiBpcyBub3QgPGNvZGU+bnVsbDwvY29kZT4sCi0gICAgICogdGhlbiBhbiA8Y29kZT5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb248L2NvZGU+IGlzIHRocm93bi4KLSAgICAgKiBJZiA8Y29kZT5uZXh0U2libGluZzwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4sCi0gICAgICogdGhlbiB0aGUgYmVoYXZpb3IgaXMgdGhlIHNhbWUgYXMgY2FsbGluZyB7QGxpbmsgI0RPTVJlc3VsdChOb2RlIG5vZGUpfSwKLSAgICAgKiBpLmUuIGFwcGVuZCB0aGUgcmVzdWx0IG5vZGVzIGFzIHRoZSBsYXN0IGNoaWxkIG9mIHRoZSBzcGVjaWZpZWQgPGNvZGU+bm9kZTwvY29kZT4uPC9wPgotICAgICAqCi0gICAgICogPHA+PGNvZGU+c3lzdGVtSWQ8L2NvZGU+IHdpbGwgYmUgc2V0IHRvIDxjb2RlPm51bGw8L2NvZGU+LjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBub2RlIFRoZSBET00gbm9kZSB0aGF0IHdpbGwgY29udGFpbiB0aGUgcmVzdWx0IHRyZWUuCi0gICAgICogQHBhcmFtIG5leHRTaWJsaW5nIFRoZSBjaGlsZCBub2RlIHdoZXJlIHRoZSByZXN1bHQgbm9kZXMgc2hvdWxkIGJlIGluc2VydGVkIGJlZm9yZS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIElmIDxjb2RlPm5leHRTaWJsaW5nPC9jb2RlPiBpcyBub3QgYSBzaWJsaW5nIG9mIDxjb2RlPm5vZGU8L2NvZGU+IG9yCi0gICAgICogICA8Y29kZT5ub2RlPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPiBhbmQgPGNvZGU+bmV4dFNpYmxpbmc8L2NvZGU+Ci0gICAgICogICBpcyBub3QgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICoKLSAgICAgKiBAc2luY2UgMS41Ci0gICAgICovCi0gICAgcHVibGljIERPTVJlc3VsdChOb2RlIG5vZGUsIE5vZGUgbmV4dFNpYmxpbmcpIHsKLQotICAgICAgICAvLyBkb2VzIHRoZSBjb3JyZW50IHBhcmVudC9jaGlsZCByZWxhdGlvbnNoaXAgZXhpc3Q/Ci0gICAgICAgIGlmIChuZXh0U2libGluZyAhPSBudWxsKSB7Ci0gICAgICAgICAgICAvLyBjYW5ub3QgYmUgYSBzaWJsaW5nIG9mIGEgbnVsbCBub2RlCi0gICAgICAgICAgICBpZiAobm9kZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiQ2Fubm90IGNyZWF0ZSBhIERPTVJlc3VsdCB3aGVuIHRoZSBuZXh0U2libGluZyBpcyBjb250YWluZWQgYnkgdGhlIFwibnVsbFwiIG5vZGUuIik7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIG5leHRTaWJsaW5nIGNvbnRhaW5lZCBieSBub2RlPwotICAgICAgICAgICAgaWYgKChub2RlLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKG5leHRTaWJsaW5nKSZOb2RlLkRPQ1VNRU5UX1BPU0lUSU9OX0NPTlRBSU5FRF9CWSk9PTApIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJDYW5ub3QgY3JlYXRlIGEgRE9NUmVzdWx0IHdoZW4gdGhlIG5leHRTaWJsaW5nIGlzIG5vdCBjb250YWluZWQgYnkgdGhlIG5vZGUuIik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBzZXROb2RlKG5vZGUpOwotICAgICAgICBzZXROZXh0U2libGluZyhuZXh0U2libGluZyk7Ci0gICAgICAgIHNldFN5c3RlbUlkKG51bGwpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPlVzZSBhIERPTSBub2RlIHRvIGNyZWF0ZSBhIG5ldyBvdXRwdXQgdGFyZ2V0IHNwZWNpZnlpbmcgdGhlIGNoaWxkIG5vZGUgd2hlcmUgdGhlIHJlc3VsdCBub2RlcyBzaG91bGQgYmUgaW5zZXJ0ZWQgYmVmb3JlIGFuZAotICAgICAqIHRoZSBzcGVjaWZpZWQgU3lzdGVtIElELjwvcD4KLSAgICAgKgotICAgICAqIDxwPkluIHByYWN0aWNlLCA8Y29kZT5ub2RlPC9jb2RlPiBhbmQgPGNvZGU+bmV4dFNpYmxpbmc8L2NvZGU+IHNob3VsZCBiZQotICAgICAqIGEge0BsaW5rIG9yZy53M2MuZG9tLkRvY3VtZW50fSBub2RlLAotICAgICAqIGEge0BsaW5rIG9yZy53M2MuZG9tLkRvY3VtZW50RnJhZ21lbnR9IG5vZGUsIG9yIGEKLSAgICAgKiB7QGxpbmsgb3JnLnczYy5kb20uRWxlbWVudH0gbm9kZS4KLSAgICAgKiBJbiBvdGhlciB3b3JkcywgYSBub2RlIHRoYXQgYWNjZXB0cyBjaGlsZHJlbi48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5Vc2UgPGNvZGU+bmV4dFNpYmxpbmc8L2NvZGU+IHRvIHNwZWNpZnkgdGhlIGNoaWxkIG5vZGUKLSAgICAgKiB3aGVyZSB0aGUgcmVzdWx0IG5vZGVzIHNob3VsZCBiZSBpbnNlcnRlZCBiZWZvcmUuCi0gICAgICogSWYgPGNvZGU+bmV4dFNpYmxpbmc8L2NvZGU+IGlzIG5vdCBhIHNpYmxpbmcgb2YgPGNvZGU+bm9kZTwvY29kZT4sCi0gICAgICogdGhlbiBhbiA8Y29kZT5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb248L2NvZGU+IGlzIHRocm93bi4KLSAgICAgKiBJZiA8Y29kZT5ub2RlPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPiBhbmQgPGNvZGU+bmV4dFNpYmxpbmc8L2NvZGU+IGlzIG5vdCA8Y29kZT5udWxsPC9jb2RlPiwKLSAgICAgKiB0aGVuIGFuIDxjb2RlPklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbjwvY29kZT4gaXMgdGhyb3duLgotICAgICAqIElmIDxjb2RlPm5leHRTaWJsaW5nPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPiwKLSAgICAgKiB0aGVuIHRoZSBiZWhhdmlvciBpcyB0aGUgc2FtZSBhcyBjYWxsaW5nIHtAbGluayAjRE9NUmVzdWx0KE5vZGUgbm9kZSwgU3RyaW5nIHN5c3RlbUlkKX0sCi0gICAgICogaS5lLiBhcHBlbmQgdGhlIHJlc3VsdCBub2RlcyBhcyB0aGUgbGFzdCBjaGlsZCBvZiB0aGUgc3BlY2lmaWVkIG5vZGUgYW5kIHVzZSB0aGUgc3BlY2lmaWVkIFN5c3RlbSBJRC48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gbm9kZSBUaGUgRE9NIG5vZGUgdGhhdCB3aWxsIGNvbnRhaW4gdGhlIHJlc3VsdCB0cmVlLgotICAgICAqIEBwYXJhbSBuZXh0U2libGluZyBUaGUgY2hpbGQgbm9kZSB3aGVyZSB0aGUgcmVzdWx0IG5vZGVzIHNob3VsZCBiZSBpbnNlcnRlZCBiZWZvcmUuCi0gICAgICogQHBhcmFtIHN5c3RlbUlkIFRoZSBzeXN0ZW0gaWRlbnRpZmllciB3aGljaCBtYXkgYmUgdXNlZCBpbiBhc3NvY2lhdGlvbiB3aXRoIHRoaXMgbm9kZS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIElmIDxjb2RlPm5leHRTaWJsaW5nPC9jb2RlPiBpcyBub3QgYQotICAgICAqICAgc2libGluZyBvZiA8Y29kZT5ub2RlPC9jb2RlPiBvcgotICAgICAqICAgPGNvZGU+bm9kZTwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4gYW5kIDxjb2RlPm5leHRTaWJsaW5nPC9jb2RlPgotICAgICAqICAgaXMgbm90IDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAqCi0gICAgICogQHNpbmNlIDEuNQotICAgICAqLwotICAgIHB1YmxpYyBET01SZXN1bHQoTm9kZSBub2RlLCBOb2RlIG5leHRTaWJsaW5nLCBTdHJpbmcgc3lzdGVtSWQpIHsKLQotICAgICAgICAvLyBkb2VzIHRoZSBjb3JyZW50IHBhcmVudC9jaGlsZCByZWxhdGlvbnNoaXAgZXhpc3Q/Ci0gICAgICAgIGlmIChuZXh0U2libGluZyAhPSBudWxsKSB7Ci0gICAgICAgICAgICAvLyBjYW5ub3QgYmUgYSBzaWJsaW5nIG9mIGEgbnVsbCBub2RlCi0gICAgICAgICAgICBpZiAobm9kZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiQ2Fubm90IGNyZWF0ZSBhIERPTVJlc3VsdCB3aGVuIHRoZSBuZXh0U2libGluZyBpcyBjb250YWluZWQgYnkgdGhlIFwibnVsbFwiIG5vZGUuIik7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vIG5leHRTaWJsaW5nIGNvbnRhaW5lZCBieSBub2RlPwotICAgICAgICAgICAgaWYgKChub2RlLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKG5leHRTaWJsaW5nKSZOb2RlLkRPQ1VNRU5UX1BPU0lUSU9OX0NPTlRBSU5FRF9CWSk9PTApIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJDYW5ub3QgY3JlYXRlIGEgRE9NUmVzdWx0IHdoZW4gdGhlIG5leHRTaWJsaW5nIGlzIG5vdCBjb250YWluZWQgYnkgdGhlIG5vZGUuIik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBzZXROb2RlKG5vZGUpOwotICAgICAgICBzZXROZXh0U2libGluZyhuZXh0U2libGluZyk7Ci0gICAgICAgIHNldFN5c3RlbUlkKHN5c3RlbUlkKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5TZXQgdGhlIG5vZGUgdGhhdCB3aWxsIGNvbnRhaW4gdGhlIHJlc3VsdCBET00gdHJlZS48cD4KLSAgICAgKgotICAgICAqIDxwPkluIHByYWN0aWNlLCB0aGUgbm9kZSBzaG91bGQgYmUKLSAgICAgKiBhIHtAbGluayBvcmcudzNjLmRvbS5Eb2N1bWVudH0gbm9kZSwKLSAgICAgKiBhIHtAbGluayBvcmcudzNjLmRvbS5Eb2N1bWVudEZyYWdtZW50fSBub2RlLCBvcgotICAgICAqIGEge0BsaW5rIG9yZy53M2MuZG9tLkVsZW1lbnR9IG5vZGUuCi0gICAgICogSW4gb3RoZXIgd29yZHMsIGEgbm9kZSB0aGF0IGFjY2VwdHMgY2hpbGRyZW4uPC9wPgotICAgICAqCi0gICAgICogPHA+QW4gPGNvZGU+SWxsZWdhbFN0YXRlRXhjZXB0aW9uPC9jb2RlPiBpcyB0aHJvd24gaWYKLSAgICAgKiA8Y29kZT5uZXh0U2libGluZzwvY29kZT4gaXMgbm90IDxjb2RlPm51bGw8L2NvZGU+IGFuZAotICAgICAqIDxjb2RlPm5vZGU8L2NvZGU+IGlzIG5vdCBhIHBhcmVudCBvZiA8Y29kZT5uZXh0U2libGluZzwvY29kZT4uCi0gICAgICogQW4gPGNvZGU+SWxsZWdhbFN0YXRlRXhjZXB0aW9uPC9jb2RlPiBpcyB0aHJvd24gaWYgPGNvZGU+bm9kZTwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4gYW5kCi0gICAgICogPGNvZGU+bmV4dFNpYmxpbmc8L2NvZGU+IGlzIG5vdCA8Y29kZT5udWxsPC9jb2RlPi48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gbm9kZSBUaGUgbm9kZSB0byB3aGljaCB0aGUgdHJhbnNmb3JtYXRpb24gd2lsbCBiZSBhcHBlbmRlZC4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIElmIDxjb2RlPm5leHRTaWJsaW5nPC9jb2RlPiBpcyBub3QKLSAgICAgKiAgIDxjb2RlPm51bGw8L2NvZGU+IGFuZAotICAgICAqICAgPGNvZGU+bmV4dFNpYmxpbmc8L2NvZGU+IGlzIG5vdCBhIGNoaWxkIG9mIDxjb2RlPm5vZGU8L2NvZGU+IG9yCi0gICAgICogICA8Y29kZT5ub2RlPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPiBhbmQKLSAgICAgKiAgIDxjb2RlPm5leHRTaWJsaW5nPC9jb2RlPiBpcyBub3QgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0Tm9kZShOb2RlIG5vZGUpIHsKLSAgICAgICAgLy8gZG9lcyB0aGUgY29ycmVudCBwYXJlbnQvY2hpbGQgcmVsYXRpb25zaGlwIGV4aXN0PwotICAgICAgICBpZiAobmV4dFNpYmxpbmcgIT0gbnVsbCkgewotICAgICAgICAgICAgLy8gY2Fubm90IGJlIGEgc2libGluZyBvZiBhIG51bGwgbm9kZQotICAgICAgICAgICAgaWYgKG5vZGUgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oIkNhbm5vdCBjcmVhdGUgYSBET01SZXN1bHQgd2hlbiB0aGUgbmV4dFNpYmxpbmcgaXMgY29udGFpbmVkIGJ5IHRoZSBcIm51bGxcIiBub2RlLiIpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBuZXh0U2libGluZyBjb250YWluZWQgYnkgbm9kZT8KLSAgICAgICAgICAgIGlmICgobm9kZS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbihuZXh0U2libGluZykmTm9kZS5ET0NVTUVOVF9QT1NJVElPTl9DT05UQUlORURfQlkpPT0wKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiQ2Fubm90IGNyZWF0ZSBhIERPTVJlc3VsdCB3aGVuIHRoZSBuZXh0U2libGluZyBpcyBub3QgY29udGFpbmVkIGJ5IHRoZSBub2RlLiIpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgdGhpcy5ub2RlID0gbm9kZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5HZXQgdGhlIG5vZGUgdGhhdCB3aWxsIGNvbnRhaW4gdGhlIHJlc3VsdCBET00gdHJlZS48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5JZiBubyBub2RlIHdhcyBzZXQgdmlhCi0gICAgICoge0BsaW5rICNET01SZXN1bHQoTm9kZSBub2RlKX0sCi0gICAgICoge0BsaW5rICNET01SZXN1bHQoTm9kZSBub2RlLCBTdHJpbmcgc3lzdGVJZCl9LAotICAgICAqIHtAbGluayAjRE9NUmVzdWx0KE5vZGUgbm9kZSwgTm9kZSBuZXh0U2libGluZyl9LAotICAgICAqIHtAbGluayAjRE9NUmVzdWx0KE5vZGUgbm9kZSwgTm9kZSBuZXh0U2libGluZywgU3RyaW5nIHN5c3RlbUlkKX0gb3IKLSAgICAgKiB7QGxpbmsgI3NldE5vZGUoTm9kZSBub2RlKX0sCi0gICAgICogdGhlbiB0aGUgbm9kZSB3aWxsIGJlIHNldCBieSB0aGUgdHJhbnNmb3JtYXRpb24sIGFuZCBtYXkgYmUgb2J0YWluZWQgZnJvbSB0aGlzIG1ldGhvZCBvbmNlIHRoZSB0cmFuc2Zvcm1hdGlvbiBpcyBjb21wbGV0ZS4KLSAgICAgKiBDYWxsaW5nIHRoaXMgbWV0aG9kIGJlZm9yZSB0aGUgdHJhbnNmb3JtYXRpb24gd2lsbCByZXR1cm4gPGNvZGU+bnVsbDwvY29kZT4uPC9wPgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgbm9kZSB0byB3aGljaCB0aGUgdHJhbnNmb3JtYXRpb24gd2lsbCBiZSBhcHBlbmRlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgTm9kZSBnZXROb2RlKCkgewotICAgICAgICByZXR1cm4gbm9kZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5TZXQgdGhlIGNoaWxkIG5vZGUgYmVmb3JlIHdoaWNoIHRoZSByZXN1bHQgbm9kZXMgd2lsbCBiZSBpbnNlcnRlZC48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5Vc2UgPGNvZGU+bmV4dFNpYmxpbmc8L2NvZGU+IHRvIHNwZWNpZnkgdGhlIGNoaWxkIG5vZGUKLSAgICAgKiBiZWZvcmUgd2hpY2ggdGhlIHJlc3VsdCBub2RlcyBzaG91bGQgYmUgaW5zZXJ0ZWQuCi0gICAgICogSWYgPGNvZGU+bmV4dFNpYmxpbmc8L2NvZGU+IGlzIG5vdCBhIGRlc2NlbmRhbnQgb2YgPGNvZGU+bm9kZTwvY29kZT4sCi0gICAgICogdGhlbiBhbiA8Y29kZT5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb248L2NvZGU+IGlzIHRocm93bi4KLSAgICAgKiBJZiA8Y29kZT5ub2RlPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPiBhbmQgPGNvZGU+bmV4dFNpYmxpbmc8L2NvZGU+IGlzIG5vdCA8Y29kZT5udWxsPC9jb2RlPiwKLSAgICAgKiB0aGVuIGFuIDxjb2RlPklsbGVnYWxTdGF0ZUV4Y2VwdGlvbjwvY29kZT4gaXMgdGhyb3duLgotICAgICAqIElmIDxjb2RlPm5leHRTaWJsaW5nPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPiwKLSAgICAgKiB0aGVuIHRoZSBiZWhhdmlvciBpcyB0aGUgc2FtZSBhcyBjYWxsaW5nIHtAbGluayAjRE9NUmVzdWx0KE5vZGUgbm9kZSl9LAotICAgICAqIGkuZS4gYXBwZW5kIHRoZSByZXN1bHQgbm9kZXMgYXMgdGhlIGxhc3QgY2hpbGQgb2YgdGhlIHNwZWNpZmllZCA8Y29kZT5ub2RlPC9jb2RlPi48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gbmV4dFNpYmxpbmcgVGhlIGNoaWxkIG5vZGUgYmVmb3JlIHdoaWNoIHRoZSByZXN1bHQgbm9kZXMgd2lsbCBiZSBpbnNlcnRlZC4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIElmIDxjb2RlPm5leHRTaWJsaW5nPC9jb2RlPiBpcyBub3QgYQotICAgICAqICAgZGVzY2VuZGFudCBvZiA8Y29kZT5ub2RlPC9jb2RlPi4KLSAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBJZiA8Y29kZT5ub2RlPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPgotICAgICAqICAgYW5kIDxjb2RlPm5leHRTaWJsaW5nPC9jb2RlPiBpcyBub3QgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICoKLSAgICAgKiBAc2luY2UgMS41Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0TmV4dFNpYmxpbmcoTm9kZSBuZXh0U2libGluZykgewotCi0gICAgICAgIC8vIGRvZXMgdGhlIGNvcnJlbnQgcGFyZW50L2NoaWxkIHJlbGF0aW9uc2hpcCBleGlzdD8KLSAgICAgICAgaWYgKG5leHRTaWJsaW5nICE9IG51bGwpIHsKLSAgICAgICAgICAgIC8vIGNhbm5vdCBiZSBhIHNpYmxpbmcgb2YgYSBudWxsIG5vZGUKLSAgICAgICAgICAgIGlmIChub2RlID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJDYW5ub3QgY3JlYXRlIGEgRE9NUmVzdWx0IHdoZW4gdGhlIG5leHRTaWJsaW5nIGlzIGNvbnRhaW5lZCBieSB0aGUgXCJudWxsXCIgbm9kZS4iKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gbmV4dFNpYmxpbmcgY29udGFpbmVkIGJ5IG5vZGU/Ci0gICAgICAgICAgICBpZiAoKG5vZGUuY29tcGFyZURvY3VtZW50UG9zaXRpb24obmV4dFNpYmxpbmcpJk5vZGUuRE9DVU1FTlRfUE9TSVRJT05fQ09OVEFJTkVEX0JZKT09MCkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkNhbm5vdCBjcmVhdGUgYSBET01SZXN1bHQgd2hlbiB0aGUgbmV4dFNpYmxpbmcgaXMgbm90IGNvbnRhaW5lZCBieSB0aGUgbm9kZS4iKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHRoaXMubmV4dFNpYmxpbmcgPSBuZXh0U2libGluZzsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5HZXQgdGhlIGNoaWxkIG5vZGUgYmVmb3JlIHdoaWNoIHRoZSByZXN1bHQgbm9kZXMgd2lsbCBiZSBpbnNlcnRlZC48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5JZiBubyBub2RlIHdhcyBzZXQgdmlhCi0gICAgICoge0BsaW5rICNET01SZXN1bHQoTm9kZSBub2RlLCBOb2RlIG5leHRTaWJsaW5nKX0sCi0gICAgICoge0BsaW5rICNET01SZXN1bHQoTm9kZSBub2RlLCBOb2RlIG5leHRTaWJsaW5nLCBTdHJpbmcgc3lzdGVtSWQpfSBvcgotICAgICAqIHtAbGluayAjc2V0TmV4dFNpYmxpbmcoTm9kZSBuZXh0U2libGluZyl9LAotICAgICAqIHRoZW4gPGNvZGU+bnVsbDwvY29kZT4gd2lsbCBiZSByZXR1cm5lZC48L3A+Ci0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBjaGlsZCBub2RlIGJlZm9yZSB3aGljaCB0aGUgcmVzdWx0IG5vZGVzIHdpbGwgYmUgaW5zZXJ0ZWQuCi0gICAgICoKLSAgICAgKiBAc2luY2UgMS41Ci0gICAgICovCi0gICAgcHVibGljIE5vZGUgZ2V0TmV4dFNpYmxpbmcoKSB7Ci0gICAgICAgIHJldHVybiBuZXh0U2libGluZzsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5TZXQgdGhlIHN5c3RlbUlkIHRoYXQgbWF5IGJlIHVzZWQgaW4gYXNzb2NpYXRpb24gd2l0aCB0aGUgbm9kZS48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gc3lzdGVtSWQgVGhlIHN5c3RlbSBpZGVudGlmaWVyIGFzIGEgVVJJIHN0cmluZy4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRTeXN0ZW1JZChTdHJpbmcgc3lzdGVtSWQpIHsKLSAgICAgICAgdGhpcy5zeXN0ZW1JZCA9IHN5c3RlbUlkOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPkdldCB0aGUgU3lzdGVtIElkZW50aWZpZXIuPC9wPgotICAgICAqCi0gICAgICogPHA+SWYgbm8gU3lzdGVtIElEIHdhcyBzZXQgdmlhCi0gICAgICoge0BsaW5rICNET01SZXN1bHQoTm9kZSBub2RlLCBTdHJpbmcgc3lzdGVtSWQpfSwKLSAgICAgKiB7QGxpbmsgI0RPTVJlc3VsdChOb2RlIG5vZGUsIE5vZGUgbmV4dFNpYmxpbmcsIFN0cmluZyBzeXN0ZW1JZCl9IG9yCi0gICAgICoge0BsaW5rICNzZXRTeXN0ZW1JZChTdHJpbmcgc3lzdGVtSWQpfSwKLSAgICAgKiB0aGVuIDxjb2RlPm51bGw8L2NvZGU+IHdpbGwgYmUgcmV0dXJuZWQuPC9wPgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgc3lzdGVtIGlkZW50aWZpZXIuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRTeXN0ZW1JZCgpIHsKLSAgICAgICAgcmV0dXJuIHN5c3RlbUlkOwotICAgIH0KLQotICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLSAgICAvLyBJbnRlcm5hbCBzdGF0ZS4KLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0KLSAgICAvKioKLSAgICAgKiA8cD5UaGUgbm9kZSB0byB3aGljaCB0aGUgdHJhbnNmb3JtYXRpb24gd2lsbCBiZSBhcHBlbmRlZC48L3A+Ci0gICAgICovCi0gICAgcHJpdmF0ZSBOb2RlIG5vZGUgPSBudWxsOwotCi0gICAgLyoqCi0gICAgICogPHA+VGhlIGNoaWxkIG5vZGUgYmVmb3JlIHdoaWNoIHRoZSByZXN1bHQgbm9kZXMgd2lsbCBiZSBpbnNlcnRlZC48L3A+Ci0gICAgICoKLSAgICAgKiBAc2luY2UgMS41Ci0gICAgICovCi0gICAgcHJpdmF0ZSBOb2RlIG5leHRTaWJsaW5nID0gbnVsbDsKLQotICAgIC8qKgotICAgICAqIDxwPlRoZSBTeXN0ZW0gSUQgdGhhdCBtYXkgYmUgdXNlZCBpbiBhc3NvY2lhdGlvbiB3aXRoIHRoZSBub2RlLjwvcD4KLSAgICAgKi8KLSAgICBwcml2YXRlIFN0cmluZyBzeXN0ZW1JZCA9IG51bGw7Ci19CmRpZmYgLS1naXQgYS9zcmMvamF2YXgveG1sL3RyYW5zZm9ybS9kb20vRE9NU291cmNlLmphdmEgYi9zcmMvamF2YXgveG1sL3RyYW5zZm9ybS9kb20vRE9NU291cmNlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDgzZTY0ZmQuLjAwMDAwMDAKLS0tIGEvc3JjL2phdmF4L3htbC90cmFuc2Zvcm0vZG9tL0RPTVNvdXJjZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTM3ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDAsIDIwMDUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLXBhY2thZ2UgamF2YXgueG1sLnRyYW5zZm9ybS5kb207Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlNvdXJjZTsKLQotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci0KLS8qKgotICogPHA+QWN0cyBhcyBhIGhvbGRlciBmb3IgYSB0cmFuc2Zvcm1hdGlvbiBTb3VyY2UgdHJlZSBpbiB0aGUKLSAqIGZvcm0gb2YgYSBEb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgdHJlZS48L3A+Ci0gKgotICogPHA+Tm90ZSB0aGF0IFhTTFQgcmVxdWlyZXMgbmFtZXNwYWNlIHN1cHBvcnQuIEF0dGVtcHRpbmcgdG8gdHJhbnNmb3JtIGEgRE9NCi0gKiB0aGF0IHdhcyBub3QgY29udHJ1Y3RlZCB3aXRoIGEgbmFtZXNwYWNlLWF3YXJlIHBhcnNlciBtYXkgcmVzdWx0IGluIGVycm9ycy4KLSAqIFBhcnNlcnMgY2FuIGJlIG1hZGUgbmFtZXNwYWNlIGF3YXJlIGJ5IGNhbGxpbmcKLSAqIHtAbGluayBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5I3NldE5hbWVzcGFjZUF3YXJlKGJvb2xlYW4gYXdhcmVuZXNzKX0uPC9wPgotICoKLSAqIEBhdXRob3IgPGEgaHJlZj0iSmVmZi5TdXR0b3JAU3VuLmNvbSI+SmVmZiBTdXR0b3I8L2E+Ci0gKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yIj5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMiBTcGVjaWZpY2F0aW9uPC9hPgotICovCi1wdWJsaWMgY2xhc3MgRE9NU291cmNlIGltcGxlbWVudHMgU291cmNlIHsKLQotICAgIC8qKgotICAgICAqIDxwPjxjb2RlPk5vZGU8L2NvZGU+IHRvIHNlcnZlIGFzIERPTSBzb3VyY2UuPC9wPgotICAgICAqLwotICAgIHByaXZhdGUgTm9kZSBub2RlOwotCi0gICAgLyoqCi0gICAgICogPHA+VGhlIGJhc2UgSUQgKFVSTCBvciBzeXN0ZW0gSUQpIGZyb20gd2hlcmUgVVJMcwotICAgICAqIHdpbGwgYmUgcmVzb2x2ZWQuPC9wPgotICAgICAqLwotICAgIHByaXZhdGUgU3RyaW5nIHN5c3RlbUlEOwotCi0gICAgLyoqIElmIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRmFjdG9yeSNnZXRGZWF0dXJlfQotICAgICAqIHJldHVybnMgdHJ1ZSB3aGVuIHBhc3NlZCB0aGlzIHZhbHVlIGFzIGFuIGFyZ3VtZW50LAotICAgICAqIHRoZSBUcmFuc2Zvcm1lciBzdXBwb3J0cyBTb3VyY2UgaW5wdXQgb2YgdGhpcyB0eXBlLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEZFQVRVUkUgPQotICAgICAgICAiaHR0cDovL2phdmF4LnhtbC50cmFuc2Zvcm0uZG9tLkRPTVNvdXJjZS9mZWF0dXJlIjsKLQotICAgIC8qKgotICAgICAqIDxwPlplcm8tYXJndW1lbnQgZGVmYXVsdCBjb25zdHJ1Y3Rvci4gIElmIHRoaXMgY29uc3RydWN0b3IgaXMgdXNlZCwgYW5kCi0gICAgICogbm8gRE9NIHNvdXJjZSBpcyBzZXQgdXNpbmcge0BsaW5rICNzZXROb2RlKE5vZGUgbm9kZSl9ICwgdGhlbiB0aGUKLSAgICAgKiA8Y29kZT5UcmFuc2Zvcm1lcjwvY29kZT4gd2lsbAotICAgICAqIGNyZWF0ZSBhbiBlbXB0eSBzb3VyY2Uge0BsaW5rIG9yZy53M2MuZG9tLkRvY3VtZW50fSB1c2luZwotICAgICAqIHtAbGluayBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXIjbmV3RG9jdW1lbnQoKX0uPC9wPgotICAgICAqCi0gICAgICogQHNlZSBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyI3RyYW5zZm9ybShTb3VyY2UgeG1sU291cmNlLCBSZXN1bHQgb3V0cHV0VGFyZ2V0KQotICAgICAqLwotICAgIHB1YmxpYyBET01Tb3VyY2UoKSB7IH0KLQotICAgIC8qKgotICAgICAqIENyZWF0ZSBhIG5ldyBpbnB1dCBzb3VyY2Ugd2l0aCBhIERPTSBub2RlLiAgVGhlIG9wZXJhdGlvbgotICAgICAqIHdpbGwgYmUgYXBwbGllZCB0byB0aGUgc3VidHJlZSByb290ZWQgYXQgdGhpcyBub2RlLiAgSW4gWFNMVCwKLSAgICAgKiBhICIvIiBwYXR0ZXJuIHN0aWxsIG1lYW5zIHRoZSByb290IG9mIHRoZSB0cmVlIChub3QgdGhlIHN1YnRyZWUpLAotICAgICAqIGFuZCB0aGUgZXZhbHVhdGlvbiBvZiBnbG9iYWwgdmFyaWFibGVzIGFuZCBwYXJhbWV0ZXJzIGlzIGRvbmUKLSAgICAgKiBmcm9tIHRoZSByb290IG5vZGUgYWxzby4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuIFRoZSBET00gbm9kZSB0aGF0IHdpbGwgY29udGFpbiB0aGUgU291cmNlIHRyZWUuCi0gICAgICovCi0gICAgcHVibGljIERPTVNvdXJjZShOb2RlIG4pIHsKLSAgICAgICAgc2V0Tm9kZShuKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGUgYSBuZXcgaW5wdXQgc291cmNlIHdpdGggYSBET00gbm9kZSwgYW5kIHdpdGggdGhlCi0gICAgICogc3lzdGVtIElEIGFsc28gcGFzc2VkIGluIGFzIHRoZSBiYXNlIFVSSS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBub2RlIFRoZSBET00gbm9kZSB0aGF0IHdpbGwgY29udGFpbiB0aGUgU291cmNlIHRyZWUuCi0gICAgICogQHBhcmFtIHN5c3RlbUlEIFNwZWNpZmllcyB0aGUgYmFzZSBVUkkgYXNzb2NpYXRlZCB3aXRoIG5vZGUuCi0gICAgICovCi0gICAgcHVibGljIERPTVNvdXJjZShOb2RlIG5vZGUsIFN0cmluZyBzeXN0ZW1JRCkgewotICAgICAgICBzZXROb2RlKG5vZGUpOwotICAgICAgICBzZXRTeXN0ZW1JZChzeXN0ZW1JRCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSBub2RlIHRoYXQgd2lsbCByZXByZXNlbnRzIGEgU291cmNlIERPTSB0cmVlLgotICAgICAqCi0gICAgICogQHBhcmFtIG5vZGUgVGhlIG5vZGUgdGhhdCBpcyB0byBiZSB0cmFuc2Zvcm1lZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXROb2RlKE5vZGUgbm9kZSkgewotICAgICAgICB0aGlzLm5vZGUgPSBub2RlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgbm9kZSB0aGF0IHJlcHJlc2VudHMgYSBTb3VyY2UgRE9NIHRyZWUuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBub2RlIHRoYXQgaXMgdG8gYmUgdHJhbnNmb3JtZWQuCi0gICAgICovCi0gICAgcHVibGljIE5vZGUgZ2V0Tm9kZSgpIHsKLSAgICAgICAgcmV0dXJuIG5vZGU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSBiYXNlIElEIChVUkwgb3Igc3lzdGVtIElEKSBmcm9tIHdoZXJlIFVSTHMKLSAgICAgKiB3aWxsIGJlIHJlc29sdmVkLgotICAgICAqCi0gICAgICogQHBhcmFtIHN5c3RlbUlEIEJhc2UgVVJMIGZvciB0aGlzIERPTSB0cmVlLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFN5c3RlbUlkKFN0cmluZyBzeXN0ZW1JRCkgewotICAgICAgICB0aGlzLnN5c3RlbUlEID0gc3lzdGVtSUQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBiYXNlIElEIChVUkwgb3Igc3lzdGVtIElEKSBmcm9tIHdoZXJlIFVSTHMKLSAgICAgKiB3aWxsIGJlIHJlc29sdmVkLgotICAgICAqCi0gICAgICogQHJldHVybiBCYXNlIFVSTCBmb3IgdGhpcyBET00gdHJlZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFN5c3RlbUlkKCkgewotICAgICAgICByZXR1cm4gdGhpcy5zeXN0ZW1JRDsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvamF2YXgveG1sL3RyYW5zZm9ybS9kb20vcGFja2FnZS5odG1sIGIvc3JjL2phdmF4L3htbC90cmFuc2Zvcm0vZG9tL3BhY2thZ2UuaHRtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDljYjgxMi4uMDAwMDAwMAotLS0gYS9zcmMvamF2YXgveG1sL3RyYW5zZm9ybS9kb20vcGFja2FnZS5odG1sCisrKyAvZGV2L251bGwKQEAgLTEsNzAgKzAsMCBAQAotPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KLTwhLS0KLUNvcHlyaWdodCAoYykgMjAwMCwgMjAwNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLURPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLQotVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLXVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi1wdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLXBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLWJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotCi1UaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLUFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi12ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLQotWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotCi1QbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotcXVlc3Rpb25zLiAKLS0tPgotCi08IURPQ1RZUEUgaHRtbAotICAgICBQVUJMSUMgIi0vL1czQy8vRFREIFhIVE1MIDEuMCBTdHJpY3QvL0VOIgotICAgICAiaHR0cDovL3d3dy53My5vcmcvVFIveGh0bWwxL0RURC94aHRtbDEtc3RyaWN0LmR0ZCI+Ci0KLTxodG1sIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sIj4KLQotPGhlYWQ+Ci0gIDx0aXRsZT5qYXZheC54bWwudHJhbnNmb3JtLmRvbTwvdGl0bGU+Ci0KLSAgPG1ldGEgbmFtZT0iQ1ZTIgotICAgICAgICBjb250ZW50PSIkSWQ6IHBhY2thZ2UuaHRtbCx2IDEuMiAyMDA1LzA2LzEwIDAzOjUwOjQwIGplZmZzdXR0b3IgRXhwICQiIC8+Ci0gIDxtZXRhIG5hbWU9IkFVVEhPUiIKLSAgICAgICAgY29udGVudD0iSmVmZi5TdXR0b3JAU3VuLmNvbSIgLz4KLTwvaGVhZD4KLTxib2R5PgotPHA+VGhpcyBwYWNrYWdlIGltcGxlbWVudHMgRE9NLXNwZWNpZmljIHRyYW5zZm9ybWF0aW9uIEFQSXMuPC9wPgotPHA+VGhlIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLmRvbS5ET01Tb3VyY2V9IGNsYXNzIGFsbG93cyB0aGUKLWNsaWVudCBvZiB0aGUgaW1wbGVtZW50YXRpb24gb2YgdGhpcyBBUEkgdG8gc3BlY2lmeSBhIERPTQote0BsaW5rIG9yZy53M2MuZG9tLk5vZGV9IGFzIHRoZSBzb3VyY2Ugb2YgdGhlIGlucHV0IHRyZWUuIFRoZSBtb2RlbCBvZgotaG93IHRoZSBUcmFuc2Zvcm1lciBkZWFscyB3aXRoIHRoZSBET00gdHJlZSBpbiB0ZXJtcyBvZiBtaXNtYXRjaGVzIHdpdGggdGhlCi08QSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2RhdGEtbW9kZWwiPlhTTFQgZGF0YSBtb2RlbDwvQT4gb3IKLW90aGVyIGRhdGEgbW9kZWxzIGlzIGJleW9uZCB0aGUgc2NvcGUgb2YgdGhpcyBkb2N1bWVudC4gQW55IG9mIHRoZSBub2RlcwotZGVyaXZlZCBmcm9tIHtAbGluayBvcmcudzNjLmRvbS5Ob2RlfSBhcmUgbGVnYWwgaW5wdXQuPC9wPgotPHA+VGhlIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLmRvbS5ET01SZXN1bHR9IGNsYXNzIGFsbG93cwotYSB7QGxpbmsgb3JnLnczYy5kb20uTm9kZX0gdG8gYmUgc3BlY2lmaWVkIHRvIHdoaWNoIHJlc3VsdCBET00gbm9kZXMgd2lsbAotYmUgYXBwZW5kZWQuIElmIGFuIG91dHB1dCBub2RlIGlzIG5vdCBzcGVjaWZpZWQsIHRoZSB0cmFuc2Zvcm1lciB3aWxsIHVzZQote0BsaW5rIGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlciNuZXdEb2N1bWVudH0gdG8gY3JlYXRlIGFuCi1vdXRwdXQge0BsaW5rIG9yZy53M2MuZG9tLkRvY3VtZW50fSBub2RlLiBJZiBhIG5vZGUgaXMgc3BlY2lmaWVkLCBpdAotc2hvdWxkIGJlIG9uZSBvZiB0aGUgZm9sbG93aW5nOiB7QGxpbmsgb3JnLnczYy5kb20uRG9jdW1lbnR9LAote0BsaW5rIG9yZy53M2MuZG9tLkVsZW1lbnR9LCBvcgote0BsaW5rIG9yZy53M2MuZG9tLkRvY3VtZW50RnJhZ21lbnR9LiBTcGVjaWZpY2F0aW9uIG9mIGFueSBvdGhlciBub2RlCi10eXBlIGlzIGltcGxlbWVudGF0aW9uIGRlcGVuZGVudCBhbmQgdW5kZWZpbmVkIGJ5IHRoaXMgQVBJLiBJZiB0aGUgcmVzdWx0IGlzIGEKLXtAbGluayBvcmcudzNjLmRvbS5Eb2N1bWVudH0sIHRoZSBvdXRwdXQgb2YgdGhlIHRyYW5zZm9ybWF0aW9uIG11c3QgaGF2ZQotYSBzaW5nbGUgZWxlbWVudCByb290IHRvIHNldCBhcyB0aGUgZG9jdW1lbnQgZWxlbWVudC48L3A+Ci08cD5UaGUge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uZG9tLkRPTUxvY2F0b3J9IG5vZGUgbWF5IGJlIHBhc3NlZAotdG8ge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb259IG9iamVjdHMsIGFuZAotcmV0cmlldmVkIGJ5IHRyeWluZyB0byBjYXN0IHRoZSByZXN1bHQgb2YgdGhlCi17QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbiNnZXRMb2NhdG9yKCl9IG1ldGhvZC4KLVRoZSBpbXBsZW1lbnRhdGlvbiBoYXMgbm8gcmVzcG9uc2liaWxpdHkgdG8gdXNlIGEgRE9NTG9jYXRvciBpbnN0ZWFkIG9mIGEKLXtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlNvdXJjZUxvY2F0b3J9ICh0aG91Z2ggbGluZSBudW1iZXJzIGFuZCB0aGUKLWxpa2UgZG8gbm90IG1ha2UgbXVjaCBzZW5zZSBmb3IgYSBET00pLCBzbyB0aGUgcmVzdWx0IG9mIGdldExvY2F0b3IgbXVzdCBhbHdheXMKLWJlIHRlc3RlZCB3aXRoIGFuIGluc3RhbmNlb2YuIDwvcD4KLTwvYm9keT4KLTwvaHRtbD4KZGlmZiAtLWdpdCBhL3NyYy9qYXZheC94bWwvdHJhbnNmb3JtL292ZXJ2aWV3Lmh0bWwgYi9zcmMvamF2YXgveG1sL3RyYW5zZm9ybS9vdmVydmlldy5odG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxYWQ5MDZhLi4wMDAwMDAwCi0tLSBhL3NyYy9qYXZheC94bWwvdHJhbnNmb3JtL292ZXJ2aWV3Lmh0bWwKKysrIC9kZXYvbnVsbApAQCAtMSwyOTEgKzAsMCBAQAotPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KLTwhLS0KLUNvcHlyaWdodCAoYykgMjAwMCwgMjAwNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLURPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLQotVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLXVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi1wdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLXBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLWJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotCi1UaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLUFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi12ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLQotWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotCi1QbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotcXVlc3Rpb25zLiAKLS0tPgotCi08IURPQ1RZUEUgaHRtbAotICAgICBQVUJMSUMgIi0vL1czQy8vRFREIFhIVE1MIDEuMCBTdHJpY3QvL0VOIgotICAgICAiaHR0cDovL3d3dy53My5vcmcvVFIveGh0bWwxL0RURC94aHRtbDEtc3RyaWN0LmR0ZCI+Ci0KLTxodG1sIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sIj4KLQotPGhlYWQ+Ci0gIDx0aXRsZT5UcmFuc2Zvcm1hdGlvbiBBUEkgRm9yIFhNTDwvdGl0bGU+Ci0KLSAgPG1ldGEgbmFtZT0iQ1ZTIgotICAgICAgICBjb250ZW50PSIkSWQ6IG92ZXJ2aWV3Lmh0bWwsdiAxLjIgMjAwNS8wNi8xMCAwMzo1MDozOSBqZWZmc3V0dG9yIEV4cCAkIiAvPgotICA8bWV0YSBuYW1lPSJBVVRIT1IiCi0gICAgICAgIGNvbnRlbnQ9IkplZmYuU3V0dG9yQFN1bi5jb20iIC8+Ci08L2hlYWQ+Ci08Ym9keT4gCi0gIAotPGgyPlRyYW5zZm9ybWF0aW9uIEFQSSBGb3IgWE1MPC9oMj4gCi0gIAotICAKLTxoMz5JbnRyb2R1Y3Rpb248L2gzPiAKLSAgCi08cD5UaGlzIG92ZXJ2aWV3IGRlc2NyaWJlcyB0aGUgc2V0IG9mIEFQSXMgY29udGFpbmVkIGluCi0JIGphdmF4LnhtbC50cmFuc2Zvcm0uIEZvciB0aGUgc2FrZSBvZiBicmV2aXR5LCB0aGVzZSBpbnRlcmZhY2VzIGFyZSByZWZlcnJlZCB0bwotCSBhcyBUckFYIChUcmFuc2Zvcm1hdGlvbnMgZm9yIFhNTCkuIDwvcD4gCi0gIAotPHA+VGhlcmUgaXMgYSBicm9hZCBuZWVkIGZvciBKYXZhIGFwcGxpY2F0aW9ucyB0byBiZSBhYmxlIHRvIHRyYW5zZm9ybSBYTUwKLQkgYW5kIHJlbGF0ZWQgdHJlZS1zaGFwZWQgZGF0YSBzdHJ1Y3R1cmVzLiBJbiBmYWN0LCBYTUwgaXMgbm90IG5vcm1hbGx5IHZlcnkKLQkgdXNlZnVsIHRvIGFuIGFwcGxpY2F0aW9uIHdpdGhvdXQgZ29pbmcgdGhyb3VnaCBzb21lIHNvcnQgb2YgdHJhbnNmb3JtYXRpb24sCi0JIHVubGVzcyB0aGUgc2VtYW50aWMgc3RydWN0dXJlIGlzIHVzZWQgZGlyZWN0bHkgYXMgZGF0YS4gQWxtb3N0IGFsbCBYTUwtcmVsYXRlZAotCSBhcHBsaWNhdGlvbnMgbmVlZCB0byBwZXJmb3JtIHRyYW5zZm9ybWF0aW9ucy4gVHJhbnNmb3JtYXRpb25zIG1heSBiZSBkZXNjcmliZWQKLQkgYnkgSmF2YSBjb2RlLCBQZXJsIGNvZGUsIDxBIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQiPlhTTFQ8L0E+Ci0JIFN0eWxlc2hlZXRzLCBvdGhlciB0eXBlcyBvZiBzY3JpcHQsIG9yIGJ5IHByb3ByaWV0YXJ5IGZvcm1hdHMuIFRoZSBpbnB1dHMsIG9uZQotCSBvciBtdWx0aXBsZSwgdG8gYSB0cmFuc2Zvcm1hdGlvbiwgbWF5IGJlIGEgVVJMLCBYTUwgc3RyZWFtLCBhIERPTSB0cmVlLCBTQVgKLQkgRXZlbnRzLCBvciBhIHByb3ByaWV0YXJ5IGZvcm1hdCBvciBkYXRhIHN0cnVjdHVyZS4gVGhlIG91dHB1dCB0eXBlcyBhcmUgdGhlCi0JIHByZXR0eSBtdWNoIHRoZSBzYW1lIHR5cGVzIGFzIHRoZSBpbnB1dHMsIGJ1dCBkaWZmZXJlbnQgaW5wdXRzIG1heSBuZWVkIHRvIGJlCi0JIGNvbWJpbmVkIHdpdGggZGlmZmVyZW50IG91dHB1dHMuPC9wPiAKLSAgCi08cD5UaGUgZ3JlYXQgY2hhbGxlbmdlIG9mIGEgdHJhbnNmb3JtYXRpb24gQVBJIGlzIGhvdyB0byBkZWFsIHdpdGggYWxsIHRoZQotCSBwb3NzaWJsZSBjb21iaW5hdGlvbnMgb2YgaW5wdXRzIGFuZCBvdXRwdXRzLCB3aXRob3V0IGJlY29taW5nIHNwZWNpYWxpemVkIGZvcgotCSBhbnkgb2YgdGhlIGdpdmVuIHR5cGVzLjwvcD4gCi0gIAotPHA+VGhlIEphdmEgY29tbXVuaXR5IHdpbGwgZ3JlYXRseSBiZW5lZml0IGZyb20gYSBjb21tb24gQVBJIHRoYXQgd2lsbAotCSBhbGxvdyB0aGVtIHRvIHVuZGVyc3RhbmQgYW5kIGFwcGx5IGEgc2luZ2xlIG1vZGVsLCB3cml0ZSB0byBjb25zaXN0ZW50Ci0JIGludGVyZmFjZXMsIGFuZCBhcHBseSB0aGUgdHJhbnNmb3JtYXRpb25zIHBvbHltb3JwaGljYWxseS4gVHJBWCBhdHRlbXB0cyB0bwotCSBkZWZpbmUgYSBtb2RlbCB0aGF0IGlzIGNsZWFuIGFuZCBnZW5lcmljLCB5ZXQgZmlsbHMgZ2VuZXJhbCBhcHBsaWNhdGlvbgotCSByZXF1aXJlbWVudHMgYWNyb3NzIGEgd2lkZSB2YXJpZXR5IG9mIHVzZXMuIDwvcD4gCi0gICAKLQkgCi08aDM+R2VuZXJhbCBUZXJtaW5vbG9neTwvaDM+IAotCSAKLTxwPlRoaXMgc2VjdGlvbiB3aWxsIGV4cGxhaW4gc29tZSBnZW5lcmFsIHRlcm1pbm9sb2d5IHVzZWQgaW4gdGhpcwotCQlkb2N1bWVudC4gVGVjaG5pY2FsIHRlcm1pbm9sb2d5IHdpbGwgYmUgZXhwbGFpbmVkIGluIHRoZSBNb2RlbCBzZWN0aW9uLiBJbiBtYW55Ci0JCWNhc2VzLCB0aGUgZ2VuZXJhbCB0ZXJtaW5vbG9neSBvdmVybGFwcyB3aXRoIHRoZSB0ZWNobmljYWwgdGVybWlub2xvZ3kuPC9wPiAKLQkgCi08dWw+Ci08bGk+Ci08cD4KLTxiPlRyZWU8L2I+Ci08YnI+VGhpcyB0ZXJtLCBhcyB1c2VkIHdpdGhpbiB0aGlzIGRvY3VtZW50LCBkZXNjcmliZXMgYW4KLQkJCSBhYnN0cmFjdCBzdHJ1Y3R1cmUgdGhhdCBjb25zaXN0cyBvZiBub2RlcyBvciBldmVudHMgdGhhdCBtYXkgYmUgcHJvZHVjZWQgYnkKLQkJCSBYTUwuIEEgVHJlZSBwaHlzaWNhbGx5IG1heSBiZSBhIERPTSB0cmVlLCBhIHNlcmllcyBvZiB3ZWxsIGJhbGFuY2VkIHBhcnNlCi0JCQkgZXZlbnRzIChzdWNoIGFzIHRob3NlIGNvbWluZyBmcm9tIGEgU0FYMiBDb250ZW50SGFuZGVyKSwgYSBzZXJpZXMgb2YgcmVxdWVzdHMKLQkJCSAodGhlIHJlc3VsdCBvZiB3aGljaCBjYW4gZGVzY3JpYmUgYSB0cmVlKSwgb3IgYSBzdHJlYW0gb2YgbWFya2VkLXVwCi0JCQkgY2hhcmFjdGVycy48L3A+Ci08L2xpPgotPGxpPgotPHA+Ci08Yj5Tb3VyY2UgVHJlZShzKTwvYj4KLTxicj5PbmUgb3IgbW9yZSB0cmVlcyB0aGF0IGFyZSB0aGUgaW5wdXRzIHRvIHRoZQotCQkJIHRyYW5zZm9ybWF0aW9uLjwvcD4KLTwvbGk+Ci08bGk+Ci08cD4KLTxiPlJlc3VsdCBUcmVlKHMpPC9iPgotPGJyPk9uZSBvciBtb3JlIHRyZWVzIHRoYXQgYXJlIHRoZSBvdXRwdXQgb2YgdGhlCi0JCQkgdHJhbnNmb3JtYXRpb24uPC9wPgotPC9saT4KLTxsaT4KLTxwPgotPGI+VHJhbnNmb3JtYXRpb248L2I+Ci08YnI+VGhlIHByb2Nlc3NvciBvZiBjb25zdW1pbmcgYSBzdHJlYW0gb3IgdHJlZSB0byBwcm9kdWNlCi0JCQkgYW5vdGhlciBzdHJlYW0gb3IgdHJlZS48L3A+Ci08L2xpPgotPGxpPgotPHA+Ci08Yj5JZGVudGl0eSAob3IgQ29weSkgVHJhbnNmb3JtYXRpb248L2I+Ci08YnI+VGhlIHByb2Nlc3Mgb2YgdHJhbnNmb3JtYXRpb24gZnJvbSBhIHNvdXJjZSB0byBhIHJlc3VsdCwKLQkJCSBtYWtpbmcgYXMgZmV3IHN0cnVjdHVyYWwgY2hhbmdlcyBhcyBwb3NzaWJsZSBhbmQgbm8gaW5mb3JtYXRpb25hbCBjaGFuZ2VzLiBUaGUKLQkJCSB0ZXJtIGlzIHNvbWV3aGF0IGxvb3NlbHkgdXNlZCwgYXMgdGhlIHByb2Nlc3MgaXMgcmVhbGx5IGEgY29weS4gZnJvbSBvbmUKLQkJCSAiZm9ybWF0IiAoc3VjaCBhcyBhIERPTSB0cmVlLCBzdHJlYW0sIG9yIHNldCBvZiBTQVggZXZlbnRzKSB0bwotCQkJIGFub3RoZXIuPC9wPgotPC9saT4KLTxsaT4KLTxwPgotPGI+U2VyaWFsaXphdGlvbjwvYj4KLTxicj5UaGUgcHJvY2VzcyBvZiB0YWtpbmcgYSB0cmVlIGFuZCB0dXJuaW5nIGl0IGludG8gYSBzdHJlYW0uIEluCi0JCQkgc29tZSBzZW5zZSwgYSBzZXJpYWxpemF0aW9uIGlzIGEgc3BlY2lhbGl6ZWQgdHJhbnNmb3JtYXRpb24uPC9wPgotPC9saT4KLTxsaT4KLTxwPgotPGI+UGFyc2luZzwvYj4KLTxicj5UaGUgcHJvY2VzcyBvZiB0YWtpbmcgYSBzdHJlYW0gYW5kIHR1cm5pbmcgaXQgaW50byBhIHRyZWUuIEluCi0JCQkgc29tZSBzZW5zZSwgcGFyc2luZyBpcyBhIHNwZWNpYWxpemVkIHRyYW5zZm9ybWF0aW9uLjwvcD4KLTwvbGk+Ci08bGk+Ci08cD4KLTxiPlRyYW5zZm9ybWVyPC9iPgotPGJyPkEgVHJhbnNmb3JtZXIgaXMgdGhlIG9iamVjdCB0aGF0IGV4ZWN1dGVzIHRoZSB0cmFuc2Zvcm1hdGlvbi4KLQkJCSA8L3A+Ci08L2xpPgotPGxpPgotPHA+Ci08Yj5UcmFuc2Zvcm1hdGlvbiBpbnN0cnVjdGlvbnM8L2I+Ci08YnI+RGVzY3JpYmVzIHRoZSB0cmFuc2Zvcm1hdGlvbi4gQSBmb3JtIG9mIGNvZGUsIHNjcmlwdCwgb3IKLQkJCSBzaW1wbHkgYSBkZWNsYXJhdGlvbiBvciBzZXJpZXMgb2YgZGVjbGFyYXRpb25zLjwvcD4KLTwvbGk+Ci08bGk+Ci08cD4KLTxiPlN0eWxlc2hlZXQ8L2I+Ci08YnI+VGhlIHNhbWUgYXMgInRyYW5zZm9ybWF0aW9uIGluc3RydWN0aW9ucywiIGV4Y2VwdCBpdCBpcwotCQkJIGxpa2VseSB0byBiZSB1c2VkIGluIGNvbmp1bmN0aW9uIHdpdGggPEEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCI+WFNMVDwvQT4uPC9wPgotPC9saT4KLTxsaT4KLTxwPgotPGI+VGVtcGxhdGVzPC9iPgotPGJyPkFub3RoZXIgZm9ybSBvZiAidHJhbnNmb3JtYXRpb24gaW5zdHJ1Y3Rpb25zLiIgSW4gdGhlIFRyQVgKLQkJCSBpbnRlcmZhY2UsIHRoaXMgdGVybSBpcyB1c2VkIHRvIGRlc2NyaWJlIHByb2Nlc3NlZCBvciBjb21waWxlZCB0cmFuc2Zvcm1hdGlvbgotCQkJIGluc3RydWN0aW9ucy4gVGhlIFNvdXJjZSBmbG93cyB0aHJvdWdoIGEgVGVtcGxhdGVzIG9iamVjdCB0byBiZSBmb3JtZWQgaW50byB0aGUKLQkJCSBSZXN1bHQuPC9wPgotPC9saT4KLTxsaT4KLTxwPgotPGI+UHJvY2Vzc29yPC9iPgotPGJyPkEgZ2VuZXJhbCB0ZXJtIGZvciB0aGUgdGhpbmcgdGhhdCBtYXkgYm90aCBwcm9jZXNzIHRoZQotCQkJIHRyYW5zZm9ybWF0aW9uIGluc3RydWN0aW9ucywgYW5kIHBlcmZvcm0gdGhlIHRyYW5zZm9ybWF0aW9uLjwvcD4KLTwvbGk+Ci08bGk+Ci08cD4KLTxiPkRPTTwvYj4KLTxicj5Eb2N1bWVudCBPYmplY3QgTW9kZWwsIHNwZWNpZmljYWxseSByZWZlcnJpbmcgdG8gdGhlCi0JCQkgPEEgaHJlZj0iI2h0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yJTIwIj5Eb2N1bWVudCBPYmplY3QgTW9kZWwKLQkJCSAoRE9NKSBMZXZlbCAyIFNwZWNpZmljYXRpb248L0E+LjwvcD4KLTwvbGk+Ci08bGk+Ci0JPHA+Ci0JCTxiPlNBWDwvYj48YnI+Ci0JCVNpbXBsZSBBUEkgZm9yIFhNTCwgc3BlY2lmaWNhbGx5IHJlZmVycmluZyB0byB0aGUgPGEgaHJlZj0iaHR0cDovL3NheC5zb3VyY2Vmb3JnZS5uZXQvIj5TQVggMi4wLjIgcmVsZWFzZTwvYT4uCi0JPC9wPgotPC9saT4KLTwvdWw+IAotICAgCi0gIAotICAKLTxoMz5Nb2RlbDwvaDM+IAotICAKLTxwPlRoZSBzZWN0aW9uIGRlZmluZXMgdGhlIGFic3RyYWN0IG1vZGVsIGZvciBUckFYLCBhcGFydCBmcm9tIHRoZSBkZXRhaWxzCi0JIG9mIHRoZSBpbnRlcmZhY2VzLjwvcD4gCi0gIAotPHA+QSBUUmFYIDxBIGhyZWY9IiNwYXR0ZXJuLVRyYW5zZm9ybWVyRmFjdG9yeSI+VHJhbnNmb3JtZXJGYWN0b3J5PC9BPiBpcyBhbiBvYmplY3QKLQkgdGhhdCBwcm9jZXNzZXMgdHJhbnNmb3JtYXRpb24gaW5zdHJ1Y3Rpb25zLCBhbmQgcHJvZHVjZXMKLQkgPEEgaHJlZj0iI3BhdHRlcm4tVGVtcGxhdGVzIj5UZW1wbGF0ZXM8L0E+IChpbiB0aGUgdGVjaG5pY2FsCi0JIHRlcm1pbm9sb2d5KS4gQSA8QSBocmVmPSIjcGF0dGVybi1UZW1wbGF0ZXMiPlRlbXBsYXRlczwvQT4KLQkgb2JqZWN0IHByb3ZpZGVzIGEgPEEgaHJlZj0iI3BhdHRlcm4tVHJhbnNmb3JtZXIiPlRyYW5zZm9ybWVyPC9BPiwgd2hpY2ggdHJhbnNmb3JtcyBvbmUgb3IKLQkgbW9yZSA8QSBocmVmPSIjcGF0dGVybi1Tb3VyY2UiPlNvdXJjZTwvQT5zIGludG8gb25lIG9yIG1vcmUKLQkgPEEgaHJlZj0iI3BhdHRlcm4tUmVzdWx0Ij5SZXN1bHQ8L0E+cy48L3A+IAotICAKLTxwPlRvIHVzZSB0aGUgVFJhWCBpbnRlcmZhY2UsIHlvdSBjcmVhdGUgYQotCSA8QSBocmVmPSIjcGF0dGVybi1UcmFuc2Zvcm1lckZhY3RvcnkiPlRyYW5zZm9ybWVyRmFjdG9yeTwvQT4sCi0JIHdoaWNoIG1heSBkaXJlY3RseSBwcm92aWRlIGEgPEEgaHJlZj0iI3BhdHRlcm4tVHJhbnNmb3JtZXJzIj5UcmFuc2Zvcm1lcnM8L0E+LCBvciB3aGljaCBjYW4gcHJvdmlkZQotCSA8QSBocmVmPSIjcGF0dGVybi1UZW1wbGF0ZXMiPlRlbXBsYXRlczwvQT4gZnJvbSBhIHZhcmlldHkgb2YKLQkgPEEgaHJlZj0iI3BhdHRlcm4tU291cmNlIj5Tb3VyY2U8L0E+cy4gVGhlCi0JIDxBIGhyZWY9IiNwYXR0ZXJuLVRlbXBsYXRlcyI+VGVtcGxhdGVzPC9BPiBvYmplY3QgaXMgYSBwcm9jZXNzZWQKLQkgb3IgY29tcGlsZWQgcmVwcmVzZW50YXRpb24gb2YgdGhlIHRyYW5zZm9ybWF0aW9uIGluc3RydWN0aW9ucywgYW5kIHByb3ZpZGVzIGEKLQkgPEEgaHJlZj0iI3BhdHRlcm4tVHJhbnNmb3JtZXIiPlRyYW5zZm9ybWVyPC9BPi4gVGhlCi0JIDxBIGhyZWY9IiNwYXR0ZXJuLVRyYW5zZm9ybWVyIj5UcmFuc2Zvcm1lcjwvQT4gcHJvY2Vzc2VzIGEKLQkgPEEgaHJlZj0iI3BhdHRlcm4tVHJhbnNmb3JtZXIiPlNvdXJjZTwvQT4gYWNjb3JkaW5nIHRvIHRoZQotCSBpbnN0cnVjdGlvbnMgZm91bmQgaW4gdGhlIDxBIGhyZWY9IiNwYXR0ZXJuLVRlbXBsYXRlcyI+VGVtcGxhdGVzPC9BPiwgYW5kIHByb2R1Y2VzIGEKLQkgPEEgaHJlZj0iI3BhdHRlcm4tUmVzdWx0Ij5SZXN1bHQ8L0E+LjwvcD4gCi0gIAotPHA+VGhlIHByb2Nlc3Mgb2YgdHJhbnNmb3JtYXRpb24gZnJvbSBhIHRyZWUsIGVpdGhlciBpbiB0aGUgZm9ybSBvZiBhbgotCSBvYmplY3QgbW9kZWwsIG9yIGluIHRoZSBmb3JtIG9mIHBhcnNlIGV2ZW50cywgaW50byBhIHN0cmVhbSwgaXMga25vd24gYXMKLQkgPGNvZGU+c2VyaWFsaXphdGlvbjwvY29kZT4uIFdlIGJlbGlldmUgdGhpcyBpcyB0aGUgbW9zdCBzdWl0YWJsZSB0ZXJtIGZvcgotCSB0aGlzIHByb2Nlc3MsIGRlc3BpdGUgdGhlIG92ZXJsYXAgd2l0aCBKYXZhIG9iamVjdCBzZXJpYWxpemF0aW9uLjwvcD4KLSAgCi08SDM+VFJhWCBQYXR0ZXJuczwvSDM+Ci08dWw+Ci08cD4KLTxiPjxhIG5hbWU9InBhdHRlcm4tUHJvY2Vzc29yIj5Qcm9jZXNzb3I8L2E+PC9iPgotPGJyPgotPGJyPgotPGk+SW50ZW50OiA8L2k+R2VuZXJpYyBjb25jZXB0IGZvciB0aGUKLSAgc2V0IG9mIG9iamVjdHMgdGhhdCBpbXBsZW1lbnQgdGhlIFRyQVggaW50ZXJmYWNlcy48YnI+Ci08aT5SZXNwb25zaWJpbGl0aWVzOiA8L2k+Q3JlYXRlIGNvbXBpbGVkIHRyYW5zZm9ybWF0aW9uIGluc3RydWN0aW9ucywgdHJhbnNmb3JtCi0gIHNvdXJjZXMsIGFuZCBtYW5hZ2UgdHJhbnNmb3JtYXRpb24gcGFyYW1ldGVycyBhbmQKLSAgcHJvcGVydGllcy48YnI+Ci08aT5UaHJlYWQgc2FmZXR5OiA8L2k+T25seSB0aGUgVGVtcGxhdGVzIG9iamVjdCBjYW4gYmUKLSAgdXNlZCBjb25jdXJyZW50bHkgaW4gbXVsdGlwbGUgdGhyZWFkcy4gVGhlIHJlc3Qgb2YgdGhlIHByb2Nlc3NvciBkb2VzIG5vdCBkbwotICBzeW5jaHJvbml6ZWQgYmxvY2tpbmcsIGFuZCBzbyBtYXkgbm90IGJlIHVzZWQgdG8gcGVyZm9ybSBtdWx0aXBsZSBjb25jdXJyZW50Ci0gIG9wZXJhdGlvbnMuIERpZmZlcmVudCBQcm9jZXNzb3JzIGNhbiBiZSB1c2VkIGNvbmN1cnJlbnRseSBieSBkaWZmZXJlbnQKLSAgdGhyZWFkcy48L3A+Ci08cD4KLTxiPjxhIG5hbWU9InBhdHRlcm4tVHJhbnNmb3JtZXJGYWN0b3J5Ij5UcmFuc2Zvcm1lckZhY3Rvcnk8L2E+PC9iPgotPGJyPgotPGJyPgotPGk+SW50ZW50OiA8L2k+U2VydmUgYXMgYSB2ZW5kb3ItbmV1dHJhbCBQcm9jZXNzb3IgaW50ZXJmYWNlIGZvcgotICA8QSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0Ij5YU0xUPC9BPiBhbmQgc2ltaWxhcgotICBwcm9jZXNzb3JzLjxicj4KLTxpPlJlc3BvbnNpYmlsaXRpZXM6IDwvaT5TZXJ2ZSBhcyBhIGZhY3RvcnkgZm9yIGEgY29uY3JldGUKLSAgaW1wbGVtZW50YXRpb24gb2YgYW4gVHJhbnNmb3JtZXJGYWN0b3J5LCBzZXJ2ZSBhcyBhIGRpcmVjdCBmYWN0b3J5IGZvcgotICBUcmFuc2Zvcm1lciBvYmplY3RzLCBzZXJ2ZSBhcyBhIGZhY3RvcnkgZm9yIFRlbXBsYXRlcyBvYmplY3RzLCBhbmQgbWFuYWdlCi0gIHByb2Nlc3NvciBzcGVjaWZpYyBmZWF0dXJlcy48YnI+Ci08aT5UaHJlYWQgc2FmZXR5OiA8L2k+QQotICBUcmFuc2Zvcm1lckZhY3RvcnkgbWF5IG5vdCBwZXJmb3JtIG11bGl0cGxlIGNvbmN1cnJlbnQKLSAgb3BlcmF0aW9ucy48L3A+Ci08cD4KLTxiPjxhIG5hbWU9InBhdHRlcm4tVGVtcGxhdGVzIj5UZW1wbGF0ZXM8L2E+PC9iPgotPGJyPgotPGJyPgotPGk+SW50ZW50OiA8L2k+VGhlCi0gIHJ1bnRpbWUgcmVwcmVzZW50YXRpb24gb2YgdGhlIHRyYW5zZm9ybWF0aW9uIGluc3RydWN0aW9ucy48YnI+Ci08aT5SZXNwb25zaWJpbGl0aWVzOiA8L2k+QSBkYXRhIGJhZyBmb3IgdHJhbnNmb3JtYXRpb24gaW5zdHJ1Y3Rpb25zOyBhY3QgYXMgYSBmYWN0b3J5Ci0gIGZvciBUcmFuc2Zvcm1lcnMuPGJyPgotPGk+VGhyZWFkIHNhZmV0eTogPC9pPlRocmVhZHNhZmUgZm9yIGNvbmN1cnJlbnQKLSAgdXNhZ2Ugb3ZlciBtdWx0aXBsZSB0aHJlYWRzIG9uY2UgY29uc3RydWN0aW9uIGlzIGNvbXBsZXRlLjwvcD4KLTxwPgotPGI+PGEgbmFtZT0icGF0dGVybi1UcmFuc2Zvcm1lciI+VHJhbnNmb3JtZXI8L2E+PC9iPgotPGJyPgotPGJyPgotPGk+SW50ZW50OiA8L2k+QWN0IGFzIGEgcGVyLXRocmVhZAotICBleGVjdXRpb24gY29udGV4dCBmb3IgdHJhbnNmb3JtYXRpb25zLCBhY3QgYXMgYW4gaW50ZXJmYWNlIGZvciBwZXJmb3JtaW5nIHRoZQotICB0cmFuc2Zvcm1hdGlvbi48YnI+Ci08aT5SZXNwb25zaWJpbGl0aWVzOiA8L2k+UGVyZm9ybSB0aGUKLSAgdHJhbnNmb3JtYXRpb24uPGJyPgotPGk+VGhyZWFkIHNhZmV0eTogPC9pPk9ubHkgb25lIGluc3RhbmNlIHBlciB0aHJlYWQKLSAgaXMgc2FmZS48YnI+Ci08aT5Ob3RlczogPC9pPlRoZSBUcmFuc2Zvcm1lciBpcyBib3VuZCB0byB0aGUgVGVtcGxhdGVzCi0gIG9iamVjdCB0aGF0IGNyZWF0ZWQgaXQuPC9wPgotPHA+Ci08Yj48YSBuYW1lPSJwYXR0ZXJuLVNvdXJjZSI+U291cmNlPC9hPjwvYj4KLTxicj4KLTxicj4KLTxpPkludGVudDogPC9pPlNlcnZlIGFzIGEKLSAgc2luZ2xlIHZlbmRvci1uZXV0cmFsIG9iamVjdCBmb3IgbXVsdGlwbGUgdHlwZXMgb2YgaW5wdXQuPGJyPgotPGk+UmVzcG9uc2liaWxpdGllczogPC9pPkFjdCBhcyBzaW1wbGUgZGF0YSBob2xkZXIgZm9yIFN5c3RlbSBJRHMsIERPTSBub2Rlcywgc3RyZWFtcywKLSAgZXRjLjxicj4KLTxpPlRocmVhZCBzYWZldHk6IDwvaT5UaHJlYWRzYWZlIGNvbmN1cnJlbnRseSBvdmVyIG11bHRpcGxlCi0gIHRocmVhZHMgZm9yIHJlYWQtb25seSBvcGVyYXRpb25zOyBtdXN0IGJlIHN5bmNocm9uaXplZCBmb3IgZWRpdAotICBvcGVyYXRpb25zLjwvcD4KLTxwPgotPGI+PGEgbmFtZT0icGF0dGVybi1SZXN1bHQiPlJlc3VsdDwvYT48L2I+Ci08YnI+Ci08YnI+Ci08aT5Qb3RlbnRpYWwgYWx0ZXJuYXRlIG5hbWU6IDwvaT5SZXN1bHRUYXJnZXQ8YnI+Ci08aT5JbnRlbnQ6IDwvaT5TZXJ2ZQotICBhcyBhIHNpbmdsZSBvYmplY3QgZm9yIG11bHRpcGxlIHR5cGVzIG9mIG91dHB1dCwgc28gdGhlcmUgY2FuIGJlIHNpbXBsZSBwcm9jZXNzCi0gIG1ldGhvZCBzaWduYXR1cmVzLjxicj4KLTxpPlJlc3BvbnNpYmlsaXRpZXM6IDwvaT5BY3QgYXMgc2ltcGxlIGRhdGEgaG9sZGVyIGZvcgotICBvdXRwdXQgc3RyZWFtLCBET00gbm9kZSwgQ29udGVudEhhbmRsZXIsIGV0Yy48YnI+Ci08aT5UaHJlYWQgc2FmZXR5OiA8L2k+VGhyZWFkc2FmZSBjb25jdXJyZW50bHkgb3ZlciBtdWx0aXBsZSB0aHJlYWRzIGZvciByZWFkLW9ubHksCi0gIG11c3QgYmUgc3luY2hyb25pemVkIGZvciBlZGl0LjwvcD4KLTwvdWw+IAotICAKLQotPC9ib2R5PgotPC9odG1sPgpkaWZmIC0tZ2l0IGEvc3JjL2phdmF4L3htbC90cmFuc2Zvcm0vcGFja2FnZS5odG1sIGIvc3JjL2phdmF4L3htbC90cmFuc2Zvcm0vcGFja2FnZS5odG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0NWMyZDc4Li4wMDAwMDAwCi0tLSBhL3NyYy9qYXZheC94bWwvdHJhbnNmb3JtL3BhY2thZ2UuaHRtbAorKysgL2Rldi9udWxsCkBAIC0xLDIzMyArMCwwIEBACi08P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJVVEYtOCI/PgotPCEtLQotQ29weXJpZ2h0IChjKSAyMDAwLCAyMDA1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotCi1UaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLXB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0KLVRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi1GSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLXZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci1hY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotCi1Zb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0yIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi1JbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0KLVBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi1vciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci1xdWVzdGlvbnMuIAotLS0+Ci0KLTwhRE9DVFlQRSBodG1sCi0gICAgIFBVQkxJQyAiLS8vVzNDLy9EVEQgWEhUTUwgMS4wIFN0cmljdC8vRU4iCi0gICAgICJodHRwOi8vd3d3LnczLm9yZy9UUi94aHRtbDEvRFREL3hodG1sMS1zdHJpY3QuZHRkIj4KLQotPGh0bWwgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwiPgotCi08aGVhZD4KLSAgPHRpdGxlPmphdmF4LnhtbC50cmFuc2Zvcm08L3RpdGxlPgotCi0gIDxtZXRhIG5hbWU9IkNWUyIKLSAgICAgICAgY29udGVudD0iJElkOiBwYWNrYWdlLmh0bWwsdiAxLjIgMjAwNS8wNi8xMCAwMzo1MDozOSBqZWZmc3V0dG9yIEV4cCAkIiAvPgotICA8bWV0YSBuYW1lPSJBVVRIT1IiCi0gICAgICAgIGNvbnRlbnQ9IkplZmYuU3V0dG9yQFN1bi5jb20iIC8+Ci08L2hlYWQ+Ci0KLTxib2R5PgotPHA+VGhpcyBwYWNrYWdlIGRlZmluZXMgdGhlIGdlbmVyaWMgQVBJcyBmb3IgcHJvY2Vzc2luZyB0cmFuc2Zvcm1hdGlvbgotaW5zdHJ1Y3Rpb25zLCBhbmQgcGVyZm9ybWluZyBhIHRyYW5zZm9ybWF0aW9uIGZyb20gc291cmNlIHRvIHJlc3VsdC4gVGhlc2UKLWludGVyZmFjZXMgaGF2ZSBubyBkZXBlbmRlbmNpZXMgb24gU0FYIG9yIHRoZSBET00gc3RhbmRhcmQsIGFuZCB0cnkgdG8gbWFrZSBhcwotZmV3IGFzc3VtcHRpb25zIGFzIHBvc3NpYmxlIGFib3V0IHRoZSBkZXRhaWxzIG9mIHRoZSBzb3VyY2UgYW5kIHJlc3VsdCBvZiBhCi10cmFuc2Zvcm1hdGlvbi4gSXQgYWNoaWV2ZXMgdGhpcyBieSBkZWZpbmluZwote0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uU291cmNlfSBhbmQKLXtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlJlc3VsdH0gaW50ZXJmYWNlcy4KLTwvcD4KLQotPHA+VG8gZGVmaW5lIGNvbmNyZXRlIGNsYXNzZXMgZm9yIHRoZSB1c2VyLCB0aGUgQVBJIGRlZmluZXMgc3BlY2lhbGl6YXRpb25zCi1vZiB0aGUgaW50ZXJmYWNlcyBmb3VuZCBhdCB0aGUgcm9vdCBsZXZlbC4gVGhlc2UgaW50ZXJmYWNlcyBhcmUgZm91bmQgaW4KLXtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLnNheH0sIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLmRvbX0sCi1hbmQge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uc3RyZWFtfS4KLTwvcD4KLQotCi08aDM+Q3JlYXRpbmcgT2JqZWN0czwvaDM+Ci0KLTxwPlRoZSBBUEkgYWxsb3dzIGEgY29uY3JldGUKLXtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRmFjdG9yeX0gb2JqZWN0IHRvIGJlIGNyZWF0ZWQgZnJvbQotdGhlIHN0YXRpYyBmdW5jdGlvbgote0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJGYWN0b3J5I25ld0luc3RhbmNlfS4KLTwvcD4KLQotCi08aDM+U3BlY2lmaWNhdGlvbiBvZiBJbnB1dHMgYW5kIE91dHB1dHM8L2gzPgotCi08cD5UaGlzIEFQSSBkZWZpbmVzIHR3byBpbnRlcmZhY2Ugb2JqZWN0cyBjYWxsZWQKLXtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlNvdXJjZX0gYW5kCi17QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5SZXN1bHR9LiBJbiBvcmRlciB0byBwYXNzIFNvdXJjZSBhbmQgUmVzdWx0Ci1vYmplY3RzIHRvIHRoZSBpbnRlcmZhY2VzLCBjb25jcmV0ZSBjbGFzc2VzIG11c3QgYmUgdXNlZC4KLVRocmVlIGNvbmNyZXRlIHJlcHJlc2VudGF0aW9ucyBhcmUgZGVmaW5lZCBmb3IgZWFjaCBvZiB0aGVzZQotb2JqZWN0czoKLXtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbS5TdHJlYW1Tb3VyY2V9IGFuZAote0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uc3RyZWFtLlN0cmVhbVJlc3VsdH0sCi17QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5zYXguU0FYU291cmNlfSBhbmQKLXtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLnNheC5TQVhSZXN1bHR9LCBhbmQKLXtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLmRvbS5ET01Tb3VyY2V9IGFuZAote0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uZG9tLkRPTVJlc3VsdH0uIEVhY2ggb2YgdGhlc2Ugb2JqZWN0cyBkZWZpbmVzCi1hIEZFQVRVUkUgc3RyaW5nICh3aGljaCBpcyBpIHRoZSBmb3JtIG9mIGEgVVJMKSwgd2hpY2ggY2FuIGJlIHBhc3NlZCBpbnRvCi17QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckZhY3RvcnkjZ2V0RmVhdHVyZX0gdG8gc2VlIGlmIHRoZQotZ2l2ZW4gdHlwZSBvZiBTb3VyY2Ugb3IgUmVzdWx0IG9iamVjdCBpcyBzdXBwb3J0ZWQuIEZvciBpbnN0YW5jZSwgdG8gdGVzdCBpZiBhCi1ET01Tb3VyY2UgYW5kIGEgU3RyZWFtUmVzdWx0IGlzIHN1cHBvcnRlZCwgeW91IGNhbiBhcHBseSB0aGUgZm9sbG93aW5nCi10ZXN0LgotPC9wPgotCi08cHJlPgotPGNvZGU+Ci1UcmFuc2Zvcm1lckZhY3RvcnkgdGZhY3RvcnkgPSBUcmFuc2Zvcm1lckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKLWlmICh0ZmFjdG9yeS5nZXRGZWF0dXJlKERPTVNvdXJjZS5GRUFUVVJFKSAmYW1wOyZhbXA7IHRmYWN0b3J5LmdldEZlYXR1cmUoU3RyZWFtUmVzdWx0LkZFQVRVUkUpKSB7Ci0uLi4KLX0KLTwvY29kZT4KLTwvcHJlPgotCi0KLTxoMz4KLTxhIG5hbWU9InFuYW1lLWRlbGltaXRlciI+UXVhbGlmaWVkIE5hbWUgUmVwcmVzZW50YXRpb248L2E+Ci08L2gzPgotCi08cD48YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMteG1sLW5hbWVzIj5OYW1lc3BhY2VzPC9hPgotcHJlc2VudCBzb21ldGhpbmcgb2YgYSBwcm9ibGVtIGFyZWEgd2hlbiBkZWFsaW5nIHdpdGggWE1MIG9iamVjdHMuIFF1YWxpZmllZAotTmFtZXMgYXBwZWFyIGluIFhNTCBtYXJrdXAgYXMgcHJlZml4ZWQgbmFtZXMuIEJ1dCB0aGUgcHJlZml4ZXMgdGhlbXNlbHZlcyBkbwotbm90IGhvbGQgaWRlbnRpdHkuIFJhdGhlciwgaXQgaXMgdGhlIFVSSXMgdGhhdCB0aGV5IGNvbnRleHR1YWxseSBtYXAgdG8gdGhhdAotaG9sZCB0aGUgaWRlbnRpdHkuIFRoZXJlZm9yZSwgd2hlbiBwYXNzaW5nIGEgUXVhbGlmaWVkIE5hbWUgbGlrZSAieHl6OmZvbyIKLWFtb25nIEphdmEgcHJvZ3JhbXMsIG9uZSBtdXN0IHByb3ZpZGUgYSBtZWFucyB0byBtYXAgInh5eiIgdG8gYSBuYW1lc3BhY2UuCi08L3A+Ci0KLTxwPk9uZSBzb2x1dGlvbiBoYXMgYmVlbiB0byBjcmVhdGUgYSAiUU5hbWUiIG9iamVjdCB0aGF0IGhvbGRzIHRoZQotbmFtZXNwYWNlIFVSSSwgYXMgd2VsbCBhcyB0aGUgcHJlZml4IGFuZCBsb2NhbCBuYW1lLCBidXQgdGhpcyBpcyBub3QgYWx3YXlzIGFuCi1vcHRpbWFsIHNvbHV0aW9uLCBhcyB3aGVuLCBmb3IgZXhhbXBsZSwgeW91IHdhbnQgdG8gdXNlIHVuaXF1ZSBzdHJpbmdzIGFzIGtleXMKLWluIGEgZGljdGlvbmFyeSBvYmplY3QuIE5vdCBoYXZpbmcgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gYWxzbyBtYWtlcyBpdAotZGlmZmljdWx0IHRvIHNwZWNpZnkgYSBuYW1lc3BhY2VkIGlkZW50aXR5IG91dHNpZGUgdGhlIGNvbnRleHQgb2YgYW4gWE1MCi1kb2N1bWVudC4KLTwvcD4KLQotPHA+SW4gb3JkZXIgdG8gcGFzcyBuYW1lc3BhY2VkIHZhbHVlcyB0byB0cmFuc2Zvcm1hdGlvbnMsCi1mb3IgCi1pbnN0YW5jZSB3aGVuIHNldHRpbmcgYSBwcm9wZXJ0eSBvciBhIHBhcmFtZXRlciBvbiBhIAote0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJ9IG9iamVjdCwKLXRoaXMgc3BlY2lmaWNhdGlvbiBkZWZpbmVzIHRoYXQgYQotU3RyaW5nICJxbmFtZSIgb2JqZWN0IHBhcmFtZXRlciBiZSBwYXNzZWQgYXMgdHdvLXBhcnQgc3RyaW5nLCB0aGUgbmFtZXNwYWNlIFVSSQotZW5jbG9zZWQgaW4gY3VybHkgYnJhY2VzICh7fSksIGZvbGxvd2VkIGJ5IHRoZSBsb2NhbCBuYW1lLiBJZiB0aGUgcW5hbWUgaGFzIGEKLW51bGwgVVJJLCB0aGVuIHRoZSBTdHJpbmcgb2JqZWN0IG9ubHkgY29udGFpbnMgdGhlIGxvY2FsIG5hbWUuIEFuIGFwcGxpY2F0aW9uCi1jYW4gc2FmZWx5IGNoZWNrIGZvciBhIG5vbi1udWxsIFVSSSBieSB0ZXN0aW5nIHRvIHNlZSBpZiB0aGUgZmlyc3QgY2hhcmFjdGVyIG9mCi10aGUgbmFtZSBpcyBhICd7JyBjaGFyYWN0ZXIuCi08L3A+Ci0KLTxwPkZvciBleGFtcGxlLCBpZiBhIFVSSSBhbmQgbG9jYWwgbmFtZSB3ZXJlIG9idGFpbmVkIGZyb20gYW4gZWxlbWVudAotZGVmaW5lZCB3aXRoICZsdDt4eXo6Zm9vIHhtbG5zOnh5ej0iaHR0cDovL3h5ei5mb28uY29tL3lhZGEvYmF6Lmh0bWwiLyZndDssCi10aGVuIHRoZSBRdWFsaWZpZWQgTmFtZSB3b3VsZCBiZSAie2h0dHA6Ly94eXouZm9vLmNvbS95YWRhL2Jhei5odG1sfWZvbyIuCi1Ob3RlIHRoYXQgdGhlIHByZWZpeCBpcyBsb3N0LgotPC9wPgotCi0KLTxoMz5SZXN1bHQgVHJlZSBTZXJpYWxpemF0aW9uPC9oMz4KLQotPHA+U2VyaWFsaXphdGlvbiBvZiB0aGUgcmVzdWx0IHRyZWUgdG8gYSBzdHJlYW0gY2FuIGJlIGNvbnRyb2xsZWQgd2l0aAotdGhlIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyI3NldE91dHB1dFByb3BlcnRpZXN9IGFuZCB0aGUKLXtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyI3NldE91dHB1dFByb3BlcnR5fSBtZXRob2RzLgotVGhlc2UgcHJvcGVydGllcyBvbmx5IGFwcGx5IHRvIHN0cmVhbSByZXN1bHRzLCB0aGV5IGhhdmUgbm8gZWZmZWN0IHdoZW4KLXRoZSByZXN1bHQgaXMgYSBET00gdHJlZSBvciBTQVggZXZlbnQgc3RyZWFtLjwvcD4KLQotPHA+U3RyaW5ncyB0aGF0IG1hdGNoIHRoZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I291dHB1dCI+WFNMVAotc3BlY2lmaWNhdGlvbiBmb3IgeHNsOm91dHB1dCBhdHRyaWJ1dGVzPC9hPiBjYW4gYmUgcmVmZXJlbmNlZCBmcm9tIHRoZQote0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uT3V0cHV0S2V5c30gY2xhc3MuIE90aGVyIHN0cmluZ3MgY2FuIGJlCi1zcGVjaWZpZWQgYXMgd2VsbC4KLUlmIHRoZSB0cmFuc2Zvcm1lciBkb2VzIG5vdCByZWNvZ25pemUgYW4gb3V0cHV0IGtleSwgYQote0BsaW5rIGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb259IGlzIHRocm93biwgdW5sZXNzIHRoZQota2V5IG5hbWUgaXMgPGEgaHJlZj0iI3FuYW1lLWRlbGltaXRlciI+bmFtZXNwYWNlIHF1YWxpZmllZDwvYT4uIE91dHB1dCBrZXkgbmFtZXMKLXRoYXQgYXJlIG5hbWVzcGFjZSBxdWFsaWZpZWQgYXJlIGFsd2F5cyBhbGxvd2VkLCBhbHRob3VnaCB0aGV5IG1heSBiZQotaWdub3JlZCBieSBzb21lIGltcGxlbWVudGF0aW9ucy48L3A+Ci0KLTxwPklmIGFsbCB0aGF0IGlzIGRlc2lyZWQgaXMgdGhlIHNpbXBsZSBpZGVudGl0eSB0cmFuc2Zvcm1hdGlvbiBvZiBhCi1zb3VyY2UgdG8gYSByZXN1bHQsIHRoZW4ge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJGYWN0b3J5fQotcHJvdmlkZXMgYQote0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJGYWN0b3J5I25ld1RyYW5zZm9ybWVyKCl9IG1ldGhvZAotd2l0aCBubyBhcmd1bWVudHMuIFRoaXMgbWV0aG9kIGNyZWF0ZXMgYSBUcmFuc2Zvcm1lciB0aGF0IGVmZmVjdGl2ZWx5IGNvcGllcwotdGhlIHNvdXJjZSB0byB0aGUgcmVzdWx0LiBUaGlzIG1ldGhvZCBtYXkgYmUgdXNlZCB0byBjcmVhdGUgYSBET00gZnJvbSBTQVgKLWV2ZW50cyBvciB0byBjcmVhdGUgYW4gWE1MIG9yIEhUTUwgc3RyZWFtIGZyb20gYSBET00gb3IgU0FYIGV2ZW50cy4gIDwvcD4KLQotPGgzPkV4Y2VwdGlvbnMgYW5kIEVycm9yIFJlcG9ydGluZzwvaDM+Ci0KLTxwPlRoZSB0cmFuc2Zvcm1hdGlvbiBBUEkgdGhyb3cgdGhyZWUgdHlwZXMgb2Ygc3BlY2lhbGl6ZWQgZXhjZXB0aW9ucy4gQQote0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yfSBpcyBwYXJhbGxlbCB0bwotdGhlIHtAbGluayBqYXZheC54bWwucGFyc2Vycy5GYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yfSwgYW5kIGlzIHRocm93bgotd2hlbiBhIGNvbmZpZ3VyYXRpb24gcHJvYmxlbSB3aXRoIHRoZSBUcmFuc2Zvcm1lckZhY3RvcnkgZXhpc3RzLiBUaGlzIGVycm9yCi13aWxsIHR5cGljYWxseSBiZSB0aHJvd24gd2hlbiB0aGUgdHJhbnNmb3JtYXRpb24gZmFjdG9yeSBjbGFzcyBzcGVjaWZpZWQgd2l0aAotdGhlICJqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRmFjdG9yeSIgc3lzdGVtIHByb3BlcnR5IGNhbm5vdCBiZSBmb3VuZCBvcgotaW5zdGFudGlhdGVkLjwvcD4KLQotPHA+QSB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb259Ci1tYXkgYmUgdGhyb3duIGlmIGZvciBhbnkgcmVhc29uIGEgVHJhbnNmb3JtZXIgY2FuIG5vdCBiZSBjcmVhdGVkLiBBCi1UcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gbWF5IGJlIHRocm93biBpZiB0aGVyZSBpcyBhIHN5bnRheCBlcnJvciBpbgotdGhlIHRyYW5zZm9ybWF0aW9uIGluc3RydWN0aW9ucywgZm9yIGV4YW1wbGUgd2hlbgote0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJGYWN0b3J5I25ld1RyYW5zZm9ybWVyfSBpcwotY2FsbGVkLjwvcD4KLQotPHA+e0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb259IGlzIGEgZ2VuZXJhbAotZXhjZXB0aW9uIHRoYXQgb2NjdXJzIGR1cmluZyB0aGUgY291cnNlIG9mIGEgdHJhbnNmb3JtYXRpb24uIEEgdHJhbnNmb3JtZXIKLWV4Y2VwdGlvbiBtYXkgd3JhcCBhbm90aGVyIGV4Y2VwdGlvbiwgYW5kIGlmIGFueSBvZiB0aGUKLXtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uI3ByaW50U3RhY2tUcmFjZSgpfQotbWV0aG9kcyBhcmUgY2FsbGVkIG9uIGl0LCBpdCB3aWxsIHByb2R1Y2UgYSBsaXN0IG9mIHN0YWNrIGR1bXBzLCBzdGFydGluZyBmcm9tCi10aGUgbW9zdCByZWNlbnQuIFRoZSB0cmFuc2Zvcm1lciBleGNlcHRpb24gYWxzbyBwcm92aWRlcyBhCi17QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2VMb2NhdG9yfSBvYmplY3Qgd2hpY2ggaW5kaWNhdGVzIHdoZXJlCi1pbiB0aGUgc291cmNlIHRyZWUgb3IgdHJhbnNmb3JtYXRpb24gaW5zdHJ1Y3Rpb25zIHRoZSBlcnJvciBvY2N1cnJlZC4KLXtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uI2dldE1lc3NhZ2VBbmRMb2NhdGlvbigpfQotbWF5IGJlIGNhbGxlZCB0byBnZXQgYW4gZXJyb3IgbWVzc2FnZSB3aXRoIGxvY2F0aW9uIGluZm8sIGFuZAote0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24jZ2V0TG9jYXRpb25Bc1N0cmluZygpfQotbWF5IGJlIGNhbGxlZCB0byBnZXQganVzdCB0aGUgbG9jYXRpb24gc3RyaW5nLjwvcD4KLQotPHA+VHJhbnNmb3JtYXRpb24gd2FybmluZ3MgYW5kIGVycm9ycyBhcmUgc2VudCB0byBhbgote0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uRXJyb3JMaXN0ZW5lcn0sIGF0IHdoaWNoIHBvaW50IHRoZQotYXBwbGljYXRpb24gbWF5IGRlY2lkZSB0byByZXBvcnQgdGhlIGVycm9yIG9yIHdhcm5pbmcsIGFuZCBtYXkgZGVjaWRlIHRvIHRocm93Ci1hbiA8Y29kZT5FeGNlcHRpb248L2NvZGU+IGZvciBhIG5vbi1mYXRhbCBlcnJvci4gVGhlIDxjb2RlPkVycm9yTGlzdGVuZXI8L2NvZGU+IG1heSBiZSBzZXQgdmlhCi17QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckZhY3Rvcnkjc2V0RXJyb3JMaXN0ZW5lcn0gZm9yCi1yZXBvcnRpbmcgZXJyb3JzIHRoYXQgaGF2ZSB0byBkbyB3aXRoIHN5bnRheCBlcnJvcnMgaW4gdGhlIHRyYW5zZm9ybWF0aW9uCi1pbnN0cnVjdGlvbnMsIG9yIHZpYQote0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXIjc2V0RXJyb3JMaXN0ZW5lcn0gdG8gcmVwb3J0Ci1lcnJvcnMgdGhhdCBvY2N1ciBkdXJpbmcgdGhlIHRyYW5zZm9ybWF0aW9uLiBUaGUgPGNvZGU+RXJyb3JMaXN0ZW5lcjwvY29kZT4gb24gYm90aCBvYmplY3RzCi13aWxsIGFsd2F5cyBiZSB2YWxpZCBhbmQgbm9uLTxjb2RlPm51bGw8L2NvZGU+LCB3aGV0aGVyIHNldCBieSB0aGUgYXBwbGljYXRpb24gb3IgYSBkZWZhdWx0Ci1pbXBsZW1lbnRhdGlvbiBwcm92aWRlZCBieSB0aGUgcHJvY2Vzc29yLgotVGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gcHJvdmlkZWQgYnkgdGhlIHByb2Nlc3NvciB3aWxsIHJlcG9ydCBhbGwgd2FybmluZ3MgYW5kIGVycm9ycyB0byA8Y29kZT5TeXN0ZW0uZXJyPC9jb2RlPgotYW5kIGRvZXMgbm90IHRocm93IGFueSA8Y29kZT5FeGNlcHRpb248L2NvZGU+cy4KLUFwcGxpY2F0aW9ucyBhcmUgPGVtPnN0cm9uZ2x5PC9lbT4gZW5jb3VyYWdlZCB0byByZWdpc3RlciBhbmQgdXNlCi08Y29kZT5FcnJvckxpc3RlbmVyPC9jb2RlPnMgdGhhdCBpbnN1cmUgcHJvcGVyIGJlaGF2aW9yIGZvciB3YXJuaW5ncyBhbmQKLWVycm9ycy4KLTwvcD4KLQotCi08aDM+UmVzb2x1dGlvbiBvZiBVUklzIHdpdGhpbiBhIHRyYW5zZm9ybWF0aW9uPC9oMz4KLQotPHA+VGhlIEFQSSBwcm92aWRlcyBhIHdheSBmb3IgVVJJcyByZWZlcmVuY2VkIGZyb20gd2l0aGluIHRoZSBzdHlsZXNoZWV0Ci1pbnN0cnVjdGlvbnMgb3Igd2l0aGluIHRoZSB0cmFuc2Zvcm1hdGlvbiB0byBiZSByZXNvbHZlZCBieSB0aGUgY2FsbGluZwotYXBwbGljYXRpb24uIFRoaXMgY2FuIGJlIGRvbmUgYnkgY3JlYXRpbmcgYSBjbGFzcyB0aGF0IGltcGxlbWVudHMgdGhlCi17QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5VUklSZXNvbHZlcn0gaW50ZXJmYWNlLCB3aXRoIGl0cyBvbmUgbWV0aG9kLAote0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uVVJJUmVzb2x2ZXIjcmVzb2x2ZX0sIGFuZCB1c2UgdGhpcyBjbGFzcyB0bwotc2V0IHRoZSBVUkkgcmVzb2x1dGlvbiBmb3IgdGhlIHRyYW5zZm9ybWF0aW9uIGluc3RydWN0aW9ucyBvciB0cmFuc2Zvcm1hdGlvbgotd2l0aCB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckZhY3Rvcnkjc2V0VVJJUmVzb2x2ZXJ9IG9yCi17QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lciNzZXRVUklSZXNvbHZlcn0uIFRoZQotPGNvZGU+VVJJUmVzb2x2ZXIucmVzb2x2ZTwvY29kZT4gbWV0aG9kIHRha2VzIHR3byBTdHJpbmcgYXJndW1lbnRzLCB0aGUgVVJJIGZvdW5kIGluIHRoZQotc3R5bGVzaGVldCBpbnN0cnVjdGlvbnMgb3IgYnVpbHQgYXMgcGFydCBvZiB0aGUgdHJhbnNmb3JtYXRpb24gcHJvY2VzcywgYW5kIHRoZQotYmFzZSBVUkkgCi1hZ2FpbnN0IHdoaWNoIHRoZSBmaXJzdCBhcmd1bWVudCB3aWxsIGJlIG1hZGUgYWJzb2x1dGUgaWYgdGhlCi1hYnNvbHV0ZSBVUkkgaXMgcmVxdWlyZWQuCi1UaGUgcmV0dXJuZWQge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uU291cmNlfSBvYmplY3QgbXVzdCBiZSB1c2FibGUgYnkKLXRoZSB0cmFuc2Zvcm1lciwgYXMgc3BlY2lmaWVkIGluIGl0cyBpbXBsZW1lbnRlZCBmZWF0dXJlcy48L3A+Ci0KLQotPC9ib2R5PgotPC9odG1sPgpkaWZmIC0tZ2l0IGEvc3JjL2phdmF4L3htbC90cmFuc2Zvcm0vc2F4L1NBWFJlc3VsdC5qYXZhIGIvc3JjL2phdmF4L3htbC90cmFuc2Zvcm0vc2F4L1NBWFJlc3VsdC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiMDE1OGIzLi4wMDAwMDAwCi0tLSBhL3NyYy9qYXZheC94bWwvdHJhbnNmb3JtL3NheC9TQVhSZXN1bHQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE0NCArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDAwLCAyMDA1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi1wYWNrYWdlIGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4OwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5SZXN1bHQ7Ci0KLWltcG9ydCBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXI7Ci0KLS8qKgotICogPHA+QWN0cyBhcyBhbiBob2xkZXIgZm9yIGEgdHJhbnNmb3JtYXRpb24gUmVzdWx0LjwvcD4KLSAqCi0gKiBAYXV0aG9yIDxhIGhyZWY9IkplZmYuU3V0dG9yQFN1bi5jb20iPkplZmYgU3V0dG9yPC9hPgotICovCi1wdWJsaWMgY2xhc3MgU0FYUmVzdWx0IGltcGxlbWVudHMgUmVzdWx0IHsKLQotICAgIC8qKgotICAgICAqIElmIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRmFjdG9yeSNnZXRGZWF0dXJlfQotICAgICAqIHJldHVybnMgdHJ1ZSB3aGVuIHBhc3NlZCB0aGlzIHZhbHVlIGFzIGFuIGFyZ3VtZW50LAotICAgICAqIHRoZSBUcmFuc2Zvcm1lciBzdXBwb3J0cyBSZXN1bHQgb3V0cHV0IG9mIHRoaXMgdHlwZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBGRUFUVVJFID0KLSAgICAgICAgImh0dHA6Ly9qYXZheC54bWwudHJhbnNmb3JtLnNheC5TQVhSZXN1bHQvZmVhdHVyZSI7Ci0KLSAgICAvKioKLSAgICAgKiBaZXJvLWFyZ3VtZW50IGRlZmF1bHQgY29uc3RydWN0b3IuCi0gICAgICovCi0gICAgcHVibGljIFNBWFJlc3VsdCgpIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGUgYSBTQVhSZXN1bHQgdGhhdCB0YXJnZXRzIGEgU0FYMiB7QGxpbmsgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXJ9LgotICAgICAqCi0gICAgICogQHBhcmFtIGhhbmRsZXIgTXVzdCBiZSBhIG5vbi1udWxsIENvbnRlbnRIYW5kbGVyIHJlZmVyZW5jZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgU0FYUmVzdWx0KENvbnRlbnRIYW5kbGVyIGhhbmRsZXIpIHsKLSAgICAgICAgc2V0SGFuZGxlcihoYW5kbGVyKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIHRhcmdldCB0byBiZSBhIFNBWDIge0BsaW5rIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyfS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBoYW5kbGVyIE11c3QgYmUgYSBub24tbnVsbCBDb250ZW50SGFuZGxlciByZWZlcmVuY2UuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0SGFuZGxlcihDb250ZW50SGFuZGxlciBoYW5kbGVyKSB7Ci0gICAgICAgIHRoaXMuaGFuZGxlciA9IGhhbmRsZXI7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSB7QGxpbmsgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXJ9IHRoYXQgaXMgdGhlIFJlc3VsdC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIENvbnRlbnRIYW5kbGVyIHRoYXQgaXMgdG8gYmUgdHJhbnNmb3JtYXRpb24gb3V0cHV0LgotICAgICAqLwotICAgIHB1YmxpYyBDb250ZW50SGFuZGxlciBnZXRIYW5kbGVyKCkgewotICAgICAgICByZXR1cm4gaGFuZGxlcjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIFNBWDIge0BsaW5rIG9yZy54bWwuc2F4LmV4dC5MZXhpY2FsSGFuZGxlcn0gZm9yIHRoZSBvdXRwdXQuCi0gICAgICoKLSAgICAgKiA8cD5UaGlzIGlzIG5lZWRlZCB0byBoYW5kbGUgWE1MIGNvbW1lbnRzIGFuZCB0aGUgbGlrZS4gIElmIHRoZQotICAgICAqIGxleGljYWwgaGFuZGxlciBpcyBub3Qgc2V0LCBhbiBhdHRlbXB0IHNob3VsZCBiZSBtYWRlIGJ5IHRoZQotICAgICAqIHRyYW5zZm9ybWVyIHRvIGNhc3QgdGhlIHtAbGluayBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcn0gdG8gYQotICAgICAqIDxjb2RlPkxleGljYWxIYW5kbGVyPC9jb2RlPi48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gaGFuZGxlciBBIG5vbi1udWxsIDxjb2RlPkxleGljYWxIYW5kbGVyPC9jb2RlPiBmb3IKLSAgICAgKiBoYW5kbGluZyBsZXhpY2FsIHBhcnNlIGV2ZW50cy4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRMZXhpY2FsSGFuZGxlcihMZXhpY2FsSGFuZGxlciBoYW5kbGVyKSB7Ci0gICAgICAgIHRoaXMubGV4aGFuZGxlciA9IGhhbmRsZXI7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IGEgU0FYMiB7QGxpbmsgb3JnLnhtbC5zYXguZXh0LkxleGljYWxIYW5kbGVyfSBmb3IgdGhlIG91dHB1dC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gQSA8Y29kZT5MZXhpY2FsSGFuZGxlcjwvY29kZT4sIG9yIG51bGwuCi0gICAgICovCi0gICAgcHVibGljIExleGljYWxIYW5kbGVyIGdldExleGljYWxIYW5kbGVyKCkgewotICAgICAgICByZXR1cm4gbGV4aGFuZGxlcjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBNZXRob2Qgc2V0U3lzdGVtSWQgU2V0IHRoZSBzeXN0ZW1JRCB0aGF0IG1heSBiZSB1c2VkIGluIGFzc29jaWF0aW9uCi0gICAgICogd2l0aCB0aGUge0BsaW5rIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyfS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzeXN0ZW1JZCBUaGUgc3lzdGVtIGlkZW50aWZpZXIgYXMgYSBVUkkgc3RyaW5nLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFN5c3RlbUlkKFN0cmluZyBzeXN0ZW1JZCkgewotICAgICAgICB0aGlzLnN5c3RlbUlkID0gc3lzdGVtSWQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBzeXN0ZW0gaWRlbnRpZmllciB0aGF0IHdhcyBzZXQgd2l0aCBzZXRTeXN0ZW1JZC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIHN5c3RlbSBpZGVudGlmaWVyIHRoYXQgd2FzIHNldCB3aXRoIHNldFN5c3RlbUlkLCBvciBudWxsCi0gICAgICogaWYgc2V0U3lzdGVtSWQgd2FzIG5vdCBjYWxsZWQuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRTeXN0ZW1JZCgpIHsKLSAgICAgICAgcmV0dXJuIHN5c3RlbUlkOwotICAgIH0KLQotICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLSAgICAvLyBJbnRlcm5hbCBzdGF0ZS4KLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0KLSAgICAvKioKLSAgICAgKiBUaGUgaGFuZGxlciBmb3IgcGFyc2UgZXZlbnRzLgotICAgICAqLwotICAgIHByaXZhdGUgQ29udGVudEhhbmRsZXIgaGFuZGxlcjsKLQotICAgIC8qKgotICAgICAqIFRoZSBoYW5kbGVyIGZvciBsZXhpY2FsIGV2ZW50cy4KLSAgICAgKi8KLSAgICBwcml2YXRlIExleGljYWxIYW5kbGVyIGxleGhhbmRsZXI7Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgc3lzdGVtSUQgdGhhdCBtYXkgYmUgdXNlZCBpbiBhc3NvY2lhdGlvbgotICAgICAqIHdpdGggdGhlIG5vZGUuCi0gICAgICovCi0gICAgcHJpdmF0ZSBTdHJpbmcgc3lzdGVtSWQ7Ci19CmRpZmYgLS1naXQgYS9zcmMvamF2YXgveG1sL3RyYW5zZm9ybS9zYXgvU0FYU291cmNlLmphdmEgYi9zcmMvamF2YXgveG1sL3RyYW5zZm9ybS9zYXgvU0FYU291cmNlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDUyMzE1NjQuLjAwMDAwMDAKLS0tIGEvc3JjL2phdmF4L3htbC90cmFuc2Zvcm0vc2F4L1NBWFNvdXJjZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjA5ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDAsIDIwMDYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLXBhY2thZ2UgamF2YXgueG1sLnRyYW5zZm9ybS5zYXg7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlNvdXJjZTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbS5TdHJlYW1Tb3VyY2U7Ci0KLWltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKLWltcG9ydCBvcmcueG1sLnNheC5YTUxSZWFkZXI7Ci0KLS8qKgotICogPHA+QWN0cyBhcyBhbiBob2xkZXIgZm9yIFNBWC1zdHlsZSBTb3VyY2UuPC9wPgotICoKLSAqIDxwPk5vdGUgdGhhdCBYU0xUIHJlcXVpcmVzIG5hbWVzcGFjZSBzdXBwb3J0LiBBdHRlbXB0aW5nIHRvIHRyYW5zZm9ybSBhbgotICogaW5wdXQgc291cmNlIHRoYXQgaXMgbm90Ci0gKiBnZW5lcmF0ZWQgd2l0aCBhIG5hbWVzcGFjZS1hd2FyZSBwYXJzZXIgbWF5IHJlc3VsdCBpbiBlcnJvcnMuCi0gKiBQYXJzZXJzIGNhbiBiZSBtYWRlIG5hbWVzcGFjZSBhd2FyZSBieSBjYWxsaW5nIHRoZQotICoge0BsaW5rIGphdmF4LnhtbC5wYXJzZXJzLlNBWFBhcnNlckZhY3Rvcnkjc2V0TmFtZXNwYWNlQXdhcmUoYm9vbGVhbiBhd2FyZW5lc3MpfSBtZXRob2QuPC9wPgotICoKLSAqIEBhdXRob3IgPGEgaHJlZj0ibWFpbHRvOkplZmYuU3V0dG9yQFN1bi5jb20iPkplZmYgU3V0dG9yPC9hPgotICovCi1wdWJsaWMgY2xhc3MgU0FYU291cmNlIGltcGxlbWVudHMgU291cmNlIHsKLQotICAgIC8qKgotICAgICAqIElmIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRmFjdG9yeSNnZXRGZWF0dXJlfQotICAgICAqIHJldHVybnMgdHJ1ZSB3aGVuIHBhc3NlZCB0aGlzIHZhbHVlIGFzIGFuIGFyZ3VtZW50LAotICAgICAqIHRoZSBUcmFuc2Zvcm1lciBzdXBwb3J0cyBTb3VyY2UgaW5wdXQgb2YgdGhpcyB0eXBlLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEZFQVRVUkUgPQotICAgICAgICAiaHR0cDovL2phdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlNBWFNvdXJjZS9mZWF0dXJlIjsKLQotICAgIC8qKgotICAgICAqIDxwPlplcm8tYXJndW1lbnQgZGVmYXVsdCBjb25zdHJ1Y3Rvci4gIElmIHRoaXMgY29uc3RydWN0b3IgaXMgdXNlZCwgYW5kCi0gICAgICogbm8gU0FYIHNvdXJjZSBpcyBzZXQgdXNpbmcKLSAgICAgKiB7QGxpbmsgI3NldElucHV0U291cmNlKElucHV0U291cmNlIGlucHV0U291cmNlKX0gLCB0aGVuIHRoZQotICAgICAqIDxjb2RlPlRyYW5zZm9ybWVyPC9jb2RlPiB3aWxsCi0gICAgICogY3JlYXRlIGFuIGVtcHR5IHNvdXJjZSB7QGxpbmsgb3JnLnhtbC5zYXguSW5wdXRTb3VyY2V9IHVzaW5nCi0gICAgICoge0BsaW5rIG9yZy54bWwuc2F4LklucHV0U291cmNlI0lucHV0U291cmNlKCkgbmV3IElucHV0U291cmNlKCl9LjwvcD4KLSAgICAgKgotICAgICAqIEBzZWUgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lciN0cmFuc2Zvcm0oU291cmNlIHhtbFNvdXJjZSwgUmVzdWx0IG91dHB1dFRhcmdldCkKLSAgICAgKi8KLSAgICBwdWJsaWMgU0FYU291cmNlKCkgeyB9Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGUgYSA8Y29kZT5TQVhTb3VyY2U8L2NvZGU+LCB1c2luZyBhbiB7QGxpbmsgb3JnLnhtbC5zYXguWE1MUmVhZGVyfQotICAgICAqIGFuZCBhIFNBWCBJbnB1dFNvdXJjZS4gVGhlIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyfQotICAgICAqIG9yIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLnNheC5TQVhUcmFuc2Zvcm1lckZhY3Rvcnl9IHdpbGwgc2V0IGl0c2VsZgotICAgICAqIHRvIGJlIHRoZSByZWFkZXIncyB7QGxpbmsgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXJ9LCBhbmQgdGhlbiB3aWxsIGNhbGwKLSAgICAgKiByZWFkZXIucGFyc2UoaW5wdXRTb3VyY2UpLgotICAgICAqCi0gICAgICogQHBhcmFtIHJlYWRlciBBbiBYTUxSZWFkZXIgdG8gYmUgdXNlZCBmb3IgdGhlIHBhcnNlLgotICAgICAqIEBwYXJhbSBpbnB1dFNvdXJjZSBBIFNBWCBpbnB1dCBzb3VyY2UgcmVmZXJlbmNlIHRoYXQgbXVzdCBiZSBub24tbnVsbAotICAgICAqIGFuZCB0aGF0IHdpbGwgYmUgcGFzc2VkIHRvIHRoZSByZWFkZXIgcGFyc2UgbWV0aG9kLgotICAgICAqLwotICAgIHB1YmxpYyBTQVhTb3VyY2UoWE1MUmVhZGVyIHJlYWRlciwgSW5wdXRTb3VyY2UgaW5wdXRTb3VyY2UpIHsKLSAgICAgICAgdGhpcy5yZWFkZXIgICAgICA9IHJlYWRlcjsKLSAgICAgICAgdGhpcy5pbnB1dFNvdXJjZSA9IGlucHV0U291cmNlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENyZWF0ZSBhIDxjb2RlPlNBWFNvdXJjZTwvY29kZT4sIHVzaW5nIGEgU0FYIDxjb2RlPklucHV0U291cmNlPC9jb2RlPi4KLSAgICAgKiBUaGUge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJ9IG9yCi0gICAgICoge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlNBWFRyYW5zZm9ybWVyRmFjdG9yeX0gY3JlYXRlcyBhCi0gICAgICogcmVhZGVyIHZpYSB7QGxpbmsgb3JnLnhtbC5zYXguaGVscGVycy5YTUxSZWFkZXJGYWN0b3J5fQotICAgICAqIChpZiBzZXRYTUxSZWFkZXIgaXMgbm90IHVzZWQpLCBzZXRzIGl0c2VsZiBhcwotICAgICAqIHRoZSByZWFkZXIncyB7QGxpbmsgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXJ9LCBhbmQgY2FsbHMKLSAgICAgKiByZWFkZXIucGFyc2UoaW5wdXRTb3VyY2UpLgotICAgICAqCi0gICAgICogQHBhcmFtIGlucHV0U291cmNlIEFuIGlucHV0IHNvdXJjZSByZWZlcmVuY2UgdGhhdCBtdXN0IGJlIG5vbi1udWxsCi0gICAgICogYW5kIHRoYXQgd2lsbCBiZSBwYXNzZWQgdG8gdGhlIHBhcnNlIG1ldGhvZCBvZiB0aGUgcmVhZGVyLgotICAgICAqLwotICAgIHB1YmxpYyBTQVhTb3VyY2UoSW5wdXRTb3VyY2UgaW5wdXRTb3VyY2UpIHsKLSAgICAgICAgdGhpcy5pbnB1dFNvdXJjZSA9IGlucHV0U291cmNlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldCB0aGUgWE1MUmVhZGVyIHRvIGJlIHVzZWQgZm9yIHRoZSBTb3VyY2UuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcmVhZGVyIEEgdmFsaWQgWE1MUmVhZGVyIG9yIFhNTEZpbHRlciByZWZlcmVuY2UuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0WE1MUmVhZGVyKFhNTFJlYWRlciByZWFkZXIpIHsKLSAgICAgICAgdGhpcy5yZWFkZXIgPSByZWFkZXI7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBYTUxSZWFkZXIgdG8gYmUgdXNlZCBmb3IgdGhlIFNvdXJjZS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gQSB2YWxpZCBYTUxSZWFkZXIgb3IgWE1MRmlsdGVyIHJlZmVyZW5jZSwgb3IgbnVsbC4KLSAgICAgKi8KLSAgICBwdWJsaWMgWE1MUmVhZGVyIGdldFhNTFJlYWRlcigpIHsKLSAgICAgICAgcmV0dXJuIHJlYWRlcjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIFNBWCBJbnB1dFNvdXJjZSB0byBiZSB1c2VkIGZvciB0aGUgU291cmNlLgotICAgICAqCi0gICAgICogQHBhcmFtIGlucHV0U291cmNlIEEgdmFsaWQgSW5wdXRTb3VyY2UgcmVmZXJlbmNlLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldElucHV0U291cmNlKElucHV0U291cmNlIGlucHV0U291cmNlKSB7Ci0gICAgICAgIHRoaXMuaW5wdXRTb3VyY2UgPSBpbnB1dFNvdXJjZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIFNBWCBJbnB1dFNvdXJjZSB0byBiZSB1c2VkIGZvciB0aGUgU291cmNlLgotICAgICAqCi0gICAgICogQHJldHVybiBBIHZhbGlkIElucHV0U291cmNlIHJlZmVyZW5jZSwgb3IgbnVsbC4KLSAgICAgKi8KLSAgICBwdWJsaWMgSW5wdXRTb3VyY2UgZ2V0SW5wdXRTb3VyY2UoKSB7Ci0gICAgICAgIHJldHVybiBpbnB1dFNvdXJjZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIHN5c3RlbSBpZGVudGlmaWVyIGZvciB0aGlzIFNvdXJjZS4gIElmIGFuIGlucHV0IHNvdXJjZQotICAgICAqIGhhcyBhbHJlYWR5IGJlZW4gc2V0LCBpdCB3aWxsIHNldCB0aGUgc3lzdGVtIElEIG9yIHRoYXQKLSAgICAgKiBpbnB1dCBzb3VyY2UsIG90aGVyd2lzZSBpdCB3aWxsIGNyZWF0ZSBhIG5ldyBpbnB1dCBzb3VyY2UuCi0gICAgICoKLSAgICAgKiA8cD5UaGUgc3lzdGVtIGlkZW50aWZpZXIgaXMgb3B0aW9uYWwgaWYgdGhlcmUgaXMgYSBieXRlIHN0cmVhbQotICAgICAqIG9yIGEgY2hhcmFjdGVyIHN0cmVhbSwgYnV0IGl0IGlzIHN0aWxsIHVzZWZ1bCB0byBwcm92aWRlIG9uZSwKLSAgICAgKiBzaW5jZSB0aGUgYXBwbGljYXRpb24gY2FuIHVzZSBpdCB0byByZXNvbHZlIHJlbGF0aXZlIFVSSXMKLSAgICAgKiBhbmQgY2FuIGluY2x1ZGUgaXQgaW4gZXJyb3IgbWVzc2FnZXMgYW5kIHdhcm5pbmdzICh0aGUgcGFyc2VyCi0gICAgICogd2lsbCBhdHRlbXB0IHRvIG9wZW4gYSBjb25uZWN0aW9uIHRvIHRoZSBVUkkgb25seSBpZgotICAgICAqIG5vIGJ5dGUgc3RyZWFtIG9yIGNoYXJhY3RlciBzdHJlYW0gaXMgc3BlY2lmaWVkKS48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gc3lzdGVtSWQgVGhlIHN5c3RlbSBpZGVudGlmaWVyIGFzIGEgVVJJIHN0cmluZy4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRTeXN0ZW1JZChTdHJpbmcgc3lzdGVtSWQpIHsKLQotICAgICAgICBpZiAobnVsbCA9PSBpbnB1dFNvdXJjZSkgewotICAgICAgICAgICAgaW5wdXRTb3VyY2UgPSBuZXcgSW5wdXRTb3VyY2Uoc3lzdGVtSWQpOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgaW5wdXRTb3VyY2Uuc2V0U3lzdGVtSWQoc3lzdGVtSWQpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+R2V0IHRoZSBiYXNlIElEIChVUkkgb3Igc3lzdGVtIElEKSBmcm9tIHdoZXJlIFVSSXMKLSAgICAgKiB3aWxsIGJlIHJlc29sdmVkLjwvcD4KLSAgICAgKgotICAgICAqIEByZXR1cm4gQmFzZSBVUkwgZm9yIHRoZSA8Y29kZT5Tb3VyY2U8L2NvZGU+LCBvciA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFN5c3RlbUlkKCkgewotCi0gICAgICAgIGlmIChpbnB1dFNvdXJjZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiBpbnB1dFNvdXJjZS5nZXRTeXN0ZW1JZCgpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhlIFhNTFJlYWRlciB0byBiZSB1c2VkIGZvciB0aGUgc291cmNlIHRyZWUgaW5wdXQuIE1heSBiZSBudWxsLgotICAgICAqLwotICAgIHByaXZhdGUgWE1MUmVhZGVyIHJlYWRlcjsKLQotICAgIC8qKgotICAgICAqIDxwPlRoZSBTQVggSW5wdXRTb3VyY2UgdG8gYmUgdXNlZCBmb3IgdGhlIHNvdXJjZSB0cmVlIGlucHV0LgotICAgICAqIFNob3VsZCBub3QgYmUgPGNvZGU+bnVsbDwvY29kZT4uPC9wPgotICAgICAqLwotICAgIHByaXZhdGUgSW5wdXRTb3VyY2UgaW5wdXRTb3VyY2U7Ci0KLSAgICAvKioKLSAgICAgKiBBdHRlbXB0IHRvIG9idGFpbiBhIFNBWCBJbnB1dFNvdXJjZSBvYmplY3QgZnJvbSBhIFNvdXJjZQotICAgICAqIG9iamVjdC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzb3VyY2UgTXVzdCBiZSBhIG5vbi1udWxsIFNvdXJjZSByZWZlcmVuY2UuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIEFuIElucHV0U291cmNlLCBvciBudWxsIGlmIFNvdXJjZSBjYW4gbm90IGJlIGNvbnZlcnRlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIElucHV0U291cmNlIHNvdXJjZVRvSW5wdXRTb3VyY2UoU291cmNlIHNvdXJjZSkgewotCi0gICAgICAgIGlmIChzb3VyY2UgaW5zdGFuY2VvZiBTQVhTb3VyY2UpIHsKLSAgICAgICAgICAgIHJldHVybiAoKFNBWFNvdXJjZSkgc291cmNlKS5nZXRJbnB1dFNvdXJjZSgpOwotICAgICAgICB9IGVsc2UgaWYgKHNvdXJjZSBpbnN0YW5jZW9mIFN0cmVhbVNvdXJjZSkgewotICAgICAgICAgICAgU3RyZWFtU291cmNlIHNzICAgICAgPSAoU3RyZWFtU291cmNlKSBzb3VyY2U7Ci0gICAgICAgICAgICBJbnB1dFNvdXJjZSAgaXNvdXJjZSA9IG5ldyBJbnB1dFNvdXJjZShzcy5nZXRTeXN0ZW1JZCgpKTsKLQotICAgICAgICAgICAgaXNvdXJjZS5zZXRCeXRlU3RyZWFtKHNzLmdldElucHV0U3RyZWFtKCkpOwotICAgICAgICAgICAgaXNvdXJjZS5zZXRDaGFyYWN0ZXJTdHJlYW0oc3MuZ2V0UmVhZGVyKCkpOwotICAgICAgICAgICAgaXNvdXJjZS5zZXRQdWJsaWNJZChzcy5nZXRQdWJsaWNJZCgpKTsKLQotICAgICAgICAgICAgcmV0dXJuIGlzb3VyY2U7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9qYXZheC94bWwvdHJhbnNmb3JtL3NheC9TQVhUcmFuc2Zvcm1lckZhY3RvcnkuamF2YSBiL3NyYy9qYXZheC94bWwvdHJhbnNmb3JtL3NheC9TQVhUcmFuc2Zvcm1lckZhY3RvcnkuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNzc3ZTBiZi4uMDAwMDAwMAotLS0gYS9zcmMvamF2YXgveG1sL3RyYW5zZm9ybS9zYXgvU0FYVHJhbnNmb3JtZXJGYWN0b3J5LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNTAgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwMCwgMjAwNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotcGFja2FnZSBqYXZheC54bWwudHJhbnNmb3JtLnNheDsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uKjsKLQotaW1wb3J0IG9yZy54bWwuc2F4LlhNTEZpbHRlcjsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGV4dGVuZHMgVHJhbnNmb3JtZXJGYWN0b3J5IHRvIHByb3ZpZGUgU0FYLXNwZWNpZmljCi0gKiBmYWN0b3J5IG1ldGhvZHMuICBJdCBwcm92aWRlcyB0d28gdHlwZXMgb2YgQ29udGVudEhhbmRsZXJzLAotICogb25lIGZvciBjcmVhdGluZyBUcmFuc2Zvcm1lcnMsIHRoZSBvdGhlciBmb3IgY3JlYXRpbmcgVGVtcGxhdGVzCi0gKiBvYmplY3RzLgotICoKLSAqIDxwPklmIGFuIGFwcGxpY2F0aW9uIHdhbnRzIHRvIHNldCB0aGUgRXJyb3JIYW5kbGVyIG9yIEVudGl0eVJlc29sdmVyCi0gKiBmb3IgYW4gWE1MUmVhZGVyIHVzZWQgZHVyaW5nIGEgdHJhbnNmb3JtYXRpb24sIGl0IHNob3VsZCB1c2UgYSBVUklSZXNvbHZlcgotICogdG8gcmV0dXJuIHRoZSBTQVhTb3VyY2Ugd2hpY2ggcHJvdmlkZXMgKHdpdGggZ2V0WE1MUmVhZGVyKSBhIHJlZmVyZW5jZSB0bwotICogdGhlIFhNTFJlYWRlci48L3A+Ci0gKi8KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBTQVhUcmFuc2Zvcm1lckZhY3RvcnkgZXh0ZW5kcyBUcmFuc2Zvcm1lckZhY3RvcnkgewotCi0gICAgLyoqIElmIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRmFjdG9yeSNnZXRGZWF0dXJlfQotICAgICAqIHJldHVybnMgdHJ1ZSB3aGVuIHBhc3NlZCB0aGlzIHZhbHVlIGFzIGFuIGFyZ3VtZW50LAotICAgICAqIHRoZSBUcmFuc2Zvcm1lckZhY3RvcnkgcmV0dXJuZWQgZnJvbQotICAgICAqIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRmFjdG9yeSNuZXdJbnN0YW5jZX0gbWF5Ci0gICAgICogYmUgc2FmZWx5IGNhc3QgdG8gYSBTQVhUcmFuc2Zvcm1lckZhY3RvcnkuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRkVBVFVSRSA9Ci0gICAgICAgICJodHRwOi8vamF2YXgueG1sLnRyYW5zZm9ybS5zYXguU0FYVHJhbnNmb3JtZXJGYWN0b3J5L2ZlYXR1cmUiOwotCi0gICAgLyoqIElmIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRmFjdG9yeSNnZXRGZWF0dXJlfQotICAgICAqIHJldHVybnMgdHJ1ZSB3aGVuIHBhc3NlZCB0aGlzIHZhbHVlIGFzIGFuIGFyZ3VtZW50LAotICAgICAqIHRoZSB7QGxpbmsgI25ld1hNTEZpbHRlcihTb3VyY2Ugc3JjKX0KLSAgICAgKiBhbmQge0BsaW5rICNuZXdYTUxGaWx0ZXIoVGVtcGxhdGVzIHRlbXBsYXRlcyl9IG1ldGhvZHMgYXJlIHN1cHBvcnRlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBGRUFUVVJFX1hNTEZJTFRFUiA9Ci0gICAgICAgICJodHRwOi8vamF2YXgueG1sLnRyYW5zZm9ybS5zYXguU0FYVHJhbnNmb3JtZXJGYWN0b3J5L2ZlYXR1cmUveG1sZmlsdGVyIjsKLQotICAgIC8qKgotICAgICAqIFRoZSBkZWZhdWx0IGNvbnN0cnVjdG9yIGlzIHByb3RlY3RlZCBvbiBwdXJwb3NlLgotICAgICAqLwotICAgIHByb3RlY3RlZCBTQVhUcmFuc2Zvcm1lckZhY3RvcnkoKSB7fQotCi0gICAgLyoqCi0gICAgICogR2V0IGEgVHJhbnNmb3JtZXJIYW5kbGVyIG9iamVjdCB0aGF0IGNhbiBwcm9jZXNzIFNBWAotICAgICAqIENvbnRlbnRIYW5kbGVyIGV2ZW50cyBpbnRvIGEgUmVzdWx0LCBiYXNlZCBvbiB0aGUgdHJhbnNmb3JtYXRpb24KLSAgICAgKiBpbnN0cnVjdGlvbnMgc3BlY2lmaWVkIGJ5IHRoZSBhcmd1bWVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzcmMgVGhlIFNvdXJjZSBvZiB0aGUgdHJhbnNmb3JtYXRpb24gaW5zdHJ1Y3Rpb25zLgotICAgICAqCi0gICAgICogQHJldHVybiBUcmFuc2Zvcm1lckhhbmRsZXIgcmVhZHkgdG8gdHJhbnNmb3JtIFNBWCBldmVudHMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBJZiBmb3Igc29tZSByZWFzb24gdGhlCi0gICAgICogVHJhbnNmb3JtZXJIYW5kbGVyIGNhbiBub3QgYmUgY3JlYXRlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3QgVHJhbnNmb3JtZXJIYW5kbGVyIG5ld1RyYW5zZm9ybWVySGFuZGxlcihTb3VyY2Ugc3JjKQotICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogR2V0IGEgVHJhbnNmb3JtZXJIYW5kbGVyIG9iamVjdCB0aGF0IGNhbiBwcm9jZXNzIFNBWAotICAgICAqIENvbnRlbnRIYW5kbGVyIGV2ZW50cyBpbnRvIGEgUmVzdWx0LCBiYXNlZCBvbiB0aGUgVGVtcGxhdGVzIGFyZ3VtZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIHRlbXBsYXRlcyBUaGUgY29tcGlsZWQgdHJhbnNmb3JtYXRpb24gaW5zdHJ1Y3Rpb25zLgotICAgICAqCi0gICAgICogQHJldHVybiBUcmFuc2Zvcm1lckhhbmRsZXIgcmVhZHkgdG8gdHJhbnNmb3JtIFNBWCBldmVudHMuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBJZiBmb3Igc29tZSByZWFzb24gdGhlCi0gICAgICogVHJhbnNmb3JtZXJIYW5kbGVyIGNhbiBub3QgYmUgY3JlYXRlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3QgVHJhbnNmb3JtZXJIYW5kbGVyIG5ld1RyYW5zZm9ybWVySGFuZGxlcigKLSAgICAgICAgVGVtcGxhdGVzIHRlbXBsYXRlcykgdGhyb3dzIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIEdldCBhIFRyYW5zZm9ybWVySGFuZGxlciBvYmplY3QgdGhhdCBjYW4gcHJvY2VzcyBTQVgKLSAgICAgKiBDb250ZW50SGFuZGxlciBldmVudHMgaW50byBhIFJlc3VsdC4gVGhlIHRyYW5zZm9ybWF0aW9uCi0gICAgICogaXMgZGVmaW5lZCBhcyBhbiBpZGVudGl0eSAob3IgY29weSkgdHJhbnNmb3JtYXRpb24sIGZvciBleGFtcGxlCi0gICAgICogdG8gY29weSBhIHNlcmllcyBvZiBTQVggcGFyc2UgZXZlbnRzIGludG8gYSBET00gdHJlZS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gQSBub24tbnVsbCByZWZlcmVuY2UgdG8gYSBUcmFuc2Zvcm1lckhhbmRsZXIsIHRoYXQgbWF5Ci0gICAgICogYmUgdXNlZCBhcyBhIENvbnRlbnRIYW5kbGVyIGZvciBTQVggcGFyc2UgZXZlbnRzLgotICAgICAqCi0gICAgICogQHRocm93cyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gSWYgZm9yIHNvbWUgcmVhc29uIHRoZQotICAgICAqIFRyYW5zZm9ybWVySGFuZGxlciBjYW5ub3QgYmUgY3JlYXRlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3QgVHJhbnNmb3JtZXJIYW5kbGVyIG5ld1RyYW5zZm9ybWVySGFuZGxlcigpCi0gICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgYSBUZW1wbGF0ZXNIYW5kbGVyIG9iamVjdCB0aGF0IGNhbiBwcm9jZXNzIFNBWAotICAgICAqIENvbnRlbnRIYW5kbGVyIGV2ZW50cyBpbnRvIGEgVGVtcGxhdGVzIG9iamVjdC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gQSBub24tbnVsbCByZWZlcmVuY2UgdG8gYSBUcmFuc2Zvcm1lckhhbmRsZXIsIHRoYXQgbWF5Ci0gICAgICogYmUgdXNlZCBhcyBhIENvbnRlbnRIYW5kbGVyIGZvciBTQVggcGFyc2UgZXZlbnRzLgotICAgICAqCi0gICAgICogQHRocm93cyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gSWYgZm9yIHNvbWUgcmVhc29uIHRoZQotICAgICAqIFRlbXBsYXRlc0hhbmRsZXIgY2Fubm90IGJlIGNyZWF0ZWQuCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IFRlbXBsYXRlc0hhbmRsZXIgbmV3VGVtcGxhdGVzSGFuZGxlcigpCi0gICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGUgYW4gWE1MRmlsdGVyIHRoYXQgdXNlcyB0aGUgZ2l2ZW4gU291cmNlIGFzIHRoZQotICAgICAqIHRyYW5zZm9ybWF0aW9uIGluc3RydWN0aW9ucy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzcmMgVGhlIFNvdXJjZSBvZiB0aGUgdHJhbnNmb3JtYXRpb24gaW5zdHJ1Y3Rpb25zLgotICAgICAqCi0gICAgICogQHJldHVybiBBbiBYTUxGaWx0ZXIgb2JqZWN0LCBvciBudWxsIGlmIHRoaXMgZmVhdHVyZSBpcyBub3Qgc3VwcG9ydGVkLgotICAgICAqCi0gICAgICogQHRocm93cyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gSWYgZm9yIHNvbWUgcmVhc29uIHRoZQotICAgICAqIFRlbXBsYXRlc0hhbmRsZXIgY2Fubm90IGJlIGNyZWF0ZWQuCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IFhNTEZpbHRlciBuZXdYTUxGaWx0ZXIoU291cmNlIHNyYykKLSAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIENyZWF0ZSBhbiBYTUxGaWx0ZXIsIGJhc2VkIG9uIHRoZSBUZW1wbGF0ZXMgYXJndW1lbnQuLgotICAgICAqCi0gICAgICogQHBhcmFtIHRlbXBsYXRlcyBUaGUgY29tcGlsZWQgdHJhbnNmb3JtYXRpb24gaW5zdHJ1Y3Rpb25zLgotICAgICAqCi0gICAgICogQHJldHVybiBBbiBYTUxGaWx0ZXIgb2JqZWN0LCBvciBudWxsIGlmIHRoaXMgZmVhdHVyZSBpcyBub3Qgc3VwcG9ydGVkLgotICAgICAqCi0gICAgICogQHRocm93cyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gSWYgZm9yIHNvbWUgcmVhc29uIHRoZQotICAgICAqIFRlbXBsYXRlc0hhbmRsZXIgY2Fubm90IGJlIGNyZWF0ZWQuCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IFhNTEZpbHRlciBuZXdYTUxGaWx0ZXIoVGVtcGxhdGVzIHRlbXBsYXRlcykKLSAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKLX0KZGlmZiAtLWdpdCBhL3NyYy9qYXZheC94bWwvdHJhbnNmb3JtL3NheC9UZW1wbGF0ZXNIYW5kbGVyLmphdmEgYi9zcmMvamF2YXgveG1sL3RyYW5zZm9ybS9zYXgvVGVtcGxhdGVzSGFuZGxlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzNGI1YmEyLi4wMDAwMDAwCi0tLSBhL3NyYy9qYXZheC94bWwvdHJhbnNmb3JtL3NheC9UZW1wbGF0ZXNIYW5kbGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw2OCArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDAwLCAyMDA1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi1wYWNrYWdlIGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4OwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS4qOwotCi1pbXBvcnQgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXI7Ci0KLS8qKgotICogQSBTQVggQ29udGVudEhhbmRsZXIgdGhhdCBtYXkgYmUgdXNlZCB0byBwcm9jZXNzIFNBWAotICogcGFyc2UgZXZlbnRzIChwYXJzaW5nIHRyYW5zZm9ybWF0aW9uIGluc3RydWN0aW9ucykgaW50byBhIFRlbXBsYXRlcyBvYmplY3QuCi0gKgotICogPHA+Tm90ZSB0aGF0IFRlbXBsYXRlc0hhbmRsZXIgZG9lcyBub3QgbmVlZCB0byBpbXBsZW1lbnQgTGV4aWNhbEhhbmRsZXIuPC9wPgotICovCi1wdWJsaWMgaW50ZXJmYWNlIFRlbXBsYXRlc0hhbmRsZXIgZXh0ZW5kcyBDb250ZW50SGFuZGxlciB7Ci0KLSAgICAvKioKLSAgICAgKiBXaGVuIGEgVGVtcGxhdGVzSGFuZGxlciBvYmplY3QgaXMgdXNlZCBhcyBhIENvbnRlbnRIYW5kbGVyCi0gICAgICogZm9yIHRoZSBwYXJzaW5nIG9mIHRyYW5zZm9ybWF0aW9uIGluc3RydWN0aW9ucywgaXQgY3JlYXRlcyBhIFRlbXBsYXRlcyBvYmplY3QsCi0gICAgICogd2hpY2ggdGhlIGNhbGxlciBjYW4gZ2V0IG9uY2UgdGhlIFNBWCBldmVudHMgaGF2ZSBiZWVuIGNvbXBsZXRlZC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIFRlbXBsYXRlcyBvYmplY3QgdGhhdCB3YXMgY3JlYXRlZCBkdXJpbmcKLSAgICAgKiB0aGUgU0FYIGV2ZW50IHByb2Nlc3MsIG9yIG51bGwgaWYgbm8gVGVtcGxhdGVzIG9iamVjdCBoYXMKLSAgICAgKiBiZWVuIGNyZWF0ZWQuCi0gICAgICoKLSAgICAgKi8KLSAgICBwdWJsaWMgVGVtcGxhdGVzIGdldFRlbXBsYXRlcygpOwotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSBiYXNlIElEIChVUkkgb3Igc3lzdGVtIElEKSBmb3IgdGhlIFRlbXBsYXRlcyBvYmplY3QKLSAgICAgKiBjcmVhdGVkIGJ5IHRoaXMgYnVpbGRlci4gIFRoaXMgbXVzdCBiZSBzZXQgaW4gb3JkZXIgdG8KLSAgICAgKiByZXNvbHZlIHJlbGF0aXZlIFVSSXMgaW4gdGhlIHN0eWxlc2hlZXQuICBUaGlzIG11c3QgYmUKLSAgICAgKiBjYWxsZWQgYmVmb3JlIHRoZSBzdGFydERvY3VtZW50IGV2ZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIHN5c3RlbUlEIEJhc2UgVVJJIGZvciB0aGlzIHN0eWxlc2hlZXQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0U3lzdGVtSWQoU3RyaW5nIHN5c3RlbUlEKTsKLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgYmFzZSBJRCAoVVJJIG9yIHN5c3RlbSBJRCkgZnJvbSB3aGVyZSByZWxhdGl2ZQotICAgICAqIFVSTHMgd2lsbCBiZSByZXNvbHZlZC4KLSAgICAgKiBAcmV0dXJuIFRoZSBzeXN0ZW1JRCB0aGF0IHdhcyBzZXQgd2l0aCB7QGxpbmsgI3NldFN5c3RlbUlkfS4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFN5c3RlbUlkKCk7Ci19CmRpZmYgLS1naXQgYS9zcmMvamF2YXgveG1sL3RyYW5zZm9ybS9zYXgvVHJhbnNmb3JtZXJIYW5kbGVyLmphdmEgYi9zcmMvamF2YXgveG1sL3RyYW5zZm9ybS9zYXgvVHJhbnNmb3JtZXJIYW5kbGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDhiY2VkNWUuLjAwMDAwMDAKLS0tIGEvc3JjL2phdmF4L3htbC90cmFuc2Zvcm0vc2F4L1RyYW5zZm9ybWVySGFuZGxlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNzYgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwMCwgMjAwNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotcGFja2FnZSBqYXZheC54bWwudHJhbnNmb3JtLnNheDsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uUmVzdWx0OwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXI7Ci0KLWltcG9ydCBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5EVERIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LmV4dC5MZXhpY2FsSGFuZGxlcjsKLQotLyoqCi0gKiBBIFRyYW5zZm9ybWVySGFuZGxlcgotICogbGlzdGVucyBmb3IgU0FYIENvbnRlbnRIYW5kbGVyIHBhcnNlIGV2ZW50cyBhbmQgdHJhbnNmb3JtcwotICogdGhlbSB0byBhIFJlc3VsdC4KLSAqLwotcHVibGljIGludGVyZmFjZSBUcmFuc2Zvcm1lckhhbmRsZXIKLSAgICBleHRlbmRzIENvbnRlbnRIYW5kbGVyLCBMZXhpY2FsSGFuZGxlciwgRFRESGFuZGxlciB7Ci0KLSAgICAvKioKLSAgICAgKiA8cD5TZXQgIHRoZSA8Y29kZT5SZXN1bHQ8L2NvZGU+IGFzc29jaWF0ZWQgd2l0aCB0aGlzCi0gICAgICogPGNvZGU+VHJhbnNmb3JtZXJIYW5kbGVyPC9jb2RlPiB0byBiZSB1c2VkIGZvciB0aGUgdHJhbnNmb3JtYXRpb24uPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIHJlc3VsdCBBIDxjb2RlPlJlc3VsdDwvY29kZT4gaW5zdGFuY2UsIHNob3VsZCBub3QgYmUKLSAgICAgKiAgIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAqCi0gICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgcmVzdWx0IGlzIGludmFsaWQgZm9yIHNvbWUgcmVhc29uLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFJlc3VsdChSZXN1bHQgcmVzdWx0KSB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSBiYXNlIElEIChVUkkgb3Igc3lzdGVtIElEKSBmcm9tIHdoZXJlIHJlbGF0aXZlCi0gICAgICogVVJMcyB3aWxsIGJlIHJlc29sdmVkLgotICAgICAqIEBwYXJhbSBzeXN0ZW1JRCBCYXNlIFVSSSBmb3IgdGhlIHNvdXJjZSB0cmVlLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFN5c3RlbUlkKFN0cmluZyBzeXN0ZW1JRCk7Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIGJhc2UgSUQgKFVSSSBvciBzeXN0ZW0gSUQpIGZyb20gd2hlcmUgcmVsYXRpdmUKLSAgICAgKiBVUkxzIHdpbGwgYmUgcmVzb2x2ZWQuCi0gICAgICogQHJldHVybiBUaGUgc3lzdGVtSUQgdGhhdCB3YXMgc2V0IHdpdGgge0BsaW5rICNzZXRTeXN0ZW1JZH0uCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRTeXN0ZW1JZCgpOwotCi0gICAgLyoqCi0gICAgICogPHA+R2V0IHRoZSA8Y29kZT5UcmFuc2Zvcm1lcjwvY29kZT4gYXNzb2NpYXRlZCB3aXRoIHRoaXMgaGFuZGxlciwgd2hpY2gKLSAgICAgKiBpcyBuZWVkZWQgaW4gb3JkZXIgdG8gc2V0IHBhcmFtZXRlcnMgYW5kIG91dHB1dCBwcm9wZXJ0aWVzLjwvcD4KLSAgICAgKgotICAgICAqIEByZXR1cm4gPGNvZGU+VHJhbnNmb3JtZXI8L2NvZGU+IGFzc29jaWF0ZWQgd2l0aCB0aGlzCi0gICAgICogICA8Y29kZT5UcmFuc2Zvcm1lckhhbmRsZXI8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBUcmFuc2Zvcm1lciBnZXRUcmFuc2Zvcm1lcigpOwotfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmF4L3htbC90cmFuc2Zvcm0vc2F4L3BhY2thZ2UuaHRtbCBiL3NyYy9qYXZheC94bWwvdHJhbnNmb3JtL3NheC9wYWNrYWdlLmh0bWwKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDk3ZGNlNDYuLjAwMDAwMDAKLS0tIGEvc3JjL2phdmF4L3htbC90cmFuc2Zvcm0vc2F4L3BhY2thZ2UuaHRtbAorKysgL2Rldi9udWxsCkBAIC0xLDEwNCArMCwwIEBACi08P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJVVEYtOCI/PgotPCEtLQotQ29weXJpZ2h0IChjKSAyMDAwLCAyMDA1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotCi1UaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLXB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0KLVRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi1GSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLXZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci1hY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotCi1Zb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0yIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi1JbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0KLVBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi1vciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci1xdWVzdGlvbnMuIAotLS0+Ci0KLTwhRE9DVFlQRSBodG1sCi0gICAgIFBVQkxJQyAiLS8vVzNDLy9EVEQgWEhUTUwgMS4wIFN0cmljdC8vRU4iCi0gICAgICJodHRwOi8vd3d3LnczLm9yZy9UUi94aHRtbDEvRFREL3hodG1sMS1zdHJpY3QuZHRkIj4KLQotPGh0bWwgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwiPgotCi08aGVhZD4KLSAgPHRpdGxlPmphdmF4LnhtbC50cmFuc2Zvcm0uc2F4PC90aXRsZT4KLQotICA8bWV0YSBuYW1lPSJDVlMiCi0gICAgICAgIGNvbnRlbnQ9IiRJZDogcGFja2FnZS5odG1sLHYgMS4yIDIwMDUvMDYvMTAgMDM6NTA6NDEgamVmZnN1dHRvciBFeHAgJCIgLz4KLSAgPG1ldGEgbmFtZT0iQVVUSE9SIgotICAgICAgICBjb250ZW50PSJKZWZmLlN1dHRvckBTdW4uY29tIiAvPgotPC9oZWFkPgotCi08Ym9keT4KLTxwPlRoaXMgcGFja2FnZSBpbXBsZW1lbnRzIFNBWDItc3BlY2lmaWMgdHJhbnNmb3JtYXRpb24gQVBJcy4gSXQgcHJvdmlkZXMKLSAgY2xhc3NlcyB3aGljaCBhbGxvdyBpbnB1dCBmcm9tIHtAbGluayBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcn0KLSAgZXZlbnRzLCBhbmQgYWxzbyBjbGFzc2VzIHRoYXQgcHJvZHVjZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciBldmVudHMuIEl0Ci0gIGFsc28gcHJvdmlkZXMgbWV0aG9kcyB0byBzZXQgdGhlIGlucHV0IHNvdXJjZSBhcyBhbgotICB7QGxpbmsgb3JnLnhtbC5zYXguWE1MUmVhZGVyfSwgb3IgdG8gdXNlIGEKLSAge0BsaW5rIG9yZy54bWwuc2F4LklucHV0U291cmNlfSBhcyB0aGUgc291cmNlLiBJdCBhbHNvIGFsbG93cyB0aGUKLSAgY3JlYXRpb24gb2YgYSB7QGxpbmsgb3JnLnhtbC5zYXguWE1MRmlsdGVyfSwgd2hpY2ggZW5hYmxlcwotICB0cmFuc2Zvcm1hdGlvbnMgdG8gInB1bGwiIGZyb20gb3RoZXIgdHJhbnNmb3JtYXRpb25zLCBhbmQgbGV0cyB0aGUgdHJhbnNmb3JtZXIKLSAgdG8gYmUgdXNlZCBwb2x5bW9ycGhpY2FsbHkgYXMgYW4ge0BsaW5rIG9yZy54bWwuc2F4LlhNTFJlYWRlcn0uPC9wPgotPHA+VGhlIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLnNheC5TQVhTb3VyY2V9IGNsYXNzIGFsbG93cyB0aGUKLSAgc2V0dGluZyBvZiBhbiB7QGxpbmsgb3JnLnhtbC5zYXguWE1MUmVhZGVyfSB0byBiZSB1c2VkIGZvciAicHVsbGluZyIKLSAgcGFyc2UgZXZlbnRzLCBhbmQgYW4ge0BsaW5rIG9yZy54bWwuc2F4LklucHV0U291cmNlfSB0aGF0IG1heSBiZSB1c2VkIHRvCi0gIHNwZWNpZnkgdGhlIFNBWCBzb3VyY2UuPC9wPgotPHA+VGhlIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLnNheC5TQVhSZXN1bHR9IGNsYXNzIGFsbG93cyB0aGUKLSAgc2V0dGluZyBvZiBhIHtAbGluayBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcn0gdG8gYmUgdGhlIHJlY2VpdmVyIG9mCi0gIFNBWDIgZXZlbnRzIGZyb20gdGhlIHRyYW5zZm9ybWF0aW9uLiAKLTxwPlRoZSB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5zYXguU0FYVHJhbnNmb3JtZXJGYWN0b3J5fSBleHRlbmRzCi0gIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRmFjdG9yeX0gdG8gcHJvdmlkZSBmYWN0b3J5Ci0gIG1ldGhvZHMgZm9yIGNyZWF0aW5nIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLnNheC5UZW1wbGF0ZXNIYW5kbGVyfSwKLSAge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlRyYW5zZm9ybWVySGFuZGxlcn0sIGFuZAotICB7QGxpbmsgb3JnLnhtbC5zYXguWE1MUmVhZGVyfSBpbnN0YW5jZXMuPC9wPgotPHA+VG8gb2J0YWluIGEge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlNBWFRyYW5zZm9ybWVyRmFjdG9yeX0sCi0gIHRoZSBjYWxsZXIgbXVzdCBjYXN0IHRoZSB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckZhY3Rvcnl9Ci0gIGluc3RhbmNlIHJldHVybmVkIGZyb20KLSAge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJGYWN0b3J5I25ld0luc3RhbmNlfS4gCi0KLTxwPlRoZSB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5zYXguVHJhbnNmb3JtZXJIYW5kbGVyfSBpbnRlcmZhY2UKLSAgYWxsb3dzIGEgdHJhbnNmb3JtYXRpb24gdG8gYmUgY3JlYXRlZCBmcm9tIFNBWDIgcGFyc2UgZXZlbnRzLCB3aGljaCBpcyBhICJwdXNoIgotICBtb2RlbCByYXRoZXIgdGhhbiB0aGUgInB1bGwiIG1vZGVsIHRoYXQgbm9ybWFsbHkgb2NjdXJzIGZvciBhIHRyYW5zZm9ybWF0aW9uLgotICBOb3JtYWwgcGFyc2UgZXZlbnRzIGFyZSByZWNlaXZlZCB0aHJvdWdoIHRoZQotICB7QGxpbmsgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXJ9IGludGVyZmFjZSwgbGV4aWNhbCBldmVudHMgc3VjaCBhcwotICBzdGFydENEQVRBIGFuZCBlbmRDREFUQSBhcmUgcmVjZWl2ZWQgdGhyb3VnaCB0aGUKLSAge0BsaW5rIG9yZy54bWwuc2F4LmV4dC5MZXhpY2FsSGFuZGxlcn0gaW50ZXJmYWNlLCBhbmQgZXZlbnRzIHRoYXQgc2lnbmFsCi0gIHRoZSBzdGFydCBvciBlbmQgb2YgZGlzYWJsaW5nIG91dHB1dCBlc2NhcGluZyBhcmUgcmVjZWl2ZWQgdmlhCi0gIHtAbGluayBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNwcm9jZXNzaW5nSW5zdHJ1Y3Rpb259LCB3aXRoIHRoZQotICB0YXJnZXQgcGFyYW1ldGVyIGJlaW5nCi0gIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlJlc3VsdCNQSV9ESVNBQkxFX09VVFBVVF9FU0NBUElOR30gYW5kCi0gIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlJlc3VsdCNQSV9FTkFCTEVfT1VUUFVUX0VTQ0FQSU5HfS4gSWYKLSAgcGFyYW1ldGVycywgb3V0cHV0IHByb3BlcnRpZXMsIG9yIG90aGVyIGZlYXR1cmVzIG5lZWQgdG8gYmUgc2V0IG9uIHRoZQotICBUcmFuc2Zvcm1lciBoYW5kbGVyLCBhIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyfSByZWZlcmVuY2UKLSAgd2lsbCBuZWVkIHRvIGJlIG9idGFpbmVkIGZyb20KLSAge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlRyYW5zZm9ybWVySGFuZGxlciNnZXRUcmFuc2Zvcm1lcn0sIGFuZAotICB0aGUgbWV0aG9kcyBpbnZva2VkIGZyb20gdGhhdCByZWZlcmVuY2UuIAotCi08cD5UaGUge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlRlbXBsYXRlc0hhbmRsZXJ9IGludGVyZmFjZQotICBhbGxvd3MgdGhlIGNyZWF0aW9uIG9mIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlRlbXBsYXRlc30gb2JqZWN0cwotICBmcm9tIFNBWDIgcGFyc2UgZXZlbnRzLiBPbmNlIHRoZSB7QGxpbmsgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXJ9Ci0gIGV2ZW50cyBhcmUgY29tcGxldGUsIHRoZSBUZW1wbGF0ZXMgb2JqZWN0IG1heSBiZSBvYnRhaW5lZCBmcm9tCi0gIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLnNheC5UZW1wbGF0ZXNIYW5kbGVyI2dldFRlbXBsYXRlc30uIE5vdGUgdGhhdAotICB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5zYXguVGVtcGxhdGVzSGFuZGxlciNzZXRTeXN0ZW1JZH0gc2hvdWxkCi0gIG5vcm1hbGx5IGJlIGNhbGxlZCBpbiBvcmRlciB0byBlc3RhYmxpc2ggYSBiYXNlIHN5c3RlbSBJRCBmcm9tIHdoaWNoIHJlbGF0aXZlCi0gIFVSTHMgbWF5IGJlIHJlc29sdmVkLiAKLTxwPlRoZQotICB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5zYXguU0FYVHJhbnNmb3JtZXJGYWN0b3J5I25ld1hNTEZpbHRlcn0KLSAgbWV0aG9kIGFsbG93cyB0aGUgY3JlYXRpb24gb2YgYSB7QGxpbmsgb3JnLnhtbC5zYXguWE1MRmlsdGVyfSwgd2hpY2gKLSAgZW5jYXBzdWxhdGVzIHRoZSBTQVgyIG5vdGlvbiBvZiBhICJwdWxsIiB0cmFuc2Zvcm1hdGlvbi4gVGhlIGZvbGxvd2luZwotICBpbGx1c3RyYXRlcyBzZXZlcmFsIHRyYW5zZm9ybWF0aW9ucyBjaGFpbmVkIHRvZ2V0aGVyLiBFYWNoIGZpbHRlciBwb2ludHMgdG8gYQotICBwYXJlbnQge0BsaW5rIG9yZy54bWwuc2F4LlhNTFJlYWRlcn0sIGFuZCB0aGUgZmluYWwgdHJhbnNmb3JtYXRpb24gaXMKLSAgY2F1c2VkIGJ5IGludm9raW5nIHtAbGluayBvcmcueG1sLnNheC5YTUxSZWFkZXIjcGFyc2V9IG9uIHRoZSBmaW5hbAotICByZWFkZXIgaW4gdGhlIGNoYWluLjwvcD4KLTwvYm9keT4KLTwvaHRtbD4KZGlmZiAtLWdpdCBhL3NyYy9qYXZheC94bWwvdHJhbnNmb3JtL3N0YXgvU3RBWFJlc3VsdC5qYXZhIGIvc3JjL2phdmF4L3htbC90cmFuc2Zvcm0vc3RheC9TdEFYUmVzdWx0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDliZWQ3N2EuLjAwMDAwMDAKLS0tIGEvc3JjL2phdmF4L3htbC90cmFuc2Zvcm0vc3RheC9TdEFYUmVzdWx0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxODMgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAwNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotcGFja2FnZSBqYXZheC54bWwudHJhbnNmb3JtLnN0YXg7Ci0KLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLlhNTEV2ZW50V3JpdGVyOwotaW1wb3J0IGphdmF4LnhtbC5zdHJlYW0uWE1MU3RyZWFtV3JpdGVyOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uUmVzdWx0OwotCi0vKioKLSAqIDxwPkFjdHMgYXMgYSBob2xkZXIgZm9yIGFuIFhNTCB7QGxpbmsgUmVzdWx0fSBpbiB0aGUKLSAqIGZvcm0gb2YgYSBTdEFYIHdyaXRlcixpLmUuCi0gKiB7QGxpbmsgWE1MU3RyZWFtV3JpdGVyfSBvciB7QGxpbmsgWE1MRXZlbnRXcml0ZXJ9LgotICogPGNvZGU+U3RBWFJlc3VsdDwvY29kZT4gY2FuIGJlIHVzZWQgaW4gYWxsIGNhc2VzIHRoYXQgYWNjZXB0Ci0gKiBhIDxjb2RlPlJlc3VsdDwvY29kZT4sIGUuZy4ge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJ9LAotICoge0BsaW5rIGphdmF4LnhtbC52YWxpZGF0aW9uLlZhbGlkYXRvcn0gd2hpY2ggYWNjZXB0Ci0gKiA8Y29kZT5SZXN1bHQ8L2NvZGU+IGFzIGlucHV0LgotICoKLSAqIEBhdXRob3IgPGEgaHJlZj0ibWFpbHRvOk5lZXJhai5CYWphakBTdW4uY29tIj5OZWVyYWogQmFqYWo8L2E+Ci0gKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzpKZWZmLlN1dHRvckBTdW4uY29tIj5KZWZmIFN1dHRvcjwvYT4KLSAqCi0gKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly9qY3Aub3JnL2VuL2pzci9kZXRhaWw/aWQ9MTczIj4KLSAqICBKU1IgMTczOiBTdHJlYW1pbmcgQVBJIGZvciBYTUw8L2E+Ci0gKiBAc2VlIFhNTFN0cmVhbVdyaXRlcgotICogQHNlZSBYTUxFdmVudFdyaXRlcgotICoKLSAqIEBzaW5jZSAxLjYKLSAqLwotcHVibGljIGNsYXNzIFN0QVhSZXN1bHQgaW1wbGVtZW50cyBSZXN1bHQgewotICAgIC8qKiBJZiB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckZhY3RvcnkjZ2V0RmVhdHVyZShTdHJpbmcgbmFtZSl9Ci0gICAgICogcmV0dXJucyB0cnVlIHdoZW4gcGFzc2VkIHRoaXMgdmFsdWUgYXMgYW4gYXJndW1lbnQsCi0gICAgICogdGhlIFRyYW5zZm9ybWVyIHN1cHBvcnRzIFJlc3VsdCBvdXRwdXQgb2YgdGhpcyB0eXBlLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEZFQVRVUkUgPQotICAgICAgICAiaHR0cDovL2phdmF4LnhtbC50cmFuc2Zvcm0uc3RheC5TdEFYUmVzdWx0L2ZlYXR1cmUiOwotCi0gICAgLyoqCi0gICAgICogPHA+PGNvZGU+WE1MRXZlbnRXcml0ZXI8L2NvZGU+IHRvIGJlIHVzZWQgZm9yCi0gICAgICogPGNvZGU+UmVzdWx0PC9jb2RlPiBvdXRwdXQuPC9wPgotICAgICAqLwotICAgIHByaXZhdGUgWE1MRXZlbnRXcml0ZXIgeG1sRXZlbnRXcml0ZXIgPSBudWxsOwotCi0gICAgLyoqCi0gICAgICogPHA+PGNvZGU+WE1MU3RyZWFtV3JpdGVyPC9jb2RlPiB0byBiZSB1c2VkIGZvcgotICAgICAqIDxjb2RlPlJlc3VsdDwvY29kZT4gb3V0cHV0LjwvcD4KLSAgICAgKi8KLSAgICBwcml2YXRlIFhNTFN0cmVhbVdyaXRlciB4bWxTdHJlYW1Xcml0ZXIgPSBudWxsOwotCi0gICAgLyoqIDxwPlN5c3RlbSBpZGVudGlmaWVyIGZvciB0aGlzIDxjb2RlPlN0QVhSZXN1bHQ8L2NvZGU+LjxwPiAqLwotICAgIHByaXZhdGUgU3RyaW5nIHN5c3RlbUlkID0gbnVsbDsKLQotICAgIC8qKgotICAgICAqIDxwPkNyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgYSA8Y29kZT5TdEFYUmVzdWx0PC9jb2RlPgotICAgICAqIGJ5IHN1cHBseWluZyBhbiB7QGxpbmsgWE1MRXZlbnRXcml0ZXJ9LjwvcD4KLSAgICAgKgotICAgICAqIDxwPjxjb2RlPlhNTEV2ZW50V3JpdGVyPC9jb2RlPiBtdXN0IGJlIGEKLSAgICAgKiBub24tPGNvZGU+bnVsbDwvY29kZT4gcmVmZXJlbmNlLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSB4bWxFdmVudFdyaXRlciA8Y29kZT5YTUxFdmVudFdyaXRlcjwvY29kZT4gdXNlZCB0byBjcmVhdGUKLSAgICAgKiAgIHRoaXMgPGNvZGU+U3RBWFJlc3VsdDwvY29kZT4uCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBJZiA8Y29kZT54bWxFdmVudFdyaXRlcjwvY29kZT4gPT0KLSAgICAgKiAgIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBTdEFYUmVzdWx0KGZpbmFsIFhNTEV2ZW50V3JpdGVyIHhtbEV2ZW50V3JpdGVyKSB7Ci0KLSAgICAgICAgaWYgKHhtbEV2ZW50V3JpdGVyID09IG51bGwpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgICJTdEFYUmVzdWx0KFhNTEV2ZW50V3JpdGVyKSB3aXRoIFhNTEV2ZW50V3JpdGVyID09IG51bGwiKTsKLSAgICAgICAgfQotCi0gICAgICAgIHRoaXMueG1sRXZlbnRXcml0ZXIgPSB4bWxFdmVudFdyaXRlcjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5DcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIGEgPGNvZGU+U3RBWFJlc3VsdDwvY29kZT4KLSAgICAgKiBieSBzdXBwbHlpbmcgYW4ge0BsaW5rIFhNTFN0cmVhbVdyaXRlcn0uPC9wPgotICAgICAqCi0gICAgICogPHA+PGNvZGU+WE1MU3RyZWFtV3JpdGVyPC9jb2RlPiBtdXN0IGJlIGEKLSAgICAgKiBub24tPGNvZGU+bnVsbDwvY29kZT4gcmVmZXJlbmNlLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSB4bWxTdHJlYW1Xcml0ZXIgPGNvZGU+WE1MU3RyZWFtV3JpdGVyPC9jb2RlPiB1c2VkIHRvIGNyZWF0ZQotICAgICAqICAgdGhpcyA8Y29kZT5TdEFYUmVzdWx0PC9jb2RlPi4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIElmIDxjb2RlPnhtbFN0cmVhbVdyaXRlcjwvY29kZT4gPT0KLSAgICAgKiAgIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBTdEFYUmVzdWx0KGZpbmFsIFhNTFN0cmVhbVdyaXRlciB4bWxTdHJlYW1Xcml0ZXIpIHsKLQotICAgICAgICBpZiAoeG1sU3RyZWFtV3JpdGVyID09IG51bGwpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgICJTdEFYUmVzdWx0KFhNTFN0cmVhbVdyaXRlcikgd2l0aCBYTUxTdHJlYW1Xcml0ZXIgPT0gbnVsbCIpOwotICAgICAgICB9Ci0KLSAgICAgICAgdGhpcy54bWxTdHJlYW1Xcml0ZXIgPSB4bWxTdHJlYW1Xcml0ZXI7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+R2V0IHRoZSA8Y29kZT5YTUxFdmVudFdyaXRlcjwvY29kZT4gdXNlZCBieSB0aGlzCi0gICAgICogPGNvZGU+U3RBWFJlc3VsdDwvY29kZT4uPC9wPgotICAgICAqCi0gICAgICogPHA+PGNvZGU+WE1MRXZlbnRXcml0ZXI8L2NvZGU+IHdpbGwgYmUgPGNvZGU+bnVsbDwvY29kZT4KLSAgICAgKiBpZiB0aGlzIDxjb2RlPlN0QVhSZXN1bHQ8L2NvZGU+IHdhcyBjcmVhdGVkIHdpdGggYQotICAgICAqIDxjb2RlPlhNTFN0cmVhbVdyaXRlcjwvY29kZT4uPC9wPgotICAgICAqCi0gICAgICogQHJldHVybiA8Y29kZT5YTUxFdmVudFdyaXRlcjwvY29kZT4gdXNlZCBieSB0aGlzCi0gICAgICogICA8Y29kZT5TdEFYUmVzdWx0PC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgWE1MRXZlbnRXcml0ZXIgZ2V0WE1MRXZlbnRXcml0ZXIoKSB7Ci0KLSAgICAgICAgcmV0dXJuIHhtbEV2ZW50V3JpdGVyOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPkdldCB0aGUgPGNvZGU+WE1MU3RyZWFtV3JpdGVyPC9jb2RlPiB1c2VkIGJ5IHRoaXMKLSAgICAgKiA8Y29kZT5TdEFYUmVzdWx0PC9jb2RlPi48L3A+Ci0gICAgICoKLSAgICAgKiA8cD48Y29kZT5YTUxTdHJlYW1Xcml0ZXI8L2NvZGU+IHdpbGwgYmUgPGNvZGU+bnVsbDwvY29kZT4KLSAgICAgKiBpZiB0aGlzIDxjb2RlPlN0QVhSZXN1bHQ8L2NvZGU+IHdhcyBjcmVhdGVkIHdpdGggYQotICAgICAqIDxjb2RlPlhNTEV2ZW50V3JpdGVyPC9jb2RlPi48L3A+Ci0gICAgICoKLSAgICAgKiBAcmV0dXJuIDxjb2RlPlhNTFN0cmVhbVdyaXRlcjwvY29kZT4gdXNlZCBieSB0aGlzCi0gICAgICogICA8Y29kZT5TdEFYUmVzdWx0PC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgWE1MU3RyZWFtV3JpdGVyIGdldFhNTFN0cmVhbVdyaXRlcigpIHsKLQotICAgICAgICByZXR1cm4geG1sU3RyZWFtV3JpdGVyOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPkluIHRoZSBjb250ZXh0IG9mIGEgPGNvZGU+U3RBWFJlc3VsdDwvY29kZT4sIGl0IGlzIG5vdCBhcHByb3ByaWF0ZQotICAgICAqIHRvIGV4cGxpY2l0bHkgc2V0IHRoZSBzeXN0ZW0gaWRlbnRpZmllci4KLSAgICAgKiBUaGUgPGNvZGU+WE1MRXZlbnRXcml0ZXI8L2NvZGU+IG9yIDxjb2RlPlhNTFN0cmVhbVdyaXRlcjwvY29kZT4KLSAgICAgKiB1c2VkIHRvIGNvbnN0cnVjdCB0aGlzIDxjb2RlPlN0QVhSZXN1bHQ8L2NvZGU+IGRldGVybWluZXMgdGhlCi0gICAgICogc3lzdGVtIGlkZW50aWZpZXIgb2YgdGhlIFhNTCByZXN1bHQuPC9wPgotICAgICAqCi0gICAgICogPHA+QW4ge0BsaW5rIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9ufSBpcyA8c3Ryb25nPmFsd2F5czwvc3Ryb25nPgotICAgICAqIHRocm93biBieSB0aGlzIG1ldGhvZC48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gc3lzdGVtSWQgSWdub3JlZC4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gSXMgPHN0cm9uZz5hbHdheXM8L3N0cm9uZz4KLSAgICAgKiAgIHRocm93biBieSB0aGlzIG1ldGhvZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRTeXN0ZW1JZChmaW5hbCBTdHJpbmcgc3lzdGVtSWQpIHsKLQotICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgIlN0QVhSZXN1bHQjc2V0U3lzdGVtSWQoc3lzdGVtSWQpIGNhbm5vdCBzZXQgdGhlICIKLSAgICAgICAgICAgICAgICArICJzeXN0ZW0gaWRlbnRpZmllciBmb3IgYSBTdEFYUmVzdWx0Iik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+VGhlIHJldHVybmVkIHN5c3RlbSBpZGVudGlmaWVyIGlzIGFsd2F5cyA8Y29kZT5udWxsPC9jb2RlPi48L3A+Ci0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSByZXR1cm5lZCBzeXN0ZW0gaWRlbnRpZmllciBpcyBhbHdheXMgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRTeXN0ZW1JZCgpIHsKLQotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvamF2YXgveG1sL3RyYW5zZm9ybS9zdGF4L1N0QVhTb3VyY2UuamF2YSBiL3NyYy9qYXZheC94bWwvdHJhbnNmb3JtL3N0YXgvU3RBWFNvdXJjZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkZDA0YjYzLi4wMDAwMDAwCi0tLSBhL3NyYy9qYXZheC94bWwvdHJhbnNmb3JtL3N0YXgvU3RBWFNvdXJjZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjM2ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMDYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLXBhY2thZ2UgamF2YXgueG1sLnRyYW5zZm9ybS5zdGF4OwotCi1pbXBvcnQgamF2YXgueG1sLnN0cmVhbS5YTUxFdmVudFJlYWRlcjsKLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLlhNTFN0cmVhbUNvbnN0YW50czsKLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLlhNTFN0cmVhbUV4Y2VwdGlvbjsKLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLlhNTFN0cmVhbVJlYWRlcjsKLWltcG9ydCBqYXZheC54bWwuc3RyZWFtLmV2ZW50cy5YTUxFdmVudDsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlNvdXJjZTsKLQotLyoqCi0gKiA8cD5BY3RzIGFzIGEgaG9sZGVyIGZvciBhbiBYTUwge0BsaW5rIFNvdXJjZX0gaW4gdGhlCi0gKiBmb3JtIG9mIGEgU3RBWCByZWFkZXIsaS5lLgotICoge0BsaW5rIFhNTFN0cmVhbVJlYWRlcn0gb3Ige0BsaW5rIFhNTEV2ZW50UmVhZGVyfS4KLSAqIDxjb2RlPlN0QVhTb3VyY2U8L2NvZGU+IGNhbiBiZSB1c2VkIGluIGFsbCBjYXNlcyB0aGF0IGFjY2VwdAotICogYSA8Y29kZT5Tb3VyY2U8L2NvZGU+LCBlLmcuIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyfSwKLSAqIHtAbGluayBqYXZheC54bWwudmFsaWRhdGlvbi5WYWxpZGF0b3J9IHdoaWNoIGFjY2VwdAotICogPGNvZGU+U291cmNlPC9jb2RlPiBhcyBpbnB1dC4KLSAqCi0gKiA8cD48Y29kZT5TdEFYU291cmNlPC9jb2RlPnMgYXJlIGNvbnN1bWVkIGR1cmluZyBwcm9jZXNzaW5nCi0gKiBhbmQgYXJlIG5vdCByZXVzYWJsZS48L3A+Ci0gKgotICogQGF1dGhvciA8YSBocmVmPSJtYWlsdG86TmVlcmFqLkJhamFqQFN1bi5jb20iPk5lZXJhaiBCYWphajwvYT4KLSAqIEBhdXRob3IgPGEgaHJlZj0ibWFpbHRvOkplZmYuU3V0dG9yQFN1bi5jb20iPkplZmYgU3V0dG9yPC9hPgotICoKLSAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL2pjcC5vcmcvZW4vanNyL2RldGFpbD9pZD0xNzMiPgotICogIEpTUiAxNzM6IFN0cmVhbWluZyBBUEkgZm9yIFhNTDwvYT4KLSAqIEBzZWUgWE1MU3RyZWFtUmVhZGVyCi0gKiBAc2VlIFhNTEV2ZW50UmVhZGVyCi0gKgotICogQHNpbmNlIDEuNgotICovCi1wdWJsaWMgY2xhc3MgU3RBWFNvdXJjZSBpbXBsZW1lbnRzIFNvdXJjZSB7Ci0KLSAgICAvKiogSWYge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJGYWN0b3J5I2dldEZlYXR1cmUoU3RyaW5nIG5hbWUpfQotICAgICAqIHJldHVybnMgdHJ1ZSB3aGVuIHBhc3NlZCB0aGlzIHZhbHVlIGFzIGFuIGFyZ3VtZW50LAotICAgICAqIHRoZSBUcmFuc2Zvcm1lciBzdXBwb3J0cyBTb3VyY2UgaW5wdXQgb2YgdGhpcyB0eXBlLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEZFQVRVUkUgPQotICAgICAgICAiaHR0cDovL2phdmF4LnhtbC50cmFuc2Zvcm0uc3RheC5TdEFYU291cmNlL2ZlYXR1cmUiOwotCi0gICAgLyoqIDxwPjxjb2RlPlhNTEV2ZW50UmVhZGVyPC9jb2RlPiB0byBiZSB1c2VkIGZvciBzb3VyY2UgaW5wdXQuPC9wPiAqLwotICAgIHByaXZhdGUgWE1MRXZlbnRSZWFkZXIgeG1sRXZlbnRSZWFkZXIgPSBudWxsOwotCi0gICAgLyoqIDxwPjxjb2RlPlhNTFN0cmVhbVJlYWRlcjwvY29kZT4gdG8gYmUgdXNlZCBmb3Igc291cmNlIGlucHV0LjwvcD4gKi8KLSAgICBwcml2YXRlIFhNTFN0cmVhbVJlYWRlciB4bWxTdHJlYW1SZWFkZXIgPSBudWxsOwotCi0gICAgLyoqIDxwPlN5c3RlbSBpZGVudGlmaWVyIG9mIHNvdXJjZSBpbnB1dC48L3A+ICovCi0gICAgcHJpdmF0ZSBTdHJpbmcgc3lzdGVtSWQgPSBudWxsOwotCi0gICAgLyoqCi0gICAgICogPHA+Q3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiBhIDxjb2RlPlN0QVhTb3VyY2U8L2NvZGU+Ci0gICAgICogYnkgc3VwcGx5aW5nIGFuIHtAbGluayBYTUxFdmVudFJlYWRlcn0uPC9wPgotICAgICAqCi0gICAgICogPHA+PGNvZGU+WE1MRXZlbnRSZWFkZXI8L2NvZGU+IG11c3QgYmUgYQotICAgICAqIG5vbi08Y29kZT5udWxsPC9jb2RlPiByZWZlcmVuY2UuPC9wPgotICAgICAqCi0gICAgICogPHA+PGNvZGU+WE1MRXZlbnRSZWFkZXI8L2NvZGU+IG11c3QgYmUgaW4KLSAgICAgKiB7QGxpbmsgWE1MU3RyZWFtQ29uc3RhbnRzI1NUQVJUX0RPQ1VNRU5UfSBvcgotICAgICAqIHtAbGluayBYTUxTdHJlYW1Db25zdGFudHMjU1RBUlRfRUxFTUVOVH0gc3RhdGUuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIHhtbEV2ZW50UmVhZGVyIDxjb2RlPlhNTEV2ZW50UmVhZGVyPC9jb2RlPiB1c2VkIHRvIGNyZWF0ZQotICAgICAqICAgdGhpcyA8Y29kZT5TdEFYU291cmNlPC9jb2RlPi4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uIElmIDxjb2RlPnhtbEV2ZW50UmVhZGVyPC9jb2RlPiBhY2Nlc3MKLSAgICAgKiAgIHRocm93cyBhbiA8Y29kZT5FeGNlcHRpb248L2NvZGU+LgotICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIElmIDxjb2RlPnhtbEV2ZW50UmVhZGVyPC9jb2RlPiA9PQotICAgICAqICAgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gSWYgPGNvZGU+eG1sRXZlbnRSZWFkZXI8L2NvZGU+Ci0gICAgICogICBpcyBub3QgaW4gPGNvZGU+WE1MU3RyZWFtQ29uc3RhbnRzLlNUQVJUX0RPQ1VNRU5UPC9jb2RlPiBvcgotICAgICAqICAgPGNvZGU+WE1MU3RyZWFtQ29uc3RhbnRzLlNUQVJUX0VMRU1FTlQ8L2NvZGU+IHN0YXRlLgotICAgICAqLwotICAgIHB1YmxpYyBTdEFYU291cmNlKGZpbmFsIFhNTEV2ZW50UmVhZGVyIHhtbEV2ZW50UmVhZGVyKQotICAgICAgICB0aHJvd3MgWE1MU3RyZWFtRXhjZXB0aW9uIHsKLQotICAgICAgICBpZiAoeG1sRXZlbnRSZWFkZXIgPT0gbnVsbCkgewotICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgIlN0QVhTb3VyY2UoWE1MRXZlbnRSZWFkZXIpIHdpdGggWE1MRXZlbnRSZWFkZXIgPT0gbnVsbCIpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gVE9ETzogVGhpcyBpcyB1Z2x5IC4uLgotICAgICAgICAvLyB0aGVyZSBpcyBubyB3YXkgdG8ga25vdyB0aGUgY3VycmVudCBwb3NpdGlvbihldmVudCkgb2YKLSAgICAgICAgLy8gWE1MRXZlbnRSZWFkZXIuICBwZWVrKCkgaXMgdGhlIG9ubHkgd2F5IHRvIGtub3cgdGhlIG5leHQgZXZlbnQuCi0gICAgICAgIC8vIFRoZSBuZXh0IGV2ZW50IG9uIHRoZSBpbnB1dCBzdHJlYW0gc2hvdWxkIGJlCi0gICAgICAgIC8vIFhNTFN0cmVhbUNvbnN0YW50cy5TVEFSVF9ET0NVTUVOVCBvcgotICAgICAgICAvLyBYTUxTdHJlYW1Db25zdGFudHMuU1RBUlRfRUxFTUVOVC4KLSAgICAgICAgWE1MRXZlbnQgZXZlbnQgPSB4bWxFdmVudFJlYWRlci5wZWVrKCk7Ci0gICAgICAgIGludCBldmVudFR5cGUgPSBldmVudC5nZXRFdmVudFR5cGUoKTsKLSAgICAgICAgaWYgKGV2ZW50VHlwZSAhPSBYTUxTdHJlYW1Db25zdGFudHMuU1RBUlRfRE9DVU1FTlQKLSAgICAgICAgICAgICAgICAmJiBldmVudFR5cGUgIT0gWE1MU3RyZWFtQ29uc3RhbnRzLlNUQVJUX0VMRU1FTlQpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgIlN0QVhTb3VyY2UoWE1MRXZlbnRSZWFkZXIpIHdpdGggWE1MRXZlbnRSZWFkZXIgIgotICAgICAgICAgICAgICAgICsgIm5vdCBpbiBYTUxTdHJlYW1Db25zdGFudHMuU1RBUlRfRE9DVU1FTlQgb3IgIgotICAgICAgICAgICAgICAgICsgIlhNTFN0cmVhbUNvbnN0YW50cy5TVEFSVF9FTEVNRU5UIHN0YXRlIik7Ci0gICAgICAgIH0KLQotICAgICAgICB0aGlzLnhtbEV2ZW50UmVhZGVyID0geG1sRXZlbnRSZWFkZXI7Ci0gICAgICAgIHN5c3RlbUlkID0gZXZlbnQuZ2V0TG9jYXRpb24oKS5nZXRTeXN0ZW1JZCgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPkNyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgYSA8Y29kZT5TdEFYU291cmNlPC9jb2RlPgotICAgICAqIGJ5IHN1cHBseWluZyBhbiB7QGxpbmsgWE1MU3RyZWFtUmVhZGVyfS48L3A+Ci0gICAgICoKLSAgICAgKiA8cD48Y29kZT5YTUxTdHJlYW1SZWFkZXI8L2NvZGU+IG11c3QgYmUgYQotICAgICAqIG5vbi08Y29kZT5udWxsPC9jb2RlPiByZWZlcmVuY2UuPC9wPgotICAgICAqCi0gICAgICogPHA+PGNvZGU+WE1MU3RyZWFtUmVhZGVyPC9jb2RlPiBtdXN0IGJlIGluCi0gICAgICoge0BsaW5rIFhNTFN0cmVhbUNvbnN0YW50cyNTVEFSVF9ET0NVTUVOVH0gb3IKLSAgICAgKiB7QGxpbmsgWE1MU3RyZWFtQ29uc3RhbnRzI1NUQVJUX0VMRU1FTlR9IHN0YXRlLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSB4bWxTdHJlYW1SZWFkZXIgPGNvZGU+WE1MU3RyZWFtUmVhZGVyPC9jb2RlPiB1c2VkIHRvIGNyZWF0ZQotICAgICAqICAgdGhpcyA8Y29kZT5TdEFYU291cmNlPC9jb2RlPi4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIElmIDxjb2RlPnhtbFN0cmVhbVJlYWRlcjwvY29kZT4gPT0KLSAgICAgKiAgIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIElmIDxjb2RlPnhtbFN0cmVhbVJlYWRlcjwvY29kZT4KLSAgICAgKiAgIGlzIG5vdCBpbiA8Y29kZT5YTUxTdHJlYW1Db25zdGFudHMuU1RBUlRfRE9DVU1FTlQ8L2NvZGU+IG9yCi0gICAgICogICA8Y29kZT5YTUxTdHJlYW1Db25zdGFudHMuU1RBUlRfRUxFTUVOVDwvY29kZT4gc3RhdGUuCi0gICAgICovCi0gICAgcHVibGljIFN0QVhTb3VyY2UoZmluYWwgWE1MU3RyZWFtUmVhZGVyIHhtbFN0cmVhbVJlYWRlcikgewotCi0gICAgICAgIGlmICh4bWxTdHJlYW1SZWFkZXIgPT0gbnVsbCkgewotICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgIlN0QVhTb3VyY2UoWE1MU3RyZWFtUmVhZGVyKSB3aXRoIFhNTFN0cmVhbVJlYWRlciA9PSBudWxsIik7Ci0gICAgICAgIH0KLQotICAgICAgICBpbnQgZXZlbnRUeXBlID0geG1sU3RyZWFtUmVhZGVyLmdldEV2ZW50VHlwZSgpOwotICAgICAgICBpZiAoZXZlbnRUeXBlICE9IFhNTFN0cmVhbUNvbnN0YW50cy5TVEFSVF9ET0NVTUVOVAotICAgICAgICAgICAgICAgICYmIGV2ZW50VHlwZSAhPSBYTUxTdHJlYW1Db25zdGFudHMuU1RBUlRfRUxFTUVOVCkgewotICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgIlN0QVhTb3VyY2UoWE1MU3RyZWFtUmVhZGVyKSB3aXRoIFhNTFN0cmVhbVJlYWRlciIKLSAgICAgICAgICAgICAgICAgICAgKyAibm90IGluIFhNTFN0cmVhbUNvbnN0YW50cy5TVEFSVF9ET0NVTUVOVCBvciAiCi0gICAgICAgICAgICAgICAgICAgICsgIlhNTFN0cmVhbUNvbnN0YW50cy5TVEFSVF9FTEVNRU5UIHN0YXRlIik7Ci0gICAgICAgIH0KLQotICAgICAgICB0aGlzLnhtbFN0cmVhbVJlYWRlciA9IHhtbFN0cmVhbVJlYWRlcjsKLSAgICAgICAgc3lzdGVtSWQgPSB4bWxTdHJlYW1SZWFkZXIuZ2V0TG9jYXRpb24oKS5nZXRTeXN0ZW1JZCgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPkdldCB0aGUgPGNvZGU+WE1MRXZlbnRSZWFkZXI8L2NvZGU+IHVzZWQgYnkgdGhpcwotICAgICAqIDxjb2RlPlN0QVhTb3VyY2U8L2NvZGU+LjwvcD4KLSAgICAgKgotICAgICAqIDxwPjxjb2RlPlhNTEV2ZW50UmVhZGVyPC9jb2RlPiB3aWxsIGJlIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAqIGlmIHRoaXMgPGNvZGU+U3RBWFNvdXJjZTwvY29kZT4gd2FzIGNyZWF0ZWQgd2l0aCBhCi0gICAgICogPGNvZGU+WE1MU3RyZWFtUmVhZGVyPC9jb2RlPi48L3A+Ci0gICAgICoKLSAgICAgKiBAcmV0dXJuIDxjb2RlPlhNTEV2ZW50UmVhZGVyPC9jb2RlPiB1c2VkIGJ5IHRoaXMKLSAgICAgKiAgIDxjb2RlPlN0QVhTb3VyY2U8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBYTUxFdmVudFJlYWRlciBnZXRYTUxFdmVudFJlYWRlcigpIHsKLQotICAgICAgICByZXR1cm4geG1sRXZlbnRSZWFkZXI7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+R2V0IHRoZSA8Y29kZT5YTUxTdHJlYW1SZWFkZXI8L2NvZGU+IHVzZWQgYnkgdGhpcwotICAgICAqIDxjb2RlPlN0QVhTb3VyY2U8L2NvZGU+LjwvcD4KLSAgICAgKgotICAgICAqIDxwPjxjb2RlPlhNTFN0cmVhbVJlYWRlcjwvY29kZT4gd2lsbCBiZSA8Y29kZT5udWxsPC9jb2RlPgotICAgICAqIGlmIHRoaXMgPGNvZGU+U3RBWFNvdXJjZTwvY29kZT4gd2FzIGNyZWF0ZWQgd2l0aCBhCi0gICAgICogPGNvZGU+WE1MRXZlbnRSZWFkZXI8L2NvZGU+LjwvcD4KLSAgICAgKgotICAgICAqIEByZXR1cm4gPGNvZGU+WE1MU3RyZWFtUmVhZGVyPC9jb2RlPiB1c2VkIGJ5IHRoaXMKLSAgICAgKiAgIDxjb2RlPlN0QVhTb3VyY2U8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBYTUxTdHJlYW1SZWFkZXIgZ2V0WE1MU3RyZWFtUmVhZGVyKCkgewotCi0gICAgICAgIHJldHVybiB4bWxTdHJlYW1SZWFkZXI7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+SW4gdGhlIGNvbnRleHQgb2YgYSA8Y29kZT5TdEFYU291cmNlPC9jb2RlPiwgaXQgaXMgbm90IGFwcHJvcHJpYXRlCi0gICAgICogdG8gZXhwbGljaXRseSBzZXQgdGhlIHN5c3RlbSBpZGVudGlmaWVyLgotICAgICAqIFRoZSA8Y29kZT5YTUxTdHJlYW1SZWFkZXI8L2NvZGU+IG9yIDxjb2RlPlhNTEV2ZW50UmVhZGVyPC9jb2RlPgotICAgICAqIHVzZWQgdG8gY29uc3RydWN0IHRoaXMgPGNvZGU+U3RBWFNvdXJjZTwvY29kZT4gZGV0ZXJtaW5lcyB0aGUKLSAgICAgKiBzeXN0ZW0gaWRlbnRpZmllciBvZiB0aGUgWE1MIHNvdXJjZS48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5BbiB7QGxpbmsgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb259IGlzIDxzdHJvbmc+YWx3YXlzPC9zdHJvbmc+Ci0gICAgICogdGhyb3duIGJ5IHRoaXMgbWV0aG9kLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzeXN0ZW1JZCBJZ25vcmVkLgotICAgICAqCi0gICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBJcyA8c3Ryb25nPmFsd2F5czwvc3Ryb25nPgotICAgICAqICAgdGhyb3duIGJ5IHRoaXMgbWV0aG9kLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFN5c3RlbUlkKGZpbmFsIFN0cmluZyBzeXN0ZW1JZCkgewotCi0gICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAiU3RBWFNvdXJjZSNzZXRTeXN0ZW1JZChzeXN0ZW1JZCkgY2Fubm90IHNldCB0aGUgIgotICAgICAgICAgICAgICAgICsgInN5c3RlbSBpZGVudGlmaWVyIGZvciBhIFN0QVhTb3VyY2UiKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5HZXQgdGhlIHN5c3RlbSBpZGVudGlmaWVyIHVzZWQgYnkgdGhpcwotICAgICAqIDxjb2RlPlN0QVhTb3VyY2U8L2NvZGU+LjwvcD4KLSAgICAgKgotICAgICAqIDxwPlRoZSA8Y29kZT5YTUxTdHJlYW1SZWFkZXI8L2NvZGU+IG9yIDxjb2RlPlhNTEV2ZW50UmVhZGVyPC9jb2RlPgotICAgICAqIHVzZWQgdG8gY29uc3RydWN0IHRoaXMgPGNvZGU+U3RBWFNvdXJjZTwvY29kZT4gaXMgcXVlcmllZCB0byBkZXRlcm1pbmUKLSAgICAgKiB0aGUgc3lzdGVtIGlkZW50aWZpZXIgb2YgdGhlIFhNTCBzb3VyY2UuPC9wPgotICAgICAqCi0gICAgICogPHA+VGhlIHN5c3RlbSBpZGVudGlmaWVyIG1heSBiZSA8Y29kZT5udWxsPC9jb2RlPiBvcgotICAgICAqIGFuIGVtcHR5IDxjb2RlPiIiPC9jb2RlPiA8Y29kZT5TdHJpbmc8L2NvZGU+LjwvcD4KLSAgICAgKgotICAgICAqIEByZXR1cm4gU3lzdGVtIGlkZW50aWZpZXIgdXNlZCBieSB0aGlzIDxjb2RlPlN0QVhTb3VyY2U8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3lzdGVtSWQoKSB7Ci0KLSAgICAgICAgcmV0dXJuIHN5c3RlbUlkOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9qYXZheC94bWwvdHJhbnNmb3JtL3N0YXgvcGFja2FnZS5odG1sIGIvc3JjL2phdmF4L3htbC90cmFuc2Zvcm0vc3RheC9wYWNrYWdlLmh0bWwKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGQwN2UwMzcuLjAwMDAwMDAKLS0tIGEvc3JjL2phdmF4L3htbC90cmFuc2Zvcm0vc3RheC9wYWNrYWdlLmh0bWwKKysrIC9kZXYvbnVsbApAQCAtMSw3MyArMCwwIEBACi08P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJVVEYtOCI/PgotPCEtLQotCi1Db3B5cmlnaHQgKGMpIDIwMDUsIDIwMDYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi1ETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0KLVRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci11bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi1wYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi1ieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLQotVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi1BTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLUZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLWFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0KLVlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLTIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLUluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLQotUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLW9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLXF1ZXN0aW9ucy4gCi0KLS0tPgotCi08IURPQ1RZUEUgaHRtbAotICAgICBQVUJMSUMgIi0vL1czQy8vRFREIFhIVE1MIDEuMCBTdHJpY3QvL0VOIgotICAgICAiaHR0cDovL3d3dy53My5vcmcvVFIveGh0bWwxL0RURC94aHRtbDEtc3RyaWN0LmR0ZCI+Ci0KLTxodG1sIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sIj4KLQk8aGVhZD4KLQkJPHRpdGxlPmphdmF4LnhtbC50cmFuc2Zvcm0uc3RheDwvdGl0bGU+Ci0KLQkJPG1ldGEgbmFtZT0iQ1ZTIgotCQkJY29udGVudD0iJElkOiBwYWNrYWdlLmh0bWwsdiAxLjIgMjAwNS8xMS8wMyAxOTozNDoyOCBqZWZmc3V0dG9yIEV4cCAkIiAvPgotCQk8bWV0YSBuYW1lPSJBVVRIT1IiCi0JCQljb250ZW50PSJKZWZmLlN1dHRvckBTdW4uY29tIiAvPgotCQk8bWV0YSBuYW1lPSJBVVRIT1IiCi0JCQljb250ZW50PSJOZWVyYWouQmFqYWpAU3VuLmNvbSIgLz4KLQk8L2hlYWQ+Ci0JPGJvZHk+Ci0JCTxwPgotCQkJUHJvdmlkZXMgZm9yIFN0QVgtc3BlY2lmaWMgdHJhbnNmb3JtYXRpb24gQVBJcy4KLQkJCVRPRE86IGJldHRlciBkZXNjcmlwdGlvbihzKS4KLQkJPC9wPgotCi0JCTxoMj5QYWNrYWdlIFNwZWNpZmljYXRpb248L2gyPgotCQk8dWw+Ci0JCQk8bGk+PGEgaHJlZj0iaHR0cDovL2pjcC5vcmcvZW4vanNyL2RldGFpbD9pZD0xNzMiPkpTUiAxNzM6IFN0cmVhbWluZyBBUEkgZm9yIFhNTDwvYT48L2xpPgotCQk8L3VsPgotCi0JCTxoMj5SZWxhdGVkIERvY3VtZW50YXRpb248L2gyPgotCi0JCTxwPkZvciBvdmVydmlld3MsIHR1dG9yaWFscywgZXhhbXBsZXMsIGd1aWRlcywgYW5kIHRvb2wgZG9jdW1lbnRhdGlvbiwgcGxlYXNlIHNlZTo8L3A+Ci0JCTx1bD4KLQkJCTxsaT48YSBocmVmPSIiPlRPRE86IFJlZmVyIHRvIG5vbi1zcGVjIGRvY3VtZW50YXRpb248L2E+PC9saT4KLQkJPC91bD4KLQotCQk8IS0tIFB1dCBAc2VlIGFuZCBAc2luY2UgdGFncyBkb3duIGhlcmUuIC0tPgotCQk8dWw+Ci0JCQk8bGk+QHNlZSBYTUxTdHJlYW1SZWFkZXI8L2xpPgotCQkJPGxpPkBzZWUgWE1MRXZlbnRSZWFkZXI8L2xpPgotCQk8L3VsPgotCQkKLQkJPHA+Ci0JCQlAc2luY2UgMS42Ci0JCTwvcD4KLQotCTwvYm9keT4KLTwvaHRtbD4KZGlmZiAtLWdpdCBhL3NyYy9qYXZheC94bWwvdHJhbnNmb3JtL3N0cmVhbS9TdHJlYW1SZXN1bHQuamF2YSBiL3NyYy9qYXZheC94bWwvdHJhbnNmb3JtL3N0cmVhbS9TdHJlYW1SZXN1bHQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMzlkZjI1My4uMDAwMDAwMAotLS0gYS9zcmMvamF2YXgveG1sL3RyYW5zZm9ybS9zdHJlYW0vU3RyZWFtUmVzdWx0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMDMgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwMCwgMjAwNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotcGFja2FnZSBqYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbTsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uUmVzdWx0OwotCi1pbXBvcnQgamF2YS5pby5GaWxlOwotaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uV3JpdGVyOwotaW1wb3J0IGphdmEubmV0Lk1hbGZvcm1lZFVSTEV4Y2VwdGlvbjsKLQotLyoqCi0gKiA8cD5BY3RzIGFzIGFuIGhvbGRlciBmb3IgYSB0cmFuc2Zvcm1hdGlvbiByZXN1bHQsCi0gKiB3aGljaCBtYXkgYmUgWE1MLCBwbGFpbiBUZXh0LCBIVE1MLCBvciBzb21lIG90aGVyIGZvcm0gb2YgbWFya3VwLjwvcD4KLSAqCi0gKiBAYXV0aG9yIDxhIGhyZWY9IkplZmYuU3V0dG9yQFN1bi5jb20iPkplZmYgU3V0dG9yPC9hPgotICovCi1wdWJsaWMgY2xhc3MgU3RyZWFtUmVzdWx0IGltcGxlbWVudHMgUmVzdWx0IHsKLQotICAgIC8qKiBJZiB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckZhY3RvcnkjZ2V0RmVhdHVyZX0KLSAgICAgKiByZXR1cm5zIHRydWUgd2hlbiBwYXNzZWQgdGhpcyB2YWx1ZSBhcyBhbiBhcmd1bWVudCwKLSAgICAgKiB0aGUgVHJhbnNmb3JtZXIgc3VwcG9ydHMgUmVzdWx0IG91dHB1dCBvZiB0aGlzIHR5cGUuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRkVBVFVSRSA9Ci0gICAgICAgICJodHRwOi8vamF2YXgueG1sLnRyYW5zZm9ybS5zdHJlYW0uU3RyZWFtUmVzdWx0L2ZlYXR1cmUiOwotCi0gICAgLyoqCi0gICAgICogWmVyby1hcmd1bWVudCBkZWZhdWx0IGNvbnN0cnVjdG9yLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJlYW1SZXN1bHQoKSB7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0IGEgU3RyZWFtUmVzdWx0IGZyb20gYSBieXRlIHN0cmVhbS4gIE5vcm1hbGx5LAotICAgICAqIGEgc3RyZWFtIHNob3VsZCBiZSB1c2VkIHJhdGhlciB0aGFuIGEgcmVhZGVyLCBzbyB0aGF0Ci0gICAgICogdGhlIHRyYW5zZm9ybWVyIG1heSB1c2UgaW5zdHJ1Y3Rpb25zIGNvbnRhaW5lZCBpbiB0aGUKLSAgICAgKiB0cmFuc2Zvcm1hdGlvbiBpbnN0cnVjdGlvbnMgdG8gY29udHJvbCB0aGUgZW5jb2RpbmcuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gb3V0cHV0U3RyZWFtIEEgdmFsaWQgT3V0cHV0U3RyZWFtIHJlZmVyZW5jZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyZWFtUmVzdWx0KE91dHB1dFN0cmVhbSBvdXRwdXRTdHJlYW0pIHsKLSAgICAgICAgc2V0T3V0cHV0U3RyZWFtKG91dHB1dFN0cmVhbSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0IGEgU3RyZWFtUmVzdWx0IGZyb20gYSBjaGFyYWN0ZXIgc3RyZWFtLiAgTm9ybWFsbHksCi0gICAgICogYSBzdHJlYW0gc2hvdWxkIGJlIHVzZWQgcmF0aGVyIHRoYW4gYSByZWFkZXIsIHNvIHRoYXQKLSAgICAgKiB0aGUgdHJhbnNmb3JtZXIgbWF5IHVzZSBpbnN0cnVjdGlvbnMgY29udGFpbmVkIGluIHRoZQotICAgICAqIHRyYW5zZm9ybWF0aW9uIGluc3RydWN0aW9ucyB0byBjb250cm9sIHRoZSBlbmNvZGluZy4gIEhvd2V2ZXIsCi0gICAgICogdGhlcmUgYXJlIHRpbWVzIHdoZW4gaXQgaXMgdXNlZnVsIHRvIHdyaXRlIHRvIGEgY2hhcmFjdGVyCi0gICAgICogc3RyZWFtLCBzdWNoIGFzIHdoZW4gdXNpbmcgYSBTdHJpbmdXcml0ZXIuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gd3JpdGVyICBBIHZhbGlkIFdyaXRlciByZWZlcmVuY2UuCi0gICAgICovCi0gICAgcHVibGljIFN0cmVhbVJlc3VsdChXcml0ZXIgd3JpdGVyKSB7Ci0gICAgICAgIHNldFdyaXRlcih3cml0ZXIpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdCBhIFN0cmVhbVJlc3VsdCBmcm9tIGEgVVJMLgotICAgICAqCi0gICAgICogQHBhcmFtIHN5c3RlbUlkIE11c3QgYmUgYSBTdHJpbmcgdGhhdCBjb25mb3JtcyB0byB0aGUgVVJJIHN5bnRheC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyZWFtUmVzdWx0KFN0cmluZyBzeXN0ZW1JZCkgewotICAgICAgICB0aGlzLnN5c3RlbUlkID0gc3lzdGVtSWQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0IGEgU3RyZWFtUmVzdWx0IGZyb20gYSBGaWxlLgotICAgICAqCi0gICAgICogQHBhcmFtIGYgTXVzdCBhIG5vbi1udWxsIEZpbGUgcmVmZXJlbmNlLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJlYW1SZXN1bHQoRmlsZSBmKSB7Ci0gICAgICAgIC8vY29udmVydCBmaWxlIHRvIGFwcHJvcHJpYXRlIFVSSSwgZi50b1VSSSgpLnRvQVNDSUlTdHJpbmcoKQotICAgICAgICAvL2NvbnZlcnRzIHRoZSBVUkkgdG8gc3RyaW5nIGFzIHBlciBydWxlIHNwZWNpZmllZCBpbgotICAgICAgICAvL1JGQyAyMzk2LAotICAgICAgICBzZXRTeXN0ZW1JZChmLnRvVVJJKCkudG9BU0NJSVN0cmluZygpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIEJ5dGVTdHJlYW0gdGhhdCBpcyB0byBiZSB3cml0dGVuIHRvLiAgTm9ybWFsbHksCi0gICAgICogYSBzdHJlYW0gc2hvdWxkIGJlIHVzZWQgcmF0aGVyIHRoYW4gYSByZWFkZXIsIHNvIHRoYXQKLSAgICAgKiB0aGUgdHJhbnNmb3JtZXIgbWF5IHVzZSBpbnN0cnVjdGlvbnMgY29udGFpbmVkIGluIHRoZQotICAgICAqIHRyYW5zZm9ybWF0aW9uIGluc3RydWN0aW9ucyB0byBjb250cm9sIHRoZSBlbmNvZGluZy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBvdXRwdXRTdHJlYW0gQSB2YWxpZCBPdXRwdXRTdHJlYW0gcmVmZXJlbmNlLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldE91dHB1dFN0cmVhbShPdXRwdXRTdHJlYW0gb3V0cHV0U3RyZWFtKSB7Ci0gICAgICAgIHRoaXMub3V0cHV0U3RyZWFtID0gb3V0cHV0U3RyZWFtOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgYnl0ZSBzdHJlYW0gdGhhdCB3YXMgc2V0IHdpdGggc2V0T3V0cHV0U3RyZWFtLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgYnl0ZSBzdHJlYW0gdGhhdCB3YXMgc2V0IHdpdGggc2V0T3V0cHV0U3RyZWFtLCBvciBudWxsCi0gICAgICogaWYgc2V0T3V0cHV0U3RyZWFtIG9yIHRoZSBCeXRlU3RyZWFtIGNvbnN0cnVjdG9yIHdhcyBub3QgY2FsbGVkLgotICAgICAqLwotICAgIHB1YmxpYyBPdXRwdXRTdHJlYW0gZ2V0T3V0cHV0U3RyZWFtKCkgewotICAgICAgICByZXR1cm4gb3V0cHV0U3RyZWFtOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldCB0aGUgd3JpdGVyIHRoYXQgaXMgdG8gcmVjZWl2ZSB0aGUgcmVzdWx0LiAgTm9ybWFsbHksCi0gICAgICogYSBzdHJlYW0gc2hvdWxkIGJlIHVzZWQgcmF0aGVyIHRoYW4gYSB3cml0ZXIsIHNvIHRoYXQKLSAgICAgKiB0aGUgdHJhbnNmb3JtZXIgbWF5IHVzZSBpbnN0cnVjdGlvbnMgY29udGFpbmVkIGluIHRoZQotICAgICAqIHRyYW5zZm9ybWF0aW9uIGluc3RydWN0aW9ucyB0byBjb250cm9sIHRoZSBlbmNvZGluZy4gIEhvd2V2ZXIsCi0gICAgICogdGhlcmUgYXJlIHRpbWVzIHdoZW4gaXQgaXMgdXNlZnVsIHRvIHdyaXRlIHRvIGEgd3JpdGVyLAotICAgICAqIHN1Y2ggYXMgd2hlbiB1c2luZyBhIFN0cmluZ1dyaXRlci4KLSAgICAgKgotICAgICAqIEBwYXJhbSB3cml0ZXIgIEEgdmFsaWQgV3JpdGVyIHJlZmVyZW5jZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRXcml0ZXIoV3JpdGVyIHdyaXRlcikgewotICAgICAgICB0aGlzLndyaXRlciA9IHdyaXRlcjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIGNoYXJhY3RlciBzdHJlYW0gdGhhdCB3YXMgc2V0IHdpdGggc2V0V3JpdGVyLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgY2hhcmFjdGVyIHN0cmVhbSB0aGF0IHdhcyBzZXQgd2l0aCBzZXRXcml0ZXIsIG9yIG51bGwKLSAgICAgKiBpZiBzZXRXcml0ZXIgb3IgdGhlIFdyaXRlciBjb25zdHJ1Y3RvciB3YXMgbm90IGNhbGxlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgV3JpdGVyIGdldFdyaXRlcigpIHsKLSAgICAgICAgcmV0dXJuIHdyaXRlcjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIHN5c3RlbUlEIHRoYXQgbWF5IGJlIHVzZWQgaW4gYXNzb2NpYXRpb24KLSAgICAgKiB3aXRoIHRoZSBieXRlIG9yIGNoYXJhY3RlciBzdHJlYW0sIG9yLCBpZiBuZWl0aGVyIGlzIHNldCwgdXNlCi0gICAgICogdGhpcyB2YWx1ZSBhcyBhIHdyaXRlYWJsZSBVUkkgKHByb2JhYmx5IGEgZmlsZSBuYW1lKS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzeXN0ZW1JZCBUaGUgc3lzdGVtIGlkZW50aWZpZXIgYXMgYSBVUkkgc3RyaW5nLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFN5c3RlbUlkKFN0cmluZyBzeXN0ZW1JZCkgewotICAgICAgICB0aGlzLnN5c3RlbUlkID0gc3lzdGVtSWQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+U2V0IHRoZSBzeXN0ZW0gSUQgZnJvbSBhIDxjb2RlPkZpbGU8L2NvZGU+IHJlZmVyZW5jZS48L3A+Ci0gICAgICoKLSAgICAgKgotICAgICAqIEBwYXJhbSBmIE11c3QgYSBub24tbnVsbCBGaWxlIHJlZmVyZW5jZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRTeXN0ZW1JZChGaWxlIGYpIHsKLSAgICAgICAgLy9jb252ZXJ0IGZpbGUgdG8gYXBwcm9wcmlhdGUgVVJJLCBmLnRvVVJJKCkudG9BU0NJSVN0cmluZygpCi0gICAgICAgIC8vY29udmVydHMgdGhlIFVSSSB0byBzdHJpbmcgYXMgcGVyIHJ1bGUgc3BlY2lmaWVkIGluCi0gICAgICAgIC8vUkZDIDIzOTYsCi0gICAgICAgIHRoaXMuc3lzdGVtSWQgPSBmLnRvVVJJKCkudG9BU0NJSVN0cmluZygpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgc3lzdGVtIGlkZW50aWZpZXIgdGhhdCB3YXMgc2V0IHdpdGggc2V0U3lzdGVtSWQuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBzeXN0ZW0gaWRlbnRpZmllciB0aGF0IHdhcyBzZXQgd2l0aCBzZXRTeXN0ZW1JZCwgb3IgbnVsbAotICAgICAqIGlmIHNldFN5c3RlbUlkIHdhcyBub3QgY2FsbGVkLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3lzdGVtSWQoKSB7Ci0gICAgICAgIHJldHVybiBzeXN0ZW1JZDsKLSAgICB9Ci0KLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0gICAgLy8gSW50ZXJuYWwgc3RhdGUuCi0gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotCi0gICAgLyoqCi0gICAgICogVGhlIHN5c3RlbUlEIHRoYXQgbWF5IGJlIHVzZWQgaW4gYXNzb2NpYXRpb24KLSAgICAgKiB3aXRoIHRoZSBieXRlIG9yIGNoYXJhY3RlciBzdHJlYW0sIG9yLCBpZiBuZWl0aGVyIGlzIHNldCwgdXNlCi0gICAgICogdGhpcyB2YWx1ZSBhcyBhIHdyaXRlYWJsZSBVUkkgKHByb2JhYmx5IGEgZmlsZSBuYW1lKS4KLSAgICAgKi8KLSAgICBwcml2YXRlIFN0cmluZyBzeXN0ZW1JZDsKLQotICAgIC8qKgotICAgICAqIFRoZSBieXRlIHN0cmVhbSB0aGF0IGlzIHRvIGJlIHdyaXR0ZW4gdG8uCi0gICAgICovCi0gICAgcHJpdmF0ZSBPdXRwdXRTdHJlYW0gb3V0cHV0U3RyZWFtOwotCi0gICAgLyoqCi0gICAgICogVGhlIGNoYXJhY3RlciBzdHJlYW0gdGhhdCBpcyB0byBiZSB3cml0dGVuIHRvLgotICAgICAqLwotICAgIHByaXZhdGUgV3JpdGVyIHdyaXRlcjsKLX0KZGlmZiAtLWdpdCBhL3NyYy9qYXZheC94bWwvdHJhbnNmb3JtL3N0cmVhbS9TdHJlYW1Tb3VyY2UuamF2YSBiL3NyYy9qYXZheC94bWwvdHJhbnNmb3JtL3N0cmVhbS9TdHJlYW1Tb3VyY2UuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYWQ0MWI5ZC4uMDAwMDAwMAotLS0gYS9zcmMvamF2YXgveG1sL3RyYW5zZm9ybS9zdHJlYW0vU3RyZWFtU291cmNlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyODQgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwMCwgMjAwNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotcGFja2FnZSBqYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbTsKLQotaW1wb3J0IGphdmEuaW8uRmlsZTsKLWltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uUmVhZGVyOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2U7Ci0KLS8qKgotICogPHA+QWN0cyBhcyBhbiBob2xkZXIgZm9yIGEgdHJhbnNmb3JtYXRpb24gU291cmNlIGluIHRoZSBmb3JtCi0gKiBvZiBhIHN0cmVhbSBvZiBYTUwgbWFya3VwLjwvcD4KLSAqCi0gKiA8cD48ZW0+Tm90ZTo8L2VtPiBEdWUgdG8gdGhlaXIgaW50ZXJuYWwgdXNlIG9mIGVpdGhlciBhIHtAbGluayBSZWFkZXJ9IG9yIHtAbGluayBJbnB1dFN0cmVhbX0gaW5zdGFuY2UsCi0gKiA8Y29kZT5TdHJlYW1Tb3VyY2U8L2NvZGU+IGluc3RhbmNlcyBtYXkgb25seSBiZSB1c2VkIG9uY2UuPC9wPgotICoKLSAqIEBhdXRob3IgPGEgaHJlZj0iSmVmZi5TdXR0b3JAU3VuLmNvbSI+SmVmZiBTdXR0b3I8L2E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBTdHJlYW1Tb3VyY2UgaW1wbGVtZW50cyBTb3VyY2UgewotCi0gICAgLyoqIElmIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRmFjdG9yeSNnZXRGZWF0dXJlfQotICAgICAqIHJldHVybnMgdHJ1ZSB3aGVuIHBhc3NlZCB0aGlzIHZhbHVlIGFzIGFuIGFyZ3VtZW50LAotICAgICAqIHRoZSBUcmFuc2Zvcm1lciBzdXBwb3J0cyBTb3VyY2UgaW5wdXQgb2YgdGhpcyB0eXBlLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEZFQVRVUkUgPQotICAgICAgICAiaHR0cDovL2phdmF4LnhtbC50cmFuc2Zvcm0uc3RyZWFtLlN0cmVhbVNvdXJjZS9mZWF0dXJlIjsKLQotICAgIC8qKgotICAgICAqIDxwPlplcm8tYXJndW1lbnQgZGVmYXVsdCBjb25zdHJ1Y3Rvci4gIElmIHRoaXMgY29uc3RydWN0b3IgaXMgdXNlZCwgYW5kCi0gICAgICogbm8gU3RyZWFtIHNvdXJjZSBpcyBzZXQgdXNpbmcKLSAgICAgKiB7QGxpbmsgI3NldElucHV0U3RyZWFtKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXRTdHJlYW0pfSBvcgotICAgICAqIHtAbGluayAjc2V0UmVhZGVyKGphdmEuaW8uUmVhZGVyIHJlYWRlcil9LCB0aGVuIHRoZQotICAgICAqIDxjb2RlPlRyYW5zZm9ybWVyPC9jb2RlPiB3aWxsCi0gICAgICogY3JlYXRlIGFuIGVtcHR5IHNvdXJjZSB7QGxpbmsgamF2YS5pby5JbnB1dFN0cmVhbX0gdXNpbmcKLSAgICAgKiB7QGxpbmsgamF2YS5pby5JbnB1dFN0cmVhbSNJbnB1dFN0cmVhbSgpIG5ldyBJbnB1dFN0cmVhbSgpfS48L3A+Ci0gICAgICoKLSAgICAgKiBAc2VlIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXIjdHJhbnNmb3JtKFNvdXJjZSB4bWxTb3VyY2UsIFJlc3VsdCBvdXRwdXRUYXJnZXQpCi0gICAgICovCi0gICAgcHVibGljIFN0cmVhbVNvdXJjZSgpIHsgfQotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0IGEgU3RyZWFtU291cmNlIGZyb20gYSBieXRlIHN0cmVhbS4gIE5vcm1hbGx5LAotICAgICAqIGEgc3RyZWFtIHNob3VsZCBiZSB1c2VkIHJhdGhlciB0aGFuIGEgcmVhZGVyLCBzbwotICAgICAqIHRoZSBYTUwgcGFyc2VyIGNhbiByZXNvbHZlIGNoYXJhY3RlciBlbmNvZGluZyBzcGVjaWZpZWQKLSAgICAgKiBieSB0aGUgWE1MIGRlY2xhcmF0aW9uLgotICAgICAqCi0gICAgICogPHA+SWYgdGhpcyBjb25zdHJ1Y3RvciBpcyB1c2VkIHRvIHByb2Nlc3MgYSBzdHlsZXNoZWV0LCBub3JtYWxseQotICAgICAqIHNldFN5c3RlbUlkIHNob3VsZCBhbHNvIGJlIGNhbGxlZCwgc28gdGhhdCByZWxhdGl2ZSBVUkkgcmVmZXJlbmNlcwotICAgICAqIGNhbiBiZSByZXNvbHZlZC48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gaW5wdXRTdHJlYW0gQSB2YWxpZCBJbnB1dFN0cmVhbSByZWZlcmVuY2UgdG8gYW4gWE1MIHN0cmVhbS4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyZWFtU291cmNlKElucHV0U3RyZWFtIGlucHV0U3RyZWFtKSB7Ci0gICAgICAgIHNldElucHV0U3RyZWFtKGlucHV0U3RyZWFtKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3QgYSBTdHJlYW1Tb3VyY2UgZnJvbSBhIGJ5dGUgc3RyZWFtLiAgTm9ybWFsbHksCi0gICAgICogYSBzdHJlYW0gc2hvdWxkIGJlIHVzZWQgcmF0aGVyIHRoYW4gYSByZWFkZXIsIHNvIHRoYXQKLSAgICAgKiB0aGUgWE1MIHBhcnNlciBjYW4gcmVzb2x2ZSBjaGFyYWN0ZXIgZW5jb2Rpbmcgc3BlY2lmaWVkCi0gICAgICogYnkgdGhlIFhNTCBkZWNsYXJhdGlvbi4KLSAgICAgKgotICAgICAqIDxwPlRoaXMgY29uc3RydWN0b3IgYWxsb3dzIHRoZSBzeXN0ZW1JRCB0byBiZSBzZXQgaW4gYWRkaXRpb24KLSAgICAgKiB0byB0aGUgaW5wdXQgc3RyZWFtLCB3aGljaCBhbGxvd3MgcmVsYXRpdmUgVVJJcwotICAgICAqIHRvIGJlIHByb2Nlc3NlZC48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gaW5wdXRTdHJlYW0gQSB2YWxpZCBJbnB1dFN0cmVhbSByZWZlcmVuY2UgdG8gYW4gWE1MIHN0cmVhbS4KLSAgICAgKiBAcGFyYW0gc3lzdGVtSWQgTXVzdCBiZSBhIFN0cmluZyB0aGF0IGNvbmZvcm1zIHRvIHRoZSBVUkkgc3ludGF4LgotICAgICAqLwotICAgIHB1YmxpYyBTdHJlYW1Tb3VyY2UoSW5wdXRTdHJlYW0gaW5wdXRTdHJlYW0sIFN0cmluZyBzeXN0ZW1JZCkgewotICAgICAgICBzZXRJbnB1dFN0cmVhbShpbnB1dFN0cmVhbSk7Ci0gICAgICAgIHNldFN5c3RlbUlkKHN5c3RlbUlkKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3QgYSBTdHJlYW1Tb3VyY2UgZnJvbSBhIGNoYXJhY3RlciByZWFkZXIuICBOb3JtYWxseSwKLSAgICAgKiBhIHN0cmVhbSBzaG91bGQgYmUgdXNlZCByYXRoZXIgdGhhbiBhIHJlYWRlciwgc28gdGhhdAotICAgICAqIHRoZSBYTUwgcGFyc2VyIGNhbiByZXNvbHZlIGNoYXJhY3RlciBlbmNvZGluZyBzcGVjaWZpZWQKLSAgICAgKiBieSB0aGUgWE1MIGRlY2xhcmF0aW9uLiAgSG93ZXZlciwgaW4gbWFueSBjYXNlcyB0aGUgZW5jb2RpbmcKLSAgICAgKiBvZiB0aGUgaW5wdXQgc3RyZWFtIGlzIGFscmVhZHkgcmVzb2x2ZWQsIGFzIGluIHRoZSBjYXNlIG9mCi0gICAgICogcmVhZGluZyBYTUwgZnJvbSBhIFN0cmluZ1JlYWRlci4KLSAgICAgKgotICAgICAqIEBwYXJhbSByZWFkZXIgQSB2YWxpZCBSZWFkZXIgcmVmZXJlbmNlIHRvIGFuIFhNTCBjaGFyYWN0ZXIgc3RyZWFtLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJlYW1Tb3VyY2UoUmVhZGVyIHJlYWRlcikgewotICAgICAgICBzZXRSZWFkZXIocmVhZGVyKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3QgYSBTdHJlYW1Tb3VyY2UgZnJvbSBhIGNoYXJhY3RlciByZWFkZXIuICBOb3JtYWxseSwKLSAgICAgKiBhIHN0cmVhbSBzaG91bGQgYmUgdXNlZCByYXRoZXIgdGhhbiBhIHJlYWRlciwgc28gdGhhdAotICAgICAqIHRoZSBYTUwgcGFyc2VyIG1heSByZXNvbHZlIGNoYXJhY3RlciBlbmNvZGluZyBzcGVjaWZpZWQKLSAgICAgKiBieSB0aGUgWE1MIGRlY2xhcmF0aW9uLiAgSG93ZXZlciwgaW4gbWFueSBjYXNlcyB0aGUgZW5jb2RpbmcKLSAgICAgKiBvZiB0aGUgaW5wdXQgc3RyZWFtIGlzIGFscmVhZHkgcmVzb2x2ZWQsIGFzIGluIHRoZSBjYXNlIG9mCi0gICAgICogcmVhZGluZyBYTUwgZnJvbSBhIFN0cmluZ1JlYWRlci4KLSAgICAgKgotICAgICAqIEBwYXJhbSByZWFkZXIgQSB2YWxpZCBSZWFkZXIgcmVmZXJlbmNlIHRvIGFuIFhNTCBjaGFyYWN0ZXIgc3RyZWFtLgotICAgICAqIEBwYXJhbSBzeXN0ZW1JZCBNdXN0IGJlIGEgU3RyaW5nIHRoYXQgY29uZm9ybXMgdG8gdGhlIFVSSSBzeW50YXguCi0gICAgICovCi0gICAgcHVibGljIFN0cmVhbVNvdXJjZShSZWFkZXIgcmVhZGVyLCBTdHJpbmcgc3lzdGVtSWQpIHsKLSAgICAgICAgc2V0UmVhZGVyKHJlYWRlcik7Ci0gICAgICAgIHNldFN5c3RlbUlkKHN5c3RlbUlkKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3QgYSBTdHJlYW1Tb3VyY2UgZnJvbSBhIFVSTC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzeXN0ZW1JZCBNdXN0IGJlIGEgU3RyaW5nIHRoYXQgY29uZm9ybXMgdG8gdGhlIFVSSSBzeW50YXguCi0gICAgICovCi0gICAgcHVibGljIFN0cmVhbVNvdXJjZShTdHJpbmcgc3lzdGVtSWQpIHsKLSAgICAgICAgdGhpcy5zeXN0ZW1JZCA9IHN5c3RlbUlkOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdCBhIFN0cmVhbVNvdXJjZSBmcm9tIGEgRmlsZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBmIE11c3QgYSBub24tbnVsbCBGaWxlIHJlZmVyZW5jZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyZWFtU291cmNlKEZpbGUgZikgewotICAgICAgICAvL2NvbnZlcnQgZmlsZSB0byBhcHByb3ByaWF0ZSBVUkksIGYudG9VUkkoKS50b0FTQ0lJU3RyaW5nKCkKLSAgICAgICAgLy9jb252ZXJ0cyB0aGUgVVJJIHRvIHN0cmluZyBhcyBwZXIgcnVsZSBzcGVjaWZpZWQgaW4KLSAgICAgICAgLy9SRkMgMjM5NiwKLSAgICAgICAgc2V0U3lzdGVtSWQoZi50b1VSSSgpLnRvQVNDSUlTdHJpbmcoKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSBieXRlIHN0cmVhbSB0byBiZSB1c2VkIGFzIGlucHV0LiAgTm9ybWFsbHksCi0gICAgICogYSBzdHJlYW0gc2hvdWxkIGJlIHVzZWQgcmF0aGVyIHRoYW4gYSByZWFkZXIsIHNvIHRoYXQKLSAgICAgKiB0aGUgWE1MIHBhcnNlciBjYW4gcmVzb2x2ZSBjaGFyYWN0ZXIgZW5jb2Rpbmcgc3BlY2lmaWVkCi0gICAgICogYnkgdGhlIFhNTCBkZWNsYXJhdGlvbi4KLSAgICAgKgotICAgICAqIDxwPklmIHRoaXMgU291cmNlIG9iamVjdCBpcyB1c2VkIHRvIHByb2Nlc3MgYSBzdHlsZXNoZWV0LCBub3JtYWxseQotICAgICAqIHNldFN5c3RlbUlkIHNob3VsZCBhbHNvIGJlIGNhbGxlZCwgc28gdGhhdCByZWxhdGl2ZSBVUkwgcmVmZXJlbmNlcwotICAgICAqIGNhbiBiZSByZXNvbHZlZC48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gaW5wdXRTdHJlYW0gQSB2YWxpZCBJbnB1dFN0cmVhbSByZWZlcmVuY2UgdG8gYW4gWE1MIHN0cmVhbS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRJbnB1dFN0cmVhbShJbnB1dFN0cmVhbSBpbnB1dFN0cmVhbSkgewotICAgICAgICB0aGlzLmlucHV0U3RyZWFtID0gaW5wdXRTdHJlYW07Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBieXRlIHN0cmVhbSB0aGF0IHdhcyBzZXQgd2l0aCBzZXRCeXRlU3RyZWFtLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgYnl0ZSBzdHJlYW0gdGhhdCB3YXMgc2V0IHdpdGggc2V0Qnl0ZVN0cmVhbSwgb3IgbnVsbAotICAgICAqIGlmIHNldEJ5dGVTdHJlYW0gb3IgdGhlIEJ5dGVTdHJlYW0gY29uc3RydWN0b3Igd2FzIG5vdCBjYWxsZWQuCi0gICAgICovCi0gICAgcHVibGljIElucHV0U3RyZWFtIGdldElucHV0U3RyZWFtKCkgewotICAgICAgICByZXR1cm4gaW5wdXRTdHJlYW07Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSBpbnB1dCB0byBiZSBhIGNoYXJhY3RlciByZWFkZXIuICBOb3JtYWxseSwKLSAgICAgKiBhIHN0cmVhbSBzaG91bGQgYmUgdXNlZCByYXRoZXIgdGhhbiBhIHJlYWRlciwgc28gdGhhdAotICAgICAqIHRoZSBYTUwgcGFyc2VyIGNhbiByZXNvbHZlIGNoYXJhY3RlciBlbmNvZGluZyBzcGVjaWZpZWQKLSAgICAgKiBieSB0aGUgWE1MIGRlY2xhcmF0aW9uLiAgSG93ZXZlciwgaW4gbWFueSBjYXNlcyB0aGUgZW5jb2RpbmcKLSAgICAgKiBvZiB0aGUgaW5wdXQgc3RyZWFtIGlzIGFscmVhZHkgcmVzb2x2ZWQsIGFzIGluIHRoZSBjYXNlIG9mCi0gICAgICogcmVhZGluZyBYTUwgZnJvbSBhIFN0cmluZ1JlYWRlci4KLSAgICAgKgotICAgICAqIEBwYXJhbSByZWFkZXIgQSB2YWxpZCBSZWFkZXIgcmVmZXJlbmNlIHRvIGFuIFhNTCBDaGFyYWN0ZXJTdHJlYW0uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0UmVhZGVyKFJlYWRlciByZWFkZXIpIHsKLSAgICAgICAgdGhpcy5yZWFkZXIgPSByZWFkZXI7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBjaGFyYWN0ZXIgc3RyZWFtIHRoYXQgd2FzIHNldCB3aXRoIHNldFJlYWRlci4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIGNoYXJhY3RlciBzdHJlYW0gdGhhdCB3YXMgc2V0IHdpdGggc2V0UmVhZGVyLCBvciBudWxsCi0gICAgICogaWYgc2V0UmVhZGVyIG9yIHRoZSBSZWFkZXIgY29uc3RydWN0b3Igd2FzIG5vdCBjYWxsZWQuCi0gICAgICovCi0gICAgcHVibGljIFJlYWRlciBnZXRSZWFkZXIoKSB7Ci0gICAgICAgIHJldHVybiByZWFkZXI7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSBwdWJsaWMgaWRlbnRpZmllciBmb3IgdGhpcyBTb3VyY2UuCi0gICAgICoKLSAgICAgKiA8cD5UaGUgcHVibGljIGlkZW50aWZpZXIgaXMgYWx3YXlzIG9wdGlvbmFsOiBpZiB0aGUgYXBwbGljYXRpb24KLSAgICAgKiB3cml0ZXIgaW5jbHVkZXMgb25lLCBpdCB3aWxsIGJlIHByb3ZpZGVkIGFzIHBhcnQgb2YgdGhlCi0gICAgICogbG9jYXRpb24gaW5mb3JtYXRpb24uPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIHB1YmxpY0lkIFRoZSBwdWJsaWMgaWRlbnRpZmllciBhcyBhIHN0cmluZy4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRQdWJsaWNJZChTdHJpbmcgcHVibGljSWQpIHsKLSAgICAgICAgdGhpcy5wdWJsaWNJZCA9IHB1YmxpY0lkOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgcHVibGljIGlkZW50aWZpZXIgdGhhdCB3YXMgc2V0IHdpdGggc2V0UHVibGljSWQuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBwdWJsaWMgaWRlbnRpZmllciB0aGF0IHdhcyBzZXQgd2l0aCBzZXRQdWJsaWNJZCwgb3IgbnVsbAotICAgICAqIGlmIHNldFB1YmxpY0lkIHdhcyBub3QgY2FsbGVkLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0UHVibGljSWQoKSB7Ci0gICAgICAgIHJldHVybiBwdWJsaWNJZDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIHN5c3RlbSBpZGVudGlmaWVyIGZvciB0aGlzIFNvdXJjZS4KLSAgICAgKgotICAgICAqIDxwPlRoZSBzeXN0ZW0gaWRlbnRpZmllciBpcyBvcHRpb25hbCBpZiB0aGVyZSBpcyBhIGJ5dGUgc3RyZWFtCi0gICAgICogb3IgYSBjaGFyYWN0ZXIgc3RyZWFtLCBidXQgaXQgaXMgc3RpbGwgdXNlZnVsIHRvIHByb3ZpZGUgb25lLAotICAgICAqIHNpbmNlIHRoZSBhcHBsaWNhdGlvbiBjYW4gdXNlIGl0IHRvIHJlc29sdmUgcmVsYXRpdmUgVVJJcwotICAgICAqIGFuZCBjYW4gaW5jbHVkZSBpdCBpbiBlcnJvciBtZXNzYWdlcyBhbmQgd2FybmluZ3MgKHRoZSBwYXJzZXIKLSAgICAgKiB3aWxsIGF0dGVtcHQgdG8gb3BlbiBhIGNvbm5lY3Rpb24gdG8gdGhlIFVSSSBvbmx5IGlmCi0gICAgICogdGhlcmUgaXMgbm8gYnl0ZSBzdHJlYW0gb3IgY2hhcmFjdGVyIHN0cmVhbSBzcGVjaWZpZWQpLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzeXN0ZW1JZCBUaGUgc3lzdGVtIGlkZW50aWZpZXIgYXMgYSBVUkwgc3RyaW5nLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFN5c3RlbUlkKFN0cmluZyBzeXN0ZW1JZCkgewotICAgICAgICB0aGlzLnN5c3RlbUlkID0gc3lzdGVtSWQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBzeXN0ZW0gaWRlbnRpZmllciB0aGF0IHdhcyBzZXQgd2l0aCBzZXRTeXN0ZW1JZC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIHN5c3RlbSBpZGVudGlmaWVyIHRoYXQgd2FzIHNldCB3aXRoIHNldFN5c3RlbUlkLCBvciBudWxsCi0gICAgICogaWYgc2V0U3lzdGVtSWQgd2FzIG5vdCBjYWxsZWQuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRTeXN0ZW1JZCgpIHsKLSAgICAgICAgcmV0dXJuIHN5c3RlbUlkOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldCB0aGUgc3lzdGVtIElEIGZyb20gYSBGaWxlIHJlZmVyZW5jZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBmIE11c3QgYSBub24tbnVsbCBGaWxlIHJlZmVyZW5jZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRTeXN0ZW1JZChGaWxlIGYpIHsKLSAgICAgICAgLy9jb252ZXJ0IGZpbGUgdG8gYXBwcm9wcmlhdGUgVVJJLCBmLnRvVVJJKCkudG9BU0NJSVN0cmluZygpCi0gICAgICAgIC8vY29udmVydHMgdGhlIFVSSSB0byBzdHJpbmcgYXMgcGVyIHJ1bGUgc3BlY2lmaWVkIGluCi0gICAgICAgIC8vUkZDIDIzOTYsCi0gICAgICAgIHRoaXMuc3lzdGVtSWQgPSBmLnRvVVJJKCkudG9BU0NJSVN0cmluZygpOwotICAgIH0KLQotICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLSAgICAvLyBJbnRlcm5hbCBzdGF0ZS4KLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0KLSAgICAvKioKLSAgICAgKiBUaGUgcHVibGljIGlkZW50aWZpZXIgZm9yIHRoaXMgaW5wdXQgc291cmNlLCBvciBudWxsLgotICAgICAqLwotICAgIHByaXZhdGUgU3RyaW5nIHB1YmxpY0lkOwotCi0gICAgLyoqCi0gICAgICogVGhlIHN5c3RlbSBpZGVudGlmaWVyIGFzIGEgVVJMIHN0cmluZywgb3IgbnVsbC4KLSAgICAgKi8KLSAgICBwcml2YXRlIFN0cmluZyBzeXN0ZW1JZDsKLQotICAgIC8qKgotICAgICAqIFRoZSBieXRlIHN0cmVhbSBmb3IgdGhpcyBTb3VyY2UsIG9yIG51bGwuCi0gICAgICovCi0gICAgcHJpdmF0ZSBJbnB1dFN0cmVhbSBpbnB1dFN0cmVhbTsKLQotICAgIC8qKgotICAgICAqIFRoZSBjaGFyYWN0ZXIgc3RyZWFtIGZvciB0aGlzIFNvdXJjZSwgb3IgbnVsbC4KLSAgICAgKi8KLSAgICBwcml2YXRlIFJlYWRlciByZWFkZXI7Ci19CmRpZmYgLS1naXQgYS9zcmMvamF2YXgveG1sL3RyYW5zZm9ybS9zdHJlYW0vcGFja2FnZS5odG1sIGIvc3JjL2phdmF4L3htbC90cmFuc2Zvcm0vc3RyZWFtL3BhY2thZ2UuaHRtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZWE1MmVjYi4uMDAwMDAwMAotLS0gYS9zcmMvamF2YXgveG1sL3RyYW5zZm9ybS9zdHJlYW0vcGFja2FnZS5odG1sCisrKyAvZGV2L251bGwKQEAgLTEsNjQgKzAsMCBAQAotPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KLTwhLS0KLUNvcHlyaWdodCAoYykgMjAwMCwgMjAwNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLURPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLQotVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLXVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi1wdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLXBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLWJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotCi1UaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLUFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi12ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLQotWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotCi1QbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotcXVlc3Rpb25zLiAKLS0tPgotCi08IURPQ1RZUEUgaHRtbAotICAgICBQVUJMSUMgIi0vL1czQy8vRFREIFhIVE1MIDEuMCBTdHJpY3QvL0VOIgotICAgICAiaHR0cDovL3d3dy53My5vcmcvVFIveGh0bWwxL0RURC94aHRtbDEtc3RyaWN0LmR0ZCI+Ci0KLTxodG1sIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sIj4KLQotPGhlYWQ+Ci0gIDx0aXRsZT5qYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbTwvdGl0bGU+Ci0KLSAgPG1ldGEgbmFtZT0iQ1ZTIgotICAgICAgICBjb250ZW50PSIkSWQ6IHBhY2thZ2UuaHRtbCx2IDEuMiAyMDA1LzA2LzEwIDAzOjUwOjQyIGplZmZzdXR0b3IgRXhwICQiIC8+Ci0gIDxtZXRhIG5hbWU9IkFVVEhPUiIKLSAgICAgICAgY29udGVudD0iSmVmZi5TdXR0b3JAU3VuLmNvbSIgLz4KLTwvaGVhZD4KLTxib2R5PgotPHA+VGhpcyBwYWNrYWdlIGltcGxlbWVudHMgc3RyZWFtLSBhbmQgVVJJLSBzcGVjaWZpYyB0cmFuc2Zvcm1hdGlvbiBBUElzLgotCSA8L3A+Ci08cD5UaGUge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uc3RyZWFtLlN0cmVhbVNvdXJjZX0gY2xhc3MKLQkgcHJvdmlkZXMgbWV0aG9kcyBmb3Igc3BlY2lmeWluZyB7QGxpbmsgamF2YS5pby5JbnB1dFN0cmVhbX0gaW5wdXQsCi0JIHtAbGluayBqYXZhLmlvLlJlYWRlcn0gaW5wdXQsIGFuZCBVUkwgaW5wdXQgaW4gdGhlIGZvcm0gb2Ygc3RyaW5ncy4gRXZlbgotCSBpZiBhbiBpbnB1dCBzdHJlYW0gb3IgcmVhZGVyIGlzIHNwZWNpZmllZCBhcyB0aGUgc291cmNlLAotCSB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5zdHJlYW0uU3RyZWFtU291cmNlI3NldFN5c3RlbUlkfSBzaG91bGQgc3RpbGwKLQkgYmUgY2FsbGVkLCBzbyB0aGF0IHRoZSB0cmFuc2Zvcm1lciBjYW4ga25vdyBmcm9tIHdoZXJlIGl0IHNob3VsZCByZXNvbHZlCi0JIHJlbGF0aXZlIFVSSXMuIFRoZSBwdWJsaWMgaWRlbnRpZmllciBpcyBhbHdheXMgb3B0aW9uYWw6IGlmIHRoZSBhcHBsaWNhdGlvbgotCSB3cml0ZXIgaW5jbHVkZXMgb25lLCBpdCB3aWxsIGJlIHByb3ZpZGVkIGFzIHBhcnQgb2YgdGhlCi0JIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlNvdXJjZUxvY2F0b3J9IGluZm9ybWF0aW9uLjwvcD4KLTxwPlRoZSB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5zdHJlYW0uU3RyZWFtUmVzdWx0fSBjbGFzcwotCSBwcm92aWRlcyBtZXRob2RzIGZvciBzcGVjaWZ5aW5nIHtAbGluayBqYXZhLmlvLk91dHB1dFN0cmVhbX0sCi0JIHtAbGluayBqYXZhLmlvLldyaXRlcn0sIG9yIGFuIG91dHB1dCBzeXN0ZW0gSUQsIGFzIHRoZSBvdXRwdXQgb2YgdGhlCi0JIHRyYW5zZm9ybWF0aW9uIHJlc3VsdC48L3A+Ci08cD5Ob3JtYWxseSBzdHJlYW1zIHNob3VsZCBiZSB1c2VkIHJhdGhlciB0aGFuIHJlYWRlcnMgb3Igd3JpdGVycywgZm9yCi0JIGJvdGggdGhlIFNvdXJjZSBhbmQgUmVzdWx0LCBzaW5jZSByZWFkZXJzIGFuZCB3cml0ZXJzIGFscmVhZHkgaGF2ZSB0aGUgZW5jb2RpbmcKLQkgZXN0YWJsaXNoZWQgdG8gYW5kIGZyb20gdGhlIGludGVybmFsIFVuaWNvZGUgZm9ybWF0LiBIb3dldmVyLCB0aGVyZSBhcmUgdGltZXMKLQkgd2hlbiBpdCBpcyB1c2VmdWwgdG8gd3JpdGUgdG8gYSBjaGFyYWN0ZXIgc3RyZWFtLCBzdWNoIGFzIHdoZW4gdXNpbmcgYQotCSBTdHJpbmdXcml0ZXIgaW4gb3JkZXIgdG8gd3JpdGUgdG8gYSBTdHJpbmcsIG9yIGluIHRoZSBjYXNlIG9mIHJlYWRpbmcgc291cmNlCi0JIFhNTCBmcm9tIGEgU3RyaW5nUmVhZGVyLjwvcD4KLTwvYm9keT4KLTwvaHRtbD4KZGlmZiAtLWdpdCBhL3NyYy9qYXZheC94bWwvdmFsaWRhdGlvbi9TY2hlbWEuamF2YSBiL3NyYy9qYXZheC94bWwvdmFsaWRhdGlvbi9TY2hlbWEuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDVjNDQ1YS4uMDAwMDAwMAotLS0gYS9zcmMvamF2YXgveG1sL3ZhbGlkYXRpb24vU2NoZW1hLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMDQgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwMywgMjAwNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotcGFja2FnZSBqYXZheC54bWwudmFsaWRhdGlvbjsKLQotLyoqCi0gKiBJbW11dGFibGUgaW4tbWVtb3J5IHJlcHJlc2VudGF0aW9uIG9mIGdyYW1tYXIuCi0gKgotICogPHA+Ci0gKiBUaGlzIG9iamVjdCByZXByZXNlbnRzIGEgc2V0IG9mIGNvbnN0cmFpbnRzIHRoYXQgY2FuIGJlIGNoZWNrZWQvCi0gKiBlbmZvcmNlZCBhZ2FpbnN0IGFuIFhNTCBkb2N1bWVudC4KLSAqCi0gKiA8cD4KLSAqIEEge0BsaW5rIFNjaGVtYX0gb2JqZWN0IGlzIHRocmVhZCBzYWZlIGFuZCBhcHBsaWNhdGlvbnMgYXJlCi0gKiBlbmNvdXJhZ2VkIHRvIHNoYXJlIGl0IGFjcm9zcyBtYW55IHBhcnNlcnMgaW4gbWFueSB0aHJlYWRzLgotICoKLSAqIDxwPgotICogQSB7QGxpbmsgU2NoZW1hfSBvYmplY3QgaXMgaW1tdXRhYmxlIGluIHRoZSBzZW5zZSB0aGF0IGl0IHNob3VsZG4ndAotICogY2hhbmdlIHRoZSBzZXQgb2YgY29uc3RyYWludHMgb25jZSBpdCBpcyBjcmVhdGVkLiBJbiBvdGhlciB3b3JkcywKLSAqIGlmIGFuIGFwcGxpY2F0aW9uIHZhbGlkYXRlcyB0aGUgc2FtZSBkb2N1bWVudCB0d2ljZSBhZ2FpbnN0IHRoZSBzYW1lCi0gKiB7QGxpbmsgU2NoZW1hfSwgaXQgbXVzdCBhbHdheXMgcHJvZHVjZSB0aGUgc2FtZSByZXN1bHQuCi0gKgotICogPHA+Ci0gKiBBIHtAbGluayBTY2hlbWF9IG9iamVjdCBpcyB1c3VhbGx5IGNyZWF0ZWQgZnJvbSB7QGxpbmsgU2NoZW1hRmFjdG9yeX0uCi0gKgotICogPHA+Ci0gKiBUd28ga2luZHMgb2YgdmFsaWRhdG9ycyBjYW4gYmUgY3JlYXRlZCBmcm9tIGEge0BsaW5rIFNjaGVtYX0gb2JqZWN0LgotICogT25lIGlzIHtAbGluayBWYWxpZGF0b3J9LCB3aGljaCBwcm92aWRlcyBoaWdobHktbGV2ZWwgdmFsaWRhdGlvbgotICogb3BlcmF0aW9ucyB0aGF0IGNvdmVyIHR5cGljYWwgdXNlIGNhc2VzLiBUaGUgb3RoZXIgaXMKLSAqIHtAbGluayBWYWxpZGF0b3JIYW5kbGVyfSwgd2hpY2ggd29ya3Mgb24gdG9wIG9mIFNBWCBmb3IgYmV0dGVyCi0gKiBtb2R1bGFyaXR5LgotICoKLSAqIDxwPgotICogVGhpcyBzcGVjaWZpY2F0aW9uIGRvZXMgbm90IHJlZmluZQotICogdGhlIHtAbGluayBqYXZhLmxhbmcuT2JqZWN0I2VxdWFscyhqYXZhLmxhbmcuT2JqZWN0KX0gbWV0aG9kLgotICogSW4gb3RoZXIgd29yZHMsIGlmIHlvdSBwYXJzZSB0aGUgc2FtZSBzY2hlbWEgdHdpY2UsIHlvdSBtYXkKLSAqIHN0aWxsIGdldCA8Y29kZT4hc2NoZW1hQS5lcXVhbHMoc2NoZW1hQik8L2NvZGU+LgotICoKLSAqIEBhdXRob3IgPGEgaHJlZj0ibWFpbHRvOktvaHN1a2UuS2F3YWd1Y2hpQFN1bi5jb20iPktvaHN1a2UgS2F3YWd1Y2hpPC9hPgotICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94bWxzY2hlbWEtMS8iPlhNTCBTY2hlbWEgUGFydCAxOiBTdHJ1Y3R1cmVzPC9hPgotICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94bWwxMS8iPkV4dGVuc2libGUgTWFya3VwIExhbmd1YWdlIChYTUwpIDEuMTwvYT4KLSAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLXhtbCI+RXh0ZW5zaWJsZSBNYXJrdXAgTGFuZ3VhZ2UgKFhNTCkgMS4wIChTZWNvbmQgRWRpdGlvbik8L2E+Ci0gKiBAc2luY2UgMS41Ci0gKi8KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBTY2hlbWEgewotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0b3IgZm9yIHRoZSBkZXJpdmVkIGNsYXNzLgotICAgICAqCi0gICAgICogPHA+Ci0gICAgICogVGhlIGNvbnN0cnVjdG9yIGRvZXMgbm90aGluZy4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgU2NoZW1hKCkgewotICAgIH0KLQotICAgIC8qKgotICAgICAqIENyZWF0ZXMgYSBuZXcge0BsaW5rIFZhbGlkYXRvcn0gZm9yIHRoaXMge0BsaW5rIFNjaGVtYX0uCi0gICAgICoKLSAgICAgKiA8cD5BIHZhbGlkYXRvciBlbmZvcmNlcy9jaGVja3MgdGhlIHNldCBvZiBjb25zdHJhaW50cyB0aGlzIG9iamVjdAotICAgICAqIHJlcHJlc2VudHMuPC9wPgotICAgICAqCi0gICAgICogPHA+SW1wbGVtZW50b3JzIHNob3VsZCBhc3N1cmUgdGhhdCB0aGUgcHJvcGVydGllcyBzZXQgb24gdGhlCi0gICAgICoge0BsaW5rIFNjaGVtYUZhY3Rvcnl9IHRoYXQgY3JlYXRlZCB0aGlzIHtAbGluayBTY2hlbWF9IGFyZSBhbHNvCi0gICAgICogc2V0IG9uIHRoZSB7QGxpbmsgVmFsaWRhdG9yfSBjb25zdHJ1Y3RlZC48L3A+Ci0gICAgICoKLSAgICAgKiBAcmV0dXJuCi0gICAgICogICAgICBBbHdheXMgcmV0dXJuIGEgbm9uLW51bGwgdmFsaWQgb2JqZWN0LgotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCBWYWxpZGF0b3IgbmV3VmFsaWRhdG9yKCk7Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGVzIGEgbmV3IHtAbGluayBWYWxpZGF0b3JIYW5kbGVyfSBmb3IgdGhpcyB7QGxpbmsgU2NoZW1hfS4KLSAgICAgKgotICAgICAqIDxwPkltcGxlbWVudG9ycyBzaG91bGQgYXNzdXJlIHRoYXQgdGhlIHByb3BlcnRpZXMgc2V0IG9uIHRoZQotICAgICAqIHtAbGluayBTY2hlbWFGYWN0b3J5fSB0aGF0IGNyZWF0ZWQgdGhpcyB7QGxpbmsgU2NoZW1hfSBhcmUgYWxzbwotICAgICAqIHNldCBvbiB0aGUge0BsaW5rIFZhbGlkYXRvckhhbmRsZXJ9IGNvbnN0cnVjdGVkLjwvcD4KLSAgICAgKgotICAgICAqIEByZXR1cm4KLSAgICAgKiAgICAgIEFsd2F5cyByZXR1cm4gYSBub24tbnVsbCB2YWxpZCBvYmplY3QuCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IFZhbGlkYXRvckhhbmRsZXIgbmV3VmFsaWRhdG9ySGFuZGxlcigpOwotfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmF4L3htbC92YWxpZGF0aW9uL1NjaGVtYUZhY3RvcnkuamF2YSBiL3NyYy9qYXZheC94bWwvdmFsaWRhdGlvbi9TY2hlbWFGYWN0b3J5LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGViYmJlNDAuLjAwMDAwMDAKLS0tIGEvc3JjL2phdmF4L3htbC92YWxpZGF0aW9uL1NjaGVtYUZhY3RvcnkuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDgwMCArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDEzLCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi1wYWNrYWdlIGphdmF4LnhtbC52YWxpZGF0aW9uOwotCi1pbXBvcnQgamF2YS5pby5GaWxlOwotaW1wb3J0IGphdmEubmV0LlVSTDsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlNvdXJjZTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbS5TdHJlYW1Tb3VyY2U7Ci1pbXBvcnQgb3JnLnczYy5kb20ubHMuTFNSZXNvdXJjZVJlc29sdmVyOwotaW1wb3J0IG9yZy54bWwuc2F4LkVycm9ySGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb247Ci0KLS8qKgotICogRmFjdG9yeSB0aGF0IGNyZWF0ZXMge0BsaW5rIFNjaGVtYX0gb2JqZWN0cyYjeDJFOyBFbnRyeS1wb2ludCB0bwotICogdGhlIHZhbGlkYXRpb24gQVBJLgotICoKLSAqIDxwPgotICoge0BsaW5rIFNjaGVtYUZhY3Rvcnl9IGlzIGEgc2NoZW1hIGNvbXBpbGVyLiBJdCByZWFkcyBleHRlcm5hbAotICogcmVwcmVzZW50YXRpb25zIG9mIHNjaGVtYXMgYW5kIHByZXBhcmVzIHRoZW0gZm9yIHZhbGlkYXRpb24uCi0gKgotICogPHA+Ci0gKiBUaGUge0BsaW5rIFNjaGVtYUZhY3Rvcnl9IGNsYXNzIGlzIG5vdCB0aHJlYWQtc2FmZS4gSW4gb3RoZXIgd29yZHMsCi0gKiBpdCBpcyB0aGUgYXBwbGljYXRpb24ncyByZXNwb25zaWJpbGl0eSB0byBlbnN1cmUgdGhhdCBhdCBtb3N0Ci0gKiBvbmUgdGhyZWFkIGlzIHVzaW5nIGEge0BsaW5rIFNjaGVtYUZhY3Rvcnl9IG9iamVjdCBhdCBhbnkKLSAqIGdpdmVuIG1vbWVudC4gSW1wbGVtZW50YXRpb25zIGFyZSBlbmNvdXJhZ2VkIHRvIG1hcmsgbWV0aG9kcwotICogYXMgPGNvZGU+c3luY2hyb25pemVkPC9jb2RlPiB0byBwcm90ZWN0IHRoZW1zZWx2ZXMgZnJvbSBicm9rZW4gY2xpZW50cy4KLSAqCi0gKiA8cD4KLSAqIHtAbGluayBTY2hlbWFGYWN0b3J5fSBpcyBub3QgcmUtZW50cmFudC4gV2hpbGUgb25lIG9mIHRoZQotICogPGNvZGU+bmV3U2NoZW1hPC9jb2RlPiBtZXRob2RzIGlzIGJlaW5nIGludm9rZWQsIGFwcGxpY2F0aW9ucwotICogbWF5IG5vdCBhdHRlbXB0IHRvIHJlY3Vyc2l2ZWx5IGludm9rZSB0aGUgPGNvZGU+bmV3U2NoZW1hPC9jb2RlPiBtZXRob2QsCi0gKiBldmVuIGZyb20gdGhlIHNhbWUgdGhyZWFkLgotICoKLSAqIDxoMj48YSBuYW1lPSJzY2hlbWFMYW5ndWFnZSI+PC9hPlNjaGVtYSBMYW5ndWFnZTwvaDI+Ci0gKiA8cD4KLSAqIFRoaXMgc3BlYyB1c2VzIGEgbmFtZXNwYWNlIFVSSSB0byBkZXNpZ25hdGUgYSBzY2hlbWEgbGFuZ3VhZ2UuCi0gKiBUaGUgZm9sbG93aW5nIHRhYmxlIHNob3dzIHRoZSB2YWx1ZXMgZGVmaW5lZCBieSB0aGlzIHNwZWNpZmljYXRpb24uCi0gKiA8cD4KLSAqIFRvIGJlIGNvbXBsaWFudCB3aXRoIHRoZSBzcGVjLCB0aGUgaW1wbGVtZW50YXRpb24KLSAqIGlzIG9ubHkgcmVxdWlyZWQgdG8gc3VwcG9ydCBXM0MgWE1MIFNjaGVtYSAxLjAuIEhvd2V2ZXIsCi0gKiBpZiBpdCBjaG9vc2VzIHRvIHN1cHBvcnQgb3RoZXIgc2NoZW1hIGxhbmd1YWdlcyBsaXN0ZWQgaGVyZSwKLSAqIGl0IG11c3QgY29uZm9ybSB0byB0aGUgcmVsZXZhbnQgYmVoYXZpb3JzIGRlc2NyaWJlZCBpbiB0aGlzIHNwZWMuCi0gKgotICogPHA+Ci0gKiBTY2hlbWEgbGFuZ3VhZ2VzIG5vdCBsaXN0ZWQgaGVyZSBhcmUgZXhwZWN0ZWQgdG8KLSAqIGludHJvZHVjZSB0aGVpciBvd24gVVJJcyB0byByZXByZXNlbnQgdGhlbXNlbHZlcy4KLSAqIFRoZSB7QGxpbmsgU2NoZW1hRmFjdG9yeX0gY2xhc3MgaXMgY2FwYWJsZSBvZiBsb2NhdGluZyBvdGhlcgotICogaW1wbGVtZW50YXRpb25zIGZvciBvdGhlciBzY2hlbWEgbGFuZ3VhZ2VzIGF0IHJ1bi10aW1lLgotICoKLSAqIDxwPgotICogTm90ZSB0aGF0IGJlY2F1c2UgdGhlIFhNTCBEVEQgaXMgc3Ryb25nbHkgdGllZCB0byB0aGUgcGFyc2luZyBwcm9jZXNzCi0gKiBhbmQgaGFzIGEgc2lnbmlmaWNhbnQgZWZmZWN0IG9uIHRoZSBwYXJzaW5nIHByb2Nlc3MsIGl0IGlzIGltcG9zc2libGUKLSAqIHRvIGRlZmluZSB0aGUgRFREIHZhbGlkYXRpb24gYXMgYSBwcm9jZXNzIGluZGVwZW5kZW50IGZyb20gcGFyc2luZy4KLSAqIEZvciB0aGlzIHJlYXNvbiwgdGhpcyBzcGVjaWZpY2F0aW9uIGRvZXMgbm90IGRlZmluZSB0aGUgc2VtYW50aWNzIGZvcgotICogdGhlIFhNTCBEVEQuIFRoaXMgZG9lc24ndCBwcm9oaWJpdCBpbXBsZW1lbnRvcnMgZnJvbSBpbXBsZW1lbnRpbmcgaXQKLSAqIGluIGEgd2F5IHRoZXkgc2VlIGZpdCwgYnV0IDxlbT51c2VycyBhcmUgd2FybmVkIHRoYXQgYW55IERURAotICogdmFsaWRhdGlvbiBpbXBsZW1lbnRlZCBvbiB0aGlzIGludGVyZmFjZSBuZWNlc3NhcmlseSBkZXZpYXRlIGZyb20KLSAqIHRoZSBYTUwgRFREIHNlbWFudGljcyBhcyBkZWZpbmVkIGluIHRoZSBYTUwgMS4wPC9lbT4uCi0gKgotICogPHRhYmxlIGJvcmRlcj0iMSIgY2VsbHBhZGRpbmc9IjIiPgotICogICA8dGhlYWQ+Ci0gKiAgICAgPHRyPgotICogICAgICAgPHRoPnZhbHVlPC90aD4KLSAqICAgICAgIDx0aD5sYW5ndWFnZTwvdGg+Ci0gKiAgICAgPC90cj4KLSAqICAgPC90aGVhZD4KLSAqICAgPHRib2R5PgotICogICAgIDx0cj4KLSAqICAgICAgIDx0ZD57QGxpbmsgamF2YXgueG1sLlhNTENvbnN0YW50cyNXM0NfWE1MX1NDSEVNQV9OU19VUkl9ICgiPGNvZGU+aHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWE8L2NvZGU+Iik8L3RkPgotICogICAgICAgPHRkPjxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3htbHNjaGVtYS0xIj5XM0MgWE1MIFNjaGVtYSAxLjA8L2E+PC90ZD4KLSAqICAgICA8L3RyPgotICogICAgIDx0cj4KLSAqICAgICAgIDx0ZD57QGxpbmsgamF2YXgueG1sLlhNTENvbnN0YW50cyNSRUxBWE5HX05TX1VSSX0gKCI8Y29kZT5odHRwOi8vcmVsYXhuZy5vcmcvbnMvc3RydWN0dXJlLzEuMDwvY29kZT4iKTwvdGQ+Ci0gKiAgICAgICA8dGQ+PGEgaHJlZj0iaHR0cDovL3d3dy5yZWxheG5nLm9yZy8iPlJFTEFYIE5HIDEuMDwvYT48L3RkPgotICogICAgIDwvdHI+Ci0gKiAgIDwvdGJvZHk+Ci0gKiA8L3RhYmxlPgotICoKLSAqIEBhdXRob3IgIDxhIGhyZWY9Im1haWx0bzpLb2hzdWtlLkthd2FndWNoaUBTdW4uY29tIj5Lb2hzdWtlIEthd2FndWNoaTwvYT4KLSAqIEBhdXRob3IgIDxhIGhyZWY9Im1haWx0bzpOZWVyYWouQmFqYWpAc3VuLmNvbSI+TmVlcmFqIEJhamFqPC9hPgotICoKLSAqIEBzaW5jZSAxLjUKLSAqLwotcHVibGljIGFic3RyYWN0IGNsYXNzIFNjaGVtYUZhY3RvcnkgewotCi0gICAgIHByaXZhdGUgc3RhdGljIFNlY3VyaXR5U3VwcG9ydCBzcyA9IG5ldyBTZWN1cml0eVN1cHBvcnQoKTsKLQotICAgIC8qKgotICAgICAqIDxwPkNvbnN0cnVjdG9yIGZvciBkZXJpdmVkIGNsYXNzZXMuPC9wPgotICAgICAqCi0gICAgICogPHA+VGhlIGNvbnN0cnVjdG9yIGRvZXMgbm90aGluZy48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5EZXJpdmVkIGNsYXNzZXMgbXVzdCBjcmVhdGUge0BsaW5rIFNjaGVtYUZhY3Rvcnl9IG9iamVjdHMgdGhhdCBoYXZlCi0gICAgICogPGNvZGU+bnVsbDwvY29kZT4ge0BsaW5rIEVycm9ySGFuZGxlcn0gYW5kCi0gICAgICogPGNvZGU+bnVsbDwvY29kZT4ge0BsaW5rIExTUmVzb3VyY2VSZXNvbHZlcn0uPC9wPgotICAgICAqLwotICAgIHByb3RlY3RlZCBTY2hlbWFGYWN0b3J5KCkgewotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPkxvb2t1cCBhbiBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgPGNvZGU+U2NoZW1hRmFjdG9yeTwvY29kZT4gdGhhdCBzdXBwb3J0cyB0aGUgc3BlY2lmaWVkCi0gICAgICogc2NoZW1hIGxhbmd1YWdlIGFuZCByZXR1cm4gaXQuPC9wPgotICAgICAqCi0gICAgICogPHA+VG8gZmluZCBhIDxjb2RlPlNjaGVtYUZhY3Rvcnk8L2NvZGU+IG9iamVjdCBmb3IgYSBnaXZlbiBzY2hlbWEgbGFuZ3VhZ2UsCi0gICAgICogdGhpcyBtZXRob2QgbG9va3MgdGhlIGZvbGxvd2luZyBwbGFjZXMgaW4gdGhlIGZvbGxvd2luZyBvcmRlcgotICAgICAqIHdoZXJlICJ0aGUgY2xhc3MgbG9hZGVyIiByZWZlcnMgdG8gdGhlIGNvbnRleHQgY2xhc3MgbG9hZGVyOjwvcD4KLSAgICAgKiA8b2w+Ci0gICAgICogIDxsaT4KLSAgICAgKiAgICAgSWYgdGhlIHN5c3RlbSBwcm9wZXJ0eQotICAgICAqICAgICA8Y29kZT4iamF2YXgueG1sLnZhbGlkYXRpb24uU2NoZW1hRmFjdG9yeTo8aT5zY2hlbWFMYW5ndWFnZTwvaT4iPC9jb2RlPgotICAgICAqICAgICBpcyBwcmVzZW50ICh3aGVyZSA8aT5zY2hlbWFMYW5ndWFnZTwvaT4gaXMgdGhlIHBhcmFtZXRlcgotICAgICAqICAgICB0byB0aGlzIG1ldGhvZCksIHRoZW4gaXRzIHZhbHVlIGlzIHJlYWQKLSAgICAgKiAgICAgYXMgYSBjbGFzcyBuYW1lLiBUaGUgbWV0aG9kIHdpbGwgdHJ5IHRvCi0gICAgICogICAgIGNyZWF0ZSBhIG5ldyBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIGJ5IHVzaW5nIHRoZSBjbGFzcyBsb2FkZXIsCi0gICAgICogICAgIGFuZCByZXR1cm5zIGl0IGlmIGl0IGlzIHN1Y2Nlc3NmdWxseSBjcmVhdGVkLgotICAgICAqICAgPC9saT4KLSAgICAgKiAgIDxsaT4KLSAgICAgKiAgICAgPGNvZGU+JGphdmEuaG9tZS9saWIvamF4cC5wcm9wZXJ0aWVzPC9jb2RlPiBpcyByZWFkIGFuZAotICAgICAqICAgICB0aGUgdmFsdWUgYXNzb2NpYXRlZCB3aXRoIHRoZSBrZXkgYmVpbmcgdGhlIHN5c3RlbSBwcm9wZXJ0eSBhYm92ZQotICAgICAqICAgICBpcyBsb29rZWQgZm9yLiBJZiBwcmVzZW50LCB0aGUgdmFsdWUgaXMgcHJvY2Vzc2VkIGp1c3QgbGlrZSBhYm92ZS4KLSAgICAgKiAgIDwvbGk+Ci0gICAgICogICA8bGk+Ci0gICAgICogICBVc2UgdGhlIHNlcnZpY2UtcHJvdmlkZXIgbG9hZGluZyBmYWNpbGl0aWVzLCBkZWZpbmVkIGJ5IHRoZQotICAgICAqICAge0BsaW5rIGphdmEudXRpbC5TZXJ2aWNlTG9hZGVyfSBjbGFzcywgdG8gYXR0ZW1wdCB0byBsb2NhdGUgYW5kIGxvYWQgYW4KLSAgICAgKiAgIGltcGxlbWVudGF0aW9uIG9mIHRoZSBzZXJ2aWNlIHVzaW5nIHRoZSB7QGxpbmtwbGFpbgotICAgICAqICAgamF2YS51dGlsLlNlcnZpY2VMb2FkZXIjbG9hZChqYXZhLmxhbmcuQ2xhc3MpIGRlZmF1bHQgbG9hZGluZyBtZWNoYW5pc219OgotICAgICAqICAgdGhlIHNlcnZpY2UtcHJvdmlkZXIgbG9hZGluZyBmYWNpbGl0eSB3aWxsIHVzZSB0aGUge0BsaW5rcGxhaW4KLSAgICAgKiAgIGphdmEubGFuZy5UaHJlYWQjZ2V0Q29udGV4dENsYXNzTG9hZGVyKCkgY3VycmVudCB0aHJlYWQncyBjb250ZXh0IGNsYXNzIGxvYWRlcn0KLSAgICAgKiAgIHRvIGF0dGVtcHQgdG8gbG9hZCB0aGUgc2VydmljZS4gSWYgdGhlIGNvbnRleHQgY2xhc3MKLSAgICAgKiAgIGxvYWRlciBpcyBudWxsLCB0aGUge0BsaW5rcGxhaW4KLSAgICAgKiAgIENsYXNzTG9hZGVyI2dldFN5c3RlbUNsYXNzTG9hZGVyKCkgc3lzdGVtIGNsYXNzIGxvYWRlcn0gd2lsbCBiZSB1c2VkLgotICAgICAqICAgPGJyPgotICAgICAqICAgRWFjaCBwb3RlbnRpYWwgc2VydmljZSBwcm92aWRlciBpcyByZXF1aXJlZCB0byBpbXBsZW1lbnQgdGhlIG1ldGhvZAotICAgICAqICAgICAgICB7QGxpbmsgI2lzU2NoZW1hTGFuZ3VhZ2VTdXBwb3J0ZWQoU3RyaW5nIHNjaGVtYUxhbmd1YWdlKX0uCi0gICAgICogICA8YnI+Ci0gICAgICogICBUaGUgZmlyc3Qgc2VydmljZSBwcm92aWRlciBmb3VuZCB0aGF0IHN1cHBvcnRzIHRoZSBzcGVjaWZpZWQgc2NoZW1hCi0gICAgICogICBsYW5ndWFnZSBpcyByZXR1cm5lZC4KLSAgICAgKiAgIDxicj4KLSAgICAgKiAgIEluIGNhc2Ugb2Yge0BsaW5rIGphdmEudXRpbC5TZXJ2aWNlQ29uZmlndXJhdGlvbkVycm9yfSBhCi0gICAgICogICB7QGxpbmsgU2NoZW1hRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvcn0gd2lsbCBiZSB0aHJvd24uCi0gICAgICogICA8L2xpPgotICAgICAqICAgPGxpPgotICAgICAqICAgICBQbGF0Zm9ybSBkZWZhdWx0IDxjb2RlPlNjaGVtYUZhY3Rvcnk8L2NvZGU+IGlzIGxvY2F0ZWQKLSAgICAgKiAgICAgaW4gYSBpbXBsZW1lbnRhdGlvbiBzcGVjaWZpYyB3YXkuIFRoZXJlIG11c3QgYmUgYSBwbGF0Zm9ybSBkZWZhdWx0Ci0gICAgICogICAgIDxjb2RlPlNjaGVtYUZhY3Rvcnk8L2NvZGU+IGZvciBXM0MgWE1MIFNjaGVtYS4KLSAgICAgKiAgIDwvbGk+Ci0gICAgICogPC9vbD4KLSAgICAgKgotICAgICAqIDxwPklmIGV2ZXJ5dGhpbmcgZmFpbHMsIHtAbGluayBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb259IHdpbGwgYmUgdGhyb3duLjwvcD4KLSAgICAgKgotICAgICAqIDxwPjxzdHJvbmc+VGlwIGZvciBUcm91YmxlLXNob290aW5nOjwvc3Ryb25nPjwvcD4KLSAgICAgKiA8cD5TZWUge0BsaW5rIGphdmEudXRpbC5Qcm9wZXJ0aWVzI2xvYWQoamF2YS5pby5JbnB1dFN0cmVhbSl9IGZvcgotICAgICAqIGV4YWN0bHkgaG93IGEgcHJvcGVydHkgZmlsZSBpcyBwYXJzZWQuIEluIHBhcnRpY3VsYXIsIGNvbG9ucyAnOicKLSAgICAgKiBuZWVkIHRvIGJlIGVzY2FwZWQgaW4gYSBwcm9wZXJ0eSBmaWxlLCBzbyBtYWtlIHN1cmUgc2NoZW1hIGxhbmd1YWdlCi0gICAgICogVVJJcyBhcmUgcHJvcGVybHkgZXNjYXBlZCBpbiBpdC4gRm9yIGV4YW1wbGU6PC9wPgotICAgICAqIDxwcmU+Ci0gICAgICogaHR0cFw6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hPW9yZy5hY21lLmZvby5YU1NjaGVtYUZhY3RvcnkKLSAgICAgKiA8L3ByZT4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzY2hlbWFMYW5ndWFnZQotICAgICAqICAgICAgU3BlY2lmaWVzIHRoZSBzY2hlbWEgbGFuZ3VhZ2Ugd2hpY2ggdGhlIHJldHVybmVkCi0gICAgICogICAgICBTY2hlbWFGYWN0b3J5IHdpbGwgdW5kZXJzdGFuZC4gU2VlCi0gICAgICogICAgICA8YSBocmVmPSIjc2NoZW1hTGFuZ3VhZ2UiPnRoZSBsaXN0IG9mIGF2YWlsYWJsZQotICAgICAqICAgICAgc2NoZW1hIGxhbmd1YWdlczwvYT4gZm9yIHRoZSBwb3NzaWJsZSB2YWx1ZXMuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIE5ldyBpbnN0YW5jZSBvZiBhIDxjb2RlPlNjaGVtYUZhY3Rvcnk8L2NvZGU+Ci0gICAgICoKLSAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgotICAgICAqICAgICAgSWYgbm8gaW1wbGVtZW50YXRpb24gb2YgdGhlIHNjaGVtYSBsYW5ndWFnZSBpcyBhdmFpbGFibGUuCi0gICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgotICAgICAqICAgICAgSWYgdGhlIDxjb2RlPnNjaGVtYUxhbmd1YWdlPC9jb2RlPiBwYXJhbWV0ZXIgaXMgbnVsbC4KLSAgICAgKiBAdGhyb3dzIFNjaGVtYUZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IKLSAgICAgKiAgICAgIElmIGEgY29uZmlndXJhdGlvbiBlcnJvciBpcyBlbmNvdW50ZXJlZC4KLSAgICAgKgotICAgICAqIEBzZWUgI25ld0luc3RhbmNlKFN0cmluZyBzY2hlbWFMYW5ndWFnZSwgU3RyaW5nIGZhY3RvcnlDbGFzc05hbWUsIENsYXNzTG9hZGVyIGNsYXNzTG9hZGVyKQotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgU2NoZW1hRmFjdG9yeSBuZXdJbnN0YW5jZShTdHJpbmcgc2NoZW1hTGFuZ3VhZ2UpIHsKLSAgICAgICAgQ2xhc3NMb2FkZXIgY2w7Ci0gICAgICAgIGNsID0gc3MuZ2V0Q29udGV4dENsYXNzTG9hZGVyKCk7Ci0KLSAgICAgICAgaWYgKGNsID09IG51bGwpIHsKLSAgICAgICAgICAgIC8vY2wgPSBDbGFzc0xvYWRlci5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpOwotICAgICAgICAgICAgLy91c2UgdGhlIGN1cnJlbnQgY2xhc3MgbG9hZGVyCi0gICAgICAgICAgICBjbCA9IFNjaGVtYUZhY3RvcnkuY2xhc3MuZ2V0Q2xhc3NMb2FkZXIoKTsKLSAgICAgICAgfQotCi0gICAgICAgIFNjaGVtYUZhY3RvcnkgZiA9IG5ldyBTY2hlbWFGYWN0b3J5RmluZGVyKGNsKS5uZXdGYWN0b3J5KHNjaGVtYUxhbmd1YWdlKTsKLSAgICAgICAgaWYgKGYgPT0gbnVsbCkgewotICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgIk5vIFNjaGVtYUZhY3RvcnkiCi0gICAgICAgICAgICAgICAgICAgICsgIiB0aGF0IGltcGxlbWVudHMgdGhlIHNjaGVtYSBsYW5ndWFnZSBzcGVjaWZpZWQgYnk6ICIgKyBzY2hlbWFMYW5ndWFnZQotICAgICAgICAgICAgICAgICAgICArICIgY291bGQgYmUgbG9hZGVkIik7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIGY7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+T2J0YWluIGEgbmV3IGluc3RhbmNlIG9mIGEgPGNvZGU+U2NoZW1hRmFjdG9yeTwvY29kZT4gZnJvbSBjbGFzcyBuYW1lLiA8Y29kZT5TY2hlbWFGYWN0b3J5PC9jb2RlPgotICAgICAqIGlzIHJldHVybmVkIGlmIHNwZWNpZmllZCBmYWN0b3J5IGNsYXNzIG5hbWUgc3VwcG9ydHMgdGhlIHNwZWNpZmllZCBzY2hlbWEgbGFuZ3VhZ2UuCi0gICAgICogVGhpcyBmdW5jdGlvbiBpcyB1c2VmdWwgd2hlbiB0aGVyZSBhcmUgbXVsdGlwbGUgcHJvdmlkZXJzIGluIHRoZSBjbGFzc3BhdGguCi0gICAgICogSXQgZ2l2ZXMgbW9yZSBjb250cm9sIHRvIHRoZSBhcHBsaWNhdGlvbiBhcyBpdCBjYW4gc3BlY2lmeSB3aGljaCBwcm92aWRlcgotICAgICAqIHNob3VsZCBiZSBsb2FkZWQuPC9wPgotICAgICAqCi0gICAgICogPGgyPlRpcCBmb3IgVHJvdWJsZS1zaG9vdGluZzwvaDI+Ci0gICAgICogPHA+U2V0dGluZyB0aGUgPGNvZGU+amF4cC5kZWJ1ZzwvY29kZT4gc3lzdGVtIHByb3BlcnR5IHdpbGwgY2F1c2UKLSAgICAgKiB0aGlzIG1ldGhvZCB0byBwcmludCBhIGxvdCBvZiBkZWJ1ZyBtZXNzYWdlcwotICAgICAqIHRvIDxjb2RlPlN5c3RlbS5lcnI8L2NvZGU+IGFib3V0IHdoYXQgaXQgaXMgZG9pbmcgYW5kIHdoZXJlIGl0IGlzIGxvb2tpbmcgYXQuPC9wPgotICAgICAqCi0gICAgICogPHA+IElmIHlvdSBoYXZlIHByb2JsZW1zIHRyeTo8L3A+Ci0gICAgICogPHByZT4KLSAgICAgKiBqYXZhIC1EamF4cC5kZWJ1Zz0xIFlvdXJQcm9ncmFtIC4uLi4KLSAgICAgKiA8L3ByZT4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzY2hlbWFMYW5ndWFnZSBTcGVjaWZpZXMgdGhlIHNjaGVtYSBsYW5ndWFnZSB3aGljaCB0aGUgcmV0dXJuZWQKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgPGNvZGU+U2NoZW1hRmFjdG9yeTwvY29kZT4gd2lsbCB1bmRlcnN0YW5kLiBTZWUKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgPGEgaHJlZj0iI3NjaGVtYUxhbmd1YWdlIj50aGUgbGlzdCBvZiBhdmFpbGFibGUKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgc2NoZW1hIGxhbmd1YWdlczwvYT4gZm9yIHRoZSBwb3NzaWJsZSB2YWx1ZXMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZmFjdG9yeUNsYXNzTmFtZSBmdWxseSBxdWFsaWZpZWQgZmFjdG9yeSBjbGFzcyBuYW1lIHRoYXQgcHJvdmlkZXMgaW1wbGVtZW50YXRpb24gb2YgPGNvZGU+amF2YXgueG1sLnZhbGlkYXRpb24uU2NoZW1hRmFjdG9yeTwvY29kZT4uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY2xhc3NMb2FkZXIgPGNvZGU+Q2xhc3NMb2FkZXI8L2NvZGU+IHVzZWQgdG8gbG9hZCB0aGUgZmFjdG9yeSBjbGFzcy4gSWYgPGNvZGU+bnVsbDwvY29kZT4KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnQgPGNvZGU+VGhyZWFkPC9jb2RlPidzIGNvbnRleHQgY2xhc3NMb2FkZXIgaXMgdXNlZCB0byBsb2FkIHRoZSBmYWN0b3J5IGNsYXNzLgotICAgICAqCi0gICAgICogQHJldHVybiBOZXcgaW5zdGFuY2Ugb2YgYSA8Y29kZT5TY2hlbWFGYWN0b3J5PC9jb2RlPgotICAgICAqCi0gICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KLSAgICAgKiAgICAgICAgICAgICAgICAgICBpZiA8Y29kZT5mYWN0b3J5Q2xhc3NOYW1lPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPiwgb3IKLSAgICAgKiAgICAgICAgICAgICAgICAgICB0aGUgZmFjdG9yeSBjbGFzcyBjYW5ub3QgYmUgbG9hZGVkLCBpbnN0YW50aWF0ZWQgb3IgZG9lc24ndAotICAgICAqICAgICAgICAgICAgICAgICAgIHN1cHBvcnQgdGhlIHNjaGVtYSBsYW5ndWFnZSBzcGVjaWZpZWQgaW4gPGNvZGU+c2NoZW1MYW5ndWFnZTwvY29kZT4KLSAgICAgKiAgICAgICAgICAgICAgICAgICBwYXJhbWV0ZXIuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCi0gICAgICogICAgICBJZiB0aGUgPGNvZGU+c2NoZW1hTGFuZ3VhZ2U8L2NvZGU+IHBhcmFtZXRlciBpcyBudWxsLgotICAgICAqCi0gICAgICogQHNlZSAjbmV3SW5zdGFuY2UoU3RyaW5nIHNjaGVtYUxhbmd1YWdlKQotICAgICAqCi0gICAgICogQHNpbmNlIDEuNgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgU2NoZW1hRmFjdG9yeSBuZXdJbnN0YW5jZShTdHJpbmcgc2NoZW1hTGFuZ3VhZ2UsIFN0cmluZyBmYWN0b3J5Q2xhc3NOYW1lLCBDbGFzc0xvYWRlciBjbGFzc0xvYWRlcil7Ci0gICAgICAgIENsYXNzTG9hZGVyIGNsID0gY2xhc3NMb2FkZXI7Ci0KLSAgICAgICAgaWYgKGNsID09IG51bGwpIHsKLSAgICAgICAgICAgIGNsID0gc3MuZ2V0Q29udGV4dENsYXNzTG9hZGVyKCk7Ci0gICAgICAgIH0KLQotICAgICAgICBTY2hlbWFGYWN0b3J5IGYgPSBuZXcgU2NoZW1hRmFjdG9yeUZpbmRlcihjbCkuY3JlYXRlSW5zdGFuY2UoZmFjdG9yeUNsYXNzTmFtZSk7Ci0gICAgICAgIGlmIChmID09IG51bGwpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgICJGYWN0b3J5ICIgKyBmYWN0b3J5Q2xhc3NOYW1lCi0gICAgICAgICAgICAgICAgICAgICsgIiBjb3VsZCBub3QgYmUgbG9hZGVkIHRvIGltcGxlbWVudCB0aGUgc2NoZW1hIGxhbmd1YWdlIHNwZWNpZmllZCBieTogIiArIHNjaGVtYUxhbmd1YWdlKTsKLSAgICAgICAgfQotICAgICAgICAvL2lmIHRoaXMgZmFjdG9yeSBzdXBwb3J0cyB0aGUgZ2l2ZW4gc2NoZW1hbGFuZ3VhZ2UgcmV0dXJuIHRoaXMgZmFjdG9yeSBlbHNlIHRocm93biBleGNlcHRpb24KLSAgICAgICAgaWYoZi5pc1NjaGVtYUxhbmd1YWdlU3VwcG9ydGVkKHNjaGVtYUxhbmd1YWdlKSl7Ci0gICAgICAgICAgICByZXR1cm4gZjsKLSAgICAgICAgfWVsc2V7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICAiRmFjdG9yeSAiICsgZi5nZXRDbGFzcygpLmdldE5hbWUoKQotICAgICAgICAgICAgICAgICAgICArICIgZG9lcyBub3QgaW1wbGVtZW50IHRoZSBzY2hlbWEgbGFuZ3VhZ2Ugc3BlY2lmaWVkIGJ5OiAiICsgc2NoZW1hTGFuZ3VhZ2UpOwotICAgICAgICB9Ci0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5JcyBzcGVjaWZpZWQgc2NoZW1hIHN1cHBvcnRlZCBieSB0aGlzIDxjb2RlPlNjaGVtYUZhY3Rvcnk8L2NvZGU+PzwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzY2hlbWFMYW5ndWFnZSBTcGVjaWZpZXMgdGhlIHNjaGVtYSBsYW5ndWFnZSB3aGljaCB0aGUgcmV0dXJuZWQgPGNvZGU+U2NoZW1hRmFjdG9yeTwvY29kZT4gd2lsbCB1bmRlcnN0YW5kLgotICAgICAqICAgIDxjb2RlPnNjaGVtYUxhbmd1YWdlPC9jb2RlPiBtdXN0IHNwZWNpZnkgYSA8YSBocmVmPSIjc2NoZW1hTGFuZ3VhZ2UiPnZhbGlkPC9hPiBzY2hlbWEgbGFuZ3VhZ2UuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIDxjb2RlPnRydWU8L2NvZGU+IGlmIDxjb2RlPlNjaGVtYUZhY3Rvcnk8L2NvZGU+IHN1cHBvcnRzIDxjb2RlPnNjaGVtYUxhbmd1YWdlPC9jb2RlPiwgZWxzZSA8Y29kZT5mYWxzZTwvY29kZT4uCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIElmIDxjb2RlPnNjaGVtYUxhbmd1YWdlPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBJZiA8Y29kZT5zY2hlbWFMYW5ndWFnZS5sZW5ndGgoKSA9PSAwPC9jb2RlPgotICAgICAqICAgb3IgPGNvZGU+c2NoZW1hTGFuZ3VhZ2U8L2NvZGU+IGRvZXMgbm90IHNwZWNpZnkgYSA8YSBocmVmPSIjc2NoZW1hTGFuZ3VhZ2UiPnZhbGlkPC9hPiBzY2hlbWEgbGFuZ3VhZ2UuCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gaXNTY2hlbWFMYW5ndWFnZVN1cHBvcnRlZChTdHJpbmcgc2NoZW1hTGFuZ3VhZ2UpOwotCi0gICAgLyoqCi0gICAgICogTG9vayB1cCB0aGUgdmFsdWUgb2YgYSBmZWF0dXJlIGZsYWcuCi0gICAgICoKLSAgICAgKiA8cD5UaGUgZmVhdHVyZSBuYW1lIGlzIGFueSBmdWxseS1xdWFsaWZpZWQgVVJJLiAgSXQgaXMKLSAgICAgKiBwb3NzaWJsZSBmb3IgYSB7QGxpbmsgU2NoZW1hRmFjdG9yeX0gdG8gcmVjb2duaXplIGEgZmVhdHVyZSBuYW1lIGJ1dAotICAgICAqIHRlbXBvcmFyaWx5IGJlIHVuYWJsZSB0byByZXR1cm4gaXRzIHZhbHVlLgotICAgICAqCi0gICAgICogPHA+SW1wbGVtZW50b3JzIGFyZSBmcmVlIChhbmQgZW5jb3VyYWdlZCkgdG8gaW52ZW50IHRoZWlyIG93biBmZWF0dXJlcywKLSAgICAgKiB1c2luZyBuYW1lcyBidWlsdCBvbiB0aGVpciBvd24gVVJJcy48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgZmVhdHVyZSBuYW1lLCB3aGljaCBpcyBhIG5vbi1udWxsIGZ1bGx5LXF1YWxpZmllZCBVUkkuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBjdXJyZW50IHZhbHVlIG9mIHRoZSBmZWF0dXJlICh0cnVlIG9yIGZhbHNlKS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiBJZiB0aGUgZmVhdHVyZQotICAgICAqICAgdmFsdWUgY2FuJ3QgYmUgYXNzaWduZWQgb3IgcmV0cmlldmVkLgotICAgICAqIEB0aHJvd3MgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIFdoZW4gdGhlCi0gICAgICogICB7QGxpbmsgU2NoZW1hRmFjdG9yeX0gcmVjb2duaXplcyB0aGUgZmVhdHVyZSBuYW1lIGJ1dAotICAgICAqICAgY2Fubm90IGRldGVybWluZSBpdHMgdmFsdWUgYXQgdGhpcyB0aW1lLgotICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gSWYgPGNvZGU+bmFtZTwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICoKLSAgICAgKiBAc2VlICNzZXRGZWF0dXJlKFN0cmluZywgYm9vbGVhbikKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXRGZWF0dXJlKFN0cmluZyBuYW1lKQotICAgICAgICB0aHJvd3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiwgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIHsKLQotICAgICAgICBpZiAobmFtZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJ0aGUgbmFtZSBwYXJhbWV0ZXIgaXMgbnVsbCIpOwotICAgICAgICB9Ci0gICAgICAgIHRocm93IG5ldyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uKG5hbWUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPlNldCBhIGZlYXR1cmUgZm9yIHRoaXMgPGNvZGU+U2NoZW1hRmFjdG9yeTwvY29kZT4sCi0gICAgICoge0BsaW5rIFNjaGVtYX1zIGNyZWF0ZWQgYnkgdGhpcyBmYWN0b3J5LCBhbmQgYnkgZXh0ZW5zaW9uLAotICAgICAqIHtAbGluayBWYWxpZGF0b3J9cyBhbmQge0BsaW5rIFZhbGlkYXRvckhhbmRsZXJ9cyBjcmVhdGVkIGJ5Ci0gICAgICogdGhvc2Uge0BsaW5rIFNjaGVtYX1zLgotICAgICAqIDwvcD4KLSAgICAgKgotICAgICAqIDxwPkltcGxlbWVudG9ycyBhbmQgZGV2ZWxvcGVycyBzaG91bGQgcGF5IHBhcnRpY3VsYXIgYXR0ZW50aW9uCi0gICAgICogdG8gaG93IHRoZSBzcGVjaWFsIHtAbGluayBTY2hlbWF9IG9iamVjdCByZXR1cm5lZCBieSB7QGxpbmsKLSAgICAgKiAjbmV3U2NoZW1hKCl9IGlzIHByb2Nlc3NlZC4gSW4gc29tZSBjYXNlcywgZm9yIGV4YW1wbGUsIHdoZW4gdGhlCi0gICAgICogPGNvZGU+U2NoZW1hRmFjdG9yeTwvY29kZT4gYW5kIHRoZSBjbGFzcyBhY3R1YWxseSBsb2FkaW5nIHRoZQotICAgICAqIHNjaGVtYSBjb21lIGZyb20gZGlmZmVyZW50IGltcGxlbWVudGF0aW9ucywgaXQgbWF5IG5vdCBiZSBwb3NzaWJsZQotICAgICAqIGZvciA8Y29kZT5TY2hlbWFGYWN0b3J5PC9jb2RlPiBmZWF0dXJlcyB0byBiZSBpbmhlcml0ZWQgYXV0b21hdGljYWxseS4KLSAgICAgKiBEZXZlbG9wZXJzIHNob3VsZAotICAgICAqIG1ha2Ugc3VyZSB0aGF0IGZlYXR1cmVzLCBzdWNoIGFzIHNlY3VyZSBwcm9jZXNzaW5nLCBhcmUgZXhwbGljaXRseQotICAgICAqIHNldCBpbiBib3RoIHBsYWNlcy48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5UaGUgZmVhdHVyZSBuYW1lIGlzIGFueSBmdWxseS1xdWFsaWZpZWQgVVJJLiBJdCBpcwotICAgICAqIHBvc3NpYmxlIGZvciBhIHtAbGluayBTY2hlbWFGYWN0b3J5fSB0byBleHBvc2UgYSBmZWF0dXJlIHZhbHVlIGJ1dAotICAgICAqIHRvIGJlIHVuYWJsZSB0byBjaGFuZ2UgdGhlIGN1cnJlbnQgdmFsdWUuPC9wPgotICAgICAqCi0gICAgICogPHA+QWxsIGltcGxlbWVudGF0aW9ucyBhcmUgcmVxdWlyZWQgdG8gc3VwcG9ydCB0aGUge0BsaW5rIGphdmF4LnhtbC5YTUxDb25zdGFudHMjRkVBVFVSRV9TRUNVUkVfUFJPQ0VTU0lOR30gZmVhdHVyZS4KLSAgICAgKiBXaGVuIHRoZSBmZWF0dXJlIGlzOjwvcD4KLSAgICAgKiA8dWw+Ci0gICAgICogICA8bGk+Ci0gICAgICogICAgIDxjb2RlPnRydWU8L2NvZGU+OiB0aGUgaW1wbGVtZW50YXRpb24gd2lsbCBsaW1pdCBYTUwgcHJvY2Vzc2luZyB0byBjb25mb3JtIHRvIGltcGxlbWVudGF0aW9uIGxpbWl0cy4KLSAgICAgKiAgICAgRXhhbXBsZXMgaW5jbHVkZSBlbml0eSBleHBhbnNpb24gbGltaXRzIGFuZCBYTUwgU2NoZW1hIGNvbnN0cnVjdHMgdGhhdCB3b3VsZCBjb25zdW1lIGxhcmdlIGFtb3VudHMgb2YgcmVzb3VyY2VzLgotICAgICAqICAgICBJZiBYTUwgcHJvY2Vzc2luZyBpcyBsaW1pdGVkIGZvciBzZWN1cml0eSByZWFzb25zLCBpdCB3aWxsIGJlIHJlcG9ydGVkIHZpYSBhIGNhbGwgdG8gdGhlIHJlZ2lzdGVyZWQKLSAgICAgKiAgICB7QGxpbmsgRXJyb3JIYW5kbGVyI2ZhdGFsRXJyb3IoU0FYUGFyc2VFeGNlcHRpb24gZXhjZXB0aW9uKX0uCi0gICAgICogICAgIFNlZSB7QGxpbmsgI3NldEVycm9ySGFuZGxlcihFcnJvckhhbmRsZXIgZXJyb3JIYW5kbGVyKX0uCi0gICAgICogICA8L2xpPgotICAgICAqICAgPGxpPgotICAgICAqICAgICA8Y29kZT5mYWxzZTwvY29kZT46IHRoZSBpbXBsZW1lbnRhdGlvbiB3aWxsIHByb2Nlc3NpbmcgWE1MIGFjY29yZGluZyB0byB0aGUgWE1MIHNwZWNpZmljYXRpb25zIHdpdGhvdXQKLSAgICAgKiAgICAgcmVnYXJkIHRvIHBvc3NpYmxlIGltcGxlbWVudGF0aW9uIGxpbWl0cy4KLSAgICAgKiAgIDwvbGk+Ci0gICAgICogPC91bD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBmZWF0dXJlIG5hbWUsIHdoaWNoIGlzIGEgbm9uLW51bGwgZnVsbHktcXVhbGlmaWVkIFVSSS4KLSAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcXVlc3RlZCB2YWx1ZSBvZiB0aGUgZmVhdHVyZSAodHJ1ZSBvciBmYWxzZSkuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24gSWYgdGhlIGZlYXR1cmUKLSAgICAgKiAgIHZhbHVlIGNhbid0IGJlIGFzc2lnbmVkIG9yIHJldHJpZXZlZC4KLSAgICAgKiBAdGhyb3dzIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBXaGVuIHRoZQotICAgICAqICAge0BsaW5rIFNjaGVtYUZhY3Rvcnl9IHJlY29nbml6ZXMgdGhlIGZlYXR1cmUgbmFtZSBidXQKLSAgICAgKiAgIGNhbm5vdCBzZXQgdGhlIHJlcXVlc3RlZCB2YWx1ZS4KLSAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIElmIDxjb2RlPm5hbWU8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAqCi0gICAgICogQHNlZSAjZ2V0RmVhdHVyZShTdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RmVhdHVyZShTdHJpbmcgbmFtZSwgYm9vbGVhbiB2YWx1ZSkKLSAgICAgICAgdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgaWYgKG5hbWUgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigidGhlIG5hbWUgcGFyYW1ldGVyIGlzIG51bGwiKTsKLSAgICAgICAgfQotICAgICAgICB0aHJvdyBuZXcgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbihuYW1lKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIHZhbHVlIG9mIGEgcHJvcGVydHkuCi0gICAgICoKLSAgICAgKiA8cD5UaGUgcHJvcGVydHkgbmFtZSBpcyBhbnkgZnVsbHktcXVhbGlmaWVkIFVSSS4gIEl0IGlzCi0gICAgICogcG9zc2libGUgZm9yIGEge0BsaW5rIFNjaGVtYUZhY3Rvcnl9IHRvIHJlY29nbml6ZSBhIHByb3BlcnR5IG5hbWUgYnV0Ci0gICAgICogdG8gYmUgdW5hYmxlIHRvIGNoYW5nZSB0aGUgY3VycmVudCB2YWx1ZS48L3A+Ci0gICAgICoKLSAgICAgKiA8cD4KLSAgICAgKiBBbGwgaW1wbGVtZW50YXRpb25zIHRoYXQgaW1wbGVtZW50IEpBWFAgMS41IG9yIG5ld2VyIGFyZSByZXF1aXJlZCB0bwotICAgICAqIHN1cHBvcnQgdGhlIHtAbGluayBqYXZheC54bWwuWE1MQ29uc3RhbnRzI0FDQ0VTU19FWFRFUk5BTF9EVER9IGFuZAotICAgICAqIHtAbGluayBqYXZheC54bWwuWE1MQ29uc3RhbnRzI0FDQ0VTU19FWFRFUk5BTF9TQ0hFTUF9IHByb3BlcnRpZXMuCi0gICAgICogPC9wPgotICAgICAqIDx1bD4KLSAgICAgKiAgIDxsaT4KLSAgICAgKiAgICAgIDxwPkFjY2VzcyB0byBleHRlcm5hbCBEVERzIGluIFNjaGVtYSBmaWxlcyBpcyByZXN0cmljdGVkIHRvIHRoZSBwcm90b2NvbHMKLSAgICAgKiAgICAgIHNwZWNpZmllZCBieSB0aGUge0BsaW5rIGphdmF4LnhtbC5YTUxDb25zdGFudHMjQUNDRVNTX0VYVEVSTkFMX0RURH0gcHJvcGVydHkuCi0gICAgICogICAgICBJZiBhY2Nlc3MgaXMgZGVuaWVkIGR1cmluZyB0aGUgY3JlYXRpb24gb2YgbmV3IFNjaGVtYSBkdWUgdG8gdGhlIHJlc3RyaWN0aW9uCi0gICAgICogICAgICBvZiB0aGlzIHByb3BlcnR5LCB7QGxpbmsgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9ufSB3aWxsIGJlIHRocm93biBieSB0aGUKLSAgICAgKiAgICAgIHtAbGluayAjbmV3U2NoZW1hKFNvdXJjZSl9IG9yIHtAbGluayAjbmV3U2NoZW1hKEZpbGUpfQotICAgICAqICAgICAgb3Ige0BsaW5rICNuZXdTY2hlbWEoVVJMKX0gb3IgIG9yIHtAbGluayAjbmV3U2NoZW1hKFNvdXJjZVtdKX0gbWV0aG9kLjwvcD4KLSAgICAgKgotICAgICAqICAgICAgPHA+QWNjZXNzIHRvIGV4dGVybmFsIERURHMgaW4geG1sIHNvdXJjZSBmaWxlcyBpcyByZXN0cmljdGVkIHRvIHRoZSBwcm90b2NvbHMKLSAgICAgKiAgICAgIHNwZWNpZmllZCBieSB0aGUge0BsaW5rIGphdmF4LnhtbC5YTUxDb25zdGFudHMjQUNDRVNTX0VYVEVSTkFMX0RURH0gcHJvcGVydHkuCi0gICAgICogICAgICBJZiBhY2Nlc3MgaXMgZGVuaWVkIGR1cmluZyB2YWxpZGF0aW9uIGR1ZSB0byB0aGUgcmVzdHJpY3Rpb24KLSAgICAgKiAgICAgIG9mIHRoaXMgcHJvcGVydHksIHtAbGluayBvcmcueG1sLnNheC5TQVhFeGNlcHRpb259IHdpbGwgYmUgdGhyb3duIGJ5IHRoZQotICAgICAqICAgICAge0BsaW5rIGphdmF4LnhtbC52YWxpZGF0aW9uLlZhbGlkYXRvciN2YWxpZGF0ZShTb3VyY2UpfSBvcgotICAgICAqICAgICAge0BsaW5rIGphdmF4LnhtbC52YWxpZGF0aW9uLlZhbGlkYXRvciN2YWxpZGF0ZShTb3VyY2UsIFJlc3VsdCl9IG1ldGhvZC48L3A+Ci0gICAgICoKLSAgICAgKiAgICAgIDxwPkFjY2VzcyB0byBleHRlcm5hbCByZWZlcmVuY2Ugc2V0IGJ5IHRoZSBzY2hlbWFMb2NhdGlvbiBhdHRyaWJ1dGUgaXMKLSAgICAgKiAgICAgIHJlc3RyaWN0ZWQgdG8gdGhlIHByb3RvY29scyBzcGVjaWZpZWQgYnkgdGhlCi0gICAgICogICAgICB7QGxpbmsgamF2YXgueG1sLlhNTENvbnN0YW50cyNBQ0NFU1NfRVhURVJOQUxfU0NIRU1BfSBwcm9wZXJ0eS4KLSAgICAgKiAgICAgIElmIGFjY2VzcyBpcyBkZW5pZWQgZHVyaW5nIHZhbGlkYXRpb24gZHVlIHRvIHRoZSByZXN0cmljdGlvbiBvZiB0aGlzIHByb3BlcnR5LAotICAgICAqICAgICAge0BsaW5rIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbn0gd2lsbCBiZSB0aHJvd24gYnkgdGhlCi0gICAgICogICAgICB7QGxpbmsgamF2YXgueG1sLnZhbGlkYXRpb24uVmFsaWRhdG9yI3ZhbGlkYXRlKFNvdXJjZSl9IG9yCi0gICAgICogICAgICB7QGxpbmsgamF2YXgueG1sLnZhbGlkYXRpb24uVmFsaWRhdG9yI3ZhbGlkYXRlKFNvdXJjZSwgUmVzdWx0KX0gbWV0aG9kLjwvcD4KLSAgICAgKgotICAgICAqICAgICAgPHA+QWNjZXNzIHRvIGV4dGVybmFsIHJlZmVyZW5jZSBzZXQgYnkgdGhlIEltcG9ydAotICAgICAqICAgICAgYW5kIEluY2x1ZGUgZWxlbWVudCBpcyByZXN0cmljdGVkIHRvIHRoZSBwcm90b2NvbHMgc3BlY2lmaWVkIGJ5IHRoZQotICAgICAqICAgICAge0BsaW5rIGphdmF4LnhtbC5YTUxDb25zdGFudHMjQUNDRVNTX0VYVEVSTkFMX1NDSEVNQX0gcHJvcGVydHkuCi0gICAgICogICAgICBJZiBhY2Nlc3MgaXMgZGVuaWVkIGR1cmluZyB0aGUgY3JlYXRpb24gb2YgbmV3IFNjaGVtYSBkdWUgdG8gdGhlIHJlc3RyaWN0aW9uCi0gICAgICogICAgICBvZiB0aGlzIHByb3BlcnR5LCB7QGxpbmsgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9ufSB3aWxsIGJlIHRocm93biBieSB0aGUKLSAgICAgKiAgICAgIHtAbGluayAjbmV3U2NoZW1hKFNvdXJjZSl9IG9yIHtAbGluayAjbmV3U2NoZW1hKEZpbGUpfQotICAgICAqICAgICAgb3Ige0BsaW5rICNuZXdTY2hlbWEoVVJMKX0gb3Ige0BsaW5rICNuZXdTY2hlbWEoU291cmNlW10pfSBtZXRob2QuPC9wPgotICAgICAqICAgPC9saT4KLSAgICAgKiA8L3VsPgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgVGhlIHByb3BlcnR5IG5hbWUsIHdoaWNoIGlzIGEgbm9uLW51bGwgZnVsbHktcXVhbGlmaWVkIFVSSS4KLSAgICAgKiBAcGFyYW0gb2JqZWN0IFRoZSByZXF1ZXN0ZWQgdmFsdWUgZm9yIHRoZSBwcm9wZXJ0eS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiBJZiB0aGUgcHJvcGVydHkKLSAgICAgKiAgIHZhbHVlIGNhbid0IGJlIGFzc2lnbmVkIG9yIHJldHJpZXZlZC4KLSAgICAgKiBAdGhyb3dzIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBXaGVuIHRoZQotICAgICAqICAge0BsaW5rIFNjaGVtYUZhY3Rvcnl9IHJlY29nbml6ZXMgdGhlIHByb3BlcnR5IG5hbWUgYnV0Ci0gICAgICogICBjYW5ub3Qgc2V0IHRoZSByZXF1ZXN0ZWQgdmFsdWUuCi0gICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBJZiA8Y29kZT5uYW1lPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRQcm9wZXJ0eShTdHJpbmcgbmFtZSwgT2JqZWN0IG9iamVjdCkKLSAgICAgICAgdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgaWYgKG5hbWUgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigidGhlIG5hbWUgcGFyYW1ldGVyIGlzIG51bGwiKTsKLSAgICAgICAgfQotICAgICAgICB0aHJvdyBuZXcgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbihuYW1lKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBMb29rIHVwIHRoZSB2YWx1ZSBvZiBhIHByb3BlcnR5LgotICAgICAqCi0gICAgICogPHA+VGhlIHByb3BlcnR5IG5hbWUgaXMgYW55IGZ1bGx5LXF1YWxpZmllZCBVUkkuICBJdCBpcwotICAgICAqIHBvc3NpYmxlIGZvciBhIHtAbGluayBTY2hlbWFGYWN0b3J5fSB0byByZWNvZ25pemUgYSBwcm9wZXJ0eSBuYW1lIGJ1dAotICAgICAqIHRlbXBvcmFyaWx5IGJlIHVuYWJsZSB0byByZXR1cm4gaXRzIHZhbHVlLjwvcD4KLSAgICAgKgotICAgICAqIDxwPntAbGluayBTY2hlbWFGYWN0b3J5fXMgYXJlIG5vdCByZXF1aXJlZCB0byByZWNvZ25pemUgYW55IHNwZWNpZmljCi0gICAgICogcHJvcGVydHkgbmFtZXMuPC9wPgotICAgICAqCi0gICAgICogPHA+SW1wbGVtZW50b3JzIGFyZSBmcmVlIChhbmQgZW5jb3VyYWdlZCkgdG8gaW52ZW50IHRoZWlyIG93biBwcm9wZXJ0aWVzLAotICAgICAqIHVzaW5nIG5hbWVzIGJ1aWx0IG9uIHRoZWlyIG93biBVUklzLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBwcm9wZXJ0eSBuYW1lLCB3aGljaCBpcyBhIG5vbi1udWxsIGZ1bGx5LXF1YWxpZmllZCBVUkkuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBjdXJyZW50IHZhbHVlIG9mIHRoZSBwcm9wZXJ0eS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiBJZiB0aGUgcHJvcGVydHkKLSAgICAgKiAgIHZhbHVlIGNhbid0IGJlIGFzc2lnbmVkIG9yIHJldHJpZXZlZC4KLSAgICAgKiBAdGhyb3dzIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBXaGVuIHRoZQotICAgICAqICAgWE1MUmVhZGVyIHJlY29nbml6ZXMgdGhlIHByb3BlcnR5IG5hbWUgYnV0Ci0gICAgICogICBjYW5ub3QgZGV0ZXJtaW5lIGl0cyB2YWx1ZSBhdCB0aGlzIHRpbWUuCi0gICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBJZiA8Y29kZT5uYW1lPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICAgKgotICAgICAqIEBzZWUgI3NldFByb3BlcnR5KFN0cmluZywgT2JqZWN0KQotICAgICAqLwotICAgIHB1YmxpYyBPYmplY3QgZ2V0UHJvcGVydHkoU3RyaW5nIG5hbWUpCi0gICAgICAgIHRocm93cyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uLCBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gewotCi0gICAgICAgIGlmIChuYW1lID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oInRoZSBuYW1lIHBhcmFtZXRlciBpcyBudWxsIik7Ci0gICAgICAgIH0KLSAgICAgICAgdGhyb3cgbmV3IFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24obmFtZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0cyB0aGUge0BsaW5rIEVycm9ySGFuZGxlcn0gdG8gcmVjZWl2ZSBlcnJvcnMgZW5jb3VudGVyZWQKLSAgICAgKiBkdXJpbmcgdGhlIDxjb2RlPm5ld1NjaGVtYTwvY29kZT4gbWV0aG9kIGludm9jYXRpb24uCi0gICAgICoKLSAgICAgKiA8cD4KLSAgICAgKiBFcnJvciBoYW5kbGVyIGNhbiBiZSB1c2VkIHRvIGN1c3RvbWl6ZSB0aGUgZXJyb3IgaGFuZGxpbmcgcHJvY2VzcwotICAgICAqIGR1cmluZyBzY2hlbWEgcGFyc2luZy4gV2hlbiBhbiB7QGxpbmsgRXJyb3JIYW5kbGVyfSBpcyBzZXQsCi0gICAgICogZXJyb3JzIGZvdW5kIGR1cmluZyB0aGUgcGFyc2luZyBvZiBzY2hlbWFzIHdpbGwgYmUgZmlyc3Qgc2VudAotICAgICAqIHRvIHRoZSB7QGxpbmsgRXJyb3JIYW5kbGVyfS4KLSAgICAgKgotICAgICAqIDxwPgotICAgICAqIFRoZSBlcnJvciBoYW5kbGVyIGNhbiBhYm9ydCB0aGUgcGFyc2luZyBvZiBhIHNjaGVtYSBpbW1lZGlhdGVseQotICAgICAqIGJ5IHRocm93aW5nIHtAbGluayBTQVhFeGNlcHRpb259IGZyb20gdGhlIGhhbmRsZXIuIE9yIGZvciBleGFtcGxlCi0gICAgICogaXQgY2FuIHByaW50IGFuIGVycm9yIHRvIHRoZSBzY3JlZW4gYW5kIHRyeSB0byBjb250aW51ZSB0aGUKLSAgICAgKiBwcm9jZXNzaW5nIGJ5IHJldHVybmluZyBub3JtYWxseSBmcm9tIHRoZSB7QGxpbmsgRXJyb3JIYW5kbGVyfQotICAgICAqCi0gICAgICogPHA+Ci0gICAgICogSWYgYW55IHtAbGluayBUaHJvd2FibGV9IChvciBpbnN0YW5jZXMgb2YgaXRzIGRlcml2ZWQgY2xhc3NlcykKLSAgICAgKiBpcyB0aHJvd24gZnJvbSBhbiB7QGxpbmsgRXJyb3JIYW5kbGVyfSwKLSAgICAgKiB0aGUgY2FsbGVyIG9mIHRoZSA8Y29kZT5uZXdTY2hlbWE8L2NvZGU+IG1ldGhvZCB3aWxsIGJlIHRocm93bgotICAgICAqIHRoZSBzYW1lIHtAbGluayBUaHJvd2FibGV9IG9iamVjdC4KLSAgICAgKgotICAgICAqIDxwPgotICAgICAqIHtAbGluayBTY2hlbWFGYWN0b3J5fSBpcyBub3QgYWxsb3dlZCB0bwotICAgICAqIHRocm93IHtAbGluayBTQVhFeGNlcHRpb259IHdpdGhvdXQgZmlyc3QgcmVwb3J0aW5nIGl0IHRvCi0gICAgICoge0BsaW5rIEVycm9ySGFuZGxlcn0uCi0gICAgICoKLSAgICAgKiA8cD4KLSAgICAgKiBBcHBsaWNhdGlvbnMgY2FuIGNhbGwgdGhpcyBtZXRob2QgZXZlbiBkdXJpbmcgYSB7QGxpbmsgU2NoZW1hfQotICAgICAqIGlzIGJlaW5nIHBhcnNlZC4KLSAgICAgKgotICAgICAqIDxwPgotICAgICAqIFdoZW4gdGhlIHtAbGluayBFcnJvckhhbmRsZXJ9IGlzIG51bGwsIHRoZSBpbXBsZW1lbnRhdGlvbiB3aWxsCi0gICAgICogYmVoYXZlIGFzIGlmIHRoZSBmb2xsb3dpbmcge0BsaW5rIEVycm9ySGFuZGxlcn0gaXMgc2V0OgotICAgICAqIDxwcmU+Ci0gICAgICogY2xhc3MgRHJhY29uaWFuRXJyb3JIYW5kbGVyIGltcGxlbWVudHMge0BsaW5rIEVycm9ySGFuZGxlcn0gewotICAgICAqICAgICBwdWJsaWMgdm9pZCBmYXRhbEVycm9yKCB7QGxpbmsgb3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb259IGUgKSB0aHJvd3Mge0BsaW5rIFNBWEV4Y2VwdGlvbn0gewotICAgICAqICAgICAgICAgdGhyb3cgZTsKLSAgICAgKiAgICAgfQotICAgICAqICAgICBwdWJsaWMgdm9pZCBlcnJvcigge0BsaW5rIG9yZy54bWwuc2F4LlNBWFBhcnNlRXhjZXB0aW9ufSBlICkgdGhyb3dzIHtAbGluayBTQVhFeGNlcHRpb259IHsKLSAgICAgKiAgICAgICAgIHRocm93IGU7Ci0gICAgICogICAgIH0KLSAgICAgKiAgICAgcHVibGljIHZvaWQgd2FybmluZygge0BsaW5rIG9yZy54bWwuc2F4LlNBWFBhcnNlRXhjZXB0aW9ufSBlICkgdGhyb3dzIHtAbGluayBTQVhFeGNlcHRpb259IHsKLSAgICAgKiAgICAgICAgIC8vIG5vb3AKLSAgICAgKiAgICAgfQotICAgICAqIH0KLSAgICAgKiA8L3ByZT4KLSAgICAgKgotICAgICAqIDxwPgotICAgICAqIFdoZW4gYSBuZXcge0BsaW5rIFNjaGVtYUZhY3Rvcnl9IG9iamVjdCBpcyBjcmVhdGVkLCBpbml0aWFsbHkKLSAgICAgKiB0aGlzIGZpZWxkIGlzIHNldCB0byBudWxsLiBUaGlzIGZpZWxkIHdpbGwgPGVtPk5PVDwvZW0+IGJlCi0gICAgICogaW5oZXJpdGVkIHRvIHtAbGluayBTY2hlbWF9cywge0BsaW5rIFZhbGlkYXRvcn1zLCBvcgotICAgICAqIHtAbGluayBWYWxpZGF0b3JIYW5kbGVyfXMgdGhhdCBhcmUgY3JlYXRlZCBmcm9tIHRoaXMge0BsaW5rIFNjaGVtYUZhY3Rvcnl9LgotICAgICAqCi0gICAgICogQHBhcmFtIGVycm9ySGFuZGxlciBBIG5ldyBlcnJvciBoYW5kbGVyIHRvIGJlIHNldC4KLSAgICAgKiAgIFRoaXMgcGFyYW1ldGVyIGNhbiBiZSA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRFcnJvckhhbmRsZXIoRXJyb3JIYW5kbGVyIGVycm9ySGFuZGxlcik7Ci0KLSAgICAvKioKLSAgICAgKiBHZXRzIHRoZSBjdXJyZW50IHtAbGluayBFcnJvckhhbmRsZXJ9IHNldCB0byB0aGlzIHtAbGluayBTY2hlbWFGYWN0b3J5fS4KLSAgICAgKgotICAgICAqIEByZXR1cm4KLSAgICAgKiAgICAgIFRoaXMgbWV0aG9kIHJldHVybnMgdGhlIG9iamVjdCB0aGF0IHdhcyBsYXN0IHNldCB0aHJvdWdoCi0gICAgICogICAgICB0aGUge0BsaW5rICNzZXRFcnJvckhhbmRsZXIoRXJyb3JIYW5kbGVyKX0gbWV0aG9kLCBvciBudWxsCi0gICAgICogICAgICBpZiB0aGF0IG1ldGhvZCBoYXMgbmV2ZXIgYmVlbiBjYWxsZWQgc2luY2UgdGhpcyB7QGxpbmsgU2NoZW1hRmFjdG9yeX0KLSAgICAgKiAgICAgIGhhcyBjcmVhdGVkLgotICAgICAqCi0gICAgICogQHNlZSAjc2V0RXJyb3JIYW5kbGVyKEVycm9ySGFuZGxlcikKLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3QgRXJyb3JIYW5kbGVyIGdldEVycm9ySGFuZGxlcigpOwotCi0gICAgLyoqCi0gICAgICogU2V0cyB0aGUge0BsaW5rIExTUmVzb3VyY2VSZXNvbHZlcn0gdG8gY3VzdG9taXplCi0gICAgICogcmVzb3VyY2UgcmVzb2x1dGlvbiB3aGVuIHBhcnNpbmcgc2NoZW1hcy4KLSAgICAgKgotICAgICAqIDxwPgotICAgICAqIHtAbGluayBTY2hlbWFGYWN0b3J5fSB1c2VzIGEge0BsaW5rIExTUmVzb3VyY2VSZXNvbHZlcn0KLSAgICAgKiB3aGVuIGl0IG5lZWRzIHRvIGxvY2F0ZSBleHRlcm5hbCByZXNvdXJjZXMgd2hpbGUgcGFyc2luZyBzY2hlbWFzLAotICAgICAqIGFsdGhvdWdoIGV4YWN0bHkgd2hhdCBjb25zdGl0dXRlcyAibG9jYXRpbmcgZXh0ZXJuYWwgcmVzb3VyY2VzIiBpcwotICAgICAqIHVwIHRvIGVhY2ggc2NoZW1hIGxhbmd1YWdlLiBGb3IgZXhhbXBsZSwgZm9yIFczQyBYTUwgU2NoZW1hLAotICAgICAqIHRoaXMgaW5jbHVkZXMgZmlsZXMgPGNvZGU+Jmx0O2luY2x1ZGU+PC9jb2RlPmQgb3IgPGNvZGU+Jmx0O2ltcG9ydD48L2NvZGU+ZWQsCi0gICAgICogYW5kIERURCByZWZlcmVuY2VkIGZyb20gc2NoZW1hIGZpbGVzLCBldGMuCi0gICAgICoKLSAgICAgKiA8cD4KLSAgICAgKiBBcHBsaWNhdGlvbnMgY2FuIGNhbGwgdGhpcyBtZXRob2QgZXZlbiBkdXJpbmcgYSB7QGxpbmsgU2NoZW1hfQotICAgICAqIGlzIGJlaW5nIHBhcnNlZC4KLSAgICAgKgotICAgICAqIDxwPgotICAgICAqIFdoZW4gdGhlIHtAbGluayBMU1Jlc291cmNlUmVzb2x2ZXJ9IGlzIG51bGwsIHRoZSBpbXBsZW1lbnRhdGlvbiB3aWxsCi0gICAgICogYmVoYXZlIGFzIGlmIHRoZSBmb2xsb3dpbmcge0BsaW5rIExTUmVzb3VyY2VSZXNvbHZlcn0gaXMgc2V0OgotICAgICAqIDxwcmU+Ci0gICAgICogY2xhc3MgRHVtYkRPTVJlc291cmNlUmVzb2x2ZXIgaW1wbGVtZW50cyB7QGxpbmsgTFNSZXNvdXJjZVJlc29sdmVyfSB7Ci0gICAgICogICAgIHB1YmxpYyB7QGxpbmsgb3JnLnczYy5kb20ubHMuTFNJbnB1dH0gcmVzb2x2ZVJlc291cmNlKAotICAgICAqICAgICAgICAgU3RyaW5nIHB1YmxpY0lkLCBTdHJpbmcgc3lzdGVtSWQsIFN0cmluZyBiYXNlVVJJKSB7Ci0gICAgICoKLSAgICAgKiAgICAgICAgIHJldHVybiBudWxsOyAvLyBhbHdheXMgcmV0dXJuIG51bGwKLSAgICAgKiAgICAgfQotICAgICAqIH0KLSAgICAgKiA8L3ByZT4KLSAgICAgKgotICAgICAqIDxwPgotICAgICAqIElmIGEge0BsaW5rIExTUmVzb3VyY2VSZXNvbHZlcn0gdGhyb3dzIGEge0BsaW5rIFJ1bnRpbWVFeGNlcHRpb259Ci0gICAgICogIChvciBpbnN0YW5jZXMgb2YgaXRzIGRlcml2ZWQgY2xhc3NlcyksCi0gICAgICogdGhlbiB0aGUge0BsaW5rIFNjaGVtYUZhY3Rvcnl9IHdpbGwgYWJvcnQgdGhlIHBhcnNpbmcgYW5kCi0gICAgICogdGhlIGNhbGxlciBvZiB0aGUgPGNvZGU+bmV3U2NoZW1hPC9jb2RlPiBtZXRob2Qgd2lsbCByZWNlaXZlCi0gICAgICogdGhlIHNhbWUge0BsaW5rIFJ1bnRpbWVFeGNlcHRpb259LgotICAgICAqCi0gICAgICogPHA+Ci0gICAgICogV2hlbiBhIG5ldyB7QGxpbmsgU2NoZW1hRmFjdG9yeX0gb2JqZWN0IGlzIGNyZWF0ZWQsIGluaXRpYWxseQotICAgICAqIHRoaXMgZmllbGQgaXMgc2V0IHRvIG51bGwuICBUaGlzIGZpZWxkIHdpbGwgPGVtPk5PVDwvZW0+IGJlCi0gICAgICogaW5oZXJpdGVkIHRvIHtAbGluayBTY2hlbWF9cywge0BsaW5rIFZhbGlkYXRvcn1zLCBvcgotICAgICAqIHtAbGluayBWYWxpZGF0b3JIYW5kbGVyfXMgdGhhdCBhcmUgY3JlYXRlZCBmcm9tIHRoaXMge0BsaW5rIFNjaGVtYUZhY3Rvcnl9LgotICAgICAqCi0gICAgICogQHBhcmFtICAgcmVzb3VyY2VSZXNvbHZlcgotICAgICAqICAgICAgQSBuZXcgcmVzb3VyY2UgcmVzb2x2ZXIgdG8gYmUgc2V0LiBUaGlzIHBhcmFtZXRlciBjYW4gYmUgbnVsbC4KLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRSZXNvdXJjZVJlc29sdmVyKExTUmVzb3VyY2VSZXNvbHZlciByZXNvdXJjZVJlc29sdmVyKTsKLQotICAgIC8qKgotICAgICAqIEdldHMgdGhlIGN1cnJlbnQge0BsaW5rIExTUmVzb3VyY2VSZXNvbHZlcn0gc2V0IHRvIHRoaXMge0BsaW5rIFNjaGVtYUZhY3Rvcnl9LgotICAgICAqCi0gICAgICogQHJldHVybgotICAgICAqICAgICAgVGhpcyBtZXRob2QgcmV0dXJucyB0aGUgb2JqZWN0IHRoYXQgd2FzIGxhc3Qgc2V0IHRocm91Z2gKLSAgICAgKiAgICAgIHRoZSB7QGxpbmsgI3NldFJlc291cmNlUmVzb2x2ZXIoTFNSZXNvdXJjZVJlc29sdmVyKX0gbWV0aG9kLCBvciBudWxsCi0gICAgICogICAgICBpZiB0aGF0IG1ldGhvZCBoYXMgbmV2ZXIgYmVlbiBjYWxsZWQgc2luY2UgdGhpcyB7QGxpbmsgU2NoZW1hRmFjdG9yeX0KLSAgICAgKiAgICAgIGhhcyBjcmVhdGVkLgotICAgICAqCi0gICAgICogQHNlZSAjc2V0RXJyb3JIYW5kbGVyKEVycm9ySGFuZGxlcikKLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3QgTFNSZXNvdXJjZVJlc29sdmVyIGdldFJlc291cmNlUmVzb2x2ZXIoKTsKLQotICAgIC8qKgotICAgICAqIDxwPlBhcnNlcyB0aGUgc3BlY2lmaWVkIHNvdXJjZSBhcyBhIHNjaGVtYSBhbmQgcmV0dXJucyBpdCBhcyBhIHNjaGVtYS48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5UaGlzIGlzIGEgY29udmVuaWVuY2UgbWV0aG9kIGZvciB7QGxpbmsgI25ld1NjaGVtYShTb3VyY2VbXSBzY2hlbWFzKX0uPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIHNjaGVtYSBTb3VyY2UgdGhhdCByZXByZXNlbnRzIGEgc2NoZW1hLgotICAgICAqCi0gICAgICogQHJldHVybiBOZXcgPGNvZGU+U2NoZW1hPC9jb2RlPiBmcm9tIHBhcnNpbmcgPGNvZGU+c2NoZW1hPC9jb2RlPi4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uIElmIGEgU0FYIGVycm9yIG9jY3VycyBkdXJpbmcgcGFyc2luZy4KLSAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIDxjb2RlPnNjaGVtYTwvY29kZT4gaXMgbnVsbC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU2NoZW1hIG5ld1NjaGVtYShTb3VyY2Ugc2NoZW1hKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICAgICAgcmV0dXJuIG5ld1NjaGVtYShuZXcgU291cmNlW117c2NoZW1hfSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+UGFyc2VzIHRoZSBzcGVjaWZpZWQgPGNvZGU+RmlsZTwvY29kZT4gYXMgYSBzY2hlbWEgYW5kIHJldHVybnMgaXQgYXMgYSA8Y29kZT5TY2hlbWE8L2NvZGU+LjwvcD4KLSAgICAgKgotICAgICAqIDxwPlRoaXMgaXMgYSBjb252ZW5pZW5jZSBtZXRob2QgZm9yIHtAbGluayAjbmV3U2NoZW1hKFNvdXJjZSBzY2hlbWEpfS48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gc2NoZW1hIEZpbGUgdGhhdCByZXByZXNlbnRzIGEgc2NoZW1hLgotICAgICAqCi0gICAgICogQHJldHVybiBOZXcgPGNvZGU+U2NoZW1hPC9jb2RlPiBmcm9tIHBhcnNpbmcgPGNvZGU+c2NoZW1hPC9jb2RlPi4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uIElmIGEgU0FYIGVycm9yIG9jY3VycyBkdXJpbmcgcGFyc2luZy4KLSAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIDxjb2RlPnNjaGVtYTwvY29kZT4gaXMgbnVsbC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU2NoZW1hIG5ld1NjaGVtYShGaWxlIHNjaGVtYSkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0gICAgICAgIHJldHVybiBuZXdTY2hlbWEobmV3IFN0cmVhbVNvdXJjZShzY2hlbWEpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5QYXJzZXMgdGhlIHNwZWNpZmllZCA8Y29kZT5VUkw8L2NvZGU+IGFzIGEgc2NoZW1hIGFuZCByZXR1cm5zIGl0IGFzIGEgPGNvZGU+U2NoZW1hPC9jb2RlPi48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5UaGlzIGlzIGEgY29udmVuaWVuY2UgbWV0aG9kIGZvciB7QGxpbmsgI25ld1NjaGVtYShTb3VyY2Ugc2NoZW1hKX0uPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIHNjaGVtYSA8Y29kZT5VUkw8L2NvZGU+IHRoYXQgcmVwcmVzZW50cyBhIHNjaGVtYS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gTmV3IDxjb2RlPlNjaGVtYTwvY29kZT4gZnJvbSBwYXJzaW5nIDxjb2RlPnNjaGVtYTwvY29kZT4uCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBJZiBhIFNBWCBlcnJvciBvY2N1cnMgZHVyaW5nIHBhcnNpbmcuCi0gICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiA8Y29kZT5zY2hlbWE8L2NvZGU+IGlzIG51bGwuCi0gICAgICovCi0gICAgcHVibGljIFNjaGVtYSBuZXdTY2hlbWEoVVJMIHNjaGVtYSkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0gICAgICAgIHJldHVybiBuZXdTY2hlbWEobmV3IFN0cmVhbVNvdXJjZShzY2hlbWEudG9FeHRlcm5hbEZvcm0oKSkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFBhcnNlcyB0aGUgc3BlY2lmaWVkIHNvdXJjZShzKSBhcyBhIHNjaGVtYSBhbmQgcmV0dXJucyBpdCBhcyBhIHNjaGVtYS4KLSAgICAgKgotICAgICAqIDxwPgotICAgICAqIFRoZSBjYWxsZWUgd2lsbCByZWFkIGFsbCB0aGUge0BsaW5rIFNvdXJjZX1zIGFuZCBjb21iaW5lIHRoZW0gaW50byBhCi0gICAgICogc2luZ2xlIHNjaGVtYS4gVGhlIGV4YWN0IHNlbWFudGljcyBvZiB0aGUgY29tYmluYXRpb24gZGVwZW5kcyBvbiB0aGUgc2NoZW1hCi0gICAgICogbGFuZ3VhZ2UgdGhhdCB0aGlzIHtAbGluayBTY2hlbWFGYWN0b3J5fSBvYmplY3QgaXMgY3JlYXRlZCBmb3IuCi0gICAgICoKLSAgICAgKiA8cD4KLSAgICAgKiBXaGVuIGFuIHtAbGluayBFcnJvckhhbmRsZXJ9IGlzIHNldCwgdGhlIGNhbGxlZSB3aWxsIHJlcG9ydCBhbGwgdGhlIGVycm9ycwotICAgICAqIGZvdW5kIGluIHNvdXJjZXMgdG8gdGhlIGhhbmRsZXIuIElmIHRoZSBoYW5kbGVyIHRocm93cyBhbiBleGNlcHRpb24sIGl0IHdpbGwKLSAgICAgKiBhYm9ydCB0aGUgc2NoZW1hIGNvbXBpbGF0aW9uIGFuZCB0aGUgc2FtZSBleGNlcHRpb24gd2lsbCBiZSB0aHJvd24gZnJvbQotICAgICAqIHRoaXMgbWV0aG9kLiBBbHNvLCBhZnRlciBhbiBlcnJvciBpcyByZXBvcnRlZCB0byBhIGhhbmRsZXIsIHRoZSBjYWxsZWUgaXMgYWxsb3dlZAotICAgICAqIHRvIGFib3J0IHRoZSBmdXJ0aGVyIHByb2Nlc3NpbmcgYnkgdGhyb3dpbmcgaXQuIElmIGFuIGVycm9yIGhhbmRsZXIgaXMgbm90IHNldCwKLSAgICAgKiB0aGUgY2FsbGVlIHdpbGwgdGhyb3cgdGhlIGZpcnN0IGVycm9yIGl0IGZpbmRzIGluIHRoZSBzb3VyY2VzLgotICAgICAqCi0gICAgICogPGgyPlczQyBYTUwgU2NoZW1hIDEuMDwvaDI+Ci0gICAgICogPHA+Ci0gICAgICogVGhlIHJlc3VsdGluZyBzY2hlbWEgY29udGFpbnMgY29tcG9uZW50cyBmcm9tIHRoZSBzcGVjaWZpZWQgc291cmNlcy4KLSAgICAgKiBUaGUgc2FtZSByZXN1bHQgd291bGQgYmUgYWNoaWV2ZWQgaWYgYWxsIHRoZXNlIHNvdXJjZXMgd2VyZQotICAgICAqIGltcG9ydGVkLCB1c2luZyBhcHByb3ByaWF0ZSB2YWx1ZXMgZm9yIHNjaGVtYUxvY2F0aW9uIGFuZCBuYW1lc3BhY2UsCi0gICAgICogaW50byBhIHNpbmdsZSBzY2hlbWEgZG9jdW1lbnQgd2l0aCBhIGRpZmZlcmVudCB0YXJnZXROYW1lc3BhY2UKLSAgICAgKiBhbmQgbm8gY29tcG9uZW50cyBvZiBpdHMgb3duLCBpZiB0aGUgaW1wb3J0IGVsZW1lbnRzIHdlcmUgZ2l2ZW4KLSAgICAgKiBpbiB0aGUgc2FtZSBvcmRlciBhcyB0aGUgc291cmNlcy4gIFNlY3Rpb24gNC4yLjMgb2YgdGhlIFhNTCBTY2hlbWEKLSAgICAgKiByZWNvbW1lbmRhdGlvbiBkZXNjcmliZXMgdGhlIG9wdGlvbnMgcHJvY2Vzc29ycyBoYXZlIGluIHRoaXMKLSAgICAgKiByZWdhcmQuICBXaGlsZSBhIHByb2Nlc3NvciBzaG91bGQgYmUgY29uc2lzdGVudCBpbiBpdHMgdHJlYXRtZW50IG9mCi0gICAgICogSkFYUCBzY2hlbWEgc291cmNlcyBhbmQgWE1MIFNjaGVtYSBpbXBvcnRzLCB0aGUgYmVoYXZpb3VyIGJldHdlZW4KLSAgICAgKiBKQVhQLWNvbXBsaWFudCBwYXJzZXJzIG1heSB2YXJ5OyBpbiBwYXJ0aWN1bGFyLCBwYXJzZXJzIG1heSBjaG9vc2UKLSAgICAgKiB0byBpZ25vcmUgYWxsIGJ1dCB0aGUgZmlyc3QgJmx0O2ltcG9ydD4gZm9yIGEgZ2l2ZW4gbmFtZXNwYWNlLAotICAgICAqIHJlZ2FyZGxlc3Mgb2YgaW5mb3JtYXRpb24gcHJvdmlkZWQgaW4gc2NoZW1hTG9jYXRpb24uCi0gICAgICoKLSAgICAgKiA8cD4KLSAgICAgKiBJZiB0aGUgcGFyc2VkIHNldCBvZiBzY2hlbWFzIGluY2x1ZGVzIGVycm9yKHMpIGFzCi0gICAgICogc3BlY2lmaWVkIGluIHRoZSBzZWN0aW9uIDUuMSBvZiB0aGUgWE1MIFNjaGVtYSBzcGVjLCB0aGVuCi0gICAgICogdGhlIGVycm9yIG11c3QgYmUgcmVwb3J0ZWQgdG8gdGhlIHtAbGluayBFcnJvckhhbmRsZXJ9LgotICAgICAqCi0gICAgICogPGgyPlJFTEFYIE5HPC9oMj4KLSAgICAgKgotICAgICAqIDxwPkZvciBSRUxBWCBORywgdGhpcyBtZXRob2QgbXVzdCB0aHJvdyB7QGxpbmsgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb259Ci0gICAgICogaWYgPGNvZGU+c2NoZW1hcy5sZW5ndGghPTE8L2NvZGU+LgotICAgICAqCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc2NoZW1hcwotICAgICAqICAgICAgaW5wdXRzIHRvIGJlIHBhcnNlZC4ge0BsaW5rIFNjaGVtYUZhY3Rvcnl9IGlzIHJlcXVpcmVkCi0gICAgICogICAgICB0byByZWNvZ25pemUge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlNBWFNvdXJjZX0sCi0gICAgICogICAgICB7QGxpbmsgU3RyZWFtU291cmNlfSwKLSAgICAgKiAgICAgIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLnN0YXguU3RBWFNvdXJjZX0sCi0gICAgICogICAgICBhbmQge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uZG9tLkRPTVNvdXJjZX0uCi0gICAgICogICAgICBJbnB1dCBzY2hlbWFzIG11c3QgYmUgWE1MIGRvY3VtZW50cyBvcgotICAgICAqICAgICAgWE1MIGVsZW1lbnRzIGFuZCBtdXN0IG5vdCBiZSBudWxsLiBGb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHksCi0gICAgICogICAgICB0aGUgcmVzdWx0cyBvZiBwYXNzaW5nIGFueXRoaW5nIG90aGVyIHRoYW4KLSAgICAgKiAgICAgIGEgZG9jdW1lbnQgb3IgZWxlbWVudCBhcmUgaW1wbGVtZW50YXRpb24tZGVwZW5kZW50LgotICAgICAqICAgICAgSW1wbGVtZW50YXRpb25zIG11c3QgZWl0aGVyIHJlY29nbml6ZSBhbmQgcHJvY2VzcyB0aGUgaW5wdXQKLSAgICAgKiAgICAgIG9yIHRocm93biBhbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuCi0gICAgICogICAgICBBbHdheXMgcmV0dXJuIGEgbm9uLW51bGwgdmFsaWQge0BsaW5rIFNjaGVtYX0gb2JqZWN0LgotICAgICAqICAgICAgTm90ZSB0aGF0IHdoZW4gYW4gZXJyb3IgaGFzIGJlZW4gcmVwb3J0ZWQsIHRoZXJlIGlzIG5vCi0gICAgICogICAgICBndWFyYW50ZWUgdGhhdCB0aGUgcmV0dXJuZWQge0BsaW5rIFNjaGVtYX0gb2JqZWN0IGlzCi0gICAgICogICAgICBtZWFuaW5nZnVsLgotICAgICAqCi0gICAgICogQHRocm93cyBTQVhFeGNlcHRpb24KLSAgICAgKiAgICAgIElmIGFuIGVycm9yIGlzIGZvdW5kIGR1cmluZyBwcm9jZXNzaW5nIHRoZSBzcGVjaWZpZWQgaW5wdXRzLgotICAgICAqICAgICAgV2hlbiBhbiB7QGxpbmsgRXJyb3JIYW5kbGVyfSBpcyBzZXQsIGVycm9ycyBhcmUgcmVwb3J0ZWQgdG8KLSAgICAgKiAgICAgIHRoZXJlIGZpcnN0LiBTZWUge0BsaW5rICNzZXRFcnJvckhhbmRsZXIoRXJyb3JIYW5kbGVyKX0uCi0gICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgotICAgICAqICAgICAgSWYgdGhlIDxjb2RlPnNjaGVtYXM8L2NvZGU+IHBhcmFtZXRlciBpdHNlbGYgaXMgbnVsbCBvcgotICAgICAqICAgICAgYW55IGl0ZW0gaW4gdGhlIGFycmF5IGlzIG51bGwuCi0gICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KLSAgICAgKiAgICAgIElmIGFueSBpdGVtIGluIHRoZSBhcnJheSBpcyBub3QgcmVjb2duaXplZCBieSB0aGlzIG1ldGhvZC4KLSAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uCi0gICAgICogICAgICBJZiB0aGUgc2NoZW1hIGxhbmd1YWdlIGRvZXNuJ3Qgc3VwcG9ydCB0aGlzIG9wZXJhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3QgU2NoZW1hIG5ld1NjaGVtYShTb3VyY2VbXSBzY2hlbWFzKSB0aHJvd3MgU0FYRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlcyBhIHNwZWNpYWwge0BsaW5rIFNjaGVtYX0gb2JqZWN0LgotICAgICAqCi0gICAgICogPHA+VGhlIGV4YWN0IHNlbWFudGljcyBvZiB0aGUgcmV0dXJuZWQge0BsaW5rIFNjaGVtYX0gb2JqZWN0Ci0gICAgICogZGVwZW5kIG9uIHRoZSBzY2hlbWEgbGFuZ3VhZ2UgZm9yIHdoaWNoIHRoaXMge0BsaW5rIFNjaGVtYUZhY3Rvcnl9Ci0gICAgICogaXMgY3JlYXRlZC4KLSAgICAgKgotICAgICAqIDxwPkFsc28sIGltcGxlbWVudGF0aW9ucyBhcmUgYWxsb3dlZCB0byB1c2UgaW1wbGVtZW50YXRpb24tc3BlY2lmaWMKLSAgICAgKiBwcm9wZXJ0eS9mZWF0dXJlIHRvIGFsdGVyIHRoZSBzZW1hbnRpY3Mgb2YgdGhpcyBtZXRob2QuPC9wPgotICAgICAqCi0gICAgICogPHA+SW1wbGVtZW50b3JzIGFuZCBkZXZlbG9wZXJzIHNob3VsZCBwYXkgcGFydGljdWxhciBhdHRlbnRpb24KLSAgICAgKiB0byBob3cgdGhlIGZlYXR1cmVzIHNldCBvbiB0aGlzIHtAbGluayBTY2hlbWFGYWN0b3J5fSBhcmUKLSAgICAgKiBwcm9jZXNzZWQgYnkgdGhpcyBzcGVjaWFsIHtAbGluayBTY2hlbWF9LgotICAgICAqIEluIHNvbWUgY2FzZXMsIGZvciBleGFtcGxlLCB3aGVuIHRoZQotICAgICAqIHtAbGluayBTY2hlbWFGYWN0b3J5fSBhbmQgdGhlIGNsYXNzIGFjdHVhbGx5IGxvYWRpbmcgdGhlCi0gICAgICogc2NoZW1hIGNvbWUgZnJvbSBkaWZmZXJlbnQgaW1wbGVtZW50YXRpb25zLCBpdCBtYXkgbm90IGJlIHBvc3NpYmxlCi0gICAgICogZm9yIHtAbGluayBTY2hlbWFGYWN0b3J5fSBmZWF0dXJlcyB0byBiZSBpbmhlcml0ZWQgYXV0b21hdGljYWxseS4KLSAgICAgKiBEZXZlbG9wZXJzIHNob3VsZAotICAgICAqIG1ha2Ugc3VyZSB0aGF0IGZlYXR1cmVzLCBzdWNoIGFzIHNlY3VyZSBwcm9jZXNzaW5nLCBhcmUgZXhwbGljaXRseQotICAgICAqIHNldCBpbiBib3RoIHBsYWNlcy48L3A+Ci0gICAgICoKLSAgICAgKiA8aDI+VzNDIFhNTCBTY2hlbWEgMS4wPC9oMj4KLSAgICAgKiA8cD4KLSAgICAgKiBGb3IgWE1MIFNjaGVtYSwgdGhpcyBtZXRob2QgY3JlYXRlcyBhIHtAbGluayBTY2hlbWF9IG9iamVjdCB0aGF0Ci0gICAgICogcGVyZm9ybXMgdmFsaWRhdGlvbiBieSB1c2luZyBsb2NhdGlvbiBoaW50cyBzcGVjaWZpZWQgaW4gZG9jdW1lbnRzLgotICAgICAqCi0gICAgICogPHA+Ci0gICAgICogVGhlIHJldHVybmVkIHtAbGluayBTY2hlbWF9IG9iamVjdCBhc3N1bWVzIHRoYXQgaWYgZG9jdW1lbnRzCi0gICAgICogcmVmZXIgdG8gdGhlIHNhbWUgVVJMIGluIHRoZSBzY2hlbWEgbG9jYXRpb24gaGludHMsCi0gICAgICogdGhleSB3aWxsIGFsd2F5cyByZXNvbHZlIHRvIHRoZSBzYW1lIHNjaGVtYSBkb2N1bWVudC4gVGhpcwotICAgICAqIGFzdXNtcHRpb24gYWxsb3dzIGltcGxlbWVudGF0aW9ucyB0byByZXVzZSBwYXJzZWQgcmVzdWx0cyBvZgotICAgICAqIHNjaGVtYSBkb2N1bWVudHMgc28gdGhhdCBtdWx0aXBsZSB2YWxpZGF0aW9ucyBhZ2FpbnN0IHRoZSBzYW1lCi0gICAgICogc2NoZW1hIHdpbGwgcnVuIGZhc3Rlci4KLSAgICAgKgotICAgICAqIDxwPgotICAgICAqIE5vdGUgdGhhdCB0aGUgdXNlIG9mIHNjaGVtYSBsb2NhdGlvbiBoaW50cyBpbnRyb2R1Y2VzIGEKLSAgICAgKiB2dWxuZXJhYmlsaXR5IHRvIGRlbmlhbC1vZi1zZXJ2aWNlIGF0dGFja3MuCi0gICAgICoKLSAgICAgKgotICAgICAqIDxoMj5SRUxBWCBORzwvaDI+Ci0gICAgICogPHA+Ci0gICAgICogUkVMQVggTkcgZG9lcyBub3Qgc3VwcG9ydCB0aGlzIG9wZXJhdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4KLSAgICAgKiAgICAgIEFsd2F5cyByZXR1cm4gbm9uLW51bGwgdmFsaWQge0BsaW5rIFNjaGVtYX0gb2JqZWN0LgotICAgICAqCi0gICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbgotICAgICAqICAgICAgSWYgdGhpcyBvcGVyYXRpb24gaXMgbm90IHN1cHBvcnRlZCBieSB0aGUgY2FsbGVlLgotICAgICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgICogICAgICBJZiB0aGlzIG9wZXJhdGlvbiBpcyBzdXBwb3J0ZWQgYnV0IGZhaWxlZCBmb3Igc29tZSByZWFzb24uCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IFNjaGVtYSBuZXdTY2hlbWEoKSB0aHJvd3MgU0FYRXhjZXB0aW9uOwotfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmF4L3htbC92YWxpZGF0aW9uL1NjaGVtYUZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IuamF2YSBiL3NyYy9qYXZheC94bWwvdmFsaWRhdGlvbi9TY2hlbWFGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDQ3YzRkZGEuLjAwMDAwMDAKLS0tIGEvc3JjL2phdmF4L3htbC92YWxpZGF0aW9uL1NjaGVtYUZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDgwICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMTMsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLXBhY2thZ2UgamF2YXgueG1sLnZhbGlkYXRpb247Ci0KLS8qKgotICogVGhyb3duIHdoZW4gYSBwcm9ibGVtIHdpdGggY29uZmlndXJhdGlvbiB3aXRoIHRoZSBTY2hlbWEgRmFjdG9yaWVzCi0gKiBleGlzdHMuIFRoaXMgZXJyb3Igd2lsbCB0eXBpY2FsbHkgYmUgdGhyb3duIHdoZW4gdGhlIGNsYXNzIG9mIGEKLSAqIHNjaGVtYSBmYWN0b3J5IHNwZWNpZmllZCBpbiB0aGUgc3lzdGVtIHByb3BlcnRpZXMgY2Fubm90IGJlIGZvdW5kCi0gKiBvciBpbnN0YW50aWF0ZWQuCi0gKiBAc2luY2UgMS44Ci0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBTY2hlbWFGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yIGV4dGVuZHMgRXJyb3IgewotCi0gICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDM1MzE0Mzg3MDMxNDc3NTAxMjZMOwotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlIGEgbmV3IDxjb2RlPlNjaGVtYUZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3I8L2NvZGU+IHdpdGggbm8KLSAgICAgKiBkZXRhaWwgbWVzc2FnZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgU2NoZW1hRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvcigpIHsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIENyZWF0ZSBhIG5ldyA8Y29kZT5TY2hlbWFGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yPC9jb2RlPiB3aXRoCi0gICAgICogdGhlIDxjb2RlPlN0cmluZzwvY29kZT4gc3BlY2lmaWVkIGFzIGFuIGVycm9yIG1lc3NhZ2UuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbWVzc2FnZSBUaGUgZXJyb3IgbWVzc2FnZSBmb3IgdGhlIGV4Y2VwdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU2NoZW1hRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvcihTdHJpbmcgbWVzc2FnZSkgewotICAgICAgICBzdXBlcihtZXNzYWdlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGUgYSBuZXcgPGNvZGU+U2NoZW1hRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvcjwvY29kZT4gd2l0aCB0aGUKLSAgICAgKiBnaXZlbiA8Y29kZT5UaHJvd2FibGU8L2NvZGU+IGJhc2UgY2F1c2UuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY2F1c2UgVGhlIGV4Y2VwdGlvbiBvciBlcnJvciB0byBiZSBlbmNhcHN1bGF0ZWQgaW4gYQotICAgICAqIFNjaGVtYUZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIFNjaGVtYUZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IoVGhyb3dhYmxlIGNhdXNlKSB7Ci0gICAgICAgIHN1cGVyKGNhdXNlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGUgYSBuZXcgPGNvZGU+U2NoZW1hRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvcjwvY29kZT4gd2l0aCB0aGUKLSAgICAgKiBnaXZlbiA8Y29kZT5UaHJvd2FibGU8L2NvZGU+IGJhc2UgY2F1c2UgYW5kIGRldGFpbCBtZXNzYWdlLgotICAgICAqCi0gICAgICogQHBhcmFtIGNhdXNlIFRoZSBleGNlcHRpb24gb3IgZXJyb3IgdG8gYmUgZW5jYXBzdWxhdGVkIGluIGEKLSAgICAgKiBTY2hlbWFGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yLgotICAgICAqIEBwYXJhbSBtZXNzYWdlIFRoZSBkZXRhaWwgbWVzc2FnZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgU2NoZW1hRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvcihTdHJpbmcgbWVzc2FnZSwgVGhyb3dhYmxlIGNhdXNlKSB7Ci0gICAgICAgIHN1cGVyKG1lc3NhZ2UsIGNhdXNlKTsKLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9qYXZheC94bWwvdmFsaWRhdGlvbi9TY2hlbWFGYWN0b3J5RmluZGVyLmphdmEgYi9zcmMvamF2YXgveG1sL3ZhbGlkYXRpb24vU2NoZW1hRmFjdG9yeUZpbmRlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA5MDdlNjdhLi4wMDAwMDAwCi0tLSBhL3NyYy9qYXZheC94bWwvdmFsaWRhdGlvbi9TY2hlbWFGYWN0b3J5RmluZGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0NDggKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwMywgMjAxMywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotcGFja2FnZSBqYXZheC54bWwudmFsaWRhdGlvbjsKLQotaW1wb3J0IGphdmEuaW8uRmlsZTsKLWltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2Q7Ci1pbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuTW9kaWZpZXI7Ci1pbXBvcnQgamF2YS5uZXQuVVJMOwotaW1wb3J0IGphdmEuc2VjdXJpdHkuQWNjZXNzQ29udHJvbENvbnRleHQ7Ci1pbXBvcnQgamF2YS5zZWN1cml0eS5BY2Nlc3NDb250cm9sbGVyOwotaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpdmlsZWdlZEFjdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKLWltcG9ydCBqYXZhLnV0aWwuU2VydmljZUNvbmZpZ3VyYXRpb25FcnJvcjsKLWltcG9ydCBqYXZhLnV0aWwuU2VydmljZUxvYWRlcjsKLQotLyoqCi0gKiBJbXBsZW1lbnRhdGlvbiBvZiB7QGxpbmsgU2NoZW1hRmFjdG9yeSNuZXdJbnN0YW5jZShTdHJpbmcpfS4KLSAqCi0gKiBAYXV0aG9yIDxhIGhyZWY9IktvaHN1a2UuS2F3YWd1Y2hpQFN1bi5jb20iPktvaHN1a2UgS2F3YWd1Y2hpPC9hPgotICogQHZlcnNpb24gJFJldmlzaW9uOiAxLjggJCwgJERhdGU6IDIwMTAtMTEtMDEgMDQ6MzY6MTMgJAotICogQHNpbmNlIDEuNQotICovCi1jbGFzcyBTY2hlbWFGYWN0b3J5RmluZGVyICB7Ci0KLSAgICAvKiogZGVidWcgc3VwcG9ydCBjb2RlLiAqLwotICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gZGVidWcgPSBmYWxzZTsKLSAgICAvKioKLSAgICAgKjxwPiBUYWtlIGNhcmUgb2YgcmVzdHJpY3Rpb25zIGltcG9zZWQgYnkgamF2YSBzZWN1cml0eSBtb2RlbCA8L3A+Ci0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU2VjdXJpdHlTdXBwb3J0IHNzID0gbmV3IFNlY3VyaXR5U3VwcG9ydCgpOwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBERUZBVUxUX1BBQ0tBR0UgPSAiY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbCI7Ci0gICAgLyoqCi0gICAgICogPHA+Q2FjaGUgcHJvcGVydGllcyBmb3IgcGVyZm9ybWFuY2UuPC9wPgotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFByb3BlcnRpZXMgY2FjaGVQcm9wcyA9IG5ldyBQcm9wZXJ0aWVzKCk7Ci0KLSAgICAvKioKLSAgICAgKiA8cD5GaXJzdCB0aW1lIHJlcXVpcmVzIGluaXRpYWxpemF0aW9uIG92ZXJoZWFkLjwvcD4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyB2b2xhdGlsZSBib29sZWFuIGZpcnN0VGltZSA9IHRydWU7Ci0KLSAgICBzdGF0aWMgewotICAgICAgICAvLyBVc2UgdHJ5L2NhdGNoIGJsb2NrIHRvIHN1cHBvcnQgYXBwbGV0cwotICAgICAgICB0cnkgewotICAgICAgICAgICAgZGVidWcgPSBzcy5nZXRTeXN0ZW1Qcm9wZXJ0eSgiamF4cC5kZWJ1ZyIpICE9IG51bGw7Ci0gICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiB1bnVzZWQpIHsKLSAgICAgICAgICAgIGRlYnVnID0gZmFsc2U7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5Db25kaXRpb25hbCBkZWJ1ZyBwcmludGluZy48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gbXNnIHRvIHByaW50Ci0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBkZWJ1Z1ByaW50bG4oU3RyaW5nIG1zZykgewotICAgICAgICBpZiAoZGVidWcpIHsKLSAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiSkFYUDogIiArIG1zZyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD48Y29kZT5DbGFzc0xvYWRlcjwvY29kZT4gdG8gdXNlIHRvIGZpbmQgPGNvZGU+U2NoZW1hRmFjdG9yeTwvY29kZT4uPC9wPgotICAgICAqLwotICAgIHByaXZhdGUgZmluYWwgQ2xhc3NMb2FkZXIgY2xhc3NMb2FkZXI7Ci0KLSAgICAvKioKLSAgICAgKiA8cD5Db25zdHJ1Y3RvciB0aGF0IHNwZWNpZmllcyA8Y29kZT5DbGFzc0xvYWRlcjwvY29kZT4gdG8gdXNlCi0gICAgICogdG8gZmluZCA8Y29kZT5TY2hlbWFGYWN0b3J5PC9jb2RlPi48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gbG9hZGVyCi0gICAgICogICAgICB0byBiZSB1c2VkIHRvIGxvYWQgcmVzb3VyY2UsIHtAbGluayBTY2hlbWFGYWN0b3J5fSwgYW5kCi0gICAgICogICAgICB7QGxpbmsgU2NoZW1hRmFjdG9yeUxvYWRlcn0gaW1wbGVtZW50YXRpb25zIGR1cmluZwotICAgICAqICAgICAgdGhlIHJlc29sdXRpb24gcHJvY2Vzcy4KLSAgICAgKiAgICAgIElmIHRoaXMgcGFyYW1ldGVyIGlzIG51bGwsIHRoZSBkZWZhdWx0IHN5c3RlbSBjbGFzcyBsb2FkZXIKLSAgICAgKiAgICAgIHdpbGwgYmUgdXNlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU2NoZW1hRmFjdG9yeUZpbmRlcihDbGFzc0xvYWRlciBsb2FkZXIpIHsKLSAgICAgICAgdGhpcy5jbGFzc0xvYWRlciA9IGxvYWRlcjsKLSAgICAgICAgaWYoIGRlYnVnICkgewotICAgICAgICAgICAgZGVidWdEaXNwbGF5Q2xhc3NMb2FkZXIoKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBkZWJ1Z0Rpc3BsYXlDbGFzc0xvYWRlcigpIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGlmKCBjbGFzc0xvYWRlciA9PSBzcy5nZXRDb250ZXh0Q2xhc3NMb2FkZXIoKSApIHsKLSAgICAgICAgICAgICAgICBkZWJ1Z1ByaW50bG4oInVzaW5nIHRocmVhZCBjb250ZXh0IGNsYXNzIGxvYWRlciAoIitjbGFzc0xvYWRlcisiKSBmb3Igc2VhcmNoIik7Ci0gICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgfQotICAgICAgICB9IGNhdGNoKCBUaHJvd2FibGUgdW51c2VkICkgewotICAgICAgICAgICAgLy8gZ2V0Q29udGV4dENsYXNzTG9hZGVyKCkgdW5kZWZpbmVkIGluIEpESzEuMQotICAgICAgICB9Ci0KLSAgICAgICAgaWYoIGNsYXNzTG9hZGVyPT1DbGFzc0xvYWRlci5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpICkgewotICAgICAgICAgICAgZGVidWdQcmludGxuKCJ1c2luZyBzeXN0ZW0gY2xhc3MgbG9hZGVyICgiK2NsYXNzTG9hZGVyKyIpIGZvciBzZWFyY2giKTsKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotCi0gICAgICAgIGRlYnVnUHJpbnRsbigidXNpbmcgY2xhc3MgbG9hZGVyICgiK2NsYXNzTG9hZGVyKyIpIGZvciBzZWFyY2giKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5DcmVhdGVzIGEgbmV3IHtAbGluayBTY2hlbWFGYWN0b3J5fSBvYmplY3QgZm9yIHRoZSBzcGVjaWZpZWQKLSAgICAgKiBzY2hlbWEgbGFuZ3VhZ2UuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIHNjaGVtYUxhbmd1YWdlCi0gICAgICogICAgICBTZWUge0BsaW5rIFNjaGVtYUZhY3RvcnkgU2NoZW1hIExhbmd1YWdlfSB0YWJsZSBpbiA8Y29kZT5TY2hlbWFGYWN0b3J5PC9jb2RlPgotICAgICAqICAgICAgZm9yIHRoZSBsaXN0IG9mIGF2YWlsYWJsZSBzY2hlbWEgbGFuZ3VhZ2VzLgotICAgICAqCi0gICAgICogQHJldHVybiA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGUgY2FsbGVlIGZhaWxzIHRvIGNyZWF0ZSBvbmUuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCi0gICAgICogICAgICBJZiB0aGUgPGNvZGU+c2NoZW1hTGFuZ3VhZ2U8L2NvZGU+IHBhcmFtZXRlciBpcyBudWxsLgotICAgICAqIEB0aHJvd3MgU2NoZW1hRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvcgotICAgICAqICAgICAgSWYgYSBjb25maWd1cmF0aW9uIGVycm9yIGlzIGVuY291bnRlcmVkLgotICAgICAqLwotICAgIHB1YmxpYyBTY2hlbWFGYWN0b3J5IG5ld0ZhY3RvcnkoU3RyaW5nIHNjaGVtYUxhbmd1YWdlKSB7Ci0gICAgICAgIGlmKHNjaGVtYUxhbmd1YWdlPT1udWxsKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKLSAgICAgICAgfQotICAgICAgICBTY2hlbWFGYWN0b3J5IGYgPSBfbmV3RmFjdG9yeShzY2hlbWFMYW5ndWFnZSk7Ci0gICAgICAgIGlmIChmICE9IG51bGwpIHsKLSAgICAgICAgICAgIGRlYnVnUHJpbnRsbigiZmFjdG9yeSAnIiArIGYuZ2V0Q2xhc3MoKS5nZXROYW1lKCkgKyAiJyB3YXMgZm91bmQgZm9yICIgKyBzY2hlbWFMYW5ndWFnZSk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBkZWJ1Z1ByaW50bG4oInVuYWJsZSB0byBmaW5kIGEgZmFjdG9yeSBmb3IgIiArIHNjaGVtYUxhbmd1YWdlKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5Mb29rdXAgYSA8Y29kZT5TY2hlbWFGYWN0b3J5PC9jb2RlPiBmb3IgdGhlIGdpdmVuIDxjb2RlPnNjaGVtYUxhbmd1YWdlPC9jb2RlPi48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gc2NoZW1hTGFuZ3VhZ2UgU2NoZW1hIGxhbmd1YWdlIHRvIGxvb2t1cCA8Y29kZT5TY2hlbWFGYWN0b3J5PC9jb2RlPiBmb3IuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIDxjb2RlPlNjaGVtYUZhY3Rvcnk8L2NvZGU+IGZvciB0aGUgZ2l2ZW4gPGNvZGU+c2NoZW1hTGFuZ3VhZ2U8L2NvZGU+LgotICAgICAqLwotICAgIHByaXZhdGUgU2NoZW1hRmFjdG9yeSBfbmV3RmFjdG9yeShTdHJpbmcgc2NoZW1hTGFuZ3VhZ2UpIHsKLSAgICAgICAgU2NoZW1hRmFjdG9yeSBzZjsKLQotICAgICAgICBTdHJpbmcgcHJvcGVydHlOYW1lID0gU0VSVklDRV9DTEFTUy5nZXROYW1lKCkgKyAiOiIgKyBzY2hlbWFMYW5ndWFnZTsKLQotICAgICAgICAvLyBzeXN0ZW0gcHJvcGVydHkgbG9vayB1cAotICAgICAgICB0cnkgewotICAgICAgICAgICAgZGVidWdQcmludGxuKCJMb29raW5nIHVwIHN5c3RlbSBwcm9wZXJ0eSAnIitwcm9wZXJ0eU5hbWUrIiciICk7Ci0gICAgICAgICAgICBTdHJpbmcgciA9IHNzLmdldFN5c3RlbVByb3BlcnR5KHByb3BlcnR5TmFtZSk7Ci0gICAgICAgICAgICBpZihyIT1udWxsKSB7Ci0gICAgICAgICAgICAgICAgZGVidWdQcmludGxuKCJUaGUgdmFsdWUgaXMgJyIrcisiJyIpOwotICAgICAgICAgICAgICAgIHNmID0gY3JlYXRlSW5zdGFuY2UociwgdHJ1ZSk7Ci0gICAgICAgICAgICAgICAgaWYoc2YhPW51bGwpICAgIHJldHVybiBzZjsKLSAgICAgICAgICAgIH0gZWxzZQotICAgICAgICAgICAgICAgIGRlYnVnUHJpbnRsbigiVGhlIHByb3BlcnR5IGlzIHVuZGVmaW5lZC4iKTsKLSAgICAgICAgfSBjYXRjaCggVGhyb3dhYmxlIHQgKSB7Ci0gICAgICAgICAgICBpZiggZGVidWcgKSB7Ci0gICAgICAgICAgICAgICAgZGVidWdQcmludGxuKCJmYWlsZWQgdG8gbG9vayB1cCBzeXN0ZW0gcHJvcGVydHkgJyIrcHJvcGVydHlOYW1lKyInIiApOwotICAgICAgICAgICAgICAgIHQucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBTdHJpbmcgamF2YWggPSBzcy5nZXRTeXN0ZW1Qcm9wZXJ0eSggImphdmEuaG9tZSIgKTsKLSAgICAgICAgU3RyaW5nIGNvbmZpZ0ZpbGUgPSBqYXZhaCArIEZpbGUuc2VwYXJhdG9yICsKLSAgICAgICAgImxpYiIgKyBGaWxlLnNlcGFyYXRvciArICJqYXhwLnByb3BlcnRpZXMiOwotCi0KLSAgICAgICAgLy8gdHJ5IHRvIHJlYWQgZnJvbSAkamF2YS5ob21lL2xpYi9qYXhwLnByb3BlcnRpZXMKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGlmKGZpcnN0VGltZSl7Ci0gICAgICAgICAgICAgICAgc3luY2hyb25pemVkKGNhY2hlUHJvcHMpewotICAgICAgICAgICAgICAgICAgICBpZihmaXJzdFRpbWUpewotICAgICAgICAgICAgICAgICAgICAgICAgRmlsZSBmPW5ldyBGaWxlKCBjb25maWdGaWxlICk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBmaXJzdFRpbWUgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmKHNzLmRvZXNGaWxlRXhpc3QoZikpewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlYnVnUHJpbnRsbigiUmVhZCBwcm9wZXJ0aWVzIGZpbGUgIiArIGYpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhY2hlUHJvcHMubG9hZChzcy5nZXRGaWxlSW5wdXRTdHJlYW0oZikpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZmluYWwgU3RyaW5nIGZhY3RvcnlDbGFzc05hbWUgPSBjYWNoZVByb3BzLmdldFByb3BlcnR5KHByb3BlcnR5TmFtZSk7Ci0gICAgICAgICAgICBkZWJ1Z1ByaW50bG4oImZvdW5kICIgKyBmYWN0b3J5Q2xhc3NOYW1lICsgIiBpbiAkamF2YS5ob21lL2pheHAucHJvcGVydGllcyIpOwotCi0gICAgICAgICAgICBpZiAoZmFjdG9yeUNsYXNzTmFtZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgc2YgPSBjcmVhdGVJbnN0YW5jZShmYWN0b3J5Q2xhc3NOYW1lLCB0cnVlKTsKLSAgICAgICAgICAgICAgICBpZihzZiAhPSBudWxsKXsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNmOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7Ci0gICAgICAgICAgICBpZiAoZGVidWcpIHsKLSAgICAgICAgICAgICAgICBleC5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIFRyeSB3aXRoIFNlcnZpY2VMb2FkZXIKLSAgICAgICAgZmluYWwgU2NoZW1hRmFjdG9yeSBmYWN0b3J5SW1wbCA9IGZpbmRTZXJ2aWNlUHJvdmlkZXIoc2NoZW1hTGFuZ3VhZ2UpOwotCi0gICAgICAgIC8vIFRoZSBmb2xsb3dpbmcgYXNzZXJ0aW9uIHNob3VsZCBhbHdheXMgYmUgdHJ1ZS4KLSAgICAgICAgLy8gVW5jb21tZW50IGl0LCByZWNvbXBpbGUsIGFuZCBydW4gd2l0aCAtZWEgaW4gY2FzZSBvZiBkb3VidHM6Ci0gICAgICAgIC8vIGFzc2VydCBmYWN0b3J5SW1wbCA9PSBudWxsIHx8IGZhY3RvcnlJbXBsLmlzU2NoZW1hTGFuZ3VhZ2VTdXBwb3J0ZWQoc2NoZW1hTGFuZ3VhZ2UpOwotCi0gICAgICAgIGlmIChmYWN0b3J5SW1wbCAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gZmFjdG9yeUltcGw7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBwbGF0Zm9ybSBkZWZhdWx0Ci0gICAgICAgIGlmKHNjaGVtYUxhbmd1YWdlLmVxdWFscygiaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiKSkgewotICAgICAgICAgICAgZGVidWdQcmludGxuKCJhdHRlbXB0aW5nIHRvIHVzZSB0aGUgcGxhdGZvcm0gZGVmYXVsdCBYTUwgU2NoZW1hIHZhbGlkYXRvciIpOwotICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUluc3RhbmNlKCJjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmpheHAudmFsaWRhdGlvbi5YTUxTY2hlbWFGYWN0b3J5IiwgdHJ1ZSk7Ci0gICAgICAgIH0KLQotICAgICAgICBkZWJ1Z1ByaW50bG4oImFsbCB0aGluZ3Mgd2VyZSB0cmllZCwgYnV0IG5vbmUgd2FzIGZvdW5kLiBiYWlsaW5nIG91dC4iKTsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLyoqIDxwPkNyZWF0ZSBjbGFzcyB1c2luZyBhcHByb3ByaWF0ZSBDbGFzc0xvYWRlci48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gY2xhc3NOYW1lIE5hbWUgb2YgY2xhc3MgdG8gY3JlYXRlLgotICAgICAqIEByZXR1cm4gQ3JlYXRlZCBjbGFzcyBvciA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwcml2YXRlIENsYXNzPD8+IGNyZWF0ZUNsYXNzKFN0cmluZyBjbGFzc05hbWUpIHsKLSAgICAgICAgQ2xhc3M8Pz4gY2xheno7Ci0gICAgICAgIC8vIG1ha2Ugc3VyZSB3ZSBoYXZlIGFjY2VzcyB0byByZXN0cmljdGVkIHBhY2thZ2VzCi0gICAgICAgIGJvb2xlYW4gaW50ZXJuYWwgPSBmYWxzZTsKLSAgICAgICAgaWYgKFN5c3RlbS5nZXRTZWN1cml0eU1hbmFnZXIoKSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpZiAoY2xhc3NOYW1lICE9IG51bGwgJiYgY2xhc3NOYW1lLnN0YXJ0c1dpdGgoREVGQVVMVF9QQUNLQUdFKSkgewotICAgICAgICAgICAgICAgIGludGVybmFsID0gdHJ1ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBpZiAoY2xhc3NMb2FkZXIgIT0gbnVsbCAmJiAhaW50ZXJuYWwpIHsKLSAgICAgICAgICAgICAgICBjbGF6eiA9IENsYXNzLmZvck5hbWUoY2xhc3NOYW1lLCBmYWxzZSwgY2xhc3NMb2FkZXIpOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBjbGF6eiA9IENsYXNzLmZvck5hbWUoY2xhc3NOYW1lKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSBjYXRjaCAoVGhyb3dhYmxlIHQpIHsKLSAgICAgICAgICAgIGlmKGRlYnVnKSAgewotICAgICAgICAgICAgICAgIHQucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBjbGF6ejsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5DcmVhdGVzIGFuIGluc3RhbmNlIG9mIHRoZSBzcGVjaWZpZWQgYW5kIHJldHVybnMgaXQuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGNsYXNzTmFtZQotICAgICAqICAgICAgZnVsbHkgcXVhbGlmaWVkIGNsYXNzIG5hbWUgdG8gYmUgaW5zdGFudGlhdGVkLgotICAgICAqCi0gICAgICogQHJldHVybiBudWxsCi0gICAgICogICAgICBpZiBpdCBmYWlscy4gRXJyb3IgbWVzc2FnZXMgd2lsbCBiZSBwcmludGVkIGJ5IHRoaXMgbWV0aG9kLgotICAgICAqLwotICAgIFNjaGVtYUZhY3RvcnkgY3JlYXRlSW5zdGFuY2UoIFN0cmluZyBjbGFzc05hbWUgKSB7Ci0gICAgICAgIHJldHVybiBjcmVhdGVJbnN0YW5jZSggY2xhc3NOYW1lLCBmYWxzZSApOwotICAgIH0KLQotICAgIFNjaGVtYUZhY3RvcnkgY3JlYXRlSW5zdGFuY2UoIFN0cmluZyBjbGFzc05hbWUsIGJvb2xlYW4gdXNlU2VydmljZXNNZWNoYW5pc20gKSB7Ci0gICAgICAgIFNjaGVtYUZhY3Rvcnkgc2NoZW1hRmFjdG9yeSA9IG51bGw7Ci0KLSAgICAgICAgZGVidWdQcmludGxuKCJjcmVhdGVJbnN0YW5jZSgiICsgY2xhc3NOYW1lICsgIikiKTsKLQotICAgICAgICAvLyBnZXQgQ2xhc3MgZnJvbSBjbGFzc05hbWUKLSAgICAgICAgQ2xhc3M8Pz4gY2xhenogPSBjcmVhdGVDbGFzcyhjbGFzc05hbWUpOwotICAgICAgICBpZiAoY2xhenogPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGRlYnVnUHJpbnRsbigiZmFpbGVkIHRvIGdldENsYXNzKCIgKyBjbGFzc05hbWUgKyAiKSIpOwotICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgICAgIGRlYnVnUHJpbnRsbigibG9hZGVkICIgKyBjbGFzc05hbWUgKyAiIGZyb20gIiArIHdoaWNoKGNsYXp6KSk7Ci0KLSAgICAgICAgLy8gaW5zdGFudGlhdGUgQ2xhc3MgYXMgYSBTY2hlbWFGYWN0b3J5Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgaWYgKCFTY2hlbWFGYWN0b3J5LmNsYXNzLmlzQXNzaWduYWJsZUZyb20oY2xhenopKSB7Ci0gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBDbGFzc0Nhc3RFeGNlcHRpb24oY2xhenouZ2V0TmFtZSgpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiBjYW5ub3QgYmUgY2FzdCB0byAiICsgU2NoZW1hRmFjdG9yeS5jbGFzcyk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGlmICghdXNlU2VydmljZXNNZWNoYW5pc20pIHsKLSAgICAgICAgICAgICAgICAgICAgc2NoZW1hRmFjdG9yeSA9IG5ld0luc3RhbmNlTm9TZXJ2aWNlTG9hZGVyKGNsYXp6KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaWYgKHNjaGVtYUZhY3RvcnkgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBzY2hlbWFGYWN0b3J5ID0gKFNjaGVtYUZhY3RvcnkpIGNsYXp6Lm5ld0luc3RhbmNlKCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICB9IGNhdGNoIChDbGFzc0Nhc3RFeGNlcHRpb24gY2xhc3NDYXN0RXhjZXB0aW9uKSB7Ci0gICAgICAgICAgICAgICAgZGVidWdQcmludGxuKCJjb3VsZCBub3QgaW5zdGFudGlhdGUgIiArIGNsYXp6LmdldE5hbWUoKSk7Ci0gICAgICAgICAgICAgICAgaWYgKGRlYnVnKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBjbGFzc0Nhc3RFeGNlcHRpb24ucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIGlsbGVnYWxBY2Nlc3NFeGNlcHRpb24pIHsKLSAgICAgICAgICAgICAgICBkZWJ1Z1ByaW50bG4oImNvdWxkIG5vdCBpbnN0YW50aWF0ZSAiICsgY2xhenouZ2V0TmFtZSgpKTsKLSAgICAgICAgICAgICAgICBpZiAoZGVidWcpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlsbGVnYWxBY2Nlc3NFeGNlcHRpb24ucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9IGNhdGNoIChJbnN0YW50aWF0aW9uRXhjZXB0aW9uIGluc3RhbnRpYXRpb25FeGNlcHRpb24pIHsKLSAgICAgICAgICAgICAgICBkZWJ1Z1ByaW50bG4oImNvdWxkIG5vdCBpbnN0YW50aWF0ZSAiICsgY2xhenouZ2V0TmFtZSgpKTsKLSAgICAgICAgICAgICAgICBpZiAoZGVidWcpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbnRpYXRpb25FeGNlcHRpb24ucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIHNjaGVtYUZhY3Rvcnk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJ5IHRvIGNvbnN0cnVjdCB1c2luZyBuZXdYTUxTY2hlbWFGYWN0b3J5Tm9TZXJ2aWNlTG9hZGVyCi0gICAgICogICBtZXRob2QgaWYgYXZhaWxhYmxlLgotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIFNjaGVtYUZhY3RvcnkgbmV3SW5zdGFuY2VOb1NlcnZpY2VMb2FkZXIoCi0gICAgICAgICBDbGFzczw/PiBwcm92aWRlckNsYXNzCi0gICAgKSB7Ci0gICAgICAgIC8vIFJldGFpbiBtYXhpbXVtIGNvbXBhdGliaWxpdHkgaWYgbm8gc2VjdXJpdHkgbWFuYWdlci4KLSAgICAgICAgaWYgKFN5c3RlbS5nZXRTZWN1cml0eU1hbmFnZXIoKSA9PSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotICAgICAgICB0cnkgewotICAgICAgICAgICAgZmluYWwgTWV0aG9kIGNyZWF0aW9uTWV0aG9kID0KLSAgICAgICAgICAgICAgICBwcm92aWRlckNsYXNzLmdldERlY2xhcmVkTWV0aG9kKAotICAgICAgICAgICAgICAgICAgICAibmV3WE1MU2NoZW1hRmFjdG9yeU5vU2VydmljZUxvYWRlciIKLSAgICAgICAgICAgICAgICApOwotICAgICAgICAgICAgZmluYWwgaW50IG1vZGlmaWVycyA9IGNyZWF0aW9uTWV0aG9kLmdldE1vZGlmaWVycygpOwotCi0gICAgICAgICAgICAvLyBEbyBub3QgY2FsbCB0aGUgbWV0aG9kIGlmIGl0J3Mgbm90IHB1YmxpYyBzdGF0aWMuCi0gICAgICAgICAgICBpZiAoIU1vZGlmaWVyLmlzU3RhdGljKG1vZGlmaWVycykgfHwgIU1vZGlmaWVyLmlzUHVibGljKG1vZGlmaWVycykpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gT25seSBjYWxscyAibmV3WE1MU2NoZW1hRmFjdG9yeU5vU2VydmljZUxvYWRlciIgaWYgaXQncwotICAgICAgICAgICAgLy8gZGVjbGFyZWQgdG8gcmV0dXJuIGFuIGluc3RhbmNlIG9mIFNjaGVtYUZhY3RvcnkuCi0gICAgICAgICAgICBmaW5hbCBDbGFzczw/PiByZXR1cm5UeXBlID0gY3JlYXRpb25NZXRob2QuZ2V0UmV0dXJuVHlwZSgpOwotICAgICAgICAgICAgaWYgKFNFUlZJQ0VfQ0xBU1MuaXNBc3NpZ25hYmxlRnJvbShyZXR1cm5UeXBlKSkgewotICAgICAgICAgICAgICAgIHJldHVybiBTRVJWSUNFX0NMQVNTLmNhc3QoY3JlYXRpb25NZXRob2QuaW52b2tlKG51bGwsIChPYmplY3RbXSludWxsKSk7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIC8vIFNob3VsZCBub3QgaGFwcGVuIHNpbmNlCi0gICAgICAgICAgICAgICAgLy8gWE1MU2NoZW1hRmFjdG9yeS5uZXdYTUxTY2hlbWFGYWN0b3J5Tm9TZXJ2aWNlTG9hZGVyIGlzCi0gICAgICAgICAgICAgICAgLy8gZGVjbGFyZWQgdG8gcmV0dXJuIFhNTFNjaGVtYUZhY3RvcnkuCi0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IENsYXNzQ2FzdEV4Y2VwdGlvbihyZXR1cm5UeXBlCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiIGNhbm5vdCBiZSBjYXN0IHRvICIgKyBTRVJWSUNFX0NMQVNTKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSBjYXRjaChDbGFzc0Nhc3RFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFNjaGVtYUZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IoZS5nZXRNZXNzYWdlKCksIGUpOwotICAgICAgICB9IGNhdGNoIChOb1N1Y2hNZXRob2RFeGNlcHRpb24gZXhjKSB7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4YykgewotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvLyBDYWxsIGlzU2NoZW1hTGFuZ3VhZ2VTdXBwb3J0ZWQgd2l0aCBpbml0aWFsIGNvbnRleHQuCi0gICAgcHJpdmF0ZSBib29sZWFuIGlzU2NoZW1hTGFuZ3VhZ2VTdXBwb3J0ZWRCeShmaW5hbCBTY2hlbWFGYWN0b3J5IGZhY3RvcnksCi0gICAgICAgICAgICBmaW5hbCBTdHJpbmcgc2NoZW1hTGFuZ3VhZ2UsCi0gICAgICAgICAgICBBY2Nlc3NDb250cm9sQ29udGV4dCBhY2MpIHsKLSAgICAgICAgcmV0dXJuIEFjY2Vzc0NvbnRyb2xsZXIuZG9Qcml2aWxlZ2VkKG5ldyBQcml2aWxlZ2VkQWN0aW9uPEJvb2xlYW4+KCkgewotICAgICAgICAgICAgcHVibGljIEJvb2xlYW4gcnVuKCkgewotICAgICAgICAgICAgICAgIHJldHVybiBmYWN0b3J5LmlzU2NoZW1hTGFuZ3VhZ2VTdXBwb3J0ZWQoc2NoZW1hTGFuZ3VhZ2UpOwotICAgICAgICAgICAgfQotICAgICAgICB9LCBhY2MpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEZpbmRzIGEgc2VydmljZSBwcm92aWRlciBzdWJjbGFzcyBvZiBTY2hlbWFGYWN0b3J5IHRoYXQgc3VwcG9ydHMgdGhlCi0gICAgICogZ2l2ZW4gc2NoZW1hIGxhbmd1YWdlIHVzaW5nIHRoZSBTZXJ2aWNlTG9hZGVyLgotICAgICAqCi0gICAgICogQHBhcmFtIHNjaGVtYUxhbmd1YWdlIFRoZSBzY2hlbWEgbGFuZ3VhZ2UgZm9yIHdoaWNoIHdlIHNlZWsgYSBmYWN0b3J5LgotICAgICAqIEByZXR1cm4gQSBTY2hlbWFGYWN0b3J5IHN1cHBvcnRpbmcgdGhlIHNwZWNpZmllZCBzY2hlbWEgbGFuZ3VhZ2UsIG9yIG51bGwKLSAgICAgKiAgICAgICAgIGlmIG5vbmUgaXMgZm91bmQuCi0gICAgICogQHRocm93cyBTY2hlbWFGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yIGlmIGEgY29uZmlndXJhdGlvbiBlcnJvciBpcyBmb3VuZC4KLSAgICAgKi8KLSAgICBwcml2YXRlIFNjaGVtYUZhY3RvcnkgZmluZFNlcnZpY2VQcm92aWRlcihmaW5hbCBTdHJpbmcgc2NoZW1hTGFuZ3VhZ2UpIHsKLSAgICAgICAgYXNzZXJ0IHNjaGVtYUxhbmd1YWdlICE9IG51bGw7Ci0gICAgICAgIC8vIHN0b3JlIGN1cnJlbnQgY29udGV4dC4KLSAgICAgICAgZmluYWwgQWNjZXNzQ29udHJvbENvbnRleHQgYWNjID0gQWNjZXNzQ29udHJvbGxlci5nZXRDb250ZXh0KCk7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICByZXR1cm4gQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQobmV3IFByaXZpbGVnZWRBY3Rpb248U2NoZW1hRmFjdG9yeT4oKSB7Ci0gICAgICAgICAgICAgICAgcHVibGljIFNjaGVtYUZhY3RvcnkgcnVuKCkgewotICAgICAgICAgICAgICAgICAgICBmaW5hbCBTZXJ2aWNlTG9hZGVyPFNjaGVtYUZhY3Rvcnk+IGxvYWRlciA9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgU2VydmljZUxvYWRlci5sb2FkKFNFUlZJQ0VfQ0xBU1MpOwotICAgICAgICAgICAgICAgICAgICBmb3IgKFNjaGVtYUZhY3RvcnkgZmFjdG9yeSA6IGxvYWRlcikgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gcmVzdG9yZSBpbml0aWFsIGNvbnRleHQgdG8gY2FsbAotICAgICAgICAgICAgICAgICAgICAgICAgLy8gZmFjdG9yeS5pc1NjaGVtYUxhbmd1YWdlU3VwcG9ydGVkCi0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNTY2hlbWFMYW5ndWFnZVN1cHBvcnRlZEJ5KGZhY3RvcnksIHNjaGVtYUxhbmd1YWdlLCBhY2MpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhY3Rvcnk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7IC8vIG5vIGZhY3RvcnkgZm91bmQuCi0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfSk7Ci0gICAgICAgIH0gY2F0Y2ggKFNlcnZpY2VDb25maWd1cmF0aW9uRXJyb3IgZXJyb3IpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBTY2hlbWFGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yKAotICAgICAgICAgICAgICAgICAgICAiUHJvdmlkZXIgZm9yICIgKyBTRVJWSUNFX0NMQVNTICsgIiBjYW5ub3QgYmUgY3JlYXRlZCIsIGVycm9yKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIENsYXNzPFNjaGVtYUZhY3Rvcnk+IFNFUlZJQ0VfQ0xBU1MgPSBTY2hlbWFGYWN0b3J5LmNsYXNzOwotCi0KLSAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgd2hpY2goIENsYXNzPD8+IGNsYXp6ICkgewotICAgICAgICByZXR1cm4gd2hpY2goIGNsYXp6LmdldE5hbWUoKSwgY2xhenouZ2V0Q2xhc3NMb2FkZXIoKSApOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPlNlYXJjaCB0aGUgc3BlY2lmaWVkIGNsYXNzbG9hZGVyIGZvciB0aGUgZ2l2ZW4gY2xhc3NuYW1lLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjbGFzc25hbWUgdGhlIGZ1bGx5IHF1YWxpZmllZCBuYW1lIG9mIHRoZSBjbGFzcyB0byBzZWFyY2ggZm9yCi0gICAgICogQHBhcmFtIGxvYWRlciB0aGUgY2xhc3Nsb2FkZXIgdG8gc2VhcmNoCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRoZSBzb3VyY2UgbG9jYXRpb24gb2YgdGhlIHJlc291cmNlLCBvciBudWxsIGlmIGl0IHdhc24ndCBmb3VuZAotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyB3aGljaChTdHJpbmcgY2xhc3NuYW1lLCBDbGFzc0xvYWRlciBsb2FkZXIpIHsKLQotICAgICAgICBTdHJpbmcgY2xhc3NuYW1lQXNSZXNvdXJjZSA9IGNsYXNzbmFtZS5yZXBsYWNlKCcuJywgJy8nKSArICIuY2xhc3MiOwotCi0gICAgICAgIGlmKCBsb2FkZXI9PW51bGwgKSAgbG9hZGVyID0gQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKTsKLQotICAgICAgICAvL1VSTCBpdCA9IGxvYWRlci5nZXRSZXNvdXJjZShjbGFzc25hbWVBc1Jlc291cmNlKTsKLSAgICAgICAgVVJMIGl0ID0gc3MuZ2V0UmVzb3VyY2VBc1VSTChsb2FkZXIsIGNsYXNzbmFtZUFzUmVzb3VyY2UpOwotICAgICAgICBpZiAoaXQgIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIGl0LnRvU3RyaW5nKCk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9qYXZheC94bWwvdmFsaWRhdGlvbi9TY2hlbWFGYWN0b3J5TG9hZGVyLmphdmEgYi9zcmMvamF2YXgveG1sL3ZhbGlkYXRpb24vU2NoZW1hRmFjdG9yeUxvYWRlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmNjE3ZDk5Li4wMDAwMDAwCi0tLSBhL3NyYy9qYXZheC94bWwvdmFsaWRhdGlvbi9TY2hlbWFGYWN0b3J5TG9hZGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw2OCArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDA0LCAyMDA2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi1wYWNrYWdlIGphdmF4LnhtbC52YWxpZGF0aW9uOwotCi0vKioKLSAqIDxwPkZhY3RvcnkgdGhhdCBjcmVhdGVzIHtAbGluayBTY2hlbWFGYWN0b3J5fS48L3A+Ci0gKgotICogPHA+PGI+RE8gTk9UIFVTRSBUSElTIENMQVNTPC9iPjwvcD4KLSAqCi0gKiA8cD4KLSAqIFRoaXMgY2xhc3Mgd2FzIGludHJvZHVjZWQgYXMgYSBwYXJ0IG9mIGFuIGVhcmx5IHByb3Bvc2FsIGR1cmluZyB0aGUKLSAqIEpTUi0yMDYgc3RhbmRhcmRpemF0aW9uIHByb2Nlc3MuIFRoZSBwcm9wb3NhbCB3YXMgZXZlbnR1YWxseSBhYmFuZG9uZWQKLSAqIGJ1dCB0aGlzIGNsYXNzIGFjY2lkZW50YWxseSByZW1haW5lZCBpbiB0aGUgc291cmNlIHRyZWUsIGFuZCBtYWRlIGl0cwotICogd2F5IGludG8gdGhlIGZpbmFsIHZlcnNpb24uCi0gKiA8L3A+PHA+Ci0gKiBUaGlzIGNsYXNzIGRvZXMgbm90IHBhcnRpY2lwYXRlIGluIGFueSBKQVhQIDEuMyBvciBKQVhQIDEuNCBwcm9jZXNzaW5nLgotICogSXQgbXVzdCBub3QgYmUgdXNlZCBieSB1c2VycyBvciBKQVhQIGltcGxlbWVudGF0aW9ucy4KLSAqIDwvcD4KLSAqCi0gKiBAYXV0aG9yIDxhIGhyZWY9IktvaHN1a2UuS2F3YWd1Y2hpQFN1bi5jb20iPktvaHN1a2UgS2F3YWd1Y2hpPC9hPgotICogQHNpbmNlIDEuNQotICovCi1wdWJsaWMgYWJzdHJhY3QgY2xhc3MgU2NoZW1hRmFjdG9yeUxvYWRlciB7Ci0KLSAgICAvKioKLSAgICAgKiBBIGRvLW5vdGhpbmcgY29uc3RydWN0b3IuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIFNjaGVtYUZhY3RvcnlMb2FkZXIoKSB7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlcyBhIG5ldyB7QGxpbmsgU2NoZW1hRmFjdG9yeX0gb2JqZWN0IGZvciB0aGUgc3BlY2lmaWVkCi0gICAgICogc2NoZW1hIGxhbmd1YWdlLgotICAgICAqCi0gICAgICogQHBhcmFtIHNjaGVtYUxhbmd1YWdlCi0gICAgICogICAgICBTZWUgPGEgaHJlZj0iU2NoZW1hRmFjdG9yeS5odG1sI3NjaGVtYUxhbmd1YWdlIj4KLSAgICAgKiAgICAgIHRoZSBsaXN0IG9mIGF2YWlsYWJsZSBzY2hlbWEgbGFuZ3VhZ2VzPC9hPi4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KLSAgICAgKiAgICAgIElmIHRoZSA8dHQ+c2NoZW1hTGFuZ3VhZ2U8L3R0PiBwYXJhbWV0ZXIgaXMgbnVsbC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlIGNhbGxlZSBmYWlscyB0byBjcmVhdGUgb25lLgotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCBTY2hlbWFGYWN0b3J5IG5ld0ZhY3RvcnkoU3RyaW5nIHNjaGVtYUxhbmd1YWdlKTsKLX0KZGlmZiAtLWdpdCBhL3NyYy9qYXZheC94bWwvdmFsaWRhdGlvbi9TZWN1cml0eVN1cHBvcnQuamF2YSBiL3NyYy9qYXZheC94bWwvdmFsaWRhdGlvbi9TZWN1cml0eVN1cHBvcnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZTExZmY2NC4uMDAwMDAwMAotLS0gYS9zcmMvamF2YXgveG1sL3ZhbGlkYXRpb24vU2VjdXJpdHlTdXBwb3J0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNjMgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAwNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotcGFja2FnZSBqYXZheC54bWwudmFsaWRhdGlvbjsKLQotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci1pbXBvcnQgamF2YS5uZXQuVVJMOwotaW1wb3J0IGphdmEuc2VjdXJpdHkuKjsKLWltcG9ydCBqYXZhLm5ldC4qOwotaW1wb3J0IGphdmEuaW8uKjsKLWltcG9ydCBqYXZhLnV0aWwuKjsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGlzIGR1cGxpY2F0ZWQgZm9yIGVhY2ggSkFYUCBzdWJwYWNrYWdlIHNvIGtlZXAgaXQgaW4gc3luYy4KLSAqIEl0IGlzIHBhY2thZ2UgcHJpdmF0ZSBhbmQgdGhlcmVmb3JlIGlzIG5vdCBleHBvc2VkIGFzIHBhcnQgb2YgdGhlIEpBWFAKLSAqIEFQSS4KLSAqCi0gKiBTZWN1cml0eSByZWxhdGVkIG1ldGhvZHMgdGhhdCBvbmx5IHdvcmsgb24gSjJTRSAxLjIgYW5kIG5ld2VyLgotICovCi1jbGFzcyBTZWN1cml0eVN1cHBvcnQgIHsKLQotCi0gICAgQ2xhc3NMb2FkZXIgZ2V0Q29udGV4dENsYXNzTG9hZGVyKCkgewotICAgICAgICByZXR1cm4gKENsYXNzTG9hZGVyKQotICAgICAgICBBY2Nlc3NDb250cm9sbGVyLmRvUHJpdmlsZWdlZChuZXcgUHJpdmlsZWdlZEFjdGlvbigpIHsKLSAgICAgICAgICAgIHB1YmxpYyBPYmplY3QgcnVuKCkgewotICAgICAgICAgICAgICAgIENsYXNzTG9hZGVyIGNsID0gbnVsbDsKLSAgICAgICAgICAgICAgICAvL3RyeSB7Ci0gICAgICAgICAgICAgICAgY2wgPSBUaHJlYWQuY3VycmVudFRocmVhZCgpLmdldENvbnRleHRDbGFzc0xvYWRlcigpOwotICAgICAgICAgICAgICAgIC8vfSBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gZXgpIHsgfQotICAgICAgICAgICAgICAgIGlmIChjbCA9PSBudWxsKQotICAgICAgICAgICAgICAgICAgICBjbCA9IENsYXNzTG9hZGVyLmdldFN5c3RlbUNsYXNzTG9hZGVyKCk7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGNsOwotICAgICAgICAgICAgfQotICAgICAgICB9KTsKLSAgICB9Ci0KLSAgICBTdHJpbmcgZ2V0U3lzdGVtUHJvcGVydHkoZmluYWwgU3RyaW5nIHByb3BOYW1lKSB7Ci0gICAgICAgIHJldHVybiAoU3RyaW5nKQotICAgICAgICAgICAgQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQobmV3IFByaXZpbGVnZWRBY3Rpb24oKSB7Ci0gICAgICAgICAgICAgICAgcHVibGljIE9iamVjdCBydW4oKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBTeXN0ZW0uZ2V0UHJvcGVydHkocHJvcE5hbWUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0pOwotICAgIH0KLQotICAgIEZpbGVJbnB1dFN0cmVhbSBnZXRGaWxlSW5wdXRTdHJlYW0oZmluYWwgRmlsZSBmaWxlKQotICAgICAgICB0aHJvd3MgRmlsZU5vdEZvdW5kRXhjZXB0aW9uCi0gICAgewotICAgICAgICB0cnkgewotICAgICAgICAgICAgcmV0dXJuIChGaWxlSW5wdXRTdHJlYW0pCi0gICAgICAgICAgICAgICAgQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQobmV3IFByaXZpbGVnZWRFeGNlcHRpb25BY3Rpb24oKSB7Ci0gICAgICAgICAgICAgICAgICAgIHB1YmxpYyBPYmplY3QgcnVuKCkgdGhyb3dzIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEZpbGVJbnB1dFN0cmVhbShmaWxlKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0pOwotICAgICAgICB9IGNhdGNoIChQcml2aWxlZ2VkQWN0aW9uRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIHRocm93IChGaWxlTm90Rm91bmRFeGNlcHRpb24pZS5nZXRFeGNlcHRpb24oKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIElucHV0U3RyZWFtIGdldFVSTElucHV0U3RyZWFtKGZpbmFsIFVSTCB1cmwpCi0gICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIHJldHVybiAoSW5wdXRTdHJlYW0pCi0gICAgICAgICAgICAgICAgQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQobmV3IFByaXZpbGVnZWRFeGNlcHRpb25BY3Rpb24oKSB7Ci0gICAgICAgICAgICAgICAgICAgIHB1YmxpYyBPYmplY3QgcnVuKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB1cmwub3BlblN0cmVhbSgpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfSk7Ci0gICAgICAgIH0gY2F0Y2ggKFByaXZpbGVnZWRBY3Rpb25FeGNlcHRpb24gZSkgewotICAgICAgICAgICAgdGhyb3cgKElPRXhjZXB0aW9uKWUuZ2V0RXhjZXB0aW9uKCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBVUkwgZ2V0UmVzb3VyY2VBc1VSTChmaW5hbCBDbGFzc0xvYWRlciBjbCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgbmFtZSkKLSAgICB7Ci0gICAgICAgIHJldHVybiAoVVJMKQotICAgICAgICAgICAgQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQobmV3IFByaXZpbGVnZWRBY3Rpb24oKSB7Ci0gICAgICAgICAgICAgICAgcHVibGljIE9iamVjdCBydW4oKSB7Ci0gICAgICAgICAgICAgICAgICAgIFVSTCB1cmw7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChjbCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICB1cmwgPSBPYmplY3QuY2xhc3MuZ2V0UmVzb3VyY2UobmFtZSk7Ci0gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICB1cmwgPSBjbC5nZXRSZXNvdXJjZShuYW1lKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICByZXR1cm4gdXJsOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0pOwotICAgIH0KLQotICAgIEVudW1lcmF0aW9uIGdldFJlc291cmNlcyhmaW5hbCBDbGFzc0xvYWRlciBjbCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgbmFtZSkgdGhyb3dzIElPRXhjZXB0aW9uCi0gICAgewotICAgICAgICB0cnl7Ci0gICAgICAgIHJldHVybiAoRW51bWVyYXRpb24pCi0gICAgICAgICAgICBBY2Nlc3NDb250cm9sbGVyLmRvUHJpdmlsZWdlZChuZXcgUHJpdmlsZWdlZEV4Y2VwdGlvbkFjdGlvbigpIHsKLSAgICAgICAgICAgICAgICBwdWJsaWMgT2JqZWN0IHJ1bigpIHRocm93cyBJT0V4Y2VwdGlvbnsKLSAgICAgICAgICAgICAgICAgICAgRW51bWVyYXRpb24gZW51bWVyYXRpb247Ci0gICAgICAgICAgICAgICAgICAgIGlmIChjbCA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBlbnVtZXJhdGlvbiA9IENsYXNzTG9hZGVyLmdldFN5c3RlbVJlc291cmNlcyhuYW1lKTsKLSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGVudW1lcmF0aW9uID0gY2wuZ2V0UmVzb3VyY2VzKG5hbWUpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBlbnVtZXJhdGlvbjsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9KTsKLSAgICAgICAgfWNhdGNoKFByaXZpbGVnZWRBY3Rpb25FeGNlcHRpb24gZSl7Ci0gICAgICAgICAgICB0aHJvdyAoSU9FeGNlcHRpb24pZS5nZXRFeGNlcHRpb24oKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIElucHV0U3RyZWFtIGdldFJlc291cmNlQXNTdHJlYW0oZmluYWwgQ2xhc3NMb2FkZXIgY2wsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIG5hbWUpCi0gICAgewotICAgICAgICByZXR1cm4gKElucHV0U3RyZWFtKQotICAgICAgICAgICAgQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQobmV3IFByaXZpbGVnZWRBY3Rpb24oKSB7Ci0gICAgICAgICAgICAgICAgcHVibGljIE9iamVjdCBydW4oKSB7Ci0gICAgICAgICAgICAgICAgICAgIElucHV0U3RyZWFtIHJpczsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGNsID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJpcyA9IE9iamVjdC5jbGFzcy5nZXRSZXNvdXJjZUFzU3RyZWFtKG5hbWUpOwotICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgcmlzID0gY2wuZ2V0UmVzb3VyY2VBc1N0cmVhbShuYW1lKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmlzOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0pOwotICAgIH0KLQotICAgIGJvb2xlYW4gZG9lc0ZpbGVFeGlzdChmaW5hbCBGaWxlIGYpIHsKLSAgICByZXR1cm4gKChCb29sZWFuKQotICAgICAgICAgICAgQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQobmV3IFByaXZpbGVnZWRBY3Rpb24oKSB7Ci0gICAgICAgICAgICAgICAgcHVibGljIE9iamVjdCBydW4oKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQm9vbGVhbihmLmV4aXN0cygpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9KSkuYm9vbGVhblZhbHVlKCk7Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvamF2YXgveG1sL3ZhbGlkYXRpb24vVHlwZUluZm9Qcm92aWRlci5qYXZhIGIvc3JjL2phdmF4L3htbC92YWxpZGF0aW9uL1R5cGVJbmZvUHJvdmlkZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNmI0YzdiNC4uMDAwMDAwMAotLS0gYS9zcmMvamF2YXgveG1sL3ZhbGlkYXRpb24vVHlwZUluZm9Qcm92aWRlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTk3ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDMsIDIwMDUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLXBhY2thZ2UgamF2YXgueG1sLnZhbGlkYXRpb247Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5UeXBlSW5mbzsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIHByb3ZpZGVzIGFjY2VzcyB0byB0aGUgdHlwZSBpbmZvcm1hdGlvbiBkZXRlcm1pbmVkCi0gKiBieSB7QGxpbmsgVmFsaWRhdG9ySGFuZGxlcn0uCi0gKgotICogPHA+Ci0gKiBTb21lIHNjaGVtYSBsYW5ndWFnZXMsIHN1Y2ggYXMgVzNDIFhNTCBTY2hlbWEsIGVuY291cmFnZXMgYSB2YWxpZGF0b3IKLSAqIHRvIHJlcG9ydCB0aGUgInR5cGUiIGl0IGFzc2lnbnMgdG8gZWFjaCBhdHRyaWJ1dGUvZWxlbWVudC4KLSAqIFRob3NlIGFwcGxpY2F0aW9ucyB3aG8gd2lzaCB0byBhY2Nlc3MgdGhpcyB0eXBlIGluZm9ybWF0aW9uIGNhbiBpbnZva2UKLSAqIG1ldGhvZHMgZGVmaW5lZCBvbiB0aGlzICJpbnRlcmZhY2UiIHRvIGFjY2VzcyBzdWNoIHR5cGUgaW5mb3JtYXRpb24uCi0gKgotICogPHA+Ci0gKiBJbXBsZW1lbnRhdGlvbiBvZiB0aGlzICJpbnRlcmZhY2UiIGNhbiBiZSBvYnRhaW5lZCB0aHJvdWdoIHRoZQotICoge0BsaW5rIFZhbGlkYXRvckhhbmRsZXIjZ2V0VHlwZUluZm9Qcm92aWRlcigpfSBtZXRob2QuCi0gKgotICogQGF1dGhvciAgPGEgaHJlZj0ibWFpbHRvOktvaHN1a2UuS2F3YWd1Y2hpQFN1bi5jb20iPktvaHN1a2UgS2F3YWd1Y2hpPC9hPgotICogQHNlZSBvcmcudzNjLmRvbS5UeXBlSW5mbwotICogQHNpbmNlIDEuNQotICovCi1wdWJsaWMgYWJzdHJhY3QgY2xhc3MgVHlwZUluZm9Qcm92aWRlciB7Ci0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RvciBmb3IgdGhlIGRlcml2ZWQgY2xhc3MuCi0gICAgICoKLSAgICAgKiA8cD4KLSAgICAgKiBUaGUgY29uc3RydWN0b3IgZG9lcyBub3RoaW5nLgotICAgICAqLwotICAgIHByb3RlY3RlZCBUeXBlSW5mb1Byb3ZpZGVyKCkgewotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPlJldHVybnMgdGhlIGltbXV0YWJsZSB7QGxpbmsgVHlwZUluZm99IG9iamVjdCBmb3IgdGhlIGN1cnJlbnQKLSAgICAgKiBlbGVtZW50LjwvcD4KLSAgICAgKgotICAgICAqIDxwPlRoZSBtZXRob2QgbWF5IG9ubHkgYmUgY2FsbGVkIGJ5IHRoZSBzdGFydEVsZW1lbnQgZXZlbnQKLSAgICAgKiBvciB0aGUgZW5kRWxlbWVudCBldmVudAotICAgICAqIG9mIHRoZSB7QGxpbmsgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXJ9IHRoYXQgdGhlIGFwcGxpY2F0aW9uIHNldHMgdG8KLSAgICAgKiB0aGUge0BsaW5rIFZhbGlkYXRvckhhbmRsZXJ9LjwvcD4KLSAgICAgKgotICAgICAqIDxwPldoZW4gVzNDIFhNTCBTY2hlbWEgdmFsaWRhdGlvbiBpcyBiZWluZyBwZXJmb3JtZWQsIGluIHRoZQotICAgICAqIGNhc2Ugd2hlcmUgYW4gZWxlbWVudCBoYXMgYSB1bmlvbiB0eXBlLCB0aGUge0BsaW5rIFR5cGVJbmZvfQotICAgICAqIHJldHVybmVkIGJ5IGEgY2FsbCB0byA8Y29kZT5nZXRFbGVtZW50VHlwZUluZm8oKTwvY29kZT4gZnJvbSB0aGUKLSAgICAgKiBzdGFydEVsZW1lbnQKLSAgICAgKiBldmVudCB3aWxsIGJlIHRoZSB1bmlvbiB0eXBlLiBUaGUgPGNvZGU+VHlwZUluZm88L2NvZGU+Ci0gICAgICogcmV0dXJuZWQgYnkgYSBjYWxsCi0gICAgICogZnJvbSB0aGUgZW5kRWxlbWVudCBldmVudCB3aWxsIGJlIHRoZSBhY3R1YWwgbWVtYmVyIHR5cGUgdXNlZAotICAgICAqIHRvIHZhbGlkYXRlIHRoZSBlbGVtZW50LjwvcD4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCi0gICAgICogICAgICBJZiB0aGlzIG1ldGhvZCBpcyBjYWxsZWQgZnJvbSBvdGhlciB7QGxpbmsgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXJ9Ci0gICAgICogICAgICBtZXRob2RzLgotICAgICAqIEByZXR1cm4KLSAgICAgKiAgICAgIEFuIGltbXV0YWJsZSB7QGxpbmsgVHlwZUluZm99IG9iamVjdCB0aGF0IHJlcHJlc2VudHMgdGhlCi0gICAgICogICAgICB0eXBlIG9mIHRoZSBjdXJyZW50IGVsZW1lbnQuCi0gICAgICogICAgICBOb3RlIHRoYXQgdGhlIGNhbGxlciBjYW4ga2VlcCByZWZlcmVuY2VzIHRvIHRoZSBvYnRhaW5lZAotICAgICAqICAgICAge0BsaW5rIFR5cGVJbmZvfSBsb25nZXIgdGhhbiB0aGUgY2FsbGJhY2sgc2NvcGUuCi0gICAgICoKLSAgICAgKiAgICAgIE90aGVyd2lzZSwgdGhpcyBtZXRob2QgcmV0dXJucwotICAgICAqICAgICAgbnVsbCBpZiB0aGUgdmFsaWRhdG9yIGlzIHVuYWJsZSB0bwotICAgICAqICAgICAgZGV0ZXJtaW5lIHRoZSB0eXBlIG9mIHRoZSBjdXJyZW50IGVsZW1lbnQgZm9yIHNvbWUgcmVhc29uCi0gICAgICogICAgICAoZm9yIGV4YW1wbGUsIGlmIHRoZSB2YWxpZGF0b3IgaXMgcmVjb3ZlcmluZyBmcm9tCi0gICAgICogICAgICBhbiBlYXJsaWVyIGVycm9yLikKLSAgICAgKgotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCBUeXBlSW5mbyBnZXRFbGVtZW50VHlwZUluZm8oKTsKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIGltbXV0YWJsZSB7QGxpbmsgVHlwZUluZm99IG9iamVjdCBmb3IgdGhlIHNwZWNpZmllZAotICAgICAqIGF0dHJpYnV0ZSBvZiB0aGUgY3VycmVudCBlbGVtZW50LgotICAgICAqCi0gICAgICogPHA+Ci0gICAgICogVGhlIG1ldGhvZCBtYXkgb25seSBiZSBjYWxsZWQgYnkgdGhlIHN0YXJ0RWxlbWVudCBldmVudCBvZgotICAgICAqIHRoZSB7QGxpbmsgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXJ9IHRoYXQgdGhlIGFwcGxpY2F0aW9uIHNldHMgdG8gdGhlCi0gICAgICoge0BsaW5rIFZhbGlkYXRvckhhbmRsZXJ9LjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBpbmRleAotICAgICAqICAgICAgVGhlIGluZGV4IG9mIHRoZSBhdHRyaWJ1dGUuIFRoZSBzYW1lIGluZGV4IGZvcgotICAgICAqICAgICAgdGhlIHtAbGluayBvcmcueG1sLnNheC5BdHRyaWJ1dGVzfSBvYmplY3QgcGFzc2VkIHRvIHRoZQotICAgICAqICAgICAgPGNvZGU+c3RhcnRFbGVtZW50PC9jb2RlPiBjYWxsYmFjay4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgotICAgICAqICAgICAgSWYgdGhlIGluZGV4IGlzIGludmFsaWQuCi0gICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KLSAgICAgKiAgICAgIElmIHRoaXMgbWV0aG9kIGlzIGNhbGxlZCBmcm9tIG90aGVyIHtAbGluayBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcn0KLSAgICAgKiAgICAgIG1ldGhvZHMuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuCi0gICAgICogICAgICBBbiBpbW11dGFibGUge0BsaW5rIFR5cGVJbmZvfSBvYmplY3QgdGhhdCByZXByZXNlbnRzIHRoZQotICAgICAqICAgICAgdHlwZSBvZiB0aGUgc3BlY2lmaWVkIGF0dHJpYnV0ZS4KLSAgICAgKiAgICAgIE5vdGUgdGhhdCB0aGUgY2FsbGVyIGNhbiBrZWVwIHJlZmVyZW5jZXMgdG8gdGhlIG9idGFpbmVkCi0gICAgICogICAgICB7QGxpbmsgVHlwZUluZm99IGxvbmdlciB0aGFuIHRoZSBjYWxsYmFjayBzY29wZS4KLSAgICAgKgotICAgICAqICAgICAgT3RoZXJ3aXNlLCB0aGlzIG1ldGhvZCByZXR1cm5zCi0gICAgICogICAgICBudWxsIGlmIHRoZSB2YWxpZGF0b3IgaXMgdW5hYmxlIHRvCi0gICAgICogICAgICBkZXRlcm1pbmUgdGhlIHR5cGUuCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IFR5cGVJbmZvIGdldEF0dHJpYnV0ZVR5cGVJbmZvKGludCBpbmRleCk7Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBzcGVjaWZpZWQgYXR0cmlidXRlIGlzIGRldGVybWluZWQKLSAgICAgKiB0byBiZSBJRC4KLSAgICAgKgotICAgICAqIDxwPgotICAgICAqIEV4YWNseSBob3cgYW4gYXR0cmlidXRlIGlzICJkZXRlcm1pbmVkIHRvIGJlIElEIiBpcyB1cCB0byB0aGUKLSAgICAgKiBzY2hlbWEgbGFuZ3VhZ2UuIEluIGNhc2Ugb2YgVzNDIFhNTCBTY2hlbWEsIHRoaXMgbWVhbnMKLSAgICAgKiB0aGF0IHRoZSBhY3R1YWwgdHlwZSBvZiB0aGUgYXR0cmlidXRlIGlzIHRoZSBidWlsdC1pbiBJRCB0eXBlCi0gICAgICogb3IgaXRzIGRlcml2ZWQgdHlwZS4KLSAgICAgKgotICAgICAqIDxwPgotICAgICAqIEEge0BsaW5rIGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlcn0gdXNlcyB0aGlzIGluZm9ybWF0aW9uCi0gICAgICogdG8gcHJvcGVybHkgaW1wbGVtZW50IHtAbGluayBvcmcudzNjLmRvbS5BdHRyI2lzSWQoKX0uCi0gICAgICoKLSAgICAgKiA8cD4KLSAgICAgKiBUaGUgbWV0aG9kIG1heSBvbmx5IGJlIGNhbGxlZCBieSB0aGUgc3RhcnRFbGVtZW50IGV2ZW50IG9mCi0gICAgICogdGhlIHtAbGluayBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcn0gdGhhdCB0aGUgYXBwbGljYXRpb24gc2V0cyB0byB0aGUKLSAgICAgKiB7QGxpbmsgVmFsaWRhdG9ySGFuZGxlcn0uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaW5kZXgKLSAgICAgKiAgICAgIFRoZSBpbmRleCBvZiB0aGUgYXR0cmlidXRlLiBUaGUgc2FtZSBpbmRleCBmb3IKLSAgICAgKiAgICAgIHRoZSB7QGxpbmsgb3JnLnhtbC5zYXguQXR0cmlidXRlc30gb2JqZWN0IHBhc3NlZCB0byB0aGUKLSAgICAgKiAgICAgIDxjb2RlPnN0YXJ0RWxlbWVudDwvY29kZT4gY2FsbGJhY2suCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KLSAgICAgKiAgICAgIElmIHRoZSBpbmRleCBpcyBpbnZhbGlkLgotICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCi0gICAgICogICAgICBJZiB0aGlzIG1ldGhvZCBpcyBjYWxsZWQgZnJvbSBvdGhlciB7QGxpbmsgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXJ9Ci0gICAgICogICAgICBtZXRob2RzLgotICAgICAqCi0gICAgICogQHJldHVybiB0cnVlCi0gICAgICogICAgICBpZiB0aGUgdHlwZSBvZiB0aGUgc3BlY2lmaWVkIGF0dHJpYnV0ZSBpcyBJRC4KLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBpc0lkQXR0cmlidXRlKGludCBpbmRleCk7Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIDxjb2RlPmZhbHNlPC9jb2RlPiBpZiB0aGUgYXR0cmlidXRlIHdhcyBhZGRlZCBieSB0aGUgdmFsaWRhdG9yLgotICAgICAqCi0gICAgICogPHA+Ci0gICAgICogVGhpcyBtZXRob2QgcHJvdmlkZXMgaW5mb3JtYXRpb24gbmVjZXNzYXJ5IGZvcgotICAgICAqIGEge0BsaW5rIGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlcn0gdG8gZGV0ZXJtaW5lIHdoYXQKLSAgICAgKiB0aGUgRE9NIHRyZWUgc2hvdWxkIHJldHVybiBmcm9tIHRoZSB7QGxpbmsgb3JnLnczYy5kb20uQXR0ciNnZXRTcGVjaWZpZWQoKX0gbWV0aG9kLgotICAgICAqCi0gICAgICogPHA+Ci0gICAgICogVGhlIG1ldGhvZCBtYXkgb25seSBiZSBjYWxsZWQgYnkgdGhlIHN0YXJ0RWxlbWVudCBldmVudCBvZgotICAgICAqIHRoZSB7QGxpbmsgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXJ9IHRoYXQgdGhlIGFwcGxpY2F0aW9uIHNldHMgdG8gdGhlCi0gICAgICoge0BsaW5rIFZhbGlkYXRvckhhbmRsZXJ9LgotICAgICAqCi0gICAgICogPHA+Ci0gICAgICogQSBnZW5lcmFsIGd1aWRlbGluZSBmb3IgdmFsaWRhdG9ycyBpcyB0byByZXR1cm4gdHJ1ZSBpZgotICAgICAqIHRoZSBhdHRyaWJ1dGUgd2FzIG9yaWdpbmFsbHkgcHJlc2VudCBpbiB0aGUgcGlwZWxpbmUsIGFuZAotICAgICAqIGZhbHNlIGlmIGl0IHdhcyBhZGRlZCBieSB0aGUgdmFsaWRhdG9yLgotICAgICAqCi0gICAgICogQHBhcmFtIGluZGV4Ci0gICAgICogICAgICBUaGUgaW5kZXggb2YgdGhlIGF0dHJpYnV0ZS4gVGhlIHNhbWUgaW5kZXggZm9yCi0gICAgICogICAgICB0aGUge0BsaW5rIG9yZy54bWwuc2F4LkF0dHJpYnV0ZXN9IG9iamVjdCBwYXNzZWQgdG8gdGhlCi0gICAgICogICAgICA8Y29kZT5zdGFydEVsZW1lbnQ8L2NvZGU+IGNhbGxiYWNrLgotICAgICAqCi0gICAgICogQHRocm93cyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCi0gICAgICogICAgICBJZiB0aGUgaW5kZXggaXMgaW52YWxpZC4KLSAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgotICAgICAqICAgICAgSWYgdGhpcyBtZXRob2QgaXMgY2FsbGVkIGZyb20gb3RoZXIge0BsaW5rIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyfQotICAgICAqICAgICAgbWV0aG9kcy4KLSAgICAgKgotICAgICAqIEByZXR1cm4KLSAgICAgKiAgICAgIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBhdHRyaWJ1dGUgd2FzIHByZXNlbnQgYmVmb3JlIHRoZSB2YWxpZGF0b3IKLSAgICAgKiAgICAgIHByb2Nlc3NlcyBpbnB1dC4gPGNvZGU+ZmFsc2U8L2NvZGU+IGlmIHRoZSBhdHRyaWJ1dGUgd2FzIGFkZGVkCi0gICAgICogICAgICBieSB0aGUgdmFsaWRhdG9yLgotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGlzU3BlY2lmaWVkKGludCBpbmRleCk7Ci19CmRpZmYgLS1naXQgYS9zcmMvamF2YXgveG1sL3ZhbGlkYXRpb24vVmFsaWRhdG9yLmphdmEgYi9zcmMvamF2YXgveG1sL3ZhbGlkYXRpb24vVmFsaWRhdG9yLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDQ5ODNlMDMuLjAwMDAwMDAKLS0tIGEvc3JjL2phdmF4L3htbC92YWxpZGF0aW9uL1ZhbGlkYXRvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTI0ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDMsIDIwMTMsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLXBhY2thZ2UgamF2YXgueG1sLnZhbGlkYXRpb247Ci0KLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5SZXN1bHQ7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2U7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5scy5MU1Jlc291cmNlUmVzb2x2ZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguRXJyb3JIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbjsKLQotLyoqCi0gKiA8cD5BIHByb2Nlc3NvciB0aGF0IGNoZWNrcyBhbiBYTUwgZG9jdW1lbnQgYWdhaW5zdCB7QGxpbmsgU2NoZW1hfS48L3A+Ci0gKgotICogPHA+Ci0gKiBBIHZhbGlkYXRvciBvYmplY3QgaXMgbm90IHRocmVhZC1zYWZlIGFuZCBub3QgcmVlbnRyYW50LgotICogSW4gb3RoZXIgd29yZHMsIGl0IGlzIHRoZSBhcHBsaWNhdGlvbidzIHJlc3BvbnNpYmlsaXR5IHRvIG1ha2UKLSAqIHN1cmUgdGhhdCBvbmUge0BsaW5rIFZhbGlkYXRvcn0gb2JqZWN0IGlzIG5vdCB1c2VkIGZyb20KLSAqIG1vcmUgdGhhbiBvbmUgdGhyZWFkIGF0IGFueSBnaXZlbiB0aW1lLCBhbmQgd2hpbGUgdGhlIDxjb2RlPnZhbGlkYXRlPC9jb2RlPgotICogbWV0aG9kIGlzIGludm9rZWQsIGFwcGxpY2F0aW9ucyBtYXkgbm90IHJlY3Vyc2l2ZWx5IGNhbGwKLSAqIHRoZSA8Y29kZT52YWxpZGF0ZTwvY29kZT4gbWV0aG9kLgotICogPHA+Ci0gKgotICoKLSAqIEBhdXRob3IgIDxhIGhyZWY9Im1haWx0bzpLb2hzdWtlLkthd2FndWNoaUBTdW4uY29tIj5Lb2hzdWtlIEthd2FndWNoaTwvYT4KLSAqIEBzaW5jZSAxLjUKLSAqLwotcHVibGljIGFic3RyYWN0IGNsYXNzIFZhbGlkYXRvciB7Ci0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RvciBmb3IgZGVyaXZlZCBjbGFzc2VzLgotICAgICAqCi0gICAgICogPHA+VGhlIGNvbnN0cnVjdG9yIGRvZXMgbm90aGluZy48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5EZXJpdmVkIGNsYXNzZXMgbXVzdCBjcmVhdGUge0BsaW5rIFZhbGlkYXRvcn0gb2JqZWN0cyB0aGF0IGhhdmUKLSAgICAgKiA8Y29kZT5udWxsPC9jb2RlPiB7QGxpbmsgRXJyb3JIYW5kbGVyfSBhbmQKLSAgICAgKiA8Y29kZT5udWxsPC9jb2RlPiB7QGxpbmsgTFNSZXNvdXJjZVJlc29sdmVyfS4KLSAgICAgKiA8L3A+Ci0gICAgICovCi0gICAgcHJvdGVjdGVkIFZhbGlkYXRvcigpIHsKLSAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIDxwPlJlc2V0IHRoaXMgPGNvZGU+VmFsaWRhdG9yPC9jb2RlPiB0byBpdHMgb3JpZ2luYWwgY29uZmlndXJhdGlvbi48L3A+Ci0gICAgICAgICAqCi0gICAgICAgICAqIDxwPjxjb2RlPlZhbGlkYXRvcjwvY29kZT4gaXMgcmVzZXQgdG8gdGhlIHNhbWUgc3RhdGUgYXMgd2hlbiBpdCB3YXMgY3JlYXRlZCB3aXRoCi0gICAgICAgICAqIHtAbGluayBTY2hlbWEjbmV3VmFsaWRhdG9yKCl9LgotICAgICAgICAgKiA8Y29kZT5yZXNldCgpPC9jb2RlPiBpcyBkZXNpZ25lZCB0byBhbGxvdyB0aGUgcmV1c2Ugb2YgZXhpc3RpbmcgPGNvZGU+VmFsaWRhdG9yPC9jb2RlPnMKLSAgICAgICAgICogdGh1cyBzYXZpbmcgcmVzb3VyY2VzIGFzc29jaWF0ZWQgd2l0aCB0aGUgY3JlYXRpb24gb2YgbmV3IDxjb2RlPlZhbGlkYXRvcjwvY29kZT5zLjwvcD4KLSAgICAgICAgICoKLSAgICAgICAgICogPHA+VGhlIHJlc2V0IDxjb2RlPlZhbGlkYXRvcjwvY29kZT4gaXMgbm90IGd1YXJhbnRlZWQgdG8gaGF2ZSB0aGUgc2FtZSB7QGxpbmsgTFNSZXNvdXJjZVJlc29sdmVyfSBvciB7QGxpbmsgRXJyb3JIYW5kbGVyfQotICAgICAgICAgKiA8Y29kZT5PYmplY3Q8L2NvZGU+cywgZS5nLiB7QGxpbmsgT2JqZWN0I2VxdWFscyhPYmplY3Qgb2JqKX0uICBJdCBpcyBndWFyYW50ZWVkIHRvIGhhdmUgYSBmdW5jdGlvbmFsbHkgZXF1YWwKLSAgICAgICAgICogPGNvZGU+TFNSZXNvdXJjZVJlc29sdmVyPC9jb2RlPiBhbmQgPGNvZGU+RXJyb3JIYW5kbGVyPC9jb2RlPi48L3A+Ci0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCByZXNldCgpOwotCi0gICAgLyoqCi0gICAgICogVmFsaWRhdGVzIHRoZSBzcGVjaWZpZWQgaW5wdXQuCi0gICAgICoKLSAgICAgKiA8cD5UaGlzIGlzIGp1c3QgYSBjb252ZW5pZW5jZSBtZXRob2QgZm9yCi0gICAgICoge0BsaW5rICN2YWxpZGF0ZShTb3VyY2Ugc291cmNlLCBSZXN1bHQgcmVzdWx0KX0KLSAgICAgKiB3aXRoIDxjb2RlPnJlc3VsdDwvY29kZT4gb2YgPGNvZGU+bnVsbDwvY29kZT4uPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIHNvdXJjZQotICAgICAqICAgICAgWE1MIHRvIGJlIHZhbGlkYXRlZC4gTXVzdCBiZSBhbiBYTUwgZG9jdW1lbnQgb3IKLSAgICAgKiAgICAgIFhNTCBlbGVtZW50IGFuZCBtdXN0IG5vdCBiZSBudWxsLiBGb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHksCi0gICAgICogICAgICB0aGUgcmVzdWx0cyBvZiBhdHRlbXB0aW5nIHRvIHZhbGlkYXRlIGFueXRoaW5nIG90aGVyIHRoYW4KLSAgICAgKiAgICAgIGEgZG9jdW1lbnQgb3IgZWxlbWVudCBhcmUgaW1wbGVtZW50YXRpb24tZGVwZW5kZW50LgotICAgICAqICAgICAgSW1wbGVtZW50YXRpb25zIG11c3QgZWl0aGVyIHJlY29nbml6ZSBhbmQgcHJvY2VzcyB0aGUgaW5wdXQKLSAgICAgKiAgICAgIG9yIHRocm93IGFuIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbi4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCi0gICAgICogICAgICBJZiB0aGUgPGNvZGU+U291cmNlPC9jb2RlPgotICAgICAqICAgICAgaXMgYW4gWE1MIGFydGlmYWN0IHRoYXQgdGhlIGltcGxlbWVudGF0aW9uIGNhbm5vdAotICAgICAqICAgICAgdmFsaWRhdGUgKGZvciBleGFtcGxlLCBhIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24pLgotICAgICAqCi0gICAgICogQHRocm93cyBTQVhFeGNlcHRpb24KLSAgICAgKiAgICAgIElmIHRoZSB7QGxpbmsgRXJyb3JIYW5kbGVyfSB0aHJvd3MgYSB7QGxpbmsgU0FYRXhjZXB0aW9ufSBvcgotICAgICAqICAgICAgaWYgYSBmYXRhbCBlcnJvciBpcyBmb3VuZCBhbmQgdGhlIHtAbGluayBFcnJvckhhbmRsZXJ9IHJldHVybnMKLSAgICAgKiAgICAgIG5vcm1hbGx5LgotICAgICAqCi0gICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgotICAgICAqICAgICAgSWYgdGhlIHZhbGlkYXRvciBpcyBwcm9jZXNzaW5nIGEKLSAgICAgKiAgICAgIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLnNheC5TQVhTb3VyY2V9IGFuZCB0aGUKLSAgICAgKiAgICAgIHVuZGVybHlpbmcge0BsaW5rIG9yZy54bWwuc2F4LlhNTFJlYWRlcn0gdGhyb3dzIGFuCi0gICAgICogICAgICB7QGxpbmsgSU9FeGNlcHRpb259LgotICAgICAqCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIElmIDxjb2RlPnNvdXJjZTwvY29kZT4gaXMKLSAgICAgKiAgIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAqCi0gICAgICogQHNlZSAjdmFsaWRhdGUoU291cmNlIHNvdXJjZSwgUmVzdWx0IHJlc3VsdCkKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB2YWxpZGF0ZShTb3VyY2Ugc291cmNlKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7Ci0KLSAgICAgICAgdmFsaWRhdGUoc291cmNlLCBudWxsKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5WYWxpZGF0ZXMgdGhlIHNwZWNpZmllZCBpbnB1dCBhbmQgc2VuZCB0aGUgYXVnbWVudGVkIHZhbGlkYXRpb24KLSAgICAgKiByZXN1bHQgdG8gdGhlIHNwZWNpZmllZCBvdXRwdXQuPC9wPgotICAgICAqCi0gICAgICogPHA+VGhpcyBtZXRob2QgcGxhY2VzIHRoZSBmb2xsb3dpbmcgcmVzdHJpY3Rpb25zIG9uIHRoZSB0eXBlcyBvZgotICAgICAqIHRoZSB7QGxpbmsgU291cmNlfS97QGxpbmsgUmVzdWx0fSBhY2NlcHRlZC48L3A+Ci0gICAgICoKLSAgICAgKiA8dGFibGUgYm9yZGVyPTE+Ci0gICAgICogPHRoZWFkPgotICAgICAqICA8dHI+Ci0gICAgICogICA8dGggY29sc3Bhbj0iNSI+PGNvZGU+U291cmNlPC9jb2RlPiAvIDxjb2RlPlJlc3VsdDwvY29kZT4gQWNjZXB0ZWQ8L3RoPgotICAgICAqICA8L3RyPgotICAgICAqICA8dHI+Ci0gICAgICogICA8dGg+PC90aD4KLSAgICAgKiAgIDx0aD57QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5zdHJlYW0uU3RyZWFtU291cmNlfTwvdGg+Ci0gICAgICogICA8dGg+e0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlNBWFNvdXJjZX08L3RoPgotICAgICAqICAgPHRoPntAbGluayBqYXZheC54bWwudHJhbnNmb3JtLmRvbS5ET01Tb3VyY2V9PC90aD4KLSAgICAgKiAgIDx0aD57QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5zdGF4LlN0QVhTb3VyY2V9PC90aD4KLSAgICAgKiAgPC90cj4KLSAgICAgKiA8L3RoZWFkPgotICAgICAqIDx0Ym9keSBhbGlnbj0iY2VudGVyIj4KLSAgICAgKiAgPHRyPgotICAgICAqICAgPHRkPjxjb2RlPm51bGw8L2NvZGU+PC90ZD4KLSAgICAgKiAgIDx0ZD5PSzwvdGQ+Ci0gICAgICogICA8dGQ+T0s8L3RkPgotICAgICAqICAgPHRkPk9LPC90ZD4KLSAgICAgKiAgIDx0ZD5PSzwvdGQ+Ci0gICAgICogIDwvdHI+Ci0gICAgICogIDx0cj4KLSAgICAgKiAgIDx0aD57QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5zdHJlYW0uU3RyZWFtUmVzdWx0fTwvdGg+Ci0gICAgICogICA8dGQ+T0s8L3RkPgotICAgICAqICAgPHRkPjxjb2RlPklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbjwvY29kZT48L3RkPgotICAgICAqICAgPHRkPjxjb2RlPklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbjwvY29kZT48L3RkPgotICAgICAqICAgPHRkPjxjb2RlPklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbjwvY29kZT48L3RkPgotICAgICAqICA8L3RyPgotICAgICAqICA8dHI+Ci0gICAgICogICA8dGg+e0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlNBWFJlc3VsdH08L3RoPgotICAgICAqICAgPHRkPjxjb2RlPklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbjwvY29kZT48L3RkPgotICAgICAqICAgPHRkPk9LPC90ZD4KLSAgICAgKiAgIDx0ZD48Y29kZT5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb248L2NvZGU+PC90ZD4KLSAgICAgKiAgIDx0ZD48Y29kZT5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb248L2NvZGU+PC90ZD4KLSAgICAgKiAgPC90cj4KLSAgICAgKiAgPHRyPgotICAgICAqICAgPHRoPntAbGluayBqYXZheC54bWwudHJhbnNmb3JtLmRvbS5ET01SZXN1bHR9PC90aD4KLSAgICAgKiAgIDx0ZD48Y29kZT5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb248L2NvZGU+PC90ZD4KLSAgICAgKiAgIDx0ZD48Y29kZT5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb248L2NvZGU+PC90ZD4KLSAgICAgKiAgIDx0ZD5PSzwvdGQ+Ci0gICAgICogICA8dGQ+PGNvZGU+SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uPC9jb2RlPjwvdGQ+Ci0gICAgICogIDwvdHI+Ci0gICAgICogIDx0cj4KLSAgICAgKiAgIDx0aD57QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5zdGF4LlN0QVhSZXN1bHR9PC90aD4KLSAgICAgKiAgIDx0ZD48Y29kZT5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb248L2NvZGU+PC90ZD4KLSAgICAgKiAgIDx0ZD48Y29kZT5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb248L2NvZGU+PC90ZD4KLSAgICAgKiAgIDx0ZD48Y29kZT5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb248L2NvZGU+PC90ZD4KLSAgICAgKiAgIDx0ZD5PSzwvdGQ+Ci0gICAgICogIDwvdHI+Ci0gICAgICogPC90Ym9keT4KLSAgICAgKiA8L3RhYmxlPgotICAgICAqCi0gICAgICogPHA+VG8gdmFsaWRhdGUgb25lIDxjb2RlPlNvdXJjZTwvY29kZT4gaW50byBhbm90aGVyIGtpbmQgb2YKLSAgICAgKiA8Y29kZT5SZXN1bHQ8L2NvZGU+LCB1c2UgdGhlIGlkZW50aXR5IHRyYW5zZm9ybWVyIChzZWUKLSAgICAgKiB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckZhY3RvcnkjbmV3VHJhbnNmb3JtZXIoKX0pLjwvcD4KLSAgICAgKgotICAgICAqIDxwPkVycm9ycyBmb3VuZCBkdXJpbmcgdGhlIHZhbGlkYXRpb24gaXMgc2VudCB0byB0aGUgc3BlY2lmaWVkCi0gICAgICoge0BsaW5rIEVycm9ySGFuZGxlcn0uPC9wPgotICAgICAqCi0gICAgICogPHA+SWYgYSBkb2N1bWVudCBpcyB2YWxpZCwgb3IgaWYgYSBkb2N1bWVudCBjb250YWlucyBzb21lIGVycm9ycwotICAgICAqIGJ1dCBub25lIG9mIHRoZW0gd2VyZSBmYXRhbCBhbmQgdGhlIDxjb2RlPkVycm9ySGFuZGxlcjwvY29kZT4gZGlkbid0Ci0gICAgICogdGhyb3cgYW55IGV4Y2VwdGlvbiwgdGhlbiB0aGUgbWV0aG9kIHJldHVybnMgbm9ybWFsbHkuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIHNvdXJjZQotICAgICAqICAgICAgWE1MIHRvIGJlIHZhbGlkYXRlZC4gTXVzdCBiZSBhbiBYTUwgZG9jdW1lbnQgb3IKLSAgICAgKiAgICAgIFhNTCBlbGVtZW50IGFuZCBtdXN0IG5vdCBiZSBudWxsLiBGb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHksCi0gICAgICogICAgICB0aGUgcmVzdWx0cyBvZiBhdHRlbXB0aW5nIHRvIHZhbGlkYXRlIGFueXRoaW5nIG90aGVyIHRoYW4KLSAgICAgKiAgICAgIGEgZG9jdW1lbnQgb3IgZWxlbWVudCBhcmUgaW1wbGVtZW50YXRpb24tZGVwZW5kZW50LgotICAgICAqICAgICAgSW1wbGVtZW50YXRpb25zIG11c3QgZWl0aGVyIHJlY29nbml6ZSBhbmQgcHJvY2VzcyB0aGUgaW5wdXQKLSAgICAgKiAgICAgIG9yIHRocm93IGFuIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSByZXN1bHQKLSAgICAgKiAgICAgIFRoZSA8Y29kZT5SZXN1bHQ8L2NvZGU+IG9iamVjdCB0aGF0IHJlY2VpdmVzIChwb3NzaWJseSBhdWdtZW50ZWQpCi0gICAgICogICAgICBYTUwuIFRoaXMgcGFyYW1ldGVyIGNhbiBiZSBudWxsIGlmIHRoZSBjYWxsZXIgaXMgbm90IGludGVyZXN0ZWQKLSAgICAgKiAgICAgIGluIGl0LgotICAgICAqCi0gICAgICogICAgICBOb3RlIHRoYXQgd2hlbiBhIDxjb2RlPkRPTVJlc3VsdDwvY29kZT4gaXMgdXNlZCwKLSAgICAgKiAgICAgIGEgdmFsaWRhdG9yIG1pZ2h0IGp1c3QgcGFzcyB0aGUgc2FtZSBET00gbm9kZSBmcm9tCi0gICAgICogICAgICA8Y29kZT5ET01Tb3VyY2U8L2NvZGU+IHRvIDxjb2RlPkRPTVJlc3VsdDwvY29kZT4KLSAgICAgKiAgICAgIChpbiB3aGljaCBjYXNlIDxjb2RlPnNvdXJjZS5nZXROb2RlKCk9PXJlc3VsdC5nZXROb2RlKCk8L2NvZGU+KSwKLSAgICAgKiAgICAgIGl0IG1pZ2h0IGNvcHkgdGhlIGVudGlyZSBET00gdHJlZSwgb3IgaXQgbWlnaHQgYWx0ZXIgdGhlCi0gICAgICogICAgICBub2RlIGdpdmVuIGJ5IHRoZSBzb3VyY2UuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgotICAgICAqICAgICAgSWYgdGhlIDxjb2RlPlJlc3VsdDwvY29kZT4gdHlwZSBkb2Vzbid0IG1hdGNoIHRoZQotICAgICAqICAgICAgPGNvZGU+U291cmNlPC9jb2RlPiB0eXBlIG9mIGlmIHRoZSA8Y29kZT5Tb3VyY2U8L2NvZGU+Ci0gICAgICogICAgICBpcyBhbiBYTUwgYXJ0aWZhY3QgdGhhdCB0aGUgaW1wbGVtZW50YXRpb24gY2Fubm90Ci0gICAgICogICAgICB2YWxpZGF0ZSAoZm9yIGV4YW1wbGUsIGEgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbikuCi0gICAgICogQHRocm93cyBTQVhFeGNlcHRpb24KLSAgICAgKiAgICAgIElmIHRoZSA8Y29kZT5FcnJvckhhbmRsZXI8L2NvZGU+IHRocm93cyBhCi0gICAgICogICAgICA8Y29kZT5TQVhFeGNlcHRpb248L2NvZGU+IG9yCi0gICAgICogICAgICBpZiBhIGZhdGFsIGVycm9yIGlzIGZvdW5kIGFuZCB0aGUgPGNvZGU+RXJyb3JIYW5kbGVyPC9jb2RlPiByZXR1cm5zCi0gICAgICogICAgICBub3JtYWxseS4KLSAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0gICAgICogICAgICBJZiB0aGUgdmFsaWRhdG9yIGlzIHByb2Nlc3NpbmcgYQotICAgICAqICAgICAgPGNvZGU+U0FYU291cmNlPC9jb2RlPiBhbmQgdGhlCi0gICAgICogICAgICB1bmRlcmx5aW5nIHtAbGluayBvcmcueG1sLnNheC5YTUxSZWFkZXJ9IHRocm93cyBhbgotICAgICAqICAgICAgPGNvZGU+SU9FeGNlcHRpb248L2NvZGU+LgotICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KLSAgICAgKiAgICAgIElmIHRoZSA8Y29kZT5zb3VyY2U8L2NvZGU+IHBhcmFtZXRlciBpcyA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICAgKgotICAgICAqIEBzZWUgI3ZhbGlkYXRlKFNvdXJjZSBzb3VyY2UpCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IHZvaWQgdmFsaWRhdGUoU291cmNlIHNvdXJjZSwgUmVzdWx0IHJlc3VsdCkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiwgSU9FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSB7QGxpbmsgRXJyb3JIYW5kbGVyfSB0byByZWNlaXZlIGVycm9ycyBlbmNvdW50ZXJlZAotICAgICAqIGR1cmluZyB0aGUgPGNvZGU+dmFsaWRhdGU8L2NvZGU+IG1ldGhvZCBpbnZvY2F0aW9uLgotICAgICAqCi0gICAgICogPHA+Ci0gICAgICogRXJyb3IgaGFuZGxlciBjYW4gYmUgdXNlZCB0byBjdXN0b21pemUgdGhlIGVycm9yIGhhbmRsaW5nIHByb2Nlc3MKLSAgICAgKiBkdXJpbmcgYSB2YWxpZGF0aW9uLiBXaGVuIGFuIHtAbGluayBFcnJvckhhbmRsZXJ9IGlzIHNldCwKLSAgICAgKiBlcnJvcnMgZm91bmQgZHVyaW5nIHRoZSB2YWxpZGF0aW9uIHdpbGwgYmUgZmlyc3Qgc2VudAotICAgICAqIHRvIHRoZSB7QGxpbmsgRXJyb3JIYW5kbGVyfS4KLSAgICAgKgotICAgICAqIDxwPgotICAgICAqIFRoZSBlcnJvciBoYW5kbGVyIGNhbiBhYm9ydCBmdXJ0aGVyIHZhbGlkYXRpb24gaW1tZWRpYXRlbHkKLSAgICAgKiBieSB0aHJvd2luZyB7QGxpbmsgU0FYRXhjZXB0aW9ufSBmcm9tIHRoZSBoYW5kbGVyLiBPciBmb3IgZXhhbXBsZQotICAgICAqIGl0IGNhbiBwcmludCBhbiBlcnJvciB0byB0aGUgc2NyZWVuIGFuZCB0cnkgdG8gY29udGludWUgdGhlCi0gICAgICogdmFsaWRhdGlvbiBieSByZXR1cm5pbmcgbm9ybWFsbHkgZnJvbSB0aGUge0BsaW5rIEVycm9ySGFuZGxlcn0KLSAgICAgKgotICAgICAqIDxwPgotICAgICAqIElmIGFueSB7QGxpbmsgVGhyb3dhYmxlfSBpcyB0aHJvd24gZnJvbSBhbiB7QGxpbmsgRXJyb3JIYW5kbGVyfSwKLSAgICAgKiB0aGUgY2FsbGVyIG9mIHRoZSA8Y29kZT52YWxpZGF0ZTwvY29kZT4gbWV0aG9kIHdpbGwgYmUgdGhyb3duCi0gICAgICogdGhlIHNhbWUge0BsaW5rIFRocm93YWJsZX0gb2JqZWN0LgotICAgICAqCi0gICAgICogPHA+Ci0gICAgICoge0BsaW5rIFZhbGlkYXRvcn0gaXMgbm90IGFsbG93ZWQgdG8KLSAgICAgKiB0aHJvdyB7QGxpbmsgU0FYRXhjZXB0aW9ufSB3aXRob3V0IGZpcnN0IHJlcG9ydGluZyBpdCB0bwotICAgICAqIHtAbGluayBFcnJvckhhbmRsZXJ9LgotICAgICAqCi0gICAgICogPHA+Ci0gICAgICogV2hlbiB0aGUge0BsaW5rIEVycm9ySGFuZGxlcn0gaXMgbnVsbCwgdGhlIGltcGxlbWVudGF0aW9uIHdpbGwKLSAgICAgKiBiZWhhdmUgYXMgaWYgdGhlIGZvbGxvd2luZyB7QGxpbmsgRXJyb3JIYW5kbGVyfSBpcyBzZXQ6Ci0gICAgICogPHByZT4KLSAgICAgKiBjbGFzcyBEcmFjb25pYW5FcnJvckhhbmRsZXIgaW1wbGVtZW50cyB7QGxpbmsgRXJyb3JIYW5kbGVyfSB7Ci0gICAgICogICAgIHB1YmxpYyB2b2lkIGZhdGFsRXJyb3IoIHtAbGluayBvcmcueG1sLnNheC5TQVhQYXJzZUV4Y2VwdGlvbn0gZSApIHRocm93cyB7QGxpbmsgU0FYRXhjZXB0aW9ufSB7Ci0gICAgICogICAgICAgICB0aHJvdyBlOwotICAgICAqICAgICB9Ci0gICAgICogICAgIHB1YmxpYyB2b2lkIGVycm9yKCB7QGxpbmsgb3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb259IGUgKSB0aHJvd3Mge0BsaW5rIFNBWEV4Y2VwdGlvbn0gewotICAgICAqICAgICAgICAgdGhyb3cgZTsKLSAgICAgKiAgICAgfQotICAgICAqICAgICBwdWJsaWMgdm9pZCB3YXJuaW5nKCB7QGxpbmsgb3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb259IGUgKSB0aHJvd3Mge0BsaW5rIFNBWEV4Y2VwdGlvbn0gewotICAgICAqICAgICAgICAgLy8gbm9vcAotICAgICAqICAgICB9Ci0gICAgICogfQotICAgICAqIDwvcHJlPgotICAgICAqCi0gICAgICogPHA+Ci0gICAgICogV2hlbiBhIG5ldyB7QGxpbmsgVmFsaWRhdG9yfSBvYmplY3QgaXMgY3JlYXRlZCwgaW5pdGlhbGx5Ci0gICAgICogdGhpcyBmaWVsZCBpcyBzZXQgdG8gbnVsbC4KLSAgICAgKgotICAgICAqIEBwYXJhbSAgIGVycm9ySGFuZGxlcgotICAgICAqICAgICAgQSBuZXcgZXJyb3IgaGFuZGxlciB0byBiZSBzZXQuIFRoaXMgcGFyYW1ldGVyIGNhbiBiZSBudWxsLgotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHNldEVycm9ySGFuZGxlcihFcnJvckhhbmRsZXIgZXJyb3JIYW5kbGVyKTsKLQotICAgIC8qKgotICAgICAqIEdldHMgdGhlIGN1cnJlbnQge0BsaW5rIEVycm9ySGFuZGxlcn0gc2V0IHRvIHRoaXMge0BsaW5rIFZhbGlkYXRvcn0uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuCi0gICAgICogICAgICBUaGlzIG1ldGhvZCByZXR1cm5zIHRoZSBvYmplY3QgdGhhdCB3YXMgbGFzdCBzZXQgdGhyb3VnaAotICAgICAqICAgICAgdGhlIHtAbGluayAjc2V0RXJyb3JIYW5kbGVyKEVycm9ySGFuZGxlcil9IG1ldGhvZCwgb3IgbnVsbAotICAgICAqICAgICAgaWYgdGhhdCBtZXRob2QgaGFzIG5ldmVyIGJlZW4gY2FsbGVkIHNpbmNlIHRoaXMge0BsaW5rIFZhbGlkYXRvcn0KLSAgICAgKiAgICAgIGhhcyBjcmVhdGVkLgotICAgICAqCi0gICAgICogQHNlZSAjc2V0RXJyb3JIYW5kbGVyKEVycm9ySGFuZGxlcikKLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3QgRXJyb3JIYW5kbGVyIGdldEVycm9ySGFuZGxlcigpOwotCi0gICAgLyoqCi0gICAgICogU2V0cyB0aGUge0BsaW5rIExTUmVzb3VyY2VSZXNvbHZlcn0gdG8gY3VzdG9taXplCi0gICAgICogcmVzb3VyY2UgcmVzb2x1dGlvbiB3aGlsZSBpbiBhIHZhbGlkYXRpb24gZXBpc29kZS4KLSAgICAgKgotICAgICAqIDxwPgotICAgICAqIHtAbGluayBWYWxpZGF0b3J9IHVzZXMgYSB7QGxpbmsgTFNSZXNvdXJjZVJlc29sdmVyfQotICAgICAqIHdoZW4gaXQgbmVlZHMgdG8gbG9jYXRlIGV4dGVybmFsIHJlc291cmNlcyB3aGlsZSBhIHZhbGlkYXRpb24sCi0gICAgICogYWx0aG91Z2ggZXhhY3RseSB3aGF0IGNvbnN0aXR1dGVzICJsb2NhdGluZyBleHRlcm5hbCByZXNvdXJjZXMiIGlzCi0gICAgICogdXAgdG8gZWFjaCBzY2hlbWEgbGFuZ3VhZ2UuCi0gICAgICoKLSAgICAgKiA8cD4KLSAgICAgKiBXaGVuIHRoZSB7QGxpbmsgTFNSZXNvdXJjZVJlc29sdmVyfSBpcyBudWxsLCB0aGUgaW1wbGVtZW50YXRpb24gd2lsbAotICAgICAqIGJlaGF2ZSBhcyBpZiB0aGUgZm9sbG93aW5nIHtAbGluayBMU1Jlc291cmNlUmVzb2x2ZXJ9IGlzIHNldDoKLSAgICAgKiA8cHJlPgotICAgICAqIGNsYXNzIER1bWJMU1Jlc291cmNlUmVzb2x2ZXIgaW1wbGVtZW50cyB7QGxpbmsgTFNSZXNvdXJjZVJlc29sdmVyfSB7Ci0gICAgICogICAgIHB1YmxpYyB7QGxpbmsgb3JnLnczYy5kb20ubHMuTFNJbnB1dH0gcmVzb2x2ZVJlc291cmNlKAotICAgICAqICAgICAgICAgU3RyaW5nIHB1YmxpY0lkLCBTdHJpbmcgc3lzdGVtSWQsIFN0cmluZyBiYXNlVVJJKSB7Ci0gICAgICoKLSAgICAgKiAgICAgICAgIHJldHVybiBudWxsOyAvLyBhbHdheXMgcmV0dXJuIG51bGwKLSAgICAgKiAgICAgfQotICAgICAqIH0KLSAgICAgKiA8L3ByZT4KLSAgICAgKgotICAgICAqIDxwPgotICAgICAqIElmIGEge0BsaW5rIExTUmVzb3VyY2VSZXNvbHZlcn0gdGhyb3dzIGEge0BsaW5rIFJ1bnRpbWVFeGNlcHRpb259Ci0gICAgICogIChvciBpbnN0YW5jZXMgb2YgaXRzIGRlcml2ZWQgY2xhc3NlcyksCi0gICAgICogdGhlbiB0aGUge0BsaW5rIFZhbGlkYXRvcn0gd2lsbCBhYm9ydCB0aGUgcGFyc2luZyBhbmQKLSAgICAgKiB0aGUgY2FsbGVyIG9mIHRoZSA8Y29kZT52YWxpZGF0ZTwvY29kZT4gbWV0aG9kIHdpbGwgcmVjZWl2ZQotICAgICAqIHRoZSBzYW1lIHtAbGluayBSdW50aW1lRXhjZXB0aW9ufS4KLSAgICAgKgotICAgICAqIDxwPgotICAgICAqIFdoZW4gYSBuZXcge0BsaW5rIFZhbGlkYXRvcn0gb2JqZWN0IGlzIGNyZWF0ZWQsIGluaXRpYWxseQotICAgICAqIHRoaXMgZmllbGQgaXMgc2V0IHRvIG51bGwuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gICByZXNvdXJjZVJlc29sdmVyCi0gICAgICogICAgICBBIG5ldyByZXNvdXJjZSByZXNvbHZlciB0byBiZSBzZXQuIFRoaXMgcGFyYW1ldGVyIGNhbiBiZSBudWxsLgotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHNldFJlc291cmNlUmVzb2x2ZXIoTFNSZXNvdXJjZVJlc29sdmVyIHJlc291cmNlUmVzb2x2ZXIpOwotCi0gICAgLyoqCi0gICAgICogR2V0cyB0aGUgY3VycmVudCB7QGxpbmsgTFNSZXNvdXJjZVJlc29sdmVyfSBzZXQgdG8gdGhpcyB7QGxpbmsgVmFsaWRhdG9yfS4KLSAgICAgKgotICAgICAqIEByZXR1cm4KLSAgICAgKiAgICAgIFRoaXMgbWV0aG9kIHJldHVybnMgdGhlIG9iamVjdCB0aGF0IHdhcyBsYXN0IHNldCB0aHJvdWdoCi0gICAgICogICAgICB0aGUge0BsaW5rICNzZXRSZXNvdXJjZVJlc29sdmVyKExTUmVzb3VyY2VSZXNvbHZlcil9IG1ldGhvZCwgb3IgbnVsbAotICAgICAqICAgICAgaWYgdGhhdCBtZXRob2QgaGFzIG5ldmVyIGJlZW4gY2FsbGVkIHNpbmNlIHRoaXMge0BsaW5rIFZhbGlkYXRvcn0KLSAgICAgKiAgICAgIGhhcyBjcmVhdGVkLgotICAgICAqCi0gICAgICogQHNlZSAjc2V0RXJyb3JIYW5kbGVyKEVycm9ySGFuZGxlcikKLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3QgTFNSZXNvdXJjZVJlc29sdmVyIGdldFJlc291cmNlUmVzb2x2ZXIoKTsKLQotCi0KLSAgICAvKioKLSAgICAgKiBMb29rIHVwIHRoZSB2YWx1ZSBvZiBhIGZlYXR1cmUgZmxhZy4KLSAgICAgKgotICAgICAqIDxwPlRoZSBmZWF0dXJlIG5hbWUgaXMgYW55IGZ1bGx5LXF1YWxpZmllZCBVUkkuICBJdCBpcwotICAgICAqIHBvc3NpYmxlIGZvciBhIHtAbGluayBWYWxpZGF0b3J9IHRvIHJlY29nbml6ZSBhIGZlYXR1cmUgbmFtZSBidXQKLSAgICAgKiB0ZW1wb3JhcmlseSBiZSB1bmFibGUgdG8gcmV0dXJuIGl0cyB2YWx1ZS4KLSAgICAgKiBTb21lIGZlYXR1cmUgdmFsdWVzIG1heSBiZSBhdmFpbGFibGUgb25seSBpbiBzcGVjaWZpYwotICAgICAqIGNvbnRleHRzLCBzdWNoIGFzIGJlZm9yZSwgZHVyaW5nLCBvciBhZnRlciBhIHZhbGlkYXRpb24uCi0gICAgICoKLSAgICAgKiA8cD5JbXBsZW1lbnRvcnMgYXJlIGZyZWUgKGFuZCBlbmNvdXJhZ2VkKSB0byBpbnZlbnQgdGhlaXIgb3duIGZlYXR1cmVzLAotICAgICAqIHVzaW5nIG5hbWVzIGJ1aWx0IG9uIHRoZWlyIG93biBVUklzLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBmZWF0dXJlIG5hbWUsIHdoaWNoIGlzIGEgbm9uLW51bGwgZnVsbHktcXVhbGlmaWVkIFVSSS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIGN1cnJlbnQgdmFsdWUgb2YgdGhlIGZlYXR1cmUgKHRydWUgb3IgZmFsc2UpLgotICAgICAqCi0gICAgICogQHRocm93cyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIElmIHRoZSBmZWF0dXJlCi0gICAgICogICB2YWx1ZSBjYW4ndCBiZSBhc3NpZ25lZCBvciByZXRyaWV2ZWQuCi0gICAgICogQHRocm93cyBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gV2hlbiB0aGUKLSAgICAgKiAgIHtAbGluayBWYWxpZGF0b3J9IHJlY29nbml6ZXMgdGhlIGZlYXR1cmUgbmFtZSBidXQKLSAgICAgKiAgIGNhbm5vdCBkZXRlcm1pbmUgaXRzIHZhbHVlIGF0IHRoaXMgdGltZS4KLSAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCi0gICAgICogICBXaGVuIHRoZSBuYW1lIHBhcmFtZXRlciBpcyBudWxsLgotICAgICAqCi0gICAgICogQHNlZSAjc2V0RmVhdHVyZShTdHJpbmcsIGJvb2xlYW4pCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0RmVhdHVyZShTdHJpbmcgbmFtZSkKLSAgICAgICAgdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgaWYgKG5hbWUgPT0gbnVsbCkgewotICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJ0aGUgbmFtZSBwYXJhbWV0ZXIgaXMgbnVsbCIpOwotICAgICAgICB9Ci0KLSAgICAgICAgdGhyb3cgbmV3IFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24obmFtZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSB2YWx1ZSBvZiBhIGZlYXR1cmUgZmxhZy4KLSAgICAgKgotICAgICAqIDxwPgotICAgICAqIEZlYXR1cmUgY2FuIGJlIHVzZWQgdG8gY29udHJvbCB0aGUgd2F5IGEge0BsaW5rIFZhbGlkYXRvcn0KLSAgICAgKiBwYXJzZXMgc2NoZW1hcywgYWx0aG91Z2gge0BsaW5rIFZhbGlkYXRvcn1zIGFyZSBub3QgcmVxdWlyZWQKLSAgICAgKiB0byByZWNvZ25pemUgYW55IHNwZWNpZmljIGZlYXR1cmUgbmFtZXMuPC9wPgotICAgICAqCi0gICAgICogPHA+VGhlIGZlYXR1cmUgbmFtZSBpcyBhbnkgZnVsbHktcXVhbGlmaWVkIFVSSS4gIEl0IGlzCi0gICAgICogcG9zc2libGUgZm9yIGEge0BsaW5rIFZhbGlkYXRvcn0gdG8gZXhwb3NlIGEgZmVhdHVyZSB2YWx1ZSBidXQKLSAgICAgKiB0byBiZSB1bmFibGUgdG8gY2hhbmdlIHRoZSBjdXJyZW50IHZhbHVlLgotICAgICAqIFNvbWUgZmVhdHVyZSB2YWx1ZXMgbWF5IGJlIGltbXV0YWJsZSBvciBtdXRhYmxlIG9ubHkKLSAgICAgKiBpbiBzcGVjaWZpYyBjb250ZXh0cywgc3VjaCBhcyBiZWZvcmUsIGR1cmluZywgb3IgYWZ0ZXIKLSAgICAgKiBhIHZhbGlkYXRpb24uPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgVGhlIGZlYXR1cmUgbmFtZSwgd2hpY2ggaXMgYSBub24tbnVsbCBmdWxseS1xdWFsaWZpZWQgVVJJLgotICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVxdWVzdGVkIHZhbHVlIG9mIHRoZSBmZWF0dXJlICh0cnVlIG9yIGZhbHNlKS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiBJZiB0aGUgZmVhdHVyZQotICAgICAqICAgdmFsdWUgY2FuJ3QgYmUgYXNzaWduZWQgb3IgcmV0cmlldmVkLgotICAgICAqIEB0aHJvd3MgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIFdoZW4gdGhlCi0gICAgICogICB7QGxpbmsgVmFsaWRhdG9yfSByZWNvZ25pemVzIHRoZSBmZWF0dXJlIG5hbWUgYnV0Ci0gICAgICogICBjYW5ub3Qgc2V0IHRoZSByZXF1ZXN0ZWQgdmFsdWUuCi0gICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgotICAgICAqICAgV2hlbiB0aGUgbmFtZSBwYXJhbWV0ZXIgaXMgbnVsbC4KLSAgICAgKgotICAgICAqIEBzZWUgI2dldEZlYXR1cmUoU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEZlYXR1cmUoU3RyaW5nIG5hbWUsIGJvb2xlYW4gdmFsdWUpCi0gICAgICAgIHRocm93cyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uLCBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gewotCi0gICAgICAgIGlmIChuYW1lID09IG51bGwpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigidGhlIG5hbWUgcGFyYW1ldGVyIGlzIG51bGwiKTsKLSAgICAgICAgfQotCi0gICAgICAgIHRocm93IG5ldyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uKG5hbWUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldCB0aGUgdmFsdWUgb2YgYSBwcm9wZXJ0eS4KLSAgICAgKgotICAgICAqIDxwPlRoZSBwcm9wZXJ0eSBuYW1lIGlzIGFueSBmdWxseS1xdWFsaWZpZWQgVVJJLiAgSXQgaXMKLSAgICAgKiBwb3NzaWJsZSBmb3IgYSB7QGxpbmsgVmFsaWRhdG9yfSB0byByZWNvZ25pemUgYSBwcm9wZXJ0eSBuYW1lIGJ1dAotICAgICAqIHRvIGJlIHVuYWJsZSB0byBjaGFuZ2UgdGhlIGN1cnJlbnQgdmFsdWUuCi0gICAgICogU29tZSBwcm9wZXJ0eSB2YWx1ZXMgbWF5IGJlIGltbXV0YWJsZSBvciBtdXRhYmxlIG9ubHkKLSAgICAgKiBpbiBzcGVjaWZpYyBjb250ZXh0cywgc3VjaCBhcyBiZWZvcmUsIGR1cmluZywgb3IgYWZ0ZXIKLSAgICAgKiBhIHZhbGlkYXRpb24uPC9wPgotICAgICAqCi0gICAgICogPHA+Ci0gICAgICogQWxsIGltcGxlbWVudGF0aW9ucyB0aGF0IGltcGxlbWVudCBKQVhQIDEuNSBvciBuZXdlciBhcmUgcmVxdWlyZWQgdG8KLSAgICAgKiBzdXBwb3J0IHRoZSB7QGxpbmsgamF2YXgueG1sLlhNTENvbnN0YW50cyNBQ0NFU1NfRVhURVJOQUxfRFREfSBhbmQKLSAgICAgKiB7QGxpbmsgamF2YXgueG1sLlhNTENvbnN0YW50cyNBQ0NFU1NfRVhURVJOQUxfU0NIRU1BfSBwcm9wZXJ0aWVzLgotICAgICAqIDwvcD4KLSAgICAgKiA8dWw+Ci0gICAgICogICA8bGk+Ci0gICAgICogICAgICA8cD5BY2Nlc3MgdG8gZXh0ZXJuYWwgRFREcyBpbiBzb3VyY2Ugb3IgU2NoZW1hIGZpbGUgaXMgcmVzdHJpY3RlZCB0bwotICAgICAqICAgICAgdGhlIHByb3RvY29scyBzcGVjaWZpZWQgYnkgdGhlIHtAbGluayBqYXZheC54bWwuWE1MQ29uc3RhbnRzI0FDQ0VTU19FWFRFUk5BTF9EVER9Ci0gICAgICogICAgICBwcm9wZXJ0eS4gIElmIGFjY2VzcyBpcyBkZW5pZWQgZHVyaW5nIHZhbGlkYXRpb24gZHVlIHRvIHRoZSByZXN0cmljdGlvbgotICAgICAqICAgICAgb2YgdGhpcyBwcm9wZXJ0eSwge0BsaW5rIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbn0gd2lsbCBiZSB0aHJvd24gYnkgdGhlCi0gICAgICogICAgICB7QGxpbmsgI3ZhbGlkYXRlKFNvdXJjZSl9IG1ldGhvZC48L3A+Ci0gICAgICoKLSAgICAgKiAgICAgIDxwPkFjY2VzcyB0byBleHRlcm5hbCByZWZlcmVuY2Ugc2V0IGJ5IHRoZSBzY2hlbWFMb2NhdGlvbiBhdHRyaWJ1dGUgaXMKLSAgICAgKiAgICAgIHJlc3RyaWN0ZWQgdG8gdGhlIHByb3RvY29scyBzcGVjaWZpZWQgYnkgdGhlCi0gICAgICogICAgICB7QGxpbmsgamF2YXgueG1sLlhNTENvbnN0YW50cyNBQ0NFU1NfRVhURVJOQUxfU0NIRU1BfSBwcm9wZXJ0eS4KLSAgICAgKiAgICAgIElmIGFjY2VzcyBpcyBkZW5pZWQgZHVyaW5nIHZhbGlkYXRpb24gZHVlIHRvIHRoZSByZXN0cmljdGlvbiBvZiB0aGlzIHByb3BlcnR5LAotICAgICAqICAgICAge0BsaW5rIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbn0gd2lsbCBiZSB0aHJvd24gYnkgdGhlCi0gICAgICogICAgICB7QGxpbmsgI3ZhbGlkYXRlKFNvdXJjZSl9IG1ldGhvZC48L3A+Ci0gICAgICogICA8L2xpPgotICAgICAqIDwvdWw+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgcHJvcGVydHkgbmFtZSwgd2hpY2ggaXMgYSBub24tbnVsbCBmdWxseS1xdWFsaWZpZWQgVVJJLgotICAgICAqIEBwYXJhbSBvYmplY3QgVGhlIHJlcXVlc3RlZCB2YWx1ZSBmb3IgdGhlIHByb3BlcnR5LgotICAgICAqCi0gICAgICogQHRocm93cyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIElmIHRoZSBwcm9wZXJ0eQotICAgICAqICAgdmFsdWUgY2FuJ3QgYmUgYXNzaWduZWQgb3IgcmV0cmlldmVkLgotICAgICAqIEB0aHJvd3MgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIFdoZW4gdGhlCi0gICAgICogICB7QGxpbmsgVmFsaWRhdG9yfSByZWNvZ25pemVzIHRoZSBwcm9wZXJ0eSBuYW1lIGJ1dAotICAgICAqICAgY2Fubm90IHNldCB0aGUgcmVxdWVzdGVkIHZhbHVlLgotICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KLSAgICAgKiAgIFdoZW4gdGhlIG5hbWUgcGFyYW1ldGVyIGlzIG51bGwuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0UHJvcGVydHkoU3RyaW5nIG5hbWUsIE9iamVjdCBvYmplY3QpCi0gICAgICAgIHRocm93cyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uLCBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gewotCi0gICAgICAgIGlmIChuYW1lID09IG51bGwpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigidGhlIG5hbWUgcGFyYW1ldGVyIGlzIG51bGwiKTsKLSAgICAgICAgfQotCi0gICAgICAgIHRocm93IG5ldyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uKG5hbWUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIExvb2sgdXAgdGhlIHZhbHVlIG9mIGEgcHJvcGVydHkuCi0gICAgICoKLSAgICAgKiA8cD5UaGUgcHJvcGVydHkgbmFtZSBpcyBhbnkgZnVsbHktcXVhbGlmaWVkIFVSSS4gIEl0IGlzCi0gICAgICogcG9zc2libGUgZm9yIGEge0BsaW5rIFZhbGlkYXRvcn0gdG8gcmVjb2duaXplIGEgcHJvcGVydHkgbmFtZSBidXQKLSAgICAgKiB0ZW1wb3JhcmlseSBiZSB1bmFibGUgdG8gcmV0dXJuIGl0cyB2YWx1ZS4KLSAgICAgKiBTb21lIHByb3BlcnR5IHZhbHVlcyBtYXkgYmUgYXZhaWxhYmxlIG9ubHkgaW4gc3BlY2lmaWMKLSAgICAgKiBjb250ZXh0cywgc3VjaCBhcyBiZWZvcmUsIGR1cmluZywgb3IgYWZ0ZXIgYSB2YWxpZGF0aW9uLjwvcD4KLSAgICAgKgotICAgICAqIDxwPntAbGluayBWYWxpZGF0b3J9cyBhcmUgbm90IHJlcXVpcmVkIHRvIHJlY29nbml6ZSBhbnkgc3BlY2lmaWMKLSAgICAgKiBwcm9wZXJ0eSBuYW1lcy48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5JbXBsZW1lbnRvcnMgYXJlIGZyZWUgKGFuZCBlbmNvdXJhZ2VkKSB0byBpbnZlbnQgdGhlaXIgb3duIHByb3BlcnRpZXMsCi0gICAgICogdXNpbmcgbmFtZXMgYnVpbHQgb24gdGhlaXIgb3duIFVSSXMuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgVGhlIHByb3BlcnR5IG5hbWUsIHdoaWNoIGlzIGEgbm9uLW51bGwgZnVsbHktcXVhbGlmaWVkIFVSSS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIGN1cnJlbnQgdmFsdWUgb2YgdGhlIHByb3BlcnR5LgotICAgICAqCi0gICAgICogQHRocm93cyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIElmIHRoZSBwcm9wZXJ0eQotICAgICAqICAgdmFsdWUgY2FuJ3QgYmUgYXNzaWduZWQgb3IgcmV0cmlldmVkLgotICAgICAqIEB0aHJvd3MgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIFdoZW4gdGhlCi0gICAgICogICBYTUxSZWFkZXIgcmVjb2duaXplcyB0aGUgcHJvcGVydHkgbmFtZSBidXQKLSAgICAgKiAgIGNhbm5vdCBkZXRlcm1pbmUgaXRzIHZhbHVlIGF0IHRoaXMgdGltZS4KLSAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCi0gICAgICogICBXaGVuIHRoZSBuYW1lIHBhcmFtZXRlciBpcyBudWxsLgotICAgICAqCi0gICAgICogQHNlZSAjc2V0UHJvcGVydHkoU3RyaW5nLCBPYmplY3QpCi0gICAgICovCi0gICAgcHVibGljIE9iamVjdCBnZXRQcm9wZXJ0eShTdHJpbmcgbmFtZSkKLSAgICAgICAgdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgaWYgKG5hbWUgPT0gbnVsbCkgewotICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJ0aGUgbmFtZSBwYXJhbWV0ZXIgaXMgbnVsbCIpOwotICAgICAgICB9Ci0KLSAgICAgICAgdGhyb3cgbmV3IFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24obmFtZSk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmF4L3htbC92YWxpZGF0aW9uL1ZhbGlkYXRvckhhbmRsZXIuamF2YSBiL3NyYy9qYXZheC94bWwvdmFsaWRhdGlvbi9WYWxpZGF0b3JIYW5kbGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDJhYTJjYzEuLjAwMDAwMDAKLS0tIGEvc3JjL2phdmF4L3htbC92YWxpZGF0aW9uL1ZhbGlkYXRvckhhbmRsZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQ4NSArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDA1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi1wYWNrYWdlIGphdmF4LnhtbC52YWxpZGF0aW9uOwotCi1pbXBvcnQgb3JnLnczYy5kb20ubHMuTFNSZXNvdXJjZVJlc29sdmVyOwotaW1wb3J0IG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LkVycm9ySGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbjsKLQotLyoqCi0gKiBTdHJlYW1pbmcgdmFsaWRhdG9yIHRoYXQgd29ya3Mgb24gU0FYIHN0cmVhbS4KLSAqCi0gKiA8cD4KLSAqIEEge0BsaW5rIFZhbGlkYXRvckhhbmRsZXJ9IG9iamVjdCBpcyBub3QgdGhyZWFkLXNhZmUgYW5kIG5vdCByZWVudHJhbnQuCi0gKiBJbiBvdGhlciB3b3JkcywgaXQgaXMgdGhlIGFwcGxpY2F0aW9uJ3MgcmVzcG9uc2liaWxpdHkgdG8gbWFrZQotICogc3VyZSB0aGF0IG9uZSB7QGxpbmsgVmFsaWRhdG9ySGFuZGxlcn0gb2JqZWN0IGlzIG5vdCB1c2VkIGZyb20KLSAqIG1vcmUgdGhhbiBvbmUgdGhyZWFkIGF0IGFueSBnaXZlbiB0aW1lLgotICoKLSAqIDxwPgotICoge0BsaW5rIFZhbGlkYXRvckhhbmRsZXJ9IGNoZWNrcyBpZiB0aGUgU0FYIGV2ZW50cyBmb2xsb3cKLSAqIHRoZSBzZXQgb2YgY29uc3RyYWludHMgZGVzY3JpYmVkIGluIHRoZSBhc3NvY2lhdGVkIHtAbGluayBTY2hlbWF9LAotICogYW5kIGFkZGl0aW9uYWxseSBpdCBtYXkgbW9kaWZ5IHRoZSBTQVggZXZlbnRzIChmb3IgZXhhbXBsZQotICogYnkgYWRkaW5nIGRlZmF1bHQgdmFsdWVzLCBldGMuKQotICoKLSAqIDxwPgotICoge0BsaW5rIFZhbGlkYXRvckhhbmRsZXJ9IGV4dGVuZHMgZnJvbSB7QGxpbmsgQ29udGVudEhhbmRsZXJ9LAotICogYnV0IGl0IHJlZmluZXMgdGhlIHVuZGVybHlpbmcge0BsaW5rIENvbnRlbnRIYW5kbGVyfSBpbgotICogdGhlIGZvbGxvd2luZyB3YXk6Ci0gKiA8b2w+Ci0gKiAgPGxpPnN0YXJ0RWxlbWVudC9lbmRFbGVtZW50IGV2ZW50cyBtdXN0IHJlY2VpdmUgbm9uLW51bGwgU3RyaW5nCi0gKiAgICAgIGZvciA8Y29kZT51cmk8L2NvZGU+LCA8Y29kZT5sb2NhbE5hbWU8L2NvZGU+LCBhbmQgPGNvZGU+cW5hbWU8L2NvZGU+LAotICogICAgICBldmVuIHRob3VnaCBTQVggYWxsb3dzIHNvbWUgb2YgdGhlbSB0byBiZSBudWxsLgotICogICAgICBTaW1pbGFybHksIHRoZSB1c2VyLXNwZWNpZmllZCB7QGxpbmsgQ29udGVudEhhbmRsZXJ9IHdpbGwgcmVjZWl2ZSBub24tbnVsbAotICogICAgICBTdHJpbmdzIGZvciBhbGwgdGhyZWUgcGFyYW1ldGVycy4KLSAqCi0gKiAgPGxpPkFwcGxpY2F0aW9ucyBtdXN0IGVuc3VyZSB0aGF0IHtAbGluayBWYWxpZGF0b3JIYW5kbGVyfSdzCi0gKiAgICAgIHtAbGluayBDb250ZW50SGFuZGxlciNzdGFydFByZWZpeE1hcHBpbmcoU3RyaW5nLFN0cmluZyl9IGFuZAotICogICAgICB7QGxpbmsgQ29udGVudEhhbmRsZXIjZW5kUHJlZml4TWFwcGluZyhTdHJpbmcpfSBhcmUgaW52b2tlZAotICogICAgICBwcm9wZXJseS4gU2ltaWxhcmx5LCB0aGUgdXNlci1zcGVjaWZpZWQge0BsaW5rIENvbnRlbnRIYW5kbGVyfQotICogICAgICB3aWxsIHJlY2VpdmUgc3RhcnRQcmVmaXhNYXBwaW5nL2VuZFByZWZpeE1hcHBpbmcgZXZlbnRzLgotICogICAgICBJZiB0aGUge0BsaW5rIFZhbGlkYXRvckhhbmRsZXJ9IGludHJvZHVjZXMgYWRkaXRpb25hbCBuYW1lc3BhY2UKLSAqICAgICAgYmluZGluZ3MsIHRoZSB1c2VyLXNwZWNpZmllZCB7QGxpbmsgQ29udGVudEhhbmRsZXJ9IHdpbGwgcmVjZWl2ZQotICogICAgICBhZGRpdGlvbmFsIHN0YXJ0UHJlZml4TWFwcGluZy9lbmRQcmVmaXhNYXBwaW5nIGV2ZW50cy4KLSAqCi0gKiAgPGxpPntAbGluayBvcmcueG1sLnNheC5BdHRyaWJ1dGVzfSBmb3IgdGhlCi0gKiAgICAgIHtAbGluayBDb250ZW50SGFuZGxlciNzdGFydEVsZW1lbnQoU3RyaW5nLFN0cmluZyxTdHJpbmcsQXR0cmlidXRlcyl9IG1ldGhvZAotICogICAgICBtYXkgb3IgbWF5IG5vdCBpbmNsdWRlIHhtbG5zKiBhdHRyaWJ1dGVzLgotICogPC9vbD4KLSAqCi0gKiA8cD4KLSAqIEEge0BsaW5rIFZhbGlkYXRvckhhbmRsZXJ9IGlzIGF1dG9tYXRpY2FsbHkgcmVzZXQgZXZlcnkgdGltZQotICogdGhlIHN0YXJ0RG9jdW1lbnQgbWV0aG9kIGlzIGludm9rZWQuCi0gKgotICogPGgyPlJlY29nbml6ZWQgUHJvcGVydGllcyBhbmQgRmVhdHVyZXM8L2gyPgotICogPHA+Ci0gKiBUaGlzIHNwZWMgZGVmaW5lcyB0aGUgZm9sbG93aW5nIGZlYXR1cmUgdGhhdCBtdXN0IGJlIHJlY29nbml6ZWQKLSAqIGJ5IGFsbCB7QGxpbmsgVmFsaWRhdG9ySGFuZGxlcn0gaW1wbGVtZW50YXRpb25zLgotICoKLSAqIDxoMz48Y29kZT5odHRwOi8veG1sLm9yZy9zYXgvZmVhdHVyZXMvbmFtZXNwYWNlLXByZWZpeGVzPC9jb2RlPjwvaDM+Ci0gKiA8cD4KLSAqIFRoaXMgZmVhdHVyZSBjb250cm9scyBob3cgYSB7QGxpbmsgVmFsaWRhdG9ySGFuZGxlcn0gaW50cm9kdWNlcwotICogbmFtZXNwYWNlIGJpbmRpbmdzIHRoYXQgd2VyZSBub3QgcHJlc2VudCBpbiB0aGUgb3JpZ2luYWwgU0FYIGV2ZW50Ci0gKiBzdHJlYW0uCi0gKiBXaGVuIHRoaXMgZmVhdHVyZSBpcyBzZXQgdG8gdHJ1ZSwgaXQgbXVzdCBtYWtlCi0gKiBzdXJlIHRoYXQgdGhlIHVzZXIncyB7QGxpbmsgQ29udGVudEhhbmRsZXJ9IHdpbGwgc2VlCi0gKiB0aGUgY29ycmVzcG9uZGluZyA8Y29kZT54bWxucyo8L2NvZGU+IGF0dHJpYnV0ZSBpbgotICogdGhlIHtAbGluayBvcmcueG1sLnNheC5BdHRyaWJ1dGVzfSBvYmplY3Qgb2YgdGhlCi0gKiB7QGxpbmsgQ29udGVudEhhbmRsZXIjc3RhcnRFbGVtZW50KFN0cmluZyxTdHJpbmcsU3RyaW5nLEF0dHJpYnV0ZXMpfQotICogY2FsbGJhY2suIE90aGVyd2lzZSwgPGNvZGU+eG1sbnMqPC9jb2RlPiBhdHRyaWJ1dGVzIG11c3Qgbm90IGJlCi0gKiBhZGRlZCB0byB7QGxpbmsgb3JnLnhtbC5zYXguQXR0cmlidXRlc30gdGhhdCdzIHBhc3NlZCB0byB0aGUKLSAqIHVzZXItc3BlY2lmaWVkIHtAbGluayBDb250ZW50SGFuZGxlcn0uCi0gKiA8cD4KLSAqIChOb3RlIHRoYXQgcmVnYXJkbGVzcyBvZiB0aGlzIHN3aXRjaCwgbmFtZXNwYWNlIGJpbmRpbmdzIGFyZQotICogYWx3YXlzIG5vdGlmaWVkIHRvIGFwcGxpY2F0aW9ucyB0aHJvdWdoCi0gKiB7QGxpbmsgQ29udGVudEhhbmRsZXIjc3RhcnRQcmVmaXhNYXBwaW5nKFN0cmluZyxTdHJpbmcpfSBhbmQKLSAqIHtAbGluayBDb250ZW50SGFuZGxlciNlbmRQcmVmaXhNYXBwaW5nKFN0cmluZyl9IG1ldGhvZHMgb2YgdGhlCi0gKiB7QGxpbmsgQ29udGVudEhhbmRsZXJ9IHNwZWNpZmllZCBieSB0aGUgdXNlci4pCi0gKgotICogPHA+Ci0gKiBOb3RlIHRoYXQgdGhpcyBmZWF0dXJlIGRvZXMgPGVtPk5PVDwvZW0+IGFmZmVjdCB0aGUgd2F5Ci0gKiBhIHtAbGluayBWYWxpZGF0b3JIYW5kbGVyfSByZWNlaXZlcyBTQVggZXZlbnRzLiBJdCBtZXJlbHkKLSAqIGNoYW5nZXMgdGhlIHdheSBpdCBhdWdtZW50cyBTQVggZXZlbnRzLgotICoKLSAqIDxwPlRoaXMgZmVhdHVyZSBpcyBzZXQgdG8gPGNvZGU+ZmFsc2U8L2NvZGU+IGJ5IGRlZmF1bHQuPC9wPgotICoKLSAqIEBhdXRob3IgIDxhIGhyZWY9Im1haWx0bzpLb2hzdWtlLkthd2FndWNoaUBTdW4uY29tIj5Lb2hzdWtlIEthd2FndWNoaTwvYT4KLSAqIEBzaW5jZSAxLjUKLSAqLwotcHVibGljIGFic3RyYWN0IGNsYXNzIFZhbGlkYXRvckhhbmRsZXIgaW1wbGVtZW50cyBDb250ZW50SGFuZGxlciB7Ci0KLSAgICAvKioKLSAgICAgKiA8cD5Db25zdHJ1Y3RvciBmb3IgZGVyaXZlZCBjbGFzc2VzLjwvcD4KLSAgICAgKgotICAgICAqIDxwPlRoZSBjb25zdHJ1Y3RvciBkb2VzIG5vdGhpbmcuPC9wPgotICAgICAqCi0gICAgICogPHA+RGVyaXZlZCBjbGFzc2VzIG11c3QgY3JlYXRlIHtAbGluayBWYWxpZGF0b3JIYW5kbGVyfSBvYmplY3RzIHRoYXQgaGF2ZQotICAgICAqIDxjb2RlPm51bGw8L2NvZGU+IHtAbGluayBFcnJvckhhbmRsZXJ9IGFuZAotICAgICAqIDxjb2RlPm51bGw8L2NvZGU+IHtAbGluayBMU1Jlc291cmNlUmVzb2x2ZXJ9LjwvcD4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgVmFsaWRhdG9ySGFuZGxlcigpIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSB7QGxpbmsgQ29udGVudEhhbmRsZXJ9IHdoaWNoIHJlY2VpdmVzCi0gICAgICogdGhlIGF1Z21lbnRlZCB2YWxpZGF0aW9uIHJlc3VsdC4KLSAgICAgKgotICAgICAqIDxwPgotICAgICAqIFdoZW4gYSB7QGxpbmsgQ29udGVudEhhbmRsZXJ9IGlzIHNwZWNpZmllZCwgYQotICAgICAqIHtAbGluayBWYWxpZGF0b3JIYW5kbGVyfSB3aWxsIHdvcmsgYXMgYSBmaWx0ZXIKLSAgICAgKiBhbmQgYmFzaWNhbGx5IGNvcHkgdGhlIGluY29taW5nIGV2ZW50cyB0byB0aGUKLSAgICAgKiBzcGVjaWZpZWQge0BsaW5rIENvbnRlbnRIYW5kbGVyfS4KLSAgICAgKgotICAgICAqIDxwPgotICAgICAqIEluIGRvaW5nIHNvLCBhIHtAbGluayBWYWxpZGF0b3JIYW5kbGVyfSBtYXkgbW9kaWZ5Ci0gICAgICogdGhlIGV2ZW50cywgZm9yIGV4YW1wbGUgYnkgYWRkaW5nIGRlZmF1bHRlZCBhdHRyaWJ1dGVzLgotICAgICAqCi0gICAgICogPHA+Ci0gICAgICogQSB7QGxpbmsgVmFsaWRhdG9ySGFuZGxlcn0gbWF5IGJ1ZmZlciBldmVudHMgdG8gY2VydGFpbgotICAgICAqIGV4dGVudCwgYnV0IHRvIGFsbG93IHtAbGluayBWYWxpZGF0b3JIYW5kbGVyfSB0byBiZSB1c2VkCi0gICAgICogYnkgYSBwYXJzZXIsIHRoZSBmb2xsb3dpbmcgcmVxdWlyZW1lbnQgaGFzIHRvIGJlIG1ldC4KLSAgICAgKgotICAgICAqIDxvbD4KLSAgICAgKiAgPGxpPldoZW4KLSAgICAgKiAgICAgIHtAbGluayBDb250ZW50SGFuZGxlciNzdGFydEVsZW1lbnQoU3RyaW5nLCBTdHJpbmcsIFN0cmluZywgQXR0cmlidXRlcyl9LAotICAgICAqICAgICAge0BsaW5rIENvbnRlbnRIYW5kbGVyI2VuZEVsZW1lbnQoU3RyaW5nLCBTdHJpbmcsIFN0cmluZyl9LAotICAgICAqICAgICAge0BsaW5rIENvbnRlbnRIYW5kbGVyI3N0YXJ0RG9jdW1lbnQoKX0sIG9yCi0gICAgICogICAgICB7QGxpbmsgQ29udGVudEhhbmRsZXIjZW5kRG9jdW1lbnQoKX0KLSAgICAgKiAgICAgIGFyZSBpbnZva2VkIG9uIGEge0BsaW5rIFZhbGlkYXRvckhhbmRsZXJ9LAotICAgICAqICAgICAgdGhlIHNhbWUgbWV0aG9kIG9uIHRoZSB1c2VyLXNwZWNpZmllZCB7QGxpbmsgQ29udGVudEhhbmRsZXJ9Ci0gICAgICogICAgICBtdXN0IGJlIGludm9rZWQgZm9yIHRoZSBzYW1lIGV2ZW50IGJlZm9yZSB0aGUgY2FsbGJhY2sKLSAgICAgKiAgICAgIHJldHVybnMuCi0gICAgICogIDxsaT57QGxpbmsgVmFsaWRhdG9ySGFuZGxlcn0gbWF5IG5vdCBpbnRyb2R1Y2UgbmV3IGVsZW1lbnRzIHRoYXQKLSAgICAgKiAgICAgIHdlcmUgbm90IHByZXNlbnQgaW4gdGhlIGlucHV0LgotICAgICAqCi0gICAgICogIDxsaT57QGxpbmsgVmFsaWRhdG9ySGFuZGxlcn0gbWF5IG5vdCByZW1vdmUgYXR0cmlidXRlcyB0aGF0IHdlcmUKLSAgICAgKiAgICAgIHByZXNlbnQgaW4gdGhlIGlucHV0LgotICAgICAqIDwvb2w+Ci0gICAgICoKLSAgICAgKiA8cD4KLSAgICAgKiBXaGVuIGEgY2FsbGJhY2sgbWV0aG9kIG9uIHRoZSBzcGVjaWZpZWQge0BsaW5rIENvbnRlbnRIYW5kbGVyfQotICAgICAqIHRocm93cyBhbiBleGNlcHRpb24sIHRoZSBzYW1lIGV4Y2VwdGlvbiBvYmplY3QgbXVzdCBiZSB0aHJvd24KLSAgICAgKiBmcm9tIHRoZSB7QGxpbmsgVmFsaWRhdG9ySGFuZGxlcn0uIFRoZSB7QGxpbmsgRXJyb3JIYW5kbGVyfQotICAgICAqIHNob3VsZCBub3QgYmUgbm90aWZpZWQgb2Ygc3VjaCBhbiBleGNlcHRpb24uCi0gICAgICoKLSAgICAgKiA8cD4KLSAgICAgKiBUaGlzIG1ldGhvZCBjYW4gYmUgY2FsbGVkIGV2ZW4gZHVyaW5nIGEgbWlkZGxlIG9mIGEgdmFsaWRhdGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSByZWNlaXZlcgotICAgICAqICAgICAgQSB7QGxpbmsgQ29udGVudEhhbmRsZXJ9IG9yIGEgbnVsbCB2YWx1ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRDb250ZW50SGFuZGxlcihDb250ZW50SGFuZGxlciByZWNlaXZlcik7Ci0KLSAgICAvKioKLSAgICAgKiBHZXRzIHRoZSB7QGxpbmsgQ29udGVudEhhbmRsZXJ9IHdoaWNoIHJlY2VpdmVzIHRoZQotICAgICAqIGF1Z21lbnRlZCB2YWxpZGF0aW9uIHJlc3VsdC4KLSAgICAgKgotICAgICAqIEByZXR1cm4KLSAgICAgKiAgICAgIFRoaXMgbWV0aG9kIHJldHVybnMgdGhlIG9iamVjdCB0aGF0IHdhcyBsYXN0IHNldCB0aHJvdWdoCi0gICAgICogICAgICB0aGUge0BsaW5rICNnZXRDb250ZW50SGFuZGxlcigpfSBtZXRob2QsIG9yIG51bGwKLSAgICAgKiAgICAgIGlmIHRoYXQgbWV0aG9kIGhhcyBuZXZlciBiZWVuIGNhbGxlZCBzaW5jZSB0aGlzIHtAbGluayBWYWxpZGF0b3JIYW5kbGVyfQotICAgICAqICAgICAgaGFzIGNyZWF0ZWQuCi0gICAgICoKLSAgICAgKiBAc2VlICNzZXRDb250ZW50SGFuZGxlcihDb250ZW50SGFuZGxlcikKLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3QgQ29udGVudEhhbmRsZXIgZ2V0Q29udGVudEhhbmRsZXIoKTsKLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIHtAbGluayBFcnJvckhhbmRsZXJ9IHRvIHJlY2VpdmUgZXJyb3JzIGVuY291bnRlcmVkCi0gICAgICogZHVyaW5nIHRoZSB2YWxpZGF0aW9uLgotICAgICAqCi0gICAgICogPHA+Ci0gICAgICogRXJyb3IgaGFuZGxlciBjYW4gYmUgdXNlZCB0byBjdXN0b21pemUgdGhlIGVycm9yIGhhbmRsaW5nIHByb2Nlc3MKLSAgICAgKiBkdXJpbmcgYSB2YWxpZGF0aW9uLiBXaGVuIGFuIHtAbGluayBFcnJvckhhbmRsZXJ9IGlzIHNldCwKLSAgICAgKiBlcnJvcnMgZm91bmQgZHVyaW5nIHRoZSB2YWxpZGF0aW9uIHdpbGwgYmUgZmlyc3Qgc2VudAotICAgICAqIHRvIHRoZSB7QGxpbmsgRXJyb3JIYW5kbGVyfS4KLSAgICAgKgotICAgICAqIDxwPgotICAgICAqIFRoZSBlcnJvciBoYW5kbGVyIGNhbiBhYm9ydCBmdXJ0aGVyIHZhbGlkYXRpb24gaW1tZWRpYXRlbHkKLSAgICAgKiBieSB0aHJvd2luZyB7QGxpbmsgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9ufSBmcm9tIHRoZSBoYW5kbGVyLiBPciBmb3IgZXhhbXBsZQotICAgICAqIGl0IGNhbiBwcmludCBhbiBlcnJvciB0byB0aGUgc2NyZWVuIGFuZCB0cnkgdG8gY29udGludWUgdGhlCi0gICAgICogdmFsaWRhdGlvbiBieSByZXR1cm5pbmcgbm9ybWFsbHkgZnJvbSB0aGUge0BsaW5rIEVycm9ySGFuZGxlcn0KLSAgICAgKgotICAgICAqIDxwPgotICAgICAqIElmIGFueSB7QGxpbmsgVGhyb3dhYmxlfSBpcyB0aHJvd24gZnJvbSBhbiB7QGxpbmsgRXJyb3JIYW5kbGVyfSwKLSAgICAgKiB0aGUgc2FtZSB7QGxpbmsgVGhyb3dhYmxlfSBvYmplY3Qgd2lsbCBiZSB0aHJvd24gdG93YXJkIHRoZQotICAgICAqIHJvb3Qgb2YgdGhlIGNhbGwgc3RhY2suCi0gICAgICoKLSAgICAgKiA8cD4KLSAgICAgKiB7QGxpbmsgVmFsaWRhdG9ySGFuZGxlcn0gaXMgbm90IGFsbG93ZWQgdG8KLSAgICAgKiB0aHJvdyB7QGxpbmsgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9ufSB3aXRob3V0IGZpcnN0IHJlcG9ydGluZyBpdCB0bwotICAgICAqIHtAbGluayBFcnJvckhhbmRsZXJ9LgotICAgICAqCi0gICAgICogPHA+Ci0gICAgICogV2hlbiB0aGUge0BsaW5rIEVycm9ySGFuZGxlcn0gaXMgbnVsbCwgdGhlIGltcGxlbWVudGF0aW9uIHdpbGwKLSAgICAgKiBiZWhhdmUgYXMgaWYgdGhlIGZvbGxvd2luZyB7QGxpbmsgRXJyb3JIYW5kbGVyfSBpcyBzZXQ6Ci0gICAgICogPHByZT4KLSAgICAgKiBjbGFzcyBEcmFjb25pYW5FcnJvckhhbmRsZXIgaW1wbGVtZW50cyB7QGxpbmsgRXJyb3JIYW5kbGVyfSB7Ci0gICAgICogICAgIHB1YmxpYyB2b2lkIGZhdGFsRXJyb3IoIHtAbGluayBvcmcueG1sLnNheC5TQVhQYXJzZUV4Y2VwdGlvbn0gZSApIHRocm93cyB7QGxpbmsgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9ufSB7Ci0gICAgICogICAgICAgICB0aHJvdyBlOwotICAgICAqICAgICB9Ci0gICAgICogICAgIHB1YmxpYyB2b2lkIGVycm9yKCB7QGxpbmsgb3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb259IGUgKSB0aHJvd3Mge0BsaW5rIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbn0gewotICAgICAqICAgICAgICAgdGhyb3cgZTsKLSAgICAgKiAgICAgfQotICAgICAqICAgICBwdWJsaWMgdm9pZCB3YXJuaW5nKCB7QGxpbmsgb3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb259IGUgKSB0aHJvd3Mge0BsaW5rIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbn0gewotICAgICAqICAgICAgICAgLy8gbm9vcAotICAgICAqICAgICB9Ci0gICAgICogfQotICAgICAqIDwvcHJlPgotICAgICAqCi0gICAgICogPHA+Ci0gICAgICogV2hlbiBhIG5ldyB7QGxpbmsgVmFsaWRhdG9ySGFuZGxlcn0gb2JqZWN0IGlzIGNyZWF0ZWQsIGluaXRpYWxseQotICAgICAqIHRoaXMgZmllbGQgaXMgc2V0IHRvIG51bGwuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gICBlcnJvckhhbmRsZXIKLSAgICAgKiAgICAgIEEgbmV3IGVycm9yIGhhbmRsZXIgdG8gYmUgc2V0LiBUaGlzIHBhcmFtZXRlciBjYW4gYmUgbnVsbC4KLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRFcnJvckhhbmRsZXIoRXJyb3JIYW5kbGVyIGVycm9ySGFuZGxlcik7Ci0KLSAgICAvKioKLSAgICAgKiBHZXRzIHRoZSBjdXJyZW50IHtAbGluayBFcnJvckhhbmRsZXJ9IHNldCB0byB0aGlzIHtAbGluayBWYWxpZGF0b3JIYW5kbGVyfS4KLSAgICAgKgotICAgICAqIEByZXR1cm4KLSAgICAgKiAgICAgIFRoaXMgbWV0aG9kIHJldHVybnMgdGhlIG9iamVjdCB0aGF0IHdhcyBsYXN0IHNldCB0aHJvdWdoCi0gICAgICogICAgICB0aGUge0BsaW5rICNzZXRFcnJvckhhbmRsZXIoRXJyb3JIYW5kbGVyKX0gbWV0aG9kLCBvciBudWxsCi0gICAgICogICAgICBpZiB0aGF0IG1ldGhvZCBoYXMgbmV2ZXIgYmVlbiBjYWxsZWQgc2luY2UgdGhpcyB7QGxpbmsgVmFsaWRhdG9ySGFuZGxlcn0KLSAgICAgKiAgICAgIGhhcyBjcmVhdGVkLgotICAgICAqCi0gICAgICogQHNlZSAjc2V0RXJyb3JIYW5kbGVyKEVycm9ySGFuZGxlcikKLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3QgRXJyb3JIYW5kbGVyIGdldEVycm9ySGFuZGxlcigpOwotCi0gICAgLyoqCi0gICAgICogU2V0cyB0aGUge0BsaW5rIExTUmVzb3VyY2VSZXNvbHZlcn0gdG8gY3VzdG9taXplCi0gICAgICogcmVzb3VyY2UgcmVzb2x1dGlvbiB3aGlsZSBpbiBhIHZhbGlkYXRpb24gZXBpc29kZS4KLSAgICAgKgotICAgICAqIDxwPgotICAgICAqIHtAbGluayBWYWxpZGF0b3JIYW5kbGVyfSB1c2VzIGEge0BsaW5rIExTUmVzb3VyY2VSZXNvbHZlcn0KLSAgICAgKiB3aGVuIGl0IG5lZWRzIHRvIGxvY2F0ZSBleHRlcm5hbCByZXNvdXJjZXMgd2hpbGUgYSB2YWxpZGF0aW9uLAotICAgICAqIGFsdGhvdWdoIGV4YWN0bHkgd2hhdCBjb25zdGl0dXRlcyAibG9jYXRpbmcgZXh0ZXJuYWwgcmVzb3VyY2VzIiBpcwotICAgICAqIHVwIHRvIGVhY2ggc2NoZW1hIGxhbmd1YWdlLgotICAgICAqCi0gICAgICogPHA+Ci0gICAgICogV2hlbiB0aGUge0BsaW5rIExTUmVzb3VyY2VSZXNvbHZlcn0gaXMgbnVsbCwgdGhlIGltcGxlbWVudGF0aW9uIHdpbGwKLSAgICAgKiBiZWhhdmUgYXMgaWYgdGhlIGZvbGxvd2luZyB7QGxpbmsgTFNSZXNvdXJjZVJlc29sdmVyfSBpcyBzZXQ6Ci0gICAgICogPHByZT4KLSAgICAgKiBjbGFzcyBEdW1iTFNSZXNvdXJjZVJlc29sdmVyIGltcGxlbWVudHMge0BsaW5rIExTUmVzb3VyY2VSZXNvbHZlcn0gewotICAgICAqICAgICBwdWJsaWMge0BsaW5rIG9yZy53M2MuZG9tLmxzLkxTSW5wdXR9IHJlc29sdmVSZXNvdXJjZSgKLSAgICAgKiAgICAgICAgIFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkLCBTdHJpbmcgYmFzZVVSSSkgewotICAgICAqCi0gICAgICogICAgICAgICByZXR1cm4gbnVsbDsgLy8gYWx3YXlzIHJldHVybiBudWxsCi0gICAgICogICAgIH0KLSAgICAgKiB9Ci0gICAgICogPC9wcmU+Ci0gICAgICoKLSAgICAgKiA8cD4KLSAgICAgKiBJZiBhIHtAbGluayBMU1Jlc291cmNlUmVzb2x2ZXJ9IHRocm93cyBhIHtAbGluayBSdW50aW1lRXhjZXB0aW9ufQotICAgICAqICAob3IgaW5zdGFuY2VzIG9mIGl0cyBkZXJpdmVkIGNsYXNzZXMpLAotICAgICAqIHRoZW4gdGhlIHtAbGluayBWYWxpZGF0b3JIYW5kbGVyfSB3aWxsIGFib3J0IHRoZSBwYXJzaW5nIGFuZAotICAgICAqIHRoZSBjYWxsZXIgb2YgdGhlIDxjb2RlPnZhbGlkYXRlPC9jb2RlPiBtZXRob2Qgd2lsbCByZWNlaXZlCi0gICAgICogdGhlIHNhbWUge0BsaW5rIFJ1bnRpbWVFeGNlcHRpb259LgotICAgICAqCi0gICAgICogPHA+Ci0gICAgICogV2hlbiBhIG5ldyB7QGxpbmsgVmFsaWRhdG9ySGFuZGxlcn0gb2JqZWN0IGlzIGNyZWF0ZWQsIGluaXRpYWxseQotICAgICAqIHRoaXMgZmllbGQgaXMgc2V0IHRvIG51bGwuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gICByZXNvdXJjZVJlc29sdmVyCi0gICAgICogICAgICBBIG5ldyByZXNvdXJjZSByZXNvbHZlciB0byBiZSBzZXQuIFRoaXMgcGFyYW1ldGVyIGNhbiBiZSBudWxsLgotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHNldFJlc291cmNlUmVzb2x2ZXIoTFNSZXNvdXJjZVJlc29sdmVyIHJlc291cmNlUmVzb2x2ZXIpOwotCi0gICAgLyoqCi0gICAgICogR2V0cyB0aGUgY3VycmVudCB7QGxpbmsgTFNSZXNvdXJjZVJlc29sdmVyfSBzZXQgdG8gdGhpcyB7QGxpbmsgVmFsaWRhdG9ySGFuZGxlcn0uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuCi0gICAgICogICAgICBUaGlzIG1ldGhvZCByZXR1cm5zIHRoZSBvYmplY3QgdGhhdCB3YXMgbGFzdCBzZXQgdGhyb3VnaAotICAgICAqICAgICAgdGhlIHtAbGluayAjc2V0UmVzb3VyY2VSZXNvbHZlcihMU1Jlc291cmNlUmVzb2x2ZXIpfSBtZXRob2QsIG9yIG51bGwKLSAgICAgKiAgICAgIGlmIHRoYXQgbWV0aG9kIGhhcyBuZXZlciBiZWVuIGNhbGxlZCBzaW5jZSB0aGlzIHtAbGluayBWYWxpZGF0b3JIYW5kbGVyfQotICAgICAqICAgICAgaGFzIGNyZWF0ZWQuCi0gICAgICoKLSAgICAgKiBAc2VlICNzZXRFcnJvckhhbmRsZXIoRXJyb3JIYW5kbGVyKQotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCBMU1Jlc291cmNlUmVzb2x2ZXIgZ2V0UmVzb3VyY2VSZXNvbHZlcigpOwotCi0gICAgLyoqCi0gICAgICogT2J0YWlucyB0aGUge0BsaW5rIFR5cGVJbmZvUHJvdmlkZXJ9IGltcGxlbWVudGF0aW9uIG9mIHRoaXMKLSAgICAgKiB7QGxpbmsgVmFsaWRhdG9ySGFuZGxlcn0uCi0gICAgICoKLSAgICAgKiA8cD4KLSAgICAgKiBUaGUgb2J0YWluZWQge0BsaW5rIFR5cGVJbmZvUHJvdmlkZXJ9IGNhbiBiZSBxdWVyaWVkIGR1cmluZyBhIHBhcnNlCi0gICAgICogdG8gYWNjZXNzIHRoZSB0eXBlIGluZm9ybWF0aW9uIGRldGVybWluZWQgYnkgdGhlIHZhbGlkYXRvci4KLSAgICAgKgotICAgICAqIDxwPgotICAgICAqIFNvbWUgc2NoZW1hIGxhbmd1YWdlcyBkbyBub3QgZGVmaW5lIHRoZSBub3Rpb24gb2YgdHlwZSwKLSAgICAgKiBmb3IgdGhvc2UgbGFuZ3VhZ2VzLCB0aGlzIG1ldGhvZCBtYXkgbm90IGJlIHN1cHBvcnRlZC4KLSAgICAgKiBIb3dldmVyLCB0byBiZSBjb21wbGlhbnQgd2l0aCB0aGlzIHNwZWNpZmljYXRpb24sIGltcGxlbWVudGF0aW9ucwotICAgICAqIGZvciBXM0MgWE1MIFNjaGVtYSAxLjAgbXVzdCBzdXBwb3J0IHRoaXMgb3BlcmF0aW9uLgotICAgICAqCi0gICAgICogQHJldHVybgotICAgICAqICAgICAgbnVsbCBpZiB0aGUgdmFsaWRhdG9yIC8gc2NoZW1hIGxhbmd1YWdlIGRvZXMgbm90IHN1cHBvcnQKLSAgICAgKiAgICAgIHRoZSBub3Rpb24gb2Yge0BsaW5rIG9yZy53M2MuZG9tLlR5cGVJbmZvfS4KLSAgICAgKiAgICAgIE90aGVyd2lzZSBhIG5vbi1udWxsIHZhbGlkIHtAbGluayBUeXBlSW5mb1Byb3ZpZGVyfS4KLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3QgVHlwZUluZm9Qcm92aWRlciBnZXRUeXBlSW5mb1Byb3ZpZGVyKCk7Ci0KLQotICAgIC8qKgotICAgICAqIExvb2sgdXAgdGhlIHZhbHVlIG9mIGEgZmVhdHVyZSBmbGFnLgotICAgICAqCi0gICAgICogPHA+VGhlIGZlYXR1cmUgbmFtZSBpcyBhbnkgZnVsbHktcXVhbGlmaWVkIFVSSS4gIEl0IGlzCi0gICAgICogcG9zc2libGUgZm9yIGEge0BsaW5rIFZhbGlkYXRvckhhbmRsZXJ9IHRvIHJlY29nbml6ZSBhIGZlYXR1cmUgbmFtZSBidXQKLSAgICAgKiB0ZW1wb3JhcmlseSBiZSB1bmFibGUgdG8gcmV0dXJuIGl0cyB2YWx1ZS4KLSAgICAgKiBTb21lIGZlYXR1cmUgdmFsdWVzIG1heSBiZSBhdmFpbGFibGUgb25seSBpbiBzcGVjaWZpYwotICAgICAqIGNvbnRleHRzLCBzdWNoIGFzIGJlZm9yZSwgZHVyaW5nLCBvciBhZnRlciBhIHZhbGlkYXRpb24uCi0gICAgICoKLSAgICAgKiA8cD5JbXBsZW1lbnRvcnMgYXJlIGZyZWUgKGFuZCBlbmNvdXJhZ2VkKSB0byBpbnZlbnQgdGhlaXIgb3duIGZlYXR1cmVzLAotICAgICAqIHVzaW5nIG5hbWVzIGJ1aWx0IG9uIHRoZWlyIG93biBVUklzLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBmZWF0dXJlIG5hbWUsIHdoaWNoIGlzIGEgbm9uLW51bGwgZnVsbHktcXVhbGlmaWVkIFVSSS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIGN1cnJlbnQgdmFsdWUgb2YgdGhlIGZlYXR1cmUgKHRydWUgb3IgZmFsc2UpLgotICAgICAqCi0gICAgICogQHRocm93cyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIElmIHRoZSBmZWF0dXJlCi0gICAgICogICB2YWx1ZSBjYW4ndCBiZSBhc3NpZ25lZCBvciByZXRyaWV2ZWQuCi0gICAgICogQHRocm93cyBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gV2hlbiB0aGUKLSAgICAgKiAgIHtAbGluayBWYWxpZGF0b3JIYW5kbGVyfSByZWNvZ25pemVzIHRoZSBmZWF0dXJlIG5hbWUgYnV0Ci0gICAgICogICBjYW5ub3QgZGV0ZXJtaW5lIGl0cyB2YWx1ZSBhdCB0aGlzIHRpbWUuCi0gICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBXaGVuIDxjb2RlPm5hbWU8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAqCi0gICAgICogQHNlZSAjc2V0RmVhdHVyZShTdHJpbmcsIGJvb2xlYW4pCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0RmVhdHVyZShTdHJpbmcgbmFtZSkKLSAgICAgICAgdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgaWYgKG5hbWUgPT0gbnVsbCkgewotICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7Ci0gICAgICAgIH0KLQotICAgICAgICB0aHJvdyBuZXcgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbihuYW1lKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5TZXQgYSBmZWF0dXJlIGZvciB0aGlzIDxjb2RlPlZhbGlkYXRvckhhbmRsZXI8L2NvZGU+LjwvcD4KLSAgICAgKgotICAgICAqIDxwPkZlYXR1cmUgY2FuIGJlIHVzZWQgdG8gY29udHJvbCB0aGUgd2F5IGEKLSAgICAgKiB7QGxpbmsgVmFsaWRhdG9ySGFuZGxlcn0gcGFyc2VzIHNjaGVtYXMuIFRoZSBmZWF0dXJlIG5hbWUgaXMKLSAgICAgKiBhbnkgZnVsbHktcXVhbGlmaWVkIFVSSS4gSXQgaXMgcG9zc2libGUgZm9yIGEKLSAgICAgKiB7QGxpbmsgU2NoZW1hRmFjdG9yeX0gdG8KLSAgICAgKiBleHBvc2UgYSBmZWF0dXJlIHZhbHVlIGJ1dCB0byBiZSB1bmFibGUgdG8gY2hhbmdlIHRoZSBjdXJyZW50Ci0gICAgICogdmFsdWUuIFNvbWUgZmVhdHVyZSB2YWx1ZXMgbWF5IGJlIGltbXV0YWJsZSBvciBtdXRhYmxlIG9ubHkgaW4KLSAgICAgKiBzcGVjaWZpYyBjb250ZXh0cywgc3VjaCBhcyBiZWZvcmUsIGR1cmluZywgb3IgYWZ0ZXIgYQotICAgICAqIHZhbGlkYXRpb24uPC9wPgotICAgICAqCi0gICAgICogPHA+QWxsIGltcGxlbWVudGF0aW9ucyBhcmUgcmVxdWlyZWQgdG8gc3VwcG9ydCB0aGUge0BsaW5rIGphdmF4LnhtbC5YTUxDb25zdGFudHMjRkVBVFVSRV9TRUNVUkVfUFJPQ0VTU0lOR30gZmVhdHVyZS4KLSAgICAgKiBXaGVuIHRoZSBmZWF0dXJlIGlzOjwvcD4KLSAgICAgKiA8dWw+Ci0gICAgICogICA8bGk+Ci0gICAgICogICAgIDxjb2RlPnRydWU8L2NvZGU+OiB0aGUgaW1wbGVtZW50YXRpb24gd2lsbCBsaW1pdCBYTUwgcHJvY2Vzc2luZyB0byBjb25mb3JtIHRvIGltcGxlbWVudGF0aW9uIGxpbWl0cy4KLSAgICAgKiAgICAgRXhhbXBsZXMgaW5jbHVkZSBlbml0eSBleHBhbnNpb24gbGltaXRzIGFuZCBYTUwgU2NoZW1hIGNvbnN0cnVjdHMgdGhhdCB3b3VsZCBjb25zdW1lIGxhcmdlIGFtb3VudHMgb2YgcmVzb3VyY2VzLgotICAgICAqICAgICBJZiBYTUwgcHJvY2Vzc2luZyBpcyBsaW1pdGVkIGZvciBzZWN1cml0eSByZWFzb25zLCBpdCB3aWxsIGJlIHJlcG9ydGVkIHZpYSBhIGNhbGwgdG8gdGhlIHJlZ2lzdGVyZWQKLSAgICAgKiAgICB7QGxpbmsgRXJyb3JIYW5kbGVyI2ZhdGFsRXJyb3IoU0FYUGFyc2VFeGNlcHRpb24gZXhjZXB0aW9uKX0uCi0gICAgICogICAgIFNlZSB7QGxpbmsgI3NldEVycm9ySGFuZGxlcihFcnJvckhhbmRsZXIgZXJyb3JIYW5kbGVyKX0uCi0gICAgICogICA8L2xpPgotICAgICAqICAgPGxpPgotICAgICAqICAgICA8Y29kZT5mYWxzZTwvY29kZT46IHRoZSBpbXBsZW1lbnRhdGlvbiB3aWxsIHByb2Nlc3NpbmcgWE1MIGFjY29yZGluZyB0byB0aGUgWE1MIHNwZWNpZmljYXRpb25zIHdpdGhvdXQKLSAgICAgKiAgICAgcmVnYXJkIHRvIHBvc3NpYmxlIGltcGxlbWVudGF0aW9uIGxpbWl0cy4KLSAgICAgKiAgIDwvbGk+Ci0gICAgICogPC91bD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBmZWF0dXJlIG5hbWUsIHdoaWNoIGlzIGEgbm9uLW51bGwgZnVsbHktcXVhbGlmaWVkIFVSSS4KLSAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcXVlc3RlZCB2YWx1ZSBvZiB0aGUgZmVhdHVyZSAodHJ1ZSBvciBmYWxzZSkuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24gSWYgdGhlIGZlYXR1cmUKLSAgICAgKiAgIHZhbHVlIGNhbid0IGJlIGFzc2lnbmVkIG9yIHJldHJpZXZlZC4KLSAgICAgKiBAdGhyb3dzIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBXaGVuIHRoZQotICAgICAqICAge0BsaW5rIFZhbGlkYXRvckhhbmRsZXJ9IHJlY29nbml6ZXMgdGhlIGZlYXR1cmUgbmFtZSBidXQKLSAgICAgKiAgIGNhbm5vdCBzZXQgdGhlIHJlcXVlc3RlZCB2YWx1ZS4KLSAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIFdoZW4gPGNvZGU+bmFtZTwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICoKLSAgICAgKiBAc2VlICNnZXRGZWF0dXJlKFN0cmluZykKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRGZWF0dXJlKFN0cmluZyBuYW1lLCBib29sZWFuIHZhbHVlKQotICAgICAgICB0aHJvd3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiwgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIHsKLQotICAgICAgICBpZiAobmFtZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKLSAgICAgICAgfQotCi0gICAgICAgIHRocm93IG5ldyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uKG5hbWUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldCB0aGUgdmFsdWUgb2YgYSBwcm9wZXJ0eS4KLSAgICAgKgotICAgICAqIDxwPlRoZSBwcm9wZXJ0eSBuYW1lIGlzIGFueSBmdWxseS1xdWFsaWZpZWQgVVJJLiAgSXQgaXMKLSAgICAgKiBwb3NzaWJsZSBmb3IgYSB7QGxpbmsgVmFsaWRhdG9ySGFuZGxlcn0gdG8gcmVjb2duaXplIGEgcHJvcGVydHkgbmFtZSBidXQKLSAgICAgKiB0byBiZSB1bmFibGUgdG8gY2hhbmdlIHRoZSBjdXJyZW50IHZhbHVlLgotICAgICAqIFNvbWUgcHJvcGVydHkgdmFsdWVzIG1heSBiZSBpbW11dGFibGUgb3IgbXV0YWJsZSBvbmx5Ci0gICAgICogaW4gc3BlY2lmaWMgY29udGV4dHMsIHN1Y2ggYXMgYmVmb3JlLCBkdXJpbmcsIG9yIGFmdGVyCi0gICAgICogYSB2YWxpZGF0aW9uLjwvcD4KLSAgICAgKgotICAgICAqIDxwPntAbGluayBWYWxpZGF0b3JIYW5kbGVyfXMgYXJlIG5vdCByZXF1aXJlZCB0byByZWNvZ25pemUgc2V0dGluZwotICAgICAqIGFueSBzcGVjaWZpYyBwcm9wZXJ0eSBuYW1lcy48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgcHJvcGVydHkgbmFtZSwgd2hpY2ggaXMgYSBub24tbnVsbCBmdWxseS1xdWFsaWZpZWQgVVJJLgotICAgICAqIEBwYXJhbSBvYmplY3QgVGhlIHJlcXVlc3RlZCB2YWx1ZSBmb3IgdGhlIHByb3BlcnR5LgotICAgICAqCi0gICAgICogQHRocm93cyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIElmIHRoZSBwcm9wZXJ0eQotICAgICAqICAgdmFsdWUgY2FuJ3QgYmUgYXNzaWduZWQgb3IgcmV0cmlldmVkLgotICAgICAqIEB0aHJvd3MgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIFdoZW4gdGhlCi0gICAgICogICB7QGxpbmsgVmFsaWRhdG9ySGFuZGxlcn0gcmVjb2duaXplcyB0aGUgcHJvcGVydHkgbmFtZSBidXQKLSAgICAgKiAgIGNhbm5vdCBzZXQgdGhlIHJlcXVlc3RlZCB2YWx1ZS4KLSAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIFdoZW4gPGNvZGU+bmFtZTwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0UHJvcGVydHkoU3RyaW5nIG5hbWUsIE9iamVjdCBvYmplY3QpCi0gICAgICAgIHRocm93cyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uLCBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gewotCi0gICAgICAgIGlmIChuYW1lID09IG51bGwpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwotICAgICAgICB9Ci0KLSAgICAgICAgdGhyb3cgbmV3IFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24obmFtZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogTG9vayB1cCB0aGUgdmFsdWUgb2YgYSBwcm9wZXJ0eS4KLSAgICAgKgotICAgICAqIDxwPlRoZSBwcm9wZXJ0eSBuYW1lIGlzIGFueSBmdWxseS1xdWFsaWZpZWQgVVJJLiAgSXQgaXMKLSAgICAgKiBwb3NzaWJsZSBmb3IgYSB7QGxpbmsgVmFsaWRhdG9ySGFuZGxlcn0gdG8gcmVjb2duaXplIGEgcHJvcGVydHkgbmFtZSBidXQKLSAgICAgKiB0ZW1wb3JhcmlseSBiZSB1bmFibGUgdG8gcmV0dXJuIGl0cyB2YWx1ZS4KLSAgICAgKiBTb21lIHByb3BlcnR5IHZhbHVlcyBtYXkgYmUgYXZhaWxhYmxlIG9ubHkgaW4gc3BlY2lmaWMKLSAgICAgKiBjb250ZXh0cywgc3VjaCBhcyBiZWZvcmUsIGR1cmluZywgb3IgYWZ0ZXIgYSB2YWxpZGF0aW9uLjwvcD4KLSAgICAgKgotICAgICAqIDxwPntAbGluayBWYWxpZGF0b3JIYW5kbGVyfXMgYXJlIG5vdCByZXF1aXJlZCB0byByZWNvZ25pemUgYW55IHNwZWNpZmljCi0gICAgICogcHJvcGVydHkgbmFtZXMuPC9wPgotICAgICAqCi0gICAgICogPHA+SW1wbGVtZW50b3JzIGFyZSBmcmVlIChhbmQgZW5jb3VyYWdlZCkgdG8gaW52ZW50IHRoZWlyIG93biBwcm9wZXJ0aWVzLAotICAgICAqIHVzaW5nIG5hbWVzIGJ1aWx0IG9uIHRoZWlyIG93biBVUklzLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBwcm9wZXJ0eSBuYW1lLCB3aGljaCBpcyBhIG5vbi1udWxsIGZ1bGx5LXF1YWxpZmllZCBVUkkuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBjdXJyZW50IHZhbHVlIG9mIHRoZSBwcm9wZXJ0eS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiBJZiB0aGUgcHJvcGVydHkKLSAgICAgKiAgIHZhbHVlIGNhbid0IGJlIGFzc2lnbmVkIG9yIHJldHJpZXZlZC4KLSAgICAgKiBAdGhyb3dzIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBXaGVuIHRoZQotICAgICAqICAgWE1MUmVhZGVyIHJlY29nbml6ZXMgdGhlIHByb3BlcnR5IG5hbWUgYnV0Ci0gICAgICogICBjYW5ub3QgZGV0ZXJtaW5lIGl0cyB2YWx1ZSBhdCB0aGlzIHRpbWUuCi0gICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBXaGVuIDxjb2RlPm5hbWU8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAqCi0gICAgICogQHNlZSAjc2V0UHJvcGVydHkoU3RyaW5nLCBPYmplY3QpCi0gICAgICovCi0gICAgcHVibGljIE9iamVjdCBnZXRQcm9wZXJ0eShTdHJpbmcgbmFtZSkKLSAgICAgICAgdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgaWYgKG5hbWUgPT0gbnVsbCkgewotICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7Ci0gICAgICAgIH0KLQotICAgICAgICB0aHJvdyBuZXcgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbihuYW1lKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvamF2YXgveG1sL3ZhbGlkYXRpb24vcGFja2FnZS5odG1sIGIvc3JjL2phdmF4L3htbC92YWxpZGF0aW9uL3BhY2thZ2UuaHRtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMmRkMDZiMy4uMDAwMDAwMAotLS0gYS9zcmMvamF2YXgveG1sL3ZhbGlkYXRpb24vcGFja2FnZS5odG1sCisrKyAvZGV2L251bGwKQEAgLTEsMTI0ICswLDAgQEAKLTw/eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04Ij8+Ci08IS0tCi1Db3B5cmlnaHQgKGMpIDIwMDMsIDIwMDUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi1ETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0KLVRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci11bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi1wYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi1ieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLQotVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi1BTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLUZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLWFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0KLVlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLTIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLUluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLQotUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLW9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLXF1ZXN0aW9ucy4gCi0tLT4KLQotPCFET0NUWVBFIGh0bWwKLSAgICAgUFVCTElDICItLy9XM0MvL0RURCBYSFRNTCAxLjAgU3RyaWN0Ly9FTiIKLSAgICAgImh0dHA6Ly93d3cudzMub3JnL1RSL3hodG1sMS9EVEQveGh0bWwxLXN0cmljdC5kdGQiPgotCi08aHRtbCB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCI+Ci0KLTxoZWFkPgotICA8dGl0bGU+amF2YXgueG1sLnZhbGlkYXRpb248L3RpdGxlPgotCi0gIDxtZXRhIG5hbWU9IkNWUyIKLSAgICAgICAgY29udGVudD0iJElkOiBwYWNrYWdlLmh0bWwsdiAxLjIgMjAwNS8wNi8xMCAwMzo1MDo0MyBqZWZmc3V0dG9yIEV4cCAkIiAvPgotICA8bWV0YSBuYW1lPSJBVVRIT1IiCi0gICAgICAgIGNvbnRlbnQ9IkplZmYuU3V0dG9yQFN1bi5jb20iIC8+Ci08L2hlYWQ+Ci0JPGJvZHk+Ci0JCTxwPgotCQkgICAgVGhpcyBwYWNrYWdlIHByb3ZpZGVzIGFuIEFQSSBmb3IgdmFsaWRhdGlvbiBvZiBYTUwgZG9jdW1lbnRzLiAgPGVtPlZhbGlkYXRpb248L2VtPiBpcyB0aGUgcHJvY2VzcyBvZiB2ZXJpZnlpbmcKLQkJICAgIHRoYXQgYW4gWE1MIGRvY3VtZW50IGlzIGFuIGluc3RhbmNlIG9mIGEgc3BlY2lmaWVkIFhNTCA8ZW0+c2NoZW1hPC9lbT4uICBBbiBYTUwgc2NoZW1hIGRlZmluZXMgdGhlCi0JCSAgICBjb250ZW50IG1vZGVsIChhbHNvIGNhbGxlZCBhIDxlbT5ncmFtbWFyPC9lbT4gb3IgPGVtPnZvY2FidWxhcnk8L2VtPikgdGhhdCBpdHMgaW5zdGFuY2UgZG9jdW1lbnRzCi0JCSAgICB3aWxsIHJlcHJlc2VudC4KLSAgICAgICAgPC9wPgotICAgICAgICA8cD4KLSAgICAgICAgICAgIFRoZXJlIGFyZSBhIG51bWJlciBvZiBwb3B1bGFyIHRlY2hub2xvZ2llcyBhdmFpbGFibGUgZm9yIGNyZWF0aW5nIGFuIFhNTCBzY2hlbWEuIFNvbWUgb2YgdGhlIG1vc3QKLSAgICAgICAgICAgIHBvcHVsYXIgaW5jbHVkZToKLQkJPC9wPgotICAgICAgICAgICAgPHVsPgotICAgICAgICAgICAgICAgIDxsaT48c3Ryb25nPkRvY3VtZW50IFR5cGUgRGVmaW5pdGlvbiAoRFREKTwvc3Ryb25nPiAtIFhNTCdzIGJ1aWx0LWluIHNjaGVtYSBsYW5ndWFnZS48L2xpPgotICAgICAgICAgICAgICAgIDxsaT48c3Ryb25nPjxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1hNTC9TY2hlbWEiPlczQyBYTUwgU2NoZW1hIChXWFMpPC9hPjwvc3Ryb25nPiAtIGFuIG9iamVjdC1vcmllbnRlZCBYTUwgc2NoZW1hCi0gICAgICAgICAgICAgICAgICAgIGxhbmd1YWdlLiBXWFMgYWxzbyBwcm92aWRlcyBhIHR5cGUgc3lzdGVtIGZvciBjb25zdHJhaW5pbmcgdGhlIGNoYXJhY3RlciBkYXRhIG9mIGFuIFhNTCBkb2N1bWVudC4KLSAgICAgICAgICAgICAgICAgICAgV1hTIGlzIG1haW50YWluZWQgYnkgdGhlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnIj5Xb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtIChXM0MpPC9hPiBhbmQgaXMgYSBXM0MKLSAgICAgICAgICAgICAgICAgICAgUmVjb21tZW5kYXRpb24gKHRoYXQgaXMsIGEgcmF0aWZpZWQgVzNDIHN0YW5kYXJkIHNwZWNpZmljYXRpb24pLjwvbGk+Ci0gICAgICAgICAgICAgICAgPGxpPjxzdHJvbmc+PGEgaHJlZj0iaHR0cDovL3d3dy5yZWxheG5nLm9yZyI+UkVMQVggTkcgKFJORyk8L2E+PC9zdHJvbmc+IC0gYSBwYXR0ZXJuLWJhc2VkLAotICAgICAgICAgICAgICAgICAgICB1c2VyLWZyaWVuZGx5IFhNTCBzY2hlbWEgbGFuZ3VhZ2UuIFJORyBzY2hlbWFzIG1heSBhbHNvIHVzZSB0eXBlcyB0byBjb25zdHJhaW4gWE1MIGNoYXJhY3RlciBkYXRhLgotICAgICAgICAgICAgICAgICAgICBSTkcgaXMgbWFpbnRhaW5lZCBieSB0aGUgPGEgaHJlZj0iaHR0cDovL3d3dy5vYXNpcy1vcGVuLm9yZyI+T3JnYW5pemF0aW9uIGZvciB0aGUgQWR2YW5jZW1lbnQgb2YKLSAgICAgICAgICAgICAgICAgICAgU3RydWN0dXJlZCBJbmZvcm1hdGlvbiBTdGFuZGFyZHMgKE9BU0lTKTwvYT4gYW5kIGlzIGJvdGggYW4gT0FTSVMgYW5kIGFuCi0gICAgICAgICAgICAgICAgICAgIDxhIGhyZWY9Imh0dHA6Ly93d3cuaXNvLm9yZyI+SVNPIChJbnRlcm5hdGlvbmFsIE9yZ2FuaXphdGlvbiBmb3IgU3RhbmRhcmRpemF0aW9uKTwvYT4gc3RhbmRhcmQuPC9saT4KLSAgICAgICAgICAgICAgICA8bGk+PHN0cm9uZz48YSBocmVmPSJodHRwOi8vd3d3LnNjaGVtYXRyb24uY29tLyI+U2NoZW1hdHJvbjwvYT48L3N0cm9uZz4gLSBhIHJ1bGVzLWJhc2VkIFhNTCBzY2hlbWEKLSAgICAgICAgICAgICAgICBsYW5ndWFnZS4gV2hlcmVhcyBEVEQsIFdYUywgYW5kIFJORyBhcmUgZGVzaWduZWQgdG8gZXhwcmVzcyB0aGUgc3RydWN0dXJlIG9mIGEgY29udGVudCBtb2RlbCwKLSAgICAgICAgICAgICAgICBTY2hlbWF0cm9uIGlzIGRlc2lnbmVkIHRvIGVuZm9yY2UgaW5kaXZpZHVhbCBydWxlcyB0aGF0IGFyZSBkaWZmaWN1bHQgb3IgaW1wb3NzaWJsZSB0byBleHByZXNzCi0gICAgICAgICAgICAgICAgd2l0aCBvdGhlciBzY2hlbWEgbGFuZ3VhZ2VzLiBTY2hlbWF0cm9uIGlzIGludGVuZGVkIHRvIHN1cHBsZW1lbnQgYSBzY2hlbWEgd3JpdHRlbiBpbgotICAgICAgICAgICAgICAgIHN0cnVjdHVyYWwgc2NoZW1hIGxhbmd1YWdlIHN1Y2ggYXMgdGhlIGFmb3JlbWVudGlvbmVkLiBTY2hlbWF0cm9uIGlzIGluIHRoZSBwcm9jZXNzCi0gICAgICAgICAgICAgICAgb2YgYmVjb21pbmcgYW4gSVNPIHN0YW5kYXJkLjwvbGk+Ci0gICAgICAgICAgICA8L3VsPgotICAgICAgICA8cD4KLQkJICAgIFByZXZpb3VzIHZlcnNpb25zIG9mIEpBWFAgc3VwcG9ydGVkIHZhbGlkYXRpb24gYXMgYSBmZWF0dXJlIG9mIGFuIFhNTCBwYXJzZXIsIHJlcHJlc2VudGVkIGJ5Ci0JCSAgICBlaXRoZXIgYSB7QGxpbmsgamF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyfSBvciB7QGxpbmsgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyfSBpbnN0YW5jZS4KLSAgICAgICAgPC9wPgotICAgICAgICA8cD4KLQkJICAgIFRoZSBKQVhQIHZhbGlkYXRpb24gQVBJIGRlY291cGxlcyB0aGUgdmFsaWRhdGlvbiBvZiBhbiBpbnN0YW5jZSBkb2N1bWVudCBmcm9tIHRoZSBwYXJzaW5nIG9mIGFuCi0JCSAgICBYTUwgZG9jdW1lbnQuIFRoaXMgaXMgYWR2YW50YWdlb3VzIGZvciBzZXZlcmFsIHJlYXNvbnMsIHNvbWUgb2Ygd2hpY2ggYXJlOgotCQk8L3A+Ci0JCSAgICA8dWw+Ci0JCSAgICAgICAgPGxpPjxzdHJvbmc+U3VwcG9ydCBmb3IgYWRkaXRpb25hbCBzY2hlbWEgbGFuZ2F1Z2VzLjwvc3Ryb25nPiBBcyBvZiBKREsgMS41LCB0aGUgdHdvIG1vc3QKLQkJICAgICAgICBwb3B1bGFyIEpBWFAgcGFyc2VyIGltcGxlbWVudGF0aW9ucywgQ3JpbXNvbiBhbmQgWGVyY2VzLCBvbmx5IHN1cHBvcnQgYSBzdWJzZXQgb2YgdGhlIGF2YWlsYWJsZQotCQkgICAgICAgIFhNTCBzY2hlbWEgbGFuZ3VhZ2VzLiBUaGUgVmFsaWRhdGlvbiBBUEkgcHJvdmlkZXMgYSBzdGFuZGFyZCBtZWNoYW5pc20gdGhyb3VnaCB3aGljaCBhcHBsaWNhdGlvbnMKLQkJICAgICAgICBtYXkgdGFrZSBvZiBhZHZhbnRhZ2Ugb2Ygc3BlY2lhbGl6YXRpb24gdmFsaWRhdGlvbiBsaWJyYXJpZXMgd2hpY2ggc3VwcG9ydCBhZGRpdGlvbmFsIHNjaGVtYQotCQkgICAgICAgIGxhbmd1YWdlcy48L2xpPgotCQkgICAgICAgIDxsaT48c3Ryb25nPkVhc3kgcnVudGltZSBjb3VwbGluZyBvZiBhbiBYTUwgaW5zdGFuY2UgYW5kIHNjaGVtYS48L3N0cm9uZz4gU3BlY2lmeWluZyB0aGUgbG9jYXRpb24KLQkJICAgICAgICBvZiBhIHNjaGVtYSB0byB1c2UgZm9yIHZhbGlkYXRpb24gd2l0aCBKQVhQIHBhcnNlcnMgY2FuIGJlIGNvbmZ1c2luZy4gVGhlIFZhbGlkYXRpb24gQVBJIG1ha2VzIHRoaXMKLQkJICAgICAgICBwcm9jZXNzIHNpbXBsZSAoc2VlIDxhIGhyZWY9IiNleGFtcGxlLTEiPmV4YW1wbGU8L2E+IGJlbG93KS48L2xpPgotICAgICAgICAgIDwvdWw+Ci0JCTxwPgotICAgICAgICAgICAgPGEgbmFtZT0iZXhhbXBsZS0xIj48c3Ryb25nPlVzYWdlIGV4YW1wbGU8L3N0cm9uZz4uPC9hPiBUaGUgZm9sbG93aW5nIGV4YW1wbGUgZGVtb25zdHJhdGVzIHZhbGlkYXRpbmcKLSAgICAgICAgICAgIGFuIFhNTCBkb2N1bWVudCB3aXRoIHRoZSBWYWxpZGF0aW9uIEFQSSAoZm9yIHJlYWRhYmlsaXR5LCBzb21lIGV4Y2VwdGlvbiBoYW5kbGluZyBpcyBub3Qgc2hvd24pOgotCQk8L3A+Ci0gICAgICAgICAgICA8cHJlPgotICAgICAgICAgICAgCi0gICAgLy8gcGFyc2UgYW4gWE1MIGRvY3VtZW50IGludG8gYSBET00gdHJlZQotICAgIERvY3VtZW50QnVpbGRlciBwYXJzZXIgPSBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCkubmV3RG9jdW1lbnRCdWlsZGVyKCk7Ci0gICAgRG9jdW1lbnQgZG9jdW1lbnQgPSBwYXJzZXIucGFyc2UobmV3IEZpbGUoImluc3RhbmNlLnhtbCIpKTsKLQotICAgIC8vIGNyZWF0ZSBhIFNjaGVtYUZhY3RvcnkgY2FwYWJsZSBvZiB1bmRlcnN0YW5kaW5nIFdYUyBzY2hlbWFzCi0gICAgU2NoZW1hRmFjdG9yeSBmYWN0b3J5ID0gU2NoZW1hRmFjdG9yeS5uZXdJbnN0YW5jZShYTUxDb25zdGFudHMuVzNDX1hNTF9TQ0hFTUFfTlNfVVJJKTsKLQotICAgIC8vIGxvYWQgYSBXWFMgc2NoZW1hLCByZXByZXNlbnRlZCBieSBhIFNjaGVtYSBpbnN0YW5jZQotICAgIFNvdXJjZSBzY2hlbWFGaWxlID0gbmV3IFN0cmVhbVNvdXJjZShuZXcgRmlsZSgibXlTY2hlbWEueHNkIikpOwotICAgIFNjaGVtYSBzY2hlbWEgPSBmYWN0b3J5Lm5ld1NjaGVtYShzY2hlbWFGaWxlKTsKLQotICAgIC8vIGNyZWF0ZSBhIFZhbGlkYXRvciBpbnN0YW5jZSwgd2hpY2ggY2FuIGJlIHVzZWQgdG8gdmFsaWRhdGUgYW4gaW5zdGFuY2UgZG9jdW1lbnQKLSAgICBWYWxpZGF0b3IgdmFsaWRhdG9yID0gc2NoZW1hLm5ld1ZhbGlkYXRvcigpOwotCi0gICAgLy8gdmFsaWRhdGUgdGhlIERPTSB0cmVlCi0gICAgdHJ5IHsKLSAgICAgICAgdmFsaWRhdG9yLnZhbGlkYXRlKG5ldyBET01Tb3VyY2UoZG9jdW1lbnQpKTsKLSAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gZSkgewotICAgICAgICAvLyBpbnN0YW5jZSBkb2N1bWVudCBpcyBpbnZhbGlkIQotICAgIH0KLTwvcHJlPgotCQk8cD4KLQkJICAgIFRoZSBKQVhQIHBhcnNpbmcgQVBJIGhhcyBiZWVuIGludGVncmF0ZWQgd2l0aCB0aGUgVmFsaWRhdGlvbiBBUEkuIEFwcGxpY2F0aW9ucyBtYXkgY3JlYXRlIGEge0BsaW5rIGphdmF4LnhtbC52YWxpZGF0aW9uLlNjaGVtYX0gd2l0aCB0aGUgdmFsaWRhdGlvbiBBUEkKLQkJICAgIGFuZCBhc3NvY2lhdGUgaXQgd2l0aCBhIHtAbGluayBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5fSBvciBhIHtAbGluayBqYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXJGYWN0b3J5fSBpbnN0YW5jZQotCQkgICAgYnkgdXNpbmcgdGhlIHtAbGluayBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5I3NldFNjaGVtYShTY2hlbWEpfSBhbmQge0BsaW5rIGphdmF4LnhtbC5wYXJzZXJzLlNBWFBhcnNlckZhY3Rvcnkjc2V0U2NoZW1hKFNjaGVtYSl9Ci0JCSAgICBtZXRob2RzLiA8c3Ryb25nPllvdSBzaG91bGQgbm90PC9zdHJvbmc+IGJvdGggc2V0IGEgc2NoZW1hIGFuZCBjYWxsIDxjb2RlPnNldFZhbGlkYXRpbmcodHJ1ZSk8L2NvZGU+IG9uIGEgcGFyc2VyIGZhY3RvcnkuIFRoZSBmb3JtZXIgdGVjaG5pcXVlCi0JCSAgICB3aWxsIGNhdXNlIHBhcnNlcnMgdG8gdXNlIHRoZSBuZXcgdmFsaWRhdGlvbiBBUEk7IHRoZSBsYXR0ZXIgd2lsbCBjYXVzZSBwYXJzZXJzIHRvIHVzZSB0aGVpciBvd24gaW50ZXJuYWwgdmFsaWRhdGlvbgotCQkgICAgZmFjaWxpdGllcy4gPHN0cm9uZz5UdXJuaW5nIG9uIGJvdGggb2YgdGhlc2Ugb3B0aW9ucyBzaW11bHRhbmVvdXNseSB3aWxsIGNhdXNlIGVpdGhlciByZWR1bmRhbnQgYmVoYXZpb3Igb3IgZXJyb3IgY29uZGl0aW9ucy48L3N0cm9uZz4KLSAgICAgICAgPC9wPgotCTwvYm9keT4KLTwvaHRtbD4KZGlmZiAtLWdpdCBhL3NyYy9qYXZheC94bWwveHBhdGgvU2VjdXJpdHlTdXBwb3J0LmphdmEgYi9zcmMvamF2YXgveG1sL3hwYXRoL1NlY3VyaXR5U3VwcG9ydC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1ODU5Yzk1Li4wMDAwMDAwCi0tLSBhL3NyYy9qYXZheC94bWwveHBhdGgvU2VjdXJpdHlTdXBwb3J0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNjAgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotcGFja2FnZSBqYXZheC54bWwueHBhdGg7Ci0KLWltcG9ydCBqYXZhLm5ldC5VUkw7Ci1pbXBvcnQgamF2YS5zZWN1cml0eS4qOwotaW1wb3J0IGphdmEubmV0Lio7Ci1pbXBvcnQgamF2YS5pby4qOwotaW1wb3J0IGphdmEudXRpbC4qOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgaXMgZHVwbGljYXRlZCBmb3IgZWFjaCBKQVhQIHN1YnBhY2thZ2Ugc28ga2VlcCBpdCBpbiBzeW5jLgotICogSXQgaXMgcGFja2FnZSBwcml2YXRlIGFuZCB0aGVyZWZvcmUgaXMgbm90IGV4cG9zZWQgYXMgcGFydCBvZiB0aGUgSkFYUAotICogQVBJLgotICoKLSAqIFNlY3VyaXR5IHJlbGF0ZWQgbWV0aG9kcyB0aGF0IG9ubHkgd29yayBvbiBKMlNFIDEuMiBhbmQgbmV3ZXIuCi0gKi8KLWNsYXNzIFNlY3VyaXR5U3VwcG9ydCAgewotCi0KLSAgICBDbGFzc0xvYWRlciBnZXRDb250ZXh0Q2xhc3NMb2FkZXIoKSB7Ci0gICAgICAgIHJldHVybiAoQ2xhc3NMb2FkZXIpCi0gICAgICAgICAgICAgICAgQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQobmV3IFByaXZpbGVnZWRBY3Rpb24oKSB7Ci0gICAgICAgICAgICBwdWJsaWMgT2JqZWN0IHJ1bigpIHsKLSAgICAgICAgICAgICAgICBDbGFzc0xvYWRlciBjbCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICAgICAgY2wgPSBUaHJlYWQuY3VycmVudFRocmVhZCgpLmdldENvbnRleHRDbGFzc0xvYWRlcigpOwotICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIGV4KSB7IH0KLSAgICAgICAgICAgICAgICByZXR1cm4gY2w7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0pOwotICAgIH0KLQotICAgIFN0cmluZyBnZXRTeXN0ZW1Qcm9wZXJ0eShmaW5hbCBTdHJpbmcgcHJvcE5hbWUpIHsKLSAgICAgICAgcmV0dXJuIChTdHJpbmcpCi0gICAgICAgICAgICBBY2Nlc3NDb250cm9sbGVyLmRvUHJpdmlsZWdlZChuZXcgUHJpdmlsZWdlZEFjdGlvbigpIHsKLSAgICAgICAgICAgICAgICBwdWJsaWMgT2JqZWN0IHJ1bigpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFN5c3RlbS5nZXRQcm9wZXJ0eShwcm9wTmFtZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfSk7Ci0gICAgfQotCi0gICAgRmlsZUlucHV0U3RyZWFtIGdldEZpbGVJbnB1dFN0cmVhbShmaW5hbCBGaWxlIGZpbGUpCi0gICAgICAgIHRocm93cyBGaWxlTm90Rm91bmRFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICByZXR1cm4gKEZpbGVJbnB1dFN0cmVhbSkKLSAgICAgICAgICAgICAgICBBY2Nlc3NDb250cm9sbGVyLmRvUHJpdmlsZWdlZChuZXcgUHJpdmlsZWdlZEV4Y2VwdGlvbkFjdGlvbigpIHsKLSAgICAgICAgICAgICAgICAgICAgcHVibGljIE9iamVjdCBydW4oKSB0aHJvd3MgRmlsZU5vdEZvdW5kRXhjZXB0aW9uIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgRmlsZUlucHV0U3RyZWFtKGZpbGUpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfSk7Ci0gICAgICAgIH0gY2F0Y2ggKFByaXZpbGVnZWRBY3Rpb25FeGNlcHRpb24gZSkgewotICAgICAgICAgICAgdGhyb3cgKEZpbGVOb3RGb3VuZEV4Y2VwdGlvbillLmdldEV4Y2VwdGlvbigpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgSW5wdXRTdHJlYW0gZ2V0VVJMSW5wdXRTdHJlYW0oZmluYWwgVVJMIHVybCkKLSAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uCi0gICAgewotICAgICAgICB0cnkgewotICAgICAgICAgICAgcmV0dXJuIChJbnB1dFN0cmVhbSkKLSAgICAgICAgICAgICAgICBBY2Nlc3NDb250cm9sbGVyLmRvUHJpdmlsZWdlZChuZXcgUHJpdmlsZWdlZEV4Y2VwdGlvbkFjdGlvbigpIHsKLSAgICAgICAgICAgICAgICAgICAgcHVibGljIE9iamVjdCBydW4oKSB0aHJvd3MgSU9FeGNlcHRpb24gewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHVybC5vcGVuU3RyZWFtKCk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9KTsKLSAgICAgICAgfSBjYXRjaCAoUHJpdmlsZWdlZEFjdGlvbkV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICB0aHJvdyAoSU9FeGNlcHRpb24pZS5nZXRFeGNlcHRpb24oKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIFVSTCBnZXRSZXNvdXJjZUFzVVJMKGZpbmFsIENsYXNzTG9hZGVyIGNsLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBuYW1lKQotICAgIHsKLSAgICAgICAgcmV0dXJuIChVUkwpCi0gICAgICAgICAgICBBY2Nlc3NDb250cm9sbGVyLmRvUHJpdmlsZWdlZChuZXcgUHJpdmlsZWdlZEFjdGlvbigpIHsKLSAgICAgICAgICAgICAgICBwdWJsaWMgT2JqZWN0IHJ1bigpIHsKLSAgICAgICAgICAgICAgICAgICAgVVJMIHVybDsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGNsID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHVybCA9IE9iamVjdC5jbGFzcy5nZXRSZXNvdXJjZShuYW1lKTsKLSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHVybCA9IGNsLmdldFJlc291cmNlKG5hbWUpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiB1cmw7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfSk7Ci0gICAgfQotCi0gICAgRW51bWVyYXRpb24gZ2V0UmVzb3VyY2VzKGZpbmFsIENsYXNzTG9hZGVyIGNsLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBuYW1lKSB0aHJvd3MgSU9FeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIHRyeXsKLSAgICAgICAgcmV0dXJuIChFbnVtZXJhdGlvbikKLSAgICAgICAgICAgIEFjY2Vzc0NvbnRyb2xsZXIuZG9Qcml2aWxlZ2VkKG5ldyBQcml2aWxlZ2VkRXhjZXB0aW9uQWN0aW9uKCkgewotICAgICAgICAgICAgICAgIHB1YmxpYyBPYmplY3QgcnVuKCkgdGhyb3dzIElPRXhjZXB0aW9uewotICAgICAgICAgICAgICAgICAgICBFbnVtZXJhdGlvbiBlbnVtZXJhdGlvbjsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGNsID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGVudW1lcmF0aW9uID0gQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtUmVzb3VyY2VzKG5hbWUpOwotICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgZW51bWVyYXRpb24gPSBjbC5nZXRSZXNvdXJjZXMobmFtZSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVudW1lcmF0aW9uOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0pOwotICAgICAgICB9Y2F0Y2goUHJpdmlsZWdlZEFjdGlvbkV4Y2VwdGlvbiBlKXsKLSAgICAgICAgICAgIHRocm93IChJT0V4Y2VwdGlvbillLmdldEV4Y2VwdGlvbigpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgSW5wdXRTdHJlYW0gZ2V0UmVzb3VyY2VBc1N0cmVhbShmaW5hbCBDbGFzc0xvYWRlciBjbCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgbmFtZSkKLSAgICB7Ci0gICAgICAgIHJldHVybiAoSW5wdXRTdHJlYW0pCi0gICAgICAgICAgICBBY2Nlc3NDb250cm9sbGVyLmRvUHJpdmlsZWdlZChuZXcgUHJpdmlsZWdlZEFjdGlvbigpIHsKLSAgICAgICAgICAgICAgICBwdWJsaWMgT2JqZWN0IHJ1bigpIHsKLSAgICAgICAgICAgICAgICAgICAgSW5wdXRTdHJlYW0gcmlzOwotICAgICAgICAgICAgICAgICAgICBpZiAoY2wgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgcmlzID0gT2JqZWN0LmNsYXNzLmdldFJlc291cmNlQXNTdHJlYW0obmFtZSk7Ci0gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByaXMgPSBjbC5nZXRSZXNvdXJjZUFzU3RyZWFtKG5hbWUpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiByaXM7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfSk7Ci0gICAgfQotCi0gICAgYm9vbGVhbiBkb2VzRmlsZUV4aXN0KGZpbmFsIEZpbGUgZikgewotICAgIHJldHVybiAoKEJvb2xlYW4pCi0gICAgICAgICAgICBBY2Nlc3NDb250cm9sbGVyLmRvUHJpdmlsZWdlZChuZXcgUHJpdmlsZWdlZEFjdGlvbigpIHsKLSAgICAgICAgICAgICAgICBwdWJsaWMgT2JqZWN0IHJ1bigpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBCb29sZWFuKGYuZXhpc3RzKCkpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0pKS5ib29sZWFuVmFsdWUoKTsKLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9qYXZheC94bWwveHBhdGgvWFBhdGguamF2YSBiL3NyYy9qYXZheC94bWwveHBhdGgvWFBhdGguamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOTBiYTRmZS4uMDAwMDAwMAotLS0gYS9zcmMvamF2YXgveG1sL3hwYXRoL1hQYXRoLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzMTkgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwMywgMjAwNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotcGFja2FnZSBqYXZheC54bWwueHBhdGg7Ci0KLWltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKLWltcG9ydCBqYXZheC54bWwubmFtZXNwYWNlLlFOYW1lOwotaW1wb3J0IGphdmF4LnhtbC5uYW1lc3BhY2UuTmFtZXNwYWNlQ29udGV4dDsKLQotLyoqCi0gKiA8cD48Y29kZT5YUGF0aDwvY29kZT4gcHJvdmlkZXMgYWNjZXNzIHRvIHRoZSBYUGF0aCBldmFsdWF0aW9uIGVudmlyb25tZW50IGFuZCBleHByZXNzaW9ucy48L3A+Ci0gKgotICogPGEgbmFtZT0iWFBhdGgtZXZhbHVhdGlvbiIvPgotICogPHRhYmxlIGJvcmRlcj0iMSIgY2VsbHBhZGRpbmc9IjIiPgotICogICA8dGhlYWQ+Ci0gKiAgICAgPHRyPgotICogICAgICAgPHRoIGNvbHNwYW49IjIiPkV2YWx1YXRpb24gb2YgWFBhdGggRXhwcmVzc2lvbnMuPC90aD4KLSAqICAgICA8L3RyPgotICogICA8L3RoZWFkPgotICogICA8dGJvZHk+Ci0gKiAgICAgPHRyPgotICogICAgICAgPHRkPmNvbnRleHQ8L3RkPgotICogICAgICAgPHRkPgotICogICAgICAgICBJZiBhIHJlcXVlc3QgaXMgbWFkZSB0byBldmFsdWF0ZSB0aGUgZXhwcmVzc2lvbiBpbiB0aGUgYWJzZW5jZQotICogb2YgYSBjb250ZXh0IGl0ZW0sIGFuIGVtcHR5IGRvY3VtZW50IG5vZGUgd2lsbCBiZSB1c2VkIGZvciB0aGUgY29udGV4dC4KLSAqIEZvciB0aGUgcHVycG9zZXMgb2YgZXZhbHVhdGluZyBYUGF0aCBleHByZXNzaW9ucywgYSBEb2N1bWVudEZyYWdtZW50Ci0gKiBpcyB0cmVhdGVkIGxpa2UgYSBEb2N1bWVudCBub2RlLgotICogICAgICA8L3RkPgotICogICAgPC90cj4KLSAqICAgIDx0cj4KLSAqICAgICAgPHRkPnZhcmlhYmxlczwvdGQ+Ci0gKiAgICAgIDx0ZD4KLSAqICAgICAgICBJZiB0aGUgZXhwcmVzc2lvbiBjb250YWlucyBhIHZhcmlhYmxlIHJlZmVyZW5jZSwgaXRzIHZhbHVlIHdpbGwgYmUgZm91bmQgdGhyb3VnaCB0aGUge0BsaW5rIFhQYXRoVmFyaWFibGVSZXNvbHZlcn0KLSAqICAgICAgICBzZXQgd2l0aCB7QGxpbmsgI3NldFhQYXRoVmFyaWFibGVSZXNvbHZlcihYUGF0aFZhcmlhYmxlUmVzb2x2ZXIgcmVzb2x2ZXIpfS4KLSAqICAgICAgICBBbiB7QGxpbmsgWFBhdGhFeHByZXNzaW9uRXhjZXB0aW9ufSBpcyByYWlzZWQgaWYgdGhlIHZhcmlhYmxlIHJlc29sdmVyIGlzIHVuZGVmaW5lZCBvcgotICogICAgICAgIHRoZSByZXNvbHZlciByZXR1cm5zIDxjb2RlPm51bGw8L2NvZGU+IGZvciB0aGUgdmFyaWFibGUuCi0gKiAgICAgICAgVGhlIHZhbHVlIG9mIGEgdmFyaWFibGUgbXVzdCBiZSBpbW11dGFibGUgdGhyb3VnaCB0aGUgY291cnNlIG9mIGFueSBzaW5nbGUgZXZhbHVhdGlvbi48L3A+Ci0gKiAgICAgIDwvdGQ+Ci0gKiAgICA8L3RyPgotICogICAgPHRyPgotICogICAgICA8dGQ+ZnVuY3Rpb25zPC90ZD4KLSAqICAgICAgPHRkPgotICogICAgICAgIElmIHRoZSBleHByZXNzaW9uIGNvbnRhaW5zIGEgZnVuY3Rpb24gcmVmZXJlbmNlLCB0aGUgZnVuY3Rpb24gd2lsbCBiZSBmb3VuZCB0aHJvdWdoIHRoZSB7QGxpbmsgWFBhdGhGdW5jdGlvblJlc29sdmVyfQotICogICAgICAgIHNldCB3aXRoIHtAbGluayAjc2V0WFBhdGhGdW5jdGlvblJlc29sdmVyKFhQYXRoRnVuY3Rpb25SZXNvbHZlciByZXNvbHZlcil9LgotICogICAgICAgIEFuIHtAbGluayBYUGF0aEV4cHJlc3Npb25FeGNlcHRpb259IGlzIHJhaXNlZCBpZiB0aGUgZnVuY3Rpb24gcmVzb2x2ZXIgaXMgdW5kZWZpbmVkIG9yCi0gKiAgICAgICAgdGhlIGZ1bmN0aW9uIHJlc29sdmVyIHJldHVybnMgPGNvZGU+bnVsbDwvY29kZT4gZm9yIHRoZSBmdW5jdGlvbi48L3A+Ci0gKiAgICAgIDwvdGQ+Ci0gKiAgICA8L3RyPgotICogICAgPHRyPgotICogICAgICA8dGQ+UU5hbWVzPC90ZD4KLSAqICAgICAgPHRkPgotICogICAgICAgIFFOYW1lcyBpbiB0aGUgZXhwcmVzc2lvbiBhcmUgcmVzb2x2ZWQgYWdhaW5zdCB0aGUgWFBhdGggbmFtZXNwYWNlIGNvbnRleHQKLSAqICAgICAgICBzZXQgd2l0aCB7QGxpbmsgI3NldE5hbWVzcGFjZUNvbnRleHQoTmFtZXNwYWNlQ29udGV4dCBuc0NvbnRleHQpfS4KLSAqICAgICAgPC90ZD4KLSAqICAgIDwvdHI+Ci0gKiAgICA8dHI+Ci0gKiAgICAgIDx0ZD5yZXN1bHQ8L3RkPgotICogICAgICA8dGQ+Ci0gKiAgICAgICAgVGhpcyByZXN1bHQgb2YgZXZhbHVhdGluZyBhbiBleHByZXNzaW9uIGlzIGNvbnZlcnRlZCB0byBhbiBpbnN0YW5jZSBvZiB0aGUgZGVzaXJlZCByZXR1cm4gdHlwZS4KLSAqICAgICAgICBWYWxpZCByZXR1cm4gdHlwZXMgYXJlIGRlZmluZWQgaW4ge0BsaW5rIFhQYXRoQ29uc3RhbnRzfS4KLSAqICAgICAgICBDb252ZXJzaW9uIHRvIHRoZSByZXR1cm4gdHlwZSBmb2xsb3dzIFhQYXRoIGNvbnZlcnNpb24gcnVsZXMuPC9wPgotICogICAgICA8L3RkPgotICogICAgPC90cj4KLSAqIDwvdGFibGU+Ci0gKgotICogPHA+QW4gWFBhdGggb2JqZWN0IGlzIG5vdCB0aHJlYWQtc2FmZSBhbmQgbm90IHJlZW50cmFudC4KLSAqIEluIG90aGVyIHdvcmRzLCBpdCBpcyB0aGUgYXBwbGljYXRpb24ncyByZXNwb25zaWJpbGl0eSB0byBtYWtlCi0gKiBzdXJlIHRoYXQgb25lIHtAbGluayBYUGF0aH0gb2JqZWN0IGlzIG5vdCB1c2VkIGZyb20KLSAqIG1vcmUgdGhhbiBvbmUgdGhyZWFkIGF0IGFueSBnaXZlbiB0aW1lLCBhbmQgd2hpbGUgdGhlIDxjb2RlPmV2YWx1YXRlPC9jb2RlPgotICogbWV0aG9kIGlzIGludm9rZWQsIGFwcGxpY2F0aW9ucyBtYXkgbm90IHJlY3Vyc2l2ZWx5IGNhbGwKLSAqIHRoZSA8Y29kZT5ldmFsdWF0ZTwvY29kZT4gbWV0aG9kLgotICogPHA+Ci0gKgotICogQGF1dGhvciAgPGEgaHJlZj0iTm9ybWFuLldhbHNoQFN1bi5jb20iPk5vcm1hbiBXYWxzaDwvYT4KLSAqIEBhdXRob3IgIDxhIGhyZWY9IkplZmYuU3V0dG9yQFN1bi5jb20iPkplZmYgU3V0dG9yPC9hPgotICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aCI+WE1MIFBhdGggTGFuZ3VhZ2UgKFhQYXRoKSBWZXJzaW9uIDEuMDwvYT4KLSAqIEBzaW5jZSAxLjUKLSAqLwotcHVibGljIGludGVyZmFjZSBYUGF0aCB7Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIDxwPlJlc2V0IHRoaXMgPGNvZGU+WFBhdGg8L2NvZGU+IHRvIGl0cyBvcmlnaW5hbCBjb25maWd1cmF0aW9uLjwvcD4KLSAgICAgICAgICoKLSAgICAgICAgICogPHA+PGNvZGU+WFBhdGg8L2NvZGU+IGlzIHJlc2V0IHRvIHRoZSBzYW1lIHN0YXRlIGFzIHdoZW4gaXQgd2FzIGNyZWF0ZWQgd2l0aAotICAgICAgICAgKiB7QGxpbmsgWFBhdGhGYWN0b3J5I25ld1hQYXRoKCl9LgotICAgICAgICAgKiA8Y29kZT5yZXNldCgpPC9jb2RlPiBpcyBkZXNpZ25lZCB0byBhbGxvdyB0aGUgcmV1c2Ugb2YgZXhpc3RpbmcgPGNvZGU+WFBhdGg8L2NvZGU+cwotICAgICAgICAgKiB0aHVzIHNhdmluZyByZXNvdXJjZXMgYXNzb2NpYXRlZCB3aXRoIHRoZSBjcmVhdGlvbiBvZiBuZXcgPGNvZGU+WFBhdGg8L2NvZGU+cy48L3A+Ci0gICAgICAgICAqCi0gICAgICAgICAqIDxwPlRoZSByZXNldCA8Y29kZT5YUGF0aDwvY29kZT4gaXMgbm90IGd1YXJhbnRlZWQgdG8gaGF2ZSB0aGUgc2FtZSB7QGxpbmsgWFBhdGhGdW5jdGlvblJlc29sdmVyfSwge0BsaW5rIFhQYXRoVmFyaWFibGVSZXNvbHZlcn0KLSAgICAgICAgICogb3Ige0BsaW5rIE5hbWVzcGFjZUNvbnRleHR9IDxjb2RlPk9iamVjdDwvY29kZT5zLCBlLmcuIHtAbGluayBPYmplY3QjZXF1YWxzKE9iamVjdCBvYmopfS4KLSAgICAgICAgICogSXQgaXMgZ3VhcmFudGVlZCB0byBoYXZlIGEgZnVuY3Rpb25hbGx5IGVxdWFsIDxjb2RlPlhQYXRoRnVuY3Rpb25SZXNvbHZlcjwvY29kZT4sIDxjb2RlPlhQYXRoVmFyaWFibGVSZXNvbHZlcjwvY29kZT4KLSAgICAgICAgICogYW5kIDxjb2RlPk5hbWVzcGFjZUNvbnRleHQ8L2NvZGU+LjwvcD4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyB2b2lkIHJlc2V0KCk7Ci0KLSAgICAvKioKLSAgICAgKiA8cD5Fc3RhYmxpc2ggYSB2YXJpYWJsZSByZXNvbHZlci48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5BIDxjb2RlPk51bGxQb2ludGVyRXhjZXB0aW9uPC9jb2RlPiBpcyB0aHJvd24gaWYgPGNvZGU+cmVzb2x2ZXI8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSByZXNvbHZlciBWYXJpYWJsZSByZXNvbHZlci4KLSAgICAgKgotICAgICAqICBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIElmIDxjb2RlPnJlc29sdmVyPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRYUGF0aFZhcmlhYmxlUmVzb2x2ZXIoWFBhdGhWYXJpYWJsZVJlc29sdmVyIHJlc29sdmVyKTsKLQotICAgIC8qKgotICAgICAgICogPHA+UmV0dXJuIHRoZSBjdXJyZW50IHZhcmlhYmxlIHJlc29sdmVyLjwvcD4KLSAgICAgICAqCi0gICAgICAgKiA8cD48Y29kZT5udWxsPC9jb2RlPiBpcyByZXR1cm5lZCBpbiBubyB2YXJpYWJsZSByZXNvbHZlciBpcyBpbiBlZmZlY3QuPC9wPgotICAgICAgICoKLSAgICAgICAqIEByZXR1cm4gQ3VycmVudCB2YXJpYWJsZSByZXNvbHZlci4KLSAgICAgICAqLwotICAgIHB1YmxpYyBYUGF0aFZhcmlhYmxlUmVzb2x2ZXIgZ2V0WFBhdGhWYXJpYWJsZVJlc29sdmVyKCk7Ci0KLSAgICAvKioKLSAgICAgICAqIDxwPkVzdGFibGlzaCBhIGZ1bmN0aW9uIHJlc29sdmVyLjwvcD4KLSAgICAgICAqCi0gICAgICAgKiA8cD5BIDxjb2RlPk51bGxQb2ludGVyRXhjZXB0aW9uPC9jb2RlPiBpcyB0aHJvd24gaWYgPGNvZGU+cmVzb2x2ZXI8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LjwvcD4KLSAgICAgICAqCi0gICAgICAgKiBAcGFyYW0gcmVzb2x2ZXIgWFBhdGggZnVuY3Rpb24gcmVzb2x2ZXIuCi0gICAgICAgKgotICAgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBJZiA8Y29kZT5yZXNvbHZlcjwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRYUGF0aEZ1bmN0aW9uUmVzb2x2ZXIoWFBhdGhGdW5jdGlvblJlc29sdmVyIHJlc29sdmVyKTsKLQotICAgIC8qKgotICAgICAgICogPHA+UmV0dXJuIHRoZSBjdXJyZW50IGZ1bmN0aW9uIHJlc29sdmVyLjwvcD4KLSAgICAgICAqCi0gICAgICAgKiA8cD48Y29kZT5udWxsPC9jb2RlPiBpcyByZXR1cm5lZCBpbiBubyBmdW5jdGlvbiByZXNvbHZlciBpcyBpbiBlZmZlY3QuPC9wPgotICAgICAgICoKLSAgICAgICAqIEByZXR1cm4gQ3VycmVudCBmdW5jdGlvbiByZXNvbHZlci4KLSAgICAgICAqLwotICAgIHB1YmxpYyBYUGF0aEZ1bmN0aW9uUmVzb2x2ZXIgZ2V0WFBhdGhGdW5jdGlvblJlc29sdmVyKCk7Ci0KLSAgICAvKioKLSAgICAgICAqIDxwPkVzdGFibGlzaCBhIG5hbWVzcGFjZSBjb250ZXh0LjwvcD4KLSAgICAgICAqCi0gICAgICAgKiA8cD5BIDxjb2RlPk51bGxQb2ludGVyRXhjZXB0aW9uPC9jb2RlPiBpcyB0aHJvd24gaWYgPGNvZGU+bnNDb250ZXh0PC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPi48L3A+Ci0gICAgICAgKgotICAgICAgICogQHBhcmFtIG5zQ29udGV4dCBOYW1lc3BhY2UgY29udGV4dCB0byB1c2UuCi0gICAgICAgKgotICAgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBJZiA8Y29kZT5uc0NvbnRleHQ8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0TmFtZXNwYWNlQ29udGV4dChOYW1lc3BhY2VDb250ZXh0IG5zQ29udGV4dCk7Ci0KLSAgICAvKioKLSAgICAgICAqIDxwPlJldHVybiB0aGUgY3VycmVudCBuYW1lc3BhY2UgY29udGV4dC48L3A+Ci0gICAgICAgKgotICAgICAgICogPHA+PGNvZGU+bnVsbDwvY29kZT4gaXMgcmV0dXJuZWQgaW4gbm8gbmFtZXNwYWNlIGNvbnRleHQgaXMgaW4gZWZmZWN0LjwvcD4KLSAgICAgICAqCi0gICAgICAgKiBAcmV0dXJuIEN1cnJlbnQgTmFtZXNwYWNlIGNvbnRleHQuCi0gICAgICAgKi8KLSAgICBwdWJsaWMgTmFtZXNwYWNlQ29udGV4dCBnZXROYW1lc3BhY2VDb250ZXh0KCk7Ci0KLSAgICAvKioKLSAgICAgICAqIDxwPkNvbXBpbGUgYW4gWFBhdGggZXhwcmVzc2lvbiBmb3IgbGF0ZXIgZXZhbHVhdGlvbi48L3A+Ci0gICAgICAgKgotICAgICAgICogPHA+SWYgPGNvZGU+ZXhwcmVzc2lvbjwvY29kZT4gY29udGFpbnMgYW55IHtAbGluayBYUGF0aEZ1bmN0aW9ufXMsCi0gICAgICAgKiB0aGV5IG11c3QgYmUgYXZhaWxhYmxlIHZpYSB0aGUge0BsaW5rIFhQYXRoRnVuY3Rpb25SZXNvbHZlcn0uCi0gICAgICAgKiBBbiB7QGxpbmsgWFBhdGhFeHByZXNzaW9uRXhjZXB0aW9ufSB3aWxsIGJlIHRocm93biBpZiB0aGUKLSAgICAgICAqIDxjb2RlPlhQYXRoRnVuY3Rpb248L2NvZGU+Ci0gICAgICAgKiBjYW5ub3QgYmUgcmVzb3ZsZWQgd2l0aCB0aGUgPGNvZGU+WFBhdGhGdW5jdGlvblJlc29sdmVyPC9jb2RlPi48L3A+Ci0gICAgICAgKgotICAgICAgICogPHA+SWYgPGNvZGU+ZXhwcmVzc2lvbjwvY29kZT4gY29udGFpbnMgYW55IHZhcmlhYmxlcywgdGhlCi0gICAgICAgKiB7QGxpbmsgWFBhdGhWYXJpYWJsZVJlc29sdmVyfSBpbiBlZmZlY3QKLSAgICAgICAqIDxzdHJvbmc+YXQgY29tcGlsZSB0aW1lPC9zdHJvbmc+IHdpbGwgYmUgdXNlZCB0byByZXNvbHZlIHRoZW0uPC9wPgotICAgICAgICoKLSAgICAgICAqIDxwPklmIDxjb2RlPmV4cHJlc3Npb248L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LCBhIDxjb2RlPk51bGxQb2ludGVyRXhjZXB0aW9uPC9jb2RlPiBpcyB0aHJvd24uPC9wPgotICAgICAgICoKLSAgICAgICAqIEBwYXJhbSBleHByZXNzaW9uIFRoZSBYUGF0aCBleHByZXNzaW9uLgotICAgICAgICoKLSAgICAgICAqIEByZXR1cm4gQ29tcGlsZWQgWFBhdGggZXhwcmVzc2lvbi4KLQotICAgICAgICogQHRocm93cyBYUGF0aEV4cHJlc3Npb25FeGNlcHRpb24gSWYgPGNvZGU+ZXhwcmVzc2lvbjwvY29kZT4gY2Fubm90IGJlIGNvbXBpbGVkLgotICAgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBJZiA8Y29kZT5leHByZXNzaW9uPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICAgICAqLwotICAgIHB1YmxpYyBYUGF0aEV4cHJlc3Npb24gY29tcGlsZShTdHJpbmcgZXhwcmVzc2lvbikKLSAgICAgICAgdGhyb3dzIFhQYXRoRXhwcmVzc2lvbkV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIDxwPkV2YWx1YXRlIGFuIDxjb2RlPlhQYXRoPC9jb2RlPiBleHByZXNzaW9uIGluIHRoZSBzcGVjaWZpZWQgY29udGV4dCBhbmQgcmV0dXJuIHRoZSByZXN1bHQgYXMgdGhlIHNwZWNpZmllZCB0eXBlLjwvcD4KLSAgICAgKgotICAgICAqIDxwPlNlZSA8YSBocmVmPSIjWFBhdGgtZXZhbHVhdGlvbiI+RXZhbHVhdGlvbiBvZiBYUGF0aCBFeHByZXNzaW9uczwvYT4gZm9yIGNvbnRleHQgaXRlbSBldmFsdWF0aW9uLAotICAgICAqIHZhcmlhYmxlLCBmdW5jdGlvbiBhbmQgPGNvZGU+UU5hbWU8L2NvZGU+IHJlc29sdXRpb24gYW5kIHJldHVybiB0eXBlIGNvbnZlcnNpb24uPC9wPgotICAgICAqCi0gICAgICogPHA+SWYgPGNvZGU+cmV0dXJuVHlwZTwvY29kZT4gaXMgbm90IG9uZSBvZiB0aGUgdHlwZXMgZGVmaW5lZCBpbiB7QGxpbmsgWFBhdGhDb25zdGFudHN9ICgKLSAgICAgKiB7QGxpbmsgWFBhdGhDb25zdGFudHMjTlVNQkVSIE5VTUJFUn0sCi0gICAgICoge0BsaW5rIFhQYXRoQ29uc3RhbnRzI1NUUklORyBTVFJJTkd9LAotICAgICAqIHtAbGluayBYUGF0aENvbnN0YW50cyNCT09MRUFOIEJPT0xFQU59LAotICAgICAqIHtAbGluayBYUGF0aENvbnN0YW50cyNOT0RFIE5PREV9IG9yCi0gICAgICoge0BsaW5rIFhQYXRoQ29uc3RhbnRzI05PREVTRVQgTk9ERVNFVH0pCi0gICAgICogdGhlbiBhbiA8Y29kZT5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb248L2NvZGU+IGlzIHRocm93bi48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5JZiBhIDxjb2RlPm51bGw8L2NvZGU+IHZhbHVlIGlzIHByb3ZpZGVkIGZvcgotICAgICAqIDxjb2RlPml0ZW08L2NvZGU+LCBhbiBlbXB0eSBkb2N1bWVudCB3aWxsIGJlIHVzZWQgZm9yIHRoZQotICAgICAqIGNvbnRleHQuCi0gICAgICogSWYgPGNvZGU+ZXhwcmVzc2lvbjwvY29kZT4gb3IgPGNvZGU+cmV0dXJuVHlwZTwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4sIHRoZW4gYQotICAgICAqIDxjb2RlPk51bGxQb2ludGVyRXhjZXB0aW9uPC9jb2RlPiBpcyB0aHJvd24uPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGV4cHJlc3Npb24gVGhlIFhQYXRoIGV4cHJlc3Npb24uCi0gICAgICogQHBhcmFtIGl0ZW0gVGhlIHN0YXJ0aW5nIGNvbnRleHQgKGEgbm9kZSwgZm9yIGV4YW1wbGUpLgotICAgICAqIEBwYXJhbSByZXR1cm5UeXBlIFRoZSBkZXNpcmVkIHJldHVybiB0eXBlLgotICAgICAqCi0gICAgICogQHJldHVybiBSZXN1bHQgb2YgZXZhbHVhdGluZyBhbiBYUGF0aCBleHByZXNzaW9uIGFzIGFuIDxjb2RlPk9iamVjdDwvY29kZT4gb2YgPGNvZGU+cmV0dXJuVHlwZTwvY29kZT4uCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhQYXRoRXhwcmVzc2lvbkV4Y2VwdGlvbiBJZiA8Y29kZT5leHByZXNzaW9uPC9jb2RlPiBjYW5ub3QgYmUgZXZhbHVhdGVkLgotICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIElmIDxjb2RlPnJldHVyblR5cGU8L2NvZGU+IGlzIG5vdCBvbmUgb2YgdGhlIHR5cGVzIGRlZmluZWQgaW4ge0BsaW5rIFhQYXRoQ29uc3RhbnRzfS4KLSAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIElmIDxjb2RlPmV4cHJlc3Npb248L2NvZGU+IG9yIDxjb2RlPnJldHVyblR5cGU8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBPYmplY3QgZXZhbHVhdGUoU3RyaW5nIGV4cHJlc3Npb24sIE9iamVjdCBpdGVtLCBRTmFtZSByZXR1cm5UeXBlKQotICAgICAgICB0aHJvd3MgWFBhdGhFeHByZXNzaW9uRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogPHA+RXZhbHVhdGUgYW4gWFBhdGggZXhwcmVzc2lvbiBpbiB0aGUgc3BlY2lmaWVkIGNvbnRleHQgYW5kIHJldHVybiB0aGUgcmVzdWx0IGFzIGEgPGNvZGU+U3RyaW5nPC9jb2RlPi48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5UaGlzIG1ldGhvZCBjYWxscyB7QGxpbmsgI2V2YWx1YXRlKFN0cmluZyBleHByZXNzaW9uLCBPYmplY3QgaXRlbSwgUU5hbWUgcmV0dXJuVHlwZSl9IHdpdGggYSA8Y29kZT5yZXR1cm5UeXBlPC9jb2RlPiBvZgotICAgICAqIHtAbGluayBYUGF0aENvbnN0YW50cyNTVFJJTkd9LjwvcD4KLSAgICAgKgotICAgICAqIDxwPlNlZSA8YSBocmVmPSIjWFBhdGgtZXZhbHVhdGlvbiI+RXZhbHVhdGlvbiBvZiBYUGF0aCBFeHByZXNzaW9uczwvYT4gZm9yIGNvbnRleHQgaXRlbSBldmFsdWF0aW9uLAotICAgICAqIHZhcmlhYmxlLCBmdW5jdGlvbiBhbmQgUU5hbWUgcmVzb2x1dGlvbiBhbmQgcmV0dXJuIHR5cGUgY29udmVyc2lvbi48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5JZiBhIDxjb2RlPm51bGw8L2NvZGU+IHZhbHVlIGlzIHByb3ZpZGVkIGZvcgotICAgICAqIDxjb2RlPml0ZW08L2NvZGU+LCBhbiBlbXB0eSBkb2N1bWVudCB3aWxsIGJlIHVzZWQgZm9yIHRoZQotICAgICAqIGNvbnRleHQuCi0gICAgICogSWYgPGNvZGU+ZXhwcmVzc2lvbjwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4sIHRoZW4gYSA8Y29kZT5OdWxsUG9pbnRlckV4Y2VwdGlvbjwvY29kZT4gaXMgdGhyb3duLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBleHByZXNzaW9uIFRoZSBYUGF0aCBleHByZXNzaW9uLgotICAgICAqIEBwYXJhbSBpdGVtIFRoZSBzdGFydGluZyBjb250ZXh0IChhIG5vZGUsIGZvciBleGFtcGxlKS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIDxjb2RlPlN0cmluZzwvY29kZT4gdGhhdCBpcyB0aGUgcmVzdWx0IG9mIGV2YWx1YXRpbmcgdGhlIGV4cHJlc3Npb24gYW5kCi0gICAgICogICBjb252ZXJ0aW5nIHRoZSByZXN1bHQgdG8gYSA8Y29kZT5TdHJpbmc8L2NvZGU+LgotICAgICAqCi0gICAgICogQHRocm93cyBYUGF0aEV4cHJlc3Npb25FeGNlcHRpb24gSWYgPGNvZGU+ZXhwcmVzc2lvbjwvY29kZT4gY2Fubm90IGJlIGV2YWx1YXRlZC4KLSAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIElmIDxjb2RlPmV4cHJlc3Npb248L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZXZhbHVhdGUoU3RyaW5nIGV4cHJlc3Npb24sIE9iamVjdCBpdGVtKQotICAgICAgICB0aHJvd3MgWFBhdGhFeHByZXNzaW9uRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogPHA+RXZhbHVhdGUgYW4gWFBhdGggZXhwcmVzc2lvbiBpbiB0aGUgY29udGV4dCBvZiB0aGUgc3BlY2lmaWVkIDxjb2RlPklucHV0U291cmNlPC9jb2RlPgotICAgICAqIGFuZCByZXR1cm4gdGhlIHJlc3VsdCBhcyB0aGUgc3BlY2lmaWVkIHR5cGUuPC9wPgotICAgICAqCi0gICAgICogPHA+VGhpcyBtZXRob2QgYnVpbGRzIGEgZGF0YSBtb2RlbCBmb3IgdGhlIHtAbGluayBJbnB1dFNvdXJjZX0gYW5kIGNhbGxzCi0gICAgICoge0BsaW5rICNldmFsdWF0ZShTdHJpbmcgZXhwcmVzc2lvbiwgT2JqZWN0IGl0ZW0sIFFOYW1lIHJldHVyblR5cGUpfSBvbiB0aGUgcmVzdWx0aW5nIGRvY3VtZW50IG9iamVjdC48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5TZWUgPGEgaHJlZj0iI1hQYXRoLWV2YWx1YXRpb24iPkV2YWx1YXRpb24gb2YgWFBhdGggRXhwcmVzc2lvbnM8L2E+IGZvciBjb250ZXh0IGl0ZW0gZXZhbHVhdGlvbiwKLSAgICAgKiB2YXJpYWJsZSwgZnVuY3Rpb24gYW5kIFFOYW1lIHJlc29sdXRpb24gYW5kIHJldHVybiB0eXBlIGNvbnZlcnNpb24uPC9wPgotICAgICAqCi0gICAgICogPHA+SWYgPGNvZGU+cmV0dXJuVHlwZTwvY29kZT4gaXMgbm90IG9uZSBvZiB0aGUgdHlwZXMgZGVmaW5lZCBpbiB7QGxpbmsgWFBhdGhDb25zdGFudHN9LAotICAgICAqIHRoZW4gYW4gPGNvZGU+SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uPC9jb2RlPiBpcyB0aHJvd24uPC9wPgotICAgICAqCi0gICAgICogPHA+SWYgPGNvZGU+ZXhwcmVzc2lvbjwvY29kZT4sIDxjb2RlPnNvdXJjZTwvY29kZT4gb3IgPGNvZGU+cmV0dXJuVHlwZTwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4sCi0gICAgICogdGhlbiBhIDxjb2RlPk51bGxQb2ludGVyRXhjZXB0aW9uPC9jb2RlPiBpcyB0aHJvd24uPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGV4cHJlc3Npb24gVGhlIFhQYXRoIGV4cHJlc3Npb24uCi0gICAgICogQHBhcmFtIHNvdXJjZSBUaGUgaW5wdXQgc291cmNlIG9mIHRoZSBkb2N1bWVudCB0byBldmFsdWF0ZSBvdmVyLgotICAgICAqIEBwYXJhbSByZXR1cm5UeXBlIFRoZSBkZXNpcmVkIHJldHVybiB0eXBlLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgPGNvZGU+T2JqZWN0PC9jb2RlPiB0aGF0IGVuY2Fwc3VsYXRlcyB0aGUgcmVzdWx0IG9mIGV2YWx1YXRpbmcgdGhlIGV4cHJlc3Npb24uCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhQYXRoRXhwcmVzc2lvbkV4Y2VwdGlvbiBJZiBleHByZXNzaW9uIGNhbm5vdCBiZSBldmFsdWF0ZWQuCi0gICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gSWYgPGNvZGU+cmV0dXJuVHlwZTwvY29kZT4gaXMgbm90IG9uZSBvZiB0aGUgdHlwZXMgZGVmaW5lZCBpbiB7QGxpbmsgWFBhdGhDb25zdGFudHN9LgotICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gSWYgPGNvZGU+ZXhwcmVzc2lvbjwvY29kZT4sIDxjb2RlPnNvdXJjZTwvY29kZT4gb3IgPGNvZGU+cmV0dXJuVHlwZTwvY29kZT4KLSAgICAgKiAgIGlzIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBPYmplY3QgZXZhbHVhdGUoCi0gICAgICAgIFN0cmluZyBleHByZXNzaW9uLAotICAgICAgICBJbnB1dFNvdXJjZSBzb3VyY2UsCi0gICAgICAgIFFOYW1lIHJldHVyblR5cGUpCi0gICAgICAgIHRocm93cyBYUGF0aEV4cHJlc3Npb25FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiA8cD5FdmFsdWF0ZSBhbiBYUGF0aCBleHByZXNzaW9uIGluIHRoZSBjb250ZXh0IG9mIHRoZSBzcGVjaWZpZWQgPGNvZGU+SW5wdXRTb3VyY2U8L2NvZGU+Ci0gICAgICogYW5kIHJldHVybiB0aGUgcmVzdWx0IGFzIGEgPGNvZGU+U3RyaW5nPC9jb2RlPi48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5UaGlzIG1ldGhvZCBjYWxscyB7QGxpbmsgI2V2YWx1YXRlKFN0cmluZyBleHByZXNzaW9uLCBJbnB1dFNvdXJjZSBzb3VyY2UsIFFOYW1lIHJldHVyblR5cGUpfSB3aXRoIGEKLSAgICAgKiA8Y29kZT5yZXR1cm5UeXBlPC9jb2RlPiBvZiB7QGxpbmsgWFBhdGhDb25zdGFudHMjU1RSSU5HfS48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5TZWUgPGEgaHJlZj0iI1hQYXRoLWV2YWx1YXRpb24iPkV2YWx1YXRpb24gb2YgWFBhdGggRXhwcmVzc2lvbnM8L2E+IGZvciBjb250ZXh0IGl0ZW0gZXZhbHVhdGlvbiwKLSAgICAgKiB2YXJpYWJsZSwgZnVuY3Rpb24gYW5kIFFOYW1lIHJlc29sdXRpb24gYW5kIHJldHVybiB0eXBlIGNvbnZlcnNpb24uPC9wPgotICAgICAqCi0gICAgICogPHA+SWYgPGNvZGU+ZXhwcmVzc2lvbjwvY29kZT4gb3IgPGNvZGU+c291cmNlPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPiwKLSAgICAgKiB0aGVuIGEgPGNvZGU+TnVsbFBvaW50ZXJFeGNlcHRpb248L2NvZGU+IGlzIHRocm93bi48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gZXhwcmVzc2lvbiBUaGUgWFBhdGggZXhwcmVzc2lvbi4KLSAgICAgKiBAcGFyYW0gc291cmNlIFRoZSA8Y29kZT5JbnB1dFNvdXJjZTwvY29kZT4gb2YgdGhlIGRvY3VtZW50IHRvIGV2YWx1YXRlIG92ZXIuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSA8Y29kZT5TdHJpbmc8L2NvZGU+IHRoYXQgaXMgdGhlIHJlc3VsdCBvZiBldmFsdWF0aW5nIHRoZSBleHByZXNzaW9uIGFuZAotICAgICAqICAgY29udmVydGluZyB0aGUgcmVzdWx0IHRvIGEgPGNvZGU+U3RyaW5nPC9jb2RlPi4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWFBhdGhFeHByZXNzaW9uRXhjZXB0aW9uIElmIGV4cHJlc3Npb24gY2Fubm90IGJlIGV2YWx1YXRlZC4KLSAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIElmIDxjb2RlPmV4cHJlc3Npb248L2NvZGU+IG9yIDxjb2RlPnNvdXJjZTwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBldmFsdWF0ZShTdHJpbmcgZXhwcmVzc2lvbiwgSW5wdXRTb3VyY2Ugc291cmNlKQotICAgICAgICB0aHJvd3MgWFBhdGhFeHByZXNzaW9uRXhjZXB0aW9uOwotfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmF4L3htbC94cGF0aC9YUGF0aENvbnN0YW50cy5qYXZhIGIvc3JjL2phdmF4L3htbC94cGF0aC9YUGF0aENvbnN0YW50cy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyMDVlMDQxLi4wMDAwMDAwCi0tLSBhL3NyYy9qYXZheC94bWwveHBhdGgvWFBhdGhDb25zdGFudHMuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDg0ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDMsIDIwMDUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLXBhY2thZ2UgamF2YXgueG1sLnhwYXRoOwotCi1pbXBvcnQgamF2YXgueG1sLm5hbWVzcGFjZS5RTmFtZTsKLQotLyoqCi0gKiA8cD5YUGF0aCBjb25zdGFudHMuPC9wPgotICoKLSAqIEBhdXRob3IgPGEgaHJlZj0ibWFpbHRvOk5vcm1hbi5XYWxzaEBTdW4uQ09NIj5Ob3JtYW4gV2Fsc2g8L2E+Ci0gKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzpKZWZmLlN1dHRvckBTdW4uQ09NIj5KZWZmIFN1dHRvcjwvYT4KLSAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGgiPlhNTCBQYXRoIExhbmd1YWdlIChYUGF0aCkgVmVyc2lvbiAxLjA8L2E+Ci0gKiBAc2luY2UgMS41Ci0gKi8KLXB1YmxpYyBjbGFzcyBYUGF0aENvbnN0YW50cyB7Ci0KLSAgICAvKioKLSAgICAgKiA8cD5Qcml2YXRlIGNvbnN0cnVjdG9yIHRvIHByZXZlbnQgaW5zdGFudGlhdGlvbi48L3A+Ci0gICAgICovCi0gICAgcHJpdmF0ZSBYUGF0aENvbnN0YW50cygpIHsgfQotCi0gICAgLyoqCi0gICAgICogPHA+VGhlIFhQYXRoIDEuMCBudW1iZXIgZGF0YSB0eXBlLjwvcD4KLSAgICAgKgotICAgICAqIDxwPk1hcHMgdG8gSmF2YSB7QGxpbmsgRG91YmxlfS48L3A+Ci0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBRTmFtZSBOVU1CRVIgPSBuZXcgUU5hbWUoImh0dHA6Ly93d3cudzMub3JnLzE5OTkvWFNML1RyYW5zZm9ybSIsICJOVU1CRVIiKTsKLQotICAgIC8qKgotICAgICAqIDxwPlRoZSBYUGF0aCAxLjAgc3RyaW5nIGRhdGEgdHlwZS48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5NYXBzIHRvIEphdmEge0BsaW5rIFN0cmluZ30uPC9wPgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgUU5hbWUgU1RSSU5HID0gbmV3IFFOYW1lKCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L1hTTC9UcmFuc2Zvcm0iLCAiU1RSSU5HIik7Ci0KLSAgICAvKioKLSAgICAgKiA8cD5UaGUgWFBhdGggMS4wIGJvb2xlYW4gZGF0YSB0eXBlLjwvcD4KLSAgICAgKgotICAgICAqIDxwPk1hcHMgdG8gSmF2YSB7QGxpbmsgQm9vbGVhbn0uPC9wPgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgUU5hbWUgQk9PTEVBTiA9IG5ldyBRTmFtZSgiaHR0cDovL3d3dy53My5vcmcvMTk5OS9YU0wvVHJhbnNmb3JtIiwgIkJPT0xFQU4iKTsKLQotICAgIC8qKgotICAgICAqIDxwPlRoZSBYUGF0aCAxLjAgTm9kZVNldCBkYXRhIHR5cGUuPC9wPgotICAgICAqCi0gICAgICogPHA+TWFwcyB0byBKYXZhIHtAbGluayBvcmcudzNjLmRvbS5Ob2RlTGlzdH0uPC9wPgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgUU5hbWUgTk9ERVNFVCA9IG5ldyBRTmFtZSgiaHR0cDovL3d3dy53My5vcmcvMTk5OS9YU0wvVHJhbnNmb3JtIiwgIk5PREVTRVQiKTsKLQotICAgIC8qKgotICAgICAqIDxwPlRoZSBYUGF0aCAxLjAgTm9kZVNldCBkYXRhIHR5cGUuCi0gICAgICoKLSAgICAgKiA8cD5NYXBzIHRvIEphdmEge0BsaW5rIG9yZy53M2MuZG9tLk5vZGV9LjwvcD4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFFOYW1lIE5PREUgPSBuZXcgUU5hbWUoImh0dHA6Ly93d3cudzMub3JnLzE5OTkvWFNML1RyYW5zZm9ybSIsICJOT0RFIik7Ci0KLSAgICAvKioKLSAgICAgKiA8cD5UaGUgVVJJIGZvciB0aGUgRE9NIG9iamVjdCBtb2RlbCwgImh0dHA6Ly9qYXZhLnN1bi5jb20vamF4cC94cGF0aC9kb20iLjwvcD4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBET01fT0JKRUNUX01PREVMID0gImh0dHA6Ly9qYXZhLnN1bi5jb20vamF4cC94cGF0aC9kb20iOwotfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmF4L3htbC94cGF0aC9YUGF0aEV4Y2VwdGlvbi5qYXZhIGIvc3JjL2phdmF4L3htbC94cGF0aC9YUGF0aEV4Y2VwdGlvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlZTY4MDI4Li4wMDAwMDAwCi0tLSBhL3NyYy9qYXZheC94bWwveHBhdGgvWFBhdGhFeGNlcHRpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE3NiArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDEzLCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi1wYWNrYWdlIGphdmF4LnhtbC54cGF0aDsKLQotaW1wb3J0IGphdmEuaW8uUHJpbnRXcml0ZXI7Ci1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uT2JqZWN0T3V0cHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uT2JqZWN0U3RyZWFtRmllbGQ7Ci1pbXBvcnQgamF2YS5pby5JbnZhbGlkQ2xhc3NFeGNlcHRpb247Ci0KLS8qKgotICogPGNvZGU+WFBhdGhFeGNlcHRpb248L2NvZGU+IHJlcHJlc2VudHMgYSBnZW5lcmljIFhQYXRoIGV4Y2VwdGlvbi48L3A+Ci0gKgotICogQGF1dGhvciAgPGEgaHJlZj0iTm9ybWFuLldhbHNoQFN1bi5jb20iPk5vcm1hbiBXYWxzaDwvYT4KLSAqIEBhdXRob3IgPGEgaHJlZj0ibWFpbHRvOkplZmYuU3V0dG9yQFN1bi5DT00iPkplZmYgU3V0dG9yPC9hPgotICogQHNpbmNlIDEuNQotICovCi1wdWJsaWMgY2xhc3MgWFBhdGhFeGNlcHRpb24gZXh0ZW5kcyBFeGNlcHRpb24gewotCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgT2JqZWN0U3RyZWFtRmllbGRbXSBzZXJpYWxQZXJzaXN0ZW50RmllbGRzID0gewotICAgICAgICBuZXcgT2JqZWN0U3RyZWFtRmllbGQoICJjYXVzZSIsIFRocm93YWJsZS5jbGFzcyApCi0gICAgfTsKLQotICAgIC8qKgotICAgICAqIDxwPlN0cmVhbSBVbmlxdWUgSWRlbnRpZmllci48L3A+Ci0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTE4MzcwODAyNjAzNzQ5ODY5ODBMOwotCi0gICAgLyoqCi0gICAgICogPHA+Q29uc3RydWN0cyBhIG5ldyA8Y29kZT5YUGF0aEV4Y2VwdGlvbjwvY29kZT4KLSAgICAgKiB3aXRoIHRoZSBzcGVjaWZpZWQgZGV0YWlsIDxjb2RlPm1lc3NhZ2U8L2NvZGU+LjwvcD4KLSAgICAgKgotICAgICAqIDxwPlRoZSA8Y29kZT5jYXVzZTwvY29kZT4gaXMgbm90IGluaXRpYWxpemVkLjwvcD4KLSAgICAgKgotICAgICAqIDxwPklmIDxjb2RlPm1lc3NhZ2U8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LAotICAgICAqIHRoZW4gYSA8Y29kZT5OdWxsUG9pbnRlckV4Y2VwdGlvbjwvY29kZT4gaXMgdGhyb3duLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBtZXNzYWdlIFRoZSBkZXRhaWwgbWVzc2FnZS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gV2hlbiA8Y29kZT5tZXNzYWdlPC9jb2RlPiBpcwotICAgICAqICAgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIFhQYXRoRXhjZXB0aW9uKFN0cmluZyBtZXNzYWdlKSB7Ci0gICAgICAgIHN1cGVyKG1lc3NhZ2UpOwotICAgICAgICBpZiAoIG1lc3NhZ2UgPT0gbnVsbCApIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbiAoICJtZXNzYWdlIGNhbid0IGJlIG51bGwiKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPkNvbnN0cnVjdHMgYSBuZXcgPGNvZGU+WFBhdGhFeGNlcHRpb248L2NvZGU+Ci0gICAgICogd2l0aCB0aGUgc3BlY2lmaWVkIDxjb2RlPmNhdXNlPC9jb2RlPi48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5JZiA8Y29kZT5jYXVzZTwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4sCi0gICAgICogdGhlbiBhIDxjb2RlPk51bGxQb2ludGVyRXhjZXB0aW9uPC9jb2RlPiBpcyB0aHJvd24uPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGNhdXNlIFRoZSBjYXVzZS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgPGNvZGU+Y2F1c2U8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBYUGF0aEV4Y2VwdGlvbihUaHJvd2FibGUgY2F1c2UpIHsKLSAgICAgICAgc3VwZXIoY2F1c2UpOwotICAgICAgICBpZiAoIGNhdXNlID09IG51bGwgKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24gKCAiY2F1c2UgY2FuJ3QgYmUgbnVsbCIpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+R2V0IHRoZSBjYXVzZSBvZiB0aGlzIFhQYXRoRXhjZXB0aW9uLjwvcD4KLSAgICAgKgotICAgICAqIEByZXR1cm4gQ2F1c2Ugb2YgdGhpcyBYUGF0aEV4Y2VwdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgVGhyb3dhYmxlIGdldENhdXNlKCkgewotICAgICAgICByZXR1cm4gc3VwZXIuZ2V0Q2F1c2UoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBXcml0ZXMgImNhdXNlIiBmaWVsZCB0byB0aGUgc3RyZWFtLgotICAgICAqIFRoZSBjYXVzZSBpcyBnb3QgZnJvbSB0aGUgcGFyZW50IGNsYXNzLgotICAgICAqCi0gICAgICogQHBhcmFtIG91dCBzdHJlYW0gdXNlZCBmb3Igc2VyaWFsaXphdGlvbi4KLSAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIHRocm93biBieSA8Y29kZT5PYmplY3RPdXRwdXRTdHJlYW08L2NvZGU+Ci0gICAgICoKLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgd3JpdGVPYmplY3QoT2JqZWN0T3V0cHV0U3RyZWFtIG91dCkKLSAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgT2JqZWN0T3V0cHV0U3RyZWFtLlB1dEZpZWxkIGZpZWxkcyA9IG91dC5wdXRGaWVsZHMoKTsKLSAgICAgICAgZmllbGRzLnB1dCgiY2F1c2UiLCAoVGhyb3dhYmxlKSBzdXBlci5nZXRDYXVzZSgpKTsKLSAgICAgICAgb3V0LndyaXRlRmllbGRzKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmVhZHMgdGhlICJjYXVzZSIgZmllbGQgZnJvbSB0aGUgc3RyZWFtLgotICAgICAqIEFuZCBpbml0aWFsaXplcyB0aGUgImNhdXNlIiBpZiBpdCB3YXNuJ3QKLSAgICAgKiBkb25lIGJlZm9yZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBpbiBzdHJlYW0gdXNlZCBmb3IgZGVzZXJpYWxpemF0aW9uCi0gICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiB0aHJvd24gYnkgPGNvZGU+T2JqZWN0SW5wdXRTdHJlYW08L2NvZGU+Ci0gICAgICogQHRocm93cyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uICB0aHJvd24gYnkgPGNvZGU+T2JqZWN0SW5wdXRTdHJlYW08L2NvZGU+Ci0gICAgICovCi0gICAgcHJpdmF0ZSB2b2lkIHJlYWRPYmplY3QoT2JqZWN0SW5wdXRTdHJlYW0gaW4pCi0gICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIENsYXNzTm90Rm91bmRFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIE9iamVjdElucHV0U3RyZWFtLkdldEZpZWxkIGZpZWxkcyA9IGluLnJlYWRGaWVsZHMoKTsKLSAgICAgICAgVGhyb3dhYmxlIHNjYXVzZSA9IChUaHJvd2FibGUpIGZpZWxkcy5nZXQoImNhdXNlIiwgbnVsbCk7Ci0KLSAgICAgICAgaWYgKHN1cGVyLmdldENhdXNlKCkgPT0gbnVsbCAmJiBzY2F1c2UgIT0gbnVsbCkgewotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICBzdXBlci5pbml0Q2F1c2Uoc2NhdXNlKTsKLSAgICAgICAgICAgIH0gY2F0Y2goSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZENsYXNzRXhjZXB0aW9uKCJJbmNvbnNpc3RlbnQgc3RhdGU6IHR3byBjYXVzZXMiKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPlByaW50IHN0YWNrIHRyYWNlIHRvIHNwZWNpZmllZCA8Y29kZT5QcmludFN0cmVhbTwvY29kZT4uPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIHMgUHJpbnQgc3RhY2sgdHJhY2UgdG8gdGhpcyA8Y29kZT5QcmludFN0cmVhbTwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcHJpbnRTdGFja1RyYWNlKGphdmEuaW8uUHJpbnRTdHJlYW0gcykgewotICAgICAgICBpZiAoZ2V0Q2F1c2UoKSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBnZXRDYXVzZSgpLnByaW50U3RhY2tUcmFjZShzKTsKLSAgICAgICAgICBzLnByaW50bG4oIi0tLS0tLS0tLS0tLS0tLSBsaW5rZWQgdG8gLS0tLS0tLS0tLS0tLS0tLS0tIik7Ci0gICAgICAgIH0KLQotICAgICAgICBzdXBlci5wcmludFN0YWNrVHJhY2Uocyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+UHJpbnQgc3RhY2sgdHJhY2UgdG8gPGNvZGU+U3lzdGVtLmVycjwvY29kZT4uPC9wPgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHByaW50U3RhY2tUcmFjZSgpIHsKLSAgICAgICAgcHJpbnRTdGFja1RyYWNlKFN5c3RlbS5lcnIpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPlByaW50IHN0YWNrIHRyYWNlIHRvIHNwZWNpZmllZCA8Y29kZT5QcmludFdyaXRlcjwvY29kZT4uPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIHMgUHJpbnQgc3RhY2sgdHJhY2UgdG8gdGhpcyA8Y29kZT5QcmludFdyaXRlcjwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcHJpbnRTdGFja1RyYWNlKFByaW50V3JpdGVyIHMpIHsKLQotICAgICAgICBpZiAoZ2V0Q2F1c2UoKSAhPSBudWxsKSB7Ci0gICAgICAgICAgICBnZXRDYXVzZSgpLnByaW50U3RhY2tUcmFjZShzKTsKLSAgICAgICAgICBzLnByaW50bG4oIi0tLS0tLS0tLS0tLS0tLSBsaW5rZWQgdG8gLS0tLS0tLS0tLS0tLS0tLS0tIik7Ci0gICAgICAgIH0KLQotICAgICAgICBzdXBlci5wcmludFN0YWNrVHJhY2Uocyk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmF4L3htbC94cGF0aC9YUGF0aEV4cHJlc3Npb24uamF2YSBiL3NyYy9qYXZheC94bWwveHBhdGgvWFBhdGhFeHByZXNzaW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDBmOTgwZjYuLjAwMDAwMDAKLS0tIGEvc3JjL2phdmF4L3htbC94cGF0aC9YUGF0aEV4cHJlc3Npb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIwMCArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDA1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi1wYWNrYWdlIGphdmF4LnhtbC54cGF0aDsKLQotaW1wb3J0IG9yZy54bWwuc2F4LklucHV0U291cmNlOwotaW1wb3J0IGphdmF4LnhtbC5uYW1lc3BhY2UuUU5hbWU7Ci0KLS8qKgotICogPHA+PGNvZGU+WFBhdGhFeHByZXNzaW9uPC9jb2RlPiBwcm92aWRlcyBhY2Nlc3MgdG8gY29tcGlsZWQgWFBhdGggZXhwcmVzc2lvbnMuPC9wPgotICoKLSAqIDxhIG5hbWU9IlhQYXRoRXhwcmVzc2lvbi1ldmFsdWF0aW9uIi8+Ci0gKiA8dGFibGUgYm9yZGVyPSIxIiBjZWxscGFkZGluZz0iMiI+Ci0gKiAgIDx0aGVhZD4KLSAqICAgICA8dHI+Ci0gKiAgICAgICA8dGggY29sc3Bhbj0iMiI+RXZhbHVhdGlvbiBvZiBYUGF0aCBFeHByZXNzaW9ucy48L3RoPgotICogICAgIDwvdHI+Ci0gKiAgIDwvdGhlYWQ+Ci0gKiAgIDx0Ym9keT4KLSAqICAgICA8dHI+Ci0gKiAgICAgICA8dGQ+Y29udGV4dDwvdGQ+Ci0gKiAgICAgICA8dGQ+Ci0gKiAgICAgICAgIElmIGEgcmVxdWVzdCBpcyBtYWRlIHRvIGV2YWx1YXRlIHRoZSBleHByZXNzaW9uIGluIHRoZSBhYnNlbmNlCi0gKiBvZiBhIGNvbnRleHQgaXRlbSwgYW4gZW1wdHkgZG9jdW1lbnQgbm9kZSB3aWxsIGJlIHVzZWQgZm9yIHRoZSBjb250ZXh0LgotICogRm9yIHRoZSBwdXJwb3NlcyBvZiBldmFsdWF0aW5nIFhQYXRoIGV4cHJlc3Npb25zLCBhIERvY3VtZW50RnJhZ21lbnQKLSAqIGlzIHRyZWF0ZWQgbGlrZSBhIERvY3VtZW50IG5vZGUuCi0gKiAgICAgIDwvdGQ+Ci0gKiAgICA8L3RyPgotICogICAgPHRyPgotICogICAgICA8dGQ+dmFyaWFibGVzPC90ZD4KLSAqICAgICAgPHRkPgotICogICAgICAgIElmIHRoZSBleHByZXNzaW9uIGNvbnRhaW5zIGEgdmFyaWFibGUgcmVmZXJlbmNlLCBpdHMgdmFsdWUgd2lsbCBiZSBmb3VuZCB0aHJvdWdoIHRoZSB7QGxpbmsgWFBhdGhWYXJpYWJsZVJlc29sdmVyfS4KLSAqICAgICAgICBBbiB7QGxpbmsgWFBhdGhFeHByZXNzaW9uRXhjZXB0aW9ufSBpcyByYWlzZWQgaWYgdGhlIHZhcmlhYmxlIHJlc29sdmVyIGlzIHVuZGVmaW5lZCBvcgotICogICAgICAgIHRoZSByZXNvbHZlciByZXR1cm5zIDxjb2RlPm51bGw8L2NvZGU+IGZvciB0aGUgdmFyaWFibGUuCi0gKiAgICAgICAgVGhlIHZhbHVlIG9mIGEgdmFyaWFibGUgbXVzdCBiZSBpbW11dGFibGUgdGhyb3VnaCB0aGUgY291cnNlIG9mIGFueSBzaW5nbGUgZXZhbHVhdGlvbi48L3A+Ci0gKiAgICAgIDwvdGQ+Ci0gKiAgICA8L3RyPgotICogICAgPHRyPgotICogICAgICA8dGQ+ZnVuY3Rpb25zPC90ZD4KLSAqICAgICAgPHRkPgotICogICAgICAgIElmIHRoZSBleHByZXNzaW9uIGNvbnRhaW5zIGEgZnVuY3Rpb24gcmVmZXJlbmNlLCB0aGUgZnVuY3Rpb24gd2lsbCBiZSBmb3VuZCB0aHJvdWdoIHRoZSB7QGxpbmsgWFBhdGhGdW5jdGlvblJlc29sdmVyfS4KLSAqICAgICAgICBBbiB7QGxpbmsgWFBhdGhFeHByZXNzaW9uRXhjZXB0aW9ufSBpcyByYWlzZWQgaWYgdGhlIGZ1bmN0aW9uIHJlc29sdmVyIGlzIHVuZGVmaW5lZCBvcgotICogICAgICAgIHRoZSBmdW5jdGlvbiByZXNvbHZlciByZXR1cm5zIDxjb2RlPm51bGw8L2NvZGU+IGZvciB0aGUgZnVuY3Rpb24uPC9wPgotICogICAgICA8L3RkPgotICogICAgPC90cj4KLSAqICAgIDx0cj4KLSAqICAgICAgPHRkPlFOYW1lczwvdGQ+Ci0gKiAgICAgIDx0ZD4KLSAqICAgICAgICBRTmFtZXMgaW4gdGhlIGV4cHJlc3Npb24gYXJlIHJlc29sdmVkIGFnYWluc3QgdGhlIFhQYXRoIG5hbWVzcGFjZSBjb250ZXh0LgotICogICAgICA8L3RkPgotICogICAgPC90cj4KLSAqICAgIDx0cj4KLSAqICAgICAgPHRkPnJlc3VsdDwvdGQ+Ci0gKiAgICAgIDx0ZD4KLSAqICAgICAgICBUaGlzIHJlc3VsdCBvZiBldmFsdWF0aW5nIGFuIGV4cHJlc3Npb24gaXMgY29udmVydGVkIHRvIGFuIGluc3RhbmNlIG9mIHRoZSBkZXNpcmVkIHJldHVybiB0eXBlLgotICogICAgICAgIFZhbGlkIHJldHVybiB0eXBlcyBhcmUgZGVmaW5lZCBpbiB7QGxpbmsgWFBhdGhDb25zdGFudHN9LgotICogICAgICAgIENvbnZlcnNpb24gdG8gdGhlIHJldHVybiB0eXBlIGZvbGxvd3MgWFBhdGggY29udmVyc2lvbiBydWxlcy48L3A+Ci0gKiAgICAgIDwvdGQ+Ci0gKiAgICA8L3RyPgotICogPC90YWJsZT4KLSAqCi0gKiA8cD5BbiBYUGF0aCBleHByZXNzaW9uIGlzIG5vdCB0aHJlYWQtc2FmZSBhbmQgbm90IHJlZW50cmFudC4KLSAqIEluIG90aGVyIHdvcmRzLCBpdCBpcyB0aGUgYXBwbGljYXRpb24ncyByZXNwb25zaWJpbGl0eSB0byBtYWtlCi0gKiBzdXJlIHRoYXQgb25lIHtAbGluayBYUGF0aEV4cHJlc3Npb259IG9iamVjdCBpcyBub3QgdXNlZCBmcm9tCi0gKiBtb3JlIHRoYW4gb25lIHRocmVhZCBhdCBhbnkgZ2l2ZW4gdGltZSwgYW5kIHdoaWxlIHRoZSA8Y29kZT5ldmFsdWF0ZTwvY29kZT4KLSAqIG1ldGhvZCBpcyBpbnZva2VkLCBhcHBsaWNhdGlvbnMgbWF5IG5vdCByZWN1cnNpdmVseSBjYWxsCi0gKiB0aGUgPGNvZGU+ZXZhbHVhdGU8L2NvZGU+IG1ldGhvZC4KLSAqIDxwPgotICoKLSAqIEBhdXRob3IgIDxhIGhyZWY9Im1haWx0bzpOb3JtYW4uV2Fsc2hAU3VuLmNvbSI+Tm9ybWFuIFdhbHNoPC9hPgotICogQGF1dGhvciAgPGEgaHJlZj0ibWFpbHRvOkplZmYuU3V0dG9yQFN1bi5jb20iPkplZmYgU3V0dG9yPC9hPgotICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aCNzZWN0aW9uLUV4cHJlc3Npb25zIj5YTUwgUGF0aCBMYW5ndWFnZSAoWFBhdGgpIFZlcnNpb24gMS4wLCBFeHByZXNzaW9uczwvYT4KLSAqIEBzaW5jZSAxLjUKLSAqLwotcHVibGljIGludGVyZmFjZSBYUGF0aEV4cHJlc3Npb24gewotCi0gICAgLyoqCi0gICAgICogPHA+RXZhbHVhdGUgdGhlIGNvbXBpbGVkIFhQYXRoIGV4cHJlc3Npb24gaW4gdGhlIHNwZWNpZmllZCBjb250ZXh0IGFuZCByZXR1cm4gdGhlIHJlc3VsdCBhcyB0aGUgc3BlY2lmaWVkIHR5cGUuPC9wPgotICAgICAqCi0gICAgICogPHA+U2VlIDxhIGhyZWY9IiNYUGF0aEV4cHJlc3Npb24tZXZhbHVhdGlvbiI+RXZhbHVhdGlvbiBvZiBYUGF0aCBFeHByZXNzaW9uczwvYT4gZm9yIGNvbnRleHQgaXRlbSBldmFsdWF0aW9uLAotICAgICAqIHZhcmlhYmxlLCBmdW5jdGlvbiBhbmQgUU5hbWUgcmVzb2x1dGlvbiBhbmQgcmV0dXJuIHR5cGUgY29udmVyc2lvbi48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5JZiA8Y29kZT5yZXR1cm5UeXBlPC9jb2RlPiBpcyBub3Qgb25lIG9mIHRoZSB0eXBlcyBkZWZpbmVkIGluIHtAbGluayBYUGF0aENvbnN0YW50c30sCi0gICAgICogdGhlbiBhbiA8Y29kZT5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb248L2NvZGU+IGlzIHRocm93bi48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5JZiBhIDxjb2RlPm51bGw8L2NvZGU+IHZhbHVlIGlzIHByb3ZpZGVkIGZvcgotICAgICAqIDxjb2RlPml0ZW08L2NvZGU+LCBhbiBlbXB0eSBkb2N1bWVudCB3aWxsIGJlIHVzZWQgZm9yIHRoZQotICAgICAqIGNvbnRleHQuCi0gICAgICogSWYgPGNvZGU+cmV0dXJuVHlwZTwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4sIHRoZW4gYSA8Y29kZT5OdWxsUG9pbnRlckV4Y2VwdGlvbjwvY29kZT4gaXMgdGhyb3duLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBpdGVtIFRoZSBzdGFydGluZyBjb250ZXh0IChhIG5vZGUsIGZvciBleGFtcGxlKS4KLSAgICAgKiBAcGFyYW0gcmV0dXJuVHlwZSBUaGUgZGVzaXJlZCByZXR1cm4gdHlwZS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIDxjb2RlPk9iamVjdDwvY29kZT4gdGhhdCBpcyB0aGUgcmVzdWx0IG9mIGV2YWx1YXRpbmcgdGhlIGV4cHJlc3Npb24gYW5kIGNvbnZlcnRpbmcgdGhlIHJlc3VsdCB0bwotICAgICAqICAgPGNvZGU+cmV0dXJuVHlwZTwvY29kZT4uCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhQYXRoRXhwcmVzc2lvbkV4Y2VwdGlvbiBJZiB0aGUgZXhwcmVzc2lvbiBjYW5ub3QgYmUgZXZhbHVhdGVkLgotICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIElmIDxjb2RlPnJldHVyblR5cGU8L2NvZGU+IGlzIG5vdCBvbmUgb2YgdGhlIHR5cGVzIGRlZmluZWQgaW4ge0BsaW5rIFhQYXRoQ29uc3RhbnRzfS4KLSAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIElmICA8Y29kZT5yZXR1cm5UeXBlPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0IGV2YWx1YXRlKE9iamVjdCBpdGVtLCBRTmFtZSByZXR1cm5UeXBlKQotICAgICAgICB0aHJvd3MgWFBhdGhFeHByZXNzaW9uRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogPHA+RXZhbHVhdGUgdGhlIGNvbXBpbGVkIFhQYXRoIGV4cHJlc3Npb24gaW4gdGhlIHNwZWNpZmllZCBjb250ZXh0IGFuZCByZXR1cm4gdGhlIHJlc3VsdCBhcyBhIDxjb2RlPlN0cmluZzwvY29kZT4uPC9wPgotICAgICAqCi0gICAgICogPHA+VGhpcyBtZXRob2QgY2FsbHMge0BsaW5rICNldmFsdWF0ZShPYmplY3QgaXRlbSwgUU5hbWUgcmV0dXJuVHlwZSl9IHdpdGggYSA8Y29kZT5yZXR1cm5UeXBlPC9jb2RlPiBvZgotICAgICAqIHtAbGluayBYUGF0aENvbnN0YW50cyNTVFJJTkd9LjwvcD4KLSAgICAgKgotICAgICAqIDxwPlNlZSA8YSBocmVmPSIjWFBhdGhFeHByZXNzaW9uLWV2YWx1YXRpb24iPkV2YWx1YXRpb24gb2YgWFBhdGggRXhwcmVzc2lvbnM8L2E+IGZvciBjb250ZXh0IGl0ZW0gZXZhbHVhdGlvbiwKLSAgICAgKiB2YXJpYWJsZSwgZnVuY3Rpb24gYW5kIFFOYW1lIHJlc29sdXRpb24gYW5kIHJldHVybiB0eXBlIGNvbnZlcnNpb24uPC9wPgotICAgICAqCi0gICAgICogPHA+SWYgYSA8Y29kZT5udWxsPC9jb2RlPiB2YWx1ZSBpcyBwcm92aWRlZCBmb3IKLSAgICAgKiA8Y29kZT5pdGVtPC9jb2RlPiwgYW4gZW1wdHkgZG9jdW1lbnQgd2lsbCBiZSB1c2VkIGZvciB0aGUKLSAgICAgKiBjb250ZXh0LgotICAgICAqCi0gICAgICogQHBhcmFtIGl0ZW0gVGhlIHN0YXJ0aW5nIGNvbnRleHQgKGEgbm9kZSwgZm9yIGV4YW1wbGUpLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgPGNvZGU+U3RyaW5nPC9jb2RlPiB0aGF0IGlzIHRoZSByZXN1bHQgb2YgZXZhbHVhdGluZyB0aGUgZXhwcmVzc2lvbiBhbmQgY29udmVydGluZyB0aGUgcmVzdWx0IHRvIGEKLSAgICAgKiAgIDxjb2RlPlN0cmluZzwvY29kZT4uCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhQYXRoRXhwcmVzc2lvbkV4Y2VwdGlvbiBJZiB0aGUgZXhwcmVzc2lvbiBjYW5ub3QgYmUgZXZhbHVhdGVkLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZXZhbHVhdGUoT2JqZWN0IGl0ZW0pCi0gICAgICAgIHRocm93cyBYUGF0aEV4cHJlc3Npb25FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiA8cD5FdmFsdWF0ZSB0aGUgY29tcGlsZWQgWFBhdGggZXhwcmVzc2lvbiBpbiB0aGUgY29udGV4dCBvZiB0aGUgc3BlY2lmaWVkIDxjb2RlPklucHV0U291cmNlPC9jb2RlPiBhbmQgcmV0dXJuIHRoZSByZXN1bHQgYXMgdGhlCi0gICAgICogc3BlY2lmaWVkIHR5cGUuPC9wPgotICAgICAqCi0gICAgICogPHA+VGhpcyBtZXRob2QgYnVpbGRzIGEgZGF0YSBtb2RlbCBmb3IgdGhlIHtAbGluayBJbnB1dFNvdXJjZX0gYW5kIGNhbGxzCi0gICAgICoge0BsaW5rICNldmFsdWF0ZShPYmplY3QgaXRlbSwgUU5hbWUgcmV0dXJuVHlwZSl9IG9uIHRoZSByZXN1bHRpbmcgZG9jdW1lbnQgb2JqZWN0LjwvcD4KLSAgICAgKgotICAgICAqIDxwPlNlZSA8YSBocmVmPSIjWFBhdGhFeHByZXNzaW9uLWV2YWx1YXRpb24iPkV2YWx1YXRpb24gb2YgWFBhdGggRXhwcmVzc2lvbnM8L2E+IGZvciBjb250ZXh0IGl0ZW0gZXZhbHVhdGlvbiwKLSAgICAgKiB2YXJpYWJsZSwgZnVuY3Rpb24gYW5kIFFOYW1lIHJlc29sdXRpb24gYW5kIHJldHVybiB0eXBlIGNvbnZlcnNpb24uPC9wPgotICAgICAqCi0gICAgICogPHA+SWYgPGNvZGU+cmV0dXJuVHlwZTwvY29kZT4gaXMgbm90IG9uZSBvZiB0aGUgdHlwZXMgZGVmaW5lZCBpbiB7QGxpbmsgWFBhdGhDb25zdGFudHN9LAotICAgICAqIHRoZW4gYW4gPGNvZGU+SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uPC9jb2RlPiBpcyB0aHJvd24uPC9wPgotICAgICAqCi0gICAgICogPHA+SWYgPGNvZGU+c291cmNlPC9jb2RlPiBvciA8Y29kZT5yZXR1cm5UeXBlPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPiwKLSAgICAgKiB0aGVuIGEgPGNvZGU+TnVsbFBvaW50ZXJFeGNlcHRpb248L2NvZGU+IGlzIHRocm93bi48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gc291cmNlIFRoZSA8Y29kZT5JbnB1dFNvdXJjZTwvY29kZT4gb2YgdGhlIGRvY3VtZW50IHRvIGV2YWx1YXRlIG92ZXIuCi0gICAgICogQHBhcmFtIHJldHVyblR5cGUgVGhlIGRlc2lyZWQgcmV0dXJuIHR5cGUuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSA8Y29kZT5PYmplY3Q8L2NvZGU+IHRoYXQgaXMgdGhlIHJlc3VsdCBvZiBldmFsdWF0aW5nIHRoZSBleHByZXNzaW9uIGFuZCBjb252ZXJ0aW5nIHRoZSByZXN1bHQgdG8KLSAgICAgKiAgIDxjb2RlPnJldHVyblR5cGU8L2NvZGU+LgotICAgICAqCi0gICAgICogQHRocm93cyBYUGF0aEV4cHJlc3Npb25FeGNlcHRpb24gSWYgdGhlIGV4cHJlc3Npb24gY2Fubm90IGJlIGV2YWx1YXRlZC4KLSAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBJZiA8Y29kZT5yZXR1cm5UeXBlPC9jb2RlPiBpcyBub3Qgb25lIG9mIHRoZSB0eXBlcyBkZWZpbmVkIGluIHtAbGluayBYUGF0aENvbnN0YW50c30uCi0gICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBJZiAgPGNvZGU+c291cmNlPC9jb2RlPiBvciA8Y29kZT5yZXR1cm5UeXBlPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0IGV2YWx1YXRlKElucHV0U291cmNlIHNvdXJjZSwgUU5hbWUgcmV0dXJuVHlwZSkKLSAgICAgICAgdGhyb3dzIFhQYXRoRXhwcmVzc2lvbkV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIDxwPkV2YWx1YXRlIHRoZSBjb21waWxlZCBYUGF0aCBleHByZXNzaW9uIGluIHRoZSBjb250ZXh0IG9mIHRoZSBzcGVjaWZpZWQgPGNvZGU+SW5wdXRTb3VyY2U8L2NvZGU+IGFuZCByZXR1cm4gdGhlIHJlc3VsdCBhcyBhCi0gICAgICogPGNvZGU+U3RyaW5nPC9jb2RlPi48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5UaGlzIG1ldGhvZCBjYWxscyB7QGxpbmsgI2V2YWx1YXRlKElucHV0U291cmNlIHNvdXJjZSwgUU5hbWUgcmV0dXJuVHlwZSl9IHdpdGggYSA8Y29kZT5yZXR1cm5UeXBlPC9jb2RlPiBvZgotICAgICAqIHtAbGluayBYUGF0aENvbnN0YW50cyNTVFJJTkd9LjwvcD4KLSAgICAgKgotICAgICAqIDxwPlNlZSA8YSBocmVmPSIjWFBhdGhFeHByZXNzaW9uLWV2YWx1YXRpb24iPkV2YWx1YXRpb24gb2YgWFBhdGggRXhwcmVzc2lvbnM8L2E+IGZvciBjb250ZXh0IGl0ZW0gZXZhbHVhdGlvbiwKLSAgICAgKiB2YXJpYWJsZSwgZnVuY3Rpb24gYW5kIFFOYW1lIHJlc29sdXRpb24gYW5kIHJldHVybiB0eXBlIGNvbnZlcnNpb24uPC9wPgotICAgICAqCi0gICAgICogPHA+SWYgPGNvZGU+c291cmNlPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPiwgdGhlbiBhIDxjb2RlPk51bGxQb2ludGVyRXhjZXB0aW9uPC9jb2RlPiBpcyB0aHJvd24uPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIHNvdXJjZSBUaGUgPGNvZGU+SW5wdXRTb3VyY2U8L2NvZGU+IG9mIHRoZSBkb2N1bWVudCB0byBldmFsdWF0ZSBvdmVyLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgPGNvZGU+U3RyaW5nPC9jb2RlPiB0aGF0IGlzIHRoZSByZXN1bHQgb2YgZXZhbHVhdGluZyB0aGUgZXhwcmVzc2lvbiBhbmQgY29udmVydGluZyB0aGUgcmVzdWx0IHRvIGEKLSAgICAgKiAgIDxjb2RlPlN0cmluZzwvY29kZT4uCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFhQYXRoRXhwcmVzc2lvbkV4Y2VwdGlvbiBJZiB0aGUgZXhwcmVzc2lvbiBjYW5ub3QgYmUgZXZhbHVhdGVkLgotICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gSWYgIDxjb2RlPnNvdXJjZTwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBldmFsdWF0ZShJbnB1dFNvdXJjZSBzb3VyY2UpCi0gICAgICAgIHRocm93cyBYUGF0aEV4cHJlc3Npb25FeGNlcHRpb247Ci19CmRpZmYgLS1naXQgYS9zcmMvamF2YXgveG1sL3hwYXRoL1hQYXRoRXhwcmVzc2lvbkV4Y2VwdGlvbi5qYXZhIGIvc3JjL2phdmF4L3htbC94cGF0aC9YUGF0aEV4cHJlc3Npb25FeGNlcHRpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDIxOTA3OC4uMDAwMDAwMAotLS0gYS9zcmMvamF2YXgveG1sL3hwYXRoL1hQYXRoRXhwcmVzc2lvbkV4Y2VwdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNzQgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwMywgMjAwNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotcGFja2FnZSBqYXZheC54bWwueHBhdGg7Ci0KLS8qKgotICogPGNvZGU+WFBhdGhFeHByZXNzaW9uRXhjZXB0aW9uPC9jb2RlPiByZXByZXNlbnRzIGFuIGVycm9yIGluIGFuIFhQYXRoIGV4cHJlc3Npb24uPC9wPgotICoKLSAqIEBhdXRob3IgIDxhIGhyZWY9Im1haWx0bzpOb3JtYW4uV2Fsc2hAU3VuLmNvbSI+Tm9ybWFuIFdhbHNoPC9hPgotICogQGF1dGhvciAgPGEgaHJlZj0ibWFpbHRvOkplZmYuU3V0dG9yQFN1bi5jb20iPkplZmYgU3V0dG9yPC9hPgotICogQHNpbmNlIDEuNQotICovCi1wdWJsaWMgY2xhc3MgWFBhdGhFeHByZXNzaW9uRXhjZXB0aW9uIGV4dGVuZHMgWFBhdGhFeGNlcHRpb24gewotCi0gICAgLyoqCi0gICAgICogPHA+U3RyZWFtIFVuaXF1ZSBJZGVudGlmaWVyLjwvcD4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMTgzNzA4MDI2MDM3NDk4Njk4MEw7Ci0KLSAgICAvKioKLSAgICAgKiA8cD5Db25zdHJ1Y3RzIGEgbmV3IDxjb2RlPlhQYXRoRXhwcmVzc2lvbkV4Y2VwdGlvbjwvY29kZT4KLSAgICAgKiB3aXRoIHRoZSBzcGVjaWZpZWQgZGV0YWlsIDxjb2RlPm1lc3NhZ2U8L2NvZGU+LjwvcD4KLSAgICAgKgotICAgICAqIDxwPlRoZSA8Y29kZT5jYXVzZTwvY29kZT4gaXMgbm90IGluaXRpYWxpemVkLjwvcD4KLSAgICAgKgotICAgICAqIDxwPklmIDxjb2RlPm1lc3NhZ2U8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LAotICAgICAqIHRoZW4gYSA8Y29kZT5OdWxsUG9pbnRlckV4Y2VwdGlvbjwvY29kZT4gaXMgdGhyb3duLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBtZXNzYWdlIFRoZSBkZXRhaWwgbWVzc2FnZS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gV2hlbiA8Y29kZT5tZXNzYWdlPC9jb2RlPiBpcwotICAgICAqICAgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIFhQYXRoRXhwcmVzc2lvbkV4Y2VwdGlvbihTdHJpbmcgbWVzc2FnZSkgewotICAgICAgICBzdXBlcihtZXNzYWdlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5Db25zdHJ1Y3RzIGEgbmV3IDxjb2RlPlhQYXRoRXhwcmVzc2lvbkV4Y2VwdGlvbjwvY29kZT4KLSAgICAgKiB3aXRoIHRoZSBzcGVjaWZpZWQgPGNvZGU+Y2F1c2U8L2NvZGU+LjwvcD4KLSAgICAgKgotICAgICAqIDxwPklmIDxjb2RlPmNhdXNlPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPiwKLSAgICAgKiB0aGVuIGEgPGNvZGU+TnVsbFBvaW50ZXJFeGNlcHRpb248L2NvZGU+IGlzIHRocm93bi48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gY2F1c2UgVGhlIGNhdXNlLgotICAgICAqCi0gICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiA8Y29kZT5jYXVzZTwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIFhQYXRoRXhwcmVzc2lvbkV4Y2VwdGlvbihUaHJvd2FibGUgY2F1c2UpIHsKLSAgICAgICAgc3VwZXIoY2F1c2UpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9qYXZheC94bWwveHBhdGgvWFBhdGhGYWN0b3J5LmphdmEgYi9zcmMvamF2YXgveG1sL3hwYXRoL1hQYXRoRmFjdG9yeS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlYTczNzBlLi4wMDAwMDAwCi0tLSBhL3NyYy9qYXZheC94bWwveHBhdGgvWFBhdGhGYWN0b3J5LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzOTAgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwMywgMjAxMywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotcGFja2FnZSBqYXZheC54bWwueHBhdGg7Ci0KLS8qKgotICogPHA+QW4gPGNvZGU+WFBhdGhGYWN0b3J5PC9jb2RlPiBpbnN0YW5jZSBjYW4gYmUgdXNlZCB0byBjcmVhdGUKLSAqIHtAbGluayBqYXZheC54bWwueHBhdGguWFBhdGh9IG9iamVjdHMuPC9wPgotICoKLSAqPHA+U2VlIHtAbGluayAjbmV3SW5zdGFuY2UoU3RyaW5nIHVyaSl9IGZvciBsb29rdXAgbWVjaGFuaXNtLjwvcD4KLSAqCi0gKiA8cD5UaGUge0BsaW5rIFhQYXRoRmFjdG9yeX0gY2xhc3MgaXMgbm90IHRocmVhZC1zYWZlLiBJbiBvdGhlciB3b3JkcywKLSAqIGl0IGlzIHRoZSBhcHBsaWNhdGlvbidzIHJlc3BvbnNpYmlsaXR5IHRvIGVuc3VyZSB0aGF0IGF0IG1vc3QKLSAqIG9uZSB0aHJlYWQgaXMgdXNpbmcgYSB7QGxpbmsgWFBhdGhGYWN0b3J5fSBvYmplY3QgYXQgYW55Ci0gKiBnaXZlbiBtb21lbnQuIEltcGxlbWVudGF0aW9ucyBhcmUgZW5jb3VyYWdlZCB0byBtYXJrIG1ldGhvZHMKLSAqIGFzIDxjb2RlPnN5bmNocm9uaXplZDwvY29kZT4gdG8gcHJvdGVjdCB0aGVtc2VsdmVzIGZyb20gYnJva2VuIGNsaWVudHMuCi0gKgotICogPHA+e0BsaW5rIFhQYXRoRmFjdG9yeX0gaXMgbm90IHJlLWVudHJhbnQuIFdoaWxlIG9uZSBvZiB0aGUKLSAqIDxjb2RlPm5ld0luc3RhbmNlPC9jb2RlPiBtZXRob2RzIGlzIGJlaW5nIGludm9rZWQsIGFwcGxpY2F0aW9ucwotICogbWF5IG5vdCBhdHRlbXB0IHRvIHJlY3Vyc2l2ZWx5IGludm9rZSBhIDxjb2RlPm5ld0luc3RhbmNlPC9jb2RlPiBtZXRob2QsCi0gKiBldmVuIGZyb20gdGhlIHNhbWUgdGhyZWFkLgotICoKLSAqIEBhdXRob3IgIDxhIGhyZWY9Im1haWx0bzpOb3JtYW4uV2Fsc2hAU3VuLmNvbSI+Tm9ybWFuIFdhbHNoPC9hPgotICogQGF1dGhvciAgPGEgaHJlZj0ibWFpbHRvOkplZmYuU3V0dG9yQFN1bi5jb20iPkplZmYgU3V0dG9yPC9hPgotICoKLSAqIEBzaW5jZSAxLjUKLSAqLwotcHVibGljIGFic3RyYWN0IGNsYXNzIFhQYXRoRmFjdG9yeSB7Ci0KLQotICAgIC8qKgotICAgICAqIDxwPlRoZSBkZWZhdWx0IHByb3BlcnR5IG5hbWUgYWNjb3JkaW5nIHRvIHRoZSBKQVhQIHNwZWMuPC9wPgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIERFRkFVTFRfUFJPUEVSVFlfTkFNRSA9ICJqYXZheC54bWwueHBhdGguWFBhdGhGYWN0b3J5IjsKLQotICAgIC8qKgotICAgICAqIDxwPkRlZmF1bHQgT2JqZWN0IE1vZGVsIFVSSS48L3A+Ci0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgREVGQVVMVF9PQkpFQ1RfTU9ERUxfVVJJID0gImh0dHA6Ly9qYXZhLnN1bi5jb20vamF4cC94cGF0aC9kb20iOwotCi0gICAgLyoqCi0gICAgICo8cD4gVGFrZSBjYXJlIG9mIHJlc3RyaWN0aW9ucyBpbXBvc2VkIGJ5IGphdmEgc2VjdXJpdHkgbW9kZWwgPC9wPgotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIFNlY3VyaXR5U3VwcG9ydCBzcyA9IG5ldyBTZWN1cml0eVN1cHBvcnQoKSA7Ci0KLSAgICAvKioKLSAgICAgKiA8cD5Qcm90ZWN0ZWQgY29uc3RydWN0b3IgYXMge0BsaW5rICNuZXdJbnN0YW5jZSgpfSBvciB7QGxpbmsgI25ld0luc3RhbmNlKFN0cmluZyB1cmkpfQotICAgICAqIG9yIHtAbGluayAjbmV3SW5zdGFuY2UoU3RyaW5nIHVyaSwgU3RyaW5nIGZhY3RvcnlDbGFzc05hbWUsIENsYXNzTG9hZGVyIGNsYXNzTG9hZGVyKX0KLSAgICAgKiBzaG91bGQgYmUgdXNlZCB0byBjcmVhdGUgYSBuZXcgaW5zdGFuY2Ugb2YgYW4gPGNvZGU+WFBhdGhGYWN0b3J5PC9jb2RlPi48L3A+Ci0gICAgICovCi0gICAgcHJvdGVjdGVkIFhQYXRoRmFjdG9yeSgpIHsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5HZXQgYSBuZXcgPGNvZGU+WFBhdGhGYWN0b3J5PC9jb2RlPiBpbnN0YW5jZSB1c2luZyB0aGUgZGVmYXVsdCBvYmplY3QgbW9kZWwsCi0gICAgICoge0BsaW5rICNERUZBVUxUX09CSkVDVF9NT0RFTF9VUkl9LAotICAgICAqIHRoZSBXM0MgRE9NLjwvcD4KLSAgICAgKgotICAgICAqIDxwPlRoaXMgbWV0aG9kIGlzIGZ1bmN0aW9uYWxseSBlcXVpdmFsZW50IHRvOjwvcD4KLSAgICAgKiA8cHJlPgotICAgICAqICAgbmV3SW5zdGFuY2UoREVGQVVMVF9PQkpFQ1RfTU9ERUxfVVJJKQotICAgICAqIDwvcHJlPgotICAgICAqCi0gICAgICogPHA+U2luY2UgdGhlIGltcGxlbWVudGF0aW9uIGZvciB0aGUgVzNDIERPTSBpcyBhbHdheXMgYXZhaWxhYmxlLCB0aGlzIG1ldGhvZCB3aWxsIG5ldmVyIGZhaWwuPC9wPgotICAgICAqCi0gICAgICogQHJldHVybiBJbnN0YW5jZSBvZiBhbiA8Y29kZT5YUGF0aEZhY3Rvcnk8L2NvZGU+LgotICAgICAqCi0gICAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIFdoZW4gdGhlcmUgaXMgYSBmYWlsdXJlIGluIGNyZWF0aW5nIGFuCi0gICAgICogICA8Y29kZT5YUGF0aEZhY3Rvcnk8L2NvZGU+IGZvciB0aGUgZGVmYXVsdCBvYmplY3QgbW9kZWwuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBYUGF0aEZhY3RvcnkgbmV3SW5zdGFuY2UoKSB7Ci0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICByZXR1cm4gbmV3SW5zdGFuY2UoREVGQVVMVF9PQkpFQ1RfTU9ERUxfVVJJKTsKLSAgICAgICAgfSBjYXRjaCAoWFBhdGhGYWN0b3J5Q29uZmlndXJhdGlvbkV4Y2VwdGlvbiB4cGF0aEZhY3RvcnlDb25maWd1cmF0aW9uRXhjZXB0aW9uKSB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgICAgICAiWFBhdGhGYWN0b3J5I25ld0luc3RhbmNlKCkgZmFpbGVkIHRvIGNyZWF0ZSBhbiBYUGF0aEZhY3RvcnkgZm9yIHRoZSBkZWZhdWx0IG9iamVjdCBtb2RlbDogIgotICAgICAgICAgICAgICAgICAgICAgICAgKyBERUZBVUxUX09CSkVDVF9NT0RFTF9VUkkKLSAgICAgICAgICAgICAgICAgICAgICAgICsgIiB3aXRoIHRoZSBYUGF0aEZhY3RvcnlDb25maWd1cmF0aW9uRXhjZXB0aW9uOiAiCi0gICAgICAgICAgICAgICAgICAgICAgICArIHhwYXRoRmFjdG9yeUNvbmZpZ3VyYXRpb25FeGNlcHRpb24udG9TdHJpbmcoKQotICAgICAgICAgICAgICAgICk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAqIDxwPkdldCBhIG5ldyA8Y29kZT5YUGF0aEZhY3Rvcnk8L2NvZGU+IGluc3RhbmNlIHVzaW5nIHRoZSBzcGVjaWZpZWQgb2JqZWN0IG1vZGVsLjwvcD4KLSAgICAqCi0gICAgKiA8cD5UbyBmaW5kIGEgPGNvZGU+WFBhdGhGYWN0b3J5PC9jb2RlPiBvYmplY3QsCi0gICAgKiB0aGlzIG1ldGhvZCBsb29rcyB0aGUgZm9sbG93aW5nIHBsYWNlcyBpbiB0aGUgZm9sbG93aW5nIG9yZGVyIHdoZXJlICJ0aGUgY2xhc3MgbG9hZGVyIiByZWZlcnMgdG8gdGhlIGNvbnRleHQgY2xhc3MgbG9hZGVyOjwvcD4KLSAgICAqIDxvbD4KLSAgICAqICAgPGxpPgotICAgICogICAgIElmIHRoZSBzeXN0ZW0gcHJvcGVydHkge0BsaW5rICNERUZBVUxUX1BST1BFUlRZX05BTUV9ICsgIjp1cmkiIGlzIHByZXNlbnQsCi0gICAgKiAgICAgd2hlcmUgdXJpIGlzIHRoZSBwYXJhbWV0ZXIgdG8gdGhpcyBtZXRob2QsIHRoZW4gaXRzIHZhbHVlIGlzIHJlYWQgYXMgYSBjbGFzcyBuYW1lLgotICAgICogICAgIFRoZSBtZXRob2Qgd2lsbCB0cnkgdG8gY3JlYXRlIGEgbmV3IGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgYnkgdXNpbmcgdGhlIGNsYXNzIGxvYWRlciwKLSAgICAqICAgICBhbmQgcmV0dXJucyBpdCBpZiBpdCBpcyBzdWNjZXNzZnVsbHkgY3JlYXRlZC4KLSAgICAqICAgPC9saT4KLSAgICAqICAgPGxpPgotICAgICogICAgICR7amF2YS5ob21lfS9saWIvamF4cC5wcm9wZXJ0aWVzIGlzIHJlYWQgYW5kIHRoZSB2YWx1ZSBhc3NvY2lhdGVkIHdpdGggdGhlIGtleSBiZWluZyB0aGUgc3lzdGVtIHByb3BlcnR5IGFib3ZlIGlzIGxvb2tlZCBmb3IuCi0gICAgKiAgICAgSWYgcHJlc2VudCwgdGhlIHZhbHVlIGlzIHByb2Nlc3NlZCBqdXN0IGxpa2UgYWJvdmUuCi0gICAgKiAgIDwvbGk+Ci0gICAgKiAgIDxsaT4KLSAgICAqICAgICBVc2UgdGhlIHNlcnZpY2UtcHJvdmlkZXIgbG9hZGluZyBmYWNpbGl0aWVzLCBkZWZpbmVkIGJ5IHRoZQotICAgICogICAgIHtAbGluayBqYXZhLnV0aWwuU2VydmljZUxvYWRlcn0gY2xhc3MsIHRvIGF0dGVtcHQgdG8gbG9jYXRlIGFuZCBsb2FkIGFuCi0gICAgKiAgICAgaW1wbGVtZW50YXRpb24gb2YgdGhlIHNlcnZpY2UgdXNpbmcgdGhlIHtAbGlua3BsYWluCi0gICAgKiAgICAgamF2YS51dGlsLlNlcnZpY2VMb2FkZXIjbG9hZChqYXZhLmxhbmcuQ2xhc3MpIGRlZmF1bHQgbG9hZGluZyBtZWNoYW5pc219OgotICAgICogICAgIHRoZSBzZXJ2aWNlLXByb3ZpZGVyIGxvYWRpbmcgZmFjaWxpdHkgd2lsbCB1c2UgdGhlIHtAbGlua3BsYWluCi0gICAgKiAgICAgamF2YS5sYW5nLlRocmVhZCNnZXRDb250ZXh0Q2xhc3NMb2FkZXIoKSBjdXJyZW50IHRocmVhZCdzIGNvbnRleHQgY2xhc3MgbG9hZGVyfQotICAgICogICAgIHRvIGF0dGVtcHQgdG8gbG9hZCB0aGUgc2VydmljZS4gSWYgdGhlIGNvbnRleHQgY2xhc3MKLSAgICAqICAgICBsb2FkZXIgaXMgbnVsbCwgdGhlIHtAbGlua3BsYWluCi0gICAgKiAgICAgQ2xhc3NMb2FkZXIjZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKSBzeXN0ZW0gY2xhc3MgbG9hZGVyfSB3aWxsIGJlIHVzZWQuCi0gICAgKiAgICAgPGJyPgotICAgICogICAgIEVhY2ggcG90ZW50aWFsIHNlcnZpY2UgcHJvdmlkZXIgaXMgcmVxdWlyZWQgdG8gaW1wbGVtZW50IHRoZSBtZXRob2QKLSAgICAqICAgICB7QGxpbmsgI2lzT2JqZWN0TW9kZWxTdXBwb3J0ZWQoU3RyaW5nIG9iamVjdE1vZGVsKX0uCi0gICAgKiAgICAgVGhlIGZpcnN0IHNlcnZpY2UgcHJvdmlkZXIgZm91bmQgdGhhdCBzdXBwb3J0cyB0aGUgc3BlY2lmaWVkIG9iamVjdAotICAgICogICAgIG1vZGVsIGlzIHJldHVybmVkLgotICAgICogICAgIDxicj4KLSAgICAqICAgICBJbiBjYXNlIG9mIHtAbGluayBqYXZhLnV0aWwuU2VydmljZUNvbmZpZ3VyYXRpb25FcnJvcn0gYW4KLSAgICAqICAgICB7QGxpbmsgWFBhdGhGYWN0b3J5Q29uZmlndXJhdGlvbkV4Y2VwdGlvbn0gd2lsbCBiZSB0aHJvd24uCi0gICAgKiAgIDwvbGk+Ci0gICAgKiAgIDxsaT4KLSAgICAqICAgICBQbGF0Zm9ybSBkZWZhdWx0IDxjb2RlPlhQYXRoRmFjdG9yeTwvY29kZT4gaXMgbG9jYXRlZCBpbiBhIHBsYXRmb3JtIHNwZWNpZmljIHdheS4KLSAgICAqICAgICBUaGVyZSBtdXN0IGJlIGEgcGxhdGZvcm0gZGVmYXVsdCBYUGF0aEZhY3RvcnkgZm9yIHRoZSBXM0MgRE9NLCBpLmUuIHtAbGluayAjREVGQVVMVF9PQkpFQ1RfTU9ERUxfVVJJfS4KLSAgICAqICAgPC9saT4KLSAgICAqIDwvb2w+Ci0gICAgKiA8cD5JZiBldmVyeXRoaW5nIGZhaWxzLCBhbiA8Y29kZT5YUGF0aEZhY3RvcnlDb25maWd1cmF0aW9uRXhjZXB0aW9uPC9jb2RlPiB3aWxsIGJlIHRocm93bi48L3A+Ci0gICAgKgotICAgICogPHA+VGlwIGZvciBUcm91YmxlLXNob290aW5nOjwvcD4KLSAgICAqIDxwPlNlZSB7QGxpbmsgamF2YS51dGlsLlByb3BlcnRpZXMjbG9hZChqYXZhLmlvLklucHV0U3RyZWFtKX0gZm9yIGV4YWN0bHkgaG93IGEgcHJvcGVydHkgZmlsZSBpcyBwYXJzZWQuCi0gICAgKiBJbiBwYXJ0aWN1bGFyLCBjb2xvbnMgJzonIG5lZWQgdG8gYmUgZXNjYXBlZCBpbiBhIHByb3BlcnR5IGZpbGUsIHNvIG1ha2Ugc3VyZSB0aGUgVVJJcyBhcmUgcHJvcGVybHkgZXNjYXBlZCBpbiBpdC4KLSAgICAqIEZvciBleGFtcGxlOjwvcD4KLSAgICAqIDxwcmU+Ci0gICAgKiAgIGh0dHBcOi8vamF2YS5zdW4uY29tL2pheHAveHBhdGgvZG9tPW9yZy5hY21lLkRvbVhQYXRoRmFjdG9yeQotICAgICogPC9wcmU+Ci0gICAgKgotICAgICogQHBhcmFtIHVyaSBJZGVudGlmaWVzIHRoZSB1bmRlcmx5aW5nIG9iamVjdCBtb2RlbC4KLSAgICAqICAgVGhlIHNwZWNpZmljYXRpb24gb25seSBkZWZpbmVzIHRoZSBVUkkge0BsaW5rICNERUZBVUxUX09CSkVDVF9NT0RFTF9VUkl9LAotICAgICogICA8Y29kZT5odHRwOi8vamF2YS5zdW4uY29tL2pheHAveHBhdGgvZG9tPC9jb2RlPiBmb3IgdGhlIFczQyBET00sCi0gICAgKiAgIHRoZSBvcmcudzNjLmRvbSBwYWNrYWdlLCBhbmQgaW1wbGVtZW50YXRpb25zIGFyZSBmcmVlIHRvIGludHJvZHVjZSBvdGhlciBVUklzIGZvciBvdGhlciBvYmplY3QgbW9kZWxzLgotICAgICoKLSAgICAqIEByZXR1cm4gSW5zdGFuY2Ugb2YgYW4gPGNvZGU+WFBhdGhGYWN0b3J5PC9jb2RlPi4KLSAgICAqCi0gICAgKiBAdGhyb3dzIFhQYXRoRmFjdG9yeUNvbmZpZ3VyYXRpb25FeGNlcHRpb24gSWYgdGhlIHNwZWNpZmllZCBvYmplY3QgbW9kZWwKLSAgICAqICAgICAgaXMgdW5hdmFpbGFibGUsIG9yIGlmIHRoZXJlIGlzIGEgY29uZmlndXJhdGlvbiBlcnJvci4KLSAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gSWYgPGNvZGU+dXJpPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIElmIDxjb2RlPnVyaTwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4KLSAgICAqICAgb3IgPGNvZGU+dXJpLmxlbmd0aCgpID09IDA8L2NvZGU+LgotICAgICovCi0gICAgcHVibGljIHN0YXRpYyBYUGF0aEZhY3RvcnkgbmV3SW5zdGFuY2UoZmluYWwgU3RyaW5nIHVyaSkKLSAgICAgICAgdGhyb3dzIFhQYXRoRmFjdG9yeUNvbmZpZ3VyYXRpb25FeGNlcHRpb24gewotCi0gICAgICAgIGlmICh1cmkgPT0gbnVsbCkgewotICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICAiWFBhdGhGYWN0b3J5I25ld0luc3RhbmNlKFN0cmluZyB1cmkpIGNhbm5vdCBiZSBjYWxsZWQgd2l0aCB1cmkgPT0gbnVsbCIpOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKHVyaS5sZW5ndGgoKSA9PSAwKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICAiWFBhdGhGYWN0b3J5I25ld0luc3RhbmNlKFN0cmluZyB1cmkpIGNhbm5vdCBiZSBjYWxsZWQgd2l0aCB1cmkgPT0gXCJcIiIpOwotICAgICAgICB9Ci0KLSAgICAgICAgQ2xhc3NMb2FkZXIgY2xhc3NMb2FkZXIgPSBzcy5nZXRDb250ZXh0Q2xhc3NMb2FkZXIoKTsKLQotICAgICAgICBpZiAoY2xhc3NMb2FkZXIgPT0gbnVsbCkgewotICAgICAgICAgICAgLy91c2UgdGhlIGN1cnJlbnQgY2xhc3MgbG9hZGVyCi0gICAgICAgICAgICBjbGFzc0xvYWRlciA9IFhQYXRoRmFjdG9yeS5jbGFzcy5nZXRDbGFzc0xvYWRlcigpOwotICAgICAgICB9Ci0KLSAgICAgICAgWFBhdGhGYWN0b3J5IHhwYXRoRmFjdG9yeSA9IG5ldyBYUGF0aEZhY3RvcnlGaW5kZXIoY2xhc3NMb2FkZXIpLm5ld0ZhY3RvcnkodXJpKTsKLQotICAgICAgICBpZiAoeHBhdGhGYWN0b3J5ID09IG51bGwpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBYUGF0aEZhY3RvcnlDb25maWd1cmF0aW9uRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICAiTm8gWFBhdGhGYWN0b3J5IGltcGxlbWVudGF0aW9uIGZvdW5kIGZvciB0aGUgb2JqZWN0IG1vZGVsOiAiCi0gICAgICAgICAgICAgICAgICAgICsgdXJpKTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiB4cGF0aEZhY3Rvcnk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+T2J0YWluIGEgbmV3IGluc3RhbmNlIG9mIGEgPGNvZGU+WFBhdGhGYWN0b3J5PC9jb2RlPiBmcm9tIGEgZmFjdG9yeSBjbGFzcyBuYW1lLiA8Y29kZT5YUGF0aEZhY3Rvcnk8L2NvZGU+Ci0gICAgICogaXMgcmV0dXJuZWQgaWYgc3BlY2lmaWVkIGZhY3RvcnkgY2xhc3Mgc3VwcG9ydHMgdGhlIHNwZWNpZmllZCBvYmplY3QgbW9kZWwuCi0gICAgICogVGhpcyBmdW5jdGlvbiBpcyB1c2VmdWwgd2hlbiB0aGVyZSBhcmUgbXVsdGlwbGUgcHJvdmlkZXJzIGluIHRoZSBjbGFzc3BhdGguCi0gICAgICogSXQgZ2l2ZXMgbW9yZSBjb250cm9sIHRvIHRoZSBhcHBsaWNhdGlvbiBhcyBpdCBjYW4gc3BlY2lmeSB3aGljaCBwcm92aWRlcgotICAgICAqIHNob3VsZCBiZSBsb2FkZWQuPC9wPgotICAgICAqCi0gICAgICoKLSAgICAgKiA8aDI+VGlwIGZvciBUcm91YmxlLXNob290aW5nPC9oMj4KLSAgICAgKiA8cD5TZXR0aW5nIHRoZSA8Y29kZT5qYXhwLmRlYnVnPC9jb2RlPiBzeXN0ZW0gcHJvcGVydHkgd2lsbCBjYXVzZQotICAgICAqIHRoaXMgbWV0aG9kIHRvIHByaW50IGEgbG90IG9mIGRlYnVnIG1lc3NhZ2VzCi0gICAgICogdG8gPGNvZGU+U3lzdGVtLmVycjwvY29kZT4gYWJvdXQgd2hhdCBpdCBpcyBkb2luZyBhbmQgd2hlcmUgaXQgaXMgbG9va2luZyBhdC48L3A+Ci0gICAgICoKLSAgICAgKiA8cD4gSWYgeW91IGhhdmUgcHJvYmxlbXMgdHJ5OjwvcD4KLSAgICAgKiA8cHJlPgotICAgICAqIGphdmEgLURqYXhwLmRlYnVnPTEgWW91clByb2dyYW0gLi4uLgotICAgICAqIDwvcHJlPgotICAgICAqCi0gICAgICogQHBhcmFtIHVyaSAgICAgICAgIElkZW50aWZpZXMgdGhlIHVuZGVybHlpbmcgb2JqZWN0IG1vZGVsLiBUaGUgc3BlY2lmaWNhdGlvbiBvbmx5IGRlZmluZXMgdGhlIFVSSQotICAgICAqICAgICAgICAgICAgICAgICAgICB7QGxpbmsgI0RFRkFVTFRfT0JKRUNUX01PREVMX1VSSX0sPGNvZGU+aHR0cDovL2phdmEuc3VuLmNvbS9qYXhwL3hwYXRoL2RvbTwvY29kZT4KLSAgICAgKiAgICAgICAgICAgICAgICAgICAgZm9yIHRoZSBXM0MgRE9NLCB0aGUgb3JnLnczYy5kb20gcGFja2FnZSwgYW5kIGltcGxlbWVudGF0aW9ucyBhcmUgZnJlZSB0byBpbnRyb2R1Y2UKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgb3RoZXIgVVJJcyBmb3Igb3RoZXIgb2JqZWN0IG1vZGVscy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBmYWN0b3J5Q2xhc3NOYW1lIGZ1bGx5IHF1YWxpZmllZCBmYWN0b3J5IGNsYXNzIG5hbWUgdGhhdCBwcm92aWRlcyBpbXBsZW1lbnRhdGlvbiBvZiA8Y29kZT5qYXZheC54bWwueHBhdGguWFBhdGhGYWN0b3J5PC9jb2RlPi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjbGFzc0xvYWRlciA8Y29kZT5DbGFzc0xvYWRlcjwvY29kZT4gdXNlZCB0byBsb2FkIHRoZSBmYWN0b3J5IGNsYXNzLiBJZiA8Y29kZT5udWxsPC9jb2RlPgotICAgICAqICAgICAgICAgICAgICAgICAgICAgY3VycmVudCA8Y29kZT5UaHJlYWQ8L2NvZGU+J3MgY29udGV4dCBjbGFzc0xvYWRlciBpcyB1c2VkIHRvIGxvYWQgdGhlIGZhY3RvcnkgY2xhc3MuCi0gICAgICoKLSAgICAgKgotICAgICAqIEByZXR1cm4gTmV3IGluc3RhbmNlIG9mIGEgPGNvZGU+WFBhdGhGYWN0b3J5PC9jb2RlPgotICAgICAqCi0gICAgICogQHRocm93cyBYUGF0aEZhY3RvcnlDb25maWd1cmF0aW9uRXhjZXB0aW9uCi0gICAgICogICAgICAgICAgICAgICAgICAgaWYgPGNvZGU+ZmFjdG9yeUNsYXNzTmFtZTwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4sIG9yCi0gICAgICogICAgICAgICAgICAgICAgICAgdGhlIGZhY3RvcnkgY2xhc3MgY2Fubm90IGJlIGxvYWRlZCwgaW5zdGFudGlhdGVkCi0gICAgICogICAgICAgICAgICAgICAgICAgb3IgdGhlIGZhY3RvcnkgY2xhc3MgZG9lcyBub3Qgc3VwcG9ydCB0aGUgb2JqZWN0IG1vZGVsIHNwZWNpZmllZAotICAgICAqICAgICAgICAgICAgICAgICAgIGluIHRoZSA8Y29kZT51cmk8L2NvZGU+IHBhcmFtZXRlci4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gSWYgPGNvZGU+dXJpPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBJZiA8Y29kZT51cmk8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+Ci0gICAgICogICAgICAgICAgb3IgPGNvZGU+dXJpLmxlbmd0aCgpID09IDA8L2NvZGU+LgotICAgICAqCi0gICAgICogQHNlZSAjbmV3SW5zdGFuY2UoKQotICAgICAqIEBzZWUgI25ld0luc3RhbmNlKFN0cmluZyB1cmkpCi0gICAgICoKLSAgICAgKiBAc2luY2UgMS42Ci0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBYUGF0aEZhY3RvcnkgbmV3SW5zdGFuY2UoU3RyaW5nIHVyaSwgU3RyaW5nIGZhY3RvcnlDbGFzc05hbWUsIENsYXNzTG9hZGVyIGNsYXNzTG9hZGVyKQotICAgICAgICB0aHJvd3MgWFBhdGhGYWN0b3J5Q29uZmlndXJhdGlvbkV4Y2VwdGlvbnsKLSAgICAgICAgQ2xhc3NMb2FkZXIgY2wgPSBjbGFzc0xvYWRlcjsKLQotICAgICAgICBpZiAodXJpID09IG51bGwpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgIlhQYXRoRmFjdG9yeSNuZXdJbnN0YW5jZShTdHJpbmcgdXJpKSBjYW5ub3QgYmUgY2FsbGVkIHdpdGggdXJpID09IG51bGwiKTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmICh1cmkubGVuZ3RoKCkgPT0gMCkgewotICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgIlhQYXRoRmFjdG9yeSNuZXdJbnN0YW5jZShTdHJpbmcgdXJpKSBjYW5ub3QgYmUgY2FsbGVkIHdpdGggdXJpID09IFwiXCIiKTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChjbCA9PSBudWxsKSB7Ci0gICAgICAgICAgICBjbCA9IHNzLmdldENvbnRleHRDbGFzc0xvYWRlcigpOwotICAgICAgICB9Ci0KLSAgICAgICAgWFBhdGhGYWN0b3J5IGYgPSBuZXcgWFBhdGhGYWN0b3J5RmluZGVyKGNsKS5jcmVhdGVJbnN0YW5jZShmYWN0b3J5Q2xhc3NOYW1lKTsKLQotICAgICAgICBpZiAoZiA9PSBudWxsKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWFBhdGhGYWN0b3J5Q29uZmlndXJhdGlvbkV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICAgIk5vIFhQYXRoRmFjdG9yeSBpbXBsZW1lbnRhdGlvbiBmb3VuZCBmb3IgdGhlIG9iamVjdCBtb2RlbDogIgotICAgICAgICAgICAgICAgICAgICArIHVyaSk7Ci0gICAgICAgIH0KLSAgICAgICAgLy9pZiB0aGlzIGZhY3Rvcnkgc3VwcG9ydHMgdGhlIGdpdmVuIHNjaGVtYWxhbmd1YWdlIHJldHVybiB0aGlzIGZhY3RvcnkgZWxzZSB0aHJvd24gZXhjZXB0aW9uCi0gICAgICAgIGlmIChmLmlzT2JqZWN0TW9kZWxTdXBwb3J0ZWQodXJpKSkgewotICAgICAgICAgICAgcmV0dXJuIGY7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWFBhdGhGYWN0b3J5Q29uZmlndXJhdGlvbkV4Y2VwdGlvbigiRmFjdG9yeSAiCi0gICAgICAgICAgICAgICAgICAgICsgZmFjdG9yeUNsYXNzTmFtZSArICIgZG9lc24ndCBzdXBwb3J0IGdpdmVuICIgKyB1cmkKLSAgICAgICAgICAgICAgICAgICAgKyAiIG9iamVjdCBtb2RlbCIpOwotICAgICAgICB9Ci0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5JcyBzcGVjaWZpZWQgb2JqZWN0IG1vZGVsIHN1cHBvcnRlZCBieSB0aGlzIDxjb2RlPlhQYXRoRmFjdG9yeTwvY29kZT4/PC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIG9iamVjdE1vZGVsIFNwZWNpZmllcyB0aGUgb2JqZWN0IG1vZGVsIHdoaWNoIHRoZSByZXR1cm5lZCA8Y29kZT5YUGF0aEZhY3Rvcnk8L2NvZGU+IHdpbGwgdW5kZXJzdGFuZC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gPGNvZGU+dHJ1ZTwvY29kZT4gaWYgPGNvZGU+WFBhdGhGYWN0b3J5PC9jb2RlPiBzdXBwb3J0cyA8Y29kZT5vYmplY3RNb2RlbDwvY29kZT4sIGVsc2UgPGNvZGU+ZmFsc2U8L2NvZGU+LgotICAgICAqCi0gICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBJZiA8Y29kZT5vYmplY3RNb2RlbDwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gSWYgPGNvZGU+b2JqZWN0TW9kZWwubGVuZ3RoKCkgPT0gMDwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gaXNPYmplY3RNb2RlbFN1cHBvcnRlZChTdHJpbmcgb2JqZWN0TW9kZWwpOwotCi0gICAgLyoqCi0gICAgICogPHA+U2V0IGEgZmVhdHVyZSBmb3IgdGhpcyA8Y29kZT5YUGF0aEZhY3Rvcnk8L2NvZGU+IGFuZAotICAgICAqIDxjb2RlPlhQYXRoPC9jb2RlPnMgY3JlYXRlZCBieSB0aGlzIGZhY3RvcnkuPC9wPgotICAgICAqCi0gICAgICogPHA+Ci0gICAgICogRmVhdHVyZSBuYW1lcyBhcmUgZnVsbHkgcXVhbGlmaWVkIHtAbGluayBqYXZhLm5ldC5VUkl9cy4KLSAgICAgKiBJbXBsZW1lbnRhdGlvbnMgbWF5IGRlZmluZSB0aGVpciBvd24gZmVhdHVyZXMuCi0gICAgICogQW4ge0BsaW5rIFhQYXRoRmFjdG9yeUNvbmZpZ3VyYXRpb25FeGNlcHRpb259IGlzIHRocm93biBpZiB0aGlzCi0gICAgICogPGNvZGU+WFBhdGhGYWN0b3J5PC9jb2RlPiBvciB0aGUgPGNvZGU+WFBhdGg8L2NvZGU+cwotICAgICAqIGl0IGNyZWF0ZXMgY2Fubm90IHN1cHBvcnQgdGhlIGZlYXR1cmUuCi0gICAgICogSXQgaXMgcG9zc2libGUgZm9yIGFuIDxjb2RlPlhQYXRoRmFjdG9yeTwvY29kZT4gdG8gZXhwb3NlIGEgZmVhdHVyZSB2YWx1ZQotICAgICAqIGJ1dCBiZSB1bmFibGUgdG8gY2hhbmdlIGl0cyBzdGF0ZS4KLSAgICAgKiA8L3A+Ci0gICAgICoKLSAgICAgKiA8cD4KLSAgICAgKiBBbGwgaW1wbGVtZW50YXRpb25zIGFyZSByZXF1aXJlZCB0byBzdXBwb3J0IHRoZSB7QGxpbmsgamF2YXgueG1sLlhNTENvbnN0YW50cyNGRUFUVVJFX1NFQ1VSRV9QUk9DRVNTSU5HfSBmZWF0dXJlLgotICAgICAqIFdoZW4gdGhlIGZlYXR1cmUgaXMgPGNvZGU+dHJ1ZTwvY29kZT4sIGFueSByZWZlcmVuY2UgdG8gIGFuIGV4dGVybmFsIGZ1bmN0aW9uIGlzIGFuIGVycm9yLgotICAgICAqIFVuZGVyIHRoZXNlIGNvbmRpdGlvbnMsIHRoZSBpbXBsZW1lbnRhdGlvbiBtdXN0IG5vdCBjYWxsIHRoZSB7QGxpbmsgWFBhdGhGdW5jdGlvblJlc29sdmVyfQotICAgICAqIGFuZCBtdXN0IHRocm93IGFuIHtAbGluayBYUGF0aEZ1bmN0aW9uRXhjZXB0aW9ufS4KLSAgICAgKiA8L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSBGZWF0dXJlIG5hbWUuCi0gICAgICogQHBhcmFtIHZhbHVlIElzIGZlYXR1cmUgc3RhdGUgPGNvZGU+dHJ1ZTwvY29kZT4gb3IgPGNvZGU+ZmFsc2U8L2NvZGU+LgotICAgICAqCi0gICAgICogQHRocm93cyBYUGF0aEZhY3RvcnlDb25maWd1cmF0aW9uRXhjZXB0aW9uIGlmIHRoaXMgPGNvZGU+WFBhdGhGYWN0b3J5PC9jb2RlPiBvciB0aGUgPGNvZGU+WFBhdGg8L2NvZGU+cwotICAgICAqICAgaXQgY3JlYXRlcyBjYW5ub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCi0gICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiA8Y29kZT5uYW1lPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRGZWF0dXJlKFN0cmluZyBuYW1lLCBib29sZWFuIHZhbHVlKQotICAgICAgICAgICAgdGhyb3dzIFhQYXRoRmFjdG9yeUNvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiA8cD5HZXQgdGhlIHN0YXRlIG9mIHRoZSBuYW1lZCBmZWF0dXJlLjwvcD4KLSAgICAgKgotICAgICAqIDxwPgotICAgICAqIEZlYXR1cmUgbmFtZXMgYXJlIGZ1bGx5IHF1YWxpZmllZCB7QGxpbmsgamF2YS5uZXQuVVJJfXMuCi0gICAgICogSW1wbGVtZW50YXRpb25zIG1heSBkZWZpbmUgdGhlaXIgb3duIGZlYXR1cmVzLgotICAgICAqIEFuIHtAbGluayBYUGF0aEZhY3RvcnlDb25maWd1cmF0aW9uRXhjZXB0aW9ufSBpcyB0aHJvd24gaWYgdGhpcwotICAgICAqIDxjb2RlPlhQYXRoRmFjdG9yeTwvY29kZT4gb3IgdGhlIDxjb2RlPlhQYXRoPC9jb2RlPnMKLSAgICAgKiBpdCBjcmVhdGVzIGNhbm5vdCBzdXBwb3J0IHRoZSBmZWF0dXJlLgotICAgICAqIEl0IGlzIHBvc3NpYmxlIGZvciBhbiA8Y29kZT5YUGF0aEZhY3Rvcnk8L2NvZGU+IHRvIGV4cG9zZSBhIGZlYXR1cmUgdmFsdWUKLSAgICAgKiBidXQgYmUgdW5hYmxlIHRvIGNoYW5nZSBpdHMgc3RhdGUuCi0gICAgICogPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgRmVhdHVyZSBuYW1lLgotICAgICAqCi0gICAgICogQHJldHVybiBTdGF0ZSBvZiB0aGUgbmFtZWQgZmVhdHVyZS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgWFBhdGhGYWN0b3J5Q29uZmlndXJhdGlvbkV4Y2VwdGlvbiBpZiB0aGlzCi0gICAgICogICA8Y29kZT5YUGF0aEZhY3Rvcnk8L2NvZGU+IG9yIHRoZSA8Y29kZT5YUGF0aDwvY29kZT5zCi0gICAgICogICBpdCBjcmVhdGVzIGNhbm5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KLSAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIDxjb2RlPm5hbWU8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGdldEZlYXR1cmUoU3RyaW5nIG5hbWUpCi0gICAgICAgICAgICB0aHJvd3MgWFBhdGhGYWN0b3J5Q29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIDxwPkVzdGFibGlzaCBhIGRlZmF1bHQgdmFyaWFibGUgcmVzb2x2ZXIuPC9wPgotICAgICAqCi0gICAgICogPHA+QW55IDxjb2RlPlhQYXRoPC9jb2RlPiBvYmplY3RzIGNvbnN0cnVjdGVkIGZyb20gdGhpcyBmYWN0b3J5IHdpbGwgdXNlCi0gICAgICogdGhlIHNwZWNpZmllZCByZXNvbHZlciBieSBkZWZhdWx0LjwvcD4KLSAgICAgKgotICAgICAqIDxwPkEgPGNvZGU+TnVsbFBvaW50ZXJFeGNlcHRpb248L2NvZGU+IGlzIHRocm93biBpZiA8Y29kZT5yZXNvbHZlcjwvY29kZT4KLSAgICAgKiBpcyA8Y29kZT5udWxsPC9jb2RlPi48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gcmVzb2x2ZXIgVmFyaWFibGUgcmVzb2x2ZXIuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIElmIDxjb2RlPnJlc29sdmVyPC9jb2RlPiBpcwotICAgICAqICAgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2V0WFBhdGhWYXJpYWJsZVJlc29sdmVyKFhQYXRoVmFyaWFibGVSZXNvbHZlciByZXNvbHZlcik7Ci0KLSAgICAvKioKLSAgICAgKiA8cD5Fc3RhYmxpc2ggYSBkZWZhdWx0IGZ1bmN0aW9uIHJlc29sdmVyLjwvcD4KLSAgICAgKgotICAgICAqIDxwPkFueSA8Y29kZT5YUGF0aDwvY29kZT4gb2JqZWN0cyBjb25zdHJ1Y3RlZCBmcm9tIHRoaXMgZmFjdG9yeSB3aWxsCi0gICAgICogdXNlIHRoZSBzcGVjaWZpZWQgcmVzb2x2ZXIgYnkgZGVmYXVsdC48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5BIDxjb2RlPk51bGxQb2ludGVyRXhjZXB0aW9uPC9jb2RlPiBpcyB0aHJvd24gaWYKLSAgICAgKiA8Y29kZT5yZXNvbHZlcjwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4uPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIHJlc29sdmVyIFhQYXRoIGZ1bmN0aW9uIHJlc29sdmVyLgotICAgICAqCi0gICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBJZiA8Y29kZT5yZXNvbHZlcjwvY29kZT4gaXMKLSAgICAgKiAgIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHNldFhQYXRoRnVuY3Rpb25SZXNvbHZlcihYUGF0aEZ1bmN0aW9uUmVzb2x2ZXIgcmVzb2x2ZXIpOwotCi0gICAgLyoqCi0gICAgKiA8cD5SZXR1cm4gYSBuZXcgPGNvZGU+WFBhdGg8L2NvZGU+IHVzaW5nIHRoZSB1bmRlcmx5aW5nIG9iamVjdAotICAgICogbW9kZWwgZGV0ZXJtaW5lZCB3aGVuIHRoZSA8Y29kZT5YUGF0aEZhY3Rvcnk8L2NvZGU+IHdhcyBpbnN0YW50aWF0ZWQuPC9wPgotICAgICoKLSAgICAqIEByZXR1cm4gTmV3IGluc3RhbmNlIG9mIGFuIDxjb2RlPlhQYXRoPC9jb2RlPi4KLSAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCBYUGF0aCBuZXdYUGF0aCgpOwotfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmF4L3htbC94cGF0aC9YUGF0aEZhY3RvcnlDb25maWd1cmF0aW9uRXhjZXB0aW9uLmphdmEgYi9zcmMvamF2YXgveG1sL3hwYXRoL1hQYXRoRmFjdG9yeUNvbmZpZ3VyYXRpb25FeGNlcHRpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggY2QzZWJkZi4uMDAwMDAwMAotLS0gYS9zcmMvamF2YXgveG1sL3hwYXRoL1hQYXRoRmFjdG9yeUNvbmZpZ3VyYXRpb25FeGNlcHRpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDczICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDMsIDIwMDUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLXBhY2thZ2UgamF2YXgueG1sLnhwYXRoOwotCi0vKioKLSAqIDxjb2RlPlhQYXRoRmFjdG9yeUNvbmZpZ3VyYXRpb25FeGNlcHRpb248L2NvZGU+IHJlcHJlc2VudHMgYSBjb25maWd1cmF0aW9uIGVycm9yIGluIGEgPGNvZGU+WFBhdGhGYWN0b3J5PC9jb2RlPiBlbnZpcm9ubWVudC48L3A+Ci0gKgotICogQGF1dGhvciAgPGEgaHJlZj0ibWFpbHRvOk5vcm1hbi5XYWxzaEBTdW4uY29tIj5Ob3JtYW4gV2Fsc2g8L2E+Ci0gKiBAYXV0aG9yICA8YSBocmVmPSJtYWlsdG86SmVmZi5TdXR0b3JAU3VuLmNvbSI+SmVmZiBTdXR0b3I8L2E+Ci0gKiBAc2luY2UgMS41Ci0gKi8KLXB1YmxpYyBjbGFzcyBYUGF0aEZhY3RvcnlDb25maWd1cmF0aW9uRXhjZXB0aW9uIGV4dGVuZHMgWFBhdGhFeGNlcHRpb24gewotCi0gICAgLyoqCi0gICAgICogPHA+U3RyZWFtIFVuaXF1ZSBJZGVudGlmaWVyLjwvcD4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMTgzNzA4MDI2MDM3NDk4Njk4MEw7Ci0KLSAgICAvKioKLSAgICAgKiA8cD5Db25zdHJ1Y3RzIGEgbmV3IDxjb2RlPlhQYXRoRmFjdG9yeUNvbmZpZ3VyYXRpb25FeGNlcHRpb248L2NvZGU+IHdpdGggdGhlIHNwZWNpZmllZCBkZXRhaWwgPGNvZGU+bWVzc2FnZTwvY29kZT4uPC9wPgotICAgICAqCi0gICAgICogPHA+VGhlIDxjb2RlPmNhdXNlPC9jb2RlPiBpcyBub3QgaW5pdGlhbGl6ZWQuPC9wPgotICAgICAqCi0gICAgICogPHA+SWYgPGNvZGU+bWVzc2FnZTwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4sCi0gICAgICogdGhlbiBhIDxjb2RlPk51bGxQb2ludGVyRXhjZXB0aW9uPC9jb2RlPiBpcyB0aHJvd24uPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIG1lc3NhZ2UgVGhlIGRldGFpbCBtZXNzYWdlLgotICAgICAqCi0gICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBXaGVuIDxjb2RlPm1lc3NhZ2U8L2NvZGU+IGlzCi0gICAgICogICA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFBhdGhGYWN0b3J5Q29uZmlndXJhdGlvbkV4Y2VwdGlvbihTdHJpbmcgbWVzc2FnZSkgewotICAgICAgICBzdXBlcihtZXNzYWdlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5Db25zdHJ1Y3RzIGEgbmV3IDxjb2RlPlhQYXRoRmFjdG9yeUNvbmZpZ3VyYXRpb25FeGNlcHRpb248L2NvZGU+Ci0gICAgICogd2l0aCB0aGUgc3BlY2lmaWVkIDxjb2RlPmNhdXNlPC9jb2RlPi48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5JZiA8Y29kZT5jYXVzZTwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4sCi0gICAgICogdGhlbiBhIDxjb2RlPk51bGxQb2ludGVyRXhjZXB0aW9uPC9jb2RlPiBpcyB0aHJvd24uPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGNhdXNlIFRoZSBjYXVzZS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgPGNvZGU+Y2F1c2U8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBYUGF0aEZhY3RvcnlDb25maWd1cmF0aW9uRXhjZXB0aW9uKFRocm93YWJsZSBjYXVzZSkgewotICAgICAgICBzdXBlcihjYXVzZSk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmF4L3htbC94cGF0aC9YUGF0aEZhY3RvcnlGaW5kZXIuamF2YSBiL3NyYy9qYXZheC94bWwveHBhdGgvWFBhdGhGYWN0b3J5RmluZGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGY5OWRkYzguLjAwMDAwMDAKLS0tIGEvc3JjL2phdmF4L3htbC94cGF0aC9YUGF0aEZhY3RvcnlGaW5kZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQ0NCArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDA0LCAyMDEzLCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi1wYWNrYWdlIGphdmF4LnhtbC54cGF0aDsKLQotaW1wb3J0IGphdmEuaW8uRmlsZTsKLWltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2Q7Ci1pbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuTW9kaWZpZXI7Ci1pbXBvcnQgamF2YS5uZXQuVVJMOwotaW1wb3J0IGphdmEuc2VjdXJpdHkuQWNjZXNzQ29udHJvbENvbnRleHQ7Ci1pbXBvcnQgamF2YS5zZWN1cml0eS5BY2Nlc3NDb250cm9sbGVyOwotaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpdmlsZWdlZEFjdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKLWltcG9ydCBqYXZhLnV0aWwuU2VydmljZUNvbmZpZ3VyYXRpb25FcnJvcjsKLWltcG9ydCBqYXZhLnV0aWwuU2VydmljZUxvYWRlcjsKLQotLyoqCi0gKiBJbXBsZW1lbnRhdGlvbiBvZiB7QGxpbmsgWFBhdGhGYWN0b3J5I25ld0luc3RhbmNlKFN0cmluZyl9LgotICoKLSAqIEBhdXRob3IgPGEgaHJlZj0iS29oc3VrZS5LYXdhZ3VjaGlAU3VuLmNvbSI+S29oc3VrZSBLYXdhZ3VjaGk8L2E+Ci0gKiBAdmVyc2lvbiAkUmV2aXNpb246IDEuNyAkLCAkRGF0ZTogMjAxMC0xMS0wMSAwNDozNjoxNCAkCi0gKiBAc2luY2UgMS41Ci0gKi8KLWNsYXNzIFhQYXRoRmFjdG9yeUZpbmRlciAgewotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBERUZBVUxUX1BBQ0tBR0UgPSAiY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsIjsKLQotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFNlY3VyaXR5U3VwcG9ydCBzcyA9IG5ldyBTZWN1cml0eVN1cHBvcnQoKSA7Ci0gICAgLyoqIGRlYnVnIHN1cHBvcnQgY29kZS4gKi8KLSAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGRlYnVnID0gZmFsc2U7Ci0gICAgc3RhdGljIHsKLSAgICAgICAgLy8gVXNlIHRyeS9jYXRjaCBibG9jayB0byBzdXBwb3J0IGFwcGxldHMKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGRlYnVnID0gc3MuZ2V0U3lzdGVtUHJvcGVydHkoImpheHAuZGVidWciKSAhPSBudWxsOwotICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gdW51c2VkKSB7Ci0gICAgICAgICAgICBkZWJ1ZyA9IGZhbHNlOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogPHA+Q2FjaGUgcHJvcGVydGllcyBmb3IgcGVyZm9ybWFuY2UuPC9wPgotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFByb3BlcnRpZXMgY2FjaGVQcm9wcyA9IG5ldyBQcm9wZXJ0aWVzKCk7Ci0KLSAgICAvKioKLSAgICAgKiA8cD5GaXJzdCB0aW1lIHJlcXVpcmVzIGluaXRpYWxpemF0aW9uIG92ZXJoZWFkLjwvcD4KLSAgICAgKi8KLSAgICBwcml2YXRlIHZvbGF0aWxlIHN0YXRpYyBib29sZWFuIGZpcnN0VGltZSA9IHRydWU7Ci0KLSAgICAvKioKLSAgICAgKiA8cD5Db25kaXRpb25hbCBkZWJ1ZyBwcmludGluZy48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gbXNnIHRvIHByaW50Ci0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBkZWJ1Z1ByaW50bG4oU3RyaW5nIG1zZykgewotICAgICAgICBpZiAoZGVidWcpIHsKLSAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiSkFYUDogIiArIG1zZyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD48Y29kZT5DbGFzc0xvYWRlcjwvY29kZT4gdG8gdXNlIHRvIGZpbmQgPGNvZGU+WFBhdGhGYWN0b3J5PC9jb2RlPi48L3A+Ci0gICAgICovCi0gICAgcHJpdmF0ZSBmaW5hbCBDbGFzc0xvYWRlciBjbGFzc0xvYWRlcjsKLQotICAgIC8qKgotICAgICAqIDxwPkNvbnN0cnVjdG9yIHRoYXQgc3BlY2lmaWVzIDxjb2RlPkNsYXNzTG9hZGVyPC9jb2RlPiB0byB1c2UKLSAgICAgKiB0byBmaW5kIDxjb2RlPlhQYXRoRmFjdG9yeTwvY29kZT4uPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGxvYWRlcgotICAgICAqICAgICAgdG8gYmUgdXNlZCB0byBsb2FkIHJlc291cmNlIGFuZCB7QGxpbmsgWFBhdGhGYWN0b3J5fQotICAgICAqICAgICAgaW1wbGVtZW50YXRpb25zIGR1cmluZyB0aGUgcmVzb2x1dGlvbiBwcm9jZXNzLgotICAgICAqICAgICAgSWYgdGhpcyBwYXJhbWV0ZXIgaXMgbnVsbCwgdGhlIGRlZmF1bHQgc3lzdGVtIGNsYXNzIGxvYWRlcgotICAgICAqICAgICAgd2lsbCBiZSB1c2VkLgotICAgICAqLwotICAgIHB1YmxpYyBYUGF0aEZhY3RvcnlGaW5kZXIoQ2xhc3NMb2FkZXIgbG9hZGVyKSB7Ci0gICAgICAgIHRoaXMuY2xhc3NMb2FkZXIgPSBsb2FkZXI7Ci0gICAgICAgIGlmKCBkZWJ1ZyApIHsKLSAgICAgICAgICAgIGRlYnVnRGlzcGxheUNsYXNzTG9hZGVyKCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgZGVidWdEaXNwbGF5Q2xhc3NMb2FkZXIoKSB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBpZiggY2xhc3NMb2FkZXIgPT0gc3MuZ2V0Q29udGV4dENsYXNzTG9hZGVyKCkgKSB7Ci0gICAgICAgICAgICAgICAgZGVidWdQcmludGxuKCJ1c2luZyB0aHJlYWQgY29udGV4dCBjbGFzcyBsb2FkZXIgKCIrY2xhc3NMb2FkZXIrIikgZm9yIHNlYXJjaCIpOwotICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSBjYXRjaCggVGhyb3dhYmxlIHVudXNlZCApIHsKLSAgICAgICAgICAgICAvLyBnZXRDb250ZXh0Q2xhc3NMb2FkZXIoKSB1bmRlZmluZWQgaW4gSkRLMS4xCi0gICAgICAgIH0KLQotICAgICAgICBpZiggY2xhc3NMb2FkZXI9PUNsYXNzTG9hZGVyLmdldFN5c3RlbUNsYXNzTG9hZGVyKCkgKSB7Ci0gICAgICAgICAgICBkZWJ1Z1ByaW50bG4oInVzaW5nIHN5c3RlbSBjbGFzcyBsb2FkZXIgKCIrY2xhc3NMb2FkZXIrIikgZm9yIHNlYXJjaCIpOwotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0KLSAgICAgICAgZGVidWdQcmludGxuKCJ1c2luZyBjbGFzcyBsb2FkZXIgKCIrY2xhc3NMb2FkZXIrIikgZm9yIHNlYXJjaCIpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPkNyZWF0ZXMgYSBuZXcge0BsaW5rIFhQYXRoRmFjdG9yeX0gb2JqZWN0IGZvciB0aGUgc3BlY2lmaWVkCi0gICAgICogb2JqZWN0IG1vZGVsLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSB1cmkKLSAgICAgKiAgICAgICBJZGVudGlmaWVzIHRoZSB1bmRlcmx5aW5nIG9iamVjdCBtb2RlbC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlIGNhbGxlZSBmYWlscyB0byBjcmVhdGUgb25lLgotICAgICAqCi0gICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgotICAgICAqICAgICAgSWYgdGhlIHBhcmFtZXRlciBpcyBudWxsLgotICAgICAqLwotICAgIHB1YmxpYyBYUGF0aEZhY3RvcnkgbmV3RmFjdG9yeShTdHJpbmcgdXJpKSB0aHJvd3MgWFBhdGhGYWN0b3J5Q29uZmlndXJhdGlvbkV4Y2VwdGlvbiB7Ci0gICAgICAgIGlmICh1cmkgPT0gbnVsbCkgewotICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7Ci0gICAgICAgIH0KLSAgICAgICAgWFBhdGhGYWN0b3J5IGYgPSBfbmV3RmFjdG9yeSh1cmkpOwotICAgICAgICBpZiAoZiAhPSBudWxsKSB7Ci0gICAgICAgICAgICBkZWJ1Z1ByaW50bG4oImZhY3RvcnkgJyIgKyBmLmdldENsYXNzKCkuZ2V0TmFtZSgpICsgIicgd2FzIGZvdW5kIGZvciAiICsgdXJpKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIGRlYnVnUHJpbnRsbigidW5hYmxlIHRvIGZpbmQgYSBmYWN0b3J5IGZvciAiICsgdXJpKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiA8cD5Mb29rdXAgYSB7QGxpbmsgWFBhdGhGYWN0b3J5fSBmb3IgdGhlIGdpdmVuIG9iamVjdCBtb2RlbC48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gdXJpIGlkZW50aWZpZXMgdGhlIG9iamVjdCBtb2RlbC4KLSAgICAgKgotICAgICAqIEByZXR1cm4ge0BsaW5rIFhQYXRoRmFjdG9yeX0gZm9yIHRoZSBnaXZlbiBvYmplY3QgbW9kZWwuCi0gICAgICovCi0gICAgcHJpdmF0ZSBYUGF0aEZhY3RvcnkgX25ld0ZhY3RvcnkoU3RyaW5nIHVyaSkgdGhyb3dzIFhQYXRoRmFjdG9yeUNvbmZpZ3VyYXRpb25FeGNlcHRpb24gewotICAgICAgICBYUGF0aEZhY3RvcnkgeHBhdGhGYWN0b3J5ID0gbnVsbDsKLQotICAgICAgICBTdHJpbmcgcHJvcGVydHlOYW1lID0gU0VSVklDRV9DTEFTUy5nZXROYW1lKCkgKyAiOiIgKyB1cmk7Ci0KLSAgICAgICAgLy8gc3lzdGVtIHByb3BlcnR5IGxvb2sgdXAKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGRlYnVnUHJpbnRsbigiTG9va2luZyB1cCBzeXN0ZW0gcHJvcGVydHkgJyIrcHJvcGVydHlOYW1lKyInIiApOwotICAgICAgICAgICAgU3RyaW5nIHIgPSBzcy5nZXRTeXN0ZW1Qcm9wZXJ0eShwcm9wZXJ0eU5hbWUpOwotICAgICAgICAgICAgaWYociE9bnVsbCkgewotICAgICAgICAgICAgICAgIGRlYnVnUHJpbnRsbigiVGhlIHZhbHVlIGlzICciK3IrIiciKTsKLSAgICAgICAgICAgICAgICB4cGF0aEZhY3RvcnkgPSBjcmVhdGVJbnN0YW5jZShyLCB0cnVlKTsKLSAgICAgICAgICAgICAgICBpZiAoeHBhdGhGYWN0b3J5ICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHhwYXRoRmFjdG9yeTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9IGVsc2UKLSAgICAgICAgICAgICAgICBkZWJ1Z1ByaW50bG4oIlRoZSBwcm9wZXJ0eSBpcyB1bmRlZmluZWQuIik7Ci0gICAgICAgIH0gY2F0Y2goIFRocm93YWJsZSB0ICkgewotICAgICAgICAgICAgaWYoIGRlYnVnICkgewotICAgICAgICAgICAgICAgIGRlYnVnUHJpbnRsbigiZmFpbGVkIHRvIGxvb2sgdXAgc3lzdGVtIHByb3BlcnR5ICciK3Byb3BlcnR5TmFtZSsiJyIgKTsKLSAgICAgICAgICAgICAgICB0LnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgU3RyaW5nIGphdmFoID0gc3MuZ2V0U3lzdGVtUHJvcGVydHkoICJqYXZhLmhvbWUiICk7Ci0gICAgICAgIFN0cmluZyBjb25maWdGaWxlID0gamF2YWggKyBGaWxlLnNlcGFyYXRvciArCi0gICAgICAgICJsaWIiICsgRmlsZS5zZXBhcmF0b3IgKyAiamF4cC5wcm9wZXJ0aWVzIjsKLQotICAgICAgICAvLyB0cnkgdG8gcmVhZCBmcm9tICRqYXZhLmhvbWUvbGliL2pheHAucHJvcGVydGllcwotICAgICAgICB0cnkgewotICAgICAgICAgICAgaWYoZmlyc3RUaW1lKXsKLSAgICAgICAgICAgICAgICBzeW5jaHJvbml6ZWQoY2FjaGVQcm9wcyl7Ci0gICAgICAgICAgICAgICAgICAgIGlmKGZpcnN0VGltZSl7Ci0gICAgICAgICAgICAgICAgICAgICAgICBGaWxlIGY9bmV3IEZpbGUoIGNvbmZpZ0ZpbGUgKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGZpcnN0VGltZSA9IGZhbHNlOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYoc3MuZG9lc0ZpbGVFeGlzdChmKSl7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVidWdQcmludGxuKCJSZWFkIHByb3BlcnRpZXMgZmlsZSAiICsgZik7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FjaGVQcm9wcy5sb2FkKHNzLmdldEZpbGVJbnB1dFN0cmVhbShmKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmaW5hbCBTdHJpbmcgZmFjdG9yeUNsYXNzTmFtZSA9IGNhY2hlUHJvcHMuZ2V0UHJvcGVydHkocHJvcGVydHlOYW1lKTsKLSAgICAgICAgICAgIGRlYnVnUHJpbnRsbigiZm91bmQgIiArIGZhY3RvcnlDbGFzc05hbWUgKyAiIGluICRqYXZhLmhvbWUvamF4cC5wcm9wZXJ0aWVzIik7Ci0KLSAgICAgICAgICAgIGlmIChmYWN0b3J5Q2xhc3NOYW1lICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICB4cGF0aEZhY3RvcnkgPSBjcmVhdGVJbnN0YW5jZShmYWN0b3J5Q2xhc3NOYW1lLCB0cnVlKTsKLSAgICAgICAgICAgICAgICBpZih4cGF0aEZhY3RvcnkgIT0gbnVsbCl7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiB4cGF0aEZhY3Rvcnk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKLSAgICAgICAgICAgIGlmIChkZWJ1ZykgewotICAgICAgICAgICAgICAgIGV4LnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gVHJ5IHdpdGggU2VydmljZUxvYWRlcgotICAgICAgICBhc3NlcnQgeHBhdGhGYWN0b3J5ID09IG51bGw7Ci0gICAgICAgIHhwYXRoRmFjdG9yeSA9IGZpbmRTZXJ2aWNlUHJvdmlkZXIodXJpKTsKLQotICAgICAgICAvLyBUaGUgZm9sbG93aW5nIGFzc2VydGlvbiBzaG91bGQgYWx3YXlzIGJlIHRydWUuCi0gICAgICAgIC8vIFVuY29tbWVudCBpdCwgcmVjb21waWxlLCBhbmQgcnVuIHdpdGggLWVhIGluIGNhc2Ugb2YgZG91YnRzOgotICAgICAgICAvLyBhc3NlcnQgeHBhdGhGYWN0b3J5ID09IG51bGwgfHwgeHBhdGhGYWN0b3J5LmlzT2JqZWN0TW9kZWxTdXBwb3J0ZWQodXJpKTsKLQotICAgICAgICBpZiAoeHBhdGhGYWN0b3J5ICE9IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiB4cGF0aEZhY3Rvcnk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBwbGF0Zm9ybSBkZWZhdWx0Ci0gICAgICAgIGlmKHVyaS5lcXVhbHMoWFBhdGhGYWN0b3J5LkRFRkFVTFRfT0JKRUNUX01PREVMX1VSSSkpIHsKLSAgICAgICAgICAgIGRlYnVnUHJpbnRsbigiYXR0ZW1wdGluZyB0byB1c2UgdGhlIHBsYXRmb3JtIGRlZmF1bHQgVzNDIERPTSBYUGF0aCBsaWIiKTsKLSAgICAgICAgICAgIHJldHVybiBjcmVhdGVJbnN0YW5jZSgiY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmpheHAuWFBhdGhGYWN0b3J5SW1wbCIsIHRydWUpOwotICAgICAgICB9Ci0KLSAgICAgICAgZGVidWdQcmludGxuKCJhbGwgdGhpbmdzIHdlcmUgdHJpZWQsIGJ1dCBub25lIHdhcyBmb3VuZC4gYmFpbGluZyBvdXQuIik7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKiA8cD5DcmVhdGUgY2xhc3MgdXNpbmcgYXBwcm9wcmlhdGUgQ2xhc3NMb2FkZXIuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGNsYXNzTmFtZSBOYW1lIG9mIGNsYXNzIHRvIGNyZWF0ZS4KLSAgICAgKiBAcmV0dXJuIENyZWF0ZWQgY2xhc3Mgb3IgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICovCi0gICAgcHJpdmF0ZSBDbGFzczw/PiBjcmVhdGVDbGFzcyhTdHJpbmcgY2xhc3NOYW1lKSB7Ci0gICAgICAgIENsYXNzIGNsYXp6OwotICAgICAgICAvLyBtYWtlIHN1cmUgd2UgaGF2ZSBhY2Nlc3MgdG8gcmVzdHJpY3RlZCBwYWNrYWdlcwotICAgICAgICBib29sZWFuIGludGVybmFsID0gZmFsc2U7Ci0gICAgICAgIGlmIChTeXN0ZW0uZ2V0U2VjdXJpdHlNYW5hZ2VyKCkgIT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKGNsYXNzTmFtZSAhPSBudWxsICYmIGNsYXNzTmFtZS5zdGFydHNXaXRoKERFRkFVTFRfUEFDS0FHRSkpIHsKLSAgICAgICAgICAgICAgICBpbnRlcm5hbCA9IHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyB1c2UgYXBwcm9wcml0ZSBDbGFzc0xvYWRlcgotICAgICAgICB0cnkgewotICAgICAgICAgICAgaWYgKGNsYXNzTG9hZGVyICE9IG51bGwgJiYgIWludGVybmFsKSB7Ci0gICAgICAgICAgICAgICAgICAgIGNsYXp6ID0gQ2xhc3MuZm9yTmFtZShjbGFzc05hbWUsIGZhbHNlLCBjbGFzc0xvYWRlcik7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICBjbGF6eiA9IENsYXNzLmZvck5hbWUoY2xhc3NOYW1lKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSBjYXRjaCAoVGhyb3dhYmxlIHQpIHsKLSAgICAgICAgICAgIGlmKGRlYnVnKSB7Ci0gICAgICAgICAgICAgICAgdC5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIGNsYXp6OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPkNyZWF0ZXMgYW4gaW5zdGFuY2Ugb2YgdGhlIHNwZWNpZmllZCBhbmQgcmV0dXJucyBpdC48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gY2xhc3NOYW1lCi0gICAgICogICAgICBmdWxseSBxdWFsaWZpZWQgY2xhc3MgbmFtZSB0byBiZSBpbnN0YW50aWF0ZWQuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIG51bGwKLSAgICAgKiAgICAgIGlmIGl0IGZhaWxzLiBFcnJvciBtZXNzYWdlcyB3aWxsIGJlIHByaW50ZWQgYnkgdGhpcyBtZXRob2QuCi0gICAgICovCi0gICAgWFBhdGhGYWN0b3J5IGNyZWF0ZUluc3RhbmNlKCBTdHJpbmcgY2xhc3NOYW1lICkKLSAgICAgICAgICAgIHRocm93cyBYUGF0aEZhY3RvcnlDb25maWd1cmF0aW9uRXhjZXB0aW9uCi0gICAgewotICAgICAgICByZXR1cm4gY3JlYXRlSW5zdGFuY2UoIGNsYXNzTmFtZSwgZmFsc2UgKTsKLSAgICB9Ci0KLSAgICBYUGF0aEZhY3RvcnkgY3JlYXRlSW5zdGFuY2UoIFN0cmluZyBjbGFzc05hbWUsIGJvb2xlYW4gdXNlU2VydmljZXNNZWNoYW5pc20gICkKLSAgICAgICAgICAgIHRocm93cyBYUGF0aEZhY3RvcnlDb25maWd1cmF0aW9uRXhjZXB0aW9uCi0gICAgewotICAgICAgICBYUGF0aEZhY3RvcnkgeFBhdGhGYWN0b3J5ID0gbnVsbDsKLQotICAgICAgICBkZWJ1Z1ByaW50bG4oImNyZWF0ZUluc3RhbmNlKCIgKyBjbGFzc05hbWUgKyAiKSIpOwotCi0gICAgICAgIC8vIGdldCBDbGFzcyBmcm9tIGNsYXNzTmFtZQotICAgICAgICBDbGFzczw/PiBjbGF6eiA9IGNyZWF0ZUNsYXNzKGNsYXNzTmFtZSk7Ci0gICAgICAgIGlmIChjbGF6eiA9PSBudWxsKSB7Ci0gICAgICAgICAgICBkZWJ1Z1ByaW50bG4oImZhaWxlZCB0byBnZXRDbGFzcygiICsgY2xhc3NOYW1lICsgIikiKTsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgICAgIGRlYnVnUHJpbnRsbigibG9hZGVkICIgKyBjbGFzc05hbWUgKyAiIGZyb20gIiArIHdoaWNoKGNsYXp6KSk7Ci0KLSAgICAgICAgLy8gaW5zdGFudGlhdGUgQ2xhc3MgYXMgYSBYUGF0aEZhY3RvcnkKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIGlmICghdXNlU2VydmljZXNNZWNoYW5pc20pIHsKLSAgICAgICAgICAgICAgICB4UGF0aEZhY3RvcnkgPSBuZXdJbnN0YW5jZU5vU2VydmljZUxvYWRlcihjbGF6eik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoeFBhdGhGYWN0b3J5ID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICB4UGF0aEZhY3RvcnkgPSAoWFBhdGhGYWN0b3J5KSBjbGF6ei5uZXdJbnN0YW5jZSgpOwotICAgICAgICAgICAgfQotICAgICAgICB9IGNhdGNoIChDbGFzc0Nhc3RFeGNlcHRpb24gY2xhc3NDYXN0RXhjZXB0aW9uKSB7Ci0gICAgICAgICAgICAgICAgZGVidWdQcmludGxuKCJjb3VsZCBub3QgaW5zdGFudGlhdGUgIiArIGNsYXp6LmdldE5hbWUoKSk7Ci0gICAgICAgICAgICAgICAgaWYgKGRlYnVnKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBjbGFzc0Nhc3RFeGNlcHRpb24ucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIGlsbGVnYWxBY2Nlc3NFeGNlcHRpb24pIHsKLSAgICAgICAgICAgICAgICBkZWJ1Z1ByaW50bG4oImNvdWxkIG5vdCBpbnN0YW50aWF0ZSAiICsgY2xhenouZ2V0TmFtZSgpKTsKLSAgICAgICAgICAgICAgICBpZiAoZGVidWcpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlsbGVnYWxBY2Nlc3NFeGNlcHRpb24ucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9IGNhdGNoIChJbnN0YW50aWF0aW9uRXhjZXB0aW9uIGluc3RhbnRpYXRpb25FeGNlcHRpb24pIHsKLSAgICAgICAgICAgICAgICBkZWJ1Z1ByaW50bG4oImNvdWxkIG5vdCBpbnN0YW50aWF0ZSAiICsgY2xhenouZ2V0TmFtZSgpKTsKLSAgICAgICAgICAgICAgICBpZiAoZGVidWcpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbnRpYXRpb25FeGNlcHRpb24ucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIHhQYXRoRmFjdG9yeTsKLSAgICB9Ci0gICAgLyoqCi0gICAgICogVHJ5IHRvIGNvbnN0cnVjdCB1c2luZyBuZXdYUGF0aEZhY3RvcnlOb1NlcnZpY2VMb2FkZXIKLSAgICAgKiAgIG1ldGhvZCBpZiBhdmFpbGFibGUuCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgWFBhdGhGYWN0b3J5IG5ld0luc3RhbmNlTm9TZXJ2aWNlTG9hZGVyKAotICAgICAgICAgQ2xhc3M8Pz4gcHJvdmlkZXJDbGFzcwotICAgICkgdGhyb3dzIFhQYXRoRmFjdG9yeUNvbmZpZ3VyYXRpb25FeGNlcHRpb24gewotICAgICAgICAvLyBSZXRhaW4gbWF4aW11bSBjb21wYXRpYmlsaXR5IGlmIG5vIHNlY3VyaXR5IG1hbmFnZXIuCi0gICAgICAgIGlmIChTeXN0ZW0uZ2V0U2VjdXJpdHlNYW5hZ2VyKCkgPT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIE1ldGhvZCBjcmVhdGlvbk1ldGhvZCA9Ci0gICAgICAgICAgICAgICAgICAgIHByb3ZpZGVyQ2xhc3MuZ2V0RGVjbGFyZWRNZXRob2QoCi0gICAgICAgICAgICAgICAgICAgICAgICAibmV3WFBhdGhGYWN0b3J5Tm9TZXJ2aWNlTG9hZGVyIgotICAgICAgICAgICAgICAgICAgICApOwotICAgICAgICAgICAgZmluYWwgaW50IG1vZGlmaWVycyA9IGNyZWF0aW9uTWV0aG9kLmdldE1vZGlmaWVycygpOwotCi0gICAgICAgICAgICAvLyBEbyBub3QgY2FsbCAibmV3WFBhdGhGYWN0b3J5Tm9TZXJ2aWNlTG9hZGVyIiBpZiBpdCdzCi0gICAgICAgICAgICAvLyBub3QgcHVibGljIHN0YXRpYy4KLSAgICAgICAgICAgIGlmICghTW9kaWZpZXIuaXNTdGF0aWMobW9kaWZpZXJzKSB8fCAhTW9kaWZpZXIuaXNQdWJsaWMobW9kaWZpZXJzKSkgewotICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBPbmx5IGNhbGxzICJuZXdYUGF0aEZhY3RvcnlOb1NlcnZpY2VMb2FkZXIiIGlmIGl0J3MKLSAgICAgICAgICAgIC8vIGRlY2xhcmVkIHRvIHJldHVybiBhbiBpbnN0YW5jZSBvZiBYUGF0aEZhY3RvcnkuCi0gICAgICAgICAgICBmaW5hbCBDbGFzczw/PiByZXR1cm5UeXBlID0gY3JlYXRpb25NZXRob2QuZ2V0UmV0dXJuVHlwZSgpOwotICAgICAgICAgICAgaWYgKFNFUlZJQ0VfQ0xBU1MuaXNBc3NpZ25hYmxlRnJvbShyZXR1cm5UeXBlKSkgewotICAgICAgICAgICAgICAgIHJldHVybiBTRVJWSUNFX0NMQVNTLmNhc3QoY3JlYXRpb25NZXRob2QuaW52b2tlKG51bGwsIChPYmplY3RbXSludWxsKSk7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIC8vIFNob3VsZCBub3QgaGFwcGVuIHNpbmNlCi0gICAgICAgICAgICAgICAgLy8gWFBhdGhGYWN0b3J5SW1wbC5uZXdYUGF0aEZhY3RvcnlOb1NlcnZpY2VMb2FkZXIgaXMKLSAgICAgICAgICAgICAgICAvLyBkZWNsYXJlZCB0byByZXR1cm4gWFBhdGhGYWN0b3J5LgotICAgICAgICAgICAgICAgIHRocm93IG5ldyBDbGFzc0Nhc3RFeGNlcHRpb24ocmV0dXJuVHlwZQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiBjYW5ub3QgYmUgY2FzdCB0byAiICsgU0VSVklDRV9DTEFTUyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWFBhdGhGYWN0b3J5Q29uZmlndXJhdGlvbkV4Y2VwdGlvbihlKTsKLSAgICAgICAgfSBjYXRjaCAoTm9TdWNoTWV0aG9kRXhjZXB0aW9uIGV4YykgewotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleGMpIHsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLy8gQ2FsbCBpc09iamVjdE1vZGVsU3VwcG9ydGVkQnkgd2l0aCBpbml0aWFsIGNvbnRleHQuCi0gICAgcHJpdmF0ZSBib29sZWFuIGlzT2JqZWN0TW9kZWxTdXBwb3J0ZWRCeShmaW5hbCBYUGF0aEZhY3RvcnkgZmFjdG9yeSwKLSAgICAgICAgICAgIGZpbmFsIFN0cmluZyBvYmplY3RNb2RlbCwKLSAgICAgICAgICAgIEFjY2Vzc0NvbnRyb2xDb250ZXh0IGFjYykgewotICAgICAgICByZXR1cm4gQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQobmV3IFByaXZpbGVnZWRBY3Rpb248Qm9vbGVhbj4oKSB7Ci0gICAgICAgICAgICAgICAgICAgIHB1YmxpYyBCb29sZWFuIHJ1bigpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWN0b3J5LmlzT2JqZWN0TW9kZWxTdXBwb3J0ZWQob2JqZWN0TW9kZWwpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfSwgYWNjKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBGaW5kcyBhIHNlcnZpY2UgcHJvdmlkZXIgc3ViY2xhc3Mgb2YgWFBhdGhGYWN0b3J5IHRoYXQgc3VwcG9ydHMgdGhlCi0gICAgICogZ2l2ZW4gb2JqZWN0IG1vZGVsIHVzaW5nIHRoZSBTZXJ2aWNlTG9hZGVyLgotICAgICAqCi0gICAgICogQHBhcmFtIG9iamVjdE1vZGVsIFVSSSBvZiBvYmplY3QgbW9kZWwgdG8gc3VwcG9ydC4KLSAgICAgKiBAcmV0dXJuIEFuIFhQYXRoRmFjdG9yeSBzdXBwb3J0aW5nIHRoZSBzcGVjaWZpZWQgb2JqZWN0IG1vZGVsLCBvciBudWxsCi0gICAgICogICAgICAgICBpZiBub25lIGlzIGZvdW5kLgotICAgICAqIEB0aHJvd3MgWFBhdGhGYWN0b3J5Q29uZmlndXJhdGlvbkV4Y2VwdGlvbiBpZiBhIGNvbmZpZ3VyYXRpb24gZXJyb3IgaXMgZm91bmQuCi0gICAgICovCi0gICAgcHJpdmF0ZSBYUGF0aEZhY3RvcnkgZmluZFNlcnZpY2VQcm92aWRlcihmaW5hbCBTdHJpbmcgb2JqZWN0TW9kZWwpCi0gICAgICAgICAgICB0aHJvd3MgWFBhdGhGYWN0b3J5Q29uZmlndXJhdGlvbkV4Y2VwdGlvbiB7Ci0KLSAgICAgICAgYXNzZXJ0IG9iamVjdE1vZGVsICE9IG51bGw7Ci0gICAgICAgIC8vIHN0b3JlIGN1cnJlbnQgY29udGV4dC4KLSAgICAgICAgZmluYWwgQWNjZXNzQ29udHJvbENvbnRleHQgYWNjID0gQWNjZXNzQ29udHJvbGxlci5nZXRDb250ZXh0KCk7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICByZXR1cm4gQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQobmV3IFByaXZpbGVnZWRBY3Rpb248WFBhdGhGYWN0b3J5PigpIHsKLSAgICAgICAgICAgICAgICBwdWJsaWMgWFBhdGhGYWN0b3J5IHJ1bigpIHsKLSAgICAgICAgICAgICAgICAgICAgZmluYWwgU2VydmljZUxvYWRlcjxYUGF0aEZhY3Rvcnk+IGxvYWRlciA9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgU2VydmljZUxvYWRlci5sb2FkKFNFUlZJQ0VfQ0xBU1MpOwotICAgICAgICAgICAgICAgICAgICBmb3IgKFhQYXRoRmFjdG9yeSBmYWN0b3J5IDogbG9hZGVyKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyByZXN0b3JlIGluaXRpYWwgY29udGV4dCB0byBjYWxsCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBmYWN0b3J5LmlzT2JqZWN0TW9kZWxTdXBwb3J0ZWRCeQotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzT2JqZWN0TW9kZWxTdXBwb3J0ZWRCeShmYWN0b3J5LCBvYmplY3RNb2RlbCwgYWNjKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWN0b3J5OwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOyAvLyBubyBmYWN0b3J5IGZvdW5kLgotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0pOwotICAgICAgICB9IGNhdGNoIChTZXJ2aWNlQ29uZmlndXJhdGlvbkVycm9yIGVycm9yKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgWFBhdGhGYWN0b3J5Q29uZmlndXJhdGlvbkV4Y2VwdGlvbihlcnJvcik7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBDbGFzczxYUGF0aEZhY3Rvcnk+IFNFUlZJQ0VfQ0xBU1MgPSBYUGF0aEZhY3RvcnkuY2xhc3M7Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgd2hpY2goIENsYXNzIGNsYXp6ICkgewotICAgICAgICByZXR1cm4gd2hpY2goIGNsYXp6LmdldE5hbWUoKSwgY2xhenouZ2V0Q2xhc3NMb2FkZXIoKSApOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPlNlYXJjaCB0aGUgc3BlY2lmaWVkIGNsYXNzbG9hZGVyIGZvciB0aGUgZ2l2ZW4gY2xhc3NuYW1lLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjbGFzc25hbWUgdGhlIGZ1bGx5IHF1YWxpZmllZCBuYW1lIG9mIHRoZSBjbGFzcyB0byBzZWFyY2ggZm9yCi0gICAgICogQHBhcmFtIGxvYWRlciB0aGUgY2xhc3Nsb2FkZXIgdG8gc2VhcmNoCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRoZSBzb3VyY2UgbG9jYXRpb24gb2YgdGhlIHJlc291cmNlLCBvciBudWxsIGlmIGl0IHdhc24ndCBmb3VuZAotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyB3aGljaChTdHJpbmcgY2xhc3NuYW1lLCBDbGFzc0xvYWRlciBsb2FkZXIpIHsKLQotICAgICAgICBTdHJpbmcgY2xhc3NuYW1lQXNSZXNvdXJjZSA9IGNsYXNzbmFtZS5yZXBsYWNlKCcuJywgJy8nKSArICIuY2xhc3MiOwotCi0gICAgICAgIGlmKCBsb2FkZXI9PW51bGwgKSAgbG9hZGVyID0gQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKTsKLQotICAgICAgICAvL1VSTCBpdCA9IGxvYWRlci5nZXRSZXNvdXJjZShjbGFzc25hbWVBc1Jlc291cmNlKTsKLSAgICAgICAgVVJMIGl0ID0gc3MuZ2V0UmVzb3VyY2VBc1VSTChsb2FkZXIsIGNsYXNzbmFtZUFzUmVzb3VyY2UpOwotICAgICAgICBpZiAoaXQgIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIGl0LnRvU3RyaW5nKCk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9qYXZheC94bWwveHBhdGgvWFBhdGhGdW5jdGlvbi5qYXZhIGIvc3JjL2phdmF4L3htbC94cGF0aC9YUGF0aEZ1bmN0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGJjM2I1NDQuLjAwMDAwMDAKLS0tIGEvc3JjL2phdmF4L3htbC94cGF0aC9YUGF0aEZ1bmN0aW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw1NiArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDA1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi1wYWNrYWdlIGphdmF4LnhtbC54cGF0aDsKLQotaW1wb3J0IGphdmEudXRpbC5MaXN0OwotCi0vKioKLSAqIDxwPjxjb2RlPlhQYXRoRnVuY3Rpb248L2NvZGU+IHByb3ZpZGVzIGFjY2VzcyB0byBYUGF0aCBmdW5jdGlvbnMuPC9wPgotICoKLSAqIDxwPkZ1bmN0aW9ucyBhcmUgaWRlbnRpZmllZCBieSBRTmFtZSBhbmQgYXJpdHkgaW4gWFBhdGguPC9wPgotICoKLSAqIEBhdXRob3IgIDxhIGhyZWY9Im1haWx0bzpOb3JtYW4uV2Fsc2hAU3VuLmNvbSI+Tm9ybWFuIFdhbHNoPC9hPgotICogQGF1dGhvciAgPGEgaHJlZj0ibWFpbHRvOkplZmYuU3V0dG9yQFN1bi5jb20iPkplZmYgU3V0dG9yPC9hPgotICogQHNpbmNlIDEuNQotICovCi1wdWJsaWMgaW50ZXJmYWNlIFhQYXRoRnVuY3Rpb24gewotICAvKioKLSAgICogPHA+RXZhbHVhdGUgdGhlIGZ1bmN0aW9uIHdpdGggdGhlIHNwZWNpZmllZCBhcmd1bWVudHMuPC9wPgotICAgKgotICAgKiA8cD5UbyB0aGUgZ3JlYXRlc3QgZXh0ZW50IHBvc3NpYmxlLCBzaWRlLWVmZmVjdHMgc2hvdWxkIGJlIGF2b2lkZWQgaW4gdGhlCi0gICAqIGRlZmluaXRpb24gb2YgZXh0ZW5zaW9uIGZ1bmN0aW9ucy4gVGhlIGltcGxlbWVudGF0aW9uIGV2YWx1YXRpbmcgYW4KLSAgICogWFBhdGggZXhwcmVzc2lvbiBpcyB1bmRlciBubyBvYmxpZ2F0aW9uIHRvIGNhbGwgZXh0ZW5zaW9uIGZ1bmN0aW9ucyBpbgotICAgKiBhbnkgcGFydGljdWxhciBvcmRlciBvciBhbnkgcGFydGljdWxhciBudW1iZXIgb2YgdGltZXMuPC9wPgotICAgKgotICAgKiBAcGFyYW0gYXJncyBUaGUgYXJndW1lbnRzLCA8Y29kZT5udWxsPC9jb2RlPiBpcyBhIHZhbGlkIHZhbHVlLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSByZXN1bHQgb2YgZXZhbHVhdGluZyB0aGUgPGNvZGU+WFBhdGg8L2NvZGU+IGZ1bmN0aW9uIGFzIGFuIDxjb2RlPk9iamVjdDwvY29kZT4uCi0gICAqCi0gICAqIEB0aHJvd3MgWFBhdGhGdW5jdGlvbkV4Y2VwdGlvbiBJZiA8Y29kZT5hcmdzPC9jb2RlPiBjYW5ub3QgYmUgZXZhbHVhdGVkIHdpdGggdGhpcyA8Y29kZT5YUGF0aDwvY29kZT4gZnVuY3Rpb24uCi0gICAqLwotICBwdWJsaWMgT2JqZWN0IGV2YWx1YXRlKExpc3QgYXJncykKLSAgICB0aHJvd3MgWFBhdGhGdW5jdGlvbkV4Y2VwdGlvbjsKLX0KZGlmZiAtLWdpdCBhL3NyYy9qYXZheC94bWwveHBhdGgvWFBhdGhGdW5jdGlvbkV4Y2VwdGlvbi5qYXZhIGIvc3JjL2phdmF4L3htbC94cGF0aC9YUGF0aEZ1bmN0aW9uRXhjZXB0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDM5OGZlN2MuLjAwMDAwMDAKLS0tIGEvc3JjL2phdmF4L3htbC94cGF0aC9YUGF0aEZ1bmN0aW9uRXhjZXB0aW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3MiArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDA1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi1wYWNrYWdlIGphdmF4LnhtbC54cGF0aDsKLQotLyoqCi0gKiA8Y29kZT5YUGF0aEZ1bmN0aW9uRXhjZXB0aW9uPC9jb2RlPiByZXByZXNlbnRzIGFuIGVycm9yIHdpdGggYW4gWFBhdGggZnVuY3Rpb24uPC9wPgotICoKLSAqIEBhdXRob3IgIDxhIGhyZWY9Im1haWx0bzpOb3JtYW4uV2Fsc2hAU3VuLmNvbSI+Tm9ybWFuIFdhbHNoPC9hPgotICogQGF1dGhvciAgPGEgaHJlZj0ibWFpbHRvOkplZmYuU3V0dG9yQFN1bi5jb20iPkplZmYgU3V0dG9yPC9hPgotICogQHNpbmNlIDEuNQotICovCi1wdWJsaWMgY2xhc3MgWFBhdGhGdW5jdGlvbkV4Y2VwdGlvbiBleHRlbmRzIFhQYXRoRXhwcmVzc2lvbkV4Y2VwdGlvbiB7Ci0KLSAgICAvKioKLSAgICAgKiA8cD5TdHJlYW0gVW5pcXVlIElkZW50aWZpZXIuPC9wPgotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC0xODM3MDgwMjYwMzc0OTg2OTgwTDsKLQotICAgIC8qKgotICAgICAqIDxwPkNvbnN0cnVjdHMgYSBuZXcgPGNvZGU+WFBhdGhGdW5jdGlvbkV4Y2VwdGlvbjwvY29kZT4gd2l0aCB0aGUgc3BlY2lmaWVkIGRldGFpbCA8Y29kZT5tZXNzYWdlPC9jb2RlPi48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5UaGUgPGNvZGU+Y2F1c2U8L2NvZGU+IGlzIG5vdCBpbml0aWFsaXplZC48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5JZiA8Y29kZT5tZXNzYWdlPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPiwKLSAgICAgKiB0aGVuIGEgPGNvZGU+TnVsbFBvaW50ZXJFeGNlcHRpb248L2NvZGU+IGlzIHRocm93bi48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gbWVzc2FnZSBUaGUgZGV0YWlsIG1lc3NhZ2UuCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIFdoZW4gPGNvZGU+bWVzc2FnZTwvY29kZT4gaXMKLSAgICAgKiAgIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBYUGF0aEZ1bmN0aW9uRXhjZXB0aW9uKFN0cmluZyBtZXNzYWdlKSB7Ci0gICAgICAgIHN1cGVyKG1lc3NhZ2UpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIDxwPkNvbnN0cnVjdHMgYSBuZXcgPGNvZGU+WFBhdGhGdW5jdGlvbkV4Y2VwdGlvbjwvY29kZT4gd2l0aCB0aGUgc3BlY2lmaWVkIDxjb2RlPmNhdXNlPC9jb2RlPi48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5JZiA8Y29kZT5jYXVzZTwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4sCi0gICAgICogdGhlbiBhIDxjb2RlPk51bGxQb2ludGVyRXhjZXB0aW9uPC9jb2RlPiBpcyB0aHJvd24uPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGNhdXNlIFRoZSBjYXVzZS4KLSAgICAgKgotICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgPGNvZGU+Y2F1c2U8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBYUGF0aEZ1bmN0aW9uRXhjZXB0aW9uKFRocm93YWJsZSBjYXVzZSkgewotICAgICAgICBzdXBlcihjYXVzZSk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmF4L3htbC94cGF0aC9YUGF0aEZ1bmN0aW9uUmVzb2x2ZXIuamF2YSBiL3NyYy9qYXZheC94bWwveHBhdGgvWFBhdGhGdW5jdGlvblJlc29sdmVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDBjMzc4NmIuLjAwMDAwMDAKLS0tIGEvc3JjL2phdmF4L3htbC94cGF0aC9YUGF0aEZ1bmN0aW9uUmVzb2x2ZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDY2ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDMsIDIwMDUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLXBhY2thZ2UgamF2YXgueG1sLnhwYXRoOwotCi1pbXBvcnQgamF2YXgueG1sLm5hbWVzcGFjZS5RTmFtZTsKLQotLyoqCi0gKiA8cD48Y29kZT5YUGF0aEZ1bmN0aW9uUmVzb2x2ZXI8L2NvZGU+IHByb3ZpZGVzIGFjY2VzcyB0byB0aGUgc2V0IG9mIHVzZXIgZGVmaW5lZCA8Y29kZT5YUGF0aEZ1bmN0aW9uPC9jb2RlPnMuPC9wPgotICoKLSAqIDxwPlhQYXRoIGZ1bmN0aW9ucyBhcmUgcmVzb2x2ZWQgYnkgbmFtZSBhbmQgYXJpdHkuCi0gKiBUaGUgcmVzb2x2ZXIgaXMgbm90IG5lZWRlZCBmb3IgWFBhdGggYnVpbHQtaW4gZnVuY3Rpb25zIGFuZCB0aGUgcmVzb2x2ZXIKLSAqIDxzdHJvbmc+PGVtPmNhbm5vdDwvZW0+PC9zdHJvbmc+IGJlIHVzZWQgdG8gb3ZlcnJpZGUgdGhvc2UgZnVuY3Rpb25zLjwvcD4KLSAqCi0gKiA8cD5JbiBwYXJ0aWN1bGFyLCB0aGUgcmVzb2x2ZXIgaXMgb25seSBjYWxsZWQgZm9yIGZ1bmN0aW9ucyBpbiBhbiBhbm90aGVyCi0gKiBuYW1lc3BhY2UgKGZ1bmN0aW9ucyB3aXRoIGFuIGV4cGxpY2l0IHByZWZpeCkuIFRoaXMgbWVhbnMgdGhhdCB5b3UgY2Fubm90Ci0gKiB1c2UgdGhlIDxjb2RlPlhQYXRoRnVuY3Rpb25SZXNvbHZlcjwvY29kZT4gdG8gaW1wbGVtZW50IHNwZWNpZmljYXRpb25zCi0gKiBsaWtlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3htbGRzaWctY29yZS8iPlhNTC1TaWduYXR1cmUgU3ludGF4Ci0gKiBhbmQgUHJvY2Vzc2luZzwvYT4gd2hpY2ggZXh0ZW5kIHRoZSBmdW5jdGlvbiBsaWJyYXJ5IG9mIFhQYXRoIDEuMCBpbiB0aGUKLSAqIHNhbWUgbmFtZXNwYWNlLiBUaGlzIGlzIGEgY29uc2VxdWVuY2Ugb2YgdGhlIGRlc2lnbiBvZiB0aGUgcmVzb2x2ZXIuPC9wPgotICoKLSAqIDxwPklmIHlvdSB3aXNoIHRvIGltcGxlbWVudCBhZGRpdGlvbmFsIGJ1aWx0LWluIGZ1bmN0aW9ucywgeW91IHdpbGwgaGF2ZSB0bwotICogZXh0ZW5kIHRoZSB1bmRlcmx5aW5nIGltcGxlbWVudGF0aW9uIGRpcmVjdGx5LjwvcD4KLSAqCi0gKiBAYXV0aG9yICA8YSBocmVmPSJtYWlsdG86Tm9ybWFuLldhbHNoQFN1bi5jb20iPk5vcm1hbiBXYWxzaDwvYT4KLSAqIEBhdXRob3IgIDxhIGhyZWY9Im1haWx0bzpKZWZmLlN1dHRvckBTdW4uY29tIj5KZWZmIFN1dHRvcjwvYT4KLSAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGgjY29yZWxpYiI+WE1MIFBhdGggTGFuZ3VhZ2UgKFhQYXRoKSBWZXJzaW9uIDEuMCwgQ29yZSBGdW5jdGlvbiBMaWJyYXJ5PC9hPgotICogQHNpbmNlIDEuNQotICovCi1wdWJsaWMgaW50ZXJmYWNlIFhQYXRoRnVuY3Rpb25SZXNvbHZlciB7Ci0gIC8qKgotICAgKiA8cD5GaW5kIGEgZnVuY3Rpb24gaW4gdGhlIHNldCBvZiBhdmFpbGFibGUgZnVuY3Rpb25zLjwvcD4KLSAgICoKLSAgICogPHA+SWYgPGNvZGU+ZnVuY3Rpb25OYW1lPC9jb2RlPiBvciA8Y29kZT5hcml0eTwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4sIHRoZW4gYSA8Y29kZT5OdWxsUG9pbnRlckV4Y2VwdGlvbjwvY29kZT4gaXMgdGhyb3duLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIGZ1bmN0aW9uTmFtZSBUaGUgZnVuY3Rpb24gbmFtZS4KLSAgICogQHBhcmFtIGFyaXR5IFRoZSBudW1iZXIgb2YgYXJndW1lbnRzIHRoYXQgdGhlIHJldHVybmVkIGZ1bmN0aW9uIG11c3QgYWNjZXB0LgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBmdW5jdGlvbiBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiBubyBmdW5jdGlvbiBuYW1lZCA8Y29kZT5mdW5jdGlvbk5hbWU8L2NvZGU+IHdpdGggPGNvZGU+YXJpdHk8L2NvZGU+IGFyZ3VtZW50cyBleGlzdHMuCi0gICAqCi0gICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gSWYgPGNvZGU+ZnVuY3Rpb25OYW1lPC9jb2RlPiBvciA8Y29kZT5hcml0eTwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAqLwotICBwdWJsaWMgWFBhdGhGdW5jdGlvbiByZXNvbHZlRnVuY3Rpb24oUU5hbWUgZnVuY3Rpb25OYW1lLCBpbnQgYXJpdHkpOwotfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmF4L3htbC94cGF0aC9YUGF0aFZhcmlhYmxlUmVzb2x2ZXIuamF2YSBiL3NyYy9qYXZheC94bWwveHBhdGgvWFBhdGhWYXJpYWJsZVJlc29sdmVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDA5NTdjMjguLjAwMDAwMDAKLS0tIGEvc3JjL2phdmF4L3htbC94cGF0aC9YUGF0aFZhcmlhYmxlUmVzb2x2ZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDU4ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDMsIDIwMDUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLXBhY2thZ2UgamF2YXgueG1sLnhwYXRoOwotCi1pbXBvcnQgamF2YXgueG1sLm5hbWVzcGFjZS5RTmFtZTsKLQotLyoqCi0gKiA8cD48Y29kZT5YUGF0aFZhcmlhYmxlUmVzb2x2ZXI8L2NvZGU+IHByb3ZpZGVzIGFjY2VzcyB0byB0aGUgc2V0IG9mIHVzZXIgZGVmaW5lZCBYUGF0aCB2YXJpYWJsZXMuPC9wPgotICoKLSAqIDxwPlRoZSA8Y29kZT5YUGF0aFZhcmlhYmxlUmVzb2x2ZXI8L2NvZGU+IGFuZCB0aGUgWFBhdGggZXZhbHVhdG9yIG11c3QgYWRoZXJlIHRvIGEgY29udHJhY3QgdGhhdAotICogY2Fubm90IGJlIGRpcmVjdGx5IGVuZm9yY2VkIGJ5IHRoZSBBUEkuICBBbHRob3VnaCB2YXJpYWJsZXMgbWF5IGJlIG11dGFibGUsCi0gKiB0aGF0IGlzLCBhbiBhcHBsaWNhdGlvbiBtYXkgd2lzaCB0byBldmFsdWF0ZSB0aGUgc2FtZSBYUGF0aCBleHByZXNzaW9uIG1vcmUKLSAqIHRoYW4gb25jZSB3aXRoIGRpZmZlcmVudCB2YXJpYWJsZSB2YWx1ZXMsIGluIHRoZSBjb3Vyc2Ugb2YgZXZhbHVhdGluZyBhbnkKLSAqIHNpbmdsZSBYUGF0aCBleHByZXNzaW9uLCBhIHZhcmlhYmxlJ3MgdmFsdWUgPHN0cm9uZz48ZW0+bXVzdDwvZW0+PC9zdHJvbmc+Ci0gKiBub3QgY2hhbmdlLjwvcD4KLSAqCi0gKiBAYXV0aG9yICA8YSBocmVmPSJtYWlsdG86Tm9ybWFuLldhbHNoQFN1bi5jb20iPk5vcm1hbiBXYWxzaDwvYT4KLSAqIEBhdXRob3IgIDxhIGhyZWY9Im1haWx0bzpKZWZmLlN1dHRvckBTdW4uY29tIj5KZWZmIFN1dHRvcjwvYT4KLSAqIEBzaW5jZSAxLjUKLSAqLwotcHVibGljIGludGVyZmFjZSBYUGF0aFZhcmlhYmxlUmVzb2x2ZXIgewotICAvKioKLSAgICogPHA+RmluZCBhIHZhcmlhYmxlIGluIHRoZSBzZXQgb2YgYXZhaWxhYmxlIHZhcmlhYmxlcy48L3A+Ci0gICAqCi0gICAqIDxwPklmIDxjb2RlPnZhcmlhYmxlTmFtZTwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4sIHRoZW4gYSA8Y29kZT5OdWxsUG9pbnRlckV4Y2VwdGlvbjwvY29kZT4gaXMgdGhyb3duLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIHZhcmlhYmxlTmFtZSBUaGUgPGNvZGU+UU5hbWU8L2NvZGU+IG9mIHRoZSB2YXJpYWJsZSBuYW1lLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSB2YXJpYWJsZXMgdmFsdWUsIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIG5vIHZhcmlhYmxlIG5hbWVkIDxjb2RlPnZhcmlhYmxlTmFtZTwvY29kZT4KLSAgICogICBleGlzdHMuICBUaGUgdmFsdWUgcmV0dXJuZWQgbXVzdCBiZSBvZiBhIHR5cGUgYXBwcm9wcmlhdGUgZm9yIHRoZSB1bmRlcmx5aW5nIG9iamVjdCBtb2RlbC4KLSAgICoKLSAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBJZiA8Y29kZT52YXJpYWJsZU5hbWU8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LgotICAgKi8KLSAgcHVibGljIE9iamVjdCByZXNvbHZlVmFyaWFibGUoUU5hbWUgdmFyaWFibGVOYW1lKTsKLX0KZGlmZiAtLWdpdCBhL3NyYy9qYXZheC94bWwveHBhdGgvcGFja2FnZS5odG1sIGIvc3JjL2phdmF4L3htbC94cGF0aC9wYWNrYWdlLmh0bWwKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDZmNDkyMjIuLjAwMDAwMDAKLS0tIGEvc3JjL2phdmF4L3htbC94cGF0aC9wYWNrYWdlLmh0bWwKKysrIC9kZXYvbnVsbApAQCAtMSwyODIgKzAsMCBAQAotPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KLTwhLS0KLUNvcHlyaWdodCAoYykgMjAwMywgMjAwNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLURPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLQotVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLXVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi1wdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLXBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLWJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotCi1UaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLUFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi12ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLQotWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotCi1QbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotcXVlc3Rpb25zLiAKLS0tPgotCi08IURPQ1RZUEUgaHRtbCBQVUJMSUMgIi0vL1czQy8vRFREIFhIVE1MIDEuMCBTdHJpY3QvL0VOIgotICAgICAgICAgICAgICAgICAgICAgICJodHRwOi8vd3d3LnczLm9yZy9UUi94aHRtbDEvRFREL3hodG1sMS1zdHJpY3QuZHRkIj4KLTxodG1sIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sIj4KLTxoZWFkPgotPHRpdGxlPmphdmF4LnhtbC54cGF0aDwvdGl0bGU+Ci08bWV0YSBuYW1lPSJAYXV0aG9yIiBjb250ZW50PSJtYWlsdG86QmVuQGdhbGJyYWl0aHMub3JnIiAvPgotPG1ldGEgbmFtZT0iQGF1dGhvciIgY29udGVudD0ibWFpbHRvOk5vcm1hbi5XYWxzaEBTdW4uY29tIiAvPgotPG1ldGEgbmFtZT0iQGF1dGhvciIgY29udGVudD0ibWFpbHRvOkplZmYuU3V0dG9yQFN1bi5jb20iIC8+Ci08bWV0YSBuYW1lPSJAdmVyc2lvbiIgY29udGVudD0iJFJldmlzaW9uOiAxLjMgJCwgJERhdGU6IDIwMDUvMTEvMDMgMTk6MzQ6MTcgJCIgLz4KLTxtZXRhIG5hbWU9IkBzZWUiIGNvbnRlbnQ9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hwYXRoIiAvPgotPG1ldGEgbmFtZT0iQHNpbmNlIiBjb250ZW50PSIxLjUiIC8+Ci08L2hlYWQ+Ci0KLTxib2R5PgotCi08cD5UaGlzIHBhY2thZ2UgcHJvdmlkZXMgYW4gPGVtPm9iamVjdC1tb2RlbCBuZXV0cmFsPC9lbT4gQVBJIGZvciB0aGUKLWV2YWx1YXRpb24gb2YgWFBhdGggZXhwcmVzc2lvbnMgYW5kIGFjY2VzcyB0byB0aGUgZXZhbHVhdGlvbgotZW52aXJvbm1lbnQuCi08L3A+Ci0KLTxwPlRoZSBmb2xsb3dpbmcgWE1MIHN0YW5kYXJkcyBhcHBseTo8L3A+Ci0KLTx1bD4KLTxsaT48YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aCI+WE1MIFBhdGggTGFuZ3VhZ2UgKFhQYXRoKSBWZXJzaW9uIDEuMDwvYT48L2xpPgotPC91bD4KLQotPGhyIC8+Ci0KLTxoMj5YUGF0aCBPdmVydmlldzwvaDI+Ci0KLTxwPlRoZSBYUGF0aCBsYW5ndWFnZSBwcm92aWRlcyBhIHNpbXBsZSwgY29uY2lzZSBzeW50YXggZm9yIHNlbGVjdGluZwotbm9kZXMgZnJvbSBhbiBYTUwgZG9jdW1lbnQuIFhQYXRoIGFsc28gcHJvdmlkZXMgcnVsZXMgZm9yIGNvbnZlcnRpbmcgYQotbm9kZSBpbiBhbiBYTUwgZG9jdW1lbnQgb2JqZWN0IG1vZGVsIChET00pIHRyZWUgdG8gYSBib29sZWFuLCBkb3VibGUsCi1vciBzdHJpbmcgdmFsdWUuIFhQYXRoIGlzIGEgVzNDLWRlZmluZWQgbGFuZ3VhZ2UgYW5kIGFuIG9mZmljaWFsIFczQwotcmVjb21tZW5kYXRpb247IHRoZSBXM0MgaG9zdHMgdGhlIFhNTCBQYXRoIExhbmd1YWdlIChYUGF0aCkgVmVyc2lvbgotMS4wIHNwZWNpZmljYXRpb24uCi08L3A+Ci0KLTxwPlhQYXRoIHN0YXJ0ZWQgaW4gbGlmZSBpbiAxOTk5IGFzIGEgc3VwcGxlbWVudCB0byB0aGUgWFNMVCBhbmQKLVhQb2ludGVyIGxhbmd1YWdlcywgYnV0IGhhcyBtb3JlIHJlY2VudGx5IGJlY29tZSBwb3B1bGFyIGFzIGEKLXN0YW5kLWFsb25lIGxhbmd1YWdlLCBhcyBhIHNpbmdsZSBYUGF0aCBleHByZXNzaW9uIGNhbiBiZSB1c2VkIHRvCi1yZXBsYWNlIG1hbnkgbGluZXMgb2YgRE9NIEFQSSBjb2RlLgotPC9wPgotCi08aDM+WFBhdGggRXhwcmVzc2lvbnM8L2gzPgotCi08cD5BbiBYUGF0aCA8ZW0+ZXhwcmVzc2lvbjwvZW0+IGlzIGNvbXBvc2VkIG9mIGEgPGVtPmxvY2F0aW9uCi1wYXRoPC9lbT4gYW5kIG9uZSBvciBtb3JlIG9wdGlvbmFsIDxlbT5wcmVkaWNhdGVzPC9lbT4uIEV4cHJlc3Npb25zCi1tYXkgYWxzbyBpbmNsdWRlIFhQYXRoIHZhcmlhYmxlcy4KLTwvcD4KLQotPHA+VGhlIGZvbGxvd2luZyBpcyBhbiBleGFtcGxlIG9mIGEgc2ltcGxlIFhQYXRoIGV4cHJlc3Npb246PC9wPgotCi08cHJlPgotL2Zvby9iYXIKLTwvcHJlPgotCi08cD5UaGlzIGV4YW1wbGUgd291bGQgc2VsZWN0IHRoZSA8Y29kZT4mbHQ7YmFyJmd0OzwvY29kZT4gZWxlbWVudCBpbgotYW4gWE1MIGRvY3VtZW50IHN1Y2ggYXMgdGhlIGZvbGxvd2luZzo8L3A+Ci0KLTxwcmU+Ci0mbHQ7Zm9vJmd0OwotJmx0O2Jhci8mZ3Q7Ci0mbHQ7L2ZvbyZndDsKLTwvcHJlPgotCi08cD5UaGUgZXhwcmVzc2lvbiA8Y29kZT4vZm9vL2JhcjwvY29kZT4gaXMgYW4gZXhhbXBsZSBvZiBhIGxvY2F0aW9uCi1wYXRoLiBXaGlsZSBYUGF0aCBsb2NhdGlvbiBwYXRocyByZXNlbWJsZSBVbml4LXN0eWxlIGZpbGUgc3lzdGVtCi1wYXRocywgYW4gaW1wb3J0YW50IGRpc3RpbmN0aW9uIGlzIHRoYXQgWFBhdGggZXhwcmVzc2lvbnMgcmV0dXJuCi08ZW0+YWxsPC9lbT4gbm9kZXMgdGhhdCBtYXRjaCB0aGUgZXhwcmVzc2lvbi4gVGh1cywgYWxsIHRocmVlCi08Y29kZT4mbHQ7YmFyJmd0OzwvY29kZT4gZWxlbWVudHMgaW4gdGhlIGZvbGxvd2luZyBkb2N1bWVudCB3b3VsZCBiZQotc2VsZWN0ZWQgYnkgdGhlIDxjb2RlPi9mb28vYmFyPC9jb2RlPiBleHByZXNzaW9uOjwvcD4KLQotPHByZT4KLSZsdDtmb28mZ3Q7Ci0mbHQ7YmFyLyZndDsKLSZsdDtiYXIvJmd0OwotJmx0O2Jhci8mZ3Q7Ci0mbHQ7L2ZvbyZndDsKLTwvcHJlPgotCi08cD5BIHNwZWNpYWwgbG9jYXRpb24gcGF0aCBvcGVyYXRvciwgPGNvZGU+Ly88L2NvZGU+LCBzZWxlY3RzIG5vZGVzIGF0Ci1hbnkgZGVwdGggaW4gYW4gWE1MIGRvY3VtZW50LiBUaGUgZm9sbG93aW5nIGV4YW1wbGUgc2VsZWN0cyBhbGwKLTxjb2RlPiZsdDtiYXImZ3Q7PC9jb2RlPiBlbGVtZW50cyByZWdhcmRsZXNzIG9mIHRoZWlyIGxvY2F0aW9uIGluIGEKLWRvY3VtZW50OjwvcD4KLQotPHByZT4KLS8vYmFyCi08L3ByZT4KLQotPHA+QSB3aWxkY2FyZCBvcGVyYXRvciwgKiwgY2F1c2VzIGFsbCBlbGVtZW50IG5vZGVzIHRvIGJlIHNlbGVjdGVkLgotVGhlIGZvbGxvd2luZyBleGFtcGxlIHNlbGVjdHMgYWxsIGNoaWxkcmVuIGVsZW1lbnRzIG9mIGEKLTxjb2RlPiZsdDtmb28mZ3Q7PC9jb2RlPiBlbGVtZW50OjwvcD4KLQotPHByZT4KLS9mb28vKgotPC9wcmU+Ci0KLTxwPkluIGFkZGl0aW9uIHRvIGVsZW1lbnQgbm9kZXMsIFhQYXRoIGxvY2F0aW9uIHBhdGhzIG1heSBhbHNvIGFkZHJlc3MKLWF0dHJpYnV0ZSBub2RlcywgdGV4dCBub2RlcywgY29tbWVudCBub2RlcywgYW5kIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24KLW5vZGVzLiBUaGUgZm9sbG93aW5nIHRhYmxlIGdpdmVzIGV4YW1wbGVzIG9mIGxvY2F0aW9uIHBhdGhzIGZvciBlYWNoCi1vZiB0aGVzZSBub2RlIHR5cGVzOjwvcD4KLQotPHRhYmxlIGJvcmRlcj0iMSI+Ci08dHI+Ci08dGQ+TG9jYXRpb24gUGF0aDwvdGQ+Ci08dGQ+RGVzY3JpcHRpb248L3RkPgotPC90cj4KLTx0cj4KLTx0ZD4KLTxjb2RlPi9mb28vYmFyLzxzdHJvbmc+QGlkPC9zdHJvbmc+PC9jb2RlPgotPC90ZD4KLTx0ZD5TZWxlY3RzIHRoZSBhdHRyaWJ1dGUgPGNvZGU+aWQ8L2NvZGU+IG9mIHRoZSA8Y29kZT4mbHQ7YmFyJmd0OzwvY29kZT4gZWxlbWVudAotPC90ZD4KLTwvdHI+Ci08dHI+Ci08dGQ+PGNvZGU+L2Zvby9iYXIvPHN0cm9uZz50ZXh0KCk8L3N0cm9uZz48L2NvZGU+Ci08L3RkPgotPHRkPlNlbGVjdHMgdGhlIHRleHQgbm9kZXMgb2YgdGhlIDxjb2RlPiZsdDtiYXImZ3Q7PC9jb2RlPiBlbGVtZW50LiBObwotZGlzdGluY3Rpb24gaXMgbWFkZSBiZXR3ZWVuIGVzY2FwZWQgYW5kIG5vbi1lc2NhcGVkIGNoYXJhY3RlciBkYXRhLgotPC90ZD4KLTwvdHI+Ci08dHI+Ci08dGQ+PGNvZGU+L2Zvby9iYXIvPHN0cm9uZz5jb21tZW50KCk8L3N0cm9uZz48L2NvZGU+Ci08L3RkPgotPHRkPlNlbGVjdHMgYWxsIGNvbW1lbnQgbm9kZXMgY29udGFpbmVkIGluIHRoZSA8Y29kZT4mbHQ7YmFyJmd0OzwvY29kZT4gZWxlbWVudC4KLTwvdGQ+Ci08L3RyPgotPHRyPgotPHRkPjxjb2RlPi9mb28vYmFyLzxzdHJvbmc+cHJvY2Vzc2luZy1pbnN0cnVjdGlvbigpPC9zdHJvbmc+PC9jb2RlPgotPC90ZD4KLTx0ZD5TZWxlY3RzIGFsbCBwcm9jZXNzaW5nLWluc3RydWN0aW9uIG5vZGVzIGNvbnRhaW5lZCBpbiB0aGUKLTxjb2RlPiZsdDtiYXImZ3Q7PC9jb2RlPiBlbGVtZW50LgotPC90ZD4KLTwvdHI+Ci08L3RhYmxlPgotCi08cD5QcmVkaWNhdGVzIGFsbG93IGZvciByZWZpbmluZyB0aGUgbm9kZXMgc2VsZWN0ZWQgYnkgYW4gWFBhdGgKLWxvY2F0aW9uIHBhdGguIFByZWRpY2F0ZXMgYXJlIG9mIHRoZSBmb3JtCi08Y29kZT5bPGVtPmV4cHJlc3Npb248L2VtPl08L2NvZGU+LiBUaGUgZm9sbG93aW5nIGV4YW1wbGUgc2VsZWN0cyBhbGwKLTxjb2RlPiZsdDtmb28mZ3Q7PC9jb2RlPiBlbGVtZW50cyB0aGF0IGNvbnRhaW4gYW4gPGNvZGU+aW5jbHVkZTwvY29kZT4KLWF0dHJpYnV0ZSB3aXRoIHRoZSB2YWx1ZSBvZiA8Y29kZT50cnVlPC9jb2RlPjo8L3A+Ci0KLTxwcmU+Ci0vL2Zvb1tAaW5jbHVkZT0ndHJ1ZSddCi08L3ByZT4KLQotPHA+UHJlZGljYXRlcyBtYXkgYmUgYXBwZW5kZWQgdG8gZWFjaCBvdGhlciB0byBmdXJ0aGVyIHJlZmluZSBhbgotZXhwcmVzc2lvbiwgc3VjaCBhczo8L3A+Ci0KLTxwcmU+Ci0vL2Zvb1tAaW5jbHVkZT0ndHJ1ZSddW0Btb2RlPSdiYXInXQotPC9wcmU+Ci0KLTxoMz5Vc2luZyB0aGUgWFBhdGggQVBJPC9oMz4KLQotPHA+Ci1UaGUgZm9sbG93aW5nIGV4YW1wbGUgZGVtb25zdHJhdGVzIHVzaW5nIHRoZSBYUGF0aCBBUEkgdG8gc2VsZWN0IG9uZQotb3IgbW9yZSBub2RlcyBmcm9tIGFuIFhNTCBkb2N1bWVudDo8L3A+Ci0KLTxwcmU+Ci1YUGF0aCB4cGF0aCA9IFhQYXRoRmFjdG9yeS5uZXdJbnN0YW5jZSgpLm5ld1hQYXRoKCk7Ci1TdHJpbmcgZXhwcmVzc2lvbiA9ICIvd2lkZ2V0cy93aWRnZXQiOwotSW5wdXRTb3VyY2UgaW5wdXRTb3VyY2UgPSBuZXcgSW5wdXRTb3VyY2UoIndpZGdldHMueG1sIik7Ci1Ob2RlTGlzdCBub2RlcyA9IChOb2RlTGlzdCkgeHBhdGguZXZhbHVhdGUoZXhwcmVzc2lvbiwgaW5wdXRTb3VyY2UsIFhQYXRoQ29uc3RhbnRzLk5PREVTRVQpOwotPC9wcmU+Ci0KLTxoMz5YUGF0aCBFeHByZXNzaW9ucyBhbmQgVHlwZXM8L2gzPgotCi08cD5XaGlsZSBYUGF0aCBleHByZXNzaW9ucyBzZWxlY3Qgbm9kZXMgaW4gdGhlIFhNTCBkb2N1bWVudCwgdGhlIFhQYXRoCi1BUEkgYWxsb3dzIHRoZSBzZWxlY3RlZCBub2RlcyB0byBiZSBjb2FsZXNjZWQgaW50byBvbmUgb2YgdGhlCi1mb2xsb3dpbmcgb3RoZXIgZGF0YSB0eXBlczo8L3A+Ci0KLTx1bD4KLTxsaT48Y29kZT5Cb29sZWFuPC9jb2RlPjwvbGk+Ci08bGk+PGNvZGU+TnVtYmVyPC9jb2RlPjwvbGk+Ci08bGk+PGNvZGU+U3RyaW5nPC9jb2RlPjwvbGk+Ci08L3VsPgotCi08cD5UaGUgZGVzaXJlZCByZXR1cm4gdHlwZSBpcyBzcGVjaWZpZWQgYnkgYSB7QGxpbmsKLWphdmF4LnhtbC5uYW1lc3BhY2UuUU5hbWV9IHBhcmFtZXRlciBpbiBtZXRob2QgY2FsbCB1c2VkIHRvIGV2YWx1YXRlCi10aGUgZXhwcmVzc2lvbiwgd2hpY2ggaXMgZWl0aGVyIGEgY2FsbCB0bwotPGNvZGU+WFBhdGhFeHByZXNzaW9uLmV2YWx1dGUoLi4uKTwvY29kZT4gb3IgdG8gb25lIG9mIHRoZQotPGNvZGU+WFBhdGguZXZhbHVhdGUoLi4uKTwvY29kZT4gY29udmVuaWVuY2UgbWV0aG9kcy4gVGhlIGFsbG93ZWQKLVFOYW1lIHZhbHVlcyBhcmUgc3BlY2lmaWVkIGFzIGNvbnN0YW50cyBpbiB0aGUge0BsaW5rCi1qYXZheC54bWwueHBhdGguWFBhdGhDb25zdGFudHN9IGNsYXNzOyB0aGV5IGFyZTo8L3A+Ci0KLTx1bD4KLTxsaT57QGxpbmsgamF2YXgueG1sLnhwYXRoLlhQYXRoQ29uc3RhbnRzI05PREVTRVR9PC9saT4KLTxsaT57QGxpbmsgamF2YXgueG1sLnhwYXRoLlhQYXRoQ29uc3RhbnRzI05PREV9PC9saT4KLTxsaT57QGxpbmsgamF2YXgueG1sLnhwYXRoLlhQYXRoQ29uc3RhbnRzI1NUUklOR308L2xpPgotPGxpPntAbGluayBqYXZheC54bWwueHBhdGguWFBhdGhDb25zdGFudHMjQk9PTEVBTn08L2xpPgotPGxpPntAbGluayBqYXZheC54bWwueHBhdGguWFBhdGhDb25zdGFudHMjTlVNQkVSfTwvbGk+Ci08L3VsPgotCi08cD5XaGVuIGEgPGNvZGU+Qm9vbGVhbjwvY29kZT4gcmV0dXJuIHR5cGUgaXMgcmVxdWVzdGVkLAotPGNvZGU+Qm9vbGVhbi5UUlVFPC9jb2RlPiBpcyByZXR1cm5lZCBpZiBvbmUgb3IgbW9yZSBub2RlcyB3ZXJlCi1zZWxlY3RlZDsgb3RoZXJ3aXNlLCA8Y29kZT5Cb29sZWFuLkZBTFNFPC9jb2RlPiBpcyByZXR1cm5lZC48L3A+Ci0KLTxwPlRoZSA8Y29kZT5TdHJpbmc8L2NvZGU+IHJldHVybiB0eXBlIGlzIGEgY29udmVuaWVuY2UgZm9yIHJldHJpZXZpbmcKLXRoZSBjaGFyYWN0ZXIgZGF0YSBmcm9tIGEgdGV4dCBub2RlLCBhdHRyaWJ1dGUgbm9kZSwgY29tbWVudCBub2RlLCBvcgotcHJvY2Vzc2luZy1pbnN0cnVjdGlvbiBub2RlLiBXaGVuIHVzZWQgb24gYW4gZWxlbWVudCBub2RlLCB0aGUgdmFsdWUKLW9mIHRoZSBjaGlsZCB0ZXh0IG5vZGVzIGlzIHJldHVybmVkLgotPC9wPgotCi08cD5UaGUgPGNvZGU+TnVtYmVyPC9jb2RlPiByZXR1cm4gdHlwZSBhdHRlbXB0cyB0byBjb2FsZXNjZSB0aGUgdGV4dAotb2YgYSBub2RlIHRvIGEgPGNvZGU+ZG91YmxlPC9jb2RlPiBkYXRhIHR5cGUuCi08L3A+Ci0KLTxoMz5YUGF0aCBDb250ZXh0PC9oMz4KLQotPHA+WFBhdGggbG9jYXRpb24gcGF0aHMgbWF5IGJlIHJlbGF0aXZlIHRvIGEgcGFydGljdWxhciBub2RlIGluIHRoZQotZG9jdW1lbnQsIGtub3duIGFzIHRoZSA8Y29kZT5jb250ZXh0PC9jb2RlPi4gQ29uc2lkZXIgdGhlIGZvbGxvd2luZwotWE1MIGRvY3VtZW50OjwvcD4KLQotPHByZT4KLSZsdDt3aWRnZXRzJmd0OwotJmx0O3dpZGdldCZndDsKLSZsdDttYW51ZmFjdHVyZXIvJmd0OwotJmx0O2RpbWVuc2lvbnMvJmd0OwotJmx0Oy93aWRnZXQmZ3Q7Ci0mbHQ7L3dpZGdldHMmZ3Q7Ci08L3ByZT4KLQotPHA+VGhlIDxjb2RlPiZsdDt3aWRnZXQmZ3Q7PC9jb2RlPiBlbGVtZW50IGNhbiBiZSBzZWxlY3RlZCB3aXRoIHRoZQotZm9sbG93aW5nIFhQYXRoIEFQSSBjb2RlOjwvcD4KLQotPHByZT4KLS8vIHBhcnNlIHRoZSBYTUwgYXMgYSBXM0MgRG9jdW1lbnQKLURvY3VtZW50QnVpbGRlciBidWlsZGVyID0gRG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5uZXdJbnN0YW5jZSgpLm5ld0RvY3VtZW50QnVpbGRlcigpOwotRG9jdW1lbnQgZG9jdW1lbnQgPSBidWlsZGVyLnBhcnNlKG5ldyBGaWxlKCIvd2lkZ2V0cy54bWwiKSk7Ci0KLVhQYXRoIHhwYXRoID0gWFBhdGhGYWN0b3J5Lm5ld0luc3RhbmNlKCkubmV3WFBhdGgoKTsKLVN0cmluZyBleHByZXNzaW9uID0gIi93aWRnZXRzL3dpZGdldCI7Ci1Ob2RlIHdpZGdldE5vZGUgPSAoTm9kZSkgeHBhdGguZXZhbHVhdGUoZXhwcmVzc2lvbiwgZG9jdW1lbnQsIFhQYXRoQ29uc3RhbnRzLk5PREUpOwotPC9wcmU+Ci0KLTxwPldpdGggYSByZWZlcmVuY2UgdG8gdGhlIDxjb2RlPiZsdDt3aWRnZXQmZ3Q7PC9jb2RlPiBlbGVtZW50LCBhCi1yZWxhdGl2ZSBYUGF0aCBleHByZXNzaW9uIGNhbiBub3cgd3JpdHRlbiB0byBzZWxlY3QgdGhlCi08Y29kZT4mbHQ7bWFudWZhY3R1cmVyJmd0OzwvY29kZT4gY2hpbGQgZWxlbWVudDo8L3A+Ci0KLTxwcmU+Ci1YUGF0aCB4cGF0aCA9IFhQYXRoRmFjdG9yeS5uZXdJbnN0YW5jZSgpLm5ld1hQYXRoKCk7Ci08c3Ryb25nPlN0cmluZyBleHByZXNzaW9uID0gIm1hbnVmYWN0dXJlciI7PC9zdHJvbmc+Ci1Ob2RlIG1hbnVmYWN0dXJlck5vZGUgPSAoTm9kZSkgeHBhdGguZXZhbHVhdGUoZXhwcmVzc2lvbiwgPHN0cm9uZz53aWRnZXROb2RlPC9zdHJvbmc+LCBYUGF0aENvbnN0YW50cy5OT0RFKTsKLTwvcHJlPgotCi08dWw+Ci08bGk+QXV0aG9yIDxhIGhyZWY9Im1haWx0bzpCZW5AZ2FsYnJhaXRocy5vcmciPkJlbiBHYWxicmFpdGg8L2E+PC9saT4KLTxsaT5BdXRob3IgPGEgaHJlZj0ibWFpbHRvOk5vcm1hbi5XYWxzaEBTdW4uY29tIj5Ob3JtYW4gV2Fsc2g8L2E+PC9saT4KLTxsaT5BdXRob3IgPGEgaHJlZj0ibWFpbHRvOkplZmYuU3V0dG9yQFN1bi5jb20iPkplZmYgU3V0dG9yPC9hPjwvbGk+Ci08bGk+U2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hwYXRoIj5YTUwgUGF0aCBMYW5ndWFnZSAoWFBhdGgpIFZlcnNpb24gMS4wPC9hPjwvbGk+Ci08bGk+U2luY2UgMS41PC9saT4KLTwvdWw+CQkKLTwvYm9keT4KLTwvaHRtbD4KZGlmZiAtLWdpdCBhL3NyYy9vcmcvdzNjL2RvbS9BdHRyLmphdmEgYi9zcmMvb3JnL3czYy9kb20vQXR0ci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4MjMxYTU0Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS9BdHRyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzMDQgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIFRoaXMgZmlsZSBpcyBhdmFpbGFibGUgdW5kZXIgYW5kIGdvdmVybmVkIGJ5IHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKLSAqIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICogSG93ZXZlciwgdGhlIGZvbGxvd2luZyBub3RpY2UgYWNjb21wYW5pZWQgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcwotICogZmlsZSBhbmQsIHBlciBpdHMgdGVybXMsIHNob3VsZCBub3QgYmUgcmVtb3ZlZDoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKLSAqCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgRXVyb3BlYW4gUmVzZWFyY2ggQ29uc29ydGl1bSBmb3IKLSAqIEluZm9ybWF0aWNzIGFuZCBNYXRoZW1hdGljcywgS2VpbyBVbml2ZXJzaXR5KS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcwotICogd29yayBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDKHIpIFNvZnR3YXJlIExpY2Vuc2UgWzFdIGluIHRoZSBob3BlIHRoYXQKLSAqIGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZAotICogd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLgotICoKLSAqIFsxXSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLzIwMDIvY29weXJpZ2h0LXNvZnR3YXJlLTIwMDIxMjMxCi0gKi8KLQotcGFja2FnZSBvcmcudzNjLmRvbTsKLQotLyoqCi0gKiBUaGUgPGNvZGU+QXR0cjwvY29kZT4gaW50ZXJmYWNlIHJlcHJlc2VudHMgYW4gYXR0cmlidXRlIGluIGFuCi0gKiA8Y29kZT5FbGVtZW50PC9jb2RlPiBvYmplY3QuIFR5cGljYWxseSB0aGUgYWxsb3dhYmxlIHZhbHVlcyBmb3IgdGhlCi0gKiBhdHRyaWJ1dGUgYXJlIGRlZmluZWQgaW4gYSBzY2hlbWEgYXNzb2NpYXRlZCB3aXRoIHRoZSBkb2N1bWVudC4KLSAqIDxwPjxjb2RlPkF0dHI8L2NvZGU+IG9iamVjdHMgaW5oZXJpdCB0aGUgPGNvZGU+Tm9kZTwvY29kZT4gaW50ZXJmYWNlLCBidXQKLSAqIHNpbmNlIHRoZXkgYXJlIG5vdCBhY3R1YWxseSBjaGlsZCBub2RlcyBvZiB0aGUgZWxlbWVudCB0aGV5IGRlc2NyaWJlLCB0aGUKLSAqIERPTSBkb2VzIG5vdCBjb25zaWRlciB0aGVtIHBhcnQgb2YgdGhlIGRvY3VtZW50IHRyZWUuIFRodXMsIHRoZQotICogPGNvZGU+Tm9kZTwvY29kZT4gYXR0cmlidXRlcyA8Y29kZT5wYXJlbnROb2RlPC9jb2RlPiwKLSAqIDxjb2RlPnByZXZpb3VzU2libGluZzwvY29kZT4sIGFuZCA8Y29kZT5uZXh0U2libGluZzwvY29kZT4gaGF2ZSBhCi0gKiA8Y29kZT5udWxsPC9jb2RlPiB2YWx1ZSBmb3IgPGNvZGU+QXR0cjwvY29kZT4gb2JqZWN0cy4gVGhlIERPTSB0YWtlcyB0aGUKLSAqIHZpZXcgdGhhdCBhdHRyaWJ1dGVzIGFyZSBwcm9wZXJ0aWVzIG9mIGVsZW1lbnRzIHJhdGhlciB0aGFuIGhhdmluZyBhCi0gKiBzZXBhcmF0ZSBpZGVudGl0eSBmcm9tIHRoZSBlbGVtZW50cyB0aGV5IGFyZSBhc3NvY2lhdGVkIHdpdGg7IHRoaXMgc2hvdWxkCi0gKiBtYWtlIGl0IG1vcmUgZWZmaWNpZW50IHRvIGltcGxlbWVudCBzdWNoIGZlYXR1cmVzIGFzIGRlZmF1bHQgYXR0cmlidXRlcwotICogYXNzb2NpYXRlZCB3aXRoIGFsbCBlbGVtZW50cyBvZiBhIGdpdmVuIHR5cGUuIEZ1cnRoZXJtb3JlLAotICogPGNvZGU+QXR0cjwvY29kZT4gbm9kZXMgbWF5IG5vdCBiZSBpbW1lZGlhdGUgY2hpbGRyZW4gb2YgYQotICogPGNvZGU+RG9jdW1lbnRGcmFnbWVudDwvY29kZT4uIEhvd2V2ZXIsIHRoZXkgY2FuIGJlIGFzc29jaWF0ZWQgd2l0aAotICogPGNvZGU+RWxlbWVudDwvY29kZT4gbm9kZXMgY29udGFpbmVkIHdpdGhpbiBhCi0gKiA8Y29kZT5Eb2N1bWVudEZyYWdtZW50PC9jb2RlPi4gSW4gc2hvcnQsIHVzZXJzIGFuZCBpbXBsZW1lbnRvcnMgb2YgdGhlCi0gKiBET00gbmVlZCB0byBiZSBhd2FyZSB0aGF0IDxjb2RlPkF0dHI8L2NvZGU+IG5vZGVzIGhhdmUgc29tZSB0aGluZ3MgaW4KLSAqIGNvbW1vbiB3aXRoIG90aGVyIG9iamVjdHMgaW5oZXJpdGluZyB0aGUgPGNvZGU+Tm9kZTwvY29kZT4gaW50ZXJmYWNlLCBidXQKLSAqIHRoZXkgYWxzbyBhcmUgcXVpdGUgZGlzdGluY3QuCi0gKiA8cD5UaGUgYXR0cmlidXRlJ3MgZWZmZWN0aXZlIHZhbHVlIGlzIGRldGVybWluZWQgYXMgZm9sbG93czogaWYgdGhpcwotICogYXR0cmlidXRlIGhhcyBiZWVuIGV4cGxpY2l0bHkgYXNzaWduZWQgYW55IHZhbHVlLCB0aGF0IHZhbHVlIGlzIHRoZQotICogYXR0cmlidXRlJ3MgZWZmZWN0aXZlIHZhbHVlOyBvdGhlcndpc2UsIGlmIHRoZXJlIGlzIGEgZGVjbGFyYXRpb24gZm9yCi0gKiB0aGlzIGF0dHJpYnV0ZSwgYW5kIHRoYXQgZGVjbGFyYXRpb24gaW5jbHVkZXMgYSBkZWZhdWx0IHZhbHVlLCB0aGVuIHRoYXQKLSAqIGRlZmF1bHQgdmFsdWUgaXMgdGhlIGF0dHJpYnV0ZSdzIGVmZmVjdGl2ZSB2YWx1ZTsgb3RoZXJ3aXNlLCB0aGUKLSAqIGF0dHJpYnV0ZSBkb2VzIG5vdCBleGlzdCBvbiB0aGlzIGVsZW1lbnQgaW4gdGhlIHN0cnVjdHVyZSBtb2RlbCB1bnRpbCBpdAotICogaGFzIGJlZW4gZXhwbGljaXRseSBhZGRlZC4gTm90ZSB0aGF0IHRoZSA8Y29kZT5Ob2RlLm5vZGVWYWx1ZTwvY29kZT4KLSAqIGF0dHJpYnV0ZSBvbiB0aGUgPGNvZGU+QXR0cjwvY29kZT4gaW5zdGFuY2UgY2FuIGFsc28gYmUgdXNlZCB0byByZXRyaWV2ZQotICogdGhlIHN0cmluZyB2ZXJzaW9uIG9mIHRoZSBhdHRyaWJ1dGUncyB2YWx1ZShzKS4KLSAqIDxwPiBJZiB0aGUgYXR0cmlidXRlIHdhcyBub3QgZXhwbGljaXRseSBnaXZlbiBhIHZhbHVlIGluIHRoZSBpbnN0YW5jZQotICogZG9jdW1lbnQgYnV0IGhhcyBhIGRlZmF1bHQgdmFsdWUgcHJvdmlkZWQgYnkgdGhlIHNjaGVtYSBhc3NvY2lhdGVkIHdpdGgKLSAqIHRoZSBkb2N1bWVudCwgYW4gYXR0cmlidXRlIG5vZGUgd2lsbCBiZSBjcmVhdGVkIHdpdGgKLSAqIDxjb2RlPnNwZWNpZmllZDwvY29kZT4gc2V0IHRvIDxjb2RlPmZhbHNlPC9jb2RlPi4gUmVtb3ZpbmcgYXR0cmlidXRlCi0gKiBub2RlcyBmb3Igd2hpY2ggYSBkZWZhdWx0IHZhbHVlIGlzIGRlZmluZWQgaW4gdGhlIHNjaGVtYSBnZW5lcmF0ZXMgYSBuZXcKLSAqIGF0dHJpYnV0ZSBub2RlIHdpdGggdGhlIGRlZmF1bHQgdmFsdWUgYW5kIDxjb2RlPnNwZWNpZmllZDwvY29kZT4gc2V0IHRvCi0gKiA8Y29kZT5mYWxzZTwvY29kZT4uIElmIHZhbGlkYXRpb24gb2NjdXJyZWQgd2hpbGUgaW52b2tpbmcKLSAqIDxjb2RlPkRvY3VtZW50Lm5vcm1hbGl6ZURvY3VtZW50KCk8L2NvZGU+LCBhdHRyaWJ1dGUgbm9kZXMgd2l0aAotICogPGNvZGU+c3BlY2lmaWVkPC9jb2RlPiBlcXVhbHMgdG8gPGNvZGU+ZmFsc2U8L2NvZGU+IGFyZSByZWNvbXB1dGVkCi0gKiBhY2NvcmRpbmcgdG8gdGhlIGRlZmF1bHQgYXR0cmlidXRlIHZhbHVlcyBwcm92aWRlZCBieSB0aGUgc2NoZW1hLiBJZiBubwotICogZGVmYXVsdCB2YWx1ZSBpcyBhc3NvY2lhdGUgd2l0aCB0aGlzIGF0dHJpYnV0ZSBpbiB0aGUgc2NoZW1hLCB0aGUKLSAqIGF0dHJpYnV0ZSBub2RlIGlzIGRpc2NhcmRlZC4KLSAqIDxwPkluIFhNTCwgd2hlcmUgdGhlIHZhbHVlIG9mIGFuIGF0dHJpYnV0ZSBjYW4gY29udGFpbiBlbnRpdHkgcmVmZXJlbmNlcywKLSAqIHRoZSBjaGlsZCBub2RlcyBvZiB0aGUgPGNvZGU+QXR0cjwvY29kZT4gbm9kZSBtYXkgYmUgZWl0aGVyCi0gKiA8Y29kZT5UZXh0PC9jb2RlPiBvciA8Y29kZT5FbnRpdHlSZWZlcmVuY2U8L2NvZGU+IG5vZGVzICh3aGVuIHRoZXNlIGFyZQotICogaW4gdXNlOyBzZWUgdGhlIGRlc2NyaXB0aW9uIG9mIDxjb2RlPkVudGl0eVJlZmVyZW5jZTwvY29kZT4gZm9yCi0gKiBkaXNjdXNzaW9uKS4KLSAqIDxwPlRoZSBET00gQ29yZSByZXByZXNlbnRzIGFsbCBhdHRyaWJ1dGUgdmFsdWVzIGFzIHNpbXBsZSBzdHJpbmdzLCBldmVuIGlmCi0gKiB0aGUgRFREIG9yIHNjaGVtYSBhc3NvY2lhdGVkIHdpdGggdGhlIGRvY3VtZW50IGRlY2xhcmVzIHRoZW0gb2Ygc29tZQotICogc3BlY2lmaWMgdHlwZSBzdWNoIGFzIHRva2VuaXplZC4KLSAqIDxwPlRoZSB3YXkgYXR0cmlidXRlIHZhbHVlIG5vcm1hbGl6YXRpb24gaXMgcGVyZm9ybWVkIGJ5IHRoZSBET00KLSAqIGltcGxlbWVudGF0aW9uIGRlcGVuZHMgb24gaG93IG11Y2ggdGhlIGltcGxlbWVudGF0aW9uIGtub3dzIGFib3V0IHRoZQotICogc2NoZW1hIGluIHVzZS4gVHlwaWNhbGx5LCB0aGUgPGNvZGU+dmFsdWU8L2NvZGU+IGFuZAotICogPGNvZGU+bm9kZVZhbHVlPC9jb2RlPiBhdHRyaWJ1dGVzIG9mIGFuIDxjb2RlPkF0dHI8L2NvZGU+IG5vZGUgaW5pdGlhbGx5Ci0gKiByZXR1cm5zIHRoZSBub3JtYWxpemVkIHZhbHVlIGdpdmVuIGJ5IHRoZSBwYXJzZXIuIEl0IGlzIGFsc28gdGhlIGNhc2UKLSAqIGFmdGVyIDxjb2RlPkRvY3VtZW50Lm5vcm1hbGl6ZURvY3VtZW50KCk8L2NvZGU+IGlzIGNhbGxlZCAoYXNzdW1pbmcgdGhlCi0gKiByaWdodCBvcHRpb25zIGhhdmUgYmVlbiBzZXQpLiBCdXQgdGhpcyBtYXkgbm90IGJlIHRoZSBjYXNlIGFmdGVyCi0gKiBtdXRhdGlvbiwgaW5kZXBlbmRlbnRseSBvZiB3aGV0aGVyIHRoZSBtdXRhdGlvbiBpcyBwZXJmb3JtZWQgYnkgc2V0dGluZwotICogdGhlIHN0cmluZyB2YWx1ZSBkaXJlY3RseSBvciBieSBjaGFuZ2luZyB0aGUgPGNvZGU+QXR0cjwvY29kZT4gY2hpbGQKLSAqIG5vZGVzLiBJbiBwYXJ0aWN1bGFyLCB0aGlzIGlzIHRydWUgd2hlbiA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy14bWwtMjAwNDAyMDQjZHQtY2hhcnJlZic+Y2hhcmFjdGVyCi0gKiByZWZlcmVuY2VzPC9hPiBhcmUgaW52b2x2ZWQsIGdpdmVuIHRoYXQgdGhleSBhcmUgbm90IHJlcHJlc2VudGVkIGluIHRoZSBET00gYW5kIHRoZXkKLSAqIGltcGFjdCBhdHRyaWJ1dGUgdmFsdWUgbm9ybWFsaXphdGlvbi4gT24gdGhlIG90aGVyIGhhbmQsIGlmIHRoZQotICogaW1wbGVtZW50YXRpb24ga25vd3MgYWJvdXQgdGhlIHNjaGVtYSBpbiB1c2Ugd2hlbiB0aGUgYXR0cmlidXRlIHZhbHVlIGlzCi0gKiBjaGFuZ2VkLCBhbmQgaXQgaXMgb2YgYSBkaWZmZXJlbnQgdHlwZSB0aGFuIENEQVRBLCBpdCBtYXkgbm9ybWFsaXplIGl0Ci0gKiBhZ2FpbiBhdCB0aGF0IHRpbWUuIFRoaXMgaXMgZXNwZWNpYWxseSB0cnVlIG9mIHNwZWNpYWxpemVkIERPTQotICogaW1wbGVtZW50YXRpb25zLCBzdWNoIGFzIFNWRyBET00gaW1wbGVtZW50YXRpb25zLCB3aGljaCBzdG9yZSBhdHRyaWJ1dGUKLSAqIHZhbHVlcyBpbiBhbiBpbnRlcm5hbCBmb3JtIGRpZmZlcmVudCBmcm9tIGEgc3RyaW5nLgotICogPHA+VGhlIGZvbGxvd2luZyB0YWJsZSBnaXZlcyBzb21lIGV4YW1wbGVzIG9mIHRoZSByZWxhdGlvbnMgYmV0d2VlbiB0aGUKLSAqIGF0dHJpYnV0ZSB2YWx1ZSBpbiB0aGUgb3JpZ2luYWwgZG9jdW1lbnQgKHBhcnNlZCBhdHRyaWJ1dGUpLCB0aGUgdmFsdWUgYXMKLSAqIGV4cG9zZWQgaW4gdGhlIERPTSwgYW5kIHRoZSBzZXJpYWxpemF0aW9uIG9mIHRoZSB2YWx1ZToKLSAqIDx0YWJsZSBib3JkZXI9JzEnIGNlbGxwYWRkaW5nPSczJz4KLSAqIDx0cj4KLSAqIDx0aD5FeGFtcGxlczwvdGg+Ci0gKiA8dGg+UGFyc2VkCi0gKiBhdHRyaWJ1dGUgdmFsdWU8L3RoPgotICogPHRoPkluaXRpYWwgPGNvZGU+QXR0ci52YWx1ZTwvY29kZT48L3RoPgotICogPHRoPlNlcmlhbGl6ZWQgYXR0cmlidXRlIHZhbHVlPC90aD4KLSAqIDwvdHI+Ci0gKiA8dHI+Ci0gKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPgotICogQ2hhcmFjdGVyIHJlZmVyZW5jZTwvdGQ+Ci0gKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPgotICogPHByZT4ieCZhbXA7IzE3ODs9NSI8L3ByZT4KLSAqIDwvdGQ+Ci0gKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPgotICogPHByZT4ieFx1MDBiMj01IjwvcHJlPgotICogPC90ZD4KLSAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+Ci0gKiA8cHJlPiJ4JmFtcDsjMTc4Oz01IjwvcHJlPgotICogPC90ZD4KLSAqIDwvdHI+Ci0gKiA8dHI+Ci0gKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPkJ1aWx0LWluCi0gKiBjaGFyYWN0ZXIgZW50aXR5PC90ZD4KLSAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+Ci0gKiA8cHJlPiJ5JmFtcDtsdDs2IjwvcHJlPgotICogPC90ZD4KLSAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+Ci0gKiA8cHJlPiJ5Jmx0OzYiPC9wcmU+Ci0gKiA8L3RkPgotICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz4KLSAqIDxwcmU+InkmYW1wO2x0OzYiPC9wcmU+Ci0gKiA8L3RkPgotICogPC90cj4KLSAqIDx0cj4KLSAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+TGl0ZXJhbCBuZXdsaW5lIGJldHdlZW48L3RkPgotICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz4KLSAqIDxwcmU+Ci0gKiAieD01JmFtcDsjMTA7eT02IjwvcHJlPgotICogPC90ZD4KLSAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+Ci0gKiA8cHJlPiJ4PTUgeT02IjwvcHJlPgotICogPC90ZD4KLSAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+Ci0gKiA8cHJlPiJ4PTUmYW1wOyMxMDt5PTYiPC9wcmU+Ci0gKiA8L3RkPgotICogPC90cj4KLSAqIDx0cj4KLSAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+Tm9ybWFsaXplZCBuZXdsaW5lIGJldHdlZW48L3RkPgotICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz4KLSAqIDxwcmU+Ing9NQotICogeT02IjwvcHJlPgotICogPC90ZD4KLSAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+Ci0gKiA8cHJlPiJ4PTUgeT02IjwvcHJlPgotICogPC90ZD4KLSAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+Ci0gKiA8cHJlPiJ4PTUgeT02IjwvcHJlPgotICogPC90ZD4KLSAqIDwvdHI+Ci0gKiA8dHI+Ci0gKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPkVudGl0eSA8Y29kZT5lPC9jb2RlPiB3aXRoIGxpdGVyYWwgbmV3bGluZTwvdGQ+Ci0gKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPgotICogPHByZT4KLSAqICZsdDshRU5USVRZIGUgJy4uLiZhbXA7IzEwOy4uLicmZ3Q7IFsuLi5dJmd0OyAieD01JmFtcDtlO3k9NiI8L3ByZT4KLSAqIDwvdGQ+Ci0gKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPjxlbT5EZXBlbmRlbnQgb24gSW1wbGVtZW50YXRpb24gYW5kIExvYWQgT3B0aW9uczwvZW0+PC90ZD4KLSAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+PGVtPkRlcGVuZGVudCBvbiBJbXBsZW1lbnRhdGlvbiBhbmQgTG9hZC9TYXZlIE9wdGlvbnM8L2VtPjwvdGQ+Ci0gKiA8L3RyPgotICogPC90YWJsZT4KLSAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy1ET00tTGV2ZWwtMy1Db3JlLTIwMDQwNDA3Jz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMyBDb3JlIFNwZWNpZmljYXRpb248L2E+LgotICovCi1wdWJsaWMgaW50ZXJmYWNlIEF0dHIgZXh0ZW5kcyBOb2RlIHsKLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoaXMgYXR0cmlidXRlLiBJZiA8Y29kZT5Ob2RlLmxvY2FsTmFtZTwvY29kZT4gaXMKLSAgICAgKiBkaWZmZXJlbnQgZnJvbSA8Y29kZT5udWxsPC9jb2RlPiwgdGhpcyBhdHRyaWJ1dGUgaXMgYSBxdWFsaWZpZWQgbmFtZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKTsKLQotICAgIC8qKgotICAgICAqICA8Y29kZT5UcnVlPC9jb2RlPiBpZiB0aGlzIGF0dHJpYnV0ZSB3YXMgZXhwbGljaXRseSBnaXZlbiBhIHZhbHVlIGluCi0gICAgICogdGhlIGluc3RhbmNlIGRvY3VtZW50LCA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLiBJZiB0aGUKLSAgICAgKiBhcHBsaWNhdGlvbiBjaGFuZ2VkIHRoZSB2YWx1ZSBvZiB0aGlzIGF0dHJpYnV0ZSBub2RlIChldmVuIGlmIGl0IGVuZHMKLSAgICAgKiB1cCBoYXZpbmcgdGhlIHNhbWUgdmFsdWUgYXMgdGhlIGRlZmF1bHQgdmFsdWUpIHRoZW4gaXQgaXMgc2V0IHRvCi0gICAgICogPGNvZGU+dHJ1ZTwvY29kZT4uIFRoZSBpbXBsZW1lbnRhdGlvbiBtYXkgaGFuZGxlIGF0dHJpYnV0ZXMgd2l0aAotICAgICAqIGRlZmF1bHQgdmFsdWVzIGZyb20gb3RoZXIgc2NoZW1hcyBzaW1pbGFybHkgYnV0IGFwcGxpY2F0aW9ucyBzaG91bGQKLSAgICAgKiB1c2UgPGNvZGU+RG9jdW1lbnQubm9ybWFsaXplRG9jdW1lbnQoKTwvY29kZT4gdG8gZ3VhcmFudGVlIHRoaXMKLSAgICAgKiBpbmZvcm1hdGlvbiBpcyB1cC10by1kYXRlLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGdldFNwZWNpZmllZCgpOwotCi0gICAgLyoqCi0gICAgICogT24gcmV0cmlldmFsLCB0aGUgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZSBpcyByZXR1cm5lZCBhcyBhIHN0cmluZy4KLSAgICAgKiBDaGFyYWN0ZXIgYW5kIGdlbmVyYWwgZW50aXR5IHJlZmVyZW5jZXMgYXJlIHJlcGxhY2VkIHdpdGggdGhlaXIKLSAgICAgKiB2YWx1ZXMuIFNlZSBhbHNvIHRoZSBtZXRob2QgPGNvZGU+Z2V0QXR0cmlidXRlPC9jb2RlPiBvbiB0aGUKLSAgICAgKiA8Y29kZT5FbGVtZW50PC9jb2RlPiBpbnRlcmZhY2UuCi0gICAgICogPGJyPk9uIHNldHRpbmcsIHRoaXMgY3JlYXRlcyBhIDxjb2RlPlRleHQ8L2NvZGU+IG5vZGUgd2l0aCB0aGUgdW5wYXJzZWQKLSAgICAgKiBjb250ZW50cyBvZiB0aGUgc3RyaW5nLCBpLmUuIGFueSBjaGFyYWN0ZXJzIHRoYXQgYW4gWE1MIHByb2Nlc3NvcgotICAgICAqIHdvdWxkIHJlY29nbml6ZSBhcyBtYXJrdXAgYXJlIGluc3RlYWQgdHJlYXRlZCBhcyBsaXRlcmFsIHRleHQuIFNlZQotICAgICAqIGFsc28gdGhlIG1ldGhvZCA8Y29kZT5FbGVtZW50LnNldEF0dHJpYnV0ZSgpPC9jb2RlPi4KLSAgICAgKiA8YnI+IFNvbWUgc3BlY2lhbGl6ZWQgaW1wbGVtZW50YXRpb25zLCBzdWNoIGFzIHNvbWUgWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDMvUkVDLVNWRzExLTIwMDMwMTE0Lyc+U1ZHIDEuMTwvYT5dCi0gICAgICogaW1wbGVtZW50YXRpb25zLCBtYXkgZG8gbm9ybWFsaXphdGlvbiBhdXRvbWF0aWNhbGx5LCBldmVuIGFmdGVyCi0gICAgICogbXV0YXRpb247IGluIHN1Y2ggY2FzZSwgdGhlIHZhbHVlIG9uIHJldHJpZXZhbCBtYXkgZGlmZmVyIGZyb20gdGhlCi0gICAgICogdmFsdWUgb24gc2V0dGluZy4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFZhbHVlKCk7Ci0gICAgLyoqCi0gICAgICogT24gcmV0cmlldmFsLCB0aGUgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZSBpcyByZXR1cm5lZCBhcyBhIHN0cmluZy4KLSAgICAgKiBDaGFyYWN0ZXIgYW5kIGdlbmVyYWwgZW50aXR5IHJlZmVyZW5jZXMgYXJlIHJlcGxhY2VkIHdpdGggdGhlaXIKLSAgICAgKiB2YWx1ZXMuIFNlZSBhbHNvIHRoZSBtZXRob2QgPGNvZGU+Z2V0QXR0cmlidXRlPC9jb2RlPiBvbiB0aGUKLSAgICAgKiA8Y29kZT5FbGVtZW50PC9jb2RlPiBpbnRlcmZhY2UuCi0gICAgICogPGJyPk9uIHNldHRpbmcsIHRoaXMgY3JlYXRlcyBhIDxjb2RlPlRleHQ8L2NvZGU+IG5vZGUgd2l0aCB0aGUgdW5wYXJzZWQKLSAgICAgKiBjb250ZW50cyBvZiB0aGUgc3RyaW5nLCBpLmUuIGFueSBjaGFyYWN0ZXJzIHRoYXQgYW4gWE1MIHByb2Nlc3NvcgotICAgICAqIHdvdWxkIHJlY29nbml6ZSBhcyBtYXJrdXAgYXJlIGluc3RlYWQgdHJlYXRlZCBhcyBsaXRlcmFsIHRleHQuIFNlZQotICAgICAqIGFsc28gdGhlIG1ldGhvZCA8Y29kZT5FbGVtZW50LnNldEF0dHJpYnV0ZSgpPC9jb2RlPi4KLSAgICAgKiA8YnI+IFNvbWUgc3BlY2lhbGl6ZWQgaW1wbGVtZW50YXRpb25zLCBzdWNoIGFzIHNvbWUgWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDMvUkVDLVNWRzExLTIwMDMwMTE0Lyc+U1ZHIDEuMTwvYT5dCi0gICAgICogaW1wbGVtZW50YXRpb25zLCBtYXkgZG8gbm9ybWFsaXphdGlvbiBhdXRvbWF0aWNhbGx5LCBldmVuIGFmdGVyCi0gICAgICogbXV0YXRpb247IGluIHN1Y2ggY2FzZSwgdGhlIHZhbHVlIG9uIHJldHJpZXZhbCBtYXkgZGlmZmVyIGZyb20gdGhlCi0gICAgICogdmFsdWUgb24gc2V0dGluZy4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgd2hlbiB0aGUgbm9kZSBpcyByZWFkb25seS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRWYWx1ZShTdHJpbmcgdmFsdWUpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIFRoZSA8Y29kZT5FbGVtZW50PC9jb2RlPiBub2RlIHRoaXMgYXR0cmlidXRlIGlzIGF0dGFjaGVkIHRvIG9yCi0gICAgICogPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhpcyBhdHRyaWJ1dGUgaXMgbm90IGluIHVzZS4KLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDIKLSAgICAgKi8KLSAgICBwdWJsaWMgRWxlbWVudCBnZXRPd25lckVsZW1lbnQoKTsKLQotICAgIC8qKgotICAgICAqICBUaGUgdHlwZSBpbmZvcm1hdGlvbiBhc3NvY2lhdGVkIHdpdGggdGhpcyBhdHRyaWJ1dGUuIFdoaWxlIHRoZSB0eXBlCi0gICAgICogaW5mb3JtYXRpb24gY29udGFpbmVkIGluIHRoaXMgYXR0cmlidXRlIGlzIGd1YXJhbnRlZSB0byBiZSBjb3JyZWN0Ci0gICAgICogYWZ0ZXIgbG9hZGluZyB0aGUgZG9jdW1lbnQgb3IgaW52b2tpbmcKLSAgICAgKiA8Y29kZT5Eb2N1bWVudC5ub3JtYWxpemVEb2N1bWVudCgpPC9jb2RlPiwgPGNvZGU+c2NoZW1hVHlwZUluZm88L2NvZGU+Ci0gICAgICogIG1heSBub3QgYmUgcmVsaWFibGUgaWYgdGhlIG5vZGUgd2FzIG1vdmVkLgotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgICAqLwotICAgIHB1YmxpYyBUeXBlSW5mbyBnZXRTY2hlbWFUeXBlSW5mbygpOwotCi0gICAgLyoqCi0gICAgICogIFJldHVybnMgd2hldGhlciB0aGlzIGF0dHJpYnV0ZSBpcyBrbm93biB0byBiZSBvZiB0eXBlIElEIChpLmUuIHRvCi0gICAgICogY29udGFpbiBhbiBpZGVudGlmaWVyIGZvciBpdHMgb3duZXIgZWxlbWVudCkgb3Igbm90LiBXaGVuIGl0IGlzIGFuZAotICAgICAqIGl0cyB2YWx1ZSBpcyB1bmlxdWUsIHRoZSA8Y29kZT5vd25lckVsZW1lbnQ8L2NvZGU+IG9mIHRoaXMgYXR0cmlidXRlCi0gICAgICogY2FuIGJlIHJldHJpZXZlZCB1c2luZyB0aGUgbWV0aG9kIDxjb2RlPkRvY3VtZW50LmdldEVsZW1lbnRCeUlkPC9jb2RlPgotICAgICAqIC4gVGhlIGltcGxlbWVudGF0aW9uIGNvdWxkIHVzZSBzZXZlcmFsIHdheXMgdG8gZGV0ZXJtaW5lIGlmIGFuCi0gICAgICogYXR0cmlidXRlIG5vZGUgaXMga25vd24gdG8gY29udGFpbiBhbiBpZGVudGlmaWVyOgotICAgICAqIDx1bD4KLSAgICAgKiA8bGk+IElmIHZhbGlkYXRpb24KLSAgICAgKiBvY2N1cnJlZCB1c2luZyBhbiBYTUwgU2NoZW1hIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAxL1JFQy14bWxzY2hlbWEtMS0yMDAxMDUwMi8nPlhNTCBTY2hlbWEgUGFydCAxPC9hPl0KLSAgICAgKiAgd2hpbGUgbG9hZGluZyB0aGUgZG9jdW1lbnQgb3Igd2hpbGUgaW52b2tpbmcKLSAgICAgKiA8Y29kZT5Eb2N1bWVudC5ub3JtYWxpemVEb2N1bWVudCgpPC9jb2RlPiwgdGhlIHBvc3Qtc2NoZW1hLXZhbGlkYXRpb24KLSAgICAgKiBpbmZvc2V0IGNvbnRyaWJ1dGlvbnMgKFBTVkkgY29udHJpYnV0aW9ucykgdmFsdWVzIGFyZSB1c2VkIHRvCi0gICAgICogZGV0ZXJtaW5lIGlmIHRoaXMgYXR0cmlidXRlIGlzIGEgc2NoZW1hLWRldGVybWluZWQgSUQgYXR0cmlidXRlIHVzaW5nCi0gICAgICogdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDMvUkVDLXhwdHItZnJhbWV3b3JrLTIwMDMwMzI1LyN0ZXJtLXNkaSc+Ci0gICAgICogc2NoZW1hLWRldGVybWluZWQgSUQ8L2E+IGRlZmluaXRpb24gaW4gWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDMvUkVDLXhwdHItZnJhbWV3b3JrLTIwMDMwMzI1Lyc+WFBvaW50ZXI8L2E+XQotICAgICAqIC4KLSAgICAgKiA8L2xpPgotICAgICAqIDxsaT4gSWYgdmFsaWRhdGlvbiBvY2N1cnJlZCB1c2luZyBhIERURCB3aGlsZSBsb2FkaW5nIHRoZSBkb2N1bWVudCBvcgotICAgICAqIHdoaWxlIGludm9raW5nIDxjb2RlPkRvY3VtZW50Lm5vcm1hbGl6ZURvY3VtZW50KCk8L2NvZGU+LCB0aGUgaW5mb3NldCA8Yj5bdHlwZSBkZWZpbml0aW9uXTwvYj4gdmFsdWUgaXMgdXNlZCB0byBkZXRlcm1pbmUgaWYgdGhpcyBhdHRyaWJ1dGUgaXMgYSBEVEQtZGV0ZXJtaW5lZCBJRAotICAgICAqIGF0dHJpYnV0ZSB1c2luZyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMy9SRUMteHB0ci1mcmFtZXdvcmstMjAwMzAzMjUvI3Rlcm0tZGRpJz4KLSAgICAgKiBEVEQtZGV0ZXJtaW5lZCBJRDwvYT4gZGVmaW5pdGlvbiBpbiBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMy9SRUMteHB0ci1mcmFtZXdvcmstMjAwMzAzMjUvJz5YUG9pbnRlcjwvYT5dCi0gICAgICogLgotICAgICAqIDwvbGk+Ci0gICAgICogPGxpPiBmcm9tIHRoZSB1c2Ugb2YgdGhlIG1ldGhvZHMgPGNvZGU+RWxlbWVudC5zZXRJZEF0dHJpYnV0ZSgpPC9jb2RlPiwKLSAgICAgKiA8Y29kZT5FbGVtZW50LnNldElkQXR0cmlidXRlTlMoKTwvY29kZT4sIG9yCi0gICAgICogPGNvZGU+RWxlbWVudC5zZXRJZEF0dHJpYnV0ZU5vZGUoKTwvY29kZT4sIGkuZS4gaXQgaXMgYW4KLSAgICAgKiB1c2VyLWRldGVybWluZWQgSUQgYXR0cmlidXRlOwotICAgICAqIDxwID48Yj5Ob3RlOjwvYj4gIFhQb2ludGVyIGZyYW1ld29yayAoc2VlIHNlY3Rpb24gMy4yIGluIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAzL1JFQy14cHRyLWZyYW1ld29yay0yMDAzMDMyNS8nPlhQb2ludGVyPC9hPl0KLSAgICAgKiApIGNvbnNpZGVyIHRoZSBET00gdXNlci1kZXRlcm1pbmVkIElEIGF0dHJpYnV0ZSBhcyBiZWluZyBwYXJ0IG9mIHRoZQotICAgICAqIFhQb2ludGVyIGV4dGVybmFsbHktZGV0ZXJtaW5lZCBJRCBkZWZpbml0aW9uLgotICAgICAqIDwvbGk+Ci0gICAgICogPGxpPiB1c2luZyBtZWNoYW5pc21zIHRoYXQKLSAgICAgKiBhcmUgb3V0c2lkZSB0aGUgc2NvcGUgb2YgdGhpcyBzcGVjaWZpY2F0aW9uLCBpdCBpcyB0aGVuIGFuCi0gICAgICogZXh0ZXJuYWxseS1kZXRlcm1pbmVkIElEIGF0dHJpYnV0ZS4gVGhpcyBpbmNsdWRlcyB1c2luZyBzY2hlbWEKLSAgICAgKiBsYW5ndWFnZXMgZGlmZmVyZW50IGZyb20gWE1MIHNjaGVtYSBhbmQgRFRELgotICAgICAqIDwvbGk+Ci0gICAgICogPC91bD4KLSAgICAgKiA8YnI+IElmIHZhbGlkYXRpb24gb2NjdXJyZWQgd2hpbGUgaW52b2tpbmcKLSAgICAgKiA8Y29kZT5Eb2N1bWVudC5ub3JtYWxpemVEb2N1bWVudCgpPC9jb2RlPiwgYWxsIHVzZXItZGV0ZXJtaW5lZCBJRAotICAgICAqIGF0dHJpYnV0ZXMgYXJlIHJlc2V0IGFuZCBhbGwgYXR0cmlidXRlIG5vZGVzIElEIGluZm9ybWF0aW9uIGFyZSB0aGVuCi0gICAgICogcmVldmFsdWF0ZWQgaW4gYWNjb3JkYW5jZSB0byB0aGUgc2NoZW1hIHVzZWQuIEFzIGEgY29uc2VxdWVuY2UsIGlmCi0gICAgICogdGhlIDxjb2RlPkF0dHIuc2NoZW1hVHlwZUluZm88L2NvZGU+IGF0dHJpYnV0ZSBjb250YWlucyBhbiBJRCB0eXBlLAotICAgICAqIDxjb2RlPmlzSWQ8L2NvZGU+IHdpbGwgYWx3YXlzIHJldHVybiB0cnVlLgotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzSWQoKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy93M2MvZG9tL0NEQVRBU2VjdGlvbi5qYXZhIGIvc3JjL29yZy93M2MvZG9tL0NEQVRBU2VjdGlvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1NzU1OWFlLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS9DREFUQVNlY3Rpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDgzICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBUaGlzIGZpbGUgaXMgYXZhaWxhYmxlIHVuZGVyIGFuZCBnb3Zlcm5lZCBieSB0aGUgR05VIEdlbmVyYWwgUHVibGljCi0gKiBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqIEhvd2V2ZXIsIHRoZSBmb2xsb3dpbmcgbm90aWNlIGFjY29tcGFuaWVkIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIG9mIHRoaXMKLSAqIGZpbGUgYW5kLCBwZXIgaXRzIHRlcm1zLCBzaG91bGQgbm90IGJlIHJlbW92ZWQ6Ci0gKgotICogQ29weXJpZ2h0IChjKSAyMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCi0gKgotICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEV1cm9wZWFuIFJlc2VhcmNoIENvbnNvcnRpdW0gZm9yCi0gKiBJbmZvcm1hdGljcyBhbmQgTWF0aGVtYXRpY3MsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMKLSAqIHdvcmsgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQyhyKSBTb2Z0d2FyZSBMaWNlbnNlIFsxXSBpbiB0aGUgaG9wZSB0aGF0Ci0gKiBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQKLSAqIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4KLSAqCi0gKiBbMV0gaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8yMDAyL2NvcHlyaWdodC1zb2Z0d2FyZS0yMDAyMTIzMQotICovCi0KLXBhY2thZ2Ugb3JnLnczYy5kb207Ci0KLS8qKgotICogQ0RBVEEgc2VjdGlvbnMgYXJlIHVzZWQgdG8gZXNjYXBlIGJsb2NrcyBvZiB0ZXh0IGNvbnRhaW5pbmcgY2hhcmFjdGVycyB0aGF0Ci0gKiB3b3VsZCBvdGhlcndpc2UgYmUgcmVnYXJkZWQgYXMgbWFya3VwLiBUaGUgb25seSBkZWxpbWl0ZXIgdGhhdCBpcwotICogcmVjb2duaXplZCBpbiBhIENEQVRBIHNlY3Rpb24gaXMgdGhlICJdXSZndDsiIHN0cmluZyB0aGF0IGVuZHMgdGhlIENEQVRBCi0gKiBzZWN0aW9uLiBDREFUQSBzZWN0aW9ucyBjYW5ub3QgYmUgbmVzdGVkLiBUaGVpciBwcmltYXJ5IHB1cnBvc2UgaXMgZm9yCi0gKiBpbmNsdWRpbmcgbWF0ZXJpYWwgc3VjaCBhcyBYTUwgZnJhZ21lbnRzLCB3aXRob3V0IG5lZWRpbmcgdG8gZXNjYXBlIGFsbAotICogdGhlIGRlbGltaXRlcnMuCi0gKiA8cD5UaGUgPGNvZGU+Q2hhcmFjdGVyRGF0YS5kYXRhPC9jb2RlPiBhdHRyaWJ1dGUgaG9sZHMgdGhlIHRleHQgdGhhdCBpcwotICogY29udGFpbmVkIGJ5IHRoZSBDREFUQSBzZWN0aW9uLiBOb3RlIHRoYXQgdGhpcyA8ZW0+bWF5PC9lbT4gY29udGFpbiBjaGFyYWN0ZXJzIHRoYXQgbmVlZCB0byBiZSBlc2NhcGVkIG91dHNpZGUgb2YgQ0RBVEEgc2VjdGlvbnMgYW5kCi0gKiB0aGF0LCBkZXBlbmRpbmcgb24gdGhlIGNoYXJhY3RlciBlbmNvZGluZyAoImNoYXJzZXQiKSBjaG9zZW4gZm9yCi0gKiBzZXJpYWxpemF0aW9uLCBpdCBtYXkgYmUgaW1wb3NzaWJsZSB0byB3cml0ZSBvdXQgc29tZSBjaGFyYWN0ZXJzIGFzIHBhcnQKLSAqIG9mIGEgQ0RBVEEgc2VjdGlvbi4KLSAqIDxwPlRoZSA8Y29kZT5DREFUQVNlY3Rpb248L2NvZGU+IGludGVyZmFjZSBpbmhlcml0cyBmcm9tIHRoZQotICogPGNvZGU+Q2hhcmFjdGVyRGF0YTwvY29kZT4gaW50ZXJmYWNlIHRocm91Z2ggdGhlIDxjb2RlPlRleHQ8L2NvZGU+Ci0gKiBpbnRlcmZhY2UuIEFkamFjZW50IDxjb2RlPkNEQVRBU2VjdGlvbjwvY29kZT4gbm9kZXMgYXJlIG5vdCBtZXJnZWQgYnkgdXNlCi0gKiBvZiB0aGUgPGNvZGU+bm9ybWFsaXplPC9jb2RlPiBtZXRob2Qgb2YgdGhlIDxjb2RlPk5vZGU8L2NvZGU+IGludGVyZmFjZS4KLSAqIDxwPiBObyBsZXhpY2FsIGNoZWNrIGlzIGRvbmUgb24gdGhlIGNvbnRlbnQgb2YgYSBDREFUQSBzZWN0aW9uIGFuZCBpdCBpcwotICogdGhlcmVmb3JlIHBvc3NpYmxlIHRvIGhhdmUgdGhlIGNoYXJhY3RlciBzZXF1ZW5jZSA8Y29kZT4iXV0mZ3Q7IjwvY29kZT4KLSAqIGluIHRoZSBjb250ZW50LCB3aGljaCBpcyBpbGxlZ2FsIGluIGEgQ0RBVEEgc2VjdGlvbiBwZXIgc2VjdGlvbiAyLjcgb2YgWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLXhtbC0yMDA0MDIwNCc+WE1MIDEuMDwvYT5dLiBUaGUKLSAqIHByZXNlbmNlIG9mIHRoaXMgY2hhcmFjdGVyIHNlcXVlbmNlIG11c3QgZ2VuZXJhdGUgYSBmYXRhbCBlcnJvciBkdXJpbmcKLSAqIHNlcmlhbGl6YXRpb24gb3IgdGhlIGNkYXRhIHNlY3Rpb24gbXVzdCBiZSBzcGxpdHRlZCBiZWZvcmUgdGhlCi0gKiBzZXJpYWxpemF0aW9uIChzZWUgYWxzbyB0aGUgcGFyYW1ldGVyIDxjb2RlPiJzcGxpdC1jZGF0YS1zZWN0aW9ucyI8L2NvZGU+Ci0gKiBpbiB0aGUgPGNvZGU+RE9NQ29uZmlndXJhdGlvbjwvY29kZT4gaW50ZXJmYWNlKS4KLSAqIDxwID48Yj5Ob3RlOjwvYj4gQmVjYXVzZSBubyBtYXJrdXAgaXMgcmVjb2duaXplZCB3aXRoaW4gYQotICogPGNvZGU+Q0RBVEFTZWN0aW9uPC9jb2RlPiwgY2hhcmFjdGVyIG51bWVyaWMgcmVmZXJlbmNlcyBjYW5ub3QgYmUgdXNlZCBhcwotICogYW4gZXNjYXBlIG1lY2hhbmlzbSB3aGVuIHNlcmlhbGl6aW5nLiBUaGVyZWZvcmUsIGFjdGlvbiBuZWVkcyB0byBiZSB0YWtlbgotICogd2hlbiBzZXJpYWxpemluZyBhIDxjb2RlPkNEQVRBU2VjdGlvbjwvY29kZT4gd2l0aCBhIGNoYXJhY3RlciBlbmNvZGluZwotICogd2hlcmUgc29tZSBvZiB0aGUgY29udGFpbmVkIGNoYXJhY3RlcnMgY2Fubm90IGJlIHJlcHJlc2VudGVkLiBGYWlsdXJlIHRvCi0gKiBkbyBzbyB3b3VsZCBub3QgcHJvZHVjZSB3ZWxsLWZvcm1lZCBYTUwuCi0gKiA8cCA+PGI+Tm90ZTo8L2I+IE9uZSBwb3RlbnRpYWwgc29sdXRpb24gaW4gdGhlIHNlcmlhbGl6YXRpb24gcHJvY2VzcyBpcyB0bwotICogZW5kIHRoZSBDREFUQSBzZWN0aW9uIGJlZm9yZSB0aGUgY2hhcmFjdGVyLCBvdXRwdXQgdGhlIGNoYXJhY3RlciB1c2luZyBhCi0gKiBjaGFyYWN0ZXIgcmVmZXJlbmNlIG9yIGVudGl0eSByZWZlcmVuY2UsIGFuZCBvcGVuIGEgbmV3IENEQVRBIHNlY3Rpb24gZm9yCi0gKiBhbnkgZnVydGhlciBjaGFyYWN0ZXJzIGluIHRoZSB0ZXh0IG5vZGUuIE5vdGUsIGhvd2V2ZXIsIHRoYXQgc29tZSBjb2RlCi0gKiBjb252ZXJzaW9uIGxpYnJhcmllcyBhdCB0aGUgdGltZSBvZiB3cml0aW5nIGRvIG5vdCByZXR1cm4gYW4gZXJyb3Igb3IKLSAqIGV4Y2VwdGlvbiB3aGVuIGEgY2hhcmFjdGVyIGlzIG1pc3NpbmcgZnJvbSB0aGUgZW5jb2RpbmcsIG1ha2luZyB0aGUgdGFzawotICogb2YgZW5zdXJpbmcgdGhhdCBkYXRhIGlzIG5vdCBjb3JydXB0ZWQgb24gc2VyaWFsaXphdGlvbiBtb3JlIGRpZmZpY3VsdC4KLSAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy1ET00tTGV2ZWwtMy1Db3JlLTIwMDQwNDA3Jz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMyBDb3JlIFNwZWNpZmljYXRpb248L2E+LgotICovCi1wdWJsaWMgaW50ZXJmYWNlIENEQVRBU2VjdGlvbiBleHRlbmRzIFRleHQgewotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy93M2MvZG9tL0NoYXJhY3RlckRhdGEuamF2YSBiL3NyYy9vcmcvdzNjL2RvbS9DaGFyYWN0ZXJEYXRhLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDQ2NjE4YzguLjAwMDAwMDAKLS0tIGEvc3JjL29yZy93M2MvZG9tL0NoYXJhY3RlckRhdGEuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE4MiArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogVGhpcyBmaWxlIGlzIGF2YWlsYWJsZSB1bmRlciBhbmQgZ292ZXJuZWQgYnkgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwotICogTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKiBIb3dldmVyLCB0aGUgZm9sbG93aW5nIG5vdGljZSBhY2NvbXBhbmllZCB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGlzCi0gKiBmaWxlIGFuZCwgcGVyIGl0cyB0ZXJtcywgc2hvdWxkIG5vdCBiZSByZW1vdmVkOgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAotICoKLSAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBFdXJvcGVhbiBSZXNlYXJjaCBDb25zb3J0aXVtIGZvcgotICogSW5mb3JtYXRpY3MgYW5kIE1hdGhlbWF0aWNzLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwgUmlnaHRzIFJlc2VydmVkLiBUaGlzCi0gKiB3b3JrIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MocikgU29mdHdhcmUgTGljZW5zZSBbMV0gaW4gdGhlIGhvcGUgdGhhdAotICogaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkCi0gKiB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuCi0gKgotICogWzFdIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvMjAwMi9jb3B5cmlnaHQtc29mdHdhcmUtMjAwMjEyMzEKLSAqLwotCi1wYWNrYWdlIG9yZy53M2MuZG9tOwotCi0vKioKLSAqIFRoZSA8Y29kZT5DaGFyYWN0ZXJEYXRhPC9jb2RlPiBpbnRlcmZhY2UgZXh0ZW5kcyBOb2RlIHdpdGggYSBzZXQgb2YKLSAqIGF0dHJpYnV0ZXMgYW5kIG1ldGhvZHMgZm9yIGFjY2Vzc2luZyBjaGFyYWN0ZXIgZGF0YSBpbiB0aGUgRE9NLiBGb3IKLSAqIGNsYXJpdHkgdGhpcyBzZXQgaXMgZGVmaW5lZCBoZXJlIHJhdGhlciB0aGFuIG9uIGVhY2ggb2JqZWN0IHRoYXQgdXNlcwotICogdGhlc2UgYXR0cmlidXRlcyBhbmQgbWV0aG9kcy4gTm8gRE9NIG9iamVjdHMgY29ycmVzcG9uZCBkaXJlY3RseSB0bwotICogPGNvZGU+Q2hhcmFjdGVyRGF0YTwvY29kZT4sIHRob3VnaCA8Y29kZT5UZXh0PC9jb2RlPiBhbmQgb3RoZXJzIGRvCi0gKiBpbmhlcml0IHRoZSBpbnRlcmZhY2UgZnJvbSBpdC4gQWxsIDxjb2RlPm9mZnNldHM8L2NvZGU+IGluIHRoaXMgaW50ZXJmYWNlCi0gKiBzdGFydCBmcm9tIDxjb2RlPjA8L2NvZGU+LgotICogPHA+QXMgZXhwbGFpbmVkIGluIHRoZSA8Y29kZT5ET01TdHJpbmc8L2NvZGU+IGludGVyZmFjZSwgdGV4dCBzdHJpbmdzIGluCi0gKiB0aGUgRE9NIGFyZSByZXByZXNlbnRlZCBpbiBVVEYtMTYsIGkuZS4gYXMgYSBzZXF1ZW5jZSBvZiAxNi1iaXQgdW5pdHMuIEluCi0gKiB0aGUgZm9sbG93aW5nLCB0aGUgdGVybSAxNi1iaXQgdW5pdHMgaXMgdXNlZCB3aGVuZXZlciBuZWNlc3NhcnkgdG8KLSAqIGluZGljYXRlIHRoYXQgaW5kZXhpbmcgb24gQ2hhcmFjdGVyRGF0YSBpcyBkb25lIGluIDE2LWJpdCB1bml0cy4KLSAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy1ET00tTGV2ZWwtMy1Db3JlLTIwMDQwNDA3Jz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMyBDb3JlIFNwZWNpZmljYXRpb248L2E+LgotICovCi1wdWJsaWMgaW50ZXJmYWNlIENoYXJhY3RlckRhdGEgZXh0ZW5kcyBOb2RlIHsKLSAgICAvKioKLSAgICAgKiBUaGUgY2hhcmFjdGVyIGRhdGEgb2YgdGhlIG5vZGUgdGhhdCBpbXBsZW1lbnRzIHRoaXMgaW50ZXJmYWNlLiBUaGUgRE9NCi0gICAgICogaW1wbGVtZW50YXRpb24gbWF5IG5vdCBwdXQgYXJiaXRyYXJ5IGxpbWl0cyBvbiB0aGUgYW1vdW50IG9mIGRhdGEKLSAgICAgKiB0aGF0IG1heSBiZSBzdG9yZWQgaW4gYSA8Y29kZT5DaGFyYWN0ZXJEYXRhPC9jb2RlPiBub2RlLiBIb3dldmVyLAotICAgICAqIGltcGxlbWVudGF0aW9uIGxpbWl0cyBtYXkgbWVhbiB0aGF0IHRoZSBlbnRpcmV0eSBvZiBhIG5vZGUncyBkYXRhIG1heQotICAgICAqIG5vdCBmaXQgaW50byBhIHNpbmdsZSA8Y29kZT5ET01TdHJpbmc8L2NvZGU+LiBJbiBzdWNoIGNhc2VzLCB0aGUgdXNlcgotICAgICAqIG1heSBjYWxsIDxjb2RlPnN1YnN0cmluZ0RhdGE8L2NvZGU+IHRvIHJldHJpZXZlIHRoZSBkYXRhIGluCi0gICAgICogYXBwcm9wcmlhdGVseSBzaXplZCBwaWVjZXMuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIERPTVNUUklOR19TSVpFX0VSUjogUmFpc2VkIHdoZW4gaXQgd291bGQgcmV0dXJuIG1vcmUgY2hhcmFjdGVycyB0aGFuCi0gICAgICogICBmaXQgaW4gYSA8Y29kZT5ET01TdHJpbmc8L2NvZGU+IHZhcmlhYmxlIG9uIHRoZSBpbXBsZW1lbnRhdGlvbgotICAgICAqICAgcGxhdGZvcm0uCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXREYXRhKCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotICAgIC8qKgotICAgICAqIFRoZSBjaGFyYWN0ZXIgZGF0YSBvZiB0aGUgbm9kZSB0aGF0IGltcGxlbWVudHMgdGhpcyBpbnRlcmZhY2UuIFRoZSBET00KLSAgICAgKiBpbXBsZW1lbnRhdGlvbiBtYXkgbm90IHB1dCBhcmJpdHJhcnkgbGltaXRzIG9uIHRoZSBhbW91bnQgb2YgZGF0YQotICAgICAqIHRoYXQgbWF5IGJlIHN0b3JlZCBpbiBhIDxjb2RlPkNoYXJhY3RlckRhdGE8L2NvZGU+IG5vZGUuIEhvd2V2ZXIsCi0gICAgICogaW1wbGVtZW50YXRpb24gbGltaXRzIG1heSBtZWFuIHRoYXQgdGhlIGVudGlyZXR5IG9mIGEgbm9kZSdzIGRhdGEgbWF5Ci0gICAgICogbm90IGZpdCBpbnRvIGEgc2luZ2xlIDxjb2RlPkRPTVN0cmluZzwvY29kZT4uIEluIHN1Y2ggY2FzZXMsIHRoZSB1c2VyCi0gICAgICogbWF5IGNhbGwgPGNvZGU+c3Vic3RyaW5nRGF0YTwvY29kZT4gdG8gcmV0cmlldmUgdGhlIGRhdGEgaW4KLSAgICAgKiBhcHByb3ByaWF0ZWx5IHNpemVkIHBpZWNlcy4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgd2hlbiB0aGUgbm9kZSBpcyByZWFkb25seS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXREYXRhKFN0cmluZyBkYXRhKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgbnVtYmVyIG9mIDE2LWJpdCB1bml0cyB0aGF0IGFyZSBhdmFpbGFibGUgdGhyb3VnaCA8Y29kZT5kYXRhPC9jb2RlPgotICAgICAqIGFuZCB0aGUgPGNvZGU+c3Vic3RyaW5nRGF0YTwvY29kZT4gbWV0aG9kIGJlbG93LiBUaGlzIG1heSBoYXZlIHRoZQotICAgICAqIHZhbHVlIHplcm8sIGkuZS4sIDxjb2RlPkNoYXJhY3RlckRhdGE8L2NvZGU+IG5vZGVzIG1heSBiZSBlbXB0eS4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldExlbmd0aCgpOwotCi0gICAgLyoqCi0gICAgICogRXh0cmFjdHMgYSByYW5nZSBvZiBkYXRhIGZyb20gdGhlIG5vZGUuCi0gICAgICogQHBhcmFtIG9mZnNldCBTdGFydCBvZmZzZXQgb2Ygc3Vic3RyaW5nIHRvIGV4dHJhY3QuCi0gICAgICogQHBhcmFtIGNvdW50IFRoZSBudW1iZXIgb2YgMTYtYml0IHVuaXRzIHRvIGV4dHJhY3QuCi0gICAgICogQHJldHVybiBUaGUgc3BlY2lmaWVkIHN1YnN0cmluZy4gSWYgdGhlIHN1bSBvZiA8Y29kZT5vZmZzZXQ8L2NvZGU+IGFuZAotICAgICAqICAgPGNvZGU+Y291bnQ8L2NvZGU+IGV4Y2VlZHMgdGhlIDxjb2RlPmxlbmd0aDwvY29kZT4sIHRoZW4gYWxsIDE2LWJpdAotICAgICAqICAgdW5pdHMgdG8gdGhlIGVuZCBvZiB0aGUgZGF0YSBhcmUgcmV0dXJuZWQuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIElOREVYX1NJWkVfRVJSOiBSYWlzZWQgaWYgdGhlIHNwZWNpZmllZCA8Y29kZT5vZmZzZXQ8L2NvZGU+IGlzCi0gICAgICogICBuZWdhdGl2ZSBvciBncmVhdGVyIHRoYW4gdGhlIG51bWJlciBvZiAxNi1iaXQgdW5pdHMgaW4KLSAgICAgKiAgIDxjb2RlPmRhdGE8L2NvZGU+LCBvciBpZiB0aGUgc3BlY2lmaWVkIDxjb2RlPmNvdW50PC9jb2RlPiBpcwotICAgICAqICAgbmVnYXRpdmUuCi0gICAgICogICA8YnI+RE9NU1RSSU5HX1NJWkVfRVJSOiBSYWlzZWQgaWYgdGhlIHNwZWNpZmllZCByYW5nZSBvZiB0ZXh0IGRvZXMKLSAgICAgKiAgIG5vdCBmaXQgaW50byBhIDxjb2RlPkRPTVN0cmluZzwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBzdWJzdHJpbmdEYXRhKGludCBvZmZzZXQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBjb3VudCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIEFwcGVuZCB0aGUgc3RyaW5nIHRvIHRoZSBlbmQgb2YgdGhlIGNoYXJhY3RlciBkYXRhIG9mIHRoZSBub2RlLiBVcG9uCi0gICAgICogc3VjY2VzcywgPGNvZGU+ZGF0YTwvY29kZT4gcHJvdmlkZXMgYWNjZXNzIHRvIHRoZSBjb25jYXRlbmF0aW9uIG9mCi0gICAgICogPGNvZGU+ZGF0YTwvY29kZT4gYW5kIHRoZSA8Y29kZT5ET01TdHJpbmc8L2NvZGU+IHNwZWNpZmllZC4KLSAgICAgKiBAcGFyYW0gYXJnIFRoZSA8Y29kZT5ET01TdHJpbmc8L2NvZGU+IHRvIGFwcGVuZC4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBub2RlIGlzIHJlYWRvbmx5LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGFwcGVuZERhdGEoU3RyaW5nIGFyZykKLSAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBJbnNlcnQgYSBzdHJpbmcgYXQgdGhlIHNwZWNpZmllZCAxNi1iaXQgdW5pdCBvZmZzZXQuCi0gICAgICogQHBhcmFtIG9mZnNldCBUaGUgY2hhcmFjdGVyIG9mZnNldCBhdCB3aGljaCB0byBpbnNlcnQuCi0gICAgICogQHBhcmFtIGFyZyBUaGUgPGNvZGU+RE9NU3RyaW5nPC9jb2RlPiB0byBpbnNlcnQuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIElOREVYX1NJWkVfRVJSOiBSYWlzZWQgaWYgdGhlIHNwZWNpZmllZCA8Y29kZT5vZmZzZXQ8L2NvZGU+IGlzCi0gICAgICogICBuZWdhdGl2ZSBvciBncmVhdGVyIHRoYW4gdGhlIG51bWJlciBvZiAxNi1iaXQgdW5pdHMgaW4KLSAgICAgKiAgIDxjb2RlPmRhdGE8L2NvZGU+LgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgbm9kZSBpcyByZWFkb25seS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBpbnNlcnREYXRhKGludCBvZmZzZXQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgYXJnKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIFJlbW92ZSBhIHJhbmdlIG9mIDE2LWJpdCB1bml0cyBmcm9tIHRoZSBub2RlLiBVcG9uIHN1Y2Nlc3MsCi0gICAgICogPGNvZGU+ZGF0YTwvY29kZT4gYW5kIDxjb2RlPmxlbmd0aDwvY29kZT4gcmVmbGVjdCB0aGUgY2hhbmdlLgotICAgICAqIEBwYXJhbSBvZmZzZXQgVGhlIG9mZnNldCBmcm9tIHdoaWNoIHRvIHN0YXJ0IHJlbW92aW5nLgotICAgICAqIEBwYXJhbSBjb3VudCBUaGUgbnVtYmVyIG9mIDE2LWJpdCB1bml0cyB0byBkZWxldGUuIElmIHRoZSBzdW0gb2YKLSAgICAgKiAgIDxjb2RlPm9mZnNldDwvY29kZT4gYW5kIDxjb2RlPmNvdW50PC9jb2RlPiBleGNlZWRzCi0gICAgICogICA8Y29kZT5sZW5ndGg8L2NvZGU+IHRoZW4gYWxsIDE2LWJpdCB1bml0cyBmcm9tIDxjb2RlPm9mZnNldDwvY29kZT4KLSAgICAgKiAgIHRvIHRoZSBlbmQgb2YgdGhlIGRhdGEgYXJlIGRlbGV0ZWQuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIElOREVYX1NJWkVfRVJSOiBSYWlzZWQgaWYgdGhlIHNwZWNpZmllZCA8Y29kZT5vZmZzZXQ8L2NvZGU+IGlzCi0gICAgICogICBuZWdhdGl2ZSBvciBncmVhdGVyIHRoYW4gdGhlIG51bWJlciBvZiAxNi1iaXQgdW5pdHMgaW4KLSAgICAgKiAgIDxjb2RlPmRhdGE8L2NvZGU+LCBvciBpZiB0aGUgc3BlY2lmaWVkIDxjb2RlPmNvdW50PC9jb2RlPiBpcwotICAgICAqICAgbmVnYXRpdmUuCi0gICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBub2RlIGlzIHJlYWRvbmx5LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGRlbGV0ZURhdGEoaW50IG9mZnNldCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBjb3VudCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBSZXBsYWNlIHRoZSBjaGFyYWN0ZXJzIHN0YXJ0aW5nIGF0IHRoZSBzcGVjaWZpZWQgMTYtYml0IHVuaXQgb2Zmc2V0Ci0gICAgICogd2l0aCB0aGUgc3BlY2lmaWVkIHN0cmluZy4KLSAgICAgKiBAcGFyYW0gb2Zmc2V0IFRoZSBvZmZzZXQgZnJvbSB3aGljaCB0byBzdGFydCByZXBsYWNpbmcuCi0gICAgICogQHBhcmFtIGNvdW50IFRoZSBudW1iZXIgb2YgMTYtYml0IHVuaXRzIHRvIHJlcGxhY2UuIElmIHRoZSBzdW0gb2YKLSAgICAgKiAgIDxjb2RlPm9mZnNldDwvY29kZT4gYW5kIDxjb2RlPmNvdW50PC9jb2RlPiBleGNlZWRzCi0gICAgICogICA8Y29kZT5sZW5ndGg8L2NvZGU+LCB0aGVuIGFsbCAxNi1iaXQgdW5pdHMgdG8gdGhlIGVuZCBvZiB0aGUgZGF0YQotICAgICAqICAgYXJlIHJlcGxhY2VkOyAoaS5lLiwgdGhlIGVmZmVjdCBpcyB0aGUgc2FtZSBhcyBhIDxjb2RlPnJlbW92ZTwvY29kZT4KLSAgICAgKiAgICBtZXRob2QgY2FsbCB3aXRoIHRoZSBzYW1lIHJhbmdlLCBmb2xsb3dlZCBieSBhbiA8Y29kZT5hcHBlbmQ8L2NvZGU+Ci0gICAgICogICAgbWV0aG9kIGludm9jYXRpb24pLgotICAgICAqIEBwYXJhbSBhcmcgVGhlIDxjb2RlPkRPTVN0cmluZzwvY29kZT4gd2l0aCB3aGljaCB0aGUgcmFuZ2UgbXVzdCBiZQotICAgICAqICAgcmVwbGFjZWQuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIElOREVYX1NJWkVfRVJSOiBSYWlzZWQgaWYgdGhlIHNwZWNpZmllZCA8Y29kZT5vZmZzZXQ8L2NvZGU+IGlzCi0gICAgICogICBuZWdhdGl2ZSBvciBncmVhdGVyIHRoYW4gdGhlIG51bWJlciBvZiAxNi1iaXQgdW5pdHMgaW4KLSAgICAgKiAgIDxjb2RlPmRhdGE8L2NvZGU+LCBvciBpZiB0aGUgc3BlY2lmaWVkIDxjb2RlPmNvdW50PC9jb2RlPiBpcwotICAgICAqICAgbmVnYXRpdmUuCi0gICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBub2RlIGlzIHJlYWRvbmx5LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHJlcGxhY2VEYXRhKGludCBvZmZzZXQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGNvdW50LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBhcmcpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy93M2MvZG9tL0NvbW1lbnQuamF2YSBiL3NyYy9vcmcvdzNjL2RvbS9Db21tZW50LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGE4ZDA3YTUuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy93M2MvZG9tL0NvbW1lbnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDU5ICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBUaGlzIGZpbGUgaXMgYXZhaWxhYmxlIHVuZGVyIGFuZCBnb3Zlcm5lZCBieSB0aGUgR05VIEdlbmVyYWwgUHVibGljCi0gKiBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqIEhvd2V2ZXIsIHRoZSBmb2xsb3dpbmcgbm90aWNlIGFjY29tcGFuaWVkIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIG9mIHRoaXMKLSAqIGZpbGUgYW5kLCBwZXIgaXRzIHRlcm1zLCBzaG91bGQgbm90IGJlIHJlbW92ZWQ6Ci0gKgotICogQ29weXJpZ2h0IChjKSAyMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCi0gKgotICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEV1cm9wZWFuIFJlc2VhcmNoIENvbnNvcnRpdW0gZm9yCi0gKiBJbmZvcm1hdGljcyBhbmQgTWF0aGVtYXRpY3MsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMKLSAqIHdvcmsgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQyhyKSBTb2Z0d2FyZSBMaWNlbnNlIFsxXSBpbiB0aGUgaG9wZSB0aGF0Ci0gKiBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQKLSAqIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4KLSAqCi0gKiBbMV0gaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8yMDAyL2NvcHlyaWdodC1zb2Z0d2FyZS0yMDAyMTIzMQotICovCi0KLXBhY2thZ2Ugb3JnLnczYy5kb207Ci0KLS8qKgotICogVGhpcyBpbnRlcmZhY2UgaW5oZXJpdHMgZnJvbSA8Y29kZT5DaGFyYWN0ZXJEYXRhPC9jb2RlPiBhbmQgcmVwcmVzZW50cyB0aGUKLSAqIGNvbnRlbnQgb2YgYSBjb21tZW50LCBpLmUuLCBhbGwgdGhlIGNoYXJhY3RlcnMgYmV0d2VlbiB0aGUgc3RhcnRpbmcgJwotICogPGNvZGU+Jmx0OyEtLTwvY29kZT4nIGFuZCBlbmRpbmcgJzxjb2RlPi0tJmd0OzwvY29kZT4nLiBOb3RlIHRoYXQgdGhpcyBpcwotICogdGhlIGRlZmluaXRpb24gb2YgYSBjb21tZW50IGluIFhNTCwgYW5kLCBpbiBwcmFjdGljZSwgSFRNTCwgYWx0aG91Z2ggc29tZQotICogSFRNTCB0b29scyBtYXkgaW1wbGVtZW50IHRoZSBmdWxsIFNHTUwgY29tbWVudCBzdHJ1Y3R1cmUuCi0gKiA8cD4gTm8gbGV4aWNhbCBjaGVjayBpcyBkb25lIG9uIHRoZSBjb250ZW50IG9mIGEgY29tbWVudCBhbmQgaXQgaXMKLSAqIHRoZXJlZm9yZSBwb3NzaWJsZSB0byBoYXZlIHRoZSBjaGFyYWN0ZXIgc2VxdWVuY2UgPGNvZGU+Ii0tIjwvY29kZT4KLSAqIChkb3VibGUtaHlwaGVuKSBpbiB0aGUgY29udGVudCwgd2hpY2ggaXMgaWxsZWdhbCBpbiBhIGNvbW1lbnQgcGVyIHNlY3Rpb24KLSAqIDIuNSBvZiBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMteG1sLTIwMDQwMjA0Jz5YTUwgMS4wPC9hPl0uIFRoZQotICogcHJlc2VuY2Ugb2YgdGhpcyBjaGFyYWN0ZXIgc2VxdWVuY2UgbXVzdCBnZW5lcmF0ZSBhIGZhdGFsIGVycm9yIGR1cmluZwotICogc2VyaWFsaXphdGlvbi4KLSAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy1ET00tTGV2ZWwtMy1Db3JlLTIwMDQwNDA3Jz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMyBDb3JlIFNwZWNpZmljYXRpb248L2E+LgotICovCi1wdWJsaWMgaW50ZXJmYWNlIENvbW1lbnQgZXh0ZW5kcyBDaGFyYWN0ZXJEYXRhIHsKLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvdzNjL2RvbS9ET01Db25maWd1cmF0aW9uLmphdmEgYi9zcmMvb3JnL3czYy9kb20vRE9NQ29uZmlndXJhdGlvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0YTNlNjZiLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS9ET01Db25maWd1cmF0aW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0NDIgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIFRoaXMgZmlsZSBpcyBhdmFpbGFibGUgdW5kZXIgYW5kIGdvdmVybmVkIGJ5IHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKLSAqIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICogSG93ZXZlciwgdGhlIGZvbGxvd2luZyBub3RpY2UgYWNjb21wYW5pZWQgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcwotICogZmlsZSBhbmQsIHBlciBpdHMgdGVybXMsIHNob3VsZCBub3QgYmUgcmVtb3ZlZDoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKLSAqCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgRXVyb3BlYW4gUmVzZWFyY2ggQ29uc29ydGl1bSBmb3IKLSAqIEluZm9ybWF0aWNzIGFuZCBNYXRoZW1hdGljcywgS2VpbyBVbml2ZXJzaXR5KS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcwotICogd29yayBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDKHIpIFNvZnR3YXJlIExpY2Vuc2UgWzFdIGluIHRoZSBob3BlIHRoYXQKLSAqIGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZAotICogd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLgotICoKLSAqIFsxXSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLzIwMDIvY29weXJpZ2h0LXNvZnR3YXJlLTIwMDIxMjMxCi0gKi8KLQotcGFja2FnZSBvcmcudzNjLmRvbTsKLQotLyoqCi0gKiAgVGhlIDxjb2RlPkRPTUNvbmZpZ3VyYXRpb248L2NvZGU+IGludGVyZmFjZSByZXByZXNlbnRzIHRoZSBjb25maWd1cmF0aW9uCi0gKiBvZiBhIGRvY3VtZW50IGFuZCBtYWludGFpbnMgYSB0YWJsZSBvZiByZWNvZ25pemVkIHBhcmFtZXRlcnMuIFVzaW5nIHRoZQotICogY29uZmlndXJhdGlvbiwgaXQgaXMgcG9zc2libGUgdG8gY2hhbmdlCi0gKiA8Y29kZT5Eb2N1bWVudC5ub3JtYWxpemVEb2N1bWVudCgpPC9jb2RlPiBiZWhhdmlvciwgc3VjaCBhcyByZXBsYWNpbmcgdGhlCi0gKiA8Y29kZT5DREFUQVNlY3Rpb248L2NvZGU+IG5vZGVzIHdpdGggPGNvZGU+VGV4dDwvY29kZT4gbm9kZXMgb3IKLSAqIHNwZWNpZnlpbmcgdGhlIHR5cGUgb2YgdGhlIHNjaGVtYSB0aGF0IG11c3QgYmUgdXNlZCB3aGVuIHRoZSB2YWxpZGF0aW9uCi0gKiBvZiB0aGUgPGNvZGU+RG9jdW1lbnQ8L2NvZGU+IGlzIHJlcXVlc3RlZC4gPGNvZGU+RE9NQ29uZmlndXJhdGlvbjwvY29kZT4KLSAqIG9iamVjdHMgYXJlIGFsc28gdXNlZCBpbiBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMtRE9NLUxldmVsLTMtTFMtMjAwNDA0MDcnPkRPTSBMZXZlbCAzIExvYWQgYW5kIFNhdmU8L2E+XQotICogIGluIHRoZSA8Y29kZT5ET01QYXJzZXI8L2NvZGU+IGFuZCA8Y29kZT5ET01TZXJpYWxpemVyPC9jb2RlPiBpbnRlcmZhY2VzLgotICogPHA+IFRoZSBwYXJhbWV0ZXIgbmFtZXMgdXNlZCBieSB0aGUgPGNvZGU+RE9NQ29uZmlndXJhdGlvbjwvY29kZT4gb2JqZWN0Ci0gKiBhcmUgZGVmaW5lZCB0aHJvdWdob3V0IHRoZSBET00gTGV2ZWwgMyBzcGVjaWZpY2F0aW9ucy4gTmFtZXMgYXJlCi0gKiBjYXNlLWluc2Vuc2l0aXZlLiBUbyBhdm9pZCBwb3NzaWJsZSBjb25mbGljdHMsIGFzIGEgY29udmVudGlvbiwgbmFtZXMKLSAqIHJlZmVycmluZyB0byBwYXJhbWV0ZXJzIGRlZmluZWQgb3V0c2lkZSB0aGUgRE9NIHNwZWNpZmljYXRpb24gc2hvdWxkIGJlCi0gKiBtYWRlIHVuaXF1ZS4gQmVjYXVzZSBwYXJhbWV0ZXJzIGFyZSBleHBvc2VkIGFzIHByb3BlcnRpZXMgaW4gbmFtZXMKLSAqIGFyZSByZWNvbW1lbmRlZCB0byBmb2xsb3cgdGhlIHNlY3Rpb24gNS4xNiBJZGVudGlmaWVycyBvZiBbVW5pY29kZV0gd2l0aCB0aGUgYWRkaXRpb24gb2YgdGhlIGNoYXJhY3RlciAnLScgKEhZUEhFTi1NSU5VUykgYnV0IGl0IGlzIG5vdAotICogZW5mb3JjZWQgYnkgdGhlIERPTSBpbXBsZW1lbnRhdGlvbi4gRE9NIExldmVsIDMgQ29yZSBJbXBsZW1lbnRhdGlvbnMgYXJlCi0gKiByZXF1aXJlZCB0byByZWNvZ25pemUgYWxsIHBhcmFtZXRlcnMgZGVmaW5lZCBpbiB0aGlzIHNwZWNpZmljYXRpb24uIFNvbWUKLSAqIHBhcmFtZXRlciB2YWx1ZXMgbWF5IGFsc28gYmUgcmVxdWlyZWQgdG8gYmUgc3VwcG9ydGVkIGJ5IHRoZQotICogaW1wbGVtZW50YXRpb24uIFJlZmVyIHRvIHRoZSBkZWZpbml0aW9uIG9mIHRoZSBwYXJhbWV0ZXIgdG8ga25vdyBpZiBhCi0gKiB2YWx1ZSBtdXN0IGJlIHN1cHBvcnRlZCBvciBub3QuCi0gKiA8cCA+PGI+Tm90ZTo8L2I+ICBQYXJhbWV0ZXJzIGFyZSBzaW1pbGFyIHRvIGZlYXR1cmVzIGFuZCBwcm9wZXJ0aWVzIHVzZWQgaW4KLSAqIFNBWDIgWzxhIGhyZWY9J2h0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmcvJz5TQVg8L2E+XS4KLSAqIDxwPiBUaGUgZm9sbG93aW5nIGxpc3Qgb2YgcGFyYW1ldGVycyBkZWZpbmVkIGluIHRoZSBET006Ci0gKiA8ZGw+Ci0gKiA8ZHQ+Ci0gKiA8Y29kZT4iY2Fub25pY2FsLWZvcm0iPC9jb2RlPjwvZHQ+Ci0gKiA8ZGQ+Ci0gKiA8ZGw+Ci0gKiA8ZHQ+PGNvZGU+dHJ1ZTwvY29kZT48L2R0PgotICogPGRkPls8ZW0+b3B0aW9uYWw8L2VtPl0gQ2Fub25pY2FsaXplIHRoZSBkb2N1bWVudCBhY2NvcmRpbmcgdG8gdGhlIHJ1bGVzIHNwZWNpZmllZCBpbiBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMS9SRUMteG1sLWMxNG4tMjAwMTAzMTUnPkNhbm9uaWNhbCBYTUw8L2E+XSwKLSAqIHN1Y2ggYXMgcmVtb3ZpbmcgdGhlIDxjb2RlPkRvY3VtZW50VHlwZTwvY29kZT4gbm9kZSAoaWYgYW55KSBmcm9tIHRoZQotICogdHJlZSwgb3IgcmVtb3Zpbmcgc3VwZXJmbHVvdXMgbmFtZXNwYWNlIGRlY2xhcmF0aW9ucyBmcm9tIGVhY2ggZWxlbWVudC4KLSAqIE5vdGUgdGhhdCB0aGlzIGlzIGxpbWl0ZWQgdG8gd2hhdCBjYW4gYmUgcmVwcmVzZW50ZWQgaW4gdGhlIERPTTsgaW4KLSAqIHBhcnRpY3VsYXIsIHRoZXJlIGlzIG5vIHdheSB0byBzcGVjaWZ5IHRoZSBvcmRlciBvZiB0aGUgYXR0cmlidXRlcyBpbiB0aGUKLSAqIERPTS4gSW4gYWRkaXRpb24sICBTZXR0aW5nIHRoaXMgcGFyYW1ldGVyIHRvIDxjb2RlPnRydWU8L2NvZGU+IHdpbGwgYWxzbwotICogc2V0IHRoZSBzdGF0ZSBvZiB0aGUgcGFyYW1ldGVycyBsaXN0ZWQgYmVsb3cuIExhdGVyIGNoYW5nZXMgdG8gdGhlIHN0YXRlCi0gKiBvZiBvbmUgb2YgdGhvc2UgcGFyYW1ldGVycyB3aWxsIHJldmVydCAiY2Fub25pY2FsLWZvcm0iIGJhY2sgdG8KLSAqIDxjb2RlPmZhbHNlPC9jb2RlPi4gUGFyYW1ldGVycyBzZXQgdG8gPGNvZGU+ZmFsc2U8L2NvZGU+OiAiZW50aXRpZXMiLCAiCi0gKiBub3JtYWxpemUtY2hhcmFjdGVycyIsICJjZGF0YS1zZWN0aW9ucyIuIFBhcmFtZXRlcnMgc2V0IHRvCi0gKiA8Y29kZT50cnVlPC9jb2RlPjogIm5hbWVzcGFjZXMiLCAibmFtZXNwYWNlLWRlY2xhcmF0aW9ucyIsICJ3ZWxsLWZvcm1lZCIsCi0gKiAiZWxlbWVudC1jb250ZW50LXdoaXRlc3BhY2UiLiBPdGhlciBwYXJhbWV0ZXJzIGFyZSBub3QgY2hhbmdlZCB1bmxlc3MKLSAqIGV4cGxpY2l0bHkgc3BlY2lmaWVkIGluIHRoZSBkZXNjcmlwdGlvbiBvZiB0aGUgcGFyYW1ldGVycy48L2RkPgotICogPGR0PgotICogPGNvZGU+ZmFsc2U8L2NvZGU+PC9kdD4KLSAqIDxkZD5bPGVtPnJlcXVpcmVkPC9lbT5dICg8ZW0+ZGVmYXVsdDwvZW0+KURvIG5vdCBjYW5vbmljYWxpemUgdGhlIGRvY3VtZW50LjwvZGQ+Ci0gKiA8L2RsPjwvZGQ+Ci0gKiA8ZHQ+PGNvZGU+ImNkYXRhLXNlY3Rpb25zIjwvY29kZT48L2R0PgotICogPGRkPgotICogPGRsPgotICogPGR0PgotICogPGNvZGU+dHJ1ZTwvY29kZT48L2R0PgotICogPGRkPls8ZW0+cmVxdWlyZWQ8L2VtPl0gKDxlbT5kZWZhdWx0PC9lbT4pS2VlcCA8Y29kZT5DREFUQVNlY3Rpb248L2NvZGU+IG5vZGVzIGluIHRoZSBkb2N1bWVudC48L2RkPgotICogPGR0Pjxjb2RlPmZhbHNlPC9jb2RlPjwvZHQ+Ci0gKiA8ZGQ+WzxlbT5yZXF1aXJlZDwvZW0+XVRyYW5zZm9ybSA8Y29kZT5DREFUQVNlY3Rpb248L2NvZGU+IG5vZGVzIGluIHRoZSBkb2N1bWVudCBpbnRvCi0gKiA8Y29kZT5UZXh0PC9jb2RlPiBub2Rlcy4gVGhlIG5ldyA8Y29kZT5UZXh0PC9jb2RlPiBub2RlIGlzIHRoZW4gY29tYmluZWQKLSAqIHdpdGggYW55IGFkamFjZW50IDxjb2RlPlRleHQ8L2NvZGU+IG5vZGUuPC9kZD4KLSAqIDwvZGw+PC9kZD4KLSAqIDxkdD4KLSAqIDxjb2RlPiJjaGVjay1jaGFyYWN0ZXItbm9ybWFsaXphdGlvbiI8L2NvZGU+PC9kdD4KLSAqIDxkZD4KLSAqIDxkbD4KLSAqIDxkdD48Y29kZT50cnVlPC9jb2RlPjwvZHQ+Ci0gKiA8ZGQ+WzxlbT5vcHRpb25hbDwvZW0+XSBDaGVjayBpZiB0aGUgY2hhcmFjdGVycyBpbiB0aGUgZG9jdW1lbnQgYXJlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLXhtbDExLTIwMDQwMjA0LyNkdC1mdWxsbm9ybSc+ZnVsbHkKLSAqIG5vcm1hbGl6ZWQ8L2E+LCBhcyBkZWZpbmVkIGluIGFwcGVuZGl4IEIgb2YgWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLXhtbDExLTIwMDQwMjA0Lyc+WE1MIDEuMTwvYT5dLiBXaGVuIGEKLSAqIHNlcXVlbmNlIG9mIGNoYXJhY3RlcnMgaXMgZW5jb3VudGVyZWQgdGhhdCBmYWlscyBub3JtYWxpemF0aW9uIGNoZWNraW5nLAotICogYW4gZXJyb3Igd2l0aCB0aGUgPGNvZGU+RE9NRXJyb3IudHlwZTwvY29kZT4gZXF1YWxzIHRvCi0gKiAiY2hlY2stY2hhcmFjdGVyLW5vcm1hbGl6YXRpb24tZmFpbHVyZSIgaXMgaXNzdWVkLiA8L2RkPgotICogPGR0Pjxjb2RlPmZhbHNlPC9jb2RlPjwvZHQ+Ci0gKiA8ZGQ+WzxlbT5yZXF1aXJlZDwvZW0+XSAoPGVtPmRlZmF1bHQ8L2VtPilEbyBub3QgY2hlY2sgaWYgY2hhcmFjdGVycyBhcmUgbm9ybWFsaXplZC48L2RkPgotICogPC9kbD48L2RkPgotICogPGR0Pjxjb2RlPiJjb21tZW50cyI8L2NvZGU+PC9kdD4KLSAqIDxkZD4KLSAqIDxkbD4KLSAqIDxkdD4KLSAqIDxjb2RlPnRydWU8L2NvZGU+PC9kdD4KLSAqIDxkZD5bPGVtPnJlcXVpcmVkPC9lbT5dICg8ZW0+ZGVmYXVsdDwvZW0+KUtlZXAgPGNvZGU+Q29tbWVudDwvY29kZT4gbm9kZXMgaW4gdGhlIGRvY3VtZW50LjwvZGQ+Ci0gKiA8ZHQ+PGNvZGU+ZmFsc2U8L2NvZGU+PC9kdD4KLSAqIDxkZD5bPGVtPnJlcXVpcmVkPC9lbT5dRGlzY2FyZCA8Y29kZT5Db21tZW50PC9jb2RlPiBub2RlcyBpbiB0aGUgZG9jdW1lbnQuPC9kZD4KLSAqIDwvZGw+PC9kZD4KLSAqIDxkdD4KLSAqIDxjb2RlPiJkYXRhdHlwZS1ub3JtYWxpemF0aW9uIjwvY29kZT48L2R0PgotICogPGRkPgotICogPGRsPgotICogPGR0Pjxjb2RlPnRydWU8L2NvZGU+PC9kdD4KLSAqIDxkZD5bPGVtPm9wdGlvbmFsPC9lbT5dIEV4cG9zZSBzY2hlbWEgbm9ybWFsaXplZCB2YWx1ZXMgaW4gdGhlIHRyZWUsIHN1Y2ggYXMgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMS9SRUMteG1sc2NoZW1hLTEtMjAwMTA1MDIvI2tleS1udic+WE1MCi0gKiBTY2hlbWEgbm9ybWFsaXplZCB2YWx1ZXM8L2E+IGluIHRoZSBjYXNlIG9mIFhNTCBTY2hlbWEuIFNpbmNlIHRoaXMgcGFyYW1ldGVyIHJlcXVpcmVzIHRvIGhhdmUgc2NoZW1hCi0gKiBpbmZvcm1hdGlvbiwgdGhlICJ2YWxpZGF0ZSIgcGFyYW1ldGVyIHdpbGwgYWxzbyBiZSBzZXQgdG8KLSAqIDxjb2RlPnRydWU8L2NvZGU+LiBIYXZpbmcgdGhpcyBwYXJhbWV0ZXIgYWN0aXZhdGVkIHdoZW4gInZhbGlkYXRlIiBpcwotICogPGNvZGU+ZmFsc2U8L2NvZGU+IGhhcyBubyBlZmZlY3QgYW5kIG5vIHNjaGVtYS1ub3JtYWxpemF0aW9uIHdpbGwgaGFwcGVuLgotICogPHAgPjxiPk5vdGU6PC9iPiAgU2luY2UgdGhlIGRvY3VtZW50IGNvbnRhaW5zIHRoZSByZXN1bHQgb2YgdGhlIFhNTCAxLjAKLSAqIHByb2Nlc3NpbmcsIHRoaXMgcGFyYW1ldGVyIGRvZXMgbm90IGFwcGx5IHRvIGF0dHJpYnV0ZSB2YWx1ZQotICogbm9ybWFsaXphdGlvbiBhcyBkZWZpbmVkIGluIHNlY3Rpb24gMy4zLjMgb2YgWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLXhtbC0yMDA0MDIwNCc+WE1MIDEuMDwvYT5dIGFuZCBpcyBvbmx5Ci0gKiBtZWFudCBmb3Igc2NoZW1hIGxhbmd1YWdlcyBvdGhlciB0aGFuIERvY3VtZW50IFR5cGUgRGVmaW5pdGlvbiAoRFREKS4gPC9kZD4KLSAqIDxkdD4KLSAqIDxjb2RlPmZhbHNlPC9jb2RlPjwvZHQ+Ci0gKiA8ZGQ+WzxlbT5yZXF1aXJlZDwvZW0+XSAoPGVtPmRlZmF1bHQ8L2VtPikgRG8gbm90IHBlcmZvcm0gc2NoZW1hIG5vcm1hbGl6YXRpb24gb24gdGhlIHRyZWUuIDwvZGQ+Ci0gKiA8L2RsPjwvZGQ+Ci0gKiA8ZHQ+Ci0gKiA8Y29kZT4iZWxlbWVudC1jb250ZW50LXdoaXRlc3BhY2UiPC9jb2RlPjwvZHQ+Ci0gKiA8ZGQ+Ci0gKiA8ZGw+Ci0gKiA8ZHQ+PGNvZGU+dHJ1ZTwvY29kZT48L2R0PgotICogPGRkPls8ZW0+cmVxdWlyZWQ8L2VtPl0gKDxlbT5kZWZhdWx0PC9lbT4pS2VlcCBhbGwgd2hpdGVzcGFjZXMgaW4gdGhlIGRvY3VtZW50LjwvZGQ+Ci0gKiA8ZHQ+PGNvZGU+ZmFsc2U8L2NvZGU+PC9kdD4KLSAqIDxkZD5bPGVtPm9wdGlvbmFsPC9lbT5dIERpc2NhcmQgYWxsIDxjb2RlPlRleHQ8L2NvZGU+IG5vZGVzIHRoYXQgY29udGFpbiB3aGl0ZXNwYWNlcyBpbiBlbGVtZW50Ci0gKiBjb250ZW50LCBhcyBkZXNjcmliZWQgaW4gPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMteG1sLWluZm9zZXQtMjAwNDAyMDQjaW5mb2l0ZW0uY2hhcmFjdGVyJz4KLSAqIFtlbGVtZW50IGNvbnRlbnQgd2hpdGVzcGFjZV08L2E+LiBUaGUgaW1wbGVtZW50YXRpb24gaXMgZXhwZWN0ZWQgdG8gdXNlIHRoZSBhdHRyaWJ1dGUKLSAqIDxjb2RlPlRleHQuaXNFbGVtZW50Q29udGVudFdoaXRlc3BhY2U8L2NvZGU+IHRvIGRldGVybWluZSBpZiBhCi0gKiA8Y29kZT5UZXh0PC9jb2RlPiBub2RlIHNob3VsZCBiZSBkaXNjYXJkZWQgb3Igbm90LjwvZGQ+Ci0gKiA8L2RsPjwvZGQ+Ci0gKiA8ZHQ+PGNvZGU+ImVudGl0aWVzIjwvY29kZT48L2R0PgotICogPGRkPgotICogPGRsPgotICogPGR0PgotICogPGNvZGU+dHJ1ZTwvY29kZT48L2R0PgotICogPGRkPls8ZW0+cmVxdWlyZWQ8L2VtPl0gKDxlbT5kZWZhdWx0PC9lbT4pS2VlcCA8Y29kZT5FbnRpdHlSZWZlcmVuY2U8L2NvZGU+IG5vZGVzIGluIHRoZSBkb2N1bWVudC48L2RkPgotICogPGR0PgotICogPGNvZGU+ZmFsc2U8L2NvZGU+PC9kdD4KLSAqIDxkZD5bPGVtPnJlcXVpcmVkPC9lbT5dIFJlbW92ZSBhbGwgPGNvZGU+RW50aXR5UmVmZXJlbmNlPC9jb2RlPiBub2RlcyBmcm9tIHRoZSBkb2N1bWVudCwKLSAqIHB1dHRpbmcgdGhlIGVudGl0eSBleHBhbnNpb25zIGRpcmVjdGx5IGluIHRoZWlyIHBsYWNlLiA8Y29kZT5UZXh0PC9jb2RlPgotICogbm9kZXMgYXJlIG5vcm1hbGl6ZWQsIGFzIGRlZmluZWQgaW4gPGNvZGU+Tm9kZS5ub3JtYWxpemU8L2NvZGU+LiBPbmx5IDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLXhtbC1pbmZvc2V0LTIwMDQwMjA0LyNpbmZvaXRlbS5yc2UnPgotICogdW5leHBhbmRlZCBlbnRpdHkgcmVmZXJlbmNlczwvYT4gYXJlIGtlcHQgaW4gdGhlIGRvY3VtZW50LiA8L2RkPgotICogPC9kbD4KLSAqIDxwID48Yj5Ob3RlOjwvYj4gIFRoaXMgcGFyYW1ldGVyIGRvZXMgbm90IGFmZmVjdCA8Y29kZT5FbnRpdHk8L2NvZGU+IG5vZGVzLiA8L2RkPgotICogPGR0PgotICogPGNvZGU+ImVycm9yLWhhbmRsZXIiPC9jb2RlPjwvZHQ+Ci0gKiA8ZGQ+WzxlbT5yZXF1aXJlZDwvZW0+XSBDb250YWlucyBhIDxjb2RlPkRPTUVycm9ySGFuZGxlcjwvY29kZT4gb2JqZWN0LiBJZiBhbiBlcnJvciBpcwotICogZW5jb3VudGVyZWQgaW4gdGhlIGRvY3VtZW50LCB0aGUgaW1wbGVtZW50YXRpb24gd2lsbCBjYWxsIGJhY2sgdGhlCi0gKiA8Y29kZT5ET01FcnJvckhhbmRsZXI8L2NvZGU+IHJlZ2lzdGVyZWQgdXNpbmcgdGhpcyBwYXJhbWV0ZXIuIFRoZQotICogaW1wbGVtZW50YXRpb24gbWF5IHByb3ZpZGUgYSBkZWZhdWx0IDxjb2RlPkRPTUVycm9ySGFuZGxlcjwvY29kZT4gb2JqZWN0LgotICogIFdoZW4gY2FsbGVkLCA8Y29kZT5ET01FcnJvci5yZWxhdGVkRGF0YTwvY29kZT4gd2lsbCBjb250YWluIHRoZSBjbG9zZXN0Ci0gKiBub2RlIHRvIHdoZXJlIHRoZSBlcnJvciBvY2N1cnJlZC4gSWYgdGhlIGltcGxlbWVudGF0aW9uIGlzIHVuYWJsZSB0bwotICogZGV0ZXJtaW5lIHRoZSBub2RlIHdoZXJlIHRoZSBlcnJvciBvY2N1cnMsCi0gKiA8Y29kZT5ET01FcnJvci5yZWxhdGVkRGF0YTwvY29kZT4gd2lsbCBjb250YWluIHRoZSA8Y29kZT5Eb2N1bWVudDwvY29kZT4KLSAqIG5vZGUuIE11dGF0aW9ucyB0byB0aGUgZG9jdW1lbnQgZnJvbSB3aXRoaW4gYW4gZXJyb3IgaGFuZGxlciB3aWxsIHJlc3VsdAotICogaW4gaW1wbGVtZW50YXRpb24gZGVwZW5kZW50IGJlaGF2aW9yLiA8L2RkPgotICogPGR0Pjxjb2RlPiJpbmZvc2V0IjwvY29kZT48L2R0PgotICogPGRkPgotICogPGRsPgotICogPGR0PgotICogPGNvZGU+dHJ1ZTwvY29kZT48L2R0PgotICogPGRkPls8ZW0+cmVxdWlyZWQ8L2VtPl1LZWVwIGluIHRoZSBkb2N1bWVudCB0aGUgaW5mb3JtYXRpb24gZGVmaW5lZCBpbiB0aGUgWE1MIEluZm9ybWF0aW9uIFNldCBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMteG1sLWluZm9zZXQtMjAwNDAyMDQvJz5YTUwgSW5mb3JtYXRpb24gU2V0PC9hPl0KLSAqIC5UaGlzIGZvcmNlcyB0aGUgZm9sbG93aW5nIHBhcmFtZXRlcnMgdG8gPGNvZGU+ZmFsc2U8L2NvZGU+OiAiCi0gKiB2YWxpZGF0ZS1pZi1zY2hlbWEiLCAiZW50aXRpZXMiLCAiZGF0YXR5cGUtbm9ybWFsaXphdGlvbiIsICJjZGF0YS1zZWN0aW9ucwotICogIi5UaGlzIGZvcmNlcyB0aGUgZm9sbG93aW5nIHBhcmFtZXRlcnMgdG8gPGNvZGU+dHJ1ZTwvY29kZT46ICIKLSAqIG5hbWVzcGFjZS1kZWNsYXJhdGlvbnMiLCAid2VsbC1mb3JtZWQiLCAiZWxlbWVudC1jb250ZW50LXdoaXRlc3BhY2UiLCAiCi0gKiBjb21tZW50cyIsICJuYW1lc3BhY2VzIi5PdGhlciBwYXJhbWV0ZXJzIGFyZSBub3QgY2hhbmdlZCB1bmxlc3MKLSAqIGV4cGxpY2l0bHkgc3BlY2lmaWVkIGluIHRoZSBkZXNjcmlwdGlvbiBvZiB0aGUgcGFyYW1ldGVycy4gTm90ZSB0aGF0Ci0gKiBxdWVyeWluZyB0aGlzIHBhcmFtZXRlciB3aXRoIDxjb2RlPmdldFBhcmFtZXRlcjwvY29kZT4gcmV0dXJucwotICogPGNvZGU+dHJ1ZTwvY29kZT4gb25seSBpZiB0aGUgaW5kaXZpZHVhbCBwYXJhbWV0ZXJzIHNwZWNpZmllZCBhYm92ZSBhcmUKLSAqIGFwcHJvcHJpYXRlbHkgc2V0LjwvZGQ+Ci0gKiA8ZHQ+PGNvZGU+ZmFsc2U8L2NvZGU+PC9kdD4KLSAqIDxkZD5TZXR0aW5nIDxjb2RlPmluZm9zZXQ8L2NvZGU+IHRvCi0gKiA8Y29kZT5mYWxzZTwvY29kZT4gaGFzIG5vIGVmZmVjdC48L2RkPgotICogPC9kbD48L2RkPgotICogPGR0Pjxjb2RlPiJuYW1lc3BhY2VzIjwvY29kZT48L2R0PgotICogPGRkPgotICogPGRsPgotICogPGR0PgotICogPGNvZGU+dHJ1ZTwvY29kZT48L2R0PgotICogPGRkPls8ZW0+cmVxdWlyZWQ8L2VtPl0gKDxlbT5kZWZhdWx0PC9lbT4pIFBlcmZvcm0gdGhlIG5hbWVzcGFjZSBwcm9jZXNzaW5nIGFzIGRlZmluZWQgaW4gLiA8L2RkPgotICogPGR0Pjxjb2RlPmZhbHNlPC9jb2RlPjwvZHQ+Ci0gKiA8ZGQ+WzxlbT5vcHRpb25hbDwvZW0+XSBEbyBub3QgcGVyZm9ybSB0aGUgbmFtZXNwYWNlIHByb2Nlc3NpbmcuIDwvZGQ+Ci0gKiA8L2RsPjwvZGQ+Ci0gKiA8ZHQ+Ci0gKiA8Y29kZT4ibmFtZXNwYWNlLWRlY2xhcmF0aW9ucyI8L2NvZGU+PC9kdD4KLSAqIDxkZD4gVGhpcyBwYXJhbWV0ZXIgaGFzIG5vIGVmZmVjdCBpZiB0aGUKLSAqIHBhcmFtZXRlciAibmFtZXNwYWNlcyIgaXMgc2V0IHRvIDxjb2RlPmZhbHNlPC9jb2RlPi4KLSAqIDxkbD4KLSAqIDxkdD48Y29kZT50cnVlPC9jb2RlPjwvZHQ+Ci0gKiA8ZGQ+WzxlbT5yZXF1aXJlZDwvZW0+XSAoPGVtPmRlZmF1bHQ8L2VtPikgSW5jbHVkZSBuYW1lc3BhY2UgZGVjbGFyYXRpb24gYXR0cmlidXRlcywgc3BlY2lmaWVkIG9yIGRlZmF1bHRlZCBmcm9tCi0gKiB0aGUgc2NoZW1hLCBpbiB0aGUgZG9jdW1lbnQuIFNlZSBhbHNvIHRoZSBzZWN0aW9ucyAiRGVjbGFyaW5nIE5hbWVzcGFjZXMiCi0gKiBpbiBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMTk5OS9SRUMteG1sLW5hbWVzLTE5OTkwMTE0Lyc+WE1MIE5hbWVzcGFjZXM8L2E+XQotICogIGFuZCBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMteG1sLW5hbWVzMTEtMjAwNDAyMDQvJz5YTUwgTmFtZXNwYWNlcyAxLjE8L2E+XQotICogLjwvZGQ+Ci0gKiA8ZHQ+PGNvZGU+ZmFsc2U8L2NvZGU+PC9kdD4KLSAqIDxkZD5bPGVtPnJlcXVpcmVkPC9lbT5dRGlzY2FyZCBhbGwgbmFtZXNwYWNlIGRlY2xhcmF0aW9uIGF0dHJpYnV0ZXMuIFRoZSBuYW1lc3BhY2UgcHJlZml4ZXMgKAotICogPGNvZGU+Tm9kZS5wcmVmaXg8L2NvZGU+KSBhcmUgcmV0YWluZWQgZXZlbiBpZiB0aGlzIHBhcmFtZXRlciBpcyBzZXQgdG8KLSAqIDxjb2RlPmZhbHNlPC9jb2RlPi48L2RkPgotICogPC9kbD48L2RkPgotICogPGR0Pjxjb2RlPiJub3JtYWxpemUtY2hhcmFjdGVycyI8L2NvZGU+PC9kdD4KLSAqIDxkZD4KLSAqIDxkbD4KLSAqIDxkdD48Y29kZT50cnVlPC9jb2RlPjwvZHQ+Ci0gKiA8ZGQ+WzxlbT5vcHRpb25hbDwvZW0+XSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy14bWwxMS0yMDA0MDIwNC8jZHQtZnVsbG5vcm0nPkZ1bGx5Ci0gKiBub3JtYWxpemVkPC9hPiB0aGUgY2hhcmFjdGVycyBpbiB0aGUgZG9jdW1lbnQgYXMgZGVmaW5lZCBpbiBhcHBlbmRpeCBCIG9mIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy14bWwxMS0yMDA0MDIwNC8nPlhNTCAxLjE8L2E+XS4gPC9kZD4KLSAqIDxkdD4KLSAqIDxjb2RlPmZhbHNlPC9jb2RlPjwvZHQ+Ci0gKiA8ZGQ+WzxlbT5yZXF1aXJlZDwvZW0+XSAoPGVtPmRlZmF1bHQ8L2VtPilEbyBub3QgcGVyZm9ybSBjaGFyYWN0ZXIgbm9ybWFsaXphdGlvbi48L2RkPgotICogPC9kbD48L2RkPgotICogPGR0Pjxjb2RlPiJzY2hlbWEtbG9jYXRpb24iPC9jb2RlPjwvZHQ+Ci0gKiA8ZGQ+WzxlbT5vcHRpb25hbDwvZW0+XSBSZXByZXNlbnQgYSA8Y29kZT5ET01TdHJpbmc8L2NvZGU+IG9iamVjdCBjb250YWluaW5nIGEgbGlzdCBvZiBVUklzLAotICogc2VwYXJhdGVkIGJ5IHdoaXRlc3BhY2VzIChjaGFyYWN0ZXJzIG1hdGNoaW5nIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy14bWwtMjAwNDAyMDQjTlQtUyc+bm9udGVybWluYWwKLSAqIHByb2R1Y3Rpb24gUzwvYT4gZGVmaW5lZCBpbiBzZWN0aW9uIDIuMyBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMteG1sLTIwMDQwMjA0Jz5YTUwgMS4wPC9hPl0pLCB0aGF0Ci0gKiByZXByZXNlbnRzIHRoZSBzY2hlbWFzIGFnYWluc3Qgd2hpY2ggdmFsaWRhdGlvbiBzaG91bGQgb2NjdXIsIGkuZS4gdGhlCi0gKiBjdXJyZW50IHNjaGVtYS4gVGhlIHR5cGVzIG9mIHNjaGVtYXMgcmVmZXJlbmNlZCBpbiB0aGlzIGxpc3QgbXVzdCBtYXRjaAotICogdGhlIHR5cGUgc3BlY2lmaWVkIHdpdGggPGNvZGU+c2NoZW1hLXR5cGU8L2NvZGU+LCBvdGhlcndpc2UgdGhlIGJlaGF2aW9yCi0gKiBvZiBhbiBpbXBsZW1lbnRhdGlvbiBpcyB1bmRlZmluZWQuICBUaGUgc2NoZW1hcyBzcGVjaWZpZWQgdXNpbmcgdGhpcwotICogcHJvcGVydHkgdGFrZSBwcmVjZWRlbmNlIHRvIHRoZSBzY2hlbWEgaW5mb3JtYXRpb24gc3BlY2lmaWVkIGluIHRoZQotICogZG9jdW1lbnQgaXRzZWxmLiBGb3IgbmFtZXNwYWNlIGF3YXJlIHNjaGVtYSwgaWYgYSBzY2hlbWEgc3BlY2lmaWVkIHVzaW5nCi0gKiB0aGlzIHByb3BlcnR5IGFuZCBhIHNjaGVtYSBzcGVjaWZpZWQgaW4gdGhlIGRvY3VtZW50IGluc3RhbmNlIChpLmUuIHVzaW5nCi0gKiB0aGUgPGNvZGU+c2NoZW1hTG9jYXRpb248L2NvZGU+IGF0dHJpYnV0ZSkgaW4gYSBzY2hlbWEgZG9jdW1lbnQgKGkuZS4KLSAqIHVzaW5nIHNjaGVtYSA8Y29kZT5pbXBvcnQ8L2NvZGU+IG1lY2hhbmlzbXMpIHNoYXJlIHRoZSBzYW1lCi0gKiA8Y29kZT50YXJnZXROYW1lc3BhY2U8L2NvZGU+LCB0aGUgc2NoZW1hIHNwZWNpZmllZCBieSB0aGUgdXNlciB1c2luZyB0aGlzCi0gKiBwcm9wZXJ0eSB3aWxsIGJlIHVzZWQuIElmIHR3byBzY2hlbWFzIHNwZWNpZmllZCB1c2luZyB0aGlzIHByb3BlcnR5IHNoYXJlCi0gKiB0aGUgc2FtZSA8Y29kZT50YXJnZXROYW1lc3BhY2U8L2NvZGU+IG9yIGhhdmUgbm8gbmFtZXNwYWNlLCB0aGUgYmVoYXZpb3IKLSAqIGlzIGltcGxlbWVudGF0aW9uIGRlcGVuZGVudC4gIElmIG5vIGxvY2F0aW9uIGhhcyBiZWVuIHByb3ZpZGVkLCB0aGlzCi0gKiBwYXJhbWV0ZXIgaXMgPGNvZGU+bnVsbDwvY29kZT4uCi0gKiA8cCA+PGI+Tm90ZTo8L2I+ICBUaGUgPGNvZGU+InNjaGVtYS1sb2NhdGlvbiI8L2NvZGU+IHBhcmFtZXRlciBpcyBpZ25vcmVkCi0gKiB1bmxlc3MgdGhlICJzY2hlbWEtdHlwZSIgcGFyYW1ldGVyIHZhbHVlIGlzIHNldC4gSXQgaXMgc3Ryb25nbHkKLSAqIHJlY29tbWVuZGVkIHRoYXQgPGNvZGU+RG9jdW1lbnQuZG9jdW1lbnRVUkk8L2NvZGU+IHdpbGwgYmUgc2V0IHNvIHRoYXQgYW4KLSAqIGltcGxlbWVudGF0aW9uIGNhbiBzdWNjZXNzZnVsbHkgcmVzb2x2ZSBhbnkgZXh0ZXJuYWwgZW50aXRpZXMgcmVmZXJlbmNlZC4gPC9kZD4KLSAqIDxkdD4KLSAqIDxjb2RlPiJzY2hlbWEtdHlwZSI8L2NvZGU+PC9kdD4KLSAqIDxkZD5bPGVtPm9wdGlvbmFsPC9lbT5dIFJlcHJlc2VudCBhIDxjb2RlPkRPTVN0cmluZzwvY29kZT4gb2JqZWN0IGNvbnRhaW5pbmcgYW4gYWJzb2x1dGUgVVJJCi0gKiBhbmQgcmVwcmVzZW50aW5nIHRoZSB0eXBlIG9mIHRoZSBzY2hlbWEgbGFuZ3VhZ2UgdXNlZCB0byB2YWxpZGF0ZSBhCi0gKiBkb2N1bWVudCBhZ2FpbnN0LiBOb3RlIHRoYXQgbm8gbGV4aWNhbCBjaGVja2luZyBpcyBkb25lIG9uIHRoZSBhYnNvbHV0ZQotICogVVJJLiAgSWYgdGhpcyBwYXJhbWV0ZXIgaXMgbm90IHNldCwgYSBkZWZhdWx0IHZhbHVlIG1heSBiZSBwcm92aWRlZCBieQotICogdGhlIGltcGxlbWVudGF0aW9uLCBiYXNlZCBvbiB0aGUgc2NoZW1hIGxhbmd1YWdlcyBzdXBwb3J0ZWQgYW5kIG9uIHRoZQotICogc2NoZW1hIGxhbmd1YWdlIHVzZWQgYXQgbG9hZCB0aW1lLiBJZiBubyB2YWx1ZSBpcyBwcm92aWRlZCwgdGhpcwotICogcGFyYW1ldGVyIGlzIDxjb2RlPm51bGw8L2NvZGU+LgotICogPHAgPjxiPk5vdGU6PC9iPiAgRm9yIFhNTCBTY2hlbWEgWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDEvUkVDLXhtbHNjaGVtYS0xLTIwMDEwNTAyLyc+WE1MIFNjaGVtYSBQYXJ0IDE8L2E+XQotICogLCBhcHBsaWNhdGlvbnMgbXVzdCB1c2UgdGhlIHZhbHVlCi0gKiA8Y29kZT4iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiPC9jb2RlPi4gRm9yIFhNTCBEVEQgWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLXhtbC0yMDA0MDIwNCc+WE1MIDEuMDwvYT5dLAotICogYXBwbGljYXRpb25zIG11c3QgdXNlIHRoZSB2YWx1ZQotICogPGNvZGU+Imh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy14bWwiPC9jb2RlPi4gT3RoZXIgc2NoZW1hIGxhbmd1YWdlcyBhcmUKLSAqIG91dHNpZGUgdGhlIHNjb3BlIG9mIHRoZSBXM0MgYW5kIHRoZXJlZm9yZSBzaG91bGQgcmVjb21tZW5kIGFuIGFic29sdXRlCi0gKiBVUkkgaW4gb3JkZXIgdG8gdXNlIHRoaXMgbWV0aG9kLiA8L2RkPgotICogPGR0Pjxjb2RlPiJzcGxpdC1jZGF0YS1zZWN0aW9ucyI8L2NvZGU+PC9kdD4KLSAqIDxkZD4KLSAqIDxkbD4KLSAqIDxkdD4KLSAqIDxjb2RlPnRydWU8L2NvZGU+PC9kdD4KLSAqIDxkZD5bPGVtPnJlcXVpcmVkPC9lbT5dICg8ZW0+ZGVmYXVsdDwvZW0+KVNwbGl0IENEQVRBIHNlY3Rpb25zIGNvbnRhaW5pbmcgdGhlIENEQVRBIHNlY3Rpb24gdGVybWluYXRpb24gbWFya2VyCi0gKiAnXV0mZ3Q7Jy4gV2hlbiBhIENEQVRBIHNlY3Rpb24gaXMgc3BsaXQgYSB3YXJuaW5nIGlzIGlzc3VlZCB3aXRoIGEKLSAqIDxjb2RlPkRPTUVycm9yLnR5cGU8L2NvZGU+IGVxdWFscyB0bwotICogPGNvZGU+ImNkYXRhLXNlY3Rpb25zLXNwbGl0dGVkIjwvY29kZT4gYW5kCi0gKiA8Y29kZT5ET01FcnJvci5yZWxhdGVkRGF0YTwvY29kZT4gZXF1YWxzIHRvIHRoZSBmaXJzdAotICogPGNvZGU+Q0RBVEFTZWN0aW9uPC9jb2RlPiBub2RlIGluIGRvY3VtZW50IG9yZGVyIHJlc3VsdGluZyBmcm9tIHRoZSBzcGxpdC48L2RkPgotICogPGR0PgotICogPGNvZGU+ZmFsc2U8L2NvZGU+PC9kdD4KLSAqIDxkZD5bPGVtPnJlcXVpcmVkPC9lbT5dU2lnbmFsIGFuIGVycm9yIGlmIGEgPGNvZGU+Q0RBVEFTZWN0aW9uPC9jb2RlPiBjb250YWlucyBhbgotICogdW5yZXByZXNlbnRhYmxlIGNoYXJhY3Rlci48L2RkPgotICogPC9kbD48L2RkPgotICogPGR0Pjxjb2RlPiJ2YWxpZGF0ZSI8L2NvZGU+PC9kdD4KLSAqIDxkZD4KLSAqIDxkbD4KLSAqIDxkdD48Y29kZT50cnVlPC9jb2RlPjwvZHQ+Ci0gKiA8ZGQ+WzxlbT5vcHRpb25hbDwvZW0+XSBSZXF1aXJlIHRoZSB2YWxpZGF0aW9uIGFnYWluc3QgYSBzY2hlbWEgKGkuZS4gWE1MIHNjaGVtYSwgRFRELCBhbnkKLSAqIG90aGVyIHR5cGUgb3IgcmVwcmVzZW50YXRpb24gb2Ygc2NoZW1hKSBvZiB0aGUgZG9jdW1lbnQgYXMgaXQgaXMgYmVpbmcKLSAqIG5vcm1hbGl6ZWQgYXMgZGVmaW5lZCBieSBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMteG1sLTIwMDQwMjA0Jz5YTUwgMS4wPC9hPl0uIElmCi0gKiB2YWxpZGF0aW9uIGVycm9ycyBhcmUgZm91bmQsIG9yIG5vIHNjaGVtYSB3YXMgZm91bmQsIHRoZSBlcnJvciBoYW5kbGVyIGlzCi0gKiBub3RpZmllZC4gU2NoZW1hLW5vcm1hbGl6ZWQgdmFsdWVzIHdpbGwgbm90IGJlIGV4cG9zZWQgYWNjb3JkaW5nIHRvIHRoZQotICogc2NoZW1hIGluIHVzZWQgdW5sZXNzIHRoZSBwYXJhbWV0ZXIgImRhdGF0eXBlLW5vcm1hbGl6YXRpb24iIGlzCi0gKiA8Y29kZT50cnVlPC9jb2RlPi4gIFRoaXMgcGFyYW1ldGVyIHdpbGwgcmVldmFsdWF0ZToKLSAqIDx1bD4KLSAqIDxsaT4gQXR0cmlidXRlIG5vZGVzIHdpdGgKLSAqIDxjb2RlPkF0dHIuc3BlY2lmaWVkPC9jb2RlPiBlcXVhbHMgdG8gPGNvZGU+ZmFsc2U8L2NvZGU+LCBhcyBzcGVjaWZpZWQgaW4KLSAqIHRoZSBkZXNjcmlwdGlvbiBvZiB0aGUgPGNvZGU+QXR0cjwvY29kZT4gaW50ZXJmYWNlOwotICogPC9saT4KLSAqIDxsaT4gVGhlIHZhbHVlIG9mIHRoZQotICogYXR0cmlidXRlIDxjb2RlPlRleHQuaXNFbGVtZW50Q29udGVudFdoaXRlc3BhY2U8L2NvZGU+IGZvciBhbGwKLSAqIDxjb2RlPlRleHQ8L2NvZGU+IG5vZGVzOwotICogPC9saT4KLSAqIDxsaT4gVGhlIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUKLSAqIDxjb2RlPkF0dHIuaXNJZDwvY29kZT4gZm9yIGFsbCA8Y29kZT5BdHRyPC9jb2RlPiBub2RlczsKLSAqIDwvbGk+Ci0gKiA8bGk+IFRoZSBhdHRyaWJ1dGVzCi0gKiA8Y29kZT5FbGVtZW50LnNjaGVtYVR5cGVJbmZvPC9jb2RlPiBhbmQgPGNvZGU+QXR0ci5zY2hlbWFUeXBlSW5mbzwvY29kZT4uCi0gKiA8L2xpPgotICogPC91bD4KLSAqIDxwID48Yj5Ob3RlOjwvYj4gICJ2YWxpZGF0ZS1pZi1zY2hlbWEiIGFuZCAidmFsaWRhdGUiIGFyZSBtdXR1YWxseQotICogZXhjbHVzaXZlLCBzZXR0aW5nIG9uZSBvZiB0aGVtIHRvIDxjb2RlPnRydWU8L2NvZGU+IHdpbGwgc2V0IHRoZSBvdGhlcgotICogb25lIHRvIDxjb2RlPmZhbHNlPC9jb2RlPi4gQXBwbGljYXRpb25zIHNob3VsZCBhbHNvIGNvbnNpZGVyIHNldHRpbmcgdGhlCi0gKiBwYXJhbWV0ZXIgIndlbGwtZm9ybWVkIiB0byA8Y29kZT50cnVlPC9jb2RlPiwgd2hpY2ggaXMgdGhlIGRlZmF1bHQgZm9yCi0gKiB0aGF0IG9wdGlvbiwgd2hlbiB2YWxpZGF0aW5nIHRoZSBkb2N1bWVudC4gPC9kZD4KLSAqIDxkdD48Y29kZT5mYWxzZTwvY29kZT48L2R0PgotICogPGRkPls8ZW0+cmVxdWlyZWQ8L2VtPl0gKDxlbT5kZWZhdWx0PC9lbT4pIERvIG5vdCBhY2NvbXBsaXNoIHNjaGVtYSBwcm9jZXNzaW5nLCBpbmNsdWRpbmcgdGhlIGludGVybmFsIHN1YnNldAotICogcHJvY2Vzc2luZy4gRGVmYXVsdCBhdHRyaWJ1dGUgdmFsdWVzIGluZm9ybWF0aW9uIGFyZSBrZXB0LiBOb3RlIHRoYXQKLSAqIHZhbGlkYXRpb24gbWlnaHQgc3RpbGwgaGFwcGVuIGlmICJ2YWxpZGF0ZS1pZi1zY2hlbWEiIGlzIDxjb2RlPnRydWU8L2NvZGU+Ci0gKiAuIDwvZGQ+Ci0gKiA8L2RsPjwvZGQ+Ci0gKiA8ZHQ+PGNvZGU+InZhbGlkYXRlLWlmLXNjaGVtYSI8L2NvZGU+PC9kdD4KLSAqIDxkZD4KLSAqIDxkbD4KLSAqIDxkdD48Y29kZT50cnVlPC9jb2RlPjwvZHQ+Ci0gKiA8ZGQ+WzxlbT5vcHRpb25hbDwvZW0+XUVuYWJsZSB2YWxpZGF0aW9uIG9ubHkgaWYgYSBkZWNsYXJhdGlvbiBmb3IgdGhlIGRvY3VtZW50IGVsZW1lbnQgY2FuIGJlCi0gKiBmb3VuZCBpbiBhIHNjaGVtYSAoaW5kZXBlbmRlbnRseSBvZiB3aGVyZSBpdCBpcyBmb3VuZCwgaS5lLiBYTUwgc2NoZW1hLAotICogRFRELCBvciBhbnkgb3RoZXIgdHlwZSBvciByZXByZXNlbnRhdGlvbiBvZiBzY2hlbWEpLiBJZiB2YWxpZGF0aW9uIGlzCi0gKiBlbmFibGVkLCB0aGlzIHBhcmFtZXRlciBoYXMgdGhlIHNhbWUgYmVoYXZpb3IgYXMgdGhlIHBhcmFtZXRlciAidmFsaWRhdGUiCi0gKiBzZXQgdG8gPGNvZGU+dHJ1ZTwvY29kZT4uCi0gKiA8cCA+PGI+Tm90ZTo8L2I+ICAidmFsaWRhdGUtaWYtc2NoZW1hIiBhbmQgInZhbGlkYXRlIiBhcmUgbXV0dWFsbHkKLSAqIGV4Y2x1c2l2ZSwgc2V0dGluZyBvbmUgb2YgdGhlbSB0byA8Y29kZT50cnVlPC9jb2RlPiB3aWxsIHNldCB0aGUgb3RoZXIKLSAqIG9uZSB0byA8Y29kZT5mYWxzZTwvY29kZT4uIDwvZGQ+Ci0gKiA8ZHQ+PGNvZGU+ZmFsc2U8L2NvZGU+PC9kdD4KLSAqIDxkZD5bPGVtPnJlcXVpcmVkPC9lbT5dICg8ZW0+ZGVmYXVsdDwvZW0+KSBObyBzY2hlbWEgcHJvY2Vzc2luZyBzaG91bGQgYmUgcGVyZm9ybWVkIGlmIHRoZSBkb2N1bWVudCBoYXMgYSBzY2hlbWEsCi0gKiBpbmNsdWRpbmcgaW50ZXJuYWwgc3Vic2V0IHByb2Nlc3NpbmcuIERlZmF1bHQgYXR0cmlidXRlIHZhbHVlcwotICogaW5mb3JtYXRpb24gYXJlIGtlcHQuIE5vdGUgdGhhdCB2YWxpZGF0aW9uIG11c3Qgc3RpbGwgaGFwcGVuIGlmICJ2YWxpZGF0ZQotICogIiBpcyA8Y29kZT50cnVlPC9jb2RlPi4gPC9kZD4KLSAqIDwvZGw+PC9kZD4KLSAqIDxkdD48Y29kZT4id2VsbC1mb3JtZWQiPC9jb2RlPjwvZHQ+Ci0gKiA8ZGQ+Ci0gKiA8ZGw+Ci0gKiA8ZHQ+PGNvZGU+dHJ1ZTwvY29kZT48L2R0PgotICogPGRkPls8ZW0+cmVxdWlyZWQ8L2VtPl0gKDxlbT5kZWZhdWx0PC9lbT4pIENoZWNrIGlmIGFsbCBub2RlcyBhcmUgWE1MIHdlbGwgZm9ybWVkIGFjY29yZGluZyB0byB0aGUgWE1MIHZlcnNpb24gaW4KLSAqIHVzZSBpbiA8Y29kZT5Eb2N1bWVudC54bWxWZXJzaW9uPC9jb2RlPjoKLSAqIDx1bD4KLSAqIDxsaT4gY2hlY2sgaWYgdGhlIGF0dHJpYnV0ZQotICogPGNvZGU+Tm9kZS5ub2RlTmFtZTwvY29kZT4gY29udGFpbnMgaW52YWxpZCBjaGFyYWN0ZXJzIGFjY29yZGluZyB0byBpdHMKLSAqIG5vZGUgdHlwZSBhbmQgZ2VuZXJhdGUgYSA8Y29kZT5ET01FcnJvcjwvY29kZT4gb2YgdHlwZQotICogPGNvZGU+IndmLWludmFsaWQtY2hhcmFjdGVyLWluLW5vZGUtbmFtZSI8L2NvZGU+LCB3aXRoIGEKLSAqIDxjb2RlPkRPTUVycm9yLlNFVkVSSVRZX0VSUk9SPC9jb2RlPiBzZXZlcml0eSwgaWYgbmVjZXNzYXJ5OwotICogPC9saT4KLSAqIDxsaT4gY2hlY2sgaWYKLSAqIHRoZSB0ZXh0IGNvbnRlbnQgaW5zaWRlIDxjb2RlPkF0dHI8L2NvZGU+LCA8Y29kZT5FbGVtZW50PC9jb2RlPiwKLSAqIDxjb2RlPkNvbW1lbnQ8L2NvZGU+LCA8Y29kZT5UZXh0PC9jb2RlPiwgPGNvZGU+Q0RBVEFTZWN0aW9uPC9jb2RlPiBub2RlcwotICogZm9yIGludmFsaWQgY2hhcmFjdGVycyBhbmQgZ2VuZXJhdGUgYSA8Y29kZT5ET01FcnJvcjwvY29kZT4gb2YgdHlwZQotICogPGNvZGU+IndmLWludmFsaWQtY2hhcmFjdGVyIjwvY29kZT4sIHdpdGggYQotICogPGNvZGU+RE9NRXJyb3IuU0VWRVJJVFlfRVJST1I8L2NvZGU+IHNldmVyaXR5LCBpZiBuZWNlc3Nhcnk7Ci0gKiA8L2xpPgotICogPGxpPiBjaGVjayBpZgotICogdGhlIGRhdGEgaW5zaWRlIDxjb2RlPlByb2Nlc3NpbmdJbnN0cnVjdGlvbjwvY29kZT4gbm9kZXMgZm9yIGludmFsaWQKLSAqIGNoYXJhY3RlcnMgYW5kIGdlbmVyYXRlIGEgPGNvZGU+RE9NRXJyb3I8L2NvZGU+IG9mIHR5cGUKLSAqIDxjb2RlPiJ3Zi1pbnZhbGlkLWNoYXJhY3RlciI8L2NvZGU+LCB3aXRoIGEKLSAqIDxjb2RlPkRPTUVycm9yLlNFVkVSSVRZX0VSUk9SPC9jb2RlPiBzZXZlcml0eSwgaWYgbmVjZXNzYXJ5OwotICogPC9saT4KLSAqIDwvdWw+PC9kZD4KLSAqIDxkdD4KLSAqIDxjb2RlPmZhbHNlPC9jb2RlPjwvZHQ+Ci0gKiA8ZGQ+WzxlbT5vcHRpb25hbDwvZW0+XSBEbyBub3QgY2hlY2sgZm9yIFhNTCB3ZWxsLWZvcm1lZG5lc3MuIDwvZGQ+Ci0gKiA8L2RsPjwvZGQ+Ci0gKiA8L2RsPgotICogPHA+IFRoZSByZXNvbHV0aW9uIG9mIHRoZSBzeXN0ZW0gaWRlbnRpZmllcnMgYXNzb2NpYXRlZCB3aXRoIGVudGl0aWVzIGlzCi0gKiBkb25lIHVzaW5nIDxjb2RlPkRvY3VtZW50LmRvY3VtZW50VVJJPC9jb2RlPi4gSG93ZXZlciwgd2hlbiB0aGUgZmVhdHVyZQotICogIkxTIiBkZWZpbmVkIGluIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy1ET00tTGV2ZWwtMy1MUy0yMDA0MDQwNyc+RE9NIExldmVsIDMgTG9hZCBhbmQgU2F2ZTwvYT5dCi0gKiAgaXMgc3VwcG9ydGVkIGJ5IHRoZSBET00gaW1wbGVtZW50YXRpb24sIHRoZSBwYXJhbWV0ZXIKLSAqICJyZXNvdXJjZS1yZXNvbHZlciIgY2FuIGFsc28gYmUgdXNlZCBvbiA8Y29kZT5ET01Db25maWd1cmF0aW9uPC9jb2RlPgotICogb2JqZWN0cyBhdHRhY2hlZCB0byA8Y29kZT5Eb2N1bWVudDwvY29kZT4gbm9kZXMuIElmIHRoaXMgcGFyYW1ldGVyIGlzCi0gKiBzZXQsIDxjb2RlPkRvY3VtZW50Lm5vcm1hbGl6ZURvY3VtZW50KCk8L2NvZGU+IHdpbGwgaW52b2tlIHRoZSByZXNvdXJjZQotICogcmVzb2x2ZXIgaW5zdGVhZCBvZiB1c2luZyA8Y29kZT5Eb2N1bWVudC5kb2N1bWVudFVSSTwvY29kZT4uCi0gKiA8cD5TZWUgYWxzbyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMtRE9NLUxldmVsLTMtQ29yZS0yMDA0MDQwNyc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDMgQ29yZSBTcGVjaWZpY2F0aW9uPC9hPi4KLSAqIEBzaW5jZSBET00gTGV2ZWwgMwotICovCi1wdWJsaWMgaW50ZXJmYWNlIERPTUNvbmZpZ3VyYXRpb24gewotICAgIC8qKgotICAgICAqIFNldCB0aGUgdmFsdWUgb2YgYSBwYXJhbWV0ZXIuCi0gICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIHBhcmFtZXRlciB0byBzZXQuCi0gICAgICogQHBhcmFtIHZhbHVlICBUaGUgbmV3IHZhbHVlIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoZSB1c2VyIHdpc2hlcyB0bwotICAgICAqICAgdW5zZXQgdGhlIHBhcmFtZXRlci4gV2hpbGUgdGhlIHR5cGUgb2YgdGhlIHZhbHVlIHBhcmFtZXRlciBpcwotICAgICAqICAgZGVmaW5lZCBhcyA8Y29kZT5ET01Vc2VyRGF0YTwvY29kZT4sIHRoZSBvYmplY3QgdHlwZSBtdXN0IG1hdGNoIHRoZQotICAgICAqICAgdHlwZSBkZWZpbmVkIGJ5IHRoZSBkZWZpbml0aW9uIG9mIHRoZSBwYXJhbWV0ZXIuIEZvciBleGFtcGxlLCBpZgotICAgICAqICAgdGhlIHBhcmFtZXRlciBpcyAiZXJyb3ItaGFuZGxlciIsIHRoZSB2YWx1ZSBtdXN0IGJlIG9mIHR5cGUKLSAgICAgKiAgIDxjb2RlPkRPTUVycm9ySGFuZGxlcjwvY29kZT4uCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgICBOT1RfRk9VTkRfRVJSOiBSYWlzZWQgd2hlbiB0aGUgcGFyYW1ldGVyIG5hbWUgaXMgbm90IHJlY29nbml6ZWQuCi0gICAgICogICA8YnI+IE5PVF9TVVBQT1JURURfRVJSOiBSYWlzZWQgd2hlbiB0aGUgcGFyYW1ldGVyIG5hbWUgaXMgcmVjb2duaXplZAotICAgICAqICAgYnV0IHRoZSByZXF1ZXN0ZWQgdmFsdWUgY2Fubm90IGJlIHNldC4KLSAgICAgKiAgIDxicj4gVFlQRV9NSVNNQVRDSF9FUlI6IFJhaXNlZCBpZiB0aGUgdmFsdWUgdHlwZSBmb3IgdGhpcyBwYXJhbWV0ZXIKLSAgICAgKiAgIG5hbWUgaXMgaW5jb21wYXRpYmxlIHdpdGggdGhlIGV4cGVjdGVkIHZhbHVlIHR5cGUuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0UGFyYW1ldGVyKFN0cmluZyBuYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPYmplY3QgdmFsdWUpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiAgUmV0dXJuIHRoZSB2YWx1ZSBvZiBhIHBhcmFtZXRlciBpZiBrbm93bi4KLSAgICAgKiBAcGFyYW0gbmFtZSAgVGhlIG5hbWUgb2YgdGhlIHBhcmFtZXRlci4KLSAgICAgKiBAcmV0dXJuICBUaGUgY3VycmVudCBvYmplY3QgYXNzb2NpYXRlZCB3aXRoIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVyIG9yCi0gICAgICogICA8Y29kZT5udWxsPC9jb2RlPiBpZiBubyBvYmplY3QgaGFzIGJlZW4gYXNzb2NpYXRlZCBvciBpZiB0aGUKLSAgICAgKiAgIHBhcmFtZXRlciBpcyBub3Qgc3VwcG9ydGVkLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICAgTk9UX0ZPVU5EX0VSUjogUmFpc2VkIHdoZW4gdGhlIHBhcmFtZXRlciBuYW1lIGlzIG5vdCByZWNvZ25pemVkLgotICAgICAqLwotICAgIHB1YmxpYyBPYmplY3QgZ2V0UGFyYW1ldGVyKFN0cmluZyBuYW1lKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBDaGVjayBpZiBzZXR0aW5nIGEgcGFyYW1ldGVyIHRvIGEgc3BlY2lmaWMgdmFsdWUgaXMgc3VwcG9ydGVkLgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBwYXJhbWV0ZXIgdG8gY2hlY2suCi0gICAgICogQHBhcmFtIHZhbHVlICBBbiBvYmplY3QuIGlmIDxjb2RlPm51bGw8L2NvZGU+LCB0aGUgcmV0dXJuZWQgdmFsdWUgaXMKLSAgICAgKiAgIDxjb2RlPnRydWU8L2NvZGU+LgotICAgICAqIEByZXR1cm4gIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBwYXJhbWV0ZXIgY291bGQgYmUgc3VjY2Vzc2Z1bGx5IHNldAotICAgICAqICAgdG8gdGhlIHNwZWNpZmllZCB2YWx1ZSwgb3IgPGNvZGU+ZmFsc2U8L2NvZGU+IGlmIHRoZSBwYXJhbWV0ZXIgaXMKLSAgICAgKiAgIG5vdCByZWNvZ25pemVkIG9yIHRoZSByZXF1ZXN0ZWQgdmFsdWUgaXMgbm90IHN1cHBvcnRlZC4gVGhpcyBkb2VzCi0gICAgICogICBub3QgY2hhbmdlIHRoZSBjdXJyZW50IHZhbHVlIG9mIHRoZSBwYXJhbWV0ZXIgaXRzZWxmLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGNhblNldFBhcmFtZXRlcihTdHJpbmcgbmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT2JqZWN0IHZhbHVlKTsKLQotICAgIC8qKgotICAgICAqICBUaGUgbGlzdCBvZiB0aGUgcGFyYW1ldGVycyBzdXBwb3J0ZWQgYnkgdGhpcwotICAgICAqIDxjb2RlPkRPTUNvbmZpZ3VyYXRpb248L2NvZGU+IG9iamVjdCBhbmQgZm9yIHdoaWNoIGF0IGxlYXN0IG9uZSB2YWx1ZQotICAgICAqIGNhbiBiZSBzZXQgYnkgdGhlIGFwcGxpY2F0aW9uLiBOb3RlIHRoYXQgdGhpcyBsaXN0IGNhbiBhbHNvIGNvbnRhaW4KLSAgICAgKiBwYXJhbWV0ZXIgbmFtZXMgZGVmaW5lZCBvdXRzaWRlIHRoaXMgc3BlY2lmaWNhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgRE9NU3RyaW5nTGlzdCBnZXRQYXJhbWV0ZXJOYW1lcygpOwotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL3czYy9kb20vRE9NRXJyb3IuamF2YSBiL3NyYy9vcmcvdzNjL2RvbS9ET01FcnJvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxNTgyMWM4Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS9ET01FcnJvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTE2ICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBUaGlzIGZpbGUgaXMgYXZhaWxhYmxlIHVuZGVyIGFuZCBnb3Zlcm5lZCBieSB0aGUgR05VIEdlbmVyYWwgUHVibGljCi0gKiBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqIEhvd2V2ZXIsIHRoZSBmb2xsb3dpbmcgbm90aWNlIGFjY29tcGFuaWVkIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIG9mIHRoaXMKLSAqIGZpbGUgYW5kLCBwZXIgaXRzIHRlcm1zLCBzaG91bGQgbm90IGJlIHJlbW92ZWQ6Ci0gKgotICogQ29weXJpZ2h0IChjKSAyMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCi0gKgotICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEV1cm9wZWFuIFJlc2VhcmNoIENvbnNvcnRpdW0gZm9yCi0gKiBJbmZvcm1hdGljcyBhbmQgTWF0aGVtYXRpY3MsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMKLSAqIHdvcmsgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQyhyKSBTb2Z0d2FyZSBMaWNlbnNlIFsxXSBpbiB0aGUgaG9wZSB0aGF0Ci0gKiBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQKLSAqIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4KLSAqCi0gKiBbMV0gaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8yMDAyL2NvcHlyaWdodC1zb2Z0d2FyZS0yMDAyMTIzMQotICovCi0KLXBhY2thZ2Ugb3JnLnczYy5kb207Ci0KLS8qKgotICogPGNvZGU+RE9NRXJyb3I8L2NvZGU+IGlzIGFuIGludGVyZmFjZSB0aGF0IGRlc2NyaWJlcyBhbiBlcnJvci4KLSAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy1ET00tTGV2ZWwtMy1Db3JlLTIwMDQwNDA3Jz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMyBDb3JlIFNwZWNpZmljYXRpb248L2E+LgotICogQHNpbmNlIERPTSBMZXZlbCAzCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgRE9NRXJyb3IgewotICAgIC8vIEVycm9yU2V2ZXJpdHkKLSAgICAvKioKLSAgICAgKiBUaGUgc2V2ZXJpdHkgb2YgdGhlIGVycm9yIGRlc2NyaWJlZCBieSB0aGUgPGNvZGU+RE9NRXJyb3I8L2NvZGU+IGlzCi0gICAgICogd2FybmluZy4gQSA8Y29kZT5TRVZFUklUWV9XQVJOSU5HPC9jb2RlPiB3aWxsIG5vdCBjYXVzZSB0aGUKLSAgICAgKiBwcm9jZXNzaW5nIHRvIHN0b3AsIHVubGVzcyA8Y29kZT5ET01FcnJvckhhbmRsZXIuaGFuZGxlRXJyb3IoKTwvY29kZT4KLSAgICAgKiByZXR1cm5zIDxjb2RlPmZhbHNlPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFNFVkVSSVRZX1dBUk5JTkcgICAgICAgICAgPSAxOwotICAgIC8qKgotICAgICAqIFRoZSBzZXZlcml0eSBvZiB0aGUgZXJyb3IgZGVzY3JpYmVkIGJ5IHRoZSA8Y29kZT5ET01FcnJvcjwvY29kZT4gaXMKLSAgICAgKiBlcnJvci4gQSA8Y29kZT5TRVZFUklUWV9FUlJPUjwvY29kZT4gbWF5IG5vdCBjYXVzZSB0aGUgcHJvY2Vzc2luZyB0bwotICAgICAqIHN0b3AgaWYgdGhlIGVycm9yIGNhbiBiZSByZWNvdmVyZWQsIHVubGVzcwotICAgICAqIDxjb2RlPkRPTUVycm9ySGFuZGxlci5oYW5kbGVFcnJvcigpPC9jb2RlPiByZXR1cm5zIDxjb2RlPmZhbHNlPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFNFVkVSSVRZX0VSUk9SICAgICAgICAgICAgPSAyOwotICAgIC8qKgotICAgICAqIFRoZSBzZXZlcml0eSBvZiB0aGUgZXJyb3IgZGVzY3JpYmVkIGJ5IHRoZSA8Y29kZT5ET01FcnJvcjwvY29kZT4gaXMKLSAgICAgKiBmYXRhbCBlcnJvci4gQSA8Y29kZT5TRVZFUklUWV9GQVRBTF9FUlJPUjwvY29kZT4gd2lsbCBjYXVzZSB0aGUKLSAgICAgKiBub3JtYWwgcHJvY2Vzc2luZyB0byBzdG9wLiBUaGUgcmV0dXJuIHZhbHVlIG9mCi0gICAgICogPGNvZGU+RE9NRXJyb3JIYW5kbGVyLmhhbmRsZUVycm9yKCk8L2NvZGU+IGlzIGlnbm9yZWQgdW5sZXNzIHRoZQotICAgICAqIGltcGxlbWVudGF0aW9uIGNob29zZXMgdG8gY29udGludWUsIGluIHdoaWNoIGNhc2UgdGhlIGJlaGF2aW9yCi0gICAgICogYmVjb21lcyB1bmRlZmluZWQuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBTRVZFUklUWV9GQVRBTF9FUlJPUiAgICAgID0gMzsKLQotICAgIC8qKgotICAgICAqIFRoZSBzZXZlcml0eSBvZiB0aGUgZXJyb3IsIGVpdGhlciA8Y29kZT5TRVZFUklUWV9XQVJOSU5HPC9jb2RlPiwKLSAgICAgKiA8Y29kZT5TRVZFUklUWV9FUlJPUjwvY29kZT4sIG9yIDxjb2RlPlNFVkVSSVRZX0ZBVEFMX0VSUk9SPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgc2hvcnQgZ2V0U2V2ZXJpdHkoKTsKLQotICAgIC8qKgotICAgICAqIEFuIGltcGxlbWVudGF0aW9uIHNwZWNpZmljIHN0cmluZyBkZXNjcmliaW5nIHRoZSBlcnJvciB0aGF0IG9jY3VycmVkLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TWVzc2FnZSgpOwotCi0gICAgLyoqCi0gICAgICogIEEgPGNvZGU+RE9NU3RyaW5nPC9jb2RlPiBpbmRpY2F0aW5nIHdoaWNoIHJlbGF0ZWQgZGF0YSBpcyBleHBlY3RlZCBpbgotICAgICAqIDxjb2RlPnJlbGF0ZWREYXRhPC9jb2RlPi4gVXNlcnMgc2hvdWxkIHJlZmVyIHRvIHRoZSBzcGVjaWZpY2F0aW9uIG9mCi0gICAgICogdGhlIGVycm9yIGluIG9yZGVyIHRvIGZpbmQgaXRzIDxjb2RlPkRPTVN0cmluZzwvY29kZT4gdHlwZSBhbmQKLSAgICAgKiA8Y29kZT5yZWxhdGVkRGF0YTwvY29kZT4gZGVmaW5pdGlvbnMgaWYgYW55LgotICAgICAqIDxwID48Yj5Ob3RlOjwvYj4gIEFzIGFuIGV4YW1wbGUsCi0gICAgICogPGNvZGU+RG9jdW1lbnQubm9ybWFsaXplRG9jdW1lbnQoKTwvY29kZT4gZG9lcyBnZW5lcmF0ZSB3YXJuaW5ncyB3aGVuCi0gICAgICogdGhlICJzcGxpdC1jZGF0YS1zZWN0aW9ucyIgcGFyYW1ldGVyIGlzIGluIHVzZS4gVGhlcmVmb3JlLCB0aGUgbWV0aG9kCi0gICAgICogZ2VuZXJhdGVzIGEgPGNvZGU+U0VWRVJJVFlfV0FSTklORzwvY29kZT4gd2l0aCA8Y29kZT50eXBlPC9jb2RlPgotICAgICAqIDxjb2RlPiJjZGF0YS1zZWN0aW9ucy1zcGxpdHRlZCI8L2NvZGU+IGFuZCB0aGUgZmlyc3QKLSAgICAgKiA8Y29kZT5DREFUQVNlY3Rpb248L2NvZGU+IG5vZGUgaW4gZG9jdW1lbnQgb3JkZXIgcmVzdWx0aW5nIGZyb20gdGhlCi0gICAgICogc3BsaXQgaXMgcmV0dXJuZWQgYnkgdGhlIDxjb2RlPnJlbGF0ZWREYXRhPC9jb2RlPiBhdHRyaWJ1dGUuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRUeXBlKCk7Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgcmVsYXRlZCBwbGF0Zm9ybSBkZXBlbmRlbnQgZXhjZXB0aW9uIGlmIGFueS4KLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0IGdldFJlbGF0ZWRFeGNlcHRpb24oKTsKLQotICAgIC8qKgotICAgICAqICBUaGUgcmVsYXRlZCA8Y29kZT5ET01FcnJvci50eXBlPC9jb2RlPiBkZXBlbmRlbnQgZGF0YSBpZiBhbnkuCi0gICAgICovCi0gICAgcHVibGljIE9iamVjdCBnZXRSZWxhdGVkRGF0YSgpOwotCi0gICAgLyoqCi0gICAgICogVGhlIGxvY2F0aW9uIG9mIHRoZSBlcnJvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgRE9NTG9jYXRvciBnZXRMb2NhdGlvbigpOwotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL3czYy9kb20vRE9NRXJyb3JIYW5kbGVyLmphdmEgYi9zcmMvb3JnL3czYy9kb20vRE9NRXJyb3JIYW5kbGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDFkZTBjYjkuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy93M2MvZG9tL0RPTUVycm9ySGFuZGxlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNzQgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIFRoaXMgZmlsZSBpcyBhdmFpbGFibGUgdW5kZXIgYW5kIGdvdmVybmVkIGJ5IHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKLSAqIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICogSG93ZXZlciwgdGhlIGZvbGxvd2luZyBub3RpY2UgYWNjb21wYW5pZWQgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcwotICogZmlsZSBhbmQsIHBlciBpdHMgdGVybXMsIHNob3VsZCBub3QgYmUgcmVtb3ZlZDoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKLSAqCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgRXVyb3BlYW4gUmVzZWFyY2ggQ29uc29ydGl1bSBmb3IKLSAqIEluZm9ybWF0aWNzIGFuZCBNYXRoZW1hdGljcywgS2VpbyBVbml2ZXJzaXR5KS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcwotICogd29yayBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDKHIpIFNvZnR3YXJlIExpY2Vuc2UgWzFdIGluIHRoZSBob3BlIHRoYXQKLSAqIGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZAotICogd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLgotICoKLSAqIFsxXSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLzIwMDIvY29weXJpZ2h0LXNvZnR3YXJlLTIwMDIxMjMxCi0gKi8KLQotcGFja2FnZSBvcmcudzNjLmRvbTsKLQotLyoqCi0gKiAgPGNvZGU+RE9NRXJyb3JIYW5kbGVyPC9jb2RlPiBpcyBhIGNhbGxiYWNrIGludGVyZmFjZSB0aGF0IHRoZSBET00KLSAqIGltcGxlbWVudGF0aW9uIGNhbiBjYWxsIHdoZW4gcmVwb3J0aW5nIGVycm9ycyB0aGF0IGhhcHBlbnMgd2hpbGUKLSAqIHByb2Nlc3NpbmcgWE1MIGRhdGEsIG9yIHdoZW4gZG9pbmcgc29tZSBvdGhlciBwcm9jZXNzaW5nIChlLmcuIHZhbGlkYXRpbmcKLSAqIGEgZG9jdW1lbnQpLiBBIDxjb2RlPkRPTUVycm9ySGFuZGxlcjwvY29kZT4gb2JqZWN0IGNhbiBiZSBhdHRhY2hlZCB0byBhCi0gKiA8Y29kZT5Eb2N1bWVudDwvY29kZT4gdXNpbmcgdGhlICJlcnJvci1oYW5kbGVyIiBvbiB0aGUKLSAqIDxjb2RlPkRPTUNvbmZpZ3VyYXRpb248L2NvZGU+IGludGVyZmFjZS4gSWYgbW9yZSB0aGFuIG9uZSBlcnJvciBuZWVkcyB0bwotICogYmUgcmVwb3J0ZWQgZHVyaW5nIGFuIG9wZXJhdGlvbiwgdGhlIHNlcXVlbmNlIGFuZCBudW1iZXJzIG9mIHRoZSBlcnJvcnMKLSAqIHBhc3NlZCB0byB0aGUgZXJyb3IgaGFuZGxlciBhcmUgaW1wbGVtZW50YXRpb24gZGVwZW5kZW50LgotICogPHA+IFRoZSBhcHBsaWNhdGlvbiB0aGF0IGlzIHVzaW5nIHRoZSBET00gaW1wbGVtZW50YXRpb24gaXMgZXhwZWN0ZWQgdG8KLSAqIGltcGxlbWVudCB0aGlzIGludGVyZmFjZS4KLSAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy1ET00tTGV2ZWwtMy1Db3JlLTIwMDQwNDA3Jz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMyBDb3JlIFNwZWNpZmljYXRpb248L2E+LgotICogQHNpbmNlIERPTSBMZXZlbCAzCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgRE9NRXJyb3JIYW5kbGVyIHsKLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgb24gdGhlIGVycm9yIGhhbmRsZXIgd2hlbiBhbiBlcnJvciBvY2N1cnMuCi0gICAgICogPGJyPiBJZiBhbiBleGNlcHRpb24gaXMgdGhyb3duIGZyb20gdGhpcyBtZXRob2QsIGl0IGlzIGNvbnNpZGVyZWQgdG8gYmUKLSAgICAgKiBlcXVpdmFsZW50IG9mIHJldHVybmluZyA8Y29kZT50cnVlPC9jb2RlPi4KLSAgICAgKiBAcGFyYW0gZXJyb3IgIFRoZSBlcnJvciBvYmplY3QgdGhhdCBkZXNjcmliZXMgdGhlIGVycm9yLiBUaGlzIG9iamVjdAotICAgICAqICAgbWF5IGJlIHJldXNlZCBieSB0aGUgRE9NIGltcGxlbWVudGF0aW9uIGFjcm9zcyBtdWx0aXBsZSBjYWxscyB0bwotICAgICAqICAgdGhlIDxjb2RlPmhhbmRsZUVycm9yPC9jb2RlPiBtZXRob2QuCi0gICAgICogQHJldHVybiAgSWYgdGhlIDxjb2RlPmhhbmRsZUVycm9yPC9jb2RlPiBtZXRob2QgcmV0dXJucwotICAgICAqICAgPGNvZGU+ZmFsc2U8L2NvZGU+LCB0aGUgRE9NIGltcGxlbWVudGF0aW9uIHNob3VsZCBzdG9wIHRoZSBjdXJyZW50Ci0gICAgICogICBwcm9jZXNzaW5nIHdoZW4gcG9zc2libGUuIElmIHRoZSBtZXRob2QgcmV0dXJucyA8Y29kZT50cnVlPC9jb2RlPiwKLSAgICAgKiAgIHRoZSBwcm9jZXNzaW5nIG1heSBjb250aW51ZSBkZXBlbmRpbmcgb24KLSAgICAgKiAgIDxjb2RlPkRPTUVycm9yLnNldmVyaXR5PC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBoYW5kbGVFcnJvcihET01FcnJvciBlcnJvcik7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvdzNjL2RvbS9ET01FeGNlcHRpb24uamF2YSBiL3NyYy9vcmcvdzNjL2RvbS9ET01FeGNlcHRpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYjM1MWI3Yi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3czYy9kb20vRE9NRXhjZXB0aW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNjIgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIFRoaXMgZmlsZSBpcyBhdmFpbGFibGUgdW5kZXIgYW5kIGdvdmVybmVkIGJ5IHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKLSAqIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICogSG93ZXZlciwgdGhlIGZvbGxvd2luZyBub3RpY2UgYWNjb21wYW5pZWQgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcwotICogZmlsZSBhbmQsIHBlciBpdHMgdGVybXMsIHNob3VsZCBub3QgYmUgcmVtb3ZlZDoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKLSAqCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgRXVyb3BlYW4gUmVzZWFyY2ggQ29uc29ydGl1bSBmb3IKLSAqIEluZm9ybWF0aWNzIGFuZCBNYXRoZW1hdGljcywgS2VpbyBVbml2ZXJzaXR5KS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcwotICogd29yayBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDKHIpIFNvZnR3YXJlIExpY2Vuc2UgWzFdIGluIHRoZSBob3BlIHRoYXQKLSAqIGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZAotICogd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLgotICoKLSAqIFsxXSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLzIwMDIvY29weXJpZ2h0LXNvZnR3YXJlLTIwMDIxMjMxCi0gKi8KLQotcGFja2FnZSBvcmcudzNjLmRvbTsKLQotLyoqCi0gKiBET00gb3BlcmF0aW9ucyBvbmx5IHJhaXNlIGV4Y2VwdGlvbnMgaW4gImV4Y2VwdGlvbmFsIiBjaXJjdW1zdGFuY2VzLCBpLmUuLAotICogd2hlbiBhbiBvcGVyYXRpb24gaXMgaW1wb3NzaWJsZSB0byBwZXJmb3JtIChlaXRoZXIgZm9yIGxvZ2ljYWwgcmVhc29ucywKLSAqIGJlY2F1c2UgZGF0YSBpcyBsb3N0LCBvciBiZWNhdXNlIHRoZSBpbXBsZW1lbnRhdGlvbiBoYXMgYmVjb21lIHVuc3RhYmxlKS4KLSAqIEluIGdlbmVyYWwsIERPTSBtZXRob2RzIHJldHVybiBzcGVjaWZpYyBlcnJvciB2YWx1ZXMgaW4gb3JkaW5hcnkKLSAqIHByb2Nlc3Npbmcgc2l0dWF0aW9ucywgc3VjaCBhcyBvdXQtb2YtYm91bmQgZXJyb3JzIHdoZW4gdXNpbmcKLSAqIDxjb2RlPk5vZGVMaXN0PC9jb2RlPi4KLSAqIDxwPkltcGxlbWVudGF0aW9ucyBzaG91bGQgcmFpc2Ugb3RoZXIgZXhjZXB0aW9ucyB1bmRlciBvdGhlciBjaXJjdW1zdGFuY2VzLgotICogRm9yIGV4YW1wbGUsIGltcGxlbWVudGF0aW9ucyBzaG91bGQgcmFpc2UgYW4gaW1wbGVtZW50YXRpb24tZGVwZW5kZW50Ci0gKiBleGNlcHRpb24gaWYgYSA8Y29kZT5udWxsPC9jb2RlPiBhcmd1bWVudCBpcyBwYXNzZWQgd2hlbiA8Y29kZT5udWxsPC9jb2RlPgotICogIHdhcyBub3QgZXhwZWN0ZWQuCi0gKiA8cD5Tb21lIGxhbmd1YWdlcyBhbmQgb2JqZWN0IHN5c3RlbXMgZG8gbm90IHN1cHBvcnQgdGhlIGNvbmNlcHQgb2YKLSAqIGV4Y2VwdGlvbnMuIEZvciBzdWNoIHN5c3RlbXMsIGVycm9yIGNvbmRpdGlvbnMgbWF5IGJlIGluZGljYXRlZCB1c2luZwotICogbmF0aXZlIGVycm9yIHJlcG9ydGluZyBtZWNoYW5pc21zLiBGb3Igc29tZSBiaW5kaW5ncywgZm9yIGV4YW1wbGUsCi0gKiBtZXRob2RzIG1heSByZXR1cm4gZXJyb3IgY29kZXMgc2ltaWxhciB0byB0aG9zZSBsaXN0ZWQgaW4gdGhlCi0gKiBjb3JyZXNwb25kaW5nIG1ldGhvZCBkZXNjcmlwdGlvbnMuCi0gKiA8cD5TZWUgYWxzbyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMtRE9NLUxldmVsLTMtQ29yZS0yMDA0MDQwNyc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDMgQ29yZSBTcGVjaWZpY2F0aW9uPC9hPi4KLSAqLwotcHVibGljIGNsYXNzIERPTUV4Y2VwdGlvbiBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24gewotICAgIHB1YmxpYyBET01FeGNlcHRpb24oc2hvcnQgY29kZSwgU3RyaW5nIG1lc3NhZ2UpIHsKLSAgICAgICBzdXBlcihtZXNzYWdlKTsKLSAgICAgICB0aGlzLmNvZGUgPSBjb2RlOwotICAgIH0KLSAgICBwdWJsaWMgc2hvcnQgICBjb2RlOwotICAgIC8vIEV4Y2VwdGlvbkNvZGUKLSAgICAvKioKLSAgICAgKiBJZiBpbmRleCBvciBzaXplIGlzIG5lZ2F0aXZlLCBvciBncmVhdGVyIHRoYW4gdGhlIGFsbG93ZWQgdmFsdWUuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBJTkRFWF9TSVpFX0VSUiAgICAgICAgICAgID0gMTsKLSAgICAvKioKLSAgICAgKiBJZiB0aGUgc3BlY2lmaWVkIHJhbmdlIG9mIHRleHQgZG9lcyBub3QgZml0IGludG8gYQotICAgICAqIDxjb2RlPkRPTVN0cmluZzwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBET01TVFJJTkdfU0laRV9FUlIgICAgICAgID0gMjsKLSAgICAvKioKLSAgICAgKiBJZiBhbnkgPGNvZGU+Tm9kZTwvY29kZT4gaXMgaW5zZXJ0ZWQgc29tZXdoZXJlIGl0IGRvZXNuJ3QgYmVsb25nLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgSElFUkFSQ0hZX1JFUVVFU1RfRVJSICAgICA9IDM7Ci0gICAgLyoqCi0gICAgICogSWYgYSA8Y29kZT5Ob2RlPC9jb2RlPiBpcyB1c2VkIGluIGEgZGlmZmVyZW50IGRvY3VtZW50IHRoYW4gdGhlIG9uZQotICAgICAqIHRoYXQgY3JlYXRlZCBpdCAodGhhdCBkb2Vzbid0IHN1cHBvcnQgaXQpLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgV1JPTkdfRE9DVU1FTlRfRVJSICAgICAgICA9IDQ7Ci0gICAgLyoqCi0gICAgICogSWYgYW4gaW52YWxpZCBvciBpbGxlZ2FsIGNoYXJhY3RlciBpcyBzcGVjaWZpZWQsIHN1Y2ggYXMgaW4gYW4gWE1MIG5hbWUuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBJTlZBTElEX0NIQVJBQ1RFUl9FUlIgICAgID0gNTsKLSAgICAvKioKLSAgICAgKiBJZiBkYXRhIGlzIHNwZWNpZmllZCBmb3IgYSA8Y29kZT5Ob2RlPC9jb2RlPiB3aGljaCBkb2VzIG5vdCBzdXBwb3J0Ci0gICAgICogZGF0YS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IE5PX0RBVEFfQUxMT1dFRF9FUlIgICAgICAgPSA2OwotICAgIC8qKgotICAgICAqIElmIGFuIGF0dGVtcHQgaXMgbWFkZSB0byBtb2RpZnkgYW4gb2JqZWN0IHdoZXJlIG1vZGlmaWNhdGlvbnMgYXJlIG5vdAotICAgICAqIGFsbG93ZWQuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIgPSA3OwotICAgIC8qKgotICAgICAqIElmIGFuIGF0dGVtcHQgaXMgbWFkZSB0byByZWZlcmVuY2UgYSA8Y29kZT5Ob2RlPC9jb2RlPiBpbiBhIGNvbnRleHQKLSAgICAgKiB3aGVyZSBpdCBkb2VzIG5vdCBleGlzdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IE5PVF9GT1VORF9FUlIgICAgICAgICAgICAgPSA4OwotICAgIC8qKgotICAgICAqIElmIHRoZSBpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdCBzdXBwb3J0IHRoZSByZXF1ZXN0ZWQgdHlwZSBvZiBvYmplY3Qgb3IKLSAgICAgKiBvcGVyYXRpb24uCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBOT1RfU1VQUE9SVEVEX0VSUiAgICAgICAgID0gOTsKLSAgICAvKioKLSAgICAgKiBJZiBhbiBhdHRlbXB0IGlzIG1hZGUgdG8gYWRkIGFuIGF0dHJpYnV0ZSB0aGF0IGlzIGFscmVhZHkgaW4gdXNlCi0gICAgICogZWxzZXdoZXJlLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgSU5VU0VfQVRUUklCVVRFX0VSUiAgICAgICA9IDEwOwotICAgIC8qKgotICAgICAqIElmIGFuIGF0dGVtcHQgaXMgbWFkZSB0byB1c2UgYW4gb2JqZWN0IHRoYXQgaXMgbm90LCBvciBpcyBubyBsb25nZXIsCi0gICAgICogdXNhYmxlLgotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgSU5WQUxJRF9TVEFURV9FUlIgICAgICAgICA9IDExOwotICAgIC8qKgotICAgICAqIElmIGFuIGludmFsaWQgb3IgaWxsZWdhbCBzdHJpbmcgaXMgc3BlY2lmaWVkLgotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgU1lOVEFYX0VSUiAgICAgICAgICAgICAgICA9IDEyOwotICAgIC8qKgotICAgICAqIElmIGFuIGF0dGVtcHQgaXMgbWFkZSB0byBtb2RpZnkgdGhlIHR5cGUgb2YgdGhlIHVuZGVybHlpbmcgb2JqZWN0LgotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgSU5WQUxJRF9NT0RJRklDQVRJT05fRVJSICA9IDEzOwotICAgIC8qKgotICAgICAqIElmIGFuIGF0dGVtcHQgaXMgbWFkZSB0byBjcmVhdGUgb3IgY2hhbmdlIGFuIG9iamVjdCBpbiBhIHdheSB3aGljaCBpcwotICAgICAqIGluY29ycmVjdCB3aXRoIHJlZ2FyZCB0byBuYW1lc3BhY2VzLgotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgTkFNRVNQQUNFX0VSUiAgICAgICAgICAgICA9IDE0OwotICAgIC8qKgotICAgICAqIElmIGEgcGFyYW1ldGVyIG9yIGFuIG9wZXJhdGlvbiBpcyBub3Qgc3VwcG9ydGVkIGJ5IHRoZSB1bmRlcmx5aW5nCi0gICAgICogb2JqZWN0LgotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgSU5WQUxJRF9BQ0NFU1NfRVJSICAgICAgICA9IDE1OwotICAgIC8qKgotICAgICAqIElmIGEgY2FsbCB0byBhIG1ldGhvZCBzdWNoIGFzIDxjb2RlPmluc2VydEJlZm9yZTwvY29kZT4gb3IKLSAgICAgKiA8Y29kZT5yZW1vdmVDaGlsZDwvY29kZT4gd291bGQgbWFrZSB0aGUgPGNvZGU+Tm9kZTwvY29kZT4gaW52YWxpZAotICAgICAqIHdpdGggcmVzcGVjdCB0byAicGFydGlhbCB2YWxpZGl0eSIsIHRoaXMgZXhjZXB0aW9uIHdvdWxkIGJlIHJhaXNlZAotICAgICAqIGFuZCB0aGUgb3BlcmF0aW9uIHdvdWxkIG5vdCBiZSBkb25lLiBUaGlzIGNvZGUgaXMgdXNlZCBpbiBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMtRE9NLUxldmVsLTMtVmFsLTIwMDQwMTI3Lyc+RE9NIExldmVsIDMgVmFsaWRhdGlvbjwvYT5dCi0gICAgICogLiBSZWZlciB0byB0aGlzIHNwZWNpZmljYXRpb24gZm9yIGZ1cnRoZXIgaW5mb3JtYXRpb24uCi0gICAgICogQHNpbmNlIERPTSBMZXZlbCAzCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBWQUxJREFUSU9OX0VSUiAgICAgICAgICAgID0gMTY7Ci0gICAgLyoqCi0gICAgICogIElmIHRoZSB0eXBlIG9mIGFuIG9iamVjdCBpcyBpbmNvbXBhdGlibGUgd2l0aCB0aGUgZXhwZWN0ZWQgdHlwZSBvZiB0aGUKLSAgICAgKiBwYXJhbWV0ZXIgYXNzb2NpYXRlZCB0byB0aGUgb2JqZWN0LgotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgVFlQRV9NSVNNQVRDSF9FUlIgICAgICAgICA9IDE3OwotCi0gICAgLy8gQWRkZWQgc2VyaWFsVmVyc2lvblVJRCB0byBwcmVzZXJ2ZSBiaW5hcnkgY29tcGF0aWJpbGl0eQotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA2NjI3NzMyMzY2Nzk1OTY5OTE2TDsKLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvdzNjL2RvbS9ET01JbXBsZW1lbnRhdGlvbi5qYXZhIGIvc3JjL29yZy93M2MvZG9tL0RPTUltcGxlbWVudGF0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGFjZjc5ZmUuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy93M2MvZG9tL0RPTUltcGxlbWVudGF0aW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNjUgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIFRoaXMgZmlsZSBpcyBhdmFpbGFibGUgdW5kZXIgYW5kIGdvdmVybmVkIGJ5IHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKLSAqIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICogSG93ZXZlciwgdGhlIGZvbGxvd2luZyBub3RpY2UgYWNjb21wYW5pZWQgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcwotICogZmlsZSBhbmQsIHBlciBpdHMgdGVybXMsIHNob3VsZCBub3QgYmUgcmVtb3ZlZDoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKLSAqCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgRXVyb3BlYW4gUmVzZWFyY2ggQ29uc29ydGl1bSBmb3IKLSAqIEluZm9ybWF0aWNzIGFuZCBNYXRoZW1hdGljcywgS2VpbyBVbml2ZXJzaXR5KS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcwotICogd29yayBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDKHIpIFNvZnR3YXJlIExpY2Vuc2UgWzFdIGluIHRoZSBob3BlIHRoYXQKLSAqIGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZAotICogd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLgotICoKLSAqIFsxXSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLzIwMDIvY29weXJpZ2h0LXNvZnR3YXJlLTIwMDIxMjMxCi0gKi8KLQotcGFja2FnZSBvcmcudzNjLmRvbTsKLQotLyoqCi0gKiBUaGUgPGNvZGU+RE9NSW1wbGVtZW50YXRpb248L2NvZGU+IGludGVyZmFjZSBwcm92aWRlcyBhIG51bWJlciBvZiBtZXRob2RzCi0gKiBmb3IgcGVyZm9ybWluZyBvcGVyYXRpb25zIHRoYXQgYXJlIGluZGVwZW5kZW50IG9mIGFueSBwYXJ0aWN1bGFyIGluc3RhbmNlCi0gKiBvZiB0aGUgZG9jdW1lbnQgb2JqZWN0IG1vZGVsLgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLURPTS1MZXZlbC0zLUNvcmUtMjAwNDA0MDcnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAzIENvcmUgU3BlY2lmaWNhdGlvbjwvYT4uCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgRE9NSW1wbGVtZW50YXRpb24gewotICAgIC8qKgotICAgICAqIFRlc3QgaWYgdGhlIERPTSBpbXBsZW1lbnRhdGlvbiBpbXBsZW1lbnRzIGEgc3BlY2lmaWMgZmVhdHVyZSBhbmQKLSAgICAgKiB2ZXJzaW9uLCBhcyBzcGVjaWZpZWQgaW4gPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMtRE9NLUxldmVsLTMtQ29yZS0yMDA0MDQwNy9jb3JlLmh0bWwjRE9NRmVhdHVyZXMiPkRPTSBGZWF0dXJlczwvYT4uCi0gICAgICogQHBhcmFtIGZlYXR1cmUgIFRoZSBuYW1lIG9mIHRoZSBmZWF0dXJlIHRvIHRlc3QuCi0gICAgICogQHBhcmFtIHZlcnNpb24gIFRoaXMgaXMgdGhlIHZlcnNpb24gbnVtYmVyIG9mIHRoZSBmZWF0dXJlIHRvIHRlc3QuCi0gICAgICogQHJldHVybiA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgZmVhdHVyZSBpcyBpbXBsZW1lbnRlZCBpbiB0aGUKLSAgICAgKiAgIHNwZWNpZmllZCB2ZXJzaW9uLCA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGhhc0ZlYXR1cmUoU3RyaW5nIGZlYXR1cmUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdmVyc2lvbik7Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGVzIGFuIGVtcHR5IDxjb2RlPkRvY3VtZW50VHlwZTwvY29kZT4gbm9kZS4gRW50aXR5IGRlY2xhcmF0aW9ucwotICAgICAqIGFuZCBub3RhdGlvbnMgYXJlIG5vdCBtYWRlIGF2YWlsYWJsZS4gRW50aXR5IHJlZmVyZW5jZSBleHBhbnNpb25zIGFuZAotICAgICAqIGRlZmF1bHQgYXR0cmlidXRlIGFkZGl0aW9ucyBkbyBub3Qgb2NjdXIuLgotICAgICAqIEBwYXJhbSBxdWFsaWZpZWROYW1lIFRoZSBxdWFsaWZpZWQgbmFtZSBvZiB0aGUgZG9jdW1lbnQgdHlwZSB0byBiZQotICAgICAqICAgY3JlYXRlZC4KLSAgICAgKiBAcGFyYW0gcHVibGljSWQgVGhlIGV4dGVybmFsIHN1YnNldCBwdWJsaWMgaWRlbnRpZmllci4KLSAgICAgKiBAcGFyYW0gc3lzdGVtSWQgVGhlIGV4dGVybmFsIHN1YnNldCBzeXN0ZW0gaWRlbnRpZmllci4KLSAgICAgKiBAcmV0dXJuIEEgbmV3IDxjb2RlPkRvY3VtZW50VHlwZTwvY29kZT4gbm9kZSB3aXRoCi0gICAgICogICA8Y29kZT5Ob2RlLm93bmVyRG9jdW1lbnQ8L2NvZGU+IHNldCB0byA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgSU5WQUxJRF9DSEFSQUNURVJfRVJSOiBSYWlzZWQgaWYgdGhlIHNwZWNpZmllZCBxdWFsaWZpZWQgbmFtZSBpcyBub3QKLSAgICAgKiAgIGFuIFhNTCBuYW1lIGFjY29yZGluZyB0byBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMteG1sLTIwMDQwMjA0Jz5YTUwgMS4wPC9hPl0uCi0gICAgICogICA8YnI+TkFNRVNQQUNFX0VSUjogUmFpc2VkIGlmIHRoZSA8Y29kZT5xdWFsaWZpZWROYW1lPC9jb2RlPiBpcwotICAgICAqICAgbWFsZm9ybWVkLgotICAgICAqICAgPGJyPk5PVF9TVVBQT1JURURfRVJSOiBNYXkgYmUgcmFpc2VkIGlmIHRoZSBpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdAotICAgICAqICAgc3VwcG9ydCB0aGUgZmVhdHVyZSAiWE1MIiBhbmQgdGhlIGxhbmd1YWdlIGV4cG9zZWQgdGhyb3VnaCB0aGUKLSAgICAgKiAgIERvY3VtZW50IGRvZXMgbm90IHN1cHBvcnQgWE1MIE5hbWVzcGFjZXMgKHN1Y2ggYXMgWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzE5OTkvUkVDLWh0bWw0MDEtMTk5OTEyMjQvJz5IVE1MIDQuMDE8L2E+XSkuCi0gICAgICogQHNpbmNlIERPTSBMZXZlbCAyCi0gICAgICovCi0gICAgcHVibGljIERvY3VtZW50VHlwZSBjcmVhdGVEb2N1bWVudFR5cGUoU3RyaW5nIHF1YWxpZmllZE5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHB1YmxpY0lkLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBzeXN0ZW1JZCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlcyBhIERPTSBEb2N1bWVudCBvYmplY3Qgb2YgdGhlIHNwZWNpZmllZCB0eXBlIHdpdGggaXRzIGRvY3VtZW50Ci0gICAgICogZWxlbWVudC4KLSAgICAgKiA8YnI+Tm90ZSB0aGF0IGJhc2VkIG9uIHRoZSA8Y29kZT5Eb2N1bWVudFR5cGU8L2NvZGU+IGdpdmVuIHRvIGNyZWF0ZQotICAgICAqIHRoZSBkb2N1bWVudCwgdGhlIGltcGxlbWVudGF0aW9uIG1heSBpbnN0YW50aWF0ZSBzcGVjaWFsaXplZAotICAgICAqIDxjb2RlPkRvY3VtZW50PC9jb2RlPiBvYmplY3RzIHRoYXQgc3VwcG9ydCBhZGRpdGlvbmFsIGZlYXR1cmVzIHRoYW4KLSAgICAgKiB0aGUgIkNvcmUiLCBzdWNoIGFzICJIVE1MIiBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMy9SRUMtRE9NLUxldmVsLTItSFRNTC0yMDAzMDEwOSc+RE9NIExldmVsIDIgSFRNTDwvYT5dCi0gICAgICogLiBPbiB0aGUgb3RoZXIgaGFuZCwgc2V0dGluZyB0aGUgPGNvZGU+RG9jdW1lbnRUeXBlPC9jb2RlPiBhZnRlciB0aGUKLSAgICAgKiBkb2N1bWVudCB3YXMgY3JlYXRlZCBtYWtlcyB0aGlzIHZlcnkgdW5saWtlbHkgdG8gaGFwcGVuLgotICAgICAqIEFsdGVybmF0aXZlbHksIHNwZWNpYWxpemVkIDxjb2RlPkRvY3VtZW50PC9jb2RlPiBjcmVhdGlvbiBtZXRob2RzLAotICAgICAqIHN1Y2ggYXMgPGNvZGU+Y3JlYXRlSFRNTERvY3VtZW50PC9jb2RlPiBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMy9SRUMtRE9NLUxldmVsLTItSFRNTC0yMDAzMDEwOSc+RE9NIExldmVsIDIgSFRNTDwvYT5dCi0gICAgICogLCBjYW4gYmUgdXNlZCB0byBvYnRhaW4gc3BlY2lmaWMgdHlwZXMgb2YgPGNvZGU+RG9jdW1lbnQ8L2NvZGU+Ci0gICAgICogb2JqZWN0cy4KLSAgICAgKiBAcGFyYW0gbmFtZXNwYWNlVVJJIFRoZSBuYW1lc3BhY2UgVVJJIG9mIHRoZSBkb2N1bWVudCBlbGVtZW50IHRvCi0gICAgICogICBjcmVhdGUgb3IgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICogQHBhcmFtIHF1YWxpZmllZE5hbWUgVGhlIHF1YWxpZmllZCBuYW1lIG9mIHRoZSBkb2N1bWVudCBlbGVtZW50IHRvIGJlCi0gICAgICogICBjcmVhdGVkIG9yIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAqIEBwYXJhbSBkb2N0eXBlIFRoZSB0eXBlIG9mIGRvY3VtZW50IHRvIGJlIGNyZWF0ZWQgb3IgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICogICBXaGVuIDxjb2RlPmRvY3R5cGU8L2NvZGU+IGlzIG5vdCA8Y29kZT5udWxsPC9jb2RlPiwgaXRzCi0gICAgICogICA8Y29kZT5Ob2RlLm93bmVyRG9jdW1lbnQ8L2NvZGU+IGF0dHJpYnV0ZSBpcyBzZXQgdG8gdGhlIGRvY3VtZW50Ci0gICAgICogICBiZWluZyBjcmVhdGVkLgotICAgICAqIEByZXR1cm4gQSBuZXcgPGNvZGU+RG9jdW1lbnQ8L2NvZGU+IG9iamVjdCB3aXRoIGl0cyBkb2N1bWVudCBlbGVtZW50LgotICAgICAqICAgSWYgdGhlIDxjb2RlPk5hbWVzcGFjZVVSSTwvY29kZT4sIDxjb2RlPnF1YWxpZmllZE5hbWU8L2NvZGU+LCBhbmQKLSAgICAgKiAgIDxjb2RlPmRvY3R5cGU8L2NvZGU+IGFyZSA8Y29kZT5udWxsPC9jb2RlPiwgdGhlIHJldHVybmVkCi0gICAgICogICA8Y29kZT5Eb2N1bWVudDwvY29kZT4gaXMgZW1wdHkgd2l0aCBubyBkb2N1bWVudCBlbGVtZW50LgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBJTlZBTElEX0NIQVJBQ1RFUl9FUlI6IFJhaXNlZCBpZiB0aGUgc3BlY2lmaWVkIHF1YWxpZmllZCBuYW1lIGlzIG5vdAotICAgICAqICAgYW4gWE1MIG5hbWUgYWNjb3JkaW5nIHRvIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy14bWwtMjAwNDAyMDQnPlhNTCAxLjA8L2E+XS4KLSAgICAgKiAgIDxicj5OQU1FU1BBQ0VfRVJSOiBSYWlzZWQgaWYgdGhlIDxjb2RlPnF1YWxpZmllZE5hbWU8L2NvZGU+IGlzCi0gICAgICogICBtYWxmb3JtZWQsIGlmIHRoZSA8Y29kZT5xdWFsaWZpZWROYW1lPC9jb2RlPiBoYXMgYSBwcmVmaXggYW5kIHRoZQotICAgICAqICAgPGNvZGU+bmFtZXNwYWNlVVJJPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPiwgb3IgaWYgdGhlCi0gICAgICogICA8Y29kZT5xdWFsaWZpZWROYW1lPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPiBhbmQgdGhlCi0gICAgICogICA8Y29kZT5uYW1lc3BhY2VVUkk8L2NvZGU+IGlzIGRpZmZlcmVudCBmcm9tIDxjb2RlPm51bGw8L2NvZGU+LCBvcgotICAgICAqICAgaWYgdGhlIDxjb2RlPnF1YWxpZmllZE5hbWU8L2NvZGU+IGhhcyBhIHByZWZpeCB0aGF0IGlzICJ4bWwiIGFuZAotICAgICAqICAgdGhlIDxjb2RlPm5hbWVzcGFjZVVSSTwvY29kZT4gaXMgZGlmZmVyZW50IGZyb20gIjxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZSc+Ci0gICAgICogICBodHRwOi8vd3d3LnczLm9yZy9YTUwvMTk5OC9uYW1lc3BhY2U8L2E+IiBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMTk5OS9SRUMteG1sLW5hbWVzLTE5OTkwMTE0Lyc+WE1MIE5hbWVzcGFjZXM8L2E+XQotICAgICAqICAgLCBvciBpZiB0aGUgRE9NIGltcGxlbWVudGF0aW9uIGRvZXMgbm90IHN1cHBvcnQgdGhlCi0gICAgICogICA8Y29kZT4iWE1MIjwvY29kZT4gZmVhdHVyZSBidXQgYSBub24tbnVsbCBuYW1lc3BhY2UgVVJJIHdhcwotICAgICAqICAgcHJvdmlkZWQsIHNpbmNlIG5hbWVzcGFjZXMgd2VyZSBkZWZpbmVkIGJ5IFhNTC4KLSAgICAgKiAgIDxicj5XUk9OR19ET0NVTUVOVF9FUlI6IFJhaXNlZCBpZiA8Y29kZT5kb2N0eXBlPC9jb2RlPiBoYXMgYWxyZWFkeQotICAgICAqICAgYmVlbiB1c2VkIHdpdGggYSBkaWZmZXJlbnQgZG9jdW1lbnQgb3Igd2FzIGNyZWF0ZWQgZnJvbSBhIGRpZmZlcmVudAotICAgICAqICAgaW1wbGVtZW50YXRpb24uCi0gICAgICogICA8YnI+Tk9UX1NVUFBPUlRFRF9FUlI6IE1heSBiZSByYWlzZWQgaWYgdGhlIGltcGxlbWVudGF0aW9uIGRvZXMgbm90Ci0gICAgICogICBzdXBwb3J0IHRoZSBmZWF0dXJlICJYTUwiIGFuZCB0aGUgbGFuZ3VhZ2UgZXhwb3NlZCB0aHJvdWdoIHRoZQotICAgICAqICAgRG9jdW1lbnQgZG9lcyBub3Qgc3VwcG9ydCBYTUwgTmFtZXNwYWNlcyAoc3VjaCBhcyBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMTk5OS9SRUMtaHRtbDQwMS0xOTk5MTIyNC8nPkhUTUwgNC4wMTwvYT5dKS4KLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDIKLSAgICAgKi8KLSAgICBwdWJsaWMgRG9jdW1lbnQgY3JlYXRlRG9jdW1lbnQoU3RyaW5nIG5hbWVzcGFjZVVSSSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHF1YWxpZmllZE5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERvY3VtZW50VHlwZSBkb2N0eXBlKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogIFRoaXMgbWV0aG9kIHJldHVybnMgYSBzcGVjaWFsaXplZCBvYmplY3Qgd2hpY2ggaW1wbGVtZW50cyB0aGUKLSAgICAgKiBzcGVjaWFsaXplZCBBUElzIG9mIHRoZSBzcGVjaWZpZWQgZmVhdHVyZSBhbmQgdmVyc2lvbiwgYXMgc3BlY2lmaWVkCi0gICAgICogaW4gPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMtRE9NLUxldmVsLTMtQ29yZS0yMDA0MDQwNy9jb3JlLmh0bWwjRE9NRmVhdHVyZXMiPkRPTSBGZWF0dXJlczwvYT4uIFRoZSBzcGVjaWFsaXplZCBvYmplY3QgbWF5IGFsc28gYmUgb2J0YWluZWQgYnkgdXNpbmcKLSAgICAgKiBiaW5kaW5nLXNwZWNpZmljIGNhc3RpbmcgbWV0aG9kcyBidXQgaXMgbm90IG5lY2Vzc2FyaWx5IGV4cGVjdGVkIHRvLAotICAgICAqIGFzIGRpc2N1c3NlZCBpbiAuIFRoaXMgbWV0aG9kIGFsc28gYWxsb3cgdGhlIGltcGxlbWVudGF0aW9uIHRvCi0gICAgICogcHJvdmlkZSBzcGVjaWFsaXplZCBvYmplY3RzIHdoaWNoIGRvIG5vdCBzdXBwb3J0IHRoZQotICAgICAqIDxjb2RlPkRPTUltcGxlbWVudGF0aW9uPC9jb2RlPiBpbnRlcmZhY2UuCi0gICAgICogQHBhcmFtIGZlYXR1cmUgIFRoZSBuYW1lIG9mIHRoZSBmZWF0dXJlIHJlcXVlc3RlZC4gTm90ZSB0aGF0IGFueSBwbHVzCi0gICAgICogICBzaWduICIrIiBwcmVwZW5kZWQgdG8gdGhlIG5hbWUgb2YgdGhlIGZlYXR1cmUgd2lsbCBiZSBpZ25vcmVkIHNpbmNlCi0gICAgICogICBpdCBpcyBub3Qgc2lnbmlmaWNhbnQgaW4gdGhlIGNvbnRleHQgb2YgdGhpcyBtZXRob2QuCi0gICAgICogQHBhcmFtIHZlcnNpb24gIFRoaXMgaXMgdGhlIHZlcnNpb24gbnVtYmVyIG9mIHRoZSBmZWF0dXJlIHRvIHRlc3QuCi0gICAgICogQHJldHVybiAgUmV0dXJucyBhbiBvYmplY3Qgd2hpY2ggaW1wbGVtZW50cyB0aGUgc3BlY2lhbGl6ZWQgQVBJcyBvZgotICAgICAqICAgdGhlIHNwZWNpZmllZCBmZWF0dXJlIGFuZCB2ZXJzaW9uLCBpZiBhbnksIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmCi0gICAgICogICB0aGVyZSBpcyBubyBvYmplY3Qgd2hpY2ggaW1wbGVtZW50cyBpbnRlcmZhY2VzIGFzc29jaWF0ZWQgd2l0aCB0aGF0Ci0gICAgICogICBmZWF0dXJlLiBJZiB0aGUgPGNvZGU+RE9NT2JqZWN0PC9jb2RlPiByZXR1cm5lZCBieSB0aGlzIG1ldGhvZAotICAgICAqICAgaW1wbGVtZW50cyB0aGUgPGNvZGU+RE9NSW1wbGVtZW50YXRpb248L2NvZGU+IGludGVyZmFjZSwgaXQgbXVzdAotICAgICAqICAgZGVsZWdhdGUgdG8gdGhlIHByaW1hcnkgY29yZSA8Y29kZT5ET01JbXBsZW1lbnRhdGlvbjwvY29kZT4gYW5kIG5vdAotICAgICAqICAgcmV0dXJuIHJlc3VsdHMgaW5jb25zaXN0ZW50IHdpdGggdGhlIHByaW1hcnkgY29yZQotICAgICAqICAgPGNvZGU+RE9NSW1wbGVtZW50YXRpb248L2NvZGU+IHN1Y2ggYXMgPGNvZGU+aGFzRmVhdHVyZTwvY29kZT4sCi0gICAgICogICA8Y29kZT5nZXRGZWF0dXJlPC9jb2RlPiwgZXRjLgotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgICAqLwotICAgIHB1YmxpYyBPYmplY3QgZ2V0RmVhdHVyZShTdHJpbmcgZmVhdHVyZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHZlcnNpb24pOwotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL3czYy9kb20vRE9NSW1wbGVtZW50YXRpb25MaXN0LmphdmEgYi9zcmMvb3JnL3czYy9kb20vRE9NSW1wbGVtZW50YXRpb25MaXN0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGQ3NzEyZjIuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy93M2MvZG9tL0RPTUltcGxlbWVudGF0aW9uTGlzdC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNzIgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIFRoaXMgZmlsZSBpcyBhdmFpbGFibGUgdW5kZXIgYW5kIGdvdmVybmVkIGJ5IHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKLSAqIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICogSG93ZXZlciwgdGhlIGZvbGxvd2luZyBub3RpY2UgYWNjb21wYW5pZWQgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcwotICogZmlsZSBhbmQsIHBlciBpdHMgdGVybXMsIHNob3VsZCBub3QgYmUgcmVtb3ZlZDoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKLSAqCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgRXVyb3BlYW4gUmVzZWFyY2ggQ29uc29ydGl1bSBmb3IKLSAqIEluZm9ybWF0aWNzIGFuZCBNYXRoZW1hdGljcywgS2VpbyBVbml2ZXJzaXR5KS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcwotICogd29yayBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDKHIpIFNvZnR3YXJlIExpY2Vuc2UgWzFdIGluIHRoZSBob3BlIHRoYXQKLSAqIGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZAotICogd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLgotICoKLSAqIFsxXSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLzIwMDIvY29weXJpZ2h0LXNvZnR3YXJlLTIwMDIxMjMxCi0gKi8KLQotcGFja2FnZSBvcmcudzNjLmRvbTsKLQotLyoqCi0gKiAgVGhlIDxjb2RlPkRPTUltcGxlbWVudGF0aW9uTGlzdDwvY29kZT4gaW50ZXJmYWNlIHByb3ZpZGVzIHRoZSBhYnN0cmFjdGlvbgotICogb2YgYW4gb3JkZXJlZCBjb2xsZWN0aW9uIG9mIERPTSBpbXBsZW1lbnRhdGlvbnMsIHdpdGhvdXQgZGVmaW5pbmcgb3IKLSAqIGNvbnN0cmFpbmluZyBob3cgdGhpcyBjb2xsZWN0aW9uIGlzIGltcGxlbWVudGVkLiBUaGUgaXRlbXMgaW4gdGhlCi0gKiA8Y29kZT5ET01JbXBsZW1lbnRhdGlvbkxpc3Q8L2NvZGU+IGFyZSBhY2Nlc3NpYmxlIHZpYSBhbiBpbnRlZ3JhbCBpbmRleCwKLSAqIHN0YXJ0aW5nIGZyb20gMC4KLSAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy1ET00tTGV2ZWwtMy1Db3JlLTIwMDQwNDA3Jz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMyBDb3JlIFNwZWNpZmljYXRpb248L2E+LgotICogQHNpbmNlIERPTSBMZXZlbCAzCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgRE9NSW1wbGVtZW50YXRpb25MaXN0IHsKLSAgICAvKioKLSAgICAgKiAgUmV0dXJucyB0aGUgPGNvZGU+aW5kZXg8L2NvZGU+dGggaXRlbSBpbiB0aGUgY29sbGVjdGlvbi4gSWYKLSAgICAgKiA8Y29kZT5pbmRleDwvY29kZT4gaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHRoZSBudW1iZXIgb2YKLSAgICAgKiA8Y29kZT5ET01JbXBsZW1lbnRhdGlvbjwvY29kZT5zIGluIHRoZSBsaXN0LCB0aGlzIHJldHVybnMKLSAgICAgKiA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICAgKiBAcGFyYW0gaW5kZXggSW5kZXggaW50byB0aGUgY29sbGVjdGlvbi4KLSAgICAgKiBAcmV0dXJuICBUaGUgPGNvZGU+RE9NSW1wbGVtZW50YXRpb248L2NvZGU+IGF0IHRoZSA8Y29kZT5pbmRleDwvY29kZT4KLSAgICAgKiAgIHRoIHBvc2l0aW9uIGluIHRoZSA8Y29kZT5ET01JbXBsZW1lbnRhdGlvbkxpc3Q8L2NvZGU+LCBvcgotICAgICAqICAgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhhdCBpcyBub3QgYSB2YWxpZCBpbmRleC4KLSAgICAgKi8KLSAgICBwdWJsaWMgRE9NSW1wbGVtZW50YXRpb24gaXRlbShpbnQgaW5kZXgpOwotCi0gICAgLyoqCi0gICAgICogIFRoZSBudW1iZXIgb2YgPGNvZGU+RE9NSW1wbGVtZW50YXRpb248L2NvZGU+cyBpbiB0aGUgbGlzdC4gVGhlIHJhbmdlCi0gICAgICogb2YgdmFsaWQgY2hpbGQgbm9kZSBpbmRpY2VzIGlzIDAgdG8gPGNvZGU+bGVuZ3RoLTE8L2NvZGU+IGluY2x1c2l2ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldExlbmd0aCgpOwotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL3czYy9kb20vRE9NSW1wbGVtZW50YXRpb25Tb3VyY2UuamF2YSBiL3NyYy9vcmcvdzNjL2RvbS9ET01JbXBsZW1lbnRhdGlvblNvdXJjZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0MWFhMWFiLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS9ET01JbXBsZW1lbnRhdGlvblNvdXJjZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsODggKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIFRoaXMgZmlsZSBpcyBhdmFpbGFibGUgdW5kZXIgYW5kIGdvdmVybmVkIGJ5IHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKLSAqIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICogSG93ZXZlciwgdGhlIGZvbGxvd2luZyBub3RpY2UgYWNjb21wYW5pZWQgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcwotICogZmlsZSBhbmQsIHBlciBpdHMgdGVybXMsIHNob3VsZCBub3QgYmUgcmVtb3ZlZDoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKLSAqCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgRXVyb3BlYW4gUmVzZWFyY2ggQ29uc29ydGl1bSBmb3IKLSAqIEluZm9ybWF0aWNzIGFuZCBNYXRoZW1hdGljcywgS2VpbyBVbml2ZXJzaXR5KS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcwotICogd29yayBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDKHIpIFNvZnR3YXJlIExpY2Vuc2UgWzFdIGluIHRoZSBob3BlIHRoYXQKLSAqIGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZAotICogd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLgotICoKLSAqIFsxXSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLzIwMDIvY29weXJpZ2h0LXNvZnR3YXJlLTIwMDIxMjMxCi0gKi8KLQotcGFja2FnZSBvcmcudzNjLmRvbTsKLQotLyoqCi0gKiBUaGlzIGludGVyZmFjZSBwZXJtaXRzIGEgRE9NIGltcGxlbWVudGVyIHRvIHN1cHBseSBvbmUgb3IgbW9yZQotICogaW1wbGVtZW50YXRpb25zLCBiYXNlZCB1cG9uIHJlcXVlc3RlZCBmZWF0dXJlcyBhbmQgdmVyc2lvbnMsIGFzIHNwZWNpZmllZAotICogaW4gPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMtRE9NLUxldmVsLTMtQ29yZS0yMDA0MDQwNy9jb3JlLmh0bWwjRE9NRmVhdHVyZXMnPkRPTQotICogRmVhdHVyZXM8L2E+LiBFYWNoIGltcGxlbWVudGVkIDxjb2RlPkRPTUltcGxlbWVudGF0aW9uU291cmNlPC9jb2RlPiBvYmplY3QgaXMKLSAqIGxpc3RlZCBpbiB0aGUgYmluZGluZy1zcGVjaWZpYyBsaXN0IG9mIGF2YWlsYWJsZSBzb3VyY2VzIHNvIHRoYXQgaXRzCi0gKiA8Y29kZT5ET01JbXBsZW1lbnRhdGlvbjwvY29kZT4gb2JqZWN0cyBhcmUgbWFkZSBhdmFpbGFibGUuCi0gKiA8cD5TZWUgYWxzbyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMtRE9NLUxldmVsLTMtQ29yZS0yMDA0MDQwNyc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDMgQ29yZSBTcGVjaWZpY2F0aW9uPC9hPi4KLSAqIEBzaW5jZSBET00gTGV2ZWwgMwotICovCi1wdWJsaWMgaW50ZXJmYWNlIERPTUltcGxlbWVudGF0aW9uU291cmNlIHsKLSAgICAvKioKLSAgICAgKiAgQSBtZXRob2QgdG8gcmVxdWVzdCB0aGUgZmlyc3QgRE9NIGltcGxlbWVudGF0aW9uIHRoYXQgc3VwcG9ydHMgdGhlCi0gICAgICogc3BlY2lmaWVkIGZlYXR1cmVzLgotICAgICAqIEBwYXJhbSBmZWF0dXJlcyAgQSBzdHJpbmcgdGhhdCBzcGVjaWZpZXMgd2hpY2ggZmVhdHVyZXMgYW5kIHZlcnNpb25zCi0gICAgICogICBhcmUgcmVxdWlyZWQuIFRoaXMgaXMgYSBzcGFjZSBzZXBhcmF0ZWQgbGlzdCBpbiB3aGljaCBlYWNoIGZlYXR1cmUKLSAgICAgKiAgIGlzIHNwZWNpZmllZCBieSBpdHMgbmFtZSBvcHRpb25hbGx5IGZvbGxvd2VkIGJ5IGEgc3BhY2UgYW5kIGEKLSAgICAgKiAgIHZlcnNpb24gbnVtYmVyLiAgVGhpcyBtZXRob2QgcmV0dXJucyB0aGUgZmlyc3QgaXRlbSBvZiB0aGUgbGlzdAotICAgICAqICAgcmV0dXJuZWQgYnkgPGNvZGU+Z2V0RE9NSW1wbGVtZW50YXRpb25MaXN0PC9jb2RlPi4gIEFzIGFuIGV4YW1wbGUsCi0gICAgICogICB0aGUgc3RyaW5nIDxjb2RlPiJYTUwgMy4wIFRyYXZlcnNhbCArRXZlbnRzIDIuMCI8L2NvZGU+IHdpbGwKLSAgICAgKiAgIHJlcXVlc3QgYSBET00gaW1wbGVtZW50YXRpb24gdGhhdCBzdXBwb3J0cyB0aGUgbW9kdWxlICJYTUwiIGZvciBpdHMKLSAgICAgKiAgIDMuMCB2ZXJzaW9uLCBhIG1vZHVsZSB0aGF0IHN1cHBvcnQgb2YgdGhlICJUcmF2ZXJzYWwiIG1vZHVsZSBmb3IKLSAgICAgKiAgIGFueSB2ZXJzaW9uLCBhbmQgdGhlIG1vZHVsZSAiRXZlbnRzIiBmb3IgaXRzIDIuMCB2ZXJzaW9uLiBUaGUKLSAgICAgKiAgIG1vZHVsZSAiRXZlbnRzIiBtdXN0IGJlIGFjY2Vzc2libGUgdXNpbmcgdGhlIG1ldGhvZAotICAgICAqICAgPGNvZGU+Tm9kZS5nZXRGZWF0dXJlKCk8L2NvZGU+IGFuZAotICAgICAqICAgPGNvZGU+RE9NSW1wbGVtZW50YXRpb24uZ2V0RmVhdHVyZSgpPC9jb2RlPi4KLSAgICAgKiBAcmV0dXJuIFRoZSBmaXJzdCBET00gaW1wbGVtZW50YXRpb24gdGhhdCBzdXBwb3J0IHRoZSBkZXNpcmVkCi0gICAgICogICBmZWF0dXJlcywgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhpcyBzb3VyY2UgaGFzIG5vbmUuCi0gICAgICovCi0gICAgcHVibGljIERPTUltcGxlbWVudGF0aW9uIGdldERPTUltcGxlbWVudGF0aW9uKFN0cmluZyBmZWF0dXJlcyk7Ci0KLSAgICAvKioKLSAgICAgKiBBIG1ldGhvZCB0byByZXF1ZXN0IGEgbGlzdCBvZiBET00gaW1wbGVtZW50YXRpb25zIHRoYXQgc3VwcG9ydCB0aGUKLSAgICAgKiBzcGVjaWZpZWQgZmVhdHVyZXMgYW5kIHZlcnNpb25zLCBhcyBzcGVjaWZpZWQgaW4gLgotICAgICAqIEBwYXJhbSBmZWF0dXJlcyBBIHN0cmluZyB0aGF0IHNwZWNpZmllcyB3aGljaCBmZWF0dXJlcyBhbmQgdmVyc2lvbnMKLSAgICAgKiAgIGFyZSByZXF1aXJlZC4gVGhpcyBpcyBhIHNwYWNlIHNlcGFyYXRlZCBsaXN0IGluIHdoaWNoIGVhY2ggZmVhdHVyZQotICAgICAqICAgaXMgc3BlY2lmaWVkIGJ5IGl0cyBuYW1lIG9wdGlvbmFsbHkgZm9sbG93ZWQgYnkgYSBzcGFjZSBhbmQgYQotICAgICAqICAgdmVyc2lvbiBudW1iZXIuIFRoaXMgaXMgc29tZXRoaW5nIGxpa2U6ICJYTUwgMy4wIFRyYXZlcnNhbCArRXZlbnRzCi0gICAgICogICAyLjAiCi0gICAgICogQHJldHVybiBBIGxpc3Qgb2YgRE9NIGltcGxlbWVudGF0aW9ucyB0aGF0IHN1cHBvcnQgdGhlIGRlc2lyZWQKLSAgICAgKiAgIGZlYXR1cmVzLgotICAgICAqLwotICAgIHB1YmxpYyBET01JbXBsZW1lbnRhdGlvbkxpc3QgZ2V0RE9NSW1wbGVtZW50YXRpb25MaXN0KFN0cmluZyBmZWF0dXJlcyk7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvdzNjL2RvbS9ET01Mb2NhdG9yLmphdmEgYi9zcmMvb3JnL3czYy9kb20vRE9NTG9jYXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA5MTA0OTc2Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS9ET01Mb2NhdG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4NyArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogVGhpcyBmaWxlIGlzIGF2YWlsYWJsZSB1bmRlciBhbmQgZ292ZXJuZWQgYnkgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwotICogTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKiBIb3dldmVyLCB0aGUgZm9sbG93aW5nIG5vdGljZSBhY2NvbXBhbmllZCB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGlzCi0gKiBmaWxlIGFuZCwgcGVyIGl0cyB0ZXJtcywgc2hvdWxkIG5vdCBiZSByZW1vdmVkOgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAotICoKLSAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBFdXJvcGVhbiBSZXNlYXJjaCBDb25zb3J0aXVtIGZvcgotICogSW5mb3JtYXRpY3MgYW5kIE1hdGhlbWF0aWNzLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwgUmlnaHRzIFJlc2VydmVkLiBUaGlzCi0gKiB3b3JrIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MocikgU29mdHdhcmUgTGljZW5zZSBbMV0gaW4gdGhlIGhvcGUgdGhhdAotICogaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkCi0gKiB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuCi0gKgotICogWzFdIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvMjAwMi9jb3B5cmlnaHQtc29mdHdhcmUtMjAwMjEyMzEKLSAqLwotCi1wYWNrYWdlIG9yZy53M2MuZG9tOwotCi0vKioKLSAqIDxjb2RlPkRPTUxvY2F0b3I8L2NvZGU+IGlzIGFuIGludGVyZmFjZSB0aGF0IGRlc2NyaWJlcyBhIGxvY2F0aW9uIChlLmcuCi0gKiB3aGVyZSBhbiBlcnJvciBvY2N1cnJlZCkuCi0gKiA8cD5TZWUgYWxzbyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMtRE9NLUxldmVsLTMtQ29yZS0yMDA0MDQwNyc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDMgQ29yZSBTcGVjaWZpY2F0aW9uPC9hPi4KLSAqIEBzaW5jZSBET00gTGV2ZWwgMwotICovCi1wdWJsaWMgaW50ZXJmYWNlIERPTUxvY2F0b3IgewotICAgIC8qKgotICAgICAqIFRoZSBsaW5lIG51bWJlciB0aGlzIGxvY2F0b3IgaXMgcG9pbnRpbmcgdG8sIG9yIDxjb2RlPi0xPC9jb2RlPiBpZgotICAgICAqIHRoZXJlIGlzIG5vIGNvbHVtbiBudW1iZXIgYXZhaWxhYmxlLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0TGluZU51bWJlcigpOwotCi0gICAgLyoqCi0gICAgICogVGhlIGNvbHVtbiBudW1iZXIgdGhpcyBsb2NhdG9yIGlzIHBvaW50aW5nIHRvLCBvciA8Y29kZT4tMTwvY29kZT4gaWYKLSAgICAgKiB0aGVyZSBpcyBubyBjb2x1bW4gbnVtYmVyIGF2YWlsYWJsZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldENvbHVtbk51bWJlcigpOwotCi0gICAgLyoqCi0gICAgICogVGhlIGJ5dGUgb2Zmc2V0IGludG8gdGhlIGlucHV0IHNvdXJjZSB0aGlzIGxvY2F0b3IgaXMgcG9pbnRpbmcgdG8gb3IKLSAgICAgKiA8Y29kZT4tMTwvY29kZT4gaWYgdGhlcmUgaXMgbm8gYnl0ZSBvZmZzZXQgYXZhaWxhYmxlLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0Qnl0ZU9mZnNldCgpOwotCi0gICAgLyoqCi0gICAgICogVGhlIFVURi0xNiwgYXMgZGVmaW5lZCBpbiBbVW5pY29kZV0gYW5kIEFtZW5kbWVudCAxIG9mIFtJU08vSUVDIDEwNjQ2XSwgb2Zmc2V0IGludG8gdGhlIGlucHV0IHNvdXJjZSB0aGlzIGxvY2F0b3IgaXMgcG9pbnRpbmcgdG8gb3IKLSAgICAgKiA8Y29kZT4tMTwvY29kZT4gaWYgdGhlcmUgaXMgbm8gVVRGLTE2IG9mZnNldCBhdmFpbGFibGUuCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRVdGYxNk9mZnNldCgpOwotCi0gICAgLyoqCi0gICAgICogVGhlIG5vZGUgdGhpcyBsb2NhdG9yIGlzIHBvaW50aW5nIHRvLCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiBubyBub2RlCi0gICAgICogaXMgYXZhaWxhYmxlLgotICAgICAqLwotICAgIHB1YmxpYyBOb2RlIGdldFJlbGF0ZWROb2RlKCk7Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgVVJJIHRoaXMgbG9jYXRvciBpcyBwb2ludGluZyB0bywgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgbm8gVVJJIGlzCi0gICAgICogYXZhaWxhYmxlLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VXJpKCk7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvdzNjL2RvbS9ET01TdHJpbmdMaXN0LmphdmEgYi9zcmMvb3JnL3czYy9kb20vRE9NU3RyaW5nTGlzdC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2NzBiZGQwLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS9ET01TdHJpbmdMaXN0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3OSArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogVGhpcyBmaWxlIGlzIGF2YWlsYWJsZSB1bmRlciBhbmQgZ292ZXJuZWQgYnkgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwotICogTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKiBIb3dldmVyLCB0aGUgZm9sbG93aW5nIG5vdGljZSBhY2NvbXBhbmllZCB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGlzCi0gKiBmaWxlIGFuZCwgcGVyIGl0cyB0ZXJtcywgc2hvdWxkIG5vdCBiZSByZW1vdmVkOgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAotICoKLSAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBFdXJvcGVhbiBSZXNlYXJjaCBDb25zb3J0aXVtIGZvcgotICogSW5mb3JtYXRpY3MgYW5kIE1hdGhlbWF0aWNzLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwgUmlnaHRzIFJlc2VydmVkLiBUaGlzCi0gKiB3b3JrIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MocikgU29mdHdhcmUgTGljZW5zZSBbMV0gaW4gdGhlIGhvcGUgdGhhdAotICogaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkCi0gKiB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuCi0gKgotICogWzFdIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvMjAwMi9jb3B5cmlnaHQtc29mdHdhcmUtMjAwMjEyMzEKLSAqLwotCi1wYWNrYWdlIG9yZy53M2MuZG9tOwotCi0vKioKLSAqICBUaGUgPGNvZGU+RE9NU3RyaW5nTGlzdDwvY29kZT4gaW50ZXJmYWNlIHByb3ZpZGVzIHRoZSBhYnN0cmFjdGlvbiBvZiBhbgotICogb3JkZXJlZCBjb2xsZWN0aW9uIG9mIDxjb2RlPkRPTVN0cmluZzwvY29kZT4gdmFsdWVzLCB3aXRob3V0IGRlZmluaW5nIG9yCi0gKiBjb25zdHJhaW5pbmcgaG93IHRoaXMgY29sbGVjdGlvbiBpcyBpbXBsZW1lbnRlZC4gVGhlIGl0ZW1zIGluIHRoZQotICogPGNvZGU+RE9NU3RyaW5nTGlzdDwvY29kZT4gYXJlIGFjY2Vzc2libGUgdmlhIGFuIGludGVncmFsIGluZGV4LCBzdGFydGluZwotICogZnJvbSAwLgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLURPTS1MZXZlbC0zLUNvcmUtMjAwNDA0MDcnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAzIENvcmUgU3BlY2lmaWNhdGlvbjwvYT4uCi0gKiBAc2luY2UgRE9NIExldmVsIDMKLSAqLwotcHVibGljIGludGVyZmFjZSBET01TdHJpbmdMaXN0IHsKLSAgICAvKioKLSAgICAgKiAgUmV0dXJucyB0aGUgPGNvZGU+aW5kZXg8L2NvZGU+dGggaXRlbSBpbiB0aGUgY29sbGVjdGlvbi4gSWYKLSAgICAgKiA8Y29kZT5pbmRleDwvY29kZT4gaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHRoZSBudW1iZXIgb2YKLSAgICAgKiA8Y29kZT5ET01TdHJpbmc8L2NvZGU+cyBpbiB0aGUgbGlzdCwgdGhpcyByZXR1cm5zIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAqIEBwYXJhbSBpbmRleCBJbmRleCBpbnRvIHRoZSBjb2xsZWN0aW9uLgotICAgICAqIEByZXR1cm4gIFRoZSA8Y29kZT5ET01TdHJpbmc8L2NvZGU+IGF0IHRoZSA8Y29kZT5pbmRleDwvY29kZT50aAotICAgICAqICAgcG9zaXRpb24gaW4gdGhlIDxjb2RlPkRPTVN0cmluZ0xpc3Q8L2NvZGU+LCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZgotICAgICAqICAgdGhhdCBpcyBub3QgYSB2YWxpZCBpbmRleC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGl0ZW0oaW50IGluZGV4KTsKLQotICAgIC8qKgotICAgICAqIFRoZSBudW1iZXIgb2YgPGNvZGU+RE9NU3RyaW5nPC9jb2RlPnMgaW4gdGhlIGxpc3QuIFRoZSByYW5nZSBvZiB2YWxpZAotICAgICAqIGNoaWxkIG5vZGUgaW5kaWNlcyBpcyAwIHRvIDxjb2RlPmxlbmd0aC0xPC9jb2RlPiBpbmNsdXNpdmUuCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRMZW5ndGgoKTsKLQotICAgIC8qKgotICAgICAqICBUZXN0IGlmIGEgc3RyaW5nIGlzIHBhcnQgb2YgdGhpcyA8Y29kZT5ET01TdHJpbmdMaXN0PC9jb2RlPi4KLSAgICAgKiBAcGFyYW0gc3RyICBUaGUgc3RyaW5nIHRvIGxvb2sgZm9yLgotICAgICAqIEByZXR1cm4gIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBzdHJpbmcgaGFzIGJlZW4gZm91bmQsCi0gICAgICogICA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKFN0cmluZyBzdHIpOwotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL3czYy9kb20vRG9jdW1lbnQuamF2YSBiL3NyYy9vcmcvdzNjL2RvbS9Eb2N1bWVudC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1ZTQ4OWFjLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS9Eb2N1bWVudC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsODQ0ICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBUaGlzIGZpbGUgaXMgYXZhaWxhYmxlIHVuZGVyIGFuZCBnb3Zlcm5lZCBieSB0aGUgR05VIEdlbmVyYWwgUHVibGljCi0gKiBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqIEhvd2V2ZXIsIHRoZSBmb2xsb3dpbmcgbm90aWNlIGFjY29tcGFuaWVkIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIG9mIHRoaXMKLSAqIGZpbGUgYW5kLCBwZXIgaXRzIHRlcm1zLCBzaG91bGQgbm90IGJlIHJlbW92ZWQ6Ci0gKgotICogQ29weXJpZ2h0IChjKSAyMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCi0gKgotICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEV1cm9wZWFuIFJlc2VhcmNoIENvbnNvcnRpdW0gZm9yCi0gKiBJbmZvcm1hdGljcyBhbmQgTWF0aGVtYXRpY3MsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMKLSAqIHdvcmsgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQyhyKSBTb2Z0d2FyZSBMaWNlbnNlIFsxXSBpbiB0aGUgaG9wZSB0aGF0Ci0gKiBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQKLSAqIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4KLSAqCi0gKiBbMV0gaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8yMDAyL2NvcHlyaWdodC1zb2Z0d2FyZS0yMDAyMTIzMQotICovCi0KLXBhY2thZ2Ugb3JnLnczYy5kb207Ci0KLS8qKgotICogVGhlIDxjb2RlPkRvY3VtZW50PC9jb2RlPiBpbnRlcmZhY2UgcmVwcmVzZW50cyB0aGUgZW50aXJlIEhUTUwgb3IgWE1MCi0gKiBkb2N1bWVudC4gQ29uY2VwdHVhbGx5LCBpdCBpcyB0aGUgcm9vdCBvZiB0aGUgZG9jdW1lbnQgdHJlZSwgYW5kIHByb3ZpZGVzCi0gKiB0aGUgcHJpbWFyeSBhY2Nlc3MgdG8gdGhlIGRvY3VtZW50J3MgZGF0YS4KLSAqIDxwPlNpbmNlIGVsZW1lbnRzLCB0ZXh0IG5vZGVzLCBjb21tZW50cywgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbnMsIGV0Yy4KLSAqIGNhbm5vdCBleGlzdCBvdXRzaWRlIHRoZSBjb250ZXh0IG9mIGEgPGNvZGU+RG9jdW1lbnQ8L2NvZGU+LCB0aGUKLSAqIDxjb2RlPkRvY3VtZW50PC9jb2RlPiBpbnRlcmZhY2UgYWxzbyBjb250YWlucyB0aGUgZmFjdG9yeSBtZXRob2RzIG5lZWRlZAotICogdG8gY3JlYXRlIHRoZXNlIG9iamVjdHMuIFRoZSA8Y29kZT5Ob2RlPC9jb2RlPiBvYmplY3RzIGNyZWF0ZWQgaGF2ZSBhCi0gKiA8Y29kZT5vd25lckRvY3VtZW50PC9jb2RlPiBhdHRyaWJ1dGUgd2hpY2ggYXNzb2NpYXRlcyB0aGVtIHdpdGggdGhlCi0gKiA8Y29kZT5Eb2N1bWVudDwvY29kZT4gd2l0aGluIHdob3NlIGNvbnRleHQgdGhleSB3ZXJlIGNyZWF0ZWQuCi0gKiA8cD5TZWUgYWxzbyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMtRE9NLUxldmVsLTMtQ29yZS0yMDA0MDQwNyc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDMgQ29yZSBTcGVjaWZpY2F0aW9uPC9hPi4KLSAqLwotcHVibGljIGludGVyZmFjZSBEb2N1bWVudCBleHRlbmRzIE5vZGUgewotICAgIC8qKgotICAgICAqIFRoZSBEb2N1bWVudCBUeXBlIERlY2xhcmF0aW9uIChzZWUgPGNvZGU+RG9jdW1lbnRUeXBlPC9jb2RlPikKLSAgICAgKiBhc3NvY2lhdGVkIHdpdGggdGhpcyBkb2N1bWVudC4gRm9yIFhNTCBkb2N1bWVudHMgd2l0aG91dCBhIGRvY3VtZW50Ci0gICAgICogdHlwZSBkZWNsYXJhdGlvbiB0aGlzIHJldHVybnMgPGNvZGU+bnVsbDwvY29kZT4uIEZvciBIVE1MIGRvY3VtZW50cywKLSAgICAgKiBhIDxjb2RlPkRvY3VtZW50VHlwZTwvY29kZT4gb2JqZWN0IG1heSBiZSByZXR1cm5lZCwgaW5kZXBlbmRlbnRseSBvZgotICAgICAqIHRoZSBwcmVzZW5jZSBvciBhYnNlbmNlIG9mIGRvY3VtZW50IHR5cGUgZGVjbGFyYXRpb24gaW4gdGhlIEhUTUwKLSAgICAgKiBkb2N1bWVudC4KLSAgICAgKiA8YnI+VGhpcyBwcm92aWRlcyBkaXJlY3QgYWNjZXNzIHRvIHRoZSA8Y29kZT5Eb2N1bWVudFR5cGU8L2NvZGU+IG5vZGUsCi0gICAgICogY2hpbGQgbm9kZSBvZiB0aGlzIDxjb2RlPkRvY3VtZW50PC9jb2RlPi4gVGhpcyBub2RlIGNhbiBiZSBzZXQgYXQKLSAgICAgKiBkb2N1bWVudCBjcmVhdGlvbiB0aW1lIGFuZCBsYXRlciBjaGFuZ2VkIHRocm91Z2ggdGhlIHVzZSBvZiBjaGlsZAotICAgICAqIG5vZGVzIG1hbmlwdWxhdGlvbiBtZXRob2RzLCBzdWNoIGFzIDxjb2RlPk5vZGUuaW5zZXJ0QmVmb3JlPC9jb2RlPiwKLSAgICAgKiBvciA8Y29kZT5Ob2RlLnJlcGxhY2VDaGlsZDwvY29kZT4uIE5vdGUsIGhvd2V2ZXIsIHRoYXQgd2hpbGUgc29tZQotICAgICAqIGltcGxlbWVudGF0aW9ucyBtYXkgaW5zdGFudGlhdGUgZGlmZmVyZW50IHR5cGVzIG9mCi0gICAgICogPGNvZGU+RG9jdW1lbnQ8L2NvZGU+IG9iamVjdHMgc3VwcG9ydGluZyBhZGRpdGlvbmFsIGZlYXR1cmVzIHRoYW4gdGhlCi0gICAgICogIkNvcmUiLCBzdWNoIGFzICJIVE1MIiBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMy9SRUMtRE9NLUxldmVsLTItSFRNTC0yMDAzMDEwOSc+RE9NIExldmVsIDIgSFRNTDwvYT5dCi0gICAgICogLCBiYXNlZCBvbiB0aGUgPGNvZGU+RG9jdW1lbnRUeXBlPC9jb2RlPiBzcGVjaWZpZWQgYXQgY3JlYXRpb24gdGltZSwKLSAgICAgKiBjaGFuZ2luZyBpdCBhZnRlcndhcmRzIGlzIHZlcnkgdW5saWtlbHkgdG8gcmVzdWx0IGluIGEgY2hhbmdlIG9mIHRoZQotICAgICAqIGZlYXR1cmVzIHN1cHBvcnRlZC4KLSAgICAgKgotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgICAqLwotICAgIHB1YmxpYyBEb2N1bWVudFR5cGUgZ2V0RG9jdHlwZSgpOwotCi0gICAgLyoqCi0gICAgICogVGhlIDxjb2RlPkRPTUltcGxlbWVudGF0aW9uPC9jb2RlPiBvYmplY3QgdGhhdCBoYW5kbGVzIHRoaXMgZG9jdW1lbnQuIEEKLSAgICAgKiBET00gYXBwbGljYXRpb24gbWF5IHVzZSBvYmplY3RzIGZyb20gbXVsdGlwbGUgaW1wbGVtZW50YXRpb25zLgotICAgICAqLwotICAgIHB1YmxpYyBET01JbXBsZW1lbnRhdGlvbiBnZXRJbXBsZW1lbnRhdGlvbigpOwotCi0gICAgLyoqCi0gICAgICogVGhpcyBpcyBhIGNvbnZlbmllbmNlIGF0dHJpYnV0ZSB0aGF0IGFsbG93cyBkaXJlY3QgYWNjZXNzIHRvIHRoZSBjaGlsZAotICAgICAqIG5vZGUgdGhhdCBpcyB0aGUgZG9jdW1lbnQgZWxlbWVudCBvZiB0aGUgZG9jdW1lbnQuCi0gICAgICovCi0gICAgcHVibGljIEVsZW1lbnQgZ2V0RG9jdW1lbnRFbGVtZW50KCk7Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGVzIGFuIGVsZW1lbnQgb2YgdGhlIHR5cGUgc3BlY2lmaWVkLiBOb3RlIHRoYXQgdGhlIGluc3RhbmNlCi0gICAgICogcmV0dXJuZWQgaW1wbGVtZW50cyB0aGUgPGNvZGU+RWxlbWVudDwvY29kZT4gaW50ZXJmYWNlLCBzbyBhdHRyaWJ1dGVzCi0gICAgICogY2FuIGJlIHNwZWNpZmllZCBkaXJlY3RseSBvbiB0aGUgcmV0dXJuZWQgb2JqZWN0LgotICAgICAqIDxicj5JbiBhZGRpdGlvbiwgaWYgdGhlcmUgYXJlIGtub3duIGF0dHJpYnV0ZXMgd2l0aCBkZWZhdWx0IHZhbHVlcywKLSAgICAgKiA8Y29kZT5BdHRyPC9jb2RlPiBub2RlcyByZXByZXNlbnRpbmcgdGhlbSBhcmUgYXV0b21hdGljYWxseSBjcmVhdGVkCi0gICAgICogYW5kIGF0dGFjaGVkIHRvIHRoZSBlbGVtZW50LgotICAgICAqIDxicj5UbyBjcmVhdGUgYW4gZWxlbWVudCB3aXRoIGEgcXVhbGlmaWVkIG5hbWUgYW5kIG5hbWVzcGFjZSBVUkksIHVzZQotICAgICAqIHRoZSA8Y29kZT5jcmVhdGVFbGVtZW50TlM8L2NvZGU+IG1ldGhvZC4KLSAgICAgKiBAcGFyYW0gdGFnTmFtZSBUaGUgbmFtZSBvZiB0aGUgZWxlbWVudCB0eXBlIHRvIGluc3RhbnRpYXRlLiBGb3IgWE1MLAotICAgICAqICAgdGhpcyBpcyBjYXNlLXNlbnNpdGl2ZSwgb3RoZXJ3aXNlIGl0IGRlcGVuZHMgb24gdGhlCi0gICAgICogICBjYXNlLXNlbnNpdGl2aXR5IG9mIHRoZSBtYXJrdXAgbGFuZ3VhZ2UgaW4gdXNlLiBJbiB0aGF0IGNhc2UsIHRoZQotICAgICAqICAgbmFtZSBpcyBtYXBwZWQgdG8gdGhlIGNhbm9uaWNhbCBmb3JtIG9mIHRoYXQgbWFya3VwIGJ5IHRoZSBET00KLSAgICAgKiAgIGltcGxlbWVudGF0aW9uLgotICAgICAqIEByZXR1cm4gQSBuZXcgPGNvZGU+RWxlbWVudDwvY29kZT4gb2JqZWN0IHdpdGggdGhlCi0gICAgICogICA8Y29kZT5ub2RlTmFtZTwvY29kZT4gYXR0cmlidXRlIHNldCB0byA8Y29kZT50YWdOYW1lPC9jb2RlPiwgYW5kCi0gICAgICogICA8Y29kZT5sb2NhbE5hbWU8L2NvZGU+LCA8Y29kZT5wcmVmaXg8L2NvZGU+LCBhbmQKLSAgICAgKiAgIDxjb2RlPm5hbWVzcGFjZVVSSTwvY29kZT4gc2V0IHRvIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBJTlZBTElEX0NIQVJBQ1RFUl9FUlI6IFJhaXNlZCBpZiB0aGUgc3BlY2lmaWVkIG5hbWUgaXMgbm90IGFuIFhNTAotICAgICAqICAgbmFtZSBhY2NvcmRpbmcgdG8gdGhlIFhNTCB2ZXJzaW9uIGluIHVzZSBzcGVjaWZpZWQgaW4gdGhlCi0gICAgICogICA8Y29kZT5Eb2N1bWVudC54bWxWZXJzaW9uPC9jb2RlPiBhdHRyaWJ1dGUuCi0gICAgICovCi0gICAgcHVibGljIEVsZW1lbnQgY3JlYXRlRWxlbWVudChTdHJpbmcgdGFnTmFtZSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGVzIGFuIGVtcHR5IDxjb2RlPkRvY3VtZW50RnJhZ21lbnQ8L2NvZGU+IG9iamVjdC4KLSAgICAgKiBAcmV0dXJuIEEgbmV3IDxjb2RlPkRvY3VtZW50RnJhZ21lbnQ8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBEb2N1bWVudEZyYWdtZW50IGNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTsKLQotICAgIC8qKgotICAgICAqIENyZWF0ZXMgYSA8Y29kZT5UZXh0PC9jb2RlPiBub2RlIGdpdmVuIHRoZSBzcGVjaWZpZWQgc3RyaW5nLgotICAgICAqIEBwYXJhbSBkYXRhIFRoZSBkYXRhIGZvciB0aGUgbm9kZS4KLSAgICAgKiBAcmV0dXJuIFRoZSBuZXcgPGNvZGU+VGV4dDwvY29kZT4gb2JqZWN0LgotICAgICAqLwotICAgIHB1YmxpYyBUZXh0IGNyZWF0ZVRleHROb2RlKFN0cmluZyBkYXRhKTsKLQotICAgIC8qKgotICAgICAqIENyZWF0ZXMgYSA8Y29kZT5Db21tZW50PC9jb2RlPiBub2RlIGdpdmVuIHRoZSBzcGVjaWZpZWQgc3RyaW5nLgotICAgICAqIEBwYXJhbSBkYXRhIFRoZSBkYXRhIGZvciB0aGUgbm9kZS4KLSAgICAgKiBAcmV0dXJuIFRoZSBuZXcgPGNvZGU+Q29tbWVudDwvY29kZT4gb2JqZWN0LgotICAgICAqLwotICAgIHB1YmxpYyBDb21tZW50IGNyZWF0ZUNvbW1lbnQoU3RyaW5nIGRhdGEpOwotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlcyBhIDxjb2RlPkNEQVRBU2VjdGlvbjwvY29kZT4gbm9kZSB3aG9zZSB2YWx1ZSBpcyB0aGUgc3BlY2lmaWVkCi0gICAgICogc3RyaW5nLgotICAgICAqIEBwYXJhbSBkYXRhIFRoZSBkYXRhIGZvciB0aGUgPGNvZGU+Q0RBVEFTZWN0aW9uPC9jb2RlPiBjb250ZW50cy4KLSAgICAgKiBAcmV0dXJuIFRoZSBuZXcgPGNvZGU+Q0RBVEFTZWN0aW9uPC9jb2RlPiBvYmplY3QuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIE5PVF9TVVBQT1JURURfRVJSOiBSYWlzZWQgaWYgdGhpcyBkb2N1bWVudCBpcyBhbiBIVE1MIGRvY3VtZW50LgotICAgICAqLwotICAgIHB1YmxpYyBDREFUQVNlY3Rpb24gY3JlYXRlQ0RBVEFTZWN0aW9uKFN0cmluZyBkYXRhKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGVzIGEgPGNvZGU+UHJvY2Vzc2luZ0luc3RydWN0aW9uPC9jb2RlPiBub2RlIGdpdmVuIHRoZSBzcGVjaWZpZWQKLSAgICAgKiBuYW1lIGFuZCBkYXRhIHN0cmluZ3MuCi0gICAgICogQHBhcmFtIHRhcmdldCBUaGUgdGFyZ2V0IHBhcnQgb2YgdGhlIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24uVW5saWtlCi0gICAgICogICA8Y29kZT5Eb2N1bWVudC5jcmVhdGVFbGVtZW50TlM8L2NvZGU+IG9yCi0gICAgICogICA8Y29kZT5Eb2N1bWVudC5jcmVhdGVBdHRyaWJ1dGVOUzwvY29kZT4sIG5vIG5hbWVzcGFjZSB3ZWxsLWZvcm1lZAotICAgICAqICAgY2hlY2tpbmcgaXMgZG9uZSBvbiB0aGUgdGFyZ2V0IG5hbWUuIEFwcGxpY2F0aW9ucyBzaG91bGQgaW52b2tlCi0gICAgICogICA8Y29kZT5Eb2N1bWVudC5ub3JtYWxpemVEb2N1bWVudCgpPC9jb2RlPiB3aXRoIHRoZSBwYXJhbWV0ZXIgIgotICAgICAqICAgbmFtZXNwYWNlcyIgc2V0IHRvIDxjb2RlPnRydWU8L2NvZGU+IGluIG9yZGVyIHRvIGVuc3VyZSB0aGF0IHRoZQotICAgICAqICAgdGFyZ2V0IG5hbWUgaXMgbmFtZXNwYWNlIHdlbGwtZm9ybWVkLgotICAgICAqIEBwYXJhbSBkYXRhIFRoZSBkYXRhIGZvciB0aGUgbm9kZS4KLSAgICAgKiBAcmV0dXJuIFRoZSBuZXcgPGNvZGU+UHJvY2Vzc2luZ0luc3RydWN0aW9uPC9jb2RlPiBvYmplY3QuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIElOVkFMSURfQ0hBUkFDVEVSX0VSUjogUmFpc2VkIGlmIHRoZSBzcGVjaWZpZWQgdGFyZ2V0IGlzIG5vdCBhbiBYTUwKLSAgICAgKiAgIG5hbWUgYWNjb3JkaW5nIHRvIHRoZSBYTUwgdmVyc2lvbiBpbiB1c2Ugc3BlY2lmaWVkIGluIHRoZQotICAgICAqICAgPGNvZGU+RG9jdW1lbnQueG1sVmVyc2lvbjwvY29kZT4gYXR0cmlidXRlLgotICAgICAqICAgPGJyPk5PVF9TVVBQT1JURURfRVJSOiBSYWlzZWQgaWYgdGhpcyBkb2N1bWVudCBpcyBhbiBIVE1MIGRvY3VtZW50LgotICAgICAqLwotICAgIHB1YmxpYyBQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24gY3JlYXRlUHJvY2Vzc2luZ0luc3RydWN0aW9uKFN0cmluZyB0YXJnZXQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGRhdGEpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIENyZWF0ZXMgYW4gPGNvZGU+QXR0cjwvY29kZT4gb2YgdGhlIGdpdmVuIG5hbWUuIE5vdGUgdGhhdCB0aGUKLSAgICAgKiA8Y29kZT5BdHRyPC9jb2RlPiBpbnN0YW5jZSBjYW4gdGhlbiBiZSBzZXQgb24gYW4gPGNvZGU+RWxlbWVudDwvY29kZT4KLSAgICAgKiB1c2luZyB0aGUgPGNvZGU+c2V0QXR0cmlidXRlTm9kZTwvY29kZT4gbWV0aG9kLgotICAgICAqIDxicj5UbyBjcmVhdGUgYW4gYXR0cmlidXRlIHdpdGggYSBxdWFsaWZpZWQgbmFtZSBhbmQgbmFtZXNwYWNlIFVSSSwgdXNlCi0gICAgICogdGhlIDxjb2RlPmNyZWF0ZUF0dHJpYnV0ZU5TPC9jb2RlPiBtZXRob2QuCi0gICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgKiBAcmV0dXJuIEEgbmV3IDxjb2RlPkF0dHI8L2NvZGU+IG9iamVjdCB3aXRoIHRoZSA8Y29kZT5ub2RlTmFtZTwvY29kZT4KLSAgICAgKiAgIGF0dHJpYnV0ZSBzZXQgdG8gPGNvZGU+bmFtZTwvY29kZT4sIGFuZCA8Y29kZT5sb2NhbE5hbWU8L2NvZGU+LAotICAgICAqICAgPGNvZGU+cHJlZml4PC9jb2RlPiwgYW5kIDxjb2RlPm5hbWVzcGFjZVVSSTwvY29kZT4gc2V0IHRvCi0gICAgICogICA8Y29kZT5udWxsPC9jb2RlPi4gVGhlIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUgaXMgdGhlIGVtcHR5IHN0cmluZy4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgSU5WQUxJRF9DSEFSQUNURVJfRVJSOiBSYWlzZWQgaWYgdGhlIHNwZWNpZmllZCBuYW1lIGlzIG5vdCBhbiBYTUwKLSAgICAgKiAgIG5hbWUgYWNjb3JkaW5nIHRvIHRoZSBYTUwgdmVyc2lvbiBpbiB1c2Ugc3BlY2lmaWVkIGluIHRoZQotICAgICAqICAgPGNvZGU+RG9jdW1lbnQueG1sVmVyc2lvbjwvY29kZT4gYXR0cmlidXRlLgotICAgICAqLwotICAgIHB1YmxpYyBBdHRyIGNyZWF0ZUF0dHJpYnV0ZShTdHJpbmcgbmFtZSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIENyZWF0ZXMgYW4gPGNvZGU+RW50aXR5UmVmZXJlbmNlPC9jb2RlPiBvYmplY3QuIEluIGFkZGl0aW9uLCBpZiB0aGUKLSAgICAgKiByZWZlcmVuY2VkIGVudGl0eSBpcyBrbm93biwgdGhlIGNoaWxkIGxpc3Qgb2YgdGhlCi0gICAgICogPGNvZGU+RW50aXR5UmVmZXJlbmNlPC9jb2RlPiBub2RlIGlzIG1hZGUgdGhlIHNhbWUgYXMgdGhhdCBvZiB0aGUKLSAgICAgKiBjb3JyZXNwb25kaW5nIDxjb2RlPkVudGl0eTwvY29kZT4gbm9kZS4KLSAgICAgKiA8cCA+PGI+Tm90ZTo8L2I+IElmIGFueSBkZXNjZW5kYW50IG9mIHRoZSA8Y29kZT5FbnRpdHk8L2NvZGU+IG5vZGUgaGFzCi0gICAgICogYW4gdW5ib3VuZCBuYW1lc3BhY2UgcHJlZml4LCB0aGUgY29ycmVzcG9uZGluZyBkZXNjZW5kYW50IG9mIHRoZQotICAgICAqIGNyZWF0ZWQgPGNvZGU+RW50aXR5UmVmZXJlbmNlPC9jb2RlPiBub2RlIGlzIGFsc28gdW5ib3VuZDsgKGl0cwotICAgICAqIDxjb2RlPm5hbWVzcGFjZVVSSTwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4pLiBUaGUgRE9NIExldmVsIDIgYW5kCi0gICAgICogMyBkbyBub3Qgc3VwcG9ydCBhbnkgbWVjaGFuaXNtIHRvIHJlc29sdmUgbmFtZXNwYWNlIHByZWZpeGVzIGluIHRoaXMKLSAgICAgKiBjYXNlLgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBlbnRpdHkgdG8gcmVmZXJlbmNlLlVubGlrZQotICAgICAqICAgPGNvZGU+RG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TPC9jb2RlPiBvcgotICAgICAqICAgPGNvZGU+RG9jdW1lbnQuY3JlYXRlQXR0cmlidXRlTlM8L2NvZGU+LCBubyBuYW1lc3BhY2Ugd2VsbC1mb3JtZWQKLSAgICAgKiAgIGNoZWNraW5nIGlzIGRvbmUgb24gdGhlIGVudGl0eSBuYW1lLiBBcHBsaWNhdGlvbnMgc2hvdWxkIGludm9rZQotICAgICAqICAgPGNvZGU+RG9jdW1lbnQubm9ybWFsaXplRG9jdW1lbnQoKTwvY29kZT4gd2l0aCB0aGUgcGFyYW1ldGVyICIKLSAgICAgKiAgIG5hbWVzcGFjZXMiIHNldCB0byA8Y29kZT50cnVlPC9jb2RlPiBpbiBvcmRlciB0byBlbnN1cmUgdGhhdCB0aGUKLSAgICAgKiAgIGVudGl0eSBuYW1lIGlzIG5hbWVzcGFjZSB3ZWxsLWZvcm1lZC4KLSAgICAgKiBAcmV0dXJuIFRoZSBuZXcgPGNvZGU+RW50aXR5UmVmZXJlbmNlPC9jb2RlPiBvYmplY3QuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIElOVkFMSURfQ0hBUkFDVEVSX0VSUjogUmFpc2VkIGlmIHRoZSBzcGVjaWZpZWQgbmFtZSBpcyBub3QgYW4gWE1MCi0gICAgICogICBuYW1lIGFjY29yZGluZyB0byB0aGUgWE1MIHZlcnNpb24gaW4gdXNlIHNwZWNpZmllZCBpbiB0aGUKLSAgICAgKiAgIDxjb2RlPkRvY3VtZW50LnhtbFZlcnNpb248L2NvZGU+IGF0dHJpYnV0ZS4KLSAgICAgKiAgIDxicj5OT1RfU1VQUE9SVEVEX0VSUjogUmFpc2VkIGlmIHRoaXMgZG9jdW1lbnQgaXMgYW4gSFRNTCBkb2N1bWVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgRW50aXR5UmVmZXJlbmNlIGNyZWF0ZUVudGl0eVJlZmVyZW5jZShTdHJpbmcgbmFtZSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhIDxjb2RlPk5vZGVMaXN0PC9jb2RlPiBvZiBhbGwgdGhlIDxjb2RlPkVsZW1lbnRzPC9jb2RlPiBpbgotICAgICAqIGRvY3VtZW50IG9yZGVyIHdpdGggYSBnaXZlbiB0YWcgbmFtZSBhbmQgYXJlIGNvbnRhaW5lZCBpbiB0aGUKLSAgICAgKiBkb2N1bWVudC4KLSAgICAgKiBAcGFyYW0gdGFnbmFtZSAgVGhlIG5hbWUgb2YgdGhlIHRhZyB0byBtYXRjaCBvbi4gVGhlIHNwZWNpYWwgdmFsdWUgIioiCi0gICAgICogICBtYXRjaGVzIGFsbCB0YWdzLiBGb3IgWE1MLCB0aGUgPGNvZGU+dGFnbmFtZTwvY29kZT4gcGFyYW1ldGVyIGlzCi0gICAgICogICBjYXNlLXNlbnNpdGl2ZSwgb3RoZXJ3aXNlIGl0IGRlcGVuZHMgb24gdGhlIGNhc2Utc2Vuc2l0aXZpdHkgb2YgdGhlCi0gICAgICogICBtYXJrdXAgbGFuZ3VhZ2UgaW4gdXNlLgotICAgICAqIEByZXR1cm4gQSBuZXcgPGNvZGU+Tm9kZUxpc3Q8L2NvZGU+IG9iamVjdCBjb250YWluaW5nIGFsbCB0aGUgbWF0Y2hlZAotICAgICAqICAgPGNvZGU+RWxlbWVudHM8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBOb2RlTGlzdCBnZXRFbGVtZW50c0J5VGFnTmFtZShTdHJpbmcgdGFnbmFtZSk7Ci0KLSAgICAvKioKLSAgICAgKiBJbXBvcnRzIGEgbm9kZSBmcm9tIGFub3RoZXIgZG9jdW1lbnQgdG8gdGhpcyBkb2N1bWVudCwgd2l0aG91dCBhbHRlcmluZwotICAgICAqIG9yIHJlbW92aW5nIHRoZSBzb3VyY2Ugbm9kZSBmcm9tIHRoZSBvcmlnaW5hbCBkb2N1bWVudDsgdGhpcyBtZXRob2QKLSAgICAgKiBjcmVhdGVzIGEgbmV3IGNvcHkgb2YgdGhlIHNvdXJjZSBub2RlLiBUaGUgcmV0dXJuZWQgbm9kZSBoYXMgbm8KLSAgICAgKiBwYXJlbnQ7ICg8Y29kZT5wYXJlbnROb2RlPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPikuCi0gICAgICogPGJyPkZvciBhbGwgbm9kZXMsIGltcG9ydGluZyBhIG5vZGUgY3JlYXRlcyBhIG5vZGUgb2JqZWN0IG93bmVkIGJ5IHRoZQotICAgICAqIGltcG9ydGluZyBkb2N1bWVudCwgd2l0aCBhdHRyaWJ1dGUgdmFsdWVzIGlkZW50aWNhbCB0byB0aGUgc291cmNlCi0gICAgICogbm9kZSdzIDxjb2RlPm5vZGVOYW1lPC9jb2RlPiBhbmQgPGNvZGU+bm9kZVR5cGU8L2NvZGU+LCBwbHVzIHRoZQotICAgICAqIGF0dHJpYnV0ZXMgcmVsYXRlZCB0byBuYW1lc3BhY2VzICg8Y29kZT5wcmVmaXg8L2NvZGU+LAotICAgICAqIDxjb2RlPmxvY2FsTmFtZTwvY29kZT4sIGFuZCA8Y29kZT5uYW1lc3BhY2VVUkk8L2NvZGU+KS4gQXMgaW4gdGhlCi0gICAgICogPGNvZGU+Y2xvbmVOb2RlPC9jb2RlPiBvcGVyYXRpb24sIHRoZSBzb3VyY2Ugbm9kZSBpcyBub3QgYWx0ZXJlZC4KLSAgICAgKiBVc2VyIGRhdGEgYXNzb2NpYXRlZCB0byB0aGUgaW1wb3J0ZWQgbm9kZSBpcyBub3QgY2FycmllZCBvdmVyLgotICAgICAqIEhvd2V2ZXIsIGlmIGFueSA8Y29kZT5Vc2VyRGF0YUhhbmRsZXJzPC9jb2RlPiBoYXMgYmVlbiBzcGVjaWZpZWQKLSAgICAgKiBhbG9uZyB3aXRoIHRoZSBhc3NvY2lhdGVkIGRhdGEgdGhlc2UgaGFuZGxlcnMgd2lsbCBiZSBjYWxsZWQgd2l0aCB0aGUKLSAgICAgKiBhcHByb3ByaWF0ZSBwYXJhbWV0ZXJzIGJlZm9yZSB0aGlzIG1ldGhvZCByZXR1cm5zLgotICAgICAqIDxicj5BZGRpdGlvbmFsIGluZm9ybWF0aW9uIGlzIGNvcGllZCBhcyBhcHByb3ByaWF0ZSB0byB0aGUKLSAgICAgKiA8Y29kZT5ub2RlVHlwZTwvY29kZT4sIGF0dGVtcHRpbmcgdG8gbWlycm9yIHRoZSBiZWhhdmlvciBleHBlY3RlZCBpZgotICAgICAqIGEgZnJhZ21lbnQgb2YgWE1MIG9yIEhUTUwgc291cmNlIHdhcyBjb3BpZWQgZnJvbSBvbmUgZG9jdW1lbnQgdG8KLSAgICAgKiBhbm90aGVyLCByZWNvZ25pemluZyB0aGF0IHRoZSB0d28gZG9jdW1lbnRzIG1heSBoYXZlIGRpZmZlcmVudCBEVERzCi0gICAgICogaW4gdGhlIFhNTCBjYXNlLiBUaGUgZm9sbG93aW5nIGxpc3QgZGVzY3JpYmVzIHRoZSBzcGVjaWZpY3MgZm9yIGVhY2gKLSAgICAgKiB0eXBlIG9mIG5vZGUuCi0gICAgICogPGRsPgotICAgICAqIDxkdD5BVFRSSUJVVEVfTk9ERTwvZHQ+Ci0gICAgICogPGRkPlRoZSA8Y29kZT5vd25lckVsZW1lbnQ8L2NvZGU+IGF0dHJpYnV0ZQotICAgICAqIGlzIHNldCB0byA8Y29kZT5udWxsPC9jb2RlPiBhbmQgdGhlIDxjb2RlPnNwZWNpZmllZDwvY29kZT4gZmxhZyBpcwotICAgICAqIHNldCB0byA8Y29kZT50cnVlPC9jb2RlPiBvbiB0aGUgZ2VuZXJhdGVkIDxjb2RlPkF0dHI8L2NvZGU+LiBUaGUKLSAgICAgKiBkZXNjZW5kYW50cyBvZiB0aGUgc291cmNlIDxjb2RlPkF0dHI8L2NvZGU+IGFyZSByZWN1cnNpdmVseSBpbXBvcnRlZAotICAgICAqIGFuZCB0aGUgcmVzdWx0aW5nIG5vZGVzIHJlYXNzZW1ibGVkIHRvIGZvcm0gdGhlIGNvcnJlc3BvbmRpbmcgc3VidHJlZS4KLSAgICAgKiBOb3RlIHRoYXQgdGhlIDxjb2RlPmRlZXA8L2NvZGU+IHBhcmFtZXRlciBoYXMgbm8gZWZmZWN0IG9uCi0gICAgICogPGNvZGU+QXR0cjwvY29kZT4gbm9kZXM7IHRoZXkgYWx3YXlzIGNhcnJ5IHRoZWlyIGNoaWxkcmVuIHdpdGggdGhlbQotICAgICAqIHdoZW4gaW1wb3J0ZWQuPC9kZD4KLSAgICAgKiA8ZHQ+RE9DVU1FTlRfRlJBR01FTlRfTk9ERTwvZHQ+Ci0gICAgICogPGRkPklmIHRoZSA8Y29kZT5kZWVwPC9jb2RlPiBvcHRpb24KLSAgICAgKiB3YXMgc2V0IHRvIDxjb2RlPnRydWU8L2NvZGU+LCB0aGUgZGVzY2VuZGFudHMgb2YgdGhlIHNvdXJjZQotICAgICAqIDxjb2RlPkRvY3VtZW50RnJhZ21lbnQ8L2NvZGU+IGFyZSByZWN1cnNpdmVseSBpbXBvcnRlZCBhbmQgdGhlCi0gICAgICogcmVzdWx0aW5nIG5vZGVzIHJlYXNzZW1ibGVkIHVuZGVyIHRoZSBpbXBvcnRlZAotICAgICAqIDxjb2RlPkRvY3VtZW50RnJhZ21lbnQ8L2NvZGU+IHRvIGZvcm0gdGhlIGNvcnJlc3BvbmRpbmcgc3VidHJlZS4KLSAgICAgKiBPdGhlcndpc2UsIHRoaXMgc2ltcGx5IGdlbmVyYXRlcyBhbiBlbXB0eQotICAgICAqIDxjb2RlPkRvY3VtZW50RnJhZ21lbnQ8L2NvZGU+LjwvZGQ+Ci0gICAgICogPGR0PkRPQ1VNRU5UX05PREU8L2R0PgotICAgICAqIDxkZD48Y29kZT5Eb2N1bWVudDwvY29kZT4KLSAgICAgKiBub2RlcyBjYW5ub3QgYmUgaW1wb3J0ZWQuPC9kZD4KLSAgICAgKiA8ZHQ+RE9DVU1FTlRfVFlQRV9OT0RFPC9kdD4KLSAgICAgKiA8ZGQ+PGNvZGU+RG9jdW1lbnRUeXBlPC9jb2RlPgotICAgICAqIG5vZGVzIGNhbm5vdCBiZSBpbXBvcnRlZC48L2RkPgotICAgICAqIDxkdD5FTEVNRU5UX05PREU8L2R0PgotICAgICAqIDxkZD48ZW0+U3BlY2lmaWVkPC9lbT4gYXR0cmlidXRlIG5vZGVzIG9mIHRoZSBzb3VyY2UgZWxlbWVudCBhcmUgaW1wb3J0ZWQsIGFuZCB0aGUgZ2VuZXJhdGVkCi0gICAgICogPGNvZGU+QXR0cjwvY29kZT4gbm9kZXMgYXJlIGF0dGFjaGVkIHRvIHRoZSBnZW5lcmF0ZWQKLSAgICAgKiA8Y29kZT5FbGVtZW50PC9jb2RlPi4gRGVmYXVsdCBhdHRyaWJ1dGVzIGFyZSA8ZW0+bm90PC9lbT4gY29waWVkLCB0aG91Z2ggaWYgdGhlIGRvY3VtZW50IGJlaW5nIGltcG9ydGVkIGludG8gZGVmaW5lcyBkZWZhdWx0Ci0gICAgICogYXR0cmlidXRlcyBmb3IgdGhpcyBlbGVtZW50IG5hbWUsIHRob3NlIGFyZSBhc3NpZ25lZC4gSWYgdGhlCi0gICAgICogPGNvZGU+aW1wb3J0Tm9kZTwvY29kZT4gPGNvZGU+ZGVlcDwvY29kZT4gcGFyYW1ldGVyIHdhcyBzZXQgdG8KLSAgICAgKiA8Y29kZT50cnVlPC9jb2RlPiwgdGhlIGRlc2NlbmRhbnRzIG9mIHRoZSBzb3VyY2UgZWxlbWVudCBhcmUKLSAgICAgKiByZWN1cnNpdmVseSBpbXBvcnRlZCBhbmQgdGhlIHJlc3VsdGluZyBub2RlcyByZWFzc2VtYmxlZCB0byBmb3JtIHRoZQotICAgICAqIGNvcnJlc3BvbmRpbmcgc3VidHJlZS48L2RkPgotICAgICAqIDxkdD5FTlRJVFlfTk9ERTwvZHQ+Ci0gICAgICogPGRkPjxjb2RlPkVudGl0eTwvY29kZT4gbm9kZXMgY2FuIGJlCi0gICAgICogaW1wb3J0ZWQsIGhvd2V2ZXIgaW4gdGhlIGN1cnJlbnQgcmVsZWFzZSBvZiB0aGUgRE9NIHRoZQotICAgICAqIDxjb2RlPkRvY3VtZW50VHlwZTwvY29kZT4gaXMgcmVhZG9ubHkuIEFiaWxpdHkgdG8gYWRkIHRoZXNlIGltcG9ydGVkCi0gICAgICogbm9kZXMgdG8gYSA8Y29kZT5Eb2N1bWVudFR5cGU8L2NvZGU+IHdpbGwgYmUgY29uc2lkZXJlZCBmb3IgYWRkaXRpb24KLSAgICAgKiB0byBhIGZ1dHVyZSByZWxlYXNlIG9mIHRoZSBET00uT24gaW1wb3J0LCB0aGUgPGNvZGU+cHVibGljSWQ8L2NvZGU+LAotICAgICAqIDxjb2RlPnN5c3RlbUlkPC9jb2RlPiwgYW5kIDxjb2RlPm5vdGF0aW9uTmFtZTwvY29kZT4gYXR0cmlidXRlcyBhcmUKLSAgICAgKiBjb3BpZWQuIElmIGEgPGNvZGU+ZGVlcDwvY29kZT4gaW1wb3J0IGlzIHJlcXVlc3RlZCwgdGhlIGRlc2NlbmRhbnRzCi0gICAgICogb2YgdGhlIHRoZSBzb3VyY2UgPGNvZGU+RW50aXR5PC9jb2RlPiBhcmUgcmVjdXJzaXZlbHkgaW1wb3J0ZWQgYW5kCi0gICAgICogdGhlIHJlc3VsdGluZyBub2RlcyByZWFzc2VtYmxlZCB0byBmb3JtIHRoZSBjb3JyZXNwb25kaW5nIHN1YnRyZWUuPC9kZD4KLSAgICAgKiA8ZHQ+Ci0gICAgICogRU5USVRZX1JFRkVSRU5DRV9OT0RFPC9kdD4KLSAgICAgKiA8ZGQ+T25seSB0aGUgPGNvZGU+RW50aXR5UmVmZXJlbmNlPC9jb2RlPiBpdHNlbGYgaXMKLSAgICAgKiBjb3BpZWQsIGV2ZW4gaWYgYSA8Y29kZT5kZWVwPC9jb2RlPiBpbXBvcnQgaXMgcmVxdWVzdGVkLCBzaW5jZSB0aGUKLSAgICAgKiBzb3VyY2UgYW5kIGRlc3RpbmF0aW9uIGRvY3VtZW50cyBtaWdodCBoYXZlIGRlZmluZWQgdGhlIGVudGl0eQotICAgICAqIGRpZmZlcmVudGx5LiBJZiB0aGUgZG9jdW1lbnQgYmVpbmcgaW1wb3J0ZWQgaW50byBwcm92aWRlcyBhCi0gICAgICogZGVmaW5pdGlvbiBmb3IgdGhpcyBlbnRpdHkgbmFtZSwgaXRzIHZhbHVlIGlzIGFzc2lnbmVkLjwvZGQ+Ci0gICAgICogPGR0Pk5PVEFUSU9OX05PREU8L2R0PgotICAgICAqIDxkZD4KLSAgICAgKiA8Y29kZT5Ob3RhdGlvbjwvY29kZT4gbm9kZXMgY2FuIGJlIGltcG9ydGVkLCBob3dldmVyIGluIHRoZSBjdXJyZW50Ci0gICAgICogcmVsZWFzZSBvZiB0aGUgRE9NIHRoZSA8Y29kZT5Eb2N1bWVudFR5cGU8L2NvZGU+IGlzIHJlYWRvbmx5LiBBYmlsaXR5Ci0gICAgICogdG8gYWRkIHRoZXNlIGltcG9ydGVkIG5vZGVzIHRvIGEgPGNvZGU+RG9jdW1lbnRUeXBlPC9jb2RlPiB3aWxsIGJlCi0gICAgICogY29uc2lkZXJlZCBmb3IgYWRkaXRpb24gdG8gYSBmdXR1cmUgcmVsZWFzZSBvZiB0aGUgRE9NLk9uIGltcG9ydCwgdGhlCi0gICAgICogPGNvZGU+cHVibGljSWQ8L2NvZGU+IGFuZCA8Y29kZT5zeXN0ZW1JZDwvY29kZT4gYXR0cmlidXRlcyBhcmUgY29waWVkLgotICAgICAqIE5vdGUgdGhhdCB0aGUgPGNvZGU+ZGVlcDwvY29kZT4gcGFyYW1ldGVyIGhhcyBubyBlZmZlY3Qgb24gdGhpcyB0eXBlCi0gICAgICogb2Ygbm9kZXMgc2luY2UgdGhleSBjYW5ub3QgaGF2ZSBhbnkgY2hpbGRyZW4uPC9kZD4KLSAgICAgKiA8ZHQ+Ci0gICAgICogUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFPC9kdD4KLSAgICAgKiA8ZGQ+VGhlIGltcG9ydGVkIG5vZGUgY29waWVzIGl0cwotICAgICAqIDxjb2RlPnRhcmdldDwvY29kZT4gYW5kIDxjb2RlPmRhdGE8L2NvZGU+IHZhbHVlcyBmcm9tIHRob3NlIG9mIHRoZQotICAgICAqIHNvdXJjZSBub2RlLk5vdGUgdGhhdCB0aGUgPGNvZGU+ZGVlcDwvY29kZT4gcGFyYW1ldGVyIGhhcyBubyBlZmZlY3QKLSAgICAgKiBvbiB0aGlzIHR5cGUgb2Ygbm9kZXMgc2luY2UgdGhleSBjYW5ub3QgaGF2ZSBhbnkgY2hpbGRyZW4uPC9kZD4KLSAgICAgKiA8ZHQ+VEVYVF9OT0RFLAotICAgICAqIENEQVRBX1NFQ1RJT05fTk9ERSwgQ09NTUVOVF9OT0RFPC9kdD4KLSAgICAgKiA8ZGQ+VGhlc2UgdGhyZWUgdHlwZXMgb2Ygbm9kZXMgaW5oZXJpdGluZwotICAgICAqIGZyb20gPGNvZGU+Q2hhcmFjdGVyRGF0YTwvY29kZT4gY29weSB0aGVpciA8Y29kZT5kYXRhPC9jb2RlPiBhbmQKLSAgICAgKiA8Y29kZT5sZW5ndGg8L2NvZGU+IGF0dHJpYnV0ZXMgZnJvbSB0aG9zZSBvZiB0aGUgc291cmNlIG5vZGUuTm90ZQotICAgICAqIHRoYXQgdGhlIDxjb2RlPmRlZXA8L2NvZGU+IHBhcmFtZXRlciBoYXMgbm8gZWZmZWN0IG9uIHRoZXNlIHR5cGVzIG9mCi0gICAgICogbm9kZXMgc2luY2UgdGhleSBjYW5ub3QgaGF2ZSBhbnkgY2hpbGRyZW4uPC9kZD4KLSAgICAgKiA8L2RsPgotICAgICAqIEBwYXJhbSBpbXBvcnRlZE5vZGUgVGhlIG5vZGUgdG8gaW1wb3J0LgotICAgICAqIEBwYXJhbSBkZWVwIElmIDxjb2RlPnRydWU8L2NvZGU+LCByZWN1cnNpdmVseSBpbXBvcnQgdGhlIHN1YnRyZWUgdW5kZXIKLSAgICAgKiAgIHRoZSBzcGVjaWZpZWQgbm9kZTsgaWYgPGNvZGU+ZmFsc2U8L2NvZGU+LCBpbXBvcnQgb25seSB0aGUgbm9kZQotICAgICAqICAgaXRzZWxmLCBhcyBleHBsYWluZWQgYWJvdmUuIFRoaXMgaGFzIG5vIGVmZmVjdCBvbiBub2RlcyB0aGF0IGNhbm5vdAotICAgICAqICAgaGF2ZSBhbnkgY2hpbGRyZW4sIGFuZCBvbiA8Y29kZT5BdHRyPC9jb2RlPiwgYW5kCi0gICAgICogICA8Y29kZT5FbnRpdHlSZWZlcmVuY2U8L2NvZGU+IG5vZGVzLgotICAgICAqIEByZXR1cm4gVGhlIGltcG9ydGVkIG5vZGUgdGhhdCBiZWxvbmdzIHRvIHRoaXMgPGNvZGU+RG9jdW1lbnQ8L2NvZGU+LgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBOT1RfU1VQUE9SVEVEX0VSUjogUmFpc2VkIGlmIHRoZSB0eXBlIG9mIG5vZGUgYmVpbmcgaW1wb3J0ZWQgaXMgbm90Ci0gICAgICogICBzdXBwb3J0ZWQuCi0gICAgICogICA8YnI+SU5WQUxJRF9DSEFSQUNURVJfRVJSOiBSYWlzZWQgaWYgb25lIG9mIHRoZSBpbXBvcnRlZCBuYW1lcyBpcyBub3QKLSAgICAgKiAgIGFuIFhNTCBuYW1lIGFjY29yZGluZyB0byB0aGUgWE1MIHZlcnNpb24gaW4gdXNlIHNwZWNpZmllZCBpbiB0aGUKLSAgICAgKiAgIDxjb2RlPkRvY3VtZW50LnhtbFZlcnNpb248L2NvZGU+IGF0dHJpYnV0ZS4gVGhpcyBtYXkgaGFwcGVuIHdoZW4KLSAgICAgKiAgIGltcG9ydGluZyBhbiBYTUwgMS4xIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy14bWwxMS0yMDA0MDIwNC8nPlhNTCAxLjE8L2E+XSBlbGVtZW50Ci0gICAgICogICBpbnRvIGFuIFhNTCAxLjAgZG9jdW1lbnQsIGZvciBpbnN0YW5jZS4KLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDIKLSAgICAgKi8KLSAgICBwdWJsaWMgTm9kZSBpbXBvcnROb2RlKE5vZGUgaW1wb3J0ZWROb2RlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBkZWVwKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIENyZWF0ZXMgYW4gZWxlbWVudCBvZiB0aGUgZ2l2ZW4gcXVhbGlmaWVkIG5hbWUgYW5kIG5hbWVzcGFjZSBVUkkuCi0gICAgICogPGJyPlBlciBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMTk5OS9SRUMteG1sLW5hbWVzLTE5OTkwMTE0Lyc+WE1MIE5hbWVzcGFjZXM8L2E+XQotICAgICAqICwgYXBwbGljYXRpb25zIG11c3QgdXNlIHRoZSB2YWx1ZSA8Y29kZT5udWxsPC9jb2RlPiBhcyB0aGUKLSAgICAgKiBuYW1lc3BhY2VVUkkgcGFyYW1ldGVyIGZvciBtZXRob2RzIGlmIHRoZXkgd2lzaCB0byBoYXZlIG5vIG5hbWVzcGFjZS4KLSAgICAgKiBAcGFyYW0gbmFtZXNwYWNlVVJJIFRoZSBuYW1lc3BhY2UgVVJJIG9mIHRoZSBlbGVtZW50IHRvIGNyZWF0ZS4KLSAgICAgKiBAcGFyYW0gcXVhbGlmaWVkTmFtZSBUaGUgcXVhbGlmaWVkIG5hbWUgb2YgdGhlIGVsZW1lbnQgdHlwZSB0bwotICAgICAqICAgaW5zdGFudGlhdGUuCi0gICAgICogQHJldHVybiBBIG5ldyA8Y29kZT5FbGVtZW50PC9jb2RlPiBvYmplY3Qgd2l0aCB0aGUgZm9sbG93aW5nCi0gICAgICogICBhdHRyaWJ1dGVzOgotICAgICAqIDx0YWJsZSBib3JkZXI9JzEnIGNlbGxwYWRkaW5nPSczJz4KLSAgICAgKiA8dHI+Ci0gICAgICogPHRoPkF0dHJpYnV0ZTwvdGg+Ci0gICAgICogPHRoPlZhbHVlPC90aD4KLSAgICAgKiA8L3RyPgotICAgICAqIDx0cj4KLSAgICAgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPjxjb2RlPk5vZGUubm9kZU5hbWU8L2NvZGU+PC90ZD4KLSAgICAgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPgotICAgICAqICAgPGNvZGU+cXVhbGlmaWVkTmFtZTwvY29kZT48L3RkPgotICAgICAqIDwvdHI+Ci0gICAgICogPHRyPgotICAgICAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+PGNvZGU+Tm9kZS5uYW1lc3BhY2VVUkk8L2NvZGU+PC90ZD4KLSAgICAgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPgotICAgICAqICAgPGNvZGU+bmFtZXNwYWNlVVJJPC9jb2RlPjwvdGQ+Ci0gICAgICogPC90cj4KLSAgICAgKiA8dHI+Ci0gICAgICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz48Y29kZT5Ob2RlLnByZWZpeDwvY29kZT48L3RkPgotICAgICAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+cHJlZml4LCBleHRyYWN0ZWQKLSAgICAgKiAgIGZyb20gPGNvZGU+cXVhbGlmaWVkTmFtZTwvY29kZT4sIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoZXJlIGlzCi0gICAgICogICBubyBwcmVmaXg8L3RkPgotICAgICAqIDwvdHI+Ci0gICAgICogPHRyPgotICAgICAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+PGNvZGU+Tm9kZS5sb2NhbE5hbWU8L2NvZGU+PC90ZD4KLSAgICAgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPmxvY2FsIG5hbWUsIGV4dHJhY3RlZCBmcm9tCi0gICAgICogICA8Y29kZT5xdWFsaWZpZWROYW1lPC9jb2RlPjwvdGQ+Ci0gICAgICogPC90cj4KLSAgICAgKiA8dHI+Ci0gICAgICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz48Y29kZT5FbGVtZW50LnRhZ05hbWU8L2NvZGU+PC90ZD4KLSAgICAgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPgotICAgICAqICAgPGNvZGU+cXVhbGlmaWVkTmFtZTwvY29kZT48L3RkPgotICAgICAqIDwvdHI+Ci0gICAgICogPC90YWJsZT4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgSU5WQUxJRF9DSEFSQUNURVJfRVJSOiBSYWlzZWQgaWYgdGhlIHNwZWNpZmllZAotICAgICAqICAgPGNvZGU+cXVhbGlmaWVkTmFtZTwvY29kZT4gaXMgbm90IGFuIFhNTCBuYW1lIGFjY29yZGluZyB0byB0aGUgWE1MCi0gICAgICogICB2ZXJzaW9uIGluIHVzZSBzcGVjaWZpZWQgaW4gdGhlIDxjb2RlPkRvY3VtZW50LnhtbFZlcnNpb248L2NvZGU+Ci0gICAgICogICBhdHRyaWJ1dGUuCi0gICAgICogICA8YnI+TkFNRVNQQUNFX0VSUjogUmFpc2VkIGlmIHRoZSA8Y29kZT5xdWFsaWZpZWROYW1lPC9jb2RlPiBpcyBhCi0gICAgICogICBtYWxmb3JtZWQgcXVhbGlmaWVkIG5hbWUsIGlmIHRoZSA8Y29kZT5xdWFsaWZpZWROYW1lPC9jb2RlPiBoYXMgYQotICAgICAqICAgcHJlZml4IGFuZCB0aGUgPGNvZGU+bmFtZXNwYWNlVVJJPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPiwgb3IKLSAgICAgKiAgIGlmIHRoZSA8Y29kZT5xdWFsaWZpZWROYW1lPC9jb2RlPiBoYXMgYSBwcmVmaXggdGhhdCBpcyAieG1sIiBhbmQKLSAgICAgKiAgIHRoZSA8Y29kZT5uYW1lc3BhY2VVUkk8L2NvZGU+IGlzIGRpZmZlcmVudCBmcm9tICI8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9YTUwvMTk5OC9uYW1lc3BhY2UnPgotICAgICAqICAgaHR0cDovL3d3dy53My5vcmcvWE1MLzE5OTgvbmFtZXNwYWNlPC9hPiIgWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzE5OTkvUkVDLXhtbC1uYW1lcy0xOTk5MDExNC8nPlhNTCBOYW1lc3BhY2VzPC9hPl0KLSAgICAgKiAgICwgb3IgaWYgdGhlIDxjb2RlPnF1YWxpZmllZE5hbWU8L2NvZGU+IG9yIGl0cyBwcmVmaXggaXMgInhtbG5zIiBhbmQKLSAgICAgKiAgIHRoZSA8Y29kZT5uYW1lc3BhY2VVUkk8L2NvZGU+IGlzIGRpZmZlcmVudCBmcm9tICI8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3htbG5zLyc+aHR0cDovL3d3dy53My5vcmcvMjAwMC94bWxucy88L2E+Iiwgb3IgaWYgdGhlIDxjb2RlPm5hbWVzcGFjZVVSSTwvY29kZT4gaXMgIjxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnLzIwMDAveG1sbnMvJz5odHRwOi8vd3d3LnczLm9yZy8yMDAwL3htbG5zLzwvYT4iIGFuZCBuZWl0aGVyIHRoZSA8Y29kZT5xdWFsaWZpZWROYW1lPC9jb2RlPiBub3IgaXRzIHByZWZpeCBpcyAieG1sbnMiLgotICAgICAqICAgPGJyPk5PVF9TVVBQT1JURURfRVJSOiBBbHdheXMgdGhyb3duIGlmIHRoZSBjdXJyZW50IGRvY3VtZW50IGRvZXMgbm90Ci0gICAgICogICBzdXBwb3J0IHRoZSA8Y29kZT4iWE1MIjwvY29kZT4gZmVhdHVyZSwgc2luY2UgbmFtZXNwYWNlcyB3ZXJlCi0gICAgICogICBkZWZpbmVkIGJ5IFhNTC4KLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDIKLSAgICAgKi8KLSAgICBwdWJsaWMgRWxlbWVudCBjcmVhdGVFbGVtZW50TlMoU3RyaW5nIG5hbWVzcGFjZVVSSSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHF1YWxpZmllZE5hbWUpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGVzIGFuIGF0dHJpYnV0ZSBvZiB0aGUgZ2l2ZW4gcXVhbGlmaWVkIG5hbWUgYW5kIG5hbWVzcGFjZSBVUkkuCi0gICAgICogPGJyPlBlciBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMTk5OS9SRUMteG1sLW5hbWVzLTE5OTkwMTE0Lyc+WE1MIE5hbWVzcGFjZXM8L2E+XQotICAgICAqICwgYXBwbGljYXRpb25zIG11c3QgdXNlIHRoZSB2YWx1ZSA8Y29kZT5udWxsPC9jb2RlPiBhcyB0aGUKLSAgICAgKiA8Y29kZT5uYW1lc3BhY2VVUkk8L2NvZGU+IHBhcmFtZXRlciBmb3IgbWV0aG9kcyBpZiB0aGV5IHdpc2ggdG8gaGF2ZQotICAgICAqIG5vIG5hbWVzcGFjZS4KLSAgICAgKiBAcGFyYW0gbmFtZXNwYWNlVVJJIFRoZSBuYW1lc3BhY2UgVVJJIG9mIHRoZSBhdHRyaWJ1dGUgdG8gY3JlYXRlLgotICAgICAqIEBwYXJhbSBxdWFsaWZpZWROYW1lIFRoZSBxdWFsaWZpZWQgbmFtZSBvZiB0aGUgYXR0cmlidXRlIHRvCi0gICAgICogICBpbnN0YW50aWF0ZS4KLSAgICAgKiBAcmV0dXJuIEEgbmV3IDxjb2RlPkF0dHI8L2NvZGU+IG9iamVjdCB3aXRoIHRoZSBmb2xsb3dpbmcgYXR0cmlidXRlczoKLSAgICAgKiA8dGFibGUgYm9yZGVyPScxJyBjZWxscGFkZGluZz0nMyc+Ci0gICAgICogPHRyPgotICAgICAqIDx0aD4KLSAgICAgKiAgIEF0dHJpYnV0ZTwvdGg+Ci0gICAgICogPHRoPlZhbHVlPC90aD4KLSAgICAgKiA8L3RyPgotICAgICAqIDx0cj4KLSAgICAgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPjxjb2RlPk5vZGUubm9kZU5hbWU8L2NvZGU+PC90ZD4KLSAgICAgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPnF1YWxpZmllZE5hbWU8L3RkPgotICAgICAqIDwvdHI+Ci0gICAgICogPHRyPgotICAgICAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+Ci0gICAgICogICA8Y29kZT5Ob2RlLm5hbWVzcGFjZVVSSTwvY29kZT48L3RkPgotICAgICAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+PGNvZGU+bmFtZXNwYWNlVVJJPC9jb2RlPjwvdGQ+Ci0gICAgICogPC90cj4KLSAgICAgKiA8dHI+Ci0gICAgICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz4KLSAgICAgKiAgIDxjb2RlPk5vZGUucHJlZml4PC9jb2RlPjwvdGQ+Ci0gICAgICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz5wcmVmaXgsIGV4dHJhY3RlZCBmcm9tCi0gICAgICogICA8Y29kZT5xdWFsaWZpZWROYW1lPC9jb2RlPiwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlcmUgaXMgbm8KLSAgICAgKiAgIHByZWZpeDwvdGQ+Ci0gICAgICogPC90cj4KLSAgICAgKiA8dHI+Ci0gICAgICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz48Y29kZT5Ob2RlLmxvY2FsTmFtZTwvY29kZT48L3RkPgotICAgICAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+bG9jYWwgbmFtZSwgZXh0cmFjdGVkIGZyb20KLSAgICAgKiAgIDxjb2RlPnF1YWxpZmllZE5hbWU8L2NvZGU+PC90ZD4KLSAgICAgKiA8L3RyPgotICAgICAqIDx0cj4KLSAgICAgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPjxjb2RlPkF0dHIubmFtZTwvY29kZT48L3RkPgotICAgICAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+Ci0gICAgICogICA8Y29kZT5xdWFsaWZpZWROYW1lPC9jb2RlPjwvdGQ+Ci0gICAgICogPC90cj4KLSAgICAgKiA8dHI+Ci0gICAgICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz48Y29kZT5Ob2RlLm5vZGVWYWx1ZTwvY29kZT48L3RkPgotICAgICAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+dGhlIGVtcHR5Ci0gICAgICogICBzdHJpbmc8L3RkPgotICAgICAqIDwvdHI+Ci0gICAgICogPC90YWJsZT4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgSU5WQUxJRF9DSEFSQUNURVJfRVJSOiBSYWlzZWQgaWYgdGhlIHNwZWNpZmllZAotICAgICAqICAgPGNvZGU+cXVhbGlmaWVkTmFtZTwvY29kZT4gaXMgbm90IGFuIFhNTCBuYW1lIGFjY29yZGluZyB0byB0aGUgWE1MCi0gICAgICogICB2ZXJzaW9uIGluIHVzZSBzcGVjaWZpZWQgaW4gdGhlIDxjb2RlPkRvY3VtZW50LnhtbFZlcnNpb248L2NvZGU+Ci0gICAgICogICBhdHRyaWJ1dGUuCi0gICAgICogICA8YnI+TkFNRVNQQUNFX0VSUjogUmFpc2VkIGlmIHRoZSA8Y29kZT5xdWFsaWZpZWROYW1lPC9jb2RlPiBpcyBhCi0gICAgICogICBtYWxmb3JtZWQgcXVhbGlmaWVkIG5hbWUsIGlmIHRoZSA8Y29kZT5xdWFsaWZpZWROYW1lPC9jb2RlPiBoYXMgYQotICAgICAqICAgcHJlZml4IGFuZCB0aGUgPGNvZGU+bmFtZXNwYWNlVVJJPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPiwgaWYKLSAgICAgKiAgIHRoZSA8Y29kZT5xdWFsaWZpZWROYW1lPC9jb2RlPiBoYXMgYSBwcmVmaXggdGhhdCBpcyAieG1sIiBhbmQgdGhlCi0gICAgICogICA8Y29kZT5uYW1lc3BhY2VVUkk8L2NvZGU+IGlzIGRpZmZlcmVudCBmcm9tICI8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9YTUwvMTk5OC9uYW1lc3BhY2UnPgotICAgICAqICAgaHR0cDovL3d3dy53My5vcmcvWE1MLzE5OTgvbmFtZXNwYWNlPC9hPiIsIGlmIHRoZSA8Y29kZT5xdWFsaWZpZWROYW1lPC9jb2RlPiBvciBpdHMgcHJlZml4IGlzICJ4bWxucyIgYW5kIHRoZQotICAgICAqICAgPGNvZGU+bmFtZXNwYWNlVVJJPC9jb2RlPiBpcyBkaWZmZXJlbnQgZnJvbSAiPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvMjAwMC94bWxucy8nPmh0dHA6Ly93d3cudzMub3JnLzIwMDAveG1sbnMvPC9hPiIsIG9yIGlmIHRoZSA8Y29kZT5uYW1lc3BhY2VVUkk8L2NvZGU+IGlzICI8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3htbG5zLyc+aHR0cDovL3d3dy53My5vcmcvMjAwMC94bWxucy88L2E+IiBhbmQgbmVpdGhlciB0aGUgPGNvZGU+cXVhbGlmaWVkTmFtZTwvY29kZT4gbm9yIGl0cyBwcmVmaXggaXMgInhtbG5zIi4KLSAgICAgKiAgIDxicj5OT1RfU1VQUE9SVEVEX0VSUjogQWx3YXlzIHRocm93biBpZiB0aGUgY3VycmVudCBkb2N1bWVudCBkb2VzIG5vdAotICAgICAqICAgc3VwcG9ydCB0aGUgPGNvZGU+IlhNTCI8L2NvZGU+IGZlYXR1cmUsIHNpbmNlIG5hbWVzcGFjZXMgd2VyZQotICAgICAqICAgZGVmaW5lZCBieSBYTUwuCi0gICAgICogQHNpbmNlIERPTSBMZXZlbCAyCi0gICAgICovCi0gICAgcHVibGljIEF0dHIgY3JlYXRlQXR0cmlidXRlTlMoU3RyaW5nIG5hbWVzcGFjZVVSSSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcXVhbGlmaWVkTmFtZSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhIDxjb2RlPk5vZGVMaXN0PC9jb2RlPiBvZiBhbGwgdGhlIDxjb2RlPkVsZW1lbnRzPC9jb2RlPiB3aXRoIGEKLSAgICAgKiBnaXZlbiBsb2NhbCBuYW1lIGFuZCBuYW1lc3BhY2UgVVJJIGluIGRvY3VtZW50IG9yZGVyLgotICAgICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkgVGhlIG5hbWVzcGFjZSBVUkkgb2YgdGhlIGVsZW1lbnRzIHRvIG1hdGNoIG9uLiBUaGUKLSAgICAgKiAgIHNwZWNpYWwgdmFsdWUgPGNvZGU+IioiPC9jb2RlPiBtYXRjaGVzIGFsbCBuYW1lc3BhY2VzLgotICAgICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGxvY2FsIG5hbWUgb2YgdGhlIGVsZW1lbnRzIHRvIG1hdGNoIG9uLiBUaGUKLSAgICAgKiAgIHNwZWNpYWwgdmFsdWUgIioiIG1hdGNoZXMgYWxsIGxvY2FsIG5hbWVzLgotICAgICAqIEByZXR1cm4gQSBuZXcgPGNvZGU+Tm9kZUxpc3Q8L2NvZGU+IG9iamVjdCBjb250YWluaW5nIGFsbCB0aGUgbWF0Y2hlZAotICAgICAqICAgPGNvZGU+RWxlbWVudHM8L2NvZGU+LgotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMgotICAgICAqLwotICAgIHB1YmxpYyBOb2RlTGlzdCBnZXRFbGVtZW50c0J5VGFnTmFtZU5TKFN0cmluZyBuYW1lc3BhY2VVUkksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGxvY2FsTmFtZSk7Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSA8Y29kZT5FbGVtZW50PC9jb2RlPiB0aGF0IGhhcyBhbiBJRCBhdHRyaWJ1dGUgd2l0aCB0aGUKLSAgICAgKiBnaXZlbiB2YWx1ZS4gSWYgbm8gc3VjaCBlbGVtZW50IGV4aXN0cywgdGhpcyByZXR1cm5zIDxjb2RlPm51bGw8L2NvZGU+Ci0gICAgICogLiBJZiBtb3JlIHRoYW4gb25lIGVsZW1lbnQgaGFzIGFuIElEIGF0dHJpYnV0ZSB3aXRoIHRoYXQgdmFsdWUsIHdoYXQKLSAgICAgKiBpcyByZXR1cm5lZCBpcyB1bmRlZmluZWQuCi0gICAgICogPGJyPiBUaGUgRE9NIGltcGxlbWVudGF0aW9uIGlzIGV4cGVjdGVkIHRvIHVzZSB0aGUgYXR0cmlidXRlCi0gICAgICogPGNvZGU+QXR0ci5pc0lkPC9jb2RlPiB0byBkZXRlcm1pbmUgaWYgYW4gYXR0cmlidXRlIGlzIG9mIHR5cGUgSUQuCi0gICAgICogPHAgPjxiPk5vdGU6PC9iPiBBdHRyaWJ1dGVzIHdpdGggdGhlIG5hbWUgIklEIiBvciAiaWQiIGFyZSBub3Qgb2YgdHlwZQotICAgICAqIElEIHVubGVzcyBzbyBkZWZpbmVkLgotICAgICAqIEBwYXJhbSBlbGVtZW50SWQgVGhlIHVuaXF1ZSA8Y29kZT5pZDwvY29kZT4gdmFsdWUgZm9yIGFuIGVsZW1lbnQuCi0gICAgICogQHJldHVybiBUaGUgbWF0Y2hpbmcgZWxlbWVudCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGVyZSBpcyBub25lLgotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMgotICAgICAqLwotICAgIHB1YmxpYyBFbGVtZW50IGdldEVsZW1lbnRCeUlkKFN0cmluZyBlbGVtZW50SWQpOwotCi0gICAgLyoqCi0gICAgICogQW4gYXR0cmlidXRlIHNwZWNpZnlpbmcgdGhlIGVuY29kaW5nIHVzZWQgZm9yIHRoaXMgZG9jdW1lbnQgYXQgdGhlIHRpbWUKLSAgICAgKiBvZiB0aGUgcGFyc2luZy4gVGhpcyBpcyA8Y29kZT5udWxsPC9jb2RlPiB3aGVuIGl0IGlzIG5vdCBrbm93biwgc3VjaAotICAgICAqIGFzIHdoZW4gdGhlIDxjb2RlPkRvY3VtZW50PC9jb2RlPiB3YXMgY3JlYXRlZCBpbiBtZW1vcnkuCi0gICAgICogQHNpbmNlIERPTSBMZXZlbCAzCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRJbnB1dEVuY29kaW5nKCk7Ci0KLSAgICAvKioKLSAgICAgKiBBbiBhdHRyaWJ1dGUgc3BlY2lmeWluZywgYXMgcGFydCBvZiB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMteG1sLTIwMDQwMjA0I05ULVhNTERlY2wnPlhNTCBkZWNsYXJhdGlvbjwvYT4sIHRoZSBlbmNvZGluZyBvZiB0aGlzIGRvY3VtZW50LiBUaGlzIGlzIDxjb2RlPm51bGw8L2NvZGU+IHdoZW4KLSAgICAgKiB1bnNwZWNpZmllZCBvciB3aGVuIGl0IGlzIG5vdCBrbm93biwgc3VjaCBhcyB3aGVuIHRoZQotICAgICAqIDxjb2RlPkRvY3VtZW50PC9jb2RlPiB3YXMgY3JlYXRlZCBpbiBtZW1vcnkuCi0gICAgICogQHNpbmNlIERPTSBMZXZlbCAzCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRYbWxFbmNvZGluZygpOwotCi0gICAgLyoqCi0gICAgICogQW4gYXR0cmlidXRlIHNwZWNpZnlpbmcsIGFzIHBhcnQgb2YgdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLXhtbC0yMDA0MDIwNCNOVC1YTUxEZWNsJz5YTUwgZGVjbGFyYXRpb248L2E+LCB3aGV0aGVyIHRoaXMgZG9jdW1lbnQgaXMgc3RhbmRhbG9uZS4gVGhpcyBpcyA8Y29kZT5mYWxzZTwvY29kZT4gd2hlbgotICAgICAqIHVuc3BlY2lmaWVkLgotICAgICAqIDxwID48Yj5Ob3RlOjwvYj4gIE5vIHZlcmlmaWNhdGlvbiBpcyBkb25lIG9uIHRoZSB2YWx1ZSB3aGVuIHNldHRpbmcKLSAgICAgKiB0aGlzIGF0dHJpYnV0ZS4gQXBwbGljYXRpb25zIHNob3VsZCB1c2UKLSAgICAgKiA8Y29kZT5Eb2N1bWVudC5ub3JtYWxpemVEb2N1bWVudCgpPC9jb2RlPiB3aXRoIHRoZSAidmFsaWRhdGUiCi0gICAgICogcGFyYW1ldGVyIHRvIHZlcmlmeSBpZiB0aGUgdmFsdWUgbWF0Y2hlcyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMteG1sLTIwMDQwMjA0I3NlYy1ybWQnPnZhbGlkaXR5Ci0gICAgICogY29uc3RyYWludCBmb3Igc3RhbmRhbG9uZSBkb2N1bWVudCBkZWNsYXJhdGlvbjwvYT4gYXMgZGVmaW5lZCBpbiBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMteG1sLTIwMDQwMjA0Jz5YTUwgMS4wPC9hPl0uCi0gICAgICogQHNpbmNlIERPTSBMZXZlbCAzCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0WG1sU3RhbmRhbG9uZSgpOwotICAgIC8qKgotICAgICAqIEFuIGF0dHJpYnV0ZSBzcGVjaWZ5aW5nLCBhcyBwYXJ0IG9mIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy14bWwtMjAwNDAyMDQjTlQtWE1MRGVjbCc+WE1MIGRlY2xhcmF0aW9uPC9hPiwgd2hldGhlciB0aGlzIGRvY3VtZW50IGlzIHN0YW5kYWxvbmUuIFRoaXMgaXMgPGNvZGU+ZmFsc2U8L2NvZGU+IHdoZW4KLSAgICAgKiB1bnNwZWNpZmllZC4KLSAgICAgKiA8cCA+PGI+Tm90ZTo8L2I+ICBObyB2ZXJpZmljYXRpb24gaXMgZG9uZSBvbiB0aGUgdmFsdWUgd2hlbiBzZXR0aW5nCi0gICAgICogdGhpcyBhdHRyaWJ1dGUuIEFwcGxpY2F0aW9ucyBzaG91bGQgdXNlCi0gICAgICogPGNvZGU+RG9jdW1lbnQubm9ybWFsaXplRG9jdW1lbnQoKTwvY29kZT4gd2l0aCB0aGUgInZhbGlkYXRlIgotICAgICAqIHBhcmFtZXRlciB0byB2ZXJpZnkgaWYgdGhlIHZhbHVlIG1hdGNoZXMgdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLXhtbC0yMDA0MDIwNCNzZWMtcm1kJz52YWxpZGl0eQotICAgICAqIGNvbnN0cmFpbnQgZm9yIHN0YW5kYWxvbmUgZG9jdW1lbnQgZGVjbGFyYXRpb248L2E+IGFzIGRlZmluZWQgaW4gWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLXhtbC0yMDA0MDIwNCc+WE1MIDEuMDwvYT5dLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICAgTk9UX1NVUFBPUlRFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIGRvY3VtZW50IGRvZXMgbm90IHN1cHBvcnQgdGhlCi0gICAgICogICAiWE1MIiBmZWF0dXJlLgotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFhtbFN0YW5kYWxvbmUoYm9vbGVhbiB4bWxTdGFuZGFsb25lKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiAgQW4gYXR0cmlidXRlIHNwZWNpZnlpbmcsIGFzIHBhcnQgb2YgdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLXhtbC0yMDA0MDIwNCNOVC1YTUxEZWNsJz5YTUwgZGVjbGFyYXRpb248L2E+LCB0aGUgdmVyc2lvbiBudW1iZXIgb2YgdGhpcyBkb2N1bWVudC4gSWYgdGhlcmUgaXMgbm8gZGVjbGFyYXRpb24gYW5kIGlmCi0gICAgICogdGhpcyBkb2N1bWVudCBzdXBwb3J0cyB0aGUgIlhNTCIgZmVhdHVyZSwgdGhlIHZhbHVlIGlzCi0gICAgICogPGNvZGU+IjEuMCI8L2NvZGU+LiBJZiB0aGlzIGRvY3VtZW50IGRvZXMgbm90IHN1cHBvcnQgdGhlICJYTUwiCi0gICAgICogZmVhdHVyZSwgdGhlIHZhbHVlIGlzIGFsd2F5cyA8Y29kZT5udWxsPC9jb2RlPi4gQ2hhbmdpbmcgdGhpcwotICAgICAqIGF0dHJpYnV0ZSB3aWxsIGFmZmVjdCBtZXRob2RzIHRoYXQgY2hlY2sgZm9yIGludmFsaWQgY2hhcmFjdGVycyBpbgotICAgICAqIFhNTCBuYW1lcy4gQXBwbGljYXRpb24gc2hvdWxkIGludm9rZQotICAgICAqIDxjb2RlPkRvY3VtZW50Lm5vcm1hbGl6ZURvY3VtZW50KCk8L2NvZGU+IGluIG9yZGVyIHRvIGNoZWNrIGZvcgotICAgICAqIGludmFsaWQgY2hhcmFjdGVycyBpbiB0aGUgPGNvZGU+Tm9kZTwvY29kZT5zIHRoYXQgYXJlIGFscmVhZHkgcGFydCBvZgotICAgICAqIHRoaXMgPGNvZGU+RG9jdW1lbnQ8L2NvZGU+LgotICAgICAqIDxicj4gRE9NIGFwcGxpY2F0aW9ucyBtYXkgdXNlIHRoZQotICAgICAqIDxjb2RlPkRPTUltcGxlbWVudGF0aW9uLmhhc0ZlYXR1cmUoZmVhdHVyZSwgdmVyc2lvbik8L2NvZGU+IG1ldGhvZAotICAgICAqIHdpdGggcGFyYW1ldGVyIHZhbHVlcyAiWE1MVmVyc2lvbiIgYW5kICIxLjAiIChyZXNwZWN0aXZlbHkpIHRvCi0gICAgICogZGV0ZXJtaW5lIGlmIGFuIGltcGxlbWVudGF0aW9uIHN1cHBvcnRzIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy14bWwtMjAwNDAyMDQnPlhNTCAxLjA8L2E+XS4gRE9NCi0gICAgICogYXBwbGljYXRpb25zIG1heSB1c2UgdGhlIHNhbWUgbWV0aG9kIHdpdGggcGFyYW1ldGVyIHZhbHVlcwotICAgICAqICJYTUxWZXJzaW9uIiBhbmQgIjEuMSIgKHJlc3BlY3RpdmVseSkgdG8gZGV0ZXJtaW5lIGlmIGFuCi0gICAgICogaW1wbGVtZW50YXRpb24gc3VwcG9ydHMgWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLXhtbDExLTIwMDQwMjA0Lyc+WE1MIDEuMTwvYT5dLiBJbiBib3RoCi0gICAgICogY2FzZXMsIGluIG9yZGVyIHRvIHN1cHBvcnQgWE1MLCBhbiBpbXBsZW1lbnRhdGlvbiBtdXN0IGFsc28gc3VwcG9ydAotICAgICAqIHRoZSAiWE1MIiBmZWF0dXJlIGRlZmluZWQgaW4gdGhpcyBzcGVjaWZpY2F0aW9uLiA8Y29kZT5Eb2N1bWVudDwvY29kZT4KLSAgICAgKiAgb2JqZWN0cyBzdXBwb3J0aW5nIGEgdmVyc2lvbiBvZiB0aGUgIlhNTFZlcnNpb24iIGZlYXR1cmUgbXVzdCBub3QKLSAgICAgKiByYWlzZSBhIDxjb2RlPk5PVF9TVVBQT1JURURfRVJSPC9jb2RlPiBleGNlcHRpb24gZm9yIHRoZSBzYW1lIHZlcnNpb24KLSAgICAgKiBudW1iZXIgd2hlbiB1c2luZyA8Y29kZT5Eb2N1bWVudC54bWxWZXJzaW9uPC9jb2RlPi4KLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFhtbFZlcnNpb24oKTsKLSAgICAvKioKLSAgICAgKiAgQW4gYXR0cmlidXRlIHNwZWNpZnlpbmcsIGFzIHBhcnQgb2YgdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLXhtbC0yMDA0MDIwNCNOVC1YTUxEZWNsJz5YTUwgZGVjbGFyYXRpb248L2E+LCB0aGUgdmVyc2lvbiBudW1iZXIgb2YgdGhpcyBkb2N1bWVudC4gSWYgdGhlcmUgaXMgbm8gZGVjbGFyYXRpb24gYW5kIGlmCi0gICAgICogdGhpcyBkb2N1bWVudCBzdXBwb3J0cyB0aGUgIlhNTCIgZmVhdHVyZSwgdGhlIHZhbHVlIGlzCi0gICAgICogPGNvZGU+IjEuMCI8L2NvZGU+LiBJZiB0aGlzIGRvY3VtZW50IGRvZXMgbm90IHN1cHBvcnQgdGhlICJYTUwiCi0gICAgICogZmVhdHVyZSwgdGhlIHZhbHVlIGlzIGFsd2F5cyA8Y29kZT5udWxsPC9jb2RlPi4gQ2hhbmdpbmcgdGhpcwotICAgICAqIGF0dHJpYnV0ZSB3aWxsIGFmZmVjdCBtZXRob2RzIHRoYXQgY2hlY2sgZm9yIGludmFsaWQgY2hhcmFjdGVycyBpbgotICAgICAqIFhNTCBuYW1lcy4gQXBwbGljYXRpb24gc2hvdWxkIGludm9rZQotICAgICAqIDxjb2RlPkRvY3VtZW50Lm5vcm1hbGl6ZURvY3VtZW50KCk8L2NvZGU+IGluIG9yZGVyIHRvIGNoZWNrIGZvcgotICAgICAqIGludmFsaWQgY2hhcmFjdGVycyBpbiB0aGUgPGNvZGU+Tm9kZTwvY29kZT5zIHRoYXQgYXJlIGFscmVhZHkgcGFydCBvZgotICAgICAqIHRoaXMgPGNvZGU+RG9jdW1lbnQ8L2NvZGU+LgotICAgICAqIDxicj4gRE9NIGFwcGxpY2F0aW9ucyBtYXkgdXNlIHRoZQotICAgICAqIDxjb2RlPkRPTUltcGxlbWVudGF0aW9uLmhhc0ZlYXR1cmUoZmVhdHVyZSwgdmVyc2lvbik8L2NvZGU+IG1ldGhvZAotICAgICAqIHdpdGggcGFyYW1ldGVyIHZhbHVlcyAiWE1MVmVyc2lvbiIgYW5kICIxLjAiIChyZXNwZWN0aXZlbHkpIHRvCi0gICAgICogZGV0ZXJtaW5lIGlmIGFuIGltcGxlbWVudGF0aW9uIHN1cHBvcnRzIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy14bWwtMjAwNDAyMDQnPlhNTCAxLjA8L2E+XS4gRE9NCi0gICAgICogYXBwbGljYXRpb25zIG1heSB1c2UgdGhlIHNhbWUgbWV0aG9kIHdpdGggcGFyYW1ldGVyIHZhbHVlcwotICAgICAqICJYTUxWZXJzaW9uIiBhbmQgIjEuMSIgKHJlc3BlY3RpdmVseSkgdG8gZGV0ZXJtaW5lIGlmIGFuCi0gICAgICogaW1wbGVtZW50YXRpb24gc3VwcG9ydHMgWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLXhtbDExLTIwMDQwMjA0Lyc+WE1MIDEuMTwvYT5dLiBJbiBib3RoCi0gICAgICogY2FzZXMsIGluIG9yZGVyIHRvIHN1cHBvcnQgWE1MLCBhbiBpbXBsZW1lbnRhdGlvbiBtdXN0IGFsc28gc3VwcG9ydAotICAgICAqIHRoZSAiWE1MIiBmZWF0dXJlIGRlZmluZWQgaW4gdGhpcyBzcGVjaWZpY2F0aW9uLiA8Y29kZT5Eb2N1bWVudDwvY29kZT4KLSAgICAgKiAgb2JqZWN0cyBzdXBwb3J0aW5nIGEgdmVyc2lvbiBvZiB0aGUgIlhNTFZlcnNpb24iIGZlYXR1cmUgbXVzdCBub3QKLSAgICAgKiByYWlzZSBhIDxjb2RlPk5PVF9TVVBQT1JURURfRVJSPC9jb2RlPiBleGNlcHRpb24gZm9yIHRoZSBzYW1lIHZlcnNpb24KLSAgICAgKiBudW1iZXIgd2hlbiB1c2luZyA8Y29kZT5Eb2N1bWVudC54bWxWZXJzaW9uPC9jb2RlPi4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgIE5PVF9TVVBQT1JURURfRVJSOiBSYWlzZWQgaWYgdGhlIHZlcnNpb24gaXMgc2V0IHRvIGEgdmFsdWUgdGhhdCBpcwotICAgICAqICAgbm90IHN1cHBvcnRlZCBieSB0aGlzIDxjb2RlPkRvY3VtZW50PC9jb2RlPiBvciBpZiB0aGlzIGRvY3VtZW50Ci0gICAgICogICBkb2VzIG5vdCBzdXBwb3J0IHRoZSAiWE1MIiBmZWF0dXJlLgotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFhtbFZlcnNpb24oU3RyaW5nIHhtbFZlcnNpb24pCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIEFuIGF0dHJpYnV0ZSBzcGVjaWZ5aW5nIHdoZXRoZXIgZXJyb3IgY2hlY2tpbmcgaXMgZW5mb3JjZWQgb3Igbm90LiBXaGVuCi0gICAgICogc2V0IHRvIDxjb2RlPmZhbHNlPC9jb2RlPiwgdGhlIGltcGxlbWVudGF0aW9uIGlzIGZyZWUgdG8gbm90IHRlc3QKLSAgICAgKiBldmVyeSBwb3NzaWJsZSBlcnJvciBjYXNlIG5vcm1hbGx5IGRlZmluZWQgb24gRE9NIG9wZXJhdGlvbnMsIGFuZCBub3QKLSAgICAgKiByYWlzZSBhbnkgPGNvZGU+RE9NRXhjZXB0aW9uPC9jb2RlPiBvbiBET00gb3BlcmF0aW9ucyBvciByZXBvcnQKLSAgICAgKiBlcnJvcnMgd2hpbGUgdXNpbmcgPGNvZGU+RG9jdW1lbnQubm9ybWFsaXplRG9jdW1lbnQoKTwvY29kZT4uIEluIGNhc2UKLSAgICAgKiBvZiBlcnJvciwgdGhlIGJlaGF2aW9yIGlzIHVuZGVmaW5lZC4gVGhpcyBhdHRyaWJ1dGUgaXMKLSAgICAgKiA8Y29kZT50cnVlPC9jb2RlPiBieSBkZWZhdWx0LgotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGdldFN0cmljdEVycm9yQ2hlY2tpbmcoKTsKLSAgICAvKioKLSAgICAgKiBBbiBhdHRyaWJ1dGUgc3BlY2lmeWluZyB3aGV0aGVyIGVycm9yIGNoZWNraW5nIGlzIGVuZm9yY2VkIG9yIG5vdC4gV2hlbgotICAgICAqIHNldCB0byA8Y29kZT5mYWxzZTwvY29kZT4sIHRoZSBpbXBsZW1lbnRhdGlvbiBpcyBmcmVlIHRvIG5vdCB0ZXN0Ci0gICAgICogZXZlcnkgcG9zc2libGUgZXJyb3IgY2FzZSBub3JtYWxseSBkZWZpbmVkIG9uIERPTSBvcGVyYXRpb25zLCBhbmQgbm90Ci0gICAgICogcmFpc2UgYW55IDxjb2RlPkRPTUV4Y2VwdGlvbjwvY29kZT4gb24gRE9NIG9wZXJhdGlvbnMgb3IgcmVwb3J0Ci0gICAgICogZXJyb3JzIHdoaWxlIHVzaW5nIDxjb2RlPkRvY3VtZW50Lm5vcm1hbGl6ZURvY3VtZW50KCk8L2NvZGU+LiBJbiBjYXNlCi0gICAgICogb2YgZXJyb3IsIHRoZSBiZWhhdmlvciBpcyB1bmRlZmluZWQuIFRoaXMgYXR0cmlidXRlIGlzCi0gICAgICogPGNvZGU+dHJ1ZTwvY29kZT4gYnkgZGVmYXVsdC4KLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRTdHJpY3RFcnJvckNoZWNraW5nKGJvb2xlYW4gc3RyaWN0RXJyb3JDaGVja2luZyk7Ci0KLSAgICAvKioKLSAgICAgKiAgVGhlIGxvY2F0aW9uIG9mIHRoZSBkb2N1bWVudCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiB1bmRlZmluZWQgb3IgaWYKLSAgICAgKiB0aGUgPGNvZGU+RG9jdW1lbnQ8L2NvZGU+IHdhcyBjcmVhdGVkIHVzaW5nCi0gICAgICogPGNvZGU+RE9NSW1wbGVtZW50YXRpb24uY3JlYXRlRG9jdW1lbnQ8L2NvZGU+LiBObyBsZXhpY2FsIGNoZWNraW5nIGlzCi0gICAgICogcGVyZm9ybWVkIHdoZW4gc2V0dGluZyB0aGlzIGF0dHJpYnV0ZTsgdGhpcyBjb3VsZCByZXN1bHQgaW4gYQotICAgICAqIDxjb2RlPm51bGw8L2NvZGU+IHZhbHVlIHJldHVybmVkIHdoZW4gdXNpbmcgPGNvZGU+Tm9kZS5iYXNlVVJJPC9jb2RlPgotICAgICAqIC4KLSAgICAgKiA8YnI+IEJld2FyZSB0aGF0IHdoZW4gdGhlIDxjb2RlPkRvY3VtZW50PC9jb2RlPiBzdXBwb3J0cyB0aGUgZmVhdHVyZQotICAgICAqICJIVE1MIiBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMy9SRUMtRE9NLUxldmVsLTItSFRNTC0yMDAzMDEwOSc+RE9NIExldmVsIDIgSFRNTDwvYT5dCi0gICAgICogLCB0aGUgaHJlZiBhdHRyaWJ1dGUgb2YgdGhlIEhUTUwgQkFTRSBlbGVtZW50IHRha2VzIHByZWNlZGVuY2Ugb3ZlcgotICAgICAqIHRoaXMgYXR0cmlidXRlIHdoZW4gY29tcHV0aW5nIDxjb2RlPk5vZGUuYmFzZVVSSTwvY29kZT4uCi0gICAgICogQHNpbmNlIERPTSBMZXZlbCAzCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXREb2N1bWVudFVSSSgpOwotICAgIC8qKgotICAgICAqICBUaGUgbG9jYXRpb24gb2YgdGhlIGRvY3VtZW50IG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIHVuZGVmaW5lZCBvciBpZgotICAgICAqIHRoZSA8Y29kZT5Eb2N1bWVudDwvY29kZT4gd2FzIGNyZWF0ZWQgdXNpbmcKLSAgICAgKiA8Y29kZT5ET01JbXBsZW1lbnRhdGlvbi5jcmVhdGVEb2N1bWVudDwvY29kZT4uIE5vIGxleGljYWwgY2hlY2tpbmcgaXMKLSAgICAgKiBwZXJmb3JtZWQgd2hlbiBzZXR0aW5nIHRoaXMgYXR0cmlidXRlOyB0aGlzIGNvdWxkIHJlc3VsdCBpbiBhCi0gICAgICogPGNvZGU+bnVsbDwvY29kZT4gdmFsdWUgcmV0dXJuZWQgd2hlbiB1c2luZyA8Y29kZT5Ob2RlLmJhc2VVUkk8L2NvZGU+Ci0gICAgICogLgotICAgICAqIDxicj4gQmV3YXJlIHRoYXQgd2hlbiB0aGUgPGNvZGU+RG9jdW1lbnQ8L2NvZGU+IHN1cHBvcnRzIHRoZSBmZWF0dXJlCi0gICAgICogIkhUTUwiIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAzL1JFQy1ET00tTGV2ZWwtMi1IVE1MLTIwMDMwMTA5Jz5ET00gTGV2ZWwgMiBIVE1MPC9hPl0KLSAgICAgKiAsIHRoZSBocmVmIGF0dHJpYnV0ZSBvZiB0aGUgSFRNTCBCQVNFIGVsZW1lbnQgdGFrZXMgcHJlY2VkZW5jZSBvdmVyCi0gICAgICogdGhpcyBhdHRyaWJ1dGUgd2hlbiBjb21wdXRpbmcgPGNvZGU+Tm9kZS5iYXNlVVJJPC9jb2RlPi4KLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXREb2N1bWVudFVSSShTdHJpbmcgZG9jdW1lbnRVUkkpOwotCi0gICAgLyoqCi0gICAgICogIEF0dGVtcHRzIHRvIGFkb3B0IGEgbm9kZSBmcm9tIGFub3RoZXIgZG9jdW1lbnQgdG8gdGhpcyBkb2N1bWVudC4gSWYKLSAgICAgKiBzdXBwb3J0ZWQsIGl0IGNoYW5nZXMgdGhlIDxjb2RlPm93bmVyRG9jdW1lbnQ8L2NvZGU+IG9mIHRoZSBzb3VyY2UKLSAgICAgKiBub2RlLCBpdHMgY2hpbGRyZW4sIGFzIHdlbGwgYXMgdGhlIGF0dGFjaGVkIGF0dHJpYnV0ZSBub2RlcyBpZiB0aGVyZQotICAgICAqIGFyZSBhbnkuIElmIHRoZSBzb3VyY2Ugbm9kZSBoYXMgYSBwYXJlbnQgaXQgaXMgZmlyc3QgcmVtb3ZlZCBmcm9tIHRoZQotICAgICAqIGNoaWxkIGxpc3Qgb2YgaXRzIHBhcmVudC4gVGhpcyBlZmZlY3RpdmVseSBhbGxvd3MgbW92aW5nIGEgc3VidHJlZQotICAgICAqIGZyb20gb25lIGRvY3VtZW50IHRvIGFub3RoZXIgKHVubGlrZSA8Y29kZT5pbXBvcnROb2RlKCk8L2NvZGU+IHdoaWNoCi0gICAgICogY3JlYXRlIGEgY29weSBvZiB0aGUgc291cmNlIG5vZGUgaW5zdGVhZCBvZiBtb3ZpbmcgaXQpLiBXaGVuIGl0Ci0gICAgICogZmFpbHMsIGFwcGxpY2F0aW9ucyBzaG91bGQgdXNlIDxjb2RlPkRvY3VtZW50LmltcG9ydE5vZGUoKTwvY29kZT4KLSAgICAgKiBpbnN0ZWFkLiBOb3RlIHRoYXQgaWYgdGhlIGFkb3B0ZWQgbm9kZSBpcyBhbHJlYWR5IHBhcnQgb2YgdGhpcwotICAgICAqIGRvY3VtZW50IChpLmUuIHRoZSBzb3VyY2UgYW5kIHRhcmdldCBkb2N1bWVudCBhcmUgdGhlIHNhbWUpLCB0aGlzCi0gICAgICogbWV0aG9kIHN0aWxsIGhhcyB0aGUgZWZmZWN0IG9mIHJlbW92aW5nIHRoZSBzb3VyY2Ugbm9kZSBmcm9tIHRoZQotICAgICAqIGNoaWxkIGxpc3Qgb2YgaXRzIHBhcmVudCwgaWYgYW55LiBUaGUgZm9sbG93aW5nIGxpc3QgZGVzY3JpYmVzIHRoZQotICAgICAqIHNwZWNpZmljcyBmb3IgZWFjaCB0eXBlIG9mIG5vZGUuCi0gICAgICogPGRsPgotICAgICAqIDxkdD5BVFRSSUJVVEVfTk9ERTwvZHQ+Ci0gICAgICogPGRkPlRoZQotICAgICAqIDxjb2RlPm93bmVyRWxlbWVudDwvY29kZT4gYXR0cmlidXRlIGlzIHNldCB0byA8Y29kZT5udWxsPC9jb2RlPiBhbmQKLSAgICAgKiB0aGUgPGNvZGU+c3BlY2lmaWVkPC9jb2RlPiBmbGFnIGlzIHNldCB0byA8Y29kZT50cnVlPC9jb2RlPiBvbiB0aGUKLSAgICAgKiBhZG9wdGVkIDxjb2RlPkF0dHI8L2NvZGU+LiBUaGUgZGVzY2VuZGFudHMgb2YgdGhlIHNvdXJjZQotICAgICAqIDxjb2RlPkF0dHI8L2NvZGU+IGFyZSByZWN1cnNpdmVseSBhZG9wdGVkLjwvZGQ+Ci0gICAgICogPGR0PkRPQ1VNRU5UX0ZSQUdNRU5UX05PREU8L2R0PgotICAgICAqIDxkZD5UaGUKLSAgICAgKiBkZXNjZW5kYW50cyBvZiB0aGUgc291cmNlIG5vZGUgYXJlIHJlY3Vyc2l2ZWx5IGFkb3B0ZWQuPC9kZD4KLSAgICAgKiA8ZHQ+RE9DVU1FTlRfTk9ERTwvZHQ+Ci0gICAgICogPGRkPgotICAgICAqIDxjb2RlPkRvY3VtZW50PC9jb2RlPiBub2RlcyBjYW5ub3QgYmUgYWRvcHRlZC48L2RkPgotICAgICAqIDxkdD5ET0NVTUVOVF9UWVBFX05PREU8L2R0PgotICAgICAqIDxkZD4KLSAgICAgKiA8Y29kZT5Eb2N1bWVudFR5cGU8L2NvZGU+IG5vZGVzIGNhbm5vdCBiZSBhZG9wdGVkLjwvZGQ+Ci0gICAgICogPGR0PkVMRU1FTlRfTk9ERTwvZHQ+Ci0gICAgICogPGRkPjxlbT5TcGVjaWZpZWQ8L2VtPiBhdHRyaWJ1dGUgbm9kZXMgb2YgdGhlIHNvdXJjZSBlbGVtZW50IGFyZSBhZG9wdGVkLiBEZWZhdWx0IGF0dHJpYnV0ZXMKLSAgICAgKiBhcmUgZGlzY2FyZGVkLCB0aG91Z2ggaWYgdGhlIGRvY3VtZW50IGJlaW5nIGFkb3B0ZWQgaW50byBkZWZpbmVzCi0gICAgICogZGVmYXVsdCBhdHRyaWJ1dGVzIGZvciB0aGlzIGVsZW1lbnQgbmFtZSwgdGhvc2UgYXJlIGFzc2lnbmVkLiBUaGUKLSAgICAgKiBkZXNjZW5kYW50cyBvZiB0aGUgc291cmNlIGVsZW1lbnQgYXJlIHJlY3Vyc2l2ZWx5IGFkb3B0ZWQuPC9kZD4KLSAgICAgKiA8ZHQ+RU5USVRZX05PREU8L2R0PgotICAgICAqIDxkZD4KLSAgICAgKiA8Y29kZT5FbnRpdHk8L2NvZGU+IG5vZGVzIGNhbm5vdCBiZSBhZG9wdGVkLjwvZGQ+Ci0gICAgICogPGR0PkVOVElUWV9SRUZFUkVOQ0VfTk9ERTwvZHQ+Ci0gICAgICogPGRkPk9ubHkKLSAgICAgKiB0aGUgPGNvZGU+RW50aXR5UmVmZXJlbmNlPC9jb2RlPiBub2RlIGl0c2VsZiBpcyBhZG9wdGVkLCB0aGUKLSAgICAgKiBkZXNjZW5kYW50cyBhcmUgZGlzY2FyZGVkLCBzaW5jZSB0aGUgc291cmNlIGFuZCBkZXN0aW5hdGlvbiBkb2N1bWVudHMKLSAgICAgKiBtaWdodCBoYXZlIGRlZmluZWQgdGhlIGVudGl0eSBkaWZmZXJlbnRseS4gSWYgdGhlIGRvY3VtZW50IGJlaW5nCi0gICAgICogaW1wb3J0ZWQgaW50byBwcm92aWRlcyBhIGRlZmluaXRpb24gZm9yIHRoaXMgZW50aXR5IG5hbWUsIGl0cyB2YWx1ZQotICAgICAqIGlzIGFzc2lnbmVkLjwvZGQ+Ci0gICAgICogPGR0Pk5PVEFUSU9OX05PREU8L2R0PgotICAgICAqIDxkZD48Y29kZT5Ob3RhdGlvbjwvY29kZT4gbm9kZXMgY2Fubm90IGJlCi0gICAgICogYWRvcHRlZC48L2RkPgotICAgICAqIDxkdD5QUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREUsIFRFWFRfTk9ERSwgQ0RBVEFfU0VDVElPTl9OT0RFLAotICAgICAqIENPTU1FTlRfTk9ERTwvZHQ+Ci0gICAgICogPGRkPlRoZXNlIG5vZGVzIGNhbiBhbGwgYmUgYWRvcHRlZC4gTm8gc3BlY2lmaWNzLjwvZGQ+Ci0gICAgICogPC9kbD4KLSAgICAgKiA8cCA+PGI+Tm90ZTo8L2I+ICBTaW5jZSBpdCBkb2VzIG5vdCBjcmVhdGUgbmV3IG5vZGVzIHVubGlrZSB0aGUKLSAgICAgKiA8Y29kZT5Eb2N1bWVudC5pbXBvcnROb2RlKCk8L2NvZGU+IG1ldGhvZCwgdGhpcyBtZXRob2QgZG9lcyBub3QgcmFpc2UKLSAgICAgKiBhbiA8Y29kZT5JTlZBTElEX0NIQVJBQ1RFUl9FUlI8L2NvZGU+IGV4Y2VwdGlvbiwgYW5kIGFwcGxpY2F0aW9ucwotICAgICAqIHNob3VsZCB1c2UgdGhlIDxjb2RlPkRvY3VtZW50Lm5vcm1hbGl6ZURvY3VtZW50KCk8L2NvZGU+IG1ldGhvZCB0bwotICAgICAqIGNoZWNrIGlmIGFuIGltcG9ydGVkIG5hbWUgaXMgbm90IGFuIFhNTCBuYW1lIGFjY29yZGluZyB0byB0aGUgWE1MCi0gICAgICogdmVyc2lvbiBpbiB1c2UuCi0gICAgICogQHBhcmFtIHNvdXJjZSBUaGUgbm9kZSB0byBtb3ZlIGludG8gdGhpcyBkb2N1bWVudC4KLSAgICAgKiBAcmV0dXJuIFRoZSBhZG9wdGVkIG5vZGUsIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoaXMgb3BlcmF0aW9uCi0gICAgICogICBmYWlscywgc3VjaCBhcyB3aGVuIHRoZSBzb3VyY2Ugbm9kZSBjb21lcyBmcm9tIGEgZGlmZmVyZW50Ci0gICAgICogICBpbXBsZW1lbnRhdGlvbi4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgTk9UX1NVUFBPUlRFRF9FUlI6IFJhaXNlZCBpZiB0aGUgc291cmNlIG5vZGUgaXMgb2YgdHlwZQotICAgICAqICAgPGNvZGU+RE9DVU1FTlQ8L2NvZGU+LCA8Y29kZT5ET0NVTUVOVF9UWVBFPC9jb2RlPi4KLSAgICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCB3aGVuIHRoZSBzb3VyY2Ugbm9kZSBpcwotICAgICAqICAgcmVhZG9ubHkuCi0gICAgICogQHNpbmNlIERPTSBMZXZlbCAzCi0gICAgICovCi0gICAgcHVibGljIE5vZGUgYWRvcHROb2RlKE5vZGUgc291cmNlKQotICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogIFRoZSBjb25maWd1cmF0aW9uIHVzZWQgd2hlbiA8Y29kZT5Eb2N1bWVudC5ub3JtYWxpemVEb2N1bWVudCgpPC9jb2RlPgotICAgICAqIGlzIGludm9rZWQuCi0gICAgICogQHNpbmNlIERPTSBMZXZlbCAzCi0gICAgICovCi0gICAgcHVibGljIERPTUNvbmZpZ3VyYXRpb24gZ2V0RG9tQ29uZmlnKCk7Ci0KLSAgICAvKioKLSAgICAgKiAgVGhpcyBtZXRob2QgYWN0cyBhcyBpZiB0aGUgZG9jdW1lbnQgd2FzIGdvaW5nIHRocm91Z2ggYSBzYXZlIGFuZCBsb2FkCi0gICAgICogY3ljbGUsIHB1dHRpbmcgdGhlIGRvY3VtZW50IGluIGEgIm5vcm1hbCIgZm9ybS4gQXMgYSBjb25zZXF1ZW5jZSwKLSAgICAgKiB0aGlzIG1ldGhvZCB1cGRhdGVzIHRoZSByZXBsYWNlbWVudCB0cmVlIG9mCi0gICAgICogPGNvZGU+RW50aXR5UmVmZXJlbmNlPC9jb2RlPiBub2RlcyBhbmQgbm9ybWFsaXplcyA8Y29kZT5UZXh0PC9jb2RlPgotICAgICAqIG5vZGVzLCBhcyBkZWZpbmVkIGluIHRoZSBtZXRob2QgPGNvZGU+Tm9kZS5ub3JtYWxpemUoKTwvY29kZT4uCi0gICAgICogPGJyPiBPdGhlcndpc2UsIHRoZSBhY3R1YWwgcmVzdWx0IGRlcGVuZHMgb24gdGhlIGZlYXR1cmVzIGJlaW5nIHNldCBvbgotICAgICAqIHRoZSA8Y29kZT5Eb2N1bWVudC5kb21Db25maWc8L2NvZGU+IG9iamVjdCBhbmQgZ292ZXJuaW5nIHdoYXQKLSAgICAgKiBvcGVyYXRpb25zIGFjdHVhbGx5IHRha2UgcGxhY2UuIE5vdGljZWFibHkgdGhpcyBtZXRob2QgY291bGQgYWxzbwotICAgICAqIG1ha2UgdGhlIGRvY3VtZW50IG5hbWVzcGFjZSB3ZWxsLWZvcm1lZCBhY2NvcmRpbmcgdG8gdGhlIGFsZ29yaXRobQotICAgICAqIGRlc2NyaWJlZCBpbiAsIGNoZWNrIHRoZSBjaGFyYWN0ZXIgbm9ybWFsaXphdGlvbiwgcmVtb3ZlIHRoZQotICAgICAqIDxjb2RlPkNEQVRBU2VjdGlvbjwvY29kZT4gbm9kZXMsIGV0Yy4gU2VlCi0gICAgICogPGNvZGU+RE9NQ29uZmlndXJhdGlvbjwvY29kZT4gZm9yIGRldGFpbHMuCi0gICAgICogPHByZT4vLyBLZWVwIGluIHRoZSBkb2N1bWVudAotICAgICAqIHRoZSBpbmZvcm1hdGlvbiBkZWZpbmVkIC8vIGluIHRoZSBYTUwgSW5mb3JtYXRpb24gU2V0IChKYXZhIGV4YW1wbGUpCi0gICAgICogRE9NQ29uZmlndXJhdGlvbiBkb2NDb25maWcgPSBteURvY3VtZW50LmdldERvbUNvbmZpZygpOwotICAgICAqIGRvY0NvbmZpZy5zZXRQYXJhbWV0ZXIoImluZm9zZXQiLCBCb29sZWFuLlRSVUUpOwotICAgICAqIG15RG9jdW1lbnQubm9ybWFsaXplRG9jdW1lbnQoKTs8L3ByZT4KLSAgICAgKgotICAgICAqIDxicj5NdXRhdGlvbiBldmVudHMsIHdoZW4gc3VwcG9ydGVkLCBhcmUgZ2VuZXJhdGVkIHRvIHJlZmxlY3QgdGhlCi0gICAgICogY2hhbmdlcyBvY2N1cnJpbmcgb24gdGhlIGRvY3VtZW50LgotICAgICAqIDxicj4gSWYgZXJyb3JzIG9jY3VyIGR1cmluZyB0aGUgaW52b2NhdGlvbiBvZiB0aGlzIG1ldGhvZCwgc3VjaCBhcyBhbgotICAgICAqIGF0dGVtcHQgdG8gdXBkYXRlIGEgcmVhZC1vbmx5IG5vZGUgb3IgYSA8Y29kZT5Ob2RlLm5vZGVOYW1lPC9jb2RlPgotICAgICAqIGNvbnRhaW5zIGFuIGludmFsaWQgY2hhcmFjdGVyIGFjY29yZGluZyB0byB0aGUgWE1MIHZlcnNpb24gaW4gdXNlLAotICAgICAqIGVycm9ycyBvciB3YXJuaW5ncyAoPGNvZGU+RE9NRXJyb3IuU0VWRVJJVFlfRVJST1I8L2NvZGU+IG9yCi0gICAgICogPGNvZGU+RE9NRXJyb3IuU0VWRVJJVFlfV0FSTklORzwvY29kZT4pIHdpbGwgYmUgcmVwb3J0ZWQgdXNpbmcgdGhlCi0gICAgICogPGNvZGU+RE9NRXJyb3JIYW5kbGVyPC9jb2RlPiBvYmplY3QgYXNzb2NpYXRlZCB3aXRoIHRoZSAiZXJyb3ItaGFuZGxlcgotICAgICAqICIgcGFyYW1ldGVyLiBOb3RlIHRoaXMgbWV0aG9kIG1pZ2h0IGFsc28gcmVwb3J0IGZhdGFsIGVycm9ycyAoCi0gICAgICogPGNvZGU+RE9NRXJyb3IuU0VWRVJJVFlfRkFUQUxfRVJST1I8L2NvZGU+KSBpZiBhbiBpbXBsZW1lbnRhdGlvbgotICAgICAqIGNhbm5vdCByZWNvdmVyIGZyb20gYW4gZXJyb3IuCi0gICAgICogQHNpbmNlIERPTSBMZXZlbCAzCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgbm9ybWFsaXplRG9jdW1lbnQoKTsKLQotICAgIC8qKgotICAgICAqIFJlbmFtZSBhbiBleGlzdGluZyBub2RlIG9mIHR5cGUgPGNvZGU+RUxFTUVOVF9OT0RFPC9jb2RlPiBvcgotICAgICAqIDxjb2RlPkFUVFJJQlVURV9OT0RFPC9jb2RlPi4KLSAgICAgKiA8YnI+V2hlbiBwb3NzaWJsZSB0aGlzIHNpbXBseSBjaGFuZ2VzIHRoZSBuYW1lIG9mIHRoZSBnaXZlbiBub2RlLAotICAgICAqIG90aGVyd2lzZSB0aGlzIGNyZWF0ZXMgYSBuZXcgbm9kZSB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZSBhbmQKLSAgICAgKiByZXBsYWNlcyB0aGUgZXhpc3Rpbmcgbm9kZSB3aXRoIHRoZSBuZXcgbm9kZSBhcyBkZXNjcmliZWQgYmVsb3cuCi0gICAgICogPGJyPklmIHNpbXBseSBjaGFuZ2luZyB0aGUgbmFtZSBvZiB0aGUgZ2l2ZW4gbm9kZSBpcyBub3QgcG9zc2libGUsIHRoZQotICAgICAqIGZvbGxvd2luZyBvcGVyYXRpb25zIGFyZSBwZXJmb3JtZWQ6IGEgbmV3IG5vZGUgaXMgY3JlYXRlZCwgYW55Ci0gICAgICogcmVnaXN0ZXJlZCBldmVudCBsaXN0ZW5lciBpcyByZWdpc3RlcmVkIG9uIHRoZSBuZXcgbm9kZSwgYW55IHVzZXIKLSAgICAgKiBkYXRhIGF0dGFjaGVkIHRvIHRoZSBvbGQgbm9kZSBpcyByZW1vdmVkIGZyb20gdGhhdCBub2RlLCB0aGUgb2xkIG5vZGUKLSAgICAgKiBpcyByZW1vdmVkIGZyb20gaXRzIHBhcmVudCBpZiBpdCBoYXMgb25lLCB0aGUgY2hpbGRyZW4gYXJlIG1vdmVkIHRvCi0gICAgICogdGhlIG5ldyBub2RlLCBpZiB0aGUgcmVuYW1lZCBub2RlIGlzIGFuIDxjb2RlPkVsZW1lbnQ8L2NvZGU+IGl0cwotICAgICAqIGF0dHJpYnV0ZXMgYXJlIG1vdmVkIHRvIHRoZSBuZXcgbm9kZSwgdGhlIG5ldyBub2RlIGlzIGluc2VydGVkIGF0IHRoZQotICAgICAqIHBvc2l0aW9uIHRoZSBvbGQgbm9kZSB1c2VkIHRvIGhhdmUgaW4gaXRzIHBhcmVudCdzIGNoaWxkIG5vZGVzIGxpc3QKLSAgICAgKiBpZiBpdCBoYXMgb25lLCB0aGUgdXNlciBkYXRhIHRoYXQgd2FzIGF0dGFjaGVkIHRvIHRoZSBvbGQgbm9kZSBpcwotICAgICAqIGF0dGFjaGVkIHRvIHRoZSBuZXcgbm9kZS4KLSAgICAgKiA8YnI+V2hlbiB0aGUgbm9kZSBiZWluZyByZW5hbWVkIGlzIGFuIDxjb2RlPkVsZW1lbnQ8L2NvZGU+IG9ubHkgdGhlCi0gICAgICogc3BlY2lmaWVkIGF0dHJpYnV0ZXMgYXJlIG1vdmVkLCBkZWZhdWx0IGF0dHJpYnV0ZXMgb3JpZ2luYXRlZCBmcm9tCi0gICAgICogdGhlIERURCBhcmUgdXBkYXRlZCBhY2NvcmRpbmcgdG8gdGhlIG5ldyBlbGVtZW50IG5hbWUuIEluIGFkZGl0aW9uLAotICAgICAqIHRoZSBpbXBsZW1lbnRhdGlvbiBtYXkgdXBkYXRlIGRlZmF1bHQgYXR0cmlidXRlcyBmcm9tIG90aGVyIHNjaGVtYXMuCi0gICAgICogQXBwbGljYXRpb25zIHNob3VsZCB1c2UgPGNvZGU+RG9jdW1lbnQubm9ybWFsaXplRG9jdW1lbnQoKTwvY29kZT4gdG8KLSAgICAgKiBndWFyYW50ZWUgdGhlc2UgYXR0cmlidXRlcyBhcmUgdXAtdG8tZGF0ZS4KLSAgICAgKiA8YnI+V2hlbiB0aGUgbm9kZSBiZWluZyByZW5hbWVkIGlzIGFuIDxjb2RlPkF0dHI8L2NvZGU+IHRoYXQgaXMKLSAgICAgKiBhdHRhY2hlZCB0byBhbiA8Y29kZT5FbGVtZW50PC9jb2RlPiwgdGhlIG5vZGUgaXMgZmlyc3QgcmVtb3ZlZCBmcm9tCi0gICAgICogdGhlIDxjb2RlPkVsZW1lbnQ8L2NvZGU+IGF0dHJpYnV0ZXMgbWFwLiBUaGVuLCBvbmNlIHJlbmFtZWQsIGVpdGhlcgotICAgICAqIGJ5IG1vZGlmeWluZyB0aGUgZXhpc3Rpbmcgbm9kZSBvciBjcmVhdGluZyBhIG5ldyBvbmUgYXMgZGVzY3JpYmVkCi0gICAgICogYWJvdmUsIGl0IGlzIHB1dCBiYWNrLgotICAgICAqIDxicj5JbiBhZGRpdGlvbiwKLSAgICAgKiA8dWw+Ci0gICAgICogPGxpPiBhIHVzZXIgZGF0YSBldmVudCA8Y29kZT5OT0RFX1JFTkFNRUQ8L2NvZGU+IGlzIGZpcmVkLAotICAgICAqIDwvbGk+Ci0gICAgICogPGxpPgotICAgICAqIHdoZW4gdGhlIGltcGxlbWVudGF0aW9uIHN1cHBvcnRzIHRoZSBmZWF0dXJlICJNdXRhdGlvbk5hbWVFdmVudHMiLAotICAgICAqIGVhY2ggbXV0YXRpb24gb3BlcmF0aW9uIGludm9sdmVkIGluIHRoaXMgbWV0aG9kIGZpcmVzIHRoZSBhcHByb3ByaWF0ZQotICAgICAqIGV2ZW50LCBhbmQgaW4gdGhlIGVuZCB0aGUgZXZlbnQgewotICAgICAqIDxjb2RlPmh0dHA6Ly93d3cudzMub3JnLzIwMDEveG1sLWV2ZW50czwvY29kZT4sCi0gICAgICogPGNvZGU+RE9NRWxlbWVudE5hbWVDaGFuZ2VkPC9jb2RlPn0gb3IgewotICAgICAqIDxjb2RlPmh0dHA6Ly93d3cudzMub3JnLzIwMDEveG1sLWV2ZW50czwvY29kZT4sCi0gICAgICogPGNvZGU+RE9NQXR0cmlidXRlTmFtZUNoYW5nZWQ8L2NvZGU+fSBpcyBmaXJlZC4KLSAgICAgKiA8L2xpPgotICAgICAqIDwvdWw+Ci0gICAgICogQHBhcmFtIG4gVGhlIG5vZGUgdG8gcmVuYW1lLgotICAgICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkgVGhlIG5ldyBuYW1lc3BhY2UgVVJJLgotICAgICAqIEBwYXJhbSBxdWFsaWZpZWROYW1lIFRoZSBuZXcgcXVhbGlmaWVkIG5hbWUuCi0gICAgICogQHJldHVybiBUaGUgcmVuYW1lZCBub2RlLiBUaGlzIGlzIGVpdGhlciB0aGUgc3BlY2lmaWVkIG5vZGUgb3IgdGhlIG5ldwotICAgICAqICAgbm9kZSB0aGF0IHdhcyBjcmVhdGVkIHRvIHJlcGxhY2UgdGhlIHNwZWNpZmllZCBub2RlLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBOT1RfU1VQUE9SVEVEX0VSUjogUmFpc2VkIHdoZW4gdGhlIHR5cGUgb2YgdGhlIHNwZWNpZmllZCBub2RlIGlzCi0gICAgICogICBuZWl0aGVyIDxjb2RlPkVMRU1FTlRfTk9ERTwvY29kZT4gbm9yIDxjb2RlPkFUVFJJQlVURV9OT0RFPC9jb2RlPiwKLSAgICAgKiAgIG9yIGlmIHRoZSBpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdCBzdXBwb3J0IHRoZSByZW5hbWluZyBvZiB0aGUKLSAgICAgKiAgIGRvY3VtZW50IGVsZW1lbnQuCi0gICAgICogICA8YnI+SU5WQUxJRF9DSEFSQUNURVJfRVJSOiBSYWlzZWQgaWYgdGhlIG5ldyBxdWFsaWZpZWQgbmFtZSBpcyBub3QgYW4KLSAgICAgKiAgIFhNTCBuYW1lIGFjY29yZGluZyB0byB0aGUgWE1MIHZlcnNpb24gaW4gdXNlIHNwZWNpZmllZCBpbiB0aGUKLSAgICAgKiAgIDxjb2RlPkRvY3VtZW50LnhtbFZlcnNpb248L2NvZGU+IGF0dHJpYnV0ZS4KLSAgICAgKiAgIDxicj5XUk9OR19ET0NVTUVOVF9FUlI6IFJhaXNlZCB3aGVuIHRoZSBzcGVjaWZpZWQgbm9kZSB3YXMgY3JlYXRlZAotICAgICAqICAgZnJvbSBhIGRpZmZlcmVudCBkb2N1bWVudCB0aGFuIHRoaXMgZG9jdW1lbnQuCi0gICAgICogICA8YnI+TkFNRVNQQUNFX0VSUjogUmFpc2VkIGlmIHRoZSA8Y29kZT5xdWFsaWZpZWROYW1lPC9jb2RlPiBpcyBhCi0gICAgICogICBtYWxmb3JtZWQgcXVhbGlmaWVkIG5hbWUsIGlmIHRoZSA8Y29kZT5xdWFsaWZpZWROYW1lPC9jb2RlPiBoYXMgYQotICAgICAqICAgcHJlZml4IGFuZCB0aGUgPGNvZGU+bmFtZXNwYWNlVVJJPC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPiwgb3IKLSAgICAgKiAgIGlmIHRoZSA8Y29kZT5xdWFsaWZpZWROYW1lPC9jb2RlPiBoYXMgYSBwcmVmaXggdGhhdCBpcyAieG1sIiBhbmQKLSAgICAgKiAgIHRoZSA8Y29kZT5uYW1lc3BhY2VVUkk8L2NvZGU+IGlzIGRpZmZlcmVudCBmcm9tICI8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9YTUwvMTk5OC9uYW1lc3BhY2UnPgotICAgICAqICAgaHR0cDovL3d3dy53My5vcmcvWE1MLzE5OTgvbmFtZXNwYWNlPC9hPiIgWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzE5OTkvUkVDLXhtbC1uYW1lcy0xOTk5MDExNC8nPlhNTCBOYW1lc3BhY2VzPC9hPl0KLSAgICAgKiAgIC4gQWxzbyByYWlzZWQsIHdoZW4gdGhlIG5vZGUgYmVpbmcgcmVuYW1lZCBpcyBhbiBhdHRyaWJ1dGUsIGlmIHRoZQotICAgICAqICAgPGNvZGU+cXVhbGlmaWVkTmFtZTwvY29kZT4sIG9yIGl0cyBwcmVmaXgsIGlzICJ4bWxucyIgYW5kIHRoZQotICAgICAqICAgPGNvZGU+bmFtZXNwYWNlVVJJPC9jb2RlPiBpcyBkaWZmZXJlbnQgZnJvbSAiPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvMjAwMC94bWxucy8nPmh0dHA6Ly93d3cudzMub3JnLzIwMDAveG1sbnMvPC9hPiIuCi0gICAgICogQHNpbmNlIERPTSBMZXZlbCAzCi0gICAgICovCi0gICAgcHVibGljIE5vZGUgcmVuYW1lTm9kZShOb2RlIG4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbmFtZXNwYWNlVVJJLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHF1YWxpZmllZE5hbWUpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL3czYy9kb20vRG9jdW1lbnRGcmFnbWVudC5qYXZhIGIvc3JjL29yZy93M2MvZG9tL0RvY3VtZW50RnJhZ21lbnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDFjMzVlZi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3czYy9kb20vRG9jdW1lbnRGcmFnbWVudC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsODIgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIFRoaXMgZmlsZSBpcyBhdmFpbGFibGUgdW5kZXIgYW5kIGdvdmVybmVkIGJ5IHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKLSAqIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICogSG93ZXZlciwgdGhlIGZvbGxvd2luZyBub3RpY2UgYWNjb21wYW5pZWQgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcwotICogZmlsZSBhbmQsIHBlciBpdHMgdGVybXMsIHNob3VsZCBub3QgYmUgcmVtb3ZlZDoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKLSAqCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgRXVyb3BlYW4gUmVzZWFyY2ggQ29uc29ydGl1bSBmb3IKLSAqIEluZm9ybWF0aWNzIGFuZCBNYXRoZW1hdGljcywgS2VpbyBVbml2ZXJzaXR5KS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcwotICogd29yayBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDKHIpIFNvZnR3YXJlIExpY2Vuc2UgWzFdIGluIHRoZSBob3BlIHRoYXQKLSAqIGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZAotICogd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLgotICoKLSAqIFsxXSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLzIwMDIvY29weXJpZ2h0LXNvZnR3YXJlLTIwMDIxMjMxCi0gKi8KLQotcGFja2FnZSBvcmcudzNjLmRvbTsKLQotLyoqCi0gKiA8Y29kZT5Eb2N1bWVudEZyYWdtZW50PC9jb2RlPiBpcyBhICJsaWdodHdlaWdodCIgb3IgIm1pbmltYWwiCi0gKiA8Y29kZT5Eb2N1bWVudDwvY29kZT4gb2JqZWN0LiBJdCBpcyB2ZXJ5IGNvbW1vbiB0byB3YW50IHRvIGJlIGFibGUgdG8KLSAqIGV4dHJhY3QgYSBwb3J0aW9uIG9mIGEgZG9jdW1lbnQncyB0cmVlIG9yIHRvIGNyZWF0ZSBhIG5ldyBmcmFnbWVudCBvZiBhCi0gKiBkb2N1bWVudC4gSW1hZ2luZSBpbXBsZW1lbnRpbmcgYSB1c2VyIGNvbW1hbmQgbGlrZSBjdXQgb3IgcmVhcnJhbmdpbmcgYQotICogZG9jdW1lbnQgYnkgbW92aW5nIGZyYWdtZW50cyBhcm91bmQuIEl0IGlzIGRlc2lyYWJsZSB0byBoYXZlIGFuIG9iamVjdAotICogd2hpY2ggY2FuIGhvbGQgc3VjaCBmcmFnbWVudHMgYW5kIGl0IGlzIHF1aXRlIG5hdHVyYWwgdG8gdXNlIGEgTm9kZSBmb3IKLSAqIHRoaXMgcHVycG9zZS4gV2hpbGUgaXQgaXMgdHJ1ZSB0aGF0IGEgPGNvZGU+RG9jdW1lbnQ8L2NvZGU+IG9iamVjdCBjb3VsZAotICogZnVsZmlsbCB0aGlzIHJvbGUsIGEgPGNvZGU+RG9jdW1lbnQ8L2NvZGU+IG9iamVjdCBjYW4gcG90ZW50aWFsbHkgYmUgYQotICogaGVhdnl3ZWlnaHQgb2JqZWN0LCBkZXBlbmRpbmcgb24gdGhlIHVuZGVybHlpbmcgaW1wbGVtZW50YXRpb24uIFdoYXQgaXMKLSAqIHJlYWxseSBuZWVkZWQgZm9yIHRoaXMgaXMgYSB2ZXJ5IGxpZ2h0d2VpZ2h0IG9iamVjdC4KLSAqIDxjb2RlPkRvY3VtZW50RnJhZ21lbnQ8L2NvZGU+IGlzIHN1Y2ggYW4gb2JqZWN0LgotICogPHA+RnVydGhlcm1vcmUsIHZhcmlvdXMgb3BlcmF0aW9ucyAtLSBzdWNoIGFzIGluc2VydGluZyBub2RlcyBhcyBjaGlsZHJlbgotICogb2YgYW5vdGhlciA8Y29kZT5Ob2RlPC9jb2RlPiAtLSBtYXkgdGFrZSA8Y29kZT5Eb2N1bWVudEZyYWdtZW50PC9jb2RlPgotICogb2JqZWN0cyBhcyBhcmd1bWVudHM7IHRoaXMgcmVzdWx0cyBpbiBhbGwgdGhlIGNoaWxkIG5vZGVzIG9mIHRoZQotICogPGNvZGU+RG9jdW1lbnRGcmFnbWVudDwvY29kZT4gYmVpbmcgbW92ZWQgdG8gdGhlIGNoaWxkIGxpc3Qgb2YgdGhpcyBub2RlLgotICogPHA+VGhlIGNoaWxkcmVuIG9mIGEgPGNvZGU+RG9jdW1lbnRGcmFnbWVudDwvY29kZT4gbm9kZSBhcmUgemVybyBvciBtb3JlCi0gKiBub2RlcyByZXByZXNlbnRpbmcgdGhlIHRvcHMgb2YgYW55IHN1Yi10cmVlcyBkZWZpbmluZyB0aGUgc3RydWN0dXJlIG9mCi0gKiB0aGUgZG9jdW1lbnQuIDxjb2RlPkRvY3VtZW50RnJhZ21lbnQ8L2NvZGU+IG5vZGVzIGRvIG5vdCBuZWVkIHRvIGJlCi0gKiB3ZWxsLWZvcm1lZCBYTUwgZG9jdW1lbnRzIChhbHRob3VnaCB0aGV5IGRvIG5lZWQgdG8gZm9sbG93IHRoZSBydWxlcwotICogaW1wb3NlZCB1cG9uIHdlbGwtZm9ybWVkIFhNTCBwYXJzZWQgZW50aXRpZXMsIHdoaWNoIGNhbiBoYXZlIG11bHRpcGxlIHRvcAotICogbm9kZXMpLiBGb3IgZXhhbXBsZSwgYSA8Y29kZT5Eb2N1bWVudEZyYWdtZW50PC9jb2RlPiBtaWdodCBoYXZlIG9ubHkgb25lCi0gKiBjaGlsZCBhbmQgdGhhdCBjaGlsZCBub2RlIGNvdWxkIGJlIGEgPGNvZGU+VGV4dDwvY29kZT4gbm9kZS4gU3VjaCBhCi0gKiBzdHJ1Y3R1cmUgbW9kZWwgcmVwcmVzZW50cyBuZWl0aGVyIGFuIEhUTUwgZG9jdW1lbnQgbm9yIGEgd2VsbC1mb3JtZWQgWE1MCi0gKiBkb2N1bWVudC4KLSAqIDxwPldoZW4gYSA8Y29kZT5Eb2N1bWVudEZyYWdtZW50PC9jb2RlPiBpcyBpbnNlcnRlZCBpbnRvIGEKLSAqIDxjb2RlPkRvY3VtZW50PC9jb2RlPiAob3IgaW5kZWVkIGFueSBvdGhlciA8Y29kZT5Ob2RlPC9jb2RlPiB0aGF0IG1heQotICogdGFrZSBjaGlsZHJlbikgdGhlIGNoaWxkcmVuIG9mIHRoZSA8Y29kZT5Eb2N1bWVudEZyYWdtZW50PC9jb2RlPiBhbmQgbm90Ci0gKiB0aGUgPGNvZGU+RG9jdW1lbnRGcmFnbWVudDwvY29kZT4gaXRzZWxmIGFyZSBpbnNlcnRlZCBpbnRvIHRoZQotICogPGNvZGU+Tm9kZTwvY29kZT4uIFRoaXMgbWFrZXMgdGhlIDxjb2RlPkRvY3VtZW50RnJhZ21lbnQ8L2NvZGU+IHZlcnkKLSAqIHVzZWZ1bCB3aGVuIHRoZSB1c2VyIHdpc2hlcyB0byBjcmVhdGUgbm9kZXMgdGhhdCBhcmUgc2libGluZ3M7IHRoZQotICogPGNvZGU+RG9jdW1lbnRGcmFnbWVudDwvY29kZT4gYWN0cyBhcyB0aGUgcGFyZW50IG9mIHRoZXNlIG5vZGVzIHNvIHRoYXQKLSAqIHRoZSB1c2VyIGNhbiB1c2UgdGhlIHN0YW5kYXJkIG1ldGhvZHMgZnJvbSB0aGUgPGNvZGU+Tm9kZTwvY29kZT4KLSAqIGludGVyZmFjZSwgc3VjaCBhcyA8Y29kZT5Ob2RlLmluc2VydEJlZm9yZTwvY29kZT4gYW5kCi0gKiA8Y29kZT5Ob2RlLmFwcGVuZENoaWxkPC9jb2RlPi4KLSAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy1ET00tTGV2ZWwtMy1Db3JlLTIwMDQwNDA3Jz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMyBDb3JlIFNwZWNpZmljYXRpb248L2E+LgotICovCi1wdWJsaWMgaW50ZXJmYWNlIERvY3VtZW50RnJhZ21lbnQgZXh0ZW5kcyBOb2RlIHsKLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvdzNjL2RvbS9Eb2N1bWVudFR5cGUuamF2YSBiL3NyYy9vcmcvdzNjL2RvbS9Eb2N1bWVudFR5cGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggM2I2ODdlMy4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3czYy9kb20vRG9jdW1lbnRUeXBlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMTIgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIFRoaXMgZmlsZSBpcyBhdmFpbGFibGUgdW5kZXIgYW5kIGdvdmVybmVkIGJ5IHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKLSAqIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICogSG93ZXZlciwgdGhlIGZvbGxvd2luZyBub3RpY2UgYWNjb21wYW5pZWQgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcwotICogZmlsZSBhbmQsIHBlciBpdHMgdGVybXMsIHNob3VsZCBub3QgYmUgcmVtb3ZlZDoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKLSAqCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgRXVyb3BlYW4gUmVzZWFyY2ggQ29uc29ydGl1bSBmb3IKLSAqIEluZm9ybWF0aWNzIGFuZCBNYXRoZW1hdGljcywgS2VpbyBVbml2ZXJzaXR5KS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcwotICogd29yayBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDKHIpIFNvZnR3YXJlIExpY2Vuc2UgWzFdIGluIHRoZSBob3BlIHRoYXQKLSAqIGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZAotICogd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLgotICoKLSAqIFsxXSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLzIwMDIvY29weXJpZ2h0LXNvZnR3YXJlLTIwMDIxMjMxCi0gKi8KLQotcGFja2FnZSBvcmcudzNjLmRvbTsKLQotLyoqCi0gKiBFYWNoIDxjb2RlPkRvY3VtZW50PC9jb2RlPiBoYXMgYSA8Y29kZT5kb2N0eXBlPC9jb2RlPiBhdHRyaWJ1dGUgd2hvc2UgdmFsdWUKLSAqIGlzIGVpdGhlciA8Y29kZT5udWxsPC9jb2RlPiBvciBhIDxjb2RlPkRvY3VtZW50VHlwZTwvY29kZT4gb2JqZWN0LiBUaGUKLSAqIDxjb2RlPkRvY3VtZW50VHlwZTwvY29kZT4gaW50ZXJmYWNlIGluIHRoZSBET00gQ29yZSBwcm92aWRlcyBhbiBpbnRlcmZhY2UKLSAqIHRvIHRoZSBsaXN0IG9mIGVudGl0aWVzIHRoYXQgYXJlIGRlZmluZWQgZm9yIHRoZSBkb2N1bWVudCwgYW5kIGxpdHRsZQotICogZWxzZSBiZWNhdXNlIHRoZSBlZmZlY3Qgb2YgbmFtZXNwYWNlcyBhbmQgdGhlIHZhcmlvdXMgWE1MIHNjaGVtYSBlZmZvcnRzCi0gKiBvbiBEVEQgcmVwcmVzZW50YXRpb24gYXJlIG5vdCBjbGVhcmx5IHVuZGVyc3Rvb2QgYXMgb2YgdGhpcyB3cml0aW5nLgotICogPHA+RE9NIExldmVsIDMgZG9lc24ndCBzdXBwb3J0IGVkaXRpbmcgPGNvZGU+RG9jdW1lbnRUeXBlPC9jb2RlPiBub2Rlcy4KLSAqIDxjb2RlPkRvY3VtZW50VHlwZTwvY29kZT4gbm9kZXMgYXJlIHJlYWQtb25seS4KLSAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy1ET00tTGV2ZWwtMy1Db3JlLTIwMDQwNDA3Jz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMyBDb3JlIFNwZWNpZmljYXRpb248L2E+LgotICovCi1wdWJsaWMgaW50ZXJmYWNlIERvY3VtZW50VHlwZSBleHRlbmRzIE5vZGUgewotICAgIC8qKgotICAgICAqIFRoZSBuYW1lIG9mIERURDsgaS5lLiwgdGhlIG5hbWUgaW1tZWRpYXRlbHkgZm9sbG93aW5nIHRoZQotICAgICAqIDxjb2RlPkRPQ1RZUEU8L2NvZGU+IGtleXdvcmQuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXROYW1lKCk7Ci0KLSAgICAvKioKLSAgICAgKiBBIDxjb2RlPk5hbWVkTm9kZU1hcDwvY29kZT4gY29udGFpbmluZyB0aGUgZ2VuZXJhbCBlbnRpdGllcywgYm90aAotICAgICAqIGV4dGVybmFsIGFuZCBpbnRlcm5hbCwgZGVjbGFyZWQgaW4gdGhlIERURC4gUGFyYW1ldGVyIGVudGl0aWVzIGFyZQotICAgICAqIG5vdCBjb250YWluZWQuIER1cGxpY2F0ZXMgYXJlIGRpc2NhcmRlZC4gRm9yIGV4YW1wbGUgaW46Ci0gICAgICogPHByZT4mbHQ7IURPQ1RZUEUKLSAgICAgKiBleCBTWVNURU0gImV4LmR0ZCIgWyAmbHQ7IUVOVElUWSBmb28gImZvbyImZ3Q7ICZsdDshRU5USVRZIGJhcgotICAgICAqICJiYXIiJmd0OyAmbHQ7IUVOVElUWSBiYXIgImJhcjIiJmd0OyAmbHQ7IUVOVElUWSAlIGJheiAiYmF6IiZndDsKLSAgICAgKiBdJmd0OyAmbHQ7ZXgvJmd0OzwvcHJlPgotICAgICAqICB0aGUgaW50ZXJmYWNlIHByb3ZpZGVzIGFjY2VzcyB0byA8Y29kZT5mb288L2NvZGU+Ci0gICAgICogYW5kIHRoZSBmaXJzdCBkZWNsYXJhdGlvbiBvZiA8Y29kZT5iYXI8L2NvZGU+IGJ1dCBub3QgdGhlIHNlY29uZAotICAgICAqIGRlY2xhcmF0aW9uIG9mIDxjb2RlPmJhcjwvY29kZT4gb3IgPGNvZGU+YmF6PC9jb2RlPi4gRXZlcnkgbm9kZSBpbgotICAgICAqIHRoaXMgbWFwIGFsc28gaW1wbGVtZW50cyB0aGUgPGNvZGU+RW50aXR5PC9jb2RlPiBpbnRlcmZhY2UuCi0gICAgICogPGJyPlRoZSBET00gTGV2ZWwgMiBkb2VzIG5vdCBzdXBwb3J0IGVkaXRpbmcgZW50aXRpZXMsIHRoZXJlZm9yZQotICAgICAqIDxjb2RlPmVudGl0aWVzPC9jb2RlPiBjYW5ub3QgYmUgYWx0ZXJlZCBpbiBhbnkgd2F5LgotICAgICAqLwotICAgIHB1YmxpYyBOYW1lZE5vZGVNYXAgZ2V0RW50aXRpZXMoKTsKLQotICAgIC8qKgotICAgICAqIEEgPGNvZGU+TmFtZWROb2RlTWFwPC9jb2RlPiBjb250YWluaW5nIHRoZSBub3RhdGlvbnMgZGVjbGFyZWQgaW4gdGhlCi0gICAgICogRFRELiBEdXBsaWNhdGVzIGFyZSBkaXNjYXJkZWQuIEV2ZXJ5IG5vZGUgaW4gdGhpcyBtYXAgYWxzbyBpbXBsZW1lbnRzCi0gICAgICogdGhlIDxjb2RlPk5vdGF0aW9uPC9jb2RlPiBpbnRlcmZhY2UuCi0gICAgICogPGJyPlRoZSBET00gTGV2ZWwgMiBkb2VzIG5vdCBzdXBwb3J0IGVkaXRpbmcgbm90YXRpb25zLCB0aGVyZWZvcmUKLSAgICAgKiA8Y29kZT5ub3RhdGlvbnM8L2NvZGU+IGNhbm5vdCBiZSBhbHRlcmVkIGluIGFueSB3YXkuCi0gICAgICovCi0gICAgcHVibGljIE5hbWVkTm9kZU1hcCBnZXROb3RhdGlvbnMoKTsKLQotICAgIC8qKgotICAgICAqIFRoZSBwdWJsaWMgaWRlbnRpZmllciBvZiB0aGUgZXh0ZXJuYWwgc3Vic2V0LgotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0UHVibGljSWQoKTsKLQotICAgIC8qKgotICAgICAqIFRoZSBzeXN0ZW0gaWRlbnRpZmllciBvZiB0aGUgZXh0ZXJuYWwgc3Vic2V0LiBUaGlzIG1heSBiZSBhbiBhYnNvbHV0ZQotICAgICAqIFVSSSBvciBub3QuCi0gICAgICogQHNpbmNlIERPTSBMZXZlbCAyCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRTeXN0ZW1JZCgpOwotCi0gICAgLyoqCi0gICAgICogVGhlIGludGVybmFsIHN1YnNldCBhcyBhIHN0cmluZywgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlcmUgaXMgbm9uZS4KLSAgICAgKiBUaGlzIGlzIGRvZXMgbm90IGNvbnRhaW4gdGhlIGRlbGltaXRpbmcgc3F1YXJlIGJyYWNrZXRzLgotICAgICAqIDxwID48Yj5Ob3RlOjwvYj4gVGhlIGFjdHVhbCBjb250ZW50IHJldHVybmVkIGRlcGVuZHMgb24gaG93IG11Y2gKLSAgICAgKiBpbmZvcm1hdGlvbiBpcyBhdmFpbGFibGUgdG8gdGhlIGltcGxlbWVudGF0aW9uLiBUaGlzIG1heSB2YXJ5Ci0gICAgICogZGVwZW5kaW5nIG9uIHZhcmlvdXMgcGFyYW1ldGVycywgaW5jbHVkaW5nIHRoZSBYTUwgcHJvY2Vzc29yIHVzZWQgdG8KLSAgICAgKiBidWlsZCB0aGUgZG9jdW1lbnQuCi0gICAgICogQHNpbmNlIERPTSBMZXZlbCAyCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRJbnRlcm5hbFN1YnNldCgpOwotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL3czYy9kb20vRWxlbWVudC5qYXZhIGIvc3JjL29yZy93M2MvZG9tL0VsZW1lbnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMTk1YzcxZi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3czYy9kb20vRWxlbWVudC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDY4ICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBUaGlzIGZpbGUgaXMgYXZhaWxhYmxlIHVuZGVyIGFuZCBnb3Zlcm5lZCBieSB0aGUgR05VIEdlbmVyYWwgUHVibGljCi0gKiBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqIEhvd2V2ZXIsIHRoZSBmb2xsb3dpbmcgbm90aWNlIGFjY29tcGFuaWVkIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIG9mIHRoaXMKLSAqIGZpbGUgYW5kLCBwZXIgaXRzIHRlcm1zLCBzaG91bGQgbm90IGJlIHJlbW92ZWQ6Ci0gKgotICogQ29weXJpZ2h0IChjKSAyMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCi0gKgotICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEV1cm9wZWFuIFJlc2VhcmNoIENvbnNvcnRpdW0gZm9yCi0gKiBJbmZvcm1hdGljcyBhbmQgTWF0aGVtYXRpY3MsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMKLSAqIHdvcmsgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQyhyKSBTb2Z0d2FyZSBMaWNlbnNlIFsxXSBpbiB0aGUgaG9wZSB0aGF0Ci0gKiBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQKLSAqIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4KLSAqCi0gKiBbMV0gaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8yMDAyL2NvcHlyaWdodC1zb2Z0d2FyZS0yMDAyMTIzMQotICovCi0KLXBhY2thZ2Ugb3JnLnczYy5kb207Ci0KLS8qKgotICogVGhlIDxjb2RlPkVsZW1lbnQ8L2NvZGU+IGludGVyZmFjZSByZXByZXNlbnRzIGFuIGVsZW1lbnQgaW4gYW4gSFRNTCBvciBYTUwKLSAqIGRvY3VtZW50LiBFbGVtZW50cyBtYXkgaGF2ZSBhdHRyaWJ1dGVzIGFzc29jaWF0ZWQgd2l0aCB0aGVtOyBzaW5jZSB0aGUKLSAqIDxjb2RlPkVsZW1lbnQ8L2NvZGU+IGludGVyZmFjZSBpbmhlcml0cyBmcm9tIDxjb2RlPk5vZGU8L2NvZGU+LCB0aGUKLSAqIGdlbmVyaWMgPGNvZGU+Tm9kZTwvY29kZT4gaW50ZXJmYWNlIGF0dHJpYnV0ZSA8Y29kZT5hdHRyaWJ1dGVzPC9jb2RlPiBtYXkKLSAqIGJlIHVzZWQgdG8gcmV0cmlldmUgdGhlIHNldCBvZiBhbGwgYXR0cmlidXRlcyBmb3IgYW4gZWxlbWVudC4gVGhlcmUgYXJlCi0gKiBtZXRob2RzIG9uIHRoZSA8Y29kZT5FbGVtZW50PC9jb2RlPiBpbnRlcmZhY2UgdG8gcmV0cmlldmUgZWl0aGVyIGFuCi0gKiA8Y29kZT5BdHRyPC9jb2RlPiBvYmplY3QgYnkgbmFtZSBvciBhbiBhdHRyaWJ1dGUgdmFsdWUgYnkgbmFtZS4gSW4gWE1MLAotICogd2hlcmUgYW4gYXR0cmlidXRlIHZhbHVlIG1heSBjb250YWluIGVudGl0eSByZWZlcmVuY2VzLCBhbgotICogPGNvZGU+QXR0cjwvY29kZT4gb2JqZWN0IHNob3VsZCBiZSByZXRyaWV2ZWQgdG8gZXhhbWluZSB0aGUgcG9zc2libHkKLSAqIGZhaXJseSBjb21wbGV4IHN1Yi10cmVlIHJlcHJlc2VudGluZyB0aGUgYXR0cmlidXRlIHZhbHVlLiBPbiB0aGUgb3RoZXIKLSAqIGhhbmQsIGluIEhUTUwsIHdoZXJlIGFsbCBhdHRyaWJ1dGVzIGhhdmUgc2ltcGxlIHN0cmluZyB2YWx1ZXMsIG1ldGhvZHMgdG8KLSAqIGRpcmVjdGx5IGFjY2VzcyBhbiBhdHRyaWJ1dGUgdmFsdWUgY2FuIHNhZmVseSBiZSB1c2VkIGFzIGEgY29udmVuaWVuY2UuCi0gKiA8cCA+PGI+Tm90ZTo8L2I+IEluIERPTSBMZXZlbCAyLCB0aGUgbWV0aG9kIDxjb2RlPm5vcm1hbGl6ZTwvY29kZT4gaXMKLSAqIGluaGVyaXRlZCBmcm9tIHRoZSA8Y29kZT5Ob2RlPC9jb2RlPiBpbnRlcmZhY2Ugd2hlcmUgaXQgd2FzIG1vdmVkLgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLURPTS1MZXZlbC0zLUNvcmUtMjAwNDA0MDcnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAzIENvcmUgU3BlY2lmaWNhdGlvbjwvYT4uCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgRWxlbWVudCBleHRlbmRzIE5vZGUgewotICAgIC8qKgotICAgICAqIFRoZSBuYW1lIG9mIHRoZSBlbGVtZW50LiBJZiA8Y29kZT5Ob2RlLmxvY2FsTmFtZTwvY29kZT4gaXMgZGlmZmVyZW50Ci0gICAgICogZnJvbSA8Y29kZT5udWxsPC9jb2RlPiwgdGhpcyBhdHRyaWJ1dGUgaXMgYSBxdWFsaWZpZWQgbmFtZS4gRm9yCi0gICAgICogZXhhbXBsZSwgaW46Ci0gICAgICogPHByZT4gJmx0O2VsZW1lbnRFeGFtcGxlIGlkPSJkZW1vIiZndDsgLi4uCi0gICAgICogJmx0Oy9lbGVtZW50RXhhbXBsZSZndDsgLCA8L3ByZT4KLSAgICAgKiAgPGNvZGU+dGFnTmFtZTwvY29kZT4gaGFzIHRoZSB2YWx1ZQotICAgICAqIDxjb2RlPiJlbGVtZW50RXhhbXBsZSI8L2NvZGU+LiBOb3RlIHRoYXQgdGhpcyBpcyBjYXNlLXByZXNlcnZpbmcgaW4KLSAgICAgKiBYTUwsIGFzIGFyZSBhbGwgb2YgdGhlIG9wZXJhdGlvbnMgb2YgdGhlIERPTS4gVGhlIEhUTUwgRE9NIHJldHVybnMKLSAgICAgKiB0aGUgPGNvZGU+dGFnTmFtZTwvY29kZT4gb2YgYW4gSFRNTCBlbGVtZW50IGluIHRoZSBjYW5vbmljYWwKLSAgICAgKiB1cHBlcmNhc2UgZm9ybSwgcmVnYXJkbGVzcyBvZiB0aGUgY2FzZSBpbiB0aGUgc291cmNlIEhUTUwgZG9jdW1lbnQuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRUYWdOYW1lKCk7Ci0KLSAgICAvKioKLSAgICAgKiBSZXRyaWV2ZXMgYW4gYXR0cmlidXRlIHZhbHVlIGJ5IG5hbWUuCi0gICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZSB0byByZXRyaWV2ZS4KLSAgICAgKiBAcmV0dXJuIFRoZSA8Y29kZT5BdHRyPC9jb2RlPiB2YWx1ZSBhcyBhIHN0cmluZywgb3IgdGhlIGVtcHR5IHN0cmluZwotICAgICAqICAgaWYgdGhhdCBhdHRyaWJ1dGUgZG9lcyBub3QgaGF2ZSBhIHNwZWNpZmllZCBvciBkZWZhdWx0IHZhbHVlLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0QXR0cmlidXRlKFN0cmluZyBuYW1lKTsKLQotICAgIC8qKgotICAgICAqIEFkZHMgYSBuZXcgYXR0cmlidXRlLiBJZiBhbiBhdHRyaWJ1dGUgd2l0aCB0aGF0IG5hbWUgaXMgYWxyZWFkeSBwcmVzZW50Ci0gICAgICogaW4gdGhlIGVsZW1lbnQsIGl0cyB2YWx1ZSBpcyBjaGFuZ2VkIHRvIGJlIHRoYXQgb2YgdGhlIHZhbHVlCi0gICAgICogcGFyYW1ldGVyLiBUaGlzIHZhbHVlIGlzIGEgc2ltcGxlIHN0cmluZzsgaXQgaXMgbm90IHBhcnNlZCBhcyBpdCBpcwotICAgICAqIGJlaW5nIHNldC4gU28gYW55IG1hcmt1cCAoc3VjaCBhcyBzeW50YXggdG8gYmUgcmVjb2duaXplZCBhcyBhbgotICAgICAqIGVudGl0eSByZWZlcmVuY2UpIGlzIHRyZWF0ZWQgYXMgbGl0ZXJhbCB0ZXh0LCBhbmQgbmVlZHMgdG8gYmUKLSAgICAgKiBhcHByb3ByaWF0ZWx5IGVzY2FwZWQgYnkgdGhlIGltcGxlbWVudGF0aW9uIHdoZW4gaXQgaXMgd3JpdHRlbiBvdXQuCi0gICAgICogSW4gb3JkZXIgdG8gYXNzaWduIGFuIGF0dHJpYnV0ZSB2YWx1ZSB0aGF0IGNvbnRhaW5zIGVudGl0eQotICAgICAqIHJlZmVyZW5jZXMsIHRoZSB1c2VyIG11c3QgY3JlYXRlIGFuIDxjb2RlPkF0dHI8L2NvZGU+IG5vZGUgcGx1cyBhbnkKLSAgICAgKiA8Y29kZT5UZXh0PC9jb2RlPiBhbmQgPGNvZGU+RW50aXR5UmVmZXJlbmNlPC9jb2RlPiBub2RlcywgYnVpbGQgdGhlCi0gICAgICogYXBwcm9wcmlhdGUgc3VidHJlZSwgYW5kIHVzZSA8Y29kZT5zZXRBdHRyaWJ1dGVOb2RlPC9jb2RlPiB0byBhc3NpZ24KLSAgICAgKiBpdCBhcyB0aGUgdmFsdWUgb2YgYW4gYXR0cmlidXRlLgotICAgICAqIDxicj5UbyBzZXQgYW4gYXR0cmlidXRlIHdpdGggYSBxdWFsaWZpZWQgbmFtZSBhbmQgbmFtZXNwYWNlIFVSSSwgdXNlCi0gICAgICogdGhlIDxjb2RlPnNldEF0dHJpYnV0ZU5TPC9jb2RlPiBtZXRob2QuCi0gICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZSB0byBjcmVhdGUgb3IgYWx0ZXIuCi0gICAgICogQHBhcmFtIHZhbHVlIFZhbHVlIHRvIHNldCBpbiBzdHJpbmcgZm9ybS4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgSU5WQUxJRF9DSEFSQUNURVJfRVJSOiBSYWlzZWQgaWYgdGhlIHNwZWNpZmllZCBuYW1lIGlzIG5vdCBhbiBYTUwKLSAgICAgKiAgIG5hbWUgYWNjb3JkaW5nIHRvIHRoZSBYTUwgdmVyc2lvbiBpbiB1c2Ugc3BlY2lmaWVkIGluIHRoZQotICAgICAqICAgPGNvZGU+RG9jdW1lbnQueG1sVmVyc2lvbjwvY29kZT4gYXR0cmlidXRlLgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgbm9kZSBpcyByZWFkb25seS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRBdHRyaWJ1dGUoU3RyaW5nIG5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyB2YWx1ZSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIFJlbW92ZXMgYW4gYXR0cmlidXRlIGJ5IG5hbWUuIElmIGEgZGVmYXVsdCB2YWx1ZSBmb3IgdGhlIHJlbW92ZWQKLSAgICAgKiBhdHRyaWJ1dGUgaXMgZGVmaW5lZCBpbiB0aGUgRFRELCBhIG5ldyBhdHRyaWJ1dGUgaW1tZWRpYXRlbHkgYXBwZWFycwotICAgICAqIHdpdGggdGhlIGRlZmF1bHQgdmFsdWUgYXMgd2VsbCBhcyB0aGUgY29ycmVzcG9uZGluZyBuYW1lc3BhY2UgVVJJLAotICAgICAqIGxvY2FsIG5hbWUsIGFuZCBwcmVmaXggd2hlbiBhcHBsaWNhYmxlLiBUaGUgaW1wbGVtZW50YXRpb24gbWF5IGhhbmRsZQotICAgICAqIGRlZmF1bHQgdmFsdWVzIGZyb20gb3RoZXIgc2NoZW1hcyBzaW1pbGFybHkgYnV0IGFwcGxpY2F0aW9ucyBzaG91bGQKLSAgICAgKiB1c2UgPGNvZGU+RG9jdW1lbnQubm9ybWFsaXplRG9jdW1lbnQoKTwvY29kZT4gdG8gZ3VhcmFudGVlIHRoaXMKLSAgICAgKiBpbmZvcm1hdGlvbiBpcyB1cC10by1kYXRlLgotICAgICAqIDxicj5JZiBubyBhdHRyaWJ1dGUgd2l0aCB0aGlzIG5hbWUgaXMgZm91bmQsIHRoaXMgbWV0aG9kIGhhcyBubyBlZmZlY3QuCi0gICAgICogPGJyPlRvIHJlbW92ZSBhbiBhdHRyaWJ1dGUgYnkgbG9jYWwgbmFtZSBhbmQgbmFtZXNwYWNlIFVSSSwgdXNlIHRoZQotICAgICAqIDxjb2RlPnJlbW92ZUF0dHJpYnV0ZU5TPC9jb2RlPiBtZXRob2QuCi0gICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZSB0byByZW1vdmUuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgbm9kZSBpcyByZWFkb25seS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCByZW1vdmVBdHRyaWJ1dGUoU3RyaW5nIG5hbWUpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBSZXRyaWV2ZXMgYW4gYXR0cmlidXRlIG5vZGUgYnkgbmFtZS4KLSAgICAgKiA8YnI+VG8gcmV0cmlldmUgYW4gYXR0cmlidXRlIG5vZGUgYnkgcXVhbGlmaWVkIG5hbWUgYW5kIG5hbWVzcGFjZSBVUkksCi0gICAgICogdXNlIHRoZSA8Y29kZT5nZXRBdHRyaWJ1dGVOb2RlTlM8L2NvZGU+IG1ldGhvZC4KLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSAoPGNvZGU+bm9kZU5hbWU8L2NvZGU+KSBvZiB0aGUgYXR0cmlidXRlIHRvCi0gICAgICogICByZXRyaWV2ZS4KLSAgICAgKiBAcmV0dXJuIFRoZSA8Y29kZT5BdHRyPC9jb2RlPiBub2RlIHdpdGggdGhlIHNwZWNpZmllZCBuYW1lICgKLSAgICAgKiAgIDxjb2RlPm5vZGVOYW1lPC9jb2RlPikgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlcmUgaXMgbm8gc3VjaAotICAgICAqICAgYXR0cmlidXRlLgotICAgICAqLwotICAgIHB1YmxpYyBBdHRyIGdldEF0dHJpYnV0ZU5vZGUoU3RyaW5nIG5hbWUpOwotCi0gICAgLyoqCi0gICAgICogQWRkcyBhIG5ldyBhdHRyaWJ1dGUgbm9kZS4gSWYgYW4gYXR0cmlidXRlIHdpdGggdGhhdCBuYW1lICgKLSAgICAgKiA8Y29kZT5ub2RlTmFtZTwvY29kZT4pIGlzIGFscmVhZHkgcHJlc2VudCBpbiB0aGUgZWxlbWVudCwgaXQgaXMKLSAgICAgKiByZXBsYWNlZCBieSB0aGUgbmV3IG9uZS4gUmVwbGFjaW5nIGFuIGF0dHJpYnV0ZSBub2RlIGJ5IGl0c2VsZiBoYXMgbm8KLSAgICAgKiBlZmZlY3QuCi0gICAgICogPGJyPlRvIGFkZCBhIG5ldyBhdHRyaWJ1dGUgbm9kZSB3aXRoIGEgcXVhbGlmaWVkIG5hbWUgYW5kIG5hbWVzcGFjZQotICAgICAqIFVSSSwgdXNlIHRoZSA8Y29kZT5zZXRBdHRyaWJ1dGVOb2RlTlM8L2NvZGU+IG1ldGhvZC4KLSAgICAgKiBAcGFyYW0gbmV3QXR0ciBUaGUgPGNvZGU+QXR0cjwvY29kZT4gbm9kZSB0byBhZGQgdG8gdGhlIGF0dHJpYnV0ZSBsaXN0LgotICAgICAqIEByZXR1cm4gSWYgdGhlIDxjb2RlPm5ld0F0dHI8L2NvZGU+IGF0dHJpYnV0ZSByZXBsYWNlcyBhbiBleGlzdGluZwotICAgICAqICAgYXR0cmlidXRlLCB0aGUgcmVwbGFjZWQgPGNvZGU+QXR0cjwvY29kZT4gbm9kZSBpcyByZXR1cm5lZCwKLSAgICAgKiAgIG90aGVyd2lzZSA8Y29kZT5udWxsPC9jb2RlPiBpcyByZXR1cm5lZC4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgV1JPTkdfRE9DVU1FTlRfRVJSOiBSYWlzZWQgaWYgPGNvZGU+bmV3QXR0cjwvY29kZT4gd2FzIGNyZWF0ZWQgZnJvbSBhCi0gICAgICogICBkaWZmZXJlbnQgZG9jdW1lbnQgdGhhbiB0aGUgb25lIHRoYXQgY3JlYXRlZCB0aGUgZWxlbWVudC4KLSAgICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIG5vZGUgaXMgcmVhZG9ubHkuCi0gICAgICogICA8YnI+SU5VU0VfQVRUUklCVVRFX0VSUjogUmFpc2VkIGlmIDxjb2RlPm5ld0F0dHI8L2NvZGU+IGlzIGFscmVhZHkgYW4KLSAgICAgKiAgIGF0dHJpYnV0ZSBvZiBhbm90aGVyIDxjb2RlPkVsZW1lbnQ8L2NvZGU+IG9iamVjdC4gVGhlIERPTSB1c2VyIG11c3QKLSAgICAgKiAgIGV4cGxpY2l0bHkgY2xvbmUgPGNvZGU+QXR0cjwvY29kZT4gbm9kZXMgdG8gcmUtdXNlIHRoZW0gaW4gb3RoZXIKLSAgICAgKiAgIGVsZW1lbnRzLgotICAgICAqLwotICAgIHB1YmxpYyBBdHRyIHNldEF0dHJpYnV0ZU5vZGUoQXR0ciBuZXdBdHRyKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIFJlbW92ZXMgdGhlIHNwZWNpZmllZCBhdHRyaWJ1dGUgbm9kZS4gSWYgYSBkZWZhdWx0IHZhbHVlIGZvciB0aGUKLSAgICAgKiByZW1vdmVkIDxjb2RlPkF0dHI8L2NvZGU+IG5vZGUgaXMgZGVmaW5lZCBpbiB0aGUgRFRELCBhIG5ldyBub2RlCi0gICAgICogaW1tZWRpYXRlbHkgYXBwZWFycyB3aXRoIHRoZSBkZWZhdWx0IHZhbHVlIGFzIHdlbGwgYXMgdGhlCi0gICAgICogY29ycmVzcG9uZGluZyBuYW1lc3BhY2UgVVJJLCBsb2NhbCBuYW1lLCBhbmQgcHJlZml4IHdoZW4gYXBwbGljYWJsZS4KLSAgICAgKiBUaGUgaW1wbGVtZW50YXRpb24gbWF5IGhhbmRsZSBkZWZhdWx0IHZhbHVlcyBmcm9tIG90aGVyIHNjaGVtYXMKLSAgICAgKiBzaW1pbGFybHkgYnV0IGFwcGxpY2F0aW9ucyBzaG91bGQgdXNlCi0gICAgICogPGNvZGU+RG9jdW1lbnQubm9ybWFsaXplRG9jdW1lbnQoKTwvY29kZT4gdG8gZ3VhcmFudGVlIHRoaXMKLSAgICAgKiBpbmZvcm1hdGlvbiBpcyB1cC10by1kYXRlLgotICAgICAqIEBwYXJhbSBvbGRBdHRyIFRoZSA8Y29kZT5BdHRyPC9jb2RlPiBub2RlIHRvIHJlbW92ZSBmcm9tIHRoZSBhdHRyaWJ1dGUKLSAgICAgKiAgIGxpc3QuCi0gICAgICogQHJldHVybiBUaGUgPGNvZGU+QXR0cjwvY29kZT4gbm9kZSB0aGF0IHdhcyByZW1vdmVkLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIG5vZGUgaXMgcmVhZG9ubHkuCi0gICAgICogICA8YnI+Tk9UX0ZPVU5EX0VSUjogUmFpc2VkIGlmIDxjb2RlPm9sZEF0dHI8L2NvZGU+IGlzIG5vdCBhbiBhdHRyaWJ1dGUKLSAgICAgKiAgIG9mIHRoZSBlbGVtZW50LgotICAgICAqLwotICAgIHB1YmxpYyBBdHRyIHJlbW92ZUF0dHJpYnV0ZU5vZGUoQXR0ciBvbGRBdHRyKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYSA8Y29kZT5Ob2RlTGlzdDwvY29kZT4gb2YgYWxsIGRlc2NlbmRhbnQgPGNvZGU+RWxlbWVudHM8L2NvZGU+Ci0gICAgICogd2l0aCBhIGdpdmVuIHRhZyBuYW1lLCBpbiBkb2N1bWVudCBvcmRlci4KLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgdGFnIHRvIG1hdGNoIG9uLiBUaGUgc3BlY2lhbCB2YWx1ZSAiKiIKLSAgICAgKiAgIG1hdGNoZXMgYWxsIHRhZ3MuCi0gICAgICogQHJldHVybiBBIGxpc3Qgb2YgbWF0Y2hpbmcgPGNvZGU+RWxlbWVudDwvY29kZT4gbm9kZXMuCi0gICAgICovCi0gICAgcHVibGljIE5vZGVMaXN0IGdldEVsZW1lbnRzQnlUYWdOYW1lKFN0cmluZyBuYW1lKTsKLQotICAgIC8qKgotICAgICAqIFJldHJpZXZlcyBhbiBhdHRyaWJ1dGUgdmFsdWUgYnkgbG9jYWwgbmFtZSBhbmQgbmFtZXNwYWNlIFVSSS4KLSAgICAgKiA8YnI+UGVyIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk5L1JFQy14bWwtbmFtZXMtMTk5OTAxMTQvJz5YTUwgTmFtZXNwYWNlczwvYT5dCi0gICAgICogLCBhcHBsaWNhdGlvbnMgbXVzdCB1c2UgdGhlIHZhbHVlIDxjb2RlPm51bGw8L2NvZGU+IGFzIHRoZQotICAgICAqIDxjb2RlPm5hbWVzcGFjZVVSSTwvY29kZT4gcGFyYW1ldGVyIGZvciBtZXRob2RzIGlmIHRoZXkgd2lzaCB0byBoYXZlCi0gICAgICogbm8gbmFtZXNwYWNlLgotICAgICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkgVGhlIG5hbWVzcGFjZSBVUkkgb2YgdGhlIGF0dHJpYnV0ZSB0byByZXRyaWV2ZS4KLSAgICAgKiBAcGFyYW0gbG9jYWxOYW1lIFRoZSBsb2NhbCBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUgdG8gcmV0cmlldmUuCi0gICAgICogQHJldHVybiBUaGUgPGNvZGU+QXR0cjwvY29kZT4gdmFsdWUgYXMgYSBzdHJpbmcsIG9yIHRoZSBlbXB0eSBzdHJpbmcKLSAgICAgKiAgIGlmIHRoYXQgYXR0cmlidXRlIGRvZXMgbm90IGhhdmUgYSBzcGVjaWZpZWQgb3IgZGVmYXVsdCB2YWx1ZS4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgTk9UX1NVUFBPUlRFRF9FUlI6IE1heSBiZSByYWlzZWQgaWYgdGhlIGltcGxlbWVudGF0aW9uIGRvZXMgbm90Ci0gICAgICogICBzdXBwb3J0IHRoZSBmZWF0dXJlIDxjb2RlPiJYTUwiPC9jb2RlPiBhbmQgdGhlIGxhbmd1YWdlIGV4cG9zZWQKLSAgICAgKiAgIHRocm91Z2ggdGhlIERvY3VtZW50IGRvZXMgbm90IHN1cHBvcnQgWE1MIE5hbWVzcGFjZXMgKHN1Y2ggYXMgWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzE5OTkvUkVDLWh0bWw0MDEtMTk5OTEyMjQvJz5IVE1MIDQuMDE8L2E+XSkuCi0gICAgICogQHNpbmNlIERPTSBMZXZlbCAyCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRBdHRyaWJ1dGVOUyhTdHJpbmcgbmFtZXNwYWNlVVJJLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGxvY2FsTmFtZSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBBZGRzIGEgbmV3IGF0dHJpYnV0ZS4gSWYgYW4gYXR0cmlidXRlIHdpdGggdGhlIHNhbWUgbG9jYWwgbmFtZSBhbmQKLSAgICAgKiBuYW1lc3BhY2UgVVJJIGlzIGFscmVhZHkgcHJlc2VudCBvbiB0aGUgZWxlbWVudCwgaXRzIHByZWZpeCBpcwotICAgICAqIGNoYW5nZWQgdG8gYmUgdGhlIHByZWZpeCBwYXJ0IG9mIHRoZSA8Y29kZT5xdWFsaWZpZWROYW1lPC9jb2RlPiwgYW5kCi0gICAgICogaXRzIHZhbHVlIGlzIGNoYW5nZWQgdG8gYmUgdGhlIDxjb2RlPnZhbHVlPC9jb2RlPiBwYXJhbWV0ZXIuIFRoaXMKLSAgICAgKiB2YWx1ZSBpcyBhIHNpbXBsZSBzdHJpbmc7IGl0IGlzIG5vdCBwYXJzZWQgYXMgaXQgaXMgYmVpbmcgc2V0LiBTbyBhbnkKLSAgICAgKiBtYXJrdXAgKHN1Y2ggYXMgc3ludGF4IHRvIGJlIHJlY29nbml6ZWQgYXMgYW4gZW50aXR5IHJlZmVyZW5jZSkgaXMKLSAgICAgKiB0cmVhdGVkIGFzIGxpdGVyYWwgdGV4dCwgYW5kIG5lZWRzIHRvIGJlIGFwcHJvcHJpYXRlbHkgZXNjYXBlZCBieSB0aGUKLSAgICAgKiBpbXBsZW1lbnRhdGlvbiB3aGVuIGl0IGlzIHdyaXR0ZW4gb3V0LiBJbiBvcmRlciB0byBhc3NpZ24gYW4KLSAgICAgKiBhdHRyaWJ1dGUgdmFsdWUgdGhhdCBjb250YWlucyBlbnRpdHkgcmVmZXJlbmNlcywgdGhlIHVzZXIgbXVzdCBjcmVhdGUKLSAgICAgKiBhbiA8Y29kZT5BdHRyPC9jb2RlPiBub2RlIHBsdXMgYW55IDxjb2RlPlRleHQ8L2NvZGU+IGFuZAotICAgICAqIDxjb2RlPkVudGl0eVJlZmVyZW5jZTwvY29kZT4gbm9kZXMsIGJ1aWxkIHRoZSBhcHByb3ByaWF0ZSBzdWJ0cmVlLAotICAgICAqIGFuZCB1c2UgPGNvZGU+c2V0QXR0cmlidXRlTm9kZU5TPC9jb2RlPiBvcgotICAgICAqIDxjb2RlPnNldEF0dHJpYnV0ZU5vZGU8L2NvZGU+IHRvIGFzc2lnbiBpdCBhcyB0aGUgdmFsdWUgb2YgYW4KLSAgICAgKiBhdHRyaWJ1dGUuCi0gICAgICogPGJyPlBlciBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMTk5OS9SRUMteG1sLW5hbWVzLTE5OTkwMTE0Lyc+WE1MIE5hbWVzcGFjZXM8L2E+XQotICAgICAqICwgYXBwbGljYXRpb25zIG11c3QgdXNlIHRoZSB2YWx1ZSA8Y29kZT5udWxsPC9jb2RlPiBhcyB0aGUKLSAgICAgKiA8Y29kZT5uYW1lc3BhY2VVUkk8L2NvZGU+IHBhcmFtZXRlciBmb3IgbWV0aG9kcyBpZiB0aGV5IHdpc2ggdG8gaGF2ZQotICAgICAqIG5vIG5hbWVzcGFjZS4KLSAgICAgKiBAcGFyYW0gbmFtZXNwYWNlVVJJIFRoZSBuYW1lc3BhY2UgVVJJIG9mIHRoZSBhdHRyaWJ1dGUgdG8gY3JlYXRlIG9yCi0gICAgICogICBhbHRlci4KLSAgICAgKiBAcGFyYW0gcXVhbGlmaWVkTmFtZSBUaGUgcXVhbGlmaWVkIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZSB0byBjcmVhdGUgb3IKLSAgICAgKiAgIGFsdGVyLgotICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2V0IGluIHN0cmluZyBmb3JtLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBJTlZBTElEX0NIQVJBQ1RFUl9FUlI6IFJhaXNlZCBpZiB0aGUgc3BlY2lmaWVkIHF1YWxpZmllZCBuYW1lIGlzIG5vdAotICAgICAqICAgYW4gWE1MIG5hbWUgYWNjb3JkaW5nIHRvIHRoZSBYTUwgdmVyc2lvbiBpbiB1c2Ugc3BlY2lmaWVkIGluIHRoZQotICAgICAqICAgPGNvZGU+RG9jdW1lbnQueG1sVmVyc2lvbjwvY29kZT4gYXR0cmlidXRlLgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgbm9kZSBpcyByZWFkb25seS4KLSAgICAgKiAgIDxicj5OQU1FU1BBQ0VfRVJSOiBSYWlzZWQgaWYgdGhlIDxjb2RlPnF1YWxpZmllZE5hbWU8L2NvZGU+IGlzCi0gICAgICogICBtYWxmb3JtZWQgcGVyIHRoZSBOYW1lc3BhY2VzIGluIFhNTCBzcGVjaWZpY2F0aW9uLCBpZiB0aGUKLSAgICAgKiAgIDxjb2RlPnF1YWxpZmllZE5hbWU8L2NvZGU+IGhhcyBhIHByZWZpeCBhbmQgdGhlCi0gICAgICogICA8Y29kZT5uYW1lc3BhY2VVUkk8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LCBpZiB0aGUKLSAgICAgKiAgIDxjb2RlPnF1YWxpZmllZE5hbWU8L2NvZGU+IGhhcyBhIHByZWZpeCB0aGF0IGlzICJ4bWwiIGFuZCB0aGUKLSAgICAgKiAgIDxjb2RlPm5hbWVzcGFjZVVSSTwvY29kZT4gaXMgZGlmZmVyZW50IGZyb20gIjxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZSc+Ci0gICAgICogICBodHRwOi8vd3d3LnczLm9yZy9YTUwvMTk5OC9uYW1lc3BhY2U8L2E+IiwgaWYgdGhlIDxjb2RlPnF1YWxpZmllZE5hbWU8L2NvZGU+IG9yIGl0cyBwcmVmaXggaXMgInhtbG5zIiBhbmQgdGhlCi0gICAgICogICA8Y29kZT5uYW1lc3BhY2VVUkk8L2NvZGU+IGlzIGRpZmZlcmVudCBmcm9tICI8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3htbG5zLyc+aHR0cDovL3d3dy53My5vcmcvMjAwMC94bWxucy88L2E+Iiwgb3IgaWYgdGhlIDxjb2RlPm5hbWVzcGFjZVVSSTwvY29kZT4gaXMgIjxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnLzIwMDAveG1sbnMvJz5odHRwOi8vd3d3LnczLm9yZy8yMDAwL3htbG5zLzwvYT4iIGFuZCBuZWl0aGVyIHRoZSA8Y29kZT5xdWFsaWZpZWROYW1lPC9jb2RlPiBub3IgaXRzIHByZWZpeCBpcyAieG1sbnMiLgotICAgICAqICAgPGJyPk5PVF9TVVBQT1JURURfRVJSOiBNYXkgYmUgcmFpc2VkIGlmIHRoZSBpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdAotICAgICAqICAgc3VwcG9ydCB0aGUgZmVhdHVyZSA8Y29kZT4iWE1MIjwvY29kZT4gYW5kIHRoZSBsYW5ndWFnZSBleHBvc2VkCi0gICAgICogICB0aHJvdWdoIHRoZSBEb2N1bWVudCBkb2VzIG5vdCBzdXBwb3J0IFhNTCBOYW1lc3BhY2VzIChzdWNoIGFzIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk5L1JFQy1odG1sNDAxLTE5OTkxMjI0Lyc+SFRNTCA0LjAxPC9hPl0pLgotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEF0dHJpYnV0ZU5TKFN0cmluZyBuYW1lc3BhY2VVUkksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHF1YWxpZmllZE5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHZhbHVlKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBSZW1vdmVzIGFuIGF0dHJpYnV0ZSBieSBsb2NhbCBuYW1lIGFuZCBuYW1lc3BhY2UgVVJJLiBJZiBhIGRlZmF1bHQKLSAgICAgKiB2YWx1ZSBmb3IgdGhlIHJlbW92ZWQgYXR0cmlidXRlIGlzIGRlZmluZWQgaW4gdGhlIERURCwgYSBuZXcKLSAgICAgKiBhdHRyaWJ1dGUgaW1tZWRpYXRlbHkgYXBwZWFycyB3aXRoIHRoZSBkZWZhdWx0IHZhbHVlIGFzIHdlbGwgYXMgdGhlCi0gICAgICogY29ycmVzcG9uZGluZyBuYW1lc3BhY2UgVVJJLCBsb2NhbCBuYW1lLCBhbmQgcHJlZml4IHdoZW4gYXBwbGljYWJsZS4KLSAgICAgKiBUaGUgaW1wbGVtZW50YXRpb24gbWF5IGhhbmRsZSBkZWZhdWx0IHZhbHVlcyBmcm9tIG90aGVyIHNjaGVtYXMKLSAgICAgKiBzaW1pbGFybHkgYnV0IGFwcGxpY2F0aW9ucyBzaG91bGQgdXNlCi0gICAgICogPGNvZGU+RG9jdW1lbnQubm9ybWFsaXplRG9jdW1lbnQoKTwvY29kZT4gdG8gZ3VhcmFudGVlIHRoaXMKLSAgICAgKiBpbmZvcm1hdGlvbiBpcyB1cC10by1kYXRlLgotICAgICAqIDxicj5JZiBubyBhdHRyaWJ1dGUgd2l0aCB0aGlzIGxvY2FsIG5hbWUgYW5kIG5hbWVzcGFjZSBVUkkgaXMgZm91bmQsCi0gICAgICogdGhpcyBtZXRob2QgaGFzIG5vIGVmZmVjdC4KLSAgICAgKiA8YnI+UGVyIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk5L1JFQy14bWwtbmFtZXMtMTk5OTAxMTQvJz5YTUwgTmFtZXNwYWNlczwvYT5dCi0gICAgICogLCBhcHBsaWNhdGlvbnMgbXVzdCB1c2UgdGhlIHZhbHVlIDxjb2RlPm51bGw8L2NvZGU+IGFzIHRoZQotICAgICAqIDxjb2RlPm5hbWVzcGFjZVVSSTwvY29kZT4gcGFyYW1ldGVyIGZvciBtZXRob2RzIGlmIHRoZXkgd2lzaCB0byBoYXZlCi0gICAgICogbm8gbmFtZXNwYWNlLgotICAgICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkgVGhlIG5hbWVzcGFjZSBVUkkgb2YgdGhlIGF0dHJpYnV0ZSB0byByZW1vdmUuCi0gICAgICogQHBhcmFtIGxvY2FsTmFtZSBUaGUgbG9jYWwgbmFtZSBvZiB0aGUgYXR0cmlidXRlIHRvIHJlbW92ZS4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBub2RlIGlzIHJlYWRvbmx5LgotICAgICAqICAgPGJyPk5PVF9TVVBQT1JURURfRVJSOiBNYXkgYmUgcmFpc2VkIGlmIHRoZSBpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdAotICAgICAqICAgc3VwcG9ydCB0aGUgZmVhdHVyZSA8Y29kZT4iWE1MIjwvY29kZT4gYW5kIHRoZSBsYW5ndWFnZSBleHBvc2VkCi0gICAgICogICB0aHJvdWdoIHRoZSBEb2N1bWVudCBkb2VzIG5vdCBzdXBwb3J0IFhNTCBOYW1lc3BhY2VzIChzdWNoIGFzIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk5L1JFQy1odG1sNDAxLTE5OTkxMjI0Lyc+SFRNTCA0LjAxPC9hPl0pLgotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHJlbW92ZUF0dHJpYnV0ZU5TKFN0cmluZyBuYW1lc3BhY2VVUkksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGxvY2FsTmFtZSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogUmV0cmlldmVzIGFuIDxjb2RlPkF0dHI8L2NvZGU+IG5vZGUgYnkgbG9jYWwgbmFtZSBhbmQgbmFtZXNwYWNlIFVSSS4KLSAgICAgKiA8YnI+UGVyIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk5L1JFQy14bWwtbmFtZXMtMTk5OTAxMTQvJz5YTUwgTmFtZXNwYWNlczwvYT5dCi0gICAgICogLCBhcHBsaWNhdGlvbnMgbXVzdCB1c2UgdGhlIHZhbHVlIDxjb2RlPm51bGw8L2NvZGU+IGFzIHRoZQotICAgICAqIDxjb2RlPm5hbWVzcGFjZVVSSTwvY29kZT4gcGFyYW1ldGVyIGZvciBtZXRob2RzIGlmIHRoZXkgd2lzaCB0byBoYXZlCi0gICAgICogbm8gbmFtZXNwYWNlLgotICAgICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkgVGhlIG5hbWVzcGFjZSBVUkkgb2YgdGhlIGF0dHJpYnV0ZSB0byByZXRyaWV2ZS4KLSAgICAgKiBAcGFyYW0gbG9jYWxOYW1lIFRoZSBsb2NhbCBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUgdG8gcmV0cmlldmUuCi0gICAgICogQHJldHVybiBUaGUgPGNvZGU+QXR0cjwvY29kZT4gbm9kZSB3aXRoIHRoZSBzcGVjaWZpZWQgYXR0cmlidXRlIGxvY2FsCi0gICAgICogICBuYW1lIGFuZCBuYW1lc3BhY2UgVVJJIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoZXJlIGlzIG5vIHN1Y2gKLSAgICAgKiAgIGF0dHJpYnV0ZS4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgTk9UX1NVUFBPUlRFRF9FUlI6IE1heSBiZSByYWlzZWQgaWYgdGhlIGltcGxlbWVudGF0aW9uIGRvZXMgbm90Ci0gICAgICogICBzdXBwb3J0IHRoZSBmZWF0dXJlIDxjb2RlPiJYTUwiPC9jb2RlPiBhbmQgdGhlIGxhbmd1YWdlIGV4cG9zZWQKLSAgICAgKiAgIHRocm91Z2ggdGhlIERvY3VtZW50IGRvZXMgbm90IHN1cHBvcnQgWE1MIE5hbWVzcGFjZXMgKHN1Y2ggYXMgWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzE5OTkvUkVDLWh0bWw0MDEtMTk5OTEyMjQvJz5IVE1MIDQuMDE8L2E+XSkuCi0gICAgICogQHNpbmNlIERPTSBMZXZlbCAyCi0gICAgICovCi0gICAgcHVibGljIEF0dHIgZ2V0QXR0cmlidXRlTm9kZU5TKFN0cmluZyBuYW1lc3BhY2VVUkksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBsb2NhbE5hbWUpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBBZGRzIGEgbmV3IGF0dHJpYnV0ZS4gSWYgYW4gYXR0cmlidXRlIHdpdGggdGhhdCBsb2NhbCBuYW1lIGFuZCB0aGF0Ci0gICAgICogbmFtZXNwYWNlIFVSSSBpcyBhbHJlYWR5IHByZXNlbnQgaW4gdGhlIGVsZW1lbnQsIGl0IGlzIHJlcGxhY2VkIGJ5Ci0gICAgICogdGhlIG5ldyBvbmUuIFJlcGxhY2luZyBhbiBhdHRyaWJ1dGUgbm9kZSBieSBpdHNlbGYgaGFzIG5vIGVmZmVjdC4KLSAgICAgKiA8YnI+UGVyIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk5L1JFQy14bWwtbmFtZXMtMTk5OTAxMTQvJz5YTUwgTmFtZXNwYWNlczwvYT5dCi0gICAgICogLCBhcHBsaWNhdGlvbnMgbXVzdCB1c2UgdGhlIHZhbHVlIDxjb2RlPm51bGw8L2NvZGU+IGFzIHRoZQotICAgICAqIDxjb2RlPm5hbWVzcGFjZVVSSTwvY29kZT4gcGFyYW1ldGVyIGZvciBtZXRob2RzIGlmIHRoZXkgd2lzaCB0byBoYXZlCi0gICAgICogbm8gbmFtZXNwYWNlLgotICAgICAqIEBwYXJhbSBuZXdBdHRyIFRoZSA8Y29kZT5BdHRyPC9jb2RlPiBub2RlIHRvIGFkZCB0byB0aGUgYXR0cmlidXRlIGxpc3QuCi0gICAgICogQHJldHVybiBJZiB0aGUgPGNvZGU+bmV3QXR0cjwvY29kZT4gYXR0cmlidXRlIHJlcGxhY2VzIGFuIGV4aXN0aW5nCi0gICAgICogICBhdHRyaWJ1dGUgd2l0aCB0aGUgc2FtZSBsb2NhbCBuYW1lIGFuZCBuYW1lc3BhY2UgVVJJLCB0aGUgcmVwbGFjZWQKLSAgICAgKiAgIDxjb2RlPkF0dHI8L2NvZGU+IG5vZGUgaXMgcmV0dXJuZWQsIG90aGVyd2lzZSA8Y29kZT5udWxsPC9jb2RlPiBpcwotICAgICAqICAgcmV0dXJuZWQuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIFdST05HX0RPQ1VNRU5UX0VSUjogUmFpc2VkIGlmIDxjb2RlPm5ld0F0dHI8L2NvZGU+IHdhcyBjcmVhdGVkIGZyb20gYQotICAgICAqICAgZGlmZmVyZW50IGRvY3VtZW50IHRoYW4gdGhlIG9uZSB0aGF0IGNyZWF0ZWQgdGhlIGVsZW1lbnQuCi0gICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBub2RlIGlzIHJlYWRvbmx5LgotICAgICAqICAgPGJyPklOVVNFX0FUVFJJQlVURV9FUlI6IFJhaXNlZCBpZiA8Y29kZT5uZXdBdHRyPC9jb2RlPiBpcyBhbHJlYWR5IGFuCi0gICAgICogICBhdHRyaWJ1dGUgb2YgYW5vdGhlciA8Y29kZT5FbGVtZW50PC9jb2RlPiBvYmplY3QuIFRoZSBET00gdXNlciBtdXN0Ci0gICAgICogICBleHBsaWNpdGx5IGNsb25lIDxjb2RlPkF0dHI8L2NvZGU+IG5vZGVzIHRvIHJlLXVzZSB0aGVtIGluIG90aGVyCi0gICAgICogICBlbGVtZW50cy4KLSAgICAgKiAgIDxicj5OT1RfU1VQUE9SVEVEX0VSUjogTWF5IGJlIHJhaXNlZCBpZiB0aGUgaW1wbGVtZW50YXRpb24gZG9lcyBub3QKLSAgICAgKiAgIHN1cHBvcnQgdGhlIGZlYXR1cmUgPGNvZGU+IlhNTCI8L2NvZGU+IGFuZCB0aGUgbGFuZ3VhZ2UgZXhwb3NlZAotICAgICAqICAgdGhyb3VnaCB0aGUgRG9jdW1lbnQgZG9lcyBub3Qgc3VwcG9ydCBYTUwgTmFtZXNwYWNlcyAoc3VjaCBhcyBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMTk5OS9SRUMtaHRtbDQwMS0xOTk5MTIyNC8nPkhUTUwgNC4wMTwvYT5dKS4KLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDIKLSAgICAgKi8KLSAgICBwdWJsaWMgQXR0ciBzZXRBdHRyaWJ1dGVOb2RlTlMoQXR0ciBuZXdBdHRyKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhIDxjb2RlPk5vZGVMaXN0PC9jb2RlPiBvZiBhbGwgdGhlIGRlc2NlbmRhbnQKLSAgICAgKiA8Y29kZT5FbGVtZW50czwvY29kZT4gd2l0aCBhIGdpdmVuIGxvY2FsIG5hbWUgYW5kIG5hbWVzcGFjZSBVUkkgaW4KLSAgICAgKiBkb2N1bWVudCBvcmRlci4KLSAgICAgKiBAcGFyYW0gbmFtZXNwYWNlVVJJIFRoZSBuYW1lc3BhY2UgVVJJIG9mIHRoZSBlbGVtZW50cyB0byBtYXRjaCBvbi4gVGhlCi0gICAgICogICBzcGVjaWFsIHZhbHVlICIqIiBtYXRjaGVzIGFsbCBuYW1lc3BhY2VzLgotICAgICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGxvY2FsIG5hbWUgb2YgdGhlIGVsZW1lbnRzIHRvIG1hdGNoIG9uLiBUaGUKLSAgICAgKiAgIHNwZWNpYWwgdmFsdWUgIioiIG1hdGNoZXMgYWxsIGxvY2FsIG5hbWVzLgotICAgICAqIEByZXR1cm4gQSBuZXcgPGNvZGU+Tm9kZUxpc3Q8L2NvZGU+IG9iamVjdCBjb250YWluaW5nIGFsbCB0aGUgbWF0Y2hlZAotICAgICAqICAgPGNvZGU+RWxlbWVudHM8L2NvZGU+LgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBOT1RfU1VQUE9SVEVEX0VSUjogTWF5IGJlIHJhaXNlZCBpZiB0aGUgaW1wbGVtZW50YXRpb24gZG9lcyBub3QKLSAgICAgKiAgIHN1cHBvcnQgdGhlIGZlYXR1cmUgPGNvZGU+IlhNTCI8L2NvZGU+IGFuZCB0aGUgbGFuZ3VhZ2UgZXhwb3NlZAotICAgICAqICAgdGhyb3VnaCB0aGUgRG9jdW1lbnQgZG9lcyBub3Qgc3VwcG9ydCBYTUwgTmFtZXNwYWNlcyAoc3VjaCBhcyBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMTk5OS9SRUMtaHRtbDQwMS0xOTk5MTIyNC8nPkhUTUwgNC4wMTwvYT5dKS4KLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDIKLSAgICAgKi8KLSAgICBwdWJsaWMgTm9kZUxpc3QgZ2V0RWxlbWVudHNCeVRhZ05hbWVOUyhTdHJpbmcgbmFtZXNwYWNlVVJJLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBsb2NhbE5hbWUpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgPGNvZGU+dHJ1ZTwvY29kZT4gd2hlbiBhbiBhdHRyaWJ1dGUgd2l0aCBhIGdpdmVuIG5hbWUgaXMKLSAgICAgKiBzcGVjaWZpZWQgb24gdGhpcyBlbGVtZW50IG9yIGhhcyBhIGRlZmF1bHQgdmFsdWUsIDxjb2RlPmZhbHNlPC9jb2RlPgotICAgICAqIG90aGVyd2lzZS4KLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlIHRvIGxvb2sgZm9yLgotICAgICAqIEByZXR1cm4gPGNvZGU+dHJ1ZTwvY29kZT4gaWYgYW4gYXR0cmlidXRlIHdpdGggdGhlIGdpdmVuIG5hbWUgaXMKLSAgICAgKiAgIHNwZWNpZmllZCBvbiB0aGlzIGVsZW1lbnQgb3IgaGFzIGEgZGVmYXVsdCB2YWx1ZSwgPGNvZGU+ZmFsc2U8L2NvZGU+Ci0gICAgICogICAgb3RoZXJ3aXNlLgotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGhhc0F0dHJpYnV0ZShTdHJpbmcgbmFtZSk7Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIDxjb2RlPnRydWU8L2NvZGU+IHdoZW4gYW4gYXR0cmlidXRlIHdpdGggYSBnaXZlbiBsb2NhbCBuYW1lIGFuZAotICAgICAqIG5hbWVzcGFjZSBVUkkgaXMgc3BlY2lmaWVkIG9uIHRoaXMgZWxlbWVudCBvciBoYXMgYSBkZWZhdWx0IHZhbHVlLAotICAgICAqIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuCi0gICAgICogPGJyPlBlciBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMTk5OS9SRUMteG1sLW5hbWVzLTE5OTkwMTE0Lyc+WE1MIE5hbWVzcGFjZXM8L2E+XQotICAgICAqICwgYXBwbGljYXRpb25zIG11c3QgdXNlIHRoZSB2YWx1ZSA8Y29kZT5udWxsPC9jb2RlPiBhcyB0aGUKLSAgICAgKiA8Y29kZT5uYW1lc3BhY2VVUkk8L2NvZGU+IHBhcmFtZXRlciBmb3IgbWV0aG9kcyBpZiB0aGV5IHdpc2ggdG8gaGF2ZQotICAgICAqIG5vIG5hbWVzcGFjZS4KLSAgICAgKiBAcGFyYW0gbmFtZXNwYWNlVVJJIFRoZSBuYW1lc3BhY2UgVVJJIG9mIHRoZSBhdHRyaWJ1dGUgdG8gbG9vayBmb3IuCi0gICAgICogQHBhcmFtIGxvY2FsTmFtZSBUaGUgbG9jYWwgbmFtZSBvZiB0aGUgYXR0cmlidXRlIHRvIGxvb2sgZm9yLgotICAgICAqIEByZXR1cm4gPGNvZGU+dHJ1ZTwvY29kZT4gaWYgYW4gYXR0cmlidXRlIHdpdGggdGhlIGdpdmVuIGxvY2FsIG5hbWUKLSAgICAgKiAgIGFuZCBuYW1lc3BhY2UgVVJJIGlzIHNwZWNpZmllZCBvciBoYXMgYSBkZWZhdWx0IHZhbHVlIG9uIHRoaXMKLSAgICAgKiAgIGVsZW1lbnQsIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIE5PVF9TVVBQT1JURURfRVJSOiBNYXkgYmUgcmFpc2VkIGlmIHRoZSBpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdAotICAgICAqICAgc3VwcG9ydCB0aGUgZmVhdHVyZSA8Y29kZT4iWE1MIjwvY29kZT4gYW5kIHRoZSBsYW5ndWFnZSBleHBvc2VkCi0gICAgICogICB0aHJvdWdoIHRoZSBEb2N1bWVudCBkb2VzIG5vdCBzdXBwb3J0IFhNTCBOYW1lc3BhY2VzIChzdWNoIGFzIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk5L1JFQy1odG1sNDAxLTE5OTkxMjI0Lyc+SFRNTCA0LjAxPC9hPl0pLgotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGhhc0F0dHJpYnV0ZU5TKFN0cmluZyBuYW1lc3BhY2VVUkksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGxvY2FsTmFtZSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogIFRoZSB0eXBlIGluZm9ybWF0aW9uIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGVsZW1lbnQuCi0gICAgICogQHNpbmNlIERPTSBMZXZlbCAzCi0gICAgICovCi0gICAgcHVibGljIFR5cGVJbmZvIGdldFNjaGVtYVR5cGVJbmZvKCk7Ci0KLSAgICAvKioKLSAgICAgKiAgSWYgdGhlIHBhcmFtZXRlciA8Y29kZT5pc0lkPC9jb2RlPiBpcyA8Y29kZT50cnVlPC9jb2RlPiwgdGhpcyBtZXRob2QKLSAgICAgKiBkZWNsYXJlcyB0aGUgc3BlY2lmaWVkIGF0dHJpYnV0ZSB0byBiZSBhIHVzZXItZGV0ZXJtaW5lZCBJRCBhdHRyaWJ1dGUKLSAgICAgKiAuIFRoaXMgYWZmZWN0cyB0aGUgdmFsdWUgb2YgPGNvZGU+QXR0ci5pc0lkPC9jb2RlPiBhbmQgdGhlIGJlaGF2aW9yCi0gICAgICogb2YgPGNvZGU+RG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQ8L2NvZGU+LCBidXQgZG9lcyBub3QgY2hhbmdlIGFueQotICAgICAqIHNjaGVtYSB0aGF0IG1heSBiZSBpbiB1c2UsIGluIHBhcnRpY3VsYXIgdGhpcyBkb2VzIG5vdCBhZmZlY3QgdGhlCi0gICAgICogPGNvZGU+QXR0ci5zY2hlbWFUeXBlSW5mbzwvY29kZT4gb2YgdGhlIHNwZWNpZmllZCA8Y29kZT5BdHRyPC9jb2RlPgotICAgICAqIG5vZGUuIFVzZSB0aGUgdmFsdWUgPGNvZGU+ZmFsc2U8L2NvZGU+IGZvciB0aGUgcGFyYW1ldGVyCi0gICAgICogPGNvZGU+aXNJZDwvY29kZT4gdG8gdW5kZWNsYXJlIGFuIGF0dHJpYnV0ZSBmb3IgYmVpbmcgYQotICAgICAqIHVzZXItZGV0ZXJtaW5lZCBJRCBhdHRyaWJ1dGUuCi0gICAgICogPGJyPiBUbyBzcGVjaWZ5IGFuIGF0dHJpYnV0ZSBieSBsb2NhbCBuYW1lIGFuZCBuYW1lc3BhY2UgVVJJLCB1c2UgdGhlCi0gICAgICogPGNvZGU+c2V0SWRBdHRyaWJ1dGVOUzwvY29kZT4gbWV0aG9kLgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUuCi0gICAgICogQHBhcmFtIGlzSWQgV2hldGhlciB0aGUgYXR0cmlidXRlIGlzIGEgb2YgdHlwZSBJRC4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBub2RlIGlzIHJlYWRvbmx5LgotICAgICAqICAgPGJyPk5PVF9GT1VORF9FUlI6IFJhaXNlZCBpZiB0aGUgc3BlY2lmaWVkIG5vZGUgaXMgbm90IGFuIGF0dHJpYnV0ZQotICAgICAqICAgb2YgdGhpcyBlbGVtZW50LgotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldElkQXR0cmlidXRlKFN0cmluZyBuYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gaXNJZCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogIElmIHRoZSBwYXJhbWV0ZXIgPGNvZGU+aXNJZDwvY29kZT4gaXMgPGNvZGU+dHJ1ZTwvY29kZT4sIHRoaXMgbWV0aG9kCi0gICAgICogZGVjbGFyZXMgdGhlIHNwZWNpZmllZCBhdHRyaWJ1dGUgdG8gYmUgYSB1c2VyLWRldGVybWluZWQgSUQgYXR0cmlidXRlCi0gICAgICogLiBUaGlzIGFmZmVjdHMgdGhlIHZhbHVlIG9mIDxjb2RlPkF0dHIuaXNJZDwvY29kZT4gYW5kIHRoZSBiZWhhdmlvcgotICAgICAqIG9mIDxjb2RlPkRvY3VtZW50LmdldEVsZW1lbnRCeUlkPC9jb2RlPiwgYnV0IGRvZXMgbm90IGNoYW5nZSBhbnkKLSAgICAgKiBzY2hlbWEgdGhhdCBtYXkgYmUgaW4gdXNlLCBpbiBwYXJ0aWN1bGFyIHRoaXMgZG9lcyBub3QgYWZmZWN0IHRoZQotICAgICAqIDxjb2RlPkF0dHIuc2NoZW1hVHlwZUluZm88L2NvZGU+IG9mIHRoZSBzcGVjaWZpZWQgPGNvZGU+QXR0cjwvY29kZT4KLSAgICAgKiBub2RlLiBVc2UgdGhlIHZhbHVlIDxjb2RlPmZhbHNlPC9jb2RlPiBmb3IgdGhlIHBhcmFtZXRlcgotICAgICAqIDxjb2RlPmlzSWQ8L2NvZGU+IHRvIHVuZGVjbGFyZSBhbiBhdHRyaWJ1dGUgZm9yIGJlaW5nIGEKLSAgICAgKiB1c2VyLWRldGVybWluZWQgSUQgYXR0cmlidXRlLgotICAgICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkgVGhlIG5hbWVzcGFjZSBVUkkgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgKiBAcGFyYW0gbG9jYWxOYW1lIFRoZSBsb2NhbCBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUuCi0gICAgICogQHBhcmFtIGlzSWQgV2hldGhlciB0aGUgYXR0cmlidXRlIGlzIGEgb2YgdHlwZSBJRC4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBub2RlIGlzIHJlYWRvbmx5LgotICAgICAqICAgPGJyPk5PVF9GT1VORF9FUlI6IFJhaXNlZCBpZiB0aGUgc3BlY2lmaWVkIG5vZGUgaXMgbm90IGFuIGF0dHJpYnV0ZQotICAgICAqICAgb2YgdGhpcyBlbGVtZW50LgotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldElkQXR0cmlidXRlTlMoU3RyaW5nIG5hbWVzcGFjZVVSSSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBsb2NhbE5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGlzSWQpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogIElmIHRoZSBwYXJhbWV0ZXIgPGNvZGU+aXNJZDwvY29kZT4gaXMgPGNvZGU+dHJ1ZTwvY29kZT4sIHRoaXMgbWV0aG9kCi0gICAgICogZGVjbGFyZXMgdGhlIHNwZWNpZmllZCBhdHRyaWJ1dGUgdG8gYmUgYSB1c2VyLWRldGVybWluZWQgSUQgYXR0cmlidXRlCi0gICAgICogLiBUaGlzIGFmZmVjdHMgdGhlIHZhbHVlIG9mIDxjb2RlPkF0dHIuaXNJZDwvY29kZT4gYW5kIHRoZSBiZWhhdmlvcgotICAgICAqIG9mIDxjb2RlPkRvY3VtZW50LmdldEVsZW1lbnRCeUlkPC9jb2RlPiwgYnV0IGRvZXMgbm90IGNoYW5nZSBhbnkKLSAgICAgKiBzY2hlbWEgdGhhdCBtYXkgYmUgaW4gdXNlLCBpbiBwYXJ0aWN1bGFyIHRoaXMgZG9lcyBub3QgYWZmZWN0IHRoZQotICAgICAqIDxjb2RlPkF0dHIuc2NoZW1hVHlwZUluZm88L2NvZGU+IG9mIHRoZSBzcGVjaWZpZWQgPGNvZGU+QXR0cjwvY29kZT4KLSAgICAgKiBub2RlLiBVc2UgdGhlIHZhbHVlIDxjb2RlPmZhbHNlPC9jb2RlPiBmb3IgdGhlIHBhcmFtZXRlcgotICAgICAqIDxjb2RlPmlzSWQ8L2NvZGU+IHRvIHVuZGVjbGFyZSBhbiBhdHRyaWJ1dGUgZm9yIGJlaW5nIGEKLSAgICAgKiB1c2VyLWRldGVybWluZWQgSUQgYXR0cmlidXRlLgotICAgICAqIEBwYXJhbSBpZEF0dHIgVGhlIGF0dHJpYnV0ZSBub2RlLgotICAgICAqIEBwYXJhbSBpc0lkIFdoZXRoZXIgdGhlIGF0dHJpYnV0ZSBpcyBhIG9mIHR5cGUgSUQuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgbm9kZSBpcyByZWFkb25seS4KLSAgICAgKiAgIDxicj5OT1RfRk9VTkRfRVJSOiBSYWlzZWQgaWYgdGhlIHNwZWNpZmllZCBub2RlIGlzIG5vdCBhbiBhdHRyaWJ1dGUKLSAgICAgKiAgIG9mIHRoaXMgZWxlbWVudC4KLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRJZEF0dHJpYnV0ZU5vZGUoQXR0ciBpZEF0dHIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gaXNJZCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy93M2MvZG9tL0VudGl0eS5qYXZhIGIvc3JjL29yZy93M2MvZG9tL0VudGl0eS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyMjQyZmUxLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS9FbnRpdHkuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExOSArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogVGhpcyBmaWxlIGlzIGF2YWlsYWJsZSB1bmRlciBhbmQgZ292ZXJuZWQgYnkgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwotICogTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKiBIb3dldmVyLCB0aGUgZm9sbG93aW5nIG5vdGljZSBhY2NvbXBhbmllZCB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGlzCi0gKiBmaWxlIGFuZCwgcGVyIGl0cyB0ZXJtcywgc2hvdWxkIG5vdCBiZSByZW1vdmVkOgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAotICoKLSAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBFdXJvcGVhbiBSZXNlYXJjaCBDb25zb3J0aXVtIGZvcgotICogSW5mb3JtYXRpY3MgYW5kIE1hdGhlbWF0aWNzLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwgUmlnaHRzIFJlc2VydmVkLiBUaGlzCi0gKiB3b3JrIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MocikgU29mdHdhcmUgTGljZW5zZSBbMV0gaW4gdGhlIGhvcGUgdGhhdAotICogaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkCi0gKiB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuCi0gKgotICogWzFdIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvMjAwMi9jb3B5cmlnaHQtc29mdHdhcmUtMjAwMjEyMzEKLSAqLwotCi1wYWNrYWdlIG9yZy53M2MuZG9tOwotCi0vKioKLSAqIFRoaXMgaW50ZXJmYWNlIHJlcHJlc2VudHMgYSBrbm93biBlbnRpdHksIGVpdGhlciBwYXJzZWQgb3IgdW5wYXJzZWQsIGluIGFuCi0gKiBYTUwgZG9jdW1lbnQuIE5vdGUgdGhhdCB0aGlzIG1vZGVscyB0aGUgZW50aXR5IGl0c2VsZiA8ZW0+bm90PC9lbT4gdGhlIGVudGl0eSBkZWNsYXJhdGlvbi4KLSAqIDxwPlRoZSA8Y29kZT5ub2RlTmFtZTwvY29kZT4gYXR0cmlidXRlIHRoYXQgaXMgaW5oZXJpdGVkIGZyb20KLSAqIDxjb2RlPk5vZGU8L2NvZGU+IGNvbnRhaW5zIHRoZSBuYW1lIG9mIHRoZSBlbnRpdHkuCi0gKiA8cD5BbiBYTUwgcHJvY2Vzc29yIG1heSBjaG9vc2UgdG8gY29tcGxldGVseSBleHBhbmQgZW50aXRpZXMgYmVmb3JlIHRoZQotICogc3RydWN0dXJlIG1vZGVsIGlzIHBhc3NlZCB0byB0aGUgRE9NOyBpbiB0aGlzIGNhc2UgdGhlcmUgd2lsbCBiZSBubwotICogPGNvZGU+RW50aXR5UmVmZXJlbmNlPC9jb2RlPiBub2RlcyBpbiB0aGUgZG9jdW1lbnQgdHJlZS4KLSAqIDxwPlhNTCBkb2VzIG5vdCBtYW5kYXRlIHRoYXQgYSBub24tdmFsaWRhdGluZyBYTUwgcHJvY2Vzc29yIHJlYWQgYW5kCi0gKiBwcm9jZXNzIGVudGl0eSBkZWNsYXJhdGlvbnMgbWFkZSBpbiB0aGUgZXh0ZXJuYWwgc3Vic2V0IG9yIGRlY2xhcmVkIGluCi0gKiBwYXJhbWV0ZXIgZW50aXRpZXMuIFRoaXMgbWVhbnMgdGhhdCBwYXJzZWQgZW50aXRpZXMgZGVjbGFyZWQgaW4gdGhlCi0gKiBleHRlcm5hbCBzdWJzZXQgbmVlZCBub3QgYmUgZXhwYW5kZWQgYnkgc29tZSBjbGFzc2VzIG9mIGFwcGxpY2F0aW9ucywgYW5kCi0gKiB0aGF0IHRoZSByZXBsYWNlbWVudCB0ZXh0IG9mIHRoZSBlbnRpdHkgbWF5IG5vdCBiZSBhdmFpbGFibGUuIFdoZW4gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLXhtbC0yMDA0MDIwNCNpbnRlcm4tcmVwbGFjZW1lbnQnPgotICogcmVwbGFjZW1lbnQgdGV4dDwvYT4gaXMgYXZhaWxhYmxlLCB0aGUgY29ycmVzcG9uZGluZyA8Y29kZT5FbnRpdHk8L2NvZGU+IG5vZGUncyBjaGlsZCBsaXN0Ci0gKiByZXByZXNlbnRzIHRoZSBzdHJ1Y3R1cmUgb2YgdGhhdCByZXBsYWNlbWVudCB2YWx1ZS4gT3RoZXJ3aXNlLCB0aGUgY2hpbGQKLSAqIGxpc3QgaXMgZW1wdHkuCi0gKiA8cD5ET00gTGV2ZWwgMyBkb2VzIG5vdCBzdXBwb3J0IGVkaXRpbmcgPGNvZGU+RW50aXR5PC9jb2RlPiBub2RlczsgaWYgYQotICogdXNlciB3YW50cyB0byBtYWtlIGNoYW5nZXMgdG8gdGhlIGNvbnRlbnRzIG9mIGFuIDxjb2RlPkVudGl0eTwvY29kZT4sCi0gKiBldmVyeSByZWxhdGVkIDxjb2RlPkVudGl0eVJlZmVyZW5jZTwvY29kZT4gbm9kZSBoYXMgdG8gYmUgcmVwbGFjZWQgaW4gdGhlCi0gKiBzdHJ1Y3R1cmUgbW9kZWwgYnkgYSBjbG9uZSBvZiB0aGUgPGNvZGU+RW50aXR5PC9jb2RlPidzIGNvbnRlbnRzLCBhbmQKLSAqIHRoZW4gdGhlIGRlc2lyZWQgY2hhbmdlcyBtdXN0IGJlIG1hZGUgdG8gZWFjaCBvZiB0aG9zZSBjbG9uZXMgaW5zdGVhZC4KLSAqIDxjb2RlPkVudGl0eTwvY29kZT4gbm9kZXMgYW5kIGFsbCB0aGVpciBkZXNjZW5kYW50cyBhcmUgcmVhZG9ubHkuCi0gKiA8cD5BbiA8Y29kZT5FbnRpdHk8L2NvZGU+IG5vZGUgZG9lcyBub3QgaGF2ZSBhbnkgcGFyZW50LgotICogPHAgPjxiPk5vdGU6PC9iPiBJZiB0aGUgZW50aXR5IGNvbnRhaW5zIGFuIHVuYm91bmQgbmFtZXNwYWNlIHByZWZpeCwgdGhlCi0gKiA8Y29kZT5uYW1lc3BhY2VVUkk8L2NvZGU+IG9mIHRoZSBjb3JyZXNwb25kaW5nIG5vZGUgaW4gdGhlCi0gKiA8Y29kZT5FbnRpdHk8L2NvZGU+IG5vZGUgc3VidHJlZSBpcyA8Y29kZT5udWxsPC9jb2RlPi4gVGhlIHNhbWUgaXMgdHJ1ZQotICogZm9yIDxjb2RlPkVudGl0eVJlZmVyZW5jZTwvY29kZT4gbm9kZXMgdGhhdCByZWZlciB0byB0aGlzIGVudGl0eSwgd2hlbgotICogdGhleSBhcmUgY3JlYXRlZCB1c2luZyB0aGUgPGNvZGU+Y3JlYXRlRW50aXR5UmVmZXJlbmNlPC9jb2RlPiBtZXRob2Qgb2YKLSAqIHRoZSA8Y29kZT5Eb2N1bWVudDwvY29kZT4gaW50ZXJmYWNlLgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLURPTS1MZXZlbC0zLUNvcmUtMjAwNDA0MDcnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAzIENvcmUgU3BlY2lmaWNhdGlvbjwvYT4uCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgRW50aXR5IGV4dGVuZHMgTm9kZSB7Ci0gICAgLyoqCi0gICAgICogVGhlIHB1YmxpYyBpZGVudGlmaWVyIGFzc29jaWF0ZWQgd2l0aCB0aGUgZW50aXR5IGlmIHNwZWNpZmllZCwgYW5kCi0gICAgICogPGNvZGU+bnVsbDwvY29kZT4gb3RoZXJ3aXNlLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0UHVibGljSWQoKTsKLQotICAgIC8qKgotICAgICAqIFRoZSBzeXN0ZW0gaWRlbnRpZmllciBhc3NvY2lhdGVkIHdpdGggdGhlIGVudGl0eSBpZiBzcGVjaWZpZWQsIGFuZAotICAgICAqIDxjb2RlPm51bGw8L2NvZGU+IG90aGVyd2lzZS4gVGhpcyBtYXkgYmUgYW4gYWJzb2x1dGUgVVJJIG9yIG5vdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFN5c3RlbUlkKCk7Ci0KLSAgICAvKioKLSAgICAgKiBGb3IgdW5wYXJzZWQgZW50aXRpZXMsIHRoZSBuYW1lIG9mIHRoZSBub3RhdGlvbiBmb3IgdGhlIGVudGl0eS4gRm9yCi0gICAgICogcGFyc2VkIGVudGl0aWVzLCB0aGlzIGlzIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Tm90YXRpb25OYW1lKCk7Ci0KLSAgICAvKioKLSAgICAgKiBBbiBhdHRyaWJ1dGUgc3BlY2lmeWluZyB0aGUgZW5jb2RpbmcgdXNlZCBmb3IgdGhpcyBlbnRpdHkgYXQgdGhlIHRpbWUKLSAgICAgKiBvZiBwYXJzaW5nLCB3aGVuIGl0IGlzIGFuIGV4dGVybmFsIHBhcnNlZCBlbnRpdHkuIFRoaXMgaXMKLSAgICAgKiA8Y29kZT5udWxsPC9jb2RlPiBpZiBpdCBhbiBlbnRpdHkgZnJvbSB0aGUgaW50ZXJuYWwgc3Vic2V0IG9yIGlmIGl0Ci0gICAgICogaXMgbm90IGtub3duLgotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0SW5wdXRFbmNvZGluZygpOwotCi0gICAgLyoqCi0gICAgICogQW4gYXR0cmlidXRlIHNwZWNpZnlpbmcsIGFzIHBhcnQgb2YgdGhlIHRleHQgZGVjbGFyYXRpb24sIHRoZSBlbmNvZGluZwotICAgICAqIG9mIHRoaXMgZW50aXR5LCB3aGVuIGl0IGlzIGFuIGV4dGVybmFsIHBhcnNlZCBlbnRpdHkuIFRoaXMgaXMKLSAgICAgKiA8Y29kZT5udWxsPC9jb2RlPiBvdGhlcndpc2UuCi0gICAgICogQHNpbmNlIERPTSBMZXZlbCAzCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRYbWxFbmNvZGluZygpOwotCi0gICAgLyoqCi0gICAgICogQW4gYXR0cmlidXRlIHNwZWNpZnlpbmcsIGFzIHBhcnQgb2YgdGhlIHRleHQgZGVjbGFyYXRpb24sIHRoZSB2ZXJzaW9uCi0gICAgICogbnVtYmVyIG9mIHRoaXMgZW50aXR5LCB3aGVuIGl0IGlzIGFuIGV4dGVybmFsIHBhcnNlZCBlbnRpdHkuIFRoaXMgaXMKLSAgICAgKiA8Y29kZT5udWxsPC9jb2RlPiBvdGhlcndpc2UuCi0gICAgICogQHNpbmNlIERPTSBMZXZlbCAzCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRYbWxWZXJzaW9uKCk7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvdzNjL2RvbS9FbnRpdHlSZWZlcmVuY2UuamF2YSBiL3NyYy9vcmcvdzNjL2RvbS9FbnRpdHlSZWZlcmVuY2UuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNjVhYWRlNi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3czYy9kb20vRW50aXR5UmVmZXJlbmNlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3MiArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogVGhpcyBmaWxlIGlzIGF2YWlsYWJsZSB1bmRlciBhbmQgZ292ZXJuZWQgYnkgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwotICogTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKiBIb3dldmVyLCB0aGUgZm9sbG93aW5nIG5vdGljZSBhY2NvbXBhbmllZCB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGlzCi0gKiBmaWxlIGFuZCwgcGVyIGl0cyB0ZXJtcywgc2hvdWxkIG5vdCBiZSByZW1vdmVkOgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAotICoKLSAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBFdXJvcGVhbiBSZXNlYXJjaCBDb25zb3J0aXVtIGZvcgotICogSW5mb3JtYXRpY3MgYW5kIE1hdGhlbWF0aWNzLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwgUmlnaHRzIFJlc2VydmVkLiBUaGlzCi0gKiB3b3JrIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MocikgU29mdHdhcmUgTGljZW5zZSBbMV0gaW4gdGhlIGhvcGUgdGhhdAotICogaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkCi0gKiB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuCi0gKgotICogWzFdIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvMjAwMi9jb3B5cmlnaHQtc29mdHdhcmUtMjAwMjEyMzEKLSAqLwotCi1wYWNrYWdlIG9yZy53M2MuZG9tOwotCi0vKioKLSAqIDxjb2RlPkVudGl0eVJlZmVyZW5jZTwvY29kZT4gbm9kZXMgbWF5IGJlIHVzZWQgdG8gcmVwcmVzZW50IGFuIGVudGl0eQotICogcmVmZXJlbmNlIGluIHRoZSB0cmVlLiBOb3RlIHRoYXQgY2hhcmFjdGVyIHJlZmVyZW5jZXMgYW5kIHJlZmVyZW5jZXMgdG8KLSAqIHByZWRlZmluZWQgZW50aXRpZXMgYXJlIGNvbnNpZGVyZWQgdG8gYmUgZXhwYW5kZWQgYnkgdGhlIEhUTUwgb3IgWE1MCi0gKiBwcm9jZXNzb3Igc28gdGhhdCBjaGFyYWN0ZXJzIGFyZSByZXByZXNlbnRlZCBieSB0aGVpciBVbmljb2RlIGVxdWl2YWxlbnQKLSAqIHJhdGhlciB0aGFuIGJ5IGFuIGVudGl0eSByZWZlcmVuY2UuIE1vcmVvdmVyLCB0aGUgWE1MIHByb2Nlc3NvciBtYXkKLSAqIGNvbXBsZXRlbHkgZXhwYW5kIHJlZmVyZW5jZXMgdG8gZW50aXRpZXMgd2hpbGUgYnVpbGRpbmcgdGhlCi0gKiA8Y29kZT5Eb2N1bWVudDwvY29kZT4sIGluc3RlYWQgb2YgcHJvdmlkaW5nIDxjb2RlPkVudGl0eVJlZmVyZW5jZTwvY29kZT4KLSAqIG5vZGVzLiBJZiBpdCBkb2VzIHByb3ZpZGUgc3VjaCBub2RlcywgdGhlbiBmb3IgYW4KLSAqIDxjb2RlPkVudGl0eVJlZmVyZW5jZTwvY29kZT4gbm9kZSB0aGF0IHJlcHJlc2VudHMgYSByZWZlcmVuY2UgdG8gYSBrbm93bgotICogZW50aXR5IGFuIDxjb2RlPkVudGl0eTwvY29kZT4gZXhpc3RzLCBhbmQgdGhlIHN1YnRyZWUgb2YgdGhlCi0gKiA8Y29kZT5FbnRpdHlSZWZlcmVuY2U8L2NvZGU+IG5vZGUgaXMgYSBjb3B5IG9mIHRoZSA8Y29kZT5FbnRpdHk8L2NvZGU+Ci0gKiBub2RlIHN1YnRyZWUuIEhvd2V2ZXIsIHRoZSBsYXR0ZXIgbWF5IG5vdCBiZSB0cnVlIHdoZW4gYW4gZW50aXR5IGNvbnRhaW5zCi0gKiBhbiB1bmJvdW5kIG5hbWVzcGFjZSBwcmVmaXguIEluIHN1Y2ggYSBjYXNlLCBiZWNhdXNlIHRoZSBuYW1lc3BhY2UgcHJlZml4Ci0gKiByZXNvbHV0aW9uIGRlcGVuZHMgb24gd2hlcmUgdGhlIGVudGl0eSByZWZlcmVuY2UgaXMsIHRoZSBkZXNjZW5kYW50cyBvZgotICogdGhlIDxjb2RlPkVudGl0eVJlZmVyZW5jZTwvY29kZT4gbm9kZSBtYXkgYmUgYm91bmQgdG8gZGlmZmVyZW50IG5hbWVzcGFjZQotICogVVJJcy4gV2hlbiBhbiA8Y29kZT5FbnRpdHlSZWZlcmVuY2U8L2NvZGU+IG5vZGUgcmVwcmVzZW50cyBhIHJlZmVyZW5jZSB0bwotICogYW4gdW5rbm93biBlbnRpdHksIHRoZSBub2RlIGhhcyBubyBjaGlsZHJlbiBhbmQgaXRzIHJlcGxhY2VtZW50IHZhbHVlLAotICogd2hlbiB1c2VkIGJ5IDxjb2RlPkF0dHIudmFsdWU8L2NvZGU+IGZvciBleGFtcGxlLCBpcyBlbXB0eS4KLSAqIDxwPkFzIGZvciA8Y29kZT5FbnRpdHk8L2NvZGU+IG5vZGVzLCA8Y29kZT5FbnRpdHlSZWZlcmVuY2U8L2NvZGU+IG5vZGVzIGFuZAotICogYWxsIHRoZWlyIGRlc2NlbmRhbnRzIGFyZSByZWFkb25seS4KLSAqIDxwID48Yj5Ob3RlOjwvYj4gPGNvZGU+RW50aXR5UmVmZXJlbmNlPC9jb2RlPiBub2RlcyBtYXkgY2F1c2UgZWxlbWVudAotICogY29udGVudCBhbmQgYXR0cmlidXRlIHZhbHVlIG5vcm1hbGl6YXRpb24gcHJvYmxlbXMgd2hlbiwgc3VjaCBhcyBpbiBYTUwKLSAqIDEuMCBhbmQgWE1MIFNjaGVtYSwgdGhlIG5vcm1hbGl6YXRpb24gaXMgcGVyZm9ybWVkIGFmdGVyIGVudGl0eSByZWZlcmVuY2UKLSAqIGFyZSBleHBhbmRlZC4KLSAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy1ET00tTGV2ZWwtMy1Db3JlLTIwMDQwNDA3Jz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMyBDb3JlIFNwZWNpZmljYXRpb248L2E+LgotICovCi1wdWJsaWMgaW50ZXJmYWNlIEVudGl0eVJlZmVyZW5jZSBleHRlbmRzIE5vZGUgewotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy93M2MvZG9tL05hbWVMaXN0LmphdmEgYi9zcmMvb3JnL3czYy9kb20vTmFtZUxpc3QuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDFjZmUxMC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3czYy9kb20vTmFtZUxpc3QuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDk3ICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBUaGlzIGZpbGUgaXMgYXZhaWxhYmxlIHVuZGVyIGFuZCBnb3Zlcm5lZCBieSB0aGUgR05VIEdlbmVyYWwgUHVibGljCi0gKiBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqIEhvd2V2ZXIsIHRoZSBmb2xsb3dpbmcgbm90aWNlIGFjY29tcGFuaWVkIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIG9mIHRoaXMKLSAqIGZpbGUgYW5kLCBwZXIgaXRzIHRlcm1zLCBzaG91bGQgbm90IGJlIHJlbW92ZWQ6Ci0gKgotICogQ29weXJpZ2h0IChjKSAyMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCi0gKgotICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEV1cm9wZWFuIFJlc2VhcmNoIENvbnNvcnRpdW0gZm9yCi0gKiBJbmZvcm1hdGljcyBhbmQgTWF0aGVtYXRpY3MsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMKLSAqIHdvcmsgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQyhyKSBTb2Z0d2FyZSBMaWNlbnNlIFsxXSBpbiB0aGUgaG9wZSB0aGF0Ci0gKiBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQKLSAqIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4KLSAqCi0gKiBbMV0gaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8yMDAyL2NvcHlyaWdodC1zb2Z0d2FyZS0yMDAyMTIzMQotICovCi0KLXBhY2thZ2Ugb3JnLnczYy5kb207Ci0KLS8qKgotICogIFRoZSA8Y29kZT5OYW1lTGlzdDwvY29kZT4gaW50ZXJmYWNlIHByb3ZpZGVzIHRoZSBhYnN0cmFjdGlvbiBvZiBhbiBvcmRlcmVkCi0gKiBjb2xsZWN0aW9uIG9mIHBhcmFsbGVsIHBhaXJzIG9mIG5hbWUgYW5kIG5hbWVzcGFjZSB2YWx1ZXMgKHdoaWNoIGNvdWxkIGJlCi0gKiBudWxsIHZhbHVlcyksIHdpdGhvdXQgZGVmaW5pbmcgb3IgY29uc3RyYWluaW5nIGhvdyB0aGlzIGNvbGxlY3Rpb24gaXMKLSAqIGltcGxlbWVudGVkLiBUaGUgaXRlbXMgaW4gdGhlIDxjb2RlPk5hbWVMaXN0PC9jb2RlPiBhcmUgYWNjZXNzaWJsZSB2aWEgYW4KLSAqIGludGVncmFsIGluZGV4LCBzdGFydGluZyBmcm9tIDAuCi0gKiA8cD5TZWUgYWxzbyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMtRE9NLUxldmVsLTMtQ29yZS0yMDA0MDQwNyc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDMgQ29yZSBTcGVjaWZpY2F0aW9uPC9hPi4KLSAqIEBzaW5jZSBET00gTGV2ZWwgMwotICovCi1wdWJsaWMgaW50ZXJmYWNlIE5hbWVMaXN0IHsKLSAgICAvKioKLSAgICAgKiAgUmV0dXJucyB0aGUgPGNvZGU+aW5kZXg8L2NvZGU+dGggbmFtZSBpdGVtIGluIHRoZSBjb2xsZWN0aW9uLgotICAgICAqIEBwYXJhbSBpbmRleCBJbmRleCBpbnRvIHRoZSBjb2xsZWN0aW9uLgotICAgICAqIEByZXR1cm4gIFRoZSBuYW1lIGF0IHRoZSA8Y29kZT5pbmRleDwvY29kZT50aCBwb3NpdGlvbiBpbiB0aGUKLSAgICAgKiAgIDxjb2RlPk5hbWVMaXN0PC9jb2RlPiwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlcmUgaXMgbm8gbmFtZSBmb3IKLSAgICAgKiAgIHRoZSBzcGVjaWZpZWQgaW5kZXggb3IgaWYgdGhlIGluZGV4IGlzIG91dCBvZiByYW5nZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoaW50IGluZGV4KTsKLQotICAgIC8qKgotICAgICAqICBSZXR1cm5zIHRoZSA8Y29kZT5pbmRleDwvY29kZT50aCBuYW1lc3BhY2VVUkkgaXRlbSBpbiB0aGUgY29sbGVjdGlvbi4KLSAgICAgKiBAcGFyYW0gaW5kZXggSW5kZXggaW50byB0aGUgY29sbGVjdGlvbi4KLSAgICAgKiBAcmV0dXJuICBUaGUgbmFtZXNwYWNlIFVSSSBhdCB0aGUgPGNvZGU+aW5kZXg8L2NvZGU+dGggcG9zaXRpb24gaW4gdGhlCi0gICAgICogICA8Y29kZT5OYW1lTGlzdDwvY29kZT4sIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoZXJlIGlzIG5vIG5hbWUgZm9yCi0gICAgICogICB0aGUgc3BlY2lmaWVkIGluZGV4IG9yIGlmIHRoZSBpbmRleCBpcyBvdXQgb2YgcmFuZ2UuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXROYW1lc3BhY2VVUkkoaW50IGluZGV4KTsKLQotICAgIC8qKgotICAgICAqICBUaGUgbnVtYmVyIG9mIHBhaXJzIChuYW1lIGFuZCBuYW1lc3BhY2VVUkkpIGluIHRoZSBsaXN0LiBUaGUgcmFuZ2Ugb2YKLSAgICAgKiB2YWxpZCBjaGlsZCBub2RlIGluZGljZXMgaXMgMCB0byA8Y29kZT5sZW5ndGgtMTwvY29kZT4gaW5jbHVzaXZlLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0TGVuZ3RoKCk7Ci0KLSAgICAvKioKLSAgICAgKiAgVGVzdCBpZiBhIG5hbWUgaXMgcGFydCBvZiB0aGlzIDxjb2RlPk5hbWVMaXN0PC9jb2RlPi4KLSAgICAgKiBAcGFyYW0gc3RyICBUaGUgbmFtZSB0byBsb29rIGZvci4KLSAgICAgKiBAcmV0dXJuICA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgbmFtZSBoYXMgYmVlbiBmb3VuZCwKLSAgICAgKiAgIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gY29udGFpbnMoU3RyaW5nIHN0cik7Ci0KLSAgICAvKioKLSAgICAgKiAgVGVzdCBpZiB0aGUgcGFpciBuYW1lc3BhY2VVUkkvbmFtZSBpcyBwYXJ0IG9mIHRoaXMKLSAgICAgKiA8Y29kZT5OYW1lTGlzdDwvY29kZT4uCi0gICAgICogQHBhcmFtIG5hbWVzcGFjZVVSSSAgVGhlIG5hbWVzcGFjZSBVUkkgdG8gbG9vayBmb3IuCi0gICAgICogQHBhcmFtIG5hbWUgIFRoZSBuYW1lIHRvIGxvb2sgZm9yLgotICAgICAqIEByZXR1cm4gIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBwYWlyIG5hbWVzcGFjZVVSSS9uYW1lIGhhcyBiZWVuCi0gICAgICogICBmb3VuZCwgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc05TKFN0cmluZyBuYW1lc3BhY2VVUkksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbmFtZSk7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvdzNjL2RvbS9OYW1lZE5vZGVNYXAuamF2YSBiL3NyYy9vcmcvdzNjL2RvbS9OYW1lZE5vZGVNYXAuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDA0NjZjMS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3czYy9kb20vTmFtZWROb2RlTWFwLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMTIgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIFRoaXMgZmlsZSBpcyBhdmFpbGFibGUgdW5kZXIgYW5kIGdvdmVybmVkIGJ5IHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKLSAqIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICogSG93ZXZlciwgdGhlIGZvbGxvd2luZyBub3RpY2UgYWNjb21wYW5pZWQgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcwotICogZmlsZSBhbmQsIHBlciBpdHMgdGVybXMsIHNob3VsZCBub3QgYmUgcmVtb3ZlZDoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKLSAqCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgRXVyb3BlYW4gUmVzZWFyY2ggQ29uc29ydGl1bSBmb3IKLSAqIEluZm9ybWF0aWNzIGFuZCBNYXRoZW1hdGljcywgS2VpbyBVbml2ZXJzaXR5KS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcwotICogd29yayBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDKHIpIFNvZnR3YXJlIExpY2Vuc2UgWzFdIGluIHRoZSBob3BlIHRoYXQKLSAqIGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZAotICogd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLgotICoKLSAqIFsxXSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLzIwMDIvY29weXJpZ2h0LXNvZnR3YXJlLTIwMDIxMjMxCi0gKi8KLQotcGFja2FnZSBvcmcudzNjLmRvbTsKLQotLyoqCi0gKiBPYmplY3RzIGltcGxlbWVudGluZyB0aGUgPGNvZGU+TmFtZWROb2RlTWFwPC9jb2RlPiBpbnRlcmZhY2UgYXJlIHVzZWQgdG8KLSAqIHJlcHJlc2VudCBjb2xsZWN0aW9ucyBvZiBub2RlcyB0aGF0IGNhbiBiZSBhY2Nlc3NlZCBieSBuYW1lLiBOb3RlIHRoYXQKLSAqIDxjb2RlPk5hbWVkTm9kZU1hcDwvY29kZT4gZG9lcyBub3QgaW5oZXJpdCBmcm9tIDxjb2RlPk5vZGVMaXN0PC9jb2RlPjsKLSAqIDxjb2RlPk5hbWVkTm9kZU1hcHM8L2NvZGU+IGFyZSBub3QgbWFpbnRhaW5lZCBpbiBhbnkgcGFydGljdWxhciBvcmRlci4KLSAqIE9iamVjdHMgY29udGFpbmVkIGluIGFuIG9iamVjdCBpbXBsZW1lbnRpbmcgPGNvZGU+TmFtZWROb2RlTWFwPC9jb2RlPiBtYXkKLSAqIGFsc28gYmUgYWNjZXNzZWQgYnkgYW4gb3JkaW5hbCBpbmRleCwgYnV0IHRoaXMgaXMgc2ltcGx5IHRvIGFsbG93Ci0gKiBjb252ZW5pZW50IGVudW1lcmF0aW9uIG9mIHRoZSBjb250ZW50cyBvZiBhIDxjb2RlPk5hbWVkTm9kZU1hcDwvY29kZT4sCi0gKiBhbmQgZG9lcyBub3QgaW1wbHkgdGhhdCB0aGUgRE9NIHNwZWNpZmllcyBhbiBvcmRlciB0byB0aGVzZSBOb2Rlcy4KLSAqIDxwPjxjb2RlPk5hbWVkTm9kZU1hcDwvY29kZT4gb2JqZWN0cyBpbiB0aGUgRE9NIGFyZSBsaXZlLgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLURPTS1MZXZlbC0zLUNvcmUtMjAwNDA0MDcnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAzIENvcmUgU3BlY2lmaWNhdGlvbjwvYT4uCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgTmFtZWROb2RlTWFwIHsKLSAgICAvKioKLSAgICAgKiBSZXRyaWV2ZXMgYSBub2RlIHNwZWNpZmllZCBieSBuYW1lLgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSA8Y29kZT5ub2RlTmFtZTwvY29kZT4gb2YgYSBub2RlIHRvIHJldHJpZXZlLgotICAgICAqIEByZXR1cm4gQSA8Y29kZT5Ob2RlPC9jb2RlPiAob2YgYW55IHR5cGUpIHdpdGggdGhlIHNwZWNpZmllZAotICAgICAqICAgPGNvZGU+bm9kZU5hbWU8L2NvZGU+LCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiBpdCBkb2VzIG5vdCBpZGVudGlmeQotICAgICAqICAgYW55IG5vZGUgaW4gdGhpcyBtYXAuCi0gICAgICovCi0gICAgcHVibGljIE5vZGUgZ2V0TmFtZWRJdGVtKFN0cmluZyBuYW1lKTsKLQotICAgIC8qKgotICAgICAqIEFkZHMgYSBub2RlIHVzaW5nIGl0cyA8Y29kZT5ub2RlTmFtZTwvY29kZT4gYXR0cmlidXRlLiBJZiBhIG5vZGUgd2l0aAotICAgICAqIHRoYXQgbmFtZSBpcyBhbHJlYWR5IHByZXNlbnQgaW4gdGhpcyBtYXAsIGl0IGlzIHJlcGxhY2VkIGJ5IHRoZSBuZXcKLSAgICAgKiBvbmUuIFJlcGxhY2luZyBhIG5vZGUgYnkgaXRzZWxmIGhhcyBubyBlZmZlY3QuCi0gICAgICogPGJyPkFzIHRoZSA8Y29kZT5ub2RlTmFtZTwvY29kZT4gYXR0cmlidXRlIGlzIHVzZWQgdG8gZGVyaXZlIHRoZSBuYW1lCi0gICAgICogd2hpY2ggdGhlIG5vZGUgbXVzdCBiZSBzdG9yZWQgdW5kZXIsIG11bHRpcGxlIG5vZGVzIG9mIGNlcnRhaW4gdHlwZXMKLSAgICAgKiAodGhvc2UgdGhhdCBoYXZlIGEgInNwZWNpYWwiIHN0cmluZyB2YWx1ZSkgY2Fubm90IGJlIHN0b3JlZCBhcyB0aGUKLSAgICAgKiBuYW1lcyB3b3VsZCBjbGFzaC4gVGhpcyBpcyBzZWVuIGFzIHByZWZlcmFibGUgdG8gYWxsb3dpbmcgbm9kZXMgdG8gYmUKLSAgICAgKiBhbGlhc2VkLgotICAgICAqIEBwYXJhbSBhcmcgQSBub2RlIHRvIHN0b3JlIGluIHRoaXMgbWFwLiBUaGUgbm9kZSB3aWxsIGxhdGVyIGJlCi0gICAgICogICBhY2Nlc3NpYmxlIHVzaW5nIHRoZSB2YWx1ZSBvZiBpdHMgPGNvZGU+bm9kZU5hbWU8L2NvZGU+IGF0dHJpYnV0ZS4KLSAgICAgKiBAcmV0dXJuIElmIHRoZSBuZXcgPGNvZGU+Tm9kZTwvY29kZT4gcmVwbGFjZXMgYW4gZXhpc3Rpbmcgbm9kZSB0aGUKLSAgICAgKiAgIHJlcGxhY2VkIDxjb2RlPk5vZGU8L2NvZGU+IGlzIHJldHVybmVkLCBvdGhlcndpc2UgPGNvZGU+bnVsbDwvY29kZT4KLSAgICAgKiAgIGlzIHJldHVybmVkLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBXUk9OR19ET0NVTUVOVF9FUlI6IFJhaXNlZCBpZiA8Y29kZT5hcmc8L2NvZGU+IHdhcyBjcmVhdGVkIGZyb20gYQotICAgICAqICAgZGlmZmVyZW50IGRvY3VtZW50IHRoYW4gdGhlIG9uZSB0aGF0IGNyZWF0ZWQgdGhpcyBtYXAuCi0gICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBtYXAgaXMgcmVhZG9ubHkuCi0gICAgICogICA8YnI+SU5VU0VfQVRUUklCVVRFX0VSUjogUmFpc2VkIGlmIDxjb2RlPmFyZzwvY29kZT4gaXMgYW4KLSAgICAgKiAgIDxjb2RlPkF0dHI8L2NvZGU+IHRoYXQgaXMgYWxyZWFkeSBhbiBhdHRyaWJ1dGUgb2YgYW5vdGhlcgotICAgICAqICAgPGNvZGU+RWxlbWVudDwvY29kZT4gb2JqZWN0LiBUaGUgRE9NIHVzZXIgbXVzdCBleHBsaWNpdGx5IGNsb25lCi0gICAgICogICA8Y29kZT5BdHRyPC9jb2RlPiBub2RlcyB0byByZS11c2UgdGhlbSBpbiBvdGhlciBlbGVtZW50cy4KLSAgICAgKiAgIDxicj5ISUVSQVJDSFlfUkVRVUVTVF9FUlI6IFJhaXNlZCBpZiBhbiBhdHRlbXB0IGlzIG1hZGUgdG8gYWRkIGEgbm9kZQotICAgICAqICAgZG9lc24ndCBiZWxvbmcgaW4gdGhpcyBOYW1lZE5vZGVNYXAuIEV4YW1wbGVzIHdvdWxkIGluY2x1ZGUgdHJ5aW5nCi0gICAgICogICB0byBpbnNlcnQgc29tZXRoaW5nIG90aGVyIHRoYW4gYW4gQXR0ciBub2RlIGludG8gYW4gRWxlbWVudCdzIG1hcAotICAgICAqICAgb2YgYXR0cmlidXRlcywgb3IgYSBub24tRW50aXR5IG5vZGUgaW50byB0aGUgRG9jdW1lbnRUeXBlJ3MgbWFwIG9mCi0gICAgICogICBFbnRpdGllcy4KLSAgICAgKi8KLSAgICBwdWJsaWMgTm9kZSBzZXROYW1lZEl0ZW0oTm9kZSBhcmcpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBSZW1vdmVzIGEgbm9kZSBzcGVjaWZpZWQgYnkgbmFtZS4gV2hlbiB0aGlzIG1hcCBjb250YWlucyB0aGUgYXR0cmlidXRlcwotICAgICAqIGF0dGFjaGVkIHRvIGFuIGVsZW1lbnQsIGlmIHRoZSByZW1vdmVkIGF0dHJpYnV0ZSBpcyBrbm93biB0byBoYXZlIGEKLSAgICAgKiBkZWZhdWx0IHZhbHVlLCBhbiBhdHRyaWJ1dGUgaW1tZWRpYXRlbHkgYXBwZWFycyBjb250YWluaW5nIHRoZQotICAgICAqIGRlZmF1bHQgdmFsdWUgYXMgd2VsbCBhcyB0aGUgY29ycmVzcG9uZGluZyBuYW1lc3BhY2UgVVJJLCBsb2NhbCBuYW1lLAotICAgICAqIGFuZCBwcmVmaXggd2hlbiBhcHBsaWNhYmxlLgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSA8Y29kZT5ub2RlTmFtZTwvY29kZT4gb2YgdGhlIG5vZGUgdG8gcmVtb3ZlLgotICAgICAqIEByZXR1cm4gVGhlIG5vZGUgcmVtb3ZlZCBmcm9tIHRoaXMgbWFwIGlmIGEgbm9kZSB3aXRoIHN1Y2ggYSBuYW1lCi0gICAgICogICBleGlzdHMuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIE5PVF9GT1VORF9FUlI6IFJhaXNlZCBpZiB0aGVyZSBpcyBubyBub2RlIG5hbWVkIDxjb2RlPm5hbWU8L2NvZGU+IGluCi0gICAgICogICB0aGlzIG1hcC4KLSAgICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIG1hcCBpcyByZWFkb25seS4KLSAgICAgKi8KLSAgICBwdWJsaWMgTm9kZSByZW1vdmVOYW1lZEl0ZW0oU3RyaW5nIG5hbWUpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSA8Y29kZT5pbmRleDwvY29kZT50aCBpdGVtIGluIHRoZSBtYXAuIElmIDxjb2RlPmluZGV4PC9jb2RlPgotICAgICAqIGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byB0aGUgbnVtYmVyIG9mIG5vZGVzIGluIHRoaXMgbWFwLCB0aGlzCi0gICAgICogcmV0dXJucyA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICAgKiBAcGFyYW0gaW5kZXggSW5kZXggaW50byB0aGlzIG1hcC4KLSAgICAgKiBAcmV0dXJuIFRoZSBub2RlIGF0IHRoZSA8Y29kZT5pbmRleDwvY29kZT50aCBwb3NpdGlvbiBpbiB0aGUgbWFwLCBvcgotICAgICAqICAgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhhdCBpcyBub3QgYSB2YWxpZCBpbmRleC4KLSAgICAgKi8KLSAgICBwdWJsaWMgTm9kZSBpdGVtKGludCBpbmRleCk7Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgbnVtYmVyIG9mIG5vZGVzIGluIHRoaXMgbWFwLiBUaGUgcmFuZ2Ugb2YgdmFsaWQgY2hpbGQgbm9kZSBpbmRpY2VzCi0gICAgICogaXMgPGNvZGU+MDwvY29kZT4gdG8gPGNvZGU+bGVuZ3RoLTE8L2NvZGU+IGluY2x1c2l2ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldExlbmd0aCgpOwotCi0gICAgLyoqCi0gICAgICogUmV0cmlldmVzIGEgbm9kZSBzcGVjaWZpZWQgYnkgbG9jYWwgbmFtZSBhbmQgbmFtZXNwYWNlIFVSSS4KLSAgICAgKiA8YnI+UGVyIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk5L1JFQy14bWwtbmFtZXMtMTk5OTAxMTQvJz5YTUwgTmFtZXNwYWNlczwvYT5dCi0gICAgICogLCBhcHBsaWNhdGlvbnMgbXVzdCB1c2UgdGhlIHZhbHVlIG51bGwgYXMgdGhlIG5hbWVzcGFjZVVSSSBwYXJhbWV0ZXIKLSAgICAgKiBmb3IgbWV0aG9kcyBpZiB0aGV5IHdpc2ggdG8gaGF2ZSBubyBuYW1lc3BhY2UuCi0gICAgICogQHBhcmFtIG5hbWVzcGFjZVVSSSBUaGUgbmFtZXNwYWNlIFVSSSBvZiB0aGUgbm9kZSB0byByZXRyaWV2ZS4KLSAgICAgKiBAcGFyYW0gbG9jYWxOYW1lIFRoZSBsb2NhbCBuYW1lIG9mIHRoZSBub2RlIHRvIHJldHJpZXZlLgotICAgICAqIEByZXR1cm4gQSA8Y29kZT5Ob2RlPC9jb2RlPiAob2YgYW55IHR5cGUpIHdpdGggdGhlIHNwZWNpZmllZCBsb2NhbAotICAgICAqICAgbmFtZSBhbmQgbmFtZXNwYWNlIFVSSSwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhleSBkbyBub3QKLSAgICAgKiAgIGlkZW50aWZ5IGFueSBub2RlIGluIHRoaXMgbWFwLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBOT1RfU1VQUE9SVEVEX0VSUjogTWF5IGJlIHJhaXNlZCBpZiB0aGUgaW1wbGVtZW50YXRpb24gZG9lcyBub3QKLSAgICAgKiAgIHN1cHBvcnQgdGhlIGZlYXR1cmUgIlhNTCIgYW5kIHRoZSBsYW5ndWFnZSBleHBvc2VkIHRocm91Z2ggdGhlCi0gICAgICogICBEb2N1bWVudCBkb2VzIG5vdCBzdXBwb3J0IFhNTCBOYW1lc3BhY2VzIChzdWNoIGFzIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk5L1JFQy1odG1sNDAxLTE5OTkxMjI0Lyc+SFRNTCA0LjAxPC9hPl0pLgotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMgotICAgICAqLwotICAgIHB1YmxpYyBOb2RlIGdldE5hbWVkSXRlbU5TKFN0cmluZyBuYW1lc3BhY2VVUkksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGxvY2FsTmFtZSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogQWRkcyBhIG5vZGUgdXNpbmcgaXRzIDxjb2RlPm5hbWVzcGFjZVVSSTwvY29kZT4gYW5kCi0gICAgICogPGNvZGU+bG9jYWxOYW1lPC9jb2RlPi4gSWYgYSBub2RlIHdpdGggdGhhdCBuYW1lc3BhY2UgVVJJIGFuZCB0aGF0Ci0gICAgICogbG9jYWwgbmFtZSBpcyBhbHJlYWR5IHByZXNlbnQgaW4gdGhpcyBtYXAsIGl0IGlzIHJlcGxhY2VkIGJ5IHRoZSBuZXcKLSAgICAgKiBvbmUuIFJlcGxhY2luZyBhIG5vZGUgYnkgaXRzZWxmIGhhcyBubyBlZmZlY3QuCi0gICAgICogPGJyPlBlciBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMTk5OS9SRUMteG1sLW5hbWVzLTE5OTkwMTE0Lyc+WE1MIE5hbWVzcGFjZXM8L2E+XQotICAgICAqICwgYXBwbGljYXRpb25zIG11c3QgdXNlIHRoZSB2YWx1ZSBudWxsIGFzIHRoZSBuYW1lc3BhY2VVUkkgcGFyYW1ldGVyCi0gICAgICogZm9yIG1ldGhvZHMgaWYgdGhleSB3aXNoIHRvIGhhdmUgbm8gbmFtZXNwYWNlLgotICAgICAqIEBwYXJhbSBhcmcgQSBub2RlIHRvIHN0b3JlIGluIHRoaXMgbWFwLiBUaGUgbm9kZSB3aWxsIGxhdGVyIGJlCi0gICAgICogICBhY2Nlc3NpYmxlIHVzaW5nIHRoZSB2YWx1ZSBvZiBpdHMgPGNvZGU+bmFtZXNwYWNlVVJJPC9jb2RlPiBhbmQKLSAgICAgKiAgIDxjb2RlPmxvY2FsTmFtZTwvY29kZT4gYXR0cmlidXRlcy4KLSAgICAgKiBAcmV0dXJuIElmIHRoZSBuZXcgPGNvZGU+Tm9kZTwvY29kZT4gcmVwbGFjZXMgYW4gZXhpc3Rpbmcgbm9kZSB0aGUKLSAgICAgKiAgIHJlcGxhY2VkIDxjb2RlPk5vZGU8L2NvZGU+IGlzIHJldHVybmVkLCBvdGhlcndpc2UgPGNvZGU+bnVsbDwvY29kZT4KLSAgICAgKiAgIGlzIHJldHVybmVkLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBXUk9OR19ET0NVTUVOVF9FUlI6IFJhaXNlZCBpZiA8Y29kZT5hcmc8L2NvZGU+IHdhcyBjcmVhdGVkIGZyb20gYQotICAgICAqICAgZGlmZmVyZW50IGRvY3VtZW50IHRoYW4gdGhlIG9uZSB0aGF0IGNyZWF0ZWQgdGhpcyBtYXAuCi0gICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBtYXAgaXMgcmVhZG9ubHkuCi0gICAgICogICA8YnI+SU5VU0VfQVRUUklCVVRFX0VSUjogUmFpc2VkIGlmIDxjb2RlPmFyZzwvY29kZT4gaXMgYW4KLSAgICAgKiAgIDxjb2RlPkF0dHI8L2NvZGU+IHRoYXQgaXMgYWxyZWFkeSBhbiBhdHRyaWJ1dGUgb2YgYW5vdGhlcgotICAgICAqICAgPGNvZGU+RWxlbWVudDwvY29kZT4gb2JqZWN0LiBUaGUgRE9NIHVzZXIgbXVzdCBleHBsaWNpdGx5IGNsb25lCi0gICAgICogICA8Y29kZT5BdHRyPC9jb2RlPiBub2RlcyB0byByZS11c2UgdGhlbSBpbiBvdGhlciBlbGVtZW50cy4KLSAgICAgKiAgIDxicj5ISUVSQVJDSFlfUkVRVUVTVF9FUlI6IFJhaXNlZCBpZiBhbiBhdHRlbXB0IGlzIG1hZGUgdG8gYWRkIGEgbm9kZQotICAgICAqICAgZG9lc24ndCBiZWxvbmcgaW4gdGhpcyBOYW1lZE5vZGVNYXAuIEV4YW1wbGVzIHdvdWxkIGluY2x1ZGUgdHJ5aW5nCi0gICAgICogICB0byBpbnNlcnQgc29tZXRoaW5nIG90aGVyIHRoYW4gYW4gQXR0ciBub2RlIGludG8gYW4gRWxlbWVudCdzIG1hcAotICAgICAqICAgb2YgYXR0cmlidXRlcywgb3IgYSBub24tRW50aXR5IG5vZGUgaW50byB0aGUgRG9jdW1lbnRUeXBlJ3MgbWFwIG9mCi0gICAgICogICBFbnRpdGllcy4KLSAgICAgKiAgIDxicj5OT1RfU1VQUE9SVEVEX0VSUjogTWF5IGJlIHJhaXNlZCBpZiB0aGUgaW1wbGVtZW50YXRpb24gZG9lcyBub3QKLSAgICAgKiAgIHN1cHBvcnQgdGhlIGZlYXR1cmUgIlhNTCIgYW5kIHRoZSBsYW5ndWFnZSBleHBvc2VkIHRocm91Z2ggdGhlCi0gICAgICogICBEb2N1bWVudCBkb2VzIG5vdCBzdXBwb3J0IFhNTCBOYW1lc3BhY2VzIChzdWNoIGFzIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk5L1JFQy1odG1sNDAxLTE5OTkxMjI0Lyc+SFRNTCA0LjAxPC9hPl0pLgotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMgotICAgICAqLwotICAgIHB1YmxpYyBOb2RlIHNldE5hbWVkSXRlbU5TKE5vZGUgYXJnKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBSZW1vdmVzIGEgbm9kZSBzcGVjaWZpZWQgYnkgbG9jYWwgbmFtZSBhbmQgbmFtZXNwYWNlIFVSSS4gQSByZW1vdmVkCi0gICAgICogYXR0cmlidXRlIG1heSBiZSBrbm93biB0byBoYXZlIGEgZGVmYXVsdCB2YWx1ZSB3aGVuIHRoaXMgbWFwIGNvbnRhaW5zCi0gICAgICogdGhlIGF0dHJpYnV0ZXMgYXR0YWNoZWQgdG8gYW4gZWxlbWVudCwgYXMgcmV0dXJuZWQgYnkgdGhlIGF0dHJpYnV0ZXMKLSAgICAgKiBhdHRyaWJ1dGUgb2YgdGhlIDxjb2RlPk5vZGU8L2NvZGU+IGludGVyZmFjZS4gSWYgc28sIGFuIGF0dHJpYnV0ZQotICAgICAqIGltbWVkaWF0ZWx5IGFwcGVhcnMgY29udGFpbmluZyB0aGUgZGVmYXVsdCB2YWx1ZSBhcyB3ZWxsIGFzIHRoZQotICAgICAqIGNvcnJlc3BvbmRpbmcgbmFtZXNwYWNlIFVSSSwgbG9jYWwgbmFtZSwgYW5kIHByZWZpeCB3aGVuIGFwcGxpY2FibGUuCi0gICAgICogPGJyPlBlciBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMTk5OS9SRUMteG1sLW5hbWVzLTE5OTkwMTE0Lyc+WE1MIE5hbWVzcGFjZXM8L2E+XQotICAgICAqICwgYXBwbGljYXRpb25zIG11c3QgdXNlIHRoZSB2YWx1ZSBudWxsIGFzIHRoZSBuYW1lc3BhY2VVUkkgcGFyYW1ldGVyCi0gICAgICogZm9yIG1ldGhvZHMgaWYgdGhleSB3aXNoIHRvIGhhdmUgbm8gbmFtZXNwYWNlLgotICAgICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkgVGhlIG5hbWVzcGFjZSBVUkkgb2YgdGhlIG5vZGUgdG8gcmVtb3ZlLgotICAgICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGxvY2FsIG5hbWUgb2YgdGhlIG5vZGUgdG8gcmVtb3ZlLgotICAgICAqIEByZXR1cm4gVGhlIG5vZGUgcmVtb3ZlZCBmcm9tIHRoaXMgbWFwIGlmIGEgbm9kZSB3aXRoIHN1Y2ggYSBsb2NhbAotICAgICAqICAgbmFtZSBhbmQgbmFtZXNwYWNlIFVSSSBleGlzdHMuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIE5PVF9GT1VORF9FUlI6IFJhaXNlZCBpZiB0aGVyZSBpcyBubyBub2RlIHdpdGggdGhlIHNwZWNpZmllZAotICAgICAqICAgPGNvZGU+bmFtZXNwYWNlVVJJPC9jb2RlPiBhbmQgPGNvZGU+bG9jYWxOYW1lPC9jb2RlPiBpbiB0aGlzIG1hcC4KLSAgICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIG1hcCBpcyByZWFkb25seS4KLSAgICAgKiAgIDxicj5OT1RfU1VQUE9SVEVEX0VSUjogTWF5IGJlIHJhaXNlZCBpZiB0aGUgaW1wbGVtZW50YXRpb24gZG9lcyBub3QKLSAgICAgKiAgIHN1cHBvcnQgdGhlIGZlYXR1cmUgIlhNTCIgYW5kIHRoZSBsYW5ndWFnZSBleHBvc2VkIHRocm91Z2ggdGhlCi0gICAgICogICBEb2N1bWVudCBkb2VzIG5vdCBzdXBwb3J0IFhNTCBOYW1lc3BhY2VzIChzdWNoIGFzIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk5L1JFQy1odG1sNDAxLTE5OTkxMjI0Lyc+SFRNTCA0LjAxPC9hPl0pLgotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMgotICAgICAqLwotICAgIHB1YmxpYyBOb2RlIHJlbW92ZU5hbWVkSXRlbU5TKFN0cmluZyBuYW1lc3BhY2VVUkksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGxvY2FsTmFtZSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL3czYy9kb20vTm9kZS5qYXZhIGIvc3JjL29yZy93M2MvZG9tL05vZGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNjg0MDRiOS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3czYy9kb20vTm9kZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTUzICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBUaGlzIGZpbGUgaXMgYXZhaWxhYmxlIHVuZGVyIGFuZCBnb3Zlcm5lZCBieSB0aGUgR05VIEdlbmVyYWwgUHVibGljCi0gKiBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqIEhvd2V2ZXIsIHRoZSBmb2xsb3dpbmcgbm90aWNlIGFjY29tcGFuaWVkIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIG9mIHRoaXMKLSAqIGZpbGUgYW5kLCBwZXIgaXRzIHRlcm1zLCBzaG91bGQgbm90IGJlIHJlbW92ZWQ6Ci0gKgotICogQ29weXJpZ2h0IChjKSAyMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCi0gKgotICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEV1cm9wZWFuIFJlc2VhcmNoIENvbnNvcnRpdW0gZm9yCi0gKiBJbmZvcm1hdGljcyBhbmQgTWF0aGVtYXRpY3MsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMKLSAqIHdvcmsgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQyhyKSBTb2Z0d2FyZSBMaWNlbnNlIFsxXSBpbiB0aGUgaG9wZSB0aGF0Ci0gKiBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQKLSAqIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4KLSAqCi0gKiBbMV0gaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8yMDAyL2NvcHlyaWdodC1zb2Z0d2FyZS0yMDAyMTIzMQotICovCi0KLXBhY2thZ2Ugb3JnLnczYy5kb207Ci0KLS8qKgotICogVGhlIDxjb2RlPk5vZGU8L2NvZGU+IGludGVyZmFjZSBpcyB0aGUgcHJpbWFyeSBkYXRhdHlwZSBmb3IgdGhlIGVudGlyZQotICogRG9jdW1lbnQgT2JqZWN0IE1vZGVsLiBJdCByZXByZXNlbnRzIGEgc2luZ2xlIG5vZGUgaW4gdGhlIGRvY3VtZW50IHRyZWUuCi0gKiBXaGlsZSBhbGwgb2JqZWN0cyBpbXBsZW1lbnRpbmcgdGhlIDxjb2RlPk5vZGU8L2NvZGU+IGludGVyZmFjZSBleHBvc2UKLSAqIG1ldGhvZHMgZm9yIGRlYWxpbmcgd2l0aCBjaGlsZHJlbiwgbm90IGFsbCBvYmplY3RzIGltcGxlbWVudGluZyB0aGUKLSAqIDxjb2RlPk5vZGU8L2NvZGU+IGludGVyZmFjZSBtYXkgaGF2ZSBjaGlsZHJlbi4gRm9yIGV4YW1wbGUsCi0gKiA8Y29kZT5UZXh0PC9jb2RlPiBub2RlcyBtYXkgbm90IGhhdmUgY2hpbGRyZW4sIGFuZCBhZGRpbmcgY2hpbGRyZW4gdG8KLSAqIHN1Y2ggbm9kZXMgcmVzdWx0cyBpbiBhIDxjb2RlPkRPTUV4Y2VwdGlvbjwvY29kZT4gYmVpbmcgcmFpc2VkLgotICogPHA+VGhlIGF0dHJpYnV0ZXMgPGNvZGU+bm9kZU5hbWU8L2NvZGU+LCA8Y29kZT5ub2RlVmFsdWU8L2NvZGU+IGFuZAotICogPGNvZGU+YXR0cmlidXRlczwvY29kZT4gYXJlIGluY2x1ZGVkIGFzIGEgbWVjaGFuaXNtIHRvIGdldCBhdCBub2RlCi0gKiBpbmZvcm1hdGlvbiB3aXRob3V0IGNhc3RpbmcgZG93biB0byB0aGUgc3BlY2lmaWMgZGVyaXZlZCBpbnRlcmZhY2UuIEluCi0gKiBjYXNlcyB3aGVyZSB0aGVyZSBpcyBubyBvYnZpb3VzIG1hcHBpbmcgb2YgdGhlc2UgYXR0cmlidXRlcyBmb3IgYQotICogc3BlY2lmaWMgPGNvZGU+bm9kZVR5cGU8L2NvZGU+IChlLmcuLCA8Y29kZT5ub2RlVmFsdWU8L2NvZGU+IGZvciBhbgotICogPGNvZGU+RWxlbWVudDwvY29kZT4gb3IgPGNvZGU+YXR0cmlidXRlczwvY29kZT4gZm9yIGEgPGNvZGU+Q29tbWVudDwvY29kZT4KLSAqICksIHRoaXMgcmV0dXJucyA8Y29kZT5udWxsPC9jb2RlPi4gTm90ZSB0aGF0IHRoZSBzcGVjaWFsaXplZCBpbnRlcmZhY2VzCi0gKiBtYXkgY29udGFpbiBhZGRpdGlvbmFsIGFuZCBtb3JlIGNvbnZlbmllbnQgbWVjaGFuaXNtcyB0byBnZXQgYW5kIHNldCB0aGUKLSAqIHJlbGV2YW50IGluZm9ybWF0aW9uLgotICogPHA+VGhlIHZhbHVlcyBvZiA8Y29kZT5ub2RlTmFtZTwvY29kZT4sCi0gKiA8Y29kZT5ub2RlVmFsdWU8L2NvZGU+LCBhbmQgPGNvZGU+YXR0cmlidXRlczwvY29kZT4gdmFyeSBhY2NvcmRpbmcgdG8gdGhlCi0gKiBub2RlIHR5cGUgYXMgZm9sbG93czoKLSAqIDx0YWJsZSBib3JkZXI9JzEnIGNlbGxwYWRkaW5nPSczJz4KLSAqIDx0cj4KLSAqIDx0aD5JbnRlcmZhY2U8L3RoPgotICogPHRoPm5vZGVOYW1lPC90aD4KLSAqIDx0aD5ub2RlVmFsdWU8L3RoPgotICogPHRoPmF0dHJpYnV0ZXM8L3RoPgotICogPC90cj4KLSAqIDx0cj4KLSAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+Ci0gKiA8Y29kZT5BdHRyPC9jb2RlPjwvdGQ+Ci0gKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPnNhbWUgYXMgPGNvZGU+QXR0ci5uYW1lPC9jb2RlPjwvdGQ+Ci0gKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPnNhbWUgYXMKLSAqIDxjb2RlPkF0dHIudmFsdWU8L2NvZGU+PC90ZD4KLSAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+PGNvZGU+bnVsbDwvY29kZT48L3RkPgotICogPC90cj4KLSAqIDx0cj4KLSAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+PGNvZGU+Q0RBVEFTZWN0aW9uPC9jb2RlPjwvdGQ+Ci0gKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPgotICogPGNvZGU+IiNjZGF0YS1zZWN0aW9uIjwvY29kZT48L3RkPgotICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz5zYW1lIGFzIDxjb2RlPkNoYXJhY3RlckRhdGEuZGF0YTwvY29kZT4sIHRoZQotICogY29udGVudCBvZiB0aGUgQ0RBVEEgU2VjdGlvbjwvdGQ+Ci0gKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPjxjb2RlPm51bGw8L2NvZGU+PC90ZD4KLSAqIDwvdHI+Ci0gKiA8dHI+Ci0gKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPjxjb2RlPkNvbW1lbnQ8L2NvZGU+PC90ZD4KLSAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+Ci0gKiA8Y29kZT4iI2NvbW1lbnQiPC9jb2RlPjwvdGQ+Ci0gKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPnNhbWUgYXMgPGNvZGU+Q2hhcmFjdGVyRGF0YS5kYXRhPC9jb2RlPiwgdGhlCi0gKiBjb250ZW50IG9mIHRoZSBjb21tZW50PC90ZD4KLSAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+PGNvZGU+bnVsbDwvY29kZT48L3RkPgotICogPC90cj4KLSAqIDx0cj4KLSAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+PGNvZGU+RG9jdW1lbnQ8L2NvZGU+PC90ZD4KLSAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+Ci0gKiA8Y29kZT4iI2RvY3VtZW50IjwvY29kZT48L3RkPgotICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz48Y29kZT5udWxsPC9jb2RlPjwvdGQ+Ci0gKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPjxjb2RlPm51bGw8L2NvZGU+PC90ZD4KLSAqIDwvdHI+Ci0gKiA8dHI+Ci0gKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPgotICogPGNvZGU+RG9jdW1lbnRGcmFnbWVudDwvY29kZT48L3RkPgotICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz48Y29kZT4iI2RvY3VtZW50LWZyYWdtZW50IjwvY29kZT48L3RkPgotICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz4KLSAqIDxjb2RlPm51bGw8L2NvZGU+PC90ZD4KLSAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+PGNvZGU+bnVsbDwvY29kZT48L3RkPgotICogPC90cj4KLSAqIDx0cj4KLSAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+PGNvZGU+RG9jdW1lbnRUeXBlPC9jb2RlPjwvdGQ+Ci0gKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPnNhbWUgYXMKLSAqIDxjb2RlPkRvY3VtZW50VHlwZS5uYW1lPC9jb2RlPjwvdGQ+Ci0gKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPjxjb2RlPm51bGw8L2NvZGU+PC90ZD4KLSAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+PGNvZGU+bnVsbDwvY29kZT48L3RkPgotICogPC90cj4KLSAqIDx0cj4KLSAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+Ci0gKiA8Y29kZT5FbGVtZW50PC9jb2RlPjwvdGQ+Ci0gKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPnNhbWUgYXMgPGNvZGU+RWxlbWVudC50YWdOYW1lPC9jb2RlPjwvdGQ+Ci0gKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPjxjb2RlPm51bGw8L2NvZGU+PC90ZD4KLSAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+Ci0gKiA8Y29kZT5OYW1lZE5vZGVNYXA8L2NvZGU+PC90ZD4KLSAqIDwvdHI+Ci0gKiA8dHI+Ci0gKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPjxjb2RlPkVudGl0eTwvY29kZT48L3RkPgotICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz5lbnRpdHkgbmFtZTwvdGQ+Ci0gKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPjxjb2RlPm51bGw8L2NvZGU+PC90ZD4KLSAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+Ci0gKiA8Y29kZT5udWxsPC9jb2RlPjwvdGQ+Ci0gKiA8L3RyPgotICogPHRyPgotICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz48Y29kZT5FbnRpdHlSZWZlcmVuY2U8L2NvZGU+PC90ZD4KLSAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+bmFtZSBvZiBlbnRpdHkgcmVmZXJlbmNlZDwvdGQ+Ci0gKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPgotICogPGNvZGU+bnVsbDwvY29kZT48L3RkPgotICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz48Y29kZT5udWxsPC9jb2RlPjwvdGQ+Ci0gKiA8L3RyPgotICogPHRyPgotICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz48Y29kZT5Ob3RhdGlvbjwvY29kZT48L3RkPgotICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz5ub3RhdGlvbiBuYW1lPC90ZD4KLSAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+Ci0gKiA8Y29kZT5udWxsPC9jb2RlPjwvdGQ+Ci0gKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPjxjb2RlPm51bGw8L2NvZGU+PC90ZD4KLSAqIDwvdHI+Ci0gKiA8dHI+Ci0gKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPjxjb2RlPlByb2Nlc3NpbmdJbnN0cnVjdGlvbjwvY29kZT48L3RkPgotICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz5zYW1lCi0gKiBhcyA8Y29kZT5Qcm9jZXNzaW5nSW5zdHJ1Y3Rpb24udGFyZ2V0PC9jb2RlPjwvdGQ+Ci0gKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPnNhbWUgYXMKLSAqIDxjb2RlPlByb2Nlc3NpbmdJbnN0cnVjdGlvbi5kYXRhPC9jb2RlPjwvdGQ+Ci0gKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPjxjb2RlPm51bGw8L2NvZGU+PC90ZD4KLSAqIDwvdHI+Ci0gKiA8dHI+Ci0gKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPjxjb2RlPlRleHQ8L2NvZGU+PC90ZD4KLSAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+Ci0gKiA8Y29kZT4iI3RleHQiPC9jb2RlPjwvdGQ+Ci0gKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPnNhbWUgYXMgPGNvZGU+Q2hhcmFjdGVyRGF0YS5kYXRhPC9jb2RlPiwgdGhlIGNvbnRlbnQKLSAqIG9mIHRoZSB0ZXh0IG5vZGU8L3RkPgotICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz48Y29kZT5udWxsPC9jb2RlPjwvdGQ+Ci0gKiA8L3RyPgotICogPC90YWJsZT4KLSAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy1ET00tTGV2ZWwtMy1Db3JlLTIwMDQwNDA3Jz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMyBDb3JlIFNwZWNpZmljYXRpb248L2E+LgotICovCi1wdWJsaWMgaW50ZXJmYWNlIE5vZGUgewotICAgIC8vIE5vZGVUeXBlCi0gICAgLyoqCi0gICAgICogVGhlIG5vZGUgaXMgYW4gPGNvZGU+RWxlbWVudDwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBFTEVNRU5UX05PREUgICAgICAgICAgICAgID0gMTsKLSAgICAvKioKLSAgICAgKiBUaGUgbm9kZSBpcyBhbiA8Y29kZT5BdHRyPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IEFUVFJJQlVURV9OT0RFICAgICAgICAgICAgPSAyOwotICAgIC8qKgotICAgICAqIFRoZSBub2RlIGlzIGEgPGNvZGU+VGV4dDwvY29kZT4gbm9kZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFRFWFRfTk9ERSAgICAgICAgICAgICAgICAgPSAzOwotICAgIC8qKgotICAgICAqIFRoZSBub2RlIGlzIGEgPGNvZGU+Q0RBVEFTZWN0aW9uPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IENEQVRBX1NFQ1RJT05fTk9ERSAgICAgICAgPSA0OwotICAgIC8qKgotICAgICAqIFRoZSBub2RlIGlzIGFuIDxjb2RlPkVudGl0eVJlZmVyZW5jZTwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBFTlRJVFlfUkVGRVJFTkNFX05PREUgICAgID0gNTsKLSAgICAvKioKLSAgICAgKiBUaGUgbm9kZSBpcyBhbiA8Y29kZT5FbnRpdHk8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgRU5USVRZX05PREUgICAgICAgICAgICAgICA9IDY7Ci0gICAgLyoqCi0gICAgICogVGhlIG5vZGUgaXMgYSA8Y29kZT5Qcm9jZXNzaW5nSW5zdHJ1Y3Rpb248L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFID0gNzsKLSAgICAvKioKLSAgICAgKiBUaGUgbm9kZSBpcyBhIDxjb2RlPkNvbW1lbnQ8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgQ09NTUVOVF9OT0RFICAgICAgICAgICAgICA9IDg7Ci0gICAgLyoqCi0gICAgICogVGhlIG5vZGUgaXMgYSA8Y29kZT5Eb2N1bWVudDwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBET0NVTUVOVF9OT0RFICAgICAgICAgICAgID0gOTsKLSAgICAvKioKLSAgICAgKiBUaGUgbm9kZSBpcyBhIDxjb2RlPkRvY3VtZW50VHlwZTwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBET0NVTUVOVF9UWVBFX05PREUgICAgICAgID0gMTA7Ci0gICAgLyoqCi0gICAgICogVGhlIG5vZGUgaXMgYSA8Y29kZT5Eb2N1bWVudEZyYWdtZW50PC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IERPQ1VNRU5UX0ZSQUdNRU5UX05PREUgICAgPSAxMTsKLSAgICAvKioKLSAgICAgKiBUaGUgbm9kZSBpcyBhIDxjb2RlPk5vdGF0aW9uPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IE5PVEFUSU9OX05PREUgICAgICAgICAgICAgPSAxMjsKLQotICAgIC8qKgotICAgICAqIFRoZSBuYW1lIG9mIHRoaXMgbm9kZSwgZGVwZW5kaW5nIG9uIGl0cyB0eXBlOyBzZWUgdGhlIHRhYmxlIGFib3ZlLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Tm9kZU5hbWUoKTsKLQotICAgIC8qKgotICAgICAqIFRoZSB2YWx1ZSBvZiB0aGlzIG5vZGUsIGRlcGVuZGluZyBvbiBpdHMgdHlwZTsgc2VlIHRoZSB0YWJsZSBhYm92ZS4KLSAgICAgKiBXaGVuIGl0IGlzIGRlZmluZWQgdG8gYmUgPGNvZGU+bnVsbDwvY29kZT4sIHNldHRpbmcgaXQgaGFzIG5vIGVmZmVjdCwKLSAgICAgKiBpbmNsdWRpbmcgaWYgdGhlIG5vZGUgaXMgcmVhZC1vbmx5LgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBET01TVFJJTkdfU0laRV9FUlI6IFJhaXNlZCB3aGVuIGl0IHdvdWxkIHJldHVybiBtb3JlIGNoYXJhY3RlcnMgdGhhbgotICAgICAqICAgZml0IGluIGEgPGNvZGU+RE9NU3RyaW5nPC9jb2RlPiB2YXJpYWJsZSBvbiB0aGUgaW1wbGVtZW50YXRpb24KLSAgICAgKiAgIHBsYXRmb3JtLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Tm9kZVZhbHVlKCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0gICAgLyoqCi0gICAgICogVGhlIHZhbHVlIG9mIHRoaXMgbm9kZSwgZGVwZW5kaW5nIG9uIGl0cyB0eXBlOyBzZWUgdGhlIHRhYmxlIGFib3ZlLgotICAgICAqIFdoZW4gaXQgaXMgZGVmaW5lZCB0byBiZSA8Y29kZT5udWxsPC9jb2RlPiwgc2V0dGluZyBpdCBoYXMgbm8gZWZmZWN0LAotICAgICAqIGluY2x1ZGluZyBpZiB0aGUgbm9kZSBpcyByZWFkLW9ubHkuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIHdoZW4gdGhlIG5vZGUgaXMgcmVhZG9ubHkgYW5kIGlmCi0gICAgICogICBpdCBpcyBub3QgZGVmaW5lZCB0byBiZSA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXROb2RlVmFsdWUoU3RyaW5nIG5vZGVWYWx1ZSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBBIGNvZGUgcmVwcmVzZW50aW5nIHRoZSB0eXBlIG9mIHRoZSB1bmRlcmx5aW5nIG9iamVjdCwgYXMgZGVmaW5lZCBhYm92ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc2hvcnQgZ2V0Tm9kZVR5cGUoKTsKLQotICAgIC8qKgotICAgICAqIFRoZSBwYXJlbnQgb2YgdGhpcyBub2RlLiBBbGwgbm9kZXMsIGV4Y2VwdCA8Y29kZT5BdHRyPC9jb2RlPiwKLSAgICAgKiA8Y29kZT5Eb2N1bWVudDwvY29kZT4sIDxjb2RlPkRvY3VtZW50RnJhZ21lbnQ8L2NvZGU+LAotICAgICAqIDxjb2RlPkVudGl0eTwvY29kZT4sIGFuZCA8Y29kZT5Ob3RhdGlvbjwvY29kZT4gbWF5IGhhdmUgYSBwYXJlbnQuCi0gICAgICogSG93ZXZlciwgaWYgYSBub2RlIGhhcyBqdXN0IGJlZW4gY3JlYXRlZCBhbmQgbm90IHlldCBhZGRlZCB0byB0aGUKLSAgICAgKiB0cmVlLCBvciBpZiBpdCBoYXMgYmVlbiByZW1vdmVkIGZyb20gdGhlIHRyZWUsIHRoaXMgaXMKLSAgICAgKiA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgTm9kZSBnZXRQYXJlbnROb2RlKCk7Ci0KLSAgICAvKioKLSAgICAgKiBBIDxjb2RlPk5vZGVMaXN0PC9jb2RlPiB0aGF0IGNvbnRhaW5zIGFsbCBjaGlsZHJlbiBvZiB0aGlzIG5vZGUuIElmCi0gICAgICogdGhlcmUgYXJlIG5vIGNoaWxkcmVuLCB0aGlzIGlzIGEgPGNvZGU+Tm9kZUxpc3Q8L2NvZGU+IGNvbnRhaW5pbmcgbm8KLSAgICAgKiBub2Rlcy4KLSAgICAgKi8KLSAgICBwdWJsaWMgTm9kZUxpc3QgZ2V0Q2hpbGROb2RlcygpOwotCi0gICAgLyoqCi0gICAgICogVGhlIGZpcnN0IGNoaWxkIG9mIHRoaXMgbm9kZS4gSWYgdGhlcmUgaXMgbm8gc3VjaCBub2RlLCB0aGlzIHJldHVybnMKLSAgICAgKiA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgTm9kZSBnZXRGaXJzdENoaWxkKCk7Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgbGFzdCBjaGlsZCBvZiB0aGlzIG5vZGUuIElmIHRoZXJlIGlzIG5vIHN1Y2ggbm9kZSwgdGhpcyByZXR1cm5zCi0gICAgICogPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIE5vZGUgZ2V0TGFzdENoaWxkKCk7Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgbm9kZSBpbW1lZGlhdGVseSBwcmVjZWRpbmcgdGhpcyBub2RlLiBJZiB0aGVyZSBpcyBubyBzdWNoIG5vZGUsCi0gICAgICogdGhpcyByZXR1cm5zIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBOb2RlIGdldFByZXZpb3VzU2libGluZygpOwotCi0gICAgLyoqCi0gICAgICogVGhlIG5vZGUgaW1tZWRpYXRlbHkgZm9sbG93aW5nIHRoaXMgbm9kZS4gSWYgdGhlcmUgaXMgbm8gc3VjaCBub2RlLAotICAgICAqIHRoaXMgcmV0dXJucyA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgTm9kZSBnZXROZXh0U2libGluZygpOwotCi0gICAgLyoqCi0gICAgICogQSA8Y29kZT5OYW1lZE5vZGVNYXA8L2NvZGU+IGNvbnRhaW5pbmcgdGhlIGF0dHJpYnV0ZXMgb2YgdGhpcyBub2RlIChpZgotICAgICAqIGl0IGlzIGFuIDxjb2RlPkVsZW1lbnQ8L2NvZGU+KSBvciA8Y29kZT5udWxsPC9jb2RlPiBvdGhlcndpc2UuCi0gICAgICovCi0gICAgcHVibGljIE5hbWVkTm9kZU1hcCBnZXRBdHRyaWJ1dGVzKCk7Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgPGNvZGU+RG9jdW1lbnQ8L2NvZGU+IG9iamVjdCBhc3NvY2lhdGVkIHdpdGggdGhpcyBub2RlLiBUaGlzIGlzCi0gICAgICogYWxzbyB0aGUgPGNvZGU+RG9jdW1lbnQ8L2NvZGU+IG9iamVjdCB1c2VkIHRvIGNyZWF0ZSBuZXcgbm9kZXMuIFdoZW4KLSAgICAgKiB0aGlzIG5vZGUgaXMgYSA8Y29kZT5Eb2N1bWVudDwvY29kZT4gb3IgYSA8Y29kZT5Eb2N1bWVudFR5cGU8L2NvZGU+Ci0gICAgICogd2hpY2ggaXMgbm90IHVzZWQgd2l0aCBhbnkgPGNvZGU+RG9jdW1lbnQ8L2NvZGU+IHlldCwgdGhpcyBpcwotICAgICAqIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAqCi0gICAgICogQHNpbmNlIERPTSBMZXZlbCAyCi0gICAgICovCi0gICAgcHVibGljIERvY3VtZW50IGdldE93bmVyRG9jdW1lbnQoKTsKLQotICAgIC8qKgotICAgICAqIEluc2VydHMgdGhlIG5vZGUgPGNvZGU+bmV3Q2hpbGQ8L2NvZGU+IGJlZm9yZSB0aGUgZXhpc3RpbmcgY2hpbGQgbm9kZQotICAgICAqIDxjb2RlPnJlZkNoaWxkPC9jb2RlPi4gSWYgPGNvZGU+cmVmQ2hpbGQ8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+LAotICAgICAqIGluc2VydCA8Y29kZT5uZXdDaGlsZDwvY29kZT4gYXQgdGhlIGVuZCBvZiB0aGUgbGlzdCBvZiBjaGlsZHJlbi4KLSAgICAgKiA8YnI+SWYgPGNvZGU+bmV3Q2hpbGQ8L2NvZGU+IGlzIGEgPGNvZGU+RG9jdW1lbnRGcmFnbWVudDwvY29kZT4gb2JqZWN0LAotICAgICAqIGFsbCBvZiBpdHMgY2hpbGRyZW4gYXJlIGluc2VydGVkLCBpbiB0aGUgc2FtZSBvcmRlciwgYmVmb3JlCi0gICAgICogPGNvZGU+cmVmQ2hpbGQ8L2NvZGU+LiBJZiB0aGUgPGNvZGU+bmV3Q2hpbGQ8L2NvZGU+IGlzIGFscmVhZHkgaW4gdGhlCi0gICAgICogdHJlZSwgaXQgaXMgZmlyc3QgcmVtb3ZlZC4KLSAgICAgKiA8cCA+PGI+Tm90ZTo8L2I+ICBJbnNlcnRpbmcgYSBub2RlIGJlZm9yZSBpdHNlbGYgaXMgaW1wbGVtZW50YXRpb24KLSAgICAgKiBkZXBlbmRlbnQuCi0gICAgICogQHBhcmFtIG5ld0NoaWxkIFRoZSBub2RlIHRvIGluc2VydC4KLSAgICAgKiBAcGFyYW0gcmVmQ2hpbGQgVGhlIHJlZmVyZW5jZSBub2RlLCBpLmUuLCB0aGUgbm9kZSBiZWZvcmUgd2hpY2ggdGhlCi0gICAgICogICBuZXcgbm9kZSBtdXN0IGJlIGluc2VydGVkLgotICAgICAqIEByZXR1cm4gVGhlIG5vZGUgYmVpbmcgaW5zZXJ0ZWQuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIEhJRVJBUkNIWV9SRVFVRVNUX0VSUjogUmFpc2VkIGlmIHRoaXMgbm9kZSBpcyBvZiBhIHR5cGUgdGhhdCBkb2VzIG5vdAotICAgICAqICAgYWxsb3cgY2hpbGRyZW4gb2YgdGhlIHR5cGUgb2YgdGhlIDxjb2RlPm5ld0NoaWxkPC9jb2RlPiBub2RlLCBvciBpZgotICAgICAqICAgdGhlIG5vZGUgdG8gaW5zZXJ0IGlzIG9uZSBvZiB0aGlzIG5vZGUncyBhbmNlc3RvcnMgb3IgdGhpcyBub2RlCi0gICAgICogICBpdHNlbGYsIG9yIGlmIHRoaXMgbm9kZSBpcyBvZiB0eXBlIDxjb2RlPkRvY3VtZW50PC9jb2RlPiBhbmQgdGhlCi0gICAgICogICBET00gYXBwbGljYXRpb24gYXR0ZW1wdHMgdG8gaW5zZXJ0IGEgc2Vjb25kCi0gICAgICogICA8Y29kZT5Eb2N1bWVudFR5cGU8L2NvZGU+IG9yIDxjb2RlPkVsZW1lbnQ8L2NvZGU+IG5vZGUuCi0gICAgICogICA8YnI+V1JPTkdfRE9DVU1FTlRfRVJSOiBSYWlzZWQgaWYgPGNvZGU+bmV3Q2hpbGQ8L2NvZGU+IHdhcyBjcmVhdGVkCi0gICAgICogICBmcm9tIGEgZGlmZmVyZW50IGRvY3VtZW50IHRoYW4gdGhlIG9uZSB0aGF0IGNyZWF0ZWQgdGhpcyBub2RlLgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgbm9kZSBpcyByZWFkb25seSBvcgotICAgICAqICAgaWYgdGhlIHBhcmVudCBvZiB0aGUgbm9kZSBiZWluZyBpbnNlcnRlZCBpcyByZWFkb25seS4KLSAgICAgKiAgIDxicj5OT1RfRk9VTkRfRVJSOiBSYWlzZWQgaWYgPGNvZGU+cmVmQ2hpbGQ8L2NvZGU+IGlzIG5vdCBhIGNoaWxkIG9mCi0gICAgICogICB0aGlzIG5vZGUuCi0gICAgICogICA8YnI+Tk9UX1NVUFBPUlRFRF9FUlI6IGlmIHRoaXMgbm9kZSBpcyBvZiB0eXBlIDxjb2RlPkRvY3VtZW50PC9jb2RlPiwKLSAgICAgKiAgIHRoaXMgZXhjZXB0aW9uIG1pZ2h0IGJlIHJhaXNlZCBpZiB0aGUgRE9NIGltcGxlbWVudGF0aW9uIGRvZXNuJ3QKLSAgICAgKiAgIHN1cHBvcnQgdGhlIGluc2VydGlvbiBvZiBhIDxjb2RlPkRvY3VtZW50VHlwZTwvY29kZT4gb3IKLSAgICAgKiAgIDxjb2RlPkVsZW1lbnQ8L2NvZGU+IG5vZGUuCi0gICAgICoKLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICAgKi8KLSAgICBwdWJsaWMgTm9kZSBpbnNlcnRCZWZvcmUoTm9kZSBuZXdDaGlsZCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTm9kZSByZWZDaGlsZCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIFJlcGxhY2VzIHRoZSBjaGlsZCBub2RlIDxjb2RlPm9sZENoaWxkPC9jb2RlPiB3aXRoIDxjb2RlPm5ld0NoaWxkPC9jb2RlPgotICAgICAqICBpbiB0aGUgbGlzdCBvZiBjaGlsZHJlbiwgYW5kIHJldHVybnMgdGhlIDxjb2RlPm9sZENoaWxkPC9jb2RlPiBub2RlLgotICAgICAqIDxicj5JZiA8Y29kZT5uZXdDaGlsZDwvY29kZT4gaXMgYSA8Y29kZT5Eb2N1bWVudEZyYWdtZW50PC9jb2RlPiBvYmplY3QsCi0gICAgICogPGNvZGU+b2xkQ2hpbGQ8L2NvZGU+IGlzIHJlcGxhY2VkIGJ5IGFsbCBvZiB0aGUKLSAgICAgKiA8Y29kZT5Eb2N1bWVudEZyYWdtZW50PC9jb2RlPiBjaGlsZHJlbiwgd2hpY2ggYXJlIGluc2VydGVkIGluIHRoZQotICAgICAqIHNhbWUgb3JkZXIuIElmIHRoZSA8Y29kZT5uZXdDaGlsZDwvY29kZT4gaXMgYWxyZWFkeSBpbiB0aGUgdHJlZSwgaXQKLSAgICAgKiBpcyBmaXJzdCByZW1vdmVkLgotICAgICAqIDxwID48Yj5Ob3RlOjwvYj4gIFJlcGxhY2luZyBhIG5vZGUgd2l0aCBpdHNlbGYgaXMgaW1wbGVtZW50YXRpb24KLSAgICAgKiBkZXBlbmRlbnQuCi0gICAgICogQHBhcmFtIG5ld0NoaWxkIFRoZSBuZXcgbm9kZSB0byBwdXQgaW4gdGhlIGNoaWxkIGxpc3QuCi0gICAgICogQHBhcmFtIG9sZENoaWxkIFRoZSBub2RlIGJlaW5nIHJlcGxhY2VkIGluIHRoZSBsaXN0LgotICAgICAqIEByZXR1cm4gVGhlIG5vZGUgcmVwbGFjZWQuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIEhJRVJBUkNIWV9SRVFVRVNUX0VSUjogUmFpc2VkIGlmIHRoaXMgbm9kZSBpcyBvZiBhIHR5cGUgdGhhdCBkb2VzIG5vdAotICAgICAqICAgYWxsb3cgY2hpbGRyZW4gb2YgdGhlIHR5cGUgb2YgdGhlIDxjb2RlPm5ld0NoaWxkPC9jb2RlPiBub2RlLCBvciBpZgotICAgICAqICAgdGhlIG5vZGUgdG8gcHV0IGluIGlzIG9uZSBvZiB0aGlzIG5vZGUncyBhbmNlc3RvcnMgb3IgdGhpcyBub2RlCi0gICAgICogICBpdHNlbGYsIG9yIGlmIHRoaXMgbm9kZSBpcyBvZiB0eXBlIDxjb2RlPkRvY3VtZW50PC9jb2RlPiBhbmQgdGhlCi0gICAgICogICByZXN1bHQgb2YgdGhlIHJlcGxhY2VtZW50IG9wZXJhdGlvbiB3b3VsZCBhZGQgYSBzZWNvbmQKLSAgICAgKiAgIDxjb2RlPkRvY3VtZW50VHlwZTwvY29kZT4gb3IgPGNvZGU+RWxlbWVudDwvY29kZT4gb24gdGhlCi0gICAgICogICA8Y29kZT5Eb2N1bWVudDwvY29kZT4gbm9kZS4KLSAgICAgKiAgIDxicj5XUk9OR19ET0NVTUVOVF9FUlI6IFJhaXNlZCBpZiA8Y29kZT5uZXdDaGlsZDwvY29kZT4gd2FzIGNyZWF0ZWQKLSAgICAgKiAgIGZyb20gYSBkaWZmZXJlbnQgZG9jdW1lbnQgdGhhbiB0aGUgb25lIHRoYXQgY3JlYXRlZCB0aGlzIG5vZGUuCi0gICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBub2RlIG9yIHRoZSBwYXJlbnQgb2YKLSAgICAgKiAgIHRoZSBuZXcgbm9kZSBpcyByZWFkb25seS4KLSAgICAgKiAgIDxicj5OT1RfRk9VTkRfRVJSOiBSYWlzZWQgaWYgPGNvZGU+b2xkQ2hpbGQ8L2NvZGU+IGlzIG5vdCBhIGNoaWxkIG9mCi0gICAgICogICB0aGlzIG5vZGUuCi0gICAgICogICA8YnI+Tk9UX1NVUFBPUlRFRF9FUlI6IGlmIHRoaXMgbm9kZSBpcyBvZiB0eXBlIDxjb2RlPkRvY3VtZW50PC9jb2RlPiwKLSAgICAgKiAgIHRoaXMgZXhjZXB0aW9uIG1pZ2h0IGJlIHJhaXNlZCBpZiB0aGUgRE9NIGltcGxlbWVudGF0aW9uIGRvZXNuJ3QKLSAgICAgKiAgIHN1cHBvcnQgdGhlIHJlcGxhY2VtZW50IG9mIHRoZSA8Y29kZT5Eb2N1bWVudFR5cGU8L2NvZGU+IGNoaWxkIG9yCi0gICAgICogICA8Y29kZT5FbGVtZW50PC9jb2RlPiBjaGlsZC4KLSAgICAgKgotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgICAqLwotICAgIHB1YmxpYyBOb2RlIHJlcGxhY2VDaGlsZChOb2RlIG5ld0NoaWxkLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOb2RlIG9sZENoaWxkKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogUmVtb3ZlcyB0aGUgY2hpbGQgbm9kZSBpbmRpY2F0ZWQgYnkgPGNvZGU+b2xkQ2hpbGQ8L2NvZGU+IGZyb20gdGhlIGxpc3QKLSAgICAgKiBvZiBjaGlsZHJlbiwgYW5kIHJldHVybnMgaXQuCi0gICAgICogQHBhcmFtIG9sZENoaWxkIFRoZSBub2RlIGJlaW5nIHJlbW92ZWQuCi0gICAgICogQHJldHVybiBUaGUgbm9kZSByZW1vdmVkLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIG5vZGUgaXMgcmVhZG9ubHkuCi0gICAgICogICA8YnI+Tk9UX0ZPVU5EX0VSUjogUmFpc2VkIGlmIDxjb2RlPm9sZENoaWxkPC9jb2RlPiBpcyBub3QgYSBjaGlsZCBvZgotICAgICAqICAgdGhpcyBub2RlLgotICAgICAqICAgPGJyPk5PVF9TVVBQT1JURURfRVJSOiBpZiB0aGlzIG5vZGUgaXMgb2YgdHlwZSA8Y29kZT5Eb2N1bWVudDwvY29kZT4sCi0gICAgICogICB0aGlzIGV4Y2VwdGlvbiBtaWdodCBiZSByYWlzZWQgaWYgdGhlIERPTSBpbXBsZW1lbnRhdGlvbiBkb2Vzbid0Ci0gICAgICogICBzdXBwb3J0IHRoZSByZW1vdmFsIG9mIHRoZSA8Y29kZT5Eb2N1bWVudFR5cGU8L2NvZGU+IGNoaWxkIG9yIHRoZQotICAgICAqICAgPGNvZGU+RWxlbWVudDwvY29kZT4gY2hpbGQuCi0gICAgICoKLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICAgKi8KLSAgICBwdWJsaWMgTm9kZSByZW1vdmVDaGlsZChOb2RlIG9sZENoaWxkKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBBZGRzIHRoZSBub2RlIDxjb2RlPm5ld0NoaWxkPC9jb2RlPiB0byB0aGUgZW5kIG9mIHRoZSBsaXN0IG9mIGNoaWxkcmVuCi0gICAgICogb2YgdGhpcyBub2RlLiBJZiB0aGUgPGNvZGU+bmV3Q2hpbGQ8L2NvZGU+IGlzIGFscmVhZHkgaW4gdGhlIHRyZWUsIGl0Ci0gICAgICogaXMgZmlyc3QgcmVtb3ZlZC4KLSAgICAgKiBAcGFyYW0gbmV3Q2hpbGQgVGhlIG5vZGUgdG8gYWRkLklmIGl0IGlzIGEKLSAgICAgKiAgIDxjb2RlPkRvY3VtZW50RnJhZ21lbnQ8L2NvZGU+IG9iamVjdCwgdGhlIGVudGlyZSBjb250ZW50cyBvZiB0aGUKLSAgICAgKiAgIGRvY3VtZW50IGZyYWdtZW50IGFyZSBtb3ZlZCBpbnRvIHRoZSBjaGlsZCBsaXN0IG9mIHRoaXMgbm9kZQotICAgICAqIEByZXR1cm4gVGhlIG5vZGUgYWRkZWQuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIEhJRVJBUkNIWV9SRVFVRVNUX0VSUjogUmFpc2VkIGlmIHRoaXMgbm9kZSBpcyBvZiBhIHR5cGUgdGhhdCBkb2VzIG5vdAotICAgICAqICAgYWxsb3cgY2hpbGRyZW4gb2YgdGhlIHR5cGUgb2YgdGhlIDxjb2RlPm5ld0NoaWxkPC9jb2RlPiBub2RlLCBvciBpZgotICAgICAqICAgdGhlIG5vZGUgdG8gYXBwZW5kIGlzIG9uZSBvZiB0aGlzIG5vZGUncyBhbmNlc3RvcnMgb3IgdGhpcyBub2RlCi0gICAgICogICBpdHNlbGYsIG9yIGlmIHRoaXMgbm9kZSBpcyBvZiB0eXBlIDxjb2RlPkRvY3VtZW50PC9jb2RlPiBhbmQgdGhlCi0gICAgICogICBET00gYXBwbGljYXRpb24gYXR0ZW1wdHMgdG8gYXBwZW5kIGEgc2Vjb25kCi0gICAgICogICA8Y29kZT5Eb2N1bWVudFR5cGU8L2NvZGU+IG9yIDxjb2RlPkVsZW1lbnQ8L2NvZGU+IG5vZGUuCi0gICAgICogICA8YnI+V1JPTkdfRE9DVU1FTlRfRVJSOiBSYWlzZWQgaWYgPGNvZGU+bmV3Q2hpbGQ8L2NvZGU+IHdhcyBjcmVhdGVkCi0gICAgICogICBmcm9tIGEgZGlmZmVyZW50IGRvY3VtZW50IHRoYW4gdGhlIG9uZSB0aGF0IGNyZWF0ZWQgdGhpcyBub2RlLgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgbm9kZSBpcyByZWFkb25seSBvcgotICAgICAqICAgaWYgdGhlIHByZXZpb3VzIHBhcmVudCBvZiB0aGUgbm9kZSBiZWluZyBpbnNlcnRlZCBpcyByZWFkb25seS4KLSAgICAgKiAgIDxicj5OT1RfU1VQUE9SVEVEX0VSUjogaWYgdGhlIDxjb2RlPm5ld0NoaWxkPC9jb2RlPiBub2RlIGlzIGEgY2hpbGQKLSAgICAgKiAgIG9mIHRoZSA8Y29kZT5Eb2N1bWVudDwvY29kZT4gbm9kZSwgdGhpcyBleGNlcHRpb24gbWlnaHQgYmUgcmFpc2VkCi0gICAgICogICBpZiB0aGUgRE9NIGltcGxlbWVudGF0aW9uIGRvZXNuJ3Qgc3VwcG9ydCB0aGUgcmVtb3ZhbCBvZiB0aGUKLSAgICAgKiAgIDxjb2RlPkRvY3VtZW50VHlwZTwvY29kZT4gY2hpbGQgb3IgPGNvZGU+RWxlbWVudDwvY29kZT4gY2hpbGQuCi0gICAgICoKLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICAgKi8KLSAgICBwdWJsaWMgTm9kZSBhcHBlbmRDaGlsZChOb2RlIG5ld0NoaWxkKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhpcyBub2RlIGhhcyBhbnkgY2hpbGRyZW4uCi0gICAgICogQHJldHVybiBSZXR1cm5zIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoaXMgbm9kZSBoYXMgYW55IGNoaWxkcmVuLAotICAgICAqICAgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBoYXNDaGlsZE5vZGVzKCk7Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGEgZHVwbGljYXRlIG9mIHRoaXMgbm9kZSwgaS5lLiwgc2VydmVzIGFzIGEgZ2VuZXJpYyBjb3B5Ci0gICAgICogY29uc3RydWN0b3IgZm9yIG5vZGVzLiBUaGUgZHVwbGljYXRlIG5vZGUgaGFzIG5vIHBhcmVudCAoCi0gICAgICogPGNvZGU+cGFyZW50Tm9kZTwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4pIGFuZCBubyB1c2VyIGRhdGEuIFVzZXIKLSAgICAgKiBkYXRhIGFzc29jaWF0ZWQgdG8gdGhlIGltcG9ydGVkIG5vZGUgaXMgbm90IGNhcnJpZWQgb3Zlci4gSG93ZXZlciwgaWYKLSAgICAgKiBhbnkgPGNvZGU+VXNlckRhdGFIYW5kbGVyczwvY29kZT4gaGFzIGJlZW4gc3BlY2lmaWVkIGFsb25nIHdpdGggdGhlCi0gICAgICogYXNzb2NpYXRlZCBkYXRhIHRoZXNlIGhhbmRsZXJzIHdpbGwgYmUgY2FsbGVkIHdpdGggdGhlIGFwcHJvcHJpYXRlCi0gICAgICogcGFyYW1ldGVycyBiZWZvcmUgdGhpcyBtZXRob2QgcmV0dXJucy4KLSAgICAgKiA8YnI+Q2xvbmluZyBhbiA8Y29kZT5FbGVtZW50PC9jb2RlPiBjb3BpZXMgYWxsIGF0dHJpYnV0ZXMgYW5kIHRoZWlyCi0gICAgICogdmFsdWVzLCBpbmNsdWRpbmcgdGhvc2UgZ2VuZXJhdGVkIGJ5IHRoZSBYTUwgcHJvY2Vzc29yIHRvIHJlcHJlc2VudAotICAgICAqIGRlZmF1bHRlZCBhdHRyaWJ1dGVzLCBidXQgdGhpcyBtZXRob2QgZG9lcyBub3QgY29weSBhbnkgY2hpbGRyZW4gaXQKLSAgICAgKiBjb250YWlucyB1bmxlc3MgaXQgaXMgYSBkZWVwIGNsb25lLiBUaGlzIGluY2x1ZGVzIHRleHQgY29udGFpbmVkIGluCi0gICAgICogYW4gdGhlIDxjb2RlPkVsZW1lbnQ8L2NvZGU+IHNpbmNlIHRoZSB0ZXh0IGlzIGNvbnRhaW5lZCBpbiBhIGNoaWxkCi0gICAgICogPGNvZGU+VGV4dDwvY29kZT4gbm9kZS4gQ2xvbmluZyBhbiA8Y29kZT5BdHRyPC9jb2RlPiBkaXJlY3RseSwgYXMKLSAgICAgKiBvcHBvc2VkIHRvIGJlIGNsb25lZCBhcyBwYXJ0IG9mIGFuIDxjb2RlPkVsZW1lbnQ8L2NvZGU+IGNsb25pbmcKLSAgICAgKiBvcGVyYXRpb24sIHJldHVybnMgYSBzcGVjaWZpZWQgYXR0cmlidXRlICg8Y29kZT5zcGVjaWZpZWQ8L2NvZGU+IGlzCi0gICAgICogPGNvZGU+dHJ1ZTwvY29kZT4pLiBDbG9uaW5nIGFuIDxjb2RlPkF0dHI8L2NvZGU+IGFsd2F5cyBjbG9uZXMgaXRzCi0gICAgICogY2hpbGRyZW4sIHNpbmNlIHRoZXkgcmVwcmVzZW50IGl0cyB2YWx1ZSwgbm8gbWF0dGVyIHdoZXRoZXIgdGhpcyBpcyBhCi0gICAgICogZGVlcCBjbG9uZSBvciBub3QuIENsb25pbmcgYW4gPGNvZGU+RW50aXR5UmVmZXJlbmNlPC9jb2RlPgotICAgICAqIGF1dG9tYXRpY2FsbHkgY29uc3RydWN0cyBpdHMgc3VidHJlZSBpZiBhIGNvcnJlc3BvbmRpbmcKLSAgICAgKiA8Y29kZT5FbnRpdHk8L2NvZGU+IGlzIGF2YWlsYWJsZSwgbm8gbWF0dGVyIHdoZXRoZXIgdGhpcyBpcyBhIGRlZXAKLSAgICAgKiBjbG9uZSBvciBub3QuIENsb25pbmcgYW55IG90aGVyIHR5cGUgb2Ygbm9kZSBzaW1wbHkgcmV0dXJucyBhIGNvcHkgb2YKLSAgICAgKiB0aGlzIG5vZGUuCi0gICAgICogPGJyPk5vdGUgdGhhdCBjbG9uaW5nIGFuIGltbXV0YWJsZSBzdWJ0cmVlIHJlc3VsdHMgaW4gYSBtdXRhYmxlIGNvcHksCi0gICAgICogYnV0IHRoZSBjaGlsZHJlbiBvZiBhbiA8Y29kZT5FbnRpdHlSZWZlcmVuY2U8L2NvZGU+IGNsb25lIGFyZSByZWFkb25seQotICAgICAqIC4gSW4gYWRkaXRpb24sIGNsb25lcyBvZiB1bnNwZWNpZmllZCA8Y29kZT5BdHRyPC9jb2RlPiBub2RlcyBhcmUKLSAgICAgKiBzcGVjaWZpZWQuIEFuZCwgY2xvbmluZyA8Y29kZT5Eb2N1bWVudDwvY29kZT4sCi0gICAgICogPGNvZGU+RG9jdW1lbnRUeXBlPC9jb2RlPiwgPGNvZGU+RW50aXR5PC9jb2RlPiwgYW5kCi0gICAgICogPGNvZGU+Tm90YXRpb248L2NvZGU+IG5vZGVzIGlzIGltcGxlbWVudGF0aW9uIGRlcGVuZGVudC4KLSAgICAgKiBAcGFyYW0gZGVlcCBJZiA8Y29kZT50cnVlPC9jb2RlPiwgcmVjdXJzaXZlbHkgY2xvbmUgdGhlIHN1YnRyZWUgdW5kZXIKLSAgICAgKiAgIHRoZSBzcGVjaWZpZWQgbm9kZTsgaWYgPGNvZGU+ZmFsc2U8L2NvZGU+LCBjbG9uZSBvbmx5IHRoZSBub2RlCi0gICAgICogICBpdHNlbGYgKGFuZCBpdHMgYXR0cmlidXRlcywgaWYgaXQgaXMgYW4gPGNvZGU+RWxlbWVudDwvY29kZT4pLgotICAgICAqIEByZXR1cm4gVGhlIGR1cGxpY2F0ZSBub2RlLgotICAgICAqLwotICAgIHB1YmxpYyBOb2RlIGNsb25lTm9kZShib29sZWFuIGRlZXApOwotCi0gICAgLyoqCi0gICAgICogIFB1dHMgYWxsIDxjb2RlPlRleHQ8L2NvZGU+IG5vZGVzIGluIHRoZSBmdWxsIGRlcHRoIG9mIHRoZSBzdWItdHJlZQotICAgICAqIHVuZGVybmVhdGggdGhpcyA8Y29kZT5Ob2RlPC9jb2RlPiwgaW5jbHVkaW5nIGF0dHJpYnV0ZSBub2RlcywgaW50byBhCi0gICAgICogIm5vcm1hbCIgZm9ybSB3aGVyZSBvbmx5IHN0cnVjdHVyZSAoZS5nLiwgZWxlbWVudHMsIGNvbW1lbnRzLAotICAgICAqIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb25zLCBDREFUQSBzZWN0aW9ucywgYW5kIGVudGl0eSByZWZlcmVuY2VzKQotICAgICAqIHNlcGFyYXRlcyA8Y29kZT5UZXh0PC9jb2RlPiBub2RlcywgaS5lLiwgdGhlcmUgYXJlIG5laXRoZXIgYWRqYWNlbnQKLSAgICAgKiA8Y29kZT5UZXh0PC9jb2RlPiBub2RlcyBub3IgZW1wdHkgPGNvZGU+VGV4dDwvY29kZT4gbm9kZXMuIFRoaXMgY2FuCi0gICAgICogYmUgdXNlZCB0byBlbnN1cmUgdGhhdCB0aGUgRE9NIHZpZXcgb2YgYSBkb2N1bWVudCBpcyB0aGUgc2FtZSBhcyBpZgotICAgICAqIGl0IHdlcmUgc2F2ZWQgYW5kIHJlLWxvYWRlZCwgYW5kIGlzIHVzZWZ1bCB3aGVuIG9wZXJhdGlvbnMgKHN1Y2ggYXMKLSAgICAgKiBYUG9pbnRlciBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMy9SRUMteHB0ci1mcmFtZXdvcmstMjAwMzAzMjUvJz5YUG9pbnRlcjwvYT5dCi0gICAgICogIGxvb2t1cHMpIHRoYXQgZGVwZW5kIG9uIGEgcGFydGljdWxhciBkb2N1bWVudCB0cmVlIHN0cnVjdHVyZSBhcmUgdG8KLSAgICAgKiBiZSB1c2VkLiBJZiB0aGUgcGFyYW1ldGVyICJub3JtYWxpemUtY2hhcmFjdGVycyIgb2YgdGhlCi0gICAgICogPGNvZGU+RE9NQ29uZmlndXJhdGlvbjwvY29kZT4gb2JqZWN0IGF0dGFjaGVkIHRvIHRoZQotICAgICAqIDxjb2RlPk5vZGUub3duZXJEb2N1bWVudDwvY29kZT4gaXMgPGNvZGU+dHJ1ZTwvY29kZT4sIHRoaXMgbWV0aG9kCi0gICAgICogd2lsbCBhbHNvIGZ1bGx5IG5vcm1hbGl6ZSB0aGUgY2hhcmFjdGVycyBvZiB0aGUgPGNvZGU+VGV4dDwvY29kZT4KLSAgICAgKiBub2Rlcy4KLSAgICAgKiA8cCA+PGI+Tm90ZTo8L2I+IEluIGNhc2VzIHdoZXJlIHRoZSBkb2N1bWVudCBjb250YWlucwotICAgICAqIDxjb2RlPkNEQVRBU2VjdGlvbnM8L2NvZGU+LCB0aGUgbm9ybWFsaXplIG9wZXJhdGlvbiBhbG9uZSBtYXkgbm90IGJlCi0gICAgICogc3VmZmljaWVudCwgc2luY2UgWFBvaW50ZXJzIGRvIG5vdCBkaWZmZXJlbnRpYXRlIGJldHdlZW4KLSAgICAgKiA8Y29kZT5UZXh0PC9jb2RlPiBub2RlcyBhbmQgPGNvZGU+Q0RBVEFTZWN0aW9uPC9jb2RlPiBub2Rlcy4KLSAgICAgKgotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIG5vcm1hbGl6ZSgpOwotCi0gICAgLyoqCi0gICAgICogIFRlc3RzIHdoZXRoZXIgdGhlIERPTSBpbXBsZW1lbnRhdGlvbiBpbXBsZW1lbnRzIGEgc3BlY2lmaWMgZmVhdHVyZSBhbmQKLSAgICAgKiB0aGF0IGZlYXR1cmUgaXMgc3VwcG9ydGVkIGJ5IHRoaXMgbm9kZSwgYXMgc3BlY2lmaWVkIGluIC4KLSAgICAgKiBAcGFyYW0gZmVhdHVyZSAgVGhlIG5hbWUgb2YgdGhlIGZlYXR1cmUgdG8gdGVzdC4KLSAgICAgKiBAcGFyYW0gdmVyc2lvbiAgVGhpcyBpcyB0aGUgdmVyc2lvbiBudW1iZXIgb2YgdGhlIGZlYXR1cmUgdG8gdGVzdC4KLSAgICAgKiBAcmV0dXJuIFJldHVybnMgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIHNwZWNpZmllZCBmZWF0dXJlIGlzCi0gICAgICogICBzdXBwb3J0ZWQgb24gdGhpcyBub2RlLCA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLgotICAgICAqCi0gICAgICogQHNpbmNlIERPTSBMZXZlbCAyCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNTdXBwb3J0ZWQoU3RyaW5nIGZlYXR1cmUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHZlcnNpb24pOwotCi0gICAgLyoqCi0gICAgICogVGhlIG5hbWVzcGFjZSBVUkkgb2YgdGhpcyBub2RlLCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiBpdCBpcwotICAgICAqIHVuc3BlY2lmaWVkIChzZWUgKS4KLSAgICAgKiA8YnI+VGhpcyBpcyBub3QgYSBjb21wdXRlZCB2YWx1ZSB0aGF0IGlzIHRoZSByZXN1bHQgb2YgYSBuYW1lc3BhY2UKLSAgICAgKiBsb29rdXAgYmFzZWQgb24gYW4gZXhhbWluYXRpb24gb2YgdGhlIG5hbWVzcGFjZSBkZWNsYXJhdGlvbnMgaW4KLSAgICAgKiBzY29wZS4gSXQgaXMgbWVyZWx5IHRoZSBuYW1lc3BhY2UgVVJJIGdpdmVuIGF0IGNyZWF0aW9uIHRpbWUuCi0gICAgICogPGJyPkZvciBub2RlcyBvZiBhbnkgdHlwZSBvdGhlciB0aGFuIDxjb2RlPkVMRU1FTlRfTk9ERTwvY29kZT4gYW5kCi0gICAgICogPGNvZGU+QVRUUklCVVRFX05PREU8L2NvZGU+IGFuZCBub2RlcyBjcmVhdGVkIHdpdGggYSBET00gTGV2ZWwgMQotICAgICAqIG1ldGhvZCwgc3VjaCBhcyA8Y29kZT5Eb2N1bWVudC5jcmVhdGVFbGVtZW50KCk8L2NvZGU+LCB0aGlzIGlzIGFsd2F5cwotICAgICAqIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAqIDxwID48Yj5Ob3RlOjwvYj4gUGVyIHRoZSA8ZW0+TmFtZXNwYWNlcyBpbiBYTUw8L2VtPiBTcGVjaWZpY2F0aW9uIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk5L1JFQy14bWwtbmFtZXMtMTk5OTAxMTQvJz5YTUwgTmFtZXNwYWNlczwvYT5dCi0gICAgICogIGFuIGF0dHJpYnV0ZSBkb2VzIG5vdCBpbmhlcml0IGl0cyBuYW1lc3BhY2UgZnJvbSB0aGUgZWxlbWVudCBpdCBpcwotICAgICAqIGF0dGFjaGVkIHRvLiBJZiBhbiBhdHRyaWJ1dGUgaXMgbm90IGV4cGxpY2l0bHkgZ2l2ZW4gYSBuYW1lc3BhY2UsIGl0Ci0gICAgICogc2ltcGx5IGhhcyBubyBuYW1lc3BhY2UuCi0gICAgICoKLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDIKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWVzcGFjZVVSSSgpOwotCi0gICAgLyoqCi0gICAgICogVGhlIG5hbWVzcGFjZSBwcmVmaXggb2YgdGhpcyBub2RlLCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiBpdCBpcwotICAgICAqIHVuc3BlY2lmaWVkLiBXaGVuIGl0IGlzIGRlZmluZWQgdG8gYmUgPGNvZGU+bnVsbDwvY29kZT4sIHNldHRpbmcgaXQKLSAgICAgKiBoYXMgbm8gZWZmZWN0LCBpbmNsdWRpbmcgaWYgdGhlIG5vZGUgaXMgcmVhZC1vbmx5LgotICAgICAqIDxicj5Ob3RlIHRoYXQgc2V0dGluZyB0aGlzIGF0dHJpYnV0ZSwgd2hlbiBwZXJtaXR0ZWQsIGNoYW5nZXMgdGhlCi0gICAgICogPGNvZGU+bm9kZU5hbWU8L2NvZGU+IGF0dHJpYnV0ZSwgd2hpY2ggaG9sZHMgdGhlIHF1YWxpZmllZCBuYW1lLCBhcwotICAgICAqIHdlbGwgYXMgdGhlIDxjb2RlPnRhZ05hbWU8L2NvZGU+IGFuZCA8Y29kZT5uYW1lPC9jb2RlPiBhdHRyaWJ1dGVzIG9mCi0gICAgICogdGhlIDxjb2RlPkVsZW1lbnQ8L2NvZGU+IGFuZCA8Y29kZT5BdHRyPC9jb2RlPiBpbnRlcmZhY2VzLCB3aGVuCi0gICAgICogYXBwbGljYWJsZS4KLSAgICAgKiA8YnI+U2V0dGluZyB0aGUgcHJlZml4IHRvIDxjb2RlPm51bGw8L2NvZGU+IG1ha2VzIGl0IHVuc3BlY2lmaWVkLAotICAgICAqIHNldHRpbmcgaXQgdG8gYW4gZW1wdHkgc3RyaW5nIGlzIGltcGxlbWVudGF0aW9uIGRlcGVuZGVudC4KLSAgICAgKiA8YnI+Tm90ZSBhbHNvIHRoYXQgY2hhbmdpbmcgdGhlIHByZWZpeCBvZiBhbiBhdHRyaWJ1dGUgdGhhdCBpcyBrbm93biB0bwotICAgICAqIGhhdmUgYSBkZWZhdWx0IHZhbHVlLCBkb2VzIG5vdCBtYWtlIGEgbmV3IGF0dHJpYnV0ZSB3aXRoIHRoZSBkZWZhdWx0Ci0gICAgICogdmFsdWUgYW5kIHRoZSBvcmlnaW5hbCBwcmVmaXggYXBwZWFyLCBzaW5jZSB0aGUKLSAgICAgKiA8Y29kZT5uYW1lc3BhY2VVUkk8L2NvZGU+IGFuZCA8Y29kZT5sb2NhbE5hbWU8L2NvZGU+IGRvIG5vdCBjaGFuZ2UuCi0gICAgICogPGJyPkZvciBub2RlcyBvZiBhbnkgdHlwZSBvdGhlciB0aGFuIDxjb2RlPkVMRU1FTlRfTk9ERTwvY29kZT4gYW5kCi0gICAgICogPGNvZGU+QVRUUklCVVRFX05PREU8L2NvZGU+IGFuZCBub2RlcyBjcmVhdGVkIHdpdGggYSBET00gTGV2ZWwgMQotICAgICAqIG1ldGhvZCwgc3VjaCBhcyA8Y29kZT5jcmVhdGVFbGVtZW50PC9jb2RlPiBmcm9tIHRoZQotICAgICAqIDxjb2RlPkRvY3VtZW50PC9jb2RlPiBpbnRlcmZhY2UsIHRoaXMgaXMgYWx3YXlzIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAqCi0gICAgICogQHNpbmNlIERPTSBMZXZlbCAyCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRQcmVmaXgoKTsKLSAgICAvKioKLSAgICAgKiBUaGUgbmFtZXNwYWNlIHByZWZpeCBvZiB0aGlzIG5vZGUsIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIGl0IGlzCi0gICAgICogdW5zcGVjaWZpZWQuIFdoZW4gaXQgaXMgZGVmaW5lZCB0byBiZSA8Y29kZT5udWxsPC9jb2RlPiwgc2V0dGluZyBpdAotICAgICAqIGhhcyBubyBlZmZlY3QsIGluY2x1ZGluZyBpZiB0aGUgbm9kZSBpcyByZWFkLW9ubHkuCi0gICAgICogPGJyPk5vdGUgdGhhdCBzZXR0aW5nIHRoaXMgYXR0cmlidXRlLCB3aGVuIHBlcm1pdHRlZCwgY2hhbmdlcyB0aGUKLSAgICAgKiA8Y29kZT5ub2RlTmFtZTwvY29kZT4gYXR0cmlidXRlLCB3aGljaCBob2xkcyB0aGUgcXVhbGlmaWVkIG5hbWUsIGFzCi0gICAgICogd2VsbCBhcyB0aGUgPGNvZGU+dGFnTmFtZTwvY29kZT4gYW5kIDxjb2RlPm5hbWU8L2NvZGU+IGF0dHJpYnV0ZXMgb2YKLSAgICAgKiB0aGUgPGNvZGU+RWxlbWVudDwvY29kZT4gYW5kIDxjb2RlPkF0dHI8L2NvZGU+IGludGVyZmFjZXMsIHdoZW4KLSAgICAgKiBhcHBsaWNhYmxlLgotICAgICAqIDxicj5TZXR0aW5nIHRoZSBwcmVmaXggdG8gPGNvZGU+bnVsbDwvY29kZT4gbWFrZXMgaXQgdW5zcGVjaWZpZWQsCi0gICAgICogc2V0dGluZyBpdCB0byBhbiBlbXB0eSBzdHJpbmcgaXMgaW1wbGVtZW50YXRpb24gZGVwZW5kZW50LgotICAgICAqIDxicj5Ob3RlIGFsc28gdGhhdCBjaGFuZ2luZyB0aGUgcHJlZml4IG9mIGFuIGF0dHJpYnV0ZSB0aGF0IGlzIGtub3duIHRvCi0gICAgICogaGF2ZSBhIGRlZmF1bHQgdmFsdWUsIGRvZXMgbm90IG1ha2UgYSBuZXcgYXR0cmlidXRlIHdpdGggdGhlIGRlZmF1bHQKLSAgICAgKiB2YWx1ZSBhbmQgdGhlIG9yaWdpbmFsIHByZWZpeCBhcHBlYXIsIHNpbmNlIHRoZQotICAgICAqIDxjb2RlPm5hbWVzcGFjZVVSSTwvY29kZT4gYW5kIDxjb2RlPmxvY2FsTmFtZTwvY29kZT4gZG8gbm90IGNoYW5nZS4KLSAgICAgKiA8YnI+Rm9yIG5vZGVzIG9mIGFueSB0eXBlIG90aGVyIHRoYW4gPGNvZGU+RUxFTUVOVF9OT0RFPC9jb2RlPiBhbmQKLSAgICAgKiA8Y29kZT5BVFRSSUJVVEVfTk9ERTwvY29kZT4gYW5kIG5vZGVzIGNyZWF0ZWQgd2l0aCBhIERPTSBMZXZlbCAxCi0gICAgICogbWV0aG9kLCBzdWNoIGFzIDxjb2RlPmNyZWF0ZUVsZW1lbnQ8L2NvZGU+IGZyb20gdGhlCi0gICAgICogPGNvZGU+RG9jdW1lbnQ8L2NvZGU+IGludGVyZmFjZSwgdGhpcyBpcyBhbHdheXMgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIElOVkFMSURfQ0hBUkFDVEVSX0VSUjogUmFpc2VkIGlmIHRoZSBzcGVjaWZpZWQgcHJlZml4IGNvbnRhaW5zIGFuCi0gICAgICogICBpbGxlZ2FsIGNoYXJhY3RlciBhY2NvcmRpbmcgdG8gdGhlIFhNTCB2ZXJzaW9uIGluIHVzZSBzcGVjaWZpZWQgaW4KLSAgICAgKiAgIHRoZSA8Y29kZT5Eb2N1bWVudC54bWxWZXJzaW9uPC9jb2RlPiBhdHRyaWJ1dGUuCi0gICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBub2RlIGlzIHJlYWRvbmx5LgotICAgICAqICAgPGJyPk5BTUVTUEFDRV9FUlI6IFJhaXNlZCBpZiB0aGUgc3BlY2lmaWVkIDxjb2RlPnByZWZpeDwvY29kZT4gaXMKLSAgICAgKiAgIG1hbGZvcm1lZCBwZXIgdGhlIE5hbWVzcGFjZXMgaW4gWE1MIHNwZWNpZmljYXRpb24sIGlmIHRoZQotICAgICAqICAgPGNvZGU+bmFtZXNwYWNlVVJJPC9jb2RlPiBvZiB0aGlzIG5vZGUgaXMgPGNvZGU+bnVsbDwvY29kZT4sIGlmIHRoZQotICAgICAqICAgc3BlY2lmaWVkIHByZWZpeCBpcyAieG1sIiBhbmQgdGhlIDxjb2RlPm5hbWVzcGFjZVVSSTwvY29kZT4gb2YgdGhpcwotICAgICAqICAgbm9kZSBpcyBkaWZmZXJlbnQgZnJvbSAiPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvWE1MLzE5OTgvbmFtZXNwYWNlJz4KLSAgICAgKiAgIGh0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZTwvYT4iLCBpZiB0aGlzIG5vZGUgaXMgYW4gYXR0cmlidXRlIGFuZCB0aGUgc3BlY2lmaWVkIHByZWZpeCBpcyAieG1sbnMiIGFuZAotICAgICAqICAgdGhlIDxjb2RlPm5hbWVzcGFjZVVSSTwvY29kZT4gb2YgdGhpcyBub2RlIGlzIGRpZmZlcmVudCBmcm9tICI8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3htbG5zLyc+aHR0cDovL3d3dy53My5vcmcvMjAwMC94bWxucy88L2E+Iiwgb3IgaWYgdGhpcyBub2RlIGlzIGFuIGF0dHJpYnV0ZSBhbmQgdGhlIDxjb2RlPnF1YWxpZmllZE5hbWU8L2NvZGU+IG9mCi0gICAgICogICB0aGlzIG5vZGUgaXMgInhtbG5zIiBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMTk5OS9SRUMteG1sLW5hbWVzLTE5OTkwMTE0Lyc+WE1MIE5hbWVzcGFjZXM8L2E+XQotICAgICAqICAgLgotICAgICAqCi0gICAgICogQHNpbmNlIERPTSBMZXZlbCAyCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0UHJlZml4KFN0cmluZyBwcmVmaXgpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIGxvY2FsIHBhcnQgb2YgdGhlIHF1YWxpZmllZCBuYW1lIG9mIHRoaXMgbm9kZS4KLSAgICAgKiA8YnI+Rm9yIG5vZGVzIG9mIGFueSB0eXBlIG90aGVyIHRoYW4gPGNvZGU+RUxFTUVOVF9OT0RFPC9jb2RlPiBhbmQKLSAgICAgKiA8Y29kZT5BVFRSSUJVVEVfTk9ERTwvY29kZT4gYW5kIG5vZGVzIGNyZWF0ZWQgd2l0aCBhIERPTSBMZXZlbCAxCi0gICAgICogbWV0aG9kLCBzdWNoIGFzIDxjb2RlPkRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoKTwvY29kZT4sIHRoaXMgaXMgYWx3YXlzCi0gICAgICogPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICoKLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDIKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldExvY2FsTmFtZSgpOwotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB3aGV0aGVyIHRoaXMgbm9kZSAoaWYgaXQgaXMgYW4gZWxlbWVudCkgaGFzIGFueSBhdHRyaWJ1dGVzLgotICAgICAqIEByZXR1cm4gUmV0dXJucyA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGlzIG5vZGUgaGFzIGFueSBhdHRyaWJ1dGVzLAotICAgICAqICAgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4KLSAgICAgKgotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGhhc0F0dHJpYnV0ZXMoKTsKLQotICAgIC8qKgotICAgICAqIFRoZSBhYnNvbHV0ZSBiYXNlIFVSSSBvZiB0aGlzIG5vZGUgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlCi0gICAgICogaW1wbGVtZW50YXRpb24gd2Fzbid0IGFibGUgdG8gb2J0YWluIGFuIGFic29sdXRlIFVSSS4gVGhpcyB2YWx1ZSBpcwotICAgICAqIGNvbXB1dGVkIGFzIGRlc2NyaWJlZCBpbiAuIEhvd2V2ZXIsIHdoZW4gdGhlIDxjb2RlPkRvY3VtZW50PC9jb2RlPgotICAgICAqIHN1cHBvcnRzIHRoZSBmZWF0dXJlICJIVE1MIiBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMy9SRUMtRE9NLUxldmVsLTItSFRNTC0yMDAzMDEwOSc+RE9NIExldmVsIDIgSFRNTDwvYT5dCi0gICAgICogLCB0aGUgYmFzZSBVUkkgaXMgY29tcHV0ZWQgdXNpbmcgZmlyc3QgdGhlIHZhbHVlIG9mIHRoZSBocmVmCi0gICAgICogYXR0cmlidXRlIG9mIHRoZSBIVE1MIEJBU0UgZWxlbWVudCBpZiBhbnksIGFuZCB0aGUgdmFsdWUgb2YgdGhlCi0gICAgICogPGNvZGU+ZG9jdW1lbnRVUkk8L2NvZGU+IGF0dHJpYnV0ZSBmcm9tIHRoZSA8Y29kZT5Eb2N1bWVudDwvY29kZT4KLSAgICAgKiBpbnRlcmZhY2Ugb3RoZXJ3aXNlLgotICAgICAqCi0gICAgICogQHNpbmNlIERPTSBMZXZlbCAzCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRCYXNlVVJJKCk7Ci0KLSAgICAvLyBEb2N1bWVudFBvc2l0aW9uCi0gICAgLyoqCi0gICAgICogVGhlIHR3byBub2RlcyBhcmUgZGlzY29ubmVjdGVkLiBPcmRlciBiZXR3ZWVuIGRpc2Nvbm5lY3RlZCBub2RlcyBpcwotICAgICAqIGFsd2F5cyBpbXBsZW1lbnRhdGlvbi1zcGVjaWZpYy4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IERPQ1VNRU5UX1BPU0lUSU9OX0RJU0NPTk5FQ1RFRCA9IDB4MDE7Ci0gICAgLyoqCi0gICAgICogVGhlIHNlY29uZCBub2RlIHByZWNlZGVzIHRoZSByZWZlcmVuY2Ugbm9kZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IERPQ1VNRU5UX1BPU0lUSU9OX1BSRUNFRElORyA9IDB4MDI7Ci0gICAgLyoqCi0gICAgICogVGhlIG5vZGUgZm9sbG93cyB0aGUgcmVmZXJlbmNlIG5vZGUuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBET0NVTUVOVF9QT1NJVElPTl9GT0xMT1dJTkcgPSAweDA0OwotICAgIC8qKgotICAgICAqIFRoZSBub2RlIGNvbnRhaW5zIHRoZSByZWZlcmVuY2Ugbm9kZS4gQSBub2RlIHdoaWNoIGNvbnRhaW5zIGlzIGFsd2F5cwotICAgICAqIHByZWNlZGluZywgdG9vLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgRE9DVU1FTlRfUE9TSVRJT05fQ09OVEFJTlMgPSAweDA4OwotICAgIC8qKgotICAgICAqIFRoZSBub2RlIGlzIGNvbnRhaW5lZCBieSB0aGUgcmVmZXJlbmNlIG5vZGUuIEEgbm9kZSB3aGljaCBpcyBjb250YWluZWQKLSAgICAgKiBpcyBhbHdheXMgZm9sbG93aW5nLCB0b28uCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBET0NVTUVOVF9QT1NJVElPTl9DT05UQUlORURfQlkgPSAweDEwOwotICAgIC8qKgotICAgICAqIFRoZSBkZXRlcm1pbmF0aW9uIG9mIHByZWNlZGluZyB2ZXJzdXMgZm9sbG93aW5nIGlzCi0gICAgICogaW1wbGVtZW50YXRpb24tc3BlY2lmaWMuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBET0NVTUVOVF9QT1NJVElPTl9JTVBMRU1FTlRBVElPTl9TUEVDSUZJQyA9IDB4MjA7Ci0KLSAgICAvKioKLSAgICAgKiBDb21wYXJlcyB0aGUgcmVmZXJlbmNlIG5vZGUsIGkuZS4gdGhlIG5vZGUgb24gd2hpY2ggdGhpcyBtZXRob2QgaXMKLSAgICAgKiBiZWluZyBjYWxsZWQsIHdpdGggYSBub2RlLCBpLmUuIHRoZSBvbmUgcGFzc2VkIGFzIGEgcGFyYW1ldGVyLCB3aXRoCi0gICAgICogcmVnYXJkIHRvIHRoZWlyIHBvc2l0aW9uIGluIHRoZSBkb2N1bWVudCBhbmQgYWNjb3JkaW5nIHRvIHRoZQotICAgICAqIGRvY3VtZW50IG9yZGVyLgotICAgICAqIEBwYXJhbSBvdGhlciBUaGUgbm9kZSB0byBjb21wYXJlIGFnYWluc3QgdGhlIHJlZmVyZW5jZSBub2RlLgotICAgICAqIEByZXR1cm4gUmV0dXJucyBob3cgdGhlIG5vZGUgaXMgcG9zaXRpb25lZCByZWxhdGl2ZWx5IHRvIHRoZSByZWZlcmVuY2UKLSAgICAgKiAgIG5vZGUuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIE5PVF9TVVBQT1JURURfRVJSOiB3aGVuIHRoZSBjb21wYXJlZCBub2RlcyBhcmUgZnJvbSBkaWZmZXJlbnQgRE9NCi0gICAgICogICBpbXBsZW1lbnRhdGlvbnMgdGhhdCBkbyBub3QgY29vcmRpbmF0ZSB0byByZXR1cm4gY29uc2lzdGVudAotICAgICAqICAgaW1wbGVtZW50YXRpb24tc3BlY2lmaWMgcmVzdWx0cy4KLSAgICAgKgotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgICAqLwotICAgIHB1YmxpYyBzaG9ydCBjb21wYXJlRG9jdW1lbnRQb3NpdGlvbihOb2RlIG90aGVyKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogVGhpcyBhdHRyaWJ1dGUgcmV0dXJucyB0aGUgdGV4dCBjb250ZW50IG9mIHRoaXMgbm9kZSBhbmQgaXRzCi0gICAgICogZGVzY2VuZGFudHMuIFdoZW4gaXQgaXMgZGVmaW5lZCB0byBiZSA8Y29kZT5udWxsPC9jb2RlPiwgc2V0dGluZyBpdAotICAgICAqIGhhcyBubyBlZmZlY3QuIE9uIHNldHRpbmcsIGFueSBwb3NzaWJsZSBjaGlsZHJlbiB0aGlzIG5vZGUgbWF5IGhhdmUKLSAgICAgKiBhcmUgcmVtb3ZlZCBhbmQsIGlmIGl0IHRoZSBuZXcgc3RyaW5nIGlzIG5vdCBlbXB0eSBvcgotICAgICAqIDxjb2RlPm51bGw8L2NvZGU+LCByZXBsYWNlZCBieSBhIHNpbmdsZSA8Y29kZT5UZXh0PC9jb2RlPiBub2RlCi0gICAgICogY29udGFpbmluZyB0aGUgc3RyaW5nIHRoaXMgYXR0cmlidXRlIGlzIHNldCB0by4KLSAgICAgKiA8YnI+IE9uIGdldHRpbmcsIG5vIHNlcmlhbGl6YXRpb24gaXMgcGVyZm9ybWVkLCB0aGUgcmV0dXJuZWQgc3RyaW5nCi0gICAgICogZG9lcyBub3QgY29udGFpbiBhbnkgbWFya3VwLiBObyB3aGl0ZXNwYWNlIG5vcm1hbGl6YXRpb24gaXMgcGVyZm9ybWVkCi0gICAgICogYW5kIHRoZSByZXR1cm5lZCBzdHJpbmcgZG9lcyBub3QgY29udGFpbiB0aGUgd2hpdGUgc3BhY2VzIGluIGVsZW1lbnQKLSAgICAgKiBjb250ZW50IChzZWUgdGhlIGF0dHJpYnV0ZQotICAgICAqIDxjb2RlPlRleHQuaXNFbGVtZW50Q29udGVudFdoaXRlc3BhY2U8L2NvZGU+KS4gU2ltaWxhcmx5LCBvbiBzZXR0aW5nLAotICAgICAqIG5vIHBhcnNpbmcgaXMgcGVyZm9ybWVkIGVpdGhlciwgdGhlIGlucHV0IHN0cmluZyBpcyB0YWtlbiBhcyBwdXJlCi0gICAgICogdGV4dHVhbCBjb250ZW50LgotICAgICAqIDxicj5UaGUgc3RyaW5nIHJldHVybmVkIGlzIG1hZGUgb2YgdGhlIHRleHQgY29udGVudCBvZiB0aGlzIG5vZGUKLSAgICAgKiBkZXBlbmRpbmcgb24gaXRzIHR5cGUsIGFzIGRlZmluZWQgYmVsb3c6Ci0gICAgICogPHRhYmxlIGJvcmRlcj0nMScgY2VsbHBhZGRpbmc9JzMnPgotICAgICAqIDx0cj4KLSAgICAgKiA8dGg+Tm9kZSB0eXBlPC90aD4KLSAgICAgKiA8dGg+Q29udGVudDwvdGg+Ci0gICAgICogPC90cj4KLSAgICAgKiA8dHI+Ci0gICAgICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz4KLSAgICAgKiBFTEVNRU5UX05PREUsIEFUVFJJQlVURV9OT0RFLCBFTlRJVFlfTk9ERSwgRU5USVRZX1JFRkVSRU5DRV9OT0RFLAotICAgICAqIERPQ1VNRU5UX0ZSQUdNRU5UX05PREU8L3RkPgotICAgICAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+Y29uY2F0ZW5hdGlvbiBvZiB0aGUgPGNvZGU+dGV4dENvbnRlbnQ8L2NvZGU+Ci0gICAgICogYXR0cmlidXRlIHZhbHVlIG9mIGV2ZXJ5IGNoaWxkIG5vZGUsIGV4Y2x1ZGluZyBDT01NRU5UX05PREUgYW5kCi0gICAgICogUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFIG5vZGVzLiBUaGlzIGlzIHRoZSBlbXB0eSBzdHJpbmcgaWYgdGhlCi0gICAgICogbm9kZSBoYXMgbm8gY2hpbGRyZW4uPC90ZD4KLSAgICAgKiA8L3RyPgotICAgICAqIDx0cj4KLSAgICAgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPlRFWFRfTk9ERSwgQ0RBVEFfU0VDVElPTl9OT0RFLCBDT01NRU5UX05PREUsCi0gICAgICogUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFPC90ZD4KLSAgICAgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPjxjb2RlPm5vZGVWYWx1ZTwvY29kZT48L3RkPgotICAgICAqIDwvdHI+Ci0gICAgICogPHRyPgotICAgICAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+RE9DVU1FTlRfTk9ERSwKLSAgICAgKiBET0NVTUVOVF9UWVBFX05PREUsIE5PVEFUSU9OX05PREU8L3RkPgotICAgICAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+PGVtPm51bGw8L2VtPjwvdGQ+Ci0gICAgICogPC90cj4KLSAgICAgKiA8L3RhYmxlPgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBET01TVFJJTkdfU0laRV9FUlI6IFJhaXNlZCB3aGVuIGl0IHdvdWxkIHJldHVybiBtb3JlIGNoYXJhY3RlcnMgdGhhbgotICAgICAqICAgZml0IGluIGEgPGNvZGU+RE9NU3RyaW5nPC9jb2RlPiB2YXJpYWJsZSBvbiB0aGUgaW1wbGVtZW50YXRpb24KLSAgICAgKiAgIHBsYXRmb3JtLgotICAgICAqCi0gICAgICogQHNpbmNlIERPTSBMZXZlbCAzCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRUZXh0Q29udGVudCgpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0gICAgLyoqCi0gICAgICogVGhpcyBhdHRyaWJ1dGUgcmV0dXJucyB0aGUgdGV4dCBjb250ZW50IG9mIHRoaXMgbm9kZSBhbmQgaXRzCi0gICAgICogZGVzY2VuZGFudHMuIFdoZW4gaXQgaXMgZGVmaW5lZCB0byBiZSA8Y29kZT5udWxsPC9jb2RlPiwgc2V0dGluZyBpdAotICAgICAqIGhhcyBubyBlZmZlY3QuIE9uIHNldHRpbmcsIGFueSBwb3NzaWJsZSBjaGlsZHJlbiB0aGlzIG5vZGUgbWF5IGhhdmUKLSAgICAgKiBhcmUgcmVtb3ZlZCBhbmQsIGlmIGl0IHRoZSBuZXcgc3RyaW5nIGlzIG5vdCBlbXB0eSBvcgotICAgICAqIDxjb2RlPm51bGw8L2NvZGU+LCByZXBsYWNlZCBieSBhIHNpbmdsZSA8Y29kZT5UZXh0PC9jb2RlPiBub2RlCi0gICAgICogY29udGFpbmluZyB0aGUgc3RyaW5nIHRoaXMgYXR0cmlidXRlIGlzIHNldCB0by4KLSAgICAgKiA8YnI+IE9uIGdldHRpbmcsIG5vIHNlcmlhbGl6YXRpb24gaXMgcGVyZm9ybWVkLCB0aGUgcmV0dXJuZWQgc3RyaW5nCi0gICAgICogZG9lcyBub3QgY29udGFpbiBhbnkgbWFya3VwLiBObyB3aGl0ZXNwYWNlIG5vcm1hbGl6YXRpb24gaXMgcGVyZm9ybWVkCi0gICAgICogYW5kIHRoZSByZXR1cm5lZCBzdHJpbmcgZG9lcyBub3QgY29udGFpbiB0aGUgd2hpdGUgc3BhY2VzIGluIGVsZW1lbnQKLSAgICAgKiBjb250ZW50IChzZWUgdGhlIGF0dHJpYnV0ZQotICAgICAqIDxjb2RlPlRleHQuaXNFbGVtZW50Q29udGVudFdoaXRlc3BhY2U8L2NvZGU+KS4gU2ltaWxhcmx5LCBvbiBzZXR0aW5nLAotICAgICAqIG5vIHBhcnNpbmcgaXMgcGVyZm9ybWVkIGVpdGhlciwgdGhlIGlucHV0IHN0cmluZyBpcyB0YWtlbiBhcyBwdXJlCi0gICAgICogdGV4dHVhbCBjb250ZW50LgotICAgICAqIDxicj5UaGUgc3RyaW5nIHJldHVybmVkIGlzIG1hZGUgb2YgdGhlIHRleHQgY29udGVudCBvZiB0aGlzIG5vZGUKLSAgICAgKiBkZXBlbmRpbmcgb24gaXRzIHR5cGUsIGFzIGRlZmluZWQgYmVsb3c6Ci0gICAgICogPHRhYmxlIGJvcmRlcj0nMScgY2VsbHBhZGRpbmc9JzMnPgotICAgICAqIDx0cj4KLSAgICAgKiA8dGg+Tm9kZSB0eXBlPC90aD4KLSAgICAgKiA8dGg+Q29udGVudDwvdGg+Ci0gICAgICogPC90cj4KLSAgICAgKiA8dHI+Ci0gICAgICogPHRkIHZhbGlnbj0ndG9wJyByb3dzcGFuPScxJyBjb2xzcGFuPScxJz4KLSAgICAgKiBFTEVNRU5UX05PREUsIEFUVFJJQlVURV9OT0RFLCBFTlRJVFlfTk9ERSwgRU5USVRZX1JFRkVSRU5DRV9OT0RFLAotICAgICAqIERPQ1VNRU5UX0ZSQUdNRU5UX05PREU8L3RkPgotICAgICAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+Y29uY2F0ZW5hdGlvbiBvZiB0aGUgPGNvZGU+dGV4dENvbnRlbnQ8L2NvZGU+Ci0gICAgICogYXR0cmlidXRlIHZhbHVlIG9mIGV2ZXJ5IGNoaWxkIG5vZGUsIGV4Y2x1ZGluZyBDT01NRU5UX05PREUgYW5kCi0gICAgICogUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFIG5vZGVzLiBUaGlzIGlzIHRoZSBlbXB0eSBzdHJpbmcgaWYgdGhlCi0gICAgICogbm9kZSBoYXMgbm8gY2hpbGRyZW4uPC90ZD4KLSAgICAgKiA8L3RyPgotICAgICAqIDx0cj4KLSAgICAgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPlRFWFRfTk9ERSwgQ0RBVEFfU0VDVElPTl9OT0RFLCBDT01NRU5UX05PREUsCi0gICAgICogUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFPC90ZD4KLSAgICAgKiA8dGQgdmFsaWduPSd0b3AnIHJvd3NwYW49JzEnIGNvbHNwYW49JzEnPjxjb2RlPm5vZGVWYWx1ZTwvY29kZT48L3RkPgotICAgICAqIDwvdHI+Ci0gICAgICogPHRyPgotICAgICAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+RE9DVU1FTlRfTk9ERSwKLSAgICAgKiBET0NVTUVOVF9UWVBFX05PREUsIE5PVEFUSU9OX05PREU8L3RkPgotICAgICAqIDx0ZCB2YWxpZ249J3RvcCcgcm93c3Bhbj0nMScgY29sc3Bhbj0nMSc+PGVtPm51bGw8L2VtPjwvdGQ+Ci0gICAgICogPC90cj4KLSAgICAgKiA8L3RhYmxlPgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCB3aGVuIHRoZSBub2RlIGlzIHJlYWRvbmx5LgotICAgICAqCi0gICAgICogQHNpbmNlIERPTSBMZXZlbCAzCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0VGV4dENvbnRlbnQoU3RyaW5nIHRleHRDb250ZW50KQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB3aGV0aGVyIHRoaXMgbm9kZSBpcyB0aGUgc2FtZSBub2RlIGFzIHRoZSBnaXZlbiBvbmUuCi0gICAgICogPGJyPlRoaXMgbWV0aG9kIHByb3ZpZGVzIGEgd2F5IHRvIGRldGVybWluZSB3aGV0aGVyIHR3bwotICAgICAqIDxjb2RlPk5vZGU8L2NvZGU+IHJlZmVyZW5jZXMgcmV0dXJuZWQgYnkgdGhlIGltcGxlbWVudGF0aW9uIHJlZmVyZW5jZQotICAgICAqIHRoZSBzYW1lIG9iamVjdC4gV2hlbiB0d28gPGNvZGU+Tm9kZTwvY29kZT4gcmVmZXJlbmNlcyBhcmUgcmVmZXJlbmNlcwotICAgICAqIHRvIHRoZSBzYW1lIG9iamVjdCwgZXZlbiBpZiB0aHJvdWdoIGEgcHJveHksIHRoZSByZWZlcmVuY2VzIG1heSBiZQotICAgICAqIHVzZWQgY29tcGxldGVseSBpbnRlcmNoYW5nZWFibHksIHN1Y2ggdGhhdCBhbGwgYXR0cmlidXRlcyBoYXZlIHRoZQotICAgICAqIHNhbWUgdmFsdWVzIGFuZCBjYWxsaW5nIHRoZSBzYW1lIERPTSBtZXRob2Qgb24gZWl0aGVyIHJlZmVyZW5jZQotICAgICAqIGFsd2F5cyBoYXMgZXhhY3RseSB0aGUgc2FtZSBlZmZlY3QuCi0gICAgICogQHBhcmFtIG90aGVyIFRoZSBub2RlIHRvIHRlc3QgYWdhaW5zdC4KLSAgICAgKiBAcmV0dXJuIFJldHVybnMgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIG5vZGVzIGFyZSB0aGUgc2FtZSwKLSAgICAgKiAgIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuCi0gICAgICoKLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc1NhbWVOb2RlKE5vZGUgb3RoZXIpOwotCi0gICAgLyoqCi0gICAgICogTG9vayB1cCB0aGUgcHJlZml4IGFzc29jaWF0ZWQgdG8gdGhlIGdpdmVuIG5hbWVzcGFjZSBVUkksIHN0YXJ0aW5nIGZyb20KLSAgICAgKiB0aGlzIG5vZGUuIFRoZSBkZWZhdWx0IG5hbWVzcGFjZSBkZWNsYXJhdGlvbnMgYXJlIGlnbm9yZWQgYnkgdGhpcwotICAgICAqIG1ldGhvZC4KLSAgICAgKiA8YnI+U2VlICBmb3IgZGV0YWlscyBvbiB0aGUgYWxnb3JpdGhtIHVzZWQgYnkgdGhpcyBtZXRob2QuCi0gICAgICogQHBhcmFtIG5hbWVzcGFjZVVSSSBUaGUgbmFtZXNwYWNlIFVSSSB0byBsb29rIGZvci4KLSAgICAgKiBAcmV0dXJuIFJldHVybnMgYW4gYXNzb2NpYXRlZCBuYW1lc3BhY2UgcHJlZml4IGlmIGZvdW5kIG9yCi0gICAgICogICA8Y29kZT5udWxsPC9jb2RlPiBpZiBub25lIGlzIGZvdW5kLiBJZiBtb3JlIHRoYW4gb25lIHByZWZpeCBhcmUKLSAgICAgKiAgIGFzc29jaWF0ZWQgdG8gdGhlIG5hbWVzcGFjZSBwcmVmaXgsIHRoZSByZXR1cm5lZCBuYW1lc3BhY2UgcHJlZml4Ci0gICAgICogICBpcyBpbXBsZW1lbnRhdGlvbiBkZXBlbmRlbnQuCi0gICAgICoKLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGxvb2t1cFByZWZpeChTdHJpbmcgbmFtZXNwYWNlVVJJKTsKLQotICAgIC8qKgotICAgICAqICBUaGlzIG1ldGhvZCBjaGVja3MgaWYgdGhlIHNwZWNpZmllZCA8Y29kZT5uYW1lc3BhY2VVUkk8L2NvZGU+IGlzIHRoZQotICAgICAqIGRlZmF1bHQgbmFtZXNwYWNlIG9yIG5vdC4KLSAgICAgKiBAcGFyYW0gbmFtZXNwYWNlVVJJIFRoZSBuYW1lc3BhY2UgVVJJIHRvIGxvb2sgZm9yLgotICAgICAqIEByZXR1cm4gUmV0dXJucyA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgc3BlY2lmaWVkCi0gICAgICogICA8Y29kZT5uYW1lc3BhY2VVUkk8L2NvZGU+IGlzIHRoZSBkZWZhdWx0IG5hbWVzcGFjZSwKLSAgICAgKiAgIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuCi0gICAgICoKLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0RlZmF1bHROYW1lc3BhY2UoU3RyaW5nIG5hbWVzcGFjZVVSSSk7Ci0KLSAgICAvKioKLSAgICAgKiBMb29rIHVwIHRoZSBuYW1lc3BhY2UgVVJJIGFzc29jaWF0ZWQgdG8gdGhlIGdpdmVuIHByZWZpeCwgc3RhcnRpbmcgZnJvbQotICAgICAqIHRoaXMgbm9kZS4KLSAgICAgKiA8YnI+U2VlICBmb3IgZGV0YWlscyBvbiB0aGUgYWxnb3JpdGhtIHVzZWQgYnkgdGhpcyBtZXRob2QuCi0gICAgICogQHBhcmFtIHByZWZpeCBUaGUgcHJlZml4IHRvIGxvb2sgZm9yLiBJZiB0aGlzIHBhcmFtZXRlciBpcwotICAgICAqICAgPGNvZGU+bnVsbDwvY29kZT4sIHRoZSBtZXRob2Qgd2lsbCByZXR1cm4gdGhlIGRlZmF1bHQgbmFtZXNwYWNlIFVSSQotICAgICAqICAgaWYgYW55LgotICAgICAqIEByZXR1cm4gUmV0dXJucyB0aGUgYXNzb2NpYXRlZCBuYW1lc3BhY2UgVVJJIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmCi0gICAgICogICBub25lIGlzIGZvdW5kLgotICAgICAqCi0gICAgICogQHNpbmNlIERPTSBMZXZlbCAzCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBsb29rdXBOYW1lc3BhY2VVUkkoU3RyaW5nIHByZWZpeCk7Ci0KLSAgICAvKioKLSAgICAgKiBUZXN0cyB3aGV0aGVyIHR3byBub2RlcyBhcmUgZXF1YWwuCi0gICAgICogPGJyPlRoaXMgbWV0aG9kIHRlc3RzIGZvciBlcXVhbGl0eSBvZiBub2Rlcywgbm90IHNhbWVuZXNzIChpLmUuLAotICAgICAqIHdoZXRoZXIgdGhlIHR3byBub2RlcyBhcmUgcmVmZXJlbmNlcyB0byB0aGUgc2FtZSBvYmplY3QpIHdoaWNoIGNhbiBiZQotICAgICAqIHRlc3RlZCB3aXRoIDxjb2RlPk5vZGUuaXNTYW1lTm9kZSgpPC9jb2RlPi4gQWxsIG5vZGVzIHRoYXQgYXJlIHRoZQotICAgICAqIHNhbWUgd2lsbCBhbHNvIGJlIGVxdWFsLCB0aG91Z2ggdGhlIHJldmVyc2UgbWF5IG5vdCBiZSB0cnVlLgotICAgICAqIDxicj5Ud28gbm9kZXMgYXJlIGVxdWFsIGlmIGFuZCBvbmx5IGlmIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKLSAgICAgKiBzYXRpc2ZpZWQ6Ci0gICAgICogPHVsPgotICAgICAqIDxsaT5UaGUgdHdvIG5vZGVzIGFyZSBvZiB0aGUgc2FtZSB0eXBlLgotICAgICAqIDwvbGk+Ci0gICAgICogPGxpPlRoZSBmb2xsb3dpbmcgc3RyaW5nCi0gICAgICogYXR0cmlidXRlcyBhcmUgZXF1YWw6IDxjb2RlPm5vZGVOYW1lPC9jb2RlPiwgPGNvZGU+bG9jYWxOYW1lPC9jb2RlPiwKLSAgICAgKiA8Y29kZT5uYW1lc3BhY2VVUkk8L2NvZGU+LCA8Y29kZT5wcmVmaXg8L2NvZGU+LCA8Y29kZT5ub2RlVmFsdWU8L2NvZGU+Ci0gICAgICogLiBUaGlzIGlzOiB0aGV5IGFyZSBib3RoIDxjb2RlPm51bGw8L2NvZGU+LCBvciB0aGV5IGhhdmUgdGhlIHNhbWUKLSAgICAgKiBsZW5ndGggYW5kIGFyZSBjaGFyYWN0ZXIgZm9yIGNoYXJhY3RlciBpZGVudGljYWwuCi0gICAgICogPC9saT4KLSAgICAgKiA8bGk+VGhlCi0gICAgICogPGNvZGU+YXR0cmlidXRlczwvY29kZT4gPGNvZGU+TmFtZWROb2RlTWFwczwvY29kZT4gYXJlIGVxdWFsLiBUaGlzCi0gICAgICogaXM6IHRoZXkgYXJlIGJvdGggPGNvZGU+bnVsbDwvY29kZT4sIG9yIHRoZXkgaGF2ZSB0aGUgc2FtZSBsZW5ndGggYW5kCi0gICAgICogZm9yIGVhY2ggbm9kZSB0aGF0IGV4aXN0cyBpbiBvbmUgbWFwIHRoZXJlIGlzIGEgbm9kZSB0aGF0IGV4aXN0cyBpbgotICAgICAqIHRoZSBvdGhlciBtYXAgYW5kIGlzIGVxdWFsLCBhbHRob3VnaCBub3QgbmVjZXNzYXJpbHkgYXQgdGhlIHNhbWUKLSAgICAgKiBpbmRleC4KLSAgICAgKiA8L2xpPgotICAgICAqIDxsaT5UaGUgPGNvZGU+Y2hpbGROb2RlczwvY29kZT4gPGNvZGU+Tm9kZUxpc3RzPC9jb2RlPiBhcmUgZXF1YWwuCi0gICAgICogVGhpcyBpczogdGhleSBhcmUgYm90aCA8Y29kZT5udWxsPC9jb2RlPiwgb3IgdGhleSBoYXZlIHRoZSBzYW1lCi0gICAgICogbGVuZ3RoIGFuZCBjb250YWluIGVxdWFsIG5vZGVzIGF0IHRoZSBzYW1lIGluZGV4LiBOb3RlIHRoYXQKLSAgICAgKiBub3JtYWxpemF0aW9uIGNhbiBhZmZlY3QgZXF1YWxpdHk7IHRvIGF2b2lkIHRoaXMsIG5vZGVzIHNob3VsZCBiZQotICAgICAqIG5vcm1hbGl6ZWQgYmVmb3JlIGJlaW5nIGNvbXBhcmVkLgotICAgICAqIDwvbGk+Ci0gICAgICogPC91bD4KLSAgICAgKiA8YnI+Rm9yIHR3byA8Y29kZT5Eb2N1bWVudFR5cGU8L2NvZGU+IG5vZGVzIHRvIGJlIGVxdWFsLCB0aGUgZm9sbG93aW5nCi0gICAgICogY29uZGl0aW9ucyBtdXN0IGFsc28gYmUgc2F0aXNmaWVkOgotICAgICAqIDx1bD4KLSAgICAgKiA8bGk+VGhlIGZvbGxvd2luZyBzdHJpbmcgYXR0cmlidXRlcwotICAgICAqIGFyZSBlcXVhbDogPGNvZGU+cHVibGljSWQ8L2NvZGU+LCA8Y29kZT5zeXN0ZW1JZDwvY29kZT4sCi0gICAgICogPGNvZGU+aW50ZXJuYWxTdWJzZXQ8L2NvZGU+LgotICAgICAqIDwvbGk+Ci0gICAgICogPGxpPlRoZSA8Y29kZT5lbnRpdGllczwvY29kZT4KLSAgICAgKiA8Y29kZT5OYW1lZE5vZGVNYXBzPC9jb2RlPiBhcmUgZXF1YWwuCi0gICAgICogPC9saT4KLSAgICAgKiA8bGk+VGhlIDxjb2RlPm5vdGF0aW9uczwvY29kZT4KLSAgICAgKiA8Y29kZT5OYW1lZE5vZGVNYXBzPC9jb2RlPiBhcmUgZXF1YWwuCi0gICAgICogPC9saT4KLSAgICAgKiA8L3VsPgotICAgICAqIDxicj5PbiB0aGUgb3RoZXIgaGFuZCwgdGhlIGZvbGxvd2luZyBkbyBub3QgYWZmZWN0IGVxdWFsaXR5OiB0aGUKLSAgICAgKiA8Y29kZT5vd25lckRvY3VtZW50PC9jb2RlPiwgPGNvZGU+YmFzZVVSSTwvY29kZT4sIGFuZAotICAgICAqIDxjb2RlPnBhcmVudE5vZGU8L2NvZGU+IGF0dHJpYnV0ZXMsIHRoZSA8Y29kZT5zcGVjaWZpZWQ8L2NvZGU+Ci0gICAgICogYXR0cmlidXRlIGZvciA8Y29kZT5BdHRyPC9jb2RlPiBub2RlcywgdGhlIDxjb2RlPnNjaGVtYVR5cGVJbmZvPC9jb2RlPgotICAgICAqICBhdHRyaWJ1dGUgZm9yIDxjb2RlPkF0dHI8L2NvZGU+IGFuZCA8Y29kZT5FbGVtZW50PC9jb2RlPiBub2RlcywgdGhlCi0gICAgICogPGNvZGU+VGV4dC5pc0VsZW1lbnRDb250ZW50V2hpdGVzcGFjZTwvY29kZT4gYXR0cmlidXRlIGZvcgotICAgICAqIDxjb2RlPlRleHQ8L2NvZGU+IG5vZGVzLCBhcyB3ZWxsIGFzIGFueSB1c2VyIGRhdGEgb3IgZXZlbnQgbGlzdGVuZXJzCi0gICAgICogcmVnaXN0ZXJlZCBvbiB0aGUgbm9kZXMuCi0gICAgICogPHAgPjxiPk5vdGU6PC9iPiAgQXMgYSBnZW5lcmFsIHJ1bGUsIGFueXRoaW5nIG5vdCBtZW50aW9uZWQgaW4gdGhlCi0gICAgICogZGVzY3JpcHRpb24gYWJvdmUgaXMgbm90IHNpZ25pZmljYW50IGluIGNvbnNpZGVyYXRpb24gb2YgZXF1YWxpdHkKLSAgICAgKiBjaGVja2luZy4gTm90ZSB0aGF0IGZ1dHVyZSB2ZXJzaW9ucyBvZiB0aGlzIHNwZWNpZmljYXRpb24gbWF5IHRha2UKLSAgICAgKiBpbnRvIGFjY291bnQgbW9yZSBhdHRyaWJ1dGVzIGFuZCBpbXBsZW1lbnRhdGlvbnMgY29uZm9ybSB0byB0aGlzCi0gICAgICogc3BlY2lmaWNhdGlvbiBhcmUgZXhwZWN0ZWQgdG8gYmUgdXBkYXRlZCBhY2NvcmRpbmdseS4KLSAgICAgKiBAcGFyYW0gYXJnIFRoZSBub2RlIHRvIGNvbXBhcmUgZXF1YWxpdHkgd2l0aC4KLSAgICAgKiBAcmV0dXJuIFJldHVybnMgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIG5vZGVzIGFyZSBlcXVhbCwKLSAgICAgKiAgIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuCi0gICAgICoKLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0VxdWFsTm9kZShOb2RlIGFyZyk7Ci0KLSAgICAvKioKLSAgICAgKiAgVGhpcyBtZXRob2QgcmV0dXJucyBhIHNwZWNpYWxpemVkIG9iamVjdCB3aGljaCBpbXBsZW1lbnRzIHRoZQotICAgICAqIHNwZWNpYWxpemVkIEFQSXMgb2YgdGhlIHNwZWNpZmllZCBmZWF0dXJlIGFuZCB2ZXJzaW9uLCBhcyBzcGVjaWZpZWQKLSAgICAgKiBpbiAuIFRoZSBzcGVjaWFsaXplZCBvYmplY3QgbWF5IGFsc28gYmUgb2J0YWluZWQgYnkgdXNpbmcKLSAgICAgKiBiaW5kaW5nLXNwZWNpZmljIGNhc3RpbmcgbWV0aG9kcyBidXQgaXMgbm90IG5lY2Vzc2FyaWx5IGV4cGVjdGVkIHRvLAotICAgICAqIGFzIGRpc2N1c3NlZCBpbiAuIFRoaXMgbWV0aG9kIGFsc28gYWxsb3cgdGhlIGltcGxlbWVudGF0aW9uIHRvCi0gICAgICogcHJvdmlkZSBzcGVjaWFsaXplZCBvYmplY3RzIHdoaWNoIGRvIG5vdCBzdXBwb3J0IHRoZSA8Y29kZT5Ob2RlPC9jb2RlPgotICAgICAqICBpbnRlcmZhY2UuCi0gICAgICogQHBhcmFtIGZlYXR1cmUgIFRoZSBuYW1lIG9mIHRoZSBmZWF0dXJlIHJlcXVlc3RlZC4gTm90ZSB0aGF0IGFueSBwbHVzCi0gICAgICogICBzaWduICIrIiBwcmVwZW5kZWQgdG8gdGhlIG5hbWUgb2YgdGhlIGZlYXR1cmUgd2lsbCBiZSBpZ25vcmVkIHNpbmNlCi0gICAgICogICBpdCBpcyBub3Qgc2lnbmlmaWNhbnQgaW4gdGhlIGNvbnRleHQgb2YgdGhpcyBtZXRob2QuCi0gICAgICogQHBhcmFtIHZlcnNpb24gIFRoaXMgaXMgdGhlIHZlcnNpb24gbnVtYmVyIG9mIHRoZSBmZWF0dXJlIHRvIHRlc3QuCi0gICAgICogQHJldHVybiAgUmV0dXJucyBhbiBvYmplY3Qgd2hpY2ggaW1wbGVtZW50cyB0aGUgc3BlY2lhbGl6ZWQgQVBJcyBvZgotICAgICAqICAgdGhlIHNwZWNpZmllZCBmZWF0dXJlIGFuZCB2ZXJzaW9uLCBpZiBhbnksIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmCi0gICAgICogICB0aGVyZSBpcyBubyBvYmplY3Qgd2hpY2ggaW1wbGVtZW50cyBpbnRlcmZhY2VzIGFzc29jaWF0ZWQgd2l0aCB0aGF0Ci0gICAgICogICBmZWF0dXJlLiBJZiB0aGUgPGNvZGU+RE9NT2JqZWN0PC9jb2RlPiByZXR1cm5lZCBieSB0aGlzIG1ldGhvZAotICAgICAqICAgaW1wbGVtZW50cyB0aGUgPGNvZGU+Tm9kZTwvY29kZT4gaW50ZXJmYWNlLCBpdCBtdXN0IGRlbGVnYXRlIHRvIHRoZQotICAgICAqICAgcHJpbWFyeSBjb3JlIDxjb2RlPk5vZGU8L2NvZGU+IGFuZCBub3QgcmV0dXJuIHJlc3VsdHMgaW5jb25zaXN0ZW50Ci0gICAgICogICB3aXRoIHRoZSBwcmltYXJ5IGNvcmUgPGNvZGU+Tm9kZTwvY29kZT4gc3VjaCBhcyBhdHRyaWJ1dGVzLAotICAgICAqICAgY2hpbGROb2RlcywgZXRjLgotICAgICAqCi0gICAgICogQHNpbmNlIERPTSBMZXZlbCAzCi0gICAgICovCi0gICAgcHVibGljIE9iamVjdCBnZXRGZWF0dXJlKFN0cmluZyBmZWF0dXJlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdmVyc2lvbik7Ci0KLSAgICAvKioKLSAgICAgKiBBc3NvY2lhdGUgYW4gb2JqZWN0IHRvIGEga2V5IG9uIHRoaXMgbm9kZS4gVGhlIG9iamVjdCBjYW4gbGF0ZXIgYmUKLSAgICAgKiByZXRyaWV2ZWQgZnJvbSB0aGlzIG5vZGUgYnkgY2FsbGluZyA8Y29kZT5nZXRVc2VyRGF0YTwvY29kZT4gd2l0aCB0aGUKLSAgICAgKiBzYW1lIGtleS4KLSAgICAgKiBAcGFyYW0ga2V5IFRoZSBrZXkgdG8gYXNzb2NpYXRlIHRoZSBvYmplY3QgdG8uCi0gICAgICogQHBhcmFtIGRhdGEgVGhlIG9iamVjdCB0byBhc3NvY2lhdGUgdG8gdGhlIGdpdmVuIGtleSwgb3IKLSAgICAgKiAgIDxjb2RlPm51bGw8L2NvZGU+IHRvIHJlbW92ZSBhbnkgZXhpc3RpbmcgYXNzb2NpYXRpb24gdG8gdGhhdCBrZXkuCi0gICAgICogQHBhcmFtIGhhbmRsZXIgVGhlIGhhbmRsZXIgdG8gYXNzb2NpYXRlIHRvIHRoYXQga2V5LCBvcgotICAgICAqICAgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICogQHJldHVybiBSZXR1cm5zIHRoZSA8Y29kZT5ET01Vc2VyRGF0YTwvY29kZT4gcHJldmlvdXNseSBhc3NvY2lhdGVkIHRvCi0gICAgICogICB0aGUgZ2l2ZW4ga2V5IG9uIHRoaXMgbm9kZSwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlcmUgd2FzIG5vbmUuCi0gICAgICoKLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0IHNldFVzZXJEYXRhKFN0cmluZyBrZXksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPYmplY3QgZGF0YSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVzZXJEYXRhSGFuZGxlciBoYW5kbGVyKTsKLQotICAgIC8qKgotICAgICAqIFJldHJpZXZlcyB0aGUgb2JqZWN0IGFzc29jaWF0ZWQgdG8gYSBrZXkgb24gYSB0aGlzIG5vZGUuIFRoZSBvYmplY3QKLSAgICAgKiBtdXN0IGZpcnN0IGhhdmUgYmVlbiBzZXQgdG8gdGhpcyBub2RlIGJ5IGNhbGxpbmcKLSAgICAgKiA8Y29kZT5zZXRVc2VyRGF0YTwvY29kZT4gd2l0aCB0aGUgc2FtZSBrZXkuCi0gICAgICogQHBhcmFtIGtleSBUaGUga2V5IHRoZSBvYmplY3QgaXMgYXNzb2NpYXRlZCB0by4KLSAgICAgKiBAcmV0dXJuIFJldHVybnMgdGhlIDxjb2RlPkRPTVVzZXJEYXRhPC9jb2RlPiBhc3NvY2lhdGVkIHRvIHRoZSBnaXZlbgotICAgICAqICAga2V5IG9uIHRoaXMgbm9kZSwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlcmUgd2FzIG5vbmUuCi0gICAgICoKLSAgICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0IGdldFVzZXJEYXRhKFN0cmluZyBrZXkpOwotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL3czYy9kb20vTm9kZUxpc3QuamF2YSBiL3NyYy9vcmcvdzNjL2RvbS9Ob2RlTGlzdC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyMDUyMWYxLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS9Ob2RlTGlzdC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNzAgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIFRoaXMgZmlsZSBpcyBhdmFpbGFibGUgdW5kZXIgYW5kIGdvdmVybmVkIGJ5IHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKLSAqIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICogSG93ZXZlciwgdGhlIGZvbGxvd2luZyBub3RpY2UgYWNjb21wYW5pZWQgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcwotICogZmlsZSBhbmQsIHBlciBpdHMgdGVybXMsIHNob3VsZCBub3QgYmUgcmVtb3ZlZDoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKLSAqCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgRXVyb3BlYW4gUmVzZWFyY2ggQ29uc29ydGl1bSBmb3IKLSAqIEluZm9ybWF0aWNzIGFuZCBNYXRoZW1hdGljcywgS2VpbyBVbml2ZXJzaXR5KS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcwotICogd29yayBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDKHIpIFNvZnR3YXJlIExpY2Vuc2UgWzFdIGluIHRoZSBob3BlIHRoYXQKLSAqIGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZAotICogd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLgotICoKLSAqIFsxXSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLzIwMDIvY29weXJpZ2h0LXNvZnR3YXJlLTIwMDIxMjMxCi0gKi8KLQotcGFja2FnZSBvcmcudzNjLmRvbTsKLQotLyoqCi0gKiBUaGUgPGNvZGU+Tm9kZUxpc3Q8L2NvZGU+IGludGVyZmFjZSBwcm92aWRlcyB0aGUgYWJzdHJhY3Rpb24gb2YgYW4gb3JkZXJlZAotICogY29sbGVjdGlvbiBvZiBub2Rlcywgd2l0aG91dCBkZWZpbmluZyBvciBjb25zdHJhaW5pbmcgaG93IHRoaXMgY29sbGVjdGlvbgotICogaXMgaW1wbGVtZW50ZWQuIDxjb2RlPk5vZGVMaXN0PC9jb2RlPiBvYmplY3RzIGluIHRoZSBET00gYXJlIGxpdmUuCi0gKiA8cD5UaGUgaXRlbXMgaW4gdGhlIDxjb2RlPk5vZGVMaXN0PC9jb2RlPiBhcmUgYWNjZXNzaWJsZSB2aWEgYW4gaW50ZWdyYWwKLSAqIGluZGV4LCBzdGFydGluZyBmcm9tIDAuCi0gKiA8cD5TZWUgYWxzbyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMtRE9NLUxldmVsLTMtQ29yZS0yMDA0MDQwNyc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDMgQ29yZSBTcGVjaWZpY2F0aW9uPC9hPi4KLSAqLwotcHVibGljIGludGVyZmFjZSBOb2RlTGlzdCB7Ci0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgPGNvZGU+aW5kZXg8L2NvZGU+dGggaXRlbSBpbiB0aGUgY29sbGVjdGlvbi4gSWYKLSAgICAgKiA8Y29kZT5pbmRleDwvY29kZT4gaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHRoZSBudW1iZXIgb2Ygbm9kZXMgaW4KLSAgICAgKiB0aGUgbGlzdCwgdGhpcyByZXR1cm5zIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAqIEBwYXJhbSBpbmRleCBJbmRleCBpbnRvIHRoZSBjb2xsZWN0aW9uLgotICAgICAqIEByZXR1cm4gVGhlIG5vZGUgYXQgdGhlIDxjb2RlPmluZGV4PC9jb2RlPnRoIHBvc2l0aW9uIGluIHRoZQotICAgICAqICAgPGNvZGU+Tm9kZUxpc3Q8L2NvZGU+LCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGF0IGlzIG5vdCBhIHZhbGlkCi0gICAgICogICBpbmRleC4KLSAgICAgKi8KLSAgICBwdWJsaWMgTm9kZSBpdGVtKGludCBpbmRleCk7Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgbnVtYmVyIG9mIG5vZGVzIGluIHRoZSBsaXN0LiBUaGUgcmFuZ2Ugb2YgdmFsaWQgY2hpbGQgbm9kZSBpbmRpY2VzCi0gICAgICogaXMgMCB0byA8Y29kZT5sZW5ndGgtMTwvY29kZT4gaW5jbHVzaXZlLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0TGVuZ3RoKCk7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvdzNjL2RvbS9Ob3RhdGlvbi5qYXZhIGIvc3JjL29yZy93M2MvZG9tL05vdGF0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDNiNWRiOTYuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy93M2MvZG9tL05vdGF0aW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw2OSArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogVGhpcyBmaWxlIGlzIGF2YWlsYWJsZSB1bmRlciBhbmQgZ292ZXJuZWQgYnkgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwotICogTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKiBIb3dldmVyLCB0aGUgZm9sbG93aW5nIG5vdGljZSBhY2NvbXBhbmllZCB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGlzCi0gKiBmaWxlIGFuZCwgcGVyIGl0cyB0ZXJtcywgc2hvdWxkIG5vdCBiZSByZW1vdmVkOgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAotICoKLSAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBFdXJvcGVhbiBSZXNlYXJjaCBDb25zb3J0aXVtIGZvcgotICogSW5mb3JtYXRpY3MgYW5kIE1hdGhlbWF0aWNzLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwgUmlnaHRzIFJlc2VydmVkLiBUaGlzCi0gKiB3b3JrIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MocikgU29mdHdhcmUgTGljZW5zZSBbMV0gaW4gdGhlIGhvcGUgdGhhdAotICogaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkCi0gKiB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuCi0gKgotICogWzFdIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvMjAwMi9jb3B5cmlnaHQtc29mdHdhcmUtMjAwMjEyMzEKLSAqLwotCi1wYWNrYWdlIG9yZy53M2MuZG9tOwotCi0vKioKLSAqIFRoaXMgaW50ZXJmYWNlIHJlcHJlc2VudHMgYSBub3RhdGlvbiBkZWNsYXJlZCBpbiB0aGUgRFRELiBBIG5vdGF0aW9uIGVpdGhlcgotICogZGVjbGFyZXMsIGJ5IG5hbWUsIHRoZSBmb3JtYXQgb2YgYW4gdW5wYXJzZWQgZW50aXR5IChzZWUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMteG1sLTIwMDQwMjA0I05vdGF0aW9ucyc+c2VjdGlvbiA0Ljc8L2E+IG9mIHRoZSBYTUwgMS4wIHNwZWNpZmljYXRpb24gWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLXhtbC0yMDA0MDIwNCc+WE1MIDEuMDwvYT5dKSwgb3IgaXMKLSAqIHVzZWQgZm9yIGZvcm1hbCBkZWNsYXJhdGlvbiBvZiBwcm9jZXNzaW5nIGluc3RydWN0aW9uIHRhcmdldHMgKHNlZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy14bWwtMjAwNDAyMDQjc2VjLXBpJz5zZWN0aW9uIDIuNjwvYT4gb2YgdGhlIFhNTCAxLjAgc3BlY2lmaWNhdGlvbiBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMteG1sLTIwMDQwMjA0Jz5YTUwgMS4wPC9hPl0pLiBUaGUKLSAqIDxjb2RlPm5vZGVOYW1lPC9jb2RlPiBhdHRyaWJ1dGUgaW5oZXJpdGVkIGZyb20gPGNvZGU+Tm9kZTwvY29kZT4gaXMgc2V0Ci0gKiB0byB0aGUgZGVjbGFyZWQgbmFtZSBvZiB0aGUgbm90YXRpb24uCi0gKiA8cD5UaGUgRE9NIENvcmUgZG9lcyBub3Qgc3VwcG9ydCBlZGl0aW5nIDxjb2RlPk5vdGF0aW9uPC9jb2RlPiBub2RlczsgdGhleQotICogYXJlIHRoZXJlZm9yZSByZWFkb25seS4KLSAqIDxwPkEgPGNvZGU+Tm90YXRpb248L2NvZGU+IG5vZGUgZG9lcyBub3QgaGF2ZSBhbnkgcGFyZW50LgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLURPTS1MZXZlbC0zLUNvcmUtMjAwNDA0MDcnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAzIENvcmUgU3BlY2lmaWNhdGlvbjwvYT4uCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgTm90YXRpb24gZXh0ZW5kcyBOb2RlIHsKLSAgICAvKioKLSAgICAgKiBUaGUgcHVibGljIGlkZW50aWZpZXIgb2YgdGhpcyBub3RhdGlvbi4gSWYgdGhlIHB1YmxpYyBpZGVudGlmaWVyIHdhcwotICAgICAqIG5vdCBzcGVjaWZpZWQsIHRoaXMgaXMgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRQdWJsaWNJZCgpOwotCi0gICAgLyoqCi0gICAgICogVGhlIHN5c3RlbSBpZGVudGlmaWVyIG9mIHRoaXMgbm90YXRpb24uIElmIHRoZSBzeXN0ZW0gaWRlbnRpZmllciB3YXMKLSAgICAgKiBub3Qgc3BlY2lmaWVkLCB0aGlzIGlzIDxjb2RlPm51bGw8L2NvZGU+LiBUaGlzIG1heSBiZSBhbiBhYnNvbHV0ZSBVUkkKLSAgICAgKiBvciBub3QuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRTeXN0ZW1JZCgpOwotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL3czYy9kb20vUHJvY2Vzc2luZ0luc3RydWN0aW9uLmphdmEgYi9zcmMvb3JnL3czYy9kb20vUHJvY2Vzc2luZ0luc3RydWN0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGE4ZWU3MzkuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy93M2MvZG9tL1Byb2Nlc3NpbmdJbnN0cnVjdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsODAgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIFRoaXMgZmlsZSBpcyBhdmFpbGFibGUgdW5kZXIgYW5kIGdvdmVybmVkIGJ5IHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKLSAqIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICogSG93ZXZlciwgdGhlIGZvbGxvd2luZyBub3RpY2UgYWNjb21wYW5pZWQgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcwotICogZmlsZSBhbmQsIHBlciBpdHMgdGVybXMsIHNob3VsZCBub3QgYmUgcmVtb3ZlZDoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKLSAqCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgRXVyb3BlYW4gUmVzZWFyY2ggQ29uc29ydGl1bSBmb3IKLSAqIEluZm9ybWF0aWNzIGFuZCBNYXRoZW1hdGljcywgS2VpbyBVbml2ZXJzaXR5KS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcwotICogd29yayBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDKHIpIFNvZnR3YXJlIExpY2Vuc2UgWzFdIGluIHRoZSBob3BlIHRoYXQKLSAqIGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZAotICogd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLgotICoKLSAqIFsxXSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLzIwMDIvY29weXJpZ2h0LXNvZnR3YXJlLTIwMDIxMjMxCi0gKi8KLQotcGFja2FnZSBvcmcudzNjLmRvbTsKLQotLyoqCi0gKiBUaGUgPGNvZGU+UHJvY2Vzc2luZ0luc3RydWN0aW9uPC9jb2RlPiBpbnRlcmZhY2UgcmVwcmVzZW50cyBhICJwcm9jZXNzaW5nCi0gKiBpbnN0cnVjdGlvbiIsIHVzZWQgaW4gWE1MIGFzIGEgd2F5IHRvIGtlZXAgcHJvY2Vzc29yLXNwZWNpZmljIGluZm9ybWF0aW9uCi0gKiBpbiB0aGUgdGV4dCBvZiB0aGUgZG9jdW1lbnQuCi0gKiA8cD4gTm8gbGV4aWNhbCBjaGVjayBpcyBkb25lIG9uIHRoZSBjb250ZW50IG9mIGEgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiBhbmQKLSAqIGl0IGlzIHRoZXJlZm9yZSBwb3NzaWJsZSB0byBoYXZlIHRoZSBjaGFyYWN0ZXIgc2VxdWVuY2UKLSAqIDxjb2RlPiI/Jmd0OyI8L2NvZGU+IGluIHRoZSBjb250ZW50LCB3aGljaCBpcyBpbGxlZ2FsIGEgcHJvY2Vzc2luZwotICogaW5zdHJ1Y3Rpb24gcGVyIHNlY3Rpb24gMi42IG9mIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy14bWwtMjAwNDAyMDQnPlhNTCAxLjA8L2E+XS4gVGhlCi0gKiBwcmVzZW5jZSBvZiB0aGlzIGNoYXJhY3RlciBzZXF1ZW5jZSBtdXN0IGdlbmVyYXRlIGEgZmF0YWwgZXJyb3IgZHVyaW5nCi0gKiBzZXJpYWxpemF0aW9uLgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLURPTS1MZXZlbC0zLUNvcmUtMjAwNDA0MDcnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAzIENvcmUgU3BlY2lmaWNhdGlvbjwvYT4uCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgUHJvY2Vzc2luZ0luc3RydWN0aW9uIGV4dGVuZHMgTm9kZSB7Ci0gICAgLyoqCi0gICAgICogVGhlIHRhcmdldCBvZiB0aGlzIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24uIFhNTCBkZWZpbmVzIHRoaXMgYXMgYmVpbmcKLSAgICAgKiB0aGUgZmlyc3QgdG9rZW4gZm9sbG93aW5nIHRoZSBtYXJrdXAgdGhhdCBiZWdpbnMgdGhlIHByb2Nlc3NpbmcKLSAgICAgKiBpbnN0cnVjdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldCgpOwotCi0gICAgLyoqCi0gICAgICogVGhlIGNvbnRlbnQgb2YgdGhpcyBwcm9jZXNzaW5nIGluc3RydWN0aW9uLiBUaGlzIGlzIGZyb20gdGhlIGZpcnN0IG5vbgotICAgICAqIHdoaXRlIHNwYWNlIGNoYXJhY3RlciBhZnRlciB0aGUgdGFyZ2V0IHRvIHRoZSBjaGFyYWN0ZXIgaW1tZWRpYXRlbHkKLSAgICAgKiBwcmVjZWRpbmcgdGhlIDxjb2RlPj8mZ3Q7PC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldERhdGEoKTsKLSAgICAvKioKLSAgICAgKiBUaGUgY29udGVudCBvZiB0aGlzIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24uIFRoaXMgaXMgZnJvbSB0aGUgZmlyc3Qgbm9uCi0gICAgICogd2hpdGUgc3BhY2UgY2hhcmFjdGVyIGFmdGVyIHRoZSB0YXJnZXQgdG8gdGhlIGNoYXJhY3RlciBpbW1lZGlhdGVseQotICAgICAqIHByZWNlZGluZyB0aGUgPGNvZGU+PyZndDs8L2NvZGU+LgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCB3aGVuIHRoZSBub2RlIGlzIHJlYWRvbmx5LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldERhdGEoU3RyaW5nIGRhdGEpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvdzNjL2RvbS9UZXh0LmphdmEgYi9zcmMvb3JnL3czYy9kb20vVGV4dC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmNTRkMGVlLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS9UZXh0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxODcgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIFRoaXMgZmlsZSBpcyBhdmFpbGFibGUgdW5kZXIgYW5kIGdvdmVybmVkIGJ5IHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKLSAqIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICogSG93ZXZlciwgdGhlIGZvbGxvd2luZyBub3RpY2UgYWNjb21wYW5pZWQgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcwotICogZmlsZSBhbmQsIHBlciBpdHMgdGVybXMsIHNob3VsZCBub3QgYmUgcmVtb3ZlZDoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKLSAqCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgRXVyb3BlYW4gUmVzZWFyY2ggQ29uc29ydGl1bSBmb3IKLSAqIEluZm9ybWF0aWNzIGFuZCBNYXRoZW1hdGljcywgS2VpbyBVbml2ZXJzaXR5KS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcwotICogd29yayBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDKHIpIFNvZnR3YXJlIExpY2Vuc2UgWzFdIGluIHRoZSBob3BlIHRoYXQKLSAqIGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZAotICogd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLgotICoKLSAqIFsxXSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLzIwMDIvY29weXJpZ2h0LXNvZnR3YXJlLTIwMDIxMjMxCi0gKi8KLQotcGFja2FnZSBvcmcudzNjLmRvbTsKLQotLyoqCi0gKiBUaGUgPGNvZGU+VGV4dDwvY29kZT4gaW50ZXJmYWNlIGluaGVyaXRzIGZyb20gPGNvZGU+Q2hhcmFjdGVyRGF0YTwvY29kZT4KLSAqIGFuZCByZXByZXNlbnRzIHRoZSB0ZXh0dWFsIGNvbnRlbnQgKHRlcm1lZCA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy14bWwtMjAwNDAyMDQjc3ludGF4Jz5jaGFyYWN0ZXIgZGF0YTwvYT4gaW4gWE1MKSBvZiBhbiA8Y29kZT5FbGVtZW50PC9jb2RlPiBvciA8Y29kZT5BdHRyPC9jb2RlPi4gSWYgdGhlcmUgaXMgbm8KLSAqIG1hcmt1cCBpbnNpZGUgYW4gZWxlbWVudCdzIGNvbnRlbnQsIHRoZSB0ZXh0IGlzIGNvbnRhaW5lZCBpbiBhIHNpbmdsZQotICogb2JqZWN0IGltcGxlbWVudGluZyB0aGUgPGNvZGU+VGV4dDwvY29kZT4gaW50ZXJmYWNlIHRoYXQgaXMgdGhlIG9ubHkKLSAqIGNoaWxkIG9mIHRoZSBlbGVtZW50LiBJZiB0aGVyZSBpcyBtYXJrdXAsIGl0IGlzIHBhcnNlZCBpbnRvIHRoZQotICogaW5mb3JtYXRpb24gaXRlbXMgKGVsZW1lbnRzLCBjb21tZW50cywgZXRjLikgYW5kIDxjb2RlPlRleHQ8L2NvZGU+IG5vZGVzCi0gKiB0aGF0IGZvcm0gdGhlIGxpc3Qgb2YgY2hpbGRyZW4gb2YgdGhlIGVsZW1lbnQuCi0gKiA8cD5XaGVuIGEgZG9jdW1lbnQgaXMgZmlyc3QgbWFkZSBhdmFpbGFibGUgdmlhIHRoZSBET00sIHRoZXJlIGlzIG9ubHkgb25lCi0gKiA8Y29kZT5UZXh0PC9jb2RlPiBub2RlIGZvciBlYWNoIGJsb2NrIG9mIHRleHQuIFVzZXJzIG1heSBjcmVhdGUgYWRqYWNlbnQKLSAqIDxjb2RlPlRleHQ8L2NvZGU+IG5vZGVzIHRoYXQgcmVwcmVzZW50IHRoZSBjb250ZW50cyBvZiBhIGdpdmVuIGVsZW1lbnQKLSAqIHdpdGhvdXQgYW55IGludGVydmVuaW5nIG1hcmt1cCwgYnV0IHNob3VsZCBiZSBhd2FyZSB0aGF0IHRoZXJlIGlzIG5vIHdheQotICogdG8gcmVwcmVzZW50IHRoZSBzZXBhcmF0aW9ucyBiZXR3ZWVuIHRoZXNlIG5vZGVzIGluIFhNTCBvciBIVE1MLCBzbyB0aGV5Ci0gKiB3aWxsIG5vdCAoaW4gZ2VuZXJhbCkgcGVyc2lzdCBiZXR3ZWVuIERPTSBlZGl0aW5nIHNlc3Npb25zLiBUaGUKLSAqIDxjb2RlPk5vZGUubm9ybWFsaXplKCk8L2NvZGU+IG1ldGhvZCBtZXJnZXMgYW55IHN1Y2ggYWRqYWNlbnQKLSAqIDxjb2RlPlRleHQ8L2NvZGU+IG9iamVjdHMgaW50byBhIHNpbmdsZSBub2RlIGZvciBlYWNoIGJsb2NrIG9mIHRleHQuCi0gKiA8cD4gTm8gbGV4aWNhbCBjaGVjayBpcyBkb25lIG9uIHRoZSBjb250ZW50IG9mIGEgPGNvZGU+VGV4dDwvY29kZT4gbm9kZQotICogYW5kLCBkZXBlbmRpbmcgb24gaXRzIHBvc2l0aW9uIGluIHRoZSBkb2N1bWVudCwgc29tZSBjaGFyYWN0ZXJzIG11c3QgYmUKLSAqIGVzY2FwZWQgZHVyaW5nIHNlcmlhbGl6YXRpb24gdXNpbmcgY2hhcmFjdGVyIHJlZmVyZW5jZXM7IGUuZy4gdGhlCi0gKiBjaGFyYWN0ZXJzICImbHQ7JmFtcDsiIGlmIHRoZSB0ZXh0dWFsIGNvbnRlbnQgaXMgcGFydCBvZiBhbiBlbGVtZW50IG9yIG9mCi0gKiBhbiBhdHRyaWJ1dGUsIHRoZSBjaGFyYWN0ZXIgc2VxdWVuY2UgIl1dJmd0OyIgd2hlbiBwYXJ0IG9mIGFuIGVsZW1lbnQsCi0gKiB0aGUgcXVvdGF0aW9uIG1hcmsgY2hhcmFjdGVyICIgb3IgdGhlIGFwb3N0cm9waGUgY2hhcmFjdGVyICcgd2hlbiBwYXJ0IG9mCi0gKiBhbiBhdHRyaWJ1dGUuCi0gKiA8cD5TZWUgYWxzbyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMtRE9NLUxldmVsLTMtQ29yZS0yMDA0MDQwNyc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDMgQ29yZSBTcGVjaWZpY2F0aW9uPC9hPi4KLSAqLwotcHVibGljIGludGVyZmFjZSBUZXh0IGV4dGVuZHMgQ2hhcmFjdGVyRGF0YSB7Ci0gICAgLyoqCi0gICAgICogQnJlYWtzIHRoaXMgbm9kZSBpbnRvIHR3byBub2RlcyBhdCB0aGUgc3BlY2lmaWVkIDxjb2RlPm9mZnNldDwvY29kZT4sCi0gICAgICoga2VlcGluZyBib3RoIGluIHRoZSB0cmVlIGFzIHNpYmxpbmdzLiBBZnRlciBiZWluZyBzcGxpdCwgdGhpcyBub2RlCi0gICAgICogd2lsbCBjb250YWluIGFsbCB0aGUgY29udGVudCB1cCB0byB0aGUgPGNvZGU+b2Zmc2V0PC9jb2RlPiBwb2ludC4gQQotICAgICAqIG5ldyBub2RlIG9mIHRoZSBzYW1lIHR5cGUsIHdoaWNoIGNvbnRhaW5zIGFsbCB0aGUgY29udGVudCBhdCBhbmQKLSAgICAgKiBhZnRlciB0aGUgPGNvZGU+b2Zmc2V0PC9jb2RlPiBwb2ludCwgaXMgcmV0dXJuZWQuIElmIHRoZSBvcmlnaW5hbAotICAgICAqIG5vZGUgaGFkIGEgcGFyZW50IG5vZGUsIHRoZSBuZXcgbm9kZSBpcyBpbnNlcnRlZCBhcyB0aGUgbmV4dCBzaWJsaW5nCi0gICAgICogb2YgdGhlIG9yaWdpbmFsIG5vZGUuIFdoZW4gdGhlIDxjb2RlPm9mZnNldDwvY29kZT4gaXMgZXF1YWwgdG8gdGhlCi0gICAgICogbGVuZ3RoIG9mIHRoaXMgbm9kZSwgdGhlIG5ldyBub2RlIGhhcyBubyBkYXRhLgotICAgICAqIEBwYXJhbSBvZmZzZXQgVGhlIDE2LWJpdCB1bml0IG9mZnNldCBhdCB3aGljaCB0byBzcGxpdCwgc3RhcnRpbmcgZnJvbQotICAgICAqICAgPGNvZGU+MDwvY29kZT4uCi0gICAgICogQHJldHVybiBUaGUgbmV3IG5vZGUsIG9mIHRoZSBzYW1lIHR5cGUgYXMgdGhpcyBub2RlLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBJTkRFWF9TSVpFX0VSUjogUmFpc2VkIGlmIHRoZSBzcGVjaWZpZWQgb2Zmc2V0IGlzIG5lZ2F0aXZlIG9yIGdyZWF0ZXIKLSAgICAgKiAgIHRoYW4gdGhlIG51bWJlciBvZiAxNi1iaXQgdW5pdHMgaW4gPGNvZGU+ZGF0YTwvY29kZT4uCi0gICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBub2RlIGlzIHJlYWRvbmx5LgotICAgICAqLwotICAgIHB1YmxpYyBUZXh0IHNwbGl0VGV4dChpbnQgb2Zmc2V0KQotICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB3aGV0aGVyIHRoaXMgdGV4dCBub2RlIGNvbnRhaW5zIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLXhtbC1pbmZvc2V0LTIwMDQwMjA0I2luZm9pdGVtLmNoYXJhY3Rlcic+Ci0gICAgICogZWxlbWVudCBjb250ZW50IHdoaXRlc3BhY2U8L2E+LCBvZnRlbiBhYnVzaXZlbHkgY2FsbGVkICJpZ25vcmFibGUgd2hpdGVzcGFjZSIuIFRoZSB0ZXh0IG5vZGUgaXMKLSAgICAgKiBkZXRlcm1pbmVkIHRvIGNvbnRhaW4gd2hpdGVzcGFjZSBpbiBlbGVtZW50IGNvbnRlbnQgZHVyaW5nIHRoZSBsb2FkCi0gICAgICogb2YgdGhlIGRvY3VtZW50IG9yIGlmIHZhbGlkYXRpb24gb2NjdXJzIHdoaWxlIHVzaW5nCi0gICAgICogPGNvZGU+RG9jdW1lbnQubm9ybWFsaXplRG9jdW1lbnQoKTwvY29kZT4uCi0gICAgICogQHNpbmNlIERPTSBMZXZlbCAzCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNFbGVtZW50Q29udGVudFdoaXRlc3BhY2UoKTsKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYWxsIHRleHQgb2YgPGNvZGU+VGV4dDwvY29kZT4gbm9kZXMgbG9naWNhbGx5LWFkamFjZW50IHRleHQKLSAgICAgKiBub2RlcyB0byB0aGlzIG5vZGUsIGNvbmNhdGVuYXRlZCBpbiBkb2N1bWVudCBvcmRlci4KLSAgICAgKiA8YnI+Rm9yIGluc3RhbmNlLCBpbiB0aGUgZXhhbXBsZSBiZWxvdyA8Y29kZT53aG9sZVRleHQ8L2NvZGU+IG9uIHRoZQotICAgICAqIDxjb2RlPlRleHQ8L2NvZGU+IG5vZGUgdGhhdCBjb250YWlucyAiYmFyIiByZXR1cm5zICJiYXJmb28iLCB3aGlsZSBvbgotICAgICAqIHRoZSA8Y29kZT5UZXh0PC9jb2RlPiBub2RlIHRoYXQgY29udGFpbnMgImZvbyIgaXQgcmV0dXJucyAiYmFyZm9vIi4KLSAgICAgKgotICAgICAqIDxwcmU+Ci0gICAgICogICAgICAgICAgICAgICAgICAgICArLS0tLS0rCi0gICAgICogICAgICAgICAgICAgICAgICAgICB8ICZsdDtwJmd0OyB8Ci0gICAgICogICAgICAgICAgICAgICAgICAgICArLS0tLS0rCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgIC9cCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgLyAgXAotICAgICAqICAgICAgICAgICAgICAgLy0tLS0tXCAgICArLS0tLS0tLSsKLSAgICAgKiAgICAgICAgICAgICAgIHwgYmFyIHwgICAgfCAmYW1wO2VudDsgfAotICAgICAqICAgICAgICAgICAgICAgXC0tLS0tLyAgICArLS0tLS0tLSsKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIC8tLS0tLVwKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgZm9vIHwKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIFwtLS0tLS8KLSAgICAgKiA8L3ByZT4KLSAgICAgKiA8ZW0+RmlndXJlOiBiYXJUZXh0Tm9kZS53aG9sZVRleHQgdmFsdWUgaXMgImJhcmZvbyI8L2VtPgotICAgICAqCi0gICAgICogQHNpbmNlIERPTSBMZXZlbCAzCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRXaG9sZVRleHQoKTsKLQotICAgIC8qKgotICAgICAqIFJlcGxhY2VzIHRoZSB0ZXh0IG9mIHRoZSBjdXJyZW50IG5vZGUgYW5kIGFsbCBsb2dpY2FsbHktYWRqYWNlbnQgdGV4dAotICAgICAqIG5vZGVzIHdpdGggdGhlIHNwZWNpZmllZCB0ZXh0LiBBbGwgbG9naWNhbGx5LWFkamFjZW50IHRleHQgbm9kZXMgYXJlCi0gICAgICogcmVtb3ZlZCBpbmNsdWRpbmcgdGhlIGN1cnJlbnQgbm9kZSB1bmxlc3MgaXQgd2FzIHRoZSByZWNpcGllbnQgb2YgdGhlCi0gICAgICogcmVwbGFjZW1lbnQgdGV4dC4KLSAgICAgKiA8cD5UaGlzIG1ldGhvZCByZXR1cm5zIHRoZSBub2RlIHdoaWNoIHJlY2VpdmVkIHRoZSByZXBsYWNlbWVudCB0ZXh0LgotICAgICAqIFRoZSByZXR1cm5lZCBub2RlIGlzOjwvcD4KLSAgICAgKiA8dWw+Ci0gICAgICogPGxpPjxjb2RlPm51bGw8L2NvZGU+LCB3aGVuIHRoZSByZXBsYWNlbWVudCB0ZXh0IGlzCi0gICAgICogdGhlIGVtcHR5IHN0cmluZzsKLSAgICAgKiA8L2xpPgotICAgICAqIDxsaT50aGUgY3VycmVudCBub2RlLCBleGNlcHQgd2hlbiB0aGUgY3VycmVudCBub2RlIGlzCi0gICAgICogcmVhZC1vbmx5OwotICAgICAqIDwvbGk+Ci0gICAgICogPGxpPiBhIG5ldyA8Y29kZT5UZXh0PC9jb2RlPiBub2RlIG9mIHRoZSBzYW1lIHR5cGUgKAotICAgICAqIDxjb2RlPlRleHQ8L2NvZGU+IG9yIDxjb2RlPkNEQVRBU2VjdGlvbjwvY29kZT4pIGFzIHRoZSBjdXJyZW50IG5vZGUKLSAgICAgKiBpbnNlcnRlZCBhdCB0aGUgbG9jYXRpb24gb2YgdGhlIHJlcGxhY2VtZW50LgotICAgICAqIDwvbGk+Ci0gICAgICogPC91bD4KLSAgICAgKiA8cD5Gb3IgaW5zdGFuY2UsIGluIHRoZSBhYm92ZSBleGFtcGxlIGNhbGxpbmcKLSAgICAgKiA8Y29kZT5yZXBsYWNlV2hvbGVUZXh0PC9jb2RlPiBvbiB0aGUgPGNvZGU+VGV4dDwvY29kZT4gbm9kZSB0aGF0Ci0gICAgICogY29udGFpbnMgImJhciIgd2l0aCAieW8iIGluIGFyZ3VtZW50IHJlc3VsdHMgaW4gdGhlIGZvbGxvd2luZzo8L3A+Ci0gICAgICoKLSAgICAgKiA8cHJlPgotICAgICAqICAgICAgICAgICAgICAgICAgICAgKy0tLS0tKwotICAgICAqICAgICAgICAgICAgICAgICAgICAgfCAmbHQ7cCZndDsgfAotICAgICAqICAgICAgICAgICAgICAgICAgICAgKy0tLS0tKwotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgfAotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgfAotICAgICAqICAgICAgICAgICAgICAgICAgICAgLy0tLS0tXAotICAgICAqICAgICAgICAgICAgICAgICAgICAgfCB5byAgfAotICAgICAqICAgICAgICAgICAgICAgICAgICAgXC0tLS0tLwotICAgICAqIDwvcHJlPgotICAgICAqIDxlbT5GaWd1cmU6IGJhclRleHROb2RlLnJlcGxhY2VXaG9sZVRleHQoInlvIikgbW9kaWZpZXMgdGhlCi0gICAgICogdGV4dHVhbCBjb250ZW50IG9mIGJhclRleHROb2RlIHdpdGggInlvIjwvZW0+Ci0gICAgICoKLSAgICAgKiA8cD5XaGVyZSB0aGUgbm9kZXMgdG8gYmUgcmVtb3ZlZCBhcmUgcmVhZC1vbmx5IGRlc2NlbmRhbnRzIG9mIGFuCi0gICAgICogPGNvZGU+RW50aXR5UmVmZXJlbmNlPC9jb2RlPiwgdGhlIDxjb2RlPkVudGl0eVJlZmVyZW5jZTwvY29kZT4gbXVzdAotICAgICAqIGJlIHJlbW92ZWQgaW5zdGVhZCBvZiB0aGUgcmVhZC1vbmx5IG5vZGVzLiBJZiBhbnkKLSAgICAgKiA8Y29kZT5FbnRpdHlSZWZlcmVuY2U8L2NvZGU+IHRvIGJlIHJlbW92ZWQgaGFzIGRlc2NlbmRhbnRzIHRoYXQgYXJlCi0gICAgICogbm90IDxjb2RlPkVudGl0eVJlZmVyZW5jZTwvY29kZT4sIDxjb2RlPlRleHQ8L2NvZGU+LCBvcgotICAgICAqIDxjb2RlPkNEQVRBU2VjdGlvbjwvY29kZT4gbm9kZXMsIHRoZSA8Y29kZT5yZXBsYWNlV2hvbGVUZXh0PC9jb2RlPgotICAgICAqIG1ldGhvZCBtdXN0IGZhaWwgYmVmb3JlIHBlcmZvcm1pbmcgYW55IG1vZGlmaWNhdGlvbiBvZiB0aGUgZG9jdW1lbnQsCi0gICAgICogcmFpc2luZyBhIDxjb2RlPkRPTUV4Y2VwdGlvbjwvY29kZT4gd2l0aCB0aGUgY29kZQotICAgICAqIDxjb2RlPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjwvY29kZT4uPC9wPgotICAgICAqIDxwPkZvciBpbnN0YW5jZSwgaW4gdGhlIGV4YW1wbGUgYmVsb3cgY2FsbGluZwotICAgICAqIDxjb2RlPnJlcGxhY2VXaG9sZVRleHQ8L2NvZGU+IG9uIHRoZSA8Y29kZT5UZXh0PC9jb2RlPiBub2RlIHRoYXQKLSAgICAgKiBjb250YWlucyAiYmFyIiBmYWlscywgYmVjYXVzZSB0aGUgPGNvZGU+RW50aXR5UmVmZXJlbmNlPC9jb2RlPiBub2RlCi0gICAgICogImVudCIgY29udGFpbnMgYW4gPGNvZGU+RWxlbWVudDwvY29kZT4gbm9kZSB3aGljaCBjYW5ub3QgYmUgcmVtb3ZlZC48L3A+Ci0gICAgICogQHBhcmFtIGNvbnRlbnQgVGhlIGNvbnRlbnQgb2YgdGhlIHJlcGxhY2luZyA8Y29kZT5UZXh0PC9jb2RlPiBub2RlLgotICAgICAqIEByZXR1cm4gVGhlIDxjb2RlPlRleHQ8L2NvZGU+IG5vZGUgY3JlYXRlZCB3aXRoIHRoZSBzcGVjaWZpZWQgY29udGVudC4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgb25lIG9mIHRoZSA8Y29kZT5UZXh0PC9jb2RlPgotICAgICAqICAgbm9kZXMgYmVpbmcgcmVwbGFjZWQgaXMgcmVhZG9ubHkuCi0gICAgICogQHNpbmNlIERPTSBMZXZlbCAzCi0gICAgICovCi0gICAgcHVibGljIFRleHQgcmVwbGFjZVdob2xlVGV4dChTdHJpbmcgY29udGVudCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvdzNjL2RvbS9UeXBlSW5mby5qYXZhIGIvc3JjL29yZy93M2MvZG9tL1R5cGVJbmZvLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDA0NGVkZTAuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy93M2MvZG9tL1R5cGVJbmZvLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMTQgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIFRoaXMgZmlsZSBpcyBhdmFpbGFibGUgdW5kZXIgYW5kIGdvdmVybmVkIGJ5IHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKLSAqIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICogSG93ZXZlciwgdGhlIGZvbGxvd2luZyBub3RpY2UgYWNjb21wYW5pZWQgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcwotICogZmlsZSBhbmQsIHBlciBpdHMgdGVybXMsIHNob3VsZCBub3QgYmUgcmVtb3ZlZDoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKLSAqCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgRXVyb3BlYW4gUmVzZWFyY2ggQ29uc29ydGl1bSBmb3IKLSAqIEluZm9ybWF0aWNzIGFuZCBNYXRoZW1hdGljcywgS2VpbyBVbml2ZXJzaXR5KS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcwotICogd29yayBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDKHIpIFNvZnR3YXJlIExpY2Vuc2UgWzFdIGluIHRoZSBob3BlIHRoYXQKLSAqIGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZAotICogd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLgotICoKLSAqIFsxXSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLzIwMDIvY29weXJpZ2h0LXNvZnR3YXJlLTIwMDIxMjMxCi0gKi8KLQotcGFja2FnZSBvcmcudzNjLmRvbTsKLQotLyoqCi0gKiAgVGhlIDxjb2RlPlR5cGVJbmZvPC9jb2RlPiBpbnRlcmZhY2UgcmVwcmVzZW50cyBhIHR5cGUgcmVmZXJlbmNlZCBmcm9tCi0gKiA8Y29kZT5FbGVtZW50PC9jb2RlPiBvciA8Y29kZT5BdHRyPC9jb2RlPiBub2Rlcywgc3BlY2lmaWVkIGluIHRoZSBzY2hlbWFzCi0gKiBhc3NvY2lhdGVkIHdpdGggdGhlIGRvY3VtZW50LiBUaGUgdHlwZSBpcyBhIHBhaXIgb2YgYSBuYW1lc3BhY2UgVVJJIGFuZAotICogbmFtZSBwcm9wZXJ0aWVzLCBhbmQgZGVwZW5kcyBvbiB0aGUgZG9jdW1lbnQncyBzY2hlbWEuCi0gKiA8cD4gSWYgdGhlIGRvY3VtZW50J3Mgc2NoZW1hIGlzIGFuIFhNTCBEVEQgWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLXhtbC0yMDA0MDIwNCc+WE1MIDEuMDwvYT5dLCB0aGUgdmFsdWVzCi0gKiBhcmUgY29tcHV0ZWQgYXMgZm9sbG93czoKLSAqIDx1bD4KLSAqIDxsaT4gSWYgdGhpcyB0eXBlIGlzIHJlZmVyZW5jZWQgZnJvbSBhbgotICogPGNvZGU+QXR0cjwvY29kZT4gbm9kZSwgPGNvZGU+dHlwZU5hbWVzcGFjZTwvY29kZT4gaXMKLSAqIDxjb2RlPiJodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMteG1sIjwvY29kZT4gYW5kIDxjb2RlPnR5cGVOYW1lPC9jb2RlPgotICogcmVwcmVzZW50cyB0aGUgPGI+W2F0dHJpYnV0ZSB0eXBlXTwvYj4gcHJvcGVydHkgaW4gdGhlIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy14bWwtaW5mb3NldC0yMDA0MDIwNC8nPlhNTCBJbmZvcm1hdGlvbiBTZXQ8L2E+XQotICogLiBJZiB0aGVyZSBpcyBubyBkZWNsYXJhdGlvbiBmb3IgdGhlIGF0dHJpYnV0ZSwgPGNvZGU+dHlwZU5hbWVzcGFjZTwvY29kZT4KLSAqICBhbmQgPGNvZGU+dHlwZU5hbWU8L2NvZGU+IGFyZSA8Y29kZT5udWxsPC9jb2RlPi4KLSAqIDwvbGk+Ci0gKiA8bGk+IElmIHRoaXMgdHlwZSBpcwotICogcmVmZXJlbmNlZCBmcm9tIGFuIDxjb2RlPkVsZW1lbnQ8L2NvZGU+IG5vZGUsIDxjb2RlPnR5cGVOYW1lc3BhY2U8L2NvZGU+Ci0gKiBhbmQgPGNvZGU+dHlwZU5hbWU8L2NvZGU+IGFyZSA8Y29kZT5udWxsPC9jb2RlPi4KLSAqIDwvbGk+Ci0gKiA8L3VsPgotICogPHA+IElmIHRoZSBkb2N1bWVudCdzIHNjaGVtYSBpcyBhbiBYTUwgU2NoZW1hIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAxL1JFQy14bWxzY2hlbWEtMS0yMDAxMDUwMi8nPlhNTCBTY2hlbWEgUGFydCAxPC9hPl0KLSAqICwgdGhlIHZhbHVlcyBhcmUgY29tcHV0ZWQgYXMgZm9sbG93cyB1c2luZyB0aGUgcG9zdC1zY2hlbWEtdmFsaWRhdGlvbgotICogaW5mb3NldCBjb250cmlidXRpb25zIChhbHNvIGNhbGxlZCBQU1ZJIGNvbnRyaWJ1dGlvbnMpOgotICogPHVsPgotICogPGxpPiBJZiB0aGUgPGI+W3ZhbGlkaXR5XTwvYj4gcHJvcGVydHkgZXhpc3RzIEFORCBpcyA8ZW0+ImludmFsaWQiPC9lbT4gb3IgPGVtPiJub3RLbm93biI8L2VtPjogdGhlIHt0YXJnZXQgbmFtZXNwYWNlfSBhbmQge25hbWV9IHByb3BlcnRpZXMgb2YgdGhlIGRlY2xhcmVkIHR5cGUgaWYKLSAqIGF2YWlsYWJsZSwgb3RoZXJ3aXNlIDxjb2RlPm51bGw8L2NvZGU+LgotICogPHAgPjxiPk5vdGU6PC9iPiAgQXQgdGhlIHRpbWUgb2Ygd3JpdGluZywgdGhlIFhNTCBTY2hlbWEgc3BlY2lmaWNhdGlvbiBkb2VzCi0gKiBub3QgcmVxdWlyZSBleHBvc2luZyB0aGUgZGVjbGFyZWQgdHlwZS4gVGh1cywgRE9NIGltcGxlbWVudGF0aW9ucyBtaWdodAotICogY2hvb3NlIG5vdCB0byBwcm92aWRlIHR5cGUgaW5mb3JtYXRpb24gaWYgdmFsaWRpdHkgaXMgbm90IHZhbGlkLgotICogPC9saT4KLSAqIDxsaT4gSWYgdGhlIDxiPlt2YWxpZGl0eV08L2I+IHByb3BlcnR5IGV4aXN0cyBhbmQgaXMgPGVtPiJ2YWxpZCI8L2VtPjoKLSAqIDxvbD4KLSAqIDxsaT4gSWYgPGI+W21lbWJlciB0eXBlIGRlZmluaXRpb25dPC9iPiBleGlzdHM6Ci0gKiA8b2w+Ci0gKiA8bGk+SWYge25hbWV9IGlzIG5vdCBhYnNlbnQsIHRoZW4gZXhwb3NlIHtuYW1lfSBhbmQge3RhcmdldAotICogbmFtZXNwYWNlfSBwcm9wZXJ0aWVzIG9mIHRoZSA8Yj5bbWVtYmVyIHR5cGUgZGVmaW5pdGlvbl08L2I+IHByb3BlcnR5OwotICogPC9saT4KLSAqIDxsaT5PdGhlcndpc2UsIGV4cG9zZSB0aGUgbmFtZXNwYWNlIGFuZCBsb2NhbCBuYW1lIG9mIHRoZQotICogY29ycmVzcG9uZGluZyBhbm9ueW1vdXMgdHlwZSBuYW1lLgotICogPC9saT4KLSAqIDwvb2w+Ci0gKiA8L2xpPgotICogPGxpPiBJZiB0aGUgPGI+W3R5cGUgZGVmaW5pdGlvbl08L2I+IHByb3BlcnR5IGV4aXN0czoKLSAqIDxvbD4KLSAqIDxsaT5JZiB7bmFtZX0gaXMgbm90IGFic2VudCwgdGhlbiBleHBvc2Uge25hbWV9IGFuZCB7dGFyZ2V0Ci0gKiBuYW1lc3BhY2V9IHByb3BlcnRpZXMgb2YgdGhlIDxiPlt0eXBlIGRlZmluaXRpb25dPC9iPiBwcm9wZXJ0eTsKLSAqIDwvbGk+Ci0gKiA8bGk+T3RoZXJ3aXNlLCBleHBvc2UgdGhlIG5hbWVzcGFjZSBhbmQgbG9jYWwgbmFtZSBvZiB0aGUKLSAqIGNvcnJlc3BvbmRpbmcgYW5vbnltb3VzIHR5cGUgbmFtZS4KLSAqIDwvbGk+Ci0gKiA8L29sPgotICogPC9saT4KLSAqIDxsaT4gSWYgdGhlIDxiPlttZW1iZXIgdHlwZSBkZWZpbml0aW9uIGFub255bW91c108L2I+IGV4aXN0czoKLSAqIDxvbD4KLSAqIDxsaT5JZiBpdCBpcyBmYWxzZSwgdGhlbiBleHBvc2UgPGI+W21lbWJlciB0eXBlIGRlZmluaXRpb24gbmFtZV08L2I+IGFuZCA8Yj5bbWVtYmVyIHR5cGUgZGVmaW5pdGlvbiBuYW1lc3BhY2VdPC9iPiBwcm9wZXJ0aWVzOwotICogPC9saT4KLSAqIDxsaT5PdGhlcndpc2UsIGV4cG9zZSB0aGUgbmFtZXNwYWNlIGFuZCBsb2NhbCBuYW1lIG9mIHRoZQotICogY29ycmVzcG9uZGluZyBhbm9ueW1vdXMgdHlwZSBuYW1lLgotICogPC9saT4KLSAqIDwvb2w+Ci0gKiA8L2xpPgotICogPGxpPiBJZiB0aGUgPGI+W3R5cGUgZGVmaW5pdGlvbiBhbm9ueW1vdXNdPC9iPiBleGlzdHM6Ci0gKiA8b2w+Ci0gKiA8bGk+SWYgaXQgaXMgZmFsc2UsIHRoZW4gZXhwb3NlIDxiPlt0eXBlIGRlZmluaXRpb24gbmFtZV08L2I+IGFuZCA8Yj5bdHlwZSBkZWZpbml0aW9uIG5hbWVzcGFjZV08L2I+IHByb3BlcnRpZXM7Ci0gKiA8L2xpPgotICogPGxpPk90aGVyd2lzZSwgZXhwb3NlIHRoZSBuYW1lc3BhY2UgYW5kIGxvY2FsIG5hbWUgb2YgdGhlCi0gKiBjb3JyZXNwb25kaW5nIGFub255bW91cyB0eXBlIG5hbWUuCi0gKiA8L2xpPgotICogPC9vbD4KLSAqIDwvbGk+Ci0gKiA8L29sPgotICogPC9saT4KLSAqIDwvdWw+Ci0gKiA8cCA+PGI+Tm90ZTo8L2I+ICBPdGhlciBzY2hlbWEgbGFuZ3VhZ2VzIGFyZSBvdXRzaWRlIHRoZSBzY29wZSBvZiB0aGUgVzNDCi0gKiBhbmQgdGhlcmVmb3JlIHNob3VsZCBkZWZpbmUgaG93IHRvIHJlcHJlc2VudCB0aGVpciB0eXBlIHN5c3RlbXMgdXNpbmcKLSAqIDxjb2RlPlR5cGVJbmZvPC9jb2RlPi4KLSAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy1ET00tTGV2ZWwtMy1Db3JlLTIwMDQwNDA3Jz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMyBDb3JlIFNwZWNpZmljYXRpb248L2E+LgotICogQHNpbmNlIERPTSBMZXZlbCAzCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgVHlwZUluZm8gewotICAgIC8qKgotICAgICAqICBUaGUgbmFtZSBvZiBhIHR5cGUgZGVjbGFyZWQgZm9yIHRoZSBhc3NvY2lhdGVkIGVsZW1lbnQgb3IgYXR0cmlidXRlLAotICAgICAqIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIHVua25vd24uCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRUeXBlTmFtZSgpOwotCi0gICAgLyoqCi0gICAgICogIFRoZSBuYW1lc3BhY2Ugb2YgdGhlIHR5cGUgZGVjbGFyZWQgZm9yIHRoZSBhc3NvY2lhdGVkIGVsZW1lbnQgb3IKLSAgICAgKiBhdHRyaWJ1dGUgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlIGVsZW1lbnQgZG9lcyBub3QgaGF2ZQotICAgICAqIGRlY2xhcmF0aW9uIG9yIGlmIG5vIG5hbWVzcGFjZSBpbmZvcm1hdGlvbiBpcyBhdmFpbGFibGUuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRUeXBlTmFtZXNwYWNlKCk7Ci0KLSAgICAvLyBEZXJpdmF0aW9uTWV0aG9kcwotICAgIC8qKgotICAgICAqICBJZiB0aGUgZG9jdW1lbnQncyBzY2hlbWEgaXMgYW4gWE1MIFNjaGVtYSBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMS9SRUMteG1sc2NoZW1hLTEtMjAwMTA1MDIvJz5YTUwgU2NoZW1hIFBhcnQgMTwvYT5dCi0gICAgICogLCB0aGlzIGNvbnN0YW50IHJlcHJlc2VudHMgdGhlIGRlcml2YXRpb24gYnkgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMS9SRUMteG1sc2NoZW1hLTEtMjAwMTA1MDIvI2tleS10eXBlUmVzdHJpY3Rpb24nPgotICAgICAqIHJlc3RyaWN0aW9uPC9hPiBpZiBjb21wbGV4IHR5cGVzIGFyZSBpbnZvbHZlZCwgb3IgYSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAxL1JFQy14bWxzY2hlbWEtMS0yMDAxMDUwMi8jZWxlbWVudC1yZXN0cmljdGlvbic+Ci0gICAgICogcmVzdHJpY3Rpb248L2E+IGlmIHNpbXBsZSB0eXBlcyBhcmUgaW52b2x2ZWQuCi0gICAgICogPGJyPiAgVGhlIHJlZmVyZW5jZSB0eXBlIGRlZmluaXRpb24gaXMgZGVyaXZlZCBieSByZXN0cmljdGlvbiBmcm9tIHRoZQotICAgICAqIG90aGVyIHR5cGUgZGVmaW5pdGlvbiBpZiB0aGUgb3RoZXIgdHlwZSBkZWZpbml0aW9uIGlzIHRoZSBzYW1lIGFzIHRoZQotICAgICAqIHJlZmVyZW5jZSB0eXBlIGRlZmluaXRpb24sIG9yIGlmIHRoZSBvdGhlciB0eXBlIGRlZmluaXRpb24gY2FuIGJlCi0gICAgICogcmVhY2hlZCByZWN1cnNpdmVseSBmb2xsb3dpbmcgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gcHJvcGVydHkKLSAgICAgKiBmcm9tIHRoZSByZWZlcmVuY2UgdHlwZSBkZWZpbml0aW9uLCBhbmQgYWxsIHRoZSA8ZW0+ZGVyaXZhdGlvbiBtZXRob2RzPC9lbT4gaW52b2x2ZWQgYXJlIHJlc3RyaWN0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFUklWQVRJT05fUkVTVFJJQ1RJT04gICAgPSAweDAwMDAwMDAxOwotICAgIC8qKgotICAgICAqICBJZiB0aGUgZG9jdW1lbnQncyBzY2hlbWEgaXMgYW4gWE1MIFNjaGVtYSBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMS9SRUMteG1sc2NoZW1hLTEtMjAwMTA1MDIvJz5YTUwgU2NoZW1hIFBhcnQgMTwvYT5dCi0gICAgICogLCB0aGlzIGNvbnN0YW50IHJlcHJlc2VudHMgdGhlIGRlcml2YXRpb24gYnkgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMS9SRUMteG1sc2NoZW1hLTEtMjAwMTA1MDIvI2tleS10eXBlRXh0ZW5zaW9uJz4KLSAgICAgKiBleHRlbnNpb248L2E+LgotICAgICAqIDxicj4gIFRoZSByZWZlcmVuY2UgdHlwZSBkZWZpbml0aW9uIGlzIGRlcml2ZWQgYnkgZXh0ZW5zaW9uIGZyb20gdGhlCi0gICAgICogb3RoZXIgdHlwZSBkZWZpbml0aW9uIGlmIHRoZSBvdGhlciB0eXBlIGRlZmluaXRpb24gY2FuIGJlIHJlYWNoZWQKLSAgICAgKiByZWN1cnNpdmVseSBmb2xsb3dpbmcgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gcHJvcGVydHkgZnJvbSB0aGUKLSAgICAgKiByZWZlcmVuY2UgdHlwZSBkZWZpbml0aW9uLCBhbmQgYXQgbGVhc3Qgb25lIG9mIHRoZSA8ZW0+ZGVyaXZhdGlvbiBtZXRob2RzPC9lbT4gaW52b2x2ZWQgaXMgYW4gZXh0ZW5zaW9uLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFUklWQVRJT05fRVhURU5TSU9OICAgICAgPSAweDAwMDAwMDAyOwotICAgIC8qKgotICAgICAqICBJZiB0aGUgZG9jdW1lbnQncyBzY2hlbWEgaXMgYW4gWE1MIFNjaGVtYSBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMS9SRUMteG1sc2NoZW1hLTEtMjAwMTA1MDIvJz5YTUwgU2NoZW1hIFBhcnQgMTwvYT5dCi0gICAgICogLCB0aGlzIGNvbnN0YW50IHJlcHJlc2VudHMgdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDEvUkVDLXhtbHNjaGVtYS0xLTIwMDEwNTAyLyNlbGVtZW50LXVuaW9uJz4KLSAgICAgKiB1bmlvbjwvYT4gaWYgc2ltcGxlIHR5cGVzIGFyZSBpbnZvbHZlZC4KLSAgICAgKiA8YnI+IFRoZSByZWZlcmVuY2UgdHlwZSBkZWZpbml0aW9uIGlzIGRlcml2ZWQgYnkgdW5pb24gZnJvbSB0aGUgb3RoZXIKLSAgICAgKiB0eXBlIGRlZmluaXRpb24gaWYgdGhlcmUgZXhpc3RzIHR3byB0eXBlIGRlZmluaXRpb25zIFQxIGFuZCBUMiBzdWNoCi0gICAgICogYXMgdGhlIHJlZmVyZW5jZSB0eXBlIGRlZmluaXRpb24gaXMgZGVyaXZlZCBmcm9tIFQxIGJ5Ci0gICAgICogPGNvZGU+REVSSVZBVElPTl9SRVNUUklDVElPTjwvY29kZT4gb3IKLSAgICAgKiA8Y29kZT5ERVJJVkFUSU9OX0VYVEVOU0lPTjwvY29kZT4sIFQyIGlzIGRlcml2ZWQgZnJvbSB0aGUgb3RoZXIgdHlwZQotICAgICAqIGRlZmluaXRpb24gYnkgPGNvZGU+REVSSVZBVElPTl9SRVNUUklDVElPTjwvY29kZT4sIFQxIGhhcyB7dmFyaWV0eX0gPGVtPnVuaW9uPC9lbT4sIGFuZCBvbmUgb2YgdGhlIHttZW1iZXIgdHlwZSBkZWZpbml0aW9uc30gaXMgVDIuIE5vdGUgdGhhdCBUMSBjb3VsZCBiZQotICAgICAqIHRoZSBzYW1lIGFzIHRoZSByZWZlcmVuY2UgdHlwZSBkZWZpbml0aW9uLCBhbmQgVDIgY291bGQgYmUgdGhlIHNhbWUKLSAgICAgKiBhcyB0aGUgb3RoZXIgdHlwZSBkZWZpbml0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFUklWQVRJT05fVU5JT04gICAgICAgICAgPSAweDAwMDAwMDA0OwotICAgIC8qKgotICAgICAqICBJZiB0aGUgZG9jdW1lbnQncyBzY2hlbWEgaXMgYW4gWE1MIFNjaGVtYSBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMS9SRUMteG1sc2NoZW1hLTEtMjAwMTA1MDIvJz5YTUwgU2NoZW1hIFBhcnQgMTwvYT5dCi0gICAgICogLCB0aGlzIGNvbnN0YW50IHJlcHJlc2VudHMgdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDEvUkVDLXhtbHNjaGVtYS0xLTIwMDEwNTAyLyNlbGVtZW50LWxpc3QnPmxpc3Q8L2E+LgotICAgICAqIDxicj4gVGhlIHJlZmVyZW5jZSB0eXBlIGRlZmluaXRpb24gaXMgZGVyaXZlZCBieSBsaXN0IGZyb20gdGhlIG90aGVyCi0gICAgICogdHlwZSBkZWZpbml0aW9uIGlmIHRoZXJlIGV4aXN0cyB0d28gdHlwZSBkZWZpbml0aW9ucyBUMSBhbmQgVDIgc3VjaAotICAgICAqIGFzIHRoZSByZWZlcmVuY2UgdHlwZSBkZWZpbml0aW9uIGlzIGRlcml2ZWQgZnJvbSBUMSBieQotICAgICAqIDxjb2RlPkRFUklWQVRJT05fUkVTVFJJQ1RJT048L2NvZGU+IG9yCi0gICAgICogPGNvZGU+REVSSVZBVElPTl9FWFRFTlNJT048L2NvZGU+LCBUMiBpcyBkZXJpdmVkIGZyb20gdGhlIG90aGVyIHR5cGUKLSAgICAgKiBkZWZpbml0aW9uIGJ5IDxjb2RlPkRFUklWQVRJT05fUkVTVFJJQ1RJT048L2NvZGU+LCBUMSBoYXMge3ZhcmlldHl9IDxlbT5saXN0PC9lbT4sIGFuZCBUMiBpcyB0aGUge2l0ZW0gdHlwZSBkZWZpbml0aW9ufS4gTm90ZSB0aGF0IFQxIGNvdWxkIGJlIHRoZSBzYW1lIGFzCi0gICAgICogdGhlIHJlZmVyZW5jZSB0eXBlIGRlZmluaXRpb24sIGFuZCBUMiBjb3VsZCBiZSB0aGUgc2FtZSBhcyB0aGUgb3RoZXIKLSAgICAgKiB0eXBlIGRlZmluaXRpb24uCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgREVSSVZBVElPTl9MSVNUICAgICAgICAgICA9IDB4MDAwMDAwMDg7Ci0KLSAgICAvKioKLSAgICAgKiAgVGhpcyBtZXRob2QgcmV0dXJucyBpZiB0aGVyZSBpcyBhIGRlcml2YXRpb24gYmV0d2VlbiB0aGUgcmVmZXJlbmNlCi0gICAgICogdHlwZSBkZWZpbml0aW9uLCBpLmUuIHRoZSA8Y29kZT5UeXBlSW5mbzwvY29kZT4gb24gd2hpY2ggdGhlIG1ldGhvZAotICAgICAqIGlzIGJlaW5nIGNhbGxlZCwgYW5kIHRoZSBvdGhlciB0eXBlIGRlZmluaXRpb24sIGkuZS4gdGhlIG9uZSBwYXNzZWQKLSAgICAgKiBhcyBwYXJhbWV0ZXJzLgotICAgICAqIEBwYXJhbSB0eXBlTmFtZXNwYWNlQXJnICB0aGUgbmFtZXNwYWNlIG9mIHRoZSBvdGhlciB0eXBlIGRlZmluaXRpb24uCi0gICAgICogQHBhcmFtIHR5cGVOYW1lQXJnICB0aGUgbmFtZSBvZiB0aGUgb3RoZXIgdHlwZSBkZWZpbml0aW9uLgotICAgICAqIEBwYXJhbSBkZXJpdmF0aW9uTWV0aG9kICB0aGUgdHlwZSBvZiBkZXJpdmF0aW9uIGFuZCBjb25kaXRpb25zIGFwcGxpZWQKLSAgICAgKiAgIGJldHdlZW4gdHdvIHR5cGVzLCBhcyBkZXNjcmliZWQgaW4gdGhlIGxpc3Qgb2YgY29uc3RhbnRzIHByb3ZpZGVkCi0gICAgICogICBpbiB0aGlzIGludGVyZmFjZS4KLSAgICAgKiBAcmV0dXJuICBJZiB0aGUgZG9jdW1lbnQncyBzY2hlbWEgaXMgYSBEVEQgb3Igbm8gc2NoZW1hIGlzIGFzc29jaWF0ZWQKLSAgICAgKiAgIHdpdGggdGhlIGRvY3VtZW50LCB0aGlzIG1ldGhvZCB3aWxsIGFsd2F5cyByZXR1cm4gPGNvZGU+ZmFsc2U8L2NvZGU+Ci0gICAgICogICAuICBJZiB0aGUgZG9jdW1lbnQncyBzY2hlbWEgaXMgYW4gWE1MIFNjaGVtYSwgdGhlIG1ldGhvZCB3aWxsIHJldHVybgotICAgICAqICAgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIHJlZmVyZW5jZSB0eXBlIGRlZmluaXRpb24gaXMgZGVyaXZlZCBmcm9tCi0gICAgICogICB0aGUgb3RoZXIgdHlwZSBkZWZpbml0aW9uIGFjY29yZGluZyB0byB0aGUgZGVyaXZhdGlvbiBwYXJhbWV0ZXIuIElmCi0gICAgICogICB0aGUgdmFsdWUgb2YgdGhlIHBhcmFtZXRlciBpcyA8Y29kZT4wPC9jb2RlPiAobm8gYml0IGlzIHNldCB0bwotICAgICAqICAgPGNvZGU+MTwvY29kZT4gZm9yIHRoZSA8Y29kZT5kZXJpdmF0aW9uTWV0aG9kPC9jb2RlPiBwYXJhbWV0ZXIpLAotICAgICAqICAgdGhlIG1ldGhvZCB3aWxsIHJldHVybiA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgb3RoZXIgdHlwZQotICAgICAqICAgZGVmaW5pdGlvbiBjYW4gYmUgcmVhY2hlZCBieSByZWN1cnNpbmcgYW55IGNvbWJpbmF0aW9uIG9mIHtiYXNlCi0gICAgICogICB0eXBlIGRlZmluaXRpb259LCB7aXRlbSB0eXBlIGRlZmluaXRpb259LCBvciB7bWVtYmVyIHR5cGUKLSAgICAgKiAgIGRlZmluaXRpb25zfSBmcm9tIHRoZSByZWZlcmVuY2UgdHlwZSBkZWZpbml0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzRGVyaXZlZEZyb20oU3RyaW5nIHR5cGVOYW1lc3BhY2VBcmcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdHlwZU5hbWVBcmcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgZGVyaXZhdGlvbk1ldGhvZCk7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvdzNjL2RvbS9Vc2VyRGF0YUhhbmRsZXIuamF2YSBiL3NyYy9vcmcvdzNjL2RvbS9Vc2VyRGF0YUhhbmRsZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYTRlYzZlOC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3czYy9kb20vVXNlckRhdGFIYW5kbGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMDEgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIFRoaXMgZmlsZSBpcyBhdmFpbGFibGUgdW5kZXIgYW5kIGdvdmVybmVkIGJ5IHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKLSAqIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICogSG93ZXZlciwgdGhlIGZvbGxvd2luZyBub3RpY2UgYWNjb21wYW5pZWQgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcwotICogZmlsZSBhbmQsIHBlciBpdHMgdGVybXMsIHNob3VsZCBub3QgYmUgcmVtb3ZlZDoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKLSAqCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgRXVyb3BlYW4gUmVzZWFyY2ggQ29uc29ydGl1bSBmb3IKLSAqIEluZm9ybWF0aWNzIGFuZCBNYXRoZW1hdGljcywgS2VpbyBVbml2ZXJzaXR5KS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcwotICogd29yayBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDKHIpIFNvZnR3YXJlIExpY2Vuc2UgWzFdIGluIHRoZSBob3BlIHRoYXQKLSAqIGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZAotICogd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLgotICoKLSAqIFsxXSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLzIwMDIvY29weXJpZ2h0LXNvZnR3YXJlLTIwMDIxMjMxCi0gKi8KLQotcGFja2FnZSBvcmcudzNjLmRvbTsKLQotLyoqCi0gKiBXaGVuIGFzc29jaWF0aW5nIGFuIG9iamVjdCB0byBhIGtleSBvbiBhIG5vZGUgdXNpbmcKLSAqIDxjb2RlPk5vZGUuc2V0VXNlckRhdGEoKTwvY29kZT4gdGhlIGFwcGxpY2F0aW9uIGNhbiBwcm92aWRlIGEgaGFuZGxlcgotICogdGhhdCBnZXRzIGNhbGxlZCB3aGVuIHRoZSBub2RlIHRoZSBvYmplY3QgaXMgYXNzb2NpYXRlZCB0byBpcyBiZWluZwotICogY2xvbmVkLCBpbXBvcnRlZCwgb3IgcmVuYW1lZC4gVGhpcyBjYW4gYmUgdXNlZCBieSB0aGUgYXBwbGljYXRpb24gdG8KLSAqIGltcGxlbWVudCB2YXJpb3VzIGJlaGF2aW9ycyByZWdhcmRpbmcgdGhlIGRhdGEgaXQgYXNzb2NpYXRlcyB0byB0aGUgRE9NCi0gKiBub2Rlcy4gVGhpcyBpbnRlcmZhY2UgZGVmaW5lcyB0aGF0IGhhbmRsZXIuCi0gKiA8cD5TZWUgYWxzbyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMtRE9NLUxldmVsLTMtQ29yZS0yMDA0MDQwNyc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDMgQ29yZSBTcGVjaWZpY2F0aW9uPC9hPi4KLSAqIEBzaW5jZSBET00gTGV2ZWwgMwotICovCi1wdWJsaWMgaW50ZXJmYWNlIFVzZXJEYXRhSGFuZGxlciB7Ci0gICAgLy8gT3BlcmF0aW9uVHlwZQotICAgIC8qKgotICAgICAqIFRoZSBub2RlIGlzIGNsb25lZCwgdXNpbmcgPGNvZGU+Tm9kZS5jbG9uZU5vZGUoKTwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBOT0RFX0NMT05FRCAgICAgICAgICAgICAgID0gMTsKLSAgICAvKioKLSAgICAgKiBUaGUgbm9kZSBpcyBpbXBvcnRlZCwgdXNpbmcgPGNvZGU+RG9jdW1lbnQuaW1wb3J0Tm9kZSgpPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IE5PREVfSU1QT1JURUQgICAgICAgICAgICAgPSAyOwotICAgIC8qKgotICAgICAqIFRoZSBub2RlIGlzIGRlbGV0ZWQuCi0gICAgICogPHAgPjxiPk5vdGU6PC9iPiBUaGlzIG1heSBub3QgYmUgc3VwcG9ydGVkIG9yIG1heSBub3QgYmUgcmVsaWFibGUgaW4KLSAgICAgKiBjZXJ0YWluIGVudmlyb25tZW50cywgc3VjaCBhcyBKYXZhLCB3aGVyZSB0aGUgaW1wbGVtZW50YXRpb24gaGFzIG5vCi0gICAgICogcmVhbCBjb250cm9sIG92ZXIgd2hlbiBvYmplY3RzIGFyZSBhY3R1YWxseSBkZWxldGVkLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgTk9ERV9ERUxFVEVEICAgICAgICAgICAgICA9IDM7Ci0gICAgLyoqCi0gICAgICogVGhlIG5vZGUgaXMgcmVuYW1lZCwgdXNpbmcgPGNvZGU+RG9jdW1lbnQucmVuYW1lTm9kZSgpPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IE5PREVfUkVOQU1FRCAgICAgICAgICAgICAgPSA0OwotICAgIC8qKgotICAgICAqIFRoZSBub2RlIGlzIGFkb3B0ZWQsIHVzaW5nIDxjb2RlPkRvY3VtZW50LmFkb3B0Tm9kZSgpPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IE5PREVfQURPUFRFRCAgICAgICAgICAgICAgPSA1OwotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIHdoZW5ldmVyIHRoZSBub2RlIGZvciB3aGljaCB0aGlzIGhhbmRsZXIgaXMKLSAgICAgKiByZWdpc3RlcmVkIGlzIGltcG9ydGVkIG9yIGNsb25lZC4KLSAgICAgKiA8YnI+IERPTSBhcHBsaWNhdGlvbnMgbXVzdCBub3QgcmFpc2UgZXhjZXB0aW9ucyBpbiBhCi0gICAgICogPGNvZGU+VXNlckRhdGFIYW5kbGVyPC9jb2RlPi4gVGhlIGVmZmVjdCBvZiB0aHJvd2luZyBleGNlcHRpb25zIGZyb20KLSAgICAgKiB0aGUgaGFuZGxlciBpcyBET00gaW1wbGVtZW50YXRpb24gZGVwZW5kZW50LgotICAgICAqIEBwYXJhbSBvcGVyYXRpb24gU3BlY2lmaWVzIHRoZSB0eXBlIG9mIG9wZXJhdGlvbiB0aGF0IGlzIGJlaW5nCi0gICAgICogICBwZXJmb3JtZWQgb24gdGhlIG5vZGUuCi0gICAgICogQHBhcmFtIGtleSBTcGVjaWZpZXMgdGhlIGtleSBmb3Igd2hpY2ggdGhpcyBoYW5kbGVyIGlzIGJlaW5nIGNhbGxlZC4KLSAgICAgKiBAcGFyYW0gZGF0YSBTcGVjaWZpZXMgdGhlIGRhdGEgZm9yIHdoaWNoIHRoaXMgaGFuZGxlciBpcyBiZWluZyBjYWxsZWQuCi0gICAgICogQHBhcmFtIHNyYyBTcGVjaWZpZXMgdGhlIG5vZGUgYmVpbmcgY2xvbmVkLCBhZG9wdGVkLCBpbXBvcnRlZCwgb3IKLSAgICAgKiAgIHJlbmFtZWQuIFRoaXMgaXMgPGNvZGU+bnVsbDwvY29kZT4gd2hlbiB0aGUgbm9kZSBpcyBiZWluZyBkZWxldGVkLgotICAgICAqIEBwYXJhbSBkc3QgU3BlY2lmaWVzIHRoZSBub2RlIG5ld2x5IGNyZWF0ZWQgaWYgYW55LCBvcgotICAgICAqICAgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgaGFuZGxlKHNob3J0IG9wZXJhdGlvbiwKLSAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGtleSwKLSAgICAgICAgICAgICAgICAgICAgICAgT2JqZWN0IGRhdGEsCi0gICAgICAgICAgICAgICAgICAgICAgIE5vZGUgc3JjLAotICAgICAgICAgICAgICAgICAgICAgICBOb2RlIGRzdCk7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvdzNjL2RvbS9ib290c3RyYXAvRE9NSW1wbGVtZW50YXRpb25SZWdpc3RyeS5qYXZhIGIvc3JjL29yZy93M2MvZG9tL2Jvb3RzdHJhcC9ET01JbXBsZW1lbnRhdGlvblJlZ2lzdHJ5LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGNmZWVlZWEuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy93M2MvZG9tL2Jvb3RzdHJhcC9ET01JbXBsZW1lbnRhdGlvblJlZ2lzdHJ5LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0MjkgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIFRoaXMgZmlsZSBpcyBhdmFpbGFibGUgdW5kZXIgYW5kIGdvdmVybmVkIGJ5IHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKLSAqIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICogSG93ZXZlciwgdGhlIGZvbGxvd2luZyBub3RpY2UgYWNjb21wYW5pZWQgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcwotICogZmlsZSBhbmQsIHBlciBpdHMgdGVybXMsIHNob3VsZCBub3QgYmUgcmVtb3ZlZDoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKLSAqCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgRXVyb3BlYW4gUmVzZWFyY2ggQ29uc29ydGl1bSBmb3IKLSAqIEluZm9ybWF0aWNzIGFuZCBNYXRoZW1hdGljcywgS2VpbyBVbml2ZXJzaXR5KS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcwotICogd29yayBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDKHIpIFNvZnR3YXJlIExpY2Vuc2UgWzFdIGluIHRoZSBob3BlIHRoYXQKLSAqIGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZAotICogd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLgotICoKLSAqIFsxXSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLzIwMDIvY29weXJpZ2h0LXNvZnR3YXJlLTIwMDIxMjMxCi0gKi8KLQotCi1wYWNrYWdlIG9yZy53M2MuZG9tLmJvb3RzdHJhcDsKLQotaW1wb3J0IGphdmEudXRpbC5TdHJpbmdUb2tlbml6ZXI7Ci1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLWltcG9ydCBvcmcudzNjLmRvbS5ET01JbXBsZW1lbnRhdGlvblNvdXJjZTsKLWltcG9ydCBvcmcudzNjLmRvbS5ET01JbXBsZW1lbnRhdGlvbkxpc3Q7Ci1pbXBvcnQgb3JnLnczYy5kb20uRE9NSW1wbGVtZW50YXRpb247Ci1pbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKLWltcG9ydCBqYXZhLmlvLkJ1ZmZlcmVkUmVhZGVyOwotaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW1SZWFkZXI7Ci1pbXBvcnQgamF2YS5zZWN1cml0eS5BY2Nlc3NDb250cm9sbGVyOwotaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpdmlsZWdlZEFjdGlvbjsKLQotLyoqCi0gKiBBIGZhY3RvcnkgdGhhdCBlbmFibGVzIGFwcGxpY2F0aW9ucyB0byBvYnRhaW4gaW5zdGFuY2VzIG9mCi0gKiA8Y29kZT5ET01JbXBsZW1lbnRhdGlvbjwvY29kZT4uCi0gKgotICogPHA+Ci0gKiBFeGFtcGxlOgotICogPC9wPgotICoKLSAqIDxwcmUgY2xhc3M9J2V4YW1wbGUnPgotICogIC8vIGdldCBhbiBpbnN0YW5jZSBvZiB0aGUgRE9NSW1wbGVtZW50YXRpb24gcmVnaXN0cnkKLSAqICBET01JbXBsZW1lbnRhdGlvblJlZ2lzdHJ5IHJlZ2lzdHJ5ID0KLSAqICAgICAgIERPTUltcGxlbWVudGF0aW9uUmVnaXN0cnkubmV3SW5zdGFuY2UoKTsKLSAqICAvLyBnZXQgYSBET00gaW1wbGVtZW50YXRpb24gdGhlIExldmVsIDMgWE1MIG1vZHVsZQotICogIERPTUltcGxlbWVudGF0aW9uIGRvbUltcGwgPQotICogICAgICAgcmVnaXN0cnkuZ2V0RE9NSW1wbGVtZW50YXRpb24oIlhNTCAzLjAiKTsKLSAqIDwvcHJlPgotICoKLSAqIDxwPgotICogVGhpcyBwcm92aWRlcyBhbiBhcHBsaWNhdGlvbiB3aXRoIGFuIGltcGxlbWVudGF0aW9uLWluZGVwZW5kZW50IHN0YXJ0aW5nCi0gKiBwb2ludC4gRE9NIGltcGxlbWVudGF0aW9ucyBtYXkgbW9kaWZ5IHRoaXMgY2xhc3MgdG8gbWVldCBuZXcgc2VjdXJpdHkKLSAqIHN0YW5kYXJkcyBvciB0byBwcm92aWRlICphZGRpdGlvbmFsKiBmYWxsYmFja3MgZm9yIHRoZSBsaXN0IG9mCi0gKiBET01JbXBsZW1lbnRhdGlvblNvdXJjZXMuCi0gKiA8L3A+Ci0gKgotICogQHNlZSBET01JbXBsZW1lbnRhdGlvbgotICogQHNlZSBET01JbXBsZW1lbnRhdGlvblNvdXJjZQotICogQHNpbmNlIERPTSBMZXZlbCAzCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBET01JbXBsZW1lbnRhdGlvblJlZ2lzdHJ5IHsKLSAgICAvKioKLSAgICAgKiBUaGUgc3lzdGVtIHByb3BlcnR5IHRvIHNwZWNpZnkgdGhlCi0gICAgICogRE9NSW1wbGVtZW50YXRpb25Tb3VyY2UgY2xhc3MgbmFtZXMuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgUFJPUEVSVFkgPQotICAgICAgICAib3JnLnczYy5kb20uRE9NSW1wbGVtZW50YXRpb25Tb3VyY2VMaXN0IjsKLQotICAgIC8qKgotICAgICAqIERlZmF1bHQgY29sdW1ucyBwZXIgbGluZS4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgREVGQVVMVF9MSU5FX0xFTkdUSCA9IDgwOwotCi0gICAgLyoqCi0gICAgICogVGhlIGxpc3Qgb2YgRE9NSW1wbGVtZW50YXRpb25Tb3VyY2VzLgotICAgICAqLwotICAgIHByaXZhdGUgVmVjdG9yIHNvdXJjZXM7Ci0KLSAgICAvKioKLSAgICAgKiBEZWZhdWx0IGNsYXNzIG5hbWUuCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEZBTExCQUNLX0NMQVNTID0KLSAgICAgICAgICAgICJjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbS5ET01YU0ltcGxlbWVudGF0aW9uU291cmNlSW1wbCI7Ci0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIERFRkFVTFRfUEFDS0FHRSA9Ci0gICAgICAgICAgICAiY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5kb20iOwotICAgIC8qKgotICAgICAqIFByaXZhdGUgY29uc3RydWN0b3IuCi0gICAgICogQHBhcmFtIHNyY3MgVmVjdG9yIExpc3Qgb2YgRE9NSW1wbGVtZW50YXRpb25Tb3VyY2VzCi0gICAgICovCi0gICAgcHJpdmF0ZSBET01JbXBsZW1lbnRhdGlvblJlZ2lzdHJ5KGZpbmFsIFZlY3RvciBzcmNzKSB7Ci0gICAgICAgIHNvdXJjZXMgPSBzcmNzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIE9idGFpbiBhIG5ldyBpbnN0YW5jZSBvZiBhIDxjb2RlPkRPTUltcGxlbWVudGF0aW9uUmVnaXN0cnk8L2NvZGU+LgotICAgICAqCi0KLSAgICAgKiBUaGUgPGNvZGU+RE9NSW1wbGVtZW50YXRpb25SZWdpc3RyeTwvY29kZT4gaXMgaW5pdGlhbGl6ZWQgYnkgdGhlCi0gICAgICogYXBwbGljYXRpb24gb3IgdGhlIGltcGxlbWVudGF0aW9uLCBkZXBlbmRpbmcgb24gdGhlIGNvbnRleHQsIGJ5Ci0gICAgICogZmlyc3QgY2hlY2tpbmcgdGhlIHZhbHVlIG9mIHRoZSBKYXZhIHN5c3RlbSBwcm9wZXJ0eQotICAgICAqIDxjb2RlPm9yZy53M2MuZG9tLkRPTUltcGxlbWVudGF0aW9uU291cmNlTGlzdDwvY29kZT4gYW5kCi0gICAgICogdGhlIHNlcnZpY2UgcHJvdmlkZXIgd2hvc2UgY29udGVudHMgYXJlIGF0Ci0gICAgICogIjxjb2RlPk1FVEFfSU5GL3NlcnZpY2VzL29yZy53M2MuZG9tLkRPTUltcGxlbWVudGF0aW9uU291cmNlTGlzdDwvY29kZT4iLgotICAgICAqIFRoZSB2YWx1ZSBvZiB0aGlzIHByb3BlcnR5IGlzIGEgd2hpdGUtc3BhY2Ugc2VwYXJhdGVkIGxpc3Qgb2YKLSAgICAgKiBuYW1lcyBvZiBhdmFpbGFibGVzIGNsYXNzZXMgaW1wbGVtZW50aW5nIHRoZQotICAgICAqIDxjb2RlPkRPTUltcGxlbWVudGF0aW9uU291cmNlPC9jb2RlPiBpbnRlcmZhY2UuIEVhY2ggY2xhc3MgbGlzdGVkCi0gICAgICogaW4gdGhlIGNsYXNzIG5hbWUgbGlzdCBpcyBpbnN0YW50aWF0ZWQgYW5kIGFueSBleGNlcHRpb25zCi0gICAgICogZW5jb3VudGVyZWQgYXJlIHRocm93biB0byB0aGUgYXBwbGljYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIGFuIGluaXRpYWxpemVkIGluc3RhbmNlIG9mIERPTUltcGxlbWVudGF0aW9uUmVnaXN0cnkKLSAgICAgKiBAdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb24KLSAgICAgKiAgICAgSWYgYW55IHNwZWNpZmllZCBjbGFzcyBjYW4gbm90IGJlIGZvdW5kCi0gICAgICogQHRocm93cyBJbnN0YW50aWF0aW9uRXhjZXB0aW9uCi0gICAgICogICAgIElmIGFueSBzcGVjaWZpZWQgY2xhc3MgaXMgYW4gaW50ZXJmYWNlIG9yIGFic3RyYWN0IGNsYXNzCi0gICAgICogQHRocm93cyBJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uCi0gICAgICogICAgIElmIHRoZSBkZWZhdWx0IGNvbnN0cnVjdG9yIG9mIGEgc3BlY2lmaWVkIGNsYXNzIGlzIG5vdCBhY2Nlc3NpYmxlCi0gICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24KLSAgICAgKiAgICAgSWYgYW55IHNwZWNpZmllZCBjbGFzcyBkb2VzIG5vdCBpbXBsZW1lbnQKLSAgICAgKiA8Y29kZT5ET01JbXBsZW1lbnRhdGlvblNvdXJjZTwvY29kZT4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIERPTUltcGxlbWVudGF0aW9uUmVnaXN0cnkgbmV3SW5zdGFuY2UoKQotICAgICAgICB0aHJvd3MKLSAgICAgICAgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiwKLSAgICAgICAgSW5zdGFudGlhdGlvbkV4Y2VwdGlvbiwKLSAgICAgICAgSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiwKLSAgICAgICAgQ2xhc3NDYXN0RXhjZXB0aW9uIHsKLSAgICAgICAgVmVjdG9yIHNvdXJjZXMgPSBuZXcgVmVjdG9yKCk7Ci0KLSAgICAgICAgQ2xhc3NMb2FkZXIgY2xhc3NMb2FkZXIgPSBnZXRDbGFzc0xvYWRlcigpOwotICAgICAgICAvLyBmZXRjaCBzeXN0ZW0gcHJvcGVydHk6Ci0gICAgICAgIFN0cmluZyBwID0gZ2V0U3lzdGVtUHJvcGVydHkoUFJPUEVSVFkpOwotCi0gICAgICAgIC8vCi0gICAgICAgIC8vIGlmIHByb3BlcnR5IGlzIG5vdCBzcGVjaWZpZWQgdGhlbiB1c2UgY29udGVudHMgb2YKLSAgICAgICAgLy8gTUVUQV9JTkYvb3JnLnczYy5kb20uRE9NSW1wbGVtZW50YXRpb25Tb3VyY2VMaXN0IGZyb20gY2xhc3NwYXRoCi0gICAgICAgIGlmIChwID09IG51bGwpIHsKLSAgICAgICAgICAgIHAgPSBnZXRTZXJ2aWNlVmFsdWUoY2xhc3NMb2FkZXIpOwotICAgICAgICB9Ci0gICAgICAgIGlmIChwID09IG51bGwpIHsKLSAgICAgICAgICAgIC8vCi0gICAgICAgICAgICAvLyBET00gSW1wbGVtZW50YXRpb25zIGNhbiBtb2RpZnkgaGVyZSB0byBhZGQgKmFkZGl0aW9uYWwqIGZhbGxiYWNrCi0gICAgICAgICAgICAvLyBtZWNoYW5pc21zIHRvIGFjY2VzcyBhIGxpc3Qgb2YgZGVmYXVsdCBET01JbXBsZW1lbnRhdGlvblNvdXJjZXMuCi0gICAgICAgICAgICAvL2ZhbGwgYmFjayB0byBKQVhQIGltcGxlbWVudGF0aW9uIGNsYXNzIGNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tLkRPTVhTSW1wbGVtZW50YXRpb25Tb3VyY2VJbXBsCi0gICAgICAgICAgICBwID0gRkFMTEJBQ0tfQ0xBU1M7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKHAgIT0gbnVsbCkgewotICAgICAgICAgICAgU3RyaW5nVG9rZW5pemVyIHN0ID0gbmV3IFN0cmluZ1Rva2VuaXplcihwKTsKLSAgICAgICAgICAgIHdoaWxlIChzdC5oYXNNb3JlVG9rZW5zKCkpIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgc291cmNlTmFtZSA9IHN0Lm5leHRUb2tlbigpOwotICAgICAgICAgICAgICAgIC8vIG1ha2Ugc3VyZSB3ZSBoYXZlIGFjY2VzcyB0byByZXN0cmljdGVkIHBhY2thZ2VzCi0gICAgICAgICAgICAgICAgYm9vbGVhbiBpbnRlcm5hbCA9IGZhbHNlOwotICAgICAgICAgICAgICAgIGlmIChTeXN0ZW0uZ2V0U2VjdXJpdHlNYW5hZ2VyKCkgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBpZiAoc291cmNlTmFtZSAhPSBudWxsICYmIHNvdXJjZU5hbWUuc3RhcnRzV2l0aChERUZBVUxUX1BBQ0tBR0UpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpbnRlcm5hbCA9IHRydWU7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgQ2xhc3Mgc291cmNlQ2xhc3MgPSBudWxsOwotICAgICAgICAgICAgICAgIGlmIChjbGFzc0xvYWRlciAhPSBudWxsICYmICFpbnRlcm5hbCkgewotICAgICAgICAgICAgICAgICAgICBzb3VyY2VDbGFzcyA9IGNsYXNzTG9hZGVyLmxvYWRDbGFzcyhzb3VyY2VOYW1lKTsKLSAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICBzb3VyY2VDbGFzcyA9IENsYXNzLmZvck5hbWUoc291cmNlTmFtZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIERPTUltcGxlbWVudGF0aW9uU291cmNlIHNvdXJjZSA9Ci0gICAgICAgICAgICAgICAgICAgIChET01JbXBsZW1lbnRhdGlvblNvdXJjZSkgc291cmNlQ2xhc3MubmV3SW5zdGFuY2UoKTsKLSAgICAgICAgICAgICAgICBzb3VyY2VzLmFkZEVsZW1lbnQoc291cmNlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbmV3IERPTUltcGxlbWVudGF0aW9uUmVnaXN0cnkoc291cmNlcyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSBmaXJzdCBpbXBsZW1lbnRhdGlvbiB0aGF0IGhhcyB0aGUgZGVzaXJlZAotICAgICAqIGZlYXR1cmVzLCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiBub25lIGlzIGZvdW5kLgotICAgICAqCi0gICAgICogQHBhcmFtIGZlYXR1cmVzCi0gICAgICogICAgICAgICAgICBBIHN0cmluZyB0aGF0IHNwZWNpZmllcyB3aGljaCBmZWF0dXJlcyBhcmUgcmVxdWlyZWQuIFRoaXMgaXMKLSAgICAgKiAgICAgICAgICAgIGEgc3BhY2Ugc2VwYXJhdGVkIGxpc3QgaW4gd2hpY2ggZWFjaCBmZWF0dXJlIGlzIHNwZWNpZmllZCBieQotICAgICAqICAgICAgICAgICAgaXRzIG5hbWUgb3B0aW9uYWxseSBmb2xsb3dlZCBieSBhIHNwYWNlIGFuZCBhIHZlcnNpb24gbnVtYmVyLgotICAgICAqICAgICAgICAgICAgVGhpcyBpcyBzb21ldGhpbmcgbGlrZTogIlhNTCAxLjAgVHJhdmVyc2FsICtFdmVudHMgMi4wIgotICAgICAqIEByZXR1cm4gQW4gaW1wbGVtZW50YXRpb24gdGhhdCBoYXMgdGhlIGRlc2lyZWQgZmVhdHVyZXMsCi0gICAgICogICAgICAgICBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiBub25lIGZvdW5kLgotICAgICAqLwotICAgIHB1YmxpYyBET01JbXBsZW1lbnRhdGlvbiBnZXRET01JbXBsZW1lbnRhdGlvbihmaW5hbCBTdHJpbmcgZmVhdHVyZXMpIHsKLSAgICAgICAgaW50IHNpemUgPSBzb3VyY2VzLnNpemUoKTsKLSAgICAgICAgU3RyaW5nIG5hbWUgPSBudWxsOwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewotICAgICAgICAgICAgRE9NSW1wbGVtZW50YXRpb25Tb3VyY2Ugc291cmNlID0KLSAgICAgICAgICAgICAgICAoRE9NSW1wbGVtZW50YXRpb25Tb3VyY2UpIHNvdXJjZXMuZWxlbWVudEF0KGkpOwotICAgICAgICAgICAgRE9NSW1wbGVtZW50YXRpb24gaW1wbCA9IHNvdXJjZS5nZXRET01JbXBsZW1lbnRhdGlvbihmZWF0dXJlcyk7Ci0gICAgICAgICAgICBpZiAoaW1wbCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGltcGw7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIGEgbGlzdCBvZiBpbXBsZW1lbnRhdGlvbnMgdGhhdCBzdXBwb3J0IHRoZQotICAgICAqIGRlc2lyZWQgZmVhdHVyZXMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZmVhdHVyZXMKLSAgICAgKiAgICAgICAgICAgIEEgc3RyaW5nIHRoYXQgc3BlY2lmaWVzIHdoaWNoIGZlYXR1cmVzIGFyZSByZXF1aXJlZC4gVGhpcyBpcwotICAgICAqICAgICAgICAgICAgYSBzcGFjZSBzZXBhcmF0ZWQgbGlzdCBpbiB3aGljaCBlYWNoIGZlYXR1cmUgaXMgc3BlY2lmaWVkIGJ5Ci0gICAgICogICAgICAgICAgICBpdHMgbmFtZSBvcHRpb25hbGx5IGZvbGxvd2VkIGJ5IGEgc3BhY2UgYW5kIGEgdmVyc2lvbiBudW1iZXIuCi0gICAgICogICAgICAgICAgICBUaGlzIGlzIHNvbWV0aGluZyBsaWtlOiAiWE1MIDEuMCBUcmF2ZXJzYWwgK0V2ZW50cyAyLjAiCi0gICAgICogQHJldHVybiBBIGxpc3Qgb2YgRE9NSW1wbGVtZW50YXRpb25zIHRoYXQgc3VwcG9ydCB0aGUgZGVzaXJlZCBmZWF0dXJlcy4KLSAgICAgKi8KLSAgICBwdWJsaWMgRE9NSW1wbGVtZW50YXRpb25MaXN0IGdldERPTUltcGxlbWVudGF0aW9uTGlzdChmaW5hbCBTdHJpbmcgZmVhdHVyZXMpIHsKLSAgICAgICAgZmluYWwgVmVjdG9yIGltcGxlbWVudGF0aW9ucyA9IG5ldyBWZWN0b3IoKTsKLSAgICAgICAgaW50IHNpemUgPSBzb3VyY2VzLnNpemUoKTsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKLSAgICAgICAgICAgIERPTUltcGxlbWVudGF0aW9uU291cmNlIHNvdXJjZSA9Ci0gICAgICAgICAgICAgICAgKERPTUltcGxlbWVudGF0aW9uU291cmNlKSBzb3VyY2VzLmVsZW1lbnRBdChpKTsKLSAgICAgICAgICAgIERPTUltcGxlbWVudGF0aW9uTGlzdCBpbXBscyA9Ci0gICAgICAgICAgICAgICAgc291cmNlLmdldERPTUltcGxlbWVudGF0aW9uTGlzdChmZWF0dXJlcyk7Ci0gICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IGltcGxzLmdldExlbmd0aCgpOyBqKyspIHsKLSAgICAgICAgICAgICAgICBET01JbXBsZW1lbnRhdGlvbiBpbXBsID0gaW1wbHMuaXRlbShqKTsKLSAgICAgICAgICAgICAgICBpbXBsZW1lbnRhdGlvbnMuYWRkRWxlbWVudChpbXBsKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbmV3IERPTUltcGxlbWVudGF0aW9uTGlzdCgpIHsKLSAgICAgICAgICAgICAgICBwdWJsaWMgRE9NSW1wbGVtZW50YXRpb24gaXRlbShmaW5hbCBpbnQgaW5kZXgpIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGluZGV4ID49IDAgJiYgaW5kZXggPCBpbXBsZW1lbnRhdGlvbnMuc2l6ZSgpKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoRE9NSW1wbGVtZW50YXRpb24pCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGltcGxlbWVudGF0aW9ucy5lbGVtZW50QXQoaW5kZXgpOwotICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBwdWJsaWMgaW50IGdldExlbmd0aCgpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGltcGxlbWVudGF0aW9ucy5zaXplKCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZWdpc3RlciBhbiBpbXBsZW1lbnRhdGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzIFRoZSBzb3VyY2UgdG8gYmUgcmVnaXN0ZXJlZCwgbWF5IG5vdCBiZSA8Y29kZT5udWxsPC9jb2RlPgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGFkZFNvdXJjZShmaW5hbCBET01JbXBsZW1lbnRhdGlvblNvdXJjZSBzKSB7Ci0gICAgICAgIGlmIChzID09IG51bGwpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwotICAgICAgICB9Ci0gICAgICAgIGlmICghc291cmNlcy5jb250YWlucyhzKSkgewotICAgICAgICAgICAgc291cmNlcy5hZGRFbGVtZW50KHMpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICoKLSAgICAgKiBHZXRzIGEgY2xhc3MgbG9hZGVyLgotICAgICAqCi0gICAgICogQHJldHVybiBBIGNsYXNzIGxvYWRlciwgcG9zc2libHkgPGNvZGU+bnVsbDwvY29kZT4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBDbGFzc0xvYWRlciBnZXRDbGFzc0xvYWRlcigpIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIENsYXNzTG9hZGVyIGNvbnRleHRDbGFzc0xvYWRlciA9IGdldENvbnRleHRDbGFzc0xvYWRlcigpOwotCi0gICAgICAgICAgICBpZiAoY29udGV4dENsYXNzTG9hZGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gY29udGV4dENsYXNzTG9hZGVyOwotICAgICAgICAgICAgfQotICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgLy8gQXNzdW1lIHRoYXQgdGhlIERPTSBhcHBsaWNhdGlvbiBpcyBpbiBhIEpSRSAxLjEsIHVzZSB0aGUKLSAgICAgICAgICAgIC8vIGN1cnJlbnQgQ2xhc3NMb2FkZXIKLSAgICAgICAgICAgIHJldHVybiBET01JbXBsZW1lbnRhdGlvblJlZ2lzdHJ5LmNsYXNzLmdldENsYXNzTG9hZGVyKCk7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIERPTUltcGxlbWVudGF0aW9uUmVnaXN0cnkuY2xhc3MuZ2V0Q2xhc3NMb2FkZXIoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBhdHRlbXB0cyB0byByZXR1cm4gdGhlIGZpcnN0IGxpbmUgb2YgdGhlIHJlc291cmNlCi0gICAgICogTUVUQV9JTkYvc2VydmljZXMvb3JnLnczYy5kb20uRE9NSW1wbGVtZW50YXRpb25Tb3VyY2VMaXN0Ci0gICAgICogZnJvbSB0aGUgcHJvdmlkZWQgQ2xhc3NMb2FkZXIuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY2xhc3NMb2FkZXIgY2xhc3NMb2FkZXIsIG1heSBub3QgYmUgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICogQHJldHVybiBmaXJzdCBsaW5lIG9mIHJlc291cmNlLCBvciA8Y29kZT5udWxsPC9jb2RlPgotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBnZXRTZXJ2aWNlVmFsdWUoZmluYWwgQ2xhc3NMb2FkZXIgY2xhc3NMb2FkZXIpIHsKLSAgICAgICAgU3RyaW5nIHNlcnZpY2VJZCA9ICJNRVRBLUlORi9zZXJ2aWNlcy8iICsgUFJPUEVSVFk7Ci0gICAgICAgIC8vIHRyeSB0byBmaW5kIHNlcnZpY2VzIGluIENMQVNTUEFUSAotICAgICAgICB0cnkgewotICAgICAgICAgICAgSW5wdXRTdHJlYW0gaXMgPSBnZXRSZXNvdXJjZUFzU3RyZWFtKGNsYXNzTG9hZGVyLCBzZXJ2aWNlSWQpOwotCi0gICAgICAgICAgICBpZiAoaXMgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIEJ1ZmZlcmVkUmVhZGVyIHJkOwotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgIHJkID0KLSAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBCdWZmZXJlZFJlYWRlcihuZXcgSW5wdXRTdHJlYW1SZWFkZXIoaXMsICJVVEYtOCIpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERFRkFVTFRfTElORV9MRU5HVEgpOwotICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJkID0KLSAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBCdWZmZXJlZFJlYWRlcihuZXcgSW5wdXRTdHJlYW1SZWFkZXIoaXMpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERFRkFVTFRfTElORV9MRU5HVEgpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBTdHJpbmcgc2VydmljZVZhbHVlID0gcmQucmVhZExpbmUoKTsKLSAgICAgICAgICAgICAgICByZC5jbG9zZSgpOwotICAgICAgICAgICAgICAgIGlmIChzZXJ2aWNlVmFsdWUgIT0gbnVsbCAmJiBzZXJ2aWNlVmFsdWUubGVuZ3RoKCkgPiAwKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBzZXJ2aWNlVmFsdWU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEEgc2ltcGxlIEpSRSAoSmF2YSBSdW50aW1lIEVudmlyb25tZW50KSAxLjEgdGVzdAotICAgICAqCi0gICAgICogQHJldHVybiA8Y29kZT50cnVlPC9jb2RlPiBpZiBKUkUgMS4xCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBpc0pSRTExKCkgewotICAgICAgICB0cnkgewotICAgICAgICAgICAgQ2xhc3MgYyA9IENsYXNzLmZvck5hbWUoImphdmEuc2VjdXJpdHkuQWNjZXNzQ29udHJvbGxlciIpOwotICAgICAgICAgICAgLy8gamF2YS5zZWN1cml0eS5BY2Nlc3NDb250cm9sbGVyIGV4aXN0ZWQgc2luY2UgMS4yIHNvLCBpZiBubwotICAgICAgICAgICAgLy8gZXhjZXB0aW9uIHdhcyB0aHJvd24sIHRoZSBET00gYXBwbGljYXRpb24gaXMgcnVubmluZyBpbiBhIEpSRQotICAgICAgICAgICAgLy8gMS4yIG9yIGhpZ2hlcgotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKLSAgICAgICAgICAgIC8vIGlnbm9yZQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIHJldHVybnMgdGhlIENvbnRleHRDbGFzc0xvYWRlciBvciA8Y29kZT5udWxsPC9jb2RlPiBpZgotICAgICAqIHJ1bm5pbmcgaW4gYSBKUkUgMS4xCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBDb250ZXh0IENsYXNzbG9hZGVyCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgQ2xhc3NMb2FkZXIgZ2V0Q29udGV4dENsYXNzTG9hZGVyKCkgewotICAgICAgICByZXR1cm4gaXNKUkUxMSgpCi0gICAgICAgICAgICA/IG51bGwKLSAgICAgICAgICAgIDogKENsYXNzTG9hZGVyKQotICAgICAgICAgICAgICBBY2Nlc3NDb250cm9sbGVyLmRvUHJpdmlsZWdlZChuZXcgUHJpdmlsZWdlZEFjdGlvbigpIHsKLSAgICAgICAgICAgICAgICAgICAgcHVibGljIE9iamVjdCBydW4oKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBDbGFzc0xvYWRlciBjbGFzc0xvYWRlciA9IG51bGw7Ci0gICAgICAgICAgICAgICAgICAgICAgICB0cnkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzTG9hZGVyID0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5nZXRDb250ZXh0Q2xhc3NMb2FkZXIoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIGV4KSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gY2xhc3NMb2FkZXI7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9KTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCByZXR1cm5zIHRoZSBzeXN0ZW0gcHJvcGVydHkgaW5kaWNhdGVkIGJ5IHRoZSBzcGVjaWZpZWQgbmFtZQotICAgICAqIGFmdGVyIGNoZWNraW5nIGFjY2VzcyBjb250cm9sIHByaXZpbGVnZXMuIEZvciBhIEpSRSAxLjEsIHRoaXMgY2hlY2sgaXMKLSAgICAgKiBub3QgZG9uZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lIHRoZSBuYW1lIG9mIHRoZSBzeXN0ZW0gcHJvcGVydHkKLSAgICAgKiBAcmV0dXJuIHRoZSBzeXN0ZW0gcHJvcGVydHkKLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgZ2V0U3lzdGVtUHJvcGVydHkoZmluYWwgU3RyaW5nIG5hbWUpIHsKLSAgICAgICAgcmV0dXJuIGlzSlJFMTEoKQotICAgICAgICAgICAgPyAoU3RyaW5nKSBTeXN0ZW0uZ2V0UHJvcGVydHkobmFtZSkKLSAgICAgICAgICAgIDogKFN0cmluZykgQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQobmV3IFByaXZpbGVnZWRBY3Rpb24oKSB7Ci0gICAgICAgICAgICAgICAgICAgIHB1YmxpYyBPYmplY3QgcnVuKCkgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFN5c3RlbS5nZXRQcm9wZXJ0eShuYW1lKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0pOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIHJldHVybnMgYW4gSW5wdXRzdHJlYW0gZm9yIHRoZSByZWFkaW5nIHJlc291cmNlCi0gICAgICogTUVUQV9JTkYvc2VydmljZXMvb3JnLnczYy5kb20uRE9NSW1wbGVtZW50YXRpb25Tb3VyY2VMaXN0IGFmdGVyIGNoZWNraW5nCi0gICAgICogYWNjZXNzIGNvbnRyb2wgcHJpdmlsZWdlcy4gRm9yIGEgSlJFIDEuMSwgdGhpcyBjaGVjayBpcyBub3QgZG9uZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjbGFzc0xvYWRlciBjbGFzc0xvYWRlcgotICAgICAqIEBwYXJhbSBuYW1lIHRoZSByZXNvdXJjZQotICAgICAqIEByZXR1cm4gYW4gSW5wdXRzdHJlYW0gZm9yIHRoZSByZXNvdXJjZSBzcGVjaWZpZWQKLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBJbnB1dFN0cmVhbSBnZXRSZXNvdXJjZUFzU3RyZWFtKGZpbmFsIENsYXNzTG9hZGVyIGNsYXNzTG9hZGVyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIG5hbWUpIHsKLSAgICAgICAgaWYgKGlzSlJFMTEoKSkgewotICAgICAgICAgICAgSW5wdXRTdHJlYW0gcmlzOwotICAgICAgICAgICAgaWYgKGNsYXNzTG9hZGVyID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICByaXMgPSBDbGFzc0xvYWRlci5nZXRTeXN0ZW1SZXNvdXJjZUFzU3RyZWFtKG5hbWUpOwotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICByaXMgPSBjbGFzc0xvYWRlci5nZXRSZXNvdXJjZUFzU3RyZWFtKG5hbWUpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIHJpczsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiAoSW5wdXRTdHJlYW0pCi0gICAgICAgICAgICAgICAgQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQobmV3IFByaXZpbGVnZWRBY3Rpb24oKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBwdWJsaWMgT2JqZWN0IHJ1bigpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbnB1dFN0cmVhbSByaXM7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNsYXNzTG9hZGVyID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmlzID0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENsYXNzTG9hZGVyLmdldFN5c3RlbVJlc291cmNlQXNTdHJlYW0obmFtZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmlzID0gY2xhc3NMb2FkZXIuZ2V0UmVzb3VyY2VBc1N0cmVhbShuYW1lKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJpczsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfSk7Ci0gICAgICAgIH0KLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL3czYy9kb20vY3NzL0NTUzJQcm9wZXJ0aWVzLmphdmEgYi9zcmMvb3JnL3czYy9kb20vY3NzL0NTUzJQcm9wZXJ0aWVzLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGQyMmRlMWQuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy93M2MvZG9tL2Nzcy9DU1MyUHJvcGVydGllcy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTgwNiArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogVGhpcyBmaWxlIGlzIGF2YWlsYWJsZSB1bmRlciBhbmQgZ292ZXJuZWQgYnkgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwotICogTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKiBIb3dldmVyLCB0aGUgZm9sbG93aW5nIG5vdGljZSBhY2NvbXBhbmllZCB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGlzCi0gKiBmaWxlIGFuZCwgcGVyIGl0cyB0ZXJtcywgc2hvdWxkIG5vdCBiZSByZW1vdmVkOgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAotICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCi0gKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKLSAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQotICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKLSAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KLSAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKLSAqIFBVUlBPU0UuCi0gKiBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KLSAqLwotCi1wYWNrYWdlIG9yZy53M2MuZG9tLmNzczsKLQotaW1wb3J0IG9yZy53M2MuZG9tLkRPTUV4Y2VwdGlvbjsKLQotLyoqCi0gKiAgVGhlIDxjb2RlPkNTUzJQcm9wZXJ0aWVzPC9jb2RlPiBpbnRlcmZhY2UgcmVwcmVzZW50cyBhIGNvbnZlbmllbmNlCi0gKiBtZWNoYW5pc20gZm9yIHJldHJpZXZpbmcgYW5kIHNldHRpbmcgcHJvcGVydGllcyB3aXRoaW4gYQotICogPGNvZGU+Q1NTU3R5bGVEZWNsYXJhdGlvbjwvY29kZT4uIFRoZSBhdHRyaWJ1dGVzIG9mIHRoaXMgaW50ZXJmYWNlCi0gKiBjb3JyZXNwb25kIHRvIGFsbCB0aGUgcHJvcGVydGllcyBzcGVjaWZpZWQgaW4gQ1NTMi4gR2V0dGluZyBhbiBhdHRyaWJ1dGUKLSAqIG9mIHRoaXMgaW50ZXJmYWNlIGlzIGVxdWl2YWxlbnQgdG8gY2FsbGluZyB0aGUKLSAqIDxjb2RlPmdldFByb3BlcnR5VmFsdWU8L2NvZGU+IG1ldGhvZCBvZiB0aGUKLSAqIDxjb2RlPkNTU1N0eWxlRGVjbGFyYXRpb248L2NvZGU+IGludGVyZmFjZS4gU2V0dGluZyBhbiBhdHRyaWJ1dGUgb2YgdGhpcwotICogaW50ZXJmYWNlIGlzIGVxdWl2YWxlbnQgdG8gY2FsbGluZyB0aGUgPGNvZGU+c2V0UHJvcGVydHk8L2NvZGU+IG1ldGhvZCBvZgotICogdGhlIDxjb2RlPkNTU1N0eWxlRGVjbGFyYXRpb248L2NvZGU+IGludGVyZmFjZS4KLSAqIDxwPiBBIGNvbmZvcm1hbnQgaW1wbGVtZW50YXRpb24gb2YgdGhlIENTUyBtb2R1bGUgaXMgbm90IHJlcXVpcmVkIHRvCi0gKiBpbXBsZW1lbnQgdGhlIDxjb2RlPkNTUzJQcm9wZXJ0aWVzPC9jb2RlPiBpbnRlcmZhY2UuIElmIGFuIGltcGxlbWVudGF0aW9uCi0gKiBkb2VzIGltcGxlbWVudCB0aGlzIGludGVyZmFjZSwgdGhlIGV4cGVjdGF0aW9uIGlzIHRoYXQgbGFuZ3VhZ2Utc3BlY2lmaWMKLSAqIG1ldGhvZHMgY2FuIGJlIHVzZWQgdG8gY2FzdCBmcm9tIGFuIGluc3RhbmNlIG9mIHRoZQotICogPGNvZGU+Q1NTU3R5bGVEZWNsYXJhdGlvbjwvY29kZT4gaW50ZXJmYWNlIHRvIHRoZQotICogPGNvZGU+Q1NTMlByb3BlcnRpZXM8L2NvZGU+IGludGVyZmFjZS4KLSAqIDxwPiBJZiBhbiBpbXBsZW1lbnRhdGlvbiBkb2VzIGltcGxlbWVudCB0aGlzIGludGVyZmFjZSwgaXQgaXMgZXhwZWN0ZWQgdG8KLSAqIHVuZGVyc3RhbmQgdGhlIHNwZWNpZmljIHN5bnRheCBvZiB0aGUgc2hvcnRoYW5kIHByb3BlcnRpZXMsIGFuZCBhcHBseQotICogdGhlaXIgc2VtYW50aWNzOyB3aGVuIHRoZSA8Y29kZT5tYXJnaW48L2NvZGU+IHByb3BlcnR5IGlzIHNldCwgZm9yCi0gKiBleGFtcGxlLCB0aGUgPGNvZGU+bWFyZ2luVG9wPC9jb2RlPiwgPGNvZGU+bWFyZ2luUmlnaHQ8L2NvZGU+LAotICogPGNvZGU+bWFyZ2luQm90dG9tPC9jb2RlPiBhbmQgPGNvZGU+bWFyZ2luTGVmdDwvY29kZT4gcHJvcGVydGllcyBhcmUKLSAqIGFjdHVhbGx5IGJlaW5nIHNldCBieSB0aGUgdW5kZXJseWluZyBpbXBsZW1lbnRhdGlvbi4KLSAqIDxwPiBXaGVuIGRlYWxpbmcgd2l0aCBDU1MgInNob3J0aGFuZCIgcHJvcGVydGllcywgdGhlIHNob3J0aGFuZCBwcm9wZXJ0aWVzCi0gKiBzaG91bGQgYmUgZGVjb21wb3NlZCBpbnRvIHRoZWlyIGNvbXBvbmVudCBsb25naGFuZCBwcm9wZXJ0aWVzIGFzCi0gKiBhcHByb3ByaWF0ZSwgYW5kIHdoZW4gcXVlcnlpbmcgZm9yIHRoZWlyIHZhbHVlLCB0aGUgZm9ybSByZXR1cm5lZCBzaG91bGQKLSAqIGJlIHRoZSBzaG9ydGVzdCBmb3JtIGV4YWN0bHkgZXF1aXZhbGVudCB0byB0aGUgZGVjbGFyYXRpb25zIG1hZGUgaW4gdGhlCi0gKiBydWxlc2V0LiBIb3dldmVyLCBpZiB0aGVyZSBpcyBubyBzaG9ydGhhbmQgZGVjbGFyYXRpb24gdGhhdCBjb3VsZCBiZQotICogYWRkZWQgdG8gdGhlIHJ1bGVzZXQgd2l0aG91dCBjaGFuZ2luZyBpbiBhbnkgd2F5IHRoZSBydWxlcyBhbHJlYWR5Ci0gKiBkZWNsYXJlZCBpbiB0aGUgcnVsZXNldCAoaS5lLiwgYnkgYWRkaW5nIGxvbmdoYW5kIHJ1bGVzIHRoYXQgd2VyZQotICogcHJldmlvdXNseSBub3QgZGVjbGFyZWQgaW4gdGhlIHJ1bGVzZXQpLCB0aGVuIHRoZSBlbXB0eSBzdHJpbmcgc2hvdWxkIGJlCi0gKiByZXR1cm5lZCBmb3IgdGhlIHNob3J0aGFuZCBwcm9wZXJ0eS4KLSAqIDxwPiBGb3IgZXhhbXBsZSwgcXVlcnlpbmcgZm9yIHRoZSA8Y29kZT5mb250PC9jb2RlPiBwcm9wZXJ0eSBzaG91bGQgbm90Ci0gKiByZXR1cm4gIm5vcm1hbCBub3JtYWwgbm9ybWFsIDE0cHQvbm9ybWFsIEFyaWFsLCBzYW5zLXNlcmlmIiwgd2hlbiAiMTRwdAotICogQXJpYWwsIHNhbnMtc2VyaWYiIHN1ZmZpY2VzLiAoVGhlIG5vcm1hbHMgYXJlIGluaXRpYWwgdmFsdWVzLCBhbmQgYXJlCi0gKiBpbXBsaWVkIGJ5IHVzZSBvZiB0aGUgbG9uZ2hhbmQgcHJvcGVydHkuKQotICogPHA+IElmIHRoZSB2YWx1ZXMgZm9yIGFsbCB0aGUgbG9uZ2hhbmQgcHJvcGVydGllcyB0aGF0IGNvbXBvc2UgYSBwYXJ0aWN1bGFyCi0gKiBzdHJpbmcgYXJlIHRoZSBpbml0aWFsIHZhbHVlcywgdGhlbiBhIHN0cmluZyBjb25zaXN0aW5nIG9mIGFsbCB0aGUKLSAqIGluaXRpYWwgdmFsdWVzIHNob3VsZCBiZSByZXR1cm5lZCAoZS5nLiBhIDxjb2RlPmJvcmRlci13aWR0aDwvY29kZT4gdmFsdWUKLSAqIG9mICJtZWRpdW0iIHNob3VsZCBiZSByZXR1cm5lZCBhcyBzdWNoLCBub3QgYXMgIiIpLgotICogPHA+IEZvciBzb21lIHNob3J0aGFuZCBwcm9wZXJ0aWVzIHRoYXQgdGFrZSBtaXNzaW5nIHZhbHVlcyBmcm9tIG90aGVyCi0gKiBzaWRlcywgc3VjaCBhcyB0aGUgPGNvZGU+bWFyZ2luPC9jb2RlPiwgPGNvZGU+cGFkZGluZzwvY29kZT4sIGFuZAotICogPGNvZGU+Ym9yZGVyLVt3aWR0aHxzdHlsZXxjb2xvcl08L2NvZGU+IHByb3BlcnRpZXMsIHRoZSBtaW5pbXVtIG51bWJlciBvZgotICogc2lkZXMgcG9zc2libGUgc2hvdWxkIGJlIHVzZWQ7IGkuZS4sICIwcHggMTBweCIgd2lsbCBiZSByZXR1cm5lZCBpbnN0ZWFkCi0gKiBvZiAiMHB4IDEwcHggMHB4IDEwcHgiLgotICogPHA+IElmIHRoZSB2YWx1ZSBvZiBhIHNob3J0aGFuZCBwcm9wZXJ0eSBjYW4gbm90IGJlIGRlY29tcG9zZWQgaW50byBpdHMKLSAqIGNvbXBvbmVudCBsb25naGFuZCBwcm9wZXJ0aWVzLCBhcyBpcyB0aGUgY2FzZSBmb3IgdGhlIDxjb2RlPmZvbnQ8L2NvZGU+Ci0gKiBwcm9wZXJ0eSB3aXRoIGEgdmFsdWUgb2YgIm1lbnUiLCBxdWVyeWluZyBmb3IgdGhlIHZhbHVlcyBvZiB0aGUgY29tcG9uZW50Ci0gKiBsb25naGFuZCBwcm9wZXJ0aWVzIHNob3VsZCByZXR1cm4gdGhlIGVtcHR5IHN0cmluZy4KLSAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAwL1JFQy1ET00tTGV2ZWwtMi1TdHlsZS0yMDAwMTExMyc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDIgU3R5bGUgU3BlY2lmaWNhdGlvbjwvYT4uCi0gKiBAc2luY2UgRE9NIExldmVsIDIKLSAqLwotcHVibGljIGludGVyZmFjZSBDU1MyUHJvcGVydGllcyB7Ci0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgYXppbXV0aCBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRBemltdXRoKCk7Ci0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgYXppbXV0aCBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIFNZTlRBWF9FUlI6IFJhaXNlZCBpZiB0aGUgbmV3IHZhbHVlIGhhcyBhIHN5bnRheCBlcnJvciBhbmQgaXMKLSAgICAgKiAgIHVucGFyc2FibGUuCi0gICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBwcm9wZXJ0eSBpcyByZWFkb25seS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRBemltdXRoKFN0cmluZyBhemltdXRoKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBTZWUgdGhlIGJhY2tncm91bmQgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0QmFja2dyb3VuZCgpOwotICAgIC8qKgotICAgICAqICBTZWUgdGhlIGJhY2tncm91bmQgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBTWU5UQVhfRVJSOiBSYWlzZWQgaWYgdGhlIG5ldyB2YWx1ZSBoYXMgYSBzeW50YXggZXJyb3IgYW5kIGlzCi0gICAgICogICB1bnBhcnNhYmxlLgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgcHJvcGVydHkgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0QmFja2dyb3VuZChTdHJpbmcgYmFja2dyb3VuZCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBiYWNrZ3JvdW5kLWF0dGFjaG1lbnQgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0QmFja2dyb3VuZEF0dGFjaG1lbnQoKTsKLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBiYWNrZ3JvdW5kLWF0dGFjaG1lbnQgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBTWU5UQVhfRVJSOiBSYWlzZWQgaWYgdGhlIG5ldyB2YWx1ZSBoYXMgYSBzeW50YXggZXJyb3IgYW5kIGlzCi0gICAgICogICB1bnBhcnNhYmxlLgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgcHJvcGVydHkgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0QmFja2dyb3VuZEF0dGFjaG1lbnQoU3RyaW5nIGJhY2tncm91bmRBdHRhY2htZW50KQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBTZWUgdGhlIGJhY2tncm91bmQtY29sb3IgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0QmFja2dyb3VuZENvbG9yKCk7Ci0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgYmFja2dyb3VuZC1jb2xvciBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIFNZTlRBWF9FUlI6IFJhaXNlZCBpZiB0aGUgbmV3IHZhbHVlIGhhcyBhIHN5bnRheCBlcnJvciBhbmQgaXMKLSAgICAgKiAgIHVucGFyc2FibGUuCi0gICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBwcm9wZXJ0eSBpcyByZWFkb25seS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRCYWNrZ3JvdW5kQ29sb3IoU3RyaW5nIGJhY2tncm91bmRDb2xvcikKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBiYWNrZ3JvdW5kLWltYWdlIHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEJhY2tncm91bmRJbWFnZSgpOwotICAgIC8qKgotICAgICAqICBTZWUgdGhlIGJhY2tncm91bmQtaW1hZ2UgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBTWU5UQVhfRVJSOiBSYWlzZWQgaWYgdGhlIG5ldyB2YWx1ZSBoYXMgYSBzeW50YXggZXJyb3IgYW5kIGlzCi0gICAgICogICB1bnBhcnNhYmxlLgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgcHJvcGVydHkgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0QmFja2dyb3VuZEltYWdlKFN0cmluZyBiYWNrZ3JvdW5kSW1hZ2UpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgYmFja2dyb3VuZC1wb3NpdGlvbiBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRCYWNrZ3JvdW5kUG9zaXRpb24oKTsKLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBiYWNrZ3JvdW5kLXBvc2l0aW9uIHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgU1lOVEFYX0VSUjogUmFpc2VkIGlmIHRoZSBuZXcgdmFsdWUgaGFzIGEgc3ludGF4IGVycm9yIGFuZCBpcwotICAgICAqICAgdW5wYXJzYWJsZS4KLSAgICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIHByb3BlcnR5IGlzIHJlYWRvbmx5LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEJhY2tncm91bmRQb3NpdGlvbihTdHJpbmcgYmFja2dyb3VuZFBvc2l0aW9uKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBTZWUgdGhlIGJhY2tncm91bmQtcmVwZWF0IHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEJhY2tncm91bmRSZXBlYXQoKTsKLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBiYWNrZ3JvdW5kLXJlcGVhdCBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIFNZTlRBWF9FUlI6IFJhaXNlZCBpZiB0aGUgbmV3IHZhbHVlIGhhcyBhIHN5bnRheCBlcnJvciBhbmQgaXMKLSAgICAgKiAgIHVucGFyc2FibGUuCi0gICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBwcm9wZXJ0eSBpcyByZWFkb25seS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRCYWNrZ3JvdW5kUmVwZWF0KFN0cmluZyBiYWNrZ3JvdW5kUmVwZWF0KQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBTZWUgdGhlIGJvcmRlciBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRCb3JkZXIoKTsKLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBib3JkZXIgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBTWU5UQVhfRVJSOiBSYWlzZWQgaWYgdGhlIG5ldyB2YWx1ZSBoYXMgYSBzeW50YXggZXJyb3IgYW5kIGlzCi0gICAgICogICB1bnBhcnNhYmxlLgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgcHJvcGVydHkgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0Qm9yZGVyKFN0cmluZyBib3JkZXIpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgYm9yZGVyLWNvbGxhcHNlIHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEJvcmRlckNvbGxhcHNlKCk7Ci0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgYm9yZGVyLWNvbGxhcHNlIHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgU1lOVEFYX0VSUjogUmFpc2VkIGlmIHRoZSBuZXcgdmFsdWUgaGFzIGEgc3ludGF4IGVycm9yIGFuZCBpcwotICAgICAqICAgdW5wYXJzYWJsZS4KLSAgICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIHByb3BlcnR5IGlzIHJlYWRvbmx5LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEJvcmRlckNvbGxhcHNlKFN0cmluZyBib3JkZXJDb2xsYXBzZSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBib3JkZXItY29sb3IgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Qm9yZGVyQ29sb3IoKTsKLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBib3JkZXItY29sb3IgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBTWU5UQVhfRVJSOiBSYWlzZWQgaWYgdGhlIG5ldyB2YWx1ZSBoYXMgYSBzeW50YXggZXJyb3IgYW5kIGlzCi0gICAgICogICB1bnBhcnNhYmxlLgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgcHJvcGVydHkgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0Qm9yZGVyQ29sb3IoU3RyaW5nIGJvcmRlckNvbG9yKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBTZWUgdGhlIGJvcmRlci1zcGFjaW5nIHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEJvcmRlclNwYWNpbmcoKTsKLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBib3JkZXItc3BhY2luZyBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIFNZTlRBWF9FUlI6IFJhaXNlZCBpZiB0aGUgbmV3IHZhbHVlIGhhcyBhIHN5bnRheCBlcnJvciBhbmQgaXMKLSAgICAgKiAgIHVucGFyc2FibGUuCi0gICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBwcm9wZXJ0eSBpcyByZWFkb25seS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRCb3JkZXJTcGFjaW5nKFN0cmluZyBib3JkZXJTcGFjaW5nKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBTZWUgdGhlIGJvcmRlci1zdHlsZSBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRCb3JkZXJTdHlsZSgpOwotICAgIC8qKgotICAgICAqICBTZWUgdGhlIGJvcmRlci1zdHlsZSBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIFNZTlRBWF9FUlI6IFJhaXNlZCBpZiB0aGUgbmV3IHZhbHVlIGhhcyBhIHN5bnRheCBlcnJvciBhbmQgaXMKLSAgICAgKiAgIHVucGFyc2FibGUuCi0gICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBwcm9wZXJ0eSBpcyByZWFkb25seS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRCb3JkZXJTdHlsZShTdHJpbmcgYm9yZGVyU3R5bGUpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgYm9yZGVyLXRvcCBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRCb3JkZXJUb3AoKTsKLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBib3JkZXItdG9wIHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgU1lOVEFYX0VSUjogUmFpc2VkIGlmIHRoZSBuZXcgdmFsdWUgaGFzIGEgc3ludGF4IGVycm9yIGFuZCBpcwotICAgICAqICAgdW5wYXJzYWJsZS4KLSAgICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIHByb3BlcnR5IGlzIHJlYWRvbmx5LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEJvcmRlclRvcChTdHJpbmcgYm9yZGVyVG9wKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBTZWUgdGhlIGJvcmRlci1yaWdodCBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRCb3JkZXJSaWdodCgpOwotICAgIC8qKgotICAgICAqICBTZWUgdGhlIGJvcmRlci1yaWdodCBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIFNZTlRBWF9FUlI6IFJhaXNlZCBpZiB0aGUgbmV3IHZhbHVlIGhhcyBhIHN5bnRheCBlcnJvciBhbmQgaXMKLSAgICAgKiAgIHVucGFyc2FibGUuCi0gICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBwcm9wZXJ0eSBpcyByZWFkb25seS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRCb3JkZXJSaWdodChTdHJpbmcgYm9yZGVyUmlnaHQpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgYm9yZGVyLWJvdHRvbSBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRCb3JkZXJCb3R0b20oKTsKLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBib3JkZXItYm90dG9tIHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgU1lOVEFYX0VSUjogUmFpc2VkIGlmIHRoZSBuZXcgdmFsdWUgaGFzIGEgc3ludGF4IGVycm9yIGFuZCBpcwotICAgICAqICAgdW5wYXJzYWJsZS4KLSAgICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIHByb3BlcnR5IGlzIHJlYWRvbmx5LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEJvcmRlckJvdHRvbShTdHJpbmcgYm9yZGVyQm90dG9tKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBTZWUgdGhlIGJvcmRlci1sZWZ0IHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEJvcmRlckxlZnQoKTsKLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBib3JkZXItbGVmdCBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIFNZTlRBWF9FUlI6IFJhaXNlZCBpZiB0aGUgbmV3IHZhbHVlIGhhcyBhIHN5bnRheCBlcnJvciBhbmQgaXMKLSAgICAgKiAgIHVucGFyc2FibGUuCi0gICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBwcm9wZXJ0eSBpcyByZWFkb25seS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRCb3JkZXJMZWZ0KFN0cmluZyBib3JkZXJMZWZ0KQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBTZWUgdGhlIGJvcmRlci10b3AtY29sb3IgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Qm9yZGVyVG9wQ29sb3IoKTsKLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBib3JkZXItdG9wLWNvbG9yIHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgU1lOVEFYX0VSUjogUmFpc2VkIGlmIHRoZSBuZXcgdmFsdWUgaGFzIGEgc3ludGF4IGVycm9yIGFuZCBpcwotICAgICAqICAgdW5wYXJzYWJsZS4KLSAgICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIHByb3BlcnR5IGlzIHJlYWRvbmx5LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEJvcmRlclRvcENvbG9yKFN0cmluZyBib3JkZXJUb3BDb2xvcikKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBib3JkZXItcmlnaHQtY29sb3IgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Qm9yZGVyUmlnaHRDb2xvcigpOwotICAgIC8qKgotICAgICAqICBTZWUgdGhlIGJvcmRlci1yaWdodC1jb2xvciBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIFNZTlRBWF9FUlI6IFJhaXNlZCBpZiB0aGUgbmV3IHZhbHVlIGhhcyBhIHN5bnRheCBlcnJvciBhbmQgaXMKLSAgICAgKiAgIHVucGFyc2FibGUuCi0gICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBwcm9wZXJ0eSBpcyByZWFkb25seS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRCb3JkZXJSaWdodENvbG9yKFN0cmluZyBib3JkZXJSaWdodENvbG9yKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBTZWUgdGhlIGJvcmRlci1ib3R0b20tY29sb3IgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Qm9yZGVyQm90dG9tQ29sb3IoKTsKLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBib3JkZXItYm90dG9tLWNvbG9yIHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgU1lOVEFYX0VSUjogUmFpc2VkIGlmIHRoZSBuZXcgdmFsdWUgaGFzIGEgc3ludGF4IGVycm9yIGFuZCBpcwotICAgICAqICAgdW5wYXJzYWJsZS4KLSAgICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIHByb3BlcnR5IGlzIHJlYWRvbmx5LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEJvcmRlckJvdHRvbUNvbG9yKFN0cmluZyBib3JkZXJCb3R0b21Db2xvcikKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBib3JkZXItbGVmdC1jb2xvciBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRCb3JkZXJMZWZ0Q29sb3IoKTsKLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBib3JkZXItbGVmdC1jb2xvciBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIFNZTlRBWF9FUlI6IFJhaXNlZCBpZiB0aGUgbmV3IHZhbHVlIGhhcyBhIHN5bnRheCBlcnJvciBhbmQgaXMKLSAgICAgKiAgIHVucGFyc2FibGUuCi0gICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBwcm9wZXJ0eSBpcyByZWFkb25seS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRCb3JkZXJMZWZ0Q29sb3IoU3RyaW5nIGJvcmRlckxlZnRDb2xvcikKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBib3JkZXItdG9wLXN0eWxlIHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEJvcmRlclRvcFN0eWxlKCk7Ci0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgYm9yZGVyLXRvcC1zdHlsZSBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIFNZTlRBWF9FUlI6IFJhaXNlZCBpZiB0aGUgbmV3IHZhbHVlIGhhcyBhIHN5bnRheCBlcnJvciBhbmQgaXMKLSAgICAgKiAgIHVucGFyc2FibGUuCi0gICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBwcm9wZXJ0eSBpcyByZWFkb25seS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRCb3JkZXJUb3BTdHlsZShTdHJpbmcgYm9yZGVyVG9wU3R5bGUpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgYm9yZGVyLXJpZ2h0LXN0eWxlIHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEJvcmRlclJpZ2h0U3R5bGUoKTsKLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBib3JkZXItcmlnaHQtc3R5bGUgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBTWU5UQVhfRVJSOiBSYWlzZWQgaWYgdGhlIG5ldyB2YWx1ZSBoYXMgYSBzeW50YXggZXJyb3IgYW5kIGlzCi0gICAgICogICB1bnBhcnNhYmxlLgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgcHJvcGVydHkgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0Qm9yZGVyUmlnaHRTdHlsZShTdHJpbmcgYm9yZGVyUmlnaHRTdHlsZSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBib3JkZXItYm90dG9tLXN0eWxlIHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEJvcmRlckJvdHRvbVN0eWxlKCk7Ci0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgYm9yZGVyLWJvdHRvbS1zdHlsZSBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIFNZTlRBWF9FUlI6IFJhaXNlZCBpZiB0aGUgbmV3IHZhbHVlIGhhcyBhIHN5bnRheCBlcnJvciBhbmQgaXMKLSAgICAgKiAgIHVucGFyc2FibGUuCi0gICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBwcm9wZXJ0eSBpcyByZWFkb25seS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRCb3JkZXJCb3R0b21TdHlsZShTdHJpbmcgYm9yZGVyQm90dG9tU3R5bGUpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgYm9yZGVyLWxlZnQtc3R5bGUgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Qm9yZGVyTGVmdFN0eWxlKCk7Ci0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgYm9yZGVyLWxlZnQtc3R5bGUgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBTWU5UQVhfRVJSOiBSYWlzZWQgaWYgdGhlIG5ldyB2YWx1ZSBoYXMgYSBzeW50YXggZXJyb3IgYW5kIGlzCi0gICAgICogICB1bnBhcnNhYmxlLgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgcHJvcGVydHkgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0Qm9yZGVyTGVmdFN0eWxlKFN0cmluZyBib3JkZXJMZWZ0U3R5bGUpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgYm9yZGVyLXRvcC13aWR0aCBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRCb3JkZXJUb3BXaWR0aCgpOwotICAgIC8qKgotICAgICAqICBTZWUgdGhlIGJvcmRlci10b3Atd2lkdGggcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBTWU5UQVhfRVJSOiBSYWlzZWQgaWYgdGhlIG5ldyB2YWx1ZSBoYXMgYSBzeW50YXggZXJyb3IgYW5kIGlzCi0gICAgICogICB1bnBhcnNhYmxlLgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgcHJvcGVydHkgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0Qm9yZGVyVG9wV2lkdGgoU3RyaW5nIGJvcmRlclRvcFdpZHRoKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBTZWUgdGhlIGJvcmRlci1yaWdodC13aWR0aCBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRCb3JkZXJSaWdodFdpZHRoKCk7Ci0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgYm9yZGVyLXJpZ2h0LXdpZHRoIHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgU1lOVEFYX0VSUjogUmFpc2VkIGlmIHRoZSBuZXcgdmFsdWUgaGFzIGEgc3ludGF4IGVycm9yIGFuZCBpcwotICAgICAqICAgdW5wYXJzYWJsZS4KLSAgICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIHByb3BlcnR5IGlzIHJlYWRvbmx5LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEJvcmRlclJpZ2h0V2lkdGgoU3RyaW5nIGJvcmRlclJpZ2h0V2lkdGgpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgYm9yZGVyLWJvdHRvbS13aWR0aCBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRCb3JkZXJCb3R0b21XaWR0aCgpOwotICAgIC8qKgotICAgICAqICBTZWUgdGhlIGJvcmRlci1ib3R0b20td2lkdGggcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBTWU5UQVhfRVJSOiBSYWlzZWQgaWYgdGhlIG5ldyB2YWx1ZSBoYXMgYSBzeW50YXggZXJyb3IgYW5kIGlzCi0gICAgICogICB1bnBhcnNhYmxlLgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgcHJvcGVydHkgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0Qm9yZGVyQm90dG9tV2lkdGgoU3RyaW5nIGJvcmRlckJvdHRvbVdpZHRoKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBTZWUgdGhlIGJvcmRlci1sZWZ0LXdpZHRoIHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEJvcmRlckxlZnRXaWR0aCgpOwotICAgIC8qKgotICAgICAqICBTZWUgdGhlIGJvcmRlci1sZWZ0LXdpZHRoIHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgU1lOVEFYX0VSUjogUmFpc2VkIGlmIHRoZSBuZXcgdmFsdWUgaGFzIGEgc3ludGF4IGVycm9yIGFuZCBpcwotICAgICAqICAgdW5wYXJzYWJsZS4KLSAgICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIHByb3BlcnR5IGlzIHJlYWRvbmx5LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEJvcmRlckxlZnRXaWR0aChTdHJpbmcgYm9yZGVyTGVmdFdpZHRoKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBTZWUgdGhlIGJvcmRlci13aWR0aCBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRCb3JkZXJXaWR0aCgpOwotICAgIC8qKgotICAgICAqICBTZWUgdGhlIGJvcmRlci13aWR0aCBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIFNZTlRBWF9FUlI6IFJhaXNlZCBpZiB0aGUgbmV3IHZhbHVlIGhhcyBhIHN5bnRheCBlcnJvciBhbmQgaXMKLSAgICAgKiAgIHVucGFyc2FibGUuCi0gICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBwcm9wZXJ0eSBpcyByZWFkb25seS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRCb3JkZXJXaWR0aChTdHJpbmcgYm9yZGVyV2lkdGgpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgYm90dG9tIHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEJvdHRvbSgpOwotICAgIC8qKgotICAgICAqICBTZWUgdGhlIGJvdHRvbSBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIFNZTlRBWF9FUlI6IFJhaXNlZCBpZiB0aGUgbmV3IHZhbHVlIGhhcyBhIHN5bnRheCBlcnJvciBhbmQgaXMKLSAgICAgKiAgIHVucGFyc2FibGUuCi0gICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBwcm9wZXJ0eSBpcyByZWFkb25seS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRCb3R0b20oU3RyaW5nIGJvdHRvbSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBjYXB0aW9uLXNpZGUgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q2FwdGlvblNpZGUoKTsKLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBjYXB0aW9uLXNpZGUgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBTWU5UQVhfRVJSOiBSYWlzZWQgaWYgdGhlIG5ldyB2YWx1ZSBoYXMgYSBzeW50YXggZXJyb3IgYW5kIGlzCi0gICAgICogICB1bnBhcnNhYmxlLgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgcHJvcGVydHkgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0Q2FwdGlvblNpZGUoU3RyaW5nIGNhcHRpb25TaWRlKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBTZWUgdGhlIGNsZWFyIHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldENsZWFyKCk7Ci0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgY2xlYXIgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBTWU5UQVhfRVJSOiBSYWlzZWQgaWYgdGhlIG5ldyB2YWx1ZSBoYXMgYSBzeW50YXggZXJyb3IgYW5kIGlzCi0gICAgICogICB1bnBhcnNhYmxlLgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgcHJvcGVydHkgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0Q2xlYXIoU3RyaW5nIGNsZWFyKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBTZWUgdGhlIGNsaXAgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q2xpcCgpOwotICAgIC8qKgotICAgICAqICBTZWUgdGhlIGNsaXAgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBTWU5UQVhfRVJSOiBSYWlzZWQgaWYgdGhlIG5ldyB2YWx1ZSBoYXMgYSBzeW50YXggZXJyb3IgYW5kIGlzCi0gICAgICogICB1bnBhcnNhYmxlLgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgcHJvcGVydHkgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0Q2xpcChTdHJpbmcgY2xpcCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBjb2xvciBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRDb2xvcigpOwotICAgIC8qKgotICAgICAqICBTZWUgdGhlIGNvbG9yIHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgU1lOVEFYX0VSUjogUmFpc2VkIGlmIHRoZSBuZXcgdmFsdWUgaGFzIGEgc3ludGF4IGVycm9yIGFuZCBpcwotICAgICAqICAgdW5wYXJzYWJsZS4KLSAgICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIHByb3BlcnR5IGlzIHJlYWRvbmx5LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldENvbG9yKFN0cmluZyBjb2xvcikKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBjb250ZW50IHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldENvbnRlbnQoKTsKLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBjb250ZW50IHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgU1lOVEFYX0VSUjogUmFpc2VkIGlmIHRoZSBuZXcgdmFsdWUgaGFzIGEgc3ludGF4IGVycm9yIGFuZCBpcwotICAgICAqICAgdW5wYXJzYWJsZS4KLSAgICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIHByb3BlcnR5IGlzIHJlYWRvbmx5LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldENvbnRlbnQoU3RyaW5nIGNvbnRlbnQpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgY291bnRlci1pbmNyZW1lbnQgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q291bnRlckluY3JlbWVudCgpOwotICAgIC8qKgotICAgICAqICBTZWUgdGhlIGNvdW50ZXItaW5jcmVtZW50IHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgU1lOVEFYX0VSUjogUmFpc2VkIGlmIHRoZSBuZXcgdmFsdWUgaGFzIGEgc3ludGF4IGVycm9yIGFuZCBpcwotICAgICAqICAgdW5wYXJzYWJsZS4KLSAgICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIHByb3BlcnR5IGlzIHJlYWRvbmx5LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldENvdW50ZXJJbmNyZW1lbnQoU3RyaW5nIGNvdW50ZXJJbmNyZW1lbnQpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgY291bnRlci1yZXNldCBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRDb3VudGVyUmVzZXQoKTsKLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBjb3VudGVyLXJlc2V0IHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgU1lOVEFYX0VSUjogUmFpc2VkIGlmIHRoZSBuZXcgdmFsdWUgaGFzIGEgc3ludGF4IGVycm9yIGFuZCBpcwotICAgICAqICAgdW5wYXJzYWJsZS4KLSAgICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIHByb3BlcnR5IGlzIHJlYWRvbmx5LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldENvdW50ZXJSZXNldChTdHJpbmcgY291bnRlclJlc2V0KQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBTZWUgdGhlIGN1ZSBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRDdWUoKTsKLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBjdWUgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBTWU5UQVhfRVJSOiBSYWlzZWQgaWYgdGhlIG5ldyB2YWx1ZSBoYXMgYSBzeW50YXggZXJyb3IgYW5kIGlzCi0gICAgICogICB1bnBhcnNhYmxlLgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgcHJvcGVydHkgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0Q3VlKFN0cmluZyBjdWUpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgY3VlLWFmdGVyIHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEN1ZUFmdGVyKCk7Ci0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgY3VlLWFmdGVyIHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgU1lOVEFYX0VSUjogUmFpc2VkIGlmIHRoZSBuZXcgdmFsdWUgaGFzIGEgc3ludGF4IGVycm9yIGFuZCBpcwotICAgICAqICAgdW5wYXJzYWJsZS4KLSAgICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIHByb3BlcnR5IGlzIHJlYWRvbmx5LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEN1ZUFmdGVyKFN0cmluZyBjdWVBZnRlcikKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBjdWUtYmVmb3JlIHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEN1ZUJlZm9yZSgpOwotICAgIC8qKgotICAgICAqICBTZWUgdGhlIGN1ZS1iZWZvcmUgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBTWU5UQVhfRVJSOiBSYWlzZWQgaWYgdGhlIG5ldyB2YWx1ZSBoYXMgYSBzeW50YXggZXJyb3IgYW5kIGlzCi0gICAgICogICB1bnBhcnNhYmxlLgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgcHJvcGVydHkgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0Q3VlQmVmb3JlKFN0cmluZyBjdWVCZWZvcmUpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgY3Vyc29yIHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEN1cnNvcigpOwotICAgIC8qKgotICAgICAqICBTZWUgdGhlIGN1cnNvciBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIFNZTlRBWF9FUlI6IFJhaXNlZCBpZiB0aGUgbmV3IHZhbHVlIGhhcyBhIHN5bnRheCBlcnJvciBhbmQgaXMKLSAgICAgKiAgIHVucGFyc2FibGUuCi0gICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBwcm9wZXJ0eSBpcyByZWFkb25seS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRDdXJzb3IoU3RyaW5nIGN1cnNvcikKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBkaXJlY3Rpb24gcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0RGlyZWN0aW9uKCk7Ci0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgZGlyZWN0aW9uIHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgU1lOVEFYX0VSUjogUmFpc2VkIGlmIHRoZSBuZXcgdmFsdWUgaGFzIGEgc3ludGF4IGVycm9yIGFuZCBpcwotICAgICAqICAgdW5wYXJzYWJsZS4KLSAgICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIHByb3BlcnR5IGlzIHJlYWRvbmx5LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldERpcmVjdGlvbihTdHJpbmcgZGlyZWN0aW9uKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBTZWUgdGhlIGRpc3BsYXkgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0RGlzcGxheSgpOwotICAgIC8qKgotICAgICAqICBTZWUgdGhlIGRpc3BsYXkgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBTWU5UQVhfRVJSOiBSYWlzZWQgaWYgdGhlIG5ldyB2YWx1ZSBoYXMgYSBzeW50YXggZXJyb3IgYW5kIGlzCi0gICAgICogICB1bnBhcnNhYmxlLgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgcHJvcGVydHkgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RGlzcGxheShTdHJpbmcgZGlzcGxheSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBlbGV2YXRpb24gcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0RWxldmF0aW9uKCk7Ci0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgZWxldmF0aW9uIHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgU1lOVEFYX0VSUjogUmFpc2VkIGlmIHRoZSBuZXcgdmFsdWUgaGFzIGEgc3ludGF4IGVycm9yIGFuZCBpcwotICAgICAqICAgdW5wYXJzYWJsZS4KLSAgICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIHByb3BlcnR5IGlzIHJlYWRvbmx5LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEVsZXZhdGlvbihTdHJpbmcgZWxldmF0aW9uKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBTZWUgdGhlIGVtcHR5LWNlbGxzIHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEVtcHR5Q2VsbHMoKTsKLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBlbXB0eS1jZWxscyBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIFNZTlRBWF9FUlI6IFJhaXNlZCBpZiB0aGUgbmV3IHZhbHVlIGhhcyBhIHN5bnRheCBlcnJvciBhbmQgaXMKLSAgICAgKiAgIHVucGFyc2FibGUuCi0gICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBwcm9wZXJ0eSBpcyByZWFkb25seS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRFbXB0eUNlbGxzKFN0cmluZyBlbXB0eUNlbGxzKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBTZWUgdGhlIGZsb2F0IHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldENzc0Zsb2F0KCk7Ci0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgZmxvYXQgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBTWU5UQVhfRVJSOiBSYWlzZWQgaWYgdGhlIG5ldyB2YWx1ZSBoYXMgYSBzeW50YXggZXJyb3IgYW5kIGlzCi0gICAgICogICB1bnBhcnNhYmxlLgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgcHJvcGVydHkgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0Q3NzRmxvYXQoU3RyaW5nIGNzc0Zsb2F0KQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBTZWUgdGhlIGZvbnQgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Rm9udCgpOwotICAgIC8qKgotICAgICAqICBTZWUgdGhlIGZvbnQgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBTWU5UQVhfRVJSOiBSYWlzZWQgaWYgdGhlIG5ldyB2YWx1ZSBoYXMgYSBzeW50YXggZXJyb3IgYW5kIGlzCi0gICAgICogICB1bnBhcnNhYmxlLgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgcHJvcGVydHkgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0Rm9udChTdHJpbmcgZm9udCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBmb250LWZhbWlseSBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRGb250RmFtaWx5KCk7Ci0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgZm9udC1mYW1pbHkgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBTWU5UQVhfRVJSOiBSYWlzZWQgaWYgdGhlIG5ldyB2YWx1ZSBoYXMgYSBzeW50YXggZXJyb3IgYW5kIGlzCi0gICAgICogICB1bnBhcnNhYmxlLgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgcHJvcGVydHkgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0Rm9udEZhbWlseShTdHJpbmcgZm9udEZhbWlseSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBmb250LXNpemUgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Rm9udFNpemUoKTsKLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBmb250LXNpemUgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBTWU5UQVhfRVJSOiBSYWlzZWQgaWYgdGhlIG5ldyB2YWx1ZSBoYXMgYSBzeW50YXggZXJyb3IgYW5kIGlzCi0gICAgICogICB1bnBhcnNhYmxlLgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgcHJvcGVydHkgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0Rm9udFNpemUoU3RyaW5nIGZvbnRTaXplKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBTZWUgdGhlIGZvbnQtc2l6ZS1hZGp1c3QgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Rm9udFNpemVBZGp1c3QoKTsKLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBmb250LXNpemUtYWRqdXN0IHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgU1lOVEFYX0VSUjogUmFpc2VkIGlmIHRoZSBuZXcgdmFsdWUgaGFzIGEgc3ludGF4IGVycm9yIGFuZCBpcwotICAgICAqICAgdW5wYXJzYWJsZS4KLSAgICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIHByb3BlcnR5IGlzIHJlYWRvbmx5LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEZvbnRTaXplQWRqdXN0KFN0cmluZyBmb250U2l6ZUFkanVzdCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBmb250LXN0cmV0Y2ggcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Rm9udFN0cmV0Y2goKTsKLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBmb250LXN0cmV0Y2ggcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBTWU5UQVhfRVJSOiBSYWlzZWQgaWYgdGhlIG5ldyB2YWx1ZSBoYXMgYSBzeW50YXggZXJyb3IgYW5kIGlzCi0gICAgICogICB1bnBhcnNhYmxlLgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgcHJvcGVydHkgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0Rm9udFN0cmV0Y2goU3RyaW5nIGZvbnRTdHJldGNoKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBTZWUgdGhlIGZvbnQtc3R5bGUgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Rm9udFN0eWxlKCk7Ci0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgZm9udC1zdHlsZSBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIFNZTlRBWF9FUlI6IFJhaXNlZCBpZiB0aGUgbmV3IHZhbHVlIGhhcyBhIHN5bnRheCBlcnJvciBhbmQgaXMKLSAgICAgKiAgIHVucGFyc2FibGUuCi0gICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBwcm9wZXJ0eSBpcyByZWFkb25seS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRGb250U3R5bGUoU3RyaW5nIGZvbnRTdHlsZSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBmb250LXZhcmlhbnQgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Rm9udFZhcmlhbnQoKTsKLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBmb250LXZhcmlhbnQgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBTWU5UQVhfRVJSOiBSYWlzZWQgaWYgdGhlIG5ldyB2YWx1ZSBoYXMgYSBzeW50YXggZXJyb3IgYW5kIGlzCi0gICAgICogICB1bnBhcnNhYmxlLgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgcHJvcGVydHkgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0Rm9udFZhcmlhbnQoU3RyaW5nIGZvbnRWYXJpYW50KQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBTZWUgdGhlIGZvbnQtd2VpZ2h0IHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEZvbnRXZWlnaHQoKTsKLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBmb250LXdlaWdodCBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIFNZTlRBWF9FUlI6IFJhaXNlZCBpZiB0aGUgbmV3IHZhbHVlIGhhcyBhIHN5bnRheCBlcnJvciBhbmQgaXMKLSAgICAgKiAgIHVucGFyc2FibGUuCi0gICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBwcm9wZXJ0eSBpcyByZWFkb25seS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRGb250V2VpZ2h0KFN0cmluZyBmb250V2VpZ2h0KQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBTZWUgdGhlIGhlaWdodCBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRIZWlnaHQoKTsKLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBoZWlnaHQgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBTWU5UQVhfRVJSOiBSYWlzZWQgaWYgdGhlIG5ldyB2YWx1ZSBoYXMgYSBzeW50YXggZXJyb3IgYW5kIGlzCi0gICAgICogICB1bnBhcnNhYmxlLgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgcHJvcGVydHkgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0SGVpZ2h0KFN0cmluZyBoZWlnaHQpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgbGVmdCBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRMZWZ0KCk7Ci0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgbGVmdCBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIFNZTlRBWF9FUlI6IFJhaXNlZCBpZiB0aGUgbmV3IHZhbHVlIGhhcyBhIHN5bnRheCBlcnJvciBhbmQgaXMKLSAgICAgKiAgIHVucGFyc2FibGUuCi0gICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBwcm9wZXJ0eSBpcyByZWFkb25seS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRMZWZ0KFN0cmluZyBsZWZ0KQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBTZWUgdGhlIGxldHRlci1zcGFjaW5nIHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldExldHRlclNwYWNpbmcoKTsKLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBsZXR0ZXItc3BhY2luZyBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIFNZTlRBWF9FUlI6IFJhaXNlZCBpZiB0aGUgbmV3IHZhbHVlIGhhcyBhIHN5bnRheCBlcnJvciBhbmQgaXMKLSAgICAgKiAgIHVucGFyc2FibGUuCi0gICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBwcm9wZXJ0eSBpcyByZWFkb25seS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRMZXR0ZXJTcGFjaW5nKFN0cmluZyBsZXR0ZXJTcGFjaW5nKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBTZWUgdGhlIGxpbmUtaGVpZ2h0IHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldExpbmVIZWlnaHQoKTsKLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBsaW5lLWhlaWdodCBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIFNZTlRBWF9FUlI6IFJhaXNlZCBpZiB0aGUgbmV3IHZhbHVlIGhhcyBhIHN5bnRheCBlcnJvciBhbmQgaXMKLSAgICAgKiAgIHVucGFyc2FibGUuCi0gICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBwcm9wZXJ0eSBpcyByZWFkb25seS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRMaW5lSGVpZ2h0KFN0cmluZyBsaW5lSGVpZ2h0KQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBTZWUgdGhlIGxpc3Qtc3R5bGUgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TGlzdFN0eWxlKCk7Ci0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgbGlzdC1zdHlsZSBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIFNZTlRBWF9FUlI6IFJhaXNlZCBpZiB0aGUgbmV3IHZhbHVlIGhhcyBhIHN5bnRheCBlcnJvciBhbmQgaXMKLSAgICAgKiAgIHVucGFyc2FibGUuCi0gICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBwcm9wZXJ0eSBpcyByZWFkb25seS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRMaXN0U3R5bGUoU3RyaW5nIGxpc3RTdHlsZSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBsaXN0LXN0eWxlLWltYWdlIHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldExpc3RTdHlsZUltYWdlKCk7Ci0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgbGlzdC1zdHlsZS1pbWFnZSBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIFNZTlRBWF9FUlI6IFJhaXNlZCBpZiB0aGUgbmV3IHZhbHVlIGhhcyBhIHN5bnRheCBlcnJvciBhbmQgaXMKLSAgICAgKiAgIHVucGFyc2FibGUuCi0gICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBwcm9wZXJ0eSBpcyByZWFkb25seS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRMaXN0U3R5bGVJbWFnZShTdHJpbmcgbGlzdFN0eWxlSW1hZ2UpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgbGlzdC1zdHlsZS1wb3NpdGlvbiBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRMaXN0U3R5bGVQb3NpdGlvbigpOwotICAgIC8qKgotICAgICAqICBTZWUgdGhlIGxpc3Qtc3R5bGUtcG9zaXRpb24gcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBTWU5UQVhfRVJSOiBSYWlzZWQgaWYgdGhlIG5ldyB2YWx1ZSBoYXMgYSBzeW50YXggZXJyb3IgYW5kIGlzCi0gICAgICogICB1bnBhcnNhYmxlLgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgcHJvcGVydHkgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0TGlzdFN0eWxlUG9zaXRpb24oU3RyaW5nIGxpc3RTdHlsZVBvc2l0aW9uKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBTZWUgdGhlIGxpc3Qtc3R5bGUtdHlwZSBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRMaXN0U3R5bGVUeXBlKCk7Ci0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgbGlzdC1zdHlsZS10eXBlIHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgU1lOVEFYX0VSUjogUmFpc2VkIGlmIHRoZSBuZXcgdmFsdWUgaGFzIGEgc3ludGF4IGVycm9yIGFuZCBpcwotICAgICAqICAgdW5wYXJzYWJsZS4KLSAgICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIHByb3BlcnR5IGlzIHJlYWRvbmx5LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldExpc3RTdHlsZVR5cGUoU3RyaW5nIGxpc3RTdHlsZVR5cGUpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgbWFyZ2luIHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE1hcmdpbigpOwotICAgIC8qKgotICAgICAqICBTZWUgdGhlIG1hcmdpbiBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIFNZTlRBWF9FUlI6IFJhaXNlZCBpZiB0aGUgbmV3IHZhbHVlIGhhcyBhIHN5bnRheCBlcnJvciBhbmQgaXMKLSAgICAgKiAgIHVucGFyc2FibGUuCi0gICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBwcm9wZXJ0eSBpcyByZWFkb25seS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRNYXJnaW4oU3RyaW5nIG1hcmdpbikKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBtYXJnaW4tdG9wIHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE1hcmdpblRvcCgpOwotICAgIC8qKgotICAgICAqICBTZWUgdGhlIG1hcmdpbi10b3AgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBTWU5UQVhfRVJSOiBSYWlzZWQgaWYgdGhlIG5ldyB2YWx1ZSBoYXMgYSBzeW50YXggZXJyb3IgYW5kIGlzCi0gICAgICogICB1bnBhcnNhYmxlLgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgcHJvcGVydHkgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0TWFyZ2luVG9wKFN0cmluZyBtYXJnaW5Ub3ApCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgbWFyZ2luLXJpZ2h0IHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE1hcmdpblJpZ2h0KCk7Ci0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgbWFyZ2luLXJpZ2h0IHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgU1lOVEFYX0VSUjogUmFpc2VkIGlmIHRoZSBuZXcgdmFsdWUgaGFzIGEgc3ludGF4IGVycm9yIGFuZCBpcwotICAgICAqICAgdW5wYXJzYWJsZS4KLSAgICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIHByb3BlcnR5IGlzIHJlYWRvbmx5LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldE1hcmdpblJpZ2h0KFN0cmluZyBtYXJnaW5SaWdodCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBtYXJnaW4tYm90dG9tIHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE1hcmdpbkJvdHRvbSgpOwotICAgIC8qKgotICAgICAqICBTZWUgdGhlIG1hcmdpbi1ib3R0b20gcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBTWU5UQVhfRVJSOiBSYWlzZWQgaWYgdGhlIG5ldyB2YWx1ZSBoYXMgYSBzeW50YXggZXJyb3IgYW5kIGlzCi0gICAgICogICB1bnBhcnNhYmxlLgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgcHJvcGVydHkgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0TWFyZ2luQm90dG9tKFN0cmluZyBtYXJnaW5Cb3R0b20pCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgbWFyZ2luLWxlZnQgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TWFyZ2luTGVmdCgpOwotICAgIC8qKgotICAgICAqICBTZWUgdGhlIG1hcmdpbi1sZWZ0IHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgU1lOVEFYX0VSUjogUmFpc2VkIGlmIHRoZSBuZXcgdmFsdWUgaGFzIGEgc3ludGF4IGVycm9yIGFuZCBpcwotICAgICAqICAgdW5wYXJzYWJsZS4KLSAgICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIHByb3BlcnR5IGlzIHJlYWRvbmx5LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldE1hcmdpbkxlZnQoU3RyaW5nIG1hcmdpbkxlZnQpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgbWFya2VyLW9mZnNldCBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRNYXJrZXJPZmZzZXQoKTsKLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBtYXJrZXItb2Zmc2V0IHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgU1lOVEFYX0VSUjogUmFpc2VkIGlmIHRoZSBuZXcgdmFsdWUgaGFzIGEgc3ludGF4IGVycm9yIGFuZCBpcwotICAgICAqICAgdW5wYXJzYWJsZS4KLSAgICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIHByb3BlcnR5IGlzIHJlYWRvbmx5LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldE1hcmtlck9mZnNldChTdHJpbmcgbWFya2VyT2Zmc2V0KQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBTZWUgdGhlIG1hcmtzIHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE1hcmtzKCk7Ci0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgbWFya3MgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBTWU5UQVhfRVJSOiBSYWlzZWQgaWYgdGhlIG5ldyB2YWx1ZSBoYXMgYSBzeW50YXggZXJyb3IgYW5kIGlzCi0gICAgICogICB1bnBhcnNhYmxlLgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgcHJvcGVydHkgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0TWFya3MoU3RyaW5nIG1hcmtzKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBTZWUgdGhlIG1heC1oZWlnaHQgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TWF4SGVpZ2h0KCk7Ci0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgbWF4LWhlaWdodCBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIFNZTlRBWF9FUlI6IFJhaXNlZCBpZiB0aGUgbmV3IHZhbHVlIGhhcyBhIHN5bnRheCBlcnJvciBhbmQgaXMKLSAgICAgKiAgIHVucGFyc2FibGUuCi0gICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBwcm9wZXJ0eSBpcyByZWFkb25seS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRNYXhIZWlnaHQoU3RyaW5nIG1heEhlaWdodCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBtYXgtd2lkdGggcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TWF4V2lkdGgoKTsKLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBtYXgtd2lkdGggcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBTWU5UQVhfRVJSOiBSYWlzZWQgaWYgdGhlIG5ldyB2YWx1ZSBoYXMgYSBzeW50YXggZXJyb3IgYW5kIGlzCi0gICAgICogICB1bnBhcnNhYmxlLgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgcHJvcGVydHkgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0TWF4V2lkdGgoU3RyaW5nIG1heFdpZHRoKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBTZWUgdGhlIG1pbi1oZWlnaHQgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TWluSGVpZ2h0KCk7Ci0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgbWluLWhlaWdodCBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIFNZTlRBWF9FUlI6IFJhaXNlZCBpZiB0aGUgbmV3IHZhbHVlIGhhcyBhIHN5bnRheCBlcnJvciBhbmQgaXMKLSAgICAgKiAgIHVucGFyc2FibGUuCi0gICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBwcm9wZXJ0eSBpcyByZWFkb25seS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRNaW5IZWlnaHQoU3RyaW5nIG1pbkhlaWdodCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBtaW4td2lkdGggcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TWluV2lkdGgoKTsKLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBtaW4td2lkdGggcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBTWU5UQVhfRVJSOiBSYWlzZWQgaWYgdGhlIG5ldyB2YWx1ZSBoYXMgYSBzeW50YXggZXJyb3IgYW5kIGlzCi0gICAgICogICB1bnBhcnNhYmxlLgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgcHJvcGVydHkgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0TWluV2lkdGgoU3RyaW5nIG1pbldpZHRoKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBTZWUgdGhlIG9ycGhhbnMgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0T3JwaGFucygpOwotICAgIC8qKgotICAgICAqICBTZWUgdGhlIG9ycGhhbnMgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBTWU5UQVhfRVJSOiBSYWlzZWQgaWYgdGhlIG5ldyB2YWx1ZSBoYXMgYSBzeW50YXggZXJyb3IgYW5kIGlzCi0gICAgICogICB1bnBhcnNhYmxlLgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgcHJvcGVydHkgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0T3JwaGFucyhTdHJpbmcgb3JwaGFucykKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBvdXRsaW5lIHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE91dGxpbmUoKTsKLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBvdXRsaW5lIHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgU1lOVEFYX0VSUjogUmFpc2VkIGlmIHRoZSBuZXcgdmFsdWUgaGFzIGEgc3ludGF4IGVycm9yIGFuZCBpcwotICAgICAqICAgdW5wYXJzYWJsZS4KLSAgICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIHByb3BlcnR5IGlzIHJlYWRvbmx5LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldE91dGxpbmUoU3RyaW5nIG91dGxpbmUpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgb3V0bGluZS1jb2xvciBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRPdXRsaW5lQ29sb3IoKTsKLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBvdXRsaW5lLWNvbG9yIHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgU1lOVEFYX0VSUjogUmFpc2VkIGlmIHRoZSBuZXcgdmFsdWUgaGFzIGEgc3ludGF4IGVycm9yIGFuZCBpcwotICAgICAqICAgdW5wYXJzYWJsZS4KLSAgICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIHByb3BlcnR5IGlzIHJlYWRvbmx5LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldE91dGxpbmVDb2xvcihTdHJpbmcgb3V0bGluZUNvbG9yKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBTZWUgdGhlIG91dGxpbmUtc3R5bGUgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0T3V0bGluZVN0eWxlKCk7Ci0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgb3V0bGluZS1zdHlsZSBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIFNZTlRBWF9FUlI6IFJhaXNlZCBpZiB0aGUgbmV3IHZhbHVlIGhhcyBhIHN5bnRheCBlcnJvciBhbmQgaXMKLSAgICAgKiAgIHVucGFyc2FibGUuCi0gICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBwcm9wZXJ0eSBpcyByZWFkb25seS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRPdXRsaW5lU3R5bGUoU3RyaW5nIG91dGxpbmVTdHlsZSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBvdXRsaW5lLXdpZHRoIHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE91dGxpbmVXaWR0aCgpOwotICAgIC8qKgotICAgICAqICBTZWUgdGhlIG91dGxpbmUtd2lkdGggcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBTWU5UQVhfRVJSOiBSYWlzZWQgaWYgdGhlIG5ldyB2YWx1ZSBoYXMgYSBzeW50YXggZXJyb3IgYW5kIGlzCi0gICAgICogICB1bnBhcnNhYmxlLgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgcHJvcGVydHkgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0T3V0bGluZVdpZHRoKFN0cmluZyBvdXRsaW5lV2lkdGgpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgb3ZlcmZsb3cgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0T3ZlcmZsb3coKTsKLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBvdmVyZmxvdyBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIFNZTlRBWF9FUlI6IFJhaXNlZCBpZiB0aGUgbmV3IHZhbHVlIGhhcyBhIHN5bnRheCBlcnJvciBhbmQgaXMKLSAgICAgKiAgIHVucGFyc2FibGUuCi0gICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBwcm9wZXJ0eSBpcyByZWFkb25seS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRPdmVyZmxvdyhTdHJpbmcgb3ZlcmZsb3cpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgcGFkZGluZyBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRQYWRkaW5nKCk7Ci0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgcGFkZGluZyBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIFNZTlRBWF9FUlI6IFJhaXNlZCBpZiB0aGUgbmV3IHZhbHVlIGhhcyBhIHN5bnRheCBlcnJvciBhbmQgaXMKLSAgICAgKiAgIHVucGFyc2FibGUuCi0gICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBwcm9wZXJ0eSBpcyByZWFkb25seS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRQYWRkaW5nKFN0cmluZyBwYWRkaW5nKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBTZWUgdGhlIHBhZGRpbmctdG9wIHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFBhZGRpbmdUb3AoKTsKLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBwYWRkaW5nLXRvcCBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIFNZTlRBWF9FUlI6IFJhaXNlZCBpZiB0aGUgbmV3IHZhbHVlIGhhcyBhIHN5bnRheCBlcnJvciBhbmQgaXMKLSAgICAgKiAgIHVucGFyc2FibGUuCi0gICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBwcm9wZXJ0eSBpcyByZWFkb25seS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRQYWRkaW5nVG9wKFN0cmluZyBwYWRkaW5nVG9wKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBTZWUgdGhlIHBhZGRpbmctcmlnaHQgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0UGFkZGluZ1JpZ2h0KCk7Ci0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgcGFkZGluZy1yaWdodCBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIFNZTlRBWF9FUlI6IFJhaXNlZCBpZiB0aGUgbmV3IHZhbHVlIGhhcyBhIHN5bnRheCBlcnJvciBhbmQgaXMKLSAgICAgKiAgIHVucGFyc2FibGUuCi0gICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBwcm9wZXJ0eSBpcyByZWFkb25seS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRQYWRkaW5nUmlnaHQoU3RyaW5nIHBhZGRpbmdSaWdodCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBwYWRkaW5nLWJvdHRvbSBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRQYWRkaW5nQm90dG9tKCk7Ci0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgcGFkZGluZy1ib3R0b20gcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBTWU5UQVhfRVJSOiBSYWlzZWQgaWYgdGhlIG5ldyB2YWx1ZSBoYXMgYSBzeW50YXggZXJyb3IgYW5kIGlzCi0gICAgICogICB1bnBhcnNhYmxlLgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgcHJvcGVydHkgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0UGFkZGluZ0JvdHRvbShTdHJpbmcgcGFkZGluZ0JvdHRvbSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBwYWRkaW5nLWxlZnQgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0UGFkZGluZ0xlZnQoKTsKLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBwYWRkaW5nLWxlZnQgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBTWU5UQVhfRVJSOiBSYWlzZWQgaWYgdGhlIG5ldyB2YWx1ZSBoYXMgYSBzeW50YXggZXJyb3IgYW5kIGlzCi0gICAgICogICB1bnBhcnNhYmxlLgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgcHJvcGVydHkgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0UGFkZGluZ0xlZnQoU3RyaW5nIHBhZGRpbmdMZWZ0KQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBTZWUgdGhlIHBhZ2UgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0UGFnZSgpOwotICAgIC8qKgotICAgICAqICBTZWUgdGhlIHBhZ2UgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBTWU5UQVhfRVJSOiBSYWlzZWQgaWYgdGhlIG5ldyB2YWx1ZSBoYXMgYSBzeW50YXggZXJyb3IgYW5kIGlzCi0gICAgICogICB1bnBhcnNhYmxlLgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgcHJvcGVydHkgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0UGFnZShTdHJpbmcgcGFnZSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBwYWdlLWJyZWFrLWFmdGVyIHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFBhZ2VCcmVha0FmdGVyKCk7Ci0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgcGFnZS1icmVhay1hZnRlciBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIFNZTlRBWF9FUlI6IFJhaXNlZCBpZiB0aGUgbmV3IHZhbHVlIGhhcyBhIHN5bnRheCBlcnJvciBhbmQgaXMKLSAgICAgKiAgIHVucGFyc2FibGUuCi0gICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBwcm9wZXJ0eSBpcyByZWFkb25seS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRQYWdlQnJlYWtBZnRlcihTdHJpbmcgcGFnZUJyZWFrQWZ0ZXIpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgcGFnZS1icmVhay1iZWZvcmUgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0UGFnZUJyZWFrQmVmb3JlKCk7Ci0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgcGFnZS1icmVhay1iZWZvcmUgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBTWU5UQVhfRVJSOiBSYWlzZWQgaWYgdGhlIG5ldyB2YWx1ZSBoYXMgYSBzeW50YXggZXJyb3IgYW5kIGlzCi0gICAgICogICB1bnBhcnNhYmxlLgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgcHJvcGVydHkgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0UGFnZUJyZWFrQmVmb3JlKFN0cmluZyBwYWdlQnJlYWtCZWZvcmUpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgcGFnZS1icmVhay1pbnNpZGUgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0UGFnZUJyZWFrSW5zaWRlKCk7Ci0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgcGFnZS1icmVhay1pbnNpZGUgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBTWU5UQVhfRVJSOiBSYWlzZWQgaWYgdGhlIG5ldyB2YWx1ZSBoYXMgYSBzeW50YXggZXJyb3IgYW5kIGlzCi0gICAgICogICB1bnBhcnNhYmxlLgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgcHJvcGVydHkgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0UGFnZUJyZWFrSW5zaWRlKFN0cmluZyBwYWdlQnJlYWtJbnNpZGUpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgcGF1c2UgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0UGF1c2UoKTsKLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBwYXVzZSBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIFNZTlRBWF9FUlI6IFJhaXNlZCBpZiB0aGUgbmV3IHZhbHVlIGhhcyBhIHN5bnRheCBlcnJvciBhbmQgaXMKLSAgICAgKiAgIHVucGFyc2FibGUuCi0gICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBwcm9wZXJ0eSBpcyByZWFkb25seS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRQYXVzZShTdHJpbmcgcGF1c2UpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgcGF1c2UtYWZ0ZXIgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0UGF1c2VBZnRlcigpOwotICAgIC8qKgotICAgICAqICBTZWUgdGhlIHBhdXNlLWFmdGVyIHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgU1lOVEFYX0VSUjogUmFpc2VkIGlmIHRoZSBuZXcgdmFsdWUgaGFzIGEgc3ludGF4IGVycm9yIGFuZCBpcwotICAgICAqICAgdW5wYXJzYWJsZS4KLSAgICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIHByb3BlcnR5IGlzIHJlYWRvbmx5LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFBhdXNlQWZ0ZXIoU3RyaW5nIHBhdXNlQWZ0ZXIpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgcGF1c2UtYmVmb3JlIHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFBhdXNlQmVmb3JlKCk7Ci0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgcGF1c2UtYmVmb3JlIHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgU1lOVEFYX0VSUjogUmFpc2VkIGlmIHRoZSBuZXcgdmFsdWUgaGFzIGEgc3ludGF4IGVycm9yIGFuZCBpcwotICAgICAqICAgdW5wYXJzYWJsZS4KLSAgICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIHByb3BlcnR5IGlzIHJlYWRvbmx5LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFBhdXNlQmVmb3JlKFN0cmluZyBwYXVzZUJlZm9yZSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBwaXRjaCBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRQaXRjaCgpOwotICAgIC8qKgotICAgICAqICBTZWUgdGhlIHBpdGNoIHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgU1lOVEFYX0VSUjogUmFpc2VkIGlmIHRoZSBuZXcgdmFsdWUgaGFzIGEgc3ludGF4IGVycm9yIGFuZCBpcwotICAgICAqICAgdW5wYXJzYWJsZS4KLSAgICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIHByb3BlcnR5IGlzIHJlYWRvbmx5LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFBpdGNoKFN0cmluZyBwaXRjaCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBwaXRjaC1yYW5nZSBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRQaXRjaFJhbmdlKCk7Ci0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgcGl0Y2gtcmFuZ2UgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBTWU5UQVhfRVJSOiBSYWlzZWQgaWYgdGhlIG5ldyB2YWx1ZSBoYXMgYSBzeW50YXggZXJyb3IgYW5kIGlzCi0gICAgICogICB1bnBhcnNhYmxlLgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgcHJvcGVydHkgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0UGl0Y2hSYW5nZShTdHJpbmcgcGl0Y2hSYW5nZSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBwbGF5LWR1cmluZyBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRQbGF5RHVyaW5nKCk7Ci0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgcGxheS1kdXJpbmcgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBTWU5UQVhfRVJSOiBSYWlzZWQgaWYgdGhlIG5ldyB2YWx1ZSBoYXMgYSBzeW50YXggZXJyb3IgYW5kIGlzCi0gICAgICogICB1bnBhcnNhYmxlLgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgcHJvcGVydHkgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0UGxheUR1cmluZyhTdHJpbmcgcGxheUR1cmluZykKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBwb3NpdGlvbiBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRQb3NpdGlvbigpOwotICAgIC8qKgotICAgICAqICBTZWUgdGhlIHBvc2l0aW9uIHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgU1lOVEFYX0VSUjogUmFpc2VkIGlmIHRoZSBuZXcgdmFsdWUgaGFzIGEgc3ludGF4IGVycm9yIGFuZCBpcwotICAgICAqICAgdW5wYXJzYWJsZS4KLSAgICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIHByb3BlcnR5IGlzIHJlYWRvbmx5LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFBvc2l0aW9uKFN0cmluZyBwb3NpdGlvbikKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBxdW90ZXMgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0UXVvdGVzKCk7Ci0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgcXVvdGVzIHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgU1lOVEFYX0VSUjogUmFpc2VkIGlmIHRoZSBuZXcgdmFsdWUgaGFzIGEgc3ludGF4IGVycm9yIGFuZCBpcwotICAgICAqICAgdW5wYXJzYWJsZS4KLSAgICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIHByb3BlcnR5IGlzIHJlYWRvbmx5LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFF1b3RlcyhTdHJpbmcgcXVvdGVzKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBTZWUgdGhlIHJpY2huZXNzIHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFJpY2huZXNzKCk7Ci0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgcmljaG5lc3MgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBTWU5UQVhfRVJSOiBSYWlzZWQgaWYgdGhlIG5ldyB2YWx1ZSBoYXMgYSBzeW50YXggZXJyb3IgYW5kIGlzCi0gICAgICogICB1bnBhcnNhYmxlLgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgcHJvcGVydHkgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0UmljaG5lc3MoU3RyaW5nIHJpY2huZXNzKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBTZWUgdGhlIHJpZ2h0IHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFJpZ2h0KCk7Ci0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgcmlnaHQgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBTWU5UQVhfRVJSOiBSYWlzZWQgaWYgdGhlIG5ldyB2YWx1ZSBoYXMgYSBzeW50YXggZXJyb3IgYW5kIGlzCi0gICAgICogICB1bnBhcnNhYmxlLgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgcHJvcGVydHkgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0UmlnaHQoU3RyaW5nIHJpZ2h0KQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBTZWUgdGhlIHNpemUgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0U2l6ZSgpOwotICAgIC8qKgotICAgICAqICBTZWUgdGhlIHNpemUgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBTWU5UQVhfRVJSOiBSYWlzZWQgaWYgdGhlIG5ldyB2YWx1ZSBoYXMgYSBzeW50YXggZXJyb3IgYW5kIGlzCi0gICAgICogICB1bnBhcnNhYmxlLgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgcHJvcGVydHkgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0U2l6ZShTdHJpbmcgc2l6ZSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBzcGVhayBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRTcGVhaygpOwotICAgIC8qKgotICAgICAqICBTZWUgdGhlIHNwZWFrIHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgU1lOVEFYX0VSUjogUmFpc2VkIGlmIHRoZSBuZXcgdmFsdWUgaGFzIGEgc3ludGF4IGVycm9yIGFuZCBpcwotICAgICAqICAgdW5wYXJzYWJsZS4KLSAgICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIHByb3BlcnR5IGlzIHJlYWRvbmx5LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFNwZWFrKFN0cmluZyBzcGVhaykKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBzcGVhay1oZWFkZXIgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3BlYWtIZWFkZXIoKTsKLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBzcGVhay1oZWFkZXIgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBTWU5UQVhfRVJSOiBSYWlzZWQgaWYgdGhlIG5ldyB2YWx1ZSBoYXMgYSBzeW50YXggZXJyb3IgYW5kIGlzCi0gICAgICogICB1bnBhcnNhYmxlLgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgcHJvcGVydHkgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0U3BlYWtIZWFkZXIoU3RyaW5nIHNwZWFrSGVhZGVyKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBTZWUgdGhlIHNwZWFrLW51bWVyYWwgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3BlYWtOdW1lcmFsKCk7Ci0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgc3BlYWstbnVtZXJhbCBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIFNZTlRBWF9FUlI6IFJhaXNlZCBpZiB0aGUgbmV3IHZhbHVlIGhhcyBhIHN5bnRheCBlcnJvciBhbmQgaXMKLSAgICAgKiAgIHVucGFyc2FibGUuCi0gICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBwcm9wZXJ0eSBpcyByZWFkb25seS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRTcGVha051bWVyYWwoU3RyaW5nIHNwZWFrTnVtZXJhbCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBzcGVhay1wdW5jdHVhdGlvbiBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRTcGVha1B1bmN0dWF0aW9uKCk7Ci0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgc3BlYWstcHVuY3R1YXRpb24gcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBTWU5UQVhfRVJSOiBSYWlzZWQgaWYgdGhlIG5ldyB2YWx1ZSBoYXMgYSBzeW50YXggZXJyb3IgYW5kIGlzCi0gICAgICogICB1bnBhcnNhYmxlLgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgcHJvcGVydHkgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0U3BlYWtQdW5jdHVhdGlvbihTdHJpbmcgc3BlYWtQdW5jdHVhdGlvbikKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBzcGVlY2gtcmF0ZSBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRTcGVlY2hSYXRlKCk7Ci0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgc3BlZWNoLXJhdGUgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBTWU5UQVhfRVJSOiBSYWlzZWQgaWYgdGhlIG5ldyB2YWx1ZSBoYXMgYSBzeW50YXggZXJyb3IgYW5kIGlzCi0gICAgICogICB1bnBhcnNhYmxlLgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgcHJvcGVydHkgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0U3BlZWNoUmF0ZShTdHJpbmcgc3BlZWNoUmF0ZSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSBzdHJlc3MgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3RyZXNzKCk7Ci0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgc3RyZXNzIHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgU1lOVEFYX0VSUjogUmFpc2VkIGlmIHRoZSBuZXcgdmFsdWUgaGFzIGEgc3ludGF4IGVycm9yIGFuZCBpcwotICAgICAqICAgdW5wYXJzYWJsZS4KLSAgICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIHByb3BlcnR5IGlzIHJlYWRvbmx5LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFN0cmVzcyhTdHJpbmcgc3RyZXNzKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBTZWUgdGhlIHRhYmxlLWxheW91dCBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRUYWJsZUxheW91dCgpOwotICAgIC8qKgotICAgICAqICBTZWUgdGhlIHRhYmxlLWxheW91dCBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIFNZTlRBWF9FUlI6IFJhaXNlZCBpZiB0aGUgbmV3IHZhbHVlIGhhcyBhIHN5bnRheCBlcnJvciBhbmQgaXMKLSAgICAgKiAgIHVucGFyc2FibGUuCi0gICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBwcm9wZXJ0eSBpcyByZWFkb25seS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRUYWJsZUxheW91dChTdHJpbmcgdGFibGVMYXlvdXQpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgdGV4dC1hbGlnbiBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRUZXh0QWxpZ24oKTsKLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSB0ZXh0LWFsaWduIHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgU1lOVEFYX0VSUjogUmFpc2VkIGlmIHRoZSBuZXcgdmFsdWUgaGFzIGEgc3ludGF4IGVycm9yIGFuZCBpcwotICAgICAqICAgdW5wYXJzYWJsZS4KLSAgICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIHByb3BlcnR5IGlzIHJlYWRvbmx5LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFRleHRBbGlnbihTdHJpbmcgdGV4dEFsaWduKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBTZWUgdGhlIHRleHQtZGVjb3JhdGlvbiBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRUZXh0RGVjb3JhdGlvbigpOwotICAgIC8qKgotICAgICAqICBTZWUgdGhlIHRleHQtZGVjb3JhdGlvbiBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIFNZTlRBWF9FUlI6IFJhaXNlZCBpZiB0aGUgbmV3IHZhbHVlIGhhcyBhIHN5bnRheCBlcnJvciBhbmQgaXMKLSAgICAgKiAgIHVucGFyc2FibGUuCi0gICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBwcm9wZXJ0eSBpcyByZWFkb25seS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRUZXh0RGVjb3JhdGlvbihTdHJpbmcgdGV4dERlY29yYXRpb24pCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgdGV4dC1pbmRlbnQgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VGV4dEluZGVudCgpOwotICAgIC8qKgotICAgICAqICBTZWUgdGhlIHRleHQtaW5kZW50IHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgU1lOVEFYX0VSUjogUmFpc2VkIGlmIHRoZSBuZXcgdmFsdWUgaGFzIGEgc3ludGF4IGVycm9yIGFuZCBpcwotICAgICAqICAgdW5wYXJzYWJsZS4KLSAgICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIHByb3BlcnR5IGlzIHJlYWRvbmx5LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFRleHRJbmRlbnQoU3RyaW5nIHRleHRJbmRlbnQpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgdGV4dC1zaGFkb3cgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VGV4dFNoYWRvdygpOwotICAgIC8qKgotICAgICAqICBTZWUgdGhlIHRleHQtc2hhZG93IHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgU1lOVEFYX0VSUjogUmFpc2VkIGlmIHRoZSBuZXcgdmFsdWUgaGFzIGEgc3ludGF4IGVycm9yIGFuZCBpcwotICAgICAqICAgdW5wYXJzYWJsZS4KLSAgICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIHByb3BlcnR5IGlzIHJlYWRvbmx5LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFRleHRTaGFkb3coU3RyaW5nIHRleHRTaGFkb3cpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgdGV4dC10cmFuc2Zvcm0gcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VGV4dFRyYW5zZm9ybSgpOwotICAgIC8qKgotICAgICAqICBTZWUgdGhlIHRleHQtdHJhbnNmb3JtIHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgU1lOVEFYX0VSUjogUmFpc2VkIGlmIHRoZSBuZXcgdmFsdWUgaGFzIGEgc3ludGF4IGVycm9yIGFuZCBpcwotICAgICAqICAgdW5wYXJzYWJsZS4KLSAgICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIHByb3BlcnR5IGlzIHJlYWRvbmx5LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFRleHRUcmFuc2Zvcm0oU3RyaW5nIHRleHRUcmFuc2Zvcm0pCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgdG9wIHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFRvcCgpOwotICAgIC8qKgotICAgICAqICBTZWUgdGhlIHRvcCBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIFNZTlRBWF9FUlI6IFJhaXNlZCBpZiB0aGUgbmV3IHZhbHVlIGhhcyBhIHN5bnRheCBlcnJvciBhbmQgaXMKLSAgICAgKiAgIHVucGFyc2FibGUuCi0gICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBwcm9wZXJ0eSBpcyByZWFkb25seS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRUb3AoU3RyaW5nIHRvcCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSB1bmljb2RlLWJpZGkgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VW5pY29kZUJpZGkoKTsKLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSB1bmljb2RlLWJpZGkgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBTWU5UQVhfRVJSOiBSYWlzZWQgaWYgdGhlIG5ldyB2YWx1ZSBoYXMgYSBzeW50YXggZXJyb3IgYW5kIGlzCi0gICAgICogICB1bnBhcnNhYmxlLgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgcHJvcGVydHkgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0VW5pY29kZUJpZGkoU3RyaW5nIHVuaWNvZGVCaWRpKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBTZWUgdGhlIHZlcnRpY2FsLWFsaWduIHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFZlcnRpY2FsQWxpZ24oKTsKLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSB2ZXJ0aWNhbC1hbGlnbiBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIFNZTlRBWF9FUlI6IFJhaXNlZCBpZiB0aGUgbmV3IHZhbHVlIGhhcyBhIHN5bnRheCBlcnJvciBhbmQgaXMKLSAgICAgKiAgIHVucGFyc2FibGUuCi0gICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBwcm9wZXJ0eSBpcyByZWFkb25seS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRWZXJ0aWNhbEFsaWduKFN0cmluZyB2ZXJ0aWNhbEFsaWduKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBTZWUgdGhlIHZpc2liaWxpdHkgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VmlzaWJpbGl0eSgpOwotICAgIC8qKgotICAgICAqICBTZWUgdGhlIHZpc2liaWxpdHkgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBTWU5UQVhfRVJSOiBSYWlzZWQgaWYgdGhlIG5ldyB2YWx1ZSBoYXMgYSBzeW50YXggZXJyb3IgYW5kIGlzCi0gICAgICogICB1bnBhcnNhYmxlLgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgcHJvcGVydHkgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0VmlzaWJpbGl0eShTdHJpbmcgdmlzaWJpbGl0eSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSB2b2ljZS1mYW1pbHkgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Vm9pY2VGYW1pbHkoKTsKLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSB2b2ljZS1mYW1pbHkgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBTWU5UQVhfRVJSOiBSYWlzZWQgaWYgdGhlIG5ldyB2YWx1ZSBoYXMgYSBzeW50YXggZXJyb3IgYW5kIGlzCi0gICAgICogICB1bnBhcnNhYmxlLgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgcHJvcGVydHkgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0Vm9pY2VGYW1pbHkoU3RyaW5nIHZvaWNlRmFtaWx5KQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBTZWUgdGhlIHZvbHVtZSBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRWb2x1bWUoKTsKLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSB2b2x1bWUgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBTWU5UQVhfRVJSOiBSYWlzZWQgaWYgdGhlIG5ldyB2YWx1ZSBoYXMgYSBzeW50YXggZXJyb3IgYW5kIGlzCi0gICAgICogICB1bnBhcnNhYmxlLgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgcHJvcGVydHkgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0Vm9sdW1lKFN0cmluZyB2b2x1bWUpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgd2hpdGUtc3BhY2UgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0V2hpdGVTcGFjZSgpOwotICAgIC8qKgotICAgICAqICBTZWUgdGhlIHdoaXRlLXNwYWNlIHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgU1lOVEFYX0VSUjogUmFpc2VkIGlmIHRoZSBuZXcgdmFsdWUgaGFzIGEgc3ludGF4IGVycm9yIGFuZCBpcwotICAgICAqICAgdW5wYXJzYWJsZS4KLSAgICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIHByb3BlcnR5IGlzIHJlYWRvbmx5LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFdoaXRlU3BhY2UoU3RyaW5nIHdoaXRlU3BhY2UpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgd2lkb3dzIHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFdpZG93cygpOwotICAgIC8qKgotICAgICAqICBTZWUgdGhlIHdpZG93cyBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIFNZTlRBWF9FUlI6IFJhaXNlZCBpZiB0aGUgbmV3IHZhbHVlIGhhcyBhIHN5bnRheCBlcnJvciBhbmQgaXMKLSAgICAgKiAgIHVucGFyc2FibGUuCi0gICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBwcm9wZXJ0eSBpcyByZWFkb25seS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRXaWRvd3MoU3RyaW5nIHdpZG93cykKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSB3aWR0aCBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRXaWR0aCgpOwotICAgIC8qKgotICAgICAqICBTZWUgdGhlIHdpZHRoIHByb3BlcnR5IGRlZmluaXRpb24gaW4gQ1NTMi4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgU1lOVEFYX0VSUjogUmFpc2VkIGlmIHRoZSBuZXcgdmFsdWUgaGFzIGEgc3ludGF4IGVycm9yIGFuZCBpcwotICAgICAqICAgdW5wYXJzYWJsZS4KLSAgICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIHByb3BlcnR5IGlzIHJlYWRvbmx5LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFdpZHRoKFN0cmluZyB3aWR0aCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSB3b3JkLXNwYWNpbmcgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0V29yZFNwYWNpbmcoKTsKLSAgICAvKioKLSAgICAgKiAgU2VlIHRoZSB3b3JkLXNwYWNpbmcgcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBTWU5UQVhfRVJSOiBSYWlzZWQgaWYgdGhlIG5ldyB2YWx1ZSBoYXMgYSBzeW50YXggZXJyb3IgYW5kIGlzCi0gICAgICogICB1bnBhcnNhYmxlLgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgcHJvcGVydHkgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0V29yZFNwYWNpbmcoU3RyaW5nIHdvcmRTcGFjaW5nKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBTZWUgdGhlIHotaW5kZXggcHJvcGVydHkgZGVmaW5pdGlvbiBpbiBDU1MyLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0WkluZGV4KCk7Ci0gICAgLyoqCi0gICAgICogIFNlZSB0aGUgei1pbmRleCBwcm9wZXJ0eSBkZWZpbml0aW9uIGluIENTUzIuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIFNZTlRBWF9FUlI6IFJhaXNlZCBpZiB0aGUgbmV3IHZhbHVlIGhhcyBhIHN5bnRheCBlcnJvciBhbmQgaXMKLSAgICAgKiAgIHVucGFyc2FibGUuCi0gICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBwcm9wZXJ0eSBpcyByZWFkb25seS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRaSW5kZXgoU3RyaW5nIHpJbmRleCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvdzNjL2RvbS9jc3MvQ1NTQ2hhcnNldFJ1bGUuamF2YSBiL3NyYy9vcmcvdzNjL2RvbS9jc3MvQ1NTQ2hhcnNldFJ1bGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMTBhNjRhYi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3czYy9kb20vY3NzL0NTU0NoYXJzZXRSdWxlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4MCArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogVGhpcyBmaWxlIGlzIGF2YWlsYWJsZSB1bmRlciBhbmQgZ292ZXJuZWQgYnkgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwotICogTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKiBIb3dldmVyLCB0aGUgZm9sbG93aW5nIG5vdGljZSBhY2NvbXBhbmllZCB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGlzCi0gKiBmaWxlIGFuZCwgcGVyIGl0cyB0ZXJtcywgc2hvdWxkIG5vdCBiZSByZW1vdmVkOgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAotICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCi0gKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKLSAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQotICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKLSAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KLSAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKLSAqIFBVUlBPU0UuCi0gKiBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KLSAqLwotCi1wYWNrYWdlIG9yZy53M2MuZG9tLmNzczsKLQotaW1wb3J0IG9yZy53M2MuZG9tLkRPTUV4Y2VwdGlvbjsKLQotLyoqCi0gKiAgVGhlIDxjb2RlPkNTU0NoYXJzZXRSdWxlPC9jb2RlPiBpbnRlcmZhY2UgcmVwcmVzZW50cyBhIEBjaGFyc2V0IHJ1bGUgaW4gYQotICogQ1NTIHN0eWxlIHNoZWV0LiBUaGUgdmFsdWUgb2YgdGhlIDxjb2RlPmVuY29kaW5nPC9jb2RlPiBhdHRyaWJ1dGUgZG9lcwotICogbm90IGFmZmVjdCB0aGUgZW5jb2Rpbmcgb2YgdGV4dCBkYXRhIGluIHRoZSBET00gb2JqZWN0czsgdGhpcyBlbmNvZGluZyBpcwotICogYWx3YXlzIFVURi0xNi4gQWZ0ZXIgYSBzdHlsZXNoZWV0IGlzIGxvYWRlZCwgdGhlIHZhbHVlIG9mIHRoZQotICogPGNvZGU+ZW5jb2Rpbmc8L2NvZGU+IGF0dHJpYnV0ZSBpcyB0aGUgdmFsdWUgZm91bmQgaW4gdGhlCi0gKiA8Y29kZT5AY2hhcnNldDwvY29kZT4gcnVsZS4gSWYgdGhlcmUgd2FzIG5vIDxjb2RlPkBjaGFyc2V0PC9jb2RlPiBpbiB0aGUKLSAqIG9yaWdpbmFsIGRvY3VtZW50LCB0aGVuIG5vIDxjb2RlPkNTU0NoYXJzZXRSdWxlPC9jb2RlPiBpcyBjcmVhdGVkLiBUaGUKLSAqIHZhbHVlIG9mIHRoZSA8Y29kZT5lbmNvZGluZzwvY29kZT4gYXR0cmlidXRlIG1heSBhbHNvIGJlIHVzZWQgYXMgYSBoaW50Ci0gKiBmb3IgdGhlIGVuY29kaW5nIHVzZWQgb24gc2VyaWFsaXphdGlvbiBvZiB0aGUgc3R5bGUgc2hlZXQuCi0gKiA8cD4gVGhlIHZhbHVlIG9mIHRoZSBAY2hhcnNldCBydWxlIChhbmQgdGhlcmVmb3JlIG9mIHRoZQotICogPGNvZGU+Q1NTQ2hhcnNldFJ1bGU8L2NvZGU+KSBtYXkgbm90IGNvcnJlc3BvbmQgdG8gdGhlIGVuY29kaW5nIHRoZQotICogZG9jdW1lbnQgYWN0dWFsbHkgY2FtZSBpbjsgY2hhcmFjdGVyIGVuY29kaW5nIGluZm9ybWF0aW9uIGUuZy4gaW4gYW4gSFRUUAotICogaGVhZGVyLCBoYXMgcHJpb3JpdHkgKHNlZSBDU1MgZG9jdW1lbnQgcmVwcmVzZW50YXRpb24pIGJ1dCB0aGlzIGlzIG5vdAotICogcmVmbGVjdGVkIGluIHRoZSA8Y29kZT5DU1NDaGFyc2V0UnVsZTwvY29kZT4uCi0gKiA8cD5TZWUgYWxzbyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMC9SRUMtRE9NLUxldmVsLTItU3R5bGUtMjAwMDExMTMnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAyIFN0eWxlIFNwZWNpZmljYXRpb248L2E+LgotICogQHNpbmNlIERPTSBMZXZlbCAyCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgQ1NTQ2hhcnNldFJ1bGUgZXh0ZW5kcyBDU1NSdWxlIHsKLSAgICAvKioKLSAgICAgKiAgVGhlIGVuY29kaW5nIGluZm9ybWF0aW9uIHVzZWQgaW4gdGhpcyA8Y29kZT5AY2hhcnNldDwvY29kZT4gcnVsZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEVuY29kaW5nKCk7Ci0gICAgLyoqCi0gICAgICogIFRoZSBlbmNvZGluZyBpbmZvcm1hdGlvbiB1c2VkIGluIHRoaXMgPGNvZGU+QGNoYXJzZXQ8L2NvZGU+IHJ1bGUuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIFNZTlRBWF9FUlI6IFJhaXNlZCBpZiB0aGUgc3BlY2lmaWVkIGVuY29kaW5nIHZhbHVlIGhhcyBhIHN5bnRheCBlcnJvcgotICAgICAqICAgYW5kIGlzIHVucGFyc2FibGUuCi0gICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBlbmNvZGluZyBydWxlIGlzCi0gICAgICogICByZWFkb25seS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRFbmNvZGluZyhTdHJpbmcgZW5jb2RpbmcpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL3czYy9kb20vY3NzL0NTU0ZvbnRGYWNlUnVsZS5qYXZhIGIvc3JjL29yZy93M2MvZG9tL2Nzcy9DU1NGb250RmFjZVJ1bGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYjRmNjg5Mi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3czYy9kb20vY3NzL0NTU0ZvbnRGYWNlUnVsZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTcgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIFRoaXMgZmlsZSBpcyBhdmFpbGFibGUgdW5kZXIgYW5kIGdvdmVybmVkIGJ5IHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKLSAqIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICogSG93ZXZlciwgdGhlIGZvbGxvd2luZyBub3RpY2UgYWNjb21wYW5pZWQgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcwotICogZmlsZSBhbmQsIHBlciBpdHMgdGVybXMsIHNob3VsZCBub3QgYmUgcmVtb3ZlZDoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDAgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKLSAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQotICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCi0gKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKLSAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCi0gKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCi0gKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCi0gKiBQVVJQT1NFLgotICogU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCi0gKi8KLQotcGFja2FnZSBvcmcudzNjLmRvbS5jc3M7Ci0KLS8qKgotICogIFRoZSA8Y29kZT5DU1NGb250RmFjZVJ1bGU8L2NvZGU+IGludGVyZmFjZSByZXByZXNlbnRzIGEgQGZvbnQtZmFjZSBydWxlIGluCi0gKiBhIENTUyBzdHlsZSBzaGVldC4gVGhlIDxjb2RlPkBmb250LWZhY2U8L2NvZGU+IHJ1bGUgaXMgdXNlZCB0byBob2xkIGEgc2V0Ci0gKiBvZiBmb250IGRlc2NyaXB0aW9ucy4KLSAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAwL1JFQy1ET00tTGV2ZWwtMi1TdHlsZS0yMDAwMTExMyc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDIgU3R5bGUgU3BlY2lmaWNhdGlvbjwvYT4uCi0gKiBAc2luY2UgRE9NIExldmVsIDIKLSAqLwotcHVibGljIGludGVyZmFjZSBDU1NGb250RmFjZVJ1bGUgZXh0ZW5kcyBDU1NSdWxlIHsKLSAgICAvKioKLSAgICAgKiAgVGhlIGRlY2xhcmF0aW9uLWJsb2NrIG9mIHRoaXMgcnVsZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgQ1NTU3R5bGVEZWNsYXJhdGlvbiBnZXRTdHlsZSgpOwotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL3czYy9kb20vY3NzL0NTU0ltcG9ydFJ1bGUuamF2YSBiL3NyYy9vcmcvdzNjL2RvbS9jc3MvQ1NTSW1wb3J0UnVsZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhOWQzMjFhLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS9jc3MvQ1NTSW1wb3J0UnVsZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNzMgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIFRoaXMgZmlsZSBpcyBhdmFpbGFibGUgdW5kZXIgYW5kIGdvdmVybmVkIGJ5IHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKLSAqIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICogSG93ZXZlciwgdGhlIGZvbGxvd2luZyBub3RpY2UgYWNjb21wYW5pZWQgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcwotICogZmlsZSBhbmQsIHBlciBpdHMgdGVybXMsIHNob3VsZCBub3QgYmUgcmVtb3ZlZDoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDAgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKLSAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQotICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCi0gKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKLSAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCi0gKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCi0gKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCi0gKiBQVVJQT1NFLgotICogU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCi0gKi8KLQotcGFja2FnZSBvcmcudzNjLmRvbS5jc3M7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5zdHlsZXNoZWV0cy5NZWRpYUxpc3Q7Ci0KLS8qKgotICogIFRoZSA8Y29kZT5DU1NJbXBvcnRSdWxlPC9jb2RlPiBpbnRlcmZhY2UgcmVwcmVzZW50cyBhIEBpbXBvcnQgcnVsZSB3aXRoaW4KLSAqIGEgQ1NTIHN0eWxlIHNoZWV0LiBUaGUgPGNvZGU+QGltcG9ydDwvY29kZT4gcnVsZSBpcyB1c2VkIHRvIGltcG9ydCBzdHlsZQotICogcnVsZXMgZnJvbSBvdGhlciBzdHlsZSBzaGVldHMuCi0gKiA8cD5TZWUgYWxzbyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMC9SRUMtRE9NLUxldmVsLTItU3R5bGUtMjAwMDExMTMnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAyIFN0eWxlIFNwZWNpZmljYXRpb248L2E+LgotICogQHNpbmNlIERPTSBMZXZlbCAyCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgQ1NTSW1wb3J0UnVsZSBleHRlbmRzIENTU1J1bGUgewotICAgIC8qKgotICAgICAqICBUaGUgbG9jYXRpb24gb2YgdGhlIHN0eWxlIHNoZWV0IHRvIGJlIGltcG9ydGVkLiBUaGUgYXR0cmlidXRlIHdpbGwgbm90Ci0gICAgICogY29udGFpbiB0aGUgPGNvZGU+InVybCguLi4pIjwvY29kZT4gc3BlY2lmaWVyIGFyb3VuZCB0aGUgVVJJLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0SHJlZigpOwotCi0gICAgLyoqCi0gICAgICogIEEgbGlzdCBvZiBtZWRpYSB0eXBlcyBmb3Igd2hpY2ggdGhpcyBzdHlsZSBzaGVldCBtYXkgYmUgdXNlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgTWVkaWFMaXN0IGdldE1lZGlhKCk7Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgc3R5bGUgc2hlZXQgcmVmZXJyZWQgdG8gYnkgdGhpcyBydWxlLCBpZiBpdCBoYXMgYmVlbiBsb2FkZWQuIFRoZQotICAgICAqIHZhbHVlIG9mIHRoaXMgYXR0cmlidXRlIGlzIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoZSBzdHlsZSBzaGVldCBoYXMKLSAgICAgKiBub3QgeWV0IGJlZW4gbG9hZGVkIG9yIGlmIGl0IHdpbGwgbm90IGJlIGxvYWRlZCAoZS5nLiBpZiB0aGUgc3R5bGUKLSAgICAgKiBzaGVldCBpcyBmb3IgYSBtZWRpYSB0eXBlIG5vdCBzdXBwb3J0ZWQgYnkgdGhlIHVzZXIgYWdlbnQpLgotICAgICAqLwotICAgIHB1YmxpYyBDU1NTdHlsZVNoZWV0IGdldFN0eWxlU2hlZXQoKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy93M2MvZG9tL2Nzcy9DU1NNZWRpYVJ1bGUuamF2YSBiL3NyYy9vcmcvdzNjL2RvbS9jc3MvQ1NTTWVkaWFSdWxlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGJmMTUzZDkuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy93M2MvZG9tL2Nzcy9DU1NNZWRpYVJ1bGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEwNSArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogVGhpcyBmaWxlIGlzIGF2YWlsYWJsZSB1bmRlciBhbmQgZ292ZXJuZWQgYnkgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwotICogTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKiBIb3dldmVyLCB0aGUgZm9sbG93aW5nIG5vdGljZSBhY2NvbXBhbmllZCB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGlzCi0gKiBmaWxlIGFuZCwgcGVyIGl0cyB0ZXJtcywgc2hvdWxkIG5vdCBiZSByZW1vdmVkOgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAotICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCi0gKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKLSAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQotICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKLSAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KLSAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKLSAqIFBVUlBPU0UuCi0gKiBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KLSAqLwotCi1wYWNrYWdlIG9yZy53M2MuZG9tLmNzczsKLQotaW1wb3J0IG9yZy53M2MuZG9tLkRPTUV4Y2VwdGlvbjsKLWltcG9ydCBvcmcudzNjLmRvbS5zdHlsZXNoZWV0cy5NZWRpYUxpc3Q7Ci0KLS8qKgotICogIFRoZSA8Y29kZT5DU1NNZWRpYVJ1bGU8L2NvZGU+IGludGVyZmFjZSByZXByZXNlbnRzIGEgQG1lZGlhIHJ1bGUgaW4gYSBDU1MKLSAqIHN0eWxlIHNoZWV0LiBBIDxjb2RlPkBtZWRpYTwvY29kZT4gcnVsZSBjYW4gYmUgdXNlZCB0byBkZWxpbWl0IHN0eWxlCi0gKiBydWxlcyBmb3Igc3BlY2lmaWMgbWVkaWEgdHlwZXMuCi0gKiA8cD5TZWUgYWxzbyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMC9SRUMtRE9NLUxldmVsLTItU3R5bGUtMjAwMDExMTMnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAyIFN0eWxlIFNwZWNpZmljYXRpb248L2E+LgotICogQHNpbmNlIERPTSBMZXZlbCAyCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgQ1NTTWVkaWFSdWxlIGV4dGVuZHMgQ1NTUnVsZSB7Ci0gICAgLyoqCi0gICAgICogIEEgbGlzdCBvZiBtZWRpYSB0eXBlcyBmb3IgdGhpcyBydWxlLgotICAgICAqLwotICAgIHB1YmxpYyBNZWRpYUxpc3QgZ2V0TWVkaWEoKTsKLQotICAgIC8qKgotICAgICAqICBBIGxpc3Qgb2YgYWxsIENTUyBydWxlcyBjb250YWluZWQgd2l0aGluIHRoZSBtZWRpYSBibG9jay4KLSAgICAgKi8KLSAgICBwdWJsaWMgQ1NTUnVsZUxpc3QgZ2V0Q3NzUnVsZXMoKTsKLQotICAgIC8qKgotICAgICAqICBVc2VkIHRvIGluc2VydCBhIG5ldyBydWxlIGludG8gdGhlIG1lZGlhIGJsb2NrLgotICAgICAqIEBwYXJhbSBydWxlICBUaGUgcGFyc2FibGUgdGV4dCByZXByZXNlbnRpbmcgdGhlIHJ1bGUuIEZvciBydWxlIHNldHMKLSAgICAgKiAgIHRoaXMgY29udGFpbnMgYm90aCB0aGUgc2VsZWN0b3IgYW5kIHRoZSBzdHlsZSBkZWNsYXJhdGlvbi4gRm9yCi0gICAgICogICBhdC1ydWxlcywgdGhpcyBzcGVjaWZpZXMgYm90aCB0aGUgYXQtaWRlbnRpZmllciBhbmQgdGhlIHJ1bGUKLSAgICAgKiAgIGNvbnRlbnQuCi0gICAgICogQHBhcmFtIGluZGV4ICBUaGUgaW5kZXggd2l0aGluIHRoZSBtZWRpYSBibG9jaydzIHJ1bGUgY29sbGVjdGlvbiBvZgotICAgICAqICAgdGhlIHJ1bGUgYmVmb3JlIHdoaWNoIHRvIGluc2VydCB0aGUgc3BlY2lmaWVkIHJ1bGUuIElmIHRoZQotICAgICAqICAgc3BlY2lmaWVkIGluZGV4IGlzIGVxdWFsIHRvIHRoZSBsZW5ndGggb2YgdGhlIG1lZGlhIGJsb2NrcydzIHJ1bGUKLSAgICAgKiAgIGNvbGxlY3Rpb24sIHRoZSBydWxlIHdpbGwgYmUgYWRkZWQgdG8gdGhlIGVuZCBvZiB0aGUgbWVkaWEgYmxvY2suCi0gICAgICogQHJldHVybiAgVGhlIGluZGV4IHdpdGhpbiB0aGUgbWVkaWEgYmxvY2sncyBydWxlIGNvbGxlY3Rpb24gb2YgdGhlCi0gICAgICogICBuZXdseSBpbnNlcnRlZCBydWxlLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBISUVSQVJDSFlfUkVRVUVTVF9FUlI6IFJhaXNlZCBpZiB0aGUgcnVsZSBjYW5ub3QgYmUgaW5zZXJ0ZWQgYXQgdGhlCi0gICAgICogICBzcGVjaWZpZWQgaW5kZXgsIGUuZy4sIGlmIGFuIDxjb2RlPkBpbXBvcnQ8L2NvZGU+IHJ1bGUgaXMgaW5zZXJ0ZWQKLSAgICAgKiAgIGFmdGVyIGEgc3RhbmRhcmQgcnVsZSBzZXQgb3Igb3RoZXIgYXQtcnVsZS4KLSAgICAgKiAgIDxicj5JTkRFWF9TSVpFX0VSUjogUmFpc2VkIGlmIHRoZSBzcGVjaWZpZWQgaW5kZXggaXMgbm90IGEgdmFsaWQKLSAgICAgKiAgIGluc2VydGlvbiBwb2ludC4KLSAgICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIG1lZGlhIHJ1bGUgaXMKLSAgICAgKiAgIHJlYWRvbmx5LgotICAgICAqICAgPGJyPlNZTlRBWF9FUlI6IFJhaXNlZCBpZiB0aGUgc3BlY2lmaWVkIHJ1bGUgaGFzIGEgc3ludGF4IGVycm9yIGFuZAotICAgICAqICAgaXMgdW5wYXJzYWJsZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGluc2VydFJ1bGUoU3RyaW5nIHJ1bGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIGludCBpbmRleCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBVc2VkIHRvIGRlbGV0ZSBhIHJ1bGUgZnJvbSB0aGUgbWVkaWEgYmxvY2suCi0gICAgICogQHBhcmFtIGluZGV4ICBUaGUgaW5kZXggd2l0aGluIHRoZSBtZWRpYSBibG9jaydzIHJ1bGUgY29sbGVjdGlvbiBvZgotICAgICAqICAgdGhlIHJ1bGUgdG8gcmVtb3ZlLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBJTkRFWF9TSVpFX0VSUjogUmFpc2VkIGlmIHRoZSBzcGVjaWZpZWQgaW5kZXggZG9lcyBub3QgY29ycmVzcG9uZCB0bwotICAgICAqICAgYSBydWxlIGluIHRoZSBtZWRpYSBydWxlIGxpc3QuCi0gICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBtZWRpYSBydWxlIGlzCi0gICAgICogICByZWFkb25seS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBkZWxldGVSdWxlKGludCBpbmRleCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvdzNjL2RvbS9jc3MvQ1NTUGFnZVJ1bGUuamF2YSBiL3NyYy9vcmcvdzNjL2RvbS9jc3MvQ1NTUGFnZVJ1bGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNzczYjc0Ni4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3czYy9kb20vY3NzL0NTU1BhZ2VSdWxlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3MyArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogVGhpcyBmaWxlIGlzIGF2YWlsYWJsZSB1bmRlciBhbmQgZ292ZXJuZWQgYnkgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwotICogTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKiBIb3dldmVyLCB0aGUgZm9sbG93aW5nIG5vdGljZSBhY2NvbXBhbmllZCB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGlzCi0gKiBmaWxlIGFuZCwgcGVyIGl0cyB0ZXJtcywgc2hvdWxkIG5vdCBiZSByZW1vdmVkOgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAotICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCi0gKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKLSAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQotICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKLSAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KLSAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKLSAqIFBVUlBPU0UuCi0gKiBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KLSAqLwotCi1wYWNrYWdlIG9yZy53M2MuZG9tLmNzczsKLQotaW1wb3J0IG9yZy53M2MuZG9tLkRPTUV4Y2VwdGlvbjsKLQotLyoqCi0gKiAgVGhlIDxjb2RlPkNTU1BhZ2VSdWxlPC9jb2RlPiBpbnRlcmZhY2UgcmVwcmVzZW50cyBhIEBwYWdlIHJ1bGUgd2l0aGluIGEKLSAqIENTUyBzdHlsZSBzaGVldC4gVGhlIDxjb2RlPkBwYWdlPC9jb2RlPiBydWxlIGlzIHVzZWQgdG8gc3BlY2lmeSB0aGUKLSAqIGRpbWVuc2lvbnMsIG9yaWVudGF0aW9uLCBtYXJnaW5zLCBldGMuIG9mIGEgcGFnZSBib3ggZm9yIHBhZ2VkIG1lZGlhLgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDAvUkVDLURPTS1MZXZlbC0yLVN0eWxlLTIwMDAxMTEzJz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMiBTdHlsZSBTcGVjaWZpY2F0aW9uPC9hPi4KLSAqIEBzaW5jZSBET00gTGV2ZWwgMgotICovCi1wdWJsaWMgaW50ZXJmYWNlIENTU1BhZ2VSdWxlIGV4dGVuZHMgQ1NTUnVsZSB7Ci0gICAgLyoqCi0gICAgICogIFRoZSBwYXJzYWJsZSB0ZXh0dWFsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBwYWdlIHNlbGVjdG9yIGZvciB0aGUgcnVsZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFNlbGVjdG9yVGV4dCgpOwotICAgIC8qKgotICAgICAqICBUaGUgcGFyc2FibGUgdGV4dHVhbCByZXByZXNlbnRhdGlvbiBvZiB0aGUgcGFnZSBzZWxlY3RvciBmb3IgdGhlIHJ1bGUuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIFNZTlRBWF9FUlI6IFJhaXNlZCBpZiB0aGUgc3BlY2lmaWVkIENTUyBzdHJpbmcgdmFsdWUgaGFzIGEgc3ludGF4Ci0gICAgICogICBlcnJvciBhbmQgaXMgdW5wYXJzYWJsZS4KLSAgICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIHJ1bGUgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0U2VsZWN0b3JUZXh0KFN0cmluZyBzZWxlY3RvclRleHQpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogIFRoZSBkZWNsYXJhdGlvbi1ibG9jayBvZiB0aGlzIHJ1bGUuCi0gICAgICovCi0gICAgcHVibGljIENTU1N0eWxlRGVjbGFyYXRpb24gZ2V0U3R5bGUoKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy93M2MvZG9tL2Nzcy9DU1NQcmltaXRpdmVWYWx1ZS5qYXZhIGIvc3JjL29yZy93M2MvZG9tL2Nzcy9DU1NQcmltaXRpdmVWYWx1ZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzMDc4ZDcyLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS9jc3MvQ1NTUHJpbWl0aXZlVmFsdWUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDMyNSArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogVGhpcyBmaWxlIGlzIGF2YWlsYWJsZSB1bmRlciBhbmQgZ292ZXJuZWQgYnkgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwotICogTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKiBIb3dldmVyLCB0aGUgZm9sbG93aW5nIG5vdGljZSBhY2NvbXBhbmllZCB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGlzCi0gKiBmaWxlIGFuZCwgcGVyIGl0cyB0ZXJtcywgc2hvdWxkIG5vdCBiZSByZW1vdmVkOgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAotICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCi0gKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKLSAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQotICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKLSAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KLSAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKLSAqIFBVUlBPU0UuCi0gKiBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KLSAqLwotCi1wYWNrYWdlIG9yZy53M2MuZG9tLmNzczsKLQotaW1wb3J0IG9yZy53M2MuZG9tLkRPTUV4Y2VwdGlvbjsKLQotLyoqCi0gKiAgVGhlIDxjb2RlPkNTU1ByaW1pdGl2ZVZhbHVlPC9jb2RlPiBpbnRlcmZhY2UgcmVwcmVzZW50cyBhIHNpbmdsZSBDU1MgdmFsdWUKLSAqIC4gVGhpcyBpbnRlcmZhY2UgbWF5IGJlIHVzZWQgdG8gZGV0ZXJtaW5lIHRoZSB2YWx1ZSBvZiBhIHNwZWNpZmljIHN0eWxlCi0gKiBwcm9wZXJ0eSBjdXJyZW50bHkgc2V0IGluIGEgYmxvY2sgb3IgdG8gc2V0IGEgc3BlY2lmaWMgc3R5bGUgcHJvcGVydHkKLSAqIGV4cGxpY2l0bHkgd2l0aGluIHRoZSBibG9jay4gQW4gaW5zdGFuY2Ugb2YgdGhpcyBpbnRlcmZhY2UgbWlnaHQgYmUKLSAqIG9idGFpbmVkIGZyb20gdGhlIDxjb2RlPmdldFByb3BlcnR5Q1NTVmFsdWU8L2NvZGU+IG1ldGhvZCBvZiB0aGUKLSAqIDxjb2RlPkNTU1N0eWxlRGVjbGFyYXRpb248L2NvZGU+IGludGVyZmFjZS4gQQotICogPGNvZGU+Q1NTUHJpbWl0aXZlVmFsdWU8L2NvZGU+IG9iamVjdCBvbmx5IG9jY3VycyBpbiBhIGNvbnRleHQgb2YgYSBDU1MKLSAqIHByb3BlcnR5LgotICogPHA+IENvbnZlcnNpb25zIGFyZSBhbGxvd2VkIGJldHdlZW4gYWJzb2x1dGUgdmFsdWVzIChmcm9tIG1pbGxpbWV0ZXJzIHRvCi0gKiBjZW50aW1ldGVycywgZnJvbSBkZWdyZWVzIHRvIHJhZGlhbnMsIGFuZCBzbyBvbikgYnV0IG5vdCBiZXR3ZWVuIHJlbGF0aXZlCi0gKiB2YWx1ZXMuIChGb3IgZXhhbXBsZSwgYSBwaXhlbCB2YWx1ZSBjYW5ub3QgYmUgY29udmVydGVkIHRvIGEgY2VudGltZXRlcgotICogdmFsdWUuKSBQZXJjZW50YWdlIHZhbHVlcyBjYW4ndCBiZSBjb252ZXJ0ZWQgc2luY2UgdGhleSBhcmUgcmVsYXRpdmUgdG8KLSAqIHRoZSBwYXJlbnQgdmFsdWUgKG9yIGFub3RoZXIgcHJvcGVydHkgdmFsdWUpLiBUaGVyZSBpcyBvbmUgZXhjZXB0aW9uIGZvcgotICogY29sb3IgcGVyY2VudGFnZSB2YWx1ZXM6IHNpbmNlIGEgY29sb3IgcGVyY2VudGFnZSB2YWx1ZSBpcyByZWxhdGl2ZSB0bwotICogdGhlIHJhbmdlIDAtMjU1LCBhIGNvbG9yIHBlcmNlbnRhZ2UgdmFsdWUgY2FuIGJlIGNvbnZlcnRlZCB0byBhIG51bWJlcjsKLSAqIChzZWUgYWxzbyB0aGUgPGNvZGU+UkdCQ29sb3I8L2NvZGU+IGludGVyZmFjZSkuCi0gKiA8cD5TZWUgYWxzbyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMC9SRUMtRE9NLUxldmVsLTItU3R5bGUtMjAwMDExMTMnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAyIFN0eWxlIFNwZWNpZmljYXRpb248L2E+LgotICogQHNpbmNlIERPTSBMZXZlbCAyCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgQ1NTUHJpbWl0aXZlVmFsdWUgZXh0ZW5kcyBDU1NWYWx1ZSB7Ci0gICAgLy8gVW5pdFR5cGVzCi0gICAgLyoqCi0gICAgICogVGhlIHZhbHVlIGlzIG5vdCBhIHJlY29nbml6ZWQgQ1NTMiB2YWx1ZS4gVGhlIHZhbHVlIGNhbiBvbmx5IGJlCi0gICAgICogb2J0YWluZWQgYnkgdXNpbmcgdGhlIDxjb2RlPmNzc1RleHQ8L2NvZGU+IGF0dHJpYnV0ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IENTU19VTktOT1dOICAgICAgICAgICAgICAgPSAwOwotICAgIC8qKgotICAgICAqIFRoZSB2YWx1ZSBpcyBhIHNpbXBsZSBudW1iZXIuIFRoZSB2YWx1ZSBjYW4gYmUgb2J0YWluZWQgYnkgdXNpbmcgdGhlCi0gICAgICogPGNvZGU+Z2V0RmxvYXRWYWx1ZTwvY29kZT4gbWV0aG9kLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgQ1NTX05VTUJFUiAgICAgICAgICAgICAgICA9IDE7Ci0gICAgLyoqCi0gICAgICogVGhlIHZhbHVlIGlzIGEgcGVyY2VudGFnZS4gVGhlIHZhbHVlIGNhbiBiZSBvYnRhaW5lZCBieSB1c2luZyB0aGUKLSAgICAgKiA8Y29kZT5nZXRGbG9hdFZhbHVlPC9jb2RlPiBtZXRob2QuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBDU1NfUEVSQ0VOVEFHRSAgICAgICAgICAgID0gMjsKLSAgICAvKioKLSAgICAgKiBUaGUgdmFsdWUgaXMgYSBsZW5ndGggKGVtcykuIFRoZSB2YWx1ZSBjYW4gYmUgb2J0YWluZWQgYnkgdXNpbmcgdGhlCi0gICAgICogPGNvZGU+Z2V0RmxvYXRWYWx1ZTwvY29kZT4gbWV0aG9kLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgQ1NTX0VNUyAgICAgICAgICAgICAgICAgICA9IDM7Ci0gICAgLyoqCi0gICAgICogVGhlIHZhbHVlIGlzIGEgbGVuZ3RoIChleHMpLiBUaGUgdmFsdWUgY2FuIGJlIG9idGFpbmVkIGJ5IHVzaW5nIHRoZQotICAgICAqIDxjb2RlPmdldEZsb2F0VmFsdWU8L2NvZGU+IG1ldGhvZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IENTU19FWFMgICAgICAgICAgICAgICAgICAgPSA0OwotICAgIC8qKgotICAgICAqIFRoZSB2YWx1ZSBpcyBhIGxlbmd0aCAocHgpLiBUaGUgdmFsdWUgY2FuIGJlIG9idGFpbmVkIGJ5IHVzaW5nIHRoZQotICAgICAqIDxjb2RlPmdldEZsb2F0VmFsdWU8L2NvZGU+IG1ldGhvZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IENTU19QWCAgICAgICAgICAgICAgICAgICAgPSA1OwotICAgIC8qKgotICAgICAqIFRoZSB2YWx1ZSBpcyBhIGxlbmd0aCAoY20pLiBUaGUgdmFsdWUgY2FuIGJlIG9idGFpbmVkIGJ5IHVzaW5nIHRoZQotICAgICAqIDxjb2RlPmdldEZsb2F0VmFsdWU8L2NvZGU+IG1ldGhvZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IENTU19DTSAgICAgICAgICAgICAgICAgICAgPSA2OwotICAgIC8qKgotICAgICAqIFRoZSB2YWx1ZSBpcyBhIGxlbmd0aCAobW0pLiBUaGUgdmFsdWUgY2FuIGJlIG9idGFpbmVkIGJ5IHVzaW5nIHRoZQotICAgICAqIDxjb2RlPmdldEZsb2F0VmFsdWU8L2NvZGU+IG1ldGhvZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IENTU19NTSAgICAgICAgICAgICAgICAgICAgPSA3OwotICAgIC8qKgotICAgICAqIFRoZSB2YWx1ZSBpcyBhIGxlbmd0aCAoaW4pLiBUaGUgdmFsdWUgY2FuIGJlIG9idGFpbmVkIGJ5IHVzaW5nIHRoZQotICAgICAqIDxjb2RlPmdldEZsb2F0VmFsdWU8L2NvZGU+IG1ldGhvZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IENTU19JTiAgICAgICAgICAgICAgICAgICAgPSA4OwotICAgIC8qKgotICAgICAqIFRoZSB2YWx1ZSBpcyBhIGxlbmd0aCAocHQpLiBUaGUgdmFsdWUgY2FuIGJlIG9idGFpbmVkIGJ5IHVzaW5nIHRoZQotICAgICAqIDxjb2RlPmdldEZsb2F0VmFsdWU8L2NvZGU+IG1ldGhvZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IENTU19QVCAgICAgICAgICAgICAgICAgICAgPSA5OwotICAgIC8qKgotICAgICAqIFRoZSB2YWx1ZSBpcyBhIGxlbmd0aCAocGMpLiBUaGUgdmFsdWUgY2FuIGJlIG9idGFpbmVkIGJ5IHVzaW5nIHRoZQotICAgICAqIDxjb2RlPmdldEZsb2F0VmFsdWU8L2NvZGU+IG1ldGhvZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IENTU19QQyAgICAgICAgICAgICAgICAgICAgPSAxMDsKLSAgICAvKioKLSAgICAgKiBUaGUgdmFsdWUgaXMgYW4gYW5nbGUgKGRlZykuIFRoZSB2YWx1ZSBjYW4gYmUgb2J0YWluZWQgYnkgdXNpbmcgdGhlCi0gICAgICogPGNvZGU+Z2V0RmxvYXRWYWx1ZTwvY29kZT4gbWV0aG9kLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgQ1NTX0RFRyAgICAgICAgICAgICAgICAgICA9IDExOwotICAgIC8qKgotICAgICAqIFRoZSB2YWx1ZSBpcyBhbiBhbmdsZSAocmFkKS4gVGhlIHZhbHVlIGNhbiBiZSBvYnRhaW5lZCBieSB1c2luZyB0aGUKLSAgICAgKiA8Y29kZT5nZXRGbG9hdFZhbHVlPC9jb2RlPiBtZXRob2QuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBDU1NfUkFEICAgICAgICAgICAgICAgICAgID0gMTI7Ci0gICAgLyoqCi0gICAgICogVGhlIHZhbHVlIGlzIGFuIGFuZ2xlIChncmFkKS4gVGhlIHZhbHVlIGNhbiBiZSBvYnRhaW5lZCBieSB1c2luZyB0aGUKLSAgICAgKiA8Y29kZT5nZXRGbG9hdFZhbHVlPC9jb2RlPiBtZXRob2QuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBDU1NfR1JBRCAgICAgICAgICAgICAgICAgID0gMTM7Ci0gICAgLyoqCi0gICAgICogVGhlIHZhbHVlIGlzIGEgdGltZSAobXMpLiBUaGUgdmFsdWUgY2FuIGJlIG9idGFpbmVkIGJ5IHVzaW5nIHRoZQotICAgICAqIDxjb2RlPmdldEZsb2F0VmFsdWU8L2NvZGU+IG1ldGhvZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IENTU19NUyAgICAgICAgICAgICAgICAgICAgPSAxNDsKLSAgICAvKioKLSAgICAgKiBUaGUgdmFsdWUgaXMgYSB0aW1lIChzKS4gVGhlIHZhbHVlIGNhbiBiZSBvYnRhaW5lZCBieSB1c2luZyB0aGUKLSAgICAgKiA8Y29kZT5nZXRGbG9hdFZhbHVlPC9jb2RlPiBtZXRob2QuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBDU1NfUyAgICAgICAgICAgICAgICAgICAgID0gMTU7Ci0gICAgLyoqCi0gICAgICogVGhlIHZhbHVlIGlzIGEgZnJlcXVlbmN5IChIeikuIFRoZSB2YWx1ZSBjYW4gYmUgb2J0YWluZWQgYnkgdXNpbmcgdGhlCi0gICAgICogPGNvZGU+Z2V0RmxvYXRWYWx1ZTwvY29kZT4gbWV0aG9kLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgQ1NTX0haICAgICAgICAgICAgICAgICAgICA9IDE2OwotICAgIC8qKgotICAgICAqIFRoZSB2YWx1ZSBpcyBhIGZyZXF1ZW5jeSAoa0h6KS4gVGhlIHZhbHVlIGNhbiBiZSBvYnRhaW5lZCBieSB1c2luZyB0aGUKLSAgICAgKiA8Y29kZT5nZXRGbG9hdFZhbHVlPC9jb2RlPiBtZXRob2QuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBDU1NfS0haICAgICAgICAgICAgICAgICAgID0gMTc7Ci0gICAgLyoqCi0gICAgICogVGhlIHZhbHVlIGlzIGEgbnVtYmVyIHdpdGggYW4gdW5rbm93biBkaW1lbnNpb24uIFRoZSB2YWx1ZSBjYW4gYmUKLSAgICAgKiBvYnRhaW5lZCBieSB1c2luZyB0aGUgPGNvZGU+Z2V0RmxvYXRWYWx1ZTwvY29kZT4gbWV0aG9kLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgQ1NTX0RJTUVOU0lPTiAgICAgICAgICAgICA9IDE4OwotICAgIC8qKgotICAgICAqIFRoZSB2YWx1ZSBpcyBhIFNUUklORy4gVGhlIHZhbHVlIGNhbiBiZSBvYnRhaW5lZCBieSB1c2luZyB0aGUKLSAgICAgKiA8Y29kZT5nZXRTdHJpbmdWYWx1ZTwvY29kZT4gbWV0aG9kLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgQ1NTX1NUUklORyAgICAgICAgICAgICAgICA9IDE5OwotICAgIC8qKgotICAgICAqIFRoZSB2YWx1ZSBpcyBhIFVSSS4gVGhlIHZhbHVlIGNhbiBiZSBvYnRhaW5lZCBieSB1c2luZyB0aGUKLSAgICAgKiA8Y29kZT5nZXRTdHJpbmdWYWx1ZTwvY29kZT4gbWV0aG9kLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgQ1NTX1VSSSAgICAgICAgICAgICAgICAgICA9IDIwOwotICAgIC8qKgotICAgICAqIFRoZSB2YWx1ZSBpcyBhbiBpZGVudGlmaWVyLiBUaGUgdmFsdWUgY2FuIGJlIG9idGFpbmVkIGJ5IHVzaW5nIHRoZQotICAgICAqIDxjb2RlPmdldFN0cmluZ1ZhbHVlPC9jb2RlPiBtZXRob2QuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBDU1NfSURFTlQgICAgICAgICAgICAgICAgID0gMjE7Ci0gICAgLyoqCi0gICAgICogVGhlIHZhbHVlIGlzIGEgYXR0cmlidXRlIGZ1bmN0aW9uLiBUaGUgdmFsdWUgY2FuIGJlIG9idGFpbmVkIGJ5IHVzaW5nCi0gICAgICogdGhlIDxjb2RlPmdldFN0cmluZ1ZhbHVlPC9jb2RlPiBtZXRob2QuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBDU1NfQVRUUiAgICAgICAgICAgICAgICAgID0gMjI7Ci0gICAgLyoqCi0gICAgICogVGhlIHZhbHVlIGlzIGEgY291bnRlciBvciBjb3VudGVycyBmdW5jdGlvbi4gVGhlIHZhbHVlIGNhbiBiZSBvYnRhaW5lZAotICAgICAqIGJ5IHVzaW5nIHRoZSA8Y29kZT5nZXRDb3VudGVyVmFsdWU8L2NvZGU+IG1ldGhvZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IENTU19DT1VOVEVSICAgICAgICAgICAgICAgPSAyMzsKLSAgICAvKioKLSAgICAgKiBUaGUgdmFsdWUgaXMgYSByZWN0IGZ1bmN0aW9uLiBUaGUgdmFsdWUgY2FuIGJlIG9idGFpbmVkIGJ5IHVzaW5nIHRoZQotICAgICAqIDxjb2RlPmdldFJlY3RWYWx1ZTwvY29kZT4gbWV0aG9kLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgQ1NTX1JFQ1QgICAgICAgICAgICAgICAgICA9IDI0OwotICAgIC8qKgotICAgICAqIFRoZSB2YWx1ZSBpcyBhIFJHQiBjb2xvci4gVGhlIHZhbHVlIGNhbiBiZSBvYnRhaW5lZCBieSB1c2luZyB0aGUKLSAgICAgKiA8Y29kZT5nZXRSR0JDb2xvclZhbHVlPC9jb2RlPiBtZXRob2QuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBDU1NfUkdCQ09MT1IgICAgICAgICAgICAgID0gMjU7Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgdHlwZSBvZiB0aGUgdmFsdWUgYXMgZGVmaW5lZCBieSB0aGUgY29uc3RhbnRzIHNwZWNpZmllZCBhYm92ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc2hvcnQgZ2V0UHJpbWl0aXZlVHlwZSgpOwotCi0gICAgLyoqCi0gICAgICogIEEgbWV0aG9kIHRvIHNldCB0aGUgZmxvYXQgdmFsdWUgd2l0aCBhIHNwZWNpZmllZCB1bml0LiBJZiB0aGUgcHJvcGVydHkKLSAgICAgKiBhdHRhY2hlZCB3aXRoIHRoaXMgdmFsdWUgY2FuIG5vdCBhY2NlcHQgdGhlIHNwZWNpZmllZCB1bml0IG9yIHRoZQotICAgICAqIGZsb2F0IHZhbHVlLCB0aGUgdmFsdWUgd2lsbCBiZSB1bmNoYW5nZWQgYW5kIGEKLSAgICAgKiA8Y29kZT5ET01FeGNlcHRpb248L2NvZGU+IHdpbGwgYmUgcmFpc2VkLgotICAgICAqIEBwYXJhbSB1bml0VHlwZSAgQSB1bml0IGNvZGUgYXMgZGVmaW5lZCBhYm92ZS4gVGhlIHVuaXQgY29kZSBjYW4gb25seQotICAgICAqICAgYmUgYSBmbG9hdCB1bml0IHR5cGUgKGkuZS4gPGNvZGU+Q1NTX05VTUJFUjwvY29kZT4sCi0gICAgICogICA8Y29kZT5DU1NfUEVSQ0VOVEFHRTwvY29kZT4sIDxjb2RlPkNTU19FTVM8L2NvZGU+LAotICAgICAqICAgPGNvZGU+Q1NTX0VYUzwvY29kZT4sIDxjb2RlPkNTU19QWDwvY29kZT4sIDxjb2RlPkNTU19DTTwvY29kZT4sCi0gICAgICogICA8Y29kZT5DU1NfTU08L2NvZGU+LCA8Y29kZT5DU1NfSU48L2NvZGU+LCA8Y29kZT5DU1NfUFQ8L2NvZGU+LAotICAgICAqICAgPGNvZGU+Q1NTX1BDPC9jb2RlPiwgPGNvZGU+Q1NTX0RFRzwvY29kZT4sIDxjb2RlPkNTU19SQUQ8L2NvZGU+LAotICAgICAqICAgPGNvZGU+Q1NTX0dSQUQ8L2NvZGU+LCA8Y29kZT5DU1NfTVM8L2NvZGU+LCA8Y29kZT5DU1NfUzwvY29kZT4sCi0gICAgICogICA8Y29kZT5DU1NfSFo8L2NvZGU+LCA8Y29kZT5DU1NfS0haPC9jb2RlPiwKLSAgICAgKiAgIDxjb2RlPkNTU19ESU1FTlNJT048L2NvZGU+KS4KLSAgICAgKiBAcGFyYW0gZmxvYXRWYWx1ZSAgVGhlIG5ldyBmbG9hdCB2YWx1ZS4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgIElOVkFMSURfQUNDRVNTX0VSUjogUmFpc2VkIGlmIHRoZSBhdHRhY2hlZCBwcm9wZXJ0eSBkb2Vzbid0IHN1cHBvcnQKLSAgICAgKiAgIHRoZSBmbG9hdCB2YWx1ZSBvciB0aGUgdW5pdCB0eXBlLgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgcHJvcGVydHkgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RmxvYXRWYWx1ZShzaG9ydCB1bml0VHlwZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZsb2F0IGZsb2F0VmFsdWUpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogIFRoaXMgbWV0aG9kIGlzIHVzZWQgdG8gZ2V0IGEgZmxvYXQgdmFsdWUgaW4gYSBzcGVjaWZpZWQgdW5pdC4gSWYgdGhpcwotICAgICAqIENTUyB2YWx1ZSBkb2Vzbid0IGNvbnRhaW4gYSBmbG9hdCB2YWx1ZSBvciBjYW4ndCBiZSBjb252ZXJ0ZWQgaW50bwotICAgICAqIHRoZSBzcGVjaWZpZWQgdW5pdCwgYSA8Y29kZT5ET01FeGNlcHRpb248L2NvZGU+IGlzIHJhaXNlZC4KLSAgICAgKiBAcGFyYW0gdW5pdFR5cGUgIEEgdW5pdCBjb2RlIHRvIGdldCB0aGUgZmxvYXQgdmFsdWUuIFRoZSB1bml0IGNvZGUgY2FuCi0gICAgICogICBvbmx5IGJlIGEgZmxvYXQgdW5pdCB0eXBlIChpLmUuIDxjb2RlPkNTU19OVU1CRVI8L2NvZGU+LAotICAgICAqICAgPGNvZGU+Q1NTX1BFUkNFTlRBR0U8L2NvZGU+LCA8Y29kZT5DU1NfRU1TPC9jb2RlPiwKLSAgICAgKiAgIDxjb2RlPkNTU19FWFM8L2NvZGU+LCA8Y29kZT5DU1NfUFg8L2NvZGU+LCA8Y29kZT5DU1NfQ008L2NvZGU+LAotICAgICAqICAgPGNvZGU+Q1NTX01NPC9jb2RlPiwgPGNvZGU+Q1NTX0lOPC9jb2RlPiwgPGNvZGU+Q1NTX1BUPC9jb2RlPiwKLSAgICAgKiAgIDxjb2RlPkNTU19QQzwvY29kZT4sIDxjb2RlPkNTU19ERUc8L2NvZGU+LCA8Y29kZT5DU1NfUkFEPC9jb2RlPiwKLSAgICAgKiAgIDxjb2RlPkNTU19HUkFEPC9jb2RlPiwgPGNvZGU+Q1NTX01TPC9jb2RlPiwgPGNvZGU+Q1NTX1M8L2NvZGU+LAotICAgICAqICAgPGNvZGU+Q1NTX0haPC9jb2RlPiwgPGNvZGU+Q1NTX0tIWjwvY29kZT4sCi0gICAgICogICA8Y29kZT5DU1NfRElNRU5TSU9OPC9jb2RlPikuCi0gICAgICogQHJldHVybiAgVGhlIGZsb2F0IHZhbHVlIGluIHRoZSBzcGVjaWZpZWQgdW5pdC4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgIElOVkFMSURfQUNDRVNTX0VSUjogUmFpc2VkIGlmIHRoZSBDU1MgdmFsdWUgZG9lc24ndCBjb250YWluIGEgZmxvYXQKLSAgICAgKiAgIHZhbHVlIG9yIGlmIHRoZSBmbG9hdCB2YWx1ZSBjYW4ndCBiZSBjb252ZXJ0ZWQgaW50byB0aGUgc3BlY2lmaWVkCi0gICAgICogICB1bml0LgotICAgICAqLwotICAgIHB1YmxpYyBmbG9hdCBnZXRGbG9hdFZhbHVlKHNob3J0IHVuaXRUeXBlKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiAgQSBtZXRob2QgdG8gc2V0IHRoZSBzdHJpbmcgdmFsdWUgd2l0aCB0aGUgc3BlY2lmaWVkIHVuaXQuIElmIHRoZQotICAgICAqIHByb3BlcnR5IGF0dGFjaGVkIHRvIHRoaXMgdmFsdWUgY2FuJ3QgYWNjZXB0IHRoZSBzcGVjaWZpZWQgdW5pdCBvcgotICAgICAqIHRoZSBzdHJpbmcgdmFsdWUsIHRoZSB2YWx1ZSB3aWxsIGJlIHVuY2hhbmdlZCBhbmQgYQotICAgICAqIDxjb2RlPkRPTUV4Y2VwdGlvbjwvY29kZT4gd2lsbCBiZSByYWlzZWQuCi0gICAgICogQHBhcmFtIHN0cmluZ1R5cGUgIEEgc3RyaW5nIGNvZGUgYXMgZGVmaW5lZCBhYm92ZS4gVGhlIHN0cmluZyBjb2RlIGNhbgotICAgICAqICAgb25seSBiZSBhIHN0cmluZyB1bml0IHR5cGUgKGkuZS4gPGNvZGU+Q1NTX1NUUklORzwvY29kZT4sCi0gICAgICogICA8Y29kZT5DU1NfVVJJPC9jb2RlPiwgPGNvZGU+Q1NTX0lERU5UPC9jb2RlPiwgYW5kCi0gICAgICogICA8Y29kZT5DU1NfQVRUUjwvY29kZT4pLgotICAgICAqIEBwYXJhbSBzdHJpbmdWYWx1ZSAgVGhlIG5ldyBzdHJpbmcgdmFsdWUuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgICBJTlZBTElEX0FDQ0VTU19FUlI6IFJhaXNlZCBpZiB0aGUgQ1NTIHZhbHVlIGRvZXNuJ3QgY29udGFpbiBhIHN0cmluZwotICAgICAqICAgdmFsdWUgb3IgaWYgdGhlIHN0cmluZyB2YWx1ZSBjYW4ndCBiZSBjb252ZXJ0ZWQgaW50byB0aGUgc3BlY2lmaWVkCi0gICAgICogICB1bml0LgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgcHJvcGVydHkgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0U3RyaW5nVmFsdWUoc2hvcnQgc3RyaW5nVHlwZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgc3RyaW5nVmFsdWUpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBUaGlzIG1ldGhvZCBpcyB1c2VkIHRvIGdldCB0aGUgc3RyaW5nIHZhbHVlLiBJZiB0aGUgQ1NTIHZhbHVlIGRvZXNuJ3QKLSAgICAgKiBjb250YWluIGEgc3RyaW5nIHZhbHVlLCBhIDxjb2RlPkRPTUV4Y2VwdGlvbjwvY29kZT4gaXMgcmFpc2VkLiAgU29tZQotICAgICAqIHByb3BlcnRpZXMgKGxpa2UgJ2ZvbnQtZmFtaWx5JyBvciAndm9pY2UtZmFtaWx5JykgY29udmVydCBhCi0gICAgICogd2hpdGVzcGFjZSBzZXBhcmF0ZWQgbGlzdCBvZiBpZGVudHMgdG8gYSBzdHJpbmcuCi0gICAgICogQHJldHVybiAgVGhlIHN0cmluZyB2YWx1ZSBpbiB0aGUgY3VycmVudCB1bml0LiBUaGUgY3VycmVudAotICAgICAqICAgPGNvZGU+cHJpbWl0aXZlVHlwZTwvY29kZT4gY2FuIG9ubHkgYmUgYSBzdHJpbmcgdW5pdCB0eXBlIChpLmUuCi0gICAgICogICA8Y29kZT5DU1NfU1RSSU5HPC9jb2RlPiwgPGNvZGU+Q1NTX1VSSTwvY29kZT4sCi0gICAgICogICA8Y29kZT5DU1NfSURFTlQ8L2NvZGU+IGFuZCA8Y29kZT5DU1NfQVRUUjwvY29kZT4pLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICAgSU5WQUxJRF9BQ0NFU1NfRVJSOiBSYWlzZWQgaWYgdGhlIENTUyB2YWx1ZSBkb2Vzbid0IGNvbnRhaW4gYSBzdHJpbmcKLSAgICAgKiAgIHZhbHVlLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3RyaW5nVmFsdWUoKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBUaGlzIG1ldGhvZCBpcyB1c2VkIHRvIGdldCB0aGUgQ291bnRlciB2YWx1ZS4gSWYgdGhpcyBDU1MgdmFsdWUKLSAgICAgKiBkb2Vzbid0IGNvbnRhaW4gYSBjb3VudGVyIHZhbHVlLCBhIDxjb2RlPkRPTUV4Y2VwdGlvbjwvY29kZT4gaXMKLSAgICAgKiByYWlzZWQuIE1vZGlmaWNhdGlvbiB0byB0aGUgY29ycmVzcG9uZGluZyBzdHlsZSBwcm9wZXJ0eSBjYW4gYmUKLSAgICAgKiBhY2hpZXZlZCB1c2luZyB0aGUgPGNvZGU+Q291bnRlcjwvY29kZT4gaW50ZXJmYWNlLgotICAgICAqIEByZXR1cm4gVGhlIENvdW50ZXIgdmFsdWUuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgICBJTlZBTElEX0FDQ0VTU19FUlI6IFJhaXNlZCBpZiB0aGUgQ1NTIHZhbHVlIGRvZXNuJ3QgY29udGFpbiBhCi0gICAgICogICBDb3VudGVyIHZhbHVlIChlLmcuIHRoaXMgaXMgbm90IDxjb2RlPkNTU19DT1VOVEVSPC9jb2RlPikuCi0gICAgICovCi0gICAgcHVibGljIENvdW50ZXIgZ2V0Q291bnRlclZhbHVlKCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBUaGlzIG1ldGhvZCBpcyB1c2VkIHRvIGdldCB0aGUgUmVjdCB2YWx1ZS4gSWYgdGhpcyBDU1MgdmFsdWUgZG9lc24ndAotICAgICAqIGNvbnRhaW4gYSByZWN0IHZhbHVlLCBhIDxjb2RlPkRPTUV4Y2VwdGlvbjwvY29kZT4gaXMgcmFpc2VkLgotICAgICAqIE1vZGlmaWNhdGlvbiB0byB0aGUgY29ycmVzcG9uZGluZyBzdHlsZSBwcm9wZXJ0eSBjYW4gYmUgYWNoaWV2ZWQKLSAgICAgKiB1c2luZyB0aGUgPGNvZGU+UmVjdDwvY29kZT4gaW50ZXJmYWNlLgotICAgICAqIEByZXR1cm4gVGhlIFJlY3QgdmFsdWUuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgICBJTlZBTElEX0FDQ0VTU19FUlI6IFJhaXNlZCBpZiB0aGUgQ1NTIHZhbHVlIGRvZXNuJ3QgY29udGFpbiBhIFJlY3QKLSAgICAgKiAgIHZhbHVlLiAoZS5nLiB0aGlzIGlzIG5vdCA8Y29kZT5DU1NfUkVDVDwvY29kZT4pLgotICAgICAqLwotICAgIHB1YmxpYyBSZWN0IGdldFJlY3RWYWx1ZSgpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiAgVGhpcyBtZXRob2QgaXMgdXNlZCB0byBnZXQgdGhlIFJHQiBjb2xvci4gSWYgdGhpcyBDU1MgdmFsdWUgZG9lc24ndAotICAgICAqIGNvbnRhaW4gYSBSR0IgY29sb3IgdmFsdWUsIGEgPGNvZGU+RE9NRXhjZXB0aW9uPC9jb2RlPiBpcyByYWlzZWQuCi0gICAgICogTW9kaWZpY2F0aW9uIHRvIHRoZSBjb3JyZXNwb25kaW5nIHN0eWxlIHByb3BlcnR5IGNhbiBiZSBhY2hpZXZlZAotICAgICAqIHVzaW5nIHRoZSA8Y29kZT5SR0JDb2xvcjwvY29kZT4gaW50ZXJmYWNlLgotICAgICAqIEByZXR1cm4gdGhlIFJHQiBjb2xvciB2YWx1ZS4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgIElOVkFMSURfQUNDRVNTX0VSUjogUmFpc2VkIGlmIHRoZSBhdHRhY2hlZCBwcm9wZXJ0eSBjYW4ndCByZXR1cm4gYQotICAgICAqICAgUkdCIGNvbG9yIHZhbHVlIChlLmcuIHRoaXMgaXMgbm90IDxjb2RlPkNTU19SR0JDT0xPUjwvY29kZT4pLgotICAgICAqLwotICAgIHB1YmxpYyBSR0JDb2xvciBnZXRSR0JDb2xvclZhbHVlKCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL3czYy9kb20vY3NzL0NTU1J1bGUuamF2YSBiL3NyYy9vcmcvdzNjL2RvbS9jc3MvQ1NTUnVsZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmODFkMGQ1Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS9jc3MvQ1NTUnVsZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTI2ICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBUaGlzIGZpbGUgaXMgYXZhaWxhYmxlIHVuZGVyIGFuZCBnb3Zlcm5lZCBieSB0aGUgR05VIEdlbmVyYWwgUHVibGljCi0gKiBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqIEhvd2V2ZXIsIHRoZSBmb2xsb3dpbmcgbm90aWNlIGFjY29tcGFuaWVkIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIG9mIHRoaXMKLSAqIGZpbGUgYW5kLCBwZXIgaXRzIHRlcm1zLCBzaG91bGQgbm90IGJlIHJlbW92ZWQ6Ci0gKgotICogQ29weXJpZ2h0IChjKSAyMDAwIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKLSAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAotICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCi0gKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQotICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgotICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgotICogUFVSUE9TRS4KLSAqIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgotICovCi0KLXBhY2thZ2Ugb3JnLnczYy5kb20uY3NzOwotCi1pbXBvcnQgb3JnLnczYy5kb20uRE9NRXhjZXB0aW9uOwotCi0vKioKLSAqICBUaGUgPGNvZGU+Q1NTUnVsZTwvY29kZT4gaW50ZXJmYWNlIGlzIHRoZSBhYnN0cmFjdCBiYXNlIGludGVyZmFjZSBmb3IgYW55Ci0gKiB0eXBlIG9mIENTUyBzdGF0ZW1lbnQuIFRoaXMgaW5jbHVkZXMgYm90aCBydWxlIHNldHMgYW5kIGF0LXJ1bGVzLiBBbgotICogaW1wbGVtZW50YXRpb24gaXMgZXhwZWN0ZWQgdG8gcHJlc2VydmUgYWxsIHJ1bGVzIHNwZWNpZmllZCBpbiBhIENTUyBzdHlsZQotICogc2hlZXQsIGV2ZW4gaWYgdGhlIHJ1bGUgaXMgbm90IHJlY29nbml6ZWQgYnkgdGhlIHBhcnNlci4gVW5yZWNvZ25pemVkCi0gKiBydWxlcyBhcmUgcmVwcmVzZW50ZWQgdXNpbmcgdGhlIDxjb2RlPkNTU1Vua25vd25SdWxlPC9jb2RlPiBpbnRlcmZhY2UuCi0gKiA8cD5TZWUgYWxzbyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMC9SRUMtRE9NLUxldmVsLTItU3R5bGUtMjAwMDExMTMnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAyIFN0eWxlIFNwZWNpZmljYXRpb248L2E+LgotICogQHNpbmNlIERPTSBMZXZlbCAyCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgQ1NTUnVsZSB7Ci0gICAgLy8gUnVsZVR5cGUKLSAgICAvKioKLSAgICAgKiBUaGUgcnVsZSBpcyBhIDxjb2RlPkNTU1Vua25vd25SdWxlPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFVOS05PV05fUlVMRSAgICAgICAgICAgICAgPSAwOwotICAgIC8qKgotICAgICAqIFRoZSBydWxlIGlzIGEgPGNvZGU+Q1NTU3R5bGVSdWxlPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFNUWUxFX1JVTEUgICAgICAgICAgICAgICAgPSAxOwotICAgIC8qKgotICAgICAqIFRoZSBydWxlIGlzIGEgPGNvZGU+Q1NTQ2hhcnNldFJ1bGU8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgQ0hBUlNFVF9SVUxFICAgICAgICAgICAgICA9IDI7Ci0gICAgLyoqCi0gICAgICogVGhlIHJ1bGUgaXMgYSA8Y29kZT5DU1NJbXBvcnRSdWxlPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IElNUE9SVF9SVUxFICAgICAgICAgICAgICAgPSAzOwotICAgIC8qKgotICAgICAqIFRoZSBydWxlIGlzIGEgPGNvZGU+Q1NTTWVkaWFSdWxlPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IE1FRElBX1JVTEUgICAgICAgICAgICAgICAgPSA0OwotICAgIC8qKgotICAgICAqIFRoZSBydWxlIGlzIGEgPGNvZGU+Q1NTRm9udEZhY2VSdWxlPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IEZPTlRfRkFDRV9SVUxFICAgICAgICAgICAgPSA1OwotICAgIC8qKgotICAgICAqIFRoZSBydWxlIGlzIGEgPGNvZGU+Q1NTUGFnZVJ1bGU8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgUEFHRV9SVUxFICAgICAgICAgICAgICAgICA9IDY7Ci0KLSAgICAvKioKLSAgICAgKiAgVGhlIHR5cGUgb2YgdGhlIHJ1bGUsIGFzIGRlZmluZWQgYWJvdmUuIFRoZSBleHBlY3RhdGlvbiBpcyB0aGF0Ci0gICAgICogYmluZGluZy1zcGVjaWZpYyBjYXN0aW5nIG1ldGhvZHMgY2FuIGJlIHVzZWQgdG8gY2FzdCBkb3duIGZyb20gYW4KLSAgICAgKiBpbnN0YW5jZSBvZiB0aGUgPGNvZGU+Q1NTUnVsZTwvY29kZT4gaW50ZXJmYWNlIHRvIHRoZSBzcGVjaWZpYwotICAgICAqIGRlcml2ZWQgaW50ZXJmYWNlIGltcGxpZWQgYnkgdGhlIDxjb2RlPnR5cGU8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBzaG9ydCBnZXRUeXBlKCk7Ci0KLSAgICAvKioKLSAgICAgKiAgVGhlIHBhcnNhYmxlIHRleHR1YWwgcmVwcmVzZW50YXRpb24gb2YgdGhlIHJ1bGUuIFRoaXMgcmVmbGVjdHMgdGhlCi0gICAgICogY3VycmVudCBzdGF0ZSBvZiB0aGUgcnVsZSBhbmQgbm90IGl0cyBpbml0aWFsIHZhbHVlLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q3NzVGV4dCgpOwotICAgIC8qKgotICAgICAqICBUaGUgcGFyc2FibGUgdGV4dHVhbCByZXByZXNlbnRhdGlvbiBvZiB0aGUgcnVsZS4gVGhpcyByZWZsZWN0cyB0aGUKLSAgICAgKiBjdXJyZW50IHN0YXRlIG9mIHRoZSBydWxlIGFuZCBub3QgaXRzIGluaXRpYWwgdmFsdWUuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIFNZTlRBWF9FUlI6IFJhaXNlZCBpZiB0aGUgc3BlY2lmaWVkIENTUyBzdHJpbmcgdmFsdWUgaGFzIGEgc3ludGF4Ci0gICAgICogICBlcnJvciBhbmQgaXMgdW5wYXJzYWJsZS4KLSAgICAgKiAgIDxicj5JTlZBTElEX01PRElGSUNBVElPTl9FUlI6IFJhaXNlZCBpZiB0aGUgc3BlY2lmaWVkIENTUyBzdHJpbmcKLSAgICAgKiAgIHZhbHVlIHJlcHJlc2VudHMgYSBkaWZmZXJlbnQgdHlwZSBvZiBydWxlIHRoYW4gdGhlIGN1cnJlbnQgb25lLgotICAgICAqICAgPGJyPkhJRVJBUkNIWV9SRVFVRVNUX0VSUjogUmFpc2VkIGlmIHRoZSBydWxlIGNhbm5vdCBiZSBpbnNlcnRlZCBhdAotICAgICAqICAgdGhpcyBwb2ludCBpbiB0aGUgc3R5bGUgc2hlZXQuCi0gICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhlIHJ1bGUgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0Q3NzVGV4dChTdHJpbmcgY3NzVGV4dCkKLSAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiAgVGhlIHN0eWxlIHNoZWV0IHRoYXQgY29udGFpbnMgdGhpcyBydWxlLgotICAgICAqLwotICAgIHB1YmxpYyBDU1NTdHlsZVNoZWV0IGdldFBhcmVudFN0eWxlU2hlZXQoKTsKLQotICAgIC8qKgotICAgICAqICBJZiB0aGlzIHJ1bGUgaXMgY29udGFpbmVkIGluc2lkZSBhbm90aGVyIHJ1bGUgKGUuZy4gYSBzdHlsZSBydWxlCi0gICAgICogaW5zaWRlIGFuIEBtZWRpYSBibG9jayksIHRoaXMgaXMgdGhlIGNvbnRhaW5pbmcgcnVsZS4gSWYgdGhpcyBydWxlIGlzCi0gICAgICogbm90IG5lc3RlZCBpbnNpZGUgYW55IG90aGVyIHJ1bGVzLCB0aGlzIHJldHVybnMgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIENTU1J1bGUgZ2V0UGFyZW50UnVsZSgpOwotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL3czYy9kb20vY3NzL0NTU1J1bGVMaXN0LmphdmEgYi9zcmMvb3JnL3czYy9kb20vY3NzL0NTU1J1bGVMaXN0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDMzODQwZWYuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy93M2MvZG9tL2Nzcy9DU1NSdWxlTGlzdC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNzIgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIFRoaXMgZmlsZSBpcyBhdmFpbGFibGUgdW5kZXIgYW5kIGdvdmVybmVkIGJ5IHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKLSAqIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICogSG93ZXZlciwgdGhlIGZvbGxvd2luZyBub3RpY2UgYWNjb21wYW5pZWQgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcwotICogZmlsZSBhbmQsIHBlciBpdHMgdGVybXMsIHNob3VsZCBub3QgYmUgcmVtb3ZlZDoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDAgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKLSAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQotICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCi0gKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKLSAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCi0gKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCi0gKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCi0gKiBQVVJQT1NFLgotICogU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCi0gKi8KLQotcGFja2FnZSBvcmcudzNjLmRvbS5jc3M7Ci0KLS8qKgotICogIFRoZSA8Y29kZT5DU1NSdWxlTGlzdDwvY29kZT4gaW50ZXJmYWNlIHByb3ZpZGVzIHRoZSBhYnN0cmFjdGlvbiBvZiBhbgotICogb3JkZXJlZCBjb2xsZWN0aW9uIG9mIENTUyBydWxlcy4KLSAqIDxwPiBUaGUgaXRlbXMgaW4gdGhlIDxjb2RlPkNTU1J1bGVMaXN0PC9jb2RlPiBhcmUgYWNjZXNzaWJsZSB2aWEgYW4KLSAqIGludGVncmFsIGluZGV4LCBzdGFydGluZyBmcm9tIDAuCi0gKiA8cD5TZWUgYWxzbyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMC9SRUMtRE9NLUxldmVsLTItU3R5bGUtMjAwMDExMTMnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAyIFN0eWxlIFNwZWNpZmljYXRpb248L2E+LgotICogQHNpbmNlIERPTSBMZXZlbCAyCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgQ1NTUnVsZUxpc3QgewotICAgIC8qKgotICAgICAqICBUaGUgbnVtYmVyIG9mIDxjb2RlPkNTU1J1bGVzPC9jb2RlPiBpbiB0aGUgbGlzdC4gVGhlIHJhbmdlIG9mIHZhbGlkCi0gICAgICogY2hpbGQgcnVsZSBpbmRpY2VzIGlzIDxjb2RlPjA8L2NvZGU+IHRvIDxjb2RlPmxlbmd0aC0xPC9jb2RlPgotICAgICAqIGluY2x1c2l2ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldExlbmd0aCgpOwotCi0gICAgLyoqCi0gICAgICogIFVzZWQgdG8gcmV0cmlldmUgYSBDU1MgcnVsZSBieSBvcmRpbmFsIGluZGV4LiBUaGUgb3JkZXIgaW4gdGhpcwotICAgICAqIGNvbGxlY3Rpb24gcmVwcmVzZW50cyB0aGUgb3JkZXIgb2YgdGhlIHJ1bGVzIGluIHRoZSBDU1Mgc3R5bGUgc2hlZXQuCi0gICAgICogSWYgaW5kZXggaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHRoZSBudW1iZXIgb2YgcnVsZXMgaW4gdGhlIGxpc3QsCi0gICAgICogdGhpcyByZXR1cm5zIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAqIEBwYXJhbSBpbmRleCBJbmRleCBpbnRvIHRoZSBjb2xsZWN0aW9uCi0gICAgICogQHJldHVybiBUaGUgc3R5bGUgcnVsZSBhdCB0aGUgPGNvZGU+aW5kZXg8L2NvZGU+IHBvc2l0aW9uIGluIHRoZQotICAgICAqICAgPGNvZGU+Q1NTUnVsZUxpc3Q8L2NvZGU+LCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGF0IGlzIG5vdCBhCi0gICAgICogICB2YWxpZCBpbmRleC4KLSAgICAgKi8KLSAgICBwdWJsaWMgQ1NTUnVsZSBpdGVtKGludCBpbmRleCk7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvdzNjL2RvbS9jc3MvQ1NTU3R5bGVEZWNsYXJhdGlvbi5qYXZhIGIvc3JjL29yZy93M2MvZG9tL2Nzcy9DU1NTdHlsZURlY2xhcmF0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGRlNjMyNjguLjAwMDAwMDAKLS0tIGEvc3JjL29yZy93M2MvZG9tL2Nzcy9DU1NTdHlsZURlY2xhcmF0aW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxOTEgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIFRoaXMgZmlsZSBpcyBhdmFpbGFibGUgdW5kZXIgYW5kIGdvdmVybmVkIGJ5IHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKLSAqIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICogSG93ZXZlciwgdGhlIGZvbGxvd2luZyBub3RpY2UgYWNjb21wYW5pZWQgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcwotICogZmlsZSBhbmQsIHBlciBpdHMgdGVybXMsIHNob3VsZCBub3QgYmUgcmVtb3ZlZDoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDAgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKLSAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQotICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCi0gKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKLSAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCi0gKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCi0gKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCi0gKiBQVVJQT1NFLgotICogU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCi0gKi8KLQotcGFja2FnZSBvcmcudzNjLmRvbS5jc3M7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5ET01FeGNlcHRpb247Ci0KLS8qKgotICogIFRoZSA8Y29kZT5DU1NTdHlsZURlY2xhcmF0aW9uPC9jb2RlPiBpbnRlcmZhY2UgcmVwcmVzZW50cyBhIHNpbmdsZSBDU1MKLSAqIGRlY2xhcmF0aW9uIGJsb2NrLiBUaGlzIGludGVyZmFjZSBtYXkgYmUgdXNlZCB0byBkZXRlcm1pbmUgdGhlIHN0eWxlCi0gKiBwcm9wZXJ0aWVzIGN1cnJlbnRseSBzZXQgaW4gYSBibG9jayBvciB0byBzZXQgc3R5bGUgcHJvcGVydGllcyBleHBsaWNpdGx5Ci0gKiB3aXRoaW4gdGhlIGJsb2NrLgotICogPHA+IFdoaWxlIGFuIGltcGxlbWVudGF0aW9uIG1heSBub3QgcmVjb2duaXplIGFsbCBDU1MgcHJvcGVydGllcyB3aXRoaW4gYQotICogQ1NTIGRlY2xhcmF0aW9uIGJsb2NrLCBpdCBpcyBleHBlY3RlZCB0byBwcm92aWRlIGFjY2VzcyB0byBhbGwgc3BlY2lmaWVkCi0gKiBwcm9wZXJ0aWVzIGluIHRoZSBzdHlsZSBzaGVldCB0aHJvdWdoIHRoZSA8Y29kZT5DU1NTdHlsZURlY2xhcmF0aW9uPC9jb2RlPgotICogIGludGVyZmFjZS4gRnVydGhlcm1vcmUsIGltcGxlbWVudGF0aW9ucyB0aGF0IHN1cHBvcnQgYSBzcGVjaWZpYyBsZXZlbCBvZgotICogQ1NTIHNob3VsZCBjb3JyZWN0bHkgaGFuZGxlIENTUyBzaG9ydGhhbmQgcHJvcGVydGllcyBmb3IgdGhhdCBsZXZlbC4gRm9yCi0gKiBhIGZ1cnRoZXIgZGlzY3Vzc2lvbiBvZiBzaG9ydGhhbmQgcHJvcGVydGllcywgc2VlIHRoZQotICogPGNvZGU+Q1NTMlByb3BlcnRpZXM8L2NvZGU+IGludGVyZmFjZS4KLSAqIDxwPiBUaGlzIGludGVyZmFjZSBpcyBhbHNvIHVzZWQgdG8gcHJvdmlkZSBhIHJlYWQtb25seSBhY2Nlc3MgdG8gdGhlCi0gKiBjb21wdXRlZCB2YWx1ZXMgb2YgYW4gZWxlbWVudC4gU2VlIGFsc28gdGhlIDxjb2RlPlZpZXdDU1M8L2NvZGU+Ci0gKiBpbnRlcmZhY2UuICBUaGUgQ1NTIE9iamVjdCBNb2RlbCBkb2Vzbid0IHByb3ZpZGUgYW4gYWNjZXNzIHRvIHRoZQotICogc3BlY2lmaWVkIG9yIGFjdHVhbCB2YWx1ZXMgb2YgdGhlIENTUyBjYXNjYWRlLgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDAvUkVDLURPTS1MZXZlbC0yLVN0eWxlLTIwMDAxMTEzJz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMiBTdHlsZSBTcGVjaWZpY2F0aW9uPC9hPi4KLSAqIEBzaW5jZSBET00gTGV2ZWwgMgotICovCi1wdWJsaWMgaW50ZXJmYWNlIENTU1N0eWxlRGVjbGFyYXRpb24gewotICAgIC8qKgotICAgICAqICBUaGUgcGFyc2FibGUgdGV4dHVhbCByZXByZXNlbnRhdGlvbiBvZiB0aGUgZGVjbGFyYXRpb24gYmxvY2sKLSAgICAgKiAoZXhjbHVkaW5nIHRoZSBzdXJyb3VuZGluZyBjdXJseSBicmFjZXMpLiBTZXR0aW5nIHRoaXMgYXR0cmlidXRlIHdpbGwKLSAgICAgKiByZXN1bHQgaW4gdGhlIHBhcnNpbmcgb2YgdGhlIG5ldyB2YWx1ZSBhbmQgcmVzZXR0aW5nIG9mIGFsbCB0aGUKLSAgICAgKiBwcm9wZXJ0aWVzIGluIHRoZSBkZWNsYXJhdGlvbiBibG9jayBpbmNsdWRpbmcgdGhlIHJlbW92YWwgb3IgYWRkaXRpb24KLSAgICAgKiBvZiBwcm9wZXJ0aWVzLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q3NzVGV4dCgpOwotICAgIC8qKgotICAgICAqICBUaGUgcGFyc2FibGUgdGV4dHVhbCByZXByZXNlbnRhdGlvbiBvZiB0aGUgZGVjbGFyYXRpb24gYmxvY2sKLSAgICAgKiAoZXhjbHVkaW5nIHRoZSBzdXJyb3VuZGluZyBjdXJseSBicmFjZXMpLiBTZXR0aW5nIHRoaXMgYXR0cmlidXRlIHdpbGwKLSAgICAgKiByZXN1bHQgaW4gdGhlIHBhcnNpbmcgb2YgdGhlIG5ldyB2YWx1ZSBhbmQgcmVzZXR0aW5nIG9mIGFsbCB0aGUKLSAgICAgKiBwcm9wZXJ0aWVzIGluIHRoZSBkZWNsYXJhdGlvbiBibG9jayBpbmNsdWRpbmcgdGhlIHJlbW92YWwgb3IgYWRkaXRpb24KLSAgICAgKiBvZiBwcm9wZXJ0aWVzLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBTWU5UQVhfRVJSOiBSYWlzZWQgaWYgdGhlIHNwZWNpZmllZCBDU1Mgc3RyaW5nIHZhbHVlIGhhcyBhIHN5bnRheAotICAgICAqICAgZXJyb3IgYW5kIGlzIHVucGFyc2FibGUuCi0gICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBkZWNsYXJhdGlvbiBpcwotICAgICAqICAgcmVhZG9ubHkgb3IgYSBwcm9wZXJ0eSBpcyByZWFkb25seS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRDc3NUZXh0KFN0cmluZyBjc3NUZXh0KQotICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogIFVzZWQgdG8gcmV0cmlldmUgdGhlIHZhbHVlIG9mIGEgQ1NTIHByb3BlcnR5IGlmIGl0IGhhcyBiZWVuIGV4cGxpY2l0bHkKLSAgICAgKiBzZXQgd2l0aGluIHRoaXMgZGVjbGFyYXRpb24gYmxvY2suCi0gICAgICogQHBhcmFtIHByb3BlcnR5TmFtZSAgVGhlIG5hbWUgb2YgdGhlIENTUyBwcm9wZXJ0eS4gU2VlIHRoZSBDU1MKLSAgICAgKiAgIHByb3BlcnR5IGluZGV4LgotICAgICAqIEByZXR1cm4gIFJldHVybnMgdGhlIHZhbHVlIG9mIHRoZSBwcm9wZXJ0eSBpZiBpdCBoYXMgYmVlbiBleHBsaWNpdGx5Ci0gICAgICogICBzZXQgZm9yIHRoaXMgZGVjbGFyYXRpb24gYmxvY2suIFJldHVybnMgdGhlIGVtcHR5IHN0cmluZyBpZiB0aGUKLSAgICAgKiAgIHByb3BlcnR5IGhhcyBub3QgYmVlbiBzZXQuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRQcm9wZXJ0eVZhbHVlKFN0cmluZyBwcm9wZXJ0eU5hbWUpOwotCi0gICAgLyoqCi0gICAgICogIFVzZWQgdG8gcmV0cmlldmUgdGhlIG9iamVjdCByZXByZXNlbnRhdGlvbiBvZiB0aGUgdmFsdWUgb2YgYSBDU1MKLSAgICAgKiBwcm9wZXJ0eSBpZiBpdCBoYXMgYmVlbiBleHBsaWNpdGx5IHNldCB3aXRoaW4gdGhpcyBkZWNsYXJhdGlvbiBibG9jay4KLSAgICAgKiBUaGlzIG1ldGhvZCByZXR1cm5zIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoZSBwcm9wZXJ0eSBpcyBhIHNob3J0aGFuZAotICAgICAqIHByb3BlcnR5LiBTaG9ydGhhbmQgcHJvcGVydHkgdmFsdWVzIGNhbiBvbmx5IGJlIGFjY2Vzc2VkIGFuZCBtb2RpZmllZAotICAgICAqIGFzIHN0cmluZ3MsIHVzaW5nIHRoZSA8Y29kZT5nZXRQcm9wZXJ0eVZhbHVlPC9jb2RlPiBhbmQKLSAgICAgKiA8Y29kZT5zZXRQcm9wZXJ0eTwvY29kZT4gbWV0aG9kcy4KLSAgICAgKiBAcGFyYW0gcHJvcGVydHlOYW1lICBUaGUgbmFtZSBvZiB0aGUgQ1NTIHByb3BlcnR5LiBTZWUgdGhlIENTUwotICAgICAqICAgcHJvcGVydHkgaW5kZXguCi0gICAgICogQHJldHVybiAgUmV0dXJucyB0aGUgdmFsdWUgb2YgdGhlIHByb3BlcnR5IGlmIGl0IGhhcyBiZWVuIGV4cGxpY2l0bHkKLSAgICAgKiAgIHNldCBmb3IgdGhpcyBkZWNsYXJhdGlvbiBibG9jay4gUmV0dXJucyA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGUKLSAgICAgKiAgIHByb3BlcnR5IGhhcyBub3QgYmVlbiBzZXQuCi0gICAgICovCi0gICAgcHVibGljIENTU1ZhbHVlIGdldFByb3BlcnR5Q1NTVmFsdWUoU3RyaW5nIHByb3BlcnR5TmFtZSk7Ci0KLSAgICAvKioKLSAgICAgKiAgVXNlZCB0byByZW1vdmUgYSBDU1MgcHJvcGVydHkgaWYgaXQgaGFzIGJlZW4gZXhwbGljaXRseSBzZXQgd2l0aGluCi0gICAgICogdGhpcyBkZWNsYXJhdGlvbiBibG9jay4KLSAgICAgKiBAcGFyYW0gcHJvcGVydHlOYW1lICBUaGUgbmFtZSBvZiB0aGUgQ1NTIHByb3BlcnR5LiBTZWUgdGhlIENTUwotICAgICAqICAgcHJvcGVydHkgaW5kZXguCi0gICAgICogQHJldHVybiAgUmV0dXJucyB0aGUgdmFsdWUgb2YgdGhlIHByb3BlcnR5IGlmIGl0IGhhcyBiZWVuIGV4cGxpY2l0bHkKLSAgICAgKiAgIHNldCBmb3IgdGhpcyBkZWNsYXJhdGlvbiBibG9jay4gUmV0dXJucyB0aGUgZW1wdHkgc3RyaW5nIGlmIHRoZQotICAgICAqICAgcHJvcGVydHkgaGFzIG5vdCBiZWVuIHNldCBvciB0aGUgcHJvcGVydHkgbmFtZSBkb2VzIG5vdCBjb3JyZXNwb25kCi0gICAgICogICB0byBhIGtub3duIENTUyBwcm9wZXJ0eS4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBkZWNsYXJhdGlvbiBpcyByZWFkb25seQotICAgICAqICAgb3IgdGhlIHByb3BlcnR5IGlzIHJlYWRvbmx5LgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgcmVtb3ZlUHJvcGVydHkoU3RyaW5nIHByb3BlcnR5TmFtZSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiAgVXNlZCB0byByZXRyaWV2ZSB0aGUgcHJpb3JpdHkgb2YgYSBDU1MgcHJvcGVydHkgKGUuZy4gdGhlCi0gICAgICogPGNvZGU+ImltcG9ydGFudCI8L2NvZGU+IHF1YWxpZmllcikgaWYgdGhlIHByaW9yaXR5IGhhcyBiZWVuCi0gICAgICogZXhwbGljaXRseSBzZXQgaW4gdGhpcyBkZWNsYXJhdGlvbiBibG9jay4KLSAgICAgKiBAcGFyYW0gcHJvcGVydHlOYW1lICBUaGUgbmFtZSBvZiB0aGUgQ1NTIHByb3BlcnR5LiBTZWUgdGhlIENTUwotICAgICAqICAgcHJvcGVydHkgaW5kZXguCi0gICAgICogQHJldHVybiAgQSBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBwcmlvcml0eSAoZS5nLgotICAgICAqICAgPGNvZGU+ImltcG9ydGFudCI8L2NvZGU+KSBpZiB0aGUgcHJvcGVydHkgaGFzIGJlZW4gZXhwbGljaXRseSBzZXQKLSAgICAgKiAgIGluIHRoaXMgZGVjbGFyYXRpb24gYmxvY2sgYW5kIGhhcyBhIHByaW9yaXR5IHNwZWNpZmllZC4gVGhlIGVtcHR5Ci0gICAgICogICBzdHJpbmcgb3RoZXJ3aXNlLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0UHJvcGVydHlQcmlvcml0eShTdHJpbmcgcHJvcGVydHlOYW1lKTsKLQotICAgIC8qKgotICAgICAqICBVc2VkIHRvIHNldCBhIHByb3BlcnR5IHZhbHVlIGFuZCBwcmlvcml0eSB3aXRoaW4gdGhpcyBkZWNsYXJhdGlvbgotICAgICAqIGJsb2NrLiA8Y29kZT5zZXRQcm9wZXJ0eTwvY29kZT4gcGVybWl0cyB0byBtb2RpZnkgYSBwcm9wZXJ0eSBvciBhZGQgYQotICAgICAqIG5ldyBvbmUgaW4gdGhlIGRlY2xhcmF0aW9uIGJsb2NrLiBBbnkgY2FsbCB0byB0aGlzIG1ldGhvZCBtYXkgbW9kaWZ5Ci0gICAgICogdGhlIG9yZGVyIG9mIHByb3BlcnRpZXMgaW4gdGhlIDxjb2RlPml0ZW08L2NvZGU+IG1ldGhvZC4KLSAgICAgKiBAcGFyYW0gcHJvcGVydHlOYW1lICBUaGUgbmFtZSBvZiB0aGUgQ1NTIHByb3BlcnR5LiBTZWUgdGhlIENTUwotICAgICAqICAgcHJvcGVydHkgaW5kZXguCi0gICAgICogQHBhcmFtIHZhbHVlICBUaGUgbmV3IHZhbHVlIG9mIHRoZSBwcm9wZXJ0eS4KLSAgICAgKiBAcGFyYW0gcHJpb3JpdHkgIFRoZSBuZXcgcHJpb3JpdHkgb2YgdGhlIHByb3BlcnR5IChlLmcuCi0gICAgICogICA8Y29kZT4iaW1wb3J0YW50IjwvY29kZT4pIG9yIHRoZSBlbXB0eSBzdHJpbmcgaWYgbm9uZS4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgU1lOVEFYX0VSUjogUmFpc2VkIGlmIHRoZSBzcGVjaWZpZWQgdmFsdWUgaGFzIGEgc3ludGF4IGVycm9yIGFuZCBpcwotICAgICAqICAgdW5wYXJzYWJsZS4KLSAgICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIGRlY2xhcmF0aW9uIGlzCi0gICAgICogICByZWFkb25seSBvciB0aGUgcHJvcGVydHkgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0UHJvcGVydHkoU3RyaW5nIHByb3BlcnR5TmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdmFsdWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHByaW9yaXR5KQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiAgVGhlIG51bWJlciBvZiBwcm9wZXJ0aWVzIHRoYXQgaGF2ZSBiZWVuIGV4cGxpY2l0bHkgc2V0IGluIHRoaXMKLSAgICAgKiBkZWNsYXJhdGlvbiBibG9jay4gVGhlIHJhbmdlIG9mIHZhbGlkIGluZGljZXMgaXMgMCB0byBsZW5ndGgtMQotICAgICAqIGluY2x1c2l2ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldExlbmd0aCgpOwotCi0gICAgLyoqCi0gICAgICogIFVzZWQgdG8gcmV0cmlldmUgdGhlIHByb3BlcnRpZXMgdGhhdCBoYXZlIGJlZW4gZXhwbGljaXRseSBzZXQgaW4gdGhpcwotICAgICAqIGRlY2xhcmF0aW9uIGJsb2NrLiBUaGUgb3JkZXIgb2YgdGhlIHByb3BlcnRpZXMgcmV0cmlldmVkIHVzaW5nIHRoaXMKLSAgICAgKiBtZXRob2QgZG9lcyBub3QgaGF2ZSB0byBiZSB0aGUgb3JkZXIgaW4gd2hpY2ggdGhleSB3ZXJlIHNldC4gVGhpcwotICAgICAqIG1ldGhvZCBjYW4gYmUgdXNlZCB0byBpdGVyYXRlIG92ZXIgYWxsIHByb3BlcnRpZXMgaW4gdGhpcyBkZWNsYXJhdGlvbgotICAgICAqIGJsb2NrLgotICAgICAqIEBwYXJhbSBpbmRleCAgSW5kZXggb2YgdGhlIHByb3BlcnR5IG5hbWUgdG8gcmV0cmlldmUuCi0gICAgICogQHJldHVybiAgVGhlIG5hbWUgb2YgdGhlIHByb3BlcnR5IGF0IHRoaXMgb3JkaW5hbCBwb3NpdGlvbi4gVGhlIGVtcHR5Ci0gICAgICogICBzdHJpbmcgaWYgbm8gcHJvcGVydHkgZXhpc3RzIGF0IHRoaXMgcG9zaXRpb24uCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBpdGVtKGludCBpbmRleCk7Ci0KLSAgICAvKioKLSAgICAgKiAgVGhlIENTUyBydWxlIHRoYXQgY29udGFpbnMgdGhpcyBkZWNsYXJhdGlvbiBibG9jayBvciA8Y29kZT5udWxsPC9jb2RlPgotICAgICAqIGlmIHRoaXMgPGNvZGU+Q1NTU3R5bGVEZWNsYXJhdGlvbjwvY29kZT4gaXMgbm90IGF0dGFjaGVkIHRvIGEKLSAgICAgKiA8Y29kZT5DU1NSdWxlPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgQ1NTUnVsZSBnZXRQYXJlbnRSdWxlKCk7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvdzNjL2RvbS9jc3MvQ1NTU3R5bGVSdWxlLmphdmEgYi9zcmMvb3JnL3czYy9kb20vY3NzL0NTU1N0eWxlUnVsZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlMTY1Y2QxLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS9jc3MvQ1NTU3R5bGVSdWxlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3NiArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogVGhpcyBmaWxlIGlzIGF2YWlsYWJsZSB1bmRlciBhbmQgZ292ZXJuZWQgYnkgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwotICogTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKiBIb3dldmVyLCB0aGUgZm9sbG93aW5nIG5vdGljZSBhY2NvbXBhbmllZCB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGlzCi0gKiBmaWxlIGFuZCwgcGVyIGl0cyB0ZXJtcywgc2hvdWxkIG5vdCBiZSByZW1vdmVkOgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAotICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCi0gKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKLSAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQotICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKLSAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KLSAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKLSAqIFBVUlBPU0UuCi0gKiBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KLSAqLwotCi1wYWNrYWdlIG9yZy53M2MuZG9tLmNzczsKLQotaW1wb3J0IG9yZy53M2MuZG9tLkRPTUV4Y2VwdGlvbjsKLQotLyoqCi0gKiAgVGhlIDxjb2RlPkNTU1N0eWxlUnVsZTwvY29kZT4gaW50ZXJmYWNlIHJlcHJlc2VudHMgYSBzaW5nbGUgcnVsZSBzZXQgaW4gYQotICogQ1NTIHN0eWxlIHNoZWV0LgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDAvUkVDLURPTS1MZXZlbC0yLVN0eWxlLTIwMDAxMTEzJz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMiBTdHlsZSBTcGVjaWZpY2F0aW9uPC9hPi4KLSAqIEBzaW5jZSBET00gTGV2ZWwgMgotICovCi1wdWJsaWMgaW50ZXJmYWNlIENTU1N0eWxlUnVsZSBleHRlbmRzIENTU1J1bGUgewotICAgIC8qKgotICAgICAqICBUaGUgdGV4dHVhbCByZXByZXNlbnRhdGlvbiBvZiB0aGUgc2VsZWN0b3IgZm9yIHRoZSBydWxlIHNldC4gVGhlCi0gICAgICogaW1wbGVtZW50YXRpb24gbWF5IGhhdmUgc3RyaXBwZWQgb3V0IGluc2lnbmlmaWNhbnQgd2hpdGVzcGFjZSB3aGlsZQotICAgICAqIHBhcnNpbmcgdGhlIHNlbGVjdG9yLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0U2VsZWN0b3JUZXh0KCk7Ci0gICAgLyoqCi0gICAgICogIFRoZSB0ZXh0dWFsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBzZWxlY3RvciBmb3IgdGhlIHJ1bGUgc2V0LiBUaGUKLSAgICAgKiBpbXBsZW1lbnRhdGlvbiBtYXkgaGF2ZSBzdHJpcHBlZCBvdXQgaW5zaWduaWZpY2FudCB3aGl0ZXNwYWNlIHdoaWxlCi0gICAgICogcGFyc2luZyB0aGUgc2VsZWN0b3IuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIFNZTlRBWF9FUlI6IFJhaXNlZCBpZiB0aGUgc3BlY2lmaWVkIENTUyBzdHJpbmcgdmFsdWUgaGFzIGEgc3ludGF4Ci0gICAgICogICBlcnJvciBhbmQgaXMgdW5wYXJzYWJsZS4KLSAgICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIHJ1bGUgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0U2VsZWN0b3JUZXh0KFN0cmluZyBzZWxlY3RvclRleHQpCi0gICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogIFRoZSBkZWNsYXJhdGlvbi1ibG9jayBvZiB0aGlzIHJ1bGUgc2V0LgotICAgICAqLwotICAgIHB1YmxpYyBDU1NTdHlsZURlY2xhcmF0aW9uIGdldFN0eWxlKCk7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvdzNjL2RvbS9jc3MvQ1NTU3R5bGVTaGVldC5qYXZhIGIvc3JjL29yZy93M2MvZG9tL2Nzcy9DU1NTdHlsZVNoZWV0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGQzY2Y3MjMuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy93M2MvZG9tL2Nzcy9DU1NTdHlsZVNoZWV0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMTQgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIFRoaXMgZmlsZSBpcyBhdmFpbGFibGUgdW5kZXIgYW5kIGdvdmVybmVkIGJ5IHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKLSAqIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICogSG93ZXZlciwgdGhlIGZvbGxvd2luZyBub3RpY2UgYWNjb21wYW5pZWQgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcwotICogZmlsZSBhbmQsIHBlciBpdHMgdGVybXMsIHNob3VsZCBub3QgYmUgcmVtb3ZlZDoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDAgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKLSAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQotICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCi0gKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKLSAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCi0gKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCi0gKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCi0gKiBQVVJQT1NFLgotICogU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCi0gKi8KLQotcGFja2FnZSBvcmcudzNjLmRvbS5jc3M7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5ET01FeGNlcHRpb247Ci1pbXBvcnQgb3JnLnczYy5kb20uc3R5bGVzaGVldHMuU3R5bGVTaGVldDsKLQotLyoqCi0gKiAgVGhlIDxjb2RlPkNTU1N0eWxlU2hlZXQ8L2NvZGU+IGludGVyZmFjZSBpcyBhIGNvbmNyZXRlIGludGVyZmFjZSB1c2VkIHRvCi0gKiByZXByZXNlbnQgYSBDU1Mgc3R5bGUgc2hlZXQgaS5lLiwgYSBzdHlsZSBzaGVldCB3aG9zZSBjb250ZW50IHR5cGUgaXMKLSAqICJ0ZXh0L2NzcyIuCi0gKiA8cD5TZWUgYWxzbyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMC9SRUMtRE9NLUxldmVsLTItU3R5bGUtMjAwMDExMTMnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAyIFN0eWxlIFNwZWNpZmljYXRpb248L2E+LgotICogQHNpbmNlIERPTSBMZXZlbCAyCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgQ1NTU3R5bGVTaGVldCBleHRlbmRzIFN0eWxlU2hlZXQgewotICAgIC8qKgotICAgICAqICBJZiB0aGlzIHN0eWxlIHNoZWV0IGNvbWVzIGZyb20gYW4gPGNvZGU+QGltcG9ydDwvY29kZT4gcnVsZSwgdGhlCi0gICAgICogPGNvZGU+b3duZXJSdWxlPC9jb2RlPiBhdHRyaWJ1dGUgd2lsbCBjb250YWluIHRoZQotICAgICAqIDxjb2RlPkNTU0ltcG9ydFJ1bGU8L2NvZGU+LiBJbiB0aGF0IGNhc2UsIHRoZSA8Y29kZT5vd25lck5vZGU8L2NvZGU+Ci0gICAgICogYXR0cmlidXRlIGluIHRoZSA8Y29kZT5TdHlsZVNoZWV0PC9jb2RlPiBpbnRlcmZhY2Ugd2lsbCBiZQotICAgICAqIDxjb2RlPm51bGw8L2NvZGU+LiBJZiB0aGUgc3R5bGUgc2hlZXQgY29tZXMgZnJvbSBhbiBlbGVtZW50IG9yIGEKLSAgICAgKiBwcm9jZXNzaW5nIGluc3RydWN0aW9uLCB0aGUgPGNvZGU+b3duZXJSdWxlPC9jb2RlPiBhdHRyaWJ1dGUgd2lsbCBiZQotICAgICAqIDxjb2RlPm51bGw8L2NvZGU+IGFuZCB0aGUgPGNvZGU+b3duZXJOb2RlPC9jb2RlPiBhdHRyaWJ1dGUgd2lsbAotICAgICAqIGNvbnRhaW4gdGhlIDxjb2RlPk5vZGU8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBDU1NSdWxlIGdldE93bmVyUnVsZSgpOwotCi0gICAgLyoqCi0gICAgICogIFRoZSBsaXN0IG9mIGFsbCBDU1MgcnVsZXMgY29udGFpbmVkIHdpdGhpbiB0aGUgc3R5bGUgc2hlZXQuIFRoaXMKLSAgICAgKiBpbmNsdWRlcyBib3RoIHJ1bGUgc2V0cyBhbmQgYXQtcnVsZXMuCi0gICAgICovCi0gICAgcHVibGljIENTU1J1bGVMaXN0IGdldENzc1J1bGVzKCk7Ci0KLSAgICAvKioKLSAgICAgKiAgVXNlZCB0byBpbnNlcnQgYSBuZXcgcnVsZSBpbnRvIHRoZSBzdHlsZSBzaGVldC4gVGhlIG5ldyBydWxlIG5vdwotICAgICAqIGJlY29tZXMgcGFydCBvZiB0aGUgY2FzY2FkZS4KLSAgICAgKiBAcGFyYW0gcnVsZSAgVGhlIHBhcnNhYmxlIHRleHQgcmVwcmVzZW50aW5nIHRoZSBydWxlLiBGb3IgcnVsZSBzZXRzCi0gICAgICogICB0aGlzIGNvbnRhaW5zIGJvdGggdGhlIHNlbGVjdG9yIGFuZCB0aGUgc3R5bGUgZGVjbGFyYXRpb24uIEZvcgotICAgICAqICAgYXQtcnVsZXMsIHRoaXMgc3BlY2lmaWVzIGJvdGggdGhlIGF0LWlkZW50aWZpZXIgYW5kIHRoZSBydWxlCi0gICAgICogICBjb250ZW50LgotICAgICAqIEBwYXJhbSBpbmRleCAgVGhlIGluZGV4IHdpdGhpbiB0aGUgc3R5bGUgc2hlZXQncyBydWxlIGxpc3Qgb2YgdGhlIHJ1bGUKLSAgICAgKiAgIGJlZm9yZSB3aGljaCB0byBpbnNlcnQgdGhlIHNwZWNpZmllZCBydWxlLiBJZiB0aGUgc3BlY2lmaWVkIGluZGV4Ci0gICAgICogICBpcyBlcXVhbCB0byB0aGUgbGVuZ3RoIG9mIHRoZSBzdHlsZSBzaGVldCdzIHJ1bGUgY29sbGVjdGlvbiwgdGhlCi0gICAgICogICBydWxlIHdpbGwgYmUgYWRkZWQgdG8gdGhlIGVuZCBvZiB0aGUgc3R5bGUgc2hlZXQuCi0gICAgICogQHJldHVybiAgVGhlIGluZGV4IHdpdGhpbiB0aGUgc3R5bGUgc2hlZXQncyBydWxlIGNvbGxlY3Rpb24gb2YgdGhlCi0gICAgICogICBuZXdseSBpbnNlcnRlZCBydWxlLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBISUVSQVJDSFlfUkVRVUVTVF9FUlI6IFJhaXNlZCBpZiB0aGUgcnVsZSBjYW5ub3QgYmUgaW5zZXJ0ZWQgYXQgdGhlCi0gICAgICogICBzcGVjaWZpZWQgaW5kZXggZS5nLiBpZiBhbiA8Y29kZT5AaW1wb3J0PC9jb2RlPiBydWxlIGlzIGluc2VydGVkCi0gICAgICogICBhZnRlciBhIHN0YW5kYXJkIHJ1bGUgc2V0IG9yIG90aGVyIGF0LXJ1bGUuCi0gICAgICogICA8YnI+SU5ERVhfU0laRV9FUlI6IFJhaXNlZCBpZiB0aGUgc3BlY2lmaWVkIGluZGV4IGlzIG5vdCBhIHZhbGlkCi0gICAgICogICBpbnNlcnRpb24gcG9pbnQuCi0gICAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBzdHlsZSBzaGVldCBpcwotICAgICAqICAgcmVhZG9ubHkuCi0gICAgICogICA8YnI+U1lOVEFYX0VSUjogUmFpc2VkIGlmIHRoZSBzcGVjaWZpZWQgcnVsZSBoYXMgYSBzeW50YXggZXJyb3IgYW5kCi0gICAgICogICBpcyB1bnBhcnNhYmxlLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgaW5zZXJ0UnVsZShTdHJpbmcgcnVsZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGluZGV4KQotICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogIFVzZWQgdG8gZGVsZXRlIGEgcnVsZSBmcm9tIHRoZSBzdHlsZSBzaGVldC4KLSAgICAgKiBAcGFyYW0gaW5kZXggIFRoZSBpbmRleCB3aXRoaW4gdGhlIHN0eWxlIHNoZWV0J3MgcnVsZSBsaXN0IG9mIHRoZSBydWxlCi0gICAgICogICB0byByZW1vdmUuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIElOREVYX1NJWkVfRVJSOiBSYWlzZWQgaWYgdGhlIHNwZWNpZmllZCBpbmRleCBkb2VzIG5vdCBjb3JyZXNwb25kIHRvCi0gICAgICogICBhIHJ1bGUgaW4gdGhlIHN0eWxlIHNoZWV0J3MgcnVsZSBsaXN0LgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgc3R5bGUgc2hlZXQgaXMKLSAgICAgKiAgIHJlYWRvbmx5LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGRlbGV0ZVJ1bGUoaW50IGluZGV4KQotICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy93M2MvZG9tL2Nzcy9DU1NVbmtub3duUnVsZS5qYXZhIGIvc3JjL29yZy93M2MvZG9tL2Nzcy9DU1NVbmtub3duUnVsZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwYjFkODdiLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS9jc3MvQ1NTVW5rbm93blJ1bGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDUxICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBUaGlzIGZpbGUgaXMgYXZhaWxhYmxlIHVuZGVyIGFuZCBnb3Zlcm5lZCBieSB0aGUgR05VIEdlbmVyYWwgUHVibGljCi0gKiBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqIEhvd2V2ZXIsIHRoZSBmb2xsb3dpbmcgbm90aWNlIGFjY29tcGFuaWVkIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIG9mIHRoaXMKLSAqIGZpbGUgYW5kLCBwZXIgaXRzIHRlcm1zLCBzaG91bGQgbm90IGJlIHJlbW92ZWQ6Ci0gKgotICogQ29weXJpZ2h0IChjKSAyMDAwIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKLSAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAotICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCi0gKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQotICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgotICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgotICogUFVSUE9TRS4KLSAqIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgotICovCi0KLXBhY2thZ2Ugb3JnLnczYy5kb20uY3NzOwotCi0vKioKLSAqICBUaGUgPGNvZGU+Q1NTVW5rbm93blJ1bGU8L2NvZGU+IGludGVyZmFjZSByZXByZXNlbnRzIGFuIGF0LXJ1bGUgbm90Ci0gKiBzdXBwb3J0ZWQgYnkgdGhpcyB1c2VyIGFnZW50LgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDAvUkVDLURPTS1MZXZlbC0yLVN0eWxlLTIwMDAxMTEzJz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMiBTdHlsZSBTcGVjaWZpY2F0aW9uPC9hPi4KLSAqIEBzaW5jZSBET00gTGV2ZWwgMgotICovCi1wdWJsaWMgaW50ZXJmYWNlIENTU1Vua25vd25SdWxlIGV4dGVuZHMgQ1NTUnVsZSB7Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL3czYy9kb20vY3NzL0NTU1ZhbHVlLmphdmEgYi9zcmMvb3JnL3czYy9kb20vY3NzL0NTU1ZhbHVlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGFlNGVmZmEuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy93M2MvZG9tL2Nzcy9DU1NWYWx1ZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTAwICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBUaGlzIGZpbGUgaXMgYXZhaWxhYmxlIHVuZGVyIGFuZCBnb3Zlcm5lZCBieSB0aGUgR05VIEdlbmVyYWwgUHVibGljCi0gKiBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqIEhvd2V2ZXIsIHRoZSBmb2xsb3dpbmcgbm90aWNlIGFjY29tcGFuaWVkIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIG9mIHRoaXMKLSAqIGZpbGUgYW5kLCBwZXIgaXRzIHRlcm1zLCBzaG91bGQgbm90IGJlIHJlbW92ZWQ6Ci0gKgotICogQ29weXJpZ2h0IChjKSAyMDAwIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKLSAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAotICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCi0gKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQotICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgotICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgotICogUFVSUE9TRS4KLSAqIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgotICovCi0KLXBhY2thZ2Ugb3JnLnczYy5kb20uY3NzOwotCi1pbXBvcnQgb3JnLnczYy5kb20uRE9NRXhjZXB0aW9uOwotCi0vKioKLSAqICBUaGUgPGNvZGU+Q1NTVmFsdWU8L2NvZGU+IGludGVyZmFjZSByZXByZXNlbnRzIGEgc2ltcGxlIG9yIGEgY29tcGxleAotICogdmFsdWUuIEEgPGNvZGU+Q1NTVmFsdWU8L2NvZGU+IG9iamVjdCBvbmx5IG9jY3VycyBpbiBhIGNvbnRleHQgb2YgYSBDU1MKLSAqIHByb3BlcnR5LgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDAvUkVDLURPTS1MZXZlbC0yLVN0eWxlLTIwMDAxMTEzJz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMiBTdHlsZSBTcGVjaWZpY2F0aW9uPC9hPi4KLSAqIEBzaW5jZSBET00gTGV2ZWwgMgotICovCi1wdWJsaWMgaW50ZXJmYWNlIENTU1ZhbHVlIHsKLSAgICAvLyBVbml0VHlwZXMKLSAgICAvKioKLSAgICAgKiBUaGUgdmFsdWUgaXMgaW5oZXJpdGVkIGFuZCB0aGUgPGNvZGU+Y3NzVGV4dDwvY29kZT4gY29udGFpbnMgImluaGVyaXQiLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgQ1NTX0lOSEVSSVQgICAgICAgICAgICAgICA9IDA7Ci0gICAgLyoqCi0gICAgICogVGhlIHZhbHVlIGlzIGEgcHJpbWl0aXZlIHZhbHVlIGFuZCBhbiBpbnN0YW5jZSBvZiB0aGUKLSAgICAgKiA8Y29kZT5DU1NQcmltaXRpdmVWYWx1ZTwvY29kZT4gaW50ZXJmYWNlIGNhbiBiZSBvYnRhaW5lZCBieSB1c2luZwotICAgICAqIGJpbmRpbmctc3BlY2lmaWMgY2FzdGluZyBtZXRob2RzIG9uIHRoaXMgaW5zdGFuY2Ugb2YgdGhlCi0gICAgICogPGNvZGU+Q1NTVmFsdWU8L2NvZGU+IGludGVyZmFjZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IENTU19QUklNSVRJVkVfVkFMVUUgICAgICAgPSAxOwotICAgIC8qKgotICAgICAqIFRoZSB2YWx1ZSBpcyBhIDxjb2RlPkNTU1ZhbHVlPC9jb2RlPiBsaXN0IGFuZCBhbiBpbnN0YW5jZSBvZiB0aGUKLSAgICAgKiA8Y29kZT5DU1NWYWx1ZUxpc3Q8L2NvZGU+IGludGVyZmFjZSBjYW4gYmUgb2J0YWluZWQgYnkgdXNpbmcKLSAgICAgKiBiaW5kaW5nLXNwZWNpZmljIGNhc3RpbmcgbWV0aG9kcyBvbiB0aGlzIGluc3RhbmNlIG9mIHRoZQotICAgICAqIDxjb2RlPkNTU1ZhbHVlPC9jb2RlPiBpbnRlcmZhY2UuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBDU1NfVkFMVUVfTElTVCAgICAgICAgICAgID0gMjsKLSAgICAvKioKLSAgICAgKiBUaGUgdmFsdWUgaXMgYSBjdXN0b20gdmFsdWUuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBDU1NfQ1VTVE9NICAgICAgICAgICAgICAgID0gMzsKLQotICAgIC8qKgotICAgICAqICBBIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgY3VycmVudCB2YWx1ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldENzc1RleHQoKTsKLSAgICAvKioKLSAgICAgKiAgQSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGN1cnJlbnQgdmFsdWUuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgICBTWU5UQVhfRVJSOiBSYWlzZWQgaWYgdGhlIHNwZWNpZmllZCBDU1Mgc3RyaW5nIHZhbHVlIGhhcyBhIHN5bnRheAotICAgICAqICAgZXJyb3IgKGFjY29yZGluZyB0byB0aGUgYXR0YWNoZWQgcHJvcGVydHkpIG9yIGlzIHVucGFyc2FibGUuCi0gICAgICogICA8YnI+SU5WQUxJRF9NT0RJRklDQVRJT05fRVJSOiBSYWlzZWQgaWYgdGhlIHNwZWNpZmllZCBDU1Mgc3RyaW5nCi0gICAgICogICB2YWx1ZSByZXByZXNlbnRzIGEgZGlmZmVyZW50IHR5cGUgb2YgdmFsdWVzIHRoYW4gdGhlIHZhbHVlcyBhbGxvd2VkCi0gICAgICogICBieSB0aGUgQ1NTIHByb3BlcnR5LgotICAgICAqICAgPGJyPiBOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIHZhbHVlIGlzIHJlYWRvbmx5LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldENzc1RleHQoU3RyaW5nIGNzc1RleHQpCi0gICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiAgQSBjb2RlIGRlZmluaW5nIHRoZSB0eXBlIG9mIHRoZSB2YWx1ZSBhcyBkZWZpbmVkIGFib3ZlLgotICAgICAqLwotICAgIHB1YmxpYyBzaG9ydCBnZXRDc3NWYWx1ZVR5cGUoKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy93M2MvZG9tL2Nzcy9DU1NWYWx1ZUxpc3QuamF2YSBiL3NyYy9vcmcvdzNjL2RvbS9jc3MvQ1NTVmFsdWVMaXN0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDE1NjczOTkuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy93M2MvZG9tL2Nzcy9DU1NWYWx1ZUxpc3QuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDc1ICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBUaGlzIGZpbGUgaXMgYXZhaWxhYmxlIHVuZGVyIGFuZCBnb3Zlcm5lZCBieSB0aGUgR05VIEdlbmVyYWwgUHVibGljCi0gKiBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqIEhvd2V2ZXIsIHRoZSBmb2xsb3dpbmcgbm90aWNlIGFjY29tcGFuaWVkIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIG9mIHRoaXMKLSAqIGZpbGUgYW5kLCBwZXIgaXRzIHRlcm1zLCBzaG91bGQgbm90IGJlIHJlbW92ZWQ6Ci0gKgotICogQ29weXJpZ2h0IChjKSAyMDAwIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKLSAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAotICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCi0gKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQotICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgotICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgotICogUFVSUE9TRS4KLSAqIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgotICovCi0KLXBhY2thZ2Ugb3JnLnczYy5kb20uY3NzOwotCi0vKioKLSAqIFRoZSA8Y29kZT5DU1NWYWx1ZUxpc3Q8L2NvZGU+IGludGVyZmFjZSBwcm92aWRlcyB0aGUgYWJzdHJhY3Rpb24gb2YgYW4KLSAqIG9yZGVyZWQgY29sbGVjdGlvbiBvZiBDU1MgdmFsdWVzLgotICogPHA+IFNvbWUgcHJvcGVydGllcyBhbGxvdyBhbiBlbXB0eSBsaXN0IGludG8gdGhlaXIgc3ludGF4LiBJbiB0aGF0IGNhc2UsCi0gKiB0aGVzZSBwcm9wZXJ0aWVzIHRha2UgdGhlIDxjb2RlPm5vbmU8L2NvZGU+IGlkZW50aWZpZXIuIFNvLCBhbiBlbXB0eSBsaXN0Ci0gKiBtZWFucyB0aGF0IHRoZSBwcm9wZXJ0eSBoYXMgdGhlIHZhbHVlIDxjb2RlPm5vbmU8L2NvZGU+LgotICogPHA+IFRoZSBpdGVtcyBpbiB0aGUgPGNvZGU+Q1NTVmFsdWVMaXN0PC9jb2RlPiBhcmUgYWNjZXNzaWJsZSB2aWEgYW4KLSAqIGludGVncmFsIGluZGV4LCBzdGFydGluZyBmcm9tIDAuCi0gKiA8cD5TZWUgYWxzbyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMC9SRUMtRE9NLUxldmVsLTItU3R5bGUtMjAwMDExMTMnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAyIFN0eWxlIFNwZWNpZmljYXRpb248L2E+LgotICogQHNpbmNlIERPTSBMZXZlbCAyCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgQ1NTVmFsdWVMaXN0IGV4dGVuZHMgQ1NTVmFsdWUgewotICAgIC8qKgotICAgICAqIFRoZSBudW1iZXIgb2YgPGNvZGU+Q1NTVmFsdWVzPC9jb2RlPiBpbiB0aGUgbGlzdC4gVGhlIHJhbmdlIG9mIHZhbGlkCi0gICAgICogdmFsdWVzIG9mIHRoZSBpbmRpY2VzIGlzIDxjb2RlPjA8L2NvZGU+IHRvIDxjb2RlPmxlbmd0aC0xPC9jb2RlPgotICAgICAqIGluY2x1c2l2ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldExlbmd0aCgpOwotCi0gICAgLyoqCi0gICAgICogVXNlZCB0byByZXRyaWV2ZSBhIDxjb2RlPkNTU1ZhbHVlPC9jb2RlPiBieSBvcmRpbmFsIGluZGV4LiBUaGUgb3JkZXIgaW4KLSAgICAgKiB0aGlzIGNvbGxlY3Rpb24gcmVwcmVzZW50cyB0aGUgb3JkZXIgb2YgdGhlIHZhbHVlcyBpbiB0aGUgQ1NTIHN0eWxlCi0gICAgICogcHJvcGVydHkuIElmIGluZGV4IGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byB0aGUgbnVtYmVyIG9mIHZhbHVlcwotICAgICAqIGluIHRoZSBsaXN0LCB0aGlzIHJldHVybnMgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICogQHBhcmFtIGluZGV4IEluZGV4IGludG8gdGhlIGNvbGxlY3Rpb24uCi0gICAgICogQHJldHVybiBUaGUgPGNvZGU+Q1NTVmFsdWU8L2NvZGU+IGF0IHRoZSA8Y29kZT5pbmRleDwvY29kZT4gcG9zaXRpb24KLSAgICAgKiAgIGluIHRoZSA8Y29kZT5DU1NWYWx1ZUxpc3Q8L2NvZGU+LCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGF0IGlzCi0gICAgICogICBub3QgYSB2YWxpZCBpbmRleC4KLSAgICAgKi8KLSAgICBwdWJsaWMgQ1NTVmFsdWUgaXRlbShpbnQgaW5kZXgpOwotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL3czYy9kb20vY3NzL0NvdW50ZXIuamF2YSBiL3NyYy9vcmcvdzNjL2RvbS9jc3MvQ291bnRlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0NGEyOTkzLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS9jc3MvQ291bnRlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNjcgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIFRoaXMgZmlsZSBpcyBhdmFpbGFibGUgdW5kZXIgYW5kIGdvdmVybmVkIGJ5IHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKLSAqIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICogSG93ZXZlciwgdGhlIGZvbGxvd2luZyBub3RpY2UgYWNjb21wYW5pZWQgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcwotICogZmlsZSBhbmQsIHBlciBpdHMgdGVybXMsIHNob3VsZCBub3QgYmUgcmVtb3ZlZDoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDAgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKLSAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQotICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCi0gKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKLSAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCi0gKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCi0gKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCi0gKiBQVVJQT1NFLgotICogU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCi0gKi8KLQotcGFja2FnZSBvcmcudzNjLmRvbS5jc3M7Ci0KLS8qKgotICogIFRoZSA8Y29kZT5Db3VudGVyPC9jb2RlPiBpbnRlcmZhY2UgaXMgdXNlZCB0byByZXByZXNlbnQgYW55IGNvdW50ZXIgb3IKLSAqIGNvdW50ZXJzIGZ1bmN0aW9uIHZhbHVlLiBUaGlzIGludGVyZmFjZSByZWZsZWN0cyB0aGUgdmFsdWVzIGluIHRoZQotICogdW5kZXJseWluZyBzdHlsZSBwcm9wZXJ0eS4KLSAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAwL1JFQy1ET00tTGV2ZWwtMi1TdHlsZS0yMDAwMTExMyc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDIgU3R5bGUgU3BlY2lmaWNhdGlvbjwvYT4uCi0gKiBAc2luY2UgRE9NIExldmVsIDIKLSAqLwotcHVibGljIGludGVyZmFjZSBDb3VudGVyIHsKLSAgICAvKioKLSAgICAgKiAgVGhpcyBhdHRyaWJ1dGUgaXMgdXNlZCBmb3IgdGhlIGlkZW50aWZpZXIgb2YgdGhlIGNvdW50ZXIuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRJZGVudGlmaWVyKCk7Ci0KLSAgICAvKioKLSAgICAgKiAgVGhpcyBhdHRyaWJ1dGUgaXMgdXNlZCBmb3IgdGhlIHN0eWxlIG9mIHRoZSBsaXN0LgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TGlzdFN0eWxlKCk7Ci0KLSAgICAvKioKLSAgICAgKiAgVGhpcyBhdHRyaWJ1dGUgaXMgdXNlZCBmb3IgdGhlIHNlcGFyYXRvciBvZiB0aGUgbmVzdGVkIGNvdW50ZXJzLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0U2VwYXJhdG9yKCk7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvdzNjL2RvbS9jc3MvRE9NSW1wbGVtZW50YXRpb25DU1MuamF2YSBiL3NyYy9vcmcvdzNjL2RvbS9jc3MvRE9NSW1wbGVtZW50YXRpb25DU1MuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMmFlYjM3ZS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3czYy9kb20vY3NzL0RPTUltcGxlbWVudGF0aW9uQ1NTLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw2OSArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogVGhpcyBmaWxlIGlzIGF2YWlsYWJsZSB1bmRlciBhbmQgZ292ZXJuZWQgYnkgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwotICogTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKiBIb3dldmVyLCB0aGUgZm9sbG93aW5nIG5vdGljZSBhY2NvbXBhbmllZCB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGlzCi0gKiBmaWxlIGFuZCwgcGVyIGl0cyB0ZXJtcywgc2hvdWxkIG5vdCBiZSByZW1vdmVkOgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAotICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCi0gKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKLSAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQotICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKLSAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KLSAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKLSAqIFBVUlBPU0UuCi0gKiBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KLSAqLwotCi1wYWNrYWdlIG9yZy53M2MuZG9tLmNzczsKLQotaW1wb3J0IG9yZy53M2MuZG9tLkRPTUltcGxlbWVudGF0aW9uOwotaW1wb3J0IG9yZy53M2MuZG9tLkRPTUV4Y2VwdGlvbjsKLQotLyoqCi0gKiAgVGhpcyBpbnRlcmZhY2UgYWxsb3dzIHRoZSBET00gdXNlciB0byBjcmVhdGUgYSA8Y29kZT5DU1NTdHlsZVNoZWV0PC9jb2RlPgotICogb3V0c2lkZSB0aGUgY29udGV4dCBvZiBhIGRvY3VtZW50LiBUaGVyZSBpcyBubyB3YXkgdG8gYXNzb2NpYXRlIHRoZSBuZXcKLSAqIDxjb2RlPkNTU1N0eWxlU2hlZXQ8L2NvZGU+IHdpdGggYSBkb2N1bWVudCBpbiBET00gTGV2ZWwgMi4KLSAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAwL1JFQy1ET00tTGV2ZWwtMi1TdHlsZS0yMDAwMTExMyc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDIgU3R5bGUgU3BlY2lmaWNhdGlvbjwvYT4uCi0gKiBAc2luY2UgRE9NICAgTGV2ZWwgMgotICovCi1wdWJsaWMgaW50ZXJmYWNlIERPTUltcGxlbWVudGF0aW9uQ1NTIGV4dGVuZHMgRE9NSW1wbGVtZW50YXRpb24gewotICAgIC8qKgotICAgICAqIENyZWF0ZXMgYSBuZXcgPGNvZGU+Q1NTU3R5bGVTaGVldDwvY29kZT4uCi0gICAgICogQHBhcmFtIHRpdGxlICBUaGUgYWR2aXNvcnkgdGl0bGUuIFNlZSBhbHNvIHRoZSAgc2VjdGlvbi4KLSAgICAgKiBAcGFyYW0gbWVkaWEgIFRoZSBjb21tYS1zZXBhcmF0ZWQgbGlzdCBvZiBtZWRpYSBhc3NvY2lhdGVkIHdpdGggdGhlCi0gICAgICogICBuZXcgc3R5bGUgc2hlZXQuIFNlZSBhbHNvIHRoZSAgc2VjdGlvbi4KLSAgICAgKiBAcmV0dXJuIEEgbmV3IENTUyBzdHlsZSBzaGVldC4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgIFNZTlRBWF9FUlI6IFJhaXNlZCBpZiB0aGUgc3BlY2lmaWVkIG1lZGlhIHN0cmluZyB2YWx1ZSBoYXMgYSBzeW50YXgKLSAgICAgKiAgIGVycm9yIGFuZCBpcyB1bnBhcnNhYmxlLgotICAgICAqLwotICAgIHB1YmxpYyBDU1NTdHlsZVNoZWV0IGNyZWF0ZUNTU1N0eWxlU2hlZXQoU3RyaW5nIHRpdGxlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG1lZGlhKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy93M2MvZG9tL2Nzcy9Eb2N1bWVudENTUy5qYXZhIGIvc3JjL29yZy93M2MvZG9tL2Nzcy9Eb2N1bWVudENTUy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0NzM5OWE3Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS9jc3MvRG9jdW1lbnRDU1MuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDc5ICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBUaGlzIGZpbGUgaXMgYXZhaWxhYmxlIHVuZGVyIGFuZCBnb3Zlcm5lZCBieSB0aGUgR05VIEdlbmVyYWwgUHVibGljCi0gKiBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqIEhvd2V2ZXIsIHRoZSBmb2xsb3dpbmcgbm90aWNlIGFjY29tcGFuaWVkIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIG9mIHRoaXMKLSAqIGZpbGUgYW5kLCBwZXIgaXRzIHRlcm1zLCBzaG91bGQgbm90IGJlIHJlbW92ZWQ6Ci0gKgotICogQ29weXJpZ2h0IChjKSAyMDAwIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKLSAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAotICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCi0gKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQotICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgotICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgotICogUFVSUE9TRS4KLSAqIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgotICovCi0KLXBhY2thZ2Ugb3JnLnczYy5kb20uY3NzOwotCi1pbXBvcnQgb3JnLnczYy5kb20uRWxlbWVudDsKLWltcG9ydCBvcmcudzNjLmRvbS5zdHlsZXNoZWV0cy5Eb2N1bWVudFN0eWxlOwotCi0vKioKLSAqIFRoaXMgaW50ZXJmYWNlIHJlcHJlc2VudHMgYSBkb2N1bWVudCB3aXRoIGEgQ1NTIHZpZXcuCi0gKiA8cD4gVGhlIDxjb2RlPmdldE92ZXJyaWRlU3R5bGU8L2NvZGU+IG1ldGhvZCBwcm92aWRlcyBhIG1lY2hhbmlzbSB0aHJvdWdoCi0gKiB3aGljaCBhIERPTSBhdXRob3IgY291bGQgZWZmZWN0IGltbWVkaWF0ZSBjaGFuZ2UgdG8gdGhlIHN0eWxlIG9mIGFuCi0gKiBlbGVtZW50IHdpdGhvdXQgbW9kaWZ5aW5nIHRoZSBleHBsaWNpdGx5IGxpbmtlZCBzdHlsZSBzaGVldHMgb2YgYQotICogZG9jdW1lbnQgb3IgdGhlIGlubGluZSBzdHlsZSBvZiBlbGVtZW50cyBpbiB0aGUgc3R5bGUgc2hlZXRzLiBUaGlzIHN0eWxlCi0gKiBzaGVldCBjb21lcyBhZnRlciB0aGUgYXV0aG9yIHN0eWxlIHNoZWV0IGluIHRoZSBjYXNjYWRlIGFsZ29yaXRobSBhbmQgaXMKLSAqIGNhbGxlZCBvdmVycmlkZSBzdHlsZSBzaGVldC4gVGhlIG92ZXJyaWRlIHN0eWxlIHNoZWV0IHRha2VzIHByZWNlZGVuY2UKLSAqIG92ZXIgYXV0aG9yIHN0eWxlIHNoZWV0cy4gQW4gIiFpbXBvcnRhbnQiIGRlY2xhcmF0aW9uIHN0aWxsIHRha2VzCi0gKiBwcmVjZWRlbmNlIG92ZXIgYSBub3JtYWwgZGVjbGFyYXRpb24uIE92ZXJyaWRlLCBhdXRob3IsIGFuZCB1c2VyIHN0eWxlCi0gKiBzaGVldHMgYWxsIG1heSBjb250YWluICIhaW1wb3J0YW50IiBkZWNsYXJhdGlvbnMuIFVzZXIgIiFpbXBvcnRhbnQiIHJ1bGVzCi0gKiB0YWtlIHByZWNlZGVuY2Ugb3ZlciBib3RoIG92ZXJyaWRlIGFuZCBhdXRob3IgIiFpbXBvcnRhbnQiIHJ1bGVzLCBhbmQKLSAqIG92ZXJyaWRlICIhaW1wb3J0YW50IiBydWxlcyB0YWtlIHByZWNlZGVuY2Ugb3ZlciBhdXRob3IgIiFpbXBvcnRhbnQiCi0gKiBydWxlcy4KLSAqIDxwPiBUaGUgZXhwZWN0YXRpb24gaXMgdGhhdCBhbiBpbnN0YW5jZSBvZiB0aGUgPGNvZGU+RG9jdW1lbnRDU1M8L2NvZGU+Ci0gKiBpbnRlcmZhY2UgY2FuIGJlIG9idGFpbmVkIGJ5IHVzaW5nIGJpbmRpbmctc3BlY2lmaWMgY2FzdGluZyBtZXRob2RzIG9uIGFuCi0gKiBpbnN0YW5jZSBvZiB0aGUgPGNvZGU+RG9jdW1lbnQ8L2NvZGU+IGludGVyZmFjZS4KLSAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAwL1JFQy1ET00tTGV2ZWwtMi1TdHlsZS0yMDAwMTExMyc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDIgU3R5bGUgU3BlY2lmaWNhdGlvbjwvYT4uCi0gKiBAc2luY2UgRE9NIExldmVsIDIKLSAqLwotcHVibGljIGludGVyZmFjZSBEb2N1bWVudENTUyBleHRlbmRzIERvY3VtZW50U3R5bGUgewotICAgIC8qKgotICAgICAqICBUaGlzIG1ldGhvZCBpcyB1c2VkIHRvIHJldHJpZXZlIHRoZSBvdmVycmlkZSBzdHlsZSBkZWNsYXJhdGlvbiBmb3IgYQotICAgICAqIHNwZWNpZmllZCBlbGVtZW50IGFuZCBhIHNwZWNpZmllZCBwc2V1ZG8tZWxlbWVudC4KLSAgICAgKiBAcGFyYW0gZWx0ICBUaGUgZWxlbWVudCB3aG9zZSBzdHlsZSBpcyB0byBiZSBtb2RpZmllZC4gVGhpcyBwYXJhbWV0ZXIKLSAgICAgKiAgIGNhbm5vdCBiZSBudWxsLgotICAgICAqIEBwYXJhbSBwc2V1ZG9FbHQgIFRoZSBwc2V1ZG8tZWxlbWVudCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiBub25lLgotICAgICAqIEByZXR1cm4gIFRoZSBvdmVycmlkZSBzdHlsZSBkZWNsYXJhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgQ1NTU3R5bGVEZWNsYXJhdGlvbiBnZXRPdmVycmlkZVN0eWxlKEVsZW1lbnQgZWx0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHBzZXVkb0VsdCk7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvdzNjL2RvbS9jc3MvRWxlbWVudENTU0lubGluZVN0eWxlLmphdmEgYi9zcmMvb3JnL3czYy9kb20vY3NzL0VsZW1lbnRDU1NJbmxpbmVTdHlsZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjN2U3MDUzLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS9jc3MvRWxlbWVudENTU0lubGluZVN0eWxlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw2MSArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogVGhpcyBmaWxlIGlzIGF2YWlsYWJsZSB1bmRlciBhbmQgZ292ZXJuZWQgYnkgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwotICogTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKiBIb3dldmVyLCB0aGUgZm9sbG93aW5nIG5vdGljZSBhY2NvbXBhbmllZCB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGlzCi0gKiBmaWxlIGFuZCwgcGVyIGl0cyB0ZXJtcywgc2hvdWxkIG5vdCBiZSByZW1vdmVkOgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAotICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCi0gKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKLSAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQotICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKLSAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KLSAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKLSAqIFBVUlBPU0UuCi0gKiBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KLSAqLwotCi1wYWNrYWdlIG9yZy53M2MuZG9tLmNzczsKLQotLyoqCi0gKiAgSW5saW5lIHN0eWxlIGluZm9ybWF0aW9uIGF0dGFjaGVkIHRvIGVsZW1lbnRzIGlzIGV4cG9zZWQgdGhyb3VnaCB0aGUKLSAqIDxjb2RlPnN0eWxlPC9jb2RlPiBhdHRyaWJ1dGUuIFRoaXMgcmVwcmVzZW50cyB0aGUgY29udGVudHMgb2YgdGhlIFNUWUxFCi0gKiBhdHRyaWJ1dGUgZm9yIEhUTUwgZWxlbWVudHMgKG9yIGVsZW1lbnRzIGluIG90aGVyIHNjaGVtYXMgb3IgRFREcyB3aGljaAotICogdXNlIHRoZSBTVFlMRSBhdHRyaWJ1dGUgaW4gdGhlIHNhbWUgd2F5KS4gVGhlIGV4cGVjdGF0aW9uIGlzIHRoYXQgYW4KLSAqIGluc3RhbmNlIG9mIHRoZSBFbGVtZW50Q1NTSW5saW5lU3R5bGUgaW50ZXJmYWNlIGNhbiBiZSBvYnRhaW5lZCBieSB1c2luZwotICogYmluZGluZy1zcGVjaWZpYyBjYXN0aW5nIG1ldGhvZHMgb24gYW4gaW5zdGFuY2Ugb2YgdGhlIEVsZW1lbnQgaW50ZXJmYWNlCi0gKiB3aGVuIHRoZSBlbGVtZW50IHN1cHBvcnRzIGlubGluZSBDU1Mgc3R5bGUgaW5mb3JtYXRpb25zLgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDAvUkVDLURPTS1MZXZlbC0yLVN0eWxlLTIwMDAxMTEzJz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMiBTdHlsZSBTcGVjaWZpY2F0aW9uPC9hPi4KLSAqIEBzaW5jZSBET00gTGV2ZWwgMgotICovCi1wdWJsaWMgaW50ZXJmYWNlIEVsZW1lbnRDU1NJbmxpbmVTdHlsZSB7Ci0gICAgLyoqCi0gICAgICogIFRoZSBzdHlsZSBhdHRyaWJ1dGUuCi0gICAgICovCi0gICAgcHVibGljIENTU1N0eWxlRGVjbGFyYXRpb24gZ2V0U3R5bGUoKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy93M2MvZG9tL2Nzcy9SR0JDb2xvci5qYXZhIGIvc3JjL29yZy93M2MvZG9tL2Nzcy9SR0JDb2xvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3ZDM3NDU4Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS9jc3MvUkdCQ29sb3IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDc2ICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBUaGlzIGZpbGUgaXMgYXZhaWxhYmxlIHVuZGVyIGFuZCBnb3Zlcm5lZCBieSB0aGUgR05VIEdlbmVyYWwgUHVibGljCi0gKiBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqIEhvd2V2ZXIsIHRoZSBmb2xsb3dpbmcgbm90aWNlIGFjY29tcGFuaWVkIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIG9mIHRoaXMKLSAqIGZpbGUgYW5kLCBwZXIgaXRzIHRlcm1zLCBzaG91bGQgbm90IGJlIHJlbW92ZWQ6Ci0gKgotICogQ29weXJpZ2h0IChjKSAyMDAwIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKLSAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAotICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCi0gKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQotICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgotICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgotICogUFVSUE9TRS4KLSAqIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgotICovCi0KLXBhY2thZ2Ugb3JnLnczYy5kb20uY3NzOwotCi0vKioKLSAqICBUaGUgPGNvZGU+UkdCQ29sb3I8L2NvZGU+IGludGVyZmFjZSBpcyB1c2VkIHRvIHJlcHJlc2VudCBhbnkgUkdCIGNvbG9yCi0gKiB2YWx1ZS4gVGhpcyBpbnRlcmZhY2UgcmVmbGVjdHMgdGhlIHZhbHVlcyBpbiB0aGUgdW5kZXJseWluZyBzdHlsZQotICogcHJvcGVydHkuIEhlbmNlLCBtb2RpZmljYXRpb25zIG1hZGUgdG8gdGhlIDxjb2RlPkNTU1ByaW1pdGl2ZVZhbHVlPC9jb2RlPgotICogb2JqZWN0cyBtb2RpZnkgdGhlIHN0eWxlIHByb3BlcnR5LgotICogPHA+IEEgc3BlY2lmaWVkIFJHQiBjb2xvciBpcyBub3QgY2xpcHBlZCAoZXZlbiBpZiB0aGUgbnVtYmVyIGlzIG91dHNpZGUgdGhlCi0gKiByYW5nZSAwLTI1NSBvciAwJS0xMDAlKS4gQSBjb21wdXRlZCBSR0IgY29sb3IgaXMgY2xpcHBlZCBkZXBlbmRpbmcgb24gdGhlCi0gKiBkZXZpY2UuCi0gKiA8cD4gRXZlbiBpZiBhIHN0eWxlIHNoZWV0IGNhbiBvbmx5IGNvbnRhaW4gYW4gaW50ZWdlciBmb3IgYSBjb2xvciB2YWx1ZSwKLSAqIHRoZSBpbnRlcm5hbCBzdG9yYWdlIG9mIHRoaXMgaW50ZWdlciBpcyBhIGZsb2F0LCBhbmQgdGhpcyBjYW4gYmUgdXNlZCBhcwotICogYSBmbG9hdCBpbiB0aGUgc3BlY2lmaWVkIG9yIHRoZSBjb21wdXRlZCBzdHlsZS4KLSAqIDxwPiBBIGNvbG9yIHBlcmNlbnRhZ2UgdmFsdWUgY2FuIGFsd2F5cyBiZSBjb252ZXJ0ZWQgdG8gYSBudW1iZXIgYW5kIHZpY2UKLSAqIHZlcnNhLgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDAvUkVDLURPTS1MZXZlbC0yLVN0eWxlLTIwMDAxMTEzJz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMiBTdHlsZSBTcGVjaWZpY2F0aW9uPC9hPi4KLSAqIEBzaW5jZSBET00gTGV2ZWwgMgotICovCi1wdWJsaWMgaW50ZXJmYWNlIFJHQkNvbG9yIHsKLSAgICAvKioKLSAgICAgKiAgVGhpcyBhdHRyaWJ1dGUgaXMgdXNlZCBmb3IgdGhlIHJlZCB2YWx1ZSBvZiB0aGUgUkdCIGNvbG9yLgotICAgICAqLwotICAgIHB1YmxpYyBDU1NQcmltaXRpdmVWYWx1ZSBnZXRSZWQoKTsKLQotICAgIC8qKgotICAgICAqICBUaGlzIGF0dHJpYnV0ZSBpcyB1c2VkIGZvciB0aGUgZ3JlZW4gdmFsdWUgb2YgdGhlIFJHQiBjb2xvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgQ1NTUHJpbWl0aXZlVmFsdWUgZ2V0R3JlZW4oKTsKLQotICAgIC8qKgotICAgICAqICBUaGlzIGF0dHJpYnV0ZSBpcyB1c2VkIGZvciB0aGUgYmx1ZSB2YWx1ZSBvZiB0aGUgUkdCIGNvbG9yLgotICAgICAqLwotICAgIHB1YmxpYyBDU1NQcmltaXRpdmVWYWx1ZSBnZXRCbHVlKCk7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvdzNjL2RvbS9jc3MvUmVjdC5qYXZhIGIvc3JjL29yZy93M2MvZG9tL2Nzcy9SZWN0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGI5ZTY5NTYuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy93M2MvZG9tL2Nzcy9SZWN0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3MyArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogVGhpcyBmaWxlIGlzIGF2YWlsYWJsZSB1bmRlciBhbmQgZ292ZXJuZWQgYnkgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwotICogTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKiBIb3dldmVyLCB0aGUgZm9sbG93aW5nIG5vdGljZSBhY2NvbXBhbmllZCB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGlzCi0gKiBmaWxlIGFuZCwgcGVyIGl0cyB0ZXJtcywgc2hvdWxkIG5vdCBiZSByZW1vdmVkOgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAotICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCi0gKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKLSAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQotICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKLSAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KLSAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKLSAqIFBVUlBPU0UuCi0gKiBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KLSAqLwotCi1wYWNrYWdlIG9yZy53M2MuZG9tLmNzczsKLQotLyoqCi0gKiAgVGhlIDxjb2RlPlJlY3Q8L2NvZGU+IGludGVyZmFjZSBpcyB1c2VkIHRvIHJlcHJlc2VudCBhbnkgcmVjdCB2YWx1ZS4gVGhpcwotICogaW50ZXJmYWNlIHJlZmxlY3RzIHRoZSB2YWx1ZXMgaW4gdGhlIHVuZGVybHlpbmcgc3R5bGUgcHJvcGVydHkuIEhlbmNlLAotICogbW9kaWZpY2F0aW9ucyBtYWRlIHRvIHRoZSA8Y29kZT5DU1NQcmltaXRpdmVWYWx1ZTwvY29kZT4gb2JqZWN0cyBtb2RpZnkKLSAqIHRoZSBzdHlsZSBwcm9wZXJ0eS4KLSAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAwL1JFQy1ET00tTGV2ZWwtMi1TdHlsZS0yMDAwMTExMyc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDIgU3R5bGUgU3BlY2lmaWNhdGlvbjwvYT4uCi0gKiBAc2luY2UgRE9NIExldmVsIDIKLSAqLwotcHVibGljIGludGVyZmFjZSBSZWN0IHsKLSAgICAvKioKLSAgICAgKiAgVGhpcyBhdHRyaWJ1dGUgaXMgdXNlZCBmb3IgdGhlIHRvcCBvZiB0aGUgcmVjdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgQ1NTUHJpbWl0aXZlVmFsdWUgZ2V0VG9wKCk7Ci0KLSAgICAvKioKLSAgICAgKiAgVGhpcyBhdHRyaWJ1dGUgaXMgdXNlZCBmb3IgdGhlIHJpZ2h0IG9mIHRoZSByZWN0LgotICAgICAqLwotICAgIHB1YmxpYyBDU1NQcmltaXRpdmVWYWx1ZSBnZXRSaWdodCgpOwotCi0gICAgLyoqCi0gICAgICogIFRoaXMgYXR0cmlidXRlIGlzIHVzZWQgZm9yIHRoZSBib3R0b20gb2YgdGhlIHJlY3QuCi0gICAgICovCi0gICAgcHVibGljIENTU1ByaW1pdGl2ZVZhbHVlIGdldEJvdHRvbSgpOwotCi0gICAgLyoqCi0gICAgICogIFRoaXMgYXR0cmlidXRlIGlzIHVzZWQgZm9yIHRoZSBsZWZ0IG9mIHRoZSByZWN0LgotICAgICAqLwotICAgIHB1YmxpYyBDU1NQcmltaXRpdmVWYWx1ZSBnZXRMZWZ0KCk7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvdzNjL2RvbS9jc3MvVmlld0NTUy5qYXZhIGIvc3JjL29yZy93M2MvZG9tL2Nzcy9WaWV3Q1NTLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDM4YjIyYjMuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy93M2MvZG9tL2Nzcy9WaWV3Q1NTLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3MiArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogVGhpcyBmaWxlIGlzIGF2YWlsYWJsZSB1bmRlciBhbmQgZ292ZXJuZWQgYnkgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwotICogTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKiBIb3dldmVyLCB0aGUgZm9sbG93aW5nIG5vdGljZSBhY2NvbXBhbmllZCB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGlzCi0gKiBmaWxlIGFuZCwgcGVyIGl0cyB0ZXJtcywgc2hvdWxkIG5vdCBiZSByZW1vdmVkOgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAotICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCi0gKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKLSAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQotICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKLSAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KLSAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKLSAqIFBVUlBPU0UuCi0gKiBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KLSAqLwotCi1wYWNrYWdlIG9yZy53M2MuZG9tLmNzczsKLQotaW1wb3J0IG9yZy53M2MuZG9tLkVsZW1lbnQ7Ci1pbXBvcnQgb3JnLnczYy5kb20udmlld3MuQWJzdHJhY3RWaWV3OwotCi0vKioKLSAqICBUaGlzIGludGVyZmFjZSByZXByZXNlbnRzIGEgQ1NTIHZpZXcuIFRoZSA8Y29kZT5nZXRDb21wdXRlZFN0eWxlPC9jb2RlPgotICogbWV0aG9kIHByb3ZpZGVzIGEgcmVhZCBvbmx5IGFjY2VzcyB0byB0aGUgY29tcHV0ZWQgdmFsdWVzIG9mIGFuIGVsZW1lbnQuCi0gKiA8cD4gVGhlIGV4cGVjdGF0aW9uIGlzIHRoYXQgYW4gaW5zdGFuY2Ugb2YgdGhlIDxjb2RlPlZpZXdDU1M8L2NvZGU+Ci0gKiBpbnRlcmZhY2UgY2FuIGJlIG9idGFpbmVkIGJ5IHVzaW5nIGJpbmRpbmctc3BlY2lmaWMgY2FzdGluZyBtZXRob2RzIG9uIGFuCi0gKiBpbnN0YW5jZSBvZiB0aGUgPGNvZGU+QWJzdHJhY3RWaWV3PC9jb2RlPiBpbnRlcmZhY2UuCi0gKiA8cD4gU2luY2UgYSBjb21wdXRlZCBzdHlsZSBpcyByZWxhdGVkIHRvIGFuIDxjb2RlPkVsZW1lbnQ8L2NvZGU+IG5vZGUsIGlmCi0gKiB0aGlzIGVsZW1lbnQgaXMgcmVtb3ZlZCBmcm9tIHRoZSBkb2N1bWVudCwgdGhlIGFzc29jaWF0ZWQKLSAqIDxjb2RlPkNTU1N0eWxlRGVjbGFyYXRpb248L2NvZGU+IGFuZCA8Y29kZT5DU1NWYWx1ZTwvY29kZT4gcmVsYXRlZCB0bwotICogdGhpcyBkZWNsYXJhdGlvbiBhcmUgbm8gbG9uZ2VyIHZhbGlkLgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDAvUkVDLURPTS1MZXZlbC0yLVN0eWxlLTIwMDAxMTEzJz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMiBTdHlsZSBTcGVjaWZpY2F0aW9uPC9hPi4KLSAqIEBzaW5jZSBET00gTGV2ZWwgMgotICovCi1wdWJsaWMgaW50ZXJmYWNlIFZpZXdDU1MgZXh0ZW5kcyBBYnN0cmFjdFZpZXcgewotICAgIC8qKgotICAgICAqICBUaGlzIG1ldGhvZCBpcyB1c2VkIHRvIGdldCB0aGUgY29tcHV0ZWQgc3R5bGUgYXMgaXQgaXMgZGVmaW5lZCBpbiBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMTk5OC9SRUMtQ1NTMi0xOTk4MDUxMic+Q1NTMjwvYT5dLgotICAgICAqIEBwYXJhbSBlbHQgIFRoZSBlbGVtZW50IHdob3NlIHN0eWxlIGlzIHRvIGJlIGNvbXB1dGVkLiBUaGlzIHBhcmFtZXRlcgotICAgICAqICAgY2Fubm90IGJlIG51bGwuCi0gICAgICogQHBhcmFtIHBzZXVkb0VsdCAgVGhlIHBzZXVkby1lbGVtZW50IG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIG5vbmUuCi0gICAgICogQHJldHVybiAgVGhlIGNvbXB1dGVkIHN0eWxlLiBUaGUgPGNvZGU+Q1NTU3R5bGVEZWNsYXJhdGlvbjwvY29kZT4gaXMKLSAgICAgKiAgIHJlYWQtb25seSBhbmQgY29udGFpbnMgb25seSBhYnNvbHV0ZSB2YWx1ZXMuCi0gICAgICovCi0gICAgcHVibGljIENTU1N0eWxlRGVjbGFyYXRpb24gZ2V0Q29tcHV0ZWRTdHlsZShFbGVtZW50IGVsdCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBwc2V1ZG9FbHQpOwotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL3czYy9kb20vZXZlbnRzL0RvY3VtZW50RXZlbnQuamF2YSBiL3NyYy9vcmcvdzNjL2RvbS9ldmVudHMvRG9jdW1lbnRFdmVudC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjZGJiYjM2Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS9ldmVudHMvRG9jdW1lbnRFdmVudC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsODUgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIFRoaXMgZmlsZSBpcyBhdmFpbGFibGUgdW5kZXIgYW5kIGdvdmVybmVkIGJ5IHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKLSAqIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICogSG93ZXZlciwgdGhlIGZvbGxvd2luZyBub3RpY2UgYWNjb21wYW5pZWQgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcwotICogZmlsZSBhbmQsIHBlciBpdHMgdGVybXMsIHNob3VsZCBub3QgYmUgcmVtb3ZlZDoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDAgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKLSAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQotICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCi0gKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKLSAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCi0gKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCi0gKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCi0gKiBQVVJQT1NFLgotICogU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCi0gKi8KLQotcGFja2FnZSBvcmcudzNjLmRvbS5ldmVudHM7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5ET01FeGNlcHRpb247Ci0KLS8qKgotICogIFRoZSA8Y29kZT5Eb2N1bWVudEV2ZW50PC9jb2RlPiBpbnRlcmZhY2UgcHJvdmlkZXMgYSBtZWNoYW5pc20gYnkgd2hpY2ggdGhlCi0gKiB1c2VyIGNhbiBjcmVhdGUgYW4gRXZlbnQgb2YgYSB0eXBlIHN1cHBvcnRlZCBieSB0aGUgaW1wbGVtZW50YXRpb24uIEl0IGlzCi0gKiBleHBlY3RlZCB0aGF0IHRoZSA8Y29kZT5Eb2N1bWVudEV2ZW50PC9jb2RlPiBpbnRlcmZhY2Ugd2lsbCBiZQotICogaW1wbGVtZW50ZWQgb24gdGhlIHNhbWUgb2JqZWN0IHdoaWNoIGltcGxlbWVudHMgdGhlIDxjb2RlPkRvY3VtZW50PC9jb2RlPgotICogaW50ZXJmYWNlIGluIGFuIGltcGxlbWVudGF0aW9uIHdoaWNoIHN1cHBvcnRzIHRoZSBFdmVudCBtb2RlbC4KLSAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAwL1JFQy1ET00tTGV2ZWwtMi1FdmVudHMtMjAwMDExMTMnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAyIEV2ZW50cyBTcGVjaWZpY2F0aW9uPC9hPi4KLSAqIEBzaW5jZSBET00gTGV2ZWwgMgotICovCi1wdWJsaWMgaW50ZXJmYWNlIERvY3VtZW50RXZlbnQgewotICAgIC8qKgotICAgICAqCi0gICAgICogQHBhcmFtIGV2ZW50VHlwZSBUaGUgPGNvZGU+ZXZlbnRUeXBlPC9jb2RlPiBwYXJhbWV0ZXIgc3BlY2lmaWVzIHRoZQotICAgICAqICAgdHlwZSBvZiA8Y29kZT5FdmVudDwvY29kZT4gaW50ZXJmYWNlIHRvIGJlIGNyZWF0ZWQuIElmIHRoZQotICAgICAqICAgPGNvZGU+RXZlbnQ8L2NvZGU+IGludGVyZmFjZSBzcGVjaWZpZWQgaXMgc3VwcG9ydGVkIGJ5IHRoZQotICAgICAqICAgaW1wbGVtZW50YXRpb24gdGhpcyBtZXRob2Qgd2lsbCByZXR1cm4gYSBuZXcgPGNvZGU+RXZlbnQ8L2NvZGU+IG9mCi0gICAgICogICB0aGUgaW50ZXJmYWNlIHR5cGUgcmVxdWVzdGVkLiBJZiB0aGUgPGNvZGU+RXZlbnQ8L2NvZGU+IGlzIHRvIGJlCi0gICAgICogICBkaXNwYXRjaGVkIHZpYSB0aGUgPGNvZGU+ZGlzcGF0Y2hFdmVudDwvY29kZT4gbWV0aG9kIHRoZQotICAgICAqICAgYXBwcm9wcmlhdGUgZXZlbnQgaW5pdCBtZXRob2QgbXVzdCBiZSBjYWxsZWQgYWZ0ZXIgY3JlYXRpb24gaW4KLSAgICAgKiAgIG9yZGVyIHRvIGluaXRpYWxpemUgdGhlIDxjb2RlPkV2ZW50PC9jb2RlPidzIHZhbHVlcy4gQXMgYW4gZXhhbXBsZSwKLSAgICAgKiAgIGEgdXNlciB3aXNoaW5nIHRvIHN5bnRoZXNpemUgc29tZSBraW5kIG9mIDxjb2RlPlVJRXZlbnQ8L2NvZGU+Ci0gICAgICogICB3b3VsZCBjYWxsIDxjb2RlPmNyZWF0ZUV2ZW50PC9jb2RlPiB3aXRoIHRoZSBwYXJhbWV0ZXIgIlVJRXZlbnRzIi4KLSAgICAgKiAgIFRoZSA8Y29kZT5pbml0VUlFdmVudDwvY29kZT4gbWV0aG9kIGNvdWxkIHRoZW4gYmUgY2FsbGVkIG9uIHRoZQotICAgICAqICAgbmV3bHkgY3JlYXRlZCA8Y29kZT5VSUV2ZW50PC9jb2RlPiB0byBzZXQgdGhlIHNwZWNpZmljIHR5cGUgb2YKLSAgICAgKiAgIFVJRXZlbnQgdG8gYmUgZGlzcGF0Y2hlZCBhbmQgc2V0IGl0cyBjb250ZXh0IGluZm9ybWF0aW9uLlRoZQotICAgICAqICAgPGNvZGU+Y3JlYXRlRXZlbnQ8L2NvZGU+IG1ldGhvZCBpcyB1c2VkIGluIGNyZWF0aW5nCi0gICAgICogICA8Y29kZT5FdmVudDwvY29kZT5zIHdoZW4gaXQgaXMgZWl0aGVyIGluY29udmVuaWVudCBvciB1bm5lY2Vzc2FyeQotICAgICAqICAgZm9yIHRoZSB1c2VyIHRvIGNyZWF0ZSBhbiA8Y29kZT5FdmVudDwvY29kZT4gdGhlbXNlbHZlcy4gSW4gY2FzZXMKLSAgICAgKiAgIHdoZXJlIHRoZSBpbXBsZW1lbnRhdGlvbiBwcm92aWRlZCA8Y29kZT5FdmVudDwvY29kZT4gaXMKLSAgICAgKiAgIGluc3VmZmljaWVudCwgdXNlcnMgbWF5IHN1cHBseSB0aGVpciBvd24gPGNvZGU+RXZlbnQ8L2NvZGU+Ci0gICAgICogICBpbXBsZW1lbnRhdGlvbnMgZm9yIHVzZSB3aXRoIHRoZSA8Y29kZT5kaXNwYXRjaEV2ZW50PC9jb2RlPiBtZXRob2QuCi0gICAgICogQHJldHVybiBUaGUgbmV3bHkgY3JlYXRlZCA8Y29kZT5FdmVudDwvY29kZT4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgTk9UX1NVUFBPUlRFRF9FUlI6IFJhaXNlZCBpZiB0aGUgaW1wbGVtZW50YXRpb24gZG9lcyBub3Qgc3VwcG9ydCB0aGUKLSAgICAgKiAgIHR5cGUgb2YgPGNvZGU+RXZlbnQ8L2NvZGU+IGludGVyZmFjZSByZXF1ZXN0ZWQKLSAgICAgKi8KLSAgICBwdWJsaWMgRXZlbnQgY3JlYXRlRXZlbnQoU3RyaW5nIGV2ZW50VHlwZSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy93M2MvZG9tL2V2ZW50cy9FdmVudC5qYXZhIGIvc3JjL29yZy93M2MvZG9tL2V2ZW50cy9FdmVudC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiMTM1MWU5Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS9ldmVudHMvRXZlbnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE3MCArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogVGhpcyBmaWxlIGlzIGF2YWlsYWJsZSB1bmRlciBhbmQgZ292ZXJuZWQgYnkgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwotICogTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKiBIb3dldmVyLCB0aGUgZm9sbG93aW5nIG5vdGljZSBhY2NvbXBhbmllZCB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGlzCi0gKiBmaWxlIGFuZCwgcGVyIGl0cyB0ZXJtcywgc2hvdWxkIG5vdCBiZSByZW1vdmVkOgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAotICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCi0gKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKLSAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQotICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKLSAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KLSAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKLSAqIFBVUlBPU0UuCi0gKiBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KLSAqLwotCi1wYWNrYWdlIG9yZy53M2MuZG9tLmV2ZW50czsKLQotLyoqCi0gKiBUaGUgPGNvZGU+RXZlbnQ8L2NvZGU+IGludGVyZmFjZSBpcyB1c2VkIHRvIHByb3ZpZGUgY29udGV4dHVhbCBpbmZvcm1hdGlvbgotICogYWJvdXQgYW4gZXZlbnQgdG8gdGhlIGhhbmRsZXIgcHJvY2Vzc2luZyB0aGUgZXZlbnQuIEFuIG9iamVjdCB3aGljaAotICogaW1wbGVtZW50cyB0aGUgPGNvZGU+RXZlbnQ8L2NvZGU+IGludGVyZmFjZSBpcyBnZW5lcmFsbHkgcGFzc2VkIGFzIHRoZQotICogZmlyc3QgcGFyYW1ldGVyIHRvIGFuIGV2ZW50IGhhbmRsZXIuIE1vcmUgc3BlY2lmaWMgY29udGV4dCBpbmZvcm1hdGlvbiBpcwotICogcGFzc2VkIHRvIGV2ZW50IGhhbmRsZXJzIGJ5IGRlcml2aW5nIGFkZGl0aW9uYWwgaW50ZXJmYWNlcyBmcm9tCi0gKiA8Y29kZT5FdmVudDwvY29kZT4gd2hpY2ggY29udGFpbiBpbmZvcm1hdGlvbiBkaXJlY3RseSByZWxhdGluZyB0byB0aGUKLSAqIHR5cGUgb2YgZXZlbnQgdGhleSBhY2NvbXBhbnkuIFRoZXNlIGRlcml2ZWQgaW50ZXJmYWNlcyBhcmUgYWxzbwotICogaW1wbGVtZW50ZWQgYnkgdGhlIG9iamVjdCBwYXNzZWQgdG8gdGhlIGV2ZW50IGxpc3RlbmVyLgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDAvUkVDLURPTS1MZXZlbC0yLUV2ZW50cy0yMDAwMTExMyc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDIgRXZlbnRzIFNwZWNpZmljYXRpb248L2E+LgotICogQHNpbmNlIERPTSBMZXZlbCAyCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgRXZlbnQgewotICAgIC8vIFBoYXNlVHlwZQotICAgIC8qKgotICAgICAqIFRoZSBjdXJyZW50IGV2ZW50IHBoYXNlIGlzIHRoZSBjYXB0dXJpbmcgcGhhc2UuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBDQVBUVVJJTkdfUEhBU0UgICAgICAgICAgID0gMTsKLSAgICAvKioKLSAgICAgKiBUaGUgZXZlbnQgaXMgY3VycmVudGx5IGJlaW5nIGV2YWx1YXRlZCBhdCB0aGUgdGFyZ2V0Ci0gICAgICogPGNvZGU+RXZlbnRUYXJnZXQ8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgQVRfVEFSR0VUICAgICAgICAgICAgICAgICA9IDI7Ci0gICAgLyoqCi0gICAgICogVGhlIGN1cnJlbnQgZXZlbnQgcGhhc2UgaXMgdGhlIGJ1YmJsaW5nIHBoYXNlLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgQlVCQkxJTkdfUEhBU0UgICAgICAgICAgICA9IDM7Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgbmFtZSBvZiB0aGUgZXZlbnQgKGNhc2UtaW5zZW5zaXRpdmUpLiBUaGUgbmFtZSBtdXN0IGJlIGFuIFhNTCBuYW1lLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VHlwZSgpOwotCi0gICAgLyoqCi0gICAgICogVXNlZCB0byBpbmRpY2F0ZSB0aGUgPGNvZGU+RXZlbnRUYXJnZXQ8L2NvZGU+IHRvIHdoaWNoIHRoZSBldmVudCB3YXMKLSAgICAgKiBvcmlnaW5hbGx5IGRpc3BhdGNoZWQuCi0gICAgICovCi0gICAgcHVibGljIEV2ZW50VGFyZ2V0IGdldFRhcmdldCgpOwotCi0gICAgLyoqCi0gICAgICogVXNlZCB0byBpbmRpY2F0ZSB0aGUgPGNvZGU+RXZlbnRUYXJnZXQ8L2NvZGU+IHdob3NlCi0gICAgICogPGNvZGU+RXZlbnRMaXN0ZW5lcnM8L2NvZGU+IGFyZSBjdXJyZW50bHkgYmVpbmcgcHJvY2Vzc2VkLiBUaGlzIGlzCi0gICAgICogcGFydGljdWxhcmx5IHVzZWZ1bCBkdXJpbmcgY2FwdHVyaW5nIGFuZCBidWJibGluZy4KLSAgICAgKi8KLSAgICBwdWJsaWMgRXZlbnRUYXJnZXQgZ2V0Q3VycmVudFRhcmdldCgpOwotCi0gICAgLyoqCi0gICAgICogVXNlZCB0byBpbmRpY2F0ZSB3aGljaCBwaGFzZSBvZiBldmVudCBmbG93IGlzIGN1cnJlbnRseSBiZWluZwotICAgICAqIGV2YWx1YXRlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgc2hvcnQgZ2V0RXZlbnRQaGFzZSgpOwotCi0gICAgLyoqCi0gICAgICogVXNlZCB0byBpbmRpY2F0ZSB3aGV0aGVyIG9yIG5vdCBhbiBldmVudCBpcyBhIGJ1YmJsaW5nIGV2ZW50LiBJZiB0aGUKLSAgICAgKiBldmVudCBjYW4gYnViYmxlIHRoZSB2YWx1ZSBpcyB0cnVlLCBlbHNlIHRoZSB2YWx1ZSBpcyBmYWxzZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXRCdWJibGVzKCk7Ci0KLSAgICAvKioKLSAgICAgKiBVc2VkIHRvIGluZGljYXRlIHdoZXRoZXIgb3Igbm90IGFuIGV2ZW50IGNhbiBoYXZlIGl0cyBkZWZhdWx0IGFjdGlvbgotICAgICAqIHByZXZlbnRlZC4gSWYgdGhlIGRlZmF1bHQgYWN0aW9uIGNhbiBiZSBwcmV2ZW50ZWQgdGhlIHZhbHVlIGlzIHRydWUsCi0gICAgICogZWxzZSB0aGUgdmFsdWUgaXMgZmFsc2UuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0Q2FuY2VsYWJsZSgpOwotCi0gICAgLyoqCi0gICAgICogIFVzZWQgdG8gc3BlY2lmeSB0aGUgdGltZSAoaW4gbWlsbGlzZWNvbmRzIHJlbGF0aXZlIHRvIHRoZSBlcG9jaCkgYXQKLSAgICAgKiB3aGljaCB0aGUgZXZlbnQgd2FzIGNyZWF0ZWQuIER1ZSB0byB0aGUgZmFjdCB0aGF0IHNvbWUgc3lzdGVtcyBtYXkKLSAgICAgKiBub3QgcHJvdmlkZSB0aGlzIGluZm9ybWF0aW9uIHRoZSB2YWx1ZSBvZiA8Y29kZT50aW1lU3RhbXA8L2NvZGU+IG1heQotICAgICAqIGJlIG5vdCBhdmFpbGFibGUgZm9yIGFsbCBldmVudHMuIFdoZW4gbm90IGF2YWlsYWJsZSwgYSB2YWx1ZSBvZiAwCi0gICAgICogd2lsbCBiZSByZXR1cm5lZC4gRXhhbXBsZXMgb2YgZXBvY2ggdGltZSBhcmUgdGhlIHRpbWUgb2YgdGhlIHN5c3RlbQotICAgICAqIHN0YXJ0IG9yIDA6MDowIFVUQyAxc3QgSmFudWFyeSAxOTcwLgotICAgICAqLwotICAgIHB1YmxpYyBsb25nIGdldFRpbWVTdGFtcCgpOwotCi0gICAgLyoqCi0gICAgICogVGhlIDxjb2RlPnN0b3BQcm9wYWdhdGlvbjwvY29kZT4gbWV0aG9kIGlzIHVzZWQgcHJldmVudCBmdXJ0aGVyCi0gICAgICogcHJvcGFnYXRpb24gb2YgYW4gZXZlbnQgZHVyaW5nIGV2ZW50IGZsb3cuIElmIHRoaXMgbWV0aG9kIGlzIGNhbGxlZAotICAgICAqIGJ5IGFueSA8Y29kZT5FdmVudExpc3RlbmVyPC9jb2RlPiB0aGUgZXZlbnQgd2lsbCBjZWFzZSBwcm9wYWdhdGluZwotICAgICAqIHRocm91Z2ggdGhlIHRyZWUuIFRoZSBldmVudCB3aWxsIGNvbXBsZXRlIGRpc3BhdGNoIHRvIGFsbCBsaXN0ZW5lcnMKLSAgICAgKiBvbiB0aGUgY3VycmVudCA8Y29kZT5FdmVudFRhcmdldDwvY29kZT4gYmVmb3JlIGV2ZW50IGZsb3cgc3RvcHMuIFRoaXMKLSAgICAgKiBtZXRob2QgbWF5IGJlIHVzZWQgZHVyaW5nIGFueSBzdGFnZSBvZiBldmVudCBmbG93LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0b3BQcm9wYWdhdGlvbigpOwotCi0gICAgLyoqCi0gICAgICogSWYgYW4gZXZlbnQgaXMgY2FuY2VsYWJsZSwgdGhlIDxjb2RlPnByZXZlbnREZWZhdWx0PC9jb2RlPiBtZXRob2QgaXMKLSAgICAgKiB1c2VkIHRvIHNpZ25pZnkgdGhhdCB0aGUgZXZlbnQgaXMgdG8gYmUgY2FuY2VsZWQsIG1lYW5pbmcgYW55IGRlZmF1bHQKLSAgICAgKiBhY3Rpb24gbm9ybWFsbHkgdGFrZW4gYnkgdGhlIGltcGxlbWVudGF0aW9uIGFzIGEgcmVzdWx0IG9mIHRoZSBldmVudAotICAgICAqIHdpbGwgbm90IG9jY3VyLiBJZiwgZHVyaW5nIGFueSBzdGFnZSBvZiBldmVudCBmbG93LCB0aGUKLSAgICAgKiA8Y29kZT5wcmV2ZW50RGVmYXVsdDwvY29kZT4gbWV0aG9kIGlzIGNhbGxlZCB0aGUgZXZlbnQgaXMgY2FuY2VsZWQuCi0gICAgICogQW55IGRlZmF1bHQgYWN0aW9uIGFzc29jaWF0ZWQgd2l0aCB0aGUgZXZlbnQgd2lsbCBub3Qgb2NjdXIuIENhbGxpbmcKLSAgICAgKiB0aGlzIG1ldGhvZCBmb3IgYSBub24tY2FuY2VsYWJsZSBldmVudCBoYXMgbm8gZWZmZWN0LiBPbmNlCi0gICAgICogPGNvZGU+cHJldmVudERlZmF1bHQ8L2NvZGU+IGhhcyBiZWVuIGNhbGxlZCBpdCB3aWxsIHJlbWFpbiBpbiBlZmZlY3QKLSAgICAgKiB0aHJvdWdob3V0IHRoZSByZW1haW5kZXIgb2YgdGhlIGV2ZW50J3MgcHJvcGFnYXRpb24uIFRoaXMgbWV0aG9kIG1heQotICAgICAqIGJlIHVzZWQgZHVyaW5nIGFueSBzdGFnZSBvZiBldmVudCBmbG93LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHByZXZlbnREZWZhdWx0KCk7Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgPGNvZGU+aW5pdEV2ZW50PC9jb2RlPiBtZXRob2QgaXMgdXNlZCB0byBpbml0aWFsaXplIHRoZSB2YWx1ZSBvZiBhbgotICAgICAqIDxjb2RlPkV2ZW50PC9jb2RlPiBjcmVhdGVkIHRocm91Z2ggdGhlIDxjb2RlPkRvY3VtZW50RXZlbnQ8L2NvZGU+Ci0gICAgICogaW50ZXJmYWNlLiBUaGlzIG1ldGhvZCBtYXkgb25seSBiZSBjYWxsZWQgYmVmb3JlIHRoZQotICAgICAqIDxjb2RlPkV2ZW50PC9jb2RlPiBoYXMgYmVlbiBkaXNwYXRjaGVkIHZpYSB0aGUKLSAgICAgKiA8Y29kZT5kaXNwYXRjaEV2ZW50PC9jb2RlPiBtZXRob2QsIHRob3VnaCBpdCBtYXkgYmUgY2FsbGVkIG11bHRpcGxlCi0gICAgICogdGltZXMgZHVyaW5nIHRoYXQgcGhhc2UgaWYgbmVjZXNzYXJ5LiBJZiBjYWxsZWQgbXVsdGlwbGUgdGltZXMgdGhlCi0gICAgICogZmluYWwgaW52b2NhdGlvbiB0YWtlcyBwcmVjZWRlbmNlLiBJZiBjYWxsZWQgZnJvbSBhIHN1YmNsYXNzIG9mCi0gICAgICogPGNvZGU+RXZlbnQ8L2NvZGU+IGludGVyZmFjZSBvbmx5IHRoZSB2YWx1ZXMgc3BlY2lmaWVkIGluIHRoZQotICAgICAqIDxjb2RlPmluaXRFdmVudDwvY29kZT4gbWV0aG9kIGFyZSBtb2RpZmllZCwgYWxsIG90aGVyIGF0dHJpYnV0ZXMgYXJlCi0gICAgICogbGVmdCB1bmNoYW5nZWQuCi0gICAgICogQHBhcmFtIGV2ZW50VHlwZUFyZyBTcGVjaWZpZXMgdGhlIGV2ZW50IHR5cGUuIFRoaXMgdHlwZSBtYXkgYmUgYW55Ci0gICAgICogICBldmVudCB0eXBlIGN1cnJlbnRseSBkZWZpbmVkIGluIHRoaXMgc3BlY2lmaWNhdGlvbiBvciBhIG5ldyBldmVudAotICAgICAqICAgdHlwZS4uIFRoZSBzdHJpbmcgbXVzdCBiZSBhbiBYTUwgbmFtZS4gQW55IG5ldyBldmVudCB0eXBlIG11c3Qgbm90Ci0gICAgICogICBiZWdpbiB3aXRoIGFueSB1cHBlciwgbG93ZXIsIG9yIG1peGVkIGNhc2UgdmVyc2lvbiBvZiB0aGUgc3RyaW5nCi0gICAgICogICAiRE9NIi4gVGhpcyBwcmVmaXggaXMgcmVzZXJ2ZWQgZm9yIGZ1dHVyZSBET00gZXZlbnQgc2V0cy4gSXQgaXMKLSAgICAgKiAgIGFsc28gc3Ryb25nbHkgcmVjb21tZW5kZWQgdGhhdCB0aGlyZCBwYXJ0aWVzIGFkZGluZyB0aGVpciBvd24KLSAgICAgKiAgIGV2ZW50cyB1c2UgdGhlaXIgb3duIHByZWZpeCB0byBhdm9pZCBjb25mdXNpb24gYW5kIGxlc3NlbiB0aGUKLSAgICAgKiAgIHByb2JhYmlsaXR5IG9mIGNvbmZsaWN0cyB3aXRoIG90aGVyIG5ldyBldmVudHMuCi0gICAgICogQHBhcmFtIGNhbkJ1YmJsZUFyZyBTcGVjaWZpZXMgd2hldGhlciBvciBub3QgdGhlIGV2ZW50IGNhbiBidWJibGUuCi0gICAgICogQHBhcmFtIGNhbmNlbGFibGVBcmcgU3BlY2lmaWVzIHdoZXRoZXIgb3Igbm90IHRoZSBldmVudCdzIGRlZmF1bHQKLSAgICAgKiAgIGFjdGlvbiBjYW4gYmUgcHJldmVudGVkLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGluaXRFdmVudChTdHJpbmcgZXZlbnRUeXBlQXJnLAotICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGNhbkJ1YmJsZUFyZywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBjYW5jZWxhYmxlQXJnKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy93M2MvZG9tL2V2ZW50cy9FdmVudEV4Y2VwdGlvbi5qYXZhIGIvc3JjL29yZy93M2MvZG9tL2V2ZW50cy9FdmVudEV4Y2VwdGlvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2MjczZjY0Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS9ldmVudHMvRXZlbnRFeGNlcHRpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDY1ICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBUaGlzIGZpbGUgaXMgYXZhaWxhYmxlIHVuZGVyIGFuZCBnb3Zlcm5lZCBieSB0aGUgR05VIEdlbmVyYWwgUHVibGljCi0gKiBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqIEhvd2V2ZXIsIHRoZSBmb2xsb3dpbmcgbm90aWNlIGFjY29tcGFuaWVkIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIG9mIHRoaXMKLSAqIGZpbGUgYW5kLCBwZXIgaXRzIHRlcm1zLCBzaG91bGQgbm90IGJlIHJlbW92ZWQ6Ci0gKgotICogQ29weXJpZ2h0IChjKSAyMDAwIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKLSAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAotICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCi0gKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQotICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgotICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgotICogUFVSUE9TRS4KLSAqIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgotICovCi0KLXBhY2thZ2Ugb3JnLnczYy5kb20uZXZlbnRzOwotCi0vKioKLSAqICBFdmVudCBvcGVyYXRpb25zIG1heSB0aHJvdyBhbiA8Y29kZT5FdmVudEV4Y2VwdGlvbjwvY29kZT4gYXMgc3BlY2lmaWVkIGluCi0gKiB0aGVpciBtZXRob2QgZGVzY3JpcHRpb25zLgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDAvUkVDLURPTS1MZXZlbC0yLUV2ZW50cy0yMDAwMTExMyc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDIgRXZlbnRzIFNwZWNpZmljYXRpb248L2E+LgotICogQHNpbmNlIERPTSBMZXZlbCAyCi0gKi8KLXB1YmxpYyBjbGFzcyBFdmVudEV4Y2VwdGlvbiBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24gewotICAgIHB1YmxpYyBFdmVudEV4Y2VwdGlvbihzaG9ydCBjb2RlLCBTdHJpbmcgbWVzc2FnZSkgewotICAgICAgIHN1cGVyKG1lc3NhZ2UpOwotICAgICAgIHRoaXMuY29kZSA9IGNvZGU7Ci0gICAgfQotICAgIHB1YmxpYyBzaG9ydCAgIGNvZGU7Ci0gICAgLy8gRXZlbnRFeGNlcHRpb25Db2RlCi0gICAgLyoqCi0gICAgICogIElmIHRoZSA8Y29kZT5FdmVudDwvY29kZT4ncyB0eXBlIHdhcyBub3Qgc3BlY2lmaWVkIGJ5IGluaXRpYWxpemluZyB0aGUKLSAgICAgKiBldmVudCBiZWZvcmUgdGhlIG1ldGhvZCB3YXMgY2FsbGVkLiBTcGVjaWZpY2F0aW9uIG9mIHRoZSBFdmVudCdzIHR5cGUKLSAgICAgKiBhcyA8Y29kZT5udWxsPC9jb2RlPiBvciBhbiBlbXB0eSBzdHJpbmcgd2lsbCBhbHNvIHRyaWdnZXIgdGhpcwotICAgICAqIGV4Y2VwdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFVOU1BFQ0lGSUVEX0VWRU5UX1RZUEVfRVJSID0gMDsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy93M2MvZG9tL2V2ZW50cy9FdmVudExpc3RlbmVyLmphdmEgYi9zcmMvb3JnL3czYy9kb20vZXZlbnRzL0V2ZW50TGlzdGVuZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMmFkZmU1OC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3czYy9kb20vZXZlbnRzL0V2ZW50TGlzdGVuZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDcwICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBUaGlzIGZpbGUgaXMgYXZhaWxhYmxlIHVuZGVyIGFuZCBnb3Zlcm5lZCBieSB0aGUgR05VIEdlbmVyYWwgUHVibGljCi0gKiBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqIEhvd2V2ZXIsIHRoZSBmb2xsb3dpbmcgbm90aWNlIGFjY29tcGFuaWVkIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIG9mIHRoaXMKLSAqIGZpbGUgYW5kLCBwZXIgaXRzIHRlcm1zLCBzaG91bGQgbm90IGJlIHJlbW92ZWQ6Ci0gKgotICogQ29weXJpZ2h0IChjKSAyMDAwIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKLSAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAotICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCi0gKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQotICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgotICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgotICogUFVSUE9TRS4KLSAqIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgotICovCi0KLXBhY2thZ2Ugb3JnLnczYy5kb20uZXZlbnRzOwotCi0vKioKLSAqICBUaGUgPGNvZGU+RXZlbnRMaXN0ZW5lcjwvY29kZT4gaW50ZXJmYWNlIGlzIHRoZSBwcmltYXJ5IG1ldGhvZCBmb3IKLSAqIGhhbmRsaW5nIGV2ZW50cy4gVXNlcnMgaW1wbGVtZW50IHRoZSA8Y29kZT5FdmVudExpc3RlbmVyPC9jb2RlPiBpbnRlcmZhY2UKLSAqIGFuZCByZWdpc3RlciB0aGVpciBsaXN0ZW5lciBvbiBhbiA8Y29kZT5FdmVudFRhcmdldDwvY29kZT4gdXNpbmcgdGhlCi0gKiA8Y29kZT5BZGRFdmVudExpc3RlbmVyPC9jb2RlPiBtZXRob2QuIFRoZSB1c2VycyBzaG91bGQgYWxzbyByZW1vdmUgdGhlaXIKLSAqIDxjb2RlPkV2ZW50TGlzdGVuZXI8L2NvZGU+IGZyb20gaXRzIDxjb2RlPkV2ZW50VGFyZ2V0PC9jb2RlPiBhZnRlciB0aGV5Ci0gKiBoYXZlIGNvbXBsZXRlZCB1c2luZyB0aGUgbGlzdGVuZXIuCi0gKiA8cD4gV2hlbiBhIDxjb2RlPk5vZGU8L2NvZGU+IGlzIGNvcGllZCB1c2luZyB0aGUgPGNvZGU+Y2xvbmVOb2RlPC9jb2RlPgotICogbWV0aG9kIHRoZSA8Y29kZT5FdmVudExpc3RlbmVyPC9jb2RlPnMgYXR0YWNoZWQgdG8gdGhlIHNvdXJjZQotICogPGNvZGU+Tm9kZTwvY29kZT4gYXJlIG5vdCBhdHRhY2hlZCB0byB0aGUgY29waWVkIDxjb2RlPk5vZGU8L2NvZGU+LiBJZgotICogdGhlIHVzZXIgd2lzaGVzIHRoZSBzYW1lIDxjb2RlPkV2ZW50TGlzdGVuZXI8L2NvZGU+cyB0byBiZSBhZGRlZCB0byB0aGUKLSAqIG5ld2x5IGNyZWF0ZWQgY29weSB0aGUgdXNlciBtdXN0IGFkZCB0aGVtIG1hbnVhbGx5LgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDAvUkVDLURPTS1MZXZlbC0yLUV2ZW50cy0yMDAwMTExMyc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDIgRXZlbnRzIFNwZWNpZmljYXRpb248L2E+LgotICogQHNpbmNlIERPTSBMZXZlbCAyCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgRXZlbnRMaXN0ZW5lciB7Ci0gICAgLyoqCi0gICAgICogIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCB3aGVuZXZlciBhbiBldmVudCBvY2N1cnMgb2YgdGhlIHR5cGUgZm9yIHdoaWNoCi0gICAgICogdGhlIDxjb2RlPiBFdmVudExpc3RlbmVyPC9jb2RlPiBpbnRlcmZhY2Ugd2FzIHJlZ2lzdGVyZWQuCi0gICAgICogQHBhcmFtIGV2dCAgVGhlIDxjb2RlPkV2ZW50PC9jb2RlPiBjb250YWlucyBjb250ZXh0dWFsIGluZm9ybWF0aW9uCi0gICAgICogICBhYm91dCB0aGUgZXZlbnQuIEl0IGFsc28gY29udGFpbnMgdGhlIDxjb2RlPnN0b3BQcm9wYWdhdGlvbjwvY29kZT4KLSAgICAgKiAgIGFuZCA8Y29kZT5wcmV2ZW50RGVmYXVsdDwvY29kZT4gbWV0aG9kcyB3aGljaCBhcmUgdXNlZCBpbgotICAgICAqICAgZGV0ZXJtaW5pbmcgdGhlIGV2ZW50J3MgZmxvdyBhbmQgZGVmYXVsdCBhY3Rpb24uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgaGFuZGxlRXZlbnQoRXZlbnQgZXZ0KTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy93M2MvZG9tL2V2ZW50cy9FdmVudFRhcmdldC5qYXZhIGIvc3JjL29yZy93M2MvZG9tL2V2ZW50cy9FdmVudFRhcmdldC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0NmFjMWY2Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS9ldmVudHMvRXZlbnRUYXJnZXQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEzMSArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogVGhpcyBmaWxlIGlzIGF2YWlsYWJsZSB1bmRlciBhbmQgZ292ZXJuZWQgYnkgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwotICogTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKiBIb3dldmVyLCB0aGUgZm9sbG93aW5nIG5vdGljZSBhY2NvbXBhbmllZCB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGlzCi0gKiBmaWxlIGFuZCwgcGVyIGl0cyB0ZXJtcywgc2hvdWxkIG5vdCBiZSByZW1vdmVkOgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAotICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCi0gKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKLSAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQotICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKLSAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KLSAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKLSAqIFBVUlBPU0UuCi0gKiBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KLSAqLwotCi1wYWNrYWdlIG9yZy53M2MuZG9tLmV2ZW50czsKLQotLyoqCi0gKiAgVGhlIDxjb2RlPkV2ZW50VGFyZ2V0PC9jb2RlPiBpbnRlcmZhY2UgaXMgaW1wbGVtZW50ZWQgYnkgYWxsCi0gKiA8Y29kZT5Ob2RlczwvY29kZT4gaW4gYW4gaW1wbGVtZW50YXRpb24gd2hpY2ggc3VwcG9ydHMgdGhlIERPTSBFdmVudAotICogTW9kZWwuIFRoZXJlZm9yZSwgdGhpcyBpbnRlcmZhY2UgY2FuIGJlIG9idGFpbmVkIGJ5IHVzaW5nCi0gKiBiaW5kaW5nLXNwZWNpZmljIGNhc3RpbmcgbWV0aG9kcyBvbiBhbiBpbnN0YW5jZSBvZiB0aGUgPGNvZGU+Tm9kZTwvY29kZT4KLSAqIGludGVyZmFjZS4gVGhlIGludGVyZmFjZSBhbGxvd3MgcmVnaXN0cmF0aW9uIGFuZCByZW1vdmFsIG9mCi0gKiA8Y29kZT5FdmVudExpc3RlbmVyczwvY29kZT4gb24gYW4gPGNvZGU+RXZlbnRUYXJnZXQ8L2NvZGU+IGFuZCBkaXNwYXRjaAotICogb2YgZXZlbnRzIHRvIHRoYXQgPGNvZGU+RXZlbnRUYXJnZXQ8L2NvZGU+LgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDAvUkVDLURPTS1MZXZlbC0yLUV2ZW50cy0yMDAwMTExMyc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDIgRXZlbnRzIFNwZWNpZmljYXRpb248L2E+LgotICogQHNpbmNlIERPTSBMZXZlbCAyCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgRXZlbnRUYXJnZXQgewotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIGFsbG93cyB0aGUgcmVnaXN0cmF0aW9uIG9mIGV2ZW50IGxpc3RlbmVycyBvbiB0aGUgZXZlbnQKLSAgICAgKiB0YXJnZXQuIElmIGFuIDxjb2RlPkV2ZW50TGlzdGVuZXI8L2NvZGU+IGlzIGFkZGVkIHRvIGFuCi0gICAgICogPGNvZGU+RXZlbnRUYXJnZXQ8L2NvZGU+IHdoaWxlIGl0IGlzIHByb2Nlc3NpbmcgYW4gZXZlbnQsIGl0IHdpbGwgbm90Ci0gICAgICogYmUgdHJpZ2dlcmVkIGJ5IHRoZSBjdXJyZW50IGFjdGlvbnMgYnV0IG1heSBiZSB0cmlnZ2VyZWQgZHVyaW5nIGEKLSAgICAgKiBsYXRlciBzdGFnZSBvZiBldmVudCBmbG93LCBzdWNoIGFzIHRoZSBidWJibGluZyBwaGFzZS4KLSAgICAgKiA8YnI+IElmIG11bHRpcGxlIGlkZW50aWNhbCA8Y29kZT5FdmVudExpc3RlbmVyPC9jb2RlPnMgYXJlIHJlZ2lzdGVyZWQKLSAgICAgKiBvbiB0aGUgc2FtZSA8Y29kZT5FdmVudFRhcmdldDwvY29kZT4gd2l0aCB0aGUgc2FtZSBwYXJhbWV0ZXJzIHRoZQotICAgICAqIGR1cGxpY2F0ZSBpbnN0YW5jZXMgYXJlIGRpc2NhcmRlZC4gVGhleSBkbyBub3QgY2F1c2UgdGhlCi0gICAgICogPGNvZGU+RXZlbnRMaXN0ZW5lcjwvY29kZT4gdG8gYmUgY2FsbGVkIHR3aWNlIGFuZCBzaW5jZSB0aGV5IGFyZQotICAgICAqIGRpc2NhcmRlZCB0aGV5IGRvIG5vdCBuZWVkIHRvIGJlIHJlbW92ZWQgd2l0aCB0aGUKLSAgICAgKiA8Y29kZT5yZW1vdmVFdmVudExpc3RlbmVyPC9jb2RlPiBtZXRob2QuCi0gICAgICogQHBhcmFtIHR5cGUgVGhlIGV2ZW50IHR5cGUgZm9yIHdoaWNoIHRoZSB1c2VyIGlzIHJlZ2lzdGVyaW5nCi0gICAgICogQHBhcmFtIGxpc3RlbmVyIFRoZSA8Y29kZT5saXN0ZW5lcjwvY29kZT4gcGFyYW1ldGVyIHRha2VzIGFuIGludGVyZmFjZQotICAgICAqICAgaW1wbGVtZW50ZWQgYnkgdGhlIHVzZXIgd2hpY2ggY29udGFpbnMgdGhlIG1ldGhvZHMgdG8gYmUgY2FsbGVkCi0gICAgICogICB3aGVuIHRoZSBldmVudCBvY2N1cnMuCi0gICAgICogQHBhcmFtIHVzZUNhcHR1cmUgSWYgdHJ1ZSwgPGNvZGU+dXNlQ2FwdHVyZTwvY29kZT4gaW5kaWNhdGVzIHRoYXQgdGhlCi0gICAgICogICB1c2VyIHdpc2hlcyB0byBpbml0aWF0ZSBjYXB0dXJlLiBBZnRlciBpbml0aWF0aW5nIGNhcHR1cmUsIGFsbAotICAgICAqICAgZXZlbnRzIG9mIHRoZSBzcGVjaWZpZWQgdHlwZSB3aWxsIGJlIGRpc3BhdGNoZWQgdG8gdGhlIHJlZ2lzdGVyZWQKLSAgICAgKiAgIDxjb2RlPkV2ZW50TGlzdGVuZXI8L2NvZGU+IGJlZm9yZSBiZWluZyBkaXNwYXRjaGVkIHRvIGFueQotICAgICAqICAgPGNvZGU+RXZlbnRUYXJnZXRzPC9jb2RlPiBiZW5lYXRoIHRoZW0gaW4gdGhlIHRyZWUuIEV2ZW50cyB3aGljaAotICAgICAqICAgYXJlIGJ1YmJsaW5nIHVwd2FyZCB0aHJvdWdoIHRoZSB0cmVlIHdpbGwgbm90IHRyaWdnZXIgYW4KLSAgICAgKiAgIDxjb2RlPkV2ZW50TGlzdGVuZXI8L2NvZGU+IGRlc2lnbmF0ZWQgdG8gdXNlIGNhcHR1cmUuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgYWRkRXZlbnRMaXN0ZW5lcihTdHJpbmcgdHlwZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEV2ZW50TGlzdGVuZXIgbGlzdGVuZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIHVzZUNhcHR1cmUpOwotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgYWxsb3dzIHRoZSByZW1vdmFsIG9mIGV2ZW50IGxpc3RlbmVycyBmcm9tIHRoZSBldmVudAotICAgICAqIHRhcmdldC4gSWYgYW4gPGNvZGU+RXZlbnRMaXN0ZW5lcjwvY29kZT4gaXMgcmVtb3ZlZCBmcm9tIGFuCi0gICAgICogPGNvZGU+RXZlbnRUYXJnZXQ8L2NvZGU+IHdoaWxlIGl0IGlzIHByb2Nlc3NpbmcgYW4gZXZlbnQsIGl0IHdpbGwgbm90Ci0gICAgICogYmUgdHJpZ2dlcmVkIGJ5IHRoZSBjdXJyZW50IGFjdGlvbnMuIDxjb2RlPkV2ZW50TGlzdGVuZXI8L2NvZGU+cyBjYW4KLSAgICAgKiBuZXZlciBiZSBpbnZva2VkIGFmdGVyIGJlaW5nIHJlbW92ZWQuCi0gICAgICogPGJyPkNhbGxpbmcgPGNvZGU+cmVtb3ZlRXZlbnRMaXN0ZW5lcjwvY29kZT4gd2l0aCBhcmd1bWVudHMgd2hpY2ggZG8KLSAgICAgKiBub3QgaWRlbnRpZnkgYW55IGN1cnJlbnRseSByZWdpc3RlcmVkIDxjb2RlPkV2ZW50TGlzdGVuZXI8L2NvZGU+IG9uCi0gICAgICogdGhlIDxjb2RlPkV2ZW50VGFyZ2V0PC9jb2RlPiBoYXMgbm8gZWZmZWN0LgotICAgICAqIEBwYXJhbSB0eXBlIFNwZWNpZmllcyB0aGUgZXZlbnQgdHlwZSBvZiB0aGUgPGNvZGU+RXZlbnRMaXN0ZW5lcjwvY29kZT4KLSAgICAgKiAgIGJlaW5nIHJlbW92ZWQuCi0gICAgICogQHBhcmFtIGxpc3RlbmVyIFRoZSA8Y29kZT5FdmVudExpc3RlbmVyPC9jb2RlPiBwYXJhbWV0ZXIgaW5kaWNhdGVzIHRoZQotICAgICAqICAgPGNvZGU+RXZlbnRMaXN0ZW5lciA8L2NvZGU+IHRvIGJlIHJlbW92ZWQuCi0gICAgICogQHBhcmFtIHVzZUNhcHR1cmUgU3BlY2lmaWVzIHdoZXRoZXIgdGhlIDxjb2RlPkV2ZW50TGlzdGVuZXI8L2NvZGU+Ci0gICAgICogICBiZWluZyByZW1vdmVkIHdhcyByZWdpc3RlcmVkIGFzIGEgY2FwdHVyaW5nIGxpc3RlbmVyIG9yIG5vdC4gSWYgYQotICAgICAqICAgbGlzdGVuZXIgd2FzIHJlZ2lzdGVyZWQgdHdpY2UsIG9uZSB3aXRoIGNhcHR1cmUgYW5kIG9uZSB3aXRob3V0LAotICAgICAqICAgZWFjaCBtdXN0IGJlIHJlbW92ZWQgc2VwYXJhdGVseS4gUmVtb3ZhbCBvZiBhIGNhcHR1cmluZyBsaXN0ZW5lcgotICAgICAqICAgZG9lcyBub3QgYWZmZWN0IGEgbm9uLWNhcHR1cmluZyB2ZXJzaW9uIG9mIHRoZSBzYW1lIGxpc3RlbmVyLCBhbmQKLSAgICAgKiAgIHZpY2UgdmVyc2EuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcmVtb3ZlRXZlbnRMaXN0ZW5lcihTdHJpbmcgdHlwZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEV2ZW50TGlzdGVuZXIgbGlzdGVuZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIHVzZUNhcHR1cmUpOwotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgYWxsb3dzIHRoZSBkaXNwYXRjaCBvZiBldmVudHMgaW50byB0aGUgaW1wbGVtZW50YXRpb25zCi0gICAgICogZXZlbnQgbW9kZWwuIEV2ZW50cyBkaXNwYXRjaGVkIGluIHRoaXMgbWFubmVyIHdpbGwgaGF2ZSB0aGUgc2FtZQotICAgICAqIGNhcHR1cmluZyBhbmQgYnViYmxpbmcgYmVoYXZpb3IgYXMgZXZlbnRzIGRpc3BhdGNoZWQgZGlyZWN0bHkgYnkgdGhlCi0gICAgICogaW1wbGVtZW50YXRpb24uIFRoZSB0YXJnZXQgb2YgdGhlIGV2ZW50IGlzIHRoZQotICAgICAqIDxjb2RlPiBFdmVudFRhcmdldDwvY29kZT4gb24gd2hpY2ggPGNvZGU+ZGlzcGF0Y2hFdmVudDwvY29kZT4gaXMKLSAgICAgKiBjYWxsZWQuCi0gICAgICogQHBhcmFtIGV2dCBTcGVjaWZpZXMgdGhlIGV2ZW50IHR5cGUsIGJlaGF2aW9yLCBhbmQgY29udGV4dHVhbAotICAgICAqICAgaW5mb3JtYXRpb24gdG8gYmUgdXNlZCBpbiBwcm9jZXNzaW5nIHRoZSBldmVudC4KLSAgICAgKiBAcmV0dXJuIFRoZSByZXR1cm4gdmFsdWUgb2YgPGNvZGU+ZGlzcGF0Y2hFdmVudDwvY29kZT4gaW5kaWNhdGVzCi0gICAgICogICB3aGV0aGVyIGFueSBvZiB0aGUgbGlzdGVuZXJzIHdoaWNoIGhhbmRsZWQgdGhlIGV2ZW50IGNhbGxlZAotICAgICAqICAgPGNvZGU+cHJldmVudERlZmF1bHQ8L2NvZGU+LiBJZiA8Y29kZT5wcmV2ZW50RGVmYXVsdDwvY29kZT4gd2FzCi0gICAgICogICBjYWxsZWQgdGhlIHZhbHVlIGlzIGZhbHNlLCBlbHNlIHRoZSB2YWx1ZSBpcyB0cnVlLgotICAgICAqIEBleGNlcHRpb24gRXZlbnRFeGNlcHRpb24KLSAgICAgKiAgIFVOU1BFQ0lGSUVEX0VWRU5UX1RZUEVfRVJSOiBSYWlzZWQgaWYgdGhlIDxjb2RlPkV2ZW50PC9jb2RlPidzIHR5cGUKLSAgICAgKiAgIHdhcyBub3Qgc3BlY2lmaWVkIGJ5IGluaXRpYWxpemluZyB0aGUgZXZlbnQgYmVmb3JlCi0gICAgICogICA8Y29kZT5kaXNwYXRjaEV2ZW50PC9jb2RlPiB3YXMgY2FsbGVkLiBTcGVjaWZpY2F0aW9uIG9mIHRoZQotICAgICAqICAgPGNvZGU+RXZlbnQ8L2NvZGU+J3MgdHlwZSBhcyA8Y29kZT5udWxsPC9jb2RlPiBvciBhbiBlbXB0eSBzdHJpbmcKLSAgICAgKiAgIHdpbGwgYWxzbyB0cmlnZ2VyIHRoaXMgZXhjZXB0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGRpc3BhdGNoRXZlbnQoRXZlbnQgZXZ0KQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIEV2ZW50RXhjZXB0aW9uOwotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL3czYy9kb20vZXZlbnRzL01vdXNlRXZlbnQuamF2YSBiL3NyYy9vcmcvdzNjL2RvbS9ldmVudHMvTW91c2VFdmVudC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkZWU0Y2RhLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS9ldmVudHMvTW91c2VFdmVudC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTg1ICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBUaGlzIGZpbGUgaXMgYXZhaWxhYmxlIHVuZGVyIGFuZCBnb3Zlcm5lZCBieSB0aGUgR05VIEdlbmVyYWwgUHVibGljCi0gKiBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqIEhvd2V2ZXIsIHRoZSBmb2xsb3dpbmcgbm90aWNlIGFjY29tcGFuaWVkIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIG9mIHRoaXMKLSAqIGZpbGUgYW5kLCBwZXIgaXRzIHRlcm1zLCBzaG91bGQgbm90IGJlIHJlbW92ZWQ6Ci0gKgotICogQ29weXJpZ2h0IChjKSAyMDAwIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKLSAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAotICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCi0gKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQotICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgotICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgotICogUFVSUE9TRS4KLSAqIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgotICovCi0KLXBhY2thZ2Ugb3JnLnczYy5kb20uZXZlbnRzOwotCi1pbXBvcnQgb3JnLnczYy5kb20udmlld3MuQWJzdHJhY3RWaWV3OwotCi0vKioKLSAqIFRoZSA8Y29kZT5Nb3VzZUV2ZW50PC9jb2RlPiBpbnRlcmZhY2UgcHJvdmlkZXMgc3BlY2lmaWMgY29udGV4dHVhbAotICogaW5mb3JtYXRpb24gYXNzb2NpYXRlZCB3aXRoIE1vdXNlIGV2ZW50cy4KLSAqIDxwPlRoZSA8Y29kZT5kZXRhaWw8L2NvZGU+IGF0dHJpYnV0ZSBpbmhlcml0ZWQgZnJvbSA8Y29kZT5VSUV2ZW50PC9jb2RlPgotICogaW5kaWNhdGVzIHRoZSBudW1iZXIgb2YgdGltZXMgYSBtb3VzZSBidXR0b24gaGFzIGJlZW4gcHJlc3NlZCBhbmQKLSAqIHJlbGVhc2VkIG92ZXIgdGhlIHNhbWUgc2NyZWVuIGxvY2F0aW9uIGR1cmluZyBhIHVzZXIgYWN0aW9uLiBUaGUKLSAqIGF0dHJpYnV0ZSB2YWx1ZSBpcyAxIHdoZW4gdGhlIHVzZXIgYmVnaW5zIHRoaXMgYWN0aW9uIGFuZCBpbmNyZW1lbnRzIGJ5IDEKLSAqIGZvciBlYWNoIGZ1bGwgc2VxdWVuY2Ugb2YgcHJlc3NpbmcgYW5kIHJlbGVhc2luZy4gSWYgdGhlIHVzZXIgbW92ZXMgdGhlCi0gKiBtb3VzZSBiZXR3ZWVuIHRoZSBtb3VzZWRvd24gYW5kIG1vdXNldXAgdGhlIHZhbHVlIHdpbGwgYmUgc2V0IHRvIDAsCi0gKiBpbmRpY2F0aW5nIHRoYXQgbm8gY2xpY2sgaXMgb2NjdXJyaW5nLgotICogPHA+SW4gdGhlIGNhc2Ugb2YgbmVzdGVkIGVsZW1lbnRzIG1vdXNlIGV2ZW50cyBhcmUgYWx3YXlzIHRhcmdldGVkIGF0IHRoZQotICogbW9zdCBkZWVwbHkgbmVzdGVkIGVsZW1lbnQuIEFuY2VzdG9ycyBvZiB0aGUgdGFyZ2V0ZWQgZWxlbWVudCBtYXkgdXNlCi0gKiBidWJibGluZyB0byBvYnRhaW4gbm90aWZpY2F0aW9uIG9mIG1vdXNlIGV2ZW50cyB3aGljaCBvY2N1ciB3aXRoaW4gaXRzCi0gKiBkZXNjZW5kZW50IGVsZW1lbnRzLgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDAvUkVDLURPTS1MZXZlbC0yLUV2ZW50cy0yMDAwMTExMyc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDIgRXZlbnRzIFNwZWNpZmljYXRpb248L2E+LgotICogQHNpbmNlIERPTSBMZXZlbCAyCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgTW91c2VFdmVudCBleHRlbmRzIFVJRXZlbnQgewotICAgIC8qKgotICAgICAqIFRoZSBob3Jpem9udGFsIGNvb3JkaW5hdGUgYXQgd2hpY2ggdGhlIGV2ZW50IG9jY3VycmVkIHJlbGF0aXZlIHRvIHRoZQotICAgICAqIG9yaWdpbiBvZiB0aGUgc2NyZWVuIGNvb3JkaW5hdGUgc3lzdGVtLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0U2NyZWVuWCgpOwotCi0gICAgLyoqCi0gICAgICogVGhlIHZlcnRpY2FsIGNvb3JkaW5hdGUgYXQgd2hpY2ggdGhlIGV2ZW50IG9jY3VycmVkIHJlbGF0aXZlIHRvIHRoZQotICAgICAqIG9yaWdpbiBvZiB0aGUgc2NyZWVuIGNvb3JkaW5hdGUgc3lzdGVtLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0U2NyZWVuWSgpOwotCi0gICAgLyoqCi0gICAgICogVGhlIGhvcml6b250YWwgY29vcmRpbmF0ZSBhdCB3aGljaCB0aGUgZXZlbnQgb2NjdXJyZWQgcmVsYXRpdmUgdG8gdGhlCi0gICAgICogRE9NIGltcGxlbWVudGF0aW9uJ3MgY2xpZW50IGFyZWEuCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRDbGllbnRYKCk7Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgdmVydGljYWwgY29vcmRpbmF0ZSBhdCB3aGljaCB0aGUgZXZlbnQgb2NjdXJyZWQgcmVsYXRpdmUgdG8gdGhlIERPTQotICAgICAqIGltcGxlbWVudGF0aW9uJ3MgY2xpZW50IGFyZWEuCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRDbGllbnRZKCk7Ci0KLSAgICAvKioKLSAgICAgKiBVc2VkIHRvIGluZGljYXRlIHdoZXRoZXIgdGhlICdjdHJsJyBrZXkgd2FzIGRlcHJlc3NlZCBkdXJpbmcgdGhlIGZpcmluZwotICAgICAqIG9mIHRoZSBldmVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXRDdHJsS2V5KCk7Ci0KLSAgICAvKioKLSAgICAgKiBVc2VkIHRvIGluZGljYXRlIHdoZXRoZXIgdGhlICdzaGlmdCcga2V5IHdhcyBkZXByZXNzZWQgZHVyaW5nIHRoZQotICAgICAqIGZpcmluZyBvZiB0aGUgZXZlbnQuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0U2hpZnRLZXkoKTsKLQotICAgIC8qKgotICAgICAqIFVzZWQgdG8gaW5kaWNhdGUgd2hldGhlciB0aGUgJ2FsdCcga2V5IHdhcyBkZXByZXNzZWQgZHVyaW5nIHRoZSBmaXJpbmcKLSAgICAgKiBvZiB0aGUgZXZlbnQuIE9uIHNvbWUgcGxhdGZvcm1zIHRoaXMga2V5IG1heSBtYXAgdG8gYW4gYWx0ZXJuYXRpdmUKLSAgICAgKiBrZXkgbmFtZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXRBbHRLZXkoKTsKLQotICAgIC8qKgotICAgICAqIFVzZWQgdG8gaW5kaWNhdGUgd2hldGhlciB0aGUgJ21ldGEnIGtleSB3YXMgZGVwcmVzc2VkIGR1cmluZyB0aGUgZmlyaW5nCi0gICAgICogb2YgdGhlIGV2ZW50LiBPbiBzb21lIHBsYXRmb3JtcyB0aGlzIGtleSBtYXkgbWFwIHRvIGFuIGFsdGVybmF0aXZlCi0gICAgICoga2V5IG5hbWUuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0TWV0YUtleSgpOwotCi0gICAgLyoqCi0gICAgICogRHVyaW5nIG1vdXNlIGV2ZW50cyBjYXVzZWQgYnkgdGhlIGRlcHJlc3Npb24gb3IgcmVsZWFzZSBvZiBhIG1vdXNlCi0gICAgICogYnV0dG9uLCA8Y29kZT5idXR0b248L2NvZGU+IGlzIHVzZWQgdG8gaW5kaWNhdGUgd2hpY2ggbW91c2UgYnV0dG9uCi0gICAgICogY2hhbmdlZCBzdGF0ZS4gVGhlIHZhbHVlcyBmb3IgPGNvZGU+YnV0dG9uPC9jb2RlPiByYW5nZSBmcm9tIHplcm8gdG8KLSAgICAgKiBpbmRpY2F0ZSB0aGUgbGVmdCBidXR0b24gb2YgdGhlIG1vdXNlLCBvbmUgdG8gaW5kaWNhdGUgdGhlIG1pZGRsZQotICAgICAqIGJ1dHRvbiBpZiBwcmVzZW50LCBhbmQgdHdvIHRvIGluZGljYXRlIHRoZSByaWdodCBidXR0b24uIEZvciBtaWNlCi0gICAgICogY29uZmlndXJlZCBmb3IgbGVmdCBoYW5kZWQgdXNlIGluIHdoaWNoIHRoZSBidXR0b24gYWN0aW9ucyBhcmUKLSAgICAgKiByZXZlcnNlZCB0aGUgdmFsdWVzIGFyZSBpbnN0ZWFkIHJlYWQgZnJvbSByaWdodCB0byBsZWZ0LgotICAgICAqLwotICAgIHB1YmxpYyBzaG9ydCBnZXRCdXR0b24oKTsKLQotICAgIC8qKgotICAgICAqIFVzZWQgdG8gaWRlbnRpZnkgYSBzZWNvbmRhcnkgPGNvZGU+RXZlbnRUYXJnZXQ8L2NvZGU+IHJlbGF0ZWQgdG8gYSBVSQotICAgICAqIGV2ZW50LiBDdXJyZW50bHkgdGhpcyBhdHRyaWJ1dGUgaXMgdXNlZCB3aXRoIHRoZSBtb3VzZW92ZXIgZXZlbnQgdG8KLSAgICAgKiBpbmRpY2F0ZSB0aGUgPGNvZGU+RXZlbnRUYXJnZXQ8L2NvZGU+IHdoaWNoIHRoZSBwb2ludGluZyBkZXZpY2UKLSAgICAgKiBleGl0ZWQgYW5kIHdpdGggdGhlIG1vdXNlb3V0IGV2ZW50IHRvIGluZGljYXRlIHRoZQotICAgICAqIDxjb2RlPkV2ZW50VGFyZ2V0PC9jb2RlPiB3aGljaCB0aGUgcG9pbnRpbmcgZGV2aWNlIGVudGVyZWQuCi0gICAgICovCi0gICAgcHVibGljIEV2ZW50VGFyZ2V0IGdldFJlbGF0ZWRUYXJnZXQoKTsKLQotICAgIC8qKgotICAgICAqIFRoZSA8Y29kZT5pbml0TW91c2VFdmVudDwvY29kZT4gbWV0aG9kIGlzIHVzZWQgdG8gaW5pdGlhbGl6ZSB0aGUgdmFsdWUKLSAgICAgKiBvZiBhIDxjb2RlPk1vdXNlRXZlbnQ8L2NvZGU+IGNyZWF0ZWQgdGhyb3VnaCB0aGUKLSAgICAgKiA8Y29kZT5Eb2N1bWVudEV2ZW50PC9jb2RlPiBpbnRlcmZhY2UuIFRoaXMgbWV0aG9kIG1heSBvbmx5IGJlIGNhbGxlZAotICAgICAqIGJlZm9yZSB0aGUgPGNvZGU+TW91c2VFdmVudDwvY29kZT4gaGFzIGJlZW4gZGlzcGF0Y2hlZCB2aWEgdGhlCi0gICAgICogPGNvZGU+ZGlzcGF0Y2hFdmVudDwvY29kZT4gbWV0aG9kLCB0aG91Z2ggaXQgbWF5IGJlIGNhbGxlZCBtdWx0aXBsZQotICAgICAqIHRpbWVzIGR1cmluZyB0aGF0IHBoYXNlIGlmIG5lY2Vzc2FyeS4gSWYgY2FsbGVkIG11bHRpcGxlIHRpbWVzLCB0aGUKLSAgICAgKiBmaW5hbCBpbnZvY2F0aW9uIHRha2VzIHByZWNlZGVuY2UuCi0gICAgICogQHBhcmFtIHR5cGVBcmcgU3BlY2lmaWVzIHRoZSBldmVudCB0eXBlLgotICAgICAqIEBwYXJhbSBjYW5CdWJibGVBcmcgU3BlY2lmaWVzIHdoZXRoZXIgb3Igbm90IHRoZSBldmVudCBjYW4gYnViYmxlLgotICAgICAqIEBwYXJhbSBjYW5jZWxhYmxlQXJnIFNwZWNpZmllcyB3aGV0aGVyIG9yIG5vdCB0aGUgZXZlbnQncyBkZWZhdWx0Ci0gICAgICogICBhY3Rpb24gY2FuIGJlIHByZXZlbnRlZC4KLSAgICAgKiBAcGFyYW0gdmlld0FyZyBTcGVjaWZpZXMgdGhlIDxjb2RlPkV2ZW50PC9jb2RlPidzCi0gICAgICogICA8Y29kZT5BYnN0cmFjdFZpZXc8L2NvZGU+LgotICAgICAqIEBwYXJhbSBkZXRhaWxBcmcgU3BlY2lmaWVzIHRoZSA8Y29kZT5FdmVudDwvY29kZT4ncyBtb3VzZSBjbGljayBjb3VudC4KLSAgICAgKiBAcGFyYW0gc2NyZWVuWEFyZyBTcGVjaWZpZXMgdGhlIDxjb2RlPkV2ZW50PC9jb2RlPidzIHNjcmVlbiB4Ci0gICAgICogICBjb29yZGluYXRlCi0gICAgICogQHBhcmFtIHNjcmVlbllBcmcgU3BlY2lmaWVzIHRoZSA8Y29kZT5FdmVudDwvY29kZT4ncyBzY3JlZW4geQotICAgICAqICAgY29vcmRpbmF0ZQotICAgICAqIEBwYXJhbSBjbGllbnRYQXJnIFNwZWNpZmllcyB0aGUgPGNvZGU+RXZlbnQ8L2NvZGU+J3MgY2xpZW50IHgKLSAgICAgKiAgIGNvb3JkaW5hdGUKLSAgICAgKiBAcGFyYW0gY2xpZW50WUFyZyBTcGVjaWZpZXMgdGhlIDxjb2RlPkV2ZW50PC9jb2RlPidzIGNsaWVudCB5Ci0gICAgICogICBjb29yZGluYXRlCi0gICAgICogQHBhcmFtIGN0cmxLZXlBcmcgU3BlY2lmaWVzIHdoZXRoZXIgb3Igbm90IGNvbnRyb2wga2V5IHdhcyBkZXByZXNzZWQKLSAgICAgKiAgIGR1cmluZyB0aGUgPGNvZGU+RXZlbnQ8L2NvZGU+LgotICAgICAqIEBwYXJhbSBhbHRLZXlBcmcgU3BlY2lmaWVzIHdoZXRoZXIgb3Igbm90IGFsdCBrZXkgd2FzIGRlcHJlc3NlZCBkdXJpbmcKLSAgICAgKiAgIHRoZSA8Y29kZT5FdmVudDwvY29kZT4uCi0gICAgICogQHBhcmFtIHNoaWZ0S2V5QXJnIFNwZWNpZmllcyB3aGV0aGVyIG9yIG5vdCBzaGlmdCBrZXkgd2FzIGRlcHJlc3NlZAotICAgICAqICAgZHVyaW5nIHRoZSA8Y29kZT5FdmVudDwvY29kZT4uCi0gICAgICogQHBhcmFtIG1ldGFLZXlBcmcgU3BlY2lmaWVzIHdoZXRoZXIgb3Igbm90IG1ldGEga2V5IHdhcyBkZXByZXNzZWQKLSAgICAgKiAgIGR1cmluZyB0aGUgPGNvZGU+RXZlbnQ8L2NvZGU+LgotICAgICAqIEBwYXJhbSBidXR0b25BcmcgU3BlY2lmaWVzIHRoZSA8Y29kZT5FdmVudDwvY29kZT4ncyBtb3VzZSBidXR0b24uCi0gICAgICogQHBhcmFtIHJlbGF0ZWRUYXJnZXRBcmcgU3BlY2lmaWVzIHRoZSA8Y29kZT5FdmVudDwvY29kZT4ncyByZWxhdGVkCi0gICAgICogICA8Y29kZT5FdmVudFRhcmdldDwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgaW5pdE1vdXNlRXZlbnQoU3RyaW5nIHR5cGVBcmcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBjYW5CdWJibGVBcmcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBjYW5jZWxhYmxlQXJnLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFic3RyYWN0VmlldyB2aWV3QXJnLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBkZXRhaWxBcmcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHNjcmVlblhBcmcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHNjcmVlbllBcmcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGNsaWVudFhBcmcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGNsaWVudFlBcmcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBjdHJsS2V5QXJnLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gYWx0S2V5QXJnLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gc2hpZnRLZXlBcmcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBtZXRhS2V5QXJnLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNob3J0IGJ1dHRvbkFyZywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFdmVudFRhcmdldCByZWxhdGVkVGFyZ2V0QXJnKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy93M2MvZG9tL2V2ZW50cy9NdXRhdGlvbkV2ZW50LmphdmEgYi9zcmMvb3JnL3czYy9kb20vZXZlbnRzL011dGF0aW9uRXZlbnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYTUyMGI2Zi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3czYy9kb20vZXZlbnRzL011dGF0aW9uRXZlbnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEzNyArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogVGhpcyBmaWxlIGlzIGF2YWlsYWJsZSB1bmRlciBhbmQgZ292ZXJuZWQgYnkgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwotICogTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKiBIb3dldmVyLCB0aGUgZm9sbG93aW5nIG5vdGljZSBhY2NvbXBhbmllZCB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGlzCi0gKiBmaWxlIGFuZCwgcGVyIGl0cyB0ZXJtcywgc2hvdWxkIG5vdCBiZSByZW1vdmVkOgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAotICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCi0gKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKLSAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQotICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKLSAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KLSAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKLSAqIFBVUlBPU0UuCi0gKiBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KLSAqLwotCi1wYWNrYWdlIG9yZy53M2MuZG9tLmV2ZW50czsKLQotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci0KLS8qKgotICogVGhlIDxjb2RlPk11dGF0aW9uRXZlbnQ8L2NvZGU+IGludGVyZmFjZSBwcm92aWRlcyBzcGVjaWZpYyBjb250ZXh0dWFsCi0gKiBpbmZvcm1hdGlvbiBhc3NvY2lhdGVkIHdpdGggTXV0YXRpb24gZXZlbnRzLgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDAvUkVDLURPTS1MZXZlbC0yLUV2ZW50cy0yMDAwMTExMyc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDIgRXZlbnRzIFNwZWNpZmljYXRpb248L2E+LgotICogQHNpbmNlIERPTSBMZXZlbCAyCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgTXV0YXRpb25FdmVudCBleHRlbmRzIEV2ZW50IHsKLSAgICAvLyBhdHRyQ2hhbmdlVHlwZQotICAgIC8qKgotICAgICAqIFRoZSA8Y29kZT5BdHRyPC9jb2RlPiB3YXMgbW9kaWZpZWQgaW4gcGxhY2UuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBNT0RJRklDQVRJT04gICAgICAgICAgICAgID0gMTsKLSAgICAvKioKLSAgICAgKiBUaGUgPGNvZGU+QXR0cjwvY29kZT4gd2FzIGp1c3QgYWRkZWQuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBBRERJVElPTiAgICAgICAgICAgICAgICAgID0gMjsKLSAgICAvKioKLSAgICAgKiBUaGUgPGNvZGU+QXR0cjwvY29kZT4gd2FzIGp1c3QgcmVtb3ZlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFJFTU9WQUwgICAgICAgICAgICAgICAgICAgPSAzOwotCi0gICAgLyoqCi0gICAgICogIDxjb2RlPnJlbGF0ZWROb2RlPC9jb2RlPiBpcyB1c2VkIHRvIGlkZW50aWZ5IGEgc2Vjb25kYXJ5IG5vZGUgcmVsYXRlZAotICAgICAqIHRvIGEgbXV0YXRpb24gZXZlbnQuIEZvciBleGFtcGxlLCBpZiBhIG11dGF0aW9uIGV2ZW50IGlzIGRpc3BhdGNoZWQKLSAgICAgKiB0byBhIG5vZGUgaW5kaWNhdGluZyB0aGF0IGl0cyBwYXJlbnQgaGFzIGNoYW5nZWQsIHRoZQotICAgICAqIDxjb2RlPnJlbGF0ZWROb2RlPC9jb2RlPiBpcyB0aGUgY2hhbmdlZCBwYXJlbnQuIElmIGFuIGV2ZW50IGlzCi0gICAgICogaW5zdGVhZCBkaXNwYXRjaGVkIHRvIGEgc3VidHJlZSBpbmRpY2F0aW5nIGEgbm9kZSB3YXMgY2hhbmdlZCB3aXRoaW4KLSAgICAgKiBpdCwgdGhlIDxjb2RlPnJlbGF0ZWROb2RlPC9jb2RlPiBpcyB0aGUgY2hhbmdlZCBub2RlLiBJbiB0aGUgY2FzZSBvZgotICAgICAqIHRoZSBET01BdHRyTW9kaWZpZWQgZXZlbnQgaXQgaW5kaWNhdGVzIHRoZSA8Y29kZT5BdHRyPC9jb2RlPiBub2RlCi0gICAgICogd2hpY2ggd2FzIG1vZGlmaWVkLCBhZGRlZCwgb3IgcmVtb3ZlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgTm9kZSBnZXRSZWxhdGVkTm9kZSgpOwotCi0gICAgLyoqCi0gICAgICogIDxjb2RlPnByZXZWYWx1ZTwvY29kZT4gaW5kaWNhdGVzIHRoZSBwcmV2aW91cyB2YWx1ZSBvZiB0aGUKLSAgICAgKiA8Y29kZT5BdHRyPC9jb2RlPiBub2RlIGluIERPTUF0dHJNb2RpZmllZCBldmVudHMsIGFuZCBvZiB0aGUKLSAgICAgKiA8Y29kZT5DaGFyYWN0ZXJEYXRhPC9jb2RlPiBub2RlIGluIERPTUNoYXJhY3RlckRhdGFNb2RpZmllZCBldmVudHMuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRQcmV2VmFsdWUoKTsKLQotICAgIC8qKgotICAgICAqICA8Y29kZT5uZXdWYWx1ZTwvY29kZT4gaW5kaWNhdGVzIHRoZSBuZXcgdmFsdWUgb2YgdGhlIDxjb2RlPkF0dHI8L2NvZGU+Ci0gICAgICogbm9kZSBpbiBET01BdHRyTW9kaWZpZWQgZXZlbnRzLCBhbmQgb2YgdGhlIDxjb2RlPkNoYXJhY3RlckRhdGE8L2NvZGU+Ci0gICAgICogbm9kZSBpbiBET01DaGFyYWN0ZXJEYXRhTW9kaWZpZWQgZXZlbnRzLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmV3VmFsdWUoKTsKLQotICAgIC8qKgotICAgICAqICA8Y29kZT5hdHRyTmFtZTwvY29kZT4gaW5kaWNhdGVzIHRoZSBuYW1lIG9mIHRoZSBjaGFuZ2VkCi0gICAgICogPGNvZGU+QXR0cjwvY29kZT4gbm9kZSBpbiBhIERPTUF0dHJNb2RpZmllZCBldmVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEF0dHJOYW1lKCk7Ci0KLSAgICAvKioKLSAgICAgKiAgPGNvZGU+YXR0ckNoYW5nZTwvY29kZT4gaW5kaWNhdGVzIHRoZSB0eXBlIG9mIGNoYW5nZSB3aGljaCB0cmlnZ2VyZWQKLSAgICAgKiB0aGUgRE9NQXR0ck1vZGlmaWVkIGV2ZW50LiBUaGUgdmFsdWVzIGNhbiBiZSA8Y29kZT5NT0RJRklDQVRJT048L2NvZGU+Ci0gICAgICogLCA8Y29kZT5BRERJVElPTjwvY29kZT4sIG9yIDxjb2RlPlJFTU9WQUw8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBzaG9ydCBnZXRBdHRyQ2hhbmdlKCk7Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgPGNvZGU+aW5pdE11dGF0aW9uRXZlbnQ8L2NvZGU+IG1ldGhvZCBpcyB1c2VkIHRvIGluaXRpYWxpemUgdGhlCi0gICAgICogdmFsdWUgb2YgYSA8Y29kZT5NdXRhdGlvbkV2ZW50PC9jb2RlPiBjcmVhdGVkIHRocm91Z2ggdGhlCi0gICAgICogPGNvZGU+RG9jdW1lbnRFdmVudDwvY29kZT4gaW50ZXJmYWNlLiBUaGlzIG1ldGhvZCBtYXkgb25seSBiZSBjYWxsZWQKLSAgICAgKiBiZWZvcmUgdGhlIDxjb2RlPk11dGF0aW9uRXZlbnQ8L2NvZGU+IGhhcyBiZWVuIGRpc3BhdGNoZWQgdmlhIHRoZQotICAgICAqIDxjb2RlPmRpc3BhdGNoRXZlbnQ8L2NvZGU+IG1ldGhvZCwgdGhvdWdoIGl0IG1heSBiZSBjYWxsZWQgbXVsdGlwbGUKLSAgICAgKiB0aW1lcyBkdXJpbmcgdGhhdCBwaGFzZSBpZiBuZWNlc3NhcnkuIElmIGNhbGxlZCBtdWx0aXBsZSB0aW1lcywgdGhlCi0gICAgICogZmluYWwgaW52b2NhdGlvbiB0YWtlcyBwcmVjZWRlbmNlLgotICAgICAqIEBwYXJhbSB0eXBlQXJnIFNwZWNpZmllcyB0aGUgZXZlbnQgdHlwZS4KLSAgICAgKiBAcGFyYW0gY2FuQnViYmxlQXJnIFNwZWNpZmllcyB3aGV0aGVyIG9yIG5vdCB0aGUgZXZlbnQgY2FuIGJ1YmJsZS4KLSAgICAgKiBAcGFyYW0gY2FuY2VsYWJsZUFyZyBTcGVjaWZpZXMgd2hldGhlciBvciBub3QgdGhlIGV2ZW50J3MgZGVmYXVsdAotICAgICAqICAgYWN0aW9uIGNhbiBiZSBwcmV2ZW50ZWQuCi0gICAgICogQHBhcmFtIHJlbGF0ZWROb2RlQXJnIFNwZWNpZmllcyB0aGUgPGNvZGU+RXZlbnQ8L2NvZGU+J3MgcmVsYXRlZCBOb2RlLgotICAgICAqIEBwYXJhbSBwcmV2VmFsdWVBcmcgU3BlY2lmaWVzIHRoZSA8Y29kZT5FdmVudDwvY29kZT4ncwotICAgICAqICAgPGNvZGU+cHJldlZhbHVlPC9jb2RlPiBhdHRyaWJ1dGUuIFRoaXMgdmFsdWUgbWF5IGJlIG51bGwuCi0gICAgICogQHBhcmFtIG5ld1ZhbHVlQXJnIFNwZWNpZmllcyB0aGUgPGNvZGU+RXZlbnQ8L2NvZGU+J3MKLSAgICAgKiAgIDxjb2RlPm5ld1ZhbHVlPC9jb2RlPiBhdHRyaWJ1dGUuIFRoaXMgdmFsdWUgbWF5IGJlIG51bGwuCi0gICAgICogQHBhcmFtIGF0dHJOYW1lQXJnIFNwZWNpZmllcyB0aGUgPGNvZGU+RXZlbnQ8L2NvZGU+J3MKLSAgICAgKiAgIDxjb2RlPmF0dHJOYW1lPC9jb2RlPiBhdHRyaWJ1dGUuIFRoaXMgdmFsdWUgbWF5IGJlIG51bGwuCi0gICAgICogQHBhcmFtIGF0dHJDaGFuZ2VBcmcgU3BlY2lmaWVzIHRoZSA8Y29kZT5FdmVudDwvY29kZT4ncwotICAgICAqICAgPGNvZGU+YXR0ckNoYW5nZTwvY29kZT4gYXR0cmlidXRlCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgaW5pdE11dGF0aW9uRXZlbnQoU3RyaW5nIHR5cGVBcmcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBjYW5CdWJibGVBcmcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBjYW5jZWxhYmxlQXJnLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5vZGUgcmVsYXRlZE5vZGVBcmcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHByZXZWYWx1ZUFyZywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbmV3VmFsdWVBcmcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGF0dHJOYW1lQXJnLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNob3J0IGF0dHJDaGFuZ2VBcmcpOwotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL3czYy9kb20vZXZlbnRzL1VJRXZlbnQuamF2YSBiL3NyYy9vcmcvdzNjL2RvbS9ldmVudHMvVUlFdmVudC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwOTMxYzVmLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS9ldmVudHMvVUlFdmVudC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsODcgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIFRoaXMgZmlsZSBpcyBhdmFpbGFibGUgdW5kZXIgYW5kIGdvdmVybmVkIGJ5IHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKLSAqIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICogSG93ZXZlciwgdGhlIGZvbGxvd2luZyBub3RpY2UgYWNjb21wYW5pZWQgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcwotICogZmlsZSBhbmQsIHBlciBpdHMgdGVybXMsIHNob3VsZCBub3QgYmUgcmVtb3ZlZDoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDAgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKLSAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQotICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCi0gKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKLSAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCi0gKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCi0gKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCi0gKiBQVVJQT1NFLgotICogU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCi0gKi8KLQotcGFja2FnZSBvcmcudzNjLmRvbS5ldmVudHM7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS52aWV3cy5BYnN0cmFjdFZpZXc7Ci0KLS8qKgotICogVGhlIDxjb2RlPlVJRXZlbnQ8L2NvZGU+IGludGVyZmFjZSBwcm92aWRlcyBzcGVjaWZpYyBjb250ZXh0dWFsIGluZm9ybWF0aW9uCi0gKiBhc3NvY2lhdGVkIHdpdGggVXNlciBJbnRlcmZhY2UgZXZlbnRzLgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDAvUkVDLURPTS1MZXZlbC0yLUV2ZW50cy0yMDAwMTExMyc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDIgRXZlbnRzIFNwZWNpZmljYXRpb248L2E+LgotICogQHNpbmNlIERPTSBMZXZlbCAyCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgVUlFdmVudCBleHRlbmRzIEV2ZW50IHsKLSAgICAvKioKLSAgICAgKiBUaGUgPGNvZGU+dmlldzwvY29kZT4gYXR0cmlidXRlIGlkZW50aWZpZXMgdGhlIDxjb2RlPkFic3RyYWN0VmlldzwvY29kZT4KLSAgICAgKiAgZnJvbSB3aGljaCB0aGUgZXZlbnQgd2FzIGdlbmVyYXRlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgQWJzdHJhY3RWaWV3IGdldFZpZXcoKTsKLQotICAgIC8qKgotICAgICAqIFNwZWNpZmllcyBzb21lIGRldGFpbCBpbmZvcm1hdGlvbiBhYm91dCB0aGUgPGNvZGU+RXZlbnQ8L2NvZGU+LAotICAgICAqIGRlcGVuZGluZyBvbiB0aGUgdHlwZSBvZiBldmVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldERldGFpbCgpOwotCi0gICAgLyoqCi0gICAgICogVGhlIDxjb2RlPmluaXRVSUV2ZW50PC9jb2RlPiBtZXRob2QgaXMgdXNlZCB0byBpbml0aWFsaXplIHRoZSB2YWx1ZSBvZgotICAgICAqIGEgPGNvZGU+VUlFdmVudDwvY29kZT4gY3JlYXRlZCB0aHJvdWdoIHRoZSA8Y29kZT5Eb2N1bWVudEV2ZW50PC9jb2RlPgotICAgICAqIGludGVyZmFjZS4gVGhpcyBtZXRob2QgbWF5IG9ubHkgYmUgY2FsbGVkIGJlZm9yZSB0aGUKLSAgICAgKiA8Y29kZT5VSUV2ZW50PC9jb2RlPiBoYXMgYmVlbiBkaXNwYXRjaGVkIHZpYSB0aGUKLSAgICAgKiA8Y29kZT5kaXNwYXRjaEV2ZW50PC9jb2RlPiBtZXRob2QsIHRob3VnaCBpdCBtYXkgYmUgY2FsbGVkIG11bHRpcGxlCi0gICAgICogdGltZXMgZHVyaW5nIHRoYXQgcGhhc2UgaWYgbmVjZXNzYXJ5LiBJZiBjYWxsZWQgbXVsdGlwbGUgdGltZXMsIHRoZQotICAgICAqIGZpbmFsIGludm9jYXRpb24gdGFrZXMgcHJlY2VkZW5jZS4KLSAgICAgKiBAcGFyYW0gdHlwZUFyZyBTcGVjaWZpZXMgdGhlIGV2ZW50IHR5cGUuCi0gICAgICogQHBhcmFtIGNhbkJ1YmJsZUFyZyBTcGVjaWZpZXMgd2hldGhlciBvciBub3QgdGhlIGV2ZW50IGNhbiBidWJibGUuCi0gICAgICogQHBhcmFtIGNhbmNlbGFibGVBcmcgU3BlY2lmaWVzIHdoZXRoZXIgb3Igbm90IHRoZSBldmVudCdzIGRlZmF1bHQKLSAgICAgKiAgIGFjdGlvbiBjYW4gYmUgcHJldmVudGVkLgotICAgICAqIEBwYXJhbSB2aWV3QXJnIFNwZWNpZmllcyB0aGUgPGNvZGU+RXZlbnQ8L2NvZGU+J3MKLSAgICAgKiAgIDxjb2RlPkFic3RyYWN0VmlldzwvY29kZT4uCi0gICAgICogQHBhcmFtIGRldGFpbEFyZyBTcGVjaWZpZXMgdGhlIDxjb2RlPkV2ZW50PC9jb2RlPidzIGRldGFpbC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBpbml0VUlFdmVudChTdHJpbmcgdHlwZUFyZywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGNhbkJ1YmJsZUFyZywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGNhbmNlbGFibGVBcmcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgQWJzdHJhY3RWaWV3IHZpZXdBcmcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGRldGFpbEFyZyk7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxBbmNob3JFbGVtZW50LmphdmEgYi9zcmMvb3JnL3czYy9kb20vaHRtbC9IVE1MQW5jaG9yRWxlbWVudC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4ZTRmNmU3Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxBbmNob3JFbGVtZW50LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNDAgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIFRoaXMgZmlsZSBpcyBhdmFpbGFibGUgdW5kZXIgYW5kIGdvdmVybmVkIGJ5IHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKLSAqIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICogSG93ZXZlciwgdGhlIGZvbGxvd2luZyBub3RpY2UgYWNjb21wYW5pZWQgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcwotICogZmlsZSBhbmQsIHBlciBpdHMgdGVybXMsIHNob3VsZCBub3QgYmUgcmVtb3ZlZDoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDAgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKLSAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQotICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCi0gKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKLSAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCi0gKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCi0gKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCi0gKiBQVVJQT1NFLiBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUKLSAqIGRldGFpbHMuCi0gKi8KLQotcGFja2FnZSBvcmcudzNjLmRvbS5odG1sOwotCi0vKioKLSAqICBUaGUgYW5jaG9yIGVsZW1lbnQuIFNlZSB0aGUgIEEgZWxlbWVudCBkZWZpbml0aW9uIGluIEhUTUwgNC4wLgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDAvQ1ItRE9NLUxldmVsLTItMjAwMDA1MTAnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAyIFNwZWNpZmljYXRpb248L2E+LgotICovCi1wdWJsaWMgaW50ZXJmYWNlIEhUTUxBbmNob3JFbGVtZW50IGV4dGVuZHMgSFRNTEVsZW1lbnQgewotICAgIC8qKgotICAgICAqICBBIHNpbmdsZSBjaGFyYWN0ZXIgYWNjZXNzIGtleSB0byBnaXZlIGFjY2VzcyB0byB0aGUgZm9ybSBjb250cm9sLiBTZWUKLSAgICAgKiB0aGUgIGFjY2Vzc2tleSBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEFjY2Vzc0tleSgpOwotICAgIHB1YmxpYyB2b2lkIHNldEFjY2Vzc0tleShTdHJpbmcgYWNjZXNzS2V5KTsKLQotICAgIC8qKgotICAgICAqICBUaGUgY2hhcmFjdGVyIGVuY29kaW5nIG9mIHRoZSBsaW5rZWQgcmVzb3VyY2UuIFNlZSB0aGUgIGNoYXJzZXQKLSAgICAgKiBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldENoYXJzZXQoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRDaGFyc2V0KFN0cmluZyBjaGFyc2V0KTsKLQotICAgIC8qKgotICAgICAqICBDb21tYS1zZXBhcmF0ZWQgbGlzdCBvZiBsZW5ndGhzLCBkZWZpbmluZyBhbiBhY3RpdmUgcmVnaW9uIGdlb21ldHJ5LgotICAgICAqIFNlZSBhbHNvIDxjb2RlPnNoYXBlPC9jb2RlPiBmb3IgdGhlIHNoYXBlIG9mIHRoZSByZWdpb24uIFNlZSB0aGUKLSAgICAgKiBjb29yZHMgYXR0cmlidXRlIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRDb29yZHMoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRDb29yZHMoU3RyaW5nIGNvb3Jkcyk7Ci0KLSAgICAvKioKLSAgICAgKiAgVGhlIFVSSSBvZiB0aGUgbGlua2VkIHJlc291cmNlLiBTZWUgdGhlICBocmVmIGF0dHJpYnV0ZSBkZWZpbml0aW9uIGluCi0gICAgICogSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRIcmVmKCk7Ci0gICAgcHVibGljIHZvaWQgc2V0SHJlZihTdHJpbmcgaHJlZik7Ci0KLSAgICAvKioKLSAgICAgKiAgTGFuZ3VhZ2UgY29kZSBvZiB0aGUgbGlua2VkIHJlc291cmNlLiBTZWUgdGhlICBocmVmbGFuZyBhdHRyaWJ1dGUKLSAgICAgKiBkZWZpbml0aW9uIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0SHJlZmxhbmcoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRIcmVmbGFuZyhTdHJpbmcgaHJlZmxhbmcpOwotCi0gICAgLyoqCi0gICAgICogIEFuY2hvciBuYW1lLiBTZWUgdGhlICBuYW1lIGF0dHJpYnV0ZSBkZWZpbml0aW9uIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpOwotICAgIHB1YmxpYyB2b2lkIHNldE5hbWUoU3RyaW5nIG5hbWUpOwotCi0gICAgLyoqCi0gICAgICogIEZvcndhcmQgbGluayB0eXBlLiBTZWUgdGhlICByZWwgYXR0cmlidXRlIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRSZWwoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRSZWwoU3RyaW5nIHJlbCk7Ci0KLSAgICAvKioKLSAgICAgKiAgUmV2ZXJzZSBsaW5rIHR5cGUuIFNlZSB0aGUgIHJldiBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFJldigpOwotICAgIHB1YmxpYyB2b2lkIHNldFJldihTdHJpbmcgcmV2KTsKLQotICAgIC8qKgotICAgICAqICBUaGUgc2hhcGUgb2YgdGhlIGFjdGl2ZSBhcmVhLiBUaGUgY29vcmRpbmF0ZXMgYXJlIGdpdmVuIGJ5Ci0gICAgICogPGNvZGU+Y29vcmRzPC9jb2RlPiAuIFNlZSB0aGUgIHNoYXBlIGF0dHJpYnV0ZSBkZWZpbml0aW9uIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0U2hhcGUoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRTaGFwZShTdHJpbmcgc2hhcGUpOwotCi0gICAgLyoqCi0gICAgICogIEluZGV4IHRoYXQgcmVwcmVzZW50cyB0aGUgZWxlbWVudCdzIHBvc2l0aW9uIGluIHRoZSB0YWJiaW5nIG9yZGVyLiBTZWUKLSAgICAgKiB0aGUgIHRhYmluZGV4IGF0dHJpYnV0ZSBkZWZpbml0aW9uIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0VGFiSW5kZXgoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRUYWJJbmRleChpbnQgdGFiSW5kZXgpOwotCi0gICAgLyoqCi0gICAgICogIEZyYW1lIHRvIHJlbmRlciB0aGUgcmVzb3VyY2UgaW4uIFNlZSB0aGUgIHRhcmdldCBhdHRyaWJ1dGUgZGVmaW5pdGlvbgotICAgICAqIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0KCk7Ci0gICAgcHVibGljIHZvaWQgc2V0VGFyZ2V0KFN0cmluZyB0YXJnZXQpOwotCi0gICAgLyoqCi0gICAgICogIEFkdmlzb3J5IGNvbnRlbnQgdHlwZS4gU2VlIHRoZSAgdHlwZSBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFR5cGUoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRUeXBlKFN0cmluZyB0eXBlKTsKLQotICAgIC8qKgotICAgICAqICBSZW1vdmVzIGtleWJvYXJkIGZvY3VzIGZyb20gdGhpcyBlbGVtZW50LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGJsdXIoKTsKLQotICAgIC8qKgotICAgICAqICBHaXZlcyBrZXlib2FyZCBmb2N1cyB0byB0aGlzIGVsZW1lbnQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZm9jdXMoKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTEFwcGxldEVsZW1lbnQuamF2YSBiL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxBcHBsZXRFbGVtZW50LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGQxNTkzMTkuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTEFwcGxldEVsZW1lbnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEzMSArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogVGhpcyBmaWxlIGlzIGF2YWlsYWJsZSB1bmRlciBhbmQgZ292ZXJuZWQgYnkgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwotICogTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKiBIb3dldmVyLCB0aGUgZm9sbG93aW5nIG5vdGljZSBhY2NvbXBhbmllZCB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGlzCi0gKiBmaWxlIGFuZCwgcGVyIGl0cyB0ZXJtcywgc2hvdWxkIG5vdCBiZSByZW1vdmVkOgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAotICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCi0gKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKLSAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQotICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKLSAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KLSAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKLSAqIFBVUlBPU0UuIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZQotICogZGV0YWlscy4KLSAqLwotCi1wYWNrYWdlIG9yZy53M2MuZG9tLmh0bWw7Ci0KLS8qKgotICogIEFuIGVtYmVkZGVkIEphdmEgYXBwbGV0LiBTZWUgdGhlICBBUFBMRVQgZWxlbWVudCBkZWZpbml0aW9uIGluIEhUTUwgNC4wLgotICogVGhpcyBlbGVtZW50IGlzIGRlcHJlY2F0ZWQgaW4gSFRNTCA0LjAuCi0gKiA8cD5TZWUgYWxzbyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMC9DUi1ET00tTGV2ZWwtMi0yMDAwMDUxMCc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDIgU3BlY2lmaWNhdGlvbjwvYT4uCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgSFRNTEFwcGxldEVsZW1lbnQgZXh0ZW5kcyBIVE1MRWxlbWVudCB7Ci0gICAgLyoqCi0gICAgICogIEFsaWducyB0aGlzIG9iamVjdCAodmVydGljYWxseSBvciBob3Jpem9udGFsbHkpICB3aXRoIHJlc3BlY3QgdG8gaXRzCi0gICAgICogc3Vycm91bmRpbmcgdGV4dC4gU2VlIHRoZSAgYWxpZ24gYXR0cmlidXRlIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gICAgICogVGhpcyBhdHRyaWJ1dGUgaXMgZGVwcmVjYXRlZCBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEFsaWduKCk7Ci0gICAgcHVibGljIHZvaWQgc2V0QWxpZ24oU3RyaW5nIGFsaWduKTsKLQotICAgIC8qKgotICAgICAqICBBbHRlcm5hdGUgdGV4dCBmb3IgdXNlciBhZ2VudHMgbm90IHJlbmRlcmluZyB0aGUgbm9ybWFsIGNvbnRlbnQgb2YKLSAgICAgKiB0aGlzIGVsZW1lbnQuIFNlZSB0aGUgIGFsdCBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4gVGhpcwotICAgICAqIGF0dHJpYnV0ZSBpcyBkZXByZWNhdGVkIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0QWx0KCk7Ci0gICAgcHVibGljIHZvaWQgc2V0QWx0KFN0cmluZyBhbHQpOwotCi0gICAgLyoqCi0gICAgICogIENvbW1hLXNlcGFyYXRlZCBhcmNoaXZlIGxpc3QuIFNlZSB0aGUgIGFyY2hpdmUgYXR0cmlidXRlIGRlZmluaXRpb24gaW4KLSAgICAgKiBIVE1MIDQuMC4gVGhpcyBhdHRyaWJ1dGUgaXMgZGVwcmVjYXRlZCBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEFyY2hpdmUoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRBcmNoaXZlKFN0cmluZyBhcmNoaXZlKTsKLQotICAgIC8qKgotICAgICAqICBBcHBsZXQgY2xhc3MgZmlsZS4gIFNlZSB0aGUgIGNvZGUgYXR0cmlidXRlIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gICAgICogVGhpcyBhdHRyaWJ1dGUgaXMgZGVwcmVjYXRlZCBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldENvZGUoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRDb2RlKFN0cmluZyBjb2RlKTsKLQotICAgIC8qKgotICAgICAqICBPcHRpb25hbCBiYXNlIFVSSSBmb3IgYXBwbGV0LiBTZWUgdGhlICBjb2RlYmFzZSBhdHRyaWJ1dGUgZGVmaW5pdGlvbgotICAgICAqIGluIEhUTUwgNC4wLiBUaGlzIGF0dHJpYnV0ZSBpcyBkZXByZWNhdGVkIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q29kZUJhc2UoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRDb2RlQmFzZShTdHJpbmcgY29kZUJhc2UpOwotCi0gICAgLyoqCi0gICAgICogIE92ZXJyaWRlIGhlaWdodC4gU2VlIHRoZSAgaGVpZ2h0IGF0dHJpYnV0ZSBkZWZpbml0aW9uIGluIEhUTUwgNC4wLgotICAgICAqIFRoaXMgYXR0cmlidXRlIGlzIGRlcHJlY2F0ZWQgaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRIZWlnaHQoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRIZWlnaHQoU3RyaW5nIGhlaWdodCk7Ci0KLSAgICAvKioKLSAgICAgKiAgSG9yaXpvbnRhbCBzcGFjZSB0byB0aGUgbGVmdCBhbmQgcmlnaHQgb2YgdGhpcyBpbWFnZSwgYXBwbGV0LCBvcgotICAgICAqIG9iamVjdC4gU2VlIHRoZSAgaHNwYWNlIGF0dHJpYnV0ZSBkZWZpbml0aW9uIGluIEhUTUwgNC4wLiBUaGlzCi0gICAgICogYXR0cmlidXRlIGlzIGRlcHJlY2F0ZWQgaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRIc3BhY2UoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRIc3BhY2UoU3RyaW5nIGhzcGFjZSk7Ci0KLSAgICAvKioKLSAgICAgKiAgVGhlIG5hbWUgb2YgdGhlIGFwcGxldC4gU2VlIHRoZSAgbmFtZSBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MCi0gICAgICogNC4wLiBUaGlzIGF0dHJpYnV0ZSBpcyBkZXByZWNhdGVkIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpOwotICAgIHB1YmxpYyB2b2lkIHNldE5hbWUoU3RyaW5nIG5hbWUpOwotCi0gICAgLyoqCi0gICAgICogIFNlcmlhbGl6ZWQgYXBwbGV0IGZpbGUuIFNlZSB0aGUgIG9iamVjdCBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MCi0gICAgICogNC4wLiBUaGlzIGF0dHJpYnV0ZSBpcyBkZXByZWNhdGVkIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0T2JqZWN0KCk7Ci0gICAgcHVibGljIHZvaWQgc2V0T2JqZWN0KFN0cmluZyBvYmplY3QpOwotCi0gICAgLyoqCi0gICAgICogIFZlcnRpY2FsIHNwYWNlIGFib3ZlIGFuZCBiZWxvdyB0aGlzIGltYWdlLCBhcHBsZXQsIG9yIG9iamVjdC4gU2VlIHRoZQotICAgICAqIHZzcGFjZSBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4gVGhpcyBhdHRyaWJ1dGUgaXMgZGVwcmVjYXRlZAotICAgICAqIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VnNwYWNlKCk7Ci0gICAgcHVibGljIHZvaWQgc2V0VnNwYWNlKFN0cmluZyB2c3BhY2UpOwotCi0gICAgLyoqCi0gICAgICogIE92ZXJyaWRlIHdpZHRoLiBTZWUgdGhlICB3aWR0aCBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4gVGhpcwotICAgICAqIGF0dHJpYnV0ZSBpcyBkZXByZWNhdGVkIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0V2lkdGgoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRXaWR0aChTdHJpbmcgd2lkdGgpOwotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL3czYy9kb20vaHRtbC9IVE1MQXJlYUVsZW1lbnQuamF2YSBiL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxBcmVhRWxlbWVudC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmNTFjYzMxLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxBcmVhRWxlbWVudC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTA3ICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBUaGlzIGZpbGUgaXMgYXZhaWxhYmxlIHVuZGVyIGFuZCBnb3Zlcm5lZCBieSB0aGUgR05VIEdlbmVyYWwgUHVibGljCi0gKiBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqIEhvd2V2ZXIsIHRoZSBmb2xsb3dpbmcgbm90aWNlIGFjY29tcGFuaWVkIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIG9mIHRoaXMKLSAqIGZpbGUgYW5kLCBwZXIgaXRzIHRlcm1zLCBzaG91bGQgbm90IGJlIHJlbW92ZWQ6Ci0gKgotICogQ29weXJpZ2h0IChjKSAyMDAwIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKLSAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAotICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCi0gKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQotICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgotICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgotICogUFVSUE9TRS4gU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlCi0gKiBkZXRhaWxzLgotICovCi0KLXBhY2thZ2Ugb3JnLnczYy5kb20uaHRtbDsKLQotLyoqCi0gKiAgQ2xpZW50LXNpZGUgaW1hZ2UgbWFwIGFyZWEgZGVmaW5pdGlvbi4gU2VlIHRoZSAgQVJFQSBlbGVtZW50IGRlZmluaXRpb24gaW4KLSAqIEhUTUwgNC4wLgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDAvQ1ItRE9NLUxldmVsLTItMjAwMDA1MTAnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAyIFNwZWNpZmljYXRpb248L2E+LgotICovCi1wdWJsaWMgaW50ZXJmYWNlIEhUTUxBcmVhRWxlbWVudCBleHRlbmRzIEhUTUxFbGVtZW50IHsKLSAgICAvKioKLSAgICAgKiAgQSBzaW5nbGUgY2hhcmFjdGVyIGFjY2VzcyBrZXkgdG8gZ2l2ZSBhY2Nlc3MgdG8gdGhlIGZvcm0gY29udHJvbC4gU2VlCi0gICAgICogdGhlICBhY2Nlc3NrZXkgYXR0cmlidXRlIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRBY2Nlc3NLZXkoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRBY2Nlc3NLZXkoU3RyaW5nIGFjY2Vzc0tleSk7Ci0KLSAgICAvKioKLSAgICAgKiAgQWx0ZXJuYXRlIHRleHQgZm9yIHVzZXIgYWdlbnRzIG5vdCByZW5kZXJpbmcgdGhlIG5vcm1hbCBjb250ZW50IG9mCi0gICAgICogdGhpcyBlbGVtZW50LiBTZWUgdGhlICBhbHQgYXR0cmlidXRlIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRBbHQoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRBbHQoU3RyaW5nIGFsdCk7Ci0KLSAgICAvKioKLSAgICAgKiAgQ29tbWEtc2VwYXJhdGVkIGxpc3Qgb2YgbGVuZ3RocywgZGVmaW5pbmcgYW4gYWN0aXZlIHJlZ2lvbiBnZW9tZXRyeS4KLSAgICAgKiBTZWUgYWxzbyA8Y29kZT5zaGFwZTwvY29kZT4gZm9yIHRoZSBzaGFwZSBvZiB0aGUgcmVnaW9uLiBTZWUgdGhlCi0gICAgICogY29vcmRzIGF0dHJpYnV0ZSBkZWZpbml0aW9uIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q29vcmRzKCk7Ci0gICAgcHVibGljIHZvaWQgc2V0Q29vcmRzKFN0cmluZyBjb29yZHMpOwotCi0gICAgLyoqCi0gICAgICogIFRoZSBVUkkgb2YgdGhlIGxpbmtlZCByZXNvdXJjZS4gU2VlIHRoZSAgaHJlZiBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbgotICAgICAqIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0SHJlZigpOwotICAgIHB1YmxpYyB2b2lkIHNldEhyZWYoU3RyaW5nIGhyZWYpOwotCi0gICAgLyoqCi0gICAgICogIFNwZWNpZmllcyB0aGF0IHRoaXMgYXJlYSBpcyBpbmFjdGl2ZSwgaS5lLiwgaGFzIG5vIGFzc29jaWF0ZWQgYWN0aW9uLgotICAgICAqIFNlZSB0aGUgIG5vaHJlZiBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXROb0hyZWYoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXROb0hyZWYoYm9vbGVhbiBub0hyZWYpOwotCi0gICAgLyoqCi0gICAgICogIFRoZSBzaGFwZSBvZiB0aGUgYWN0aXZlIGFyZWEuIFRoZSBjb29yZGluYXRlcyBhcmUgZ2l2ZW4gYnkKLSAgICAgKiA8Y29kZT5jb29yZHM8L2NvZGU+IC4gU2VlIHRoZSAgc2hhcGUgYXR0cmlidXRlIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRTaGFwZSgpOwotICAgIHB1YmxpYyB2b2lkIHNldFNoYXBlKFN0cmluZyBzaGFwZSk7Ci0KLSAgICAvKioKLSAgICAgKiAgSW5kZXggdGhhdCByZXByZXNlbnRzIHRoZSBlbGVtZW50J3MgcG9zaXRpb24gaW4gdGhlIHRhYmJpbmcgb3JkZXIuIFNlZQotICAgICAqIHRoZSAgdGFiaW5kZXggYXR0cmlidXRlIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRUYWJJbmRleCgpOwotICAgIHB1YmxpYyB2b2lkIHNldFRhYkluZGV4KGludCB0YWJJbmRleCk7Ci0KLSAgICAvKioKLSAgICAgKiAgRnJhbWUgdG8gcmVuZGVyIHRoZSByZXNvdXJjZSBpbi4gU2VlIHRoZSAgdGFyZ2V0IGF0dHJpYnV0ZSBkZWZpbml0aW9uCi0gICAgICogaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXQoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRUYXJnZXQoU3RyaW5nIHRhcmdldCk7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxCUkVsZW1lbnQuamF2YSBiL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxCUkVsZW1lbnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZjM1MjEyZi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3czYy9kb20vaHRtbC9IVE1MQlJFbGVtZW50LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw1NiArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogVGhpcyBmaWxlIGlzIGF2YWlsYWJsZSB1bmRlciBhbmQgZ292ZXJuZWQgYnkgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwotICogTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKiBIb3dldmVyLCB0aGUgZm9sbG93aW5nIG5vdGljZSBhY2NvbXBhbmllZCB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGlzCi0gKiBmaWxlIGFuZCwgcGVyIGl0cyB0ZXJtcywgc2hvdWxkIG5vdCBiZSByZW1vdmVkOgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAotICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCi0gKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKLSAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQotICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKLSAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KLSAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKLSAqIFBVUlBPU0UuIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZQotICogZGV0YWlscy4KLSAqLwotCi1wYWNrYWdlIG9yZy53M2MuZG9tLmh0bWw7Ci0KLS8qKgotICogIEZvcmNlIGEgbGluZSBicmVhay4gU2VlIHRoZSAgQlIgZWxlbWVudCBkZWZpbml0aW9uIGluIEhUTUwgNC4wLgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDAvQ1ItRE9NLUxldmVsLTItMjAwMDA1MTAnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAyIFNwZWNpZmljYXRpb248L2E+LgotICovCi1wdWJsaWMgaW50ZXJmYWNlIEhUTUxCUkVsZW1lbnQgZXh0ZW5kcyBIVE1MRWxlbWVudCB7Ci0gICAgLyoqCi0gICAgICogIENvbnRyb2wgZmxvdyBvZiB0ZXh0IGFyb3VuZCBmbG9hdHMuIFNlZSB0aGUgIGNsZWFyIGF0dHJpYnV0ZSBkZWZpbml0aW9uCi0gICAgICogIGluIEhUTUwgNC4wLiBUaGlzIGF0dHJpYnV0ZSBpcyBkZXByZWNhdGVkIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q2xlYXIoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRDbGVhcihTdHJpbmcgY2xlYXIpOwotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL3czYy9kb20vaHRtbC9IVE1MQmFzZUVsZW1lbnQuamF2YSBiL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxCYXNlRWxlbWVudC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2OWY1MThiLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxCYXNlRWxlbWVudC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNjIgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIFRoaXMgZmlsZSBpcyBhdmFpbGFibGUgdW5kZXIgYW5kIGdvdmVybmVkIGJ5IHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKLSAqIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICogSG93ZXZlciwgdGhlIGZvbGxvd2luZyBub3RpY2UgYWNjb21wYW5pZWQgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcwotICogZmlsZSBhbmQsIHBlciBpdHMgdGVybXMsIHNob3VsZCBub3QgYmUgcmVtb3ZlZDoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDAgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKLSAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQotICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCi0gKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKLSAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCi0gKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCi0gKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCi0gKiBQVVJQT1NFLiBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUKLSAqIGRldGFpbHMuCi0gKi8KLQotcGFja2FnZSBvcmcudzNjLmRvbS5odG1sOwotCi0vKioKLSAqICBEb2N1bWVudCBiYXNlIFVSSS4gU2VlIHRoZSAgQkFTRSBlbGVtZW50IGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gKiA8cD5TZWUgYWxzbyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMC9DUi1ET00tTGV2ZWwtMi0yMDAwMDUxMCc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDIgU3BlY2lmaWNhdGlvbjwvYT4uCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgSFRNTEJhc2VFbGVtZW50IGV4dGVuZHMgSFRNTEVsZW1lbnQgewotICAgIC8qKgotICAgICAqICBUaGUgYmFzZSBVUkkuIFNlZSB0aGUgIGhyZWYgYXR0cmlidXRlIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRIcmVmKCk7Ci0gICAgcHVibGljIHZvaWQgc2V0SHJlZihTdHJpbmcgaHJlZik7Ci0KLSAgICAvKioKLSAgICAgKiAgVGhlIGRlZmF1bHQgdGFyZ2V0IGZyYW1lLiBTZWUgdGhlICB0YXJnZXQgYXR0cmlidXRlIGRlZmluaXRpb24gaW4gSFRNTAotICAgICAqIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFRhcmdldCgpOwotICAgIHB1YmxpYyB2b2lkIHNldFRhcmdldChTdHJpbmcgdGFyZ2V0KTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTEJhc2VGb250RWxlbWVudC5qYXZhIGIvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTEJhc2VGb250RWxlbWVudC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2OGVkNjExLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxCYXNlRm9udEVsZW1lbnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDcxICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBUaGlzIGZpbGUgaXMgYXZhaWxhYmxlIHVuZGVyIGFuZCBnb3Zlcm5lZCBieSB0aGUgR05VIEdlbmVyYWwgUHVibGljCi0gKiBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqIEhvd2V2ZXIsIHRoZSBmb2xsb3dpbmcgbm90aWNlIGFjY29tcGFuaWVkIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIG9mIHRoaXMKLSAqIGZpbGUgYW5kLCBwZXIgaXRzIHRlcm1zLCBzaG91bGQgbm90IGJlIHJlbW92ZWQ6Ci0gKgotICogQ29weXJpZ2h0IChjKSAyMDAwIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKLSAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAotICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCi0gKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQotICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgotICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgotICogUFVSUE9TRS4gU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlCi0gKiBkZXRhaWxzLgotICovCi0KLXBhY2thZ2Ugb3JnLnczYy5kb20uaHRtbDsKLQotLyoqCi0gKiAgQmFzZSBmb250LiBTZWUgdGhlICBCQVNFRk9OVCBlbGVtZW50IGRlZmluaXRpb24gaW4gSFRNTCA0LjAuIFRoaXMgZWxlbWVudAotICogaXMgZGVwcmVjYXRlZCBpbiBIVE1MIDQuMC4KLSAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAwL0NSLURPTS1MZXZlbC0yLTIwMDAwNTEwJz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMiBTcGVjaWZpY2F0aW9uPC9hPi4KLSAqLwotcHVibGljIGludGVyZmFjZSBIVE1MQmFzZUZvbnRFbGVtZW50IGV4dGVuZHMgSFRNTEVsZW1lbnQgewotICAgIC8qKgotICAgICAqICBGb250IGNvbG9yLiBTZWUgdGhlICBjb2xvciBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4gVGhpcwotICAgICAqIGF0dHJpYnV0ZSBpcyBkZXByZWNhdGVkIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q29sb3IoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRDb2xvcihTdHJpbmcgY29sb3IpOwotCi0gICAgLyoqCi0gICAgICogIEZvbnQgZmFjZSBpZGVudGlmaWVyLiBTZWUgdGhlICBmYWNlIGF0dHJpYnV0ZSBkZWZpbml0aW9uIGluIEhUTUwgNC4wLgotICAgICAqIFRoaXMgYXR0cmlidXRlIGlzIGRlcHJlY2F0ZWQgaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRGYWNlKCk7Ci0gICAgcHVibGljIHZvaWQgc2V0RmFjZShTdHJpbmcgZmFjZSk7Ci0KLSAgICAvKioKLSAgICAgKiAgRm9udCBzaXplLiBTZWUgdGhlICBzaXplIGF0dHJpYnV0ZSBkZWZpbml0aW9uIGluIEhUTUwgNC4wLiBUaGlzCi0gICAgICogYXR0cmlidXRlIGlzIGRlcHJlY2F0ZWQgaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRTaXplKCk7Ci0gICAgcHVibGljIHZvaWQgc2V0U2l6ZShTdHJpbmcgc2l6ZSk7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxCb2R5RWxlbWVudC5qYXZhIGIvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTEJvZHlFbGVtZW50LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGQwZjJlNDUuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTEJvZHlFbGVtZW50LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5NyArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogVGhpcyBmaWxlIGlzIGF2YWlsYWJsZSB1bmRlciBhbmQgZ292ZXJuZWQgYnkgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwotICogTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKiBIb3dldmVyLCB0aGUgZm9sbG93aW5nIG5vdGljZSBhY2NvbXBhbmllZCB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGlzCi0gKiBmaWxlIGFuZCwgcGVyIGl0cyB0ZXJtcywgc2hvdWxkIG5vdCBiZSByZW1vdmVkOgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAotICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCi0gKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKLSAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQotICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKLSAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KLSAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKLSAqIFBVUlBPU0UuIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZQotICogZGV0YWlscy4KLSAqLwotCi1wYWNrYWdlIG9yZy53M2MuZG9tLmh0bWw7Ci0KLS8qKgotICogIFRoZSBIVE1MIGRvY3VtZW50IGJvZHkuIFRoaXMgZWxlbWVudCBpcyBhbHdheXMgcHJlc2VudCBpbiB0aGUgRE9NIEFQSSwKLSAqIGV2ZW4gaWYgdGhlIHRhZ3MgYXJlIG5vdCBwcmVzZW50IGluIHRoZSBzb3VyY2UgZG9jdW1lbnQuIFNlZSB0aGUgIEJPRFkKLSAqIGVsZW1lbnQgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAwL0NSLURPTS1MZXZlbC0yLTIwMDAwNTEwJz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMiBTcGVjaWZpY2F0aW9uPC9hPi4KLSAqLwotcHVibGljIGludGVyZmFjZSBIVE1MQm9keUVsZW1lbnQgZXh0ZW5kcyBIVE1MRWxlbWVudCB7Ci0gICAgLyoqCi0gICAgICogIENvbG9yIG9mIGFjdGl2ZSBsaW5rcyAoYWZ0ZXIgbW91c2UtYnV0dG9uIGRvd24sIGJ1dCBiZWZvcmUKLSAgICAgKiBtb3VzZS1idXR0b24gdXApLiBTZWUgdGhlICBhbGluayBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAgICAgKiBUaGlzIGF0dHJpYnV0ZSBpcyBkZXByZWNhdGVkIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0QUxpbmsoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRBTGluayhTdHJpbmcgYUxpbmspOwotCi0gICAgLyoqCi0gICAgICogIFVSSSBvZiB0aGUgYmFja2dyb3VuZCB0ZXh0dXJlIHRpbGUgaW1hZ2UuIFNlZSB0aGUgIGJhY2tncm91bmQKLSAgICAgKiBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4gVGhpcyBhdHRyaWJ1dGUgaXMgZGVwcmVjYXRlZCBpbiBIVE1MCi0gICAgICogNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0QmFja2dyb3VuZCgpOwotICAgIHB1YmxpYyB2b2lkIHNldEJhY2tncm91bmQoU3RyaW5nIGJhY2tncm91bmQpOwotCi0gICAgLyoqCi0gICAgICogIERvY3VtZW50IGJhY2tncm91bmQgY29sb3IuIFNlZSB0aGUgIGJnY29sb3IgYXR0cmlidXRlIGRlZmluaXRpb24gaW4KLSAgICAgKiBIVE1MIDQuMC4gVGhpcyBhdHRyaWJ1dGUgaXMgZGVwcmVjYXRlZCBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEJnQ29sb3IoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRCZ0NvbG9yKFN0cmluZyBiZ0NvbG9yKTsKLQotICAgIC8qKgotICAgICAqICBDb2xvciBvZiBsaW5rcyB0aGF0IGFyZSBub3QgYWN0aXZlIGFuZCB1bnZpc2l0ZWQuIFNlZSB0aGUgIGxpbmsKLSAgICAgKiBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4gVGhpcyBhdHRyaWJ1dGUgaXMgZGVwcmVjYXRlZCBpbiBIVE1MCi0gICAgICogNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TGluaygpOwotICAgIHB1YmxpYyB2b2lkIHNldExpbmsoU3RyaW5nIGxpbmspOwotCi0gICAgLyoqCi0gICAgICogIERvY3VtZW50IHRleHQgY29sb3IuIFNlZSB0aGUgIHRleHQgYXR0cmlidXRlIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gICAgICogVGhpcyBhdHRyaWJ1dGUgaXMgZGVwcmVjYXRlZCBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFRleHQoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRUZXh0KFN0cmluZyB0ZXh0KTsKLQotICAgIC8qKgotICAgICAqICBDb2xvciBvZiBsaW5rcyB0aGF0IGhhdmUgYmVlbiB2aXNpdGVkIGJ5IHRoZSB1c2VyLiBTZWUgdGhlICB2bGluawotICAgICAqIGF0dHJpYnV0ZSBkZWZpbml0aW9uIGluIEhUTUwgNC4wLiBUaGlzIGF0dHJpYnV0ZSBpcyBkZXByZWNhdGVkIGluIEhUTUwKLSAgICAgKiA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRWTGluaygpOwotICAgIHB1YmxpYyB2b2lkIHNldFZMaW5rKFN0cmluZyB2TGluayk7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxCdXR0b25FbGVtZW50LmphdmEgYi9zcmMvb3JnL3czYy9kb20vaHRtbC9IVE1MQnV0dG9uRWxlbWVudC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4ZDQ1ZGJmLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxCdXR0b25FbGVtZW50LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5NSArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogVGhpcyBmaWxlIGlzIGF2YWlsYWJsZSB1bmRlciBhbmQgZ292ZXJuZWQgYnkgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwotICogTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKiBIb3dldmVyLCB0aGUgZm9sbG93aW5nIG5vdGljZSBhY2NvbXBhbmllZCB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGlzCi0gKiBmaWxlIGFuZCwgcGVyIGl0cyB0ZXJtcywgc2hvdWxkIG5vdCBiZSByZW1vdmVkOgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAotICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCi0gKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKLSAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQotICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKLSAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KLSAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKLSAqIFBVUlBPU0UuIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZQotICogZGV0YWlscy4KLSAqLwotCi1wYWNrYWdlIG9yZy53M2MuZG9tLmh0bWw7Ci0KLS8qKgotICogIFB1c2ggYnV0dG9uLiBTZWUgdGhlICBCVVRUT04gZWxlbWVudCBkZWZpbml0aW9uIGluIEhUTUwgNC4wLgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDAvQ1ItRE9NLUxldmVsLTItMjAwMDA1MTAnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAyIFNwZWNpZmljYXRpb248L2E+LgotICovCi1wdWJsaWMgaW50ZXJmYWNlIEhUTUxCdXR0b25FbGVtZW50IGV4dGVuZHMgSFRNTEVsZW1lbnQgewotICAgIC8qKgotICAgICAqICBSZXR1cm5zIHRoZSA8Y29kZT5GT1JNPC9jb2RlPiBlbGVtZW50IGNvbnRhaW5pbmcgdGhpcyBjb250cm9sLiBSZXR1cm5zCi0gICAgICogPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhpcyBjb250cm9sIGlzIG5vdCB3aXRoaW4gdGhlIGNvbnRleHQgb2YgYSBmb3JtLgotICAgICAqLwotICAgIHB1YmxpYyBIVE1MRm9ybUVsZW1lbnQgZ2V0Rm9ybSgpOwotCi0gICAgLyoqCi0gICAgICogIEEgc2luZ2xlIGNoYXJhY3RlciBhY2Nlc3Mga2V5IHRvIGdpdmUgYWNjZXNzIHRvIHRoZSBmb3JtIGNvbnRyb2wuIFNlZQotICAgICAqIHRoZSAgYWNjZXNza2V5IGF0dHJpYnV0ZSBkZWZpbml0aW9uIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0QWNjZXNzS2V5KCk7Ci0gICAgcHVibGljIHZvaWQgc2V0QWNjZXNzS2V5KFN0cmluZyBhY2Nlc3NLZXkpOwotCi0gICAgLyoqCi0gICAgICogIFRoZSBjb250cm9sIGlzIHVuYXZhaWxhYmxlIGluIHRoaXMgY29udGV4dC4gU2VlIHRoZSAgZGlzYWJsZWQKLSAgICAgKiBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXREaXNhYmxlZCgpOwotICAgIHB1YmxpYyB2b2lkIHNldERpc2FibGVkKGJvb2xlYW4gZGlzYWJsZWQpOwotCi0gICAgLyoqCi0gICAgICogIEZvcm0gY29udHJvbCBvciBvYmplY3QgbmFtZSB3aGVuIHN1Ym1pdHRlZCB3aXRoIGEgZm9ybS4gU2VlIHRoZSAgbmFtZQotICAgICAqIGF0dHJpYnV0ZSBkZWZpbml0aW9uIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpOwotICAgIHB1YmxpYyB2b2lkIHNldE5hbWUoU3RyaW5nIG5hbWUpOwotCi0gICAgLyoqCi0gICAgICogIEluZGV4IHRoYXQgcmVwcmVzZW50cyB0aGUgZWxlbWVudCdzIHBvc2l0aW9uIGluIHRoZSB0YWJiaW5nIG9yZGVyLiBTZWUKLSAgICAgKiB0aGUgIHRhYmluZGV4IGF0dHJpYnV0ZSBkZWZpbml0aW9uIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0VGFiSW5kZXgoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRUYWJJbmRleChpbnQgdGFiSW5kZXgpOwotCi0gICAgLyoqCi0gICAgICogIFRoZSB0eXBlIG9mIGJ1dHRvbi4gU2VlIHRoZSAgdHlwZSBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFR5cGUoKTsKLQotICAgIC8qKgotICAgICAqICBUaGUgY3VycmVudCBmb3JtIGNvbnRyb2wgdmFsdWUuIFNlZSB0aGUgIHZhbHVlIGF0dHJpYnV0ZSBkZWZpbml0aW9uIGluCi0gICAgICogSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRWYWx1ZSgpOwotICAgIHB1YmxpYyB2b2lkIHNldFZhbHVlKFN0cmluZyB2YWx1ZSk7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxDb2xsZWN0aW9uLmphdmEgYi9zcmMvb3JnL3czYy9kb20vaHRtbC9IVE1MQ29sbGVjdGlvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxYzg3ZmQ5Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxDb2xsZWN0aW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4NSArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogVGhpcyBmaWxlIGlzIGF2YWlsYWJsZSB1bmRlciBhbmQgZ292ZXJuZWQgYnkgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwotICogTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKiBIb3dldmVyLCB0aGUgZm9sbG93aW5nIG5vdGljZSBhY2NvbXBhbmllZCB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGlzCi0gKiBmaWxlIGFuZCwgcGVyIGl0cyB0ZXJtcywgc2hvdWxkIG5vdCBiZSByZW1vdmVkOgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAotICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCi0gKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKLSAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQotICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKLSAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KLSAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKLSAqIFBVUlBPU0UuIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZQotICogZGV0YWlscy4KLSAqLwotCi1wYWNrYWdlIG9yZy53M2MuZG9tLmh0bWw7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotCi0vKioKLSAqICBBbiA8Y29kZT5IVE1MQ29sbGVjdGlvbjwvY29kZT4gaXMgYSBsaXN0IG9mIG5vZGVzLiBBbiBpbmRpdmlkdWFsIG5vZGUgbWF5Ci0gKiBiZSBhY2Nlc3NlZCBieSBlaXRoZXIgb3JkaW5hbCBpbmRleCBvciB0aGUgbm9kZSdzPGNvZGU+bmFtZTwvY29kZT4gb3IKLSAqIDxjb2RlPmlkPC9jb2RlPiBhdHRyaWJ1dGVzLiAgTm90ZTogQ29sbGVjdGlvbnMgaW4gdGhlIEhUTUwgRE9NIGFyZSBhc3N1bWVkCi0gKiB0byBiZSAgbGl2ZSBtZWFuaW5nIHRoYXQgdGhleSBhcmUgYXV0b21hdGljYWxseSB1cGRhdGVkIHdoZW4gdGhlCi0gKiB1bmRlcmx5aW5nIGRvY3VtZW50IGlzIGNoYW5nZWQuCi0gKiA8cD5TZWUgYWxzbyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMC9DUi1ET00tTGV2ZWwtMi0yMDAwMDUxMCc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDIgU3BlY2lmaWNhdGlvbjwvYT4uCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgSFRNTENvbGxlY3Rpb24gewotICAgIC8qKgotICAgICAqICBUaGlzIGF0dHJpYnV0ZSBzcGVjaWZpZXMgdGhlIGxlbmd0aCBvciAgc2l6ZSBvZiB0aGUgbGlzdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldExlbmd0aCgpOwotCi0gICAgLyoqCi0gICAgICogIFRoaXMgbWV0aG9kIHJldHJpZXZlcyBhIG5vZGUgc3BlY2lmaWVkIGJ5IG9yZGluYWwgaW5kZXguIE5vZGVzIGFyZQotICAgICAqIG51bWJlcmVkIGluIHRyZWUgb3JkZXIgKGRlcHRoLWZpcnN0IHRyYXZlcnNhbCBvcmRlcikuCi0gICAgICogQHBhcmFtIGluZGV4ICBUaGUgaW5kZXggb2YgdGhlIG5vZGUgdG8gYmUgZmV0Y2hlZC4gVGhlIGluZGV4IG9yaWdpbiBpcwotICAgICAqICAgMC4KLSAgICAgKiBAcmV0dXJuICBUaGUgPGNvZGU+Tm9kZTwvY29kZT4gYXQgdGhlIGNvcnJlc3BvbmRpbmcgcG9zaXRpb24gdXBvbgotICAgICAqICAgc3VjY2Vzcy4gQSB2YWx1ZSBvZiA8Y29kZT5udWxsPC9jb2RlPiBpcyByZXR1cm5lZCBpZiB0aGUgaW5kZXggaXMKLSAgICAgKiAgIG91dCBvZiByYW5nZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgTm9kZSBpdGVtKGludCBpbmRleCk7Ci0KLSAgICAvKioKLSAgICAgKiAgVGhpcyBtZXRob2QgcmV0cmlldmVzIGEgPGNvZGU+Tm9kZTwvY29kZT4gdXNpbmcgYSBuYW1lLiBJdCBmaXJzdAotICAgICAqIHNlYXJjaGVzIGZvciBhIDxjb2RlPk5vZGU8L2NvZGU+IHdpdGggYSBtYXRjaGluZyA8Y29kZT5pZDwvY29kZT4KLSAgICAgKiBhdHRyaWJ1dGUuIElmIGl0IGRvZXNuJ3QgZmluZCBvbmUsIGl0IHRoZW4gc2VhcmNoZXMgZm9yIGEKLSAgICAgKiA8Y29kZT5Ob2RlPC9jb2RlPiB3aXRoIGEgbWF0Y2hpbmcgPGNvZGU+bmFtZTwvY29kZT4gYXR0cmlidXRlLCBidXQKLSAgICAgKiBvbmx5IG9uIHRob3NlIGVsZW1lbnRzIHRoYXQgYXJlIGFsbG93ZWQgYSBuYW1lIGF0dHJpYnV0ZS4KLSAgICAgKiBAcGFyYW0gbmFtZSAgVGhlIG5hbWUgb2YgdGhlIDxjb2RlPk5vZGU8L2NvZGU+IHRvIGJlIGZldGNoZWQuCi0gICAgICogQHJldHVybiAgVGhlIDxjb2RlPk5vZGU8L2NvZGU+IHdpdGggYSA8Y29kZT5uYW1lPC9jb2RlPiBvcgotICAgICAqICAgPGNvZGU+aWQ8L2NvZGU+IGF0dHJpYnV0ZSB3aG9zZSB2YWx1ZSBjb3JyZXNwb25kcyB0byB0aGUgc3BlY2lmaWVkCi0gICAgICogICBzdHJpbmcuIFVwb24gZmFpbHVyZSAoZS5nLiwgbm8gbm9kZSB3aXRoIHRoaXMgbmFtZSBleGlzdHMpLCByZXR1cm5zCi0gICAgICogICA8Y29kZT5udWxsPC9jb2RlPiAuCi0gICAgICovCi0gICAgcHVibGljIE5vZGUgbmFtZWRJdGVtKFN0cmluZyBuYW1lKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTERMaXN0RWxlbWVudC5qYXZhIGIvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTERMaXN0RWxlbWVudC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4ZTBkYWQ5Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxETGlzdEVsZW1lbnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDU2ICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBUaGlzIGZpbGUgaXMgYXZhaWxhYmxlIHVuZGVyIGFuZCBnb3Zlcm5lZCBieSB0aGUgR05VIEdlbmVyYWwgUHVibGljCi0gKiBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqIEhvd2V2ZXIsIHRoZSBmb2xsb3dpbmcgbm90aWNlIGFjY29tcGFuaWVkIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIG9mIHRoaXMKLSAqIGZpbGUgYW5kLCBwZXIgaXRzIHRlcm1zLCBzaG91bGQgbm90IGJlIHJlbW92ZWQ6Ci0gKgotICogQ29weXJpZ2h0IChjKSAyMDAwIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKLSAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAotICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCi0gKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQotICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgotICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgotICogUFVSUE9TRS4gU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlCi0gKiBkZXRhaWxzLgotICovCi0KLXBhY2thZ2Ugb3JnLnczYy5kb20uaHRtbDsKLQotLyoqCi0gKiAgRGVmaW5pdGlvbiBsaXN0LiBTZWUgdGhlICBETCBlbGVtZW50IGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gKiA8cD5TZWUgYWxzbyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMC9DUi1ET00tTGV2ZWwtMi0yMDAwMDUxMCc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDIgU3BlY2lmaWNhdGlvbjwvYT4uCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgSFRNTERMaXN0RWxlbWVudCBleHRlbmRzIEhUTUxFbGVtZW50IHsKLSAgICAvKioKLSAgICAgKiAgUmVkdWNlIHNwYWNpbmcgYmV0d2VlbiBsaXN0IGl0ZW1zLiBTZWUgdGhlICBjb21wYWN0IGF0dHJpYnV0ZQotICAgICAqIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuIFRoaXMgYXR0cmlidXRlIGlzIGRlcHJlY2F0ZWQgaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0Q29tcGFjdCgpOwotICAgIHB1YmxpYyB2b2lkIHNldENvbXBhY3QoYm9vbGVhbiBjb21wYWN0KTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTERPTUltcGxlbWVudGF0aW9uLmphdmEgYi9zcmMvb3JnL3czYy9kb20vaHRtbC9IVE1MRE9NSW1wbGVtZW50YXRpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNGQxNTU0MS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3czYy9kb20vaHRtbC9IVE1MRE9NSW1wbGVtZW50YXRpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDYzICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBUaGlzIGZpbGUgaXMgYXZhaWxhYmxlIHVuZGVyIGFuZCBnb3Zlcm5lZCBieSB0aGUgR05VIEdlbmVyYWwgUHVibGljCi0gKiBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqIEhvd2V2ZXIsIHRoZSBmb2xsb3dpbmcgbm90aWNlIGFjY29tcGFuaWVkIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIG9mIHRoaXMKLSAqIGZpbGUgYW5kLCBwZXIgaXRzIHRlcm1zLCBzaG91bGQgbm90IGJlIHJlbW92ZWQ6Ci0gKgotICogQ29weXJpZ2h0IChjKSAyMDAwIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKLSAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAotICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCi0gKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQotICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgotICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgotICogUFVSUE9TRS4gU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlCi0gKiBkZXRhaWxzLgotICovCi0KLXBhY2thZ2Ugb3JnLnczYy5kb20uaHRtbDsKLQotaW1wb3J0IG9yZy53M2MuZG9tLkRPTUltcGxlbWVudGF0aW9uOwotCi0vKioKLSAqICBUaGUgPGNvZGU+SFRNTERPTUltcGxlbWVudGF0aW9uPC9jb2RlPiBpbnRlcmZhY2UgZXh0ZW5kcyB0aGUKLSAqIDxjb2RlPkRPTUltcGxlbWVudGF0aW9uPC9jb2RlPiBpbnRlcmZhY2Ugd2l0aCBhIG1ldGhvZCBmb3IgY3JlYXRpbmcgYW4KLSAqIEhUTUwgZG9jdW1lbnQgaW5zdGFuY2UuCi0gKiBAc2luY2UgRE9NIExldmVsIDIKLSAqLwotcHVibGljIGludGVyZmFjZSBIVE1MRE9NSW1wbGVtZW50YXRpb24gZXh0ZW5kcyBET01JbXBsZW1lbnRhdGlvbiB7Ci0gICAgLyoqCi0gICAgICogIENyZWF0ZXMgYW4gPGNvZGU+SFRNTERvY3VtZW50PC9jb2RlPiBvYmplY3Qgd2l0aCB0aGUgbWluaW1hbCB0cmVlIG1hZGUKLSAgICAgKiBvZiB0aGUgZm9sbG93aW5nIGVsZW1lbnRzOiA8Y29kZT5IVE1MPC9jb2RlPiAsIDxjb2RlPkhFQUQ8L2NvZGU+ICwKLSAgICAgKiA8Y29kZT5USVRMRTwvY29kZT4gLCBhbmQgPGNvZGU+Qk9EWTwvY29kZT4gLgotICAgICAqIEBwYXJhbSB0aXRsZSAgVGhlIHRpdGxlIG9mIHRoZSBkb2N1bWVudCB0byBiZSBzZXQgYXMgdGhlIGNvbnRlbnQgb2YgdGhlCi0gICAgICogICA8Y29kZT5USVRMRTwvY29kZT4gZWxlbWVudCwgdGhyb3VnaCBhIGNoaWxkIDxjb2RlPlRleHQ8L2NvZGU+IG5vZGUuCi0gICAgICogQHJldHVybiAgQSBuZXcgPGNvZGU+SFRNTERvY3VtZW50PC9jb2RlPiBvYmplY3QuCi0gICAgICovCi0gICAgcHVibGljIEhUTUxEb2N1bWVudCBjcmVhdGVIVE1MRG9jdW1lbnQoU3RyaW5nIHRpdGxlKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTERpcmVjdG9yeUVsZW1lbnQuamF2YSBiL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxEaXJlY3RvcnlFbGVtZW50LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDBmYjMzOTAuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTERpcmVjdG9yeUVsZW1lbnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDU3ICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBUaGlzIGZpbGUgaXMgYXZhaWxhYmxlIHVuZGVyIGFuZCBnb3Zlcm5lZCBieSB0aGUgR05VIEdlbmVyYWwgUHVibGljCi0gKiBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqIEhvd2V2ZXIsIHRoZSBmb2xsb3dpbmcgbm90aWNlIGFjY29tcGFuaWVkIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIG9mIHRoaXMKLSAqIGZpbGUgYW5kLCBwZXIgaXRzIHRlcm1zLCBzaG91bGQgbm90IGJlIHJlbW92ZWQ6Ci0gKgotICogQ29weXJpZ2h0IChjKSAyMDAwIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKLSAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAotICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCi0gKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQotICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgotICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgotICogUFVSUE9TRS4gU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlCi0gKiBkZXRhaWxzLgotICovCi0KLXBhY2thZ2Ugb3JnLnczYy5kb20uaHRtbDsKLQotLyoqCi0gKiAgRGlyZWN0b3J5IGxpc3QuIFNlZSB0aGUgIERJUiBlbGVtZW50IGRlZmluaXRpb24gaW4gSFRNTCA0LjAuIFRoaXMgZWxlbWVudAotICogaXMgZGVwcmVjYXRlZCBpbiBIVE1MIDQuMC4KLSAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAwL0NSLURPTS1MZXZlbC0yLTIwMDAwNTEwJz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMiBTcGVjaWZpY2F0aW9uPC9hPi4KLSAqLwotcHVibGljIGludGVyZmFjZSBIVE1MRGlyZWN0b3J5RWxlbWVudCBleHRlbmRzIEhUTUxFbGVtZW50IHsKLSAgICAvKioKLSAgICAgKiAgUmVkdWNlIHNwYWNpbmcgYmV0d2VlbiBsaXN0IGl0ZW1zLiBTZWUgdGhlICBjb21wYWN0IGF0dHJpYnV0ZQotICAgICAqIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuIFRoaXMgYXR0cmlidXRlIGlzIGRlcHJlY2F0ZWQgaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0Q29tcGFjdCgpOwotICAgIHB1YmxpYyB2b2lkIHNldENvbXBhY3QoYm9vbGVhbiBjb21wYWN0KTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTERpdkVsZW1lbnQuamF2YSBiL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxEaXZFbGVtZW50LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGVlMWI3MjcuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTERpdkVsZW1lbnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDU2ICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBUaGlzIGZpbGUgaXMgYXZhaWxhYmxlIHVuZGVyIGFuZCBnb3Zlcm5lZCBieSB0aGUgR05VIEdlbmVyYWwgUHVibGljCi0gKiBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqIEhvd2V2ZXIsIHRoZSBmb2xsb3dpbmcgbm90aWNlIGFjY29tcGFuaWVkIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIG9mIHRoaXMKLSAqIGZpbGUgYW5kLCBwZXIgaXRzIHRlcm1zLCBzaG91bGQgbm90IGJlIHJlbW92ZWQ6Ci0gKgotICogQ29weXJpZ2h0IChjKSAyMDAwIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKLSAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAotICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCi0gKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQotICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgotICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgotICogUFVSUE9TRS4gU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlCi0gKiBkZXRhaWxzLgotICovCi0KLXBhY2thZ2Ugb3JnLnczYy5kb20uaHRtbDsKLQotLyoqCi0gKiAgR2VuZXJpYyBibG9jayBjb250YWluZXIuIFNlZSB0aGUgIERJViBlbGVtZW50IGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gKiA8cD5TZWUgYWxzbyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMC9DUi1ET00tTGV2ZWwtMi0yMDAwMDUxMCc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDIgU3BlY2lmaWNhdGlvbjwvYT4uCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgSFRNTERpdkVsZW1lbnQgZXh0ZW5kcyBIVE1MRWxlbWVudCB7Ci0gICAgLyoqCi0gICAgICogIEhvcml6b250YWwgdGV4dCBhbGlnbm1lbnQuIFNlZSB0aGUgIGFsaWduIGF0dHJpYnV0ZSBkZWZpbml0aW9uIGluIEhUTUwKLSAgICAgKiA0LjAuIFRoaXMgYXR0cmlidXRlIGlzIGRlcHJlY2F0ZWQgaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRBbGlnbigpOwotICAgIHB1YmxpYyB2b2lkIHNldEFsaWduKFN0cmluZyBhbGlnbik7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxEb2N1bWVudC5qYXZhIGIvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTERvY3VtZW50LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDUxMTZmYzUuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTERvY3VtZW50LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxODMgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIFRoaXMgZmlsZSBpcyBhdmFpbGFibGUgdW5kZXIgYW5kIGdvdmVybmVkIGJ5IHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKLSAqIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICogSG93ZXZlciwgdGhlIGZvbGxvd2luZyBub3RpY2UgYWNjb21wYW5pZWQgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcwotICogZmlsZSBhbmQsIHBlciBpdHMgdGVybXMsIHNob3VsZCBub3QgYmUgcmVtb3ZlZDoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDAgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKLSAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQotICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCi0gKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKLSAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCi0gKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCi0gKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCi0gKiBQVVJQT1NFLiBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUKLSAqIGRldGFpbHMuCi0gKi8KLQotcGFja2FnZSBvcmcudzNjLmRvbS5odG1sOwotCi1pbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZUxpc3Q7Ci0KLS8qKgotICogIEFuIDxjb2RlPkhUTUxEb2N1bWVudDwvY29kZT4gaXMgdGhlIHJvb3Qgb2YgdGhlIEhUTUwgaGllcmFyY2h5IGFuZCBob2xkcwotICogdGhlIGVudGlyZSBjb250ZW50LiBCZXNpZGVzIHByb3ZpZGluZyBhY2Nlc3MgdG8gdGhlIGhpZXJhcmNoeSwgaXQgYWxzbwotICogcHJvdmlkZXMgc29tZSBjb252ZW5pZW5jZSBtZXRob2RzIGZvciBhY2Nlc3NpbmcgY2VydGFpbiBzZXRzIG9mCi0gKiBpbmZvcm1hdGlvbiBmcm9tIHRoZSBkb2N1bWVudC4KLSAqIDxwPiBUaGUgZm9sbG93aW5nIHByb3BlcnRpZXMgaGF2ZSBiZWVuIGRlcHJlY2F0ZWQgaW4gZmF2b3Igb2YgdGhlCi0gKiBjb3JyZXNwb25kaW5nIG9uZXMgZm9yIHRoZSA8Y29kZT5CT0RZPC9jb2RlPiBlbGVtZW50OiBhbGlua0NvbG9yIGJhY2tncm91bmQKLSAqICBiZ0NvbG9yIGZnQ29sb3IgbGlua0NvbG9yIHZsaW5rQ29sb3IgSW4gRE9NIExldmVsIDIsIHRoZSBtZXRob2QKLSAqIDxjb2RlPmdldEVsZW1lbnRCeUlkPC9jb2RlPiBpcyBpbmhlcml0ZWQgZnJvbSB0aGUgPGNvZGU+RG9jdW1lbnQ8L2NvZGU+Ci0gKiBpbnRlcmZhY2Ugd2hlcmUgaXQgd2FzIG1vdmVkLgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDAvQ1ItRE9NLUxldmVsLTItMjAwMDA1MTAnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAyIFNwZWNpZmljYXRpb248L2E+LgotICovCi1wdWJsaWMgaW50ZXJmYWNlIEhUTUxEb2N1bWVudCBleHRlbmRzIERvY3VtZW50IHsKLSAgICAvKioKLSAgICAgKiAgVGhlIHRpdGxlIG9mIGEgZG9jdW1lbnQgYXMgc3BlY2lmaWVkIGJ5IHRoZSA8Y29kZT5USVRMRTwvY29kZT4gZWxlbWVudAotICAgICAqIGluIHRoZSBoZWFkIG9mIHRoZSBkb2N1bWVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFRpdGxlKCk7Ci0gICAgcHVibGljIHZvaWQgc2V0VGl0bGUoU3RyaW5nIHRpdGxlKTsKLQotICAgIC8qKgotICAgICAqICBSZXR1cm5zIHRoZSBVUkkgIG9mIHRoZSBwYWdlIHRoYXQgbGlua2VkIHRvIHRoaXMgcGFnZS4gVGhlIHZhbHVlIGlzIGFuCi0gICAgICogZW1wdHkgc3RyaW5nIGlmIHRoZSB1c2VyIG5hdmlnYXRlZCB0byB0aGUgcGFnZSBkaXJlY3RseSAobm90IHRocm91Z2ggYQotICAgICAqIGxpbmssIGJ1dCwgZm9yIGV4YW1wbGUsIHZpYSBhIGJvb2ttYXJrKS4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFJlZmVycmVyKCk7Ci0KLSAgICAvKioKLSAgICAgKiAgVGhlIGRvbWFpbiBuYW1lIG9mIHRoZSBzZXJ2ZXIgdGhhdCBzZXJ2ZWQgdGhlIGRvY3VtZW50LCBvcgotICAgICAqIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoZSBzZXJ2ZXIgY2Fubm90IGJlIGlkZW50aWZpZWQgYnkgYSBkb21haW4gbmFtZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldERvbWFpbigpOwotCi0gICAgLyoqCi0gICAgICogIFRoZSBjb21wbGV0ZSBVUkkgIG9mIHRoZSBkb2N1bWVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFVSTCgpOwotCi0gICAgLyoqCi0gICAgICogIFRoZSBlbGVtZW50IHRoYXQgY29udGFpbnMgdGhlIGNvbnRlbnQgZm9yIHRoZSBkb2N1bWVudC4gSW4gZG9jdW1lbnRzCi0gICAgICogd2l0aCA8Y29kZT5CT0RZPC9jb2RlPiBjb250ZW50cywgcmV0dXJucyB0aGUgPGNvZGU+Qk9EWTwvY29kZT4KLSAgICAgKiBlbGVtZW50LiBJbiBmcmFtZXNldCBkb2N1bWVudHMsIHRoaXMgcmV0dXJucyB0aGUgb3V0ZXJtb3N0Ci0gICAgICogPGNvZGU+RlJBTUVTRVQ8L2NvZGU+IGVsZW1lbnQuCi0gICAgICovCi0gICAgcHVibGljIEhUTUxFbGVtZW50IGdldEJvZHkoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRCb2R5KEhUTUxFbGVtZW50IGJvZHkpOwotCi0gICAgLyoqCi0gICAgICogIEEgY29sbGVjdGlvbiBvZiBhbGwgdGhlIDxjb2RlPklNRzwvY29kZT4gZWxlbWVudHMgaW4gYSBkb2N1bWVudC4gVGhlCi0gICAgICogYmVoYXZpb3IgaXMgbGltaXRlZCB0byA8Y29kZT5JTUc8L2NvZGU+IGVsZW1lbnRzIGZvciBiYWNrd2FyZHMKLSAgICAgKiBjb21wYXRpYmlsaXR5LgotICAgICAqLwotICAgIHB1YmxpYyBIVE1MQ29sbGVjdGlvbiBnZXRJbWFnZXMoKTsKLQotICAgIC8qKgotICAgICAqICBBIGNvbGxlY3Rpb24gb2YgYWxsIHRoZSA8Y29kZT5PQkpFQ1Q8L2NvZGU+IGVsZW1lbnRzIHRoYXQgaW5jbHVkZQotICAgICAqIGFwcGxldHMgYW5kIDxjb2RlPkFQUExFVDwvY29kZT4gKCBkZXByZWNhdGVkICkgZWxlbWVudHMgaW4gYSBkb2N1bWVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgSFRNTENvbGxlY3Rpb24gZ2V0QXBwbGV0cygpOwotCi0gICAgLyoqCi0gICAgICogIEEgY29sbGVjdGlvbiBvZiBhbGwgPGNvZGU+QVJFQTwvY29kZT4gZWxlbWVudHMgYW5kIGFuY2hvciAoCi0gICAgICogPGNvZGU+QTwvY29kZT4gKSBlbGVtZW50cyBpbiBhIGRvY3VtZW50IHdpdGggYSB2YWx1ZSBmb3IgdGhlCi0gICAgICogPGNvZGU+aHJlZjwvY29kZT4gYXR0cmlidXRlLgotICAgICAqLwotICAgIHB1YmxpYyBIVE1MQ29sbGVjdGlvbiBnZXRMaW5rcygpOwotCi0gICAgLyoqCi0gICAgICogIEEgY29sbGVjdGlvbiBvZiBhbGwgdGhlIGZvcm1zIG9mIGEgZG9jdW1lbnQuCi0gICAgICovCi0gICAgcHVibGljIEhUTUxDb2xsZWN0aW9uIGdldEZvcm1zKCk7Ci0KLSAgICAvKioKLSAgICAgKiAgQSBjb2xsZWN0aW9uIG9mIGFsbCB0aGUgYW5jaG9yICg8Y29kZT5BPC9jb2RlPiApIGVsZW1lbnRzIGluIGEgZG9jdW1lbnQKLSAgICAgKiAgd2l0aCBhIHZhbHVlIGZvciB0aGUgPGNvZGU+bmFtZTwvY29kZT4gYXR0cmlidXRlLiBOb3RlLiBGb3IgcmVhc29ucwotICAgICAqIG9mIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5LCB0aGUgcmV0dXJuZWQgc2V0IG9mIGFuY2hvcnMgb25seSBjb250YWlucwotICAgICAqIHRob3NlIGFuY2hvcnMgY3JlYXRlZCB3aXRoIHRoZSA8Y29kZT5uYW1lPC9jb2RlPiAgYXR0cmlidXRlLCBub3QgdGhvc2UKLSAgICAgKiBjcmVhdGVkIHdpdGggdGhlIDxjb2RlPmlkPC9jb2RlPiBhdHRyaWJ1dGUuCi0gICAgICovCi0gICAgcHVibGljIEhUTUxDb2xsZWN0aW9uIGdldEFuY2hvcnMoKTsKLQotICAgIC8qKgotICAgICAqICBUaGUgY29va2llcyBhc3NvY2lhdGVkIHdpdGggdGhpcyBkb2N1bWVudC4gSWYgdGhlcmUgYXJlIG5vbmUsIHRoZQotICAgICAqIHZhbHVlIGlzIGFuIGVtcHR5IHN0cmluZy4gT3RoZXJ3aXNlLCB0aGUgdmFsdWUgaXMgYSBzdHJpbmc6IGEKLSAgICAgKiBzZW1pY29sb24tZGVsaW1pdGVkIGxpc3Qgb2YgIm5hbWUsIHZhbHVlIiBwYWlycyBmb3IgYWxsIHRoZSBjb29raWVzCi0gICAgICogYXNzb2NpYXRlZCB3aXRoIHRoZSBwYWdlLiBGb3IgZXhhbXBsZSwKLSAgICAgKiA8Y29kZT5uYW1lPXZhbHVlO2V4cGlyZXM9ZGF0ZTwvY29kZT4gLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q29va2llKCk7Ci0gICAgcHVibGljIHZvaWQgc2V0Q29va2llKFN0cmluZyBjb29raWUpOwotCi0gICAgLyoqCi0gICAgICogIE5vdGUuIFRoaXMgbWV0aG9kIGFuZCB0aGUgb25lcyBmb2xsb3dpbmcgIGFsbG93IGEgdXNlciB0byBhZGQgdG8gb3IKLSAgICAgKiByZXBsYWNlIHRoZSBzdHJ1Y3R1cmUgbW9kZWwgb2YgYSBkb2N1bWVudCB1c2luZyBzdHJpbmdzIG9mIHVucGFyc2VkCi0gICAgICogSFRNTC4gQXQgdGhlIHRpbWUgb2YgIHdyaXRpbmcgYWx0ZXJuYXRlIG1ldGhvZHMgZm9yIHByb3ZpZGluZyBzaW1pbGFyCi0gICAgICogZnVuY3Rpb25hbGl0eSBmb3IgIGJvdGggSFRNTCBhbmQgWE1MIGRvY3VtZW50cyB3ZXJlIGJlaW5nIGNvbnNpZGVyZWQuCi0gICAgICogVGhlIGZvbGxvd2luZyBtZXRob2RzIG1heSBiZSBkZXByZWNhdGVkIGF0IHNvbWUgcG9pbnQgaW4gdGhlIGZ1dHVyZSBpbgotICAgICAqIGZhdm9yIG9mIGEgbW9yZSBnZW5lcmFsLXB1cnBvc2UgbWVjaGFuaXNtLgotICAgICAqIDxicj4gT3BlbiBhIGRvY3VtZW50IHN0cmVhbSBmb3Igd3JpdGluZy4gSWYgYSBkb2N1bWVudCBleGlzdHMgaW4gdGhlCi0gICAgICogdGFyZ2V0LCB0aGlzIG1ldGhvZCBjbGVhcnMgaXQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgb3BlbigpOwotCi0gICAgLyoqCi0gICAgICogIENsb3NlcyBhIGRvY3VtZW50IHN0cmVhbSBvcGVuZWQgYnkgPGNvZGU+b3BlbigpPC9jb2RlPiBhbmQgZm9yY2VzCi0gICAgICogcmVuZGVyaW5nLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGNsb3NlKCk7Ci0KLSAgICAvKioKLSAgICAgKiAgV3JpdGUgYSBzdHJpbmcgb2YgdGV4dCB0byBhIGRvY3VtZW50IHN0cmVhbSBvcGVuZWQgYnkKLSAgICAgKiA8Y29kZT5vcGVuKCk8L2NvZGU+IC4gVGhlIHRleHQgaXMgcGFyc2VkIGludG8gdGhlIGRvY3VtZW50J3Mgc3RydWN0dXJlCi0gICAgICogbW9kZWwuCi0gICAgICogQHBhcmFtIHRleHQgIFRoZSBzdHJpbmcgdG8gYmUgcGFyc2VkIGludG8gc29tZSBzdHJ1Y3R1cmUgaW4gdGhlCi0gICAgICogICBkb2N1bWVudCBzdHJ1Y3R1cmUgbW9kZWwuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgd3JpdGUoU3RyaW5nIHRleHQpOwotCi0gICAgLyoqCi0gICAgICogIFdyaXRlIGEgc3RyaW5nIG9mIHRleHQgZm9sbG93ZWQgYnkgYSBuZXdsaW5lIGNoYXJhY3RlciB0byBhIGRvY3VtZW50Ci0gICAgICogc3RyZWFtIG9wZW5lZCBieSA8Y29kZT5vcGVuKCk8L2NvZGU+IC4gVGhlIHRleHQgaXMgcGFyc2VkIGludG8gdGhlCi0gICAgICogZG9jdW1lbnQncyBzdHJ1Y3R1cmUgbW9kZWwuCi0gICAgICogQHBhcmFtIHRleHQgIFRoZSBzdHJpbmcgdG8gYmUgcGFyc2VkIGludG8gc29tZSBzdHJ1Y3R1cmUgaW4gdGhlCi0gICAgICogICBkb2N1bWVudCBzdHJ1Y3R1cmUgbW9kZWwuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgd3JpdGVsbihTdHJpbmcgdGV4dCk7Ci0KLSAgICAvKioKLSAgICAgKiAgUmV0dXJucyB0aGUgKHBvc3NpYmx5IGVtcHR5KSBjb2xsZWN0aW9uIG9mIGVsZW1lbnRzIHdob3NlCi0gICAgICogPGNvZGU+bmFtZTwvY29kZT4gdmFsdWUgaXMgZ2l2ZW4gYnkgPGNvZGU+ZWxlbWVudE5hbWU8L2NvZGU+IC4KLSAgICAgKiBAcGFyYW0gZWxlbWVudE5hbWUgIFRoZSA8Y29kZT5uYW1lPC9jb2RlPiBhdHRyaWJ1dGUgdmFsdWUgZm9yIGFuCi0gICAgICogICBlbGVtZW50LgotICAgICAqIEByZXR1cm4gIFRoZSBtYXRjaGluZyBlbGVtZW50cy4KLSAgICAgKi8KLSAgICBwdWJsaWMgTm9kZUxpc3QgZ2V0RWxlbWVudHNCeU5hbWUoU3RyaW5nIGVsZW1lbnROYW1lKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTEVsZW1lbnQuamF2YSBiL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxFbGVtZW50LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGI1YjE3OGEuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTEVsZW1lbnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDk0ICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBUaGlzIGZpbGUgaXMgYXZhaWxhYmxlIHVuZGVyIGFuZCBnb3Zlcm5lZCBieSB0aGUgR05VIEdlbmVyYWwgUHVibGljCi0gKiBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqIEhvd2V2ZXIsIHRoZSBmb2xsb3dpbmcgbm90aWNlIGFjY29tcGFuaWVkIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIG9mIHRoaXMKLSAqIGZpbGUgYW5kLCBwZXIgaXRzIHRlcm1zLCBzaG91bGQgbm90IGJlIHJlbW92ZWQ6Ci0gKgotICogQ29weXJpZ2h0IChjKSAyMDAwIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKLSAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAotICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCi0gKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQotICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgotICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgotICogUFVSUE9TRS4gU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlCi0gKiBkZXRhaWxzLgotICovCi0KLXBhY2thZ2Ugb3JnLnczYy5kb20uaHRtbDsKLQotaW1wb3J0IG9yZy53M2MuZG9tLkVsZW1lbnQ7Ci0KLS8qKgotICogIEFsbCBIVE1MIGVsZW1lbnQgaW50ZXJmYWNlcyBkZXJpdmUgZnJvbSB0aGlzIGNsYXNzLiBFbGVtZW50cyB0aGF0IG9ubHkKLSAqIGV4cG9zZSB0aGUgSFRNTCBjb3JlIGF0dHJpYnV0ZXMgYXJlIHJlcHJlc2VudGVkIGJ5IHRoZSBiYXNlCi0gKiA8Y29kZT5IVE1MRWxlbWVudDwvY29kZT4gaW50ZXJmYWNlLiBUaGVzZSBlbGVtZW50cyBhcmUgYXMgZm9sbG93czogIEhFQUQKLSAqIHNwZWNpYWw6IFNVQiwgU1VQLCBTUEFOLCBCRE8gZm9udDogVFQsIEksIEIsIFUsIFMsIFNUUklLRSwgQklHLCBTTUFMTAotICogcGhyYXNlOiBFTSwgU1RST05HLCBERk4sIENPREUsIFNBTVAsIEtCRCwgVkFSLCBDSVRFLCBBQ1JPTllNLCBBQkJSIGxpc3Q6Ci0gKiBERCwgRFQgTk9GUkFNRVMsIE5PU0NSSVBUIEFERFJFU1MsIENFTlRFUiBUaGUgPGNvZGU+c3R5bGU8L2NvZGU+IGF0dHJpYnV0ZQotICogb2YgYW4gSFRNTCBlbGVtZW50IGlzIGFjY2Vzc2libGUgdGhyb3VnaCB0aGUKLSAqIDxjb2RlPkVsZW1lbnRDU1NJbmxpbmVTdHlsZTwvY29kZT4gaW50ZXJmYWNlIHdoaWNoIGlzIGRlZmluZWQgaW4gdGhlICAuCi0gKiA8cD5TZWUgYWxzbyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMC9DUi1ET00tTGV2ZWwtMi0yMDAwMDUxMCc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDIgU3BlY2lmaWNhdGlvbjwvYT4uCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgSFRNTEVsZW1lbnQgZXh0ZW5kcyBFbGVtZW50IHsKLSAgICAvKioKLSAgICAgKiAgVGhlIGVsZW1lbnQncyBpZGVudGlmaWVyLiBTZWUgdGhlICBpZCBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldElkKCk7Ci0gICAgcHVibGljIHZvaWQgc2V0SWQoU3RyaW5nIGlkKTsKLQotICAgIC8qKgotICAgICAqICBUaGUgZWxlbWVudCdzIGFkdmlzb3J5IHRpdGxlLiBTZWUgdGhlICB0aXRsZSBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbgotICAgICAqIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VGl0bGUoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRUaXRsZShTdHJpbmcgdGl0bGUpOwotCi0gICAgLyoqCi0gICAgICogIExhbmd1YWdlIGNvZGUgZGVmaW5lZCBpbiBSRkMgMTc2Ni4gU2VlIHRoZSAgbGFuZyBhdHRyaWJ1dGUgZGVmaW5pdGlvbgotICAgICAqIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TGFuZygpOwotICAgIHB1YmxpYyB2b2lkIHNldExhbmcoU3RyaW5nIGxhbmcpOwotCi0gICAgLyoqCi0gICAgICogIFNwZWNpZmllcyB0aGUgYmFzZSBkaXJlY3Rpb24gb2YgZGlyZWN0aW9uYWxseSBuZXV0cmFsIHRleHQgYW5kIHRoZQotICAgICAqIGRpcmVjdGlvbmFsaXR5IG9mIHRhYmxlcy4gU2VlIHRoZSAgZGlyIGF0dHJpYnV0ZSBkZWZpbml0aW9uIGluIEhUTUwKLSAgICAgKiA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXREaXIoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXREaXIoU3RyaW5nIGRpcik7Ci0KLSAgICAvKioKLSAgICAgKiAgVGhlIGNsYXNzIGF0dHJpYnV0ZSBvZiB0aGUgZWxlbWVudC4gVGhpcyBhdHRyaWJ1dGUgaGFzIGJlZW4gcmVuYW1lZAotICAgICAqIGR1ZSB0byBjb25mbGljdHMgd2l0aCB0aGUgImNsYXNzIiBrZXl3b3JkIGV4cG9zZWQgYnkgbWFueSBsYW5ndWFnZXMuCi0gICAgICogU2VlIHRoZSAgY2xhc3MgYXR0cmlidXRlIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRDbGFzc05hbWUoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRDbGFzc05hbWUoU3RyaW5nIGNsYXNzTmFtZSk7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxGaWVsZFNldEVsZW1lbnQuamF2YSBiL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxGaWVsZFNldEVsZW1lbnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggY2IyYzBiZC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3czYy9kb20vaHRtbC9IVE1MRmllbGRTZXRFbGVtZW50LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw1NiArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogVGhpcyBmaWxlIGlzIGF2YWlsYWJsZSB1bmRlciBhbmQgZ292ZXJuZWQgYnkgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwotICogTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKiBIb3dldmVyLCB0aGUgZm9sbG93aW5nIG5vdGljZSBhY2NvbXBhbmllZCB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGlzCi0gKiBmaWxlIGFuZCwgcGVyIGl0cyB0ZXJtcywgc2hvdWxkIG5vdCBiZSByZW1vdmVkOgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAotICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCi0gKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKLSAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQotICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKLSAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KLSAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKLSAqIFBVUlBPU0UuIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZQotICogZGV0YWlscy4KLSAqLwotCi1wYWNrYWdlIG9yZy53M2MuZG9tLmh0bWw7Ci0KLS8qKgotICogIE9yZ2FuaXplcyBmb3JtIGNvbnRyb2xzIGludG8gbG9naWNhbCBncm91cHMuIFNlZSB0aGUgICBGSUVMRFNFVCAgZWxlbWVudAotICogZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAwL0NSLURPTS1MZXZlbC0yLTIwMDAwNTEwJz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMiBTcGVjaWZpY2F0aW9uPC9hPi4KLSAqLwotcHVibGljIGludGVyZmFjZSBIVE1MRmllbGRTZXRFbGVtZW50IGV4dGVuZHMgSFRNTEVsZW1lbnQgewotICAgIC8qKgotICAgICAqICBSZXR1cm5zIHRoZSA8Y29kZT5GT1JNPC9jb2RlPiBlbGVtZW50IGNvbnRhaW5pbmcgdGhpcyBjb250cm9sLiBSZXR1cm5zCi0gICAgICogPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhpcyBjb250cm9sIGlzIG5vdCB3aXRoaW4gdGhlIGNvbnRleHQgb2YgYSBmb3JtLgotICAgICAqLwotICAgIHB1YmxpYyBIVE1MRm9ybUVsZW1lbnQgZ2V0Rm9ybSgpOwotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL3czYy9kb20vaHRtbC9IVE1MRm9udEVsZW1lbnQuamF2YSBiL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxGb250RWxlbWVudC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjOGZjMTU3Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxGb250RWxlbWVudC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNzEgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIFRoaXMgZmlsZSBpcyBhdmFpbGFibGUgdW5kZXIgYW5kIGdvdmVybmVkIGJ5IHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKLSAqIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICogSG93ZXZlciwgdGhlIGZvbGxvd2luZyBub3RpY2UgYWNjb21wYW5pZWQgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcwotICogZmlsZSBhbmQsIHBlciBpdHMgdGVybXMsIHNob3VsZCBub3QgYmUgcmVtb3ZlZDoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDAgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKLSAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQotICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCi0gKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKLSAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCi0gKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCi0gKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCi0gKiBQVVJQT1NFLiBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUKLSAqIGRldGFpbHMuCi0gKi8KLQotcGFja2FnZSBvcmcudzNjLmRvbS5odG1sOwotCi0vKioKLSAqICBMb2NhbCBjaGFuZ2UgdG8gZm9udC4gU2VlIHRoZSAgRk9OVCBlbGVtZW50IGRlZmluaXRpb24gaW4gSFRNTCA0LjAuIFRoaXMKLSAqIGVsZW1lbnQgaXMgZGVwcmVjYXRlZCBpbiBIVE1MIDQuMC4KLSAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAwL0NSLURPTS1MZXZlbC0yLTIwMDAwNTEwJz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMiBTcGVjaWZpY2F0aW9uPC9hPi4KLSAqLwotcHVibGljIGludGVyZmFjZSBIVE1MRm9udEVsZW1lbnQgZXh0ZW5kcyBIVE1MRWxlbWVudCB7Ci0gICAgLyoqCi0gICAgICogIEZvbnQgY29sb3IuIFNlZSB0aGUgIGNvbG9yIGF0dHJpYnV0ZSBkZWZpbml0aW9uIGluIEhUTUwgNC4wLiBUaGlzCi0gICAgICogYXR0cmlidXRlIGlzIGRlcHJlY2F0ZWQgaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRDb2xvcigpOwotICAgIHB1YmxpYyB2b2lkIHNldENvbG9yKFN0cmluZyBjb2xvcik7Ci0KLSAgICAvKioKLSAgICAgKiAgRm9udCBmYWNlIGlkZW50aWZpZXIuIFNlZSB0aGUgIGZhY2UgYXR0cmlidXRlIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gICAgICogVGhpcyBhdHRyaWJ1dGUgaXMgZGVwcmVjYXRlZCBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEZhY2UoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRGYWNlKFN0cmluZyBmYWNlKTsKLQotICAgIC8qKgotICAgICAqICBGb250IHNpemUuIFNlZSB0aGUgIHNpemUgYXR0cmlidXRlIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuIFRoaXMKLSAgICAgKiBhdHRyaWJ1dGUgaXMgZGVwcmVjYXRlZCBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFNpemUoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRTaXplKFN0cmluZyBzaXplKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTEZvcm1FbGVtZW50LmphdmEgYi9zcmMvb3JnL3czYy9kb20vaHRtbC9IVE1MRm9ybUVsZW1lbnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNDJlMmVkZC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3czYy9kb20vaHRtbC9IVE1MRm9ybUVsZW1lbnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExNSArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogVGhpcyBmaWxlIGlzIGF2YWlsYWJsZSB1bmRlciBhbmQgZ292ZXJuZWQgYnkgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwotICogTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKiBIb3dldmVyLCB0aGUgZm9sbG93aW5nIG5vdGljZSBhY2NvbXBhbmllZCB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGlzCi0gKiBmaWxlIGFuZCwgcGVyIGl0cyB0ZXJtcywgc2hvdWxkIG5vdCBiZSByZW1vdmVkOgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAotICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCi0gKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKLSAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQotICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKLSAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KLSAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKLSAqIFBVUlBPU0UuIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZQotICogZGV0YWlscy4KLSAqLwotCi1wYWNrYWdlIG9yZy53M2MuZG9tLmh0bWw7Ci0KLS8qKgotICogIFRoZSA8Y29kZT5GT1JNPC9jb2RlPiBlbGVtZW50IGVuY29tcGFzc2VzIGJlaGF2aW9yIHNpbWlsYXIgdG8gYSBjb2xsZWN0aW9uCi0gKiBhbmQgYW4gZWxlbWVudC4gSXQgcHJvdmlkZXMgZGlyZWN0IGFjY2VzcyB0byB0aGUgY29udGFpbmVkIGlucHV0IGVsZW1lbnRzCi0gKiBhcyB3ZWxsIGFzIHRoZSBhdHRyaWJ1dGVzIG9mIHRoZSBmb3JtIGVsZW1lbnQuIFNlZSB0aGUgIEZPUk0gZWxlbWVudAotICogZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAwL0NSLURPTS1MZXZlbC0yLTIwMDAwNTEwJz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMiBTcGVjaWZpY2F0aW9uPC9hPi4KLSAqLwotcHVibGljIGludGVyZmFjZSBIVE1MRm9ybUVsZW1lbnQgZXh0ZW5kcyBIVE1MRWxlbWVudCB7Ci0gICAgLyoqCi0gICAgICogIFJldHVybnMgYSBjb2xsZWN0aW9uIG9mIGFsbCBjb250cm9sIGVsZW1lbnRzIGluIHRoZSBmb3JtLgotICAgICAqLwotICAgIHB1YmxpYyBIVE1MQ29sbGVjdGlvbiBnZXRFbGVtZW50cygpOwotCi0gICAgLyoqCi0gICAgICogIFRoZSBudW1iZXIgb2YgZm9ybSBjb250cm9scyBpbiB0aGUgZm9ybS4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldExlbmd0aCgpOwotCi0gICAgLyoqCi0gICAgICogIE5hbWVzIHRoZSBmb3JtLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpOwotICAgIHB1YmxpYyB2b2lkIHNldE5hbWUoU3RyaW5nIG5hbWUpOwotCi0gICAgLyoqCi0gICAgICogIExpc3Qgb2YgY2hhcmFjdGVyIHNldHMgc3VwcG9ydGVkIGJ5IHRoZSBzZXJ2ZXIuIFNlZSB0aGUKLSAgICAgKiBhY2NlcHQtY2hhcnNldCBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEFjY2VwdENoYXJzZXQoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRBY2NlcHRDaGFyc2V0KFN0cmluZyBhY2NlcHRDaGFyc2V0KTsKLQotICAgIC8qKgotICAgICAqICBTZXJ2ZXItc2lkZSBmb3JtIGhhbmRsZXIuIFNlZSB0aGUgIGFjdGlvbiBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MCi0gICAgICogNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0QWN0aW9uKCk7Ci0gICAgcHVibGljIHZvaWQgc2V0QWN0aW9uKFN0cmluZyBhY3Rpb24pOwotCi0gICAgLyoqCi0gICAgICogIFRoZSBjb250ZW50IHR5cGUgb2YgdGhlIHN1Ym1pdHRlZCBmb3JtLCAgZ2VuZXJhbGx5Ci0gICAgICogImFwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCIuICBTZWUgdGhlICBlbmN0eXBlIGF0dHJpYnV0ZQotICAgICAqIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRFbmN0eXBlKCk7Ci0gICAgcHVibGljIHZvaWQgc2V0RW5jdHlwZShTdHJpbmcgZW5jdHlwZSk7Ci0KLSAgICAvKioKLSAgICAgKiAgSFRUUCBtZXRob2QgdXNlZCB0byBzdWJtaXQgZm9ybS4gU2VlIHRoZSAgbWV0aG9kIGF0dHJpYnV0ZSBkZWZpbml0aW9uCi0gICAgICogaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRNZXRob2QoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRNZXRob2QoU3RyaW5nIG1ldGhvZCk7Ci0KLSAgICAvKioKLSAgICAgKiAgRnJhbWUgdG8gcmVuZGVyIHRoZSByZXNvdXJjZSBpbi4gU2VlIHRoZSAgdGFyZ2V0IGF0dHJpYnV0ZSBkZWZpbml0aW9uCi0gICAgICogaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXQoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRUYXJnZXQoU3RyaW5nIHRhcmdldCk7Ci0KLSAgICAvKioKLSAgICAgKiAgU3VibWl0cyB0aGUgZm9ybS4gSXQgcGVyZm9ybXMgdGhlIHNhbWUgYWN0aW9uIGFzIGEgIHN1Ym1pdCBidXR0b24uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3VibWl0KCk7Ci0KLSAgICAvKioKLSAgICAgKiAgUmVzdG9yZXMgYSBmb3JtIGVsZW1lbnQncyBkZWZhdWx0IHZhbHVlcy4gSXQgcGVyZm9ybXMgIHRoZSBzYW1lIGFjdGlvbgotICAgICAqIGFzIGEgcmVzZXQgYnV0dG9uLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHJlc2V0KCk7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxGcmFtZUVsZW1lbnQuamF2YSBiL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxGcmFtZUVsZW1lbnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNWZmYTQyNS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3czYy9kb20vaHRtbC9IVE1MRnJhbWVFbGVtZW50LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMTQgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIFRoaXMgZmlsZSBpcyBhdmFpbGFibGUgdW5kZXIgYW5kIGdvdmVybmVkIGJ5IHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKLSAqIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICogSG93ZXZlciwgdGhlIGZvbGxvd2luZyBub3RpY2UgYWNjb21wYW5pZWQgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcwotICogZmlsZSBhbmQsIHBlciBpdHMgdGVybXMsIHNob3VsZCBub3QgYmUgcmVtb3ZlZDoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDAgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKLSAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQotICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCi0gKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKLSAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCi0gKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCi0gKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCi0gKiBQVVJQT1NFLiBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUKLSAqIGRldGFpbHMuCi0gKi8KLQotcGFja2FnZSBvcmcudzNjLmRvbS5odG1sOwotCi1pbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7Ci0KLS8qKgotICogIENyZWF0ZSBhIGZyYW1lLiBTZWUgdGhlICBGUkFNRSBlbGVtZW50IGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gKiA8cD5TZWUgYWxzbyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMC9DUi1ET00tTGV2ZWwtMi0yMDAwMDUxMCc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDIgU3BlY2lmaWNhdGlvbjwvYT4uCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgSFRNTEZyYW1lRWxlbWVudCBleHRlbmRzIEhUTUxFbGVtZW50IHsKLSAgICAvKioKLSAgICAgKiAgUmVxdWVzdCBmcmFtZSBib3JkZXJzLiBTZWUgdGhlICBmcmFtZWJvcmRlciBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbgotICAgICAqIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0RnJhbWVCb3JkZXIoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRGcmFtZUJvcmRlcihTdHJpbmcgZnJhbWVCb3JkZXIpOwotCi0gICAgLyoqCi0gICAgICogIFVSSSBkZXNpZ25hdGluZyBhIGxvbmcgZGVzY3JpcHRpb24gb2YgdGhpcyBpbWFnZSBvciBmcmFtZS4gU2VlIHRoZQotICAgICAqIGxvbmdkZXNjIGF0dHJpYnV0ZSBkZWZpbml0aW9uIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TG9uZ0Rlc2MoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRMb25nRGVzYyhTdHJpbmcgbG9uZ0Rlc2MpOwotCi0gICAgLyoqCi0gICAgICogIEZyYW1lIG1hcmdpbiBoZWlnaHQsIGluIHBpeGVscy4gU2VlIHRoZSAgbWFyZ2luaGVpZ2h0IGF0dHJpYnV0ZQotICAgICAqIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRNYXJnaW5IZWlnaHQoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRNYXJnaW5IZWlnaHQoU3RyaW5nIG1hcmdpbkhlaWdodCk7Ci0KLSAgICAvKioKLSAgICAgKiAgRnJhbWUgbWFyZ2luIHdpZHRoLCBpbiBwaXhlbHMuIFNlZSB0aGUgIG1hcmdpbndpZHRoIGF0dHJpYnV0ZQotICAgICAqIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRNYXJnaW5XaWR0aCgpOwotICAgIHB1YmxpYyB2b2lkIHNldE1hcmdpbldpZHRoKFN0cmluZyBtYXJnaW5XaWR0aCk7Ci0KLSAgICAvKioKLSAgICAgKiAgVGhlIGZyYW1lIG5hbWUgKG9iamVjdCBvZiB0aGUgPGNvZGU+dGFyZ2V0PC9jb2RlPiBhdHRyaWJ1dGUpLiBTZWUgdGhlCi0gICAgICogbmFtZSBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXROYW1lKFN0cmluZyBuYW1lKTsKLQotICAgIC8qKgotICAgICAqICBXaGVuIHRydWUsIGZvcmJpZCB1c2VyIGZyb20gcmVzaXppbmcgZnJhbWUuIFNlZSB0aGUgIG5vcmVzaXplCi0gICAgICogYXR0cmlidXRlIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0Tm9SZXNpemUoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXROb1Jlc2l6ZShib29sZWFuIG5vUmVzaXplKTsKLQotICAgIC8qKgotICAgICAqICBTcGVjaWZ5IHdoZXRoZXIgb3Igbm90IHRoZSBmcmFtZSBzaG91bGQgaGF2ZSBzY3JvbGxiYXJzLiBTZWUgdGhlCi0gICAgICogc2Nyb2xsaW5nIGF0dHJpYnV0ZSBkZWZpbml0aW9uIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0U2Nyb2xsaW5nKCk7Ci0gICAgcHVibGljIHZvaWQgc2V0U2Nyb2xsaW5nKFN0cmluZyBzY3JvbGxpbmcpOwotCi0gICAgLyoqCi0gICAgICogIEEgVVJJIGRlc2lnbmF0aW5nIHRoZSBpbml0aWFsIGZyYW1lIGNvbnRlbnRzLiBTZWUgdGhlICBzcmMgYXR0cmlidXRlCi0gICAgICogZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFNyYygpOwotICAgIHB1YmxpYyB2b2lkIHNldFNyYyhTdHJpbmcgc3JjKTsKLQotICAgIC8qKgotICAgICAqICBUaGUgZG9jdW1lbnQgdGhpcyBmcmFtZSBjb250YWlucywgaWYgdGhlcmUgaXMgYW55IGFuZCBpdCBpcyBhdmFpbGFibGUsCi0gICAgICogb3IgPGNvZGU+bnVsbDwvY29kZT4gb3RoZXJ3aXNlLgotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMgotICAgICAqLwotICAgIHB1YmxpYyBEb2N1bWVudCBnZXRDb250ZW50RG9jdW1lbnQoKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTEZyYW1lU2V0RWxlbWVudC5qYXZhIGIvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTEZyYW1lU2V0RWxlbWVudC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmYjZmN2U5Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxGcmFtZVNldEVsZW1lbnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDYzICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBUaGlzIGZpbGUgaXMgYXZhaWxhYmxlIHVuZGVyIGFuZCBnb3Zlcm5lZCBieSB0aGUgR05VIEdlbmVyYWwgUHVibGljCi0gKiBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqIEhvd2V2ZXIsIHRoZSBmb2xsb3dpbmcgbm90aWNlIGFjY29tcGFuaWVkIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIG9mIHRoaXMKLSAqIGZpbGUgYW5kLCBwZXIgaXRzIHRlcm1zLCBzaG91bGQgbm90IGJlIHJlbW92ZWQ6Ci0gKgotICogQ29weXJpZ2h0IChjKSAyMDAwIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKLSAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAotICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCi0gKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQotICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgotICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgotICogUFVSUE9TRS4gU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlCi0gKiBkZXRhaWxzLgotICovCi0KLXBhY2thZ2Ugb3JnLnczYy5kb20uaHRtbDsKLQotLyoqCi0gKiAgQ3JlYXRlIGEgZ3JpZCBvZiBmcmFtZXMuIFNlZSB0aGUgIEZSQU1FU0VUIGVsZW1lbnQgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAwL0NSLURPTS1MZXZlbC0yLTIwMDAwNTEwJz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMiBTcGVjaWZpY2F0aW9uPC9hPi4KLSAqLwotcHVibGljIGludGVyZmFjZSBIVE1MRnJhbWVTZXRFbGVtZW50IGV4dGVuZHMgSFRNTEVsZW1lbnQgewotICAgIC8qKgotICAgICAqICBUaGUgbnVtYmVyIG9mIGNvbHVtbnMgb2YgZnJhbWVzIGluIHRoZSBmcmFtZXNldC4gU2VlIHRoZSAgY29scwotICAgICAqIGF0dHJpYnV0ZSBkZWZpbml0aW9uIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q29scygpOwotICAgIHB1YmxpYyB2b2lkIHNldENvbHMoU3RyaW5nIGNvbHMpOwotCi0gICAgLyoqCi0gICAgICogIFRoZSBudW1iZXIgb2Ygcm93cyBvZiBmcmFtZXMgaW4gdGhlIGZyYW1lc2V0LiBTZWUgdGhlICByb3dzIGF0dHJpYnV0ZQotICAgICAqIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRSb3dzKCk7Ci0gICAgcHVibGljIHZvaWQgc2V0Um93cyhTdHJpbmcgcm93cyk7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxIUkVsZW1lbnQuamF2YSBiL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxIUkVsZW1lbnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMzM0YzA0ZC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3czYy9kb20vaHRtbC9IVE1MSFJFbGVtZW50LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3OCArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogVGhpcyBmaWxlIGlzIGF2YWlsYWJsZSB1bmRlciBhbmQgZ292ZXJuZWQgYnkgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwotICogTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKiBIb3dldmVyLCB0aGUgZm9sbG93aW5nIG5vdGljZSBhY2NvbXBhbmllZCB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGlzCi0gKiBmaWxlIGFuZCwgcGVyIGl0cyB0ZXJtcywgc2hvdWxkIG5vdCBiZSByZW1vdmVkOgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAotICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCi0gKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKLSAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQotICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKLSAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KLSAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKLSAqIFBVUlBPU0UuIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZQotICogZGV0YWlscy4KLSAqLwotCi1wYWNrYWdlIG9yZy53M2MuZG9tLmh0bWw7Ci0KLS8qKgotICogIENyZWF0ZSBhIGhvcml6b250YWwgcnVsZS4gU2VlIHRoZSAgSFIgZWxlbWVudCBkZWZpbml0aW9uIGluIEhUTUwgNC4wLgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDAvQ1ItRE9NLUxldmVsLTItMjAwMDA1MTAnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAyIFNwZWNpZmljYXRpb248L2E+LgotICovCi1wdWJsaWMgaW50ZXJmYWNlIEhUTUxIUkVsZW1lbnQgZXh0ZW5kcyBIVE1MRWxlbWVudCB7Ci0gICAgLyoqCi0gICAgICogIEFsaWduIHRoZSBydWxlIG9uIHRoZSBwYWdlLiBTZWUgdGhlICBhbGlnbiBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbgotICAgICAqIEhUTUwgNC4wLiBUaGlzIGF0dHJpYnV0ZSBpcyBkZXByZWNhdGVkIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0QWxpZ24oKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRBbGlnbihTdHJpbmcgYWxpZ24pOwotCi0gICAgLyoqCi0gICAgICogIEluZGljYXRlcyB0byB0aGUgdXNlciBhZ2VudCB0aGF0IHRoZXJlIHNob3VsZCBiZSBubyBzaGFkaW5nIGluIHRoZQotICAgICAqIHJlbmRlcmluZyBvZiB0aGlzIGVsZW1lbnQuIFNlZSB0aGUgIG5vc2hhZGUgYXR0cmlidXRlIGRlZmluaXRpb24gaW4KLSAgICAgKiBIVE1MIDQuMC4gVGhpcyBhdHRyaWJ1dGUgaXMgZGVwcmVjYXRlZCBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXROb1NoYWRlKCk7Ci0gICAgcHVibGljIHZvaWQgc2V0Tm9TaGFkZShib29sZWFuIG5vU2hhZGUpOwotCi0gICAgLyoqCi0gICAgICogIFRoZSBoZWlnaHQgb2YgdGhlIHJ1bGUuIFNlZSB0aGUgIHNpemUgYXR0cmlidXRlIGRlZmluaXRpb24gaW4gSFRNTAotICAgICAqIDQuMC4gVGhpcyBhdHRyaWJ1dGUgaXMgZGVwcmVjYXRlZCBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFNpemUoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRTaXplKFN0cmluZyBzaXplKTsKLQotICAgIC8qKgotICAgICAqICBUaGUgd2lkdGggb2YgdGhlIHJ1bGUuIFNlZSB0aGUgIHdpZHRoIGF0dHJpYnV0ZSBkZWZpbml0aW9uIGluIEhUTUwKLSAgICAgKiA0LjAuIFRoaXMgYXR0cmlidXRlIGlzIGRlcHJlY2F0ZWQgaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRXaWR0aCgpOwotICAgIHB1YmxpYyB2b2lkIHNldFdpZHRoKFN0cmluZyB3aWR0aCk7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxIZWFkRWxlbWVudC5qYXZhIGIvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTEhlYWRFbGVtZW50LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDg4OTRkMzIuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTEhlYWRFbGVtZW50LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw1NiArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogVGhpcyBmaWxlIGlzIGF2YWlsYWJsZSB1bmRlciBhbmQgZ292ZXJuZWQgYnkgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwotICogTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKiBIb3dldmVyLCB0aGUgZm9sbG93aW5nIG5vdGljZSBhY2NvbXBhbmllZCB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGlzCi0gKiBmaWxlIGFuZCwgcGVyIGl0cyB0ZXJtcywgc2hvdWxkIG5vdCBiZSByZW1vdmVkOgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAotICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCi0gKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKLSAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQotICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKLSAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KLSAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKLSAqIFBVUlBPU0UuIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZQotICogZGV0YWlscy4KLSAqLwotCi1wYWNrYWdlIG9yZy53M2MuZG9tLmh0bWw7Ci0KLS8qKgotICogIERvY3VtZW50IGhlYWQgaW5mb3JtYXRpb24uIFNlZSB0aGUgIEhFQUQgZWxlbWVudCBkZWZpbml0aW9uIGluIEhUTUwgNC4wLgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDAvQ1ItRE9NLUxldmVsLTItMjAwMDA1MTAnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAyIFNwZWNpZmljYXRpb248L2E+LgotICovCi1wdWJsaWMgaW50ZXJmYWNlIEhUTUxIZWFkRWxlbWVudCBleHRlbmRzIEhUTUxFbGVtZW50IHsKLSAgICAvKioKLSAgICAgKiAgVVJJIGRlc2lnbmF0aW5nIGEgbWV0YWRhdGEgcHJvZmlsZS4gU2VlIHRoZSAgcHJvZmlsZSBhdHRyaWJ1dGUKLSAgICAgKiBkZWZpbml0aW9uIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0UHJvZmlsZSgpOwotICAgIHB1YmxpYyB2b2lkIHNldFByb2ZpbGUoU3RyaW5nIHByb2ZpbGUpOwotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL3czYy9kb20vaHRtbC9IVE1MSGVhZGluZ0VsZW1lbnQuamF2YSBiL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxIZWFkaW5nRWxlbWVudC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwY2Q0ZWZlLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxIZWFkaW5nRWxlbWVudC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTcgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIFRoaXMgZmlsZSBpcyBhdmFpbGFibGUgdW5kZXIgYW5kIGdvdmVybmVkIGJ5IHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKLSAqIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICogSG93ZXZlciwgdGhlIGZvbGxvd2luZyBub3RpY2UgYWNjb21wYW5pZWQgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcwotICogZmlsZSBhbmQsIHBlciBpdHMgdGVybXMsIHNob3VsZCBub3QgYmUgcmVtb3ZlZDoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDAgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKLSAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQotICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCi0gKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKLSAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCi0gKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCi0gKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCi0gKiBQVVJQT1NFLiBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUKLSAqIGRldGFpbHMuCi0gKi8KLQotcGFja2FnZSBvcmcudzNjLmRvbS5odG1sOwotCi0vKioKLSAqICBGb3IgdGhlIDxjb2RlPkgxPC9jb2RlPiB0byA8Y29kZT5INjwvY29kZT4gZWxlbWVudHMuIFNlZSB0aGUgIEgxIGVsZW1lbnQKLSAqIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gKiA8cD5TZWUgYWxzbyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMC9DUi1ET00tTGV2ZWwtMi0yMDAwMDUxMCc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDIgU3BlY2lmaWNhdGlvbjwvYT4uCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgSFRNTEhlYWRpbmdFbGVtZW50IGV4dGVuZHMgSFRNTEVsZW1lbnQgewotICAgIC8qKgotICAgICAqICBIb3Jpem9udGFsIHRleHQgYWxpZ25tZW50LiBTZWUgdGhlICBhbGlnbiBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MCi0gICAgICogNC4wLiBUaGlzIGF0dHJpYnV0ZSBpcyBkZXByZWNhdGVkIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0QWxpZ24oKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRBbGlnbihTdHJpbmcgYWxpZ24pOwotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL3czYy9kb20vaHRtbC9IVE1MSHRtbEVsZW1lbnQuamF2YSBiL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxIdG1sRWxlbWVudC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhMmZhMzc5Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxIdG1sRWxlbWVudC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTcgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIFRoaXMgZmlsZSBpcyBhdmFpbGFibGUgdW5kZXIgYW5kIGdvdmVybmVkIGJ5IHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKLSAqIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICogSG93ZXZlciwgdGhlIGZvbGxvd2luZyBub3RpY2UgYWNjb21wYW5pZWQgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcwotICogZmlsZSBhbmQsIHBlciBpdHMgdGVybXMsIHNob3VsZCBub3QgYmUgcmVtb3ZlZDoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDAgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKLSAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQotICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCi0gKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKLSAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCi0gKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCi0gKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCi0gKiBQVVJQT1NFLiBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUKLSAqIGRldGFpbHMuCi0gKi8KLQotcGFja2FnZSBvcmcudzNjLmRvbS5odG1sOwotCi0vKioKLSAqICBSb290IG9mIGFuIEhUTUwgZG9jdW1lbnQuIFNlZSB0aGUgIEhUTUwgZWxlbWVudCBkZWZpbml0aW9uIGluIEhUTUwgNC4wLgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDAvQ1ItRE9NLUxldmVsLTItMjAwMDA1MTAnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAyIFNwZWNpZmljYXRpb248L2E+LgotICovCi1wdWJsaWMgaW50ZXJmYWNlIEhUTUxIdG1sRWxlbWVudCBleHRlbmRzIEhUTUxFbGVtZW50IHsKLSAgICAvKioKLSAgICAgKiAgVmVyc2lvbiBpbmZvcm1hdGlvbiBhYm91dCB0aGUgZG9jdW1lbnQncyBEVEQuIFNlZSB0aGUgIHZlcnNpb24KLSAgICAgKiBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4gVGhpcyBhdHRyaWJ1dGUgaXMgZGVwcmVjYXRlZCBpbiBIVE1MCi0gICAgICogNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VmVyc2lvbigpOwotICAgIHB1YmxpYyB2b2lkIHNldFZlcnNpb24oU3RyaW5nIHZlcnNpb24pOwotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL3czYy9kb20vaHRtbC9IVE1MSUZyYW1lRWxlbWVudC5qYXZhIGIvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTElGcmFtZUVsZW1lbnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDhjMTk4OC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3czYy9kb20vaHRtbC9IVE1MSUZyYW1lRWxlbWVudC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTI3ICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBUaGlzIGZpbGUgaXMgYXZhaWxhYmxlIHVuZGVyIGFuZCBnb3Zlcm5lZCBieSB0aGUgR05VIEdlbmVyYWwgUHVibGljCi0gKiBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqIEhvd2V2ZXIsIHRoZSBmb2xsb3dpbmcgbm90aWNlIGFjY29tcGFuaWVkIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIG9mIHRoaXMKLSAqIGZpbGUgYW5kLCBwZXIgaXRzIHRlcm1zLCBzaG91bGQgbm90IGJlIHJlbW92ZWQ6Ci0gKgotICogQ29weXJpZ2h0IChjKSAyMDAwIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKLSAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAotICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCi0gKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQotICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgotICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgotICogUFVSUE9TRS4gU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlCi0gKiBkZXRhaWxzLgotICovCi0KLXBhY2thZ2Ugb3JnLnczYy5kb20uaHRtbDsKLQotaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OwotCi0vKioKLSAqICBJbmxpbmUgc3Vid2luZG93cy4gU2VlIHRoZSAgSUZSQU1FIGVsZW1lbnQgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAwL0NSLURPTS1MZXZlbC0yLTIwMDAwNTEwJz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMiBTcGVjaWZpY2F0aW9uPC9hPi4KLSAqLwotcHVibGljIGludGVyZmFjZSBIVE1MSUZyYW1lRWxlbWVudCBleHRlbmRzIEhUTUxFbGVtZW50IHsKLSAgICAvKioKLSAgICAgKiAgQWxpZ25zIHRoaXMgb2JqZWN0ICh2ZXJ0aWNhbGx5IG9yIGhvcml6b250YWxseSkgIHdpdGggcmVzcGVjdCB0byBpdHMKLSAgICAgKiBzdXJyb3VuZGluZyB0ZXh0LiBTZWUgdGhlICBhbGlnbiBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAgICAgKiBUaGlzIGF0dHJpYnV0ZSBpcyBkZXByZWNhdGVkIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0QWxpZ24oKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRBbGlnbihTdHJpbmcgYWxpZ24pOwotCi0gICAgLyoqCi0gICAgICogIFJlcXVlc3QgZnJhbWUgYm9yZGVycy4gU2VlIHRoZSAgZnJhbWVib3JkZXIgYXR0cmlidXRlIGRlZmluaXRpb24gaW4KLSAgICAgKiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEZyYW1lQm9yZGVyKCk7Ci0gICAgcHVibGljIHZvaWQgc2V0RnJhbWVCb3JkZXIoU3RyaW5nIGZyYW1lQm9yZGVyKTsKLQotICAgIC8qKgotICAgICAqICBGcmFtZSBoZWlnaHQuIFNlZSB0aGUgIGhlaWdodCBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEhlaWdodCgpOwotICAgIHB1YmxpYyB2b2lkIHNldEhlaWdodChTdHJpbmcgaGVpZ2h0KTsKLQotICAgIC8qKgotICAgICAqICBVUkkgZGVzaWduYXRpbmcgYSBsb25nIGRlc2NyaXB0aW9uIG9mIHRoaXMgaW1hZ2Ugb3IgZnJhbWUuIFNlZSB0aGUKLSAgICAgKiBsb25nZGVzYyBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldExvbmdEZXNjKCk7Ci0gICAgcHVibGljIHZvaWQgc2V0TG9uZ0Rlc2MoU3RyaW5nIGxvbmdEZXNjKTsKLQotICAgIC8qKgotICAgICAqICBGcmFtZSBtYXJnaW4gaGVpZ2h0LCBpbiBwaXhlbHMuIFNlZSB0aGUgIG1hcmdpbmhlaWdodCBhdHRyaWJ1dGUKLSAgICAgKiBkZWZpbml0aW9uIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TWFyZ2luSGVpZ2h0KCk7Ci0gICAgcHVibGljIHZvaWQgc2V0TWFyZ2luSGVpZ2h0KFN0cmluZyBtYXJnaW5IZWlnaHQpOwotCi0gICAgLyoqCi0gICAgICogIEZyYW1lIG1hcmdpbiB3aWR0aCwgaW4gcGl4ZWxzLiBTZWUgdGhlICBtYXJnaW53aWR0aCBhdHRyaWJ1dGUKLSAgICAgKiBkZWZpbml0aW9uIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TWFyZ2luV2lkdGgoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRNYXJnaW5XaWR0aChTdHJpbmcgbWFyZ2luV2lkdGgpOwotCi0gICAgLyoqCi0gICAgICogIFRoZSBmcmFtZSBuYW1lIChvYmplY3Qgb2YgdGhlIDxjb2RlPnRhcmdldDwvY29kZT4gYXR0cmlidXRlKS4gU2VlIHRoZQotICAgICAqIG5hbWUgYXR0cmlidXRlIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXROYW1lKCk7Ci0gICAgcHVibGljIHZvaWQgc2V0TmFtZShTdHJpbmcgbmFtZSk7Ci0KLSAgICAvKioKLSAgICAgKiAgU3BlY2lmeSB3aGV0aGVyIG9yIG5vdCB0aGUgZnJhbWUgc2hvdWxkIGhhdmUgc2Nyb2xsYmFycy4gU2VlIHRoZQotICAgICAqIHNjcm9sbGluZyBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFNjcm9sbGluZygpOwotICAgIHB1YmxpYyB2b2lkIHNldFNjcm9sbGluZyhTdHJpbmcgc2Nyb2xsaW5nKTsKLQotICAgIC8qKgotICAgICAqICBBIFVSSSBkZXNpZ25hdGluZyB0aGUgaW5pdGlhbCBmcmFtZSBjb250ZW50cy4gU2VlIHRoZSAgc3JjIGF0dHJpYnV0ZQotICAgICAqIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRTcmMoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRTcmMoU3RyaW5nIHNyYyk7Ci0KLSAgICAvKioKLSAgICAgKiAgRnJhbWUgd2lkdGguIFNlZSB0aGUgIHdpZHRoIGF0dHJpYnV0ZSBkZWZpbml0aW9uIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0V2lkdGgoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRXaWR0aChTdHJpbmcgd2lkdGgpOwotCi0gICAgLyoqCi0gICAgICogIFRoZSBkb2N1bWVudCB0aGlzIGZyYW1lIGNvbnRhaW5zLCBpZiB0aGVyZSBpcyBhbnkgYW5kIGl0IGlzIGF2YWlsYWJsZSwKLSAgICAgKiBvciA8Y29kZT5udWxsPC9jb2RlPiBvdGhlcndpc2UuCi0gICAgICogQHNpbmNlIERPTSBMZXZlbCAyCi0gICAgICovCi0gICAgcHVibGljIERvY3VtZW50IGdldENvbnRlbnREb2N1bWVudCgpOwotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL3czYy9kb20vaHRtbC9IVE1MSW1hZ2VFbGVtZW50LmphdmEgYi9zcmMvb3JnL3czYy9kb20vaHRtbC9IVE1MSW1hZ2VFbGVtZW50LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDdmY2VkNjEuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTEltYWdlRWxlbWVudC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTM4ICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBUaGlzIGZpbGUgaXMgYXZhaWxhYmxlIHVuZGVyIGFuZCBnb3Zlcm5lZCBieSB0aGUgR05VIEdlbmVyYWwgUHVibGljCi0gKiBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqIEhvd2V2ZXIsIHRoZSBmb2xsb3dpbmcgbm90aWNlIGFjY29tcGFuaWVkIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIG9mIHRoaXMKLSAqIGZpbGUgYW5kLCBwZXIgaXRzIHRlcm1zLCBzaG91bGQgbm90IGJlIHJlbW92ZWQ6Ci0gKgotICogQ29weXJpZ2h0IChjKSAyMDAwIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKLSAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAotICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCi0gKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQotICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgotICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgotICogUFVSUE9TRS4gU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlCi0gKiBkZXRhaWxzLgotICovCi0KLXBhY2thZ2Ugb3JnLnczYy5kb20uaHRtbDsKLQotLyoqCi0gKiAgRW1iZWRkZWQgaW1hZ2UuIFNlZSB0aGUgIElNRyBlbGVtZW50IGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gKiA8cD5TZWUgYWxzbyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMC9DUi1ET00tTGV2ZWwtMi0yMDAwMDUxMCc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDIgU3BlY2lmaWNhdGlvbjwvYT4uCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgSFRNTEltYWdlRWxlbWVudCBleHRlbmRzIEhUTUxFbGVtZW50IHsKLSAgICAvKioKLSAgICAgKiAgVVJJIGRlc2lnbmF0aW5nIHRoZSBzb3VyY2Ugb2YgdGhpcyBpbWFnZSwgZm9yIGxvdy1yZXNvbHV0aW9uIG91dHB1dC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldExvd1NyYygpOwotICAgIHB1YmxpYyB2b2lkIHNldExvd1NyYyhTdHJpbmcgbG93U3JjKTsKLQotICAgIC8qKgotICAgICAqICBUaGUgbmFtZSBvZiB0aGUgZWxlbWVudCAoZm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5KS4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXROYW1lKFN0cmluZyBuYW1lKTsKLQotICAgIC8qKgotICAgICAqICBBbGlnbnMgdGhpcyBvYmplY3QgKHZlcnRpY2FsbHkgb3IgaG9yaXpvbnRhbGx5KSAgd2l0aCByZXNwZWN0IHRvIGl0cwotICAgICAqIHN1cnJvdW5kaW5nIHRleHQuIFNlZSB0aGUgIGFsaWduIGF0dHJpYnV0ZSBkZWZpbml0aW9uIGluIEhUTUwgNC4wLgotICAgICAqIFRoaXMgYXR0cmlidXRlIGlzIGRlcHJlY2F0ZWQgaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRBbGlnbigpOwotICAgIHB1YmxpYyB2b2lkIHNldEFsaWduKFN0cmluZyBhbGlnbik7Ci0KLSAgICAvKioKLSAgICAgKiAgQWx0ZXJuYXRlIHRleHQgZm9yIHVzZXIgYWdlbnRzIG5vdCByZW5kZXJpbmcgdGhlIG5vcm1hbCBjb250ZW50IG9mCi0gICAgICogdGhpcyBlbGVtZW50LiBTZWUgdGhlICBhbHQgYXR0cmlidXRlIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRBbHQoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRBbHQoU3RyaW5nIGFsdCk7Ci0KLSAgICAvKioKLSAgICAgKiAgV2lkdGggb2YgYm9yZGVyIGFyb3VuZCBpbWFnZS4gU2VlIHRoZSAgYm9yZGVyIGF0dHJpYnV0ZSBkZWZpbml0aW9uIGluCi0gICAgICogSFRNTCA0LjAuIFRoaXMgYXR0cmlidXRlIGlzIGRlcHJlY2F0ZWQgaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRCb3JkZXIoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRCb3JkZXIoU3RyaW5nIGJvcmRlcik7Ci0KLSAgICAvKioKLSAgICAgKiAgT3ZlcnJpZGUgaGVpZ2h0LiBTZWUgdGhlICBoZWlnaHQgYXR0cmlidXRlIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRIZWlnaHQoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRIZWlnaHQoU3RyaW5nIGhlaWdodCk7Ci0KLSAgICAvKioKLSAgICAgKiAgSG9yaXpvbnRhbCBzcGFjZSB0byB0aGUgbGVmdCBhbmQgcmlnaHQgb2YgdGhpcyBpbWFnZS4gU2VlIHRoZSAgaHNwYWNlCi0gICAgICogYXR0cmlidXRlIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuIFRoaXMgYXR0cmlidXRlIGlzIGRlcHJlY2F0ZWQgaW4gSFRNTAotICAgICAqIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEhzcGFjZSgpOwotICAgIHB1YmxpYyB2b2lkIHNldEhzcGFjZShTdHJpbmcgaHNwYWNlKTsKLQotICAgIC8qKgotICAgICAqICBVc2Ugc2VydmVyLXNpZGUgaW1hZ2UgbWFwLiBTZWUgdGhlICBpc21hcCBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MCi0gICAgICogNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGdldElzTWFwKCk7Ci0gICAgcHVibGljIHZvaWQgc2V0SXNNYXAoYm9vbGVhbiBpc01hcCk7Ci0KLSAgICAvKioKLSAgICAgKiAgVVJJIGRlc2lnbmF0aW5nIGEgbG9uZyBkZXNjcmlwdGlvbiBvZiB0aGlzIGltYWdlIG9yIGZyYW1lLiBTZWUgdGhlCi0gICAgICogbG9uZ2Rlc2MgYXR0cmlidXRlIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRMb25nRGVzYygpOwotICAgIHB1YmxpYyB2b2lkIHNldExvbmdEZXNjKFN0cmluZyBsb25nRGVzYyk7Ci0KLSAgICAvKioKLSAgICAgKiAgVVJJIGRlc2lnbmF0aW5nIHRoZSBzb3VyY2Ugb2YgdGhpcyBpbWFnZS4gU2VlIHRoZSAgc3JjIGF0dHJpYnV0ZQotICAgICAqIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRTcmMoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRTcmMoU3RyaW5nIHNyYyk7Ci0KLSAgICAvKioKLSAgICAgKiAgVXNlIGNsaWVudC1zaWRlIGltYWdlIG1hcC4gU2VlIHRoZSAgdXNlbWFwIGF0dHJpYnV0ZSBkZWZpbml0aW9uIGluCi0gICAgICogSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRVc2VNYXAoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRVc2VNYXAoU3RyaW5nIHVzZU1hcCk7Ci0KLSAgICAvKioKLSAgICAgKiAgVmVydGljYWwgc3BhY2UgYWJvdmUgYW5kIGJlbG93IHRoaXMgaW1hZ2UuIFNlZSB0aGUgIHZzcGFjZSBhdHRyaWJ1dGUKLSAgICAgKiBkZWZpbml0aW9uIGluIEhUTUwgNC4wLiBUaGlzIGF0dHJpYnV0ZSBpcyBkZXByZWNhdGVkIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VnNwYWNlKCk7Ci0gICAgcHVibGljIHZvaWQgc2V0VnNwYWNlKFN0cmluZyB2c3BhY2UpOwotCi0gICAgLyoqCi0gICAgICogIE92ZXJyaWRlIHdpZHRoLiBTZWUgdGhlICB3aWR0aCBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFdpZHRoKCk7Ci0gICAgcHVibGljIHZvaWQgc2V0V2lkdGgoU3RyaW5nIHdpZHRoKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTElucHV0RWxlbWVudC5qYXZhIGIvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTElucHV0RWxlbWVudC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiNThkOGI4Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxJbnB1dEVsZW1lbnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIyNSArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogVGhpcyBmaWxlIGlzIGF2YWlsYWJsZSB1bmRlciBhbmQgZ292ZXJuZWQgYnkgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwotICogTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKiBIb3dldmVyLCB0aGUgZm9sbG93aW5nIG5vdGljZSBhY2NvbXBhbmllZCB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGlzCi0gKiBmaWxlIGFuZCwgcGVyIGl0cyB0ZXJtcywgc2hvdWxkIG5vdCBiZSByZW1vdmVkOgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAotICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCi0gKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKLSAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQotICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKLSAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KLSAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKLSAqIFBVUlBPU0UuIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZQotICogZGV0YWlscy4KLSAqLwotCi1wYWNrYWdlIG9yZy53M2MuZG9tLmh0bWw7Ci0KLS8qKgotICogIEZvcm0gY29udHJvbC4gIE5vdGUuIERlcGVuZGluZyB1cG9uIHRoZSBlbnZpcm9ubWVudCBpbiB3aGljaCB0aGUgcGFnZSBpcwotICogYmVpbmcgdmlld2VkLCB0aGUgdmFsdWUgcHJvcGVydHkgbWF5IGJlIHJlYWQtb25seSBmb3IgdGhlIGZpbGUgdXBsb2FkCi0gKiBpbnB1dCB0eXBlLiBGb3IgdGhlICJwYXNzd29yZCIgaW5wdXQgdHlwZSwgdGhlIGFjdHVhbCB2YWx1ZSByZXR1cm5lZCBtYXkKLSAqIGJlIG1hc2tlZCB0byBwcmV2ZW50IHVuYXV0aG9yaXplZCB1c2UuIFNlZSB0aGUgIElOUFVUIGVsZW1lbnQgZGVmaW5pdGlvbgotICogaW4gSFRNTCA0LjAuCi0gKiA8cD5TZWUgYWxzbyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMC9DUi1ET00tTGV2ZWwtMi0yMDAwMDUxMCc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDIgU3BlY2lmaWNhdGlvbjwvYT4uCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgSFRNTElucHV0RWxlbWVudCBleHRlbmRzIEhUTUxFbGVtZW50IHsKLSAgICAvKioKLSAgICAgKiAgV2hlbiB0aGUgPGNvZGU+dHlwZTwvY29kZT4gYXR0cmlidXRlIG9mIHRoZSBlbGVtZW50IGhhcyB0aGUgdmFsdWUKLSAgICAgKiAiVGV4dCIsICJGaWxlIiBvciAiUGFzc3dvcmQiLCB0aGlzIHJlcHJlc2VudHMgdGhlIEhUTUwgdmFsdWUgYXR0cmlidXRlCi0gICAgICogb2YgdGhlIGVsZW1lbnQuIFRoZSB2YWx1ZSBvZiB0aGlzIGF0dHJpYnV0ZSBkb2VzIG5vdCBjaGFuZ2UgaWYgdGhlCi0gICAgICogY29udGVudHMgb2YgdGhlIGNvcnJlc3BvbmRpbmcgZm9ybSBjb250cm9sLCBpbiBhbiBpbnRlcmFjdGl2ZSB1c2VyCi0gICAgICogYWdlbnQsIGNoYW5nZXMuIENoYW5naW5nIHRoaXMgYXR0cmlidXRlLCBob3dldmVyLCByZXNldHMgdGhlIGNvbnRlbnRzCi0gICAgICogb2YgdGhlIGZvcm0gY29udHJvbC4gU2VlIHRoZSAgdmFsdWUgYXR0cmlidXRlIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXREZWZhdWx0VmFsdWUoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXREZWZhdWx0VmFsdWUoU3RyaW5nIGRlZmF1bHRWYWx1ZSk7Ci0KLSAgICAvKioKLSAgICAgKiAgV2hlbiA8Y29kZT50eXBlPC9jb2RlPiBoYXMgdGhlIHZhbHVlICJSYWRpbyIgb3IgIkNoZWNrYm94IiwgdGhpcwotICAgICAqIHJlcHJlc2VudHMgdGhlIEhUTUwgY2hlY2tlZCBhdHRyaWJ1dGUgb2YgdGhlIGVsZW1lbnQuIFRoZSB2YWx1ZSBvZgotICAgICAqIHRoaXMgYXR0cmlidXRlIGRvZXMgbm90IGNoYW5nZSBpZiB0aGUgc3RhdGUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgZm9ybQotICAgICAqIGNvbnRyb2wsIGluIGFuIGludGVyYWN0aXZlIHVzZXIgYWdlbnQsIGNoYW5nZXMuIENoYW5nZXMgdG8gdGhpcwotICAgICAqIGF0dHJpYnV0ZSwgaG93ZXZlciwgcmVzZXRzIHRoZSBzdGF0ZSBvZiB0aGUgZm9ybSBjb250cm9sLiBTZWUgdGhlCi0gICAgICogY2hlY2tlZCBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXREZWZhdWx0Q2hlY2tlZCgpOwotICAgIHB1YmxpYyB2b2lkIHNldERlZmF1bHRDaGVja2VkKGJvb2xlYW4gZGVmYXVsdENoZWNrZWQpOwotCi0gICAgLyoqCi0gICAgICogIFJldHVybnMgdGhlIDxjb2RlPkZPUk08L2NvZGU+IGVsZW1lbnQgY29udGFpbmluZyB0aGlzIGNvbnRyb2wuIFJldHVybnMKLSAgICAgKiA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGlzIGNvbnRyb2wgaXMgbm90IHdpdGhpbiB0aGUgY29udGV4dCBvZiBhIGZvcm0uCi0gICAgICovCi0gICAgcHVibGljIEhUTUxGb3JtRWxlbWVudCBnZXRGb3JtKCk7Ci0KLSAgICAvKioKLSAgICAgKiAgQSBjb21tYS1zZXBhcmF0ZWQgbGlzdCBvZiBjb250ZW50IHR5cGVzIHRoYXQgYSBzZXJ2ZXIgcHJvY2Vzc2luZyB0aGlzCi0gICAgICogZm9ybSB3aWxsIGhhbmRsZSBjb3JyZWN0bHkuIFNlZSB0aGUgIGFjY2VwdCBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbgotICAgICAqIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0QWNjZXB0KCk7Ci0gICAgcHVibGljIHZvaWQgc2V0QWNjZXB0KFN0cmluZyBhY2NlcHQpOwotCi0gICAgLyoqCi0gICAgICogIEEgc2luZ2xlIGNoYXJhY3RlciBhY2Nlc3Mga2V5IHRvIGdpdmUgYWNjZXNzIHRvIHRoZSBmb3JtIGNvbnRyb2wuIFNlZQotICAgICAqIHRoZSAgYWNjZXNza2V5IGF0dHJpYnV0ZSBkZWZpbml0aW9uIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0QWNjZXNzS2V5KCk7Ci0gICAgcHVibGljIHZvaWQgc2V0QWNjZXNzS2V5KFN0cmluZyBhY2Nlc3NLZXkpOwotCi0gICAgLyoqCi0gICAgICogIEFsaWducyB0aGlzIG9iamVjdCAodmVydGljYWxseSBvciBob3Jpem9udGFsbHkpICB3aXRoIHJlc3BlY3QgdG8gaXRzCi0gICAgICogc3Vycm91bmRpbmcgdGV4dC4gU2VlIHRoZSAgYWxpZ24gYXR0cmlidXRlIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gICAgICogVGhpcyBhdHRyaWJ1dGUgaXMgZGVwcmVjYXRlZCBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEFsaWduKCk7Ci0gICAgcHVibGljIHZvaWQgc2V0QWxpZ24oU3RyaW5nIGFsaWduKTsKLQotICAgIC8qKgotICAgICAqICBBbHRlcm5hdGUgdGV4dCBmb3IgdXNlciBhZ2VudHMgbm90IHJlbmRlcmluZyB0aGUgbm9ybWFsIGNvbnRlbnQgb2YKLSAgICAgKiB0aGlzIGVsZW1lbnQuIFNlZSB0aGUgIGFsdCBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEFsdCgpOwotICAgIHB1YmxpYyB2b2lkIHNldEFsdChTdHJpbmcgYWx0KTsKLQotICAgIC8qKgotICAgICAqICBXaGVuIHRoZSA8Y29kZT50eXBlPC9jb2RlPiBhdHRyaWJ1dGUgb2YgdGhlIGVsZW1lbnQgaGFzIHRoZSB2YWx1ZQotICAgICAqICJSYWRpbyIgb3IgIkNoZWNrYm94IiwgdGhpcyByZXByZXNlbnRzIHRoZSBjdXJyZW50IHN0YXRlIG9mIHRoZSBmb3JtCi0gICAgICogY29udHJvbCwgaW4gYW4gaW50ZXJhY3RpdmUgdXNlciBhZ2VudC4gQ2hhbmdlcyB0byB0aGlzIGF0dHJpYnV0ZQotICAgICAqIGNoYW5nZSB0aGUgc3RhdGUgb2YgdGhlIGZvcm0gY29udHJvbCwgYnV0IGRvIG5vdCBjaGFuZ2UgdGhlIHZhbHVlIG9mCi0gICAgICogdGhlIEhUTUwgdmFsdWUgYXR0cmlidXRlIG9mIHRoZSBlbGVtZW50LgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGdldENoZWNrZWQoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRDaGVja2VkKGJvb2xlYW4gY2hlY2tlZCk7Ci0KLSAgICAvKioKLSAgICAgKiAgVGhlIGNvbnRyb2wgaXMgdW5hdmFpbGFibGUgaW4gdGhpcyBjb250ZXh0LiBTZWUgdGhlICBkaXNhYmxlZAotICAgICAqIGF0dHJpYnV0ZSBkZWZpbml0aW9uIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGdldERpc2FibGVkKCk7Ci0gICAgcHVibGljIHZvaWQgc2V0RGlzYWJsZWQoYm9vbGVhbiBkaXNhYmxlZCk7Ci0KLSAgICAvKioKLSAgICAgKiAgTWF4aW11bSBudW1iZXIgb2YgY2hhcmFjdGVycyBmb3IgdGV4dCBmaWVsZHMsIHdoZW4gPGNvZGU+dHlwZTwvY29kZT4KLSAgICAgKiBoYXMgdGhlIHZhbHVlICJUZXh0IiBvciAiUGFzc3dvcmQiLiBTZWUgdGhlICBtYXhsZW5ndGggYXR0cmlidXRlCi0gICAgICogZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldE1heExlbmd0aCgpOwotICAgIHB1YmxpYyB2b2lkIHNldE1heExlbmd0aChpbnQgbWF4TGVuZ3RoKTsKLQotICAgIC8qKgotICAgICAqICBGb3JtIGNvbnRyb2wgb3Igb2JqZWN0IG5hbWUgd2hlbiBzdWJtaXR0ZWQgd2l0aCBhIGZvcm0uIFNlZSB0aGUgIG5hbWUKLSAgICAgKiBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXROYW1lKFN0cmluZyBuYW1lKTsKLQotICAgIC8qKgotICAgICAqICBUaGlzIGNvbnRyb2wgaXMgcmVhZC1vbmx5LiBSZWxldmFudCBvbmx5IHdoZW4gPGNvZGU+dHlwZTwvY29kZT4gaGFzCi0gICAgICogdGhlIHZhbHVlICJUZXh0IiBvciAiUGFzc3dvcmQiLiBTZWUgdGhlICByZWFkb25seSBhdHRyaWJ1dGUgZGVmaW5pdGlvbgotICAgICAqIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGdldFJlYWRPbmx5KCk7Ci0gICAgcHVibGljIHZvaWQgc2V0UmVhZE9ubHkoYm9vbGVhbiByZWFkT25seSk7Ci0KLSAgICAvKioKLSAgICAgKiAgU2l6ZSBpbmZvcm1hdGlvbi4gVGhlIHByZWNpc2UgbWVhbmluZyBpcyBzcGVjaWZpYyB0byBlYWNoIHR5cGUgb2YKLSAgICAgKiBmaWVsZC4gIFNlZSB0aGUgIHNpemUgYXR0cmlidXRlIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRTaXplKCk7Ci0gICAgcHVibGljIHZvaWQgc2V0U2l6ZShTdHJpbmcgc2l6ZSk7Ci0KLSAgICAvKioKLSAgICAgKiAgV2hlbiB0aGUgPGNvZGU+dHlwZTwvY29kZT4gYXR0cmlidXRlIGhhcyB0aGUgdmFsdWUgIkltYWdlIiwgdGhpcwotICAgICAqIGF0dHJpYnV0ZSBzcGVjaWZpZXMgdGhlIGxvY2F0aW9uIG9mIHRoZSBpbWFnZSB0byBiZSB1c2VkIHRvIGRlY29yYXRlCi0gICAgICogdGhlIGdyYXBoaWNhbCBzdWJtaXQgYnV0dG9uLiBTZWUgdGhlICBzcmMgYXR0cmlidXRlIGRlZmluaXRpb24gaW4gSFRNTAotICAgICAqIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFNyYygpOwotICAgIHB1YmxpYyB2b2lkIHNldFNyYyhTdHJpbmcgc3JjKTsKLQotICAgIC8qKgotICAgICAqICBJbmRleCB0aGF0IHJlcHJlc2VudHMgdGhlIGVsZW1lbnQncyBwb3NpdGlvbiBpbiB0aGUgdGFiYmluZyBvcmRlci4gU2VlCi0gICAgICogdGhlICB0YWJpbmRleCBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldFRhYkluZGV4KCk7Ci0gICAgcHVibGljIHZvaWQgc2V0VGFiSW5kZXgoaW50IHRhYkluZGV4KTsKLQotICAgIC8qKgotICAgICAqICBUaGUgdHlwZSBvZiBjb250cm9sIGNyZWF0ZWQuIFNlZSB0aGUgIHR5cGUgYXR0cmlidXRlIGRlZmluaXRpb24gaW4KLSAgICAgKiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFR5cGUoKTsKLQotICAgIC8qKgotICAgICAqICBVc2UgY2xpZW50LXNpZGUgaW1hZ2UgbWFwLiBTZWUgdGhlICB1c2VtYXAgYXR0cmlidXRlIGRlZmluaXRpb24gaW4KLSAgICAgKiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFVzZU1hcCgpOwotICAgIHB1YmxpYyB2b2lkIHNldFVzZU1hcChTdHJpbmcgdXNlTWFwKTsKLQotICAgIC8qKgotICAgICAqICBXaGVuIHRoZSA8Y29kZT50eXBlPC9jb2RlPiBhdHRyaWJ1dGUgb2YgdGhlIGVsZW1lbnQgaGFzIHRoZSB2YWx1ZQotICAgICAqICJUZXh0IiwgIkZpbGUiIG9yICJQYXNzd29yZCIsIHRoaXMgcmVwcmVzZW50cyB0aGUgY3VycmVudCBjb250ZW50cyBvZgotICAgICAqIHRoZSBjb3JyZXNwb25kaW5nIGZvcm0gY29udHJvbCwgaW4gYW4gaW50ZXJhY3RpdmUgdXNlciBhZ2VudC4gQ2hhbmdpbmcKLSAgICAgKiB0aGlzIGF0dHJpYnV0ZSBjaGFuZ2VzIHRoZSBjb250ZW50cyBvZiB0aGUgZm9ybSBjb250cm9sLCBidXQgZG9lcyBub3QKLSAgICAgKiBjaGFuZ2UgdGhlIHZhbHVlIG9mIHRoZSBIVE1MIHZhbHVlIGF0dHJpYnV0ZSBvZiB0aGUgZWxlbWVudC4gV2hlbiB0aGUKLSAgICAgKiA8Y29kZT50eXBlPC9jb2RlPiBhdHRyaWJ1dGUgb2YgdGhlIGVsZW1lbnQgaGFzIHRoZSB2YWx1ZSAiQnV0dG9uIiwKLSAgICAgKiAiSGlkZGVuIiwgIlN1Ym1pdCIsICJSZXNldCIsICJJbWFnZSIsICJDaGVja2JveCIgb3IgIlJhZGlvIiwgdGhpcwotICAgICAqIHJlcHJlc2VudHMgdGhlIEhUTUwgdmFsdWUgYXR0cmlidXRlIG9mIHRoZSBlbGVtZW50LiBTZWUgdGhlICB2YWx1ZQotICAgICAqIGF0dHJpYnV0ZSBkZWZpbml0aW9uIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VmFsdWUoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRWYWx1ZShTdHJpbmcgdmFsdWUpOwotCi0gICAgLyoqCi0gICAgICogIFJlbW92ZXMga2V5Ym9hcmQgZm9jdXMgZnJvbSB0aGlzIGVsZW1lbnQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgYmx1cigpOwotCi0gICAgLyoqCi0gICAgICogIEdpdmVzIGtleWJvYXJkIGZvY3VzIHRvIHRoaXMgZWxlbWVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBmb2N1cygpOwotCi0gICAgLyoqCi0gICAgICogIFNlbGVjdCB0aGUgY29udGVudHMgb2YgdGhlIHRleHQgYXJlYS4gRm9yIDxjb2RlPklOUFVUPC9jb2RlPiBlbGVtZW50cwotICAgICAqIHdob3NlIDxjb2RlPnR5cGU8L2NvZGU+IGF0dHJpYnV0ZSBoYXMgb25lIG9mIHRoZSBmb2xsb3dpbmcgdmFsdWVzOgotICAgICAqICJUZXh0IiwgIkZpbGUiLCBvciAiUGFzc3dvcmQiLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNlbGVjdCgpOwotCi0gICAgLyoqCi0gICAgICogIFNpbXVsYXRlIGEgbW91c2UtY2xpY2suIEZvciA8Y29kZT5JTlBVVDwvY29kZT4gZWxlbWVudHMgd2hvc2UKLSAgICAgKiA8Y29kZT50eXBlPC9jb2RlPiBhdHRyaWJ1dGUgaGFzIG9uZSBvZiB0aGUgZm9sbG93aW5nIHZhbHVlczogIkJ1dHRvbiIsCi0gICAgICogIkNoZWNrYm94IiwgIlJhZGlvIiwgIlJlc2V0Iiwgb3IgIlN1Ym1pdCIuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY2xpY2soKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTElzSW5kZXhFbGVtZW50LmphdmEgYi9zcmMvb3JnL3czYy9kb20vaHRtbC9IVE1MSXNJbmRleEVsZW1lbnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMTExZWRkZS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3czYy9kb20vaHRtbC9IVE1MSXNJbmRleEVsZW1lbnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDYzICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBUaGlzIGZpbGUgaXMgYXZhaWxhYmxlIHVuZGVyIGFuZCBnb3Zlcm5lZCBieSB0aGUgR05VIEdlbmVyYWwgUHVibGljCi0gKiBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqIEhvd2V2ZXIsIHRoZSBmb2xsb3dpbmcgbm90aWNlIGFjY29tcGFuaWVkIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIG9mIHRoaXMKLSAqIGZpbGUgYW5kLCBwZXIgaXRzIHRlcm1zLCBzaG91bGQgbm90IGJlIHJlbW92ZWQ6Ci0gKgotICogQ29weXJpZ2h0IChjKSAyMDAwIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKLSAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAotICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCi0gKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQotICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgotICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgotICogUFVSUE9TRS4gU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlCi0gKiBkZXRhaWxzLgotICovCi0KLXBhY2thZ2Ugb3JnLnczYy5kb20uaHRtbDsKLQotLyoqCi0gKiAgVGhpcyBlbGVtZW50IGlzIHVzZWQgZm9yIHNpbmdsZS1saW5lIHRleHQgaW5wdXQuIFNlZSB0aGUgIElTSU5ERVggZWxlbWVudAotICogZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4gVGhpcyBlbGVtZW50IGlzIGRlcHJlY2F0ZWQgaW4gSFRNTCA0LjAuCi0gKiA8cD5TZWUgYWxzbyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMC9DUi1ET00tTGV2ZWwtMi0yMDAwMDUxMCc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDIgU3BlY2lmaWNhdGlvbjwvYT4uCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgSFRNTElzSW5kZXhFbGVtZW50IGV4dGVuZHMgSFRNTEVsZW1lbnQgewotICAgIC8qKgotICAgICAqICBSZXR1cm5zIHRoZSA8Y29kZT5GT1JNPC9jb2RlPiBlbGVtZW50IGNvbnRhaW5pbmcgdGhpcyBjb250cm9sLiBSZXR1cm5zCi0gICAgICogPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhpcyBjb250cm9sIGlzIG5vdCB3aXRoaW4gdGhlIGNvbnRleHQgb2YgYSBmb3JtLgotICAgICAqLwotICAgIHB1YmxpYyBIVE1MRm9ybUVsZW1lbnQgZ2V0Rm9ybSgpOwotCi0gICAgLyoqCi0gICAgICogIFRoZSBwcm9tcHQgbWVzc2FnZS4gU2VlIHRoZSAgcHJvbXB0IGF0dHJpYnV0ZSBkZWZpbml0aW9uIGluIEhUTUwgNC4wLgotICAgICAqIFRoaXMgYXR0cmlidXRlIGlzIGRlcHJlY2F0ZWQgaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRQcm9tcHQoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRQcm9tcHQoU3RyaW5nIHByb21wdCk7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxMSUVsZW1lbnQuamF2YSBiL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxMSUVsZW1lbnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZjQxMTNmMS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3czYy9kb20vaHRtbC9IVE1MTElFbGVtZW50LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw2NCArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogVGhpcyBmaWxlIGlzIGF2YWlsYWJsZSB1bmRlciBhbmQgZ292ZXJuZWQgYnkgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwotICogTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKiBIb3dldmVyLCB0aGUgZm9sbG93aW5nIG5vdGljZSBhY2NvbXBhbmllZCB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGlzCi0gKiBmaWxlIGFuZCwgcGVyIGl0cyB0ZXJtcywgc2hvdWxkIG5vdCBiZSByZW1vdmVkOgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAotICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCi0gKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKLSAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQotICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKLSAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KLSAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKLSAqIFBVUlBPU0UuIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZQotICogZGV0YWlscy4KLSAqLwotCi1wYWNrYWdlIG9yZy53M2MuZG9tLmh0bWw7Ci0KLS8qKgotICogIExpc3QgaXRlbS4gU2VlIHRoZSAgTEkgZWxlbWVudCBkZWZpbml0aW9uIGluIEhUTUwgNC4wLgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDAvQ1ItRE9NLUxldmVsLTItMjAwMDA1MTAnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAyIFNwZWNpZmljYXRpb248L2E+LgotICovCi1wdWJsaWMgaW50ZXJmYWNlIEhUTUxMSUVsZW1lbnQgZXh0ZW5kcyBIVE1MRWxlbWVudCB7Ci0gICAgLyoqCi0gICAgICogIExpc3QgaXRlbSBidWxsZXQgc3R5bGUuIFNlZSB0aGUgIHR5cGUgYXR0cmlidXRlIGRlZmluaXRpb24gaW4gSFRNTAotICAgICAqIDQuMC4gVGhpcyBhdHRyaWJ1dGUgaXMgZGVwcmVjYXRlZCBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFR5cGUoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRUeXBlKFN0cmluZyB0eXBlKTsKLQotICAgIC8qKgotICAgICAqICBSZXNldCBzZXF1ZW5jZSBudW1iZXIgd2hlbiB1c2VkIGluIDxjb2RlPk9MPC9jb2RlPiAuIFNlZSB0aGUgIHZhbHVlCi0gICAgICogYXR0cmlidXRlIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuIFRoaXMgYXR0cmlidXRlIGlzIGRlcHJlY2F0ZWQgaW4gSFRNTAotICAgICAqIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldFZhbHVlKCk7Ci0gICAgcHVibGljIHZvaWQgc2V0VmFsdWUoaW50IHZhbHVlKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTExhYmVsRWxlbWVudC5qYXZhIGIvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTExhYmVsRWxlbWVudC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkM2ZkNmJlLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxMYWJlbEVsZW1lbnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDcwICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBUaGlzIGZpbGUgaXMgYXZhaWxhYmxlIHVuZGVyIGFuZCBnb3Zlcm5lZCBieSB0aGUgR05VIEdlbmVyYWwgUHVibGljCi0gKiBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqIEhvd2V2ZXIsIHRoZSBmb2xsb3dpbmcgbm90aWNlIGFjY29tcGFuaWVkIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIG9mIHRoaXMKLSAqIGZpbGUgYW5kLCBwZXIgaXRzIHRlcm1zLCBzaG91bGQgbm90IGJlIHJlbW92ZWQ6Ci0gKgotICogQ29weXJpZ2h0IChjKSAyMDAwIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKLSAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAotICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCi0gKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQotICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgotICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgotICogUFVSUE9TRS4gU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlCi0gKiBkZXRhaWxzLgotICovCi0KLXBhY2thZ2Ugb3JnLnczYy5kb20uaHRtbDsKLQotLyoqCi0gKiAgRm9ybSBmaWVsZCBsYWJlbCB0ZXh0LiBTZWUgdGhlICBMQUJFTCBlbGVtZW50IGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gKiA8cD5TZWUgYWxzbyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMC9DUi1ET00tTGV2ZWwtMi0yMDAwMDUxMCc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDIgU3BlY2lmaWNhdGlvbjwvYT4uCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgSFRNTExhYmVsRWxlbWVudCBleHRlbmRzIEhUTUxFbGVtZW50IHsKLSAgICAvKioKLSAgICAgKiAgUmV0dXJucyB0aGUgPGNvZGU+Rk9STTwvY29kZT4gZWxlbWVudCBjb250YWluaW5nIHRoaXMgY29udHJvbC4gUmV0dXJucwotICAgICAqIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoaXMgY29udHJvbCBpcyBub3Qgd2l0aGluIHRoZSBjb250ZXh0IG9mIGEgZm9ybS4KLSAgICAgKi8KLSAgICBwdWJsaWMgSFRNTEZvcm1FbGVtZW50IGdldEZvcm0oKTsKLQotICAgIC8qKgotICAgICAqICBBIHNpbmdsZSBjaGFyYWN0ZXIgYWNjZXNzIGtleSB0byBnaXZlIGFjY2VzcyB0byB0aGUgZm9ybSBjb250cm9sLiBTZWUKLSAgICAgKiB0aGUgIGFjY2Vzc2tleSBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEFjY2Vzc0tleSgpOwotICAgIHB1YmxpYyB2b2lkIHNldEFjY2Vzc0tleShTdHJpbmcgYWNjZXNzS2V5KTsKLQotICAgIC8qKgotICAgICAqICBUaGlzIGF0dHJpYnV0ZSBsaW5rcyB0aGlzIGxhYmVsIHdpdGggYW5vdGhlciBmb3JtIGNvbnRyb2wgYnkKLSAgICAgKiA8Y29kZT5pZDwvY29kZT4gYXR0cmlidXRlLiBTZWUgdGhlICBmb3IgYXR0cmlidXRlIGRlZmluaXRpb24gaW4gSFRNTAotICAgICAqIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEh0bWxGb3IoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRIdG1sRm9yKFN0cmluZyBodG1sRm9yKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTExlZ2VuZEVsZW1lbnQuamF2YSBiL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxMZWdlbmRFbGVtZW50LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGZmZTA4MTYuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTExlZ2VuZEVsZW1lbnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDcxICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBUaGlzIGZpbGUgaXMgYXZhaWxhYmxlIHVuZGVyIGFuZCBnb3Zlcm5lZCBieSB0aGUgR05VIEdlbmVyYWwgUHVibGljCi0gKiBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqIEhvd2V2ZXIsIHRoZSBmb2xsb3dpbmcgbm90aWNlIGFjY29tcGFuaWVkIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIG9mIHRoaXMKLSAqIGZpbGUgYW5kLCBwZXIgaXRzIHRlcm1zLCBzaG91bGQgbm90IGJlIHJlbW92ZWQ6Ci0gKgotICogQ29weXJpZ2h0IChjKSAyMDAwIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKLSAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAotICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCi0gKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQotICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgotICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgotICogUFVSUE9TRS4gU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlCi0gKiBkZXRhaWxzLgotICovCi0KLXBhY2thZ2Ugb3JnLnczYy5kb20uaHRtbDsKLQotLyoqCi0gKiAgUHJvdmlkZXMgYSBjYXB0aW9uIGZvciBhIDxjb2RlPkZJRUxEU0VUPC9jb2RlPiBncm91cGluZy4gIFNlZSB0aGUgIExFR0VORAotICogZWxlbWVudCBkZWZpbml0aW9uIGluIEhUTUwgNC4wLgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDAvQ1ItRE9NLUxldmVsLTItMjAwMDA1MTAnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAyIFNwZWNpZmljYXRpb248L2E+LgotICovCi1wdWJsaWMgaW50ZXJmYWNlIEhUTUxMZWdlbmRFbGVtZW50IGV4dGVuZHMgSFRNTEVsZW1lbnQgewotICAgIC8qKgotICAgICAqICBSZXR1cm5zIHRoZSA8Y29kZT5GT1JNPC9jb2RlPiBlbGVtZW50IGNvbnRhaW5pbmcgdGhpcyBjb250cm9sLiBSZXR1cm5zCi0gICAgICogPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhpcyBjb250cm9sIGlzIG5vdCB3aXRoaW4gdGhlIGNvbnRleHQgb2YgYSBmb3JtLgotICAgICAqLwotICAgIHB1YmxpYyBIVE1MRm9ybUVsZW1lbnQgZ2V0Rm9ybSgpOwotCi0gICAgLyoqCi0gICAgICogIEEgc2luZ2xlIGNoYXJhY3RlciBhY2Nlc3Mga2V5IHRvIGdpdmUgYWNjZXNzIHRvIHRoZSBmb3JtIGNvbnRyb2wuIFNlZQotICAgICAqIHRoZSAgYWNjZXNza2V5IGF0dHJpYnV0ZSBkZWZpbml0aW9uIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0QWNjZXNzS2V5KCk7Ci0gICAgcHVibGljIHZvaWQgc2V0QWNjZXNzS2V5KFN0cmluZyBhY2Nlc3NLZXkpOwotCi0gICAgLyoqCi0gICAgICogIFRleHQgYWxpZ25tZW50IHJlbGF0aXZlIHRvIDxjb2RlPkZJRUxEU0VUPC9jb2RlPiAuIFNlZSB0aGUgIGFsaWduCi0gICAgICogYXR0cmlidXRlIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuIFRoaXMgYXR0cmlidXRlIGlzIGRlcHJlY2F0ZWQgaW4gSFRNTAotICAgICAqIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEFsaWduKCk7Ci0gICAgcHVibGljIHZvaWQgc2V0QWxpZ24oU3RyaW5nIGFsaWduKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTExpbmtFbGVtZW50LmphdmEgYi9zcmMvb3JnL3czYy9kb20vaHRtbC9IVE1MTGlua0VsZW1lbnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggY2MwMzE2NC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3czYy9kb20vaHRtbC9IVE1MTGlua0VsZW1lbnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExMiArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogVGhpcyBmaWxlIGlzIGF2YWlsYWJsZSB1bmRlciBhbmQgZ292ZXJuZWQgYnkgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwotICogTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKiBIb3dldmVyLCB0aGUgZm9sbG93aW5nIG5vdGljZSBhY2NvbXBhbmllZCB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGlzCi0gKiBmaWxlIGFuZCwgcGVyIGl0cyB0ZXJtcywgc2hvdWxkIG5vdCBiZSByZW1vdmVkOgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAotICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCi0gKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKLSAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQotICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKLSAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KLSAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKLSAqIFBVUlBPU0UuIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZQotICogZGV0YWlscy4KLSAqLwotCi1wYWNrYWdlIG9yZy53M2MuZG9tLmh0bWw7Ci0KLS8qKgotICogIFRoZSA8Y29kZT5MSU5LPC9jb2RlPiBlbGVtZW50IHNwZWNpZmllcyBhIGxpbmsgdG8gYW4gZXh0ZXJuYWwgcmVzb3VyY2UsCi0gKiBhbmQgZGVmaW5lcyB0aGlzIGRvY3VtZW50J3MgcmVsYXRpb25zaGlwIHRvIHRoYXQgcmVzb3VyY2UgKG9yIHZpY2UgdmVyc2EpLgotICogIFNlZSB0aGUgIExJTksgZWxlbWVudCBkZWZpbml0aW9uIGluIEhUTUwgNC4wICAoc2VlIGFsc28gdGhlCi0gKiA8Y29kZT5MaW5rU3R5bGU8L2NvZGU+IGludGVyZmFjZSBpbiB0aGUgIG1vZHVsZSkuCi0gKiA8cD5TZWUgYWxzbyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMC9DUi1ET00tTGV2ZWwtMi0yMDAwMDUxMCc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDIgU3BlY2lmaWNhdGlvbjwvYT4uCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgSFRNTExpbmtFbGVtZW50IGV4dGVuZHMgSFRNTEVsZW1lbnQgewotICAgIC8qKgotICAgICAqICBFbmFibGVzL2Rpc2FibGVzIHRoZSBsaW5rLiBUaGlzIGlzIGN1cnJlbnRseSBvbmx5IHVzZWQgZm9yIHN0eWxlIHNoZWV0Ci0gICAgICogbGlua3MsIGFuZCBtYXkgYmUgdXNlZCB0byBhY3RpdmF0ZSBvciBkZWFjdGl2YXRlIHN0eWxlIHNoZWV0cy4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXREaXNhYmxlZCgpOwotICAgIHB1YmxpYyB2b2lkIHNldERpc2FibGVkKGJvb2xlYW4gZGlzYWJsZWQpOwotCi0gICAgLyoqCi0gICAgICogIFRoZSBjaGFyYWN0ZXIgZW5jb2Rpbmcgb2YgdGhlIHJlc291cmNlIGJlaW5nIGxpbmtlZCB0by4gU2VlIHRoZQotICAgICAqIGNoYXJzZXQgYXR0cmlidXRlIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRDaGFyc2V0KCk7Ci0gICAgcHVibGljIHZvaWQgc2V0Q2hhcnNldChTdHJpbmcgY2hhcnNldCk7Ci0KLSAgICAvKioKLSAgICAgKiAgVGhlIFVSSSBvZiB0aGUgbGlua2VkIHJlc291cmNlLiBTZWUgdGhlICBocmVmIGF0dHJpYnV0ZSBkZWZpbml0aW9uIGluCi0gICAgICogSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRIcmVmKCk7Ci0gICAgcHVibGljIHZvaWQgc2V0SHJlZihTdHJpbmcgaHJlZik7Ci0KLSAgICAvKioKLSAgICAgKiAgTGFuZ3VhZ2UgY29kZSBvZiB0aGUgbGlua2VkIHJlc291cmNlLiBTZWUgdGhlICBocmVmbGFuZyBhdHRyaWJ1dGUKLSAgICAgKiBkZWZpbml0aW9uIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0SHJlZmxhbmcoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRIcmVmbGFuZyhTdHJpbmcgaHJlZmxhbmcpOwotCi0gICAgLyoqCi0gICAgICogIERlc2lnbmVkIGZvciB1c2Ugd2l0aCBvbmUgb3IgbW9yZSB0YXJnZXQgbWVkaWEuIFNlZSB0aGUgIG1lZGlhCi0gICAgICogYXR0cmlidXRlIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRNZWRpYSgpOwotICAgIHB1YmxpYyB2b2lkIHNldE1lZGlhKFN0cmluZyBtZWRpYSk7Ci0KLSAgICAvKioKLSAgICAgKiAgRm9yd2FyZCBsaW5rIHR5cGUuIFNlZSB0aGUgIHJlbCBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFJlbCgpOwotICAgIHB1YmxpYyB2b2lkIHNldFJlbChTdHJpbmcgcmVsKTsKLQotICAgIC8qKgotICAgICAqICBSZXZlcnNlIGxpbmsgdHlwZS4gU2VlIHRoZSAgcmV2IGF0dHJpYnV0ZSBkZWZpbml0aW9uIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0UmV2KCk7Ci0gICAgcHVibGljIHZvaWQgc2V0UmV2KFN0cmluZyByZXYpOwotCi0gICAgLyoqCi0gICAgICogIEZyYW1lIHRvIHJlbmRlciB0aGUgcmVzb3VyY2UgaW4uIFNlZSB0aGUgIHRhcmdldCBhdHRyaWJ1dGUgZGVmaW5pdGlvbgotICAgICAqIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0KCk7Ci0gICAgcHVibGljIHZvaWQgc2V0VGFyZ2V0KFN0cmluZyB0YXJnZXQpOwotCi0gICAgLyoqCi0gICAgICogIEFkdmlzb3J5IGNvbnRlbnQgdHlwZS4gU2VlIHRoZSAgdHlwZSBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFR5cGUoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRUeXBlKFN0cmluZyB0eXBlKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTE1hcEVsZW1lbnQuamF2YSBiL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxNYXBFbGVtZW50LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGYyYjQyMjIuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTE1hcEVsZW1lbnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDYxICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBUaGlzIGZpbGUgaXMgYXZhaWxhYmxlIHVuZGVyIGFuZCBnb3Zlcm5lZCBieSB0aGUgR05VIEdlbmVyYWwgUHVibGljCi0gKiBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqIEhvd2V2ZXIsIHRoZSBmb2xsb3dpbmcgbm90aWNlIGFjY29tcGFuaWVkIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIG9mIHRoaXMKLSAqIGZpbGUgYW5kLCBwZXIgaXRzIHRlcm1zLCBzaG91bGQgbm90IGJlIHJlbW92ZWQ6Ci0gKgotICogQ29weXJpZ2h0IChjKSAyMDAwIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKLSAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAotICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCi0gKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQotICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgotICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgotICogUFVSUE9TRS4gU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlCi0gKiBkZXRhaWxzLgotICovCi0KLXBhY2thZ2Ugb3JnLnczYy5kb20uaHRtbDsKLQotLyoqCi0gKiAgQ2xpZW50LXNpZGUgaW1hZ2UgbWFwLiBTZWUgdGhlICBNQVAgZWxlbWVudCBkZWZpbml0aW9uIGluIEhUTUwgNC4wLgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDAvQ1ItRE9NLUxldmVsLTItMjAwMDA1MTAnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAyIFNwZWNpZmljYXRpb248L2E+LgotICovCi1wdWJsaWMgaW50ZXJmYWNlIEhUTUxNYXBFbGVtZW50IGV4dGVuZHMgSFRNTEVsZW1lbnQgewotICAgIC8qKgotICAgICAqICBUaGUgbGlzdCBvZiBhcmVhcyBkZWZpbmVkIGZvciB0aGUgaW1hZ2UgbWFwLgotICAgICAqLwotICAgIHB1YmxpYyBIVE1MQ29sbGVjdGlvbiBnZXRBcmVhcygpOwotCi0gICAgLyoqCi0gICAgICogIE5hbWVzIHRoZSBtYXAgKGZvciB1c2Ugd2l0aCA8Y29kZT51c2VtYXA8L2NvZGU+ICkuIFNlZSB0aGUgIG5hbWUKLSAgICAgKiBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXROYW1lKFN0cmluZyBuYW1lKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTE1lbnVFbGVtZW50LmphdmEgYi9zcmMvb3JnL3czYy9kb20vaHRtbC9IVE1MTWVudUVsZW1lbnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYjU3OTg3OS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3czYy9kb20vaHRtbC9IVE1MTWVudUVsZW1lbnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDU3ICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBUaGlzIGZpbGUgaXMgYXZhaWxhYmxlIHVuZGVyIGFuZCBnb3Zlcm5lZCBieSB0aGUgR05VIEdlbmVyYWwgUHVibGljCi0gKiBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqIEhvd2V2ZXIsIHRoZSBmb2xsb3dpbmcgbm90aWNlIGFjY29tcGFuaWVkIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIG9mIHRoaXMKLSAqIGZpbGUgYW5kLCBwZXIgaXRzIHRlcm1zLCBzaG91bGQgbm90IGJlIHJlbW92ZWQ6Ci0gKgotICogQ29weXJpZ2h0IChjKSAyMDAwIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKLSAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAotICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCi0gKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQotICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgotICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgotICogUFVSUE9TRS4gU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlCi0gKiBkZXRhaWxzLgotICovCi0KLXBhY2thZ2Ugb3JnLnczYy5kb20uaHRtbDsKLQotLyoqCi0gKiAgTWVudSBsaXN0LiBTZWUgdGhlICBNRU5VIGVsZW1lbnQgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4gVGhpcyBlbGVtZW50IGlzCi0gKiBkZXByZWNhdGVkIGluIEhUTUwgNC4wLgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDAvQ1ItRE9NLUxldmVsLTItMjAwMDA1MTAnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAyIFNwZWNpZmljYXRpb248L2E+LgotICovCi1wdWJsaWMgaW50ZXJmYWNlIEhUTUxNZW51RWxlbWVudCBleHRlbmRzIEhUTUxFbGVtZW50IHsKLSAgICAvKioKLSAgICAgKiAgUmVkdWNlIHNwYWNpbmcgYmV0d2VlbiBsaXN0IGl0ZW1zLiBTZWUgdGhlICBjb21wYWN0IGF0dHJpYnV0ZQotICAgICAqIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuIFRoaXMgYXR0cmlidXRlIGlzIGRlcHJlY2F0ZWQgaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0Q29tcGFjdCgpOwotICAgIHB1YmxpYyB2b2lkIHNldENvbXBhY3QoYm9vbGVhbiBjb21wYWN0KTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTE1ldGFFbGVtZW50LmphdmEgYi9zcmMvb3JnL3czYy9kb20vaHRtbC9IVE1MTWV0YUVsZW1lbnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMzg5MjBlNC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3czYy9kb20vaHRtbC9IVE1MTWV0YUVsZW1lbnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDc3ICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBUaGlzIGZpbGUgaXMgYXZhaWxhYmxlIHVuZGVyIGFuZCBnb3Zlcm5lZCBieSB0aGUgR05VIEdlbmVyYWwgUHVibGljCi0gKiBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqIEhvd2V2ZXIsIHRoZSBmb2xsb3dpbmcgbm90aWNlIGFjY29tcGFuaWVkIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIG9mIHRoaXMKLSAqIGZpbGUgYW5kLCBwZXIgaXRzIHRlcm1zLCBzaG91bGQgbm90IGJlIHJlbW92ZWQ6Ci0gKgotICogQ29weXJpZ2h0IChjKSAyMDAwIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKLSAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAotICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCi0gKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQotICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgotICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgotICogUFVSUE9TRS4gU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlCi0gKiBkZXRhaWxzLgotICovCi0KLXBhY2thZ2Ugb3JnLnczYy5kb20uaHRtbDsKLQotLyoqCi0gKiAgVGhpcyBjb250YWlucyBnZW5lcmljIG1ldGEtaW5mb3JtYXRpb24gYWJvdXQgdGhlIGRvY3VtZW50LiBTZWUgdGhlICBNRVRBCi0gKiBlbGVtZW50IGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gKiA8cD5TZWUgYWxzbyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMC9DUi1ET00tTGV2ZWwtMi0yMDAwMDUxMCc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDIgU3BlY2lmaWNhdGlvbjwvYT4uCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgSFRNTE1ldGFFbGVtZW50IGV4dGVuZHMgSFRNTEVsZW1lbnQgewotICAgIC8qKgotICAgICAqICBBc3NvY2lhdGVkIGluZm9ybWF0aW9uLiBTZWUgdGhlICBjb250ZW50IGF0dHJpYnV0ZSBkZWZpbml0aW9uIGluIEhUTUwKLSAgICAgKiA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRDb250ZW50KCk7Ci0gICAgcHVibGljIHZvaWQgc2V0Q29udGVudChTdHJpbmcgY29udGVudCk7Ci0KLSAgICAvKioKLSAgICAgKiAgSFRUUCByZXNwb25zZSBoZWFkZXIgbmFtZS4gU2VlIHRoZSAgaHR0cC1lcXVpdiBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbgotICAgICAqIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0SHR0cEVxdWl2KCk7Ci0gICAgcHVibGljIHZvaWQgc2V0SHR0cEVxdWl2KFN0cmluZyBodHRwRXF1aXYpOwotCi0gICAgLyoqCi0gICAgICogIE1ldGEgaW5mb3JtYXRpb24gbmFtZS4gU2VlIHRoZSAgbmFtZSBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXROYW1lKFN0cmluZyBuYW1lKTsKLQotICAgIC8qKgotICAgICAqICBTZWxlY3QgZm9ybSBvZiBjb250ZW50LiBTZWUgdGhlICBzY2hlbWUgYXR0cmlidXRlIGRlZmluaXRpb24gaW4gSFRNTAotICAgICAqIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFNjaGVtZSgpOwotICAgIHB1YmxpYyB2b2lkIHNldFNjaGVtZShTdHJpbmcgc2NoZW1lKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTE1vZEVsZW1lbnQuamF2YSBiL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxNb2RFbGVtZW50LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGNmZDk2YTEuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTE1vZEVsZW1lbnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDY0ICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBUaGlzIGZpbGUgaXMgYXZhaWxhYmxlIHVuZGVyIGFuZCBnb3Zlcm5lZCBieSB0aGUgR05VIEdlbmVyYWwgUHVibGljCi0gKiBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqIEhvd2V2ZXIsIHRoZSBmb2xsb3dpbmcgbm90aWNlIGFjY29tcGFuaWVkIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIG9mIHRoaXMKLSAqIGZpbGUgYW5kLCBwZXIgaXRzIHRlcm1zLCBzaG91bGQgbm90IGJlIHJlbW92ZWQ6Ci0gKgotICogQ29weXJpZ2h0IChjKSAyMDAwIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKLSAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAotICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCi0gKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQotICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgotICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgotICogUFVSUE9TRS4gU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlCi0gKiBkZXRhaWxzLgotICovCi0KLXBhY2thZ2Ugb3JnLnczYy5kb20uaHRtbDsKLQotLyoqCi0gKiAgTm90aWNlIG9mIG1vZGlmaWNhdGlvbiB0byBwYXJ0IG9mIGEgZG9jdW1lbnQuIFNlZSB0aGUgICBJTlMgIGFuZCAgREVMCi0gKiBlbGVtZW50IGRlZmluaXRpb25zIGluIEhUTUwgNC4wLgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDAvQ1ItRE9NLUxldmVsLTItMjAwMDA1MTAnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAyIFNwZWNpZmljYXRpb248L2E+LgotICovCi1wdWJsaWMgaW50ZXJmYWNlIEhUTUxNb2RFbGVtZW50IGV4dGVuZHMgSFRNTEVsZW1lbnQgewotICAgIC8qKgotICAgICAqICBBIFVSSSBkZXNpZ25hdGluZyBhIGRvY3VtZW50IHRoYXQgZGVzY3JpYmVzIHRoZSByZWFzb24gZm9yIHRoZSBjaGFuZ2UuCi0gICAgICogU2VlIHRoZSAgY2l0ZSBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldENpdGUoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRDaXRlKFN0cmluZyBjaXRlKTsKLQotICAgIC8qKgotICAgICAqICBUaGUgZGF0ZSBhbmQgdGltZSBvZiB0aGUgY2hhbmdlLiBTZWUgdGhlICBkYXRldGltZSBhdHRyaWJ1dGUgZGVmaW5pdGlvbgotICAgICAqICBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldERhdGVUaW1lKCk7Ci0gICAgcHVibGljIHZvaWQgc2V0RGF0ZVRpbWUoU3RyaW5nIGRhdGVUaW1lKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTE9MaXN0RWxlbWVudC5qYXZhIGIvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTE9MaXN0RWxlbWVudC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3MjhlNzYwLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxPTGlzdEVsZW1lbnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDcwICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBUaGlzIGZpbGUgaXMgYXZhaWxhYmxlIHVuZGVyIGFuZCBnb3Zlcm5lZCBieSB0aGUgR05VIEdlbmVyYWwgUHVibGljCi0gKiBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqIEhvd2V2ZXIsIHRoZSBmb2xsb3dpbmcgbm90aWNlIGFjY29tcGFuaWVkIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIG9mIHRoaXMKLSAqIGZpbGUgYW5kLCBwZXIgaXRzIHRlcm1zLCBzaG91bGQgbm90IGJlIHJlbW92ZWQ6Ci0gKgotICogQ29weXJpZ2h0IChjKSAyMDAwIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKLSAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAotICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCi0gKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQotICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgotICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgotICogUFVSUE9TRS4gU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlCi0gKiBkZXRhaWxzLgotICovCi0KLXBhY2thZ2Ugb3JnLnczYy5kb20uaHRtbDsKLQotLyoqCi0gKiAgT3JkZXJlZCBsaXN0LiBTZWUgdGhlICBPTCBlbGVtZW50IGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gKiA8cD5TZWUgYWxzbyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMC9DUi1ET00tTGV2ZWwtMi0yMDAwMDUxMCc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDIgU3BlY2lmaWNhdGlvbjwvYT4uCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgSFRNTE9MaXN0RWxlbWVudCBleHRlbmRzIEhUTUxFbGVtZW50IHsKLSAgICAvKioKLSAgICAgKiAgUmVkdWNlIHNwYWNpbmcgYmV0d2VlbiBsaXN0IGl0ZW1zLiBTZWUgdGhlICBjb21wYWN0IGF0dHJpYnV0ZQotICAgICAqIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuIFRoaXMgYXR0cmlidXRlIGlzIGRlcHJlY2F0ZWQgaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0Q29tcGFjdCgpOwotICAgIHB1YmxpYyB2b2lkIHNldENvbXBhY3QoYm9vbGVhbiBjb21wYWN0KTsKLQotICAgIC8qKgotICAgICAqICBTdGFydGluZyBzZXF1ZW5jZSBudW1iZXIuIFNlZSB0aGUgIHN0YXJ0IGF0dHJpYnV0ZSBkZWZpbml0aW9uIGluIEhUTUwKLSAgICAgKiA0LjAuIFRoaXMgYXR0cmlidXRlIGlzIGRlcHJlY2F0ZWQgaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRTdGFydCgpOwotICAgIHB1YmxpYyB2b2lkIHNldFN0YXJ0KGludCBzdGFydCk7Ci0KLSAgICAvKioKLSAgICAgKiAgTnVtYmVyaW5nIHN0eWxlLiBTZWUgdGhlICB0eXBlIGF0dHJpYnV0ZSBkZWZpbml0aW9uIGluIEhUTUwgNC4wLiBUaGlzCi0gICAgICogYXR0cmlidXRlIGlzIGRlcHJlY2F0ZWQgaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRUeXBlKCk7Ci0gICAgcHVibGljIHZvaWQgc2V0VHlwZShTdHJpbmcgdHlwZSk7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxPYmplY3RFbGVtZW50LmphdmEgYi9zcmMvb3JnL3czYy9kb20vaHRtbC9IVE1MT2JqZWN0RWxlbWVudC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA5NzIwOTFiLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxPYmplY3RFbGVtZW50LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxODggKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIFRoaXMgZmlsZSBpcyBhdmFpbGFibGUgdW5kZXIgYW5kIGdvdmVybmVkIGJ5IHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKLSAqIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICogSG93ZXZlciwgdGhlIGZvbGxvd2luZyBub3RpY2UgYWNjb21wYW5pZWQgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcwotICogZmlsZSBhbmQsIHBlciBpdHMgdGVybXMsIHNob3VsZCBub3QgYmUgcmVtb3ZlZDoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDAgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKLSAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQotICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCi0gKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKLSAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCi0gKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCi0gKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCi0gKiBQVVJQT1NFLiBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUKLSAqIGRldGFpbHMuCi0gKi8KLQotcGFja2FnZSBvcmcudzNjLmRvbS5odG1sOwotCi1pbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7Ci0KLS8qKgotICogIEdlbmVyaWMgZW1iZWRkZWQgb2JqZWN0LiAgTm90ZS4gSW4gcHJpbmNpcGxlLCBhbGwgcHJvcGVydGllcyBvbiB0aGUgb2JqZWN0Ci0gKiBlbGVtZW50IGFyZSByZWFkLXdyaXRlIGJ1dCBpbiBzb21lIGVudmlyb25tZW50cyBzb21lIHByb3BlcnRpZXMgbWF5IGJlCi0gKiByZWFkLW9ubHkgb25jZSB0aGUgdW5kZXJseWluZyBvYmplY3QgaXMgaW5zdGFudGlhdGVkLiBTZWUgdGhlICBPQkpFQ1QKLSAqIGVsZW1lbnQgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAwL0NSLURPTS1MZXZlbC0yLTIwMDAwNTEwJz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMiBTcGVjaWZpY2F0aW9uPC9hPi4KLSAqLwotcHVibGljIGludGVyZmFjZSBIVE1MT2JqZWN0RWxlbWVudCBleHRlbmRzIEhUTUxFbGVtZW50IHsKLSAgICAvKioKLSAgICAgKiAgUmV0dXJucyB0aGUgPGNvZGU+Rk9STTwvY29kZT4gZWxlbWVudCBjb250YWluaW5nIHRoaXMgY29udHJvbC4gUmV0dXJucwotICAgICAqIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoaXMgY29udHJvbCBpcyBub3Qgd2l0aGluIHRoZSBjb250ZXh0IG9mIGEgZm9ybS4KLSAgICAgKi8KLSAgICBwdWJsaWMgSFRNTEZvcm1FbGVtZW50IGdldEZvcm0oKTsKLQotICAgIC8qKgotICAgICAqICBBcHBsZXQgY2xhc3MgZmlsZS4gU2VlIHRoZSA8Y29kZT5jb2RlPC9jb2RlPiBhdHRyaWJ1dGUgZm9yCi0gICAgICogSFRNTEFwcGxldEVsZW1lbnQuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRDb2RlKCk7Ci0gICAgcHVibGljIHZvaWQgc2V0Q29kZShTdHJpbmcgY29kZSk7Ci0KLSAgICAvKioKLSAgICAgKiAgQWxpZ25zIHRoaXMgb2JqZWN0ICh2ZXJ0aWNhbGx5IG9yIGhvcml6b250YWxseSkgIHdpdGggcmVzcGVjdCB0byBpdHMKLSAgICAgKiBzdXJyb3VuZGluZyB0ZXh0LiBTZWUgdGhlICBhbGlnbiBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAgICAgKiBUaGlzIGF0dHJpYnV0ZSBpcyBkZXByZWNhdGVkIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0QWxpZ24oKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRBbGlnbihTdHJpbmcgYWxpZ24pOwotCi0gICAgLyoqCi0gICAgICogIFNwYWNlLXNlcGFyYXRlZCBsaXN0IG9mIGFyY2hpdmVzLiBTZWUgdGhlICBhcmNoaXZlIGF0dHJpYnV0ZSBkZWZpbml0aW9uCi0gICAgICogIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0QXJjaGl2ZSgpOwotICAgIHB1YmxpYyB2b2lkIHNldEFyY2hpdmUoU3RyaW5nIGFyY2hpdmUpOwotCi0gICAgLyoqCi0gICAgICogIFdpZHRoIG9mIGJvcmRlciBhcm91bmQgdGhlIG9iamVjdC4gU2VlIHRoZSAgYm9yZGVyIGF0dHJpYnV0ZSBkZWZpbml0aW9uCi0gICAgICogIGluIEhUTUwgNC4wLiBUaGlzIGF0dHJpYnV0ZSBpcyBkZXByZWNhdGVkIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Qm9yZGVyKCk7Ci0gICAgcHVibGljIHZvaWQgc2V0Qm9yZGVyKFN0cmluZyBib3JkZXIpOwotCi0gICAgLyoqCi0gICAgICogIEJhc2UgVVJJIGZvciA8Y29kZT5jbGFzc2lkPC9jb2RlPiAsIDxjb2RlPmRhdGE8L2NvZGU+ICwgYW5kCi0gICAgICogPGNvZGU+YXJjaGl2ZTwvY29kZT4gYXR0cmlidXRlcy4gU2VlIHRoZSAgY29kZWJhc2UgYXR0cmlidXRlIGRlZmluaXRpb24KLSAgICAgKiAgaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRDb2RlQmFzZSgpOwotICAgIHB1YmxpYyB2b2lkIHNldENvZGVCYXNlKFN0cmluZyBjb2RlQmFzZSk7Ci0KLSAgICAvKioKLSAgICAgKiAgQ29udGVudCB0eXBlIGZvciBkYXRhIGRvd25sb2FkZWQgdmlhIDxjb2RlPmNsYXNzaWQ8L2NvZGU+IGF0dHJpYnV0ZS4KLSAgICAgKiBTZWUgdGhlICBjb2RldHlwZSBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldENvZGVUeXBlKCk7Ci0gICAgcHVibGljIHZvaWQgc2V0Q29kZVR5cGUoU3RyaW5nIGNvZGVUeXBlKTsKLQotICAgIC8qKgotICAgICAqICBBIFVSSSBzcGVjaWZ5aW5nIHRoZSBsb2NhdGlvbiBvZiB0aGUgb2JqZWN0J3MgZGF0YS4gIFNlZSB0aGUgIGRhdGEKLSAgICAgKiBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldERhdGEoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXREYXRhKFN0cmluZyBkYXRhKTsKLQotICAgIC8qKgotICAgICAqICBEZWNsYXJlIChmb3IgZnV0dXJlIHJlZmVyZW5jZSksIGJ1dCBkbyBub3QgaW5zdGFudGlhdGUsIHRoaXMgb2JqZWN0LgotICAgICAqIFNlZSB0aGUgIGRlY2xhcmUgYXR0cmlidXRlIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0RGVjbGFyZSgpOwotICAgIHB1YmxpYyB2b2lkIHNldERlY2xhcmUoYm9vbGVhbiBkZWNsYXJlKTsKLQotICAgIC8qKgotICAgICAqICBPdmVycmlkZSBoZWlnaHQuIFNlZSB0aGUgIGhlaWdodCBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEhlaWdodCgpOwotICAgIHB1YmxpYyB2b2lkIHNldEhlaWdodChTdHJpbmcgaGVpZ2h0KTsKLQotICAgIC8qKgotICAgICAqICBIb3Jpem9udGFsIHNwYWNlIHRvIHRoZSBsZWZ0IGFuZCByaWdodCBvZiB0aGlzIGltYWdlLCBhcHBsZXQsIG9yCi0gICAgICogb2JqZWN0LiBTZWUgdGhlICBoc3BhY2UgYXR0cmlidXRlIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuIFRoaXMKLSAgICAgKiBhdHRyaWJ1dGUgaXMgZGVwcmVjYXRlZCBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEhzcGFjZSgpOwotICAgIHB1YmxpYyB2b2lkIHNldEhzcGFjZShTdHJpbmcgaHNwYWNlKTsKLQotICAgIC8qKgotICAgICAqICBGb3JtIGNvbnRyb2wgb3Igb2JqZWN0IG5hbWUgd2hlbiBzdWJtaXR0ZWQgd2l0aCBhIGZvcm0uIFNlZSB0aGUgIG5hbWUKLSAgICAgKiBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXROYW1lKFN0cmluZyBuYW1lKTsKLQotICAgIC8qKgotICAgICAqICBNZXNzYWdlIHRvIHJlbmRlciB3aGlsZSBsb2FkaW5nIHRoZSBvYmplY3QuIFNlZSB0aGUgIHN0YW5kYnkgYXR0cmlidXRlCi0gICAgICogZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFN0YW5kYnkoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRTdGFuZGJ5KFN0cmluZyBzdGFuZGJ5KTsKLQotICAgIC8qKgotICAgICAqICBJbmRleCB0aGF0IHJlcHJlc2VudHMgdGhlIGVsZW1lbnQncyBwb3NpdGlvbiBpbiB0aGUgdGFiYmluZyBvcmRlci4gU2VlCi0gICAgICogdGhlICB0YWJpbmRleCBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldFRhYkluZGV4KCk7Ci0gICAgcHVibGljIHZvaWQgc2V0VGFiSW5kZXgoaW50IHRhYkluZGV4KTsKLQotICAgIC8qKgotICAgICAqICBDb250ZW50IHR5cGUgZm9yIGRhdGEgZG93bmxvYWRlZCB2aWEgPGNvZGU+ZGF0YTwvY29kZT4gYXR0cmlidXRlLiBTZWUKLSAgICAgKiB0aGUgIHR5cGUgYXR0cmlidXRlIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRUeXBlKCk7Ci0gICAgcHVibGljIHZvaWQgc2V0VHlwZShTdHJpbmcgdHlwZSk7Ci0KLSAgICAvKioKLSAgICAgKiAgVXNlIGNsaWVudC1zaWRlIGltYWdlIG1hcC4gU2VlIHRoZSAgdXNlbWFwIGF0dHJpYnV0ZSBkZWZpbml0aW9uIGluCi0gICAgICogSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRVc2VNYXAoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRVc2VNYXAoU3RyaW5nIHVzZU1hcCk7Ci0KLSAgICAvKioKLSAgICAgKiAgVmVydGljYWwgc3BhY2UgYWJvdmUgYW5kIGJlbG93IHRoaXMgaW1hZ2UsIGFwcGxldCwgb3Igb2JqZWN0LiBTZWUgdGhlCi0gICAgICogdnNwYWNlIGF0dHJpYnV0ZSBkZWZpbml0aW9uIGluIEhUTUwgNC4wLiBUaGlzIGF0dHJpYnV0ZSBpcyBkZXByZWNhdGVkCi0gICAgICogaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRWc3BhY2UoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRWc3BhY2UoU3RyaW5nIHZzcGFjZSk7Ci0KLSAgICAvKioKLSAgICAgKiAgT3ZlcnJpZGUgd2lkdGguIFNlZSB0aGUgIHdpZHRoIGF0dHJpYnV0ZSBkZWZpbml0aW9uIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0V2lkdGgoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRXaWR0aChTdHJpbmcgd2lkdGgpOwotCi0gICAgLyoqCi0gICAgICogIFRoZSBkb2N1bWVudCB0aGlzIG9iamVjdCBjb250YWlucywgaWYgdGhlcmUgaXMgYW55IGFuZCBpdCBpcwotICAgICAqIGF2YWlsYWJsZSwgb3IgPGNvZGU+bnVsbDwvY29kZT4gb3RoZXJ3aXNlLgotICAgICAqIEBzaW5jZSBET00gTGV2ZWwgMgotICAgICAqLwotICAgIHB1YmxpYyBEb2N1bWVudCBnZXRDb250ZW50RG9jdW1lbnQoKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTE9wdEdyb3VwRWxlbWVudC5qYXZhIGIvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTE9wdEdyb3VwRWxlbWVudC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlZGRkZjM2Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxPcHRHcm91cEVsZW1lbnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDY0ICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBUaGlzIGZpbGUgaXMgYXZhaWxhYmxlIHVuZGVyIGFuZCBnb3Zlcm5lZCBieSB0aGUgR05VIEdlbmVyYWwgUHVibGljCi0gKiBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqIEhvd2V2ZXIsIHRoZSBmb2xsb3dpbmcgbm90aWNlIGFjY29tcGFuaWVkIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIG9mIHRoaXMKLSAqIGZpbGUgYW5kLCBwZXIgaXRzIHRlcm1zLCBzaG91bGQgbm90IGJlIHJlbW92ZWQ6Ci0gKgotICogQ29weXJpZ2h0IChjKSAyMDAwIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKLSAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAotICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCi0gKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQotICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgotICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgotICogUFVSUE9TRS4gU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlCi0gKiBkZXRhaWxzLgotICovCi0KLXBhY2thZ2Ugb3JnLnczYy5kb20uaHRtbDsKLQotLyoqCi0gKiAgR3JvdXAgb3B0aW9ucyB0b2dldGhlciBpbiBsb2dpY2FsIHN1YmRpdmlzaW9ucy4gU2VlIHRoZSAgT1BUR1JPVVAgZWxlbWVudAotICogZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAwL0NSLURPTS1MZXZlbC0yLTIwMDAwNTEwJz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMiBTcGVjaWZpY2F0aW9uPC9hPi4KLSAqLwotcHVibGljIGludGVyZmFjZSBIVE1MT3B0R3JvdXBFbGVtZW50IGV4dGVuZHMgSFRNTEVsZW1lbnQgewotICAgIC8qKgotICAgICAqICBUaGUgY29udHJvbCBpcyB1bmF2YWlsYWJsZSBpbiB0aGlzIGNvbnRleHQuIFNlZSB0aGUgIGRpc2FibGVkCi0gICAgICogYXR0cmlidXRlIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0RGlzYWJsZWQoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXREaXNhYmxlZChib29sZWFuIGRpc2FibGVkKTsKLQotICAgIC8qKgotICAgICAqICBBc3NpZ25zIGEgbGFiZWwgdG8gdGhpcyBvcHRpb24gZ3JvdXAuIFNlZSB0aGUgIGxhYmVsIGF0dHJpYnV0ZQotICAgICAqIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRMYWJlbCgpOwotICAgIHB1YmxpYyB2b2lkIHNldExhYmVsKFN0cmluZyBsYWJlbCk7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxPcHRpb25FbGVtZW50LmphdmEgYi9zcmMvb3JnL3czYy9kb20vaHRtbC9IVE1MT3B0aW9uRWxlbWVudC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyNzM2NTg4Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxPcHRpb25FbGVtZW50LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMDYgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIFRoaXMgZmlsZSBpcyBhdmFpbGFibGUgdW5kZXIgYW5kIGdvdmVybmVkIGJ5IHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKLSAqIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICogSG93ZXZlciwgdGhlIGZvbGxvd2luZyBub3RpY2UgYWNjb21wYW5pZWQgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcwotICogZmlsZSBhbmQsIHBlciBpdHMgdGVybXMsIHNob3VsZCBub3QgYmUgcmVtb3ZlZDoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDAgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKLSAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQotICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCi0gKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKLSAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCi0gKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCi0gKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCi0gKiBQVVJQT1NFLiBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUKLSAqIGRldGFpbHMuCi0gKi8KLQotcGFja2FnZSBvcmcudzNjLmRvbS5odG1sOwotCi0vKioKLSAqICBBIHNlbGVjdGFibGUgY2hvaWNlLiBTZWUgdGhlICBPUFRJT04gZWxlbWVudCBkZWZpbml0aW9uIGluIEhUTUwgNC4wLgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDAvQ1ItRE9NLUxldmVsLTItMjAwMDA1MTAnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAyIFNwZWNpZmljYXRpb248L2E+LgotICovCi1wdWJsaWMgaW50ZXJmYWNlIEhUTUxPcHRpb25FbGVtZW50IGV4dGVuZHMgSFRNTEVsZW1lbnQgewotICAgIC8qKgotICAgICAqICBSZXR1cm5zIHRoZSA8Y29kZT5GT1JNPC9jb2RlPiBlbGVtZW50IGNvbnRhaW5pbmcgdGhpcyBjb250cm9sLiBSZXR1cm5zCi0gICAgICogPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhpcyBjb250cm9sIGlzIG5vdCB3aXRoaW4gdGhlIGNvbnRleHQgb2YgYSBmb3JtLgotICAgICAqLwotICAgIHB1YmxpYyBIVE1MRm9ybUVsZW1lbnQgZ2V0Rm9ybSgpOwotCi0gICAgLyoqCi0gICAgICogIFJlcHJlc2VudHMgdGhlIHZhbHVlIG9mIHRoZSBIVE1MIHNlbGVjdGVkIGF0dHJpYnV0ZS4gVGhlIHZhbHVlIG9mIHRoaXMKLSAgICAgKiBhdHRyaWJ1dGUgZG9lcyBub3QgY2hhbmdlIGlmIHRoZSBzdGF0ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBmb3JtCi0gICAgICogY29udHJvbCwgaW4gYW4gaW50ZXJhY3RpdmUgdXNlciBhZ2VudCwgY2hhbmdlcy4gQ2hhbmdpbmcKLSAgICAgKiA8Y29kZT5kZWZhdWx0U2VsZWN0ZWQ8L2NvZGU+ICwgaG93ZXZlciwgcmVzZXRzIHRoZSBzdGF0ZSBvZiB0aGUgZm9ybQotICAgICAqIGNvbnRyb2wuIFNlZSB0aGUgIHNlbGVjdGVkIGF0dHJpYnV0ZSBkZWZpbml0aW9uIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGdldERlZmF1bHRTZWxlY3RlZCgpOwotICAgIHB1YmxpYyB2b2lkIHNldERlZmF1bHRTZWxlY3RlZChib29sZWFuIGRlZmF1bHRTZWxlY3RlZCk7Ci0KLSAgICAvKioKLSAgICAgKiAgVGhlIHRleHQgY29udGFpbmVkIHdpdGhpbiB0aGUgb3B0aW9uIGVsZW1lbnQuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRUZXh0KCk7Ci0KLSAgICAvKioKLSAgICAgKiAgVGhlIGluZGV4IG9mIHRoaXMgPGNvZGU+T1BUSU9OPC9jb2RlPiBpbiBpdHMgcGFyZW50IDxjb2RlPlNFTEVDVDwvY29kZT4KLSAgICAgKiAgLCBzdGFydGluZyBmcm9tIDAuCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRJbmRleCgpOwotCi0gICAgLyoqCi0gICAgICogIFRoZSBjb250cm9sIGlzIHVuYXZhaWxhYmxlIGluIHRoaXMgY29udGV4dC4gU2VlIHRoZSAgZGlzYWJsZWQKLSAgICAgKiBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXREaXNhYmxlZCgpOwotICAgIHB1YmxpYyB2b2lkIHNldERpc2FibGVkKGJvb2xlYW4gZGlzYWJsZWQpOwotCi0gICAgLyoqCi0gICAgICogIE9wdGlvbiBsYWJlbCBmb3IgdXNlIGluIGhpZXJhcmNoaWNhbCBtZW51cy4gU2VlIHRoZSAgbGFiZWwgYXR0cmlidXRlCi0gICAgICogZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldExhYmVsKCk7Ci0gICAgcHVibGljIHZvaWQgc2V0TGFiZWwoU3RyaW5nIGxhYmVsKTsKLQotICAgIC8qKgotICAgICAqICBSZXByZXNlbnRzIHRoZSBjdXJyZW50IHN0YXRlIG9mIHRoZSBjb3JyZXNwb25kaW5nIGZvcm0gY29udHJvbCwgaW4gYW4KLSAgICAgKiBpbnRlcmFjdGl2ZSB1c2VyIGFnZW50LiBDaGFuZ2luZyB0aGlzIGF0dHJpYnV0ZSBjaGFuZ2VzIHRoZSBzdGF0ZSBvZgotICAgICAqIHRoZSBmb3JtIGNvbnRyb2wsIGJ1dCBkb2VzIG5vdCBjaGFuZ2UgdGhlIHZhbHVlIG9mIHRoZSBIVE1MIHNlbGVjdGVkCi0gICAgICogYXR0cmlidXRlIG9mIHRoZSBlbGVtZW50LgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGdldFNlbGVjdGVkKCk7Ci0gICAgcHVibGljIHZvaWQgc2V0U2VsZWN0ZWQoYm9vbGVhbiBzZWxlY3RlZCk7Ci0KLSAgICAvKioKLSAgICAgKiAgVGhlIGN1cnJlbnQgZm9ybSBjb250cm9sIHZhbHVlLiBTZWUgdGhlICB2YWx1ZSBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbgotICAgICAqIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VmFsdWUoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRWYWx1ZShTdHJpbmcgdmFsdWUpOwotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL3czYy9kb20vaHRtbC9IVE1MUGFyYWdyYXBoRWxlbWVudC5qYXZhIGIvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTFBhcmFncmFwaEVsZW1lbnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYTdkYzVkNi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3czYy9kb20vaHRtbC9IVE1MUGFyYWdyYXBoRWxlbWVudC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTYgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIFRoaXMgZmlsZSBpcyBhdmFpbGFibGUgdW5kZXIgYW5kIGdvdmVybmVkIGJ5IHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKLSAqIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICogSG93ZXZlciwgdGhlIGZvbGxvd2luZyBub3RpY2UgYWNjb21wYW5pZWQgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcwotICogZmlsZSBhbmQsIHBlciBpdHMgdGVybXMsIHNob3VsZCBub3QgYmUgcmVtb3ZlZDoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDAgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKLSAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQotICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCi0gKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKLSAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCi0gKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCi0gKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCi0gKiBQVVJQT1NFLiBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUKLSAqIGRldGFpbHMuCi0gKi8KLQotcGFja2FnZSBvcmcudzNjLmRvbS5odG1sOwotCi0vKioKLSAqICBQYXJhZ3JhcGhzLiBTZWUgdGhlICBQIGVsZW1lbnQgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAwL0NSLURPTS1MZXZlbC0yLTIwMDAwNTEwJz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMiBTcGVjaWZpY2F0aW9uPC9hPi4KLSAqLwotcHVibGljIGludGVyZmFjZSBIVE1MUGFyYWdyYXBoRWxlbWVudCBleHRlbmRzIEhUTUxFbGVtZW50IHsKLSAgICAvKioKLSAgICAgKiAgSG9yaXpvbnRhbCB0ZXh0IGFsaWdubWVudC4gU2VlIHRoZSAgYWxpZ24gYXR0cmlidXRlIGRlZmluaXRpb24gaW4gSFRNTAotICAgICAqIDQuMC4gVGhpcyBhdHRyaWJ1dGUgaXMgZGVwcmVjYXRlZCBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEFsaWduKCk7Ci0gICAgcHVibGljIHZvaWQgc2V0QWxpZ24oU3RyaW5nIGFsaWduKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTFBhcmFtRWxlbWVudC5qYXZhIGIvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTFBhcmFtRWxlbWVudC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2YjE4NDc2Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxQYXJhbUVsZW1lbnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDc5ICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBUaGlzIGZpbGUgaXMgYXZhaWxhYmxlIHVuZGVyIGFuZCBnb3Zlcm5lZCBieSB0aGUgR05VIEdlbmVyYWwgUHVibGljCi0gKiBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqIEhvd2V2ZXIsIHRoZSBmb2xsb3dpbmcgbm90aWNlIGFjY29tcGFuaWVkIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIG9mIHRoaXMKLSAqIGZpbGUgYW5kLCBwZXIgaXRzIHRlcm1zLCBzaG91bGQgbm90IGJlIHJlbW92ZWQ6Ci0gKgotICogQ29weXJpZ2h0IChjKSAyMDAwIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKLSAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAotICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCi0gKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQotICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgotICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgotICogUFVSUE9TRS4gU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlCi0gKiBkZXRhaWxzLgotICovCi0KLXBhY2thZ2Ugb3JnLnczYy5kb20uaHRtbDsKLQotLyoqCi0gKiAgUGFyYW1ldGVycyBmZWQgdG8gdGhlIDxjb2RlPk9CSkVDVDwvY29kZT4gZWxlbWVudC4gU2VlIHRoZSAgUEFSQU0gZWxlbWVudAotICogZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAwL0NSLURPTS1MZXZlbC0yLTIwMDAwNTEwJz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMiBTcGVjaWZpY2F0aW9uPC9hPi4KLSAqLwotcHVibGljIGludGVyZmFjZSBIVE1MUGFyYW1FbGVtZW50IGV4dGVuZHMgSFRNTEVsZW1lbnQgewotICAgIC8qKgotICAgICAqICBUaGUgbmFtZSBvZiBhIHJ1bi10aW1lIHBhcmFtZXRlci4gU2VlIHRoZSAgbmFtZSBhdHRyaWJ1dGUgZGVmaW5pdGlvbgotICAgICAqIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpOwotICAgIHB1YmxpYyB2b2lkIHNldE5hbWUoU3RyaW5nIG5hbWUpOwotCi0gICAgLyoqCi0gICAgICogIENvbnRlbnQgdHlwZSBmb3IgdGhlIDxjb2RlPnZhbHVlPC9jb2RlPiBhdHRyaWJ1dGUgd2hlbgotICAgICAqIDxjb2RlPnZhbHVldHlwZTwvY29kZT4gaGFzIHRoZSB2YWx1ZSAicmVmIi4gU2VlIHRoZSAgdHlwZSBhdHRyaWJ1dGUKLSAgICAgKiBkZWZpbml0aW9uIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VHlwZSgpOwotICAgIHB1YmxpYyB2b2lkIHNldFR5cGUoU3RyaW5nIHR5cGUpOwotCi0gICAgLyoqCi0gICAgICogIFRoZSB2YWx1ZSBvZiBhIHJ1bi10aW1lIHBhcmFtZXRlci4gU2VlIHRoZSAgdmFsdWUgYXR0cmlidXRlIGRlZmluaXRpb24KLSAgICAgKiBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFZhbHVlKCk7Ci0gICAgcHVibGljIHZvaWQgc2V0VmFsdWUoU3RyaW5nIHZhbHVlKTsKLQotICAgIC8qKgotICAgICAqICBJbmZvcm1hdGlvbiBhYm91dCB0aGUgbWVhbmluZyBvZiB0aGUgPGNvZGU+dmFsdWU8L2NvZGU+IGF0dHJpYnV0ZQotICAgICAqIHZhbHVlLiBTZWUgdGhlICB2YWx1ZXR5cGUgYXR0cmlidXRlIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRWYWx1ZVR5cGUoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRWYWx1ZVR5cGUoU3RyaW5nIHZhbHVlVHlwZSk7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxQcmVFbGVtZW50LmphdmEgYi9zcmMvb3JnL3czYy9kb20vaHRtbC9IVE1MUHJlRWxlbWVudC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0MGIxOTlmLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxQcmVFbGVtZW50LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw1NiArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogVGhpcyBmaWxlIGlzIGF2YWlsYWJsZSB1bmRlciBhbmQgZ292ZXJuZWQgYnkgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwotICogTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKiBIb3dldmVyLCB0aGUgZm9sbG93aW5nIG5vdGljZSBhY2NvbXBhbmllZCB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGlzCi0gKiBmaWxlIGFuZCwgcGVyIGl0cyB0ZXJtcywgc2hvdWxkIG5vdCBiZSByZW1vdmVkOgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAotICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCi0gKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKLSAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQotICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKLSAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KLSAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKLSAqIFBVUlBPU0UuIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZQotICogZGV0YWlscy4KLSAqLwotCi1wYWNrYWdlIG9yZy53M2MuZG9tLmh0bWw7Ci0KLS8qKgotICogIFByZWZvcm1hdHRlZCB0ZXh0LiBTZWUgdGhlICBQUkUgZWxlbWVudCBkZWZpbml0aW9uIGluIEhUTUwgNC4wLgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDAvQ1ItRE9NLUxldmVsLTItMjAwMDA1MTAnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAyIFNwZWNpZmljYXRpb248L2E+LgotICovCi1wdWJsaWMgaW50ZXJmYWNlIEhUTUxQcmVFbGVtZW50IGV4dGVuZHMgSFRNTEVsZW1lbnQgewotICAgIC8qKgotICAgICAqICBGaXhlZCB3aWR0aCBmb3IgY29udGVudC4gU2VlIHRoZSAgd2lkdGggYXR0cmlidXRlIGRlZmluaXRpb24gaW4gSFRNTAotICAgICAqIDQuMC4gVGhpcyBhdHRyaWJ1dGUgaXMgZGVwcmVjYXRlZCBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldFdpZHRoKCk7Ci0gICAgcHVibGljIHZvaWQgc2V0V2lkdGgoaW50IHdpZHRoKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTFF1b3RlRWxlbWVudC5qYXZhIGIvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTFF1b3RlRWxlbWVudC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2MWFiZjFmLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxRdW90ZUVsZW1lbnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDU3ICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBUaGlzIGZpbGUgaXMgYXZhaWxhYmxlIHVuZGVyIGFuZCBnb3Zlcm5lZCBieSB0aGUgR05VIEdlbmVyYWwgUHVibGljCi0gKiBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqIEhvd2V2ZXIsIHRoZSBmb2xsb3dpbmcgbm90aWNlIGFjY29tcGFuaWVkIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIG9mIHRoaXMKLSAqIGZpbGUgYW5kLCBwZXIgaXRzIHRlcm1zLCBzaG91bGQgbm90IGJlIHJlbW92ZWQ6Ci0gKgotICogQ29weXJpZ2h0IChjKSAyMDAwIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKLSAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAotICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCi0gKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQotICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgotICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgotICogUFVSUE9TRS4gU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlCi0gKiBkZXRhaWxzLgotICovCi0KLXBhY2thZ2Ugb3JnLnczYy5kb20uaHRtbDsKLQotLyoqCi0gKiAgRm9yIHRoZSA8Y29kZT5RPC9jb2RlPiBhbmQgPGNvZGU+QkxPQ0tRVU9URTwvY29kZT4gZWxlbWVudHMuIFNlZSB0aGUgIFEKLSAqIGVsZW1lbnQgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAwL0NSLURPTS1MZXZlbC0yLTIwMDAwNTEwJz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMiBTcGVjaWZpY2F0aW9uPC9hPi4KLSAqLwotcHVibGljIGludGVyZmFjZSBIVE1MUXVvdGVFbGVtZW50IGV4dGVuZHMgSFRNTEVsZW1lbnQgewotICAgIC8qKgotICAgICAqICBBIFVSSSBkZXNpZ25hdGluZyBhIHNvdXJjZSBkb2N1bWVudCBvciBtZXNzYWdlLiBTZWUgdGhlICBjaXRlCi0gICAgICogYXR0cmlidXRlIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRDaXRlKCk7Ci0gICAgcHVibGljIHZvaWQgc2V0Q2l0ZShTdHJpbmcgY2l0ZSk7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxTY3JpcHRFbGVtZW50LmphdmEgYi9zcmMvb3JnL3czYy9kb20vaHRtbC9IVE1MU2NyaXB0RWxlbWVudC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1MDA0YTQxLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxTY3JpcHRFbGVtZW50LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5NSArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogVGhpcyBmaWxlIGlzIGF2YWlsYWJsZSB1bmRlciBhbmQgZ292ZXJuZWQgYnkgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwotICogTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKiBIb3dldmVyLCB0aGUgZm9sbG93aW5nIG5vdGljZSBhY2NvbXBhbmllZCB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGlzCi0gKiBmaWxlIGFuZCwgcGVyIGl0cyB0ZXJtcywgc2hvdWxkIG5vdCBiZSByZW1vdmVkOgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAotICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCi0gKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKLSAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQotICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKLSAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KLSAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKLSAqIFBVUlBPU0UuIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZQotICogZGV0YWlscy4KLSAqLwotCi1wYWNrYWdlIG9yZy53M2MuZG9tLmh0bWw7Ci0KLS8qKgotICogIFNjcmlwdCBzdGF0ZW1lbnRzLiBTZWUgdGhlICBTQ1JJUFQgZWxlbWVudCBkZWZpbml0aW9uIGluIEhUTUwgNC4wLgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDAvQ1ItRE9NLUxldmVsLTItMjAwMDA1MTAnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAyIFNwZWNpZmljYXRpb248L2E+LgotICovCi1wdWJsaWMgaW50ZXJmYWNlIEhUTUxTY3JpcHRFbGVtZW50IGV4dGVuZHMgSFRNTEVsZW1lbnQgewotICAgIC8qKgotICAgICAqICBUaGUgc2NyaXB0IGNvbnRlbnQgb2YgdGhlIGVsZW1lbnQuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRUZXh0KCk7Ci0gICAgcHVibGljIHZvaWQgc2V0VGV4dChTdHJpbmcgdGV4dCk7Ci0KLSAgICAvKioKLSAgICAgKiAgUmVzZXJ2ZWQgZm9yIGZ1dHVyZSB1c2UuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRIdG1sRm9yKCk7Ci0gICAgcHVibGljIHZvaWQgc2V0SHRtbEZvcihTdHJpbmcgaHRtbEZvcik7Ci0KLSAgICAvKioKLSAgICAgKiAgUmVzZXJ2ZWQgZm9yIGZ1dHVyZSB1c2UuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRFdmVudCgpOwotICAgIHB1YmxpYyB2b2lkIHNldEV2ZW50KFN0cmluZyBldmVudCk7Ci0KLSAgICAvKioKLSAgICAgKiAgVGhlIGNoYXJhY3RlciBlbmNvZGluZyBvZiB0aGUgbGlua2VkIHJlc291cmNlLiBTZWUgdGhlICBjaGFyc2V0Ci0gICAgICogYXR0cmlidXRlIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRDaGFyc2V0KCk7Ci0gICAgcHVibGljIHZvaWQgc2V0Q2hhcnNldChTdHJpbmcgY2hhcnNldCk7Ci0KLSAgICAvKioKLSAgICAgKiAgSW5kaWNhdGVzIHRoYXQgdGhlIHVzZXIgYWdlbnQgY2FuIGRlZmVyIHByb2Nlc3Npbmcgb2YgdGhlIHNjcmlwdC4gIFNlZQotICAgICAqIHRoZSAgZGVmZXIgYXR0cmlidXRlIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0RGVmZXIoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXREZWZlcihib29sZWFuIGRlZmVyKTsKLQotICAgIC8qKgotICAgICAqICBVUkkgZGVzaWduYXRpbmcgYW4gZXh0ZXJuYWwgc2NyaXB0LiBTZWUgdGhlICBzcmMgYXR0cmlidXRlIGRlZmluaXRpb24KLSAgICAgKiBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFNyYygpOwotICAgIHB1YmxpYyB2b2lkIHNldFNyYyhTdHJpbmcgc3JjKTsKLQotICAgIC8qKgotICAgICAqICBUaGUgY29udGVudCB0eXBlIG9mIHRoZSBzY3JpcHQgbGFuZ3VhZ2UuIFNlZSB0aGUgIHR5cGUgYXR0cmlidXRlCi0gICAgICogZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFR5cGUoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRUeXBlKFN0cmluZyB0eXBlKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTFNlbGVjdEVsZW1lbnQuamF2YSBiL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxTZWxlY3RFbGVtZW50LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDk2MTFjY2EuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTFNlbGVjdEVsZW1lbnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE2MiArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogVGhpcyBmaWxlIGlzIGF2YWlsYWJsZSB1bmRlciBhbmQgZ292ZXJuZWQgYnkgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwotICogTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKiBIb3dldmVyLCB0aGUgZm9sbG93aW5nIG5vdGljZSBhY2NvbXBhbmllZCB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGlzCi0gKiBmaWxlIGFuZCwgcGVyIGl0cyB0ZXJtcywgc2hvdWxkIG5vdCBiZSByZW1vdmVkOgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAotICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCi0gKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKLSAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQotICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKLSAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KLSAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKLSAqIFBVUlBPU0UuIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZQotICogZGV0YWlscy4KLSAqLwotCi1wYWNrYWdlIG9yZy53M2MuZG9tLmh0bWw7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5ET01FeGNlcHRpb247Ci0KLS8qKgotICogIFRoZSBzZWxlY3QgZWxlbWVudCBhbGxvd3MgdGhlIHNlbGVjdGlvbiBvZiBhbiBvcHRpb24uIFRoZSBjb250YWluZWQKLSAqIG9wdGlvbnMgY2FuIGJlIGRpcmVjdGx5IGFjY2Vzc2VkIHRocm91Z2ggdGhlIHNlbGVjdCBlbGVtZW50IGFzIGEKLSAqIGNvbGxlY3Rpb24uIFNlZSB0aGUgIFNFTEVDVCBlbGVtZW50IGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gKiA8cD5TZWUgYWxzbyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMC9DUi1ET00tTGV2ZWwtMi0yMDAwMDUxMCc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDIgU3BlY2lmaWNhdGlvbjwvYT4uCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgSFRNTFNlbGVjdEVsZW1lbnQgZXh0ZW5kcyBIVE1MRWxlbWVudCB7Ci0gICAgLyoqCi0gICAgICogIFRoZSB0eXBlIG9mIHRoaXMgZm9ybSBjb250cm9sLiBUaGlzIGlzIHRoZSBzdHJpbmcgInNlbGVjdC1tdWx0aXBsZSIKLSAgICAgKiB3aGVuIHRoZSBtdWx0aXBsZSBhdHRyaWJ1dGUgaXMgPGNvZGU+dHJ1ZTwvY29kZT4gYW5kIHRoZSBzdHJpbmcKLSAgICAgKiAic2VsZWN0LW9uZSIgd2hlbiA8Y29kZT5mYWxzZTwvY29kZT4gLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VHlwZSgpOwotCi0gICAgLyoqCi0gICAgICogIFRoZSBvcmRpbmFsIGluZGV4IG9mIHRoZSBzZWxlY3RlZCBvcHRpb24sIHN0YXJ0aW5nIGZyb20gMC4gVGhlIHZhbHVlCi0gICAgICogLTEgaXMgcmV0dXJuZWQgaWYgbm8gZWxlbWVudCBpcyBzZWxlY3RlZC4gSWYgbXVsdGlwbGUgb3B0aW9ucyBhcmUKLSAgICAgKiBzZWxlY3RlZCwgdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBzZWxlY3RlZCBvcHRpb24gaXMgcmV0dXJuZWQuCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRTZWxlY3RlZEluZGV4KCk7Ci0gICAgcHVibGljIHZvaWQgc2V0U2VsZWN0ZWRJbmRleChpbnQgc2VsZWN0ZWRJbmRleCk7Ci0KLSAgICAvKioKLSAgICAgKiAgVGhlIGN1cnJlbnQgZm9ybSBjb250cm9sIHZhbHVlLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VmFsdWUoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRWYWx1ZShTdHJpbmcgdmFsdWUpOwotCi0gICAgLyoqCi0gICAgICogIFRoZSBudW1iZXIgb2Ygb3B0aW9ucyBpbiB0aGlzIDxjb2RlPlNFTEVDVDwvY29kZT4gLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0TGVuZ3RoKCk7Ci0KLSAgICAvKioKLSAgICAgKiAgUmV0dXJucyB0aGUgPGNvZGU+Rk9STTwvY29kZT4gZWxlbWVudCBjb250YWluaW5nIHRoaXMgY29udHJvbC4gUmV0dXJucwotICAgICAqIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoaXMgY29udHJvbCBpcyBub3Qgd2l0aGluIHRoZSBjb250ZXh0IG9mIGEgZm9ybS4KLSAgICAgKi8KLSAgICBwdWJsaWMgSFRNTEZvcm1FbGVtZW50IGdldEZvcm0oKTsKLQotICAgIC8qKgotICAgICAqICBUaGUgY29sbGVjdGlvbiBvZiA8Y29kZT5PUFRJT048L2NvZGU+IGVsZW1lbnRzIGNvbnRhaW5lZCBieSB0aGlzCi0gICAgICogZWxlbWVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgSFRNTENvbGxlY3Rpb24gZ2V0T3B0aW9ucygpOwotCi0gICAgLyoqCi0gICAgICogIFRoZSBjb250cm9sIGlzIHVuYXZhaWxhYmxlIGluIHRoaXMgY29udGV4dC4gU2VlIHRoZSAgZGlzYWJsZWQKLSAgICAgKiBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXREaXNhYmxlZCgpOwotICAgIHB1YmxpYyB2b2lkIHNldERpc2FibGVkKGJvb2xlYW4gZGlzYWJsZWQpOwotCi0gICAgLyoqCi0gICAgICogIElmIHRydWUsIG11bHRpcGxlIDxjb2RlPk9QVElPTjwvY29kZT4gZWxlbWVudHMgbWF5ICBiZSBzZWxlY3RlZCBpbgotICAgICAqIHRoaXMgPGNvZGU+U0VMRUNUPC9jb2RlPiAuIFNlZSB0aGUgIG11bHRpcGxlIGF0dHJpYnV0ZSBkZWZpbml0aW9uIGluCi0gICAgICogSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0TXVsdGlwbGUoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRNdWx0aXBsZShib29sZWFuIG11bHRpcGxlKTsKLQotICAgIC8qKgotICAgICAqICBGb3JtIGNvbnRyb2wgb3Igb2JqZWN0IG5hbWUgd2hlbiBzdWJtaXR0ZWQgd2l0aCBhIGZvcm0uIFNlZSB0aGUgIG5hbWUKLSAgICAgKiBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXROYW1lKFN0cmluZyBuYW1lKTsKLQotICAgIC8qKgotICAgICAqICBOdW1iZXIgb2YgdmlzaWJsZSByb3dzLiBTZWUgdGhlICBzaXplIGF0dHJpYnV0ZSBkZWZpbml0aW9uIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0U2l6ZSgpOwotICAgIHB1YmxpYyB2b2lkIHNldFNpemUoaW50IHNpemUpOwotCi0gICAgLyoqCi0gICAgICogIEluZGV4IHRoYXQgcmVwcmVzZW50cyB0aGUgZWxlbWVudCdzIHBvc2l0aW9uIGluIHRoZSB0YWJiaW5nIG9yZGVyLiBTZWUKLSAgICAgKiB0aGUgIHRhYmluZGV4IGF0dHJpYnV0ZSBkZWZpbml0aW9uIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0VGFiSW5kZXgoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRUYWJJbmRleChpbnQgdGFiSW5kZXgpOwotCi0gICAgLyoqCi0gICAgICogIEFkZCBhIG5ldyBlbGVtZW50IHRvIHRoZSBjb2xsZWN0aW9uIG9mIDxjb2RlPk9QVElPTjwvY29kZT4gZWxlbWVudHMKLSAgICAgKiBmb3IgdGhpcyA8Y29kZT5TRUxFQ1Q8L2NvZGU+IC4gVGhpcyBtZXRob2QgaXMgdGhlIGVxdWl2YWxlbnQgb2YgdGhlCi0gICAgICogPGNvZGU+YXBwZW5kQ2hpbGQ8L2NvZGU+IG1ldGhvZCBvZiB0aGUgPGNvZGU+Tm9kZTwvY29kZT4gaW50ZXJmYWNlIGlmCi0gICAgICogdGhlIDxjb2RlPmJlZm9yZTwvY29kZT4gcGFyYW1ldGVyIGlzIDxjb2RlPm51bGw8L2NvZGU+IC4gSXQgaXMKLSAgICAgKiBlcXVpdmFsZW50IHRvIHRoZSA8Y29kZT5pbnNlcnRCZWZvcmU8L2NvZGU+IG1ldGhvZCBvbiB0aGUgcGFyZW50IG9mCi0gICAgICogPGNvZGU+YmVmb3JlPC9jb2RlPiBpbiBhbGwgb3RoZXIgY2FzZXMuCi0gICAgICogQHBhcmFtIGVsZW1lbnQgIFRoZSBlbGVtZW50IHRvIGFkZC4KLSAgICAgKiBAcGFyYW0gYmVmb3JlICBUaGUgZWxlbWVudCB0byBpbnNlcnQgYmVmb3JlLCBvciA8Y29kZT5udWxsPC9jb2RlPiBmb3IKLSAgICAgKiAgIHRoZSB0YWlsIG9mIHRoZSBsaXN0LgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICAgTk9UX0ZPVU5EX0VSUjogUmFpc2VkIGlmIDxjb2RlPmJlZm9yZTwvY29kZT4gaXMgbm90IGEgZGVzY2VuZGFudCBvZgotICAgICAqICAgdGhlIDxjb2RlPlNFTEVDVDwvY29kZT4gZWxlbWVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBhZGQoSFRNTEVsZW1lbnQgZWxlbWVudCwKLSAgICAgICAgICAgICAgICAgICAgSFRNTEVsZW1lbnQgYmVmb3JlKQotICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogIFJlbW92ZSBhbiBlbGVtZW50IGZyb20gdGhlIGNvbGxlY3Rpb24gb2YgPGNvZGU+T1BUSU9OPC9jb2RlPiBlbGVtZW50cwotICAgICAqIGZvciB0aGlzIDxjb2RlPlNFTEVDVDwvY29kZT4gLiBEb2VzIG5vdGhpbmcgaWYgbm8gZWxlbWVudCBoYXMgdGhlIGdpdmVuCi0gICAgICogIGluZGV4LgotICAgICAqIEBwYXJhbSBpbmRleCAgVGhlIGluZGV4IG9mIHRoZSBpdGVtIHRvIHJlbW92ZSwgc3RhcnRpbmcgZnJvbSAwLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHJlbW92ZShpbnQgaW5kZXgpOwotCi0gICAgLyoqCi0gICAgICogIFJlbW92ZXMga2V5Ym9hcmQgZm9jdXMgZnJvbSB0aGlzIGVsZW1lbnQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgYmx1cigpOwotCi0gICAgLyoqCi0gICAgICogIEdpdmVzIGtleWJvYXJkIGZvY3VzIHRvIHRoaXMgZWxlbWVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBmb2N1cygpOwotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL3czYy9kb20vaHRtbC9IVE1MU3R5bGVFbGVtZW50LmphdmEgYi9zcmMvb3JnL3czYy9kb20vaHRtbC9IVE1MU3R5bGVFbGVtZW50LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGQ4MTFlODUuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTFN0eWxlRWxlbWVudC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNzAgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIFRoaXMgZmlsZSBpcyBhdmFpbGFibGUgdW5kZXIgYW5kIGdvdmVybmVkIGJ5IHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKLSAqIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICogSG93ZXZlciwgdGhlIGZvbGxvd2luZyBub3RpY2UgYWNjb21wYW5pZWQgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcwotICogZmlsZSBhbmQsIHBlciBpdHMgdGVybXMsIHNob3VsZCBub3QgYmUgcmVtb3ZlZDoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDAgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKLSAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQotICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCi0gKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKLSAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCi0gKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCi0gKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCi0gKiBQVVJQT1NFLiBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUKLSAqIGRldGFpbHMuCi0gKi8KLQotcGFja2FnZSBvcmcudzNjLmRvbS5odG1sOwotCi0vKioKLSAqICBTdHlsZSBpbmZvcm1hdGlvbi4gU2VlIHRoZSAgU1RZTEUgZWxlbWVudCBkZWZpbml0aW9uIGluIEhUTUwgNC4wLCB0aGUKLSAqIG1vZHVsZSBhbmQgdGhlIDxjb2RlPkxpbmtTdHlsZTwvY29kZT4gaW50ZXJmYWNlIGluIHRoZSAgbW9kdWxlLgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDAvQ1ItRE9NLUxldmVsLTItMjAwMDA1MTAnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAyIFNwZWNpZmljYXRpb248L2E+LgotICovCi1wdWJsaWMgaW50ZXJmYWNlIEhUTUxTdHlsZUVsZW1lbnQgZXh0ZW5kcyBIVE1MRWxlbWVudCB7Ci0gICAgLyoqCi0gICAgICogIEVuYWJsZXMvZGlzYWJsZXMgdGhlIHN0eWxlIHNoZWV0LgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGdldERpc2FibGVkKCk7Ci0gICAgcHVibGljIHZvaWQgc2V0RGlzYWJsZWQoYm9vbGVhbiBkaXNhYmxlZCk7Ci0KLSAgICAvKioKLSAgICAgKiAgRGVzaWduZWQgZm9yIHVzZSB3aXRoIG9uZSBvciBtb3JlIHRhcmdldCBtZWRpYS4gU2VlIHRoZSAgbWVkaWEKLSAgICAgKiBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE1lZGlhKCk7Ci0gICAgcHVibGljIHZvaWQgc2V0TWVkaWEoU3RyaW5nIG1lZGlhKTsKLQotICAgIC8qKgotICAgICAqICBUaGUgY29udGVudCB0eXBlIHBmIHRoZSBzdHlsZSBzaGVldCBsYW5ndWFnZS4gU2VlIHRoZSAgdHlwZSBhdHRyaWJ1dGUKLSAgICAgKiBkZWZpbml0aW9uIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VHlwZSgpOwotICAgIHB1YmxpYyB2b2lkIHNldFR5cGUoU3RyaW5nIHR5cGUpOwotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL3czYy9kb20vaHRtbC9IVE1MVGFibGVDYXB0aW9uRWxlbWVudC5qYXZhIGIvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTFRhYmxlQ2FwdGlvbkVsZW1lbnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYjgwMDEzNy4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3czYy9kb20vaHRtbC9IVE1MVGFibGVDYXB0aW9uRWxlbWVudC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTYgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIFRoaXMgZmlsZSBpcyBhdmFpbGFibGUgdW5kZXIgYW5kIGdvdmVybmVkIGJ5IHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKLSAqIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICogSG93ZXZlciwgdGhlIGZvbGxvd2luZyBub3RpY2UgYWNjb21wYW5pZWQgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcwotICogZmlsZSBhbmQsIHBlciBpdHMgdGVybXMsIHNob3VsZCBub3QgYmUgcmVtb3ZlZDoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDAgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKLSAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQotICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCi0gKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKLSAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCi0gKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCi0gKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCi0gKiBQVVJQT1NFLiBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUKLSAqIGRldGFpbHMuCi0gKi8KLQotcGFja2FnZSBvcmcudzNjLmRvbS5odG1sOwotCi0vKioKLSAqICBUYWJsZSBjYXB0aW9uIFNlZSB0aGUgIENBUFRJT04gZWxlbWVudCBkZWZpbml0aW9uIGluIEhUTUwgNC4wLgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDAvQ1ItRE9NLUxldmVsLTItMjAwMDA1MTAnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAyIFNwZWNpZmljYXRpb248L2E+LgotICovCi1wdWJsaWMgaW50ZXJmYWNlIEhUTUxUYWJsZUNhcHRpb25FbGVtZW50IGV4dGVuZHMgSFRNTEVsZW1lbnQgewotICAgIC8qKgotICAgICAqICBDYXB0aW9uIGFsaWdubWVudCB3aXRoIHJlc3BlY3QgdG8gdGhlIHRhYmxlLiBTZWUgdGhlICBhbGlnbiBhdHRyaWJ1dGUKLSAgICAgKiBkZWZpbml0aW9uIGluIEhUTUwgNC4wLiBUaGlzIGF0dHJpYnV0ZSBpcyBkZXByZWNhdGVkIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0QWxpZ24oKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRBbGlnbihTdHJpbmcgYWxpZ24pOwotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL3czYy9kb20vaHRtbC9IVE1MVGFibGVDZWxsRWxlbWVudC5qYXZhIGIvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTFRhYmxlQ2VsbEVsZW1lbnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYjdkZWJiZi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3czYy9kb20vaHRtbC9IVE1MVGFibGVDZWxsRWxlbWVudC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTU0ICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBUaGlzIGZpbGUgaXMgYXZhaWxhYmxlIHVuZGVyIGFuZCBnb3Zlcm5lZCBieSB0aGUgR05VIEdlbmVyYWwgUHVibGljCi0gKiBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqIEhvd2V2ZXIsIHRoZSBmb2xsb3dpbmcgbm90aWNlIGFjY29tcGFuaWVkIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIG9mIHRoaXMKLSAqIGZpbGUgYW5kLCBwZXIgaXRzIHRlcm1zLCBzaG91bGQgbm90IGJlIHJlbW92ZWQ6Ci0gKgotICogQ29weXJpZ2h0IChjKSAyMDAwIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKLSAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAotICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCi0gKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQotICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgotICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgotICogUFVSUE9TRS4gU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlCi0gKiBkZXRhaWxzLgotICovCi0KLXBhY2thZ2Ugb3JnLnczYy5kb20uaHRtbDsKLQotLyoqCi0gKiAgVGhlIG9iamVjdCB1c2VkIHRvIHJlcHJlc2VudCB0aGUgPGNvZGU+VEg8L2NvZGU+IGFuZCA8Y29kZT5URDwvY29kZT4KLSAqIGVsZW1lbnRzLiBTZWUgdGhlICBURCBlbGVtZW50IGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gKiA8cD5TZWUgYWxzbyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMC9DUi1ET00tTGV2ZWwtMi0yMDAwMDUxMCc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDIgU3BlY2lmaWNhdGlvbjwvYT4uCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgSFRNTFRhYmxlQ2VsbEVsZW1lbnQgZXh0ZW5kcyBIVE1MRWxlbWVudCB7Ci0gICAgLyoqCi0gICAgICogIFRoZSBpbmRleCBvZiB0aGlzIGNlbGwgaW4gdGhlIHJvdywgc3RhcnRpbmcgZnJvbSAwLiBUaGlzIGluZGV4IGlzIGluCi0gICAgICogZG9jdW1lbnQgdHJlZSBvcmRlciBhbmQgbm90IGRpc3BsYXkgb3JkZXIuCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRDZWxsSW5kZXgoKTsKLQotICAgIC8qKgotICAgICAqICBBYmJyZXZpYXRpb24gZm9yIGhlYWRlciBjZWxscy4gU2VlIHRoZSAgYWJiciBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbgotICAgICAqIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0QWJicigpOwotICAgIHB1YmxpYyB2b2lkIHNldEFiYnIoU3RyaW5nIGFiYnIpOwotCi0gICAgLyoqCi0gICAgICogIEhvcml6b250YWwgYWxpZ25tZW50IG9mIGRhdGEgaW4gY2VsbC4gU2VlIHRoZSAgYWxpZ24gYXR0cmlidXRlCi0gICAgICogZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEFsaWduKCk7Ci0gICAgcHVibGljIHZvaWQgc2V0QWxpZ24oU3RyaW5nIGFsaWduKTsKLQotICAgIC8qKgotICAgICAqICBOYW1lcyBncm91cCBvZiByZWxhdGVkIGhlYWRlcnMuIFNlZSB0aGUgIGF4aXMgYXR0cmlidXRlIGRlZmluaXRpb24gaW4KLSAgICAgKiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEF4aXMoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRBeGlzKFN0cmluZyBheGlzKTsKLQotICAgIC8qKgotICAgICAqICBDZWxsIGJhY2tncm91bmQgY29sb3IuIFNlZSB0aGUgIGJnY29sb3IgYXR0cmlidXRlIGRlZmluaXRpb24gaW4gSFRNTAotICAgICAqIDQuMC4gVGhpcyBhdHRyaWJ1dGUgaXMgZGVwcmVjYXRlZCBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEJnQ29sb3IoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRCZ0NvbG9yKFN0cmluZyBiZ0NvbG9yKTsKLQotICAgIC8qKgotICAgICAqICBBbGlnbm1lbnQgY2hhcmFjdGVyIGZvciBjZWxscyBpbiBhIGNvbHVtbi4gU2VlIHRoZSAgY2hhciBhdHRyaWJ1dGUKLSAgICAgKiBkZWZpbml0aW9uIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q2goKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRDaChTdHJpbmcgY2gpOwotCi0gICAgLyoqCi0gICAgICogIE9mZnNldCBvZiBhbGlnbm1lbnQgY2hhcmFjdGVyLiBTZWUgdGhlICBjaGFyb2ZmIGF0dHJpYnV0ZSBkZWZpbml0aW9uCi0gICAgICogaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRDaE9mZigpOwotICAgIHB1YmxpYyB2b2lkIHNldENoT2ZmKFN0cmluZyBjaE9mZik7Ci0KLSAgICAvKioKLSAgICAgKiAgTnVtYmVyIG9mIGNvbHVtbnMgc3Bhbm5lZCBieSBjZWxsLiBTZWUgdGhlICBjb2xzcGFuIGF0dHJpYnV0ZQotICAgICAqIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRDb2xTcGFuKCk7Ci0gICAgcHVibGljIHZvaWQgc2V0Q29sU3BhbihpbnQgY29sU3Bhbik7Ci0KLSAgICAvKioKLSAgICAgKiAgTGlzdCBvZiA8Y29kZT5pZDwvY29kZT4gYXR0cmlidXRlIHZhbHVlcyBmb3IgaGVhZGVyIGNlbGxzLiBTZWUgdGhlCi0gICAgICogaGVhZGVycyBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEhlYWRlcnMoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRIZWFkZXJzKFN0cmluZyBoZWFkZXJzKTsKLQotICAgIC8qKgotICAgICAqICBDZWxsIGhlaWdodC4gU2VlIHRoZSAgaGVpZ2h0IGF0dHJpYnV0ZSBkZWZpbml0aW9uIGluIEhUTUwgNC4wLiBUaGlzCi0gICAgICogYXR0cmlidXRlIGlzIGRlcHJlY2F0ZWQgaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRIZWlnaHQoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRIZWlnaHQoU3RyaW5nIGhlaWdodCk7Ci0KLSAgICAvKioKLSAgICAgKiAgU3VwcHJlc3Mgd29yZCB3cmFwcGluZy4gU2VlIHRoZSAgbm93cmFwIGF0dHJpYnV0ZSBkZWZpbml0aW9uIGluIEhUTUwKLSAgICAgKiA0LjAuIFRoaXMgYXR0cmlidXRlIGlzIGRlcHJlY2F0ZWQgaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0Tm9XcmFwKCk7Ci0gICAgcHVibGljIHZvaWQgc2V0Tm9XcmFwKGJvb2xlYW4gbm9XcmFwKTsKLQotICAgIC8qKgotICAgICAqICBOdW1iZXIgb2Ygcm93cyBzcGFubmVkIGJ5IGNlbGwuIFNlZSB0aGUgIHJvd3NwYW4gYXR0cmlidXRlIGRlZmluaXRpb24KLSAgICAgKiBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldFJvd1NwYW4oKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRSb3dTcGFuKGludCByb3dTcGFuKTsKLQotICAgIC8qKgotICAgICAqICBTY29wZSBjb3ZlcmVkIGJ5IGhlYWRlciBjZWxscy4gU2VlIHRoZSAgc2NvcGUgYXR0cmlidXRlIGRlZmluaXRpb24gaW4KLSAgICAgKiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFNjb3BlKCk7Ci0gICAgcHVibGljIHZvaWQgc2V0U2NvcGUoU3RyaW5nIHNjb3BlKTsKLQotICAgIC8qKgotICAgICAqICBWZXJ0aWNhbCBhbGlnbm1lbnQgb2YgZGF0YSBpbiBjZWxsLiBTZWUgdGhlICB2YWxpZ24gYXR0cmlidXRlCi0gICAgICogZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFZBbGlnbigpOwotICAgIHB1YmxpYyB2b2lkIHNldFZBbGlnbihTdHJpbmcgdkFsaWduKTsKLQotICAgIC8qKgotICAgICAqICBDZWxsIHdpZHRoLiBTZWUgdGhlICB3aWR0aCBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4gVGhpcwotICAgICAqIGF0dHJpYnV0ZSBpcyBkZXByZWNhdGVkIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0V2lkdGgoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRXaWR0aChTdHJpbmcgd2lkdGgpOwotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL3czYy9kb20vaHRtbC9IVE1MVGFibGVDb2xFbGVtZW50LmphdmEgYi9zcmMvb3JnL3czYy9kb20vaHRtbC9IVE1MVGFibGVDb2xFbGVtZW50LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGQ3ZWNlMGYuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTFRhYmxlQ29sRWxlbWVudC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTEgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIFRoaXMgZmlsZSBpcyBhdmFpbGFibGUgdW5kZXIgYW5kIGdvdmVybmVkIGJ5IHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKLSAqIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICogSG93ZXZlciwgdGhlIGZvbGxvd2luZyBub3RpY2UgYWNjb21wYW5pZWQgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcwotICogZmlsZSBhbmQsIHBlciBpdHMgdGVybXMsIHNob3VsZCBub3QgYmUgcmVtb3ZlZDoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDAgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKLSAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQotICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCi0gKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKLSAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCi0gKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCi0gKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCi0gKiBQVVJQT1NFLiBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUKLSAqIGRldGFpbHMuCi0gKi8KLQotcGFja2FnZSBvcmcudzNjLmRvbS5odG1sOwotCi0vKioKLSAqICBSZWdyb3VwcyB0aGUgPGNvZGU+Q09MPC9jb2RlPiBhbmQgPGNvZGU+Q09MR1JPVVA8L2NvZGU+IGVsZW1lbnRzLiBTZWUgdGhlCi0gKiBDT0wgZWxlbWVudCBkZWZpbml0aW9uIGluIEhUTUwgNC4wLgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDAvQ1ItRE9NLUxldmVsLTItMjAwMDA1MTAnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAyIFNwZWNpZmljYXRpb248L2E+LgotICovCi1wdWJsaWMgaW50ZXJmYWNlIEhUTUxUYWJsZUNvbEVsZW1lbnQgZXh0ZW5kcyBIVE1MRWxlbWVudCB7Ci0gICAgLyoqCi0gICAgICogIEhvcml6b250YWwgYWxpZ25tZW50IG9mIGNlbGwgZGF0YSBpbiBjb2x1bW4uIFNlZSB0aGUgIGFsaWduIGF0dHJpYnV0ZQotICAgICAqIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRBbGlnbigpOwotICAgIHB1YmxpYyB2b2lkIHNldEFsaWduKFN0cmluZyBhbGlnbik7Ci0KLSAgICAvKioKLSAgICAgKiAgQWxpZ25tZW50IGNoYXJhY3RlciBmb3IgY2VsbHMgaW4gYSBjb2x1bW4uIFNlZSB0aGUgIGNoYXIgYXR0cmlidXRlCi0gICAgICogZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldENoKCk7Ci0gICAgcHVibGljIHZvaWQgc2V0Q2goU3RyaW5nIGNoKTsKLQotICAgIC8qKgotICAgICAqICBPZmZzZXQgb2YgYWxpZ25tZW50IGNoYXJhY3Rlci4gU2VlIHRoZSAgY2hhcm9mZiBhdHRyaWJ1dGUgZGVmaW5pdGlvbgotICAgICAqIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q2hPZmYoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRDaE9mZihTdHJpbmcgY2hPZmYpOwotCi0gICAgLyoqCi0gICAgICogIEluZGljYXRlcyB0aGUgbnVtYmVyIG9mIGNvbHVtbnMgaW4gYSBncm91cCBvciBhZmZlY3RlZCBieSBhIGdyb3VwaW5nLgotICAgICAqIFNlZSB0aGUgIHNwYW4gYXR0cmlidXRlIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRTcGFuKCk7Ci0gICAgcHVibGljIHZvaWQgc2V0U3BhbihpbnQgc3Bhbik7Ci0KLSAgICAvKioKLSAgICAgKiAgVmVydGljYWwgYWxpZ25tZW50IG9mIGNlbGwgZGF0YSBpbiBjb2x1bW4uIFNlZSB0aGUgIHZhbGlnbiBhdHRyaWJ1dGUKLSAgICAgKiBkZWZpbml0aW9uIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VkFsaWduKCk7Ci0gICAgcHVibGljIHZvaWQgc2V0VkFsaWduKFN0cmluZyB2QWxpZ24pOwotCi0gICAgLyoqCi0gICAgICogIERlZmF1bHQgY29sdW1uIHdpZHRoLiBTZWUgdGhlICB3aWR0aCBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFdpZHRoKCk7Ci0gICAgcHVibGljIHZvaWQgc2V0V2lkdGgoU3RyaW5nIHdpZHRoKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTFRhYmxlRWxlbWVudC5qYXZhIGIvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTFRhYmxlRWxlbWVudC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmNTdkNTFjLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxUYWJsZUVsZW1lbnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIxNyArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogVGhpcyBmaWxlIGlzIGF2YWlsYWJsZSB1bmRlciBhbmQgZ292ZXJuZWQgYnkgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwotICogTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKiBIb3dldmVyLCB0aGUgZm9sbG93aW5nIG5vdGljZSBhY2NvbXBhbmllZCB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGlzCi0gKiBmaWxlIGFuZCwgcGVyIGl0cyB0ZXJtcywgc2hvdWxkIG5vdCBiZSByZW1vdmVkOgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAotICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCi0gKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKLSAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQotICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKLSAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KLSAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKLSAqIFBVUlBPU0UuIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZQotICogZGV0YWlscy4KLSAqLwotCi1wYWNrYWdlIG9yZy53M2MuZG9tLmh0bWw7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5ET01FeGNlcHRpb247Ci0KLS8qKgotICogIFRoZSBjcmVhdGUqIGFuZCBkZWxldGUqIG1ldGhvZHMgb24gdGhlIHRhYmxlIGFsbG93IGF1dGhvcnMgdG8gY29uc3RydWN0Ci0gKiBhbmQgbW9kaWZ5IHRhYmxlcy4gSFRNTCA0LjAgc3BlY2lmaWVzIHRoYXQgb25seSBvbmUgb2YgZWFjaCBvZiB0aGUKLSAqIDxjb2RlPkNBUFRJT048L2NvZGU+ICwgPGNvZGU+VEhFQUQ8L2NvZGU+ICwgYW5kIDxjb2RlPlRGT09UPC9jb2RlPgotICogZWxlbWVudHMgbWF5IGV4aXN0IGluIGEgdGFibGUuIFRoZXJlZm9yZSwgaWYgb25lIGV4aXN0cywgYW5kIHRoZQotICogY3JlYXRlVEhlYWQoKSBvciBjcmVhdGVURm9vdCgpIG1ldGhvZCBpcyBjYWxsZWQsIHRoZSBtZXRob2QgcmV0dXJucyB0aGUKLSAqIGV4aXN0aW5nIFRIZWFkIG9yIFRGb290IGVsZW1lbnQuIFNlZSB0aGUgIFRBQkxFIGVsZW1lbnQgZGVmaW5pdGlvbiBpbiBIVE1MCi0gKiA0LjAuCi0gKiA8cD5TZWUgYWxzbyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMC9DUi1ET00tTGV2ZWwtMi0yMDAwMDUxMCc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDIgU3BlY2lmaWNhdGlvbjwvYT4uCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgSFRNTFRhYmxlRWxlbWVudCBleHRlbmRzIEhUTUxFbGVtZW50IHsKLSAgICAvKioKLSAgICAgKiAgUmV0dXJucyB0aGUgdGFibGUncyA8Y29kZT5DQVBUSU9OPC9jb2RlPiAsIG9yIHZvaWQgaWYgbm9uZSBleGlzdHMuCi0gICAgICovCi0gICAgcHVibGljIEhUTUxUYWJsZUNhcHRpb25FbGVtZW50IGdldENhcHRpb24oKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRDYXB0aW9uKEhUTUxUYWJsZUNhcHRpb25FbGVtZW50IGNhcHRpb24pOwotCi0gICAgLyoqCi0gICAgICogIFJldHVybnMgdGhlIHRhYmxlJ3MgPGNvZGU+VEhFQUQ8L2NvZGU+ICwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgbm9uZQotICAgICAqIGV4aXN0cy4KLSAgICAgKi8KLSAgICBwdWJsaWMgSFRNTFRhYmxlU2VjdGlvbkVsZW1lbnQgZ2V0VEhlYWQoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRUSGVhZChIVE1MVGFibGVTZWN0aW9uRWxlbWVudCB0SGVhZCk7Ci0KLSAgICAvKioKLSAgICAgKiAgUmV0dXJucyB0aGUgdGFibGUncyA8Y29kZT5URk9PVDwvY29kZT4gLCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiBub25lCi0gICAgICogZXhpc3RzLgotICAgICAqLwotICAgIHB1YmxpYyBIVE1MVGFibGVTZWN0aW9uRWxlbWVudCBnZXRURm9vdCgpOwotICAgIHB1YmxpYyB2b2lkIHNldFRGb290KEhUTUxUYWJsZVNlY3Rpb25FbGVtZW50IHRGb290KTsKLQotICAgIC8qKgotICAgICAqICBSZXR1cm5zIGEgY29sbGVjdGlvbiBvZiBhbGwgdGhlIHJvd3MgaW4gdGhlIHRhYmxlLCBpbmNsdWRpbmcgYWxsIGluCi0gICAgICogPGNvZGU+VEhFQUQ8L2NvZGU+ICwgPGNvZGU+VEZPT1Q8L2NvZGU+ICwgYWxsIDxjb2RlPlRCT0RZPC9jb2RlPgotICAgICAqIGVsZW1lbnRzLgotICAgICAqLwotICAgIHB1YmxpYyBIVE1MQ29sbGVjdGlvbiBnZXRSb3dzKCk7Ci0KLSAgICAvKioKLSAgICAgKiAgUmV0dXJucyBhIGNvbGxlY3Rpb24gb2YgdGhlIGRlZmluZWQgdGFibGUgYm9kaWVzLgotICAgICAqLwotICAgIHB1YmxpYyBIVE1MQ29sbGVjdGlvbiBnZXRUQm9kaWVzKCk7Ci0KLSAgICAvKioKLSAgICAgKiAgU3BlY2lmaWVzIHRoZSB0YWJsZSdzIHBvc2l0aW9uIHdpdGggcmVzcGVjdCB0byB0aGUgcmVzdCBvZiB0aGUKLSAgICAgKiBkb2N1bWVudC4gU2VlIHRoZSAgYWxpZ24gYXR0cmlidXRlIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuIFRoaXMKLSAgICAgKiBhdHRyaWJ1dGUgaXMgZGVwcmVjYXRlZCBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEFsaWduKCk7Ci0gICAgcHVibGljIHZvaWQgc2V0QWxpZ24oU3RyaW5nIGFsaWduKTsKLQotICAgIC8qKgotICAgICAqICBDZWxsIGJhY2tncm91bmQgY29sb3IuIFNlZSB0aGUgIGJnY29sb3IgYXR0cmlidXRlIGRlZmluaXRpb24gaW4gSFRNTAotICAgICAqIDQuMC4gVGhpcyBhdHRyaWJ1dGUgaXMgZGVwcmVjYXRlZCBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEJnQ29sb3IoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRCZ0NvbG9yKFN0cmluZyBiZ0NvbG9yKTsKLQotICAgIC8qKgotICAgICAqICBUaGUgd2lkdGggb2YgdGhlIGJvcmRlciBhcm91bmQgdGhlIHRhYmxlLiBTZWUgdGhlICBib3JkZXIgYXR0cmlidXRlCi0gICAgICogZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEJvcmRlcigpOwotICAgIHB1YmxpYyB2b2lkIHNldEJvcmRlcihTdHJpbmcgYm9yZGVyKTsKLQotICAgIC8qKgotICAgICAqICBTcGVjaWZpZXMgdGhlIGhvcml6b250YWwgYW5kIHZlcnRpY2FsIHNwYWNlIGJldHdlZW4gY2VsbCBjb250ZW50IGFuZAotICAgICAqIGNlbGwgYm9yZGVycy4gU2VlIHRoZSAgY2VsbHBhZGRpbmcgYXR0cmlidXRlIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRDZWxsUGFkZGluZygpOwotICAgIHB1YmxpYyB2b2lkIHNldENlbGxQYWRkaW5nKFN0cmluZyBjZWxsUGFkZGluZyk7Ci0KLSAgICAvKioKLSAgICAgKiAgU3BlY2lmaWVzIHRoZSBob3Jpem9udGFsIGFuZCB2ZXJ0aWNhbCBzZXBhcmF0aW9uIGJldHdlZW4gY2VsbHMuIFNlZQotICAgICAqIHRoZSAgY2VsbHNwYWNpbmcgYXR0cmlidXRlIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRDZWxsU3BhY2luZygpOwotICAgIHB1YmxpYyB2b2lkIHNldENlbGxTcGFjaW5nKFN0cmluZyBjZWxsU3BhY2luZyk7Ci0KLSAgICAvKioKLSAgICAgKiAgU3BlY2lmaWVzIHdoaWNoIGV4dGVybmFsIHRhYmxlIGJvcmRlcnMgdG8gcmVuZGVyLiBTZWUgdGhlICBmcmFtZQotICAgICAqIGF0dHJpYnV0ZSBkZWZpbml0aW9uIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0RnJhbWUoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRGcmFtZShTdHJpbmcgZnJhbWUpOwotCi0gICAgLyoqCi0gICAgICogIFNwZWNpZmllcyB3aGljaCBpbnRlcm5hbCB0YWJsZSBib3JkZXJzIHRvIHJlbmRlci4gU2VlIHRoZSAgcnVsZXMKLSAgICAgKiBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFJ1bGVzKCk7Ci0gICAgcHVibGljIHZvaWQgc2V0UnVsZXMoU3RyaW5nIHJ1bGVzKTsKLQotICAgIC8qKgotICAgICAqICBEZXNjcmlwdGlvbiBhYm91dCB0aGUgcHVycG9zZSBvciBzdHJ1Y3R1cmUgb2YgYSB0YWJsZS4gU2VlIHRoZQotICAgICAqIHN1bW1hcnkgYXR0cmlidXRlIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRTdW1tYXJ5KCk7Ci0gICAgcHVibGljIHZvaWQgc2V0U3VtbWFyeShTdHJpbmcgc3VtbWFyeSk7Ci0KLSAgICAvKioKLSAgICAgKiAgU3BlY2lmaWVzIHRoZSBkZXNpcmVkIHRhYmxlIHdpZHRoLiBTZWUgdGhlICB3aWR0aCBhdHRyaWJ1dGUgZGVmaW5pdGlvbgotICAgICAqIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0V2lkdGgoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRXaWR0aChTdHJpbmcgd2lkdGgpOwotCi0gICAgLyoqCi0gICAgICogIENyZWF0ZSBhIHRhYmxlIGhlYWRlciByb3cgb3IgcmV0dXJuIGFuIGV4aXN0aW5nIG9uZS4KLSAgICAgKiBAcmV0dXJuICBBIG5ldyB0YWJsZSBoZWFkZXIgZWxlbWVudCAoPGNvZGU+VEhFQUQ8L2NvZGU+ICkuCi0gICAgICovCi0gICAgcHVibGljIEhUTUxFbGVtZW50IGNyZWF0ZVRIZWFkKCk7Ci0KLSAgICAvKioKLSAgICAgKiAgRGVsZXRlIHRoZSBoZWFkZXIgZnJvbSB0aGUgdGFibGUsIGlmIG9uZSBleGlzdHMuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZGVsZXRlVEhlYWQoKTsKLQotICAgIC8qKgotICAgICAqICBDcmVhdGUgYSB0YWJsZSBmb290ZXIgcm93IG9yIHJldHVybiBhbiBleGlzdGluZyBvbmUuCi0gICAgICogQHJldHVybiAgQSBmb290ZXIgZWxlbWVudCAoPGNvZGU+VEZPT1Q8L2NvZGU+ICkuCi0gICAgICovCi0gICAgcHVibGljIEhUTUxFbGVtZW50IGNyZWF0ZVRGb290KCk7Ci0KLSAgICAvKioKLSAgICAgKiAgRGVsZXRlIHRoZSBmb290ZXIgZnJvbSB0aGUgdGFibGUsIGlmIG9uZSBleGlzdHMuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZGVsZXRlVEZvb3QoKTsKLQotICAgIC8qKgotICAgICAqICBDcmVhdGUgYSBuZXcgdGFibGUgY2FwdGlvbiBvYmplY3Qgb3IgcmV0dXJuIGFuIGV4aXN0aW5nIG9uZS4KLSAgICAgKiBAcmV0dXJuICBBIDxjb2RlPkNBUFRJT048L2NvZGU+IGVsZW1lbnQuCi0gICAgICovCi0gICAgcHVibGljIEhUTUxFbGVtZW50IGNyZWF0ZUNhcHRpb24oKTsKLQotICAgIC8qKgotICAgICAqICBEZWxldGUgdGhlIHRhYmxlIGNhcHRpb24sIGlmIG9uZSBleGlzdHMuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZGVsZXRlQ2FwdGlvbigpOwotCi0gICAgLyoqCi0gICAgICogIEluc2VydCBhIG5ldyBlbXB0eSByb3cgaW4gdGhlIHRhYmxlLiBUaGUgbmV3IHJvdyBpcyBpbnNlcnRlZAotICAgICAqIGltbWVkaWF0ZWx5IGJlZm9yZSBhbmQgaW4gdGhlIHNhbWUgc2VjdGlvbiBhcyB0aGUgY3VycmVudAotICAgICAqIDxjb2RlPmluZGV4PC9jb2RlPiB0aCByb3cgaW4gdGhlIHRhYmxlLiBJZiA8Y29kZT5pbmRleDwvY29kZT4gaXMgZXF1YWwKLSAgICAgKiB0byB0aGUgbnVtYmVyIG9mIHJvd3MsIHRoZSBuZXcgcm93IGlzIGFwcGVuZGVkLiBJbiBhZGRpdGlvbiwgd2hlbiB0aGUKLSAgICAgKiB0YWJsZSBpcyBlbXB0eSB0aGUgcm93IGlzIGluc2VydGVkIGludG8gYSA8Y29kZT5UQk9EWTwvY29kZT4gd2hpY2ggaXMKLSAgICAgKiBjcmVhdGVkIGFuZCBpbnNlcnRlZCBpbnRvIHRoZSB0YWJsZS4gTm90ZS4gQSB0YWJsZSByb3cgY2Fubm90IGJlIGVtcHR5Ci0gICAgICogYWNjb3JkaW5nIHRvIEhUTUwgNC4wIFJlY29tbWVuZGF0aW9uLgotICAgICAqIEBwYXJhbSBpbmRleCAgVGhlIHJvdyBudW1iZXIgd2hlcmUgdG8gaW5zZXJ0IGEgbmV3IHJvdy4gVGhpcyBpbmRleAotICAgICAqICAgc3RhcnRzIGZyb20gMCBhbmQgaXMgcmVsYXRpdmUgdG8gYWxsIHRoZSByb3dzIGNvbnRhaW5lZCBpbnNpZGUgdGhlCi0gICAgICogICB0YWJsZSwgcmVnYXJkbGVzcyBvZiBzZWN0aW9uIHBhcmVudGFnZS4KLSAgICAgKiBAcmV0dXJuICBUaGUgbmV3bHkgY3JlYXRlZCByb3cuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgICBJTkRFWF9TSVpFX0VSUjogUmFpc2VkIGlmIHRoZSBzcGVjaWZpZWQgaW5kZXggaXMgZ3JlYXRlciB0aGFuIHRoZQotICAgICAqICAgbnVtYmVyIG9mIHJvd3Mgb3IgaWYgdGhlIGluZGV4IGlzIG5lZ2F0aXZlLgotICAgICAqLwotICAgIHB1YmxpYyBIVE1MRWxlbWVudCBpbnNlcnRSb3coaW50IGluZGV4KQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBEZWxldGUgYSB0YWJsZSByb3cuCi0gICAgICogQHBhcmFtIGluZGV4ICBUaGUgaW5kZXggb2YgdGhlIHJvdyB0byBiZSBkZWxldGVkLiBUaGlzIGluZGV4IHN0YXJ0cwotICAgICAqICAgZnJvbSAwIGFuZCBpcyByZWxhdGl2ZSB0byBhbGwgdGhlIHJvd3MgY29udGFpbmVkIGluc2lkZSB0aGUgdGFibGUsCi0gICAgICogICByZWdhcmRsZXNzIG9mIHNlY3Rpb24gcGFyZW50YWdlLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICAgSU5ERVhfU0laRV9FUlI6IFJhaXNlZCBpZiB0aGUgc3BlY2lmaWVkIGluZGV4IGlzIGdyZWF0ZXIgdGhhbiBvcgotICAgICAqICAgZXF1YWwgdG8gdGhlIG51bWJlciBvZiByb3dzIG9yIGlmIHRoZSBpbmRleCBpcyBuZWdhdGl2ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBkZWxldGVSb3coaW50IGluZGV4KQotICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL3czYy9kb20vaHRtbC9IVE1MVGFibGVSb3dFbGVtZW50LmphdmEgYi9zcmMvb3JnL3czYy9kb20vaHRtbC9IVE1MVGFibGVSb3dFbGVtZW50LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGEyNGZmNDIuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTFRhYmxlUm93RWxlbWVudC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTMxICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBUaGlzIGZpbGUgaXMgYXZhaWxhYmxlIHVuZGVyIGFuZCBnb3Zlcm5lZCBieSB0aGUgR05VIEdlbmVyYWwgUHVibGljCi0gKiBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqIEhvd2V2ZXIsIHRoZSBmb2xsb3dpbmcgbm90aWNlIGFjY29tcGFuaWVkIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIG9mIHRoaXMKLSAqIGZpbGUgYW5kLCBwZXIgaXRzIHRlcm1zLCBzaG91bGQgbm90IGJlIHJlbW92ZWQ6Ci0gKgotICogQ29weXJpZ2h0IChjKSAyMDAwIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKLSAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAotICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCi0gKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQotICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgotICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgotICogUFVSUE9TRS4gU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlCi0gKiBkZXRhaWxzLgotICovCi0KLXBhY2thZ2Ugb3JnLnczYy5kb20uaHRtbDsKLQotaW1wb3J0IG9yZy53M2MuZG9tLkRPTUV4Y2VwdGlvbjsKLQotLyoqCi0gKiAgQSByb3cgaW4gYSB0YWJsZS4gU2VlIHRoZSAgVFIgZWxlbWVudCBkZWZpbml0aW9uIGluIEhUTUwgNC4wLgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDAvQ1ItRE9NLUxldmVsLTItMjAwMDA1MTAnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAyIFNwZWNpZmljYXRpb248L2E+LgotICovCi1wdWJsaWMgaW50ZXJmYWNlIEhUTUxUYWJsZVJvd0VsZW1lbnQgZXh0ZW5kcyBIVE1MRWxlbWVudCB7Ci0gICAgLyoqCi0gICAgICogIFRoZSBpbmRleCBvZiB0aGlzIHJvdywgcmVsYXRpdmUgdG8gdGhlIGVudGlyZSB0YWJsZSwgc3RhcnRpbmcgZnJvbSAwLgotICAgICAqIFRoaXMgaXMgaW4gZG9jdW1lbnQgdHJlZSBvcmRlciBhbmQgbm90IGRpc3BsYXkgb3JkZXIuIFRoZQotICAgICAqIDxjb2RlPnJvd0luZGV4PC9jb2RlPiBkb2VzIG5vdCB0YWtlIGludG8gYWNjb3VudCBzZWN0aW9ucyAoCi0gICAgICogPGNvZGU+VEhFQUQ8L2NvZGU+ICwgPGNvZGU+VEZPT1Q8L2NvZGU+ICwgb3IgPGNvZGU+VEJPRFk8L2NvZGU+ICkKLSAgICAgKiB3aXRoaW4gdGhlIHRhYmxlLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0Um93SW5kZXgoKTsKLQotICAgIC8qKgotICAgICAqICBUaGUgaW5kZXggb2YgdGhpcyByb3csIHJlbGF0aXZlIHRvIHRoZSBjdXJyZW50IHNlY3Rpb24gKAotICAgICAqIDxjb2RlPlRIRUFEPC9jb2RlPiAsIDxjb2RlPlRGT09UPC9jb2RlPiAsIG9yIDxjb2RlPlRCT0RZPC9jb2RlPiApLAotICAgICAqIHN0YXJ0aW5nIGZyb20gMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldFNlY3Rpb25Sb3dJbmRleCgpOwotCi0gICAgLyoqCi0gICAgICogIFRoZSBjb2xsZWN0aW9uIG9mIGNlbGxzIGluIHRoaXMgcm93LgotICAgICAqLwotICAgIHB1YmxpYyBIVE1MQ29sbGVjdGlvbiBnZXRDZWxscygpOwotCi0gICAgLyoqCi0gICAgICogIEhvcml6b250YWwgYWxpZ25tZW50IG9mIGRhdGEgd2l0aGluIGNlbGxzIG9mIHRoaXMgcm93LiBTZWUgdGhlICBhbGlnbgotICAgICAqIGF0dHJpYnV0ZSBkZWZpbml0aW9uIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0QWxpZ24oKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRBbGlnbihTdHJpbmcgYWxpZ24pOwotCi0gICAgLyoqCi0gICAgICogIEJhY2tncm91bmQgY29sb3IgZm9yIHJvd3MuIFNlZSB0aGUgIGJnY29sb3IgYXR0cmlidXRlIGRlZmluaXRpb24gaW4KLSAgICAgKiBIVE1MIDQuMC4gVGhpcyBhdHRyaWJ1dGUgaXMgZGVwcmVjYXRlZCBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEJnQ29sb3IoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRCZ0NvbG9yKFN0cmluZyBiZ0NvbG9yKTsKLQotICAgIC8qKgotICAgICAqICBBbGlnbm1lbnQgY2hhcmFjdGVyIGZvciBjZWxscyBpbiBhIGNvbHVtbi4gU2VlIHRoZSAgY2hhciBhdHRyaWJ1dGUKLSAgICAgKiBkZWZpbml0aW9uIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q2goKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRDaChTdHJpbmcgY2gpOwotCi0gICAgLyoqCi0gICAgICogIE9mZnNldCBvZiBhbGlnbm1lbnQgY2hhcmFjdGVyLiBTZWUgdGhlICBjaGFyb2ZmIGF0dHJpYnV0ZSBkZWZpbml0aW9uCi0gICAgICogaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRDaE9mZigpOwotICAgIHB1YmxpYyB2b2lkIHNldENoT2ZmKFN0cmluZyBjaE9mZik7Ci0KLSAgICAvKioKLSAgICAgKiAgVmVydGljYWwgYWxpZ25tZW50IG9mIGRhdGEgd2l0aGluIGNlbGxzIG9mIHRoaXMgcm93LiBTZWUgdGhlICB2YWxpZ24KLSAgICAgKiBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFZBbGlnbigpOwotICAgIHB1YmxpYyB2b2lkIHNldFZBbGlnbihTdHJpbmcgdkFsaWduKTsKLQotICAgIC8qKgotICAgICAqICBJbnNlcnQgYW4gZW1wdHkgPGNvZGU+VEQ8L2NvZGU+IGNlbGwgaW50byB0aGlzIHJvdy4gSWYKLSAgICAgKiA8Y29kZT5pbmRleDwvY29kZT4gaXMgZXF1YWwgdG8gdGhlIG51bWJlciBvZiBjZWxscywgdGhlIG5ldyBjZWxsIGlzCi0gICAgICogYXBwZW5kZWQKLSAgICAgKiBAcGFyYW0gaW5kZXggIFRoZSBwbGFjZSB0byBpbnNlcnQgdGhlIGNlbGwsIHN0YXJ0aW5nIGZyb20gMC4KLSAgICAgKiBAcmV0dXJuICBUaGUgbmV3bHkgY3JlYXRlZCBjZWxsLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICAgSU5ERVhfU0laRV9FUlI6IFJhaXNlZCBpZiB0aGUgc3BlY2lmaWVkIDxjb2RlPmluZGV4PC9jb2RlPiBpcwotICAgICAqICAgZ3JlYXRlciB0aGFuIHRoZSBudW1iZXIgb2YgY2VsbHMgb3IgaWYgdGhlIGluZGV4IGlzIG5lZ2F0aXZlLgotICAgICAqLwotICAgIHB1YmxpYyBIVE1MRWxlbWVudCBpbnNlcnRDZWxsKGludCBpbmRleCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogIERlbGV0ZSBhIGNlbGwgZnJvbSB0aGUgY3VycmVudCByb3cuCi0gICAgICogQHBhcmFtIGluZGV4ICBUaGUgaW5kZXggb2YgdGhlIGNlbGwgdG8gZGVsZXRlLCBzdGFydGluZyBmcm9tIDAuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgICBJTkRFWF9TSVpFX0VSUjogUmFpc2VkIGlmIHRoZSBzcGVjaWZpZWQgPGNvZGU+aW5kZXg8L2NvZGU+IGlzCi0gICAgICogICBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gdGhlIG51bWJlciBvZiBjZWxscyBvciBpZiB0aGUgaW5kZXggaXMKLSAgICAgKiAgIG5lZ2F0aXZlLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGRlbGV0ZUNlbGwoaW50IGluZGV4KQotICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTFRhYmxlU2VjdGlvbkVsZW1lbnQuamF2YSBiL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxUYWJsZVNlY3Rpb25FbGVtZW50LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGY2YzNjZmEuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy93M2MvZG9tL2h0bWwvSFRNTFRhYmxlU2VjdGlvbkVsZW1lbnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExMyArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogVGhpcyBmaWxlIGlzIGF2YWlsYWJsZSB1bmRlciBhbmQgZ292ZXJuZWQgYnkgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwotICogTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKiBIb3dldmVyLCB0aGUgZm9sbG93aW5nIG5vdGljZSBhY2NvbXBhbmllZCB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGlzCi0gKiBmaWxlIGFuZCwgcGVyIGl0cyB0ZXJtcywgc2hvdWxkIG5vdCBiZSByZW1vdmVkOgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAotICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCi0gKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKLSAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQotICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKLSAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KLSAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKLSAqIFBVUlBPU0UuIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZQotICogZGV0YWlscy4KLSAqLwotCi1wYWNrYWdlIG9yZy53M2MuZG9tLmh0bWw7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5ET01FeGNlcHRpb247Ci0KLS8qKgotICogIFRoZSA8Y29kZT5USEVBRDwvY29kZT4gLCA8Y29kZT5URk9PVDwvY29kZT4gLCBhbmQgPGNvZGU+VEJPRFk8L2NvZGU+Ci0gKiBlbGVtZW50cy4KLSAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAwL0NSLURPTS1MZXZlbC0yLTIwMDAwNTEwJz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMiBTcGVjaWZpY2F0aW9uPC9hPi4KLSAqLwotcHVibGljIGludGVyZmFjZSBIVE1MVGFibGVTZWN0aW9uRWxlbWVudCBleHRlbmRzIEhUTUxFbGVtZW50IHsKLSAgICAvKioKLSAgICAgKiAgSG9yaXpvbnRhbCBhbGlnbm1lbnQgb2YgZGF0YSBpbiBjZWxscy4gU2VlIHRoZSA8Y29kZT5hbGlnbjwvY29kZT4KLSAgICAgKiBhdHRyaWJ1dGUgZm9yIEhUTUxUaGVhZEVsZW1lbnQgZm9yIGRldGFpbHMuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRBbGlnbigpOwotICAgIHB1YmxpYyB2b2lkIHNldEFsaWduKFN0cmluZyBhbGlnbik7Ci0KLSAgICAvKioKLSAgICAgKiAgQWxpZ25tZW50IGNoYXJhY3RlciBmb3IgY2VsbHMgaW4gYSBjb2x1bW4uIFNlZSB0aGUgIGNoYXIgYXR0cmlidXRlCi0gICAgICogZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldENoKCk7Ci0gICAgcHVibGljIHZvaWQgc2V0Q2goU3RyaW5nIGNoKTsKLQotICAgIC8qKgotICAgICAqICBPZmZzZXQgb2YgYWxpZ25tZW50IGNoYXJhY3Rlci4gU2VlIHRoZSAgY2hhcm9mZiBhdHRyaWJ1dGUgZGVmaW5pdGlvbgotICAgICAqIGluIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q2hPZmYoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRDaE9mZihTdHJpbmcgY2hPZmYpOwotCi0gICAgLyoqCi0gICAgICogIFZlcnRpY2FsIGFsaWdubWVudCBvZiBkYXRhIGluIGNlbGxzLiBTZWUgdGhlIDxjb2RlPnZhbGlnbjwvY29kZT4KLSAgICAgKiBhdHRyaWJ1dGUgZm9yIEhUTUxUaGVhZEVsZW1lbnQgZm9yIGRldGFpbHMuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRWQWxpZ24oKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRWQWxpZ24oU3RyaW5nIHZBbGlnbik7Ci0KLSAgICAvKioKLSAgICAgKiAgVGhlIGNvbGxlY3Rpb24gb2Ygcm93cyBpbiB0aGlzIHRhYmxlIHNlY3Rpb24uCi0gICAgICovCi0gICAgcHVibGljIEhUTUxDb2xsZWN0aW9uIGdldFJvd3MoKTsKLQotICAgIC8qKgotICAgICAqICBJbnNlcnQgYSByb3cgaW50byB0aGlzIHNlY3Rpb24uIFRoZSBuZXcgcm93IGlzIGluc2VydGVkIGltbWVkaWF0ZWx5Ci0gICAgICogYmVmb3JlIHRoZSBjdXJyZW50IDxjb2RlPmluZGV4PC9jb2RlPiB0aCByb3cgaW4gdGhpcyBzZWN0aW9uLiBJZgotICAgICAqIDxjb2RlPmluZGV4PC9jb2RlPiBpcyBlcXVhbCB0byB0aGUgbnVtYmVyIG9mIHJvd3MgaW4gdGhpcyBzZWN0aW9uLCB0aGUKLSAgICAgKiBuZXcgcm93IGlzIGFwcGVuZGVkLgotICAgICAqIEBwYXJhbSBpbmRleCAgVGhlIHJvdyBudW1iZXIgd2hlcmUgdG8gaW5zZXJ0IGEgbmV3IHJvdy4gVGhpcyBpbmRleAotICAgICAqICAgc3RhcnRzIGZyb20gMCBhbmQgaXMgcmVsYXRpdmUgb25seSB0byB0aGUgcm93cyBjb250YWluZWQgaW5zaWRlIHRoaXMKLSAgICAgKiAgIHNlY3Rpb24sIG5vdCBhbGwgdGhlIHJvd3MgaW4gdGhlIHRhYmxlLgotICAgICAqIEByZXR1cm4gIFRoZSBuZXdseSBjcmVhdGVkIHJvdy4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgIElOREVYX1NJWkVfRVJSOiBSYWlzZWQgaWYgdGhlIHNwZWNpZmllZCBpbmRleCBpcyBncmVhdGVyIHRoYW4gdGhlCi0gICAgICogICBudW1iZXIgb2Ygcm93cyBvZiBpZiB0aGUgaW5kZXggaXMgbmVhZ2F0aXZlLgotICAgICAqLwotICAgIHB1YmxpYyBIVE1MRWxlbWVudCBpbnNlcnRSb3coaW50IGluZGV4KQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBEZWxldGUgYSByb3cgZnJvbSB0aGlzIHNlY3Rpb24uCi0gICAgICogQHBhcmFtIGluZGV4ICBUaGUgaW5kZXggb2YgdGhlIHJvdyB0byBiZSBkZWxldGVkLiBUaGlzIGluZGV4IHN0YXJ0cwotICAgICAqICAgZnJvbSAwIGFuZCBpcyByZWxhdGl2ZSBvbmx5IHRvIHRoZSByb3dzIGNvbnRhaW5lZCBpbnNpZGUgdGhpcwotICAgICAqICAgc2VjdGlvbiwgbm90IGFsbCB0aGUgcm93cyBpbiB0aGUgdGFibGUuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgICBJTkRFWF9TSVpFX0VSUjogUmFpc2VkIGlmIHRoZSBzcGVjaWZpZWQgaW5kZXggaXMgZ3JlYXRlciB0aGFuIG9yCi0gICAgICogICBlcXVhbCB0byB0aGUgbnVtYmVyIG9mIHJvd3Mgb3IgaWYgdGhlIGluZGV4IGlzIG5lZ2F0aXZlLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGRlbGV0ZVJvdyhpbnQgaW5kZXgpCi0gICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxUZXh0QXJlYUVsZW1lbnQuamF2YSBiL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxUZXh0QXJlYUVsZW1lbnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMTU0NmE3ZC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3czYy9kb20vaHRtbC9IVE1MVGV4dEFyZWFFbGVtZW50LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNDIgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIFRoaXMgZmlsZSBpcyBhdmFpbGFibGUgdW5kZXIgYW5kIGdvdmVybmVkIGJ5IHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKLSAqIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICogSG93ZXZlciwgdGhlIGZvbGxvd2luZyBub3RpY2UgYWNjb21wYW5pZWQgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcwotICogZmlsZSBhbmQsIHBlciBpdHMgdGVybXMsIHNob3VsZCBub3QgYmUgcmVtb3ZlZDoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDAgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKLSAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQotICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCi0gKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKLSAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCi0gKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCi0gKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCi0gKiBQVVJQT1NFLiBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUKLSAqIGRldGFpbHMuCi0gKi8KLQotcGFja2FnZSBvcmcudzNjLmRvbS5odG1sOwotCi0vKioKLSAqICBNdWx0aS1saW5lIHRleHQgZmllbGQuIFNlZSB0aGUgIFRFWFRBUkVBIGVsZW1lbnQgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAwL0NSLURPTS1MZXZlbC0yLTIwMDAwNTEwJz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMiBTcGVjaWZpY2F0aW9uPC9hPi4KLSAqLwotcHVibGljIGludGVyZmFjZSBIVE1MVGV4dEFyZWFFbGVtZW50IGV4dGVuZHMgSFRNTEVsZW1lbnQgewotICAgIC8qKgotICAgICAqICBSZXByZXNlbnRzIHRoZSBjb250ZW50cyBvZiB0aGUgZWxlbWVudC4gVGhlIHZhbHVlIG9mIHRoaXMgYXR0cmlidXRlCi0gICAgICogZG9lcyBub3QgY2hhbmdlIGlmIHRoZSBjb250ZW50cyBvZiB0aGUgY29ycmVzcG9uZGluZyBmb3JtIGNvbnRyb2wsIGluCi0gICAgICogYW4gaW50ZXJhY3RpdmUgdXNlciBhZ2VudCwgY2hhbmdlcy4gQ2hhbmdpbmcgdGhpcyBhdHRyaWJ1dGUsIGhvd2V2ZXIsCi0gICAgICogcmVzZXRzIHRoZSBjb250ZW50cyBvZiB0aGUgZm9ybSBjb250cm9sLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0RGVmYXVsdFZhbHVlKCk7Ci0gICAgcHVibGljIHZvaWQgc2V0RGVmYXVsdFZhbHVlKFN0cmluZyBkZWZhdWx0VmFsdWUpOwotCi0gICAgLyoqCi0gICAgICogIFJldHVybnMgdGhlIDxjb2RlPkZPUk08L2NvZGU+IGVsZW1lbnQgY29udGFpbmluZyB0aGlzIGNvbnRyb2wuIFJldHVybnMKLSAgICAgKiA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGlzIGNvbnRyb2wgaXMgbm90IHdpdGhpbiB0aGUgY29udGV4dCBvZiBhIGZvcm0uCi0gICAgICovCi0gICAgcHVibGljIEhUTUxGb3JtRWxlbWVudCBnZXRGb3JtKCk7Ci0KLSAgICAvKioKLSAgICAgKiAgQSBzaW5nbGUgY2hhcmFjdGVyIGFjY2VzcyBrZXkgdG8gZ2l2ZSBhY2Nlc3MgdG8gdGhlIGZvcm0gY29udHJvbC4gU2VlCi0gICAgICogdGhlICBhY2Nlc3NrZXkgYXR0cmlidXRlIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRBY2Nlc3NLZXkoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRBY2Nlc3NLZXkoU3RyaW5nIGFjY2Vzc0tleSk7Ci0KLSAgICAvKioKLSAgICAgKiAgV2lkdGggb2YgY29udHJvbCAoaW4gY2hhcmFjdGVycykuIFNlZSB0aGUgIGNvbHMgYXR0cmlidXRlIGRlZmluaXRpb24KLSAgICAgKiBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldENvbHMoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRDb2xzKGludCBjb2xzKTsKLQotICAgIC8qKgotICAgICAqICBUaGUgY29udHJvbCBpcyB1bmF2YWlsYWJsZSBpbiB0aGlzIGNvbnRleHQuIFNlZSB0aGUgIGRpc2FibGVkCi0gICAgICogYXR0cmlidXRlIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0RGlzYWJsZWQoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXREaXNhYmxlZChib29sZWFuIGRpc2FibGVkKTsKLQotICAgIC8qKgotICAgICAqICBGb3JtIGNvbnRyb2wgb3Igb2JqZWN0IG5hbWUgd2hlbiBzdWJtaXR0ZWQgd2l0aCBhIGZvcm0uIFNlZSB0aGUgIG5hbWUKLSAgICAgKiBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXROYW1lKFN0cmluZyBuYW1lKTsKLQotICAgIC8qKgotICAgICAqICBUaGlzIGNvbnRyb2wgaXMgcmVhZC1vbmx5LiBTZWUgdGhlICByZWFkb25seSBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbgotICAgICAqIEhUTUwgNC4wLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGdldFJlYWRPbmx5KCk7Ci0gICAgcHVibGljIHZvaWQgc2V0UmVhZE9ubHkoYm9vbGVhbiByZWFkT25seSk7Ci0KLSAgICAvKioKLSAgICAgKiAgTnVtYmVyIG9mIHRleHQgcm93cy4gU2VlIHRoZSAgcm93cyBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldFJvd3MoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRSb3dzKGludCByb3dzKTsKLQotICAgIC8qKgotICAgICAqICBJbmRleCB0aGF0IHJlcHJlc2VudHMgdGhlIGVsZW1lbnQncyBwb3NpdGlvbiBpbiB0aGUgdGFiYmluZyBvcmRlci4gU2VlCi0gICAgICogdGhlICB0YWJpbmRleCBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldFRhYkluZGV4KCk7Ci0gICAgcHVibGljIHZvaWQgc2V0VGFiSW5kZXgoaW50IHRhYkluZGV4KTsKLQotICAgIC8qKgotICAgICAqICBUaGUgdHlwZSBvZiB0aGlzIGZvcm0gY29udHJvbC4gVGhpcyB0aGUgc3RyaW5nICJ0ZXh0YXJlYSIuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRUeXBlKCk7Ci0KLSAgICAvKioKLSAgICAgKiAgUmVwcmVzZW50cyB0aGUgY3VycmVudCBjb250ZW50cyBvZiB0aGUgY29ycmVzcG9uZGluZyBmb3JtIGNvbnRyb2wsIGluCi0gICAgICogYW4gaW50ZXJhY3RpdmUgdXNlciBhZ2VudC4gQ2hhbmdpbmcgdGhpcyBhdHRyaWJ1dGUgY2hhbmdlcyB0aGUKLSAgICAgKiBjb250ZW50cyBvZiB0aGUgZm9ybSBjb250cm9sLCBidXQgZG9lcyBub3QgY2hhbmdlIHRoZSBjb250ZW50cyBvZiB0aGUKLSAgICAgKiBlbGVtZW50LiBJZiB0aGUgZW50aXJldHkgb2YgdGhlIGRhdGEgY2FuIG5vdCBmaXQgaW50byBhIHNpbmdsZQotICAgICAqIDxjb2RlPkRPTVN0cmluZzwvY29kZT4gLCB0aGUgaW1wbGVtZW50YXRpb24gbWF5IHRydW5jYXRlIHRoZSBkYXRhLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VmFsdWUoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRWYWx1ZShTdHJpbmcgdmFsdWUpOwotCi0gICAgLyoqCi0gICAgICogIFJlbW92ZXMga2V5Ym9hcmQgZm9jdXMgZnJvbSB0aGlzIGVsZW1lbnQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgYmx1cigpOwotCi0gICAgLyoqCi0gICAgICogIEdpdmVzIGtleWJvYXJkIGZvY3VzIHRvIHRoaXMgZWxlbWVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBmb2N1cygpOwotCi0gICAgLyoqCi0gICAgICogIFNlbGVjdCB0aGUgY29udGVudHMgb2YgdGhlIDxjb2RlPlRFWFRBUkVBPC9jb2RlPiAuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2VsZWN0KCk7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxUaXRsZUVsZW1lbnQuamF2YSBiL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxUaXRsZUVsZW1lbnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOWIzYzFjYi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3czYy9kb20vaHRtbC9IVE1MVGl0bGVFbGVtZW50LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw1NSArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogVGhpcyBmaWxlIGlzIGF2YWlsYWJsZSB1bmRlciBhbmQgZ292ZXJuZWQgYnkgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwotICogTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKiBIb3dldmVyLCB0aGUgZm9sbG93aW5nIG5vdGljZSBhY2NvbXBhbmllZCB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGlzCi0gKiBmaWxlIGFuZCwgcGVyIGl0cyB0ZXJtcywgc2hvdWxkIG5vdCBiZSByZW1vdmVkOgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAotICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCi0gKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKLSAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQotICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKLSAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KLSAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKLSAqIFBVUlBPU0UuIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZQotICogZGV0YWlscy4KLSAqLwotCi1wYWNrYWdlIG9yZy53M2MuZG9tLmh0bWw7Ci0KLS8qKgotICogIFRoZSBkb2N1bWVudCB0aXRsZS4gU2VlIHRoZSAgVElUTEUgZWxlbWVudCBkZWZpbml0aW9uIGluIEhUTUwgNC4wLgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDAvQ1ItRE9NLUxldmVsLTItMjAwMDA1MTAnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAyIFNwZWNpZmljYXRpb248L2E+LgotICovCi1wdWJsaWMgaW50ZXJmYWNlIEhUTUxUaXRsZUVsZW1lbnQgZXh0ZW5kcyBIVE1MRWxlbWVudCB7Ci0gICAgLyoqCi0gICAgICogIFRoZSBzcGVjaWZpZWQgdGl0bGUgYXMgYSBzdHJpbmcuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRUZXh0KCk7Ci0gICAgcHVibGljIHZvaWQgc2V0VGV4dChTdHJpbmcgdGV4dCk7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxVTGlzdEVsZW1lbnQuamF2YSBiL3NyYy9vcmcvdzNjL2RvbS9odG1sL0hUTUxVTGlzdEVsZW1lbnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggY2Q0Mzg2YS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3czYy9kb20vaHRtbC9IVE1MVUxpc3RFbGVtZW50LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw2MyArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogVGhpcyBmaWxlIGlzIGF2YWlsYWJsZSB1bmRlciBhbmQgZ292ZXJuZWQgYnkgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwotICogTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKiBIb3dldmVyLCB0aGUgZm9sbG93aW5nIG5vdGljZSBhY2NvbXBhbmllZCB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGlzCi0gKiBmaWxlIGFuZCwgcGVyIGl0cyB0ZXJtcywgc2hvdWxkIG5vdCBiZSByZW1vdmVkOgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAotICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCi0gKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKLSAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQotICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKLSAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KLSAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKLSAqIFBVUlBPU0UuIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZQotICogZGV0YWlscy4KLSAqLwotCi1wYWNrYWdlIG9yZy53M2MuZG9tLmh0bWw7Ci0KLS8qKgotICogIFVub3JkZXJlZCBsaXN0LiBTZWUgdGhlICBVTCBlbGVtZW50IGRlZmluaXRpb24gaW4gSFRNTCA0LjAuCi0gKiA8cD5TZWUgYWxzbyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMC9DUi1ET00tTGV2ZWwtMi0yMDAwMDUxMCc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDIgU3BlY2lmaWNhdGlvbjwvYT4uCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgSFRNTFVMaXN0RWxlbWVudCBleHRlbmRzIEhUTUxFbGVtZW50IHsKLSAgICAvKioKLSAgICAgKiAgUmVkdWNlIHNwYWNpbmcgYmV0d2VlbiBsaXN0IGl0ZW1zLiBTZWUgdGhlICBjb21wYWN0IGF0dHJpYnV0ZQotICAgICAqIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuIFRoaXMgYXR0cmlidXRlIGlzIGRlcHJlY2F0ZWQgaW4gSFRNTCA0LjAuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0Q29tcGFjdCgpOwotICAgIHB1YmxpYyB2b2lkIHNldENvbXBhY3QoYm9vbGVhbiBjb21wYWN0KTsKLQotICAgIC8qKgotICAgICAqICBCdWxsZXQgc3R5bGUuIFNlZSB0aGUgIHR5cGUgYXR0cmlidXRlIGRlZmluaXRpb24gaW4gSFRNTCA0LjAuIFRoaXMKLSAgICAgKiBhdHRyaWJ1dGUgaXMgZGVwcmVjYXRlZCBpbiBIVE1MIDQuMC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFR5cGUoKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRUeXBlKFN0cmluZyB0eXBlKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy93M2MvZG9tL2xzL0RPTUltcGxlbWVudGF0aW9uTFMuamF2YSBiL3NyYy9vcmcvdzNjL2RvbS9scy9ET01JbXBsZW1lbnRhdGlvbkxTLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGM4NzZkYWYuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy93M2MvZG9tL2xzL0RPTUltcGxlbWVudGF0aW9uTFMuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE1MSArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogVGhpcyBmaWxlIGlzIGF2YWlsYWJsZSB1bmRlciBhbmQgZ292ZXJuZWQgYnkgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwotICogTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKiBIb3dldmVyLCB0aGUgZm9sbG93aW5nIG5vdGljZSBhY2NvbXBhbmllZCB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGlzCi0gKiBmaWxlIGFuZCwgcGVyIGl0cyB0ZXJtcywgc2hvdWxkIG5vdCBiZSByZW1vdmVkOgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAotICoKLSAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBFdXJvcGVhbiBSZXNlYXJjaCBDb25zb3J0aXVtIGZvcgotICogSW5mb3JtYXRpY3MgYW5kIE1hdGhlbWF0aWNzLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwgUmlnaHRzIFJlc2VydmVkLiBUaGlzCi0gKiB3b3JrIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MocikgU29mdHdhcmUgTGljZW5zZSBbMV0gaW4gdGhlIGhvcGUgdGhhdAotICogaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkCi0gKiB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuCi0gKgotICogWzFdIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvMjAwMi9jb3B5cmlnaHQtc29mdHdhcmUtMjAwMjEyMzEKLSAqLwotCi1wYWNrYWdlIG9yZy53M2MuZG9tLmxzOwotCi1pbXBvcnQgb3JnLnczYy5kb20uRE9NRXhjZXB0aW9uOwotCi0vKioKLSAqICA8Y29kZT5ET01JbXBsZW1lbnRhdGlvbkxTPC9jb2RlPiBjb250YWlucyB0aGUgZmFjdG9yeSBtZXRob2RzIGZvciBjcmVhdGluZwotICogTG9hZCBhbmQgU2F2ZSBvYmplY3RzLgotICogPHA+IFRoZSBleHBlY3RhdGlvbiBpcyB0aGF0IGFuIGluc3RhbmNlIG9mIHRoZQotICogPGNvZGU+RE9NSW1wbGVtZW50YXRpb25MUzwvY29kZT4gaW50ZXJmYWNlIGNhbiBiZSBvYnRhaW5lZCBieSB1c2luZwotICogYmluZGluZy1zcGVjaWZpYyBjYXN0aW5nIG1ldGhvZHMgb24gYW4gaW5zdGFuY2Ugb2YgdGhlCi0gKiA8Y29kZT5ET01JbXBsZW1lbnRhdGlvbjwvY29kZT4gaW50ZXJmYWNlIG9yLCBpZiB0aGUgPGNvZGU+RG9jdW1lbnQ8L2NvZGU+Ci0gKiBzdXBwb3J0cyB0aGUgZmVhdHVyZSA8Y29kZT4iQ29yZSI8L2NvZGU+IHZlcnNpb24gPGNvZGU+IjMuMCI8L2NvZGU+Ci0gKiBkZWZpbmVkIGluIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy1ET00tTGV2ZWwtMy1Db3JlLTIwMDQwNDA3Jz5ET00gTGV2ZWwgMyBDb3JlPC9hPl0KLSAqICwgYnkgdXNpbmcgdGhlIG1ldGhvZCA8Y29kZT5ET01JbXBsZW1lbnRhdGlvbi5nZXRGZWF0dXJlPC9jb2RlPiB3aXRoCi0gKiBwYXJhbWV0ZXIgdmFsdWVzIDxjb2RlPiJMUyI8L2NvZGU+IChvciA8Y29kZT4iTFMtQXN5bmMiPC9jb2RlPikgYW5kCi0gKiA8Y29kZT4iMy4wIjwvY29kZT4gKHJlc3BlY3RpdmVseSkuCi0gKiA8cD5TZWUgYWxzbyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMtRE9NLUxldmVsLTMtTFMtMjAwNDA0MDcnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAzIExvYWQKLWFuZCBTYXZlIFNwZWNpZmljYXRpb248L2E+LgotICovCi1wdWJsaWMgaW50ZXJmYWNlIERPTUltcGxlbWVudGF0aW9uTFMgewotICAgIC8vIERPTUltcGxlbWVudGF0aW9uTFNNb2RlCi0gICAgLyoqCi0gICAgICogQ3JlYXRlIGEgc3luY2hyb25vdXMgPGNvZGU+TFNQYXJzZXI8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgTU9ERV9TWU5DSFJPTk9VUyAgICAgICAgICA9IDE7Ci0gICAgLyoqCi0gICAgICogQ3JlYXRlIGFuIGFzeW5jaHJvbm91cyA8Y29kZT5MU1BhcnNlcjwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBNT0RFX0FTWU5DSFJPTk9VUyAgICAgICAgID0gMjsKLQotICAgIC8qKgotICAgICAqIENyZWF0ZSBhIG5ldyA8Y29kZT5MU1BhcnNlcjwvY29kZT4uIFRoZSBuZXdseSBjb25zdHJ1Y3RlZCBwYXJzZXIgbWF5Ci0gICAgICogdGhlbiBiZSBjb25maWd1cmVkIGJ5IG1lYW5zIG9mIGl0cyA8Y29kZT5ET01Db25maWd1cmF0aW9uPC9jb2RlPgotICAgICAqIG9iamVjdCwgYW5kIHVzZWQgdG8gcGFyc2UgZG9jdW1lbnRzIGJ5IG1lYW5zIG9mIGl0cyA8Y29kZT5wYXJzZTwvY29kZT4KLSAgICAgKiAgbWV0aG9kLgotICAgICAqIEBwYXJhbSBtb2RlICBUaGUgPGNvZGU+bW9kZTwvY29kZT4gYXJndW1lbnQgaXMgZWl0aGVyCi0gICAgICogICA8Y29kZT5NT0RFX1NZTkNIUk9OT1VTPC9jb2RlPiBvciA8Y29kZT5NT0RFX0FTWU5DSFJPTk9VUzwvY29kZT4sIGlmCi0gICAgICogICA8Y29kZT5tb2RlPC9jb2RlPiBpcyA8Y29kZT5NT0RFX1NZTkNIUk9OT1VTPC9jb2RlPiB0aGVuIHRoZQotICAgICAqICAgPGNvZGU+TFNQYXJzZXI8L2NvZGU+IHRoYXQgaXMgY3JlYXRlZCB3aWxsIG9wZXJhdGUgaW4gc3luY2hyb25vdXMKLSAgICAgKiAgIG1vZGUsIGlmIGl0J3MgPGNvZGU+TU9ERV9BU1lOQ0hST05PVVM8L2NvZGU+IHRoZW4gdGhlCi0gICAgICogICA8Y29kZT5MU1BhcnNlcjwvY29kZT4gdGhhdCBpcyBjcmVhdGVkIHdpbGwgb3BlcmF0ZSBpbiBhc3luY2hyb25vdXMKLSAgICAgKiAgIG1vZGUuCi0gICAgICogQHBhcmFtIHNjaGVtYVR5cGUgIEFuIGFic29sdXRlIFVSSSByZXByZXNlbnRpbmcgdGhlIHR5cGUgb2YgdGhlIHNjaGVtYQotICAgICAqICAgbGFuZ3VhZ2UgdXNlZCBkdXJpbmcgdGhlIGxvYWQgb2YgYSA8Y29kZT5Eb2N1bWVudDwvY29kZT4gdXNpbmcgdGhlCi0gICAgICogICBuZXdseSBjcmVhdGVkIDxjb2RlPkxTUGFyc2VyPC9jb2RlPi4gTm90ZSB0aGF0IG5vIGxleGljYWwgY2hlY2tpbmcKLSAgICAgKiAgIGlzIGRvbmUgb24gdGhlIGFic29sdXRlIFVSSS4gSW4gb3JkZXIgdG8gY3JlYXRlIGEKLSAgICAgKiAgIDxjb2RlPkxTUGFyc2VyPC9jb2RlPiBmb3IgYW55IGtpbmQgb2Ygc2NoZW1hIHR5cGVzIChpLmUuIHRoZQotICAgICAqICAgTFNQYXJzZXIgd2lsbCBiZSBmcmVlIHRvIHVzZSBhbnkgc2NoZW1hIGZvdW5kKSwgdXNlIHRoZSB2YWx1ZQotICAgICAqICAgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICogPHAgPjxiPk5vdGU6PC9iPiAgICBGb3IgVzNDIFhNTCBTY2hlbWEgWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDEvUkVDLXhtbHNjaGVtYS0xLTIwMDEwNTAyLyc+WE1MIFNjaGVtYSBQYXJ0IDE8L2E+XQotICAgICAqICAgLCBhcHBsaWNhdGlvbnMgbXVzdCB1c2UgdGhlIHZhbHVlCi0gICAgICogICA8Y29kZT4iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiPC9jb2RlPi4gRm9yIFhNTCBEVEQgWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLXhtbC0yMDA0MDIwNCc+WE1MIDEuMDwvYT5dLAotICAgICAqICAgYXBwbGljYXRpb25zIG11c3QgdXNlIHRoZSB2YWx1ZQotICAgICAqICAgPGNvZGU+Imh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy14bWwiPC9jb2RlPi4gT3RoZXIgU2NoZW1hIGxhbmd1YWdlcwotICAgICAqICAgYXJlIG91dHNpZGUgdGhlIHNjb3BlIG9mIHRoZSBXM0MgYW5kIHRoZXJlZm9yZSBzaG91bGQgcmVjb21tZW5kIGFuCi0gICAgICogICBhYnNvbHV0ZSBVUkkgaW4gb3JkZXIgdG8gdXNlIHRoaXMgbWV0aG9kLgotICAgICAqIEByZXR1cm4gIFRoZSBuZXdseSBjcmVhdGVkIDxjb2RlPkxTUGFyc2VyPC9jb2RlPiBvYmplY3QuIFRoaXMKLSAgICAgKiAgIDxjb2RlPkxTUGFyc2VyPC9jb2RlPiBpcyBlaXRoZXIgc3luY2hyb25vdXMgb3IgYXN5bmNocm9ub3VzCi0gICAgICogICBkZXBlbmRpbmcgb24gdGhlIHZhbHVlIG9mIHRoZSA8Y29kZT5tb2RlPC9jb2RlPiBhcmd1bWVudC4KLSAgICAgKiA8cCA+PGI+Tm90ZTo8L2I+ICAgIEJ5IGRlZmF1bHQsIHRoZSBuZXdseSBjcmVhdGVkIDxjb2RlPkxTUGFyc2VyPC9jb2RlPgotICAgICAqICAgZG9lcyBub3QgY29udGFpbiBhIDxjb2RlPkRPTUVycm9ySGFuZGxlcjwvY29kZT4sIGkuZS4gdGhlIHZhbHVlIG9mCi0gICAgICogICB0aGUgIjxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0zLUNvcmUvY29yZS5odG1sI3BhcmFtZXRlci1lcnJvci1oYW5kbGVyJz4KLSAgICAgKiAgIGVycm9yLWhhbmRsZXI8L2E+IiBjb25maWd1cmF0aW9uIHBhcmFtZXRlciBpcyA8Y29kZT5udWxsPC9jb2RlPi4gSG93ZXZlciwgaW1wbGVtZW50YXRpb25zCi0gICAgICogICBtYXkgcHJvdmlkZSBhIGRlZmF1bHQgZXJyb3IgaGFuZGxlciBhdCBjcmVhdGlvbiB0aW1lLiBJbiB0aGF0IGNhc2UsCi0gICAgICogICB0aGUgaW5pdGlhbCB2YWx1ZSBvZiB0aGUgPGNvZGU+ImVycm9yLWhhbmRsZXIiPC9jb2RlPiBjb25maWd1cmF0aW9uCi0gICAgICogICBwYXJhbWV0ZXIgb24gdGhlIG5ldyA8Y29kZT5MU1BhcnNlcjwvY29kZT4gb2JqZWN0IGNvbnRhaW5zIGEKLSAgICAgKiAgIHJlZmVyZW5jZSB0byB0aGUgZGVmYXVsdCBlcnJvciBoYW5kbGVyLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICAgTk9UX1NVUFBPUlRFRF9FUlI6IFJhaXNlZCBpZiB0aGUgcmVxdWVzdGVkIG1vZGUgb3Igc2NoZW1hIHR5cGUgaXMKLSAgICAgKiAgIG5vdCBzdXBwb3J0ZWQuCi0gICAgICovCi0gICAgcHVibGljIExTUGFyc2VyIGNyZWF0ZUxTUGFyc2VyKHNob3J0IG1vZGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBzY2hlbWFUeXBlKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogIENyZWF0ZSBhIG5ldyA8Y29kZT5MU1NlcmlhbGl6ZXI8L2NvZGU+IG9iamVjdC4KLSAgICAgKiBAcmV0dXJuIFRoZSBuZXdseSBjcmVhdGVkIDxjb2RlPkxTU2VyaWFsaXplcjwvY29kZT4gb2JqZWN0LgotICAgICAqIDxwID48Yj5Ob3RlOjwvYj4gICAgQnkgZGVmYXVsdCwgdGhlIG5ld2x5IGNyZWF0ZWQKLSAgICAgKiAgIDxjb2RlPkxTU2VyaWFsaXplcjwvY29kZT4gaGFzIG5vIDxjb2RlPkRPTUVycm9ySGFuZGxlcjwvY29kZT4sIGkuZS4KLSAgICAgKiAgIHRoZSB2YWx1ZSBvZiB0aGUgPGNvZGU+ImVycm9yLWhhbmRsZXIiPC9jb2RlPiBjb25maWd1cmF0aW9uCi0gICAgICogICBwYXJhbWV0ZXIgaXMgPGNvZGU+bnVsbDwvY29kZT4uIEhvd2V2ZXIsIGltcGxlbWVudGF0aW9ucyBtYXkKLSAgICAgKiAgIHByb3ZpZGUgYSBkZWZhdWx0IGVycm9yIGhhbmRsZXIgYXQgY3JlYXRpb24gdGltZS4gSW4gdGhhdCBjYXNlLCB0aGUKLSAgICAgKiAgIGluaXRpYWwgdmFsdWUgb2YgdGhlIDxjb2RlPiJlcnJvci1oYW5kbGVyIjwvY29kZT4gY29uZmlndXJhdGlvbgotICAgICAqICAgcGFyYW1ldGVyIG9uIHRoZSBuZXcgPGNvZGU+TFNTZXJpYWxpemVyPC9jb2RlPiBvYmplY3QgY29udGFpbnMgYQotICAgICAqICAgcmVmZXJlbmNlIHRvIHRoZSBkZWZhdWx0IGVycm9yIGhhbmRsZXIuCi0gICAgICovCi0gICAgcHVibGljIExTU2VyaWFsaXplciBjcmVhdGVMU1NlcmlhbGl6ZXIoKTsKLQotICAgIC8qKgotICAgICAqICBDcmVhdGUgYSBuZXcgZW1wdHkgaW5wdXQgc291cmNlIG9iamVjdCB3aGVyZQotICAgICAqIDxjb2RlPkxTSW5wdXQuY2hhcmFjdGVyU3RyZWFtPC9jb2RlPiwgPGNvZGU+TFNJbnB1dC5ieXRlU3RyZWFtPC9jb2RlPgotICAgICAqICwgPGNvZGU+TFNJbnB1dC5zdHJpbmdEYXRhPC9jb2RlPiA8Y29kZT5MU0lucHV0LnN5c3RlbUlkPC9jb2RlPiwKLSAgICAgKiA8Y29kZT5MU0lucHV0LnB1YmxpY0lkPC9jb2RlPiwgPGNvZGU+TFNJbnB1dC5iYXNlVVJJPC9jb2RlPiwgYW5kCi0gICAgICogPGNvZGU+TFNJbnB1dC5lbmNvZGluZzwvY29kZT4gYXJlIG51bGwsIGFuZAotICAgICAqIDxjb2RlPkxTSW5wdXQuY2VydGlmaWVkVGV4dDwvY29kZT4gaXMgZmFsc2UuCi0gICAgICogQHJldHVybiAgVGhlIG5ld2x5IGNyZWF0ZWQgaW5wdXQgb2JqZWN0LgotICAgICAqLwotICAgIHB1YmxpYyBMU0lucHV0IGNyZWF0ZUxTSW5wdXQoKTsKLQotICAgIC8qKgotICAgICAqICBDcmVhdGUgYSBuZXcgZW1wdHkgb3V0cHV0IGRlc3RpbmF0aW9uIG9iamVjdCB3aGVyZQotICAgICAqIDxjb2RlPkxTT3V0cHV0LmNoYXJhY3RlclN0cmVhbTwvY29kZT4sCi0gICAgICogPGNvZGU+TFNPdXRwdXQuYnl0ZVN0cmVhbTwvY29kZT4sIDxjb2RlPkxTT3V0cHV0LnN5c3RlbUlkPC9jb2RlPiwKLSAgICAgKiA8Y29kZT5MU091dHB1dC5lbmNvZGluZzwvY29kZT4gYXJlIG51bGwuCi0gICAgICogQHJldHVybiAgVGhlIG5ld2x5IGNyZWF0ZWQgb3V0cHV0IG9iamVjdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgTFNPdXRwdXQgY3JlYXRlTFNPdXRwdXQoKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy93M2MvZG9tL2xzL0xTRXhjZXB0aW9uLmphdmEgYi9zcmMvb3JnL3czYy9kb20vbHMvTFNFeGNlcHRpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZjIzZDM4YS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3czYy9kb20vbHMvTFNFeGNlcHRpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDc2ICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBUaGlzIGZpbGUgaXMgYXZhaWxhYmxlIHVuZGVyIGFuZCBnb3Zlcm5lZCBieSB0aGUgR05VIEdlbmVyYWwgUHVibGljCi0gKiBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqIEhvd2V2ZXIsIHRoZSBmb2xsb3dpbmcgbm90aWNlIGFjY29tcGFuaWVkIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIG9mIHRoaXMKLSAqIGZpbGUgYW5kLCBwZXIgaXRzIHRlcm1zLCBzaG91bGQgbm90IGJlIHJlbW92ZWQ6Ci0gKgotICogQ29weXJpZ2h0IChjKSAyMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCi0gKgotICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEV1cm9wZWFuIFJlc2VhcmNoIENvbnNvcnRpdW0gZm9yCi0gKiBJbmZvcm1hdGljcyBhbmQgTWF0aGVtYXRpY3MsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMKLSAqIHdvcmsgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQyhyKSBTb2Z0d2FyZSBMaWNlbnNlIFsxXSBpbiB0aGUgaG9wZSB0aGF0Ci0gKiBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQKLSAqIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4KLSAqCi0gKiBbMV0gaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8yMDAyL2NvcHlyaWdodC1zb2Z0d2FyZS0yMDAyMTIzMQotICovCi0KLXBhY2thZ2Ugb3JnLnczYy5kb20ubHM7Ci0KLS8qKgotICogIFBhcnNlciBvciB3cml0ZSBvcGVyYXRpb25zIG1heSB0aHJvdyBhbiA8Y29kZT5MU0V4Y2VwdGlvbjwvY29kZT4gaWYgdGhlCi0gKiBwcm9jZXNzaW5nIGlzIHN0b3BwZWQuIFRoZSBwcm9jZXNzaW5nIGNhbiBiZSBzdG9wcGVkIGR1ZSB0byBhCi0gKiA8Y29kZT5ET01FcnJvcjwvY29kZT4gd2l0aCBhIHNldmVyaXR5IG9mCi0gKiA8Y29kZT5ET01FcnJvci5TRVZFUklUWV9GQVRBTF9FUlJPUjwvY29kZT4gb3IgYSBub24gcmVjb3ZlcmVkCi0gKiA8Y29kZT5ET01FcnJvci5TRVZFUklUWV9FUlJPUjwvY29kZT4sIG9yIGlmCi0gKiA8Y29kZT5ET01FcnJvckhhbmRsZXIuaGFuZGxlRXJyb3IoKTwvY29kZT4gcmV0dXJuZWQgPGNvZGU+ZmFsc2U8L2NvZGU+LgotICogPHAgPjxiPk5vdGU6PC9iPiAgQXMgc3VnZ2VzdGVkIGluIHRoZSBkZWZpbml0aW9uIG9mIHRoZSBjb25zdGFudHMgaW4gdGhlCi0gKiA8Y29kZT5ET01FcnJvcjwvY29kZT4gaW50ZXJmYWNlLCBhIERPTSBpbXBsZW1lbnRhdGlvbiBtYXkgY2hvb3NlIHRvCi0gKiBjb250aW51ZSBhZnRlciBhIGZhdGFsIGVycm9yLCBidXQgdGhlIHJlc3VsdGluZyBET00gdHJlZSBpcyB0aGVuCi0gKiBpbXBsZW1lbnRhdGlvbiBkZXBlbmRlbnQuCi0gKiA8cD5TZWUgYWxzbyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMtRE9NLUxldmVsLTMtTFMtMjAwNDA0MDcnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAzIExvYWQKLWFuZCBTYXZlIFNwZWNpZmljYXRpb248L2E+LgotICovCi1wdWJsaWMgY2xhc3MgTFNFeGNlcHRpb24gZXh0ZW5kcyBSdW50aW1lRXhjZXB0aW9uIHsKLSAgICBwdWJsaWMgTFNFeGNlcHRpb24oc2hvcnQgY29kZSwgU3RyaW5nIG1lc3NhZ2UpIHsKLSAgICAgICBzdXBlcihtZXNzYWdlKTsKLSAgICAgICB0aGlzLmNvZGUgPSBjb2RlOwotICAgIH0KLSAgICBwdWJsaWMgc2hvcnQgICBjb2RlOwotICAgIC8vIExTRXhjZXB0aW9uQ29kZQotICAgIC8qKgotICAgICAqICBJZiBhbiBhdHRlbXB0IHdhcyBtYWRlIHRvIGxvYWQgYSBkb2N1bWVudCwgb3IgYW4gWE1MIEZyYWdtZW50LCB1c2luZwotICAgICAqIDxjb2RlPkxTUGFyc2VyPC9jb2RlPiBhbmQgdGhlIHByb2Nlc3NpbmcgaGFzIGJlZW4gc3RvcHBlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFBBUlNFX0VSUiAgICAgICAgICAgICAgICAgPSA4MTsKLSAgICAvKioKLSAgICAgKiAgSWYgYW4gYXR0ZW1wdCB3YXMgbWFkZSB0byBzZXJpYWxpemUgYSA8Y29kZT5Ob2RlPC9jb2RlPiB1c2luZwotICAgICAqIDxjb2RlPkxTU2VyaWFsaXplcjwvY29kZT4gYW5kIHRoZSBwcm9jZXNzaW5nIGhhcyBiZWVuIHN0b3BwZWQuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBTRVJJQUxJWkVfRVJSICAgICAgICAgICAgID0gODI7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvdzNjL2RvbS9scy9MU0lucHV0LmphdmEgYi9zcmMvb3JnL3czYy9kb20vbHMvTFNJbnB1dC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhOWIwOGMxLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS9scy9MU0lucHV0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyNDcgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIFRoaXMgZmlsZSBpcyBhdmFpbGFibGUgdW5kZXIgYW5kIGdvdmVybmVkIGJ5IHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKLSAqIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICogSG93ZXZlciwgdGhlIGZvbGxvd2luZyBub3RpY2UgYWNjb21wYW5pZWQgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcwotICogZmlsZSBhbmQsIHBlciBpdHMgdGVybXMsIHNob3VsZCBub3QgYmUgcmVtb3ZlZDoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKLSAqCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgRXVyb3BlYW4gUmVzZWFyY2ggQ29uc29ydGl1bSBmb3IKLSAqIEluZm9ybWF0aWNzIGFuZCBNYXRoZW1hdGljcywgS2VpbyBVbml2ZXJzaXR5KS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcwotICogd29yayBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDKHIpIFNvZnR3YXJlIExpY2Vuc2UgWzFdIGluIHRoZSBob3BlIHRoYXQKLSAqIGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZAotICogd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLgotICoKLSAqIFsxXSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLzIwMDIvY29weXJpZ2h0LXNvZnR3YXJlLTIwMDIxMjMxCi0gKi8KLQotcGFja2FnZSBvcmcudzNjLmRvbS5sczsKLQotLyoqCi0gKiAgVGhpcyBpbnRlcmZhY2UgcmVwcmVzZW50cyBhbiBpbnB1dCBzb3VyY2UgZm9yIGRhdGEuCi0gKiA8cD4gVGhpcyBpbnRlcmZhY2UgYWxsb3dzIGFuIGFwcGxpY2F0aW9uIHRvIGVuY2Fwc3VsYXRlIGluZm9ybWF0aW9uIGFib3V0Ci0gKiBhbiBpbnB1dCBzb3VyY2UgaW4gYSBzaW5nbGUgb2JqZWN0LCB3aGljaCBtYXkgaW5jbHVkZSBhIHB1YmxpYwotICogaWRlbnRpZmllciwgYSBzeXN0ZW0gaWRlbnRpZmllciwgYSBieXRlIHN0cmVhbSAocG9zc2libHkgd2l0aCBhIHNwZWNpZmllZAotICogZW5jb2RpbmcpLCBhIGJhc2UgVVJJLCBhbmQvb3IgYSBjaGFyYWN0ZXIgc3RyZWFtLgotICogPHA+IFRoZSBleGFjdCBkZWZpbml0aW9ucyBvZiBhIGJ5dGUgc3RyZWFtIGFuZCBhIGNoYXJhY3RlciBzdHJlYW0gYXJlCi0gKiBiaW5kaW5nIGRlcGVuZGVudC4KLSAqIDxwPiBUaGUgYXBwbGljYXRpb24gaXMgZXhwZWN0ZWQgdG8gcHJvdmlkZSBvYmplY3RzIHRoYXQgaW1wbGVtZW50IHRoaXMKLSAqIGludGVyZmFjZSB3aGVuZXZlciBzdWNoIG9iamVjdHMgYXJlIG5lZWRlZC4gVGhlIGFwcGxpY2F0aW9uIGNhbiBlaXRoZXIKLSAqIHByb3ZpZGUgaXRzIG93biBvYmplY3RzIHRoYXQgaW1wbGVtZW50IHRoaXMgaW50ZXJmYWNlLCBvciBpdCBjYW4gdXNlIHRoZQotICogZ2VuZXJpYyBmYWN0b3J5IG1ldGhvZCA8Y29kZT5ET01JbXBsZW1lbnRhdGlvbkxTLmNyZWF0ZUxTSW5wdXQoKTwvY29kZT4KLSAqIHRvIGNyZWF0ZSBvYmplY3RzIHRoYXQgaW1wbGVtZW50IHRoaXMgaW50ZXJmYWNlLgotICogPHA+IFRoZSA8Y29kZT5MU1BhcnNlcjwvY29kZT4gd2lsbCB1c2UgdGhlIDxjb2RlPkxTSW5wdXQ8L2NvZGU+IG9iamVjdCB0bwotICogZGV0ZXJtaW5lIGhvdyB0byByZWFkIGRhdGEuIFRoZSA8Y29kZT5MU1BhcnNlcjwvY29kZT4gd2lsbCBsb29rIGF0IHRoZQotICogZGlmZmVyZW50IGlucHV0cyBzcGVjaWZpZWQgaW4gdGhlIDxjb2RlPkxTSW5wdXQ8L2NvZGU+IGluIHRoZSBmb2xsb3dpbmcKLSAqIG9yZGVyIHRvIGtub3cgd2hpY2ggb25lIHRvIHJlYWQgZnJvbSwgdGhlIGZpcnN0IG9uZSB0aGF0IGlzIG5vdCBudWxsIGFuZAotICogbm90IGFuIGVtcHR5IHN0cmluZyB3aWxsIGJlIHVzZWQ6Ci0gKiA8b2w+Ci0gKiA8bGk+IDxjb2RlPkxTSW5wdXQuY2hhcmFjdGVyU3RyZWFtPC9jb2RlPgotICogPC9saT4KLSAqIDxsaT4KLSAqIDxjb2RlPkxTSW5wdXQuYnl0ZVN0cmVhbTwvY29kZT4KLSAqIDwvbGk+Ci0gKiA8bGk+IDxjb2RlPkxTSW5wdXQuc3RyaW5nRGF0YTwvY29kZT4KLSAqIDwvbGk+Ci0gKiA8bGk+Ci0gKiA8Y29kZT5MU0lucHV0LnN5c3RlbUlkPC9jb2RlPgotICogPC9saT4KLSAqIDxsaT4gPGNvZGU+TFNJbnB1dC5wdWJsaWNJZDwvY29kZT4KLSAqIDwvbGk+Ci0gKiA8L29sPgotICogPHA+IElmIGFsbCBpbnB1dHMgYXJlIG51bGwsIHRoZSA8Y29kZT5MU1BhcnNlcjwvY29kZT4gd2lsbCByZXBvcnQgYQotICogPGNvZGU+RE9NRXJyb3I8L2NvZGU+IHdpdGggaXRzIDxjb2RlPkRPTUVycm9yLnR5cGU8L2NvZGU+IHNldCB0bwotICogPGNvZGU+Im5vLWlucHV0LXNwZWNpZmllZCI8L2NvZGU+IGFuZCBpdHMgPGNvZGU+RE9NRXJyb3Iuc2V2ZXJpdHk8L2NvZGU+Ci0gKiBzZXQgdG8gPGNvZGU+RE9NRXJyb3IuU0VWRVJJVFlfRkFUQUxfRVJST1I8L2NvZGU+LgotICogPHA+IDxjb2RlPkxTSW5wdXQ8L2NvZGU+IG9iamVjdHMgYmVsb25nIHRvIHRoZSBhcHBsaWNhdGlvbi4gVGhlIERPTQotICogaW1wbGVtZW50YXRpb24gd2lsbCBuZXZlciBtb2RpZnkgdGhlbSAodGhvdWdoIGl0IG1heSBtYWtlIGNvcGllcyBhbmQKLSAqIG1vZGlmeSB0aGUgY29waWVzLCBpZiBuZWNlc3NhcnkpLgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLURPTS1MZXZlbC0zLUxTLTIwMDQwNDA3Jz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMyBMb2FkCi1hbmQgU2F2ZSBTcGVjaWZpY2F0aW9uPC9hPi4KLSAqLwotcHVibGljIGludGVyZmFjZSBMU0lucHV0IHsKLSAgICAvKioKLSAgICAgKiAgQW4gYXR0cmlidXRlIG9mIGEgbGFuZ3VhZ2UgYW5kIGJpbmRpbmcgZGVwZW5kZW50IHR5cGUgdGhhdCByZXByZXNlbnRzCi0gICAgICogYSBzdHJlYW0gb2YgMTYtYml0IHVuaXRzLiBUaGUgYXBwbGljYXRpb24gbXVzdCBlbmNvZGUgdGhlIHN0cmVhbQotICAgICAqIHVzaW5nIFVURi0xNiAoZGVmaW5lZCBpbiBbVW5pY29kZV0gYW5kIGluIFtJU08vSUVDIDEwNjQ2XSkuIEl0IGlzIG5vdCBhIHJlcXVpcmVtZW50IHRvIGhhdmUgYW4gWE1MIGRlY2xhcmF0aW9uIHdoZW4KLSAgICAgKiB1c2luZyBjaGFyYWN0ZXIgc3RyZWFtcy4gSWYgYW4gWE1MIGRlY2xhcmF0aW9uIGlzIHByZXNlbnQsIHRoZSB2YWx1ZQotICAgICAqIG9mIHRoZSBlbmNvZGluZyBhdHRyaWJ1dGUgd2lsbCBiZSBpZ25vcmVkLgotICAgICAqLwotICAgIHB1YmxpYyBqYXZhLmlvLlJlYWRlciBnZXRDaGFyYWN0ZXJTdHJlYW0oKTsKLSAgICAvKioKLSAgICAgKiAgQW4gYXR0cmlidXRlIG9mIGEgbGFuZ3VhZ2UgYW5kIGJpbmRpbmcgZGVwZW5kZW50IHR5cGUgdGhhdCByZXByZXNlbnRzCi0gICAgICogYSBzdHJlYW0gb2YgMTYtYml0IHVuaXRzLiBUaGUgYXBwbGljYXRpb24gbXVzdCBlbmNvZGUgdGhlIHN0cmVhbQotICAgICAqIHVzaW5nIFVURi0xNiAoZGVmaW5lZCBpbiBbVW5pY29kZV0gYW5kIGluIFtJU08vSUVDIDEwNjQ2XSkuIEl0IGlzIG5vdCBhIHJlcXVpcmVtZW50IHRvIGhhdmUgYW4gWE1MIGRlY2xhcmF0aW9uIHdoZW4KLSAgICAgKiB1c2luZyBjaGFyYWN0ZXIgc3RyZWFtcy4gSWYgYW4gWE1MIGRlY2xhcmF0aW9uIGlzIHByZXNlbnQsIHRoZSB2YWx1ZQotICAgICAqIG9mIHRoZSBlbmNvZGluZyBhdHRyaWJ1dGUgd2lsbCBiZSBpZ25vcmVkLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldENoYXJhY3RlclN0cmVhbShqYXZhLmlvLlJlYWRlciBjaGFyYWN0ZXJTdHJlYW0pOwotCi0gICAgLyoqCi0gICAgICogIEFuIGF0dHJpYnV0ZSBvZiBhIGxhbmd1YWdlIGFuZCBiaW5kaW5nIGRlcGVuZGVudCB0eXBlIHRoYXQgcmVwcmVzZW50cwotICAgICAqIGEgc3RyZWFtIG9mIGJ5dGVzLgotICAgICAqIDxicj4gSWYgdGhlIGFwcGxpY2F0aW9uIGtub3dzIHRoZSBjaGFyYWN0ZXIgZW5jb2Rpbmcgb2YgdGhlIGJ5dGUKLSAgICAgKiBzdHJlYW0sIGl0IHNob3VsZCBzZXQgdGhlIGVuY29kaW5nIGF0dHJpYnV0ZS4gU2V0dGluZyB0aGUgZW5jb2RpbmcgaW4KLSAgICAgKiB0aGlzIHdheSB3aWxsIG92ZXJyaWRlIGFueSBlbmNvZGluZyBzcGVjaWZpZWQgaW4gYW4gWE1MIGRlY2xhcmF0aW9uCi0gICAgICogaW4gdGhlIGRhdGEuCi0gICAgICovCi0gICAgcHVibGljIGphdmEuaW8uSW5wdXRTdHJlYW0gZ2V0Qnl0ZVN0cmVhbSgpOwotICAgIC8qKgotICAgICAqICBBbiBhdHRyaWJ1dGUgb2YgYSBsYW5ndWFnZSBhbmQgYmluZGluZyBkZXBlbmRlbnQgdHlwZSB0aGF0IHJlcHJlc2VudHMKLSAgICAgKiBhIHN0cmVhbSBvZiBieXRlcy4KLSAgICAgKiA8YnI+IElmIHRoZSBhcHBsaWNhdGlvbiBrbm93cyB0aGUgY2hhcmFjdGVyIGVuY29kaW5nIG9mIHRoZSBieXRlCi0gICAgICogc3RyZWFtLCBpdCBzaG91bGQgc2V0IHRoZSBlbmNvZGluZyBhdHRyaWJ1dGUuIFNldHRpbmcgdGhlIGVuY29kaW5nIGluCi0gICAgICogdGhpcyB3YXkgd2lsbCBvdmVycmlkZSBhbnkgZW5jb2Rpbmcgc3BlY2lmaWVkIGluIGFuIFhNTCBkZWNsYXJhdGlvbgotICAgICAqIGluIHRoZSBkYXRhLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEJ5dGVTdHJlYW0oamF2YS5pby5JbnB1dFN0cmVhbSBieXRlU3RyZWFtKTsKLQotICAgIC8qKgotICAgICAqICBTdHJpbmcgZGF0YSB0byBwYXJzZS4gSWYgcHJvdmlkZWQsIHRoaXMgd2lsbCBhbHdheXMgYmUgdHJlYXRlZCBhcyBhCi0gICAgICogc2VxdWVuY2Ugb2YgMTYtYml0IHVuaXRzIChVVEYtMTYgZW5jb2RlZCBjaGFyYWN0ZXJzKS4gSXQgaXMgbm90IGEKLSAgICAgKiByZXF1aXJlbWVudCB0byBoYXZlIGFuIFhNTCBkZWNsYXJhdGlvbiB3aGVuIHVzaW5nCi0gICAgICogPGNvZGU+c3RyaW5nRGF0YTwvY29kZT4uIElmIGFuIFhNTCBkZWNsYXJhdGlvbiBpcyBwcmVzZW50LCB0aGUgdmFsdWUKLSAgICAgKiBvZiB0aGUgZW5jb2RpbmcgYXR0cmlidXRlIHdpbGwgYmUgaWdub3JlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFN0cmluZ0RhdGEoKTsKLSAgICAvKioKLSAgICAgKiAgU3RyaW5nIGRhdGEgdG8gcGFyc2UuIElmIHByb3ZpZGVkLCB0aGlzIHdpbGwgYWx3YXlzIGJlIHRyZWF0ZWQgYXMgYQotICAgICAqIHNlcXVlbmNlIG9mIDE2LWJpdCB1bml0cyAoVVRGLTE2IGVuY29kZWQgY2hhcmFjdGVycykuIEl0IGlzIG5vdCBhCi0gICAgICogcmVxdWlyZW1lbnQgdG8gaGF2ZSBhbiBYTUwgZGVjbGFyYXRpb24gd2hlbiB1c2luZwotICAgICAqIDxjb2RlPnN0cmluZ0RhdGE8L2NvZGU+LiBJZiBhbiBYTUwgZGVjbGFyYXRpb24gaXMgcHJlc2VudCwgdGhlIHZhbHVlCi0gICAgICogb2YgdGhlIGVuY29kaW5nIGF0dHJpYnV0ZSB3aWxsIGJlIGlnbm9yZWQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0U3RyaW5nRGF0YShTdHJpbmcgc3RyaW5nRGF0YSk7Ci0KLSAgICAvKioKLSAgICAgKiAgVGhlIHN5c3RlbSBpZGVudGlmaWVyLCBhIFVSSSByZWZlcmVuY2UgWzxhIGhyZWY9J2h0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzIzOTYudHh0Jz5JRVRGIFJGQyAyMzk2PC9hPl0sIGZvciB0aGlzCi0gICAgICogaW5wdXQgc291cmNlLiBUaGUgc3lzdGVtIGlkZW50aWZpZXIgaXMgb3B0aW9uYWwgaWYgdGhlcmUgaXMgYSBieXRlCi0gICAgICogc3RyZWFtLCBhIGNoYXJhY3RlciBzdHJlYW0sIG9yIHN0cmluZyBkYXRhLiBJdCBpcyBzdGlsbCB1c2VmdWwgdG8KLSAgICAgKiBwcm92aWRlIG9uZSwgc2luY2UgdGhlIGFwcGxpY2F0aW9uIHdpbGwgdXNlIGl0IHRvIHJlc29sdmUgYW55Ci0gICAgICogcmVsYXRpdmUgVVJJcyBhbmQgY2FuIGluY2x1ZGUgaXQgaW4gZXJyb3IgbWVzc2FnZXMgYW5kIHdhcm5pbmdzLiAoVGhlCi0gICAgICogTFNQYXJzZXIgd2lsbCBvbmx5IGF0dGVtcHQgdG8gZmV0Y2ggdGhlIHJlc291cmNlIGlkZW50aWZpZWQgYnkgdGhlCi0gICAgICogVVJJIHJlZmVyZW5jZSBpZiB0aGVyZSBpcyBubyBvdGhlciBpbnB1dCBhdmFpbGFibGUgaW4gdGhlIGlucHV0Ci0gICAgICogc291cmNlLikKLSAgICAgKiA8YnI+IElmIHRoZSBhcHBsaWNhdGlvbiBrbm93cyB0aGUgY2hhcmFjdGVyIGVuY29kaW5nIG9mIHRoZSBvYmplY3QKLSAgICAgKiBwb2ludGVkIHRvIGJ5IHRoZSBzeXN0ZW0gaWRlbnRpZmllciwgaXQgY2FuIHNldCB0aGUgZW5jb2RpbmcgdXNpbmcKLSAgICAgKiB0aGUgPGNvZGU+ZW5jb2Rpbmc8L2NvZGU+IGF0dHJpYnV0ZS4KLSAgICAgKiA8YnI+IElmIHRoZSBzcGVjaWZpZWQgc3lzdGVtIElEIGlzIGEgcmVsYXRpdmUgVVJJIHJlZmVyZW5jZSAoc2VlCi0gICAgICogc2VjdGlvbiA1IGluIFs8YSBocmVmPSdodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyMzk2LnR4dCc+SUVURiBSRkMgMjM5NjwvYT5dKSwgdGhlIERPTQotICAgICAqIGltcGxlbWVudGF0aW9uIHdpbGwgYXR0ZW1wdCB0byByZXNvbHZlIHRoZSByZWxhdGl2ZSBVUkkgd2l0aCB0aGUKLSAgICAgKiA8Y29kZT5iYXNlVVJJPC9jb2RlPiBhcyB0aGUgYmFzZSwgaWYgdGhhdCBmYWlscywgdGhlIGJlaGF2aW9yIGlzCi0gICAgICogaW1wbGVtZW50YXRpb24gZGVwZW5kZW50LgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3lzdGVtSWQoKTsKLSAgICAvKioKLSAgICAgKiAgVGhlIHN5c3RlbSBpZGVudGlmaWVyLCBhIFVSSSByZWZlcmVuY2UgWzxhIGhyZWY9J2h0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzIzOTYudHh0Jz5JRVRGIFJGQyAyMzk2PC9hPl0sIGZvciB0aGlzCi0gICAgICogaW5wdXQgc291cmNlLiBUaGUgc3lzdGVtIGlkZW50aWZpZXIgaXMgb3B0aW9uYWwgaWYgdGhlcmUgaXMgYSBieXRlCi0gICAgICogc3RyZWFtLCBhIGNoYXJhY3RlciBzdHJlYW0sIG9yIHN0cmluZyBkYXRhLiBJdCBpcyBzdGlsbCB1c2VmdWwgdG8KLSAgICAgKiBwcm92aWRlIG9uZSwgc2luY2UgdGhlIGFwcGxpY2F0aW9uIHdpbGwgdXNlIGl0IHRvIHJlc29sdmUgYW55Ci0gICAgICogcmVsYXRpdmUgVVJJcyBhbmQgY2FuIGluY2x1ZGUgaXQgaW4gZXJyb3IgbWVzc2FnZXMgYW5kIHdhcm5pbmdzLiAoVGhlCi0gICAgICogTFNQYXJzZXIgd2lsbCBvbmx5IGF0dGVtcHQgdG8gZmV0Y2ggdGhlIHJlc291cmNlIGlkZW50aWZpZWQgYnkgdGhlCi0gICAgICogVVJJIHJlZmVyZW5jZSBpZiB0aGVyZSBpcyBubyBvdGhlciBpbnB1dCBhdmFpbGFibGUgaW4gdGhlIGlucHV0Ci0gICAgICogc291cmNlLikKLSAgICAgKiA8YnI+IElmIHRoZSBhcHBsaWNhdGlvbiBrbm93cyB0aGUgY2hhcmFjdGVyIGVuY29kaW5nIG9mIHRoZSBvYmplY3QKLSAgICAgKiBwb2ludGVkIHRvIGJ5IHRoZSBzeXN0ZW0gaWRlbnRpZmllciwgaXQgY2FuIHNldCB0aGUgZW5jb2RpbmcgdXNpbmcKLSAgICAgKiB0aGUgPGNvZGU+ZW5jb2Rpbmc8L2NvZGU+IGF0dHJpYnV0ZS4KLSAgICAgKiA8YnI+IElmIHRoZSBzcGVjaWZpZWQgc3lzdGVtIElEIGlzIGEgcmVsYXRpdmUgVVJJIHJlZmVyZW5jZSAoc2VlCi0gICAgICogc2VjdGlvbiA1IGluIFs8YSBocmVmPSdodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyMzk2LnR4dCc+SUVURiBSRkMgMjM5NjwvYT5dKSwgdGhlIERPTQotICAgICAqIGltcGxlbWVudGF0aW9uIHdpbGwgYXR0ZW1wdCB0byByZXNvbHZlIHRoZSByZWxhdGl2ZSBVUkkgd2l0aCB0aGUKLSAgICAgKiA8Y29kZT5iYXNlVVJJPC9jb2RlPiBhcyB0aGUgYmFzZSwgaWYgdGhhdCBmYWlscywgdGhlIGJlaGF2aW9yIGlzCi0gICAgICogaW1wbGVtZW50YXRpb24gZGVwZW5kZW50LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFN5c3RlbUlkKFN0cmluZyBzeXN0ZW1JZCk7Ci0KLSAgICAvKioKLSAgICAgKiAgVGhlIHB1YmxpYyBpZGVudGlmaWVyIGZvciB0aGlzIGlucHV0IHNvdXJjZS4gVGhpcyBtYXkgYmUgbWFwcGVkIHRvIGFuCi0gICAgICogaW5wdXQgc291cmNlIHVzaW5nIGFuIGltcGxlbWVudGF0aW9uIGRlcGVuZGVudCBtZWNoYW5pc20gKHN1Y2ggYXMKLSAgICAgKiBjYXRhbG9ndWVzIG9yIG90aGVyIG1hcHBpbmdzKS4gVGhlIHB1YmxpYyBpZGVudGlmaWVyLCBpZiBzcGVjaWZpZWQsCi0gICAgICogbWF5IGFsc28gYmUgcmVwb3J0ZWQgYXMgcGFydCBvZiB0aGUgbG9jYXRpb24gaW5mb3JtYXRpb24gd2hlbiBlcnJvcnMKLSAgICAgKiBhcmUgcmVwb3J0ZWQuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRQdWJsaWNJZCgpOwotICAgIC8qKgotICAgICAqICBUaGUgcHVibGljIGlkZW50aWZpZXIgZm9yIHRoaXMgaW5wdXQgc291cmNlLiBUaGlzIG1heSBiZSBtYXBwZWQgdG8gYW4KLSAgICAgKiBpbnB1dCBzb3VyY2UgdXNpbmcgYW4gaW1wbGVtZW50YXRpb24gZGVwZW5kZW50IG1lY2hhbmlzbSAoc3VjaCBhcwotICAgICAqIGNhdGFsb2d1ZXMgb3Igb3RoZXIgbWFwcGluZ3MpLiBUaGUgcHVibGljIGlkZW50aWZpZXIsIGlmIHNwZWNpZmllZCwKLSAgICAgKiBtYXkgYWxzbyBiZSByZXBvcnRlZCBhcyBwYXJ0IG9mIHRoZSBsb2NhdGlvbiBpbmZvcm1hdGlvbiB3aGVuIGVycm9ycwotICAgICAqIGFyZSByZXBvcnRlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRQdWJsaWNJZChTdHJpbmcgcHVibGljSWQpOwotCi0gICAgLyoqCi0gICAgICogIFRoZSBiYXNlIFVSSSB0byBiZSB1c2VkIChzZWUgc2VjdGlvbiA1LjEuNCBpbiBbPGEgaHJlZj0naHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjM5Ni50eHQnPklFVEYgUkZDIDIzOTY8L2E+XSkgZm9yCi0gICAgICogcmVzb2x2aW5nIGEgcmVsYXRpdmUgPGNvZGU+c3lzdGVtSWQ8L2NvZGU+IHRvIGFuIGFic29sdXRlIFVSSS4KLSAgICAgKiA8YnI+IElmLCB3aGVuIHVzZWQsIHRoZSBiYXNlIFVSSSBpcyBpdHNlbGYgYSByZWxhdGl2ZSBVUkksIGFuIGVtcHR5Ci0gICAgICogc3RyaW5nLCBvciBudWxsLCB0aGUgYmVoYXZpb3IgaXMgaW1wbGVtZW50YXRpb24gZGVwZW5kZW50LgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0QmFzZVVSSSgpOwotICAgIC8qKgotICAgICAqICBUaGUgYmFzZSBVUkkgdG8gYmUgdXNlZCAoc2VlIHNlY3Rpb24gNS4xLjQgaW4gWzxhIGhyZWY9J2h0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzIzOTYudHh0Jz5JRVRGIFJGQyAyMzk2PC9hPl0pIGZvcgotICAgICAqIHJlc29sdmluZyBhIHJlbGF0aXZlIDxjb2RlPnN5c3RlbUlkPC9jb2RlPiB0byBhbiBhYnNvbHV0ZSBVUkkuCi0gICAgICogPGJyPiBJZiwgd2hlbiB1c2VkLCB0aGUgYmFzZSBVUkkgaXMgaXRzZWxmIGEgcmVsYXRpdmUgVVJJLCBhbiBlbXB0eQotICAgICAqIHN0cmluZywgb3IgbnVsbCwgdGhlIGJlaGF2aW9yIGlzIGltcGxlbWVudGF0aW9uIGRlcGVuZGVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRCYXNlVVJJKFN0cmluZyBiYXNlVVJJKTsKLQotICAgIC8qKgotICAgICAqICBUaGUgY2hhcmFjdGVyIGVuY29kaW5nLCBpZiBrbm93bi4gVGhlIGVuY29kaW5nIG11c3QgYmUgYSBzdHJpbmcKLSAgICAgKiBhY2NlcHRhYmxlIGZvciBhbiBYTUwgZW5jb2RpbmcgZGVjbGFyYXRpb24gKFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy14bWwtMjAwNDAyMDQnPlhNTCAxLjA8L2E+XSBzZWN0aW9uCi0gICAgICogNC4zLjMgIkNoYXJhY3RlciBFbmNvZGluZyBpbiBFbnRpdGllcyIpLgotICAgICAqIDxicj4gVGhpcyBhdHRyaWJ1dGUgaGFzIG5vIGVmZmVjdCB3aGVuIHRoZSBhcHBsaWNhdGlvbiBwcm92aWRlcyBhCi0gICAgICogY2hhcmFjdGVyIHN0cmVhbSBvciBzdHJpbmcgZGF0YS4gRm9yIG90aGVyIHNvdXJjZXMgb2YgaW5wdXQsIGFuCi0gICAgICogZW5jb2Rpbmcgc3BlY2lmaWVkIGJ5IG1lYW5zIG9mIHRoaXMgYXR0cmlidXRlIHdpbGwgb3ZlcnJpZGUgYW55Ci0gICAgICogZW5jb2Rpbmcgc3BlY2lmaWVkIGluIHRoZSBYTUwgZGVjbGFyYXRpb24gb3IgdGhlIFRleHQgZGVjbGFyYXRpb24sIG9yCi0gICAgICogYW4gZW5jb2Rpbmcgb2J0YWluZWQgZnJvbSBhIGhpZ2hlciBsZXZlbCBwcm90b2NvbCwgc3VjaCBhcyBIVFRQIFs8YSBocmVmPSdodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyNjE2LnR4dCc+SUVURiBSRkMgMjYxNjwvYT5dLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0RW5jb2RpbmcoKTsKLSAgICAvKioKLSAgICAgKiAgVGhlIGNoYXJhY3RlciBlbmNvZGluZywgaWYga25vd24uIFRoZSBlbmNvZGluZyBtdXN0IGJlIGEgc3RyaW5nCi0gICAgICogYWNjZXB0YWJsZSBmb3IgYW4gWE1MIGVuY29kaW5nIGRlY2xhcmF0aW9uIChbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMteG1sLTIwMDQwMjA0Jz5YTUwgMS4wPC9hPl0gc2VjdGlvbgotICAgICAqIDQuMy4zICJDaGFyYWN0ZXIgRW5jb2RpbmcgaW4gRW50aXRpZXMiKS4KLSAgICAgKiA8YnI+IFRoaXMgYXR0cmlidXRlIGhhcyBubyBlZmZlY3Qgd2hlbiB0aGUgYXBwbGljYXRpb24gcHJvdmlkZXMgYQotICAgICAqIGNoYXJhY3RlciBzdHJlYW0gb3Igc3RyaW5nIGRhdGEuIEZvciBvdGhlciBzb3VyY2VzIG9mIGlucHV0LCBhbgotICAgICAqIGVuY29kaW5nIHNwZWNpZmllZCBieSBtZWFucyBvZiB0aGlzIGF0dHJpYnV0ZSB3aWxsIG92ZXJyaWRlIGFueQotICAgICAqIGVuY29kaW5nIHNwZWNpZmllZCBpbiB0aGUgWE1MIGRlY2xhcmF0aW9uIG9yIHRoZSBUZXh0IGRlY2xhcmF0aW9uLCBvcgotICAgICAqIGFuIGVuY29kaW5nIG9idGFpbmVkIGZyb20gYSBoaWdoZXIgbGV2ZWwgcHJvdG9jb2wsIHN1Y2ggYXMgSFRUUCBbPGEgaHJlZj0naHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjYxNi50eHQnPklFVEYgUkZDIDI2MTY8L2E+XS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRFbmNvZGluZyhTdHJpbmcgZW5jb2RpbmcpOwotCi0gICAgLyoqCi0gICAgICogIElmIHNldCB0byB0cnVlLCBhc3N1bWUgdGhhdCB0aGUgaW5wdXQgaXMgY2VydGlmaWVkIChzZWUgc2VjdGlvbiAyLjEzCi0gICAgICogaW4gWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLXhtbDExLTIwMDQwMjA0Lyc+WE1MIDEuMTwvYT5dKSB3aGVuCi0gICAgICogcGFyc2luZyBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMteG1sMTEtMjAwNDAyMDQvJz5YTUwgMS4xPC9hPl0uCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0Q2VydGlmaWVkVGV4dCgpOwotICAgIC8qKgotICAgICAqICBJZiBzZXQgdG8gdHJ1ZSwgYXNzdW1lIHRoYXQgdGhlIGlucHV0IGlzIGNlcnRpZmllZCAoc2VlIHNlY3Rpb24gMi4xMwotICAgICAqIGluIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy14bWwxMS0yMDA0MDIwNC8nPlhNTCAxLjE8L2E+XSkgd2hlbgotICAgICAqIHBhcnNpbmcgWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLXhtbDExLTIwMDQwMjA0Lyc+WE1MIDEuMTwvYT5dLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldENlcnRpZmllZFRleHQoYm9vbGVhbiBjZXJ0aWZpZWRUZXh0KTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy93M2MvZG9tL2xzL0xTTG9hZEV2ZW50LmphdmEgYi9zcmMvb3JnL3czYy9kb20vbHMvTFNMb2FkRXZlbnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNWM5Yjc2Ny4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3czYy9kb20vbHMvTFNMb2FkRXZlbnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDY0ICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBUaGlzIGZpbGUgaXMgYXZhaWxhYmxlIHVuZGVyIGFuZCBnb3Zlcm5lZCBieSB0aGUgR05VIEdlbmVyYWwgUHVibGljCi0gKiBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqIEhvd2V2ZXIsIHRoZSBmb2xsb3dpbmcgbm90aWNlIGFjY29tcGFuaWVkIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIG9mIHRoaXMKLSAqIGZpbGUgYW5kLCBwZXIgaXRzIHRlcm1zLCBzaG91bGQgbm90IGJlIHJlbW92ZWQ6Ci0gKgotICogQ29weXJpZ2h0IChjKSAyMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCi0gKgotICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEV1cm9wZWFuIFJlc2VhcmNoIENvbnNvcnRpdW0gZm9yCi0gKiBJbmZvcm1hdGljcyBhbmQgTWF0aGVtYXRpY3MsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMKLSAqIHdvcmsgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQyhyKSBTb2Z0d2FyZSBMaWNlbnNlIFsxXSBpbiB0aGUgaG9wZSB0aGF0Ci0gKiBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQKLSAqIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4KLSAqCi0gKiBbMV0gaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8yMDAyL2NvcHlyaWdodC1zb2Z0d2FyZS0yMDAyMTIzMQotICovCi0KLXBhY2thZ2Ugb3JnLnczYy5kb20ubHM7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKLWltcG9ydCBvcmcudzNjLmRvbS5ldmVudHMuRXZlbnQ7Ci0KLS8qKgotICogIFRoaXMgaW50ZXJmYWNlIHJlcHJlc2VudHMgYSBsb2FkIGV2ZW50IG9iamVjdCB0aGF0IHNpZ25hbHMgdGhlIGNvbXBsZXRpb24KLSAqIG9mIGEgZG9jdW1lbnQgbG9hZC4KLSAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy1ET00tTGV2ZWwtMy1MUy0yMDA0MDQwNyc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDMgTG9hZAotYW5kIFNhdmUgU3BlY2lmaWNhdGlvbjwvYT4uCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgTFNMb2FkRXZlbnQgZXh0ZW5kcyBFdmVudCB7Ci0gICAgLyoqCi0gICAgICogVGhlIGRvY3VtZW50IHRoYXQgZmluaXNoZWQgbG9hZGluZy4KLSAgICAgKi8KLSAgICBwdWJsaWMgRG9jdW1lbnQgZ2V0TmV3RG9jdW1lbnQoKTsKLQotICAgIC8qKgotICAgICAqIFRoZSBpbnB1dCBzb3VyY2UgdGhhdCB3YXMgcGFyc2VkLgotICAgICAqLwotICAgIHB1YmxpYyBMU0lucHV0IGdldElucHV0KCk7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvdzNjL2RvbS9scy9MU091dHB1dC5qYXZhIGIvc3JjL29yZy93M2MvZG9tL2xzL0xTT3V0cHV0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGM2YWNlNDguLjAwMDAwMDAKLS0tIGEvc3JjL29yZy93M2MvZG9tL2xzL0xTT3V0cHV0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMzUgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIFRoaXMgZmlsZSBpcyBhdmFpbGFibGUgdW5kZXIgYW5kIGdvdmVybmVkIGJ5IHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKLSAqIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICogSG93ZXZlciwgdGhlIGZvbGxvd2luZyBub3RpY2UgYWNjb21wYW5pZWQgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcwotICogZmlsZSBhbmQsIHBlciBpdHMgdGVybXMsIHNob3VsZCBub3QgYmUgcmVtb3ZlZDoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKLSAqCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgRXVyb3BlYW4gUmVzZWFyY2ggQ29uc29ydGl1bSBmb3IKLSAqIEluZm9ybWF0aWNzIGFuZCBNYXRoZW1hdGljcywgS2VpbyBVbml2ZXJzaXR5KS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcwotICogd29yayBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDKHIpIFNvZnR3YXJlIExpY2Vuc2UgWzFdIGluIHRoZSBob3BlIHRoYXQKLSAqIGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZAotICogd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLgotICoKLSAqIFsxXSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLzIwMDIvY29weXJpZ2h0LXNvZnR3YXJlLTIwMDIxMjMxCi0gKi8KLQotcGFja2FnZSBvcmcudzNjLmRvbS5sczsKLQotLyoqCi0gKiAgVGhpcyBpbnRlcmZhY2UgcmVwcmVzZW50cyBhbiBvdXRwdXQgZGVzdGluYXRpb24gZm9yIGRhdGEuCi0gKiA8cD4gVGhpcyBpbnRlcmZhY2UgYWxsb3dzIGFuIGFwcGxpY2F0aW9uIHRvIGVuY2Fwc3VsYXRlIGluZm9ybWF0aW9uIGFib3V0Ci0gKiBhbiBvdXRwdXQgZGVzdGluYXRpb24gaW4gYSBzaW5nbGUgb2JqZWN0LCB3aGljaCBtYXkgaW5jbHVkZSBhIFVSSSwgYSBieXRlCi0gKiBzdHJlYW0gKHBvc3NpYmx5IHdpdGggYSBzcGVjaWZpZWQgZW5jb2RpbmcpLCBhIGJhc2UgVVJJLCBhbmQvb3IgYQotICogY2hhcmFjdGVyIHN0cmVhbS4KLSAqIDxwPiBUaGUgZXhhY3QgZGVmaW5pdGlvbnMgb2YgYSBieXRlIHN0cmVhbSBhbmQgYSBjaGFyYWN0ZXIgc3RyZWFtIGFyZQotICogYmluZGluZyBkZXBlbmRlbnQuCi0gKiA8cD4gVGhlIGFwcGxpY2F0aW9uIGlzIGV4cGVjdGVkIHRvIHByb3ZpZGUgb2JqZWN0cyB0aGF0IGltcGxlbWVudCB0aGlzCi0gKiBpbnRlcmZhY2Ugd2hlbmV2ZXIgc3VjaCBvYmplY3RzIGFyZSBuZWVkZWQuIFRoZSBhcHBsaWNhdGlvbiBjYW4gZWl0aGVyCi0gKiBwcm92aWRlIGl0cyBvd24gb2JqZWN0cyB0aGF0IGltcGxlbWVudCB0aGlzIGludGVyZmFjZSwgb3IgaXQgY2FuIHVzZSB0aGUKLSAqIGdlbmVyaWMgZmFjdG9yeSBtZXRob2QgPGNvZGU+RE9NSW1wbGVtZW50YXRpb25MUy5jcmVhdGVMU091dHB1dCgpPC9jb2RlPgotICogdG8gY3JlYXRlIG9iamVjdHMgdGhhdCBpbXBsZW1lbnQgdGhpcyBpbnRlcmZhY2UuCi0gKiA8cD4gVGhlIDxjb2RlPkxTU2VyaWFsaXplcjwvY29kZT4gd2lsbCB1c2UgdGhlIDxjb2RlPkxTT3V0cHV0PC9jb2RlPiBvYmplY3QKLSAqIHRvIGRldGVybWluZSB3aGVyZSB0byBzZXJpYWxpemUgdGhlIG91dHB1dCB0by4gVGhlCi0gKiA8Y29kZT5MU1NlcmlhbGl6ZXI8L2NvZGU+IHdpbGwgbG9vayBhdCB0aGUgZGlmZmVyZW50IG91dHB1dHMgc3BlY2lmaWVkIGluCi0gKiB0aGUgPGNvZGU+TFNPdXRwdXQ8L2NvZGU+IGluIHRoZSBmb2xsb3dpbmcgb3JkZXIgdG8ga25vdyB3aGljaCBvbmUgdG8KLSAqIG91dHB1dCB0bywgdGhlIGZpcnN0IG9uZSB0aGF0IGlzIG5vdCBudWxsIGFuZCBub3QgYW4gZW1wdHkgc3RyaW5nIHdpbGwgYmUKLSAqIHVzZWQ6Ci0gKiA8b2w+Ci0gKiA8bGk+IDxjb2RlPkxTT3V0cHV0LmNoYXJhY3RlclN0cmVhbTwvY29kZT4KLSAqIDwvbGk+Ci0gKiA8bGk+Ci0gKiA8Y29kZT5MU091dHB1dC5ieXRlU3RyZWFtPC9jb2RlPgotICogPC9saT4KLSAqIDxsaT4gPGNvZGU+TFNPdXRwdXQuc3lzdGVtSWQ8L2NvZGU+Ci0gKiA8L2xpPgotICogPC9vbD4KLSAqIDxwPiA8Y29kZT5MU091dHB1dDwvY29kZT4gb2JqZWN0cyBiZWxvbmcgdG8gdGhlIGFwcGxpY2F0aW9uLiBUaGUgRE9NCi0gKiBpbXBsZW1lbnRhdGlvbiB3aWxsIG5ldmVyIG1vZGlmeSB0aGVtICh0aG91Z2ggaXQgbWF5IG1ha2UgY29waWVzIGFuZAotICogbW9kaWZ5IHRoZSBjb3BpZXMsIGlmIG5lY2Vzc2FyeSkuCi0gKiA8cD5TZWUgYWxzbyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMtRE9NLUxldmVsLTMtTFMtMjAwNDA0MDcnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAzIExvYWQKLWFuZCBTYXZlIFNwZWNpZmljYXRpb248L2E+LgotICovCi1wdWJsaWMgaW50ZXJmYWNlIExTT3V0cHV0IHsKLSAgICAvKioKLSAgICAgKiAgQW4gYXR0cmlidXRlIG9mIGEgbGFuZ3VhZ2UgYW5kIGJpbmRpbmcgZGVwZW5kZW50IHR5cGUgdGhhdCByZXByZXNlbnRzCi0gICAgICogYSB3cml0YWJsZSBzdHJlYW0gdG8gd2hpY2ggMTYtYml0IHVuaXRzIGNhbiBiZSBvdXRwdXQuCi0gICAgICovCi0gICAgcHVibGljIGphdmEuaW8uV3JpdGVyIGdldENoYXJhY3RlclN0cmVhbSgpOwotICAgIC8qKgotICAgICAqICBBbiBhdHRyaWJ1dGUgb2YgYSBsYW5ndWFnZSBhbmQgYmluZGluZyBkZXBlbmRlbnQgdHlwZSB0aGF0IHJlcHJlc2VudHMKLSAgICAgKiBhIHdyaXRhYmxlIHN0cmVhbSB0byB3aGljaCAxNi1iaXQgdW5pdHMgY2FuIGJlIG91dHB1dC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRDaGFyYWN0ZXJTdHJlYW0oamF2YS5pby5Xcml0ZXIgY2hhcmFjdGVyU3RyZWFtKTsKLQotICAgIC8qKgotICAgICAqICBBbiBhdHRyaWJ1dGUgb2YgYSBsYW5ndWFnZSBhbmQgYmluZGluZyBkZXBlbmRlbnQgdHlwZSB0aGF0IHJlcHJlc2VudHMKLSAgICAgKiBhIHdyaXRhYmxlIHN0cmVhbSBvZiBieXRlcy4KLSAgICAgKi8KLSAgICBwdWJsaWMgamF2YS5pby5PdXRwdXRTdHJlYW0gZ2V0Qnl0ZVN0cmVhbSgpOwotICAgIC8qKgotICAgICAqICBBbiBhdHRyaWJ1dGUgb2YgYSBsYW5ndWFnZSBhbmQgYmluZGluZyBkZXBlbmRlbnQgdHlwZSB0aGF0IHJlcHJlc2VudHMKLSAgICAgKiBhIHdyaXRhYmxlIHN0cmVhbSBvZiBieXRlcy4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRCeXRlU3RyZWFtKGphdmEuaW8uT3V0cHV0U3RyZWFtIGJ5dGVTdHJlYW0pOwotCi0gICAgLyoqCi0gICAgICogIFRoZSBzeXN0ZW0gaWRlbnRpZmllciwgYSBVUkkgcmVmZXJlbmNlIFs8YSBocmVmPSdodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyMzk2LnR4dCc+SUVURiBSRkMgMjM5NjwvYT5dLCBmb3IgdGhpcwotICAgICAqIG91dHB1dCBkZXN0aW5hdGlvbi4KLSAgICAgKiA8YnI+IElmIHRoZSBzeXN0ZW0gSUQgaXMgYSByZWxhdGl2ZSBVUkkgcmVmZXJlbmNlIChzZWUgc2VjdGlvbiA1IGluIFs8YSBocmVmPSdodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyMzk2LnR4dCc+SUVURiBSRkMgMjM5NjwvYT5dKSwgdGhlCi0gICAgICogYmVoYXZpb3IgaXMgaW1wbGVtZW50YXRpb24gZGVwZW5kZW50LgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3lzdGVtSWQoKTsKLSAgICAvKioKLSAgICAgKiAgVGhlIHN5c3RlbSBpZGVudGlmaWVyLCBhIFVSSSByZWZlcmVuY2UgWzxhIGhyZWY9J2h0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzIzOTYudHh0Jz5JRVRGIFJGQyAyMzk2PC9hPl0sIGZvciB0aGlzCi0gICAgICogb3V0cHV0IGRlc3RpbmF0aW9uLgotICAgICAqIDxicj4gSWYgdGhlIHN5c3RlbSBJRCBpcyBhIHJlbGF0aXZlIFVSSSByZWZlcmVuY2UgKHNlZSBzZWN0aW9uIDUgaW4gWzxhIGhyZWY9J2h0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzIzOTYudHh0Jz5JRVRGIFJGQyAyMzk2PC9hPl0pLCB0aGUKLSAgICAgKiBiZWhhdmlvciBpcyBpbXBsZW1lbnRhdGlvbiBkZXBlbmRlbnQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0U3lzdGVtSWQoU3RyaW5nIHN5c3RlbUlkKTsKLQotICAgIC8qKgotICAgICAqICBUaGUgY2hhcmFjdGVyIGVuY29kaW5nIHRvIHVzZSBmb3IgdGhlIG91dHB1dC4gVGhlIGVuY29kaW5nIG11c3QgYmUgYQotICAgICAqIHN0cmluZyBhY2NlcHRhYmxlIGZvciBhbiBYTUwgZW5jb2RpbmcgZGVjbGFyYXRpb24gKFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy14bWwtMjAwNDAyMDQnPlhNTCAxLjA8L2E+XSBzZWN0aW9uCi0gICAgICogNC4zLjMgIkNoYXJhY3RlciBFbmNvZGluZyBpbiBFbnRpdGllcyIpLCBpdCBpcyByZWNvbW1lbmRlZCB0aGF0Ci0gICAgICogY2hhcmFjdGVyIGVuY29kaW5ncyByZWdpc3RlcmVkIChhcyBjaGFyc2V0cykgd2l0aCB0aGUgSW50ZXJuZXQKLSAgICAgKiBBc3NpZ25lZCBOdW1iZXJzIEF1dGhvcml0eSBbPGEgaHJlZj0nZnRwOi8vZnRwLmlzaS5lZHUvaW4tbm90ZXMvaWFuYS9hc3NpZ25tZW50cy9jaGFyYWN0ZXItc2V0cyc+SUFOQS1DSEFSU0VUUzwvYT5dCi0gICAgICogIHNob3VsZCBiZSByZWZlcnJlZCB0byB1c2luZyB0aGVpciByZWdpc3RlcmVkIG5hbWVzLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0RW5jb2RpbmcoKTsKLSAgICAvKioKLSAgICAgKiAgVGhlIGNoYXJhY3RlciBlbmNvZGluZyB0byB1c2UgZm9yIHRoZSBvdXRwdXQuIFRoZSBlbmNvZGluZyBtdXN0IGJlIGEKLSAgICAgKiBzdHJpbmcgYWNjZXB0YWJsZSBmb3IgYW4gWE1MIGVuY29kaW5nIGRlY2xhcmF0aW9uIChbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMteG1sLTIwMDQwMjA0Jz5YTUwgMS4wPC9hPl0gc2VjdGlvbgotICAgICAqIDQuMy4zICJDaGFyYWN0ZXIgRW5jb2RpbmcgaW4gRW50aXRpZXMiKSwgaXQgaXMgcmVjb21tZW5kZWQgdGhhdAotICAgICAqIGNoYXJhY3RlciBlbmNvZGluZ3MgcmVnaXN0ZXJlZCAoYXMgY2hhcnNldHMpIHdpdGggdGhlIEludGVybmV0Ci0gICAgICogQXNzaWduZWQgTnVtYmVycyBBdXRob3JpdHkgWzxhIGhyZWY9J2Z0cDovL2Z0cC5pc2kuZWR1L2luLW5vdGVzL2lhbmEvYXNzaWdubWVudHMvY2hhcmFjdGVyLXNldHMnPklBTkEtQ0hBUlNFVFM8L2E+XQotICAgICAqICBzaG91bGQgYmUgcmVmZXJyZWQgdG8gdXNpbmcgdGhlaXIgcmVnaXN0ZXJlZCBuYW1lcy4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRFbmNvZGluZyhTdHJpbmcgZW5jb2RpbmcpOwotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL3czYy9kb20vbHMvTFNQYXJzZXIuamF2YSBiL3NyYy9vcmcvdzNjL2RvbS9scy9MU1BhcnNlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3MmQ3ZGIyLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS9scy9MU1BhcnNlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDk1ICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBUaGlzIGZpbGUgaXMgYXZhaWxhYmxlIHVuZGVyIGFuZCBnb3Zlcm5lZCBieSB0aGUgR05VIEdlbmVyYWwgUHVibGljCi0gKiBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqIEhvd2V2ZXIsIHRoZSBmb2xsb3dpbmcgbm90aWNlIGFjY29tcGFuaWVkIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIG9mIHRoaXMKLSAqIGZpbGUgYW5kLCBwZXIgaXRzIHRlcm1zLCBzaG91bGQgbm90IGJlIHJlbW92ZWQ6Ci0gKgotICogQ29weXJpZ2h0IChjKSAyMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCi0gKgotICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEV1cm9wZWFuIFJlc2VhcmNoIENvbnNvcnRpdW0gZm9yCi0gKiBJbmZvcm1hdGljcyBhbmQgTWF0aGVtYXRpY3MsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMKLSAqIHdvcmsgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQyhyKSBTb2Z0d2FyZSBMaWNlbnNlIFsxXSBpbiB0aGUgaG9wZSB0aGF0Ci0gKiBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQKLSAqIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4KLSAqCi0gKiBbMV0gaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8yMDAyL2NvcHlyaWdodC1zb2Z0d2FyZS0yMDAyMTIzMQotICovCi0KLXBhY2thZ2Ugb3JnLnczYy5kb20ubHM7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKLWltcG9ydCBvcmcudzNjLmRvbS5ET01Db25maWd1cmF0aW9uOwotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci1pbXBvcnQgb3JnLnczYy5kb20uRE9NRXhjZXB0aW9uOwotCi0vKioKLSAqICBBbiBpbnRlcmZhY2UgdG8gYW4gb2JqZWN0IHRoYXQgaXMgYWJsZSB0byBidWlsZCwgb3IgYXVnbWVudCwgYSBET00gdHJlZQotICogZnJvbSB2YXJpb3VzIGlucHV0IHNvdXJjZXMuCi0gKiA8cD4gPGNvZGU+TFNQYXJzZXI8L2NvZGU+IHByb3ZpZGVzIGFuIEFQSSBmb3IgcGFyc2luZyBYTUwgYW5kIGJ1aWxkaW5nIHRoZQotICogY29ycmVzcG9uZGluZyBET00gZG9jdW1lbnQgc3RydWN0dXJlLiBBIDxjb2RlPkxTUGFyc2VyPC9jb2RlPiBpbnN0YW5jZQotICogY2FuIGJlIG9idGFpbmVkIGJ5IGludm9raW5nIHRoZQotICogPGNvZGU+RE9NSW1wbGVtZW50YXRpb25MUy5jcmVhdGVMU1BhcnNlcigpPC9jb2RlPiBtZXRob2QuCi0gKiA8cD4gQXMgc3BlY2lmaWVkIGluIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy1ET00tTGV2ZWwtMy1Db3JlLTIwMDQwNDA3Jz5ET00gTGV2ZWwgMyBDb3JlPC9hPl0KLSAqICwgd2hlbiBhIGRvY3VtZW50IGlzIGZpcnN0IG1hZGUgYXZhaWxhYmxlIHZpYSB0aGUgTFNQYXJzZXI6Ci0gKiA8dWw+Ci0gKiA8bGk+IHRoZXJlIHdpbGwKLSAqIG5ldmVyIGJlIHR3byBhZGphY2VudCBub2RlcyBvZiB0eXBlIE5PREVfVEVYVCwgYW5kIHRoZXJlIHdpbGwgbmV2ZXIgYmUKLSAqIGVtcHR5IHRleHQgbm9kZXMuCi0gKiA8L2xpPgotICogPGxpPiBpdCBpcyBleHBlY3RlZCB0aGF0IHRoZSA8Y29kZT52YWx1ZTwvY29kZT4gYW5kCi0gKiA8Y29kZT5ub2RlVmFsdWU8L2NvZGU+IGF0dHJpYnV0ZXMgb2YgYW4gPGNvZGU+QXR0cjwvY29kZT4gbm9kZSBpbml0aWFsbHkKLSAqIHJldHVybiB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMteG1sLTIwMDQwMjA0I0FWTm9ybWFsaXplJz5YTUwgMS4wCi0gKiBub3JtYWxpemVkIHZhbHVlPC9hPi4gSG93ZXZlciwgaWYgdGhlIHBhcmFtZXRlcnMgIjxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0zLUNvcmUvY29yZS5odG1sI3BhcmFtZXRlci12YWxpZGF0ZS1pZi1zY2hlbWEnPgotICogdmFsaWRhdGUtaWYtc2NoZW1hPC9hPiIgYW5kICI8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMy1Db3JlL2NvcmUuaHRtbCNwYXJhbWV0ZXItZGF0YXR5cGUtbm9ybWFsaXphdGlvbic+Ci0gKiBkYXRhdHlwZS1ub3JtYWxpemF0aW9uPC9hPiIgYXJlIHNldCB0byA8Y29kZT50cnVlPC9jb2RlPiwgZGVwZW5kaW5nIG9uIHRoZSBhdHRyaWJ1dGUgbm9ybWFsaXphdGlvbgotICogdXNlZCwgdGhlIGF0dHJpYnV0ZSB2YWx1ZXMgbWF5IGRpZmZlciBmcm9tIHRoZSBvbmVzIG9idGFpbmVkIGJ5IHRoZSBYTUwKLSAqIDEuMCBhdHRyaWJ1dGUgbm9ybWFsaXphdGlvbi4gSWYgdGhlIHBhcmFtZXRlcnMgIjxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0zLUNvcmUvY29yZS5odG1sI3BhcmFtZXRlci1kYXRhdHlwZS1ub3JtYWxpemF0aW9uJz4KLSAqIGRhdGF0eXBlLW5vcm1hbGl6YXRpb248L2E+IiBpcyBzZXQgdG8gPGNvZGU+ZmFsc2U8L2NvZGU+LCB0aGUgWE1MIDEuMCBhdHRyaWJ1dGUgbm9ybWFsaXphdGlvbiBpcwotICogZ3VhcmFudGVlZCB0byBvY2N1ciwgYW5kIGlmIHRoZSBhdHRyaWJ1dGVzIGxpc3QgZG9lcyBub3QgY29udGFpbgotICogbmFtZXNwYWNlIGRlY2xhcmF0aW9ucywgdGhlIDxjb2RlPmF0dHJpYnV0ZXM8L2NvZGU+IGF0dHJpYnV0ZSBvbgotICogPGNvZGU+RWxlbWVudDwvY29kZT4gbm9kZSByZXByZXNlbnRzIHRoZSBwcm9wZXJ0eSA8Yj5bYXR0cmlidXRlc108L2I+IGRlZmluZWQgaW4gWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLXhtbC1pbmZvc2V0LTIwMDQwMjA0Lyc+WE1MIEluZm9ybWF0aW9uIFNldDwvYT5dCi0gKiAuCi0gKiA8L2xpPgotICogPC91bD4KLSAqIDxwPiBBc3luY2hyb25vdXMgPGNvZGU+TFNQYXJzZXI8L2NvZGU+IG9iamVjdHMgYXJlIGV4cGVjdGVkIHRvIGFsc28KLSAqIGltcGxlbWVudCB0aGUgPGNvZGU+ZXZlbnRzOjpFdmVudFRhcmdldDwvY29kZT4gaW50ZXJmYWNlIHNvIHRoYXQgZXZlbnQKLSAqIGxpc3RlbmVycyBjYW4gYmUgcmVnaXN0ZXJlZCBvbiBhc3luY2hyb25vdXMgPGNvZGU+TFNQYXJzZXI8L2NvZGU+Ci0gKiBvYmplY3RzLgotICogPHA+IEV2ZW50cyBzdXBwb3J0ZWQgYnkgYXN5bmNocm9ub3VzIDxjb2RlPkxTUGFyc2VyPC9jb2RlPiBvYmplY3RzIGFyZToKLSAqIDxkbD4KLSAqIDxkdD5sb2FkPC9kdD4KLSAqIDxkZD4KLSAqICBUaGUgPGNvZGU+TFNQYXJzZXI8L2NvZGU+IGZpbmlzaGVzIHRvIGxvYWQgdGhlIGRvY3VtZW50LiBTZWUgYWxzbyB0aGUKLSAqIGRlZmluaXRpb24gb2YgdGhlIDxjb2RlPkxTTG9hZEV2ZW50PC9jb2RlPiBpbnRlcmZhY2UuIDwvZGQ+Ci0gKiA8ZHQ+cHJvZ3Jlc3M8L2R0PgotICogPGRkPiBUaGUKLSAqIDxjb2RlPkxTUGFyc2VyPC9jb2RlPiBzaWduYWxzIHByb2dyZXNzIGFzIGRhdGEgaXMgcGFyc2VkLiAgVGhpcwotICogc3BlY2lmaWNhdGlvbiBkb2VzIG5vdCBhdHRlbXB0IHRvIGRlZmluZSBleGFjdGx5IHdoZW4gcHJvZ3Jlc3MgZXZlbnRzCi0gKiBzaG91bGQgYmUgZGlzcGF0Y2hlZC4gVGhhdCBpcyBpbnRlbnRpb25hbGx5IGxlZnQgYXMKLSAqIGltcGxlbWVudGF0aW9uLWRlcGVuZGVudC4gSGVyZSBpcyBvbmUgZXhhbXBsZSBvZiBob3cgYW4gYXBwbGljYXRpb24gbWlnaHQKLSAqIGRpc3BhdGNoIHByb2dyZXNzIGV2ZW50czogT25jZSB0aGUgcGFyc2VyIHN0YXJ0cyByZWNlaXZpbmcgZGF0YSwgYQotICogcHJvZ3Jlc3MgZXZlbnQgaXMgZGlzcGF0Y2hlZCB0byBpbmRpY2F0ZSB0aGF0IHRoZSBwYXJzaW5nIHN0YXJ0cy4gRnJvbQotICogdGhlcmUgb24sIGEgcHJvZ3Jlc3MgZXZlbnQgaXMgZGlzcGF0Y2hlZCBmb3IgZXZlcnkgNDA5NiBieXRlcyBvZiBkYXRhCi0gKiB0aGF0IGlzIHJlY2VpdmVkIGFuZCBwcm9jZXNzZWQuIFRoaXMgaXMgb25seSBvbmUgZXhhbXBsZSwgdGhvdWdoLCBhbmQKLSAqIGltcGxlbWVudGF0aW9ucyBjYW4gY2hvb3NlIHRvIGRpc3BhdGNoIHByb2dyZXNzIGV2ZW50cyBhdCBhbnkgdGltZSB3aGlsZQotICogcGFyc2luZywgb3Igbm90IGRpc3BhdGNoIHRoZW0gYXQgYWxsLiAgU2VlIGFsc28gdGhlIGRlZmluaXRpb24gb2YgdGhlCi0gKiA8Y29kZT5MU1Byb2dyZXNzRXZlbnQ8L2NvZGU+IGludGVyZmFjZS4gPC9kZD4KLSAqIDwvZGw+Ci0gKiA8cCA+PGI+Tm90ZTo8L2I+ICBBbGwgZXZlbnRzIGRlZmluZWQgaW4gdGhpcyBzcGVjaWZpY2F0aW9uIHVzZSB0aGUKLSAqIG5hbWVzcGFjZSBVUkkgPGNvZGU+Imh0dHA6Ly93d3cudzMub3JnLzIwMDIvRE9NTFMiPC9jb2RlPi4KLSAqIDxwPiBXaGlsZSBwYXJzaW5nIGFuIGlucHV0IHNvdXJjZSwgZXJyb3JzIGFyZSByZXBvcnRlZCB0byB0aGUgYXBwbGljYXRpb24KLSAqIHRocm91Z2ggdGhlIGVycm9yIGhhbmRsZXIgKDxjb2RlPkxTUGFyc2VyLmRvbUNvbmZpZzwvY29kZT4ncyAiPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTMtQ29yZS9jb3JlLmh0bWwjcGFyYW1ldGVyLWVycm9yLWhhbmRsZXInPgotICogZXJyb3ItaGFuZGxlcjwvYT4iIHBhcmFtZXRlcikuIFRoaXMgc3BlY2lmaWNhdGlvbiBkb2VzIGluIG5vIHdheSB0cnkgdG8gZGVmaW5lIGFsbCBwb3NzaWJsZQotICogZXJyb3JzIHRoYXQgY2FuIG9jY3VyIHdoaWxlIHBhcnNpbmcgWE1MLCBvciBhbnkgb3RoZXIgbWFya3VwLCBidXQgc29tZQotICogY29tbW9uIGVycm9yIGNhc2VzIGFyZSBkZWZpbmVkLiBUaGUgdHlwZXMgKDxjb2RlPkRPTUVycm9yLnR5cGU8L2NvZGU+KSBvZgotICogZXJyb3JzIGFuZCB3YXJuaW5ncyBkZWZpbmVkIGJ5IHRoaXMgc3BlY2lmaWNhdGlvbiBhcmU6Ci0gKiA8ZGw+Ci0gKiA8ZHQ+Ci0gKiA8Y29kZT4iY2hlY2stY2hhcmFjdGVyLW5vcm1hbGl6YXRpb24tZmFpbHVyZSIgW2Vycm9yXTwvY29kZT4gPC9kdD4KLSAqIDxkZD4gUmFpc2VkIGlmCi0gKiB0aGUgcGFyYW1ldGVyICI8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMy1Db3JlL2NvcmUuaHRtbCNwYXJhbWV0ZXItY2hlY2stY2hhcmFjdGVyLW5vcm1hbGl6YXRpb24nPgotICogY2hlY2stY2hhcmFjdGVyLW5vcm1hbGl6YXRpb248L2E+IiBpcyBzZXQgdG8gdHJ1ZSBhbmQgYSBzdHJpbmcgaXMgZW5jb3VudGVyZWQgdGhhdCBmYWlscyBub3JtYWxpemF0aW9uCi0gKiBjaGVja2luZy4gPC9kZD4KLSAqIDxkdD48Y29kZT4iZG9jdHlwZS1ub3QtYWxsb3dlZCIgW2ZhdGFsXTwvY29kZT48L2R0PgotICogPGRkPiBSYWlzZWQgaWYgdGhlCi0gKiBjb25maWd1cmF0aW9uIHBhcmFtZXRlciAiZGlzYWxsb3ctZG9jdHlwZSIgaXMgc2V0IHRvIDxjb2RlPnRydWU8L2NvZGU+Ci0gKiBhbmQgYSBkb2N0eXBlIGlzIGVuY291bnRlcmVkLiA8L2RkPgotICogPGR0Pjxjb2RlPiJuby1pbnB1dC1zcGVjaWZpZWQiIFtmYXRhbF08L2NvZGU+PC9kdD4KLSAqIDxkZD4KLSAqIFJhaXNlZCB3aGVuIGxvYWRpbmcgYSBkb2N1bWVudCBhbmQgbm8gaW5wdXQgaXMgc3BlY2lmaWVkIGluIHRoZQotICogPGNvZGU+TFNJbnB1dDwvY29kZT4gb2JqZWN0LiA8L2RkPgotICogPGR0PgotICogPGNvZGU+InBpLWJhc2UtdXJpLW5vdC1wcmVzZXJ2ZWQiIFt3YXJuaW5nXTwvY29kZT48L2R0PgotICogPGRkPiBSYWlzZWQgaWYgYSBwcm9jZXNzaW5nCi0gKiBpbnN0cnVjdGlvbiBpcyBlbmNvdW50ZXJlZCBpbiBhIGxvY2F0aW9uIHdoZXJlIHRoZSBiYXNlIFVSSSBvZiB0aGUKLSAqIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gY2FuIG5vdCBiZSBwcmVzZXJ2ZWQuICBPbmUgZXhhbXBsZSBvZiBhIGNhc2Ugd2hlcmUKLSAqIHRoaXMgd2FybmluZyB3aWxsIGJlIHJhaXNlZCBpcyBpZiB0aGUgY29uZmlndXJhdGlvbiBwYXJhbWV0ZXIgIjxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0zLUNvcmUvY29yZS5odG1sI3BhcmFtZXRlci1lbnRpdGllcyc+Ci0gKiBlbnRpdGllczwvYT4iIGlzIHNldCB0byA8Y29kZT5mYWxzZTwvY29kZT4gYW5kIHRoZSBmb2xsb3dpbmcgWE1MIGZpbGUgaXMgcGFyc2VkOgotICogPHByZT4KLSAqICZsdDshRE9DVFlQRSByb290IFsgJmx0OyFFTlRJVFkgZSBTWVNURU0gJ3N1YmRpci9teWVudGl0eS5lbnQnIF0mZ3Q7Ci0gKiAmbHQ7cm9vdCZndDsgJmFtcDtlOyAmbHQ7L3Jvb3QmZ3Q7PC9wcmU+Ci0gKiAgQW5kIDxjb2RlPnN1YmRpci9teWVudGl0eS5lbnQ8L2NvZGU+Ci0gKiBjb250YWluczoKLSAqIDxwcmU+Jmx0O29uZSZndDsgJmx0O3R3by8mZ3Q7ICZsdDsvb25lJmd0OyAmbHQ7P3BpIDMuMTQxNTk/Jmd0OwotICogJmx0O21vcmUvJmd0OzwvcHJlPgotICogPC9kZD4KLSAqIDxkdD48Y29kZT4idW5ib3VuZC1wcmVmaXgtaW4tZW50aXR5IiBbd2FybmluZ108L2NvZGU+PC9kdD4KLSAqIDxkZD4gQW4KLSAqIGltcGxlbWVudGF0aW9uIGRlcGVuZGVudCB3YXJuaW5nIHRoYXQgbWF5IGJlIHJhaXNlZCBpZiB0aGUgY29uZmlndXJhdGlvbgotICogcGFyYW1ldGVyICI8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMy1Db3JlL2NvcmUuaHRtbCNwYXJhbWV0ZXItbmFtZXNwYWNlcyc+Ci0gKiBuYW1lc3BhY2VzPC9hPiIgaXMgc2V0IHRvIDxjb2RlPnRydWU8L2NvZGU+IGFuZCBhbiB1bmJvdW5kIG5hbWVzcGFjZSBwcmVmaXggaXMKLSAqIGVuY291bnRlcmVkIGluIGFuIGVudGl0eSdzIHJlcGxhY2VtZW50IHRleHQuIFJhaXNpbmcgdGhpcyB3YXJuaW5nIGlzIG5vdAotICogZW5mb3JjZWQgc2luY2Ugc29tZSBleGlzdGluZyBwYXJzZXJzIG1heSBub3QgcmVjb2duaXplIHVuYm91bmQgbmFtZXNwYWNlCi0gKiBwcmVmaXhlcyBpbiB0aGUgcmVwbGFjZW1lbnQgdGV4dCBvZiBlbnRpdGllcy4gPC9kZD4KLSAqIDxkdD4KLSAqIDxjb2RlPiJ1bmtub3duLWNoYXJhY3Rlci1kZW5vcm1hbGl6YXRpb24iIFtmYXRhbF08L2NvZGU+PC9kdD4KLSAqIDxkZD4gUmFpc2VkIGlmIHRoZQotICogY29uZmlndXJhdGlvbiBwYXJhbWV0ZXIgImlnbm9yZS11bmtub3duLWNoYXJhY3Rlci1kZW5vcm1hbGl6YXRpb25zIiBpcwotICogc2V0IHRvIDxjb2RlPmZhbHNlPC9jb2RlPiBhbmQgYSBjaGFyYWN0ZXIgaXMgZW5jb3VudGVyZWQgZm9yIHdoaWNoIHRoZQotICogcHJvY2Vzc29yIGNhbm5vdCBkZXRlcm1pbmUgdGhlIG5vcm1hbGl6YXRpb24gcHJvcGVydGllcy4gPC9kZD4KLSAqIDxkdD4KLSAqIDxjb2RlPiJ1bnN1cHBvcnRlZC1lbmNvZGluZyIgW2ZhdGFsXTwvY29kZT48L2R0PgotICogPGRkPiBSYWlzZWQgaWYgYW4gdW5zdXBwb3J0ZWQKLSAqIGVuY29kaW5nIGlzIGVuY291bnRlcmVkLiA8L2RkPgotICogPGR0Pjxjb2RlPiJ1bnN1cHBvcnRlZC1tZWRpYS10eXBlIiBbZmF0YWxdPC9jb2RlPjwvZHQ+Ci0gKiA8ZGQ+Ci0gKiBSYWlzZWQgaWYgdGhlIGNvbmZpZ3VyYXRpb24gcGFyYW1ldGVyICJzdXBwb3J0ZWQtbWVkaWEtdHlwZXMtb25seSIgaXMgc2V0Ci0gKiB0byA8Y29kZT50cnVlPC9jb2RlPiBhbmQgYW4gdW5zdXBwb3J0ZWQgbWVkaWEgdHlwZSBpcyBlbmNvdW50ZXJlZC4gPC9kZD4KLSAqIDwvZGw+Ci0gKiA8cD4gSW4gYWRkaXRpb24gdG8gcmFpc2luZyB0aGUgZGVmaW5lZCBlcnJvcnMgYW5kIHdhcm5pbmdzLCBpbXBsZW1lbnRhdGlvbnMKLSAqIGFyZSBleHBlY3RlZCB0byByYWlzZSBpbXBsZW1lbnRhdGlvbiBzcGVjaWZpYyBlcnJvcnMgYW5kIHdhcm5pbmdzIGZvciBhbnkKLSAqIG90aGVyIGVycm9yIGFuZCB3YXJuaW5nIGNhc2VzIHN1Y2ggYXMgSU8gZXJyb3JzIChmaWxlIG5vdCBmb3VuZCwKLSAqIHBlcm1pc3Npb24gZGVuaWVkLC4uLiksIFhNTCB3ZWxsLWZvcm1lZG5lc3MgZXJyb3JzLCBhbmQgc28gb24uCi0gKiA8cD5TZWUgYWxzbyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMtRE9NLUxldmVsLTMtTFMtMjAwNDA0MDcnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAzIExvYWQKLWFuZCBTYXZlIFNwZWNpZmljYXRpb248L2E+LgotICovCi1wdWJsaWMgaW50ZXJmYWNlIExTUGFyc2VyIHsKLSAgICAvKioKLSAgICAgKiAgVGhlIDxjb2RlPkRPTUNvbmZpZ3VyYXRpb248L2NvZGU+IG9iamVjdCB1c2VkIHdoZW4gcGFyc2luZyBhbiBpbnB1dAotICAgICAqIHNvdXJjZS4gVGhpcyA8Y29kZT5ET01Db25maWd1cmF0aW9uPC9jb2RlPiBpcyBzcGVjaWZpYyB0byB0aGUgcGFyc2UKLSAgICAgKiBvcGVyYXRpb24uIE5vIHBhcmFtZXRlciB2YWx1ZXMgZnJvbSB0aGlzIDxjb2RlPkRPTUNvbmZpZ3VyYXRpb248L2NvZGU+Ci0gICAgICogIG9iamVjdCBhcmUgcGFzc2VkIGF1dG9tYXRpY2FsbHkgdG8gdGhlIDxjb2RlPkRPTUNvbmZpZ3VyYXRpb248L2NvZGU+Ci0gICAgICogb2JqZWN0IG9uIHRoZSA8Y29kZT5Eb2N1bWVudDwvY29kZT4gdGhhdCBpcyBjcmVhdGVkLCBvciB1c2VkLCBieSB0aGUKLSAgICAgKiBwYXJzZSBvcGVyYXRpb24uIFRoZSBET00gYXBwbGljYXRpb24gaXMgcmVzcG9uc2libGUgZm9yIHBhc3NpbmcgYW55Ci0gICAgICogbmVlZGVkIHBhcmFtZXRlciB2YWx1ZXMgZnJvbSB0aGlzIDxjb2RlPkRPTUNvbmZpZ3VyYXRpb248L2NvZGU+Ci0gICAgICogb2JqZWN0IHRvIHRoZSA8Y29kZT5ET01Db25maWd1cmF0aW9uPC9jb2RlPiBvYmplY3QgcmVmZXJlbmNlZCBieSB0aGUKLSAgICAgKiA8Y29kZT5Eb2N1bWVudDwvY29kZT4gb2JqZWN0LgotICAgICAqIDxicj4gSW4gYWRkaXRpb24gdG8gdGhlIHBhcmFtZXRlcnMgcmVjb2duaXplZCBpbiBvbiB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTMtQ29yZS9jb3JlLmh0bWwjRE9NQ29uZmlndXJhdGlvbic+Ci0gICAgICogRE9NQ29uZmlndXJhdGlvbjwvYT4gaW50ZXJmYWNlIGRlZmluZWQgaW4gWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLURPTS1MZXZlbC0zLUNvcmUtMjAwNDA0MDcnPkRPTSBMZXZlbCAzIENvcmU8L2E+XQotICAgICAqICwgdGhlIDxjb2RlPkRPTUNvbmZpZ3VyYXRpb248L2NvZGU+IG9iamVjdHMgZm9yIDxjb2RlPkxTUGFyc2VyPC9jb2RlPgotICAgICAqIGFkZCBvciBtb2RpZnkgdGhlIGZvbGxvd2luZyBwYXJhbWV0ZXJzOgotICAgICAqIDxkbD4KLSAgICAgKiA8ZHQ+Ci0gICAgICogPGNvZGU+ImNoYXJzZXQtb3ZlcnJpZGVzLXhtbC1lbmNvZGluZyI8L2NvZGU+PC9kdD4KLSAgICAgKiA8ZGQ+Ci0gICAgICogPGRsPgotICAgICAqIDxkdD48Y29kZT50cnVlPC9jb2RlPjwvZHQ+Ci0gICAgICogPGRkPls8ZW0+b3B0aW9uYWw8L2VtPl0gKDxlbT5kZWZhdWx0PC9lbT4pIElmIGEgaGlnaGVyIGxldmVsIHByb3RvY29sIHN1Y2ggYXMgSFRUUCBbPGEgaHJlZj0naHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjYxNi50eHQnPklFVEYgUkZDIDI2MTY8L2E+XSBwcm92aWRlcyBhbgotICAgICAqIGluZGljYXRpb24gb2YgdGhlIGNoYXJhY3RlciBlbmNvZGluZyBvZiB0aGUgaW5wdXQgc3RyZWFtIGJlaW5nCi0gICAgICogcHJvY2Vzc2VkLCB0aGF0IHdpbGwgb3ZlcnJpZGUgYW55IGVuY29kaW5nIHNwZWNpZmllZCBpbiB0aGUgWE1MCi0gICAgICogZGVjbGFyYXRpb24gb3IgdGhlIFRleHQgZGVjbGFyYXRpb24gKHNlZSBhbHNvIHNlY3Rpb24gNC4zLjMsCi0gICAgICogIkNoYXJhY3RlciBFbmNvZGluZyBpbiBFbnRpdGllcyIsIGluIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy14bWwtMjAwNDAyMDQnPlhNTCAxLjA8L2E+XSkuCi0gICAgICogRXhwbGljaXRseSBzZXR0aW5nIGFuIGVuY29kaW5nIGluIHRoZSA8Y29kZT5MU0lucHV0PC9jb2RlPiBvdmVycmlkZXMKLSAgICAgKiBhbnkgZW5jb2RpbmcgZnJvbSB0aGUgcHJvdG9jb2wuIDwvZGQ+Ci0gICAgICogPGR0Pjxjb2RlPmZhbHNlPC9jb2RlPjwvZHQ+Ci0gICAgICogPGRkPls8ZW0+cmVxdWlyZWQ8L2VtPl0gVGhlIHBhcnNlciBpZ25vcmVzIGFueSBjaGFyYWN0ZXIgc2V0IGVuY29kaW5nIGluZm9ybWF0aW9uIGZyb20KLSAgICAgKiBoaWdoZXItbGV2ZWwgcHJvdG9jb2xzLiA8L2RkPgotICAgICAqIDwvZGw+PC9kZD4KLSAgICAgKiA8ZHQ+PGNvZGU+ImRpc2FsbG93LWRvY3R5cGUiPC9jb2RlPjwvZHQ+Ci0gICAgICogPGRkPgotICAgICAqIDxkbD4KLSAgICAgKiA8ZHQ+Ci0gICAgICogPGNvZGU+dHJ1ZTwvY29kZT48L2R0PgotICAgICAqIDxkZD5bPGVtPm9wdGlvbmFsPC9lbT5dIFRocm93IGEgZmF0YWwgPGI+ImRvY3R5cGUtbm90LWFsbG93ZWQiPC9iPiBlcnJvciBpZiBhIGRvY3R5cGUgbm9kZSBpcyBmb3VuZCB3aGlsZSBwYXJzaW5nIHRoZSBkb2N1bWVudC4gVGhpcyBpcwotICAgICAqIHVzZWZ1bCB3aGVuIGRlYWxpbmcgd2l0aCB0aGluZ3MgbGlrZSBTT0FQIGVudmVsb3BlcyB3aGVyZSBkb2N0eXBlCi0gICAgICogbm9kZXMgYXJlIG5vdCBhbGxvd2VkLiA8L2RkPgotICAgICAqIDxkdD48Y29kZT5mYWxzZTwvY29kZT48L2R0PgotICAgICAqIDxkZD5bPGVtPnJlcXVpcmVkPC9lbT5dICg8ZW0+ZGVmYXVsdDwvZW0+KSBBbGxvdyBkb2N0eXBlIG5vZGVzIGluIHRoZSBkb2N1bWVudC4gPC9kZD4KLSAgICAgKiA8L2RsPjwvZGQ+Ci0gICAgICogPGR0PgotICAgICAqIDxjb2RlPiJpZ25vcmUtdW5rbm93bi1jaGFyYWN0ZXItZGVub3JtYWxpemF0aW9ucyI8L2NvZGU+PC9kdD4KLSAgICAgKiA8ZGQ+Ci0gICAgICogPGRsPgotICAgICAqIDxkdD4KLSAgICAgKiA8Y29kZT50cnVlPC9jb2RlPjwvZHQ+Ci0gICAgICogPGRkPls8ZW0+cmVxdWlyZWQ8L2VtPl0gKDxlbT5kZWZhdWx0PC9lbT4pIElmLCB3aGlsZSB2ZXJpZnlpbmcgZnVsbCBub3JtYWxpemF0aW9uIHdoZW4gWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLXhtbDExLTIwMDQwMjA0Lyc+WE1MIDEuMTwvYT5dIGlzCi0gICAgICogc3VwcG9ydGVkLCBhIHByb2Nlc3NvciBlbmNvdW50ZXJzIGNoYXJhY3RlcnMgZm9yIHdoaWNoIGl0IGNhbm5vdAotICAgICAqIGRldGVybWluZSB0aGUgbm9ybWFsaXphdGlvbiBwcm9wZXJ0aWVzLCB0aGVuIHRoZSBwcm9jZXNzb3Igd2lsbAotICAgICAqIGlnbm9yZSBhbnkgcG9zc2libGUgZGVub3JtYWxpemF0aW9ucyBjYXVzZWQgYnkgdGhlc2UgY2hhcmFjdGVycy4KLSAgICAgKiBUaGlzIHBhcmFtZXRlciBpcyBpZ25vcmVkIGZvciBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMteG1sLTIwMDQwMjA0Jz5YTUwgMS4wPC9hPl0uIDwvZGQ+Ci0gICAgICogPGR0PgotICAgICAqIDxjb2RlPmZhbHNlPC9jb2RlPjwvZHQ+Ci0gICAgICogPGRkPls8ZW0+b3B0aW9uYWw8L2VtPl0gUmVwb3J0IGFuIGZhdGFsIDxiPiJ1bmtub3duLWNoYXJhY3Rlci1kZW5vcm1hbGl6YXRpb24iPC9iPiBlcnJvciBpZiBhIGNoYXJhY3RlciBpcyBlbmNvdW50ZXJlZCBmb3Igd2hpY2ggdGhlIHByb2Nlc3NvciBjYW5ub3QKLSAgICAgKiBkZXRlcm1pbmUgdGhlIG5vcm1hbGl6YXRpb24gcHJvcGVydGllcy4gPC9kZD4KLSAgICAgKiA8L2RsPjwvZGQ+Ci0gICAgICogPGR0Pjxjb2RlPiJpbmZvc2V0IjwvY29kZT48L2R0PgotICAgICAqIDxkZD4gU2VlCi0gICAgICogdGhlIGRlZmluaXRpb24gb2YgPGNvZGU+RE9NQ29uZmlndXJhdGlvbjwvY29kZT4gZm9yIGEgZGVzY3JpcHRpb24gb2YKLSAgICAgKiB0aGlzIHBhcmFtZXRlci4gVW5saWtlIGluIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy1ET00tTGV2ZWwtMy1Db3JlLTIwMDQwNDA3Jz5ET00gTGV2ZWwgMyBDb3JlPC9hPl0KLSAgICAgKiAsIHRoaXMgcGFyYW1ldGVyIHdpbGwgZGVmYXVsdCB0byA8Y29kZT50cnVlPC9jb2RlPiBmb3IKLSAgICAgKiA8Y29kZT5MU1BhcnNlcjwvY29kZT4uIDwvZGQ+Ci0gICAgICogPGR0Pjxjb2RlPiJuYW1lc3BhY2VzIjwvY29kZT48L2R0PgotICAgICAqIDxkZD4KLSAgICAgKiA8ZGw+Ci0gICAgICogPGR0Pjxjb2RlPnRydWU8L2NvZGU+PC9kdD4KLSAgICAgKiA8ZGQ+WzxlbT5yZXF1aXJlZDwvZW0+XSAoPGVtPmRlZmF1bHQ8L2VtPikgUGVyZm9ybSB0aGUgbmFtZXNwYWNlIHByb2Nlc3NpbmcgYXMgZGVmaW5lZCBpbiBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMTk5OS9SRUMteG1sLW5hbWVzLTE5OTkwMTE0Lyc+WE1MIE5hbWVzcGFjZXM8L2E+XQotICAgICAqICBhbmQgWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLXhtbC1uYW1lczExLTIwMDQwMjA0Lyc+WE1MIE5hbWVzcGFjZXMgMS4xPC9hPl0KLSAgICAgKiAuIDwvZGQ+Ci0gICAgICogPGR0Pjxjb2RlPmZhbHNlPC9jb2RlPjwvZHQ+Ci0gICAgICogPGRkPls8ZW0+b3B0aW9uYWw8L2VtPl0gRG8gbm90IHBlcmZvcm0gdGhlIG5hbWVzcGFjZSBwcm9jZXNzaW5nLiA8L2RkPgotICAgICAqIDwvZGw+PC9kZD4KLSAgICAgKiA8ZHQ+Ci0gICAgICogPGNvZGU+InJlc291cmNlLXJlc29sdmVyIjwvY29kZT48L2R0PgotICAgICAqIDxkZD5bPGVtPnJlcXVpcmVkPC9lbT5dIEEgcmVmZXJlbmNlIHRvIGEgPGNvZGU+TFNSZXNvdXJjZVJlc29sdmVyPC9jb2RlPiBvYmplY3QsIG9yIG51bGwuIElmCi0gICAgICogdGhlIHZhbHVlIG9mIHRoaXMgcGFyYW1ldGVyIGlzIG5vdCBudWxsIHdoZW4gYW4gZXh0ZXJuYWwgcmVzb3VyY2UKLSAgICAgKiAoc3VjaCBhcyBhbiBleHRlcm5hbCBYTUwgZW50aXR5IG9yIGFuIFhNTCBzY2hlbWEgbG9jYXRpb24pIGlzCi0gICAgICogZW5jb3VudGVyZWQsIHRoZSBpbXBsZW1lbnRhdGlvbiB3aWxsIHJlcXVlc3QgdGhhdCB0aGUKLSAgICAgKiA8Y29kZT5MU1Jlc291cmNlUmVzb2x2ZXI8L2NvZGU+IHJlZmVyZW5jZWQgaW4gdGhpcyBwYXJhbWV0ZXIgcmVzb2x2ZXMKLSAgICAgKiB0aGUgcmVzb3VyY2UuIDwvZGQ+Ci0gICAgICogPGR0Pjxjb2RlPiJzdXBwb3J0ZWQtbWVkaWEtdHlwZXMtb25seSI8L2NvZGU+PC9kdD4KLSAgICAgKiA8ZGQ+Ci0gICAgICogPGRsPgotICAgICAqIDxkdD4KLSAgICAgKiA8Y29kZT50cnVlPC9jb2RlPjwvZHQ+Ci0gICAgICogPGRkPls8ZW0+b3B0aW9uYWw8L2VtPl0gQ2hlY2sgdGhhdCB0aGUgbWVkaWEgdHlwZSBvZiB0aGUgcGFyc2VkIHJlc291cmNlIGlzIGEgc3VwcG9ydGVkIG1lZGlhCi0gICAgICogdHlwZS4gSWYgYW4gdW5zdXBwb3J0ZWQgbWVkaWEgdHlwZSBpcyBlbmNvdW50ZXJlZCwgYSBmYXRhbCBlcnJvciBvZgotICAgICAqIHR5cGUgPGI+InVuc3VwcG9ydGVkLW1lZGlhLXR5cGUiPC9iPiB3aWxsIGJlIHJhaXNlZC4gVGhlIG1lZGlhIHR5cGVzIGRlZmluZWQgaW4gWzxhIGhyZWY9J2h0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzMwMjMudHh0Jz5JRVRGIFJGQyAzMDIzPC9hPl0gbXVzdCBhbHdheXMKLSAgICAgKiBiZSBhY2NlcHRlZC4gPC9kZD4KLSAgICAgKiA8ZHQ+PGNvZGU+ZmFsc2U8L2NvZGU+PC9kdD4KLSAgICAgKiA8ZGQ+WzxlbT5yZXF1aXJlZDwvZW0+XSAoPGVtPmRlZmF1bHQ8L2VtPikgQWNjZXB0IGFueSBtZWRpYSB0eXBlLiA8L2RkPgotICAgICAqIDwvZGw+PC9kZD4KLSAgICAgKiA8ZHQ+PGNvZGU+InZhbGlkYXRlIjwvY29kZT48L2R0PgotICAgICAqIDxkZD4gU2VlIHRoZSBkZWZpbml0aW9uIG9mCi0gICAgICogPGNvZGU+RE9NQ29uZmlndXJhdGlvbjwvY29kZT4gZm9yIGEgZGVzY3JpcHRpb24gb2YgdGhpcyBwYXJhbWV0ZXIuCi0gICAgICogVW5saWtlIGluIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy1ET00tTGV2ZWwtMy1Db3JlLTIwMDQwNDA3Jz5ET00gTGV2ZWwgMyBDb3JlPC9hPl0KLSAgICAgKiAsIHRoZSBwcm9jZXNzaW5nIG9mIHRoZSBpbnRlcm5hbCBzdWJzZXQgaXMgYWx3YXlzIGFjY29tcGxpc2hlZCwgZXZlbgotICAgICAqIGlmIHRoaXMgcGFyYW1ldGVyIGlzIHNldCB0byA8Y29kZT5mYWxzZTwvY29kZT4uIDwvZGQ+Ci0gICAgICogPGR0PgotICAgICAqIDxjb2RlPiJ2YWxpZGF0ZS1pZi1zY2hlbWEiPC9jb2RlPjwvZHQ+Ci0gICAgICogPGRkPiBTZWUgdGhlIGRlZmluaXRpb24gb2YKLSAgICAgKiA8Y29kZT5ET01Db25maWd1cmF0aW9uPC9jb2RlPiBmb3IgYSBkZXNjcmlwdGlvbiBvZiB0aGlzIHBhcmFtZXRlci4KLSAgICAgKiBVbmxpa2UgaW4gWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLURPTS1MZXZlbC0zLUNvcmUtMjAwNDA0MDcnPkRPTSBMZXZlbCAzIENvcmU8L2E+XQotICAgICAqICwgdGhlIHByb2Nlc3Npbmcgb2YgdGhlIGludGVybmFsIHN1YnNldCBpcyBhbHdheXMgYWNjb21wbGlzaGVkLCBldmVuCi0gICAgICogaWYgdGhpcyBwYXJhbWV0ZXIgaXMgc2V0IHRvIDxjb2RlPmZhbHNlPC9jb2RlPi4gPC9kZD4KLSAgICAgKiA8ZHQ+Ci0gICAgICogPGNvZGU+IndlbGwtZm9ybWVkIjwvY29kZT48L2R0PgotICAgICAqIDxkZD4gU2VlIHRoZSBkZWZpbml0aW9uIG9mCi0gICAgICogPGNvZGU+RE9NQ29uZmlndXJhdGlvbjwvY29kZT4gZm9yIGEgZGVzY3JpcHRpb24gb2YgdGhpcyBwYXJhbWV0ZXIuCi0gICAgICogVW5saWtlIGluIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy1ET00tTGV2ZWwtMy1Db3JlLTIwMDQwNDA3Jz5ET00gTGV2ZWwgMyBDb3JlPC9hPl0KLSAgICAgKiAsIHRoaXMgcGFyYW1ldGVyIGNhbm5vdCBiZSBzZXQgdG8gPGNvZGU+ZmFsc2U8L2NvZGU+LiA8L2RkPgotICAgICAqIDwvZGw+Ci0gICAgICovCi0gICAgcHVibGljIERPTUNvbmZpZ3VyYXRpb24gZ2V0RG9tQ29uZmlnKCk7Ci0KLSAgICAvKioKLSAgICAgKiAgV2hlbiBhIGZpbHRlciBpcyBwcm92aWRlZCwgdGhlIGltcGxlbWVudGF0aW9uIHdpbGwgY2FsbCBvdXQgdG8gdGhlCi0gICAgICogZmlsdGVyIGFzIGl0IGlzIGNvbnN0cnVjdGluZyB0aGUgRE9NIHRyZWUgc3RydWN0dXJlLiBUaGUgZmlsdGVyIGNhbgotICAgICAqIGNob29zZSB0byByZW1vdmUgZWxlbWVudHMgZnJvbSB0aGUgZG9jdW1lbnQgYmVpbmcgY29uc3RydWN0ZWQsIG9yIHRvCi0gICAgICogdGVybWluYXRlIHRoZSBwYXJzaW5nIGVhcmx5LgotICAgICAqIDxicj4gVGhlIGZpbHRlciBpcyBpbnZva2VkIGFmdGVyIHRoZSBvcGVyYXRpb25zIHJlcXVlc3RlZCBieSB0aGUKLSAgICAgKiA8Y29kZT5ET01Db25maWd1cmF0aW9uPC9jb2RlPiBwYXJhbWV0ZXJzIGhhdmUgYmVlbiBhcHBsaWVkLiBGb3IKLSAgICAgKiBleGFtcGxlLCBpZiAiPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTMtQ29yZS9jb3JlLmh0bWwjcGFyYW1ldGVyLXZhbGlkYXRlJz4KLSAgICAgKiB2YWxpZGF0ZTwvYT4iIGlzIHNldCB0byA8Y29kZT50cnVlPC9jb2RlPiwgdGhlIHZhbGlkYXRpb24gaXMgZG9uZSBiZWZvcmUgaW52b2tpbmcgdGhlCi0gICAgICogZmlsdGVyLgotICAgICAqLwotICAgIHB1YmxpYyBMU1BhcnNlckZpbHRlciBnZXRGaWx0ZXIoKTsKLSAgICAvKioKLSAgICAgKiAgV2hlbiBhIGZpbHRlciBpcyBwcm92aWRlZCwgdGhlIGltcGxlbWVudGF0aW9uIHdpbGwgY2FsbCBvdXQgdG8gdGhlCi0gICAgICogZmlsdGVyIGFzIGl0IGlzIGNvbnN0cnVjdGluZyB0aGUgRE9NIHRyZWUgc3RydWN0dXJlLiBUaGUgZmlsdGVyIGNhbgotICAgICAqIGNob29zZSB0byByZW1vdmUgZWxlbWVudHMgZnJvbSB0aGUgZG9jdW1lbnQgYmVpbmcgY29uc3RydWN0ZWQsIG9yIHRvCi0gICAgICogdGVybWluYXRlIHRoZSBwYXJzaW5nIGVhcmx5LgotICAgICAqIDxicj4gVGhlIGZpbHRlciBpcyBpbnZva2VkIGFmdGVyIHRoZSBvcGVyYXRpb25zIHJlcXVlc3RlZCBieSB0aGUKLSAgICAgKiA8Y29kZT5ET01Db25maWd1cmF0aW9uPC9jb2RlPiBwYXJhbWV0ZXJzIGhhdmUgYmVlbiBhcHBsaWVkLiBGb3IKLSAgICAgKiBleGFtcGxlLCBpZiAiPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTMtQ29yZS9jb3JlLmh0bWwjcGFyYW1ldGVyLXZhbGlkYXRlJz4KLSAgICAgKiB2YWxpZGF0ZTwvYT4iIGlzIHNldCB0byA8Y29kZT50cnVlPC9jb2RlPiwgdGhlIHZhbGlkYXRpb24gaXMgZG9uZSBiZWZvcmUgaW52b2tpbmcgdGhlCi0gICAgICogZmlsdGVyLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEZpbHRlcihMU1BhcnNlckZpbHRlciBmaWx0ZXIpOwotCi0gICAgLyoqCi0gICAgICogIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSA8Y29kZT5MU1BhcnNlcjwvY29kZT4gaXMgYXN5bmNocm9ub3VzLAotICAgICAqIDxjb2RlPmZhbHNlPC9jb2RlPiBpZiBpdCBpcyBzeW5jaHJvbm91cy4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXRBc3luYygpOwotCi0gICAgLyoqCi0gICAgICogIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSA8Y29kZT5MU1BhcnNlcjwvY29kZT4gaXMgY3VycmVudGx5IGJ1c3kKLSAgICAgKiBsb2FkaW5nIGEgZG9jdW1lbnQsIG90aGVyd2lzZSA8Y29kZT5mYWxzZTwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0QnVzeSgpOwotCi0gICAgLyoqCi0gICAgICogUGFyc2UgYW4gWE1MIGRvY3VtZW50IGZyb20gYSByZXNvdXJjZSBpZGVudGlmaWVkIGJ5IGEKLSAgICAgKiA8Y29kZT5MU0lucHV0PC9jb2RlPi4KLSAgICAgKiBAcGFyYW0gaW5wdXQgIFRoZSA8Y29kZT5MU0lucHV0PC9jb2RlPiBmcm9tIHdoaWNoIHRoZSBzb3VyY2Ugb2YgdGhlCi0gICAgICogICBkb2N1bWVudCBpcyB0byBiZSByZWFkLgotICAgICAqIEByZXR1cm4gIElmIHRoZSA8Y29kZT5MU1BhcnNlcjwvY29kZT4gaXMgYSBzeW5jaHJvbm91cwotICAgICAqICAgPGNvZGU+TFNQYXJzZXI8L2NvZGU+LCB0aGUgbmV3bHkgY3JlYXRlZCBhbmQgcG9wdWxhdGVkCi0gICAgICogICA8Y29kZT5Eb2N1bWVudDwvY29kZT4gaXMgcmV0dXJuZWQuIElmIHRoZSA8Y29kZT5MU1BhcnNlcjwvY29kZT4gaXMKLSAgICAgKiAgIGFzeW5jaHJvbm91cywgPGNvZGU+bnVsbDwvY29kZT4gaXMgcmV0dXJuZWQgc2luY2UgdGhlIGRvY3VtZW50Ci0gICAgICogICBvYmplY3QgbWF5IG5vdCB5ZXQgYmUgY29uc3RydWN0ZWQgd2hlbiB0aGlzIG1ldGhvZCByZXR1cm5zLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICAgSU5WQUxJRF9TVEFURV9FUlI6IFJhaXNlZCBpZiB0aGUgPGNvZGU+TFNQYXJzZXI8L2NvZGU+J3MKLSAgICAgKiAgIDxjb2RlPkxTUGFyc2VyLmJ1c3k8L2NvZGU+IGF0dHJpYnV0ZSBpcyA8Y29kZT50cnVlPC9jb2RlPi4KLSAgICAgKiBAZXhjZXB0aW9uIExTRXhjZXB0aW9uCi0gICAgICogICAgUEFSU0VfRVJSOiBSYWlzZWQgaWYgdGhlIDxjb2RlPkxTUGFyc2VyPC9jb2RlPiB3YXMgdW5hYmxlIHRvIGxvYWQKLSAgICAgKiAgIHRoZSBYTUwgZG9jdW1lbnQuIERPTSBhcHBsaWNhdGlvbnMgc2hvdWxkIGF0dGFjaCBhCi0gICAgICogICA8Y29kZT5ET01FcnJvckhhbmRsZXI8L2NvZGU+IHVzaW5nIHRoZSBwYXJhbWV0ZXIgIjxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0zLUNvcmUvY29yZS5odG1sI3BhcmFtZXRlci1lcnJvci1oYW5kbGVyJz4KLSAgICAgKiAgIGVycm9yLWhhbmRsZXI8L2E+IiBpZiB0aGV5IHdpc2ggdG8gZ2V0IGRldGFpbHMgb24gdGhlIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyBEb2N1bWVudCBwYXJzZShMU0lucHV0IGlucHV0KQotICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uLCBMU0V4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBQYXJzZSBhbiBYTUwgZG9jdW1lbnQgZnJvbSBhIGxvY2F0aW9uIGlkZW50aWZpZWQgYnkgYSBVUkkgcmVmZXJlbmNlIFs8YSBocmVmPSdodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyMzk2LnR4dCc+SUVURiBSRkMgMjM5NjwvYT5dLiBJZiB0aGUgVVJJCi0gICAgICogY29udGFpbnMgYSBmcmFnbWVudCBpZGVudGlmaWVyIChzZWUgc2VjdGlvbiA0LjEgaW4gWzxhIGhyZWY9J2h0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzIzOTYudHh0Jz5JRVRGIFJGQyAyMzk2PC9hPl0pLCB0aGUKLSAgICAgKiBiZWhhdmlvciBpcyBub3QgZGVmaW5lZCBieSB0aGlzIHNwZWNpZmljYXRpb24sIGZ1dHVyZSB2ZXJzaW9ucyBvZgotICAgICAqIHRoaXMgc3BlY2lmaWNhdGlvbiBtYXkgZGVmaW5lIHRoZSBiZWhhdmlvci4KLSAgICAgKiBAcGFyYW0gdXJpIFRoZSBsb2NhdGlvbiBvZiB0aGUgWE1MIGRvY3VtZW50IHRvIGJlIHJlYWQuCi0gICAgICogQHJldHVybiAgSWYgdGhlIDxjb2RlPkxTUGFyc2VyPC9jb2RlPiBpcyBhIHN5bmNocm9ub3VzCi0gICAgICogICA8Y29kZT5MU1BhcnNlcjwvY29kZT4sIHRoZSBuZXdseSBjcmVhdGVkIGFuZCBwb3B1bGF0ZWQKLSAgICAgKiAgIDxjb2RlPkRvY3VtZW50PC9jb2RlPiBpcyByZXR1cm5lZCwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgYW4gZXJyb3IKLSAgICAgKiAgIG9jY3VyZWQuIElmIHRoZSA8Y29kZT5MU1BhcnNlcjwvY29kZT4gaXMgYXN5bmNocm9ub3VzLAotICAgICAqICAgPGNvZGU+bnVsbDwvY29kZT4gaXMgcmV0dXJuZWQgc2luY2UgdGhlIGRvY3VtZW50IG9iamVjdCBtYXkgbm90IHlldAotICAgICAqICAgYmUgY29uc3RydWN0ZWQgd2hlbiB0aGlzIG1ldGhvZCByZXR1cm5zLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICAgSU5WQUxJRF9TVEFURV9FUlI6IFJhaXNlZCBpZiB0aGUgPGNvZGU+TFNQYXJzZXIuYnVzeTwvY29kZT4KLSAgICAgKiAgIGF0dHJpYnV0ZSBpcyA8Y29kZT50cnVlPC9jb2RlPi4KLSAgICAgKiBAZXhjZXB0aW9uIExTRXhjZXB0aW9uCi0gICAgICogICAgUEFSU0VfRVJSOiBSYWlzZWQgaWYgdGhlIDxjb2RlPkxTUGFyc2VyPC9jb2RlPiB3YXMgdW5hYmxlIHRvIGxvYWQKLSAgICAgKiAgIHRoZSBYTUwgZG9jdW1lbnQuIERPTSBhcHBsaWNhdGlvbnMgc2hvdWxkIGF0dGFjaCBhCi0gICAgICogICA8Y29kZT5ET01FcnJvckhhbmRsZXI8L2NvZGU+IHVzaW5nIHRoZSBwYXJhbWV0ZXIgIjxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0zLUNvcmUvY29yZS5odG1sI3BhcmFtZXRlci1lcnJvci1oYW5kbGVyJz4KLSAgICAgKiAgIGVycm9yLWhhbmRsZXI8L2E+IiBpZiB0aGV5IHdpc2ggdG8gZ2V0IGRldGFpbHMgb24gdGhlIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyBEb2N1bWVudCBwYXJzZVVSSShTdHJpbmcgdXJpKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uLCBMU0V4Y2VwdGlvbjsKLQotICAgIC8vIEFDVElPTl9UWVBFUwotICAgIC8qKgotICAgICAqICBBcHBlbmQgdGhlIHJlc3VsdCBvZiB0aGUgcGFyc2Ugb3BlcmF0aW9uIGFzIGNoaWxkcmVuIG9mIHRoZSBjb250ZXh0Ci0gICAgICogbm9kZS4gRm9yIHRoaXMgYWN0aW9uIHRvIHdvcmssIHRoZSBjb250ZXh0IG5vZGUgbXVzdCBiZSBhbgotICAgICAqIDxjb2RlPkVsZW1lbnQ8L2NvZGU+IG9yIGEgPGNvZGU+RG9jdW1lbnRGcmFnbWVudDwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBBQ1RJT05fQVBQRU5EX0FTX0NISUxEUkVOID0gMTsKLSAgICAvKioKLSAgICAgKiAgUmVwbGFjZSBhbGwgdGhlIGNoaWxkcmVuIG9mIHRoZSBjb250ZXh0IG5vZGUgd2l0aCB0aGUgcmVzdWx0IG9mIHRoZQotICAgICAqIHBhcnNlIG9wZXJhdGlvbi4gRm9yIHRoaXMgYWN0aW9uIHRvIHdvcmssIHRoZSBjb250ZXh0IG5vZGUgbXVzdCBiZSBhbgotICAgICAqIDxjb2RlPkVsZW1lbnQ8L2NvZGU+LCBhIDxjb2RlPkRvY3VtZW50PC9jb2RlPiwgb3IgYQotICAgICAqIDxjb2RlPkRvY3VtZW50RnJhZ21lbnQ8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgQUNUSU9OX1JFUExBQ0VfQ0hJTERSRU4gICA9IDI7Ci0gICAgLyoqCi0gICAgICogIEluc2VydCB0aGUgcmVzdWx0IG9mIHRoZSBwYXJzZSBvcGVyYXRpb24gYXMgdGhlIGltbWVkaWF0ZWx5IHByZWNlZGluZwotICAgICAqIHNpYmxpbmcgb2YgdGhlIGNvbnRleHQgbm9kZS4gRm9yIHRoaXMgYWN0aW9uIHRvIHdvcmsgdGhlIGNvbnRleHQKLSAgICAgKiBub2RlJ3MgcGFyZW50IG11c3QgYmUgYW4gPGNvZGU+RWxlbWVudDwvY29kZT4gb3IgYQotICAgICAqIDxjb2RlPkRvY3VtZW50RnJhZ21lbnQ8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgQUNUSU9OX0lOU0VSVF9CRUZPUkUgICAgICA9IDM7Ci0gICAgLyoqCi0gICAgICogIEluc2VydCB0aGUgcmVzdWx0IG9mIHRoZSBwYXJzZSBvcGVyYXRpb24gYXMgdGhlIGltbWVkaWF0ZWx5IGZvbGxvd2luZwotICAgICAqIHNpYmxpbmcgb2YgdGhlIGNvbnRleHQgbm9kZS4gRm9yIHRoaXMgYWN0aW9uIHRvIHdvcmsgdGhlIGNvbnRleHQKLSAgICAgKiBub2RlJ3MgcGFyZW50IG11c3QgYmUgYW4gPGNvZGU+RWxlbWVudDwvY29kZT4gb3IgYQotICAgICAqIDxjb2RlPkRvY3VtZW50RnJhZ21lbnQ8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgQUNUSU9OX0lOU0VSVF9BRlRFUiAgICAgICA9IDQ7Ci0gICAgLyoqCi0gICAgICogIFJlcGxhY2UgdGhlIGNvbnRleHQgbm9kZSB3aXRoIHRoZSByZXN1bHQgb2YgdGhlIHBhcnNlIG9wZXJhdGlvbi4gRm9yCi0gICAgICogdGhpcyBhY3Rpb24gdG8gd29yaywgdGhlIGNvbnRleHQgbm9kZSBtdXN0IGhhdmUgYSBwYXJlbnQsIGFuZCB0aGUKLSAgICAgKiBwYXJlbnQgbXVzdCBiZSBhbiA8Y29kZT5FbGVtZW50PC9jb2RlPiBvciBhCi0gICAgICogPGNvZGU+RG9jdW1lbnRGcmFnbWVudDwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBBQ1RJT05fUkVQTEFDRSAgICAgICAgICAgID0gNTsKLQotICAgIC8qKgotICAgICAqICBQYXJzZSBhbiBYTUwgZnJhZ21lbnQgZnJvbSBhIHJlc291cmNlIGlkZW50aWZpZWQgYnkgYQotICAgICAqIDxjb2RlPkxTSW5wdXQ8L2NvZGU+IGFuZCBpbnNlcnQgdGhlIGNvbnRlbnQgaW50byBhbiBleGlzdGluZyBkb2N1bWVudAotICAgICAqIGF0IHRoZSBwb3NpdGlvbiBzcGVjaWZpZWQgd2l0aCB0aGUgPGNvZGU+Y29udGV4dDwvY29kZT4gYW5kCi0gICAgICogPGNvZGU+YWN0aW9uPC9jb2RlPiBhcmd1bWVudHMuIFdoZW4gcGFyc2luZyB0aGUgaW5wdXQgc3RyZWFtLCB0aGUKLSAgICAgKiBjb250ZXh0IG5vZGUgKG9yIGl0cyBwYXJlbnQsIGRlcGVuZGluZyBvbiB3aGVyZSB0aGUgcmVzdWx0IHdpbGwgYmUKLSAgICAgKiBpbnNlcnRlZCkgaXMgdXNlZCBmb3IgcmVzb2x2aW5nIHVuYm91bmQgbmFtZXNwYWNlIHByZWZpeGVzLiBUaGUKLSAgICAgKiBjb250ZXh0IG5vZGUncyA8Y29kZT5vd25lckRvY3VtZW50PC9jb2RlPiBub2RlIChvciB0aGUgbm9kZSBpdHNlbGYgaWYKLSAgICAgKiB0aGUgbm9kZSBvZiB0eXBlIDxjb2RlPkRPQ1VNRU5UX05PREU8L2NvZGU+KSBpcyB1c2VkIHRvIHJlc29sdmUKLSAgICAgKiBkZWZhdWx0IGF0dHJpYnV0ZXMgYW5kIGVudGl0eSByZWZlcmVuY2VzLgotICAgICAqIDxicj4gQXMgdGhlIG5ldyBkYXRhIGlzIGluc2VydGVkIGludG8gdGhlIGRvY3VtZW50LCBhdCBsZWFzdCBvbmUKLSAgICAgKiBtdXRhdGlvbiBldmVudCBpcyBmaXJlZCBwZXIgbmV3IGltbWVkaWF0ZSBjaGlsZCBvciBzaWJsaW5nIG9mIHRoZQotICAgICAqIGNvbnRleHQgbm9kZS4KLSAgICAgKiA8YnI+IElmIHRoZSBjb250ZXh0IG5vZGUgaXMgYSA8Y29kZT5Eb2N1bWVudDwvY29kZT4gbm9kZSBhbmQgdGhlIGFjdGlvbgotICAgICAqIGlzIDxjb2RlPkFDVElPTl9SRVBMQUNFX0NISUxEUkVOPC9jb2RlPiwgdGhlbiB0aGUgZG9jdW1lbnQgdGhhdCBpcwotICAgICAqIHBhc3NlZCBhcyB0aGUgY29udGV4dCBub2RlIHdpbGwgYmUgY2hhbmdlZCBzdWNoIHRoYXQgaXRzCi0gICAgICogPGNvZGU+eG1sRW5jb2Rpbmc8L2NvZGU+LCA8Y29kZT5kb2N1bWVudFVSSTwvY29kZT4sCi0gICAgICogPGNvZGU+eG1sVmVyc2lvbjwvY29kZT4sIDxjb2RlPmlucHV0RW5jb2Rpbmc8L2NvZGU+LAotICAgICAqIDxjb2RlPnhtbFN0YW5kYWxvbmU8L2NvZGU+LCBhbmQgYWxsIG90aGVyIHN1Y2ggYXR0cmlidXRlcyBhcmUgc2V0IHRvCi0gICAgICogd2hhdCB0aGV5IHdvdWxkIGJlIHNldCB0byBpZiB0aGUgaW5wdXQgc291cmNlIHdhcyBwYXJzZWQgdXNpbmcKLSAgICAgKiA8Y29kZT5MU1BhcnNlci5wYXJzZSgpPC9jb2RlPi4KLSAgICAgKiA8YnI+IFRoaXMgbWV0aG9kIGlzIGFsd2F5cyBzeW5jaHJvbm91cywgZXZlbiBpZiB0aGUKLSAgICAgKiA8Y29kZT5MU1BhcnNlcjwvY29kZT4gaXMgYXN5bmNocm9ub3VzICg8Y29kZT5MU1BhcnNlci5hc3luYzwvY29kZT4gaXMKLSAgICAgKiA8Y29kZT50cnVlPC9jb2RlPikuCi0gICAgICogPGJyPiBJZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgcGFyc2luZywgdGhlIGNhbGxlciBpcyBub3RpZmllZCB0aHJvdWdoCi0gICAgICogdGhlIDxjb2RlPkVycm9ySGFuZGxlcjwvY29kZT4gaW5zdGFuY2UgYXNzb2NpYXRlZCB3aXRoIHRoZSAiPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTMtQ29yZS9jb3JlLmh0bWwjcGFyYW1ldGVyLWVycm9yLWhhbmRsZXInPgotICAgICAqIGVycm9yLWhhbmRsZXI8L2E+IiBwYXJhbWV0ZXIgb2YgdGhlIDxjb2RlPkRPTUNvbmZpZ3VyYXRpb248L2NvZGU+LgotICAgICAqIDxicj4gV2hlbiBjYWxsaW5nIDxjb2RlPnBhcnNlV2l0aENvbnRleHQ8L2NvZGU+LCB0aGUgdmFsdWVzIG9mIHRoZQotICAgICAqIGZvbGxvd2luZyBjb25maWd1cmF0aW9uIHBhcmFtZXRlcnMgd2lsbCBiZSBpZ25vcmVkIGFuZCB0aGVpciBkZWZhdWx0Ci0gICAgICogdmFsdWVzIHdpbGwgYWx3YXlzIGJlIHVzZWQgaW5zdGVhZDogIjxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0zLUNvcmUvY29yZS5odG1sI3BhcmFtZXRlci12YWxpZGF0ZSc+Ci0gICAgICogdmFsaWRhdGU8L2E+IiwgIjxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0zLUNvcmUvY29yZS5odG1sI3BhcmFtZXRlci12YWxpZGF0ZS1pZi1zY2hlbWEnPgotICAgICAqIHZhbGlkYXRlLWlmLXNjaGVtYTwvYT4iLCBhbmQgIjxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0zLUNvcmUvY29yZS5odG1sI3BhcmFtZXRlci1lbGVtZW50LWNvbnRlbnQtd2hpdGVzcGFjZSc+Ci0gICAgICogZWxlbWVudC1jb250ZW50LXdoaXRlc3BhY2U8L2E+Ii4gT3RoZXIgcGFyYW1ldGVycyB3aWxsIGJlIHRyZWF0ZWQgbm9ybWFsbHksIGFuZCB0aGUgcGFyc2VyIGlzIGV4cGVjdGVkCi0gICAgICogdG8gY2FsbCB0aGUgPGNvZGU+TFNQYXJzZXJGaWx0ZXI8L2NvZGU+IGp1c3QgYXMgaWYgYSB3aG9sZSBkb2N1bWVudAotICAgICAqIHdhcyBwYXJzZWQuCi0gICAgICogQHBhcmFtIGlucHV0ICBUaGUgPGNvZGU+TFNJbnB1dDwvY29kZT4gZnJvbSB3aGljaCB0aGUgc291cmNlIGRvY3VtZW50Ci0gICAgICogICBpcyB0byBiZSByZWFkLiBUaGUgc291cmNlIGRvY3VtZW50IG11c3QgYmUgYW4gWE1MIGZyYWdtZW50LCBpLmUuCi0gICAgICogICBhbnl0aGluZyBleGNlcHQgYSBjb21wbGV0ZSBYTUwgZG9jdW1lbnQgKGV4Y2VwdCBpbiB0aGUgY2FzZSB3aGVyZQotICAgICAqICAgdGhlIGNvbnRleHQgbm9kZSBvZiB0eXBlIDxjb2RlPkRPQ1VNRU5UX05PREU8L2NvZGU+LCBhbmQgdGhlIGFjdGlvbgotICAgICAqICAgaXMgPGNvZGU+QUNUSU9OX1JFUExBQ0VfQ0hJTERSRU48L2NvZGU+KSwgYSBET0NUWVBFIChpbnRlcm5hbAotICAgICAqICAgc3Vic2V0KSwgZW50aXR5IGRlY2xhcmF0aW9uKHMpLCBub3RhdGlvbiBkZWNsYXJhdGlvbihzKSwgb3IgWE1MIG9yCi0gICAgICogICB0ZXh0IGRlY2xhcmF0aW9uKHMpLgotICAgICAqIEBwYXJhbSBjb250ZXh0QXJnICBUaGUgbm9kZSB0aGF0IGlzIHVzZWQgYXMgdGhlIGNvbnRleHQgZm9yIHRoZSBkYXRhCi0gICAgICogICB0aGF0IGlzIGJlaW5nIHBhcnNlZC4gVGhpcyBub2RlIG11c3QgYmUgYSA8Y29kZT5Eb2N1bWVudDwvY29kZT4KLSAgICAgKiAgIG5vZGUsIGEgPGNvZGU+RG9jdW1lbnRGcmFnbWVudDwvY29kZT4gbm9kZSwgb3IgYSBub2RlIG9mIGEgdHlwZQotICAgICAqICAgdGhhdCBpcyBhbGxvd2VkIGFzIGEgY2hpbGQgb2YgYW4gPGNvZGU+RWxlbWVudDwvY29kZT4gbm9kZSwgZS5nLiBpdAotICAgICAqICAgY2Fubm90IGJlIGFuIDxjb2RlPkF0dHJpYnV0ZTwvY29kZT4gbm9kZS4KLSAgICAgKiBAcGFyYW0gYWN0aW9uICBUaGlzIHBhcmFtZXRlciBkZXNjcmliZXMgd2hpY2ggYWN0aW9uIHNob3VsZCBiZSB0YWtlbgotICAgICAqICAgYmV0d2VlbiB0aGUgbmV3IHNldCBvZiBub2RlcyBiZWluZyBpbnNlcnRlZCBhbmQgdGhlIGV4aXN0aW5nCi0gICAgICogICBjaGlsZHJlbiBvZiB0aGUgY29udGV4dCBub2RlLiBUaGUgc2V0IG9mIHBvc3NpYmxlIGFjdGlvbnMgaXMKLSAgICAgKiAgIGRlZmluZWQgaW4gPGNvZGU+QUNUSU9OX1RZUEVTPC9jb2RlPiBhYm92ZS4KLSAgICAgKiBAcmV0dXJuICBSZXR1cm4gdGhlIG5vZGUgdGhhdCBpcyB0aGUgcmVzdWx0IG9mIHRoZSBwYXJzZSBvcGVyYXRpb24uIElmCi0gICAgICogICB0aGUgcmVzdWx0IGlzIG1vcmUgdGhhbiBvbmUgdG9wLWxldmVsIG5vZGUsIHRoZSBmaXJzdCBvbmUgaXMKLSAgICAgKiAgIHJldHVybmVkLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBISUVSQVJDSFlfUkVRVUVTVF9FUlI6IFJhaXNlZCBpZiB0aGUgY29udGVudCBjYW5ub3QgcmVwbGFjZSwgYmUKLSAgICAgKiAgIGluc2VydGVkIGJlZm9yZSwgYWZ0ZXIsIG9yIGFzIGEgY2hpbGQgb2YgdGhlIGNvbnRleHQgbm9kZSAoc2VlIGFsc28KLSAgICAgKiAgIDxjb2RlPk5vZGUuaW5zZXJ0QmVmb3JlPC9jb2RlPiBvciA8Y29kZT5Ob2RlLnJlcGxhY2VDaGlsZDwvY29kZT4gaW4gWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLURPTS1MZXZlbC0zLUNvcmUtMjAwNDA0MDcnPkRPTSBMZXZlbCAzIENvcmU8L2E+XQotICAgICAqICAgKS4KLSAgICAgKiAgIDxicj4gTk9UX1NVUFBPUlRFRF9FUlI6IFJhaXNlZCBpZiB0aGUgPGNvZGU+TFNQYXJzZXI8L2NvZGU+IGRvZXNuJ3QKLSAgICAgKiAgIHN1cHBvcnQgdGhpcyBtZXRob2QsIG9yIGlmIHRoZSBjb250ZXh0IG5vZGUgaXMgb2YgdHlwZQotICAgICAqICAgPGNvZGU+RG9jdW1lbnQ8L2NvZGU+IGFuZCB0aGUgRE9NIGltcGxlbWVudGF0aW9uIGRvZXNuJ3Qgc3VwcG9ydAotICAgICAqICAgdGhlIHJlcGxhY2VtZW50IG9mIHRoZSA8Y29kZT5Eb2N1bWVudFR5cGU8L2NvZGU+IGNoaWxkIG9yCi0gICAgICogICA8Y29kZT5FbGVtZW50PC9jb2RlPiBjaGlsZC4KLSAgICAgKiAgIDxicj4gTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhlIGNvbnRleHQgbm9kZSBpcyBhCi0gICAgICogICByZWFkIG9ubHkgbm9kZSBhbmQgdGhlIGNvbnRlbnQgaXMgYmVpbmcgYXBwZW5kZWQgdG8gaXRzIGNoaWxkIGxpc3QsCi0gICAgICogICBvciBpZiB0aGUgcGFyZW50IG5vZGUgb2YgdGhlIGNvbnRleHQgbm9kZSBpcyByZWFkIG9ubHkgbm9kZSBhbmQgdGhlCi0gICAgICogICBjb250ZW50IGlzIGJlaW5nIGluc2VydGVkIGluIGl0cyBjaGlsZCBsaXN0LgotICAgICAqICAgPGJyPiBJTlZBTElEX1NUQVRFX0VSUjogUmFpc2VkIGlmIHRoZSA8Y29kZT5MU1BhcnNlci5idXN5PC9jb2RlPgotICAgICAqICAgYXR0cmlidXRlIGlzIDxjb2RlPnRydWU8L2NvZGU+LgotICAgICAqIEBleGNlcHRpb24gTFNFeGNlcHRpb24KLSAgICAgKiAgICBQQVJTRV9FUlI6IFJhaXNlZCBpZiB0aGUgPGNvZGU+TFNQYXJzZXI8L2NvZGU+IHdhcyB1bmFibGUgdG8gbG9hZAotICAgICAqICAgdGhlIFhNTCBmcmFnbWVudC4gRE9NIGFwcGxpY2F0aW9ucyBzaG91bGQgYXR0YWNoIGEKLSAgICAgKiAgIDxjb2RlPkRPTUVycm9ySGFuZGxlcjwvY29kZT4gdXNpbmcgdGhlIHBhcmFtZXRlciAiPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTMtQ29yZS9jb3JlLmh0bWwjcGFyYW1ldGVyLWVycm9yLWhhbmRsZXInPgotICAgICAqICAgZXJyb3ItaGFuZGxlcjwvYT4iIGlmIHRoZXkgd2lzaCB0byBnZXQgZGV0YWlscyBvbiB0aGUgZXJyb3IuCi0gICAgICovCi0gICAgcHVibGljIE5vZGUgcGFyc2VXaXRoQ29udGV4dChMU0lucHV0IGlucHV0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTm9kZSBjb250ZXh0QXJnLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hvcnQgYWN0aW9uKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbiwgTFNFeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiAgQWJvcnQgdGhlIGxvYWRpbmcgb2YgdGhlIGRvY3VtZW50IHRoYXQgaXMgY3VycmVudGx5IGJlaW5nIGxvYWRlZCBieQotICAgICAqIHRoZSA8Y29kZT5MU1BhcnNlcjwvY29kZT4uIElmIHRoZSA8Y29kZT5MU1BhcnNlcjwvY29kZT4gaXMgY3VycmVudGx5Ci0gICAgICogbm90IGJ1c3ksIGEgY2FsbCB0byB0aGlzIG1ldGhvZCBkb2VzIG5vdGhpbmcuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgYWJvcnQoKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy93M2MvZG9tL2xzL0xTUGFyc2VyRmlsdGVyLmphdmEgYi9zcmMvb3JnL3czYy9kb20vbHMvTFNQYXJzZXJGaWx0ZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDYzOGMzOC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3czYy9kb20vbHMvTFNQYXJzZXJGaWx0ZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIwMSArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogVGhpcyBmaWxlIGlzIGF2YWlsYWJsZSB1bmRlciBhbmQgZ292ZXJuZWQgYnkgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwotICogTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKiBIb3dldmVyLCB0aGUgZm9sbG93aW5nIG5vdGljZSBhY2NvbXBhbmllZCB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGlzCi0gKiBmaWxlIGFuZCwgcGVyIGl0cyB0ZXJtcywgc2hvdWxkIG5vdCBiZSByZW1vdmVkOgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAotICoKLSAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBFdXJvcGVhbiBSZXNlYXJjaCBDb25zb3J0aXVtIGZvcgotICogSW5mb3JtYXRpY3MgYW5kIE1hdGhlbWF0aWNzLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwgUmlnaHRzIFJlc2VydmVkLiBUaGlzCi0gKiB3b3JrIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MocikgU29mdHdhcmUgTGljZW5zZSBbMV0gaW4gdGhlIGhvcGUgdGhhdAotICogaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkCi0gKiB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuCi0gKgotICogWzFdIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvMjAwMi9jb3B5cmlnaHQtc29mdHdhcmUtMjAwMjEyMzEKLSAqLwotCi1wYWNrYWdlIG9yZy53M2MuZG9tLmxzOwotCi1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcudzNjLmRvbS5FbGVtZW50OwotCi0vKioKLSAqICA8Y29kZT5MU1BhcnNlckZpbHRlcjwvY29kZT5zIHByb3ZpZGUgYXBwbGljYXRpb25zIHRoZSBhYmlsaXR5IHRvIGV4YW1pbmUKLSAqIG5vZGVzIGFzIHRoZXkgYXJlIGJlaW5nIGNvbnN0cnVjdGVkIHdoaWxlIHBhcnNpbmcuIEFzIGVhY2ggbm9kZSBpcwotICogZXhhbWluZWQsIGl0IG1heSBiZSBtb2RpZmllZCBvciByZW1vdmVkLCBvciB0aGUgZW50aXJlIHBhcnNlIG1heSBiZQotICogdGVybWluYXRlZCBlYXJseS4KLSAqIDxwPiBBdCB0aGUgdGltZSBhbnkgb2YgdGhlIGZpbHRlciBtZXRob2RzIGFyZSBjYWxsZWQgYnkgdGhlIHBhcnNlciwgdGhlCi0gKiBvd25lciBEb2N1bWVudCBhbmQgRE9NSW1wbGVtZW50YXRpb24gb2JqZWN0cyBleGlzdCBhbmQgYXJlIGFjY2Vzc2libGUuCi0gKiBUaGUgZG9jdW1lbnQgZWxlbWVudCBpcyBuZXZlciBwYXNzZWQgdG8gdGhlIDxjb2RlPkxTUGFyc2VyRmlsdGVyPC9jb2RlPgotICogbWV0aG9kcywgaS5lLiBpdCBpcyBub3QgcG9zc2libGUgdG8gZmlsdGVyIG91dCB0aGUgZG9jdW1lbnQgZWxlbWVudC4KLSAqIDxjb2RlPkRvY3VtZW50PC9jb2RlPiwgPGNvZGU+RG9jdW1lbnRUeXBlPC9jb2RlPiwgPGNvZGU+Tm90YXRpb248L2NvZGU+LAotICogPGNvZGU+RW50aXR5PC9jb2RlPiwgYW5kIDxjb2RlPkF0dHI8L2NvZGU+IG5vZGVzIGFyZSBuZXZlciBwYXNzZWQgdG8gdGhlCi0gKiA8Y29kZT5hY2NlcHROb2RlPC9jb2RlPiBtZXRob2Qgb24gdGhlIGZpbHRlci4gVGhlIGNoaWxkIG5vZGVzIG9mIGFuCi0gKiA8Y29kZT5FbnRpdHlSZWZlcmVuY2U8L2NvZGU+IG5vZGUgYXJlIHBhc3NlZCB0byB0aGUgZmlsdGVyIGlmIHRoZQotICogcGFyYW1ldGVyICI8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMy1Db3JlL2NvcmUuaHRtbCNwYXJhbWV0ZXItZW50aXRpZXMnPgotICogZW50aXRpZXM8L2E+IiBpcyBzZXQgdG8gPGNvZGU+ZmFsc2U8L2NvZGU+LiBOb3RlIHRoYXQsIGFzIGRlc2NyaWJlZCBieSB0aGUgcGFyYW1ldGVyICI8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMy1Db3JlL2NvcmUuaHRtbCNwYXJhbWV0ZXItZW50aXRpZXMnPgotICogZW50aXRpZXM8L2E+IiwgdW5leHBhbmRlZCBlbnRpdHkgcmVmZXJlbmNlIG5vZGVzIGFyZSBuZXZlciBkaXNjYXJkZWQgYW5kIGFyZSBhbHdheXMKLSAqIHBhc3NlZCB0byB0aGUgZmlsdGVyLgotICogPHA+IEFsbCB2YWxpZGl0eSBjaGVja2luZyB3aGlsZSBwYXJzaW5nIGEgZG9jdW1lbnQgb2NjdXJzIG9uIHRoZSBzb3VyY2UKLSAqIGRvY3VtZW50IGFzIGl0IGFwcGVhcnMgb24gdGhlIGlucHV0IHN0cmVhbSwgbm90IG9uIHRoZSBET00gZG9jdW1lbnQgYXMgaXQKLSAqIGlzIGJ1aWx0IGluIG1lbW9yeS4gV2l0aCBmaWx0ZXJzLCB0aGUgZG9jdW1lbnQgaW4gbWVtb3J5IG1heSBiZSBhIHN1YnNldAotICogb2YgdGhlIGRvY3VtZW50IG9uIHRoZSBzdHJlYW0sIGFuZCBpdHMgdmFsaWRpdHkgbWF5IGhhdmUgYmVlbiBhZmZlY3RlZCBieQotICogdGhlIGZpbHRlcmluZy4KLSAqIDxwPiBBbGwgZGVmYXVsdCBhdHRyaWJ1dGVzIG11c3QgYmUgcHJlc2VudCBvbiBlbGVtZW50cyB3aGVuIHRoZSBlbGVtZW50cwotICogYXJlIHBhc3NlZCB0byB0aGUgZmlsdGVyIG1ldGhvZHMuIEFsbCBvdGhlciBkZWZhdWx0IGNvbnRlbnQgbXVzdCBiZQotICogcGFzc2VkIHRvIHRoZSBmaWx0ZXIgbWV0aG9kcy4KLSAqIDxwPiBET00gYXBwbGljYXRpb25zIG11c3Qgbm90IHJhaXNlIGV4Y2VwdGlvbnMgaW4gYSBmaWx0ZXIuIFRoZSBlZmZlY3Qgb2YKLSAqIHRocm93aW5nIGV4Y2VwdGlvbnMgZnJvbSBhIGZpbHRlciBpcyBET00gaW1wbGVtZW50YXRpb24gZGVwZW5kZW50LgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLURPTS1MZXZlbC0zLUxTLTIwMDQwNDA3Jz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMyBMb2FkCi1hbmQgU2F2ZSBTcGVjaWZpY2F0aW9uPC9hPi4KLSAqLwotcHVibGljIGludGVyZmFjZSBMU1BhcnNlckZpbHRlciB7Ci0gICAgLy8gQ29uc3RhbnRzIHJldHVybmVkIGJ5IHN0YXJ0RWxlbWVudCBhbmQgYWNjZXB0Tm9kZQotICAgIC8qKgotICAgICAqIEFjY2VwdCB0aGUgbm9kZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IEZJTFRFUl9BQ0NFUFQgICAgICAgICAgICAgPSAxOwotICAgIC8qKgotICAgICAqIFJlamVjdCB0aGUgbm9kZSBhbmQgaXRzIGNoaWxkcmVuLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgRklMVEVSX1JFSkVDVCAgICAgICAgICAgICA9IDI7Ci0gICAgLyoqCi0gICAgICogU2tpcCB0aGlzIHNpbmdsZSBub2RlLiBUaGUgY2hpbGRyZW4gb2YgdGhpcyBub2RlIHdpbGwgc3RpbGwgYmUKLSAgICAgKiBjb25zaWRlcmVkLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgRklMVEVSX1NLSVAgICAgICAgICAgICAgICA9IDM7Ci0gICAgLyoqCi0gICAgICogIEludGVycnVwdCB0aGUgbm9ybWFsIHByb2Nlc3Npbmcgb2YgdGhlIGRvY3VtZW50LgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgRklMVEVSX0lOVEVSUlVQVCAgICAgICAgICA9IDQ7Ci0KLSAgICAvKioKLSAgICAgKiAgVGhlIHBhcnNlciB3aWxsIGNhbGwgdGhpcyBtZXRob2QgYWZ0ZXIgZWFjaCA8Y29kZT5FbGVtZW50PC9jb2RlPiBzdGFydAotICAgICAqIHRhZyBoYXMgYmVlbiBzY2FubmVkLCBidXQgYmVmb3JlIHRoZSByZW1haW5kZXIgb2YgdGhlCi0gICAgICogPGNvZGU+RWxlbWVudDwvY29kZT4gaXMgcHJvY2Vzc2VkLiBUaGUgaW50ZW50IGlzIHRvIGFsbG93IHRoZQotICAgICAqIGVsZW1lbnQsIGluY2x1ZGluZyBhbnkgY2hpbGRyZW4sIHRvIGJlIGVmZmljaWVudGx5IHNraXBwZWQuIE5vdGUgdGhhdAotICAgICAqIG9ubHkgZWxlbWVudCBub2RlcyBhcmUgcGFzc2VkIHRvIHRoZSA8Y29kZT5zdGFydEVsZW1lbnQ8L2NvZGU+Ci0gICAgICogZnVuY3Rpb24uCi0gICAgICogPGJyPlRoZSBlbGVtZW50IG5vZGUgcGFzc2VkIHRvIDxjb2RlPnN0YXJ0RWxlbWVudDwvY29kZT4gZm9yIGZpbHRlcmluZwotICAgICAqIHdpbGwgaW5jbHVkZSBhbGwgb2YgdGhlIEVsZW1lbnQncyBhdHRyaWJ1dGVzLCBidXQgbm9uZSBvZiB0aGUKLSAgICAgKiBjaGlsZHJlbiBub2Rlcy4gVGhlIEVsZW1lbnQgbWF5IG5vdCB5ZXQgYmUgaW4gcGxhY2UgaW4gdGhlIGRvY3VtZW50Ci0gICAgICogYmVpbmcgY29uc3RydWN0ZWQgKGl0IG1heSBub3QgaGF2ZSBhIHBhcmVudCBub2RlLikKLSAgICAgKiA8YnI+QSA8Y29kZT5zdGFydEVsZW1lbnQ8L2NvZGU+IGZpbHRlciBmdW5jdGlvbiBtYXkgYWNjZXNzIG9yIGNoYW5nZQotICAgICAqIHRoZSBhdHRyaWJ1dGVzIGZvciB0aGUgRWxlbWVudC4gQ2hhbmdpbmcgTmFtZXNwYWNlIGRlY2xhcmF0aW9ucyB3aWxsCi0gICAgICogaGF2ZSBubyBlZmZlY3Qgb24gbmFtZXNwYWNlIHJlc29sdXRpb24gYnkgdGhlIHBhcnNlci4KLSAgICAgKiA8YnI+Rm9yIGVmZmljaWVuY3ksIHRoZSBFbGVtZW50IG5vZGUgcGFzc2VkIHRvIHRoZSBmaWx0ZXIgbWF5IG5vdCBiZQotICAgICAqIHRoZSBzYW1lIG9uZSBhcyBpcyBhY3R1YWxseSBwbGFjZWQgaW4gdGhlIHRyZWUgaWYgdGhlIG5vZGUgaXMKLSAgICAgKiBhY2NlcHRlZC4gQW5kIHRoZSBhY3R1YWwgbm9kZSAobm9kZSBvYmplY3QgaWRlbnRpdHkpIG1heSBiZSByZXVzZWQKLSAgICAgKiBkdXJpbmcgdGhlIHByb2Nlc3Mgb2YgcmVhZGluZyBpbiBhbmQgZmlsdGVyaW5nIGEgZG9jdW1lbnQuCi0gICAgICogQHBhcmFtIGVsZW1lbnRBcmcgVGhlIG5ld2x5IGVuY291bnRlcmVkIGVsZW1lbnQuIEF0IHRoZSB0aW1lIHRoaXMKLSAgICAgKiAgIG1ldGhvZCBpcyBjYWxsZWQsIHRoZSBlbGVtZW50IGlzIGluY29tcGxldGUgLSBpdCB3aWxsIGhhdmUgaXRzCi0gICAgICogICBhdHRyaWJ1dGVzLCBidXQgbm8gY2hpbGRyZW4uCi0gICAgICogQHJldHVybgotICAgICAqIDx1bD4KLSAgICAgKiA8bGk+IDxjb2RlPkZJTFRFUl9BQ0NFUFQ8L2NvZGU+IGlmIHRoZSA8Y29kZT5FbGVtZW50PC9jb2RlPiBzaG91bGQKLSAgICAgKiAgIGJlIGluY2x1ZGVkIGluIHRoZSBET00gZG9jdW1lbnQgYmVpbmcgYnVpbHQuCi0gICAgICogPC9saT4KLSAgICAgKiA8bGk+Ci0gICAgICogICA8Y29kZT5GSUxURVJfUkVKRUNUPC9jb2RlPiBpZiB0aGUgPGNvZGU+RWxlbWVudDwvY29kZT4gYW5kIGFsbCBvZgotICAgICAqICAgaXRzIGNoaWxkcmVuIHNob3VsZCBiZSByZWplY3RlZC4KLSAgICAgKiA8L2xpPgotICAgICAqIDxsaT4gPGNvZGU+RklMVEVSX1NLSVA8L2NvZGU+IGlmIHRoZQotICAgICAqICAgPGNvZGU+RWxlbWVudDwvY29kZT4gc2hvdWxkIGJlIHNraXBwZWQuIEFsbCBvZiBpdHMgY2hpbGRyZW4gYXJlCi0gICAgICogICBpbnNlcnRlZCBpbiBwbGFjZSBvZiB0aGUgc2tpcHBlZCA8Y29kZT5FbGVtZW50PC9jb2RlPiBub2RlLgotICAgICAqIDwvbGk+Ci0gICAgICogPGxpPgotICAgICAqICAgPGNvZGU+RklMVEVSX0lOVEVSUlVQVDwvY29kZT4gaWYgdGhlIGZpbHRlciB3YW50cyB0byBzdG9wIHRoZQotICAgICAqICAgcHJvY2Vzc2luZyBvZiB0aGUgZG9jdW1lbnQuIEludGVycnVwdGluZyB0aGUgcHJvY2Vzc2luZyBvZiB0aGUKLSAgICAgKiAgIGRvY3VtZW50IGRvZXMgbm8gbG9uZ2VyIGd1YXJhbnRlZSB0aGF0IHRoZSByZXN1bHRpbmcgRE9NIHRyZWUgaXMKLSAgICAgKiAgIFhNTCB3ZWxsLWZvcm1lZC4gVGhlIDxjb2RlPkVsZW1lbnQ8L2NvZGU+IGlzIHJlamVjdGVkLgotICAgICAqIDwvbGk+Ci0gICAgICogPC91bD4gUmV0dXJuaW5nCi0gICAgICogICBhbnkgb3RoZXIgdmFsdWVzIHdpbGwgcmVzdWx0IGluIHVuc3BlY2lmaWVkIGJlaGF2aW9yLgotICAgICAqLwotICAgIHB1YmxpYyBzaG9ydCBzdGFydEVsZW1lbnQoRWxlbWVudCBlbGVtZW50QXJnKTsKLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIHdpbGwgYmUgY2FsbGVkIGJ5IHRoZSBwYXJzZXIgYXQgdGhlIGNvbXBsZXRpb24gb2YgdGhlCi0gICAgICogcGFyc2luZyBvZiBlYWNoIG5vZGUuIFRoZSBub2RlIGFuZCBhbGwgb2YgaXRzIGRlc2NlbmRhbnRzIHdpbGwgZXhpc3QKLSAgICAgKiBhbmQgYmUgY29tcGxldGUuIFRoZSBwYXJlbnQgbm9kZSB3aWxsIGFsc28gZXhpc3QsIGFsdGhvdWdoIGl0IG1heSBiZQotICAgICAqIGluY29tcGxldGUsIGkuZS4gaXQgbWF5IGhhdmUgYWRkaXRpb25hbCBjaGlsZHJlbiB0aGF0IGhhdmUgbm90IHlldAotICAgICAqIGJlZW4gcGFyc2VkLiBBdHRyaWJ1dGUgbm9kZXMgYXJlIG5ldmVyIHBhc3NlZCB0byB0aGlzIGZ1bmN0aW9uLgotICAgICAqIDxicj5Gcm9tIHdpdGhpbiB0aGlzIG1ldGhvZCwgdGhlIG5ldyBub2RlIG1heSBiZSBmcmVlbHkgbW9kaWZpZWQgLQotICAgICAqIGNoaWxkcmVuIG1heSBiZSBhZGRlZCBvciByZW1vdmVkLCB0ZXh0IG5vZGVzIG1vZGlmaWVkLCBldGMuIFRoZSBzdGF0ZQotICAgICAqIG9mIHRoZSByZXN0IG9mIHRoZSBkb2N1bWVudCBvdXRzaWRlIHRoaXMgbm9kZSBpcyBub3QgZGVmaW5lZCwgYW5kIHRoZQotICAgICAqIGFmZmVjdCBvZiBhbnkgYXR0ZW1wdCB0byBuYXZpZ2F0ZSB0bywgb3IgdG8gbW9kaWZ5IGFueSBvdGhlciBwYXJ0IG9mCi0gICAgICogdGhlIGRvY3VtZW50IGlzIHVuZGVmaW5lZC4KLSAgICAgKiA8YnI+Rm9yIHZhbGlkYXRpbmcgcGFyc2VycywgdGhlIGNoZWNrcyBhcmUgbWFkZSBvbiB0aGUgb3JpZ2luYWwKLSAgICAgKiBkb2N1bWVudCwgYmVmb3JlIGFueSBtb2RpZmljYXRpb24gYnkgdGhlIGZpbHRlci4gTm8gdmFsaWRpdHkgY2hlY2tzCi0gICAgICogYXJlIG1hZGUgb24gYW55IGRvY3VtZW50IG1vZGlmaWNhdGlvbnMgbWFkZSBieSB0aGUgZmlsdGVyLgotICAgICAqIDxicj5JZiB0aGlzIG5ldyBub2RlIGlzIHJlamVjdGVkLCB0aGUgcGFyc2VyIG1pZ2h0IHJldXNlIHRoZSBuZXcgbm9kZQotICAgICAqIGFuZCBhbnkgb2YgaXRzIGRlc2NlbmRhbnRzLgotICAgICAqIEBwYXJhbSBub2RlQXJnIFRoZSBuZXdseSBjb25zdHJ1Y3RlZCBlbGVtZW50LiBBdCB0aGUgdGltZSB0aGlzIG1ldGhvZAotICAgICAqICAgaXMgY2FsbGVkLCB0aGUgZWxlbWVudCBpcyBjb21wbGV0ZSAtIGl0IGhhcyBhbGwgb2YgaXRzIGNoaWxkcmVuCi0gICAgICogICAoYW5kIHRoZWlyIGNoaWxkcmVuLCByZWN1cnNpdmVseSkgYW5kIGF0dHJpYnV0ZXMsIGFuZCBpcyBhdHRhY2hlZAotICAgICAqICAgYXMgYSBjaGlsZCB0byBpdHMgcGFyZW50LgotICAgICAqIEByZXR1cm4KLSAgICAgKiA8dWw+Ci0gICAgICogPGxpPiA8Y29kZT5GSUxURVJfQUNDRVBUPC9jb2RlPiBpZiB0aGlzIDxjb2RlPk5vZGU8L2NvZGU+IHNob3VsZAotICAgICAqICAgYmUgaW5jbHVkZWQgaW4gdGhlIERPTSBkb2N1bWVudCBiZWluZyBidWlsdC4KLSAgICAgKiA8L2xpPgotICAgICAqIDxsaT4KLSAgICAgKiAgIDxjb2RlPkZJTFRFUl9SRUpFQ1Q8L2NvZGU+IGlmIHRoZSA8Y29kZT5Ob2RlPC9jb2RlPiBhbmQgYWxsIG9mIGl0cwotICAgICAqICAgY2hpbGRyZW4gc2hvdWxkIGJlIHJlamVjdGVkLgotICAgICAqIDwvbGk+Ci0gICAgICogPGxpPiA8Y29kZT5GSUxURVJfU0tJUDwvY29kZT4gaWYgdGhlCi0gICAgICogICA8Y29kZT5Ob2RlPC9jb2RlPiBzaG91bGQgYmUgc2tpcHBlZCBhbmQgdGhlIDxjb2RlPk5vZGU8L2NvZGU+Ci0gICAgICogICBzaG91bGQgYmUgcmVwbGFjZWQgYnkgYWxsIHRoZSBjaGlsZHJlbiBvZiB0aGUgPGNvZGU+Tm9kZTwvY29kZT4uCi0gICAgICogPC9saT4KLSAgICAgKiA8bGk+Ci0gICAgICogICA8Y29kZT5GSUxURVJfSU5URVJSVVBUPC9jb2RlPiBpZiB0aGUgZmlsdGVyIHdhbnRzIHRvIHN0b3AgdGhlCi0gICAgICogICBwcm9jZXNzaW5nIG9mIHRoZSBkb2N1bWVudC4gSW50ZXJydXB0aW5nIHRoZSBwcm9jZXNzaW5nIG9mIHRoZQotICAgICAqICAgZG9jdW1lbnQgZG9lcyBubyBsb25nZXIgZ3VhcmFudGVlIHRoYXQgdGhlIHJlc3VsdGluZyBET00gdHJlZSBpcwotICAgICAqICAgWE1MIHdlbGwtZm9ybWVkLiBUaGUgPGNvZGU+Tm9kZTwvY29kZT4gaXMgYWNjZXB0ZWQgYW5kIHdpbGwgYmUgdGhlCi0gICAgICogICBsYXN0IGNvbXBsZXRlbHkgcGFyc2VkIG5vZGUuCi0gICAgICogPC9saT4KLSAgICAgKiA8L3VsPgotICAgICAqLwotICAgIHB1YmxpYyBzaG9ydCBhY2NlcHROb2RlKE5vZGUgbm9kZUFyZyk7Ci0KLSAgICAvKioKLSAgICAgKiAgVGVsbHMgdGhlIDxjb2RlPkxTUGFyc2VyPC9jb2RlPiB3aGF0IHR5cGVzIG9mIG5vZGVzIHRvIHNob3cgdG8gdGhlCi0gICAgICogbWV0aG9kIDxjb2RlPkxTUGFyc2VyRmlsdGVyLmFjY2VwdE5vZGU8L2NvZGU+LiBJZiBhIG5vZGUgaXMgbm90IHNob3duCi0gICAgICogdG8gdGhlIGZpbHRlciB1c2luZyB0aGlzIGF0dHJpYnV0ZSwgaXQgaXMgYXV0b21hdGljYWxseSBpbmNsdWRlZCBpbgotICAgICAqIHRoZSBET00gZG9jdW1lbnQgYmVpbmcgYnVpbHQuIFNlZSA8Y29kZT5Ob2RlRmlsdGVyPC9jb2RlPiBmb3IKLSAgICAgKiBkZWZpbml0aW9uIG9mIHRoZSBjb25zdGFudHMuIFRoZSBjb25zdGFudHMgPGNvZGU+U0hPV19BVFRSSUJVVEU8L2NvZGU+Ci0gICAgICogLCA8Y29kZT5TSE9XX0RPQ1VNRU5UPC9jb2RlPiwgPGNvZGU+U0hPV19ET0NVTUVOVF9UWVBFPC9jb2RlPiwKLSAgICAgKiA8Y29kZT5TSE9XX05PVEFUSU9OPC9jb2RlPiwgPGNvZGU+U0hPV19FTlRJVFk8L2NvZGU+LCBhbmQKLSAgICAgKiA8Y29kZT5TSE9XX0RPQ1VNRU5UX0ZSQUdNRU5UPC9jb2RlPiBhcmUgbWVhbmluZ2xlc3MgaGVyZS4gVGhvc2Ugbm9kZXMKLSAgICAgKiB3aWxsIG5ldmVyIGJlIHBhc3NlZCB0byA8Y29kZT5MU1BhcnNlckZpbHRlci5hY2NlcHROb2RlPC9jb2RlPi4KLSAgICAgKiA8YnI+IFRoZSBjb25zdGFudHMgdXNlZCBoZXJlIGFyZSBkZWZpbmVkIGluIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAwL1JFQy1ET00tTGV2ZWwtMi1UcmF2ZXJzYWwtUmFuZ2UtMjAwMDExMTMnPkRPTSBMZXZlbCAyIFRyYXZlcnNhbCBhbmQgICAgICBSYW5nZTwvYT5dCi0gICAgICogLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0V2hhdFRvU2hvdygpOwotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL3czYy9kb20vbHMvTFNQcm9ncmVzc0V2ZW50LmphdmEgYi9zcmMvb3JnL3czYy9kb20vbHMvTFNQcm9ncmVzc0V2ZW50LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDI1YTc2YTYuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy93M2MvZG9tL2xzL0xTUHJvZ3Jlc3NFdmVudC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNzcgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIFRoaXMgZmlsZSBpcyBhdmFpbGFibGUgdW5kZXIgYW5kIGdvdmVybmVkIGJ5IHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKLSAqIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICogSG93ZXZlciwgdGhlIGZvbGxvd2luZyBub3RpY2UgYWNjb21wYW5pZWQgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcwotICogZmlsZSBhbmQsIHBlciBpdHMgdGVybXMsIHNob3VsZCBub3QgYmUgcmVtb3ZlZDoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKLSAqCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgRXVyb3BlYW4gUmVzZWFyY2ggQ29uc29ydGl1bSBmb3IKLSAqIEluZm9ybWF0aWNzIGFuZCBNYXRoZW1hdGljcywgS2VpbyBVbml2ZXJzaXR5KS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcwotICogd29yayBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDKHIpIFNvZnR3YXJlIExpY2Vuc2UgWzFdIGluIHRoZSBob3BlIHRoYXQKLSAqIGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZAotICogd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLgotICoKLSAqIFsxXSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLzIwMDIvY29weXJpZ2h0LXNvZnR3YXJlLTIwMDIxMjMxCi0gKi8KLQotcGFja2FnZSBvcmcudzNjLmRvbS5sczsKLQotaW1wb3J0IG9yZy53M2MuZG9tLmV2ZW50cy5FdmVudDsKLQotLyoqCi0gKiAgVGhpcyBpbnRlcmZhY2UgcmVwcmVzZW50cyBhIHByb2dyZXNzIGV2ZW50IG9iamVjdCB0aGF0IG5vdGlmaWVzIHRoZQotICogYXBwbGljYXRpb24gYWJvdXQgcHJvZ3Jlc3MgYXMgYSBkb2N1bWVudCBpcyBwYXJzZWQuIEl0IGV4dGVuZHMgdGhlCi0gKiA8Y29kZT5FdmVudDwvY29kZT4gaW50ZXJmYWNlIGRlZmluZWQgaW4gWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDMvTk9URS1ET00tTGV2ZWwtMy1FdmVudHMtMjAwMzExMDcnPkRPTSBMZXZlbCAzIEV2ZW50czwvYT5dCi0gKiAuCi0gKiA8cD4gVGhlIHVuaXRzIHVzZWQgZm9yIHRoZSBhdHRyaWJ1dGVzIDxjb2RlPnBvc2l0aW9uPC9jb2RlPiBhbmQKLSAqIDxjb2RlPnRvdGFsU2l6ZTwvY29kZT4gYXJlIG5vdCBzcGVjaWZpZWQgYW5kIGNhbiBiZSBpbXBsZW1lbnRhdGlvbiBhbmQKLSAqIGlucHV0IGRlcGVuZGVudC4KLSAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy1ET00tTGV2ZWwtMy1MUy0yMDA0MDQwNyc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDMgTG9hZAotYW5kIFNhdmUgU3BlY2lmaWNhdGlvbjwvYT4uCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgTFNQcm9ncmVzc0V2ZW50IGV4dGVuZHMgRXZlbnQgewotICAgIC8qKgotICAgICAqIFRoZSBpbnB1dCBzb3VyY2UgdGhhdCBpcyBiZWluZyBwYXJzZWQuCi0gICAgICovCi0gICAgcHVibGljIExTSW5wdXQgZ2V0SW5wdXQoKTsKLQotICAgIC8qKgotICAgICAqIFRoZSBjdXJyZW50IHBvc2l0aW9uIGluIHRoZSBpbnB1dCBzb3VyY2UsIGluY2x1ZGluZyBhbGwgZXh0ZXJuYWwKLSAgICAgKiBlbnRpdGllcyBhbmQgb3RoZXIgcmVzb3VyY2VzIHRoYXQgaGF2ZSBiZWVuIHJlYWQuCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRQb3NpdGlvbigpOwotCi0gICAgLyoqCi0gICAgICogVGhlIHRvdGFsIHNpemUgb2YgdGhlIGRvY3VtZW50IGluY2x1ZGluZyBhbGwgZXh0ZXJuYWwgcmVzb3VyY2VzLCB0aGlzCi0gICAgICogbnVtYmVyIG1pZ2h0IGNoYW5nZSBhcyBhIGRvY3VtZW50IGlzIGJlaW5nIHBhcnNlZCBpZiByZWZlcmVuY2VzIHRvCi0gICAgICogbW9yZSBleHRlcm5hbCByZXNvdXJjZXMgYXJlIHNlZW4uIEEgdmFsdWUgb2YgPGNvZGU+MDwvY29kZT4gaXMKLSAgICAgKiByZXR1cm5lZCBpZiB0aGUgdG90YWwgc2l6ZSBjYW5ub3QgYmUgZGV0ZXJtaW5lZCBvciBlc3RpbWF0ZWQuCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRUb3RhbFNpemUoKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy93M2MvZG9tL2xzL0xTUmVzb3VyY2VSZXNvbHZlci5qYXZhIGIvc3JjL29yZy93M2MvZG9tL2xzL0xTUmVzb3VyY2VSZXNvbHZlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiY2I1N2JlLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS9scy9MU1Jlc291cmNlUmVzb2x2ZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExMCArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogVGhpcyBmaWxlIGlzIGF2YWlsYWJsZSB1bmRlciBhbmQgZ292ZXJuZWQgYnkgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwotICogTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKiBIb3dldmVyLCB0aGUgZm9sbG93aW5nIG5vdGljZSBhY2NvbXBhbmllZCB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGlzCi0gKiBmaWxlIGFuZCwgcGVyIGl0cyB0ZXJtcywgc2hvdWxkIG5vdCBiZSByZW1vdmVkOgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwNCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAotICoKLSAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBFdXJvcGVhbiBSZXNlYXJjaCBDb25zb3J0aXVtIGZvcgotICogSW5mb3JtYXRpY3MgYW5kIE1hdGhlbWF0aWNzLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwgUmlnaHRzIFJlc2VydmVkLiBUaGlzCi0gKiB3b3JrIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MocikgU29mdHdhcmUgTGljZW5zZSBbMV0gaW4gdGhlIGhvcGUgdGhhdAotICogaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkCi0gKiB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuCi0gKgotICogWzFdIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvMjAwMi9jb3B5cmlnaHQtc29mdHdhcmUtMjAwMjEyMzEKLSAqLwotCi1wYWNrYWdlIG9yZy53M2MuZG9tLmxzOwotCi0vKioKLSAqICA8Y29kZT5MU1Jlc291cmNlUmVzb2x2ZXI8L2NvZGU+IHByb3ZpZGVzIGEgd2F5IGZvciBhcHBsaWNhdGlvbnMgdG8KLSAqIHJlZGlyZWN0IHJlZmVyZW5jZXMgdG8gZXh0ZXJuYWwgcmVzb3VyY2VzLgotICogPHA+IEFwcGxpY2F0aW9ucyBuZWVkaW5nIHRvIGltcGxlbWVudCBjdXN0b20gaGFuZGxpbmcgZm9yIGV4dGVybmFsCi0gKiByZXNvdXJjZXMgY2FuIGltcGxlbWVudCB0aGlzIGludGVyZmFjZSBhbmQgcmVnaXN0ZXIgdGhlaXIgaW1wbGVtZW50YXRpb24KLSAqIGJ5IHNldHRpbmcgdGhlICJyZXNvdXJjZS1yZXNvbHZlciIgcGFyYW1ldGVyIG9mCi0gKiA8Y29kZT5ET01Db25maWd1cmF0aW9uPC9jb2RlPiBvYmplY3RzIGF0dGFjaGVkIHRvIDxjb2RlPkxTUGFyc2VyPC9jb2RlPgotICogYW5kIDxjb2RlPkxTU2VyaWFsaXplcjwvY29kZT4uIEl0IGNhbiBhbHNvIGJlIHJlZ2lzdGVyIG9uCi0gKiA8Y29kZT5ET01Db25maWd1cmF0aW9uPC9jb2RlPiBvYmplY3RzIGF0dGFjaGVkIHRvIDxjb2RlPkRvY3VtZW50PC9jb2RlPgotICogaWYgdGhlICJMUyIgZmVhdHVyZSBpcyBzdXBwb3J0ZWQuCi0gKiA8cD4gVGhlIDxjb2RlPkxTUGFyc2VyPC9jb2RlPiB3aWxsIHRoZW4gYWxsb3cgdGhlIGFwcGxpY2F0aW9uIHRvIGludGVyY2VwdAotICogYW55IGV4dGVybmFsIGVudGl0aWVzLCBpbmNsdWRpbmcgdGhlIGV4dGVybmFsIERURCBzdWJzZXQgYW5kIGV4dGVybmFsCi0gKiBwYXJhbWV0ZXIgZW50aXRpZXMsIGJlZm9yZSBpbmNsdWRpbmcgdGhlbS4gVGhlIHRvcC1sZXZlbCBkb2N1bWVudCBlbnRpdHkKLSAqIGlzIG5ldmVyIHBhc3NlZCB0byB0aGUgPGNvZGU+cmVzb2x2ZVJlc291cmNlPC9jb2RlPiBtZXRob2QuCi0gKiA8cD4gTWFueSBET00gYXBwbGljYXRpb25zIHdpbGwgbm90IG5lZWQgdG8gaW1wbGVtZW50IHRoaXMgaW50ZXJmYWNlLCBidXQgaXQKLSAqIHdpbGwgYmUgZXNwZWNpYWxseSB1c2VmdWwgZm9yIGFwcGxpY2F0aW9ucyB0aGF0IGJ1aWxkIFhNTCBkb2N1bWVudHMgZnJvbQotICogZGF0YWJhc2VzIG9yIG90aGVyIHNwZWNpYWxpemVkIGlucHV0IHNvdXJjZXMsIG9yIGZvciBhcHBsaWNhdGlvbnMgdGhhdAotICogdXNlIFVSTnMuCi0gKiA8cCA+PGI+Tm90ZTo8L2I+ICA8Y29kZT5MU1Jlc291cmNlUmVzb2x2ZXI8L2NvZGU+IGlzIGJhc2VkIG9uIHRoZSBTQVgyIFs8YSBocmVmPSdodHRwOi8vd3d3LnNheHByb2plY3Qub3JnLyc+U0FYPC9hPl0gPGNvZGU+RW50aXR5UmVzb2x2ZXI8L2NvZGU+Ci0gKiBpbnRlcmZhY2UuCi0gKiA8cD5TZWUgYWxzbyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMtRE9NLUxldmVsLTMtTFMtMjAwNDA0MDcnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAzIExvYWQKLWFuZCBTYXZlIFNwZWNpZmljYXRpb248L2E+LgotICovCi1wdWJsaWMgaW50ZXJmYWNlIExTUmVzb3VyY2VSZXNvbHZlciB7Ci0gICAgLyoqCi0gICAgICogIEFsbG93IHRoZSBhcHBsaWNhdGlvbiB0byByZXNvbHZlIGV4dGVybmFsIHJlc291cmNlcy4KLSAgICAgKiA8YnI+IFRoZSA8Y29kZT5MU1BhcnNlcjwvY29kZT4gd2lsbCBjYWxsIHRoaXMgbWV0aG9kIGJlZm9yZSBvcGVuaW5nIGFueQotICAgICAqIGV4dGVybmFsIHJlc291cmNlLCBpbmNsdWRpbmcgdGhlIGV4dGVybmFsIERURCBzdWJzZXQsIGV4dGVybmFsCi0gICAgICogZW50aXRpZXMgcmVmZXJlbmNlZCB3aXRoaW4gdGhlIERURCwgYW5kIGV4dGVybmFsIGVudGl0aWVzIHJlZmVyZW5jZWQKLSAgICAgKiB3aXRoaW4gdGhlIGRvY3VtZW50IGVsZW1lbnQgKGhvd2V2ZXIsIHRoZSB0b3AtbGV2ZWwgZG9jdW1lbnQgZW50aXR5Ci0gICAgICogaXMgbm90IHBhc3NlZCB0byB0aGlzIG1ldGhvZCkuIFRoZSBhcHBsaWNhdGlvbiBtYXkgdGhlbiByZXF1ZXN0IHRoYXQKLSAgICAgKiB0aGUgPGNvZGU+TFNQYXJzZXI8L2NvZGU+IHJlc29sdmUgdGhlIGV4dGVybmFsIHJlc291cmNlIGl0c2VsZiwgdGhhdAotICAgICAqIGl0IHVzZSBhbiBhbHRlcm5hdGl2ZSBVUkksIG9yIHRoYXQgaXQgdXNlIGFuIGVudGlyZWx5IGRpZmZlcmVudCBpbnB1dAotICAgICAqIHNvdXJjZS4KLSAgICAgKiA8YnI+IEFwcGxpY2F0aW9uIHdyaXRlcnMgY2FuIHVzZSB0aGlzIG1ldGhvZCB0byByZWRpcmVjdCBleHRlcm5hbAotICAgICAqIHN5c3RlbSBpZGVudGlmaWVycyB0byBzZWN1cmUgYW5kL29yIGxvY2FsIFVSSSwgdG8gbG9vayB1cCBwdWJsaWMKLSAgICAgKiBpZGVudGlmaWVycyBpbiBhIGNhdGFsb2d1ZSwgb3IgdG8gcmVhZCBhbiBlbnRpdHkgZnJvbSBhIGRhdGFiYXNlIG9yCi0gICAgICogb3RoZXIgaW5wdXQgc291cmNlIChpbmNsdWRpbmcsIGZvciBleGFtcGxlLCBhIGRpYWxvZyBib3gpLgotICAgICAqIEBwYXJhbSB0eXBlICBUaGUgdHlwZSBvZiB0aGUgcmVzb3VyY2UgYmVpbmcgcmVzb2x2ZWQuIEZvciBYTUwgWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLXhtbC0yMDA0MDIwNCc+WE1MIDEuMDwvYT5dIHJlc291cmNlcwotICAgICAqICAgKGkuZS4gZW50aXRpZXMpLCBhcHBsaWNhdGlvbnMgbXVzdCB1c2UgdGhlIHZhbHVlCi0gICAgICogICA8Y29kZT4iaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLXhtbCI8L2NvZGU+LiBGb3IgWE1MIFNjaGVtYSBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMS9SRUMteG1sc2NoZW1hLTEtMjAwMTA1MDIvJz5YTUwgU2NoZW1hIFBhcnQgMTwvYT5dCi0gICAgICogICAsIGFwcGxpY2F0aW9ucyBtdXN0IHVzZSB0aGUgdmFsdWUKLSAgICAgKiAgIDxjb2RlPiJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYSI8L2NvZGU+LiBPdGhlciB0eXBlcyBvZgotICAgICAqICAgcmVzb3VyY2VzIGFyZSBvdXRzaWRlIHRoZSBzY29wZSBvZiB0aGlzIHNwZWNpZmljYXRpb24gYW5kIHRoZXJlZm9yZQotICAgICAqICAgc2hvdWxkIHJlY29tbWVuZCBhbiBhYnNvbHV0ZSBVUkkgaW4gb3JkZXIgdG8gdXNlIHRoaXMgbWV0aG9kLgotICAgICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkgIFRoZSBuYW1lc3BhY2Ugb2YgdGhlIHJlc291cmNlIGJlaW5nIHJlc29sdmVkLAotICAgICAqICAgZS5nLiB0aGUgdGFyZ2V0IG5hbWVzcGFjZSBvZiB0aGUgWE1MIFNjaGVtYSBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMS9SRUMteG1sc2NoZW1hLTEtMjAwMTA1MDIvJz5YTUwgU2NoZW1hIFBhcnQgMTwvYT5dCi0gICAgICogICAgd2hlbiByZXNvbHZpbmcgWE1MIFNjaGVtYSByZXNvdXJjZXMuCi0gICAgICogQHBhcmFtIHB1YmxpY0lkICBUaGUgcHVibGljIGlkZW50aWZpZXIgb2YgdGhlIGV4dGVybmFsIGVudGl0eSBiZWluZwotICAgICAqICAgcmVmZXJlbmNlZCwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgbm8gcHVibGljIGlkZW50aWZpZXIgd2FzCi0gICAgICogICBzdXBwbGllZCBvciBpZiB0aGUgcmVzb3VyY2UgaXMgbm90IGFuIGVudGl0eS4KLSAgICAgKiBAcGFyYW0gc3lzdGVtSWQgIFRoZSBzeXN0ZW0gaWRlbnRpZmllciwgYSBVUkkgcmVmZXJlbmNlIFs8YSBocmVmPSdodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyMzk2LnR4dCc+SUVURiBSRkMgMjM5NjwvYT5dLCBvZiB0aGUKLSAgICAgKiAgIGV4dGVybmFsIHJlc291cmNlIGJlaW5nIHJlZmVyZW5jZWQsIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIG5vCi0gICAgICogICBzeXN0ZW0gaWRlbnRpZmllciB3YXMgc3VwcGxpZWQuCi0gICAgICogQHBhcmFtIGJhc2VVUkkgIFRoZSBhYnNvbHV0ZSBiYXNlIFVSSSBvZiB0aGUgcmVzb3VyY2UgYmVpbmcgcGFyc2VkLCBvcgotICAgICAqICAgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlcmUgaXMgbm8gYmFzZSBVUkkuCi0gICAgICogQHJldHVybiAgQSA8Y29kZT5MU0lucHV0PC9jb2RlPiBvYmplY3QgZGVzY3JpYmluZyB0aGUgbmV3IGlucHV0Ci0gICAgICogICBzb3VyY2UsIG9yIDxjb2RlPm51bGw8L2NvZGU+IHRvIHJlcXVlc3QgdGhhdCB0aGUgcGFyc2VyIG9wZW4gYQotICAgICAqICAgcmVndWxhciBVUkkgY29ubmVjdGlvbiB0byB0aGUgcmVzb3VyY2UuCi0gICAgICovCi0gICAgcHVibGljIExTSW5wdXQgcmVzb2x2ZVJlc291cmNlKFN0cmluZyB0eXBlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbmFtZXNwYWNlVVJJLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcHVibGljSWQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBzeXN0ZW1JZCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGJhc2VVUkkpOwotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL3czYy9kb20vbHMvTFNTZXJpYWxpemVyLmphdmEgYi9zcmMvb3JnL3czYy9kb20vbHMvTFNTZXJpYWxpemVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDY1NTNmMjEuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy93M2MvZG9tL2xzL0xTU2VyaWFsaXplci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDY1ICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBUaGlzIGZpbGUgaXMgYXZhaWxhYmxlIHVuZGVyIGFuZCBnb3Zlcm5lZCBieSB0aGUgR05VIEdlbmVyYWwgUHVibGljCi0gKiBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqIEhvd2V2ZXIsIHRoZSBmb2xsb3dpbmcgbm90aWNlIGFjY29tcGFuaWVkIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIG9mIHRoaXMKLSAqIGZpbGUgYW5kLCBwZXIgaXRzIHRlcm1zLCBzaG91bGQgbm90IGJlIHJlbW92ZWQ6Ci0gKgotICogQ29weXJpZ2h0IChjKSAyMDA0IFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCi0gKgotICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEV1cm9wZWFuIFJlc2VhcmNoIENvbnNvcnRpdW0gZm9yCi0gKiBJbmZvcm1hdGljcyBhbmQgTWF0aGVtYXRpY3MsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMKLSAqIHdvcmsgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQyhyKSBTb2Z0d2FyZSBMaWNlbnNlIFsxXSBpbiB0aGUgaG9wZSB0aGF0Ci0gKiBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQKLSAqIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4KLSAqCi0gKiBbMV0gaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8yMDAyL2NvcHlyaWdodC1zb2Z0d2FyZS0yMDAyMTIzMQotICovCi0KLXBhY2thZ2Ugb3JnLnczYy5kb20ubHM7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5ET01Db25maWd1cmF0aW9uOwotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci1pbXBvcnQgb3JnLnczYy5kb20uRE9NRXhjZXB0aW9uOwotCi0vKioKLSAqICBBIDxjb2RlPkxTU2VyaWFsaXplcjwvY29kZT4gcHJvdmlkZXMgYW4gQVBJIGZvciBzZXJpYWxpemluZyAod3JpdGluZykgYQotICogRE9NIGRvY3VtZW50IG91dCBpbnRvIFhNTC4gVGhlIFhNTCBkYXRhIGlzIHdyaXR0ZW4gdG8gYSBzdHJpbmcgb3IgYW4KLSAqIG91dHB1dCBzdHJlYW0uIEFueSBjaGFuZ2VzIG9yIGZpeHVwcyBtYWRlIGR1cmluZyB0aGUgc2VyaWFsaXphdGlvbiBhZmZlY3QKLSAqIG9ubHkgdGhlIHNlcmlhbGl6ZWQgZGF0YS4gVGhlIDxjb2RlPkRvY3VtZW50PC9jb2RlPiBvYmplY3QgYW5kIGl0cwotICogY2hpbGRyZW4gYXJlIG5ldmVyIGFsdGVyZWQgYnkgdGhlIHNlcmlhbGl6YXRpb24gb3BlcmF0aW9uLgotICogPHA+IER1cmluZyBzZXJpYWxpemF0aW9uIG9mIFhNTCBkYXRhLCBuYW1lc3BhY2UgZml4dXAgaXMgZG9uZSBhcyBkZWZpbmVkIGluIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy1ET00tTGV2ZWwtMy1Db3JlLTIwMDQwNDA3Jz5ET00gTGV2ZWwgMyBDb3JlPC9hPl0KLSAqICwgQXBwZW5kaXggQi4gWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDAvUkVDLURPTS1MZXZlbC0yLUNvcmUtMjAwMDExMTMnPkRPTSBMZXZlbCAyIENvcmU8L2E+XQotICogIGFsbG93cyBlbXB0eSBzdHJpbmdzIGFzIGEgcmVhbCBuYW1lc3BhY2UgVVJJLiBJZiB0aGUKLSAqIDxjb2RlPm5hbWVzcGFjZVVSSTwvY29kZT4gb2YgYSA8Y29kZT5Ob2RlPC9jb2RlPiBpcyBlbXB0eSBzdHJpbmcsIHRoZQotICogc2VyaWFsaXphdGlvbiB3aWxsIHRyZWF0IHRoZW0gYXMgPGNvZGU+bnVsbDwvY29kZT4sIGlnbm9yaW5nIHRoZSBwcmVmaXgKLSAqIGlmIGFueS4KLSAqIDxwPiA8Y29kZT5MU1NlcmlhbGl6ZXI8L2NvZGU+IGFjY2VwdHMgYW55IG5vZGUgdHlwZSBmb3Igc2VyaWFsaXphdGlvbi4gRm9yCi0gKiBub2RlcyBvZiB0eXBlIDxjb2RlPkRvY3VtZW50PC9jb2RlPiBvciA8Y29kZT5FbnRpdHk8L2NvZGU+LCB3ZWxsLWZvcm1lZAotICogWE1MIHdpbGwgYmUgY3JlYXRlZCB3aGVuIHBvc3NpYmxlICh3ZWxsLWZvcm1lZG5lc3MgaXMgZ3VhcmFudGVlZCBpZiB0aGUKLSAqIGRvY3VtZW50IG9yIGVudGl0eSBjb21lcyBmcm9tIGEgcGFyc2Ugb3BlcmF0aW9uIGFuZCBpcyB1bmNoYW5nZWQgc2luY2UgaXQKLSAqIHdhcyBjcmVhdGVkKS4gVGhlIHNlcmlhbGl6ZWQgb3V0cHV0IGZvciB0aGVzZSBub2RlIHR5cGVzIGlzIGVpdGhlciBhcyBhCi0gKiBYTUwgZG9jdW1lbnQgb3IgYW4gRXh0ZXJuYWwgWE1MIEVudGl0eSwgcmVzcGVjdGl2ZWx5LCBhbmQgaXMgYWNjZXB0YWJsZQotICogaW5wdXQgZm9yIGFuIFhNTCBwYXJzZXIuIEZvciBhbGwgb3RoZXIgdHlwZXMgb2Ygbm9kZXMgdGhlIHNlcmlhbGl6ZWQgZm9ybQotICogaXMgaW1wbGVtZW50YXRpb24gZGVwZW5kZW50LgotICogPHA+V2l0aGluIGEgPGNvZGU+RG9jdW1lbnQ8L2NvZGU+LCA8Y29kZT5Eb2N1bWVudEZyYWdtZW50PC9jb2RlPiwgb3IKLSAqIDxjb2RlPkVudGl0eTwvY29kZT4gYmVpbmcgc2VyaWFsaXplZCwgPGNvZGU+Tm9kZXM8L2NvZGU+IGFyZSBwcm9jZXNzZWQgYXMKLSAqIGZvbGxvd3MKLSAqIDx1bD4KLSAqIDxsaT4gPGNvZGU+RG9jdW1lbnQ8L2NvZGU+IG5vZGVzIGFyZSB3cml0dGVuLCBpbmNsdWRpbmcgdGhlIFhNTAotICogZGVjbGFyYXRpb24gKHVubGVzcyB0aGUgcGFyYW1ldGVyICJ4bWwtZGVjbGFyYXRpb24iIGlzIHNldCB0bwotICogPGNvZGU+ZmFsc2U8L2NvZGU+KSBhbmQgYSBEVEQgc3Vic2V0LCBpZiBvbmUgZXhpc3RzIGluIHRoZSBET00uIFdyaXRpbmcgYQotICogPGNvZGU+RG9jdW1lbnQ8L2NvZGU+IG5vZGUgc2VyaWFsaXplcyB0aGUgZW50aXJlIGRvY3VtZW50LgotICogPC9saT4KLSAqIDxsaT4KLSAqIDxjb2RlPkVudGl0eTwvY29kZT4gbm9kZXMsIHdoZW4gd3JpdHRlbiBkaXJlY3RseSBieQotICogPGNvZGU+TFNTZXJpYWxpemVyLndyaXRlPC9jb2RlPiwgb3V0cHV0cyB0aGUgZW50aXR5IGV4cGFuc2lvbiBidXQgbm8KLSAqIG5hbWVzcGFjZSBmaXh1cCBpcyBkb25lLiBUaGUgcmVzdWx0aW5nIG91dHB1dCB3aWxsIGJlIHZhbGlkIGFzIGFuCi0gKiBleHRlcm5hbCBlbnRpdHkuCi0gKiA8L2xpPgotICogPGxpPiBJZiB0aGUgcGFyYW1ldGVyICI8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMy1Db3JlL2NvcmUuaHRtbCNwYXJhbWV0ZXItZW50aXRpZXMnPgotICogZW50aXRpZXM8L2E+IiBpcyBzZXQgdG8gPGNvZGU+dHJ1ZTwvY29kZT4sIDxjb2RlPkVudGl0eVJlZmVyZW5jZTwvY29kZT4gbm9kZXMgYXJlCi0gKiBzZXJpYWxpemVkIGFzIGFuIGVudGl0eSByZWZlcmVuY2Ugb2YgdGhlIGZvcm0gIgotICogPGNvZGU+JmFtcDtlbnRpdHlOYW1lOzwvY29kZT4iIGluIHRoZSBvdXRwdXQuIENoaWxkIG5vZGVzICh0aGUgZXhwYW5zaW9uKQotICogb2YgdGhlIGVudGl0eSByZWZlcmVuY2UgYXJlIGlnbm9yZWQuIElmIHRoZSBwYXJhbWV0ZXIgIjxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0zLUNvcmUvY29yZS5odG1sI3BhcmFtZXRlci1lbnRpdGllcyc+Ci0gKiBlbnRpdGllczwvYT4iIGlzIHNldCB0byA8Y29kZT5mYWxzZTwvY29kZT4sIG9ubHkgdGhlIGNoaWxkcmVuIG9mIHRoZSBlbnRpdHkgcmVmZXJlbmNlCi0gKiBhcmUgc2VyaWFsaXplZC4gPGNvZGU+RW50aXR5UmVmZXJlbmNlPC9jb2RlPiBub2RlcyB3aXRoIG5vIGNoaWxkcmVuIChubwotICogY29ycmVzcG9uZGluZyA8Y29kZT5FbnRpdHk8L2NvZGU+IG5vZGUgb3IgdGhlIGNvcnJlc3BvbmRpbmcKLSAqIDxjb2RlPkVudGl0eTwvY29kZT4gbm9kZXMgaGF2ZSBubyBjaGlsZHJlbikgYXJlIGFsd2F5cyBzZXJpYWxpemVkLgotICogPC9saT4KLSAqIDxsaT4KLSAqIDxjb2RlPkNEQVRBc2VjdGlvbnM8L2NvZGU+IGNvbnRhaW5pbmcgY29udGVudCBjaGFyYWN0ZXJzIHRoYXQgY2Fubm90IGJlCi0gKiByZXByZXNlbnRlZCBpbiB0aGUgc3BlY2lmaWVkIG91dHB1dCBlbmNvZGluZyBhcmUgaGFuZGxlZCBhY2NvcmRpbmcgdG8gdGhlCi0gKiAiPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTMtQ29yZS9jb3JlLmh0bWwjcGFyYW1ldGVyLXNwbGl0LWNkYXRhLXNlY3Rpb25zJz4KLSAqIHNwbGl0LWNkYXRhLXNlY3Rpb25zPC9hPiIgcGFyYW1ldGVyLiAgSWYgdGhlIHBhcmFtZXRlciBpcyBzZXQgdG8gPGNvZGU+dHJ1ZTwvY29kZT4sCi0gKiA8Y29kZT5DREFUQXNlY3Rpb25zPC9jb2RlPiBhcmUgc3BsaXQsIGFuZCB0aGUgdW5yZXByZXNlbnRhYmxlIGNoYXJhY3RlcnMKLSAqIGFyZSBzZXJpYWxpemVkIGFzIG51bWVyaWMgY2hhcmFjdGVyIHJlZmVyZW5jZXMgaW4gb3JkaW5hcnkgY29udGVudC4gVGhlCi0gKiBleGFjdCBwb3NpdGlvbiBhbmQgbnVtYmVyIG9mIHNwbGl0cyBpcyBub3Qgc3BlY2lmaWVkLiAgSWYgdGhlIHBhcmFtZXRlcgotICogaXMgc2V0IHRvIDxjb2RlPmZhbHNlPC9jb2RlPiwgdW5yZXByZXNlbnRhYmxlIGNoYXJhY3RlcnMgaW4gYQotICogPGNvZGU+Q0RBVEFzZWN0aW9uPC9jb2RlPiBhcmUgcmVwb3J0ZWQgYXMKLSAqIDxjb2RlPiJ3Zi1pbnZhbGlkLWNoYXJhY3RlciI8L2NvZGU+IGVycm9ycyBpZiB0aGUgcGFyYW1ldGVyICI8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMy1Db3JlL2NvcmUuaHRtbCNwYXJhbWV0ZXItd2VsbC1mb3JtZWQnPgotICogd2VsbC1mb3JtZWQ8L2E+IiBpcyBzZXQgdG8gPGNvZGU+dHJ1ZTwvY29kZT4uIFRoZSBlcnJvciBpcyBub3QgcmVjb3ZlcmFibGUgLSB0aGVyZSBpcyBubwotICogbWVjaGFuaXNtIGZvciBzdXBwbHlpbmcgYWx0ZXJuYXRpdmUgY2hhcmFjdGVycyBhbmQgY29udGludWluZyB3aXRoIHRoZQotICogc2VyaWFsaXphdGlvbi4KLSAqIDwvbGk+Ci0gKiA8bGk+IDxjb2RlPkRvY3VtZW50RnJhZ21lbnQ8L2NvZGU+IG5vZGVzIGFyZSBzZXJpYWxpemVkIGJ5Ci0gKiBzZXJpYWxpemluZyB0aGUgY2hpbGRyZW4gb2YgdGhlIGRvY3VtZW50IGZyYWdtZW50IGluIHRoZSBvcmRlciB0aGV5Ci0gKiBhcHBlYXIgaW4gdGhlIGRvY3VtZW50IGZyYWdtZW50LgotICogPC9saT4KLSAqIDxsaT4gQWxsIG90aGVyIG5vZGUgdHlwZXMgKEVsZW1lbnQsIFRleHQsCi0gKiBldGMuKSBhcmUgc2VyaWFsaXplZCB0byB0aGVpciBjb3JyZXNwb25kaW5nIFhNTCBzb3VyY2UgZm9ybS4KLSAqIDwvbGk+Ci0gKiA8L3VsPgotICogPHAgPjxiPk5vdGU6PC9iPiAgVGhlIHNlcmlhbGl6YXRpb24gb2YgYSA8Y29kZT5Ob2RlPC9jb2RlPiBkb2VzIG5vdCBhbHdheXMKLSAqIGdlbmVyYXRlIGEgd2VsbC1mb3JtZWQgWE1MIGRvY3VtZW50LCBpLmUuIGEgPGNvZGU+TFNQYXJzZXI8L2NvZGU+IG1pZ2h0Ci0gKiB0aHJvdyBmYXRhbCBlcnJvcnMgd2hlbiBwYXJzaW5nIHRoZSByZXN1bHRpbmcgc2VyaWFsaXphdGlvbi4KLSAqIDxwPiBXaXRoaW4gdGhlIGNoYXJhY3RlciBkYXRhIG9mIGEgZG9jdW1lbnQgKG91dHNpZGUgb2YgbWFya3VwKSwgYW55Ci0gKiBjaGFyYWN0ZXJzIHRoYXQgY2Fubm90IGJlIHJlcHJlc2VudGVkIGRpcmVjdGx5IGFyZSByZXBsYWNlZCB3aXRoCi0gKiBjaGFyYWN0ZXIgcmVmZXJlbmNlcy4gT2NjdXJyZW5jZXMgb2YgJyZsdDsnIGFuZCAnJmFtcDsnIGFyZSByZXBsYWNlZCBieQotICogdGhlIHByZWRlZmluZWQgZW50aXRpZXMgJmFtcDtsdDsgYW5kICZhbXA7YW1wOy4gVGhlIG90aGVyIHByZWRlZmluZWQKLSAqIGVudGl0aWVzICgmYW1wO2d0OywgJmFtcDthcG9zOywgYW5kICZhbXA7cXVvdDspIG1pZ2h0IG5vdCBiZSB1c2VkLCBleGNlcHQKLSAqIHdoZXJlIG5lZWRlZCAoZS5nLiB1c2luZyAmYW1wO2d0OyBpbiBjYXNlcyBzdWNoIGFzICddXSZndDsnKS4gQW55Ci0gKiBjaGFyYWN0ZXJzIHRoYXQgY2Fubm90IGJlIHJlcHJlc2VudGVkIGRpcmVjdGx5IGluIHRoZSBvdXRwdXQgY2hhcmFjdGVyCi0gKiBlbmNvZGluZyBhcmUgc2VyaWFsaXplZCBhcyBudW1lcmljIGNoYXJhY3RlciByZWZlcmVuY2VzIChhbmQgc2luY2UKLSAqIGNoYXJhY3RlciBlbmNvZGluZyBzdGFuZGFyZHMgY29tbW9ubHkgdXNlIGhleGFkZWNpbWFsIHJlcHJlc2VudGF0aW9ucyBvZgotICogY2hhcmFjdGVycywgdXNpbmcgdGhlIGhleGFkZWNpbWFsIHJlcHJlc2VudGF0aW9uIHdoZW4gc2VyaWFsaXppbmcKLSAqIGNoYXJhY3RlciByZWZlcmVuY2VzIGlzIGVuY291cmFnZWQpLgotICogPHA+IFRvIGFsbG93IGF0dHJpYnV0ZSB2YWx1ZXMgdG8gY29udGFpbiBib3RoIHNpbmdsZSBhbmQgZG91YmxlIHF1b3RlcywgdGhlCi0gKiBhcG9zdHJvcGhlIG9yIHNpbmdsZS1xdW90ZSBjaGFyYWN0ZXIgKCcpIG1heSBiZSByZXByZXNlbnRlZCBhcwotICogIiZhbXA7YXBvczsiLCBhbmQgdGhlIGRvdWJsZS1xdW90ZSBjaGFyYWN0ZXIgKCIpICBhcyAiJmFtcDtxdW90OyIuIE5ldwotICogbGluZSBjaGFyYWN0ZXJzIGFuZCBvdGhlciBjaGFyYWN0ZXJzIHRoYXQgY2Fubm90IGJlIHJlcHJlc2VudGVkIGRpcmVjdGx5Ci0gKiBpbiBhdHRyaWJ1dGUgdmFsdWVzIGluIHRoZSBvdXRwdXQgY2hhcmFjdGVyIGVuY29kaW5nIGFyZSBzZXJpYWxpemVkIGFzIGEKLSAqIG51bWVyaWMgY2hhcmFjdGVyIHJlZmVyZW5jZS4KLSAqIDxwPiBXaXRoaW4gbWFya3VwLCBidXQgb3V0c2lkZSBvZiBhdHRyaWJ1dGVzLCBhbnkgb2NjdXJyZW5jZSBvZiBhIGNoYXJhY3RlcgotICogdGhhdCBjYW5ub3QgYmUgcmVwcmVzZW50ZWQgaW4gdGhlIG91dHB1dCBjaGFyYWN0ZXIgZW5jb2RpbmcgaXMgcmVwb3J0ZWQKLSAqIGFzIGEgPGNvZGU+RE9NRXJyb3I8L2NvZGU+IGZhdGFsIGVycm9yLiBBbiBleGFtcGxlIHdvdWxkIGJlIHNlcmlhbGl6aW5nCi0gKiB0aGUgZWxlbWVudCAmbHQ7TGFDYVx1MDBmMWFkYS8mZ3Q7IHdpdGggPGNvZGU+ZW5jb2Rpbmc9InVzLWFzY2lpIjwvY29kZT4uCi0gKiBUaGlzIHdpbGwgcmVzdWx0IHdpdGggYSBnZW5lcmF0aW9uIG9mIGEgPGNvZGU+RE9NRXJyb3I8L2NvZGU+Ci0gKiAid2YtaW52YWxpZC1jaGFyYWN0ZXItaW4tbm9kZS1uYW1lIiAoYXMgcHJvcG9zZWQgaW4gIjxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0zLUNvcmUvY29yZS5odG1sI3BhcmFtZXRlci13ZWxsLWZvcm1lZCc+Ci0gKiB3ZWxsLWZvcm1lZDwvYT4iKS4KLSAqIDxwPiBXaGVuIHJlcXVlc3RlZCBieSBzZXR0aW5nIHRoZSBwYXJhbWV0ZXIgIjxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0zLUNvcmUvY29yZS5odG1sI3BhcmFtZXRlci1ub3JtYWxpemUtY2hhcmFjdGVycyc+Ci0gKiBub3JtYWxpemUtY2hhcmFjdGVyczwvYT4iIG9uIDxjb2RlPkxTU2VyaWFsaXplcjwvY29kZT4gdG8gdHJ1ZSwgY2hhcmFjdGVyIG5vcm1hbGl6YXRpb24gaXMKLSAqIHBlcmZvcm1lZCBhY2NvcmRpbmcgdG8gdGhlIGRlZmluaXRpb24gb2YgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMteG1sMTEtMjAwNDAyMDQvI2R0LWZ1bGxub3JtJz5mdWxseQotICogbm9ybWFsaXplZDwvYT4gY2hhcmFjdGVycyBpbmNsdWRlZCBpbiBhcHBlbmRpeCBFIG9mIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy14bWwxMS0yMDA0MDIwNC8nPlhNTCAxLjE8L2E+XSBvbiBhbGwKLSAqIGRhdGEgdG8gYmUgc2VyaWFsaXplZCwgYm90aCBtYXJrdXAgYW5kIGNoYXJhY3RlciBkYXRhLiBUaGUgY2hhcmFjdGVyCi0gKiBub3JtYWxpemF0aW9uIHByb2Nlc3MgYWZmZWN0cyBvbmx5IHRoZSBkYXRhIGFzIGl0IGlzIGJlaW5nIHdyaXR0ZW47IGl0Ci0gKiBkb2VzIG5vdCBhbHRlciB0aGUgRE9NJ3MgdmlldyBvZiB0aGUgZG9jdW1lbnQgYWZ0ZXIgc2VyaWFsaXphdGlvbiBoYXMKLSAqIGNvbXBsZXRlZC4KLSAqIDxwPiBJbXBsZW1lbnRhdGlvbnMgYXJlIHJlcXVpcmVkIHRvIHN1cHBvcnQgdGhlIGVuY29kaW5ncyAiVVRGLTgiLAotICogIlVURi0xNiIsICJVVEYtMTZCRSIsIGFuZCAiVVRGLTE2TEUiIHRvIGd1YXJhbnRlZSB0aGF0IGRhdGEgaXMKLSAqIHNlcmlhbGl6YWJsZSBpbiBhbGwgZW5jb2RpbmdzIHRoYXQgYXJlIHJlcXVpcmVkIHRvIGJlIHN1cHBvcnRlZCBieSBhbGwKLSAqIFhNTCBwYXJzZXJzLiBXaGVuIHRoZSBlbmNvZGluZyBpcyBVVEYtOCwgd2hldGhlciBvciBub3QgYSBieXRlIG9yZGVyIG1hcmsKLSAqIGlzIHNlcmlhbGl6ZWQsIG9yIGlmIHRoZSBvdXRwdXQgaXMgYmlnLWVuZGlhbiBvciBsaXR0bGUtZW5kaWFuLCBpcwotICogaW1wbGVtZW50YXRpb24gZGVwZW5kZW50LiBXaGVuIHRoZSBlbmNvZGluZyBpcyBVVEYtMTYsIHdoZXRoZXIgb3Igbm90IHRoZQotICogb3V0cHV0IGlzIGJpZy1lbmRpYW4gb3IgbGl0dGxlLWVuZGlhbiBpcyBpbXBsZW1lbnRhdGlvbiBkZXBlbmRlbnQsIGJ1dCBhCi0gKiBCeXRlIE9yZGVyIE1hcmsgbXVzdCBiZSBnZW5lcmF0ZWQgZm9yIG5vbi1jaGFyYWN0ZXIgb3V0cHV0cywgc3VjaCBhcwotICogPGNvZGU+TFNPdXRwdXQuYnl0ZVN0cmVhbTwvY29kZT4gb3IgPGNvZGU+TFNPdXRwdXQuc3lzdGVtSWQ8L2NvZGU+LiBJZgotICogdGhlIEJ5dGUgT3JkZXIgTWFyayBpcyBub3QgZ2VuZXJhdGVkLCBhICJieXRlLW9yZGVyLW1hcmstbmVlZGVkIiB3YXJuaW5nCi0gKiBpcyByZXBvcnRlZC4gV2hlbiB0aGUgZW5jb2RpbmcgaXMgVVRGLTE2TEUgb3IgVVRGLTE2QkUsIHRoZSBvdXRwdXQgaXMKLSAqIGJpZy1lbmRpYW4gKFVURi0xNkJFKSBvciBsaXR0bGUtZW5kaWFuIChVVEYtMTZMRSkgYW5kIHRoZSBCeXRlIE9yZGVyIE1hcmsKLSAqIGlzIG5vdCBiZSBnZW5lcmF0ZWQuIEluIGFsbCBjYXNlcywgdGhlIGVuY29kaW5nIGRlY2xhcmF0aW9uLCBpZgotICogZ2VuZXJhdGVkLCB3aWxsIGNvcnJlc3BvbmQgdG8gdGhlIGVuY29kaW5nIHVzZWQgZHVyaW5nIHRoZSBzZXJpYWxpemF0aW9uCi0gKiAoZS5nLiA8Y29kZT5lbmNvZGluZz0iVVRGLTE2IjwvY29kZT4gd2lsbCBhcHBlYXIgaWYgVVRGLTE2IHdhcwotICogcmVxdWVzdGVkKS4KLSAqIDxwPiBOYW1lc3BhY2VzIGFyZSBmaXhlZCB1cCBkdXJpbmcgc2VyaWFsaXphdGlvbiwgdGhlIHNlcmlhbGl6YXRpb24gcHJvY2VzcwotICogd2lsbCB2ZXJpZnkgdGhhdCBuYW1lc3BhY2UgZGVjbGFyYXRpb25zLCBuYW1lc3BhY2UgcHJlZml4ZXMgYW5kIHRoZQotICogbmFtZXNwYWNlIFVSSSBhc3NvY2lhdGVkIHdpdGggZWxlbWVudHMgYW5kIGF0dHJpYnV0ZXMgYXJlIGNvbnNpc3RlbnQuIElmCi0gKiBpbmNvbnNpc3RlbmNpZXMgYXJlIGZvdW5kLCB0aGUgc2VyaWFsaXplZCBmb3JtIG9mIHRoZSBkb2N1bWVudCB3aWxsIGJlCi0gKiBhbHRlcmVkIHRvIHJlbW92ZSB0aGVtLiBUaGUgbWV0aG9kIHVzZWQgZm9yIGRvaW5nIHRoZSBuYW1lc3BhY2UgZml4dXAKLSAqIHdoaWxlIHNlcmlhbGl6aW5nIGEgZG9jdW1lbnQgaXMgdGhlIGFsZ29yaXRobSBkZWZpbmVkIGluIEFwcGVuZGl4IEIuMSwKLSAqICJOYW1lc3BhY2Ugbm9ybWFsaXphdGlvbiIsIG9mIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy1ET00tTGV2ZWwtMy1Db3JlLTIwMDQwNDA3Jz5ET00gTGV2ZWwgMyBDb3JlPC9hPl0KLSAqIC4KLSAqIDxwPiBXaGlsZSBzZXJpYWxpemluZyBhIGRvY3VtZW50LCB0aGUgcGFyYW1ldGVyICJkaXNjYXJkLWRlZmF1bHQtY29udGVudCIKLSAqIGNvbnRyb2xzIHdoZXRoZXIgb3Igbm90IG5vbi1zcGVjaWZpZWQgZGF0YSBpcyBzZXJpYWxpemVkLgotICogPHA+IFdoaWxlIHNlcmlhbGl6aW5nLCBlcnJvcnMgYW5kIHdhcm5pbmdzIGFyZSByZXBvcnRlZCB0byB0aGUgYXBwbGljYXRpb24KLSAqIHRocm91Z2ggdGhlIGVycm9yIGhhbmRsZXIgKDxjb2RlPkxTU2VyaWFsaXplci5kb21Db25maWc8L2NvZGU+J3MgIjxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0zLUNvcmUvY29yZS5odG1sI3BhcmFtZXRlci1lcnJvci1oYW5kbGVyJz4KLSAqIGVycm9yLWhhbmRsZXI8L2E+IiBwYXJhbWV0ZXIpLiBUaGlzIHNwZWNpZmljYXRpb24gZG9lcyBpbiBubyB3YXkgdHJ5IHRvIGRlZmluZSBhbGwgcG9zc2libGUKLSAqIGVycm9ycyBhbmQgd2FybmluZ3MgdGhhdCBjYW4gb2NjdXIgd2hpbGUgc2VyaWFsaXppbmcgYSBET00gbm9kZSwgYnV0IHNvbWUKLSAqIGNvbW1vbiBlcnJvciBhbmQgd2FybmluZyBjYXNlcyBhcmUgZGVmaW5lZC4gVGhlIHR5cGVzICgKLSAqIDxjb2RlPkRPTUVycm9yLnR5cGU8L2NvZGU+KSBvZiBlcnJvcnMgYW5kIHdhcm5pbmdzIGRlZmluZWQgYnkgdGhpcwotICogc3BlY2lmaWNhdGlvbiBhcmU6Ci0gKiA8ZGw+Ci0gKiA8ZHQ+PGNvZGU+Im5vLW91dHB1dC1zcGVjaWZpZWQiIFtmYXRhbF08L2NvZGU+PC9kdD4KLSAqIDxkZD4gUmFpc2VkIHdoZW4KLSAqIHdyaXRpbmcgdG8gYSA8Y29kZT5MU091dHB1dDwvY29kZT4gaWYgbm8gb3V0cHV0IGlzIHNwZWNpZmllZCBpbiB0aGUKLSAqIDxjb2RlPkxTT3V0cHV0PC9jb2RlPi4gPC9kZD4KLSAqIDxkdD4KLSAqIDxjb2RlPiJ1bmJvdW5kLXByZWZpeC1pbi1lbnRpdHktcmVmZXJlbmNlIiBbZmF0YWxdPC9jb2RlPiA8L2R0PgotICogPGRkPiBSYWlzZWQgaWYgdGhlCi0gKiBjb25maWd1cmF0aW9uIHBhcmFtZXRlciAiPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTMtQ29yZS9jb3JlLmh0bWwjcGFyYW1ldGVyLW5hbWVzcGFjZXMnPgotICogbmFtZXNwYWNlczwvYT4iIGlzIHNldCB0byA8Y29kZT50cnVlPC9jb2RlPiBhbmQgYW4gZW50aXR5IHdob3NlIHJlcGxhY2VtZW50IHRleHQKLSAqIGNvbnRhaW5zIHVuYm91bmQgbmFtZXNwYWNlIHByZWZpeGVzIGlzIHJlZmVyZW5jZWQgaW4gYSBsb2NhdGlvbiB3aGVyZQotICogdGhlcmUgYXJlIG5vIGJpbmRpbmdzIGZvciB0aGUgbmFtZXNwYWNlIHByZWZpeGVzLiA8L2RkPgotICogPGR0PgotICogPGNvZGU+InVuc3VwcG9ydGVkLWVuY29kaW5nIiBbZmF0YWxdPC9jb2RlPjwvZHQ+Ci0gKiA8ZGQ+IFJhaXNlZCBpZiBhbiB1bnN1cHBvcnRlZAotICogZW5jb2RpbmcgaXMgZW5jb3VudGVyZWQuIDwvZGQ+Ci0gKiA8L2RsPgotICogPHA+IEluIGFkZGl0aW9uIHRvIHJhaXNpbmcgdGhlIGRlZmluZWQgZXJyb3JzIGFuZCB3YXJuaW5ncywgaW1wbGVtZW50YXRpb25zCi0gKiBhcmUgZXhwZWN0ZWQgdG8gcmFpc2UgaW1wbGVtZW50YXRpb24gc3BlY2lmaWMgZXJyb3JzIGFuZCB3YXJuaW5ncyBmb3IgYW55Ci0gKiBvdGhlciBlcnJvciBhbmQgd2FybmluZyBjYXNlcyBzdWNoIGFzIElPIGVycm9ycyAoZmlsZSBub3QgZm91bmQsCi0gKiBwZXJtaXNzaW9uIGRlbmllZCwuLi4pIGFuZCBzbyBvbi4KLSAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy1ET00tTGV2ZWwtMy1MUy0yMDA0MDQwNyc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDMgTG9hZAotYW5kIFNhdmUgU3BlY2lmaWNhdGlvbjwvYT4uCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgTFNTZXJpYWxpemVyIHsKLSAgICAvKioKLSAgICAgKiAgVGhlIDxjb2RlPkRPTUNvbmZpZ3VyYXRpb248L2NvZGU+IG9iamVjdCB1c2VkIGJ5IHRoZQotICAgICAqIDxjb2RlPkxTU2VyaWFsaXplcjwvY29kZT4gd2hlbiBzZXJpYWxpemluZyBhIERPTSBub2RlLgotICAgICAqIDxicj4gSW4gYWRkaXRpb24gdG8gdGhlIHBhcmFtZXRlcnMgcmVjb2duaXplZCBieSB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTMtQ29yZS9jb3JlLmh0bWwjRE9NQ29uZmlndXJhdGlvbic+Ci0gICAgICogRE9NQ29uZmlndXJhdGlvbjwvYT4gaW50ZXJmYWNlIGRlZmluZWQgaW4gWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLURPTS1MZXZlbC0zLUNvcmUtMjAwNDA0MDcnPkRPTSBMZXZlbCAzIENvcmU8L2E+XQotICAgICAqICwgdGhlIDxjb2RlPkRPTUNvbmZpZ3VyYXRpb248L2NvZGU+IG9iamVjdHMgZm9yCi0gICAgICogPGNvZGU+TFNTZXJpYWxpemVyPC9jb2RlPiBhZGRzLCBvciBtb2RpZmllcywgdGhlIGZvbGxvd2luZwotICAgICAqIHBhcmFtZXRlcnM6Ci0gICAgICogPGRsPgotICAgICAqIDxkdD48Y29kZT4iY2Fub25pY2FsLWZvcm0iPC9jb2RlPjwvZHQ+Ci0gICAgICogPGRkPgotICAgICAqIDxkbD4KLSAgICAgKiA8ZHQ+PGNvZGU+dHJ1ZTwvY29kZT48L2R0PgotICAgICAqIDxkZD5bPGVtPm9wdGlvbmFsPC9lbT5dIFdyaXRlcyB0aGUgZG9jdW1lbnQgYWNjb3JkaW5nIHRvIHRoZSBydWxlcyBzcGVjaWZpZWQgaW4gWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDEvUkVDLXhtbC1jMTRuLTIwMDEwMzE1Jz5DYW5vbmljYWwgWE1MPC9hPl0uCi0gICAgICogSW4gYWRkaXRpb24gdG8gdGhlIGJlaGF2aW9yIGRlc2NyaWJlZCBpbiAiPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTMtQ29yZS9jb3JlLmh0bWwjcGFyYW1ldGVyLWNhbm9uaWNhbC1mb3JtJz4KLSAgICAgKiBjYW5vbmljYWwtZm9ybTwvYT4iIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy1ET00tTGV2ZWwtMy1Db3JlLTIwMDQwNDA3Jz5ET00gTGV2ZWwgMyBDb3JlPC9hPl0KLSAgICAgKiAsIHNldHRpbmcgdGhpcyBwYXJhbWV0ZXIgdG8gPGNvZGU+dHJ1ZTwvY29kZT4gd2lsbCBzZXQgdGhlIHBhcmFtZXRlcnMKLSAgICAgKiAiZm9ybWF0LXByZXR0eS1wcmludCIsICJkaXNjYXJkLWRlZmF1bHQtY29udGVudCIsIGFuZCAieG1sLWRlY2xhcmF0aW9uCi0gICAgICogIiwgdG8gPGNvZGU+ZmFsc2U8L2NvZGU+LiBTZXR0aW5nIG9uZSBvZiB0aG9zZSBwYXJhbWV0ZXJzIHRvCi0gICAgICogPGNvZGU+dHJ1ZTwvY29kZT4gd2lsbCBzZXQgdGhpcyBwYXJhbWV0ZXIgdG8gPGNvZGU+ZmFsc2U8L2NvZGU+LgotICAgICAqIFNlcmlhbGl6aW5nIGFuIFhNTCAxLjEgZG9jdW1lbnQgd2hlbiAiY2Fub25pY2FsLWZvcm0iIGlzCi0gICAgICogPGNvZGU+dHJ1ZTwvY29kZT4gd2lsbCBnZW5lcmF0ZSBhIGZhdGFsIGVycm9yLiA8L2RkPgotICAgICAqIDxkdD48Y29kZT5mYWxzZTwvY29kZT48L2R0PgotICAgICAqIDxkZD5bPGVtPnJlcXVpcmVkPC9lbT5dICg8ZW0+ZGVmYXVsdDwvZW0+KSBEbyBub3QgY2Fub25pY2FsaXplIHRoZSBvdXRwdXQuIDwvZGQ+Ci0gICAgICogPC9kbD48L2RkPgotICAgICAqIDxkdD48Y29kZT4iZGlzY2FyZC1kZWZhdWx0LWNvbnRlbnQiPC9jb2RlPjwvZHQ+Ci0gICAgICogPGRkPgotICAgICAqIDxkbD4KLSAgICAgKiA8ZHQ+Ci0gICAgICogPGNvZGU+dHJ1ZTwvY29kZT48L2R0PgotICAgICAqIDxkZD5bPGVtPnJlcXVpcmVkPC9lbT5dICg8ZW0+ZGVmYXVsdDwvZW0+KSBVc2UgdGhlIDxjb2RlPkF0dHIuc3BlY2lmaWVkPC9jb2RlPiBhdHRyaWJ1dGUgdG8gZGVjaWRlIHdoYXQgYXR0cmlidXRlcwotICAgICAqIHNob3VsZCBiZSBkaXNjYXJkZWQuIE5vdGUgdGhhdCBzb21lIGltcGxlbWVudGF0aW9ucyBtaWdodCB1c2UKLSAgICAgKiB3aGF0ZXZlciBpbmZvcm1hdGlvbiBhdmFpbGFibGUgdG8gdGhlIGltcGxlbWVudGF0aW9uIChpLmUuIFhNTAotICAgICAqIHNjaGVtYSwgRFRELCB0aGUgPGNvZGU+QXR0ci5zcGVjaWZpZWQ8L2NvZGU+IGF0dHJpYnV0ZSwgYW5kIHNvIG9uKSB0bwotICAgICAqIGRldGVybWluZSB3aGF0IGF0dHJpYnV0ZXMgYW5kIGNvbnRlbnQgdG8gZGlzY2FyZCBpZiB0aGlzIHBhcmFtZXRlciBpcwotICAgICAqIHNldCB0byA8Y29kZT50cnVlPC9jb2RlPi4gPC9kZD4KLSAgICAgKiA8ZHQ+PGNvZGU+ZmFsc2U8L2NvZGU+PC9kdD4KLSAgICAgKiA8ZGQ+WzxlbT5yZXF1aXJlZDwvZW0+XUtlZXAgYWxsIGF0dHJpYnV0ZXMgYW5kIGFsbCBjb250ZW50LjwvZGQ+Ci0gICAgICogPC9kbD48L2RkPgotICAgICAqIDxkdD48Y29kZT4iZm9ybWF0LXByZXR0eS1wcmludCI8L2NvZGU+PC9kdD4KLSAgICAgKiA8ZGQ+Ci0gICAgICogPGRsPgotICAgICAqIDxkdD4KLSAgICAgKiA8Y29kZT50cnVlPC9jb2RlPjwvZHQ+Ci0gICAgICogPGRkPls8ZW0+b3B0aW9uYWw8L2VtPl0gRm9ybWF0dGluZyB0aGUgb3V0cHV0IGJ5IGFkZGluZyB3aGl0ZXNwYWNlIHRvIHByb2R1Y2UgYSBwcmV0dHktcHJpbnRlZCwKLSAgICAgKiBpbmRlbnRlZCwgaHVtYW4tcmVhZGFibGUgZm9ybS4gVGhlIGV4YWN0IGZvcm0gb2YgdGhlIHRyYW5zZm9ybWF0aW9ucwotICAgICAqIGlzIG5vdCBzcGVjaWZpZWQgYnkgdGhpcyBzcGVjaWZpY2F0aW9uLiBQcmV0dHktcHJpbnRpbmcgY2hhbmdlcyB0aGUKLSAgICAgKiBjb250ZW50IG9mIHRoZSBkb2N1bWVudCBhbmQgbWF5IGFmZmVjdCB0aGUgdmFsaWRpdHkgb2YgdGhlIGRvY3VtZW50LAotICAgICAqIHZhbGlkYXRpbmcgaW1wbGVtZW50YXRpb25zIHNob3VsZCBwcmVzZXJ2ZSB2YWxpZGl0eS4gPC9kZD4KLSAgICAgKiA8ZHQ+Ci0gICAgICogPGNvZGU+ZmFsc2U8L2NvZGU+PC9kdD4KLSAgICAgKiA8ZGQ+WzxlbT5yZXF1aXJlZDwvZW0+XSAoPGVtPmRlZmF1bHQ8L2VtPikgRG9uJ3QgcHJldHR5LXByaW50IHRoZSByZXN1bHQuIDwvZGQ+Ci0gICAgICogPC9kbD48L2RkPgotICAgICAqIDxkdD4KLSAgICAgKiA8Y29kZT4iaWdub3JlLXVua25vd24tY2hhcmFjdGVyLWRlbm9ybWFsaXphdGlvbnMiPC9jb2RlPiA8L2R0PgotICAgICAqIDxkZD4KLSAgICAgKiA8ZGw+Ci0gICAgICogPGR0PgotICAgICAqIDxjb2RlPnRydWU8L2NvZGU+PC9kdD4KLSAgICAgKiA8ZGQ+WzxlbT5yZXF1aXJlZDwvZW0+XSAoPGVtPmRlZmF1bHQ8L2VtPikgSWYsIHdoaWxlIHZlcmlmeWluZyBmdWxsIG5vcm1hbGl6YXRpb24gd2hlbiBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMteG1sMTEtMjAwNDAyMDQvJz5YTUwgMS4xPC9hPl0gaXMKLSAgICAgKiBzdXBwb3J0ZWQsIGEgY2hhcmFjdGVyIGlzIGVuY291bnRlcmVkIGZvciB3aGljaCB0aGUgbm9ybWFsaXphdGlvbgotICAgICAqIHByb3BlcnRpZXMgY2Fubm90IGJlIGRldGVybWluZWQsIHRoZW4gcmFpc2UgYQotICAgICAqIDxjb2RlPiJ1bmtub3duLWNoYXJhY3Rlci1kZW5vcm1hbGl6YXRpb24iPC9jb2RlPiB3YXJuaW5nIChpbnN0ZWFkIG9mCi0gICAgICogcmFpc2luZyBhbiBlcnJvciwgaWYgdGhpcyBwYXJhbWV0ZXIgaXMgbm90IHNldCkgYW5kIGlnbm9yZSBhbnkKLSAgICAgKiBwb3NzaWJsZSBkZW5vcm1hbGl6YXRpb25zIGNhdXNlZCBieSB0aGVzZSBjaGFyYWN0ZXJzLiA8L2RkPgotICAgICAqIDxkdD4KLSAgICAgKiA8Y29kZT5mYWxzZTwvY29kZT48L2R0PgotICAgICAqIDxkZD5bPGVtPm9wdGlvbmFsPC9lbT5dIFJlcG9ydCBhIGZhdGFsIGVycm9yIGlmIGEgY2hhcmFjdGVyIGlzIGVuY291bnRlcmVkIGZvciB3aGljaCB0aGUKLSAgICAgKiBwcm9jZXNzb3IgY2Fubm90IGRldGVybWluZSB0aGUgbm9ybWFsaXphdGlvbiBwcm9wZXJ0aWVzLiA8L2RkPgotICAgICAqIDwvZGw+PC9kZD4KLSAgICAgKiA8ZHQ+Ci0gICAgICogPGNvZGU+Im5vcm1hbGl6ZS1jaGFyYWN0ZXJzIjwvY29kZT48L2R0PgotICAgICAqIDxkZD4gVGhpcyBwYXJhbWV0ZXIgaXMgZXF1aXZhbGVudCB0bwotICAgICAqIHRoZSBvbmUgZGVmaW5lZCBieSA8Y29kZT5ET01Db25maWd1cmF0aW9uPC9jb2RlPiBpbiBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMtRE9NLUxldmVsLTMtQ29yZS0yMDA0MDQwNyc+RE9NIExldmVsIDMgQ29yZTwvYT5dCi0gICAgICogLiBVbmxpa2UgaW4gdGhlIENvcmUsIHRoZSBkZWZhdWx0IHZhbHVlIGZvciB0aGlzIHBhcmFtZXRlciBpcwotICAgICAqIDxjb2RlPnRydWU8L2NvZGU+LiBXaGlsZSBET00gaW1wbGVtZW50YXRpb25zIGFyZSBub3QgcmVxdWlyZWQgdG8KLSAgICAgKiBzdXBwb3J0IDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLXhtbDExLTIwMDQwMjA0LyNkdC1mdWxsbm9ybSc+ZnVsbHkKLSAgICAgKiBub3JtYWxpemluZzwvYT4gdGhlIGNoYXJhY3RlcnMgaW4gdGhlIGRvY3VtZW50IGFjY29yZGluZyB0byBhcHBlbmRpeCBFIG9mIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy14bWwxMS0yMDA0MDIwNC8nPlhNTCAxLjE8L2E+XSwgdGhpcwotICAgICAqIHBhcmFtZXRlciBtdXN0IGJlIGFjdGl2YXRlZCBieSBkZWZhdWx0IGlmIHN1cHBvcnRlZC4gPC9kZD4KLSAgICAgKiA8ZHQ+Ci0gICAgICogPGNvZGU+InhtbC1kZWNsYXJhdGlvbiI8L2NvZGU+PC9kdD4KLSAgICAgKiA8ZGQ+Ci0gICAgICogPGRsPgotICAgICAqIDxkdD48Y29kZT50cnVlPC9jb2RlPjwvZHQ+Ci0gICAgICogPGRkPls8ZW0+cmVxdWlyZWQ8L2VtPl0gKDxlbT5kZWZhdWx0PC9lbT4pIElmIGEgPGNvZGU+RG9jdW1lbnQ8L2NvZGU+LCA8Y29kZT5FbGVtZW50PC9jb2RlPiwgb3IgPGNvZGU+RW50aXR5PC9jb2RlPgotICAgICAqICBub2RlIGlzIHNlcmlhbGl6ZWQsIHRoZSBYTUwgZGVjbGFyYXRpb24sIG9yIHRleHQgZGVjbGFyYXRpb24sIHNob3VsZAotICAgICAqIGJlIGluY2x1ZGVkLiBUaGUgdmVyc2lvbiAoPGNvZGU+RG9jdW1lbnQueG1sVmVyc2lvbjwvY29kZT4gaWYgdGhlCi0gICAgICogZG9jdW1lbnQgaXMgYSBMZXZlbCAzIGRvY3VtZW50IGFuZCB0aGUgdmVyc2lvbiBpcyBub24tbnVsbCwgb3RoZXJ3aXNlCi0gICAgICogdXNlIHRoZSB2YWx1ZSAiMS4wIiksIGFuZCB0aGUgb3V0cHV0IGVuY29kaW5nIChzZWUKLSAgICAgKiA8Y29kZT5MU1NlcmlhbGl6ZXIud3JpdGU8L2NvZGU+IGZvciBkZXRhaWxzIG9uIGhvdyB0byBmaW5kIHRoZSBvdXRwdXQKLSAgICAgKiBlbmNvZGluZykgYXJlIHNwZWNpZmllZCBpbiB0aGUgc2VyaWFsaXplZCBYTUwgZGVjbGFyYXRpb24uIDwvZGQ+Ci0gICAgICogPGR0PgotICAgICAqIDxjb2RlPmZhbHNlPC9jb2RlPjwvZHQ+Ci0gICAgICogPGRkPls8ZW0+cmVxdWlyZWQ8L2VtPl0gRG8gbm90IHNlcmlhbGl6ZSB0aGUgWE1MIGFuZCB0ZXh0IGRlY2xhcmF0aW9ucy4gUmVwb3J0IGEKLSAgICAgKiA8Y29kZT4ieG1sLWRlY2xhcmF0aW9uLW5lZWRlZCI8L2NvZGU+IHdhcm5pbmcgaWYgdGhpcyB3aWxsIGNhdXNlCi0gICAgICogcHJvYmxlbXMgKGkuZS4gdGhlIHNlcmlhbGl6ZWQgZGF0YSBpcyBvZiBhbiBYTUwgdmVyc2lvbiBvdGhlciB0aGFuIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy14bWwtMjAwNDAyMDQnPlhNTCAxLjA8L2E+XSwgb3IgYW4KLSAgICAgKiBlbmNvZGluZyB3b3VsZCBiZSBuZWVkZWQgdG8gYmUgYWJsZSB0byByZS1wYXJzZSB0aGUgc2VyaWFsaXplZCBkYXRhKS4gPC9kZD4KLSAgICAgKiA8L2RsPjwvZGQ+Ci0gICAgICogPC9kbD4KLSAgICAgKi8KLSAgICBwdWJsaWMgRE9NQ29uZmlndXJhdGlvbiBnZXREb21Db25maWcoKTsKLQotICAgIC8qKgotICAgICAqICBUaGUgZW5kLW9mLWxpbmUgc2VxdWVuY2Ugb2YgY2hhcmFjdGVycyB0byBiZSB1c2VkIGluIHRoZSBYTUwgYmVpbmcKLSAgICAgKiB3cml0dGVuIG91dC4gQW55IHN0cmluZyBpcyBzdXBwb3J0ZWQsIGJ1dCBYTUwgdHJlYXRzIG9ubHkgYSBjZXJ0YWluCi0gICAgICogc2V0IG9mIGNoYXJhY3RlcnMgc2VxdWVuY2UgYXMgZW5kLW9mLWxpbmUgKFNlZSBzZWN0aW9uIDIuMTEsCi0gICAgICogIkVuZC1vZi1MaW5lIEhhbmRsaW5nIiBpbiBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMteG1sLTIwMDQwMjA0Jz5YTUwgMS4wPC9hPl0sIGlmIHRoZQotICAgICAqIHNlcmlhbGl6ZWQgY29udGVudCBpcyBYTUwgMS4wIG9yIHNlY3Rpb24gMi4xMSwgIkVuZC1vZi1MaW5lIEhhbmRsaW5nIgotICAgICAqIGluIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy14bWwxMS0yMDA0MDIwNC8nPlhNTCAxLjE8L2E+XSwgaWYgdGhlCi0gICAgICogc2VyaWFsaXplZCBjb250ZW50IGlzIFhNTCAxLjEpLiBVc2luZyBvdGhlciBjaGFyYWN0ZXIgc2VxdWVuY2VzIHRoYW4KLSAgICAgKiB0aGUgcmVjb21tZW5kZWQgb25lcyBjYW4gcmVzdWx0IGluIGEgZG9jdW1lbnQgdGhhdCBpcyBlaXRoZXIgbm90Ci0gICAgICogc2VyaWFsaXphYmxlIG9yIG5vdCB3ZWxsLWZvcm1lZCkuCi0gICAgICogPGJyPiBPbiByZXRyaWV2YWwsIHRoZSBkZWZhdWx0IHZhbHVlIG9mIHRoaXMgYXR0cmlidXRlIGlzIHRoZQotICAgICAqIGltcGxlbWVudGF0aW9uIHNwZWNpZmljIGRlZmF1bHQgZW5kLW9mLWxpbmUgc2VxdWVuY2UuIERPTQotICAgICAqIGltcGxlbWVudGF0aW9ucyBzaG91bGQgY2hvb3NlIHRoZSBkZWZhdWx0IHRvIG1hdGNoIHRoZSB1c3VhbAotICAgICAqIGNvbnZlbnRpb24gZm9yIHRleHQgZmlsZXMgaW4gdGhlIGVudmlyb25tZW50IGJlaW5nIHVzZWQuCi0gICAgICogSW1wbGVtZW50YXRpb25zIG11c3QgY2hvb3NlIGEgZGVmYXVsdCBzZXF1ZW5jZSB0aGF0IG1hdGNoZXMgb25lIG9mCi0gICAgICogdGhvc2UgYWxsb3dlZCBieSBYTUwgMS4wIG9yIFhNTCAxLjEsIGRlcGVuZGluZyBvbiB0aGUgc2VyaWFsaXplZAotICAgICAqIGNvbnRlbnQuIFNldHRpbmcgdGhpcyBhdHRyaWJ1dGUgdG8gPGNvZGU+bnVsbDwvY29kZT4gd2lsbCByZXNldCBpdHMKLSAgICAgKiB2YWx1ZSB0byB0aGUgZGVmYXVsdCB2YWx1ZS4KLSAgICAgKiA8YnI+Ci0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXROZXdMaW5lKCk7Ci0gICAgLyoqCi0gICAgICogIFRoZSBlbmQtb2YtbGluZSBzZXF1ZW5jZSBvZiBjaGFyYWN0ZXJzIHRvIGJlIHVzZWQgaW4gdGhlIFhNTCBiZWluZwotICAgICAqIHdyaXR0ZW4gb3V0LiBBbnkgc3RyaW5nIGlzIHN1cHBvcnRlZCwgYnV0IFhNTCB0cmVhdHMgb25seSBhIGNlcnRhaW4KLSAgICAgKiBzZXQgb2YgY2hhcmFjdGVycyBzZXF1ZW5jZSBhcyBlbmQtb2YtbGluZSAoU2VlIHNlY3Rpb24gMi4xMSwKLSAgICAgKiAiRW5kLW9mLUxpbmUgSGFuZGxpbmciIGluIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA0L1JFQy14bWwtMjAwNDAyMDQnPlhNTCAxLjA8L2E+XSwgaWYgdGhlCi0gICAgICogc2VyaWFsaXplZCBjb250ZW50IGlzIFhNTCAxLjAgb3Igc2VjdGlvbiAyLjExLCAiRW5kLW9mLUxpbmUgSGFuZGxpbmciCi0gICAgICogaW4gWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLXhtbDExLTIwMDQwMjA0Lyc+WE1MIDEuMTwvYT5dLCBpZiB0aGUKLSAgICAgKiBzZXJpYWxpemVkIGNvbnRlbnQgaXMgWE1MIDEuMSkuIFVzaW5nIG90aGVyIGNoYXJhY3RlciBzZXF1ZW5jZXMgdGhhbgotICAgICAqIHRoZSByZWNvbW1lbmRlZCBvbmVzIGNhbiByZXN1bHQgaW4gYSBkb2N1bWVudCB0aGF0IGlzIGVpdGhlciBub3QKLSAgICAgKiBzZXJpYWxpemFibGUgb3Igbm90IHdlbGwtZm9ybWVkKS4KLSAgICAgKiA8YnI+IE9uIHJldHJpZXZhbCwgdGhlIGRlZmF1bHQgdmFsdWUgb2YgdGhpcyBhdHRyaWJ1dGUgaXMgdGhlCi0gICAgICogaW1wbGVtZW50YXRpb24gc3BlY2lmaWMgZGVmYXVsdCBlbmQtb2YtbGluZSBzZXF1ZW5jZS4gRE9NCi0gICAgICogaW1wbGVtZW50YXRpb25zIHNob3VsZCBjaG9vc2UgdGhlIGRlZmF1bHQgdG8gbWF0Y2ggdGhlIHVzdWFsCi0gICAgICogY29udmVudGlvbiBmb3IgdGV4dCBmaWxlcyBpbiB0aGUgZW52aXJvbm1lbnQgYmVpbmcgdXNlZC4KLSAgICAgKiBJbXBsZW1lbnRhdGlvbnMgbXVzdCBjaG9vc2UgYSBkZWZhdWx0IHNlcXVlbmNlIHRoYXQgbWF0Y2hlcyBvbmUgb2YKLSAgICAgKiB0aG9zZSBhbGxvd2VkIGJ5IFhNTCAxLjAgb3IgWE1MIDEuMSwgZGVwZW5kaW5nIG9uIHRoZSBzZXJpYWxpemVkCi0gICAgICogY29udGVudC4gU2V0dGluZyB0aGlzIGF0dHJpYnV0ZSB0byA8Y29kZT5udWxsPC9jb2RlPiB3aWxsIHJlc2V0IGl0cwotICAgICAqIHZhbHVlIHRvIHRoZSBkZWZhdWx0IHZhbHVlLgotICAgICAqIDxicj4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXROZXdMaW5lKFN0cmluZyBuZXdMaW5lKTsKLQotICAgIC8qKgotICAgICAqICBXaGVuIHRoZSBhcHBsaWNhdGlvbiBwcm92aWRlcyBhIGZpbHRlciwgdGhlIHNlcmlhbGl6ZXIgd2lsbCBjYWxsIG91dAotICAgICAqIHRvIHRoZSBmaWx0ZXIgYmVmb3JlIHNlcmlhbGl6aW5nIGVhY2ggTm9kZS4gVGhlIGZpbHRlciBpbXBsZW1lbnRhdGlvbgotICAgICAqIGNhbiBjaG9vc2UgdG8gcmVtb3ZlIHRoZSBub2RlIGZyb20gdGhlIHN0cmVhbSBvciB0byB0ZXJtaW5hdGUgdGhlCi0gICAgICogc2VyaWFsaXphdGlvbiBlYXJseS4KLSAgICAgKiA8YnI+IFRoZSBmaWx0ZXIgaXMgaW52b2tlZCBhZnRlciB0aGUgb3BlcmF0aW9ucyByZXF1ZXN0ZWQgYnkgdGhlCi0gICAgICogPGNvZGU+RE9NQ29uZmlndXJhdGlvbjwvY29kZT4gcGFyYW1ldGVycyBoYXZlIGJlZW4gYXBwbGllZC4gRm9yCi0gICAgICogZXhhbXBsZSwgQ0RBVEEgc2VjdGlvbnMgd29uJ3QgYmUgcGFzc2VkIHRvIHRoZSBmaWx0ZXIgaWYgIjxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0zLUNvcmUvY29yZS5odG1sI3BhcmFtZXRlci1jZGF0YS1zZWN0aW9ucyc+Ci0gICAgICogY2RhdGEtc2VjdGlvbnM8L2E+IiBpcyBzZXQgdG8gPGNvZGU+ZmFsc2U8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBMU1NlcmlhbGl6ZXJGaWx0ZXIgZ2V0RmlsdGVyKCk7Ci0gICAgLyoqCi0gICAgICogIFdoZW4gdGhlIGFwcGxpY2F0aW9uIHByb3ZpZGVzIGEgZmlsdGVyLCB0aGUgc2VyaWFsaXplciB3aWxsIGNhbGwgb3V0Ci0gICAgICogdG8gdGhlIGZpbHRlciBiZWZvcmUgc2VyaWFsaXppbmcgZWFjaCBOb2RlLiBUaGUgZmlsdGVyIGltcGxlbWVudGF0aW9uCi0gICAgICogY2FuIGNob29zZSB0byByZW1vdmUgdGhlIG5vZGUgZnJvbSB0aGUgc3RyZWFtIG9yIHRvIHRlcm1pbmF0ZSB0aGUKLSAgICAgKiBzZXJpYWxpemF0aW9uIGVhcmx5LgotICAgICAqIDxicj4gVGhlIGZpbHRlciBpcyBpbnZva2VkIGFmdGVyIHRoZSBvcGVyYXRpb25zIHJlcXVlc3RlZCBieSB0aGUKLSAgICAgKiA8Y29kZT5ET01Db25maWd1cmF0aW9uPC9jb2RlPiBwYXJhbWV0ZXJzIGhhdmUgYmVlbiBhcHBsaWVkLiBGb3IKLSAgICAgKiBleGFtcGxlLCBDREFUQSBzZWN0aW9ucyB3b24ndCBiZSBwYXNzZWQgdG8gdGhlIGZpbHRlciBpZiAiPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTMtQ29yZS9jb3JlLmh0bWwjcGFyYW1ldGVyLWNkYXRhLXNlY3Rpb25zJz4KLSAgICAgKiBjZGF0YS1zZWN0aW9uczwvYT4iIGlzIHNldCB0byA8Y29kZT5mYWxzZTwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RmlsdGVyKExTU2VyaWFsaXplckZpbHRlciBmaWx0ZXIpOwotCi0gICAgLyoqCi0gICAgICogIFNlcmlhbGl6ZSB0aGUgc3BlY2lmaWVkIG5vZGUgYXMgZGVzY3JpYmVkIGFib3ZlIGluIHRoZSBnZW5lcmFsCi0gICAgICogZGVzY3JpcHRpb24gb2YgdGhlIDxjb2RlPkxTU2VyaWFsaXplcjwvY29kZT4gaW50ZXJmYWNlLiBUaGUgb3V0cHV0IGlzCi0gICAgICogd3JpdHRlbiB0byB0aGUgc3VwcGxpZWQgPGNvZGU+TFNPdXRwdXQ8L2NvZGU+LgotICAgICAqIDxicj4gV2hlbiB3cml0aW5nIHRvIGEgPGNvZGU+TFNPdXRwdXQ8L2NvZGU+LCB0aGUgZW5jb2RpbmcgaXMgZm91bmQgYnkKLSAgICAgKiBsb29raW5nIGF0IHRoZSBlbmNvZGluZyBpbmZvcm1hdGlvbiB0aGF0IGlzIHJlYWNoYWJsZSB0aHJvdWdoIHRoZQotICAgICAqIDxjb2RlPkxTT3V0cHV0PC9jb2RlPiBhbmQgdGhlIGl0ZW0gdG8gYmUgd3JpdHRlbiAob3IgaXRzIG93bmVyCi0gICAgICogZG9jdW1lbnQpIGluIHRoaXMgb3JkZXI6Ci0gICAgICogPG9sPgotICAgICAqIDxsaT4gPGNvZGU+TFNPdXRwdXQuZW5jb2Rpbmc8L2NvZGU+LAotICAgICAqIDwvbGk+Ci0gICAgICogPGxpPgotICAgICAqIDxjb2RlPkRvY3VtZW50LmlucHV0RW5jb2Rpbmc8L2NvZGU+LAotICAgICAqIDwvbGk+Ci0gICAgICogPGxpPgotICAgICAqIDxjb2RlPkRvY3VtZW50LnhtbEVuY29kaW5nPC9jb2RlPi4KLSAgICAgKiA8L2xpPgotICAgICAqIDwvb2w+Ci0gICAgICogPGJyPiBJZiBubyBlbmNvZGluZyBpcyByZWFjaGFibGUgdGhyb3VnaCB0aGUgYWJvdmUgcHJvcGVydGllcywgYQotICAgICAqIGRlZmF1bHQgZW5jb2Rpbmcgb2YgIlVURi04IiB3aWxsIGJlIHVzZWQuIElmIHRoZSBzcGVjaWZpZWQgZW5jb2RpbmcKLSAgICAgKiBpcyBub3Qgc3VwcG9ydGVkIGFuICJ1bnN1cHBvcnRlZC1lbmNvZGluZyIgZmF0YWwgZXJyb3IgaXMgcmFpc2VkLgotICAgICAqIDxicj4gSWYgbm8gb3V0cHV0IGlzIHNwZWNpZmllZCBpbiB0aGUgPGNvZGU+TFNPdXRwdXQ8L2NvZGU+LCBhCi0gICAgICogIm5vLW91dHB1dC1zcGVjaWZpZWQiIGZhdGFsIGVycm9yIGlzIHJhaXNlZC4KLSAgICAgKiA8YnI+IFRoZSBpbXBsZW1lbnRhdGlvbiBpcyByZXNwb25zaWJsZSBvZiBhc3NvY2lhdGluZyB0aGUgYXBwcm9wcmlhdGUKLSAgICAgKiBtZWRpYSB0eXBlIHdpdGggdGhlIHNlcmlhbGl6ZWQgZGF0YS4KLSAgICAgKiA8YnI+IFdoZW4gd3JpdGluZyB0byBhIEhUVFAgVVJJLCBhIEhUVFAgUFVUIGlzIHBlcmZvcm1lZC4gV2hlbiB3cml0aW5nCi0gICAgICogdG8gb3RoZXIgdHlwZXMgb2YgVVJJcywgdGhlIG1lY2hhbmlzbSBmb3Igd3JpdGluZyB0aGUgZGF0YSB0byB0aGUgVVJJCi0gICAgICogaXMgaW1wbGVtZW50YXRpb24gZGVwZW5kZW50LgotICAgICAqIEBwYXJhbSBub2RlQXJnICBUaGUgbm9kZSB0byBzZXJpYWxpemUuCi0gICAgICogQHBhcmFtIGRlc3RpbmF0aW9uIFRoZSBkZXN0aW5hdGlvbiBmb3IgdGhlIHNlcmlhbGl6ZWQgRE9NLgotICAgICAqIEByZXR1cm4gIFJldHVybnMgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgPGNvZGU+bm9kZTwvY29kZT4gd2FzCi0gICAgICogICBzdWNjZXNzZnVsbHkgc2VyaWFsaXplZC4gUmV0dXJuIDxjb2RlPmZhbHNlPC9jb2RlPiBpbiBjYXNlIHRoZQotICAgICAqICAgbm9ybWFsIHByb2Nlc3Npbmcgc3RvcHBlZCBidXQgdGhlIGltcGxlbWVudGF0aW9uIGtlcHQgc2VyaWFsaXppbmcKLSAgICAgKiAgIHRoZSBkb2N1bWVudDsgdGhlIHJlc3VsdCBvZiB0aGUgc2VyaWFsaXphdGlvbiBiZWluZyBpbXBsZW1lbnRhdGlvbgotICAgICAqICAgZGVwZW5kZW50IHRoZW4uCi0gICAgICogQGV4Y2VwdGlvbiBMU0V4Y2VwdGlvbgotICAgICAqICAgIFNFUklBTElaRV9FUlI6IFJhaXNlZCBpZiB0aGUgPGNvZGU+TFNTZXJpYWxpemVyPC9jb2RlPiB3YXMgdW5hYmxlIHRvCi0gICAgICogICBzZXJpYWxpemUgdGhlIG5vZGUuIERPTSBhcHBsaWNhdGlvbnMgc2hvdWxkIGF0dGFjaCBhCi0gICAgICogICA8Y29kZT5ET01FcnJvckhhbmRsZXI8L2NvZGU+IHVzaW5nIHRoZSBwYXJhbWV0ZXIgIjxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0zLUNvcmUvY29yZS5odG1sI3BhcmFtZXRlci1lcnJvci1oYW5kbGVyJz4KLSAgICAgKiAgIGVycm9yLWhhbmRsZXI8L2E+IiBpZiB0aGV5IHdpc2ggdG8gZ2V0IGRldGFpbHMgb24gdGhlIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIHdyaXRlKE5vZGUgbm9kZUFyZywKLSAgICAgICAgICAgICAgICAgICAgICAgICBMU091dHB1dCBkZXN0aW5hdGlvbikKLSAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgTFNFeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiAgQSBjb252ZW5pZW5jZSBtZXRob2QgdGhhdCBhY3RzIGFzIGlmIDxjb2RlPkxTU2VyaWFsaXplci53cml0ZTwvY29kZT4KLSAgICAgKiB3YXMgY2FsbGVkIHdpdGggYSA8Y29kZT5MU091dHB1dDwvY29kZT4gd2l0aCBubyBlbmNvZGluZyBzcGVjaWZpZWQKLSAgICAgKiBhbmQgPGNvZGU+TFNPdXRwdXQuc3lzdGVtSWQ8L2NvZGU+IHNldCB0byB0aGUgPGNvZGU+dXJpPC9jb2RlPgotICAgICAqIGFyZ3VtZW50LgotICAgICAqIEBwYXJhbSBub2RlQXJnICBUaGUgbm9kZSB0byBzZXJpYWxpemUuCi0gICAgICogQHBhcmFtIHVyaSBUaGUgVVJJIHRvIHdyaXRlIHRvLgotICAgICAqIEByZXR1cm4gIFJldHVybnMgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgPGNvZGU+bm9kZTwvY29kZT4gd2FzCi0gICAgICogICBzdWNjZXNzZnVsbHkgc2VyaWFsaXplZC4gUmV0dXJuIDxjb2RlPmZhbHNlPC9jb2RlPiBpbiBjYXNlIHRoZQotICAgICAqICAgbm9ybWFsIHByb2Nlc3Npbmcgc3RvcHBlZCBidXQgdGhlIGltcGxlbWVudGF0aW9uIGtlcHQgc2VyaWFsaXppbmcKLSAgICAgKiAgIHRoZSBkb2N1bWVudDsgdGhlIHJlc3VsdCBvZiB0aGUgc2VyaWFsaXphdGlvbiBiZWluZyBpbXBsZW1lbnRhdGlvbgotICAgICAqICAgZGVwZW5kZW50IHRoZW4uCi0gICAgICogQGV4Y2VwdGlvbiBMU0V4Y2VwdGlvbgotICAgICAqICAgIFNFUklBTElaRV9FUlI6IFJhaXNlZCBpZiB0aGUgPGNvZGU+TFNTZXJpYWxpemVyPC9jb2RlPiB3YXMgdW5hYmxlIHRvCi0gICAgICogICBzZXJpYWxpemUgdGhlIG5vZGUuIERPTSBhcHBsaWNhdGlvbnMgc2hvdWxkIGF0dGFjaCBhCi0gICAgICogICA8Y29kZT5ET01FcnJvckhhbmRsZXI8L2NvZGU+IHVzaW5nIHRoZSBwYXJhbWV0ZXIgIjxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0zLUNvcmUvY29yZS5odG1sI3BhcmFtZXRlci1lcnJvci1oYW5kbGVyJz4KLSAgICAgKiAgIGVycm9yLWhhbmRsZXI8L2E+IiBpZiB0aGV5IHdpc2ggdG8gZ2V0IGRldGFpbHMgb24gdGhlIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIHdyaXRlVG9VUkkoTm9kZSBub2RlQXJnLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHVyaSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBMU0V4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBTZXJpYWxpemUgdGhlIHNwZWNpZmllZCBub2RlIGFzIGRlc2NyaWJlZCBhYm92ZSBpbiB0aGUgZ2VuZXJhbAotICAgICAqIGRlc2NyaXB0aW9uIG9mIHRoZSA8Y29kZT5MU1NlcmlhbGl6ZXI8L2NvZGU+IGludGVyZmFjZS4gVGhlIG91dHB1dCBpcwotICAgICAqIHdyaXR0ZW4gdG8gYSA8Y29kZT5ET01TdHJpbmc8L2NvZGU+IHRoYXQgaXMgcmV0dXJuZWQgdG8gdGhlIGNhbGxlci4KLSAgICAgKiBUaGUgZW5jb2RpbmcgdXNlZCBpcyB0aGUgZW5jb2Rpbmcgb2YgdGhlIDxjb2RlPkRPTVN0cmluZzwvY29kZT4gdHlwZSwKLSAgICAgKiBpLmUuIFVURi0xNi4gTm90ZSB0aGF0IG5vIEJ5dGUgT3JkZXIgTWFyayBpcyBnZW5lcmF0ZWQgaW4gYQotICAgICAqIDxjb2RlPkRPTVN0cmluZzwvY29kZT4gb2JqZWN0LgotICAgICAqIEBwYXJhbSBub2RlQXJnICBUaGUgbm9kZSB0byBzZXJpYWxpemUuCi0gICAgICogQHJldHVybiAgUmV0dXJucyB0aGUgc2VyaWFsaXplZCBkYXRhLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICAgRE9NU1RSSU5HX1NJWkVfRVJSOiBSYWlzZWQgaWYgdGhlIHJlc3VsdGluZyBzdHJpbmcgaXMgdG9vIGxvbmcgdG8KLSAgICAgKiAgIGZpdCBpbiBhIDxjb2RlPkRPTVN0cmluZzwvY29kZT4uCi0gICAgICogQGV4Y2VwdGlvbiBMU0V4Y2VwdGlvbgotICAgICAqICAgIFNFUklBTElaRV9FUlI6IFJhaXNlZCBpZiB0aGUgPGNvZGU+TFNTZXJpYWxpemVyPC9jb2RlPiB3YXMgdW5hYmxlIHRvCi0gICAgICogICBzZXJpYWxpemUgdGhlIG5vZGUuIERPTSBhcHBsaWNhdGlvbnMgc2hvdWxkIGF0dGFjaCBhCi0gICAgICogICA8Y29kZT5ET01FcnJvckhhbmRsZXI8L2NvZGU+IHVzaW5nIHRoZSBwYXJhbWV0ZXIgIjxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0zLUNvcmUvY29yZS5odG1sI3BhcmFtZXRlci1lcnJvci1oYW5kbGVyJz4KLSAgICAgKiAgIGVycm9yLWhhbmRsZXI8L2E+IiBpZiB0aGV5IHdpc2ggdG8gZ2V0IGRldGFpbHMgb24gdGhlIGVycm9yLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgd3JpdGVUb1N0cmluZyhOb2RlIG5vZGVBcmcpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb24sIExTRXhjZXB0aW9uOwotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL3czYy9kb20vbHMvTFNTZXJpYWxpemVyRmlsdGVyLmphdmEgYi9zcmMvb3JnL3czYy9kb20vbHMvTFNTZXJpYWxpemVyRmlsdGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGJjOGU3MjQuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy93M2MvZG9tL2xzL0xTU2VyaWFsaXplckZpbHRlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTIgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIFRoaXMgZmlsZSBpcyBhdmFpbGFibGUgdW5kZXIgYW5kIGdvdmVybmVkIGJ5IHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKLSAqIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICogSG93ZXZlciwgdGhlIGZvbGxvd2luZyBub3RpY2UgYWNjb21wYW5pZWQgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcwotICogZmlsZSBhbmQsIHBlciBpdHMgdGVybXMsIHNob3VsZCBub3QgYmUgcmVtb3ZlZDoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDQgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKLSAqCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgRXVyb3BlYW4gUmVzZWFyY2ggQ29uc29ydGl1bSBmb3IKLSAqIEluZm9ybWF0aWNzIGFuZCBNYXRoZW1hdGljcywgS2VpbyBVbml2ZXJzaXR5KS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcwotICogd29yayBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDKHIpIFNvZnR3YXJlIExpY2Vuc2UgWzFdIGluIHRoZSBob3BlIHRoYXQKLSAqIGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZAotICogd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLgotICoKLSAqIFsxXSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLzIwMDIvY29weXJpZ2h0LXNvZnR3YXJlLTIwMDIxMjMxCi0gKi8KLQotcGFja2FnZSBvcmcudzNjLmRvbS5sczsKLQotaW1wb3J0IG9yZy53M2MuZG9tLnRyYXZlcnNhbC5Ob2RlRmlsdGVyOwotCi0vKioKLSAqICA8Y29kZT5MU1NlcmlhbGl6ZXJGaWx0ZXI8L2NvZGU+cyBwcm92aWRlIGFwcGxpY2F0aW9ucyB0aGUgYWJpbGl0eSB0bwotICogZXhhbWluZSBub2RlcyBhcyB0aGV5IGFyZSBiZWluZyBzZXJpYWxpemVkIGFuZCBkZWNpZGUgd2hhdCBub2RlcyBzaG91bGQKLSAqIGJlIHNlcmlhbGl6ZWQgb3Igbm90LiBUaGUgPGNvZGU+TFNTZXJpYWxpemVyRmlsdGVyPC9jb2RlPiBpbnRlcmZhY2UgaXMKLSAqIGJhc2VkIG9uIHRoZSA8Y29kZT5Ob2RlRmlsdGVyPC9jb2RlPiBpbnRlcmZhY2UgZGVmaW5lZCBpbiBbPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMC9SRUMtRE9NLUxldmVsLTItVHJhdmVyc2FsLVJhbmdlLTIwMDAxMTEzJz5ET00gTGV2ZWwgMiBUcmF2ZXJzYWwgYW5kICAgICAgUmFuZ2U8L2E+XQotICogLgotICogPHA+IDxjb2RlPkRvY3VtZW50PC9jb2RlPiwgPGNvZGU+RG9jdW1lbnRUeXBlPC9jb2RlPiwKLSAqIDxjb2RlPkRvY3VtZW50RnJhZ21lbnQ8L2NvZGU+LCA8Y29kZT5Ob3RhdGlvbjwvY29kZT4sIDxjb2RlPkVudGl0eTwvY29kZT4KLSAqICwgYW5kIGNoaWxkcmVuIG9mIDxjb2RlPkF0dHI8L2NvZGU+IG5vZGVzIGFyZSBub3QgcGFzc2VkIHRvIHRoZSBmaWx0ZXIuCi0gKiBUaGUgY2hpbGQgbm9kZXMgb2YgYW4gPGNvZGU+RW50aXR5UmVmZXJlbmNlPC9jb2RlPiBub2RlIGFyZSBvbmx5IHBhc3NlZAotICogdG8gdGhlIGZpbHRlciBpZiB0aGUgPGNvZGU+RW50aXR5UmVmZXJlbmNlPC9jb2RlPiBub2RlIGlzIHNraXBwZWQgYnkgdGhlCi0gKiBtZXRob2QgPGNvZGU+TFNQYXJzZXJGaWx0ZXIuYWNjZXB0Tm9kZSgpPC9jb2RlPi4KLSAqIDxwPiBXaGVuIHNlcmlhbGl6aW5nIGFuIDxjb2RlPkVsZW1lbnQ8L2NvZGU+LCB0aGUgZWxlbWVudCBpcyBwYXNzZWQgdG8gdGhlCi0gKiBmaWx0ZXIgYmVmb3JlIGFueSBvZiBpdHMgYXR0cmlidXRlcyBhcmUgcGFzc2VkIHRvIHRoZSBmaWx0ZXIuIE5hbWVzcGFjZQotICogZGVjbGFyYXRpb24gYXR0cmlidXRlcywgYW5kIGRlZmF1bHQgYXR0cmlidXRlcyAoZXhjZXB0IGluIHRoZSBjYXNlIHdoZW4gIgotICogZGlzY2FyZC1kZWZhdWx0LWNvbnRlbnQiIGlzIHNldCB0byA8Y29kZT5mYWxzZTwvY29kZT4pLCBhcmUgbmV2ZXIgcGFzc2VkCi0gKiB0byB0aGUgZmlsdGVyLgotICogPHA+IFRoZSByZXN1bHQgb2YgYW55IGF0dGVtcHQgdG8gbW9kaWZ5IGEgbm9kZSBwYXNzZWQgdG8gYQotICogPGNvZGU+TFNTZXJpYWxpemVyRmlsdGVyPC9jb2RlPiBpcyBpbXBsZW1lbnRhdGlvbiBkZXBlbmRlbnQuCi0gKiA8cD4gRE9NIGFwcGxpY2F0aW9ucyBtdXN0IG5vdCByYWlzZSBleGNlcHRpb25zIGluIGEgZmlsdGVyLiBUaGUgZWZmZWN0IG9mCi0gKiB0aHJvd2luZyBleGNlcHRpb25zIGZyb20gYSBmaWx0ZXIgaXMgRE9NIGltcGxlbWVudGF0aW9uIGRlcGVuZGVudC4KLSAqIDxwPiBGb3IgZWZmaWNpZW5jeSwgYSBub2RlIHBhc3NlZCB0byB0aGUgZmlsdGVyIG1heSBub3QgYmUgdGhlIHNhbWUgYXMgdGhlCi0gKiBvbmUgdGhhdCBpcyBhY3R1YWxseSBpbiB0aGUgdHJlZS4gQW5kIHRoZSBhY3R1YWwgbm9kZSAobm9kZSBvYmplY3QKLSAqIGlkZW50aXR5KSBtYXkgYmUgcmV1c2VkIGR1cmluZyB0aGUgcHJvY2VzcyBvZiBmaWx0ZXJpbmcgYW5kIHNlcmlhbGl6aW5nIGEKLSAqIGRvY3VtZW50LgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDQvUkVDLURPTS1MZXZlbC0zLUxTLTIwMDQwNDA3Jz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMyBMb2FkCi1hbmQgU2F2ZSBTcGVjaWZpY2F0aW9uPC9hPi4KLSAqLwotcHVibGljIGludGVyZmFjZSBMU1NlcmlhbGl6ZXJGaWx0ZXIgZXh0ZW5kcyBOb2RlRmlsdGVyIHsKLSAgICAvKioKLSAgICAgKiAgVGVsbHMgdGhlIDxjb2RlPkxTU2VyaWFsaXplcjwvY29kZT4gd2hhdCB0eXBlcyBvZiBub2RlcyB0byBzaG93IHRvIHRoZQotICAgICAqIGZpbHRlci4gSWYgYSBub2RlIGlzIG5vdCBzaG93biB0byB0aGUgZmlsdGVyIHVzaW5nIHRoaXMgYXR0cmlidXRlLCBpdAotICAgICAqIGlzIGF1dG9tYXRpY2FsbHkgc2VyaWFsaXplZC4gU2VlIDxjb2RlPk5vZGVGaWx0ZXI8L2NvZGU+IGZvcgotICAgICAqIGRlZmluaXRpb24gb2YgdGhlIGNvbnN0YW50cy4gVGhlIGNvbnN0YW50cyA8Y29kZT5TSE9XX0RPQ1VNRU5UPC9jb2RlPgotICAgICAqICwgPGNvZGU+U0hPV19ET0NVTUVOVF9UWVBFPC9jb2RlPiwgPGNvZGU+U0hPV19ET0NVTUVOVF9GUkFHTUVOVDwvY29kZT4KLSAgICAgKiAsIDxjb2RlPlNIT1dfTk9UQVRJT048L2NvZGU+LCBhbmQgPGNvZGU+U0hPV19FTlRJVFk8L2NvZGU+IGFyZQotICAgICAqIG1lYW5pbmdsZXNzIGhlcmUsIHN1Y2ggbm9kZXMgd2lsbCBuZXZlciBiZSBwYXNzZWQgdG8gYQotICAgICAqIDxjb2RlPkxTU2VyaWFsaXplckZpbHRlcjwvY29kZT4uCi0gICAgICogPGJyPiBVbmxpa2UgWzxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDAvUkVDLURPTS1MZXZlbC0yLVRyYXZlcnNhbC1SYW5nZS0yMDAwMTExMyc+RE9NIExldmVsIDIgVHJhdmVyc2FsIGFuZCAgICAgIFJhbmdlPC9hPl0KLSAgICAgKiAsIHRoZSA8Y29kZT5TSE9XX0FUVFJJQlVURTwvY29kZT4gY29uc3RhbnQgaW5kaWNhdGVzIHRoYXQgdGhlCi0gICAgICogPGNvZGU+QXR0cjwvY29kZT4gbm9kZXMgYXJlIHNob3duIGFuZCBwYXNzZWQgdG8gdGhlIGZpbHRlci4KLSAgICAgKiA8YnI+IFRoZSBjb25zdGFudHMgdXNlZCBoZXJlIGFyZSBkZWZpbmVkIGluIFs8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAwL1JFQy1ET00tTGV2ZWwtMi1UcmF2ZXJzYWwtUmFuZ2UtMjAwMDExMTMnPkRPTSBMZXZlbCAyIFRyYXZlcnNhbCBhbmQgICAgICBSYW5nZTwvYT5dCi0gICAgICogLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0V2hhdFRvU2hvdygpOwotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL3czYy9kb20vcGFja2FnZS5odG1sIGIvc3JjL29yZy93M2MvZG9tL3BhY2thZ2UuaHRtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMzYyYjFmZi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3czYy9kb20vcGFja2FnZS5odG1sCisrKyAvZGV2L251bGwKQEAgLTEsMTMgKzAsMCBAQAotPGh0bWw+Ci08aGVhZD4KLTx0aXRsZT5vcmcudzNjLmRvbSBwYWNrYWdlPC90aXRsZT4KLTwvaGVhZD4KLTxib2R5IGJnY29sb3I9IndoaXRlIj4KLVByb3ZpZGVzIHRoZSBpbnRlcmZhY2VzIGZvciB0aGUgRG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pLiBTdXBwb3J0cyB0aGUKLTxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUNvcmUvIj5Eb2N1bWVudCBPYmplY3QgTW9kZWwgTGV2ZWwgMiBDb3JlIEFQSWk8L2E+LCAKLTxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0zLUNvcmUiPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAzIENvcmU8L2E+LCAKLWFuZCA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMy1MUyI+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDMgTG9hZCBhbmQgU2F2ZTwvYT4uCi0KLUBzaW5jZSBKREsxLjQKLTwvYm9keT4KLTwvaHRtbD4KZGlmZiAtLWdpdCBhL3NyYy9vcmcvdzNjL2RvbS9yYW5nZXMvRG9jdW1lbnRSYW5nZS5qYXZhIGIvc3JjL29yZy93M2MvZG9tL3Jhbmdlcy9Eb2N1bWVudFJhbmdlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDM0MmY5ZTMuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy93M2MvZG9tL3Jhbmdlcy9Eb2N1bWVudFJhbmdlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw2MiArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogVGhpcyBmaWxlIGlzIGF2YWlsYWJsZSB1bmRlciBhbmQgZ292ZXJuZWQgYnkgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwotICogTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKiBIb3dldmVyLCB0aGUgZm9sbG93aW5nIG5vdGljZSBhY2NvbXBhbmllZCB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGlzCi0gKiBmaWxlIGFuZCwgcGVyIGl0cyB0ZXJtcywgc2hvdWxkIG5vdCBiZSByZW1vdmVkOgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAotICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCi0gKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKLSAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQotICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKLSAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KLSAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKLSAqIFBVUlBPU0UuCi0gKiBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KLSAqLwotCi1wYWNrYWdlIG9yZy53M2MuZG9tLnJhbmdlczsKLQotLyoqCi0gKiA8cD5TZWUgYWxzbyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMC9SRUMtRE9NLUxldmVsLTItVHJhdmVyc2FsLVJhbmdlLTIwMDAxMTEzJz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMiBUcmF2ZXJzYWwgYW5kIFJhbmdlIFNwZWNpZmljYXRpb248L2E+LgotICogQHNpbmNlIERPTSBMZXZlbCAyCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgRG9jdW1lbnRSYW5nZSB7Ci0gICAgLyoqCi0gICAgICogVGhpcyBpbnRlcmZhY2UgY2FuIGJlIG9idGFpbmVkIGZyb20gdGhlIG9iamVjdCBpbXBsZW1lbnRpbmcgdGhlCi0gICAgICogPGNvZGU+RG9jdW1lbnQ8L2NvZGU+IGludGVyZmFjZSB1c2luZyBiaW5kaW5nLXNwZWNpZmljIGNhc3RpbmcKLSAgICAgKiBtZXRob2RzLgotICAgICAqIEByZXR1cm4gVGhlIGluaXRpYWwgc3RhdGUgb2YgdGhlIFJhbmdlIHJldHVybmVkIGZyb20gdGhpcyBtZXRob2QgaXMKLSAgICAgKiAgIHN1Y2ggdGhhdCBib3RoIG9mIGl0cyBib3VuZGFyeS1wb2ludHMgYXJlIHBvc2l0aW9uZWQgYXQgdGhlCi0gICAgICogICBiZWdpbm5pbmcgb2YgdGhlIGNvcnJlc3BvbmRpbmcgRG9jdW1lbnQsIGJlZm9yZSBhbnkgY29udGVudC4gVGhlCi0gICAgICogICBSYW5nZSByZXR1cm5lZCBjYW4gb25seSBiZSB1c2VkIHRvIHNlbGVjdCBjb250ZW50IGFzc29jaWF0ZWQgd2l0aAotICAgICAqICAgdGhpcyBEb2N1bWVudCwgb3Igd2l0aCBEb2N1bWVudEZyYWdtZW50cyBhbmQgQXR0cnMgZm9yIHdoaWNoIHRoaXMKLSAgICAgKiAgIERvY3VtZW50IGlzIHRoZSA8Y29kZT5vd25lckRvY3VtZW50PC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgUmFuZ2UgY3JlYXRlUmFuZ2UoKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy93M2MvZG9tL3Jhbmdlcy9SYW5nZS5qYXZhIGIvc3JjL29yZy93M2MvZG9tL3Jhbmdlcy9SYW5nZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkNDJmYWQwLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS9yYW5nZXMvUmFuZ2UuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQ0NSArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogVGhpcyBmaWxlIGlzIGF2YWlsYWJsZSB1bmRlciBhbmQgZ292ZXJuZWQgYnkgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwotICogTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKiBIb3dldmVyLCB0aGUgZm9sbG93aW5nIG5vdGljZSBhY2NvbXBhbmllZCB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGlzCi0gKiBmaWxlIGFuZCwgcGVyIGl0cyB0ZXJtcywgc2hvdWxkIG5vdCBiZSByZW1vdmVkOgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAotICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCi0gKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKLSAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQotICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKLSAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KLSAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKLSAqIFBVUlBPU0UuCi0gKiBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KLSAqLwotCi1wYWNrYWdlIG9yZy53M2MuZG9tLnJhbmdlczsKLQotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci1pbXBvcnQgb3JnLnczYy5kb20uRE9NRXhjZXB0aW9uOwotaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50RnJhZ21lbnQ7Ci0KLS8qKgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDAvUkVDLURPTS1MZXZlbC0yLVRyYXZlcnNhbC1SYW5nZS0yMDAwMTExMyc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDIgVHJhdmVyc2FsIGFuZCBSYW5nZSBTcGVjaWZpY2F0aW9uPC9hPi4KLSAqIEBzaW5jZSBET00gTGV2ZWwgMgotICovCi1wdWJsaWMgaW50ZXJmYWNlIFJhbmdlIHsKLSAgICAvKioKLSAgICAgKiBOb2RlIHdpdGhpbiB3aGljaCB0aGUgUmFuZ2UgYmVnaW5zCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIElOVkFMSURfU1RBVEVfRVJSOiBSYWlzZWQgaWYgPGNvZGU+ZGV0YWNoKCk8L2NvZGU+IGhhcyBhbHJlYWR5IGJlZW4KLSAgICAgKiAgIGludm9rZWQgb24gdGhpcyBvYmplY3QuCi0gICAgICovCi0gICAgcHVibGljIE5vZGUgZ2V0U3RhcnRDb250YWluZXIoKQotICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogT2Zmc2V0IHdpdGhpbiB0aGUgc3RhcnRpbmcgbm9kZSBvZiB0aGUgUmFuZ2UuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIElOVkFMSURfU1RBVEVfRVJSOiBSYWlzZWQgaWYgPGNvZGU+ZGV0YWNoKCk8L2NvZGU+IGhhcyBhbHJlYWR5IGJlZW4KLSAgICAgKiAgIGludm9rZWQgb24gdGhpcyBvYmplY3QuCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRTdGFydE9mZnNldCgpCi0gICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBOb2RlIHdpdGhpbiB3aGljaCB0aGUgUmFuZ2UgZW5kcwotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBJTlZBTElEX1NUQVRFX0VSUjogUmFpc2VkIGlmIDxjb2RlPmRldGFjaCgpPC9jb2RlPiBoYXMgYWxyZWFkeSBiZWVuCi0gICAgICogICBpbnZva2VkIG9uIHRoaXMgb2JqZWN0LgotICAgICAqLwotICAgIHB1YmxpYyBOb2RlIGdldEVuZENvbnRhaW5lcigpCi0gICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBPZmZzZXQgd2l0aGluIHRoZSBlbmRpbmcgbm9kZSBvZiB0aGUgUmFuZ2UuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIElOVkFMSURfU1RBVEVfRVJSOiBSYWlzZWQgaWYgPGNvZGU+ZGV0YWNoKCk8L2NvZGU+IGhhcyBhbHJlYWR5IGJlZW4KLSAgICAgKiAgIGludm9rZWQgb24gdGhpcyBvYmplY3QuCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRFbmRPZmZzZXQoKQotICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogVFJVRSBpZiB0aGUgUmFuZ2UgaXMgY29sbGFwc2VkCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIElOVkFMSURfU1RBVEVfRVJSOiBSYWlzZWQgaWYgPGNvZGU+ZGV0YWNoKCk8L2NvZGU+IGhhcyBhbHJlYWR5IGJlZW4KLSAgICAgKiAgIGludm9rZWQgb24gdGhpcyBvYmplY3QuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0Q29sbGFwc2VkKCkKLSAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIFRoZSBkZWVwZXN0IGNvbW1vbiBhbmNlc3RvciBjb250YWluZXIgb2YgdGhlIFJhbmdlJ3MgdHdvCi0gICAgICogYm91bmRhcnktcG9pbnRzLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBJTlZBTElEX1NUQVRFX0VSUjogUmFpc2VkIGlmIDxjb2RlPmRldGFjaCgpPC9jb2RlPiBoYXMgYWxyZWFkeSBiZWVuCi0gICAgICogICBpbnZva2VkIG9uIHRoaXMgb2JqZWN0LgotICAgICAqLwotICAgIHB1YmxpYyBOb2RlIGdldENvbW1vbkFuY2VzdG9yQ29udGFpbmVyKCkKLSAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIGF0dHJpYnV0ZXMgZGVzY3JpYmluZyB0aGUgc3RhcnQgb2YgdGhlIFJhbmdlLgotICAgICAqIEBwYXJhbSByZWZOb2RlIFRoZSA8Y29kZT5yZWZOb2RlPC9jb2RlPiB2YWx1ZS4gVGhpcyBwYXJhbWV0ZXIgbXVzdCBiZQotICAgICAqICAgZGlmZmVyZW50IGZyb20gPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICogQHBhcmFtIG9mZnNldCBUaGUgPGNvZGU+c3RhcnRPZmZzZXQ8L2NvZGU+IHZhbHVlLgotICAgICAqIEBleGNlcHRpb24gUmFuZ2VFeGNlcHRpb24KLSAgICAgKiAgIElOVkFMSURfTk9ERV9UWVBFX0VSUjogUmFpc2VkIGlmIDxjb2RlPnJlZk5vZGU8L2NvZGU+IG9yIGFuIGFuY2VzdG9yCi0gICAgICogICBvZiA8Y29kZT5yZWZOb2RlPC9jb2RlPiBpcyBhbiBFbnRpdHksIE5vdGF0aW9uLCBvciBEb2N1bWVudFR5cGUKLSAgICAgKiAgIG5vZGUuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIElOREVYX1NJWkVfRVJSOiBSYWlzZWQgaWYgPGNvZGU+b2Zmc2V0PC9jb2RlPiBpcyBuZWdhdGl2ZSBvciBncmVhdGVyCi0gICAgICogICB0aGFuIHRoZSBudW1iZXIgb2YgY2hpbGQgdW5pdHMgaW4gPGNvZGU+cmVmTm9kZTwvY29kZT4uIENoaWxkIHVuaXRzCi0gICAgICogICBhcmUgMTYtYml0IHVuaXRzIGlmIDxjb2RlPnJlZk5vZGU8L2NvZGU+IGlzIGEgdHlwZSBvZiBDaGFyYWN0ZXJEYXRhCi0gICAgICogICBub2RlIChlLmcuLCBhIFRleHQgb3IgQ29tbWVudCBub2RlKSBvciBhIFByb2Nlc3NpbmdJbnN0cnVjdGlvbgotICAgICAqICAgbm9kZS4gQ2hpbGQgdW5pdHMgYXJlIE5vZGVzIGluIGFsbCBvdGhlciBjYXNlcy4KLSAgICAgKiAgIDxicj5JTlZBTElEX1NUQVRFX0VSUjogUmFpc2VkIGlmIDxjb2RlPmRldGFjaCgpPC9jb2RlPiBoYXMgYWxyZWFkeQotICAgICAqICAgYmVlbiBpbnZva2VkIG9uIHRoaXMgb2JqZWN0LgotICAgICAqICAgPGJyPldST05HX0RPQ1VNRU5UX0VSUjogUmFpc2VkIGlmIDxjb2RlPnJlZk5vZGU8L2NvZGU+IHdhcyBjcmVhdGVkCi0gICAgICogICBmcm9tIGEgZGlmZmVyZW50IGRvY3VtZW50IHRoYW4gdGhlIG9uZSB0aGF0IGNyZWF0ZWQgdGhpcyByYW5nZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRTdGFydChOb2RlIHJlZk5vZGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgaW50IG9mZnNldCkKLSAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgUmFuZ2VFeGNlcHRpb24sIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIGF0dHJpYnV0ZXMgZGVzY3JpYmluZyB0aGUgZW5kIG9mIGEgUmFuZ2UuCi0gICAgICogQHBhcmFtIHJlZk5vZGUgVGhlIDxjb2RlPnJlZk5vZGU8L2NvZGU+IHZhbHVlLiBUaGlzIHBhcmFtZXRlciBtdXN0IGJlCi0gICAgICogICBkaWZmZXJlbnQgZnJvbSA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICAgKiBAcGFyYW0gb2Zmc2V0IFRoZSA8Y29kZT5lbmRPZmZzZXQ8L2NvZGU+IHZhbHVlLgotICAgICAqIEBleGNlcHRpb24gUmFuZ2VFeGNlcHRpb24KLSAgICAgKiAgIElOVkFMSURfTk9ERV9UWVBFX0VSUjogUmFpc2VkIGlmIDxjb2RlPnJlZk5vZGU8L2NvZGU+IG9yIGFuIGFuY2VzdG9yCi0gICAgICogICBvZiA8Y29kZT5yZWZOb2RlPC9jb2RlPiBpcyBhbiBFbnRpdHksIE5vdGF0aW9uLCBvciBEb2N1bWVudFR5cGUKLSAgICAgKiAgIG5vZGUuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIElOREVYX1NJWkVfRVJSOiBSYWlzZWQgaWYgPGNvZGU+b2Zmc2V0PC9jb2RlPiBpcyBuZWdhdGl2ZSBvciBncmVhdGVyCi0gICAgICogICB0aGFuIHRoZSBudW1iZXIgb2YgY2hpbGQgdW5pdHMgaW4gPGNvZGU+cmVmTm9kZTwvY29kZT4uIENoaWxkIHVuaXRzCi0gICAgICogICBhcmUgMTYtYml0IHVuaXRzIGlmIDxjb2RlPnJlZk5vZGU8L2NvZGU+IGlzIGEgdHlwZSBvZiBDaGFyYWN0ZXJEYXRhCi0gICAgICogICBub2RlIChlLmcuLCBhIFRleHQgb3IgQ29tbWVudCBub2RlKSBvciBhIFByb2Nlc3NpbmdJbnN0cnVjdGlvbgotICAgICAqICAgbm9kZS4gQ2hpbGQgdW5pdHMgYXJlIE5vZGVzIGluIGFsbCBvdGhlciBjYXNlcy4KLSAgICAgKiAgIDxicj5JTlZBTElEX1NUQVRFX0VSUjogUmFpc2VkIGlmIDxjb2RlPmRldGFjaCgpPC9jb2RlPiBoYXMgYWxyZWFkeQotICAgICAqICAgYmVlbiBpbnZva2VkIG9uIHRoaXMgb2JqZWN0LgotICAgICAqICAgPGJyPldST05HX0RPQ1VNRU5UX0VSUjogUmFpc2VkIGlmIDxjb2RlPnJlZk5vZGU8L2NvZGU+IHdhcyBjcmVhdGVkCi0gICAgICogICBmcm9tIGEgZGlmZmVyZW50IGRvY3VtZW50IHRoYW4gdGhlIG9uZSB0aGF0IGNyZWF0ZWQgdGhpcyByYW5nZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRFbmQoTm9kZSByZWZOb2RlLAotICAgICAgICAgICAgICAgICAgICAgICBpbnQgb2Zmc2V0KQotICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgUmFuZ2VFeGNlcHRpb24sIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIHN0YXJ0IHBvc2l0aW9uIHRvIGJlIGJlZm9yZSBhIG5vZGUKLSAgICAgKiBAcGFyYW0gcmVmTm9kZSBSYW5nZSBzdGFydHMgYmVmb3JlIDxjb2RlPnJlZk5vZGU8L2NvZGU+Ci0gICAgICogQGV4Y2VwdGlvbiBSYW5nZUV4Y2VwdGlvbgotICAgICAqICAgSU5WQUxJRF9OT0RFX1RZUEVfRVJSOiBSYWlzZWQgaWYgdGhlIHJvb3QgY29udGFpbmVyIG9mCi0gICAgICogICA8Y29kZT5yZWZOb2RlPC9jb2RlPiBpcyBub3QgYW4gQXR0ciwgRG9jdW1lbnQsIG9yIERvY3VtZW50RnJhZ21lbnQKLSAgICAgKiAgIG5vZGUgb3IgaWYgPGNvZGU+cmVmTm9kZTwvY29kZT4gaXMgYSBEb2N1bWVudCwgRG9jdW1lbnRGcmFnbWVudCwKLSAgICAgKiAgIEF0dHIsIEVudGl0eSwgb3IgTm90YXRpb24gbm9kZS4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgSU5WQUxJRF9TVEFURV9FUlI6IFJhaXNlZCBpZiA8Y29kZT5kZXRhY2goKTwvY29kZT4gaGFzIGFscmVhZHkgYmVlbgotICAgICAqICAgaW52b2tlZCBvbiB0aGlzIG9iamVjdC4KLSAgICAgKiAgIDxicj5XUk9OR19ET0NVTUVOVF9FUlI6IFJhaXNlZCBpZiA8Y29kZT5yZWZOb2RlPC9jb2RlPiB3YXMgY3JlYXRlZAotICAgICAqICAgZnJvbSBhIGRpZmZlcmVudCBkb2N1bWVudCB0aGFuIHRoZSBvbmUgdGhhdCBjcmVhdGVkIHRoaXMgcmFuZ2UuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0U3RhcnRCZWZvcmUoTm9kZSByZWZOb2RlKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBSYW5nZUV4Y2VwdGlvbiwgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogU2V0cyB0aGUgc3RhcnQgcG9zaXRpb24gdG8gYmUgYWZ0ZXIgYSBub2RlCi0gICAgICogQHBhcmFtIHJlZk5vZGUgUmFuZ2Ugc3RhcnRzIGFmdGVyIDxjb2RlPnJlZk5vZGU8L2NvZGU+Ci0gICAgICogQGV4Y2VwdGlvbiBSYW5nZUV4Y2VwdGlvbgotICAgICAqICAgSU5WQUxJRF9OT0RFX1RZUEVfRVJSOiBSYWlzZWQgaWYgdGhlIHJvb3QgY29udGFpbmVyIG9mCi0gICAgICogICA8Y29kZT5yZWZOb2RlPC9jb2RlPiBpcyBub3QgYW4gQXR0ciwgRG9jdW1lbnQsIG9yIERvY3VtZW50RnJhZ21lbnQKLSAgICAgKiAgIG5vZGUgb3IgaWYgPGNvZGU+cmVmTm9kZTwvY29kZT4gaXMgYSBEb2N1bWVudCwgRG9jdW1lbnRGcmFnbWVudCwKLSAgICAgKiAgIEF0dHIsIEVudGl0eSwgb3IgTm90YXRpb24gbm9kZS4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgSU5WQUxJRF9TVEFURV9FUlI6IFJhaXNlZCBpZiA8Y29kZT5kZXRhY2goKTwvY29kZT4gaGFzIGFscmVhZHkgYmVlbgotICAgICAqICAgaW52b2tlZCBvbiB0aGlzIG9iamVjdC4KLSAgICAgKiAgIDxicj5XUk9OR19ET0NVTUVOVF9FUlI6IFJhaXNlZCBpZiA8Y29kZT5yZWZOb2RlPC9jb2RlPiB3YXMgY3JlYXRlZAotICAgICAqICAgZnJvbSBhIGRpZmZlcmVudCBkb2N1bWVudCB0aGFuIHRoZSBvbmUgdGhhdCBjcmVhdGVkIHRoaXMgcmFuZ2UuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0U3RhcnRBZnRlcihOb2RlIHJlZk5vZGUpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgUmFuZ2VFeGNlcHRpb24sIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIGVuZCBwb3NpdGlvbiB0byBiZSBiZWZvcmUgYSBub2RlLgotICAgICAqIEBwYXJhbSByZWZOb2RlIFJhbmdlIGVuZHMgYmVmb3JlIDxjb2RlPnJlZk5vZGU8L2NvZGU+Ci0gICAgICogQGV4Y2VwdGlvbiBSYW5nZUV4Y2VwdGlvbgotICAgICAqICAgSU5WQUxJRF9OT0RFX1RZUEVfRVJSOiBSYWlzZWQgaWYgdGhlIHJvb3QgY29udGFpbmVyIG9mCi0gICAgICogICA8Y29kZT5yZWZOb2RlPC9jb2RlPiBpcyBub3QgYW4gQXR0ciwgRG9jdW1lbnQsIG9yIERvY3VtZW50RnJhZ21lbnQKLSAgICAgKiAgIG5vZGUgb3IgaWYgPGNvZGU+cmVmTm9kZTwvY29kZT4gaXMgYSBEb2N1bWVudCwgRG9jdW1lbnRGcmFnbWVudCwKLSAgICAgKiAgIEF0dHIsIEVudGl0eSwgb3IgTm90YXRpb24gbm9kZS4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgSU5WQUxJRF9TVEFURV9FUlI6IFJhaXNlZCBpZiA8Y29kZT5kZXRhY2goKTwvY29kZT4gaGFzIGFscmVhZHkgYmVlbgotICAgICAqICAgaW52b2tlZCBvbiB0aGlzIG9iamVjdC4KLSAgICAgKiAgIDxicj5XUk9OR19ET0NVTUVOVF9FUlI6IFJhaXNlZCBpZiA8Y29kZT5yZWZOb2RlPC9jb2RlPiB3YXMgY3JlYXRlZAotICAgICAqICAgZnJvbSBhIGRpZmZlcmVudCBkb2N1bWVudCB0aGFuIHRoZSBvbmUgdGhhdCBjcmVhdGVkIHRoaXMgcmFuZ2UuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RW5kQmVmb3JlKE5vZGUgcmVmTm9kZSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIFJhbmdlRXhjZXB0aW9uLCBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSBlbmQgb2YgYSBSYW5nZSB0byBiZSBhZnRlciBhIG5vZGUKLSAgICAgKiBAcGFyYW0gcmVmTm9kZSBSYW5nZSBlbmRzIGFmdGVyIDxjb2RlPnJlZk5vZGU8L2NvZGU+LgotICAgICAqIEBleGNlcHRpb24gUmFuZ2VFeGNlcHRpb24KLSAgICAgKiAgIElOVkFMSURfTk9ERV9UWVBFX0VSUjogUmFpc2VkIGlmIHRoZSByb290IGNvbnRhaW5lciBvZgotICAgICAqICAgPGNvZGU+cmVmTm9kZTwvY29kZT4gaXMgbm90IGFuIEF0dHIsIERvY3VtZW50IG9yIERvY3VtZW50RnJhZ21lbnQKLSAgICAgKiAgIG5vZGUgb3IgaWYgPGNvZGU+cmVmTm9kZTwvY29kZT4gaXMgYSBEb2N1bWVudCwgRG9jdW1lbnRGcmFnbWVudCwKLSAgICAgKiAgIEF0dHIsIEVudGl0eSwgb3IgTm90YXRpb24gbm9kZS4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgSU5WQUxJRF9TVEFURV9FUlI6IFJhaXNlZCBpZiA8Y29kZT5kZXRhY2goKTwvY29kZT4gaGFzIGFscmVhZHkgYmVlbgotICAgICAqICAgaW52b2tlZCBvbiB0aGlzIG9iamVjdC4KLSAgICAgKiAgIDxicj5XUk9OR19ET0NVTUVOVF9FUlI6IFJhaXNlZCBpZiA8Y29kZT5yZWZOb2RlPC9jb2RlPiB3YXMgY3JlYXRlZAotICAgICAqICAgZnJvbSBhIGRpZmZlcmVudCBkb2N1bWVudCB0aGFuIHRoZSBvbmUgdGhhdCBjcmVhdGVkIHRoaXMgcmFuZ2UuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RW5kQWZ0ZXIoTm9kZSByZWZOb2RlKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBSYW5nZUV4Y2VwdGlvbiwgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogQ29sbGFwc2UgYSBSYW5nZSBvbnRvIG9uZSBvZiBpdHMgYm91bmRhcnktcG9pbnRzCi0gICAgICogQHBhcmFtIHRvU3RhcnQgSWYgVFJVRSwgY29sbGFwc2VzIHRoZSBSYW5nZSBvbnRvIGl0cyBzdGFydDsgaWYgRkFMU0UsCi0gICAgICogICBjb2xsYXBzZXMgaXQgb250byBpdHMgZW5kLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBJTlZBTElEX1NUQVRFX0VSUjogUmFpc2VkIGlmIDxjb2RlPmRldGFjaCgpPC9jb2RlPiBoYXMgYWxyZWFkeSBiZWVuCi0gICAgICogICBpbnZva2VkIG9uIHRoaXMgb2JqZWN0LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGNvbGxhcHNlKGJvb2xlYW4gdG9TdGFydCkKLSAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogU2VsZWN0IGEgbm9kZSBhbmQgaXRzIGNvbnRlbnRzCi0gICAgICogQHBhcmFtIHJlZk5vZGUgVGhlIG5vZGUgdG8gc2VsZWN0LgotICAgICAqIEBleGNlcHRpb24gUmFuZ2VFeGNlcHRpb24KLSAgICAgKiAgIElOVkFMSURfTk9ERV9UWVBFX0VSUjogUmFpc2VkIGlmIGFuIGFuY2VzdG9yIG9mIDxjb2RlPnJlZk5vZGU8L2NvZGU+Ci0gICAgICogICBpcyBhbiBFbnRpdHksIE5vdGF0aW9uIG9yIERvY3VtZW50VHlwZSBub2RlIG9yIGlmCi0gICAgICogICA8Y29kZT5yZWZOb2RlPC9jb2RlPiBpcyBhIERvY3VtZW50LCBEb2N1bWVudEZyYWdtZW50LCBBdHRyLCBFbnRpdHksCi0gICAgICogICBvciBOb3RhdGlvbiBub2RlLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBJTlZBTElEX1NUQVRFX0VSUjogUmFpc2VkIGlmIDxjb2RlPmRldGFjaCgpPC9jb2RlPiBoYXMgYWxyZWFkeSBiZWVuCi0gICAgICogICBpbnZva2VkIG9uIHRoaXMgb2JqZWN0LgotICAgICAqICAgPGJyPldST05HX0RPQ1VNRU5UX0VSUjogUmFpc2VkIGlmIDxjb2RlPnJlZk5vZGU8L2NvZGU+IHdhcyBjcmVhdGVkCi0gICAgICogICBmcm9tIGEgZGlmZmVyZW50IGRvY3VtZW50IHRoYW4gdGhlIG9uZSB0aGF0IGNyZWF0ZWQgdGhpcyByYW5nZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZWxlY3ROb2RlKE5vZGUgcmVmTm9kZSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBSYW5nZUV4Y2VwdGlvbiwgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogU2VsZWN0IHRoZSBjb250ZW50cyB3aXRoaW4gYSBub2RlCi0gICAgICogQHBhcmFtIHJlZk5vZGUgTm9kZSB0byBzZWxlY3QgZnJvbQotICAgICAqIEBleGNlcHRpb24gUmFuZ2VFeGNlcHRpb24KLSAgICAgKiAgIElOVkFMSURfTk9ERV9UWVBFX0VSUjogUmFpc2VkIGlmIDxjb2RlPnJlZk5vZGU8L2NvZGU+IG9yIGFuIGFuY2VzdG9yCi0gICAgICogICBvZiA8Y29kZT5yZWZOb2RlPC9jb2RlPiBpcyBhbiBFbnRpdHksIE5vdGF0aW9uIG9yIERvY3VtZW50VHlwZSBub2RlLgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBJTlZBTElEX1NUQVRFX0VSUjogUmFpc2VkIGlmIDxjb2RlPmRldGFjaCgpPC9jb2RlPiBoYXMgYWxyZWFkeSBiZWVuCi0gICAgICogICBpbnZva2VkIG9uIHRoaXMgb2JqZWN0LgotICAgICAqICAgPGJyPldST05HX0RPQ1VNRU5UX0VSUjogUmFpc2VkIGlmIDxjb2RlPnJlZk5vZGU8L2NvZGU+IHdhcyBjcmVhdGVkCi0gICAgICogICBmcm9tIGEgZGlmZmVyZW50IGRvY3VtZW50IHRoYW4gdGhlIG9uZSB0aGF0IGNyZWF0ZWQgdGhpcyByYW5nZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZWxlY3ROb2RlQ29udGVudHMoTm9kZSByZWZOb2RlKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgUmFuZ2VFeGNlcHRpb24sIERPTUV4Y2VwdGlvbjsKLQotICAgIC8vIENvbXBhcmVIb3cKLSAgICAvKioKLSAgICAgKiBDb21wYXJlIHN0YXJ0IGJvdW5kYXJ5LXBvaW50IG9mIDxjb2RlPnNvdXJjZVJhbmdlPC9jb2RlPiB0byBzdGFydAotICAgICAqIGJvdW5kYXJ5LXBvaW50IG9mIFJhbmdlIG9uIHdoaWNoIDxjb2RlPmNvbXBhcmVCb3VuZGFyeVBvaW50czwvY29kZT4KLSAgICAgKiBpcyBpbnZva2VkLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgU1RBUlRfVE9fU1RBUlQgICAgICAgICAgICA9IDA7Ci0gICAgLyoqCi0gICAgICogQ29tcGFyZSBzdGFydCBib3VuZGFyeS1wb2ludCBvZiA8Y29kZT5zb3VyY2VSYW5nZTwvY29kZT4gdG8gZW5kCi0gICAgICogYm91bmRhcnktcG9pbnQgb2YgUmFuZ2Ugb24gd2hpY2ggPGNvZGU+Y29tcGFyZUJvdW5kYXJ5UG9pbnRzPC9jb2RlPgotICAgICAqIGlzIGludm9rZWQuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBTVEFSVF9UT19FTkQgICAgICAgICAgICAgID0gMTsKLSAgICAvKioKLSAgICAgKiBDb21wYXJlIGVuZCBib3VuZGFyeS1wb2ludCBvZiA8Y29kZT5zb3VyY2VSYW5nZTwvY29kZT4gdG8gZW5kCi0gICAgICogYm91bmRhcnktcG9pbnQgb2YgUmFuZ2Ugb24gd2hpY2ggPGNvZGU+Y29tcGFyZUJvdW5kYXJ5UG9pbnRzPC9jb2RlPgotICAgICAqIGlzIGludm9rZWQuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBFTkRfVE9fRU5EICAgICAgICAgICAgICAgID0gMjsKLSAgICAvKioKLSAgICAgKiBDb21wYXJlIGVuZCBib3VuZGFyeS1wb2ludCBvZiA8Y29kZT5zb3VyY2VSYW5nZTwvY29kZT4gdG8gc3RhcnQKLSAgICAgKiBib3VuZGFyeS1wb2ludCBvZiBSYW5nZSBvbiB3aGljaCA8Y29kZT5jb21wYXJlQm91bmRhcnlQb2ludHM8L2NvZGU+Ci0gICAgICogaXMgaW52b2tlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IEVORF9UT19TVEFSVCAgICAgICAgICAgICAgPSAzOwotCi0gICAgLyoqCi0gICAgICogQ29tcGFyZSB0aGUgYm91bmRhcnktcG9pbnRzIG9mIHR3byBSYW5nZXMgaW4gYSBkb2N1bWVudC4KLSAgICAgKiBAcGFyYW0gaG93IEEgY29kZSByZXByZXNlbnRpbmcgdGhlIHR5cGUgb2YgY29tcGFyaXNvbiwgYXMgZGVmaW5lZAotICAgICAqICAgYWJvdmUuCi0gICAgICogQHBhcmFtIHNvdXJjZVJhbmdlIFRoZSA8Y29kZT5SYW5nZTwvY29kZT4gb24gd2hpY2ggdGhpcyBjdXJyZW50Ci0gICAgICogICA8Y29kZT5SYW5nZTwvY29kZT4gaXMgY29tcGFyZWQgdG8uCi0gICAgICogQHJldHVybiAgLTEsIDAgb3IgMSBkZXBlbmRpbmcgb24gd2hldGhlciB0aGUgY29ycmVzcG9uZGluZwotICAgICAqICAgYm91bmRhcnktcG9pbnQgb2YgdGhlIFJhbmdlIGlzIHJlc3BlY3RpdmVseSBiZWZvcmUsIGVxdWFsIHRvLCBvcgotICAgICAqICAgYWZ0ZXIgdGhlIGNvcnJlc3BvbmRpbmcgYm91bmRhcnktcG9pbnQgb2YgPGNvZGU+c291cmNlUmFuZ2U8L2NvZGU+LgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBXUk9OR19ET0NVTUVOVF9FUlI6IFJhaXNlZCBpZiB0aGUgdHdvIFJhbmdlcyBhcmUgbm90IGluIHRoZSBzYW1lCi0gICAgICogICBEb2N1bWVudCBvciBEb2N1bWVudEZyYWdtZW50LgotICAgICAqICAgPGJyPklOVkFMSURfU1RBVEVfRVJSOiBSYWlzZWQgaWYgPGNvZGU+ZGV0YWNoKCk8L2NvZGU+IGhhcyBhbHJlYWR5Ci0gICAgICogICBiZWVuIGludm9rZWQgb24gdGhpcyBvYmplY3QuCi0gICAgICovCi0gICAgcHVibGljIHNob3J0IGNvbXBhcmVCb3VuZGFyeVBvaW50cyhzaG9ydCBob3csCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSYW5nZSBzb3VyY2VSYW5nZSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBSZW1vdmVzIHRoZSBjb250ZW50cyBvZiBhIFJhbmdlIGZyb20gdGhlIGNvbnRhaW5pbmcgZG9jdW1lbnQgb3IKLSAgICAgKiBkb2N1bWVudCBmcmFnbWVudCB3aXRob3V0IHJldHVybmluZyBhIHJlZmVyZW5jZSB0byB0aGUgcmVtb3ZlZAotICAgICAqIGNvbnRlbnQuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIGFueSBwb3J0aW9uIG9mIHRoZSBjb250ZW50IG9mCi0gICAgICogICB0aGUgUmFuZ2UgaXMgcmVhZC1vbmx5IG9yIGFueSBvZiB0aGUgbm9kZXMgdGhhdCBjb250YWluIGFueSBvZiB0aGUKLSAgICAgKiAgIGNvbnRlbnQgb2YgdGhlIFJhbmdlIGFyZSByZWFkLW9ubHkuCi0gICAgICogICA8YnI+SU5WQUxJRF9TVEFURV9FUlI6IFJhaXNlZCBpZiA8Y29kZT5kZXRhY2goKTwvY29kZT4gaGFzIGFscmVhZHkKLSAgICAgKiAgIGJlZW4gaW52b2tlZCBvbiB0aGlzIG9iamVjdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBkZWxldGVDb250ZW50cygpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIE1vdmVzIHRoZSBjb250ZW50cyBvZiBhIFJhbmdlIGZyb20gdGhlIGNvbnRhaW5pbmcgZG9jdW1lbnQgb3IgZG9jdW1lbnQKLSAgICAgKiBmcmFnbWVudCB0byBhIG5ldyBEb2N1bWVudEZyYWdtZW50LgotICAgICAqIEByZXR1cm4gQSBEb2N1bWVudEZyYWdtZW50IGNvbnRhaW5pbmcgdGhlIGV4dHJhY3RlZCBjb250ZW50cy4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgYW55IHBvcnRpb24gb2YgdGhlIGNvbnRlbnQgb2YKLSAgICAgKiAgIHRoZSBSYW5nZSBpcyByZWFkLW9ubHkgb3IgYW55IG9mIHRoZSBub2RlcyB3aGljaCBjb250YWluIGFueSBvZiB0aGUKLSAgICAgKiAgIGNvbnRlbnQgb2YgdGhlIFJhbmdlIGFyZSByZWFkLW9ubHkuCi0gICAgICogICA8YnI+SElFUkFSQ0hZX1JFUVVFU1RfRVJSOiBSYWlzZWQgaWYgYSBEb2N1bWVudFR5cGUgbm9kZSB3b3VsZCBiZQotICAgICAqICAgZXh0cmFjdGVkIGludG8gdGhlIG5ldyBEb2N1bWVudEZyYWdtZW50LgotICAgICAqICAgPGJyPklOVkFMSURfU1RBVEVfRVJSOiBSYWlzZWQgaWYgPGNvZGU+ZGV0YWNoKCk8L2NvZGU+IGhhcyBhbHJlYWR5Ci0gICAgICogICBiZWVuIGludm9rZWQgb24gdGhpcyBvYmplY3QuCi0gICAgICovCi0gICAgcHVibGljIERvY3VtZW50RnJhZ21lbnQgZXh0cmFjdENvbnRlbnRzKCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIER1cGxpY2F0ZXMgdGhlIGNvbnRlbnRzIG9mIGEgUmFuZ2UKLSAgICAgKiBAcmV0dXJuIEEgRG9jdW1lbnRGcmFnbWVudCB0aGF0IGNvbnRhaW5zIGNvbnRlbnQgZXF1aXZhbGVudCB0byB0aGlzCi0gICAgICogICBSYW5nZS4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgSElFUkFSQ0hZX1JFUVVFU1RfRVJSOiBSYWlzZWQgaWYgYSBEb2N1bWVudFR5cGUgbm9kZSB3b3VsZCBiZQotICAgICAqICAgZXh0cmFjdGVkIGludG8gdGhlIG5ldyBEb2N1bWVudEZyYWdtZW50LgotICAgICAqICAgPGJyPklOVkFMSURfU1RBVEVfRVJSOiBSYWlzZWQgaWYgPGNvZGU+ZGV0YWNoKCk8L2NvZGU+IGhhcyBhbHJlYWR5Ci0gICAgICogICBiZWVuIGludm9rZWQgb24gdGhpcyBvYmplY3QuCi0gICAgICovCi0gICAgcHVibGljIERvY3VtZW50RnJhZ21lbnQgY2xvbmVDb250ZW50cygpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogSW5zZXJ0cyBhIG5vZGUgaW50byB0aGUgRG9jdW1lbnQgb3IgRG9jdW1lbnRGcmFnbWVudCBhdCB0aGUgc3RhcnQgb2YKLSAgICAgKiB0aGUgUmFuZ2UuIElmIHRoZSBjb250YWluZXIgaXMgYSBUZXh0IG5vZGUsIHRoaXMgd2lsbCBiZSBzcGxpdCBhdCB0aGUKLSAgICAgKiBzdGFydCBvZiB0aGUgUmFuZ2UgKGFzIGlmIHRoZSBUZXh0IG5vZGUncyBzcGxpdFRleHQgbWV0aG9kIHdhcwotICAgICAqIHBlcmZvcm1lZCBhdCB0aGUgaW5zZXJ0aW9uIHBvaW50KSBhbmQgdGhlIGluc2VydGlvbiB3aWxsIG9jY3VyCi0gICAgICogYmV0d2VlbiB0aGUgdHdvIHJlc3VsdGluZyBUZXh0IG5vZGVzLiBBZGphY2VudCBUZXh0IG5vZGVzIHdpbGwgbm90IGJlCi0gICAgICogYXV0b21hdGljYWxseSBtZXJnZWQuIElmIHRoZSBub2RlIHRvIGJlIGluc2VydGVkIGlzIGEKLSAgICAgKiBEb2N1bWVudEZyYWdtZW50IG5vZGUsIHRoZSBjaGlsZHJlbiB3aWxsIGJlIGluc2VydGVkIHJhdGhlciB0aGFuIHRoZQotICAgICAqIERvY3VtZW50RnJhZ21lbnQgbm9kZSBpdHNlbGYuCi0gICAgICogQHBhcmFtIG5ld05vZGUgVGhlIG5vZGUgdG8gaW5zZXJ0IGF0IHRoZSBzdGFydCBvZiB0aGUgUmFuZ2UKLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgYW4gYW5jZXN0b3IgY29udGFpbmVyIG9mIHRoZQotICAgICAqICAgc3RhcnQgb2YgdGhlIFJhbmdlIGlzIHJlYWQtb25seS4KLSAgICAgKiAgIDxicj5XUk9OR19ET0NVTUVOVF9FUlI6IFJhaXNlZCBpZiA8Y29kZT5uZXdOb2RlPC9jb2RlPiBhbmQgdGhlCi0gICAgICogICBjb250YWluZXIgb2YgdGhlIHN0YXJ0IG9mIHRoZSBSYW5nZSB3ZXJlIG5vdCBjcmVhdGVkIGZyb20gdGhlIHNhbWUKLSAgICAgKiAgIGRvY3VtZW50LgotICAgICAqICAgPGJyPkhJRVJBUkNIWV9SRVFVRVNUX0VSUjogUmFpc2VkIGlmIHRoZSBjb250YWluZXIgb2YgdGhlIHN0YXJ0IG9mCi0gICAgICogICB0aGUgUmFuZ2UgaXMgb2YgYSB0eXBlIHRoYXQgZG9lcyBub3QgYWxsb3cgY2hpbGRyZW4gb2YgdGhlIHR5cGUgb2YKLSAgICAgKiAgIDxjb2RlPm5ld05vZGU8L2NvZGU+IG9yIGlmIDxjb2RlPm5ld05vZGU8L2NvZGU+IGlzIGFuIGFuY2VzdG9yIG9mCi0gICAgICogICB0aGUgY29udGFpbmVyLgotICAgICAqICAgPGJyPklOVkFMSURfU1RBVEVfRVJSOiBSYWlzZWQgaWYgPGNvZGU+ZGV0YWNoKCk8L2NvZGU+IGhhcyBhbHJlYWR5Ci0gICAgICogICBiZWVuIGludm9rZWQgb24gdGhpcyBvYmplY3QuCi0gICAgICogQGV4Y2VwdGlvbiBSYW5nZUV4Y2VwdGlvbgotICAgICAqICAgSU5WQUxJRF9OT0RFX1RZUEVfRVJSOiBSYWlzZWQgaWYgPGNvZGU+bmV3Tm9kZTwvY29kZT4gaXMgYW4gQXR0ciwKLSAgICAgKiAgIEVudGl0eSwgTm90YXRpb24sIG9yIERvY3VtZW50IG5vZGUuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgaW5zZXJ0Tm9kZShOb2RlIG5ld05vZGUpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uLCBSYW5nZUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIFJlcGFyZW50cyB0aGUgY29udGVudHMgb2YgdGhlIFJhbmdlIHRvIHRoZSBnaXZlbiBub2RlIGFuZCBpbnNlcnRzIHRoZQotICAgICAqIG5vZGUgYXQgdGhlIHBvc2l0aW9uIG9mIHRoZSBzdGFydCBvZiB0aGUgUmFuZ2UuCi0gICAgICogQHBhcmFtIG5ld1BhcmVudCBUaGUgbm9kZSB0byBzdXJyb3VuZCB0aGUgY29udGVudHMgd2l0aC4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgYW4gYW5jZXN0b3IgY29udGFpbmVyIG9mCi0gICAgICogICBlaXRoZXIgYm91bmRhcnktcG9pbnQgb2YgdGhlIFJhbmdlIGlzIHJlYWQtb25seS4KLSAgICAgKiAgIDxicj5XUk9OR19ET0NVTUVOVF9FUlI6IFJhaXNlZCBpZiA8Y29kZT4gbmV3UGFyZW50PC9jb2RlPiBhbmQgdGhlCi0gICAgICogICBjb250YWluZXIgb2YgdGhlIHN0YXJ0IG9mIHRoZSBSYW5nZSB3ZXJlIG5vdCBjcmVhdGVkIGZyb20gdGhlIHNhbWUKLSAgICAgKiAgIGRvY3VtZW50LgotICAgICAqICAgPGJyPkhJRVJBUkNIWV9SRVFVRVNUX0VSUjogUmFpc2VkIGlmIHRoZSBjb250YWluZXIgb2YgdGhlIHN0YXJ0IG9mCi0gICAgICogICB0aGUgUmFuZ2UgaXMgb2YgYSB0eXBlIHRoYXQgZG9lcyBub3QgYWxsb3cgY2hpbGRyZW4gb2YgdGhlIHR5cGUgb2YKLSAgICAgKiAgIDxjb2RlPm5ld1BhcmVudDwvY29kZT4gb3IgaWYgPGNvZGU+bmV3UGFyZW50PC9jb2RlPiBpcyBhbiBhbmNlc3RvcgotICAgICAqICAgb2YgdGhlIGNvbnRhaW5lciBvciBpZiA8Y29kZT5ub2RlPC9jb2RlPiB3b3VsZCBlbmQgdXAgd2l0aCBhIGNoaWxkCi0gICAgICogICBub2RlIG9mIGEgdHlwZSBub3QgYWxsb3dlZCBieSB0aGUgdHlwZSBvZiA8Y29kZT5ub2RlPC9jb2RlPi4KLSAgICAgKiAgIDxicj5JTlZBTElEX1NUQVRFX0VSUjogUmFpc2VkIGlmIDxjb2RlPmRldGFjaCgpPC9jb2RlPiBoYXMgYWxyZWFkeQotICAgICAqICAgYmVlbiBpbnZva2VkIG9uIHRoaXMgb2JqZWN0LgotICAgICAqIEBleGNlcHRpb24gUmFuZ2VFeGNlcHRpb24KLSAgICAgKiAgIEJBRF9CT1VOREFSWVBPSU5UU19FUlI6IFJhaXNlZCBpZiB0aGUgUmFuZ2UgcGFydGlhbGx5IHNlbGVjdHMgYQotICAgICAqICAgbm9uLXRleHQgbm9kZS4KLSAgICAgKiAgIDxicj5JTlZBTElEX05PREVfVFlQRV9FUlI6IFJhaXNlZCBpZiA8Y29kZT4gbm9kZTwvY29kZT4gaXMgYW4gQXR0ciwKLSAgICAgKiAgIEVudGl0eSwgRG9jdW1lbnRUeXBlLCBOb3RhdGlvbiwgRG9jdW1lbnQsIG9yIERvY3VtZW50RnJhZ21lbnQgbm9kZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdXJyb3VuZENvbnRlbnRzKE5vZGUgbmV3UGFyZW50KQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbiwgUmFuZ2VFeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBQcm9kdWNlcyBhIG5ldyBSYW5nZSB3aG9zZSBib3VuZGFyeS1wb2ludHMgYXJlIGVxdWFsIHRvIHRoZQotICAgICAqIGJvdW5kYXJ5LXBvaW50cyBvZiB0aGUgUmFuZ2UuCi0gICAgICogQHJldHVybiBUaGUgZHVwbGljYXRlZCBSYW5nZS4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgSU5WQUxJRF9TVEFURV9FUlI6IFJhaXNlZCBpZiA8Y29kZT5kZXRhY2goKTwvY29kZT4gaGFzIGFscmVhZHkgYmVlbgotICAgICAqICAgaW52b2tlZCBvbiB0aGlzIG9iamVjdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgUmFuZ2UgY2xvbmVSYW5nZSgpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIGNvbnRlbnRzIG9mIGEgUmFuZ2UgYXMgYSBzdHJpbmcuIFRoaXMgc3RyaW5nIGNvbnRhaW5zIG9ubHkKLSAgICAgKiB0aGUgZGF0YSBjaGFyYWN0ZXJzLCBub3QgYW55IG1hcmt1cC4KLSAgICAgKiBAcmV0dXJuIFRoZSBjb250ZW50cyBvZiB0aGUgUmFuZ2UuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIElOVkFMSURfU1RBVEVfRVJSOiBSYWlzZWQgaWYgPGNvZGU+ZGV0YWNoKCk8L2NvZGU+IGhhcyBhbHJlYWR5IGJlZW4KLSAgICAgKiAgIGludm9rZWQgb24gdGhpcyBvYmplY3QuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogQ2FsbGVkIHRvIGluZGljYXRlIHRoYXQgdGhlIFJhbmdlIGlzIG5vIGxvbmdlciBpbiB1c2UgYW5kIHRoYXQgdGhlCi0gICAgICogaW1wbGVtZW50YXRpb24gbWF5IHJlbGlucXVpc2ggYW55IHJlc291cmNlcyBhc3NvY2lhdGVkIHdpdGggdGhpcwotICAgICAqIFJhbmdlLiBTdWJzZXF1ZW50IGNhbGxzIHRvIGFueSBtZXRob2RzIG9yIGF0dHJpYnV0ZSBnZXR0ZXJzIG9uIHRoaXMKLSAgICAgKiBSYW5nZSB3aWxsIHJlc3VsdCBpbiBhIDxjb2RlPkRPTUV4Y2VwdGlvbjwvY29kZT4gYmVpbmcgdGhyb3duIHdpdGggYW4KLSAgICAgKiBlcnJvciBjb2RlIG9mIDxjb2RlPklOVkFMSURfU1RBVEVfRVJSPC9jb2RlPi4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgSU5WQUxJRF9TVEFURV9FUlI6IFJhaXNlZCBpZiA8Y29kZT5kZXRhY2goKTwvY29kZT4gaGFzIGFscmVhZHkgYmVlbgotICAgICAqICAgaW52b2tlZCBvbiB0aGlzIG9iamVjdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBkZXRhY2goKQotICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL3czYy9kb20vcmFuZ2VzL1JhbmdlRXhjZXB0aW9uLmphdmEgYi9zcmMvb3JnL3czYy9kb20vcmFuZ2VzL1JhbmdlRXhjZXB0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDE5OGExMzUuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy93M2MvZG9tL3Jhbmdlcy9SYW5nZUV4Y2VwdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNjggKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIFRoaXMgZmlsZSBpcyBhdmFpbGFibGUgdW5kZXIgYW5kIGdvdmVybmVkIGJ5IHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKLSAqIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICogSG93ZXZlciwgdGhlIGZvbGxvd2luZyBub3RpY2UgYWNjb21wYW5pZWQgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcwotICogZmlsZSBhbmQsIHBlciBpdHMgdGVybXMsIHNob3VsZCBub3QgYmUgcmVtb3ZlZDoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDAgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKLSAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQotICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCi0gKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKLSAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCi0gKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCi0gKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCi0gKiBQVVJQT1NFLgotICogU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCi0gKi8KLQotcGFja2FnZSBvcmcudzNjLmRvbS5yYW5nZXM7Ci0KLS8qKgotICogUmFuZ2Ugb3BlcmF0aW9ucyBtYXkgdGhyb3cgYSA8Y29kZT5SYW5nZUV4Y2VwdGlvbjwvY29kZT4gYXMgc3BlY2lmaWVkIGluCi0gKiB0aGVpciBtZXRob2QgZGVzY3JpcHRpb25zLgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDAvUkVDLURPTS1MZXZlbC0yLVRyYXZlcnNhbC1SYW5nZS0yMDAwMTExMyc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDIgVHJhdmVyc2FsIGFuZCBSYW5nZSBTcGVjaWZpY2F0aW9uPC9hPi4KLSAqIEBzaW5jZSBET00gTGV2ZWwgMgotICovCi1wdWJsaWMgY2xhc3MgUmFuZ2VFeGNlcHRpb24gZXh0ZW5kcyBSdW50aW1lRXhjZXB0aW9uIHsKLSAgICBwdWJsaWMgUmFuZ2VFeGNlcHRpb24oc2hvcnQgY29kZSwgU3RyaW5nIG1lc3NhZ2UpIHsKLSAgICAgICBzdXBlcihtZXNzYWdlKTsKLSAgICAgICB0aGlzLmNvZGUgPSBjb2RlOwotICAgIH0KLSAgICBwdWJsaWMgc2hvcnQgICBjb2RlOwotICAgIC8vIFJhbmdlRXhjZXB0aW9uQ29kZQotICAgIC8qKgotICAgICAqIElmIHRoZSBib3VuZGFyeS1wb2ludHMgb2YgYSBSYW5nZSBkbyBub3QgbWVldCBzcGVjaWZpYyByZXF1aXJlbWVudHMuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBCQURfQk9VTkRBUllQT0lOVFNfRVJSICAgID0gMTsKLSAgICAvKioKLSAgICAgKiBJZiB0aGUgY29udGFpbmVyIG9mIGFuIGJvdW5kYXJ5LXBvaW50IG9mIGEgUmFuZ2UgaXMgYmVpbmcgc2V0IHRvIGVpdGhlcgotICAgICAqIGEgbm9kZSBvZiBhbiBpbnZhbGlkIHR5cGUgb3IgYSBub2RlIHdpdGggYW4gYW5jZXN0b3Igb2YgYW4gaW52YWxpZAotICAgICAqIHR5cGUuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBJTlZBTElEX05PREVfVFlQRV9FUlIgICAgID0gMjsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy93M2MvZG9tL3Jhbmdlcy9wYWNrYWdlLmh0bWwgYi9zcmMvb3JnL3czYy9kb20vcmFuZ2VzL3BhY2thZ2UuaHRtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDEyMzE1Yi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3czYy9kb20vcmFuZ2VzL3BhY2thZ2UuaHRtbAorKysgL2Rldi9udWxsCkBAIC0xLDExMSArMCwwIEBACi08aHRtbD4KLTxoZWFkPgotICAgIDx0aXRsZT5XM0MgSVBSIFNPRlRXQVJFIE5PVElDRTwvdGl0bGU+Ci08L2hlYWQ+Ci08Ym9keSBiZ2NvbG9yPSJ3aGl0ZSI+Ci0gICAgPHA+Ci0gICAgICBEb2N1bWVudCBPYmplY3QgTW9kZWwgTGV2ZWwgMiBUcmF2ZXJzYWwgYW5kIFJhbmdlIGlzIGEgCi0gICAgICBwbGF0Zm9ybSBhbmQgbGFuZ3VhZ2UtbmV1dHJhbCBpbnRlcmZhY2VzIHRoYXQgYWxsb3cgcHJvZ3JhbXMgCi0gICAgICBhbmQgc2NyaXB0cyB0byBkeW5hbWljYWxseSB0cmF2ZXJzZSBhbmQgaWRlbnRpZnkgYSByYW5nZSBvZgotICAgICAgY29udGVudCBpbiBhIGRvY3VtZW50LiBUaGUgRG9jdW1lbnQgT2JqZWN0IE1vZGVsIExldmVsIDIgCi0gICAgICBUcmF2ZXJzYWwgYW5kIFJhbmdlIGJ1aWxkIG9uIHRoZSBEb2N1bWVudCBPYmplY3QgTW9kZWwgTGV2ZWwgMgotICAgICAgQ29yZS4KLSAgICA8L3A+Ci0gICAgPHA+Ci0gICAgICBUaGUgRE9NIExldmVsIDIgVHJhdmVyc2FsIGFuZCBSYW5nZSBzcGVjaWZpY2F0aW9uIGlzIGNvbXBvc2VkCi0gICAgICBvZiB0d28gbW9kdWxlcy4gVGhlIHR3byBtb2R1bGVzIGNvbnRhaW4gc3BlY2lhbGl6ZWQgaW50ZXJmYWNlcyAKLSAgICAgIGRlZGljYXRlZCB0byB0cmF2ZXJzaW5nIHRoZSBkb2N1bWVudCBzdHJ1Y3R1cmUgYW5kIGlkZW50aWZ5aW5nIAotICAgICAgYW5kIG1hbmlwdWxhdGluZyBhIHJhbmdlIGluIGEgZG9jdW1lbnQuCi0gICAgPC9wPgotICAgIDxoMT4KLSAgICAgIFczQyBJUFIgU09GVFdBUkUgTk9USUNFCi0gICAgPC9oMT4KLSAgICA8aDM+Ci0gICAgICBDb3B5cmlnaHQgJmNvcHk7IDIwMDAgPGxvYyBocmVmPSJodHRwOi8vd3d3LnczLm9yZy8iPldvcmxkIFdpZGUgV2ViCi0gICAgICBDb25zb3J0aXVtPC9sb2M+LCAoPGxvYyBocmVmPSJodHRwOi8vd3d3Lmxjcy5taXQuZWR1LyI+TWFzc2FjaHVzZXR0cwotICAgICAgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3k8L2xvYz4sIDxsb2MgaHJlZj0iaHR0cDovL3d3dy5pbnJpYS5mci8iPkluc3RpdHV0Ci0gICAgICBOYXRpb25hbCBkZSBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlPC9sb2M+LCA8bG9jCi0gICAgICBocmVmPSJodHRwOi8vd3d3LmtlaW8uYWMuanAvIj5LZWlvIFVuaXZlcnNpdHk8L2xvYz4pLiBBbGwgUmlnaHRzCi0gICAgICBSZXNlcnZlZC4KLSAgICA8L2gzPgotICAgIDxwPgotICAgICAgVGhlIERPTSBiaW5kaW5ncyBhcmUgcHVibGlzaGVkIHVuZGVyIHRoZSBXM0MgU29mdHdhcmUgQ29weXJpZ2h0IE5vdGljZQotICAgICAgYW5kIExpY2Vuc2UuIFRoZSBzb2Z0d2FyZSBsaWNlbnNlIHJlcXVpcmVzICJOb3RpY2Ugb2YgYW55IGNoYW5nZXMgb3IKLSAgICAgIG1vZGlmaWNhdGlvbnMgdG8gdGhlIFczQyBmaWxlcywgaW5jbHVkaW5nIHRoZSBkYXRlIGNoYW5nZXMgd2VyZSBtYWRlLiIKLSAgICAgIENvbnNlcXVlbnRseSwgbW9kaWZpZWQgdmVyc2lvbnMgb2YgdGhlIERPTSBiaW5kaW5ncyBtdXN0IGRvY3VtZW50IHRoYXQKLSAgICAgIHRoZXkgZG8gbm90IGNvbmZvcm0gdG8gdGhlIFczQyBzdGFuZGFyZDsgaW4gdGhlIGNhc2Ugb2YgdGhlIElETCBiaW5kaW5nLAotICAgICAgdGhlIHByYWdtYSBwcmVmaXggY2FuIG5vIGxvbmdlciBiZSAndzNjLm9yZyc7IGluIHRoZSBjYXNlIG9mIHRoZSBKYXZhCi0gICAgICBiaW5kaW5nLCB0aGUgcGFja2FnZSBuYW1lcyBjYW4gbm8gbG9uZ2VyIGJlIGluIHRoZSAnb3JnLnczYycgcGFja2FnZS4KLSAgICA8L3A+Ci0gICAgPHA+Ci0gICAgICA8Yj5Ob3RlOjwvYj4gVGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhlIFczQyBTb2Z0d2FyZSBDb3B5cmlnaHQgTm90aWNlCi0gICAgICBhbmQgTGljZW5zZSBjb3VsZCBiZSBmb3VuZCBhdCA8YQotICAgICAgaHJlZj0naHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC9jb3B5cmlnaHQtc29mdHdhcmUtMTk5ODA3MjAnPmh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvY29weXJpZ2h0LXNvZnR3YXJlLTE5OTgwNzIwPC9hPgotICAgIDwvcD4KLSAgICA8aDM+Ci0gICAgICBDb3B5cmlnaHQgJmNvcHk7IDE5OTQtMjAwMCA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy8iPldvcmxkIFdpZGUgV2ViCi0gICAgICBDb25zb3J0aXVtPC9hPiwgKDxhIGhyZWY9Imh0dHA6Ly93d3cubGNzLm1pdC5lZHUvIj5NYXNzYWNodXNldHRzCi0gICAgICBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neTwvYT4sIDxhIGhyZWY9Imh0dHA6Ly93d3cuaW5yaWEuZnIvIj5JbnN0aXR1dAotICAgICAgTmF0aW9uYWwgZGUgUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZTwvYT4sIDxhCi0gICAgICBocmVmPSJodHRwOi8vd3d3LmtlaW8uYWMuanAvIj5LZWlvIFVuaXZlcnNpdHk8L2E+KS4gQWxsIFJpZ2h0cwotICAgICAgUmVzZXJ2ZWQuIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvCi0gICAgPC9oMz4KLSAgICA8cD4KLSAgICAgIFRoaXMgVzNDIHdvcmsgKGluY2x1ZGluZyBzb2Z0d2FyZSwgZG9jdW1lbnRzLCBvciBvdGhlciByZWxhdGVkIGl0ZW1zKSBpcwotICAgICAgYmVpbmcgcHJvdmlkZWQgYnkgdGhlIGNvcHlyaWdodCBob2xkZXJzIHVuZGVyIHRoZSBmb2xsb3dpbmcgbGljZW5zZS4gQnkKLSAgICAgIG9idGFpbmluZywgdXNpbmcgYW5kL29yIGNvcHlpbmcgdGhpcyB3b3JrLCB5b3UgKHRoZSBsaWNlbnNlZSkgYWdyZWUgdGhhdAotICAgICAgeW91IGhhdmUgcmVhZCwgdW5kZXJzdG9vZCwgYW5kIHdpbGwgY29tcGx5IHdpdGggdGhlIGZvbGxvd2luZyB0ZXJtcyBhbmQKLSAgICAgIGNvbmRpdGlvbnM6Ci0gICAgPC9wPgotICAgIDxwPgotICAgICAgUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIGFuZCBtb2RpZnkgdGhpcyBzb2Z0d2FyZSBhbmQgaXRzIGRvY3VtZW50YXRpb24sCi0gICAgICB3aXRoIG9yIHdpdGhvdXQgbW9kaWZpY2F0aW9uLCZuYnNwOyBmb3IgYW55IHB1cnBvc2UgYW5kIHdpdGhvdXQgZmVlIG9yCi0gICAgICByb3lhbHR5IGlzIGhlcmVieSBncmFudGVkLCBwcm92aWRlZCB0aGF0IHlvdSBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgb24gQUxMCi0gICAgICBjb3BpZXMgb2YgdGhlIHNvZnR3YXJlIGFuZCBkb2N1bWVudGF0aW9uIG9yIHBvcnRpb25zIHRoZXJlb2YsIGluY2x1ZGluZwotICAgICAgbW9kaWZpY2F0aW9ucywgdGhhdCB5b3UgbWFrZToKLSAgICA8L3A+Ci0gICAgPG9sPgotICAgICAgPGxpPgotCVRoZSBmdWxsIHRleHQgb2YgdGhpcyBOT1RJQ0UgaW4gYSBsb2NhdGlvbiB2aWV3YWJsZSB0byB1c2VycyBvZiB0aGUKLQlyZWRpc3RyaWJ1dGVkIG9yIGRlcml2YXRpdmUgd29yay4KLSAgICAgIDwvbGk+Ci0gICAgICA8bGk+Ci0JQW55IHByZS1leGlzdGluZyBpbnRlbGxlY3R1YWwgcHJvcGVydHkgZGlzY2xhaW1lcnMsIG5vdGljZXMsIG9yIHRlcm1zCi0JYW5kIGNvbmRpdGlvbnMuIElmIG5vbmUgZXhpc3QsIGEgc2hvcnQgbm90aWNlIG9mIHRoZSBmb2xsb3dpbmcgZm9ybQotCShoeXBlcnRleHQgaXMgcHJlZmVycmVkLCB0ZXh0IGlzIHBlcm1pdHRlZCkgc2hvdWxkIGJlIHVzZWQgd2l0aGluIHRoZQotCWJvZHkgb2YgYW55IHJlZGlzdHJpYnV0ZWQgb3IgZGVyaXZhdGl2ZSBjb2RlOiAiQ29weXJpZ2h0ICZjb3B5OwotCVskZGF0ZS1vZi1zb2Z0d2FyZV0gPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvIj5Xb3JsZCBXaWRlIFdlYgotCUNvbnNvcnRpdW08L2E+LCAoPGEgaHJlZj0iaHR0cDovL3d3dy5sY3MubWl0LmVkdS8iPk1hc3NhY2h1c2V0dHMKLQlJbnN0aXR1dGUgb2YgVGVjaG5vbG9neTwvYT4sIDxhIGhyZWY9Imh0dHA6Ly93d3cuaW5yaWEuZnIvIj5JbnN0aXR1dAotCU5hdGlvbmFsIGRlIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWU8L2E+LCA8YQotCWhyZWY9Imh0dHA6Ly93d3cua2Vpby5hYy5qcC8iPktlaW8gVW5pdmVyc2l0eTwvYT4pLiAgQWxsIFJpZ2h0cwotCVJlc2VydmVkLiBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyIKLSAgICAgIDwvbGk+Ci0gICAgICA8bGk+Ci0JTm90aWNlIG9mIGFueSBjaGFuZ2VzIG9yIG1vZGlmaWNhdGlvbnMgdG8gdGhlIFczQyBmaWxlcywgaW5jbHVkaW5nIHRoZQotCWRhdGUgY2hhbmdlcyB3ZXJlIG1hZGUuIChXZSByZWNvbW1lbmQgeW91IHByb3ZpZGUgVVJJcyB0byB0aGUgbG9jYXRpb24KLQlmcm9tIHdoaWNoIHRoZSBjb2RlIGlzIGRlcml2ZWQuKQotICAgICAgPC9saT4KLSAgICA8L29sPgotICAgIDxwPgotICAgICAgVEhJUyBTT0ZUV0FSRSBBTkQgRE9DVU1FTlRBVElPTiBJUyBQUk9WSURFRCAiQVMgSVMsIiBBTkQgQ09QWVJJR0hUCi0gICAgICBIT0xERVJTIE1BS0UgTk8gUkVQUkVTRU5UQVRJT05TIE9SIFdBUlJBTlRJRVMsIEVYUFJFU1MgT1IgSU1QTElFRCwKLSAgICAgIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8sIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIE9SIEZJVE5FU1MKLSAgICAgIEZPUiBBTlkgUEFSVElDVUxBUiBQVVJQT1NFIE9SIFRIQVQgVEhFIFVTRSBPRiBUSEUgU09GVFdBUkUgT1IKLSAgICAgIERPQ1VNRU5UQVRJT04gV0lMTCBOT1QgSU5GUklOR0UgQU5ZIFRISVJEIFBBUlRZIFBBVEVOVFMsIENPUFlSSUdIVFMsCi0gICAgICBUUkFERU1BUktTIE9SIE9USEVSIFJJR0hUUy4KLSAgICA8L3A+Ci0gICAgPHA+Ci0gICAgICBDT1BZUklHSFQgSE9MREVSUyBXSUxMIE5PVCBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBTUEVDSUFMIE9SCi0gICAgICBDT05TRVFVRU5USUFMIERBTUFHRVMgQVJJU0lORyBPVVQgT0YgQU5ZIFVTRSBPRiBUSEUgU09GVFdBUkUgT1IKLSAgICAgIERPQ1VNRU5UQVRJT04uCi0gICAgPC9wPgotICAgIDxwPgotICAgICAgVGhlIG5hbWUgYW5kIHRyYWRlbWFya3Mgb2YgY29weXJpZ2h0IGhvbGRlcnMgbWF5IE5PVCBiZSB1c2VkIGluCi0gICAgICBhZHZlcnRpc2luZyBvciBwdWJsaWNpdHkgcGVydGFpbmluZyB0byB0aGUgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYywKLSAgICAgIHdyaXR0ZW4gcHJpb3IgcGVybWlzc2lvbi4gVGl0bGUgdG8gY29weXJpZ2h0IGluIHRoaXMgc29mdHdhcmUgYW5kIGFueQotICAgICAgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIHdpbGwgYXQgYWxsIHRpbWVzIHJlbWFpbiB3aXRoIGNvcHlyaWdodAotICAgICAgaG9sZGVycy4KLSAgICA8L3A+Ci0gIDwvYm9keT4KLTwvaHRtbD4KZGlmZiAtLWdpdCBhL3NyYy9vcmcvdzNjL2RvbS9zdHlsZXNoZWV0cy9Eb2N1bWVudFN0eWxlLmphdmEgYi9zcmMvb3JnL3czYy9kb20vc3R5bGVzaGVldHMvRG9jdW1lbnRTdHlsZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyYmUzOWU3Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS9zdHlsZXNoZWV0cy9Eb2N1bWVudFN0eWxlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw2MyArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogVGhpcyBmaWxlIGlzIGF2YWlsYWJsZSB1bmRlciBhbmQgZ292ZXJuZWQgYnkgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwotICogTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKiBIb3dldmVyLCB0aGUgZm9sbG93aW5nIG5vdGljZSBhY2NvbXBhbmllZCB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGlzCi0gKiBmaWxlIGFuZCwgcGVyIGl0cyB0ZXJtcywgc2hvdWxkIG5vdCBiZSByZW1vdmVkOgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAotICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCi0gKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKLSAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQotICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKLSAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KLSAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKLSAqIFBVUlBPU0UuCi0gKiBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KLSAqLwotCi1wYWNrYWdlIG9yZy53M2MuZG9tLnN0eWxlc2hlZXRzOwotCi0vKioKLSAqICBUaGUgPGNvZGU+RG9jdW1lbnRTdHlsZTwvY29kZT4gaW50ZXJmYWNlIHByb3ZpZGVzIGEgbWVjaGFuaXNtIGJ5IHdoaWNoIHRoZQotICogc3R5bGUgc2hlZXRzIGVtYmVkZGVkIGluIGEgZG9jdW1lbnQgY2FuIGJlIHJldHJpZXZlZC4gVGhlIGV4cGVjdGF0aW9uIGlzCi0gKiB0aGF0IGFuIGluc3RhbmNlIG9mIHRoZSA8Y29kZT5Eb2N1bWVudFN0eWxlPC9jb2RlPiBpbnRlcmZhY2UgY2FuIGJlCi0gKiBvYnRhaW5lZCBieSB1c2luZyBiaW5kaW5nLXNwZWNpZmljIGNhc3RpbmcgbWV0aG9kcyBvbiBhbiBpbnN0YW5jZSBvZiB0aGUKLSAqIDxjb2RlPkRvY3VtZW50PC9jb2RlPiBpbnRlcmZhY2UuCi0gKiA8cD5TZWUgYWxzbyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMC9SRUMtRE9NLUxldmVsLTItU3R5bGUtMjAwMDExMTMnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAyIFN0eWxlIFNwZWNpZmljYXRpb248L2E+LgotICogQHNpbmNlIERPTSBMZXZlbCAyCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgRG9jdW1lbnRTdHlsZSB7Ci0gICAgLyoqCi0gICAgICogIEEgbGlzdCBjb250YWluaW5nIGFsbCB0aGUgc3R5bGUgc2hlZXRzIGV4cGxpY2l0bHkgbGlua2VkIGludG8gb3IKLSAgICAgKiBlbWJlZGRlZCBpbiBhIGRvY3VtZW50LiBGb3IgSFRNTCBkb2N1bWVudHMsIHRoaXMgaW5jbHVkZXMgZXh0ZXJuYWwKLSAgICAgKiBzdHlsZSBzaGVldHMsIGluY2x1ZGVkIHZpYSB0aGUgSFRNTCAgTElOSyBlbGVtZW50LCBhbmQgaW5saW5lICBTVFlMRQotICAgICAqIGVsZW1lbnRzLiBJbiBYTUwsIHRoaXMgaW5jbHVkZXMgZXh0ZXJuYWwgc3R5bGUgc2hlZXRzLCBpbmNsdWRlZCB2aWEKLSAgICAgKiBzdHlsZSBzaGVldCBwcm9jZXNzaW5nIGluc3RydWN0aW9ucyAoc2VlIFtYTUwgU3R5bGVTaGVldF0pLgotICAgICAqLwotICAgIHB1YmxpYyBTdHlsZVNoZWV0TGlzdCBnZXRTdHlsZVNoZWV0cygpOwotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL3czYy9kb20vc3R5bGVzaGVldHMvTGlua1N0eWxlLmphdmEgYi9zcmMvb3JnL3czYy9kb20vc3R5bGVzaGVldHMvTGlua1N0eWxlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDliZDdiNjguLjAwMDAwMDAKLS0tIGEvc3JjL29yZy93M2MvZG9tL3N0eWxlc2hlZXRzL0xpbmtTdHlsZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNjAgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIFRoaXMgZmlsZSBpcyBhdmFpbGFibGUgdW5kZXIgYW5kIGdvdmVybmVkIGJ5IHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKLSAqIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICogSG93ZXZlciwgdGhlIGZvbGxvd2luZyBub3RpY2UgYWNjb21wYW5pZWQgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcwotICogZmlsZSBhbmQsIHBlciBpdHMgdGVybXMsIHNob3VsZCBub3QgYmUgcmVtb3ZlZDoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDAgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKLSAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQotICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCi0gKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKLSAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCi0gKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCi0gKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCi0gKiBQVVJQT1NFLgotICogU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCi0gKi8KLQotcGFja2FnZSBvcmcudzNjLmRvbS5zdHlsZXNoZWV0czsKLQotLyoqCi0gKiAgVGhlIDxjb2RlPkxpbmtTdHlsZTwvY29kZT4gaW50ZXJmYWNlIHByb3ZpZGVzIGEgbWVjaGFuaXNtIGJ5IHdoaWNoIGEgc3R5bGUKLSAqIHNoZWV0IGNhbiBiZSByZXRyaWV2ZWQgZnJvbSB0aGUgbm9kZSByZXNwb25zaWJsZSBmb3IgbGlua2luZyBpdCBpbnRvIGEKLSAqIGRvY3VtZW50LiBBbiBpbnN0YW5jZSBvZiB0aGUgPGNvZGU+TGlua1N0eWxlPC9jb2RlPiBpbnRlcmZhY2UgY2FuIGJlCi0gKiBvYnRhaW5lZCB1c2luZyBiaW5kaW5nLXNwZWNpZmljIGNhc3RpbmcgbWV0aG9kcyBvbiBhbiBpbnN0YW5jZSBvZiBhCi0gKiBsaW5raW5nIG5vZGUgKDxjb2RlPkhUTUxMaW5rRWxlbWVudDwvY29kZT4sIDxjb2RlPkhUTUxTdHlsZUVsZW1lbnQ8L2NvZGU+Ci0gKiBvciA8Y29kZT5Qcm9jZXNzaW5nSW5zdHJ1Y3Rpb248L2NvZGU+IGluIERPTSBMZXZlbCAyKS4KLSAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAwL1JFQy1ET00tTGV2ZWwtMi1TdHlsZS0yMDAwMTExMyc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDIgU3R5bGUgU3BlY2lmaWNhdGlvbjwvYT4uCi0gKiBAc2luY2UgRE9NIExldmVsIDIKLSAqLwotcHVibGljIGludGVyZmFjZSBMaW5rU3R5bGUgewotICAgIC8qKgotICAgICAqICBUaGUgc3R5bGUgc2hlZXQuCi0gICAgICovCi0gICAgcHVibGljIFN0eWxlU2hlZXQgZ2V0U2hlZXQoKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy93M2MvZG9tL3N0eWxlc2hlZXRzL01lZGlhTGlzdC5qYXZhIGIvc3JjL29yZy93M2MvZG9tL3N0eWxlc2hlZXRzL01lZGlhTGlzdC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxYTgyNzY3Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS9zdHlsZXNoZWV0cy9NZWRpYUxpc3QuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExNCArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogVGhpcyBmaWxlIGlzIGF2YWlsYWJsZSB1bmRlciBhbmQgZ292ZXJuZWQgYnkgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwotICogTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKiBIb3dldmVyLCB0aGUgZm9sbG93aW5nIG5vdGljZSBhY2NvbXBhbmllZCB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGlzCi0gKiBmaWxlIGFuZCwgcGVyIGl0cyB0ZXJtcywgc2hvdWxkIG5vdCBiZSByZW1vdmVkOgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAotICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCi0gKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKLSAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQotICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKLSAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KLSAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKLSAqIFBVUlBPU0UuCi0gKiBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KLSAqLwotCi1wYWNrYWdlIG9yZy53M2MuZG9tLnN0eWxlc2hlZXRzOwotCi1pbXBvcnQgb3JnLnczYy5kb20uRE9NRXhjZXB0aW9uOwotCi0vKioKLSAqICBUaGUgPGNvZGU+TWVkaWFMaXN0PC9jb2RlPiBpbnRlcmZhY2UgcHJvdmlkZXMgdGhlIGFic3RyYWN0aW9uIG9mIGFuCi0gKiBvcmRlcmVkIGNvbGxlY3Rpb24gb2YgbWVkaWEsIHdpdGhvdXQgZGVmaW5pbmcgb3IgY29uc3RyYWluaW5nIGhvdyB0aGlzCi0gKiBjb2xsZWN0aW9uIGlzIGltcGxlbWVudGVkLiBBbiBlbXB0eSBsaXN0IGlzIHRoZSBzYW1lIGFzIGEgbGlzdCB0aGF0Ci0gKiBjb250YWlucyB0aGUgbWVkaXVtIDxjb2RlPiJhbGwiPC9jb2RlPi4KLSAqIDxwPiBUaGUgaXRlbXMgaW4gdGhlIDxjb2RlPk1lZGlhTGlzdDwvY29kZT4gYXJlIGFjY2Vzc2libGUgdmlhIGFuIGludGVncmFsCi0gKiBpbmRleCwgc3RhcnRpbmcgZnJvbSAwLgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDAvUkVDLURPTS1MZXZlbC0yLVN0eWxlLTIwMDAxMTEzJz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMiBTdHlsZSBTcGVjaWZpY2F0aW9uPC9hPi4KLSAqIEBzaW5jZSBET00gTGV2ZWwgMgotICovCi1wdWJsaWMgaW50ZXJmYWNlIE1lZGlhTGlzdCB7Ci0gICAgLyoqCi0gICAgICogIFRoZSBwYXJzYWJsZSB0ZXh0dWFsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBtZWRpYSBsaXN0LiBUaGlzIGlzIGEKLSAgICAgKiBjb21tYS1zZXBhcmF0ZWQgbGlzdCBvZiBtZWRpYS4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE1lZGlhVGV4dCgpOwotICAgIC8qKgotICAgICAqICBUaGUgcGFyc2FibGUgdGV4dHVhbCByZXByZXNlbnRhdGlvbiBvZiB0aGUgbWVkaWEgbGlzdC4gVGhpcyBpcyBhCi0gICAgICogY29tbWEtc2VwYXJhdGVkIGxpc3Qgb2YgbWVkaWEuCi0gICAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICAgKiAgIFNZTlRBWF9FUlI6IFJhaXNlZCBpZiB0aGUgc3BlY2lmaWVkIHN0cmluZyB2YWx1ZSBoYXMgYSBzeW50YXggZXJyb3IKLSAgICAgKiAgIGFuZCBpcyB1bnBhcnNhYmxlLgotICAgICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgbWVkaWEgbGlzdCBpcwotICAgICAqICAgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0TWVkaWFUZXh0KFN0cmluZyBtZWRpYVRleHQpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiAgVGhlIG51bWJlciBvZiBtZWRpYSBpbiB0aGUgbGlzdC4gVGhlIHJhbmdlIG9mIHZhbGlkIG1lZGlhIGlzCi0gICAgICogPGNvZGU+MDwvY29kZT4gdG8gPGNvZGU+bGVuZ3RoLTE8L2NvZGU+IGluY2x1c2l2ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldExlbmd0aCgpOwotCi0gICAgLyoqCi0gICAgICogIFJldHVybnMgdGhlIDxjb2RlPmluZGV4PC9jb2RlPnRoIGluIHRoZSBsaXN0LiBJZiA8Y29kZT5pbmRleDwvY29kZT4gaXMKLSAgICAgKiBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gdGhlIG51bWJlciBvZiBtZWRpYSBpbiB0aGUgbGlzdCwgdGhpcwotICAgICAqIHJldHVybnMgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICogQHBhcmFtIGluZGV4ICBJbmRleCBpbnRvIHRoZSBjb2xsZWN0aW9uLgotICAgICAqIEByZXR1cm4gIFRoZSBtZWRpdW0gYXQgdGhlIDxjb2RlPmluZGV4PC9jb2RlPnRoIHBvc2l0aW9uIGluIHRoZQotICAgICAqICAgPGNvZGU+TWVkaWFMaXN0PC9jb2RlPiwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhhdCBpcyBub3QgYSB2YWxpZAotICAgICAqICAgaW5kZXguCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBpdGVtKGludCBpbmRleCk7Ci0KLSAgICAvKioKLSAgICAgKiAgRGVsZXRlcyB0aGUgbWVkaXVtIGluZGljYXRlZCBieSA8Y29kZT5vbGRNZWRpdW08L2NvZGU+IGZyb20gdGhlIGxpc3QuCi0gICAgICogQHBhcmFtIG9sZE1lZGl1bSBUaGUgbWVkaXVtIHRvIGRlbGV0ZSBpbiB0aGUgbWVkaWEgbGlzdC4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgIE5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgbGlzdCBpcyByZWFkb25seS4KLSAgICAgKiAgIDxicj4gTk9UX0ZPVU5EX0VSUjogUmFpc2VkIGlmIDxjb2RlPm9sZE1lZGl1bTwvY29kZT4gaXMgbm90IGluIHRoZQotICAgICAqICAgbGlzdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBkZWxldGVNZWRpdW0oU3RyaW5nIG9sZE1lZGl1bSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqICBBZGRzIHRoZSBtZWRpdW0gPGNvZGU+bmV3TWVkaXVtPC9jb2RlPiB0byB0aGUgZW5kIG9mIHRoZSBsaXN0LiBJZiB0aGUKLSAgICAgKiA8Y29kZT5uZXdNZWRpdW08L2NvZGU+IGlzIGFscmVhZHkgdXNlZCwgaXQgaXMgZmlyc3QgcmVtb3ZlZC4KLSAgICAgKiBAcGFyYW0gbmV3TWVkaXVtIFRoZSBuZXcgbWVkaXVtIHRvIGFkZC4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgIElOVkFMSURfQ0hBUkFDVEVSX0VSUjogSWYgdGhlIG1lZGl1bSBjb250YWlucyBjaGFyYWN0ZXJzIHRoYXQgYXJlCi0gICAgICogICBpbnZhbGlkIGluIHRoZSB1bmRlcmx5aW5nIHN0eWxlIGxhbmd1YWdlLgotICAgICAqICAgPGJyPiBOT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIGxpc3QgaXMgcmVhZG9ubHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgYXBwZW5kTWVkaXVtKFN0cmluZyBuZXdNZWRpdW0pCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvdzNjL2RvbS9zdHlsZXNoZWV0cy9TdHlsZVNoZWV0LmphdmEgYi9zcmMvb3JnL3czYy9kb20vc3R5bGVzaGVldHMvU3R5bGVTaGVldC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2MTdjNjhlLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS9zdHlsZXNoZWV0cy9TdHlsZVNoZWV0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMzIgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIFRoaXMgZmlsZSBpcyBhdmFpbGFibGUgdW5kZXIgYW5kIGdvdmVybmVkIGJ5IHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKLSAqIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICogSG93ZXZlciwgdGhlIGZvbGxvd2luZyBub3RpY2UgYWNjb21wYW5pZWQgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcwotICogZmlsZSBhbmQsIHBlciBpdHMgdGVybXMsIHNob3VsZCBub3QgYmUgcmVtb3ZlZDoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDAgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKLSAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQotICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCi0gKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKLSAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCi0gKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCi0gKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCi0gKiBQVVJQT1NFLgotICogU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCi0gKi8KLQotcGFja2FnZSBvcmcudzNjLmRvbS5zdHlsZXNoZWV0czsKLQotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci0KLS8qKgotICogIFRoZSA8Y29kZT5TdHlsZVNoZWV0PC9jb2RlPiBpbnRlcmZhY2UgaXMgdGhlIGFic3RyYWN0IGJhc2UgaW50ZXJmYWNlIGZvcgotICogYW55IHR5cGUgb2Ygc3R5bGUgc2hlZXQuIEl0IHJlcHJlc2VudHMgYSBzaW5nbGUgc3R5bGUgc2hlZXQgYXNzb2NpYXRlZAotICogd2l0aCBhIHN0cnVjdHVyZWQgZG9jdW1lbnQuIEluIEhUTUwsIHRoZSBTdHlsZVNoZWV0IGludGVyZmFjZSByZXByZXNlbnRzCi0gKiBlaXRoZXIgYW4gZXh0ZXJuYWwgc3R5bGUgc2hlZXQsIGluY2x1ZGVkIHZpYSB0aGUgSFRNTCAgTElOSyBlbGVtZW50LCBvcgotICogYW4gaW5saW5lICBTVFlMRSBlbGVtZW50LiBJbiBYTUwsIHRoaXMgaW50ZXJmYWNlIHJlcHJlc2VudHMgYW4gZXh0ZXJuYWwKLSAqIHN0eWxlIHNoZWV0LCBpbmNsdWRlZCB2aWEgYSBzdHlsZSBzaGVldCBwcm9jZXNzaW5nIGluc3RydWN0aW9uLgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDAvUkVDLURPTS1MZXZlbC0yLVN0eWxlLTIwMDAxMTEzJz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMiBTdHlsZSBTcGVjaWZpY2F0aW9uPC9hPi4KLSAqIEBzaW5jZSBET00gTGV2ZWwgMgotICovCi1wdWJsaWMgaW50ZXJmYWNlIFN0eWxlU2hlZXQgewotICAgIC8qKgotICAgICAqICBUaGlzIHNwZWNpZmllcyB0aGUgc3R5bGUgc2hlZXQgbGFuZ3VhZ2UgZm9yIHRoaXMgc3R5bGUgc2hlZXQuIFRoZQotICAgICAqIHN0eWxlIHNoZWV0IGxhbmd1YWdlIGlzIHNwZWNpZmllZCBhcyBhIGNvbnRlbnQgdHlwZSAoZS5nLgotICAgICAqICJ0ZXh0L2NzcyIpLiBUaGUgY29udGVudCB0eXBlIGlzIG9mdGVuIHNwZWNpZmllZCBpbiB0aGUKLSAgICAgKiA8Y29kZT5vd25lck5vZGU8L2NvZGU+LiBBbHNvIHNlZSB0aGUgdHlwZSBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBmb3IKLSAgICAgKiB0aGUgPGNvZGU+TElOSzwvY29kZT4gZWxlbWVudCBpbiBIVE1MIDQuMCwgYW5kIHRoZSB0eXBlCi0gICAgICogcHNldWRvLWF0dHJpYnV0ZSBmb3IgdGhlIFhNTCBzdHlsZSBzaGVldCBwcm9jZXNzaW5nIGluc3RydWN0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VHlwZSgpOwotCi0gICAgLyoqCi0gICAgICogIDxjb2RlPmZhbHNlPC9jb2RlPiBpZiB0aGUgc3R5bGUgc2hlZXQgaXMgYXBwbGllZCB0byB0aGUgZG9jdW1lbnQuCi0gICAgICogPGNvZGU+dHJ1ZTwvY29kZT4gaWYgaXQgaXMgbm90LiBNb2RpZnlpbmcgdGhpcyBhdHRyaWJ1dGUgbWF5IGNhdXNlIGEKLSAgICAgKiBuZXcgcmVzb2x1dGlvbiBvZiBzdHlsZSBmb3IgdGhlIGRvY3VtZW50LiBBIHN0eWxlc2hlZXQgb25seSBhcHBsaWVzCi0gICAgICogaWYgYm90aCBhbiBhcHByb3ByaWF0ZSBtZWRpdW0gZGVmaW5pdGlvbiBpcyBwcmVzZW50IGFuZCB0aGUgZGlzYWJsZWQKLSAgICAgKiBhdHRyaWJ1dGUgaXMgZmFsc2UuIFNvLCBpZiB0aGUgbWVkaWEgZG9lc24ndCBhcHBseSB0byB0aGUgY3VycmVudAotICAgICAqIHVzZXIgYWdlbnQsIHRoZSA8Y29kZT5kaXNhYmxlZDwvY29kZT4gYXR0cmlidXRlIGlzIGlnbm9yZWQuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0RGlzYWJsZWQoKTsKLSAgICAvKioKLSAgICAgKiAgPGNvZGU+ZmFsc2U8L2NvZGU+IGlmIHRoZSBzdHlsZSBzaGVldCBpcyBhcHBsaWVkIHRvIHRoZSBkb2N1bWVudC4KLSAgICAgKiA8Y29kZT50cnVlPC9jb2RlPiBpZiBpdCBpcyBub3QuIE1vZGlmeWluZyB0aGlzIGF0dHJpYnV0ZSBtYXkgY2F1c2UgYQotICAgICAqIG5ldyByZXNvbHV0aW9uIG9mIHN0eWxlIGZvciB0aGUgZG9jdW1lbnQuIEEgc3R5bGVzaGVldCBvbmx5IGFwcGxpZXMKLSAgICAgKiBpZiBib3RoIGFuIGFwcHJvcHJpYXRlIG1lZGl1bSBkZWZpbml0aW9uIGlzIHByZXNlbnQgYW5kIHRoZSBkaXNhYmxlZAotICAgICAqIGF0dHJpYnV0ZSBpcyBmYWxzZS4gU28sIGlmIHRoZSBtZWRpYSBkb2Vzbid0IGFwcGx5IHRvIHRoZSBjdXJyZW50Ci0gICAgICogdXNlciBhZ2VudCwgdGhlIDxjb2RlPmRpc2FibGVkPC9jb2RlPiBhdHRyaWJ1dGUgaXMgaWdub3JlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXREaXNhYmxlZChib29sZWFuIGRpc2FibGVkKTsKLQotICAgIC8qKgotICAgICAqICBUaGUgbm9kZSB0aGF0IGFzc29jaWF0ZXMgdGhpcyBzdHlsZSBzaGVldCB3aXRoIHRoZSBkb2N1bWVudC4gRm9yIEhUTUwsCi0gICAgICogdGhpcyBtYXkgYmUgdGhlIGNvcnJlc3BvbmRpbmcgPGNvZGU+TElOSzwvY29kZT4gb3IgPGNvZGU+U1RZTEU8L2NvZGU+Ci0gICAgICogZWxlbWVudC4gRm9yIFhNTCwgaXQgbWF5IGJlIHRoZSBsaW5raW5nIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24uIEZvcgotICAgICAqIHN0eWxlIHNoZWV0cyB0aGF0IGFyZSBpbmNsdWRlZCBieSBvdGhlciBzdHlsZSBzaGVldHMsIHRoZSB2YWx1ZSBvZgotICAgICAqIHRoaXMgYXR0cmlidXRlIGlzIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBOb2RlIGdldE93bmVyTm9kZSgpOwotCi0gICAgLyoqCi0gICAgICogIEZvciBzdHlsZSBzaGVldCBsYW5ndWFnZXMgdGhhdCBzdXBwb3J0IHRoZSBjb25jZXB0IG9mIHN0eWxlIHNoZWV0Ci0gICAgICogaW5jbHVzaW9uLCB0aGlzIGF0dHJpYnV0ZSByZXByZXNlbnRzIHRoZSBpbmNsdWRpbmcgc3R5bGUgc2hlZXQsIGlmCi0gICAgICogb25lIGV4aXN0cy4gSWYgdGhlIHN0eWxlIHNoZWV0IGlzIGEgdG9wLWxldmVsIHN0eWxlIHNoZWV0LCBvciB0aGUKLSAgICAgKiBzdHlsZSBzaGVldCBsYW5ndWFnZSBkb2VzIG5vdCBzdXBwb3J0IGluY2x1c2lvbiwgdGhlIHZhbHVlIG9mIHRoaXMKLSAgICAgKiBhdHRyaWJ1dGUgaXMgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIFN0eWxlU2hlZXQgZ2V0UGFyZW50U3R5bGVTaGVldCgpOwotCi0gICAgLyoqCi0gICAgICogIElmIHRoZSBzdHlsZSBzaGVldCBpcyBhIGxpbmtlZCBzdHlsZSBzaGVldCwgdGhlIHZhbHVlIG9mIGl0cyBhdHRyaWJ1dGUKLSAgICAgKiBpcyBpdHMgbG9jYXRpb24uIEZvciBpbmxpbmUgc3R5bGUgc2hlZXRzLCB0aGUgdmFsdWUgb2YgdGhpcyBhdHRyaWJ1dGUKLSAgICAgKiBpcyA8Y29kZT5udWxsPC9jb2RlPi4gU2VlIHRoZSBocmVmIGF0dHJpYnV0ZSBkZWZpbml0aW9uIGZvciB0aGUKLSAgICAgKiA8Y29kZT5MSU5LPC9jb2RlPiBlbGVtZW50IGluIEhUTUwgNC4wLCBhbmQgdGhlIGhyZWYgcHNldWRvLWF0dHJpYnV0ZQotICAgICAqIGZvciB0aGUgWE1MIHN0eWxlIHNoZWV0IHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24uCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRIcmVmKCk7Ci0KLSAgICAvKioKLSAgICAgKiAgVGhlIGFkdmlzb3J5IHRpdGxlLiBUaGUgdGl0bGUgaXMgb2Z0ZW4gc3BlY2lmaWVkIGluIHRoZQotICAgICAqIDxjb2RlPm93bmVyTm9kZTwvY29kZT4uIFNlZSB0aGUgdGl0bGUgYXR0cmlidXRlIGRlZmluaXRpb24gZm9yIHRoZQotICAgICAqIDxjb2RlPkxJTks8L2NvZGU+IGVsZW1lbnQgaW4gSFRNTCA0LjAsIGFuZCB0aGUgdGl0bGUgcHNldWRvLWF0dHJpYnV0ZQotICAgICAqIGZvciB0aGUgWE1MIHN0eWxlIHNoZWV0IHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24uCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRUaXRsZSgpOwotCi0gICAgLyoqCi0gICAgICogIFRoZSBpbnRlbmRlZCBkZXN0aW5hdGlvbiBtZWRpYSBmb3Igc3R5bGUgaW5mb3JtYXRpb24uIFRoZSBtZWRpYSBpcwotICAgICAqIG9mdGVuIHNwZWNpZmllZCBpbiB0aGUgPGNvZGU+b3duZXJOb2RlPC9jb2RlPi4gSWYgbm8gbWVkaWEgaGFzIGJlZW4KLSAgICAgKiBzcGVjaWZpZWQsIHRoZSA8Y29kZT5NZWRpYUxpc3Q8L2NvZGU+IHdpbGwgYmUgZW1wdHkuIFNlZSB0aGUgbWVkaWEKLSAgICAgKiBhdHRyaWJ1dGUgZGVmaW5pdGlvbiBmb3IgdGhlIDxjb2RlPkxJTks8L2NvZGU+IGVsZW1lbnQgaW4gSFRNTCA0LjAsCi0gICAgICogYW5kIHRoZSBtZWRpYSBwc2V1ZG8tYXR0cmlidXRlIGZvciB0aGUgWE1MIHN0eWxlIHNoZWV0IHByb2Nlc3NpbmcKLSAgICAgKiBpbnN0cnVjdGlvbiAuIE1vZGlmeWluZyB0aGUgbWVkaWEgbGlzdCBtYXkgY2F1c2UgYSBjaGFuZ2UgdG8gdGhlCi0gICAgICogYXR0cmlidXRlIDxjb2RlPmRpc2FibGVkPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgTWVkaWFMaXN0IGdldE1lZGlhKCk7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvdzNjL2RvbS9zdHlsZXNoZWV0cy9TdHlsZVNoZWV0TGlzdC5qYXZhIGIvc3JjL29yZy93M2MvZG9tL3N0eWxlc2hlZXRzL1N0eWxlU2hlZXRMaXN0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDZjZDUyNTQuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy93M2MvZG9tL3N0eWxlc2hlZXRzL1N0eWxlU2hlZXRMaXN0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3MSArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogVGhpcyBmaWxlIGlzIGF2YWlsYWJsZSB1bmRlciBhbmQgZ292ZXJuZWQgYnkgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwotICogTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKiBIb3dldmVyLCB0aGUgZm9sbG93aW5nIG5vdGljZSBhY2NvbXBhbmllZCB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGlzCi0gKiBmaWxlIGFuZCwgcGVyIGl0cyB0ZXJtcywgc2hvdWxkIG5vdCBiZSByZW1vdmVkOgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAotICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCi0gKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKLSAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQotICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKLSAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KLSAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKLSAqIFBVUlBPU0UuCi0gKiBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KLSAqLwotCi1wYWNrYWdlIG9yZy53M2MuZG9tLnN0eWxlc2hlZXRzOwotCi0vKioKLSAqIFRoZSA8Y29kZT5TdHlsZVNoZWV0TGlzdDwvY29kZT4gaW50ZXJmYWNlIHByb3ZpZGVzIHRoZSBhYnN0cmFjdGlvbiBvZiBhbgotICogb3JkZXJlZCBjb2xsZWN0aW9uIG9mIHN0eWxlIHNoZWV0cy4KLSAqIDxwPiBUaGUgaXRlbXMgaW4gdGhlIDxjb2RlPlN0eWxlU2hlZXRMaXN0PC9jb2RlPiBhcmUgYWNjZXNzaWJsZSB2aWEgYW4KLSAqIGludGVncmFsIGluZGV4LCBzdGFydGluZyBmcm9tIDAuCi0gKiA8cD5TZWUgYWxzbyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMC9SRUMtRE9NLUxldmVsLTItU3R5bGUtMjAwMDExMTMnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAyIFN0eWxlIFNwZWNpZmljYXRpb248L2E+LgotICogQHNpbmNlIERPTSBMZXZlbCAyCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgU3R5bGVTaGVldExpc3QgewotICAgIC8qKgotICAgICAqICBUaGUgbnVtYmVyIG9mIDxjb2RlPlN0eWxlU2hlZXRzPC9jb2RlPiBpbiB0aGUgbGlzdC4gVGhlIHJhbmdlIG9mIHZhbGlkCi0gICAgICogY2hpbGQgc3R5bGVzaGVldCBpbmRpY2VzIGlzIDxjb2RlPjA8L2NvZGU+IHRvIDxjb2RlPmxlbmd0aC0xPC9jb2RlPgotICAgICAqIGluY2x1c2l2ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldExlbmd0aCgpOwotCi0gICAgLyoqCi0gICAgICogIFVzZWQgdG8gcmV0cmlldmUgYSBzdHlsZSBzaGVldCBieSBvcmRpbmFsIGluZGV4LiBJZiBpbmRleCBpcyBncmVhdGVyCi0gICAgICogdGhhbiBvciBlcXVhbCB0byB0aGUgbnVtYmVyIG9mIHN0eWxlIHNoZWV0cyBpbiB0aGUgbGlzdCwgdGhpcyByZXR1cm5zCi0gICAgICogPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICogQHBhcmFtIGluZGV4IEluZGV4IGludG8gdGhlIGNvbGxlY3Rpb24KLSAgICAgKiBAcmV0dXJuIFRoZSBzdHlsZSBzaGVldCBhdCB0aGUgPGNvZGU+aW5kZXg8L2NvZGU+IHBvc2l0aW9uIGluIHRoZQotICAgICAqICAgPGNvZGU+U3R5bGVTaGVldExpc3Q8L2NvZGU+LCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGF0IGlzIG5vdCBhCi0gICAgICogICB2YWxpZCBpbmRleC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3R5bGVTaGVldCBpdGVtKGludCBpbmRleCk7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvdzNjL2RvbS90cmF2ZXJzYWwvRG9jdW1lbnRUcmF2ZXJzYWwuamF2YSBiL3NyYy9vcmcvdzNjL2RvbS90cmF2ZXJzYWwvRG9jdW1lbnRUcmF2ZXJzYWwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggODA5Mzg4OC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3czYy9kb20vdHJhdmVyc2FsL0RvY3VtZW50VHJhdmVyc2FsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMjIgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIFRoaXMgZmlsZSBpcyBhdmFpbGFibGUgdW5kZXIgYW5kIGdvdmVybmVkIGJ5IHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKLSAqIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICogSG93ZXZlciwgdGhlIGZvbGxvd2luZyBub3RpY2UgYWNjb21wYW5pZWQgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcwotICogZmlsZSBhbmQsIHBlciBpdHMgdGVybXMsIHNob3VsZCBub3QgYmUgcmVtb3ZlZDoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDAgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKLSAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQotICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCi0gKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKLSAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCi0gKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCi0gKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCi0gKiBQVVJQT1NFLgotICogU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCi0gKi8KLQotcGFja2FnZSBvcmcudzNjLmRvbS50cmF2ZXJzYWw7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotaW1wb3J0IG9yZy53M2MuZG9tLkRPTUV4Y2VwdGlvbjsKLQotLyoqCi0gKiA8Y29kZT5Eb2N1bWVudFRyYXZlcnNhbDwvY29kZT4gY29udGFpbnMgbWV0aG9kcyB0aGF0IGNyZWF0ZQotICogPGNvZGU+Tm9kZUl0ZXJhdG9yczwvY29kZT4gYW5kIDxjb2RlPlRyZWVXYWxrZXJzPC9jb2RlPiB0byB0cmF2ZXJzZSBhCi0gKiBub2RlIGFuZCBpdHMgY2hpbGRyZW4gaW4gZG9jdW1lbnQgb3JkZXIgKGRlcHRoIGZpcnN0LCBwcmUtb3JkZXIKLSAqIHRyYXZlcnNhbCwgd2hpY2ggaXMgZXF1aXZhbGVudCB0byB0aGUgb3JkZXIgaW4gd2hpY2ggdGhlIHN0YXJ0IHRhZ3Mgb2NjdXIKLSAqIGluIHRoZSB0ZXh0IHJlcHJlc2VudGF0aW9uIG9mIHRoZSBkb2N1bWVudCkuIEluIERPTXMgd2hpY2ggc3VwcG9ydCB0aGUKLSAqIFRyYXZlcnNhbCBmZWF0dXJlLCA8Y29kZT5Eb2N1bWVudFRyYXZlcnNhbDwvY29kZT4gd2lsbCBiZSBpbXBsZW1lbnRlZCBieQotICogdGhlIHNhbWUgb2JqZWN0cyB0aGF0IGltcGxlbWVudCB0aGUgRG9jdW1lbnQgaW50ZXJmYWNlLgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDAvUkVDLURPTS1MZXZlbC0yLVRyYXZlcnNhbC1SYW5nZS0yMDAwMTExMyc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDIgVHJhdmVyc2FsIGFuZCBSYW5nZSBTcGVjaWZpY2F0aW9uPC9hPi4KLSAqIEBzaW5jZSBET00gTGV2ZWwgMgotICovCi1wdWJsaWMgaW50ZXJmYWNlIERvY3VtZW50VHJhdmVyc2FsIHsKLSAgICAvKioKLSAgICAgKiBDcmVhdGUgYSBuZXcgPGNvZGU+Tm9kZUl0ZXJhdG9yPC9jb2RlPiBvdmVyIHRoZSBzdWJ0cmVlIHJvb3RlZCBhdCB0aGUKLSAgICAgKiBzcGVjaWZpZWQgbm9kZS4KLSAgICAgKiBAcGFyYW0gcm9vdCBUaGUgbm9kZSB3aGljaCB3aWxsIGJlIGl0ZXJhdGVkIHRvZ2V0aGVyIHdpdGggaXRzCi0gICAgICogICBjaGlsZHJlbi4gVGhlIDxjb2RlPk5vZGVJdGVyYXRvcjwvY29kZT4gaXMgaW5pdGlhbGx5IHBvc2l0aW9uZWQKLSAgICAgKiAgIGp1c3QgYmVmb3JlIHRoaXMgbm9kZS4gVGhlIDxjb2RlPndoYXRUb1Nob3c8L2NvZGU+IGZsYWdzIGFuZCB0aGUKLSAgICAgKiAgIGZpbHRlciwgaWYgYW55LCBhcmUgbm90IGNvbnNpZGVyZWQgd2hlbiBzZXR0aW5nIHRoaXMgcG9zaXRpb24uIFRoZQotICAgICAqICAgcm9vdCBtdXN0IG5vdCBiZSA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICAgKiBAcGFyYW0gd2hhdFRvU2hvdyBUaGlzIGZsYWcgc3BlY2lmaWVzIHdoaWNoIG5vZGUgdHlwZXMgbWF5IGFwcGVhciBpbgotICAgICAqICAgdGhlIGxvZ2ljYWwgdmlldyBvZiB0aGUgdHJlZSBwcmVzZW50ZWQgYnkgdGhlCi0gICAgICogICA8Y29kZT5Ob2RlSXRlcmF0b3I8L2NvZGU+LiBTZWUgdGhlIGRlc2NyaXB0aW9uIG9mCi0gICAgICogICA8Y29kZT5Ob2RlRmlsdGVyPC9jb2RlPiBmb3IgdGhlIHNldCBvZiBwb3NzaWJsZSA8Y29kZT5TSE9XXzwvY29kZT4KLSAgICAgKiAgIHZhbHVlcy5UaGVzZSBmbGFncyBjYW4gYmUgY29tYmluZWQgdXNpbmcgPGNvZGU+T1I8L2NvZGU+LgotICAgICAqIEBwYXJhbSBmaWx0ZXIgVGhlIDxjb2RlPk5vZGVGaWx0ZXI8L2NvZGU+IHRvIGJlIHVzZWQgd2l0aCB0aGlzCi0gICAgICogICA8Y29kZT5Ob2RlSXRlcmF0b3I8L2NvZGU+LCBvciA8Y29kZT5udWxsPC9jb2RlPiB0byBpbmRpY2F0ZSBubwotICAgICAqICAgZmlsdGVyLgotICAgICAqIEBwYXJhbSBlbnRpdHlSZWZlcmVuY2VFeHBhbnNpb24gVGhlIHZhbHVlIG9mIHRoaXMgZmxhZyBkZXRlcm1pbmVzCi0gICAgICogICB3aGV0aGVyIGVudGl0eSByZWZlcmVuY2Ugbm9kZXMgYXJlIGV4cGFuZGVkLgotICAgICAqIEByZXR1cm4gVGhlIG5ld2x5IGNyZWF0ZWQgPGNvZGU+Tm9kZUl0ZXJhdG9yPC9jb2RlPi4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgTk9UX1NVUFBPUlRFRF9FUlI6IFJhaXNlZCBpZiB0aGUgc3BlY2lmaWVkIDxjb2RlPnJvb3Q8L2NvZGU+IGlzCi0gICAgICogICA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgTm9kZUl0ZXJhdG9yIGNyZWF0ZU5vZGVJdGVyYXRvcihOb2RlIHJvb3QsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHdoYXRUb1Nob3csCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTm9kZUZpbHRlciBmaWx0ZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBlbnRpdHlSZWZlcmVuY2VFeHBhbnNpb24pCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIENyZWF0ZSBhIG5ldyA8Y29kZT5UcmVlV2Fsa2VyPC9jb2RlPiBvdmVyIHRoZSBzdWJ0cmVlIHJvb3RlZCBhdCB0aGUKLSAgICAgKiBzcGVjaWZpZWQgbm9kZS4KLSAgICAgKiBAcGFyYW0gcm9vdCBUaGUgbm9kZSB3aGljaCB3aWxsIHNlcnZlIGFzIHRoZSA8Y29kZT5yb290PC9jb2RlPiBmb3IgdGhlCi0gICAgICogICA8Y29kZT5UcmVlV2Fsa2VyPC9jb2RlPi4gVGhlIDxjb2RlPndoYXRUb1Nob3c8L2NvZGU+IGZsYWdzIGFuZCB0aGUKLSAgICAgKiAgIDxjb2RlPk5vZGVGaWx0ZXI8L2NvZGU+IGFyZSBub3QgY29uc2lkZXJlZCB3aGVuIHNldHRpbmcgdGhpcyB2YWx1ZTsKLSAgICAgKiAgIGFueSBub2RlIHR5cGUgd2lsbCBiZSBhY2NlcHRlZCBhcyB0aGUgPGNvZGU+cm9vdDwvY29kZT4uIFRoZQotICAgICAqICAgPGNvZGU+Y3VycmVudE5vZGU8L2NvZGU+IG9mIHRoZSA8Y29kZT5UcmVlV2Fsa2VyPC9jb2RlPiBpcwotICAgICAqICAgaW5pdGlhbGl6ZWQgdG8gdGhpcyBub2RlLCB3aGV0aGVyIG9yIG5vdCBpdCBpcyB2aXNpYmxlLiBUaGUKLSAgICAgKiAgIDxjb2RlPnJvb3Q8L2NvZGU+IGZ1bmN0aW9ucyBhcyBhIHN0b3BwaW5nIHBvaW50IGZvciB0cmF2ZXJzYWwKLSAgICAgKiAgIG1ldGhvZHMgdGhhdCBsb29rIHVwd2FyZCBpbiB0aGUgZG9jdW1lbnQgc3RydWN0dXJlLCBzdWNoIGFzCi0gICAgICogICA8Y29kZT5wYXJlbnROb2RlPC9jb2RlPiBhbmQgbmV4dE5vZGUuIFRoZSA8Y29kZT5yb290PC9jb2RlPiBtdXN0Ci0gICAgICogICBub3QgYmUgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICogQHBhcmFtIHdoYXRUb1Nob3cgVGhpcyBmbGFnIHNwZWNpZmllcyB3aGljaCBub2RlIHR5cGVzIG1heSBhcHBlYXIgaW4KLSAgICAgKiAgIHRoZSBsb2dpY2FsIHZpZXcgb2YgdGhlIHRyZWUgcHJlc2VudGVkIGJ5IHRoZQotICAgICAqICAgPGNvZGU+VHJlZVdhbGtlcjwvY29kZT4uIFNlZSB0aGUgZGVzY3JpcHRpb24gb2YKLSAgICAgKiAgIDxjb2RlPk5vZGVGaWx0ZXI8L2NvZGU+IGZvciB0aGUgc2V0IG9mIHBvc3NpYmxlIDxjb2RlPlNIT1dfPC9jb2RlPgotICAgICAqICAgdmFsdWVzLlRoZXNlIGZsYWdzIGNhbiBiZSBjb21iaW5lZCB1c2luZyA8Y29kZT5PUjwvY29kZT4uCi0gICAgICogQHBhcmFtIGZpbHRlciBUaGUgPGNvZGU+Tm9kZUZpbHRlcjwvY29kZT4gdG8gYmUgdXNlZCB3aXRoIHRoaXMKLSAgICAgKiAgIDxjb2RlPlRyZWVXYWxrZXI8L2NvZGU+LCBvciA8Y29kZT5udWxsPC9jb2RlPiB0byBpbmRpY2F0ZSBubyBmaWx0ZXIuCi0gICAgICogQHBhcmFtIGVudGl0eVJlZmVyZW5jZUV4cGFuc2lvbiBJZiB0aGlzIGZsYWcgaXMgZmFsc2UsIHRoZSBjb250ZW50cyBvZgotICAgICAqICAgPGNvZGU+RW50aXR5UmVmZXJlbmNlPC9jb2RlPiBub2RlcyBhcmUgbm90IHByZXNlbnRlZCBpbiB0aGUgbG9naWNhbAotICAgICAqICAgdmlldy4KLSAgICAgKiBAcmV0dXJuIFRoZSBuZXdseSBjcmVhdGVkIDxjb2RlPlRyZWVXYWxrZXI8L2NvZGU+LgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICAgTk9UX1NVUFBPUlRFRF9FUlI6IFJhaXNlZCBpZiB0aGUgc3BlY2lmaWVkIDxjb2RlPnJvb3Q8L2NvZGU+IGlzCi0gICAgICogICA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgVHJlZVdhbGtlciBjcmVhdGVUcmVlV2Fsa2VyKE5vZGUgcm9vdCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCB3aGF0VG9TaG93LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTm9kZUZpbHRlciBmaWx0ZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGVudGl0eVJlZmVyZW5jZUV4cGFuc2lvbikKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvdzNjL2RvbS90cmF2ZXJzYWwvTm9kZUZpbHRlci5qYXZhIGIvc3JjL29yZy93M2MvZG9tL3RyYXZlcnNhbC9Ob2RlRmlsdGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGU2ZjIyYjIuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy93M2MvZG9tL3RyYXZlcnNhbC9Ob2RlRmlsdGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNzMgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIFRoaXMgZmlsZSBpcyBhdmFpbGFibGUgdW5kZXIgYW5kIGdvdmVybmVkIGJ5IHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKLSAqIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICogSG93ZXZlciwgdGhlIGZvbGxvd2luZyBub3RpY2UgYWNjb21wYW5pZWQgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcwotICogZmlsZSBhbmQsIHBlciBpdHMgdGVybXMsIHNob3VsZCBub3QgYmUgcmVtb3ZlZDoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDAgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKLSAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQotICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCi0gKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKLSAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCi0gKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCi0gKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCi0gKiBQVVJQT1NFLgotICogU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCi0gKi8KLQotcGFja2FnZSBvcmcudzNjLmRvbS50cmF2ZXJzYWw7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotCi0vKioKLSAqIEZpbHRlcnMgYXJlIG9iamVjdHMgdGhhdCBrbm93IGhvdyB0byAiZmlsdGVyIG91dCIgbm9kZXMuIElmIGEKLSAqIDxjb2RlPk5vZGVJdGVyYXRvcjwvY29kZT4gb3IgPGNvZGU+VHJlZVdhbGtlcjwvY29kZT4gaXMgZ2l2ZW4gYQotICogPGNvZGU+Tm9kZUZpbHRlcjwvY29kZT4sIGl0IGFwcGxpZXMgdGhlIGZpbHRlciBiZWZvcmUgaXQgcmV0dXJucyB0aGUgbmV4dAotICogbm9kZS4gSWYgdGhlIGZpbHRlciBzYXlzIHRvIGFjY2VwdCB0aGUgbm9kZSwgdGhlIHRyYXZlcnNhbCBsb2dpYyByZXR1cm5zCi0gKiBpdDsgb3RoZXJ3aXNlLCB0cmF2ZXJzYWwgbG9va3MgZm9yIHRoZSBuZXh0IG5vZGUgYW5kIHByZXRlbmRzIHRoYXQgdGhlCi0gKiBub2RlIHRoYXQgd2FzIHJlamVjdGVkIHdhcyBub3QgdGhlcmUuCi0gKiA8cD5UaGUgRE9NIGRvZXMgbm90IHByb3ZpZGUgYW55IGZpbHRlcnMuIDxjb2RlPk5vZGVGaWx0ZXI8L2NvZGU+IGlzIGp1c3QgYW4KLSAqIGludGVyZmFjZSB0aGF0IHVzZXJzIGNhbiBpbXBsZW1lbnQgdG8gcHJvdmlkZSB0aGVpciBvd24gZmlsdGVycy4KLSAqIDxwPjxjb2RlPk5vZGVGaWx0ZXJzPC9jb2RlPiBkbyBub3QgbmVlZCB0byBrbm93IGhvdyB0byB0cmF2ZXJzZSBmcm9tIG5vZGUKLSAqIHRvIG5vZGUsIG5vciBkbyB0aGV5IG5lZWQgdG8ga25vdyBhbnl0aGluZyBhYm91dCB0aGUgZGF0YSBzdHJ1Y3R1cmUgdGhhdAotICogaXMgYmVpbmcgdHJhdmVyc2VkLiBUaGlzIG1ha2VzIGl0IHZlcnkgZWFzeSB0byB3cml0ZSBmaWx0ZXJzLCBzaW5jZSB0aGUKLSAqIG9ubHkgdGhpbmcgdGhleSBoYXZlIHRvIGtub3cgaG93IHRvIGRvIGlzIGV2YWx1YXRlIGEgc2luZ2xlIG5vZGUuIE9uZQotICogZmlsdGVyIG1heSBiZSB1c2VkIHdpdGggYSBudW1iZXIgb2YgZGlmZmVyZW50IGtpbmRzIG9mIHRyYXZlcnNhbHMsCi0gKiBlbmNvdXJhZ2luZyBjb2RlIHJldXNlLgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDAvUkVDLURPTS1MZXZlbC0yLVRyYXZlcnNhbC1SYW5nZS0yMDAwMTExMyc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDIgVHJhdmVyc2FsIGFuZCBSYW5nZSBTcGVjaWZpY2F0aW9uPC9hPi4KLSAqIEBzaW5jZSBET00gTGV2ZWwgMgotICovCi1wdWJsaWMgaW50ZXJmYWNlIE5vZGVGaWx0ZXIgewotICAgIC8vIENvbnN0YW50cyByZXR1cm5lZCBieSBhY2NlcHROb2RlCi0gICAgLyoqCi0gICAgICogQWNjZXB0IHRoZSBub2RlLiBOYXZpZ2F0aW9uIG1ldGhvZHMgZGVmaW5lZCBmb3IKLSAgICAgKiA8Y29kZT5Ob2RlSXRlcmF0b3I8L2NvZGU+IG9yIDxjb2RlPlRyZWVXYWxrZXI8L2NvZGU+IHdpbGwgcmV0dXJuIHRoaXMKLSAgICAgKiBub2RlLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgRklMVEVSX0FDQ0VQVCAgICAgICAgICAgICA9IDE7Ci0gICAgLyoqCi0gICAgICogUmVqZWN0IHRoZSBub2RlLiBOYXZpZ2F0aW9uIG1ldGhvZHMgZGVmaW5lZCBmb3IKLSAgICAgKiA8Y29kZT5Ob2RlSXRlcmF0b3I8L2NvZGU+IG9yIDxjb2RlPlRyZWVXYWxrZXI8L2NvZGU+IHdpbGwgbm90IHJldHVybgotICAgICAqIHRoaXMgbm9kZS4gRm9yIDxjb2RlPlRyZWVXYWxrZXI8L2NvZGU+LCB0aGUgY2hpbGRyZW4gb2YgdGhpcyBub2RlCi0gICAgICogd2lsbCBhbHNvIGJlIHJlamVjdGVkLiA8Y29kZT5Ob2RlSXRlcmF0b3JzPC9jb2RlPiB0cmVhdCB0aGlzIGFzIGEKLSAgICAgKiBzeW5vbnltIGZvciA8Y29kZT5GSUxURVJfU0tJUDwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBGSUxURVJfUkVKRUNUICAgICAgICAgICAgID0gMjsKLSAgICAvKioKLSAgICAgKiBTa2lwIHRoaXMgc2luZ2xlIG5vZGUuIE5hdmlnYXRpb24gbWV0aG9kcyBkZWZpbmVkIGZvcgotICAgICAqIDxjb2RlPk5vZGVJdGVyYXRvcjwvY29kZT4gb3IgPGNvZGU+VHJlZVdhbGtlcjwvY29kZT4gd2lsbCBub3QgcmV0dXJuCi0gICAgICogdGhpcyBub2RlLiBGb3IgYm90aCA8Y29kZT5Ob2RlSXRlcmF0b3I8L2NvZGU+IGFuZAotICAgICAqIDxjb2RlPlRyZWVXYWxrZXI8L2NvZGU+LCB0aGUgY2hpbGRyZW4gb2YgdGhpcyBub2RlIHdpbGwgc3RpbGwgYmUKLSAgICAgKiBjb25zaWRlcmVkLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgRklMVEVSX1NLSVAgICAgICAgICAgICAgICA9IDM7Ci0KLSAgICAvLyBDb25zdGFudHMgZm9yIHdoYXRUb1Nob3cKLSAgICAvKioKLSAgICAgKiBTaG93IGFsbCA8Y29kZT5Ob2RlczwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0hPV19BTEwgICAgICAgICAgICAgICAgICA9IDB4RkZGRkZGRkY7Ci0gICAgLyoqCi0gICAgICogU2hvdyA8Y29kZT5FbGVtZW50PC9jb2RlPiBub2Rlcy4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTSE9XX0VMRU1FTlQgICAgICAgICAgICAgID0gMHgwMDAwMDAwMTsKLSAgICAvKioKLSAgICAgKiBTaG93IDxjb2RlPkF0dHI8L2NvZGU+IG5vZGVzLiBUaGlzIGlzIG1lYW5pbmdmdWwgb25seSB3aGVuIGNyZWF0aW5nIGFuCi0gICAgICogPGNvZGU+Tm9kZUl0ZXJhdG9yPC9jb2RlPiBvciA8Y29kZT5UcmVlV2Fsa2VyPC9jb2RlPiB3aXRoIGFuCi0gICAgICogYXR0cmlidXRlIG5vZGUgYXMgaXRzIDxjb2RlPnJvb3Q8L2NvZGU+OyBpbiB0aGlzIGNhc2UsIGl0IG1lYW5zIHRoYXQKLSAgICAgKiB0aGUgYXR0cmlidXRlIG5vZGUgd2lsbCBhcHBlYXIgaW4gdGhlIGZpcnN0IHBvc2l0aW9uIG9mIHRoZSBpdGVyYXRpb24KLSAgICAgKiBvciB0cmF2ZXJzYWwuIFNpbmNlIGF0dHJpYnV0ZXMgYXJlIG5ldmVyIGNoaWxkcmVuIG9mIG90aGVyIG5vZGVzLAotICAgICAqIHRoZXkgZG8gbm90IGFwcGVhciB3aGVuIHRyYXZlcnNpbmcgb3ZlciB0aGUgZG9jdW1lbnQgdHJlZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTSE9XX0FUVFJJQlVURSAgICAgICAgICAgID0gMHgwMDAwMDAwMjsKLSAgICAvKioKLSAgICAgKiBTaG93IDxjb2RlPlRleHQ8L2NvZGU+IG5vZGVzLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNIT1dfVEVYVCAgICAgICAgICAgICAgICAgPSAweDAwMDAwMDA0OwotICAgIC8qKgotICAgICAqIFNob3cgPGNvZGU+Q0RBVEFTZWN0aW9uPC9jb2RlPiBub2Rlcy4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTSE9XX0NEQVRBX1NFQ1RJT04gICAgICAgID0gMHgwMDAwMDAwODsKLSAgICAvKioKLSAgICAgKiBTaG93IDxjb2RlPkVudGl0eVJlZmVyZW5jZTwvY29kZT4gbm9kZXMuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0hPV19FTlRJVFlfUkVGRVJFTkNFICAgICA9IDB4MDAwMDAwMTA7Ci0gICAgLyoqCi0gICAgICogU2hvdyA8Y29kZT5FbnRpdHk8L2NvZGU+IG5vZGVzLiBUaGlzIGlzIG1lYW5pbmdmdWwgb25seSB3aGVuIGNyZWF0aW5nCi0gICAgICogYW4gPGNvZGU+Tm9kZUl0ZXJhdG9yPC9jb2RlPiBvciA8Y29kZT5UcmVlV2Fsa2VyPC9jb2RlPiB3aXRoIGFuCi0gICAgICogPGNvZGU+RW50aXR5PC9jb2RlPiBub2RlIGFzIGl0cyA8Y29kZT5yb290PC9jb2RlPjsgaW4gdGhpcyBjYXNlLCBpdAotICAgICAqIG1lYW5zIHRoYXQgdGhlIDxjb2RlPkVudGl0eTwvY29kZT4gbm9kZSB3aWxsIGFwcGVhciBpbiB0aGUgZmlyc3QKLSAgICAgKiBwb3NpdGlvbiBvZiB0aGUgdHJhdmVyc2FsLiBTaW5jZSBlbnRpdGllcyBhcmUgbm90IHBhcnQgb2YgdGhlCi0gICAgICogZG9jdW1lbnQgdHJlZSwgdGhleSBkbyBub3QgYXBwZWFyIHdoZW4gdHJhdmVyc2luZyBvdmVyIHRoZSBkb2N1bWVudAotICAgICAqIHRyZWUuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0hPV19FTlRJVFkgICAgICAgICAgICAgICA9IDB4MDAwMDAwMjA7Ci0gICAgLyoqCi0gICAgICogU2hvdyA8Y29kZT5Qcm9jZXNzaW5nSW5zdHJ1Y3Rpb248L2NvZGU+IG5vZGVzLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNIT1dfUFJPQ0VTU0lOR19JTlNUUlVDVElPTiA9IDB4MDAwMDAwNDA7Ci0gICAgLyoqCi0gICAgICogU2hvdyA8Y29kZT5Db21tZW50PC9jb2RlPiBub2Rlcy4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTSE9XX0NPTU1FTlQgICAgICAgICAgICAgID0gMHgwMDAwMDA4MDsKLSAgICAvKioKLSAgICAgKiBTaG93IDxjb2RlPkRvY3VtZW50PC9jb2RlPiBub2Rlcy4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTSE9XX0RPQ1VNRU5UICAgICAgICAgICAgID0gMHgwMDAwMDEwMDsKLSAgICAvKioKLSAgICAgKiBTaG93IDxjb2RlPkRvY3VtZW50VHlwZTwvY29kZT4gbm9kZXMuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0hPV19ET0NVTUVOVF9UWVBFICAgICAgICA9IDB4MDAwMDAyMDA7Ci0gICAgLyoqCi0gICAgICogU2hvdyA8Y29kZT5Eb2N1bWVudEZyYWdtZW50PC9jb2RlPiBub2Rlcy4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTSE9XX0RPQ1VNRU5UX0ZSQUdNRU5UICAgID0gMHgwMDAwMDQwMDsKLSAgICAvKioKLSAgICAgKiBTaG93IDxjb2RlPk5vdGF0aW9uPC9jb2RlPiBub2Rlcy4gVGhpcyBpcyBtZWFuaW5nZnVsIG9ubHkgd2hlbiBjcmVhdGluZwotICAgICAqIGFuIDxjb2RlPk5vZGVJdGVyYXRvcjwvY29kZT4gb3IgPGNvZGU+VHJlZVdhbGtlcjwvY29kZT4gd2l0aCBhCi0gICAgICogPGNvZGU+Tm90YXRpb248L2NvZGU+IG5vZGUgYXMgaXRzIDxjb2RlPnJvb3Q8L2NvZGU+OyBpbiB0aGlzIGNhc2UsIGl0Ci0gICAgICogbWVhbnMgdGhhdCB0aGUgPGNvZGU+Tm90YXRpb248L2NvZGU+IG5vZGUgd2lsbCBhcHBlYXIgaW4gdGhlIGZpcnN0Ci0gICAgICogcG9zaXRpb24gb2YgdGhlIHRyYXZlcnNhbC4gU2luY2Ugbm90YXRpb25zIGFyZSBub3QgcGFydCBvZiB0aGUKLSAgICAgKiBkb2N1bWVudCB0cmVlLCB0aGV5IGRvIG5vdCBhcHBlYXIgd2hlbiB0cmF2ZXJzaW5nIG92ZXIgdGhlIGRvY3VtZW50Ci0gICAgICogdHJlZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTSE9XX05PVEFUSU9OICAgICAgICAgICAgID0gMHgwMDAwMDgwMDsKLQotICAgIC8qKgotICAgICAqIFRlc3Qgd2hldGhlciBhIHNwZWNpZmllZCBub2RlIGlzIHZpc2libGUgaW4gdGhlIGxvZ2ljYWwgdmlldyBvZiBhCi0gICAgICogPGNvZGU+VHJlZVdhbGtlcjwvY29kZT4gb3IgPGNvZGU+Tm9kZUl0ZXJhdG9yPC9jb2RlPi4gVGhpcyBmdW5jdGlvbgotICAgICAqIHdpbGwgYmUgY2FsbGVkIGJ5IHRoZSBpbXBsZW1lbnRhdGlvbiBvZiA8Y29kZT5UcmVlV2Fsa2VyPC9jb2RlPiBhbmQKLSAgICAgKiA8Y29kZT5Ob2RlSXRlcmF0b3I8L2NvZGU+OyBpdCBpcyBub3Qgbm9ybWFsbHkgY2FsbGVkIGRpcmVjdGx5IGZyb20KLSAgICAgKiB1c2VyIGNvZGUuIChUaG91Z2ggeW91IGNvdWxkIGRvIHNvIGlmIHlvdSB3YW50ZWQgdG8gdXNlIHRoZSBzYW1lCi0gICAgICogZmlsdGVyIHRvIGd1aWRlIHlvdXIgb3duIGFwcGxpY2F0aW9uIGxvZ2ljLikKLSAgICAgKiBAcGFyYW0gbiBUaGUgbm9kZSB0byBjaGVjayB0byBzZWUgaWYgaXQgcGFzc2VzIHRoZSBmaWx0ZXIgb3Igbm90LgotICAgICAqIEByZXR1cm4gQSBjb25zdGFudCB0byBkZXRlcm1pbmUgd2hldGhlciB0aGUgbm9kZSBpcyBhY2NlcHRlZCwKLSAgICAgKiAgIHJlamVjdGVkLCBvciBza2lwcGVkLCBhcyBkZWZpbmVkIGFib3ZlLgotICAgICAqLwotICAgIHB1YmxpYyBzaG9ydCBhY2NlcHROb2RlKE5vZGUgbik7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvdzNjL2RvbS90cmF2ZXJzYWwvTm9kZUl0ZXJhdG9yLmphdmEgYi9zcmMvb3JnL3czYy9kb20vdHJhdmVyc2FsL05vZGVJdGVyYXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwZjZhZWJmLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS90cmF2ZXJzYWwvTm9kZUl0ZXJhdG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMzggKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIFRoaXMgZmlsZSBpcyBhdmFpbGFibGUgdW5kZXIgYW5kIGdvdmVybmVkIGJ5IHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKLSAqIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICogSG93ZXZlciwgdGhlIGZvbGxvd2luZyBub3RpY2UgYWNjb21wYW5pZWQgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcwotICogZmlsZSBhbmQsIHBlciBpdHMgdGVybXMsIHNob3VsZCBub3QgYmUgcmVtb3ZlZDoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDAgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKLSAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQotICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCi0gKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKLSAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCi0gKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCi0gKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCi0gKiBQVVJQT1NFLgotICogU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCi0gKi8KLQotcGFja2FnZSBvcmcudzNjLmRvbS50cmF2ZXJzYWw7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotaW1wb3J0IG9yZy53M2MuZG9tLkRPTUV4Y2VwdGlvbjsKLQotLyoqCi0gKiA8Y29kZT5Ob2RlSXRlcmF0b3JzPC9jb2RlPiBhcmUgdXNlZCB0byBzdGVwIHRocm91Z2ggYSBzZXQgb2Ygbm9kZXMsIGUuZy4KLSAqIHRoZSBzZXQgb2Ygbm9kZXMgaW4gYSA8Y29kZT5Ob2RlTGlzdDwvY29kZT4sIHRoZSBkb2N1bWVudCBzdWJ0cmVlCi0gKiBnb3Zlcm5lZCBieSBhIHBhcnRpY3VsYXIgPGNvZGU+Tm9kZTwvY29kZT4sIHRoZSByZXN1bHRzIG9mIGEgcXVlcnksIG9yCi0gKiBhbnkgb3RoZXIgc2V0IG9mIG5vZGVzLiBUaGUgc2V0IG9mIG5vZGVzIHRvIGJlIGl0ZXJhdGVkIGlzIGRldGVybWluZWQgYnkKLSAqIHRoZSBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgPGNvZGU+Tm9kZUl0ZXJhdG9yPC9jb2RlPi4gRE9NIExldmVsIDIKLSAqIHNwZWNpZmllcyBhIHNpbmdsZSA8Y29kZT5Ob2RlSXRlcmF0b3I8L2NvZGU+IGltcGxlbWVudGF0aW9uIGZvcgotICogZG9jdW1lbnQtb3JkZXIgdHJhdmVyc2FsIG9mIGEgZG9jdW1lbnQgc3VidHJlZS4gSW5zdGFuY2VzIG9mIHRoZXNlCi0gKiA8Y29kZT5Ob2RlSXRlcmF0b3JzPC9jb2RlPiBhcmUgY3JlYXRlZCBieSBjYWxsaW5nCi0gKiA8Y29kZT5Eb2N1bWVudFRyYXZlcnNhbDwvY29kZT48Y29kZT4uY3JlYXRlTm9kZUl0ZXJhdG9yKCk8L2NvZGU+LgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDAvUkVDLURPTS1MZXZlbC0yLVRyYXZlcnNhbC1SYW5nZS0yMDAwMTExMyc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDIgVHJhdmVyc2FsIGFuZCBSYW5nZSBTcGVjaWZpY2F0aW9uPC9hPi4KLSAqIEBzaW5jZSBET00gTGV2ZWwgMgotICovCi1wdWJsaWMgaW50ZXJmYWNlIE5vZGVJdGVyYXRvciB7Ci0gICAgLyoqCi0gICAgICogVGhlIHJvb3Qgbm9kZSBvZiB0aGUgPGNvZGU+Tm9kZUl0ZXJhdG9yPC9jb2RlPiwgYXMgc3BlY2lmaWVkIHdoZW4gaXQKLSAgICAgKiB3YXMgY3JlYXRlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgTm9kZSBnZXRSb290KCk7Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIGF0dHJpYnV0ZSBkZXRlcm1pbmVzIHdoaWNoIG5vZGUgdHlwZXMgYXJlIHByZXNlbnRlZCB2aWEgdGhlCi0gICAgICogPGNvZGU+Tm9kZUl0ZXJhdG9yPC9jb2RlPi4gVGhlIGF2YWlsYWJsZSBzZXQgb2YgY29uc3RhbnRzIGlzIGRlZmluZWQKLSAgICAgKiBpbiB0aGUgPGNvZGU+Tm9kZUZpbHRlcjwvY29kZT4gaW50ZXJmYWNlLiAgTm9kZXMgbm90IGFjY2VwdGVkIGJ5Ci0gICAgICogPGNvZGU+d2hhdFRvU2hvdzwvY29kZT4gd2lsbCBiZSBza2lwcGVkLCBidXQgdGhlaXIgY2hpbGRyZW4gbWF5IHN0aWxsCi0gICAgICogYmUgY29uc2lkZXJlZC4gTm90ZSB0aGF0IHRoaXMgc2tpcCB0YWtlcyBwcmVjZWRlbmNlIG92ZXIgdGhlIGZpbHRlciwKLSAgICAgKiBpZiBhbnkuCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRXaGF0VG9TaG93KCk7Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgPGNvZGU+Tm9kZUZpbHRlcjwvY29kZT4gdXNlZCB0byBzY3JlZW4gbm9kZXMuCi0gICAgICovCi0gICAgcHVibGljIE5vZGVGaWx0ZXIgZ2V0RmlsdGVyKCk7Ci0KLSAgICAvKioKLSAgICAgKiAgVGhlIHZhbHVlIG9mIHRoaXMgZmxhZyBkZXRlcm1pbmVzIHdoZXRoZXIgdGhlIGNoaWxkcmVuIG9mIGVudGl0eQotICAgICAqIHJlZmVyZW5jZSBub2RlcyBhcmUgdmlzaWJsZSB0byB0aGUgPGNvZGU+Tm9kZUl0ZXJhdG9yPC9jb2RlPi4gSWYKLSAgICAgKiBmYWxzZSwgdGhlc2UgY2hpbGRyZW4gIGFuZCB0aGVpciBkZXNjZW5kYW50cyB3aWxsIGJlIHJlamVjdGVkLiBOb3RlCi0gICAgICogdGhhdCB0aGlzIHJlamVjdGlvbiB0YWtlcyBwcmVjZWRlbmNlIG92ZXIgPGNvZGU+d2hhdFRvU2hvdzwvY29kZT4gYW5kCi0gICAgICogdGhlIGZpbHRlci4gQWxzbyBub3RlIHRoYXQgdGhpcyBpcyBjdXJyZW50bHkgdGhlIG9ubHkgc2l0dWF0aW9uIHdoZXJlCi0gICAgICogPGNvZGU+Tm9kZUl0ZXJhdG9yczwvY29kZT4gbWF5IHJlamVjdCBhIGNvbXBsZXRlIHN1YnRyZWUgcmF0aGVyIHRoYW4KLSAgICAgKiBza2lwcGluZyBpbmRpdmlkdWFsIG5vZGVzLgotICAgICAqIDxicj4KLSAgICAgKiA8YnI+IFRvIHByb2R1Y2UgYSB2aWV3IG9mIHRoZSBkb2N1bWVudCB0aGF0IGhhcyBlbnRpdHkgcmVmZXJlbmNlcwotICAgICAqIGV4cGFuZGVkIGFuZCBkb2VzIG5vdCBleHBvc2UgdGhlIGVudGl0eSByZWZlcmVuY2Ugbm9kZSBpdHNlbGYsIHVzZQotICAgICAqIHRoZSA8Y29kZT53aGF0VG9TaG93PC9jb2RlPiBmbGFncyB0byBoaWRlIHRoZSBlbnRpdHkgcmVmZXJlbmNlIG5vZGUKLSAgICAgKiBhbmQgc2V0IDxjb2RlPmV4cGFuZEVudGl0eVJlZmVyZW5jZXM8L2NvZGU+IHRvIHRydWUgd2hlbiBjcmVhdGluZyB0aGUKLSAgICAgKiA8Y29kZT5Ob2RlSXRlcmF0b3I8L2NvZGU+LiBUbyBwcm9kdWNlIGEgdmlldyBvZiB0aGUgZG9jdW1lbnQgdGhhdCBoYXMKLSAgICAgKiBlbnRpdHkgcmVmZXJlbmNlIG5vZGVzIGJ1dCBubyBlbnRpdHkgZXhwYW5zaW9uLCB1c2UgdGhlCi0gICAgICogPGNvZGU+d2hhdFRvU2hvdzwvY29kZT4gZmxhZ3MgdG8gc2hvdyB0aGUgZW50aXR5IHJlZmVyZW5jZSBub2RlIGFuZAotICAgICAqIHNldCA8Y29kZT5leHBhbmRFbnRpdHlSZWZlcmVuY2VzPC9jb2RlPiB0byBmYWxzZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXRFeHBhbmRFbnRpdHlSZWZlcmVuY2VzKCk7Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBuZXh0IG5vZGUgaW4gdGhlIHNldCBhbmQgYWR2YW5jZXMgdGhlIHBvc2l0aW9uIG9mIHRoZQotICAgICAqIDxjb2RlPk5vZGVJdGVyYXRvcjwvY29kZT4gaW4gdGhlIHNldC4gQWZ0ZXIgYQotICAgICAqIDxjb2RlPk5vZGVJdGVyYXRvcjwvY29kZT4gaXMgY3JlYXRlZCwgdGhlIGZpcnN0IGNhbGwgdG8KLSAgICAgKiA8Y29kZT5uZXh0Tm9kZSgpPC9jb2RlPiByZXR1cm5zIHRoZSBmaXJzdCBub2RlIGluIHRoZSBzZXQuCi0gICAgICogQHJldHVybiBUaGUgbmV4dCA8Y29kZT5Ob2RlPC9jb2RlPiBpbiB0aGUgc2V0IGJlaW5nIGl0ZXJhdGVkIG92ZXIsIG9yCi0gICAgICogICA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGVyZSBhcmUgbm8gbW9yZSBtZW1iZXJzIGluIHRoYXQgc2V0LgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBJTlZBTElEX1NUQVRFX0VSUjogUmFpc2VkIGlmIHRoaXMgbWV0aG9kIGlzIGNhbGxlZCBhZnRlciB0aGUKLSAgICAgKiAgIDxjb2RlPmRldGFjaDwvY29kZT4gbWV0aG9kIHdhcyBpbnZva2VkLgotICAgICAqLwotICAgIHB1YmxpYyBOb2RlIG5leHROb2RlKCkKLSAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgcHJldmlvdXMgbm9kZSBpbiB0aGUgc2V0IGFuZCBtb3ZlcyB0aGUgcG9zaXRpb24gb2YgdGhlCi0gICAgICogPGNvZGU+Tm9kZUl0ZXJhdG9yPC9jb2RlPiBiYWNrd2FyZHMgaW4gdGhlIHNldC4KLSAgICAgKiBAcmV0dXJuIFRoZSBwcmV2aW91cyA8Y29kZT5Ob2RlPC9jb2RlPiBpbiB0aGUgc2V0IGJlaW5nIGl0ZXJhdGVkIG92ZXIsCi0gICAgICogICBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGVyZSBhcmUgbm8gbW9yZSBtZW1iZXJzIGluIHRoYXQgc2V0LgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBJTlZBTElEX1NUQVRFX0VSUjogUmFpc2VkIGlmIHRoaXMgbWV0aG9kIGlzIGNhbGxlZCBhZnRlciB0aGUKLSAgICAgKiAgIDxjb2RlPmRldGFjaDwvY29kZT4gbWV0aG9kIHdhcyBpbnZva2VkLgotICAgICAqLwotICAgIHB1YmxpYyBOb2RlIHByZXZpb3VzTm9kZSgpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBEZXRhY2hlcyB0aGUgPGNvZGU+Tm9kZUl0ZXJhdG9yPC9jb2RlPiBmcm9tIHRoZSBzZXQgd2hpY2ggaXQgaXRlcmF0ZWQKLSAgICAgKiBvdmVyLCByZWxlYXNpbmcgYW55IGNvbXB1dGF0aW9uYWwgcmVzb3VyY2VzIGFuZCBwbGFjaW5nIHRoZQotICAgICAqIDxjb2RlPk5vZGVJdGVyYXRvcjwvY29kZT4gaW4gdGhlIElOVkFMSUQgc3RhdGUuIEFmdGVyCi0gICAgICogPGNvZGU+ZGV0YWNoPC9jb2RlPiBoYXMgYmVlbiBpbnZva2VkLCBjYWxscyB0byA8Y29kZT5uZXh0Tm9kZTwvY29kZT4KLSAgICAgKiBvciA8Y29kZT5wcmV2aW91c05vZGU8L2NvZGU+IHdpbGwgcmFpc2UgdGhlIGV4Y2VwdGlvbgotICAgICAqIElOVkFMSURfU1RBVEVfRVJSLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGRldGFjaCgpOwotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL3czYy9kb20vdHJhdmVyc2FsL1RyZWVXYWxrZXIuamF2YSBiL3NyYy9vcmcvdzNjL2RvbS90cmF2ZXJzYWwvVHJlZVdhbGtlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmMDg3NmU1Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS90cmF2ZXJzYWwvVHJlZVdhbGtlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjA4ICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBUaGlzIGZpbGUgaXMgYXZhaWxhYmxlIHVuZGVyIGFuZCBnb3Zlcm5lZCBieSB0aGUgR05VIEdlbmVyYWwgUHVibGljCi0gKiBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqIEhvd2V2ZXIsIHRoZSBmb2xsb3dpbmcgbm90aWNlIGFjY29tcGFuaWVkIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIG9mIHRoaXMKLSAqIGZpbGUgYW5kLCBwZXIgaXRzIHRlcm1zLCBzaG91bGQgbm90IGJlIHJlbW92ZWQ6Ci0gKgotICogQ29weXJpZ2h0IChjKSAyMDAwIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKLSAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAotICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCi0gKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQotICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgotICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgotICogUFVSUE9TRS4KLSAqIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgotICovCi0KLXBhY2thZ2Ugb3JnLnczYy5kb20udHJhdmVyc2FsOwotCi1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcudzNjLmRvbS5ET01FeGNlcHRpb247Ci0KLS8qKgotICogPGNvZGU+VHJlZVdhbGtlcjwvY29kZT4gb2JqZWN0cyBhcmUgdXNlZCB0byBuYXZpZ2F0ZSBhIGRvY3VtZW50IHRyZWUgb3IKLSAqIHN1YnRyZWUgdXNpbmcgdGhlIHZpZXcgb2YgdGhlIGRvY3VtZW50IGRlZmluZWQgYnkgdGhlaXIKLSAqIDxjb2RlPndoYXRUb1Nob3c8L2NvZGU+IGZsYWdzIGFuZCBmaWx0ZXIgKGlmIGFueSkuIEFueSBmdW5jdGlvbiB3aGljaAotICogcGVyZm9ybXMgbmF2aWdhdGlvbiB1c2luZyBhIDxjb2RlPlRyZWVXYWxrZXI8L2NvZGU+IHdpbGwgYXV0b21hdGljYWxseQotICogc3VwcG9ydCBhbnkgdmlldyBkZWZpbmVkIGJ5IGEgPGNvZGU+VHJlZVdhbGtlcjwvY29kZT4uCi0gKiA8cD5PbWl0dGluZyBub2RlcyBmcm9tIHRoZSBsb2dpY2FsIHZpZXcgb2YgYSBzdWJ0cmVlIGNhbiByZXN1bHQgaW4gYQotICogc3RydWN0dXJlIHRoYXQgaXMgc3Vic3RhbnRpYWxseSBkaWZmZXJlbnQgZnJvbSB0aGUgc2FtZSBzdWJ0cmVlIGluIHRoZQotICogY29tcGxldGUsIHVuZmlsdGVyZWQgZG9jdW1lbnQuIE5vZGVzIHRoYXQgYXJlIHNpYmxpbmdzIGluIHRoZQotICogPGNvZGU+VHJlZVdhbGtlcjwvY29kZT4gdmlldyBtYXkgYmUgY2hpbGRyZW4gb2YgZGlmZmVyZW50LCB3aWRlbHkKLSAqIHNlcGFyYXRlZCBub2RlcyBpbiB0aGUgb3JpZ2luYWwgdmlldy4gRm9yIGluc3RhbmNlLCBjb25zaWRlciBhCi0gKiA8Y29kZT5Ob2RlRmlsdGVyPC9jb2RlPiB0aGF0IHNraXBzIGFsbCBub2RlcyBleGNlcHQgZm9yIFRleHQgbm9kZXMgYW5kCi0gKiB0aGUgcm9vdCBub2RlIG9mIGEgZG9jdW1lbnQuIEluIHRoZSBsb2dpY2FsIHZpZXcgdGhhdCByZXN1bHRzLCBhbGwgdGV4dAotICogbm9kZXMgd2lsbCBiZSBzaWJsaW5ncyBhbmQgYXBwZWFyIGFzIGRpcmVjdCBjaGlsZHJlbiBvZiB0aGUgcm9vdCBub2RlLCBubwotICogbWF0dGVyIGhvdyBkZWVwbHkgbmVzdGVkIHRoZSBzdHJ1Y3R1cmUgb2YgdGhlIG9yaWdpbmFsIGRvY3VtZW50LgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDAvUkVDLURPTS1MZXZlbC0yLVRyYXZlcnNhbC1SYW5nZS0yMDAwMTExMyc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDIgVHJhdmVyc2FsIGFuZCBSYW5nZSBTcGVjaWZpY2F0aW9uPC9hPi4KLSAqIEBzaW5jZSBET00gTGV2ZWwgMgotICovCi1wdWJsaWMgaW50ZXJmYWNlIFRyZWVXYWxrZXIgewotICAgIC8qKgotICAgICAqIFRoZSA8Y29kZT5yb290PC9jb2RlPiBub2RlIG9mIHRoZSA8Y29kZT5UcmVlV2Fsa2VyPC9jb2RlPiwgYXMgc3BlY2lmaWVkCi0gICAgICogd2hlbiBpdCB3YXMgY3JlYXRlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgTm9kZSBnZXRSb290KCk7Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIGF0dHJpYnV0ZSBkZXRlcm1pbmVzIHdoaWNoIG5vZGUgdHlwZXMgYXJlIHByZXNlbnRlZCB2aWEgdGhlCi0gICAgICogPGNvZGU+VHJlZVdhbGtlcjwvY29kZT4uIFRoZSBhdmFpbGFibGUgc2V0IG9mIGNvbnN0YW50cyBpcyBkZWZpbmVkIGluCi0gICAgICogdGhlIDxjb2RlPk5vZGVGaWx0ZXI8L2NvZGU+IGludGVyZmFjZS4gIE5vZGVzIG5vdCBhY2NlcHRlZCBieQotICAgICAqIDxjb2RlPndoYXRUb1Nob3c8L2NvZGU+IHdpbGwgYmUgc2tpcHBlZCwgYnV0IHRoZWlyIGNoaWxkcmVuIG1heSBzdGlsbAotICAgICAqIGJlIGNvbnNpZGVyZWQuIE5vdGUgdGhhdCB0aGlzIHNraXAgdGFrZXMgcHJlY2VkZW5jZSBvdmVyIHRoZSBmaWx0ZXIsCi0gICAgICogaWYgYW55LgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0V2hhdFRvU2hvdygpOwotCi0gICAgLyoqCi0gICAgICogVGhlIGZpbHRlciB1c2VkIHRvIHNjcmVlbiBub2Rlcy4KLSAgICAgKi8KLSAgICBwdWJsaWMgTm9kZUZpbHRlciBnZXRGaWx0ZXIoKTsKLQotICAgIC8qKgotICAgICAqIFRoZSB2YWx1ZSBvZiB0aGlzIGZsYWcgZGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBjaGlsZHJlbiBvZiBlbnRpdHkKLSAgICAgKiByZWZlcmVuY2Ugbm9kZXMgYXJlIHZpc2libGUgdG8gdGhlIDxjb2RlPlRyZWVXYWxrZXI8L2NvZGU+LiBJZiBmYWxzZSwKLSAgICAgKiB0aGVzZSBjaGlsZHJlbiAgYW5kIHRoZWlyIGRlc2NlbmRhbnRzIHdpbGwgYmUgcmVqZWN0ZWQuIE5vdGUgdGhhdAotICAgICAqIHRoaXMgcmVqZWN0aW9uIHRha2VzIHByZWNlZGVuY2Ugb3ZlciA8Y29kZT53aGF0VG9TaG93PC9jb2RlPiBhbmQgdGhlCi0gICAgICogZmlsdGVyLCBpZiBhbnkuCi0gICAgICogPGJyPiBUbyBwcm9kdWNlIGEgdmlldyBvZiB0aGUgZG9jdW1lbnQgdGhhdCBoYXMgZW50aXR5IHJlZmVyZW5jZXMKLSAgICAgKiBleHBhbmRlZCBhbmQgZG9lcyBub3QgZXhwb3NlIHRoZSBlbnRpdHkgcmVmZXJlbmNlIG5vZGUgaXRzZWxmLCB1c2UKLSAgICAgKiB0aGUgPGNvZGU+d2hhdFRvU2hvdzwvY29kZT4gZmxhZ3MgdG8gaGlkZSB0aGUgZW50aXR5IHJlZmVyZW5jZSBub2RlCi0gICAgICogYW5kIHNldCA8Y29kZT5leHBhbmRFbnRpdHlSZWZlcmVuY2VzPC9jb2RlPiB0byB0cnVlIHdoZW4gY3JlYXRpbmcgdGhlCi0gICAgICogPGNvZGU+VHJlZVdhbGtlcjwvY29kZT4uIFRvIHByb2R1Y2UgYSB2aWV3IG9mIHRoZSBkb2N1bWVudCB0aGF0IGhhcwotICAgICAqIGVudGl0eSByZWZlcmVuY2Ugbm9kZXMgYnV0IG5vIGVudGl0eSBleHBhbnNpb24sIHVzZSB0aGUKLSAgICAgKiA8Y29kZT53aGF0VG9TaG93PC9jb2RlPiBmbGFncyB0byBzaG93IHRoZSBlbnRpdHkgcmVmZXJlbmNlIG5vZGUgYW5kCi0gICAgICogc2V0IDxjb2RlPmV4cGFuZEVudGl0eVJlZmVyZW5jZXM8L2NvZGU+IHRvIGZhbHNlLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGdldEV4cGFuZEVudGl0eVJlZmVyZW5jZXMoKTsKLQotICAgIC8qKgotICAgICAqIFRoZSBub2RlIGF0IHdoaWNoIHRoZSA8Y29kZT5UcmVlV2Fsa2VyPC9jb2RlPiBpcyBjdXJyZW50bHkgcG9zaXRpb25lZC4KLSAgICAgKiA8YnI+QWx0ZXJhdGlvbnMgdG8gdGhlIERPTSB0cmVlIG1heSBjYXVzZSB0aGUgY3VycmVudCBub2RlIHRvIG5vIGxvbmdlcgotICAgICAqIGJlIGFjY2VwdGVkIGJ5IHRoZSA8Y29kZT5UcmVlV2Fsa2VyPC9jb2RlPidzIGFzc29jaWF0ZWQgZmlsdGVyLgotICAgICAqIDxjb2RlPmN1cnJlbnROb2RlPC9jb2RlPiBtYXkgYWxzbyBiZSBleHBsaWNpdGx5IHNldCB0byBhbnkgbm9kZSwKLSAgICAgKiB3aGV0aGVyIG9yIG5vdCBpdCBpcyB3aXRoaW4gdGhlIHN1YnRyZWUgc3BlY2lmaWVkIGJ5IHRoZQotICAgICAqIDxjb2RlPnJvb3Q8L2NvZGU+IG5vZGUgb3Igd291bGQgYmUgYWNjZXB0ZWQgYnkgdGhlIGZpbHRlciBhbmQKLSAgICAgKiA8Y29kZT53aGF0VG9TaG93PC9jb2RlPiBmbGFncy4gRnVydGhlciB0cmF2ZXJzYWwgb2NjdXJzIHJlbGF0aXZlIHRvCi0gICAgICogPGNvZGU+Y3VycmVudE5vZGU8L2NvZGU+IGV2ZW4gaWYgaXQgaXMgbm90IHBhcnQgb2YgdGhlIGN1cnJlbnQgdmlldywKLSAgICAgKiBieSBhcHBseWluZyB0aGUgZmlsdGVycyBpbiB0aGUgcmVxdWVzdGVkIGRpcmVjdGlvbjsgaWYgbm8gdHJhdmVyc2FsCi0gICAgICogaXMgcG9zc2libGUsIDxjb2RlPmN1cnJlbnROb2RlPC9jb2RlPiBpcyBub3QgY2hhbmdlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgTm9kZSBnZXRDdXJyZW50Tm9kZSgpOwotICAgIC8qKgotICAgICAqIFRoZSBub2RlIGF0IHdoaWNoIHRoZSA8Y29kZT5UcmVlV2Fsa2VyPC9jb2RlPiBpcyBjdXJyZW50bHkgcG9zaXRpb25lZC4KLSAgICAgKiA8YnI+QWx0ZXJhdGlvbnMgdG8gdGhlIERPTSB0cmVlIG1heSBjYXVzZSB0aGUgY3VycmVudCBub2RlIHRvIG5vIGxvbmdlcgotICAgICAqIGJlIGFjY2VwdGVkIGJ5IHRoZSA8Y29kZT5UcmVlV2Fsa2VyPC9jb2RlPidzIGFzc29jaWF0ZWQgZmlsdGVyLgotICAgICAqIDxjb2RlPmN1cnJlbnROb2RlPC9jb2RlPiBtYXkgYWxzbyBiZSBleHBsaWNpdGx5IHNldCB0byBhbnkgbm9kZSwKLSAgICAgKiB3aGV0aGVyIG9yIG5vdCBpdCBpcyB3aXRoaW4gdGhlIHN1YnRyZWUgc3BlY2lmaWVkIGJ5IHRoZQotICAgICAqIDxjb2RlPnJvb3Q8L2NvZGU+IG5vZGUgb3Igd291bGQgYmUgYWNjZXB0ZWQgYnkgdGhlIGZpbHRlciBhbmQKLSAgICAgKiA8Y29kZT53aGF0VG9TaG93PC9jb2RlPiBmbGFncy4gRnVydGhlciB0cmF2ZXJzYWwgb2NjdXJzIHJlbGF0aXZlIHRvCi0gICAgICogPGNvZGU+Y3VycmVudE5vZGU8L2NvZGU+IGV2ZW4gaWYgaXQgaXMgbm90IHBhcnQgb2YgdGhlIGN1cnJlbnQgdmlldywKLSAgICAgKiBieSBhcHBseWluZyB0aGUgZmlsdGVycyBpbiB0aGUgcmVxdWVzdGVkIGRpcmVjdGlvbjsgaWYgbm8gdHJhdmVyc2FsCi0gICAgICogaXMgcG9zc2libGUsIDxjb2RlPmN1cnJlbnROb2RlPC9jb2RlPiBpcyBub3QgY2hhbmdlZC4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgTk9UX1NVUFBPUlRFRF9FUlI6IFJhaXNlZCBpZiBhbiBhdHRlbXB0IGlzIG1hZGUgdG8gc2V0Ci0gICAgICogICA8Y29kZT5jdXJyZW50Tm9kZTwvY29kZT4gdG8gPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0Q3VycmVudE5vZGUoTm9kZSBjdXJyZW50Tm9kZSkKLSAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogTW92ZXMgdG8gYW5kIHJldHVybnMgdGhlIGNsb3Nlc3QgdmlzaWJsZSBhbmNlc3RvciBub2RlIG9mIHRoZSBjdXJyZW50Ci0gICAgICogbm9kZS4gSWYgdGhlIHNlYXJjaCBmb3IgPGNvZGU+cGFyZW50Tm9kZTwvY29kZT4gYXR0ZW1wdHMgdG8gc3RlcAotICAgICAqIHVwd2FyZCBmcm9tIHRoZSA8Y29kZT5UcmVlV2Fsa2VyPC9jb2RlPidzIDxjb2RlPnJvb3Q8L2NvZGU+IG5vZGUsIG9yCi0gICAgICogaWYgaXQgZmFpbHMgdG8gZmluZCBhIHZpc2libGUgYW5jZXN0b3Igbm9kZSwgdGhpcyBtZXRob2QgcmV0YWlucyB0aGUKLSAgICAgKiBjdXJyZW50IHBvc2l0aW9uIGFuZCByZXR1cm5zIDxjb2RlPm51bGw8L2NvZGU+LgotICAgICAqIEByZXR1cm4gVGhlIG5ldyBwYXJlbnQgbm9kZSwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlIGN1cnJlbnQgbm9kZQotICAgICAqICAgaGFzIG5vIHBhcmVudCAgaW4gdGhlIDxjb2RlPlRyZWVXYWxrZXI8L2NvZGU+J3MgbG9naWNhbCB2aWV3LgotICAgICAqLwotICAgIHB1YmxpYyBOb2RlIHBhcmVudE5vZGUoKTsKLQotICAgIC8qKgotICAgICAqIE1vdmVzIHRoZSA8Y29kZT5UcmVlV2Fsa2VyPC9jb2RlPiB0byB0aGUgZmlyc3QgdmlzaWJsZSBjaGlsZCBvZiB0aGUKLSAgICAgKiBjdXJyZW50IG5vZGUsIGFuZCByZXR1cm5zIHRoZSBuZXcgbm9kZS4gSWYgdGhlIGN1cnJlbnQgbm9kZSBoYXMgbm8KLSAgICAgKiB2aXNpYmxlIGNoaWxkcmVuLCByZXR1cm5zIDxjb2RlPm51bGw8L2NvZGU+LCBhbmQgcmV0YWlucyB0aGUgY3VycmVudAotICAgICAqIG5vZGUuCi0gICAgICogQHJldHVybiBUaGUgbmV3IG5vZGUsIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoZSBjdXJyZW50IG5vZGUgaGFzIG5vCi0gICAgICogICB2aXNpYmxlIGNoaWxkcmVuICBpbiB0aGUgPGNvZGU+VHJlZVdhbGtlcjwvY29kZT4ncyBsb2dpY2FsIHZpZXcuCi0gICAgICovCi0gICAgcHVibGljIE5vZGUgZmlyc3RDaGlsZCgpOwotCi0gICAgLyoqCi0gICAgICogTW92ZXMgdGhlIDxjb2RlPlRyZWVXYWxrZXI8L2NvZGU+IHRvIHRoZSBsYXN0IHZpc2libGUgY2hpbGQgb2YgdGhlCi0gICAgICogY3VycmVudCBub2RlLCBhbmQgcmV0dXJucyB0aGUgbmV3IG5vZGUuIElmIHRoZSBjdXJyZW50IG5vZGUgaGFzIG5vCi0gICAgICogdmlzaWJsZSBjaGlsZHJlbiwgcmV0dXJucyA8Y29kZT5udWxsPC9jb2RlPiwgYW5kIHJldGFpbnMgdGhlIGN1cnJlbnQKLSAgICAgKiBub2RlLgotICAgICAqIEByZXR1cm4gVGhlIG5ldyBub2RlLCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGUgY3VycmVudCBub2RlIGhhcyBubwotICAgICAqICAgY2hpbGRyZW4gIGluIHRoZSA8Y29kZT5UcmVlV2Fsa2VyPC9jb2RlPidzIGxvZ2ljYWwgdmlldy4KLSAgICAgKi8KLSAgICBwdWJsaWMgTm9kZSBsYXN0Q2hpbGQoKTsKLQotICAgIC8qKgotICAgICAqIE1vdmVzIHRoZSA8Y29kZT5UcmVlV2Fsa2VyPC9jb2RlPiB0byB0aGUgcHJldmlvdXMgc2libGluZyBvZiB0aGUKLSAgICAgKiBjdXJyZW50IG5vZGUsIGFuZCByZXR1cm5zIHRoZSBuZXcgbm9kZS4gSWYgdGhlIGN1cnJlbnQgbm9kZSBoYXMgbm8KLSAgICAgKiB2aXNpYmxlIHByZXZpb3VzIHNpYmxpbmcsIHJldHVybnMgPGNvZGU+bnVsbDwvY29kZT4sIGFuZCByZXRhaW5zIHRoZQotICAgICAqIGN1cnJlbnQgbm9kZS4KLSAgICAgKiBAcmV0dXJuIFRoZSBuZXcgbm9kZSwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlIGN1cnJlbnQgbm9kZSBoYXMgbm8KLSAgICAgKiAgIHByZXZpb3VzIHNpYmxpbmcuICBpbiB0aGUgPGNvZGU+VHJlZVdhbGtlcjwvY29kZT4ncyBsb2dpY2FsIHZpZXcuCi0gICAgICovCi0gICAgcHVibGljIE5vZGUgcHJldmlvdXNTaWJsaW5nKCk7Ci0KLSAgICAvKioKLSAgICAgKiBNb3ZlcyB0aGUgPGNvZGU+VHJlZVdhbGtlcjwvY29kZT4gdG8gdGhlIG5leHQgc2libGluZyBvZiB0aGUgY3VycmVudAotICAgICAqIG5vZGUsIGFuZCByZXR1cm5zIHRoZSBuZXcgbm9kZS4gSWYgdGhlIGN1cnJlbnQgbm9kZSBoYXMgbm8gdmlzaWJsZQotICAgICAqIG5leHQgc2libGluZywgcmV0dXJucyA8Y29kZT5udWxsPC9jb2RlPiwgYW5kIHJldGFpbnMgdGhlIGN1cnJlbnQgbm9kZS4KLSAgICAgKiBAcmV0dXJuIFRoZSBuZXcgbm9kZSwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlIGN1cnJlbnQgbm9kZSBoYXMgbm8KLSAgICAgKiAgIG5leHQgc2libGluZy4gIGluIHRoZSA8Y29kZT5UcmVlV2Fsa2VyPC9jb2RlPidzIGxvZ2ljYWwgdmlldy4KLSAgICAgKi8KLSAgICBwdWJsaWMgTm9kZSBuZXh0U2libGluZygpOwotCi0gICAgLyoqCi0gICAgICogTW92ZXMgdGhlIDxjb2RlPlRyZWVXYWxrZXI8L2NvZGU+IHRvIHRoZSBwcmV2aW91cyB2aXNpYmxlIG5vZGUgaW4KLSAgICAgKiBkb2N1bWVudCBvcmRlciByZWxhdGl2ZSB0byB0aGUgY3VycmVudCBub2RlLCBhbmQgcmV0dXJucyB0aGUgbmV3Ci0gICAgICogbm9kZS4gSWYgdGhlIGN1cnJlbnQgbm9kZSBoYXMgbm8gcHJldmlvdXMgbm9kZSwgIG9yIGlmIHRoZSBzZWFyY2ggZm9yCi0gICAgICogPGNvZGU+cHJldmlvdXNOb2RlPC9jb2RlPiBhdHRlbXB0cyB0byBzdGVwIHVwd2FyZCBmcm9tIHRoZQotICAgICAqIDxjb2RlPlRyZWVXYWxrZXI8L2NvZGU+J3MgPGNvZGU+cm9vdDwvY29kZT4gbm9kZSwgIHJldHVybnMKLSAgICAgKiA8Y29kZT5udWxsPC9jb2RlPiwgYW5kIHJldGFpbnMgdGhlIGN1cnJlbnQgbm9kZS4KLSAgICAgKiBAcmV0dXJuIFRoZSBuZXcgbm9kZSwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlIGN1cnJlbnQgbm9kZSBoYXMgbm8KLSAgICAgKiAgIHByZXZpb3VzIG5vZGUgIGluIHRoZSA8Y29kZT5UcmVlV2Fsa2VyPC9jb2RlPidzIGxvZ2ljYWwgdmlldy4KLSAgICAgKi8KLSAgICBwdWJsaWMgTm9kZSBwcmV2aW91c05vZGUoKTsKLQotICAgIC8qKgotICAgICAqIE1vdmVzIHRoZSA8Y29kZT5UcmVlV2Fsa2VyPC9jb2RlPiB0byB0aGUgbmV4dCB2aXNpYmxlIG5vZGUgaW4gZG9jdW1lbnQKLSAgICAgKiBvcmRlciByZWxhdGl2ZSB0byB0aGUgY3VycmVudCBub2RlLCBhbmQgcmV0dXJucyB0aGUgbmV3IG5vZGUuIElmIHRoZQotICAgICAqIGN1cnJlbnQgbm9kZSBoYXMgbm8gbmV4dCBub2RlLCBvciBpZiB0aGUgc2VhcmNoIGZvciBuZXh0Tm9kZSBhdHRlbXB0cwotICAgICAqIHRvIHN0ZXAgdXB3YXJkIGZyb20gdGhlIDxjb2RlPlRyZWVXYWxrZXI8L2NvZGU+J3MgPGNvZGU+cm9vdDwvY29kZT4KLSAgICAgKiBub2RlLCByZXR1cm5zIDxjb2RlPm51bGw8L2NvZGU+LCBhbmQgcmV0YWlucyB0aGUgY3VycmVudCBub2RlLgotICAgICAqIEByZXR1cm4gVGhlIG5ldyBub2RlLCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGUgY3VycmVudCBub2RlIGhhcyBubwotICAgICAqICAgbmV4dCBub2RlICBpbiB0aGUgPGNvZGU+VHJlZVdhbGtlcjwvY29kZT4ncyBsb2dpY2FsIHZpZXcuCi0gICAgICovCi0gICAgcHVibGljIE5vZGUgbmV4dE5vZGUoKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy93M2MvZG9tL3ZpZXdzL0Fic3RyYWN0Vmlldy5qYXZhIGIvc3JjL29yZy93M2MvZG9tL3ZpZXdzL0Fic3RyYWN0Vmlldy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1MjE5NTcxLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS92aWV3cy9BYnN0cmFjdFZpZXcuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDU2ICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBUaGlzIGZpbGUgaXMgYXZhaWxhYmxlIHVuZGVyIGFuZCBnb3Zlcm5lZCBieSB0aGUgR05VIEdlbmVyYWwgUHVibGljCi0gKiBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqIEhvd2V2ZXIsIHRoZSBmb2xsb3dpbmcgbm90aWNlIGFjY29tcGFuaWVkIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIG9mIHRoaXMKLSAqIGZpbGUgYW5kLCBwZXIgaXRzIHRlcm1zLCBzaG91bGQgbm90IGJlIHJlbW92ZWQ6Ci0gKgotICogQ29weXJpZ2h0IChjKSAyMDAwIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKLSAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAotICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCi0gKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQotICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgotICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgotICogUFVSUE9TRS4KLSAqIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgotICovCi0KLXBhY2thZ2Ugb3JnLnczYy5kb20udmlld3M7Ci0KLS8qKgotICogQSBiYXNlIGludGVyZmFjZSB0aGF0IGFsbCB2aWV3cyBzaGFsbCBkZXJpdmUgZnJvbS4KLSAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAwL1JFQy1ET00tTGV2ZWwtMi1WaWV3cy0yMDAwMTExMyc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDIgVmlld3MgU3BlY2lmaWNhdGlvbjwvYT4uCi0gKiBAc2luY2UgRE9NIExldmVsIDIKLSAqLwotcHVibGljIGludGVyZmFjZSBBYnN0cmFjdFZpZXcgewotICAgIC8qKgotICAgICAqIFRoZSBzb3VyY2UgPGNvZGU+RG9jdW1lbnRWaWV3PC9jb2RlPiBvZiB3aGljaCB0aGlzIGlzIGFuCi0gICAgICogPGNvZGU+QWJzdHJhY3RWaWV3PC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgRG9jdW1lbnRWaWV3IGdldERvY3VtZW50KCk7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvdzNjL2RvbS92aWV3cy9Eb2N1bWVudFZpZXcuamF2YSBiL3NyYy9vcmcvdzNjL2RvbS92aWV3cy9Eb2N1bWVudFZpZXcuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMzg3OTNhNC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3czYy9kb20vdmlld3MvRG9jdW1lbnRWaWV3LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw1OSArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogVGhpcyBmaWxlIGlzIGF2YWlsYWJsZSB1bmRlciBhbmQgZ292ZXJuZWQgYnkgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwotICogTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKiBIb3dldmVyLCB0aGUgZm9sbG93aW5nIG5vdGljZSBhY2NvbXBhbmllZCB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGlzCi0gKiBmaWxlIGFuZCwgcGVyIGl0cyB0ZXJtcywgc2hvdWxkIG5vdCBiZSByZW1vdmVkOgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMCBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAotICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCi0gKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKLSAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQotICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKLSAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KLSAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKLSAqIFBVUlBPU0UuCi0gKiBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KLSAqLwotCi1wYWNrYWdlIG9yZy53M2MuZG9tLnZpZXdzOwotCi0vKioKLSAqIFRoZSA8Y29kZT5Eb2N1bWVudFZpZXc8L2NvZGU+IGludGVyZmFjZSBpcyBpbXBsZW1lbnRlZCBieQotICogPGNvZGU+RG9jdW1lbnQ8L2NvZGU+IG9iamVjdHMgaW4gRE9NIGltcGxlbWVudGF0aW9ucyBzdXBwb3J0aW5nIERPTQotICogVmlld3MuIEl0IHByb3ZpZGVzIGFuIGF0dHJpYnV0ZSB0byByZXRyaWV2ZSB0aGUgZGVmYXVsdCB2aWV3IG9mIGEKLSAqIGRvY3VtZW50LgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDAvUkVDLURPTS1MZXZlbC0yLVZpZXdzLTIwMDAxMTEzJz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMiBWaWV3cyBTcGVjaWZpY2F0aW9uPC9hPi4KLSAqIEBzaW5jZSBET00gTGV2ZWwgMgotICovCi1wdWJsaWMgaW50ZXJmYWNlIERvY3VtZW50VmlldyB7Ci0gICAgLyoqCi0gICAgICogVGhlIGRlZmF1bHQgPGNvZGU+QWJzdHJhY3RWaWV3PC9jb2RlPiBmb3IgdGhpcyA8Y29kZT5Eb2N1bWVudDwvY29kZT4sCi0gICAgICogb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgbm9uZSBhdmFpbGFibGUuCi0gICAgICovCi0gICAgcHVibGljIEFic3RyYWN0VmlldyBnZXREZWZhdWx0VmlldygpOwotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL3czYy9kb20veHBhdGgvQ09QWVJJR0hULmh0bWwgYi9zcmMvb3JnL3czYy9kb20veHBhdGgvQ09QWVJJR0hULmh0bWwKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGM3ZTBlNDkuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy93M2MvZG9tL3hwYXRoL0NPUFlSSUdIVC5odG1sCisrKyAvZGV2L251bGwKQEAgLTEsMTA2ICswLDAgQEAKLTwhRE9DVFlQRSBodG1sIFBVQkxJQyAiLS8vVzNDLy9EVEQgWEhUTUwgMS4wIFRyYW5zaXRpb25hbC8vRU4iCi0gICAgImh0dHA6Ly93d3cudzMub3JnL1RSL3hodG1sMS9EVEQveGh0bWwxLXRyYW5zaXRpb25hbC5kdGQiPgotPGh0bWw+Ci0gIDxoZWFkPgotICAgIDxtZXRhIGh0dHAtZXF1aXY9IkNvbnRlbnQtVHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PXVzLWFzY2lpIiAvPgotICAgIDx0aXRsZT5XM0MgSVBSIFNPRlRXQVJFIE5PVElDRTwvdGl0bGU+Ci08c3R5bGUgdHlwZT0idGV4dC9jc3MiPgotPCEtLQotaHRtbCwgYm9keSB7IGJhY2tncm91bmQ6ICNmZmY7IGNvbG9yOiAjMDAwOyB9IC8qIGJvZHkgZm9yIFdpbmRvd3MgSUUzICovCi0tLT4KLTwvc3R5bGU+Ci0gIDwvaGVhZD4KLSAgPGJvZHk+Ci0gICAgPGgxPgotICAgICAgVzNDIElQUiBTT0ZUV0FSRSBOT1RJQ0UKLSAgICA8L2gxPgotICAgIDxoMz4KLSAgICAgIENvcHlyaWdodCAmY29weTsgMjAwMiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy8iPldvcmxkIFdpZGUgV2ViCi0gICAgICBDb25zb3J0aXVtPC9hPiwgKDxhIGhyZWY9Imh0dHA6Ly93d3cubGNzLm1pdC5lZHUvIj5NYXNzYWNodXNldHRzCi0gICAgICBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neTwvYT4sIDxhIGhyZWY9Imh0dHA6Ly93d3cuaW5yaWEuZnIvIj5JbnN0aXR1dAotICAgICAgTmF0aW9uYWwgZGUgUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZTwvYT4sIDxhCi0gICAgICBocmVmPSJodHRwOi8vd3d3LmtlaW8uYWMuanAvIj5LZWlvIFVuaXZlcnNpdHk8L2E+KS4gQWxsIFJpZ2h0cwotICAgICAgUmVzZXJ2ZWQuCi0gICAgPC9oMz4KLSAgICA8cD4KLSAgICAgIFRoZSBET00gYmluZGluZ3MgYXJlIHB1Ymxpc2hlZCB1bmRlciB0aGUgVzNDIFNvZnR3YXJlIENvcHlyaWdodCBOb3RpY2UKLSAgICAgIGFuZCBMaWNlbnNlLiBUaGUgc29mdHdhcmUgbGljZW5zZSByZXF1aXJlcyAiTm90aWNlIG9mIGFueSBjaGFuZ2VzIG9yCi0gICAgICBtb2RpZmljYXRpb25zIHRvIHRoZSBXM0MgZmlsZXMsIGluY2x1ZGluZyB0aGUgZGF0ZSBjaGFuZ2VzIHdlcmUgbWFkZS4iCi0gICAgICBDb25zZXF1ZW50bHksIG1vZGlmaWVkIHZlcnNpb25zIG9mIHRoZSBET00gYmluZGluZ3MgbXVzdCBkb2N1bWVudCB0aGF0Ci0gICAgICB0aGV5IGRvIG5vdCBjb25mb3JtIHRvIHRoZSBXM0Mgc3RhbmRhcmQ7IGluIHRoZSBjYXNlIG9mIHRoZSBJREwKLSAgICAgIGRlZmluaXRpb25zLCB0aGUgcHJhZ21hIHByZWZpeCBjYW4gbm8gbG9uZ2VyIGJlICd3M2Mub3JnJzsgaW4gdGhlIGNhc2Ugb2YKLSAgICAgIHRoZSBKYXZhIGxhbmd1YWdlIGJpbmRpbmcsIHRoZSBwYWNrYWdlIG5hbWVzIGNhbiBubyBsb25nZXIgYmUgaW4gdGhlCi0gICAgICAnb3JnLnczYycgcGFja2FnZS4KLSAgICA8L3A+Ci0gICAgPHA+Ci0gICAgICA8Yj5Ob3RlOjwvYj4gVGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhlIFczQyBTb2Z0d2FyZSBDb3B5cmlnaHQgTm90aWNlCi0gICAgICBhbmQgTGljZW5zZSBjb3VsZCBiZSBmb3VuZCBhdCA8YQotICAgICAgaHJlZj0naHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC9jb3B5cmlnaHQtc29mdHdhcmUtMTk5ODA3MjAnPmh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvY29weXJpZ2h0LXNvZnR3YXJlLTE5OTgwNzIwPC9hPgotICAgIDwvcD4KLSAgICA8aDM+Ci0gICAgICBDb3B5cmlnaHQgJmNvcHk7IDE5OTQtMjAwMiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy8iPldvcmxkIFdpZGUgV2ViCi0gICAgICBDb25zb3J0aXVtPC9hPiwgKDxhIGhyZWY9Imh0dHA6Ly93d3cubGNzLm1pdC5lZHUvIj5NYXNzYWNodXNldHRzCi0gICAgICBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neTwvYT4sIDxhIGhyZWY9Imh0dHA6Ly93d3cuaW5yaWEuZnIvIj5JbnN0aXR1dAotICAgICAgTmF0aW9uYWwgZGUgUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZTwvYT4sIDxhCi0gICAgICBocmVmPSJodHRwOi8vd3d3LmtlaW8uYWMuanAvIj5LZWlvIFVuaXZlcnNpdHk8L2E+KS4gQWxsIFJpZ2h0cwotICAgICAgUmVzZXJ2ZWQuIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvCi0gICAgPC9oMz4KLSAgICA8cD4KLSAgICAgIFRoaXMgVzNDIHdvcmsgKGluY2x1ZGluZyBzb2Z0d2FyZSwgZG9jdW1lbnRzLCBvciBvdGhlciByZWxhdGVkIGl0ZW1zKSBpcwotICAgICAgYmVpbmcgcHJvdmlkZWQgYnkgdGhlIGNvcHlyaWdodCBob2xkZXJzIHVuZGVyIHRoZSBmb2xsb3dpbmcgbGljZW5zZS4gQnkKLSAgICAgIG9idGFpbmluZywgdXNpbmcgYW5kL29yIGNvcHlpbmcgdGhpcyB3b3JrLCB5b3UgKHRoZSBsaWNlbnNlZSkgYWdyZWUgdGhhdAotICAgICAgeW91IGhhdmUgcmVhZCwgdW5kZXJzdG9vZCwgYW5kIHdpbGwgY29tcGx5IHdpdGggdGhlIGZvbGxvd2luZyB0ZXJtcyBhbmQKLSAgICAgIGNvbmRpdGlvbnM6Ci0gICAgPC9wPgotICAgIDxwPgotICAgICAgUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIGFuZCBtb2RpZnkgdGhpcyBzb2Z0d2FyZSBhbmQgaXRzIGRvY3VtZW50YXRpb24sCi0gICAgICB3aXRoIG9yIHdpdGhvdXQgbW9kaWZpY2F0aW9uLCZuYnNwOyBmb3IgYW55IHB1cnBvc2UgYW5kIHdpdGhvdXQgZmVlIG9yCi0gICAgICByb3lhbHR5IGlzIGhlcmVieSBncmFudGVkLCBwcm92aWRlZCB0aGF0IHlvdSBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgb24gQUxMCi0gICAgICBjb3BpZXMgb2YgdGhlIHNvZnR3YXJlIGFuZCBkb2N1bWVudGF0aW9uIG9yIHBvcnRpb25zIHRoZXJlb2YsIGluY2x1ZGluZwotICAgICAgbW9kaWZpY2F0aW9ucywgdGhhdCB5b3UgbWFrZToKLSAgICA8L3A+Ci0gICAgPG9sPgotICAgICAgPGxpPgotCVRoZSBmdWxsIHRleHQgb2YgdGhpcyBOT1RJQ0UgaW4gYSBsb2NhdGlvbiB2aWV3YWJsZSB0byB1c2VycyBvZiB0aGUKLQlyZWRpc3RyaWJ1dGVkIG9yIGRlcml2YXRpdmUgd29yay4KLSAgICAgIDwvbGk+Ci0gICAgICA8bGk+Ci0JQW55IHByZS1leGlzdGluZyBpbnRlbGxlY3R1YWwgcHJvcGVydHkgZGlzY2xhaW1lcnMsIG5vdGljZXMsIG9yIHRlcm1zCi0JYW5kIGNvbmRpdGlvbnMuIElmIG5vbmUgZXhpc3QsIGEgc2hvcnQgbm90aWNlIG9mIHRoZSBmb2xsb3dpbmcgZm9ybQotCShoeXBlcnRleHQgaXMgcHJlZmVycmVkLCB0ZXh0IGlzIHBlcm1pdHRlZCkgc2hvdWxkIGJlIHVzZWQgd2l0aGluIHRoZQotCWJvZHkgb2YgYW55IHJlZGlzdHJpYnV0ZWQgb3IgZGVyaXZhdGl2ZSBjb2RlOiAiQ29weXJpZ2h0ICZjb3B5OwotCVskZGF0ZS1vZi1zb2Z0d2FyZV0gPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvIj5Xb3JsZCBXaWRlIFdlYgotCUNvbnNvcnRpdW08L2E+LCAoPGEgaHJlZj0iaHR0cDovL3d3dy5sY3MubWl0LmVkdS8iPk1hc3NhY2h1c2V0dHMKLQlJbnN0aXR1dGUgb2YgVGVjaG5vbG9neTwvYT4sIDxhIGhyZWY9Imh0dHA6Ly93d3cuaW5yaWEuZnIvIj5JbnN0aXR1dAotCU5hdGlvbmFsIGRlIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWU8L2E+LCA8YQotCWhyZWY9Imh0dHA6Ly93d3cua2Vpby5hYy5qcC8iPktlaW8gVW5pdmVyc2l0eTwvYT4pLiAgQWxsIFJpZ2h0cwotCVJlc2VydmVkLiBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyIKLSAgICAgIDwvbGk+Ci0gICAgICA8bGk+Ci0JTm90aWNlIG9mIGFueSBjaGFuZ2VzIG9yIG1vZGlmaWNhdGlvbnMgdG8gdGhlIFczQyBmaWxlcywgaW5jbHVkaW5nIHRoZQotCWRhdGUgY2hhbmdlcyB3ZXJlIG1hZGUuIChXZSByZWNvbW1lbmQgeW91IHByb3ZpZGUgVVJJcyB0byB0aGUgbG9jYXRpb24KLQlmcm9tIHdoaWNoIHRoZSBjb2RlIGlzIGRlcml2ZWQuKQotICAgICAgPC9saT4KLSAgICA8L29sPgotICAgIDxwPgotICAgICAgVEhJUyBTT0ZUV0FSRSBBTkQgRE9DVU1FTlRBVElPTiBJUyBQUk9WSURFRCAiQVMgSVMsIiBBTkQgQ09QWVJJR0hUCi0gICAgICBIT0xERVJTIE1BS0UgTk8gUkVQUkVTRU5UQVRJT05TIE9SIFdBUlJBTlRJRVMsIEVYUFJFU1MgT1IgSU1QTElFRCwKLSAgICAgIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8sIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIE9SIEZJVE5FU1MKLSAgICAgIEZPUiBBTlkgUEFSVElDVUxBUiBQVVJQT1NFIE9SIFRIQVQgVEhFIFVTRSBPRiBUSEUgU09GVFdBUkUgT1IKLSAgICAgIERPQ1VNRU5UQVRJT04gV0lMTCBOT1QgSU5GUklOR0UgQU5ZIFRISVJEIFBBUlRZIFBBVEVOVFMsIENPUFlSSUdIVFMsCi0gICAgICBUUkFERU1BUktTIE9SIE9USEVSIFJJR0hUUy4KLSAgICA8L3A+Ci0gICAgPHA+Ci0gICAgICBDT1BZUklHSFQgSE9MREVSUyBXSUxMIE5PVCBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBTUEVDSUFMIE9SCi0gICAgICBDT05TRVFVRU5USUFMIERBTUFHRVMgQVJJU0lORyBPVVQgT0YgQU5ZIFVTRSBPRiBUSEUgU09GVFdBUkUgT1IKLSAgICAgIERPQ1VNRU5UQVRJT04uCi0gICAgPC9wPgotICAgIDxwPgotICAgICAgVGhlIG5hbWUgYW5kIHRyYWRlbWFya3Mgb2YgY29weXJpZ2h0IGhvbGRlcnMgbWF5IE5PVCBiZSB1c2VkIGluCi0gICAgICBhZHZlcnRpc2luZyBvciBwdWJsaWNpdHkgcGVydGFpbmluZyB0byB0aGUgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYywKLSAgICAgIHdyaXR0ZW4gcHJpb3IgcGVybWlzc2lvbi4gVGl0bGUgdG8gY29weXJpZ2h0IGluIHRoaXMgc29mdHdhcmUgYW5kIGFueQotICAgICAgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIHdpbGwgYXQgYWxsIHRpbWVzIHJlbWFpbiB3aXRoIGNvcHlyaWdodAotICAgICAgaG9sZGVycy4KLSAgICA8L3A+Ci0gIDwvYm9keT4KLTwvaHRtbD4KZGlmZiAtLWdpdCBhL3NyYy9vcmcvdzNjL2RvbS94cGF0aC9YUGF0aEV2YWx1YXRvci5qYXZhIGIvc3JjL29yZy93M2MvZG9tL3hwYXRoL1hQYXRoRXZhbHVhdG9yLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGRhNmJlYzUuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy93M2MvZG9tL3hwYXRoL1hQYXRoRXZhbHVhdG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNjIgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIFRoaXMgZmlsZSBpcyBhdmFpbGFibGUgdW5kZXIgYW5kIGdvdmVybmVkIGJ5IHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKLSAqIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICogSG93ZXZlciwgdGhlIGZvbGxvd2luZyBub3RpY2UgYWNjb21wYW5pZWQgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcwotICogZmlsZSBhbmQsIHBlciBpdHMgdGVybXMsIHNob3VsZCBub3QgYmUgcmVtb3ZlZDoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDIgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKLSAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQotICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCi0gKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKLSAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCi0gKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCi0gKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCi0gKiBQVVJQT1NFLgotICogU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCi0gKi8KLQotcGFja2FnZSBvcmcudzNjLmRvbS54cGF0aDsKLQotCi1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcudzNjLmRvbS5ET01FeGNlcHRpb247Ci0KLS8qKgotICogIFRoZSBldmFsdWF0aW9uIG9mIFhQYXRoIGV4cHJlc3Npb25zIGlzIHByb3ZpZGVkIGJ5Ci0gKiA8Y29kZT5YUGF0aEV2YWx1YXRvcjwvY29kZT4uIEluIGEgRE9NIGltcGxlbWVudGF0aW9uIHdoaWNoIHN1cHBvcnRzIHRoZQotICogWFBhdGggMy4wIGZlYXR1cmUsIGFzIGRlc2NyaWJlZCBhYm92ZSwgdGhlIDxjb2RlPlhQYXRoRXZhbHVhdG9yPC9jb2RlPgotICogaW50ZXJmYWNlIHdpbGwgYmUgaW1wbGVtZW50ZWQgb24gdGhlIHNhbWUgb2JqZWN0IHdoaWNoIGltcGxlbWVudHMgdGhlCi0gKiA8Y29kZT5Eb2N1bWVudDwvY29kZT4gaW50ZXJmYWNlIHBlcm1pdHRpbmcgaXQgdG8gYmUgb2J0YWluZWQgYnkgdGhlIHVzdWFsCi0gKiBiaW5kaW5nLXNwZWNpZmljIG1ldGhvZCBzdWNoIGFzIGNhc3Rpbmcgb3IgYnkgdXNpbmcgdGhlIERPTSBMZXZlbCAzCi0gKiBnZXRJbnRlcmZhY2UgbWV0aG9kLiBJbiB0aGlzIGNhc2UgdGhlIGltcGxlbWVudGF0aW9uIG9idGFpbmVkIGZyb20gdGhlCi0gKiBEb2N1bWVudCBzdXBwb3J0cyB0aGUgWFBhdGggRE9NIG1vZHVsZSBhbmQgaXMgY29tcGF0aWJsZSB3aXRoIHRoZSBYUGF0aAotICogMS4wIHNwZWNpZmljYXRpb24uCi0gKiA8cD5FdmFsdWF0aW9uIG9mIGV4cHJlc3Npb25zIHdpdGggc3BlY2lhbGl6ZWQgZXh0ZW5zaW9uIGZ1bmN0aW9ucyBvcgotICogdmFyaWFibGVzIG1heSBub3Qgd29yayBpbiBhbGwgaW1wbGVtZW50YXRpb25zIGFuZCBpcywgdGhlcmVmb3JlLCBub3QKLSAqIHBvcnRhYmxlLiA8Y29kZT5YUGF0aEV2YWx1YXRvcjwvY29kZT4gaW1wbGVtZW50YXRpb25zIG1heSBiZSBhdmFpbGFibGUKLSAqIGZyb20gb3RoZXIgc291cmNlcyB0aGF0IGNvdWxkIHByb3ZpZGUgc3BlY2lmaWMgc3VwcG9ydCBmb3Igc3BlY2lhbGl6ZWQKLSAqIGV4dGVuc2lvbiBmdW5jdGlvbnMgb3IgdmFyaWFibGVzIGFzIHdvdWxkIGJlIGRlZmluZWQgYnkgb3RoZXIKLSAqIHNwZWNpZmljYXRpb25zLgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnLzIwMDIvMDgvV0QtRE9NLUxldmVsLTMtWFBhdGgtMjAwMjA4MjAnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAzIFhQYXRoIFNwZWNpZmljYXRpb248L2E+LgotICovCi1wdWJsaWMgaW50ZXJmYWNlIFhQYXRoRXZhbHVhdG9yIHsKLSAgICAvKioKLSAgICAgKiBDcmVhdGVzIGEgcGFyc2VkIFhQYXRoIGV4cHJlc3Npb24gd2l0aCByZXNvbHZlZCBuYW1lc3BhY2VzLiBUaGlzIGlzCi0gICAgICogdXNlZnVsIHdoZW4gYW4gZXhwcmVzc2lvbiB3aWxsIGJlIHJldXNlZCBpbiBhbiBhcHBsaWNhdGlvbiBzaW5jZSBpdAotICAgICAqIG1ha2VzIGl0IHBvc3NpYmxlIHRvIGNvbXBpbGUgdGhlIGV4cHJlc3Npb24gc3RyaW5nIGludG8gYSBtb3JlCi0gICAgICogZWZmaWNpZW50IGludGVybmFsIGZvcm0gYW5kIHByZXJlc29sdmUgYWxsIG5hbWVzcGFjZSBwcmVmaXhlcyB3aGljaAotICAgICAqIG9jY3VyIHdpdGhpbiB0aGUgZXhwcmVzc2lvbi4KLSAgICAgKiBAcGFyYW0gZXhwcmVzc2lvbiBUaGUgWFBhdGggZXhwcmVzc2lvbiBzdHJpbmcgdG8gYmUgcGFyc2VkLgotICAgICAqIEBwYXJhbSByZXNvbHZlciBUaGUgPGNvZGU+cmVzb2x2ZXI8L2NvZGU+IHBlcm1pdHMgdHJhbnNsYXRpb24gb2YKLSAgICAgKiAgIHByZWZpeGVzIHdpdGhpbiB0aGUgWFBhdGggZXhwcmVzc2lvbiBpbnRvIGFwcHJvcHJpYXRlIG5hbWVzcGFjZSBVUklzCi0gICAgICogICAuIElmIHRoaXMgaXMgc3BlY2lmaWVkIGFzIDxjb2RlPm51bGw8L2NvZGU+LCBhbnkgbmFtZXNwYWNlIHByZWZpeAotICAgICAqICAgd2l0aGluIHRoZSBleHByZXNzaW9uIHdpbGwgcmVzdWx0IGluIDxjb2RlPkRPTUV4Y2VwdGlvbjwvY29kZT4KLSAgICAgKiAgIGJlaW5nIHRocm93biB3aXRoIHRoZSBjb2RlIDxjb2RlPk5BTUVTUEFDRV9FUlI8L2NvZGU+LgotICAgICAqIEByZXR1cm4gVGhlIGNvbXBpbGVkIGZvcm0gb2YgdGhlIFhQYXRoIGV4cHJlc3Npb24uCi0gICAgICogQGV4Y2VwdGlvbiBYUGF0aEV4Y2VwdGlvbgotICAgICAqICAgSU5WQUxJRF9FWFBSRVNTSU9OX0VSUjogUmFpc2VkIGlmIHRoZSBleHByZXNzaW9uIGlzIG5vdCBsZWdhbAotICAgICAqICAgYWNjb3JkaW5nIHRvIHRoZSBydWxlcyBvZiB0aGUgPGNvZGU+WFBhdGhFdmFsdWF0b3I8L2NvZGU+aQotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBOQU1FU1BBQ0VfRVJSOiBSYWlzZWQgaWYgdGhlIGV4cHJlc3Npb24gY29udGFpbnMgbmFtZXNwYWNlIHByZWZpeGVzCi0gICAgICogICB3aGljaCBjYW5ub3QgYmUgcmVzb2x2ZWQgYnkgdGhlIHNwZWNpZmllZAotICAgICAqICAgPGNvZGU+WFBhdGhOU1Jlc29sdmVyPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgWFBhdGhFeHByZXNzaW9uIGNyZWF0ZUV4cHJlc3Npb24oU3RyaW5nIGV4cHJlc3Npb24sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhQYXRoTlNSZXNvbHZlciByZXNvbHZlcikKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIFhQYXRoRXhjZXB0aW9uLCBET01FeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBBZGFwdHMgYW55IERPTSBub2RlIHRvIHJlc29sdmUgbmFtZXNwYWNlcyBzbyB0aGF0IGFuIFhQYXRoIGV4cHJlc3Npb24KLSAgICAgKiBjYW4gYmUgZWFzaWx5IGV2YWx1YXRlZCByZWxhdGl2ZSB0byB0aGUgY29udGV4dCBvZiB0aGUgbm9kZSB3aGVyZSBpdAotICAgICAqIGFwcGVhcmVkIHdpdGhpbiB0aGUgZG9jdW1lbnQuIFRoaXMgYWRhcHRlciB3b3JrcyBsaWtlIHRoZSBET00gTGV2ZWwgMwotICAgICAqIG1ldGhvZCA8Y29kZT5sb29rdXBOYW1lc3BhY2VVUkk8L2NvZGU+IG9uIG5vZGVzIGluIHJlc29sdmluZyB0aGUKLSAgICAgKiBuYW1lc3BhY2VVUkkgZnJvbSBhIGdpdmVuIHByZWZpeCB1c2luZyB0aGUgY3VycmVudCBpbmZvcm1hdGlvbgotICAgICAqIGF2YWlsYWJsZSBpbiB0aGUgbm9kZSdzIGhpZXJhcmNoeSBhdCB0aGUgdGltZSBsb29rdXBOYW1lc3BhY2VVUkkgaXMKLSAgICAgKiBjYWxsZWQuIGFsc28gY29ycmVjdGx5IHJlc29sdmluZyB0aGUgaW1wbGljaXQgeG1sIHByZWZpeC4KLSAgICAgKiBAcGFyYW0gbm9kZVJlc29sdmVyIFRoZSBub2RlIHRvIGJlIHVzZWQgYXMgYSBjb250ZXh0IGZvciBuYW1lc3BhY2UKLSAgICAgKiAgIHJlc29sdXRpb24uCi0gICAgICogQHJldHVybiA8Y29kZT5YUGF0aE5TUmVzb2x2ZXI8L2NvZGU+IHdoaWNoIHJlc29sdmVzIG5hbWVzcGFjZXMgd2l0aAotICAgICAqICAgcmVzcGVjdCB0byB0aGUgZGVmaW5pdGlvbnMgaW4gc2NvcGUgZm9yIGEgc3BlY2lmaWVkIG5vZGUuCi0gICAgICovCi0gICAgcHVibGljIFhQYXRoTlNSZXNvbHZlciBjcmVhdGVOU1Jlc29sdmVyKE5vZGUgbm9kZVJlc29sdmVyKTsKLQotICAgIC8qKgotICAgICAqIEV2YWx1YXRlcyBhbiBYUGF0aCBleHByZXNzaW9uIHN0cmluZyBhbmQgcmV0dXJucyBhIHJlc3VsdCBvZiB0aGUKLSAgICAgKiBzcGVjaWZpZWQgdHlwZSBpZiBwb3NzaWJsZS4KLSAgICAgKiBAcGFyYW0gZXhwcmVzc2lvbiBUaGUgWFBhdGggZXhwcmVzc2lvbiBzdHJpbmcgdG8gYmUgcGFyc2VkIGFuZAotICAgICAqICAgZXZhbHVhdGVkLgotICAgICAqIEBwYXJhbSBjb250ZXh0Tm9kZSBUaGUgPGNvZGU+Y29udGV4dDwvY29kZT4gaXMgY29udGV4dCBub2RlIGZvciB0aGUKLSAgICAgKiAgIGV2YWx1YXRpb24gb2YgdGhpcyBYUGF0aCBleHByZXNzaW9uLiBJZiB0aGUgWFBhdGhFdmFsdWF0b3Igd2FzCi0gICAgICogICBvYnRhaW5lZCBieSBjYXN0aW5nIHRoZSA8Y29kZT5Eb2N1bWVudDwvY29kZT4gdGhlbiB0aGlzIG11c3QgYmUKLSAgICAgKiAgIG93bmVkIGJ5IHRoZSBzYW1lIGRvY3VtZW50IGFuZCBtdXN0IGJlIGEgPGNvZGU+RG9jdW1lbnQ8L2NvZGU+LAotICAgICAqICAgPGNvZGU+RWxlbWVudDwvY29kZT4sIDxjb2RlPkF0dHJpYnV0ZTwvY29kZT4sIDxjb2RlPlRleHQ8L2NvZGU+LAotICAgICAqICAgPGNvZGU+Q0RBVEFTZWN0aW9uPC9jb2RlPiwgPGNvZGU+Q29tbWVudDwvY29kZT4sCi0gICAgICogICA8Y29kZT5Qcm9jZXNzaW5nSW5zdHJ1Y3Rpb248L2NvZGU+LCBvciA8Y29kZT5YUGF0aE5hbWVzcGFjZTwvY29kZT4KLSAgICAgKiAgIG5vZGUuIElmIHRoZSBjb250ZXh0IG5vZGUgaXMgYSA8Y29kZT5UZXh0PC9jb2RlPiBvciBhCi0gICAgICogICA8Y29kZT5DREFUQVNlY3Rpb248L2NvZGU+LCB0aGVuIHRoZSBjb250ZXh0IGlzIGludGVycHJldGVkIGFzIHRoZQotICAgICAqICAgd2hvbGUgbG9naWNhbCB0ZXh0IG5vZGUgYXMgc2VlbiBieSBYUGF0aCwgdW5sZXNzIHRoZSBub2RlIGlzIGVtcHR5Ci0gICAgICogICBpbiB3aGljaCBjYXNlIGl0IG1heSBub3Qgc2VydmUgYXMgdGhlIFhQYXRoIGNvbnRleHQuCi0gICAgICogQHBhcmFtIHJlc29sdmVyIFRoZSA8Y29kZT5yZXNvbHZlcjwvY29kZT4gcGVybWl0cyB0cmFuc2xhdGlvbiBvZgotICAgICAqICAgcHJlZml4ZXMgd2l0aGluIHRoZSBYUGF0aCBleHByZXNzaW9uIGludG8gYXBwcm9wcmlhdGUgbmFtZXNwYWNlIFVSSXMKLSAgICAgKiAgIC4gSWYgdGhpcyBpcyBzcGVjaWZpZWQgYXMgPGNvZGU+bnVsbDwvY29kZT4sIGFueSBuYW1lc3BhY2UgcHJlZml4Ci0gICAgICogICB3aXRoaW4gdGhlIGV4cHJlc3Npb24gd2lsbCByZXN1bHQgaW4gPGNvZGU+RE9NRXhjZXB0aW9uPC9jb2RlPgotICAgICAqICAgYmVpbmcgdGhyb3duIHdpdGggdGhlIGNvZGUgPGNvZGU+TkFNRVNQQUNFX0VSUjwvY29kZT4uCi0gICAgICogQHBhcmFtIHR5cGUgSWYgYSBzcGVjaWZpYyA8Y29kZT50eXBlPC9jb2RlPiBpcyBzcGVjaWZpZWQsIHRoZW4gdGhlCi0gICAgICogICByZXN1bHQgd2lsbCBiZSByZXR1cm5lZCBhcyB0aGUgY29ycmVzcG9uZGluZyB0eXBlLkZvciBYUGF0aCAxLjAKLSAgICAgKiAgIHJlc3VsdHMsIHRoaXMgbXVzdCBiZSBvbmUgb2YgdGhlIGNvZGVzIG9mIHRoZQotICAgICAqICAgPGNvZGU+WFBhdGhSZXN1bHQ8L2NvZGU+IGludGVyZmFjZS4KLSAgICAgKiBAcGFyYW0gcmVzdWx0IFRoZSA8Y29kZT5yZXN1bHQ8L2NvZGU+IHNwZWNpZmllcyBhIHNwZWNpZmljIHJlc3VsdAotICAgICAqICAgb2JqZWN0IHdoaWNoIG1heSBiZSByZXVzZWQgYW5kIHJldHVybmVkIGJ5IHRoaXMgbWV0aG9kLiBJZiB0aGlzIGlzCi0gICAgICogICBzcGVjaWZpZWQgYXMgPGNvZGU+bnVsbDwvY29kZT5vciB0aGUgaW1wbGVtZW50YXRpb24gZG9lcyBub3QgcmV1c2UKLSAgICAgKiAgIHRoZSBzcGVjaWZpZWQgcmVzdWx0LCBhIG5ldyByZXN1bHQgb2JqZWN0IHdpbGwgYmUgY29uc3RydWN0ZWQgYW5kCi0gICAgICogICByZXR1cm5lZC5Gb3IgWFBhdGggMS4wIHJlc3VsdHMsIHRoaXMgb2JqZWN0IHdpbGwgYmUgb2YgdHlwZQotICAgICAqICAgPGNvZGU+WFBhdGhSZXN1bHQ8L2NvZGU+LgotICAgICAqIEByZXR1cm4gVGhlIHJlc3VsdCBvZiB0aGUgZXZhbHVhdGlvbiBvZiB0aGUgWFBhdGggZXhwcmVzc2lvbi5Gb3IgWFBhdGgKLSAgICAgKiAgIDEuMCByZXN1bHRzLCB0aGlzIG9iamVjdCB3aWxsIGJlIG9mIHR5cGUgPGNvZGU+WFBhdGhSZXN1bHQ8L2NvZGU+LgotICAgICAqIEBleGNlcHRpb24gWFBhdGhFeGNlcHRpb24KLSAgICAgKiAgIElOVkFMSURfRVhQUkVTU0lPTl9FUlI6IFJhaXNlZCBpZiB0aGUgZXhwcmVzc2lvbiBpcyBub3QgbGVnYWwKLSAgICAgKiAgIGFjY29yZGluZyB0byB0aGUgcnVsZXMgb2YgdGhlIDxjb2RlPlhQYXRoRXZhbHVhdG9yPC9jb2RlPmkKLSAgICAgKiAgIDxicj5UWVBFX0VSUjogUmFpc2VkIGlmIHRoZSByZXN1bHQgY2Fubm90IGJlIGNvbnZlcnRlZCB0byByZXR1cm4gdGhlCi0gICAgICogICBzcGVjaWZpZWQgdHlwZS4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgTkFNRVNQQUNFX0VSUjogUmFpc2VkIGlmIHRoZSBleHByZXNzaW9uIGNvbnRhaW5zIG5hbWVzcGFjZSBwcmVmaXhlcwotICAgICAqICAgd2hpY2ggY2Fubm90IGJlIHJlc29sdmVkIGJ5IHRoZSBzcGVjaWZpZWQKLSAgICAgKiAgIDxjb2RlPlhQYXRoTlNSZXNvbHZlcjwvY29kZT4uCi0gICAgICogICA8YnI+V1JPTkdfRE9DVU1FTlRfRVJSOiBUaGUgTm9kZSBpcyBmcm9tIGEgZG9jdW1lbnQgdGhhdCBpcyBub3QKLSAgICAgKiAgIHN1cHBvcnRlZCBieSB0aGlzIDxjb2RlPlhQYXRoRXZhbHVhdG9yPC9jb2RlPi4KLSAgICAgKiAgIDxicj5OT1RfU1VQUE9SVEVEX0VSUjogVGhlIE5vZGUgaXMgbm90IGEgdHlwZSBwZXJtaXR0ZWQgYXMgYW4gWFBhdGgKLSAgICAgKiAgIGNvbnRleHQgbm9kZSBvciB0aGUgcmVxdWVzdCB0eXBlIGlzIG5vdCBwZXJtaXR0ZWQgYnkgdGhpcwotICAgICAqICAgPGNvZGU+WFBhdGhFdmFsdWF0b3I8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBPYmplY3QgZXZhbHVhdGUoU3RyaW5nIGV4cHJlc3Npb24sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICBOb2RlIGNvbnRleHROb2RlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgWFBhdGhOU1Jlc29sdmVyIHJlc29sdmVyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hvcnQgdHlwZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgIE9iamVjdCByZXN1bHQpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgWFBhdGhFeGNlcHRpb24sIERPTUV4Y2VwdGlvbjsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy93M2MvZG9tL3hwYXRoL1hQYXRoRXhjZXB0aW9uLmphdmEgYi9zcmMvb3JnL3czYy9kb20veHBhdGgvWFBhdGhFeGNlcHRpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNzUxMjFkNC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3czYy9kb20veHBhdGgvWFBhdGhFeGNlcHRpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDY4ICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBUaGlzIGZpbGUgaXMgYXZhaWxhYmxlIHVuZGVyIGFuZCBnb3Zlcm5lZCBieSB0aGUgR05VIEdlbmVyYWwgUHVibGljCi0gKiBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqIEhvd2V2ZXIsIHRoZSBmb2xsb3dpbmcgbm90aWNlIGFjY29tcGFuaWVkIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIG9mIHRoaXMKLSAqIGZpbGUgYW5kLCBwZXIgaXRzIHRlcm1zLCBzaG91bGQgbm90IGJlIHJlbW92ZWQ6Ci0gKgotICogQ29weXJpZ2h0IChjKSAyMDAyIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKLSAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAotICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCi0gKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQotICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgotICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgotICogUFVSUE9TRS4KLSAqIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgotICovCi0KLXBhY2thZ2Ugb3JnLnczYy5kb20ueHBhdGg7Ci0KLS8qKgotICogQSBuZXcgZXhjZXB0aW9uIGhhcyBiZWVuIGNyZWF0ZWQgZm9yIGV4Y2VwdGlvbnMgc3BlY2lmaWMgdG8gdGhlc2UgWFBhdGgKLSAqIGludGVyZmFjZXMuCi0gKiA8cD5TZWUgYWxzbyB0aGUgPGEgaHJlZj0naHR0cDovL3d3dy53My5vcmcvMjAwMi8wOC9XRC1ET00tTGV2ZWwtMy1YUGF0aC0yMDAyMDgyMCc+RG9jdW1lbnQgT2JqZWN0IE1vZGVsIChET00pIExldmVsIDMgWFBhdGggU3BlY2lmaWNhdGlvbjwvYT4uCi0gKi8KLXB1YmxpYyBjbGFzcyBYUGF0aEV4Y2VwdGlvbiBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24gewotICAgIHB1YmxpYyBYUGF0aEV4Y2VwdGlvbihzaG9ydCBjb2RlLCBTdHJpbmcgbWVzc2FnZSkgewotICAgICAgIHN1cGVyKG1lc3NhZ2UpOwotICAgICAgIHRoaXMuY29kZSA9IGNvZGU7Ci0gICAgfQotICAgIHB1YmxpYyBzaG9ydCAgIGNvZGU7Ci0gICAgLy8gWFBhdGhFeGNlcHRpb25Db2RlCi0gICAgLyoqCi0gICAgICogSWYgdGhlIGV4cHJlc3Npb24gaGFzIGEgc3ludGF4IGVycm9yIG9yIG90aGVyd2lzZSBpcyBub3QgYSBsZWdhbAotICAgICAqIGV4cHJlc3Npb24gYWNjb3JkaW5nIHRvIHRoZSBydWxlcyBvZiB0aGUgc3BlY2lmaWMKLSAgICAgKiA8Y29kZT5YUGF0aEV2YWx1YXRvcjwvY29kZT4gb3IgY29udGFpbnMgc3BlY2lhbGl6ZWQgZXh0ZW5zaW9uCi0gICAgICogZnVuY3Rpb25zIG9yIHZhcmlhYmxlcyBub3Qgc3VwcG9ydGVkIGJ5IHRoaXMgaW1wbGVtZW50YXRpb24uCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBJTlZBTElEX0VYUFJFU1NJT05fRVJSICAgID0gMTsKLSAgICAvKioKLSAgICAgKiBJZiB0aGUgZXhwcmVzc2lvbiBjYW5ub3QgYmUgY29udmVydGVkIHRvIHJldHVybiB0aGUgc3BlY2lmaWVkIHR5cGUuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBUWVBFX0VSUiAgICAgICAgICAgICAgICAgID0gMjsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy93M2MvZG9tL3hwYXRoL1hQYXRoRXhwcmVzc2lvbi5qYXZhIGIvc3JjL29yZy93M2MvZG9tL3hwYXRoL1hQYXRoRXhwcmVzc2lvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxN2VjNDEyLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvdzNjL2RvbS94cGF0aC9YUGF0aEV4cHJlc3Npb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDk1ICswLDAgQEAKLS8qCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8qCi0gKiBUaGlzIGZpbGUgaXMgYXZhaWxhYmxlIHVuZGVyIGFuZCBnb3Zlcm5lZCBieSB0aGUgR05VIEdlbmVyYWwgUHVibGljCi0gKiBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqIEhvd2V2ZXIsIHRoZSBmb2xsb3dpbmcgbm90aWNlIGFjY29tcGFuaWVkIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIG9mIHRoaXMKLSAqIGZpbGUgYW5kLCBwZXIgaXRzIHRlcm1zLCBzaG91bGQgbm90IGJlIHJlbW92ZWQ6Ci0gKgotICogQ29weXJpZ2h0IChjKSAyMDAyIFdvcmxkIFdpZGUgV2ViIENvbnNvcnRpdW0sCi0gKiAoTWFzc2FjaHVzZXR0cyBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgSW5zdGl0dXQgTmF0aW9uYWwgZGUKLSAqIFJlY2hlcmNoZSBlbiBJbmZvcm1hdGlxdWUgZXQgZW4gQXV0b21hdGlxdWUsIEtlaW8gVW5pdmVyc2l0eSkuIEFsbAotICogUmlnaHRzIFJlc2VydmVkLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFczQydzIFNvZnR3YXJlCi0gKiBJbnRlbGxlY3R1YWwgUHJvcGVydHkgTGljZW5zZS4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZQotICogaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbgotICogdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgotICogUFVSUE9TRS4KLSAqIFNlZSBXM0MgTGljZW5zZSBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsLyBmb3IgbW9yZSBkZXRhaWxzLgotICovCi0KLXBhY2thZ2Ugb3JnLnczYy5kb20ueHBhdGg7Ci0KLQotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci1pbXBvcnQgb3JnLnczYy5kb20uRE9NRXhjZXB0aW9uOwotCi0vKioKLSAqIFRoZSA8Y29kZT5YUGF0aEV4cHJlc3Npb248L2NvZGU+IGludGVyZmFjZSByZXByZXNlbnRzIGEgcGFyc2VkIGFuZCByZXNvbHZlZAotICogWFBhdGggZXhwcmVzc2lvbi4KLSAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy8yMDAyLzA4L1dELURPTS1MZXZlbC0zLVhQYXRoLTIwMDIwODIwJz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMyBYUGF0aCBTcGVjaWZpY2F0aW9uPC9hPi4KLSAqLwotcHVibGljIGludGVyZmFjZSBYUGF0aEV4cHJlc3Npb24gewotICAgIC8qKgotICAgICAqIEV2YWx1YXRlcyB0aGlzIFhQYXRoIGV4cHJlc3Npb24gYW5kIHJldHVybnMgYSByZXN1bHQuCi0gICAgICogQHBhcmFtIGNvbnRleHROb2RlIFRoZSA8Y29kZT5jb250ZXh0PC9jb2RlPiBpcyBjb250ZXh0IG5vZGUgZm9yIHRoZQotICAgICAqICAgZXZhbHVhdGlvbiBvZiB0aGlzIFhQYXRoIGV4cHJlc3Npb24uSWYgdGhlIFhQYXRoRXZhbHVhdG9yIHdhcwotICAgICAqICAgb2J0YWluZWQgYnkgY2FzdGluZyB0aGUgPGNvZGU+RG9jdW1lbnQ8L2NvZGU+IHRoZW4gdGhpcyBtdXN0IGJlCi0gICAgICogICBvd25lZCBieSB0aGUgc2FtZSBkb2N1bWVudCBhbmQgbXVzdCBiZSBhIDxjb2RlPkRvY3VtZW50PC9jb2RlPiwKLSAgICAgKiAgIDxjb2RlPkVsZW1lbnQ8L2NvZGU+LCA8Y29kZT5BdHRyaWJ1dGU8L2NvZGU+LCA8Y29kZT5UZXh0PC9jb2RlPiwKLSAgICAgKiAgIDxjb2RlPkNEQVRBU2VjdGlvbjwvY29kZT4sIDxjb2RlPkNvbW1lbnQ8L2NvZGU+LAotICAgICAqICAgPGNvZGU+UHJvY2Vzc2luZ0luc3RydWN0aW9uPC9jb2RlPiwgb3IgPGNvZGU+WFBhdGhOYW1lc3BhY2U8L2NvZGU+Ci0gICAgICogICBub2RlLklmIHRoZSBjb250ZXh0IG5vZGUgaXMgYSA8Y29kZT5UZXh0PC9jb2RlPiBvciBhCi0gICAgICogICA8Y29kZT5DREFUQVNlY3Rpb248L2NvZGU+LCB0aGVuIHRoZSBjb250ZXh0IGlzIGludGVycHJldGVkIGFzIHRoZQotICAgICAqICAgd2hvbGUgbG9naWNhbCB0ZXh0IG5vZGUgYXMgc2VlbiBieSBYUGF0aCwgdW5sZXNzIHRoZSBub2RlIGlzIGVtcHR5Ci0gICAgICogICBpbiB3aGljaCBjYXNlIGl0IG1heSBub3Qgc2VydmUgYXMgdGhlIFhQYXRoIGNvbnRleHQuCi0gICAgICogQHBhcmFtIHR5cGUgSWYgYSBzcGVjaWZpYyA8Y29kZT50eXBlPC9jb2RlPiBpcyBzcGVjaWZpZWQsIHRoZW4gdGhlCi0gICAgICogICByZXN1bHQgd2lsbCBiZSBjb2VyY2VkIHRvIHJldHVybiB0aGUgc3BlY2lmaWVkIHR5cGUgcmVseWluZyBvbgotICAgICAqICAgWFBhdGggY29udmVyc2lvbnMgYW5kIGZhaWwgaWYgdGhlIGRlc2lyZWQgY29lcmNpb24gaXMgbm90IHBvc3NpYmxlLgotICAgICAqICAgVGhpcyBtdXN0IGJlIG9uZSBvZiB0aGUgdHlwZSBjb2RlcyBvZiA8Y29kZT5YUGF0aFJlc3VsdDwvY29kZT4uCi0gICAgICogQHBhcmFtIHJlc3VsdCBUaGUgPGNvZGU+cmVzdWx0PC9jb2RlPiBzcGVjaWZpZXMgYSBzcGVjaWZpYyByZXN1bHQKLSAgICAgKiAgIG9iamVjdCB3aGljaCBtYXkgYmUgcmV1c2VkIGFuZCByZXR1cm5lZCBieSB0aGlzIG1ldGhvZC4gSWYgdGhpcyBpcwotICAgICAqICAgc3BlY2lmaWVkIGFzIDxjb2RlPm51bGw8L2NvZGU+b3IgdGhlIGltcGxlbWVudGF0aW9uIGRvZXMgbm90IHJldXNlCi0gICAgICogICB0aGUgc3BlY2lmaWVkIHJlc3VsdCwgYSBuZXcgcmVzdWx0IG9iamVjdCB3aWxsIGJlIGNvbnN0cnVjdGVkIGFuZAotICAgICAqICAgcmV0dXJuZWQuRm9yIFhQYXRoIDEuMCByZXN1bHRzLCB0aGlzIG9iamVjdCB3aWxsIGJlIG9mIHR5cGUKLSAgICAgKiAgIDxjb2RlPlhQYXRoUmVzdWx0PC9jb2RlPi4KLSAgICAgKiBAcmV0dXJuIFRoZSByZXN1bHQgb2YgdGhlIGV2YWx1YXRpb24gb2YgdGhlIFhQYXRoIGV4cHJlc3Npb24uRm9yIFhQYXRoCi0gICAgICogICAxLjAgcmVzdWx0cywgdGhpcyBvYmplY3Qgd2lsbCBiZSBvZiB0eXBlIDxjb2RlPlhQYXRoUmVzdWx0PC9jb2RlPi4KLSAgICAgKiBAZXhjZXB0aW9uIFhQYXRoRXhjZXB0aW9uCi0gICAgICogICBUWVBFX0VSUjogUmFpc2VkIGlmIHRoZSByZXN1bHQgY2Fubm90IGJlIGNvbnZlcnRlZCB0byByZXR1cm4gdGhlCi0gICAgICogICBzcGVjaWZpZWQgdHlwZS4KLSAgICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgICAqICAgV1JPTkdfRE9DVU1FTlRfRVJSOiBUaGUgTm9kZSBpcyBmcm9tIGEgZG9jdW1lbnQgdGhhdCBpcyBub3Qgc3VwcG9ydGVkCi0gICAgICogICBieSB0aGUgWFBhdGhFdmFsdWF0b3IgdGhhdCBjcmVhdGVkIHRoaXMgPGNvZGU+WFBhdGhFeHByZXNzaW9uPC9jb2RlPgotICAgICAqICAgLgotICAgICAqICAgPGJyPk5PVF9TVVBQT1JURURfRVJSOiBUaGUgTm9kZSBpcyBub3QgYSB0eXBlIHBlcm1pdHRlZCBhcyBhbiBYUGF0aAotICAgICAqICAgY29udGV4dCBub2RlIG9yIHRoZSByZXF1ZXN0IHR5cGUgaXMgbm90IHBlcm1pdHRlZCBieSB0aGlzCi0gICAgICogICA8Y29kZT5YUGF0aEV4cHJlc3Npb248L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBPYmplY3QgZXZhbHVhdGUoTm9kZSBjb250ZXh0Tm9kZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgIHNob3J0IHR5cGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICBPYmplY3QgcmVzdWx0KQotICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIFhQYXRoRXhjZXB0aW9uLCBET01FeGNlcHRpb247Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvdzNjL2RvbS94cGF0aC9YUGF0aE5TUmVzb2x2ZXIuamF2YSBiL3NyYy9vcmcvdzNjL2RvbS94cGF0aC9YUGF0aE5TUmVzb2x2ZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNjhlYjFmMy4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3czYy9kb20veHBhdGgvWFBhdGhOU1Jlc29sdmVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw2NCArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogVGhpcyBmaWxlIGlzIGF2YWlsYWJsZSB1bmRlciBhbmQgZ292ZXJuZWQgYnkgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwotICogTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKiBIb3dldmVyLCB0aGUgZm9sbG93aW5nIG5vdGljZSBhY2NvbXBhbmllZCB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGlzCi0gKiBmaWxlIGFuZCwgcGVyIGl0cyB0ZXJtcywgc2hvdWxkIG5vdCBiZSByZW1vdmVkOgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMiBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAotICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCi0gKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKLSAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQotICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKLSAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KLSAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKLSAqIFBVUlBPU0UuCi0gKiBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KLSAqLwotCi1wYWNrYWdlIG9yZy53M2MuZG9tLnhwYXRoOwotCi0KLS8qKgotICogVGhlIDxjb2RlPlhQYXRoTlNSZXNvbHZlcjwvY29kZT4gaW50ZXJmYWNlIHBlcm1pdCA8Y29kZT5wcmVmaXg8L2NvZGU+Ci0gKiBzdHJpbmdzIGluIHRoZSBleHByZXNzaW9uIHRvIGJlIHByb3Blcmx5IGJvdW5kIHRvCi0gKiA8Y29kZT5uYW1lc3BhY2VVUkk8L2NvZGU+IHN0cmluZ3MuIDxjb2RlPlhQYXRoRXZhbHVhdG9yPC9jb2RlPiBjYW4KLSAqIGNvbnN0cnVjdCBhbiBpbXBsZW1lbnRhdGlvbiBvZiA8Y29kZT5YUGF0aE5TUmVzb2x2ZXI8L2NvZGU+IGZyb20gYSBub2RlLAotICogb3IgdGhlIGludGVyZmFjZSBtYXkgYmUgaW1wbGVtZW50ZWQgYnkgYW55IGFwcGxpY2F0aW9uLgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnLzIwMDIvMDgvV0QtRE9NLUxldmVsLTMtWFBhdGgtMjAwMjA4MjAnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAzIFhQYXRoIFNwZWNpZmljYXRpb248L2E+LgotICovCi1wdWJsaWMgaW50ZXJmYWNlIFhQYXRoTlNSZXNvbHZlciB7Ci0gICAgLyoqCi0gICAgICogTG9vayB1cCB0aGUgbmFtZXNwYWNlIFVSSSBhc3NvY2lhdGVkIHRvIHRoZSBnaXZlbiBuYW1lc3BhY2UgcHJlZml4LiBUaGUKLSAgICAgKiBYUGF0aCBldmFsdWF0b3IgbXVzdCBuZXZlciBjYWxsIHRoaXMgd2l0aCBhIDxjb2RlPm51bGw8L2NvZGU+IG9yCi0gICAgICogZW1wdHkgYXJndW1lbnQsIGJlY2F1c2UgdGhlIHJlc3VsdCBvZiBkb2luZyB0aGlzIGlzIHVuZGVmaW5lZC4KLSAgICAgKiBAcGFyYW0gcHJlZml4IFRoZSBwcmVmaXggdG8gbG9vayBmb3IuCi0gICAgICogQHJldHVybiBSZXR1cm5zIHRoZSBhc3NvY2lhdGVkIG5hbWVzcGFjZSBVUkkgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYKLSAgICAgKiAgIG5vbmUgaXMgZm91bmQuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBsb29rdXBOYW1lc3BhY2VVUkkoU3RyaW5nIHByZWZpeCk7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvdzNjL2RvbS94cGF0aC9YUGF0aE5hbWVzcGFjZS5qYXZhIGIvc3JjL29yZy93M2MvZG9tL3hwYXRoL1hQYXRoTmFtZXNwYWNlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGNkZmVhODguLjAwMDAwMDAKLS0tIGEvc3JjL29yZy93M2MvZG9tL3hwYXRoL1hQYXRoTmFtZXNwYWNlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5NCArMCwwIEBACi0vKgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vKgotICogVGhpcyBmaWxlIGlzIGF2YWlsYWJsZSB1bmRlciBhbmQgZ292ZXJuZWQgYnkgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwotICogTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKiBIb3dldmVyLCB0aGUgZm9sbG93aW5nIG5vdGljZSBhY2NvbXBhbmllZCB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGlzCi0gKiBmaWxlIGFuZCwgcGVyIGl0cyB0ZXJtcywgc2hvdWxkIG5vdCBiZSByZW1vdmVkOgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMiBXb3JsZCBXaWRlIFdlYiBDb25zb3J0aXVtLAotICogKE1hc3NhY2h1c2V0dHMgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIEluc3RpdHV0IE5hdGlvbmFsIGRlCi0gKiBSZWNoZXJjaGUgZW4gSW5mb3JtYXRpcXVlIGV0IGVuIEF1dG9tYXRpcXVlLCBLZWlvIFVuaXZlcnNpdHkpLiBBbGwKLSAqIFJpZ2h0cyBSZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBXM0MncyBTb2Z0d2FyZQotICogSW50ZWxsZWN0dWFsIFByb3BlcnR5IExpY2Vuc2UuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUKLSAqIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4KLSAqIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKLSAqIFBVUlBPU0UuCi0gKiBTZWUgVzNDIExpY2Vuc2UgaHR0cDovL3d3dy53My5vcmcvQ29uc29ydGl1bS9MZWdhbC8gZm9yIG1vcmUgZGV0YWlscy4KLSAqLwotCi1wYWNrYWdlIG9yZy53M2MuZG9tLnhwYXRoOwotCi0KLWltcG9ydCBvcmcudzNjLmRvbS5FbGVtZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci0KLS8qKgotICogVGhlIDxjb2RlPlhQYXRoTmFtZXNwYWNlPC9jb2RlPiBpbnRlcmZhY2UgaXMgcmV0dXJuZWQgYnkKLSAqIDxjb2RlPlhQYXRoUmVzdWx0PC9jb2RlPiBpbnRlcmZhY2VzIHRvIHJlcHJlc2VudCB0aGUgWFBhdGggbmFtZXNwYWNlIG5vZGUKLSAqIHR5cGUgdGhhdCBET00gbGFja3MuIFRoZXJlIGlzIG5vIHB1YmxpYyBjb25zdHJ1Y3RvciBmb3IgdGhpcyBub2RlIHR5cGUuCi0gKiBBdHRlbXB0cyB0byBwbGFjZSBpdCBpbnRvIGEgaGllcmFyY2h5IG9yIGEgTmFtZWROb2RlTWFwIHJlc3VsdCBpbiBhCi0gKiA8Y29kZT5ET01FeGNlcHRpb248L2NvZGU+IHdpdGggdGhlIGNvZGUgPGNvZGU+SElFUkFSQ0hZX1JFUVVFU1RfRVJSPC9jb2RlPgotICogLiBUaGlzIG5vZGUgaXMgcmVhZCBvbmx5LCBzbyBtZXRob2RzIG9yIHNldHRpbmcgb2YgYXR0cmlidXRlcyB0aGF0IHdvdWxkCi0gKiBtdXRhdGUgdGhlIG5vZGUgcmVzdWx0IGluIGEgRE9NRXhjZXB0aW9uIHdpdGggdGhlIGNvZGUKLSAqIDxjb2RlPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjwvY29kZT4uCi0gKiA8cD5UaGUgY29yZSBzcGVjaWZpY2F0aW9uIGRlc2NyaWJlcyBhdHRyaWJ1dGVzIG9mIHRoZSA8Y29kZT5Ob2RlPC9jb2RlPgotICogaW50ZXJmYWNlIHRoYXQgYXJlIGRpZmZlcmVudCBmb3IgZGlmZmVyZW50IG5vZGUgbm9kZSB0eXBlcyBidXQgZG9lcyBub3QKLSAqIGRlc2NyaWJlIDxjb2RlPlhQQVRIX05BTUVTUEFDRV9OT0RFPC9jb2RlPiwgc28gaGVyZSBpcyBhIGRlc2NyaXB0aW9uIG9mCi0gKiB0aG9zZSBhdHRyaWJ1dGVzIGZvciB0aGlzIG5vZGUgdHlwZS4gQWxsIGF0dHJpYnV0ZXMgb2YgPGNvZGU+Tm9kZTwvY29kZT4KLSAqIG5vdCBkZXNjcmliZWQgaW4gdGhpcyBzZWN0aW9uIGhhdmUgYSA8Y29kZT5udWxsPC9jb2RlPiBvcgotICogPGNvZGU+ZmFsc2U8L2NvZGU+IHZhbHVlLgotICogPHA+PGNvZGU+b3duZXJEb2N1bWVudDwvY29kZT4gbWF0Y2hlcyB0aGUgPGNvZGU+b3duZXJEb2N1bWVudDwvY29kZT4gb2YgdGhlCi0gKiA8Y29kZT5vd25lckVsZW1lbnQ8L2NvZGU+IGV2ZW4gaWYgdGhlIGVsZW1lbnQgaXMgbGF0ZXIgYWRvcHRlZC4KLSAqIDxwPjxjb2RlPnByZWZpeDwvY29kZT4gaXMgdGhlIHByZWZpeCBvZiB0aGUgbmFtZXNwYWNlIHJlcHJlc2VudGVkIGJ5IHRoZQotICogbm9kZS4KLSAqIDxwPjxjb2RlPm5vZGVOYW1lPC9jb2RlPiBpcyB0aGUgc2FtZSBhcyA8Y29kZT5wcmVmaXg8L2NvZGU+LgotICogPHA+PGNvZGU+bm9kZVR5cGU8L2NvZGU+IGlzIGVxdWFsIHRvIDxjb2RlPlhQQVRIX05BTUVTUEFDRV9OT0RFPC9jb2RlPi4KLSAqIDxwPjxjb2RlPm5hbWVzcGFjZVVSSTwvY29kZT4gaXMgdGhlIG5hbWVzcGFjZSBVUkkgb2YgdGhlIG5hbWVzcGFjZQotICogcmVwcmVzZW50ZWQgYnkgdGhlIG5vZGUuCi0gKiA8cD48Y29kZT5hZG9wdE5vZGU8L2NvZGU+LCA8Y29kZT5jbG9uZU5vZGU8L2NvZGU+LCBhbmQKLSAqIDxjb2RlPmltcG9ydE5vZGU8L2NvZGU+IGZhaWwgb24gdGhpcyBub2RlIHR5cGUgYnkgcmFpc2luZyBhCi0gKiA8Y29kZT5ET01FeGNlcHRpb248L2NvZGU+IHdpdGggdGhlIGNvZGUgPGNvZGU+Tk9UX1NVUFBPUlRFRF9FUlI8L2NvZGU+LkluCi0gKiBmdXR1cmUgdmVyc2lvbnMgb2YgdGhlIFhQYXRoIHNwZWNpZmljYXRpb24sIHRoZSBkZWZpbml0aW9uIG9mIGEgbmFtZXNwYWNlCi0gKiBub2RlIG1heSBiZSBjaGFuZ2VkIGluY29tYXRpYmx5LCBpbiB3aGljaCBjYXNlIGluY29tcGF0aWJsZSBjaGFuZ2VzIHRvCi0gKiBmaWVsZCB2YWx1ZXMgbWF5IGJlIHJlcXVpcmVkIHRvIGltcGxlbWVudCB2ZXJzaW9ucyBiZXlvbmQgWFBhdGggMS4wLgotICogPHA+U2VlIGFsc28gdGhlIDxhIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnLzIwMDIvMDgvV0QtRE9NLUxldmVsLTMtWFBhdGgtMjAwMjA4MjAnPkRvY3VtZW50IE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAzIFhQYXRoIFNwZWNpZmljYXRpb248L2E+LgotICovCi1wdWJsaWMgaW50ZXJmYWNlIFhQYXRoTmFtZXNwYWNlIGV4dGVuZHMgTm9kZSB7Ci0gICAgLy8gWFBhdGhOb2RlVHlwZQotICAgIC8qKgotICAgICAqIFRoZSBub2RlIGlzIGEgPGNvZGU+TmFtZXNwYWNlPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFhQQVRIX05BTUVTUEFDRV9OT0RFICAgICAgPSAxMzsKLQotICAgIC8qKgotICAgICAqIFRoZSA8Y29kZT5FbGVtZW50PC9jb2RlPiBvbiB3aGljaCB0aGUgbmFtZXNwYWNlIHdhcyBpbiBzY29wZSB3aGVuIGl0Ci0gICAgICogd2FzIHJlcXVlc3RlZC4gVGhpcyBkb2VzIG5vdCBjaGFuZ2Ugb24gYSByZXR1cm5lZCBuYW1lc3BhY2Ugbm9kZSBldmVuCi0gICAgICogaWYgdGhlIGRvY3VtZW50IGNoYW5nZXMgc3VjaCB0aGF0IHRoZSBuYW1lc3BhY2UgZ29lcyBvdXQgb2Ygc2NvcGUgb24KLSAgICAgKiB0aGF0IGVsZW1lbnQgYW5kIHRoaXMgbm9kZSBpcyBubyBsb25nZXIgZm91bmQgdGhlcmUgYnkgWFBhdGguCi0gICAgICovCi0gICAgcHVibGljIEVsZW1lbnQgZ2V0T3duZXJFbGVtZW50KCk7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvdzNjL2RvbS94cGF0aC9YUGF0aFJlc3VsdC5qYXZhIGIvc3JjL29yZy93M2MvZG9tL3hwYXRoL1hQYXRoUmVzdWx0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGQwNDIwMTEuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy93M2MvZG9tL3hwYXRoL1hQYXRoUmVzdWx0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyNDEgKzAsMCBAQAotLyoKLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLyoKLSAqIFRoaXMgZmlsZSBpcyBhdmFpbGFibGUgdW5kZXIgYW5kIGdvdmVybmVkIGJ5IHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKLSAqIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICogSG93ZXZlciwgdGhlIGZvbGxvd2luZyBub3RpY2UgYWNjb21wYW5pZWQgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcwotICogZmlsZSBhbmQsIHBlciBpdHMgdGVybXMsIHNob3VsZCBub3QgYmUgcmVtb3ZlZDoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDIgV29ybGQgV2lkZSBXZWIgQ29uc29ydGl1bSwKLSAqIChNYXNzYWNodXNldHRzIEluc3RpdHV0ZSBvZiBUZWNobm9sb2d5LCBJbnN0aXR1dCBOYXRpb25hbCBkZQotICogUmVjaGVyY2hlIGVuIEluZm9ybWF0aXF1ZSBldCBlbiBBdXRvbWF0aXF1ZSwgS2VpbyBVbml2ZXJzaXR5KS4gQWxsCi0gKiBSaWdodHMgUmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVzNDJ3MgU29mdHdhcmUKLSAqIEludGVsbGVjdHVhbCBQcm9wZXJ0eSBMaWNlbnNlLiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlCi0gKiBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuCi0gKiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCi0gKiBQVVJQT1NFLgotICogU2VlIFczQyBMaWNlbnNlIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvIGZvciBtb3JlIGRldGFpbHMuCi0gKi8KLQotcGFja2FnZSBvcmcudzNjLmRvbS54cGF0aDsKLQotCi1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcudzNjLmRvbS5ET01FeGNlcHRpb247Ci0KLS8qKgotICogVGhlIDxjb2RlPlhQYXRoUmVzdWx0PC9jb2RlPiBpbnRlcmZhY2UgcmVwcmVzZW50cyB0aGUgcmVzdWx0IG9mIHRoZQotICogZXZhbHVhdGlvbiBvZiBhbiBYUGF0aCAxLjAgZXhwcmVzc2lvbiB3aXRoaW4gdGhlIGNvbnRleHQgb2YgYSBwYXJ0aWN1bGFyCi0gKiBub2RlLiBTaW5jZSBldmFsdWF0aW9uIG9mIGFuIFhQYXRoIGV4cHJlc3Npb24gY2FuIHJlc3VsdCBpbiB2YXJpb3VzCi0gKiByZXN1bHQgdHlwZXMsIHRoaXMgb2JqZWN0IG1ha2VzIGl0IHBvc3NpYmxlIHRvIGRpc2NvdmVyIGFuZCBtYW5pcHVsYXRlCi0gKiB0aGUgdHlwZSBhbmQgdmFsdWUgb2YgdGhlIHJlc3VsdC4KLSAqIDxwPlNlZSBhbHNvIHRoZSA8YSBocmVmPSdodHRwOi8vd3d3LnczLm9yZy8yMDAyLzA4L1dELURPTS1MZXZlbC0zLVhQYXRoLTIwMDIwODIwJz5Eb2N1bWVudCBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMyBYUGF0aCBTcGVjaWZpY2F0aW9uPC9hPi4KLSAqLwotcHVibGljIGludGVyZmFjZSBYUGF0aFJlc3VsdCB7Ci0gICAgLy8gWFBhdGhSZXN1bHRUeXBlCi0gICAgLyoqCi0gICAgICogVGhpcyBjb2RlIGRvZXMgbm90IHJlcHJlc2VudCBhIHNwZWNpZmljIHR5cGUuIEFuIGV2YWx1YXRpb24gb2YgYW4gWFBhdGgKLSAgICAgKiBleHByZXNzaW9uIHdpbGwgbmV2ZXIgcHJvZHVjZSB0aGlzIHR5cGUuIElmIHRoaXMgdHlwZSBpcyByZXF1ZXN0ZWQsCi0gICAgICogdGhlbiB0aGUgZXZhbHVhdGlvbiByZXR1cm5zIHdoYXRldmVyIHR5cGUgbmF0dXJhbGx5IHJlc3VsdHMgZnJvbQotICAgICAqIGV2YWx1YXRpb24gb2YgdGhlIGV4cHJlc3Npb24uCi0gICAgICogPGJyPklmIHRoZSBuYXR1cmFsIHJlc3VsdCBpcyBhIG5vZGUgc2V0IHdoZW4gPGNvZGU+QU5ZX1RZUEU8L2NvZGU+IHdhcwotICAgICAqIHJlcXVlc3RlZCwgdGhlbiA8Y29kZT5VTk9SREVSRURfTk9ERV9JVEVSQVRPUl9UWVBFPC9jb2RlPiBpcyBhbHdheXMKLSAgICAgKiB0aGUgcmVzdWx0aW5nIHR5cGUuIEFueSBvdGhlciByZXByZXNlbnRhdGlvbiBvZiBhIG5vZGUgc2V0IG11c3QgYmUKLSAgICAgKiBleHBsaWNpdGx5IHJlcXVlc3RlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IEFOWV9UWVBFICAgICAgICAgICAgICAgICAgPSAwOwotICAgIC8qKgotICAgICAqIFRoZSByZXN1bHQgaXMgYSBudW1iZXIgYXMgZGVmaW5lZCBieSAuIERvY3VtZW50IG1vZGlmaWNhdGlvbiBkb2VzIG5vdAotICAgICAqIGludmFsaWRhdGUgdGhlIG51bWJlciwgYnV0IG1heSBtZWFuIHRoYXQgcmVldmFsdWF0aW9uIHdvdWxkIG5vdCB5aWVsZAotICAgICAqIHRoZSBzYW1lIG51bWJlci4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IE5VTUJFUl9UWVBFICAgICAgICAgICAgICAgPSAxOwotICAgIC8qKgotICAgICAqIFRoZSByZXN1bHQgaXMgYSBzdHJpbmcgYXMgZGVmaW5lZCBieSAuIERvY3VtZW50IG1vZGlmaWNhdGlvbiBkb2VzIG5vdAotICAgICAqIGludmFsaWRhdGUgdGhlIHN0cmluZywgYnV0IG1heSBtZWFuIHRoYXQgdGhlIHN0cmluZyBubyBsb25nZXIKLSAgICAgKiBjb3JyZXNwb25kcyB0byB0aGUgY3VycmVudCBkb2N1bWVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFNUUklOR19UWVBFICAgICAgICAgICAgICAgPSAyOwotICAgIC8qKgotICAgICAqIFRoZSByZXN1bHQgaXMgYSBib29sZWFuIGFzIGRlZmluZWQgYnkgLiBEb2N1bWVudCBtb2RpZmljYXRpb24gZG9lcyBub3QKLSAgICAgKiBpbnZhbGlkYXRlIHRoZSBib29sZWFuLCBidXQgbWF5IG1lYW4gdGhhdCByZWV2YWx1YXRpb24gd291bGQgbm90Ci0gICAgICogeWllbGQgdGhlIHNhbWUgYm9vbGVhbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IEJPT0xFQU5fVFlQRSAgICAgICAgICAgICAgPSAzOwotICAgIC8qKgotICAgICAqIFRoZSByZXN1bHQgaXMgYSBub2RlIHNldCBhcyBkZWZpbmVkIGJ5ICB0aGF0IHdpbGwgYmUgYWNjZXNzZWQKLSAgICAgKiBpdGVyYXRpdmVseSwgd2hpY2ggbWF5IG5vdCBwcm9kdWNlIG5vZGVzIGluIGEgcGFydGljdWxhciBvcmRlci4KLSAgICAgKiBEb2N1bWVudCBtb2RpZmljYXRpb24gaW52YWxpZGF0ZXMgdGhlIGl0ZXJhdGlvbi4KLSAgICAgKiA8YnI+VGhpcyBpcyB0aGUgZGVmYXVsdCB0eXBlIHJldHVybmVkIGlmIHRoZSByZXN1bHQgaXMgYSBub2RlIHNldCBhbmQKLSAgICAgKiA8Y29kZT5BTllfVFlQRTwvY29kZT4gaXMgcmVxdWVzdGVkLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgVU5PUkRFUkVEX05PREVfSVRFUkFUT1JfVFlQRSA9IDQ7Ci0gICAgLyoqCi0gICAgICogVGhlIHJlc3VsdCBpcyBhIG5vZGUgc2V0IGFzIGRlZmluZWQgYnkgIHRoYXQgd2lsbCBiZSBhY2Nlc3NlZAotICAgICAqIGl0ZXJhdGl2ZWx5LCB3aGljaCB3aWxsIHByb2R1Y2UgZG9jdW1lbnQtb3JkZXJlZCBub2Rlcy4gRG9jdW1lbnQKLSAgICAgKiBtb2RpZmljYXRpb24gaW52YWxpZGF0ZXMgdGhlIGl0ZXJhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IE9SREVSRURfTk9ERV9JVEVSQVRPUl9UWVBFID0gNTsKLSAgICAvKioKLSAgICAgKiBUaGUgcmVzdWx0IGlzIGEgbm9kZSBzZXQgYXMgZGVmaW5lZCBieSAgdGhhdCB3aWxsIGJlIGFjY2Vzc2VkIGFzIGEKLSAgICAgKiBzbmFwc2hvdCBsaXN0IG9mIG5vZGVzIHRoYXQgbWF5IG5vdCBiZSBpbiBhIHBhcnRpY3VsYXIgb3JkZXIuCi0gICAgICogRG9jdW1lbnQgbW9kaWZpY2F0aW9uIGRvZXMgbm90IGludmFsaWRhdGUgdGhlIHNuYXBzaG90IGJ1dCBtYXkgbWVhbgotICAgICAqIHRoYXQgcmVldmFsdWF0aW9uIHdvdWxkIG5vdCB5aWVsZCB0aGUgc2FtZSBzbmFwc2hvdCBhbmQgbm9kZXMgaW4gdGhlCi0gICAgICogc25hcHNob3QgbWF5IGhhdmUgYmVlbiBhbHRlcmVkLCBtb3ZlZCwgb3IgcmVtb3ZlZCBmcm9tIHRoZSBkb2N1bWVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFVOT1JERVJFRF9OT0RFX1NOQVBTSE9UX1RZUEUgPSA2OwotICAgIC8qKgotICAgICAqIFRoZSByZXN1bHQgaXMgYSBub2RlIHNldCBhcyBkZWZpbmVkIGJ5ICB0aGF0IHdpbGwgYmUgYWNjZXNzZWQgYXMgYQotICAgICAqIHNuYXBzaG90IGxpc3Qgb2Ygbm9kZXMgdGhhdCB3aWxsIGJlIGluIG9yaWdpbmFsIGRvY3VtZW50IG9yZGVyLgotICAgICAqIERvY3VtZW50IG1vZGlmaWNhdGlvbiBkb2VzIG5vdCBpbnZhbGlkYXRlIHRoZSBzbmFwc2hvdCBidXQgbWF5IG1lYW4KLSAgICAgKiB0aGF0IHJlZXZhbHVhdGlvbiB3b3VsZCBub3QgeWllbGQgdGhlIHNhbWUgc25hcHNob3QgYW5kIG5vZGVzIGluIHRoZQotICAgICAqIHNuYXBzaG90IG1heSBoYXZlIGJlZW4gYWx0ZXJlZCwgbW92ZWQsIG9yIHJlbW92ZWQgZnJvbSB0aGUgZG9jdW1lbnQuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBPUkRFUkVEX05PREVfU05BUFNIT1RfVFlQRSA9IDc7Ci0gICAgLyoqCi0gICAgICogVGhlIHJlc3VsdCBpcyBhIG5vZGUgc2V0IGFzIGRlZmluZWQgYnkgIGFuZCB3aWxsIGJlIGFjY2Vzc2VkIGFzIGEKLSAgICAgKiBzaW5nbGUgbm9kZSwgd2hpY2ggbWF5IGJlIDxjb2RlPm51bGw8L2NvZGU+aWYgdGhlIG5vZGUgc2V0IGlzIGVtcHR5LgotICAgICAqIERvY3VtZW50IG1vZGlmaWNhdGlvbiBkb2VzIG5vdCBpbnZhbGlkYXRlIHRoZSBub2RlLCBidXQgbWF5IG1lYW4gdGhhdAotICAgICAqIHRoZSByZXN1bHQgbm9kZSBubyBsb25nZXIgY29ycmVzcG9uZHMgdG8gdGhlIGN1cnJlbnQgZG9jdW1lbnQuIFRoaXMKLSAgICAgKiBpcyBhIGNvbnZlbmllbmNlIHRoYXQgcGVybWl0cyBvcHRpbWl6YXRpb24gc2luY2UgdGhlIGltcGxlbWVudGF0aW9uCi0gICAgICogY2FuIHN0b3Agb25jZSBhbnkgbm9kZSBpbiB0aGUgaW4gdGhlIHJlc3VsdGluZyBzZXQgaGFzIGJlZW4gZm91bmQuCi0gICAgICogPGJyPklmIHRoZXJlIGFyZSBtb3JlIHRoYW4gb25lIG5vZGUgaW4gdGhlIGFjdHVhbCByZXN1bHQsIHRoZSBzaW5nbGUKLSAgICAgKiBub2RlIHJldHVybmVkIG1pZ2h0IG5vdCBiZSB0aGUgZmlyc3QgaW4gZG9jdW1lbnQgb3JkZXIuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBBTllfVU5PUkRFUkVEX05PREVfVFlQRSAgID0gODsKLSAgICAvKioKLSAgICAgKiBUaGUgcmVzdWx0IGlzIGEgbm9kZSBzZXQgYXMgZGVmaW5lZCBieSAgYW5kIHdpbGwgYmUgYWNjZXNzZWQgYXMgYQotICAgICAqIHNpbmdsZSBub2RlLCB3aGljaCBtYXkgYmUgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlIG5vZGUgc2V0IGlzIGVtcHR5LgotICAgICAqIERvY3VtZW50IG1vZGlmaWNhdGlvbiBkb2VzIG5vdCBpbnZhbGlkYXRlIHRoZSBub2RlLCBidXQgbWF5IG1lYW4gdGhhdAotICAgICAqIHRoZSByZXN1bHQgbm9kZSBubyBsb25nZXIgY29ycmVzcG9uZHMgdG8gdGhlIGN1cnJlbnQgZG9jdW1lbnQuIFRoaXMKLSAgICAgKiBpcyBhIGNvbnZlbmllbmNlIHRoYXQgcGVybWl0cyBvcHRpbWl6YXRpb24gc2luY2UgdGhlIGltcGxlbWVudGF0aW9uCi0gICAgICogY2FuIHN0b3Agb25jZSB0aGUgZmlyc3Qgbm9kZSBpbiBkb2N1bWVudCBvcmRlciBvZiB0aGUgcmVzdWx0aW5nIHNldAotICAgICAqIGhhcyBiZWVuIGZvdW5kLgotICAgICAqIDxicj5JZiB0aGVyZSBhcmUgbW9yZSB0aGFuIG9uZSBub2RlIGluIHRoZSBhY3R1YWwgcmVzdWx0LCB0aGUgc2luZ2xlCi0gICAgICogbm9kZSByZXR1cm5lZCB3aWxsIGJlIHRoZSBmaXJzdCBpbiBkb2N1bWVudCBvcmRlci4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IEZJUlNUX09SREVSRURfTk9ERV9UWVBFICAgPSA5OwotCi0gICAgLyoqCi0gICAgICogQSBjb2RlIHJlcHJlc2VudGluZyB0aGUgdHlwZSBvZiB0aGlzIHJlc3VsdCwgYXMgZGVmaW5lZCBieSB0aGUgdHlwZQotICAgICAqIGNvbnN0YW50cy4KLSAgICAgKi8KLSAgICBwdWJsaWMgc2hvcnQgZ2V0UmVzdWx0VHlwZSgpOwotCi0gICAgLyoqCi0gICAgICogVGhlIHZhbHVlIG9mIHRoaXMgbnVtYmVyIHJlc3VsdC4gSWYgdGhlIG5hdGl2ZSBkb3VibGUgdHlwZSBvZiB0aGUgRE9NCi0gICAgICogYmluZGluZyBkb2VzIG5vdCBkaXJlY3RseSBzdXBwb3J0IHRoZSBleGFjdCBJRUVFIDc1NCByZXN1bHQgb2YgdGhlCi0gICAgICogWFBhdGggZXhwcmVzc2lvbiwgdGhlbiBpdCBpcyB1cCB0byB0aGUgZGVmaW5pdGlvbiBvZiB0aGUgYmluZGluZwotICAgICAqIGJpbmRpbmcgdG8gc3BlY2lmeSBob3cgdGhlIFhQYXRoIG51bWJlciBpcyBjb252ZXJ0ZWQgdG8gdGhlIG5hdGl2ZQotICAgICAqIGJpbmRpbmcgbnVtYmVyLgotICAgICAqIEBleGNlcHRpb24gWFBhdGhFeGNlcHRpb24KLSAgICAgKiAgIFRZUEVfRVJSOiByYWlzZWQgaWYgPGNvZGU+cmVzdWx0VHlwZTwvY29kZT4gaXMgbm90Ci0gICAgICogICA8Y29kZT5OVU1CRVJfVFlQRTwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIGRvdWJsZSBnZXROdW1iZXJWYWx1ZSgpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBYUGF0aEV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIFRoZSB2YWx1ZSBvZiB0aGlzIHN0cmluZyByZXN1bHQuCi0gICAgICogQGV4Y2VwdGlvbiBYUGF0aEV4Y2VwdGlvbgotICAgICAqICAgVFlQRV9FUlI6IHJhaXNlZCBpZiA8Y29kZT5yZXN1bHRUeXBlPC9jb2RlPiBpcyBub3QKLSAgICAgKiAgIDxjb2RlPlNUUklOR19UWVBFPC9jb2RlPi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFN0cmluZ1ZhbHVlKCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIFhQYXRoRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogVGhlIHZhbHVlIG9mIHRoaXMgYm9vbGVhbiByZXN1bHQuCi0gICAgICogQGV4Y2VwdGlvbiBYUGF0aEV4Y2VwdGlvbgotICAgICAqICAgVFlQRV9FUlI6IHJhaXNlZCBpZiA8Y29kZT5yZXN1bHRUeXBlPC9jb2RlPiBpcyBub3QKLSAgICAgKiAgIDxjb2RlPkJPT0xFQU5fVFlQRTwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0Qm9vbGVhblZhbHVlKCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIFhQYXRoRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogVGhlIHZhbHVlIG9mIHRoaXMgc2luZ2xlIG5vZGUgcmVzdWx0LCB3aGljaCBtYXkgYmUgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICogQGV4Y2VwdGlvbiBYUGF0aEV4Y2VwdGlvbgotICAgICAqICAgVFlQRV9FUlI6IHJhaXNlZCBpZiA8Y29kZT5yZXN1bHRUeXBlPC9jb2RlPiBpcyBub3QKLSAgICAgKiAgIDxjb2RlPkFOWV9VTk9SREVSRURfTk9ERV9UWVBFPC9jb2RlPiBvcgotICAgICAqICAgPGNvZGU+RklSU1RfT1JERVJFRF9OT0RFX1RZUEU8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBOb2RlIGdldFNpbmdsZU5vZGVWYWx1ZSgpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBYUGF0aEV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIFNpZ25pZmllcyB0aGF0IHRoZSBpdGVyYXRvciBoYXMgYmVjb21lIGludmFsaWQuIFRydWUgaWYKLSAgICAgKiA8Y29kZT5yZXN1bHRUeXBlPC9jb2RlPiBpcyA8Y29kZT5VTk9SREVSRURfTk9ERV9JVEVSQVRPUl9UWVBFPC9jb2RlPgotICAgICAqIG9yIDxjb2RlPk9SREVSRURfTk9ERV9JVEVSQVRPUl9UWVBFPC9jb2RlPiBhbmQgdGhlIGRvY3VtZW50IGhhcyBiZWVuCi0gICAgICogbW9kaWZpZWQgc2luY2UgdGhpcyByZXN1bHQgd2FzIHJldHVybmVkLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGdldEludmFsaWRJdGVyYXRvclN0YXRlKCk7Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgbnVtYmVyIG9mIG5vZGVzIGluIHRoZSByZXN1bHQgc25hcHNob3QuIFZhbGlkIHZhbHVlcyBmb3IKLSAgICAgKiBzbmFwc2hvdEl0ZW0gaW5kaWNlcyBhcmUgPGNvZGU+MDwvY29kZT4gdG8KLSAgICAgKiA8Y29kZT5zbmFwc2hvdExlbmd0aC0xPC9jb2RlPiBpbmNsdXNpdmUuCi0gICAgICogQGV4Y2VwdGlvbiBYUGF0aEV4Y2VwdGlvbgotICAgICAqICAgVFlQRV9FUlI6IHJhaXNlZCBpZiA8Y29kZT5yZXN1bHRUeXBlPC9jb2RlPiBpcyBub3QKLSAgICAgKiAgIDxjb2RlPlVOT1JERVJFRF9OT0RFX1NOQVBTSE9UX1RZUEU8L2NvZGU+IG9yCi0gICAgICogICA8Y29kZT5PUkRFUkVEX05PREVfU05BUFNIT1RfVFlQRTwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRTbmFwc2hvdExlbmd0aCgpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBYUGF0aEV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIEl0ZXJhdGVzIGFuZCByZXR1cm5zIHRoZSBuZXh0IG5vZGUgZnJvbSB0aGUgbm9kZSBzZXQgb3IKLSAgICAgKiA8Y29kZT5udWxsPC9jb2RlPmlmIHRoZXJlIGFyZSBubyBtb3JlIG5vZGVzLgotICAgICAqIEByZXR1cm4gUmV0dXJucyB0aGUgbmV4dCBub2RlLgotICAgICAqIEBleGNlcHRpb24gWFBhdGhFeGNlcHRpb24KLSAgICAgKiAgIFRZUEVfRVJSOiByYWlzZWQgaWYgPGNvZGU+cmVzdWx0VHlwZTwvY29kZT4gaXMgbm90Ci0gICAgICogICA8Y29kZT5VTk9SREVSRURfTk9ERV9JVEVSQVRPUl9UWVBFPC9jb2RlPiBvcgotICAgICAqICAgPGNvZGU+T1JERVJFRF9OT0RFX0lURVJBVE9SX1RZUEU8L2NvZGU+LgotICAgICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAgICogICBJTlZBTElEX1NUQVRFX0VSUjogVGhlIGRvY3VtZW50IGhhcyBiZWVuIG11dGF0ZWQgc2luY2UgdGhlIHJlc3VsdCB3YXMKLSAgICAgKiAgIHJldHVybmVkLgotICAgICAqLwotICAgIHB1YmxpYyBOb2RlIGl0ZXJhdGVOZXh0KCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgWFBhdGhFeGNlcHRpb24sIERPTUV4Y2VwdGlvbjsKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIDxjb2RlPmluZGV4PC9jb2RlPnRoIGl0ZW0gaW4gdGhlIHNuYXBzaG90IGNvbGxlY3Rpb24uIElmCi0gICAgICogPGNvZGU+aW5kZXg8L2NvZGU+IGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byB0aGUgbnVtYmVyIG9mIG5vZGVzIGluCi0gICAgICogdGhlIGxpc3QsIHRoaXMgbWV0aG9kIHJldHVybnMgPGNvZGU+bnVsbDwvY29kZT4uIFVubGlrZSB0aGUgaXRlcmF0b3IKLSAgICAgKiByZXN1bHQsIHRoZSBzbmFwc2hvdCBkb2VzIG5vdCBiZWNvbWUgaW52YWxpZCwgYnV0IG1heSBub3QgY29ycmVzcG9uZAotICAgICAqIHRvIHRoZSBjdXJyZW50IGRvY3VtZW50IGlmIGl0IGlzIG11dGF0ZWQuCi0gICAgICogQHBhcmFtIGluZGV4IEluZGV4IGludG8gdGhlIHNuYXBzaG90IGNvbGxlY3Rpb24uCi0gICAgICogQHJldHVybiBUaGUgbm9kZSBhdCB0aGUgPGNvZGU+aW5kZXg8L2NvZGU+dGggcG9zaXRpb24gaW4gdGhlCi0gICAgICogICA8Y29kZT5Ob2RlTGlzdDwvY29kZT4sIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoYXQgaXMgbm90IGEgdmFsaWQKLSAgICAgKiAgIGluZGV4LgotICAgICAqIEBleGNlcHRpb24gWFBhdGhFeGNlcHRpb24KLSAgICAgKiAgIFRZUEVfRVJSOiByYWlzZWQgaWYgPGNvZGU+cmVzdWx0VHlwZTwvY29kZT4gaXMgbm90Ci0gICAgICogICA8Y29kZT5VTk9SREVSRURfTk9ERV9TTkFQU0hPVF9UWVBFPC9jb2RlPiBvcgotICAgICAqICAgPGNvZGU+T1JERVJFRF9OT0RFX1NOQVBTSE9UX1RZUEU8L2NvZGU+LgotICAgICAqLwotICAgIHB1YmxpYyBOb2RlIHNuYXBzaG90SXRlbShpbnQgaW5kZXgpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBYUGF0aEV4Y2VwdGlvbjsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy94bWwvc2F4L0F0dHJpYnV0ZUxpc3QuamF2YSBiL3NyYy9vcmcveG1sL3NheC9BdHRyaWJ1dGVMaXN0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDA3ZWUzZGQuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy94bWwvc2F4L0F0dHJpYnV0ZUxpc3QuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIxNyArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDAwLCAyMDA1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vLyBTQVggQXR0cmlidXRlIExpc3QgSW50ZXJmYWNlLgotLy8gaHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZwotLy8gTm8gd2FycmFudHk7IG5vIGNvcHlyaWdodCAtLSB1c2UgdGhpcyBhcyB5b3Ugd2lsbC4KLS8vICRJZDogQXR0cmlidXRlTGlzdC5qYXZhLHYgMS4zIDIwMDQvMTEvMDMgMjI6NDQ6NTEganN1dHRvciBFeHAgJAotCi1wYWNrYWdlIG9yZy54bWwuc2F4OwotCi0vKioKLSAqIEludGVyZmFjZSBmb3IgYW4gZWxlbWVudCdzIGF0dHJpYnV0ZSBzcGVjaWZpY2F0aW9ucy4KLSAqCi0gKiA8YmxvY2txdW90ZT4KLSAqIDxlbT5UaGlzIG1vZHVsZSwgYm90aCBzb3VyY2UgY29kZSBhbmQgZG9jdW1lbnRhdGlvbiwgaXMgaW4gdGhlCi0gKiBQdWJsaWMgRG9tYWluLCBhbmQgY29tZXMgd2l0aCA8c3Ryb25nPk5PIFdBUlJBTlRZPC9zdHJvbmc+LjwvZW0+Ci0gKiBTZWUgPGEgaHJlZj0naHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZyc+aHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZzwvYT4KLSAqIGZvciBmdXJ0aGVyIGluZm9ybWF0aW9uLgotICogPC9ibG9ja3F1b3RlPgotICoKLSAqIDxwPlRoaXMgaXMgdGhlIG9yaWdpbmFsIFNBWDEgaW50ZXJmYWNlIGZvciByZXBvcnRpbmcgYW4gZWxlbWVudCdzCi0gKiBhdHRyaWJ1dGVzLiAgVW5saWtlIHRoZSBuZXcge0BsaW5rIG9yZy54bWwuc2F4LkF0dHJpYnV0ZXMgQXR0cmlidXRlc30KLSAqIGludGVyZmFjZSwgaXQgZG9lcyBub3Qgc3VwcG9ydCBOYW1lc3BhY2UtcmVsYXRlZCBpbmZvcm1hdGlvbi48L3A+Ci0gKgotICogPHA+V2hlbiBhbiBhdHRyaWJ1dGUgbGlzdCBpcyBzdXBwbGllZCBhcyBwYXJ0IG9mIGEKLSAqIHtAbGluayBvcmcueG1sLnNheC5Eb2N1bWVudEhhbmRsZXIjc3RhcnRFbGVtZW50IHN0YXJ0RWxlbWVudH0KLSAqIGV2ZW50LCB0aGUgbGlzdCB3aWxsIHJldHVybiB2YWxpZCByZXN1bHRzIG9ubHkgZHVyaW5nIHRoZQotICogc2NvcGUgb2YgdGhlIGV2ZW50OyBvbmNlIHRoZSBldmVudCBoYW5kbGVyIHJldHVybnMgY29udHJvbAotICogdG8gdGhlIHBhcnNlciwgdGhlIGF0dHJpYnV0ZSBsaXN0IGlzIGludmFsaWQuICBUbyBzYXZlIGEKLSAqIHBlcnNpc3RlbnQgY29weSBvZiB0aGUgYXR0cmlidXRlIGxpc3QsIHVzZSB0aGUgU0FYMQotICoge0BsaW5rIG9yZy54bWwuc2F4LmhlbHBlcnMuQXR0cmlidXRlTGlzdEltcGwgQXR0cmlidXRlTGlzdEltcGx9Ci0gKiBoZWxwZXIgY2xhc3MuPC9wPgotICoKLSAqIDxwPkFuIGF0dHJpYnV0ZSBsaXN0IGluY2x1ZGVzIG9ubHkgYXR0cmlidXRlcyB0aGF0IGhhdmUgYmVlbgotICogc3BlY2lmaWVkIG9yIGRlZmF1bHRlZDogI0lNUExJRUQgYXR0cmlidXRlcyB3aWxsIG5vdCBiZSBpbmNsdWRlZC48L3A+Ci0gKgotICogPHA+VGhlcmUgYXJlIHR3byB3YXlzIGZvciB0aGUgU0FYIGFwcGxpY2F0aW9uIHRvIG9idGFpbiBpbmZvcm1hdGlvbgotICogZnJvbSB0aGUgQXR0cmlidXRlTGlzdC4gIEZpcnN0LCBpdCBjYW4gaXRlcmF0ZSB0aHJvdWdoIHRoZSBlbnRpcmUKLSAqIGxpc3Q6PC9wPgotICoKLSAqIDxwcmU+Ci0gKiBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQgKFN0cmluZyBuYW1lLCBBdHRyaWJ1dGVMaXN0IGF0dHMpIHsKLSAqICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhdHRzLmdldExlbmd0aCgpOyBpKyspIHsKLSAqICAgICBTdHJpbmcgbmFtZSA9IGF0dHMuZ2V0TmFtZShpKTsKLSAqICAgICBTdHJpbmcgdHlwZSA9IGF0dHMuZ2V0VHlwZShpKTsKLSAqICAgICBTdHJpbmcgdmFsdWUgPSBhdHRzLmdldFZhbHVlKGkpOwotICogICAgIFsuLi5dCi0gKiAgIH0KLSAqIH0KLSAqIDwvcHJlPgotICoKLSAqIDxwPihOb3RlIHRoYXQgdGhlIHJlc3VsdCBvZiBnZXRMZW5ndGgoKSB3aWxsIGJlIHplcm8gaWYgdGhlcmUKLSAqIGFyZSBubyBhdHRyaWJ1dGVzLikKLSAqCi0gKiA8cD5BcyBhbiBhbHRlcm5hdGl2ZSwgdGhlIGFwcGxpY2F0aW9uIGNhbiByZXF1ZXN0IHRoZSB2YWx1ZSBvcgotICogdHlwZSBvZiBzcGVjaWZpYyBhdHRyaWJ1dGVzOjwvcD4KLSAqCi0gKiA8cHJlPgotICogcHVibGljIHZvaWQgc3RhcnRFbGVtZW50IChTdHJpbmcgbmFtZSwgQXR0cmlidXRlTGlzdCBhdHRzKSB7Ci0gKiAgIFN0cmluZyBpZGVudGlmaWVyID0gYXR0cy5nZXRWYWx1ZSgiaWQiKTsKLSAqICAgU3RyaW5nIGxhYmVsID0gYXR0cy5nZXRWYWx1ZSgibGFiZWwiKTsKLSAqICAgWy4uLl0KLSAqIH0KLSAqIDwvcHJlPgotICoKLSAqIEBkZXByZWNhdGVkIFRoaXMgaW50ZXJmYWNlIGhhcyBiZWVuIHJlcGxhY2VkIGJ5IHRoZSBTQVgyCi0gKiAgICAgICAgICAgICB7QGxpbmsgb3JnLnhtbC5zYXguQXR0cmlidXRlcyBBdHRyaWJ1dGVzfQotICogICAgICAgICAgICAgaW50ZXJmYWNlLCB3aGljaCBpbmNsdWRlcyBOYW1lc3BhY2Ugc3VwcG9ydC4KLSAqIEBzaW5jZSBTQVggMS4wCi0gKiBAYXV0aG9yIERhdmlkIE1lZ2dpbnNvbgotICogQHNlZSBvcmcueG1sLnNheC5Eb2N1bWVudEhhbmRsZXIjc3RhcnRFbGVtZW50IHN0YXJ0RWxlbWVudAotICogQHNlZSBvcmcueG1sLnNheC5oZWxwZXJzLkF0dHJpYnV0ZUxpc3RJbXBsIEF0dHJpYnV0ZUxpc3RJbXBsCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgQXR0cmlidXRlTGlzdCB7Ci0KLQotICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0gICAgLy8gSXRlcmF0aW9uIG1ldGhvZHMuCi0gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSBudW1iZXIgb2YgYXR0cmlidXRlcyBpbiB0aGlzIGxpc3QuCi0gICAgICoKLSAgICAgKiA8cD5UaGUgU0FYIHBhcnNlciBtYXkgcHJvdmlkZSBhdHRyaWJ1dGVzIGluIGFueQotICAgICAqIGFyYml0cmFyeSBvcmRlciwgcmVnYXJkbGVzcyBvZiB0aGUgb3JkZXIgaW4gd2hpY2ggdGhleSB3ZXJlCi0gICAgICogZGVjbGFyZWQgb3Igc3BlY2lmaWVkLiAgVGhlIG51bWJlciBvZiBhdHRyaWJ1dGVzIG1heSBiZQotICAgICAqIHplcm8uPC9wPgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgbnVtYmVyIG9mIGF0dHJpYnV0ZXMgaW4gdGhlIGxpc3QuCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IGludCBnZXRMZW5ndGggKCk7Ci0KLQotICAgIC8qKgotICAgICAqIFJldHVybiB0aGUgbmFtZSBvZiBhbiBhdHRyaWJ1dGUgaW4gdGhpcyBsaXN0IChieSBwb3NpdGlvbikuCi0gICAgICoKLSAgICAgKiA8cD5UaGUgbmFtZXMgbXVzdCBiZSB1bmlxdWU6IHRoZSBTQVggcGFyc2VyIHNoYWxsIG5vdCBpbmNsdWRlIHRoZQotICAgICAqIHNhbWUgYXR0cmlidXRlIHR3aWNlLiAgQXR0cmlidXRlcyB3aXRob3V0IHZhbHVlcyAodGhvc2UgZGVjbGFyZWQKLSAgICAgKiAjSU1QTElFRCB3aXRob3V0IGEgdmFsdWUgc3BlY2lmaWVkIGluIHRoZSBzdGFydCB0YWcpIHdpbGwgYmUKLSAgICAgKiBvbWl0dGVkIGZyb20gdGhlIGxpc3QuPC9wPgotICAgICAqCi0gICAgICogPHA+SWYgdGhlIGF0dHJpYnV0ZSBuYW1lIGhhcyBhIG5hbWVzcGFjZSBwcmVmaXgsIHRoZSBwcmVmaXgKLSAgICAgKiB3aWxsIHN0aWxsIGJlIGF0dGFjaGVkLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBpIFRoZSBpbmRleCBvZiB0aGUgYXR0cmlidXRlIGluIHRoZSBsaXN0IChzdGFydGluZyBhdCAwKS4KLSAgICAgKiBAcmV0dXJuIFRoZSBuYW1lIG9mIHRoZSBpbmRleGVkIGF0dHJpYnV0ZSwgb3IgbnVsbAotICAgICAqICAgICAgICAgaWYgdGhlIGluZGV4IGlzIG91dCBvZiByYW5nZS4KLSAgICAgKiBAc2VlICNnZXRMZW5ndGgKLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nIGdldE5hbWUgKGludCBpKTsKLQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSB0eXBlIG9mIGFuIGF0dHJpYnV0ZSBpbiB0aGUgbGlzdCAoYnkgcG9zaXRpb24pLgotICAgICAqCi0gICAgICogPHA+VGhlIGF0dHJpYnV0ZSB0eXBlIGlzIG9uZSBvZiB0aGUgc3RyaW5ncyAiQ0RBVEEiLCAiSUQiLAotICAgICAqICJJRFJFRiIsICJJRFJFRlMiLCAiTk1UT0tFTiIsICJOTVRPS0VOUyIsICJFTlRJVFkiLCAiRU5USVRJRVMiLAotICAgICAqIG9yICJOT1RBVElPTiIgKGFsd2F5cyBpbiB1cHBlciBjYXNlKS48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5JZiB0aGUgcGFyc2VyIGhhcyBub3QgcmVhZCBhIGRlY2xhcmF0aW9uIGZvciB0aGUgYXR0cmlidXRlLAotICAgICAqIG9yIGlmIHRoZSBwYXJzZXIgZG9lcyBub3QgcmVwb3J0IGF0dHJpYnV0ZSB0eXBlcywgdGhlbiBpdCBtdXN0Ci0gICAgICogcmV0dXJuIHRoZSB2YWx1ZSAiQ0RBVEEiIGFzIHN0YXRlZCBpbiB0aGUgWE1MIDEuMCBSZWNvbW1lbnRhdGlvbgotICAgICAqIChjbGF1c2UgMy4zLjMsICJBdHRyaWJ1dGUtVmFsdWUgTm9ybWFsaXphdGlvbiIpLjwvcD4KLSAgICAgKgotICAgICAqIDxwPkZvciBhbiBlbnVtZXJhdGVkIGF0dHJpYnV0ZSB0aGF0IGlzIG5vdCBhIG5vdGF0aW9uLCB0aGUKLSAgICAgKiBwYXJzZXIgd2lsbCByZXBvcnQgdGhlIHR5cGUgYXMgIk5NVE9LRU4iLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBpIFRoZSBpbmRleCBvZiB0aGUgYXR0cmlidXRlIGluIHRoZSBsaXN0IChzdGFydGluZyBhdCAwKS4KLSAgICAgKiBAcmV0dXJuIFRoZSBhdHRyaWJ1dGUgdHlwZSBhcyBhIHN0cmluZywgb3IKLSAgICAgKiAgICAgICAgIG51bGwgaWYgdGhlIGluZGV4IGlzIG91dCBvZiByYW5nZS4KLSAgICAgKiBAc2VlICNnZXRMZW5ndGgKLSAgICAgKiBAc2VlICNnZXRUeXBlKGphdmEubGFuZy5TdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IFN0cmluZyBnZXRUeXBlIChpbnQgaSk7Ci0KLQotICAgIC8qKgotICAgICAqIFJldHVybiB0aGUgdmFsdWUgb2YgYW4gYXR0cmlidXRlIGluIHRoZSBsaXN0IChieSBwb3NpdGlvbikuCi0gICAgICoKLSAgICAgKiA8cD5JZiB0aGUgYXR0cmlidXRlIHZhbHVlIGlzIGEgbGlzdCBvZiB0b2tlbnMgKElEUkVGUywKLSAgICAgKiBFTlRJVElFUywgb3IgTk1UT0tFTlMpLCB0aGUgdG9rZW5zIHdpbGwgYmUgY29uY2F0ZW5hdGVkCi0gICAgICogaW50byBhIHNpbmdsZSBzdHJpbmcgc2VwYXJhdGVkIGJ5IHdoaXRlc3BhY2UuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGkgVGhlIGluZGV4IG9mIHRoZSBhdHRyaWJ1dGUgaW4gdGhlIGxpc3QgKHN0YXJ0aW5nIGF0IDApLgotICAgICAqIEByZXR1cm4gVGhlIGF0dHJpYnV0ZSB2YWx1ZSBhcyBhIHN0cmluZywgb3IKLSAgICAgKiAgICAgICAgIG51bGwgaWYgdGhlIGluZGV4IGlzIG91dCBvZiByYW5nZS4KLSAgICAgKiBAc2VlICNnZXRMZW5ndGgKLSAgICAgKiBAc2VlICNnZXRWYWx1ZShqYXZhLmxhbmcuU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCBTdHJpbmcgZ2V0VmFsdWUgKGludCBpKTsKLQotCi0KLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotICAgIC8vIExvb2t1cCBtZXRob2RzLgotICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0KLQotICAgIC8qKgotICAgICAqIFJldHVybiB0aGUgdHlwZSBvZiBhbiBhdHRyaWJ1dGUgaW4gdGhlIGxpc3QgKGJ5IG5hbWUpLgotICAgICAqCi0gICAgICogPHA+VGhlIHJldHVybiB2YWx1ZSBpcyB0aGUgc2FtZSBhcyB0aGUgcmV0dXJuIHZhbHVlIGZvcgotICAgICAqIGdldFR5cGUoaW50KS48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5JZiB0aGUgYXR0cmlidXRlIG5hbWUgaGFzIGEgbmFtZXNwYWNlIHByZWZpeCBpbiB0aGUgZG9jdW1lbnQsCi0gICAgICogdGhlIGFwcGxpY2F0aW9uIG11c3QgaW5jbHVkZSB0aGUgcHJlZml4IGhlcmUuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgKiBAcmV0dXJuIFRoZSBhdHRyaWJ1dGUgdHlwZSBhcyBhIHN0cmluZywgb3IgbnVsbCBpZiBubwotICAgICAqICAgICAgICAgc3VjaCBhdHRyaWJ1dGUgZXhpc3RzLgotICAgICAqIEBzZWUgI2dldFR5cGUoaW50KQotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCBTdHJpbmcgZ2V0VHlwZSAoU3RyaW5nIG5hbWUpOwotCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIHZhbHVlIG9mIGFuIGF0dHJpYnV0ZSBpbiB0aGUgbGlzdCAoYnkgbmFtZSkuCi0gICAgICoKLSAgICAgKiA8cD5UaGUgcmV0dXJuIHZhbHVlIGlzIHRoZSBzYW1lIGFzIHRoZSByZXR1cm4gdmFsdWUgZm9yCi0gICAgICogZ2V0VmFsdWUoaW50KS48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5JZiB0aGUgYXR0cmlidXRlIG5hbWUgaGFzIGEgbmFtZXNwYWNlIHByZWZpeCBpbiB0aGUgZG9jdW1lbnQsCi0gICAgICogdGhlIGFwcGxpY2F0aW9uIG11c3QgaW5jbHVkZSB0aGUgcHJlZml4IGhlcmUuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZSB0byByZXR1cm4KLSAgICAgKiBAcmV0dXJuIFRoZSBhdHRyaWJ1dGUgdmFsdWUgYXMgYSBzdHJpbmcsIG9yIG51bGwgaWYKLSAgICAgKiAgICAgICAgIG5vIHN1Y2ggYXR0cmlidXRlIGV4aXN0cy4KLSAgICAgKiBAc2VlICNnZXRWYWx1ZShpbnQpCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IFN0cmluZyBnZXRWYWx1ZSAoU3RyaW5nIG5hbWUpOwotCi19Ci0KLS8vIGVuZCBvZiBBdHRyaWJ1dGVMaXN0LmphdmEKZGlmZiAtLWdpdCBhL3NyYy9vcmcveG1sL3NheC9BdHRyaWJ1dGVzLmphdmEgYi9zcmMvb3JnL3htbC9zYXgvQXR0cmlidXRlcy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMjAyYWE0Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcveG1sL3NheC9BdHRyaWJ1dGVzLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyODEgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwMCwgMjAwNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLy8gQXR0cmlidXRlcy5qYXZhIC0gYXR0cmlidXRlIGxpc3Qgd2l0aCBOYW1lc3BhY2Ugc3VwcG9ydAotLy8gaHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZwotLy8gV3JpdHRlbiBieSBEYXZpZCBNZWdnaW5zb24KLS8vIE5PIFdBUlJBTlRZISAgVGhpcyBjbGFzcyBpcyBpbiB0aGUgcHVibGljIGRvbWFpbi4KLS8vICRJZDogQXR0cmlidXRlcy5qYXZhLHYgMS4yIDIwMDQvMTEvMDMgMjI6NDQ6NTEganN1dHRvciBFeHAgJAotCi1wYWNrYWdlIG9yZy54bWwuc2F4OwotCi0KLS8qKgotICogSW50ZXJmYWNlIGZvciBhIGxpc3Qgb2YgWE1MIGF0dHJpYnV0ZXMuCi0gKgotICogPGJsb2NrcXVvdGU+Ci0gKiA8ZW0+VGhpcyBtb2R1bGUsIGJvdGggc291cmNlIGNvZGUgYW5kIGRvY3VtZW50YXRpb24sIGlzIGluIHRoZQotICogUHVibGljIERvbWFpbiwgYW5kIGNvbWVzIHdpdGggPHN0cm9uZz5OTyBXQVJSQU5UWTwvc3Ryb25nPi48L2VtPgotICogU2VlIDxhIGhyZWY9J2h0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmcnPmh0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmc8L2E+Ci0gKiBmb3IgZnVydGhlciBpbmZvcm1hdGlvbi4KLSAqIDwvYmxvY2txdW90ZT4KLSAqCi0gKiA8cD5UaGlzIGludGVyZmFjZSBhbGxvd3MgYWNjZXNzIHRvIGEgbGlzdCBvZiBhdHRyaWJ1dGVzIGluCi0gKiB0aHJlZSBkaWZmZXJlbnQgd2F5czo8L3A+Ci0gKgotICogPG9sPgotICogPGxpPmJ5IGF0dHJpYnV0ZSBpbmRleDs8L2xpPgotICogPGxpPmJ5IE5hbWVzcGFjZS1xdWFsaWZpZWQgbmFtZTsgb3I8L2xpPgotICogPGxpPmJ5IHF1YWxpZmllZCAocHJlZml4ZWQpIG5hbWUuPC9saT4KLSAqIDwvb2w+Ci0gKgotICogPHA+VGhlIGxpc3Qgd2lsbCBub3QgY29udGFpbiBhdHRyaWJ1dGVzIHRoYXQgd2VyZSBkZWNsYXJlZAotICogI0lNUExJRUQgYnV0IG5vdCBzcGVjaWZpZWQgaW4gdGhlIHN0YXJ0IHRhZy4gIEl0IHdpbGwgYWxzbyBub3QKLSAqIGNvbnRhaW4gYXR0cmlidXRlcyB1c2VkIGFzIE5hbWVzcGFjZSBkZWNsYXJhdGlvbnMgKHhtbG5zKikgdW5sZXNzCi0gKiB0aGUgPGNvZGU+aHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL25hbWVzcGFjZS1wcmVmaXhlczwvY29kZT4KLSAqIGZlYXR1cmUgaXMgc2V0IHRvIDx2YXI+dHJ1ZTwvdmFyPiAoaXQgaXMgPHZhcj5mYWxzZTwvdmFyPiBieQotICogZGVmYXVsdCkuCi0gKiBCZWNhdXNlIFNBWDIgY29uZm9ybXMgdG8gdGhlIG9yaWdpbmFsICJOYW1lc3BhY2VzIGluIFhNTCIKLSAqIHJlY29tbWVuZGF0aW9uLCBpdCBub3JtYWxseSBkb2VzIG5vdAotICogZ2l2ZSBuYW1lc3BhY2UgZGVjbGFyYXRpb24gYXR0cmlidXRlcyBhIG5hbWVzcGFjZSBVUkkuCi0gKiA8L3A+Ci0gKgotICogPHA+U29tZSBTQVgyIHBhcnNlcnMgbWF5IHN1cHBvcnQgdXNpbmcgYW4gb3B0aW9uYWwgZmVhdHVyZSBmbGFnCi0gKiAoPGNvZGU+aHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL3htbG5zLXVyaXM8L2NvZGU+KSB0byByZXF1ZXN0Ci0gKiB0aGF0IHRob3NlIGF0dHJpYnV0ZXMgYmUgZ2l2ZW4gVVJJcywgY29uZm9ybWluZyB0byBhIGxhdGVyCi0gKiBiYWNrd2FyZHMtaW5jb21wYXRpYmxlIHJldmlzaW9uIG9mIHRoYXQgcmVjb21tZW5kYXRpb24uICAoVGhlCi0gKiBhdHRyaWJ1dGUncyAibG9jYWwgbmFtZSIgd2lsbCBiZSB0aGUgcHJlZml4LCBvciAieG1sbnMiIHdoZW4KLSAqIGRlZmluaW5nIGEgZGVmYXVsdCBlbGVtZW50IG5hbWVzcGFjZS4pICBGb3IgcG9ydGFiaWxpdHksIGhhbmRsZXIKLSAqIGNvZGUgc2hvdWxkIGFsd2F5cyByZXNvbHZlIHRoYXQgY29uZmxpY3QsIHJhdGhlciB0aGFuIHJlcXVpcmluZwotICogcGFyc2VycyB0aGF0IGNhbiBjaGFuZ2UgdGhlIHNldHRpbmcgb2YgdGhhdCBmZWF0dXJlIGZsYWcuICA8L3A+Ci0gKgotICogPHA+SWYgdGhlIG5hbWVzcGFjZS1wcmVmaXhlcyBmZWF0dXJlIChzZWUgYWJvdmUpIGlzCi0gKiA8dmFyPmZhbHNlPC92YXI+LCBhY2Nlc3MgYnkgcXVhbGlmaWVkIG5hbWUgbWF5IG5vdCBiZSBhdmFpbGFibGU7IGlmCi0gKiB0aGUgPGNvZGU+aHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL25hbWVzcGFjZXM8L2NvZGU+IGZlYXR1cmUgaXMKLSAqIDx2YXI+ZmFsc2U8L3Zhcj4sIGFjY2VzcyBieSBOYW1lc3BhY2UtcXVhbGlmaWVkIG5hbWVzIG1heSBub3QgYmUKLSAqIGF2YWlsYWJsZS48L3A+Ci0gKgotICogPHA+VGhpcyBpbnRlcmZhY2UgcmVwbGFjZXMgdGhlIG5vdy1kZXByZWNhdGVkIFNBWDEge0BsaW5rCi0gKiBvcmcueG1sLnNheC5BdHRyaWJ1dGVMaXN0IEF0dHJpYnV0ZUxpc3R9IGludGVyZmFjZSwgd2hpY2ggZG9lcyBub3QKLSAqIGNvbnRhaW4gTmFtZXNwYWNlIHN1cHBvcnQuICBJbiBhZGRpdGlvbiB0byBOYW1lc3BhY2Ugc3VwcG9ydCwgaXQKLSAqIGFkZHMgdGhlIDx2YXI+Z2V0SW5kZXg8L3Zhcj4gbWV0aG9kcyAoYmVsb3cpLjwvcD4KLSAqCi0gKiA8cD5UaGUgb3JkZXIgb2YgYXR0cmlidXRlcyBpbiB0aGUgbGlzdCBpcyB1bnNwZWNpZmllZCwgYW5kIHdpbGwKLSAqIHZhcnkgZnJvbSBpbXBsZW1lbnRhdGlvbiB0byBpbXBsZW1lbnRhdGlvbi48L3A+Ci0gKgotICogQHNpbmNlIFNBWCAyLjAKLSAqIEBhdXRob3IgRGF2aWQgTWVnZ2luc29uCi0gKiBAc2VlIG9yZy54bWwuc2F4LmhlbHBlcnMuQXR0cmlidXRlc0ltcGwKLSAqIEBzZWUgb3JnLnhtbC5zYXguZXh0LkRlY2xIYW5kbGVyI2F0dHJpYnV0ZURlY2wKLSAqLwotcHVibGljIGludGVyZmFjZSBBdHRyaWJ1dGVzCi17Ci0KLQotICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0gICAgLy8gSW5kZXhlZCBhY2Nlc3MuCi0gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSBudW1iZXIgb2YgYXR0cmlidXRlcyBpbiB0aGUgbGlzdC4KLSAgICAgKgotICAgICAqIDxwPk9uY2UgeW91IGtub3cgdGhlIG51bWJlciBvZiBhdHRyaWJ1dGVzLCB5b3UgY2FuIGl0ZXJhdGUKLSAgICAgKiB0aHJvdWdoIHRoZSBsaXN0LjwvcD4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIG51bWJlciBvZiBhdHRyaWJ1dGVzIGluIHRoZSBsaXN0LgotICAgICAqIEBzZWUgI2dldFVSSShpbnQpCi0gICAgICogQHNlZSAjZ2V0TG9jYWxOYW1lKGludCkKLSAgICAgKiBAc2VlICNnZXRRTmFtZShpbnQpCi0gICAgICogQHNlZSAjZ2V0VHlwZShpbnQpCi0gICAgICogQHNlZSAjZ2V0VmFsdWUoaW50KQotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCBpbnQgZ2V0TGVuZ3RoICgpOwotCi0KLSAgICAvKioKLSAgICAgKiBMb29rIHVwIGFuIGF0dHJpYnV0ZSdzIE5hbWVzcGFjZSBVUkkgYnkgaW5kZXguCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGF0dHJpYnV0ZSBpbmRleCAoemVyby1iYXNlZCkuCi0gICAgICogQHJldHVybiBUaGUgTmFtZXNwYWNlIFVSSSwgb3IgdGhlIGVtcHR5IHN0cmluZyBpZiBub25lCi0gICAgICogICAgICAgICBpcyBhdmFpbGFibGUsIG9yIG51bGwgaWYgdGhlIGluZGV4IGlzIG91dCBvZgotICAgICAqICAgICAgICAgcmFuZ2UuCi0gICAgICogQHNlZSAjZ2V0TGVuZ3RoCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IFN0cmluZyBnZXRVUkkgKGludCBpbmRleCk7Ci0KLQotICAgIC8qKgotICAgICAqIExvb2sgdXAgYW4gYXR0cmlidXRlJ3MgbG9jYWwgbmFtZSBieSBpbmRleC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBpbmRleCBUaGUgYXR0cmlidXRlIGluZGV4ICh6ZXJvLWJhc2VkKS4KLSAgICAgKiBAcmV0dXJuIFRoZSBsb2NhbCBuYW1lLCBvciB0aGUgZW1wdHkgc3RyaW5nIGlmIE5hbWVzcGFjZQotICAgICAqICAgICAgICAgcHJvY2Vzc2luZyBpcyBub3QgYmVpbmcgcGVyZm9ybWVkLCBvciBudWxsCi0gICAgICogICAgICAgICBpZiB0aGUgaW5kZXggaXMgb3V0IG9mIHJhbmdlLgotICAgICAqIEBzZWUgI2dldExlbmd0aAotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCBTdHJpbmcgZ2V0TG9jYWxOYW1lIChpbnQgaW5kZXgpOwotCi0KLSAgICAvKioKLSAgICAgKiBMb29rIHVwIGFuIGF0dHJpYnV0ZSdzIFhNTCBxdWFsaWZpZWQgKHByZWZpeGVkKSBuYW1lIGJ5IGluZGV4LgotICAgICAqCi0gICAgICogQHBhcmFtIGluZGV4IFRoZSBhdHRyaWJ1dGUgaW5kZXggKHplcm8tYmFzZWQpLgotICAgICAqIEByZXR1cm4gVGhlIFhNTCBxdWFsaWZpZWQgbmFtZSwgb3IgdGhlIGVtcHR5IHN0cmluZwotICAgICAqICAgICAgICAgaWYgbm9uZSBpcyBhdmFpbGFibGUsIG9yIG51bGwgaWYgdGhlIGluZGV4Ci0gICAgICogICAgICAgICBpcyBvdXQgb2YgcmFuZ2UuCi0gICAgICogQHNlZSAjZ2V0TGVuZ3RoCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IFN0cmluZyBnZXRRTmFtZSAoaW50IGluZGV4KTsKLQotCi0gICAgLyoqCi0gICAgICogTG9vayB1cCBhbiBhdHRyaWJ1dGUncyB0eXBlIGJ5IGluZGV4LgotICAgICAqCi0gICAgICogPHA+VGhlIGF0dHJpYnV0ZSB0eXBlIGlzIG9uZSBvZiB0aGUgc3RyaW5ncyAiQ0RBVEEiLCAiSUQiLAotICAgICAqICJJRFJFRiIsICJJRFJFRlMiLCAiTk1UT0tFTiIsICJOTVRPS0VOUyIsICJFTlRJVFkiLCAiRU5USVRJRVMiLAotICAgICAqIG9yICJOT1RBVElPTiIgKGFsd2F5cyBpbiB1cHBlciBjYXNlKS48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5JZiB0aGUgcGFyc2VyIGhhcyBub3QgcmVhZCBhIGRlY2xhcmF0aW9uIGZvciB0aGUgYXR0cmlidXRlLAotICAgICAqIG9yIGlmIHRoZSBwYXJzZXIgZG9lcyBub3QgcmVwb3J0IGF0dHJpYnV0ZSB0eXBlcywgdGhlbiBpdCBtdXN0Ci0gICAgICogcmV0dXJuIHRoZSB2YWx1ZSAiQ0RBVEEiIGFzIHN0YXRlZCBpbiB0aGUgWE1MIDEuMCBSZWNvbW1lbmRhdGlvbgotICAgICAqIChjbGF1c2UgMy4zLjMsICJBdHRyaWJ1dGUtVmFsdWUgTm9ybWFsaXphdGlvbiIpLjwvcD4KLSAgICAgKgotICAgICAqIDxwPkZvciBhbiBlbnVtZXJhdGVkIGF0dHJpYnV0ZSB0aGF0IGlzIG5vdCBhIG5vdGF0aW9uLCB0aGUKLSAgICAgKiBwYXJzZXIgd2lsbCByZXBvcnQgdGhlIHR5cGUgYXMgIk5NVE9LRU4iLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBpbmRleCBUaGUgYXR0cmlidXRlIGluZGV4ICh6ZXJvLWJhc2VkKS4KLSAgICAgKiBAcmV0dXJuIFRoZSBhdHRyaWJ1dGUncyB0eXBlIGFzIGEgc3RyaW5nLCBvciBudWxsIGlmIHRoZQotICAgICAqICAgICAgICAgaW5kZXggaXMgb3V0IG9mIHJhbmdlLgotICAgICAqIEBzZWUgI2dldExlbmd0aAotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCBTdHJpbmcgZ2V0VHlwZSAoaW50IGluZGV4KTsKLQotCi0gICAgLyoqCi0gICAgICogTG9vayB1cCBhbiBhdHRyaWJ1dGUncyB2YWx1ZSBieSBpbmRleC4KLSAgICAgKgotICAgICAqIDxwPklmIHRoZSBhdHRyaWJ1dGUgdmFsdWUgaXMgYSBsaXN0IG9mIHRva2VucyAoSURSRUZTLAotICAgICAqIEVOVElUSUVTLCBvciBOTVRPS0VOUyksIHRoZSB0b2tlbnMgd2lsbCBiZSBjb25jYXRlbmF0ZWQKLSAgICAgKiBpbnRvIGEgc2luZ2xlIHN0cmluZyB3aXRoIGVhY2ggdG9rZW4gc2VwYXJhdGVkIGJ5IGEKLSAgICAgKiBzaW5nbGUgc3BhY2UuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGluZGV4IFRoZSBhdHRyaWJ1dGUgaW5kZXggKHplcm8tYmFzZWQpLgotICAgICAqIEByZXR1cm4gVGhlIGF0dHJpYnV0ZSdzIHZhbHVlIGFzIGEgc3RyaW5nLCBvciBudWxsIGlmIHRoZQotICAgICAqICAgICAgICAgaW5kZXggaXMgb3V0IG9mIHJhbmdlLgotICAgICAqIEBzZWUgI2dldExlbmd0aAotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCBTdHJpbmcgZ2V0VmFsdWUgKGludCBpbmRleCk7Ci0KLQotCi0gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLSAgICAvLyBOYW1lLWJhc2VkIHF1ZXJ5LgotICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0KLQotICAgIC8qKgotICAgICAqIExvb2sgdXAgdGhlIGluZGV4IG9mIGFuIGF0dHJpYnV0ZSBieSBOYW1lc3BhY2UgbmFtZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSB1cmkgVGhlIE5hbWVzcGFjZSBVUkksIG9yIHRoZSBlbXB0eSBzdHJpbmcgaWYKLSAgICAgKiAgICAgICAgdGhlIG5hbWUgaGFzIG5vIE5hbWVzcGFjZSBVUkkuCi0gICAgICogQHBhcmFtIGxvY2FsTmFtZSBUaGUgYXR0cmlidXRlJ3MgbG9jYWwgbmFtZS4KLSAgICAgKiBAcmV0dXJuIFRoZSBpbmRleCBvZiB0aGUgYXR0cmlidXRlLCBvciAtMSBpZiBpdCBkb2VzIG5vdAotICAgICAqICAgICAgICAgYXBwZWFyIGluIHRoZSBsaXN0LgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0SW5kZXggKFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUpOwotCi0KLSAgICAvKioKLSAgICAgKiBMb29rIHVwIHRoZSBpbmRleCBvZiBhbiBhdHRyaWJ1dGUgYnkgWE1MIHF1YWxpZmllZCAocHJlZml4ZWQpIG5hbWUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcU5hbWUgVGhlIHF1YWxpZmllZCAocHJlZml4ZWQpIG5hbWUuCi0gICAgICogQHJldHVybiBUaGUgaW5kZXggb2YgdGhlIGF0dHJpYnV0ZSwgb3IgLTEgaWYgaXQgZG9lcyBub3QKLSAgICAgKiAgICAgICAgIGFwcGVhciBpbiB0aGUgbGlzdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldEluZGV4IChTdHJpbmcgcU5hbWUpOwotCi0KLSAgICAvKioKLSAgICAgKiBMb29rIHVwIGFuIGF0dHJpYnV0ZSdzIHR5cGUgYnkgTmFtZXNwYWNlIG5hbWUuCi0gICAgICoKLSAgICAgKiA8cD5TZWUge0BsaW5rICNnZXRUeXBlKGludCkgZ2V0VHlwZShpbnQpfSBmb3IgYSBkZXNjcmlwdGlvbgotICAgICAqIG9mIHRoZSBwb3NzaWJsZSB0eXBlcy48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gdXJpIFRoZSBOYW1lc3BhY2UgVVJJLCBvciB0aGUgZW1wdHkgU3RyaW5nIGlmIHRoZQotICAgICAqICAgICAgICBuYW1lIGhhcyBubyBOYW1lc3BhY2UgVVJJLgotICAgICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGxvY2FsIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgKiBAcmV0dXJuIFRoZSBhdHRyaWJ1dGUgdHlwZSBhcyBhIHN0cmluZywgb3IgbnVsbCBpZiB0aGUKLSAgICAgKiAgICAgICAgIGF0dHJpYnV0ZSBpcyBub3QgaW4gdGhlIGxpc3Qgb3IgaWYgTmFtZXNwYWNlCi0gICAgICogICAgICAgICBwcm9jZXNzaW5nIGlzIG5vdCBiZWluZyBwZXJmb3JtZWQuCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IFN0cmluZyBnZXRUeXBlIChTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxOYW1lKTsKLQotCi0gICAgLyoqCi0gICAgICogTG9vayB1cCBhbiBhdHRyaWJ1dGUncyB0eXBlIGJ5IFhNTCBxdWFsaWZpZWQgKHByZWZpeGVkKSBuYW1lLgotICAgICAqCi0gICAgICogPHA+U2VlIHtAbGluayAjZ2V0VHlwZShpbnQpIGdldFR5cGUoaW50KX0gZm9yIGEgZGVzY3JpcHRpb24KLSAgICAgKiBvZiB0aGUgcG9zc2libGUgdHlwZXMuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIHFOYW1lIFRoZSBYTUwgcXVhbGlmaWVkIG5hbWUuCi0gICAgICogQHJldHVybiBUaGUgYXR0cmlidXRlIHR5cGUgYXMgYSBzdHJpbmcsIG9yIG51bGwgaWYgdGhlCi0gICAgICogICAgICAgICBhdHRyaWJ1dGUgaXMgbm90IGluIHRoZSBsaXN0IG9yIGlmIHF1YWxpZmllZCBuYW1lcwotICAgICAqICAgICAgICAgYXJlIG5vdCBhdmFpbGFibGUuCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IFN0cmluZyBnZXRUeXBlIChTdHJpbmcgcU5hbWUpOwotCi0KLSAgICAvKioKLSAgICAgKiBMb29rIHVwIGFuIGF0dHJpYnV0ZSdzIHZhbHVlIGJ5IE5hbWVzcGFjZSBuYW1lLgotICAgICAqCi0gICAgICogPHA+U2VlIHtAbGluayAjZ2V0VmFsdWUoaW50KSBnZXRWYWx1ZShpbnQpfSBmb3IgYSBkZXNjcmlwdGlvbgotICAgICAqIG9mIHRoZSBwb3NzaWJsZSB2YWx1ZXMuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIHVyaSBUaGUgTmFtZXNwYWNlIFVSSSwgb3IgdGhlIGVtcHR5IFN0cmluZyBpZiB0aGUKLSAgICAgKiAgICAgICAgbmFtZSBoYXMgbm8gTmFtZXNwYWNlIFVSSS4KLSAgICAgKiBAcGFyYW0gbG9jYWxOYW1lIFRoZSBsb2NhbCBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUuCi0gICAgICogQHJldHVybiBUaGUgYXR0cmlidXRlIHZhbHVlIGFzIGEgc3RyaW5nLCBvciBudWxsIGlmIHRoZQotICAgICAqICAgICAgICAgYXR0cmlidXRlIGlzIG5vdCBpbiB0aGUgbGlzdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nIGdldFZhbHVlIChTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxOYW1lKTsKLQotCi0gICAgLyoqCi0gICAgICogTG9vayB1cCBhbiBhdHRyaWJ1dGUncyB2YWx1ZSBieSBYTUwgcXVhbGlmaWVkIChwcmVmaXhlZCkgbmFtZS4KLSAgICAgKgotICAgICAqIDxwPlNlZSB7QGxpbmsgI2dldFZhbHVlKGludCkgZ2V0VmFsdWUoaW50KX0gZm9yIGEgZGVzY3JpcHRpb24KLSAgICAgKiBvZiB0aGUgcG9zc2libGUgdmFsdWVzLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBxTmFtZSBUaGUgWE1MIHF1YWxpZmllZCBuYW1lLgotICAgICAqIEByZXR1cm4gVGhlIGF0dHJpYnV0ZSB2YWx1ZSBhcyBhIHN0cmluZywgb3IgbnVsbCBpZiB0aGUKLSAgICAgKiAgICAgICAgIGF0dHJpYnV0ZSBpcyBub3QgaW4gdGhlIGxpc3Qgb3IgaWYgcXVhbGlmaWVkIG5hbWVzCi0gICAgICogICAgICAgICBhcmUgbm90IGF2YWlsYWJsZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nIGdldFZhbHVlIChTdHJpbmcgcU5hbWUpOwotCi19Ci0KLS8vIGVuZCBvZiBBdHRyaWJ1dGVzLmphdmEKZGlmZiAtLWdpdCBhL3NyYy9vcmcveG1sL3NheC9DT1BZSU5HIGIvc3JjL29yZy94bWwvc2F4L0NPUFlJTkcKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGRkMGI5ODEuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy94bWwvc2F4L0NPUFlJTkcKKysrIC9kZXYvbnVsbApAQCAtMSwxMiArMCwwIEBACi1TQVggSVMgRlJFRQotLS0tLS0tLS0tLS0KLQotSSBoZXJlYnkgYWJhbmRvbiBhbnkgcHJvcGVydHkgcmlnaHRzIHRvIFNBWCAyLjAgKHRoZSBTaW1wbGUgQVBJIGZvcgotWE1MKSwgYW5kIHJlbGVhc2UgYWxsIG9mIHRoZSBTQVggMi4wIHNvdXJjZSBjb2RlLCBjb21waWxlZCBjb2RlLCBhbmQKLWRvY3VtZW50YXRpb24gY29udGFpbmVkIGluIHRoaXMgZGlzdHJpYnV0aW9uIGludG8gdGhlIFB1YmxpYyBEb21haW4uCi1TQVggY29tZXMgd2l0aCBOTyBXQVJSQU5UWSBvciBndWFyYW50ZWUgb2YgZml0bmVzcyBmb3IgYW55IHB1cnBvc2UuCi0KLQotRGF2aWQgTWVnZ2luc29uCi1kYXZpZEBtZWdnaW5zb24uY29tCi0yMDAwLTAxLTE0CmRpZmYgLS1naXQgYS9zcmMvb3JnL3htbC9zYXgvQ09QWUlORy50eHQgYi9zcmMvb3JnL3htbC9zYXgvQ09QWUlORy50eHQKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDI3NTE4YjQuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy94bWwvc2F4L0NPUFlJTkcudHh0CisrKyAvZGV2L251bGwKQEAgLTEsMzkgKzAsMCBAQAotCQkJIFNBWCBDT1BZUklHSFQgU1RBVFVTCi0KLVZlcnNpb24gMS4wIG9mIHRoZSBTaW1wbGUgQVBJIGZvciBYTUwgKFNBWCksIGNyZWF0ZWQgY29sbGVjdGl2ZWx5IGJ5Ci10aGUgbWVtYmVyc2hpcCBvZiB0aGUgWE1MLURFViBtYWlsaW5nIGxpc3QsIGlzIGhlcmVieSByZWxlYXNlZCBpbnRvCi10aGUgcHVibGljIGRvbWFpbi4KLQotTm8gb25lIG93bnMgU0FYOiB5b3UgbWF5IHVzZSBpdCBmcmVlbHkgaW4gYm90aCBjb21tZXJjaWFsIGFuZAotbm9uLWNvbW1lcmNpYWwgYXBwbGljYXRpb25zLCBidW5kbGUgaXQgd2l0aCB5b3VyIHNvZnR3YXJlCi1kaXN0cmlidXRpb24sIGluY2x1ZGUgaXQgb24gYSBDRC1ST00sIGxpc3QgdGhlIHNvdXJjZSBjb2RlIGluIGEgYm9vaywKLW1pcnJvciB0aGUgZG9jdW1lbnRhdGlvbiBhdCB5b3VyIG93biB3ZWIgc2l0ZSwgb3IgdXNlIGl0IGluIGFueSBvdGhlcgotd2F5IHlvdSBzZWUgZml0LgotCi0KLQkJCSAgICAgTk8gV0FSUkFOVFkKLQotQmVjYXVzZSBTQVggaXMgcmVsZWFzZWQgdG8gdGhlIHB1YmxpYyBkb21haW4sIHRoZXJlIGlzIG5vIHdhcnJhbnR5IGZvcgotdGhlIGRlc2lnbiBvciBmb3IgdGhlIHNvZnR3YXJlIGltcGxlbWVudGF0aW9uLCB0byB0aGUgZXh0ZW50IHBlcm1pdHRlZAotYnkgYXBwbGljYWJsZSBsYXcuICBFeGNlcHQgd2hlbiBvdGhlcndpc2Ugc3RhdGVkIGluIHdyaXRpbmcgdGhlCi1jb3B5cmlnaHQgaG9sZGVycyBhbmQvb3Igb3RoZXIgcGFydGllcyBwcm92aWRlIFNBWCAiYXMgaXMiIHdpdGhvdXQKLXdhcnJhbnR5IG9mIGFueSBraW5kLCBlaXRoZXIgZXhwcmVzc2VkIG9yIGltcGxpZWQsIGluY2x1ZGluZywgYnV0IG5vdAotbGltaXRlZCB0bywgdGhlIGltcGxpZWQgd2FycmFudGllcyBvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yCi1hIHBhcnRpY3VsYXIgcHVycG9zZS4gIFRoZSBlbnRpcmUgcmlzayBhcyB0byB0aGUgcXVhbGl0eSBhbmQKLXBlcmZvcm1hbmNlIG9mIFNBWCBpcyB3aXRoIHlvdS4gIFNob3VsZCBTQVggcHJvdmUgZGVmZWN0aXZlLCB5b3UKLWFzc3VtZSB0aGUgY29zdCBvZiBhbGwgbmVjZXNzYXJ5IHNlcnZpY2luZywgcmVwYWlyIG9yIGNvcnJlY3Rpb24uCi0KLUluIG5vIGV2ZW50IHVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZwotd2lsbCBhbnkgY29weXJpZ2h0IGhvbGRlciwgb3IgYW55IG90aGVyIHBhcnR5IHdobyBtYXkgbW9kaWZ5IGFuZC9vcgotcmVkaXN0cmlidXRlIFNBWCwgYmUgbGlhYmxlIHRvIHlvdSBmb3IgZGFtYWdlcywgaW5jbHVkaW5nIGFueSBnZW5lcmFsLAotc3BlY2lhbCwgaW5jaWRlbnRhbCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMgYXJpc2luZyBvdXQgb2YgdGhlIHVzZSBvcgotaW5hYmlsaXR5IHRvIHVzZSBTQVggKGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gbG9zcyBvZiBkYXRhIG9yCi1kYXRhIGJlaW5nIHJlbmRlcmVkIGluYWNjdXJhdGUgb3IgbG9zc2VzIHN1c3RhaW5lZCBieSB5b3Ugb3IgdGhpcmQKLXBhcnRpZXMgb3IgYSBmYWlsdXJlIG9mIHRoZSBTQVggdG8gb3BlcmF0ZSB3aXRoIGFueSBvdGhlciBwcm9ncmFtcyksCi1ldmVuIGlmIHN1Y2ggaG9sZGVyIG9yIG90aGVyIHBhcnR5IGhhcyBiZWVuIGFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5Ci1vZiBzdWNoIGRhbWFnZXMuCi0KLQotRGF2aWQgTWVnZ2luc29uIDxzYXhAbWVnZ2luc29uLmNvbT4KLTE5OTgtMDUtMTEKLQpkaWZmIC0tZ2l0IGEvc3JjL29yZy94bWwvc2F4L0NvbnRlbnRIYW5kbGVyLmphdmEgYi9zcmMvb3JnL3htbC9zYXgvQ29udGVudEhhbmRsZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOTlkOGY1YS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3htbC9zYXgvQ29udGVudEhhbmRsZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQ0MyArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDAwLCAyMDA1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vLyBDb250ZW50SGFuZGxlci5qYXZhIC0gaGFuZGxlIG1haW4gZG9jdW1lbnQgY29udGVudC4KLS8vIGh0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmcKLS8vIFdyaXR0ZW4gYnkgRGF2aWQgTWVnZ2luc29uCi0vLyBOTyBXQVJSQU5UWSEgIFRoaXMgY2xhc3MgaXMgaW4gdGhlIHB1YmxpYyBkb21haW4uCi0vLyAkSWQ6IENvbnRlbnRIYW5kbGVyLmphdmEsdiAxLjIgMjAwNC8xMS8wMyAyMjo0NDo1MSBqc3V0dG9yIEV4cCAkCi0KLXBhY2thZ2Ugb3JnLnhtbC5zYXg7Ci0KLQotLyoqCi0gKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiB0aGUgbG9naWNhbCBjb250ZW50IG9mIGEgZG9jdW1lbnQuCi0gKgotICogPGJsb2NrcXVvdGU+Ci0gKiA8ZW0+VGhpcyBtb2R1bGUsIGJvdGggc291cmNlIGNvZGUgYW5kIGRvY3VtZW50YXRpb24sIGlzIGluIHRoZQotICogUHVibGljIERvbWFpbiwgYW5kIGNvbWVzIHdpdGggPHN0cm9uZz5OTyBXQVJSQU5UWTwvc3Ryb25nPi48L2VtPgotICogU2VlIDxhIGhyZWY9J2h0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmcnPmh0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmc8L2E+Ci0gKiBmb3IgZnVydGhlciBpbmZvcm1hdGlvbi4KLSAqIDwvYmxvY2txdW90ZT4KLSAqCi0gKiA8cD5UaGlzIGlzIHRoZSBtYWluIGludGVyZmFjZSB0aGF0IG1vc3QgU0FYIGFwcGxpY2F0aW9ucwotICogaW1wbGVtZW50OiBpZiB0aGUgYXBwbGljYXRpb24gbmVlZHMgdG8gYmUgaW5mb3JtZWQgb2YgYmFzaWMgcGFyc2luZwotICogZXZlbnRzLCBpdCBpbXBsZW1lbnRzIHRoaXMgaW50ZXJmYWNlIGFuZCByZWdpc3RlcnMgYW4gaW5zdGFuY2Ugd2l0aAotICogdGhlIFNBWCBwYXJzZXIgdXNpbmcgdGhlIHtAbGluayBvcmcueG1sLnNheC5YTUxSZWFkZXIjc2V0Q29udGVudEhhbmRsZXIKLSAqIHNldENvbnRlbnRIYW5kbGVyfSBtZXRob2QuICBUaGUgcGFyc2VyIHVzZXMgdGhlIGluc3RhbmNlIHRvIHJlcG9ydAotICogYmFzaWMgZG9jdW1lbnQtcmVsYXRlZCBldmVudHMgbGlrZSB0aGUgc3RhcnQgYW5kIGVuZCBvZiBlbGVtZW50cwotICogYW5kIGNoYXJhY3RlciBkYXRhLjwvcD4KLSAqCi0gKiA8cD5UaGUgb3JkZXIgb2YgZXZlbnRzIGluIHRoaXMgaW50ZXJmYWNlIGlzIHZlcnkgaW1wb3J0YW50LCBhbmQKLSAqIG1pcnJvcnMgdGhlIG9yZGVyIG9mIGluZm9ybWF0aW9uIGluIHRoZSBkb2N1bWVudCBpdHNlbGYuICBGb3IKLSAqIGV4YW1wbGUsIGFsbCBvZiBhbiBlbGVtZW50J3MgY29udGVudCAoY2hhcmFjdGVyIGRhdGEsIHByb2Nlc3NpbmcKLSAqIGluc3RydWN0aW9ucywgYW5kL29yIHN1YmVsZW1lbnRzKSB3aWxsIGFwcGVhciwgaW4gb3JkZXIsIGJldHdlZW4KLSAqIHRoZSBzdGFydEVsZW1lbnQgZXZlbnQgYW5kIHRoZSBjb3JyZXNwb25kaW5nIGVuZEVsZW1lbnQgZXZlbnQuPC9wPgotICoKLSAqIDxwPlRoaXMgaW50ZXJmYWNlIGlzIHNpbWlsYXIgdG8gdGhlIG5vdy1kZXByZWNhdGVkIFNBWCAxLjAKLSAqIERvY3VtZW50SGFuZGxlciBpbnRlcmZhY2UsIGJ1dCBpdCBhZGRzIHN1cHBvcnQgZm9yIE5hbWVzcGFjZXMKLSAqIGFuZCBmb3IgcmVwb3J0aW5nIHNraXBwZWQgZW50aXRpZXMgKGluIG5vbi12YWxpZGF0aW5nIFhNTAotICogcHJvY2Vzc29ycykuPC9wPgotICoKLSAqIDxwPkltcGxlbWVudG9ycyBzaG91bGQgbm90ZSB0aGF0IHRoZXJlIGlzIGFsc28gYQotICogPGNvZGU+Q29udGVudEhhbmRsZXI8L2NvZGU+IGNsYXNzIGluIHRoZSA8Y29kZT5qYXZhLm5ldDwvY29kZT4KLSAqIHBhY2thZ2U7IHRoYXQgbWVhbnMgdGhhdCBpdCdzIHByb2JhYmx5IGEgYmFkIGlkZWEgdG8gZG88L3A+Ci0gKgotICogPHByZT5pbXBvcnQgamF2YS5uZXQuKjsKLSAqIGltcG9ydCBvcmcueG1sLnNheC4qOwotICogPC9wcmU+Ci0gKgotICogPHA+SW4gZmFjdCwgImltcG9ydCAuLi4qIiBpcyB1c3VhbGx5IGEgc2lnbiBvZiBzbG9wcHkgcHJvZ3JhbW1pbmcKLSAqIGFueXdheSwgc28gdGhlIHVzZXIgc2hvdWxkIGNvbnNpZGVyIHRoaXMgYSBmZWF0dXJlIHJhdGhlciB0aGFuIGEKLSAqIGJ1Zy48L3A+Ci0gKgotICogQHNpbmNlIFNBWCAyLjAKLSAqIEBhdXRob3IgRGF2aWQgTWVnZ2luc29uCi0gKiBAc2VlIG9yZy54bWwuc2F4LlhNTFJlYWRlcgotICogQHNlZSBvcmcueG1sLnNheC5EVERIYW5kbGVyCi0gKiBAc2VlIG9yZy54bWwuc2F4LkVycm9ySGFuZGxlcgotICovCi1wdWJsaWMgaW50ZXJmYWNlIENvbnRlbnRIYW5kbGVyCi17Ci0KLSAgICAvKioKLSAgICAgKiBSZWNlaXZlIGFuIG9iamVjdCBmb3IgbG9jYXRpbmcgdGhlIG9yaWdpbiBvZiBTQVggZG9jdW1lbnQgZXZlbnRzLgotICAgICAqCi0gICAgICogPHA+U0FYIHBhcnNlcnMgYXJlIHN0cm9uZ2x5IGVuY291cmFnZWQgKHRob3VnaCBub3QgYWJzb2x1dGVseQotICAgICAqIHJlcXVpcmVkKSB0byBzdXBwbHkgYSBsb2NhdG9yOiBpZiBpdCBkb2VzIHNvLCBpdCBtdXN0IHN1cHBseQotICAgICAqIHRoZSBsb2NhdG9yIHRvIHRoZSBhcHBsaWNhdGlvbiBieSBpbnZva2luZyB0aGlzIG1ldGhvZCBiZWZvcmUKLSAgICAgKiBpbnZva2luZyBhbnkgb2YgdGhlIG90aGVyIG1ldGhvZHMgaW4gdGhlIENvbnRlbnRIYW5kbGVyCi0gICAgICogaW50ZXJmYWNlLjwvcD4KLSAgICAgKgotICAgICAqIDxwPlRoZSBsb2NhdG9yIGFsbG93cyB0aGUgYXBwbGljYXRpb24gdG8gZGV0ZXJtaW5lIHRoZSBlbmQKLSAgICAgKiBwb3NpdGlvbiBvZiBhbnkgZG9jdW1lbnQtcmVsYXRlZCBldmVudCwgZXZlbiBpZiB0aGUgcGFyc2VyIGlzCi0gICAgICogbm90IHJlcG9ydGluZyBhbiBlcnJvci4gIFR5cGljYWxseSwgdGhlIGFwcGxpY2F0aW9uIHdpbGwKLSAgICAgKiB1c2UgdGhpcyBpbmZvcm1hdGlvbiBmb3IgcmVwb3J0aW5nIGl0cyBvd24gZXJyb3JzIChzdWNoIGFzCi0gICAgICogY2hhcmFjdGVyIGNvbnRlbnQgdGhhdCBkb2VzIG5vdCBtYXRjaCBhbiBhcHBsaWNhdGlvbidzCi0gICAgICogYnVzaW5lc3MgcnVsZXMpLiAgVGhlIGluZm9ybWF0aW9uIHJldHVybmVkIGJ5IHRoZSBsb2NhdG9yCi0gICAgICogaXMgcHJvYmFibHkgbm90IHN1ZmZpY2llbnQgZm9yIHVzZSB3aXRoIGEgc2VhcmNoIGVuZ2luZS48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5Ob3RlIHRoYXQgdGhlIGxvY2F0b3Igd2lsbCByZXR1cm4gY29ycmVjdCBpbmZvcm1hdGlvbiBvbmx5Ci0gICAgICogZHVyaW5nIHRoZSBpbnZvY2F0aW9uIFNBWCBldmVudCBjYWxsYmFja3MgYWZ0ZXIKLSAgICAgKiB7QGxpbmsgI3N0YXJ0RG9jdW1lbnQgc3RhcnREb2N1bWVudH0gcmV0dXJucyBhbmQgYmVmb3JlCi0gICAgICoge0BsaW5rICNlbmREb2N1bWVudCBlbmREb2N1bWVudH0gaXMgY2FsbGVkLiAgVGhlCi0gICAgICogYXBwbGljYXRpb24gc2hvdWxkIG5vdCBhdHRlbXB0IHRvIHVzZSBpdCBhdCBhbnkgb3RoZXIgdGltZS48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gbG9jYXRvciBhbiBvYmplY3QgdGhhdCBjYW4gcmV0dXJuIHRoZSBsb2NhdGlvbiBvZgotICAgICAqICAgICAgICAgICAgICAgIGFueSBTQVggZG9jdW1lbnQgZXZlbnQKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkxvY2F0b3IKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXREb2N1bWVudExvY2F0b3IgKExvY2F0b3IgbG9jYXRvcik7Ci0KLQotICAgIC8qKgotICAgICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIHRoZSBiZWdpbm5pbmcgb2YgYSBkb2N1bWVudC4KLSAgICAgKgotICAgICAqIDxwPlRoZSBTQVggcGFyc2VyIHdpbGwgaW52b2tlIHRoaXMgbWV0aG9kIG9ubHkgb25jZSwgYmVmb3JlIGFueQotICAgICAqIG90aGVyIGV2ZW50IGNhbGxiYWNrcyAoZXhjZXB0IGZvciB7QGxpbmsgI3NldERvY3VtZW50TG9jYXRvcgotICAgICAqIHNldERvY3VtZW50TG9jYXRvcn0pLjwvcD4KLSAgICAgKgotICAgICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIGFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24KLSAgICAgKiBAc2VlICNlbmREb2N1bWVudAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RG9jdW1lbnQgKCkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbjsKLQotCi0gICAgLyoqCi0gICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIGVuZCBvZiBhIGRvY3VtZW50LgotICAgICAqCi0gICAgICogPHA+PHN0cm9uZz5UaGVyZSBpcyBhbiBhcHBhcmVudCBjb250cmFkaWN0aW9uIGJldHdlZW4gdGhlCi0gICAgICogZG9jdW1lbnRhdGlvbiBmb3IgdGhpcyBtZXRob2QgYW5kIHRoZSBkb2N1bWVudGF0aW9uIGZvciB7QGxpbmsKLSAgICAgKiBvcmcueG1sLnNheC5FcnJvckhhbmRsZXIjZmF0YWxFcnJvcn0uICBVbnRpbCB0aGlzIGFtYmlndWl0eSBpcwotICAgICAqIHJlc29sdmVkIGluIGEgZnV0dXJlIG1ham9yIHJlbGVhc2UsIGNsaWVudHMgc2hvdWxkIG1ha2Ugbm8KLSAgICAgKiBhc3N1bXB0aW9ucyBhYm91dCB3aGV0aGVyIGVuZERvY3VtZW50KCkgd2lsbCBvciB3aWxsIG5vdCBiZQotICAgICAqIGludm9rZWQgd2hlbiB0aGUgcGFyc2VyIGhhcyByZXBvcnRlZCBhIGZhdGFsRXJyb3IoKSBvciB0aHJvd24KLSAgICAgKiBhbiBleGNlcHRpb24uPC9zdHJvbmc+PC9wPgotICAgICAqCi0gICAgICogPHA+VGhlIFNBWCBwYXJzZXIgd2lsbCBpbnZva2UgdGhpcyBtZXRob2Qgb25seSBvbmNlLCBhbmQgaXQgd2lsbAotICAgICAqIGJlIHRoZSBsYXN0IG1ldGhvZCBpbnZva2VkIGR1cmluZyB0aGUgcGFyc2UuICBUaGUgcGFyc2VyIHNoYWxsCi0gICAgICogbm90IGludm9rZSB0aGlzIG1ldGhvZCB1bnRpbCBpdCBoYXMgZWl0aGVyIGFiYW5kb25lZCBwYXJzaW5nCi0gICAgICogKGJlY2F1c2Ugb2YgYW4gdW5yZWNvdmVyYWJsZSBlcnJvcikgb3IgcmVhY2hlZCB0aGUgZW5kIG9mCi0gICAgICogaW5wdXQuPC9wPgotICAgICAqCi0gICAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gYW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbgotICAgICAqIEBzZWUgI3N0YXJ0RG9jdW1lbnQKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbmREb2N1bWVudCgpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb247Ci0KLQotICAgIC8qKgotICAgICAqIEJlZ2luIHRoZSBzY29wZSBvZiBhIHByZWZpeC1VUkkgTmFtZXNwYWNlIG1hcHBpbmcuCi0gICAgICoKLSAgICAgKiA8cD5UaGUgaW5mb3JtYXRpb24gZnJvbSB0aGlzIGV2ZW50IGlzIG5vdCBuZWNlc3NhcnkgZm9yCi0gICAgICogbm9ybWFsIE5hbWVzcGFjZSBwcm9jZXNzaW5nOiB0aGUgU0FYIFhNTCByZWFkZXIgd2lsbAotICAgICAqIGF1dG9tYXRpY2FsbHkgcmVwbGFjZSBwcmVmaXhlcyBmb3IgZWxlbWVudCBhbmQgYXR0cmlidXRlCi0gICAgICogbmFtZXMgd2hlbiB0aGUgPGNvZGU+aHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL25hbWVzcGFjZXM8L2NvZGU+Ci0gICAgICogZmVhdHVyZSBpcyA8dmFyPnRydWU8L3Zhcj4gKHRoZSBkZWZhdWx0KS48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5UaGVyZSBhcmUgY2FzZXMsIGhvd2V2ZXIsIHdoZW4gYXBwbGljYXRpb25zIG5lZWQgdG8KLSAgICAgKiB1c2UgcHJlZml4ZXMgaW4gY2hhcmFjdGVyIGRhdGEgb3IgaW4gYXR0cmlidXRlIHZhbHVlcywKLSAgICAgKiB3aGVyZSB0aGV5IGNhbm5vdCBzYWZlbHkgYmUgZXhwYW5kZWQgYXV0b21hdGljYWxseTsgdGhlCi0gICAgICogc3RhcnQvZW5kUHJlZml4TWFwcGluZyBldmVudCBzdXBwbGllcyB0aGUgaW5mb3JtYXRpb24KLSAgICAgKiB0byB0aGUgYXBwbGljYXRpb24gdG8gZXhwYW5kIHByZWZpeGVzIGluIHRob3NlIGNvbnRleHRzCi0gICAgICogaXRzZWxmLCBpZiBuZWNlc3NhcnkuPC9wPgotICAgICAqCi0gICAgICogPHA+Tm90ZSB0aGF0IHN0YXJ0L2VuZFByZWZpeE1hcHBpbmcgZXZlbnRzIGFyZSBub3QKLSAgICAgKiBndWFyYW50ZWVkIHRvIGJlIHByb3Blcmx5IG5lc3RlZCByZWxhdGl2ZSB0byBlYWNoIG90aGVyOgotICAgICAqIGFsbCBzdGFydFByZWZpeE1hcHBpbmcgZXZlbnRzIHdpbGwgb2NjdXIgaW1tZWRpYXRlbHkgYmVmb3JlIHRoZQotICAgICAqIGNvcnJlc3BvbmRpbmcge0BsaW5rICNzdGFydEVsZW1lbnQgc3RhcnRFbGVtZW50fSBldmVudCwKLSAgICAgKiBhbmQgYWxsIHtAbGluayAjZW5kUHJlZml4TWFwcGluZyBlbmRQcmVmaXhNYXBwaW5nfQotICAgICAqIGV2ZW50cyB3aWxsIG9jY3VyIGltbWVkaWF0ZWx5IGFmdGVyIHRoZSBjb3JyZXNwb25kaW5nCi0gICAgICoge0BsaW5rICNlbmRFbGVtZW50IGVuZEVsZW1lbnR9IGV2ZW50LAotICAgICAqIGJ1dCB0aGVpciBvcmRlciBpcyBub3Qgb3RoZXJ3aXNlCi0gICAgICogZ3VhcmFudGVlZC48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5UaGVyZSBzaG91bGQgbmV2ZXIgYmUgc3RhcnQvZW5kUHJlZml4TWFwcGluZyBldmVudHMgZm9yIHRoZQotICAgICAqICJ4bWwiIHByZWZpeCwgc2luY2UgaXQgaXMgcHJlZGVjbGFyZWQgYW5kIGltbXV0YWJsZS48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gcHJlZml4IHRoZSBOYW1lc3BhY2UgcHJlZml4IGJlaW5nIGRlY2xhcmVkLgotICAgICAqICBBbiBlbXB0eSBzdHJpbmcgaXMgdXNlZCBmb3IgdGhlIGRlZmF1bHQgZWxlbWVudCBuYW1lc3BhY2UsCi0gICAgICogIHdoaWNoIGhhcyBubyBwcmVmaXguCi0gICAgICogQHBhcmFtIHVyaSB0aGUgTmFtZXNwYWNlIFVSSSB0aGUgcHJlZml4IGlzIG1hcHBlZCB0bwotICAgICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIHRoZSBjbGllbnQgbWF5IHRocm93Ci0gICAgICogICAgICAgICAgICBhbiBleGNlcHRpb24gZHVyaW5nIHByb2Nlc3NpbmcKLSAgICAgKiBAc2VlICNlbmRQcmVmaXhNYXBwaW5nCi0gICAgICogQHNlZSAjc3RhcnRFbGVtZW50Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnRQcmVmaXhNYXBwaW5nIChTdHJpbmcgcHJlZml4LCBTdHJpbmcgdXJpKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uOwotCi0KLSAgICAvKioKLSAgICAgKiBFbmQgdGhlIHNjb3BlIG9mIGEgcHJlZml4LVVSSSBtYXBwaW5nLgotICAgICAqCi0gICAgICogPHA+U2VlIHtAbGluayAjc3RhcnRQcmVmaXhNYXBwaW5nIHN0YXJ0UHJlZml4TWFwcGluZ30gZm9yCi0gICAgICogZGV0YWlscy4gIFRoZXNlIGV2ZW50cyB3aWxsIGFsd2F5cyBvY2N1ciBpbW1lZGlhdGVseSBhZnRlciB0aGUKLSAgICAgKiBjb3JyZXNwb25kaW5nIHtAbGluayAjZW5kRWxlbWVudCBlbmRFbGVtZW50fSBldmVudCwgYnV0IHRoZSBvcmRlciBvZgotICAgICAqIHtAbGluayAjZW5kUHJlZml4TWFwcGluZyBlbmRQcmVmaXhNYXBwaW5nfSBldmVudHMgaXMgbm90IG90aGVyd2lzZQotICAgICAqIGd1YXJhbnRlZWQuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIHByZWZpeCB0aGUgcHJlZml4IHRoYXQgd2FzIGJlaW5nIG1hcHBlZC4KLSAgICAgKiAgVGhpcyBpcyB0aGUgZW1wdHkgc3RyaW5nIHdoZW4gYSBkZWZhdWx0IG1hcHBpbmcgc2NvcGUgZW5kcy4KLSAgICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiB0aGUgY2xpZW50IG1heSB0aHJvdwotICAgICAqICAgICAgICAgICAgYW4gZXhjZXB0aW9uIGR1cmluZyBwcm9jZXNzaW5nCi0gICAgICogQHNlZSAjc3RhcnRQcmVmaXhNYXBwaW5nCi0gICAgICogQHNlZSAjZW5kRWxlbWVudAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZFByZWZpeE1hcHBpbmcgKFN0cmluZyBwcmVmaXgpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb247Ci0KLQotICAgIC8qKgotICAgICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIHRoZSBiZWdpbm5pbmcgb2YgYW4gZWxlbWVudC4KLSAgICAgKgotICAgICAqIDxwPlRoZSBQYXJzZXIgd2lsbCBpbnZva2UgdGhpcyBtZXRob2QgYXQgdGhlIGJlZ2lubmluZyBvZiBldmVyeQotICAgICAqIGVsZW1lbnQgaW4gdGhlIFhNTCBkb2N1bWVudDsgdGhlcmUgd2lsbCBiZSBhIGNvcnJlc3BvbmRpbmcKLSAgICAgKiB7QGxpbmsgI2VuZEVsZW1lbnQgZW5kRWxlbWVudH0gZXZlbnQgZm9yIGV2ZXJ5IHN0YXJ0RWxlbWVudCBldmVudAotICAgICAqIChldmVuIHdoZW4gdGhlIGVsZW1lbnQgaXMgZW1wdHkpLiBBbGwgb2YgdGhlIGVsZW1lbnQncyBjb250ZW50IHdpbGwgYmUKLSAgICAgKiByZXBvcnRlZCwgaW4gb3JkZXIsIGJlZm9yZSB0aGUgY29ycmVzcG9uZGluZyBlbmRFbGVtZW50Ci0gICAgICogZXZlbnQuPC9wPgotICAgICAqCi0gICAgICogPHA+VGhpcyBldmVudCBhbGxvd3MgdXAgdG8gdGhyZWUgbmFtZSBjb21wb25lbnRzIGZvciBlYWNoCi0gICAgICogZWxlbWVudDo8L3A+Ci0gICAgICoKLSAgICAgKiA8b2w+Ci0gICAgICogPGxpPnRoZSBOYW1lc3BhY2UgVVJJOzwvbGk+Ci0gICAgICogPGxpPnRoZSBsb2NhbCBuYW1lOyBhbmQ8L2xpPgotICAgICAqIDxsaT50aGUgcXVhbGlmaWVkIChwcmVmaXhlZCkgbmFtZS48L2xpPgotICAgICAqIDwvb2w+Ci0gICAgICoKLSAgICAgKiA8cD5Bbnkgb3IgYWxsIG9mIHRoZXNlIG1heSBiZSBwcm92aWRlZCwgZGVwZW5kaW5nIG9uIHRoZQotICAgICAqIHZhbHVlcyBvZiB0aGUgPHZhcj5odHRwOi8veG1sLm9yZy9zYXgvZmVhdHVyZXMvbmFtZXNwYWNlczwvdmFyPgotICAgICAqIGFuZCB0aGUgPHZhcj5odHRwOi8veG1sLm9yZy9zYXgvZmVhdHVyZXMvbmFtZXNwYWNlLXByZWZpeGVzPC92YXI+Ci0gICAgICogcHJvcGVydGllczo8L3A+Ci0gICAgICoKLSAgICAgKiA8dWw+Ci0gICAgICogPGxpPnRoZSBOYW1lc3BhY2UgVVJJIGFuZCBsb2NhbCBuYW1lIGFyZSByZXF1aXJlZCB3aGVuCi0gICAgICogdGhlIG5hbWVzcGFjZXMgcHJvcGVydHkgaXMgPHZhcj50cnVlPC92YXI+ICh0aGUgZGVmYXVsdCksIGFuZCBhcmUKLSAgICAgKiBvcHRpb25hbCB3aGVuIHRoZSBuYW1lc3BhY2VzIHByb3BlcnR5IGlzIDx2YXI+ZmFsc2U8L3Zhcj4gKGlmIG9uZSBpcwotICAgICAqIHNwZWNpZmllZCwgYm90aCBtdXN0IGJlKTs8L2xpPgotICAgICAqIDxsaT50aGUgcXVhbGlmaWVkIG5hbWUgaXMgcmVxdWlyZWQgd2hlbiB0aGUgbmFtZXNwYWNlLXByZWZpeGVzIHByb3BlcnR5Ci0gICAgICogaXMgPHZhcj50cnVlPC92YXI+LCBhbmQgaXMgb3B0aW9uYWwgd2hlbiB0aGUgbmFtZXNwYWNlLXByZWZpeGVzIHByb3BlcnR5Ci0gICAgICogaXMgPHZhcj5mYWxzZTwvdmFyPiAodGhlIGRlZmF1bHQpLjwvbGk+Ci0gICAgICogPC91bD4KLSAgICAgKgotICAgICAqIDxwPk5vdGUgdGhhdCB0aGUgYXR0cmlidXRlIGxpc3QgcHJvdmlkZWQgd2lsbCBjb250YWluIG9ubHkKLSAgICAgKiBhdHRyaWJ1dGVzIHdpdGggZXhwbGljaXQgdmFsdWVzIChzcGVjaWZpZWQgb3IgZGVmYXVsdGVkKToKLSAgICAgKiAjSU1QTElFRCBhdHRyaWJ1dGVzIHdpbGwgYmUgb21pdHRlZC4gIFRoZSBhdHRyaWJ1dGUgbGlzdAotICAgICAqIHdpbGwgY29udGFpbiBhdHRyaWJ1dGVzIHVzZWQgZm9yIE5hbWVzcGFjZSBkZWNsYXJhdGlvbnMKLSAgICAgKiAoeG1sbnMqIGF0dHJpYnV0ZXMpIG9ubHkgaWYgdGhlCi0gICAgICogPGNvZGU+aHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL25hbWVzcGFjZS1wcmVmaXhlczwvY29kZT4KLSAgICAgKiBwcm9wZXJ0eSBpcyB0cnVlIChpdCBpcyBmYWxzZSBieSBkZWZhdWx0LCBhbmQgc3VwcG9ydCBmb3IgYQotICAgICAqIHRydWUgdmFsdWUgaXMgb3B0aW9uYWwpLjwvcD4KLSAgICAgKgotICAgICAqIDxwPkxpa2Uge0BsaW5rICNjaGFyYWN0ZXJzIGNoYXJhY3RlcnMoKX0sIGF0dHJpYnV0ZSB2YWx1ZXMgbWF5IGhhdmUKLSAgICAgKiBjaGFyYWN0ZXJzIHRoYXQgbmVlZCBtb3JlIHRoYW4gb25lIDxjb2RlPmNoYXI8L2NvZGU+IHZhbHVlLiAgPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIHVyaSB0aGUgTmFtZXNwYWNlIFVSSSwgb3IgdGhlIGVtcHR5IHN0cmluZyBpZiB0aGUKLSAgICAgKiAgICAgICAgZWxlbWVudCBoYXMgbm8gTmFtZXNwYWNlIFVSSSBvciBpZiBOYW1lc3BhY2UKLSAgICAgKiAgICAgICAgcHJvY2Vzc2luZyBpcyBub3QgYmVpbmcgcGVyZm9ybWVkCi0gICAgICogQHBhcmFtIGxvY2FsTmFtZSB0aGUgbG9jYWwgbmFtZSAod2l0aG91dCBwcmVmaXgpLCBvciB0aGUKLSAgICAgKiAgICAgICAgZW1wdHkgc3RyaW5nIGlmIE5hbWVzcGFjZSBwcm9jZXNzaW5nIGlzIG5vdCBiZWluZwotICAgICAqICAgICAgICBwZXJmb3JtZWQKLSAgICAgKiBAcGFyYW0gcU5hbWUgdGhlIHF1YWxpZmllZCBuYW1lICh3aXRoIHByZWZpeCksIG9yIHRoZQotICAgICAqICAgICAgICBlbXB0eSBzdHJpbmcgaWYgcXVhbGlmaWVkIG5hbWVzIGFyZSBub3QgYXZhaWxhYmxlCi0gICAgICogQHBhcmFtIGF0dHMgdGhlIGF0dHJpYnV0ZXMgYXR0YWNoZWQgdG8gdGhlIGVsZW1lbnQuICBJZgotICAgICAqICAgICAgICB0aGVyZSBhcmUgbm8gYXR0cmlidXRlcywgaXQgc2hhbGwgYmUgYW4gZW1wdHkKLSAgICAgKiAgICAgICAgQXR0cmlidXRlcyBvYmplY3QuICBUaGUgdmFsdWUgb2YgdGhpcyBvYmplY3QgYWZ0ZXIKLSAgICAgKiAgICAgICAgc3RhcnRFbGVtZW50IHJldHVybnMgaXMgdW5kZWZpbmVkCi0gICAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gYW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbgotICAgICAqIEBzZWUgI2VuZEVsZW1lbnQKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkF0dHJpYnV0ZXMKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LmhlbHBlcnMuQXR0cmlidXRlc0ltcGwKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQgKFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcU5hbWUsIEF0dHJpYnV0ZXMgYXR0cykKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbjsKLQotCi0gICAgLyoqCi0gICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIGVuZCBvZiBhbiBlbGVtZW50LgotICAgICAqCi0gICAgICogPHA+VGhlIFNBWCBwYXJzZXIgd2lsbCBpbnZva2UgdGhpcyBtZXRob2QgYXQgdGhlIGVuZCBvZiBldmVyeQotICAgICAqIGVsZW1lbnQgaW4gdGhlIFhNTCBkb2N1bWVudDsgdGhlcmUgd2lsbCBiZSBhIGNvcnJlc3BvbmRpbmcKLSAgICAgKiB7QGxpbmsgI3N0YXJ0RWxlbWVudCBzdGFydEVsZW1lbnR9IGV2ZW50IGZvciBldmVyeSBlbmRFbGVtZW50Ci0gICAgICogZXZlbnQgKGV2ZW4gd2hlbiB0aGUgZWxlbWVudCBpcyBlbXB0eSkuPC9wPgotICAgICAqCi0gICAgICogPHA+Rm9yIGluZm9ybWF0aW9uIG9uIHRoZSBuYW1lcywgc2VlIHN0YXJ0RWxlbWVudC48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gdXJpIHRoZSBOYW1lc3BhY2UgVVJJLCBvciB0aGUgZW1wdHkgc3RyaW5nIGlmIHRoZQotICAgICAqICAgICAgICBlbGVtZW50IGhhcyBubyBOYW1lc3BhY2UgVVJJIG9yIGlmIE5hbWVzcGFjZQotICAgICAqICAgICAgICBwcm9jZXNzaW5nIGlzIG5vdCBiZWluZyBwZXJmb3JtZWQKLSAgICAgKiBAcGFyYW0gbG9jYWxOYW1lIHRoZSBsb2NhbCBuYW1lICh3aXRob3V0IHByZWZpeCksIG9yIHRoZQotICAgICAqICAgICAgICBlbXB0eSBzdHJpbmcgaWYgTmFtZXNwYWNlIHByb2Nlc3NpbmcgaXMgbm90IGJlaW5nCi0gICAgICogICAgICAgIHBlcmZvcm1lZAotICAgICAqIEBwYXJhbSBxTmFtZSB0aGUgcXVhbGlmaWVkIFhNTCBuYW1lICh3aXRoIHByZWZpeCksIG9yIHRoZQotICAgICAqICAgICAgICBlbXB0eSBzdHJpbmcgaWYgcXVhbGlmaWVkIG5hbWVzIGFyZSBub3QgYXZhaWxhYmxlCi0gICAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gYW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZEVsZW1lbnQgKFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHFOYW1lKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uOwotCi0KLSAgICAvKioKLSAgICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBjaGFyYWN0ZXIgZGF0YS4KLSAgICAgKgotICAgICAqIDxwPlRoZSBQYXJzZXIgd2lsbCBjYWxsIHRoaXMgbWV0aG9kIHRvIHJlcG9ydCBlYWNoIGNodW5rIG9mCi0gICAgICogY2hhcmFjdGVyIGRhdGEuICBTQVggcGFyc2VycyBtYXkgcmV0dXJuIGFsbCBjb250aWd1b3VzIGNoYXJhY3RlcgotICAgICAqIGRhdGEgaW4gYSBzaW5nbGUgY2h1bmssIG9yIHRoZXkgbWF5IHNwbGl0IGl0IGludG8gc2V2ZXJhbAotICAgICAqIGNodW5rczsgaG93ZXZlciwgYWxsIG9mIHRoZSBjaGFyYWN0ZXJzIGluIGFueSBzaW5nbGUgZXZlbnQKLSAgICAgKiBtdXN0IGNvbWUgZnJvbSB0aGUgc2FtZSBleHRlcm5hbCBlbnRpdHkgc28gdGhhdCB0aGUgTG9jYXRvcgotICAgICAqIHByb3ZpZGVzIHVzZWZ1bCBpbmZvcm1hdGlvbi48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5UaGUgYXBwbGljYXRpb24gbXVzdCBub3QgYXR0ZW1wdCB0byByZWFkIGZyb20gdGhlIGFycmF5Ci0gICAgICogb3V0c2lkZSBvZiB0aGUgc3BlY2lmaWVkIHJhbmdlLjwvcD4KLSAgICAgKgotICAgICAqIDxwPkluZGl2aWR1YWwgY2hhcmFjdGVycyBtYXkgY29uc2lzdCBvZiBtb3JlIHRoYW4gb25lIEphdmEKLSAgICAgKiA8Y29kZT5jaGFyPC9jb2RlPiB2YWx1ZS4gIFRoZXJlIGFyZSB0d28gaW1wb3J0YW50IGNhc2VzIHdoZXJlIHRoaXMKLSAgICAgKiBoYXBwZW5zLCBiZWNhdXNlIGNoYXJhY3RlcnMgY2FuJ3QgYmUgcmVwcmVzZW50ZWQgaW4ganVzdCBzaXh0ZWVuIGJpdHMuCi0gICAgICogSW4gb25lIGNhc2UsIGNoYXJhY3RlcnMgYXJlIHJlcHJlc2VudGVkIGluIGEgPGVtPlN1cnJvZ2F0ZSBQYWlyPC9lbT4sCi0gICAgICogdXNpbmcgdHdvIHNwZWNpYWwgVW5pY29kZSB2YWx1ZXMuIFN1Y2ggY2hhcmFjdGVycyBhcmUgaW4gdGhlIHNvLWNhbGxlZAotICAgICAqICJBc3RyYWwgUGxhbmVzIiwgd2l0aCBhIGNvZGUgcG9pbnQgYWJvdmUgVStGRkZGLiAgQSBzZWNvbmQgY2FzZSBpbnZvbHZlcwotICAgICAqIGNvbXBvc2l0ZSBjaGFyYWN0ZXJzLCBzdWNoIGFzIGEgYmFzZSBjaGFyYWN0ZXIgY29tYmluaW5nIHdpdGggb25lIG9yCi0gICAgICogbW9yZSBhY2NlbnQgY2hhcmFjdGVycy4gPC9wPgotICAgICAqCi0gICAgICogPHA+IFlvdXIgY29kZSBzaG91bGQgbm90IGFzc3VtZSB0aGF0IGFsZ29yaXRobXMgdXNpbmcKLSAgICAgKiA8Y29kZT5jaGFyPC9jb2RlPi1hdC1hLXRpbWUgaWRpb21zIHdpbGwgYmUgd29ya2luZyBpbiBjaGFyYWN0ZXIKLSAgICAgKiB1bml0czsgaW4gc29tZSBjYXNlcyB0aGV5IHdpbGwgc3BsaXQgY2hhcmFjdGVycy4gIFRoaXMgaXMgcmVsZXZhbnQKLSAgICAgKiB3aGVyZXZlciBYTUwgcGVybWl0cyBhcmJpdHJhcnkgY2hhcmFjdGVycywgc3VjaCBhcyBhdHRyaWJ1dGUgdmFsdWVzLAotICAgICAqIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gZGF0YSwgYW5kIGNvbW1lbnRzIGFzIHdlbGwgYXMgaW4gZGF0YSByZXBvcnRlZAotICAgICAqIGZyb20gdGhpcyBtZXRob2QuICBJdCdzIGFsc28gZ2VuZXJhbGx5IHJlbGV2YW50IHdoZW5ldmVyIEphdmEgY29kZQotICAgICAqIG1hbmlwdWxhdGVzIGludGVybmF0aW9uYWxpemVkIHRleHQ7IHRoZSBpc3N1ZSBpc24ndCB1bmlxdWUgdG8gWE1MLjwvcD4KLSAgICAgKgotICAgICAqIDxwPk5vdGUgdGhhdCBzb21lIHBhcnNlcnMgd2lsbCByZXBvcnQgd2hpdGVzcGFjZSBpbiBlbGVtZW50Ci0gICAgICogY29udGVudCB1c2luZyB0aGUge0BsaW5rICNpZ25vcmFibGVXaGl0ZXNwYWNlIGlnbm9yYWJsZVdoaXRlc3BhY2V9Ci0gICAgICogbWV0aG9kIHJhdGhlciB0aGFuIHRoaXMgb25lICh2YWxpZGF0aW5nIHBhcnNlcnMgPGVtPm11c3Q8L2VtPgotICAgICAqIGRvIHNvKS48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gY2ggdGhlIGNoYXJhY3RlcnMgZnJvbSB0aGUgWE1MIGRvY3VtZW50Ci0gICAgICogQHBhcmFtIHN0YXJ0IHRoZSBzdGFydCBwb3NpdGlvbiBpbiB0aGUgYXJyYXkKLSAgICAgKiBAcGFyYW0gbGVuZ3RoIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyB0byByZWFkIGZyb20gdGhlIGFycmF5Ci0gICAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gYW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbgotICAgICAqIEBzZWUgI2lnbm9yYWJsZVdoaXRlc3BhY2UKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkxvY2F0b3IKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBjaGFyYWN0ZXJzIChjaGFyIGNoW10sIGludCBzdGFydCwgaW50IGxlbmd0aCkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbjsKLQotCi0gICAgLyoqCi0gICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgaWdub3JhYmxlIHdoaXRlc3BhY2UgaW4gZWxlbWVudCBjb250ZW50LgotICAgICAqCi0gICAgICogPHA+VmFsaWRhdGluZyBQYXJzZXJzIG11c3QgdXNlIHRoaXMgbWV0aG9kIHRvIHJlcG9ydCBlYWNoIGNodW5rCi0gICAgICogb2Ygd2hpdGVzcGFjZSBpbiBlbGVtZW50IGNvbnRlbnQgKHNlZSB0aGUgVzNDIFhNTCAxLjAKLSAgICAgKiByZWNvbW1lbmRhdGlvbiwgc2VjdGlvbiAyLjEwKTogbm9uLXZhbGlkYXRpbmcgcGFyc2VycyBtYXkgYWxzbwotICAgICAqIHVzZSB0aGlzIG1ldGhvZCBpZiB0aGV5IGFyZSBjYXBhYmxlIG9mIHBhcnNpbmcgYW5kIHVzaW5nCi0gICAgICogY29udGVudCBtb2RlbHMuPC9wPgotICAgICAqCi0gICAgICogPHA+U0FYIHBhcnNlcnMgbWF5IHJldHVybiBhbGwgY29udGlndW91cyB3aGl0ZXNwYWNlIGluIGEgc2luZ2xlCi0gICAgICogY2h1bmssIG9yIHRoZXkgbWF5IHNwbGl0IGl0IGludG8gc2V2ZXJhbCBjaHVua3M7IGhvd2V2ZXIsIGFsbCBvZgotICAgICAqIHRoZSBjaGFyYWN0ZXJzIGluIGFueSBzaW5nbGUgZXZlbnQgbXVzdCBjb21lIGZyb20gdGhlIHNhbWUKLSAgICAgKiBleHRlcm5hbCBlbnRpdHksIHNvIHRoYXQgdGhlIExvY2F0b3IgcHJvdmlkZXMgdXNlZnVsCi0gICAgICogaW5mb3JtYXRpb24uPC9wPgotICAgICAqCi0gICAgICogPHA+VGhlIGFwcGxpY2F0aW9uIG11c3Qgbm90IGF0dGVtcHQgdG8gcmVhZCBmcm9tIHRoZSBhcnJheQotICAgICAqIG91dHNpZGUgb2YgdGhlIHNwZWNpZmllZCByYW5nZS48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gY2ggdGhlIGNoYXJhY3RlcnMgZnJvbSB0aGUgWE1MIGRvY3VtZW50Ci0gICAgICogQHBhcmFtIHN0YXJ0IHRoZSBzdGFydCBwb3NpdGlvbiBpbiB0aGUgYXJyYXkKLSAgICAgKiBAcGFyYW0gbGVuZ3RoIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyB0byByZWFkIGZyb20gdGhlIGFycmF5Ci0gICAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gYW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbgotICAgICAqIEBzZWUgI2NoYXJhY3RlcnMKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBpZ25vcmFibGVXaGl0ZXNwYWNlIChjaGFyIGNoW10sIGludCBzdGFydCwgaW50IGxlbmd0aCkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbjsKLQotCi0gICAgLyoqCi0gICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgYSBwcm9jZXNzaW5nIGluc3RydWN0aW9uLgotICAgICAqCi0gICAgICogPHA+VGhlIFBhcnNlciB3aWxsIGludm9rZSB0aGlzIG1ldGhvZCBvbmNlIGZvciBlYWNoIHByb2Nlc3NpbmcKLSAgICAgKiBpbnN0cnVjdGlvbiBmb3VuZDogbm90ZSB0aGF0IHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb25zIG1heSBvY2N1cgotICAgICAqIGJlZm9yZSBvciBhZnRlciB0aGUgbWFpbiBkb2N1bWVudCBlbGVtZW50LjwvcD4KLSAgICAgKgotICAgICAqIDxwPkEgU0FYIHBhcnNlciBtdXN0IG5ldmVyIHJlcG9ydCBhbiBYTUwgZGVjbGFyYXRpb24gKFhNTCAxLjAsCi0gICAgICogc2VjdGlvbiAyLjgpIG9yIGEgdGV4dCBkZWNsYXJhdGlvbiAoWE1MIDEuMCwgc2VjdGlvbiA0LjMuMSkKLSAgICAgKiB1c2luZyB0aGlzIG1ldGhvZC48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5MaWtlIHtAbGluayAjY2hhcmFjdGVycyBjaGFyYWN0ZXJzKCl9LCBwcm9jZXNzaW5nIGluc3RydWN0aW9uCi0gICAgICogZGF0YSBtYXkgaGF2ZSBjaGFyYWN0ZXJzIHRoYXQgbmVlZCBtb3JlIHRoYW4gb25lIDxjb2RlPmNoYXI8L2NvZGU+Ci0gICAgICogdmFsdWUuIDwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSB0YXJnZXQgdGhlIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gdGFyZ2V0Ci0gICAgICogQHBhcmFtIGRhdGEgdGhlIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gZGF0YSwgb3IgbnVsbCBpZgotICAgICAqICAgICAgICBub25lIHdhcyBzdXBwbGllZC4gIFRoZSBkYXRhIGRvZXMgbm90IGluY2x1ZGUgYW55Ci0gICAgICogICAgICAgIHdoaXRlc3BhY2Ugc2VwYXJhdGluZyBpdCBmcm9tIHRoZSB0YXJnZXQKLSAgICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBhbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcHJvY2Vzc2luZ0luc3RydWN0aW9uIChTdHJpbmcgdGFyZ2V0LCBTdHJpbmcgZGF0YSkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbjsKLQotCi0gICAgLyoqCi0gICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgYSBza2lwcGVkIGVudGl0eS4KLSAgICAgKiBUaGlzIGlzIG5vdCBjYWxsZWQgZm9yIGVudGl0eSByZWZlcmVuY2VzIHdpdGhpbiBtYXJrdXAgY29uc3RydWN0cwotICAgICAqIHN1Y2ggYXMgZWxlbWVudCBzdGFydCB0YWdzIG9yIG1hcmt1cCBkZWNsYXJhdGlvbnMuICAoVGhlIFhNTAotICAgICAqIHJlY29tbWVuZGF0aW9uIHJlcXVpcmVzIHJlcG9ydGluZyBza2lwcGVkIGV4dGVybmFsIGVudGl0aWVzLgotICAgICAqIFNBWCBhbHNvIHJlcG9ydHMgaW50ZXJuYWwgZW50aXR5IGV4cGFuc2lvbi9ub24tZXhwYW5zaW9uLCBleGNlcHQKLSAgICAgKiB3aXRoaW4gbWFya3VwIGNvbnN0cnVjdHMuKQotICAgICAqCi0gICAgICogPHA+VGhlIFBhcnNlciB3aWxsIGludm9rZSB0aGlzIG1ldGhvZCBlYWNoIHRpbWUgdGhlIGVudGl0eSBpcwotICAgICAqIHNraXBwZWQuICBOb24tdmFsaWRhdGluZyBwcm9jZXNzb3JzIG1heSBza2lwIGVudGl0aWVzIGlmIHRoZXkKLSAgICAgKiBoYXZlIG5vdCBzZWVuIHRoZSBkZWNsYXJhdGlvbnMgKGJlY2F1c2UsIGZvciBleGFtcGxlLCB0aGUKLSAgICAgKiBlbnRpdHkgd2FzIGRlY2xhcmVkIGluIGFuIGV4dGVybmFsIERURCBzdWJzZXQpLiAgQWxsIHByb2Nlc3NvcnMKLSAgICAgKiBtYXkgc2tpcCBleHRlcm5hbCBlbnRpdGllcywgZGVwZW5kaW5nIG9uIHRoZSB2YWx1ZXMgb2YgdGhlCi0gICAgICogPGNvZGU+aHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL2V4dGVybmFsLWdlbmVyYWwtZW50aXRpZXM8L2NvZGU+Ci0gICAgICogYW5kIHRoZQotICAgICAqIDxjb2RlPmh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy9leHRlcm5hbC1wYXJhbWV0ZXItZW50aXRpZXM8L2NvZGU+Ci0gICAgICogcHJvcGVydGllcy48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSB0aGUgbmFtZSBvZiB0aGUgc2tpcHBlZCBlbnRpdHkuICBJZiBpdCBpcyBhCi0gICAgICogICAgICAgIHBhcmFtZXRlciBlbnRpdHksIHRoZSBuYW1lIHdpbGwgYmVnaW4gd2l0aCAnJScsIGFuZCBpZgotICAgICAqICAgICAgICBpdCBpcyB0aGUgZXh0ZXJuYWwgRFREIHN1YnNldCwgaXQgd2lsbCBiZSB0aGUgc3RyaW5nCi0gICAgICogICAgICAgICJbZHRkXSIKLSAgICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBhbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2tpcHBlZEVudGl0eSAoU3RyaW5nIG5hbWUpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb247Ci19Ci0KLS8vIGVuZCBvZiBDb250ZW50SGFuZGxlci5qYXZhCmRpZmYgLS1naXQgYS9zcmMvb3JnL3htbC9zYXgvRFRESGFuZGxlci5qYXZhIGIvc3JjL29yZy94bWwvc2F4L0RUREhhbmRsZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNmQ0M2VjZC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3htbC9zYXgvRFRESGFuZGxlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTQxICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDAsIDIwMDUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8vIFNBWCBEVEQgaGFuZGxlci4KLS8vIGh0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmcKLS8vIE5vIHdhcnJhbnR5OyBubyBjb3B5cmlnaHQgLS0gdXNlIHRoaXMgYXMgeW91IHdpbGwuCi0vLyAkSWQ6IERUREhhbmRsZXIuamF2YSx2IDEuMiAyMDA0LzExLzAzIDIyOjQ0OjUxIGpzdXR0b3IgRXhwICQKLQotcGFja2FnZSBvcmcueG1sLnNheDsKLQotLyoqCi0gKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBiYXNpYyBEVEQtcmVsYXRlZCBldmVudHMuCi0gKgotICogPGJsb2NrcXVvdGU+Ci0gKiA8ZW0+VGhpcyBtb2R1bGUsIGJvdGggc291cmNlIGNvZGUgYW5kIGRvY3VtZW50YXRpb24sIGlzIGluIHRoZQotICogUHVibGljIERvbWFpbiwgYW5kIGNvbWVzIHdpdGggPHN0cm9uZz5OTyBXQVJSQU5UWTwvc3Ryb25nPi48L2VtPgotICogU2VlIDxhIGhyZWY9J2h0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmcnPmh0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmc8L2E+Ci0gKiBmb3IgZnVydGhlciBpbmZvcm1hdGlvbi4KLSAqIDwvYmxvY2txdW90ZT4KLSAqCi0gKiA8cD5JZiBhIFNBWCBhcHBsaWNhdGlvbiBuZWVkcyBpbmZvcm1hdGlvbiBhYm91dCBub3RhdGlvbnMgYW5kCi0gKiB1bnBhcnNlZCBlbnRpdGllcywgdGhlbiB0aGUgYXBwbGljYXRpb24gaW1wbGVtZW50cyB0aGlzCi0gKiBpbnRlcmZhY2UgYW5kIHJlZ2lzdGVycyBhbiBpbnN0YW5jZSB3aXRoIHRoZSBTQVggcGFyc2VyIHVzaW5nCi0gKiB0aGUgcGFyc2VyJ3Mgc2V0RFRESGFuZGxlciBtZXRob2QuICBUaGUgcGFyc2VyIHVzZXMgdGhlCi0gKiBpbnN0YW5jZSB0byByZXBvcnQgbm90YXRpb24gYW5kIHVucGFyc2VkIGVudGl0eSBkZWNsYXJhdGlvbnMgdG8KLSAqIHRoZSBhcHBsaWNhdGlvbi48L3A+Ci0gKgotICogPHA+Tm90ZSB0aGF0IHRoaXMgaW50ZXJmYWNlIGluY2x1ZGVzIG9ubHkgdGhvc2UgRFREIGV2ZW50cyB0aGF0Ci0gKiB0aGUgWE1MIHJlY29tbWVuZGF0aW9uIDxlbT5yZXF1aXJlczwvZW0+IHByb2Nlc3NvcnMgdG8gcmVwb3J0OgotICogbm90YXRpb24gYW5kIHVucGFyc2VkIGVudGl0eSBkZWNsYXJhdGlvbnMuPC9wPgotICoKLSAqIDxwPlRoZSBTQVggcGFyc2VyIG1heSByZXBvcnQgdGhlc2UgZXZlbnRzIGluIGFueSBvcmRlciwgcmVnYXJkbGVzcwotICogb2YgdGhlIG9yZGVyIGluIHdoaWNoIHRoZSBub3RhdGlvbnMgYW5kIHVucGFyc2VkIGVudGl0aWVzIHdlcmUKLSAqIGRlY2xhcmVkOyBob3dldmVyLCBhbGwgRFREIGV2ZW50cyBtdXN0IGJlIHJlcG9ydGVkIGFmdGVyIHRoZQotICogZG9jdW1lbnQgaGFuZGxlcidzIHN0YXJ0RG9jdW1lbnQgZXZlbnQsIGFuZCBiZWZvcmUgdGhlIGZpcnN0Ci0gKiBzdGFydEVsZW1lbnQgZXZlbnQuCi0gKiAoSWYgdGhlIHtAbGluayBvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXIgTGV4aWNhbEhhbmRsZXJ9IGlzCi0gKiB1c2VkLCB0aGVzZSBldmVudHMgbXVzdCBhbHNvIGJlIHJlcG9ydGVkIGJlZm9yZSB0aGUgZW5kRFREIGV2ZW50LikKLSAqIDwvcD4KLSAqCi0gKiA8cD5JdCBpcyB1cCB0byB0aGUgYXBwbGljYXRpb24gdG8gc3RvcmUgdGhlIGluZm9ybWF0aW9uIGZvcgotICogZnV0dXJlIHVzZSAocGVyaGFwcyBpbiBhIGhhc2ggdGFibGUgb3Igb2JqZWN0IHRyZWUpLgotICogSWYgdGhlIGFwcGxpY2F0aW9uIGVuY291bnRlcnMgYXR0cmlidXRlcyBvZiB0eXBlICJOT1RBVElPTiIsCi0gKiAiRU5USVRZIiwgb3IgIkVOVElUSUVTIiwgaXQgY2FuIHVzZSB0aGUgaW5mb3JtYXRpb24gdGhhdCBpdAotICogb2J0YWluZWQgdGhyb3VnaCB0aGlzIGludGVyZmFjZSB0byBmaW5kIHRoZSBlbnRpdHkgYW5kL29yCi0gKiBub3RhdGlvbiBjb3JyZXNwb25kaW5nIHdpdGggdGhlIGF0dHJpYnV0ZSB2YWx1ZS48L3A+Ci0gKgotICogQHNpbmNlIFNBWCAxLjAKLSAqIEBhdXRob3IgRGF2aWQgTWVnZ2luc29uCi0gKiBAc2VlIG9yZy54bWwuc2F4LlhNTFJlYWRlciNzZXREVERIYW5kbGVyCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgRFRESGFuZGxlciB7Ci0KLQotICAgIC8qKgotICAgICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGEgbm90YXRpb24gZGVjbGFyYXRpb24gZXZlbnQuCi0gICAgICoKLSAgICAgKiA8cD5JdCBpcyB1cCB0byB0aGUgYXBwbGljYXRpb24gdG8gcmVjb3JkIHRoZSBub3RhdGlvbiBmb3IgbGF0ZXIKLSAgICAgKiByZWZlcmVuY2UsIGlmIG5lY2Vzc2FyeTsKLSAgICAgKiBub3RhdGlvbnMgbWF5IGFwcGVhciBhcyBhdHRyaWJ1dGUgdmFsdWVzIGFuZCBpbiB1bnBhcnNlZCBlbnRpdHkKLSAgICAgKiBkZWNsYXJhdGlvbnMsIGFuZCBhcmUgc29tZXRpbWUgdXNlZCB3aXRoIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24KLSAgICAgKiB0YXJnZXQgbmFtZXMuPC9wPgotICAgICAqCi0gICAgICogPHA+QXQgbGVhc3Qgb25lIG9mIHB1YmxpY0lkIGFuZCBzeXN0ZW1JZCBtdXN0IGJlIG5vbi1udWxsLgotICAgICAqIElmIGEgc3lzdGVtIGlkZW50aWZpZXIgaXMgcHJlc2VudCwgYW5kIGl0IGlzIGEgVVJMLCB0aGUgU0FYCi0gICAgICogcGFyc2VyIG11c3QgcmVzb2x2ZSBpdCBmdWxseSBiZWZvcmUgcGFzc2luZyBpdCB0byB0aGUKLSAgICAgKiBhcHBsaWNhdGlvbiB0aHJvdWdoIHRoaXMgZXZlbnQuPC9wPgotICAgICAqCi0gICAgICogPHA+VGhlcmUgaXMgbm8gZ3VhcmFudGVlIHRoYXQgdGhlIG5vdGF0aW9uIGRlY2xhcmF0aW9uIHdpbGwgYmUKLSAgICAgKiByZXBvcnRlZCBiZWZvcmUgYW55IHVucGFyc2VkIGVudGl0aWVzIHRoYXQgdXNlIGl0LjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBub3RhdGlvbiBuYW1lLgotICAgICAqIEBwYXJhbSBwdWJsaWNJZCBUaGUgbm90YXRpb24ncyBwdWJsaWMgaWRlbnRpZmllciwgb3IgbnVsbCBpZgotICAgICAqICAgICAgICBub25lIHdhcyBnaXZlbi4KLSAgICAgKiBAcGFyYW0gc3lzdGVtSWQgVGhlIG5vdGF0aW9uJ3Mgc3lzdGVtIGlkZW50aWZpZXIsIG9yIG51bGwgaWYKLSAgICAgKiAgICAgICAgbm9uZSB3YXMgZ2l2ZW4uCi0gICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICAgKiBAc2VlICN1bnBhcnNlZEVudGl0eURlY2wKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkF0dHJpYnV0ZXMKLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBub3RhdGlvbkRlY2wgKFN0cmluZyBuYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHB1YmxpY0lkLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHN5c3RlbUlkKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uOwotCi0KLSAgICAvKioKLSAgICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBhbiB1bnBhcnNlZCBlbnRpdHkgZGVjbGFyYXRpb24gZXZlbnQuCi0gICAgICoKLSAgICAgKiA8cD5Ob3RlIHRoYXQgdGhlIG5vdGF0aW9uIG5hbWUgY29ycmVzcG9uZHMgdG8gYSBub3RhdGlvbgotICAgICAqIHJlcG9ydGVkIGJ5IHRoZSB7QGxpbmsgI25vdGF0aW9uRGVjbCBub3RhdGlvbkRlY2x9IGV2ZW50LgotICAgICAqIEl0IGlzIHVwIHRvIHRoZSBhcHBsaWNhdGlvbiB0byByZWNvcmQgdGhlIGVudGl0eSBmb3IgbGF0ZXIKLSAgICAgKiByZWZlcmVuY2UsIGlmIG5lY2Vzc2FyeTsKLSAgICAgKiB1bnBhcnNlZCBlbnRpdGllcyBtYXkgYXBwZWFyIGFzIGF0dHJpYnV0ZSB2YWx1ZXMuCi0gICAgICogPC9wPgotICAgICAqCi0gICAgICogPHA+SWYgdGhlIHN5c3RlbSBpZGVudGlmaWVyIGlzIGEgVVJMLCB0aGUgcGFyc2VyIG11c3QgcmVzb2x2ZSBpdAotICAgICAqIGZ1bGx5IGJlZm9yZSBwYXNzaW5nIGl0IHRvIHRoZSBhcHBsaWNhdGlvbi48L3A+Ci0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSB1bnBhcnNlZCBlbnRpdHkncyBuYW1lLgotICAgICAqIEBwYXJhbSBwdWJsaWNJZCBUaGUgZW50aXR5J3MgcHVibGljIGlkZW50aWZpZXIsIG9yIG51bGwgaWYgbm9uZQotICAgICAqICAgICAgICB3YXMgZ2l2ZW4uCi0gICAgICogQHBhcmFtIHN5c3RlbUlkIFRoZSBlbnRpdHkncyBzeXN0ZW0gaWRlbnRpZmllci4KLSAgICAgKiBAcGFyYW0gbm90YXRpb25OYW1lIFRoZSBuYW1lIG9mIHRoZSBhc3NvY2lhdGVkIG5vdGF0aW9uLgotICAgICAqIEBzZWUgI25vdGF0aW9uRGVjbAotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQXR0cmlidXRlcwotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHVucGFyc2VkRW50aXR5RGVjbCAoU3RyaW5nIG5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcHVibGljSWQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgc3lzdGVtSWQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbm90YXRpb25OYW1lKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uOwotCi19Ci0KLS8vIGVuZCBvZiBEVERIYW5kbGVyLmphdmEKZGlmZiAtLWdpdCBhL3NyYy9vcmcveG1sL3NheC9Eb2N1bWVudEhhbmRsZXIuamF2YSBiL3NyYy9vcmcveG1sL3NheC9Eb2N1bWVudEhhbmRsZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZmZlNGQyYS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3htbC9zYXgvRG9jdW1lbnRIYW5kbGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyNTYgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwMCwgMjAwNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLy8gU0FYIGRvY3VtZW50IGhhbmRsZXIuCi0vLyBodHRwOi8vd3d3LnNheHByb2plY3Qub3JnCi0vLyBObyB3YXJyYW50eTsgbm8gY29weXJpZ2h0IC0tIHVzZSB0aGlzIGFzIHlvdSB3aWxsLgotLy8gJElkOiBEb2N1bWVudEhhbmRsZXIuamF2YSx2IDEuMiAyMDA0LzExLzAzIDIyOjQ0OjUxIGpzdXR0b3IgRXhwICQKLQotcGFja2FnZSBvcmcueG1sLnNheDsKLQotLyoqCi0gKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBnZW5lcmFsIGRvY3VtZW50IGV2ZW50cy4KLSAqCi0gKiA8YmxvY2txdW90ZT4KLSAqIDxlbT5UaGlzIG1vZHVsZSwgYm90aCBzb3VyY2UgY29kZSBhbmQgZG9jdW1lbnRhdGlvbiwgaXMgaW4gdGhlCi0gKiBQdWJsaWMgRG9tYWluLCBhbmQgY29tZXMgd2l0aCA8c3Ryb25nPk5PIFdBUlJBTlRZPC9zdHJvbmc+LjwvZW0+Ci0gKiBTZWUgPGEgaHJlZj0naHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZyc+aHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZzwvYT4KLSAqIGZvciBmdXJ0aGVyIGluZm9ybWF0aW9uLgotICogPC9ibG9ja3F1b3RlPgotICoKLSAqIDxwPlRoaXMgd2FzIHRoZSBtYWluIGV2ZW50LWhhbmRsaW5nIGludGVyZmFjZSBmb3IgU0FYMTsgaW4KLSAqIFNBWDIsIGl0IGhhcyBiZWVuIHJlcGxhY2VkIGJ5IHtAbGluayBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcgotICogQ29udGVudEhhbmRsZXJ9LCB3aGljaCBwcm92aWRlcyBOYW1lc3BhY2Ugc3VwcG9ydCBhbmQgcmVwb3J0aW5nCi0gKiBvZiBza2lwcGVkIGVudGl0aWVzLiAgVGhpcyBpbnRlcmZhY2UgaXMgaW5jbHVkZWQgaW4gU0FYMiBvbmx5Ci0gKiB0byBzdXBwb3J0IGxlZ2FjeSBTQVgxIGFwcGxpY2F0aW9ucy48L3A+Ci0gKgotICogPHA+VGhlIG9yZGVyIG9mIGV2ZW50cyBpbiB0aGlzIGludGVyZmFjZSBpcyB2ZXJ5IGltcG9ydGFudCwgYW5kCi0gKiBtaXJyb3JzIHRoZSBvcmRlciBvZiBpbmZvcm1hdGlvbiBpbiB0aGUgZG9jdW1lbnQgaXRzZWxmLiAgRm9yCi0gKiBleGFtcGxlLCBhbGwgb2YgYW4gZWxlbWVudCdzIGNvbnRlbnQgKGNoYXJhY3RlciBkYXRhLCBwcm9jZXNzaW5nCi0gKiBpbnN0cnVjdGlvbnMsIGFuZC9vciBzdWJlbGVtZW50cykgd2lsbCBhcHBlYXIsIGluIG9yZGVyLCBiZXR3ZWVuCi0gKiB0aGUgc3RhcnRFbGVtZW50IGV2ZW50IGFuZCB0aGUgY29ycmVzcG9uZGluZyBlbmRFbGVtZW50IGV2ZW50LjwvcD4KLSAqCi0gKiA8cD5BcHBsaWNhdGlvbiB3cml0ZXJzIHdobyBkbyBub3Qgd2FudCB0byBpbXBsZW1lbnQgdGhlIGVudGlyZQotICogaW50ZXJmYWNlIGNhbiBkZXJpdmUgYSBjbGFzcyBmcm9tIEhhbmRsZXJCYXNlLCB3aGljaCBpbXBsZW1lbnRzCi0gKiB0aGUgZGVmYXVsdCBmdW5jdGlvbmFsaXR5OyBwYXJzZXIgd3JpdGVycyBjYW4gaW5zdGFudGlhdGUKLSAqIEhhbmRsZXJCYXNlIHRvIG9idGFpbiBhIGRlZmF1bHQgaGFuZGxlci4gIFRoZSBhcHBsaWNhdGlvbiBjYW4gZmluZAotICogdGhlIGxvY2F0aW9uIG9mIGFueSBkb2N1bWVudCBldmVudCB1c2luZyB0aGUgTG9jYXRvciBpbnRlcmZhY2UKLSAqIHN1cHBsaWVkIGJ5IHRoZSBQYXJzZXIgdGhyb3VnaCB0aGUgc2V0RG9jdW1lbnRMb2NhdG9yIG1ldGhvZC48L3A+Ci0gKgotICogQGRlcHJlY2F0ZWQgVGhpcyBpbnRlcmZhY2UgaGFzIGJlZW4gcmVwbGFjZWQgYnkgdGhlIFNBWDIKLSAqICAgICAgICAgICAgIHtAbGluayBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciBDb250ZW50SGFuZGxlcn0KLSAqICAgICAgICAgICAgIGludGVyZmFjZSwgd2hpY2ggaW5jbHVkZXMgTmFtZXNwYWNlIHN1cHBvcnQuCi0gKiBAc2luY2UgU0FYIDEuMAotICogQGF1dGhvciBEYXZpZCBNZWdnaW5zb24KLSAqIEBzZWUgb3JnLnhtbC5zYXguUGFyc2VyI3NldERvY3VtZW50SGFuZGxlcgotICogQHNlZSBvcmcueG1sLnNheC5Mb2NhdG9yCi0gKiBAc2VlIG9yZy54bWwuc2F4LkhhbmRsZXJCYXNlCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgRG9jdW1lbnRIYW5kbGVyIHsKLQotCi0gICAgLyoqCi0gICAgICogUmVjZWl2ZSBhbiBvYmplY3QgZm9yIGxvY2F0aW5nIHRoZSBvcmlnaW4gb2YgU0FYIGRvY3VtZW50IGV2ZW50cy4KLSAgICAgKgotICAgICAqIDxwPlNBWCBwYXJzZXJzIGFyZSBzdHJvbmdseSBlbmNvdXJhZ2VkICh0aG91Z2ggbm90IGFic29sdXRlbHkKLSAgICAgKiByZXF1aXJlZCkgdG8gc3VwcGx5IGEgbG9jYXRvcjogaWYgaXQgZG9lcyBzbywgaXQgbXVzdCBzdXBwbHkKLSAgICAgKiB0aGUgbG9jYXRvciB0byB0aGUgYXBwbGljYXRpb24gYnkgaW52b2tpbmcgdGhpcyBtZXRob2QgYmVmb3JlCi0gICAgICogaW52b2tpbmcgYW55IG9mIHRoZSBvdGhlciBtZXRob2RzIGluIHRoZSBEb2N1bWVudEhhbmRsZXIKLSAgICAgKiBpbnRlcmZhY2UuPC9wPgotICAgICAqCi0gICAgICogPHA+VGhlIGxvY2F0b3IgYWxsb3dzIHRoZSBhcHBsaWNhdGlvbiB0byBkZXRlcm1pbmUgdGhlIGVuZAotICAgICAqIHBvc2l0aW9uIG9mIGFueSBkb2N1bWVudC1yZWxhdGVkIGV2ZW50LCBldmVuIGlmIHRoZSBwYXJzZXIgaXMKLSAgICAgKiBub3QgcmVwb3J0aW5nIGFuIGVycm9yLiAgVHlwaWNhbGx5LCB0aGUgYXBwbGljYXRpb24gd2lsbAotICAgICAqIHVzZSB0aGlzIGluZm9ybWF0aW9uIGZvciByZXBvcnRpbmcgaXRzIG93biBlcnJvcnMgKHN1Y2ggYXMKLSAgICAgKiBjaGFyYWN0ZXIgY29udGVudCB0aGF0IGRvZXMgbm90IG1hdGNoIGFuIGFwcGxpY2F0aW9uJ3MKLSAgICAgKiBidXNpbmVzcyBydWxlcykuICBUaGUgaW5mb3JtYXRpb24gcmV0dXJuZWQgYnkgdGhlIGxvY2F0b3IKLSAgICAgKiBpcyBwcm9iYWJseSBub3Qgc3VmZmljaWVudCBmb3IgdXNlIHdpdGggYSBzZWFyY2ggZW5naW5lLjwvcD4KLSAgICAgKgotICAgICAqIDxwPk5vdGUgdGhhdCB0aGUgbG9jYXRvciB3aWxsIHJldHVybiBjb3JyZWN0IGluZm9ybWF0aW9uIG9ubHkKLSAgICAgKiBkdXJpbmcgdGhlIGludm9jYXRpb24gb2YgdGhlIGV2ZW50cyBpbiB0aGlzIGludGVyZmFjZS4gIFRoZQotICAgICAqIGFwcGxpY2F0aW9uIHNob3VsZCBub3QgYXR0ZW1wdCB0byB1c2UgaXQgYXQgYW55IG90aGVyIHRpbWUuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGxvY2F0b3IgQW4gb2JqZWN0IHRoYXQgY2FuIHJldHVybiB0aGUgbG9jYXRpb24gb2YKLSAgICAgKiAgICAgICAgICAgICAgICBhbnkgU0FYIGRvY3VtZW50IGV2ZW50LgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguTG9jYXRvcgotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHNldERvY3VtZW50TG9jYXRvciAoTG9jYXRvciBsb2NhdG9yKTsKLQotCi0gICAgLyoqCi0gICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIGJlZ2lubmluZyBvZiBhIGRvY3VtZW50LgotICAgICAqCi0gICAgICogPHA+VGhlIFNBWCBwYXJzZXIgd2lsbCBpbnZva2UgdGhpcyBtZXRob2Qgb25seSBvbmNlLCBiZWZvcmUgYW55Ci0gICAgICogb3RoZXIgbWV0aG9kcyBpbiB0aGlzIGludGVyZmFjZSBvciBpbiBEVERIYW5kbGVyIChleGNlcHQgZm9yCi0gICAgICogc2V0RG9jdW1lbnRMb2NhdG9yKS48L3A+Ci0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHN0YXJ0RG9jdW1lbnQgKCkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbjsKLQotCi0gICAgLyoqCi0gICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIGVuZCBvZiBhIGRvY3VtZW50LgotICAgICAqCi0gICAgICogPHA+VGhlIFNBWCBwYXJzZXIgd2lsbCBpbnZva2UgdGhpcyBtZXRob2Qgb25seSBvbmNlLCBhbmQgaXQgd2lsbAotICAgICAqIGJlIHRoZSBsYXN0IG1ldGhvZCBpbnZva2VkIGR1cmluZyB0aGUgcGFyc2UuICBUaGUgcGFyc2VyIHNoYWxsCi0gICAgICogbm90IGludm9rZSB0aGlzIG1ldGhvZCB1bnRpbCBpdCBoYXMgZWl0aGVyIGFiYW5kb25lZCBwYXJzaW5nCi0gICAgICogKGJlY2F1c2Ugb2YgYW4gdW5yZWNvdmVyYWJsZSBlcnJvcikgb3IgcmVhY2hlZCB0aGUgZW5kIG9mCi0gICAgICogaW5wdXQuPC9wPgotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBlbmREb2N1bWVudCAoKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uOwotCi0KLSAgICAvKioKLSAgICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiB0aGUgYmVnaW5uaW5nIG9mIGFuIGVsZW1lbnQuCi0gICAgICoKLSAgICAgKiA8cD5UaGUgUGFyc2VyIHdpbGwgaW52b2tlIHRoaXMgbWV0aG9kIGF0IHRoZSBiZWdpbm5pbmcgb2YgZXZlcnkKLSAgICAgKiBlbGVtZW50IGluIHRoZSBYTUwgZG9jdW1lbnQ7IHRoZXJlIHdpbGwgYmUgYSBjb3JyZXNwb25kaW5nCi0gICAgICogZW5kRWxlbWVudCgpIGV2ZW50IGZvciBldmVyeSBzdGFydEVsZW1lbnQoKSBldmVudCAoZXZlbiB3aGVuIHRoZQotICAgICAqIGVsZW1lbnQgaXMgZW1wdHkpLiBBbGwgb2YgdGhlIGVsZW1lbnQncyBjb250ZW50IHdpbGwgYmUKLSAgICAgKiByZXBvcnRlZCwgaW4gb3JkZXIsIGJlZm9yZSB0aGUgY29ycmVzcG9uZGluZyBlbmRFbGVtZW50KCkKLSAgICAgKiBldmVudC48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5JZiB0aGUgZWxlbWVudCBuYW1lIGhhcyBhIG5hbWVzcGFjZSBwcmVmaXgsIHRoZSBwcmVmaXggd2lsbAotICAgICAqIHN0aWxsIGJlIGF0dGFjaGVkLiAgTm90ZSB0aGF0IHRoZSBhdHRyaWJ1dGUgbGlzdCBwcm92aWRlZCB3aWxsCi0gICAgICogY29udGFpbiBvbmx5IGF0dHJpYnV0ZXMgd2l0aCBleHBsaWNpdCB2YWx1ZXMgKHNwZWNpZmllZCBvcgotICAgICAqIGRlZmF1bHRlZCk6ICNJTVBMSUVEIGF0dHJpYnV0ZXMgd2lsbCBiZSBvbWl0dGVkLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBlbGVtZW50IHR5cGUgbmFtZS4KLSAgICAgKiBAcGFyYW0gYXR0cyBUaGUgYXR0cmlidXRlcyBhdHRhY2hlZCB0byB0aGUgZWxlbWVudCwgaWYgYW55LgotICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAgICogQHNlZSAjZW5kRWxlbWVudAotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQXR0cmlidXRlTGlzdAotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHN0YXJ0RWxlbWVudCAoU3RyaW5nIG5hbWUsIEF0dHJpYnV0ZUxpc3QgYXR0cykKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbjsKLQotCi0gICAgLyoqCi0gICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIGVuZCBvZiBhbiBlbGVtZW50LgotICAgICAqCi0gICAgICogPHA+VGhlIFNBWCBwYXJzZXIgd2lsbCBpbnZva2UgdGhpcyBtZXRob2QgYXQgdGhlIGVuZCBvZiBldmVyeQotICAgICAqIGVsZW1lbnQgaW4gdGhlIFhNTCBkb2N1bWVudDsgdGhlcmUgd2lsbCBiZSBhIGNvcnJlc3BvbmRpbmcKLSAgICAgKiBzdGFydEVsZW1lbnQoKSBldmVudCBmb3IgZXZlcnkgZW5kRWxlbWVudCgpIGV2ZW50IChldmVuIHdoZW4gdGhlCi0gICAgICogZWxlbWVudCBpcyBlbXB0eSkuPC9wPgotICAgICAqCi0gICAgICogPHA+SWYgdGhlIGVsZW1lbnQgbmFtZSBoYXMgYSBuYW1lc3BhY2UgcHJlZml4LCB0aGUgcHJlZml4IHdpbGwKLSAgICAgKiBzdGlsbCBiZSBhdHRhY2hlZCB0byB0aGUgbmFtZS48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgZWxlbWVudCB0eXBlIG5hbWUKLSAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIGVuZEVsZW1lbnQgKFN0cmluZyBuYW1lKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uOwotCi0KLSAgICAvKioKLSAgICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBjaGFyYWN0ZXIgZGF0YS4KLSAgICAgKgotICAgICAqIDxwPlRoZSBQYXJzZXIgd2lsbCBjYWxsIHRoaXMgbWV0aG9kIHRvIHJlcG9ydCBlYWNoIGNodW5rIG9mCi0gICAgICogY2hhcmFjdGVyIGRhdGEuICBTQVggcGFyc2VycyBtYXkgcmV0dXJuIGFsbCBjb250aWd1b3VzIGNoYXJhY3RlcgotICAgICAqIGRhdGEgaW4gYSBzaW5nbGUgY2h1bmssIG9yIHRoZXkgbWF5IHNwbGl0IGl0IGludG8gc2V2ZXJhbAotICAgICAqIGNodW5rczsgaG93ZXZlciwgYWxsIG9mIHRoZSBjaGFyYWN0ZXJzIGluIGFueSBzaW5nbGUgZXZlbnQKLSAgICAgKiBtdXN0IGNvbWUgZnJvbSB0aGUgc2FtZSBleHRlcm5hbCBlbnRpdHksIHNvIHRoYXQgdGhlIExvY2F0b3IKLSAgICAgKiBwcm92aWRlcyB1c2VmdWwgaW5mb3JtYXRpb24uPC9wPgotICAgICAqCi0gICAgICogPHA+VGhlIGFwcGxpY2F0aW9uIG11c3Qgbm90IGF0dGVtcHQgdG8gcmVhZCBmcm9tIHRoZSBhcnJheQotICAgICAqIG91dHNpZGUgb2YgdGhlIHNwZWNpZmllZCByYW5nZS48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5Ob3RlIHRoYXQgc29tZSBwYXJzZXJzIHdpbGwgcmVwb3J0IHdoaXRlc3BhY2UgdXNpbmcgdGhlCi0gICAgICogaWdub3JhYmxlV2hpdGVzcGFjZSgpIG1ldGhvZCByYXRoZXIgdGhhbiB0aGlzIG9uZSAodmFsaWRhdGluZwotICAgICAqIHBhcnNlcnMgbXVzdCBkbyBzbykuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGNoIFRoZSBjaGFyYWN0ZXJzIGZyb20gdGhlIFhNTCBkb2N1bWVudC4KLSAgICAgKiBAcGFyYW0gc3RhcnQgVGhlIHN0YXJ0IHBvc2l0aW9uIGluIHRoZSBhcnJheS4KLSAgICAgKiBAcGFyYW0gbGVuZ3RoIFRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyB0byByZWFkIGZyb20gdGhlIGFycmF5LgotICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAgICogQHNlZSAjaWdub3JhYmxlV2hpdGVzcGFjZQotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguTG9jYXRvcgotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIGNoYXJhY3RlcnMgKGNoYXIgY2hbXSwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uOwotCi0KLSAgICAvKioKLSAgICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBpZ25vcmFibGUgd2hpdGVzcGFjZSBpbiBlbGVtZW50IGNvbnRlbnQuCi0gICAgICoKLSAgICAgKiA8cD5WYWxpZGF0aW5nIFBhcnNlcnMgbXVzdCB1c2UgdGhpcyBtZXRob2QgdG8gcmVwb3J0IGVhY2ggY2h1bmsKLSAgICAgKiBvZiBpZ25vcmFibGUgd2hpdGVzcGFjZSAoc2VlIHRoZSBXM0MgWE1MIDEuMCByZWNvbW1lbmRhdGlvbiwKLSAgICAgKiBzZWN0aW9uIDIuMTApOiBub24tdmFsaWRhdGluZyBwYXJzZXJzIG1heSBhbHNvIHVzZSB0aGlzIG1ldGhvZAotICAgICAqIGlmIHRoZXkgYXJlIGNhcGFibGUgb2YgcGFyc2luZyBhbmQgdXNpbmcgY29udGVudCBtb2RlbHMuPC9wPgotICAgICAqCi0gICAgICogPHA+U0FYIHBhcnNlcnMgbWF5IHJldHVybiBhbGwgY29udGlndW91cyB3aGl0ZXNwYWNlIGluIGEgc2luZ2xlCi0gICAgICogY2h1bmssIG9yIHRoZXkgbWF5IHNwbGl0IGl0IGludG8gc2V2ZXJhbCBjaHVua3M7IGhvd2V2ZXIsIGFsbCBvZgotICAgICAqIHRoZSBjaGFyYWN0ZXJzIGluIGFueSBzaW5nbGUgZXZlbnQgbXVzdCBjb21lIGZyb20gdGhlIHNhbWUKLSAgICAgKiBleHRlcm5hbCBlbnRpdHksIHNvIHRoYXQgdGhlIExvY2F0b3IgcHJvdmlkZXMgdXNlZnVsCi0gICAgICogaW5mb3JtYXRpb24uPC9wPgotICAgICAqCi0gICAgICogPHA+VGhlIGFwcGxpY2F0aW9uIG11c3Qgbm90IGF0dGVtcHQgdG8gcmVhZCBmcm9tIHRoZSBhcnJheQotICAgICAqIG91dHNpZGUgb2YgdGhlIHNwZWNpZmllZCByYW5nZS48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gY2ggVGhlIGNoYXJhY3RlcnMgZnJvbSB0aGUgWE1MIGRvY3VtZW50LgotICAgICAqIEBwYXJhbSBzdGFydCBUaGUgc3RhcnQgcG9zaXRpb24gaW4gdGhlIGFycmF5LgotICAgICAqIEBwYXJhbSBsZW5ndGggVGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHJlYWQgZnJvbSB0aGUgYXJyYXkuCi0gICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICAgKiBAc2VlICNjaGFyYWN0ZXJzCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IHZvaWQgaWdub3JhYmxlV2hpdGVzcGFjZSAoY2hhciBjaFtdLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb247Ci0KLQotICAgIC8qKgotICAgICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGEgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbi4KLSAgICAgKgotICAgICAqIDxwPlRoZSBQYXJzZXIgd2lsbCBpbnZva2UgdGhpcyBtZXRob2Qgb25jZSBmb3IgZWFjaCBwcm9jZXNzaW5nCi0gICAgICogaW5zdHJ1Y3Rpb24gZm91bmQ6IG5vdGUgdGhhdCBwcm9jZXNzaW5nIGluc3RydWN0aW9ucyBtYXkgb2NjdXIKLSAgICAgKiBiZWZvcmUgb3IgYWZ0ZXIgdGhlIG1haW4gZG9jdW1lbnQgZWxlbWVudC48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5BIFNBWCBwYXJzZXIgc2hvdWxkIG5ldmVyIHJlcG9ydCBhbiBYTUwgZGVjbGFyYXRpb24gKFhNTCAxLjAsCi0gICAgICogc2VjdGlvbiAyLjgpIG9yIGEgdGV4dCBkZWNsYXJhdGlvbiAoWE1MIDEuMCwgc2VjdGlvbiA0LjMuMSkKLSAgICAgKiB1c2luZyB0aGlzIG1ldGhvZC48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gdGFyZ2V0IFRoZSBwcm9jZXNzaW5nIGluc3RydWN0aW9uIHRhcmdldC4KLSAgICAgKiBAcGFyYW0gZGF0YSBUaGUgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiBkYXRhLCBvciBudWxsIGlmCi0gICAgICogICAgICAgIG5vbmUgd2FzIHN1cHBsaWVkLgotICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IHZvaWQgcHJvY2Vzc2luZ0luc3RydWN0aW9uIChTdHJpbmcgdGFyZ2V0LCBTdHJpbmcgZGF0YSkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbjsKLQotfQotCi0vLyBlbmQgb2YgRG9jdW1lbnRIYW5kbGVyLmphdmEKZGlmZiAtLWdpdCBhL3NyYy9vcmcveG1sL3NheC9FbnRpdHlSZXNvbHZlci5qYXZhIGIvc3JjL29yZy94bWwvc2F4L0VudGl0eVJlc29sdmVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDZmOGM1MDEuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy94bWwvc2F4L0VudGl0eVJlc29sdmVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNDMgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwMCwgMjAwNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLy8gU0FYIGVudGl0eSByZXNvbHZlci4KLS8vIGh0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmcKLS8vIE5vIHdhcnJhbnR5OyBubyBjb3B5cmlnaHQgLS0gdXNlIHRoaXMgYXMgeW91IHdpbGwuCi0vLyAkSWQ6IEVudGl0eVJlc29sdmVyLmphdmEsdiAxLjIgMjAwNC8xMS8wMyAyMjo0NDo1MiBqc3V0dG9yIEV4cCAkCi0KLXBhY2thZ2Ugb3JnLnhtbC5zYXg7Ci0KLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotCi0KLS8qKgotICogQmFzaWMgaW50ZXJmYWNlIGZvciByZXNvbHZpbmcgZW50aXRpZXMuCi0gKgotICogPGJsb2NrcXVvdGU+Ci0gKiA8ZW0+VGhpcyBtb2R1bGUsIGJvdGggc291cmNlIGNvZGUgYW5kIGRvY3VtZW50YXRpb24sIGlzIGluIHRoZQotICogUHVibGljIERvbWFpbiwgYW5kIGNvbWVzIHdpdGggPHN0cm9uZz5OTyBXQVJSQU5UWTwvc3Ryb25nPi48L2VtPgotICogU2VlIDxhIGhyZWY9J2h0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmcnPmh0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmc8L2E+Ci0gKiBmb3IgZnVydGhlciBpbmZvcm1hdGlvbi4KLSAqIDwvYmxvY2txdW90ZT4KLSAqCi0gKiA8cD5JZiBhIFNBWCBhcHBsaWNhdGlvbiBuZWVkcyB0byBpbXBsZW1lbnQgY3VzdG9taXplZCBoYW5kbGluZwotICogZm9yIGV4dGVybmFsIGVudGl0aWVzLCBpdCBtdXN0IGltcGxlbWVudCB0aGlzIGludGVyZmFjZSBhbmQKLSAqIHJlZ2lzdGVyIGFuIGluc3RhbmNlIHdpdGggdGhlIFNBWCBkcml2ZXIgdXNpbmcgdGhlCi0gKiB7QGxpbmsgb3JnLnhtbC5zYXguWE1MUmVhZGVyI3NldEVudGl0eVJlc29sdmVyIHNldEVudGl0eVJlc29sdmVyfQotICogbWV0aG9kLjwvcD4KLSAqCi0gKiA8cD5UaGUgWE1MIHJlYWRlciB3aWxsIHRoZW4gYWxsb3cgdGhlIGFwcGxpY2F0aW9uIHRvIGludGVyY2VwdCBhbnkKLSAqIGV4dGVybmFsIGVudGl0aWVzIChpbmNsdWRpbmcgdGhlIGV4dGVybmFsIERURCBzdWJzZXQgYW5kIGV4dGVybmFsCi0gKiBwYXJhbWV0ZXIgZW50aXRpZXMsIGlmIGFueSkgYmVmb3JlIGluY2x1ZGluZyB0aGVtLjwvcD4KLSAqCi0gKiA8cD5NYW55IFNBWCBhcHBsaWNhdGlvbnMgd2lsbCBub3QgbmVlZCB0byBpbXBsZW1lbnQgdGhpcyBpbnRlcmZhY2UsCi0gKiBidXQgaXQgd2lsbCBiZSBlc3BlY2lhbGx5IHVzZWZ1bCBmb3IgYXBwbGljYXRpb25zIHRoYXQgYnVpbGQKLSAqIFhNTCBkb2N1bWVudHMgZnJvbSBkYXRhYmFzZXMgb3Igb3RoZXIgc3BlY2lhbGlzZWQgaW5wdXQgc291cmNlcywKLSAqIG9yIGZvciBhcHBsaWNhdGlvbnMgdGhhdCB1c2UgVVJJIHR5cGVzIG90aGVyIHRoYW4gVVJMcy48L3A+Ci0gKgotICogPHA+VGhlIGZvbGxvd2luZyByZXNvbHZlciB3b3VsZCBwcm92aWRlIHRoZSBhcHBsaWNhdGlvbgotICogd2l0aCBhIHNwZWNpYWwgY2hhcmFjdGVyIHN0cmVhbSBmb3IgdGhlIGVudGl0eSB3aXRoIHRoZSBzeXN0ZW0KLSAqIGlkZW50aWZpZXIgImh0dHA6Ly93d3cubXlob3N0LmNvbS90b2RheSI6PC9wPgotICoKLSAqIDxwcmU+Ci0gKiBpbXBvcnQgb3JnLnhtbC5zYXguRW50aXR5UmVzb2x2ZXI7Ci0gKiBpbXBvcnQgb3JnLnhtbC5zYXguSW5wdXRTb3VyY2U7Ci0gKgotICogcHVibGljIGNsYXNzIE15UmVzb2x2ZXIgaW1wbGVtZW50cyBFbnRpdHlSZXNvbHZlciB7Ci0gKiAgIHB1YmxpYyBJbnB1dFNvdXJjZSByZXNvbHZlRW50aXR5IChTdHJpbmcgcHVibGljSWQsIFN0cmluZyBzeXN0ZW1JZCkKLSAqICAgewotICogICAgIGlmIChzeXN0ZW1JZC5lcXVhbHMoImh0dHA6Ly93d3cubXlob3N0LmNvbS90b2RheSIpKSB7Ci0gKiAgICAgICAgICAgICAgLy8gcmV0dXJuIGEgc3BlY2lhbCBpbnB1dCBzb3VyY2UKLSAqICAgICAgIE15UmVhZGVyIHJlYWRlciA9IG5ldyBNeVJlYWRlcigpOwotICogICAgICAgcmV0dXJuIG5ldyBJbnB1dFNvdXJjZShyZWFkZXIpOwotICogICAgIH0gZWxzZSB7Ci0gKiAgICAgICAgICAgICAgLy8gdXNlIHRoZSBkZWZhdWx0IGJlaGF2aW91cgotICogICAgICAgcmV0dXJuIG51bGw7Ci0gKiAgICAgfQotICogICB9Ci0gKiB9Ci0gKiA8L3ByZT4KLSAqCi0gKiA8cD5UaGUgYXBwbGljYXRpb24gY2FuIGFsc28gdXNlIHRoaXMgaW50ZXJmYWNlIHRvIHJlZGlyZWN0IHN5c3RlbQotICogaWRlbnRpZmllcnMgdG8gbG9jYWwgVVJJcyBvciB0byBsb29rIHVwIHJlcGxhY2VtZW50cyBpbiBhIGNhdGFsb2cKLSAqIChwb3NzaWJseSBieSB1c2luZyB0aGUgcHVibGljIGlkZW50aWZpZXIpLjwvcD4KLSAqCi0gKiBAc2luY2UgU0FYIDEuMAotICogQGF1dGhvciBEYXZpZCBNZWdnaW5zb24KLSAqIEBzZWUgb3JnLnhtbC5zYXguWE1MUmVhZGVyI3NldEVudGl0eVJlc29sdmVyCi0gKiBAc2VlIG9yZy54bWwuc2F4LklucHV0U291cmNlCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgRW50aXR5UmVzb2x2ZXIgewotCi0KLSAgICAvKioKLSAgICAgKiBBbGxvdyB0aGUgYXBwbGljYXRpb24gdG8gcmVzb2x2ZSBleHRlcm5hbCBlbnRpdGllcy4KLSAgICAgKgotICAgICAqIDxwPlRoZSBwYXJzZXIgd2lsbCBjYWxsIHRoaXMgbWV0aG9kIGJlZm9yZSBvcGVuaW5nIGFueSBleHRlcm5hbAotICAgICAqIGVudGl0eSBleGNlcHQgdGhlIHRvcC1sZXZlbCBkb2N1bWVudCBlbnRpdHkuICBTdWNoIGVudGl0aWVzIGluY2x1ZGUKLSAgICAgKiB0aGUgZXh0ZXJuYWwgRFREIHN1YnNldCBhbmQgZXh0ZXJuYWwgcGFyYW1ldGVyIGVudGl0aWVzIHJlZmVyZW5jZWQKLSAgICAgKiB3aXRoaW4gdGhlIERURCAoaW4gZWl0aGVyIGNhc2UsIG9ubHkgaWYgdGhlIHBhcnNlciByZWFkcyBleHRlcm5hbAotICAgICAqIHBhcmFtZXRlciBlbnRpdGllcyksIGFuZCBleHRlcm5hbCBnZW5lcmFsIGVudGl0aWVzIHJlZmVyZW5jZWQKLSAgICAgKiB3aXRoaW4gdGhlIGRvY3VtZW50IGVsZW1lbnQgKGlmIHRoZSBwYXJzZXIgcmVhZHMgZXh0ZXJuYWwgZ2VuZXJhbAotICAgICAqIGVudGl0aWVzKS4gIFRoZSBhcHBsaWNhdGlvbiBtYXkgcmVxdWVzdCB0aGF0IHRoZSBwYXJzZXIgbG9jYXRlCi0gICAgICogdGhlIGVudGl0eSBpdHNlbGYsIHRoYXQgaXQgdXNlIGFuIGFsdGVybmF0aXZlIFVSSSwgb3IgdGhhdCBpdAotICAgICAqIHVzZSBkYXRhIHByb3ZpZGVkIGJ5IHRoZSBhcHBsaWNhdGlvbiAoYXMgYSBjaGFyYWN0ZXIgb3IgYnl0ZQotICAgICAqIGlucHV0IHN0cmVhbSkuPC9wPgotICAgICAqCi0gICAgICogPHA+QXBwbGljYXRpb24gd3JpdGVycyBjYW4gdXNlIHRoaXMgbWV0aG9kIHRvIHJlZGlyZWN0IGV4dGVybmFsCi0gICAgICogc3lzdGVtIGlkZW50aWZpZXJzIHRvIHNlY3VyZSBhbmQvb3IgbG9jYWwgVVJJcywgdG8gbG9vayB1cAotICAgICAqIHB1YmxpYyBpZGVudGlmaWVycyBpbiBhIGNhdGFsb2d1ZSwgb3IgdG8gcmVhZCBhbiBlbnRpdHkgZnJvbSBhCi0gICAgICogZGF0YWJhc2Ugb3Igb3RoZXIgaW5wdXQgc291cmNlIChpbmNsdWRpbmcsIGZvciBleGFtcGxlLCBhIGRpYWxvZwotICAgICAqIGJveCkuICBOZWl0aGVyIFhNTCBub3IgU0FYIHNwZWNpZmllcyBhIHByZWZlcnJlZCBwb2xpY3kgZm9yIHVzaW5nCi0gICAgICogcHVibGljIG9yIHN5c3RlbSBJRHMgdG8gcmVzb2x2ZSByZXNvdXJjZXMuICBIb3dldmVyLCBTQVggc3BlY2lmaWVzCi0gICAgICogaG93IHRvIGludGVycHJldCBhbnkgSW5wdXRTb3VyY2UgcmV0dXJuZWQgYnkgdGhpcyBtZXRob2QsIGFuZCB0aGF0Ci0gICAgICogaWYgbm9uZSBpcyByZXR1cm5lZCwgdGhlbiB0aGUgc3lzdGVtIElEIHdpbGwgYmUgZGVyZWZlcmVuY2VkIGFzCi0gICAgICogYSBVUkwuICA8L3A+Ci0gICAgICoKLSAgICAgKiA8cD5JZiB0aGUgc3lzdGVtIGlkZW50aWZpZXIgaXMgYSBVUkwsIHRoZSBTQVggcGFyc2VyIG11c3QKLSAgICAgKiByZXNvbHZlIGl0IGZ1bGx5IGJlZm9yZSByZXBvcnRpbmcgaXQgdG8gdGhlIGFwcGxpY2F0aW9uLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBwdWJsaWNJZCBUaGUgcHVibGljIGlkZW50aWZpZXIgb2YgdGhlIGV4dGVybmFsIGVudGl0eQotICAgICAqICAgICAgICBiZWluZyByZWZlcmVuY2VkLCBvciBudWxsIGlmIG5vbmUgd2FzIHN1cHBsaWVkLgotICAgICAqIEBwYXJhbSBzeXN0ZW1JZCBUaGUgc3lzdGVtIGlkZW50aWZpZXIgb2YgdGhlIGV4dGVybmFsIGVudGl0eQotICAgICAqICAgICAgICBiZWluZyByZWZlcmVuY2VkLgotICAgICAqIEByZXR1cm4gQW4gSW5wdXRTb3VyY2Ugb2JqZWN0IGRlc2NyaWJpbmcgdGhlIG5ldyBpbnB1dCBzb3VyY2UsCi0gICAgICogICAgICAgICBvciBudWxsIHRvIHJlcXVlc3QgdGhhdCB0aGUgcGFyc2VyIG9wZW4gYSByZWd1bGFyCi0gICAgICogICAgICAgICBVUkkgY29ubmVjdGlvbiB0byB0aGUgc3lzdGVtIGlkZW50aWZpZXIuCi0gICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICAgKiBAZXhjZXB0aW9uIGphdmEuaW8uSU9FeGNlcHRpb24gQSBKYXZhLXNwZWNpZmljIElPIGV4Y2VwdGlvbiwKLSAgICAgKiAgICAgICAgICAgIHBvc3NpYmx5IHRoZSByZXN1bHQgb2YgY3JlYXRpbmcgYSBuZXcgSW5wdXRTdHJlYW0KLSAgICAgKiAgICAgICAgICAgIG9yIFJlYWRlciBmb3IgdGhlIElucHV0U291cmNlLgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguSW5wdXRTb3VyY2UKLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3QgSW5wdXRTb3VyY2UgcmVzb2x2ZUVudGl0eSAoU3RyaW5nIHB1YmxpY0lkLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgc3lzdGVtSWQpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24sIElPRXhjZXB0aW9uOwotCi19Ci0KLS8vIGVuZCBvZiBFbnRpdHlSZXNvbHZlci5qYXZhCmRpZmYgLS1naXQgYS9zcmMvb3JnL3htbC9zYXgvRXJyb3JIYW5kbGVyLmphdmEgYi9zcmMvb3JnL3htbC9zYXgvRXJyb3JIYW5kbGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDExODMzODIuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy94bWwvc2F4L0Vycm9ySGFuZGxlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTYzICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDAsIDIwMDUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8vIFNBWCBlcnJvciBoYW5kbGVyLgotLy8gaHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZwotLy8gTm8gd2FycmFudHk7IG5vIGNvcHlyaWdodCAtLSB1c2UgdGhpcyBhcyB5b3Ugd2lsbC4KLS8vICRJZDogRXJyb3JIYW5kbGVyLmphdmEsdiAxLjIgMjAwNC8xMS8wMyAyMjo0NDo1MiBqc3V0dG9yIEV4cCAkCi0KLXBhY2thZ2Ugb3JnLnhtbC5zYXg7Ci0KLQotLyoqCi0gKiBCYXNpYyBpbnRlcmZhY2UgZm9yIFNBWCBlcnJvciBoYW5kbGVycy4KLSAqCi0gKiA8YmxvY2txdW90ZT4KLSAqIDxlbT5UaGlzIG1vZHVsZSwgYm90aCBzb3VyY2UgY29kZSBhbmQgZG9jdW1lbnRhdGlvbiwgaXMgaW4gdGhlCi0gKiBQdWJsaWMgRG9tYWluLCBhbmQgY29tZXMgd2l0aCA8c3Ryb25nPk5PIFdBUlJBTlRZPC9zdHJvbmc+LjwvZW0+Ci0gKiBTZWUgPGEgaHJlZj0naHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZyc+aHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZzwvYT4KLSAqIGZvciBmdXJ0aGVyIGluZm9ybWF0aW9uLgotICogPC9ibG9ja3F1b3RlPgotICoKLSAqIDxwPklmIGEgU0FYIGFwcGxpY2F0aW9uIG5lZWRzIHRvIGltcGxlbWVudCBjdXN0b21pemVkIGVycm9yCi0gKiBoYW5kbGluZywgaXQgbXVzdCBpbXBsZW1lbnQgdGhpcyBpbnRlcmZhY2UgYW5kIHRoZW4gcmVnaXN0ZXIgYW4KLSAqIGluc3RhbmNlIHdpdGggdGhlIFhNTCByZWFkZXIgdXNpbmcgdGhlCi0gKiB7QGxpbmsgb3JnLnhtbC5zYXguWE1MUmVhZGVyI3NldEVycm9ySGFuZGxlciBzZXRFcnJvckhhbmRsZXJ9Ci0gKiBtZXRob2QuICBUaGUgcGFyc2VyIHdpbGwgdGhlbiByZXBvcnQgYWxsIGVycm9ycyBhbmQgd2FybmluZ3MKLSAqIHRocm91Z2ggdGhpcyBpbnRlcmZhY2UuPC9wPgotICoKLSAqIDxwPjxzdHJvbmc+V0FSTklORzo8L3N0cm9uZz4gSWYgYW4gYXBwbGljYXRpb24gZG9lcyA8ZW0+bm90PC9lbT4KLSAqIHJlZ2lzdGVyIGFuIEVycm9ySGFuZGxlciwgWE1MIHBhcnNpbmcgZXJyb3JzIHdpbGwgZ28gdW5yZXBvcnRlZCwKLSAqIGV4Y2VwdCB0aGF0IDxlbT5TQVhQYXJzZUV4Y2VwdGlvbjwvZW0+cyB3aWxsIGJlIHRocm93biBmb3IgZmF0YWwgZXJyb3JzLgotICogSW4gb3JkZXIgdG8gZGV0ZWN0IHZhbGlkaXR5IGVycm9ycywgYW4gRXJyb3JIYW5kbGVyIHRoYXQgZG9lcyBzb21ldGhpbmcKLSAqIHdpdGgge0BsaW5rICNlcnJvciBlcnJvcigpfSBjYWxscyBtdXN0IGJlIHJlZ2lzdGVyZWQuPC9wPgotICoKLSAqIDxwPkZvciBYTUwgcHJvY2Vzc2luZyBlcnJvcnMsIGEgU0FYIGRyaXZlciBtdXN0IHVzZSB0aGlzIGludGVyZmFjZQotICogaW4gcHJlZmVyZW5jZSB0byB0aHJvd2luZyBhbiBleGNlcHRpb246IGl0IGlzIHVwIHRvIHRoZSBhcHBsaWNhdGlvbgotICogdG8gZGVjaWRlIHdoZXRoZXIgdG8gdGhyb3cgYW4gZXhjZXB0aW9uIGZvciBkaWZmZXJlbnQgdHlwZXMgb2YKLSAqIGVycm9ycyBhbmQgd2FybmluZ3MuICBOb3RlLCBob3dldmVyLCB0aGF0IHRoZXJlIGlzIG5vIHJlcXVpcmVtZW50IHRoYXQKLSAqIHRoZSBwYXJzZXIgY29udGludWUgdG8gcmVwb3J0IGFkZGl0aW9uYWwgZXJyb3JzIGFmdGVyIGEgY2FsbCB0bwotICoge0BsaW5rICNmYXRhbEVycm9yIGZhdGFsRXJyb3J9LiAgSW4gb3RoZXIgd29yZHMsIGEgU0FYIGRyaXZlciBjbGFzcwotICogbWF5IHRocm93IGFuIGV4Y2VwdGlvbiBhZnRlciByZXBvcnRpbmcgYW55IGZhdGFsRXJyb3IuCi0gKiBBbHNvIHBhcnNlcnMgbWF5IHRocm93IGFwcHJvcHJpYXRlIGV4Y2VwdGlvbnMgZm9yIG5vbi1YTUwgZXJyb3JzLgotICogRm9yIGV4YW1wbGUsIHtAbGluayBYTUxSZWFkZXIjcGFyc2UgWE1MUmVhZGVyLnBhcnNlKCl9IHdvdWxkIHRocm93Ci0gKiBhbiBJT0V4Y2VwdGlvbiBmb3IgZXJyb3JzIGFjY2Vzc2luZyBlbnRpdGllcyBvciB0aGUgZG9jdW1lbnQuPC9wPgotICoKLSAqIEBzaW5jZSBTQVggMS4wCi0gKiBAYXV0aG9yIERhdmlkIE1lZ2dpbnNvbgotICogQHNlZSBvcmcueG1sLnNheC5YTUxSZWFkZXIjc2V0RXJyb3JIYW5kbGVyCi0gKiBAc2VlIG9yZy54bWwuc2F4LlNBWFBhcnNlRXhjZXB0aW9uCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgRXJyb3JIYW5kbGVyIHsKLQotCi0gICAgLyoqCi0gICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgYSB3YXJuaW5nLgotICAgICAqCi0gICAgICogPHA+U0FYIHBhcnNlcnMgd2lsbCB1c2UgdGhpcyBtZXRob2QgdG8gcmVwb3J0IGNvbmRpdGlvbnMgdGhhdAotICAgICAqIGFyZSBub3QgZXJyb3JzIG9yIGZhdGFsIGVycm9ycyBhcyBkZWZpbmVkIGJ5IHRoZSBYTUwKLSAgICAgKiByZWNvbW1lbmRhdGlvbi4gIFRoZSBkZWZhdWx0IGJlaGF2aW91ciBpcyB0byB0YWtlIG5vCi0gICAgICogYWN0aW9uLjwvcD4KLSAgICAgKgotICAgICAqIDxwPlRoZSBTQVggcGFyc2VyIG11c3QgY29udGludWUgdG8gcHJvdmlkZSBub3JtYWwgcGFyc2luZyBldmVudHMKLSAgICAgKiBhZnRlciBpbnZva2luZyB0aGlzIG1ldGhvZDogaXQgc2hvdWxkIHN0aWxsIGJlIHBvc3NpYmxlIGZvciB0aGUKLSAgICAgKiBhcHBsaWNhdGlvbiB0byBwcm9jZXNzIHRoZSBkb2N1bWVudCB0aHJvdWdoIHRvIHRoZSBlbmQuPC9wPgotICAgICAqCi0gICAgICogPHA+RmlsdGVycyBtYXkgdXNlIHRoaXMgbWV0aG9kIHRvIHJlcG9ydCBvdGhlciwgbm9uLVhNTCB3YXJuaW5ncwotICAgICAqIGFzIHdlbGwuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGV4Y2VwdGlvbiBUaGUgd2FybmluZyBpbmZvcm1hdGlvbiBlbmNhcHN1bGF0ZWQgaW4gYQotICAgICAqICAgICAgICAgICAgICAgICAgU0FYIHBhcnNlIGV4Y2VwdGlvbi4KLSAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCB3YXJuaW5nIChTQVhQYXJzZUV4Y2VwdGlvbiBleGNlcHRpb24pCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb247Ci0KLQotICAgIC8qKgotICAgICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGEgcmVjb3ZlcmFibGUgZXJyb3IuCi0gICAgICoKLSAgICAgKiA8cD5UaGlzIGNvcnJlc3BvbmRzIHRvIHRoZSBkZWZpbml0aW9uIG9mICJlcnJvciIgaW4gc2VjdGlvbiAxLjIKLSAgICAgKiBvZiB0aGUgVzNDIFhNTCAxLjAgUmVjb21tZW5kYXRpb24uICBGb3IgZXhhbXBsZSwgYSB2YWxpZGF0aW5nCi0gICAgICogcGFyc2VyIHdvdWxkIHVzZSB0aGlzIGNhbGxiYWNrIHRvIHJlcG9ydCB0aGUgdmlvbGF0aW9uIG9mIGEKLSAgICAgKiB2YWxpZGl0eSBjb25zdHJhaW50LiAgVGhlIGRlZmF1bHQgYmVoYXZpb3VyIGlzIHRvIHRha2Ugbm8KLSAgICAgKiBhY3Rpb24uPC9wPgotICAgICAqCi0gICAgICogPHA+VGhlIFNBWCBwYXJzZXIgbXVzdCBjb250aW51ZSB0byBwcm92aWRlIG5vcm1hbCBwYXJzaW5nCi0gICAgICogZXZlbnRzIGFmdGVyIGludm9raW5nIHRoaXMgbWV0aG9kOiBpdCBzaG91bGQgc3RpbGwgYmUgcG9zc2libGUKLSAgICAgKiBmb3IgdGhlIGFwcGxpY2F0aW9uIHRvIHByb2Nlc3MgdGhlIGRvY3VtZW50IHRocm91Z2ggdG8gdGhlIGVuZC4KLSAgICAgKiBJZiB0aGUgYXBwbGljYXRpb24gY2Fubm90IGRvIHNvLCB0aGVuIHRoZSBwYXJzZXIgc2hvdWxkIHJlcG9ydAotICAgICAqIGEgZmF0YWwgZXJyb3IgZXZlbiBpZiB0aGUgWE1MIHJlY29tbWVuZGF0aW9uIGRvZXMgbm90IHJlcXVpcmUKLSAgICAgKiBpdCB0byBkbyBzby48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5GaWx0ZXJzIG1heSB1c2UgdGhpcyBtZXRob2QgdG8gcmVwb3J0IG90aGVyLCBub24tWE1MIGVycm9ycwotICAgICAqIGFzIHdlbGwuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGV4Y2VwdGlvbiBUaGUgZXJyb3IgaW5mb3JtYXRpb24gZW5jYXBzdWxhdGVkIGluIGEKLSAgICAgKiAgICAgICAgICAgICAgICAgIFNBWCBwYXJzZSBleGNlcHRpb24uCi0gICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LlNBWFBhcnNlRXhjZXB0aW9uCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IHZvaWQgZXJyb3IgKFNBWFBhcnNlRXhjZXB0aW9uIGV4Y2VwdGlvbikKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbjsKLQotCi0gICAgLyoqCi0gICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgYSBub24tcmVjb3ZlcmFibGUgZXJyb3IuCi0gICAgICoKLSAgICAgKiA8cD48c3Ryb25nPlRoZXJlIGlzIGFuIGFwcGFyZW50IGNvbnRyYWRpY3Rpb24gYmV0d2VlbiB0aGUKLSAgICAgKiBkb2N1bWVudGF0aW9uIGZvciB0aGlzIG1ldGhvZCBhbmQgdGhlIGRvY3VtZW50YXRpb24gZm9yIHtAbGluawotICAgICAqIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI2VuZERvY3VtZW50fS4gIFVudGlsIHRoaXMgYW1iaWd1aXR5Ci0gICAgICogaXMgcmVzb2x2ZWQgaW4gYSBmdXR1cmUgbWFqb3IgcmVsZWFzZSwgY2xpZW50cyBzaG91bGQgbWFrZSBubwotICAgICAqIGFzc3VtcHRpb25zIGFib3V0IHdoZXRoZXIgZW5kRG9jdW1lbnQoKSB3aWxsIG9yIHdpbGwgbm90IGJlCi0gICAgICogaW52b2tlZCB3aGVuIHRoZSBwYXJzZXIgaGFzIHJlcG9ydGVkIGEgZmF0YWxFcnJvcigpIG9yIHRocm93bgotICAgICAqIGFuIGV4Y2VwdGlvbi48L3N0cm9uZz48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5UaGlzIGNvcnJlc3BvbmRzIHRvIHRoZSBkZWZpbml0aW9uIG9mICJmYXRhbCBlcnJvciIgaW4KLSAgICAgKiBzZWN0aW9uIDEuMiBvZiB0aGUgVzNDIFhNTCAxLjAgUmVjb21tZW5kYXRpb24uICBGb3IgZXhhbXBsZSwgYQotICAgICAqIHBhcnNlciB3b3VsZCB1c2UgdGhpcyBjYWxsYmFjayB0byByZXBvcnQgdGhlIHZpb2xhdGlvbiBvZiBhCi0gICAgICogd2VsbC1mb3JtZWRuZXNzIGNvbnN0cmFpbnQuPC9wPgotICAgICAqCi0gICAgICogPHA+VGhlIGFwcGxpY2F0aW9uIG11c3QgYXNzdW1lIHRoYXQgdGhlIGRvY3VtZW50IGlzIHVudXNhYmxlCi0gICAgICogYWZ0ZXIgdGhlIHBhcnNlciBoYXMgaW52b2tlZCB0aGlzIG1ldGhvZCwgYW5kIHNob3VsZCBjb250aW51ZQotICAgICAqIChpZiBhdCBhbGwpIG9ubHkgZm9yIHRoZSBzYWtlIG9mIGNvbGxlY3RpbmcgYWRkaXRpb25hbCBlcnJvcgotICAgICAqIG1lc3NhZ2VzOiBpbiBmYWN0LCBTQVggcGFyc2VycyBhcmUgZnJlZSB0byBzdG9wIHJlcG9ydGluZyBhbnkKLSAgICAgKiBvdGhlciBldmVudHMgb25jZSB0aGlzIG1ldGhvZCBoYXMgYmVlbiBpbnZva2VkLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBleGNlcHRpb24gVGhlIGVycm9yIGluZm9ybWF0aW9uIGVuY2Fwc3VsYXRlZCBpbiBhCi0gICAgICogICAgICAgICAgICAgICAgICBTQVggcGFyc2UgZXhjZXB0aW9uLgotICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5TQVhQYXJzZUV4Y2VwdGlvbgotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIGZhdGFsRXJyb3IgKFNBWFBhcnNlRXhjZXB0aW9uIGV4Y2VwdGlvbikKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbjsKLQotfQotCi0vLyBlbmQgb2YgRXJyb3JIYW5kbGVyLmphdmEKZGlmZiAtLWdpdCBhL3NyYy9vcmcveG1sL3NheC9IYW5kbGVyQmFzZS5qYXZhIGIvc3JjL29yZy94bWwvc2F4L0hhbmRsZXJCYXNlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGRiMmU2NDYuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy94bWwvc2F4L0hhbmRsZXJCYXNlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzOTMgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwMCwgMjAwNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLy8gU0FYIGRlZmF1bHQgaGFuZGxlciBiYXNlIGNsYXNzLgotLy8gaHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZwotLy8gTm8gd2FycmFudHk7IG5vIGNvcHlyaWdodCAtLSB1c2UgdGhpcyBhcyB5b3Ugd2lsbC4KLS8vICRJZDogSGFuZGxlckJhc2UuamF2YSx2IDEuMiAyMDA1LzA2LzEwIDAzOjUwOjQ3IGplZmZzdXR0b3IgRXhwICQKLQotcGFja2FnZSBvcmcueG1sLnNheDsKLQotLyoqCi0gKiBEZWZhdWx0IGJhc2UgY2xhc3MgZm9yIGhhbmRsZXJzLgotICoKLSAqIDxibG9ja3F1b3RlPgotICogPGVtPlRoaXMgbW9kdWxlLCBib3RoIHNvdXJjZSBjb2RlIGFuZCBkb2N1bWVudGF0aW9uLCBpcyBpbiB0aGUKLSAqIFB1YmxpYyBEb21haW4sIGFuZCBjb21lcyB3aXRoIDxzdHJvbmc+Tk8gV0FSUkFOVFk8L3N0cm9uZz4uPC9lbT4KLSAqIFNlZSA8YSBocmVmPSdodHRwOi8vd3d3LnNheHByb2plY3Qub3JnJz5odHRwOi8vd3d3LnNheHByb2plY3Qub3JnPC9hPgotICogZm9yIGZ1cnRoZXIgaW5mb3JtYXRpb24uCi0gKiA8L2Jsb2NrcXVvdGU+Ci0gKgotICogPHA+VGhpcyBjbGFzcyBpbXBsZW1lbnRzIHRoZSBkZWZhdWx0IGJlaGF2aW91ciBmb3IgZm91ciBTQVgxCi0gKiBpbnRlcmZhY2VzOiBFbnRpdHlSZXNvbHZlciwgRFRESGFuZGxlciwgRG9jdW1lbnRIYW5kbGVyLAotICogYW5kIEVycm9ySGFuZGxlci4gIEl0IGlzIG5vdyBvYnNvbGV0ZSwgYnV0IGlzIGluY2x1ZGVkIGluIFNBWDIgdG8KLSAqIHN1cHBvcnQgbGVnYWN5IFNBWDEgYXBwbGljYXRpb25zLiAgU0FYMiBhcHBsaWNhdGlvbnMgc2hvdWxkIHVzZQotICogdGhlIHtAbGluayBvcmcueG1sLnNheC5oZWxwZXJzLkRlZmF1bHRIYW5kbGVyIERlZmF1bHRIYW5kbGVyfQotICogY2xhc3MgaW5zdGVhZC48L3A+Ci0gKgotICogPHA+QXBwbGljYXRpb24gd3JpdGVycyBjYW4gZXh0ZW5kIHRoaXMgY2xhc3Mgd2hlbiB0aGV5IG5lZWQgdG8KLSAqIGltcGxlbWVudCBvbmx5IHBhcnQgb2YgYW4gaW50ZXJmYWNlOyBwYXJzZXIgd3JpdGVycyBjYW4KLSAqIGluc3RhbnRpYXRlIHRoaXMgY2xhc3MgdG8gcHJvdmlkZSBkZWZhdWx0IGhhbmRsZXJzIHdoZW4gdGhlCi0gKiBhcHBsaWNhdGlvbiBoYXMgbm90IHN1cHBsaWVkIGl0cyBvd24uPC9wPgotICoKLSAqIDxwPk5vdGUgdGhhdCB0aGUgdXNlIG9mIHRoaXMgY2xhc3MgaXMgb3B0aW9uYWwuPC9wPgotICoKLSAqIEBkZXByZWNhdGVkIFRoaXMgY2xhc3Mgd29ya3Mgd2l0aCB0aGUgZGVwcmVjYXRlZAotICogICAgICAgICAgICAge0BsaW5rIG9yZy54bWwuc2F4LkRvY3VtZW50SGFuZGxlciBEb2N1bWVudEhhbmRsZXJ9Ci0gKiAgICAgICAgICAgICBpbnRlcmZhY2UuICBJdCBoYXMgYmVlbiByZXBsYWNlZCBieSB0aGUgU0FYMgotICogICAgICAgICAgICAge0BsaW5rIG9yZy54bWwuc2F4LmhlbHBlcnMuRGVmYXVsdEhhbmRsZXIgRGVmYXVsdEhhbmRsZXJ9Ci0gKiAgICAgICAgICAgICBjbGFzcy4KLSAqIEBzaW5jZSBTQVggMS4wCi0gKiBAYXV0aG9yIERhdmlkIE1lZ2dpbnNvbgotICogQHNlZSBvcmcueG1sLnNheC5FbnRpdHlSZXNvbHZlcgotICogQHNlZSBvcmcueG1sLnNheC5EVERIYW5kbGVyCi0gKiBAc2VlIG9yZy54bWwuc2F4LkRvY3VtZW50SGFuZGxlcgotICogQHNlZSBvcmcueG1sLnNheC5FcnJvckhhbmRsZXIKLSAqLwotcHVibGljIGNsYXNzIEhhbmRsZXJCYXNlCi0gICAgaW1wbGVtZW50cyBFbnRpdHlSZXNvbHZlciwgRFRESGFuZGxlciwgRG9jdW1lbnRIYW5kbGVyLCBFcnJvckhhbmRsZXIKLXsKLQotCi0gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLSAgICAvLyBEZWZhdWx0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBFbnRpdHlSZXNvbHZlciBpbnRlcmZhY2UuCi0gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLQotICAgIC8qKgotICAgICAqIFJlc29sdmUgYW4gZXh0ZXJuYWwgZW50aXR5LgotICAgICAqCi0gICAgICogPHA+QWx3YXlzIHJldHVybiBudWxsLCBzbyB0aGF0IHRoZSBwYXJzZXIgd2lsbCB1c2UgdGhlIHN5c3RlbQotICAgICAqIGlkZW50aWZpZXIgcHJvdmlkZWQgaW4gdGhlIFhNTCBkb2N1bWVudC4gIFRoaXMgbWV0aG9kIGltcGxlbWVudHMKLSAgICAgKiB0aGUgU0FYIGRlZmF1bHQgYmVoYXZpb3VyOiBhcHBsaWNhdGlvbiB3cml0ZXJzIGNhbiBvdmVycmlkZSBpdAotICAgICAqIGluIGEgc3ViY2xhc3MgdG8gZG8gc3BlY2lhbCB0cmFuc2xhdGlvbnMgc3VjaCBhcyBjYXRhbG9nIGxvb2t1cHMKLSAgICAgKiBvciBVUkkgcmVkaXJlY3Rpb24uPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIHB1YmxpY0lkIFRoZSBwdWJsaWMgaWRlbnRpZmVyLCBvciBudWxsIGlmIG5vbmUgaXMKLSAgICAgKiAgICAgICAgICAgICAgICAgYXZhaWxhYmxlLgotICAgICAqIEBwYXJhbSBzeXN0ZW1JZCBUaGUgc3lzdGVtIGlkZW50aWZpZXIgcHJvdmlkZWQgaW4gdGhlIFhNTAotICAgICAqICAgICAgICAgICAgICAgICBkb2N1bWVudC4KLSAgICAgKiBAcmV0dXJuIFRoZSBuZXcgaW5wdXQgc291cmNlLCBvciBudWxsIHRvIHJlcXVpcmUgdGhlCi0gICAgICogICAgICAgICBkZWZhdWx0IGJlaGF2aW91ci4KLSAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguRW50aXR5UmVzb2x2ZXIjcmVzb2x2ZUVudGl0eQotICAgICAqLwotICAgIHB1YmxpYyBJbnB1dFNvdXJjZSByZXNvbHZlRW50aXR5IChTdHJpbmcgcHVibGljSWQsIFN0cmluZyBzeXN0ZW1JZCkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0KLQotICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0gICAgLy8gRGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBvZiBEVERIYW5kbGVyIGludGVyZmFjZS4KLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotCi0KLSAgICAvKioKLSAgICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBhIG5vdGF0aW9uIGRlY2xhcmF0aW9uLgotICAgICAqCi0gICAgICogPHA+QnkgZGVmYXVsdCwgZG8gbm90aGluZy4gIEFwcGxpY2F0aW9uIHdyaXRlcnMgbWF5IG92ZXJyaWRlIHRoaXMKLSAgICAgKiBtZXRob2QgaW4gYSBzdWJjbGFzcyBpZiB0aGV5IHdpc2ggdG8ga2VlcCB0cmFjayBvZiB0aGUgbm90YXRpb25zCi0gICAgICogZGVjbGFyZWQgaW4gYSBkb2N1bWVudC48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbm90YXRpb24gbmFtZS4KLSAgICAgKiBAcGFyYW0gcHVibGljSWQgVGhlIG5vdGF0aW9uIHB1YmxpYyBpZGVudGlmaWVyLCBvciBudWxsIGlmIG5vdAotICAgICAqICAgICAgICAgICAgICAgICBhdmFpbGFibGUuCi0gICAgICogQHBhcmFtIHN5c3RlbUlkIFRoZSBub3RhdGlvbiBzeXN0ZW0gaWRlbnRpZmllci4KLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkRUREhhbmRsZXIjbm90YXRpb25EZWNsCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgbm90YXRpb25EZWNsIChTdHJpbmcgbmFtZSwgU3RyaW5nIHB1YmxpY0lkLCBTdHJpbmcgc3lzdGVtSWQpCi0gICAgewotICAgICAgICAvLyBubyBvcAotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgYW4gdW5wYXJzZWQgZW50aXR5IGRlY2xhcmF0aW9uLgotICAgICAqCi0gICAgICogPHA+QnkgZGVmYXVsdCwgZG8gbm90aGluZy4gIEFwcGxpY2F0aW9uIHdyaXRlcnMgbWF5IG92ZXJyaWRlIHRoaXMKLSAgICAgKiBtZXRob2QgaW4gYSBzdWJjbGFzcyB0byBrZWVwIHRyYWNrIG9mIHRoZSB1bnBhcnNlZCBlbnRpdGllcwotICAgICAqIGRlY2xhcmVkIGluIGEgZG9jdW1lbnQuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgVGhlIGVudGl0eSBuYW1lLgotICAgICAqIEBwYXJhbSBwdWJsaWNJZCBUaGUgZW50aXR5IHB1YmxpYyBpZGVudGlmaWVyLCBvciBudWxsIGlmIG5vdAotICAgICAqICAgICAgICAgICAgICAgICBhdmFpbGFibGUuCi0gICAgICogQHBhcmFtIHN5c3RlbUlkIFRoZSBlbnRpdHkgc3lzdGVtIGlkZW50aWZpZXIuCi0gICAgICogQHBhcmFtIG5vdGF0aW9uTmFtZSBUaGUgbmFtZSBvZiB0aGUgYXNzb2NpYXRlZCBub3RhdGlvbi4KLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkRUREhhbmRsZXIjdW5wYXJzZWRFbnRpdHlEZWNsCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdW5wYXJzZWRFbnRpdHlEZWNsIChTdHJpbmcgbmFtZSwgU3RyaW5nIHB1YmxpY0lkLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHN5c3RlbUlkLCBTdHJpbmcgbm90YXRpb25OYW1lKQotICAgIHsKLSAgICAgICAgLy8gbm8gb3AKLSAgICB9Ci0KLQotCi0gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLSAgICAvLyBEZWZhdWx0IGltcGxlbWVudGF0aW9uIG9mIERvY3VtZW50SGFuZGxlciBpbnRlcmZhY2UuCi0gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLQotCi0gICAgLyoqCi0gICAgICogUmVjZWl2ZSBhIExvY2F0b3Igb2JqZWN0IGZvciBkb2N1bWVudCBldmVudHMuCi0gICAgICoKLSAgICAgKiA8cD5CeSBkZWZhdWx0LCBkbyBub3RoaW5nLiAgQXBwbGljYXRpb24gd3JpdGVycyBtYXkgb3ZlcnJpZGUgdGhpcwotICAgICAqIG1ldGhvZCBpbiBhIHN1YmNsYXNzIGlmIHRoZXkgd2lzaCB0byBzdG9yZSB0aGUgbG9jYXRvciBmb3IgdXNlCi0gICAgICogd2l0aCBvdGhlciBkb2N1bWVudCBldmVudHMuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGxvY2F0b3IgQSBsb2NhdG9yIGZvciBhbGwgU0FYIGRvY3VtZW50IGV2ZW50cy4KLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkRvY3VtZW50SGFuZGxlciNzZXREb2N1bWVudExvY2F0b3IKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkxvY2F0b3IKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXREb2N1bWVudExvY2F0b3IgKExvY2F0b3IgbG9jYXRvcikKLSAgICB7Ci0gICAgICAgIC8vIG5vIG9wCi0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiB0aGUgYmVnaW5uaW5nIG9mIHRoZSBkb2N1bWVudC4KLSAgICAgKgotICAgICAqIDxwPkJ5IGRlZmF1bHQsIGRvIG5vdGhpbmcuICBBcHBsaWNhdGlvbiB3cml0ZXJzIG1heSBvdmVycmlkZSB0aGlzCi0gICAgICogbWV0aG9kIGluIGEgc3ViY2xhc3MgdG8gdGFrZSBzcGVjaWZpYyBhY3Rpb25zIGF0IHRoZSBiZWdpbm5pbmcKLSAgICAgKiBvZiBhIGRvY3VtZW50IChzdWNoIGFzIGFsbG9jYXRpbmcgdGhlIHJvb3Qgbm9kZSBvZiBhIHRyZWUgb3IKLSAgICAgKiBjcmVhdGluZyBhbiBvdXRwdXQgZmlsZSkuPC9wPgotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkRvY3VtZW50SGFuZGxlciNzdGFydERvY3VtZW50Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnREb2N1bWVudCAoKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICAvLyBubyBvcAotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIGVuZCBvZiB0aGUgZG9jdW1lbnQuCi0gICAgICoKLSAgICAgKiA8cD5CeSBkZWZhdWx0LCBkbyBub3RoaW5nLiAgQXBwbGljYXRpb24gd3JpdGVycyBtYXkgb3ZlcnJpZGUgdGhpcwotICAgICAqIG1ldGhvZCBpbiBhIHN1YmNsYXNzIHRvIHRha2Ugc3BlY2lmaWMgYWN0aW9ucyBhdCB0aGUgZW5kCi0gICAgICogb2YgYSBkb2N1bWVudCAoc3VjaCBhcyBmaW5hbGlzaW5nIGEgdHJlZSBvciBjbG9zaW5nIGFuIG91dHB1dAotICAgICAqIGZpbGUpLjwvcD4KLSAgICAgKgotICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5Eb2N1bWVudEhhbmRsZXIjZW5kRG9jdW1lbnQKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbmREb2N1bWVudCAoKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICAvLyBubyBvcAotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIHN0YXJ0IG9mIGFuIGVsZW1lbnQuCi0gICAgICoKLSAgICAgKiA8cD5CeSBkZWZhdWx0LCBkbyBub3RoaW5nLiAgQXBwbGljYXRpb24gd3JpdGVycyBtYXkgb3ZlcnJpZGUgdGhpcwotICAgICAqIG1ldGhvZCBpbiBhIHN1YmNsYXNzIHRvIHRha2Ugc3BlY2lmaWMgYWN0aW9ucyBhdCB0aGUgc3RhcnQgb2YKLSAgICAgKiBlYWNoIGVsZW1lbnQgKHN1Y2ggYXMgYWxsb2NhdGluZyBhIG5ldyB0cmVlIG5vZGUgb3Igd3JpdGluZwotICAgICAqIG91dHB1dCB0byBhIGZpbGUpLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBlbGVtZW50IHR5cGUgbmFtZS4KLSAgICAgKiBAcGFyYW0gYXR0cmlidXRlcyBUaGUgc3BlY2lmaWVkIG9yIGRlZmF1bHRlZCBhdHRyaWJ1dGVzLgotICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5Eb2N1bWVudEhhbmRsZXIjc3RhcnRFbGVtZW50Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnRFbGVtZW50IChTdHJpbmcgbmFtZSwgQXR0cmlidXRlTGlzdCBhdHRyaWJ1dGVzKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICAvLyBubyBvcAotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIGVuZCBvZiBhbiBlbGVtZW50LgotICAgICAqCi0gICAgICogPHA+QnkgZGVmYXVsdCwgZG8gbm90aGluZy4gIEFwcGxpY2F0aW9uIHdyaXRlcnMgbWF5IG92ZXJyaWRlIHRoaXMKLSAgICAgKiBtZXRob2QgaW4gYSBzdWJjbGFzcyB0byB0YWtlIHNwZWNpZmljIGFjdGlvbnMgYXQgdGhlIGVuZCBvZgotICAgICAqIGVhY2ggZWxlbWVudCAoc3VjaCBhcyBmaW5hbGlzaW5nIGEgdHJlZSBub2RlIG9yIHdyaXRpbmcKLSAgICAgKiBvdXRwdXQgdG8gYSBmaWxlKS48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSB0aGUgZWxlbWVudCBuYW1lCi0gICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkRvY3VtZW50SGFuZGxlciNlbmRFbGVtZW50Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kRWxlbWVudCAoU3RyaW5nIG5hbWUpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIC8vIG5vIG9wCi0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBjaGFyYWN0ZXIgZGF0YSBpbnNpZGUgYW4gZWxlbWVudC4KLSAgICAgKgotICAgICAqIDxwPkJ5IGRlZmF1bHQsIGRvIG5vdGhpbmcuICBBcHBsaWNhdGlvbiB3cml0ZXJzIG1heSBvdmVycmlkZSB0aGlzCi0gICAgICogbWV0aG9kIHRvIHRha2Ugc3BlY2lmaWMgYWN0aW9ucyBmb3IgZWFjaCBjaHVuayBvZiBjaGFyYWN0ZXIgZGF0YQotICAgICAqIChzdWNoIGFzIGFkZGluZyB0aGUgZGF0YSB0byBhIG5vZGUgb3IgYnVmZmVyLCBvciBwcmludGluZyBpdCB0bwotICAgICAqIGEgZmlsZSkuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGNoIFRoZSBjaGFyYWN0ZXJzLgotICAgICAqIEBwYXJhbSBzdGFydCBUaGUgc3RhcnQgcG9zaXRpb24gaW4gdGhlIGNoYXJhY3RlciBhcnJheS4KLSAgICAgKiBAcGFyYW0gbGVuZ3RoIFRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyB0byB1c2UgZnJvbSB0aGUKLSAgICAgKiAgICAgICAgICAgICAgIGNoYXJhY3RlciBhcnJheS4KLSAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguRG9jdW1lbnRIYW5kbGVyI2NoYXJhY3RlcnMKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBjaGFyYWN0ZXJzIChjaGFyIGNoW10sIGludCBzdGFydCwgaW50IGxlbmd0aCkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgLy8gbm8gb3AKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGlnbm9yYWJsZSB3aGl0ZXNwYWNlIGluIGVsZW1lbnQgY29udGVudC4KLSAgICAgKgotICAgICAqIDxwPkJ5IGRlZmF1bHQsIGRvIG5vdGhpbmcuICBBcHBsaWNhdGlvbiB3cml0ZXJzIG1heSBvdmVycmlkZSB0aGlzCi0gICAgICogbWV0aG9kIHRvIHRha2Ugc3BlY2lmaWMgYWN0aW9ucyBmb3IgZWFjaCBjaHVuayBvZiBpZ25vcmFibGUKLSAgICAgKiB3aGl0ZXNwYWNlIChzdWNoIGFzIGFkZGluZyBkYXRhIHRvIGEgbm9kZSBvciBidWZmZXIsIG9yIHByaW50aW5nCi0gICAgICogaXQgdG8gYSBmaWxlKS48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gY2ggVGhlIHdoaXRlc3BhY2UgY2hhcmFjdGVycy4KLSAgICAgKiBAcGFyYW0gc3RhcnQgVGhlIHN0YXJ0IHBvc2l0aW9uIGluIHRoZSBjaGFyYWN0ZXIgYXJyYXkuCi0gICAgICogQHBhcmFtIGxlbmd0aCBUaGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gdXNlIGZyb20gdGhlCi0gICAgICogICAgICAgICAgICAgICBjaGFyYWN0ZXIgYXJyYXkuCi0gICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkRvY3VtZW50SGFuZGxlciNpZ25vcmFibGVXaGl0ZXNwYWNlCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgaWdub3JhYmxlV2hpdGVzcGFjZSAoY2hhciBjaFtdLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIC8vIG5vIG9wCi0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBhIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24uCi0gICAgICoKLSAgICAgKiA8cD5CeSBkZWZhdWx0LCBkbyBub3RoaW5nLiAgQXBwbGljYXRpb24gd3JpdGVycyBtYXkgb3ZlcnJpZGUgdGhpcwotICAgICAqIG1ldGhvZCBpbiBhIHN1YmNsYXNzIHRvIHRha2Ugc3BlY2lmaWMgYWN0aW9ucyBmb3IgZWFjaAotICAgICAqIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24sIHN1Y2ggYXMgc2V0dGluZyBzdGF0dXMgdmFyaWFibGVzIG9yCi0gICAgICogaW52b2tpbmcgb3RoZXIgbWV0aG9kcy48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gdGFyZ2V0IFRoZSBwcm9jZXNzaW5nIGluc3RydWN0aW9uIHRhcmdldC4KLSAgICAgKiBAcGFyYW0gZGF0YSBUaGUgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiBkYXRhLCBvciBudWxsIGlmCi0gICAgICogICAgICAgICAgICAgbm9uZSBpcyBzdXBwbGllZC4KLSAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguRG9jdW1lbnRIYW5kbGVyI3Byb2Nlc3NpbmdJbnN0cnVjdGlvbgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHByb2Nlc3NpbmdJbnN0cnVjdGlvbiAoU3RyaW5nIHRhcmdldCwgU3RyaW5nIGRhdGEpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIC8vIG5vIG9wCi0gICAgfQotCi0KLQotICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0gICAgLy8gRGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgRXJyb3JIYW5kbGVyIGludGVyZmFjZS4KLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotCi0KLSAgICAvKioKLSAgICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBhIHBhcnNlciB3YXJuaW5nLgotICAgICAqCi0gICAgICogPHA+VGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gZG9lcyBub3RoaW5nLiAgQXBwbGljYXRpb24gd3JpdGVycwotICAgICAqIG1heSBvdmVycmlkZSB0aGlzIG1ldGhvZCBpbiBhIHN1YmNsYXNzIHRvIHRha2Ugc3BlY2lmaWMgYWN0aW9ucwotICAgICAqIGZvciBlYWNoIHdhcm5pbmcsIHN1Y2ggYXMgaW5zZXJ0aW5nIHRoZSBtZXNzYWdlIGluIGEgbG9nIGZpbGUgb3IKLSAgICAgKiBwcmludGluZyBpdCB0byB0aGUgY29uc29sZS48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gZSBUaGUgd2FybmluZyBpbmZvcm1hdGlvbiBlbmNvZGVkIGFzIGFuIGV4Y2VwdGlvbi4KLSAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguRXJyb3JIYW5kbGVyI3dhcm5pbmcKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LlNBWFBhcnNlRXhjZXB0aW9uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgd2FybmluZyAoU0FYUGFyc2VFeGNlcHRpb24gZSkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgLy8gbm8gb3AKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGEgcmVjb3ZlcmFibGUgcGFyc2VyIGVycm9yLgotICAgICAqCi0gICAgICogPHA+VGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gZG9lcyBub3RoaW5nLiAgQXBwbGljYXRpb24gd3JpdGVycwotICAgICAqIG1heSBvdmVycmlkZSB0aGlzIG1ldGhvZCBpbiBhIHN1YmNsYXNzIHRvIHRha2Ugc3BlY2lmaWMgYWN0aW9ucwotICAgICAqIGZvciBlYWNoIGVycm9yLCBzdWNoIGFzIGluc2VydGluZyB0aGUgbWVzc2FnZSBpbiBhIGxvZyBmaWxlIG9yCi0gICAgICogcHJpbnRpbmcgaXQgdG8gdGhlIGNvbnNvbGUuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGUgVGhlIHdhcm5pbmcgaW5mb3JtYXRpb24gZW5jb2RlZCBhcyBhbiBleGNlcHRpb24uCi0gICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkVycm9ySGFuZGxlciN3YXJuaW5nCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5TQVhQYXJzZUV4Y2VwdGlvbgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVycm9yIChTQVhQYXJzZUV4Y2VwdGlvbiBlKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICAvLyBubyBvcAotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogUmVwb3J0IGEgZmF0YWwgWE1MIHBhcnNpbmcgZXJyb3IuCi0gICAgICoKLSAgICAgKiA8cD5UaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiB0aHJvd3MgYSBTQVhQYXJzZUV4Y2VwdGlvbi4KLSAgICAgKiBBcHBsaWNhdGlvbiB3cml0ZXJzIG1heSBvdmVycmlkZSB0aGlzIG1ldGhvZCBpbiBhIHN1YmNsYXNzIGlmCi0gICAgICogdGhleSBuZWVkIHRvIHRha2Ugc3BlY2lmaWMgYWN0aW9ucyBmb3IgZWFjaCBmYXRhbCBlcnJvciAoc3VjaCBhcwotICAgICAqIGNvbGxlY3RpbmcgYWxsIG9mIHRoZSBlcnJvcnMgaW50byBhIHNpbmdsZSByZXBvcnQpOiBpbiBhbnkgY2FzZSwKLSAgICAgKiB0aGUgYXBwbGljYXRpb24gbXVzdCBzdG9wIGFsbCByZWd1bGFyIHByb2Nlc3Npbmcgd2hlbiB0aGlzCi0gICAgICogbWV0aG9kIGlzIGludm9rZWQsIHNpbmNlIHRoZSBkb2N1bWVudCBpcyBubyBsb25nZXIgcmVsaWFibGUsIGFuZAotICAgICAqIHRoZSBwYXJzZXIgbWF5IG5vIGxvbmdlciByZXBvcnQgcGFyc2luZyBldmVudHMuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGUgVGhlIGVycm9yIGluZm9ybWF0aW9uIGVuY29kZWQgYXMgYW4gZXhjZXB0aW9uLgotICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5FcnJvckhhbmRsZXIjZmF0YWxFcnJvcgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBmYXRhbEVycm9yIChTQVhQYXJzZUV4Y2VwdGlvbiBlKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICB0aHJvdyBlOwotICAgIH0KLQotfQotCi0vLyBlbmQgb2YgSGFuZGxlckJhc2UuamF2YQpkaWZmIC0tZ2l0IGEvc3JjL29yZy94bWwvc2F4L0lucHV0U291cmNlLmphdmEgYi9zcmMvb3JnL3htbC9zYXgvSW5wdXRTb3VyY2UuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNGY0N2Y5ZS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3htbC9zYXgvSW5wdXRTb3VyY2UuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDM2MCArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDAwLCAyMDA1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vLyBTQVggaW5wdXQgc291cmNlLgotLy8gaHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZwotLy8gTm8gd2FycmFudHk7IG5vIGNvcHlyaWdodCAtLSB1c2UgdGhpcyBhcyB5b3Ugd2lsbC4KLS8vICRJZDogSW5wdXRTb3VyY2UuamF2YSx2IDEuMiAyMDA0LzExLzAzIDIyOjU1OjMyIGpzdXR0b3IgRXhwICQKLQotcGFja2FnZSBvcmcueG1sLnNheDsKLQotaW1wb3J0IGphdmEuaW8uUmVhZGVyOwotaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07Ci0KLS8qKgotICogQSBzaW5nbGUgaW5wdXQgc291cmNlIGZvciBhbiBYTUwgZW50aXR5LgotICoKLSAqIDxibG9ja3F1b3RlPgotICogPGVtPlRoaXMgbW9kdWxlLCBib3RoIHNvdXJjZSBjb2RlIGFuZCBkb2N1bWVudGF0aW9uLCBpcyBpbiB0aGUKLSAqIFB1YmxpYyBEb21haW4sIGFuZCBjb21lcyB3aXRoIDxzdHJvbmc+Tk8gV0FSUkFOVFk8L3N0cm9uZz4uPC9lbT4KLSAqIFNlZSA8YSBocmVmPSdodHRwOi8vd3d3LnNheHByb2plY3Qub3JnJz5odHRwOi8vd3d3LnNheHByb2plY3Qub3JnPC9hPgotICogZm9yIGZ1cnRoZXIgaW5mb3JtYXRpb24uCi0gKiA8L2Jsb2NrcXVvdGU+Ci0gKgotICogPHA+VGhpcyBjbGFzcyBhbGxvd3MgYSBTQVggYXBwbGljYXRpb24gdG8gZW5jYXBzdWxhdGUgaW5mb3JtYXRpb24KLSAqIGFib3V0IGFuIGlucHV0IHNvdXJjZSBpbiBhIHNpbmdsZSBvYmplY3QsIHdoaWNoIG1heSBpbmNsdWRlCi0gKiBhIHB1YmxpYyBpZGVudGlmaWVyLCBhIHN5c3RlbSBpZGVudGlmaWVyLCBhIGJ5dGUgc3RyZWFtIChwb3NzaWJseQotICogd2l0aCBhIHNwZWNpZmllZCBlbmNvZGluZyksIGFuZC9vciBhIGNoYXJhY3RlciBzdHJlYW0uPC9wPgotICoKLSAqIDxwPlRoZXJlIGFyZSB0d28gcGxhY2VzIHRoYXQgdGhlIGFwcGxpY2F0aW9uIGNhbiBkZWxpdmVyIGFuCi0gKiBpbnB1dCBzb3VyY2UgdG8gdGhlIHBhcnNlcjogYXMgdGhlIGFyZ3VtZW50IHRvIHRoZSBQYXJzZXIucGFyc2UKLSAqIG1ldGhvZCwgb3IgYXMgdGhlIHJldHVybiB2YWx1ZSBvZiB0aGUgRW50aXR5UmVzb2x2ZXIucmVzb2x2ZUVudGl0eQotICogbWV0aG9kLjwvcD4KLSAqCi0gKiA8cD5UaGUgU0FYIHBhcnNlciB3aWxsIHVzZSB0aGUgSW5wdXRTb3VyY2Ugb2JqZWN0IHRvIGRldGVybWluZSBob3cKLSAqIHRvIHJlYWQgWE1MIGlucHV0LiAgSWYgdGhlcmUgaXMgYSBjaGFyYWN0ZXIgc3RyZWFtIGF2YWlsYWJsZSwgdGhlCi0gKiBwYXJzZXIgd2lsbCByZWFkIHRoYXQgc3RyZWFtIGRpcmVjdGx5LCBkaXNyZWdhcmRpbmcgYW55IHRleHQKLSAqIGVuY29kaW5nIGRlY2xhcmF0aW9uIGZvdW5kIGluIHRoYXQgc3RyZWFtLgotICogSWYgdGhlcmUgaXMgbm8gY2hhcmFjdGVyIHN0cmVhbSwgYnV0IHRoZXJlIGlzCi0gKiBhIGJ5dGUgc3RyZWFtLCB0aGUgcGFyc2VyIHdpbGwgdXNlIHRoYXQgYnl0ZSBzdHJlYW0sIHVzaW5nIHRoZQotICogZW5jb2Rpbmcgc3BlY2lmaWVkIGluIHRoZSBJbnB1dFNvdXJjZSBvciBlbHNlIChpZiBubyBlbmNvZGluZyBpcwotICogc3BlY2lmaWVkKSBhdXRvZGV0ZWN0aW5nIHRoZSBjaGFyYWN0ZXIgZW5jb2RpbmcgdXNpbmcgYW4gYWxnb3JpdGhtCi0gKiBzdWNoIGFzIHRoZSBvbmUgaW4gdGhlIFhNTCBzcGVjaWZpY2F0aW9uLiAgSWYgbmVpdGhlciBhIGNoYXJhY3RlcgotICogc3RyZWFtIG5vciBhCi0gKiBieXRlIHN0cmVhbSBpcyBhdmFpbGFibGUsIHRoZSBwYXJzZXIgd2lsbCBhdHRlbXB0IHRvIG9wZW4gYSBVUkkKLSAqIGNvbm5lY3Rpb24gdG8gdGhlIHJlc291cmNlIGlkZW50aWZpZWQgYnkgdGhlIHN5c3RlbQotICogaWRlbnRpZmllci48L3A+Ci0gKgotICogPHA+QW4gSW5wdXRTb3VyY2Ugb2JqZWN0IGJlbG9uZ3MgdG8gdGhlIGFwcGxpY2F0aW9uOiB0aGUgU0FYIHBhcnNlcgotICogc2hhbGwgbmV2ZXIgbW9kaWZ5IGl0IGluIGFueSB3YXkgKGl0IG1heSBtb2RpZnkgYSBjb3B5IGlmCi0gKiBuZWNlc3NhcnkpLiAgSG93ZXZlciwgc3RhbmRhcmQgcHJvY2Vzc2luZyBvZiBib3RoIGJ5dGUgYW5kCi0gKiBjaGFyYWN0ZXIgc3RyZWFtcyBpcyB0byBjbG9zZSB0aGVtIG9uIGFzIHBhcnQgb2YgZW5kLW9mLXBhcnNlIGNsZWFudXAsCi0gKiBzbyBhcHBsaWNhdGlvbnMgc2hvdWxkIG5vdCBhdHRlbXB0IHRvIHJlLXVzZSBzdWNoIHN0cmVhbXMgYWZ0ZXIgdGhleQotICogaGF2ZSBiZWVuIGhhbmRlZCB0byBhIHBhcnNlci4gIDwvcD4KLSAqCi0gKiBAc2luY2UgU0FYIDEuMAotICogQGF1dGhvciBEYXZpZCBNZWdnaW5zb24KLSAqIEBzZWUgb3JnLnhtbC5zYXguWE1MUmVhZGVyI3BhcnNlKG9yZy54bWwuc2F4LklucHV0U291cmNlKQotICogQHNlZSBvcmcueG1sLnNheC5FbnRpdHlSZXNvbHZlciNyZXNvbHZlRW50aXR5Ci0gKiBAc2VlIGphdmEuaW8uSW5wdXRTdHJlYW0KLSAqIEBzZWUgamF2YS5pby5SZWFkZXIKLSAqLwotcHVibGljIGNsYXNzIElucHV0U291cmNlIHsKLQotICAgIC8qKgotICAgICAqIFplcm8tYXJndW1lbnQgZGVmYXVsdCBjb25zdHJ1Y3Rvci4KLSAgICAgKgotICAgICAqIEBzZWUgI3NldFB1YmxpY0lkCi0gICAgICogQHNlZSAjc2V0U3lzdGVtSWQKLSAgICAgKiBAc2VlICNzZXRCeXRlU3RyZWFtCi0gICAgICogQHNlZSAjc2V0Q2hhcmFjdGVyU3RyZWFtCi0gICAgICogQHNlZSAjc2V0RW5jb2RpbmcKLSAgICAgKi8KLSAgICBwdWJsaWMgSW5wdXRTb3VyY2UgKCkKLSAgICB7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBDcmVhdGUgYSBuZXcgaW5wdXQgc291cmNlIHdpdGggYSBzeXN0ZW0gaWRlbnRpZmllci4KLSAgICAgKgotICAgICAqIDxwPkFwcGxpY2F0aW9ucyBtYXkgdXNlIHNldFB1YmxpY0lkIHRvIGluY2x1ZGUgYQotICAgICAqIHB1YmxpYyBpZGVudGlmaWVyIGFzIHdlbGwsIG9yIHNldEVuY29kaW5nIHRvIHNwZWNpZnkKLSAgICAgKiB0aGUgY2hhcmFjdGVyIGVuY29kaW5nLCBpZiBrbm93bi48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5JZiB0aGUgc3lzdGVtIGlkZW50aWZpZXIgaXMgYSBVUkwsIGl0IG11c3QgYmUgZnVsbHkKLSAgICAgKiByZXNvbHZlZCAoaXQgbWF5IG5vdCBiZSBhIHJlbGF0aXZlIFVSTCkuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIHN5c3RlbUlkIFRoZSBzeXN0ZW0gaWRlbnRpZmllciAoVVJJKS4KLSAgICAgKiBAc2VlICNzZXRQdWJsaWNJZAotICAgICAqIEBzZWUgI3NldFN5c3RlbUlkCi0gICAgICogQHNlZSAjc2V0Qnl0ZVN0cmVhbQotICAgICAqIEBzZWUgI3NldEVuY29kaW5nCi0gICAgICogQHNlZSAjc2V0Q2hhcmFjdGVyU3RyZWFtCi0gICAgICovCi0gICAgcHVibGljIElucHV0U291cmNlIChTdHJpbmcgc3lzdGVtSWQpCi0gICAgewotICAgICAgICBzZXRTeXN0ZW1JZChzeXN0ZW1JZCk7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBDcmVhdGUgYSBuZXcgaW5wdXQgc291cmNlIHdpdGggYSBieXRlIHN0cmVhbS4KLSAgICAgKgotICAgICAqIDxwPkFwcGxpY2F0aW9uIHdyaXRlcnMgc2hvdWxkIHVzZSBzZXRTeXN0ZW1JZCgpIHRvIHByb3ZpZGUgYSBiYXNlCi0gICAgICogZm9yIHJlc29sdmluZyByZWxhdGl2ZSBVUklzLCBtYXkgdXNlIHNldFB1YmxpY0lkIHRvIGluY2x1ZGUgYQotICAgICAqIHB1YmxpYyBpZGVudGlmaWVyLCBhbmQgbWF5IHVzZSBzZXRFbmNvZGluZyB0byBzcGVjaWZ5IHRoZSBvYmplY3QncwotICAgICAqIGNoYXJhY3RlciBlbmNvZGluZy48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gYnl0ZVN0cmVhbSBUaGUgcmF3IGJ5dGUgc3RyZWFtIGNvbnRhaW5pbmcgdGhlIGRvY3VtZW50LgotICAgICAqIEBzZWUgI3NldFB1YmxpY0lkCi0gICAgICogQHNlZSAjc2V0U3lzdGVtSWQKLSAgICAgKiBAc2VlICNzZXRFbmNvZGluZwotICAgICAqIEBzZWUgI3NldEJ5dGVTdHJlYW0KLSAgICAgKiBAc2VlICNzZXRDaGFyYWN0ZXJTdHJlYW0KLSAgICAgKi8KLSAgICBwdWJsaWMgSW5wdXRTb3VyY2UgKElucHV0U3RyZWFtIGJ5dGVTdHJlYW0pCi0gICAgewotICAgICAgICBzZXRCeXRlU3RyZWFtKGJ5dGVTdHJlYW0pOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlIGEgbmV3IGlucHV0IHNvdXJjZSB3aXRoIGEgY2hhcmFjdGVyIHN0cmVhbS4KLSAgICAgKgotICAgICAqIDxwPkFwcGxpY2F0aW9uIHdyaXRlcnMgc2hvdWxkIHVzZSBzZXRTeXN0ZW1JZCgpIHRvIHByb3ZpZGUgYSBiYXNlCi0gICAgICogZm9yIHJlc29sdmluZyByZWxhdGl2ZSBVUklzLCBhbmQgbWF5IHVzZSBzZXRQdWJsaWNJZCB0byBpbmNsdWRlIGEKLSAgICAgKiBwdWJsaWMgaWRlbnRpZmllci48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5UaGUgY2hhcmFjdGVyIHN0cmVhbSBzaGFsbCBub3QgaW5jbHVkZSBhIGJ5dGUgb3JkZXIgbWFyay48L3A+Ci0gICAgICoKLSAgICAgKiBAc2VlICNzZXRQdWJsaWNJZAotICAgICAqIEBzZWUgI3NldFN5c3RlbUlkCi0gICAgICogQHNlZSAjc2V0Qnl0ZVN0cmVhbQotICAgICAqIEBzZWUgI3NldENoYXJhY3RlclN0cmVhbQotICAgICAqLwotICAgIHB1YmxpYyBJbnB1dFNvdXJjZSAoUmVhZGVyIGNoYXJhY3RlclN0cmVhbSkKLSAgICB7Ci0gICAgICAgIHNldENoYXJhY3RlclN0cmVhbShjaGFyYWN0ZXJTdHJlYW0pOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSBwdWJsaWMgaWRlbnRpZmllciBmb3IgdGhpcyBpbnB1dCBzb3VyY2UuCi0gICAgICoKLSAgICAgKiA8cD5UaGUgcHVibGljIGlkZW50aWZpZXIgaXMgYWx3YXlzIG9wdGlvbmFsOiBpZiB0aGUgYXBwbGljYXRpb24KLSAgICAgKiB3cml0ZXIgaW5jbHVkZXMgb25lLCBpdCB3aWxsIGJlIHByb3ZpZGVkIGFzIHBhcnQgb2YgdGhlCi0gICAgICogbG9jYXRpb24gaW5mb3JtYXRpb24uPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIHB1YmxpY0lkIFRoZSBwdWJsaWMgaWRlbnRpZmllciBhcyBhIHN0cmluZy4KLSAgICAgKiBAc2VlICNnZXRQdWJsaWNJZAotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguTG9jYXRvciNnZXRQdWJsaWNJZAotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb24jZ2V0UHVibGljSWQKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRQdWJsaWNJZCAoU3RyaW5nIHB1YmxpY0lkKQotICAgIHsKLSAgICAgICAgdGhpcy5wdWJsaWNJZCA9IHB1YmxpY0lkOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBwdWJsaWMgaWRlbnRpZmllciBmb3IgdGhpcyBpbnB1dCBzb3VyY2UuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBwdWJsaWMgaWRlbnRpZmllciwgb3IgbnVsbCBpZiBub25lIHdhcyBzdXBwbGllZC4KLSAgICAgKiBAc2VlICNzZXRQdWJsaWNJZAotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0UHVibGljSWQgKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBwdWJsaWNJZDsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFNldCB0aGUgc3lzdGVtIGlkZW50aWZpZXIgZm9yIHRoaXMgaW5wdXQgc291cmNlLgotICAgICAqCi0gICAgICogPHA+VGhlIHN5c3RlbSBpZGVudGlmaWVyIGlzIG9wdGlvbmFsIGlmIHRoZXJlIGlzIGEgYnl0ZSBzdHJlYW0KLSAgICAgKiBvciBhIGNoYXJhY3RlciBzdHJlYW0sIGJ1dCBpdCBpcyBzdGlsbCB1c2VmdWwgdG8gcHJvdmlkZSBvbmUsCi0gICAgICogc2luY2UgdGhlIGFwcGxpY2F0aW9uIGNhbiB1c2UgaXQgdG8gcmVzb2x2ZSByZWxhdGl2ZSBVUklzCi0gICAgICogYW5kIGNhbiBpbmNsdWRlIGl0IGluIGVycm9yIG1lc3NhZ2VzIGFuZCB3YXJuaW5ncyAodGhlIHBhcnNlcgotICAgICAqIHdpbGwgYXR0ZW1wdCB0byBvcGVuIGEgY29ubmVjdGlvbiB0byB0aGUgVVJJIG9ubHkgaWYKLSAgICAgKiB0aGVyZSBpcyBubyBieXRlIHN0cmVhbSBvciBjaGFyYWN0ZXIgc3RyZWFtIHNwZWNpZmllZCkuPC9wPgotICAgICAqCi0gICAgICogPHA+SWYgdGhlIGFwcGxpY2F0aW9uIGtub3dzIHRoZSBjaGFyYWN0ZXIgZW5jb2Rpbmcgb2YgdGhlCi0gICAgICogb2JqZWN0IHBvaW50ZWQgdG8gYnkgdGhlIHN5c3RlbSBpZGVudGlmaWVyLCBpdCBjYW4gcmVnaXN0ZXIKLSAgICAgKiB0aGUgZW5jb2RpbmcgdXNpbmcgdGhlIHNldEVuY29kaW5nIG1ldGhvZC48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5JZiB0aGUgc3lzdGVtIGlkZW50aWZpZXIgaXMgYSBVUkwsIGl0IG11c3QgYmUgZnVsbHkKLSAgICAgKiByZXNvbHZlZCAoaXQgbWF5IG5vdCBiZSBhIHJlbGF0aXZlIFVSTCkuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIHN5c3RlbUlkIFRoZSBzeXN0ZW0gaWRlbnRpZmllciBhcyBhIHN0cmluZy4KLSAgICAgKiBAc2VlICNzZXRFbmNvZGluZwotICAgICAqIEBzZWUgI2dldFN5c3RlbUlkCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5Mb2NhdG9yI2dldFN5c3RlbUlkCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5TQVhQYXJzZUV4Y2VwdGlvbiNnZXRTeXN0ZW1JZAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFN5c3RlbUlkIChTdHJpbmcgc3lzdGVtSWQpCi0gICAgewotICAgICAgICB0aGlzLnN5c3RlbUlkID0gc3lzdGVtSWQ7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIHN5c3RlbSBpZGVudGlmaWVyIGZvciB0aGlzIGlucHV0IHNvdXJjZS4KLSAgICAgKgotICAgICAqIDxwPlRoZSBnZXRFbmNvZGluZyBtZXRob2Qgd2lsbCByZXR1cm4gdGhlIGNoYXJhY3RlciBlbmNvZGluZwotICAgICAqIG9mIHRoZSBvYmplY3QgcG9pbnRlZCB0bywgb3IgbnVsbCBpZiB1bmtub3duLjwvcD4KLSAgICAgKgotICAgICAqIDxwPklmIHRoZSBzeXN0ZW0gSUQgaXMgYSBVUkwsIGl0IHdpbGwgYmUgZnVsbHkgcmVzb2x2ZWQuPC9wPgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgc3lzdGVtIGlkZW50aWZpZXIsIG9yIG51bGwgaWYgbm9uZSB3YXMgc3VwcGxpZWQuCi0gICAgICogQHNlZSAjc2V0U3lzdGVtSWQKLSAgICAgKiBAc2VlICNnZXRFbmNvZGluZwotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3lzdGVtSWQgKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBzeXN0ZW1JZDsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFNldCB0aGUgYnl0ZSBzdHJlYW0gZm9yIHRoaXMgaW5wdXQgc291cmNlLgotICAgICAqCi0gICAgICogPHA+VGhlIFNBWCBwYXJzZXIgd2lsbCBpZ25vcmUgdGhpcyBpZiB0aGVyZSBpcyBhbHNvIGEgY2hhcmFjdGVyCi0gICAgICogc3RyZWFtIHNwZWNpZmllZCwgYnV0IGl0IHdpbGwgdXNlIGEgYnl0ZSBzdHJlYW0gaW4gcHJlZmVyZW5jZQotICAgICAqIHRvIG9wZW5pbmcgYSBVUkkgY29ubmVjdGlvbiBpdHNlbGYuPC9wPgotICAgICAqCi0gICAgICogPHA+SWYgdGhlIGFwcGxpY2F0aW9uIGtub3dzIHRoZSBjaGFyYWN0ZXIgZW5jb2Rpbmcgb2YgdGhlCi0gICAgICogYnl0ZSBzdHJlYW0sIGl0IHNob3VsZCBzZXQgaXQgd2l0aCB0aGUgc2V0RW5jb2RpbmcgbWV0aG9kLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBieXRlU3RyZWFtIEEgYnl0ZSBzdHJlYW0gY29udGFpbmluZyBhbiBYTUwgZG9jdW1lbnQgb3IKLSAgICAgKiAgICAgICAgb3RoZXIgZW50aXR5LgotICAgICAqIEBzZWUgI3NldEVuY29kaW5nCi0gICAgICogQHNlZSAjZ2V0Qnl0ZVN0cmVhbQotICAgICAqIEBzZWUgI2dldEVuY29kaW5nCi0gICAgICogQHNlZSBqYXZhLmlvLklucHV0U3RyZWFtCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0Qnl0ZVN0cmVhbSAoSW5wdXRTdHJlYW0gYnl0ZVN0cmVhbSkKLSAgICB7Ci0gICAgICAgIHRoaXMuYnl0ZVN0cmVhbSA9IGJ5dGVTdHJlYW07Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIGJ5dGUgc3RyZWFtIGZvciB0aGlzIGlucHV0IHNvdXJjZS4KLSAgICAgKgotICAgICAqIDxwPlRoZSBnZXRFbmNvZGluZyBtZXRob2Qgd2lsbCByZXR1cm4gdGhlIGNoYXJhY3RlcgotICAgICAqIGVuY29kaW5nIGZvciB0aGlzIGJ5dGUgc3RyZWFtLCBvciBudWxsIGlmIHVua25vd24uPC9wPgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgYnl0ZSBzdHJlYW0sIG9yIG51bGwgaWYgbm9uZSB3YXMgc3VwcGxpZWQuCi0gICAgICogQHNlZSAjZ2V0RW5jb2RpbmcKLSAgICAgKiBAc2VlICNzZXRCeXRlU3RyZWFtCi0gICAgICovCi0gICAgcHVibGljIElucHV0U3RyZWFtIGdldEJ5dGVTdHJlYW0gKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBieXRlU3RyZWFtOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSBjaGFyYWN0ZXIgZW5jb2RpbmcsIGlmIGtub3duLgotICAgICAqCi0gICAgICogPHA+VGhlIGVuY29kaW5nIG11c3QgYmUgYSBzdHJpbmcgYWNjZXB0YWJsZSBmb3IgYW4KLSAgICAgKiBYTUwgZW5jb2RpbmcgZGVjbGFyYXRpb24gKHNlZSBzZWN0aW9uIDQuMy4zIG9mIHRoZSBYTUwgMS4wCi0gICAgICogcmVjb21tZW5kYXRpb24pLjwvcD4KLSAgICAgKgotICAgICAqIDxwPlRoaXMgbWV0aG9kIGhhcyBubyBlZmZlY3Qgd2hlbiB0aGUgYXBwbGljYXRpb24gcHJvdmlkZXMgYQotICAgICAqIGNoYXJhY3RlciBzdHJlYW0uPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGVuY29kaW5nIEEgc3RyaW5nIGRlc2NyaWJpbmcgdGhlIGNoYXJhY3RlciBlbmNvZGluZy4KLSAgICAgKiBAc2VlICNzZXRTeXN0ZW1JZAotICAgICAqIEBzZWUgI3NldEJ5dGVTdHJlYW0KLSAgICAgKiBAc2VlICNnZXRFbmNvZGluZwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEVuY29kaW5nIChTdHJpbmcgZW5jb2RpbmcpCi0gICAgewotICAgICAgICB0aGlzLmVuY29kaW5nID0gZW5jb2Rpbmc7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIGNoYXJhY3RlciBlbmNvZGluZyBmb3IgYSBieXRlIHN0cmVhbSBvciBVUkkuCi0gICAgICogVGhpcyB2YWx1ZSB3aWxsIGJlIGlnbm9yZWQgd2hlbiB0aGUgYXBwbGljYXRpb24gcHJvdmlkZXMgYQotICAgICAqIGNoYXJhY3RlciBzdHJlYW0uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBlbmNvZGluZywgb3IgbnVsbCBpZiBub25lIHdhcyBzdXBwbGllZC4KLSAgICAgKiBAc2VlICNzZXRCeXRlU3RyZWFtCi0gICAgICogQHNlZSAjZ2V0U3lzdGVtSWQKLSAgICAgKiBAc2VlICNnZXRCeXRlU3RyZWFtCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRFbmNvZGluZyAoKQotICAgIHsKLSAgICAgICAgcmV0dXJuIGVuY29kaW5nOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSBjaGFyYWN0ZXIgc3RyZWFtIGZvciB0aGlzIGlucHV0IHNvdXJjZS4KLSAgICAgKgotICAgICAqIDxwPklmIHRoZXJlIGlzIGEgY2hhcmFjdGVyIHN0cmVhbSBzcGVjaWZpZWQsIHRoZSBTQVggcGFyc2VyCi0gICAgICogd2lsbCBpZ25vcmUgYW55IGJ5dGUgc3RyZWFtIGFuZCB3aWxsIG5vdCBhdHRlbXB0IHRvIG9wZW4KLSAgICAgKiBhIFVSSSBjb25uZWN0aW9uIHRvIHRoZSBzeXN0ZW0gaWRlbnRpZmllci48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gY2hhcmFjdGVyU3RyZWFtIFRoZSBjaGFyYWN0ZXIgc3RyZWFtIGNvbnRhaW5pbmcgdGhlCi0gICAgICogICAgICAgIFhNTCBkb2N1bWVudCBvciBvdGhlciBlbnRpdHkuCi0gICAgICogQHNlZSAjZ2V0Q2hhcmFjdGVyU3RyZWFtCi0gICAgICogQHNlZSBqYXZhLmlvLlJlYWRlcgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldENoYXJhY3RlclN0cmVhbSAoUmVhZGVyIGNoYXJhY3RlclN0cmVhbSkKLSAgICB7Ci0gICAgICAgIHRoaXMuY2hhcmFjdGVyU3RyZWFtID0gY2hhcmFjdGVyU3RyZWFtOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBjaGFyYWN0ZXIgc3RyZWFtIGZvciB0aGlzIGlucHV0IHNvdXJjZS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIGNoYXJhY3RlciBzdHJlYW0sIG9yIG51bGwgaWYgbm9uZSB3YXMgc3VwcGxpZWQuCi0gICAgICogQHNlZSAjc2V0Q2hhcmFjdGVyU3RyZWFtCi0gICAgICovCi0gICAgcHVibGljIFJlYWRlciBnZXRDaGFyYWN0ZXJTdHJlYW0gKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBjaGFyYWN0ZXJTdHJlYW07Ci0gICAgfQotCi0KLQotICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0gICAgLy8gSW50ZXJuYWwgc3RhdGUuCi0gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLQotICAgIHByaXZhdGUgU3RyaW5nIHB1YmxpY0lkOwotICAgIHByaXZhdGUgU3RyaW5nIHN5c3RlbUlkOwotICAgIHByaXZhdGUgSW5wdXRTdHJlYW0gYnl0ZVN0cmVhbTsKLSAgICBwcml2YXRlIFN0cmluZyBlbmNvZGluZzsKLSAgICBwcml2YXRlIFJlYWRlciBjaGFyYWN0ZXJTdHJlYW07Ci0KLX0KLQotLy8gZW5kIG9mIElucHV0U291cmNlLmphdmEKZGlmZiAtLWdpdCBhL3NyYy9vcmcveG1sL3NheC9Mb2NhdG9yLmphdmEgYi9zcmMvb3JnL3htbC9zYXgvTG9jYXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4NjgxNjhkLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcveG1sL3NheC9Mb2NhdG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNjAgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwMCwgMjAwNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLy8gU0FYIGxvY2F0b3IgaW50ZXJmYWNlIGZvciBkb2N1bWVudCBldmVudHMuCi0vLyBodHRwOi8vd3d3LnNheHByb2plY3Qub3JnCi0vLyBObyB3YXJyYW50eTsgbm8gY29weXJpZ2h0IC0tIHVzZSB0aGlzIGFzIHlvdSB3aWxsLgotLy8gJElkOiBMb2NhdG9yLmphdmEsdiAxLjIgMjAwNC8xMS8wMyAyMjo1NTozMiBqc3V0dG9yIEV4cCAkCi0KLXBhY2thZ2Ugb3JnLnhtbC5zYXg7Ci0KLQotLyoqCi0gKiBJbnRlcmZhY2UgZm9yIGFzc29jaWF0aW5nIGEgU0FYIGV2ZW50IHdpdGggYSBkb2N1bWVudCBsb2NhdGlvbi4KLSAqCi0gKiA8YmxvY2txdW90ZT4KLSAqIDxlbT5UaGlzIG1vZHVsZSwgYm90aCBzb3VyY2UgY29kZSBhbmQgZG9jdW1lbnRhdGlvbiwgaXMgaW4gdGhlCi0gKiBQdWJsaWMgRG9tYWluLCBhbmQgY29tZXMgd2l0aCA8c3Ryb25nPk5PIFdBUlJBTlRZPC9zdHJvbmc+LjwvZW0+Ci0gKiBTZWUgPGEgaHJlZj0naHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZyc+aHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZzwvYT4KLSAqIGZvciBmdXJ0aGVyIGluZm9ybWF0aW9uLgotICogPC9ibG9ja3F1b3RlPgotICoKLSAqIDxwPklmIGEgU0FYIHBhcnNlciBwcm92aWRlcyBsb2NhdGlvbiBpbmZvcm1hdGlvbiB0byB0aGUgU0FYCi0gKiBhcHBsaWNhdGlvbiwgaXQgZG9lcyBzbyBieSBpbXBsZW1lbnRpbmcgdGhpcyBpbnRlcmZhY2UgYW5kIHRoZW4KLSAqIHBhc3NpbmcgYW4gaW5zdGFuY2UgdG8gdGhlIGFwcGxpY2F0aW9uIHVzaW5nIHRoZSBjb250ZW50Ci0gKiBoYW5kbGVyJ3Mge0BsaW5rIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI3NldERvY3VtZW50TG9jYXRvcgotICogc2V0RG9jdW1lbnRMb2NhdG9yfSBtZXRob2QuICBUaGUgYXBwbGljYXRpb24gY2FuIHVzZSB0aGUKLSAqIG9iamVjdCB0byBvYnRhaW4gdGhlIGxvY2F0aW9uIG9mIGFueSBvdGhlciBTQVggZXZlbnQKLSAqIGluIHRoZSBYTUwgc291cmNlIGRvY3VtZW50LjwvcD4KLSAqCi0gKiA8cD5Ob3RlIHRoYXQgdGhlIHJlc3VsdHMgcmV0dXJuZWQgYnkgdGhlIG9iamVjdCB3aWxsIGJlIHZhbGlkIG9ubHkKLSAqIGR1cmluZyB0aGUgc2NvcGUgb2YgZWFjaCBjYWxsYmFjayBtZXRob2Q6IHRoZSBhcHBsaWNhdGlvbgotICogd2lsbCByZWNlaXZlIHVucHJlZGljdGFibGUgcmVzdWx0cyBpZiBpdCBhdHRlbXB0cyB0byB1c2UgdGhlCi0gKiBsb2NhdG9yIGF0IGFueSBvdGhlciB0aW1lLCBvciBhZnRlciBwYXJzaW5nIGNvbXBsZXRlcy48L3A+Ci0gKgotICogPHA+U0FYIHBhcnNlcnMgYXJlIG5vdCByZXF1aXJlZCB0byBzdXBwbHkgYSBsb2NhdG9yLCBidXQgdGhleSBhcmUKLSAqIHZlcnkgc3Ryb25nbHkgZW5jb3VyYWdlZCB0byBkbyBzby4gIElmIHRoZSBwYXJzZXIgc3VwcGxpZXMgYQotICogbG9jYXRvciwgaXQgbXVzdCBkbyBzbyBiZWZvcmUgcmVwb3J0aW5nIGFueSBvdGhlciBkb2N1bWVudCBldmVudHMuCi0gKiBJZiBubyBsb2NhdG9yIGhhcyBiZWVuIHNldCBieSB0aGUgdGltZSB0aGUgYXBwbGljYXRpb24gcmVjZWl2ZXMKLSAqIHRoZSB7QGxpbmsgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjc3RhcnREb2N1bWVudCBzdGFydERvY3VtZW50fQotICogZXZlbnQsIHRoZSBhcHBsaWNhdGlvbiBzaG91bGQgYXNzdW1lIHRoYXQgYSBsb2NhdG9yIGlzIG5vdAotICogYXZhaWxhYmxlLjwvcD4KLSAqCi0gKiBAc2luY2UgU0FYIDEuMAotICogQGF1dGhvciBEYXZpZCBNZWdnaW5zb24KLSAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjc2V0RG9jdW1lbnRMb2NhdG9yCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgTG9jYXRvciB7Ci0KLQotICAgIC8qKgotICAgICAqIFJldHVybiB0aGUgcHVibGljIGlkZW50aWZpZXIgZm9yIHRoZSBjdXJyZW50IGRvY3VtZW50IGV2ZW50LgotICAgICAqCi0gICAgICogPHA+VGhlIHJldHVybiB2YWx1ZSBpcyB0aGUgcHVibGljIGlkZW50aWZpZXIgb2YgdGhlIGRvY3VtZW50Ci0gICAgICogZW50aXR5IG9yIG9mIHRoZSBleHRlcm5hbCBwYXJzZWQgZW50aXR5IGluIHdoaWNoIHRoZSBtYXJrdXAKLSAgICAgKiB0cmlnZ2VyaW5nIHRoZSBldmVudCBhcHBlYXJzLjwvcD4KLSAgICAgKgotICAgICAqIEByZXR1cm4gQSBzdHJpbmcgY29udGFpbmluZyB0aGUgcHVibGljIGlkZW50aWZpZXIsIG9yCi0gICAgICogICAgICAgICBudWxsIGlmIG5vbmUgaXMgYXZhaWxhYmxlLgotICAgICAqIEBzZWUgI2dldFN5c3RlbUlkCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IFN0cmluZyBnZXRQdWJsaWNJZCAoKTsKLQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSBzeXN0ZW0gaWRlbnRpZmllciBmb3IgdGhlIGN1cnJlbnQgZG9jdW1lbnQgZXZlbnQuCi0gICAgICoKLSAgICAgKiA8cD5UaGUgcmV0dXJuIHZhbHVlIGlzIHRoZSBzeXN0ZW0gaWRlbnRpZmllciBvZiB0aGUgZG9jdW1lbnQKLSAgICAgKiBlbnRpdHkgb3Igb2YgdGhlIGV4dGVybmFsIHBhcnNlZCBlbnRpdHkgaW4gd2hpY2ggdGhlIG1hcmt1cAotICAgICAqIHRyaWdnZXJpbmcgdGhlIGV2ZW50IGFwcGVhcnMuPC9wPgotICAgICAqCi0gICAgICogPHA+SWYgdGhlIHN5c3RlbSBpZGVudGlmaWVyIGlzIGEgVVJMLCB0aGUgcGFyc2VyIG11c3QgcmVzb2x2ZSBpdAotICAgICAqIGZ1bGx5IGJlZm9yZSBwYXNzaW5nIGl0IHRvIHRoZSBhcHBsaWNhdGlvbi4gIEZvciBleGFtcGxlLCBhIGZpbGUKLSAgICAgKiBuYW1lIG11c3QgYWx3YXlzIGJlIHByb3ZpZGVkIGFzIGEgPGVtPmZpbGU6Li4uPC9lbT4gVVJMLCBhbmQgb3RoZXIKLSAgICAgKiBraW5kcyBvZiByZWxhdGl2ZSBVUkkgYXJlIGFsc28gcmVzb2x2ZWQgYWdhaW5zdCB0aGVpciBiYXNlcy48L3A+Ci0gICAgICoKLSAgICAgKiBAcmV0dXJuIEEgc3RyaW5nIGNvbnRhaW5pbmcgdGhlIHN5c3RlbSBpZGVudGlmaWVyLCBvciBudWxsCi0gICAgICogICAgICAgICBpZiBub25lIGlzIGF2YWlsYWJsZS4KLSAgICAgKiBAc2VlICNnZXRQdWJsaWNJZAotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCBTdHJpbmcgZ2V0U3lzdGVtSWQgKCk7Ci0KLQotICAgIC8qKgotICAgICAqIFJldHVybiB0aGUgbGluZSBudW1iZXIgd2hlcmUgdGhlIGN1cnJlbnQgZG9jdW1lbnQgZXZlbnQgZW5kcy4KLSAgICAgKiBMaW5lcyBhcmUgZGVsaW1pdGVkIGJ5IGxpbmUgZW5kcywgd2hpY2ggYXJlIGRlZmluZWQgaW4KLSAgICAgKiB0aGUgWE1MIHNwZWNpZmljYXRpb24uCi0gICAgICoKLSAgICAgKiA8cD48c3Ryb25nPldhcm5pbmc6PC9zdHJvbmc+IFRoZSByZXR1cm4gdmFsdWUgZnJvbSB0aGUgbWV0aG9kCi0gICAgICogaXMgaW50ZW5kZWQgb25seSBhcyBhbiBhcHByb3hpbWF0aW9uIGZvciB0aGUgc2FrZSBvZiBkaWFnbm9zdGljczsKLSAgICAgKiBpdCBpcyBub3QgaW50ZW5kZWQgdG8gcHJvdmlkZSBzdWZmaWNpZW50IGluZm9ybWF0aW9uCi0gICAgICogdG8gZWRpdCB0aGUgY2hhcmFjdGVyIGNvbnRlbnQgb2YgdGhlIG9yaWdpbmFsIFhNTCBkb2N1bWVudC4KLSAgICAgKiBJbiBzb21lIGNhc2VzLCB0aGVzZSAibGluZSIgbnVtYmVycyBtYXRjaCB3aGF0IHdvdWxkIGJlIGRpc3BsYXllZAotICAgICAqIGFzIGNvbHVtbnMsIGFuZCBpbiBvdGhlcnMgdGhleSBtYXkgbm90IG1hdGNoIHRoZSBzb3VyY2UgdGV4dAotICAgICAqIGR1ZSB0byBpbnRlcm5hbCBlbnRpdHkgZXhwYW5zaW9uLiAgPC9wPgotICAgICAqCi0gICAgICogPHA+VGhlIHJldHVybiB2YWx1ZSBpcyBhbiBhcHByb3hpbWF0aW9uIG9mIHRoZSBsaW5lIG51bWJlcgotICAgICAqIGluIHRoZSBkb2N1bWVudCBlbnRpdHkgb3IgZXh0ZXJuYWwgcGFyc2VkIGVudGl0eSB3aGVyZSB0aGUKLSAgICAgKiBtYXJrdXAgdHJpZ2dlcmluZyB0aGUgZXZlbnQgYXBwZWFycy48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5JZiBwb3NzaWJsZSwgdGhlIFNBWCBkcml2ZXIgc2hvdWxkIHByb3ZpZGUgdGhlIGxpbmUgcG9zaXRpb24KLSAgICAgKiBvZiB0aGUgZmlyc3QgY2hhcmFjdGVyIGFmdGVyIHRoZSB0ZXh0IGFzc29jaWF0ZWQgd2l0aCB0aGUgZG9jdW1lbnQKLSAgICAgKiBldmVudC4gIFRoZSBmaXJzdCBsaW5lIGlzIGxpbmUgMS48L3A+Ci0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBsaW5lIG51bWJlciwgb3IgLTEgaWYgbm9uZSBpcyBhdmFpbGFibGUuCi0gICAgICogQHNlZSAjZ2V0Q29sdW1uTnVtYmVyCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IGludCBnZXRMaW5lTnVtYmVyICgpOwotCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIGNvbHVtbiBudW1iZXIgd2hlcmUgdGhlIGN1cnJlbnQgZG9jdW1lbnQgZXZlbnQgZW5kcy4KLSAgICAgKiBUaGlzIGlzIG9uZS1iYXNlZCBudW1iZXIgb2YgSmF2YSA8Y29kZT5jaGFyPC9jb2RlPiB2YWx1ZXMgc2luY2UKLSAgICAgKiB0aGUgbGFzdCBsaW5lIGVuZC4KLSAgICAgKgotICAgICAqIDxwPjxzdHJvbmc+V2FybmluZzo8L3N0cm9uZz4gVGhlIHJldHVybiB2YWx1ZSBmcm9tIHRoZSBtZXRob2QKLSAgICAgKiBpcyBpbnRlbmRlZCBvbmx5IGFzIGFuIGFwcHJveGltYXRpb24gZm9yIHRoZSBzYWtlIG9mIGRpYWdub3N0aWNzOwotICAgICAqIGl0IGlzIG5vdCBpbnRlbmRlZCB0byBwcm92aWRlIHN1ZmZpY2llbnQgaW5mb3JtYXRpb24KLSAgICAgKiB0byBlZGl0IHRoZSBjaGFyYWN0ZXIgY29udGVudCBvZiB0aGUgb3JpZ2luYWwgWE1MIGRvY3VtZW50LgotICAgICAqIEZvciBleGFtcGxlLCB3aGVuIGxpbmVzIGNvbnRhaW4gY29tYmluaW5nIGNoYXJhY3RlciBzZXF1ZW5jZXMsIHdpZGUKLSAgICAgKiBjaGFyYWN0ZXJzLCBzdXJyb2dhdGUgcGFpcnMsIG9yIGJpLWRpcmVjdGlvbmFsIHRleHQsIHRoZSB2YWx1ZSBtYXkKLSAgICAgKiBub3QgY29ycmVzcG9uZCB0byB0aGUgY29sdW1uIGluIGEgdGV4dCBlZGl0b3IncyBkaXNwbGF5LiA8L3A+Ci0gICAgICoKLSAgICAgKiA8cD5UaGUgcmV0dXJuIHZhbHVlIGlzIGFuIGFwcHJveGltYXRpb24gb2YgdGhlIGNvbHVtbiBudW1iZXIKLSAgICAgKiBpbiB0aGUgZG9jdW1lbnQgZW50aXR5IG9yIGV4dGVybmFsIHBhcnNlZCBlbnRpdHkgd2hlcmUgdGhlCi0gICAgICogbWFya3VwIHRyaWdnZXJpbmcgdGhlIGV2ZW50IGFwcGVhcnMuPC9wPgotICAgICAqCi0gICAgICogPHA+SWYgcG9zc2libGUsIHRoZSBTQVggZHJpdmVyIHNob3VsZCBwcm92aWRlIHRoZSBsaW5lIHBvc2l0aW9uCi0gICAgICogb2YgdGhlIGZpcnN0IGNoYXJhY3RlciBhZnRlciB0aGUgdGV4dCBhc3NvY2lhdGVkIHdpdGggdGhlIGRvY3VtZW50Ci0gICAgICogZXZlbnQuICBUaGUgZmlyc3QgY29sdW1uIGluIGVhY2ggbGluZSBpcyBjb2x1bW4gMS48L3A+Ci0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBjb2x1bW4gbnVtYmVyLCBvciAtMSBpZiBub25lIGlzIGF2YWlsYWJsZS4KLSAgICAgKiBAc2VlICNnZXRMaW5lTnVtYmVyCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IGludCBnZXRDb2x1bW5OdW1iZXIgKCk7Ci0KLX0KLQotLy8gZW5kIG9mIExvY2F0b3IuamF2YQpkaWZmIC0tZ2l0IGEvc3JjL29yZy94bWwvc2F4L1BhcnNlci5qYXZhIGIvc3JjL29yZy94bWwvc2F4L1BhcnNlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2MWJmYmM3Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcveG1sL3NheC9QYXJzZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIzMyArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDAwLCAyMDA1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vLyBTQVggcGFyc2VyIGludGVyZmFjZS4KLS8vIGh0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmcKLS8vIE5vIHdhcnJhbnR5OyBubyBjb3B5cmlnaHQgLS0gdXNlIHRoaXMgYXMgeW91IHdpbGwuCi0vLyAkSWQ6IFBhcnNlci5qYXZhLHYgMS4yIDIwMDQvMTEvMDMgMjI6NTU6MzIganN1dHRvciBFeHAgJAotCi1wYWNrYWdlIG9yZy54bWwuc2F4OwotCi1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwotCi0KLS8qKgotICogQmFzaWMgaW50ZXJmYWNlIGZvciBTQVggKFNpbXBsZSBBUEkgZm9yIFhNTCkgcGFyc2Vycy4KLSAqCi0gKiA8YmxvY2txdW90ZT4KLSAqIDxlbT5UaGlzIG1vZHVsZSwgYm90aCBzb3VyY2UgY29kZSBhbmQgZG9jdW1lbnRhdGlvbiwgaXMgaW4gdGhlCi0gKiBQdWJsaWMgRG9tYWluLCBhbmQgY29tZXMgd2l0aCA8c3Ryb25nPk5PIFdBUlJBTlRZPC9zdHJvbmc+LjwvZW0+Ci0gKiBTZWUgPGEgaHJlZj0naHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZyc+aHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZzwvYT4KLSAqIGZvciBmdXJ0aGVyIGluZm9ybWF0aW9uLgotICogPC9ibG9ja3F1b3RlPgotICoKLSAqIDxwPlRoaXMgd2FzIHRoZSBtYWluIGV2ZW50IHN1cHBsaWVyIGludGVyZmFjZSBmb3IgU0FYMTsgaXQgaGFzCi0gKiBiZWVuIHJlcGxhY2VkIGluIFNBWDIgYnkge0BsaW5rIG9yZy54bWwuc2F4LlhNTFJlYWRlciBYTUxSZWFkZXJ9LAotICogd2hpY2ggaW5jbHVkZXMgTmFtZXNwYWNlIHN1cHBvcnQgYW5kIHNvcGhpc3RpY2F0ZWQgY29uZmlndXJhYmlsaXR5Ci0gKiBhbmQgZXh0ZW5zaWJpbGl0eS48L3A+Ci0gKgotICogPHA+QWxsIFNBWDEgcGFyc2VycyBtdXN0IGltcGxlbWVudCB0aGlzIGJhc2ljIGludGVyZmFjZTogaXQgYWxsb3dzCi0gKiBhcHBsaWNhdGlvbnMgdG8gcmVnaXN0ZXIgaGFuZGxlcnMgZm9yIGRpZmZlcmVudCB0eXBlcyBvZiBldmVudHMKLSAqIGFuZCB0byBpbml0aWF0ZSBhIHBhcnNlIGZyb20gYSBVUkksIG9yIGEgY2hhcmFjdGVyIHN0cmVhbS48L3A+Ci0gKgotICogPHA+QWxsIFNBWDEgcGFyc2VycyBtdXN0IGFsc28gaW1wbGVtZW50IGEgemVyby1hcmd1bWVudCBjb25zdHJ1Y3RvcgotICogKHRob3VnaCBvdGhlciBjb25zdHJ1Y3RvcnMgYXJlIGFsc28gYWxsb3dlZCkuPC9wPgotICoKLSAqIDxwPlNBWDEgcGFyc2VycyBhcmUgcmV1c2FibGUgYnV0IG5vdCByZS1lbnRyYW50OiB0aGUgYXBwbGljYXRpb24KLSAqIG1heSByZXVzZSBhIHBhcnNlciBvYmplY3QgKHBvc3NpYmx5IHdpdGggYSBkaWZmZXJlbnQgaW5wdXQgc291cmNlKQotICogb25jZSB0aGUgZmlyc3QgcGFyc2UgaGFzIGNvbXBsZXRlZCBzdWNjZXNzZnVsbHksIGJ1dCBpdCBtYXkgbm90Ci0gKiBpbnZva2UgdGhlIHBhcnNlKCkgbWV0aG9kcyByZWN1cnNpdmVseSB3aXRoaW4gYSBwYXJzZS48L3A+Ci0gKgotICogQGRlcHJlY2F0ZWQgVGhpcyBpbnRlcmZhY2UgaGFzIGJlZW4gcmVwbGFjZWQgYnkgdGhlIFNBWDIKLSAqICAgICAgICAgICAgIHtAbGluayBvcmcueG1sLnNheC5YTUxSZWFkZXIgWE1MUmVhZGVyfQotICogICAgICAgICAgICAgaW50ZXJmYWNlLCB3aGljaCBpbmNsdWRlcyBOYW1lc3BhY2Ugc3VwcG9ydC4KLSAqIEBzaW5jZSBTQVggMS4wCi0gKiBAYXV0aG9yIERhdmlkIE1lZ2dpbnNvbgotICogQHNlZSBvcmcueG1sLnNheC5FbnRpdHlSZXNvbHZlcgotICogQHNlZSBvcmcueG1sLnNheC5EVERIYW5kbGVyCi0gKiBAc2VlIG9yZy54bWwuc2F4LkRvY3VtZW50SGFuZGxlcgotICogQHNlZSBvcmcueG1sLnNheC5FcnJvckhhbmRsZXIKLSAqIEBzZWUgb3JnLnhtbC5zYXguSGFuZGxlckJhc2UKLSAqIEBzZWUgb3JnLnhtbC5zYXguSW5wdXRTb3VyY2UKLSAqLwotcHVibGljIGludGVyZmFjZSBQYXJzZXIKLXsKLQotICAgIC8qKgotICAgICAqIEFsbG93IGFuIGFwcGxpY2F0aW9uIHRvIHJlcXVlc3QgYSBsb2NhbGUgZm9yIGVycm9ycyBhbmQgd2FybmluZ3MuCi0gICAgICoKLSAgICAgKiA8cD5TQVggcGFyc2VycyBhcmUgbm90IHJlcXVpcmVkIHRvIHByb3ZpZGUgbG9jYWxpc2F0aW9uIGZvciBlcnJvcnMKLSAgICAgKiBhbmQgd2FybmluZ3M7IGlmIHRoZXkgY2Fubm90IHN1cHBvcnQgdGhlIHJlcXVlc3RlZCBsb2NhbGUsCi0gICAgICogaG93ZXZlciwgdGhleSBtdXN0IHRocm93IGEgU0FYIGV4Y2VwdGlvbi4gIEFwcGxpY2F0aW9ucyBtYXkKLSAgICAgKiBub3QgcmVxdWVzdCBhIGxvY2FsZSBjaGFuZ2UgaW4gdGhlIG1pZGRsZSBvZiBhIHBhcnNlLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBsb2NhbGUgQSBKYXZhIExvY2FsZSBvYmplY3QuCi0gICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gVGhyb3dzIGFuIGV4Y2VwdGlvbgotICAgICAqICAgICAgICAgICAgKHVzaW5nIHRoZSBwcmV2aW91cyBvciBkZWZhdWx0IGxvY2FsZSkgaWYgdGhlCi0gICAgICogICAgICAgICAgICByZXF1ZXN0ZWQgbG9jYWxlIGlzIG5vdCBzdXBwb3J0ZWQuCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LlNBWFBhcnNlRXhjZXB0aW9uCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2V0TG9jYWxlIChMb2NhbGUgbG9jYWxlKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uOwotCi0KLSAgICAvKioKLSAgICAgKiBBbGxvdyBhbiBhcHBsaWNhdGlvbiB0byByZWdpc3RlciBhIGN1c3RvbSBlbnRpdHkgcmVzb2x2ZXIuCi0gICAgICoKLSAgICAgKiA8cD5JZiB0aGUgYXBwbGljYXRpb24gZG9lcyBub3QgcmVnaXN0ZXIgYW4gZW50aXR5IHJlc29sdmVyLCB0aGUKLSAgICAgKiBTQVggcGFyc2VyIHdpbGwgcmVzb2x2ZSBzeXN0ZW0gaWRlbnRpZmllcnMgYW5kIG9wZW4gY29ubmVjdGlvbnMKLSAgICAgKiB0byBlbnRpdGllcyBpdHNlbGYgKHRoaXMgaXMgdGhlIGRlZmF1bHQgYmVoYXZpb3VyIGltcGxlbWVudGVkIGluCi0gICAgICogSGFuZGxlckJhc2UpLjwvcD4KLSAgICAgKgotICAgICAqIDxwPkFwcGxpY2F0aW9ucyBtYXkgcmVnaXN0ZXIgYSBuZXcgb3IgZGlmZmVyZW50IGVudGl0eSByZXNvbHZlcgotICAgICAqIGluIHRoZSBtaWRkbGUgb2YgYSBwYXJzZSwgYW5kIHRoZSBTQVggcGFyc2VyIG11c3QgYmVnaW4gdXNpbmcKLSAgICAgKiB0aGUgbmV3IHJlc29sdmVyIGltbWVkaWF0ZWx5LjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSByZXNvbHZlciBUaGUgb2JqZWN0IGZvciByZXNvbHZpbmcgZW50aXRpZXMuCi0gICAgICogQHNlZSBFbnRpdHlSZXNvbHZlcgotICAgICAqIEBzZWUgSGFuZGxlckJhc2UKLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRFbnRpdHlSZXNvbHZlciAoRW50aXR5UmVzb2x2ZXIgcmVzb2x2ZXIpOwotCi0KLSAgICAvKioKLSAgICAgKiBBbGxvdyBhbiBhcHBsaWNhdGlvbiB0byByZWdpc3RlciBhIERURCBldmVudCBoYW5kbGVyLgotICAgICAqCi0gICAgICogPHA+SWYgdGhlIGFwcGxpY2F0aW9uIGRvZXMgbm90IHJlZ2lzdGVyIGEgRFREIGhhbmRsZXIsIGFsbCBEVEQKLSAgICAgKiBldmVudHMgcmVwb3J0ZWQgYnkgdGhlIFNBWCBwYXJzZXIgd2lsbCBiZSBzaWxlbnRseQotICAgICAqIGlnbm9yZWQgKHRoaXMgaXMgdGhlIGRlZmF1bHQgYmVoYXZpb3VyIGltcGxlbWVudGVkIGJ5Ci0gICAgICogSGFuZGxlckJhc2UpLjwvcD4KLSAgICAgKgotICAgICAqIDxwPkFwcGxpY2F0aW9ucyBtYXkgcmVnaXN0ZXIgYSBuZXcgb3IgZGlmZmVyZW50Ci0gICAgICogaGFuZGxlciBpbiB0aGUgbWlkZGxlIG9mIGEgcGFyc2UsIGFuZCB0aGUgU0FYIHBhcnNlciBtdXN0Ci0gICAgICogYmVnaW4gdXNpbmcgdGhlIG5ldyBoYW5kbGVyIGltbWVkaWF0ZWx5LjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBoYW5kbGVyIFRoZSBEVEQgaGFuZGxlci4KLSAgICAgKiBAc2VlIERUREhhbmRsZXIKLSAgICAgKiBAc2VlIEhhbmRsZXJCYXNlCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2V0RFRESGFuZGxlciAoRFRESGFuZGxlciBoYW5kbGVyKTsKLQotCi0gICAgLyoqCi0gICAgICogQWxsb3cgYW4gYXBwbGljYXRpb24gdG8gcmVnaXN0ZXIgYSBkb2N1bWVudCBldmVudCBoYW5kbGVyLgotICAgICAqCi0gICAgICogPHA+SWYgdGhlIGFwcGxpY2F0aW9uIGRvZXMgbm90IHJlZ2lzdGVyIGEgZG9jdW1lbnQgaGFuZGxlciwgYWxsCi0gICAgICogZG9jdW1lbnQgZXZlbnRzIHJlcG9ydGVkIGJ5IHRoZSBTQVggcGFyc2VyIHdpbGwgYmUgc2lsZW50bHkKLSAgICAgKiBpZ25vcmVkICh0aGlzIGlzIHRoZSBkZWZhdWx0IGJlaGF2aW91ciBpbXBsZW1lbnRlZCBieQotICAgICAqIEhhbmRsZXJCYXNlKS48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5BcHBsaWNhdGlvbnMgbWF5IHJlZ2lzdGVyIGEgbmV3IG9yIGRpZmZlcmVudCBoYW5kbGVyIGluIHRoZQotICAgICAqIG1pZGRsZSBvZiBhIHBhcnNlLCBhbmQgdGhlIFNBWCBwYXJzZXIgbXVzdCBiZWdpbiB1c2luZyB0aGUgbmV3Ci0gICAgICogaGFuZGxlciBpbW1lZGlhdGVseS48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gaGFuZGxlciBUaGUgZG9jdW1lbnQgaGFuZGxlci4KLSAgICAgKiBAc2VlIERvY3VtZW50SGFuZGxlcgotICAgICAqIEBzZWUgSGFuZGxlckJhc2UKLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXREb2N1bWVudEhhbmRsZXIgKERvY3VtZW50SGFuZGxlciBoYW5kbGVyKTsKLQotCi0gICAgLyoqCi0gICAgICogQWxsb3cgYW4gYXBwbGljYXRpb24gdG8gcmVnaXN0ZXIgYW4gZXJyb3IgZXZlbnQgaGFuZGxlci4KLSAgICAgKgotICAgICAqIDxwPklmIHRoZSBhcHBsaWNhdGlvbiBkb2VzIG5vdCByZWdpc3RlciBhbiBlcnJvciBldmVudCBoYW5kbGVyLAotICAgICAqIGFsbCBlcnJvciBldmVudHMgcmVwb3J0ZWQgYnkgdGhlIFNBWCBwYXJzZXIgd2lsbCBiZSBzaWxlbnRseQotICAgICAqIGlnbm9yZWQsIGV4Y2VwdCBmb3IgZmF0YWxFcnJvciwgd2hpY2ggd2lsbCB0aHJvdyBhIFNBWEV4Y2VwdGlvbgotICAgICAqICh0aGlzIGlzIHRoZSBkZWZhdWx0IGJlaGF2aW91ciBpbXBsZW1lbnRlZCBieSBIYW5kbGVyQmFzZSkuPC9wPgotICAgICAqCi0gICAgICogPHA+QXBwbGljYXRpb25zIG1heSByZWdpc3RlciBhIG5ldyBvciBkaWZmZXJlbnQgaGFuZGxlciBpbiB0aGUKLSAgICAgKiBtaWRkbGUgb2YgYSBwYXJzZSwgYW5kIHRoZSBTQVggcGFyc2VyIG11c3QgYmVnaW4gdXNpbmcgdGhlIG5ldwotICAgICAqIGhhbmRsZXIgaW1tZWRpYXRlbHkuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGhhbmRsZXIgVGhlIGVycm9yIGhhbmRsZXIuCi0gICAgICogQHNlZSBFcnJvckhhbmRsZXIKLSAgICAgKiBAc2VlIFNBWEV4Y2VwdGlvbgotICAgICAqIEBzZWUgSGFuZGxlckJhc2UKLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRFcnJvckhhbmRsZXIgKEVycm9ySGFuZGxlciBoYW5kbGVyKTsKLQotCi0gICAgLyoqCi0gICAgICogUGFyc2UgYW4gWE1MIGRvY3VtZW50LgotICAgICAqCi0gICAgICogPHA+VGhlIGFwcGxpY2F0aW9uIGNhbiB1c2UgdGhpcyBtZXRob2QgdG8gaW5zdHJ1Y3QgdGhlIFNBWCBwYXJzZXIKLSAgICAgKiB0byBiZWdpbiBwYXJzaW5nIGFuIFhNTCBkb2N1bWVudCBmcm9tIGFueSB2YWxpZCBpbnB1dAotICAgICAqIHNvdXJjZSAoYSBjaGFyYWN0ZXIgc3RyZWFtLCBhIGJ5dGUgc3RyZWFtLCBvciBhIFVSSSkuPC9wPgotICAgICAqCi0gICAgICogPHA+QXBwbGljYXRpb25zIG1heSBub3QgaW52b2tlIHRoaXMgbWV0aG9kIHdoaWxlIGEgcGFyc2UgaXMgaW4KLSAgICAgKiBwcm9ncmVzcyAodGhleSBzaG91bGQgY3JlYXRlIGEgbmV3IFBhcnNlciBpbnN0ZWFkIGZvciBlYWNoCi0gICAgICogYWRkaXRpb25hbCBYTUwgZG9jdW1lbnQpLiAgT25jZSBhIHBhcnNlIGlzIGNvbXBsZXRlLCBhbgotICAgICAqIGFwcGxpY2F0aW9uIG1heSByZXVzZSB0aGUgc2FtZSBQYXJzZXIgb2JqZWN0LCBwb3NzaWJseSB3aXRoIGEKLSAgICAgKiBkaWZmZXJlbnQgaW5wdXQgc291cmNlLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzb3VyY2UgVGhlIGlucHV0IHNvdXJjZSBmb3IgdGhlIHRvcC1sZXZlbCBvZiB0aGUKLSAgICAgKiAgICAgICAgWE1MIGRvY3VtZW50LgotICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAgICogQGV4Y2VwdGlvbiBqYXZhLmlvLklPRXhjZXB0aW9uIEFuIElPIGV4Y2VwdGlvbiBmcm9tIHRoZSBwYXJzZXIsCi0gICAgICogICAgICAgICAgICBwb3NzaWJseSBmcm9tIGEgYnl0ZSBzdHJlYW0gb3IgY2hhcmFjdGVyIHN0cmVhbQotICAgICAqICAgICAgICAgICAgc3VwcGxpZWQgYnkgdGhlIGFwcGxpY2F0aW9uLgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguSW5wdXRTb3VyY2UKLSAgICAgKiBAc2VlICNwYXJzZShqYXZhLmxhbmcuU3RyaW5nKQotICAgICAqIEBzZWUgI3NldEVudGl0eVJlc29sdmVyCi0gICAgICogQHNlZSAjc2V0RFRESGFuZGxlcgotICAgICAqIEBzZWUgI3NldERvY3VtZW50SGFuZGxlcgotICAgICAqIEBzZWUgI3NldEVycm9ySGFuZGxlcgotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHBhcnNlIChJbnB1dFNvdXJjZSBzb3VyY2UpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24sIElPRXhjZXB0aW9uOwotCi0KLSAgICAvKioKLSAgICAgKiBQYXJzZSBhbiBYTUwgZG9jdW1lbnQgZnJvbSBhIHN5c3RlbSBpZGVudGlmaWVyIChVUkkpLgotICAgICAqCi0gICAgICogPHA+VGhpcyBtZXRob2QgaXMgYSBzaG9ydGN1dCBmb3IgdGhlIGNvbW1vbiBjYXNlIG9mIHJlYWRpbmcgYQotICAgICAqIGRvY3VtZW50IGZyb20gYSBzeXN0ZW0gaWRlbnRpZmllci4gIEl0IGlzIHRoZSBleGFjdAotICAgICAqIGVxdWl2YWxlbnQgb2YgdGhlIGZvbGxvd2luZzo8L3A+Ci0gICAgICoKLSAgICAgKiA8cHJlPgotICAgICAqIHBhcnNlKG5ldyBJbnB1dFNvdXJjZShzeXN0ZW1JZCkpOwotICAgICAqIDwvcHJlPgotICAgICAqCi0gICAgICogPHA+SWYgdGhlIHN5c3RlbSBpZGVudGlmaWVyIGlzIGEgVVJMLCBpdCBtdXN0IGJlIGZ1bGx5IHJlc29sdmVkCi0gICAgICogYnkgdGhlIGFwcGxpY2F0aW9uIGJlZm9yZSBpdCBpcyBwYXNzZWQgdG8gdGhlIHBhcnNlci48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gc3lzdGVtSWQgVGhlIHN5c3RlbSBpZGVudGlmaWVyIChVUkkpLgotICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAgICogQGV4Y2VwdGlvbiBqYXZhLmlvLklPRXhjZXB0aW9uIEFuIElPIGV4Y2VwdGlvbiBmcm9tIHRoZSBwYXJzZXIsCi0gICAgICogICAgICAgICAgICBwb3NzaWJseSBmcm9tIGEgYnl0ZSBzdHJlYW0gb3IgY2hhcmFjdGVyIHN0cmVhbQotICAgICAqICAgICAgICAgICAgc3VwcGxpZWQgYnkgdGhlIGFwcGxpY2F0aW9uLgotICAgICAqIEBzZWUgI3BhcnNlKG9yZy54bWwuc2F4LklucHV0U291cmNlKQotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHBhcnNlIChTdHJpbmcgc3lzdGVtSWQpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24sIElPRXhjZXB0aW9uOwotCi19Ci0KLS8vIGVuZCBvZiBQYXJzZXIuamF2YQpkaWZmIC0tZ2l0IGEvc3JjL29yZy94bWwvc2F4L1NBWEV4Y2VwdGlvbi5qYXZhIGIvc3JjL29yZy94bWwvc2F4L1NBWEV4Y2VwdGlvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2NWIyNWNjLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcveG1sL3NheC9TQVhFeGNlcHRpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE4OCArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDAwLCAyMDA1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vLyBTQVggZXhjZXB0aW9uIGNsYXNzLgotLy8gaHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZwotLy8gTm8gd2FycmFudHk7IG5vIGNvcHlyaWdodCAtLSB1c2UgdGhpcyBhcyB5b3Ugd2lsbC4KLS8vICRJZDogU0FYRXhjZXB0aW9uLmphdmEsdiAxLjMgMjAwNC8xMS8wMyAyMjo1NTozMiBqc3V0dG9yIEV4cCAkCi0KLXBhY2thZ2Ugb3JnLnhtbC5zYXg7Ci0KLS8qKgotICogRW5jYXBzdWxhdGUgYSBnZW5lcmFsIFNBWCBlcnJvciBvciB3YXJuaW5nLgotICoKLSAqIDxibG9ja3F1b3RlPgotICogPGVtPlRoaXMgbW9kdWxlLCBib3RoIHNvdXJjZSBjb2RlIGFuZCBkb2N1bWVudGF0aW9uLCBpcyBpbiB0aGUKLSAqIFB1YmxpYyBEb21haW4sIGFuZCBjb21lcyB3aXRoIDxzdHJvbmc+Tk8gV0FSUkFOVFk8L3N0cm9uZz4uPC9lbT4KLSAqIFNlZSA8YSBocmVmPSdodHRwOi8vd3d3LnNheHByb2plY3Qub3JnJz5odHRwOi8vd3d3LnNheHByb2plY3Qub3JnPC9hPgotICogZm9yIGZ1cnRoZXIgaW5mb3JtYXRpb24uCi0gKiA8L2Jsb2NrcXVvdGU+Ci0gKgotICogPHA+VGhpcyBjbGFzcyBjYW4gY29udGFpbiBiYXNpYyBlcnJvciBvciB3YXJuaW5nIGluZm9ybWF0aW9uIGZyb20KLSAqIGVpdGhlciB0aGUgWE1MIHBhcnNlciBvciB0aGUgYXBwbGljYXRpb246IGEgcGFyc2VyIHdyaXRlciBvcgotICogYXBwbGljYXRpb24gd3JpdGVyIGNhbiBzdWJjbGFzcyBpdCB0byBwcm92aWRlIGFkZGl0aW9uYWwKLSAqIGZ1bmN0aW9uYWxpdHkuICBTQVggaGFuZGxlcnMgbWF5IHRocm93IHRoaXMgZXhjZXB0aW9uIG9yCi0gKiBhbnkgZXhjZXB0aW9uIHN1YmNsYXNzZWQgZnJvbSBpdC48L3A+Ci0gKgotICogPHA+SWYgdGhlIGFwcGxpY2F0aW9uIG5lZWRzIHRvIHBhc3MgdGhyb3VnaCBvdGhlciB0eXBlcyBvZgotICogZXhjZXB0aW9ucywgaXQgbXVzdCB3cmFwIHRob3NlIGV4Y2VwdGlvbnMgaW4gYSBTQVhFeGNlcHRpb24KLSAqIG9yIGFuIGV4Y2VwdGlvbiBkZXJpdmVkIGZyb20gYSBTQVhFeGNlcHRpb24uPC9wPgotICoKLSAqIDxwPklmIHRoZSBwYXJzZXIgb3IgYXBwbGljYXRpb24gbmVlZHMgdG8gaW5jbHVkZSBpbmZvcm1hdGlvbiBhYm91dCBhCi0gKiBzcGVjaWZpYyBsb2NhdGlvbiBpbiBhbiBYTUwgZG9jdW1lbnQsIGl0IHNob3VsZCB1c2UgdGhlCi0gKiB7QGxpbmsgb3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb24gU0FYUGFyc2VFeGNlcHRpb259IHN1YmNsYXNzLjwvcD4KLSAqCi0gKiBAc2luY2UgU0FYIDEuMAotICogQGF1dGhvciBEYXZpZCBNZWdnaW5zb24KLSAqIEB2ZXJzaW9uIDIuMC4xIChzYXgycjIpCi0gKiBAc2VlIG9yZy54bWwuc2F4LlNBWFBhcnNlRXhjZXB0aW9uCi0gKi8KLXB1YmxpYyBjbGFzcyBTQVhFeGNlcHRpb24gZXh0ZW5kcyBFeGNlcHRpb24gewotCi0KLSAgICAvKioKLSAgICAgKiBDcmVhdGUgYSBuZXcgU0FYRXhjZXB0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBTQVhFeGNlcHRpb24gKCkKLSAgICB7Ci0gICAgICAgIHN1cGVyKCk7Ci0gICAgICAgIHRoaXMuZXhjZXB0aW9uID0gbnVsbDsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIENyZWF0ZSBhIG5ldyBTQVhFeGNlcHRpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbWVzc2FnZSBUaGUgZXJyb3Igb3Igd2FybmluZyBtZXNzYWdlLgotICAgICAqLwotICAgIHB1YmxpYyBTQVhFeGNlcHRpb24gKFN0cmluZyBtZXNzYWdlKSB7Ci0gICAgICAgIHN1cGVyKG1lc3NhZ2UpOwotICAgICAgICB0aGlzLmV4Y2VwdGlvbiA9IG51bGw7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBDcmVhdGUgYSBuZXcgU0FYRXhjZXB0aW9uIHdyYXBwaW5nIGFuIGV4aXN0aW5nIGV4Y2VwdGlvbi4KLSAgICAgKgotICAgICAqIDxwPlRoZSBleGlzdGluZyBleGNlcHRpb24gd2lsbCBiZSBlbWJlZGRlZCBpbiB0aGUgbmV3Ci0gICAgICogb25lLCBhbmQgaXRzIG1lc3NhZ2Ugd2lsbCBiZWNvbWUgdGhlIGRlZmF1bHQgbWVzc2FnZSBmb3IKLSAgICAgKiB0aGUgU0FYRXhjZXB0aW9uLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlIFRoZSBleGNlcHRpb24gdG8gYmUgd3JhcHBlZCBpbiBhIFNBWEV4Y2VwdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU0FYRXhjZXB0aW9uIChFeGNlcHRpb24gZSkKLSAgICB7Ci0gICAgICAgIHN1cGVyKCk7Ci0gICAgICAgIHRoaXMuZXhjZXB0aW9uID0gZTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIENyZWF0ZSBhIG5ldyBTQVhFeGNlcHRpb24gZnJvbSBhbiBleGlzdGluZyBleGNlcHRpb24uCi0gICAgICoKLSAgICAgKiA8cD5UaGUgZXhpc3RpbmcgZXhjZXB0aW9uIHdpbGwgYmUgZW1iZWRkZWQgaW4gdGhlIG5ldwotICAgICAqIG9uZSwgYnV0IHRoZSBuZXcgZXhjZXB0aW9uIHdpbGwgaGF2ZSBpdHMgb3duIG1lc3NhZ2UuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIG1lc3NhZ2UgVGhlIGRldGFpbCBtZXNzYWdlLgotICAgICAqIEBwYXJhbSBlIFRoZSBleGNlcHRpb24gdG8gYmUgd3JhcHBlZCBpbiBhIFNBWEV4Y2VwdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU0FYRXhjZXB0aW9uIChTdHJpbmcgbWVzc2FnZSwgRXhjZXB0aW9uIGUpCi0gICAgewotICAgICAgICBzdXBlcihtZXNzYWdlKTsKLSAgICAgICAgdGhpcy5leGNlcHRpb24gPSBlOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIGEgZGV0YWlsIG1lc3NhZ2UgZm9yIHRoaXMgZXhjZXB0aW9uLgotICAgICAqCi0gICAgICogPHA+SWYgdGhlcmUgaXMgYW4gZW1iZWRkZWQgZXhjZXB0aW9uLCBhbmQgaWYgdGhlIFNBWEV4Y2VwdGlvbgotICAgICAqIGhhcyBubyBkZXRhaWwgbWVzc2FnZSBvZiBpdHMgb3duLCB0aGlzIG1ldGhvZCB3aWxsIHJldHVybgotICAgICAqIHRoZSBkZXRhaWwgbWVzc2FnZSBmcm9tIHRoZSBlbWJlZGRlZCBleGNlcHRpb24uPC9wPgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgZXJyb3Igb3Igd2FybmluZyBtZXNzYWdlLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TWVzc2FnZSAoKQotICAgIHsKLSAgICAgICAgU3RyaW5nIG1lc3NhZ2UgPSBzdXBlci5nZXRNZXNzYWdlKCk7Ci0KLSAgICAgICAgaWYgKG1lc3NhZ2UgPT0gbnVsbCAmJiBleGNlcHRpb24gIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIGV4Y2VwdGlvbi5nZXRNZXNzYWdlKCk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gbWVzc2FnZTsKLSAgICAgICAgfQotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSBlbWJlZGRlZCBleGNlcHRpb24sIGlmIGFueS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIGVtYmVkZGVkIGV4Y2VwdGlvbiwgb3IgbnVsbCBpZiB0aGVyZSBpcyBub25lLgotICAgICAqLwotICAgIHB1YmxpYyBFeGNlcHRpb24gZ2V0RXhjZXB0aW9uICgpCi0gICAgewotICAgICAgICByZXR1cm4gZXhjZXB0aW9uOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybiB0aGUgY2F1c2Ugb2YgdGhlIGV4Y2VwdGlvbgotICAgICAqCi0gICAgICogQHJldHVybiBSZXR1cm4gdGhlIGNhdXNlIG9mIHRoZSBleGNlcHRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgVGhyb3dhYmxlIGdldENhdXNlKCkgewotICAgICAgICByZXR1cm4gZXhjZXB0aW9uOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIE92ZXJyaWRlIHRvU3RyaW5nIHRvIHBpY2sgdXAgYW55IGVtYmVkZGVkIGV4Y2VwdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gQSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBleGNlcHRpb24uCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyB0b1N0cmluZyAoKQotICAgIHsKLSAgICAgICAgaWYgKGV4Y2VwdGlvbiAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gc3VwZXIudG9TdHJpbmcoKSArICJcbiIgKyBleGNlcHRpb24udG9TdHJpbmcoKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiBzdXBlci50b1N0cmluZygpOwotICAgICAgICB9Ci0gICAgfQotCi0KLQotICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLSAgICAvLyBJbnRlcm5hbCBzdGF0ZS4KLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0KLQotICAgIC8qKgotICAgICAqIEBzZXJpYWwgVGhlIGVtYmVkZGVkIGV4Y2VwdGlvbiBpZiB0dW5uZWxsaW5nLCBvciBudWxsLgotICAgICAqLwotICAgIHByaXZhdGUgRXhjZXB0aW9uIGV4Y2VwdGlvbjsKLQotICAgIC8vIEFkZGVkIHNlcmlhbFZlcnNpb25VSUQgdG8gcHJlc2VydmUgYmluYXJ5IGNvbXBhdGliaWxpdHkKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNTgzMjQxNjM1MjU2MDczNzYwTDsKLX0KLQotLy8gZW5kIG9mIFNBWEV4Y2VwdGlvbi5qYXZhCmRpZmYgLS1naXQgYS9zcmMvb3JnL3htbC9zYXgvU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbi5qYXZhIGIvc3JjL29yZy94bWwvc2F4L1NBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZjk2M2UwMS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3htbC9zYXgvU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNzkgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwMCwgMjAwNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLy8gU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbi5qYXZhIC0gdW5yZWNvZ25pemVkIGZlYXR1cmUgb3IgdmFsdWUuCi0vLyBodHRwOi8vd3d3LnNheHByb2plY3Qub3JnCi0vLyBXcml0dGVuIGJ5IERhdmlkIE1lZ2dpbnNvbgotLy8gTk8gV0FSUkFOVFkhICBUaGlzIGNsYXNzIGlzIGluIHRoZSBQdWJsaWMgRG9tYWluLgotLy8gJElkOiBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uLmphdmEsdiAxLjMgMjAwNC8xMS8wMyAyMjo1NTozMiBqc3V0dG9yIEV4cCAkCi0KLXBhY2thZ2Ugb3JnLnhtbC5zYXg7Ci0KLQotLyoqCi0gKiBFeGNlcHRpb24gY2xhc3MgZm9yIGFuIHVucmVjb2duaXplZCBpZGVudGlmaWVyLgotICoKLSAqIDxibG9ja3F1b3RlPgotICogPGVtPlRoaXMgbW9kdWxlLCBib3RoIHNvdXJjZSBjb2RlIGFuZCBkb2N1bWVudGF0aW9uLCBpcyBpbiB0aGUKLSAqIFB1YmxpYyBEb21haW4sIGFuZCBjb21lcyB3aXRoIDxzdHJvbmc+Tk8gV0FSUkFOVFk8L3N0cm9uZz4uPC9lbT4KLSAqIFNlZSA8YSBocmVmPSdodHRwOi8vd3d3LnNheHByb2plY3Qub3JnJz5odHRwOi8vd3d3LnNheHByb2plY3Qub3JnPC9hPgotICogZm9yIGZ1cnRoZXIgaW5mb3JtYXRpb24uCi0gKiA8L2Jsb2NrcXVvdGU+Ci0gKgotICogPHA+QW4gWE1MUmVhZGVyIHdpbGwgdGhyb3cgdGhpcyBleGNlcHRpb24gd2hlbiBpdCBmaW5kcyBhbgotICogdW5yZWNvZ25pemVkIGZlYXR1cmUgb3IgcHJvcGVydHkgaWRlbnRpZmllcjsgU0FYIGFwcGxpY2F0aW9ucyBhbmQKLSAqIGV4dGVuc2lvbnMgbWF5IHVzZSB0aGlzIGNsYXNzIGZvciBvdGhlciwgc2ltaWxhciBwdXJwb3Nlcy48L3A+Ci0gKgotICogQHNpbmNlIFNBWCAyLjAKLSAqIEBhdXRob3IgRGF2aWQgTWVnZ2luc29uCi0gKiBAc2VlIG9yZy54bWwuc2F4LlNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbgotICovCi1wdWJsaWMgY2xhc3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiBleHRlbmRzIFNBWEV4Y2VwdGlvbgotewotCi0gICAgLyoqCi0gICAgICogRGVmYXVsdCBjb25zdHJ1Y3Rvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiAoKQotICAgIHsKLSAgICAgICAgc3VwZXIoKTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdCBhIG5ldyBleGNlcHRpb24gd2l0aCB0aGUgZ2l2ZW4gbWVzc2FnZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBtZXNzYWdlIFRoZSB0ZXh0IG1lc3NhZ2Ugb2YgdGhlIGV4Y2VwdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiAoU3RyaW5nIG1lc3NhZ2UpCi0gICAgewotICAgICAgICBzdXBlcihtZXNzYWdlKTsKLSAgICB9Ci0KLSAgICAvLyBBZGRlZCBzZXJpYWxWZXJzaW9uVUlEIHRvIHByZXNlcnZlIGJpbmFyeSBjb21wYXRpYmlsaXR5Ci0gICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDU0NDA1MDY2MjA1MDk1NTcyMTNMOwotfQotCi0vLyBlbmQgb2YgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbi5qYXZhCmRpZmYgLS1naXQgYS9zcmMvb3JnL3htbC9zYXgvU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uLmphdmEgYi9zcmMvb3JnL3htbC9zYXgvU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGQzMWY0OWUuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy94bWwvc2F4L1NBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNzkgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwMCwgMjAwNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLy8gU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uLmphdmEgLSB1bnN1cHBvcnRlZCBmZWF0dXJlIG9yIHZhbHVlLgotLy8gaHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZwotLy8gV3JpdHRlbiBieSBEYXZpZCBNZWdnaW5zb24KLS8vIE5PIFdBUlJBTlRZISAgVGhpcyBjbGFzcyBpcyBpbiB0aGUgUHVibGljIERvbWFpbi4KLS8vICRJZDogU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uLmphdmEsdiAxLjQgMjAwNC8xMS8wMyAyMjo1NTozMiBqc3V0dG9yIEV4cCAkCi0KLXBhY2thZ2Ugb3JnLnhtbC5zYXg7Ci0KLS8qKgotICogRXhjZXB0aW9uIGNsYXNzIGZvciBhbiB1bnN1cHBvcnRlZCBvcGVyYXRpb24uCi0gKgotICogPGJsb2NrcXVvdGU+Ci0gKiA8ZW0+VGhpcyBtb2R1bGUsIGJvdGggc291cmNlIGNvZGUgYW5kIGRvY3VtZW50YXRpb24sIGlzIGluIHRoZQotICogUHVibGljIERvbWFpbiwgYW5kIGNvbWVzIHdpdGggPHN0cm9uZz5OTyBXQVJSQU5UWTwvc3Ryb25nPi48L2VtPgotICogU2VlIDxhIGhyZWY9J2h0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmcnPmh0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmc8L2E+Ci0gKiBmb3IgZnVydGhlciBpbmZvcm1hdGlvbi4KLSAqIDwvYmxvY2txdW90ZT4KLSAqCi0gKiA8cD5BbiBYTUxSZWFkZXIgd2lsbCB0aHJvdyB0aGlzIGV4Y2VwdGlvbiB3aGVuIGl0IHJlY29nbml6ZXMgYQotICogZmVhdHVyZSBvciBwcm9wZXJ0eSBpZGVudGlmaWVyLCBidXQgY2Fubm90IHBlcmZvcm0gdGhlIHJlcXVlc3RlZAotICogb3BlcmF0aW9uIChzZXR0aW5nIGEgc3RhdGUgb3IgdmFsdWUpLiAgT3RoZXIgU0FYMiBhcHBsaWNhdGlvbnMgYW5kCi0gKiBleHRlbnNpb25zIG1heSB1c2UgdGhpcyBjbGFzcyBmb3Igc2ltaWxhciBwdXJwb3Nlcy48L3A+Ci0gKgotICogQHNpbmNlIFNBWCAyLjAKLSAqIEBhdXRob3IgRGF2aWQgTWVnZ2luc29uCi0gKiBAc2VlIG9yZy54bWwuc2F4LlNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24KLSAqLwotcHVibGljIGNsYXNzIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBleHRlbmRzIFNBWEV4Y2VwdGlvbgotewotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0IGEgbmV3IGV4Y2VwdGlvbiB3aXRoIG5vIG1lc3NhZ2UuCi0gICAgICovCi0gICAgcHVibGljIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiAoKQotICAgIHsKLSAgICAgICAgc3VwZXIoKTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdCBhIG5ldyBleGNlcHRpb24gd2l0aCB0aGUgZ2l2ZW4gbWVzc2FnZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBtZXNzYWdlIFRoZSB0ZXh0IG1lc3NhZ2Ugb2YgdGhlIGV4Y2VwdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIChTdHJpbmcgbWVzc2FnZSkKLSAgICB7Ci0gICAgICAgIHN1cGVyKG1lc3NhZ2UpOwotICAgIH0KLQotICAgIC8vIEFkZGVkIHNlcmlhbFZlcnNpb25VSUQgdG8gcHJlc2VydmUgYmluYXJ5IGNvbXBhdGliaWxpdHkKLSAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTE0MjI4MTg5MzQ2NDE4MjM4NDZMOwotfQotCi0vLyBlbmQgb2YgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uLmphdmEKZGlmZiAtLWdpdCBhL3NyYy9vcmcveG1sL3NheC9TQVhQYXJzZUV4Y2VwdGlvbi5qYXZhIGIvc3JjL29yZy94bWwvc2F4L1NBWFBhcnNlRXhjZXB0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDM4ZjM3ZmYuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy94bWwvc2F4L1NBWFBhcnNlRXhjZXB0aW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzMTMgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwMCwgMjAwNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLy8gU0FYIGV4Y2VwdGlvbiBjbGFzcy4KLS8vIGh0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmcKLS8vIE5vIHdhcnJhbnR5OyBubyBjb3B5cmlnaHQgLS0gdXNlIHRoaXMgYXMgeW91IHdpbGwuCi0vLyAkSWQ6IFNBWFBhcnNlRXhjZXB0aW9uLmphdmEsdiAxLjIgMjAwNC8xMS8wMyAyMjo1NTozMiBqc3V0dG9yIEV4cCAkCi0KLXBhY2thZ2Ugb3JnLnhtbC5zYXg7Ci0KLS8qKgotICogRW5jYXBzdWxhdGUgYW4gWE1MIHBhcnNlIGVycm9yIG9yIHdhcm5pbmcuCi0gKgotICogPGJsb2NrcXVvdGU+Ci0gKiA8ZW0+VGhpcyBtb2R1bGUsIGJvdGggc291cmNlIGNvZGUgYW5kIGRvY3VtZW50YXRpb24sIGlzIGluIHRoZQotICogUHVibGljIERvbWFpbiwgYW5kIGNvbWVzIHdpdGggPHN0cm9uZz5OTyBXQVJSQU5UWTwvc3Ryb25nPi48L2VtPgotICogU2VlIDxhIGhyZWY9J2h0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmcnPmh0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmc8L2E+Ci0gKiBmb3IgZnVydGhlciBpbmZvcm1hdGlvbi4KLSAqIDwvYmxvY2txdW90ZT4KLSAqCi0gKiA8cD5UaGlzIGV4Y2VwdGlvbiBtYXkgaW5jbHVkZSBpbmZvcm1hdGlvbiBmb3IgbG9jYXRpbmcgdGhlIGVycm9yCi0gKiBpbiB0aGUgb3JpZ2luYWwgWE1MIGRvY3VtZW50LCBhcyBpZiBpdCBjYW1lIGZyb20gYSB7QGxpbmsgTG9jYXRvcn0KLSAqIG9iamVjdC4gIE5vdGUgdGhhdCBhbHRob3VnaCB0aGUgYXBwbGljYXRpb24KLSAqIHdpbGwgcmVjZWl2ZSBhIFNBWFBhcnNlRXhjZXB0aW9uIGFzIHRoZSBhcmd1bWVudCB0byB0aGUgaGFuZGxlcnMKLSAqIGluIHRoZSB7QGxpbmsgb3JnLnhtbC5zYXguRXJyb3JIYW5kbGVyIEVycm9ySGFuZGxlcn0gaW50ZXJmYWNlLAotICogdGhlIGFwcGxpY2F0aW9uIGlzIG5vdCBhY3R1YWxseSByZXF1aXJlZCB0byB0aHJvdyB0aGUgZXhjZXB0aW9uOwotICogaW5zdGVhZCwgaXQgY2FuIHNpbXBseSByZWFkIHRoZSBpbmZvcm1hdGlvbiBpbiBpdCBhbmQgdGFrZSBhCi0gKiBkaWZmZXJlbnQgYWN0aW9uLjwvcD4KLSAqCi0gKiA8cD5TaW5jZSB0aGlzIGV4Y2VwdGlvbiBpcyBhIHN1YmNsYXNzIG9mIHtAbGluayBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAqIFNBWEV4Y2VwdGlvbn0sIGl0IGluaGVyaXRzIHRoZSBhYmlsaXR5IHRvIHdyYXAgYW5vdGhlciBleGNlcHRpb24uPC9wPgotICoKLSAqIEBzaW5jZSBTQVggMS4wCi0gKiBAYXV0aG9yIERhdmlkIE1lZ2dpbnNvbgotICogQHZlcnNpb24gMi4wLjEgKHNheDJyMikKLSAqIEBzZWUgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gKiBAc2VlIG9yZy54bWwuc2F4LkxvY2F0b3IKLSAqIEBzZWUgb3JnLnhtbC5zYXguRXJyb3JIYW5kbGVyCi0gKi8KLXB1YmxpYyBjbGFzcyBTQVhQYXJzZUV4Y2VwdGlvbiBleHRlbmRzIFNBWEV4Y2VwdGlvbiB7Ci0KLQotICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLSAgICAvLyBDb25zdHJ1Y3RvcnMuCi0gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotCi0KLSAgICAvKioKLSAgICAgKiBDcmVhdGUgYSBuZXcgU0FYUGFyc2VFeGNlcHRpb24gZnJvbSBhIG1lc3NhZ2UgYW5kIGEgTG9jYXRvci4KLSAgICAgKgotICAgICAqIDxwPlRoaXMgY29uc3RydWN0b3IgaXMgZXNwZWNpYWxseSB1c2VmdWwgd2hlbiBhbiBhcHBsaWNhdGlvbiBpcwotICAgICAqIGNyZWF0aW5nIGl0cyBvd24gZXhjZXB0aW9uIGZyb20gd2l0aGluIGEge0BsaW5rIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyCi0gICAgICogQ29udGVudEhhbmRsZXJ9IGNhbGxiYWNrLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBtZXNzYWdlIFRoZSBlcnJvciBvciB3YXJuaW5nIG1lc3NhZ2UuCi0gICAgICogQHBhcmFtIGxvY2F0b3IgVGhlIGxvY2F0b3Igb2JqZWN0IGZvciB0aGUgZXJyb3Igb3Igd2FybmluZyAobWF5IGJlCi0gICAgICogICAgICAgIG51bGwpLgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguTG9jYXRvcgotICAgICAqLwotICAgIHB1YmxpYyBTQVhQYXJzZUV4Y2VwdGlvbiAoU3RyaW5nIG1lc3NhZ2UsIExvY2F0b3IgbG9jYXRvcikgewotICAgICAgICBzdXBlcihtZXNzYWdlKTsKLSAgICAgICAgaWYgKGxvY2F0b3IgIT0gbnVsbCkgewotICAgICAgICAgICAgaW5pdChsb2NhdG9yLmdldFB1YmxpY0lkKCksIGxvY2F0b3IuZ2V0U3lzdGVtSWQoKSwKLSAgICAgICAgICAgICAgICAgbG9jYXRvci5nZXRMaW5lTnVtYmVyKCksIGxvY2F0b3IuZ2V0Q29sdW1uTnVtYmVyKCkpOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgaW5pdChudWxsLCBudWxsLCAtMSwgLTEpOwotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBXcmFwIGFuIGV4aXN0aW5nIGV4Y2VwdGlvbiBpbiBhIFNBWFBhcnNlRXhjZXB0aW9uLgotICAgICAqCi0gICAgICogPHA+VGhpcyBjb25zdHJ1Y3RvciBpcyBlc3BlY2lhbGx5IHVzZWZ1bCB3aGVuIGFuIGFwcGxpY2F0aW9uIGlzCi0gICAgICogY3JlYXRpbmcgaXRzIG93biBleGNlcHRpb24gZnJvbSB3aXRoaW4gYSB7QGxpbmsgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIKLSAgICAgKiBDb250ZW50SGFuZGxlcn0gY2FsbGJhY2ssIGFuZCBuZWVkcyB0byB3cmFwIGFuIGV4aXN0aW5nIGV4Y2VwdGlvbiB0aGF0IGlzIG5vdCBhCi0gICAgICogc3ViY2xhc3Mgb2Yge0BsaW5rIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBTQVhFeGNlcHRpb259LjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBtZXNzYWdlIFRoZSBlcnJvciBvciB3YXJuaW5nIG1lc3NhZ2UsIG9yIG51bGwgdG8KLSAgICAgKiAgICAgICAgICAgICAgICB1c2UgdGhlIG1lc3NhZ2UgZnJvbSB0aGUgZW1iZWRkZWQgZXhjZXB0aW9uLgotICAgICAqIEBwYXJhbSBsb2NhdG9yIFRoZSBsb2NhdG9yIG9iamVjdCBmb3IgdGhlIGVycm9yIG9yIHdhcm5pbmcgKG1heSBiZQotICAgICAqICAgICAgICBudWxsKS4KLSAgICAgKiBAcGFyYW0gZSBBbnkgZXhjZXB0aW9uLgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguTG9jYXRvcgotICAgICAqLwotICAgIHB1YmxpYyBTQVhQYXJzZUV4Y2VwdGlvbiAoU3RyaW5nIG1lc3NhZ2UsIExvY2F0b3IgbG9jYXRvciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgIHN1cGVyKG1lc3NhZ2UsIGUpOwotICAgICAgICBpZiAobG9jYXRvciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBpbml0KGxvY2F0b3IuZ2V0UHVibGljSWQoKSwgbG9jYXRvci5nZXRTeXN0ZW1JZCgpLAotICAgICAgICAgICAgICAgICBsb2NhdG9yLmdldExpbmVOdW1iZXIoKSwgbG9jYXRvci5nZXRDb2x1bW5OdW1iZXIoKSk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBpbml0KG51bGwsIG51bGwsIC0xLCAtMSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIENyZWF0ZSBhIG5ldyBTQVhQYXJzZUV4Y2VwdGlvbi4KLSAgICAgKgotICAgICAqIDxwPlRoaXMgY29uc3RydWN0b3IgaXMgbW9zdCB1c2VmdWwgZm9yIHBhcnNlciB3cml0ZXJzLjwvcD4KLSAgICAgKgotICAgICAqIDxwPkFsbCBwYXJhbWV0ZXJzIGV4Y2VwdCB0aGUgbWVzc2FnZSBhcmUgYXMgaWYKLSAgICAgKiB0aGV5IHdlcmUgcHJvdmlkZWQgYnkgYSB7QGxpbmsgTG9jYXRvcn0uICBGb3IgZXhhbXBsZSwgaWYgdGhlCi0gICAgICogc3lzdGVtIGlkZW50aWZpZXIgaXMgYSBVUkwgKGluY2x1ZGluZyByZWxhdGl2ZSBmaWxlbmFtZSksIHRoZQotICAgICAqIGNhbGxlciBtdXN0IHJlc29sdmUgaXQgZnVsbHkgYmVmb3JlIGNyZWF0aW5nIHRoZSBleGNlcHRpb24uPC9wPgotICAgICAqCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbWVzc2FnZSBUaGUgZXJyb3Igb3Igd2FybmluZyBtZXNzYWdlLgotICAgICAqIEBwYXJhbSBwdWJsaWNJZCBUaGUgcHVibGljIGlkZW50aWZpZXIgb2YgdGhlIGVudGl0eSB0aGF0IGdlbmVyYXRlZAotICAgICAqICAgICAgICAgICAgICAgICB0aGUgZXJyb3Igb3Igd2FybmluZy4KLSAgICAgKiBAcGFyYW0gc3lzdGVtSWQgVGhlIHN5c3RlbSBpZGVudGlmaWVyIG9mIHRoZSBlbnRpdHkgdGhhdCBnZW5lcmF0ZWQKLSAgICAgKiAgICAgICAgICAgICAgICAgdGhlIGVycm9yIG9yIHdhcm5pbmcuCi0gICAgICogQHBhcmFtIGxpbmVOdW1iZXIgVGhlIGxpbmUgbnVtYmVyIG9mIHRoZSBlbmQgb2YgdGhlIHRleHQgdGhhdAotICAgICAqICAgICAgICAgICAgICAgICAgIGNhdXNlZCB0aGUgZXJyb3Igb3Igd2FybmluZy4KLSAgICAgKiBAcGFyYW0gY29sdW1uTnVtYmVyIFRoZSBjb2x1bW4gbnVtYmVyIG9mIHRoZSBlbmQgb2YgdGhlIHRleHQgdGhhdAotICAgICAqICAgICAgICAgICAgICAgICAgICAgY2F1c2UgdGhlIGVycm9yIG9yIHdhcm5pbmcuCi0gICAgICovCi0gICAgcHVibGljIFNBWFBhcnNlRXhjZXB0aW9uIChTdHJpbmcgbWVzc2FnZSwgU3RyaW5nIHB1YmxpY0lkLCBTdHJpbmcgc3lzdGVtSWQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbGluZU51bWJlciwgaW50IGNvbHVtbk51bWJlcikKLSAgICB7Ci0gICAgICAgIHN1cGVyKG1lc3NhZ2UpOwotICAgICAgICBpbml0KHB1YmxpY0lkLCBzeXN0ZW1JZCwgbGluZU51bWJlciwgY29sdW1uTnVtYmVyKTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIENyZWF0ZSBhIG5ldyBTQVhQYXJzZUV4Y2VwdGlvbiB3aXRoIGFuIGVtYmVkZGVkIGV4Y2VwdGlvbi4KLSAgICAgKgotICAgICAqIDxwPlRoaXMgY29uc3RydWN0b3IgaXMgbW9zdCB1c2VmdWwgZm9yIHBhcnNlciB3cml0ZXJzIHdobwotICAgICAqIG5lZWQgdG8gd3JhcCBhbiBleGNlcHRpb24gdGhhdCBpcyBub3QgYSBzdWJjbGFzcyBvZgotICAgICAqIHtAbGluayBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gU0FYRXhjZXB0aW9ufS48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5BbGwgcGFyYW1ldGVycyBleGNlcHQgdGhlIG1lc3NhZ2UgYW5kIGV4Y2VwdGlvbiBhcmUgYXMgaWYKLSAgICAgKiB0aGV5IHdlcmUgcHJvdmlkZWQgYnkgYSB7QGxpbmsgTG9jYXRvcn0uICBGb3IgZXhhbXBsZSwgaWYgdGhlCi0gICAgICogc3lzdGVtIGlkZW50aWZpZXIgaXMgYSBVUkwgKGluY2x1ZGluZyByZWxhdGl2ZSBmaWxlbmFtZSksIHRoZQotICAgICAqIGNhbGxlciBtdXN0IHJlc29sdmUgaXQgZnVsbHkgYmVmb3JlIGNyZWF0aW5nIHRoZSBleGNlcHRpb24uPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIG1lc3NhZ2UgVGhlIGVycm9yIG9yIHdhcm5pbmcgbWVzc2FnZSwgb3IgbnVsbCB0byB1c2UKLSAgICAgKiAgICAgICAgICAgICAgICB0aGUgbWVzc2FnZSBmcm9tIHRoZSBlbWJlZGRlZCBleGNlcHRpb24uCi0gICAgICogQHBhcmFtIHB1YmxpY0lkIFRoZSBwdWJsaWMgaWRlbnRpZmllciBvZiB0aGUgZW50aXR5IHRoYXQgZ2VuZXJhdGVkCi0gICAgICogICAgICAgICAgICAgICAgIHRoZSBlcnJvciBvciB3YXJuaW5nLgotICAgICAqIEBwYXJhbSBzeXN0ZW1JZCBUaGUgc3lzdGVtIGlkZW50aWZpZXIgb2YgdGhlIGVudGl0eSB0aGF0IGdlbmVyYXRlZAotICAgICAqICAgICAgICAgICAgICAgICB0aGUgZXJyb3Igb3Igd2FybmluZy4KLSAgICAgKiBAcGFyYW0gbGluZU51bWJlciBUaGUgbGluZSBudW1iZXIgb2YgdGhlIGVuZCBvZiB0aGUgdGV4dCB0aGF0Ci0gICAgICogICAgICAgICAgICAgICAgICAgY2F1c2VkIHRoZSBlcnJvciBvciB3YXJuaW5nLgotICAgICAqIEBwYXJhbSBjb2x1bW5OdW1iZXIgVGhlIGNvbHVtbiBudW1iZXIgb2YgdGhlIGVuZCBvZiB0aGUgdGV4dCB0aGF0Ci0gICAgICogICAgICAgICAgICAgICAgICAgICBjYXVzZSB0aGUgZXJyb3Igb3Igd2FybmluZy4KLSAgICAgKiBAcGFyYW0gZSBBbm90aGVyIGV4Y2VwdGlvbiB0byBlbWJlZCBpbiB0aGlzIG9uZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgU0FYUGFyc2VFeGNlcHRpb24gKFN0cmluZyBtZXNzYWdlLCBTdHJpbmcgcHVibGljSWQsIFN0cmluZyBzeXN0ZW1JZCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBsaW5lTnVtYmVyLCBpbnQgY29sdW1uTnVtYmVyLCBFeGNlcHRpb24gZSkKLSAgICB7Ci0gICAgICAgIHN1cGVyKG1lc3NhZ2UsIGUpOwotICAgICAgICBpbml0KHB1YmxpY0lkLCBzeXN0ZW1JZCwgbGluZU51bWJlciwgY29sdW1uTnVtYmVyKTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIEludGVybmFsIGluaXRpYWxpemF0aW9uIG1ldGhvZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBwdWJsaWNJZCBUaGUgcHVibGljIGlkZW50aWZpZXIgb2YgdGhlIGVudGl0eSB3aGljaCBnZW5lcmF0ZWQgdGhlIGV4Y2VwdGlvbiwKLSAgICAgKiAgICAgICAgb3IgbnVsbC4KLSAgICAgKiBAcGFyYW0gc3lzdGVtSWQgVGhlIHN5c3RlbSBpZGVudGlmaWVyIG9mIHRoZSBlbnRpdHkgd2hpY2ggZ2VuZXJhdGVkIHRoZSBleGNlcHRpb24sCi0gICAgICogICAgICAgIG9yIG51bGwuCi0gICAgICogQHBhcmFtIGxpbmVOdW1iZXIgVGhlIGxpbmUgbnVtYmVyIG9mIHRoZSBlcnJvciwgb3IgLTEuCi0gICAgICogQHBhcmFtIGNvbHVtbk51bWJlciBUaGUgY29sdW1uIG51bWJlciBvZiB0aGUgZXJyb3IsIG9yIC0xLgotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCBpbml0IChTdHJpbmcgcHVibGljSWQsIFN0cmluZyBzeXN0ZW1JZCwKLSAgICAgICAgICAgICAgICAgICAgICAgaW50IGxpbmVOdW1iZXIsIGludCBjb2x1bW5OdW1iZXIpCi0gICAgewotICAgICAgICB0aGlzLnB1YmxpY0lkID0gcHVibGljSWQ7Ci0gICAgICAgIHRoaXMuc3lzdGVtSWQgPSBzeXN0ZW1JZDsKLSAgICAgICAgdGhpcy5saW5lTnVtYmVyID0gbGluZU51bWJlcjsKLSAgICAgICAgdGhpcy5jb2x1bW5OdW1iZXIgPSBjb2x1bW5OdW1iZXI7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIHB1YmxpYyBpZGVudGlmaWVyIG9mIHRoZSBlbnRpdHkgd2hlcmUgdGhlIGV4Y2VwdGlvbiBvY2N1cnJlZC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gQSBzdHJpbmcgY29udGFpbmluZyB0aGUgcHVibGljIGlkZW50aWZpZXIsIG9yIG51bGwKLSAgICAgKiAgICAgICAgIGlmIG5vbmUgaXMgYXZhaWxhYmxlLgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguTG9jYXRvciNnZXRQdWJsaWNJZAotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0UHVibGljSWQgKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiB0aGlzLnB1YmxpY0lkOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBzeXN0ZW0gaWRlbnRpZmllciBvZiB0aGUgZW50aXR5IHdoZXJlIHRoZSBleGNlcHRpb24gb2NjdXJyZWQuCi0gICAgICoKLSAgICAgKiA8cD5JZiB0aGUgc3lzdGVtIGlkZW50aWZpZXIgaXMgYSBVUkwsIGl0IHdpbGwgaGF2ZSBiZWVuIHJlc29sdmVkCi0gICAgICogZnVsbHkuPC9wPgotICAgICAqCi0gICAgICogQHJldHVybiBBIHN0cmluZyBjb250YWluaW5nIHRoZSBzeXN0ZW0gaWRlbnRpZmllciwgb3IgbnVsbAotICAgICAqICAgICAgICAgaWYgbm9uZSBpcyBhdmFpbGFibGUuCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5Mb2NhdG9yI2dldFN5c3RlbUlkCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRTeXN0ZW1JZCAoKQotICAgIHsKLSAgICAgICAgcmV0dXJuIHRoaXMuc3lzdGVtSWQ7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBUaGUgbGluZSBudW1iZXIgb2YgdGhlIGVuZCBvZiB0aGUgdGV4dCB3aGVyZSB0aGUgZXhjZXB0aW9uIG9jY3VycmVkLgotICAgICAqCi0gICAgICogPHA+VGhlIGZpcnN0IGxpbmUgaXMgbGluZSAxLjwvcD4KLSAgICAgKgotICAgICAqIEByZXR1cm4gQW4gaW50ZWdlciByZXByZXNlbnRpbmcgdGhlIGxpbmUgbnVtYmVyLCBvciAtMQotICAgICAqICAgICAgICAgaWYgbm9uZSBpcyBhdmFpbGFibGUuCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5Mb2NhdG9yI2dldExpbmVOdW1iZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldExpbmVOdW1iZXIgKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiB0aGlzLmxpbmVOdW1iZXI7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBUaGUgY29sdW1uIG51bWJlciBvZiB0aGUgZW5kIG9mIHRoZSB0ZXh0IHdoZXJlIHRoZSBleGNlcHRpb24gb2NjdXJyZWQuCi0gICAgICoKLSAgICAgKiA8cD5UaGUgZmlyc3QgY29sdW1uIGluIGEgbGluZSBpcyBwb3NpdGlvbiAxLjwvcD4KLSAgICAgKgotICAgICAqIEByZXR1cm4gQW4gaW50ZWdlciByZXByZXNlbnRpbmcgdGhlIGNvbHVtbiBudW1iZXIsIG9yIC0xCi0gICAgICogICAgICAgICBpZiBub25lIGlzIGF2YWlsYWJsZS4KLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkxvY2F0b3IjZ2V0Q29sdW1uTnVtYmVyCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRDb2x1bW5OdW1iZXIgKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiB0aGlzLmNvbHVtbk51bWJlcjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBPdmVycmlkZSB0b1N0cmluZyB0byBwcm92aWRlIG1vcmUgZGV0YWlsZWQgZXJyb3IgbWVzc2FnZS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gQSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBleGNlcHRpb24uCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKLSAgICAgICAgU3RyaW5nQnVpbGRlciBidWYgPSBuZXcgU3RyaW5nQnVpbGRlcihnZXRDbGFzcygpLmdldE5hbWUoKSk7Ci0gICAgICAgIFN0cmluZyBtZXNzYWdlID0gZ2V0TG9jYWxpemVkTWVzc2FnZSgpOwotICAgICAgICBpZiAocHVibGljSWQhPW51bGwpICAgIGJ1Zi5hcHBlbmQoInB1YmxpY0lkOiAiKS5hcHBlbmQocHVibGljSWQpOwotICAgICAgICBpZiAoc3lzdGVtSWQhPW51bGwpICAgIGJ1Zi5hcHBlbmQoIjsgc3lzdGVtSWQ6ICIpLmFwcGVuZChzeXN0ZW1JZCk7Ci0gICAgICAgIGlmIChsaW5lTnVtYmVyIT0tMSkgICAgYnVmLmFwcGVuZCgiOyBsaW5lTnVtYmVyOiAiKS5hcHBlbmQobGluZU51bWJlcik7Ci0gICAgICAgIGlmIChjb2x1bW5OdW1iZXIhPS0xKSAgYnVmLmFwcGVuZCgiOyBjb2x1bW5OdW1iZXI6ICIpLmFwcGVuZChjb2x1bW5OdW1iZXIpOwotCi0gICAgICAgLy9hcHBlbmQgdGhlIGV4Y2VwdGlvbiBtZXNzYWdlIGF0IHRoZSBlbmQKLSAgICAgICAgaWYgKG1lc3NhZ2UhPW51bGwpICAgICBidWYuYXBwZW5kKCI7ICIpLmFwcGVuZChtZXNzYWdlKTsKLSAgICAgICAgcmV0dXJuIGJ1Zi50b1N0cmluZygpOwotICAgIH0KLQotICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLSAgICAvLyBJbnRlcm5hbCBzdGF0ZS4KLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0KLQotICAgIC8qKgotICAgICAqIEBzZXJpYWwgVGhlIHB1YmxpYyBpZGVudGlmaWVyLCBvciBudWxsLgotICAgICAqIEBzZWUgI2dldFB1YmxpY0lkCi0gICAgICovCi0gICAgcHJpdmF0ZSBTdHJpbmcgcHVibGljSWQ7Ci0KLQotICAgIC8qKgotICAgICAqIEBzZXJpYWwgVGhlIHN5c3RlbSBpZGVudGlmaWVyLCBvciBudWxsLgotICAgICAqIEBzZWUgI2dldFN5c3RlbUlkCi0gICAgICovCi0gICAgcHJpdmF0ZSBTdHJpbmcgc3lzdGVtSWQ7Ci0KLQotICAgIC8qKgotICAgICAqIEBzZXJpYWwgVGhlIGxpbmUgbnVtYmVyLCBvciAtMS4KLSAgICAgKiBAc2VlICNnZXRMaW5lTnVtYmVyCi0gICAgICovCi0gICAgcHJpdmF0ZSBpbnQgbGluZU51bWJlcjsKLQotCi0gICAgLyoqCi0gICAgICogQHNlcmlhbCBUaGUgY29sdW1uIG51bWJlciwgb3IgLTEuCi0gICAgICogQHNlZSAjZ2V0Q29sdW1uTnVtYmVyCi0gICAgICovCi0gICAgcHJpdmF0ZSBpbnQgY29sdW1uTnVtYmVyOwotCi0gICAgLy8gQWRkZWQgc2VyaWFsVmVyc2lvblVJRCB0byBwcmVzZXJ2ZSBiaW5hcnkgY29tcGF0aWJpbGl0eQotICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNTY1MTE2NTg3MjQ3NjcwOTMzNkw7Ci19Ci0KLS8vIGVuZCBvZiBTQVhQYXJzZUV4Y2VwdGlvbi5qYXZhCmRpZmYgLS1naXQgYS9zcmMvb3JnL3htbC9zYXgvWE1MRmlsdGVyLmphdmEgYi9zcmMvb3JnL3htbC9zYXgvWE1MRmlsdGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGY4OGNmZjEuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy94bWwvc2F4L1hNTEZpbHRlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsODkgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwMCwgMjAwNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLy8gWE1MRmlsdGVyLmphdmEgLSBmaWx0ZXIgU0FYMiBldmVudHMuCi0vLyBodHRwOi8vd3d3LnNheHByb2plY3Qub3JnCi0vLyBXcml0dGVuIGJ5IERhdmlkIE1lZ2dpbnNvbgotLy8gTk8gV0FSUkFOVFkhICBUaGlzIGNsYXNzIGlzIGluIHRoZSBQdWJsaWMgRG9tYWluLgotLy8gJElkOiBYTUxGaWx0ZXIuamF2YSx2IDEuMiAyMDA0LzExLzAzIDIyOjU1OjMyIGpzdXR0b3IgRXhwICQKLQotcGFja2FnZSBvcmcueG1sLnNheDsKLQotCi0vKioKLSAqIEludGVyZmFjZSBmb3IgYW4gWE1MIGZpbHRlci4KLSAqCi0gKiA8YmxvY2txdW90ZT4KLSAqIDxlbT5UaGlzIG1vZHVsZSwgYm90aCBzb3VyY2UgY29kZSBhbmQgZG9jdW1lbnRhdGlvbiwgaXMgaW4gdGhlCi0gKiBQdWJsaWMgRG9tYWluLCBhbmQgY29tZXMgd2l0aCA8c3Ryb25nPk5PIFdBUlJBTlRZPC9zdHJvbmc+LjwvZW0+Ci0gKiBTZWUgPGEgaHJlZj0naHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZyc+aHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZzwvYT4KLSAqIGZvciBmdXJ0aGVyIGluZm9ybWF0aW9uLgotICogPC9ibG9ja3F1b3RlPgotICoKLSAqIDxwPkFuIFhNTCBmaWx0ZXIgaXMgbGlrZSBhbiBYTUwgcmVhZGVyLCBleGNlcHQgdGhhdCBpdCBvYnRhaW5zIGl0cwotICogZXZlbnRzIGZyb20gYW5vdGhlciBYTUwgcmVhZGVyIHJhdGhlciB0aGFuIGEgcHJpbWFyeSBzb3VyY2UgbGlrZQotICogYW4gWE1MIGRvY3VtZW50IG9yIGRhdGFiYXNlLiAgRmlsdGVycyBjYW4gbW9kaWZ5IGEgc3RyZWFtIG9mCi0gKiBldmVudHMgYXMgdGhleSBwYXNzIG9uIHRvIHRoZSBmaW5hbCBhcHBsaWNhdGlvbi48L3A+Ci0gKgotICogPHA+VGhlIFhNTEZpbHRlckltcGwgaGVscGVyIGNsYXNzIHByb3ZpZGVzIGEgY29udmVuaWVudCBiYXNlCi0gKiBmb3IgY3JlYXRpbmcgU0FYMiBmaWx0ZXJzLCBieSBwYXNzaW5nIG9uIGFsbCB7QGxpbmsgb3JnLnhtbC5zYXguRW50aXR5UmVzb2x2ZXIKLSAqIEVudGl0eVJlc29sdmVyfSwge0BsaW5rIG9yZy54bWwuc2F4LkRUREhhbmRsZXIgRFRESGFuZGxlcn0sCi0gKiB7QGxpbmsgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIgQ29udGVudEhhbmRsZXJ9IGFuZCB7QGxpbmsgb3JnLnhtbC5zYXguRXJyb3JIYW5kbGVyCi0gKiBFcnJvckhhbmRsZXJ9IGV2ZW50cyBhdXRvbWF0aWNhbGx5LjwvcD4KLSAqCi0gKiBAc2luY2UgU0FYIDIuMAotICogQGF1dGhvciBEYXZpZCBNZWdnaW5zb24KLSAqIEBzZWUgb3JnLnhtbC5zYXguaGVscGVycy5YTUxGaWx0ZXJJbXBsCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgWE1MRmlsdGVyIGV4dGVuZHMgWE1MUmVhZGVyCi17Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIHBhcmVudCByZWFkZXIuCi0gICAgICoKLSAgICAgKiA8cD5UaGlzIG1ldGhvZCBhbGxvd3MgdGhlIGFwcGxpY2F0aW9uIHRvIGxpbmsgdGhlIGZpbHRlciB0bwotICAgICAqIGEgcGFyZW50IHJlYWRlciAod2hpY2ggbWF5IGJlIGFub3RoZXIgZmlsdGVyKS4gIFRoZSBhcmd1bWVudAotICAgICAqIG1heSBub3QgYmUgbnVsbC48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gcGFyZW50IFRoZSBwYXJlbnQgcmVhZGVyLgotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHNldFBhcmVudCAoWE1MUmVhZGVyIHBhcmVudCk7Ci0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgcGFyZW50IHJlYWRlci4KLSAgICAgKgotICAgICAqIDxwPlRoaXMgbWV0aG9kIGFsbG93cyB0aGUgYXBwbGljYXRpb24gdG8gcXVlcnkgdGhlIHBhcmVudAotICAgICAqIHJlYWRlciAod2hpY2ggbWF5IGJlIGFub3RoZXIgZmlsdGVyKS4gIEl0IGlzIGdlbmVyYWxseSBhCi0gICAgICogYmFkIGlkZWEgdG8gcGVyZm9ybSBhbnkgb3BlcmF0aW9ucyBvbiB0aGUgcGFyZW50IHJlYWRlcgotICAgICAqIGRpcmVjdGx5OiB0aGV5IHNob3VsZCBhbGwgcGFzcyB0aHJvdWdoIHRoaXMgZmlsdGVyLjwvcD4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIHBhcmVudCBmaWx0ZXIsIG9yIG51bGwgaWYgbm9uZSBoYXMgYmVlbiBzZXQuCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IFhNTFJlYWRlciBnZXRQYXJlbnQgKCk7Ci0KLX0KLQotLy8gZW5kIG9mIFhNTEZpbHRlci5qYXZhCmRpZmYgLS1naXQgYS9zcmMvb3JnL3htbC9zYXgvWE1MUmVhZGVyLmphdmEgYi9zcmMvb3JnL3htbC9zYXgvWE1MUmVhZGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDkzYjczNDIuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy94bWwvc2F4L1hNTFJlYWRlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDI4ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDAsIDIwMDUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8vIFhNTFJlYWRlci5qYXZhIC0gcmVhZCBhbiBYTUwgZG9jdW1lbnQuCi0vLyBodHRwOi8vd3d3LnNheHByb2plY3Qub3JnCi0vLyBXcml0dGVuIGJ5IERhdmlkIE1lZ2dpbnNvbgotLy8gTk8gV0FSUkFOVFkhICBUaGlzIGNsYXNzIGlzIGluIHRoZSBQdWJsaWMgRG9tYWluLgotLy8gJElkOiBYTUxSZWFkZXIuamF2YSx2IDEuMyAyMDA0LzExLzAzIDIyOjU1OjMyIGpzdXR0b3IgRXhwICQKLQotcGFja2FnZSBvcmcueG1sLnNheDsKLQotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci0KLQotLyoqCi0gKiBJbnRlcmZhY2UgZm9yIHJlYWRpbmcgYW4gWE1MIGRvY3VtZW50IHVzaW5nIGNhbGxiYWNrcy4KLSAqCi0gKiA8YmxvY2txdW90ZT4KLSAqIDxlbT5UaGlzIG1vZHVsZSwgYm90aCBzb3VyY2UgY29kZSBhbmQgZG9jdW1lbnRhdGlvbiwgaXMgaW4gdGhlCi0gKiBQdWJsaWMgRG9tYWluLCBhbmQgY29tZXMgd2l0aCA8c3Ryb25nPk5PIFdBUlJBTlRZPC9zdHJvbmc+LjwvZW0+Ci0gKiBTZWUgPGEgaHJlZj0naHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZyc+aHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZzwvYT4KLSAqIGZvciBmdXJ0aGVyIGluZm9ybWF0aW9uLgotICogPC9ibG9ja3F1b3RlPgotICoKLSAqIDxwPjxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gZGVzcGl0ZSBpdHMgbmFtZSwgdGhpcyBpbnRlcmZhY2UgZG9lcwotICogPGVtPm5vdDwvZW0+IGV4dGVuZCB0aGUgc3RhbmRhcmQgSmF2YSB7QGxpbmsgamF2YS5pby5SZWFkZXIgUmVhZGVyfQotICogaW50ZXJmYWNlLCBiZWNhdXNlIHJlYWRpbmcgWE1MIGlzIGEgZnVuZGFtZW50YWxseSBkaWZmZXJlbnQgYWN0aXZpdHkKLSAqIHRoYW4gcmVhZGluZyBjaGFyYWN0ZXIgZGF0YS48L3A+Ci0gKgotICogPHA+WE1MUmVhZGVyIGlzIHRoZSBpbnRlcmZhY2UgdGhhdCBhbiBYTUwgcGFyc2VyJ3MgU0FYMiBkcml2ZXIgbXVzdAotICogaW1wbGVtZW50LiAgVGhpcyBpbnRlcmZhY2UgYWxsb3dzIGFuIGFwcGxpY2F0aW9uIHRvIHNldCBhbmQKLSAqIHF1ZXJ5IGZlYXR1cmVzIGFuZCBwcm9wZXJ0aWVzIGluIHRoZSBwYXJzZXIsIHRvIHJlZ2lzdGVyCi0gKiBldmVudCBoYW5kbGVycyBmb3IgZG9jdW1lbnQgcHJvY2Vzc2luZywgYW5kIHRvIGluaXRpYXRlCi0gKiBhIGRvY3VtZW50IHBhcnNlLjwvcD4KLSAqCi0gKiA8cD5BbGwgU0FYIGludGVyZmFjZXMgYXJlIGFzc3VtZWQgdG8gYmUgc3luY2hyb25vdXM6IHRoZQotICoge0BsaW5rICNwYXJzZSBwYXJzZX0gbWV0aG9kcyBtdXN0IG5vdCByZXR1cm4gdW50aWwgcGFyc2luZwotICogaXMgY29tcGxldGUsIGFuZCByZWFkZXJzIG11c3Qgd2FpdCBmb3IgYW4gZXZlbnQtaGFuZGxlciBjYWxsYmFjawotICogdG8gcmV0dXJuIGJlZm9yZSByZXBvcnRpbmcgdGhlIG5leHQgZXZlbnQuPC9wPgotICoKLSAqIDxwPlRoaXMgaW50ZXJmYWNlIHJlcGxhY2VzIHRoZSAobm93IGRlcHJlY2F0ZWQpIFNBWCAxLjAge0BsaW5rCi0gKiBvcmcueG1sLnNheC5QYXJzZXIgUGFyc2VyfSBpbnRlcmZhY2UuICBUaGUgWE1MUmVhZGVyIGludGVyZmFjZQotICogY29udGFpbnMgdHdvIGltcG9ydGFudCBlbmhhbmNlbWVudHMgb3ZlciB0aGUgb2xkIFBhcnNlcgotICogaW50ZXJmYWNlIChhcyB3ZWxsIGFzIHNvbWUgbWlub3Igb25lcyk6PC9wPgotICoKLSAqIDxvbD4KLSAqIDxsaT5pdCBhZGRzIGEgc3RhbmRhcmQgd2F5IHRvIHF1ZXJ5IGFuZCBzZXQgZmVhdHVyZXMgYW5kCi0gKiAgcHJvcGVydGllczsgYW5kPC9saT4KLSAqIDxsaT5pdCBhZGRzIE5hbWVzcGFjZSBzdXBwb3J0LCB3aGljaCBpcyByZXF1aXJlZCBmb3IgbWFueQotICogIGhpZ2hlci1sZXZlbCBYTUwgc3RhbmRhcmRzLjwvbGk+Ci0gKiA8L29sPgotICoKLSAqIDxwPlRoZXJlIGFyZSBhZGFwdGVycyBhdmFpbGFibGUgdG8gY29udmVydCBhIFNBWDEgUGFyc2VyIHRvCi0gKiBhIFNBWDIgWE1MUmVhZGVyIGFuZCB2aWNlLXZlcnNhLjwvcD4KLSAqCi0gKiBAc2luY2UgU0FYIDIuMAotICogQGF1dGhvciBEYXZpZCBNZWdnaW5zb24KLSAqIEBzZWUgb3JnLnhtbC5zYXguWE1MRmlsdGVyCi0gKiBAc2VlIG9yZy54bWwuc2F4LmhlbHBlcnMuUGFyc2VyQWRhcHRlcgotICogQHNlZSBvcmcueG1sLnNheC5oZWxwZXJzLlhNTFJlYWRlckFkYXB0ZXIKLSAqLwotcHVibGljIGludGVyZmFjZSBYTUxSZWFkZXIKLXsKLQotCi0gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLSAgICAvLyBDb25maWd1cmF0aW9uLgotICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0KLQotICAgIC8qKgotICAgICAqIExvb2sgdXAgdGhlIHZhbHVlIG9mIGEgZmVhdHVyZSBmbGFnLgotICAgICAqCi0gICAgICogPHA+VGhlIGZlYXR1cmUgbmFtZSBpcyBhbnkgZnVsbHktcXVhbGlmaWVkIFVSSS4gIEl0IGlzCi0gICAgICogcG9zc2libGUgZm9yIGFuIFhNTFJlYWRlciB0byByZWNvZ25pemUgYSBmZWF0dXJlIG5hbWUgYnV0Ci0gICAgICogdGVtcG9yYXJpbHkgYmUgdW5hYmxlIHRvIHJldHVybiBpdHMgdmFsdWUuCi0gICAgICogU29tZSBmZWF0dXJlIHZhbHVlcyBtYXkgYmUgYXZhaWxhYmxlIG9ubHkgaW4gc3BlY2lmaWMKLSAgICAgKiBjb250ZXh0cywgc3VjaCBhcyBiZWZvcmUsIGR1cmluZywgb3IgYWZ0ZXIgYSBwYXJzZS4KLSAgICAgKiBBbHNvLCBzb21lIGZlYXR1cmUgdmFsdWVzIG1heSBub3QgYmUgcHJvZ3JhbW1hdGljYWxseSBhY2Nlc3NpYmxlLgotICAgICAqIChJbiB0aGUgY2FzZSBvZiBhbiBhZGFwdGVyIGZvciBTQVgxIHtAbGluayBQYXJzZXJ9LCB0aGVyZSBpcyBubwotICAgICAqIGltcGxlbWVudGF0aW9uLWluZGVwZW5kZW50IHdheSB0byBleHBvc2Ugd2hldGhlciB0aGUgdW5kZXJseWluZwotICAgICAqIHBhcnNlciBpcyBwZXJmb3JtaW5nIHZhbGlkYXRpb24sIGV4cGFuZGluZyBleHRlcm5hbCBlbnRpdGllcywKLSAgICAgKiBhbmQgc28gZm9ydGguKSA8L3A+Ci0gICAgICoKLSAgICAgKiA8cD5BbGwgWE1MUmVhZGVycyBhcmUgcmVxdWlyZWQgdG8gcmVjb2duaXplIHRoZQotICAgICAqIGh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy9uYW1lc3BhY2VzIGFuZCB0aGUKLSAgICAgKiBodHRwOi8veG1sLm9yZy9zYXgvZmVhdHVyZXMvbmFtZXNwYWNlLXByZWZpeGVzIGZlYXR1cmUgbmFtZXMuPC9wPgotICAgICAqCi0gICAgICogPHA+VHlwaWNhbCB1c2FnZSBpcyBzb21ldGhpbmcgbGlrZSB0aGlzOjwvcD4KLSAgICAgKgotICAgICAqIDxwcmU+Ci0gICAgICogWE1MUmVhZGVyIHIgPSBuZXcgTXlTQVhEcml2ZXIoKTsKLSAgICAgKgotICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRyeSB0byBhY3RpdmF0ZSB2YWxpZGF0aW9uCi0gICAgICogdHJ5IHsKLSAgICAgKiAgIHIuc2V0RmVhdHVyZSgiaHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL3ZhbGlkYXRpb24iLCB0cnVlKTsKLSAgICAgKiB9IGNhdGNoIChTQVhFeGNlcHRpb24gZSkgewotICAgICAqICAgU3lzdGVtLmVyci5wcmludGxuKCJDYW5ub3QgYWN0aXZhdGUgdmFsaWRhdGlvbi4iKTsKLSAgICAgKiB9Ci0gICAgICoKLSAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAvLyByZWdpc3RlciBldmVudCBoYW5kbGVycwotICAgICAqIHIuc2V0Q29udGVudEhhbmRsZXIobmV3IE15Q29udGVudEhhbmRsZXIoKSk7Ci0gICAgICogci5zZXRFcnJvckhhbmRsZXIobmV3IE15RXJyb3JIYW5kbGVyKCkpOwotICAgICAqCi0gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgLy8gcGFyc2UgdGhlIGZpcnN0IGRvY3VtZW50Ci0gICAgICogdHJ5IHsKLSAgICAgKiAgIHIucGFyc2UoImh0dHA6Ly93d3cuZm9vLmNvbS9teWRvYy54bWwiKTsKLSAgICAgKiB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7Ci0gICAgICogICBTeXN0ZW0uZXJyLnByaW50bG4oIkkvTyBleGNlcHRpb24gcmVhZGluZyBYTUwgZG9jdW1lbnQiKTsKLSAgICAgKiB9IGNhdGNoIChTQVhFeGNlcHRpb24gZSkgewotICAgICAqICAgU3lzdGVtLmVyci5wcmludGxuKCJYTUwgZXhjZXB0aW9uIHJlYWRpbmcgZG9jdW1lbnQuIik7Ci0gICAgICogfQotICAgICAqIDwvcHJlPgotICAgICAqCi0gICAgICogPHA+SW1wbGVtZW50b3JzIGFyZSBmcmVlIChhbmQgZW5jb3VyYWdlZCkgdG8gaW52ZW50IHRoZWlyIG93biBmZWF0dXJlcywKLSAgICAgKiB1c2luZyBuYW1lcyBidWlsdCBvbiB0aGVpciBvd24gVVJJcy48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgZmVhdHVyZSBuYW1lLCB3aGljaCBpcyBhIGZ1bGx5LXF1YWxpZmllZCBVUkkuCi0gICAgICogQHJldHVybiBUaGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgZmVhdHVyZSAodHJ1ZSBvciBmYWxzZSkuCi0gICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIElmIHRoZSBmZWF0dXJlCi0gICAgICogICAgICAgICAgICB2YWx1ZSBjYW4ndCBiZSBhc3NpZ25lZCBvciByZXRyaWV2ZWQuCi0gICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gV2hlbiB0aGUKLSAgICAgKiAgICAgICAgICAgIFhNTFJlYWRlciByZWNvZ25pemVzIHRoZSBmZWF0dXJlIG5hbWUgYnV0Ci0gICAgICogICAgICAgICAgICBjYW5ub3QgZGV0ZXJtaW5lIGl0cyB2YWx1ZSBhdCB0aGlzIHRpbWUuCi0gICAgICogQHNlZSAjc2V0RmVhdHVyZQotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGdldEZlYXR1cmUgKFN0cmluZyBuYW1lKQotICAgICAgICB0aHJvd3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiwgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uOwotCi0KLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIHZhbHVlIG9mIGEgZmVhdHVyZSBmbGFnLgotICAgICAqCi0gICAgICogPHA+VGhlIGZlYXR1cmUgbmFtZSBpcyBhbnkgZnVsbHktcXVhbGlmaWVkIFVSSS4gIEl0IGlzCi0gICAgICogcG9zc2libGUgZm9yIGFuIFhNTFJlYWRlciB0byBleHBvc2UgYSBmZWF0dXJlIHZhbHVlIGJ1dAotICAgICAqIHRvIGJlIHVuYWJsZSB0byBjaGFuZ2UgdGhlIGN1cnJlbnQgdmFsdWUuCi0gICAgICogU29tZSBmZWF0dXJlIHZhbHVlcyBtYXkgYmUgaW1tdXRhYmxlIG9yIG11dGFibGUgb25seQotICAgICAqIGluIHNwZWNpZmljIGNvbnRleHRzLCBzdWNoIGFzIGJlZm9yZSwgZHVyaW5nLCBvciBhZnRlcgotICAgICAqIGEgcGFyc2UuPC9wPgotICAgICAqCi0gICAgICogPHA+QWxsIFhNTFJlYWRlcnMgYXJlIHJlcXVpcmVkIHRvIHN1cHBvcnQgc2V0dGluZwotICAgICAqIGh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy9uYW1lc3BhY2VzIHRvIHRydWUgYW5kCi0gICAgICogaHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL25hbWVzcGFjZS1wcmVmaXhlcyB0byBmYWxzZS48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgZmVhdHVyZSBuYW1lLCB3aGljaCBpcyBhIGZ1bGx5LXF1YWxpZmllZCBVUkkuCi0gICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXF1ZXN0ZWQgdmFsdWUgb2YgdGhlIGZlYXR1cmUgKHRydWUgb3IgZmFsc2UpLgotICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiBJZiB0aGUgZmVhdHVyZQotICAgICAqICAgICAgICAgICAgdmFsdWUgY2FuJ3QgYmUgYXNzaWduZWQgb3IgcmV0cmlldmVkLgotICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIFdoZW4gdGhlCi0gICAgICogICAgICAgICAgICBYTUxSZWFkZXIgcmVjb2duaXplcyB0aGUgZmVhdHVyZSBuYW1lIGJ1dAotICAgICAqICAgICAgICAgICAgY2Fubm90IHNldCB0aGUgcmVxdWVzdGVkIHZhbHVlLgotICAgICAqIEBzZWUgI2dldEZlYXR1cmUKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRGZWF0dXJlIChTdHJpbmcgbmFtZSwgYm9vbGVhbiB2YWx1ZSkKLSAgICAgICAgdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbjsKLQotCi0gICAgLyoqCi0gICAgICogTG9vayB1cCB0aGUgdmFsdWUgb2YgYSBwcm9wZXJ0eS4KLSAgICAgKgotICAgICAqIDxwPlRoZSBwcm9wZXJ0eSBuYW1lIGlzIGFueSBmdWxseS1xdWFsaWZpZWQgVVJJLiAgSXQgaXMKLSAgICAgKiBwb3NzaWJsZSBmb3IgYW4gWE1MUmVhZGVyIHRvIHJlY29nbml6ZSBhIHByb3BlcnR5IG5hbWUgYnV0Ci0gICAgICogdGVtcG9yYXJpbHkgYmUgdW5hYmxlIHRvIHJldHVybiBpdHMgdmFsdWUuCi0gICAgICogU29tZSBwcm9wZXJ0eSB2YWx1ZXMgbWF5IGJlIGF2YWlsYWJsZSBvbmx5IGluIHNwZWNpZmljCi0gICAgICogY29udGV4dHMsIHN1Y2ggYXMgYmVmb3JlLCBkdXJpbmcsIG9yIGFmdGVyIGEgcGFyc2UuPC9wPgotICAgICAqCi0gICAgICogPHA+WE1MUmVhZGVycyBhcmUgbm90IHJlcXVpcmVkIHRvIHJlY29nbml6ZSBhbnkgc3BlY2lmaWMKLSAgICAgKiBwcm9wZXJ0eSBuYW1lcywgdGhvdWdoIGFuIGluaXRpYWwgY29yZSBzZXQgaXMgZG9jdW1lbnRlZCBmb3IKLSAgICAgKiBTQVgyLjwvcD4KLSAgICAgKgotICAgICAqIDxwPkltcGxlbWVudG9ycyBhcmUgZnJlZSAoYW5kIGVuY291cmFnZWQpIHRvIGludmVudCB0aGVpciBvd24gcHJvcGVydGllcywKLSAgICAgKiB1c2luZyBuYW1lcyBidWlsdCBvbiB0aGVpciBvd24gVVJJcy48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgcHJvcGVydHkgbmFtZSwgd2hpY2ggaXMgYSBmdWxseS1xdWFsaWZpZWQgVVJJLgotICAgICAqIEByZXR1cm4gVGhlIGN1cnJlbnQgdmFsdWUgb2YgdGhlIHByb3BlcnR5LgotICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiBJZiB0aGUgcHJvcGVydHkKLSAgICAgKiAgICAgICAgICAgIHZhbHVlIGNhbid0IGJlIGFzc2lnbmVkIG9yIHJldHJpZXZlZC4KLSAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBXaGVuIHRoZQotICAgICAqICAgICAgICAgICAgWE1MUmVhZGVyIHJlY29nbml6ZXMgdGhlIHByb3BlcnR5IG5hbWUgYnV0Ci0gICAgICogICAgICAgICAgICBjYW5ub3QgZGV0ZXJtaW5lIGl0cyB2YWx1ZSBhdCB0aGlzIHRpbWUuCi0gICAgICogQHNlZSAjc2V0UHJvcGVydHkKLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0IGdldFByb3BlcnR5IChTdHJpbmcgbmFtZSkKLSAgICAgICAgdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbjsKLQotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSB2YWx1ZSBvZiBhIHByb3BlcnR5LgotICAgICAqCi0gICAgICogPHA+VGhlIHByb3BlcnR5IG5hbWUgaXMgYW55IGZ1bGx5LXF1YWxpZmllZCBVUkkuICBJdCBpcwotICAgICAqIHBvc3NpYmxlIGZvciBhbiBYTUxSZWFkZXIgdG8gcmVjb2duaXplIGEgcHJvcGVydHkgbmFtZSBidXQKLSAgICAgKiB0byBiZSB1bmFibGUgdG8gY2hhbmdlIHRoZSBjdXJyZW50IHZhbHVlLgotICAgICAqIFNvbWUgcHJvcGVydHkgdmFsdWVzIG1heSBiZSBpbW11dGFibGUgb3IgbXV0YWJsZSBvbmx5Ci0gICAgICogaW4gc3BlY2lmaWMgY29udGV4dHMsIHN1Y2ggYXMgYmVmb3JlLCBkdXJpbmcsIG9yIGFmdGVyCi0gICAgICogYSBwYXJzZS48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5YTUxSZWFkZXJzIGFyZSBub3QgcmVxdWlyZWQgdG8gcmVjb2duaXplIHNldHRpbmcKLSAgICAgKiBhbnkgc3BlY2lmaWMgcHJvcGVydHkgbmFtZXMsIHRob3VnaCBhIGNvcmUgc2V0IGlzIGRlZmluZWQgYnkKLSAgICAgKiBTQVgyLjwvcD4KLSAgICAgKgotICAgICAqIDxwPlRoaXMgbWV0aG9kIGlzIGFsc28gdGhlIHN0YW5kYXJkIG1lY2hhbmlzbSBmb3Igc2V0dGluZwotICAgICAqIGV4dGVuZGVkIGhhbmRsZXJzLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBwcm9wZXJ0eSBuYW1lLCB3aGljaCBpcyBhIGZ1bGx5LXF1YWxpZmllZCBVUkkuCi0gICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXF1ZXN0ZWQgdmFsdWUgZm9yIHRoZSBwcm9wZXJ0eS4KLSAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24gSWYgdGhlIHByb3BlcnR5Ci0gICAgICogICAgICAgICAgICB2YWx1ZSBjYW4ndCBiZSBhc3NpZ25lZCBvciByZXRyaWV2ZWQuCi0gICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gV2hlbiB0aGUKLSAgICAgKiAgICAgICAgICAgIFhNTFJlYWRlciByZWNvZ25pemVzIHRoZSBwcm9wZXJ0eSBuYW1lIGJ1dAotICAgICAqICAgICAgICAgICAgY2Fubm90IHNldCB0aGUgcmVxdWVzdGVkIHZhbHVlLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFByb3BlcnR5IChTdHJpbmcgbmFtZSwgT2JqZWN0IHZhbHVlKQotICAgICAgICB0aHJvd3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiwgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uOwotCi0KLQotICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0gICAgLy8gRXZlbnQgaGFuZGxlcnMuCi0gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLQotCi0gICAgLyoqCi0gICAgICogQWxsb3cgYW4gYXBwbGljYXRpb24gdG8gcmVnaXN0ZXIgYW4gZW50aXR5IHJlc29sdmVyLgotICAgICAqCi0gICAgICogPHA+SWYgdGhlIGFwcGxpY2F0aW9uIGRvZXMgbm90IHJlZ2lzdGVyIGFuIGVudGl0eSByZXNvbHZlciwKLSAgICAgKiB0aGUgWE1MUmVhZGVyIHdpbGwgcGVyZm9ybSBpdHMgb3duIGRlZmF1bHQgcmVzb2x1dGlvbi48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5BcHBsaWNhdGlvbnMgbWF5IHJlZ2lzdGVyIGEgbmV3IG9yIGRpZmZlcmVudCByZXNvbHZlciBpbiB0aGUKLSAgICAgKiBtaWRkbGUgb2YgYSBwYXJzZSwgYW5kIHRoZSBTQVggcGFyc2VyIG11c3QgYmVnaW4gdXNpbmcgdGhlIG5ldwotICAgICAqIHJlc29sdmVyIGltbWVkaWF0ZWx5LjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSByZXNvbHZlciBUaGUgZW50aXR5IHJlc29sdmVyLgotICAgICAqIEBzZWUgI2dldEVudGl0eVJlc29sdmVyCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RW50aXR5UmVzb2x2ZXIgKEVudGl0eVJlc29sdmVyIHJlc29sdmVyKTsKLQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSBjdXJyZW50IGVudGl0eSByZXNvbHZlci4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIGN1cnJlbnQgZW50aXR5IHJlc29sdmVyLCBvciBudWxsIGlmIG5vbmUKLSAgICAgKiAgICAgICAgIGhhcyBiZWVuIHJlZ2lzdGVyZWQuCi0gICAgICogQHNlZSAjc2V0RW50aXR5UmVzb2x2ZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgRW50aXR5UmVzb2x2ZXIgZ2V0RW50aXR5UmVzb2x2ZXIgKCk7Ci0KLQotICAgIC8qKgotICAgICAqIEFsbG93IGFuIGFwcGxpY2F0aW9uIHRvIHJlZ2lzdGVyIGEgRFREIGV2ZW50IGhhbmRsZXIuCi0gICAgICoKLSAgICAgKiA8cD5JZiB0aGUgYXBwbGljYXRpb24gZG9lcyBub3QgcmVnaXN0ZXIgYSBEVEQgaGFuZGxlciwgYWxsIERURAotICAgICAqIGV2ZW50cyByZXBvcnRlZCBieSB0aGUgU0FYIHBhcnNlciB3aWxsIGJlIHNpbGVudGx5IGlnbm9yZWQuPC9wPgotICAgICAqCi0gICAgICogPHA+QXBwbGljYXRpb25zIG1heSByZWdpc3RlciBhIG5ldyBvciBkaWZmZXJlbnQgaGFuZGxlciBpbiB0aGUKLSAgICAgKiBtaWRkbGUgb2YgYSBwYXJzZSwgYW5kIHRoZSBTQVggcGFyc2VyIG11c3QgYmVnaW4gdXNpbmcgdGhlIG5ldwotICAgICAqIGhhbmRsZXIgaW1tZWRpYXRlbHkuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGhhbmRsZXIgVGhlIERURCBoYW5kbGVyLgotICAgICAqIEBzZWUgI2dldERUREhhbmRsZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXREVERIYW5kbGVyIChEVERIYW5kbGVyIGhhbmRsZXIpOwotCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIGN1cnJlbnQgRFREIGhhbmRsZXIuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBjdXJyZW50IERURCBoYW5kbGVyLCBvciBudWxsIGlmIG5vbmUKLSAgICAgKiAgICAgICAgIGhhcyBiZWVuIHJlZ2lzdGVyZWQuCi0gICAgICogQHNlZSAjc2V0RFRESGFuZGxlcgotICAgICAqLwotICAgIHB1YmxpYyBEVERIYW5kbGVyIGdldERUREhhbmRsZXIgKCk7Ci0KLQotICAgIC8qKgotICAgICAqIEFsbG93IGFuIGFwcGxpY2F0aW9uIHRvIHJlZ2lzdGVyIGEgY29udGVudCBldmVudCBoYW5kbGVyLgotICAgICAqCi0gICAgICogPHA+SWYgdGhlIGFwcGxpY2F0aW9uIGRvZXMgbm90IHJlZ2lzdGVyIGEgY29udGVudCBoYW5kbGVyLCBhbGwKLSAgICAgKiBjb250ZW50IGV2ZW50cyByZXBvcnRlZCBieSB0aGUgU0FYIHBhcnNlciB3aWxsIGJlIHNpbGVudGx5Ci0gICAgICogaWdub3JlZC48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5BcHBsaWNhdGlvbnMgbWF5IHJlZ2lzdGVyIGEgbmV3IG9yIGRpZmZlcmVudCBoYW5kbGVyIGluIHRoZQotICAgICAqIG1pZGRsZSBvZiBhIHBhcnNlLCBhbmQgdGhlIFNBWCBwYXJzZXIgbXVzdCBiZWdpbiB1c2luZyB0aGUgbmV3Ci0gICAgICogaGFuZGxlciBpbW1lZGlhdGVseS48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gaGFuZGxlciBUaGUgY29udGVudCBoYW5kbGVyLgotICAgICAqIEBzZWUgI2dldENvbnRlbnRIYW5kbGVyCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0Q29udGVudEhhbmRsZXIgKENvbnRlbnRIYW5kbGVyIGhhbmRsZXIpOwotCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIGN1cnJlbnQgY29udGVudCBoYW5kbGVyLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgY3VycmVudCBjb250ZW50IGhhbmRsZXIsIG9yIG51bGwgaWYgbm9uZQotICAgICAqICAgICAgICAgaGFzIGJlZW4gcmVnaXN0ZXJlZC4KLSAgICAgKiBAc2VlICNzZXRDb250ZW50SGFuZGxlcgotICAgICAqLwotICAgIHB1YmxpYyBDb250ZW50SGFuZGxlciBnZXRDb250ZW50SGFuZGxlciAoKTsKLQotCi0gICAgLyoqCi0gICAgICogQWxsb3cgYW4gYXBwbGljYXRpb24gdG8gcmVnaXN0ZXIgYW4gZXJyb3IgZXZlbnQgaGFuZGxlci4KLSAgICAgKgotICAgICAqIDxwPklmIHRoZSBhcHBsaWNhdGlvbiBkb2VzIG5vdCByZWdpc3RlciBhbiBlcnJvciBoYW5kbGVyLCBhbGwKLSAgICAgKiBlcnJvciBldmVudHMgcmVwb3J0ZWQgYnkgdGhlIFNBWCBwYXJzZXIgd2lsbCBiZSBzaWxlbnRseQotICAgICAqIGlnbm9yZWQ7IGhvd2V2ZXIsIG5vcm1hbCBwcm9jZXNzaW5nIG1heSBub3QgY29udGludWUuICBJdCBpcwotICAgICAqIGhpZ2hseSByZWNvbW1lbmRlZCB0aGF0IGFsbCBTQVggYXBwbGljYXRpb25zIGltcGxlbWVudCBhbgotICAgICAqIGVycm9yIGhhbmRsZXIgdG8gYXZvaWQgdW5leHBlY3RlZCBidWdzLjwvcD4KLSAgICAgKgotICAgICAqIDxwPkFwcGxpY2F0aW9ucyBtYXkgcmVnaXN0ZXIgYSBuZXcgb3IgZGlmZmVyZW50IGhhbmRsZXIgaW4gdGhlCi0gICAgICogbWlkZGxlIG9mIGEgcGFyc2UsIGFuZCB0aGUgU0FYIHBhcnNlciBtdXN0IGJlZ2luIHVzaW5nIHRoZSBuZXcKLSAgICAgKiBoYW5kbGVyIGltbWVkaWF0ZWx5LjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBoYW5kbGVyIFRoZSBlcnJvciBoYW5kbGVyLgotICAgICAqIEBzZWUgI2dldEVycm9ySGFuZGxlcgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEVycm9ySGFuZGxlciAoRXJyb3JIYW5kbGVyIGhhbmRsZXIpOwotCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIGN1cnJlbnQgZXJyb3IgaGFuZGxlci4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIGN1cnJlbnQgZXJyb3IgaGFuZGxlciwgb3IgbnVsbCBpZiBub25lCi0gICAgICogICAgICAgICBoYXMgYmVlbiByZWdpc3RlcmVkLgotICAgICAqIEBzZWUgI3NldEVycm9ySGFuZGxlcgotICAgICAqLwotICAgIHB1YmxpYyBFcnJvckhhbmRsZXIgZ2V0RXJyb3JIYW5kbGVyICgpOwotCi0KLQotICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0gICAgLy8gUGFyc2luZy4KLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotCi0gICAgLyoqCi0gICAgICogUGFyc2UgYW4gWE1MIGRvY3VtZW50LgotICAgICAqCi0gICAgICogPHA+VGhlIGFwcGxpY2F0aW9uIGNhbiB1c2UgdGhpcyBtZXRob2QgdG8gaW5zdHJ1Y3QgdGhlIFhNTAotICAgICAqIHJlYWRlciB0byBiZWdpbiBwYXJzaW5nIGFuIFhNTCBkb2N1bWVudCBmcm9tIGFueSB2YWxpZCBpbnB1dAotICAgICAqIHNvdXJjZSAoYSBjaGFyYWN0ZXIgc3RyZWFtLCBhIGJ5dGUgc3RyZWFtLCBvciBhIFVSSSkuPC9wPgotICAgICAqCi0gICAgICogPHA+QXBwbGljYXRpb25zIG1heSBub3QgaW52b2tlIHRoaXMgbWV0aG9kIHdoaWxlIGEgcGFyc2UgaXMgaW4KLSAgICAgKiBwcm9ncmVzcyAodGhleSBzaG91bGQgY3JlYXRlIGEgbmV3IFhNTFJlYWRlciBpbnN0ZWFkIGZvciBlYWNoCi0gICAgICogbmVzdGVkIFhNTCBkb2N1bWVudCkuICBPbmNlIGEgcGFyc2UgaXMgY29tcGxldGUsIGFuCi0gICAgICogYXBwbGljYXRpb24gbWF5IHJldXNlIHRoZSBzYW1lIFhNTFJlYWRlciBvYmplY3QsIHBvc3NpYmx5IHdpdGggYQotICAgICAqIGRpZmZlcmVudCBpbnB1dCBzb3VyY2UuCi0gICAgICogQ29uZmlndXJhdGlvbiBvZiB0aGUgWE1MUmVhZGVyIG9iamVjdCAoc3VjaCBhcyBoYW5kbGVyIGJpbmRpbmdzIGFuZAotICAgICAqIHZhbHVlcyBlc3RhYmxpc2hlZCBmb3IgZmVhdHVyZSBmbGFncyBhbmQgcHJvcGVydGllcykgaXMgdW5jaGFuZ2VkCi0gICAgICogYnkgY29tcGxldGlvbiBvZiBhIHBhcnNlLCB1bmxlc3MgdGhlIGRlZmluaXRpb24gb2YgdGhhdCBhc3BlY3Qgb2YKLSAgICAgKiB0aGUgY29uZmlndXJhdGlvbiBleHBsaWNpdGx5IHNwZWNpZmllcyBvdGhlciBiZWhhdmlvci4KLSAgICAgKiAoRm9yIGV4YW1wbGUsIGZlYXR1cmUgZmxhZ3Mgb3IgcHJvcGVydGllcyBleHBvc2luZwotICAgICAqIGNoYXJhY3RlcmlzdGljcyBvZiB0aGUgZG9jdW1lbnQgYmVpbmcgcGFyc2VkLikKLSAgICAgKiA8L3A+Ci0gICAgICoKLSAgICAgKiA8cD5EdXJpbmcgdGhlIHBhcnNlLCB0aGUgWE1MUmVhZGVyIHdpbGwgcHJvdmlkZSBpbmZvcm1hdGlvbgotICAgICAqIGFib3V0IHRoZSBYTUwgZG9jdW1lbnQgdGhyb3VnaCB0aGUgcmVnaXN0ZXJlZCBldmVudAotICAgICAqIGhhbmRsZXJzLjwvcD4KLSAgICAgKgotICAgICAqIDxwPlRoaXMgbWV0aG9kIGlzIHN5bmNocm9ub3VzOiBpdCB3aWxsIG5vdCByZXR1cm4gdW50aWwgcGFyc2luZwotICAgICAqIGhhcyBlbmRlZC4gIElmIGEgY2xpZW50IGFwcGxpY2F0aW9uIHdhbnRzIHRvIHRlcm1pbmF0ZQotICAgICAqIHBhcnNpbmcgZWFybHksIGl0IHNob3VsZCB0aHJvdyBhbiBleGNlcHRpb24uPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGlucHV0IFRoZSBpbnB1dCBzb3VyY2UgZm9yIHRoZSB0b3AtbGV2ZWwgb2YgdGhlCi0gICAgICogICAgICAgIFhNTCBkb2N1bWVudC4KLSAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgICAqIEBleGNlcHRpb24gamF2YS5pby5JT0V4Y2VwdGlvbiBBbiBJTyBleGNlcHRpb24gZnJvbSB0aGUgcGFyc2VyLAotICAgICAqICAgICAgICAgICAgcG9zc2libHkgZnJvbSBhIGJ5dGUgc3RyZWFtIG9yIGNoYXJhY3RlciBzdHJlYW0KLSAgICAgKiAgICAgICAgICAgIHN1cHBsaWVkIGJ5IHRoZSBhcHBsaWNhdGlvbi4KLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LklucHV0U291cmNlCi0gICAgICogQHNlZSAjcGFyc2UoamF2YS5sYW5nLlN0cmluZykKLSAgICAgKiBAc2VlICNzZXRFbnRpdHlSZXNvbHZlcgotICAgICAqIEBzZWUgI3NldERUREhhbmRsZXIKLSAgICAgKiBAc2VlICNzZXRDb250ZW50SGFuZGxlcgotICAgICAqIEBzZWUgI3NldEVycm9ySGFuZGxlcgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHBhcnNlIChJbnB1dFNvdXJjZSBpbnB1dCkKLSAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBTQVhFeGNlcHRpb247Ci0KLQotICAgIC8qKgotICAgICAqIFBhcnNlIGFuIFhNTCBkb2N1bWVudCBmcm9tIGEgc3lzdGVtIGlkZW50aWZpZXIgKFVSSSkuCi0gICAgICoKLSAgICAgKiA8cD5UaGlzIG1ldGhvZCBpcyBhIHNob3J0Y3V0IGZvciB0aGUgY29tbW9uIGNhc2Ugb2YgcmVhZGluZyBhCi0gICAgICogZG9jdW1lbnQgZnJvbSBhIHN5c3RlbSBpZGVudGlmaWVyLiAgSXQgaXMgdGhlIGV4YWN0Ci0gICAgICogZXF1aXZhbGVudCBvZiB0aGUgZm9sbG93aW5nOjwvcD4KLSAgICAgKgotICAgICAqIDxwcmU+Ci0gICAgICogcGFyc2UobmV3IElucHV0U291cmNlKHN5c3RlbUlkKSk7Ci0gICAgICogPC9wcmU+Ci0gICAgICoKLSAgICAgKiA8cD5JZiB0aGUgc3lzdGVtIGlkZW50aWZpZXIgaXMgYSBVUkwsIGl0IG11c3QgYmUgZnVsbHkgcmVzb2x2ZWQKLSAgICAgKiBieSB0aGUgYXBwbGljYXRpb24gYmVmb3JlIGl0IGlzIHBhc3NlZCB0byB0aGUgcGFyc2VyLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzeXN0ZW1JZCBUaGUgc3lzdGVtIGlkZW50aWZpZXIgKFVSSSkuCi0gICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICAgKiBAZXhjZXB0aW9uIGphdmEuaW8uSU9FeGNlcHRpb24gQW4gSU8gZXhjZXB0aW9uIGZyb20gdGhlIHBhcnNlciwKLSAgICAgKiAgICAgICAgICAgIHBvc3NpYmx5IGZyb20gYSBieXRlIHN0cmVhbSBvciBjaGFyYWN0ZXIgc3RyZWFtCi0gICAgICogICAgICAgICAgICBzdXBwbGllZCBieSB0aGUgYXBwbGljYXRpb24uCi0gICAgICogQHNlZSAjcGFyc2Uob3JnLnhtbC5zYXguSW5wdXRTb3VyY2UpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcGFyc2UgKFN0cmluZyBzeXN0ZW1JZCkKLSAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBTQVhFeGNlcHRpb247Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcveG1sL3NheC9leHQvQXR0cmlidXRlczIuamF2YSBiL3NyYy9vcmcveG1sL3NheC9leHQvQXR0cmlidXRlczIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNGM3MDIzZC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3htbC9zYXgvZXh0L0F0dHJpYnV0ZXMyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNTYgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwNCwgMjAwNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLy8gQXR0cmlidXRlczIuamF2YSAtIGV4dGVuZGVkIEF0dHJpYnV0ZXMKLS8vIGh0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmcKLS8vIFB1YmxpYyBEb21haW46IG5vIHdhcnJhbnR5LgotLy8gJElkOiBBdHRyaWJ1dGVzMi5qYXZhLHYgMS4yIDIwMDQvMTEvMDMgMjI6NDk6MDcganN1dHRvciBFeHAgJAotCi1wYWNrYWdlIG9yZy54bWwuc2F4LmV4dDsKLQotaW1wb3J0IG9yZy54bWwuc2F4LkF0dHJpYnV0ZXM7Ci0KLQotLyoqCi0gKiBTQVgyIGV4dGVuc2lvbiB0byBhdWdtZW50IHRoZSBwZXItYXR0cmlidXRlIGluZm9ybWF0aW9uCi0gKiBwcm92aWRlZCB0aG91Z2gge0BsaW5rIEF0dHJpYnV0ZXN9LgotICogSWYgYW4gaW1wbGVtZW50YXRpb24gc3VwcG9ydHMgdGhpcyBleHRlbnNpb24sIHRoZSBhdHRyaWJ1dGVzCi0gKiBwcm92aWRlZCBpbiB7QGxpbmsgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjc3RhcnRFbGVtZW50Ci0gKiBDb250ZW50SGFuZGxlci5zdGFydEVsZW1lbnQoKSB9IHdpbGwgaW1wbGVtZW50IHRoaXMgaW50ZXJmYWNlLAotICogYW5kIHRoZSA8ZW0+aHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL3VzZS1hdHRyaWJ1dGVzMjwvZW0+Ci0gKiBmZWF0dXJlIGZsYWcgd2lsbCBoYXZlIHRoZSB2YWx1ZSA8ZW0+dHJ1ZTwvZW0+LgotICoKLSAqIDxibG9ja3F1b3RlPgotICogPGVtPlRoaXMgbW9kdWxlLCBib3RoIHNvdXJjZSBjb2RlIGFuZCBkb2N1bWVudGF0aW9uLCBpcyBpbiB0aGUKLSAqIFB1YmxpYyBEb21haW4sIGFuZCBjb21lcyB3aXRoIDxzdHJvbmc+Tk8gV0FSUkFOVFk8L3N0cm9uZz4uPC9lbT4KLSAqIDwvYmxvY2txdW90ZT4KLSAqCi0gKiA8cD4gWE1MUmVhZGVyIGltcGxlbWVudGF0aW9ucyBhcmUgbm90IHJlcXVpcmVkIHRvIHN1cHBvcnQgdGhpcwotICogaW5mb3JtYXRpb24sIGFuZCBpdCBpcyBub3QgcGFydCBvZiBjb3JlLW9ubHkgU0FYMiBkaXN0cmlidXRpb25zLjwvcD4KLSAqCi0gKiA8cD5Ob3RlIHRoYXQgaWYgYW4gYXR0cmlidXRlIHdhcyBkZWZhdWx0ZWQgKDxlbT4haXNTcGVjaWZpZWQoKTwvZW0+KQotICogaXQgd2lsbCBvZiBuZWNlc3NpdHkgYWxzbyBoYXZlIGJlZW4gZGVjbGFyZWQgKDxlbT5pc0RlY2xhcmVkKCk8L2VtPikKLSAqIGluIHRoZSBEVEQuCi0gKiBTaW1pbGFybHkgaWYgYW4gYXR0cmlidXRlJ3MgdHlwZSBpcyBhbnl0aGluZyBleGNlcHQgQ0RBVEEsIHRoZW4gaXQKLSAqIG11c3QgaGF2ZSBiZWVuIGRlY2xhcmVkLgotICogPC9wPgotICoKLSAqIEBzaW5jZSBTQVggMi4wIChleHRlbnNpb25zIDEuMSBhbHBoYSkKLSAqIEBhdXRob3IgRGF2aWQgQnJvd25lbGwKLSAqLwotcHVibGljIGludGVyZmFjZSBBdHRyaWJ1dGVzMiBleHRlbmRzIEF0dHJpYnV0ZXMKLXsKLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGZhbHNlIHVubGVzcyB0aGUgYXR0cmlidXRlIHdhcyBkZWNsYXJlZCBpbiB0aGUgRFRELgotICAgICAqIFRoaXMgaGVscHMgZGlzdGluZ3Vpc2ggdHdvIGtpbmRzIG9mIGF0dHJpYnV0ZXMgdGhhdCBTQVggcmVwb3J0cwotICAgICAqIGFzIENEQVRBOiAgb25lcyB0aGF0IHdlcmUgZGVjbGFyZWQgKGFuZCBoZW5jZSBhcmUgdXN1YWxseSB2YWxpZCksCi0gICAgICogYW5kIHRob3NlIHRoYXQgd2VyZSBub3QgKGFuZCB3aGljaCBhcmUgbmV2ZXIgdmFsaWQpLgotICAgICAqCi0gICAgICogQHBhcmFtIGluZGV4IFRoZSBhdHRyaWJ1dGUgaW5kZXggKHplcm8tYmFzZWQpLgotICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgYXR0cmlidXRlIHdhcyBkZWNsYXJlZCBpbiB0aGUgRFRELAotICAgICAqICAgICAgICAgIGZhbHNlIG90aGVyd2lzZS4KLSAgICAgKiBAZXhjZXB0aW9uIGphdmEubGFuZy5BcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gV2hlbiB0aGUKLSAgICAgKiAgICAgICAgICAgIHN1cHBsaWVkIGluZGV4IGRvZXMgbm90IGlkZW50aWZ5IGFuIGF0dHJpYnV0ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0RlY2xhcmVkIChpbnQgaW5kZXgpOwotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBmYWxzZSB1bmxlc3MgdGhlIGF0dHJpYnV0ZSB3YXMgZGVjbGFyZWQgaW4gdGhlIERURC4KLSAgICAgKiBUaGlzIGhlbHBzIGRpc3Rpbmd1aXNoIHR3byBraW5kcyBvZiBhdHRyaWJ1dGVzIHRoYXQgU0FYIHJlcG9ydHMKLSAgICAgKiBhcyBDREFUQTogIG9uZXMgdGhhdCB3ZXJlIGRlY2xhcmVkIChhbmQgaGVuY2UgYXJlIHVzdWFsbHkgdmFsaWQpLAotICAgICAqIGFuZCB0aG9zZSB0aGF0IHdlcmUgbm90IChhbmQgd2hpY2ggYXJlIG5ldmVyIHZhbGlkKS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBxTmFtZSBUaGUgWE1MIHF1YWxpZmllZCAocHJlZml4ZWQpIG5hbWUuCi0gICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBhdHRyaWJ1dGUgd2FzIGRlY2xhcmVkIGluIHRoZSBEVEQsCi0gICAgICogICAgICAgICAgZmFsc2Ugb3RoZXJ3aXNlLgotICAgICAqIEBleGNlcHRpb24gamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBXaGVuIHRoZQotICAgICAqICAgICAgICAgICAgc3VwcGxpZWQgbmFtZSBkb2VzIG5vdCBpZGVudGlmeSBhbiBhdHRyaWJ1dGUuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNEZWNsYXJlZCAoU3RyaW5nIHFOYW1lKTsKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgZmFsc2UgdW5sZXNzIHRoZSBhdHRyaWJ1dGUgd2FzIGRlY2xhcmVkIGluIHRoZSBEVEQuCi0gICAgICogVGhpcyBoZWxwcyBkaXN0aW5ndWlzaCB0d28ga2luZHMgb2YgYXR0cmlidXRlcyB0aGF0IFNBWCByZXBvcnRzCi0gICAgICogYXMgQ0RBVEE6ICBvbmVzIHRoYXQgd2VyZSBkZWNsYXJlZCAoYW5kIGhlbmNlIGFyZSB1c3VhbGx5IHZhbGlkKSwKLSAgICAgKiBhbmQgdGhvc2UgdGhhdCB3ZXJlIG5vdCAoYW5kIHdoaWNoIGFyZSBuZXZlciB2YWxpZCkuCi0gICAgICoKLSAgICAgKiA8cD5SZW1lbWJlciB0aGF0IHNpbmNlIERURHMgZG8gbm90ICJ1bmRlcnN0YW5kIiBuYW1lc3BhY2VzLCB0aGUKLSAgICAgKiBuYW1lc3BhY2UgVVJJIGFzc29jaWF0ZWQgd2l0aCBhbiBhdHRyaWJ1dGUgbWF5IG5vdCBoYXZlIGNvbWUgZnJvbQotICAgICAqIHRoZSBEVEQuICBUaGUgZGVjbGFyYXRpb24gd2lsbCBoYXZlIGFwcGxpZWQgdG8gdGhlIGF0dHJpYnV0ZSdzCi0gICAgICogPGVtPnFOYW1lPC9lbT4uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdXJpIFRoZSBOYW1lc3BhY2UgVVJJLCBvciB0aGUgZW1wdHkgc3RyaW5nIGlmCi0gICAgICogICAgICAgIHRoZSBuYW1lIGhhcyBubyBOYW1lc3BhY2UgVVJJLgotICAgICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGF0dHJpYnV0ZSdzIGxvY2FsIG5hbWUuCi0gICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBhdHRyaWJ1dGUgd2FzIGRlY2xhcmVkIGluIHRoZSBEVEQsCi0gICAgICogICAgICAgICAgZmFsc2Ugb3RoZXJ3aXNlLgotICAgICAqIEBleGNlcHRpb24gamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBXaGVuIHRoZQotICAgICAqICAgICAgICAgICAgc3VwcGxpZWQgbmFtZXMgZG8gbm90IGlkZW50aWZ5IGFuIGF0dHJpYnV0ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0RlY2xhcmVkIChTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxOYW1lKTsKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdHJ1ZSB1bmxlc3MgdGhlIGF0dHJpYnV0ZSB2YWx1ZSB3YXMgcHJvdmlkZWQKLSAgICAgKiBieSBEVEQgZGVmYXVsdGluZy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBpbmRleCBUaGUgYXR0cmlidXRlIGluZGV4ICh6ZXJvLWJhc2VkKS4KLSAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHZhbHVlIHdhcyBmb3VuZCBpbiB0aGUgWE1MIHRleHQsCi0gICAgICogICAgICAgICAgZmFsc2UgaWYgdGhlIHZhbHVlIHdhcyBwcm92aWRlZCBieSBEVEQgZGVmYXVsdGluZy4KLSAgICAgKiBAZXhjZXB0aW9uIGphdmEubGFuZy5BcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gV2hlbiB0aGUKLSAgICAgKiAgICAgICAgICAgIHN1cHBsaWVkIGluZGV4IGRvZXMgbm90IGlkZW50aWZ5IGFuIGF0dHJpYnV0ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc1NwZWNpZmllZCAoaW50IGluZGV4KTsKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdHJ1ZSB1bmxlc3MgdGhlIGF0dHJpYnV0ZSB2YWx1ZSB3YXMgcHJvdmlkZWQKLSAgICAgKiBieSBEVEQgZGVmYXVsdGluZy4KLSAgICAgKgotICAgICAqIDxwPlJlbWVtYmVyIHRoYXQgc2luY2UgRFREcyBkbyBub3QgInVuZGVyc3RhbmQiIG5hbWVzcGFjZXMsIHRoZQotICAgICAqIG5hbWVzcGFjZSBVUkkgYXNzb2NpYXRlZCB3aXRoIGFuIGF0dHJpYnV0ZSBtYXkgbm90IGhhdmUgY29tZSBmcm9tCi0gICAgICogdGhlIERURC4gIFRoZSBkZWNsYXJhdGlvbiB3aWxsIGhhdmUgYXBwbGllZCB0byB0aGUgYXR0cmlidXRlJ3MKLSAgICAgKiA8ZW0+cU5hbWU8L2VtPi4KLSAgICAgKgotICAgICAqIEBwYXJhbSB1cmkgVGhlIE5hbWVzcGFjZSBVUkksIG9yIHRoZSBlbXB0eSBzdHJpbmcgaWYKLSAgICAgKiAgICAgICAgdGhlIG5hbWUgaGFzIG5vIE5hbWVzcGFjZSBVUkkuCi0gICAgICogQHBhcmFtIGxvY2FsTmFtZSBUaGUgYXR0cmlidXRlJ3MgbG9jYWwgbmFtZS4KLSAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHZhbHVlIHdhcyBmb3VuZCBpbiB0aGUgWE1MIHRleHQsCi0gICAgICogICAgICAgICAgZmFsc2UgaWYgdGhlIHZhbHVlIHdhcyBwcm92aWRlZCBieSBEVEQgZGVmYXVsdGluZy4KLSAgICAgKiBAZXhjZXB0aW9uIGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gV2hlbiB0aGUKLSAgICAgKiAgICAgICAgICAgIHN1cHBsaWVkIG5hbWVzIGRvIG5vdCBpZGVudGlmeSBhbiBhdHRyaWJ1dGUuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNTcGVjaWZpZWQgKFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUpOwotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIHVubGVzcyB0aGUgYXR0cmlidXRlIHZhbHVlIHdhcyBwcm92aWRlZAotICAgICAqIGJ5IERURCBkZWZhdWx0aW5nLgotICAgICAqCi0gICAgICogQHBhcmFtIHFOYW1lIFRoZSBYTUwgcXVhbGlmaWVkIChwcmVmaXhlZCkgbmFtZS4KLSAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHZhbHVlIHdhcyBmb3VuZCBpbiB0aGUgWE1MIHRleHQsCi0gICAgICogICAgICAgICAgZmFsc2UgaWYgdGhlIHZhbHVlIHdhcyBwcm92aWRlZCBieSBEVEQgZGVmYXVsdGluZy4KLSAgICAgKiBAZXhjZXB0aW9uIGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gV2hlbiB0aGUKLSAgICAgKiAgICAgICAgICAgIHN1cHBsaWVkIG5hbWUgZG9lcyBub3QgaWRlbnRpZnkgYW4gYXR0cmlidXRlLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzU3BlY2lmaWVkIChTdHJpbmcgcU5hbWUpOwotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy94bWwvc2F4L2V4dC9BdHRyaWJ1dGVzMkltcGwuamF2YSBiL3NyYy9vcmcveG1sL3NheC9leHQvQXR0cmlidXRlczJJbXBsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGFhYmIwYjkuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy94bWwvc2F4L2V4dC9BdHRyaWJ1dGVzMkltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDMzMiArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDA0LCAyMDA1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vLyBBdHRyaWJ1dGVzMkltcGwuamF2YSAtIGV4dGVuZGVkIEF0dHJpYnV0ZXNJbXBsCi0vLyBodHRwOi8vd3d3LnNheHByb2plY3Qub3JnCi0vLyBQdWJsaWMgRG9tYWluOiBubyB3YXJyYW50eS4KLS8vICRJZDogQXR0cmlidXRlczJJbXBsLmphdmEsdiAxLjMgMjAwNS8wMi8yNCAxMToyMDoxOCBnZzE1NjczOSBFeHAgJAotCi1wYWNrYWdlIG9yZy54bWwuc2F4LmV4dDsKLQotaW1wb3J0IG9yZy54bWwuc2F4LkF0dHJpYnV0ZXM7Ci1pbXBvcnQgb3JnLnhtbC5zYXguaGVscGVycy5BdHRyaWJ1dGVzSW1wbDsKLQotCi0vKioKLSAqIFNBWDIgZXh0ZW5zaW9uIGhlbHBlciBmb3IgYWRkaXRpb25hbCBBdHRyaWJ1dGVzIGluZm9ybWF0aW9uLAotICogaW1wbGVtZW50aW5nIHRoZSB7QGxpbmsgQXR0cmlidXRlczJ9IGludGVyZmFjZS4KLSAqCi0gKiA8YmxvY2txdW90ZT4KLSAqIDxlbT5UaGlzIG1vZHVsZSwgYm90aCBzb3VyY2UgY29kZSBhbmQgZG9jdW1lbnRhdGlvbiwgaXMgaW4gdGhlCi0gKiBQdWJsaWMgRG9tYWluLCBhbmQgY29tZXMgd2l0aCA8c3Ryb25nPk5PIFdBUlJBTlRZPC9zdHJvbmc+LjwvZW0+Ci0gKiA8L2Jsb2NrcXVvdGU+Ci0gKgotICogPHA+VGhpcyBpcyBub3QgcGFydCBvZiBjb3JlLW9ubHkgU0FYMiBkaXN0cmlidXRpb25zLjwvcD4KLSAqCi0gKiA8cD5UaGUgPGVtPnNwZWNpZmllZDwvZW0+IGZsYWcgZm9yIGVhY2ggYXR0cmlidXRlIHdpbGwgYWx3YXlzCi0gKiBiZSB0cnVlLCB1bmxlc3MgaXQgaGFzIGJlZW4gc2V0IHRvIGZhbHNlIGluIHRoZSBjb3B5IGNvbnN0cnVjdG9yCi0gKiBvciB1c2luZyB7QGxpbmsgI3NldFNwZWNpZmllZH0uCi0gKiBTaW1pbGFybHksIHRoZSA8ZW0+ZGVjbGFyZWQ8L2VtPiBmbGFnIGZvciBlYWNoIGF0dHJpYnV0ZSB3aWxsCi0gKiBhbHdheXMgYmUgZmFsc2UsIGV4Y2VwdCBmb3IgZGVmYXVsdGVkIGF0dHJpYnV0ZXMgKDxlbT5zcGVjaWZpZWQ8L2VtPgotICogaXMgZmFsc2UpLCBub24tQ0RBVEEgYXR0cmlidXRlcywgb3Igd2hlbiBpdCBpcyBzZXQgdG8gdHJ1ZSB1c2luZwotICoge0BsaW5rICNzZXREZWNsYXJlZH0uCi0gKiBJZiB5b3UgY2hhbmdlIGFuIGF0dHJpYnV0ZSdzIHR5cGUgYnkgaGFuZCwgeW91IG1heSBuZWVkIHRvIG1vZGlmeQotICogaXRzIDxlbT5kZWNsYXJlZDwvZW0+IGZsYWcgdG8gbWF0Y2guCi0gKiA8L3A+Ci0gKgotICogQHNpbmNlIFNBWCAyLjAgKGV4dGVuc2lvbnMgMS4xIGFscGhhKQotICogQGF1dGhvciBEYXZpZCBCcm93bmVsbAotICovCi1wdWJsaWMgY2xhc3MgQXR0cmlidXRlczJJbXBsIGV4dGVuZHMgQXR0cmlidXRlc0ltcGwgaW1wbGVtZW50cyBBdHRyaWJ1dGVzMgotewotICAgIHByaXZhdGUgYm9vbGVhbiAgICAgZGVjbGFyZWQgW107Ci0gICAgcHJpdmF0ZSBib29sZWFuICAgICBzcGVjaWZpZWQgW107Ci0KLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdCBhIG5ldywgZW1wdHkgQXR0cmlidXRlczJJbXBsIG9iamVjdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgQXR0cmlidXRlczJJbXBsICgpIHsKLSAgICAgICAgc3BlY2lmaWVkID0gbnVsbDsKLSAgICAgICAgZGVjbGFyZWQgPSBudWxsOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogQ29weSBhbiBleGlzdGluZyBBdHRyaWJ1dGVzIG9yIEF0dHJpYnV0ZXMyIG9iamVjdC4KLSAgICAgKiBJZiB0aGUgb2JqZWN0IGltcGxlbWVudHMgQXR0cmlidXRlczIsIHZhbHVlcyBvZiB0aGUKLSAgICAgKiA8ZW0+c3BlY2lmaWVkPC9lbT4gYW5kIDxlbT5kZWNsYXJlZDwvZW0+IGZsYWdzIGZvciBlYWNoCi0gICAgICogYXR0cmlidXRlIGFyZSBjb3BpZWQuCi0gICAgICogT3RoZXJ3aXNlIHRoZSBmbGFnIHZhbHVlcyBhcmUgZGVmYXVsdGVkIHRvIGFzc3VtZSBubyBEVEQgd2FzIHVzZWQsCi0gICAgICogdW5sZXNzIHRoZXJlIGlzIGV2aWRlbmNlIHRvIHRoZSBjb250cmFyeSAoc3VjaCBhcyBhdHRyaWJ1dGVzIHdpdGgKLSAgICAgKiB0eXBlIG90aGVyIHRoYW4gQ0RBVEEsIHdoaWNoIG11c3QgaGF2ZSBiZWVuIDxlbT5kZWNsYXJlZDwvZW0+KS4KLSAgICAgKgotICAgICAqIDxwPlRoaXMgY29uc3RydWN0b3IgaXMgZXNwZWNpYWxseSB1c2VmdWwgaW5zaWRlIGEKLSAgICAgKiB7QGxpbmsgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjc3RhcnRFbGVtZW50IHN0YXJ0RWxlbWVudH0gZXZlbnQuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGF0dHMgVGhlIGV4aXN0aW5nIEF0dHJpYnV0ZXMgb2JqZWN0LgotICAgICAqLwotICAgIHB1YmxpYyBBdHRyaWJ1dGVzMkltcGwgKEF0dHJpYnV0ZXMgYXR0cykKLSAgICB7Ci0gICAgICAgIHN1cGVyIChhdHRzKTsKLSAgICB9Ci0KLQotICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0gICAgLy8gSW1wbGVtZW50YXRpb24gb2YgQXR0cmlidXRlczIKLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUncyAiZGVjbGFyZWQiIGZsYWcuCi0gICAgICovCi0gICAgLy8gamF2YWRvYyBtb3N0bHkgZnJvbSBpbnRlcmZhY2UKLSAgICBwdWJsaWMgYm9vbGVhbiBpc0RlY2xhcmVkIChpbnQgaW5kZXgpCi0gICAgewotICAgICAgICBpZiAoaW5kZXggPCAwIHx8IGluZGV4ID49IGdldExlbmd0aCAoKSkKLSAgICAgICAgICAgIHRocm93IG5ldyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gKAotICAgICAgICAgICAgICAgICJObyBhdHRyaWJ1dGUgYXQgaW5kZXg6ICIgKyBpbmRleCk7Ci0gICAgICAgIHJldHVybiBkZWNsYXJlZCBbaW5kZXhdOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgYXR0cmlidXRlJ3MgImRlY2xhcmVkIiBmbGFnLgotICAgICAqLwotICAgIC8vIGphdmFkb2MgbW9zdGx5IGZyb20gaW50ZXJmYWNlCi0gICAgcHVibGljIGJvb2xlYW4gaXNEZWNsYXJlZCAoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSkKLSAgICB7Ci0gICAgICAgIGludCBpbmRleCA9IGdldEluZGV4ICh1cmksIGxvY2FsTmFtZSk7Ci0KLSAgICAgICAgaWYgKGluZGV4IDwgMCkKLSAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gKAotICAgICAgICAgICAgICAgICJObyBzdWNoIGF0dHJpYnV0ZTogbG9jYWw9IiArIGxvY2FsTmFtZQotICAgICAgICAgICAgICAgICsgIiwgbmFtZXNwYWNlPSIgKyB1cmkpOwotICAgICAgICByZXR1cm4gZGVjbGFyZWQgW2luZGV4XTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIGN1cnJlbnQgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZSdzICJkZWNsYXJlZCIgZmxhZy4KLSAgICAgKi8KLSAgICAvLyBqYXZhZG9jIG1vc3RseSBmcm9tIGludGVyZmFjZQotICAgIHB1YmxpYyBib29sZWFuIGlzRGVjbGFyZWQgKFN0cmluZyBxTmFtZSkKLSAgICB7Ci0gICAgICAgIGludCBpbmRleCA9IGdldEluZGV4IChxTmFtZSk7Ci0KLSAgICAgICAgaWYgKGluZGV4IDwgMCkKLSAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gKAotICAgICAgICAgICAgICAgICJObyBzdWNoIGF0dHJpYnV0ZTogIiArIHFOYW1lKTsKLSAgICAgICAgcmV0dXJuIGRlY2xhcmVkIFtpbmRleF07Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IHZhbHVlIG9mIGFuIGF0dHJpYnV0ZSdzICJzcGVjaWZpZWQiIGZsYWcuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGF0dHJpYnV0ZSBpbmRleCAoemVyby1iYXNlZCkuCi0gICAgICogQHJldHVybiBjdXJyZW50IGZsYWcgdmFsdWUKLSAgICAgKiBAZXhjZXB0aW9uIGphdmEubGFuZy5BcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gV2hlbiB0aGUKLSAgICAgKiAgICAgICAgICAgIHN1cHBsaWVkIGluZGV4IGRvZXMgbm90IGlkZW50aWZ5IGFuIGF0dHJpYnV0ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc1NwZWNpZmllZCAoaW50IGluZGV4KQotICAgIHsKLSAgICAgICAgaWYgKGluZGV4IDwgMCB8fCBpbmRleCA+PSBnZXRMZW5ndGggKCkpCi0gICAgICAgICAgICB0aHJvdyBuZXcgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uICgKLSAgICAgICAgICAgICAgICAiTm8gYXR0cmlidXRlIGF0IGluZGV4OiAiICsgaW5kZXgpOwotICAgICAgICByZXR1cm4gc3BlY2lmaWVkIFtpbmRleF07Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IHZhbHVlIG9mIGFuIGF0dHJpYnV0ZSdzICJzcGVjaWZpZWQiIGZsYWcuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdXJpIFRoZSBOYW1lc3BhY2UgVVJJLCBvciB0aGUgZW1wdHkgc3RyaW5nIGlmCi0gICAgICogICAgICAgIHRoZSBuYW1lIGhhcyBubyBOYW1lc3BhY2UgVVJJLgotICAgICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGF0dHJpYnV0ZSdzIGxvY2FsIG5hbWUuCi0gICAgICogQHJldHVybiBjdXJyZW50IGZsYWcgdmFsdWUKLSAgICAgKiBAZXhjZXB0aW9uIGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gV2hlbiB0aGUKLSAgICAgKiAgICAgICAgICAgIHN1cHBsaWVkIG5hbWVzIGRvIG5vdCBpZGVudGlmeSBhbiBhdHRyaWJ1dGUuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNTcGVjaWZpZWQgKFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUpCi0gICAgewotICAgICAgICBpbnQgaW5kZXggPSBnZXRJbmRleCAodXJpLCBsb2NhbE5hbWUpOwotCi0gICAgICAgIGlmIChpbmRleCA8IDApCi0gICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uICgKLSAgICAgICAgICAgICAgICAiTm8gc3VjaCBhdHRyaWJ1dGU6IGxvY2FsPSIgKyBsb2NhbE5hbWUKLSAgICAgICAgICAgICAgICArICIsIG5hbWVzcGFjZT0iICsgdXJpKTsKLSAgICAgICAgcmV0dXJuIHNwZWNpZmllZCBbaW5kZXhdOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgY3VycmVudCB2YWx1ZSBvZiBhbiBhdHRyaWJ1dGUncyAic3BlY2lmaWVkIiBmbGFnLgotICAgICAqCi0gICAgICogQHBhcmFtIHFOYW1lIFRoZSBYTUwgcXVhbGlmaWVkIChwcmVmaXhlZCkgbmFtZS4KLSAgICAgKiBAcmV0dXJuIGN1cnJlbnQgZmxhZyB2YWx1ZQotICAgICAqIEBleGNlcHRpb24gamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBXaGVuIHRoZQotICAgICAqICAgICAgICAgICAgc3VwcGxpZWQgbmFtZSBkb2VzIG5vdCBpZGVudGlmeSBhbiBhdHRyaWJ1dGUuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNTcGVjaWZpZWQgKFN0cmluZyBxTmFtZSkKLSAgICB7Ci0gICAgICAgIGludCBpbmRleCA9IGdldEluZGV4IChxTmFtZSk7Ci0KLSAgICAgICAgaWYgKGluZGV4IDwgMCkKLSAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gKAotICAgICAgICAgICAgICAgICJObyBzdWNoIGF0dHJpYnV0ZTogIiArIHFOYW1lKTsKLSAgICAgICAgcmV0dXJuIHNwZWNpZmllZCBbaW5kZXhdOwotICAgIH0KLQotCi0gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLSAgICAvLyBNYW5pcHVsYXRvcnMKLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotCi0KLSAgICAvKioKLSAgICAgKiBDb3B5IGFuIGVudGlyZSBBdHRyaWJ1dGVzIG9iamVjdC4gIFRoZSAic3BlY2lmaWVkIiBmbGFncyBhcmUKLSAgICAgKiBhc3NpZ25lZCBhcyB0cnVlLCBhbmQgImRlY2xhcmVkIiBmbGFncyBhcyBmYWxzZSAoZXhjZXB0IHdoZW4KLSAgICAgKiBhbiBhdHRyaWJ1dGUncyB0eXBlIGlzIG5vdCBDREFUQSksCi0gICAgICogdW5sZXNzIHRoZSBvYmplY3QgaXMgYW4gQXR0cmlidXRlczIgb2JqZWN0LgotICAgICAqIEluIHRoYXQgY2FzZSB0aG9zZSBmbGFnIHZhbHVlcyBhcmUgYWxsIGNvcGllZC4KLSAgICAgKgotICAgICAqIEBzZWUgQXR0cmlidXRlc0ltcGwjc2V0QXR0cmlidXRlcwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEF0dHJpYnV0ZXMgKEF0dHJpYnV0ZXMgYXR0cykKLSAgICB7Ci0gICAgICAgIGludCBsZW5ndGggPSBhdHRzLmdldExlbmd0aCAoKTsKLQotICAgICAgICBzdXBlci5zZXRBdHRyaWJ1dGVzIChhdHRzKTsKLSAgICAgICAgZGVjbGFyZWQgPSBuZXcgYm9vbGVhbiBbbGVuZ3RoXTsKLSAgICAgICAgc3BlY2lmaWVkID0gbmV3IGJvb2xlYW4gW2xlbmd0aF07Ci0KLSAgICAgICAgaWYgKGF0dHMgaW5zdGFuY2VvZiBBdHRyaWJ1dGVzMikgewotICAgICAgICAgICAgQXR0cmlidXRlczIgYTIgPSAoQXR0cmlidXRlczIpIGF0dHM7Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgZGVjbGFyZWQgW2ldID0gYTIuaXNEZWNsYXJlZCAoaSk7Ci0gICAgICAgICAgICAgICAgc3BlY2lmaWVkIFtpXSA9IGEyLmlzU3BlY2lmaWVkIChpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgICAgICBkZWNsYXJlZCBbaV0gPSAhIkNEQVRBIi5lcXVhbHMgKGF0dHMuZ2V0VHlwZSAoaSkpOwotICAgICAgICAgICAgICAgIHNwZWNpZmllZCBbaV0gPSB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBBZGQgYW4gYXR0cmlidXRlIHRvIHRoZSBlbmQgb2YgdGhlIGxpc3QsIHNldHRpbmcgaXRzCi0gICAgICogInNwZWNpZmllZCIgZmxhZyB0byB0cnVlLiAgVG8gc2V0IHRoYXQgZmxhZydzIHZhbHVlCi0gICAgICogdG8gZmFsc2UsIHVzZSB7QGxpbmsgI3NldFNwZWNpZmllZH0uCi0gICAgICoKLSAgICAgKiA8cD5Vbmxlc3MgdGhlIGF0dHJpYnV0ZSA8ZW0+dHlwZTwvZW0+IGlzIENEQVRBLCB0aGlzIGF0dHJpYnV0ZQotICAgICAqIGlzIG1hcmtlZCBhcyBiZWluZyBkZWNsYXJlZCBpbiB0aGUgRFRELiAgVG8gc2V0IHRoYXQgZmxhZydzIHZhbHVlCi0gICAgICogdG8gdHJ1ZSBmb3IgQ0RBVEEgYXR0cmlidXRlcywgdXNlIHtAbGluayAjc2V0RGVjbGFyZWR9LgotICAgICAqCi0gICAgICogQHNlZSBBdHRyaWJ1dGVzSW1wbCNhZGRBdHRyaWJ1dGUKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBhZGRBdHRyaWJ1dGUgKFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUsIFN0cmluZyBxTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyB0eXBlLCBTdHJpbmcgdmFsdWUpCi0gICAgewotICAgICAgICBzdXBlci5hZGRBdHRyaWJ1dGUgKHVyaSwgbG9jYWxOYW1lLCBxTmFtZSwgdHlwZSwgdmFsdWUpOwotCi0KLSAgICAgICAgaW50IGxlbmd0aCA9IGdldExlbmd0aCAoKTsKLSAgICAgICAgaWYoc3BlY2lmaWVkPT1udWxsKQotICAgICAgICB7Ci0gICAgICAgICAgICBzcGVjaWZpZWQgPSBuZXcgYm9vbGVhbltsZW5ndGhdOwotICAgICAgICAgICAgZGVjbGFyZWQgPSBuZXcgYm9vbGVhbltsZW5ndGhdOwotICAgICAgICB9IGVsc2UgaWYgKGxlbmd0aCA+IHNwZWNpZmllZC5sZW5ndGgpIHsKLSAgICAgICAgICAgIGJvb2xlYW4gICAgIG5ld0ZsYWdzIFtdOwotCi0gICAgICAgICAgICBuZXdGbGFncyA9IG5ldyBib29sZWFuIFtsZW5ndGhdOwotICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weSAoZGVjbGFyZWQsIDAsIG5ld0ZsYWdzLCAwLCBkZWNsYXJlZC5sZW5ndGgpOwotICAgICAgICAgICAgZGVjbGFyZWQgPSBuZXdGbGFnczsKLQotICAgICAgICAgICAgbmV3RmxhZ3MgPSBuZXcgYm9vbGVhbiBbbGVuZ3RoXTsKLSAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkgKHNwZWNpZmllZCwgMCwgbmV3RmxhZ3MsIDAsIHNwZWNpZmllZC5sZW5ndGgpOwotICAgICAgICAgICAgc3BlY2lmaWVkID0gbmV3RmxhZ3M7Ci0gICAgICAgIH0KLQotICAgICAgICBzcGVjaWZpZWQgW2xlbmd0aCAtIDFdID0gdHJ1ZTsKLSAgICAgICAgZGVjbGFyZWQgW2xlbmd0aCAtIDFdID0gISJDREFUQSIuZXF1YWxzICh0eXBlKTsKLSAgICB9Ci0KLQotICAgIC8vIGphdmFkb2MgZW50aXJlbHkgZnJvbSBzdXBlcmNsYXNzCi0gICAgcHVibGljIHZvaWQgcmVtb3ZlQXR0cmlidXRlIChpbnQgaW5kZXgpCi0gICAgewotICAgICAgICBpbnQgb3JpZ01heCA9IGdldExlbmd0aCAoKSAtIDE7Ci0KLSAgICAgICAgc3VwZXIucmVtb3ZlQXR0cmlidXRlIChpbmRleCk7Ci0gICAgICAgIGlmIChpbmRleCAhPSBvcmlnTWF4KSB7Ci0gICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5IChkZWNsYXJlZCwgaW5kZXggKyAxLCBkZWNsYXJlZCwgaW5kZXgsCi0gICAgICAgICAgICAgICAgICAgIG9yaWdNYXggLSBpbmRleCk7Ci0gICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5IChzcGVjaWZpZWQsIGluZGV4ICsgMSwgc3BlY2lmaWVkLCBpbmRleCwKLSAgICAgICAgICAgICAgICAgICAgb3JpZ01heCAtIGluZGV4KTsKLSAgICAgICAgfQotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogQXNzaWduIGEgdmFsdWUgdG8gdGhlICJkZWNsYXJlZCIgZmxhZyBvZiBhIHNwZWNpZmljIGF0dHJpYnV0ZS4KLSAgICAgKiBUaGlzIGlzIG5vcm1hbGx5IG5lZWRlZCBvbmx5IGZvciBhdHRyaWJ1dGVzIG9mIHR5cGUgQ0RBVEEsCi0gICAgICogaW5jbHVkaW5nIGF0dHJpYnV0ZXMgd2hvc2UgdHlwZSBpcyBjaGFuZ2VkIHRvIG9yIGZyb20gQ0RBVEEuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBhdHRyaWJ1dGUgKHplcm8tYmFzZWQpLgotICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZGVzaXJlZCBmbGFnIHZhbHVlLgotICAgICAqIEBleGNlcHRpb24gamF2YS5sYW5nLkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBXaGVuIHRoZQotICAgICAqICAgICAgICAgICAgc3VwcGxpZWQgaW5kZXggZG9lcyBub3QgaWRlbnRpZnkgYW4gYXR0cmlidXRlLgotICAgICAqIEBzZWUgI3NldFR5cGUKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXREZWNsYXJlZCAoaW50IGluZGV4LCBib29sZWFuIHZhbHVlKQotICAgIHsKLSAgICAgICAgaWYgKGluZGV4IDwgMCB8fCBpbmRleCA+PSBnZXRMZW5ndGggKCkpCi0gICAgICAgICAgICB0aHJvdyBuZXcgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uICgKLSAgICAgICAgICAgICAgICAiTm8gYXR0cmlidXRlIGF0IGluZGV4OiAiICsgaW5kZXgpOwotICAgICAgICBkZWNsYXJlZCBbaW5kZXhdID0gdmFsdWU7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBBc3NpZ24gYSB2YWx1ZSB0byB0aGUgInNwZWNpZmllZCIgZmxhZyBvZiBhIHNwZWNpZmljIGF0dHJpYnV0ZS4KLSAgICAgKiBUaGlzIGlzIHRoZSBvbmx5IHdheSB0aGlzIGZsYWcgY2FuIGJlIGNsZWFyZWQsIGV4Y2VwdCBjbGVhcmluZwotICAgICAqIGJ5IGluaXRpYWxpemF0aW9uIHdpdGggdGhlIGNvcHkgY29uc3RydWN0b3IuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBhdHRyaWJ1dGUgKHplcm8tYmFzZWQpLgotICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZGVzaXJlZCBmbGFnIHZhbHVlLgotICAgICAqIEBleGNlcHRpb24gamF2YS5sYW5nLkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBXaGVuIHRoZQotICAgICAqICAgICAgICAgICAgc3VwcGxpZWQgaW5kZXggZG9lcyBub3QgaWRlbnRpZnkgYW4gYXR0cmlidXRlLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFNwZWNpZmllZCAoaW50IGluZGV4LCBib29sZWFuIHZhbHVlKQotICAgIHsKLSAgICAgICAgaWYgKGluZGV4IDwgMCB8fCBpbmRleCA+PSBnZXRMZW5ndGggKCkpCi0gICAgICAgICAgICB0aHJvdyBuZXcgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uICgKLSAgICAgICAgICAgICAgICAiTm8gYXR0cmlidXRlIGF0IGluZGV4OiAiICsgaW5kZXgpOwotICAgICAgICBzcGVjaWZpZWQgW2luZGV4XSA9IHZhbHVlOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcveG1sL3NheC9leHQvRGVjbEhhbmRsZXIuamF2YSBiL3NyYy9vcmcveG1sL3NheC9leHQvRGVjbEhhbmRsZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYjJjNzJjNS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3htbC9zYXgvZXh0L0RlY2xIYW5kbGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNzAgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwMCwgMjAwNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLy8gRGVjbEhhbmRsZXIuamF2YSAtIE9wdGlvbmFsIGhhbmRsZXIgZm9yIERURCBkZWNsYXJhdGlvbiBldmVudHMuCi0vLyBodHRwOi8vd3d3LnNheHByb2plY3Qub3JnCi0vLyBQdWJsaWMgRG9tYWluOiBubyB3YXJyYW50eS4KLS8vICRJZDogRGVjbEhhbmRsZXIuamF2YSx2IDEuMiAyMDA0LzExLzAzIDIyOjQ5OjA4IGpzdXR0b3IgRXhwICQKLQotcGFja2FnZSBvcmcueG1sLnNheC5leHQ7Ci0KLWltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci0KLQotLyoqCi0gKiBTQVgyIGV4dGVuc2lvbiBoYW5kbGVyIGZvciBEVEQgZGVjbGFyYXRpb24gZXZlbnRzLgotICoKLSAqIDxibG9ja3F1b3RlPgotICogPGVtPlRoaXMgbW9kdWxlLCBib3RoIHNvdXJjZSBjb2RlIGFuZCBkb2N1bWVudGF0aW9uLCBpcyBpbiB0aGUKLSAqIFB1YmxpYyBEb21haW4sIGFuZCBjb21lcyB3aXRoIDxzdHJvbmc+Tk8gV0FSUkFOVFk8L3N0cm9uZz4uPC9lbT4KLSAqIFNlZSA8YSBocmVmPSdodHRwOi8vd3d3LnNheHByb2plY3Qub3JnJz5odHRwOi8vd3d3LnNheHByb2plY3Qub3JnPC9hPgotICogZm9yIGZ1cnRoZXIgaW5mb3JtYXRpb24uCi0gKiA8L2Jsb2NrcXVvdGU+Ci0gKgotICogPHA+VGhpcyBpcyBhbiBvcHRpb25hbCBleHRlbnNpb24gaGFuZGxlciBmb3IgU0FYMiB0byBwcm92aWRlIG1vcmUKLSAqIGNvbXBsZXRlIGluZm9ybWF0aW9uIGFib3V0IERURCBkZWNsYXJhdGlvbnMgaW4gYW4gWE1MIGRvY3VtZW50LgotICogWE1MIHJlYWRlcnMgYXJlIG5vdCByZXF1aXJlZCB0byByZWNvZ25pemUgdGhpcyBoYW5kbGVyLCBhbmQgaXQKLSAqIGlzIG5vdCBwYXJ0IG9mIGNvcmUtb25seSBTQVgyIGRpc3RyaWJ1dGlvbnMuPC9wPgotICoKLSAqIDxwPk5vdGUgdGhhdCBkYXRhLXJlbGF0ZWQgRFREIGRlY2xhcmF0aW9ucyAodW5wYXJzZWQgZW50aXRpZXMgYW5kCi0gKiBub3RhdGlvbnMpIGFyZSBhbHJlYWR5IHJlcG9ydGVkIHRocm91Z2ggdGhlIHtAbGluawotICogb3JnLnhtbC5zYXguRFRESGFuZGxlciBEVERIYW5kbGVyfSBpbnRlcmZhY2UuPC9wPgotICoKLSAqIDxwPklmIHlvdSBhcmUgdXNpbmcgdGhlIGRlY2xhcmF0aW9uIGhhbmRsZXIgdG9nZXRoZXIgd2l0aCBhIGxleGljYWwKLSAqIGhhbmRsZXIsIGFsbCBvZiB0aGUgZXZlbnRzIHdpbGwgb2NjdXIgYmV0d2VlbiB0aGUKLSAqIHtAbGluayBvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXIjc3RhcnREVEQgc3RhcnREVER9IGFuZCB0aGUKLSAqIHtAbGluayBvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXIjZW5kRFREIGVuZERURH0gZXZlbnRzLjwvcD4KLSAqCi0gKiA8cD5UbyBzZXQgdGhlIERlY2xIYW5kbGVyIGZvciBhbiBYTUwgcmVhZGVyLCB1c2UgdGhlCi0gKiB7QGxpbmsgb3JnLnhtbC5zYXguWE1MUmVhZGVyI3NldFByb3BlcnR5IHNldFByb3BlcnR5fSBtZXRob2QKLSAqIHdpdGggdGhlIHByb3BlcnR5IG5hbWUKLSAqIDxjb2RlPmh0dHA6Ly94bWwub3JnL3NheC9wcm9wZXJ0aWVzL2RlY2xhcmF0aW9uLWhhbmRsZXI8L2NvZGU+Ci0gKiBhbmQgYW4gb2JqZWN0IGltcGxlbWVudGluZyB0aGlzIGludGVyZmFjZSAob3IgbnVsbCkgYXMgdGhlIHZhbHVlLgotICogSWYgdGhlIHJlYWRlciBkb2VzIG5vdCByZXBvcnQgZGVjbGFyYXRpb24gZXZlbnRzLCBpdCB3aWxsIHRocm93IGEKLSAqIHtAbGluayBvcmcueG1sLnNheC5TQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb259Ci0gKiB3aGVuIHlvdSBhdHRlbXB0IHRvIHJlZ2lzdGVyIHRoZSBoYW5kbGVyLjwvcD4KLSAqCi0gKiBAc2luY2UgU0FYIDIuMCAoZXh0ZW5zaW9ucyAxLjApCi0gKiBAYXV0aG9yIERhdmlkIE1lZ2dpbnNvbgotICovCi1wdWJsaWMgaW50ZXJmYWNlIERlY2xIYW5kbGVyCi17Ci0KLSAgICAvKioKLSAgICAgKiBSZXBvcnQgYW4gZWxlbWVudCB0eXBlIGRlY2xhcmF0aW9uLgotICAgICAqCi0gICAgICogPHA+VGhlIGNvbnRlbnQgbW9kZWwgd2lsbCBjb25zaXN0IG9mIHRoZSBzdHJpbmcgIkVNUFRZIiwgdGhlCi0gICAgICogc3RyaW5nICJBTlkiLCBvciBhIHBhcmVudGhlc2lzZWQgZ3JvdXAsIG9wdGlvbmFsbHkgZm9sbG93ZWQKLSAgICAgKiBieSBhbiBvY2N1cnJlbmNlIGluZGljYXRvci4gIFRoZSBtb2RlbCB3aWxsIGJlIG5vcm1hbGl6ZWQgc28KLSAgICAgKiB0aGF0IGFsbCBwYXJhbWV0ZXIgZW50aXRpZXMgYXJlIGZ1bGx5IHJlc29sdmVkIGFuZCBhbGwgd2hpdGVzcGFjZQotICAgICAqIGlzIHJlbW92ZWQsYW5kIHdpbGwgaW5jbHVkZSB0aGUgZW5jbG9zaW5nIHBhcmVudGhlc2VzLiAgT3RoZXIKLSAgICAgKiBub3JtYWxpemF0aW9uIChzdWNoIGFzIHJlbW92aW5nIHJlZHVuZGFudCBwYXJlbnRoZXNlcyBvcgotICAgICAqIHNpbXBsaWZ5aW5nIG9jY3VycmVuY2UgaW5kaWNhdG9ycykgaXMgYXQgdGhlIGRpc2NyZXRpb24gb2YgdGhlCi0gICAgICogcGFyc2VyLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBlbGVtZW50IHR5cGUgbmFtZS4KLSAgICAgKiBAcGFyYW0gbW9kZWwgVGhlIGNvbnRlbnQgbW9kZWwgYXMgYSBub3JtYWxpemVkIHN0cmluZy4KLSAgICAgKiBAZXhjZXB0aW9uIFNBWEV4Y2VwdGlvbiBUaGUgYXBwbGljYXRpb24gbWF5IHJhaXNlIGFuIGV4Y2VwdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBlbGVtZW50RGVjbCAoU3RyaW5nIG5hbWUsIFN0cmluZyBtb2RlbCkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbjsKLQotCi0gICAgLyoqCi0gICAgICogUmVwb3J0IGFuIGF0dHJpYnV0ZSB0eXBlIGRlY2xhcmF0aW9uLgotICAgICAqCi0gICAgICogPHA+T25seSB0aGUgZWZmZWN0aXZlIChmaXJzdCkgZGVjbGFyYXRpb24gZm9yIGFuIGF0dHJpYnV0ZSB3aWxsCi0gICAgICogYmUgcmVwb3J0ZWQuICBUaGUgdHlwZSB3aWxsIGJlIG9uZSBvZiB0aGUgc3RyaW5ncyAiQ0RBVEEiLAotICAgICAqICJJRCIsICJJRFJFRiIsICJJRFJFRlMiLCAiTk1UT0tFTiIsICJOTVRPS0VOUyIsICJFTlRJVFkiLAotICAgICAqICJFTlRJVElFUyIsIGEgcGFyZW50aGVzaXplZCB0b2tlbiBncm91cCB3aXRoCi0gICAgICogdGhlIHNlcGFyYXRvciAifCIgYW5kIGFsbCB3aGl0ZXNwYWNlIHJlbW92ZWQsIG9yIHRoZSB3b3JkCi0gICAgICogIk5PVEFUSU9OIiBmb2xsb3dlZCBieSBhIHNwYWNlIGZvbGxvd2VkIGJ5IGEgcGFyZW50aGVzaXplZAotICAgICAqIHRva2VuIGdyb3VwIHdpdGggYWxsIHdoaXRlc3BhY2UgcmVtb3ZlZC48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5UaGUgdmFsdWUgd2lsbCBiZSB0aGUgdmFsdWUgYXMgcmVwb3J0ZWQgdG8gYXBwbGljYXRpb25zLAotICAgICAqIGFwcHJvcHJpYXRlbHkgbm9ybWFsaXplZCBhbmQgd2l0aCBlbnRpdHkgYW5kIGNoYXJhY3RlcgotICAgICAqIHJlZmVyZW5jZXMgZXhwYW5kZWQuICA8L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gZU5hbWUgVGhlIG5hbWUgb2YgdGhlIGFzc29jaWF0ZWQgZWxlbWVudC4KLSAgICAgKiBAcGFyYW0gYU5hbWUgVGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICAgKiBAcGFyYW0gdHlwZSBBIHN0cmluZyByZXByZXNlbnRpbmcgdGhlIGF0dHJpYnV0ZSB0eXBlLgotICAgICAqIEBwYXJhbSBtb2RlIEEgc3RyaW5nIHJlcHJlc2VudGluZyB0aGUgYXR0cmlidXRlIGRlZmF1bHRpbmcgbW9kZQotICAgICAqICAgICAgICAoIiNJTVBMSUVEIiwgIiNSRVFVSVJFRCIsIG9yICIjRklYRUQiKSBvciBudWxsIGlmCi0gICAgICogICAgICAgIG5vbmUgb2YgdGhlc2UgYXBwbGllcy4KLSAgICAgKiBAcGFyYW0gdmFsdWUgQSBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBhdHRyaWJ1dGUncyBkZWZhdWx0IHZhbHVlLAotICAgICAqICAgICAgICBvciBudWxsIGlmIHRoZXJlIGlzIG5vbmUuCi0gICAgICogQGV4Y2VwdGlvbiBTQVhFeGNlcHRpb24gVGhlIGFwcGxpY2F0aW9uIG1heSByYWlzZSBhbiBleGNlcHRpb24uCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IHZvaWQgYXR0cmlidXRlRGVjbCAoU3RyaW5nIGVOYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBhTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdHlwZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbW9kZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdmFsdWUpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb247Ci0KLQotICAgIC8qKgotICAgICAqIFJlcG9ydCBhbiBpbnRlcm5hbCBlbnRpdHkgZGVjbGFyYXRpb24uCi0gICAgICoKLSAgICAgKiA8cD5Pbmx5IHRoZSBlZmZlY3RpdmUgKGZpcnN0KSBkZWNsYXJhdGlvbiBmb3IgZWFjaCBlbnRpdHkKLSAgICAgKiB3aWxsIGJlIHJlcG9ydGVkLiAgQWxsIHBhcmFtZXRlciBlbnRpdGllcyBpbiB0aGUgdmFsdWUKLSAgICAgKiB3aWxsIGJlIGV4cGFuZGVkLCBidXQgZ2VuZXJhbCBlbnRpdGllcyB3aWxsIG5vdC48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgZW50aXR5LiAgSWYgaXQgaXMgYSBwYXJhbWV0ZXIKLSAgICAgKiAgICAgICAgZW50aXR5LCB0aGUgbmFtZSB3aWxsIGJlZ2luIHdpdGggJyUnLgotICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwbGFjZW1lbnQgdGV4dCBvZiB0aGUgZW50aXR5LgotICAgICAqIEBleGNlcHRpb24gU0FYRXhjZXB0aW9uIFRoZSBhcHBsaWNhdGlvbiBtYXkgcmFpc2UgYW4gZXhjZXB0aW9uLgotICAgICAqIEBzZWUgI2V4dGVybmFsRW50aXR5RGVjbAotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguRFRESGFuZGxlciN1bnBhcnNlZEVudGl0eURlY2wKLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBpbnRlcm5hbEVudGl0eURlY2wgKFN0cmluZyBuYW1lLCBTdHJpbmcgdmFsdWUpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb247Ci0KLQotICAgIC8qKgotICAgICAqIFJlcG9ydCBhIHBhcnNlZCBleHRlcm5hbCBlbnRpdHkgZGVjbGFyYXRpb24uCi0gICAgICoKLSAgICAgKiA8cD5Pbmx5IHRoZSBlZmZlY3RpdmUgKGZpcnN0KSBkZWNsYXJhdGlvbiBmb3IgZWFjaCBlbnRpdHkKLSAgICAgKiB3aWxsIGJlIHJlcG9ydGVkLjwvcD4KLSAgICAgKgotICAgICAqIDxwPklmIHRoZSBzeXN0ZW0gaWRlbnRpZmllciBpcyBhIFVSTCwgdGhlIHBhcnNlciBtdXN0IHJlc29sdmUgaXQKLSAgICAgKiBmdWxseSBiZWZvcmUgcGFzc2luZyBpdCB0byB0aGUgYXBwbGljYXRpb24uPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGVudGl0eS4gIElmIGl0IGlzIGEgcGFyYW1ldGVyCi0gICAgICogICAgICAgIGVudGl0eSwgdGhlIG5hbWUgd2lsbCBiZWdpbiB3aXRoICclJy4KLSAgICAgKiBAcGFyYW0gcHVibGljSWQgVGhlIGVudGl0eSdzIHB1YmxpYyBpZGVudGlmaWVyLCBvciBudWxsIGlmIG5vbmUKLSAgICAgKiAgICAgICAgd2FzIGdpdmVuLgotICAgICAqIEBwYXJhbSBzeXN0ZW1JZCBUaGUgZW50aXR5J3Mgc3lzdGVtIGlkZW50aWZpZXIuCi0gICAgICogQGV4Y2VwdGlvbiBTQVhFeGNlcHRpb24gVGhlIGFwcGxpY2F0aW9uIG1heSByYWlzZSBhbiBleGNlcHRpb24uCi0gICAgICogQHNlZSAjaW50ZXJuYWxFbnRpdHlEZWNsCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5EVERIYW5kbGVyI3VucGFyc2VkRW50aXR5RGVjbAotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIGV4dGVybmFsRW50aXR5RGVjbCAoU3RyaW5nIG5hbWUsIFN0cmluZyBwdWJsaWNJZCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBzeXN0ZW1JZCkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbjsKLQotfQotCi0vLyBlbmQgb2YgRGVjbEhhbmRsZXIuamF2YQpkaWZmIC0tZ2l0IGEvc3JjL29yZy94bWwvc2F4L2V4dC9EZWZhdWx0SGFuZGxlcjIuamF2YSBiL3NyYy9vcmcveG1sL3NheC9leHQvRGVmYXVsdEhhbmRsZXIyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGNiN2E5MWEuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy94bWwvc2F4L2V4dC9EZWZhdWx0SGFuZGxlcjIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE1NCArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDA0LCAyMDA1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vLyBEZWZhdWx0SGFuZGxlcjIuamF2YSAtIGV4dGVuZGVkIERlZmF1bHRIYW5kbGVyCi0vLyBodHRwOi8vd3d3LnNheHByb2plY3Qub3JnCi0vLyBQdWJsaWMgRG9tYWluOiBubyB3YXJyYW50eS4KLS8vICRJZDogRGVmYXVsdEhhbmRsZXIyLmphdmEsdiAxLjIgMjAwNC8xMS8wMyAyMjo0OTowOCBqc3V0dG9yIEV4cCAkCi0KLXBhY2thZ2Ugb3JnLnhtbC5zYXguZXh0OwotCi1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguaGVscGVycy5EZWZhdWx0SGFuZGxlcjsKLQotCi0vKioKLSAqIFRoaXMgY2xhc3MgZXh0ZW5kcyB0aGUgU0FYMiBiYXNlIGhhbmRsZXIgY2xhc3MgdG8gc3VwcG9ydCB0aGUKLSAqIFNBWDIge0BsaW5rIExleGljYWxIYW5kbGVyfSwge0BsaW5rIERlY2xIYW5kbGVyfSwgYW5kCi0gKiB7QGxpbmsgRW50aXR5UmVzb2x2ZXIyfSBleHRlbnNpb25zLiAgRXhjZXB0IGZvciBvdmVycmlkaW5nIHRoZQotICogb3JpZ2luYWwgU0FYMSB7QGxpbmsgRGVmYXVsdEhhbmRsZXIjcmVzb2x2ZUVudGl0eSByZXNvbHZlRW50aXR5KCl9Ci0gKiBtZXRob2QgdGhlIGFkZGVkIGhhbmRsZXIgbWV0aG9kcyBqdXN0IHJldHVybi4gIFN1YmNsYXNzZXJzIG1heQotICogb3ZlcnJpZGUgZXZlcnl0aGluZyBvbiBhIG1ldGhvZC1ieS1tZXRob2QgYmFzaXMuCi0gKgotICogPGJsb2NrcXVvdGU+Ci0gKiA8ZW0+VGhpcyBtb2R1bGUsIGJvdGggc291cmNlIGNvZGUgYW5kIGRvY3VtZW50YXRpb24sIGlzIGluIHRoZQotICogUHVibGljIERvbWFpbiwgYW5kIGNvbWVzIHdpdGggPHN0cm9uZz5OTyBXQVJSQU5UWTwvc3Ryb25nPi48L2VtPgotICogPC9ibG9ja3F1b3RlPgotICoKLSAqIDxwPiA8ZW0+Tm90ZTo8L2VtPiB0aGlzIGNsYXNzIG1pZ2h0IHlldCBsZWFybiB0aGF0IHRoZQotICogPGVtPkNvbnRlbnRIYW5kbGVyLnNldERvY3VtZW50TG9jYXRvcigpPC9lbT4gY2FsbCBtaWdodCBiZSBwYXNzZWQgYQotICoge0BsaW5rIExvY2F0b3IyfSBvYmplY3QsIGFuZCB0aGF0IHRoZQotICogPGVtPkNvbnRlbnRIYW5kbGVyLnN0YXJ0RWxlbWVudCgpPC9lbT4gY2FsbCBtaWdodCBiZSBwYXNzZWQgYQotICoge0BsaW5rIEF0dHJpYnV0ZXMyfSBvYmplY3QuCi0gKgotICogQHNpbmNlIFNBWCAyLjAgKGV4dGVuc2lvbnMgMS4xIGFscGhhKQotICogQGF1dGhvciBEYXZpZCBCcm93bmVsbAotICovCi1wdWJsaWMgY2xhc3MgRGVmYXVsdEhhbmRsZXIyIGV4dGVuZHMgRGVmYXVsdEhhbmRsZXIKLSAgICBpbXBsZW1lbnRzIExleGljYWxIYW5kbGVyLCBEZWNsSGFuZGxlciwgRW50aXR5UmVzb2x2ZXIyCi17Ci0gICAgLyoqIENvbnN0cnVjdHMgYSBoYW5kbGVyIHdoaWNoIGlnbm9yZXMgYWxsIHBhcnNpbmcgZXZlbnRzLiAqLwotICAgIHB1YmxpYyBEZWZhdWx0SGFuZGxlcjIgKCkgeyB9Ci0KLQotICAgIC8vIFNBWDIgZXh0LTEuMCBMZXhpY2FsSGFuZGxlcgotCi0gICAgcHVibGljIHZvaWQgc3RhcnRDREFUQSAoKQotICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICAgICAge30KLQotICAgIHB1YmxpYyB2b2lkIGVuZENEQVRBICgpCi0gICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgICAgICB7fQotCi0gICAgcHVibGljIHZvaWQgc3RhcnREVEQgKFN0cmluZyBuYW1lLCBTdHJpbmcgcHVibGljSWQsIFN0cmluZyBzeXN0ZW1JZCkKLSAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgICAgIHt9Ci0KLSAgICBwdWJsaWMgdm9pZCBlbmREVEQgKCkKLSAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgICAgIHt9Ci0KLSAgICBwdWJsaWMgdm9pZCBzdGFydEVudGl0eSAoU3RyaW5nIG5hbWUpCi0gICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgICAgICB7fQotCi0gICAgcHVibGljIHZvaWQgZW5kRW50aXR5IChTdHJpbmcgbmFtZSkKLSAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgICAgIHt9Ci0KLSAgICBwdWJsaWMgdm9pZCBjb21tZW50IChjaGFyIGNoIFtdLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpCi0gICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgICAgICB7IH0KLQotCi0gICAgLy8gU0FYMiBleHQtMS4wIERlY2xIYW5kbGVyCi0KLSAgICBwdWJsaWMgdm9pZCBhdHRyaWJ1dGVEZWNsIChTdHJpbmcgZU5hbWUsIFN0cmluZyBhTmFtZSwKLSAgICAgICAgICAgIFN0cmluZyB0eXBlLCBTdHJpbmcgbW9kZSwgU3RyaW5nIHZhbHVlKQotICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICAgICAge30KLQotICAgIHB1YmxpYyB2b2lkIGVsZW1lbnREZWNsIChTdHJpbmcgbmFtZSwgU3RyaW5nIG1vZGVsKQotICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICAgICAge30KLQotICAgIHB1YmxpYyB2b2lkIGV4dGVybmFsRW50aXR5RGVjbCAoU3RyaW5nIG5hbWUsCi0gICAgICAgIFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkKQotICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICAgICAge30KLQotICAgIHB1YmxpYyB2b2lkIGludGVybmFsRW50aXR5RGVjbCAoU3RyaW5nIG5hbWUsIFN0cmluZyB2YWx1ZSkKLSAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgICAgIHt9Ci0KLSAgICAvLyBTQVgyIGV4dC0xLjEgRW50aXR5UmVzb2x2ZXIyCi0KLSAgICAvKioKLSAgICAgKiBUZWxscyB0aGUgcGFyc2VyIHRoYXQgaWYgbm8gZXh0ZXJuYWwgc3Vic2V0IGhhcyBiZWVuIGRlY2xhcmVkCi0gICAgICogaW4gdGhlIGRvY3VtZW50IHRleHQsIG5vbmUgc2hvdWxkIGJlIHVzZWQuCi0gICAgICovCi0gICAgcHVibGljIElucHV0U291cmNlIGdldEV4dGVybmFsU3Vic2V0IChTdHJpbmcgbmFtZSwgU3RyaW5nIGJhc2VVUkkpCi0gICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24KLSAgICAgICAgeyByZXR1cm4gbnVsbDsgfQotCi0gICAgLyoqCi0gICAgICogVGVsbHMgdGhlIHBhcnNlciB0byByZXNvbHZlIHRoZSBzeXN0ZW1JZCBhZ2FpbnN0IHRoZSBiYXNlVVJJCi0gICAgICogYW5kIHJlYWQgdGhlIGVudGl0eSB0ZXh0IGZyb20gdGhhdCByZXN1bHRpbmcgYWJzb2x1dGUgVVJJLgotICAgICAqIE5vdGUgdGhhdCBiZWNhdXNlIHRoZSBvbGRlcgotICAgICAqIHtAbGluayBEZWZhdWx0SGFuZGxlciNyZXNvbHZlRW50aXR5IERlZmF1bHRIYW5kbGVyLnJlc29sdmVFbnRpdHkoKX0sCi0gICAgICogbWV0aG9kIGlzIG92ZXJyaWRkZW4gdG8gY2FsbCB0aGlzIG9uZSwgdGhpcyBtZXRob2QgbWF5IHNvbWV0aW1lcwotICAgICAqIGJlIGludm9rZWQgd2l0aCBudWxsIDxlbT5uYW1lPC9lbT4gYW5kIDxlbT5iYXNlVVJJPC9lbT4sIGFuZAotICAgICAqIHdpdGggdGhlIDxlbT5zeXN0ZW1JZDwvZW0+IGFscmVhZHkgYWJzb2x1dGl6ZWQuCi0gICAgICovCi0gICAgcHVibGljIElucHV0U291cmNlIHJlc29sdmVFbnRpdHkgKFN0cmluZyBuYW1lLCBTdHJpbmcgcHVibGljSWQsCi0gICAgICAgICAgICBTdHJpbmcgYmFzZVVSSSwgU3RyaW5nIHN5c3RlbUlkKQotICAgIHRocm93cyBTQVhFeGNlcHRpb24sIElPRXhjZXB0aW9uCi0gICAgICAgIHsgcmV0dXJuIG51bGw7IH0KLQotICAgIC8vIFNBWDEgRW50aXR5UmVzb2x2ZXIKLQotICAgIC8qKgotICAgICAqIEludm9rZXMKLSAgICAgKiB7QGxpbmsgRW50aXR5UmVzb2x2ZXIyI3Jlc29sdmVFbnRpdHkgRW50aXR5UmVzb2x2ZXIyLnJlc29sdmVFbnRpdHkoKX0KLSAgICAgKiB3aXRoIG51bGwgZW50aXR5IG5hbWUgYW5kIGJhc2UgVVJJLgotICAgICAqIFlvdSBvbmx5IG5lZWQgdG8gb3ZlcnJpZGUgdGhhdCBtZXRob2QgdG8gdXNlIHRoaXMgY2xhc3MuCi0gICAgICovCi0gICAgcHVibGljIElucHV0U291cmNlIHJlc29sdmVFbnRpdHkgKFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkKQotICAgIHRocm93cyBTQVhFeGNlcHRpb24sIElPRXhjZXB0aW9uCi0gICAgICAgIHsgcmV0dXJuIHJlc29sdmVFbnRpdHkgKG51bGwsIHB1YmxpY0lkLCBudWxsLCBzeXN0ZW1JZCk7IH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcveG1sL3NheC9leHQvRW50aXR5UmVzb2x2ZXIyLmphdmEgYi9zcmMvb3JnL3htbC9zYXgvZXh0L0VudGl0eVJlc29sdmVyMi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkYmQxMjQyLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcveG1sL3NheC9leHQvRW50aXR5UmVzb2x2ZXIyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMjEgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwNCwgMjAwNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLy8gRW50aXR5UmVzb2x2ZXIyLmphdmEgLSBFeHRlbmRlZCBTQVggZW50aXR5IHJlc29sdmVyLgotLy8gaHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZwotLy8gTm8gd2FycmFudHk7IG5vIGNvcHlyaWdodCAtLSB1c2UgdGhpcyBhcyB5b3Ugd2lsbC4KLS8vICRJZDogRW50aXR5UmVzb2x2ZXIyLmphdmEsdiAxLjIgMjAwNC8xMS8wMyAyMjo0OTowOCBqc3V0dG9yIEV4cCAkCi0KLXBhY2thZ2Ugb3JnLnhtbC5zYXguZXh0OwotCi1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLQotaW1wb3J0IG9yZy54bWwuc2F4LkVudGl0eVJlc29sdmVyOwotaW1wb3J0IG9yZy54bWwuc2F4LklucHV0U291cmNlOwotaW1wb3J0IG9yZy54bWwuc2F4LlhNTFJlYWRlcjsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci0KLQotLyoqCi0gKiBFeHRlbmRlZCBpbnRlcmZhY2UgZm9yIG1hcHBpbmcgZXh0ZXJuYWwgZW50aXR5IHJlZmVyZW5jZXMgdG8gaW5wdXQKLSAqIHNvdXJjZXMsIG9yIHByb3ZpZGluZyBhIG1pc3NpbmcgZXh0ZXJuYWwgc3Vic2V0LiAgVGhlCi0gKiB7QGxpbmsgWE1MUmVhZGVyI3NldEVudGl0eVJlc29sdmVyIFhNTFJlYWRlci5zZXRFbnRpdHlSZXNvbHZlcigpfSBtZXRob2QKLSAqIGlzIHVzZWQgdG8gcHJvdmlkZSBpbXBsZW1lbnRhdGlvbnMgb2YgdGhpcyBpbnRlcmZhY2UgdG8gcGFyc2Vycy4KLSAqIFdoZW4gYSBwYXJzZXIgdXNlcyB0aGUgbWV0aG9kcyBpbiB0aGlzIGludGVyZmFjZSwgdGhlCi0gKiB7QGxpbmsgRW50aXR5UmVzb2x2ZXIyI3Jlc29sdmVFbnRpdHkgRW50aXR5UmVzb2x2ZXIyLnJlc29sdmVFbnRpdHkoKX0KLSAqIG1ldGhvZCAoaW4gdGhpcyBpbnRlcmZhY2UpIGlzIHVzZWQgPGVtPmluc3RlYWQgb2Y8L2VtPiB0aGUgb2xkZXIgKFNBWCAxLjApCi0gKiB7QGxpbmsgRW50aXR5UmVzb2x2ZXIjcmVzb2x2ZUVudGl0eSBFbnRpdHlSZXNvbHZlci5yZXNvbHZlRW50aXR5KCl9IG1ldGhvZC4KLSAqCi0gKiA8YmxvY2txdW90ZT4KLSAqIDxlbT5UaGlzIG1vZHVsZSwgYm90aCBzb3VyY2UgY29kZSBhbmQgZG9jdW1lbnRhdGlvbiwgaXMgaW4gdGhlCi0gKiBQdWJsaWMgRG9tYWluLCBhbmQgY29tZXMgd2l0aCA8c3Ryb25nPk5PIFdBUlJBTlRZPC9zdHJvbmc+LjwvZW0+Ci0gKiA8L2Jsb2NrcXVvdGU+Ci0gKgotICogPHA+SWYgYSBTQVggYXBwbGljYXRpb24gcmVxdWlyZXMgdGhlIGN1c3RvbWl6ZWQgaGFuZGxpbmcgd2hpY2ggdGhpcwotICogaW50ZXJmYWNlIGRlZmluZXMgZm9yIGV4dGVybmFsIGVudGl0aWVzLCBpdCBtdXN0IGVuc3VyZSB0aGF0IGl0IHVzZXMKLSAqIGFuIFhNTFJlYWRlciB3aXRoIHRoZQotICogPGVtPmh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy91c2UtZW50aXR5LXJlc29sdmVyMjwvZW0+IGZlYXR1cmUgZmxhZwotICogc2V0IHRvIDxlbT50cnVlPC9lbT4gKHdoaWNoIGlzIGl0cyBkZWZhdWx0IHZhbHVlIHdoZW4gdGhlIGZlYXR1cmUgaXMKLSAqIHJlY29nbml6ZWQpLiAgSWYgdGhhdCBmbGFnIGlzIHVucmVjb2duaXplZCwgb3IgaXRzIHZhbHVlIGlzIGZhbHNlLAotICogb3IgdGhlIHJlc29sdmVyIGRvZXMgbm90IGltcGxlbWVudCB0aGlzIGludGVyZmFjZSwgdGhlbiBvbmx5IHRoZQotICoge0BsaW5rIEVudGl0eVJlc29sdmVyfSBtZXRob2Qgd2lsbCBiZSB1c2VkLgotICogPC9wPgotICoKLSAqIDxwPlRoYXQgc3VwcG9ydHMgdGhyZWUgY2F0ZWdvcmllcyBvZiBhcHBsaWNhdGlvbiB0aGF0IG1vZGlmeSBlbnRpdHkKLSAqIHJlc29sdXRpb24uICA8ZW0+T2xkIFN0eWxlPC9lbT4gYXBwbGljYXRpb25zIHdvbid0IGtub3cgYWJvdXQgdGhpcyBpbnRlcmZhY2U7Ci0gKiB0aGV5IHdpbGwgcHJvdmlkZSBhbiBFbnRpdHlSZXNvbHZlci4KLSAqIDxlbT5UcmFuc2l0aW9uYWwgTW9kZTwvZW0+IHByb3ZpZGUgYW4gRW50aXR5UmVzb2x2ZXIyIGFuZCBhdXRvbWF0aWNhbGx5Ci0gKiBnZXQgdGhlIGJlbmVmaXQgb2YgaXRzIG1ldGhvZHMgaW4gYW55IHN5c3RlbXMgKHBhcnNlcnMgb3Igb3RoZXIgdG9vbHMpCi0gKiBzdXBwb3J0aW5nIGl0LCBkdWUgdG8gcG9seW1vcnBoaXNtLgotICogQm90aCA8ZW0+T2xkIFN0eWxlPC9lbT4gYW5kIDxlbT5UcmFuc2l0aW9uYWwgTW9kZTwvZW0+IGFwcGxpY2F0aW9ucyB3aWxsCi0gKiB3b3JrIHdpdGggYW55IFNBWDIgcGFyc2VyLgotICogPGVtPk5ldyBzdHlsZTwvZW0+IGFwcGxpY2F0aW9ucyB3aWxsIGZhaWwgdG8gcnVuIGV4Y2VwdCBvbiBTQVgyIHBhcnNlcnMKLSAqIHRoYXQgc3VwcG9ydCB0aGlzIHBhcnRpY3VsYXIgZmVhdHVyZS4KLSAqIFRoZXkgd2lsbCBpbnNpc3QgdGhhdCBmZWF0dXJlIGZsYWcgaGF2ZSBhIHZhbHVlIG9mICJ0cnVlIiwgYW5kIHRoZQotICogRW50aXR5UmVzb2x2ZXIyIGltcGxlbWVudGF0aW9uIHRoZXkgcHJvdmlkZSAgbWlnaHQgdGhyb3cgYW4gZXhjZXB0aW9uCi0gKiBpZiB0aGUgb3JpZ2luYWwgU0FYIDEuMCBzdHlsZSBlbnRpdHkgcmVzb2x1dGlvbiBtZXRob2QgaXMgaW52b2tlZC4KLSAqIDwvcD4KLSAqCi0gKiBAc2VlIG9yZy54bWwuc2F4LlhNTFJlYWRlciNzZXRFbnRpdHlSZXNvbHZlcgotICoKLSAqIEBzaW5jZSBTQVggMi4wIChleHRlbnNpb25zIDEuMSBhbHBoYSkKLSAqIEBhdXRob3IgRGF2aWQgQnJvd25lbGwKLSAqLwotcHVibGljIGludGVyZmFjZSBFbnRpdHlSZXNvbHZlcjIgZXh0ZW5kcyBFbnRpdHlSZXNvbHZlcgotewotICAgIC8qKgotICAgICAqIEFsbG93cyBhcHBsaWNhdGlvbnMgdG8gcHJvdmlkZSBhbiBleHRlcm5hbCBzdWJzZXQgZm9yIGRvY3VtZW50cwotICAgICAqIHRoYXQgZG9uJ3QgZXhwbGljaXRseSBkZWZpbmUgb25lLiAgRG9jdW1lbnRzIHdpdGggRE9DVFlQRSBkZWNsYXJhdGlvbnMKLSAgICAgKiB0aGF0IG9taXQgYW4gZXh0ZXJuYWwgc3Vic2V0IGNhbiB0aHVzIGF1Z21lbnQgdGhlIGRlY2xhcmF0aW9ucwotICAgICAqIGF2YWlsYWJsZSBmb3IgdmFsaWRhdGlvbiwgZW50aXR5IHByb2Nlc3NpbmcsIGFuZCBhdHRyaWJ1dGUgcHJvY2Vzc2luZwotICAgICAqIChub3JtYWxpemF0aW9uLCBkZWZhdWx0aW5nLCBhbmQgcmVwb3J0aW5nIHR5cGVzIGluY2x1ZGluZyBJRCkuCi0gICAgICogVGhpcyBhdWdtZW50YXRpb24gaXMgcmVwb3J0ZWQKLSAgICAgKiB0aHJvdWdoIHRoZSB7QGxpbmsgTGV4aWNhbEhhbmRsZXIjc3RhcnREVEQgc3RhcnREVEQoKX0gbWV0aG9kIGFzIGlmCi0gICAgICogdGhlIGRvY3VtZW50IHRleHQgaGFkIG9yaWdpbmFsbHkgaW5jbHVkZWQgdGhlIGV4dGVybmFsIHN1YnNldDsKLSAgICAgKiB0aGlzIGNhbGxiYWNrIGlzIG1hZGUgYmVmb3JlIGFueSBpbnRlcm5hbCBzdWJzZXQgZGF0YSBvciBlcnJvcnMKLSAgICAgKiBhcmUgcmVwb3J0ZWQuPC9wPgotICAgICAqCi0gICAgICogPHA+VGhpcyBtZXRob2QgY2FuIGFsc28gYmUgdXNlZCB3aXRoIGRvY3VtZW50cyB0aGF0IGhhdmUgbm8gRE9DVFlQRQotICAgICAqIGRlY2xhcmF0aW9uLiAgV2hlbiB0aGUgcm9vdCBlbGVtZW50IGlzIGVuY291bnRlcmVkLAotICAgICAqIGJ1dCBubyBET0NUWVBFIGRlY2xhcmF0aW9uIGhhcyBiZWVuIHNlZW4sIHRoaXMgbWV0aG9kIGlzCi0gICAgICogaW52b2tlZC4gIElmIGl0IHJldHVybnMgYSB2YWx1ZSBmb3IgdGhlIGV4dGVybmFsIHN1YnNldCwgdGhhdCByb290Ci0gICAgICogZWxlbWVudCBpcyBkZWNsYXJlZCB0byBiZSB0aGUgcm9vdCBlbGVtZW50LCBnaXZpbmcgdGhlIGVmZmVjdCBvZgotICAgICAqIHNwbGljaW5nIGEgRE9DVFlQRSBkZWNsYXJhdGlvbiBhdCB0aGUgZW5kIHRoZSBwcm9sb2cgb2YgYSBkb2N1bWVudAotICAgICAqIHRoYXQgY291bGQgbm90IG90aGVyd2lzZSBiZSB2YWxpZC4gIFRoZSBzZXF1ZW5jZSBvZiBwYXJzZXIgY2FsbGJhY2tzCi0gICAgICogaW4gdGhhdCBjYXNlIGxvZ2ljYWxseSByZXNlbWJsZXMgdGhpczo8L3A+Ci0gICAgICoKLSAgICAgKiA8cHJlPgotICAgICAqIC4uLiBjb21tZW50cyBhbmQgUElzIGZyb20gdGhlIHByb2xvZyAoYXMgdXN1YWwpCi0gICAgICogc3RhcnREVEQgKCJyb290TmFtZSIsIHNvdXJjZS5nZXRQdWJsaWNJZCAoKSwgc291cmNlLmdldFN5c3RlbUlkICgpKTsKLSAgICAgKiBzdGFydEVudGl0eSAoIltkdGRdIik7Ci0gICAgICogLi4uIGRlY2xhcmF0aW9ucywgY29tbWVudHMsIGFuZCBQSXMgZnJvbSB0aGUgZXh0ZXJuYWwgc3Vic2V0Ci0gICAgICogZW5kRW50aXR5ICgiW2R0ZF0iKTsKLSAgICAgKiBlbmREVEQgKCk7Ci0gICAgICogLi4uIHRoZW4gdGhlIHJlc3Qgb2YgdGhlIGRvY3VtZW50IChhcyB1c3VhbCkKLSAgICAgKiBzdGFydEVsZW1lbnQgKC4uLiwgInJvb3ROYW1lIiwgLi4uKTsKLSAgICAgKiA8L3ByZT4KLSAgICAgKgotICAgICAqIDxwPk5vdGUgdGhhdCB0aGUgSW5wdXRTb3VyY2UgZ2V0cyBubyBmdXJ0aGVyIHJlc29sdXRpb24uCi0gICAgICogSW1wbGVtZW50YXRpb25zIG9mIHRoaXMgbWV0aG9kIG1heSB3aXNoIHRvIGludm9rZQotICAgICAqIHtAbGluayAjcmVzb2x2ZUVudGl0eSByZXNvbHZlRW50aXR5KCl9IHRvIGdhaW4gYmVuZWZpdHMgc3VjaCBhcyB1c2UKLSAgICAgKiBvZiBsb2NhbCBjYWNoZXMgb2YgRFREIGVudGl0aWVzLiAgQWxzbywgdGhpcyBtZXRob2Qgd2lsbCBuZXZlciBiZQotICAgICAqIHVzZWQgYnkgYSAobm9uLXZhbGlkYXRpbmcpIHByb2Nlc3NvciB0aGF0IGlzIG5vdCBpbmNsdWRpbmcgZXh0ZXJuYWwKLSAgICAgKiBwYXJhbWV0ZXIgZW50aXRpZXMuIDwvcD4KLSAgICAgKgotICAgICAqIDxwPlVzZXMgZm9yIHRoaXMgbWV0aG9kIGluY2x1ZGUgZmFjaWxpdGF0aW5nIGRhdGEgdmFsaWRhdGlvbiB3aGVuCi0gICAgICogaW50ZXJvcGVyYXRpbmcgd2l0aCBYTUwgcHJvY2Vzc29ycyB0aGF0IHdvdWxkIGFsd2F5cyByZXF1aXJlCi0gICAgICogdW5kZXNpcmFibGUgbmV0d29yayBhY2Nlc3NlcyBmb3IgZXh0ZXJuYWwgZW50aXRpZXMsIG9yIHdoaWNoIGZvcgotICAgICAqIG90aGVyIHJlYXNvbnMgYWRvcHQgYSAibm8gRFREcyIgcG9saWN5LgotICAgICAqIE5vbi12YWxpZGF0aW9uIG1vdGl2ZXMgaW5jbHVkZSBmb3JjaW5nIGRvY3VtZW50cyB0byBpbmNsdWRlIERURHMgc28KLSAgICAgKiB0aGF0IGF0dHJpYnV0ZXMgYXJlIGhhbmRsZWQgY29uc2lzdGVudGx5LgotICAgICAqIEZvciBleGFtcGxlLCBhbiBYUGF0aCBwcm9jZXNzb3IgbmVlZHMgdG8ga25vdyB3aGljaCBhdHRpYnV0ZXMgaGF2ZQotICAgICAqIHR5cGUgIklEIiBiZWZvcmUgaXQgY2FuIHByb2Nlc3MgYSB3aWRlbHkgdXNlZCB0eXBlIG9mIHJlZmVyZW5jZS48L3A+Ci0gICAgICoKLSAgICAgKiA8cD48c3Ryb25nPldhcm5pbmc6PC9zdHJvbmc+IFJldHVybmluZyBhbiBleHRlcm5hbCBzdWJzZXQgbW9kaWZpZXMKLSAgICAgKiB0aGUgaW5wdXQgZG9jdW1lbnQuICBCeSBwcm92aWRpbmcgZGVmaW5pdGlvbnMgZm9yIGdlbmVyYWwgZW50aXRpZXMsCi0gICAgICogaXQgY2FuIG1ha2UgYSBtYWxmb3JtZWQgZG9jdW1lbnQgYXBwZWFyIHRvIGJlIHdlbGwgZm9ybWVkLgotICAgICAqIDwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lIElkZW50aWZpZXMgdGhlIGRvY3VtZW50IHJvb3QgZWxlbWVudC4gIFRoaXMgbmFtZSBjb21lcwotICAgICAqICBmcm9tIGEgRE9DVFlQRSBkZWNsYXJhdGlvbiAod2hlcmUgYXZhaWxhYmxlKSBvciBmcm9tIHRoZSBhY3R1YWwKLSAgICAgKiAgcm9vdCBlbGVtZW50LgotICAgICAqIEBwYXJhbSBiYXNlVVJJIFRoZSBkb2N1bWVudCdzIGJhc2UgVVJJLCBzZXJ2aW5nIGFzIGFuIGFkZGl0aW9uYWwKLSAgICAgKiAgaGludCBmb3Igc2VsZWN0aW5nIHRoZSBleHRlcm5hbCBzdWJzZXQuICBUaGlzIGlzIGFsd2F5cyBhbiBhYnNvbHV0ZQotICAgICAqICBVUkksIHVubGVzcyBpdCBpcyBudWxsIGJlY2F1c2UgdGhlIFhNTFJlYWRlciB3YXMgZ2l2ZW4gYW4gSW5wdXRTb3VyY2UKLSAgICAgKiAgd2l0aG91dCBvbmUuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIEFuIElucHV0U291cmNlIG9iamVjdCBkZXNjcmliaW5nIHRoZSBuZXcgZXh0ZXJuYWwgc3Vic2V0Ci0gICAgICogIHRvIGJlIHVzZWQgYnkgdGhlIHBhcnNlciwgb3IgbnVsbCB0byBpbmRpY2F0ZSB0aGF0IG5vIGV4dGVybmFsCi0gICAgICogIHN1YnNldCBpcyBwcm92aWRlZC4KLSAgICAgKgotICAgICAqIEBleGNlcHRpb24gU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseSB3cmFwcGluZwotICAgICAqICBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICAgKiBAZXhjZXB0aW9uIElPRXhjZXB0aW9uIFByb2JhYmx5IGluZGljYXRpbmcgYSBmYWlsdXJlIHRvIGNyZWF0ZQotICAgICAqICBhIG5ldyBJbnB1dFN0cmVhbSBvciBSZWFkZXIsIG9yIGFuIGlsbGVnYWwgVVJMLgotICAgICAqLwotICAgIHB1YmxpYyBJbnB1dFNvdXJjZSBnZXRFeHRlcm5hbFN1YnNldCAoU3RyaW5nIG5hbWUsIFN0cmluZyBiYXNlVVJJKQotICAgIHRocm93cyBTQVhFeGNlcHRpb24sIElPRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogQWxsb3dzIGFwcGxpY2F0aW9ucyB0byBtYXAgcmVmZXJlbmNlcyB0byBleHRlcm5hbCBlbnRpdGllcyBpbnRvIGlucHV0Ci0gICAgICogc291cmNlcywgb3IgdGVsbCB0aGUgcGFyc2VyIGl0IHNob3VsZCB1c2UgY29udmVudGlvbmFsIFVSSSByZXNvbHV0aW9uLgotICAgICAqIFRoaXMgbWV0aG9kIGlzIG9ubHkgY2FsbGVkIGZvciBleHRlcm5hbCBlbnRpdGllcyB3aGljaCBoYXZlIGJlZW4KLSAgICAgKiBwcm9wZXJseSBkZWNsYXJlZC4KLSAgICAgKiBUaGlzIG1ldGhvZCBwcm92aWRlcyBtb3JlIGZsZXhpYmlsaXR5IHRoYW4gdGhlIHtAbGluayBFbnRpdHlSZXNvbHZlcn0KLSAgICAgKiBpbnRlcmZhY2UsIHN1cHBvcnRpbmcgaW1wbGVtZW50YXRpb25zIG9mIG1vcmUgY29tcGxleCBjYXRhbG9ndWUKLSAgICAgKiBzY2hlbWVzIHN1Y2ggYXMgdGhlIG9uZSBkZWZpbmVkIGJ5IHRoZSA8YSBocmVmPQotICAgICAgICAiaHR0cDovL3d3dy5vYXNpcy1vcGVuLm9yZy9jb21taXR0ZWVzL2VudGl0eS9zcGVjLTIwMDEtMDgtMDYuaHRtbCIKLSAgICAgICAgPk9BU0lTIFhNTCBDYXRhbG9nczwvYT4gc3BlY2lmaWNhdGlvbi48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5QYXJzZXJzIGNvbmZpZ3VyZWQgdG8gdXNlIHRoaXMgcmVzb2x2ZXIgbWV0aG9kIHdpbGwgY2FsbCBpdAotICAgICAqIHRvIGRldGVybWluZSB0aGUgaW5wdXQgc291cmNlIHRvIHVzZSBmb3IgYW55IGV4dGVybmFsIGVudGl0eQotICAgICAqIGJlaW5nIGluY2x1ZGVkIGJlY2F1c2Ugb2YgYSByZWZlcmVuY2UgaW4gdGhlIFhNTCB0ZXh0LgotICAgICAqIFRoYXQgZXhjbHVkZXMgdGhlIGRvY3VtZW50IGVudGl0eSwgYW5kIGFueSBleHRlcm5hbCBlbnRpdHkgcmV0dXJuZWQKLSAgICAgKiBieSB7QGxpbmsgI2dldEV4dGVybmFsU3Vic2V0IGdldEV4dGVybmFsU3Vic2V0KCl9LgotICAgICAqIFdoZW4gYSAobm9uLXZhbGlkYXRpbmcpIHByb2Nlc3NvciBpcyBjb25maWd1cmVkIG5vdCB0byBpbmNsdWRlCi0gICAgICogYSBjbGFzcyBvZiBlbnRpdGllcyAocGFyYW1ldGVyIG9yIGdlbmVyYWwpIHRocm91Z2ggdXNlIG9mIGZlYXR1cmUKLSAgICAgKiBmbGFncywgdGhpcyBtZXRob2QgaXMgbm90IGludm9rZWQgZm9yIHN1Y2ggZW50aXRpZXMuICA8L3A+Ci0gICAgICoKLSAgICAgKiA8cD5Ob3RlIHRoYXQgdGhlIGVudGl0eSBuYW1pbmcgc2NoZW1lIHVzZWQgaGVyZSBpcyB0aGUgc2FtZSBvbmUKLSAgICAgKiB1c2VkIGluIHRoZSB7QGxpbmsgTGV4aWNhbEhhbmRsZXJ9LCBvciBpbiB0aGUge0BsaW5rCi0gICAgICAgIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI3NraXBwZWRFbnRpdHkKLSAgICAgICAgQ29udGVudEhhbmRsZXIuc2tpcHBlZEVudGl0eSgpfQotICAgICAqIG1ldGhvZC4gPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgSWRlbnRpZmllcyB0aGUgZXh0ZXJuYWwgZW50aXR5IGJlaW5nIHJlc29sdmVkLgotICAgICAqICBFaXRoZXIgIltkdGRdIiBmb3IgdGhlIGV4dGVybmFsIHN1YnNldCwgb3IgYSBuYW1lIHN0YXJ0aW5nCi0gICAgICogIHdpdGggIiUiIHRvIGluZGljYXRlIGEgcGFyYW1ldGVyIGVudGl0eSwgb3IgZWxzZSB0aGUgbmFtZSBvZgotICAgICAqICBhIGdlbmVyYWwgZW50aXR5LiAgVGhpcyBpcyBuZXZlciBudWxsIHdoZW4gaW52b2tlZCBieSBhIFNBWDIKLSAgICAgKiAgcGFyc2VyLgotICAgICAqIEBwYXJhbSBwdWJsaWNJZCBUaGUgcHVibGljIGlkZW50aWZpZXIgb2YgdGhlIGV4dGVybmFsIGVudGl0eSBiZWluZwotICAgICAqICByZWZlcmVuY2VkIChub3JtYWxpemVkIGFzIHJlcXVpcmVkIGJ5IHRoZSBYTUwgc3BlY2lmaWNhdGlvbiksIG9yCi0gICAgICogIG51bGwgaWYgbm9uZSB3YXMgc3VwcGxpZWQuCi0gICAgICogQHBhcmFtIGJhc2VVUkkgVGhlIFVSSSB3aXRoIHJlc3BlY3QgdG8gd2hpY2ggcmVsYXRpdmUgc3lzdGVtSURzCi0gICAgICogIGFyZSBpbnRlcnByZXRlZC4gIFRoaXMgaXMgYWx3YXlzIGFuIGFic29sdXRlIFVSSSwgdW5sZXNzIGl0IGlzCi0gICAgICogIG51bGwgKGxpa2VseSBiZWNhdXNlIHRoZSBYTUxSZWFkZXIgd2FzIGdpdmVuIGFuIElucHV0U291cmNlIHdpdGhvdXQKLSAgICAgKiAgb25lKS4gIFRoaXMgVVJJIGlzIGRlZmluZWQgYnkgdGhlIFhNTCBzcGVjaWZpY2F0aW9uIHRvIGJlIHRoZSBvbmUKLSAgICAgKiAgYXNzb2NpYXRlZCB3aXRoIHRoZSAiJmx0OyIgc3RhcnRpbmcgdGhlIHJlbGV2YW50IGRlY2xhcmF0aW9uLgotICAgICAqIEBwYXJhbSBzeXN0ZW1JZCBUaGUgc3lzdGVtIGlkZW50aWZpZXIgb2YgdGhlIGV4dGVybmFsIGVudGl0eQotICAgICAqICBiZWluZyByZWZlcmVuY2VkOyBlaXRoZXIgYSByZWxhdGl2ZSBvciBhYnNvbHV0ZSBVUkkuCi0gICAgICogIFRoaXMgaXMgbmV2ZXIgbnVsbCB3aGVuIGludm9rZWQgYnkgYSBTQVgyIHBhcnNlcjsgb25seSBkZWNsYXJlZAotICAgICAqICBlbnRpdGllcywgYW5kIGFueSBleHRlcm5hbCBzdWJzZXQsIGFyZSByZXNvbHZlZCBieSBzdWNoIHBhcnNlcnMuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIEFuIElucHV0U291cmNlIG9iamVjdCBkZXNjcmliaW5nIHRoZSBuZXcgaW5wdXQgc291cmNlIHRvCi0gICAgICogIGJlIHVzZWQgYnkgdGhlIHBhcnNlci4gIFJldHVybmluZyBudWxsIGRpcmVjdHMgdGhlIHBhcnNlciB0bwotICAgICAqICByZXNvbHZlIHRoZSBzeXN0ZW0gSUQgYWdhaW5zdCB0aGUgYmFzZSBVUkkgYW5kIG9wZW4gYSBjb25uZWN0aW9uCi0gICAgICogIHRvIHJlc3VsdGluZyBVUkkuCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIFNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkgd3JhcHBpbmcKLSAgICAgKiAgYW5vdGhlciBleGNlcHRpb24uCi0gICAgICogQGV4Y2VwdGlvbiBJT0V4Y2VwdGlvbiBQcm9iYWJseSBpbmRpY2F0aW5nIGEgZmFpbHVyZSB0byBjcmVhdGUKLSAgICAgKiAgYSBuZXcgSW5wdXRTdHJlYW0gb3IgUmVhZGVyLCBvciBhbiBpbGxlZ2FsIFVSTC4KLSAgICAgKi8KLSAgICBwdWJsaWMgSW5wdXRTb3VyY2UgcmVzb2x2ZUVudGl0eSAoCi0gICAgICAgICAgICBTdHJpbmcgbmFtZSwKLSAgICAgICAgICAgIFN0cmluZyBwdWJsaWNJZCwKLSAgICAgICAgICAgIFN0cmluZyBiYXNlVVJJLAotICAgICAgICAgICAgU3RyaW5nIHN5c3RlbUlkCi0gICAgKSB0aHJvd3MgU0FYRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbjsKLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcveG1sL3NheC9leHQvTGV4aWNhbEhhbmRsZXIuamF2YSBiL3NyYy9vcmcveG1sL3NheC9leHQvTGV4aWNhbEhhbmRsZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZGNjZWNlZS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3htbC9zYXgvZXh0L0xleGljYWxIYW5kbGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMzYgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwMCwgMjAwNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLy8gTGV4aWNhbEhhbmRsZXIuamF2YSAtIG9wdGlvbmFsIGhhbmRsZXIgZm9yIGxleGljYWwgcGFyc2UgZXZlbnRzLgotLy8gaHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZwotLy8gUHVibGljIERvbWFpbjogbm8gd2FycmFudHkuCi0vLyAkSWQ6IExleGljYWxIYW5kbGVyLmphdmEsdiAxLjIgMjAwNC8xMS8wMyAyMjo0OTowOCBqc3V0dG9yIEV4cCAkCi0KLXBhY2thZ2Ugb3JnLnhtbC5zYXguZXh0OwotCi1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotCi0vKioKLSAqIFNBWDIgZXh0ZW5zaW9uIGhhbmRsZXIgZm9yIGxleGljYWwgZXZlbnRzLgotICoKLSAqIDxibG9ja3F1b3RlPgotICogPGVtPlRoaXMgbW9kdWxlLCBib3RoIHNvdXJjZSBjb2RlIGFuZCBkb2N1bWVudGF0aW9uLCBpcyBpbiB0aGUKLSAqIFB1YmxpYyBEb21haW4sIGFuZCBjb21lcyB3aXRoIDxzdHJvbmc+Tk8gV0FSUkFOVFk8L3N0cm9uZz4uPC9lbT4KLSAqIFNlZSA8YSBocmVmPSdodHRwOi8vd3d3LnNheHByb2plY3Qub3JnJz5odHRwOi8vd3d3LnNheHByb2plY3Qub3JnPC9hPgotICogZm9yIGZ1cnRoZXIgaW5mb3JtYXRpb24uCi0gKiA8L2Jsb2NrcXVvdGU+Ci0gKgotICogPHA+VGhpcyBpcyBhbiBvcHRpb25hbCBleHRlbnNpb24gaGFuZGxlciBmb3IgU0FYMiB0byBwcm92aWRlCi0gKiBsZXhpY2FsIGluZm9ybWF0aW9uIGFib3V0IGFuIFhNTCBkb2N1bWVudCwgc3VjaCBhcyBjb21tZW50cwotICogYW5kIENEQVRBIHNlY3Rpb24gYm91bmRhcmllcy4KLSAqIFhNTCByZWFkZXJzIGFyZSBub3QgcmVxdWlyZWQgdG8gcmVjb2duaXplIHRoaXMgaGFuZGxlciwgYW5kIGl0Ci0gKiBpcyBub3QgcGFydCBvZiBjb3JlLW9ubHkgU0FYMiBkaXN0cmlidXRpb25zLjwvcD4KLSAqCi0gKiA8cD5UaGUgZXZlbnRzIGluIHRoZSBsZXhpY2FsIGhhbmRsZXIgYXBwbHkgdG8gdGhlIGVudGlyZSBkb2N1bWVudCwKLSAqIG5vdCBqdXN0IHRvIHRoZSBkb2N1bWVudCBlbGVtZW50LCBhbmQgYWxsIGxleGljYWwgaGFuZGxlciBldmVudHMKLSAqIG11c3QgYXBwZWFyIGJldHdlZW4gdGhlIGNvbnRlbnQgaGFuZGxlcidzIHN0YXJ0RG9jdW1lbnQgYW5kCi0gKiBlbmREb2N1bWVudCBldmVudHMuPC9wPgotICoKLSAqIDxwPlRvIHNldCB0aGUgTGV4aWNhbEhhbmRsZXIgZm9yIGFuIFhNTCByZWFkZXIsIHVzZSB0aGUKLSAqIHtAbGluayBvcmcueG1sLnNheC5YTUxSZWFkZXIjc2V0UHJvcGVydHkgc2V0UHJvcGVydHl9IG1ldGhvZAotICogd2l0aCB0aGUgcHJvcGVydHkgbmFtZQotICogPGNvZGU+aHR0cDovL3htbC5vcmcvc2F4L3Byb3BlcnRpZXMvbGV4aWNhbC1oYW5kbGVyPC9jb2RlPgotICogYW5kIGFuIG9iamVjdCBpbXBsZW1lbnRpbmcgdGhpcyBpbnRlcmZhY2UgKG9yIG51bGwpIGFzIHRoZSB2YWx1ZS4KLSAqIElmIHRoZSByZWFkZXIgZG9lcyBub3QgcmVwb3J0IGxleGljYWwgZXZlbnRzLCBpdCB3aWxsIHRocm93IGEKLSAqIHtAbGluayBvcmcueG1sLnNheC5TQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb259Ci0gKiB3aGVuIHlvdSBhdHRlbXB0IHRvIHJlZ2lzdGVyIHRoZSBoYW5kbGVyLjwvcD4KLSAqCi0gKiBAc2luY2UgU0FYIDIuMCAoZXh0ZW5zaW9ucyAxLjApCi0gKiBAYXV0aG9yIERhdmlkIE1lZ2dpbnNvbgotICovCi1wdWJsaWMgaW50ZXJmYWNlIExleGljYWxIYW5kbGVyCi17Ci0KLSAgICAvKioKLSAgICAgKiBSZXBvcnQgdGhlIHN0YXJ0IG9mIERURCBkZWNsYXJhdGlvbnMsIGlmIGFueS4KLSAgICAgKgotICAgICAqIDxwPlRoaXMgbWV0aG9kIGlzIGludGVuZGVkIHRvIHJlcG9ydCB0aGUgYmVnaW5uaW5nIG9mIHRoZQotICAgICAqIERPQ1RZUEUgZGVjbGFyYXRpb247IGlmIHRoZSBkb2N1bWVudCBoYXMgbm8gRE9DVFlQRSBkZWNsYXJhdGlvbiwKLSAgICAgKiB0aGlzIG1ldGhvZCB3aWxsIG5vdCBiZSBpbnZva2VkLjwvcD4KLSAgICAgKgotICAgICAqIDxwPkFsbCBkZWNsYXJhdGlvbnMgcmVwb3J0ZWQgdGhyb3VnaAotICAgICAqIHtAbGluayBvcmcueG1sLnNheC5EVERIYW5kbGVyIERUREhhbmRsZXJ9IG9yCi0gICAgICoge0BsaW5rIG9yZy54bWwuc2F4LmV4dC5EZWNsSGFuZGxlciBEZWNsSGFuZGxlcn0gZXZlbnRzIG11c3QgYXBwZWFyCi0gICAgICogYmV0d2VlbiB0aGUgc3RhcnREVEQgYW5kIHtAbGluayAjZW5kRFREIGVuZERURH0gZXZlbnRzLgotICAgICAqIERlY2xhcmF0aW9ucyBhcmUgYXNzdW1lZCB0byBiZWxvbmcgdG8gdGhlIGludGVybmFsIERURCBzdWJzZXQKLSAgICAgKiB1bmxlc3MgdGhleSBhcHBlYXIgYmV0d2VlbiB7QGxpbmsgI3N0YXJ0RW50aXR5IHN0YXJ0RW50aXR5fQotICAgICAqIGFuZCB7QGxpbmsgI2VuZEVudGl0eSBlbmRFbnRpdHl9IGV2ZW50cy4gIENvbW1lbnRzIGFuZAotICAgICAqIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb25zIGZyb20gdGhlIERURCBzaG91bGQgYWxzbyBiZSByZXBvcnRlZAotICAgICAqIGJldHdlZW4gdGhlIHN0YXJ0RFREIGFuZCBlbmREVEQgZXZlbnRzLCBpbiB0aGVpciBvcmlnaW5hbAotICAgICAqIG9yZGVyIG9mIChsb2dpY2FsKSBvY2N1cnJlbmNlOyB0aGV5IGFyZSBub3QgcmVxdWlyZWQgdG8KLSAgICAgKiBhcHBlYXIgaW4gdGhlaXIgY29ycmVjdCBsb2NhdGlvbnMgcmVsYXRpdmUgdG8gRFRESGFuZGxlcgotICAgICAqIG9yIERlY2xIYW5kbGVyIGV2ZW50cywgaG93ZXZlci48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5Ob3RlIHRoYXQgdGhlIHN0YXJ0L2VuZERURCBldmVudHMgd2lsbCBhcHBlYXIgd2l0aGluCi0gICAgICogdGhlIHN0YXJ0L2VuZERvY3VtZW50IGV2ZW50cyBmcm9tIENvbnRlbnRIYW5kbGVyIGFuZAotICAgICAqIGJlZm9yZSB0aGUgZmlyc3QKLSAgICAgKiB7QGxpbmsgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjc3RhcnRFbGVtZW50IHN0YXJ0RWxlbWVudH0KLSAgICAgKiBldmVudC48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgZG9jdW1lbnQgdHlwZSBuYW1lLgotICAgICAqIEBwYXJhbSBwdWJsaWNJZCBUaGUgZGVjbGFyZWQgcHVibGljIGlkZW50aWZpZXIgZm9yIHRoZQotICAgICAqICAgICAgICBleHRlcm5hbCBEVEQgc3Vic2V0LCBvciBudWxsIGlmIG5vbmUgd2FzIGRlY2xhcmVkLgotICAgICAqIEBwYXJhbSBzeXN0ZW1JZCBUaGUgZGVjbGFyZWQgc3lzdGVtIGlkZW50aWZpZXIgZm9yIHRoZQotICAgICAqICAgICAgICBleHRlcm5hbCBEVEQgc3Vic2V0LCBvciBudWxsIGlmIG5vbmUgd2FzIGRlY2xhcmVkLgotICAgICAqICAgICAgICAoTm90ZSB0aGF0IHRoaXMgaXMgbm90IHJlc29sdmVkIGFnYWluc3QgdGhlIGRvY3VtZW50Ci0gICAgICogICAgICAgIGJhc2UgVVJJLikKLSAgICAgKiBAZXhjZXB0aW9uIFNBWEV4Y2VwdGlvbiBUaGUgYXBwbGljYXRpb24gbWF5IHJhaXNlIGFuCi0gICAgICogICAgICAgICAgICBleGNlcHRpb24uCi0gICAgICogQHNlZSAjZW5kRFRECi0gICAgICogQHNlZSAjc3RhcnRFbnRpdHkKLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzdGFydERURCAoU3RyaW5nIG5hbWUsIFN0cmluZyBwdWJsaWNJZCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHN5c3RlbUlkKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uOwotCi0KLSAgICAvKioKLSAgICAgKiBSZXBvcnQgdGhlIGVuZCBvZiBEVEQgZGVjbGFyYXRpb25zLgotICAgICAqCi0gICAgICogPHA+VGhpcyBtZXRob2QgaXMgaW50ZW5kZWQgdG8gcmVwb3J0IHRoZSBlbmQgb2YgdGhlCi0gICAgICogRE9DVFlQRSBkZWNsYXJhdGlvbjsgaWYgdGhlIGRvY3VtZW50IGhhcyBubyBET0NUWVBFIGRlY2xhcmF0aW9uLAotICAgICAqIHRoaXMgbWV0aG9kIHdpbGwgbm90IGJlIGludm9rZWQuPC9wPgotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBTQVhFeGNlcHRpb24gVGhlIGFwcGxpY2F0aW9uIG1heSByYWlzZSBhbiBleGNlcHRpb24uCi0gICAgICogQHNlZSAjc3RhcnREVEQKLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBlbmREVEQgKCkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbjsKLQotCi0gICAgLyoqCi0gICAgICogUmVwb3J0IHRoZSBiZWdpbm5pbmcgb2Ygc29tZSBpbnRlcm5hbCBhbmQgZXh0ZXJuYWwgWE1MIGVudGl0aWVzLgotICAgICAqCi0gICAgICogPHA+VGhlIHJlcG9ydGluZyBvZiBwYXJhbWV0ZXIgZW50aXRpZXMgKGluY2x1ZGluZwotICAgICAqIHRoZSBleHRlcm5hbCBEVEQgc3Vic2V0KSBpcyBvcHRpb25hbCwgYW5kIFNBWDIgZHJpdmVycyB0aGF0Ci0gICAgICogcmVwb3J0IExleGljYWxIYW5kbGVyIGV2ZW50cyBtYXkgbm90IGltcGxlbWVudCBpdDsgeW91IGNhbiB1c2UgdGhlCi0gICAgICogPGNvZGUKLSAgICAgKiA+aHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL2xleGljYWwtaGFuZGxlci9wYXJhbWV0ZXItZW50aXRpZXM8L2NvZGU+Ci0gICAgICogZmVhdHVyZSB0byBxdWVyeSBvciBjb250cm9sIHRoZSByZXBvcnRpbmcgb2YgcGFyYW1ldGVyIGVudGl0aWVzLjwvcD4KLSAgICAgKgotICAgICAqIDxwPkdlbmVyYWwgZW50aXRpZXMgYXJlIHJlcG9ydGVkIHdpdGggdGhlaXIgcmVndWxhciBuYW1lcywKLSAgICAgKiBwYXJhbWV0ZXIgZW50aXRpZXMgaGF2ZSAnJScgcHJlcGVuZGVkIHRvIHRoZWlyIG5hbWVzLCBhbmQKLSAgICAgKiB0aGUgZXh0ZXJuYWwgRFREIHN1YnNldCBoYXMgdGhlIHBzZXVkby1lbnRpdHkgbmFtZSAiW2R0ZF0iLjwvcD4KLSAgICAgKgotICAgICAqIDxwPldoZW4gYSBTQVgyIGRyaXZlciBpcyBwcm92aWRpbmcgdGhlc2UgZXZlbnRzLCBhbGwgb3RoZXIKLSAgICAgKiBldmVudHMgbXVzdCBiZSBwcm9wZXJseSBuZXN0ZWQgd2l0aGluIHN0YXJ0L2VuZCBlbnRpdHkKLSAgICAgKiBldmVudHMuICBUaGVyZSBpcyBubyBhZGRpdGlvbmFsIHJlcXVpcmVtZW50IHRoYXQgZXZlbnRzIGZyb20KLSAgICAgKiB7QGxpbmsgb3JnLnhtbC5zYXguZXh0LkRlY2xIYW5kbGVyIERlY2xIYW5kbGVyfSBvcgotICAgICAqIHtAbGluayBvcmcueG1sLnNheC5EVERIYW5kbGVyIERUREhhbmRsZXJ9IGJlIHByb3Blcmx5IG9yZGVyZWQuPC9wPgotICAgICAqCi0gICAgICogPHA+Tm90ZSB0aGF0IHNraXBwZWQgZW50aXRpZXMgd2lsbCBiZSByZXBvcnRlZCB0aHJvdWdoIHRoZQotICAgICAqIHtAbGluayBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNza2lwcGVkRW50aXR5IHNraXBwZWRFbnRpdHl9Ci0gICAgICogZXZlbnQsIHdoaWNoIGlzIHBhcnQgb2YgdGhlIENvbnRlbnRIYW5kbGVyIGludGVyZmFjZS48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5CZWNhdXNlIG9mIHRoZSBzdHJlYW1pbmcgZXZlbnQgbW9kZWwgdGhhdCBTQVggdXNlcywgc29tZQotICAgICAqIGVudGl0eSBib3VuZGFyaWVzIGNhbm5vdCBiZSByZXBvcnRlZCB1bmRlciBhbnkKLSAgICAgKiBjaXJjdW1zdGFuY2VzOjwvcD4KLSAgICAgKgotICAgICAqIDx1bD4KLSAgICAgKiA8bGk+Z2VuZXJhbCBlbnRpdGllcyB3aXRoaW4gYXR0cmlidXRlIHZhbHVlczwvbGk+Ci0gICAgICogPGxpPnBhcmFtZXRlciBlbnRpdGllcyB3aXRoaW4gZGVjbGFyYXRpb25zPC9saT4KLSAgICAgKiA8L3VsPgotICAgICAqCi0gICAgICogPHA+VGhlc2Ugd2lsbCBiZSBzaWxlbnRseSBleHBhbmRlZCwgd2l0aCBubyBpbmRpY2F0aW9uIG9mIHdoZXJlCi0gICAgICogdGhlIG9yaWdpbmFsIGVudGl0eSBib3VuZGFyaWVzIHdlcmUuPC9wPgotICAgICAqCi0gICAgICogPHA+Tm90ZSBhbHNvIHRoYXQgdGhlIGJvdW5kYXJpZXMgb2YgY2hhcmFjdGVyIHJlZmVyZW5jZXMgKHdoaWNoCi0gICAgICogYXJlIG5vdCByZWFsbHkgZW50aXRpZXMgYW55d2F5KSBhcmUgbm90IHJlcG9ydGVkLjwvcD4KLSAgICAgKgotICAgICAqIDxwPkFsbCBzdGFydC9lbmRFbnRpdHkgZXZlbnRzIG11c3QgYmUgcHJvcGVybHkgbmVzdGVkLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGVudGl0eS4gIElmIGl0IGlzIGEgcGFyYW1ldGVyCi0gICAgICogICAgICAgIGVudGl0eSwgdGhlIG5hbWUgd2lsbCBiZWdpbiB3aXRoICclJywgYW5kIGlmIGl0IGlzIHRoZQotICAgICAqICAgICAgICBleHRlcm5hbCBEVEQgc3Vic2V0LCBpdCB3aWxsIGJlICJbZHRkXSIuCi0gICAgICogQGV4Y2VwdGlvbiBTQVhFeGNlcHRpb24gVGhlIGFwcGxpY2F0aW9uIG1heSByYWlzZSBhbiBleGNlcHRpb24uCi0gICAgICogQHNlZSAjZW5kRW50aXR5Ci0gICAgICogQHNlZSBvcmcueG1sLnNheC5leHQuRGVjbEhhbmRsZXIjaW50ZXJuYWxFbnRpdHlEZWNsCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5leHQuRGVjbEhhbmRsZXIjZXh0ZXJuYWxFbnRpdHlEZWNsCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IHZvaWQgc3RhcnRFbnRpdHkgKFN0cmluZyBuYW1lKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uOwotCi0KLSAgICAvKioKLSAgICAgKiBSZXBvcnQgdGhlIGVuZCBvZiBhbiBlbnRpdHkuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgZW50aXR5IHRoYXQgaXMgZW5kaW5nLgotICAgICAqIEBleGNlcHRpb24gU0FYRXhjZXB0aW9uIFRoZSBhcHBsaWNhdGlvbiBtYXkgcmFpc2UgYW4gZXhjZXB0aW9uLgotICAgICAqIEBzZWUgI3N0YXJ0RW50aXR5Ci0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IHZvaWQgZW5kRW50aXR5IChTdHJpbmcgbmFtZSkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbjsKLQotCi0gICAgLyoqCi0gICAgICogUmVwb3J0IHRoZSBzdGFydCBvZiBhIENEQVRBIHNlY3Rpb24uCi0gICAgICoKLSAgICAgKiA8cD5UaGUgY29udGVudHMgb2YgdGhlIENEQVRBIHNlY3Rpb24gd2lsbCBiZSByZXBvcnRlZCB0aHJvdWdoCi0gICAgICogdGhlIHJlZ3VsYXIge0BsaW5rIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI2NoYXJhY3RlcnMKLSAgICAgKiBjaGFyYWN0ZXJzfSBldmVudDsgdGhpcyBldmVudCBpcyBpbnRlbmRlZCBvbmx5IHRvIHJlcG9ydAotICAgICAqIHRoZSBib3VuZGFyeS48L3A+Ci0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIFNBWEV4Y2VwdGlvbiBUaGUgYXBwbGljYXRpb24gbWF5IHJhaXNlIGFuIGV4Y2VwdGlvbi4KLSAgICAgKiBAc2VlICNlbmRDREFUQQotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHN0YXJ0Q0RBVEEgKCkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbjsKLQotCi0gICAgLyoqCi0gICAgICogUmVwb3J0IHRoZSBlbmQgb2YgYSBDREFUQSBzZWN0aW9uLgotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBTQVhFeGNlcHRpb24gVGhlIGFwcGxpY2F0aW9uIG1heSByYWlzZSBhbiBleGNlcHRpb24uCi0gICAgICogQHNlZSAjc3RhcnRDREFUQQotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIGVuZENEQVRBICgpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb247Ci0KLQotICAgIC8qKgotICAgICAqIFJlcG9ydCBhbiBYTUwgY29tbWVudCBhbnl3aGVyZSBpbiB0aGUgZG9jdW1lbnQuCi0gICAgICoKLSAgICAgKiA8cD5UaGlzIGNhbGxiYWNrIHdpbGwgYmUgdXNlZCBmb3IgY29tbWVudHMgaW5zaWRlIG9yIG91dHNpZGUgdGhlCi0gICAgICogZG9jdW1lbnQgZWxlbWVudCwgaW5jbHVkaW5nIGNvbW1lbnRzIGluIHRoZSBleHRlcm5hbCBEVEQKLSAgICAgKiBzdWJzZXQgKGlmIHJlYWQpLiAgQ29tbWVudHMgaW4gdGhlIERURCBtdXN0IGJlIHByb3Blcmx5Ci0gICAgICogbmVzdGVkIGluc2lkZSBzdGFydC9lbmREVEQgYW5kIHN0YXJ0L2VuZEVudGl0eSBldmVudHMgKGlmCi0gICAgICogdXNlZCkuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGNoIEFuIGFycmF5IGhvbGRpbmcgdGhlIGNoYXJhY3RlcnMgaW4gdGhlIGNvbW1lbnQuCi0gICAgICogQHBhcmFtIHN0YXJ0IFRoZSBzdGFydGluZyBwb3NpdGlvbiBpbiB0aGUgYXJyYXkuCi0gICAgICogQHBhcmFtIGxlbmd0aCBUaGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gdXNlIGZyb20gdGhlIGFycmF5LgotICAgICAqIEBleGNlcHRpb24gU0FYRXhjZXB0aW9uIFRoZSBhcHBsaWNhdGlvbiBtYXkgcmFpc2UgYW4gZXhjZXB0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIGNvbW1lbnQgKGNoYXIgY2hbXSwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uOwotCi19Ci0KLS8vIGVuZCBvZiBMZXhpY2FsSGFuZGxlci5qYXZhCmRpZmYgLS1naXQgYS9zcmMvb3JnL3htbC9zYXgvZXh0L0xvY2F0b3IyLmphdmEgYi9zcmMvb3JnL3htbC9zYXgvZXh0L0xvY2F0b3IyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGM2NTFhNmUuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy94bWwvc2F4L2V4dC9Mb2NhdG9yMi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTkgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwNCwgMjAwNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLy8gTG9jYXRvcjIuamF2YSAtIGV4dGVuZGVkIExvY2F0b3IKLS8vIGh0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmcKLS8vIFB1YmxpYyBEb21haW46IG5vIHdhcnJhbnR5LgotLy8gJElkOiBMb2NhdG9yMi5qYXZhLHYgMS4yIDIwMDQvMTEvMDMgMjI6NDk6MDgganN1dHRvciBFeHAgJAotCi1wYWNrYWdlIG9yZy54bWwuc2F4LmV4dDsKLQotaW1wb3J0IG9yZy54bWwuc2F4LkxvY2F0b3I7Ci0KLQotLyoqCi0gKiBTQVgyIGV4dGVuc2lvbiB0byBhdWdtZW50IHRoZSBlbnRpdHkgaW5mb3JtYXRpb24gcHJvdmlkZWQKLSAqIHRob3VnaCBhIHtAbGluayBMb2NhdG9yfS4KLSAqIElmIGFuIGltcGxlbWVudGF0aW9uIHN1cHBvcnRzIHRoaXMgZXh0ZW5zaW9uLCB0aGUgTG9jYXRvcgotICogcHJvdmlkZWQgaW4ge0BsaW5rIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI3NldERvY3VtZW50TG9jYXRvcgotICogQ29udGVudEhhbmRsZXIuc2V0RG9jdW1lbnRMb2NhdG9yKCkgfSB3aWxsIGltcGxlbWVudCB0aGlzCi0gKiBpbnRlcmZhY2UsIGFuZCB0aGUKLSAqIDxlbT5odHRwOi8veG1sLm9yZy9zYXgvZmVhdHVyZXMvdXNlLWxvY2F0b3IyPC9lbT4gZmVhdHVyZQotICogZmxhZyB3aWxsIGhhdmUgdGhlIHZhbHVlIDxlbT50cnVlPC9lbT4uCi0gKgotICogPGJsb2NrcXVvdGU+Ci0gKiA8ZW0+VGhpcyBtb2R1bGUsIGJvdGggc291cmNlIGNvZGUgYW5kIGRvY3VtZW50YXRpb24sIGlzIGluIHRoZQotICogUHVibGljIERvbWFpbiwgYW5kIGNvbWVzIHdpdGggPHN0cm9uZz5OTyBXQVJSQU5UWTwvc3Ryb25nPi48L2VtPgotICogPC9ibG9ja3F1b3RlPgotICoKLSAqIDxwPiBYTUxSZWFkZXIgaW1wbGVtZW50YXRpb25zIGFyZSBub3QgcmVxdWlyZWQgdG8gc3VwcG9ydCB0aGlzCi0gKiBpbmZvcm1hdGlvbiwgYW5kIGl0IGlzIG5vdCBwYXJ0IG9mIGNvcmUtb25seSBTQVgyIGRpc3RyaWJ1dGlvbnMuPC9wPgotICoKLSAqIEBzaW5jZSBTQVggMi4wIChleHRlbnNpb25zIDEuMSBhbHBoYSkKLSAqIEBhdXRob3IgRGF2aWQgQnJvd25lbGwKLSAqLwotcHVibGljIGludGVyZmFjZSBMb2NhdG9yMiBleHRlbmRzIExvY2F0b3IKLXsKLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSB2ZXJzaW9uIG9mIFhNTCB1c2VkIGZvciB0aGUgZW50aXR5LiAgVGhpcyB3aWxsCi0gICAgICogbm9ybWFsbHkgYmUgdGhlIGlkZW50aWZpZXIgZnJvbSB0aGUgY3VycmVudCBlbnRpdHkncwotICAgICAqIDxlbT4mbHQ7P3htbCZuYnNwO3ZlcnNpb249Jy4uLicmbmJzcDsuLi4/Jmd0OzwvZW0+IGRlY2xhcmF0aW9uLAotICAgICAqIG9yIGJlIGRlZmF1bHRlZCBieSB0aGUgcGFyc2VyLgotICAgICAqCi0gICAgICogQHJldHVybiBJZGVudGlmaWVyIGZvciB0aGUgWE1MIHZlcnNpb24gYmVpbmcgdXNlZCB0byBpbnRlcnByZXQKLSAgICAgKiB0aGUgZW50aXR5J3MgdGV4dCwgb3IgbnVsbCBpZiB0aGF0IGluZm9ybWF0aW9uIGlzIG5vdCB5ZXQKLSAgICAgKiBhdmFpbGFibGUgaW4gdGhlIGN1cnJlbnQgcGFyc2luZyBzdGF0ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFhNTFZlcnNpb24gKCk7Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSBjaGFyYWN0ZXIgZW5jb2RpbmcgZm9yIHRoZSBlbnRpdHkuCi0gICAgICogSWYgdGhlIGVuY29kaW5nIHdhcyBkZWNsYXJlZCBleHRlcm5hbGx5IChmb3IgZXhhbXBsZSwgaW4gYSBNSU1FCi0gICAgICogQ29udGVudC1UeXBlIGhlYWRlciksIHRoYXQgd2lsbCBiZSB0aGUgbmFtZSByZXR1cm5lZC4gIEVsc2UgaWYgdGhlcmUKLSAgICAgKiB3YXMgYW4gPGVtPiZsdDs/eG1sJm5ic3A7Li4uZW5jb2Rpbmc9Jy4uLic/Jmd0OzwvZW0+IGRlY2xhcmF0aW9uIGF0Ci0gICAgICogdGhlIHN0YXJ0IG9mIHRoZSBkb2N1bWVudCwgdGhhdCBlbmNvZGluZyBuYW1lIHdpbGwgYmUgcmV0dXJuZWQuCi0gICAgICogT3RoZXJ3aXNlIHRoZSBlbmNvZGluZyB3aWxsIGJlZW4gaW5mZXJyZWQgKG5vcm1hbGx5IHRvIGJlIFVURi04LCBvcgotICAgICAqIHNvbWUgVVRGLTE2IHZhcmlhbnQpLCBhbmQgdGhhdCBpbmZlcnJlZCBuYW1lIHdpbGwgYmUgcmV0dXJuZWQuCi0gICAgICoKLSAgICAgKiA8cD5XaGVuIGFuIHtAbGluayBvcmcueG1sLnNheC5JbnB1dFNvdXJjZSBJbnB1dFNvdXJjZX0gaXMgdXNlZAotICAgICAqIHRvIHByb3ZpZGUgYW4gZW50aXR5J3MgY2hhcmFjdGVyIHN0cmVhbSwgdGhpcyBtZXRob2QgcmV0dXJucyB0aGUKLSAgICAgKiBlbmNvZGluZyBwcm92aWRlZCBpbiB0aGF0IGlucHV0IHN0cmVhbS4KLSAgICAgKgotICAgICAqIDxwPiBOb3RlIHRoYXQgc29tZSByZWNlbnQgVzNDIHNwZWNpZmljYXRpb25zIHJlcXVpcmUgdGhhdCB0ZXh0Ci0gICAgICogaW4gc29tZSBlbmNvZGluZ3MgYmUgbm9ybWFsaXplZCwgdXNpbmcgVW5pY29kZSBOb3JtYWxpemF0aW9uCi0gICAgICogRm9ybSBDLCBiZWZvcmUgcHJvY2Vzc2luZy4gIFN1Y2ggbm9ybWFsaXphdGlvbiBtdXN0IGJlIHBlcmZvcm1lZAotICAgICAqIGJ5IGFwcGxpY2F0aW9ucywgYW5kIHdvdWxkIG5vcm1hbGx5IGJlIHRyaWdnZXJlZCBiYXNlZCBvbiB0aGUKLSAgICAgKiB2YWx1ZSByZXR1cm5lZCBieSB0aGlzIG1ldGhvZC4KLSAgICAgKgotICAgICAqIDxwPiBFbmNvZGluZyBuYW1lcyBtYXkgYmUgdGhvc2UgdXNlZCBieSB0aGUgdW5kZXJseWluZyBKVk0sCi0gICAgICogYW5kIGNvbXBhcmlzb25zIHNob3VsZCBiZSBjYXNlLWluc2Vuc2l0aXZlLgotICAgICAqCi0gICAgICogQHJldHVybiBOYW1lIG9mIHRoZSBjaGFyYWN0ZXIgZW5jb2RpbmcgYmVpbmcgdXNlZCB0byBpbnRlcnByZXQKLSAgICAgKiAqIHRoZSBlbnRpdHkncyB0ZXh0LCBvciBudWxsIGlmIHRoaXMgd2FzIG5vdCBwcm92aWRlZCBmb3IgYSAqCi0gICAgICogY2hhcmFjdGVyIHN0cmVhbSBwYXNzZWQgdGhyb3VnaCBhbiBJbnB1dFNvdXJjZSBvciBpcyBvdGhlcndpc2UKLSAgICAgKiBub3QgeWV0IGF2YWlsYWJsZSBpbiB0aGUgY3VycmVudCBwYXJzaW5nIHN0YXRlLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0RW5jb2RpbmcgKCk7Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL3htbC9zYXgvZXh0L0xvY2F0b3IySW1wbC5qYXZhIGIvc3JjL29yZy94bWwvc2F4L2V4dC9Mb2NhdG9yMkltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZDQ3YjI3ZS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3htbC9zYXgvZXh0L0xvY2F0b3IySW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTI1ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDQsIDIwMDUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8vIExvY2F0b3IySW1wbC5qYXZhIC0gZXh0ZW5kZWQgTG9jYXRvckltcGwKLS8vIGh0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmcKLS8vIFB1YmxpYyBEb21haW46IG5vIHdhcnJhbnR5LgotLy8gJElkOiBMb2NhdG9yMkltcGwuamF2YSx2IDEuMiAyMDA0LzExLzAzIDIyOjQ5OjA4IGpzdXR0b3IgRXhwICQKLQotcGFja2FnZSBvcmcueG1sLnNheC5leHQ7Ci0KLWltcG9ydCBvcmcueG1sLnNheC5Mb2NhdG9yOwotaW1wb3J0IG9yZy54bWwuc2F4LmhlbHBlcnMuTG9jYXRvckltcGw7Ci0KLQotLyoqCi0gKiBTQVgyIGV4dGVuc2lvbiBoZWxwZXIgZm9yIGhvbGRpbmcgYWRkaXRpb25hbCBFbnRpdHkgaW5mb3JtYXRpb24sCi0gKiBpbXBsZW1lbnRpbmcgdGhlIHtAbGluayBMb2NhdG9yMn0gaW50ZXJmYWNlLgotICoKLSAqIDxibG9ja3F1b3RlPgotICogPGVtPlRoaXMgbW9kdWxlLCBib3RoIHNvdXJjZSBjb2RlIGFuZCBkb2N1bWVudGF0aW9uLCBpcyBpbiB0aGUKLSAqIFB1YmxpYyBEb21haW4sIGFuZCBjb21lcyB3aXRoIDxzdHJvbmc+Tk8gV0FSUkFOVFk8L3N0cm9uZz4uPC9lbT4KLSAqIDwvYmxvY2txdW90ZT4KLSAqCi0gKiA8cD4gVGhpcyBpcyBub3QgcGFydCBvZiBjb3JlLW9ubHkgU0FYMiBkaXN0cmlidXRpb25zLjwvcD4KLSAqCi0gKiBAc2luY2UgU0FYIDIuMC4yCi0gKiBAYXV0aG9yIERhdmlkIEJyb3duZWxsCi0gKi8KLXB1YmxpYyBjbGFzcyBMb2NhdG9yMkltcGwgZXh0ZW5kcyBMb2NhdG9ySW1wbCBpbXBsZW1lbnRzIExvY2F0b3IyCi17Ci0gICAgcHJpdmF0ZSBTdHJpbmcgICAgICBlbmNvZGluZzsKLSAgICBwcml2YXRlIFN0cmluZyAgICAgIHZlcnNpb247Ci0KLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdCBhIG5ldywgZW1wdHkgTG9jYXRvcjJJbXBsIG9iamVjdC4KLSAgICAgKiBUaGlzIHdpbGwgbm90IG5vcm1hbGx5IGJlIHVzZWZ1bCwgc2luY2UgdGhlIG1haW4gcHVycG9zZQotICAgICAqIG9mIHRoaXMgY2xhc3MgaXMgdG8gbWFrZSBhIHNuYXBzaG90IG9mIGFuIGV4aXN0aW5nIExvY2F0b3IuCi0gICAgICovCi0gICAgcHVibGljIExvY2F0b3IySW1wbCAoKSB7IH0KLQotICAgIC8qKgotICAgICAqIENvcHkgYW4gZXhpc3RpbmcgTG9jYXRvciBvciBMb2NhdG9yMiBvYmplY3QuCi0gICAgICogSWYgdGhlIG9iamVjdCBpbXBsZW1lbnRzIExvY2F0b3IyLCB2YWx1ZXMgb2YgdGhlCi0gICAgICogPGVtPmVuY29kaW5nPC9lbT4gYW5kIDxlbT52ZXJzaW9uPC9lbT5zdHJpbmdzIGFyZSBjb3BpZWQsCi0gICAgICogb3RoZXJ3aXNlIHRoZXkgc2V0IHRvIDxlbT5udWxsPC9lbT4uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbG9jYXRvciBUaGUgZXhpc3RpbmcgTG9jYXRvciBvYmplY3QuCi0gICAgICovCi0gICAgcHVibGljIExvY2F0b3IySW1wbCAoTG9jYXRvciBsb2NhdG9yKQotICAgIHsKLSAgICAgICAgc3VwZXIgKGxvY2F0b3IpOwotICAgICAgICBpZiAobG9jYXRvciBpbnN0YW5jZW9mIExvY2F0b3IyKSB7Ci0gICAgICAgICAgICBMb2NhdG9yMiAgICBsMiA9IChMb2NhdG9yMikgbG9jYXRvcjsKLQotICAgICAgICAgICAgdmVyc2lvbiA9IGwyLmdldFhNTFZlcnNpb24gKCk7Ci0gICAgICAgICAgICBlbmNvZGluZyA9IGwyLmdldEVuY29kaW5nICgpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLSAgICAvLyBMb2NhdG9yMiBtZXRob2QgaW1wbGVtZW50YXRpb25zCi0gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIGN1cnJlbnQgdmFsdWUgb2YgdGhlIHZlcnNpb24gcHJvcGVydHkuCi0gICAgICoKLSAgICAgKiBAc2VlICNzZXRYTUxWZXJzaW9uCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRYTUxWZXJzaW9uICgpCi0gICAgICAgIHsgcmV0dXJuIHZlcnNpb247IH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIGN1cnJlbnQgdmFsdWUgb2YgdGhlIGVuY29kaW5nIHByb3BlcnR5LgotICAgICAqCi0gICAgICogQHNlZSAjc2V0RW5jb2RpbmcKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldEVuY29kaW5nICgpCi0gICAgICAgIHsgcmV0dXJuIGVuY29kaW5nOyB9Ci0KLQotICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0gICAgLy8gU2V0dGVycwotICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0KLSAgICAvKioKLSAgICAgKiBBc3NpZ25zIHRoZSBjdXJyZW50IHZhbHVlIG9mIHRoZSB2ZXJzaW9uIHByb3BlcnR5LgotICAgICAqCi0gICAgICogQHBhcmFtIHZlcnNpb24gdGhlIG5ldyAidmVyc2lvbiIgdmFsdWUKLSAgICAgKiBAc2VlICNnZXRYTUxWZXJzaW9uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0WE1MVmVyc2lvbiAoU3RyaW5nIHZlcnNpb24pCi0gICAgICAgIHsgdGhpcy52ZXJzaW9uID0gdmVyc2lvbjsgfQotCi0gICAgLyoqCi0gICAgICogQXNzaWducyB0aGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgZW5jb2RpbmcgcHJvcGVydHkuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZW5jb2RpbmcgdGhlIG5ldyAiZW5jb2RpbmciIHZhbHVlCi0gICAgICogQHNlZSAjZ2V0RW5jb2RpbmcKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRFbmNvZGluZyAoU3RyaW5nIGVuY29kaW5nKQotICAgICAgICB7IHRoaXMuZW5jb2RpbmcgPSBlbmNvZGluZzsgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy94bWwvc2F4L2V4dC9wYWNrYWdlLmh0bWwgYi9zcmMvb3JnL3htbC9zYXgvZXh0L3BhY2thZ2UuaHRtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNzRkNjNhNS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3htbC9zYXgvZXh0L3BhY2thZ2UuaHRtbAorKysgL2Rldi9udWxsCkBAIC0xLDQ2ICswLDAgQEAKLTxIVE1MPjxIRUFEPgotPCEtLSAkSWQ6IHBhY2thZ2UuaHRtbCx2IDEuMyAyMDA3LzEwLzAyIDE5OjMyOjI0IG5kdyBFeHAgJCAtLT4KLTwvSEVBRD48Qk9EWT4KLQotPHA+Ci1UaGlzIHBhY2thZ2UgY29udGFpbnMgaW50ZXJmYWNlcyB0byBTQVgyIGZhY2lsaXRpZXMgdGhhdAotY29uZm9ybWFudCBTQVggZHJpdmVycyB3b24ndCBuZWNlc3NhcmlseSBzdXBwb3J0LgotCi08cD5TZWUgPGEgdGFyZ2V0PSdfdG9wJyBocmVmPSdodHRwOi8vd3d3LnNheHByb2plY3Qub3JnJz5odHRwOi8vd3d3LnNheHByb2plY3Qub3JnPC9hPgotZm9yIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgU0FYLjwvcD4KLQotPHA+IFRoaXMgcGFja2FnZSBpcyBpbmRlcGVuZGVudCBvZiB0aGUgU0FYMiBjb3JlLCB0aG91Z2ggdGhlIGZ1bmN0aW9uYWxpdHkKLWV4cG9zZWQgZ2VuZXJhbGx5IG5lZWRzIHRvIGJlIGltcGxlbWVudGVkIHdpdGhpbiBhIHBhcnNlciBjb3JlLgotVGhhdCBpbmRlcGVuZGVuY2UgaGFzIHNldmVyYWwgY29uc2VxdWVuY2VzOjwvcD4KLQotPHVsPgotCi08bGk+U0FYMiBkcml2ZXJzIGFyZSA8ZW0+bm90PC9lbT4gcmVxdWlyZWQgdG8gcmVjb2duaXplIHRoZXNlIGhhbmRsZXJzLgotPC9saT4KLQotPGxpPllvdSBjYW5ub3QgYXNzdW1lIHRoYXQgdGhlIGNsYXNzIGZpbGVzIHdpbGwgYmUgcHJlc2VudCBpbiBldmVyeSBTQVgyCi1pbnN0YWxsYXRpb24uPC9saT4KLQotPGxpPlRoaXMgcGFja2FnZSBtYXkgYmUgdXBkYXRlZCBpbmRlcGVuZGVudGx5IG9mIFNBWDIgKGkuZS4gbmV3Ci1oYW5kbGVycyBhbmQgY2xhc3NlcyBtYXkgYmUgYWRkZWQgd2l0aG91dCB1cGRhdGluZyBTQVgyIGl0c2VsZikuPC9saT4KLQotPGxpPlRoZSBuZXcgaGFuZGxlcnMgYXJlIG5vdCBpbXBsZW1lbnRlZCBieSB0aGUgU0FYMgotPGNvZGU+b3JnLnhtbC5zYXguaGVscGVycy5EZWZhdWx0SGFuZGxlcjwvY29kZT4gb3IKLTxjb2RlPm9yZy54bWwuc2F4LmhlbHBlcnMuWE1MRmlsdGVySW1wbDwvY29kZT4gY2xhc3Nlcy4KLVlvdSBjYW4gc3ViY2xhc3MgdGhlc2UgaWYgeW91IG5lZWQgc3VjaCBiZWhhdmlvciwgb3IKLXVzZSB0aGUgaGVscGVyIGNsYXNzZXMgZm91bmQgaGVyZS48L2xpPgotCi08bGk+VGhlIGhhbmRsZXJzIG5lZWQgdG8gYmUgcmVnaXN0ZXJlZCBkaWZmZXJlbnRseSB0aGFuIGNvcmUgU0FYMgotaGFuZGxlcnMuPC9saT4KLQotPC91bD4KLQotPHA+VGhpcyBwYWNrYWdlLCBTQVgyLWV4dCwgaXMgYSBzdGFuZGFyZGl6ZWQgZXh0ZW5zaW9uIHRvIFNBWDIuICBJdCBpcwotZGVzaWduZWQgYm90aCB0byBhbGxvdyBTQVggcGFyc2VycyB0byBwYXNzIGNlcnRhaW4gdHlwZXMgb2YgaW5mb3JtYXRpb24KLXRvIGFwcGxpY2F0aW9ucywgYW5kIHRvIHNlcnZlIGFzIGEgc2ltcGxlIG1vZGVsIGZvciBvdGhlciBTQVgyIHBhcnNlcgotZXh0ZW5zaW9uIHBhY2thZ2VzLiAgTm90IGFsbCBzdWNoIGV4dGVuc2lvbiBwYWNrYWdlcyBzaG91bGQgbmVlZCB0bwotYmUgcmVjb2duaXplZCBkaXJlY3RseSBieSBwYXJzZXJzLCBob3dldmVyLgotQXMgYW4gZXhhbXBsZSwgbW9zdCB2YWxpZGF0aW9uIHN5c3RlbXMgY2FuIGJlIGNsZWFubHkgbGF5ZXJlZCBvbiB0b3AKLW9mIHBhcnNlcnMgc3VwcG9ydGluZyB0aGUgc3RhbmRhcmRpemVkIFNBWDIgaW50ZXJmYWNlcy4gIDwvcD4KLQotPC9CT0RZPjwvSFRNTD4KZGlmZiAtLWdpdCBhL3NyYy9vcmcveG1sL3NheC9oZWxwZXJzL0F0dHJpYnV0ZUxpc3RJbXBsLmphdmEgYi9zcmMvb3JnL3htbC9zYXgvaGVscGVycy9BdHRyaWJ1dGVMaXN0SW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA5M2MxMTFlLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcveG1sL3NheC9oZWxwZXJzL0F0dHJpYnV0ZUxpc3RJbXBsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzMzYgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwMCwgMjAwNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLy8gU0FYIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gZm9yIEF0dHJpYnV0ZUxpc3QuCi0vLyBodHRwOi8vd3d3LnNheHByb2plY3Qub3JnCi0vLyBObyB3YXJyYW50eTsgbm8gY29weXJpZ2h0IC0tIHVzZSB0aGlzIGFzIHlvdSB3aWxsLgotLy8gJElkOiBBdHRyaWJ1dGVMaXN0SW1wbC5qYXZhLHYgMS4yIDIwMDQvMTEvMDMgMjI6NTM6MDgganN1dHRvciBFeHAgJAotCi1wYWNrYWdlIG9yZy54bWwuc2F4LmhlbHBlcnM7Ci0KLWltcG9ydCBvcmcueG1sLnNheC5BdHRyaWJ1dGVMaXN0OwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotCi0vKioKLSAqIERlZmF1bHQgaW1wbGVtZW50YXRpb24gZm9yIEF0dHJpYnV0ZUxpc3QuCi0gKgotICogPGJsb2NrcXVvdGU+Ci0gKiA8ZW0+VGhpcyBtb2R1bGUsIGJvdGggc291cmNlIGNvZGUgYW5kIGRvY3VtZW50YXRpb24sIGlzIGluIHRoZQotICogUHVibGljIERvbWFpbiwgYW5kIGNvbWVzIHdpdGggPHN0cm9uZz5OTyBXQVJSQU5UWTwvc3Ryb25nPi48L2VtPgotICogU2VlIDxhIGhyZWY9J2h0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmcnPmh0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmc8L2E+Ci0gKiBmb3IgZnVydGhlciBpbmZvcm1hdGlvbi4KLSAqIDwvYmxvY2txdW90ZT4KLSAqCi0gKiA8cD5BdHRyaWJ1dGVMaXN0IGltcGxlbWVudHMgdGhlIGRlcHJlY2F0ZWQgU0FYMSB7QGxpbmsKLSAqIG9yZy54bWwuc2F4LkF0dHJpYnV0ZUxpc3QgQXR0cmlidXRlTGlzdH0gaW50ZXJmYWNlLCBhbmQgaGFzIGJlZW4KLSAqIHJlcGxhY2VkIGJ5IHRoZSBuZXcgU0FYMiB7QGxpbmsgb3JnLnhtbC5zYXguaGVscGVycy5BdHRyaWJ1dGVzSW1wbAotICogQXR0cmlidXRlc0ltcGx9IGludGVyZmFjZS48L3A+Ci0gKgotICogPHA+VGhpcyBjbGFzcyBwcm92aWRlcyBhIGNvbnZlbmllbmNlIGltcGxlbWVudGF0aW9uIG9mIHRoZSBTQVgKLSAqIHtAbGluayBvcmcueG1sLnNheC5BdHRyaWJ1dGVMaXN0IEF0dHJpYnV0ZUxpc3R9IGludGVyZmFjZS4gIFRoaXMKLSAqIGltcGxlbWVudGF0aW9uIGlzIHVzZWZ1bCBib3RoIGZvciBTQVggcGFyc2VyIHdyaXRlcnMsIHdobyBjYW4gdXNlCi0gKiBpdCB0byBwcm92aWRlIGF0dHJpYnV0ZXMgdG8gdGhlIGFwcGxpY2F0aW9uLCBhbmQgZm9yIFNBWCBhcHBsaWNhdGlvbgotICogd3JpdGVycywgd2hvIGNhbiB1c2UgaXQgdG8gY3JlYXRlIGEgcGVyc2lzdGVudCBjb3B5IG9mIGFuIGVsZW1lbnQncwotICogYXR0cmlidXRlIHNwZWNpZmljYXRpb25zOjwvcD4KLSAqCi0gKiA8cHJlPgotICogcHJpdmF0ZSBBdHRyaWJ1dGVMaXN0IG15YXR0czsKLSAqCi0gKiBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQgKFN0cmluZyBuYW1lLCBBdHRyaWJ1dGVMaXN0IGF0dHMpCi0gKiB7Ci0gKiAgICAgICAgICAgICAgLy8gY3JlYXRlIGEgcGVyc2lzdGVudCBjb3B5IG9mIHRoZSBhdHRyaWJ1dGUgbGlzdAotICogICAgICAgICAgICAgIC8vIGZvciB1c2Ugb3V0c2lkZSB0aGlzIG1ldGhvZAotICogICBteWF0dHMgPSBuZXcgQXR0cmlidXRlTGlzdEltcGwoYXR0cyk7Ci0gKiAgIFsuLi5dCi0gKiB9Ci0gKiA8L3ByZT4KLSAqCi0gKiA8cD5QbGVhc2Ugbm90ZSB0aGF0IFNBWCBwYXJzZXJzIGFyZSBub3QgcmVxdWlyZWQgdG8gdXNlIHRoaXMKLSAqIGNsYXNzIHRvIHByb3ZpZGUgYW4gaW1wbGVtZW50YXRpb24gb2YgQXR0cmlidXRlTGlzdDsgaXQgaXMKLSAqIHN1cHBsaWVkIG9ubHkgYXMgYW4gb3B0aW9uYWwgY29udmVuaWVuY2UuICBJbiBwYXJ0aWN1bGFyLAotICogcGFyc2VyIHdyaXRlcnMgYXJlIGVuY291cmFnZWQgdG8gaW52ZW50IG1vcmUgZWZmaWNpZW50Ci0gKiBpbXBsZW1lbnRhdGlvbnMuPC9wPgotICoKLSAqIEBkZXByZWNhdGVkIFRoaXMgY2xhc3MgaW1wbGVtZW50cyBhIGRlcHJlY2F0ZWQgaW50ZXJmYWNlLAotICogICAgICAgICAgICAge0BsaW5rIG9yZy54bWwuc2F4LkF0dHJpYnV0ZUxpc3QgQXR0cmlidXRlTGlzdH07Ci0gKiAgICAgICAgICAgICB0aGF0IGludGVyZmFjZSBoYXMgYmVlbiByZXBsYWNlZCBieQotICogICAgICAgICAgICAge0BsaW5rIG9yZy54bWwuc2F4LkF0dHJpYnV0ZXMgQXR0cmlidXRlc30sCi0gKiAgICAgICAgICAgICB3aGljaCBpcyBpbXBsZW1lbnRlZCBpbiB0aGUKLSAqICAgICAgICAgICAgIHtAbGluayBvcmcueG1sLnNheC5oZWxwZXJzLkF0dHJpYnV0ZXNJbXBsCi0gKiAgICAgICAgICAgIEF0dHJpYnV0ZXNJbXBsfSBoZWxwZXIgY2xhc3MuCi0gKiBAc2luY2UgU0FYIDEuMAotICogQGF1dGhvciBEYXZpZCBNZWdnaW5zb24KLSAqIEBzZWUgb3JnLnhtbC5zYXguQXR0cmlidXRlTGlzdAotICogQHNlZSBvcmcueG1sLnNheC5Eb2N1bWVudEhhbmRsZXIjc3RhcnRFbGVtZW50Ci0gKi8KLXB1YmxpYyBjbGFzcyBBdHRyaWJ1dGVMaXN0SW1wbCBpbXBsZW1lbnRzIEF0dHJpYnV0ZUxpc3QKLXsKLQotICAgIC8qKgotICAgICAqIENyZWF0ZSBhbiBlbXB0eSBhdHRyaWJ1dGUgbGlzdC4KLSAgICAgKgotICAgICAqIDxwPlRoaXMgY29uc3RydWN0b3IgaXMgbW9zdCB1c2VmdWwgZm9yIHBhcnNlciB3cml0ZXJzLCB3aG8KLSAgICAgKiB3aWxsIHVzZSBpdCB0byBjcmVhdGUgYSBzaW5nbGUsIHJldXNhYmxlIGF0dHJpYnV0ZSBsaXN0IHRoYXQKLSAgICAgKiBjYW4gYmUgcmVzZXQgd2l0aCB0aGUgY2xlYXIgbWV0aG9kIGJldHdlZW4gZWxlbWVudHMuPC9wPgotICAgICAqCi0gICAgICogQHNlZSAjYWRkQXR0cmlidXRlCi0gICAgICogQHNlZSAjY2xlYXIKLSAgICAgKi8KLSAgICBwdWJsaWMgQXR0cmlidXRlTGlzdEltcGwgKCkKLSAgICB7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3QgYSBwZXJzaXN0ZW50IGNvcHkgb2YgYW4gZXhpc3RpbmcgYXR0cmlidXRlIGxpc3QuCi0gICAgICoKLSAgICAgKiA8cD5UaGlzIGNvbnN0cnVjdG9yIGlzIG1vc3QgdXNlZnVsIGZvciBhcHBsaWNhdGlvbiB3cml0ZXJzLAotICAgICAqIHdobyB3aWxsIHVzZSBpdCB0byBjcmVhdGUgYSBwZXJzaXN0ZW50IGNvcHkgb2YgYW4gZXhpc3RpbmcKLSAgICAgKiBhdHRyaWJ1dGUgbGlzdC48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gYXR0cyBUaGUgYXR0cmlidXRlIGxpc3QgdG8gY29weQotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguRG9jdW1lbnRIYW5kbGVyI3N0YXJ0RWxlbWVudAotICAgICAqLwotICAgIHB1YmxpYyBBdHRyaWJ1dGVMaXN0SW1wbCAoQXR0cmlidXRlTGlzdCBhdHRzKQotICAgIHsKLSAgICAgICAgc2V0QXR0cmlidXRlTGlzdChhdHRzKTsKLSAgICB9Ci0KLQotCi0gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLSAgICAvLyBNZXRob2RzIHNwZWNpZmljIHRvIHRoaXMgY2xhc3MuCi0gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLQotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSBhdHRyaWJ1dGUgbGlzdCwgZGlzY2FyZGluZyBwcmV2aW91cyBjb250ZW50cy4KLSAgICAgKgotICAgICAqIDxwPlRoaXMgbWV0aG9kIGFsbG93cyBhbiBhcHBsaWNhdGlvbiB3cml0ZXIgdG8gcmV1c2UgYW4KLSAgICAgKiBhdHRyaWJ1dGUgbGlzdCBlYXNpbHkuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGF0dHMgVGhlIGF0dHJpYnV0ZSBsaXN0IHRvIGNvcHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0QXR0cmlidXRlTGlzdCAoQXR0cmlidXRlTGlzdCBhdHRzKQotICAgIHsKLSAgICAgICAgaW50IGNvdW50ID0gYXR0cy5nZXRMZW5ndGgoKTsKLQotICAgICAgICBjbGVhcigpOwotCi0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykgewotICAgICAgICAgICAgYWRkQXR0cmlidXRlKGF0dHMuZ2V0TmFtZShpKSwgYXR0cy5nZXRUeXBlKGkpLCBhdHRzLmdldFZhbHVlKGkpKTsKLSAgICAgICAgfQotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogQWRkIGFuIGF0dHJpYnV0ZSB0byBhbiBhdHRyaWJ1dGUgbGlzdC4KLSAgICAgKgotICAgICAqIDxwPlRoaXMgbWV0aG9kIGlzIHByb3ZpZGVkIGZvciBTQVggcGFyc2VyIHdyaXRlcnMsIHRvIGFsbG93IHRoZW0KLSAgICAgKiB0byBidWlsZCB1cCBhbiBhdHRyaWJ1dGUgbGlzdCBpbmNyZW1lbnRhbGx5IGJlZm9yZSBkZWxpdmVyaW5nCi0gICAgICogaXQgdG8gdGhlIGFwcGxpY2F0aW9uLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBhdHRyaWJ1dGUgbmFtZS4KLSAgICAgKiBAcGFyYW0gdHlwZSBUaGUgYXR0cmlidXRlIHR5cGUgKCJOTVRPS0VOIiBmb3IgYW4gZW51bWVyYXRpb24pLgotICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYXR0cmlidXRlIHZhbHVlIChtdXN0IG5vdCBiZSBudWxsKS4KLSAgICAgKiBAc2VlICNyZW1vdmVBdHRyaWJ1dGUKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkRvY3VtZW50SGFuZGxlciNzdGFydEVsZW1lbnQKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBhZGRBdHRyaWJ1dGUgKFN0cmluZyBuYW1lLCBTdHJpbmcgdHlwZSwgU3RyaW5nIHZhbHVlKQotICAgIHsKLSAgICAgICAgbmFtZXMuYWRkRWxlbWVudChuYW1lKTsKLSAgICAgICAgdHlwZXMuYWRkRWxlbWVudCh0eXBlKTsKLSAgICAgICAgdmFsdWVzLmFkZEVsZW1lbnQodmFsdWUpOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogUmVtb3ZlIGFuIGF0dHJpYnV0ZSBmcm9tIHRoZSBsaXN0LgotICAgICAqCi0gICAgICogPHA+U0FYIGFwcGxpY2F0aW9uIHdyaXRlcnMgY2FuIHVzZSB0aGlzIG1ldGhvZCB0byBmaWx0ZXIgYW4KLSAgICAgKiBhdHRyaWJ1dGUgb3V0IG9mIGFuIEF0dHJpYnV0ZUxpc3QuICBOb3RlIHRoYXQgaW52b2tpbmcgdGhpcwotICAgICAqIG1ldGhvZCB3aWxsIGNoYW5nZSB0aGUgbGVuZ3RoIG9mIHRoZSBhdHRyaWJ1dGUgbGlzdCBhbmQKLSAgICAgKiBzb21lIG9mIHRoZSBhdHRyaWJ1dGUncyBpbmRpY2VzLjwvcD4KLSAgICAgKgotICAgICAqIDxwPklmIHRoZSByZXF1ZXN0ZWQgYXR0cmlidXRlIGlzIG5vdCBpbiB0aGUgbGlzdCwgdGhpcyBpcwotICAgICAqIGEgbm8tb3AuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgVGhlIGF0dHJpYnV0ZSBuYW1lLgotICAgICAqIEBzZWUgI2FkZEF0dHJpYnV0ZQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHJlbW92ZUF0dHJpYnV0ZSAoU3RyaW5nIG5hbWUpCi0gICAgewotICAgICAgICBpbnQgaSA9IG5hbWVzLmluZGV4T2YobmFtZSk7Ci0KLSAgICAgICAgaWYgKGkgPj0gMCkgewotICAgICAgICAgICAgbmFtZXMucmVtb3ZlRWxlbWVudEF0KGkpOwotICAgICAgICAgICAgdHlwZXMucmVtb3ZlRWxlbWVudEF0KGkpOwotICAgICAgICAgICAgdmFsdWVzLnJlbW92ZUVsZW1lbnRBdChpKTsKLSAgICAgICAgfQotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogQ2xlYXIgdGhlIGF0dHJpYnV0ZSBsaXN0LgotICAgICAqCi0gICAgICogPHA+U0FYIHBhcnNlciB3cml0ZXJzIGNhbiB1c2UgdGhpcyBtZXRob2QgdG8gcmVzZXQgdGhlIGF0dHJpYnV0ZQotICAgICAqIGxpc3QgYmV0d2VlbiBEb2N1bWVudEhhbmRsZXIuc3RhcnRFbGVtZW50IGV2ZW50cy4gIE5vcm1hbGx5LAotICAgICAqIGl0IHdpbGwgbWFrZSBzZW5zZSB0byByZXVzZSB0aGUgc2FtZSBBdHRyaWJ1dGVMaXN0SW1wbCBvYmplY3QKLSAgICAgKiByYXRoZXIgdGhhbiBhbGxvY2F0aW5nIGEgbmV3IG9uZSBlYWNoIHRpbWUuPC9wPgotICAgICAqCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5Eb2N1bWVudEhhbmRsZXIjc3RhcnRFbGVtZW50Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgY2xlYXIgKCkKLSAgICB7Ci0gICAgICAgIG5hbWVzLnJlbW92ZUFsbEVsZW1lbnRzKCk7Ci0gICAgICAgIHR5cGVzLnJlbW92ZUFsbEVsZW1lbnRzKCk7Ci0gICAgICAgIHZhbHVlcy5yZW1vdmVBbGxFbGVtZW50cygpOwotICAgIH0KLQotCi0KLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotICAgIC8vIEltcGxlbWVudGF0aW9uIG9mIG9yZy54bWwuc2F4LkF0dHJpYnV0ZUxpc3QKLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIG51bWJlciBvZiBhdHRyaWJ1dGVzIGluIHRoZSBsaXN0LgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgbnVtYmVyIG9mIGF0dHJpYnV0ZXMgaW4gdGhlIGxpc3QuCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5BdHRyaWJ1dGVMaXN0I2dldExlbmd0aAotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0TGVuZ3RoICgpCi0gICAgewotICAgICAgICByZXR1cm4gbmFtZXMuc2l6ZSgpOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBuYW1lIG9mIGFuIGF0dHJpYnV0ZSAoYnkgcG9zaXRpb24pLgotICAgICAqCi0gICAgICogQHBhcmFtIGkgVGhlIHBvc2l0aW9uIG9mIHRoZSBhdHRyaWJ1dGUgaW4gdGhlIGxpc3QuCi0gICAgICogQHJldHVybiBUaGUgYXR0cmlidXRlIG5hbWUgYXMgYSBzdHJpbmcsIG9yIG51bGwgaWYgdGhlcmUKLSAgICAgKiAgICAgICAgIGlzIG5vIGF0dHJpYnV0ZSBhdCB0aGF0IHBvc2l0aW9uLgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQXR0cmlidXRlTGlzdCNnZXROYW1lKGludCkKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUgKGludCBpKQotICAgIHsKLSAgICAgICAgaWYgKGkgPCAwKSB7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotICAgICAgICB0cnkgewotICAgICAgICAgICAgcmV0dXJuIChTdHJpbmcpbmFtZXMuZWxlbWVudEF0KGkpOwotICAgICAgICB9IGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgdHlwZSBvZiBhbiBhdHRyaWJ1dGUgKGJ5IHBvc2l0aW9uKS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBpIFRoZSBwb3NpdGlvbiBvZiB0aGUgYXR0cmlidXRlIGluIHRoZSBsaXN0LgotICAgICAqIEByZXR1cm4gVGhlIGF0dHJpYnV0ZSB0eXBlIGFzIGEgc3RyaW5nICgiTk1UT0tFTiIgZm9yIGFuCi0gICAgICogICAgICAgICBlbnVtZXJhdGlvbiwgYW5kICJDREFUQSIgaWYgbm8gZGVjbGFyYXRpb24gd2FzCi0gICAgICogICAgICAgICByZWFkKSwgb3IgbnVsbCBpZiB0aGVyZSBpcyBubyBhdHRyaWJ1dGUgYXQKLSAgICAgKiAgICAgICAgIHRoYXQgcG9zaXRpb24uCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5BdHRyaWJ1dGVMaXN0I2dldFR5cGUoaW50KQotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VHlwZSAoaW50IGkpCi0gICAgewotICAgICAgICBpZiAoaSA8IDApIHsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICByZXR1cm4gKFN0cmluZyl0eXBlcy5lbGVtZW50QXQoaSk7Ci0gICAgICAgIH0gY2F0Y2ggKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSB2YWx1ZSBvZiBhbiBhdHRyaWJ1dGUgKGJ5IHBvc2l0aW9uKS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBpIFRoZSBwb3NpdGlvbiBvZiB0aGUgYXR0cmlidXRlIGluIHRoZSBsaXN0LgotICAgICAqIEByZXR1cm4gVGhlIGF0dHJpYnV0ZSB2YWx1ZSBhcyBhIHN0cmluZywgb3IgbnVsbCBpZgotICAgICAqICAgICAgICAgdGhlcmUgaXMgbm8gYXR0cmlidXRlIGF0IHRoYXQgcG9zaXRpb24uCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5BdHRyaWJ1dGVMaXN0I2dldFZhbHVlKGludCkKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFZhbHVlIChpbnQgaSkKLSAgICB7Ci0gICAgICAgIGlmIChpIDwgMCkgewotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIHJldHVybiAoU3RyaW5nKXZhbHVlcy5lbGVtZW50QXQoaSk7Ci0gICAgICAgIH0gY2F0Y2ggKEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSB0eXBlIG9mIGFuIGF0dHJpYnV0ZSAoYnkgbmFtZSkuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgYXR0cmlidXRlIG5hbWUuCi0gICAgICogQHJldHVybiBUaGUgYXR0cmlidXRlIHR5cGUgYXMgYSBzdHJpbmcgKCJOTVRPS0VOIiBmb3IgYW4KLSAgICAgKiAgICAgICAgIGVudW1lcmF0aW9uLCBhbmQgIkNEQVRBIiBpZiBubyBkZWNsYXJhdGlvbiB3YXMKLSAgICAgKiAgICAgICAgIHJlYWQpLgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQXR0cmlidXRlTGlzdCNnZXRUeXBlKGphdmEubGFuZy5TdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRUeXBlIChTdHJpbmcgbmFtZSkKLSAgICB7Ci0gICAgICAgIHJldHVybiBnZXRUeXBlKG5hbWVzLmluZGV4T2YobmFtZSkpOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSB2YWx1ZSBvZiBhbiBhdHRyaWJ1dGUgKGJ5IG5hbWUpLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgVGhlIGF0dHJpYnV0ZSBuYW1lLgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQXR0cmlidXRlTGlzdCNnZXRWYWx1ZShqYXZhLmxhbmcuU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VmFsdWUgKFN0cmluZyBuYW1lKQotICAgIHsKLSAgICAgICAgcmV0dXJuIGdldFZhbHVlKG5hbWVzLmluZGV4T2YobmFtZSkpOwotICAgIH0KLQotCi0KLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotICAgIC8vIEludGVybmFsIHN0YXRlLgotICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0KLSAgICBWZWN0b3IgbmFtZXMgPSBuZXcgVmVjdG9yKCk7Ci0gICAgVmVjdG9yIHR5cGVzID0gbmV3IFZlY3RvcigpOwotICAgIFZlY3RvciB2YWx1ZXMgPSBuZXcgVmVjdG9yKCk7Ci0KLX0KLQotLy8gZW5kIG9mIEF0dHJpYnV0ZUxpc3RJbXBsLmphdmEKZGlmZiAtLWdpdCBhL3NyYy9vcmcveG1sL3NheC9oZWxwZXJzL0F0dHJpYnV0ZXNJbXBsLmphdmEgYi9zcmMvb3JnL3htbC9zYXgvaGVscGVycy9BdHRyaWJ1dGVzSW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmYzVlOTUzLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcveG1sL3NheC9oZWxwZXJzL0F0dHJpYnV0ZXNJbXBsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw2NDEgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwMCwgMjAwNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLy8gQXR0cmlidXRlc0ltcGwuamF2YSAtIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gb2YgQXR0cmlidXRlcy4KLS8vIGh0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmcKLS8vIFdyaXR0ZW4gYnkgRGF2aWQgTWVnZ2luc29uCi0vLyBOTyBXQVJSQU5UWSEgIFRoaXMgY2xhc3MgaXMgaW4gdGhlIHB1YmxpYyBkb21haW4uCi0vLyAkSWQ6IEF0dHJpYnV0ZXNJbXBsLmphdmEsdiAxLjIgMjAwNC8xMS8wMyAyMjo1MzowOCBqc3V0dG9yIEV4cCAkCi0KLXBhY2thZ2Ugb3JnLnhtbC5zYXguaGVscGVyczsKLQotaW1wb3J0IG9yZy54bWwuc2F4LkF0dHJpYnV0ZXM7Ci0KLQotLyoqCi0gKiBEZWZhdWx0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBBdHRyaWJ1dGVzIGludGVyZmFjZS4KLSAqCi0gKiA8YmxvY2txdW90ZT4KLSAqIDxlbT5UaGlzIG1vZHVsZSwgYm90aCBzb3VyY2UgY29kZSBhbmQgZG9jdW1lbnRhdGlvbiwgaXMgaW4gdGhlCi0gKiBQdWJsaWMgRG9tYWluLCBhbmQgY29tZXMgd2l0aCA8c3Ryb25nPk5PIFdBUlJBTlRZPC9zdHJvbmc+LjwvZW0+Ci0gKiBTZWUgPGEgaHJlZj0naHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZyc+aHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZzwvYT4KLSAqIGZvciBmdXJ0aGVyIGluZm9ybWF0aW9uLgotICogPC9ibG9ja3F1b3RlPgotICoKLSAqIDxwPlRoaXMgY2xhc3MgcHJvdmlkZXMgYSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBTQVgyCi0gKiB7QGxpbmsgb3JnLnhtbC5zYXguQXR0cmlidXRlcyBBdHRyaWJ1dGVzfSBpbnRlcmZhY2UsIHdpdGggdGhlCi0gKiBhZGRpdGlvbiBvZiBtYW5pcHVsYXRvcnMgc28gdGhhdCB0aGUgbGlzdCBjYW4gYmUgbW9kaWZpZWQgb3IKLSAqIHJldXNlZC48L3A+Ci0gKgotICogPHA+VGhlcmUgYXJlIHR3byB0eXBpY2FsIHVzZXMgb2YgdGhpcyBjbGFzczo8L3A+Ci0gKgotICogPG9sPgotICogPGxpPnRvIHRha2UgYSBwZXJzaXN0ZW50IHNuYXBzaG90IG9mIGFuIEF0dHJpYnV0ZXMgb2JqZWN0Ci0gKiAgaW4gYSB7QGxpbmsgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjc3RhcnRFbGVtZW50IHN0YXJ0RWxlbWVudH0gZXZlbnQ7IG9yPC9saT4KLSAqIDxsaT50byBjb25zdHJ1Y3Qgb3IgbW9kaWZ5IGFuIEF0dHJpYnV0ZXMgb2JqZWN0IGluIGEgU0FYMiBkcml2ZXIgb3IgZmlsdGVyLjwvbGk+Ci0gKiA8L29sPgotICoKLSAqIDxwPlRoaXMgY2xhc3MgcmVwbGFjZXMgdGhlIG5vdy1kZXByZWNhdGVkIFNBWDEge0BsaW5rCi0gKiBvcmcueG1sLnNheC5oZWxwZXJzLkF0dHJpYnV0ZUxpc3RJbXBsIEF0dHJpYnV0ZUxpc3RJbXBsfQotICogY2xhc3M7IGluIGFkZGl0aW9uIHRvIHN1cHBvcnRpbmcgdGhlIHVwZGF0ZWQgQXR0cmlidXRlcwotICogaW50ZXJmYWNlIHJhdGhlciB0aGFuIHRoZSBkZXByZWNhdGVkIHtAbGluayBvcmcueG1sLnNheC5BdHRyaWJ1dGVMaXN0Ci0gKiBBdHRyaWJ1dGVMaXN0fSBpbnRlcmZhY2UsIGl0IGFsc28gaW5jbHVkZXMgYSBtdWNoIG1vcmUgZWZmaWNpZW50Ci0gKiBpbXBsZW1lbnRhdGlvbiB1c2luZyBhIHNpbmdsZSBhcnJheSByYXRoZXIgdGhhbiBhIHNldCBvZiBWZWN0b3JzLjwvcD4KLSAqCi0gKiBAc2luY2UgU0FYIDIuMAotICogQGF1dGhvciBEYXZpZCBNZWdnaW5zb24KLSAqLwotcHVibGljIGNsYXNzIEF0dHJpYnV0ZXNJbXBsIGltcGxlbWVudHMgQXR0cmlidXRlcwotewotCi0KLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotICAgIC8vIENvbnN0cnVjdG9ycy4KLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotCi0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3QgYSBuZXcsIGVtcHR5IEF0dHJpYnV0ZXNJbXBsIG9iamVjdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgQXR0cmlidXRlc0ltcGwgKCkKLSAgICB7Ci0gICAgICAgIGxlbmd0aCA9IDA7Ci0gICAgICAgIGRhdGEgPSBudWxsOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogQ29weSBhbiBleGlzdGluZyBBdHRyaWJ1dGVzIG9iamVjdC4KLSAgICAgKgotICAgICAqIDxwPlRoaXMgY29uc3RydWN0b3IgaXMgZXNwZWNpYWxseSB1c2VmdWwgaW5zaWRlIGEKLSAgICAgKiB7QGxpbmsgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjc3RhcnRFbGVtZW50IHN0YXJ0RWxlbWVudH0gZXZlbnQuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGF0dHMgVGhlIGV4aXN0aW5nIEF0dHJpYnV0ZXMgb2JqZWN0LgotICAgICAqLwotICAgIHB1YmxpYyBBdHRyaWJ1dGVzSW1wbCAoQXR0cmlidXRlcyBhdHRzKQotICAgIHsKLSAgICAgICAgc2V0QXR0cmlidXRlcyhhdHRzKTsKLSAgICB9Ci0KLQotCi0gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLSAgICAvLyBJbXBsZW1lbnRhdGlvbiBvZiBvcmcueG1sLnNheC5BdHRyaWJ1dGVzLgotICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0KLQotICAgIC8qKgotICAgICAqIFJldHVybiB0aGUgbnVtYmVyIG9mIGF0dHJpYnV0ZXMgaW4gdGhlIGxpc3QuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBudW1iZXIgb2YgYXR0cmlidXRlcyBpbiB0aGUgbGlzdC4KLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkF0dHJpYnV0ZXMjZ2V0TGVuZ3RoCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRMZW5ndGggKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBsZW5ndGg7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gYW4gYXR0cmlidXRlJ3MgTmFtZXNwYWNlIFVSSS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBpbmRleCBUaGUgYXR0cmlidXRlJ3MgaW5kZXggKHplcm8tYmFzZWQpLgotICAgICAqIEByZXR1cm4gVGhlIE5hbWVzcGFjZSBVUkksIHRoZSBlbXB0eSBzdHJpbmcgaWYgbm9uZSBpcwotICAgICAqICAgICAgICAgYXZhaWxhYmxlLCBvciBudWxsIGlmIHRoZSBpbmRleCBpcyBvdXQgb2YgcmFuZ2UuCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5BdHRyaWJ1dGVzI2dldFVSSQotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VVJJIChpbnQgaW5kZXgpCi0gICAgewotICAgICAgICBpZiAoaW5kZXggPj0gMCAmJiBpbmRleCA8IGxlbmd0aCkgewotICAgICAgICAgICAgcmV0dXJuIGRhdGFbaW5kZXgqNV07Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIGFuIGF0dHJpYnV0ZSdzIGxvY2FsIG5hbWUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGF0dHJpYnV0ZSdzIGluZGV4ICh6ZXJvLWJhc2VkKS4KLSAgICAgKiBAcmV0dXJuIFRoZSBhdHRyaWJ1dGUncyBsb2NhbCBuYW1lLCB0aGUgZW1wdHkgc3RyaW5nIGlmCi0gICAgICogICAgICAgICBub25lIGlzIGF2YWlsYWJsZSwgb3IgbnVsbCBpZiB0aGUgaW5kZXggaWYgb3V0IG9mIHJhbmdlLgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQXR0cmlidXRlcyNnZXRMb2NhbE5hbWUKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldExvY2FsTmFtZSAoaW50IGluZGV4KQotICAgIHsKLSAgICAgICAgaWYgKGluZGV4ID49IDAgJiYgaW5kZXggPCBsZW5ndGgpIHsKLSAgICAgICAgICAgIHJldHVybiBkYXRhW2luZGV4KjUrMV07Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIGFuIGF0dHJpYnV0ZSdzIHF1YWxpZmllZCAocHJlZml4ZWQpIG5hbWUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGF0dHJpYnV0ZSdzIGluZGV4ICh6ZXJvLWJhc2VkKS4KLSAgICAgKiBAcmV0dXJuIFRoZSBhdHRyaWJ1dGUncyBxdWFsaWZpZWQgbmFtZSwgdGhlIGVtcHR5IHN0cmluZyBpZgotICAgICAqICAgICAgICAgbm9uZSBpcyBhdmFpbGFibGUsIG9yIG51bGwgaWYgdGhlIGluZGV4IGlzIG91dCBvZiBib3VuZHMuCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5BdHRyaWJ1dGVzI2dldFFOYW1lCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRRTmFtZSAoaW50IGluZGV4KQotICAgIHsKLSAgICAgICAgaWYgKGluZGV4ID49IDAgJiYgaW5kZXggPCBsZW5ndGgpIHsKLSAgICAgICAgICAgIHJldHVybiBkYXRhW2luZGV4KjUrMl07Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIGFuIGF0dHJpYnV0ZSdzIHR5cGUgYnkgaW5kZXguCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGF0dHJpYnV0ZSdzIGluZGV4ICh6ZXJvLWJhc2VkKS4KLSAgICAgKiBAcmV0dXJuIFRoZSBhdHRyaWJ1dGUncyB0eXBlLCAiQ0RBVEEiIGlmIHRoZSB0eXBlIGlzIHVua25vd24sIG9yIG51bGwKLSAgICAgKiAgICAgICAgIGlmIHRoZSBpbmRleCBpcyBvdXQgb2YgYm91bmRzLgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQXR0cmlidXRlcyNnZXRUeXBlKGludCkKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFR5cGUgKGludCBpbmRleCkKLSAgICB7Ci0gICAgICAgIGlmIChpbmRleCA+PSAwICYmIGluZGV4IDwgbGVuZ3RoKSB7Ci0gICAgICAgICAgICByZXR1cm4gZGF0YVtpbmRleCo1KzNdOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFJldHVybiBhbiBhdHRyaWJ1dGUncyB2YWx1ZSBieSBpbmRleC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBpbmRleCBUaGUgYXR0cmlidXRlJ3MgaW5kZXggKHplcm8tYmFzZWQpLgotICAgICAqIEByZXR1cm4gVGhlIGF0dHJpYnV0ZSdzIHZhbHVlIG9yIG51bGwgaWYgdGhlIGluZGV4IGlzIG91dCBvZiBib3VuZHMuCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5BdHRyaWJ1dGVzI2dldFZhbHVlKGludCkKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFZhbHVlIChpbnQgaW5kZXgpCi0gICAgewotICAgICAgICBpZiAoaW5kZXggPj0gMCAmJiBpbmRleCA8IGxlbmd0aCkgewotICAgICAgICAgICAgcmV0dXJuIGRhdGFbaW5kZXgqNSs0XTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBMb29rIHVwIGFuIGF0dHJpYnV0ZSdzIGluZGV4IGJ5IE5hbWVzcGFjZSBuYW1lLgotICAgICAqCi0gICAgICogPHA+SW4gbWFueSBjYXNlcywgaXQgd2lsbCBiZSBtb3JlIGVmZmljaWVudCB0byBsb29rIHVwIHRoZSBuYW1lIG9uY2UgYW5kCi0gICAgICogdXNlIHRoZSBpbmRleCBxdWVyeSBtZXRob2RzIHJhdGhlciB0aGFuIHVzaW5nIHRoZSBuYW1lIHF1ZXJ5IG1ldGhvZHMKLSAgICAgKiByZXBlYXRlZGx5LjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSB1cmkgVGhlIGF0dHJpYnV0ZSdzIE5hbWVzcGFjZSBVUkksIG9yIHRoZSBlbXB0eQotICAgICAqICAgICAgICBzdHJpbmcgaWYgbm9uZSBpcyBhdmFpbGFibGUuCi0gICAgICogQHBhcmFtIGxvY2FsTmFtZSBUaGUgYXR0cmlidXRlJ3MgbG9jYWwgbmFtZS4KLSAgICAgKiBAcmV0dXJuIFRoZSBhdHRyaWJ1dGUncyBpbmRleCwgb3IgLTEgaWYgbm9uZSBtYXRjaGVzLgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQXR0cmlidXRlcyNnZXRJbmRleChqYXZhLmxhbmcuU3RyaW5nLGphdmEubGFuZy5TdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRJbmRleCAoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSkKLSAgICB7Ci0gICAgICAgIGludCBtYXggPSBsZW5ndGggKiA1OwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1heDsgaSArPSA1KSB7Ci0gICAgICAgICAgICBpZiAoZGF0YVtpXS5lcXVhbHModXJpKSAmJiBkYXRhW2krMV0uZXF1YWxzKGxvY2FsTmFtZSkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gaSAvIDU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIC0xOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogTG9vayB1cCBhbiBhdHRyaWJ1dGUncyBpbmRleCBieSBxdWFsaWZpZWQgKHByZWZpeGVkKSBuYW1lLgotICAgICAqCi0gICAgICogQHBhcmFtIHFOYW1lIFRoZSBxdWFsaWZpZWQgbmFtZS4KLSAgICAgKiBAcmV0dXJuIFRoZSBhdHRyaWJ1dGUncyBpbmRleCwgb3IgLTEgaWYgbm9uZSBtYXRjaGVzLgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQXR0cmlidXRlcyNnZXRJbmRleChqYXZhLmxhbmcuU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0SW5kZXggKFN0cmluZyBxTmFtZSkKLSAgICB7Ci0gICAgICAgIGludCBtYXggPSBsZW5ndGggKiA1OwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1heDsgaSArPSA1KSB7Ci0gICAgICAgICAgICBpZiAoZGF0YVtpKzJdLmVxdWFscyhxTmFtZSkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gaSAvIDU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIC0xOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogTG9vayB1cCBhbiBhdHRyaWJ1dGUncyB0eXBlIGJ5IE5hbWVzcGFjZS1xdWFsaWZpZWQgbmFtZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSB1cmkgVGhlIE5hbWVzcGFjZSBVUkksIG9yIHRoZSBlbXB0eSBzdHJpbmcgZm9yIGEgbmFtZQotICAgICAqICAgICAgICB3aXRoIG5vIGV4cGxpY2l0IE5hbWVzcGFjZSBVUkkuCi0gICAgICogQHBhcmFtIGxvY2FsTmFtZSBUaGUgbG9jYWwgbmFtZS4KLSAgICAgKiBAcmV0dXJuIFRoZSBhdHRyaWJ1dGUncyB0eXBlLCBvciBudWxsIGlmIHRoZXJlIGlzIG5vCi0gICAgICogICAgICAgICBtYXRjaGluZyBhdHRyaWJ1dGUuCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5BdHRyaWJ1dGVzI2dldFR5cGUoamF2YS5sYW5nLlN0cmluZyxqYXZhLmxhbmcuU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VHlwZSAoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSkKLSAgICB7Ci0gICAgICAgIGludCBtYXggPSBsZW5ndGggKiA1OwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1heDsgaSArPSA1KSB7Ci0gICAgICAgICAgICBpZiAoZGF0YVtpXS5lcXVhbHModXJpKSAmJiBkYXRhW2krMV0uZXF1YWxzKGxvY2FsTmFtZSkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZGF0YVtpKzNdOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogTG9vayB1cCBhbiBhdHRyaWJ1dGUncyB0eXBlIGJ5IHF1YWxpZmllZCAocHJlZml4ZWQpIG5hbWUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcU5hbWUgVGhlIHF1YWxpZmllZCBuYW1lLgotICAgICAqIEByZXR1cm4gVGhlIGF0dHJpYnV0ZSdzIHR5cGUsIG9yIG51bGwgaWYgdGhlcmUgaXMgbm8KLSAgICAgKiAgICAgICAgIG1hdGNoaW5nIGF0dHJpYnV0ZS4KLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkF0dHJpYnV0ZXMjZ2V0VHlwZShqYXZhLmxhbmcuU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VHlwZSAoU3RyaW5nIHFOYW1lKQotICAgIHsKLSAgICAgICAgaW50IG1heCA9IGxlbmd0aCAqIDU7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbWF4OyBpICs9IDUpIHsKLSAgICAgICAgICAgIGlmIChkYXRhW2krMl0uZXF1YWxzKHFOYW1lKSkgewotICAgICAgICAgICAgICAgIHJldHVybiBkYXRhW2krM107Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBMb29rIHVwIGFuIGF0dHJpYnV0ZSdzIHZhbHVlIGJ5IE5hbWVzcGFjZS1xdWFsaWZpZWQgbmFtZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSB1cmkgVGhlIE5hbWVzcGFjZSBVUkksIG9yIHRoZSBlbXB0eSBzdHJpbmcgZm9yIGEgbmFtZQotICAgICAqICAgICAgICB3aXRoIG5vIGV4cGxpY2l0IE5hbWVzcGFjZSBVUkkuCi0gICAgICogQHBhcmFtIGxvY2FsTmFtZSBUaGUgbG9jYWwgbmFtZS4KLSAgICAgKiBAcmV0dXJuIFRoZSBhdHRyaWJ1dGUncyB2YWx1ZSwgb3IgbnVsbCBpZiB0aGVyZSBpcyBubwotICAgICAqICAgICAgICAgbWF0Y2hpbmcgYXR0cmlidXRlLgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQXR0cmlidXRlcyNnZXRWYWx1ZShqYXZhLmxhbmcuU3RyaW5nLGphdmEubGFuZy5TdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRWYWx1ZSAoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSkKLSAgICB7Ci0gICAgICAgIGludCBtYXggPSBsZW5ndGggKiA1OwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1heDsgaSArPSA1KSB7Ci0gICAgICAgICAgICBpZiAoZGF0YVtpXS5lcXVhbHModXJpKSAmJiBkYXRhW2krMV0uZXF1YWxzKGxvY2FsTmFtZSkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZGF0YVtpKzRdOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogTG9vayB1cCBhbiBhdHRyaWJ1dGUncyB2YWx1ZSBieSBxdWFsaWZpZWQgKHByZWZpeGVkKSBuYW1lLgotICAgICAqCi0gICAgICogQHBhcmFtIHFOYW1lIFRoZSBxdWFsaWZpZWQgbmFtZS4KLSAgICAgKiBAcmV0dXJuIFRoZSBhdHRyaWJ1dGUncyB2YWx1ZSwgb3IgbnVsbCBpZiB0aGVyZSBpcyBubwotICAgICAqICAgICAgICAgbWF0Y2hpbmcgYXR0cmlidXRlLgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQXR0cmlidXRlcyNnZXRWYWx1ZShqYXZhLmxhbmcuU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VmFsdWUgKFN0cmluZyBxTmFtZSkKLSAgICB7Ci0gICAgICAgIGludCBtYXggPSBsZW5ndGggKiA1OwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1heDsgaSArPSA1KSB7Ci0gICAgICAgICAgICBpZiAoZGF0YVtpKzJdLmVxdWFscyhxTmFtZSkpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gZGF0YVtpKzRdOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotCi0KLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotICAgIC8vIE1hbmlwdWxhdG9ycy4KLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotCi0KLSAgICAvKioKLSAgICAgKiBDbGVhciB0aGUgYXR0cmlidXRlIGxpc3QgZm9yIHJldXNlLgotICAgICAqCi0gICAgICogPHA+Tm90ZSB0aGF0IGxpdHRsZSBtZW1vcnkgaXMgZnJlZWQgYnkgdGhpcyBjYWxsOgotICAgICAqIHRoZSBjdXJyZW50IGFycmF5IGlzIGtlcHQgc28gaXQgY2FuIGJlCi0gICAgICogcmV1c2VkLjwvcD4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBjbGVhciAoKQotICAgIHsKLSAgICAgICAgaWYgKGRhdGEgIT0gbnVsbCkgewotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAobGVuZ3RoICogNSk7IGkrKykKLSAgICAgICAgICAgICAgICBkYXRhIFtpXSA9IG51bGw7Ci0gICAgICAgIH0KLSAgICAgICAgbGVuZ3RoID0gMDsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIENvcHkgYW4gZW50aXJlIEF0dHJpYnV0ZXMgb2JqZWN0LgotICAgICAqCi0gICAgICogPHA+SXQgbWF5IGJlIG1vcmUgZWZmaWNpZW50IHRvIHJldXNlIGFuIGV4aXN0aW5nIG9iamVjdAotICAgICAqIHJhdGhlciB0aGFuIGNvbnN0YW50bHkgYWxsb2NhdGluZyBuZXcgb25lcy48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gYXR0cyBUaGUgYXR0cmlidXRlcyB0byBjb3B5LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEF0dHJpYnV0ZXMgKEF0dHJpYnV0ZXMgYXR0cykKLSAgICB7Ci0gICAgICAgIGNsZWFyKCk7Ci0gICAgICAgIGxlbmd0aCA9IGF0dHMuZ2V0TGVuZ3RoKCk7Ci0gICAgICAgIGlmIChsZW5ndGggPiAwKSB7Ci0gICAgICAgICAgICBkYXRhID0gbmV3IFN0cmluZ1tsZW5ndGgqNV07Ci0gICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgZGF0YVtpKjVdID0gYXR0cy5nZXRVUkkoaSk7Ci0gICAgICAgICAgICAgICAgZGF0YVtpKjUrMV0gPSBhdHRzLmdldExvY2FsTmFtZShpKTsKLSAgICAgICAgICAgICAgICBkYXRhW2kqNSsyXSA9IGF0dHMuZ2V0UU5hbWUoaSk7Ci0gICAgICAgICAgICAgICAgZGF0YVtpKjUrM10gPSBhdHRzLmdldFR5cGUoaSk7Ci0gICAgICAgICAgICAgICAgZGF0YVtpKjUrNF0gPSBhdHRzLmdldFZhbHVlKGkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBBZGQgYW4gYXR0cmlidXRlIHRvIHRoZSBlbmQgb2YgdGhlIGxpc3QuCi0gICAgICoKLSAgICAgKiA8cD5Gb3IgdGhlIHNha2Ugb2Ygc3BlZWQsIHRoaXMgbWV0aG9kIGRvZXMgbm8gY2hlY2tpbmcKLSAgICAgKiB0byBzZWUgaWYgdGhlIGF0dHJpYnV0ZSBpcyBhbHJlYWR5IGluIHRoZSBsaXN0OiB0aGF0IGlzCi0gICAgICogdGhlIHJlc3BvbnNpYmlsaXR5IG9mIHRoZSBhcHBsaWNhdGlvbi48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gdXJpIFRoZSBOYW1lc3BhY2UgVVJJLCBvciB0aGUgZW1wdHkgc3RyaW5nIGlmCi0gICAgICogICAgICAgIG5vbmUgaXMgYXZhaWxhYmxlIG9yIE5hbWVzcGFjZSBwcm9jZXNzaW5nIGlzIG5vdAotICAgICAqICAgICAgICBiZWluZyBwZXJmb3JtZWQuCi0gICAgICogQHBhcmFtIGxvY2FsTmFtZSBUaGUgbG9jYWwgbmFtZSwgb3IgdGhlIGVtcHR5IHN0cmluZyBpZgotICAgICAqICAgICAgICBOYW1lc3BhY2UgcHJvY2Vzc2luZyBpcyBub3QgYmVpbmcgcGVyZm9ybWVkLgotICAgICAqIEBwYXJhbSBxTmFtZSBUaGUgcXVhbGlmaWVkIChwcmVmaXhlZCkgbmFtZSwgb3IgdGhlIGVtcHR5IHN0cmluZwotICAgICAqICAgICAgICBpZiBxdWFsaWZpZWQgbmFtZXMgYXJlIG5vdCBhdmFpbGFibGUuCi0gICAgICogQHBhcmFtIHR5cGUgVGhlIGF0dHJpYnV0ZSB0eXBlIGFzIGEgc3RyaW5nLgotICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYXR0cmlidXRlIHZhbHVlLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGFkZEF0dHJpYnV0ZSAoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSwgU3RyaW5nIHFOYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHR5cGUsIFN0cmluZyB2YWx1ZSkKLSAgICB7Ci0gICAgICAgIGVuc3VyZUNhcGFjaXR5KGxlbmd0aCsxKTsKLSAgICAgICAgZGF0YVtsZW5ndGgqNV0gPSB1cmk7Ci0gICAgICAgIGRhdGFbbGVuZ3RoKjUrMV0gPSBsb2NhbE5hbWU7Ci0gICAgICAgIGRhdGFbbGVuZ3RoKjUrMl0gPSBxTmFtZTsKLSAgICAgICAgZGF0YVtsZW5ndGgqNSszXSA9IHR5cGU7Ci0gICAgICAgIGRhdGFbbGVuZ3RoKjUrNF0gPSB2YWx1ZTsKLSAgICAgICAgbGVuZ3RoKys7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBTZXQgYW4gYXR0cmlidXRlIGluIHRoZSBsaXN0LgotICAgICAqCi0gICAgICogPHA+Rm9yIHRoZSBzYWtlIG9mIHNwZWVkLCB0aGlzIG1ldGhvZCBkb2VzIG5vIGNoZWNraW5nCi0gICAgICogZm9yIG5hbWUgY29uZmxpY3RzIG9yIHdlbGwtZm9ybWVkbmVzczogc3VjaCBjaGVja3MgYXJlIHRoZQotICAgICAqIHJlc3BvbnNpYmlsaXR5IG9mIHRoZSBhcHBsaWNhdGlvbi48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBhdHRyaWJ1dGUgKHplcm8tYmFzZWQpLgotICAgICAqIEBwYXJhbSB1cmkgVGhlIE5hbWVzcGFjZSBVUkksIG9yIHRoZSBlbXB0eSBzdHJpbmcgaWYKLSAgICAgKiAgICAgICAgbm9uZSBpcyBhdmFpbGFibGUgb3IgTmFtZXNwYWNlIHByb2Nlc3NpbmcgaXMgbm90Ci0gICAgICogICAgICAgIGJlaW5nIHBlcmZvcm1lZC4KLSAgICAgKiBAcGFyYW0gbG9jYWxOYW1lIFRoZSBsb2NhbCBuYW1lLCBvciB0aGUgZW1wdHkgc3RyaW5nIGlmCi0gICAgICogICAgICAgIE5hbWVzcGFjZSBwcm9jZXNzaW5nIGlzIG5vdCBiZWluZyBwZXJmb3JtZWQuCi0gICAgICogQHBhcmFtIHFOYW1lIFRoZSBxdWFsaWZpZWQgbmFtZSwgb3IgdGhlIGVtcHR5IHN0cmluZwotICAgICAqICAgICAgICBpZiBxdWFsaWZpZWQgbmFtZXMgYXJlIG5vdCBhdmFpbGFibGUuCi0gICAgICogQHBhcmFtIHR5cGUgVGhlIGF0dHJpYnV0ZSB0eXBlIGFzIGEgc3RyaW5nLgotICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYXR0cmlidXRlIHZhbHVlLgotICAgICAqIEBleGNlcHRpb24gamF2YS5sYW5nLkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBXaGVuIHRoZQotICAgICAqICAgICAgICAgICAgc3VwcGxpZWQgaW5kZXggZG9lcyBub3QgcG9pbnQgdG8gYW4gYXR0cmlidXRlCi0gICAgICogICAgICAgICAgICBpbiB0aGUgbGlzdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRBdHRyaWJ1dGUgKGludCBpbmRleCwgU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBxTmFtZSwgU3RyaW5nIHR5cGUsIFN0cmluZyB2YWx1ZSkKLSAgICB7Ci0gICAgICAgIGlmIChpbmRleCA+PSAwICYmIGluZGV4IDwgbGVuZ3RoKSB7Ci0gICAgICAgICAgICBkYXRhW2luZGV4KjVdID0gdXJpOwotICAgICAgICAgICAgZGF0YVtpbmRleCo1KzFdID0gbG9jYWxOYW1lOwotICAgICAgICAgICAgZGF0YVtpbmRleCo1KzJdID0gcU5hbWU7Ci0gICAgICAgICAgICBkYXRhW2luZGV4KjUrM10gPSB0eXBlOwotICAgICAgICAgICAgZGF0YVtpbmRleCo1KzRdID0gdmFsdWU7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBiYWRJbmRleChpbmRleCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFJlbW92ZSBhbiBhdHRyaWJ1dGUgZnJvbSB0aGUgbGlzdC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGF0dHJpYnV0ZSAoemVyby1iYXNlZCkuCi0gICAgICogQGV4Y2VwdGlvbiBqYXZhLmxhbmcuQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIFdoZW4gdGhlCi0gICAgICogICAgICAgICAgICBzdXBwbGllZCBpbmRleCBkb2VzIG5vdCBwb2ludCB0byBhbiBhdHRyaWJ1dGUKLSAgICAgKiAgICAgICAgICAgIGluIHRoZSBsaXN0LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHJlbW92ZUF0dHJpYnV0ZSAoaW50IGluZGV4KQotICAgIHsKLSAgICAgICAgaWYgKGluZGV4ID49IDAgJiYgaW5kZXggPCBsZW5ndGgpIHsKLSAgICAgICAgICAgIGlmIChpbmRleCA8IGxlbmd0aCAtIDEpIHsKLSAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGRhdGEsIChpbmRleCsxKSo1LCBkYXRhLCBpbmRleCo1LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGxlbmd0aC1pbmRleC0xKSo1KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGluZGV4ID0gKGxlbmd0aCAtIDEpICogNTsKLSAgICAgICAgICAgIGRhdGEgW2luZGV4KytdID0gbnVsbDsKLSAgICAgICAgICAgIGRhdGEgW2luZGV4KytdID0gbnVsbDsKLSAgICAgICAgICAgIGRhdGEgW2luZGV4KytdID0gbnVsbDsKLSAgICAgICAgICAgIGRhdGEgW2luZGV4KytdID0gbnVsbDsKLSAgICAgICAgICAgIGRhdGEgW2luZGV4XSA9IG51bGw7Ci0gICAgICAgICAgICBsZW5ndGgtLTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIGJhZEluZGV4KGluZGV4KTsKLSAgICAgICAgfQotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSBOYW1lc3BhY2UgVVJJIG9mIGEgc3BlY2lmaWMgYXR0cmlidXRlLgotICAgICAqCi0gICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgYXR0cmlidXRlICh6ZXJvLWJhc2VkKS4KLSAgICAgKiBAcGFyYW0gdXJpIFRoZSBhdHRyaWJ1dGUncyBOYW1lc3BhY2UgVVJJLCBvciB0aGUgZW1wdHkKLSAgICAgKiAgICAgICAgc3RyaW5nIGZvciBub25lLgotICAgICAqIEBleGNlcHRpb24gamF2YS5sYW5nLkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBXaGVuIHRoZQotICAgICAqICAgICAgICAgICAgc3VwcGxpZWQgaW5kZXggZG9lcyBub3QgcG9pbnQgdG8gYW4gYXR0cmlidXRlCi0gICAgICogICAgICAgICAgICBpbiB0aGUgbGlzdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRVUkkgKGludCBpbmRleCwgU3RyaW5nIHVyaSkKLSAgICB7Ci0gICAgICAgIGlmIChpbmRleCA+PSAwICYmIGluZGV4IDwgbGVuZ3RoKSB7Ci0gICAgICAgICAgICBkYXRhW2luZGV4KjVdID0gdXJpOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgYmFkSW5kZXgoaW5kZXgpOwotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIGxvY2FsIG5hbWUgb2YgYSBzcGVjaWZpYyBhdHRyaWJ1dGUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBhdHRyaWJ1dGUgKHplcm8tYmFzZWQpLgotICAgICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGF0dHJpYnV0ZSdzIGxvY2FsIG5hbWUsIG9yIHRoZSBlbXB0eQotICAgICAqICAgICAgICBzdHJpbmcgZm9yIG5vbmUuCi0gICAgICogQGV4Y2VwdGlvbiBqYXZhLmxhbmcuQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIFdoZW4gdGhlCi0gICAgICogICAgICAgICAgICBzdXBwbGllZCBpbmRleCBkb2VzIG5vdCBwb2ludCB0byBhbiBhdHRyaWJ1dGUKLSAgICAgKiAgICAgICAgICAgIGluIHRoZSBsaXN0LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldExvY2FsTmFtZSAoaW50IGluZGV4LCBTdHJpbmcgbG9jYWxOYW1lKQotICAgIHsKLSAgICAgICAgaWYgKGluZGV4ID49IDAgJiYgaW5kZXggPCBsZW5ndGgpIHsKLSAgICAgICAgICAgIGRhdGFbaW5kZXgqNSsxXSA9IGxvY2FsTmFtZTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIGJhZEluZGV4KGluZGV4KTsKLSAgICAgICAgfQotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSBxdWFsaWZpZWQgbmFtZSBvZiBhIHNwZWNpZmljIGF0dHJpYnV0ZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGF0dHJpYnV0ZSAoemVyby1iYXNlZCkuCi0gICAgICogQHBhcmFtIHFOYW1lIFRoZSBhdHRyaWJ1dGUncyBxdWFsaWZpZWQgbmFtZSwgb3IgdGhlIGVtcHR5Ci0gICAgICogICAgICAgIHN0cmluZyBmb3Igbm9uZS4KLSAgICAgKiBAZXhjZXB0aW9uIGphdmEubGFuZy5BcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gV2hlbiB0aGUKLSAgICAgKiAgICAgICAgICAgIHN1cHBsaWVkIGluZGV4IGRvZXMgbm90IHBvaW50IHRvIGFuIGF0dHJpYnV0ZQotICAgICAqICAgICAgICAgICAgaW4gdGhlIGxpc3QuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0UU5hbWUgKGludCBpbmRleCwgU3RyaW5nIHFOYW1lKQotICAgIHsKLSAgICAgICAgaWYgKGluZGV4ID49IDAgJiYgaW5kZXggPCBsZW5ndGgpIHsKLSAgICAgICAgICAgIGRhdGFbaW5kZXgqNSsyXSA9IHFOYW1lOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgYmFkSW5kZXgoaW5kZXgpOwotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIHR5cGUgb2YgYSBzcGVjaWZpYyBhdHRyaWJ1dGUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBhdHRyaWJ1dGUgKHplcm8tYmFzZWQpLgotICAgICAqIEBwYXJhbSB0eXBlIFRoZSBhdHRyaWJ1dGUncyB0eXBlLgotICAgICAqIEBleGNlcHRpb24gamF2YS5sYW5nLkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBXaGVuIHRoZQotICAgICAqICAgICAgICAgICAgc3VwcGxpZWQgaW5kZXggZG9lcyBub3QgcG9pbnQgdG8gYW4gYXR0cmlidXRlCi0gICAgICogICAgICAgICAgICBpbiB0aGUgbGlzdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRUeXBlIChpbnQgaW5kZXgsIFN0cmluZyB0eXBlKQotICAgIHsKLSAgICAgICAgaWYgKGluZGV4ID49IDAgJiYgaW5kZXggPCBsZW5ndGgpIHsKLSAgICAgICAgICAgIGRhdGFbaW5kZXgqNSszXSA9IHR5cGU7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBiYWRJbmRleChpbmRleCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFNldCB0aGUgdmFsdWUgb2YgYSBzcGVjaWZpYyBhdHRyaWJ1dGUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBhdHRyaWJ1dGUgKHplcm8tYmFzZWQpLgotICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYXR0cmlidXRlJ3MgdmFsdWUuCi0gICAgICogQGV4Y2VwdGlvbiBqYXZhLmxhbmcuQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIFdoZW4gdGhlCi0gICAgICogICAgICAgICAgICBzdXBwbGllZCBpbmRleCBkb2VzIG5vdCBwb2ludCB0byBhbiBhdHRyaWJ1dGUKLSAgICAgKiAgICAgICAgICAgIGluIHRoZSBsaXN0LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFZhbHVlIChpbnQgaW5kZXgsIFN0cmluZyB2YWx1ZSkKLSAgICB7Ci0gICAgICAgIGlmIChpbmRleCA+PSAwICYmIGluZGV4IDwgbGVuZ3RoKSB7Ci0gICAgICAgICAgICBkYXRhW2luZGV4KjUrNF0gPSB2YWx1ZTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIGJhZEluZGV4KGluZGV4KTsKLSAgICAgICAgfQotICAgIH0KLQotCi0KLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotICAgIC8vIEludGVybmFsIG1ldGhvZHMuCi0gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLQotCi0gICAgLyoqCi0gICAgICogRW5zdXJlIHRoZSBpbnRlcm5hbCBhcnJheSdzIGNhcGFjaXR5LgotICAgICAqCi0gICAgICogQHBhcmFtIG4gVGhlIG1pbmltdW0gbnVtYmVyIG9mIGF0dHJpYnV0ZXMgdGhhdCB0aGUgYXJyYXkgbXVzdAotICAgICAqICAgICAgICBiZSBhYmxlIHRvIGhvbGQuCi0gICAgICovCi0gICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUNhcGFjaXR5IChpbnQgbikgICAgewotICAgICAgICBpZiAobiA8PSAwKSB7Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLSAgICAgICAgaW50IG1heDsKLSAgICAgICAgaWYgKGRhdGEgPT0gbnVsbCB8fCBkYXRhLmxlbmd0aCA9PSAwKSB7Ci0gICAgICAgICAgICBtYXggPSAyNTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChkYXRhLmxlbmd0aCA+PSBuICogNSkgewotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgbWF4ID0gZGF0YS5sZW5ndGg7Ci0gICAgICAgIH0KLSAgICAgICAgd2hpbGUgKG1heCA8IG4gKiA1KSB7Ci0gICAgICAgICAgICBtYXggKj0gMjsKLSAgICAgICAgfQotCi0gICAgICAgIFN0cmluZyBuZXdEYXRhW10gPSBuZXcgU3RyaW5nW21heF07Ci0gICAgICAgIGlmIChsZW5ndGggPiAwKSB7Ci0gICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGRhdGEsIDAsIG5ld0RhdGEsIDAsIGxlbmd0aCo1KTsKLSAgICAgICAgfQotICAgICAgICBkYXRhID0gbmV3RGF0YTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFJlcG9ydCBhIGJhZCBhcnJheSBpbmRleCBpbiBhIG1hbmlwdWxhdG9yLgotICAgICAqCi0gICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byByZXBvcnQuCi0gICAgICogQGV4Y2VwdGlvbiBqYXZhLmxhbmcuQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIEFsd2F5cy4KLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgYmFkSW5kZXggKGludCBpbmRleCkKLSAgICAgICAgdGhyb3dzIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgU3RyaW5nIG1zZyA9Ci0gICAgICAgICAgICAiQXR0ZW1wdCB0byBtb2RpZnkgYXR0cmlidXRlIGF0IGlsbGVnYWwgaW5kZXg6ICIgKyBpbmRleDsKLSAgICAgICAgdGhyb3cgbmV3IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihtc2cpOwotICAgIH0KLQotCi0KLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotICAgIC8vIEludGVybmFsIHN0YXRlLgotICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0KLSAgICBpbnQgbGVuZ3RoOwotICAgIFN0cmluZyBkYXRhIFtdOwotCi19Ci0KLS8vIGVuZCBvZiBBdHRyaWJ1dGVzSW1wbC5qYXZhCmRpZmYgLS1naXQgYS9zcmMvb3JnL3htbC9zYXgvaGVscGVycy9EZWZhdWx0SGFuZGxlci5qYXZhIGIvc3JjL29yZy94bWwvc2F4L2hlbHBlcnMvRGVmYXVsdEhhbmRsZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNGFlNmIxZC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3htbC9zYXgvaGVscGVycy9EZWZhdWx0SGFuZGxlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDkxICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDAsIDIwMDYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8vIERlZmF1bHRIYW5kbGVyLmphdmEgLSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBjb3JlIGhhbmRsZXJzLgotLy8gaHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZwotLy8gV3JpdHRlbiBieSBEYXZpZCBNZWdnaW5zb24KLS8vIE5PIFdBUlJBTlRZISAgVGhpcyBjbGFzcyBpcyBpbiB0aGUgcHVibGljIGRvbWFpbi4KLS8vICRJZDogRGVmYXVsdEhhbmRsZXIuamF2YSx2IDEuMyAyMDA2LzA0LzEzIDAyOjA2OjMyIGplZmZzdXR0b3IgRXhwICQKLQotcGFja2FnZSBvcmcueG1sLnNheC5oZWxwZXJzOwotCi1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLQotaW1wb3J0IG9yZy54bWwuc2F4LklucHV0U291cmNlOwotaW1wb3J0IG9yZy54bWwuc2F4LkxvY2F0b3I7Ci1pbXBvcnQgb3JnLnhtbC5zYXguQXR0cmlidXRlczsKLWltcG9ydCBvcmcueG1sLnNheC5FbnRpdHlSZXNvbHZlcjsKLWltcG9ydCBvcmcueG1sLnNheC5EVERIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LkVycm9ySGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb247Ci0KLQotLyoqCi0gKiBEZWZhdWx0IGJhc2UgY2xhc3MgZm9yIFNBWDIgZXZlbnQgaGFuZGxlcnMuCi0gKgotICogPGJsb2NrcXVvdGU+Ci0gKiA8ZW0+VGhpcyBtb2R1bGUsIGJvdGggc291cmNlIGNvZGUgYW5kIGRvY3VtZW50YXRpb24sIGlzIGluIHRoZQotICogUHVibGljIERvbWFpbiwgYW5kIGNvbWVzIHdpdGggPHN0cm9uZz5OTyBXQVJSQU5UWTwvc3Ryb25nPi48L2VtPgotICogU2VlIDxhIGhyZWY9J2h0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmcnPmh0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmc8L2E+Ci0gKiBmb3IgZnVydGhlciBpbmZvcm1hdGlvbi4KLSAqIDwvYmxvY2txdW90ZT4KLSAqCi0gKiA8cD5UaGlzIGNsYXNzIGlzIGF2YWlsYWJsZSBhcyBhIGNvbnZlbmllbmNlIGJhc2UgY2xhc3MgZm9yIFNBWDIKLSAqIGFwcGxpY2F0aW9uczogaXQgcHJvdmlkZXMgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbnMgZm9yIGFsbCBvZiB0aGUKLSAqIGNhbGxiYWNrcyBpbiB0aGUgZm91ciBjb3JlIFNBWDIgaGFuZGxlciBjbGFzc2VzOjwvcD4KLSAqCi0gKiA8dWw+Ci0gKiA8bGk+e0BsaW5rIG9yZy54bWwuc2F4LkVudGl0eVJlc29sdmVyIEVudGl0eVJlc29sdmVyfTwvbGk+Ci0gKiA8bGk+e0BsaW5rIG9yZy54bWwuc2F4LkRUREhhbmRsZXIgRFRESGFuZGxlcn08L2xpPgotICogPGxpPntAbGluayBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciBDb250ZW50SGFuZGxlcn08L2xpPgotICogPGxpPntAbGluayBvcmcueG1sLnNheC5FcnJvckhhbmRsZXIgRXJyb3JIYW5kbGVyfTwvbGk+Ci0gKiA8L3VsPgotICoKLSAqIDxwPkFwcGxpY2F0aW9uIHdyaXRlcnMgY2FuIGV4dGVuZCB0aGlzIGNsYXNzIHdoZW4gdGhleSBuZWVkIHRvCi0gKiBpbXBsZW1lbnQgb25seSBwYXJ0IG9mIGFuIGludGVyZmFjZTsgcGFyc2VyIHdyaXRlcnMgY2FuCi0gKiBpbnN0YW50aWF0ZSB0aGlzIGNsYXNzIHRvIHByb3ZpZGUgZGVmYXVsdCBoYW5kbGVycyB3aGVuIHRoZQotICogYXBwbGljYXRpb24gaGFzIG5vdCBzdXBwbGllZCBpdHMgb3duLjwvcD4KLSAqCi0gKiA8cD5UaGlzIGNsYXNzIHJlcGxhY2VzIHRoZSBkZXByZWNhdGVkIFNBWDEKLSAqIHtAbGluayBvcmcueG1sLnNheC5IYW5kbGVyQmFzZSBIYW5kbGVyQmFzZX0gY2xhc3MuPC9wPgotICoKLSAqIEBzaW5jZSBTQVggMi4wCi0gKiBAYXV0aG9yIERhdmlkIE1lZ2dpbnNvbiwKLSAqIEBzZWUgb3JnLnhtbC5zYXguRW50aXR5UmVzb2x2ZXIKLSAqIEBzZWUgb3JnLnhtbC5zYXguRFRESGFuZGxlcgotICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcgotICogQHNlZSBvcmcueG1sLnNheC5FcnJvckhhbmRsZXIKLSAqLwotcHVibGljIGNsYXNzIERlZmF1bHRIYW5kbGVyCi0gICAgaW1wbGVtZW50cyBFbnRpdHlSZXNvbHZlciwgRFRESGFuZGxlciwgQ29udGVudEhhbmRsZXIsIEVycm9ySGFuZGxlcgotewotCi0KLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotICAgIC8vIERlZmF1bHQgaW1wbGVtZW50YXRpb24gb2YgdGhlIEVudGl0eVJlc29sdmVyIGludGVyZmFjZS4KLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotCi0gICAgLyoqCi0gICAgICogUmVzb2x2ZSBhbiBleHRlcm5hbCBlbnRpdHkuCi0gICAgICoKLSAgICAgKiA8cD5BbHdheXMgcmV0dXJuIG51bGwsIHNvIHRoYXQgdGhlIHBhcnNlciB3aWxsIHVzZSB0aGUgc3lzdGVtCi0gICAgICogaWRlbnRpZmllciBwcm92aWRlZCBpbiB0aGUgWE1MIGRvY3VtZW50LiAgVGhpcyBtZXRob2QgaW1wbGVtZW50cwotICAgICAqIHRoZSBTQVggZGVmYXVsdCBiZWhhdmlvdXI6IGFwcGxpY2F0aW9uIHdyaXRlcnMgY2FuIG92ZXJyaWRlIGl0Ci0gICAgICogaW4gYSBzdWJjbGFzcyB0byBkbyBzcGVjaWFsIHRyYW5zbGF0aW9ucyBzdWNoIGFzIGNhdGFsb2cgbG9va3VwcwotICAgICAqIG9yIFVSSSByZWRpcmVjdGlvbi48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gcHVibGljSWQgVGhlIHB1YmxpYyBpZGVudGlmaWVyLCBvciBudWxsIGlmIG5vbmUgaXMKLSAgICAgKiAgICAgICAgICAgICAgICAgYXZhaWxhYmxlLgotICAgICAqIEBwYXJhbSBzeXN0ZW1JZCBUaGUgc3lzdGVtIGlkZW50aWZpZXIgcHJvdmlkZWQgaW4gdGhlIFhNTAotICAgICAqICAgICAgICAgICAgICAgICBkb2N1bWVudC4KLSAgICAgKiBAcmV0dXJuIFRoZSBuZXcgaW5wdXQgc291cmNlLCBvciBudWxsIHRvIHJlcXVpcmUgdGhlCi0gICAgICogICAgICAgICBkZWZhdWx0IGJlaGF2aW91ci4KLSAgICAgKiBAZXhjZXB0aW9uIGphdmEuaW8uSU9FeGNlcHRpb24gSWYgdGhlcmUgaXMgYW4gZXJyb3Igc2V0dGluZwotICAgICAqICAgICAgICAgICAgdXAgdGhlIG5ldyBpbnB1dCBzb3VyY2UuCi0gICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkVudGl0eVJlc29sdmVyI3Jlc29sdmVFbnRpdHkKLSAgICAgKi8KLSAgICBwdWJsaWMgSW5wdXRTb3VyY2UgcmVzb2x2ZUVudGl0eSAoU3RyaW5nIHB1YmxpY0lkLCBTdHJpbmcgc3lzdGVtSWQpCi0gICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLQotCi0gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLSAgICAvLyBEZWZhdWx0IGltcGxlbWVudGF0aW9uIG9mIERUREhhbmRsZXIgaW50ZXJmYWNlLgotICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0KLQotICAgIC8qKgotICAgICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGEgbm90YXRpb24gZGVjbGFyYXRpb24uCi0gICAgICoKLSAgICAgKiA8cD5CeSBkZWZhdWx0LCBkbyBub3RoaW5nLiAgQXBwbGljYXRpb24gd3JpdGVycyBtYXkgb3ZlcnJpZGUgdGhpcwotICAgICAqIG1ldGhvZCBpbiBhIHN1YmNsYXNzIGlmIHRoZXkgd2lzaCB0byBrZWVwIHRyYWNrIG9mIHRoZSBub3RhdGlvbnMKLSAgICAgKiBkZWNsYXJlZCBpbiBhIGRvY3VtZW50LjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBub3RhdGlvbiBuYW1lLgotICAgICAqIEBwYXJhbSBwdWJsaWNJZCBUaGUgbm90YXRpb24gcHVibGljIGlkZW50aWZpZXIsIG9yIG51bGwgaWYgbm90Ci0gICAgICogICAgICAgICAgICAgICAgIGF2YWlsYWJsZS4KLSAgICAgKiBAcGFyYW0gc3lzdGVtSWQgVGhlIG5vdGF0aW9uIHN5c3RlbSBpZGVudGlmaWVyLgotICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5EVERIYW5kbGVyI25vdGF0aW9uRGVjbAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIG5vdGF0aW9uRGVjbCAoU3RyaW5nIG5hbWUsIFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICAvLyBubyBvcAotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgYW4gdW5wYXJzZWQgZW50aXR5IGRlY2xhcmF0aW9uLgotICAgICAqCi0gICAgICogPHA+QnkgZGVmYXVsdCwgZG8gbm90aGluZy4gIEFwcGxpY2F0aW9uIHdyaXRlcnMgbWF5IG92ZXJyaWRlIHRoaXMKLSAgICAgKiBtZXRob2QgaW4gYSBzdWJjbGFzcyB0byBrZWVwIHRyYWNrIG9mIHRoZSB1bnBhcnNlZCBlbnRpdGllcwotICAgICAqIGRlY2xhcmVkIGluIGEgZG9jdW1lbnQuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgVGhlIGVudGl0eSBuYW1lLgotICAgICAqIEBwYXJhbSBwdWJsaWNJZCBUaGUgZW50aXR5IHB1YmxpYyBpZGVudGlmaWVyLCBvciBudWxsIGlmIG5vdAotICAgICAqICAgICAgICAgICAgICAgICBhdmFpbGFibGUuCi0gICAgICogQHBhcmFtIHN5c3RlbUlkIFRoZSBlbnRpdHkgc3lzdGVtIGlkZW50aWZpZXIuCi0gICAgICogQHBhcmFtIG5vdGF0aW9uTmFtZSBUaGUgbmFtZSBvZiB0aGUgYXNzb2NpYXRlZCBub3RhdGlvbi4KLSAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguRFRESGFuZGxlciN1bnBhcnNlZEVudGl0eURlY2wKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB1bnBhcnNlZEVudGl0eURlY2wgKFN0cmluZyBuYW1lLCBTdHJpbmcgcHVibGljSWQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgc3lzdGVtSWQsIFN0cmluZyBub3RhdGlvbk5hbWUpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIC8vIG5vIG9wCi0gICAgfQotCi0KLQotICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0gICAgLy8gRGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBvZiBDb250ZW50SGFuZGxlciBpbnRlcmZhY2UuCi0gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLQotCi0gICAgLyoqCi0gICAgICogUmVjZWl2ZSBhIExvY2F0b3Igb2JqZWN0IGZvciBkb2N1bWVudCBldmVudHMuCi0gICAgICoKLSAgICAgKiA8cD5CeSBkZWZhdWx0LCBkbyBub3RoaW5nLiAgQXBwbGljYXRpb24gd3JpdGVycyBtYXkgb3ZlcnJpZGUgdGhpcwotICAgICAqIG1ldGhvZCBpbiBhIHN1YmNsYXNzIGlmIHRoZXkgd2lzaCB0byBzdG9yZSB0aGUgbG9jYXRvciBmb3IgdXNlCi0gICAgICogd2l0aCBvdGhlciBkb2N1bWVudCBldmVudHMuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGxvY2F0b3IgQSBsb2NhdG9yIGZvciBhbGwgU0FYIGRvY3VtZW50IGV2ZW50cy4KLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI3NldERvY3VtZW50TG9jYXRvcgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguTG9jYXRvcgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldERvY3VtZW50TG9jYXRvciAoTG9jYXRvciBsb2NhdG9yKQotICAgIHsKLSAgICAgICAgLy8gbm8gb3AKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIHRoZSBiZWdpbm5pbmcgb2YgdGhlIGRvY3VtZW50LgotICAgICAqCi0gICAgICogPHA+QnkgZGVmYXVsdCwgZG8gbm90aGluZy4gIEFwcGxpY2F0aW9uIHdyaXRlcnMgbWF5IG92ZXJyaWRlIHRoaXMKLSAgICAgKiBtZXRob2QgaW4gYSBzdWJjbGFzcyB0byB0YWtlIHNwZWNpZmljIGFjdGlvbnMgYXQgdGhlIGJlZ2lubmluZwotICAgICAqIG9mIGEgZG9jdW1lbnQgKHN1Y2ggYXMgYWxsb2NhdGluZyB0aGUgcm9vdCBub2RlIG9mIGEgdHJlZSBvcgotICAgICAqIGNyZWF0aW5nIGFuIG91dHB1dCBmaWxlKS48L3A+Ci0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjc3RhcnREb2N1bWVudAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RG9jdW1lbnQgKCkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgLy8gbm8gb3AKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIHRoZSBlbmQgb2YgdGhlIGRvY3VtZW50LgotICAgICAqCi0gICAgICogPHA+QnkgZGVmYXVsdCwgZG8gbm90aGluZy4gIEFwcGxpY2F0aW9uIHdyaXRlcnMgbWF5IG92ZXJyaWRlIHRoaXMKLSAgICAgKiBtZXRob2QgaW4gYSBzdWJjbGFzcyB0byB0YWtlIHNwZWNpZmljIGFjdGlvbnMgYXQgdGhlIGVuZAotICAgICAqIG9mIGEgZG9jdW1lbnQgKHN1Y2ggYXMgZmluYWxpc2luZyBhIHRyZWUgb3IgY2xvc2luZyBhbiBvdXRwdXQKLSAgICAgKiBmaWxlKS48L3A+Ci0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjZW5kRG9jdW1lbnQKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbmREb2N1bWVudCAoKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICAvLyBubyBvcAotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIHN0YXJ0IG9mIGEgTmFtZXNwYWNlIG1hcHBpbmcuCi0gICAgICoKLSAgICAgKiA8cD5CeSBkZWZhdWx0LCBkbyBub3RoaW5nLiAgQXBwbGljYXRpb24gd3JpdGVycyBtYXkgb3ZlcnJpZGUgdGhpcwotICAgICAqIG1ldGhvZCBpbiBhIHN1YmNsYXNzIHRvIHRha2Ugc3BlY2lmaWMgYWN0aW9ucyBhdCB0aGUgc3RhcnQgb2YKLSAgICAgKiBlYWNoIE5hbWVzcGFjZSBwcmVmaXggc2NvcGUgKHN1Y2ggYXMgc3RvcmluZyB0aGUgcHJlZml4IG1hcHBpbmcpLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBwcmVmaXggVGhlIE5hbWVzcGFjZSBwcmVmaXggYmVpbmcgZGVjbGFyZWQuCi0gICAgICogQHBhcmFtIHVyaSBUaGUgTmFtZXNwYWNlIFVSSSBtYXBwZWQgdG8gdGhlIHByZWZpeC4KLSAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjc3RhcnRQcmVmaXhNYXBwaW5nCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnRQcmVmaXhNYXBwaW5nIChTdHJpbmcgcHJlZml4LCBTdHJpbmcgdXJpKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICAvLyBubyBvcAotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIGVuZCBvZiBhIE5hbWVzcGFjZSBtYXBwaW5nLgotICAgICAqCi0gICAgICogPHA+QnkgZGVmYXVsdCwgZG8gbm90aGluZy4gIEFwcGxpY2F0aW9uIHdyaXRlcnMgbWF5IG92ZXJyaWRlIHRoaXMKLSAgICAgKiBtZXRob2QgaW4gYSBzdWJjbGFzcyB0byB0YWtlIHNwZWNpZmljIGFjdGlvbnMgYXQgdGhlIGVuZCBvZgotICAgICAqIGVhY2ggcHJlZml4IG1hcHBpbmcuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIHByZWZpeCBUaGUgTmFtZXNwYWNlIHByZWZpeCBiZWluZyBkZWNsYXJlZC4KLSAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjZW5kUHJlZml4TWFwcGluZwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZFByZWZpeE1hcHBpbmcgKFN0cmluZyBwcmVmaXgpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIC8vIG5vIG9wCi0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiB0aGUgc3RhcnQgb2YgYW4gZWxlbWVudC4KLSAgICAgKgotICAgICAqIDxwPkJ5IGRlZmF1bHQsIGRvIG5vdGhpbmcuICBBcHBsaWNhdGlvbiB3cml0ZXJzIG1heSBvdmVycmlkZSB0aGlzCi0gICAgICogbWV0aG9kIGluIGEgc3ViY2xhc3MgdG8gdGFrZSBzcGVjaWZpYyBhY3Rpb25zIGF0IHRoZSBzdGFydCBvZgotICAgICAqIGVhY2ggZWxlbWVudCAoc3VjaCBhcyBhbGxvY2F0aW5nIGEgbmV3IHRyZWUgbm9kZSBvciB3cml0aW5nCi0gICAgICogb3V0cHV0IHRvIGEgZmlsZSkuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIHVyaSBUaGUgTmFtZXNwYWNlIFVSSSwgb3IgdGhlIGVtcHR5IHN0cmluZyBpZiB0aGUKLSAgICAgKiAgICAgICAgZWxlbWVudCBoYXMgbm8gTmFtZXNwYWNlIFVSSSBvciBpZiBOYW1lc3BhY2UKLSAgICAgKiAgICAgICAgcHJvY2Vzc2luZyBpcyBub3QgYmVpbmcgcGVyZm9ybWVkLgotICAgICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGxvY2FsIG5hbWUgKHdpdGhvdXQgcHJlZml4KSwgb3IgdGhlCi0gICAgICogICAgICAgIGVtcHR5IHN0cmluZyBpZiBOYW1lc3BhY2UgcHJvY2Vzc2luZyBpcyBub3QgYmVpbmcKLSAgICAgKiAgICAgICAgcGVyZm9ybWVkLgotICAgICAqIEBwYXJhbSBxTmFtZSBUaGUgcXVhbGlmaWVkIG5hbWUgKHdpdGggcHJlZml4KSwgb3IgdGhlCi0gICAgICogICAgICAgIGVtcHR5IHN0cmluZyBpZiBxdWFsaWZpZWQgbmFtZXMgYXJlIG5vdCBhdmFpbGFibGUuCi0gICAgICogQHBhcmFtIGF0dHJpYnV0ZXMgVGhlIGF0dHJpYnV0ZXMgYXR0YWNoZWQgdG8gdGhlIGVsZW1lbnQuICBJZgotICAgICAqICAgICAgICB0aGVyZSBhcmUgbm8gYXR0cmlidXRlcywgaXQgc2hhbGwgYmUgYW4gZW1wdHkKLSAgICAgKiAgICAgICAgQXR0cmlidXRlcyBvYmplY3QuCi0gICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI3N0YXJ0RWxlbWVudAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudCAoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBxTmFtZSwgQXR0cmlidXRlcyBhdHRyaWJ1dGVzKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICAvLyBubyBvcAotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIGVuZCBvZiBhbiBlbGVtZW50LgotICAgICAqCi0gICAgICogPHA+QnkgZGVmYXVsdCwgZG8gbm90aGluZy4gIEFwcGxpY2F0aW9uIHdyaXRlcnMgbWF5IG92ZXJyaWRlIHRoaXMKLSAgICAgKiBtZXRob2QgaW4gYSBzdWJjbGFzcyB0byB0YWtlIHNwZWNpZmljIGFjdGlvbnMgYXQgdGhlIGVuZCBvZgotICAgICAqIGVhY2ggZWxlbWVudCAoc3VjaCBhcyBmaW5hbGlzaW5nIGEgdHJlZSBub2RlIG9yIHdyaXRpbmcKLSAgICAgKiBvdXRwdXQgdG8gYSBmaWxlKS48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gdXJpIFRoZSBOYW1lc3BhY2UgVVJJLCBvciB0aGUgZW1wdHkgc3RyaW5nIGlmIHRoZQotICAgICAqICAgICAgICBlbGVtZW50IGhhcyBubyBOYW1lc3BhY2UgVVJJIG9yIGlmIE5hbWVzcGFjZQotICAgICAqICAgICAgICBwcm9jZXNzaW5nIGlzIG5vdCBiZWluZyBwZXJmb3JtZWQuCi0gICAgICogQHBhcmFtIGxvY2FsTmFtZSBUaGUgbG9jYWwgbmFtZSAod2l0aG91dCBwcmVmaXgpLCBvciB0aGUKLSAgICAgKiAgICAgICAgZW1wdHkgc3RyaW5nIGlmIE5hbWVzcGFjZSBwcm9jZXNzaW5nIGlzIG5vdCBiZWluZwotICAgICAqICAgICAgICBwZXJmb3JtZWQuCi0gICAgICogQHBhcmFtIHFOYW1lIFRoZSBxdWFsaWZpZWQgbmFtZSAod2l0aCBwcmVmaXgpLCBvciB0aGUKLSAgICAgKiAgICAgICAgZW1wdHkgc3RyaW5nIGlmIHF1YWxpZmllZCBuYW1lcyBhcmUgbm90IGF2YWlsYWJsZS4KLSAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjZW5kRWxlbWVudAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZEVsZW1lbnQgKFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUsIFN0cmluZyBxTmFtZSkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgLy8gbm8gb3AKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGNoYXJhY3RlciBkYXRhIGluc2lkZSBhbiBlbGVtZW50LgotICAgICAqCi0gICAgICogPHA+QnkgZGVmYXVsdCwgZG8gbm90aGluZy4gIEFwcGxpY2F0aW9uIHdyaXRlcnMgbWF5IG92ZXJyaWRlIHRoaXMKLSAgICAgKiBtZXRob2QgdG8gdGFrZSBzcGVjaWZpYyBhY3Rpb25zIGZvciBlYWNoIGNodW5rIG9mIGNoYXJhY3RlciBkYXRhCi0gICAgICogKHN1Y2ggYXMgYWRkaW5nIHRoZSBkYXRhIHRvIGEgbm9kZSBvciBidWZmZXIsIG9yIHByaW50aW5nIGl0IHRvCi0gICAgICogYSBmaWxlKS48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gY2ggVGhlIGNoYXJhY3RlcnMuCi0gICAgICogQHBhcmFtIHN0YXJ0IFRoZSBzdGFydCBwb3NpdGlvbiBpbiB0aGUgY2hhcmFjdGVyIGFycmF5LgotICAgICAqIEBwYXJhbSBsZW5ndGggVGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHVzZSBmcm9tIHRoZQotICAgICAqICAgICAgICAgICAgICAgY2hhcmFjdGVyIGFycmF5LgotICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNjaGFyYWN0ZXJzCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY2hhcmFjdGVycyAoY2hhciBjaFtdLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIC8vIG5vIG9wCi0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBpZ25vcmFibGUgd2hpdGVzcGFjZSBpbiBlbGVtZW50IGNvbnRlbnQuCi0gICAgICoKLSAgICAgKiA8cD5CeSBkZWZhdWx0LCBkbyBub3RoaW5nLiAgQXBwbGljYXRpb24gd3JpdGVycyBtYXkgb3ZlcnJpZGUgdGhpcwotICAgICAqIG1ldGhvZCB0byB0YWtlIHNwZWNpZmljIGFjdGlvbnMgZm9yIGVhY2ggY2h1bmsgb2YgaWdub3JhYmxlCi0gICAgICogd2hpdGVzcGFjZSAoc3VjaCBhcyBhZGRpbmcgZGF0YSB0byBhIG5vZGUgb3IgYnVmZmVyLCBvciBwcmludGluZwotICAgICAqIGl0IHRvIGEgZmlsZSkuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGNoIFRoZSB3aGl0ZXNwYWNlIGNoYXJhY3RlcnMuCi0gICAgICogQHBhcmFtIHN0YXJ0IFRoZSBzdGFydCBwb3NpdGlvbiBpbiB0aGUgY2hhcmFjdGVyIGFycmF5LgotICAgICAqIEBwYXJhbSBsZW5ndGggVGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHVzZSBmcm9tIHRoZQotICAgICAqICAgICAgICAgICAgICAgY2hhcmFjdGVyIGFycmF5LgotICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNpZ25vcmFibGVXaGl0ZXNwYWNlCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgaWdub3JhYmxlV2hpdGVzcGFjZSAoY2hhciBjaFtdLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIC8vIG5vIG9wCi0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBhIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24uCi0gICAgICoKLSAgICAgKiA8cD5CeSBkZWZhdWx0LCBkbyBub3RoaW5nLiAgQXBwbGljYXRpb24gd3JpdGVycyBtYXkgb3ZlcnJpZGUgdGhpcwotICAgICAqIG1ldGhvZCBpbiBhIHN1YmNsYXNzIHRvIHRha2Ugc3BlY2lmaWMgYWN0aW9ucyBmb3IgZWFjaAotICAgICAqIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24sIHN1Y2ggYXMgc2V0dGluZyBzdGF0dXMgdmFyaWFibGVzIG9yCi0gICAgICogaW52b2tpbmcgb3RoZXIgbWV0aG9kcy48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gdGFyZ2V0IFRoZSBwcm9jZXNzaW5nIGluc3RydWN0aW9uIHRhcmdldC4KLSAgICAgKiBAcGFyYW0gZGF0YSBUaGUgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiBkYXRhLCBvciBudWxsIGlmCi0gICAgICogICAgICAgICAgICAgbm9uZSBpcyBzdXBwbGllZC4KLSAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjcHJvY2Vzc2luZ0luc3RydWN0aW9uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcHJvY2Vzc2luZ0luc3RydWN0aW9uIChTdHJpbmcgdGFyZ2V0LCBTdHJpbmcgZGF0YSkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgLy8gbm8gb3AKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGEgc2tpcHBlZCBlbnRpdHkuCi0gICAgICoKLSAgICAgKiA8cD5CeSBkZWZhdWx0LCBkbyBub3RoaW5nLiAgQXBwbGljYXRpb24gd3JpdGVycyBtYXkgb3ZlcnJpZGUgdGhpcwotICAgICAqIG1ldGhvZCBpbiBhIHN1YmNsYXNzIHRvIHRha2Ugc3BlY2lmaWMgYWN0aW9ucyBmb3IgZWFjaAotICAgICAqIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24sIHN1Y2ggYXMgc2V0dGluZyBzdGF0dXMgdmFyaWFibGVzIG9yCi0gICAgICogaW52b2tpbmcgb3RoZXIgbWV0aG9kcy48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgc2tpcHBlZCBlbnRpdHkuCi0gICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI3Byb2Nlc3NpbmdJbnN0cnVjdGlvbgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNraXBwZWRFbnRpdHkgKFN0cmluZyBuYW1lKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICAvLyBubyBvcAotICAgIH0KLQotCi0KLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotICAgIC8vIERlZmF1bHQgaW1wbGVtZW50YXRpb24gb2YgdGhlIEVycm9ySGFuZGxlciBpbnRlcmZhY2UuCi0gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLQotCi0gICAgLyoqCi0gICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgYSBwYXJzZXIgd2FybmluZy4KLSAgICAgKgotICAgICAqIDxwPlRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIGRvZXMgbm90aGluZy4gIEFwcGxpY2F0aW9uIHdyaXRlcnMKLSAgICAgKiBtYXkgb3ZlcnJpZGUgdGhpcyBtZXRob2QgaW4gYSBzdWJjbGFzcyB0byB0YWtlIHNwZWNpZmljIGFjdGlvbnMKLSAgICAgKiBmb3IgZWFjaCB3YXJuaW5nLCBzdWNoIGFzIGluc2VydGluZyB0aGUgbWVzc2FnZSBpbiBhIGxvZyBmaWxlIG9yCi0gICAgICogcHJpbnRpbmcgaXQgdG8gdGhlIGNvbnNvbGUuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGUgVGhlIHdhcm5pbmcgaW5mb3JtYXRpb24gZW5jb2RlZCBhcyBhbiBleGNlcHRpb24uCi0gICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkVycm9ySGFuZGxlciN3YXJuaW5nCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5TQVhQYXJzZUV4Y2VwdGlvbgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHdhcm5pbmcgKFNBWFBhcnNlRXhjZXB0aW9uIGUpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIC8vIG5vIG9wCi0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBhIHJlY292ZXJhYmxlIHBhcnNlciBlcnJvci4KLSAgICAgKgotICAgICAqIDxwPlRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIGRvZXMgbm90aGluZy4gIEFwcGxpY2F0aW9uIHdyaXRlcnMKLSAgICAgKiBtYXkgb3ZlcnJpZGUgdGhpcyBtZXRob2QgaW4gYSBzdWJjbGFzcyB0byB0YWtlIHNwZWNpZmljIGFjdGlvbnMKLSAgICAgKiBmb3IgZWFjaCBlcnJvciwgc3VjaCBhcyBpbnNlcnRpbmcgdGhlIG1lc3NhZ2UgaW4gYSBsb2cgZmlsZSBvcgotICAgICAqIHByaW50aW5nIGl0IHRvIHRoZSBjb25zb2xlLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlIFRoZSBlcnJvciBpbmZvcm1hdGlvbiBlbmNvZGVkIGFzIGFuIGV4Y2VwdGlvbi4KLSAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguRXJyb3JIYW5kbGVyI3dhcm5pbmcKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LlNBWFBhcnNlRXhjZXB0aW9uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZXJyb3IgKFNBWFBhcnNlRXhjZXB0aW9uIGUpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIC8vIG5vIG9wCi0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBSZXBvcnQgYSBmYXRhbCBYTUwgcGFyc2luZyBlcnJvci4KLSAgICAgKgotICAgICAqIDxwPlRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIHRocm93cyBhIFNBWFBhcnNlRXhjZXB0aW9uLgotICAgICAqIEFwcGxpY2F0aW9uIHdyaXRlcnMgbWF5IG92ZXJyaWRlIHRoaXMgbWV0aG9kIGluIGEgc3ViY2xhc3MgaWYKLSAgICAgKiB0aGV5IG5lZWQgdG8gdGFrZSBzcGVjaWZpYyBhY3Rpb25zIGZvciBlYWNoIGZhdGFsIGVycm9yIChzdWNoIGFzCi0gICAgICogY29sbGVjdGluZyBhbGwgb2YgdGhlIGVycm9ycyBpbnRvIGEgc2luZ2xlIHJlcG9ydCk6IGluIGFueSBjYXNlLAotICAgICAqIHRoZSBhcHBsaWNhdGlvbiBtdXN0IHN0b3AgYWxsIHJlZ3VsYXIgcHJvY2Vzc2luZyB3aGVuIHRoaXMKLSAgICAgKiBtZXRob2QgaXMgaW52b2tlZCwgc2luY2UgdGhlIGRvY3VtZW50IGlzIG5vIGxvbmdlciByZWxpYWJsZSwgYW5kCi0gICAgICogdGhlIHBhcnNlciBtYXkgbm8gbG9uZ2VyIHJlcG9ydCBwYXJzaW5nIGV2ZW50cy48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gZSBUaGUgZXJyb3IgaW5mb3JtYXRpb24gZW5jb2RlZCBhcyBhbiBleGNlcHRpb24uCi0gICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkVycm9ySGFuZGxlciNmYXRhbEVycm9yCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5TQVhQYXJzZUV4Y2VwdGlvbgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGZhdGFsRXJyb3IgKFNBWFBhcnNlRXhjZXB0aW9uIGUpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIHRocm93IGU7Ci0gICAgfQotCi19Ci0KLS8vIGVuZCBvZiBEZWZhdWx0SGFuZGxlci5qYXZhCmRpZmYgLS1naXQgYS9zcmMvb3JnL3htbC9zYXgvaGVscGVycy9Mb2NhdG9ySW1wbC5qYXZhIGIvc3JjL29yZy94bWwvc2F4L2hlbHBlcnMvTG9jYXRvckltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZjRjNTM4Yi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3htbC9zYXgvaGVscGVycy9Mb2NhdG9ySW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjM4ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDAsIDIwMDUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8vIFNBWCBkZWZhdWx0IGltcGxlbWVudGF0aW9uIGZvciBMb2NhdG9yLgotLy8gaHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZwotLy8gTm8gd2FycmFudHk7IG5vIGNvcHlyaWdodCAtLSB1c2UgdGhpcyBhcyB5b3Ugd2lsbC4KLS8vICRJZDogTG9jYXRvckltcGwuamF2YSx2IDEuMiAyMDA0LzExLzAzIDIyOjUzOjA5IGpzdXR0b3IgRXhwICQKLQotcGFja2FnZSBvcmcueG1sLnNheC5oZWxwZXJzOwotCi1pbXBvcnQgb3JnLnhtbC5zYXguTG9jYXRvcjsKLQotCi0vKioKLSAqIFByb3ZpZGUgYW4gb3B0aW9uYWwgY29udmVuaWVuY2UgaW1wbGVtZW50YXRpb24gb2YgTG9jYXRvci4KLSAqCi0gKiA8YmxvY2txdW90ZT4KLSAqIDxlbT5UaGlzIG1vZHVsZSwgYm90aCBzb3VyY2UgY29kZSBhbmQgZG9jdW1lbnRhdGlvbiwgaXMgaW4gdGhlCi0gKiBQdWJsaWMgRG9tYWluLCBhbmQgY29tZXMgd2l0aCA8c3Ryb25nPk5PIFdBUlJBTlRZPC9zdHJvbmc+LjwvZW0+Ci0gKiBTZWUgPGEgaHJlZj0naHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZyc+aHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZzwvYT4KLSAqIGZvciBmdXJ0aGVyIGluZm9ybWF0aW9uLgotICogPC9ibG9ja3F1b3RlPgotICoKLSAqIDxwPlRoaXMgY2xhc3MgaXMgYXZhaWxhYmxlIG1haW5seSBmb3IgYXBwbGljYXRpb24gd3JpdGVycywgd2hvCi0gKiBjYW4gdXNlIGl0IHRvIG1ha2UgYSBwZXJzaXN0ZW50IHNuYXBzaG90IG9mIGEgbG9jYXRvciBhdCBhbnkKLSAqIHBvaW50IGR1cmluZyBhIGRvY3VtZW50IHBhcnNlOjwvcD4KLSAqCi0gKiA8cHJlPgotICogTG9jYXRvciBsb2NhdG9yOwotICogTG9jYXRvciBzdGFydGxvYzsKLSAqCi0gKiBwdWJsaWMgdm9pZCBzZXRMb2NhdG9yIChMb2NhdG9yIGxvY2F0b3IpCi0gKiB7Ci0gKiAgICAgICAgIC8vIG5vdGUgdGhlIGxvY2F0b3IKLSAqICAgdGhpcy5sb2NhdG9yID0gbG9jYXRvcjsKLSAqIH0KLSAqCi0gKiBwdWJsaWMgdm9pZCBzdGFydERvY3VtZW50ICgpCi0gKiB7Ci0gKiAgICAgICAgIC8vIHNhdmUgdGhlIGxvY2F0aW9uIG9mIHRoZSBzdGFydCBvZiB0aGUgZG9jdW1lbnQKLSAqICAgICAgICAgLy8gZm9yIGZ1dHVyZSB1c2UuCi0gKiAgIExvY2F0b3Igc3RhcnRsb2MgPSBuZXcgTG9jYXRvckltcGwobG9jYXRvcik7Ci0gKiB9Ci0gKjwvcHJlPgotICoKLSAqIDxwPk5vcm1hbGx5LCBwYXJzZXIgd3JpdGVycyB3aWxsIG5vdCB1c2UgdGhpcyBjbGFzcywgc2luY2UgaXQKLSAqIGlzIG1vcmUgZWZmaWNpZW50IHRvIHByb3ZpZGUgbG9jYXRpb24gaW5mb3JtYXRpb24gb25seSB3aGVuCi0gKiByZXF1ZXN0ZWQsIHJhdGhlciB0aGFuIGNvbnN0YW50bHkgdXBkYXRpbmcgYSBMb2NhdG9yIG9iamVjdC48L3A+Ci0gKgotICogQHNpbmNlIFNBWCAxLjAKLSAqIEBhdXRob3IgRGF2aWQgTWVnZ2luc29uCi0gKiBAc2VlIG9yZy54bWwuc2F4LkxvY2F0b3IgTG9jYXRvcgotICovCi1wdWJsaWMgY2xhc3MgTG9jYXRvckltcGwgaW1wbGVtZW50cyBMb2NhdG9yCi17Ci0KLQotICAgIC8qKgotICAgICAqIFplcm8tYXJndW1lbnQgY29uc3RydWN0b3IuCi0gICAgICoKLSAgICAgKiA8cD5UaGlzIHdpbGwgbm90IG5vcm1hbGx5IGJlIHVzZWZ1bCwgc2luY2UgdGhlIG1haW4gcHVycG9zZQotICAgICAqIG9mIHRoaXMgY2xhc3MgaXMgdG8gbWFrZSBhIHNuYXBzaG90IG9mIGFuIGV4aXN0aW5nIExvY2F0b3IuPC9wPgotICAgICAqLwotICAgIHB1YmxpYyBMb2NhdG9ySW1wbCAoKQotICAgIHsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIENvcHkgY29uc3RydWN0b3IuCi0gICAgICoKLSAgICAgKiA8cD5DcmVhdGUgYSBwZXJzaXN0ZW50IGNvcHkgb2YgdGhlIGN1cnJlbnQgc3RhdGUgb2YgYSBsb2NhdG9yLgotICAgICAqIFdoZW4gdGhlIG9yaWdpbmFsIGxvY2F0b3IgY2hhbmdlcywgdGhpcyBjb3B5IHdpbGwgc3RpbGwga2VlcAotICAgICAqIHRoZSBvcmlnaW5hbCB2YWx1ZXMgKGFuZCBpdCBjYW4gYmUgdXNlZCBvdXRzaWRlIHRoZSBzY29wZSBvZgotICAgICAqIERvY3VtZW50SGFuZGxlciBtZXRob2RzKS48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gbG9jYXRvciBUaGUgbG9jYXRvciB0byBjb3B5LgotICAgICAqLwotICAgIHB1YmxpYyBMb2NhdG9ySW1wbCAoTG9jYXRvciBsb2NhdG9yKQotICAgIHsKLSAgICAgICAgc2V0UHVibGljSWQobG9jYXRvci5nZXRQdWJsaWNJZCgpKTsKLSAgICAgICAgc2V0U3lzdGVtSWQobG9jYXRvci5nZXRTeXN0ZW1JZCgpKTsKLSAgICAgICAgc2V0TGluZU51bWJlcihsb2NhdG9yLmdldExpbmVOdW1iZXIoKSk7Ci0gICAgICAgIHNldENvbHVtbk51bWJlcihsb2NhdG9yLmdldENvbHVtbk51bWJlcigpKTsKLSAgICB9Ci0KLQotCi0gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLSAgICAvLyBJbXBsZW1lbnRhdGlvbiBvZiBvcmcueG1sLnNheC5Mb2NhdG9yCi0gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSBzYXZlZCBwdWJsaWMgaWRlbnRpZmllci4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIHB1YmxpYyBpZGVudGlmaWVyIGFzIGEgc3RyaW5nLCBvciBudWxsIGlmIG5vbmUKLSAgICAgKiAgICAgICAgIGlzIGF2YWlsYWJsZS4KLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkxvY2F0b3IjZ2V0UHVibGljSWQKLSAgICAgKiBAc2VlICNzZXRQdWJsaWNJZAotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0UHVibGljSWQgKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBwdWJsaWNJZDsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFJldHVybiB0aGUgc2F2ZWQgc3lzdGVtIGlkZW50aWZpZXIuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBzeXN0ZW0gaWRlbnRpZmllciBhcyBhIHN0cmluZywgb3IgbnVsbCBpZiBub25lCi0gICAgICogICAgICAgICBpcyBhdmFpbGFibGUuCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5Mb2NhdG9yI2dldFN5c3RlbUlkCi0gICAgICogQHNlZSAjc2V0U3lzdGVtSWQKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFN5c3RlbUlkICgpCi0gICAgewotICAgICAgICByZXR1cm4gc3lzdGVtSWQ7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIHNhdmVkIGxpbmUgbnVtYmVyICgxLWJhc2VkKS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIGxpbmUgbnVtYmVyIGFzIGFuIGludGVnZXIsIG9yIC0xIGlmIG5vbmUgaXMgYXZhaWxhYmxlLgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguTG9jYXRvciNnZXRMaW5lTnVtYmVyCi0gICAgICogQHNlZSAjc2V0TGluZU51bWJlcgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0TGluZU51bWJlciAoKQotICAgIHsKLSAgICAgICAgcmV0dXJuIGxpbmVOdW1iZXI7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIHNhdmVkIGNvbHVtbiBudW1iZXIgKDEtYmFzZWQpLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgY29sdW1uIG51bWJlciBhcyBhbiBpbnRlZ2VyLCBvciAtMSBpZiBub25lIGlzIGF2YWlsYWJsZS4KLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkxvY2F0b3IjZ2V0Q29sdW1uTnVtYmVyCi0gICAgICogQHNlZSAjc2V0Q29sdW1uTnVtYmVyCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRDb2x1bW5OdW1iZXIgKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBjb2x1bW5OdW1iZXI7Ci0gICAgfQotCi0KLQotICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0gICAgLy8gU2V0dGVycyBmb3IgdGhlIHByb3BlcnRpZXMgKG5vdCBpbiBvcmcueG1sLnNheC5Mb2NhdG9yKQotICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0KLQotICAgIC8qKgotICAgICAqIFNldCB0aGUgcHVibGljIGlkZW50aWZpZXIgZm9yIHRoaXMgbG9jYXRvci4KLSAgICAgKgotICAgICAqIEBwYXJhbSBwdWJsaWNJZCBUaGUgbmV3IHB1YmxpYyBpZGVudGlmaWVyLCBvciBudWxsCi0gICAgICogICAgICAgIGlmIG5vbmUgaXMgYXZhaWxhYmxlLgotICAgICAqIEBzZWUgI2dldFB1YmxpY0lkCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0UHVibGljSWQgKFN0cmluZyBwdWJsaWNJZCkKLSAgICB7Ci0gICAgICAgIHRoaXMucHVibGljSWQgPSBwdWJsaWNJZDsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFNldCB0aGUgc3lzdGVtIGlkZW50aWZpZXIgZm9yIHRoaXMgbG9jYXRvci4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzeXN0ZW1JZCBUaGUgbmV3IHN5c3RlbSBpZGVudGlmaWVyLCBvciBudWxsCi0gICAgICogICAgICAgIGlmIG5vbmUgaXMgYXZhaWxhYmxlLgotICAgICAqIEBzZWUgI2dldFN5c3RlbUlkCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0U3lzdGVtSWQgKFN0cmluZyBzeXN0ZW1JZCkKLSAgICB7Ci0gICAgICAgIHRoaXMuc3lzdGVtSWQgPSBzeXN0ZW1JZDsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFNldCB0aGUgbGluZSBudW1iZXIgZm9yIHRoaXMgbG9jYXRvciAoMS1iYXNlZCkuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbGluZU51bWJlciBUaGUgbGluZSBudW1iZXIsIG9yIC0xIGlmIG5vbmUgaXMgYXZhaWxhYmxlLgotICAgICAqIEBzZWUgI2dldExpbmVOdW1iZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRMaW5lTnVtYmVyIChpbnQgbGluZU51bWJlcikKLSAgICB7Ci0gICAgICAgIHRoaXMubGluZU51bWJlciA9IGxpbmVOdW1iZXI7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIGNvbHVtbiBudW1iZXIgZm9yIHRoaXMgbG9jYXRvciAoMS1iYXNlZCkuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29sdW1uTnVtYmVyIFRoZSBjb2x1bW4gbnVtYmVyLCBvciAtMSBpZiBub25lIGlzIGF2YWlsYWJsZS4KLSAgICAgKiBAc2VlICNnZXRDb2x1bW5OdW1iZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRDb2x1bW5OdW1iZXIgKGludCBjb2x1bW5OdW1iZXIpCi0gICAgewotICAgICAgICB0aGlzLmNvbHVtbk51bWJlciA9IGNvbHVtbk51bWJlcjsKLSAgICB9Ci0KLQotCi0gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLSAgICAvLyBJbnRlcm5hbCBzdGF0ZS4KLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotCi0gICAgcHJpdmF0ZSBTdHJpbmcgcHVibGljSWQ7Ci0gICAgcHJpdmF0ZSBTdHJpbmcgc3lzdGVtSWQ7Ci0gICAgcHJpdmF0ZSBpbnQgbGluZU51bWJlcjsKLSAgICBwcml2YXRlIGludCBjb2x1bW5OdW1iZXI7Ci0KLX0KLQotLy8gZW5kIG9mIExvY2F0b3JJbXBsLmphdmEKZGlmZiAtLWdpdCBhL3NyYy9vcmcveG1sL3NheC9oZWxwZXJzL05hbWVzcGFjZVN1cHBvcnQuamF2YSBiL3NyYy9vcmcveG1sL3NheC9oZWxwZXJzL05hbWVzcGFjZVN1cHBvcnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZjhlZjZlMy4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3htbC9zYXgvaGVscGVycy9OYW1lc3BhY2VTdXBwb3J0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4NTAgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwMCwgMjAxNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotLy8gTmFtZXNwYWNlU3VwcG9ydC5qYXZhIC0gZ2VuZXJpYyBOYW1lc3BhY2Ugc3VwcG9ydCBmb3IgU0FYLgotLy8gaHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZwotLy8gV3JpdHRlbiBieSBEYXZpZCBNZWdnaW5zb24KLS8vIFRoaXMgY2xhc3MgaXMgaW4gdGhlIFB1YmxpYyBEb21haW4uICBOTyBXQVJSQU5UWSEKLS8vICRJZDogTmFtZXNwYWNlU3VwcG9ydC5qYXZhLHYgMS41IDIwMDQvMTEvMDMgMjI6NTM6MDkganN1dHRvciBFeHAgJAotCi1wYWNrYWdlIG9yZy54bWwuc2F4LmhlbHBlcnM7Ci0KLWltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwotaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKLWltcG9ydCBqYXZhLnV0aWwuRW1wdHlTdGFja0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247Ci1pbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7Ci1pbXBvcnQgamF2YS51dGlsLkxpc3Q7Ci1pbXBvcnQgamF2YS51dGlsLk1hcDsKLQotCi0vKioKLSAqIEVuY2Fwc3VsYXRlIE5hbWVzcGFjZSBsb2dpYyBmb3IgdXNlIGJ5IGFwcGxpY2F0aW9ucyB1c2luZyBTQVgsCi0gKiBvciBpbnRlcm5hbGx5IGJ5IFNBWCBkcml2ZXJzLgotICoKLSAqIDxibG9ja3F1b3RlPgotICogPGVtPlRoaXMgbW9kdWxlLCBib3RoIHNvdXJjZSBjb2RlIGFuZCBkb2N1bWVudGF0aW9uLCBpcyBpbiB0aGUKLSAqIFB1YmxpYyBEb21haW4sIGFuZCBjb21lcyB3aXRoIDxzdHJvbmc+Tk8gV0FSUkFOVFk8L3N0cm9uZz4uPC9lbT4KLSAqIFNlZSA8YSBocmVmPSdodHRwOi8vd3d3LnNheHByb2plY3Qub3JnJz5odHRwOi8vd3d3LnNheHByb2plY3Qub3JnPC9hPgotICogZm9yIGZ1cnRoZXIgaW5mb3JtYXRpb24uCi0gKiA8L2Jsb2NrcXVvdGU+Ci0gKgotICogPHA+VGhpcyBjbGFzcyBlbmNhcHN1bGF0ZXMgdGhlIGxvZ2ljIG9mIE5hbWVzcGFjZSBwcm9jZXNzaW5nOiBpdAotICogdHJhY2tzIHRoZSBkZWNsYXJhdGlvbnMgY3VycmVudGx5IGluIGZvcmNlIGZvciBlYWNoIGNvbnRleHQgYW5kCi0gKiBhdXRvbWF0aWNhbGx5IHByb2Nlc3NlcyBxdWFsaWZpZWQgWE1MIG5hbWVzIGludG8gdGhlaXIgTmFtZXNwYWNlCi0gKiBwYXJ0czsgaXQgY2FuIGFsc28gYmUgdXNlZCBpbiByZXZlcnNlIGZvciBnZW5lcmF0aW5nIFhNTCBxbmFtZXMKLSAqIGZyb20gTmFtZXNwYWNlcy48L3A+Ci0gKgotICogPHA+TmFtZXNwYWNlIHN1cHBvcnQgb2JqZWN0cyBhcmUgcmV1c2FibGUsIGJ1dCB0aGUgcmVzZXQgbWV0aG9kCi0gKiBtdXN0IGJlIGludm9rZWQgYmV0d2VlbiBlYWNoIHNlc3Npb24uPC9wPgotICoKLSAqIDxwPkhlcmUgaXMgYSBzaW1wbGUgc2Vzc2lvbjo8L3A+Ci0gKgotICogPHByZT4KLSAqIFN0cmluZyBwYXJ0c1tdID0gbmV3IFN0cmluZ1szXTsKLSAqIE5hbWVzcGFjZVN1cHBvcnQgc3VwcG9ydCA9IG5ldyBOYW1lc3BhY2VTdXBwb3J0KCk7Ci0gKgotICogc3VwcG9ydC5wdXNoQ29udGV4dCgpOwotICogc3VwcG9ydC5kZWNsYXJlUHJlZml4KCIiLCAiaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCIpOwotICogc3VwcG9ydC5kZWNsYXJlUHJlZml4KCJkYyIsICJodHRwOi8vd3d3LnB1cmwub3JnL2RjIyIpOwotICoKLSAqIHBhcnRzID0gc3VwcG9ydC5wcm9jZXNzTmFtZSgicCIsIHBhcnRzLCBmYWxzZSk7Ci0gKiBTeXN0ZW0ub3V0LnByaW50bG4oIk5hbWVzcGFjZSBVUkk6ICIgKyBwYXJ0c1swXSk7Ci0gKiBTeXN0ZW0ub3V0LnByaW50bG4oIkxvY2FsIG5hbWU6ICIgKyBwYXJ0c1sxXSk7Ci0gKiBTeXN0ZW0ub3V0LnByaW50bG4oIlJhdyBuYW1lOiAiICsgcGFydHNbMl0pOwotICoKLSAqIHBhcnRzID0gc3VwcG9ydC5wcm9jZXNzTmFtZSgiZGM6dGl0bGUiLCBwYXJ0cywgZmFsc2UpOwotICogU3lzdGVtLm91dC5wcmludGxuKCJOYW1lc3BhY2UgVVJJOiAiICsgcGFydHNbMF0pOwotICogU3lzdGVtLm91dC5wcmludGxuKCJMb2NhbCBuYW1lOiAiICsgcGFydHNbMV0pOwotICogU3lzdGVtLm91dC5wcmludGxuKCJSYXcgbmFtZTogIiArIHBhcnRzWzJdKTsKLSAqCi0gKiBzdXBwb3J0LnBvcENvbnRleHQoKTsKLSAqIDwvcHJlPgotICoKLSAqIDxwPk5vdGUgdGhhdCB0aGlzIGNsYXNzIGlzIG9wdGltaXplZCBmb3IgdGhlIHVzZSBjYXNlIHdoZXJlIG1vc3QKLSAqIGVsZW1lbnRzIGRvIG5vdCBjb250YWluIE5hbWVzcGFjZSBkZWNsYXJhdGlvbnM6IGlmIHRoZSBzYW1lCi0gKiBwcmVmaXgvVVJJIG1hcHBpbmcgaXMgcmVwZWF0ZWQgZm9yIGVhY2ggY29udGV4dCAoZm9yIGV4YW1wbGUpLCB0aGlzCi0gKiBjbGFzcyB3aWxsIGJlIHNvbWV3aGF0IGxlc3MgZWZmaWNpZW50LjwvcD4KLSAqCi0gKiA8cD5BbHRob3VnaCBTQVggZHJpdmVycyAocGFyc2VycykgbWF5IGNob29zZSB0byB1c2UgdGhpcyBjbGFzcyB0bwotICogaW1wbGVtZW50IG5hbWVzcGFjZSBoYW5kbGluZywgdGhleSBhcmUgbm90IHJlcXVpcmVkIHRvIGRvIHNvLgotICogQXBwbGljYXRpb25zIG11c3QgdHJhY2sgbmFtZXNwYWNlIGluZm9ybWF0aW9uIHRoZW1zZWx2ZXMgaWYgdGhleQotICogd2FudCB0byB1c2UgbmFtZXNwYWNlIGluZm9ybWF0aW9uLgotICoKLSAqIEBzaW5jZSBTQVggMi4wCi0gKiBAYXV0aG9yIERhdmlkIE1lZ2dpbnNvbgotICovCi1wdWJsaWMgY2xhc3MgTmFtZXNwYWNlU3VwcG9ydAotewotCi0KLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotICAgIC8vIENvbnN0YW50cy4KLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotCi0KLSAgICAvKioKLSAgICAgKiBUaGUgWE1MIE5hbWVzcGFjZSBVUkkgYXMgYSBjb25zdGFudC4KLSAgICAgKiBUaGUgdmFsdWUgaXMgPGNvZGU+aHR0cDovL3d3dy53My5vcmcvWE1MLzE5OTgvbmFtZXNwYWNlPC9jb2RlPgotICAgICAqIGFzIGRlZmluZWQgaW4gdGhlICJOYW1lc3BhY2VzIGluIFhNTCIgKiByZWNvbW1lbmRhdGlvbi4KLSAgICAgKgotICAgICAqIDxwPlRoaXMgaXMgdGhlIE5hbWVzcGFjZSBVUkkgdGhhdCBpcyBhdXRvbWF0aWNhbGx5IG1hcHBlZAotICAgICAqIHRvIHRoZSAieG1sIiBwcmVmaXguPC9wPgotICAgICAqLwotICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgU3RyaW5nIFhNTE5TID0KLSAgICAgICAgImh0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZSI7Ci0KLQotICAgIC8qKgotICAgICAqIFRoZSBuYW1lc3BhY2UgZGVjbGFyYXRpb24gVVJJIGFzIGEgY29uc3RhbnQuCi0gICAgICogVGhlIHZhbHVlIGlzIDxjb2RlPmh0dHA6Ly93d3cudzMub3JnL3htbG5zLzIwMDAvPC9jb2RlPiwgYXMgZGVmaW5lZAotICAgICAqIGluIGEgYmFja3dhcmRzLWluY29tcGF0aWJsZSBlcnJhdHVtIHRvIHRoZSAiTmFtZXNwYWNlcyBpbiBYTUwiCi0gICAgICogcmVjb21tZW5kYXRpb24uICBCZWNhdXNlIHRoYXQgZXJyYXR1bSBwb3N0ZGF0ZWQgU0FYMiwgU0FYMiBkZWZhdWx0cwotICAgICAqIHRvIHRoZSBvcmlnaW5hbCByZWNvbW1lbmRhdGlvbiwgYW5kIGRvZXMgbm90IG5vcm1hbGx5IHVzZSB0aGlzIFVSSS4KLSAgICAgKgotICAgICAqCi0gICAgICogPHA+VGhpcyBpcyB0aGUgTmFtZXNwYWNlIFVSSSB0aGF0IGlzIG9wdGlvbmFsbHkgYXBwbGllZCB0bwotICAgICAqIDxlbT54bWxuczwvZW0+IGFuZCA8ZW0+eG1sbnM6KjwvZW0+IGF0dHJpYnV0ZXMsIHdoaWNoIGFyZSB1c2VkIHRvCi0gICAgICogZGVjbGFyZSBuYW1lc3BhY2VzLiAgPC9wPgotICAgICAqCi0gICAgICogQHNpbmNlIFNBWCAyLjFhbHBoYQotICAgICAqIEBzZWUgI3NldE5hbWVzcGFjZURlY2xVcmlzCi0gICAgICogQHNlZSAjaXNOYW1lc3BhY2VEZWNsVXJpcwotICAgICAqLwotICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgU3RyaW5nIE5TREVDTCA9Ci0gICAgICAgICJodHRwOi8vd3d3LnczLm9yZy94bWxucy8yMDAwLyI7Ci0KLQotICAgIC8qKgotICAgICAqIEFuIGVtcHR5IGVudW1lcmF0aW9uLgotICAgICAqLwotICAgIHByaXZhdGUgZmluYWwgc3RhdGljIEVudW1lcmF0aW9uIEVNUFRZX0VOVU1FUkFUSU9OID0KLSAgICAgICAgICAgIENvbGxlY3Rpb25zLmVudW1lcmF0aW9uKG5ldyBBcnJheUxpc3Q8U3RyaW5nPigpKTsKLQotCi0gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLSAgICAvLyBDb25zdHJ1Y3Rvci4KLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotCi0KLSAgICAvKioKLSAgICAgKiBDcmVhdGUgYSBuZXcgTmFtZXNwYWNlIHN1cHBvcnQgb2JqZWN0LgotICAgICAqLwotICAgIHB1YmxpYyBOYW1lc3BhY2VTdXBwb3J0ICgpCi0gICAgewotICAgICAgICByZXNldCgpOwotICAgIH0KLQotCi0KLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotICAgIC8vIENvbnRleHQgbWFuYWdlbWVudC4KLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotCi0KLSAgICAvKioKLSAgICAgKiBSZXNldCB0aGlzIE5hbWVzcGFjZSBzdXBwb3J0IG9iamVjdCBmb3IgcmV1c2UuCi0gICAgICoKLSAgICAgKiA8cD5JdCBpcyBuZWNlc3NhcnkgdG8gaW52b2tlIHRoaXMgbWV0aG9kIGJlZm9yZSByZXVzaW5nIHRoZQotICAgICAqIE5hbWVzcGFjZSBzdXBwb3J0IG9iamVjdCBmb3IgYSBuZXcgc2Vzc2lvbi4gIElmIG5hbWVzcGFjZQotICAgICAqIGRlY2xhcmF0aW9uIFVSSXMgYXJlIHRvIGJlIHN1cHBvcnRlZCwgdGhhdCBmbGFnIG11c3QgYWxzbwotICAgICAqIGJlIHNldCB0byBhIG5vbi1kZWZhdWx0IHZhbHVlLgotICAgICAqIDwvcD4KLSAgICAgKgotICAgICAqIEBzZWUgI3NldE5hbWVzcGFjZURlY2xVcmlzCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcmVzZXQgKCkKLSAgICB7Ci0gICAgICAgIGNvbnRleHRzID0gbmV3IENvbnRleHRbMzJdOwotICAgICAgICBuYW1lc3BhY2VEZWNsVXJpcyA9IGZhbHNlOwotICAgICAgICBjb250ZXh0UG9zID0gMDsKLSAgICAgICAgY29udGV4dHNbY29udGV4dFBvc10gPSBjdXJyZW50Q29udGV4dCA9IG5ldyBDb250ZXh0KCk7Ci0gICAgICAgIGN1cnJlbnRDb250ZXh0LmRlY2xhcmVQcmVmaXgoInhtbCIsIFhNTE5TKTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFN0YXJ0IGEgbmV3IE5hbWVzcGFjZSBjb250ZXh0LgotICAgICAqIFRoZSBuZXcgY29udGV4dCB3aWxsIGF1dG9tYXRpY2FsbHkgaW5oZXJpdAotICAgICAqIHRoZSBkZWNsYXJhdGlvbnMgb2YgaXRzIHBhcmVudCBjb250ZXh0LCBidXQgaXQgd2lsbCBhbHNvIGtlZXAKLSAgICAgKiB0cmFjayBvZiB3aGljaCBkZWNsYXJhdGlvbnMgd2VyZSBtYWRlIHdpdGhpbiB0aGlzIGNvbnRleHQuCi0gICAgICoKLSAgICAgKiA8cD5FdmVudCBjYWxsYmFjayBjb2RlIHNob3VsZCBzdGFydCBhIG5ldyBjb250ZXh0IG9uY2UgcGVyIGVsZW1lbnQuCi0gICAgICogVGhpcyBtZWFucyBiZWluZyByZWFkeSB0byBjYWxsIHRoaXMgaW4gZWl0aGVyIG9mIHR3byBwbGFjZXMuCi0gICAgICogRm9yIGVsZW1lbnRzIHRoYXQgZG9uJ3QgaW5jbHVkZSBuYW1lc3BhY2UgZGVjbGFyYXRpb25zLCB0aGUKLSAgICAgKiA8ZW0+Q29udGVudEhhbmRsZXIuc3RhcnRFbGVtZW50KCk8L2VtPiBjYWxsYmFjayBpcyB0aGUgcmlnaHQgcGxhY2UuCi0gICAgICogRm9yIGVsZW1lbnRzIHdpdGggc3VjaCBhIGRlY2xhcmF0aW9uLCBpdCdkIGRvbmUgaW4gdGhlIGZpcnN0Ci0gICAgICogPGVtPkNvbnRlbnRIYW5kbGVyLnN0YXJ0UHJlZml4TWFwcGluZygpPC9lbT4gY2FsbGJhY2suCi0gICAgICogQSBib29sZWFuIGZsYWcgY2FuIGJlIHVzZWQgdG8KLSAgICAgKiB0cmFjayB3aGV0aGVyIGEgY29udGV4dCBoYXMgYmVlbiBzdGFydGVkIHlldC4gIFdoZW4gZWl0aGVyIG9mCi0gICAgICogdGhvc2UgbWV0aG9kcyBpcyBjYWxsZWQsIGl0IGNoZWNrcyB0aGUgZmxhZyB0byBzZWUgaWYgYSBuZXcgY29udGV4dAotICAgICAqIG5lZWRzIHRvIGJlIHN0YXJ0ZWQuICBJZiBzbywgaXQgc3RhcnRzIHRoZSBjb250ZXh0IGFuZCBzZXRzIHRoZQotICAgICAqIGZsYWcuICBBZnRlciA8ZW0+Q29udGVudEhhbmRsZXIuc3RhcnRFbGVtZW50KCk8L2VtPgotICAgICAqIGRvZXMgdGhhdCwgaXQgYWx3YXlzIGNsZWFycyB0aGUgZmxhZy4KLSAgICAgKgotICAgICAqIDxwPk5vcm1hbGx5LCBTQVggZHJpdmVycyB3b3VsZCBwdXNoIGEgbmV3IGNvbnRleHQgYXQgdGhlIGJlZ2lubmluZwotICAgICAqIG9mIGVhY2ggWE1MIGVsZW1lbnQuICBUaGVuIHRoZXkgcGVyZm9ybSBhIGZpcnN0IHBhc3Mgb3ZlciB0aGUKLSAgICAgKiBhdHRyaWJ1dGVzIHRvIHByb2Nlc3MgYWxsIG5hbWVzcGFjZSBkZWNsYXJhdGlvbnMsIG1ha2luZwotICAgICAqIDxlbT5Db250ZW50SGFuZGxlci5zdGFydFByZWZpeE1hcHBpbmcoKTwvZW0+IGNhbGxiYWNrcy4KLSAgICAgKiBUaGVuIGEgc2Vjb25kIHBhc3MgaXMgbWFkZSwgdG8gZGV0ZXJtaW5lIHRoZSBuYW1lc3BhY2UtcXVhbGlmaWVkCi0gICAgICogbmFtZXMgZm9yIGFsbCBhdHRyaWJ1dGVzIGFuZCBmb3IgdGhlIGVsZW1lbnQgbmFtZS4KLSAgICAgKiBGaW5hbGx5IGFsbCB0aGUgaW5mb3JtYXRpb24gZm9yIHRoZQotICAgICAqIDxlbT5Db250ZW50SGFuZGxlci5zdGFydEVsZW1lbnQoKTwvZW0+IGNhbGxiYWNrIGlzIGF2YWlsYWJsZSwKLSAgICAgKiBzbyBpdCBjYW4gdGhlbiBiZSBtYWRlLgotICAgICAqCi0gICAgICogPHA+VGhlIE5hbWVzcGFjZSBzdXBwb3J0IG9iamVjdCBhbHdheXMgc3RhcnRzIHdpdGggYSBiYXNlIGNvbnRleHQKLSAgICAgKiBhbHJlYWR5IGluIGZvcmNlOiBpbiB0aGlzIGNvbnRleHQsIG9ubHkgdGhlICJ4bWwiIHByZWZpeCBpcwotICAgICAqIGRlY2xhcmVkLjwvcD4KLSAgICAgKgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIKLSAgICAgKiBAc2VlICNwb3BDb250ZXh0Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgcHVzaENvbnRleHQgKCkKLSAgICB7Ci0gICAgICAgIGludCBtYXggPSBjb250ZXh0cy5sZW5ndGg7Ci0KLSAgICAgICAgY29udGV4dFBvcysrOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEV4dGVuZCB0aGUgYXJyYXkgaWYgbmVjZXNzYXJ5Ci0gICAgICAgIGlmIChjb250ZXh0UG9zID49IG1heCkgewotICAgICAgICAgICAgQ29udGV4dCBuZXdDb250ZXh0c1tdID0gbmV3IENvbnRleHRbbWF4KjJdOwotICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShjb250ZXh0cywgMCwgbmV3Q29udGV4dHMsIDAsIG1heCk7Ci0gICAgICAgICAgICBtYXggKj0gMjsKLSAgICAgICAgICAgIGNvbnRleHRzID0gbmV3Q29udGV4dHM7Ci0gICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBBbGxvY2F0ZSB0aGUgY29udGV4dCBpZiBuZWNlc3NhcnkuCi0gICAgICAgIGN1cnJlbnRDb250ZXh0ID0gY29udGV4dHNbY29udGV4dFBvc107Ci0gICAgICAgIGlmIChjdXJyZW50Q29udGV4dCA9PSBudWxsKSB7Ci0gICAgICAgICAgICBjb250ZXh0c1tjb250ZXh0UG9zXSA9IGN1cnJlbnRDb250ZXh0ID0gbmV3IENvbnRleHQoKTsKLSAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNldCB0aGUgcGFyZW50LCBpZiBhbnkuCi0gICAgICAgIGlmIChjb250ZXh0UG9zID4gMCkgewotICAgICAgICAgICAgY3VycmVudENvbnRleHQuc2V0UGFyZW50KGNvbnRleHRzW2NvbnRleHRQb3MgLSAxXSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFJldmVydCB0byB0aGUgcHJldmlvdXMgTmFtZXNwYWNlIGNvbnRleHQuCi0gICAgICoKLSAgICAgKiA8cD5Ob3JtYWxseSwgeW91IHNob3VsZCBwb3AgdGhlIGNvbnRleHQgYXQgdGhlIGVuZCBvZiBlYWNoCi0gICAgICogWE1MIGVsZW1lbnQuICBBZnRlciBwb3BwaW5nIHRoZSBjb250ZXh0LCBhbGwgTmFtZXNwYWNlIHByZWZpeAotICAgICAqIG1hcHBpbmdzIHRoYXQgd2VyZSBwcmV2aW91c2x5IGluIGZvcmNlIGFyZSByZXN0b3JlZC48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5Zb3UgbXVzdCBub3QgYXR0ZW1wdCB0byBkZWNsYXJlIGFkZGl0aW9uYWwgTmFtZXNwYWNlCi0gICAgICogcHJlZml4ZXMgYWZ0ZXIgcG9wcGluZyBhIGNvbnRleHQsIHVubGVzcyB5b3UgcHVzaCBhbm90aGVyCi0gICAgICogY29udGV4dCBmaXJzdC48L3A+Ci0gICAgICoKLSAgICAgKiBAc2VlICNwdXNoQ29udGV4dAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHBvcENvbnRleHQgKCkKLSAgICB7Ci0gICAgICAgIGNvbnRleHRzW2NvbnRleHRQb3NdLmNsZWFyKCk7Ci0gICAgICAgIGNvbnRleHRQb3MtLTsKLSAgICAgICAgaWYgKGNvbnRleHRQb3MgPCAwKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgRW1wdHlTdGFja0V4Y2VwdGlvbigpOwotICAgICAgICB9Ci0gICAgICAgIGN1cnJlbnRDb250ZXh0ID0gY29udGV4dHNbY29udGV4dFBvc107Ci0gICAgfQotCi0KLQotICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0gICAgLy8gT3BlcmF0aW9ucyB3aXRoaW4gYSBjb250ZXh0LgotICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0KLQotICAgIC8qKgotICAgICAqIERlY2xhcmUgYSBOYW1lc3BhY2UgcHJlZml4LiAgQWxsIHByZWZpeGVzIG11c3QgYmUgZGVjbGFyZWQKLSAgICAgKiBiZWZvcmUgdGhleSBhcmUgcmVmZXJlbmNlZC4gIEZvciBleGFtcGxlLCBhIFNBWCBkcml2ZXIgKHBhcnNlcikKLSAgICAgKiB3b3VsZCBzY2FuIGFuIGVsZW1lbnQncyBhdHRyaWJ1dGVzCi0gICAgICogaW4gdHdvIHBhc3NlczogIGZpcnN0IGZvciBuYW1lc3BhY2UgZGVjbGFyYXRpb25zLAotICAgICAqIHRoZW4gYSBzZWNvbmQgcGFzcyB1c2luZyB7QGxpbmsgI3Byb2Nlc3NOYW1lIHByb2Nlc3NOYW1lKCl9IHRvCi0gICAgICogaW50ZXJwcmV0IHByZWZpeGVzIGFnYWluc3QgKHBvdGVudGlhbGx5IHJlZGVmaW5lZCkgcHJlZml4ZXMuCi0gICAgICoKLSAgICAgKiA8cD5UaGlzIG1ldGhvZCBkZWNsYXJlcyBhIHByZWZpeCBpbiB0aGUgY3VycmVudCBOYW1lc3BhY2UKLSAgICAgKiBjb250ZXh0OyB0aGUgcHJlZml4IHdpbGwgcmVtYWluIGluIGZvcmNlIHVudGlsIHRoaXMgY29udGV4dAotICAgICAqIGlzIHBvcHBlZCwgdW5sZXNzIGl0IGlzIHNoYWRvd2VkIGluIGEgZGVzY2VuZGFudCBjb250ZXh0LjwvcD4KLSAgICAgKgotICAgICAqIDxwPlRvIGRlY2xhcmUgdGhlIGRlZmF1bHQgZWxlbWVudCBOYW1lc3BhY2UsIHVzZSB0aGUgZW1wdHkgc3RyaW5nIGFzCi0gICAgICogdGhlIHByZWZpeC48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5Ob3RlIHRoYXQgdGhlcmUgaXMgYW4gYXN5bW1ldHJ5IGluIHRoaXMgbGlicmFyeToge0BsaW5rCi0gICAgICogI2dldFByZWZpeCBnZXRQcmVmaXh9IHdpbGwgbm90IHJldHVybiB0aGUgIiIgcHJlZml4LAotICAgICAqIGV2ZW4gaWYgeW91IGhhdmUgZGVjbGFyZWQgYSBkZWZhdWx0IGVsZW1lbnQgbmFtZXNwYWNlLgotICAgICAqIFRvIGNoZWNrIGZvciBhIGRlZmF1bHQgbmFtZXNwYWNlLAotICAgICAqIHlvdSBoYXZlIHRvIGxvb2sgaXQgdXAgZXhwbGljaXRseSB1c2luZyB7QGxpbmsgI2dldFVSSSBnZXRVUkl9LgotICAgICAqIFRoaXMgYXN5bW1ldHJ5IGV4aXN0cyB0byBtYWtlIGl0IGVhc2llciB0byBsb29rIHVwIHByZWZpeGVzCi0gICAgICogZm9yIGF0dHJpYnV0ZSBuYW1lcywgd2hlcmUgdGhlIGRlZmF1bHQgcHJlZml4IGlzIG5vdCBhbGxvd2VkLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBwcmVmaXggVGhlIHByZWZpeCB0byBkZWNsYXJlLCBvciB0aGUgZW1wdHkgc3RyaW5nIHRvCi0gICAgICogIGluZGljYXRlIHRoZSBkZWZhdWx0IGVsZW1lbnQgbmFtZXNwYWNlLiAgVGhpcyBtYXkgbmV2ZXIgaGF2ZQotICAgICAqICB0aGUgdmFsdWUgInhtbCIgb3IgInhtbG5zIi4KLSAgICAgKiBAcGFyYW0gdXJpIFRoZSBOYW1lc3BhY2UgVVJJIHRvIGFzc29jaWF0ZSB3aXRoIHRoZSBwcmVmaXguCi0gICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBwcmVmaXggd2FzIGxlZ2FsLCBmYWxzZSBvdGhlcndpc2UKLSAgICAgKgotICAgICAqIEBzZWUgI3Byb2Nlc3NOYW1lCi0gICAgICogQHNlZSAjZ2V0VVJJCi0gICAgICogQHNlZSAjZ2V0UHJlZml4Ci0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZGVjbGFyZVByZWZpeCAoU3RyaW5nIHByZWZpeCwgU3RyaW5nIHVyaSkKLSAgICB7Ci0gICAgICAgIGlmIChwcmVmaXguZXF1YWxzKCJ4bWwiKSB8fCBwcmVmaXguZXF1YWxzKCJ4bWxucyIpKSB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBjdXJyZW50Q29udGV4dC5kZWNsYXJlUHJlZml4KHByZWZpeCwgdXJpKTsKLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBQcm9jZXNzIGEgcmF3IFhNTCBxdWFsaWZpZWQgbmFtZSwgYWZ0ZXIgYWxsIGRlY2xhcmF0aW9ucyBpbiB0aGUKLSAgICAgKiBjdXJyZW50IGNvbnRleHQgaGF2ZSBiZWVuIGhhbmRsZWQgYnkge0BsaW5rICNkZWNsYXJlUHJlZml4Ci0gICAgICogZGVjbGFyZVByZWZpeCgpfS4KLSAgICAgKgotICAgICAqIDxwPlRoaXMgbWV0aG9kIHByb2Nlc3NlcyBhIHJhdyBYTUwgcXVhbGlmaWVkIG5hbWUgaW4gdGhlCi0gICAgICogY3VycmVudCBjb250ZXh0IGJ5IHJlbW92aW5nIHRoZSBwcmVmaXggYW5kIGxvb2tpbmcgaXQgdXAgYW1vbmcKLSAgICAgKiB0aGUgcHJlZml4ZXMgY3VycmVudGx5IGRlY2xhcmVkLiAgVGhlIHJldHVybiB2YWx1ZSB3aWxsIGJlIHRoZQotICAgICAqIGFycmF5IHN1cHBsaWVkIGJ5IHRoZSBjYWxsZXIsIGZpbGxlZCBpbiBhcyBmb2xsb3dzOjwvcD4KLSAgICAgKgotICAgICAqIDxkbD4KLSAgICAgKiA8ZHQ+cGFydHNbMF08L2R0PgotICAgICAqIDxkZD5UaGUgTmFtZXNwYWNlIFVSSSwgb3IgYW4gZW1wdHkgc3RyaW5nIGlmIG5vbmUgaXMKLSAgICAgKiAgaW4gdXNlLjwvZGQ+Ci0gICAgICogPGR0PnBhcnRzWzFdPC9kdD4KLSAgICAgKiA8ZGQ+VGhlIGxvY2FsIG5hbWUgKHdpdGhvdXQgcHJlZml4KS48L2RkPgotICAgICAqIDxkdD5wYXJ0c1syXTwvZHQ+Ci0gICAgICogPGRkPlRoZSBvcmlnaW5hbCByYXcgbmFtZS48L2RkPgotICAgICAqIDwvZGw+Ci0gICAgICoKLSAgICAgKiA8cD5BbGwgb2YgdGhlIHN0cmluZ3MgaW4gdGhlIGFycmF5IHdpbGwgYmUgaW50ZXJuYWxpemVkLiAgSWYKLSAgICAgKiB0aGUgcmF3IG5hbWUgaGFzIGEgcHJlZml4IHRoYXQgaGFzIG5vdCBiZWVuIGRlY2xhcmVkLCB0aGVuCi0gICAgICogdGhlIHJldHVybiB2YWx1ZSB3aWxsIGJlIG51bGwuPC9wPgotICAgICAqCi0gICAgICogPHA+Tm90ZSB0aGF0IGF0dHJpYnV0ZSBuYW1lcyBhcmUgcHJvY2Vzc2VkIGRpZmZlcmVudGx5IHRoYW4KLSAgICAgKiBlbGVtZW50IG5hbWVzOiBhbiB1bnByZWZpeGVkIGVsZW1lbnQgbmFtZSB3aWxsIHJlY2VpdmUgdGhlCi0gICAgICogZGVmYXVsdCBOYW1lc3BhY2UgKGlmIGFueSksIHdoaWxlIGFuIHVucHJlZml4ZWQgYXR0cmlidXRlIG5hbWUKLSAgICAgKiB3aWxsIG5vdC48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gcU5hbWUgVGhlIFhNTCBxdWFsaWZpZWQgbmFtZSB0byBiZSBwcm9jZXNzZWQuCi0gICAgICogQHBhcmFtIHBhcnRzIEFuIGFycmF5IHN1cHBsaWVkIGJ5IHRoZSBjYWxsZXIsIGNhcGFibGUgb2YKLSAgICAgKiAgICAgICAgaG9sZGluZyBhdCBsZWFzdCB0aHJlZSBtZW1iZXJzLgotICAgICAqIEBwYXJhbSBpc0F0dHJpYnV0ZSBBIGZsYWcgaW5kaWNhdGluZyB3aGV0aGVyIHRoaXMgaXMgYW4KLSAgICAgKiAgICAgICAgYXR0cmlidXRlIG5hbWUgKHRydWUpIG9yIGFuIGVsZW1lbnQgbmFtZSAoZmFsc2UpLgotICAgICAqIEByZXR1cm4gVGhlIHN1cHBsaWVkIGFycmF5IGhvbGRpbmcgdGhyZWUgaW50ZXJuYWxpemVkIHN0cmluZ3MKLSAgICAgKiAgICAgICAgcmVwcmVzZW50aW5nIHRoZSBOYW1lc3BhY2UgVVJJIChvciBlbXB0eSBzdHJpbmcpLCB0aGUKLSAgICAgKiAgICAgICAgbG9jYWwgbmFtZSwgYW5kIHRoZSBYTUwgcXVhbGlmaWVkIG5hbWU7IG9yIG51bGwgaWYgdGhlcmUKLSAgICAgKiAgICAgICAgaXMgYW4gdW5kZWNsYXJlZCBwcmVmaXguCi0gICAgICogQHNlZSAjZGVjbGFyZVByZWZpeAotICAgICAqIEBzZWUgamF2YS5sYW5nLlN0cmluZyNpbnRlcm4gKi8KLSAgICBwdWJsaWMgU3RyaW5nIFtdIHByb2Nlc3NOYW1lIChTdHJpbmcgcU5hbWUsIFN0cmluZyBwYXJ0c1tdLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gaXNBdHRyaWJ1dGUpCi0gICAgewotICAgICAgICBTdHJpbmcgbXlQYXJ0c1tdID0gY3VycmVudENvbnRleHQucHJvY2Vzc05hbWUocU5hbWUsIGlzQXR0cmlidXRlKTsKLSAgICAgICAgaWYgKG15UGFydHMgPT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBwYXJ0c1swXSA9IG15UGFydHNbMF07Ci0gICAgICAgICAgICBwYXJ0c1sxXSA9IG15UGFydHNbMV07Ci0gICAgICAgICAgICBwYXJ0c1syXSA9IG15UGFydHNbMl07Ci0gICAgICAgICAgICByZXR1cm4gcGFydHM7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIExvb2sgdXAgYSBwcmVmaXggYW5kIGdldCB0aGUgY3VycmVudGx5LW1hcHBlZCBOYW1lc3BhY2UgVVJJLgotICAgICAqCi0gICAgICogPHA+VGhpcyBtZXRob2QgbG9va3MgdXAgdGhlIHByZWZpeCBpbiB0aGUgY3VycmVudCBjb250ZXh0LgotICAgICAqIFVzZSB0aGUgZW1wdHkgc3RyaW5nICgiIikgZm9yIHRoZSBkZWZhdWx0IE5hbWVzcGFjZS48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gcHJlZml4IFRoZSBwcmVmaXggdG8gbG9vayB1cC4KLSAgICAgKiBAcmV0dXJuIFRoZSBhc3NvY2lhdGVkIE5hbWVzcGFjZSBVUkksIG9yIG51bGwgaWYgdGhlIHByZWZpeAotICAgICAqICAgICAgICAgaXMgdW5kZWNsYXJlZCBpbiB0aGlzIGNvbnRleHQuCi0gICAgICogQHNlZSAjZ2V0UHJlZml4Ci0gICAgICogQHNlZSAjZ2V0UHJlZml4ZXMKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFVSSSAoU3RyaW5nIHByZWZpeCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBjdXJyZW50Q29udGV4dC5nZXRVUkkocHJlZml4KTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFJldHVybiBhbiBlbnVtZXJhdGlvbiBvZiBhbGwgcHJlZml4ZXMgd2hvc2UgZGVjbGFyYXRpb25zIGFyZQotICAgICAqIGFjdGl2ZSBpbiB0aGUgY3VycmVudCBjb250ZXh0LgotICAgICAqIFRoaXMgaW5jbHVkZXMgZGVjbGFyYXRpb25zIGZyb20gcGFyZW50IGNvbnRleHRzIHRoYXQgaGF2ZQotICAgICAqIG5vdCBiZWVuIG92ZXJyaWRkZW4uCi0gICAgICoKLSAgICAgKiA8cD48c3Ryb25nPk5vdGU6PC9zdHJvbmc+IGlmIHRoZXJlIGlzIGEgZGVmYXVsdCBwcmVmaXgsIGl0IHdpbGwgbm90IGJlCi0gICAgICogcmV0dXJuZWQgaW4gdGhpcyBlbnVtZXJhdGlvbjsgY2hlY2sgZm9yIHRoZSBkZWZhdWx0IHByZWZpeAotICAgICAqIHVzaW5nIHRoZSB7QGxpbmsgI2dldFVSSSBnZXRVUkl9IHdpdGggYW4gYXJndW1lbnQgb2YgIiIuPC9wPgotICAgICAqCi0gICAgICogQHJldHVybiBBbiBlbnVtZXJhdGlvbiBvZiBwcmVmaXhlcyAobmV2ZXIgZW1wdHkpLgotICAgICAqIEBzZWUgI2dldERlY2xhcmVkUHJlZml4ZXMKLSAgICAgKiBAc2VlICNnZXRVUkkKLSAgICAgKi8KLSAgICBwdWJsaWMgRW51bWVyYXRpb24gZ2V0UHJlZml4ZXMgKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBjdXJyZW50Q29udGV4dC5nZXRQcmVmaXhlcygpOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIG9uZSBvZiB0aGUgcHJlZml4ZXMgbWFwcGVkIHRvIGEgTmFtZXNwYWNlIFVSSS4KLSAgICAgKgotICAgICAqIDxwPklmIG1vcmUgdGhhbiBvbmUgcHJlZml4IGlzIGN1cnJlbnRseSBtYXBwZWQgdG8gdGhlIHNhbWUKLSAgICAgKiBVUkksIHRoaXMgbWV0aG9kIHdpbGwgbWFrZSBhbiBhcmJpdHJhcnkgc2VsZWN0aW9uOyBpZiB5b3UKLSAgICAgKiB3YW50IGFsbCBvZiB0aGUgcHJlZml4ZXMsIHVzZSB0aGUge0BsaW5rICNnZXRQcmVmaXhlc30KLSAgICAgKiBtZXRob2QgaW5zdGVhZC48L3A+Ci0gICAgICoKLSAgICAgKiA8cD48c3Ryb25nPk5vdGU6PC9zdHJvbmc+IHRoaXMgd2lsbCBuZXZlciByZXR1cm4gdGhlIGVtcHR5IChkZWZhdWx0KSBwcmVmaXg7Ci0gICAgICogdG8gY2hlY2sgZm9yIGEgZGVmYXVsdCBwcmVmaXgsIHVzZSB0aGUge0BsaW5rICNnZXRVUkkgZ2V0VVJJfQotICAgICAqIG1ldGhvZCB3aXRoIGFuIGFyZ3VtZW50IG9mICIiLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSB1cmkgdGhlIG5hbWVzcGFjZSBVUkkKLSAgICAgKiBAcmV0dXJuIG9uZSBvZiB0aGUgcHJlZml4ZXMgY3VycmVudGx5IG1hcHBlZCB0byB0aGUgVVJJIHN1cHBsaWVkLAotICAgICAqICAgICAgICAgb3IgbnVsbCBpZiBub25lIGlzIG1hcHBlZCBvciBpZiB0aGUgVVJJIGlzIGFzc2lnbmVkIHRvCi0gICAgICogICAgICAgICB0aGUgZGVmYXVsdCBuYW1lc3BhY2UKLSAgICAgKiBAc2VlICNnZXRQcmVmaXhlcyhqYXZhLmxhbmcuU3RyaW5nKQotICAgICAqIEBzZWUgI2dldFVSSQotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0UHJlZml4IChTdHJpbmcgdXJpKQotICAgIHsKLSAgICAgICAgcmV0dXJuIGN1cnJlbnRDb250ZXh0LmdldFByZWZpeCh1cmkpOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIGFuIGVudW1lcmF0aW9uIG9mIGFsbCBwcmVmaXhlcyBmb3IgYSBnaXZlbiBVUkkgd2hvc2UKLSAgICAgKiBkZWNsYXJhdGlvbnMgYXJlIGFjdGl2ZSBpbiB0aGUgY3VycmVudCBjb250ZXh0LgotICAgICAqIFRoaXMgaW5jbHVkZXMgZGVjbGFyYXRpb25zIGZyb20gcGFyZW50IGNvbnRleHRzIHRoYXQgaGF2ZQotICAgICAqIG5vdCBiZWVuIG92ZXJyaWRkZW4uCi0gICAgICoKLSAgICAgKiA8cD5UaGlzIG1ldGhvZCByZXR1cm5zIHByZWZpeGVzIG1hcHBlZCB0byBhIHNwZWNpZmljIE5hbWVzcGFjZQotICAgICAqIFVSSS4gIFRoZSB4bWw6IHByZWZpeCB3aWxsIGJlIGluY2x1ZGVkLiAgSWYgeW91IHdhbnQgb25seSBvbmUKLSAgICAgKiBwcmVmaXggdGhhdCdzIG1hcHBlZCB0byB0aGUgTmFtZXNwYWNlIFVSSSwgYW5kIHlvdSBkb24ndCBjYXJlCi0gICAgICogd2hpY2ggb25lIHlvdSBnZXQsIHVzZSB0aGUge0BsaW5rICNnZXRQcmVmaXggZ2V0UHJlZml4fQotICAgICAqICBtZXRob2QgaW5zdGVhZC48L3A+Ci0gICAgICoKLSAgICAgKiA8cD48c3Ryb25nPk5vdGU6PC9zdHJvbmc+IHRoZSBlbXB0eSAoZGVmYXVsdCkgcHJlZml4IGlzIDxlbT5uZXZlcjwvZW0+IGluY2x1ZGVkCi0gICAgICogaW4gdGhpcyBlbnVtZXJhdGlvbjsgdG8gY2hlY2sgZm9yIHRoZSBwcmVzZW5jZSBvZiBhIGRlZmF1bHQKLSAgICAgKiBOYW1lc3BhY2UsIHVzZSB0aGUge0BsaW5rICNnZXRVUkkgZ2V0VVJJfSBtZXRob2Qgd2l0aCBhbgotICAgICAqIGFyZ3VtZW50IG9mICIiLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSB1cmkgVGhlIE5hbWVzcGFjZSBVUkkuCi0gICAgICogQHJldHVybiBBbiBlbnVtZXJhdGlvbiBvZiBwcmVmaXhlcyAobmV2ZXIgZW1wdHkpLgotICAgICAqIEBzZWUgI2dldFByZWZpeAotICAgICAqIEBzZWUgI2dldERlY2xhcmVkUHJlZml4ZXMKLSAgICAgKiBAc2VlICNnZXRVUkkKLSAgICAgKi8KLSAgICBwdWJsaWMgRW51bWVyYXRpb24gZ2V0UHJlZml4ZXMgKFN0cmluZyB1cmkpCi0gICAgewotICAgICAgICBMaXN0PFN0cmluZz4gcHJlZml4ZXMgPSBuZXcgQXJyYXlMaXN0PD4oKTsKLSAgICAgICAgRW51bWVyYXRpb24gYWxsUHJlZml4ZXMgPSBnZXRQcmVmaXhlcygpOwotICAgICAgICB3aGlsZSAoYWxsUHJlZml4ZXMuaGFzTW9yZUVsZW1lbnRzKCkpIHsKLSAgICAgICAgICAgIFN0cmluZyBwcmVmaXggPSAoU3RyaW5nKWFsbFByZWZpeGVzLm5leHRFbGVtZW50KCk7Ci0gICAgICAgICAgICBpZiAodXJpLmVxdWFscyhnZXRVUkkocHJlZml4KSkpIHsKLSAgICAgICAgICAgICAgICBwcmVmaXhlcy5hZGQocHJlZml4KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnMuZW51bWVyYXRpb24ocHJlZml4ZXMpOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIGFuIGVudW1lcmF0aW9uIG9mIGFsbCBwcmVmaXhlcyBkZWNsYXJlZCBpbiB0aGlzIGNvbnRleHQuCi0gICAgICoKLSAgICAgKiA8cD5UaGUgZW1wdHkgKGRlZmF1bHQpIHByZWZpeCB3aWxsIGJlIGluY2x1ZGVkIGluIHRoaXMKLSAgICAgKiBlbnVtZXJhdGlvbjsgbm90ZSB0aGF0IHRoaXMgYmVoYXZpb3VyIGRpZmZlcnMgZnJvbSB0aGF0IG9mCi0gICAgICoge0BsaW5rICNnZXRQcmVmaXh9IGFuZCB7QGxpbmsgI2dldFByZWZpeGVzfS48L3A+Ci0gICAgICoKLSAgICAgKiBAcmV0dXJuIEFuIGVudW1lcmF0aW9uIG9mIGFsbCBwcmVmaXhlcyBkZWNsYXJlZCBpbiB0aGlzCi0gICAgICogICAgICAgICBjb250ZXh0LgotICAgICAqIEBzZWUgI2dldFByZWZpeGVzCi0gICAgICogQHNlZSAjZ2V0VVJJCi0gICAgICovCi0gICAgcHVibGljIEVudW1lcmF0aW9uIGdldERlY2xhcmVkUHJlZml4ZXMgKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBjdXJyZW50Q29udGV4dC5nZXREZWNsYXJlZFByZWZpeGVzKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29udHJvbHMgd2hldGhlciBuYW1lc3BhY2UgZGVjbGFyYXRpb24gYXR0cmlidXRlcyBhcmUgcGxhY2VkCi0gICAgICogaW50byB0aGUge0BsaW5rICNOU0RFQ0wgTlNERUNMfSBuYW1lc3BhY2UKLSAgICAgKiBieSB7QGxpbmsgI3Byb2Nlc3NOYW1lIHByb2Nlc3NOYW1lKCl9LiAgVGhpcyBtYXkgb25seSBiZQotICAgICAqIGNoYW5nZWQgYmVmb3JlIGFueSBjb250ZXh0cyBoYXZlIGJlZW4gcHVzaGVkLgotICAgICAqCi0gICAgICogQHNpbmNlIFNBWCAyLjFhbHBoYQotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gd2hlbiBhdHRlbXB0aW5nIHRvIHNldCB0aGlzCi0gICAgICogIGFmdGVyIGFueSBjb250ZXh0IGhhcyBiZWVuIHB1c2hlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXROYW1lc3BhY2VEZWNsVXJpcyAoYm9vbGVhbiB2YWx1ZSkKLSAgICB7Ci0gICAgICAgIGlmIChjb250ZXh0UG9zICE9IDApCi0gICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uICgpOwotICAgICAgICBpZiAodmFsdWUgPT0gbmFtZXNwYWNlRGVjbFVyaXMpCi0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIG5hbWVzcGFjZURlY2xVcmlzID0gdmFsdWU7Ci0gICAgICAgIGlmICh2YWx1ZSkKLSAgICAgICAgICAgIGN1cnJlbnRDb250ZXh0LmRlY2xhcmVQcmVmaXggKCJ4bWxucyIsIE5TREVDTCk7Ci0gICAgICAgIGVsc2UgewotICAgICAgICAgICAgY29udGV4dHNbY29udGV4dFBvc10gPSBjdXJyZW50Q29udGV4dCA9IG5ldyBDb250ZXh0KCk7Ci0gICAgICAgICAgICBjdXJyZW50Q29udGV4dC5kZWNsYXJlUHJlZml4KCJ4bWwiLCBYTUxOUyk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRydWUgaWYgbmFtZXNwYWNlIGRlY2xhcmF0aW9uIGF0dHJpYnV0ZXMgYXJlIHBsYWNlZCBpbnRvCi0gICAgICogYSBuYW1lc3BhY2UuICBUaGlzIGJlaGF2aW9yIGlzIG5vdCB0aGUgZGVmYXVsdC4KLSAgICAgKgotICAgICAqIEBzaW5jZSBTQVggMi4xYWxwaGEKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc05hbWVzcGFjZURlY2xVcmlzICgpCi0gICAgICAgIHsgcmV0dXJuIG5hbWVzcGFjZURlY2xVcmlzOyB9Ci0KLQotCi0gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLSAgICAvLyBJbnRlcm5hbCBzdGF0ZS4KLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotCi0gICAgcHJpdmF0ZSBDb250ZXh0IGNvbnRleHRzW107Ci0gICAgcHJpdmF0ZSBDb250ZXh0IGN1cnJlbnRDb250ZXh0OwotICAgIHByaXZhdGUgaW50IGNvbnRleHRQb3M7Ci0gICAgcHJpdmF0ZSBib29sZWFuIG5hbWVzcGFjZURlY2xVcmlzOwotCi0KLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotICAgIC8vIEludGVybmFsIGNsYXNzZXMuCi0gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLQotICAgIC8qKgotICAgICAqIEludGVybmFsIGNsYXNzIGZvciBhIHNpbmdsZSBOYW1lc3BhY2UgY29udGV4dC4KLSAgICAgKgotICAgICAqIDxwPlRoaXMgbW9kdWxlIGNhY2hlcyBhbmQgcmV1c2VzIE5hbWVzcGFjZSBjb250ZXh0cywKLSAgICAgKiBzbyB0aGUgbnVtYmVyIGFsbG9jYXRlZAotICAgICAqIHdpbGwgYmUgZXF1YWwgdG8gdGhlIGVsZW1lbnQgZGVwdGggb2YgdGhlIGRvY3VtZW50LCBub3QgdG8gdGhlIHRvdGFsCi0gICAgICogbnVtYmVyIG9mIGVsZW1lbnRzIChpLmUuIDUtMTAgcmF0aGVyIHRoYW4gdGVucyBvZiB0aG91c2FuZHMpLgotICAgICAqIEFsc28sIGRhdGEgc3RydWN0dXJlcyB1c2VkIHRvIHJlcHJlc2VudCBjb250ZXh0cyBhcmUgc2hhcmVkIHdoZW4KLSAgICAgKiBwb3NzaWJsZSAoY2hpbGQgY29udGV4dHMgd2l0aG91dCBkZWNsYXJhdGlvbnMpIHRvIGZ1cnRoZXIgcmVkdWNlCi0gICAgICogdGhlIGFtb3VudCBvZiBtZW1vcnkgdGhhdCdzIGNvbnN1bWVkLgotICAgICAqIDwvcD4KLSAgICAgKi8KLSAgICBmaW5hbCBjbGFzcyBDb250ZXh0IHsKLQotICAgICAgICAvKioKLSAgICAgICAgICogQ3JlYXRlIHRoZSByb290LWxldmVsIE5hbWVzcGFjZSBjb250ZXh0LgotICAgICAgICAgKi8KLSAgICAgICAgQ29udGV4dCAoKQotICAgICAgICB7Ci0gICAgICAgICAgICBjb3B5VGFibGVzKCk7Ci0gICAgICAgIH0KLQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiAoUmUpc2V0IHRoZSBwYXJlbnQgb2YgdGhpcyBOYW1lc3BhY2UgY29udGV4dC4KLSAgICAgICAgICogVGhlIGNvbnRleHQgbXVzdCBlaXRoZXIgaGF2ZSBiZWVuIGZyZXNobHkgY29uc3RydWN0ZWQsCi0gICAgICAgICAqIG9yIG11c3QgaGF2ZSBiZWVuIGNsZWFyZWQuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBjb250ZXh0IFRoZSBwYXJlbnQgTmFtZXNwYWNlIGNvbnRleHQgb2JqZWN0LgotICAgICAgICAgKi8KLSAgICAgICAgdm9pZCBzZXRQYXJlbnQgKENvbnRleHQgcGFyZW50KQotICAgICAgICB7Ci0gICAgICAgICAgICB0aGlzLnBhcmVudCA9IHBhcmVudDsKLSAgICAgICAgICAgIGRlY2xhcmF0aW9ucyA9IG51bGw7Ci0gICAgICAgICAgICBwcmVmaXhUYWJsZSA9IHBhcmVudC5wcmVmaXhUYWJsZTsKLSAgICAgICAgICAgIHVyaVRhYmxlID0gcGFyZW50LnVyaVRhYmxlOwotICAgICAgICAgICAgZWxlbWVudE5hbWVUYWJsZSA9IHBhcmVudC5lbGVtZW50TmFtZVRhYmxlOwotICAgICAgICAgICAgYXR0cmlidXRlTmFtZVRhYmxlID0gcGFyZW50LmF0dHJpYnV0ZU5hbWVUYWJsZTsKLSAgICAgICAgICAgIGRlZmF1bHROUyA9IHBhcmVudC5kZWZhdWx0TlM7Ci0gICAgICAgICAgICBkZWNsU2VlbiA9IGZhbHNlOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIE1ha2VzIGFzc29jaWF0ZWQgc3RhdGUgYmVjb21lIGNvbGxlY3RpYmxlLAotICAgICAgICAgKiBpbnZhbGlkYXRpbmcgdGhpcyBjb250ZXh0LgotICAgICAgICAgKiB7QGxpbmsgI3NldFBhcmVudH0gbXVzdCBiZSBjYWxsZWQgYmVmb3JlCi0gICAgICAgICAqIHRoaXMgY29udGV4dCBtYXkgYmUgdXNlZCBhZ2Fpbi4KLSAgICAgICAgICovCi0gICAgICAgIHZvaWQgY2xlYXIgKCkKLSAgICAgICAgewotICAgICAgICAgICAgcGFyZW50ID0gbnVsbDsKLSAgICAgICAgICAgIHByZWZpeFRhYmxlID0gbnVsbDsKLSAgICAgICAgICAgIHVyaVRhYmxlID0gbnVsbDsKLSAgICAgICAgICAgIGVsZW1lbnROYW1lVGFibGUgPSBudWxsOwotICAgICAgICAgICAgYXR0cmlidXRlTmFtZVRhYmxlID0gbnVsbDsKLSAgICAgICAgICAgIGRlZmF1bHROUyA9IG51bGw7Ci0gICAgICAgIH0KLQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBEZWNsYXJlIGEgTmFtZXNwYWNlIHByZWZpeCBmb3IgdGhpcyBjb250ZXh0LgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gcHJlZml4IFRoZSBwcmVmaXggdG8gZGVjbGFyZS4KLSAgICAgICAgICogQHBhcmFtIHVyaSBUaGUgYXNzb2NpYXRlZCBOYW1lc3BhY2UgVVJJLgotICAgICAgICAgKiBAc2VlIG9yZy54bWwuc2F4LmhlbHBlcnMuTmFtZXNwYWNlU3VwcG9ydCNkZWNsYXJlUHJlZml4Ci0gICAgICAgICAqLwotICAgICAgICB2b2lkIGRlY2xhcmVQcmVmaXggKFN0cmluZyBwcmVmaXgsIFN0cmluZyB1cmkpCi0gICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTGF6eSBwcm9jZXNzaW5nLi4uCi0vLyAgICAgICAgICBpZiAoIWRlY2xzT0spCi0vLyAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiAoCi0vLyAgICAgICAgICAgICAgICAgICJjYW4ndCBkZWNsYXJlIGFueSBtb3JlIHByZWZpeGVzIGluIHRoaXMgY29udGV4dCIpOwotICAgICAgICAgICAgaWYgKCFkZWNsU2VlbikgewotICAgICAgICAgICAgICAgIGNvcHlUYWJsZXMoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChkZWNsYXJhdGlvbnMgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGRlY2xhcmF0aW9ucyA9IG5ldyBBcnJheUxpc3Q8PigpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBwcmVmaXggPSBwcmVmaXguaW50ZXJuKCk7Ci0gICAgICAgICAgICB1cmkgPSB1cmkuaW50ZXJuKCk7Ci0gICAgICAgICAgICBpZiAoIiIuZXF1YWxzKHByZWZpeCkpIHsKLSAgICAgICAgICAgICAgICBpZiAoIiIuZXF1YWxzKHVyaSkpIHsKLSAgICAgICAgICAgICAgICAgICAgZGVmYXVsdE5TID0gbnVsbDsKLSAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICBkZWZhdWx0TlMgPSB1cmk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICBwcmVmaXhUYWJsZS5wdXQocHJlZml4LCB1cmkpOwotICAgICAgICAgICAgICAgIHVyaVRhYmxlLnB1dCh1cmksIHByZWZpeCk7IC8vIG1heSB3aXBlIG91dCBhbm90aGVyIHByZWZpeAotICAgICAgICAgICAgfQotICAgICAgICAgICAgZGVjbGFyYXRpb25zLmFkZChwcmVmaXgpOwotICAgICAgICB9Ci0KLQotICAgICAgICAvKioKLSAgICAgICAgICogUHJvY2VzcyBhbiBYTUwgcXVhbGlmaWVkIG5hbWUgaW4gdGhpcyBjb250ZXh0LgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gcU5hbWUgVGhlIFhNTCBxdWFsaWZpZWQgbmFtZS4KLSAgICAgICAgICogQHBhcmFtIGlzQXR0cmlidXRlIHRydWUgaWYgdGhpcyBpcyBhbiBhdHRyaWJ1dGUgbmFtZS4KLSAgICAgICAgICogQHJldHVybiBBbiBhcnJheSBvZiB0aHJlZSBzdHJpbmdzIGNvbnRhaW5pbmcgdGhlCi0gICAgICAgICAqICAgICAgICAgVVJJIHBhcnQgKG9yIGVtcHR5IHN0cmluZyksIHRoZSBsb2NhbCBwYXJ0LAotICAgICAgICAgKiAgICAgICAgIGFuZCB0aGUgcmF3IG5hbWUsIGFsbCBpbnRlcm5hbGl6ZWQsIG9yIG51bGwKLSAgICAgICAgICogICAgICAgICBpZiB0aGVyZSBpcyBhbiB1bmRlY2xhcmVkIHByZWZpeC4KLSAgICAgICAgICogQHNlZSBvcmcueG1sLnNheC5oZWxwZXJzLk5hbWVzcGFjZVN1cHBvcnQjcHJvY2Vzc05hbWUKLSAgICAgICAgICovCi0gICAgICAgIFN0cmluZyBbXSBwcm9jZXNzTmFtZSAoU3RyaW5nIHFOYW1lLCBib29sZWFuIGlzQXR0cmlidXRlKQotICAgICAgICB7Ci0gICAgICAgICAgICBTdHJpbmcgbmFtZVtdOwotICAgICAgICAgICAgTWFwPFN0cmluZywgU3RyaW5nW10+IHRhYmxlOwotCi0gICAgICAgICAgICAvLyBTZWxlY3QgdGhlIGFwcHJvcHJpYXRlIHRhYmxlLgotICAgICAgICAgICAgaWYgKGlzQXR0cmlidXRlKSB7Ci0gICAgICAgICAgICAgICAgdGFibGUgPSBhdHRyaWJ1dGVOYW1lVGFibGU7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIHRhYmxlID0gZWxlbWVudE5hbWVUYWJsZTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gU3RhcnQgYnkgbG9va2luZyBpbiB0aGUgY2FjaGUsIGFuZAotICAgICAgICAgICAgLy8gcmV0dXJuIGltbWVkaWF0ZWx5IGlmIHRoZSBuYW1lCi0gICAgICAgICAgICAvLyBpcyBhbHJlYWR5IGtub3duIGluIHRoaXMgY29udGVudAotICAgICAgICAgICAgbmFtZSA9IChTdHJpbmdbXSl0YWJsZS5nZXQocU5hbWUpOwotICAgICAgICAgICAgaWYgKG5hbWUgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJldHVybiBuYW1lOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBXZSBoYXZlbid0IHNlZW4gdGhpcyBuYW1lIGluIHRoaXMKLSAgICAgICAgICAgIC8vIGNvbnRleHQgYmVmb3JlLiAgTWF5YmUgaW4gdGhlIHBhcmVudAotICAgICAgICAgICAgLy8gY29udGV4dCwgYnV0IHdlIGNhbid0IGFzc3VtZSBwcmVmaXgKLSAgICAgICAgICAgIC8vIGJpbmRpbmdzIGFyZSB0aGUgc2FtZS4KLSAgICAgICAgICAgIG5hbWUgPSBuZXcgU3RyaW5nWzNdOwotICAgICAgICAgICAgbmFtZVsyXSA9IHFOYW1lLmludGVybigpOwotICAgICAgICAgICAgaW50IGluZGV4ID0gcU5hbWUuaW5kZXhPZignOicpOwotCi0KLSAgICAgICAgICAgIC8vIE5vIHByZWZpeC4KLSAgICAgICAgICAgIGlmIChpbmRleCA9PSAtMSkgewotICAgICAgICAgICAgICAgIGlmIChpc0F0dHJpYnV0ZSkgewotICAgICAgICAgICAgICAgICAgICBpZiAocU5hbWUgPT0gInhtbG5zIiAmJiBuYW1lc3BhY2VEZWNsVXJpcykKLSAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVbMF0gPSBOU0RFQ0w7Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVbMF0gPSAiIjsKLSAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGRlZmF1bHROUyA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgIG5hbWVbMF0gPSAiIjsKLSAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICBuYW1lWzBdID0gZGVmYXVsdE5TOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBuYW1lWzFdID0gbmFtZVsyXTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgLy8gUHJlZml4Ci0gICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgcHJlZml4ID0gcU5hbWUuc3Vic3RyaW5nKDAsIGluZGV4KTsKLSAgICAgICAgICAgICAgICBTdHJpbmcgbG9jYWwgPSBxTmFtZS5zdWJzdHJpbmcoaW5kZXgrMSk7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIHVyaTsKLSAgICAgICAgICAgICAgICBpZiAoIiIuZXF1YWxzKHByZWZpeCkpIHsKLSAgICAgICAgICAgICAgICAgICAgdXJpID0gZGVmYXVsdE5TOwotICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIHVyaSA9IChTdHJpbmcpcHJlZml4VGFibGUuZ2V0KHByZWZpeCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGlmICh1cmkgPT0gbnVsbAotICAgICAgICAgICAgICAgICAgICAgICAgfHwgKCFpc0F0dHJpYnV0ZSAmJiAieG1sbnMiLmVxdWFscyAocHJlZml4KSkpIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIG5hbWVbMF0gPSB1cmk7Ci0gICAgICAgICAgICAgICAgbmFtZVsxXSA9IGxvY2FsLmludGVybigpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBTYXZlIGluIHRoZSBjYWNoZSBmb3IgZnV0dXJlIHVzZS4KLSAgICAgICAgICAgIC8vIChDb3VsZCBiZSBzaGFyZWQgd2l0aCBwYXJlbnQgY29udGV4dC4uLikKLSAgICAgICAgICAgIHRhYmxlLnB1dChuYW1lWzJdLCBuYW1lKTsKLSAgICAgICAgICAgIHJldHVybiBuYW1lOwotICAgICAgICB9Ci0KLQotICAgICAgICAvKioKLSAgICAgICAgICogTG9vayB1cCB0aGUgVVJJIGFzc29jaWF0ZWQgd2l0aCBhIHByZWZpeCBpbiB0aGlzIGNvbnRleHQuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBwcmVmaXggVGhlIHByZWZpeCB0byBsb29rIHVwLgotICAgICAgICAgKiBAcmV0dXJuIFRoZSBhc3NvY2lhdGVkIE5hbWVzcGFjZSBVUkksIG9yIG51bGwgaWYgbm9uZSBpcwotICAgICAgICAgKiAgICAgICAgIGRlY2xhcmVkLgotICAgICAgICAgKiBAc2VlIG9yZy54bWwuc2F4LmhlbHBlcnMuTmFtZXNwYWNlU3VwcG9ydCNnZXRVUkkKLSAgICAgICAgICovCi0gICAgICAgIFN0cmluZyBnZXRVUkkgKFN0cmluZyBwcmVmaXgpCi0gICAgICAgIHsKLSAgICAgICAgICAgIGlmICgiIi5lcXVhbHMocHJlZml4KSkgewotICAgICAgICAgICAgICAgIHJldHVybiBkZWZhdWx0TlM7Ci0gICAgICAgICAgICB9IGVsc2UgaWYgKHByZWZpeFRhYmxlID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIChTdHJpbmcpcHJlZml4VGFibGUuZ2V0KHByZWZpeCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBMb29rIHVwIG9uZSBvZiB0aGUgcHJlZml4ZXMgYXNzb2NpYXRlZCB3aXRoIGEgVVJJIGluIHRoaXMgY29udGV4dC4KLSAgICAgICAgICoKLSAgICAgICAgICogPHA+U2luY2UgbWFueSBwcmVmaXhlcyBtYXkgYmUgbWFwcGVkIHRvIHRoZSBzYW1lIFVSSSwKLSAgICAgICAgICogdGhlIHJldHVybiB2YWx1ZSBtYXkgYmUgdW5yZWxpYWJsZS48L3A+Ci0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSB1cmkgVGhlIFVSSSB0byBsb29rIHVwLgotICAgICAgICAgKiBAcmV0dXJuIFRoZSBhc3NvY2lhdGVkIHByZWZpeCwgb3IgbnVsbCBpZiBub25lIGlzIGRlY2xhcmVkLgotICAgICAgICAgKiBAc2VlIG9yZy54bWwuc2F4LmhlbHBlcnMuTmFtZXNwYWNlU3VwcG9ydCNnZXRQcmVmaXgKLSAgICAgICAgICovCi0gICAgICAgIFN0cmluZyBnZXRQcmVmaXggKFN0cmluZyB1cmkpCi0gICAgICAgIHsKLSAgICAgICAgICAgIGlmICh1cmlUYWJsZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIHJldHVybiAoU3RyaW5nKXVyaVRhYmxlLmdldCh1cmkpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLQotICAgICAgICAvKioKLSAgICAgICAgICogUmV0dXJuIGFuIGVudW1lcmF0aW9uIG9mIHByZWZpeGVzIGRlY2xhcmVkIGluIHRoaXMgY29udGV4dC4KLSAgICAgICAgICoKLSAgICAgICAgICogQHJldHVybiBBbiBlbnVtZXJhdGlvbiBvZiBwcmVmaXhlcyAocG9zc2libHkgZW1wdHkpLgotICAgICAgICAgKiBAc2VlIG9yZy54bWwuc2F4LmhlbHBlcnMuTmFtZXNwYWNlU3VwcG9ydCNnZXREZWNsYXJlZFByZWZpeGVzCi0gICAgICAgICAqLwotICAgICAgICBFbnVtZXJhdGlvbiBnZXREZWNsYXJlZFByZWZpeGVzICgpCi0gICAgICAgIHsKLSAgICAgICAgICAgIGlmIChkZWNsYXJhdGlvbnMgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJldHVybiBFTVBUWV9FTlVNRVJBVElPTjsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLmVudW1lcmF0aW9uKGRlY2xhcmF0aW9ucyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogUmV0dXJuIGFuIGVudW1lcmF0aW9uIG9mIGFsbCBwcmVmaXhlcyBjdXJyZW50bHkgaW4gZm9yY2UuCi0gICAgICAgICAqCi0gICAgICAgICAqIDxwPlRoZSBkZWZhdWx0IHByZWZpeCwgaWYgaW4gZm9yY2UsIGlzIDxlbT5ub3Q8L2VtPgotICAgICAgICAgKiByZXR1cm5lZCwgYW5kIHdpbGwgaGF2ZSB0byBiZSBjaGVja2VkIGZvciBzZXBhcmF0ZWx5LjwvcD4KLSAgICAgICAgICoKLSAgICAgICAgICogQHJldHVybiBBbiBlbnVtZXJhdGlvbiBvZiBwcmVmaXhlcyAobmV2ZXIgZW1wdHkpLgotICAgICAgICAgKiBAc2VlIG9yZy54bWwuc2F4LmhlbHBlcnMuTmFtZXNwYWNlU3VwcG9ydCNnZXRQcmVmaXhlcwotICAgICAgICAgKi8KLSAgICAgICAgRW51bWVyYXRpb24gZ2V0UHJlZml4ZXMgKCkKLSAgICAgICAgewotICAgICAgICAgICAgaWYgKHByZWZpeFRhYmxlID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gRU1QVFlfRU5VTUVSQVRJT047Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIHJldHVybiBDb2xsZWN0aW9ucy5lbnVtZXJhdGlvbihwcmVmaXhUYWJsZS5rZXlTZXQoKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotCi0KLSAgICAgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotICAgICAgICAvLyBJbnRlcm5hbCBtZXRob2RzLgotICAgICAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0KLQotICAgICAgICAvKioKLSAgICAgICAgICogQ29weSBvbiB3cml0ZSBmb3IgdGhlIGludGVybmFsIHRhYmxlcyBpbiB0aGlzIGNvbnRleHQuCi0gICAgICAgICAqCi0gICAgICAgICAqIDxwPlRoaXMgY2xhc3MgaXMgb3B0aW1pemVkIGZvciB0aGUgbm9ybWFsIGNhc2Ugd2hlcmUgbW9zdAotICAgICAgICAgKiBlbGVtZW50cyBkbyBub3QgY29udGFpbiBOYW1lc3BhY2UgZGVjbGFyYXRpb25zLjwvcD4KLSAgICAgICAgICovCi0gICAgICAgIHByaXZhdGUgdm9pZCBjb3B5VGFibGVzICgpCi0gICAgICAgIHsKLSAgICAgICAgICAgIGlmIChwcmVmaXhUYWJsZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgcHJlZml4VGFibGUgPSBuZXcgSGFzaE1hcDw+KHByZWZpeFRhYmxlKTsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgcHJlZml4VGFibGUgPSBuZXcgSGFzaE1hcDw+KCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAodXJpVGFibGUgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHVyaVRhYmxlID0gbmV3IEhhc2hNYXA8Pih1cmlUYWJsZSk7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIHVyaVRhYmxlID0gbmV3IEhhc2hNYXA8PigpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxlbWVudE5hbWVUYWJsZSA9IG5ldyBIYXNoTWFwPD4oKTsKLSAgICAgICAgICAgIGF0dHJpYnV0ZU5hbWVUYWJsZSA9IG5ldyBIYXNoTWFwPD4oKTsKLSAgICAgICAgICAgIGRlY2xTZWVuID0gdHJ1ZTsKLSAgICAgICAgfQotCi0KLQotICAgICAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0gICAgICAgIC8vIFByb3RlY3RlZCBzdGF0ZS4KLSAgICAgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotCi0gICAgICAgIE1hcDxTdHJpbmcsIFN0cmluZz4gcHJlZml4VGFibGU7Ci0gICAgICAgIE1hcDxTdHJpbmcsIFN0cmluZz4gdXJpVGFibGU7Ci0gICAgICAgIE1hcDxTdHJpbmcsIFN0cmluZ1tdPiBlbGVtZW50TmFtZVRhYmxlOwotICAgICAgICBNYXA8U3RyaW5nLCBTdHJpbmdbXT4gYXR0cmlidXRlTmFtZVRhYmxlOwotICAgICAgICBTdHJpbmcgZGVmYXVsdE5TID0gbnVsbDsKLQotCi0KLSAgICAgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotICAgICAgICAvLyBJbnRlcm5hbCBzdGF0ZS4KLSAgICAgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotCi0gICAgICAgIHByaXZhdGUgTGlzdDxTdHJpbmc+IGRlY2xhcmF0aW9ucyA9IG51bGw7Ci0gICAgICAgIHByaXZhdGUgYm9vbGVhbiBkZWNsU2VlbiA9IGZhbHNlOwotICAgICAgICBwcml2YXRlIENvbnRleHQgcGFyZW50ID0gbnVsbDsKLSAgICB9Ci19Ci0KLS8vIGVuZCBvZiBOYW1lc3BhY2VTdXBwb3J0LmphdmEKZGlmZiAtLWdpdCBhL3NyYy9vcmcveG1sL3NheC9oZWxwZXJzL05ld0luc3RhbmNlLmphdmEgYi9zcmMvb3JnL3htbC9zYXgvaGVscGVycy9OZXdJbnN0YW5jZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjMzUxNmIxLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcveG1sL3NheC9oZWxwZXJzL05ld0luc3RhbmNlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4NyArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IChjKSAyMDAxLCAyMDEzLCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgotICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgotICoKLSAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Ci0gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwotICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCi0gKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCi0gKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKLSAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgotICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCi0gKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAotICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KLSAqCi0gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCi0gKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCi0gKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCi0gKgotICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKLSAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKLSAqIHF1ZXN0aW9ucy4KLSAqLwotCi0vLyBOZXdJbnN0YW5jZS5qYXZhIC0gY3JlYXRlIGEgbmV3IGluc3RhbmNlIG9mIGEgY2xhc3MgYnkgbmFtZS4KLS8vIGh0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmcKLS8vIFdyaXR0ZW4gYnkgRWR3aW4gR29laSwgZWR3aW5nb0BhcGFjaGUub3JnCi0vLyBhbmQgYnkgRGF2aWQgQnJvd25lbGwsIGRicm93bmVsbEB1c2Vycy5zb3VyY2Vmb3JnZS5uZXQKLS8vIE5PIFdBUlJBTlRZISAgVGhpcyBjbGFzcyBpcyBpbiB0aGUgUHVibGljIERvbWFpbi4KLS8vICRJZDogTmV3SW5zdGFuY2UuamF2YSx2IDEuMiAyMDA1LzA2LzEwIDAzOjUwOjUwIGplZmZzdXR0b3IgRXhwICQKLQotcGFja2FnZSBvcmcueG1sLnNheC5oZWxwZXJzOwotCi1pbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kOwotaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lkludm9jYXRpb25UYXJnZXRFeGNlcHRpb247Ci0KLS8qKgotICogQ3JlYXRlIGEgbmV3IGluc3RhbmNlIG9mIGEgY2xhc3MgYnkgbmFtZS4KLSAqCi0gKiA8YmxvY2txdW90ZT4KLSAqIDxlbT5UaGlzIG1vZHVsZSwgYm90aCBzb3VyY2UgY29kZSBhbmQgZG9jdW1lbnRhdGlvbiwgaXMgaW4gdGhlCi0gKiBQdWJsaWMgRG9tYWluLCBhbmQgY29tZXMgd2l0aCA8c3Ryb25nPk5PIFdBUlJBTlRZPC9zdHJvbmc+LjwvZW0+Ci0gKiBTZWUgPGEgaHJlZj0naHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZyc+aHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZzwvYT4KLSAqIGZvciBmdXJ0aGVyIGluZm9ybWF0aW9uLgotICogPC9ibG9ja3F1b3RlPgotICoKLSAqIDxwPlRoaXMgY2xhc3MgY29udGFpbnMgYSBzdGF0aWMgbWV0aG9kIGZvciBjcmVhdGluZyBhbiBpbnN0YW5jZSBvZiBhCi0gKiBjbGFzcyBmcm9tIGFuIGV4cGxpY2l0IGNsYXNzIG5hbWUuICBJdCB0cmllcyB0byB1c2UgdGhlIHRocmVhZCdzIGNvbnRleHQKLSAqIENsYXNzTG9hZGVyIGlmIHBvc3NpYmxlIGFuZCBmYWxscyBiYWNrIHRvIHVzaW5nCi0gKiBDbGFzcy5mb3JOYW1lKFN0cmluZykuPC9wPgotICoKLSAqIDxwPlRoaXMgY29kZSBpcyBkZXNpZ25lZCB0byBjb21waWxlIGFuZCBydW4gb24gSkRLIHZlcnNpb24gMS4xIGFuZCBsYXRlcgotICogaW5jbHVkaW5nIHZlcnNpb25zIG9mIEphdmEgMi48L3A+Ci0gKgotICogQGF1dGhvciBFZHdpbiBHb2VpLCBEYXZpZCBCcm93bmVsbAotICogQHZlcnNpb24gMi4wLjEgKHNheDJyMikKLSAqLwotY2xhc3MgTmV3SW5zdGFuY2UgewotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBERUZBVUxUX1BBQ0tBR0UgPSAiY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbCI7Ci0gICAgLyoqCi0gICAgICogQ3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiB0aGUgc3BlY2lmaWVkIGNsYXNzIG5hbWUKLSAgICAgKgotICAgICAqIFBhY2thZ2UgcHJpdmF0ZSBzbyB0aGlzIGNvZGUgaXMgbm90IGV4cG9zZWQgYXQgdGhlIEFQSSBsZXZlbC4KLSAgICAgKi8KLSAgICBzdGF0aWMgT2JqZWN0IG5ld0luc3RhbmNlIChDbGFzc0xvYWRlciBjbGFzc0xvYWRlciwgU3RyaW5nIGNsYXNzTmFtZSkKLSAgICAgICAgdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb24sIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24sCi0gICAgICAgICAgICBJbnN0YW50aWF0aW9uRXhjZXB0aW9uCi0gICAgewotICAgICAgICAvLyBtYWtlIHN1cmUgd2UgaGF2ZSBhY2Nlc3MgdG8gcmVzdHJpY3RlZCBwYWNrYWdlcwotICAgICAgICBib29sZWFuIGludGVybmFsID0gZmFsc2U7Ci0gICAgICAgIGlmIChTeXN0ZW0uZ2V0U2VjdXJpdHlNYW5hZ2VyKCkgIT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKGNsYXNzTmFtZSAhPSBudWxsICYmIGNsYXNzTmFtZS5zdGFydHNXaXRoKERFRkFVTFRfUEFDS0FHRSkpIHsKLSAgICAgICAgICAgICAgICBpbnRlcm5hbCA9IHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBDbGFzcyBkcml2ZXJDbGFzczsKLSAgICAgICAgaWYgKGNsYXNzTG9hZGVyID09IG51bGwgfHwgaW50ZXJuYWwpIHsKLSAgICAgICAgICAgIGRyaXZlckNsYXNzID0gQ2xhc3MuZm9yTmFtZShjbGFzc05hbWUpOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgZHJpdmVyQ2xhc3MgPSBjbGFzc0xvYWRlci5sb2FkQ2xhc3MoY2xhc3NOYW1lKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gZHJpdmVyQ2xhc3MubmV3SW5zdGFuY2UoKTsKLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcveG1sL3NheC9oZWxwZXJzL1BhcnNlckFkYXB0ZXIuamF2YSBiL3NyYy9vcmcveG1sL3NheC9oZWxwZXJzL1BhcnNlckFkYXB0ZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNjJlNzZjNy4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3htbC9zYXgvaGVscGVycy9QYXJzZXJBZGFwdGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMDcxICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDAsIDIwMTMsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8vIFBhcnNlckFkYXB0ZXIuamF2YSAtIGFkYXB0IGEgU0FYMSBQYXJzZXIgdG8gYSBTQVgyIFhNTFJlYWRlci4KLS8vIGh0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmcKLS8vIFdyaXR0ZW4gYnkgRGF2aWQgTWVnZ2luc29uCi0vLyBOTyBXQVJSQU5UWSEgIFRoaXMgY2xhc3MgaXMgaW4gdGhlIHB1YmxpYyBkb21haW4uCi0vLyAkSWQ6IFBhcnNlckFkYXB0ZXIuamF2YSx2IDEuMyAyMDA0LzExLzAzIDIyOjUzOjA5IGpzdXR0b3IgRXhwICQKLQotcGFja2FnZSBvcmcueG1sLnNheC5oZWxwZXJzOwotCi1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247Ci1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotaW1wb3J0IG9yZy54bWwuc2F4LlBhcnNlcjsgICAgICAvLyBkZXByZWNhdGVkCi1pbXBvcnQgb3JnLnhtbC5zYXguSW5wdXRTb3VyY2U7Ci1pbXBvcnQgb3JnLnhtbC5zYXguTG9jYXRvcjsKLWltcG9ydCBvcmcueG1sLnNheC5BdHRyaWJ1dGVMaXN0OyAvLyBkZXByZWNhdGVkCi1pbXBvcnQgb3JnLnhtbC5zYXguRW50aXR5UmVzb2x2ZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguRFRESGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5Eb2N1bWVudEhhbmRsZXI7IC8vIGRlcHJlY2F0ZWQKLWltcG9ydCBvcmcueG1sLnNheC5FcnJvckhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWFBhcnNlRXhjZXB0aW9uOwotCi1pbXBvcnQgb3JnLnhtbC5zYXguWE1MUmVhZGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LkF0dHJpYnV0ZXM7Ci1pbXBvcnQgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb247Ci0KLQotLyoqCi0gKiBBZGFwdCBhIFNBWDEgUGFyc2VyIGFzIGEgU0FYMiBYTUxSZWFkZXIuCi0gKgotICogPGJsb2NrcXVvdGU+Ci0gKiA8ZW0+VGhpcyBtb2R1bGUsIGJvdGggc291cmNlIGNvZGUgYW5kIGRvY3VtZW50YXRpb24sIGlzIGluIHRoZQotICogUHVibGljIERvbWFpbiwgYW5kIGNvbWVzIHdpdGggPHN0cm9uZz5OTyBXQVJSQU5UWTwvc3Ryb25nPi48L2VtPgotICogU2VlIDxhIGhyZWY9J2h0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmcnPmh0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmc8L2E+Ci0gKiBmb3IgZnVydGhlciBpbmZvcm1hdGlvbi4KLSAqIDwvYmxvY2txdW90ZT4KLSAqCi0gKiA8cD5UaGlzIGNsYXNzIHdyYXBzIGEgU0FYMSB7QGxpbmsgb3JnLnhtbC5zYXguUGFyc2VyIFBhcnNlcn0KLSAqIGFuZCBtYWtlcyBpdCBhY3QgYXMgYSBTQVgyIHtAbGluayBvcmcueG1sLnNheC5YTUxSZWFkZXIgWE1MUmVhZGVyfSwKLSAqIHdpdGggZmVhdHVyZSwgcHJvcGVydHksIGFuZCBOYW1lc3BhY2Ugc3VwcG9ydC4gIE5vdGUKLSAqIHRoYXQgaXQgaXMgbm90IHBvc3NpYmxlIHRvIHJlcG9ydCB7QGxpbmsgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjc2tpcHBlZEVudGl0eQotICogc2tpcHBlZEVudGl0eX0gZXZlbnRzLCBzaW5jZSBTQVgxIGRvZXMgbm90IG1ha2UgdGhhdCBpbmZvcm1hdGlvbiBhdmFpbGFibGUuPC9wPgotICoKLSAqIDxwPlRoaXMgYWRhcHRlciBkb2VzIG5vdCB0ZXN0IGZvciBkdXBsaWNhdGUgTmFtZXNwYWNlLXF1YWxpZmllZAotICogYXR0cmlidXRlIG5hbWVzLjwvcD4KLSAqCi0gKiBAc2luY2UgU0FYIDIuMAotICogQGF1dGhvciBEYXZpZCBNZWdnaW5zb24KLSAqIEB2ZXJzaW9uIDIuMC4xIChzYXgycjIpCi0gKiBAc2VlIG9yZy54bWwuc2F4LmhlbHBlcnMuWE1MUmVhZGVyQWRhcHRlcgotICogQHNlZSBvcmcueG1sLnNheC5YTUxSZWFkZXIKLSAqIEBzZWUgb3JnLnhtbC5zYXguUGFyc2VyCi0gKi8KLXB1YmxpYyBjbGFzcyBQYXJzZXJBZGFwdGVyIGltcGxlbWVudHMgWE1MUmVhZGVyLCBEb2N1bWVudEhhbmRsZXIKLXsKLSAgICBwcml2YXRlIHN0YXRpYyBTZWN1cml0eVN1cHBvcnQgc3MgPSBuZXcgU2VjdXJpdHlTdXBwb3J0KCk7Ci0KLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotICAgIC8vIENvbnN0cnVjdG9ycy4KLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotCi0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3QgYSBuZXcgcGFyc2VyIGFkYXB0ZXIuCi0gICAgICoKLSAgICAgKiA8cD5Vc2UgdGhlICJvcmcueG1sLnNheC5wYXJzZXIiIHByb3BlcnR5IHRvIGxvY2F0ZSB0aGUKLSAgICAgKiBlbWJlZGRlZCBTQVgxIGRyaXZlci48L3A+Ci0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIFNBWEV4Y2VwdGlvbiBJZiB0aGUgZW1iZWRkZWQgZHJpdmVyCi0gICAgICogICAgICAgICAgICBjYW5ub3QgYmUgaW5zdGFudGlhdGVkIG9yIGlmIHRoZQotICAgICAqICAgICAgICAgICAgb3JnLnhtbC5zYXgucGFyc2VyIHByb3BlcnR5IGlzIG5vdCBzcGVjaWZpZWQuCi0gICAgICovCi0gICAgcHVibGljIFBhcnNlckFkYXB0ZXIgKCkKLSAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIHN1cGVyKCk7Ci0KLSAgICAgICAgU3RyaW5nIGRyaXZlciA9IHNzLmdldFN5c3RlbVByb3BlcnR5KCJvcmcueG1sLnNheC5wYXJzZXIiKTsKLQotICAgICAgICB0cnkgewotICAgICAgICAgICAgc2V0dXAoUGFyc2VyRmFjdG9yeS5tYWtlUGFyc2VyKCkpOwotICAgICAgICB9IGNhdGNoIChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGUxKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcKLSAgICAgICAgICAgICAgICBTQVhFeGNlcHRpb24oIkNhbm5vdCBmaW5kIFNBWDEgZHJpdmVyIGNsYXNzICIgKwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcml2ZXIsIGUxKTsKLSAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBlMikgewotICAgICAgICAgICAgdGhyb3cgbmV3Ci0gICAgICAgICAgICAgICAgU0FYRXhjZXB0aW9uKCJTQVgxIGRyaXZlciBjbGFzcyAiICsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHJpdmVyICsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiBmb3VuZCBidXQgY2Fubm90IGJlIGxvYWRlZCIsIGUyKTsKLSAgICAgICAgfSBjYXRjaCAoSW5zdGFudGlhdGlvbkV4Y2VwdGlvbiBlMykgewotICAgICAgICAgICAgdGhyb3cgbmV3Ci0gICAgICAgICAgICAgICAgU0FYRXhjZXB0aW9uKCJTQVgxIGRyaXZlciBjbGFzcyAiICsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHJpdmVyICsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiBsb2FkZWQgYnV0IGNhbm5vdCBiZSBpbnN0YW50aWF0ZWQiLCBlMyk7Ci0gICAgICAgIH0gY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBlNCkgewotICAgICAgICAgICAgdGhyb3cgbmV3Ci0gICAgICAgICAgICAgICAgU0FYRXhjZXB0aW9uKCJTQVgxIGRyaXZlciBjbGFzcyAiICsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHJpdmVyICsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiBkb2VzIG5vdCBpbXBsZW1lbnQgb3JnLnhtbC5zYXguUGFyc2VyIik7Ci0gICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGU1KSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcKLSAgICAgICAgICAgICAgICBTQVhFeGNlcHRpb24oIlN5c3RlbSBwcm9wZXJ0eSBvcmcueG1sLnNheC5wYXJzZXIgbm90IHNwZWNpZmllZCIpOwotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3QgYSBuZXcgcGFyc2VyIGFkYXB0ZXIuCi0gICAgICoKLSAgICAgKiA8cD5Ob3RlIHRoYXQgdGhlIGVtYmVkZGVkIHBhcnNlciBjYW5ub3QgYmUgY2hhbmdlZCBvbmNlIHRoZQotICAgICAqIGFkYXB0ZXIgaXMgY3JlYXRlZDsgdG8gZW1iZWQgYSBkaWZmZXJlbnQgcGFyc2VyLCBhbGxvY2F0ZQotICAgICAqIGEgbmV3IFBhcnNlckFkYXB0ZXIuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIHBhcnNlciBUaGUgU0FYMSBwYXJzZXIgdG8gZW1iZWQuCi0gICAgICogQGV4Y2VwdGlvbiBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24gSWYgdGhlIHBhcnNlciBwYXJhbWV0ZXIKLSAgICAgKiAgICAgICAgICAgIGlzIG51bGwuCi0gICAgICovCi0gICAgcHVibGljIFBhcnNlckFkYXB0ZXIgKFBhcnNlciBwYXJzZXIpCi0gICAgewotICAgICAgICBzdXBlcigpOwotICAgICAgICBzZXR1cChwYXJzZXIpOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogSW50ZXJuYWwgc2V0dXAgbWV0aG9kLgotICAgICAqCi0gICAgICogQHBhcmFtIHBhcnNlciBUaGUgZW1iZWRkZWQgcGFyc2VyLgotICAgICAqIEBleGNlcHRpb24gamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uIElmIHRoZSBwYXJzZXIgcGFyYW1ldGVyCi0gICAgICogICAgICAgICAgICBpcyBudWxsLgotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCBzZXR1cCAoUGFyc2VyIHBhcnNlcikKLSAgICB7Ci0gICAgICAgIGlmIChwYXJzZXIgPT0gbnVsbCkgewotICAgICAgICAgICAgdGhyb3cgbmV3Ci0gICAgICAgICAgICAgICAgTnVsbFBvaW50ZXJFeGNlcHRpb24oIlBhcnNlciBhcmd1bWVudCBtdXN0IG5vdCBiZSBudWxsIik7Ci0gICAgICAgIH0KLSAgICAgICAgdGhpcy5wYXJzZXIgPSBwYXJzZXI7Ci0gICAgICAgIGF0dHMgPSBuZXcgQXR0cmlidXRlc0ltcGwoKTsKLSAgICAgICAgbnNTdXBwb3J0ID0gbmV3IE5hbWVzcGFjZVN1cHBvcnQoKTsKLSAgICAgICAgYXR0QWRhcHRlciA9IG5ldyBBdHRyaWJ1dGVMaXN0QWRhcHRlcigpOwotICAgIH0KLQotCi0KLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotICAgIC8vIEltcGxlbWVudGF0aW9uIG9mIG9yZy54bWwuc2F4LlhNTFJlYWRlci4KLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotCi0KLSAgICAvLwotICAgIC8vIEludGVybmFsIGNvbnN0YW50cyBmb3IgdGhlIHNha2Ugb2YgY29udmVuaWVuY2UuCi0gICAgLy8KLSAgICBwcml2YXRlIGZpbmFsIHN0YXRpYyBTdHJpbmcgRkVBVFVSRVMgPSAiaHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzLyI7Ci0gICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgU3RyaW5nIE5BTUVTUEFDRVMgPSBGRUFUVVJFUyArICJuYW1lc3BhY2VzIjsKLSAgICBwcml2YXRlIGZpbmFsIHN0YXRpYyBTdHJpbmcgTkFNRVNQQUNFX1BSRUZJWEVTID0gRkVBVFVSRVMgKyAibmFtZXNwYWNlLXByZWZpeGVzIjsKLSAgICBwcml2YXRlIGZpbmFsIHN0YXRpYyBTdHJpbmcgWE1MTlNfVVJJcyA9IEZFQVRVUkVTICsgInhtbG5zLXVyaXMiOwotCi0KLSAgICAvKioKLSAgICAgKiBTZXQgYSBmZWF0dXJlIGZsYWcgZm9yIHRoZSBwYXJzZXIuCi0gICAgICoKLSAgICAgKiA8cD5UaGUgb25seSBmZWF0dXJlcyByZWNvZ25pemVkIGFyZSBuYW1lc3BhY2VzIGFuZAotICAgICAqIG5hbWVzcGFjZS1wcmVmaXhlcy48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgZmVhdHVyZSBuYW1lLCBhcyBhIGNvbXBsZXRlIFVSSS4KLSAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcXVlc3RlZCBmZWF0dXJlIHZhbHVlLgotICAgICAqIEBleGNlcHRpb24gU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiBJZiB0aGUgZmVhdHVyZQotICAgICAqICAgICAgICAgICAgY2FuJ3QgYmUgYXNzaWduZWQgb3IgcmV0cmlldmVkLgotICAgICAqIEBleGNlcHRpb24gU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIElmIHRoZSBmZWF0dXJlCi0gICAgICogICAgICAgICAgICBjYW4ndCBiZSBhc3NpZ25lZCB0aGF0IHZhbHVlLgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguWE1MUmVhZGVyI3NldEZlYXR1cmUKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRGZWF0dXJlIChTdHJpbmcgbmFtZSwgYm9vbGVhbiB2YWx1ZSkKLSAgICAgICAgdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaWYgKG5hbWUuZXF1YWxzKE5BTUVTUEFDRVMpKSB7Ci0gICAgICAgICAgICBjaGVja05vdFBhcnNpbmcoImZlYXR1cmUiLCBuYW1lKTsKLSAgICAgICAgICAgIG5hbWVzcGFjZXMgPSB2YWx1ZTsKLSAgICAgICAgICAgIGlmICghbmFtZXNwYWNlcyAmJiAhcHJlZml4ZXMpIHsKLSAgICAgICAgICAgICAgICBwcmVmaXhlcyA9IHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gZWxzZSBpZiAobmFtZS5lcXVhbHMoTkFNRVNQQUNFX1BSRUZJWEVTKSkgewotICAgICAgICAgICAgY2hlY2tOb3RQYXJzaW5nKCJmZWF0dXJlIiwgbmFtZSk7Ci0gICAgICAgICAgICBwcmVmaXhlcyA9IHZhbHVlOwotICAgICAgICAgICAgaWYgKCFwcmVmaXhlcyAmJiAhbmFtZXNwYWNlcykgewotICAgICAgICAgICAgICAgIG5hbWVzcGFjZXMgPSB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICB9IGVsc2UgaWYgKG5hbWUuZXF1YWxzKFhNTE5TX1VSSXMpKSB7Ci0gICAgICAgICAgICBjaGVja05vdFBhcnNpbmcoImZlYXR1cmUiLCBuYW1lKTsKLSAgICAgICAgICAgIHVyaXMgPSB2YWx1ZTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uKCJGZWF0dXJlOiAiICsgbmFtZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIENoZWNrIGEgcGFyc2VyIGZlYXR1cmUgZmxhZy4KLSAgICAgKgotICAgICAqIDxwPlRoZSBvbmx5IGZlYXR1cmVzIHJlY29nbml6ZWQgYXJlIG5hbWVzcGFjZXMgYW5kCi0gICAgICogbmFtZXNwYWNlLXByZWZpeGVzLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBmZWF0dXJlIG5hbWUsIGFzIGEgY29tcGxldGUgVVJJLgotICAgICAqIEByZXR1cm4gVGhlIGN1cnJlbnQgZmVhdHVyZSB2YWx1ZS4KLSAgICAgKiBAZXhjZXB0aW9uIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24gSWYgdGhlIGZlYXR1cmUKLSAgICAgKiAgICAgICAgICAgIHZhbHVlIGNhbid0IGJlIGFzc2lnbmVkIG9yIHJldHJpZXZlZC4KLSAgICAgKiBAZXhjZXB0aW9uIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBJZiB0aGUKLSAgICAgKiAgICAgICAgICAgIGZlYXR1cmUgaXMgbm90IGN1cnJlbnRseSByZWFkYWJsZS4KLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LlhNTFJlYWRlciNzZXRGZWF0dXJlCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0RmVhdHVyZSAoU3RyaW5nIG5hbWUpCi0gICAgICAgIHRocm93cyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uLCBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGlmIChuYW1lLmVxdWFscyhOQU1FU1BBQ0VTKSkgewotICAgICAgICAgICAgcmV0dXJuIG5hbWVzcGFjZXM7Ci0gICAgICAgIH0gZWxzZSBpZiAobmFtZS5lcXVhbHMoTkFNRVNQQUNFX1BSRUZJWEVTKSkgewotICAgICAgICAgICAgcmV0dXJuIHByZWZpeGVzOwotICAgICAgICB9IGVsc2UgaWYgKG5hbWUuZXF1YWxzKFhNTE5TX1VSSXMpKSB7Ci0gICAgICAgICAgICByZXR1cm4gdXJpczsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uKCJGZWF0dXJlOiAiICsgbmFtZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFNldCBhIHBhcnNlciBwcm9wZXJ0eS4KLSAgICAgKgotICAgICAqIDxwPk5vIHByb3BlcnRpZXMgYXJlIGN1cnJlbnRseSByZWNvZ25pemVkLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBwcm9wZXJ0eSBuYW1lLgotICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcHJvcGVydHkgdmFsdWUuCi0gICAgICogQGV4Y2VwdGlvbiBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIElmIHRoZSBwcm9wZXJ0eQotICAgICAqICAgICAgICAgICAgdmFsdWUgY2FuJ3QgYmUgYXNzaWduZWQgb3IgcmV0cmlldmVkLgotICAgICAqIEBleGNlcHRpb24gU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIElmIHRoZSBwcm9wZXJ0eQotICAgICAqICAgICAgICAgICAgY2FuJ3QgYmUgYXNzaWduZWQgdGhhdCB2YWx1ZS4KLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LlhNTFJlYWRlciNzZXRQcm9wZXJ0eQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFByb3BlcnR5IChTdHJpbmcgbmFtZSwgT2JqZWN0IHZhbHVlKQotICAgICAgICB0aHJvd3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiwgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uCi0gICAgewotICAgICAgICB0aHJvdyBuZXcgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbigiUHJvcGVydHk6ICIgKyBuYW1lKTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIEdldCBhIHBhcnNlciBwcm9wZXJ0eS4KLSAgICAgKgotICAgICAqIDxwPk5vIHByb3BlcnRpZXMgYXJlIGN1cnJlbnRseSByZWNvZ25pemVkLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBwcm9wZXJ0eSBuYW1lLgotICAgICAqIEByZXR1cm4gVGhlIHByb3BlcnR5IHZhbHVlLgotICAgICAqIEBleGNlcHRpb24gU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiBJZiB0aGUgcHJvcGVydHkKLSAgICAgKiAgICAgICAgICAgIHZhbHVlIGNhbid0IGJlIGFzc2lnbmVkIG9yIHJldHJpZXZlZC4KLSAgICAgKiBAZXhjZXB0aW9uIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBJZiB0aGUgcHJvcGVydHkKLSAgICAgKiAgICAgICAgICAgIHZhbHVlIGlzIG5vdCBjdXJyZW50bHkgcmVhZGFibGUuCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5YTUxSZWFkZXIjZ2V0UHJvcGVydHkKLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0IGdldFByb3BlcnR5IChTdHJpbmcgbmFtZSkKLSAgICAgICAgdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgdGhyb3cgbmV3IFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24oIlByb3BlcnR5OiAiICsgbmFtZSk7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIGVudGl0eSByZXNvbHZlci4KLSAgICAgKgotICAgICAqIEBwYXJhbSByZXNvbHZlciBUaGUgbmV3IGVudGl0eSByZXNvbHZlci4KLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LlhNTFJlYWRlciNzZXRFbnRpdHlSZXNvbHZlcgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEVudGl0eVJlc29sdmVyIChFbnRpdHlSZXNvbHZlciByZXNvbHZlcikKLSAgICB7Ci0gICAgICAgIGVudGl0eVJlc29sdmVyID0gcmVzb2x2ZXI7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIGN1cnJlbnQgZW50aXR5IHJlc29sdmVyLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgY3VycmVudCBlbnRpdHkgcmVzb2x2ZXIsIG9yIG51bGwgaWYgbm9uZSB3YXMgc3VwcGxpZWQuCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5YTUxSZWFkZXIjZ2V0RW50aXR5UmVzb2x2ZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgRW50aXR5UmVzb2x2ZXIgZ2V0RW50aXR5UmVzb2x2ZXIgKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBlbnRpdHlSZXNvbHZlcjsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFNldCB0aGUgRFREIGhhbmRsZXIuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaGFuZGxlciB0aGUgbmV3IERURCBoYW5kbGVyCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5YTUxSZWFkZXIjc2V0RW50aXR5UmVzb2x2ZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXREVERIYW5kbGVyIChEVERIYW5kbGVyIGhhbmRsZXIpCi0gICAgewotICAgICAgICBkdGRIYW5kbGVyID0gaGFuZGxlcjsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFJldHVybiB0aGUgY3VycmVudCBEVEQgaGFuZGxlci4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdGhlIGN1cnJlbnQgRFREIGhhbmRsZXIsIG9yIG51bGwgaWYgbm9uZSB3YXMgc3VwcGxpZWQKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LlhNTFJlYWRlciNnZXRFbnRpdHlSZXNvbHZlcgotICAgICAqLwotICAgIHB1YmxpYyBEVERIYW5kbGVyIGdldERUREhhbmRsZXIgKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBkdGRIYW5kbGVyOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSBjb250ZW50IGhhbmRsZXIuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaGFuZGxlciB0aGUgbmV3IGNvbnRlbnQgaGFuZGxlcgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguWE1MUmVhZGVyI3NldEVudGl0eVJlc29sdmVyCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0Q29udGVudEhhbmRsZXIgKENvbnRlbnRIYW5kbGVyIGhhbmRsZXIpCi0gICAgewotICAgICAgICBjb250ZW50SGFuZGxlciA9IGhhbmRsZXI7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIGN1cnJlbnQgY29udGVudCBoYW5kbGVyLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgY3VycmVudCBjb250ZW50IGhhbmRsZXIsIG9yIG51bGwgaWYgbm9uZSB3YXMgc3VwcGxpZWQuCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5YTUxSZWFkZXIjZ2V0RW50aXR5UmVzb2x2ZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgQ29udGVudEhhbmRsZXIgZ2V0Q29udGVudEhhbmRsZXIgKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBjb250ZW50SGFuZGxlcjsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFNldCB0aGUgZXJyb3IgaGFuZGxlci4KLSAgICAgKgotICAgICAqIEBwYXJhbSBoYW5kbGVyIFRoZSBuZXcgZXJyb3IgaGFuZGxlci4KLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LlhNTFJlYWRlciNzZXRFbnRpdHlSZXNvbHZlcgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEVycm9ySGFuZGxlciAoRXJyb3JIYW5kbGVyIGhhbmRsZXIpCi0gICAgewotICAgICAgICBlcnJvckhhbmRsZXIgPSBoYW5kbGVyOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSBjdXJyZW50IGVycm9yIGhhbmRsZXIuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBjdXJyZW50IGVycm9yIGhhbmRsZXIsIG9yIG51bGwgaWYgbm9uZSB3YXMgc3VwcGxpZWQuCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5YTUxSZWFkZXIjZ2V0RW50aXR5UmVzb2x2ZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgRXJyb3JIYW5kbGVyIGdldEVycm9ySGFuZGxlciAoKQotICAgIHsKLSAgICAgICAgcmV0dXJuIGVycm9ySGFuZGxlcjsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFBhcnNlIGFuIFhNTCBkb2N1bWVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzeXN0ZW1JZCBUaGUgYWJzb2x1dGUgVVJMIG9mIHRoZSBkb2N1bWVudC4KLSAgICAgKiBAZXhjZXB0aW9uIGphdmEuaW8uSU9FeGNlcHRpb24gSWYgdGhlcmUgaXMgYSBwcm9ibGVtIHJlYWRpbmcKLSAgICAgKiAgICAgICAgICAgIHRoZSByYXcgY29udGVudCBvZiB0aGUgZG9jdW1lbnQuCi0gICAgICogQGV4Y2VwdGlvbiBTQVhFeGNlcHRpb24gSWYgdGhlcmUgaXMgYSBwcm9ibGVtCi0gICAgICogICAgICAgICAgICBwcm9jZXNzaW5nIHRoZSBkb2N1bWVudC4KLSAgICAgKiBAc2VlICNwYXJzZShvcmcueG1sLnNheC5JbnB1dFNvdXJjZSkKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LlBhcnNlciNwYXJzZShqYXZhLmxhbmcuU3RyaW5nKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHBhcnNlIChTdHJpbmcgc3lzdGVtSWQpCi0gICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBwYXJzZShuZXcgSW5wdXRTb3VyY2Uoc3lzdGVtSWQpKTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFBhcnNlIGFuIFhNTCBkb2N1bWVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBpbnB1dCBBbiBpbnB1dCBzb3VyY2UgZm9yIHRoZSBkb2N1bWVudC4KLSAgICAgKiBAZXhjZXB0aW9uIGphdmEuaW8uSU9FeGNlcHRpb24gSWYgdGhlcmUgaXMgYSBwcm9ibGVtIHJlYWRpbmcKLSAgICAgKiAgICAgICAgICAgIHRoZSByYXcgY29udGVudCBvZiB0aGUgZG9jdW1lbnQuCi0gICAgICogQGV4Y2VwdGlvbiBTQVhFeGNlcHRpb24gSWYgdGhlcmUgaXMgYSBwcm9ibGVtCi0gICAgICogICAgICAgICAgICBwcm9jZXNzaW5nIHRoZSBkb2N1bWVudC4KLSAgICAgKiBAc2VlICNwYXJzZShqYXZhLmxhbmcuU3RyaW5nKQotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguUGFyc2VyI3BhcnNlKG9yZy54bWwuc2F4LklucHV0U291cmNlKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHBhcnNlIChJbnB1dFNvdXJjZSBpbnB1dCkKLSAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGlmIChwYXJzaW5nKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKCJQYXJzZXIgaXMgYWxyZWFkeSBpbiB1c2UiKTsKLSAgICAgICAgfQotICAgICAgICBzZXR1cFBhcnNlcigpOwotICAgICAgICBwYXJzaW5nID0gdHJ1ZTsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIHBhcnNlci5wYXJzZShpbnB1dCk7Ci0gICAgICAgIH0gZmluYWxseSB7Ci0gICAgICAgICAgICBwYXJzaW5nID0gZmFsc2U7Ci0gICAgICAgIH0KLSAgICAgICAgcGFyc2luZyA9IGZhbHNlOwotICAgIH0KLQotCi0KLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotICAgIC8vIEltcGxlbWVudGF0aW9uIG9mIG9yZy54bWwuc2F4LkRvY3VtZW50SGFuZGxlci4KLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotCi0KLSAgICAvKioKLSAgICAgKiBBZGFwdGVyIGltcGxlbWVudGF0aW9uIG1ldGhvZDsgZG8gbm90IGNhbGwuCi0gICAgICogQWRhcHQgYSBTQVgxIGRvY3VtZW50IGxvY2F0b3IgZXZlbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbG9jYXRvciBBIGRvY3VtZW50IGxvY2F0b3IuCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNzZXREb2N1bWVudExvY2F0b3IKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXREb2N1bWVudExvY2F0b3IgKExvY2F0b3IgbG9jYXRvcikKLSAgICB7Ci0gICAgICAgIHRoaXMubG9jYXRvciA9IGxvY2F0b3I7Ci0gICAgICAgIGlmIChjb250ZW50SGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBjb250ZW50SGFuZGxlci5zZXREb2N1bWVudExvY2F0b3IobG9jYXRvcik7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIEFkYXB0ZXIgaW1wbGVtZW50YXRpb24gbWV0aG9kOyBkbyBub3QgY2FsbC4KLSAgICAgKiBBZGFwdCBhIFNBWDEgc3RhcnQgZG9jdW1lbnQgZXZlbnQuCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIFNBWEV4Y2VwdGlvbiBUaGUgY2xpZW50IG1heSByYWlzZSBhCi0gICAgICogICAgICAgICAgICBwcm9jZXNzaW5nIGV4Y2VwdGlvbi4KLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkRvY3VtZW50SGFuZGxlciNzdGFydERvY3VtZW50Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnREb2N1bWVudCAoKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAoY29udGVudEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgY29udGVudEhhbmRsZXIuc3RhcnREb2N1bWVudCgpOwotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBBZGFwdGVyIGltcGxlbWVudGF0aW9uIG1ldGhvZDsgZG8gbm90IGNhbGwuCi0gICAgICogQWRhcHQgYSBTQVgxIGVuZCBkb2N1bWVudCBldmVudC4KLSAgICAgKgotICAgICAqIEBleGNlcHRpb24gU0FYRXhjZXB0aW9uIFRoZSBjbGllbnQgbWF5IHJhaXNlIGEKLSAgICAgKiAgICAgICAgICAgIHByb2Nlc3NpbmcgZXhjZXB0aW9uLgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguRG9jdW1lbnRIYW5kbGVyI2VuZERvY3VtZW50Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kRG9jdW1lbnQgKCkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaWYgKGNvbnRlbnRIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGNvbnRlbnRIYW5kbGVyLmVuZERvY3VtZW50KCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIEFkYXB0ZXIgaW1wbGVtZW50YXRpb24gbWV0aG9kOyBkbyBub3QgY2FsbC4KLSAgICAgKiBBZGFwdCBhIFNBWDEgc3RhcnRFbGVtZW50IGV2ZW50LgotICAgICAqCi0gICAgICogPHA+SWYgbmVjZXNzYXJ5LCBwZXJmb3JtIE5hbWVzcGFjZSBwcm9jZXNzaW5nLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBxTmFtZSBUaGUgcXVhbGlmaWVkIChwcmVmaXhlZCkgbmFtZS4KLSAgICAgKiBAcGFyYW0gcUF0dHMgVGhlIFhNTCBhdHRyaWJ1dGUgbGlzdCAod2l0aCBxbmFtZXMpLgotICAgICAqIEBleGNlcHRpb24gU0FYRXhjZXB0aW9uIFRoZSBjbGllbnQgbWF5IHJhaXNlIGEKLSAgICAgKiAgICAgICAgICAgIHByb2Nlc3NpbmcgZXhjZXB0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudCAoU3RyaW5nIHFOYW1lLCBBdHRyaWJ1dGVMaXN0IHFBdHRzKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGVzZSBhcmUgZXhjZXB0aW9ucyBmcm9tIHRoZQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBmaXJzdCBwYXNzOyB0aGV5IHNob3VsZCBiZQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpZ25vcmVkIGlmIHRoZXJlJ3MgYSBzZWNvbmQgcGFzcywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYnV0IHJlcG9ydGVkIG90aGVyd2lzZS4KLSAgICAgICAgVmVjdG9yIGV4Y2VwdGlvbnMgPSBudWxsOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIElmIHdlJ3JlIG5vdCBkb2luZyBOYW1lc3BhY2UKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcHJvY2Vzc2luZywgZGlzcGF0Y2ggdGhpcyBxdWlja2x5LgotICAgICAgICBpZiAoIW5hbWVzcGFjZXMpIHsKLSAgICAgICAgICAgIGlmIChjb250ZW50SGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgYXR0QWRhcHRlci5zZXRBdHRyaWJ1dGVMaXN0KHFBdHRzKTsKLSAgICAgICAgICAgICAgICBjb250ZW50SGFuZGxlci5zdGFydEVsZW1lbnQoIiIsICIiLCBxTmFtZS5pbnRlcm4oKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0QWRhcHRlcik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLQotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9LLCB3ZSdyZSBkb2luZyBOYW1lc3BhY2UgcHJvY2Vzc2luZy4KLSAgICAgICAgbnNTdXBwb3J0LnB1c2hDb250ZXh0KCk7Ci0gICAgICAgIGludCBsZW5ndGggPSBxQXR0cy5nZXRMZW5ndGgoKTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBGaXJzdCBwYXNzOiAgaGFuZGxlIE5TIGRlY2xzCi0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKLSAgICAgICAgICAgIFN0cmluZyBhdHRRTmFtZSA9IHFBdHRzLmdldE5hbWUoaSk7Ci0KLSAgICAgICAgICAgIGlmICghYXR0UU5hbWUuc3RhcnRzV2l0aCgieG1sbnMiKSkKLSAgICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ291bGQgYmUgYSBkZWNsYXJhdGlvbi4uLgotICAgICAgICAgICAgU3RyaW5nIHByZWZpeDsKLSAgICAgICAgICAgIGludCBuID0gYXR0UU5hbWUuaW5kZXhPZignOicpOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHhtbG5zPS4uLgotICAgICAgICAgICAgaWYgKG4gPT0gLTEgJiYgYXR0UU5hbWUubGVuZ3RoICgpID09IDUpIHsKLSAgICAgICAgICAgICAgICBwcmVmaXggPSAiIjsKLSAgICAgICAgICAgIH0gZWxzZSBpZiAobiAhPSA1KSB7Ci0gICAgICAgICAgICAgICAgLy8gWE1MIG5hbWVzcGFjZXMgc3BlYyBkb2Vzbid0IGRpc2N1c3MgInhtbG5zZjpvbyIKLSAgICAgICAgICAgICAgICAvLyAoYW5kIHNpbWlsYXJseSBuYW1lZCkgYXR0cmlidXRlcyAuLi4gYXQgbW9zdCwgd2FybgotICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgfSBlbHNlICAgICAgICAgICAgICAvLyB4bWxuczpmb289Li4uCi0gICAgICAgICAgICAgICAgcHJlZml4ID0gYXR0UU5hbWUuc3Vic3RyaW5nKG4rMSk7Ci0KLSAgICAgICAgICAgIFN0cmluZyB2YWx1ZSA9IHFBdHRzLmdldFZhbHVlKGkpOwotICAgICAgICAgICAgaWYgKCFuc1N1cHBvcnQuZGVjbGFyZVByZWZpeChwcmVmaXgsIHZhbHVlKSkgewotICAgICAgICAgICAgICAgIHJlcG9ydEVycm9yKCJJbGxlZ2FsIE5hbWVzcGFjZSBwcmVmaXg6ICIgKyBwcmVmaXgpOwotICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKGNvbnRlbnRIYW5kbGVyICE9IG51bGwpCi0gICAgICAgICAgICAgICAgY29udGVudEhhbmRsZXIuc3RhcnRQcmVmaXhNYXBwaW5nKHByZWZpeCwgdmFsdWUpOwotICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2Vjb25kIHBhc3M6IGNvcHkgYWxsIHJlbGV2YW50Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGF0dHJpYnV0ZXMgaW50byB0aGUgU0FYMiBBdHRyaWJ1dGVMaXN0Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHVzaW5nIHVwZGF0ZWQgcHJlZml4IGJpbmRpbmdzCi0gICAgICAgIGF0dHMuY2xlYXIoKTsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykgewotICAgICAgICAgICAgU3RyaW5nIGF0dFFOYW1lID0gcUF0dHMuZ2V0TmFtZShpKTsKLSAgICAgICAgICAgIFN0cmluZyB0eXBlID0gcUF0dHMuZ2V0VHlwZShpKTsKLSAgICAgICAgICAgIFN0cmluZyB2YWx1ZSA9IHFBdHRzLmdldFZhbHVlKGkpOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIERlY2xhcmF0aW9uPwotICAgICAgICAgICAgaWYgKGF0dFFOYW1lLnN0YXJ0c1dpdGgoInhtbG5zIikpIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgcHJlZml4OwotICAgICAgICAgICAgICAgIGludCBuID0gYXR0UU5hbWUuaW5kZXhPZignOicpOwotCi0gICAgICAgICAgICAgICAgaWYgKG4gPT0gLTEgJiYgYXR0UU5hbWUubGVuZ3RoICgpID09IDUpIHsKLSAgICAgICAgICAgICAgICAgICAgcHJlZml4ID0gIiI7Ci0gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChuICE9IDUpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gWE1MIG5hbWVzcGFjZXMgc3BlYyBkb2Vzbid0IGRpc2N1c3MgInhtbG5zZjpvbyIKLSAgICAgICAgICAgICAgICAgICAgLy8gKGFuZCBzaW1pbGFybHkgbmFtZWQpIGF0dHJpYnV0ZXMgLi4uIGlnbm9yZQotICAgICAgICAgICAgICAgICAgICBwcmVmaXggPSBudWxsOwotICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIHByZWZpeCA9IGF0dFFOYW1lLnN1YnN0cmluZyg2KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFllcywgZGVjbDogIHJlcG9ydCBvciBwcnVuZQotICAgICAgICAgICAgICAgIGlmIChwcmVmaXggIT0gbnVsbCkgewotICAgICAgICAgICAgICAgICAgICBpZiAocHJlZml4ZXMpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmICh1cmlzKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG5vdGUgZnVua3kgY2FzZTogIGxvY2FsbmFtZSBjYW4gYmUgbnVsbAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHdoZW4gZGVjbGFyaW5nIHRoZSBkZWZhdWx0IHByZWZpeCwgYW5kCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8geWV0IHRoZSB1cmkgaXNuJ3QgbnVsbC4KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRzLmFkZEF0dHJpYnV0ZSAobnNTdXBwb3J0LlhNTE5TLCBwcmVmaXgsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRRTmFtZS5pbnRlcm4oKSwgdHlwZSwgdmFsdWUpOwotICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHMuYWRkQXR0cmlidXRlICgiIiwgIiIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRRTmFtZS5pbnRlcm4oKSwgdHlwZSwgdmFsdWUpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBOb3QgYSBkZWNsYXJhdGlvbiAtLSByZXBvcnQKLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIGF0dE5hbWVbXSA9IHByb2Nlc3NOYW1lKGF0dFFOYW1lLCB0cnVlLCB0cnVlKTsKLSAgICAgICAgICAgICAgICBhdHRzLmFkZEF0dHJpYnV0ZShhdHROYW1lWzBdLCBhdHROYW1lWzFdLCBhdHROYW1lWzJdLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUsIHZhbHVlKTsKLSAgICAgICAgICAgIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgaWYgKGV4Y2VwdGlvbnMgPT0gbnVsbCkKLSAgICAgICAgICAgICAgICAgICAgZXhjZXB0aW9ucyA9IG5ldyBWZWN0b3IoKTsKLSAgICAgICAgICAgICAgICBleGNlcHRpb25zLmFkZEVsZW1lbnQoZSk7Ci0gICAgICAgICAgICAgICAgYXR0cy5hZGRBdHRyaWJ1dGUoIiIsIGF0dFFOYW1lLCBhdHRRTmFtZSwgdHlwZSwgdmFsdWUpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gbm93IGhhbmRsZSB0aGUgZGVmZXJyZWQgZXhjZXB0aW9uIHJlcG9ydHMKLSAgICAgICAgaWYgKGV4Y2VwdGlvbnMgIT0gbnVsbCAmJiBlcnJvckhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBleGNlcHRpb25zLnNpemUoKTsgaSsrKQotICAgICAgICAgICAgICAgIGVycm9ySGFuZGxlci5lcnJvcigoU0FYUGFyc2VFeGNlcHRpb24pCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChleGNlcHRpb25zLmVsZW1lbnRBdChpKSkpOwotICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gT0ssIGZpbmFsbHkgcmVwb3J0IHRoZSBldmVudC4KLSAgICAgICAgaWYgKGNvbnRlbnRIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIFN0cmluZyBuYW1lW10gPSBwcm9jZXNzTmFtZShxTmFtZSwgZmFsc2UsIGZhbHNlKTsKLSAgICAgICAgICAgIGNvbnRlbnRIYW5kbGVyLnN0YXJ0RWxlbWVudChuYW1lWzBdLCBuYW1lWzFdLCBuYW1lWzJdLCBhdHRzKTsKLSAgICAgICAgfQotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogQWRhcHRlciBpbXBsZW1lbnRhdGlvbiBtZXRob2Q7IGRvIG5vdCBjYWxsLgotICAgICAqIEFkYXB0IGEgU0FYMSBlbmQgZWxlbWVudCBldmVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBxTmFtZSBUaGUgcXVhbGlmaWVkIChwcmVmaXhlZCkgbmFtZS4KLSAgICAgKiBAZXhjZXB0aW9uIFNBWEV4Y2VwdGlvbiBUaGUgY2xpZW50IG1heSByYWlzZSBhCi0gICAgICogICAgICAgICAgICBwcm9jZXNzaW5nIGV4Y2VwdGlvbi4KLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkRvY3VtZW50SGFuZGxlciNlbmRFbGVtZW50Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kRWxlbWVudCAoU3RyaW5nIHFOYW1lKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJZiB3ZSdyZSBub3QgZG9pbmcgTmFtZXNwYWNlCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHByb2Nlc3NpbmcsIGRpc3BhdGNoIHRoaXMgcXVpY2tseS4KLSAgICAgICAgaWYgKCFuYW1lc3BhY2VzKSB7Ci0gICAgICAgICAgICBpZiAoY29udGVudEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgICAgIGNvbnRlbnRIYW5kbGVyLmVuZEVsZW1lbnQoIiIsICIiLCBxTmFtZS5pbnRlcm4oKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTcGxpdCB0aGUgbmFtZS4KLSAgICAgICAgU3RyaW5nIG5hbWVzW10gPSBwcm9jZXNzTmFtZShxTmFtZSwgZmFsc2UsIGZhbHNlKTsKLSAgICAgICAgaWYgKGNvbnRlbnRIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGNvbnRlbnRIYW5kbGVyLmVuZEVsZW1lbnQobmFtZXNbMF0sIG5hbWVzWzFdLCBuYW1lc1syXSk7Ci0gICAgICAgICAgICBFbnVtZXJhdGlvbiBwcmVmaXhlcyA9IG5zU3VwcG9ydC5nZXREZWNsYXJlZFByZWZpeGVzKCk7Ci0gICAgICAgICAgICB3aGlsZSAocHJlZml4ZXMuaGFzTW9yZUVsZW1lbnRzKCkpIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgcHJlZml4ID0gKFN0cmluZylwcmVmaXhlcy5uZXh0RWxlbWVudCgpOwotICAgICAgICAgICAgICAgIGNvbnRlbnRIYW5kbGVyLmVuZFByZWZpeE1hcHBpbmcocHJlZml4KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBuc1N1cHBvcnQucG9wQ29udGV4dCgpOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogQWRhcHRlciBpbXBsZW1lbnRhdGlvbiBtZXRob2Q7IGRvIG5vdCBjYWxsLgotICAgICAqIEFkYXB0IGEgU0FYMSBjaGFyYWN0ZXJzIGV2ZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIGNoIEFuIGFycmF5IG9mIGNoYXJhY3RlcnMuCi0gICAgICogQHBhcmFtIHN0YXJ0IFRoZSBzdGFydGluZyBwb3NpdGlvbiBpbiB0aGUgYXJyYXkuCi0gICAgICogQHBhcmFtIGxlbmd0aCBUaGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gdXNlLgotICAgICAqIEBleGNlcHRpb24gU0FYRXhjZXB0aW9uIFRoZSBjbGllbnQgbWF5IHJhaXNlIGEKLSAgICAgKiAgICAgICAgICAgIHByb2Nlc3NpbmcgZXhjZXB0aW9uLgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguRG9jdW1lbnRIYW5kbGVyI2NoYXJhY3RlcnMKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBjaGFyYWN0ZXJzIChjaGFyIGNoW10sIGludCBzdGFydCwgaW50IGxlbmd0aCkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaWYgKGNvbnRlbnRIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGNvbnRlbnRIYW5kbGVyLmNoYXJhY3RlcnMoY2gsIHN0YXJ0LCBsZW5ndGgpOwotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBBZGFwdGVyIGltcGxlbWVudGF0aW9uIG1ldGhvZDsgZG8gbm90IGNhbGwuCi0gICAgICogQWRhcHQgYSBTQVgxIGlnbm9yYWJsZSB3aGl0ZXNwYWNlIGV2ZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIGNoIEFuIGFycmF5IG9mIGNoYXJhY3RlcnMuCi0gICAgICogQHBhcmFtIHN0YXJ0IFRoZSBzdGFydGluZyBwb3NpdGlvbiBpbiB0aGUgYXJyYXkuCi0gICAgICogQHBhcmFtIGxlbmd0aCBUaGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gdXNlLgotICAgICAqIEBleGNlcHRpb24gU0FYRXhjZXB0aW9uIFRoZSBjbGllbnQgbWF5IHJhaXNlIGEKLSAgICAgKiAgICAgICAgICAgIHByb2Nlc3NpbmcgZXhjZXB0aW9uLgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguRG9jdW1lbnRIYW5kbGVyI2lnbm9yYWJsZVdoaXRlc3BhY2UKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBpZ25vcmFibGVXaGl0ZXNwYWNlIChjaGFyIGNoW10sIGludCBzdGFydCwgaW50IGxlbmd0aCkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaWYgKGNvbnRlbnRIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGNvbnRlbnRIYW5kbGVyLmlnbm9yYWJsZVdoaXRlc3BhY2UoY2gsIHN0YXJ0LCBsZW5ndGgpOwotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBBZGFwdGVyIGltcGxlbWVudGF0aW9uIG1ldGhvZDsgZG8gbm90IGNhbGwuCi0gICAgICogQWRhcHQgYSBTQVgxIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gZXZlbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdGFyZ2V0IFRoZSBwcm9jZXNzaW5nIGluc3RydWN0aW9uIHRhcmdldC4KLSAgICAgKiBAcGFyYW0gZGF0YSBUaGUgcmVtYWluZGVyIG9mIHRoZSBwcm9jZXNzaW5nIGluc3RydWN0aW9uCi0gICAgICogQGV4Y2VwdGlvbiBTQVhFeGNlcHRpb24gVGhlIGNsaWVudCBtYXkgcmFpc2UgYQotICAgICAqICAgICAgICAgICAgcHJvY2Vzc2luZyBleGNlcHRpb24uCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5Eb2N1bWVudEhhbmRsZXIjcHJvY2Vzc2luZ0luc3RydWN0aW9uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcHJvY2Vzc2luZ0luc3RydWN0aW9uIChTdHJpbmcgdGFyZ2V0LCBTdHJpbmcgZGF0YSkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaWYgKGNvbnRlbnRIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGNvbnRlbnRIYW5kbGVyLnByb2Nlc3NpbmdJbnN0cnVjdGlvbih0YXJnZXQsIGRhdGEpOwotICAgICAgICB9Ci0gICAgfQotCi0KLQotICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0gICAgLy8gSW50ZXJuYWwgdXRpbGl0eSBtZXRob2RzLgotICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0KLQotICAgIC8qKgotICAgICAqIEluaXRpYWxpemUgdGhlIHBhcnNlciBiZWZvcmUgZWFjaCBydW4uCi0gICAgICovCi0gICAgcHJpdmF0ZSB2b2lkIHNldHVwUGFyc2VyICgpCi0gICAgewotICAgICAgICAvLyBjYXRjaCBhbiBpbGxlZ2FsICJub25zZW5zZSIgc3RhdGUuCi0gICAgICAgIGlmICghcHJlZml4ZXMgJiYgIW5hbWVzcGFjZXMpCi0gICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uICgpOwotCi0gICAgICAgIG5zU3VwcG9ydC5yZXNldCgpOwotICAgICAgICBpZiAodXJpcykKLSAgICAgICAgICAgIG5zU3VwcG9ydC5zZXROYW1lc3BhY2VEZWNsVXJpcyAodHJ1ZSk7Ci0KLSAgICAgICAgaWYgKGVudGl0eVJlc29sdmVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIHBhcnNlci5zZXRFbnRpdHlSZXNvbHZlcihlbnRpdHlSZXNvbHZlcik7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGR0ZEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgcGFyc2VyLnNldERUREhhbmRsZXIoZHRkSGFuZGxlcik7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKGVycm9ySGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBwYXJzZXIuc2V0RXJyb3JIYW5kbGVyKGVycm9ySGFuZGxlcik7Ci0gICAgICAgIH0KLSAgICAgICAgcGFyc2VyLnNldERvY3VtZW50SGFuZGxlcih0aGlzKTsKLSAgICAgICAgbG9jYXRvciA9IG51bGw7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBQcm9jZXNzIGEgcXVhbGlmaWVkIChwcmVmaXhlZCkgbmFtZS4KLSAgICAgKgotICAgICAqIDxwPklmIHRoZSBuYW1lIGhhcyBhbiB1bmRlY2xhcmVkIHByZWZpeCwgdXNlIG9ubHkgdGhlIHFuYW1lCi0gICAgICogYW5kIG1ha2UgYW4gRXJyb3JIYW5kbGVyLmVycm9yIGNhbGxiYWNrIGluIGNhc2UgdGhlIGFwcCBpcwotICAgICAqIGludGVyZXN0ZWQuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIHFOYW1lIFRoZSBxdWFsaWZpZWQgKHByZWZpeGVkKSBuYW1lLgotICAgICAqIEBwYXJhbSBpc0F0dHJpYnV0ZSB0cnVlIGlmIHRoaXMgaXMgYW4gYXR0cmlidXRlIG5hbWUuCi0gICAgICogQHJldHVybiBUaGUgbmFtZSBzcGxpdCBpbnRvIHRocmVlIHBhcnRzLgotICAgICAqIEBleGNlcHRpb24gU0FYRXhjZXB0aW9uIFRoZSBjbGllbnQgbWF5IHRocm93Ci0gICAgICogICAgICAgICAgICBhbiBleGNlcHRpb24gaWYgdGhlcmUgaXMgYW4gZXJyb3IgY2FsbGJhY2suCi0gICAgICovCi0gICAgcHJpdmF0ZSBTdHJpbmcgW10gcHJvY2Vzc05hbWUgKFN0cmluZyBxTmFtZSwgYm9vbGVhbiBpc0F0dHJpYnV0ZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiB1c2VFeGNlcHRpb24pCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIFN0cmluZyBwYXJ0c1tdID0gbnNTdXBwb3J0LnByb2Nlc3NOYW1lKHFOYW1lLCBuYW1lUGFydHMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzQXR0cmlidXRlKTsKLSAgICAgICAgaWYgKHBhcnRzID09IG51bGwpIHsKLSAgICAgICAgICAgIGlmICh1c2VFeGNlcHRpb24pCi0gICAgICAgICAgICAgICAgdGhyb3cgbWFrZUV4Y2VwdGlvbigiVW5kZWNsYXJlZCBwcmVmaXg6ICIgKyBxTmFtZSk7Ci0gICAgICAgICAgICByZXBvcnRFcnJvcigiVW5kZWNsYXJlZCBwcmVmaXg6ICIgKyBxTmFtZSk7Ci0gICAgICAgICAgICBwYXJ0cyA9IG5ldyBTdHJpbmdbM107Ci0gICAgICAgICAgICBwYXJ0c1swXSA9IHBhcnRzWzFdID0gIiI7Ci0gICAgICAgICAgICBwYXJ0c1syXSA9IHFOYW1lLmludGVybigpOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBwYXJ0czsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFJlcG9ydCBhIG5vbi1mYXRhbCBlcnJvci4KLSAgICAgKgotICAgICAqIEBwYXJhbSBtZXNzYWdlIFRoZSBlcnJvciBtZXNzYWdlLgotICAgICAqIEBleGNlcHRpb24gU0FYRXhjZXB0aW9uIFRoZSBjbGllbnQgbWF5IHRocm93Ci0gICAgICogICAgICAgICAgICBhbiBleGNlcHRpb24uCi0gICAgICovCi0gICAgdm9pZCByZXBvcnRFcnJvciAoU3RyaW5nIG1lc3NhZ2UpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGlmIChlcnJvckhhbmRsZXIgIT0gbnVsbCkKLSAgICAgICAgICAgIGVycm9ySGFuZGxlci5lcnJvcihtYWtlRXhjZXB0aW9uKG1lc3NhZ2UpKTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdCBhbiBleGNlcHRpb24gZm9yIHRoZSBjdXJyZW50IGNvbnRleHQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbWVzc2FnZSBUaGUgZXJyb3IgbWVzc2FnZS4KLSAgICAgKi8KLSAgICBwcml2YXRlIFNBWFBhcnNlRXhjZXB0aW9uIG1ha2VFeGNlcHRpb24gKFN0cmluZyBtZXNzYWdlKQotICAgIHsKLSAgICAgICAgaWYgKGxvY2F0b3IgIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIG5ldyBTQVhQYXJzZUV4Y2VwdGlvbihtZXNzYWdlLCBsb2NhdG9yKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiBuZXcgU0FYUGFyc2VFeGNlcHRpb24obWVzc2FnZSwgbnVsbCwgbnVsbCwgLTEsIC0xKTsKLSAgICAgICAgfQotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogVGhyb3cgYW4gZXhjZXB0aW9uIGlmIHdlIGFyZSBwYXJzaW5nLgotICAgICAqCi0gICAgICogPHA+VXNlIHRoaXMgbWV0aG9kIHRvIGRldGVjdCBpbGxlZ2FsIGZlYXR1cmUgb3IKLSAgICAgKiBwcm9wZXJ0eSBjaGFuZ2VzLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSB0eXBlIFRoZSB0eXBlIG9mIHRoaW5nIChmZWF0dXJlIG9yIHByb3BlcnR5KS4KLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgZmVhdHVyZSBvciBwcm9wZXJ0eSBuYW1lLgotICAgICAqIEBleGNlcHRpb24gU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIElmIGEKLSAgICAgKiAgICAgICAgICAgIGRvY3VtZW50IGlzIGN1cnJlbnRseSBiZWluZyBwYXJzZWQuCi0gICAgICovCi0gICAgcHJpdmF0ZSB2b2lkIGNoZWNrTm90UGFyc2luZyAoU3RyaW5nIHR5cGUsIFN0cmluZyBuYW1lKQotICAgICAgICB0aHJvd3MgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAocGFyc2luZykgewotICAgICAgICAgICAgdGhyb3cgbmV3IFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbigiQ2Fubm90IGNoYW5nZSAiICsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZSArICcgJyArCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUgKyAiIHdoaWxlIHBhcnNpbmciKTsKLQotICAgICAgICB9Ci0gICAgfQotCi0KLQotICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0gICAgLy8gSW50ZXJuYWwgc3RhdGUuCi0gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLQotICAgIHByaXZhdGUgTmFtZXNwYWNlU3VwcG9ydCBuc1N1cHBvcnQ7Ci0gICAgcHJpdmF0ZSBBdHRyaWJ1dGVMaXN0QWRhcHRlciBhdHRBZGFwdGVyOwotCi0gICAgcHJpdmF0ZSBib29sZWFuIHBhcnNpbmcgPSBmYWxzZTsKLSAgICBwcml2YXRlIFN0cmluZyBuYW1lUGFydHNbXSA9IG5ldyBTdHJpbmdbM107Ci0KLSAgICBwcml2YXRlIFBhcnNlciBwYXJzZXIgPSBudWxsOwotCi0gICAgcHJpdmF0ZSBBdHRyaWJ1dGVzSW1wbCBhdHRzID0gbnVsbDsKLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBGZWF0dXJlcwotICAgIHByaXZhdGUgYm9vbGVhbiBuYW1lc3BhY2VzID0gdHJ1ZTsKLSAgICBwcml2YXRlIGJvb2xlYW4gcHJlZml4ZXMgPSBmYWxzZTsKLSAgICBwcml2YXRlIGJvb2xlYW4gdXJpcyA9IGZhbHNlOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFByb3BlcnRpZXMKLQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBIYW5kbGVycwotICAgIExvY2F0b3IgbG9jYXRvcjsKLQotICAgIEVudGl0eVJlc29sdmVyIGVudGl0eVJlc29sdmVyID0gbnVsbDsKLSAgICBEVERIYW5kbGVyIGR0ZEhhbmRsZXIgPSBudWxsOwotICAgIENvbnRlbnRIYW5kbGVyIGNvbnRlbnRIYW5kbGVyID0gbnVsbDsKLSAgICBFcnJvckhhbmRsZXIgZXJyb3JIYW5kbGVyID0gbnVsbDsKLQotCi0KLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotICAgIC8vIElubmVyIGNsYXNzIHRvIHdyYXAgYW4gQXR0cmlidXRlTGlzdCB3aGVuIG5vdCBkb2luZyBOUyBwcm9jLgotICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0KLQotICAgIC8qKgotICAgICAqIEFkYXB0IGEgU0FYMSBBdHRyaWJ1dGVMaXN0IGFzIGEgU0FYMiBBdHRyaWJ1dGVzIG9iamVjdC4KLSAgICAgKgotICAgICAqIDxwPlRoaXMgY2xhc3MgaXMgaW4gdGhlIFB1YmxpYyBEb21haW4sIGFuZCBjb21lcyB3aXRoIE5PCi0gICAgICogV0FSUkFOVFkgb2YgYW55IGtpbmQuPC9wPgotICAgICAqCi0gICAgICogPHA+VGhpcyB3cmFwcGVyIGNsYXNzIGlzIHVzZWQgb25seSB3aGVuIE5hbWVzcGFjZSBzdXBwb3J0Ci0gICAgICogaXMgZGlzYWJsZWQgLS0gaXQgcHJvdmlkZXMgcHJldHR5IG11Y2ggYSBkaXJlY3QgbWFwcGluZwotICAgICAqIGZyb20gU0FYMSB0byBTQVgyLCBleGNlcHQgdGhhdCBuYW1lcyBhbmQgdHlwZXMgYXJlCi0gICAgICogaW50ZXJuZWQgd2hlbmV2ZXIgcmVxdWVzdGVkLjwvcD4KLSAgICAgKi8KLSAgICBmaW5hbCBjbGFzcyBBdHRyaWJ1dGVMaXN0QWRhcHRlciBpbXBsZW1lbnRzIEF0dHJpYnV0ZXMKLSAgICB7Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIENvbnN0cnVjdCBhIG5ldyBhZGFwdGVyLgotICAgICAgICAgKi8KLSAgICAgICAgQXR0cmlidXRlTGlzdEFkYXB0ZXIgKCkKLSAgICAgICAgewotICAgICAgICB9Ci0KLQotICAgICAgICAvKioKLSAgICAgICAgICogU2V0IHRoZSBlbWJlZGRlZCBBdHRyaWJ1dGVMaXN0LgotICAgICAgICAgKgotICAgICAgICAgKiA8cD5UaGlzIG1ldGhvZCBtdXN0IGJlIGludm9rZWQgYmVmb3JlIGFueSBvZiB0aGUgb3RoZXJzCi0gICAgICAgICAqIGNhbiBiZSB1c2VkLjwvcD4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIFRoZSBTQVgxIGF0dHJpYnV0ZSBsaXN0ICh3aXRoIHFuYW1lcykuCi0gICAgICAgICAqLwotICAgICAgICB2b2lkIHNldEF0dHJpYnV0ZUxpc3QgKEF0dHJpYnV0ZUxpc3QgcUF0dHMpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHRoaXMucUF0dHMgPSBxQXR0czsKLSAgICAgICAgfQotCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFJldHVybiB0aGUgbGVuZ3RoIG9mIHRoZSBhdHRyaWJ1dGUgbGlzdC4KLSAgICAgICAgICoKLSAgICAgICAgICogQHJldHVybiBUaGUgbnVtYmVyIG9mIGF0dHJpYnV0ZXMgaW4gdGhlIGxpc3QuCi0gICAgICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQXR0cmlidXRlcyNnZXRMZW5ndGgKLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBpbnQgZ2V0TGVuZ3RoICgpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHJldHVybiBxQXR0cy5nZXRMZW5ndGgoKTsKLSAgICAgICAgfQotCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFJldHVybiB0aGUgTmFtZXNwYWNlIFVSSSBvZiB0aGUgc3BlY2lmaWVkIGF0dHJpYnV0ZS4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIFRoZSBhdHRyaWJ1dGUncyBpbmRleC4KLSAgICAgICAgICogQHJldHVybiBBbHdheXMgdGhlIGVtcHR5IHN0cmluZy4KLSAgICAgICAgICogQHNlZSBvcmcueG1sLnNheC5BdHRyaWJ1dGVzI2dldFVSSQotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIFN0cmluZyBnZXRVUkkgKGludCBpKQotICAgICAgICB7Ci0gICAgICAgICAgICByZXR1cm4gIiI7Ci0gICAgICAgIH0KLQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBSZXR1cm4gdGhlIGxvY2FsIG5hbWUgb2YgdGhlIHNwZWNpZmllZCBhdHRyaWJ1dGUuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBUaGUgYXR0cmlidXRlJ3MgaW5kZXguCi0gICAgICAgICAqIEByZXR1cm4gQWx3YXlzIHRoZSBlbXB0eSBzdHJpbmcuCi0gICAgICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQXR0cmlidXRlcyNnZXRMb2NhbE5hbWUKLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0TG9jYWxOYW1lIChpbnQgaSkKLSAgICAgICAgewotICAgICAgICAgICAgcmV0dXJuICIiOwotICAgICAgICB9Ci0KLQotICAgICAgICAvKioKLSAgICAgICAgICogUmV0dXJuIHRoZSBxdWFsaWZpZWQgKHByZWZpeGVkKSBuYW1lIG9mIHRoZSBzcGVjaWZpZWQgYXR0cmlidXRlLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gVGhlIGF0dHJpYnV0ZSdzIGluZGV4LgotICAgICAgICAgKiBAcmV0dXJuIFRoZSBhdHRyaWJ1dGUncyBxdWFsaWZpZWQgbmFtZSwgaW50ZXJuYWxpemVkLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIFN0cmluZyBnZXRRTmFtZSAoaW50IGkpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHJldHVybiBxQXR0cy5nZXROYW1lKGkpLmludGVybigpOwotICAgICAgICB9Ci0KLQotICAgICAgICAvKioKLSAgICAgICAgICogUmV0dXJuIHRoZSB0eXBlIG9mIHRoZSBzcGVjaWZpZWQgYXR0cmlidXRlLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gVGhlIGF0dHJpYnV0ZSdzIGluZGV4LgotICAgICAgICAgKiBAcmV0dXJuIFRoZSBhdHRyaWJ1dGUncyB0eXBlIGFzIGFuIGludGVybmFsaXplZCBzdHJpbmcuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFR5cGUgKGludCBpKQotICAgICAgICB7Ci0gICAgICAgICAgICByZXR1cm4gcUF0dHMuZ2V0VHlwZShpKS5pbnRlcm4oKTsKLSAgICAgICAgfQotCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFJldHVybiB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBhdHRyaWJ1dGUuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBUaGUgYXR0cmlidXRlJ3MgaW5kZXguCi0gICAgICAgICAqIEByZXR1cm4gVGhlIGF0dHJpYnV0ZSdzIHZhbHVlLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIFN0cmluZyBnZXRWYWx1ZSAoaW50IGkpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHJldHVybiBxQXR0cy5nZXRWYWx1ZShpKTsKLSAgICAgICAgfQotCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIExvb2sgdXAgYW4gYXR0cmlidXRlIGluZGV4IGJ5IE5hbWVzcGFjZSBuYW1lLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gdXJpIFRoZSBOYW1lc3BhY2UgVVJJIG9yIHRoZSBlbXB0eSBzdHJpbmcuCi0gICAgICAgICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGxvY2FsIG5hbWUuCi0gICAgICAgICAqIEByZXR1cm4gVGhlIGF0dHJpYnV0ZXMgaW5kZXgsIG9yIC0xIGlmIG5vbmUgd2FzIGZvdW5kLgotICAgICAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkF0dHJpYnV0ZXMjZ2V0SW5kZXgoamF2YS5sYW5nLlN0cmluZyxqYXZhLmxhbmcuU3RyaW5nKQotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIGludCBnZXRJbmRleCAoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSkKLSAgICAgICAgewotICAgICAgICAgICAgcmV0dXJuIC0xOwotICAgICAgICB9Ci0KLQotICAgICAgICAvKioKLSAgICAgICAgICogTG9vayB1cCBhbiBhdHRyaWJ1dGUgaW5kZXggYnkgcXVhbGlmaWVkIChwcmVmaXhlZCkgbmFtZS4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIHFOYW1lIFRoZSBxdWFsaWZpZWQgbmFtZS4KLSAgICAgICAgICogQHJldHVybiBUaGUgYXR0cmlidXRlcyBpbmRleCwgb3IgLTEgaWYgbm9uZSB3YXMgZm91bmQuCi0gICAgICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQXR0cmlidXRlcyNnZXRJbmRleChqYXZhLmxhbmcuU3RyaW5nKQotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIGludCBnZXRJbmRleCAoU3RyaW5nIHFOYW1lKQotICAgICAgICB7Ci0gICAgICAgICAgICBpbnQgbWF4ID0gYXR0cy5nZXRMZW5ndGgoKTsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbWF4OyBpKyspIHsKLSAgICAgICAgICAgICAgICBpZiAocUF0dHMuZ2V0TmFtZShpKS5lcXVhbHMocU5hbWUpKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiAtMTsKLSAgICAgICAgfQotCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIExvb2sgdXAgdGhlIHR5cGUgb2YgYW4gYXR0cmlidXRlIGJ5IE5hbWVzcGFjZSBuYW1lLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gdXJpIFRoZSBOYW1lc3BhY2UgVVJJCi0gICAgICAgICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGxvY2FsIG5hbWUuCi0gICAgICAgICAqIEByZXR1cm4gVGhlIGF0dHJpYnV0ZSdzIHR5cGUgYXMgYW4gaW50ZXJuYWxpemVkIHN0cmluZy4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0VHlwZSAoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSkKLSAgICAgICAgewotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBMb29rIHVwIHRoZSB0eXBlIG9mIGFuIGF0dHJpYnV0ZSBieSBxdWFsaWZpZWQgKHByZWZpeGVkKSBuYW1lLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gcU5hbWUgVGhlIHF1YWxpZmllZCBuYW1lLgotICAgICAgICAgKiBAcmV0dXJuIFRoZSBhdHRyaWJ1dGUncyB0eXBlIGFzIGFuIGludGVybmFsaXplZCBzdHJpbmcuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFR5cGUgKFN0cmluZyBxTmFtZSkKLSAgICAgICAgewotICAgICAgICAgICAgcmV0dXJuIHFBdHRzLmdldFR5cGUocU5hbWUpLmludGVybigpOwotICAgICAgICB9Ci0KLQotICAgICAgICAvKioKLSAgICAgICAgICogTG9vayB1cCB0aGUgdmFsdWUgb2YgYW4gYXR0cmlidXRlIGJ5IE5hbWVzcGFjZSBuYW1lLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gdXJpIFRoZSBOYW1lc3BhY2UgVVJJCi0gICAgICAgICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGxvY2FsIG5hbWUuCi0gICAgICAgICAqIEByZXR1cm4gVGhlIGF0dHJpYnV0ZSdzIHZhbHVlLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIFN0cmluZyBnZXRWYWx1ZSAoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSkKLSAgICAgICAgewotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBMb29rIHVwIHRoZSB2YWx1ZSBvZiBhbiBhdHRyaWJ1dGUgYnkgcXVhbGlmaWVkIChwcmVmaXhlZCkgbmFtZS4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIHFOYW1lIFRoZSBxdWFsaWZpZWQgbmFtZS4KLSAgICAgICAgICogQHJldHVybiBUaGUgYXR0cmlidXRlJ3MgdmFsdWUuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFZhbHVlIChTdHJpbmcgcU5hbWUpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHJldHVybiBxQXR0cy5nZXRWYWx1ZShxTmFtZSk7Ci0gICAgICAgIH0KLQotICAgICAgICBwcml2YXRlIEF0dHJpYnV0ZUxpc3QgcUF0dHM7Ci0gICAgfQotfQotCi0vLyBlbmQgb2YgUGFyc2VyQWRhcHRlci5qYXZhCmRpZmYgLS1naXQgYS9zcmMvb3JnL3htbC9zYXgvaGVscGVycy9QYXJzZXJGYWN0b3J5LmphdmEgYi9zcmMvb3JnL3htbC9zYXgvaGVscGVycy9QYXJzZXJGYWN0b3J5LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAzOTgzMTIuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy94bWwvc2F4L2hlbHBlcnMvUGFyc2VyRmFjdG9yeS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTQ3ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDAsIDIwMTMsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8vIFNBWCBwYXJzZXIgZmFjdG9yeS4KLS8vIGh0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmcKLS8vIE5vIHdhcnJhbnR5OyBubyBjb3B5cmlnaHQgLS0gdXNlIHRoaXMgYXMgeW91IHdpbGwuCi0vLyAkSWQ6IFBhcnNlckZhY3RvcnkuamF2YSx2IDEuMiAyMDA0LzExLzAzIDIyOjUzOjA5IGpzdXR0b3IgRXhwICQKLQotcGFja2FnZSBvcmcueG1sLnNheC5oZWxwZXJzOwotCi1pbXBvcnQgb3JnLnhtbC5zYXguUGFyc2VyOwotCi0KLS8qKgotICogSmF2YS1zcGVjaWZpYyBjbGFzcyBmb3IgZHluYW1pY2FsbHkgbG9hZGluZyBTQVggcGFyc2Vycy4KLSAqCi0gKiA8YmxvY2txdW90ZT4KLSAqIDxlbT5UaGlzIG1vZHVsZSwgYm90aCBzb3VyY2UgY29kZSBhbmQgZG9jdW1lbnRhdGlvbiwgaXMgaW4gdGhlCi0gKiBQdWJsaWMgRG9tYWluLCBhbmQgY29tZXMgd2l0aCA8c3Ryb25nPk5PIFdBUlJBTlRZPC9zdHJvbmc+LjwvZW0+Ci0gKiBTZWUgPGEgaHJlZj0naHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZyc+aHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZzwvYT4KLSAqIGZvciBmdXJ0aGVyIGluZm9ybWF0aW9uLgotICogPC9ibG9ja3F1b3RlPgotICoKLSAqIDxwPjxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gVGhpcyBjbGFzcyBpcyBkZXNpZ25lZCB0byB3b3JrIHdpdGggdGhlIG5vdy1kZXByZWNhdGVkCi0gKiBTQVgxIHtAbGluayBvcmcueG1sLnNheC5QYXJzZXIgUGFyc2VyfSBjbGFzcy4gIFNBWDIgYXBwbGljYXRpb25zIHNob3VsZCB1c2UKLSAqIHtAbGluayBvcmcueG1sLnNheC5oZWxwZXJzLlhNTFJlYWRlckZhY3RvcnkgWE1MUmVhZGVyRmFjdG9yeX0gaW5zdGVhZC48L3A+Ci0gKgotICogPHA+UGFyc2VyRmFjdG9yeSBpcyBub3QgcGFydCBvZiB0aGUgcGxhdGZvcm0taW5kZXBlbmRlbnQgZGVmaW5pdGlvbgotICogb2YgU0FYOyBpdCBpcyBhbiBhZGRpdGlvbmFsIGNvbnZlbmllbmNlIGNsYXNzIGRlc2lnbmVkCi0gKiBzcGVjaWZpY2FsbHkgZm9yIEphdmEgWE1MIGFwcGxpY2F0aW9uIHdyaXRlcnMuICBTQVggYXBwbGljYXRpb25zCi0gKiBjYW4gdXNlIHRoZSBzdGF0aWMgbWV0aG9kcyBpbiB0aGlzIGNsYXNzIHRvIGFsbG9jYXRlIGEgU0FYIHBhcnNlcgotICogZHluYW1pY2FsbHkgYXQgcnVuLXRpbWUgYmFzZWQgZWl0aGVyIG9uIHRoZSB2YWx1ZSBvZiB0aGUKLSAqIGBvcmcueG1sLnNheC5wYXJzZXInIHN5c3RlbSBwcm9wZXJ0eSBvciBvbiBhIHN0cmluZyBjb250YWluaW5nIHRoZSBjbGFzcwotICogbmFtZS48L3A+Ci0gKgotICogPHA+Tm90ZSB0aGF0IHRoZSBhcHBsaWNhdGlvbiBzdGlsbCByZXF1aXJlcyBhbiBYTUwgcGFyc2VyIHRoYXQKLSAqIGltcGxlbWVudHMgU0FYMS48L3A+Ci0gKgotICogQGRlcHJlY2F0ZWQgVGhpcyBjbGFzcyB3b3JrcyB3aXRoIHRoZSBkZXByZWNhdGVkCi0gKiAgICAgICAgICAgICB7QGxpbmsgb3JnLnhtbC5zYXguUGFyc2VyIFBhcnNlcn0KLSAqICAgICAgICAgICAgIGludGVyZmFjZS4KLSAqIEBzaW5jZSBTQVggMS4wCi0gKiBAYXV0aG9yIERhdmlkIE1lZ2dpbnNvbgotICogQHZlcnNpb24gMi4wLjEgKHNheDJyMikKLSAqLwotcHVibGljIGNsYXNzIFBhcnNlckZhY3RvcnkgewotICAgIHByaXZhdGUgc3RhdGljIFNlY3VyaXR5U3VwcG9ydCBzcyA9IG5ldyBTZWN1cml0eVN1cHBvcnQoKTsKLQotICAgIC8qKgotICAgICAqIFByaXZhdGUgbnVsbCBjb25zdHJ1Y3Rvci4KLSAgICAgKi8KLSAgICBwcml2YXRlIFBhcnNlckZhY3RvcnkgKCkKLSAgICB7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBDcmVhdGUgYSBuZXcgU0FYIHBhcnNlciB1c2luZyB0aGUgYG9yZy54bWwuc2F4LnBhcnNlcicgc3lzdGVtIHByb3BlcnR5LgotICAgICAqCi0gICAgICogPHA+VGhlIG5hbWVkIGNsYXNzIG11c3QgZXhpc3QgYW5kIG11c3QgaW1wbGVtZW50IHRoZQotICAgICAqIHtAbGluayBvcmcueG1sLnNheC5QYXJzZXIgUGFyc2VyfSBpbnRlcmZhY2UuPC9wPgotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24gVGhlcmUgaXMgbm8gdmFsdWUKLSAgICAgKiAgICAgICAgICAgIGZvciB0aGUgYG9yZy54bWwuc2F4LnBhcnNlcicgc3lzdGVtIHByb3BlcnR5LgotICAgICAqIEBleGNlcHRpb24gamF2YS5sYW5nLkNsYXNzTm90Rm91bmRFeGNlcHRpb24gVGhlIFNBWCBwYXJzZXIKLSAgICAgKiAgICAgICAgICAgIGNsYXNzIHdhcyBub3QgZm91bmQgKGNoZWNrIHlvdXIgQ0xBU1NQQVRIKS4KLSAgICAgKiBAZXhjZXB0aW9uIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gVGhlIFNBWCBwYXJzZXIgY2xhc3Mgd2FzCi0gICAgICogICAgICAgICAgICBmb3VuZCwgYnV0IHlvdSBkbyBub3QgaGF2ZSBwZXJtaXNzaW9uIHRvIGxvYWQKLSAgICAgKiAgICAgICAgICAgIGl0LgotICAgICAqIEBleGNlcHRpb24gSW5zdGFudGlhdGlvbkV4Y2VwdGlvbiBUaGUgU0FYIHBhcnNlciBjbGFzcyB3YXMKLSAgICAgKiAgICAgICAgICAgIGZvdW5kIGJ1dCBjb3VsZCBub3QgYmUgaW5zdGFudGlhdGVkLgotICAgICAqIEBleGNlcHRpb24gamF2YS5sYW5nLkNsYXNzQ2FzdEV4Y2VwdGlvbiBUaGUgU0FYIHBhcnNlciBjbGFzcwotICAgICAqICAgICAgICAgICAgd2FzIGZvdW5kIGFuZCBpbnN0YW50aWF0ZWQsIGJ1dCBkb2VzIG5vdCBpbXBsZW1lbnQKLSAgICAgKiAgICAgICAgICAgIG9yZy54bWwuc2F4LlBhcnNlci4KLSAgICAgKiBAc2VlICNtYWtlUGFyc2VyKGphdmEubGFuZy5TdHJpbmcpCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5QYXJzZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFBhcnNlciBtYWtlUGFyc2VyICgpCi0gICAgICAgIHRocm93cyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uLAotICAgICAgICBJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uLAotICAgICAgICBJbnN0YW50aWF0aW9uRXhjZXB0aW9uLAotICAgICAgICBOdWxsUG9pbnRlckV4Y2VwdGlvbiwKLSAgICAgICAgQ2xhc3NDYXN0RXhjZXB0aW9uCi0gICAgewotICAgICAgICBTdHJpbmcgY2xhc3NOYW1lID0gc3MuZ2V0U3lzdGVtUHJvcGVydHkoIm9yZy54bWwuc2F4LnBhcnNlciIpOwotICAgICAgICBpZiAoY2xhc3NOYW1lID09IG51bGwpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigiTm8gdmFsdWUgZm9yIHNheC5wYXJzZXIgcHJvcGVydHkiKTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiBtYWtlUGFyc2VyKGNsYXNzTmFtZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIENyZWF0ZSBhIG5ldyBTQVggcGFyc2VyIG9iamVjdCB1c2luZyB0aGUgY2xhc3MgbmFtZSBwcm92aWRlZC4KLSAgICAgKgotICAgICAqIDxwPlRoZSBuYW1lZCBjbGFzcyBtdXN0IGV4aXN0IGFuZCBtdXN0IGltcGxlbWVudCB0aGUKLSAgICAgKiB7QGxpbmsgb3JnLnhtbC5zYXguUGFyc2VyIFBhcnNlcn0gaW50ZXJmYWNlLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjbGFzc05hbWUgQSBzdHJpbmcgY29udGFpbmluZyB0aGUgbmFtZSBvZiB0aGUKLSAgICAgKiAgICAgICAgICAgICAgICAgIFNBWCBwYXJzZXIgY2xhc3MuCi0gICAgICogQGV4Y2VwdGlvbiBqYXZhLmxhbmcuQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBUaGUgU0FYIHBhcnNlcgotICAgICAqICAgICAgICAgICAgY2xhc3Mgd2FzIG5vdCBmb3VuZCAoY2hlY2sgeW91ciBDTEFTU1BBVEgpLgotICAgICAqIEBleGNlcHRpb24gSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBUaGUgU0FYIHBhcnNlciBjbGFzcyB3YXMKLSAgICAgKiAgICAgICAgICAgIGZvdW5kLCBidXQgeW91IGRvIG5vdCBoYXZlIHBlcm1pc3Npb24gdG8gbG9hZAotICAgICAqICAgICAgICAgICAgaXQuCi0gICAgICogQGV4Y2VwdGlvbiBJbnN0YW50aWF0aW9uRXhjZXB0aW9uIFRoZSBTQVggcGFyc2VyIGNsYXNzIHdhcwotICAgICAqICAgICAgICAgICAgZm91bmQgYnV0IGNvdWxkIG5vdCBiZSBpbnN0YW50aWF0ZWQuCi0gICAgICogQGV4Y2VwdGlvbiBqYXZhLmxhbmcuQ2xhc3NDYXN0RXhjZXB0aW9uIFRoZSBTQVggcGFyc2VyIGNsYXNzCi0gICAgICogICAgICAgICAgICB3YXMgZm91bmQgYW5kIGluc3RhbnRpYXRlZCwgYnV0IGRvZXMgbm90IGltcGxlbWVudAotICAgICAqICAgICAgICAgICAgb3JnLnhtbC5zYXguUGFyc2VyLgotICAgICAqIEBzZWUgI21ha2VQYXJzZXIoKQotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguUGFyc2VyCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBQYXJzZXIgbWFrZVBhcnNlciAoU3RyaW5nIGNsYXNzTmFtZSkKLSAgICAgICAgdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb24sCi0gICAgICAgIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24sCi0gICAgICAgIEluc3RhbnRpYXRpb25FeGNlcHRpb24sCi0gICAgICAgIENsYXNzQ2FzdEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgcmV0dXJuIChQYXJzZXIpIE5ld0luc3RhbmNlLm5ld0luc3RhbmNlICgKLSAgICAgICAgICAgICAgICBzcy5nZXRDb250ZXh0Q2xhc3NMb2FkZXIoKSwgY2xhc3NOYW1lKTsKLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcveG1sL3NheC9oZWxwZXJzL1NlY3VyaXR5U3VwcG9ydC5qYXZhIGIvc3JjL29yZy94bWwvc2F4L2hlbHBlcnMvU2VjdXJpdHlTdXBwb3J0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGY3YzczYmYuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy94bWwvc2F4L2hlbHBlcnMvU2VjdXJpdHlTdXBwb3J0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMDggKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwNCwgMjAxMywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLSAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KLSAqCi0gKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAotICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwotICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAotICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCi0gKgotICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCi0gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKLSAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQotICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKLSAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCi0gKgotICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgotICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAotICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgotICoKLSAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCi0gKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55Ci0gKiBxdWVzdGlvbnMuCi0gKi8KLQotcGFja2FnZSBvcmcueG1sLnNheC5oZWxwZXJzOwotCi1pbXBvcnQgamF2YS5pby4qOwotaW1wb3J0IGphdmEuc2VjdXJpdHkuKjsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGlzIGR1cGxpY2F0ZWQgZm9yIGVhY2ggSkFYUCBzdWJwYWNrYWdlIHNvIGtlZXAgaXQgaW4gc3luYy4KLSAqIEl0IGlzIHBhY2thZ2UgcHJpdmF0ZSBhbmQgdGhlcmVmb3JlIGlzIG5vdCBleHBvc2VkIGFzIHBhcnQgb2YgdGhlIEpBWFAKLSAqIEFQSS4KLSAqCi0gKiBTZWN1cml0eSByZWxhdGVkIG1ldGhvZHMgdGhhdCBvbmx5IHdvcmsgb24gSjJTRSAxLjIgYW5kIG5ld2VyLgotICovCi1jbGFzcyBTZWN1cml0eVN1cHBvcnQgIHsKLQotCi0gICAgQ2xhc3NMb2FkZXIgZ2V0Q29udGV4dENsYXNzTG9hZGVyKCkgdGhyb3dzIFNlY3VyaXR5RXhjZXB0aW9uewotICAgICAgICByZXR1cm4gKENsYXNzTG9hZGVyKQotICAgICAgICAgICAgICAgIEFjY2Vzc0NvbnRyb2xsZXIuZG9Qcml2aWxlZ2VkKG5ldyBQcml2aWxlZ2VkQWN0aW9uKCkgewotICAgICAgICAgICAgcHVibGljIE9iamVjdCBydW4oKSB7Ci0gICAgICAgICAgICAgICAgQ2xhc3NMb2FkZXIgY2wgPSBudWxsOwotICAgICAgICAgICAgICAgIC8vdHJ5IHsKLSAgICAgICAgICAgICAgICBjbCA9IFRocmVhZC5jdXJyZW50VGhyZWFkKCkuZ2V0Q29udGV4dENsYXNzTG9hZGVyKCk7Ci0gICAgICAgICAgICAgICAgLy99IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBleCkgeyB9Ci0KLSAgICAgICAgICAgICAgICBpZiAoY2wgPT0gbnVsbCkKLSAgICAgICAgICAgICAgICAgICAgY2wgPSBDbGFzc0xvYWRlci5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpOwotCi0gICAgICAgICAgICAgICAgcmV0dXJuIGNsOwotICAgICAgICAgICAgfQotICAgICAgICB9KTsKLSAgICB9Ci0KLSAgICBTdHJpbmcgZ2V0U3lzdGVtUHJvcGVydHkoZmluYWwgU3RyaW5nIHByb3BOYW1lKSB7Ci0gICAgICAgIHJldHVybiAoU3RyaW5nKQotICAgICAgICAgICAgQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQobmV3IFByaXZpbGVnZWRBY3Rpb24oKSB7Ci0gICAgICAgICAgICAgICAgcHVibGljIE9iamVjdCBydW4oKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBTeXN0ZW0uZ2V0UHJvcGVydHkocHJvcE5hbWUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0pOwotICAgIH0KLQotICAgIEZpbGVJbnB1dFN0cmVhbSBnZXRGaWxlSW5wdXRTdHJlYW0oZmluYWwgRmlsZSBmaWxlKQotICAgICAgICB0aHJvd3MgRmlsZU5vdEZvdW5kRXhjZXB0aW9uCi0gICAgewotICAgICAgICB0cnkgewotICAgICAgICAgICAgcmV0dXJuIChGaWxlSW5wdXRTdHJlYW0pCi0gICAgICAgICAgICAgICAgQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQobmV3IFByaXZpbGVnZWRFeGNlcHRpb25BY3Rpb24oKSB7Ci0gICAgICAgICAgICAgICAgICAgIHB1YmxpYyBPYmplY3QgcnVuKCkgdGhyb3dzIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEZpbGVJbnB1dFN0cmVhbShmaWxlKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0pOwotICAgICAgICB9IGNhdGNoIChQcml2aWxlZ2VkQWN0aW9uRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIHRocm93IChGaWxlTm90Rm91bmRFeGNlcHRpb24pZS5nZXRFeGNlcHRpb24oKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIElucHV0U3RyZWFtIGdldFJlc291cmNlQXNTdHJlYW0oZmluYWwgQ2xhc3NMb2FkZXIgY2wsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIG5hbWUpCi0gICAgewotICAgICAgICByZXR1cm4gKElucHV0U3RyZWFtKQotICAgICAgICAgICAgQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQobmV3IFByaXZpbGVnZWRBY3Rpb24oKSB7Ci0gICAgICAgICAgICAgICAgcHVibGljIE9iamVjdCBydW4oKSB7Ci0gICAgICAgICAgICAgICAgICAgIElucHV0U3RyZWFtIHJpczsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGNsID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJpcyA9IE9iamVjdC5jbGFzcy5nZXRSZXNvdXJjZUFzU3RyZWFtKG5hbWUpOwotICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICAgICAgcmlzID0gY2wuZ2V0UmVzb3VyY2VBc1N0cmVhbShuYW1lKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmlzOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0pOwotICAgIH0KLQotICAgIGJvb2xlYW4gZG9lc0ZpbGVFeGlzdChmaW5hbCBGaWxlIGYpIHsKLSAgICByZXR1cm4gKChCb29sZWFuKQotICAgICAgICAgICAgQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQobmV3IFByaXZpbGVnZWRBY3Rpb24oKSB7Ci0gICAgICAgICAgICAgICAgcHVibGljIE9iamVjdCBydW4oKSB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQm9vbGVhbihmLmV4aXN0cygpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9KSkuYm9vbGVhblZhbHVlKCk7Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL3htbC9zYXgvaGVscGVycy9YTUxGaWx0ZXJJbXBsLmphdmEgYi9zcmMvb3JnL3htbC9zYXgvaGVscGVycy9YTUxGaWx0ZXJJbXBsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDFlNTU2NzIuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy94bWwvc2F4L2hlbHBlcnMvWE1MRmlsdGVySW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNzM3ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDAsIDIwMDUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8vIFhNTEZpbHRlckltcGwuamF2YSAtIGJhc2UgU0FYMiBmaWx0ZXIgaW1wbGVtZW50YXRpb24uCi0vLyBodHRwOi8vd3d3LnNheHByb2plY3Qub3JnCi0vLyBXcml0dGVuIGJ5IERhdmlkIE1lZ2dpbnNvbgotLy8gTk8gV0FSUkFOVFkhICBUaGlzIGNsYXNzIGlzIGluIHRoZSBQdWJsaWMgRG9tYWluLgotLy8gJElkOiBYTUxGaWx0ZXJJbXBsLmphdmEsdiAxLjMgMjAwNC8xMS8wMyAyMjo1MzowOSBqc3V0dG9yIEV4cCAkCi0KLXBhY2thZ2Ugb3JnLnhtbC5zYXguaGVscGVyczsKLQotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci0KLWltcG9ydCBvcmcueG1sLnNheC5YTUxSZWFkZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguWE1MRmlsdGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LklucHV0U291cmNlOwotaW1wb3J0IG9yZy54bWwuc2F4LkxvY2F0b3I7Ci1pbXBvcnQgb3JnLnhtbC5zYXguQXR0cmlidXRlczsKLWltcG9ydCBvcmcueG1sLnNheC5FbnRpdHlSZXNvbHZlcjsKLWltcG9ydCBvcmcueG1sLnNheC5EVERIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LkVycm9ySGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb247Ci0KLQotLyoqCi0gKiBCYXNlIGNsYXNzIGZvciBkZXJpdmluZyBhbiBYTUwgZmlsdGVyLgotICoKLSAqIDxibG9ja3F1b3RlPgotICogPGVtPlRoaXMgbW9kdWxlLCBib3RoIHNvdXJjZSBjb2RlIGFuZCBkb2N1bWVudGF0aW9uLCBpcyBpbiB0aGUKLSAqIFB1YmxpYyBEb21haW4sIGFuZCBjb21lcyB3aXRoIDxzdHJvbmc+Tk8gV0FSUkFOVFk8L3N0cm9uZz4uPC9lbT4KLSAqIFNlZSA8YSBocmVmPSdodHRwOi8vd3d3LnNheHByb2plY3Qub3JnJz5odHRwOi8vd3d3LnNheHByb2plY3Qub3JnPC9hPgotICogZm9yIGZ1cnRoZXIgaW5mb3JtYXRpb24uCi0gKiA8L2Jsb2NrcXVvdGU+Ci0gKgotICogPHA+VGhpcyBjbGFzcyBpcyBkZXNpZ25lZCB0byBzaXQgYmV0d2VlbiBhbiB7QGxpbmsgb3JnLnhtbC5zYXguWE1MUmVhZGVyCi0gKiBYTUxSZWFkZXJ9IGFuZCB0aGUgY2xpZW50IGFwcGxpY2F0aW9uJ3MgZXZlbnQgaGFuZGxlcnMuICBCeSBkZWZhdWx0LCBpdAotICogZG9lcyBub3RoaW5nIGJ1dCBwYXNzIHJlcXVlc3RzIHVwIHRvIHRoZSByZWFkZXIgYW5kIGV2ZW50cwotICogb24gdG8gdGhlIGhhbmRsZXJzIHVubW9kaWZpZWQsIGJ1dCBzdWJjbGFzc2VzIGNhbiBvdmVycmlkZQotICogc3BlY2lmaWMgbWV0aG9kcyB0byBtb2RpZnkgdGhlIGV2ZW50IHN0cmVhbSBvciB0aGUgY29uZmlndXJhdGlvbgotICogcmVxdWVzdHMgYXMgdGhleSBwYXNzIHRocm91Z2guPC9wPgotICoKLSAqIEBzaW5jZSBTQVggMi4wCi0gKiBAYXV0aG9yIERhdmlkIE1lZ2dpbnNvbgotICogQHNlZSBvcmcueG1sLnNheC5YTUxGaWx0ZXIKLSAqIEBzZWUgb3JnLnhtbC5zYXguWE1MUmVhZGVyCi0gKiBAc2VlIG9yZy54bWwuc2F4LkVudGl0eVJlc29sdmVyCi0gKiBAc2VlIG9yZy54bWwuc2F4LkRUREhhbmRsZXIKLSAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIKLSAqIEBzZWUgb3JnLnhtbC5zYXguRXJyb3JIYW5kbGVyCi0gKi8KLXB1YmxpYyBjbGFzcyBYTUxGaWx0ZXJJbXBsCi0gICAgaW1wbGVtZW50cyBYTUxGaWx0ZXIsIEVudGl0eVJlc29sdmVyLCBEVERIYW5kbGVyLCBDb250ZW50SGFuZGxlciwgRXJyb3JIYW5kbGVyCi17Ci0KLQotICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0gICAgLy8gQ29uc3RydWN0b3JzLgotICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0KLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdCBhbiBlbXB0eSBYTUwgZmlsdGVyLCB3aXRoIG5vIHBhcmVudC4KLSAgICAgKgotICAgICAqIDxwPlRoaXMgZmlsdGVyIHdpbGwgaGF2ZSBubyBwYXJlbnQ6IHlvdSBtdXN0IGFzc2lnbiBhIHBhcmVudAotICAgICAqIGJlZm9yZSB5b3Ugc3RhcnQgYSBwYXJzZSBvciBkbyBhbnkgY29uZmlndXJhdGlvbiB3aXRoCi0gICAgICogc2V0RmVhdHVyZSBvciBzZXRQcm9wZXJ0eSwgdW5sZXNzIHlvdSB1c2UgdGhpcyBhcyBhIHB1cmUgZXZlbnQKLSAgICAgKiBjb25zdW1lciByYXRoZXIgdGhhbiBhcyBhbiB7QGxpbmsgWE1MUmVhZGVyfS48L3A+Ci0gICAgICoKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LlhNTFJlYWRlciNzZXRGZWF0dXJlCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5YTUxSZWFkZXIjc2V0UHJvcGVydHkKLSAgICAgKiBAc2VlICNzZXRQYXJlbnQKLSAgICAgKi8KLSAgICBwdWJsaWMgWE1MRmlsdGVySW1wbCAoKQotICAgIHsKLSAgICAgICAgc3VwZXIoKTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdCBhbiBYTUwgZmlsdGVyIHdpdGggdGhlIHNwZWNpZmllZCBwYXJlbnQuCi0gICAgICoKLSAgICAgKiBAc2VlICNzZXRQYXJlbnQKLSAgICAgKiBAc2VlICNnZXRQYXJlbnQKLSAgICAgKi8KLSAgICBwdWJsaWMgWE1MRmlsdGVySW1wbCAoWE1MUmVhZGVyIHBhcmVudCkKLSAgICB7Ci0gICAgICAgIHN1cGVyKCk7Ci0gICAgICAgIHNldFBhcmVudChwYXJlbnQpOwotICAgIH0KLQotCi0KLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotICAgIC8vIEltcGxlbWVudGF0aW9uIG9mIG9yZy54bWwuc2F4LlhNTEZpbHRlci4KLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotCi0KLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIHBhcmVudCByZWFkZXIuCi0gICAgICoKLSAgICAgKiA8cD5UaGlzIGlzIHRoZSB7QGxpbmsgb3JnLnhtbC5zYXguWE1MUmVhZGVyIFhNTFJlYWRlcn0gZnJvbSB3aGljaAotICAgICAqIHRoaXMgZmlsdGVyIHdpbGwgb2J0YWluIGl0cyBldmVudHMgYW5kIHRvIHdoaWNoIGl0IHdpbGwgcGFzcyBpdHMKLSAgICAgKiBjb25maWd1cmF0aW9uIHJlcXVlc3RzLiAgVGhlIHBhcmVudCBtYXkgaXRzZWxmIGJlIGFub3RoZXIgZmlsdGVyLjwvcD4KLSAgICAgKgotICAgICAqIDxwPklmIHRoZXJlIGlzIG5vIHBhcmVudCByZWFkZXIgc2V0LCBhbnkgYXR0ZW1wdCB0byBwYXJzZQotICAgICAqIG9yIHRvIHNldCBvciBnZXQgYSBmZWF0dXJlIG9yIHByb3BlcnR5IHdpbGwgZmFpbC48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gcGFyZW50IFRoZSBwYXJlbnQgWE1MIHJlYWRlci4KLSAgICAgKiBAc2VlICNnZXRQYXJlbnQKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRQYXJlbnQgKFhNTFJlYWRlciBwYXJlbnQpCi0gICAgewotICAgICAgICB0aGlzLnBhcmVudCA9IHBhcmVudDsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgcGFyZW50IHJlYWRlci4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIHBhcmVudCBYTUwgcmVhZGVyLCBvciBudWxsIGlmIG5vbmUgaXMgc2V0LgotICAgICAqIEBzZWUgI3NldFBhcmVudAotICAgICAqLwotICAgIHB1YmxpYyBYTUxSZWFkZXIgZ2V0UGFyZW50ICgpCi0gICAgewotICAgICAgICByZXR1cm4gcGFyZW50OwotICAgIH0KLQotCi0KLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotICAgIC8vIEltcGxlbWVudGF0aW9uIG9mIG9yZy54bWwuc2F4LlhNTFJlYWRlci4KLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotCi0KLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIHZhbHVlIG9mIGEgZmVhdHVyZS4KLSAgICAgKgotICAgICAqIDxwPlRoaXMgd2lsbCBhbHdheXMgZmFpbCBpZiB0aGUgcGFyZW50IGlzIG51bGwuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgVGhlIGZlYXR1cmUgbmFtZS4KLSAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcXVlc3RlZCBmZWF0dXJlIHZhbHVlLgotICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiBJZiB0aGUgZmVhdHVyZQotICAgICAqICAgICAgICAgICAgdmFsdWUgY2FuJ3QgYmUgYXNzaWduZWQgb3IgcmV0cmlldmVkIGZyb20gdGhlIHBhcmVudC4KLSAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBXaGVuIHRoZQotICAgICAqICAgICAgICAgICAgcGFyZW50IHJlY29nbml6ZXMgdGhlIGZlYXR1cmUgbmFtZSBidXQKLSAgICAgKiAgICAgICAgICAgIGNhbm5vdCBzZXQgdGhlIHJlcXVlc3RlZCB2YWx1ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRGZWF0dXJlIChTdHJpbmcgbmFtZSwgYm9vbGVhbiB2YWx1ZSkKLSAgICAgICAgdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaWYgKHBhcmVudCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBwYXJlbnQuc2V0RmVhdHVyZShuYW1lLCB2YWx1ZSk7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbigiRmVhdHVyZTogIiArIG5hbWUpOwotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBMb29rIHVwIHRoZSB2YWx1ZSBvZiBhIGZlYXR1cmUuCi0gICAgICoKLSAgICAgKiA8cD5UaGlzIHdpbGwgYWx3YXlzIGZhaWwgaWYgdGhlIHBhcmVudCBpcyBudWxsLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBmZWF0dXJlIG5hbWUuCi0gICAgICogQHJldHVybiBUaGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgZmVhdHVyZS4KLSAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24gSWYgdGhlIGZlYXR1cmUKLSAgICAgKiAgICAgICAgICAgIHZhbHVlIGNhbid0IGJlIGFzc2lnbmVkIG9yIHJldHJpZXZlZCBmcm9tIHRoZSBwYXJlbnQuCi0gICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gV2hlbiB0aGUKLSAgICAgKiAgICAgICAgICAgIHBhcmVudCByZWNvZ25pemVzIHRoZSBmZWF0dXJlIG5hbWUgYnV0Ci0gICAgICogICAgICAgICAgICBjYW5ub3QgZGV0ZXJtaW5lIGl0cyB2YWx1ZSBhdCB0aGlzIHRpbWUuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0RmVhdHVyZSAoU3RyaW5nIG5hbWUpCi0gICAgICAgIHRocm93cyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uLCBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGlmIChwYXJlbnQgIT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIHBhcmVudC5nZXRGZWF0dXJlKG5hbWUpOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgdGhyb3cgbmV3IFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24oIkZlYXR1cmU6ICIgKyBuYW1lKTsKLSAgICAgICAgfQotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSB2YWx1ZSBvZiBhIHByb3BlcnR5LgotICAgICAqCi0gICAgICogPHA+VGhpcyB3aWxsIGFsd2F5cyBmYWlsIGlmIHRoZSBwYXJlbnQgaXMgbnVsbC48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgcHJvcGVydHkgbmFtZS4KLSAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcXVlc3RlZCBwcm9wZXJ0eSB2YWx1ZS4KLSAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24gSWYgdGhlIHByb3BlcnR5Ci0gICAgICogICAgICAgICAgICB2YWx1ZSBjYW4ndCBiZSBhc3NpZ25lZCBvciByZXRyaWV2ZWQgZnJvbSB0aGUgcGFyZW50LgotICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIFdoZW4gdGhlCi0gICAgICogICAgICAgICAgICBwYXJlbnQgcmVjb2duaXplcyB0aGUgcHJvcGVydHkgbmFtZSBidXQKLSAgICAgKiAgICAgICAgICAgIGNhbm5vdCBzZXQgdGhlIHJlcXVlc3RlZCB2YWx1ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRQcm9wZXJ0eSAoU3RyaW5nIG5hbWUsIE9iamVjdCB2YWx1ZSkKLSAgICAgICAgdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaWYgKHBhcmVudCAhPSBudWxsKSB7Ci0gICAgICAgICAgICBwYXJlbnQuc2V0UHJvcGVydHkobmFtZSwgdmFsdWUpOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgdGhyb3cgbmV3IFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24oIlByb3BlcnR5OiAiICsgbmFtZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIExvb2sgdXAgdGhlIHZhbHVlIG9mIGEgcHJvcGVydHkuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgcHJvcGVydHkgbmFtZS4KLSAgICAgKiBAcmV0dXJuIFRoZSBjdXJyZW50IHZhbHVlIG9mIHRoZSBwcm9wZXJ0eS4KLSAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24gSWYgdGhlIHByb3BlcnR5Ci0gICAgICogICAgICAgICAgICB2YWx1ZSBjYW4ndCBiZSBhc3NpZ25lZCBvciByZXRyaWV2ZWQgZnJvbSB0aGUgcGFyZW50LgotICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIFdoZW4gdGhlCi0gICAgICogICAgICAgICAgICBwYXJlbnQgcmVjb2duaXplcyB0aGUgcHJvcGVydHkgbmFtZSBidXQKLSAgICAgKiAgICAgICAgICAgIGNhbm5vdCBkZXRlcm1pbmUgaXRzIHZhbHVlIGF0IHRoaXMgdGltZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0IGdldFByb3BlcnR5IChTdHJpbmcgbmFtZSkKLSAgICAgICAgdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaWYgKHBhcmVudCAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gcGFyZW50LmdldFByb3BlcnR5KG5hbWUpOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgdGhyb3cgbmV3IFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24oIlByb3BlcnR5OiAiICsgbmFtZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFNldCB0aGUgZW50aXR5IHJlc29sdmVyLgotICAgICAqCi0gICAgICogQHBhcmFtIHJlc29sdmVyIFRoZSBuZXcgZW50aXR5IHJlc29sdmVyLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEVudGl0eVJlc29sdmVyIChFbnRpdHlSZXNvbHZlciByZXNvbHZlcikKLSAgICB7Ci0gICAgICAgIGVudGl0eVJlc29sdmVyID0gcmVzb2x2ZXI7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIGN1cnJlbnQgZW50aXR5IHJlc29sdmVyLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgY3VycmVudCBlbnRpdHkgcmVzb2x2ZXIsIG9yIG51bGwgaWYgbm9uZSB3YXMgc2V0LgotICAgICAqLwotICAgIHB1YmxpYyBFbnRpdHlSZXNvbHZlciBnZXRFbnRpdHlSZXNvbHZlciAoKQotICAgIHsKLSAgICAgICAgcmV0dXJuIGVudGl0eVJlc29sdmVyOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSBEVEQgZXZlbnQgaGFuZGxlci4KLSAgICAgKgotICAgICAqIEBwYXJhbSBoYW5kbGVyIHRoZSBuZXcgRFREIGhhbmRsZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXREVERIYW5kbGVyIChEVERIYW5kbGVyIGhhbmRsZXIpCi0gICAgewotICAgICAgICBkdGRIYW5kbGVyID0gaGFuZGxlcjsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgY3VycmVudCBEVEQgZXZlbnQgaGFuZGxlci4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIGN1cnJlbnQgRFREIGhhbmRsZXIsIG9yIG51bGwgaWYgbm9uZSB3YXMgc2V0LgotICAgICAqLwotICAgIHB1YmxpYyBEVERIYW5kbGVyIGdldERUREhhbmRsZXIgKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBkdGRIYW5kbGVyOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSBjb250ZW50IGV2ZW50IGhhbmRsZXIuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaGFuZGxlciB0aGUgbmV3IGNvbnRlbnQgaGFuZGxlcgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldENvbnRlbnRIYW5kbGVyIChDb250ZW50SGFuZGxlciBoYW5kbGVyKQotICAgIHsKLSAgICAgICAgY29udGVudEhhbmRsZXIgPSBoYW5kbGVyOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBjb250ZW50IGV2ZW50IGhhbmRsZXIuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBjdXJyZW50IGNvbnRlbnQgaGFuZGxlciwgb3IgbnVsbCBpZiBub25lIHdhcyBzZXQuCi0gICAgICovCi0gICAgcHVibGljIENvbnRlbnRIYW5kbGVyIGdldENvbnRlbnRIYW5kbGVyICgpCi0gICAgewotICAgICAgICByZXR1cm4gY29udGVudEhhbmRsZXI7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIGVycm9yIGV2ZW50IGhhbmRsZXIuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaGFuZGxlciB0aGUgbmV3IGVycm9yIGhhbmRsZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRFcnJvckhhbmRsZXIgKEVycm9ySGFuZGxlciBoYW5kbGVyKQotICAgIHsKLSAgICAgICAgZXJyb3JIYW5kbGVyID0gaGFuZGxlcjsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgY3VycmVudCBlcnJvciBldmVudCBoYW5kbGVyLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgY3VycmVudCBlcnJvciBoYW5kbGVyLCBvciBudWxsIGlmIG5vbmUgd2FzIHNldC4KLSAgICAgKi8KLSAgICBwdWJsaWMgRXJyb3JIYW5kbGVyIGdldEVycm9ySGFuZGxlciAoKQotICAgIHsKLSAgICAgICAgcmV0dXJuIGVycm9ySGFuZGxlcjsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFBhcnNlIGEgZG9jdW1lbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaW5wdXQgVGhlIGlucHV0IHNvdXJjZSBmb3IgdGhlIGRvY3VtZW50IGVudGl0eS4KLSAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgICAqIEBleGNlcHRpb24gamF2YS5pby5JT0V4Y2VwdGlvbiBBbiBJTyBleGNlcHRpb24gZnJvbSB0aGUgcGFyc2VyLAotICAgICAqICAgICAgICAgICAgcG9zc2libHkgZnJvbSBhIGJ5dGUgc3RyZWFtIG9yIGNoYXJhY3RlciBzdHJlYW0KLSAgICAgKiAgICAgICAgICAgIHN1cHBsaWVkIGJ5IHRoZSBhcHBsaWNhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBwYXJzZSAoSW5wdXRTb3VyY2UgaW5wdXQpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24sIElPRXhjZXB0aW9uCi0gICAgewotICAgICAgICBzZXR1cFBhcnNlKCk7Ci0gICAgICAgIHBhcmVudC5wYXJzZShpbnB1dCk7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBQYXJzZSBhIGRvY3VtZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIHN5c3RlbUlkIFRoZSBzeXN0ZW0gaWRlbnRpZmllciBhcyBhIGZ1bGx5LXF1YWxpZmllZCBVUkkuCi0gICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICAgKiBAZXhjZXB0aW9uIGphdmEuaW8uSU9FeGNlcHRpb24gQW4gSU8gZXhjZXB0aW9uIGZyb20gdGhlIHBhcnNlciwKLSAgICAgKiAgICAgICAgICAgIHBvc3NpYmx5IGZyb20gYSBieXRlIHN0cmVhbSBvciBjaGFyYWN0ZXIgc3RyZWFtCi0gICAgICogICAgICAgICAgICBzdXBwbGllZCBieSB0aGUgYXBwbGljYXRpb24uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcGFyc2UgKFN0cmluZyBzeXN0ZW1JZCkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIHBhcnNlKG5ldyBJbnB1dFNvdXJjZShzeXN0ZW1JZCkpOwotICAgIH0KLQotCi0KLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotICAgIC8vIEltcGxlbWVudGF0aW9uIG9mIG9yZy54bWwuc2F4LkVudGl0eVJlc29sdmVyLgotICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0KLQotICAgIC8qKgotICAgICAqIEZpbHRlciBhbiBleHRlcm5hbCBlbnRpdHkgcmVzb2x1dGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBwdWJsaWNJZCBUaGUgZW50aXR5J3MgcHVibGljIGlkZW50aWZpZXIsIG9yIG51bGwuCi0gICAgICogQHBhcmFtIHN5c3RlbUlkIFRoZSBlbnRpdHkncyBzeXN0ZW0gaWRlbnRpZmllci4KLSAgICAgKiBAcmV0dXJuIEEgbmV3IElucHV0U291cmNlIG9yIG51bGwgZm9yIHRoZSBkZWZhdWx0LgotICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIFRoZSBjbGllbnQgbWF5IHRocm93Ci0gICAgICogICAgICAgICAgICBhbiBleGNlcHRpb24gZHVyaW5nIHByb2Nlc3NpbmcuCi0gICAgICogQGV4Y2VwdGlvbiBqYXZhLmlvLklPRXhjZXB0aW9uIFRoZSBjbGllbnQgbWF5IHRocm93IGFuCi0gICAgICogICAgICAgICAgICBJL08tcmVsYXRlZCBleGNlcHRpb24gd2hpbGUgb2J0YWluaW5nIHRoZQotICAgICAqICAgICAgICAgICAgbmV3IElucHV0U291cmNlLgotICAgICAqLwotICAgIHB1YmxpYyBJbnB1dFNvdXJjZSByZXNvbHZlRW50aXR5IChTdHJpbmcgcHVibGljSWQsIFN0cmluZyBzeXN0ZW1JZCkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGlmIChlbnRpdHlSZXNvbHZlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gZW50aXR5UmVzb2x2ZXIucmVzb2x2ZUVudGl0eShwdWJsaWNJZCwgc3lzdGVtSWQpOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotCi0gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLSAgICAvLyBJbXBsZW1lbnRhdGlvbiBvZiBvcmcueG1sLnNheC5EVERIYW5kbGVyLgotICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0KLQotICAgIC8qKgotICAgICAqIEZpbHRlciBhIG5vdGF0aW9uIGRlY2xhcmF0aW9uIGV2ZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgVGhlIG5vdGF0aW9uIG5hbWUuCi0gICAgICogQHBhcmFtIHB1YmxpY0lkIFRoZSBub3RhdGlvbidzIHB1YmxpYyBpZGVudGlmaWVyLCBvciBudWxsLgotICAgICAqIEBwYXJhbSBzeXN0ZW1JZCBUaGUgbm90YXRpb24ncyBzeXN0ZW0gaWRlbnRpZmllciwgb3IgbnVsbC4KLSAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBUaGUgY2xpZW50IG1heSB0aHJvdwotICAgICAqICAgICAgICAgICAgYW4gZXhjZXB0aW9uIGR1cmluZyBwcm9jZXNzaW5nLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIG5vdGF0aW9uRGVjbCAoU3RyaW5nIG5hbWUsIFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAoZHRkSGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBkdGRIYW5kbGVyLm5vdGF0aW9uRGVjbChuYW1lLCBwdWJsaWNJZCwgc3lzdGVtSWQpOwotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBGaWx0ZXIgYW4gdW5wYXJzZWQgZW50aXR5IGRlY2xhcmF0aW9uIGV2ZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgVGhlIGVudGl0eSBuYW1lLgotICAgICAqIEBwYXJhbSBwdWJsaWNJZCBUaGUgZW50aXR5J3MgcHVibGljIGlkZW50aWZpZXIsIG9yIG51bGwuCi0gICAgICogQHBhcmFtIHN5c3RlbUlkIFRoZSBlbnRpdHkncyBzeXN0ZW0gaWRlbnRpZmllciwgb3IgbnVsbC4KLSAgICAgKiBAcGFyYW0gbm90YXRpb25OYW1lIFRoZSBuYW1lIG9mIHRoZSBhc3NvY2lhdGVkIG5vdGF0aW9uLgotICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIFRoZSBjbGllbnQgbWF5IHRocm93Ci0gICAgICogICAgICAgICAgICBhbiBleGNlcHRpb24gZHVyaW5nIHByb2Nlc3NpbmcuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdW5wYXJzZWRFbnRpdHlEZWNsIChTdHJpbmcgbmFtZSwgU3RyaW5nIHB1YmxpY0lkLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHN5c3RlbUlkLCBTdHJpbmcgbm90YXRpb25OYW1lKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAoZHRkSGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBkdGRIYW5kbGVyLnVucGFyc2VkRW50aXR5RGVjbChuYW1lLCBwdWJsaWNJZCwgc3lzdGVtSWQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3RhdGlvbk5hbWUpOwotICAgICAgICB9Ci0gICAgfQotCi0KLQotICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0gICAgLy8gSW1wbGVtZW50YXRpb24gb2Ygb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIuCi0gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLQotCi0gICAgLyoqCi0gICAgICogRmlsdGVyIGEgbmV3IGRvY3VtZW50IGxvY2F0b3IgZXZlbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbG9jYXRvciBUaGUgZG9jdW1lbnQgbG9jYXRvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXREb2N1bWVudExvY2F0b3IgKExvY2F0b3IgbG9jYXRvcikKLSAgICB7Ci0gICAgICAgIHRoaXMubG9jYXRvciA9IGxvY2F0b3I7Ci0gICAgICAgIGlmIChjb250ZW50SGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBjb250ZW50SGFuZGxlci5zZXREb2N1bWVudExvY2F0b3IobG9jYXRvcik7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIEZpbHRlciBhIHN0YXJ0IGRvY3VtZW50IGV2ZW50LgotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gVGhlIGNsaWVudCBtYXkgdGhyb3cKLSAgICAgKiAgICAgICAgICAgIGFuIGV4Y2VwdGlvbiBkdXJpbmcgcHJvY2Vzc2luZy4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydERvY3VtZW50ICgpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGlmIChjb250ZW50SGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBjb250ZW50SGFuZGxlci5zdGFydERvY3VtZW50KCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIEZpbHRlciBhbiBlbmQgZG9jdW1lbnQgZXZlbnQuCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBUaGUgY2xpZW50IG1heSB0aHJvdwotICAgICAqICAgICAgICAgICAgYW4gZXhjZXB0aW9uIGR1cmluZyBwcm9jZXNzaW5nLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZERvY3VtZW50ICgpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGlmIChjb250ZW50SGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBjb250ZW50SGFuZGxlci5lbmREb2N1bWVudCgpOwotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBGaWx0ZXIgYSBzdGFydCBOYW1lc3BhY2UgcHJlZml4IG1hcHBpbmcgZXZlbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcHJlZml4IFRoZSBOYW1lc3BhY2UgcHJlZml4LgotICAgICAqIEBwYXJhbSB1cmkgVGhlIE5hbWVzcGFjZSBVUkkuCi0gICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gVGhlIGNsaWVudCBtYXkgdGhyb3cKLSAgICAgKiAgICAgICAgICAgIGFuIGV4Y2VwdGlvbiBkdXJpbmcgcHJvY2Vzc2luZy4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydFByZWZpeE1hcHBpbmcgKFN0cmluZyBwcmVmaXgsIFN0cmluZyB1cmkpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGlmIChjb250ZW50SGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBjb250ZW50SGFuZGxlci5zdGFydFByZWZpeE1hcHBpbmcocHJlZml4LCB1cmkpOwotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBGaWx0ZXIgYW4gZW5kIE5hbWVzcGFjZSBwcmVmaXggbWFwcGluZyBldmVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBwcmVmaXggVGhlIE5hbWVzcGFjZSBwcmVmaXguCi0gICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gVGhlIGNsaWVudCBtYXkgdGhyb3cKLSAgICAgKiAgICAgICAgICAgIGFuIGV4Y2VwdGlvbiBkdXJpbmcgcHJvY2Vzc2luZy4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbmRQcmVmaXhNYXBwaW5nIChTdHJpbmcgcHJlZml4KQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAoY29udGVudEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgY29udGVudEhhbmRsZXIuZW5kUHJlZml4TWFwcGluZyhwcmVmaXgpOwotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBGaWx0ZXIgYSBzdGFydCBlbGVtZW50IGV2ZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIHVyaSBUaGUgZWxlbWVudCdzIE5hbWVzcGFjZSBVUkksIG9yIHRoZSBlbXB0eSBzdHJpbmcuCi0gICAgICogQHBhcmFtIGxvY2FsTmFtZSBUaGUgZWxlbWVudCdzIGxvY2FsIG5hbWUsIG9yIHRoZSBlbXB0eSBzdHJpbmcuCi0gICAgICogQHBhcmFtIHFOYW1lIFRoZSBlbGVtZW50J3MgcXVhbGlmaWVkIChwcmVmaXhlZCkgbmFtZSwgb3IgdGhlIGVtcHR5Ci0gICAgICogICAgICAgIHN0cmluZy4KLSAgICAgKiBAcGFyYW0gYXR0cyBUaGUgZWxlbWVudCdzIGF0dHJpYnV0ZXMuCi0gICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gVGhlIGNsaWVudCBtYXkgdGhyb3cKLSAgICAgKiAgICAgICAgICAgIGFuIGV4Y2VwdGlvbiBkdXJpbmcgcHJvY2Vzc2luZy4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQgKFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUsIFN0cmluZyBxTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0dHJpYnV0ZXMgYXR0cykKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaWYgKGNvbnRlbnRIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGNvbnRlbnRIYW5kbGVyLnN0YXJ0RWxlbWVudCh1cmksIGxvY2FsTmFtZSwgcU5hbWUsIGF0dHMpOwotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBGaWx0ZXIgYW4gZW5kIGVsZW1lbnQgZXZlbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdXJpIFRoZSBlbGVtZW50J3MgTmFtZXNwYWNlIFVSSSwgb3IgdGhlIGVtcHR5IHN0cmluZy4KLSAgICAgKiBAcGFyYW0gbG9jYWxOYW1lIFRoZSBlbGVtZW50J3MgbG9jYWwgbmFtZSwgb3IgdGhlIGVtcHR5IHN0cmluZy4KLSAgICAgKiBAcGFyYW0gcU5hbWUgVGhlIGVsZW1lbnQncyBxdWFsaWZpZWQgKHByZWZpeGVkKSBuYW1lLCBvciB0aGUgZW1wdHkKLSAgICAgKiAgICAgICAgc3RyaW5nLgotICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIFRoZSBjbGllbnQgbWF5IHRocm93Ci0gICAgICogICAgICAgICAgICBhbiBleGNlcHRpb24gZHVyaW5nIHByb2Nlc3NpbmcuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kRWxlbWVudCAoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSwgU3RyaW5nIHFOYW1lKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAoY29udGVudEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgY29udGVudEhhbmRsZXIuZW5kRWxlbWVudCh1cmksIGxvY2FsTmFtZSwgcU5hbWUpOwotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBGaWx0ZXIgYSBjaGFyYWN0ZXIgZGF0YSBldmVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjaCBBbiBhcnJheSBvZiBjaGFyYWN0ZXJzLgotICAgICAqIEBwYXJhbSBzdGFydCBUaGUgc3RhcnRpbmcgcG9zaXRpb24gaW4gdGhlIGFycmF5LgotICAgICAqIEBwYXJhbSBsZW5ndGggVGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHVzZSBmcm9tIHRoZSBhcnJheS4KLSAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBUaGUgY2xpZW50IG1heSB0aHJvdwotICAgICAqICAgICAgICAgICAgYW4gZXhjZXB0aW9uIGR1cmluZyBwcm9jZXNzaW5nLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGNoYXJhY3RlcnMgKGNoYXIgY2hbXSwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAoY29udGVudEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgY29udGVudEhhbmRsZXIuY2hhcmFjdGVycyhjaCwgc3RhcnQsIGxlbmd0aCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIEZpbHRlciBhbiBpZ25vcmFibGUgd2hpdGVzcGFjZSBldmVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjaCBBbiBhcnJheSBvZiBjaGFyYWN0ZXJzLgotICAgICAqIEBwYXJhbSBzdGFydCBUaGUgc3RhcnRpbmcgcG9zaXRpb24gaW4gdGhlIGFycmF5LgotICAgICAqIEBwYXJhbSBsZW5ndGggVGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHVzZSBmcm9tIHRoZSBhcnJheS4KLSAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBUaGUgY2xpZW50IG1heSB0aHJvdwotICAgICAqICAgICAgICAgICAgYW4gZXhjZXB0aW9uIGR1cmluZyBwcm9jZXNzaW5nLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGlnbm9yYWJsZVdoaXRlc3BhY2UgKGNoYXIgY2hbXSwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAoY29udGVudEhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgY29udGVudEhhbmRsZXIuaWdub3JhYmxlV2hpdGVzcGFjZShjaCwgc3RhcnQsIGxlbmd0aCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIEZpbHRlciBhIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gZXZlbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdGFyZ2V0IFRoZSBwcm9jZXNzaW5nIGluc3RydWN0aW9uIHRhcmdldC4KLSAgICAgKiBAcGFyYW0gZGF0YSBUaGUgdGV4dCBmb2xsb3dpbmcgdGhlIHRhcmdldC4KLSAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBUaGUgY2xpZW50IG1heSB0aHJvdwotICAgICAqICAgICAgICAgICAgYW4gZXhjZXB0aW9uIGR1cmluZyBwcm9jZXNzaW5nLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHByb2Nlc3NpbmdJbnN0cnVjdGlvbiAoU3RyaW5nIHRhcmdldCwgU3RyaW5nIGRhdGEpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGlmIChjb250ZW50SGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBjb250ZW50SGFuZGxlci5wcm9jZXNzaW5nSW5zdHJ1Y3Rpb24odGFyZ2V0LCBkYXRhKTsKLSAgICAgICAgfQotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogRmlsdGVyIGEgc2tpcHBlZCBlbnRpdHkgZXZlbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgc2tpcHBlZCBlbnRpdHkuCi0gICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gVGhlIGNsaWVudCBtYXkgdGhyb3cKLSAgICAgKiAgICAgICAgICAgIGFuIGV4Y2VwdGlvbiBkdXJpbmcgcHJvY2Vzc2luZy4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBza2lwcGVkRW50aXR5IChTdHJpbmcgbmFtZSkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaWYgKGNvbnRlbnRIYW5kbGVyICE9IG51bGwpIHsKLSAgICAgICAgICAgIGNvbnRlbnRIYW5kbGVyLnNraXBwZWRFbnRpdHkobmFtZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotCi0gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLSAgICAvLyBJbXBsZW1lbnRhdGlvbiBvZiBvcmcueG1sLnNheC5FcnJvckhhbmRsZXIuCi0gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLQotCi0gICAgLyoqCi0gICAgICogRmlsdGVyIGEgd2FybmluZyBldmVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlIFRoZSB3YXJuaW5nIGFzIGFuIGV4Y2VwdGlvbi4KLSAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBUaGUgY2xpZW50IG1heSB0aHJvdwotICAgICAqICAgICAgICAgICAgYW4gZXhjZXB0aW9uIGR1cmluZyBwcm9jZXNzaW5nLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHdhcm5pbmcgKFNBWFBhcnNlRXhjZXB0aW9uIGUpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGlmIChlcnJvckhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZXJyb3JIYW5kbGVyLndhcm5pbmcoZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIEZpbHRlciBhbiBlcnJvciBldmVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlIFRoZSBlcnJvciBhcyBhbiBleGNlcHRpb24uCi0gICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gVGhlIGNsaWVudCBtYXkgdGhyb3cKLSAgICAgKiAgICAgICAgICAgIGFuIGV4Y2VwdGlvbiBkdXJpbmcgcHJvY2Vzc2luZy4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlcnJvciAoU0FYUGFyc2VFeGNlcHRpb24gZSkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaWYgKGVycm9ySGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBlcnJvckhhbmRsZXIuZXJyb3IoZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIEZpbHRlciBhIGZhdGFsIGVycm9yIGV2ZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIGUgVGhlIGVycm9yIGFzIGFuIGV4Y2VwdGlvbi4KLSAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBUaGUgY2xpZW50IG1heSB0aHJvdwotICAgICAqICAgICAgICAgICAgYW4gZXhjZXB0aW9uIGR1cmluZyBwcm9jZXNzaW5nLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGZhdGFsRXJyb3IgKFNBWFBhcnNlRXhjZXB0aW9uIGUpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGlmIChlcnJvckhhbmRsZXIgIT0gbnVsbCkgewotICAgICAgICAgICAgZXJyb3JIYW5kbGVyLmZhdGFsRXJyb3IoZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotCi0gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLSAgICAvLyBJbnRlcm5hbCBtZXRob2RzLgotICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0KLQotICAgIC8qKgotICAgICAqIFNldCB1cCBiZWZvcmUgYSBwYXJzZS4KLSAgICAgKgotICAgICAqIDxwPkJlZm9yZSBldmVyeSBwYXJzZSwgY2hlY2sgd2hldGhlciB0aGUgcGFyZW50IGlzCi0gICAgICogbm9uLW51bGwsIGFuZCByZS1yZWdpc3RlciB0aGUgZmlsdGVyIGZvciBhbGwgb2YgdGhlCi0gICAgICogZXZlbnRzLjwvcD4KLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgc2V0dXBQYXJzZSAoKQotICAgIHsKLSAgICAgICAgaWYgKHBhcmVudCA9PSBudWxsKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIk5vIHBhcmVudCBmb3IgZmlsdGVyIik7Ci0gICAgICAgIH0KLSAgICAgICAgcGFyZW50LnNldEVudGl0eVJlc29sdmVyKHRoaXMpOwotICAgICAgICBwYXJlbnQuc2V0RFRESGFuZGxlcih0aGlzKTsKLSAgICAgICAgcGFyZW50LnNldENvbnRlbnRIYW5kbGVyKHRoaXMpOwotICAgICAgICBwYXJlbnQuc2V0RXJyb3JIYW5kbGVyKHRoaXMpOwotICAgIH0KLQotCi0KLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotICAgIC8vIEludGVybmFsIHN0YXRlLgotICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0KLSAgICBwcml2YXRlIFhNTFJlYWRlciBwYXJlbnQgPSBudWxsOwotICAgIHByaXZhdGUgTG9jYXRvciBsb2NhdG9yID0gbnVsbDsKLSAgICBwcml2YXRlIEVudGl0eVJlc29sdmVyIGVudGl0eVJlc29sdmVyID0gbnVsbDsKLSAgICBwcml2YXRlIERUREhhbmRsZXIgZHRkSGFuZGxlciA9IG51bGw7Ci0gICAgcHJpdmF0ZSBDb250ZW50SGFuZGxlciBjb250ZW50SGFuZGxlciA9IG51bGw7Ci0gICAgcHJpdmF0ZSBFcnJvckhhbmRsZXIgZXJyb3JIYW5kbGVyID0gbnVsbDsKLQotfQotCi0vLyBlbmQgb2YgWE1MRmlsdGVySW1wbC5qYXZhCmRpZmYgLS1naXQgYS9zcmMvb3JnL3htbC9zYXgvaGVscGVycy9YTUxSZWFkZXJBZGFwdGVyLmphdmEgYi9zcmMvb3JnL3htbC9zYXgvaGVscGVycy9YTUxSZWFkZXJBZGFwdGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDM5NDYzM2YuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy94bWwvc2F4L2hlbHBlcnMvWE1MUmVhZGVyQWRhcHRlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTYyICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDAsIDIwMDUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8vIFhNTFJlYWRlckFkYXB0ZXIuamF2YSAtIGFkYXB0IGFuIFNBWDIgWE1MUmVhZGVyIHRvIGEgU0FYMSBQYXJzZXIKLS8vIGh0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmcKLS8vIFdyaXR0ZW4gYnkgRGF2aWQgTWVnZ2luc29uCi0vLyBOTyBXQVJSQU5UWSEgIFRoaXMgY2xhc3MgaXMgaW4gdGhlIHB1YmxpYyBkb21haW4uCi0vLyAkSWQ6IFhNTFJlYWRlckFkYXB0ZXIuamF2YSx2IDEuMyAyMDA0LzExLzAzIDIyOjUzOjA5IGpzdXR0b3IgRXhwICQKLQotcGFja2FnZSBvcmcueG1sLnNheC5oZWxwZXJzOwotCi1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwotCi1pbXBvcnQgb3JnLnhtbC5zYXguUGFyc2VyOyAgICAgIC8vIGRlcHJlY2F0ZWQKLWltcG9ydCBvcmcueG1sLnNheC5Mb2NhdG9yOwotaW1wb3J0IG9yZy54bWwuc2F4LklucHV0U291cmNlOwotaW1wb3J0IG9yZy54bWwuc2F4LkF0dHJpYnV0ZUxpc3Q7IC8vIGRlcHJlY2F0ZWQKLWltcG9ydCBvcmcueG1sLnNheC5FbnRpdHlSZXNvbHZlcjsKLWltcG9ydCBvcmcueG1sLnNheC5EVERIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LkRvY3VtZW50SGFuZGxlcjsgLy8gZGVwcmVjYXRlZAotaW1wb3J0IG9yZy54bWwuc2F4LkVycm9ySGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci0KLWltcG9ydCBvcmcueG1sLnNheC5YTUxSZWFkZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguQXR0cmlidXRlczsKLWltcG9ydCBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb247Ci0KLQotLyoqCi0gKiBBZGFwdCBhIFNBWDIgWE1MUmVhZGVyIGFzIGEgU0FYMSBQYXJzZXIuCi0gKgotICogPGJsb2NrcXVvdGU+Ci0gKiA8ZW0+VGhpcyBtb2R1bGUsIGJvdGggc291cmNlIGNvZGUgYW5kIGRvY3VtZW50YXRpb24sIGlzIGluIHRoZQotICogUHVibGljIERvbWFpbiwgYW5kIGNvbWVzIHdpdGggPHN0cm9uZz5OTyBXQVJSQU5UWTwvc3Ryb25nPi48L2VtPgotICogU2VlIDxhIGhyZWY9J2h0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmcnPmh0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmc8L2E+Ci0gKiBmb3IgZnVydGhlciBpbmZvcm1hdGlvbi4KLSAqIDwvYmxvY2txdW90ZT4KLSAqCi0gKiA8cD5UaGlzIGNsYXNzIHdyYXBzIGEgU0FYMiB7QGxpbmsgb3JnLnhtbC5zYXguWE1MUmVhZGVyIFhNTFJlYWRlcn0KLSAqIGFuZCBtYWtlcyBpdCBhY3QgYXMgYSBTQVgxIHtAbGluayBvcmcueG1sLnNheC5QYXJzZXIgUGFyc2VyfS4gIFRoZSBYTUxSZWFkZXIKLSAqIG11c3Qgc3VwcG9ydCBhIHRydWUgdmFsdWUgZm9yIHRoZQotICogaHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL25hbWVzcGFjZS1wcmVmaXhlcyBwcm9wZXJ0eSBvciBwYXJzaW5nIHdpbGwgZmFpbAotICogd2l0aCBhIHtAbGluayBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gU0FYRXhjZXB0aW9ufTsgaWYgdGhlIFhNTFJlYWRlcgotICogc3VwcG9ydHMgYSBmYWxzZSB2YWx1ZSBmb3IgdGhlIGh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy9uYW1lc3BhY2VzCi0gKiBwcm9wZXJ0eSwgdGhhdCB3aWxsIGFsc28gYmUgdXNlZCB0byBpbXByb3ZlIGVmZmljaWVuY3kuPC9wPgotICoKLSAqIEBzaW5jZSBTQVggMi4wCi0gKiBAYXV0aG9yIERhdmlkIE1lZ2dpbnNvbgotICogQHNlZSBvcmcueG1sLnNheC5QYXJzZXIKLSAqIEBzZWUgb3JnLnhtbC5zYXguWE1MUmVhZGVyCi0gKi8KLXB1YmxpYyBjbGFzcyBYTUxSZWFkZXJBZGFwdGVyIGltcGxlbWVudHMgUGFyc2VyLCBDb250ZW50SGFuZGxlcgotewotCi0KLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotICAgIC8vIENvbnN0cnVjdG9yLgotICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0KLQotICAgIC8qKgotICAgICAqIENyZWF0ZSBhIG5ldyBhZGFwdGVyLgotICAgICAqCi0gICAgICogPHA+VXNlIHRoZSAib3JnLnhtbC5zYXguZHJpdmVyIiBwcm9wZXJ0eSB0byBsb2NhdGUgdGhlIFNBWDIKLSAgICAgKiBkcml2ZXIgdG8gZW1iZWQuPC9wPgotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gSWYgdGhlIGVtYmVkZGVkIGRyaXZlcgotICAgICAqICAgICAgICAgICAgY2Fubm90IGJlIGluc3RhbnRpYXRlZCBvciBpZiB0aGUKLSAgICAgKiAgICAgICAgICAgIG9yZy54bWwuc2F4LmRyaXZlciBwcm9wZXJ0eSBpcyBub3Qgc3BlY2lmaWVkLgotICAgICAqLwotICAgIHB1YmxpYyBYTUxSZWFkZXJBZGFwdGVyICgpCi0gICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBzZXR1cChYTUxSZWFkZXJGYWN0b3J5LmNyZWF0ZVhNTFJlYWRlcigpKTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIENyZWF0ZSBhIG5ldyBhZGFwdGVyLgotICAgICAqCi0gICAgICogPHA+Q3JlYXRlIGEgbmV3IGFkYXB0ZXIsIHdyYXBwZWQgYXJvdW5kIGEgU0FYMiBYTUxSZWFkZXIuCi0gICAgICogVGhlIGFkYXB0ZXIgd2lsbCBtYWtlIHRoZSBYTUxSZWFkZXIgYWN0IGxpa2UgYSBTQVgxCi0gICAgICogUGFyc2VyLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSB4bWxSZWFkZXIgVGhlIFNBWDIgWE1MUmVhZGVyIHRvIHdyYXAuCi0gICAgICogQGV4Y2VwdGlvbiBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24gSWYgdGhlIGFyZ3VtZW50IGlzIG51bGwuCi0gICAgICovCi0gICAgcHVibGljIFhNTFJlYWRlckFkYXB0ZXIgKFhNTFJlYWRlciB4bWxSZWFkZXIpCi0gICAgewotICAgICAgICBzZXR1cCh4bWxSZWFkZXIpOwotICAgIH0KLQotCi0KLSAgICAvKioKLSAgICAgKiBJbnRlcm5hbCBzZXR1cC4KLSAgICAgKgotICAgICAqIEBwYXJhbSB4bWxSZWFkZXIgVGhlIGVtYmVkZGVkIFhNTFJlYWRlci4KLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgc2V0dXAgKFhNTFJlYWRlciB4bWxSZWFkZXIpCi0gICAgewotICAgICAgICBpZiAoeG1sUmVhZGVyID09IG51bGwpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigiWE1MUmVhZGVyIG11c3Qgbm90IGJlIG51bGwiKTsKLSAgICAgICAgfQotICAgICAgICB0aGlzLnhtbFJlYWRlciA9IHhtbFJlYWRlcjsKLSAgICAgICAgcUF0dHMgPSBuZXcgQXR0cmlidXRlc0FkYXB0ZXIoKTsKLSAgICB9Ci0KLQotCi0gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLSAgICAvLyBJbXBsZW1lbnRhdGlvbiBvZiBvcmcueG1sLnNheC5QYXJzZXIuCi0gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLQotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSBsb2NhbGUgZm9yIGVycm9yIHJlcG9ydGluZy4KLSAgICAgKgotICAgICAqIDxwPlRoaXMgaXMgbm90IHN1cHBvcnRlZCBpbiBTQVgyLCBhbmQgd2lsbCBhbHdheXMgdGhyb3cKLSAgICAgKiBhbiBleGNlcHRpb24uPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGxvY2FsZSB0aGUgbG9jYWxlIGZvciBlcnJvciByZXBvcnRpbmcuCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5QYXJzZXIjc2V0TG9jYWxlCi0gICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gVGhyb3duIHVubGVzcyBvdmVycmlkZGVuLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldExvY2FsZSAoTG9jYWxlIGxvY2FsZSkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgdGhyb3cgbmV3IFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbigic2V0TG9jYWxlIG5vdCBzdXBwb3J0ZWQiKTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFJlZ2lzdGVyIHRoZSBlbnRpdHkgcmVzb2x2ZXIuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcmVzb2x2ZXIgVGhlIG5ldyByZXNvbHZlci4KLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LlBhcnNlciNzZXRFbnRpdHlSZXNvbHZlcgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEVudGl0eVJlc29sdmVyIChFbnRpdHlSZXNvbHZlciByZXNvbHZlcikKLSAgICB7Ci0gICAgICAgIHhtbFJlYWRlci5zZXRFbnRpdHlSZXNvbHZlcihyZXNvbHZlcik7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBSZWdpc3RlciB0aGUgRFREIGV2ZW50IGhhbmRsZXIuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaGFuZGxlciBUaGUgbmV3IERURCBldmVudCBoYW5kbGVyLgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguUGFyc2VyI3NldERUREhhbmRsZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXREVERIYW5kbGVyIChEVERIYW5kbGVyIGhhbmRsZXIpCi0gICAgewotICAgICAgICB4bWxSZWFkZXIuc2V0RFRESGFuZGxlcihoYW5kbGVyKTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFJlZ2lzdGVyIHRoZSBTQVgxIGRvY3VtZW50IGV2ZW50IGhhbmRsZXIuCi0gICAgICoKLSAgICAgKiA8cD5Ob3RlIHRoYXQgdGhlIFNBWDEgZG9jdW1lbnQgaGFuZGxlciBoYXMgbm8gTmFtZXNwYWNlCi0gICAgICogc3VwcG9ydC48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gaGFuZGxlciBUaGUgbmV3IFNBWDEgZG9jdW1lbnQgZXZlbnQgaGFuZGxlci4KLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LlBhcnNlciNzZXREb2N1bWVudEhhbmRsZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXREb2N1bWVudEhhbmRsZXIgKERvY3VtZW50SGFuZGxlciBoYW5kbGVyKQotICAgIHsKLSAgICAgICAgZG9jdW1lbnRIYW5kbGVyID0gaGFuZGxlcjsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFJlZ2lzdGVyIHRoZSBlcnJvciBldmVudCBoYW5kbGVyLgotICAgICAqCi0gICAgICogQHBhcmFtIGhhbmRsZXIgVGhlIG5ldyBlcnJvciBldmVudCBoYW5kbGVyLgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguUGFyc2VyI3NldEVycm9ySGFuZGxlcgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEVycm9ySGFuZGxlciAoRXJyb3JIYW5kbGVyIGhhbmRsZXIpCi0gICAgewotICAgICAgICB4bWxSZWFkZXIuc2V0RXJyb3JIYW5kbGVyKGhhbmRsZXIpOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogUGFyc2UgdGhlIGRvY3VtZW50LgotICAgICAqCi0gICAgICogPHA+VGhpcyBtZXRob2Qgd2lsbCB0aHJvdyBhbiBleGNlcHRpb24gaWYgdGhlIGVtYmVkZGVkCi0gICAgICogWE1MUmVhZGVyIGRvZXMgbm90IHN1cHBvcnQgdGhlCi0gICAgICogaHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL25hbWVzcGFjZS1wcmVmaXhlcyBwcm9wZXJ0eS48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gc3lzdGVtSWQgVGhlIGFic29sdXRlIFVSTCBvZiB0aGUgZG9jdW1lbnQuCi0gICAgICogQGV4Y2VwdGlvbiBqYXZhLmlvLklPRXhjZXB0aW9uIElmIHRoZXJlIGlzIGEgcHJvYmxlbSByZWFkaW5nCi0gICAgICogICAgICAgICAgICB0aGUgcmF3IGNvbnRlbnQgb2YgdGhlIGRvY3VtZW50LgotICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIElmIHRoZXJlIGlzIGEgcHJvYmxlbQotICAgICAqICAgICAgICAgICAgcHJvY2Vzc2luZyB0aGUgZG9jdW1lbnQuCi0gICAgICogQHNlZSAjcGFyc2Uob3JnLnhtbC5zYXguSW5wdXRTb3VyY2UpCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5QYXJzZXIjcGFyc2UoamF2YS5sYW5nLlN0cmluZykKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBwYXJzZSAoU3RyaW5nIHN5c3RlbUlkKQotICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgcGFyc2UobmV3IElucHV0U291cmNlKHN5c3RlbUlkKSk7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBQYXJzZSB0aGUgZG9jdW1lbnQuCi0gICAgICoKLSAgICAgKiA8cD5UaGlzIG1ldGhvZCB3aWxsIHRocm93IGFuIGV4Y2VwdGlvbiBpZiB0aGUgZW1iZWRkZWQKLSAgICAgKiBYTUxSZWFkZXIgZG9lcyBub3Qgc3VwcG9ydCB0aGUKLSAgICAgKiBodHRwOi8veG1sLm9yZy9zYXgvZmVhdHVyZXMvbmFtZXNwYWNlLXByZWZpeGVzIHByb3BlcnR5LjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBpbnB1dCBBbiBpbnB1dCBzb3VyY2UgZm9yIHRoZSBkb2N1bWVudC4KLSAgICAgKiBAZXhjZXB0aW9uIGphdmEuaW8uSU9FeGNlcHRpb24gSWYgdGhlcmUgaXMgYSBwcm9ibGVtIHJlYWRpbmcKLSAgICAgKiAgICAgICAgICAgIHRoZSByYXcgY29udGVudCBvZiB0aGUgZG9jdW1lbnQuCi0gICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gSWYgdGhlcmUgaXMgYSBwcm9ibGVtCi0gICAgICogICAgICAgICAgICBwcm9jZXNzaW5nIHRoZSBkb2N1bWVudC4KLSAgICAgKiBAc2VlICNwYXJzZShqYXZhLmxhbmcuU3RyaW5nKQotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguUGFyc2VyI3BhcnNlKG9yZy54bWwuc2F4LklucHV0U291cmNlKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHBhcnNlIChJbnB1dFNvdXJjZSBpbnB1dCkKLSAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIHNldHVwWE1MUmVhZGVyKCk7Ci0gICAgICAgIHhtbFJlYWRlci5wYXJzZShpbnB1dCk7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBTZXQgdXAgdGhlIFhNTCByZWFkZXIuCi0gICAgICovCi0gICAgcHJpdmF0ZSB2b2lkIHNldHVwWE1MUmVhZGVyICgpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIHhtbFJlYWRlci5zZXRGZWF0dXJlKCJodHRwOi8veG1sLm9yZy9zYXgvZmVhdHVyZXMvbmFtZXNwYWNlLXByZWZpeGVzIiwgdHJ1ZSk7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICB4bWxSZWFkZXIuc2V0RmVhdHVyZSgiaHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL25hbWVzcGFjZXMiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UpOwotICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgLy8gTk8gT1A6IGl0J3MganVzdCBleHRyYSBpbmZvcm1hdGlvbiwgYW5kIHdlIGNhbiBpZ25vcmUgaXQKLSAgICAgICAgfQotICAgICAgICB4bWxSZWFkZXIuc2V0Q29udGVudEhhbmRsZXIodGhpcyk7Ci0gICAgfQotCi0KLQotICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0gICAgLy8gSW1wbGVtZW50YXRpb24gb2Ygb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIuCi0gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLQotCi0gICAgLyoqCi0gICAgICogU2V0IGEgZG9jdW1lbnQgbG9jYXRvci4KLSAgICAgKgotICAgICAqIEBwYXJhbSBsb2NhdG9yIFRoZSBkb2N1bWVudCBsb2NhdG9yLgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjc2V0RG9jdW1lbnRMb2NhdG9yCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RG9jdW1lbnRMb2NhdG9yIChMb2NhdG9yIGxvY2F0b3IpCi0gICAgewotICAgICAgICBpZiAoZG9jdW1lbnRIYW5kbGVyICE9IG51bGwpCi0gICAgICAgICAgICBkb2N1bWVudEhhbmRsZXIuc2V0RG9jdW1lbnRMb2NhdG9yKGxvY2F0b3IpOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogU3RhcnQgZG9jdW1lbnQgZXZlbnQuCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBUaGUgY2xpZW50IG1heSByYWlzZSBhCi0gICAgICogICAgICAgICAgICBwcm9jZXNzaW5nIGV4Y2VwdGlvbi4KLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI3N0YXJ0RG9jdW1lbnQKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydERvY3VtZW50ICgpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGlmIChkb2N1bWVudEhhbmRsZXIgIT0gbnVsbCkKLSAgICAgICAgICAgIGRvY3VtZW50SGFuZGxlci5zdGFydERvY3VtZW50KCk7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBFbmQgZG9jdW1lbnQgZXZlbnQuCi0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBUaGUgY2xpZW50IG1heSByYWlzZSBhCi0gICAgICogICAgICAgICAgICBwcm9jZXNzaW5nIGV4Y2VwdGlvbi4KLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI2VuZERvY3VtZW50Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kRG9jdW1lbnQgKCkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaWYgKGRvY3VtZW50SGFuZGxlciAhPSBudWxsKQotICAgICAgICAgICAgZG9jdW1lbnRIYW5kbGVyLmVuZERvY3VtZW50KCk7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBBZGFwdCBhIFNBWDIgc3RhcnQgcHJlZml4IG1hcHBpbmcgZXZlbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcHJlZml4IFRoZSBwcmVmaXggYmVpbmcgbWFwcGVkLgotICAgICAqIEBwYXJhbSB1cmkgVGhlIE5hbWVzcGFjZSBVUkkgYmVpbmcgbWFwcGVkIHRvLgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjc3RhcnRQcmVmaXhNYXBwaW5nCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnRQcmVmaXhNYXBwaW5nIChTdHJpbmcgcHJlZml4LCBTdHJpbmcgdXJpKQotICAgIHsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIEFkYXB0IGEgU0FYMiBlbmQgcHJlZml4IG1hcHBpbmcgZXZlbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcHJlZml4IFRoZSBwcmVmaXggYmVpbmcgbWFwcGVkLgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjZW5kUHJlZml4TWFwcGluZwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZFByZWZpeE1hcHBpbmcgKFN0cmluZyBwcmVmaXgpCi0gICAgewotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogQWRhcHQgYSBTQVgyIHN0YXJ0IGVsZW1lbnQgZXZlbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdXJpIFRoZSBOYW1lc3BhY2UgVVJJLgotICAgICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIE5hbWVzcGFjZSBsb2NhbCBuYW1lLgotICAgICAqIEBwYXJhbSBxTmFtZSBUaGUgcXVhbGlmaWVkIChwcmVmaXhlZCkgbmFtZS4KLSAgICAgKiBAcGFyYW0gYXR0cyBUaGUgU0FYMiBhdHRyaWJ1dGVzLgotICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIFRoZSBjbGllbnQgbWF5IHJhaXNlIGEKLSAgICAgKiAgICAgICAgICAgIHByb2Nlc3NpbmcgZXhjZXB0aW9uLgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjZW5kRG9jdW1lbnQKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQgKFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcU5hbWUsIEF0dHJpYnV0ZXMgYXR0cykKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaWYgKGRvY3VtZW50SGFuZGxlciAhPSBudWxsKSB7Ci0gICAgICAgICAgICBxQXR0cy5zZXRBdHRyaWJ1dGVzKGF0dHMpOwotICAgICAgICAgICAgZG9jdW1lbnRIYW5kbGVyLnN0YXJ0RWxlbWVudChxTmFtZSwgcUF0dHMpOwotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBBZGFwdCBhIFNBWDIgZW5kIGVsZW1lbnQgZXZlbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdXJpIFRoZSBOYW1lc3BhY2UgVVJJLgotICAgICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIE5hbWVzcGFjZSBsb2NhbCBuYW1lLgotICAgICAqIEBwYXJhbSBxTmFtZSBUaGUgcXVhbGlmaWVkIChwcmVmaXhlZCkgbmFtZS4KLSAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBUaGUgY2xpZW50IG1heSByYWlzZSBhCi0gICAgICogICAgICAgICAgICBwcm9jZXNzaW5nIGV4Y2VwdGlvbi4KLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI2VuZEVsZW1lbnQKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbmRFbGVtZW50IChTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxOYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBxTmFtZSkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaWYgKGRvY3VtZW50SGFuZGxlciAhPSBudWxsKQotICAgICAgICAgICAgZG9jdW1lbnRIYW5kbGVyLmVuZEVsZW1lbnQocU5hbWUpOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogQWRhcHQgYSBTQVgyIGNoYXJhY3RlcnMgZXZlbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY2ggQW4gYXJyYXkgb2YgY2hhcmFjdGVycy4KLSAgICAgKiBAcGFyYW0gc3RhcnQgVGhlIHN0YXJ0aW5nIHBvc2l0aW9uIGluIHRoZSBhcnJheS4KLSAgICAgKiBAcGFyYW0gbGVuZ3RoIFRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyB0byB1c2UuCi0gICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gVGhlIGNsaWVudCBtYXkgcmFpc2UgYQotICAgICAqICAgICAgICAgICAgcHJvY2Vzc2luZyBleGNlcHRpb24uCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNjaGFyYWN0ZXJzCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY2hhcmFjdGVycyAoY2hhciBjaFtdLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIGlmIChkb2N1bWVudEhhbmRsZXIgIT0gbnVsbCkKLSAgICAgICAgICAgIGRvY3VtZW50SGFuZGxlci5jaGFyYWN0ZXJzKGNoLCBzdGFydCwgbGVuZ3RoKTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIEFkYXB0IGEgU0FYMiBpZ25vcmFibGUgd2hpdGVzcGFjZSBldmVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjaCBBbiBhcnJheSBvZiBjaGFyYWN0ZXJzLgotICAgICAqIEBwYXJhbSBzdGFydCBUaGUgc3RhcnRpbmcgcG9zaXRpb24gaW4gdGhlIGFycmF5LgotICAgICAqIEBwYXJhbSBsZW5ndGggVGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHVzZS4KLSAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBUaGUgY2xpZW50IG1heSByYWlzZSBhCi0gICAgICogICAgICAgICAgICBwcm9jZXNzaW5nIGV4Y2VwdGlvbi4KLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI2lnbm9yYWJsZVdoaXRlc3BhY2UKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBpZ25vcmFibGVXaGl0ZXNwYWNlIChjaGFyIGNoW10sIGludCBzdGFydCwgaW50IGxlbmd0aCkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgaWYgKGRvY3VtZW50SGFuZGxlciAhPSBudWxsKQotICAgICAgICAgICAgZG9jdW1lbnRIYW5kbGVyLmlnbm9yYWJsZVdoaXRlc3BhY2UoY2gsIHN0YXJ0LCBsZW5ndGgpOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogQWRhcHQgYSBTQVgyIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gZXZlbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdGFyZ2V0IFRoZSBwcm9jZXNzaW5nIGluc3RydWN0aW9uIHRhcmdldC4KLSAgICAgKiBAcGFyYW0gZGF0YSBUaGUgcmVtYWluZGVyIG9mIHRoZSBwcm9jZXNzaW5nIGluc3RydWN0aW9uCi0gICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gVGhlIGNsaWVudCBtYXkgcmFpc2UgYQotICAgICAqICAgICAgICAgICAgcHJvY2Vzc2luZyBleGNlcHRpb24uCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24gKFN0cmluZyB0YXJnZXQsIFN0cmluZyBkYXRhKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICBpZiAoZG9jdW1lbnRIYW5kbGVyICE9IG51bGwpCi0gICAgICAgICAgICBkb2N1bWVudEhhbmRsZXIucHJvY2Vzc2luZ0luc3RydWN0aW9uKHRhcmdldCwgZGF0YSk7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBBZGFwdCBhIFNBWDIgc2tpcHBlZCBlbnRpdHkgZXZlbnQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgc2tpcHBlZCBlbnRpdHkuCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNza2lwcGVkRW50aXR5Ci0gICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gVGhyb3dhYmxlIGJ5IHN1YmNsYXNzZXMuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2tpcHBlZEVudGl0eSAoU3RyaW5nIG5hbWUpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgfQotCi0KLQotICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0gICAgLy8gSW50ZXJuYWwgc3RhdGUuCi0gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLQotICAgIFhNTFJlYWRlciB4bWxSZWFkZXI7Ci0gICAgRG9jdW1lbnRIYW5kbGVyIGRvY3VtZW50SGFuZGxlcjsKLSAgICBBdHRyaWJ1dGVzQWRhcHRlciBxQXR0czsKLQotCi0KLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotICAgIC8vIEludGVybmFsIGNsYXNzLgotICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0KLQotICAgIC8qKgotICAgICAqIEludGVybmFsIGNsYXNzIHRvIHdyYXAgYSBTQVgyIEF0dHJpYnV0ZXMgb2JqZWN0IGZvciBTQVgxLgotICAgICAqLwotICAgIGZpbmFsIGNsYXNzIEF0dHJpYnV0ZXNBZGFwdGVyIGltcGxlbWVudHMgQXR0cmlidXRlTGlzdAotICAgIHsKLSAgICAgICAgQXR0cmlidXRlc0FkYXB0ZXIgKCkKLSAgICAgICAgewotICAgICAgICB9Ci0KLQotICAgICAgICAvKioKLSAgICAgICAgICogU2V0IHRoZSBlbWJlZGRlZCBBdHRyaWJ1dGVzIG9iamVjdC4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIFRoZSBlbWJlZGRlZCBTQVgyIEF0dHJpYnV0ZXMuCi0gICAgICAgICAqLwotICAgICAgICB2b2lkIHNldEF0dHJpYnV0ZXMgKEF0dHJpYnV0ZXMgYXR0cmlidXRlcykKLSAgICAgICAgewotICAgICAgICAgICAgdGhpcy5hdHRyaWJ1dGVzID0gYXR0cmlidXRlczsKLSAgICAgICAgfQotCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFJldHVybiB0aGUgbnVtYmVyIG9mIGF0dHJpYnV0ZXMuCi0gICAgICAgICAqCi0gICAgICAgICAqIEByZXR1cm4gVGhlIGxlbmd0aCBvZiB0aGUgYXR0cmlidXRlIGxpc3QuCi0gICAgICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQXR0cmlidXRlTGlzdCNnZXRMZW5ndGgKLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBpbnQgZ2V0TGVuZ3RoICgpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHJldHVybiBhdHRyaWJ1dGVzLmdldExlbmd0aCgpOwotICAgICAgICB9Ci0KLQotICAgICAgICAvKioKLSAgICAgICAgICogUmV0dXJuIHRoZSBxdWFsaWZpZWQgKHByZWZpeGVkKSBuYW1lIG9mIGFuIGF0dHJpYnV0ZSBieSBwb3NpdGlvbi4KLSAgICAgICAgICoKLSAgICAgICAgICogQHJldHVybiBUaGUgcXVhbGlmaWVkIG5hbWUuCi0gICAgICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQXR0cmlidXRlTGlzdCNnZXROYW1lCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUgKGludCBpKQotICAgICAgICB7Ci0gICAgICAgICAgICByZXR1cm4gYXR0cmlidXRlcy5nZXRRTmFtZShpKTsKLSAgICAgICAgfQotCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFJldHVybiB0aGUgdHlwZSBvZiBhbiBhdHRyaWJ1dGUgYnkgcG9zaXRpb24uCi0gICAgICAgICAqCi0gICAgICAgICAqIEByZXR1cm4gVGhlIHR5cGUuCi0gICAgICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQXR0cmlidXRlTGlzdCNnZXRUeXBlKGludCkKLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0VHlwZSAoaW50IGkpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHJldHVybiBhdHRyaWJ1dGVzLmdldFR5cGUoaSk7Ci0gICAgICAgIH0KLQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBSZXR1cm4gdGhlIHZhbHVlIG9mIGFuIGF0dHJpYnV0ZSBieSBwb3NpdGlvbi4KLSAgICAgICAgICoKLSAgICAgICAgICogQHJldHVybiBUaGUgdmFsdWUuCi0gICAgICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQXR0cmlidXRlTGlzdCNnZXRWYWx1ZShpbnQpCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFZhbHVlIChpbnQgaSkKLSAgICAgICAgewotICAgICAgICAgICAgcmV0dXJuIGF0dHJpYnV0ZXMuZ2V0VmFsdWUoaSk7Ci0gICAgICAgIH0KLQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBSZXR1cm4gdGhlIHR5cGUgb2YgYW4gYXR0cmlidXRlIGJ5IHF1YWxpZmllZCAocHJlZml4ZWQpIG5hbWUuCi0gICAgICAgICAqCi0gICAgICAgICAqIEByZXR1cm4gVGhlIHR5cGUuCi0gICAgICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQXR0cmlidXRlTGlzdCNnZXRUeXBlKGphdmEubGFuZy5TdHJpbmcpCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFR5cGUgKFN0cmluZyBxTmFtZSkKLSAgICAgICAgewotICAgICAgICAgICAgcmV0dXJuIGF0dHJpYnV0ZXMuZ2V0VHlwZShxTmFtZSk7Ci0gICAgICAgIH0KLQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBSZXR1cm4gdGhlIHZhbHVlIG9mIGFuIGF0dHJpYnV0ZSBieSBxdWFsaWZpZWQgKHByZWZpeGVkKSBuYW1lLgotICAgICAgICAgKgotICAgICAgICAgKiBAcmV0dXJuIFRoZSB2YWx1ZS4KLSAgICAgICAgICogQHNlZSBvcmcueG1sLnNheC5BdHRyaWJ1dGVMaXN0I2dldFZhbHVlKGphdmEubGFuZy5TdHJpbmcpCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFZhbHVlIChTdHJpbmcgcU5hbWUpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHJldHVybiBhdHRyaWJ1dGVzLmdldFZhbHVlKHFOYW1lKTsKLSAgICAgICAgfQotCi0gICAgICAgIHByaXZhdGUgQXR0cmlidXRlcyBhdHRyaWJ1dGVzOwotICAgIH0KLQotfQotCi0vLyBlbmQgb2YgWE1MUmVhZGVyQWRhcHRlci5qYXZhCmRpZmYgLS1naXQgYS9zcmMvb3JnL3htbC9zYXgvaGVscGVycy9YTUxSZWFkZXJGYWN0b3J5LmphdmEgYi9zcmMvb3JnL3htbC9zYXgvaGVscGVycy9YTUxSZWFkZXJGYWN0b3J5LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDI3Y2UxYzEuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy94bWwvc2F4L2hlbHBlcnMvWE1MUmVhZGVyRmFjdG9yeS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjQ0ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDAsIDIwMTMsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCi0gKgotICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKLSAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCi0gKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKLSAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKLSAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgotICoKLSAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAotICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCi0gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKLSAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0Ci0gKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgotICoKLSAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KLSAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKLSAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KLSAqCi0gKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQotICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQotICogcXVlc3Rpb25zLgotICovCi0KLS8vIFhNTFJlYWRlckZhY3RvcnkuamF2YSAtIGZhY3RvcnkgZm9yIGNyZWF0aW5nIGEgbmV3IHJlYWRlci4KLS8vIGh0dHA6Ly93d3cuc2F4cHJvamVjdC5vcmcKLS8vIFdyaXR0ZW4gYnkgRGF2aWQgTWVnZ2luc29uCi0vLyBhbmQgYnkgRGF2aWQgQnJvd25lbGwKLS8vIE5PIFdBUlJBTlRZISAgVGhpcyBjbGFzcyBpcyBpbiB0aGUgUHVibGljIERvbWFpbi4KLS8vICRJZDogWE1MUmVhZGVyRmFjdG9yeS5qYXZhLHYgMS4yLjIuMSAyMDA1LzA3LzMxIDIyOjQ4OjA4IGplZmZzdXR0b3IgRXhwICQKLQotcGFja2FnZSBvcmcueG1sLnNheC5oZWxwZXJzOwotaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRSZWFkZXI7Ci1pbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKLWltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtUmVhZGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LlhNTFJlYWRlcjsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci0KLQotLyoqCi0gKiBGYWN0b3J5IGZvciBjcmVhdGluZyBhbiBYTUwgcmVhZGVyLgotICoKLSAqIDxibG9ja3F1b3RlPgotICogPGVtPlRoaXMgbW9kdWxlLCBib3RoIHNvdXJjZSBjb2RlIGFuZCBkb2N1bWVudGF0aW9uLCBpcyBpbiB0aGUKLSAqIFB1YmxpYyBEb21haW4sIGFuZCBjb21lcyB3aXRoIDxzdHJvbmc+Tk8gV0FSUkFOVFk8L3N0cm9uZz4uPC9lbT4KLSAqIFNlZSA8YSBocmVmPSdodHRwOi8vd3d3LnNheHByb2plY3Qub3JnJz5odHRwOi8vd3d3LnNheHByb2plY3Qub3JnPC9hPgotICogZm9yIGZ1cnRoZXIgaW5mb3JtYXRpb24uCi0gKiA8L2Jsb2NrcXVvdGU+Ci0gKgotICogPHA+VGhpcyBjbGFzcyBjb250YWlucyBzdGF0aWMgbWV0aG9kcyBmb3IgY3JlYXRpbmcgYW4gWE1MIHJlYWRlcgotICogZnJvbSBhbiBleHBsaWNpdCBjbGFzcyBuYW1lLCBvciBiYXNlZCBvbiBydW50aW1lIGRlZmF1bHRzOjwvcD4KLSAqCi0gKiA8cHJlPgotICogdHJ5IHsKLSAqICAgWE1MUmVhZGVyIG15UmVhZGVyID0gWE1MUmVhZGVyRmFjdG9yeS5jcmVhdGVYTUxSZWFkZXIoKTsKLSAqIH0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7Ci0gKiAgIFN5c3RlbS5lcnIucHJpbnRsbihlLmdldE1lc3NhZ2UoKSk7Ci0gKiB9Ci0gKiA8L3ByZT4KLSAqCi0gKiA8cD48c3Ryb25nPk5vdGUgdG8gRGlzdHJpYnV0aW9ucyBidW5kbGVkIHdpdGggcGFyc2Vyczo8L3N0cm9uZz4KLSAqIFlvdSBzaG91bGQgbW9kaWZ5IHRoZSBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgbm8tYXJndW1lbnRzCi0gKiA8ZW0+Y3JlYXRlWE1MUmVhZGVyPC9lbT4gdG8gaGFuZGxlIGNhc2VzIHdoZXJlIHRoZSBleHRlcm5hbAotICogY29uZmlndXJhdGlvbiBtZWNoYW5pc21zIGFyZW4ndCBzZXQgdXAuICBUaGF0IG1ldGhvZCBzaG91bGQgZG8gaXRzCi0gKiBiZXN0IHRvIHJldHVybiBhIHBhcnNlciB3aGVuIG9uZSBpcyBpbiB0aGUgY2xhc3MgcGF0aCwgZXZlbiB3aGVuCi0gKiBub3RoaW5nIGJvdW5kIGl0cyBjbGFzcyBuYW1lIHRvIDxjb2RlPm9yZy54bWwuc2F4LmRyaXZlcjwvY29kZT4gc28KLSAqIHRob3NlIGNvbmZpZ3VyYXRpb24gbWVjaGFuaXNtcyB3b3VsZCBzZWUgaXQuPC9wPgotICoKLSAqIEBzaW5jZSBTQVggMi4wCi0gKiBAYXV0aG9yIERhdmlkIE1lZ2dpbnNvbiwgRGF2aWQgQnJvd25lbGwKLSAqIEB2ZXJzaW9uIDIuMC4xIChzYXgycjIpCi0gKi8KLWZpbmFsIHB1YmxpYyBjbGFzcyBYTUxSZWFkZXJGYWN0b3J5Ci17Ci0gICAgLyoqCi0gICAgICogUHJpdmF0ZSBjb25zdHJ1Y3Rvci4KLSAgICAgKgotICAgICAqIDxwPlRoaXMgY29uc3RydWN0b3IgcHJldmVudHMgdGhlIGNsYXNzIGZyb20gYmVpbmcgaW5zdGFudGlhdGVkLjwvcD4KLSAgICAgKi8KLSAgICBwcml2YXRlIFhNTFJlYWRlckZhY3RvcnkgKCkKLSAgICB7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIHByb3BlcnR5ID0gIm9yZy54bWwuc2F4LmRyaXZlciI7Ci0gICAgcHJpdmF0ZSBzdGF0aWMgU2VjdXJpdHlTdXBwb3J0IHNzID0gbmV3IFNlY3VyaXR5U3VwcG9ydCgpOwotCi0gICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIF9jbHNGcm9tSmFyID0gbnVsbDsKLSAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIF9qYXJyZWFkID0gZmFsc2U7Ci0gICAgLyoqCi0gICAgICogQXR0ZW1wdCB0byBjcmVhdGUgYW4gWE1MUmVhZGVyIGZyb20gc3lzdGVtIGRlZmF1bHRzLgotICAgICAqIEluIGVudmlyb25tZW50cyB3aGljaCBjYW4gc3VwcG9ydCBpdCwgdGhlIG5hbWUgb2YgdGhlIFhNTFJlYWRlcgotICAgICAqIGNsYXNzIGlzIGRldGVybWluZWQgYnkgdHJ5aW5nIGVhY2ggdGhlc2Ugb3B0aW9ucyBpbiBvcmRlciwgYW5kCi0gICAgICogdXNpbmcgdGhlIGZpcnN0IG9uZSB3aGljaCBzdWNjZWVkczo8L3A+IDx1bD4KLSAgICAgKgotICAgICAqIDxsaT5JZiB0aGUgc3lzdGVtIHByb3BlcnR5IDxjb2RlPm9yZy54bWwuc2F4LmRyaXZlcjwvY29kZT4KLSAgICAgKiBoYXMgYSB2YWx1ZSwgdGhhdCBpcyB1c2VkIGFzIGFuIFhNTFJlYWRlciBjbGFzcyBuYW1lLiA8L2xpPgotICAgICAqCi0gICAgICogPGxpPlRoZSBKQVIgIlNlcnZpY2VzIEFQSSIgaXMgdXNlZCB0byBsb29rIGZvciBhIGNsYXNzIG5hbWUKLSAgICAgKiBpbiB0aGUgPGVtPk1FVEEtSU5GL3NlcnZpY2VzL29yZy54bWwuc2F4LmRyaXZlcjwvZW0+IGZpbGUgaW4KLSAgICAgKiBqYXJmaWxlcyBhdmFpbGFibGUgdG8gdGhlIHJ1bnRpbWUuPC9saT4KLSAgICAgKgotICAgICAqIDxsaT4gU0FYIHBhcnNlciBkaXN0cmlidXRpb25zIGFyZSBzdHJvbmdseSBlbmNvdXJhZ2VkIHRvIHByb3ZpZGUKLSAgICAgKiBhIGRlZmF1bHQgWE1MUmVhZGVyIGNsYXNzIG5hbWUgdGhhdCB3aWxsIHRha2UgZWZmZWN0IG9ubHkgd2hlbgotICAgICAqIHByZXZpb3VzIG9wdGlvbnMgKG9uIHRoaXMgbGlzdCkgYXJlIG5vdCBzdWNjZXNzZnVsLjwvbGk+Ci0gICAgICoKLSAgICAgKiA8bGk+RmluYWxseSwgaWYge0BsaW5rIFBhcnNlckZhY3RvcnkjbWFrZVBhcnNlcigpfSBjYW4KLSAgICAgKiByZXR1cm4gYSBzeXN0ZW0gZGVmYXVsdCBTQVgxIHBhcnNlciwgdGhhdCBwYXJzZXIgaXMgd3JhcHBlZCBpbgotICAgICAqIGEge0BsaW5rIFBhcnNlckFkYXB0ZXJ9LiAgKFRoaXMgaXMgYSBtaWdyYXRpb24gYWlkIGZvciBTQVgxCi0gICAgICogZW52aXJvbm1lbnRzLCB3aGVyZSB0aGUgPGNvZGU+b3JnLnhtbC5zYXgucGFyc2VyPC9jb2RlPiBzeXN0ZW0KLSAgICAgKiBwcm9wZXJ0eSB3aWxsIG9mdGVuIGJlIHVzYWJsZS4pIDwvbGk+Ci0gICAgICoKLSAgICAgKiA8L3VsPgotICAgICAqCi0gICAgICogPHA+IEluIGVudmlyb25tZW50cyBzdWNoIGFzIHNtYWxsIGVtYmVkZGVkIHN5c3RlbXMsIHdoaWNoIGNhbiBub3QKLSAgICAgKiBzdXBwb3J0IHRoYXQgZmxleGliaWxpdHksIG90aGVyIG1lY2hhbmlzbXMgdG8gZGV0ZXJtaW5lIHRoZSBkZWZhdWx0Ci0gICAgICogbWF5IGJlIHVzZWQuIDwvcD4KLSAgICAgKgotICAgICAqIDxwPk5vdGUgdGhhdCBtYW55IEphdmEgZW52aXJvbm1lbnRzIGFsbG93IHN5c3RlbSBwcm9wZXJ0aWVzIHRvIGJlCi0gICAgICogaW5pdGlhbGl6ZWQgb24gYSBjb21tYW5kIGxpbmUuICBUaGlzIG1lYW5zIHRoYXQgPGVtPmluIG1vc3QgY2FzZXM8L2VtPgotICAgICAqIHNldHRpbmcgYSBnb29kIHZhbHVlIGZvciB0aGF0IHByb3BlcnR5IGVuc3VyZXMgdGhhdCBjYWxscyB0byB0aGlzCi0gICAgICogbWV0aG9kIHdpbGwgc3VjY2VlZCwgZXhjZXB0IHdoZW4gc2VjdXJpdHkgcG9saWNpZXMgaW50ZXJ2ZW5lLgotICAgICAqIFRoaXMgd2lsbCBhbHNvIG1heGltaXplIGFwcGxpY2F0aW9uIHBvcnRhYmlsaXR5IHRvIG9sZGVyIFNBWAotICAgICAqIGVudmlyb25tZW50cywgd2l0aCBsZXNzIHJvYnVzdCBpbXBsZW1lbnRhdGlvbnMgb2YgdGhpcyBtZXRob2QuCi0gICAgICogPC9wPgotICAgICAqCi0gICAgICogQHJldHVybiBBIG5ldyBYTUxSZWFkZXIuCi0gICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gSWYgbm8gZGVmYXVsdCBYTUxSZWFkZXIgY2xhc3MKLSAgICAgKiAgICAgICAgICAgIGNhbiBiZSBpZGVudGlmaWVkIGFuZCBpbnN0YW50aWF0ZWQuCi0gICAgICogQHNlZSAjY3JlYXRlWE1MUmVhZGVyKGphdmEubGFuZy5TdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBYTUxSZWFkZXIgY3JlYXRlWE1MUmVhZGVyICgpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIFN0cmluZyAgICAgICAgICBjbGFzc05hbWUgPSBudWxsOwotICAgICAgICBDbGFzc0xvYWRlciAgICAgY2wgPSBzcy5nZXRDb250ZXh0Q2xhc3NMb2FkZXIoKTsKLQotICAgICAgICAvLyAxLiB0cnkgdGhlIEpWTS1pbnN0YW5jZS13aWRlIHN5c3RlbSBwcm9wZXJ0eQotICAgICAgICB0cnkgewotICAgICAgICAgICAgY2xhc3NOYW1lID0gc3MuZ2V0U3lzdGVtUHJvcGVydHkocHJvcGVydHkpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIGUpIHsgLyogY29udGludWUgc2VhcmNoaW5nICovIH0KLQotICAgICAgICAvLyAyLiBpZiB0aGF0IGZhaWxzLCB0cnkgTUVUQS1JTkYvc2VydmljZXMvCi0gICAgICAgIGlmIChjbGFzc05hbWUgPT0gbnVsbCkgewotICAgICAgICAgICAgaWYgKCFfamFycmVhZCkgewotICAgICAgICAgICAgICAgIF9qYXJyZWFkID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICBTdHJpbmcgICAgICBzZXJ2aWNlID0gIk1FVEEtSU5GL3NlcnZpY2VzLyIgKyBwcm9wZXJ0eTsKLSAgICAgICAgICAgICAgICBJbnB1dFN0cmVhbSBpbjsKLSAgICAgICAgICAgICAgICBCdWZmZXJlZFJlYWRlciAgICAgIHJlYWRlcjsKLQotICAgICAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChjbCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpbiA9IHNzLmdldFJlc291cmNlQXNTdHJlYW0oY2wsIHNlcnZpY2UpOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBJZiBubyBwcm92aWRlciBmb3VuZCB0aGVuIHRyeSB0aGUgY3VycmVudCBDbGFzc0xvYWRlcgotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGluID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbCA9IG51bGw7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW4gPSBzcy5nZXRSZXNvdXJjZUFzU3RyZWFtKGNsLCBzZXJ2aWNlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5vIENvbnRleHQgQ2xhc3NMb2FkZXIsIHRyeSB0aGUgY3VycmVudCBDbGFzc0xvYWRlcgotICAgICAgICAgICAgICAgICAgICAgICAgaW4gPSBzcy5nZXRSZXNvdXJjZUFzU3RyZWFtKGNsLCBzZXJ2aWNlKTsKLSAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgIGlmIChpbiAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICByZWFkZXIgPSBuZXcgQnVmZmVyZWRSZWFkZXIgKG5ldyBJbnB1dFN0cmVhbVJlYWRlciAoaW4sICJVVEY4IikpOwotICAgICAgICAgICAgICAgICAgICAgICAgX2Nsc0Zyb21KYXIgPSByZWFkZXIucmVhZExpbmUgKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpbi5jbG9zZSAoKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2xhc3NOYW1lID0gX2Nsc0Zyb21KYXI7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyAzLiBEaXN0cm8tc3BlY2lmaWMgZmFsbGJhY2sKLSAgICAgICAgaWYgKGNsYXNzTmFtZSA9PSBudWxsKSB7Ci0vLyBCRUdJTiBESVNUUklCVVRJT04tU1BFQ0lGSUMKLQotICAgICAgICAgICAgLy8gRVhBTVBMRToKLSAgICAgICAgICAgIC8vIGNsYXNzTmFtZSA9ICJjb20uZXhhbXBsZS5zYXguWG1sUmVhZGVyIjsKLSAgICAgICAgICAgIC8vIG9yIGEgJEpBVkFfSE9NRS9qcmUvbGliLypwcm9wZXJ0aWVzIHNldHRpbmcuLi4KLSAgICAgICAgICAgIGNsYXNzTmFtZSA9ICJjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnBhcnNlcnMuU0FYUGFyc2VyIjsKLQotLy8gRU5EIERJU1RSSUJVVElPTi1TUEVDSUZJQwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gZG8gd2Uga25vdyB0aGUgWE1MUmVhZGVyIGltcGxlbWVudGF0aW9uIGNsYXNzIHlldD8KLSAgICAgICAgaWYgKGNsYXNzTmFtZSAhPSBudWxsKQotICAgICAgICAgICAgcmV0dXJuIGxvYWRDbGFzcyAoY2wsIGNsYXNzTmFtZSk7Ci0KLSAgICAgICAgLy8gNC4gcGFuaWMgLS0gYWRhcHQgYW55IFNBWDEgcGFyc2VyCi0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICByZXR1cm4gbmV3IFBhcnNlckFkYXB0ZXIgKFBhcnNlckZhY3RvcnkubWFrZVBhcnNlciAoKSk7Ci0gICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uICgiQ2FuJ3QgY3JlYXRlIGRlZmF1bHQgWE1MUmVhZGVyOyAiCi0gICAgICAgICAgICAgICAgICAgICsgImlzIHN5c3RlbSBwcm9wZXJ0eSBvcmcueG1sLnNheC5kcml2ZXIgc2V0PyIpOwotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBBdHRlbXB0IHRvIGNyZWF0ZSBhbiBYTUwgcmVhZGVyIGZyb20gYSBjbGFzcyBuYW1lLgotICAgICAqCi0gICAgICogPHA+R2l2ZW4gYSBjbGFzcyBuYW1lLCB0aGlzIG1ldGhvZCBhdHRlbXB0cyB0byBsb2FkCi0gICAgICogYW5kIGluc3RhbnRpYXRlIHRoZSBjbGFzcyBhcyBhbiBYTUwgcmVhZGVyLjwvcD4KLSAgICAgKgotICAgICAqIDxwPk5vdGUgdGhhdCB0aGlzIG1ldGhvZCB3aWxsIG5vdCBiZSB1c2FibGUgaW4gZW52aXJvbm1lbnRzIHdoZXJlCi0gICAgICogdGhlIGNhbGxlciAocGVyaGFwcyBhbiBhcHBsZXQpIGlzIG5vdCBwZXJtaXR0ZWQgdG8gbG9hZCBjbGFzc2VzCi0gICAgICogZHluYW1pY2FsbHkuPC9wPgotICAgICAqCi0gICAgICogQHJldHVybiBBIG5ldyBYTUwgcmVhZGVyLgotICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIElmIHRoZSBjbGFzcyBjYW5ub3QgYmUKLSAgICAgKiAgICAgICAgICAgIGxvYWRlZCwgaW5zdGFudGlhdGVkLCBhbmQgY2FzdCB0byBYTUxSZWFkZXIuCi0gICAgICogQHNlZSAjY3JlYXRlWE1MUmVhZGVyKCkKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFhNTFJlYWRlciBjcmVhdGVYTUxSZWFkZXIgKFN0cmluZyBjbGFzc05hbWUpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICAgIHJldHVybiBsb2FkQ2xhc3MgKHNzLmdldENvbnRleHRDbGFzc0xvYWRlcigpLCBjbGFzc05hbWUpOwotICAgIH0KLQotICAgIHByaXZhdGUgc3RhdGljIFhNTFJlYWRlciBsb2FkQ2xhc3MgKENsYXNzTG9hZGVyIGxvYWRlciwgU3RyaW5nIGNsYXNzTmFtZSkKLSAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICB0cnkgewotICAgICAgICAgICAgcmV0dXJuIChYTUxSZWFkZXIpIE5ld0luc3RhbmNlLm5ld0luc3RhbmNlIChsb2FkZXIsIGNsYXNzTmFtZSk7Ci0gICAgICAgIH0gY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gZTEpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oIlNBWDIgZHJpdmVyIGNsYXNzICIgKyBjbGFzc05hbWUgKwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIG5vdCBmb3VuZCIsIGUxKTsKLSAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBlMikgewotICAgICAgICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbigiU0FYMiBkcml2ZXIgY2xhc3MgIiArIGNsYXNzTmFtZSArCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgZm91bmQgYnV0IGNhbm5vdCBiZSBsb2FkZWQiLCBlMik7Ci0gICAgICAgIH0gY2F0Y2ggKEluc3RhbnRpYXRpb25FeGNlcHRpb24gZTMpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oIlNBWDIgZHJpdmVyIGNsYXNzICIgKyBjbGFzc05hbWUgKwotICAgICAgICAgICAiIGxvYWRlZCBidXQgY2Fubm90IGJlIGluc3RhbnRpYXRlZCAobm8gZW1wdHkgcHVibGljIGNvbnN0cnVjdG9yPykiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlMyk7Ci0gICAgICAgIH0gY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBlNCkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbigiU0FYMiBkcml2ZXIgY2xhc3MgIiArIGNsYXNzTmFtZSArCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgZG9lcyBub3QgaW1wbGVtZW50IFhNTFJlYWRlciIsIGU0KTsKLSAgICAgICAgfQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcveG1sL3NheC9oZWxwZXJzL3BhY2thZ2UuaHRtbCBiL3NyYy9vcmcveG1sL3NheC9oZWxwZXJzL3BhY2thZ2UuaHRtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAxZjBlMi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3htbC9zYXgvaGVscGVycy9wYWNrYWdlLmh0bWwKKysrIC9kZXYvbnVsbApAQCAtMSwxMSArMCwwIEBACi08SFRNTD48SEVBRD4KLTwhLS0gJElkOiBwYWNrYWdlLmh0bWwsdiAxLjMgMjAwNy8xMC8wMiAxOTozMjoyNCBuZHcgRXhwICQgLS0+Ci08L0hFQUQ+PEJPRFk+Ci0KLTxwPlRoaXMgcGFja2FnZSBjb250YWlucyAiaGVscGVyIiBjbGFzc2VzLCBpbmNsdWRpbmcKLXN1cHBvcnQgZm9yIGJvb3RzdHJhcHBpbmcgU0FYLWJhc2VkIGFwcGxpY2F0aW9ucy4KLQotPHA+U2VlIDxhIHRhcmdldD0nX3RvcCcgaHJlZj0naHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZyc+aHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZzwvYT4KLWZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IFNBWC48L3A+Ci0KLTwvQk9EWT48L0hUTUw+CmRpZmYgLS1naXQgYS9zcmMvb3JnL3htbC9zYXgvcGFja2FnZS5odG1sIGIvc3JjL29yZy94bWwvc2F4L3BhY2thZ2UuaHRtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMmFmNWU0Yy4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL3htbC9zYXgvcGFja2FnZS5odG1sCisrKyAvZGV2L251bGwKQEAgLTEsMjk3ICswLDAgQEAKLTxodG1sPjxoZWFkPgotPCEtLSAkSWQ6IHBhY2thZ2UuaHRtbCx2IDEuMyAyMDA3LzEwLzAyIDE5OjMyOjI0IG5kdyBFeHAgJCAtLT4KLTwvaGVhZD48Ym9keT4KLQotPHA+IFRoaXMgcGFja2FnZSBwcm92aWRlcyB0aGUgY29yZSBTQVggQVBJcy4KLVNvbWUgU0FYMSBBUElzIGFyZSBkZXByZWNhdGVkIHRvIGVuY291cmFnZSBpbnRlZ3JhdGlvbiBvZgotbmFtZXNwYWNlLWF3YXJlbmVzcyBpbnRvIGRlc2lnbnMgb2YgbmV3IGFwcGxpY2F0aW9ucwotYW5kIGludG8gbWFpbnRlbmFuY2Ugb2YgZXhpc3RpbmcgaW5mcmFzdHJ1Y3R1cmUuIDwvcD4KLQotPHA+U2VlIDxhIHRhcmdldD0nX3RvcCcgaHJlZj0naHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZyc+aHR0cDovL3d3dy5zYXhwcm9qZWN0Lm9yZzwvYT4KLWZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IFNBWC48L3A+Ci0KLQotPGgyPiBTQVgyIFN0YW5kYXJkIEZlYXR1cmUgRmxhZ3MgPC9oMj4KLQotPHA+IE9uZSBvZiB0aGUgZXNzZW50aWFsIGNoYXJhY3RlcmlzdGljcyBvZiBTQVgyIGlzIHRoYXQgaXQgYWRkZWQKLWZlYXR1cmUgZmxhZ3Mgd2hpY2ggY2FuIGJlIHVzZWQgdG8gZXhhbWluZSBhbmQgcGVyaGFwcyBtb2RpZnkKLXBhcnNlciBtb2RlcywgaW4gcGFydGljdWxhciBtb2RlcyBzdWNoIGFzIHZhbGlkYXRpb24uCi1TaW5jZSBmZWF0dXJlcyBhcmUgaWRlbnRpZmllZCBieSAoYWJzb2x1dGUpIFVSSXMsIGFueW9uZQotY2FuIGRlZmluZSBzdWNoIGZlYXR1cmVzLiAgIAotQ3VycmVudGx5IGRlZmluZWQgc3RhbmRhcmQgZmVhdHVyZSBVUklzIGhhdmUgdGhlIHByZWZpeAotPGNvZGU+aHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzLzwvY29kZT4gYmVmb3JlIGFuIGlkZW50aWZpZXIgc3VjaCBhcwotPGNvZGU+dmFsaWRhdGlvbjwvY29kZT4uICBUdXJuIGZlYXR1cmVzIG9uIG9yIG9mZiB1c2luZwotPGVtPnNldEZlYXR1cmU8L2VtPi4gIFRob3NlIHN0YW5kYXJkIGlkZW50aWZpZXJzIGFyZTogPC9wPgotCi0KLTx0YWJsZSBib3JkZXI9IjEiIGNlbGxwYWRkaW5nPSIzIiBjZWxsc3BhY2luZz0iMCIgd2lkdGg9IjEwMCUiPgotICAgIDx0ciBhbGlnbj0iY2VudGVyIiBiZ2NvbG9yPSIjY2NjY2ZmIj4KLQk8dGg+RmVhdHVyZSBJRDwvdGg+Ci0JPHRoPkFjY2VzczwvdGg+Ci0JPHRoPkRlZmF1bHQ8L3RoPgotCTx0aD5EZXNjcmlwdGlvbjwvdGg+Ci0JPC90cj4KLQotICAgIDx0cj4KLQk8dGQ+ZXh0ZXJuYWwtZ2VuZXJhbC1lbnRpdGllczwvdGQ+Ci0JPHRkPjxlbT5yZWFkL3dyaXRlPC9lbT48L3RkPgotCTx0ZD48ZW0+dW5zcGVjaWZpZWQ8L2VtPjwvdGQ+Ci0JPHRkPiBSZXBvcnRzIHdoZXRoZXIgdGhpcyBwYXJzZXIgcHJvY2Vzc2VzIGV4dGVybmFsCi0JICAgIGdlbmVyYWwgZW50aXRpZXM7IGFsd2F5cyB0cnVlIGlmIHZhbGlkYXRpbmcuCi0JCTwvdGQ+Ci0JPC90cj4KLQotICAgIDx0cj4KLQk8dGQ+ZXh0ZXJuYWwtcGFyYW1ldGVyLWVudGl0aWVzPC90ZD4KLQk8dGQ+PGVtPnJlYWQvd3JpdGU8L2VtPjwvdGQ+Ci0JPHRkPjxlbT51bnNwZWNpZmllZDwvZW0+PC90ZD4KLQk8dGQ+IFJlcG9ydHMgd2hldGhlciB0aGlzIHBhcnNlciBwcm9jZXNzZXMgZXh0ZXJuYWwKLQkgICAgcGFyYW1ldGVyIGVudGl0aWVzOyBhbHdheXMgdHJ1ZSBpZiB2YWxpZGF0aW5nLgotCQk8L3RkPgotCTwvdHI+Ci0KLSAgICA8dHI+Ci0JPHRkPmlzLXN0YW5kYWxvbmU8L3RkPgotCTx0ZD4ocGFyc2luZykgPGVtPnJlYWQtb25seTwvZW0+LCAobm90IHBhcnNpbmcpIDxlbT5ub25lPC9lbT48L3RkPgotCTx0ZD5ub3QgYXBwbGljYWJsZTwvdGQ+Ci0JPHRkPiBNYXkgYmUgZXhhbWluZWQgb25seSBkdXJpbmcgYSBwYXJzZSwgYWZ0ZXIgdGhlCi0JICAgIDxlbT5zdGFydERvY3VtZW50KCk8L2VtPiBjYWxsYmFjayBoYXMgYmVlbiBjb21wbGV0ZWQ7IHJlYWQtb25seS4KLQkgICAgVGhlIHZhbHVlIGlzIHRydWUgaWYgdGhlIGRvY3VtZW50IHNwZWNpZmllZCBzdGFuZGFsb25lPSJ5ZXMiIGluIAotCSAgICBpdHMgWE1MIGRlY2xhcmF0aW9uLCBhbmQgb3RoZXJ3aXNlIGlzIGZhbHNlLgotCQk8L3RkPgotCTwvdHI+Ci0KLSAgICA8dHI+Ci0JPHRkPmxleGljYWwtaGFuZGxlci9wYXJhbWV0ZXItZW50aXRpZXM8L3RkPgotCTx0ZD48ZW0+cmVhZC93cml0ZTwvZW0+PC90ZD4KLQk8dGQ+PGVtPnVuc3BlY2lmaWVkPC9lbT48L3RkPgotCTx0ZD4gQSB2YWx1ZSBvZiAidHJ1ZSIgaW5kaWNhdGVzIHRoYXQgdGhlIExleGljYWxIYW5kbGVyIHdpbGwgcmVwb3J0Ci0JICAgIHRoZSBiZWdpbm5pbmcgYW5kIGVuZCBvZiBwYXJhbWV0ZXIgZW50aXRpZXMuCi0JCTwvdGQ+Ci0JPC90cj4KLQotICAgIDx0cj4KLQk8dGQ+bmFtZXNwYWNlczwvdGQ+Ci0JPHRkPjxlbT5yZWFkL3dyaXRlPC9lbT48L3RkPgotCTx0ZD50cnVlPC90ZD4KLQk8dGQ+IEEgdmFsdWUgb2YgInRydWUiIGluZGljYXRlcyBuYW1lc3BhY2UgVVJJcyBhbmQgdW5wcmVmaXhlZCBsb2NhbCBuYW1lcwotCSAgICBmb3IgZWxlbWVudCBhbmQgYXR0cmlidXRlIG5hbWVzIHdpbGwgYmUgYXZhaWxhYmxlLgotCQk8L3RkPgotCTwvdHI+Ci0KLSAgICA8dHI+Ci0JPHRkPm5hbWVzcGFjZS1wcmVmaXhlczwvdGQ+Ci0JPHRkPjxlbT5yZWFkL3dyaXRlPC9lbT48L3RkPgotCTx0ZD5mYWxzZTwvdGQ+Ci0JPHRkPiBBIHZhbHVlIG9mICJ0cnVlIiBpbmRpY2F0ZXMgdGhhdCBYTUwgcXVhbGlmaWVkIG5hbWVzICh3aXRoIHByZWZpeGVzKSBhbmQKLQkgICAgYXR0cmlidXRlcyAoaW5jbHVkaW5nIDxlbT54bWxucyo8L2VtPiBhdHRyaWJ1dGVzKSB3aWxsIGJlIGF2YWlsYWJsZS4KLQkJPC90ZD4KLQk8L3RyPgotCi0gICAgPHRyPgotCTx0ZD5yZXNvbHZlLWR0ZC11cmlzPC90ZD4KLQk8dGQ+PGVtPnJlYWQvd3JpdGU8L2VtPjwvdGQ+Ci0JPHRkPjxlbT50cnVlPC9lbT48L3RkPgotCTx0ZD4gQSB2YWx1ZSBvZiAidHJ1ZSIgaW5kaWNhdGVzIHRoYXQgc3lzdGVtIElEcyBpbiBkZWNsYXJhdGlvbnMgd2lsbAotCSAgICBiZSBhYnNvbHV0aXplZCAocmVsYXRpdmUgdG8gdGhlaXIgYmFzZSBVUklzKSBiZWZvcmUgcmVwb3J0aW5nLgotCSAgICAoVGhhdCBpcyB0aGUgZGVmYXVsdCBiZWhhdmlvciBmb3IgYWxsIFNBWDIgWE1MIHBhcnNlcnMuKQotCSAgICBBIHZhbHVlIG9mICJmYWxzZSIgaW5kaWNhdGVzIHRob3NlIElEcyB3aWxsIG5vdCBiZSBhYnNvbHV0aXplZDsKLQkgICAgcGFyc2VycyB3aWxsIHByb3ZpZGUgdGhlIGJhc2UgVVJJIGZyb20KLQkgICAgPGVtPkxvY2F0b3IuZ2V0U3lzdGVtSWQoKTwvZW0+LgotCSAgICBUaGlzIGFwcGxpZXMgdG8gc3lzdGVtIElEcyBwYXNzZWQgaW4gPHVsPgotCQk8bGk+PGVtPkRUREhhbmRsZXIubm90YXRpb25EZWNsKCk8L2VtPiwKLQkJPGxpPjxlbT5EVERIYW5kbGVyLnVucGFyc2VkRW50aXR5RGVjbCgpPC9lbT4sIGFuZAotCQk8bGk+PGVtPkRlY2xIYW5kbGVyLmV4dGVybmFsRW50aXR5RGVjbCgpPC9lbT4uCi0JICAgIDwvdWw+Ci0JICAgIEl0IGRvZXMgbm90IGFwcGx5IHRvIDxlbT5FbnRpdHlSZXNvbHZlci5yZXNvbHZlRW50aXR5KCk8L2VtPiwKLQkgICAgd2hpY2ggaXMgbm90IHVzZWQgdG8gcmVwb3J0IGRlY2xhcmF0aW9ucywgb3IgdG8KLQkgICAgPGVtPkxleGljYWxIYW5kbGVyLnN0YXJ0RFREKCk8L2VtPiwgd2hpY2ggYWxyZWFkeSBwcm92aWRlcwotCSAgICB0aGUgbm9uLWFic29sdXRpemVkIFVSSS4KLQkgICAgPC90ZD4KLQk8L3RyPgotCi0gICAgPHRyPgotCTx0ZD5zdHJpbmctaW50ZXJuaW5nPC90ZD4KLQk8dGQ+PGVtPnJlYWQvd3JpdGU8L2VtPjwvdGQ+Ci0JPHRkPjxlbT51bnNwZWNpZmllZDwvZW0+PC90ZD4KLQk8dGQ+IEhhcyBhIHZhbHVlIG9mICJ0cnVlIiBpZiBhbGwgWE1MIG5hbWVzIChmb3IgZWxlbWVudHMsIHByZWZpeGVzLAotCSAgICBhdHRyaWJ1dGVzLCBlbnRpdGllcywgbm90YXRpb25zLCBhbmQgbG9jYWwgbmFtZXMpLAotCSAgICBhcyB3ZWxsIGFzIE5hbWVzcGFjZSBVUklzLCB3aWxsIGhhdmUgYmVlbiBpbnRlcm5lZAotCSAgICB1c2luZyA8ZW0+amF2YS5sYW5nLlN0cmluZy5pbnRlcm48L2VtPi4gVGhpcyBzdXBwb3J0cyBmYXN0Ci0JICAgIHRlc3Rpbmcgb2YgZXF1YWxpdHkvaW5lcXVhbGl0eSBhZ2FpbnN0IHN0cmluZyBjb25zdGFudHMsCi0JICAgIHJhdGhlciB0aGFuIGZvcmNpbmcgc2xvd2VyIGNhbGxzIHRvIDxlbT5TdHJpbmcuZXF1YWxzKCk8L2VtPi4KLQkgICAgPC90ZD4KLQk8L3RyPgotCi0gICAgPHRyPgotICAgIDx0ZD51bmljb2RlLW5vcm1hbGl6YXRpb24tY2hlY2tpbmc8L3RkPgotICAgIDx0ZD48ZW0+cmVhZC93cml0ZTwvZW0+PC90ZD4KLSAgICA8dGQ+PGVtPmZhbHNlPC9lbT48L3RkPgotICAgIDx0ZD4gQ29udHJvbHMgd2hldGhlciB0aGUgcGFyc2VyIHJlcG9ydHMgVW5pY29kZSBub3JtYWxpemF0aW9uIAotICAgICAgICBlcnJvcnMgYXMgZGVzY3JpYmVkIGluIHNlY3Rpb24gMi4xMyBhbmQgQXBwZW5kaXggQiBvZiB0aGUgCi0gICAgICAgIFhNTCAxLjEgUmVjb21tZW5kYXRpb24uIElmIHRydWUsIFVuaWNvZGUgbm9ybWFsaXphdGlvbgotICAgICAgICBlcnJvcnMgYXJlIHJlcG9ydGVkIHVzaW5nIHRoZSBFcnJvckhhbmRsZXIuZXJyb3IoKSBjYWxsYmFjay4KLSAgICAgICAgU3VjaCBlcnJvcnMgYXJlIG5vdCBmYXRhbCBpbiB0aGVtc2VsdmVzICh0aG91Z2gsIG9idmlvdXNseSwKLSAgICAgICAgb3RoZXIgVW5pY29kZS1yZWxhdGVkIGVuY29kaW5nIGVycm9ycyBtYXkgYmUpLgotCQk8L3RkPgotICAgIDwvdHI+Ci0gICAgCi0gICAgPHRyPgotCTx0ZD51c2UtYXR0cmlidXRlczI8L3RkPgotCTx0ZD48ZW0+cmVhZC1vbmx5PC9lbT48L3RkPgotCTx0ZD5ub3QgYXBwbGljYWJsZTwvdGQ+Ci0JPHRkPiBSZXR1cm5zICJ0cnVlIiBpZiB0aGUgPGVtPkF0dHJpYnV0ZXM8L2VtPiBvYmplY3RzIHBhc3NlZCBieQotCSAgICB0aGlzIHBhcnNlciBpbiA8ZW0+Q29udGVudEhhbmRsZXIuc3RhcnRFbGVtZW50KCk8L2VtPgotCSAgICBpbXBsZW1lbnQgdGhlIDxhIGhyZWY9ImV4dC9BdHRyaWJ1dGVzMi5odG1sIgotCSAgICA+PGVtPm9yZy54bWwuc2F4LmV4dC5BdHRyaWJ1dGVzMjwvZW0+PC9hPiBpbnRlcmZhY2UuCi0JICAgIFRoYXQgaW50ZXJmYWNlIGV4cG9zZXMgYWRkaXRpb25hbCBEVEQtcmVsYXRlZCBpbmZvcm1hdGlvbiwKLQkgICAgc3VjaCBhcyB3aGV0aGVyIHRoZSBhdHRyaWJ1dGUgd2FzIHNwZWNpZmllZCBpbiB0aGUKLQkgICAgc291cmNlIHRleHQgcmF0aGVyIHRoYW4gZGVmYXVsdGVkLgotCQk8L3RkPgotCTwvdHI+Ci0KLSAgICA8dHI+Ci0JPHRkPnVzZS1sb2NhdG9yMjwvdGQ+Ci0JPHRkPjxlbT5yZWFkLW9ubHk8L2VtPjwvdGQ+Ci0JPHRkPm5vdCBhcHBsaWNhYmxlPC90ZD4KLQk8dGQ+IFJldHVybnMgInRydWUiIGlmIHRoZSA8ZW0+TG9jYXRvcjwvZW0+IG9iamVjdHMgcGFzc2VkIGJ5Ci0JICAgIHRoaXMgcGFyc2VyIGluIDxlbT5Db250ZW50SGFuZGxlci5zZXREb2N1bWVudExvY2F0b3IoKTwvZW0+Ci0JICAgIGltcGxlbWVudCB0aGUgPGEgaHJlZj0iZXh0L0xvY2F0b3IyLmh0bWwiCi0JICAgID48ZW0+b3JnLnhtbC5zYXguZXh0LkxvY2F0b3IyPC9lbT48L2E+IGludGVyZmFjZS4KLQkgICAgVGhhdCBpbnRlcmZhY2UgZXhwb3NlcyBhZGRpdGlvbmFsIGVudGl0eSBpbmZvcm1hdGlvbiwKLQkgICAgc3VjaCBhcyB0aGUgY2hhcmFjdGVyIGVuY29kaW5nIGFuZCBYTUwgdmVyc2lvbiB1c2VkLgotCQk8L3RkPgotCTwvdHI+Ci0KLSAgICA8dHI+Ci0JPHRkPnVzZS1lbnRpdHktcmVzb2x2ZXIyPC90ZD4KLQk8dGQ+PGVtPnJlYWQvd3JpdGU8L2VtPjwvdGQ+Ci0JPHRkPjxlbT50cnVlPC9lbT48L3RkPgotCTx0ZD4gUmV0dXJucyAidHJ1ZSIgaWYsIHdoZW4gPGVtPnNldEVudGl0eVJlc29sdmVyPC9lbT4gaXMgZ2l2ZW4KLQkgICAgYW4gb2JqZWN0IGltcGxlbWVudGluZyB0aGUgPGEgaHJlZj0iZXh0L0VudGl0eVJlc29sdmVyMi5odG1sIgotCSAgICA+PGVtPm9yZy54bWwuc2F4LmV4dC5FbnRpdHlSZXNvbHZlcjI8L2VtPjwvYT4gaW50ZXJmYWNlLAotCSAgICB0aG9zZSBuZXcgbWV0aG9kcyB3aWxsIGJlIHVzZWQuCi0JICAgIFJldHVybnMgImZhbHNlIiB0byBpbmRpY2F0ZSB0aGF0IHRob3NlIG1ldGhvZHMgd2lsbCBub3QgYmUgdXNlZC4KLQkJPC90ZD4KLQk8L3RyPgotCi0gICAgPHRyPgotCTx0ZD52YWxpZGF0aW9uPC90ZD4KLQk8dGQ+PGVtPnJlYWQvd3JpdGU8L2VtPjwvdGQ+Ci0JPHRkPjxlbT51bnNwZWNpZmllZDwvZW0+PC90ZD4KLQk8dGQ+IENvbnRyb2xzIHdoZXRoZXIgdGhlIHBhcnNlciBpcyByZXBvcnRpbmcgYWxsIHZhbGlkaXR5Ci0JICAgIGVycm9yczsgaWYgdHJ1ZSwgYWxsIGV4dGVybmFsIGVudGl0aWVzIHdpbGwgYmUgcmVhZC4KLQkJPC90ZD4KLQk8L3RyPgotCi0gICAgPHRyPgotCTx0ZD54bWxucy11cmlzPC90ZD4KLQk8dGQ+PGVtPnJlYWQvd3JpdGU8L2VtPjwvdGQ+Ci0JPHRkPjxlbT5mYWxzZTwvZW0+PC90ZD4KLQk8dGQ+IENvbnRyb2xzIHdoZXRoZXIsIHdoZW4gdGhlIDxlbT5uYW1lc3BhY2UtcHJlZml4ZXM8L2VtPiBmZWF0dXJlCi0JICAgIGlzIHNldCwgdGhlIHBhcnNlciB0cmVhdHMgbmFtZXNwYWNlIGRlY2xhcmF0aW9uIGF0dHJpYnV0ZXMgYXMKLQkgICAgYmVpbmcgaW4gdGhlIDxlbT5odHRwOi8vd3d3LnczLm9yZy8yMDAwL3htbG5zLzwvZW0+IG5hbWVzcGFjZS4KLQkgICAgQnkgZGVmYXVsdCwgU0FYMiBjb25mb3JtcyB0byB0aGUgb3JpZ2luYWwgIk5hbWVzcGFjZXMgaW4gWE1MIgotCSAgICBSZWNvbW1lbmRhdGlvbiwgd2hpY2ggZXhwbGljaXRseSBzdGF0ZXMgdGhhdCBzdWNoIGF0dHJpYnV0ZXMgYXJlCi0JICAgIG5vdCBpbiBhbnkgbmFtZXNwYWNlLgotCSAgICBTZXR0aW5nIHRoaXMgb3B0aW9uYWwgZmxhZyB0byAidHJ1ZSIgbWFrZXMgdGhlIFNBWDIgZXZlbnRzIGNvbmZvcm0gdG8KLQkgICAgYSBsYXRlciBiYWNrd2FyZHMtaW5jb21wYXRpYmxlIHJldmlzaW9uIG9mIHRoYXQgcmVjb21tZW5kYXRpb24sCi0JICAgIHBsYWNpbmcgdGhvc2UgYXR0cmlidXRlcyBpbiBhIG5hbWVzcGFjZS4KLQkJPC90ZD4KLQk8L3RyPgotCi0gICAgPHRyPgotICAgIDx0ZD54bWwtMS4xPC90ZD4KLSAgICA8dGQ+PGVtPnJlYWQtb25seTwvZW0+PC90ZD4KLSAgICA8dGQ+bm90IGFwcGxpY2FibGU8L3RkPgotICAgIDx0ZD4gUmV0dXJucyAidHJ1ZSIgaWYgdGhlIHBhcnNlciBzdXBwb3J0cyBib3RoIFhNTCAxLjEgYW5kIFhNTCAxLjAuCi0gICAgICAgIFJldHVybnMgImZhbHNlIiBpZiB0aGUgcGFyc2VyIHN1cHBvcnRzIG9ubHkgWE1MIDEuMC4KLQkJPC90ZD4KLSAgICA8L3RyPgotCi08L3RhYmxlPgotCi08cD4gU3VwcG9ydCBmb3IgdGhlIGRlZmF1bHQgdmFsdWVzIG9mIHRoZQotPGVtPm5hbWVzcGFjZXM8L2VtPiBhbmQgPGVtPm5hbWVzcGFjZS1wcmVmaXhlczwvZW0+Ci1wcm9wZXJ0aWVzIGlzIHJlcXVpcmVkLgotU3VwcG9ydCBmb3IgYW55IG90aGVyIGZlYXR1cmUgZmxhZ3MgaXMgZW50aXJlbHkgb3B0aW9uYWwuCi08L3A+Ci0KLTxwPiBGb3IgZGVmYXVsdCB2YWx1ZXMgbm90IHNwZWNpZmllZCBieSBTQVgyLAotZWFjaCBYTUxSZWFkZXIgaW1wbGVtZW50YXRpb24gc3BlY2lmaWVzIGl0cyBkZWZhdWx0LAotb3IgbWF5IGNob29zZSBub3QgdG8gZXhwb3NlIHRoZSBmZWF0dXJlIGZsYWcuCi1Vbmxlc3Mgb3RoZXJ3aXNlIHNwZWNpZmllZCBoZXJlLAotaW1wbGVtZW50YXRpb25zIG1heSBzdXBwb3J0IGNoYW5naW5nIGN1cnJlbnQgdmFsdWVzCi1vZiB0aGVzZSBzdGFuZGFyZCBmZWF0dXJlIGZsYWdzLCBidXQgbm90IHdoaWxlIHBhcnNpbmcuCi08L3A+Ci0KLTxoMj4gU0FYMiBTdGFuZGFyZCBIYW5kbGVyIGFuZCBQcm9wZXJ0eSBJRHMgPC9oMj4KLQotPHA+IEZvciBwYXJzZXIgaW50ZXJmYWNlIGNoYXJhY3RlcmlzdGljcyB0aGF0IGFyZSBkZXNjcmliZWQKLWFzIG9iamVjdHMsIGEgc2VwYXJhdGUgbmFtZXNwYWNlIGlzIGRlZmluZWQuICBUaGUKLW9iamVjdHMgaW4gdGhpcyBuYW1lc3BhY2UgYXJlIGFnYWluIGlkZW50aWZpZWQgYnkgVVJJLCBhbmQKLXRoZSBzdGFuZGFyZCBwcm9wZXJ0eSBVUklzIGhhdmUgdGhlIHByZWZpeAotPGNvZGU+aHR0cDovL3htbC5vcmcvc2F4L3Byb3BlcnRpZXMvPC9jb2RlPiBiZWZvcmUgYW4gaWRlbnRpZmllciBzdWNoIGFzCi08Y29kZT5sZXhpY2FsLWhhbmRsZXI8L2NvZGU+IG9yCi08Y29kZT5kb20tbm9kZTwvY29kZT4uICBNYW5hZ2UgdGhvc2UgcHJvcGVydGllcyB1c2luZwotPGVtPnNldFByb3BlcnR5KCk8L2VtPi4gIFRob3NlIGlkZW50aWZpZXJzIGFyZTogPC9wPgotCi08dGFibGUgYm9yZGVyPSIxIiBjZWxscGFkZGluZz0iMyIgY2VsbHNwYWNpbmc9IjAiIHdpZHRoPSIxMDAlIj4KLSAgICA8dHIgYWxpZ249ImNlbnRlciIgYmdjb2xvcj0iI2NjY2NmZiI+Ci0JPHRoPlByb3BlcnR5IElEPC90aD4KLQk8dGg+RGVzY3JpcHRpb248L3RoPgotCTwvdHI+Ci0KLSAgICA8dHI+Ci0JPHRkPmRlY2xhcmF0aW9uLWhhbmRsZXI8L3RkPgotCTx0ZD4gVXNlZCB0byBzZWUgbW9zdCBEVEQgZGVjbGFyYXRpb25zIGV4Y2VwdCB0aG9zZSB0cmVhdGVkCi0JICAgIGFzIGxleGljYWwgKCJkb2N1bWVudCBlbGVtZW50IG5hbWUgaXMgLi4uIikgb3Igd2hpY2ggYXJlCi0JICAgIG1hbmRhdG9yeSBmb3IgYWxsIFNBWCBwYXJzZXJzICg8ZW0+RFRESGFuZGxlcjwvZW0+KS4KLQkgICAgVGhlIE9iamVjdCBtdXN0IGltcGxlbWVudCA8YSBocmVmPSJleHQvRGVjbEhhbmRsZXIuaHRtbCIKLQkgICAgPjxlbT5vcmcueG1sLnNheC5leHQuRGVjbEhhbmRsZXI8L2VtPjwvYT4uCi0JICAgIDwvdGQ+Ci0JPC90cj4KLQotICAgIDx0cj4KLSAgICAgICAgPHRkPmRvY3VtZW50LXhtbC12ZXJzaW9uPC90ZD4KLSAgICAgICAgPHRkPiBNYXkgYmUgZXhhbWluZWQgb25seSBkdXJpbmcgYSBwYXJzZSwgYWZ0ZXIgdGhlIHN0YXJ0RG9jdW1lbnQoKQotICAgICAgICAgICAgY2FsbGJhY2sgaGFzIGJlZW4gY29tcGxldGVkOyByZWFkLW9ubHkuIFRoaXMgcHJvcGVydHkgaXMgYSAKLSAgICAgICAgICAgIGxpdGVyYWwgc3RyaW5nIGRlc2NyaWJpbmcgdGhlIGFjdHVhbCBYTUwgdmVyc2lvbiBvZiB0aGUgZG9jdW1lbnQsIAotICAgICAgICAgICAgc3VjaCBhcyAiMS4wIiBvciAiMS4xIi4KLSAgICAgICAgICAgIDwvdGQ+Ci0gICAgICAgIDwvdHI+Ci0gICAgCi0gICAgPHRyPgotCTx0ZD5kb20tbm9kZTwvdGQ+Ci0JPHRkPiBGb3IgIkRPTSBXYWxrZXIiIHN0eWxlIHBhcnNlcnMsIHdoaWNoIGlnbm9yZSB0aGVpcgotCSAgICA8ZW0+cGFyc2VyLnBhcnNlKCk8L2VtPiBwYXJhbWV0ZXJzLCB0aGlzIGlzIHVzZWQgdG8KLQkgICAgc3BlY2lmeSB0aGUgRE9NIChzdWIpdHJlZSBiZWluZyB3YWxrZWQgYnkgdGhlIHBhcnNlci4KLQkgICAgVGhlIE9iamVjdCBtdXN0IGltcGxlbWVudCB0aGUKLQkgICAgPGVtPm9yZy53M2MuZG9tLk5vZGU8L2VtPiBpbnRlcmZhY2UuCi0JICAgIDwvdGQ+Ci0JPC90cj4KLQotICAgIDx0cj4KLQk8dGQ+bGV4aWNhbC1oYW5kbGVyPC90ZD4KLQk8dGQ+IFVzZWQgdG8gc2VlIHNvbWUgc3ludGF4IGV2ZW50cyB0aGF0IGFyZSBlc3NlbnRpYWwgaW4gc29tZQotCSAgICBhcHBsaWNhdGlvbnM6ICBjb21tZW50cywgQ0RBVEEgZGVsaW1pdGVycywgc2VsZWN0ZWQgZ2VuZXJhbAotCSAgICBlbnRpdHkgaW5jbHVzaW9ucywgYW5kIHRoZSBzdGFydCBhbmQgZW5kIG9mIHRoZSBEVEQKLQkgICAgKGFuZCBkZWNsYXJhdGlvbiBvZiBkb2N1bWVudCBlbGVtZW50IG5hbWUpLgotCSAgICBUaGUgT2JqZWN0IG11c3QgaW1wbGVtZW50IDxhIGhyZWY9ImV4dC9MZXhpY2FsSGFuZGxlci5odG1sIgotCSAgICA+PGVtPm9yZy54bWwuc2F4LmV4dC5MZXhpY2FsSGFuZGxlcjwvZW0+PC9hPi4KLQkgICAgPC90ZD4KLQk8L3RyPgotCi0gICAgPHRyPgotCTx0ZD54bWwtc3RyaW5nPC90ZD4KLQk8dGQ+IFJlYWRhYmxlIG9ubHkgZHVyaW5nIGEgcGFyc2VyIGNhbGxiYWNrLCB0aGlzIGV4cG9zZXMgYSA8Yj5UQlM8L2I+Ci0JICAgIGNodW5rIG9mIGNoYXJhY3RlcnMgcmVzcG9uc2libGUgZm9yIHRoZSBjdXJyZW50IGV2ZW50LiA8L3RkPgotCTwvdHI+Ci0KLTwvdGFibGU+Ci0KLTxwPiBBbGwgb2YgdGhlc2Ugc3RhbmRhcmQgcHJvcGVydGllcyBhcmUgb3B0aW9uYWw7Ci1YTUxSZWFkZXIgaW1wbGVtZW50YXRpb25zIG5lZWQgbm90IHN1cHBvcnQgdGhlbS4KLTwvcD4KLQotPC9ib2R5PjwvaHRtbD4K